[
  {
    "path": ".editorconfig",
    "content": "; Top-most EditorConfig file\nroot = true\n\n[*]\ncharset = utf-8 # standardize on no BOM (except resx, see below)\nindent_style = tab\nindent_size = 4\nguidelines = 110\ntab_width = 4\nend_of_line = crlf\n\n# .net tooling writes the BOM to resx files on running dotnet build ILSpy.sln regardless,\n# so we should direct text editors to NOT change the file\n[*.resx]\ncharset = utf-8-bom\n\n[*.il]\nindent_style = space\nindent_size = 2\n[*.{yml,yaml}]\nindent_style = space\nindent_size = 2\n[*.{csproj,props}]\nindent_style = space\nindent_size = 2\n[*.config]\nindent_style = space\nindent_size = 2\n[*.nuspec]\nindent_style = space\nindent_size = 2\n[*.vsixmanifest]\nindent_style = space\nindent_size = 2\n[*.vsct]\nindent_style = space\nindent_size = 2\n\n[*.cs]\n# New line preferences\ncsharp_new_line_before_open_brace = methods, types, control_blocks, local_functions\ncsharp_new_line_before_else = true\ncsharp_new_line_before_catch = true\ncsharp_new_line_before_finally = true\ncsharp_new_line_before_members_in_object_initializers = false\ncsharp_new_line_before_members_in_anonymous_types = false\ncsharp_new_line_within_query_expression_clauses = false\n\n# Indentation preferences\ncsharp_indent_block_contents = true\ncsharp_indent_braces = false\ncsharp_indent_case_contents = true\ncsharp_indent_case_contents_when_block = false\ncsharp_indent_switch_labels = true\ncsharp_indent_labels = no_change\n\n# Avoid 'this.' in generated code unless absolutely necessary, but allow developers to use it\ndotnet_style_qualification_for_field = false:silent\ndotnet_style_qualification_for_property = false:silent\ndotnet_style_qualification_for_method = false:silent\ndotnet_style_qualification_for_event = false:silent\n\n# Do not use 'var' when generating code, but allow developers to use it\ncsharp_style_var_for_built_in_types = false:silent\ncsharp_style_var_when_type_is_apparent = true:suggestion\ncsharp_style_var_elsewhere = false:silent\n\n# Use language keywords instead of BCL types when generating code, but allow developers to use either\ndotnet_style_predefined_type_for_locals_parameters_members = true:silent\ndotnet_style_predefined_type_for_member_access = true:silent\n\n# Using directives\ndotnet_sort_system_directives_first = true\ndotnet_separate_import_directive_groups = true\n\n# Wrapping\ncsharp_preserve_single_line_blocks = true\ncsharp_preserve_single_line_statements = false\n\n# Code style\ncsharp_prefer_braces = true:silent\n\n# Expression-level preferences\ndotnet_style_object_initializer = true:suggestion\ndotnet_style_collection_initializer = true:suggestion\ndotnet_style_explicit_tuple_names = true:suggestion\ndotnet_style_coalesce_expression = true:suggestion\ndotnet_style_null_propagation = true:suggestion\n\n# Expression-bodied members\ncsharp_style_expression_bodied_methods = false:silent\ncsharp_style_expression_bodied_constructors = false:silent\ncsharp_style_expression_bodied_operators = false:silent\ncsharp_style_expression_bodied_properties = true:silent\ncsharp_style_expression_bodied_indexers = true:silent\ncsharp_style_expression_bodied_accessors = true:silent\n\n# Pattern matching\ncsharp_style_pattern_matching_over_is_with_cast_check = true:suggestion\ncsharp_style_pattern_matching_over_as_with_null_check = true:suggestion\ncsharp_style_inlined_variable_declaration = true:suggestion\n\n# Null checking preferences\ncsharp_style_throw_expression = true:suggestion\ncsharp_style_conditional_delegate_call = true:suggestion\n\n# Space preferences\ncsharp_space_after_cast = false\ncsharp_space_after_colon_in_inheritance_clause = true\ncsharp_space_after_comma = true\ncsharp_space_after_dot = false\ncsharp_space_after_keywords_in_control_flow_statements = true\ncsharp_space_after_semicolon_in_for_statement = true\ncsharp_space_around_binary_operators = before_and_after\ncsharp_space_around_declaration_statements = false\ncsharp_space_before_colon_in_inheritance_clause = true\ncsharp_space_before_comma = false\ncsharp_space_before_dot = false\ncsharp_space_before_open_square_brackets = false\ncsharp_space_before_semicolon_in_for_statement = false\ncsharp_space_between_empty_square_brackets = false\ncsharp_space_between_method_call_empty_parameter_list_parentheses = false\ncsharp_space_between_method_call_name_and_opening_parenthesis = false\ncsharp_space_between_method_call_parameter_list_parentheses = false\ncsharp_space_between_method_declaration_empty_parameter_list_parentheses = false\ncsharp_space_between_method_declaration_name_and_open_parenthesis = false\ncsharp_space_between_method_declaration_parameter_list_parentheses = false\ncsharp_space_between_parentheses = false\ncsharp_space_between_square_brackets = false\n\n# Naming rules\n# Naming styles:\ndotnet_naming_style.lower_camel_case_style.capitalization = camel_case\ndotnet_naming_style.upper_camel_case_style.capitalization = pascal_case\n\n# Symbol groups:\n# all non-private fields\ndotnet_naming_symbols.fields_symbols.applicable_accessibilities = *\ndotnet_naming_symbols.fields_symbols.applicable_kinds = field\n# all private/protected fields except constants\ndotnet_naming_symbols.private_fields_symbols.applicable_accessibilities = private,protected,private_protected\ndotnet_naming_symbols.private_fields_symbols.applicable_kinds = field\n\n# Naming rules:\n# all non-private fields are pascal case\ndotnet_naming_rule.fields_rule.severity = warning\ndotnet_naming_rule.fields_rule.style = upper_camel_case_style\ndotnet_naming_rule.fields_rule.symbols = fields_symbols\n# all private fields are camel case\ndotnet_naming_rule.private_fields_rule.severity = warning\ndotnet_naming_rule.private_fields_rule.style = lower_camel_case_style\ndotnet_naming_rule.private_fields_rule.symbols = private_fields_symbols\n\n# General settings:\ncsharp_using_directive_placement = outside_namespace:silent\ncsharp_prefer_simple_using_statement = true:suggestion\ncsharp_style_namespace_declarations = block_scoped:silent\ncsharp_style_prefer_method_group_conversion = true:silent\ncsharp_style_prefer_top_level_statements = true:silent\ncsharp_style_prefer_primary_constructors = true:suggestion\ncsharp_prefer_system_threading_lock = true:suggestion\ncsharp_style_expression_bodied_lambdas = true:silent\ncsharp_style_expression_bodied_local_functions = false:silent\ncsharp_style_prefer_null_check_over_type_check = true:suggestion\ncsharp_prefer_simple_default_expression = true:suggestion\ncsharp_style_prefer_local_over_anonymous_function = true:suggestion\ncsharp_style_prefer_index_operator = true:suggestion\ncsharp_style_prefer_range_operator = true:suggestion\ncsharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion\ncsharp_style_prefer_tuple_swap = true:suggestion\ncsharp_style_prefer_utf8_string_literals = true:suggestion\ncsharp_style_deconstructed_variable_declaration = true:suggestion\ncsharp_prefer_static_local_function = true:suggestion\ncsharp_prefer_static_anonymous_function = true:suggestion\ncsharp_style_prefer_readonly_struct = true:suggestion\ncsharp_style_prefer_readonly_struct_member = true:suggestion\ncsharp_style_allow_embedded_statements_on_same_line_experimental = true:silent\ncsharp_style_allow_blank_lines_between_consecutive_braces_experimental = true:silent\ncsharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent\ncsharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true:silent\ncsharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent\ncsharp_style_prefer_switch_expression = true:suggestion\ncsharp_style_prefer_pattern_matching = true:silent\ncsharp_style_prefer_not_pattern = true:suggestion\ncsharp_style_prefer_extended_property_pattern = true:suggestion\n\ndotnet_style_operator_placement_when_wrapping = beginning_of_line\ndotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion\ndotnet_style_prefer_auto_properties = true:silent\ndotnet_style_prefer_simplified_boolean_expressions = true:suggestion\ndotnet_style_prefer_conditional_expression_over_assignment = true:silent\ndotnet_style_prefer_conditional_expression_over_return = true:silent\ndotnet_style_prefer_inferred_tuple_names = true:suggestion\ndotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion\ndotnet_style_prefer_compound_assignment = true:suggestion\ndotnet_style_prefer_simplified_interpolation = true:suggestion\ndotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion\ndotnet_style_namespace_match_folder = true:suggestion\ndotnet_style_readonly_field = true:suggestion\ndotnet_style_require_accessibility_modifiers = omit_if_default:suggestion\ndotnet_style_allow_multiple_blank_lines_experimental = false:warning\ndotnet_style_allow_statement_immediately_after_block_experimental = true:silent\ndotnet_code_quality_unused_parameters = all:suggestion\ndotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent\ndotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent\ndotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent\ndotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent\n\n\n# Errors and warnings\ndotnet_diagnostic.IDE0007.severity = none\n\ndotnet_diagnostic.CA1001.severity = warning\ndotnet_diagnostic.CA1009.severity = warning\ndotnet_diagnostic.CA1016.severity = warning\n#dotnet_diagnostic.CA1033.severity = warning # Disabled because currently, there are too many violations\ndotnet_diagnostic.CA1049.severity = warning\ndotnet_diagnostic.CA1060.severity = warning\ndotnet_diagnostic.CA1061.severity = warning\ndotnet_diagnostic.CA1063.severity = warning\ndotnet_diagnostic.CA1065.severity = warning\ndotnet_diagnostic.CA1301.severity = warning\ndotnet_diagnostic.CA1400.severity = warning\ndotnet_diagnostic.CA1401.severity = warning\ndotnet_diagnostic.CA1403.severity = warning\ndotnet_diagnostic.CA1404.severity = warning\ndotnet_diagnostic.CA1405.severity = warning\ndotnet_diagnostic.CA1410.severity = warning\ndotnet_diagnostic.CA1415.severity = warning\ndotnet_diagnostic.CA1821.severity = warning\ndotnet_diagnostic.CA1900.severity = warning\ndotnet_diagnostic.CA1901.severity = warning\ndotnet_diagnostic.CA2002.severity = warning\ndotnet_diagnostic.CA2100.severity = warning\ndotnet_diagnostic.CA2101.severity = warning\ndotnet_diagnostic.CA2108.severity = warning\ndotnet_diagnostic.CA2111.severity = warning\ndotnet_diagnostic.CA2112.severity = warning\ndotnet_diagnostic.CA2114.severity = warning\ndotnet_diagnostic.CA2116.severity = warning\ndotnet_diagnostic.CA2117.severity = warning\ndotnet_diagnostic.CA2122.severity = warning\ndotnet_diagnostic.CA2123.severity = warning\ndotnet_diagnostic.CA2124.severity = warning\ndotnet_diagnostic.CA2126.severity = warning\ndotnet_diagnostic.CA2131.severity = warning\ndotnet_diagnostic.CA2132.severity = warning\ndotnet_diagnostic.CA2133.severity = warning\ndotnet_diagnostic.CA2134.severity = warning\ndotnet_diagnostic.CA2137.severity = warning\ndotnet_diagnostic.CA2138.severity = warning\ndotnet_diagnostic.CA2140.severity = warning\ndotnet_diagnostic.CA2141.severity = warning\ndotnet_diagnostic.CA2146.severity = warning\ndotnet_diagnostic.CA2147.severity = warning\ndotnet_diagnostic.CA2149.severity = warning\ndotnet_diagnostic.CA2200.severity = warning\ndotnet_diagnostic.CA2202.severity = warning\ndotnet_diagnostic.CA2207.severity = warning\ndotnet_diagnostic.CA2212.severity = warning\ndotnet_diagnostic.CA2213.severity = warning\ndotnet_diagnostic.CA2214.severity = warning\ndotnet_diagnostic.CA2216.severity = warning\ndotnet_diagnostic.CA2220.severity = warning\ndotnet_diagnostic.CA2229.severity = warning\ndotnet_diagnostic.CA2231.severity = warning\ndotnet_diagnostic.CA2232.severity = warning\ndotnet_diagnostic.CA2235.severity = warning\ndotnet_diagnostic.CA2236.severity = warning\ndotnet_diagnostic.CA2237.severity = warning\ndotnet_diagnostic.CA2238.severity = warning\ndotnet_diagnostic.CA2240.severity = warning\ndotnet_diagnostic.CA2241.severity = warning\ndotnet_diagnostic.CA2242.severity = warning\n\n# MEF006: No importing constructor\ndotnet_diagnostic.MEF006.severity = silent\n"
  },
  {
    "path": ".git-blame-ignore-revs",
    "content": "# https://github.com/icsharpcode/ILSpy/issues/2128\n0d9f871a4f7c478fdf3f7b699d74e77506e978a4"
  },
  {
    "path": ".gitattributes",
    "content": "* text=auto\n*.cs text diff=csharp\n*.sln text eol=crlf\n*.csproj text eol=crlf\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "github: [dgrunwald, siegfriedpammer, christophwille]\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: General bug report\nabout: Error dialog, crash, or anything else unrelated to the decompiled code\ntitle: ''\nlabels: Bug\nassignees: ''\n\n---\n\n### Steps to reproduce\n1. \n2. \n3. \n\n### Error message shown\n\n```\nCopy and paste any error messages / relevant text and/or screenshot the incorrect behaviour.\n```\n\n### Details\n* Product in use: e.g. ILSpy / ICSharpCode.Decompiler nuget package / VS extension\n* Version in use: e.g. 6.0.0 or a commit hash (use Help>About to see which ILSpy version you are using)\n* Any other relevant information to the issue, or your interest in contributing a fix.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: Enhancement\nassignees: ''\n\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is and why it's important to you. Ex. I'm always frustrated when [...]\nAny (even unsuccessful) ways in which you've tried to workaround the problem currently\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/wrong_decompilation.md",
    "content": "---\nname: Wrong decompilation\nabout: Decompiled code doesn't compile, or behaves differently to the original IL\ntitle: ''\nlabels: Bug, Decompiler\nassignees: ''\n\n---\n\n### Input code\nPlease provide the input that failed to decompile.\nIf providing IL code as input, please provide enough context to allow us to re-assemble the IL.\nIf uploading a complete assembly, please mention which method failed to decompile.\n\n### Erroneous output\n```c#\nIf relevant, the incorrectly decompiled output, or an exception with stack trace.\n```\nIf the output fails to re-compile, provide the compiler error message.\nIf the output has the wrong behavior, explain how it differs from the expected behavior.\n\n### Details\n* Product in use: e.g. ILSpy / ICSharpCode.Decompiler nuget package / VS extension\n* Version in use: e.g. 6.0.0 or a commit hash (use Help>About to see which ILSpy version you are using)\n* Any other relevant information to the issue, or your interest in contributing a fix.\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "Link to issue(s) this covers\n\n### Problem\nLink to, or brief information about the issue\n\n### Solution\n* Any comments on the approach taken, its consistency with surrounding code, etc.\n* Which part of this PR is most in need of attention/improvement?\n* [ ] At least one test covering the code changed\n\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "# Set update schedule for GitHub Actions\n\nversion: 2\nupdates:\n\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      # Check for updates to GitHub Actions every weekday\n      interval: \"weekly\"\n"
  },
  {
    "path": ".github/workflows/build-frontends.yml",
    "content": "name: Build XPlat Frontends\n\non:\n  push:\n    branches: '**'\n  pull_request:\n    branches: [ master, release/** ]\n\npermissions:\n  contents: read\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v6\n      with:\n        fetch-depth: 0\n        persist-credentials: false\n        \n    - uses: actions/setup-dotnet@v5\n      with:\n        dotnet-version: '10.0.x'\n        dotnet-quality: 'preview'\n\n    - name: Install dependencies\n      run: dotnet restore ILSpy.XPlat.slnf -p:RestoreEnablePackagePruning=false\n\n    - name: Build Debug\n      run: dotnet msbuild ILSpy.XPlat.slnf -p:Configuration=Debug -bl:Debug.binlog\n\n    - name: Build Release\n      run: dotnet msbuild ILSpy.XPlat.slnf -p:Configuration=Release -bl:Release.binlog\n\n    - name: list files\n      if: always()\n      run: ls -la\n\n    - name: print VERSION\n      if: always()\n      run: cat VERSION\n\n    - name: Upload binlog\n      if: always()\n      uses: actions/upload-artifact@v7\n      with:\n        name: binlog\n        path: '**/*.binlog'\n        if-no-files-found: error\n"
  },
  {
    "path": ".github/workflows/build-ilspy.yml",
    "content": "name: Build ILSpy\n\non:\n  push:\n    branches: '**'\n  pull_request:\n    branches: [ master, release/** ]\n\npermissions:\n  contents: read\n\njobs:\n  Build:\n    permissions:\n      packages: write  # for dotnet nuget push\n    runs-on: windows-2025\n    strategy:\n      fail-fast: false\n      matrix:\n        Configuration: [ Debug, Release ]\n    env:\n      BuildPlatform: Any CPU\n      StagingDirectory: buildartifacts \n\n    steps:\n    - run: mkdir -p $env:StagingDirectory\n      \n\n    - uses: actions/checkout@v6\n      with:\n        submodules: true\n        fetch-depth: 0\n        persist-credentials: false\n\n    - uses: actions/setup-dotnet@v5\n      with:\n        dotnet-version: '10.0.x'\n        dotnet-quality: 'preview'\n      env:\n        DOTNET_INSTALL_DIR: ${{ runner.temp }}/.dotnet\n        DOTNET_ROOT: ${{ runner.temp }}/.dotnet\n\n    - name: Add msbuild to PATH\n      uses: microsoft/setup-msbuild@v2\n\n    - name: Install dotnet-format\n      env:\n        DOTNET_FORMAT_VERSION: 10.0.100-rtm.25531.102\n        DOTNET_FORMAT_SOURCE: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10-transport/nuget/v3/index.json\n      run: dotnet tool install -g dotnet-format --version \"${{env.DOTNET_FORMAT_VERSION}}\" --add-source \"${{env.DOTNET_FORMAT_SOURCE}}\"\n\n    - name: Install wix (locked version)\n      run: dotnet tool install --global wix --version 6.0.2\n      \n    - name: Install wix extesnion (locked version)\n      run: wix.exe extension add -g WixToolset.UI.wixext/6.0.2\n\n    - name: Get Version\n      id: version\n      shell: pwsh\n      run: |\n        .\\BuildTools\\ghactions-install.ps1\n        Get-ChildItem Env: | Where-Object {$_.Name -Match \"^ILSPY_\"} | %{ echo \"$($_.Name)=$($_.Value)\" } | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append\n\n    - name: Restore the application\n      run: msbuild ILSpy.sln /t:Restore /p:RestoreEnablePackagePruning=false /p:Configuration=${{ matrix.configuration }} /p:Platform=$env:BuildPlatform\n\n    - name: Build\n      run: msbuild ILSpy.sln /p:Configuration=${{ matrix.configuration }} /p:Platform=$env:BuildPlatform /m\n\n    - name: Format check\n      run: dotnet-format whitespace --verify-no-changes --verbosity detailed ILSpy.sln\n\n    - name: Execute unit tests\n      run: dotnet test --solution ilspy.sln --configuration ${{ matrix.configuration }} --no-build --report-trx --results-directory test-results/${{ matrix.configuration }}\n\n    - name: Upload Test Logs\n      uses: actions/upload-artifact@v7\n      if: success() || failure()\n      with:\n        name: test-results-${{ matrix.configuration }}\n        path: 'test-results/${{ matrix.configuration }}/*.trx'\n\n    - name: Create Test Report\n      uses: icsharpcode/test-summary-action@dist\n      if: always()\n      with:\n        paths: \"test-results/${{ matrix.configuration }}/*.trx\"\n        folded: true\n      \n    - name: Verify package contents\n      if: matrix.configuration == 'debug'\n      shell: pwsh\n      run: |\n        .\\BuildTools\\create-filelists.ps1\n        git diff --exit-code\n    \n    - name: Zip ILSpy (framework-dependent)\n      run: 7z a -tzip $env:StagingDirectory\\ILSpy_binaries.zip .\\ILSpy\\bin\\${{ matrix.configuration }}\\net10.0-windows\\*.dll .\\ILSpy\\bin\\${{ matrix.configuration }}\\net10.0-windows\\*.exe .\\ILSpy\\bin\\${{ matrix.configuration }}\\net10.0-windows\\*.config .\\ILSpy\\bin\\${{ matrix.configuration }}\\net10.0-windows\\*.json .\\ILSpy\\bin\\${{ matrix.configuration }}\\net10.0-windows\\*\\ILSpy.resources.dll .\\ILSpy\\bin\\${{ matrix.configuration }}\\net10.0-windows\\*\\ILSpy.ReadyToRun.Plugin.resources.dll\n\n    - name: Publish x64/arm64 framework-dependent/self-contained\n      shell: pwsh\n      run: .\\publish.ps1\n\n    - name: Zip ILSpy Release (x64 self-contained)\n      if: matrix.configuration == 'release'    \n      run: 7z a -tzip $env:StagingDirectory\\ILSpy_selfcontained_x64.zip .\\ILSpy\\bin\\Release\\net10.0-windows\\win-x64\\publish\\selfcontained\\*\n\n    - name: Zip ILSpy Release (arm64 framework-dependent)\n      if: matrix.configuration == 'release'    \n      run: 7z a -tzip $env:StagingDirectory\\ILSpy_binaries_arm64.zip .\\ILSpy\\bin\\Release\\net10.0-windows\\win-arm64\\publish\\fwdependent\\*\n\n    - name: Pack NuGets\n      if: matrix.configuration == 'release'\n      run: |\n        dotnet pack ICSharpCode.Decompiler --no-restore\n        dotnet pack ICSharpCode.BamlDecompiler --no-restore\n        dotnet pack ICSharpCode.ILSpyX --no-restore\n\n    - name: Build Installer (x64 and arm64, framework-dependent)\n      if: matrix.configuration == 'release'  \n      run: |\n        msbuild ILSpy.Installer.sln /t:Restore /p:Configuration=\"Release\" /p:Platform=\"Any CPU\"\n        msbuild ILSpy.Installer.sln /p:Configuration=\"Release\" /p:Platform=\"Any CPU\"\n        msbuild ILSpy.Installer.sln /p:Configuration=\"Release\" /p:Platform=\"Any CPU\" /p:PlatformForInstaller=\"ARM64\"\n\n    - name: Build VS Extensions (for 2017-2019 and 2022)\n      if: matrix.configuration == 'release'  \n      run: |\n        msbuild ILSpy.VSExtensions.sln /t:Restore /p:Configuration=\"Release\" /p:Platform=\"Any CPU\"\n        msbuild ILSpy.VSExtensions.sln /p:Configuration=\"Release\" /p:Platform=\"Any CPU\"\n\n    # https://github.com/actions/upload-artifact\n    - name: Upload VSIX (VS 2019) release build artifacts\n      if: matrix.configuration == 'release'\n      uses: actions/upload-artifact@v7\n      with:\n        name: ILSpy VS Addin for VS 2017-2019 ${{ steps.version.outputs.ILSPY_VERSION_NUMBER }} (${{ matrix.configuration }})\n        path: ILSpy.AddIn\\bin\\${{ matrix.configuration }}\\net472\\*.vsix\n        if-no-files-found: error\n\n    - name: Upload VSIX (VS 2022) release build artifacts\n      if: matrix.configuration == 'release'\n      uses: actions/upload-artifact@v7\n      with:\n        name: ILSpy VS Addin for VS 2022 ${{ steps.version.outputs.ILSPY_VERSION_NUMBER }} (${{ matrix.configuration }})\n        path: ILSpy.AddIn.VS2022\\bin\\${{ matrix.configuration }}\\net472\\*.vsix\n        if-no-files-found: error\n\n    - name: Upload Decompiler NuGet release build artifacts\n      if: matrix.configuration == 'release'\n      uses: actions/upload-artifact@v7\n      with:\n        name: ICSharpCode.Decompiler NuGet Package (${{ matrix.configuration }})\n        path: ICSharpCode.Decompiler\\bin\\Release\\ICSharpCode.Decompiler*.nupkg\n        if-no-files-found: error\n\n    - name: Publish Decompiler NuGet\n      if: github.ref == 'refs/heads/master' && matrix.configuration == 'release'\n      run: |\n        dotnet nuget push \"ICSharpCode.Decompiler\\bin\\Release\\ICSharpCode.Decompiler*.nupkg\" --api-key ${{ secrets.GITHUB_TOKEN }} --source https://nuget.pkg.github.com/${{ github.repository_owner }}\n\n    - name: Upload ILSpyX NuGet release build artifacts\n      if: matrix.configuration == 'release'\n      uses: actions/upload-artifact@v7\n      with:\n        name: ICSharpCode.ILSpyX NuGet Package (${{ matrix.configuration }})\n        path: ICSharpCode.ILSpyX\\bin\\Release\\ICSharpCode.ILSpyX*.nupkg\n        if-no-files-found: error\n\n    - name: Publish ILSpyX NuGet\n      if: github.ref == 'refs/heads/master' && matrix.configuration == 'release'\n      run: |\n        dotnet nuget push \"ICSharpCode.ILSpyX\\bin\\Release\\ICSharpCode.ILSpyX*.nupkg\" --api-key ${{ secrets.GITHUB_TOKEN }} --source https://nuget.pkg.github.com/${{ github.repository_owner }}\n\n    - name: Upload BamlDecompiler NuGet release build artifacts\n      if: matrix.configuration == 'release'\n      uses: actions/upload-artifact@v7\n      with:\n        name: ICSharpCode.BamlDecompiler NuGet Package (${{ matrix.configuration }})\n        path: ICSharpCode.BamlDecompiler\\bin\\Release\\ICSharpCode.BamlDecompiler*.nupkg\n        if-no-files-found: error\n\n    - name: Publish DecomBamlDecompilerpiler NuGet\n      if: github.ref == 'refs/heads/master' && matrix.configuration == 'release'\n      run: |\n        dotnet nuget push \"ICSharpCode.BamlDecompiler\\bin\\Release\\ICSharpCode.BamlDecompiler*.nupkg\" --api-key ${{ secrets.GITHUB_TOKEN }} --source https://nuget.pkg.github.com/${{ github.repository_owner }}\n\n    - name: Upload zip binaries build artifacts\n      uses: actions/upload-artifact@v7\n      with:\n        name: ILSpy ${{ steps.version.outputs.ILSPY_VERSION_NUMBER }} (${{ matrix.configuration }})\n        path: ${{ env.StagingDirectory }}\\ILSpy_binaries.zip\n        if-no-files-found: error\n\n    - name: Upload x64 self-contained zip (Release-only)\n      if: matrix.configuration == 'release'\n      uses: actions/upload-artifact@v7\n      with:\n        name: ILSpy self-contained x64 ${{ steps.version.outputs.ILSPY_VERSION_NUMBER }} (${{ matrix.configuration }})\n        path: ${{ env.StagingDirectory }}\\ILSpy_selfcontained_x64.zip\n        if-no-files-found: error\n\n    - name: Upload arm64 framework-dependent zip (Release-only)\n      if: matrix.configuration == 'release'\n      uses: actions/upload-artifact@v7\n      with:\n        name: ILSpy arm64 ${{ steps.version.outputs.ILSPY_VERSION_NUMBER }} (${{ matrix.configuration }})\n        path: ${{ env.StagingDirectory }}\\ILSpy_binaries_arm64.zip\n        if-no-files-found: error\n\n    - name: Upload x64 installer artifact\n      if: matrix.configuration == 'release'\n      uses: actions/upload-artifact@v7\n      with:\n        name: ILSpy Installer x64 ${{ steps.version.outputs.ILSPY_VERSION_NUMBER }} (${{ matrix.configuration }})\n        path: ILSpy.Installer\\wix\\*-x64.msi\n        if-no-files-found: error\n\n    - name: Upload arm64 installer artifact\n      if: matrix.configuration == 'release'\n      uses: actions/upload-artifact@v7\n      with:\n        name: ILSpy Installer arm64 ${{ steps.version.outputs.ILSPY_VERSION_NUMBER }} (${{ matrix.configuration }})\n        path: ILSpy.Installer\\wix\\*-arm64.msi\n        if-no-files-found: error\n\n    - name: Upload ilspycmd release build artifacts\n      if: matrix.configuration == 'release'\n      uses: actions/upload-artifact@v7\n      with:\n        name: ilspycmd dotnet tool (${{ matrix.configuration }})\n        path: ICSharpCode.ILSpyCmd\\bin\\Release\\ilspycmd*.nupkg\n        if-no-files-found: error\n"
  },
  {
    "path": ".github/workflows/codeql-analysis.yml",
    "content": "name: \"CodeQL\"\n\non:\n  push:\n    branches: '**'\n  pull_request:\n    branches: [ master, release/** ]\n\npermissions:\n  contents: read\n\njobs:\n  analyze:\n    permissions:\n      actions: read  # for github/codeql-action/init to get workflow details\n      security-events: write  # for github/codeql-action/analyze to upload SARIF results\n      \n    name: Analyze\n    runs-on: ubuntu-latest\n\n    strategy:\n      fail-fast: false\n      matrix:\n        language: [ 'csharp' ]\n\n    steps:\n    - name: Checkout repository\n      uses: actions/checkout@v6\n      with:\n        fetch-depth: 0\n        persist-credentials: false\n    \n    - name: Initialize CodeQL\n      uses: github/codeql-action/init@v4\n      with:\n        languages: ${{ matrix.language }}\n\n    - uses: actions/setup-dotnet@v5\n      with:\n        dotnet-version: '10.0.x'\n        dotnet-quality: 'preview'\n\n    - name: Build\n      run: dotnet build ILSpy.XPlat.slnf --configuration Release -p:RestoreEnablePackagePruning=false\n\n    - name: Perform CodeQL Analysis\n      uses: github/codeql-action/analyze@v4\n"
  },
  {
    "path": ".github/workflows/generate-bom.yml",
    "content": "name: Generate BOM\n\non:\n  workflow_dispatch:\n\npermissions:\n  contents: read\n\njobs:\n  build:\n\n    runs-on: windows-2022\n\n    steps:\n    - name: Checkout\n      run: git config --global core.autocrlf true\n    - uses: actions/checkout@v6\n      with:\n        submodules: true\n        persist-credentials: false\n\n    - name: Install CycloneDX\n      run: dotnet tool install --global CycloneDX\n      \n    - name: Analyze\n      run: dotnet-CycloneDX ILSpy/ILSpy.csproj --output sbom --recursive --exclude-dev --exclude-test-projects\n\n    - name: Upload BOM\n      uses: actions/upload-artifact@v7\n      with:\n        name: ILSpyBOM.xml\n        path: sbom/bom.xml\n        if-no-files-found: error"
  },
  {
    "path": ".github/workflows/lock.yml",
    "content": "name: 'Lock threads'\n\non:\n  schedule:\n    - cron: '0 0 * * *'\n\npermissions:\n  contents: read\n\njobs:\n  lock:\n    permissions:\n      issues: write  # for dessant/lock-threads to lock issues\n    runs-on: ubuntu-latest\n    steps:\n      - uses: dessant/lock-threads@v6.0.0\n        with:\n          github-token: ${{ github.token }}\n          issue-inactive-days: '90'\n          issue-lock-reason: 'resolved'\n          process-only: 'issues'\n"
  },
  {
    "path": ".github/workflows/scorecard.yml",
    "content": "name: Scorecard supply-chain security\n\non:\n  # For Branch-Protection check. Only the default branch is supported. See\n  # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection (disabled)\n  # branch_protection_rule:\n  workflow_dispatch:\n\n  # schedule (\"Maintained\") and push are disabled atm\n  # schedule:\n    # - cron: '25 1 * * 2'\n  # push:\n    # branches: [ \"master\" ]\n\npermissions: read-all\n\njobs:\n  analysis:\n    name: Scorecard analysis\n    runs-on: ubuntu-latest\n    permissions:\n      security-events: write # Needed to upload the results to code-scanning dashboard.\n      id-token: write # Needed to publish results and get a badge (see publish_results below).\n\n    steps:\n      - name: \"Checkout code\"\n        uses: actions/checkout@v6\n        with:\n          persist-credentials: false\n\n      - name: \"Run analysis\"\n        uses: ossf/scorecard-action@v2.4.3 # https://github.com/marketplace/actions/ossf-scorecard-action\n        with:\n          results_file: results.sarif\n          results_format: sarif\n          publish_results: true\n\n      - name: \"Upload artifact\"\n        uses: actions/upload-artifact@v7\n        with:\n          name: SARIF file\n          path: results.sarif\n          retention-days: 5\n\n      - name: \"Upload to code-scanning\"\n        uses: github/codeql-action/upload-sarif@v4\n        with:\n          sarif_file: results.sarif\n"
  },
  {
    "path": ".gitignore",
    "content": "bin/\nobj/\nAppPackages/\nBundleArtifacts/\n*.user\n/Resharper-ILSpy-Style.xml\n_ReSharper*/\n*.ReSharper\n*.patch\n.vs/\n.idea/\n/ILSpy.AddIn*/Packages/*\n/ILSpy.AddIn*/source.extension.vsixmanifest\n/ICSharpCode.Decompiler.Tests/TestCases/Disassembler/Pretty/*.dll\n/ICSharpCode.Decompiler.Tests/TestCases/Disassembler/Pretty/*.result.il\n/ICSharpCode.Decompiler.Tests/TestCases/Correctness/*.exe\n/ICSharpCode.Decompiler.Tests/TestCases/Correctness/*.exe.config\nmultitargeting.props\nILSpy.Installer/wix/\n/VERSION\n/ICSharpCode.Decompiler/Properties/DecompilerVersionInfo.cs\n**/.vscode/\nDecompilerTests.config.json\n*.trx"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"ILSpy-tests\"]\n\tpath = ILSpy-tests\n\turl = https://github.com/icsharpcode/ILSpy-tests\n\tbranch = master\n"
  },
  {
    "path": ".tgitconfig",
    "content": "[tgit]\n\ticon = ILSpy/Images/ILSpy.ico\n"
  },
  {
    "path": "BuildTools/ILSpy.AddIn.VS2022.vsix.filelist",
    "content": "[Content_Types].xml\ncatalog.json\nen-US\\ILSpy.AddIn.VS2022.resources.dll\nextension.vsixmanifest\nICSharpCode.Decompiler.dll\nICSharpCode.ILSpyX.dll\nICSharpCode.TreeView.dll\nILSpy.AddIn.VS2022.dll\nILSpy.AddIn.VS2022.pkgdef\nILSpy.BamlDecompiler.Plugin.dll\nILSpy.deps.json\nILSpy.dll\nILSpy.exe\nILSpy.ReadyToRun.Plugin.dll\nILSpy.runtimeconfig.json\nILSpy\\AvalonDock.dll\nILSpy\\AvalonDock.Themes.VS2013.dll\nILSpy\\DataGridExtensions.dll\nILSpy\\Iced.dll\nILSpy\\ICSharpCode.AvalonEdit.dll\nILSpy\\ICSharpCode.Decompiler.dll\nILSpy\\ICSharpCode.ILSpyX.dll\nILSpy\\ICSharpCode.TreeView.dll\nILSpy\\ILCompiler.Reflection.ReadyToRun.dll\nILSpy\\ILSpy.BamlDecompiler.Plugin.deps.json\nILSpy\\ILSpy.BamlDecompiler.Plugin.dll\nILSpy\\ILSpy.deps.json\nILSpy\\ILSpy.dll\nILSpy\\ILSpy.exe\nILSpy\\ILSpy.ReadyToRun.Plugin.deps.json\nILSpy\\ILSpy.ReadyToRun.Plugin.dll\nILSpy\\ILSpy.runtimeconfig.json\nILSpy\\K4os.Compression.LZ4.dll\nILSpy\\Microsoft.DiaSymReader.Converter.Xml.dll\nILSpy\\Microsoft.DiaSymReader.dll\nILSpy\\Microsoft.DiaSymReader.PortablePdb.dll\nILSpy\\Microsoft.VisualStudio.Composition.dll\nILSpy\\Microsoft.VisualStudio.Composition.NetFxAttributes.dll\nILSpy\\Microsoft.VisualStudio.Validation.dll\nILSpy\\Microsoft.Xaml.Behaviors.dll\nILSpy\\Mono.Cecil.dll\nILSpy\\Mono.Cecil.Mdb.dll\nILSpy\\Mono.Cecil.Pdb.dll\nILSpy\\Mono.Cecil.Rocks.dll\nILSpy\\System.ComponentModel.Composition.dll\nILSpy\\System.Composition.AttributedModel.dll\nILSpy\\System.Composition.Convention.dll\nILSpy\\System.Composition.Hosting.dll\nILSpy\\System.Composition.Runtime.dll\nILSpy\\System.Composition.TypedParts.dll\nILSpy\\TomsToolbox.Essentials.dll\nILSpy\\TomsToolbox.ObservableCollections.dll\nILSpy\\TomsToolbox.Wpf.dll\nILSpy\\TomsToolbox.Wpf.Styles.dll\nILSpy-Large.ico\nlicense.txt\nmanifest.json\nMono.Cecil.dll"
  },
  {
    "path": "BuildTools/ILSpy.AddIn.vsix.filelist",
    "content": "[Content_Types].xml\ncatalog.json\nen-US\\ILSpy.AddIn.resources.dll\nextension.vsixmanifest\nICSharpCode.Decompiler.dll\nICSharpCode.ILSpyX.dll\nICSharpCode.TreeView.dll\nILSpy.AddIn.dll\nILSpy.AddIn.pkgdef\nILSpy.BamlDecompiler.Plugin.dll\nILSpy.deps.json\nILSpy.dll\nILSpy.exe\nILSpy.ReadyToRun.Plugin.dll\nILSpy.runtimeconfig.json\nILSpy\\AvalonDock.dll\nILSpy\\AvalonDock.Themes.VS2013.dll\nILSpy\\DataGridExtensions.dll\nILSpy\\Iced.dll\nILSpy\\ICSharpCode.AvalonEdit.dll\nILSpy\\ICSharpCode.Decompiler.dll\nILSpy\\ICSharpCode.ILSpyX.dll\nILSpy\\ICSharpCode.TreeView.dll\nILSpy\\ILCompiler.Reflection.ReadyToRun.dll\nILSpy\\ILSpy.BamlDecompiler.Plugin.deps.json\nILSpy\\ILSpy.BamlDecompiler.Plugin.dll\nILSpy\\ILSpy.deps.json\nILSpy\\ILSpy.dll\nILSpy\\ILSpy.exe\nILSpy\\ILSpy.ReadyToRun.Plugin.deps.json\nILSpy\\ILSpy.ReadyToRun.Plugin.dll\nILSpy\\ILSpy.runtimeconfig.json\nILSpy\\K4os.Compression.LZ4.dll\nILSpy\\Microsoft.DiaSymReader.Converter.Xml.dll\nILSpy\\Microsoft.DiaSymReader.dll\nILSpy\\Microsoft.DiaSymReader.PortablePdb.dll\nILSpy\\Microsoft.VisualStudio.Composition.dll\nILSpy\\Microsoft.VisualStudio.Composition.NetFxAttributes.dll\nILSpy\\Microsoft.VisualStudio.Validation.dll\nILSpy\\Microsoft.Xaml.Behaviors.dll\nILSpy\\Mono.Cecil.dll\nILSpy\\Mono.Cecil.Mdb.dll\nILSpy\\Mono.Cecil.Pdb.dll\nILSpy\\Mono.Cecil.Rocks.dll\nILSpy\\System.ComponentModel.Composition.dll\nILSpy\\System.Composition.AttributedModel.dll\nILSpy\\System.Composition.Convention.dll\nILSpy\\System.Composition.Hosting.dll\nILSpy\\System.Composition.Runtime.dll\nILSpy\\System.Composition.TypedParts.dll\nILSpy\\TomsToolbox.Essentials.dll\nILSpy\\TomsToolbox.ObservableCollections.dll\nILSpy\\TomsToolbox.Wpf.dll\nILSpy\\TomsToolbox.Wpf.Styles.dll\nILSpy-Large.ico\nlicense.txt\nmanifest.json\nMono.Cecil.dll"
  },
  {
    "path": "BuildTools/ILSpy.msi.filelist",
    "content": "AvalonDock.dll_2384574099\nAvalonDock.Themes.VS2013.dll_1693991188\nDataGridExtensions.dll_3175011569\nIced.dll_3795180016\nICSharpCode.AvalonEdit.dll_2202357673\nICSharpCode.Decompiler.dll_1302002478\nICSharpCode.ILSpyX.dll_1982182100\nICSharpCode.TreeView.dll_128291808\nILCompiler.Reflection.ReadyToRun.dll_961256598\nILSpy.BamlDecompiler.Plugin.deps.json_425274809\nILSpy.BamlDecompiler.Plugin.dll_1186184332\nILSpy.deps.json_14220630\nILSpy.dll_828718029\nILSpy.exe_2512527281\nILSpy.ReadyToRun.Plugin.deps.json_3602879258\nILSpy.ReadyToRun.Plugin.dll_3493023742\nILSpy.ReadyToRun.Plugin.resources.dll_3072497650\nILSpy.resources.dll_1963394151\nILSpy.runtimeconfig.json_4170109836\nK4os.Compression.LZ4.dll_841780051\nMicrosoft.DiaSymReader.Converter.Xml.dll_1504543009\nMicrosoft.DiaSymReader.dll_2664270437\nMicrosoft.DiaSymReader.PortablePdb.dll_645824024\nMicrosoft.VisualStudio.Composition.dll_3669554833\nMicrosoft.VisualStudio.Composition.NetFxAttributes.dll_4085550965\nMicrosoft.VisualStudio.Validation.dll_3370943218\nMicrosoft.Xaml.Behaviors.dll_3088279542\nMono.Cecil.dll_2043069113\nMono.Cecil.Mdb.dll_881308441\nMono.Cecil.Pdb.dll_94684032\nMono.Cecil.Rocks.dll_284129705\nSystem.ComponentModel.Composition.dll_3956562358\nSystem.Composition.AttributedModel.dll_2731655713\nSystem.Composition.Convention.dll_1880631244\nSystem.Composition.Hosting.dll_1479266732\nSystem.Composition.Runtime.dll_4043919224\nSystem.Composition.TypedParts.dll_1680333710\nTomsToolbox.Essentials.dll_1205939788\nTomsToolbox.ObservableCollections.dll_75279310\nTomsToolbox.Wpf.dll_28003915\nTomsToolbox.Wpf.Styles.dll_1483228554\n"
  },
  {
    "path": "BuildTools/bom-classify-encodings.ps1",
    "content": "<#\n.SYNOPSIS\nClassify text files by encoding under the current subtree, respecting .gitignore.\n\n.DESCRIPTION\nEnumerates tracked files and untracked-but-not-ignored files (via Git) beneath\nPWD. Skips likely-binary files (NUL probe). Classifies remaining files as:\n\t- 'utf8'          : valid UTF-8 (no BOM) or empty file\n\t- 'utf8-with-bom' : starts with UTF-8 BOM (EF BB BF)\n\t- 'other'         : text but not valid UTF-8 (e.g., UTF-16/ANSI)\n\nOutputs:\n\t1) Relative paths of files classified as 'other'\n\t2) A table by extension: UTF8 / UTF8-with-BOM / Other / Total\n\nNotes:\n\t- Read-only: this script makes no changes.\n\t- Requires Git and must be run inside a Git work tree.\n#>\n\n[CmdletBinding()]\nparam()\n\nSet-StrictMode -Version Latest\n$ErrorActionPreference = 'Stop'\n\n# --- Git enumeration ---------------------------------------------------------\nfunction Assert-InGitWorkTree {\n\t# Throws if not inside a Git work tree.\n\t$inside = (& git rev-parse --is-inside-work-tree 2>$null).Trim()\n\tif ($LASTEXITCODE -ne 0 -or $inside -ne 'true') {\n\t\tthrow 'Not in a Git work tree.'\n\t}\n}\n\nfunction Get-GitFilesUnderPwd {\n\t<#\n\t\tReturns full paths to tracked + untracked-not-ignored files under PWD.\n\t#>\n\tAssert-InGitWorkTree\n\n\t$repoRoot = (& git rev-parse --show-toplevel).Trim()\n\t$pwdPath  = (Get-Location).Path\n\n\t# cached (tracked) + others (untracked not ignored)\n\t$nulSeparated = & git -C $repoRoot ls-files -z --cached --others --exclude-standard\n\n\t$relativePaths = $nulSeparated.Split(\n\t\t[char]0, [System.StringSplitOptions]::RemoveEmptyEntries)\n\n\tforeach ($relPath in $relativePaths) {\n\t\t$fullPath = Join-Path $repoRoot $relPath\n\n\t\t# Only include files under the current subtree.\n\t\tif ($fullPath.StartsWith($pwdPath,\n\t\t\t\t[System.StringComparison]::OrdinalIgnoreCase)) {\n\t\t\tif (Test-Path -LiteralPath $fullPath -PathType Leaf) { $fullPath }\n\t\t}\n\t}\n}\n\n# --- Probes ------------------------------------------------------------------\nfunction Test-ProbablyBinary {\n\t# Heuristic: treat as binary if the first 8 KiB contains any NUL byte.\n\tparam([Parameter(Mandatory)][string]$Path)\n\n\ttry {\n\t\t$stream = [System.IO.File]::Open($Path,'Open','Read','ReadWrite')\n\t\ttry {\n\t\t\t$len = [int][Math]::Min(8192,$stream.Length)\n\t\t\tif ($len -le 0) { return $false }\n\n\t\t\t$buffer = [byte[]]::new($len)\n\t\t\t[void]$stream.Read($buffer,0,$len)\n\t\t\treturn ($buffer -contains 0)\n\t\t}\n\t\tfinally { $stream.Dispose() }\n\t}\n\tcatch { return $false }\n}\n\nfunction Get-TextEncodingCategory {\n\t# Returns 'utf8', 'utf8-with-bom', 'other', or $null for likely-binary.\n\tparam([Parameter(Mandatory)][string]$Path)\n\n\t$stream = [System.IO.File]::Open($Path,'Open','Read','ReadWrite')\n\ttry {\n\t\t$fileLength = $stream.Length\n\t\tif ($fileLength -eq 0) { return 'utf8' }\n\n\t\t# BOM check (EF BB BF)\n\t\t$header = [byte[]]::new([Math]::Min(3,$fileLength))\n\t\t[void]$stream.Read($header,0,$header.Length)\n\t\tif ($header.Length -ge 3 -and\n\t\t\t\t$header[0] -eq 0xEF -and $header[1] -eq 0xBB -and $header[2] -eq 0xBF) {\n\t\t\treturn 'utf8-with-bom'\n\t\t}\n\n\t\t# Quick binary probe before expensive decoding\n\t\t$stream.Position = 0\n\t\t$sampleLen = [int][Math]::Min(8192,$fileLength)\n\t\t$sample = [byte[]]::new($sampleLen)\n\t\t[void]$stream.Read($sample,0,$sampleLen)\n\t\tif ($sample -contains 0) { return $null }\n\t}\n\tfinally { $stream.Dispose() }\n\n\t# Validate UTF-8 by decoding with throw-on-invalid option (no BOM).\n\ttry {\n\t\t$bytes = [System.IO.File]::ReadAllBytes($Path)\n\t\t$utf8 = [System.Text.UTF8Encoding]::new($false,$true)\n\t\t[void]$utf8.GetString($bytes)\n\t\treturn 'utf8'\n\t}\n\tcatch { return 'other' }\n}\n\n# --- Main --------------------------------------------------------------------\n$otherFiles  = @()\n$byExtension = @{}\n\n$allFiles = Get-GitFilesUnderPwd\n\nforeach ($fullPath in $allFiles) {\n\t# Avoid decoding likely-binary files.\n\tif (Test-ProbablyBinary $fullPath) { continue }\n\n\t$category = Get-TextEncodingCategory $fullPath\n\tif (-not $category) { continue }\n\n\t$ext = [IO.Path]::GetExtension($fullPath).ToLower()\n\tif (-not $byExtension.ContainsKey($ext)) {\n\t\t$byExtension[$ext] = @{ 'utf8' = 0; 'utf8-with-bom' = 0; 'other' = 0 }\n\t}\n\n\t$byExtension[$ext][$category]++\n\n\tif ($category -eq 'other') {\n\t\t$otherFiles += (Resolve-Path -LiteralPath $fullPath -Relative)\n\t}\n}\n\n# 1) Files in 'other'\nif ($otherFiles.Count -gt 0) {\n\t'Files classified as ''other'':'\n\t$otherFiles | Sort-Object | ForEach-Object { \"  $_\" }\n\t''\n}\n\n# 2) Table by extension\n$rows = foreach ($kv in $byExtension.GetEnumerator()) {\n\t$ext = if ($kv.Key) { $kv.Key } else { '[noext]' }\n\t$u   = [int]$kv.Value['utf8']\n\t$b   = [int]$kv.Value['utf8-with-bom']\n\t$o   = [int]$kv.Value['other']\n\n\t[PSCustomObject]@{\n\t\tExtension       = $ext\n\t\tUTF8            = $u\n\t\t'UTF8-with-BOM' = $b\n\t\tOther           = $o\n\t\tTotal           = $u + $b + $o\n\t}\n}\n\n$rows |\n\tSort-Object -Property (\n\t\t\t@{Expression='Total';Descending=$true},\n\t\t@{Expression='Extension';Descending=$false}\n\t) |\n\tFormat-Table -AutoSize\n"
  },
  {
    "path": "BuildTools/bom-strip.ps1",
    "content": "<#\n.SYNOPSIS\nStrip UTF-8 BOM from selected text files under the current subtree, respecting\n.gitignore.\n\n.DESCRIPTION\nEnumerates tracked and untracked-but-not-ignored files under the current\ndirectory (via Git), filters to texty extensions and dotfiles, skips likely\nbinary files (NUL probe), and removes a leading UTF-8 BOM (EF BB BF) in place.\n\nRefuses to run if there are uncommitted changes as a safeguard. Use -Force to override.\nSupports -WhatIf/-Confirm via ShouldProcess.\n#>\n\n[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')]\nparam(\n\t[switch]$Force\n)\n\nSet-StrictMode -Version Latest\n$ErrorActionPreference = 'Stop'\n\n# --- File sets (ILSpy) ------------------------------------------------------\n$Dotfiles = @(\n\t'.gitignore', '.editorconfig', '.gitattributes', '.gitmodules',\n\t'.tgitconfig', '.vsconfig'\n)\n\n$AllowedExts = @(\n\t'.bat','.config','.cs','.csproj','.css','.filelist','.fs','.html','.il',\n\t'.ipynb','.js','.json','.less','.manifest','.md','.projitems','.props',\n\t'.ps1','.psd1','.shproj','.sln','.slnf','.svg','.template',\n\t'.tt', '.txt','.vb','.vsct','.vsixlangpack','.wxl','.xaml','.xml','.xshd','.yml'\n)\n\n$IncludeNoExt = $true  # include names like LICENSE\n\n# --- Git checks / enumeration -----------------------------------------------\nfunction Assert-InGitWorkTree {\n\t$inside = (& git rev-parse --is-inside-work-tree 2>$null).Trim()\n\tif ($LASTEXITCODE -ne 0 -or $inside -ne 'true') {\n\t\tthrow 'Not in a Git work tree.'\n\t}\n}\n\nfunction Assert-CleanWorkingTree {\n\tif ($Force) { return }\n\n\t$status = & git status --porcelain -z\n\tif ($LASTEXITCODE -ne 0) { throw 'git status failed.' }\n\n\tif (-not [string]::IsNullOrEmpty($status)) {\n\t\tthrow 'Working tree not clean. Commit/stash changes or use -Force.'\n\t}\n}\n\nfunction Get-GitFilesUnderPwd {\n\tAssert-InGitWorkTree\n\n\t$repoRoot = (& git rev-parse --show-toplevel).Trim()\n\t$pwdPath  = (Get-Location).Path\n\n\t$tracked = & git -C $repoRoot ls-files -z\n\t$others  = & git -C $repoRoot ls-files --others --exclude-standard -z\n\n\t$allRel = (\"$tracked$others\").Split(\n\t\t[char]0, [System.StringSplitOptions]::RemoveEmptyEntries)\n\n\tforeach ($relPath in $allRel) {\n\t\t$fullPath = Join-Path $repoRoot $relPath\n\t\tif ($fullPath.StartsWith($pwdPath,\n\t\t\t\t[System.StringComparison]::OrdinalIgnoreCase)) {\n\t\t\tif (Test-Path -LiteralPath $fullPath -PathType Leaf) {\n\t\t\t\t$fullPath\n\t\t\t}\n\t\t}\n\t}\n}\n\n# --- Probes -----------------------------------------------------------------\nfunction Test-HasUtf8Bom {\n\tparam([Parameter(Mandatory)][string]$Path)\n\n\ttry {\n\t\t$stream = [System.IO.File]::Open($Path,'Open','Read','ReadWrite')\n\t\ttry {\n\t\t\tif ($stream.Length -lt 3) { return $false }\n\n\t\t\t$header = [byte[]]::new(3)\n\t\t\t[void]$stream.Read($header,0,3)\n\n\t\t\treturn ($header[0] -eq 0xEF -and\n\t\t\t\t\t\t\t$header[1] -eq 0xBB -and\n\t\t\t\t\t\t\t$header[2] -eq 0xBF)\n\t\t}\n\t\tfinally {\n\t\t\t$stream.Dispose()\n\t\t}\n\t}\n\tcatch { return $false }\n}\n\nfunction Test-ProbablyBinary {\n\t# Binary if the first 8 KiB contains any NUL byte.\n\tparam([Parameter(Mandatory)][string]$Path)\n\n\ttry {\n\t\t$stream = [System.IO.File]::Open($Path,'Open','Read','ReadWrite')\n\t\ttry {\n\t\t\t$len = [int][Math]::Min(8192,$stream.Length)\n\t\t\tif ($len -le 0) { return $false }\n\n\t\t\t$buffer = [byte[]]::new($len)\n\t\t\t[void]$stream.Read($buffer,0,$len)\n\n\t\t\treturn ($buffer -contains 0)\n\t\t}\n\t\tfinally {\n\t\t\t$stream.Dispose()\n\t\t}\n\t}\n\tcatch { return $false }\n}\n\n# --- Mutation ---------------------------------------------------------------\nfunction Remove-Utf8BomInPlace {\n\t# Write the existing buffer from offset 3, no extra full-size allocation.\n\tparam([Parameter(Mandatory)][string]$Path)\n\n\t$bytes = [System.IO.File]::ReadAllBytes($Path)\n\tif ($bytes.Length -lt 3) { return $false }\n\n\tif ($bytes[0] -ne 0xEF -or\n\t\t\t$bytes[1] -ne 0xBB -or\n\t\t\t$bytes[2] -ne 0xBF) {\n\t\treturn $false\n\t}\n\n\t$stream = [System.IO.File]::Open($Path,'Create','Write','ReadWrite')\n\ttry {\n\t\t$stream.Write($bytes, 3, $bytes.Length - 3)\n\t\t$stream.SetLength($bytes.Length - 3)\n\t}\n\tfinally {\n\t\t$stream.Dispose()\n\t}\n\n\treturn $true\n}\n\n# --- Main -------------------------------------------------------------------\nAssert-InGitWorkTree\nAssert-CleanWorkingTree\n\n$allFiles = Get-GitFilesUnderPwd\n\n$targets = $allFiles | % {\n\t$fileName = [IO.Path]::GetFileName($_)\n\t$ext      = [IO.Path]::GetExtension($fileName)\n\n\t$isDot    = $Dotfiles -contains $fileName\n\t$isNoExt  = -not $fileName.Contains('.')\n\n\tif ($isDot -or ($AllowedExts -contains $ext) -or\n\t\t\t($IncludeNoExt -and $isNoExt -and -not $isDot)) {\n\t\t$_\n\t}\n}\n| ? { Test-HasUtf8Bom $_ }\n| ? { -not (Test-ProbablyBinary $_) }\n\n$changed        = 0\n$byExtension    = @{}\n$dotfileChanges = 0\n\n$targets | % {\n\t$relative = Resolve-Path -LiteralPath $_ -Relative\n\n\tif ($PSCmdlet.ShouldProcess($relative,'Strip UTF-8 BOM')) {\n\t\tif (Remove-Utf8BomInPlace -Path $_) {\n\t\t\t$changed++\n\n\t\t\t$fileName = [IO.Path]::GetFileName($_)\n\t\t\tif ($Dotfiles -contains $fileName) { $dotfileChanges++ }\n\n\t\t\t$ext = [IO.Path]::GetExtension($fileName)\n\t\t\tif (-not $byExtension.ContainsKey($ext)) { $byExtension[$ext] = 0 }\n\t\t\t$byExtension[$ext]++\n\n\t\t\t\"stripped BOM: $relative\"\n\t\t}\n\t}\n}\n\n\"Done. Stripped BOM from $changed file(s).\"\n\nif ($byExtension.Keys.Count -gt 0) {\n\t\"\"\n\t\"By extension:\"\n\t$byExtension.GetEnumerator() | Sort-Object Name | % {\n\t\t$key = if ([string]::IsNullOrEmpty($_.Name)) { '[noext]' } else { $_.Name }\n\t\t\"  {0}: {1}\" -f $key, $_.Value\n\t}\n}\n\nif ($dotfileChanges -gt 0) {\n\t\"  [dotfiles]: $dotfileChanges\"\n}\n"
  },
  {
    "path": "BuildTools/create-filelists.ps1",
    "content": "$ErrorActionPreference = \"Stop\";\n\n$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False\n\ngci -Include *.vsix, *.msi -recurse | foreach ($_) {\n\tif (-not ($_.FullName -contains \"\\bin\\Debug\\\")) {\n\t\tcontinue;\n\t}\n\t$idx=-1;\n\t$body=$false;\n\t$outputFileName = \".\\BuildTools\\$($_.Name -replace '-\\d+\\.\\d+\\.\\d+\\.\\d+', '').filelist\";\n\t$lines = 7z l $_.FullName  | foreach {\n\t\tif ($idx -eq -1) {\n\t\t\t$idx = $_.IndexOf(\"Name\");\n\t\t}\n\t\t$p = $body;\n\t\tif ($idx -gt 0) {\n\t\t\t$body = ($body -ne ($_ -match ' *-[ -]+'))\n\t\t}\n\t\tif ($p -and $body) {\n\t\t\t$_.Substring($idx)\n\t\t}\n\t} | sort\n\t[System.IO.File]::WriteAllLines($outputFileName, $lines, $Utf8NoBomEncoding)\n}\n"
  },
  {
    "path": "BuildTools/format.bat",
    "content": "@rem This file can be used to trigger the commit hook's formatting,\n@rem modifying the local formatting even if not committing all changes.\npushd %~dp0\\..\n\"%ProgramFiles%\\Git\\usr\\bin\\bash.exe\" BuildTools\\pre-commit --format\npopd"
  },
  {
    "path": "BuildTools/ghactions-install.ps1",
    "content": "$ErrorActionPreference = \"Stop\"\n\n$baseCommit = \"d779383cb85003d6dabeb976f0845631e07bf463\";\n$baseCommitRev = 1;\n\n# make sure this matches artifacts-only branches list in appveyor.yml!\n$masterBranches = '^refs/heads/(master|release/.+)$';\n\n$decompilerVersionInfoTemplateFile = \"ICSharpCode.Decompiler/Properties/DecompilerVersionInfo.template.cs\";\n\n$versionParts = @{};\nGet-Content $decompilerVersionInfoTemplateFile | where { $_ -match 'string (\\w+) = \"?(\\w+)\"?;' } | foreach { $versionParts.Add($Matches[1], $Matches[2]) }\n\n$major = $versionParts.Major;\n$minor = $versionParts.Minor;\n$build = $versionParts.Build;\n$versionName = $versionParts.VersionName;\n\nif ($versionName -ne \"null\") {\n\t$versionName = \"-$versionName\";\n} else {\n\t$versionName = \"\";\n}\n\nWrite-Host \"GITHUB_REF: '$env:GITHUB_REF'\";\n\nif ($env:GITHUB_REF -match $masterBranches) {\n\t$branch = \"\";\n\t$suffix = \"\";\n} elseif ($env:GITHUB_REF -match '^refs/pull/(\\d+)/merge$') {\n\t$branch = \"\";\n\t$suffix = \"-pr\" + $Matches[1];\n} elseif ($env:GITHUB_REF -match '^refs/heads/(.+)$') {\n\t$branch = \"-\" + $Matches[1];\n\t$suffix = \"\";\n} else {\n\t$branch = \"\";\n\t$suffix = \"\";\n}\n\n$revision = [Int32]::Parse((git rev-list --count \"$baseCommit..HEAD\")) + $baseCommitRev;\n\n$newVersion=\"$major.$minor.$build.$revision\";\n$ilspyVersionNumber = \"$newVersion$branch$versionName$suffix\";\n$ilspyVersionNumber = $ilspyVersionNumber.Replace(\"/\", \"-\");\n$env:ILSPY_VERSION_NUMBER=\"$ilspyVersionNumber\";\n$env:ILSPY_VERSION_NUMBER | Out-File \"ILSPY_VERSION\"\nWrite-Host \"new version: $ilspyVersionNumber\";\n"
  },
  {
    "path": "BuildTools/pre-commit",
    "content": "#!/bin/sh\n#\n# To enable this hook, copy/symlink this file to \".git/hooks/pre-commit\".\n#  mklink .git\\hooks\\pre-commit ..\\..\\BuildTools\\pre-commit\n\nset -eu\n\nDOTNET_FORMAT_VERSION=10.0.100-rtm.25531.102\nDOTNET_FORMAT_SOURCE=\"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10-transport/nuget/v3/index.json\"\nDOTNET_PATH=\"$LOCALAPPDATA/ICSharpCode/ILSpy/dotnet-format-$DOTNET_FORMAT_VERSION\"\nif [ ! -d \"$DOTNET_PATH\" ]; then\n echo \"Downloading dotnet-format $DOTNET_FORMAT_VERSION...\"\n dotnet tool install --tool-path \"$DOTNET_PATH\" dotnet-format --version \"$DOTNET_FORMAT_VERSION\" --add-source \"$DOTNET_FORMAT_SOURCE\"\nfi\n\n\"$DOTNET_PATH/dotnet-format.exe\" --version\nif [ \"${1:-}\" = \"--format\" ]; then\n\t# called via format.bat\n\t\"$DOTNET_PATH/dotnet-format.exe\" whitespace --no-restore --verbosity detailed ILSpy.sln\nelif git diff --quiet --ignore-submodules; then\n\t\"$DOTNET_PATH/dotnet-format.exe\" whitespace --no-restore --verbosity detailed ILSpy.sln\n\tgit add -u -- \\*\\*.cs\nelse\n\techo Partial commit: only verifying formatting\n\texec \"$DOTNET_PATH/dotnet-format.exe\" whitespace --verify-no-changes --no-restore --verbosity detailed ILSpy.sln\nfi\n"
  },
  {
    "path": "BuildTools/sort-resx.ps1",
    "content": "$ErrorActionPreference = \"Stop\";\n\n[Reflection.Assembly]::LoadWithPartialName(\"System.Xml.Linq\") | Out-Null\n\nWrite-Host \"Sorting .resx files...\";\n\nGet-ChildItem -Include *.resx -Recurse | foreach ($_) {\n\tWrite-Host $_.FullName;\n\t\n\t$doc = [System.Xml.Linq.XDocument]::Load($_.FullName);\n\t$descendants = [System.Linq.Enumerable]::ToArray($doc.Descendants(\"data\"));\n\n\t[System.Xml.Linq.Extensions]::Remove($descendants);\n\t$ordered = [System.Linq.Enumerable]::OrderBy($descendants, [System.Func[System.Xml.Linq.XElement,string]] { param ($e) $e.Attribute(\"name\").Value }, [System.StringComparer]::Ordinal);\n\t$doc.Root.Add($ordered);\n\t$doc.Save($_.FullName);\n}\n\n"
  },
  {
    "path": "BuildTools/update-assemblyinfo.ps1",
    "content": "if (-not ($PSVersionTable.PSCompatibleVersions -contains \"5.0\")) {\n\tWrite-Error \"This script requires at least powershell version 5.0!\";\n\treturn 255;\n}\n\n$ErrorActionPreference = \"Stop\"\n\n$baseCommit = \"d779383cb85003d6dabeb976f0845631e07bf463\";\n$baseCommitRev = 1;\n\n# make sure this matches artifacts-only branches list in appveyor.yml!\n$masterBranches = '^(master|release/.+)$';\n\n$decompilerVersionInfoTemplateFile = \"ICSharpCode.Decompiler/Properties/DecompilerVersionInfo.template.cs\";\n\nfunction Test-File([string]$filename) {\n\treturn [System.IO.File]::Exists((Join-Path (Get-Location) $filename));\n}\n\nfunction Test-Dir([string]$name) {\n\treturn [System.IO.Directory]::Exists((Join-Path (Get-Location) $name));\n}\n\nfunction Find-Git() {\n\ttry {\n\t\t$executable = (get-command git).Path;\n\t\treturn $executable -ne $null;\n\t} catch {\n\t\t#git not found in path, continue;\n\t}\n\t#we're on Windows\n\tif ($env:PROGRAMFILES -ne $null) {\n\t\t#hack for x86 powershell used by default (yuck!)\n\t\tif (${env:PROGRAMFILES(X86)} -eq ${env:PROGRAMFILES}) {\n\t\t\t$env:PROGRAMFILES = $env:PROGRAMFILES.Substring(0, $env:PROGRAMFILES.Length - 6);\n\t\t}\n\t\t#try to add git to path\n\t\tif ([System.IO.Directory]::Exists(\"$env:PROGRAMFILES\\git\\cmd\\\")) {\n\t\t\t$env:PATH = \"$env:PATH;$env:PROGRAMFILES\\git\\cmd\\\";\n\t\t\treturn $true;\n\t\t}\n\t}\n\treturn $false;\n}\n\nfunction No-Git() {\n\treturn -not (((Test-Dir \".git\") -or (Test-File \".git\")) -and (Find-Git));\n}\n\nfunction gitVersion() {\n\tif (No-Git) {\n\t\treturn 0;\n\t}\n\ttry {\n\t\treturn [Int32]::Parse((git rev-list --count \"$baseCommit..HEAD\" 2>&1 | Tee-Object -Variable cmdOutput)) + $baseCommitRev;\n\t} catch {\n\t\tWrite-Host $cmdOutput\n\t\treturn 0;\n\t}\n}\n\nfunction gitCommitHash() {\n\tif (No-Git) {\n\t\treturn \"0000000000000000000000000000000000000000\";\n\t}\n\ttry {\n\t\treturn (git rev-list --max-count 1 HEAD 2>&1 | Tee-Object -Variable cmdOutput);\n\t} catch {\n\t\tWrite-Host $cmdOutput\n\t\treturn \"0000000000000000000000000000000000000000\";\n\t}\n}\n\nfunction gitShortCommitHash() {\n\tif (No-Git) {\n\t\treturn \"00000000\";\n\t}\n\ttry {\n\t\treturn (git rev-parse --short=8 (git rev-list --max-count 1 HEAD 2>&1 | Tee-Object -Variable cmdOutput) 2>&1 | Tee-Object -Variable cmdOutput);\n\t} catch {\n\t\tWrite-Host $cmdOutput\n\t\treturn \"00000000\";\n\t}\t\n}\n\nfunction gitBranch() {\n\tif (No-Git) {\n\t\treturn \"no-branch\";\n\t}\n\n\tif ($env:APPVEYOR_REPO_BRANCH -ne $null) {\n\t\treturn $env:APPVEYOR_REPO_BRANCH;\n\t} elseif ($env:BUILD_SOURCEBRANCHNAME -ne $null) {\n\t\treturn $env:BUILD_SOURCEBRANCHNAME;\n\t} else {\n\t\treturn ((git branch --no-color).Split([System.Environment]::NewLine) | where { $_ -match \"^\\* \" } | select -First 1).Substring(2);\n\t}\n}\n\n$templateFiles = (\n\t@{Input=$decompilerVersionInfoTemplateFile; Output=\"ICSharpCode.Decompiler/Properties/DecompilerVersionInfo.cs\"},\n\t@{Input=\"ILSpy.AddIn/source.extension.vsixmanifest.template\"; Output = \"ILSpy.AddIn/source.extension.vsixmanifest\"},\n\t@{Input=\"ILSpy.AddIn.VS2022/source.extension.vsixmanifest.template\"; Output = \"ILSpy.AddIn.VS2022/source.extension.vsixmanifest\"}\n);\n\n[string]$mutexId = \"ILSpyUpdateAssemblyInfo\" + (Get-Location).ToString().GetHashCode();\nWrite-Host $mutexId;\n[bool]$createdNew = $false;\n$mutex = New-Object System.Threading.Mutex($true, $mutexId, [ref]$createdNew);\ntry {\n\tif (-not $createdNew) {\n\t\ttry {\n\t\t\t$mutex.WaitOne(10000);\n\t\t} catch [System.Threading.AbandonedMutexException] {\n\t\t}\n\t\treturn 0;\n\t}\n\n\tif (-not (Test-File \"ILSpy.sln\")) {\n\t\tWrite-Error \"Working directory must be the ILSpy repo root!\";\n\t\treturn 2;\n\t}\n\n\t$versionParts = @{};\n\tGet-Content $decompilerVersionInfoTemplateFile | where { $_ -match 'string (\\w+) = \"?(\\w+)\"?;' } | foreach { $versionParts.Add($Matches[1], $Matches[2]) }\n\n\t$major = $versionParts.Major;\n\t$minor = $versionParts.Minor;\n\t$build = $versionParts.Build;\n\t$versionName = $versionParts.VersionName;\n\t$revision = gitVersion;\n\t$branchName = gitBranch;\n\t$gitCommitHash = gitCommitHash;\n\t$gitShortCommitHash = gitShortCommitHash;\n\n\tif ($branchName -match $masterBranches) {\n\t\t$postfixBranchName = \"\";\n\t} else {\n\t\t$postfixBranchName = \"-$branchName\";\n\t}\n\n\tif ($versionName -eq \"null\") {\n\t\t$versionName = \"\";\n\t\t$postfixVersionName = \"\";\n\t} else {\n\t\t$postfixVersionName = \"-$versionName\";\n\t}\n\t\n\t$buildConfig = $args[0].ToString().ToLower();\n\tif ($buildConfig -eq \"release\") {\n\t\t$buildConfig = \"\";\n\t} else {\n\t\t$buildConfig = \"-\" + $buildConfig;\n\t}\n\n\t$fullVersionNumber = \"$major.$minor.$build.$revision\";\n\tif ((-not (Test-File \"VERSION\")) -or (((Get-Content \"VERSION\") -Join [System.Environment]::NewLine) -ne \"$fullVersionNumber$postfixVersionName\")) {\n\t\t\"$fullVersionNumber$postfixVersionName\" | Out-File -Encoding utf8 -NoNewLine \"VERSION\";\n\t}\n    \n\tforeach ($file in $templateFiles) {\n\t\t[string]$in = (Get-Content $file.Input) -Join [System.Environment]::NewLine;\n\n\t\t$out = $in.Replace('$INSERTVERSION$', $fullVersionNumber);\n\t\t$out = $out.Replace('$INSERTMAJORVERSION$', $major);\n\t\t$out = $out.Replace('$INSERTREVISION$', $revision);\n\t\t$out = $out.Replace('$INSERTCOMMITHASH$', $gitCommitHash);\n\t\t$out = $out.Replace('$INSERTSHORTCOMMITHASH$', $gitShortCommitHash);\n\t\t$out = $out.Replace('$INSERTDATE$', [System.DateTime]::Now.ToString(\"MM/dd/yyyy\"));\n\t\t$out = $out.Replace('$INSERTYEAR$', [System.DateTime]::Now.Year.ToString());\n\t\t$out = $out.Replace('$INSERTBRANCHNAME$', $branchName);\n\t\t$out = $out.Replace('$INSERTBRANCHPOSTFIX$', $postfixBranchName);\n\t\t$out = $out.Replace('$INSERTVERSIONNAME$', $versionName);\n\t\t$out = $out.Replace('$INSERTVERSIONNAMEPOSTFIX$', $postfixVersionName);\n\t\t$out = $out.Replace('$INSERTBUILDCONFIG$', $buildConfig);\n\n\t\tif ((-not (Test-File $file.Output)) -or (((Get-Content $file.Output) -Join [System.Environment]::NewLine) -ne $out)) {\n\t\t\t$utf8NoBom = New-Object System.Text.UTF8Encoding($false);\n\t\t\t[System.IO.File]::WriteAllText($file.Output, $out, $utf8NoBom);\n\t\t}\n\t}\n\t\n} finally {\n\t$mutex.ReleaseMutex();\n\t$mutex.Close();\n}"
  },
  {
    "path": "Directory.Build.props",
    "content": "<Project>\n  <PropertyGroup>\n    <NoWarn>$(NoWarn);NU1510</NoWarn>\n  </PropertyGroup>\n\n  <PropertyGroup>\n    <EnableNUnitRunner>true</EnableNUnitRunner>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "Directory.Packages.props",
    "content": "<Project>\n  <PropertyGroup>\n    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>\n    <CentralPackageTransitivePinningEnabled>false</CentralPackageTransitivePinningEnabled>\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageVersion Include=\"AvalonEdit\" Version=\"6.3.1.120\" />\n    <PackageVersion Include=\"AwesomeAssertions\" Version=\"9.4.0\" />\n    <PackageVersion Include=\"CliWrap\" Version=\"3.10.0\" />\n    <PackageVersion Include=\"DataGridExtensions\" Version=\"2.9.1\" />\n    <PackageVersion Include=\"DiffLib\" Version=\"2025.0.0\" />\n    <PackageVersion Include=\"Dirkster.AvalonDock.Themes.VS2013\" Version=\"4.72.1\" />\n    <PackageVersion Include=\"ILCompiler.Reflection.ReadyToRun.Experimental\" Version=\"10.0.0-rtm.25531.102\" />\n    <PackageVersion Include=\"Iced\" Version=\"1.21.0\" />\n    <PackageVersion Include=\"K4os.Compression.LZ4\" Version=\"1.3.8\" />\n    <PackageVersion Include=\"McMaster.Extensions.CommandLineUtils\" Version=\"5.0.1\" />\n    <PackageVersion Include=\"McMaster.Extensions.Hosting.CommandLine\" Version=\"5.0.1\" />\n    <PackageVersion Include=\"Microsoft.CodeAnalysis.CSharp\" Version=\"5.3.0\" />\n    <PackageVersion Include=\"Microsoft.CodeAnalysis.VisualBasic\" Version=\"5.3.0\" />\n    <PackageVersion Include=\"Microsoft.DiaSymReader.Converter.Xml\" Version=\"1.1.0-beta2-22171-02\" />\n    <PackageVersion Include=\"Microsoft.DiaSymReader\" Version=\"1.4.0\" />\n    <PackageVersion Include=\"Microsoft.DiaSymReader.Native\" Version=\"17.0.0-beta1.21524.1\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Configuration\" Version=\"10.0.5\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Configuration.Json\" Version=\"10.0.5\" />\n    <PackageVersion Include=\"Microsoft.Extensions.DependencyInjection.Abstractions\" Version=\"10.0.5\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Hosting\" Version=\"10.0.5\" />\n    <PackageVersion Include=\"Microsoft.NET.Test.Sdk\" Version=\"17.14.1\" />\n    <PackageVersion Include=\"Microsoft.NETCore.ILAsm\" Version=\"10.0.5\" />\n    <PackageVersion Include=\"Microsoft.NETCore.ILDAsm\" Version=\"10.0.5\" />\n    <PackageVersion Include=\"Microsoft.Sbom.Targets\" Version=\"4.1.5\" />\n    <PackageVersion Include=\"Microsoft.SourceLink.GitHub\" Version=\"10.0.201\" />\n    <PackageVersion Include=\"Microsoft.Testing.Extensions.TrxReport\" Version=\"2.0.2\" />\n    <PackageVersion Include=\"Microsoft.Testing.Extensions.VSTestBridge\" Version=\"2.0.2\" />\n    <PackageVersion Include=\"Microsoft.Xaml.Behaviors.Wpf\" Version=\"1.1.142\" />\n    <PackageVersion Include=\"Mono.Cecil\" Version=\"0.11.6\" />\n    <PackageVersion Include=\"NSubstitute\" Version=\"5.3.0\" />\n    <PackageVersion Include=\"NSubstitute.Analyzers.CSharp\" Version=\"1.0.17\" />\n    <PackageVersion Include=\"NUnit\" Version=\"4.5.1\" />\n    <PackageVersion Include=\"NUnit3TestAdapter\" Version=\"6.1.0\" />\n    <PackageVersion Include=\"NuGet.Protocol\" Version=\"7.3.0\" />\n    <PackageVersion Include=\"PowerShellStandard.Library\" Version=\"5.1.1\" />\n    <PackageVersion Include=\"System.Composition.AttributedModel\" Version=\"10.0.5\" />\n    <PackageVersion Include=\"System.Collections.Immutable\" Version=\"10.0.5\" />\n    <PackageVersion Include=\"System.Memory\" Version=\"4.6.3\" />\n    <PackageVersion Include=\"System.Reflection.Metadata\" Version=\"10.0.5\" />\n    <PackageVersion Include=\"System.Resources.Extensions\" Version=\"10.0.5\" />\n    <PackageVersion Include=\"System.Runtime.CompilerServices.Unsafe\" Version=\"6.1.2\" />\n    <PackageVersion Include=\"System.Security.Cryptography.Pkcs\" Version=\"10.0.5\" />\n    <PackageVersion Include=\"TomsToolbox.Composition.MicrosoftExtensions\" Version=\"2.22.2\" />\n    <PackageVersion Include=\"TomsToolbox.Wpf.Composition\" Version=\"2.22.2\" />\n    <PackageVersion Include=\"TomsToolbox.Wpf.Composition.AttributedModel\" Version=\"2.22.2\" />\n    <PackageVersion Include=\"TomsToolbox.Wpf.Styles\" Version=\"2.22.2\" />\n    <PackageVersion Include=\"coverlet.MTP\" Version=\"8.0.1\" />\n    <PackageVersion Include=\"System.Net.Http\" Version=\"4.3.4\" />\n    <PackageVersion Include=\"System.Private.Uri\" Version=\"4.3.2\" />\n    <PackageVersion Include=\"System.Text.RegularExpressions\" Version=\"4.3.1\" />\n  </ItemGroup>\n  <ItemGroup>\n    <GlobalPackageReference Include=\"TomsToolbox.Composition.Analyzer\" Version=\"2.22.2\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Baml/BamlContext.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nusing Metadata = ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.BamlDecompiler.Baml\n{\n\tinternal class BamlContext\n\t{\n\t\tpublic IDecompilerTypeSystem TypeSystem { get; }\n\t\tpublic KnownThings KnownThings { get; }\n\n\t\tDictionary<ushort, (string FullAssemblyName, IModule Assembly)> assemblyMap = new Dictionary<ushort, (string FullAssemblyName, IModule Assembly)>();\n\n\t\tpublic Dictionary<ushort, AssemblyInfoRecord> AssemblyIdMap { get; }\n\t\tpublic Dictionary<ushort, AttributeInfoRecord> AttributeIdMap { get; }\n\t\tpublic Dictionary<ushort, StringInfoRecord> StringIdMap { get; }\n\t\tpublic Dictionary<ushort, TypeInfoRecord> TypeIdMap { get; }\n\n\t\tBamlContext(IDecompilerTypeSystem typeSystem)\n\t\t{\n\t\t\tthis.TypeSystem = typeSystem;\n\t\t\tKnownThings = new KnownThings(typeSystem);\n\n\t\t\tAssemblyIdMap = new Dictionary<ushort, AssemblyInfoRecord>();\n\t\t\tAttributeIdMap = new Dictionary<ushort, AttributeInfoRecord>();\n\t\t\tStringIdMap = new Dictionary<ushort, StringInfoRecord>();\n\t\t\tTypeIdMap = new Dictionary<ushort, TypeInfoRecord>();\n\t\t}\n\n\t\tpublic static BamlContext ConstructContext(IDecompilerTypeSystem typeSystem, BamlDocument document, CancellationToken token)\n\t\t{\n\t\t\tvar ctx = new BamlContext(typeSystem);\n\n\t\t\tforeach (var record in document)\n\t\t\t{\n\t\t\t\ttoken.ThrowIfCancellationRequested();\n\n\t\t\t\tif (record is AssemblyInfoRecord assemblyInfo)\n\t\t\t\t{\n\t\t\t\t\tif (assemblyInfo.AssemblyId == ctx.AssemblyIdMap.Count)\n\t\t\t\t\t\tctx.AssemblyIdMap.Add(assemblyInfo.AssemblyId, assemblyInfo);\n\t\t\t\t}\n\t\t\t\telse if (record is AttributeInfoRecord attrInfo)\n\t\t\t\t{\n\t\t\t\t\tif (attrInfo.AttributeId == ctx.AttributeIdMap.Count)\n\t\t\t\t\t\tctx.AttributeIdMap.Add(attrInfo.AttributeId, attrInfo);\n\t\t\t\t}\n\t\t\t\telse if (record is StringInfoRecord strInfo)\n\t\t\t\t{\n\t\t\t\t\tif (strInfo.StringId == ctx.StringIdMap.Count)\n\t\t\t\t\t\tctx.StringIdMap.Add(strInfo.StringId, strInfo);\n\t\t\t\t}\n\t\t\t\telse if (record is TypeInfoRecord typeInfo)\n\t\t\t\t{\n\t\t\t\t\tif (typeInfo.TypeId == ctx.TypeIdMap.Count)\n\t\t\t\t\t\tctx.TypeIdMap.Add(typeInfo.TypeId, typeInfo);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn ctx;\n\t\t}\n\n\t\tpublic (string FullAssemblyName, IModule Assembly) ResolveAssembly(ushort id)\n\t\t{\n\t\t\tid &= 0xfff;\n\t\t\tif (!assemblyMap.TryGetValue(id, out var assembly))\n\t\t\t{\n\t\t\t\tif (AssemblyIdMap.TryGetValue(id, out var assemblyRec))\n\t\t\t\t{\n\t\t\t\t\tvar assemblyName = Metadata.AssemblyNameReference.Parse(assemblyRec.AssemblyFullName);\n\n\t\t\t\t\tif (assemblyName.Name == TypeSystem.MainModule.AssemblyName)\n\t\t\t\t\t{\n\t\t\t\t\t\tassembly = (assemblyRec.AssemblyFullName, TypeSystem.MainModule);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tassembly = (assemblyRec.AssemblyFullName, FindMatchingReference(assemblyName));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tassembly = (null, null);\n\n\t\t\t\tassemblyMap[id] = assembly;\n\t\t\t}\n\t\t\treturn assembly;\n\t\t}\n\n\t\tprivate IModule FindMatchingReference(AssemblyNameReference name)\n\t\t{\n\t\t\tIModule bestMatch = null;\n\t\t\tforeach (var module in TypeSystem.ReferencedModules)\n\t\t\t{\n\t\t\t\tif (module.AssemblyName == name.Name)\n\t\t\t\t{\n\t\t\t\t\t// using highest version as criterion\n\t\t\t\t\tif (bestMatch == null || bestMatch.AssemblyVersion <= module.AssemblyVersion)\n\t\t\t\t\t{\n\t\t\t\t\t\tbestMatch = module;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn bestMatch;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Baml/BamlDocument.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.BamlDecompiler.Baml\n{\n\tinternal class BamlDocument : List<BamlRecord>\n\t{\n\t\tpublic string DocumentName { get; set; }\n\n\t\tpublic string Signature { get; set; }\n\t\tpublic BamlVersion ReaderVersion { get; set; }\n\t\tpublic BamlVersion UpdaterVersion { get; set; }\n\t\tpublic BamlVersion WriterVersion { get; set; }\n\n\t\tpublic struct BamlVersion\n\t\t{\n\t\t\tpublic ushort Major;\n\t\t\tpublic ushort Minor;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Baml/BamlNode.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Threading;\n\nnamespace ICSharpCode.BamlDecompiler.Baml\n{\n\tinternal abstract class BamlNode\n\t{\n\t\tpublic BamlBlockNode Parent { get; set; }\n\t\tpublic abstract BamlRecordType Type { get; }\n\t\tpublic object Annotation { get; set; }\n\n\t\tpublic abstract BamlRecord Record { get; }\n\n\t\tpublic static bool IsHeader(BamlRecord rec)\n\t\t{\n\t\t\tswitch (rec.Type)\n\t\t\t{\n\t\t\t\tcase BamlRecordType.ConstructorParametersStart:\n\t\t\t\tcase BamlRecordType.DocumentStart:\n\t\t\t\tcase BamlRecordType.ElementStart:\n\t\t\t\tcase BamlRecordType.KeyElementStart:\n\t\t\t\tcase BamlRecordType.NamedElementStart:\n\t\t\t\tcase BamlRecordType.PropertyArrayStart:\n\t\t\t\tcase BamlRecordType.PropertyComplexStart:\n\t\t\t\tcase BamlRecordType.PropertyDictionaryStart:\n\t\t\t\tcase BamlRecordType.PropertyListStart:\n\t\t\t\tcase BamlRecordType.StaticResourceStart:\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool IsFooter(BamlRecord rec)\n\t\t{\n\t\t\tswitch (rec.Type)\n\t\t\t{\n\t\t\t\tcase BamlRecordType.ConstructorParametersEnd:\n\t\t\t\tcase BamlRecordType.DocumentEnd:\n\t\t\t\tcase BamlRecordType.ElementEnd:\n\t\t\t\tcase BamlRecordType.KeyElementEnd:\n\t\t\t\tcase BamlRecordType.PropertyArrayEnd:\n\t\t\t\tcase BamlRecordType.PropertyComplexEnd:\n\t\t\t\tcase BamlRecordType.PropertyDictionaryEnd:\n\t\t\t\tcase BamlRecordType.PropertyListEnd:\n\t\t\t\tcase BamlRecordType.StaticResourceEnd:\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool IsMatch(BamlRecord header, BamlRecord footer)\n\t\t{\n\t\t\tswitch (header.Type)\n\t\t\t{\n\t\t\t\tcase BamlRecordType.ConstructorParametersStart:\n\t\t\t\t\treturn footer.Type == BamlRecordType.ConstructorParametersEnd;\n\n\t\t\t\tcase BamlRecordType.DocumentStart:\n\t\t\t\t\treturn footer.Type == BamlRecordType.DocumentEnd;\n\n\t\t\t\tcase BamlRecordType.KeyElementStart:\n\t\t\t\t\treturn footer.Type == BamlRecordType.KeyElementEnd;\n\n\t\t\t\tcase BamlRecordType.PropertyArrayStart:\n\t\t\t\t\treturn footer.Type == BamlRecordType.PropertyArrayEnd;\n\n\t\t\t\tcase BamlRecordType.PropertyComplexStart:\n\t\t\t\t\treturn footer.Type == BamlRecordType.PropertyComplexEnd;\n\n\t\t\t\tcase BamlRecordType.PropertyDictionaryStart:\n\t\t\t\t\treturn footer.Type == BamlRecordType.PropertyDictionaryEnd;\n\n\t\t\t\tcase BamlRecordType.PropertyListStart:\n\t\t\t\t\treturn footer.Type == BamlRecordType.PropertyListEnd;\n\n\t\t\t\tcase BamlRecordType.StaticResourceStart:\n\t\t\t\t\treturn footer.Type == BamlRecordType.StaticResourceEnd;\n\n\t\t\t\tcase BamlRecordType.ElementStart:\n\t\t\t\tcase BamlRecordType.NamedElementStart:\n\t\t\t\t\treturn footer.Type == BamlRecordType.ElementEnd;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static BamlNode Parse(BamlDocument document, CancellationToken token)\n\t\t{\n\t\t\tDebug.Assert(document.Count > 0 && document[0].Type == BamlRecordType.DocumentStart);\n\n\t\t\tBamlBlockNode current = null;\n\t\t\tvar stack = new Stack<BamlBlockNode>();\n\n\t\t\tfor (int i = 0; i < document.Count; i++)\n\t\t\t{\n\t\t\t\ttoken.ThrowIfCancellationRequested();\n\n\t\t\t\tif (IsHeader(document[i]))\n\t\t\t\t{\n\t\t\t\t\tvar prev = current;\n\n\t\t\t\t\tcurrent = new BamlBlockNode {\n\t\t\t\t\t\tHeader = document[i]\n\t\t\t\t\t};\n\n\t\t\t\t\tif (prev != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tprev.Children.Add(current);\n\t\t\t\t\t\tcurrent.Parent = prev;\n\t\t\t\t\t\tstack.Push(prev);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (IsFooter(document[i]))\n\t\t\t\t{\n\t\t\t\t\tif (current == null)\n\t\t\t\t\t\tthrow new Exception(\"Unexpected footer.\");\n\n\t\t\t\t\twhile (!IsMatch(current.Header, document[i]))\n\t\t\t\t\t{\n\t\t\t\t\t\t// End record can be omited (sometimes).\n\t\t\t\t\t\tif (stack.Count > 0)\n\t\t\t\t\t\t\tcurrent = stack.Pop();\n\t\t\t\t\t}\n\t\t\t\t\tcurrent.Footer = document[i];\n\t\t\t\t\tif (stack.Count > 0)\n\t\t\t\t\t\tcurrent = stack.Pop();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tcurrent.Children.Add(new BamlRecordNode(document[i]) { Parent = current });\n\t\t\t}\n\t\t\tDebug.Assert(stack.Count == 0);\n\t\t\treturn current;\n\t\t}\n\t}\n\n\tinternal class BamlRecordNode : BamlNode\n\t{\n\t\tBamlRecord record;\n\n\t\tpublic override BamlRecord Record => record;\n\t\tpublic override BamlRecordType Type => Record.Type;\n\n\t\tpublic BamlRecordNode(BamlRecord record) => this.record = record;\n\t}\n\n\tinternal class BamlBlockNode : BamlNode\n\t{\n\t\tpublic BamlRecord Header { get; set; }\n\t\tpublic IList<BamlNode> Children { get; }\n\t\tpublic BamlRecord Footer { get; set; }\n\n\t\tpublic override BamlRecord Record => Header;\n\t\tpublic override BamlRecordType Type => Header.Type;\n\n\t\tpublic BamlBlockNode() => Children = new List<BamlNode>();\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Baml/BamlReader.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Text;\nusing System.Threading;\n\nnamespace ICSharpCode.BamlDecompiler.Baml\n{\n\tinternal class BamlBinaryReader : BinaryReader\n\t{\n\t\tpublic BamlBinaryReader(Stream stream)\n\t\t\t: base(stream)\n\t\t{\n\t\t}\n\n\t\tpublic int ReadEncodedInt() => Read7BitEncodedInt();\n\t}\n\n\tinternal class BamlReader\n\t{\n\t\tconst string MSBAML_SIG = \"MSBAML\";\n\n\t\tinternal static bool IsBamlHeader(Stream str)\n\t\t{\n\t\t\tvar pos = str.Position;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar rdr = new BinaryReader(str, Encoding.Unicode);\n\t\t\t\tint len = (int)(rdr.ReadUInt32() >> 1);\n\t\t\t\tif (len != MSBAML_SIG.Length)\n\t\t\t\t\treturn false;\n\t\t\t\tvar sig = new string(rdr.ReadChars(len));\n\t\t\t\treturn sig == MSBAML_SIG;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tstr.Position = pos;\n\t\t\t}\n\t\t}\n\n\t\tstatic string ReadSignature(Stream str)\n\t\t{\n\t\t\tvar rdr = new BinaryReader(str, Encoding.Unicode);\n\t\t\tuint len = rdr.ReadUInt32();\n\t\t\tvar sig = new string(rdr.ReadChars((int)(len >> 1)));\n\t\t\trdr.ReadBytes((int)(((len + 3) & ~3) - len));\n\t\t\treturn sig;\n\t\t}\n\n\t\tpublic static BamlDocument ReadDocument(Stream str, CancellationToken token)\n\t\t{\n\t\t\tvar ret = new BamlDocument();\n\t\t\tvar reader = new BamlBinaryReader(str);\n\t\t\tret.Signature = ReadSignature(str);\n\t\t\tif (ret.Signature != MSBAML_SIG)\n\t\t\t\tthrow new NotSupportedException();\n\t\t\tret.ReaderVersion = new BamlDocument.BamlVersion { Major = reader.ReadUInt16(), Minor = reader.ReadUInt16() };\n\t\t\tret.UpdaterVersion = new BamlDocument.BamlVersion { Major = reader.ReadUInt16(), Minor = reader.ReadUInt16() };\n\t\t\tret.WriterVersion = new BamlDocument.BamlVersion { Major = reader.ReadUInt16(), Minor = reader.ReadUInt16() };\n\t\t\tif (ret.ReaderVersion.Major != 0 || ret.ReaderVersion.Minor != 0x60 ||\n\t\t\t\tret.UpdaterVersion.Major != 0 || ret.UpdaterVersion.Minor != 0x60 ||\n\t\t\t\tret.WriterVersion.Major != 0 || ret.WriterVersion.Minor != 0x60)\n\t\t\t\tthrow new NotSupportedException();\n\n\t\t\tvar recs = new Dictionary<long, BamlRecord>();\n\t\t\twhile (str.Position < str.Length)\n\t\t\t{\n\t\t\t\ttoken.ThrowIfCancellationRequested();\n\n\t\t\t\tlong pos = str.Position;\n\t\t\t\tvar type = (BamlRecordType)reader.ReadByte();\n\t\t\t\tBamlRecord rec = null;\n\t\t\t\tswitch (type)\n\t\t\t\t{\n\t\t\t\t\tcase BamlRecordType.AssemblyInfo:\n\t\t\t\t\t\trec = new AssemblyInfoRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.AttributeInfo:\n\t\t\t\t\t\trec = new AttributeInfoRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.ConstructorParametersStart:\n\t\t\t\t\t\trec = new ConstructorParametersStartRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.ConstructorParametersEnd:\n\t\t\t\t\t\trec = new ConstructorParametersEndRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.ConstructorParameterType:\n\t\t\t\t\t\trec = new ConstructorParameterTypeRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.ConnectionId:\n\t\t\t\t\t\trec = new ConnectionIdRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.ContentProperty:\n\t\t\t\t\t\trec = new ContentPropertyRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.DefAttribute:\n\t\t\t\t\t\trec = new DefAttributeRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.DefAttributeKeyString:\n\t\t\t\t\t\trec = new DefAttributeKeyStringRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.DefAttributeKeyType:\n\t\t\t\t\t\trec = new DefAttributeKeyTypeRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.DeferableContentStart:\n\t\t\t\t\t\trec = new DeferableContentStartRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.DocumentEnd:\n\t\t\t\t\t\trec = new DocumentEndRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.DocumentStart:\n\t\t\t\t\t\trec = new DocumentStartRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.ElementEnd:\n\t\t\t\t\t\trec = new ElementEndRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.ElementStart:\n\t\t\t\t\t\trec = new ElementStartRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.KeyElementEnd:\n\t\t\t\t\t\trec = new KeyElementEndRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.KeyElementStart:\n\t\t\t\t\t\trec = new KeyElementStartRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.LineNumberAndPosition:\n\t\t\t\t\t\trec = new LineNumberAndPositionRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.LinePosition:\n\t\t\t\t\t\trec = new LinePositionRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.LiteralContent:\n\t\t\t\t\t\trec = new LiteralContentRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.NamedElementStart:\n\t\t\t\t\t\trec = new NamedElementStartRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.OptimizedStaticResource:\n\t\t\t\t\t\trec = new OptimizedStaticResourceRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.PIMapping:\n\t\t\t\t\t\trec = new PIMappingRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.PresentationOptionsAttribute:\n\t\t\t\t\t\trec = new PresentationOptionsAttributeRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.Property:\n\t\t\t\t\t\trec = new PropertyRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.PropertyArrayEnd:\n\t\t\t\t\t\trec = new PropertyArrayEndRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.PropertyArrayStart:\n\t\t\t\t\t\trec = new PropertyArrayStartRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.PropertyComplexEnd:\n\t\t\t\t\t\trec = new PropertyComplexEndRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.PropertyComplexStart:\n\t\t\t\t\t\trec = new PropertyComplexStartRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.PropertyCustom:\n\t\t\t\t\t\trec = new PropertyCustomRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.PropertyDictionaryEnd:\n\t\t\t\t\t\trec = new PropertyDictionaryEndRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.PropertyDictionaryStart:\n\t\t\t\t\t\trec = new PropertyDictionaryStartRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.PropertyListEnd:\n\t\t\t\t\t\trec = new PropertyListEndRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.PropertyListStart:\n\t\t\t\t\t\trec = new PropertyListStartRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.PropertyStringReference:\n\t\t\t\t\t\trec = new PropertyStringReferenceRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.PropertyTypeReference:\n\t\t\t\t\t\trec = new PropertyTypeReferenceRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.PropertyWithConverter:\n\t\t\t\t\t\trec = new PropertyWithConverterRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.PropertyWithExtension:\n\t\t\t\t\t\trec = new PropertyWithExtensionRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.PropertyWithStaticResourceId:\n\t\t\t\t\t\trec = new PropertyWithStaticResourceIdRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.RoutedEvent:\n\t\t\t\t\t\trec = new RoutedEventRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.StaticResourceEnd:\n\t\t\t\t\t\trec = new StaticResourceEndRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.StaticResourceId:\n\t\t\t\t\t\trec = new StaticResourceIdRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.StaticResourceStart:\n\t\t\t\t\t\trec = new StaticResourceStartRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.StringInfo:\n\t\t\t\t\t\trec = new StringInfoRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.Text:\n\t\t\t\t\t\trec = new TextRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.TextWithConverter:\n\t\t\t\t\t\trec = new TextWithConverterRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.TextWithId:\n\t\t\t\t\t\trec = new TextWithIdRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.TypeInfo:\n\t\t\t\t\t\trec = new TypeInfoRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.TypeSerializerInfo:\n\t\t\t\t\t\trec = new TypeSerializerInfoRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.XmlnsProperty:\n\t\t\t\t\t\trec = new XmlnsPropertyRecord();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.XmlAttribute:\n\t\t\t\t\tcase BamlRecordType.ProcessingInstruction:\n\t\t\t\t\tcase BamlRecordType.LastRecordType:\n\t\t\t\t\tcase BamlRecordType.EndAttributes:\n\t\t\t\t\tcase BamlRecordType.DefTag:\n\t\t\t\t\tcase BamlRecordType.ClrEvent:\n\t\t\t\t\tcase BamlRecordType.Comment:\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new NotSupportedException();\n\t\t\t\t}\n\t\t\t\trec.Position = pos;\n\n\t\t\t\trec.Read(reader);\n\t\t\t\tret.Add(rec);\n\t\t\t\trecs.Add(pos, rec);\n\t\t\t}\n\t\t\tfor (int i = 0; i < ret.Count; i++)\n\t\t\t{\n\t\t\t\tif (ret[i] is IBamlDeferRecord defer)\n\t\t\t\t\tdefer.ReadDefer(ret, i, _ => recs[_]);\n\t\t\t}\n\n\t\t\treturn ret;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Baml/BamlRecords.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System;\nusing System.Diagnostics;\nusing System.IO;\n\nnamespace ICSharpCode.BamlDecompiler.Baml\n{\n\tinternal enum BamlRecordType : byte\n\t{\n\t\tClrEvent = 0x13,\n\t\tComment = 0x17,\n\t\tAssemblyInfo = 0x1c,\n\t\tAttributeInfo = 0x1f,\n\t\tConstructorParametersStart = 0x2a,\n\t\tConstructorParametersEnd = 0x2b,\n\t\tConstructorParameterType = 0x2c,\n\t\tConnectionId = 0x2d,\n\t\tContentProperty = 0x2e,\n\t\tDefAttribute = 0x19,\n\t\tDefAttributeKeyString = 0x26,\n\t\tDefAttributeKeyType = 0x27,\n\t\tDeferableContentStart = 0x25,\n\t\tDefTag = 0x18,\n\t\tDocumentEnd = 0x2,\n\t\tDocumentStart = 0x1,\n\t\tElementEnd = 0x4,\n\t\tElementStart = 0x3,\n\t\tEndAttributes = 0x1a,\n\t\tKeyElementEnd = 0x29,\n\t\tKeyElementStart = 0x28,\n\t\tLastRecordType = 0x39,\n\t\tLineNumberAndPosition = 0x35,\n\t\tLinePosition = 0x36,\n\t\tLiteralContent = 0xf,\n\t\tNamedElementStart = 0x2f,\n\t\tOptimizedStaticResource = 0x37,\n\t\tPIMapping = 0x1b,\n\t\tPresentationOptionsAttribute = 0x34,\n\t\tProcessingInstruction = 0x16,\n\t\tProperty = 0x5,\n\t\tPropertyArrayEnd = 0xa,\n\t\tPropertyArrayStart = 0x9,\n\t\tPropertyComplexEnd = 0x8,\n\t\tPropertyComplexStart = 0x7,\n\t\tPropertyCustom = 0x6,\n\t\tPropertyDictionaryEnd = 0xe,\n\t\tPropertyDictionaryStart = 0xd,\n\t\tPropertyListEnd = 0xc,\n\t\tPropertyListStart = 0xb,\n\t\tPropertyStringReference = 0x21,\n\t\tPropertyTypeReference = 0x22,\n\t\tPropertyWithConverter = 0x24,\n\t\tPropertyWithExtension = 0x23,\n\t\tPropertyWithStaticResourceId = 0x38,\n\t\tRoutedEvent = 0x12,\n\t\tStaticResourceEnd = 0x31,\n\t\tStaticResourceId = 0x32,\n\t\tStaticResourceStart = 0x30,\n\t\tStringInfo = 0x20,\n\t\tText = 0x10,\n\t\tTextWithConverter = 0x11,\n\t\tTextWithId = 0x33,\n\t\tTypeInfo = 0x1d,\n\t\tTypeSerializerInfo = 0x1e,\n\t\tXmlAttribute = 0x15,\n\t\tXmlnsProperty = 0x14\n\t}\n\n\tinternal abstract class BamlRecord\n\t{\n\t\tpublic abstract BamlRecordType Type { get; }\n\t\tpublic long Position { get; internal set; }\n\t\tpublic abstract void Read(BamlBinaryReader reader);\n\t\tpublic abstract void Write(BamlBinaryWriter writer);\n\t}\n\n\tinternal abstract class SizedBamlRecord : BamlRecord\n\t{\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t\tlong pos = reader.BaseStream.Position;\n\t\t\tint size = reader.ReadEncodedInt();\n\n\t\t\tReadData(reader, size - (int)(reader.BaseStream.Position - pos));\n\t\t}\n\n\t\tint SizeofEncodedInt(int val)\n\t\t{\n\t\t\tif ((val & ~0x7F) == 0)\n\t\t\t{\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif ((val & ~0x3FFF) == 0)\n\t\t\t{\n\t\t\t\treturn 2;\n\t\t\t}\n\t\t\tif ((val & ~0x1FFFFF) == 0)\n\t\t\t{\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t\tif ((val & ~0xFFFFFFF) == 0)\n\t\t\t{\n\t\t\t\treturn 4;\n\t\t\t}\n\t\t\treturn 5;\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t\tlong pos = writer.BaseStream.Position;\n\t\t\tWriteData(writer);\n\t\t\tvar size = (int)(writer.BaseStream.Position - pos);\n\t\t\tsize = SizeofEncodedInt(SizeofEncodedInt(size) + size) + size;\n\t\t\twriter.BaseStream.Position = pos;\n\t\t\twriter.WriteEncodedInt(size);\n\t\t\tWriteData(writer);\n\t\t}\n\n\t\tprotected abstract void ReadData(BamlBinaryReader reader, int size);\n\t\tprotected abstract void WriteData(BamlBinaryWriter writer);\n\t}\n\n\tinternal interface IBamlDeferRecord\n\t{\n\t\tlong Position { get; }\n\t\tBamlRecord Record { get; set; }\n\t\tvoid ReadDefer(BamlDocument doc, int index, Func<long, BamlRecord> resolve);\n\t\tvoid WriteDefer(BamlDocument doc, int index, BinaryWriter wtr);\n\t}\n\n\tinternal class XmlnsPropertyRecord : SizedBamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.XmlnsProperty;\n\n\t\tpublic string Prefix { get; set; }\n\t\tpublic string XmlNamespace { get; set; }\n\t\tpublic ushort[] AssemblyIds { get; set; }\n\n\t\tprotected override void ReadData(BamlBinaryReader reader, int size)\n\t\t{\n\t\t\tPrefix = reader.ReadString();\n\t\t\tXmlNamespace = reader.ReadString();\n\t\t\tAssemblyIds = new ushort[reader.ReadUInt16()];\n\t\t\tfor (int i = 0; i < AssemblyIds.Length; i++)\n\t\t\t\tAssemblyIds[i] = reader.ReadUInt16();\n\t\t}\n\n\t\tprotected override void WriteData(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(Prefix);\n\t\t\twriter.Write(XmlNamespace);\n\t\t\twriter.Write((ushort)AssemblyIds.Length);\n\t\t\tforeach (ushort i in AssemblyIds)\n\t\t\t\twriter.Write(i);\n\t\t}\n\t}\n\n\tinternal class PresentationOptionsAttributeRecord : SizedBamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.PresentationOptionsAttribute;\n\n\t\tpublic string Value { get; set; }\n\t\tpublic ushort NameId { get; set; }\n\n\t\tprotected override void ReadData(BamlBinaryReader reader, int size)\n\t\t{\n\t\t\tValue = reader.ReadString();\n\t\t\tNameId = reader.ReadUInt16();\n\t\t}\n\n\t\tprotected override void WriteData(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(Value);\n\t\t\twriter.Write(NameId);\n\t\t}\n\t}\n\n\tinternal class PIMappingRecord : SizedBamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.PIMapping;\n\n\t\tpublic string XmlNamespace { get; set; }\n\t\tpublic string ClrNamespace { get; set; }\n\t\tpublic ushort AssemblyId { get; set; }\n\n\t\tprotected override void ReadData(BamlBinaryReader reader, int size)\n\t\t{\n\t\t\tXmlNamespace = reader.ReadString();\n\t\t\tClrNamespace = reader.ReadString();\n\t\t\tAssemblyId = reader.ReadUInt16();\n\t\t}\n\n\t\tprotected override void WriteData(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(XmlNamespace);\n\t\t\twriter.Write(ClrNamespace);\n\t\t\twriter.Write(AssemblyId);\n\t\t}\n\t}\n\n\tinternal class AssemblyInfoRecord : SizedBamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.AssemblyInfo;\n\n\t\tpublic ushort AssemblyId { get; set; }\n\t\tpublic string AssemblyFullName { get; set; }\n\n\t\tprotected override void ReadData(BamlBinaryReader reader, int size)\n\t\t{\n\t\t\tAssemblyId = reader.ReadUInt16();\n\t\t\tAssemblyFullName = reader.ReadString();\n\t\t}\n\n\t\tprotected override void WriteData(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(AssemblyId);\n\t\t\twriter.Write(AssemblyFullName);\n\t\t}\n\t}\n\n\tinternal class PropertyRecord : SizedBamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.Property;\n\n\t\tpublic ushort AttributeId { get; set; }\n\t\tpublic string Value { get; set; }\n\n\t\tprotected override void ReadData(BamlBinaryReader reader, int size)\n\t\t{\n\t\t\tAttributeId = reader.ReadUInt16();\n\t\t\tValue = reader.ReadString();\n\t\t}\n\n\t\tprotected override void WriteData(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(AttributeId);\n\t\t\twriter.Write(Value);\n\t\t}\n\t}\n\n\tinternal class PropertyWithConverterRecord : PropertyRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.PropertyWithConverter;\n\n\t\tpublic ushort ConverterTypeId { get; set; }\n\n\t\tprotected override void ReadData(BamlBinaryReader reader, int size)\n\t\t{\n\t\t\tbase.ReadData(reader, size);\n\t\t\tConverterTypeId = reader.ReadUInt16();\n\t\t}\n\n\t\tprotected override void WriteData(BamlBinaryWriter writer)\n\t\t{\n\t\t\tbase.WriteData(writer);\n\t\t\twriter.Write(ConverterTypeId);\n\t\t}\n\t}\n\n\tinternal class PropertyCustomRecord : SizedBamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.PropertyCustom;\n\n\t\tpublic ushort AttributeId { get; set; }\n\t\tpublic ushort SerializerTypeId { get; set; }\n\t\tpublic byte[] Data { get; set; }\n\n\t\tprotected override void ReadData(BamlBinaryReader reader, int size)\n\t\t{\n\t\t\tlong pos = reader.BaseStream.Position;\n\t\t\tAttributeId = reader.ReadUInt16();\n\t\t\tSerializerTypeId = reader.ReadUInt16();\n\t\t\tData = reader.ReadBytes(size - (int)(reader.BaseStream.Position - pos));\n\t\t}\n\n\t\tprotected override void WriteData(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(AttributeId);\n\t\t\twriter.Write(SerializerTypeId);\n\t\t\twriter.Write(Data);\n\t\t}\n\t}\n\n\tinternal class DefAttributeRecord : SizedBamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.DefAttribute;\n\n\t\tpublic string Value { get; set; }\n\t\tpublic ushort NameId { get; set; }\n\n\t\tprotected override void ReadData(BamlBinaryReader reader, int size)\n\t\t{\n\t\t\tValue = reader.ReadString();\n\t\t\tNameId = reader.ReadUInt16();\n\t\t}\n\n\t\tprotected override void WriteData(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(Value);\n\t\t\twriter.Write(NameId);\n\t\t}\n\t}\n\n\tinternal class DefAttributeKeyStringRecord : SizedBamlRecord, IBamlDeferRecord\n\t{\n\t\tinternal uint pos = 0xffffffff;\n\n\t\tpublic override BamlRecordType Type => BamlRecordType.DefAttributeKeyString;\n\n\t\tpublic ushort ValueId { get; set; }\n\t\tpublic bool Shared { get; set; }\n\t\tpublic bool SharedSet { get; set; }\n\n\t\tpublic BamlRecord Record { get; set; }\n\n\t\tpublic void ReadDefer(BamlDocument doc, int index, Func<long, BamlRecord> resolve)\n\t\t{\n\t\t\tbool keys = true;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tswitch (doc[index].Type)\n\t\t\t\t{\n\t\t\t\t\tcase BamlRecordType.DefAttributeKeyString:\n\t\t\t\t\tcase BamlRecordType.DefAttributeKeyType:\n\t\t\t\t\tcase BamlRecordType.OptimizedStaticResource:\n\t\t\t\t\t\tkeys = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.StaticResourceStart:\n\t\t\t\t\t\tNavigateTree(doc, BamlRecordType.StaticResourceStart, BamlRecordType.StaticResourceEnd, ref index);\n\t\t\t\t\t\tkeys = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.KeyElementStart:\n\t\t\t\t\t\tNavigateTree(doc, BamlRecordType.KeyElementStart, BamlRecordType.KeyElementEnd, ref index);\n\t\t\t\t\t\tkeys = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tkeys = false;\n\t\t\t\t\t\tindex--;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tindex++;\n\t\t\t} while (keys);\n\t\t\tRecord = resolve(doc[index].Position + pos);\n\t\t}\n\n\t\tpublic void WriteDefer(BamlDocument doc, int index, BinaryWriter wtr)\n\t\t{\n\t\t\tbool keys = true;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tswitch (doc[index].Type)\n\t\t\t\t{\n\t\t\t\t\tcase BamlRecordType.DefAttributeKeyString:\n\t\t\t\t\tcase BamlRecordType.DefAttributeKeyType:\n\t\t\t\t\tcase BamlRecordType.OptimizedStaticResource:\n\t\t\t\t\t\tkeys = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.StaticResourceStart:\n\t\t\t\t\t\tNavigateTree(doc, BamlRecordType.StaticResourceStart, BamlRecordType.StaticResourceEnd, ref index);\n\t\t\t\t\t\tkeys = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.KeyElementStart:\n\t\t\t\t\t\tNavigateTree(doc, BamlRecordType.KeyElementStart, BamlRecordType.KeyElementEnd, ref index);\n\t\t\t\t\t\tkeys = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tkeys = false;\n\t\t\t\t\t\tindex--;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tindex++;\n\t\t\t} while (keys);\n\t\t\twtr.BaseStream.Seek(pos, SeekOrigin.Begin);\n\t\t\twtr.Write((uint)(Record.Position - doc[index].Position));\n\t\t}\n\n\t\tprotected override void ReadData(BamlBinaryReader reader, int size)\n\t\t{\n\t\t\tValueId = reader.ReadUInt16();\n\t\t\tpos = reader.ReadUInt32();\n\t\t\tShared = reader.ReadBoolean();\n\t\t\tSharedSet = reader.ReadBoolean();\n\t\t}\n\n\t\tprotected override void WriteData(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(ValueId);\n\t\t\tpos = (uint)writer.BaseStream.Position;\n\t\t\twriter.Write((uint)0);\n\t\t\twriter.Write(Shared);\n\t\t\twriter.Write(SharedSet);\n\t\t}\n\n\t\tstatic void NavigateTree(BamlDocument doc, BamlRecordType start, BamlRecordType end, ref int index)\n\t\t{\n\t\t\tindex++;\n\t\t\twhile (true) //Assume there alway is a end\n\t\t\t{\n\t\t\t\tif (doc[index].Type == start)\n\t\t\t\t\tNavigateTree(doc, start, end, ref index);\n\t\t\t\telse if (doc[index].Type == end)\n\t\t\t\t\treturn;\n\t\t\t\tindex++;\n\t\t\t}\n\t\t}\n\t}\n\n\tinternal class TypeInfoRecord : SizedBamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.TypeInfo;\n\n\t\tpublic ushort TypeId { get; set; }\n\t\tpublic ushort AssemblyId { get; set; }\n\t\tpublic string TypeFullName { get; set; }\n\n\t\tprotected override void ReadData(BamlBinaryReader reader, int size)\n\t\t{\n\t\t\tTypeId = reader.ReadUInt16();\n\t\t\tAssemblyId = reader.ReadUInt16();\n\t\t\tTypeFullName = reader.ReadString();\n\t\t}\n\n\t\tprotected override void WriteData(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(TypeId);\n\t\t\twriter.Write(AssemblyId);\n\t\t\twriter.Write(TypeFullName);\n\t\t}\n\t}\n\n\tinternal class TypeSerializerInfoRecord : TypeInfoRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.TypeSerializerInfo;\n\n\t\tpublic ushort SerializerTypeId { get; set; }\n\n\t\tprotected override void ReadData(BamlBinaryReader reader, int size)\n\t\t{\n\t\t\tbase.ReadData(reader, size);\n\t\t\tSerializerTypeId = reader.ReadUInt16();\n\t\t}\n\n\t\tprotected override void WriteData(BamlBinaryWriter writer)\n\t\t{\n\t\t\tbase.WriteData(writer);\n\t\t\twriter.Write(SerializerTypeId);\n\t\t}\n\t}\n\n\tinternal class AttributeInfoRecord : SizedBamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.AttributeInfo;\n\n\t\tpublic ushort AttributeId { get; set; }\n\t\tpublic ushort OwnerTypeId { get; set; }\n\t\tpublic byte AttributeUsage { get; set; }\n\t\tpublic string Name { get; set; }\n\n\t\tprotected override void ReadData(BamlBinaryReader reader, int size)\n\t\t{\n\t\t\tAttributeId = reader.ReadUInt16();\n\t\t\tOwnerTypeId = reader.ReadUInt16();\n\t\t\tAttributeUsage = reader.ReadByte();\n\t\t\tName = reader.ReadString();\n\t\t}\n\n\t\tprotected override void WriteData(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(AttributeId);\n\t\t\twriter.Write(OwnerTypeId);\n\t\t\twriter.Write(AttributeUsage);\n\t\t\twriter.Write(Name);\n\t\t}\n\t}\n\n\tinternal class StringInfoRecord : SizedBamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.StringInfo;\n\n\t\tpublic ushort StringId { get; set; }\n\t\tpublic string Value { get; set; }\n\n\t\tprotected override void ReadData(BamlBinaryReader reader, int size)\n\t\t{\n\t\t\tStringId = reader.ReadUInt16();\n\t\t\tValue = reader.ReadString();\n\t\t}\n\n\t\tprotected override void WriteData(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(StringId);\n\t\t\twriter.Write(Value);\n\t\t}\n\t}\n\n\tinternal class TextRecord : SizedBamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.Text;\n\n\t\tpublic string Value { get; set; }\n\n\t\tprotected override void ReadData(BamlBinaryReader reader, int size) => Value = reader.ReadString();\n\n\t\tprotected override void WriteData(BamlBinaryWriter writer) => writer.Write(Value);\n\t}\n\n\tinternal class TextWithConverterRecord : TextRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.TextWithConverter;\n\n\t\tpublic ushort ConverterTypeId { get; set; }\n\n\t\tprotected override void ReadData(BamlBinaryReader reader, int size)\n\t\t{\n\t\t\tbase.ReadData(reader, size);\n\t\t\tConverterTypeId = reader.ReadUInt16();\n\t\t}\n\n\t\tprotected override void WriteData(BamlBinaryWriter writer)\n\t\t{\n\t\t\tbase.WriteData(writer);\n\t\t\twriter.Write(ConverterTypeId);\n\t\t}\n\t}\n\n\tinternal class TextWithIdRecord : SizedBamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.TextWithId;\n\n\t\tpublic ushort ValueId { get; set; }\n\n\t\tprotected override void ReadData(BamlBinaryReader reader, int size) => ValueId = reader.ReadUInt16();\n\n\t\tprotected override void WriteData(BamlBinaryWriter writer) => writer.Write(ValueId);\n\t}\n\n\tinternal class LiteralContentRecord : SizedBamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.LiteralContent;\n\n\t\tpublic string Value { get; set; }\n\t\tpublic uint Reserved0 { get; set; }\n\t\tpublic uint Reserved1 { get; set; }\n\n\t\tprotected override void ReadData(BamlBinaryReader reader, int size)\n\t\t{\n\t\t\tValue = reader.ReadString();\n\t\t\tReserved0 = reader.ReadUInt32();\n\t\t\tReserved1 = reader.ReadUInt32();\n\t\t}\n\n\t\tprotected override void WriteData(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(Value);\n\t\t\twriter.Write(Reserved0);\n\t\t\twriter.Write(Reserved1);\n\t\t}\n\t}\n\n\tinternal class RoutedEventRecord : SizedBamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.RoutedEvent;\n\n\t\tpublic string Value { get; set; }\n\t\tpublic ushort AttributeId { get; set; }\n\t\tpublic uint Reserved1 { get; set; }\n\n\t\tprotected override void ReadData(BamlBinaryReader reader, int size)\n\t\t{\n\t\t\tAttributeId = reader.ReadUInt16();\n\t\t\tValue = reader.ReadString();\n\t\t}\n\n\t\tprotected override void WriteData(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(Value);\n\t\t\twriter.Write(AttributeId);\n\t\t}\n\t}\n\n\tinternal class DocumentStartRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.DocumentStart;\n\n\t\tpublic bool LoadAsync { get; set; }\n\t\tpublic uint MaxAsyncRecords { get; set; }\n\t\tpublic bool DebugBaml { get; set; }\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t\tLoadAsync = reader.ReadBoolean();\n\t\t\tMaxAsyncRecords = reader.ReadUInt32();\n\t\t\tDebugBaml = reader.ReadBoolean();\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(LoadAsync);\n\t\t\twriter.Write(MaxAsyncRecords);\n\t\t\twriter.Write(DebugBaml);\n\t\t}\n\t}\n\n\tinternal class DocumentEndRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.DocumentEnd;\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t}\n\t}\n\n\tinternal class ElementStartRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.ElementStart;\n\n\t\tpublic ushort TypeId { get; set; }\n\t\tpublic byte Flags { get; set; }\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t\tTypeId = reader.ReadUInt16();\n\t\t\tFlags = reader.ReadByte();\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(TypeId);\n\t\t\twriter.Write(Flags);\n\t\t}\n\t}\n\n\tinternal class ElementEndRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.ElementEnd;\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t}\n\t}\n\n\tinternal class KeyElementStartRecord : DefAttributeKeyTypeRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.KeyElementStart;\n\t}\n\n\tinternal class KeyElementEndRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.KeyElementEnd;\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t}\n\t}\n\n\tinternal class ConnectionIdRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.ConnectionId;\n\n\t\tpublic uint ConnectionId { get; set; }\n\n\t\tpublic override void Read(BamlBinaryReader reader) => ConnectionId = reader.ReadUInt32();\n\n\t\tpublic override void Write(BamlBinaryWriter writer) => writer.Write(ConnectionId);\n\t}\n\n\tinternal class PropertyWithExtensionRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.PropertyWithExtension;\n\n\t\tpublic ushort AttributeId { get; set; }\n\t\tpublic ushort Flags { get; set; }\n\t\tpublic ushort ValueId { get; set; }\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t\tAttributeId = reader.ReadUInt16();\n\t\t\tFlags = reader.ReadUInt16();\n\t\t\tValueId = reader.ReadUInt16();\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(AttributeId);\n\t\t\twriter.Write(Flags);\n\t\t\twriter.Write(ValueId);\n\t\t}\n\t}\n\n\tinternal class PropertyTypeReferenceRecord : PropertyComplexStartRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.PropertyTypeReference;\n\n\t\tpublic ushort TypeId { get; set; }\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t\tbase.Read(reader);\n\t\t\tTypeId = reader.ReadUInt16();\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t\tbase.Write(writer);\n\t\t\twriter.Write(TypeId);\n\t\t}\n\t}\n\n\tinternal class PropertyStringReferenceRecord : PropertyComplexStartRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.PropertyStringReference;\n\n\t\tpublic ushort StringId { get; set; }\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t\tbase.Read(reader);\n\t\t\tStringId = reader.ReadUInt16();\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t\tbase.Write(writer);\n\t\t\twriter.Write(StringId);\n\t\t}\n\t}\n\n\tinternal class PropertyWithStaticResourceIdRecord : StaticResourceIdRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.PropertyWithStaticResourceId;\n\n\t\tpublic ushort AttributeId { get; set; }\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t\tAttributeId = reader.ReadUInt16();\n\t\t\tbase.Read(reader);\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(AttributeId);\n\t\t\tbase.Write(writer);\n\t\t}\n\t}\n\n\tinternal class ContentPropertyRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.ContentProperty;\n\n\t\tpublic ushort AttributeId { get; set; }\n\n\t\tpublic override void Read(BamlBinaryReader reader) => AttributeId = reader.ReadUInt16();\n\n\t\tpublic override void Write(BamlBinaryWriter writer) => writer.Write(AttributeId);\n\t}\n\n\tinternal class DefAttributeKeyTypeRecord : ElementStartRecord, IBamlDeferRecord\n\t{\n\t\tinternal uint pos = 0xffffffff;\n\n\t\tpublic override BamlRecordType Type => BamlRecordType.DefAttributeKeyType;\n\n\t\tpublic bool Shared { get; set; }\n\t\tpublic bool SharedSet { get; set; }\n\n\t\tpublic BamlRecord Record { get; set; }\n\n\t\tpublic void ReadDefer(BamlDocument doc, int index, Func<long, BamlRecord> resolve)\n\t\t{\n\t\t\tbool keys = true;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tswitch (doc[index].Type)\n\t\t\t\t{\n\t\t\t\t\tcase BamlRecordType.DefAttributeKeyString:\n\t\t\t\t\tcase BamlRecordType.DefAttributeKeyType:\n\t\t\t\t\tcase BamlRecordType.OptimizedStaticResource:\n\t\t\t\t\t\tkeys = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.StaticResourceStart:\n\t\t\t\t\t\tNavigateTree(doc, BamlRecordType.StaticResourceStart, BamlRecordType.StaticResourceEnd, ref index);\n\t\t\t\t\t\tkeys = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.KeyElementStart:\n\t\t\t\t\t\tNavigateTree(doc, BamlRecordType.KeyElementStart, BamlRecordType.KeyElementEnd, ref index);\n\t\t\t\t\t\tkeys = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tkeys = false;\n\t\t\t\t\t\tindex--;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tindex++;\n\t\t\t} while (keys);\n\t\t\tRecord = resolve(doc[index].Position + pos);\n\t\t}\n\n\t\tpublic void WriteDefer(BamlDocument doc, int index, BinaryWriter wtr)\n\t\t{\n\t\t\tbool keys = true;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tswitch (doc[index].Type)\n\t\t\t\t{\n\t\t\t\t\tcase BamlRecordType.DefAttributeKeyString:\n\t\t\t\t\tcase BamlRecordType.DefAttributeKeyType:\n\t\t\t\t\tcase BamlRecordType.OptimizedStaticResource:\n\t\t\t\t\t\tkeys = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.StaticResourceStart:\n\t\t\t\t\t\tNavigateTree(doc, BamlRecordType.StaticResourceStart, BamlRecordType.StaticResourceEnd, ref index);\n\t\t\t\t\t\tkeys = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BamlRecordType.KeyElementStart:\n\t\t\t\t\t\tNavigateTree(doc, BamlRecordType.KeyElementStart, BamlRecordType.KeyElementEnd, ref index);\n\t\t\t\t\t\tkeys = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tkeys = false;\n\t\t\t\t\t\tindex--;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tindex++;\n\t\t\t} while (keys);\n\t\t\twtr.BaseStream.Seek(pos, SeekOrigin.Begin);\n\t\t\twtr.Write((uint)(Record.Position - doc[index].Position));\n\t\t}\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t\tbase.Read(reader);\n\t\t\tpos = reader.ReadUInt32();\n\t\t\tShared = reader.ReadBoolean();\n\t\t\tSharedSet = reader.ReadBoolean();\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t\tbase.Write(writer);\n\t\t\tpos = (uint)writer.BaseStream.Position;\n\t\t\twriter.Write((uint)0);\n\t\t\twriter.Write(Shared);\n\t\t\twriter.Write(SharedSet);\n\t\t}\n\n\t\tstatic void NavigateTree(BamlDocument doc, BamlRecordType start, BamlRecordType end, ref int index)\n\t\t{\n\t\t\tindex++;\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tif (doc[index].Type == start)\n\t\t\t\t\tNavigateTree(doc, start, end, ref index);\n\t\t\t\telse if (doc[index].Type == end)\n\t\t\t\t\treturn;\n\t\t\t\tindex++;\n\t\t\t}\n\t\t}\n\t}\n\n\tinternal class PropertyListStartRecord : PropertyComplexStartRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.PropertyListStart;\n\t}\n\n\tinternal class PropertyListEndRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.PropertyListEnd;\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t}\n\t}\n\n\tinternal class PropertyDictionaryStartRecord : PropertyComplexStartRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.PropertyDictionaryStart;\n\t}\n\n\tinternal class PropertyDictionaryEndRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.PropertyDictionaryEnd;\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t}\n\t}\n\n\tinternal class PropertyArrayStartRecord : PropertyComplexStartRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.PropertyArrayStart;\n\t}\n\n\tinternal class PropertyArrayEndRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.PropertyArrayEnd;\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t}\n\t}\n\n\tinternal class PropertyComplexStartRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.PropertyComplexStart;\n\n\t\tpublic ushort AttributeId { get; set; }\n\n\t\tpublic override void Read(BamlBinaryReader reader) => AttributeId = reader.ReadUInt16();\n\n\t\tpublic override void Write(BamlBinaryWriter writer) => writer.Write(AttributeId);\n\t}\n\n\tinternal class PropertyComplexEndRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.PropertyComplexEnd;\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t}\n\t}\n\n\tinternal class ConstructorParametersStartRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.ConstructorParametersStart;\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t}\n\t}\n\n\tinternal class ConstructorParametersEndRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.ConstructorParametersEnd;\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t}\n\t}\n\n\tinternal class ConstructorParameterTypeRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.ConstructorParameterType;\n\n\t\tpublic ushort TypeId { get; set; }\n\n\t\tpublic override void Read(BamlBinaryReader reader) => TypeId = reader.ReadUInt16();\n\n\t\tpublic override void Write(BamlBinaryWriter writer) => writer.Write(TypeId);\n\t}\n\n\tinternal class DeferableContentStartRecord : BamlRecord, IBamlDeferRecord\n\t{\n\t\tlong pos;\n\t\tinternal uint size = 0xffffffff;\n\n\t\tpublic override BamlRecordType Type => BamlRecordType.DeferableContentStart;\n\n\t\tpublic BamlRecord Record { get; set; }\n\n\t\tpublic void ReadDefer(BamlDocument doc, int index, Func<long, BamlRecord> resolve) => Record = resolve(pos + size);\n\n\t\tpublic void WriteDefer(BamlDocument doc, int index, BinaryWriter wtr)\n\t\t{\n\t\t\twtr.BaseStream.Seek(pos, SeekOrigin.Begin);\n\t\t\twtr.Write((uint)(Record.Position - (pos + 4)));\n\t\t}\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t\tsize = reader.ReadUInt32();\n\t\t\tpos = reader.BaseStream.Position;\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t\tpos = writer.BaseStream.Position;\n\t\t\twriter.Write((uint)0);\n\t\t}\n\t}\n\n\tinternal class StaticResourceStartRecord : ElementStartRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.StaticResourceStart;\n\t}\n\n\tinternal class StaticResourceEndRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.StaticResourceEnd;\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t}\n\t}\n\n\tinternal class StaticResourceIdRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.StaticResourceId;\n\n\t\tpublic ushort StaticResourceId { get; set; }\n\n\t\tpublic override void Read(BamlBinaryReader reader) => StaticResourceId = reader.ReadUInt16();\n\n\t\tpublic override void Write(BamlBinaryWriter writer) => writer.Write(StaticResourceId);\n\t}\n\n\tinternal class OptimizedStaticResourceRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.OptimizedStaticResource;\n\n\t\tpublic byte Flags { get; set; }\n\t\tpublic ushort ValueId { get; set; }\n\n\t\tpublic bool IsType => (Flags & 1) != 0;\n\n\t\tpublic bool IsStatic => (Flags & 2) != 0;\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t\tFlags = reader.ReadByte();\n\t\t\tValueId = reader.ReadUInt16();\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(Flags);\n\t\t\twriter.Write(ValueId);\n\t\t}\n\t}\n\n\tinternal class LineNumberAndPositionRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.LineNumberAndPosition;\n\n\t\tpublic uint LineNumber { get; set; }\n\t\tpublic uint LinePosition { get; set; }\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t\tLineNumber = reader.ReadUInt32();\n\t\t\tLinePosition = reader.ReadUInt32();\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(LineNumber);\n\t\t\twriter.Write(LinePosition);\n\t\t}\n\t}\n\n\tinternal class LinePositionRecord : BamlRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.LinePosition;\n\n\t\tpublic uint LinePosition { get; set; }\n\n\t\tpublic override void Read(BamlBinaryReader reader) => LinePosition = reader.ReadUInt32();\n\n\t\tpublic override void Write(BamlBinaryWriter writer) => writer.Write(LinePosition);\n\t}\n\n\tinternal class NamedElementStartRecord : ElementStartRecord\n\t{\n\t\tpublic override BamlRecordType Type => BamlRecordType.NamedElementStart;\n\n\t\tpublic string RuntimeName { get; set; }\n\n\t\tpublic override void Read(BamlBinaryReader reader)\n\t\t{\n\t\t\tTypeId = reader.ReadUInt16();\n\t\t\tRuntimeName = reader.ReadString();\n\t\t}\n\n\t\tpublic override void Write(BamlBinaryWriter writer)\n\t\t{\n\t\t\twriter.Write(TypeId);\n\t\t\tif (RuntimeName != null)\n\t\t\t{\n\t\t\t\twriter.Write(RuntimeName);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Baml/BamlWriter.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Text;\n\nnamespace ICSharpCode.BamlDecompiler.Baml\n{\n\tinternal class BamlBinaryWriter : BinaryWriter\n\t{\n\t\tpublic BamlBinaryWriter(Stream stream)\n\t\t\t: base(stream)\n\t\t{\n\t\t}\n\n\t\tpublic void WriteEncodedInt(int val) => Write7BitEncodedInt(val);\n\t}\n\n\tinternal class BamlWriter\n\t{\n\t\tpublic static void WriteDocument(BamlDocument doc, Stream str)\n\t\t{\n\t\t\tvar writer = new BamlBinaryWriter(str);\n\t\t\t{\n\t\t\t\tvar wtr = new BinaryWriter(str, Encoding.Unicode);\n\t\t\t\tint len = doc.Signature.Length * 2;\n\t\t\t\twtr.Write(len);\n\t\t\t\twtr.Write(doc.Signature.ToCharArray());\n\t\t\t\twtr.Write(new byte[((len + 3) & ~3) - len]);\n\t\t\t}\n\t\t\twriter.Write(doc.ReaderVersion.Major);\n\t\t\twriter.Write(doc.ReaderVersion.Minor);\n\t\t\twriter.Write(doc.UpdaterVersion.Major);\n\t\t\twriter.Write(doc.UpdaterVersion.Minor);\n\t\t\twriter.Write(doc.WriterVersion.Major);\n\t\t\twriter.Write(doc.WriterVersion.Minor);\n\n\t\t\tvar defers = new List<int>();\n\t\t\tfor (int i = 0; i < doc.Count; i++)\n\t\t\t{\n\t\t\t\tBamlRecord rec = doc[i];\n\t\t\t\trec.Position = str.Position;\n\t\t\t\twriter.Write((byte)rec.Type);\n\t\t\t\trec.Write(writer);\n\t\t\t\tif (rec is IBamlDeferRecord)\n\t\t\t\t\tdefers.Add(i);\n\t\t\t}\n\t\t\tforeach (int i in defers)\n\t\t\t\t(doc[i] as IBamlDeferRecord).WriteDefer(doc, i, writer);\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Baml/KnownMembers.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nnamespace ICSharpCode.BamlDecompiler.Baml\n{\n\t// Auto generated. Do not modify.\n\n\tinternal enum KnownMembers : short\n\t{\n\t\tUnknown = 0,\n\t\tAccessText_Text = 1,\n\t\tBeginStoryboard_Storyboard = 2,\n\t\tBitmapEffectGroup_Children = 3,\n\t\tBorder_Background = 4,\n\t\tBorder_BorderBrush = 5,\n\t\tBorder_BorderThickness = 6,\n\t\tButtonBase_Command = 7,\n\t\tButtonBase_CommandParameter = 8,\n\t\tButtonBase_CommandTarget = 9,\n\t\tButtonBase_IsPressed = 10,\n\t\tColumnDefinition_MaxWidth = 11,\n\t\tColumnDefinition_MinWidth = 12,\n\t\tColumnDefinition_Width = 13,\n\t\tContentControl_Content = 14,\n\t\tContentControl_ContentTemplate = 15,\n\t\tContentControl_ContentTemplateSelector = 16,\n\t\tContentControl_HasContent = 17,\n\t\tContentElement_Focusable = 18,\n\t\tContentPresenter_Content = 19,\n\t\tContentPresenter_ContentSource = 20,\n\t\tContentPresenter_ContentTemplate = 21,\n\t\tContentPresenter_ContentTemplateSelector = 22,\n\t\tContentPresenter_RecognizesAccessKey = 23,\n\t\tControl_Background = 24,\n\t\tControl_BorderBrush = 25,\n\t\tControl_BorderThickness = 26,\n\t\tControl_FontFamily = 27,\n\t\tControl_FontSize = 28,\n\t\tControl_FontStretch = 29,\n\t\tControl_FontStyle = 30,\n\t\tControl_FontWeight = 31,\n\t\tControl_Foreground = 32,\n\t\tControl_HorizontalContentAlignment = 33,\n\t\tControl_IsTabStop = 34,\n\t\tControl_Padding = 35,\n\t\tControl_TabIndex = 36,\n\t\tControl_Template = 37,\n\t\tControl_VerticalContentAlignment = 38,\n\t\tDockPanel_Dock = 39,\n\t\tDockPanel_LastChildFill = 40,\n\t\tDocumentViewerBase_Document = 41,\n\t\tDrawingGroup_Children = 42,\n\t\tFlowDocumentReader_Document = 43,\n\t\tFlowDocumentScrollViewer_Document = 44,\n\t\tFrameworkContentElement_Style = 45,\n\t\tFrameworkElement_FlowDirection = 46,\n\t\tFrameworkElement_Height = 47,\n\t\tFrameworkElement_HorizontalAlignment = 48,\n\t\tFrameworkElement_Margin = 49,\n\t\tFrameworkElement_MaxHeight = 50,\n\t\tFrameworkElement_MaxWidth = 51,\n\t\tFrameworkElement_MinHeight = 52,\n\t\tFrameworkElement_MinWidth = 53,\n\t\tFrameworkElement_Name = 54,\n\t\tFrameworkElement_Style = 55,\n\t\tFrameworkElement_VerticalAlignment = 56,\n\t\tFrameworkElement_Width = 57,\n\t\tGeneralTransformGroup_Children = 58,\n\t\tGeometryGroup_Children = 59,\n\t\tGradientBrush_GradientStops = 60,\n\t\tGrid_Column = 61,\n\t\tGrid_ColumnSpan = 62,\n\t\tGrid_Row = 63,\n\t\tGrid_RowSpan = 64,\n\t\tGridViewColumn_Header = 65,\n\t\tHeaderedContentControl_HasHeader = 66,\n\t\tHeaderedContentControl_Header = 67,\n\t\tHeaderedContentControl_HeaderTemplate = 68,\n\t\tHeaderedContentControl_HeaderTemplateSelector = 69,\n\t\tHeaderedItemsControl_HasHeader = 70,\n\t\tHeaderedItemsControl_Header = 71,\n\t\tHeaderedItemsControl_HeaderTemplate = 72,\n\t\tHeaderedItemsControl_HeaderTemplateSelector = 73,\n\t\tHyperlink_NavigateUri = 74,\n\t\tImage_Source = 75,\n\t\tImage_Stretch = 76,\n\t\tItemsControl_ItemContainerStyle = 77,\n\t\tItemsControl_ItemContainerStyleSelector = 78,\n\t\tItemsControl_ItemTemplate = 79,\n\t\tItemsControl_ItemTemplateSelector = 80,\n\t\tItemsControl_ItemsPanel = 81,\n\t\tItemsControl_ItemsSource = 82,\n\t\tMaterialGroup_Children = 83,\n\t\tModel3DGroup_Children = 84,\n\t\tPage_Content = 85,\n\t\tPanel_Background = 86,\n\t\tPath_Data = 87,\n\t\tPathFigure_Segments = 88,\n\t\tPathGeometry_Figures = 89,\n\t\tPopup_Child = 90,\n\t\tPopup_IsOpen = 91,\n\t\tPopup_Placement = 92,\n\t\tPopup_PopupAnimation = 93,\n\t\tRowDefinition_Height = 94,\n\t\tRowDefinition_MaxHeight = 95,\n\t\tRowDefinition_MinHeight = 96,\n\t\tScrollViewer_CanContentScroll = 97,\n\t\tScrollViewer_HorizontalScrollBarVisibility = 98,\n\t\tScrollViewer_VerticalScrollBarVisibility = 99,\n\t\tShape_Fill = 100,\n\t\tShape_Stroke = 101,\n\t\tShape_StrokeThickness = 102,\n\t\tTextBlock_Background = 103,\n\t\tTextBlock_FontFamily = 104,\n\t\tTextBlock_FontSize = 105,\n\t\tTextBlock_FontStretch = 106,\n\t\tTextBlock_FontStyle = 107,\n\t\tTextBlock_FontWeight = 108,\n\t\tTextBlock_Foreground = 109,\n\t\tTextBlock_Text = 110,\n\t\tTextBlock_TextDecorations = 111,\n\t\tTextBlock_TextTrimming = 112,\n\t\tTextBlock_TextWrapping = 113,\n\t\tTextBox_Text = 114,\n\t\tTextElement_Background = 115,\n\t\tTextElement_FontFamily = 116,\n\t\tTextElement_FontSize = 117,\n\t\tTextElement_FontStretch = 118,\n\t\tTextElement_FontStyle = 119,\n\t\tTextElement_FontWeight = 120,\n\t\tTextElement_Foreground = 121,\n\t\tTimelineGroup_Children = 122,\n\t\tTrack_IsDirectionReversed = 123,\n\t\tTrack_Maximum = 124,\n\t\tTrack_Minimum = 125,\n\t\tTrack_Orientation = 126,\n\t\tTrack_Value = 127,\n\t\tTrack_ViewportSize = 128,\n\t\tTransform3DGroup_Children = 129,\n\t\tTransformGroup_Children = 130,\n\t\tUIElement_ClipToBounds = 131,\n\t\tUIElement_Focusable = 132,\n\t\tUIElement_IsEnabled = 133,\n\t\tUIElement_RenderTransform = 134,\n\t\tUIElement_Visibility = 135,\n\t\tViewport3D_Children = 136,\n\n\t\tAdornedElementPlaceholder_Child = 138,\n\t\tAdornerDecorator_Child = 139,\n\t\tAnchoredBlock_Blocks = 140,\n\t\tArrayExtension_Items = 141,\n\t\tBlockUIContainer_Child = 142,\n\t\tBold_Inlines = 143,\n\t\tBooleanAnimationUsingKeyFrames_KeyFrames = 144,\n\t\tBorder_Child = 145,\n\t\tBulletDecorator_Child = 146,\n\t\tButton_Content = 147,\n\t\tButtonBase_Content = 148,\n\t\tByteAnimationUsingKeyFrames_KeyFrames = 149,\n\t\tCanvas_Children = 150,\n\t\tCharAnimationUsingKeyFrames_KeyFrames = 151,\n\t\tCheckBox_Content = 152,\n\t\tColorAnimationUsingKeyFrames_KeyFrames = 153,\n\t\tComboBox_Items = 154,\n\t\tComboBoxItem_Content = 155,\n\t\tContextMenu_Items = 156,\n\t\tControlTemplate_VisualTree = 157,\n\t\tDataTemplate_VisualTree = 158,\n\t\tDataTrigger_Setters = 159,\n\t\tDecimalAnimationUsingKeyFrames_KeyFrames = 160,\n\t\tDecorator_Child = 161,\n\t\tDockPanel_Children = 162,\n\t\tDocumentViewer_Document = 163,\n\t\tDoubleAnimationUsingKeyFrames_KeyFrames = 164,\n\t\tEventTrigger_Actions = 165,\n\t\tExpander_Content = 166,\n\t\tFigure_Blocks = 167,\n\t\tFixedDocument_Pages = 168,\n\t\tFixedDocumentSequence_References = 169,\n\t\tFixedPage_Children = 170,\n\t\tFloater_Blocks = 171,\n\t\tFlowDocument_Blocks = 172,\n\t\tFlowDocumentPageViewer_Document = 173,\n\t\tFrameworkTemplate_VisualTree = 174,\n\t\tGrid_Children = 175,\n\t\tGridView_Columns = 176,\n\t\tGridViewColumnHeader_Content = 177,\n\t\tGroupBox_Content = 178,\n\t\tGroupItem_Content = 179,\n\t\tHeaderedContentControl_Content = 180,\n\t\tHeaderedItemsControl_Items = 181,\n\t\tHierarchicalDataTemplate_VisualTree = 182,\n\t\tHyperlink_Inlines = 183,\n\t\tInkCanvas_Children = 184,\n\t\tInkPresenter_Child = 185,\n\t\tInlineUIContainer_Child = 186,\n\t\tInputScopeName_NameValue = 187,\n\t\tInt16AnimationUsingKeyFrames_KeyFrames = 188,\n\t\tInt32AnimationUsingKeyFrames_KeyFrames = 189,\n\t\tInt64AnimationUsingKeyFrames_KeyFrames = 190,\n\t\tItalic_Inlines = 191,\n\t\tItemsControl_Items = 192,\n\t\tItemsPanelTemplate_VisualTree = 193,\n\t\tLabel_Content = 194,\n\t\tLinearGradientBrush_GradientStops = 195,\n\t\tList_ListItems = 196,\n\t\tListBox_Items = 197,\n\t\tListBoxItem_Content = 198,\n\t\tListItem_Blocks = 199,\n\t\tListView_Items = 200,\n\t\tListViewItem_Content = 201,\n\t\tMatrixAnimationUsingKeyFrames_KeyFrames = 202,\n\t\tMenu_Items = 203,\n\t\tMenuBase_Items = 204,\n\t\tMenuItem_Items = 205,\n\t\tModelVisual3D_Children = 206,\n\t\tMultiBinding_Bindings = 207,\n\t\tMultiDataTrigger_Setters = 208,\n\t\tMultiTrigger_Setters = 209,\n\t\tObjectAnimationUsingKeyFrames_KeyFrames = 210,\n\t\tPageContent_Child = 211,\n\t\tPageFunctionBase_Content = 212,\n\t\tPanel_Children = 213,\n\t\tParagraph_Inlines = 214,\n\t\tParallelTimeline_Children = 215,\n\t\tPoint3DAnimationUsingKeyFrames_KeyFrames = 216,\n\t\tPointAnimationUsingKeyFrames_KeyFrames = 217,\n\t\tPriorityBinding_Bindings = 218,\n\t\tQuaternionAnimationUsingKeyFrames_KeyFrames = 219,\n\t\tRadialGradientBrush_GradientStops = 220,\n\t\tRadioButton_Content = 221,\n\t\tRectAnimationUsingKeyFrames_KeyFrames = 222,\n\t\tRepeatButton_Content = 223,\n\t\tRichTextBox_Document = 224,\n\t\tRotation3DAnimationUsingKeyFrames_KeyFrames = 225,\n\t\tRun_Text = 226,\n\t\tScrollViewer_Content = 227,\n\t\tSection_Blocks = 228,\n\t\tSelector_Items = 229,\n\t\tSingleAnimationUsingKeyFrames_KeyFrames = 230,\n\t\tSizeAnimationUsingKeyFrames_KeyFrames = 231,\n\t\tSpan_Inlines = 232,\n\t\tStackPanel_Children = 233,\n\t\tStatusBar_Items = 234,\n\t\tStatusBarItem_Content = 235,\n\t\tStoryboard_Children = 236,\n\t\tStringAnimationUsingKeyFrames_KeyFrames = 237,\n\t\tStyle_Setters = 238,\n\t\tTabControl_Items = 239,\n\t\tTabItem_Content = 240,\n\t\tTabPanel_Children = 241,\n\t\tTable_RowGroups = 242,\n\t\tTableCell_Blocks = 243,\n\t\tTableRow_Cells = 244,\n\t\tTableRowGroup_Rows = 245,\n\t\tTextBlock_Inlines = 246,\n\t\tThicknessAnimationUsingKeyFrames_KeyFrames = 247,\n\t\tToggleButton_Content = 248,\n\t\tToolBar_Items = 249,\n\t\tToolBarOverflowPanel_Children = 250,\n\t\tToolBarPanel_Children = 251,\n\t\tToolBarTray_ToolBars = 252,\n\t\tToolTip_Content = 253,\n\t\tTreeView_Items = 254,\n\t\tTreeViewItem_Items = 255,\n\t\tTrigger_Setters = 256,\n\t\tUnderline_Inlines = 257,\n\t\tUniformGrid_Children = 258,\n\t\tUserControl_Content = 259,\n\t\tVector3DAnimationUsingKeyFrames_KeyFrames = 260,\n\t\tVectorAnimationUsingKeyFrames_KeyFrames = 261,\n\t\tViewbox_Child = 262,\n\t\tViewport3DVisual_Children = 263,\n\t\tVirtualizingPanel_Children = 264,\n\t\tVirtualizingStackPanel_Children = 265,\n\t\tWindow_Content = 266,\n\t\tWrapPanel_Children = 267,\n\t\tXmlDataProvider_XmlSerializer = 268,\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Baml/KnownThings.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.BamlDecompiler.Baml\n{\n\tinternal partial class KnownThings\n\t{\n\t\treadonly IDecompilerTypeSystem typeSystem;\n\n\t\treadonly Dictionary<int, IModule> assemblies;\n\t\treadonly Dictionary<KnownMembers, KnownMember> members;\n\t\treadonly Dictionary<KnownTypes, ITypeDefinition> types;\n\t\treadonly Dictionary<int, string> strings;\n\t\treadonly Dictionary<int, (string, string, string)> resources;\n\n\t\tpublic KnownThings(IDecompilerTypeSystem typeSystem)\n\t\t{\n\t\t\tthis.typeSystem = typeSystem;\n\n\t\t\tassemblies = new Dictionary<int, IModule>();\n\t\t\ttypes = new Dictionary<KnownTypes, ITypeDefinition>();\n\t\t\tmembers = new Dictionary<KnownMembers, KnownMember>();\n\t\t\tstrings = new Dictionary<int, string>();\n\t\t\tresources = new Dictionary<int, (string, string, string)>();\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tInitAssemblies();\n\t\t\t\tInitTypes();\n\t\t\t\tInitMembers();\n\t\t\t\tInitStrings();\n\t\t\t\tInitResources();\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tthrow new ICSharpCode.Decompiler.DecompilerException(typeSystem.MainModule.MetadataFile, ex.Message, ex);\n\t\t\t}\n\t\t}\n\n\t\tpublic Func<KnownTypes, ITypeDefinition> Types => id => types[id];\n\t\tpublic Func<KnownMembers, KnownMember> Members => id => members[id];\n\t\tpublic Func<short, string> Strings => id => strings[id];\n\t\tpublic Func<short, (string, string, string)> Resources => id => resources[id];\n\t\tpublic IModule FrameworkAssembly => assemblies[0];\n\t\tIModule ResolveAssembly(string name)\n\t\t{\n\t\t\tIModule module = typeSystem.Modules.FirstOrDefault(m => m.AssemblyName == name);\n\t\t\tif (module == null)\n\t\t\t\tthrow new Exception(\"Could not resolve known assembly '\" + name + \"'!\");\n\t\t\treturn module;\n\t\t}\n\n\t\tITypeDefinition InitType(IModule assembly, string ns, string name) => assembly.GetTypeDefinition(new TopLevelTypeName(ns, name));\n\t\tKnownMember InitMember(KnownTypes parent, string name, ITypeDefinition type) => new KnownMember(parent, types[parent], name, type);\n\t}\n\n\tinternal class KnownMember\n\t{\n\t\tpublic KnownMember(KnownTypes parent, ITypeDefinition declType, string name, ITypeDefinition type)\n\t\t{\n\t\t\tParent = parent;\n\t\t\tProperty = declType.GetProperties(p => p.Name == name, GetMemberOptions.IgnoreInheritedMembers).SingleOrDefault();\n\t\t\tDeclaringType = declType;\n\t\t\tName = name;\n\t\t\tType = type;\n\t\t}\n\n\t\tpublic KnownTypes Parent { get; }\n\t\tpublic ITypeDefinition DeclaringType { get; }\n\t\tpublic IProperty Property { get; }\n\t\tpublic string Name { get; }\n\t\tpublic ITypeDefinition Type { get; }\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Baml/KnownThings.g.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System;\n\nnamespace ICSharpCode.BamlDecompiler.Baml\n{\n\tinternal partial class KnownThings\n\t{\n\t\t// Auto-generated. Do not modify.\n\n\t\tvoid InitAssemblies()\n\t\t{\n\t\t\tassemblies[0] = ResolveAssembly(\"mscorlib\");\n\t\t\tassemblies[1] = ResolveAssembly(\"System\");\n\t\t\tassemblies[2] = ResolveAssembly(\"WindowsBase\");\n\t\t\tassemblies[3] = ResolveAssembly(\"PresentationCore\");\n\t\t\tassemblies[4] = ResolveAssembly(\"PresentationFramework\");\n\t\t\tassemblies[5] = ResolveAssembly(\"System.Xml\");\n\t\t}\n\n\t\tvoid InitTypes()\n\t\t{\n\n\t\t\ttypes[KnownTypes.AccessText] = InitType(assemblies[4], \"System.Windows.Controls\", \"AccessText\");\n\t\t\ttypes[KnownTypes.AdornedElementPlaceholder] = InitType(assemblies[4], \"System.Windows.Controls\", \"AdornedElementPlaceholder\");\n\t\t\ttypes[KnownTypes.Adorner] = InitType(assemblies[4], \"System.Windows.Documents\", \"Adorner\");\n\t\t\ttypes[KnownTypes.AdornerDecorator] = InitType(assemblies[4], \"System.Windows.Documents\", \"AdornerDecorator\");\n\t\t\ttypes[KnownTypes.AdornerLayer] = InitType(assemblies[4], \"System.Windows.Documents\", \"AdornerLayer\");\n\t\t\ttypes[KnownTypes.AffineTransform3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"AffineTransform3D\");\n\t\t\ttypes[KnownTypes.AmbientLight] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"AmbientLight\");\n\t\t\ttypes[KnownTypes.AnchoredBlock] = InitType(assemblies[4], \"System.Windows.Documents\", \"AnchoredBlock\");\n\t\t\ttypes[KnownTypes.Animatable] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Animatable\");\n\t\t\ttypes[KnownTypes.AnimationClock] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"AnimationClock\");\n\t\t\ttypes[KnownTypes.AnimationTimeline] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"AnimationTimeline\");\n\t\t\ttypes[KnownTypes.Application] = InitType(assemblies[4], \"System.Windows\", \"Application\");\n\t\t\ttypes[KnownTypes.ArcSegment] = InitType(assemblies[3], \"System.Windows.Media\", \"ArcSegment\");\n\t\t\ttypes[KnownTypes.ArrayExtension] = InitType(assemblies[4], \"System.Windows.Markup\", \"ArrayExtension\");\n\t\t\ttypes[KnownTypes.AxisAngleRotation3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"AxisAngleRotation3D\");\n\t\t\ttypes[KnownTypes.BaseIListConverter] = InitType(assemblies[3], \"System.Windows.Media.Converters\", \"BaseIListConverter\");\n\t\t\ttypes[KnownTypes.BeginStoryboard] = InitType(assemblies[4], \"System.Windows.Media.Animation\", \"BeginStoryboard\");\n\t\t\ttypes[KnownTypes.BevelBitmapEffect] = InitType(assemblies[3], \"System.Windows.Media.Effects\", \"BevelBitmapEffect\");\n\t\t\ttypes[KnownTypes.BezierSegment] = InitType(assemblies[3], \"System.Windows.Media\", \"BezierSegment\");\n\t\t\ttypes[KnownTypes.Binding] = InitType(assemblies[4], \"System.Windows.Data\", \"Binding\");\n\t\t\ttypes[KnownTypes.BindingBase] = InitType(assemblies[4], \"System.Windows.Data\", \"BindingBase\");\n\t\t\ttypes[KnownTypes.BindingExpression] = InitType(assemblies[4], \"System.Windows.Data\", \"BindingExpression\");\n\t\t\ttypes[KnownTypes.BindingExpressionBase] = InitType(assemblies[4], \"System.Windows.Data\", \"BindingExpressionBase\");\n\t\t\ttypes[KnownTypes.BindingListCollectionView] = InitType(assemblies[4], \"System.Windows.Data\", \"BindingListCollectionView\");\n\t\t\ttypes[KnownTypes.BitmapDecoder] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"BitmapDecoder\");\n\t\t\ttypes[KnownTypes.BitmapEffect] = InitType(assemblies[3], \"System.Windows.Media.Effects\", \"BitmapEffect\");\n\t\t\ttypes[KnownTypes.BitmapEffectCollection] = InitType(assemblies[3], \"System.Windows.Media.Effects\", \"BitmapEffectCollection\");\n\t\t\ttypes[KnownTypes.BitmapEffectGroup] = InitType(assemblies[3], \"System.Windows.Media.Effects\", \"BitmapEffectGroup\");\n\t\t\ttypes[KnownTypes.BitmapEffectInput] = InitType(assemblies[3], \"System.Windows.Media.Effects\", \"BitmapEffectInput\");\n\t\t\ttypes[KnownTypes.BitmapEncoder] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"BitmapEncoder\");\n\t\t\ttypes[KnownTypes.BitmapFrame] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"BitmapFrame\");\n\t\t\ttypes[KnownTypes.BitmapImage] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"BitmapImage\");\n\t\t\ttypes[KnownTypes.BitmapMetadata] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"BitmapMetadata\");\n\t\t\ttypes[KnownTypes.BitmapPalette] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"BitmapPalette\");\n\t\t\ttypes[KnownTypes.BitmapSource] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"BitmapSource\");\n\t\t\ttypes[KnownTypes.Block] = InitType(assemblies[4], \"System.Windows.Documents\", \"Block\");\n\t\t\ttypes[KnownTypes.BlockUIContainer] = InitType(assemblies[4], \"System.Windows.Documents\", \"BlockUIContainer\");\n\t\t\ttypes[KnownTypes.BlurBitmapEffect] = InitType(assemblies[3], \"System.Windows.Media.Effects\", \"BlurBitmapEffect\");\n\t\t\ttypes[KnownTypes.BmpBitmapDecoder] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"BmpBitmapDecoder\");\n\t\t\ttypes[KnownTypes.BmpBitmapEncoder] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"BmpBitmapEncoder\");\n\t\t\ttypes[KnownTypes.Bold] = InitType(assemblies[4], \"System.Windows.Documents\", \"Bold\");\n\t\t\ttypes[KnownTypes.BoolIListConverter] = InitType(assemblies[3], \"System.Windows.Media.Converters\", \"BoolIListConverter\");\n\t\t\ttypes[KnownTypes.Boolean] = InitType(assemblies[0], \"System\", \"Boolean\");\n\t\t\ttypes[KnownTypes.BooleanAnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"BooleanAnimationBase\");\n\t\t\ttypes[KnownTypes.BooleanAnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"BooleanAnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.BooleanConverter] = InitType(assemblies[1], \"System.ComponentModel\", \"BooleanConverter\");\n\t\t\ttypes[KnownTypes.BooleanKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"BooleanKeyFrame\");\n\t\t\ttypes[KnownTypes.BooleanKeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"BooleanKeyFrameCollection\");\n\t\t\ttypes[KnownTypes.BooleanToVisibilityConverter] = InitType(assemblies[4], \"System.Windows.Controls\", \"BooleanToVisibilityConverter\");\n\t\t\ttypes[KnownTypes.Border] = InitType(assemblies[4], \"System.Windows.Controls\", \"Border\");\n\t\t\ttypes[KnownTypes.BorderGapMaskConverter] = InitType(assemblies[4], \"System.Windows.Controls\", \"BorderGapMaskConverter\");\n\t\t\ttypes[KnownTypes.Brush] = InitType(assemblies[3], \"System.Windows.Media\", \"Brush\");\n\t\t\ttypes[KnownTypes.BrushConverter] = InitType(assemblies[3], \"System.Windows.Media\", \"BrushConverter\");\n\t\t\ttypes[KnownTypes.BulletDecorator] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"BulletDecorator\");\n\t\t\ttypes[KnownTypes.Button] = InitType(assemblies[4], \"System.Windows.Controls\", \"Button\");\n\t\t\ttypes[KnownTypes.ButtonBase] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"ButtonBase\");\n\t\t\ttypes[KnownTypes.Byte] = InitType(assemblies[0], \"System\", \"Byte\");\n\t\t\ttypes[KnownTypes.ByteAnimation] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ByteAnimation\");\n\t\t\ttypes[KnownTypes.ByteAnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ByteAnimationBase\");\n\t\t\ttypes[KnownTypes.ByteAnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ByteAnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.ByteConverter] = InitType(assemblies[1], \"System.ComponentModel\", \"ByteConverter\");\n\t\t\ttypes[KnownTypes.ByteKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ByteKeyFrame\");\n\t\t\ttypes[KnownTypes.ByteKeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ByteKeyFrameCollection\");\n\t\t\ttypes[KnownTypes.CachedBitmap] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"CachedBitmap\");\n\t\t\ttypes[KnownTypes.Camera] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Camera\");\n\t\t\ttypes[KnownTypes.Canvas] = InitType(assemblies[4], \"System.Windows.Controls\", \"Canvas\");\n\t\t\ttypes[KnownTypes.Char] = InitType(assemblies[0], \"System\", \"Char\");\n\t\t\ttypes[KnownTypes.CharAnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"CharAnimationBase\");\n\t\t\ttypes[KnownTypes.CharAnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"CharAnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.CharConverter] = InitType(assemblies[1], \"System.ComponentModel\", \"CharConverter\");\n\t\t\ttypes[KnownTypes.CharIListConverter] = InitType(assemblies[3], \"System.Windows.Media.Converters\", \"CharIListConverter\");\n\t\t\ttypes[KnownTypes.CharKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"CharKeyFrame\");\n\t\t\ttypes[KnownTypes.CharKeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"CharKeyFrameCollection\");\n\t\t\ttypes[KnownTypes.CheckBox] = InitType(assemblies[4], \"System.Windows.Controls\", \"CheckBox\");\n\t\t\ttypes[KnownTypes.Clock] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Clock\");\n\t\t\ttypes[KnownTypes.ClockController] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ClockController\");\n\t\t\ttypes[KnownTypes.ClockGroup] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ClockGroup\");\n\t\t\ttypes[KnownTypes.CollectionContainer] = InitType(assemblies[4], \"System.Windows.Data\", \"CollectionContainer\");\n\t\t\ttypes[KnownTypes.CollectionView] = InitType(assemblies[4], \"System.Windows.Data\", \"CollectionView\");\n\t\t\ttypes[KnownTypes.CollectionViewSource] = InitType(assemblies[4], \"System.Windows.Data\", \"CollectionViewSource\");\n\t\t\ttypes[KnownTypes.Color] = InitType(assemblies[3], \"System.Windows.Media\", \"Color\");\n\t\t\ttypes[KnownTypes.ColorAnimation] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ColorAnimation\");\n\t\t\ttypes[KnownTypes.ColorAnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ColorAnimationBase\");\n\t\t\ttypes[KnownTypes.ColorAnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ColorAnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.ColorConvertedBitmap] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"ColorConvertedBitmap\");\n\t\t\ttypes[KnownTypes.ColorConvertedBitmapExtension] = InitType(assemblies[4], \"System.Windows\", \"ColorConvertedBitmapExtension\");\n\t\t\ttypes[KnownTypes.ColorConverter] = InitType(assemblies[3], \"System.Windows.Media\", \"ColorConverter\");\n\t\t\ttypes[KnownTypes.ColorKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ColorKeyFrame\");\n\t\t\ttypes[KnownTypes.ColorKeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ColorKeyFrameCollection\");\n\t\t\ttypes[KnownTypes.ColumnDefinition] = InitType(assemblies[4], \"System.Windows.Controls\", \"ColumnDefinition\");\n\t\t\ttypes[KnownTypes.CombinedGeometry] = InitType(assemblies[3], \"System.Windows.Media\", \"CombinedGeometry\");\n\t\t\ttypes[KnownTypes.ComboBox] = InitType(assemblies[4], \"System.Windows.Controls\", \"ComboBox\");\n\t\t\ttypes[KnownTypes.ComboBoxItem] = InitType(assemblies[4], \"System.Windows.Controls\", \"ComboBoxItem\");\n\t\t\ttypes[KnownTypes.CommandConverter] = InitType(assemblies[4], \"System.Windows.Input\", \"CommandConverter\");\n\t\t\ttypes[KnownTypes.ComponentResourceKey] = InitType(assemblies[4], \"System.Windows\", \"ComponentResourceKey\");\n\t\t\ttypes[KnownTypes.ComponentResourceKeyConverter] = InitType(assemblies[4], \"System.Windows.Markup\", \"ComponentResourceKeyConverter\");\n\t\t\ttypes[KnownTypes.CompositionTarget] = InitType(assemblies[3], \"System.Windows.Media\", \"CompositionTarget\");\n\t\t\ttypes[KnownTypes.Condition] = InitType(assemblies[4], \"System.Windows\", \"Condition\");\n\t\t\ttypes[KnownTypes.ContainerVisual] = InitType(assemblies[3], \"System.Windows.Media\", \"ContainerVisual\");\n\t\t\ttypes[KnownTypes.ContentControl] = InitType(assemblies[4], \"System.Windows.Controls\", \"ContentControl\");\n\t\t\ttypes[KnownTypes.ContentElement] = InitType(assemblies[3], \"System.Windows\", \"ContentElement\");\n\t\t\ttypes[KnownTypes.ContentPresenter] = InitType(assemblies[4], \"System.Windows.Controls\", \"ContentPresenter\");\n\t\t\ttypes[KnownTypes.ContentPropertyAttribute] = InitType(assemblies[2], \"System.Windows.Markup\", \"ContentPropertyAttribute\");\n\t\t\ttypes[KnownTypes.ContentWrapperAttribute] = InitType(assemblies[2], \"System.Windows.Markup\", \"ContentWrapperAttribute\");\n\t\t\ttypes[KnownTypes.ContextMenu] = InitType(assemblies[4], \"System.Windows.Controls\", \"ContextMenu\");\n\t\t\ttypes[KnownTypes.ContextMenuService] = InitType(assemblies[4], \"System.Windows.Controls\", \"ContextMenuService\");\n\t\t\ttypes[KnownTypes.Control] = InitType(assemblies[4], \"System.Windows.Controls\", \"Control\");\n\t\t\ttypes[KnownTypes.ControlTemplate] = InitType(assemblies[4], \"System.Windows.Controls\", \"ControlTemplate\");\n\t\t\ttypes[KnownTypes.ControllableStoryboardAction] = InitType(assemblies[4], \"System.Windows.Media.Animation\", \"ControllableStoryboardAction\");\n\t\t\ttypes[KnownTypes.CornerRadius] = InitType(assemblies[4], \"System.Windows\", \"CornerRadius\");\n\t\t\ttypes[KnownTypes.CornerRadiusConverter] = InitType(assemblies[4], \"System.Windows\", \"CornerRadiusConverter\");\n\t\t\ttypes[KnownTypes.CroppedBitmap] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"CroppedBitmap\");\n\t\t\ttypes[KnownTypes.CultureInfo] = InitType(assemblies[0], \"System.Globalization\", \"CultureInfo\");\n\t\t\ttypes[KnownTypes.CultureInfoConverter] = InitType(assemblies[1], \"System.ComponentModel\", \"CultureInfoConverter\");\n\t\t\ttypes[KnownTypes.CultureInfoIetfLanguageTagConverter] = InitType(assemblies[3], \"System.Windows\", \"CultureInfoIetfLanguageTagConverter\");\n\t\t\ttypes[KnownTypes.Cursor] = InitType(assemblies[3], \"System.Windows.Input\", \"Cursor\");\n\t\t\ttypes[KnownTypes.CursorConverter] = InitType(assemblies[3], \"System.Windows.Input\", \"CursorConverter\");\n\t\t\ttypes[KnownTypes.DashStyle] = InitType(assemblies[3], \"System.Windows.Media\", \"DashStyle\");\n\t\t\ttypes[KnownTypes.DataChangedEventManager] = InitType(assemblies[4], \"System.Windows.Data\", \"DataChangedEventManager\");\n\t\t\ttypes[KnownTypes.DataTemplate] = InitType(assemblies[4], \"System.Windows\", \"DataTemplate\");\n\t\t\ttypes[KnownTypes.DataTemplateKey] = InitType(assemblies[4], \"System.Windows\", \"DataTemplateKey\");\n\t\t\ttypes[KnownTypes.DataTrigger] = InitType(assemblies[4], \"System.Windows\", \"DataTrigger\");\n\t\t\ttypes[KnownTypes.DateTime] = InitType(assemblies[0], \"System\", \"DateTime\");\n\t\t\ttypes[KnownTypes.DateTimeConverter] = InitType(assemblies[1], \"System.ComponentModel\", \"DateTimeConverter\");\n\t\t\ttypes[KnownTypes.DateTimeConverter2] = InitType(assemblies[2], \"System.Windows.Markup\", \"DateTimeConverter2\");\n\t\t\ttypes[KnownTypes.Decimal] = InitType(assemblies[0], \"System\", \"Decimal\");\n\t\t\ttypes[KnownTypes.DecimalAnimation] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DecimalAnimation\");\n\t\t\ttypes[KnownTypes.DecimalAnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DecimalAnimationBase\");\n\t\t\ttypes[KnownTypes.DecimalAnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DecimalAnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.DecimalConverter] = InitType(assemblies[1], \"System.ComponentModel\", \"DecimalConverter\");\n\t\t\ttypes[KnownTypes.DecimalKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DecimalKeyFrame\");\n\t\t\ttypes[KnownTypes.DecimalKeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DecimalKeyFrameCollection\");\n\t\t\ttypes[KnownTypes.Decorator] = InitType(assemblies[4], \"System.Windows.Controls\", \"Decorator\");\n\t\t\ttypes[KnownTypes.DefinitionBase] = InitType(assemblies[4], \"System.Windows.Controls\", \"DefinitionBase\");\n\t\t\ttypes[KnownTypes.DependencyObject] = InitType(assemblies[2], \"System.Windows\", \"DependencyObject\");\n\t\t\ttypes[KnownTypes.DependencyProperty] = InitType(assemblies[2], \"System.Windows\", \"DependencyProperty\");\n\t\t\ttypes[KnownTypes.DependencyPropertyConverter] = InitType(assemblies[4], \"System.Windows.Markup\", \"DependencyPropertyConverter\");\n\t\t\ttypes[KnownTypes.DialogResultConverter] = InitType(assemblies[4], \"System.Windows\", \"DialogResultConverter\");\n\t\t\ttypes[KnownTypes.DiffuseMaterial] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"DiffuseMaterial\");\n\t\t\ttypes[KnownTypes.DirectionalLight] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"DirectionalLight\");\n\t\t\ttypes[KnownTypes.DiscreteBooleanKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscreteBooleanKeyFrame\");\n\t\t\ttypes[KnownTypes.DiscreteByteKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscreteByteKeyFrame\");\n\t\t\ttypes[KnownTypes.DiscreteCharKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscreteCharKeyFrame\");\n\t\t\ttypes[KnownTypes.DiscreteColorKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscreteColorKeyFrame\");\n\t\t\ttypes[KnownTypes.DiscreteDecimalKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscreteDecimalKeyFrame\");\n\t\t\ttypes[KnownTypes.DiscreteDoubleKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscreteDoubleKeyFrame\");\n\t\t\ttypes[KnownTypes.DiscreteInt16KeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscreteInt16KeyFrame\");\n\t\t\ttypes[KnownTypes.DiscreteInt32KeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscreteInt32KeyFrame\");\n\t\t\ttypes[KnownTypes.DiscreteInt64KeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscreteInt64KeyFrame\");\n\t\t\ttypes[KnownTypes.DiscreteMatrixKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscreteMatrixKeyFrame\");\n\t\t\ttypes[KnownTypes.DiscreteObjectKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscreteObjectKeyFrame\");\n\t\t\ttypes[KnownTypes.DiscretePoint3DKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscretePoint3DKeyFrame\");\n\t\t\ttypes[KnownTypes.DiscretePointKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscretePointKeyFrame\");\n\t\t\ttypes[KnownTypes.DiscreteQuaternionKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscreteQuaternionKeyFrame\");\n\t\t\ttypes[KnownTypes.DiscreteRectKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscreteRectKeyFrame\");\n\t\t\ttypes[KnownTypes.DiscreteRotation3DKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscreteRotation3DKeyFrame\");\n\t\t\ttypes[KnownTypes.DiscreteSingleKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscreteSingleKeyFrame\");\n\t\t\ttypes[KnownTypes.DiscreteSizeKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscreteSizeKeyFrame\");\n\t\t\ttypes[KnownTypes.DiscreteStringKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscreteStringKeyFrame\");\n\t\t\ttypes[KnownTypes.DiscreteThicknessKeyFrame] = InitType(assemblies[4], \"System.Windows.Media.Animation\", \"DiscreteThicknessKeyFrame\");\n\t\t\ttypes[KnownTypes.DiscreteVector3DKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscreteVector3DKeyFrame\");\n\t\t\ttypes[KnownTypes.DiscreteVectorKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DiscreteVectorKeyFrame\");\n\t\t\ttypes[KnownTypes.DockPanel] = InitType(assemblies[4], \"System.Windows.Controls\", \"DockPanel\");\n\t\t\ttypes[KnownTypes.DocumentPageView] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"DocumentPageView\");\n\t\t\ttypes[KnownTypes.DocumentReference] = InitType(assemblies[4], \"System.Windows.Documents\", \"DocumentReference\");\n\t\t\ttypes[KnownTypes.DocumentViewer] = InitType(assemblies[4], \"System.Windows.Controls\", \"DocumentViewer\");\n\t\t\ttypes[KnownTypes.DocumentViewerBase] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"DocumentViewerBase\");\n\t\t\ttypes[KnownTypes.Double] = InitType(assemblies[0], \"System\", \"Double\");\n\t\t\ttypes[KnownTypes.DoubleAnimation] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DoubleAnimation\");\n\t\t\ttypes[KnownTypes.DoubleAnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DoubleAnimationBase\");\n\t\t\ttypes[KnownTypes.DoubleAnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DoubleAnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.DoubleAnimationUsingPath] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DoubleAnimationUsingPath\");\n\t\t\ttypes[KnownTypes.DoubleCollection] = InitType(assemblies[3], \"System.Windows.Media\", \"DoubleCollection\");\n\t\t\ttypes[KnownTypes.DoubleCollectionConverter] = InitType(assemblies[3], \"System.Windows.Media\", \"DoubleCollectionConverter\");\n\t\t\ttypes[KnownTypes.DoubleConverter] = InitType(assemblies[1], \"System.ComponentModel\", \"DoubleConverter\");\n\t\t\ttypes[KnownTypes.DoubleIListConverter] = InitType(assemblies[3], \"System.Windows.Media.Converters\", \"DoubleIListConverter\");\n\t\t\ttypes[KnownTypes.DoubleKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DoubleKeyFrame\");\n\t\t\ttypes[KnownTypes.DoubleKeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DoubleKeyFrameCollection\");\n\t\t\ttypes[KnownTypes.Drawing] = InitType(assemblies[3], \"System.Windows.Media\", \"Drawing\");\n\t\t\ttypes[KnownTypes.DrawingBrush] = InitType(assemblies[3], \"System.Windows.Media\", \"DrawingBrush\");\n\t\t\ttypes[KnownTypes.DrawingCollection] = InitType(assemblies[3], \"System.Windows.Media\", \"DrawingCollection\");\n\t\t\ttypes[KnownTypes.DrawingContext] = InitType(assemblies[3], \"System.Windows.Media\", \"DrawingContext\");\n\t\t\ttypes[KnownTypes.DrawingGroup] = InitType(assemblies[3], \"System.Windows.Media\", \"DrawingGroup\");\n\t\t\ttypes[KnownTypes.DrawingImage] = InitType(assemblies[3], \"System.Windows.Media\", \"DrawingImage\");\n\t\t\ttypes[KnownTypes.DrawingVisual] = InitType(assemblies[3], \"System.Windows.Media\", \"DrawingVisual\");\n\t\t\ttypes[KnownTypes.DropShadowBitmapEffect] = InitType(assemblies[3], \"System.Windows.Media.Effects\", \"DropShadowBitmapEffect\");\n\t\t\ttypes[KnownTypes.Duration] = InitType(assemblies[3], \"System.Windows\", \"Duration\");\n\t\t\ttypes[KnownTypes.DurationConverter] = InitType(assemblies[3], \"System.Windows\", \"DurationConverter\");\n\t\t\ttypes[KnownTypes.DynamicResourceExtension] = InitType(assemblies[4], \"System.Windows\", \"DynamicResourceExtension\");\n\t\t\ttypes[KnownTypes.DynamicResourceExtensionConverter] = InitType(assemblies[4], \"System.Windows\", \"DynamicResourceExtensionConverter\");\n\t\t\ttypes[KnownTypes.Ellipse] = InitType(assemblies[4], \"System.Windows.Shapes\", \"Ellipse\");\n\t\t\ttypes[KnownTypes.EllipseGeometry] = InitType(assemblies[3], \"System.Windows.Media\", \"EllipseGeometry\");\n\t\t\ttypes[KnownTypes.EmbossBitmapEffect] = InitType(assemblies[3], \"System.Windows.Media.Effects\", \"EmbossBitmapEffect\");\n\t\t\ttypes[KnownTypes.EmissiveMaterial] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"EmissiveMaterial\");\n\t\t\ttypes[KnownTypes.EnumConverter] = InitType(assemblies[1], \"System.ComponentModel\", \"EnumConverter\");\n\t\t\ttypes[KnownTypes.EventManager] = InitType(assemblies[3], \"System.Windows\", \"EventManager\");\n\t\t\ttypes[KnownTypes.EventSetter] = InitType(assemblies[4], \"System.Windows\", \"EventSetter\");\n\t\t\ttypes[KnownTypes.EventTrigger] = InitType(assemblies[4], \"System.Windows\", \"EventTrigger\");\n\t\t\ttypes[KnownTypes.Expander] = InitType(assemblies[4], \"System.Windows.Controls\", \"Expander\");\n\t\t\ttypes[KnownTypes.Expression] = InitType(assemblies[2], \"System.Windows\", \"Expression\");\n\t\t\ttypes[KnownTypes.ExpressionConverter] = InitType(assemblies[2], \"System.Windows\", \"ExpressionConverter\");\n\t\t\ttypes[KnownTypes.Figure] = InitType(assemblies[4], \"System.Windows.Documents\", \"Figure\");\n\t\t\ttypes[KnownTypes.FigureLength] = InitType(assemblies[4], \"System.Windows\", \"FigureLength\");\n\t\t\ttypes[KnownTypes.FigureLengthConverter] = InitType(assemblies[4], \"System.Windows\", \"FigureLengthConverter\");\n\t\t\ttypes[KnownTypes.FixedDocument] = InitType(assemblies[4], \"System.Windows.Documents\", \"FixedDocument\");\n\t\t\ttypes[KnownTypes.FixedDocumentSequence] = InitType(assemblies[4], \"System.Windows.Documents\", \"FixedDocumentSequence\");\n\t\t\ttypes[KnownTypes.FixedPage] = InitType(assemblies[4], \"System.Windows.Documents\", \"FixedPage\");\n\t\t\ttypes[KnownTypes.Floater] = InitType(assemblies[4], \"System.Windows.Documents\", \"Floater\");\n\t\t\ttypes[KnownTypes.FlowDocument] = InitType(assemblies[4], \"System.Windows.Documents\", \"FlowDocument\");\n\t\t\ttypes[KnownTypes.FlowDocumentPageViewer] = InitType(assemblies[4], \"System.Windows.Controls\", \"FlowDocumentPageViewer\");\n\t\t\ttypes[KnownTypes.FlowDocumentReader] = InitType(assemblies[4], \"System.Windows.Controls\", \"FlowDocumentReader\");\n\t\t\ttypes[KnownTypes.FlowDocumentScrollViewer] = InitType(assemblies[4], \"System.Windows.Controls\", \"FlowDocumentScrollViewer\");\n\t\t\ttypes[KnownTypes.FocusManager] = InitType(assemblies[3], \"System.Windows.Input\", \"FocusManager\");\n\t\t\ttypes[KnownTypes.FontFamily] = InitType(assemblies[3], \"System.Windows.Media\", \"FontFamily\");\n\t\t\ttypes[KnownTypes.FontFamilyConverter] = InitType(assemblies[3], \"System.Windows.Media\", \"FontFamilyConverter\");\n\t\t\ttypes[KnownTypes.FontSizeConverter] = InitType(assemblies[4], \"System.Windows\", \"FontSizeConverter\");\n\t\t\ttypes[KnownTypes.FontStretch] = InitType(assemblies[3], \"System.Windows\", \"FontStretch\");\n\t\t\ttypes[KnownTypes.FontStretchConverter] = InitType(assemblies[3], \"System.Windows\", \"FontStretchConverter\");\n\t\t\ttypes[KnownTypes.FontStyle] = InitType(assemblies[3], \"System.Windows\", \"FontStyle\");\n\t\t\ttypes[KnownTypes.FontStyleConverter] = InitType(assemblies[3], \"System.Windows\", \"FontStyleConverter\");\n\t\t\ttypes[KnownTypes.FontWeight] = InitType(assemblies[3], \"System.Windows\", \"FontWeight\");\n\t\t\ttypes[KnownTypes.FontWeightConverter] = InitType(assemblies[3], \"System.Windows\", \"FontWeightConverter\");\n\t\t\ttypes[KnownTypes.FormatConvertedBitmap] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"FormatConvertedBitmap\");\n\t\t\ttypes[KnownTypes.Frame] = InitType(assemblies[4], \"System.Windows.Controls\", \"Frame\");\n\t\t\ttypes[KnownTypes.FrameworkContentElement] = InitType(assemblies[4], \"System.Windows\", \"FrameworkContentElement\");\n\t\t\ttypes[KnownTypes.FrameworkElement] = InitType(assemblies[4], \"System.Windows\", \"FrameworkElement\");\n\t\t\ttypes[KnownTypes.FrameworkElementFactory] = InitType(assemblies[4], \"System.Windows\", \"FrameworkElementFactory\");\n\t\t\ttypes[KnownTypes.FrameworkPropertyMetadata] = InitType(assemblies[4], \"System.Windows\", \"FrameworkPropertyMetadata\");\n\t\t\ttypes[KnownTypes.FrameworkPropertyMetadataOptions] = InitType(assemblies[4], \"System.Windows\", \"FrameworkPropertyMetadataOptions\");\n\t\t\ttypes[KnownTypes.FrameworkRichTextComposition] = InitType(assemblies[4], \"System.Windows.Documents\", \"FrameworkRichTextComposition\");\n\t\t\ttypes[KnownTypes.FrameworkTemplate] = InitType(assemblies[4], \"System.Windows\", \"FrameworkTemplate\");\n\t\t\ttypes[KnownTypes.FrameworkTextComposition] = InitType(assemblies[4], \"System.Windows.Documents\", \"FrameworkTextComposition\");\n\t\t\ttypes[KnownTypes.Freezable] = InitType(assemblies[2], \"System.Windows\", \"Freezable\");\n\t\t\ttypes[KnownTypes.GeneralTransform] = InitType(assemblies[3], \"System.Windows.Media\", \"GeneralTransform\");\n\t\t\ttypes[KnownTypes.GeneralTransformCollection] = InitType(assemblies[3], \"System.Windows.Media\", \"GeneralTransformCollection\");\n\t\t\ttypes[KnownTypes.GeneralTransformGroup] = InitType(assemblies[3], \"System.Windows.Media\", \"GeneralTransformGroup\");\n\t\t\ttypes[KnownTypes.Geometry] = InitType(assemblies[3], \"System.Windows.Media\", \"Geometry\");\n\t\t\ttypes[KnownTypes.Geometry3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Geometry3D\");\n\t\t\ttypes[KnownTypes.GeometryCollection] = InitType(assemblies[3], \"System.Windows.Media\", \"GeometryCollection\");\n\t\t\ttypes[KnownTypes.GeometryConverter] = InitType(assemblies[3], \"System.Windows.Media\", \"GeometryConverter\");\n\t\t\ttypes[KnownTypes.GeometryDrawing] = InitType(assemblies[3], \"System.Windows.Media\", \"GeometryDrawing\");\n\t\t\ttypes[KnownTypes.GeometryGroup] = InitType(assemblies[3], \"System.Windows.Media\", \"GeometryGroup\");\n\t\t\ttypes[KnownTypes.GeometryModel3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"GeometryModel3D\");\n\t\t\ttypes[KnownTypes.GestureRecognizer] = InitType(assemblies[3], \"System.Windows.Ink\", \"GestureRecognizer\");\n\t\t\ttypes[KnownTypes.GifBitmapDecoder] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"GifBitmapDecoder\");\n\t\t\ttypes[KnownTypes.GifBitmapEncoder] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"GifBitmapEncoder\");\n\t\t\ttypes[KnownTypes.GlyphRun] = InitType(assemblies[3], \"System.Windows.Media\", \"GlyphRun\");\n\t\t\ttypes[KnownTypes.GlyphRunDrawing] = InitType(assemblies[3], \"System.Windows.Media\", \"GlyphRunDrawing\");\n\t\t\ttypes[KnownTypes.GlyphTypeface] = InitType(assemblies[3], \"System.Windows.Media\", \"GlyphTypeface\");\n\t\t\ttypes[KnownTypes.Glyphs] = InitType(assemblies[4], \"System.Windows.Documents\", \"Glyphs\");\n\t\t\ttypes[KnownTypes.GradientBrush] = InitType(assemblies[3], \"System.Windows.Media\", \"GradientBrush\");\n\t\t\ttypes[KnownTypes.GradientStop] = InitType(assemblies[3], \"System.Windows.Media\", \"GradientStop\");\n\t\t\ttypes[KnownTypes.GradientStopCollection] = InitType(assemblies[3], \"System.Windows.Media\", \"GradientStopCollection\");\n\t\t\ttypes[KnownTypes.Grid] = InitType(assemblies[4], \"System.Windows.Controls\", \"Grid\");\n\t\t\ttypes[KnownTypes.GridLength] = InitType(assemblies[4], \"System.Windows\", \"GridLength\");\n\t\t\ttypes[KnownTypes.GridLengthConverter] = InitType(assemblies[4], \"System.Windows\", \"GridLengthConverter\");\n\t\t\ttypes[KnownTypes.GridSplitter] = InitType(assemblies[4], \"System.Windows.Controls\", \"GridSplitter\");\n\t\t\ttypes[KnownTypes.GridView] = InitType(assemblies[4], \"System.Windows.Controls\", \"GridView\");\n\t\t\ttypes[KnownTypes.GridViewColumn] = InitType(assemblies[4], \"System.Windows.Controls\", \"GridViewColumn\");\n\t\t\ttypes[KnownTypes.GridViewColumnHeader] = InitType(assemblies[4], \"System.Windows.Controls\", \"GridViewColumnHeader\");\n\t\t\ttypes[KnownTypes.GridViewHeaderRowPresenter] = InitType(assemblies[4], \"System.Windows.Controls\", \"GridViewHeaderRowPresenter\");\n\t\t\ttypes[KnownTypes.GridViewRowPresenter] = InitType(assemblies[4], \"System.Windows.Controls\", \"GridViewRowPresenter\");\n\t\t\ttypes[KnownTypes.GridViewRowPresenterBase] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"GridViewRowPresenterBase\");\n\t\t\ttypes[KnownTypes.GroupBox] = InitType(assemblies[4], \"System.Windows.Controls\", \"GroupBox\");\n\t\t\ttypes[KnownTypes.GroupItem] = InitType(assemblies[4], \"System.Windows.Controls\", \"GroupItem\");\n\t\t\ttypes[KnownTypes.Guid] = InitType(assemblies[0], \"System\", \"Guid\");\n\t\t\ttypes[KnownTypes.GuidConverter] = InitType(assemblies[1], \"System.ComponentModel\", \"GuidConverter\");\n\t\t\ttypes[KnownTypes.GuidelineSet] = InitType(assemblies[3], \"System.Windows.Media\", \"GuidelineSet\");\n\t\t\ttypes[KnownTypes.HeaderedContentControl] = InitType(assemblies[4], \"System.Windows.Controls\", \"HeaderedContentControl\");\n\t\t\ttypes[KnownTypes.HeaderedItemsControl] = InitType(assemblies[4], \"System.Windows.Controls\", \"HeaderedItemsControl\");\n\t\t\ttypes[KnownTypes.HierarchicalDataTemplate] = InitType(assemblies[4], \"System.Windows\", \"HierarchicalDataTemplate\");\n\t\t\ttypes[KnownTypes.HostVisual] = InitType(assemblies[3], \"System.Windows.Media\", \"HostVisual\");\n\t\t\ttypes[KnownTypes.Hyperlink] = InitType(assemblies[4], \"System.Windows.Documents\", \"Hyperlink\");\n\t\t\ttypes[KnownTypes.IAddChild] = InitType(assemblies[3], \"System.Windows.Markup\", \"IAddChild\");\n\t\t\ttypes[KnownTypes.IAddChildInternal] = InitType(assemblies[3], \"System.Windows.Markup\", \"IAddChildInternal\");\n\t\t\ttypes[KnownTypes.ICommand] = InitType(assemblies[3], \"System.Windows.Input\", \"ICommand\");\n\t\t\ttypes[KnownTypes.IComponentConnector] = InitType(assemblies[2], \"System.Windows.Markup\", \"IComponentConnector\");\n\t\t\ttypes[KnownTypes.INameScope] = InitType(assemblies[2], \"System.Windows.Markup\", \"INameScope\");\n\t\t\ttypes[KnownTypes.IStyleConnector] = InitType(assemblies[4], \"System.Windows.Markup\", \"IStyleConnector\");\n\t\t\ttypes[KnownTypes.IconBitmapDecoder] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"IconBitmapDecoder\");\n\t\t\ttypes[KnownTypes.Image] = InitType(assemblies[4], \"System.Windows.Controls\", \"Image\");\n\t\t\ttypes[KnownTypes.ImageBrush] = InitType(assemblies[3], \"System.Windows.Media\", \"ImageBrush\");\n\t\t\ttypes[KnownTypes.ImageDrawing] = InitType(assemblies[3], \"System.Windows.Media\", \"ImageDrawing\");\n\t\t\ttypes[KnownTypes.ImageMetadata] = InitType(assemblies[3], \"System.Windows.Media\", \"ImageMetadata\");\n\t\t\ttypes[KnownTypes.ImageSource] = InitType(assemblies[3], \"System.Windows.Media\", \"ImageSource\");\n\t\t\ttypes[KnownTypes.ImageSourceConverter] = InitType(assemblies[3], \"System.Windows.Media\", \"ImageSourceConverter\");\n\t\t\ttypes[KnownTypes.InPlaceBitmapMetadataWriter] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"InPlaceBitmapMetadataWriter\");\n\t\t\ttypes[KnownTypes.InkCanvas] = InitType(assemblies[4], \"System.Windows.Controls\", \"InkCanvas\");\n\t\t\ttypes[KnownTypes.InkPresenter] = InitType(assemblies[4], \"System.Windows.Controls\", \"InkPresenter\");\n\t\t\ttypes[KnownTypes.Inline] = InitType(assemblies[4], \"System.Windows.Documents\", \"Inline\");\n\t\t\ttypes[KnownTypes.InlineCollection] = InitType(assemblies[4], \"System.Windows.Documents\", \"InlineCollection\");\n\t\t\ttypes[KnownTypes.InlineUIContainer] = InitType(assemblies[4], \"System.Windows.Documents\", \"InlineUIContainer\");\n\t\t\ttypes[KnownTypes.InputBinding] = InitType(assemblies[3], \"System.Windows.Input\", \"InputBinding\");\n\t\t\ttypes[KnownTypes.InputDevice] = InitType(assemblies[3], \"System.Windows.Input\", \"InputDevice\");\n\t\t\ttypes[KnownTypes.InputLanguageManager] = InitType(assemblies[3], \"System.Windows.Input\", \"InputLanguageManager\");\n\t\t\ttypes[KnownTypes.InputManager] = InitType(assemblies[3], \"System.Windows.Input\", \"InputManager\");\n\t\t\ttypes[KnownTypes.InputMethod] = InitType(assemblies[3], \"System.Windows.Input\", \"InputMethod\");\n\t\t\ttypes[KnownTypes.InputScope] = InitType(assemblies[3], \"System.Windows.Input\", \"InputScope\");\n\t\t\ttypes[KnownTypes.InputScopeConverter] = InitType(assemblies[3], \"System.Windows.Input\", \"InputScopeConverter\");\n\t\t\ttypes[KnownTypes.InputScopeName] = InitType(assemblies[3], \"System.Windows.Input\", \"InputScopeName\");\n\t\t\ttypes[KnownTypes.InputScopeNameConverter] = InitType(assemblies[3], \"System.Windows.Input\", \"InputScopeNameConverter\");\n\t\t\ttypes[KnownTypes.Int16] = InitType(assemblies[0], \"System\", \"Int16\");\n\t\t\ttypes[KnownTypes.Int16Animation] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Int16Animation\");\n\t\t\ttypes[KnownTypes.Int16AnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Int16AnimationBase\");\n\t\t\ttypes[KnownTypes.Int16AnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Int16AnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.Int16Converter] = InitType(assemblies[1], \"System.ComponentModel\", \"Int16Converter\");\n\t\t\ttypes[KnownTypes.Int16KeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Int16KeyFrame\");\n\t\t\ttypes[KnownTypes.Int16KeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Int16KeyFrameCollection\");\n\t\t\ttypes[KnownTypes.Int32] = InitType(assemblies[0], \"System\", \"Int32\");\n\t\t\ttypes[KnownTypes.Int32Animation] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Int32Animation\");\n\t\t\ttypes[KnownTypes.Int32AnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Int32AnimationBase\");\n\t\t\ttypes[KnownTypes.Int32AnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Int32AnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.Int32Collection] = InitType(assemblies[3], \"System.Windows.Media\", \"Int32Collection\");\n\t\t\ttypes[KnownTypes.Int32CollectionConverter] = InitType(assemblies[3], \"System.Windows.Media\", \"Int32CollectionConverter\");\n\t\t\ttypes[KnownTypes.Int32Converter] = InitType(assemblies[1], \"System.ComponentModel\", \"Int32Converter\");\n\t\t\ttypes[KnownTypes.Int32KeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Int32KeyFrame\");\n\t\t\ttypes[KnownTypes.Int32KeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Int32KeyFrameCollection\");\n\t\t\ttypes[KnownTypes.Int32Rect] = InitType(assemblies[2], \"System.Windows\", \"Int32Rect\");\n\t\t\ttypes[KnownTypes.Int32RectConverter] = InitType(assemblies[2], \"System.Windows\", \"Int32RectConverter\");\n\t\t\ttypes[KnownTypes.Int64] = InitType(assemblies[0], \"System\", \"Int64\");\n\t\t\ttypes[KnownTypes.Int64Animation] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Int64Animation\");\n\t\t\ttypes[KnownTypes.Int64AnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Int64AnimationBase\");\n\t\t\ttypes[KnownTypes.Int64AnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Int64AnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.Int64Converter] = InitType(assemblies[1], \"System.ComponentModel\", \"Int64Converter\");\n\t\t\ttypes[KnownTypes.Int64KeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Int64KeyFrame\");\n\t\t\ttypes[KnownTypes.Int64KeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Int64KeyFrameCollection\");\n\t\t\ttypes[KnownTypes.Italic] = InitType(assemblies[4], \"System.Windows.Documents\", \"Italic\");\n\t\t\ttypes[KnownTypes.ItemCollection] = InitType(assemblies[4], \"System.Windows.Controls\", \"ItemCollection\");\n\t\t\ttypes[KnownTypes.ItemsControl] = InitType(assemblies[4], \"System.Windows.Controls\", \"ItemsControl\");\n\t\t\ttypes[KnownTypes.ItemsPanelTemplate] = InitType(assemblies[4], \"System.Windows.Controls\", \"ItemsPanelTemplate\");\n\t\t\ttypes[KnownTypes.ItemsPresenter] = InitType(assemblies[4], \"System.Windows.Controls\", \"ItemsPresenter\");\n\t\t\ttypes[KnownTypes.JournalEntry] = InitType(assemblies[4], \"System.Windows.Navigation\", \"JournalEntry\");\n\t\t\ttypes[KnownTypes.JournalEntryListConverter] = InitType(assemblies[4], \"System.Windows.Navigation\", \"JournalEntryListConverter\");\n\t\t\ttypes[KnownTypes.JournalEntryUnifiedViewConverter] = InitType(assemblies[4], \"System.Windows.Navigation\", \"JournalEntryUnifiedViewConverter\");\n\t\t\ttypes[KnownTypes.JpegBitmapDecoder] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"JpegBitmapDecoder\");\n\t\t\ttypes[KnownTypes.JpegBitmapEncoder] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"JpegBitmapEncoder\");\n\t\t\ttypes[KnownTypes.KeyBinding] = InitType(assemblies[3], \"System.Windows.Input\", \"KeyBinding\");\n\t\t\ttypes[KnownTypes.KeyConverter] = InitType(assemblies[2], \"System.Windows.Input\", \"KeyConverter\");\n\t\t\ttypes[KnownTypes.KeyGesture] = InitType(assemblies[3], \"System.Windows.Input\", \"KeyGesture\");\n\t\t\ttypes[KnownTypes.KeyGestureConverter] = InitType(assemblies[3], \"System.Windows.Input\", \"KeyGestureConverter\");\n\t\t\ttypes[KnownTypes.KeySpline] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"KeySpline\");\n\t\t\ttypes[KnownTypes.KeySplineConverter] = InitType(assemblies[3], \"System.Windows\", \"KeySplineConverter\");\n\t\t\ttypes[KnownTypes.KeyTime] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"KeyTime\");\n\t\t\ttypes[KnownTypes.KeyTimeConverter] = InitType(assemblies[3], \"System.Windows\", \"KeyTimeConverter\");\n\t\t\ttypes[KnownTypes.KeyboardDevice] = InitType(assemblies[3], \"System.Windows.Input\", \"KeyboardDevice\");\n\t\t\ttypes[KnownTypes.Label] = InitType(assemblies[4], \"System.Windows.Controls\", \"Label\");\n\t\t\ttypes[KnownTypes.LateBoundBitmapDecoder] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"LateBoundBitmapDecoder\");\n\t\t\ttypes[KnownTypes.LengthConverter] = InitType(assemblies[4], \"System.Windows\", \"LengthConverter\");\n\t\t\ttypes[KnownTypes.Light] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Light\");\n\t\t\ttypes[KnownTypes.Line] = InitType(assemblies[4], \"System.Windows.Shapes\", \"Line\");\n\t\t\ttypes[KnownTypes.LineBreak] = InitType(assemblies[4], \"System.Windows.Documents\", \"LineBreak\");\n\t\t\ttypes[KnownTypes.LineGeometry] = InitType(assemblies[3], \"System.Windows.Media\", \"LineGeometry\");\n\t\t\ttypes[KnownTypes.LineSegment] = InitType(assemblies[3], \"System.Windows.Media\", \"LineSegment\");\n\t\t\ttypes[KnownTypes.LinearByteKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"LinearByteKeyFrame\");\n\t\t\ttypes[KnownTypes.LinearColorKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"LinearColorKeyFrame\");\n\t\t\ttypes[KnownTypes.LinearDecimalKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"LinearDecimalKeyFrame\");\n\t\t\ttypes[KnownTypes.LinearDoubleKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"LinearDoubleKeyFrame\");\n\t\t\ttypes[KnownTypes.LinearGradientBrush] = InitType(assemblies[3], \"System.Windows.Media\", \"LinearGradientBrush\");\n\t\t\ttypes[KnownTypes.LinearInt16KeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"LinearInt16KeyFrame\");\n\t\t\ttypes[KnownTypes.LinearInt32KeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"LinearInt32KeyFrame\");\n\t\t\ttypes[KnownTypes.LinearInt64KeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"LinearInt64KeyFrame\");\n\t\t\ttypes[KnownTypes.LinearPoint3DKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"LinearPoint3DKeyFrame\");\n\t\t\ttypes[KnownTypes.LinearPointKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"LinearPointKeyFrame\");\n\t\t\ttypes[KnownTypes.LinearQuaternionKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"LinearQuaternionKeyFrame\");\n\t\t\ttypes[KnownTypes.LinearRectKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"LinearRectKeyFrame\");\n\t\t\ttypes[KnownTypes.LinearRotation3DKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"LinearRotation3DKeyFrame\");\n\t\t\ttypes[KnownTypes.LinearSingleKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"LinearSingleKeyFrame\");\n\t\t\ttypes[KnownTypes.LinearSizeKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"LinearSizeKeyFrame\");\n\t\t\ttypes[KnownTypes.LinearThicknessKeyFrame] = InitType(assemblies[4], \"System.Windows.Media.Animation\", \"LinearThicknessKeyFrame\");\n\t\t\ttypes[KnownTypes.LinearVector3DKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"LinearVector3DKeyFrame\");\n\t\t\ttypes[KnownTypes.LinearVectorKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"LinearVectorKeyFrame\");\n\t\t\ttypes[KnownTypes.List] = InitType(assemblies[4], \"System.Windows.Documents\", \"List\");\n\t\t\ttypes[KnownTypes.ListBox] = InitType(assemblies[4], \"System.Windows.Controls\", \"ListBox\");\n\t\t\ttypes[KnownTypes.ListBoxItem] = InitType(assemblies[4], \"System.Windows.Controls\", \"ListBoxItem\");\n\t\t\ttypes[KnownTypes.ListCollectionView] = InitType(assemblies[4], \"System.Windows.Data\", \"ListCollectionView\");\n\t\t\ttypes[KnownTypes.ListItem] = InitType(assemblies[4], \"System.Windows.Documents\", \"ListItem\");\n\t\t\ttypes[KnownTypes.ListView] = InitType(assemblies[4], \"System.Windows.Controls\", \"ListView\");\n\t\t\ttypes[KnownTypes.ListViewItem] = InitType(assemblies[4], \"System.Windows.Controls\", \"ListViewItem\");\n\t\t\ttypes[KnownTypes.Localization] = InitType(assemblies[4], \"System.Windows\", \"Localization\");\n\t\t\ttypes[KnownTypes.LostFocusEventManager] = InitType(assemblies[4], \"System.Windows\", \"LostFocusEventManager\");\n\t\t\ttypes[KnownTypes.MarkupExtension] = InitType(assemblies[2], \"System.Windows.Markup\", \"MarkupExtension\");\n\t\t\ttypes[KnownTypes.Material] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Material\");\n\t\t\ttypes[KnownTypes.MaterialCollection] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"MaterialCollection\");\n\t\t\ttypes[KnownTypes.MaterialGroup] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"MaterialGroup\");\n\t\t\ttypes[KnownTypes.Matrix] = InitType(assemblies[2], \"System.Windows.Media\", \"Matrix\");\n\t\t\ttypes[KnownTypes.Matrix3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Matrix3D\");\n\t\t\ttypes[KnownTypes.Matrix3DConverter] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Matrix3DConverter\");\n\t\t\ttypes[KnownTypes.MatrixAnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"MatrixAnimationBase\");\n\t\t\ttypes[KnownTypes.MatrixAnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"MatrixAnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.MatrixAnimationUsingPath] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"MatrixAnimationUsingPath\");\n\t\t\ttypes[KnownTypes.MatrixCamera] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"MatrixCamera\");\n\t\t\ttypes[KnownTypes.MatrixConverter] = InitType(assemblies[2], \"System.Windows.Media\", \"MatrixConverter\");\n\t\t\ttypes[KnownTypes.MatrixKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"MatrixKeyFrame\");\n\t\t\ttypes[KnownTypes.MatrixKeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"MatrixKeyFrameCollection\");\n\t\t\ttypes[KnownTypes.MatrixTransform] = InitType(assemblies[3], \"System.Windows.Media\", \"MatrixTransform\");\n\t\t\ttypes[KnownTypes.MatrixTransform3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"MatrixTransform3D\");\n\t\t\ttypes[KnownTypes.MediaClock] = InitType(assemblies[3], \"System.Windows.Media\", \"MediaClock\");\n\t\t\ttypes[KnownTypes.MediaElement] = InitType(assemblies[4], \"System.Windows.Controls\", \"MediaElement\");\n\t\t\ttypes[KnownTypes.MediaPlayer] = InitType(assemblies[3], \"System.Windows.Media\", \"MediaPlayer\");\n\t\t\ttypes[KnownTypes.MediaTimeline] = InitType(assemblies[3], \"System.Windows.Media\", \"MediaTimeline\");\n\t\t\ttypes[KnownTypes.Menu] = InitType(assemblies[4], \"System.Windows.Controls\", \"Menu\");\n\t\t\ttypes[KnownTypes.MenuBase] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"MenuBase\");\n\t\t\ttypes[KnownTypes.MenuItem] = InitType(assemblies[4], \"System.Windows.Controls\", \"MenuItem\");\n\t\t\ttypes[KnownTypes.MenuScrollingVisibilityConverter] = InitType(assemblies[4], \"System.Windows.Controls\", \"MenuScrollingVisibilityConverter\");\n\t\t\ttypes[KnownTypes.MeshGeometry3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"MeshGeometry3D\");\n\t\t\ttypes[KnownTypes.Model3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Model3D\");\n\t\t\ttypes[KnownTypes.Model3DCollection] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Model3DCollection\");\n\t\t\ttypes[KnownTypes.Model3DGroup] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Model3DGroup\");\n\t\t\ttypes[KnownTypes.ModelVisual3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"ModelVisual3D\");\n\t\t\ttypes[KnownTypes.ModifierKeysConverter] = InitType(assemblies[2], \"System.Windows.Input\", \"ModifierKeysConverter\");\n\t\t\ttypes[KnownTypes.MouseActionConverter] = InitType(assemblies[3], \"System.Windows.Input\", \"MouseActionConverter\");\n\t\t\ttypes[KnownTypes.MouseBinding] = InitType(assemblies[3], \"System.Windows.Input\", \"MouseBinding\");\n\t\t\ttypes[KnownTypes.MouseDevice] = InitType(assemblies[3], \"System.Windows.Input\", \"MouseDevice\");\n\t\t\ttypes[KnownTypes.MouseGesture] = InitType(assemblies[3], \"System.Windows.Input\", \"MouseGesture\");\n\t\t\ttypes[KnownTypes.MouseGestureConverter] = InitType(assemblies[3], \"System.Windows.Input\", \"MouseGestureConverter\");\n\t\t\ttypes[KnownTypes.MultiBinding] = InitType(assemblies[4], \"System.Windows.Data\", \"MultiBinding\");\n\t\t\ttypes[KnownTypes.MultiBindingExpression] = InitType(assemblies[4], \"System.Windows.Data\", \"MultiBindingExpression\");\n\t\t\ttypes[KnownTypes.MultiDataTrigger] = InitType(assemblies[4], \"System.Windows\", \"MultiDataTrigger\");\n\t\t\ttypes[KnownTypes.MultiTrigger] = InitType(assemblies[4], \"System.Windows\", \"MultiTrigger\");\n\t\t\ttypes[KnownTypes.NameScope] = InitType(assemblies[4], \"System.Windows\", \"NameScope\");\n\t\t\ttypes[KnownTypes.NavigationWindow] = InitType(assemblies[4], \"System.Windows.Navigation\", \"NavigationWindow\");\n\t\t\ttypes[KnownTypes.NullExtension] = InitType(assemblies[4], \"System.Windows.Markup\", \"NullExtension\");\n\t\t\ttypes[KnownTypes.NullableBoolConverter] = InitType(assemblies[4], \"System.Windows\", \"NullableBoolConverter\");\n\t\t\ttypes[KnownTypes.NullableConverter] = InitType(assemblies[1], \"System.ComponentModel\", \"NullableConverter\");\n\t\t\ttypes[KnownTypes.NumberSubstitution] = InitType(assemblies[3], \"System.Windows.Media\", \"NumberSubstitution\");\n\t\t\ttypes[KnownTypes.Object] = InitType(assemblies[0], \"System\", \"Object\");\n\t\t\ttypes[KnownTypes.ObjectAnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ObjectAnimationBase\");\n\t\t\ttypes[KnownTypes.ObjectAnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ObjectAnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.ObjectDataProvider] = InitType(assemblies[4], \"System.Windows.Data\", \"ObjectDataProvider\");\n\t\t\ttypes[KnownTypes.ObjectKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ObjectKeyFrame\");\n\t\t\ttypes[KnownTypes.ObjectKeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ObjectKeyFrameCollection\");\n\t\t\ttypes[KnownTypes.OrthographicCamera] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"OrthographicCamera\");\n\t\t\ttypes[KnownTypes.OuterGlowBitmapEffect] = InitType(assemblies[3], \"System.Windows.Media.Effects\", \"OuterGlowBitmapEffect\");\n\t\t\ttypes[KnownTypes.Page] = InitType(assemblies[4], \"System.Windows.Controls\", \"Page\");\n\t\t\ttypes[KnownTypes.PageContent] = InitType(assemblies[4], \"System.Windows.Documents\", \"PageContent\");\n\t\t\ttypes[KnownTypes.PageFunctionBase] = InitType(assemblies[4], \"System.Windows.Navigation\", \"PageFunctionBase\");\n\t\t\ttypes[KnownTypes.Panel] = InitType(assemblies[4], \"System.Windows.Controls\", \"Panel\");\n\t\t\ttypes[KnownTypes.Paragraph] = InitType(assemblies[4], \"System.Windows.Documents\", \"Paragraph\");\n\t\t\ttypes[KnownTypes.ParallelTimeline] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ParallelTimeline\");\n\t\t\ttypes[KnownTypes.ParserContext] = InitType(assemblies[4], \"System.Windows.Markup\", \"ParserContext\");\n\t\t\ttypes[KnownTypes.PasswordBox] = InitType(assemblies[4], \"System.Windows.Controls\", \"PasswordBox\");\n\t\t\ttypes[KnownTypes.Path] = InitType(assemblies[4], \"System.Windows.Shapes\", \"Path\");\n\t\t\ttypes[KnownTypes.PathFigure] = InitType(assemblies[3], \"System.Windows.Media\", \"PathFigure\");\n\t\t\ttypes[KnownTypes.PathFigureCollection] = InitType(assemblies[3], \"System.Windows.Media\", \"PathFigureCollection\");\n\t\t\ttypes[KnownTypes.PathFigureCollectionConverter] = InitType(assemblies[3], \"System.Windows.Media\", \"PathFigureCollectionConverter\");\n\t\t\ttypes[KnownTypes.PathGeometry] = InitType(assemblies[3], \"System.Windows.Media\", \"PathGeometry\");\n\t\t\ttypes[KnownTypes.PathSegment] = InitType(assemblies[3], \"System.Windows.Media\", \"PathSegment\");\n\t\t\ttypes[KnownTypes.PathSegmentCollection] = InitType(assemblies[3], \"System.Windows.Media\", \"PathSegmentCollection\");\n\t\t\ttypes[KnownTypes.PauseStoryboard] = InitType(assemblies[4], \"System.Windows.Media.Animation\", \"PauseStoryboard\");\n\t\t\ttypes[KnownTypes.Pen] = InitType(assemblies[3], \"System.Windows.Media\", \"Pen\");\n\t\t\ttypes[KnownTypes.PerspectiveCamera] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"PerspectiveCamera\");\n\t\t\ttypes[KnownTypes.PixelFormat] = InitType(assemblies[3], \"System.Windows.Media\", \"PixelFormat\");\n\t\t\ttypes[KnownTypes.PixelFormatConverter] = InitType(assemblies[3], \"System.Windows.Media\", \"PixelFormatConverter\");\n\t\t\ttypes[KnownTypes.PngBitmapDecoder] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"PngBitmapDecoder\");\n\t\t\ttypes[KnownTypes.PngBitmapEncoder] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"PngBitmapEncoder\");\n\t\t\ttypes[KnownTypes.Point] = InitType(assemblies[2], \"System.Windows\", \"Point\");\n\t\t\ttypes[KnownTypes.Point3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Point3D\");\n\t\t\ttypes[KnownTypes.Point3DAnimation] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Point3DAnimation\");\n\t\t\ttypes[KnownTypes.Point3DAnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Point3DAnimationBase\");\n\t\t\ttypes[KnownTypes.Point3DAnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Point3DAnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.Point3DCollection] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Point3DCollection\");\n\t\t\ttypes[KnownTypes.Point3DCollectionConverter] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Point3DCollectionConverter\");\n\t\t\ttypes[KnownTypes.Point3DConverter] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Point3DConverter\");\n\t\t\ttypes[KnownTypes.Point3DKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Point3DKeyFrame\");\n\t\t\ttypes[KnownTypes.Point3DKeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Point3DKeyFrameCollection\");\n\t\t\ttypes[KnownTypes.Point4D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Point4D\");\n\t\t\ttypes[KnownTypes.Point4DConverter] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Point4DConverter\");\n\t\t\ttypes[KnownTypes.PointAnimation] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"PointAnimation\");\n\t\t\ttypes[KnownTypes.PointAnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"PointAnimationBase\");\n\t\t\ttypes[KnownTypes.PointAnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"PointAnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.PointAnimationUsingPath] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"PointAnimationUsingPath\");\n\t\t\ttypes[KnownTypes.PointCollection] = InitType(assemblies[3], \"System.Windows.Media\", \"PointCollection\");\n\t\t\ttypes[KnownTypes.PointCollectionConverter] = InitType(assemblies[3], \"System.Windows.Media\", \"PointCollectionConverter\");\n\t\t\ttypes[KnownTypes.PointConverter] = InitType(assemblies[2], \"System.Windows\", \"PointConverter\");\n\t\t\ttypes[KnownTypes.PointIListConverter] = InitType(assemblies[3], \"System.Windows.Media.Converters\", \"PointIListConverter\");\n\t\t\ttypes[KnownTypes.PointKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"PointKeyFrame\");\n\t\t\ttypes[KnownTypes.PointKeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"PointKeyFrameCollection\");\n\t\t\ttypes[KnownTypes.PointLight] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"PointLight\");\n\t\t\ttypes[KnownTypes.PointLightBase] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"PointLightBase\");\n\t\t\ttypes[KnownTypes.PolyBezierSegment] = InitType(assemblies[3], \"System.Windows.Media\", \"PolyBezierSegment\");\n\t\t\ttypes[KnownTypes.PolyLineSegment] = InitType(assemblies[3], \"System.Windows.Media\", \"PolyLineSegment\");\n\t\t\ttypes[KnownTypes.PolyQuadraticBezierSegment] = InitType(assemblies[3], \"System.Windows.Media\", \"PolyQuadraticBezierSegment\");\n\t\t\ttypes[KnownTypes.Polygon] = InitType(assemblies[4], \"System.Windows.Shapes\", \"Polygon\");\n\t\t\ttypes[KnownTypes.Polyline] = InitType(assemblies[4], \"System.Windows.Shapes\", \"Polyline\");\n\t\t\ttypes[KnownTypes.Popup] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"Popup\");\n\t\t\ttypes[KnownTypes.PresentationSource] = InitType(assemblies[3], \"System.Windows\", \"PresentationSource\");\n\t\t\ttypes[KnownTypes.PriorityBinding] = InitType(assemblies[4], \"System.Windows.Data\", \"PriorityBinding\");\n\t\t\ttypes[KnownTypes.PriorityBindingExpression] = InitType(assemblies[4], \"System.Windows.Data\", \"PriorityBindingExpression\");\n\t\t\ttypes[KnownTypes.ProgressBar] = InitType(assemblies[4], \"System.Windows.Controls\", \"ProgressBar\");\n\t\t\ttypes[KnownTypes.ProjectionCamera] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"ProjectionCamera\");\n\t\t\ttypes[KnownTypes.PropertyPath] = InitType(assemblies[4], \"System.Windows\", \"PropertyPath\");\n\t\t\ttypes[KnownTypes.PropertyPathConverter] = InitType(assemblies[4], \"System.Windows\", \"PropertyPathConverter\");\n\t\t\ttypes[KnownTypes.QuadraticBezierSegment] = InitType(assemblies[3], \"System.Windows.Media\", \"QuadraticBezierSegment\");\n\t\t\ttypes[KnownTypes.Quaternion] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Quaternion\");\n\t\t\ttypes[KnownTypes.QuaternionAnimation] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"QuaternionAnimation\");\n\t\t\ttypes[KnownTypes.QuaternionAnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"QuaternionAnimationBase\");\n\t\t\ttypes[KnownTypes.QuaternionAnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"QuaternionAnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.QuaternionConverter] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"QuaternionConverter\");\n\t\t\ttypes[KnownTypes.QuaternionKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"QuaternionKeyFrame\");\n\t\t\ttypes[KnownTypes.QuaternionKeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"QuaternionKeyFrameCollection\");\n\t\t\ttypes[KnownTypes.QuaternionRotation3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"QuaternionRotation3D\");\n\t\t\ttypes[KnownTypes.RadialGradientBrush] = InitType(assemblies[3], \"System.Windows.Media\", \"RadialGradientBrush\");\n\t\t\ttypes[KnownTypes.RadioButton] = InitType(assemblies[4], \"System.Windows.Controls\", \"RadioButton\");\n\t\t\ttypes[KnownTypes.RangeBase] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"RangeBase\");\n\t\t\ttypes[KnownTypes.Rect] = InitType(assemblies[2], \"System.Windows\", \"Rect\");\n\t\t\ttypes[KnownTypes.Rect3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Rect3D\");\n\t\t\ttypes[KnownTypes.Rect3DConverter] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Rect3DConverter\");\n\t\t\ttypes[KnownTypes.RectAnimation] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"RectAnimation\");\n\t\t\ttypes[KnownTypes.RectAnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"RectAnimationBase\");\n\t\t\ttypes[KnownTypes.RectAnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"RectAnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.RectConverter] = InitType(assemblies[2], \"System.Windows\", \"RectConverter\");\n\t\t\ttypes[KnownTypes.RectKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"RectKeyFrame\");\n\t\t\ttypes[KnownTypes.RectKeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"RectKeyFrameCollection\");\n\t\t\ttypes[KnownTypes.Rectangle] = InitType(assemblies[4], \"System.Windows.Shapes\", \"Rectangle\");\n\t\t\ttypes[KnownTypes.RectangleGeometry] = InitType(assemblies[3], \"System.Windows.Media\", \"RectangleGeometry\");\n\t\t\ttypes[KnownTypes.RelativeSource] = InitType(assemblies[4], \"System.Windows.Data\", \"RelativeSource\");\n\t\t\ttypes[KnownTypes.RemoveStoryboard] = InitType(assemblies[4], \"System.Windows.Media.Animation\", \"RemoveStoryboard\");\n\t\t\ttypes[KnownTypes.RenderOptions] = InitType(assemblies[3], \"System.Windows.Media\", \"RenderOptions\");\n\t\t\ttypes[KnownTypes.RenderTargetBitmap] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"RenderTargetBitmap\");\n\t\t\ttypes[KnownTypes.RepeatBehavior] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"RepeatBehavior\");\n\t\t\ttypes[KnownTypes.RepeatBehaviorConverter] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"RepeatBehaviorConverter\");\n\t\t\ttypes[KnownTypes.RepeatButton] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"RepeatButton\");\n\t\t\ttypes[KnownTypes.ResizeGrip] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"ResizeGrip\");\n\t\t\ttypes[KnownTypes.ResourceDictionary] = InitType(assemblies[4], \"System.Windows\", \"ResourceDictionary\");\n\t\t\ttypes[KnownTypes.ResourceKey] = InitType(assemblies[4], \"System.Windows\", \"ResourceKey\");\n\t\t\ttypes[KnownTypes.ResumeStoryboard] = InitType(assemblies[4], \"System.Windows.Media.Animation\", \"ResumeStoryboard\");\n\t\t\ttypes[KnownTypes.RichTextBox] = InitType(assemblies[4], \"System.Windows.Controls\", \"RichTextBox\");\n\t\t\ttypes[KnownTypes.RotateTransform] = InitType(assemblies[3], \"System.Windows.Media\", \"RotateTransform\");\n\t\t\ttypes[KnownTypes.RotateTransform3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"RotateTransform3D\");\n\t\t\ttypes[KnownTypes.Rotation3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Rotation3D\");\n\t\t\ttypes[KnownTypes.Rotation3DAnimation] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Rotation3DAnimation\");\n\t\t\ttypes[KnownTypes.Rotation3DAnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Rotation3DAnimationBase\");\n\t\t\ttypes[KnownTypes.Rotation3DAnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Rotation3DAnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.Rotation3DKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Rotation3DKeyFrame\");\n\t\t\ttypes[KnownTypes.Rotation3DKeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Rotation3DKeyFrameCollection\");\n\t\t\ttypes[KnownTypes.RoutedCommand] = InitType(assemblies[3], \"System.Windows.Input\", \"RoutedCommand\");\n\t\t\ttypes[KnownTypes.RoutedEvent] = InitType(assemblies[3], \"System.Windows\", \"RoutedEvent\");\n\t\t\ttypes[KnownTypes.RoutedEventConverter] = InitType(assemblies[4], \"System.Windows.Markup\", \"RoutedEventConverter\");\n\t\t\ttypes[KnownTypes.RoutedUICommand] = InitType(assemblies[3], \"System.Windows.Input\", \"RoutedUICommand\");\n\t\t\ttypes[KnownTypes.RoutingStrategy] = InitType(assemblies[3], \"System.Windows\", \"RoutingStrategy\");\n\t\t\ttypes[KnownTypes.RowDefinition] = InitType(assemblies[4], \"System.Windows.Controls\", \"RowDefinition\");\n\t\t\ttypes[KnownTypes.Run] = InitType(assemblies[4], \"System.Windows.Documents\", \"Run\");\n\t\t\ttypes[KnownTypes.RuntimeNamePropertyAttribute] = InitType(assemblies[2], \"System.Windows.Markup\", \"RuntimeNamePropertyAttribute\");\n\t\t\ttypes[KnownTypes.SByte] = InitType(assemblies[0], \"System\", \"SByte\");\n\t\t\ttypes[KnownTypes.SByteConverter] = InitType(assemblies[1], \"System.ComponentModel\", \"SByteConverter\");\n\t\t\ttypes[KnownTypes.ScaleTransform] = InitType(assemblies[3], \"System.Windows.Media\", \"ScaleTransform\");\n\t\t\ttypes[KnownTypes.ScaleTransform3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"ScaleTransform3D\");\n\t\t\ttypes[KnownTypes.ScrollBar] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"ScrollBar\");\n\t\t\ttypes[KnownTypes.ScrollContentPresenter] = InitType(assemblies[4], \"System.Windows.Controls\", \"ScrollContentPresenter\");\n\t\t\ttypes[KnownTypes.ScrollViewer] = InitType(assemblies[4], \"System.Windows.Controls\", \"ScrollViewer\");\n\t\t\ttypes[KnownTypes.Section] = InitType(assemblies[4], \"System.Windows.Documents\", \"Section\");\n\t\t\ttypes[KnownTypes.SeekStoryboard] = InitType(assemblies[4], \"System.Windows.Media.Animation\", \"SeekStoryboard\");\n\t\t\ttypes[KnownTypes.Selector] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"Selector\");\n\t\t\ttypes[KnownTypes.Separator] = InitType(assemblies[4], \"System.Windows.Controls\", \"Separator\");\n\t\t\ttypes[KnownTypes.SetStoryboardSpeedRatio] = InitType(assemblies[4], \"System.Windows.Media.Animation\", \"SetStoryboardSpeedRatio\");\n\t\t\ttypes[KnownTypes.Setter] = InitType(assemblies[4], \"System.Windows\", \"Setter\");\n\t\t\ttypes[KnownTypes.SetterBase] = InitType(assemblies[4], \"System.Windows\", \"SetterBase\");\n\t\t\ttypes[KnownTypes.Shape] = InitType(assemblies[4], \"System.Windows.Shapes\", \"Shape\");\n\t\t\ttypes[KnownTypes.Single] = InitType(assemblies[0], \"System\", \"Single\");\n\t\t\ttypes[KnownTypes.SingleAnimation] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SingleAnimation\");\n\t\t\ttypes[KnownTypes.SingleAnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SingleAnimationBase\");\n\t\t\ttypes[KnownTypes.SingleAnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SingleAnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.SingleConverter] = InitType(assemblies[1], \"System.ComponentModel\", \"SingleConverter\");\n\t\t\ttypes[KnownTypes.SingleKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SingleKeyFrame\");\n\t\t\ttypes[KnownTypes.SingleKeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SingleKeyFrameCollection\");\n\t\t\ttypes[KnownTypes.Size] = InitType(assemblies[2], \"System.Windows\", \"Size\");\n\t\t\ttypes[KnownTypes.Size3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Size3D\");\n\t\t\ttypes[KnownTypes.Size3DConverter] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Size3DConverter\");\n\t\t\ttypes[KnownTypes.SizeAnimation] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SizeAnimation\");\n\t\t\ttypes[KnownTypes.SizeAnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SizeAnimationBase\");\n\t\t\ttypes[KnownTypes.SizeAnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SizeAnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.SizeConverter] = InitType(assemblies[2], \"System.Windows\", \"SizeConverter\");\n\t\t\ttypes[KnownTypes.SizeKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SizeKeyFrame\");\n\t\t\ttypes[KnownTypes.SizeKeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SizeKeyFrameCollection\");\n\t\t\ttypes[KnownTypes.SkewTransform] = InitType(assemblies[3], \"System.Windows.Media\", \"SkewTransform\");\n\t\t\ttypes[KnownTypes.SkipStoryboardToFill] = InitType(assemblies[4], \"System.Windows.Media.Animation\", \"SkipStoryboardToFill\");\n\t\t\ttypes[KnownTypes.Slider] = InitType(assemblies[4], \"System.Windows.Controls\", \"Slider\");\n\t\t\ttypes[KnownTypes.SolidColorBrush] = InitType(assemblies[3], \"System.Windows.Media\", \"SolidColorBrush\");\n\t\t\ttypes[KnownTypes.SoundPlayerAction] = InitType(assemblies[4], \"System.Windows.Controls\", \"SoundPlayerAction\");\n\t\t\ttypes[KnownTypes.Span] = InitType(assemblies[4], \"System.Windows.Documents\", \"Span\");\n\t\t\ttypes[KnownTypes.SpecularMaterial] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"SpecularMaterial\");\n\t\t\ttypes[KnownTypes.SpellCheck] = InitType(assemblies[4], \"System.Windows.Controls\", \"SpellCheck\");\n\t\t\ttypes[KnownTypes.SplineByteKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SplineByteKeyFrame\");\n\t\t\ttypes[KnownTypes.SplineColorKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SplineColorKeyFrame\");\n\t\t\ttypes[KnownTypes.SplineDecimalKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SplineDecimalKeyFrame\");\n\t\t\ttypes[KnownTypes.SplineDoubleKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SplineDoubleKeyFrame\");\n\t\t\ttypes[KnownTypes.SplineInt16KeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SplineInt16KeyFrame\");\n\t\t\ttypes[KnownTypes.SplineInt32KeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SplineInt32KeyFrame\");\n\t\t\ttypes[KnownTypes.SplineInt64KeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SplineInt64KeyFrame\");\n\t\t\ttypes[KnownTypes.SplinePoint3DKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SplinePoint3DKeyFrame\");\n\t\t\ttypes[KnownTypes.SplinePointKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SplinePointKeyFrame\");\n\t\t\ttypes[KnownTypes.SplineQuaternionKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SplineQuaternionKeyFrame\");\n\t\t\ttypes[KnownTypes.SplineRectKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SplineRectKeyFrame\");\n\t\t\ttypes[KnownTypes.SplineRotation3DKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SplineRotation3DKeyFrame\");\n\t\t\ttypes[KnownTypes.SplineSingleKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SplineSingleKeyFrame\");\n\t\t\ttypes[KnownTypes.SplineSizeKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SplineSizeKeyFrame\");\n\t\t\ttypes[KnownTypes.SplineThicknessKeyFrame] = InitType(assemblies[4], \"System.Windows.Media.Animation\", \"SplineThicknessKeyFrame\");\n\t\t\ttypes[KnownTypes.SplineVector3DKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SplineVector3DKeyFrame\");\n\t\t\ttypes[KnownTypes.SplineVectorKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SplineVectorKeyFrame\");\n\t\t\ttypes[KnownTypes.SpotLight] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"SpotLight\");\n\t\t\ttypes[KnownTypes.StackPanel] = InitType(assemblies[4], \"System.Windows.Controls\", \"StackPanel\");\n\t\t\ttypes[KnownTypes.StaticExtension] = InitType(assemblies[4], \"System.Windows.Markup\", \"StaticExtension\");\n\t\t\ttypes[KnownTypes.StaticResourceExtension] = InitType(assemblies[4], \"System.Windows\", \"StaticResourceExtension\");\n\t\t\ttypes[KnownTypes.StatusBar] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"StatusBar\");\n\t\t\ttypes[KnownTypes.StatusBarItem] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"StatusBarItem\");\n\t\t\ttypes[KnownTypes.StickyNoteControl] = InitType(assemblies[4], \"System.Windows.Controls\", \"StickyNoteControl\");\n\t\t\ttypes[KnownTypes.StopStoryboard] = InitType(assemblies[4], \"System.Windows.Media.Animation\", \"StopStoryboard\");\n\t\t\ttypes[KnownTypes.Storyboard] = InitType(assemblies[4], \"System.Windows.Media.Animation\", \"Storyboard\");\n\t\t\ttypes[KnownTypes.StreamGeometry] = InitType(assemblies[3], \"System.Windows.Media\", \"StreamGeometry\");\n\t\t\ttypes[KnownTypes.StreamGeometryContext] = InitType(assemblies[3], \"System.Windows.Media\", \"StreamGeometryContext\");\n\t\t\ttypes[KnownTypes.StreamResourceInfo] = InitType(assemblies[4], \"System.Windows.Resources\", \"StreamResourceInfo\");\n\t\t\ttypes[KnownTypes.String] = InitType(assemblies[0], \"System\", \"String\");\n\t\t\ttypes[KnownTypes.StringAnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"StringAnimationBase\");\n\t\t\ttypes[KnownTypes.StringAnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"StringAnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.StringConverter] = InitType(assemblies[1], \"System.ComponentModel\", \"StringConverter\");\n\t\t\ttypes[KnownTypes.StringKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"StringKeyFrame\");\n\t\t\ttypes[KnownTypes.StringKeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"StringKeyFrameCollection\");\n\t\t\ttypes[KnownTypes.StrokeCollection] = InitType(assemblies[3], \"System.Windows.Ink\", \"StrokeCollection\");\n\t\t\ttypes[KnownTypes.StrokeCollectionConverter] = InitType(assemblies[3], \"System.Windows\", \"StrokeCollectionConverter\");\n\t\t\ttypes[KnownTypes.Style] = InitType(assemblies[4], \"System.Windows\", \"Style\");\n\t\t\ttypes[KnownTypes.Stylus] = InitType(assemblies[3], \"System.Windows.Input\", \"Stylus\");\n\t\t\ttypes[KnownTypes.StylusDevice] = InitType(assemblies[3], \"System.Windows.Input\", \"StylusDevice\");\n\t\t\ttypes[KnownTypes.TabControl] = InitType(assemblies[4], \"System.Windows.Controls\", \"TabControl\");\n\t\t\ttypes[KnownTypes.TabItem] = InitType(assemblies[4], \"System.Windows.Controls\", \"TabItem\");\n\t\t\ttypes[KnownTypes.TabPanel] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"TabPanel\");\n\t\t\ttypes[KnownTypes.Table] = InitType(assemblies[4], \"System.Windows.Documents\", \"Table\");\n\t\t\ttypes[KnownTypes.TableCell] = InitType(assemblies[4], \"System.Windows.Documents\", \"TableCell\");\n\t\t\ttypes[KnownTypes.TableColumn] = InitType(assemblies[4], \"System.Windows.Documents\", \"TableColumn\");\n\t\t\ttypes[KnownTypes.TableRow] = InitType(assemblies[4], \"System.Windows.Documents\", \"TableRow\");\n\t\t\ttypes[KnownTypes.TableRowGroup] = InitType(assemblies[4], \"System.Windows.Documents\", \"TableRowGroup\");\n\t\t\ttypes[KnownTypes.TabletDevice] = InitType(assemblies[3], \"System.Windows.Input\", \"TabletDevice\");\n\t\t\ttypes[KnownTypes.TemplateBindingExpression] = InitType(assemblies[4], \"System.Windows\", \"TemplateBindingExpression\");\n\t\t\ttypes[KnownTypes.TemplateBindingExpressionConverter] = InitType(assemblies[4], \"System.Windows\", \"TemplateBindingExpressionConverter\");\n\t\t\ttypes[KnownTypes.TemplateBindingExtension] = InitType(assemblies[4], \"System.Windows\", \"TemplateBindingExtension\");\n\t\t\ttypes[KnownTypes.TemplateBindingExtensionConverter] = InitType(assemblies[4], \"System.Windows\", \"TemplateBindingExtensionConverter\");\n\t\t\ttypes[KnownTypes.TemplateKey] = InitType(assemblies[4], \"System.Windows\", \"TemplateKey\");\n\t\t\ttypes[KnownTypes.TemplateKeyConverter] = InitType(assemblies[4], \"System.Windows.Markup\", \"TemplateKeyConverter\");\n\t\t\ttypes[KnownTypes.TextBlock] = InitType(assemblies[4], \"System.Windows.Controls\", \"TextBlock\");\n\t\t\ttypes[KnownTypes.TextBox] = InitType(assemblies[4], \"System.Windows.Controls\", \"TextBox\");\n\t\t\ttypes[KnownTypes.TextBoxBase] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"TextBoxBase\");\n\t\t\ttypes[KnownTypes.TextComposition] = InitType(assemblies[3], \"System.Windows.Input\", \"TextComposition\");\n\t\t\ttypes[KnownTypes.TextCompositionManager] = InitType(assemblies[3], \"System.Windows.Input\", \"TextCompositionManager\");\n\t\t\ttypes[KnownTypes.TextDecoration] = InitType(assemblies[3], \"System.Windows\", \"TextDecoration\");\n\t\t\ttypes[KnownTypes.TextDecorationCollection] = InitType(assemblies[3], \"System.Windows\", \"TextDecorationCollection\");\n\t\t\ttypes[KnownTypes.TextDecorationCollectionConverter] = InitType(assemblies[3], \"System.Windows\", \"TextDecorationCollectionConverter\");\n\t\t\ttypes[KnownTypes.TextEffect] = InitType(assemblies[3], \"System.Windows.Media\", \"TextEffect\");\n\t\t\ttypes[KnownTypes.TextEffectCollection] = InitType(assemblies[3], \"System.Windows.Media\", \"TextEffectCollection\");\n\t\t\ttypes[KnownTypes.TextElement] = InitType(assemblies[4], \"System.Windows.Documents\", \"TextElement\");\n\t\t\ttypes[KnownTypes.TextSearch] = InitType(assemblies[4], \"System.Windows.Controls\", \"TextSearch\");\n\t\t\ttypes[KnownTypes.ThemeDictionaryExtension] = InitType(assemblies[4], \"System.Windows\", \"ThemeDictionaryExtension\");\n\t\t\ttypes[KnownTypes.Thickness] = InitType(assemblies[4], \"System.Windows\", \"Thickness\");\n\t\t\ttypes[KnownTypes.ThicknessAnimation] = InitType(assemblies[4], \"System.Windows.Media.Animation\", \"ThicknessAnimation\");\n\t\t\ttypes[KnownTypes.ThicknessAnimationBase] = InitType(assemblies[4], \"System.Windows.Media.Animation\", \"ThicknessAnimationBase\");\n\t\t\ttypes[KnownTypes.ThicknessAnimationUsingKeyFrames] = InitType(assemblies[4], \"System.Windows.Media.Animation\", \"ThicknessAnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.ThicknessConverter] = InitType(assemblies[4], \"System.Windows\", \"ThicknessConverter\");\n\t\t\ttypes[KnownTypes.ThicknessKeyFrame] = InitType(assemblies[4], \"System.Windows.Media.Animation\", \"ThicknessKeyFrame\");\n\t\t\ttypes[KnownTypes.ThicknessKeyFrameCollection] = InitType(assemblies[4], \"System.Windows.Media.Animation\", \"ThicknessKeyFrameCollection\");\n\t\t\ttypes[KnownTypes.Thumb] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"Thumb\");\n\t\t\ttypes[KnownTypes.TickBar] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"TickBar\");\n\t\t\ttypes[KnownTypes.TiffBitmapDecoder] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"TiffBitmapDecoder\");\n\t\t\ttypes[KnownTypes.TiffBitmapEncoder] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"TiffBitmapEncoder\");\n\t\t\ttypes[KnownTypes.TileBrush] = InitType(assemblies[3], \"System.Windows.Media\", \"TileBrush\");\n\t\t\ttypes[KnownTypes.TimeSpan] = InitType(assemblies[0], \"System\", \"TimeSpan\");\n\t\t\ttypes[KnownTypes.TimeSpanConverter] = InitType(assemblies[1], \"System.ComponentModel\", \"TimeSpanConverter\");\n\t\t\ttypes[KnownTypes.Timeline] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Timeline\");\n\t\t\ttypes[KnownTypes.TimelineCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"TimelineCollection\");\n\t\t\ttypes[KnownTypes.TimelineGroup] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"TimelineGroup\");\n\t\t\ttypes[KnownTypes.ToggleButton] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"ToggleButton\");\n\t\t\ttypes[KnownTypes.ToolBar] = InitType(assemblies[4], \"System.Windows.Controls\", \"ToolBar\");\n\t\t\ttypes[KnownTypes.ToolBarOverflowPanel] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"ToolBarOverflowPanel\");\n\t\t\ttypes[KnownTypes.ToolBarPanel] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"ToolBarPanel\");\n\t\t\ttypes[KnownTypes.ToolBarTray] = InitType(assemblies[4], \"System.Windows.Controls\", \"ToolBarTray\");\n\t\t\ttypes[KnownTypes.ToolTip] = InitType(assemblies[4], \"System.Windows.Controls\", \"ToolTip\");\n\t\t\ttypes[KnownTypes.ToolTipService] = InitType(assemblies[4], \"System.Windows.Controls\", \"ToolTipService\");\n\t\t\ttypes[KnownTypes.Track] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"Track\");\n\t\t\ttypes[KnownTypes.Transform] = InitType(assemblies[3], \"System.Windows.Media\", \"Transform\");\n\t\t\ttypes[KnownTypes.Transform3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Transform3D\");\n\t\t\ttypes[KnownTypes.Transform3DCollection] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Transform3DCollection\");\n\t\t\ttypes[KnownTypes.Transform3DGroup] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Transform3DGroup\");\n\t\t\ttypes[KnownTypes.TransformCollection] = InitType(assemblies[3], \"System.Windows.Media\", \"TransformCollection\");\n\t\t\ttypes[KnownTypes.TransformConverter] = InitType(assemblies[3], \"System.Windows.Media\", \"TransformConverter\");\n\t\t\ttypes[KnownTypes.TransformGroup] = InitType(assemblies[3], \"System.Windows.Media\", \"TransformGroup\");\n\t\t\ttypes[KnownTypes.TransformedBitmap] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"TransformedBitmap\");\n\t\t\ttypes[KnownTypes.TranslateTransform] = InitType(assemblies[3], \"System.Windows.Media\", \"TranslateTransform\");\n\t\t\ttypes[KnownTypes.TranslateTransform3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"TranslateTransform3D\");\n\t\t\ttypes[KnownTypes.TreeView] = InitType(assemblies[4], \"System.Windows.Controls\", \"TreeView\");\n\t\t\ttypes[KnownTypes.TreeViewItem] = InitType(assemblies[4], \"System.Windows.Controls\", \"TreeViewItem\");\n\t\t\ttypes[KnownTypes.Trigger] = InitType(assemblies[4], \"System.Windows\", \"Trigger\");\n\t\t\ttypes[KnownTypes.TriggerAction] = InitType(assemblies[4], \"System.Windows\", \"TriggerAction\");\n\t\t\ttypes[KnownTypes.TriggerBase] = InitType(assemblies[4], \"System.Windows\", \"TriggerBase\");\n\t\t\ttypes[KnownTypes.TypeExtension] = InitType(assemblies[4], \"System.Windows.Markup\", \"TypeExtension\");\n\t\t\ttypes[KnownTypes.TypeTypeConverter] = InitType(assemblies[2], \"System.Windows.Markup\", \"TypeTypeConverter\");\n\t\t\ttypes[KnownTypes.Typography] = InitType(assemblies[4], \"System.Windows.Documents\", \"Typography\");\n\t\t\ttypes[KnownTypes.UIElement] = InitType(assemblies[3], \"System.Windows\", \"UIElement\");\n\t\t\ttypes[KnownTypes.UInt16] = InitType(assemblies[0], \"System\", \"UInt16\");\n\t\t\ttypes[KnownTypes.UInt16Converter] = InitType(assemblies[1], \"System.ComponentModel\", \"UInt16Converter\");\n\t\t\ttypes[KnownTypes.UInt32] = InitType(assemblies[0], \"System\", \"UInt32\");\n\t\t\ttypes[KnownTypes.UInt32Converter] = InitType(assemblies[1], \"System.ComponentModel\", \"UInt32Converter\");\n\t\t\ttypes[KnownTypes.UInt64] = InitType(assemblies[0], \"System\", \"UInt64\");\n\t\t\ttypes[KnownTypes.UInt64Converter] = InitType(assemblies[1], \"System.ComponentModel\", \"UInt64Converter\");\n\t\t\ttypes[KnownTypes.UShortIListConverter] = InitType(assemblies[3], \"System.Windows.Media.Converters\", \"UShortIListConverter\");\n\t\t\ttypes[KnownTypes.Underline] = InitType(assemblies[4], \"System.Windows.Documents\", \"Underline\");\n\t\t\ttypes[KnownTypes.UniformGrid] = InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"UniformGrid\");\n\t\t\ttypes[KnownTypes.Uri] = InitType(assemblies[1], \"System\", \"Uri\");\n\t\t\ttypes[KnownTypes.UriTypeConverter] = InitType(assemblies[1], \"System\", \"UriTypeConverter\");\n\t\t\ttypes[KnownTypes.UserControl] = InitType(assemblies[4], \"System.Windows.Controls\", \"UserControl\");\n\t\t\ttypes[KnownTypes.Validation] = InitType(assemblies[4], \"System.Windows.Controls\", \"Validation\");\n\t\t\ttypes[KnownTypes.Vector] = InitType(assemblies[2], \"System.Windows\", \"Vector\");\n\t\t\ttypes[KnownTypes.Vector3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Vector3D\");\n\t\t\ttypes[KnownTypes.Vector3DAnimation] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Vector3DAnimation\");\n\t\t\ttypes[KnownTypes.Vector3DAnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Vector3DAnimationBase\");\n\t\t\ttypes[KnownTypes.Vector3DAnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Vector3DAnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.Vector3DCollection] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Vector3DCollection\");\n\t\t\ttypes[KnownTypes.Vector3DCollectionConverter] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Vector3DCollectionConverter\");\n\t\t\ttypes[KnownTypes.Vector3DConverter] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Vector3DConverter\");\n\t\t\ttypes[KnownTypes.Vector3DKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Vector3DKeyFrame\");\n\t\t\ttypes[KnownTypes.Vector3DKeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Vector3DKeyFrameCollection\");\n\t\t\ttypes[KnownTypes.VectorAnimation] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"VectorAnimation\");\n\t\t\ttypes[KnownTypes.VectorAnimationBase] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"VectorAnimationBase\");\n\t\t\ttypes[KnownTypes.VectorAnimationUsingKeyFrames] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"VectorAnimationUsingKeyFrames\");\n\t\t\ttypes[KnownTypes.VectorCollection] = InitType(assemblies[3], \"System.Windows.Media\", \"VectorCollection\");\n\t\t\ttypes[KnownTypes.VectorCollectionConverter] = InitType(assemblies[3], \"System.Windows.Media\", \"VectorCollectionConverter\");\n\t\t\ttypes[KnownTypes.VectorConverter] = InitType(assemblies[2], \"System.Windows\", \"VectorConverter\");\n\t\t\ttypes[KnownTypes.VectorKeyFrame] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"VectorKeyFrame\");\n\t\t\ttypes[KnownTypes.VectorKeyFrameCollection] = InitType(assemblies[3], \"System.Windows.Media.Animation\", \"VectorKeyFrameCollection\");\n\t\t\ttypes[KnownTypes.VideoDrawing] = InitType(assemblies[3], \"System.Windows.Media\", \"VideoDrawing\");\n\t\t\ttypes[KnownTypes.ViewBase] = InitType(assemblies[4], \"System.Windows.Controls\", \"ViewBase\");\n\t\t\ttypes[KnownTypes.Viewbox] = InitType(assemblies[4], \"System.Windows.Controls\", \"Viewbox\");\n\t\t\ttypes[KnownTypes.Viewport3D] = InitType(assemblies[4], \"System.Windows.Controls\", \"Viewport3D\");\n\t\t\ttypes[KnownTypes.Viewport3DVisual] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Viewport3DVisual\");\n\t\t\ttypes[KnownTypes.VirtualizingPanel] = InitType(assemblies[4], \"System.Windows.Controls\", \"VirtualizingPanel\");\n\t\t\ttypes[KnownTypes.VirtualizingStackPanel] = InitType(assemblies[4], \"System.Windows.Controls\", \"VirtualizingStackPanel\");\n\t\t\ttypes[KnownTypes.Visual] = InitType(assemblies[3], \"System.Windows.Media\", \"Visual\");\n\t\t\ttypes[KnownTypes.Visual3D] = InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Visual3D\");\n\t\t\ttypes[KnownTypes.VisualBrush] = InitType(assemblies[3], \"System.Windows.Media\", \"VisualBrush\");\n\t\t\ttypes[KnownTypes.VisualTarget] = InitType(assemblies[3], \"System.Windows.Media\", \"VisualTarget\");\n\t\t\ttypes[KnownTypes.WeakEventManager] = InitType(assemblies[2], \"System.Windows\", \"WeakEventManager\");\n\t\t\ttypes[KnownTypes.WhitespaceSignificantCollectionAttribute] = InitType(assemblies[2], \"System.Windows.Markup\", \"WhitespaceSignificantCollectionAttribute\");\n\t\t\ttypes[KnownTypes.Window] = InitType(assemblies[4], \"System.Windows\", \"Window\");\n\t\t\ttypes[KnownTypes.WmpBitmapDecoder] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"WmpBitmapDecoder\");\n\t\t\ttypes[KnownTypes.WmpBitmapEncoder] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"WmpBitmapEncoder\");\n\t\t\ttypes[KnownTypes.WrapPanel] = InitType(assemblies[4], \"System.Windows.Controls\", \"WrapPanel\");\n\t\t\ttypes[KnownTypes.WriteableBitmap] = InitType(assemblies[3], \"System.Windows.Media.Imaging\", \"WriteableBitmap\");\n\t\t\ttypes[KnownTypes.XamlBrushSerializer] = InitType(assemblies[4], \"System.Windows.Markup\", \"XamlBrushSerializer\");\n\t\t\ttypes[KnownTypes.XamlInt32CollectionSerializer] = InitType(assemblies[4], \"System.Windows.Markup\", \"XamlInt32CollectionSerializer\");\n\t\t\ttypes[KnownTypes.XamlPathDataSerializer] = InitType(assemblies[4], \"System.Windows.Markup\", \"XamlPathDataSerializer\");\n\t\t\ttypes[KnownTypes.XamlPoint3DCollectionSerializer] = InitType(assemblies[4], \"System.Windows.Markup\", \"XamlPoint3DCollectionSerializer\");\n\t\t\ttypes[KnownTypes.XamlPointCollectionSerializer] = InitType(assemblies[4], \"System.Windows.Markup\", \"XamlPointCollectionSerializer\");\n\t\t\ttypes[KnownTypes.XamlReader] = InitType(assemblies[4], \"System.Windows.Markup\", \"XamlReader\");\n\t\t\ttypes[KnownTypes.XamlStyleSerializer] = InitType(assemblies[4], \"System.Windows.Markup\", \"XamlStyleSerializer\");\n\t\t\ttypes[KnownTypes.XamlTemplateSerializer] = InitType(assemblies[4], \"System.Windows.Markup\", \"XamlTemplateSerializer\");\n\t\t\ttypes[KnownTypes.XamlVector3DCollectionSerializer] = InitType(assemblies[4], \"System.Windows.Markup\", \"XamlVector3DCollectionSerializer\");\n\t\t\ttypes[KnownTypes.XamlWriter] = InitType(assemblies[4], \"System.Windows.Markup\", \"XamlWriter\");\n\t\t\ttypes[KnownTypes.XmlDataProvider] = InitType(assemblies[4], \"System.Windows.Data\", \"XmlDataProvider\");\n\t\t\ttypes[KnownTypes.XmlLangPropertyAttribute] = InitType(assemblies[2], \"System.Windows.Markup\", \"XmlLangPropertyAttribute\");\n\t\t\ttypes[KnownTypes.XmlLanguage] = InitType(assemblies[3], \"System.Windows.Markup\", \"XmlLanguage\");\n\t\t\ttypes[KnownTypes.XmlLanguageConverter] = InitType(assemblies[3], \"System.Windows.Markup\", \"XmlLanguageConverter\");\n\t\t\ttypes[KnownTypes.XmlNamespaceMapping] = InitType(assemblies[4], \"System.Windows.Data\", \"XmlNamespaceMapping\");\n\t\t\ttypes[KnownTypes.ZoomPercentageConverter] = InitType(assemblies[4], \"System.Windows.Documents\", \"ZoomPercentageConverter\");\n\t\t}\n\n\t\tvoid InitMembers()\n\t\t{\n\t\t\tmembers[KnownMembers.AccessText_Text] = InitMember(KnownTypes.AccessText, \"Text\", InitType(assemblies[0], \"System\", \"String\"));\n\t\t\tmembers[KnownMembers.BeginStoryboard_Storyboard] = InitMember(KnownTypes.BeginStoryboard, \"Storyboard\", InitType(assemblies[4], \"System.Windows.Media.Animation\", \"Storyboard\"));\n\t\t\tmembers[KnownMembers.BitmapEffectGroup_Children] = InitMember(KnownTypes.BitmapEffectGroup, \"Children\", InitType(assemblies[3], \"System.Windows.Media.Effects\", \"BitmapEffectCollection\"));\n\t\t\tmembers[KnownMembers.Border_Background] = InitMember(KnownTypes.Border, \"Background\", InitType(assemblies[3], \"System.Windows.Media\", \"Brush\"));\n\t\t\tmembers[KnownMembers.Border_BorderBrush] = InitMember(KnownTypes.Border, \"BorderBrush\", InitType(assemblies[3], \"System.Windows.Media\", \"Brush\"));\n\t\t\tmembers[KnownMembers.Border_BorderThickness] = InitMember(KnownTypes.Border, \"BorderThickness\", InitType(assemblies[4], \"System.Windows\", \"Thickness\"));\n\t\t\tmembers[KnownMembers.ButtonBase_Command] = InitMember(KnownTypes.ButtonBase, \"Command\", InitType(assemblies[3], \"System.Windows.Input\", \"ICommand\"));\n\t\t\tmembers[KnownMembers.ButtonBase_CommandParameter] = InitMember(KnownTypes.ButtonBase, \"CommandParameter\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.ButtonBase_CommandTarget] = InitMember(KnownTypes.ButtonBase, \"CommandTarget\", InitType(assemblies[3], \"System.Windows\", \"IInputElement\"));\n\t\t\tmembers[KnownMembers.ButtonBase_IsPressed] = InitMember(KnownTypes.ButtonBase, \"IsPressed\", InitType(assemblies[0], \"System\", \"Boolean\"));\n\t\t\tmembers[KnownMembers.ColumnDefinition_MaxWidth] = InitMember(KnownTypes.ColumnDefinition, \"MaxWidth\", InitType(assemblies[0], \"System\", \"Double\"));\n\t\t\tmembers[KnownMembers.ColumnDefinition_MinWidth] = InitMember(KnownTypes.ColumnDefinition, \"MinWidth\", InitType(assemblies[0], \"System\", \"Double\"));\n\t\t\tmembers[KnownMembers.ColumnDefinition_Width] = InitMember(KnownTypes.ColumnDefinition, \"Width\", InitType(assemblies[4], \"System.Windows\", \"GridLength\"));\n\t\t\tmembers[KnownMembers.ContentControl_Content] = InitMember(KnownTypes.ContentControl, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.ContentControl_ContentTemplate] = InitMember(KnownTypes.ContentControl, \"ContentTemplate\", InitType(assemblies[4], \"System.Windows\", \"DataTemplate\"));\n\t\t\tmembers[KnownMembers.ContentControl_ContentTemplateSelector] = InitMember(KnownTypes.ContentControl, \"ContentTemplateSelector\", InitType(assemblies[4], \"System.Windows.Controls\", \"DataTemplateSelector\"));\n\t\t\tmembers[KnownMembers.ContentControl_HasContent] = InitMember(KnownTypes.ContentControl, \"HasContent\", InitType(assemblies[0], \"System\", \"Boolean\"));\n\t\t\tmembers[KnownMembers.ContentElement_Focusable] = InitMember(KnownTypes.ContentElement, \"Focusable\", InitType(assemblies[0], \"System\", \"Boolean\"));\n\t\t\tmembers[KnownMembers.ContentPresenter_Content] = InitMember(KnownTypes.ContentPresenter, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.ContentPresenter_ContentSource] = InitMember(KnownTypes.ContentPresenter, \"ContentSource\", InitType(assemblies[0], \"System\", \"String\"));\n\t\t\tmembers[KnownMembers.ContentPresenter_ContentTemplate] = InitMember(KnownTypes.ContentPresenter, \"ContentTemplate\", InitType(assemblies[4], \"System.Windows\", \"DataTemplate\"));\n\t\t\tmembers[KnownMembers.ContentPresenter_ContentTemplateSelector] = InitMember(KnownTypes.ContentPresenter, \"ContentTemplateSelector\", InitType(assemblies[4], \"System.Windows.Controls\", \"DataTemplateSelector\"));\n\t\t\tmembers[KnownMembers.ContentPresenter_RecognizesAccessKey] = InitMember(KnownTypes.ContentPresenter, \"RecognizesAccessKey\", InitType(assemblies[0], \"System\", \"Boolean\"));\n\t\t\tmembers[KnownMembers.Control_Background] = InitMember(KnownTypes.Control, \"Background\", InitType(assemblies[3], \"System.Windows.Media\", \"Brush\"));\n\t\t\tmembers[KnownMembers.Control_BorderBrush] = InitMember(KnownTypes.Control, \"BorderBrush\", InitType(assemblies[3], \"System.Windows.Media\", \"Brush\"));\n\t\t\tmembers[KnownMembers.Control_BorderThickness] = InitMember(KnownTypes.Control, \"BorderThickness\", InitType(assemblies[4], \"System.Windows\", \"Thickness\"));\n\t\t\tmembers[KnownMembers.Control_FontFamily] = InitMember(KnownTypes.Control, \"FontFamily\", InitType(assemblies[3], \"System.Windows.Media\", \"FontFamily\"));\n\t\t\tmembers[KnownMembers.Control_FontSize] = InitMember(KnownTypes.Control, \"FontSize\", InitType(assemblies[0], \"System\", \"Double\"));\n\t\t\tmembers[KnownMembers.Control_FontStretch] = InitMember(KnownTypes.Control, \"FontStretch\", InitType(assemblies[3], \"System.Windows\", \"FontStretch\"));\n\t\t\tmembers[KnownMembers.Control_FontStyle] = InitMember(KnownTypes.Control, \"FontStyle\", InitType(assemblies[3], \"System.Windows\", \"FontStyle\"));\n\t\t\tmembers[KnownMembers.Control_FontWeight] = InitMember(KnownTypes.Control, \"FontWeight\", InitType(assemblies[3], \"System.Windows\", \"FontWeight\"));\n\t\t\tmembers[KnownMembers.Control_Foreground] = InitMember(KnownTypes.Control, \"Foreground\", InitType(assemblies[3], \"System.Windows.Media\", \"Brush\"));\n\t\t\tmembers[KnownMembers.Control_HorizontalContentAlignment] = InitMember(KnownTypes.Control, \"HorizontalContentAlignment\", InitType(assemblies[4], \"System.Windows\", \"HorizontalAlignment\"));\n\t\t\tmembers[KnownMembers.Control_IsTabStop] = InitMember(KnownTypes.Control, \"IsTabStop\", InitType(assemblies[0], \"System\", \"Boolean\"));\n\t\t\tmembers[KnownMembers.Control_Padding] = InitMember(KnownTypes.Control, \"Padding\", InitType(assemblies[4], \"System.Windows\", \"Thickness\"));\n\t\t\tmembers[KnownMembers.Control_TabIndex] = InitMember(KnownTypes.Control, \"TabIndex\", InitType(assemblies[0], \"System\", \"Int32\"));\n\t\t\tmembers[KnownMembers.Control_Template] = InitMember(KnownTypes.Control, \"Template\", InitType(assemblies[4], \"System.Windows.Controls\", \"ControlTemplate\"));\n\t\t\tmembers[KnownMembers.Control_VerticalContentAlignment] = InitMember(KnownTypes.Control, \"VerticalContentAlignment\", InitType(assemblies[4], \"System.Windows\", \"VerticalAlignment\"));\n\t\t\tmembers[KnownMembers.DockPanel_Dock] = InitMember(KnownTypes.DockPanel, \"Dock\", InitType(assemblies[4], \"System.Windows.Controls\", \"Dock\"));\n\t\t\tmembers[KnownMembers.DockPanel_LastChildFill] = InitMember(KnownTypes.DockPanel, \"LastChildFill\", InitType(assemblies[0], \"System\", \"Boolean\"));\n\t\t\tmembers[KnownMembers.DocumentViewerBase_Document] = InitMember(KnownTypes.DocumentViewerBase, \"Document\", InitType(assemblies[3], \"System.Windows.Documents\", \"IDocumentPaginatorSource\"));\n\t\t\tmembers[KnownMembers.DrawingGroup_Children] = InitMember(KnownTypes.DrawingGroup, \"Children\", InitType(assemblies[3], \"System.Windows.Media\", \"DrawingCollection\"));\n\t\t\tmembers[KnownMembers.FlowDocumentReader_Document] = InitMember(KnownTypes.FlowDocumentReader, \"Document\", InitType(assemblies[4], \"System.Windows.Documents\", \"FlowDocument\"));\n\t\t\tmembers[KnownMembers.FlowDocumentScrollViewer_Document] = InitMember(KnownTypes.FlowDocumentScrollViewer, \"Document\", InitType(assemblies[4], \"System.Windows.Documents\", \"FlowDocument\"));\n\t\t\tmembers[KnownMembers.FrameworkContentElement_Style] = InitMember(KnownTypes.FrameworkContentElement, \"Style\", InitType(assemblies[4], \"System.Windows\", \"Style\"));\n\t\t\tmembers[KnownMembers.FrameworkElement_FlowDirection] = InitMember(KnownTypes.FrameworkElement, \"FlowDirection\", InitType(assemblies[3], \"System.Windows\", \"FlowDirection\"));\n\t\t\tmembers[KnownMembers.FrameworkElement_Height] = InitMember(KnownTypes.FrameworkElement, \"Height\", InitType(assemblies[0], \"System\", \"Double\"));\n\t\t\tmembers[KnownMembers.FrameworkElement_HorizontalAlignment] = InitMember(KnownTypes.FrameworkElement, \"HorizontalAlignment\", InitType(assemblies[4], \"System.Windows\", \"HorizontalAlignment\"));\n\t\t\tmembers[KnownMembers.FrameworkElement_Margin] = InitMember(KnownTypes.FrameworkElement, \"Margin\", InitType(assemblies[4], \"System.Windows\", \"Thickness\"));\n\t\t\tmembers[KnownMembers.FrameworkElement_MaxHeight] = InitMember(KnownTypes.FrameworkElement, \"MaxHeight\", InitType(assemblies[0], \"System\", \"Double\"));\n\t\t\tmembers[KnownMembers.FrameworkElement_MaxWidth] = InitMember(KnownTypes.FrameworkElement, \"MaxWidth\", InitType(assemblies[0], \"System\", \"Double\"));\n\t\t\tmembers[KnownMembers.FrameworkElement_MinHeight] = InitMember(KnownTypes.FrameworkElement, \"MinHeight\", InitType(assemblies[0], \"System\", \"Double\"));\n\t\t\tmembers[KnownMembers.FrameworkElement_MinWidth] = InitMember(KnownTypes.FrameworkElement, \"MinWidth\", InitType(assemblies[0], \"System\", \"Double\"));\n\t\t\tmembers[KnownMembers.FrameworkElement_Name] = InitMember(KnownTypes.FrameworkElement, \"Name\", InitType(assemblies[0], \"System\", \"String\"));\n\t\t\tmembers[KnownMembers.FrameworkElement_Style] = InitMember(KnownTypes.FrameworkElement, \"Style\", InitType(assemblies[4], \"System.Windows\", \"Style\"));\n\t\t\tmembers[KnownMembers.FrameworkElement_VerticalAlignment] = InitMember(KnownTypes.FrameworkElement, \"VerticalAlignment\", InitType(assemblies[4], \"System.Windows\", \"VerticalAlignment\"));\n\t\t\tmembers[KnownMembers.FrameworkElement_Width] = InitMember(KnownTypes.FrameworkElement, \"Width\", InitType(assemblies[0], \"System\", \"Double\"));\n\t\t\tmembers[KnownMembers.GeneralTransformGroup_Children] = InitMember(KnownTypes.GeneralTransformGroup, \"Children\", InitType(assemblies[3], \"System.Windows.Media\", \"GeneralTransformCollection\"));\n\t\t\tmembers[KnownMembers.GeometryGroup_Children] = InitMember(KnownTypes.GeometryGroup, \"Children\", InitType(assemblies[3], \"System.Windows.Media\", \"GeometryCollection\"));\n\t\t\tmembers[KnownMembers.GradientBrush_GradientStops] = InitMember(KnownTypes.GradientBrush, \"GradientStops\", InitType(assemblies[3], \"System.Windows.Media\", \"GradientStopCollection\"));\n\t\t\tmembers[KnownMembers.Grid_Column] = InitMember(KnownTypes.Grid, \"Column\", InitType(assemblies[0], \"System\", \"Int32\"));\n\t\t\tmembers[KnownMembers.Grid_ColumnSpan] = InitMember(KnownTypes.Grid, \"ColumnSpan\", InitType(assemblies[0], \"System\", \"Int32\"));\n\t\t\tmembers[KnownMembers.Grid_Row] = InitMember(KnownTypes.Grid, \"Row\", InitType(assemblies[0], \"System\", \"Int32\"));\n\t\t\tmembers[KnownMembers.Grid_RowSpan] = InitMember(KnownTypes.Grid, \"RowSpan\", InitType(assemblies[0], \"System\", \"Int32\"));\n\t\t\tmembers[KnownMembers.GridViewColumn_Header] = InitMember(KnownTypes.GridViewColumn, \"Header\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.HeaderedContentControl_HasHeader] = InitMember(KnownTypes.HeaderedContentControl, \"HasHeader\", InitType(assemblies[0], \"System\", \"Boolean\"));\n\t\t\tmembers[KnownMembers.HeaderedContentControl_Header] = InitMember(KnownTypes.HeaderedContentControl, \"Header\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.HeaderedContentControl_HeaderTemplate] = InitMember(KnownTypes.HeaderedContentControl, \"HeaderTemplate\", InitType(assemblies[4], \"System.Windows\", \"DataTemplate\"));\n\t\t\tmembers[KnownMembers.HeaderedContentControl_HeaderTemplateSelector] = InitMember(KnownTypes.HeaderedContentControl, \"HeaderTemplateSelector\", InitType(assemblies[4], \"System.Windows.Controls\", \"DataTemplateSelector\"));\n\t\t\tmembers[KnownMembers.HeaderedItemsControl_HasHeader] = InitMember(KnownTypes.HeaderedItemsControl, \"HasHeader\", InitType(assemblies[0], \"System\", \"Boolean\"));\n\t\t\tmembers[KnownMembers.HeaderedItemsControl_Header] = InitMember(KnownTypes.HeaderedItemsControl, \"Header\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.HeaderedItemsControl_HeaderTemplate] = InitMember(KnownTypes.HeaderedItemsControl, \"HeaderTemplate\", InitType(assemblies[4], \"System.Windows\", \"DataTemplate\"));\n\t\t\tmembers[KnownMembers.HeaderedItemsControl_HeaderTemplateSelector] = InitMember(KnownTypes.HeaderedItemsControl, \"HeaderTemplateSelector\", InitType(assemblies[4], \"System.Windows.Controls\", \"DataTemplateSelector\"));\n\t\t\tmembers[KnownMembers.Hyperlink_NavigateUri] = InitMember(KnownTypes.Hyperlink, \"NavigateUri\", InitType(assemblies[1], \"System\", \"Uri\"));\n\t\t\tmembers[KnownMembers.Image_Source] = InitMember(KnownTypes.Image, \"Source\", InitType(assemblies[3], \"System.Windows.Media\", \"ImageSource\"));\n\t\t\tmembers[KnownMembers.Image_Stretch] = InitMember(KnownTypes.Image, \"Stretch\", InitType(assemblies[3], \"System.Windows.Media\", \"Stretch\"));\n\t\t\tmembers[KnownMembers.ItemsControl_ItemContainerStyle] = InitMember(KnownTypes.ItemsControl, \"ItemContainerStyle\", InitType(assemblies[4], \"System.Windows\", \"Style\"));\n\t\t\tmembers[KnownMembers.ItemsControl_ItemContainerStyleSelector] = InitMember(KnownTypes.ItemsControl, \"ItemContainerStyleSelector\", InitType(assemblies[4], \"System.Windows.Controls\", \"StyleSelector\"));\n\t\t\tmembers[KnownMembers.ItemsControl_ItemTemplate] = InitMember(KnownTypes.ItemsControl, \"ItemTemplate\", InitType(assemblies[4], \"System.Windows\", \"DataTemplate\"));\n\t\t\tmembers[KnownMembers.ItemsControl_ItemTemplateSelector] = InitMember(KnownTypes.ItemsControl, \"ItemTemplateSelector\", InitType(assemblies[4], \"System.Windows.Controls\", \"DataTemplateSelector\"));\n\t\t\tmembers[KnownMembers.ItemsControl_ItemsPanel] = InitMember(KnownTypes.ItemsControl, \"ItemsPanel\", InitType(assemblies[4], \"System.Windows.Controls\", \"ItemsPanelTemplate\"));\n\t\t\tmembers[KnownMembers.ItemsControl_ItemsSource] = InitMember(KnownTypes.ItemsControl, \"ItemsSource\", InitType(assemblies[0], \"System.Collections\", \"IEnumerable\"));\n\t\t\tmembers[KnownMembers.MaterialGroup_Children] = InitMember(KnownTypes.MaterialGroup, \"Children\", InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"MaterialCollection\"));\n\t\t\tmembers[KnownMembers.Model3DGroup_Children] = InitMember(KnownTypes.Model3DGroup, \"Children\", InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Model3DCollection\"));\n\t\t\tmembers[KnownMembers.Page_Content] = InitMember(KnownTypes.Page, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.Panel_Background] = InitMember(KnownTypes.Panel, \"Background\", InitType(assemblies[3], \"System.Windows.Media\", \"Brush\"));\n\t\t\tmembers[KnownMembers.Path_Data] = InitMember(KnownTypes.Path, \"Data\", InitType(assemblies[3], \"System.Windows.Media\", \"Geometry\"));\n\t\t\tmembers[KnownMembers.PathFigure_Segments] = InitMember(KnownTypes.PathFigure, \"Segments\", InitType(assemblies[3], \"System.Windows.Media\", \"PathSegmentCollection\"));\n\t\t\tmembers[KnownMembers.PathGeometry_Figures] = InitMember(KnownTypes.PathGeometry, \"Figures\", InitType(assemblies[3], \"System.Windows.Media\", \"PathFigureCollection\"));\n\t\t\tmembers[KnownMembers.Popup_Child] = InitMember(KnownTypes.Popup, \"Child\", InitType(assemblies[3], \"System.Windows\", \"UIElement\"));\n\t\t\tmembers[KnownMembers.Popup_IsOpen] = InitMember(KnownTypes.Popup, \"IsOpen\", InitType(assemblies[0], \"System\", \"Boolean\"));\n\t\t\tmembers[KnownMembers.Popup_Placement] = InitMember(KnownTypes.Popup, \"Placement\", InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"PlacementMode\"));\n\t\t\tmembers[KnownMembers.Popup_PopupAnimation] = InitMember(KnownTypes.Popup, \"PopupAnimation\", InitType(assemblies[4], \"System.Windows.Controls.Primitives\", \"PopupAnimation\"));\n\t\t\tmembers[KnownMembers.RowDefinition_Height] = InitMember(KnownTypes.RowDefinition, \"Height\", InitType(assemblies[4], \"System.Windows\", \"GridLength\"));\n\t\t\tmembers[KnownMembers.RowDefinition_MaxHeight] = InitMember(KnownTypes.RowDefinition, \"MaxHeight\", InitType(assemblies[0], \"System\", \"Double\"));\n\t\t\tmembers[KnownMembers.RowDefinition_MinHeight] = InitMember(KnownTypes.RowDefinition, \"MinHeight\", InitType(assemblies[0], \"System\", \"Double\"));\n\t\t\tmembers[KnownMembers.ScrollViewer_CanContentScroll] = InitMember(KnownTypes.ScrollViewer, \"CanContentScroll\", InitType(assemblies[0], \"System\", \"Boolean\"));\n\t\t\tmembers[KnownMembers.ScrollViewer_HorizontalScrollBarVisibility] = InitMember(KnownTypes.ScrollViewer, \"HorizontalScrollBarVisibility\", InitType(assemblies[4], \"System.Windows.Controls\", \"ScrollBarVisibility\"));\n\t\t\tmembers[KnownMembers.ScrollViewer_VerticalScrollBarVisibility] = InitMember(KnownTypes.ScrollViewer, \"VerticalScrollBarVisibility\", InitType(assemblies[4], \"System.Windows.Controls\", \"ScrollBarVisibility\"));\n\t\t\tmembers[KnownMembers.Shape_Fill] = InitMember(KnownTypes.Shape, \"Fill\", InitType(assemblies[3], \"System.Windows.Media\", \"Brush\"));\n\t\t\tmembers[KnownMembers.Shape_Stroke] = InitMember(KnownTypes.Shape, \"Stroke\", InitType(assemblies[3], \"System.Windows.Media\", \"Brush\"));\n\t\t\tmembers[KnownMembers.Shape_StrokeThickness] = InitMember(KnownTypes.Shape, \"StrokeThickness\", InitType(assemblies[0], \"System\", \"Double\"));\n\t\t\tmembers[KnownMembers.TextBlock_Background] = InitMember(KnownTypes.TextBlock, \"Background\", InitType(assemblies[3], \"System.Windows.Media\", \"Brush\"));\n\t\t\tmembers[KnownMembers.TextBlock_FontFamily] = InitMember(KnownTypes.TextBlock, \"FontFamily\", InitType(assemblies[3], \"System.Windows.Media\", \"FontFamily\"));\n\t\t\tmembers[KnownMembers.TextBlock_FontSize] = InitMember(KnownTypes.TextBlock, \"FontSize\", InitType(assemblies[0], \"System\", \"Double\"));\n\t\t\tmembers[KnownMembers.TextBlock_FontStretch] = InitMember(KnownTypes.TextBlock, \"FontStretch\", InitType(assemblies[3], \"System.Windows\", \"FontStretch\"));\n\t\t\tmembers[KnownMembers.TextBlock_FontStyle] = InitMember(KnownTypes.TextBlock, \"FontStyle\", InitType(assemblies[3], \"System.Windows\", \"FontStyle\"));\n\t\t\tmembers[KnownMembers.TextBlock_FontWeight] = InitMember(KnownTypes.TextBlock, \"FontWeight\", InitType(assemblies[3], \"System.Windows\", \"FontWeight\"));\n\t\t\tmembers[KnownMembers.TextBlock_Foreground] = InitMember(KnownTypes.TextBlock, \"Foreground\", InitType(assemblies[3], \"System.Windows.Media\", \"Brush\"));\n\t\t\tmembers[KnownMembers.TextBlock_Text] = InitMember(KnownTypes.TextBlock, \"Text\", InitType(assemblies[0], \"System\", \"String\"));\n\t\t\tmembers[KnownMembers.TextBlock_TextDecorations] = InitMember(KnownTypes.TextBlock, \"TextDecorations\", InitType(assemblies[3], \"System.Windows\", \"TextDecorationCollection\"));\n\t\t\tmembers[KnownMembers.TextBlock_TextTrimming] = InitMember(KnownTypes.TextBlock, \"TextTrimming\", InitType(assemblies[3], \"System.Windows\", \"TextTrimming\"));\n\t\t\tmembers[KnownMembers.TextBlock_TextWrapping] = InitMember(KnownTypes.TextBlock, \"TextWrapping\", InitType(assemblies[3], \"System.Windows\", \"TextWrapping\"));\n\t\t\tmembers[KnownMembers.TextBox_Text] = InitMember(KnownTypes.TextBox, \"Text\", InitType(assemblies[0], \"System\", \"String\"));\n\t\t\tmembers[KnownMembers.TextElement_Background] = InitMember(KnownTypes.TextElement, \"Background\", InitType(assemblies[3], \"System.Windows.Media\", \"Brush\"));\n\t\t\tmembers[KnownMembers.TextElement_FontFamily] = InitMember(KnownTypes.TextElement, \"FontFamily\", InitType(assemblies[3], \"System.Windows.Media\", \"FontFamily\"));\n\t\t\tmembers[KnownMembers.TextElement_FontSize] = InitMember(KnownTypes.TextElement, \"FontSize\", InitType(assemblies[0], \"System\", \"Double\"));\n\t\t\tmembers[KnownMembers.TextElement_FontStretch] = InitMember(KnownTypes.TextElement, \"FontStretch\", InitType(assemblies[3], \"System.Windows\", \"FontStretch\"));\n\t\t\tmembers[KnownMembers.TextElement_FontStyle] = InitMember(KnownTypes.TextElement, \"FontStyle\", InitType(assemblies[3], \"System.Windows\", \"FontStyle\"));\n\t\t\tmembers[KnownMembers.TextElement_FontWeight] = InitMember(KnownTypes.TextElement, \"FontWeight\", InitType(assemblies[3], \"System.Windows\", \"FontWeight\"));\n\t\t\tmembers[KnownMembers.TextElement_Foreground] = InitMember(KnownTypes.TextElement, \"Foreground\", InitType(assemblies[3], \"System.Windows.Media\", \"Brush\"));\n\t\t\tmembers[KnownMembers.TimelineGroup_Children] = InitMember(KnownTypes.TimelineGroup, \"Children\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"TimelineCollection\"));\n\t\t\tmembers[KnownMembers.Track_IsDirectionReversed] = InitMember(KnownTypes.Track, \"IsDirectionReversed\", InitType(assemblies[0], \"System\", \"Boolean\"));\n\t\t\tmembers[KnownMembers.Track_Maximum] = InitMember(KnownTypes.Track, \"Maximum\", InitType(assemblies[0], \"System\", \"Double\"));\n\t\t\tmembers[KnownMembers.Track_Minimum] = InitMember(KnownTypes.Track, \"Minimum\", InitType(assemblies[0], \"System\", \"Double\"));\n\t\t\tmembers[KnownMembers.Track_Orientation] = InitMember(KnownTypes.Track, \"Orientation\", InitType(assemblies[4], \"System.Windows.Controls\", \"Orientation\"));\n\t\t\tmembers[KnownMembers.Track_Value] = InitMember(KnownTypes.Track, \"Value\", InitType(assemblies[0], \"System\", \"Double\"));\n\t\t\tmembers[KnownMembers.Track_ViewportSize] = InitMember(KnownTypes.Track, \"ViewportSize\", InitType(assemblies[0], \"System\", \"Double\"));\n\t\t\tmembers[KnownMembers.Transform3DGroup_Children] = InitMember(KnownTypes.Transform3DGroup, \"Children\", InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Transform3DCollection\"));\n\t\t\tmembers[KnownMembers.TransformGroup_Children] = InitMember(KnownTypes.TransformGroup, \"Children\", InitType(assemblies[3], \"System.Windows.Media\", \"TransformCollection\"));\n\t\t\tmembers[KnownMembers.UIElement_ClipToBounds] = InitMember(KnownTypes.UIElement, \"ClipToBounds\", InitType(assemblies[0], \"System\", \"Boolean\"));\n\t\t\tmembers[KnownMembers.UIElement_Focusable] = InitMember(KnownTypes.UIElement, \"Focusable\", InitType(assemblies[0], \"System\", \"Boolean\"));\n\t\t\tmembers[KnownMembers.UIElement_IsEnabled] = InitMember(KnownTypes.UIElement, \"IsEnabled\", InitType(assemblies[0], \"System\", \"Boolean\"));\n\t\t\tmembers[KnownMembers.UIElement_RenderTransform] = InitMember(KnownTypes.UIElement, \"RenderTransform\", InitType(assemblies[3], \"System.Windows.Media\", \"Transform\"));\n\t\t\tmembers[KnownMembers.UIElement_Visibility] = InitMember(KnownTypes.UIElement, \"Visibility\", InitType(assemblies[3], \"System.Windows\", \"Visibility\"));\n\t\t\tmembers[KnownMembers.Viewport3D_Children] = InitMember(KnownTypes.Viewport3D, \"Children\", InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Visual3DCollection\"));\n\n\t\t\tmembers[KnownMembers.AdornedElementPlaceholder_Child] = InitMember(KnownTypes.AdornedElementPlaceholder, \"Child\", InitType(assemblies[3], \"System.Windows\", \"UIElement\"));\n\t\t\tmembers[KnownMembers.AdornerDecorator_Child] = InitMember(KnownTypes.AdornerDecorator, \"Child\", InitType(assemblies[3], \"System.Windows\", \"UIElement\"));\n\t\t\tmembers[KnownMembers.AnchoredBlock_Blocks] = InitMember(KnownTypes.AnchoredBlock, \"Blocks\", InitType(assemblies[4], \"System.Windows.Documents\", \"BlockCollection\"));\n\t\t\tmembers[KnownMembers.ArrayExtension_Items] = InitMember(KnownTypes.ArrayExtension, \"Items\", InitType(assemblies[0], \"System.Collections\", \"IList\"));\n\t\t\tmembers[KnownMembers.BlockUIContainer_Child] = InitMember(KnownTypes.BlockUIContainer, \"Child\", InitType(assemblies[3], \"System.Windows\", \"UIElement\"));\n\t\t\tmembers[KnownMembers.Bold_Inlines] = InitMember(KnownTypes.Bold, \"Inlines\", InitType(assemblies[4], \"System.Windows.Documents\", \"InlineCollection\"));\n\t\t\tmembers[KnownMembers.BooleanAnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.BooleanAnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"BooleanKeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.Border_Child] = InitMember(KnownTypes.Border, \"Child\", InitType(assemblies[3], \"System.Windows\", \"UIElement\"));\n\t\t\tmembers[KnownMembers.BulletDecorator_Child] = InitMember(KnownTypes.BulletDecorator, \"Child\", InitType(assemblies[3], \"System.Windows\", \"UIElement\"));\n\t\t\tmembers[KnownMembers.Button_Content] = InitMember(KnownTypes.Button, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.ButtonBase_Content] = InitMember(KnownTypes.ButtonBase, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.ByteAnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.ByteAnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ByteKeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.Canvas_Children] = InitMember(KnownTypes.Canvas, \"Children\", InitType(assemblies[4], \"System.Windows.Controls\", \"UIElementCollection\"));\n\t\t\tmembers[KnownMembers.CharAnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.CharAnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"CharKeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.CheckBox_Content] = InitMember(KnownTypes.CheckBox, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.ColorAnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.ColorAnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ColorKeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.ComboBox_Items] = InitMember(KnownTypes.ComboBox, \"Items\", InitType(assemblies[4], \"System.Windows.Controls\", \"ItemCollection\"));\n\t\t\tmembers[KnownMembers.ComboBoxItem_Content] = InitMember(KnownTypes.ComboBoxItem, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.ContextMenu_Items] = InitMember(KnownTypes.ContextMenu, \"Items\", InitType(assemblies[4], \"System.Windows.Controls\", \"ItemCollection\"));\n\t\t\tmembers[KnownMembers.ControlTemplate_VisualTree] = InitMember(KnownTypes.ControlTemplate, \"VisualTree\", InitType(assemblies[4], \"System.Windows\", \"FrameworkElementFactory\"));\n\t\t\tmembers[KnownMembers.DataTemplate_VisualTree] = InitMember(KnownTypes.DataTemplate, \"VisualTree\", InitType(assemblies[4], \"System.Windows\", \"FrameworkElementFactory\"));\n\t\t\tmembers[KnownMembers.DataTrigger_Setters] = InitMember(KnownTypes.DataTrigger, \"Setters\", InitType(assemblies[4], \"System.Windows\", \"SetterBaseCollection\"));\n\t\t\tmembers[KnownMembers.DecimalAnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.DecimalAnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DecimalKeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.Decorator_Child] = InitMember(KnownTypes.Decorator, \"Child\", InitType(assemblies[3], \"System.Windows\", \"UIElement\"));\n\t\t\tmembers[KnownMembers.DockPanel_Children] = InitMember(KnownTypes.DockPanel, \"Children\", InitType(assemblies[4], \"System.Windows.Controls\", \"UIElementCollection\"));\n\t\t\tmembers[KnownMembers.DocumentViewer_Document] = InitMember(KnownTypes.DocumentViewer, \"Document\", InitType(assemblies[3], \"System.Windows.Documents\", \"IDocumentPaginatorSource\"));\n\t\t\tmembers[KnownMembers.DoubleAnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.DoubleAnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"DoubleKeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.EventTrigger_Actions] = InitMember(KnownTypes.EventTrigger, \"Actions\", InitType(assemblies[4], \"System.Windows\", \"TriggerActionCollection\"));\n\t\t\tmembers[KnownMembers.Expander_Content] = InitMember(KnownTypes.Expander, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.Figure_Blocks] = InitMember(KnownTypes.Figure, \"Blocks\", InitType(assemblies[4], \"System.Windows.Documents\", \"BlockCollection\"));\n\t\t\tmembers[KnownMembers.FixedDocument_Pages] = InitMember(KnownTypes.FixedDocument, \"Pages\", InitType(assemblies[4], \"System.Windows.Documents\", \"PageContentCollection\"));\n\t\t\tmembers[KnownMembers.FixedDocumentSequence_References] = InitMember(KnownTypes.FixedDocumentSequence, \"References\", InitType(assemblies[4], \"System.Windows.Documents\", \"DocumentReferenceCollection\"));\n\t\t\tmembers[KnownMembers.FixedPage_Children] = InitMember(KnownTypes.FixedPage, \"Children\", InitType(assemblies[4], \"System.Windows.Controls\", \"UIElementCollection\"));\n\t\t\tmembers[KnownMembers.Floater_Blocks] = InitMember(KnownTypes.Floater, \"Blocks\", InitType(assemblies[4], \"System.Windows.Documents\", \"BlockCollection\"));\n\t\t\tmembers[KnownMembers.FlowDocument_Blocks] = InitMember(KnownTypes.FlowDocument, \"Blocks\", InitType(assemblies[4], \"System.Windows.Documents\", \"BlockCollection\"));\n\t\t\tmembers[KnownMembers.FlowDocumentPageViewer_Document] = InitMember(KnownTypes.FlowDocumentPageViewer, \"Document\", InitType(assemblies[3], \"System.Windows.Documents\", \"IDocumentPaginatorSource\"));\n\t\t\tmembers[KnownMembers.FrameworkTemplate_VisualTree] = InitMember(KnownTypes.FrameworkTemplate, \"VisualTree\", InitType(assemblies[4], \"System.Windows\", \"FrameworkElementFactory\"));\n\t\t\tmembers[KnownMembers.Grid_Children] = InitMember(KnownTypes.Grid, \"Children\", InitType(assemblies[4], \"System.Windows.Controls\", \"UIElementCollection\"));\n\t\t\tmembers[KnownMembers.GridView_Columns] = InitMember(KnownTypes.GridView, \"Columns\", InitType(assemblies[4], \"System.Windows.Controls\", \"GridViewColumnCollection\"));\n\t\t\tmembers[KnownMembers.GridViewColumnHeader_Content] = InitMember(KnownTypes.GridViewColumnHeader, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.GroupBox_Content] = InitMember(KnownTypes.GroupBox, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.GroupItem_Content] = InitMember(KnownTypes.GroupItem, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.HeaderedContentControl_Content] = InitMember(KnownTypes.HeaderedContentControl, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.HeaderedItemsControl_Items] = InitMember(KnownTypes.HeaderedItemsControl, \"Items\", InitType(assemblies[4], \"System.Windows.Controls\", \"ItemCollection\"));\n\t\t\tmembers[KnownMembers.HierarchicalDataTemplate_VisualTree] = InitMember(KnownTypes.HierarchicalDataTemplate, \"VisualTree\", InitType(assemblies[4], \"System.Windows\", \"FrameworkElementFactory\"));\n\t\t\tmembers[KnownMembers.Hyperlink_Inlines] = InitMember(KnownTypes.Hyperlink, \"Inlines\", InitType(assemblies[4], \"System.Windows.Documents\", \"InlineCollection\"));\n\t\t\tmembers[KnownMembers.InkCanvas_Children] = InitMember(KnownTypes.InkCanvas, \"Children\", InitType(assemblies[4], \"System.Windows.Controls\", \"UIElementCollection\"));\n\t\t\tmembers[KnownMembers.InkPresenter_Child] = InitMember(KnownTypes.InkPresenter, \"Child\", InitType(assemblies[3], \"System.Windows\", \"UIElement\"));\n\t\t\tmembers[KnownMembers.InlineUIContainer_Child] = InitMember(KnownTypes.InlineUIContainer, \"Child\", InitType(assemblies[3], \"System.Windows\", \"UIElement\"));\n\t\t\tmembers[KnownMembers.InputScopeName_NameValue] = InitMember(KnownTypes.InputScopeName, \"NameValue\", InitType(assemblies[3], \"System.Windows.Input\", \"InputScopeNameValue\"));\n\t\t\tmembers[KnownMembers.Int16AnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.Int16AnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Int16KeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.Int32AnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.Int32AnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Int32KeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.Int64AnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.Int64AnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Int64KeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.Italic_Inlines] = InitMember(KnownTypes.Italic, \"Inlines\", InitType(assemblies[4], \"System.Windows.Documents\", \"InlineCollection\"));\n\t\t\tmembers[KnownMembers.ItemsControl_Items] = InitMember(KnownTypes.ItemsControl, \"Items\", InitType(assemblies[4], \"System.Windows.Controls\", \"ItemCollection\"));\n\t\t\tmembers[KnownMembers.ItemsPanelTemplate_VisualTree] = InitMember(KnownTypes.ItemsPanelTemplate, \"VisualTree\", InitType(assemblies[4], \"System.Windows\", \"FrameworkElementFactory\"));\n\t\t\tmembers[KnownMembers.Label_Content] = InitMember(KnownTypes.Label, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.LinearGradientBrush_GradientStops] = InitMember(KnownTypes.LinearGradientBrush, \"GradientStops\", InitType(assemblies[3], \"System.Windows.Media\", \"GradientStopCollection\"));\n\t\t\tmembers[KnownMembers.List_ListItems] = InitMember(KnownTypes.List, \"ListItems\", InitType(assemblies[4], \"System.Windows.Documents\", \"ListItemCollection\"));\n\t\t\tmembers[KnownMembers.ListBox_Items] = InitMember(KnownTypes.ListBox, \"Items\", InitType(assemblies[4], \"System.Windows.Controls\", \"ItemCollection\"));\n\t\t\tmembers[KnownMembers.ListBoxItem_Content] = InitMember(KnownTypes.ListBoxItem, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.ListItem_Blocks] = InitMember(KnownTypes.ListItem, \"Blocks\", InitType(assemblies[4], \"System.Windows.Documents\", \"BlockCollection\"));\n\t\t\tmembers[KnownMembers.ListView_Items] = InitMember(KnownTypes.ListView, \"Items\", InitType(assemblies[4], \"System.Windows.Controls\", \"ItemCollection\"));\n\t\t\tmembers[KnownMembers.ListViewItem_Content] = InitMember(KnownTypes.ListViewItem, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.MatrixAnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.MatrixAnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"MatrixKeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.Menu_Items] = InitMember(KnownTypes.Menu, \"Items\", InitType(assemblies[4], \"System.Windows.Controls\", \"ItemCollection\"));\n\t\t\tmembers[KnownMembers.MenuBase_Items] = InitMember(KnownTypes.MenuBase, \"Items\", InitType(assemblies[4], \"System.Windows.Controls\", \"ItemCollection\"));\n\t\t\tmembers[KnownMembers.MenuItem_Items] = InitMember(KnownTypes.MenuItem, \"Items\", InitType(assemblies[4], \"System.Windows.Controls\", \"ItemCollection\"));\n\t\t\tmembers[KnownMembers.ModelVisual3D_Children] = InitMember(KnownTypes.ModelVisual3D, \"Children\", InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Visual3DCollection\"));\n\t\t\tmembers[KnownMembers.MultiBinding_Bindings] = InitMember(KnownTypes.MultiBinding, \"Bindings\", InitType(assemblies[0], \"System.Collections.ObjectModel\", \"Collection`1\"));\n\t\t\tmembers[KnownMembers.MultiDataTrigger_Setters] = InitMember(KnownTypes.MultiDataTrigger, \"Setters\", InitType(assemblies[4], \"System.Windows\", \"SetterBaseCollection\"));\n\t\t\tmembers[KnownMembers.MultiTrigger_Setters] = InitMember(KnownTypes.MultiTrigger, \"Setters\", InitType(assemblies[4], \"System.Windows\", \"SetterBaseCollection\"));\n\t\t\tmembers[KnownMembers.ObjectAnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.ObjectAnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"ObjectKeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.PageContent_Child] = InitMember(KnownTypes.PageContent, \"Child\", InitType(assemblies[4], \"System.Windows.Documents\", \"FixedPage\"));\n\t\t\tmembers[KnownMembers.PageFunctionBase_Content] = InitMember(KnownTypes.PageFunctionBase, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.Panel_Children] = InitMember(KnownTypes.Panel, \"Children\", InitType(assemblies[4], \"System.Windows.Controls\", \"UIElementCollection\"));\n\t\t\tmembers[KnownMembers.Paragraph_Inlines] = InitMember(KnownTypes.Paragraph, \"Inlines\", InitType(assemblies[4], \"System.Windows.Documents\", \"InlineCollection\"));\n\t\t\tmembers[KnownMembers.ParallelTimeline_Children] = InitMember(KnownTypes.ParallelTimeline, \"Children\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"TimelineCollection\"));\n\t\t\tmembers[KnownMembers.Point3DAnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.Point3DAnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Point3DKeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.PointAnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.PointAnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"PointKeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.PriorityBinding_Bindings] = InitMember(KnownTypes.PriorityBinding, \"Bindings\", InitType(assemblies[0], \"System.Collections.ObjectModel\", \"Collection`1\"));\n\t\t\tmembers[KnownMembers.QuaternionAnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.QuaternionAnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"QuaternionKeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.RadialGradientBrush_GradientStops] = InitMember(KnownTypes.RadialGradientBrush, \"GradientStops\", InitType(assemblies[3], \"System.Windows.Media\", \"GradientStopCollection\"));\n\t\t\tmembers[KnownMembers.RadioButton_Content] = InitMember(KnownTypes.RadioButton, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.RectAnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.RectAnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"RectKeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.RepeatButton_Content] = InitMember(KnownTypes.RepeatButton, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.RichTextBox_Document] = InitMember(KnownTypes.RichTextBox, \"Document\", InitType(assemblies[4], \"System.Windows.Documents\", \"FlowDocument\"));\n\t\t\tmembers[KnownMembers.Rotation3DAnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.Rotation3DAnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Rotation3DKeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.Run_Text] = InitMember(KnownTypes.Run, \"Text\", InitType(assemblies[0], \"System\", \"String\"));\n\t\t\tmembers[KnownMembers.ScrollViewer_Content] = InitMember(KnownTypes.ScrollViewer, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.Section_Blocks] = InitMember(KnownTypes.Section, \"Blocks\", InitType(assemblies[4], \"System.Windows.Documents\", \"BlockCollection\"));\n\t\t\tmembers[KnownMembers.Selector_Items] = InitMember(KnownTypes.Selector, \"Items\", InitType(assemblies[4], \"System.Windows.Controls\", \"ItemCollection\"));\n\t\t\tmembers[KnownMembers.SingleAnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.SingleAnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SingleKeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.SizeAnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.SizeAnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"SizeKeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.Span_Inlines] = InitMember(KnownTypes.Span, \"Inlines\", InitType(assemblies[4], \"System.Windows.Documents\", \"InlineCollection\"));\n\t\t\tmembers[KnownMembers.StackPanel_Children] = InitMember(KnownTypes.StackPanel, \"Children\", InitType(assemblies[4], \"System.Windows.Controls\", \"UIElementCollection\"));\n\t\t\tmembers[KnownMembers.StatusBar_Items] = InitMember(KnownTypes.StatusBar, \"Items\", InitType(assemblies[4], \"System.Windows.Controls\", \"ItemCollection\"));\n\t\t\tmembers[KnownMembers.StatusBarItem_Content] = InitMember(KnownTypes.StatusBarItem, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.Storyboard_Children] = InitMember(KnownTypes.Storyboard, \"Children\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"TimelineCollection\"));\n\t\t\tmembers[KnownMembers.StringAnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.StringAnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"StringKeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.Style_Setters] = InitMember(KnownTypes.Style, \"Setters\", InitType(assemblies[4], \"System.Windows\", \"SetterBaseCollection\"));\n\t\t\tmembers[KnownMembers.TabControl_Items] = InitMember(KnownTypes.TabControl, \"Items\", InitType(assemblies[4], \"System.Windows.Controls\", \"ItemCollection\"));\n\t\t\tmembers[KnownMembers.TabItem_Content] = InitMember(KnownTypes.TabItem, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.TabPanel_Children] = InitMember(KnownTypes.TabPanel, \"Children\", InitType(assemblies[4], \"System.Windows.Controls\", \"UIElementCollection\"));\n\t\t\tmembers[KnownMembers.Table_RowGroups] = InitMember(KnownTypes.Table, \"RowGroups\", InitType(assemblies[4], \"System.Windows.Documents\", \"TableRowGroupCollection\"));\n\t\t\tmembers[KnownMembers.TableCell_Blocks] = InitMember(KnownTypes.TableCell, \"Blocks\", InitType(assemblies[4], \"System.Windows.Documents\", \"BlockCollection\"));\n\t\t\tmembers[KnownMembers.TableRow_Cells] = InitMember(KnownTypes.TableRow, \"Cells\", InitType(assemblies[4], \"System.Windows.Documents\", \"TableCellCollection\"));\n\t\t\tmembers[KnownMembers.TableRowGroup_Rows] = InitMember(KnownTypes.TableRowGroup, \"Rows\", InitType(assemblies[4], \"System.Windows.Documents\", \"TableRowCollection\"));\n\t\t\tmembers[KnownMembers.TextBlock_Inlines] = InitMember(KnownTypes.TextBlock, \"Inlines\", InitType(assemblies[4], \"System.Windows.Documents\", \"InlineCollection\"));\n\t\t\tmembers[KnownMembers.ThicknessAnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.ThicknessAnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[4], \"System.Windows.Media.Animation\", \"ThicknessKeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.ToggleButton_Content] = InitMember(KnownTypes.ToggleButton, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.ToolBar_Items] = InitMember(KnownTypes.ToolBar, \"Items\", InitType(assemblies[4], \"System.Windows.Controls\", \"ItemCollection\"));\n\t\t\tmembers[KnownMembers.ToolBarOverflowPanel_Children] = InitMember(KnownTypes.ToolBarOverflowPanel, \"Children\", InitType(assemblies[4], \"System.Windows.Controls\", \"UIElementCollection\"));\n\t\t\tmembers[KnownMembers.ToolBarPanel_Children] = InitMember(KnownTypes.ToolBarPanel, \"Children\", InitType(assemblies[4], \"System.Windows.Controls\", \"UIElementCollection\"));\n\t\t\tmembers[KnownMembers.ToolBarTray_ToolBars] = InitMember(KnownTypes.ToolBarTray, \"ToolBars\", InitType(assemblies[0], \"System.Collections.ObjectModel\", \"Collection`1\"));\n\t\t\tmembers[KnownMembers.ToolTip_Content] = InitMember(KnownTypes.ToolTip, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.TreeView_Items] = InitMember(KnownTypes.TreeView, \"Items\", InitType(assemblies[4], \"System.Windows.Controls\", \"ItemCollection\"));\n\t\t\tmembers[KnownMembers.TreeViewItem_Items] = InitMember(KnownTypes.TreeViewItem, \"Items\", InitType(assemblies[4], \"System.Windows.Controls\", \"ItemCollection\"));\n\t\t\tmembers[KnownMembers.Trigger_Setters] = InitMember(KnownTypes.Trigger, \"Setters\", InitType(assemblies[4], \"System.Windows\", \"SetterBaseCollection\"));\n\t\t\tmembers[KnownMembers.Underline_Inlines] = InitMember(KnownTypes.Underline, \"Inlines\", InitType(assemblies[4], \"System.Windows.Documents\", \"InlineCollection\"));\n\t\t\tmembers[KnownMembers.UniformGrid_Children] = InitMember(KnownTypes.UniformGrid, \"Children\", InitType(assemblies[4], \"System.Windows.Controls\", \"UIElementCollection\"));\n\t\t\tmembers[KnownMembers.UserControl_Content] = InitMember(KnownTypes.UserControl, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.Vector3DAnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.Vector3DAnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"Vector3DKeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.VectorAnimationUsingKeyFrames_KeyFrames] = InitMember(KnownTypes.VectorAnimationUsingKeyFrames, \"KeyFrames\", InitType(assemblies[3], \"System.Windows.Media.Animation\", \"VectorKeyFrameCollection\"));\n\t\t\tmembers[KnownMembers.Viewbox_Child] = InitMember(KnownTypes.Viewbox, \"Child\", InitType(assemblies[3], \"System.Windows\", \"UIElement\"));\n\t\t\tmembers[KnownMembers.Viewport3DVisual_Children] = InitMember(KnownTypes.Viewport3DVisual, \"Children\", InitType(assemblies[3], \"System.Windows.Media.Media3D\", \"Visual3DCollection\"));\n\t\t\tmembers[KnownMembers.VirtualizingPanel_Children] = InitMember(KnownTypes.VirtualizingPanel, \"Children\", InitType(assemblies[4], \"System.Windows.Controls\", \"UIElementCollection\"));\n\t\t\tmembers[KnownMembers.VirtualizingStackPanel_Children] = InitMember(KnownTypes.VirtualizingStackPanel, \"Children\", InitType(assemblies[4], \"System.Windows.Controls\", \"UIElementCollection\"));\n\t\t\tmembers[KnownMembers.Window_Content] = InitMember(KnownTypes.Window, \"Content\", InitType(assemblies[0], \"System\", \"Object\"));\n\t\t\tmembers[KnownMembers.WrapPanel_Children] = InitMember(KnownTypes.WrapPanel, \"Children\", InitType(assemblies[4], \"System.Windows.Controls\", \"UIElementCollection\"));\n\t\t\tmembers[KnownMembers.XmlDataProvider_XmlSerializer] = InitMember(KnownTypes.XmlDataProvider, \"XmlSerializer\", InitType(assemblies[5], \"System.Xml.Serialization\", \"IXmlSerializable\"));\n\t\t}\n\n\t\tvoid InitStrings()\n\t\t{\n\t\t\tstrings[1] = \"Name\";\n\t\t\tstrings[2] = \"Uid\";\n\t\t}\n\n\t\tvoid InitResources()\n\t\t{\n\t\t\tresources[1] = (\"SystemColors\", \"ActiveBorderBrushKey\", \"ActiveBorderBrush\");\n\t\t\tresources[2] = (\"SystemColors\", \"ActiveCaptionBrushKey\", \"ActiveCaptionBrush\");\n\t\t\tresources[3] = (\"SystemColors\", \"ActiveCaptionTextBrushKey\", \"ActiveCaptionTextBrush\");\n\t\t\tresources[4] = (\"SystemColors\", \"AppWorkspaceBrushKey\", \"AppWorkspaceBrush\");\n\t\t\tresources[5] = (\"SystemColors\", \"ControlBrushKey\", \"ControlBrush\");\n\t\t\tresources[6] = (\"SystemColors\", \"ControlDarkBrushKey\", \"ControlDarkBrush\");\n\t\t\tresources[7] = (\"SystemColors\", \"ControlDarkDarkBrushKey\", \"ControlDarkDarkBrush\");\n\t\t\tresources[8] = (\"SystemColors\", \"ControlLightBrushKey\", \"ControlLightBrush\");\n\t\t\tresources[9] = (\"SystemColors\", \"ControlLightLightBrushKey\", \"ControlLightLightBrush\");\n\t\t\tresources[10] = (\"SystemColors\", \"ControlTextBrushKey\", \"ControlTextBrush\");\n\t\t\tresources[11] = (\"SystemColors\", \"DesktopBrushKey\", \"DesktopBrush\");\n\t\t\tresources[12] = (\"SystemColors\", \"GradientActiveCaptionBrushKey\", \"GradientActiveCaptionBrush\");\n\t\t\tresources[13] = (\"SystemColors\", \"GradientInactiveCaptionBrushKey\", \"GradientInactiveCaptionBrush\");\n\t\t\tresources[14] = (\"SystemColors\", \"GrayTextBrushKey\", \"GrayTextBrush\");\n\t\t\tresources[15] = (\"SystemColors\", \"HighlightBrushKey\", \"HighlightBrush\");\n\t\t\tresources[16] = (\"SystemColors\", \"HighlightTextBrushKey\", \"HighlightTextBrush\");\n\t\t\tresources[17] = (\"SystemColors\", \"HotTrackBrushKey\", \"HotTrackBrush\");\n\t\t\tresources[18] = (\"SystemColors\", \"InactiveBorderBrushKey\", \"InactiveBorderBrush\");\n\t\t\tresources[19] = (\"SystemColors\", \"InactiveCaptionBrushKey\", \"InactiveCaptionBrush\");\n\t\t\tresources[20] = (\"SystemColors\", \"InactiveCaptionTextBrushKey\", \"InactiveCaptionTextBrush\");\n\t\t\tresources[21] = (\"SystemColors\", \"InfoBrushKey\", \"InfoBrush\");\n\t\t\tresources[22] = (\"SystemColors\", \"InfoTextBrushKey\", \"InfoTextBrush\");\n\t\t\tresources[23] = (\"SystemColors\", \"MenuBrushKey\", \"MenuBrush\");\n\t\t\tresources[24] = (\"SystemColors\", \"MenuBarBrushKey\", \"MenuBarBrush\");\n\t\t\tresources[25] = (\"SystemColors\", \"MenuHighlightBrushKey\", \"MenuHighlightBrush\");\n\t\t\tresources[26] = (\"SystemColors\", \"MenuTextBrushKey\", \"MenuTextBrush\");\n\t\t\tresources[27] = (\"SystemColors\", \"ScrollBarBrushKey\", \"ScrollBarBrush\");\n\t\t\tresources[28] = (\"SystemColors\", \"WindowBrushKey\", \"WindowBrush\");\n\t\t\tresources[29] = (\"SystemColors\", \"WindowFrameBrushKey\", \"WindowFrameBrush\");\n\t\t\tresources[30] = (\"SystemColors\", \"WindowTextBrushKey\", \"WindowTextBrush\");\n\t\t\tresources[31] = (\"SystemColors\", \"ActiveBorderColorKey\", \"ActiveBorderColor\");\n\t\t\tresources[32] = (\"SystemColors\", \"ActiveCaptionColorKey\", \"ActiveCaptionColor\");\n\t\t\tresources[33] = (\"SystemColors\", \"ActiveCaptionTextColorKey\", \"ActiveCaptionTextColor\");\n\t\t\tresources[34] = (\"SystemColors\", \"AppWorkspaceColorKey\", \"AppWorkspaceColor\");\n\t\t\tresources[35] = (\"SystemColors\", \"ControlColorKey\", \"ControlColor\");\n\t\t\tresources[36] = (\"SystemColors\", \"ControlDarkColorKey\", \"ControlDarkColor\");\n\t\t\tresources[37] = (\"SystemColors\", \"ControlDarkDarkColorKey\", \"ControlDarkDarkColor\");\n\t\t\tresources[38] = (\"SystemColors\", \"ControlLightColorKey\", \"ControlLightColor\");\n\t\t\tresources[39] = (\"SystemColors\", \"ControlLightLightColorKey\", \"ControlLightLightColor\");\n\t\t\tresources[40] = (\"SystemColors\", \"ControlTextColorKey\", \"ControlTextColor\");\n\t\t\tresources[41] = (\"SystemColors\", \"DesktopColorKey\", \"DesktopColor\");\n\t\t\tresources[42] = (\"SystemColors\", \"GradientActiveCaptionColorKey\", \"GradientActiveCaptionColor\");\n\t\t\tresources[43] = (\"SystemColors\", \"GradientInactiveCaptionColorKey\", \"GradientInactiveCaptionColor\");\n\t\t\tresources[44] = (\"SystemColors\", \"GrayTextColorKey\", \"GrayTextColor\");\n\t\t\tresources[45] = (\"SystemColors\", \"HighlightColorKey\", \"HighlightColor\");\n\t\t\tresources[46] = (\"SystemColors\", \"HighlightTextColorKey\", \"HighlightTextColor\");\n\t\t\tresources[47] = (\"SystemColors\", \"HotTrackColorKey\", \"HotTrackColor\");\n\t\t\tresources[48] = (\"SystemColors\", \"InactiveBorderColorKey\", \"InactiveBorderColor\");\n\t\t\tresources[49] = (\"SystemColors\", \"InactiveCaptionColorKey\", \"InactiveCaptionColor\");\n\t\t\tresources[50] = (\"SystemColors\", \"InactiveCaptionTextColorKey\", \"InactiveCaptionTextColor\");\n\t\t\tresources[51] = (\"SystemColors\", \"InfoColorKey\", \"InfoColor\");\n\t\t\tresources[52] = (\"SystemColors\", \"InfoTextColorKey\", \"InfoTextColor\");\n\t\t\tresources[53] = (\"SystemColors\", \"MenuColorKey\", \"MenuColor\");\n\t\t\tresources[54] = (\"SystemColors\", \"MenuBarColorKey\", \"MenuBarColor\");\n\t\t\tresources[55] = (\"SystemColors\", \"MenuHighlightColorKey\", \"MenuHighlightColor\");\n\t\t\tresources[56] = (\"SystemColors\", \"MenuTextColorKey\", \"MenuTextColor\");\n\t\t\tresources[57] = (\"SystemColors\", \"ScrollBarColorKey\", \"ScrollBarColor\");\n\t\t\tresources[58] = (\"SystemColors\", \"WindowColorKey\", \"WindowColor\");\n\t\t\tresources[59] = (\"SystemColors\", \"WindowFrameColorKey\", \"WindowFrameColor\");\n\t\t\tresources[60] = (\"SystemColors\", \"WindowTextColorKey\", \"WindowTextColor\");\n\n\t\t\tresources[63] = (\"SystemFonts\", \"CaptionFontSizeKey\", \"CaptionFontSize\");\n\t\t\tresources[64] = (\"SystemFonts\", \"CaptionFontFamilyKey\", \"CaptionFontFamily\");\n\t\t\tresources[65] = (\"SystemFonts\", \"CaptionFontStyleKey\", \"CaptionFontStyle\");\n\t\t\tresources[66] = (\"SystemFonts\", \"CaptionFontWeightKey\", \"CaptionFontWeight\");\n\t\t\tresources[67] = (\"SystemFonts\", \"CaptionFontTextDecorationsKey\", \"CaptionFontTextDecorations\");\n\t\t\tresources[68] = (\"SystemFonts\", \"SmallCaptionFontSizeKey\", \"SmallCaptionFontSize\");\n\t\t\tresources[69] = (\"SystemFonts\", \"SmallCaptionFontFamilyKey\", \"SmallCaptionFontFamily\");\n\t\t\tresources[70] = (\"SystemFonts\", \"SmallCaptionFontStyleKey\", \"SmallCaptionFontStyle\");\n\t\t\tresources[71] = (\"SystemFonts\", \"SmallCaptionFontWeightKey\", \"SmallCaptionFontWeight\");\n\t\t\tresources[72] = (\"SystemFonts\", \"SmallCaptionFontTextDecorationsKey\", \"SmallCaptionFontTextDecorations\");\n\t\t\tresources[73] = (\"SystemFonts\", \"MenuFontSizeKey\", \"MenuFontSize\");\n\t\t\tresources[74] = (\"SystemFonts\", \"MenuFontFamilyKey\", \"MenuFontFamily\");\n\t\t\tresources[75] = (\"SystemFonts\", \"MenuFontStyleKey\", \"MenuFontStyle\");\n\t\t\tresources[76] = (\"SystemFonts\", \"MenuFontWeightKey\", \"MenuFontWeight\");\n\t\t\tresources[77] = (\"SystemFonts\", \"MenuFontTextDecorationsKey\", \"MenuFontTextDecorations\");\n\t\t\tresources[78] = (\"SystemFonts\", \"StatusFontSizeKey\", \"StatusFontSize\");\n\t\t\tresources[79] = (\"SystemFonts\", \"StatusFontFamilyKey\", \"StatusFontFamily\");\n\t\t\tresources[80] = (\"SystemFonts\", \"StatusFontStyleKey\", \"StatusFontStyle\");\n\t\t\tresources[81] = (\"SystemFonts\", \"StatusFontWeightKey\", \"StatusFontWeight\");\n\t\t\tresources[82] = (\"SystemFonts\", \"StatusFontTextDecorationsKey\", \"StatusFontTextDecorations\");\n\t\t\tresources[83] = (\"SystemFonts\", \"MessageFontSizeKey\", \"MessageFontSize\");\n\t\t\tresources[84] = (\"SystemFonts\", \"MessageFontFamilyKey\", \"MessageFontFamily\");\n\t\t\tresources[85] = (\"SystemFonts\", \"MessageFontStyleKey\", \"MessageFontStyle\");\n\t\t\tresources[86] = (\"SystemFonts\", \"MessageFontWeightKey\", \"MessageFontWeight\");\n\t\t\tresources[87] = (\"SystemFonts\", \"MessageFontTextDecorationsKey\", \"MessageFontTextDecorations\");\n\t\t\tresources[88] = (\"SystemFonts\", \"IconFontSizeKey\", \"IconFontSize\");\n\t\t\tresources[89] = (\"SystemFonts\", \"IconFontFamilyKey\", \"IconFontFamily\");\n\t\t\tresources[90] = (\"SystemFonts\", \"IconFontStyleKey\", \"IconFontStyle\");\n\t\t\tresources[91] = (\"SystemFonts\", \"IconFontWeightKey\", \"IconFontWeight\");\n\t\t\tresources[92] = (\"SystemFonts\", \"IconFontTextDecorationsKey\", \"IconFontTextDecorations\");\n\n\t\t\tresources[95] = (\"SystemParameters\", \"ThinHorizontalBorderHeightKey\", \"ThinHorizontalBorderHeight\");\n\t\t\tresources[96] = (\"SystemParameters\", \"ThinVerticalBorderWidthKey\", \"ThinVerticalBorderWidth\");\n\t\t\tresources[97] = (\"SystemParameters\", \"CursorWidthKey\", \"CursorWidth\");\n\t\t\tresources[98] = (\"SystemParameters\", \"CursorHeightKey\", \"CursorHeight\");\n\t\t\tresources[99] = (\"SystemParameters\", \"ThickHorizontalBorderHeightKey\", \"ThickHorizontalBorderHeight\");\n\t\t\tresources[100] = (\"SystemParameters\", \"ThickVerticalBorderWidthKey\", \"ThickVerticalBorderWidth\");\n\t\t\tresources[101] = (\"SystemParameters\", \"FixedFrameHorizontalBorderHeightKey\", \"FixedFrameHorizontalBorderHeight\");\n\t\t\tresources[102] = (\"SystemParameters\", \"FixedFrameVerticalBorderWidthKey\", \"FixedFrameVerticalBorderWidth\");\n\t\t\tresources[103] = (\"SystemParameters\", \"FocusHorizontalBorderHeightKey\", \"FocusHorizontalBorderHeight\");\n\t\t\tresources[104] = (\"SystemParameters\", \"FocusVerticalBorderWidthKey\", \"FocusVerticalBorderWidth\");\n\t\t\tresources[105] = (\"SystemParameters\", \"FullPrimaryScreenWidthKey\", \"FullPrimaryScreenWidth\");\n\t\t\tresources[106] = (\"SystemParameters\", \"FullPrimaryScreenHeightKey\", \"FullPrimaryScreenHeight\");\n\t\t\tresources[107] = (\"SystemParameters\", \"HorizontalScrollBarButtonWidthKey\", \"HorizontalScrollBarButtonWidth\");\n\t\t\tresources[108] = (\"SystemParameters\", \"HorizontalScrollBarHeightKey\", \"HorizontalScrollBarHeight\");\n\t\t\tresources[109] = (\"SystemParameters\", \"HorizontalScrollBarThumbWidthKey\", \"HorizontalScrollBarThumbWidth\");\n\t\t\tresources[110] = (\"SystemParameters\", \"IconWidthKey\", \"IconWidth\");\n\t\t\tresources[111] = (\"SystemParameters\", \"IconHeightKey\", \"IconHeight\");\n\t\t\tresources[112] = (\"SystemParameters\", \"IconGridWidthKey\", \"IconGridWidth\");\n\t\t\tresources[113] = (\"SystemParameters\", \"IconGridHeightKey\", \"IconGridHeight\");\n\t\t\tresources[114] = (\"SystemParameters\", \"MaximizedPrimaryScreenWidthKey\", \"MaximizedPrimaryScreenWidth\");\n\t\t\tresources[115] = (\"SystemParameters\", \"MaximizedPrimaryScreenHeightKey\", \"MaximizedPrimaryScreenHeight\");\n\t\t\tresources[116] = (\"SystemParameters\", \"MaximumWindowTrackWidthKey\", \"MaximumWindowTrackWidth\");\n\t\t\tresources[117] = (\"SystemParameters\", \"MaximumWindowTrackHeightKey\", \"MaximumWindowTrackHeight\");\n\t\t\tresources[118] = (\"SystemParameters\", \"MenuCheckmarkWidthKey\", \"MenuCheckmarkWidth\");\n\t\t\tresources[119] = (\"SystemParameters\", \"MenuCheckmarkHeightKey\", \"MenuCheckmarkHeight\");\n\t\t\tresources[120] = (\"SystemParameters\", \"MenuButtonWidthKey\", \"MenuButtonWidth\");\n\t\t\tresources[121] = (\"SystemParameters\", \"MenuButtonHeightKey\", \"MenuButtonHeight\");\n\t\t\tresources[122] = (\"SystemParameters\", \"MinimumWindowWidthKey\", \"MinimumWindowWidth\");\n\t\t\tresources[123] = (\"SystemParameters\", \"MinimumWindowHeightKey\", \"MinimumWindowHeight\");\n\t\t\tresources[124] = (\"SystemParameters\", \"MinimizedWindowWidthKey\", \"MinimizedWindowWidth\");\n\t\t\tresources[125] = (\"SystemParameters\", \"MinimizedWindowHeightKey\", \"MinimizedWindowHeight\");\n\t\t\tresources[126] = (\"SystemParameters\", \"MinimizedGridWidthKey\", \"MinimizedGridWidth\");\n\t\t\tresources[127] = (\"SystemParameters\", \"MinimizedGridHeightKey\", \"MinimizedGridHeight\");\n\t\t\tresources[128] = (\"SystemParameters\", \"MinimumWindowTrackWidthKey\", \"MinimumWindowTrackWidth\");\n\t\t\tresources[129] = (\"SystemParameters\", \"MinimumWindowTrackHeightKey\", \"MinimumWindowTrackHeight\");\n\t\t\tresources[130] = (\"SystemParameters\", \"PrimaryScreenWidthKey\", \"PrimaryScreenWidth\");\n\t\t\tresources[131] = (\"SystemParameters\", \"PrimaryScreenHeightKey\", \"PrimaryScreenHeight\");\n\t\t\tresources[132] = (\"SystemParameters\", \"WindowCaptionButtonWidthKey\", \"WindowCaptionButtonWidth\");\n\t\t\tresources[133] = (\"SystemParameters\", \"WindowCaptionButtonHeightKey\", \"WindowCaptionButtonHeight\");\n\t\t\tresources[134] = (\"SystemParameters\", \"ResizeFrameHorizontalBorderHeightKey\", \"ResizeFrameHorizontalBorderHeight\");\n\t\t\tresources[135] = (\"SystemParameters\", \"ResizeFrameVerticalBorderWidthKey\", \"ResizeFrameVerticalBorderWidth\");\n\t\t\tresources[136] = (\"SystemParameters\", \"SmallIconWidthKey\", \"SmallIconWidth\");\n\t\t\tresources[137] = (\"SystemParameters\", \"SmallIconHeightKey\", \"SmallIconHeight\");\n\t\t\tresources[138] = (\"SystemParameters\", \"SmallWindowCaptionButtonWidthKey\", \"SmallWindowCaptionButtonWidth\");\n\t\t\tresources[139] = (\"SystemParameters\", \"SmallWindowCaptionButtonHeightKey\", \"SmallWindowCaptionButtonHeight\");\n\t\t\tresources[140] = (\"SystemParameters\", \"VirtualScreenWidthKey\", \"VirtualScreenWidth\");\n\t\t\tresources[141] = (\"SystemParameters\", \"VirtualScreenHeightKey\", \"VirtualScreenHeight\");\n\t\t\tresources[142] = (\"SystemParameters\", \"VerticalScrollBarWidthKey\", \"VerticalScrollBarWidth\");\n\t\t\tresources[143] = (\"SystemParameters\", \"VerticalScrollBarButtonHeightKey\", \"VerticalScrollBarButtonHeight\");\n\t\t\tresources[144] = (\"SystemParameters\", \"WindowCaptionHeightKey\", \"WindowCaptionHeight\");\n\t\t\tresources[145] = (\"SystemParameters\", \"KanjiWindowHeightKey\", \"KanjiWindowHeight\");\n\t\t\tresources[146] = (\"SystemParameters\", \"MenuBarHeightKey\", \"MenuBarHeight\");\n\t\t\tresources[147] = (\"SystemParameters\", \"SmallCaptionHeightKey\", \"SmallCaptionHeight\");\n\t\t\tresources[148] = (\"SystemParameters\", \"VerticalScrollBarThumbHeightKey\", \"VerticalScrollBarThumbHeight\");\n\t\t\tresources[149] = (\"SystemParameters\", \"IsImmEnabledKey\", \"IsImmEnabled\");\n\t\t\tresources[150] = (\"SystemParameters\", \"IsMediaCenterKey\", \"IsMediaCenter\");\n\t\t\tresources[151] = (\"SystemParameters\", \"IsMenuDropRightAlignedKey\", \"IsMenuDropRightAligned\");\n\t\t\tresources[152] = (\"SystemParameters\", \"IsMiddleEastEnabledKey\", \"IsMiddleEastEnabled\");\n\t\t\tresources[153] = (\"SystemParameters\", \"IsMousePresentKey\", \"IsMousePresent\");\n\t\t\tresources[154] = (\"SystemParameters\", \"IsMouseWheelPresentKey\", \"IsMouseWheelPresent\");\n\t\t\tresources[155] = (\"SystemParameters\", \"IsPenWindowsKey\", \"IsPenWindows\");\n\t\t\tresources[156] = (\"SystemParameters\", \"IsRemotelyControlledKey\", \"IsRemotelyControlled\");\n\t\t\tresources[157] = (\"SystemParameters\", \"IsRemoteSessionKey\", \"IsRemoteSession\");\n\t\t\tresources[158] = (\"SystemParameters\", \"ShowSoundsKey\", \"ShowSounds\");\n\t\t\tresources[159] = (\"SystemParameters\", \"IsSlowMachineKey\", \"IsSlowMachine\");\n\t\t\tresources[160] = (\"SystemParameters\", \"SwapButtonsKey\", \"SwapButtons\");\n\t\t\tresources[161] = (\"SystemParameters\", \"IsTabletPCKey\", \"IsTabletPC\");\n\t\t\tresources[162] = (\"SystemParameters\", \"VirtualScreenLeftKey\", \"VirtualScreenLeft\");\n\t\t\tresources[163] = (\"SystemParameters\", \"VirtualScreenTopKey\", \"VirtualScreenTop\");\n\t\t\tresources[164] = (\"SystemParameters\", \"FocusBorderWidthKey\", \"FocusBorderWidth\");\n\t\t\tresources[165] = (\"SystemParameters\", \"FocusBorderHeightKey\", \"FocusBorderHeight\");\n\t\t\tresources[166] = (\"SystemParameters\", \"HighContrastKey\", \"HighContrast\");\n\t\t\tresources[167] = (\"SystemParameters\", \"DropShadowKey\", \"DropShadow\");\n\t\t\tresources[168] = (\"SystemParameters\", \"FlatMenuKey\", \"FlatMenu\");\n\t\t\tresources[169] = (\"SystemParameters\", \"WorkAreaKey\", \"WorkArea\");\n\t\t\tresources[170] = (\"SystemParameters\", \"IconHorizontalSpacingKey\", \"IconHorizontalSpacing\");\n\t\t\tresources[171] = (\"SystemParameters\", \"IconVerticalSpacingKey\", \"IconVerticalSpacing\");\n\t\t\tresources[172] = (\"SystemParameters\", \"IconTitleWrapKey\", \"IconTitleWrap\");\n\t\t\tresources[173] = (\"SystemParameters\", \"KeyboardCuesKey\", \"KeyboardCues\");\n\t\t\tresources[174] = (\"SystemParameters\", \"KeyboardDelayKey\", \"KeyboardDelay\");\n\t\t\tresources[175] = (\"SystemParameters\", \"KeyboardPreferenceKey\", \"KeyboardPreference\");\n\t\t\tresources[176] = (\"SystemParameters\", \"KeyboardSpeedKey\", \"KeyboardSpeed\");\n\t\t\tresources[177] = (\"SystemParameters\", \"SnapToDefaultButtonKey\", \"SnapToDefaultButton\");\n\t\t\tresources[178] = (\"SystemParameters\", \"WheelScrollLinesKey\", \"WheelScrollLines\");\n\t\t\tresources[179] = (\"SystemParameters\", \"MouseHoverTimeKey\", \"MouseHoverTime\");\n\t\t\tresources[180] = (\"SystemParameters\", \"MouseHoverHeightKey\", \"MouseHoverHeight\");\n\t\t\tresources[181] = (\"SystemParameters\", \"MouseHoverWidthKey\", \"MouseHoverWidth\");\n\t\t\tresources[182] = (\"SystemParameters\", \"MenuDropAlignmentKey\", \"MenuDropAlignment\");\n\t\t\tresources[183] = (\"SystemParameters\", \"MenuFadeKey\", \"MenuFade\");\n\t\t\tresources[184] = (\"SystemParameters\", \"MenuShowDelayKey\", \"MenuShowDelay\");\n\t\t\tresources[185] = (\"SystemParameters\", \"ComboBoxAnimationKey\", \"ComboBoxAnimation\");\n\t\t\tresources[186] = (\"SystemParameters\", \"ClientAreaAnimationKey\", \"ClientAreaAnimation\");\n\t\t\tresources[187] = (\"SystemParameters\", \"CursorShadowKey\", \"CursorShadow\");\n\t\t\tresources[188] = (\"SystemParameters\", \"GradientCaptionsKey\", \"GradientCaptions\");\n\t\t\tresources[189] = (\"SystemParameters\", \"HotTrackingKey\", \"HotTracking\");\n\t\t\tresources[190] = (\"SystemParameters\", \"ListBoxSmoothScrollingKey\", \"ListBoxSmoothScrolling\");\n\t\t\tresources[191] = (\"SystemParameters\", \"MenuAnimationKey\", \"MenuAnimation\");\n\t\t\tresources[192] = (\"SystemParameters\", \"SelectionFadeKey\", \"SelectionFade\");\n\t\t\tresources[193] = (\"SystemParameters\", \"StylusHotTrackingKey\", \"StylusHotTracking\");\n\t\t\tresources[194] = (\"SystemParameters\", \"ToolTipAnimationKey\", \"ToolTipAnimation\");\n\t\t\tresources[195] = (\"SystemParameters\", \"ToolTipFadeKey\", \"ToolTipFade\");\n\t\t\tresources[196] = (\"SystemParameters\", \"UIEffectsKey\", \"UIEffects\");\n\t\t\tresources[197] = (\"SystemParameters\", \"MinimizeAnimationKey\", \"MinimizeAnimation\");\n\t\t\tresources[198] = (\"SystemParameters\", \"BorderKey\", \"Border\");\n\t\t\tresources[199] = (\"SystemParameters\", \"CaretWidthKey\", \"CaretWidth\");\n\t\t\tresources[200] = (\"SystemParameters\", \"ForegroundFlashCountKey\", \"ForegroundFlashCount\");\n\t\t\tresources[201] = (\"SystemParameters\", \"DragFullWindowsKey\", \"DragFullWindows\");\n\t\t\tresources[202] = (\"SystemParameters\", \"BorderWidthKey\", \"BorderWidth\");\n\t\t\tresources[203] = (\"SystemParameters\", \"ScrollWidthKey\", \"ScrollWidth\");\n\t\t\tresources[204] = (\"SystemParameters\", \"ScrollHeightKey\", \"ScrollHeight\");\n\t\t\tresources[205] = (\"SystemParameters\", \"CaptionWidthKey\", \"CaptionWidth\");\n\t\t\tresources[206] = (\"SystemParameters\", \"CaptionHeightKey\", \"CaptionHeight\");\n\t\t\tresources[207] = (\"SystemParameters\", \"SmallCaptionWidthKey\", \"SmallCaptionWidth\");\n\t\t\tresources[208] = (\"SystemParameters\", \"MenuWidthKey\", \"MenuWidth\");\n\t\t\tresources[209] = (\"SystemParameters\", \"MenuHeightKey\", \"MenuHeight\");\n\t\t\tresources[210] = (\"SystemParameters\", \"ComboBoxPopupAnimationKey\", \"ComboBoxPopupAnimation\");\n\t\t\tresources[211] = (\"SystemParameters\", \"MenuPopupAnimationKey\", \"MenuPopupAnimation\");\n\t\t\tresources[212] = (\"SystemParameters\", \"ToolTipPopupAnimationKey\", \"ToolTipPopupAnimation\");\n\t\t\tresources[213] = (\"SystemParameters\", \"PowerLineStatusKey\", \"PowerLineStatus\");\n\n\t\t\tresources[215] = (\"SystemParameters\", \"FocusVisualStyleKey\", \"FocusVisualStyle\");\n\t\t\tresources[216] = (\"SystemParameters\", \"NavigationChromeDownLevelStyleKey\", \"NavigationChromeDownLevelStyle\");\n\t\t\tresources[217] = (\"SystemParameters\", \"NavigationChromeStyleKey\", \"NavigationChromeStyle\");\n\n\t\t\tresources[219] = (\"MenuItem\", \"SeparatorStyleKey\", \"MenuItemSeparatorStyle\");\n\t\t\tresources[220] = (\"GridView\", \"GridViewScrollViewerStyleKey\", \"GridViewScrollViewerStyle\");\n\t\t\tresources[221] = (\"GridView\", \"GridViewStyleKey\", \"GridViewStyle\");\n\t\t\tresources[222] = (\"GridView\", \"GridViewItemContainerStyleKey\", \"GridViewItemContainerStyle\");\n\t\t\tresources[223] = (\"StatusBar\", \"SeparatorStyleKey\", \"StatusBarSeparatorStyle\");\n\t\t\tresources[224] = (\"ToolBar\", \"ButtonStyleKey\", \"ToolBarButtonStyle\");\n\t\t\tresources[225] = (\"ToolBar\", \"ToggleButtonStyleKey\", \"ToolBarToggleButtonStyle\");\n\t\t\tresources[226] = (\"ToolBar\", \"SeparatorStyleKey\", \"ToolBarSeparatorStyle\");\n\t\t\tresources[227] = (\"ToolBar\", \"CheckBoxStyleKey\", \"ToolBarCheckBoxStyle\");\n\t\t\tresources[228] = (\"ToolBar\", \"RadioButtonStyleKey\", \"ToolBarRadioButtonStyle\");\n\t\t\tresources[229] = (\"ToolBar\", \"ComboBoxStyleKey\", \"ToolBarComboBoxStyle\");\n\t\t\tresources[230] = (\"ToolBar\", \"TextBoxStyleKey\", \"ToolBarTextBoxStyle\");\n\t\t\tresources[231] = (\"ToolBar\", \"MenuStyleKey\", \"ToolBarMenuStyle\");\n\n\t\t\tresources[234] = (\"SystemColors\", \"InactiveSelectionHighlightBrushKey\", \"InactiveSelectionHighlightBrush\");\n\t\t\tresources[235] = (\"SystemColors\", \"InactiveSelectionHighlightTextBrushKey\", \"InactiveSelectionHighlightTextBrush\");\n\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Baml/KnownThings.gen.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Text;\n\nnamespace Test {\n\tinternal class Program {\n\t\tstatic T GetMember<T>(Func<string, BindingFlags, T> func, string name) =>\n\t\t\tfunc(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);\n\n\t\tstatic Assembly GetDeclAssembly(Type type) {\n\t\t\tif (type.IsDefined(typeof(TypeForwardedFromAttribute), false)) {\n\t\t\t\tvar attr = (TypeForwardedFromAttribute)type.GetCustomAttributes(typeof(TypeForwardedFromAttribute), false)[0];\n\t\t\t\treturn Assembly.Load(attr.AssemblyFullName);\n\t\t\t}\n\t\t\treturn type.Assembly;\n\t\t}\n\n\t\tstatic void Main(string[] args) {\n\t\t\tvar asmName = \"PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\";\n\t\t\tvar assembly = Assembly.Load(asmName);\n\t\t\tvar ctx = assembly.GetType(\"System.Windows.Baml2006.WpfSharedBamlSchemaContext\");\n\t\t\tvar instance = Activator.CreateInstance(ctx);\n\n\t\t\tvar assemblies = ExtractAssemblies(ctx, instance);\n\t\t\tvar types = ExtractTypes(ctx, instance);\n\t\t\tvar members = ExtractMembers(ctx, instance);\n\t\t\tvar strings = ExtractStrings(ctx, instance);\n\t\t\tvar resources = ExtractResources(assembly);\n\n\t\t\tvar code = new StringBuilder();\n\n\t\t\tforeach (var type in types) {\n\t\t\t\tif (type == null)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (!assemblies.Contains(GetDeclAssembly(type)))\n\t\t\t\t\tassemblies.Add(GetDeclAssembly(type));\n\t\t\t}\n\n\t\t\tforeach (var member in members) {\n\t\t\t\tif (member == null)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (!assemblies.Contains(GetDeclAssembly(member.Item3)))\n\t\t\t\t\tassemblies.Add(GetDeclAssembly(member.Item3));\n\t\t\t}\n\n\t\t\tcode.AppendLine(\"\\tinternal enum KnownTypes : short {\");\n\t\t\tcode.AppendLine(\"\\t\\tUnknown = 0,\");\n\t\t\tfor (int i = 1; i < types.Count; i++) {\n\t\t\t\tif (types[i] == null) {\n\t\t\t\t\tcode.AppendLine();\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tvar line = \"\\t\\t{0} = {1},\";\n\t\t\t\tcode.AppendLine(string.Format(line, types[i].Name, i));\n\t\t\t}\n\t\t\tcode.AppendLine(\"\\t}\").AppendLine();\n\n\t\t\tcode.AppendLine(\"\\tinternal enum KnownMembers : short {\");\n\t\t\tcode.AppendLine(\"\\t\\tUnknown = 0,\");\n\t\t\tfor (int i = 1; i < members.Count; i++) {\n\t\t\t\tif (members[i] == null) {\n\t\t\t\t\tcode.AppendLine();\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tvar line = \"\\t\\t{0}_{1} = {2},\";\n\t\t\t\tcode.AppendLine(string.Format(line, members[i].Item1.Name, members[i].Item2, i));\n\t\t\t}\n\t\t\tcode.AppendLine(\"\\t}\").AppendLine();\n\n\t\t\tcode.AppendLine(\"\\t\\tvoid InitAssemblies() {\");\n\t\t\tfor (int i = 0; i < assemblies.Count; i++) {\n\t\t\t\tvar line = \"\\t\\t\\tassemblies[{0}] = ResolveAssembly(\\\"{1}\\\");\";\n\t\t\t\tcode.AppendLine(string.Format(line, i, assemblies[i]));\n\t\t\t}\n\t\t\tcode.AppendLine(\"\\t\\t}\").AppendLine();\n\n\t\t\tcode.AppendLine(\"\\t\\tvoid InitTypes() {\");\n\t\t\tfor (int i = 0; i < types.Count; i++) {\n\t\t\t\tvar type = types[i];\n\t\t\t\tif (type == null) {\n\t\t\t\t\tcode.AppendLine();\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tvar line = \"\\t\\t\\ttypes[KnownTypes.{0}] = InitType(assemblies[{1}], \\\"{2}\\\", \\\"{3}\\\");\";\n\t\t\t\tcode.AppendLine(string.Format(line, new object[] {\n\t\t\t\t\ttype.Name,\n\t\t\t\t\tassemblies.IndexOf(GetDeclAssembly(type)),\n\t\t\t\t\ttype.Namespace,\n\t\t\t\t\ttype.Name\n\t\t\t\t}));\n\t\t\t}\n\t\t\tcode.AppendLine(\"\\t\\t}\").AppendLine();\n\n\t\t\tcode.AppendLine(\"\\t\\tvoid InitMembers() {\");\n\t\t\tfor (int i = 0; i < members.Count; i++) {\n\t\t\t\tvar member = members[i];\n\t\t\t\tif (member == null) {\n\t\t\t\t\tcode.AppendLine();\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tvar line = \"\\t\\t\\tmembers[KnownMembers.{0}_{1}] = InitMember(KnownTypes.{0}, \\\"{1}\\\", InitType(assemblies[{2}], \\\"{3}\\\", \\\"{4}\\\"));\";\n\t\t\t\tcode.AppendLine(string.Format(line, new object[] {\n\t\t\t\t\tmember.Item1.Name,\n\t\t\t\t\tmember.Item2,\n\t\t\t\t\tassemblies.IndexOf(GetDeclAssembly(member.Item3)),\n\t\t\t\t\tmember.Item3.Namespace,\n\t\t\t\t\tmember.Item3.Name\n\t\t\t\t}));\n\t\t\t}\n\t\t\tcode.AppendLine(\"\\t\\t}\").AppendLine();\n\n\t\t\tcode.AppendLine(\"\\t\\tvoid InitStrings() {\");\n\t\t\tfor (int i = 0; i < strings.Count; i++) {\n\t\t\t\tif (strings[i] == null)\n\t\t\t\t\tcontinue;\n\t\t\t\tvar line = \"\\t\\t\\tstrings[{0}] = \\\"{1}\\\";\";\n\t\t\t\tcode.AppendLine(string.Format(line, i, strings[i]));\n\t\t\t}\n\t\t\tcode.AppendLine(\"\\t\\t}\").AppendLine();\n\n\t\t\tcode.AppendLine(\"\\t\\tvoid InitResources() {\");\n\t\t\tfor (int i = 0; i < resources.Count; i++) {\n\t\t\t\tif (resources[i] == null) {\n\t\t\t\t\tcode.AppendLine();\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tvar res = resources[i];\n\t\t\t\tvar line = \"\\t\\t\\tresources[{0}] = (\\\"{1}\\\", \\\"{2}\\\", \\\"{3}\\\");\";\n\t\t\t\tcode.AppendLine(string.Format(line, i, res.Item1.Name, res.Item2, res.Item3));\n\t\t\t}\n\t\t\tcode.AppendLine(\"\\t\\t}\").AppendLine();\n\n\t\t\tConsole.WriteLine(code);\n\t\t}\n\n\t\tstatic List<Assembly> ExtractAssemblies(Type ctx, object instance) {\n\t\t\tvar getAssembly = GetMember(ctx.GetMethod, \"GetKnownBamlAssembly\");\n\t\t\tvar assemblies = (Array)GetMember(ctx.GetField, \"_knownBamlAssemblies\").GetValue(instance);\n\n\t\t\tvar bamlAssembly = ctx.Assembly.GetType(\"System.Windows.Baml2006.Baml6Assembly\");\n\t\t\tvar property = GetMember(bamlAssembly.GetProperty, \"Assembly\");\n\n\t\t\tvar extract = new List<Assembly>();\n\t\t\tfor (int i = 0; i < assemblies.Length; i++) {\n\t\t\t\ttry {\n\t\t\t\t\tvar asm = getAssembly.Invoke(instance, new object[] { (short)(-i) });\n\t\t\t\t\tvar asmValue = (Assembly)property.GetValue(asm, null);\n\t\t\t\t\textract.Add(asmValue);\n\t\t\t\t}\n\t\t\t\tcatch {\n\t\t\t\t\textract.Add(null);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn extract;\n\t\t}\n\n\t\tstatic List<Type> ExtractTypes(Type ctx, object instance) {\n\t\t\tvar getType = GetMember(ctx.GetMethod, \"GetKnownBamlType\");\n\t\t\tvar types = (Array)GetMember(ctx.GetField, \"_knownBamlTypes\").GetValue(instance);\n\n\t\t\tvar bamlType = ctx.Assembly.GetType(\"System.Windows.Baml2006.WpfKnownType\");\n\t\t\tvar field = GetMember(bamlType.GetField, \"_underlyingType\");\n\n\t\t\tvar extract = new List<Type>() { null };\n\t\t\tfor (int i = 1; i < types.Length; i++) {\n\t\t\t\ttry {\n\t\t\t\t\tvar type = getType.Invoke(instance, new object[] { (short)(-i) });\n\t\t\t\t\tvar typeValue = (Type)field.GetValue(type);\n\t\t\t\t\textract.Add(typeValue);\n\t\t\t\t}\n\t\t\t\tcatch {\n\t\t\t\t\textract.Add(null);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn extract;\n\t\t}\n\n\t\tstatic List<Tuple<Type, string, Type>> ExtractMembers(Type ctx, object instance) {\n\t\t\tvar getMember = GetMember(ctx.GetMethod, \"GetKnownBamlMember\");\n\t\t\tvar members = (Array)GetMember(ctx.GetField, \"_knownBamlMembers\").GetValue(instance);\n\n\t\t\tvar bamlMember = ctx.Assembly.GetType(\"System.Windows.Baml2006.WpfKnownMember\");\n\t\t\tvar propertyName = GetMember(bamlMember.GetProperty, \"Name\");\n\t\t\tvar propertyType = GetMember(bamlMember.GetProperty, \"Type\");\n\n\t\t\tvar bamlType = ctx.Assembly.GetType(\"System.Windows.Baml2006.WpfKnownType\");\n\t\t\tvar propertyUnderlyType = GetMember(bamlType.GetProperty, \"UnderlyingType\");\n\n\t\t\tvar mapTable = ctx.Assembly.GetType(\"System.Windows.Markup.BamlMapTable\");\n\t\t\tvar getAttrRecord = mapTable.GetMethod(\"GetAttributeInfoFromId\", BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(short) }, null);\n\t\t\tvar getAttrOwner = GetMember(mapTable.GetMethod, \"GetAttributeOwnerType\");\n\t\t\tvar tbl = mapTable.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)[0].Invoke(new object[] { null });\n\n\t\t\tvar extract = new List<Tuple<Type, string, Type>>() { null };\n\t\t\tfor (int i = 1; i < members.Length; i++) {\n\t\t\t\ttry {\n\t\t\t\t\tvar member = getMember.Invoke(instance, new object[] { (short)(-i) });\n\t\t\t\t\tvar name = (string)propertyName.GetValue(member, null);\n\t\t\t\t\tvar type = (Type)propertyUnderlyType.GetValue(propertyType.GetValue(member, null), null);\n\n\t\t\t\t\tvar declType = (Type)getAttrOwner.Invoke(tbl, new object[] { getAttrRecord.Invoke(tbl, new object[] { (short)(-i) }) });\n\n\t\t\t\t\textract.Add(Tuple.Create(declType, name, type));\n\t\t\t\t}\n\t\t\t\tcatch {\n\t\t\t\t\textract.Add(null);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn extract;\n\t\t}\n\n\t\tstatic List<string> ExtractStrings(Type ctx, object instance) {\n\t\t\tvar getString = GetMember(ctx.GetMethod, \"GetKnownBamlString\");\n\n\t\t\tvar extract = new List<string>();\n\t\t\tfor (int i = 0; i < 10; i++) {\n\t\t\t\ttry {\n\t\t\t\t\tvar str = (string)getString.Invoke(instance, new object[] { (short)(-i) });\n\t\t\t\t\textract.Add(str);\n\t\t\t\t}\n\t\t\t\tcatch {\n\t\t\t\t\textract.Add(null);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn extract;\n\t\t}\n\n\t\tstatic List<Tuple<Type, string, string>> ExtractResources(Assembly asm) {\n\t\t\tvar resIdType = asm.GetType(\"System.Windows.SystemResourceKeyID\");\n\t\t\tvar cvrtType = asm.GetType(\"System.Windows.Markup.SystemKeyConverter\");\n\n\t\t\tvar getSysType = GetMember(cvrtType.GetMethod, \"GetSystemClassType\");\n\t\t\tvar getSysKeyName = GetMember(cvrtType.GetMethod, \"GetSystemKeyName\");\n\t\t\tvar getSysPropertyName = GetMember(cvrtType.GetMethod, \"GetSystemPropertyName\");\n\n\t\t\tvar values = Enum.GetValues(resIdType);\n\n\t\t\tvar extract = new List<Tuple<Type, string, string>>();\n\t\t\tfor (int i = 0; i < values.Length; i++) {\n\t\t\t\tvar value = values.GetValue(i);\n\t\t\t\tif (Enum.GetName(resIdType, value).StartsWith(\"Internal\")) {\n\t\t\t\t\textract.Add(null);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tvar type = (Type)getSysType.Invoke(null, new object[] { value });\n\t\t\t\tvar keyName = (string)getSysKeyName.Invoke(null, new object[] { value });\n\t\t\t\tvar propName = (string)getSysPropertyName.Invoke(null, new object[] { value });\n\t\t\t\textract.Add(Tuple.Create(type, keyName, propName));\n\t\t\t}\n\t\t\treturn extract;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Baml/KnownTypes.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nnamespace ICSharpCode.BamlDecompiler.Baml\n{\n\t// Auto generated. Do not modify.\n\n\tinternal enum KnownTypes : short\n\t{\n\t\tUnknown = 0,\n\t\tAccessText = 1,\n\t\tAdornedElementPlaceholder = 2,\n\t\tAdorner = 3,\n\t\tAdornerDecorator = 4,\n\t\tAdornerLayer = 5,\n\t\tAffineTransform3D = 6,\n\t\tAmbientLight = 7,\n\t\tAnchoredBlock = 8,\n\t\tAnimatable = 9,\n\t\tAnimationClock = 10,\n\t\tAnimationTimeline = 11,\n\t\tApplication = 12,\n\t\tArcSegment = 13,\n\t\tArrayExtension = 14,\n\t\tAxisAngleRotation3D = 15,\n\t\tBaseIListConverter = 16,\n\t\tBeginStoryboard = 17,\n\t\tBevelBitmapEffect = 18,\n\t\tBezierSegment = 19,\n\t\tBinding = 20,\n\t\tBindingBase = 21,\n\t\tBindingExpression = 22,\n\t\tBindingExpressionBase = 23,\n\t\tBindingListCollectionView = 24,\n\t\tBitmapDecoder = 25,\n\t\tBitmapEffect = 26,\n\t\tBitmapEffectCollection = 27,\n\t\tBitmapEffectGroup = 28,\n\t\tBitmapEffectInput = 29,\n\t\tBitmapEncoder = 30,\n\t\tBitmapFrame = 31,\n\t\tBitmapImage = 32,\n\t\tBitmapMetadata = 33,\n\t\tBitmapPalette = 34,\n\t\tBitmapSource = 35,\n\t\tBlock = 36,\n\t\tBlockUIContainer = 37,\n\t\tBlurBitmapEffect = 38,\n\t\tBmpBitmapDecoder = 39,\n\t\tBmpBitmapEncoder = 40,\n\t\tBold = 41,\n\t\tBoolIListConverter = 42,\n\t\tBoolean = 43,\n\t\tBooleanAnimationBase = 44,\n\t\tBooleanAnimationUsingKeyFrames = 45,\n\t\tBooleanConverter = 46,\n\t\tBooleanKeyFrame = 47,\n\t\tBooleanKeyFrameCollection = 48,\n\t\tBooleanToVisibilityConverter = 49,\n\t\tBorder = 50,\n\t\tBorderGapMaskConverter = 51,\n\t\tBrush = 52,\n\t\tBrushConverter = 53,\n\t\tBulletDecorator = 54,\n\t\tButton = 55,\n\t\tButtonBase = 56,\n\t\tByte = 57,\n\t\tByteAnimation = 58,\n\t\tByteAnimationBase = 59,\n\t\tByteAnimationUsingKeyFrames = 60,\n\t\tByteConverter = 61,\n\t\tByteKeyFrame = 62,\n\t\tByteKeyFrameCollection = 63,\n\t\tCachedBitmap = 64,\n\t\tCamera = 65,\n\t\tCanvas = 66,\n\t\tChar = 67,\n\t\tCharAnimationBase = 68,\n\t\tCharAnimationUsingKeyFrames = 69,\n\t\tCharConverter = 70,\n\t\tCharIListConverter = 71,\n\t\tCharKeyFrame = 72,\n\t\tCharKeyFrameCollection = 73,\n\t\tCheckBox = 74,\n\t\tClock = 75,\n\t\tClockController = 76,\n\t\tClockGroup = 77,\n\t\tCollectionContainer = 78,\n\t\tCollectionView = 79,\n\t\tCollectionViewSource = 80,\n\t\tColor = 81,\n\t\tColorAnimation = 82,\n\t\tColorAnimationBase = 83,\n\t\tColorAnimationUsingKeyFrames = 84,\n\t\tColorConvertedBitmap = 85,\n\t\tColorConvertedBitmapExtension = 86,\n\t\tColorConverter = 87,\n\t\tColorKeyFrame = 88,\n\t\tColorKeyFrameCollection = 89,\n\t\tColumnDefinition = 90,\n\t\tCombinedGeometry = 91,\n\t\tComboBox = 92,\n\t\tComboBoxItem = 93,\n\t\tCommandConverter = 94,\n\t\tComponentResourceKey = 95,\n\t\tComponentResourceKeyConverter = 96,\n\t\tCompositionTarget = 97,\n\t\tCondition = 98,\n\t\tContainerVisual = 99,\n\t\tContentControl = 100,\n\t\tContentElement = 101,\n\t\tContentPresenter = 102,\n\t\tContentPropertyAttribute = 103,\n\t\tContentWrapperAttribute = 104,\n\t\tContextMenu = 105,\n\t\tContextMenuService = 106,\n\t\tControl = 107,\n\t\tControlTemplate = 108,\n\t\tControllableStoryboardAction = 109,\n\t\tCornerRadius = 110,\n\t\tCornerRadiusConverter = 111,\n\t\tCroppedBitmap = 112,\n\t\tCultureInfo = 113,\n\t\tCultureInfoConverter = 114,\n\t\tCultureInfoIetfLanguageTagConverter = 115,\n\t\tCursor = 116,\n\t\tCursorConverter = 117,\n\t\tDashStyle = 118,\n\t\tDataChangedEventManager = 119,\n\t\tDataTemplate = 120,\n\t\tDataTemplateKey = 121,\n\t\tDataTrigger = 122,\n\t\tDateTime = 123,\n\t\tDateTimeConverter = 124,\n\t\tDateTimeConverter2 = 125,\n\t\tDecimal = 126,\n\t\tDecimalAnimation = 127,\n\t\tDecimalAnimationBase = 128,\n\t\tDecimalAnimationUsingKeyFrames = 129,\n\t\tDecimalConverter = 130,\n\t\tDecimalKeyFrame = 131,\n\t\tDecimalKeyFrameCollection = 132,\n\t\tDecorator = 133,\n\t\tDefinitionBase = 134,\n\t\tDependencyObject = 135,\n\t\tDependencyProperty = 136,\n\t\tDependencyPropertyConverter = 137,\n\t\tDialogResultConverter = 138,\n\t\tDiffuseMaterial = 139,\n\t\tDirectionalLight = 140,\n\t\tDiscreteBooleanKeyFrame = 141,\n\t\tDiscreteByteKeyFrame = 142,\n\t\tDiscreteCharKeyFrame = 143,\n\t\tDiscreteColorKeyFrame = 144,\n\t\tDiscreteDecimalKeyFrame = 145,\n\t\tDiscreteDoubleKeyFrame = 146,\n\t\tDiscreteInt16KeyFrame = 147,\n\t\tDiscreteInt32KeyFrame = 148,\n\t\tDiscreteInt64KeyFrame = 149,\n\t\tDiscreteMatrixKeyFrame = 150,\n\t\tDiscreteObjectKeyFrame = 151,\n\t\tDiscretePoint3DKeyFrame = 152,\n\t\tDiscretePointKeyFrame = 153,\n\t\tDiscreteQuaternionKeyFrame = 154,\n\t\tDiscreteRectKeyFrame = 155,\n\t\tDiscreteRotation3DKeyFrame = 156,\n\t\tDiscreteSingleKeyFrame = 157,\n\t\tDiscreteSizeKeyFrame = 158,\n\t\tDiscreteStringKeyFrame = 159,\n\t\tDiscreteThicknessKeyFrame = 160,\n\t\tDiscreteVector3DKeyFrame = 161,\n\t\tDiscreteVectorKeyFrame = 162,\n\t\tDockPanel = 163,\n\t\tDocumentPageView = 164,\n\t\tDocumentReference = 165,\n\t\tDocumentViewer = 166,\n\t\tDocumentViewerBase = 167,\n\t\tDouble = 168,\n\t\tDoubleAnimation = 169,\n\t\tDoubleAnimationBase = 170,\n\t\tDoubleAnimationUsingKeyFrames = 171,\n\t\tDoubleAnimationUsingPath = 172,\n\t\tDoubleCollection = 173,\n\t\tDoubleCollectionConverter = 174,\n\t\tDoubleConverter = 175,\n\t\tDoubleIListConverter = 176,\n\t\tDoubleKeyFrame = 177,\n\t\tDoubleKeyFrameCollection = 178,\n\t\tDrawing = 179,\n\t\tDrawingBrush = 180,\n\t\tDrawingCollection = 181,\n\t\tDrawingContext = 182,\n\t\tDrawingGroup = 183,\n\t\tDrawingImage = 184,\n\t\tDrawingVisual = 185,\n\t\tDropShadowBitmapEffect = 186,\n\t\tDuration = 187,\n\t\tDurationConverter = 188,\n\t\tDynamicResourceExtension = 189,\n\t\tDynamicResourceExtensionConverter = 190,\n\t\tEllipse = 191,\n\t\tEllipseGeometry = 192,\n\t\tEmbossBitmapEffect = 193,\n\t\tEmissiveMaterial = 194,\n\t\tEnumConverter = 195,\n\t\tEventManager = 196,\n\t\tEventSetter = 197,\n\t\tEventTrigger = 198,\n\t\tExpander = 199,\n\t\tExpression = 200,\n\t\tExpressionConverter = 201,\n\t\tFigure = 202,\n\t\tFigureLength = 203,\n\t\tFigureLengthConverter = 204,\n\t\tFixedDocument = 205,\n\t\tFixedDocumentSequence = 206,\n\t\tFixedPage = 207,\n\t\tFloater = 208,\n\t\tFlowDocument = 209,\n\t\tFlowDocumentPageViewer = 210,\n\t\tFlowDocumentReader = 211,\n\t\tFlowDocumentScrollViewer = 212,\n\t\tFocusManager = 213,\n\t\tFontFamily = 214,\n\t\tFontFamilyConverter = 215,\n\t\tFontSizeConverter = 216,\n\t\tFontStretch = 217,\n\t\tFontStretchConverter = 218,\n\t\tFontStyle = 219,\n\t\tFontStyleConverter = 220,\n\t\tFontWeight = 221,\n\t\tFontWeightConverter = 222,\n\t\tFormatConvertedBitmap = 223,\n\t\tFrame = 224,\n\t\tFrameworkContentElement = 225,\n\t\tFrameworkElement = 226,\n\t\tFrameworkElementFactory = 227,\n\t\tFrameworkPropertyMetadata = 228,\n\t\tFrameworkPropertyMetadataOptions = 229,\n\t\tFrameworkRichTextComposition = 230,\n\t\tFrameworkTemplate = 231,\n\t\tFrameworkTextComposition = 232,\n\t\tFreezable = 233,\n\t\tGeneralTransform = 234,\n\t\tGeneralTransformCollection = 235,\n\t\tGeneralTransformGroup = 236,\n\t\tGeometry = 237,\n\t\tGeometry3D = 238,\n\t\tGeometryCollection = 239,\n\t\tGeometryConverter = 240,\n\t\tGeometryDrawing = 241,\n\t\tGeometryGroup = 242,\n\t\tGeometryModel3D = 243,\n\t\tGestureRecognizer = 244,\n\t\tGifBitmapDecoder = 245,\n\t\tGifBitmapEncoder = 246,\n\t\tGlyphRun = 247,\n\t\tGlyphRunDrawing = 248,\n\t\tGlyphTypeface = 249,\n\t\tGlyphs = 250,\n\t\tGradientBrush = 251,\n\t\tGradientStop = 252,\n\t\tGradientStopCollection = 253,\n\t\tGrid = 254,\n\t\tGridLength = 255,\n\t\tGridLengthConverter = 256,\n\t\tGridSplitter = 257,\n\t\tGridView = 258,\n\t\tGridViewColumn = 259,\n\t\tGridViewColumnHeader = 260,\n\t\tGridViewHeaderRowPresenter = 261,\n\t\tGridViewRowPresenter = 262,\n\t\tGridViewRowPresenterBase = 263,\n\t\tGroupBox = 264,\n\t\tGroupItem = 265,\n\t\tGuid = 266,\n\t\tGuidConverter = 267,\n\t\tGuidelineSet = 268,\n\t\tHeaderedContentControl = 269,\n\t\tHeaderedItemsControl = 270,\n\t\tHierarchicalDataTemplate = 271,\n\t\tHostVisual = 272,\n\t\tHyperlink = 273,\n\t\tIAddChild = 274,\n\t\tIAddChildInternal = 275,\n\t\tICommand = 276,\n\t\tIComponentConnector = 277,\n\t\tINameScope = 278,\n\t\tIStyleConnector = 279,\n\t\tIconBitmapDecoder = 280,\n\t\tImage = 281,\n\t\tImageBrush = 282,\n\t\tImageDrawing = 283,\n\t\tImageMetadata = 284,\n\t\tImageSource = 285,\n\t\tImageSourceConverter = 286,\n\t\tInPlaceBitmapMetadataWriter = 287,\n\t\tInkCanvas = 288,\n\t\tInkPresenter = 289,\n\t\tInline = 290,\n\t\tInlineCollection = 291,\n\t\tInlineUIContainer = 292,\n\t\tInputBinding = 293,\n\t\tInputDevice = 294,\n\t\tInputLanguageManager = 295,\n\t\tInputManager = 296,\n\t\tInputMethod = 297,\n\t\tInputScope = 298,\n\t\tInputScopeConverter = 299,\n\t\tInputScopeName = 300,\n\t\tInputScopeNameConverter = 301,\n\t\tInt16 = 302,\n\t\tInt16Animation = 303,\n\t\tInt16AnimationBase = 304,\n\t\tInt16AnimationUsingKeyFrames = 305,\n\t\tInt16Converter = 306,\n\t\tInt16KeyFrame = 307,\n\t\tInt16KeyFrameCollection = 308,\n\t\tInt32 = 309,\n\t\tInt32Animation = 310,\n\t\tInt32AnimationBase = 311,\n\t\tInt32AnimationUsingKeyFrames = 312,\n\t\tInt32Collection = 313,\n\t\tInt32CollectionConverter = 314,\n\t\tInt32Converter = 315,\n\t\tInt32KeyFrame = 316,\n\t\tInt32KeyFrameCollection = 317,\n\t\tInt32Rect = 318,\n\t\tInt32RectConverter = 319,\n\t\tInt64 = 320,\n\t\tInt64Animation = 321,\n\t\tInt64AnimationBase = 322,\n\t\tInt64AnimationUsingKeyFrames = 323,\n\t\tInt64Converter = 324,\n\t\tInt64KeyFrame = 325,\n\t\tInt64KeyFrameCollection = 326,\n\t\tItalic = 327,\n\t\tItemCollection = 328,\n\t\tItemsControl = 329,\n\t\tItemsPanelTemplate = 330,\n\t\tItemsPresenter = 331,\n\t\tJournalEntry = 332,\n\t\tJournalEntryListConverter = 333,\n\t\tJournalEntryUnifiedViewConverter = 334,\n\t\tJpegBitmapDecoder = 335,\n\t\tJpegBitmapEncoder = 336,\n\t\tKeyBinding = 337,\n\t\tKeyConverter = 338,\n\t\tKeyGesture = 339,\n\t\tKeyGestureConverter = 340,\n\t\tKeySpline = 341,\n\t\tKeySplineConverter = 342,\n\t\tKeyTime = 343,\n\t\tKeyTimeConverter = 344,\n\t\tKeyboardDevice = 345,\n\t\tLabel = 346,\n\t\tLateBoundBitmapDecoder = 347,\n\t\tLengthConverter = 348,\n\t\tLight = 349,\n\t\tLine = 350,\n\t\tLineBreak = 351,\n\t\tLineGeometry = 352,\n\t\tLineSegment = 353,\n\t\tLinearByteKeyFrame = 354,\n\t\tLinearColorKeyFrame = 355,\n\t\tLinearDecimalKeyFrame = 356,\n\t\tLinearDoubleKeyFrame = 357,\n\t\tLinearGradientBrush = 358,\n\t\tLinearInt16KeyFrame = 359,\n\t\tLinearInt32KeyFrame = 360,\n\t\tLinearInt64KeyFrame = 361,\n\t\tLinearPoint3DKeyFrame = 362,\n\t\tLinearPointKeyFrame = 363,\n\t\tLinearQuaternionKeyFrame = 364,\n\t\tLinearRectKeyFrame = 365,\n\t\tLinearRotation3DKeyFrame = 366,\n\t\tLinearSingleKeyFrame = 367,\n\t\tLinearSizeKeyFrame = 368,\n\t\tLinearThicknessKeyFrame = 369,\n\t\tLinearVector3DKeyFrame = 370,\n\t\tLinearVectorKeyFrame = 371,\n\t\tList = 372,\n\t\tListBox = 373,\n\t\tListBoxItem = 374,\n\t\tListCollectionView = 375,\n\t\tListItem = 376,\n\t\tListView = 377,\n\t\tListViewItem = 378,\n\t\tLocalization = 379,\n\t\tLostFocusEventManager = 380,\n\t\tMarkupExtension = 381,\n\t\tMaterial = 382,\n\t\tMaterialCollection = 383,\n\t\tMaterialGroup = 384,\n\t\tMatrix = 385,\n\t\tMatrix3D = 386,\n\t\tMatrix3DConverter = 387,\n\t\tMatrixAnimationBase = 388,\n\t\tMatrixAnimationUsingKeyFrames = 389,\n\t\tMatrixAnimationUsingPath = 390,\n\t\tMatrixCamera = 391,\n\t\tMatrixConverter = 392,\n\t\tMatrixKeyFrame = 393,\n\t\tMatrixKeyFrameCollection = 394,\n\t\tMatrixTransform = 395,\n\t\tMatrixTransform3D = 396,\n\t\tMediaClock = 397,\n\t\tMediaElement = 398,\n\t\tMediaPlayer = 399,\n\t\tMediaTimeline = 400,\n\t\tMenu = 401,\n\t\tMenuBase = 402,\n\t\tMenuItem = 403,\n\t\tMenuScrollingVisibilityConverter = 404,\n\t\tMeshGeometry3D = 405,\n\t\tModel3D = 406,\n\t\tModel3DCollection = 407,\n\t\tModel3DGroup = 408,\n\t\tModelVisual3D = 409,\n\t\tModifierKeysConverter = 410,\n\t\tMouseActionConverter = 411,\n\t\tMouseBinding = 412,\n\t\tMouseDevice = 413,\n\t\tMouseGesture = 414,\n\t\tMouseGestureConverter = 415,\n\t\tMultiBinding = 416,\n\t\tMultiBindingExpression = 417,\n\t\tMultiDataTrigger = 418,\n\t\tMultiTrigger = 419,\n\t\tNameScope = 420,\n\t\tNavigationWindow = 421,\n\t\tNullExtension = 422,\n\t\tNullableBoolConverter = 423,\n\t\tNullableConverter = 424,\n\t\tNumberSubstitution = 425,\n\t\tObject = 426,\n\t\tObjectAnimationBase = 427,\n\t\tObjectAnimationUsingKeyFrames = 428,\n\t\tObjectDataProvider = 429,\n\t\tObjectKeyFrame = 430,\n\t\tObjectKeyFrameCollection = 431,\n\t\tOrthographicCamera = 432,\n\t\tOuterGlowBitmapEffect = 433,\n\t\tPage = 434,\n\t\tPageContent = 435,\n\t\tPageFunctionBase = 436,\n\t\tPanel = 437,\n\t\tParagraph = 438,\n\t\tParallelTimeline = 439,\n\t\tParserContext = 440,\n\t\tPasswordBox = 441,\n\t\tPath = 442,\n\t\tPathFigure = 443,\n\t\tPathFigureCollection = 444,\n\t\tPathFigureCollectionConverter = 445,\n\t\tPathGeometry = 446,\n\t\tPathSegment = 447,\n\t\tPathSegmentCollection = 448,\n\t\tPauseStoryboard = 449,\n\t\tPen = 450,\n\t\tPerspectiveCamera = 451,\n\t\tPixelFormat = 452,\n\t\tPixelFormatConverter = 453,\n\t\tPngBitmapDecoder = 454,\n\t\tPngBitmapEncoder = 455,\n\t\tPoint = 456,\n\t\tPoint3D = 457,\n\t\tPoint3DAnimation = 458,\n\t\tPoint3DAnimationBase = 459,\n\t\tPoint3DAnimationUsingKeyFrames = 460,\n\t\tPoint3DCollection = 461,\n\t\tPoint3DCollectionConverter = 462,\n\t\tPoint3DConverter = 463,\n\t\tPoint3DKeyFrame = 464,\n\t\tPoint3DKeyFrameCollection = 465,\n\t\tPoint4D = 466,\n\t\tPoint4DConverter = 467,\n\t\tPointAnimation = 468,\n\t\tPointAnimationBase = 469,\n\t\tPointAnimationUsingKeyFrames = 470,\n\t\tPointAnimationUsingPath = 471,\n\t\tPointCollection = 472,\n\t\tPointCollectionConverter = 473,\n\t\tPointConverter = 474,\n\t\tPointIListConverter = 475,\n\t\tPointKeyFrame = 476,\n\t\tPointKeyFrameCollection = 477,\n\t\tPointLight = 478,\n\t\tPointLightBase = 479,\n\t\tPolyBezierSegment = 480,\n\t\tPolyLineSegment = 481,\n\t\tPolyQuadraticBezierSegment = 482,\n\t\tPolygon = 483,\n\t\tPolyline = 484,\n\t\tPopup = 485,\n\t\tPresentationSource = 486,\n\t\tPriorityBinding = 487,\n\t\tPriorityBindingExpression = 488,\n\t\tProgressBar = 489,\n\t\tProjectionCamera = 490,\n\t\tPropertyPath = 491,\n\t\tPropertyPathConverter = 492,\n\t\tQuadraticBezierSegment = 493,\n\t\tQuaternion = 494,\n\t\tQuaternionAnimation = 495,\n\t\tQuaternionAnimationBase = 496,\n\t\tQuaternionAnimationUsingKeyFrames = 497,\n\t\tQuaternionConverter = 498,\n\t\tQuaternionKeyFrame = 499,\n\t\tQuaternionKeyFrameCollection = 500,\n\t\tQuaternionRotation3D = 501,\n\t\tRadialGradientBrush = 502,\n\t\tRadioButton = 503,\n\t\tRangeBase = 504,\n\t\tRect = 505,\n\t\tRect3D = 506,\n\t\tRect3DConverter = 507,\n\t\tRectAnimation = 508,\n\t\tRectAnimationBase = 509,\n\t\tRectAnimationUsingKeyFrames = 510,\n\t\tRectConverter = 511,\n\t\tRectKeyFrame = 512,\n\t\tRectKeyFrameCollection = 513,\n\t\tRectangle = 514,\n\t\tRectangleGeometry = 515,\n\t\tRelativeSource = 516,\n\t\tRemoveStoryboard = 517,\n\t\tRenderOptions = 518,\n\t\tRenderTargetBitmap = 519,\n\t\tRepeatBehavior = 520,\n\t\tRepeatBehaviorConverter = 521,\n\t\tRepeatButton = 522,\n\t\tResizeGrip = 523,\n\t\tResourceDictionary = 524,\n\t\tResourceKey = 525,\n\t\tResumeStoryboard = 526,\n\t\tRichTextBox = 527,\n\t\tRotateTransform = 528,\n\t\tRotateTransform3D = 529,\n\t\tRotation3D = 530,\n\t\tRotation3DAnimation = 531,\n\t\tRotation3DAnimationBase = 532,\n\t\tRotation3DAnimationUsingKeyFrames = 533,\n\t\tRotation3DKeyFrame = 534,\n\t\tRotation3DKeyFrameCollection = 535,\n\t\tRoutedCommand = 536,\n\t\tRoutedEvent = 537,\n\t\tRoutedEventConverter = 538,\n\t\tRoutedUICommand = 539,\n\t\tRoutingStrategy = 540,\n\t\tRowDefinition = 541,\n\t\tRun = 542,\n\t\tRuntimeNamePropertyAttribute = 543,\n\t\tSByte = 544,\n\t\tSByteConverter = 545,\n\t\tScaleTransform = 546,\n\t\tScaleTransform3D = 547,\n\t\tScrollBar = 548,\n\t\tScrollContentPresenter = 549,\n\t\tScrollViewer = 550,\n\t\tSection = 551,\n\t\tSeekStoryboard = 552,\n\t\tSelector = 553,\n\t\tSeparator = 554,\n\t\tSetStoryboardSpeedRatio = 555,\n\t\tSetter = 556,\n\t\tSetterBase = 557,\n\t\tShape = 558,\n\t\tSingle = 559,\n\t\tSingleAnimation = 560,\n\t\tSingleAnimationBase = 561,\n\t\tSingleAnimationUsingKeyFrames = 562,\n\t\tSingleConverter = 563,\n\t\tSingleKeyFrame = 564,\n\t\tSingleKeyFrameCollection = 565,\n\t\tSize = 566,\n\t\tSize3D = 567,\n\t\tSize3DConverter = 568,\n\t\tSizeAnimation = 569,\n\t\tSizeAnimationBase = 570,\n\t\tSizeAnimationUsingKeyFrames = 571,\n\t\tSizeConverter = 572,\n\t\tSizeKeyFrame = 573,\n\t\tSizeKeyFrameCollection = 574,\n\t\tSkewTransform = 575,\n\t\tSkipStoryboardToFill = 576,\n\t\tSlider = 577,\n\t\tSolidColorBrush = 578,\n\t\tSoundPlayerAction = 579,\n\t\tSpan = 580,\n\t\tSpecularMaterial = 581,\n\t\tSpellCheck = 582,\n\t\tSplineByteKeyFrame = 583,\n\t\tSplineColorKeyFrame = 584,\n\t\tSplineDecimalKeyFrame = 585,\n\t\tSplineDoubleKeyFrame = 586,\n\t\tSplineInt16KeyFrame = 587,\n\t\tSplineInt32KeyFrame = 588,\n\t\tSplineInt64KeyFrame = 589,\n\t\tSplinePoint3DKeyFrame = 590,\n\t\tSplinePointKeyFrame = 591,\n\t\tSplineQuaternionKeyFrame = 592,\n\t\tSplineRectKeyFrame = 593,\n\t\tSplineRotation3DKeyFrame = 594,\n\t\tSplineSingleKeyFrame = 595,\n\t\tSplineSizeKeyFrame = 596,\n\t\tSplineThicknessKeyFrame = 597,\n\t\tSplineVector3DKeyFrame = 598,\n\t\tSplineVectorKeyFrame = 599,\n\t\tSpotLight = 600,\n\t\tStackPanel = 601,\n\t\tStaticExtension = 602,\n\t\tStaticResourceExtension = 603,\n\t\tStatusBar = 604,\n\t\tStatusBarItem = 605,\n\t\tStickyNoteControl = 606,\n\t\tStopStoryboard = 607,\n\t\tStoryboard = 608,\n\t\tStreamGeometry = 609,\n\t\tStreamGeometryContext = 610,\n\t\tStreamResourceInfo = 611,\n\t\tString = 612,\n\t\tStringAnimationBase = 613,\n\t\tStringAnimationUsingKeyFrames = 614,\n\t\tStringConverter = 615,\n\t\tStringKeyFrame = 616,\n\t\tStringKeyFrameCollection = 617,\n\t\tStrokeCollection = 618,\n\t\tStrokeCollectionConverter = 619,\n\t\tStyle = 620,\n\t\tStylus = 621,\n\t\tStylusDevice = 622,\n\t\tTabControl = 623,\n\t\tTabItem = 624,\n\t\tTabPanel = 625,\n\t\tTable = 626,\n\t\tTableCell = 627,\n\t\tTableColumn = 628,\n\t\tTableRow = 629,\n\t\tTableRowGroup = 630,\n\t\tTabletDevice = 631,\n\t\tTemplateBindingExpression = 632,\n\t\tTemplateBindingExpressionConverter = 633,\n\t\tTemplateBindingExtension = 634,\n\t\tTemplateBindingExtensionConverter = 635,\n\t\tTemplateKey = 636,\n\t\tTemplateKeyConverter = 637,\n\t\tTextBlock = 638,\n\t\tTextBox = 639,\n\t\tTextBoxBase = 640,\n\t\tTextComposition = 641,\n\t\tTextCompositionManager = 642,\n\t\tTextDecoration = 643,\n\t\tTextDecorationCollection = 644,\n\t\tTextDecorationCollectionConverter = 645,\n\t\tTextEffect = 646,\n\t\tTextEffectCollection = 647,\n\t\tTextElement = 648,\n\t\tTextSearch = 649,\n\t\tThemeDictionaryExtension = 650,\n\t\tThickness = 651,\n\t\tThicknessAnimation = 652,\n\t\tThicknessAnimationBase = 653,\n\t\tThicknessAnimationUsingKeyFrames = 654,\n\t\tThicknessConverter = 655,\n\t\tThicknessKeyFrame = 656,\n\t\tThicknessKeyFrameCollection = 657,\n\t\tThumb = 658,\n\t\tTickBar = 659,\n\t\tTiffBitmapDecoder = 660,\n\t\tTiffBitmapEncoder = 661,\n\t\tTileBrush = 662,\n\t\tTimeSpan = 663,\n\t\tTimeSpanConverter = 664,\n\t\tTimeline = 665,\n\t\tTimelineCollection = 666,\n\t\tTimelineGroup = 667,\n\t\tToggleButton = 668,\n\t\tToolBar = 669,\n\t\tToolBarOverflowPanel = 670,\n\t\tToolBarPanel = 671,\n\t\tToolBarTray = 672,\n\t\tToolTip = 673,\n\t\tToolTipService = 674,\n\t\tTrack = 675,\n\t\tTransform = 676,\n\t\tTransform3D = 677,\n\t\tTransform3DCollection = 678,\n\t\tTransform3DGroup = 679,\n\t\tTransformCollection = 680,\n\t\tTransformConverter = 681,\n\t\tTransformGroup = 682,\n\t\tTransformedBitmap = 683,\n\t\tTranslateTransform = 684,\n\t\tTranslateTransform3D = 685,\n\t\tTreeView = 686,\n\t\tTreeViewItem = 687,\n\t\tTrigger = 688,\n\t\tTriggerAction = 689,\n\t\tTriggerBase = 690,\n\t\tTypeExtension = 691,\n\t\tTypeTypeConverter = 692,\n\t\tTypography = 693,\n\t\tUIElement = 694,\n\t\tUInt16 = 695,\n\t\tUInt16Converter = 696,\n\t\tUInt32 = 697,\n\t\tUInt32Converter = 698,\n\t\tUInt64 = 699,\n\t\tUInt64Converter = 700,\n\t\tUShortIListConverter = 701,\n\t\tUnderline = 702,\n\t\tUniformGrid = 703,\n\t\tUri = 704,\n\t\tUriTypeConverter = 705,\n\t\tUserControl = 706,\n\t\tValidation = 707,\n\t\tVector = 708,\n\t\tVector3D = 709,\n\t\tVector3DAnimation = 710,\n\t\tVector3DAnimationBase = 711,\n\t\tVector3DAnimationUsingKeyFrames = 712,\n\t\tVector3DCollection = 713,\n\t\tVector3DCollectionConverter = 714,\n\t\tVector3DConverter = 715,\n\t\tVector3DKeyFrame = 716,\n\t\tVector3DKeyFrameCollection = 717,\n\t\tVectorAnimation = 718,\n\t\tVectorAnimationBase = 719,\n\t\tVectorAnimationUsingKeyFrames = 720,\n\t\tVectorCollection = 721,\n\t\tVectorCollectionConverter = 722,\n\t\tVectorConverter = 723,\n\t\tVectorKeyFrame = 724,\n\t\tVectorKeyFrameCollection = 725,\n\t\tVideoDrawing = 726,\n\t\tViewBase = 727,\n\t\tViewbox = 728,\n\t\tViewport3D = 729,\n\t\tViewport3DVisual = 730,\n\t\tVirtualizingPanel = 731,\n\t\tVirtualizingStackPanel = 732,\n\t\tVisual = 733,\n\t\tVisual3D = 734,\n\t\tVisualBrush = 735,\n\t\tVisualTarget = 736,\n\t\tWeakEventManager = 737,\n\t\tWhitespaceSignificantCollectionAttribute = 738,\n\t\tWindow = 739,\n\t\tWmpBitmapDecoder = 740,\n\t\tWmpBitmapEncoder = 741,\n\t\tWrapPanel = 742,\n\t\tWriteableBitmap = 743,\n\t\tXamlBrushSerializer = 744,\n\t\tXamlInt32CollectionSerializer = 745,\n\t\tXamlPathDataSerializer = 746,\n\t\tXamlPoint3DCollectionSerializer = 747,\n\t\tXamlPointCollectionSerializer = 748,\n\t\tXamlReader = 749,\n\t\tXamlStyleSerializer = 750,\n\t\tXamlTemplateSerializer = 751,\n\t\tXamlVector3DCollectionSerializer = 752,\n\t\tXamlWriter = 753,\n\t\tXmlDataProvider = 754,\n\t\tXmlLangPropertyAttribute = 755,\n\t\tXmlLanguage = 756,\n\t\tXmlLanguageConverter = 757,\n\t\tXmlNamespaceMapping = 758,\n\t\tZoomPercentageConverter = 759,\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/BamlConnectionId.cs",
    "content": "/*\n\tCopyright (c) 2019 Siegfried Pammer\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.BamlDecompiler\n{\n\t/// <summary>\n\t/// Represents a field assignment of a XAML code-behind class.\n\t/// </summary>\n\tinternal sealed class FieldAssignment\n\t{\n\t\tpublic IField Field;\n\t}\n\n\t/// <summary>\n\t/// Represents an event registration of a XAML code-behind class.\n\t/// </summary>\n\tinternal sealed class EventRegistration\n\t{\n\t\tpublic string EventName, MethodName;\n\t}\n\n\tinternal class BamlConnectionId\n\t{\n\t\tpublic uint Id { get; }\n\n\t\tpublic BamlConnectionId(uint id) => Id = id;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/BamlDecompilationResult.cs",
    "content": "// Copyright (c) 2021 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Xml.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.BamlDecompiler\n{\n\tpublic class BamlDecompilationResult\n\t{\n\t\tpublic XDocument Xaml { get; }\n\t\tpublic List<string> AssemblyReferences { get; }\n\n\t\tpublic FullTypeName? TypeName { get; }\n\n\t\tpublic List<EntityHandle> GeneratedMembers { get; }\n\n\t\tpublic BamlDecompilationResult(XDocument xaml, FullTypeName? typeName, IEnumerable<string> assemblyReferences, IEnumerable<EntityHandle> generatedMembers)\n\t\t{\n\t\t\tthis.Xaml = xaml;\n\t\t\tthis.TypeName = typeName;\n\t\t\tthis.AssemblyReferences = assemblyReferences.ToList();\n\t\t\tthis.GeneratedMembers = generatedMembers.ToList();\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/BamlDecompilerSettings.cs",
    "content": "// Copyright (c) 2021 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.ComponentModel;\nusing System.Runtime.CompilerServices;\n\nnamespace ICSharpCode.BamlDecompiler\n{\n\tpublic class BamlDecompilerSettings : INotifyPropertyChanged\n\t{\n\t\tbool throwOnAssemblyResolveErrors = true;\n\n\t\t[Browsable(false)]\n\t\tpublic bool ThrowOnAssemblyResolveErrors {\n\t\t\tget { return throwOnAssemblyResolveErrors; }\n\t\t\tset {\n\t\t\t\tif (throwOnAssemblyResolveErrors != value)\n\t\t\t\t{\n\t\t\t\t\tthrowOnAssemblyResolveErrors = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic event PropertyChangedEventHandler PropertyChanged;\n\n\t\tprotected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)\n\t\t{\n\t\t\tif (PropertyChanged != null)\n\t\t\t{\n\t\t\t\tPropertyChanged(this, new PropertyChangedEventArgs(propertyName));\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/BamlDecompilerTypeSystem.cs",
    "content": "// Copyright (c) 2021 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.BamlDecompiler\n{\n\tpublic class BamlDecompilerTypeSystem : SimpleCompilation, IDecompilerTypeSystem\n\t{\n\t\tstring[] defaultBamlReferences = new[] {\n\t\t\t\t\"mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\t\"System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\t\"WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\t\"PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\t\"PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\t\"PresentationUI, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\t\"System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\n\t\t\t};\n\n\t\tpublic BamlDecompilerTypeSystem(MetadataFile mainModule, IAssemblyResolver assemblyResolver)\n\t\t{\n\t\t\tif (mainModule == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(mainModule));\n\t\t\tif (assemblyResolver == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(assemblyResolver));\n\t\t\t// Load referenced assemblies and type-forwarder references.\n\t\t\t// This is necessary to make .NET Core/PCL binaries work better.\n\t\t\tvar referencedAssemblies = new List<MetadataFile>();\n\t\t\tvar assemblyReferenceQueue = new Queue<(bool IsAssembly, MetadataFile MainModule, object Reference)>();\n\t\t\tvar mainMetadata = mainModule.Metadata;\n\t\t\tforeach (var h in mainMetadata.GetModuleReferences())\n\t\t\t{\n\t\t\t\tvar moduleRef = mainMetadata.GetModuleReference(h);\n\t\t\t\tvar moduleName = mainMetadata.GetString(moduleRef.Name);\n\t\t\t\tforeach (var fileHandle in mainMetadata.AssemblyFiles)\n\t\t\t\t{\n\t\t\t\t\tvar file = mainMetadata.GetAssemblyFile(fileHandle);\n\t\t\t\t\tif (mainMetadata.StringComparer.Equals(file.Name, moduleName) && file.ContainsMetadata)\n\t\t\t\t\t{\n\t\t\t\t\t\tassemblyReferenceQueue.Enqueue((false, mainModule, moduleName));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tforeach (var refs in mainModule.AssemblyReferences)\n\t\t\t{\n\t\t\t\tassemblyReferenceQueue.Enqueue((true, mainModule, refs));\n\t\t\t}\n\t\t\tforeach (var bamlReference in defaultBamlReferences)\n\t\t\t{\n\t\t\t\tassemblyReferenceQueue.Enqueue((true, mainModule, AssemblyNameReference.Parse(bamlReference)));\n\t\t\t}\n\t\t\tvar comparer = KeyComparer.Create(((bool IsAssembly, MetadataFile MainModule, object Reference) reference) =>\n\t\t\t\treference.IsAssembly ? \"A:\" + ((IAssemblyReference)reference.Reference).FullName :\n\t\t\t\t\t\t\t\t\t   \"M:\" + reference.Reference);\n\t\t\tvar processedAssemblyReferences = new HashSet<(bool IsAssembly, MetadataFile Parent, object Reference)>(comparer);\n\t\t\twhile (assemblyReferenceQueue.Count > 0)\n\t\t\t{\n\t\t\t\tvar asmRef = assemblyReferenceQueue.Dequeue();\n\t\t\t\tif (!processedAssemblyReferences.Add(asmRef))\n\t\t\t\t\tcontinue;\n\t\t\t\tMetadataFile asm;\n\t\t\t\tif (asmRef.IsAssembly)\n\t\t\t\t{\n\t\t\t\t\tasm = assemblyResolver.Resolve((IAssemblyReference)asmRef.Reference);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tasm = assemblyResolver.ResolveModule(asmRef.MainModule, (string)asmRef.Reference);\n\t\t\t\t}\n\t\t\t\tif (asm != null)\n\t\t\t\t{\n\t\t\t\t\treferencedAssemblies.Add(asm);\n\t\t\t\t\tvar metadata = asm.Metadata;\n\t\t\t\t\tforeach (var h in metadata.ExportedTypes)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar exportedType = metadata.GetExportedType(h);\n\t\t\t\t\t\tswitch (exportedType.Implementation.Kind)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase HandleKind.AssemblyReference:\n\t\t\t\t\t\t\t\tassemblyReferenceQueue.Enqueue((true, asm, new ICSharpCode.Decompiler.Metadata.AssemblyReference(asm, (AssemblyReferenceHandle)exportedType.Implementation)));\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase HandleKind.AssemblyFile:\n\t\t\t\t\t\t\t\tvar file = metadata.GetAssemblyFile((AssemblyFileHandle)exportedType.Implementation);\n\t\t\t\t\t\t\t\tassemblyReferenceQueue.Enqueue((false, asm, metadata.GetString(file.Name)));\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar mainModuleWithOptions = mainModule.WithOptions(TypeSystemOptions.Default);\n\t\t\tvar referencedAssembliesWithOptions = referencedAssemblies.Select(file => file.WithOptions(TypeSystemOptions.Default));\n\t\t\t// Primitive types are necessary to avoid assertions in ILReader.\n\t\t\t// Fallback to MinimalCorlib to provide the primitive types.\n\t\t\tif (!HasType(KnownTypeCode.Void) || !HasType(KnownTypeCode.Int32))\n\t\t\t{\n\t\t\t\tInit(mainModule.WithOptions(TypeSystemOptions.Default), referencedAssembliesWithOptions.Concat(new[] { MinimalCorlib.Instance }));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tInit(mainModuleWithOptions, referencedAssembliesWithOptions);\n\t\t\t}\n\t\t\tthis.MainModule = (MetadataModule)base.MainModule;\n\n\t\t\tbool HasType(KnownTypeCode code)\n\t\t\t{\n\t\t\t\tTopLevelTypeName name = KnownTypeReference.Get(code).TypeName;\n\t\t\t\tif (!mainModule.GetTypeDefinition(name).IsNil)\n\t\t\t\t\treturn true;\n\t\t\t\tforeach (var file in referencedAssemblies)\n\t\t\t\t{\n\t\t\t\t\tif (!file.GetTypeDefinition(name).IsNil)\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic new MetadataModule MainModule { get; }\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/BamlElement.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Collections.Generic;\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler\n{\n\tinternal readonly struct XamlNode\n\t{\n\t\tXamlNode(XElement value)\n\t\t{\n\t\t\tElement = value;\n\t\t\tString = null;\n\t\t}\n\n\t\tXamlNode(string value)\n\t\t{\n\t\t\tElement = null;\n\t\t\tString = value;\n\t\t}\n\n\t\tpublic readonly XElement Element;\n\t\tpublic readonly string String;\n\n\t\tpublic static implicit operator XamlNode(XElement value) => new XamlNode(value);\n\t\tpublic static implicit operator XamlNode(string value) => new XamlNode(value);\n\t\tpublic static implicit operator XElement(XamlNode node) => node.Element;\n\t\tpublic static implicit operator string(XamlNode node) => node.String;\n\t}\n\n\tinternal class BamlElement\n\t{\n\t\tpublic BamlNode Node { get; }\n\t\tpublic XamlNode Xaml { get; set; }\n\n\t\tpublic BamlElement Parent { get; set; }\n\t\tpublic IList<BamlElement> Children { get; }\n\n\t\tpublic BamlElement(BamlNode node)\n\t\t{\n\t\t\tNode = node;\n\t\t\tChildren = new List<BamlElement>();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Blocks/ConstructorParametersHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class ConstructorParametersStartHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.ConstructorParametersStart;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar doc = new BamlElement(node);\n\t\t\tdoc.Xaml = new XElement(ctx.GetPseudoName(\"Ctor\"));\n\t\t\tparent.Xaml.Element.Add(doc.Xaml.Element);\n\n\t\t\tHandlerMap.ProcessChildren(ctx, (BamlBlockNode)node, doc);\n\t\t\treturn doc;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Blocks/DocumentHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class DocumentHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.DocumentStart;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar doc = new BamlElement(node);\n\t\t\tdoc.Xaml = new XElement(ctx.GetPseudoName(\"Document\"));\n\n\t\t\tHandlerMap.ProcessChildren(ctx, (BamlBlockNode)node, doc);\n\t\t\treturn doc;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Blocks/ElementHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\nusing ICSharpCode.BamlDecompiler.Xaml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class ElementHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.ElementStart;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (ElementStartRecord)((BamlBlockNode)node).Header;\n\t\t\tvar doc = new BamlElement(node);\n\n\t\t\tvar elemType = ctx.ResolveType(record.TypeId);\n\t\t\tdoc.Xaml = new XElement(elemType.ToXName(ctx));\n\n\t\t\tdoc.Xaml.Element.AddAnnotation(elemType);\n\t\t\tparent.Xaml.Element.Add(doc.Xaml.Element);\n\n\t\t\tHandlerMap.ProcessChildren(ctx, (BamlBlockNode)node, doc);\n\t\t\tif (node.Annotation is XamlResourceKey key && key.KeyNode.Record != node.Record)\n\t\t\t{\n\t\t\t\tvar handler = (IDeferHandler)HandlerMap.LookupHandler(key.KeyNode.Record.Type);\n\t\t\t\tvar keyElem = handler.TranslateDefer(ctx, key.KeyNode, doc);\n\n\t\t\t\tdoc.Children.Add(keyElem);\n\t\t\t\tkeyElem.Parent = doc;\n\t\t\t}\n\n\t\t\telemType.ResolveNamespace(doc.Xaml, ctx);\n\t\t\tdoc.Xaml.Element.Name = elemType.ToXName(ctx);\n\n\t\t\treturn doc;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Blocks/KeyElementStartHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\nusing ICSharpCode.BamlDecompiler.Xaml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class KeyElementStartHandler : ElementHandler, IHandler, IDeferHandler\n\t{\n\t\tBamlRecordType IHandler.Type => BamlRecordType.KeyElementStart;\n\n\t\tBamlElement IHandler.Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tXamlResourceKey.Create(node);\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic BamlElement TranslateDefer(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (KeyElementStartRecord)((BamlBlockNode)node).Header;\n\t\t\tvar key = (XamlResourceKey)node.Annotation;\n\n\t\t\tvar bamlElem = new BamlElement(node);\n\t\t\tbamlElem.Xaml = new XElement(ctx.GetKnownNamespace(\"Key\", XamlContext.KnownNamespace_Xaml, parent.Xaml));\n\t\t\tparent.Xaml.Element.Add(bamlElem.Xaml.Element);\n\t\t\tkey.KeyElement = bamlElem;\n\t\t\tbase.Translate(ctx, node, bamlElem);\n\n\t\t\treturn bamlElem;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Blocks/PropertyArrayHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class PropertyArrayHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.PropertyArrayStart;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (PropertyArrayStartRecord)((BamlBlockNode)node).Header;\n\t\t\tvar doc = new BamlElement(node);\n\n\t\t\tvar elemAttr = ctx.ResolveProperty(record.AttributeId);\n\t\t\tdoc.Xaml = new XElement(elemAttr.ToXName(ctx, null));\n\n\t\t\tdoc.Xaml.Element.AddAnnotation(elemAttr);\n\t\t\tparent.Xaml.Element.Add(doc.Xaml.Element);\n\n\t\t\tHandlerMap.ProcessChildren(ctx, (BamlBlockNode)node, doc);\n\t\t\telemAttr.DeclaringType.ResolveNamespace(doc.Xaml, ctx);\n\t\t\tdoc.Xaml.Element.Name = elemAttr.ToXName(ctx, null);\n\n\t\t\treturn doc;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Blocks/PropertyComplexHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class PropertyComplexHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.PropertyComplexStart;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (PropertyComplexStartRecord)((BamlBlockNode)node).Header;\n\t\t\tvar doc = new BamlElement(node);\n\n\t\t\tvar elemAttr = ctx.ResolveProperty(record.AttributeId);\n\t\t\tdoc.Xaml = new XElement(elemAttr.ToXName(ctx, null));\n\n\t\t\tdoc.Xaml.Element.AddAnnotation(elemAttr);\n\t\t\tparent.Xaml.Element.Add(doc.Xaml.Element);\n\n\t\t\tHandlerMap.ProcessChildren(ctx, (BamlBlockNode)node, doc);\n\t\t\telemAttr.DeclaringType.ResolveNamespace(doc.Xaml, ctx);\n\t\t\tdoc.Xaml.Element.Name = elemAttr.ToXName(ctx, null);\n\n\t\t\treturn doc;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Blocks/PropertyDictionaryHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class PropertyDictionaryHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.PropertyDictionaryStart;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (PropertyDictionaryStartRecord)((BamlBlockNode)node).Header;\n\t\t\tvar doc = new BamlElement(node);\n\n\t\t\tvar elemAttr = ctx.ResolveProperty(record.AttributeId);\n\t\t\tdoc.Xaml = new XElement(elemAttr.ToXName(ctx, null));\n\n\t\t\tdoc.Xaml.Element.AddAnnotation(elemAttr);\n\t\t\tparent.Xaml.Element.Add(doc.Xaml.Element);\n\n\t\t\tHandlerMap.ProcessChildren(ctx, (BamlBlockNode)node, doc);\n\t\t\telemAttr.DeclaringType.ResolveNamespace(doc.Xaml, ctx);\n\t\t\tdoc.Xaml.Element.Name = elemAttr.ToXName(ctx, null);\n\n\t\t\treturn doc;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Blocks/PropertyListHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class PropertyListHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.PropertyListStart;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (PropertyListStartRecord)((BamlBlockNode)node).Header;\n\t\t\tvar doc = new BamlElement(node);\n\n\t\t\tvar elemAttr = ctx.ResolveProperty(record.AttributeId);\n\t\t\tdoc.Xaml = new XElement(elemAttr.ToXName(ctx, null));\n\n\t\t\tdoc.Xaml.Element.AddAnnotation(elemAttr);\n\t\t\tparent.Xaml.Element.Add(doc.Xaml.Element);\n\n\t\t\tHandlerMap.ProcessChildren(ctx, (BamlBlockNode)node, doc);\n\t\t\telemAttr.DeclaringType.ResolveNamespace(doc.Xaml, ctx);\n\t\t\tdoc.Xaml.Element.Name = elemAttr.ToXName(ctx, null);\n\n\t\t\treturn doc;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/AssemblyInfoHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class AssemblyInfoHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.AssemblyInfo;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) => null;\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/AttributeInfoHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class AttributeInfoHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.AttributeInfo;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) => null;\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/ConnectionIdHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class ConnectionIdHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.ConnectionId;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (ConnectionIdRecord)((BamlRecordNode)node).Record;\n\n\t\t\tparent.Xaml.Element.AddAnnotation(new BamlConnectionId(record.ConnectionId));\n\n\t\t\treturn null;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/ConstructorParameterTypeHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\nusing ICSharpCode.BamlDecompiler.Xaml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class ConstructorParameterTypeHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.ConstructorParameterType;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (ConstructorParameterTypeRecord)((BamlRecordNode)node).Record;\n\n\t\t\tvar elem = new XElement(ctx.GetKnownNamespace(\"TypeExtension\", XamlContext.KnownNamespace_Xaml, parent.Xaml));\n\t\t\telem.AddAnnotation(ctx.ResolveType(0xfd4d)); // Known type - TypeExtension\n\n\t\t\tvar bamlElem = new BamlElement(node);\n\t\t\tbamlElem.Xaml = elem;\n\t\t\tparent.Xaml.Element.Add(elem);\n\n\t\t\tvar type = ctx.ResolveType(record.TypeId);\n\t\t\tvar typeName = ctx.ToString(parent.Xaml, type);\n\t\t\telem.Add(new XElement(ctx.GetPseudoName(\"Ctor\"), typeName));\n\n\t\t\treturn bamlElem;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/ContentPropertyHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class ContentPropertyHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.ContentProperty;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (ContentPropertyRecord)((BamlRecordNode)node).Record;\n\t\t\t// TODO: What to do here?\n\n\t\t\treturn null;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/DefAttributeHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class DefAttributeHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.DefAttribute;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (DefAttributeRecord)((BamlRecordNode)node).Record;\n\n\t\t\tvar attrName = ctx.ResolveString(record.NameId);\n\t\t\tparent.Xaml.Element.Add(new XAttribute(ctx.GetKnownNamespace(attrName, XamlContext.KnownNamespace_Xaml), record.Value));\n\n\t\t\treturn null;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/DefAttributeKeyStringHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\nusing ICSharpCode.BamlDecompiler.Xaml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class DefAttributeStringHandler : IHandler, IDeferHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.DefAttributeKeyString;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tXamlResourceKey.Create(node);\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic BamlElement TranslateDefer(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (DefAttributeKeyStringRecord)((BamlRecordNode)node).Record;\n\t\t\tvar key = (XamlResourceKey)node.Annotation;\n\n\t\t\tvar bamlElem = new BamlElement(node);\n\t\t\tbamlElem.Xaml = new XElement(ctx.GetKnownNamespace(\"Key\", XamlContext.KnownNamespace_Xaml, parent.Xaml));\n\t\t\tparent.Xaml.Element.Add(bamlElem.Xaml.Element);\n\t\t\tbamlElem.Xaml.Element.Value = ctx.ResolveString(record.ValueId);\n\t\t\tkey.KeyElement = bamlElem;\n\n\t\t\treturn bamlElem;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/DefAttributeKeyTypeHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\nusing ICSharpCode.BamlDecompiler.Xaml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class DefAttributeTypeHandler : IHandler, IDeferHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.DefAttributeKeyType;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tXamlResourceKey.Create(node);\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic BamlElement TranslateDefer(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (DefAttributeKeyTypeRecord)((BamlRecordNode)node).Record;\n\t\t\tvar type = ctx.ResolveType(record.TypeId);\n\t\t\tvar typeName = ctx.ToString(parent.Xaml, type);\n\t\t\tvar key = (XamlResourceKey)node.Annotation;\n\n\t\t\tvar bamlElem = new BamlElement(node);\n\t\t\tbamlElem.Xaml = new XElement(ctx.GetKnownNamespace(\"Key\", XamlContext.KnownNamespace_Xaml, parent.Xaml));\n\t\t\tparent.Xaml.Element.Add(bamlElem.Xaml.Element);\n\n\t\t\tvar typeElem = new XElement(ctx.GetKnownNamespace(\"TypeExtension\", XamlContext.KnownNamespace_Xaml, parent.Xaml));\n\t\t\ttypeElem.AddAnnotation(ctx.ResolveType(0xfd4d)); // Known type - TypeExtension\n\t\t\ttypeElem.Add(new XElement(ctx.GetPseudoName(\"Ctor\"), typeName));\n\t\t\tbamlElem.Xaml.Element.Add(typeElem);\n\n\t\t\tkey.KeyElement = bamlElem;\n\n\t\t\treturn bamlElem;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/DeferableContentStartHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Diagnostics;\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class DeferableContentStartHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.DeferableContentStart;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (DeferableContentStartRecord)((BamlRecordNode)node).Record;\n\n\t\t\tDebug.Assert(record.Record == ((BamlBlockNode)parent.Node).Footer);\n\n\t\t\treturn null;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/LineNumberAndPositionHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class LineNumberAndPositionHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.LineNumberAndPosition;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) => null;\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/LinePositionHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class LinePositionHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.LinePosition;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) => null;\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/LiteralContentHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class LiteralContentHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.LiteralContent;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (LiteralContentRecord)((BamlRecordNode)node).Record;\n\n\t\t\tvar elem = new XElement(ctx.GetKnownNamespace(\"XData\", XamlContext.KnownNamespace_Xaml, parent.Xaml));\n\t\t\tvar content = XElement.Parse(record.Value);\n\t\t\telem.Add(content);\n\n\t\t\tparent.Xaml.Element.Add(elem);\n\n\t\t\treturn null;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/OptimizedStaticResourceHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\nusing ICSharpCode.BamlDecompiler.Xaml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class OptimizedStaticResourceHandler : IHandler, IDeferHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.OptimizedStaticResource;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (OptimizedStaticResourceRecord)((BamlRecordNode)node).Record;\n\t\t\tvar key = XamlResourceKey.FindKeyInSiblings(node);\n\n\t\t\tkey.StaticResources.Add(node);\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic BamlElement TranslateDefer(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (OptimizedStaticResourceRecord)((BamlRecordNode)node).Record;\n\t\t\tvar bamlElem = new BamlElement(node);\n\t\t\tobject key;\n\t\t\tif (record.IsType)\n\t\t\t{\n\t\t\t\tvar value = ctx.ResolveType(record.ValueId);\n\n\t\t\t\tvar typeElem = new XElement(ctx.GetKnownNamespace(\"TypeExtension\", XamlContext.KnownNamespace_Xaml, parent.Xaml));\n\t\t\t\ttypeElem.AddAnnotation(ctx.ResolveType(0xfd4d)); // Known type - TypeExtension\n\t\t\t\ttypeElem.Add(new XElement(ctx.GetPseudoName(\"Ctor\"), ctx.ToString(parent.Xaml, value)));\n\t\t\t\tkey = typeElem;\n\t\t\t}\n\t\t\telse if (record.IsStatic)\n\t\t\t{\n\t\t\t\tstring attrName;\n\t\t\t\tif (record.ValueId > 0x7fff)\n\t\t\t\t{\n\t\t\t\t\tbool isKey = true;\n\t\t\t\t\tshort bamlId = unchecked((short)-record.ValueId);\n\t\t\t\t\tif (bamlId > 232 && bamlId < 464)\n\t\t\t\t\t{\n\t\t\t\t\t\tbamlId -= 232;\n\t\t\t\t\t\tisKey = false;\n\t\t\t\t\t}\n\t\t\t\t\telse if (bamlId > 464 && bamlId < 467)\n\t\t\t\t\t{\n\t\t\t\t\t\tbamlId -= 231;\n\t\t\t\t\t}\n\t\t\t\t\telse if (bamlId > 467 && bamlId < 470)\n\t\t\t\t\t{\n\t\t\t\t\t\tbamlId -= 234;\n\t\t\t\t\t\tisKey = false;\n\t\t\t\t\t}\n\t\t\t\t\tvar res = ctx.Baml.KnownThings.Resources(bamlId);\n\t\t\t\t\tstring name;\n\t\t\t\t\tif (isKey)\n\t\t\t\t\t\tname = res.Item1 + \".\" + res.Item2;\n\t\t\t\t\telse\n\t\t\t\t\t\tname = res.Item1 + \".\" + res.Item3;\n\t\t\t\t\tvar xmlns = ctx.GetXmlNamespace(XamlContext.KnownNamespace_Presentation);\n\t\t\t\t\tattrName = ctx.ToString(parent.Xaml, xmlns.GetName(name));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar value = ctx.ResolveProperty(record.ValueId);\n\n\t\t\t\t\tvalue.DeclaringType.ResolveNamespace(parent.Xaml, ctx);\n\t\t\t\t\tvar xName = value.ToXName(ctx, parent.Xaml);\n\n\t\t\t\t\tattrName = ctx.ToString(parent.Xaml, xName);\n\t\t\t\t}\n\n\t\t\t\tvar staticElem = new XElement(ctx.GetKnownNamespace(\"StaticExtension\", XamlContext.KnownNamespace_Xaml, parent.Xaml));\n\t\t\t\tstaticElem.AddAnnotation(ctx.ResolveType(0xfda6)); // Known type - StaticExtension\n\t\t\t\tstaticElem.Add(new XElement(ctx.GetPseudoName(\"Ctor\"), attrName));\n\t\t\t\tkey = staticElem;\n\t\t\t}\n\t\t\telse\n\t\t\t\tkey = ctx.ResolveString(record.ValueId);\n\n\t\t\tvar extType = ctx.ResolveType(0xfda5);\n\t\t\tvar resElem = new XElement(extType.ToXName(ctx));\n\t\t\tresElem.AddAnnotation(extType); // Known type - StaticResourceExtension\n\t\t\tbamlElem.Xaml = resElem;\n\t\t\tparent.Xaml.Element.Add(resElem);\n\n\t\t\tvar attrElem = new XElement(ctx.GetPseudoName(\"Ctor\"));\n\t\t\tattrElem.Add(key);\n\t\t\tresElem.Add(attrElem);\n\n\t\t\treturn bamlElem;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/PIMappingHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class PIMappingHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.PIMapping;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) => null;\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/PresentationOptionsAttributeHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class PresentationOptionsAttributeHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.PresentationOptionsAttribute;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (PresentationOptionsAttributeRecord)((BamlRecordNode)node).Record;\n\n\t\t\tvar attrName = ctx.ResolveString(record.NameId);\n\t\t\tvar attr = new XAttribute(ctx.GetKnownNamespace(attrName, XamlContext.KnownNamespace_PresentationOptions, parent.Xaml), record.Value);\n\t\t\tparent.Xaml.Element.Add(attr);\n\n\t\t\treturn null;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/PropertyCustomHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System;\nusing System.Diagnostics;\nusing System.Globalization;\nusing System.IO;\nusing System.Text;\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\nusing ICSharpCode.BamlDecompiler.Xaml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class PropertyCustomHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.PropertyCustom;\n\n\t\tenum IntegerCollectionType : byte\n\t\t{\n\t\t\tUnknown,\n\t\t\tConsecutive,\n\t\t\tU1,\n\t\t\tU2,\n\t\t\tI4\n\t\t}\n\n\t\tstring Deserialize(XamlContext ctx, XElement elem, KnownTypes ser, byte[] value)\n\t\t{\n\t\t\tusing (BinaryReader reader = new BinaryReader(new MemoryStream(value)))\n\t\t\t{\n\t\t\t\tswitch (ser)\n\t\t\t\t{\n\t\t\t\t\tcase KnownTypes.DependencyPropertyConverter:\n\t\t\t\t\t{\n\t\t\t\t\t\tif (value.Length == 2)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar property = ctx.ResolveProperty(reader.ReadUInt16());\n\t\t\t\t\t\t\treturn ctx.ToString(elem, property.ToXName(ctx, elem, NeedsFullName(property, ctx, elem)));\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar type = ctx.ResolveType(reader.ReadUInt16());\n\t\t\t\t\t\t\tvar name = reader.ReadString();\n\t\t\t\t\t\t\tvar typeName = ctx.ToString(elem, type);\n\t\t\t\t\t\t\treturn typeName + \".\" + name;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcase KnownTypes.EnumConverter:\n\t\t\t\t\t{\n\t\t\t\t\t\tuint enumVal = reader.ReadUInt32();\n\t\t\t\t\t\t// TODO: Convert to enum names\n\t\t\t\t\t\treturn enumVal.ToString(\"D\", CultureInfo.InvariantCulture);\n\t\t\t\t\t}\n\n\t\t\t\t\tcase KnownTypes.BooleanConverter:\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(value.Length == 1);\n\t\t\t\t\t\treturn (reader.ReadByte() == 1).ToString(CultureInfo.InvariantCulture);\n\t\t\t\t\t}\n\n\t\t\t\t\tcase KnownTypes.XamlBrushSerializer:\n\t\t\t\t\t{\n\t\t\t\t\t\tswitch (reader.ReadByte())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase 1: // KnownSolidColor\n\t\t\t\t\t\t\t\treturn string.Format(CultureInfo.InvariantCulture, \"#{0:X8}\", reader.ReadUInt32());\n\t\t\t\t\t\t\tcase 2: // OtherColor\n\t\t\t\t\t\t\t\treturn reader.ReadString();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase KnownTypes.XamlPathDataSerializer:\n\t\t\t\t\t\treturn XamlPathDeserializer.Deserialize(reader);\n\n\t\t\t\t\tcase KnownTypes.XamlPoint3DCollectionSerializer:\n\t\t\t\t\tcase KnownTypes.XamlVector3DCollectionSerializer:\n\t\t\t\t\t{\n\t\t\t\t\t\tvar sb = new StringBuilder();\n\t\t\t\t\t\tvar count = reader.ReadUInt32();\n\t\t\t\t\t\tfor (uint i = 0; i < count; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsb.AppendFormat(CultureInfo.InvariantCulture, \"{0:R},{1:R},{2:R} \",\n\t\t\t\t\t\t\t\treader.ReadXamlDouble(),\n\t\t\t\t\t\t\t\treader.ReadXamlDouble(),\n\t\t\t\t\t\t\t\treader.ReadXamlDouble());\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn sb.ToString().Trim();\n\t\t\t\t\t}\n\n\t\t\t\t\tcase KnownTypes.XamlPointCollectionSerializer:\n\t\t\t\t\t{\n\t\t\t\t\t\tvar sb = new StringBuilder();\n\t\t\t\t\t\tvar count = reader.ReadUInt32();\n\t\t\t\t\t\tfor (uint i = 0; i < count; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsb.AppendFormat(CultureInfo.InvariantCulture, \"{0:R},{1:R} \",\n\t\t\t\t\t\t\t\treader.ReadXamlDouble(),\n\t\t\t\t\t\t\t\treader.ReadXamlDouble());\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn sb.ToString().Trim();\n\t\t\t\t\t}\n\n\t\t\t\t\tcase KnownTypes.XamlInt32CollectionSerializer:\n\t\t\t\t\t{\n\t\t\t\t\t\tvar sb = new StringBuilder();\n\t\t\t\t\t\tvar type = (IntegerCollectionType)reader.ReadByte();\n\t\t\t\t\t\tvar count = reader.ReadInt32();\n\n\t\t\t\t\t\tswitch (type)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase IntegerCollectionType.Consecutive:\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvar start = reader.ReadInt32();\n\t\t\t\t\t\t\t\tfor (int i = 0; i < count; i++)\n\t\t\t\t\t\t\t\t\tsb.AppendFormat(CultureInfo.InvariantCulture, \"{0:D}\", start + i);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase IntegerCollectionType.U1:\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfor (int i = 0; i < count; i++)\n\t\t\t\t\t\t\t\t\tsb.AppendFormat(CultureInfo.InvariantCulture, \"{0:D}\", reader.ReadByte());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase IntegerCollectionType.U2:\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfor (int i = 0; i < count; i++)\n\t\t\t\t\t\t\t\t\tsb.AppendFormat(CultureInfo.InvariantCulture, \"{0:D}\", reader.ReadUInt16());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase IntegerCollectionType.I4:\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfor (int i = 0; i < count; i++)\n\t\t\t\t\t\t\t\t\tsb.AppendFormat(CultureInfo.InvariantCulture, \"{0:D}\", reader.ReadInt32());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tthrow new NotSupportedException(type.ToString());\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn sb.ToString().Trim();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new NotSupportedException(ser.ToString());\n\t\t}\n\n\t\tprivate bool NeedsFullName(XamlProperty property, XamlContext ctx, XElement elem)\n\t\t{\n\t\t\tXElement p = elem.Parent;\n\t\t\twhile (p != null && p.Annotation<XamlType>()?.ResolvedType.FullName != \"System.Windows.Style\")\n\t\t\t{\n\t\t\t\tp = p.Parent;\n\t\t\t}\n\t\t\tvar type = p?.Annotation<TargetTypeAnnotation>()?.Type;\n\t\t\tif (type == null)\n\t\t\t\treturn true;\n\t\t\treturn property.IsAttachedTo(type);\n\t\t}\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (PropertyCustomRecord)((BamlRecordNode)node).Record;\n\t\t\tvar serTypeId = ((short)record.SerializerTypeId & 0xfff);\n\t\t\tbool valueType = ((short)record.SerializerTypeId & 0x4000) == 0x4000;\n\n\t\t\tvar elemType = parent.Xaml.Element.Annotation<XamlType>();\n\t\t\tvar xamlProp = ctx.ResolveProperty(record.AttributeId);\n\n\t\t\tstring value = Deserialize(ctx, parent.Xaml, (KnownTypes)serTypeId, record.Data);\n\t\t\tvar attr = new XAttribute(xamlProp.ToXName(ctx, parent.Xaml, xamlProp.IsAttachedTo(elemType)), value);\n\t\t\tparent.Xaml.Element.Add(attr);\n\n\t\t\treturn null;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/PropertyHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\nusing ICSharpCode.BamlDecompiler.Xaml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class PropertyHandler : IHandler\n\t{\n\t\tpublic virtual BamlRecordType Type => BamlRecordType.Property;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (PropertyRecord)((BamlRecordNode)node).Record;\n\n\t\t\tvar elemType = parent.Xaml.Element.Annotation<XamlType>();\n\t\t\tvar xamlProp = ctx.ResolveProperty(record.AttributeId);\n\t\t\tvar value = XamlUtils.Escape(record.Value);\n\t\t\txamlProp.DeclaringType.ResolveNamespace(parent.Xaml, ctx);\n\n\t\t\tparent.Xaml.Element.Add(ConstructXAttribute());\n\n\t\t\treturn null;\n\n\t\t\tXAttribute ConstructXAttribute()\n\t\t\t{\n\t\t\t\tif (xamlProp.IsAttachedTo(elemType))\n\t\t\t\t\treturn new XAttribute(xamlProp.ToXName(ctx, parent.Xaml, true), value);\n\n\t\t\t\tif (xamlProp.PropertyName == \"Name\" && elemType.ResolvedType.GetDefinition()?.ParentModule.IsMainModule == true)\n\t\t\t\t\treturn new XAttribute(ctx.GetKnownNamespace(\"Name\", XamlContext.KnownNamespace_Xaml), value);\n\n\t\t\t\treturn new XAttribute(xamlProp.ToXName(ctx, parent.Xaml, false), value);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/PropertyTypeReferenceHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nusing ICSharpCode.BamlDecompiler.Baml;\nusing ICSharpCode.BamlDecompiler.Xaml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class PropertyTypeReferenceHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.PropertyTypeReference;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (PropertyTypeReferenceRecord)((BamlRecordNode)node).Record;\n\t\t\tvar attr = ctx.ResolveProperty(record.AttributeId);\n\t\t\tvar type = ctx.ResolveType(record.TypeId);\n\t\t\tvar typeName = ctx.ToString(parent.Xaml, type);\n\n\t\t\tvar elem = new BamlElement(node);\n\n\t\t\tvar elemAttr = ctx.ResolveProperty(record.AttributeId);\n\t\t\telem.Xaml = new XElement(elemAttr.ToXName(ctx, null));\n\n\t\t\tif (attr.ResolvedMember?.FullNameIs(\"System.Windows.Style\", \"TargetType\") == true)\n\t\t\t{\n\t\t\t\tparent.Xaml.Element.AddAnnotation(new TargetTypeAnnotation(type));\n\t\t\t}\n\n\t\t\telem.Xaml.Element.AddAnnotation(elemAttr);\n\t\t\tparent.Xaml.Element.Add(elem.Xaml.Element);\n\n\t\t\tvar typeElem = new XElement(ctx.GetKnownNamespace(\"TypeExtension\", XamlContext.KnownNamespace_Xaml, parent.Xaml));\n\t\t\ttypeElem.AddAnnotation(ctx.ResolveType(0xfd4d)); // Known type - TypeExtension\n\t\t\ttypeElem.Add(new XElement(ctx.GetPseudoName(\"Ctor\"), typeName));\n\t\t\telem.Xaml.Element.Add(typeElem);\n\n\t\t\telemAttr.DeclaringType.ResolveNamespace(elem.Xaml, ctx);\n\t\t\telem.Xaml.Element.Name = elemAttr.ToXName(ctx, null);\n\n\t\t\treturn elem;\n\t\t}\n\t}\n\n\tinternal class TargetTypeAnnotation\n\t{\n\t\tpublic XamlType Type { get; }\n\n\t\tpublic TargetTypeAnnotation(XamlType type)\n\t\t{\n\t\t\tthis.Type = type;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/PropertyWithConverterHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class PropertyWithConverterHandler : PropertyHandler, IHandler\n\t{\n\t\tBamlRecordType IHandler.Type => BamlRecordType.PropertyWithConverter;\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/PropertyWithExtensionHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\nusing ICSharpCode.BamlDecompiler.Xaml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class PropertyWithExtensionHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.PropertyWithExtension;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (PropertyWithExtensionRecord)((BamlRecordNode)node).Record;\n\t\t\tvar extTypeId = ((short)record.Flags & 0xfff);\n\t\t\tbool valTypeExt = ((short)record.Flags & 0x4000) == 0x4000;\n\t\t\tbool valStaticExt = ((short)record.Flags & 0x2000) == 0x2000;\n\n\t\t\tvar elemType = parent.Xaml.Element.Annotation<XamlType>();\n\t\t\tvar xamlProp = ctx.ResolveProperty(record.AttributeId);\n\t\t\tvar extType = ctx.ResolveType(unchecked((ushort)-extTypeId));\n\t\t\textType.ResolveNamespace(parent.Xaml, ctx);\n\n\t\t\tvar ext = new XamlExtension(extType);\n\t\t\tif (valTypeExt || extTypeId == (short)KnownTypes.TypeExtension)\n\t\t\t{\n\t\t\t\tvar value = ctx.ResolveType(record.ValueId);\n\n\t\t\t\tobject[] initializer = new object[] { ctx.ToString(parent.Xaml, value) };\n\t\t\t\tif (valTypeExt)\n\t\t\t\t\tinitializer = new object[] { new XamlExtension(ctx.ResolveType(0xfd4d)) { Initializer = initializer } }; // Known type - TypeExtension\n\n\t\t\t\text.Initializer = initializer;\n\t\t\t}\n\t\t\telse if (extTypeId == (short)KnownTypes.TemplateBindingExtension)\n\t\t\t{\n\t\t\t\tvar value = ctx.ResolveProperty(record.ValueId);\n\n\t\t\t\tvalue.DeclaringType.ResolveNamespace(parent.Xaml, ctx);\n\t\t\t\tvar xName = value.ToXName(ctx, parent.Xaml, true);\n\n\t\t\t\text.Initializer = new object[] { ctx.ToString(parent.Xaml, xName) };\n\t\t\t}\n\t\t\telse if (valStaticExt || extTypeId == (short)KnownTypes.StaticExtension)\n\t\t\t{\n\t\t\t\tstring attrName;\n\t\t\t\tif (record.ValueId > 0x7fff)\n\t\t\t\t{\n\t\t\t\t\tbool isKey = true;\n\t\t\t\t\tshort bamlId = unchecked((short)-record.ValueId);\n\t\t\t\t\tif (bamlId > 232 && bamlId < 464)\n\t\t\t\t\t{\n\t\t\t\t\t\tbamlId -= 232;\n\t\t\t\t\t\tisKey = false;\n\t\t\t\t\t}\n\t\t\t\t\telse if (bamlId > 464 && bamlId < 467)\n\t\t\t\t\t{\n\t\t\t\t\t\tbamlId -= 231;\n\t\t\t\t\t}\n\t\t\t\t\telse if (bamlId > 467 && bamlId < 470)\n\t\t\t\t\t{\n\t\t\t\t\t\tbamlId -= 234;\n\t\t\t\t\t\tisKey = false;\n\t\t\t\t\t}\n\t\t\t\t\tvar res = ctx.Baml.KnownThings.Resources(bamlId);\n\t\t\t\t\tstring name;\n\t\t\t\t\tif (isKey)\n\t\t\t\t\t\tname = res.Item1 + \".\" + res.Item2;\n\t\t\t\t\telse\n\t\t\t\t\t\tname = res.Item1 + \".\" + res.Item3;\n\t\t\t\t\tvar xmlns = ctx.GetXmlNamespace(XamlContext.KnownNamespace_Presentation);\n\t\t\t\t\tattrName = ctx.ToString(parent.Xaml, xmlns.GetName(name));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar value = ctx.ResolveProperty(record.ValueId);\n\n\t\t\t\t\tvalue.DeclaringType.ResolveNamespace(parent.Xaml, ctx);\n\t\t\t\t\tvar xName = value.ToXName(ctx, parent.Xaml);\n\n\t\t\t\t\tattrName = ctx.ToString(parent.Xaml, xName);\n\t\t\t\t}\n\n\t\t\t\tobject[] initializer = new object[] { attrName };\n\t\t\t\tif (valStaticExt)\n\t\t\t\t\tinitializer = new object[] { new XamlExtension(ctx.ResolveType(0xfda6)) { Initializer = initializer } }; // Known type - StaticExtension\n\n\t\t\t\text.Initializer = initializer;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\text.Initializer = new object[] { XamlUtils.Escape(ctx.ResolveString(record.ValueId)) };\n\t\t\t}\n\n\t\t\tvar extValue = ext.ToString(ctx, parent.Xaml);\n\t\t\tvar attr = new XAttribute(xamlProp.ToXName(ctx, parent.Xaml, xamlProp.IsAttachedTo(elemType)), extValue);\n\t\t\tparent.Xaml.Element.Add(attr);\n\n\t\t\treturn null;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/PropertyWithStaticResourceIdHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System;\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\nusing ICSharpCode.BamlDecompiler.Xaml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class PropertyWithStaticResourceIdHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.PropertyWithStaticResourceId;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (PropertyWithStaticResourceIdRecord)((BamlRecordNode)node).Record;\n\t\t\tvar doc = new BamlElement(node);\n\n\t\t\tvar elemAttr = ctx.ResolveProperty(record.AttributeId);\n\t\t\tdoc.Xaml = new XElement(elemAttr.ToXName(ctx, null));\n\n\t\t\tdoc.Xaml.Element.AddAnnotation(elemAttr);\n\t\t\tparent.Xaml.Element.Add(doc.Xaml.Element);\n\n\t\t\tBamlNode found = node;\n\t\t\tXamlResourceKey key;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tkey = XamlResourceKey.FindKeyInAncestors(found.Parent, out found);\n\t\t\t} while (key != null && record.StaticResourceId >= key.StaticResources.Count);\n\n\t\t\tif (key == null)\n\t\t\t\tthrow new Exception(\"Cannot find StaticResource @\" + node.Record.Position);\n\n\t\t\tvar resNode = key.StaticResources[record.StaticResourceId];\n\n\t\t\tvar handler = (IDeferHandler)HandlerMap.LookupHandler(resNode.Type);\n\t\t\tvar resElem = handler.TranslateDefer(ctx, resNode, doc);\n\n\t\t\tdoc.Children.Add(resElem);\n\t\t\tresElem.Parent = doc;\n\n\t\t\telemAttr.DeclaringType.ResolveNamespace(doc.Xaml, ctx);\n\t\t\tdoc.Xaml.Element.Name = elemAttr.ToXName(ctx, null);\n\n\t\t\treturn doc;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/StaticResourceIdHandler.cs",
    "content": "// Copyright (c) 2019 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.BamlDecompiler.Baml;\nusing ICSharpCode.BamlDecompiler.Xaml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tclass StaticResourceIdHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.StaticResourceId;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (StaticResourceIdRecord)((BamlRecordNode)node).Record;\n\n\t\t\tBamlNode found = node;\n\t\t\tXamlResourceKey key;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tkey = XamlResourceKey.FindKeyInAncestors(found.Parent, out found);\n\t\t\t} while (key != null && record.StaticResourceId >= key.StaticResources.Count);\n\n\t\t\tif (key == null)\n\t\t\t\tthrow new Exception(\"Cannot find StaticResource @\" + node.Record.Position);\n\n\t\t\tvar resNode = key.StaticResources[record.StaticResourceId];\n\n\t\t\tvar handler = (IDeferHandler)HandlerMap.LookupHandler(resNode.Type);\n\t\t\tvar resElem = handler.TranslateDefer(ctx, resNode, parent);\n\n\t\t\tparent.Children.Add(resElem);\n\t\t\tresElem.Parent = parent;\n\n\t\t\treturn resElem;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/StaticResourceStartHandler.cs",
    "content": "// Copyright (c) 2019 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\nusing ICSharpCode.BamlDecompiler.Xaml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tclass StaticResourceStartHandler : IHandler, IDeferHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.StaticResourceStart;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (StaticResourceStartRecord)((BamlBlockNode)node).Record;\n\t\t\tvar key = XamlResourceKey.FindKeyInSiblings(node);\n\n\t\t\tkey.StaticResources.Add(node);\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic BamlElement TranslateDefer(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (StaticResourceStartRecord)((BamlBlockNode)node).Record;\n\t\t\tvar doc = new BamlElement(node);\n\t\t\tvar elemType = ctx.ResolveType(record.TypeId);\n\t\t\tdoc.Xaml = new XElement(elemType.ToXName(ctx));\n\t\t\tdoc.Xaml.Element.AddAnnotation(elemType);\n\t\t\tparent.Xaml.Element.Add(doc.Xaml.Element);\n\t\t\tHandlerMap.ProcessChildren(ctx, (BamlBlockNode)node, doc);\n\t\t\treturn doc;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/TextHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class TextHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.Text;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (TextRecord)((BamlRecordNode)node).Record;\n\n\t\t\tparent.Xaml.Element.Add(record.Value);\n\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tinternal class TextWithIdHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.TextWithId;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (TextWithIdRecord)((BamlRecordNode)node).Record;\n\n\t\t\tparent.Xaml.Element.Add(ctx.ResolveString(record.ValueId));\n\n\t\t\treturn null;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/TextWithConverterHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class TextWithConverterHandler : TextHandler, IHandler\n\t{\n\t\tBamlRecordType IHandler.Type => BamlRecordType.TextWithConverter;\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/TypeInfoHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class TypeInfoHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.TypeInfo;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) => null;\n\t}\n\n\tinternal class TypeSerializerInfoHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.TypeSerializerInfo;\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) => null;\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Handlers/Records/XmlnsPropertyHandler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Xml;\nusing System.Xml.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nusing ICSharpCode.BamlDecompiler.Baml;\nusing ICSharpCode.BamlDecompiler.Xaml;\n\nnamespace ICSharpCode.BamlDecompiler.Handlers\n{\n\tinternal class XmlnsPropertyHandler : IHandler\n\t{\n\t\tpublic BamlRecordType Type => BamlRecordType.XmlnsProperty;\n\n\t\tIEnumerable<string> ResolveCLRNamespaces(IModule assembly, string ns)\n\t\t{\n\t\t\tforeach (var attr in assembly.GetAssemblyAttributes().Where(a => a.AttributeType.FullName == \"System.Windows.Markup.XmlnsDefinitionAttribute\"))\n\t\t\t{\n\t\t\t\tDebug.Assert(attr.FixedArguments.Length == 2);\n\n\t\t\t\tvar xmlNs = attr.FixedArguments[0].Value;\n\t\t\t\tvar clrNs = attr.FixedArguments[1].Value;\n\t\t\t\tDebug.Assert(xmlNs is string && clrNs is string);\n\n\t\t\t\tif ((string)xmlNs == ns)\n\t\t\t\t\tyield return (string)clrNs;\n\t\t\t}\n\t\t}\n\n\t\tpublic BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent)\n\t\t{\n\t\t\tvar record = (XmlnsPropertyRecord)((BamlRecordNode)node).Record;\n\t\t\tforeach (var asmId in record.AssemblyIds)\n\t\t\t{\n\t\t\t\tvar assembly = ctx.Baml.ResolveAssembly(asmId);\n\t\t\t\tctx.XmlNs.Add(new NamespaceMap(record.Prefix, assembly.FullAssemblyName, record.XmlNamespace));\n\n\t\t\t\tif (assembly.Assembly?.IsMainModule == true)\n\t\t\t\t{\n\t\t\t\t\tforeach (var clrNs in ResolveCLRNamespaces(assembly.Assembly, record.XmlNamespace))\n\t\t\t\t\t\tctx.XmlNs.Add(new NamespaceMap(record.Prefix, assembly.FullAssemblyName, record.XmlNamespace, clrNs));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tXName xmlnsDef;\n\t\t\tif (string.IsNullOrEmpty(record.Prefix))\n\t\t\t\txmlnsDef = \"xmlns\";\n\t\t\telse\n\t\t\t\txmlnsDef = XNamespace.Xmlns + XmlConvert.EncodeLocalName(record.Prefix);\n\t\t\tparent.Xaml.Element.Add(new XAttribute(xmlnsDef, ctx.GetXmlNamespace(record.XmlNamespace)));\n\n\t\t\treturn null;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/ICSharpCode.BamlDecompiler.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <TargetFramework>net10.0</TargetFramework>\r\n    \r\n    <SignAssembly>True</SignAssembly>\r\n    <AssemblyOriginatorKeyFile>..\\ICSharpCode.Decompiler\\ICSharpCode.Decompiler.snk</AssemblyOriginatorKeyFile>\r\n    \r\n    <NeutralLanguage>en-US</NeutralLanguage>\r\n    <GenerateAssemblyVersionAttribute>False</GenerateAssemblyVersionAttribute>\r\n    <GenerateAssemblyFileVersionAttribute>False</GenerateAssemblyFileVersionAttribute>\r\n    <GenerateAssemblyInformationalVersionAttribute>False</GenerateAssemblyInformationalVersionAttribute>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup>\r\n    <PackageId>ICSharpCode.BamlDecompiler</PackageId>\r\n    <PackageVersion>10.0.0.0-noversion</PackageVersion>\r\n    <Title>ILSpy BAML Decompiler</Title>\r\n    <Authors>ILSpy Contributors</Authors>\r\n    <PackageLicenseExpression>MIT</PackageLicenseExpression>\r\n    <PackageProjectUrl>https://github.com/icsharpcode/ILSpy/</PackageProjectUrl>\r\n    <Description>Cross-Platform library for decompiling BAML.</Description>\r\n    <PackageReadmeFile>PackageReadme.md</PackageReadmeFile>\r\n    <Company>ic#code</Company>\r\n    <Product>BamlDecompiler</Product>\r\n    <RepositoryType>git</RepositoryType>\r\n    <RepositoryUrl>https://github.com/icsharpcode/ILSpy.git</RepositoryUrl>\r\n    <PackageIconUrl>../ICSharpCode.Decompiler/DecompilerNuGetPackageIcon.png</PackageIconUrl>\r\n    <PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>\r\n    <Copyright>Copyright 2024-$([System.DateTime]::Now.Year) AlphaSierraPapa</Copyright>\r\n    <PackageTags>C# Decompiler ILSpy</PackageTags>\r\n    <GenerateSBOM>true</GenerateSBOM>\r\n\t\r\n    <DebugType>embedded</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n    <EmbedUntrackedSources>true</EmbedUntrackedSources>\r\n    <PublishRepositoryUrl>true</PublishRepositoryUrl>\r\n  </PropertyGroup>\r\n  \r\n  <ItemGroup>\r\n    <None Include=\"PackageReadme.md\" Pack=\"true\" PackagePath=\"\\\" />\r\n  </ItemGroup>\r\n\r\n  <!-- https://devblogs.microsoft.com/nuget/enable-repeatable-package-restores-using-a-lock-file/ -->\r\n  <PropertyGroup>\r\n    <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>\r\n\t<RestoreLockedMode>true</RestoreLockedMode>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <Compile Remove=\"Baml\\KnownThings.gen.cs\" />\r\n  </ItemGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(GITHUB_ACTIONS)' == 'true'\">\r\n    <ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>\r\n  </PropertyGroup>\r\n\r\n  <!-- Inject ILSpyUpdateAssemblyInfo as dependency of the GetPackageVersion\r\n    target so Pack uses the generated version when evaluating project references. -->\r\n  <PropertyGroup>\r\n    <GetPackageVersionDependsOn>\r\n      ILSpyUpdateAssemblyInfo;\r\n      $(GetPackageVersionDependsOn)\r\n    </GetPackageVersionDependsOn>\r\n  </PropertyGroup>\r\n  \r\n  <ItemGroup>\r\n    <PackageReference Include=\"Microsoft.Sbom.Targets\">\r\n      <PrivateAssets>all</PrivateAssets>\r\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\r\n    </PackageReference>\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\ICSharpCode.Decompiler\\ICSharpCode.Decompiler.csproj\" />\r\n  </ItemGroup>\r\n  \r\n  <Target Name=\"ILSpyUpdateAssemblyInfo\" AfterTargets=\"ResolveProjectReferences\">\r\n    <ReadLinesFromFile ContinueOnError=\"true\" File=\"..\\VERSION\">\r\n      <Output TaskParameter=\"Lines\" PropertyName=\"PackageVersion\" />\r\n      <Output TaskParameter=\"Lines\" PropertyName=\"SbomGenerationPackageVersion\" />\r\n    </ReadLinesFromFile>\r\n  </Target>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/IHandlers.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler\n{\n\tinternal interface IHandler\n\t{\n\t\tBamlRecordType Type { get; }\n\t\tBamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent);\n\t}\n\n\tinternal interface IDeferHandler\n\t{\n\t\tBamlElement TranslateDefer(XamlContext ctx, BamlNode node, BamlElement parent);\n\t}\n\n\tinternal static class HandlerMap\n\t{\n\t\tstatic readonly Dictionary<BamlRecordType, IHandler> handlers;\n\n\t\tstatic HandlerMap()\n\t\t{\n\t\t\thandlers = new Dictionary<BamlRecordType, IHandler>();\n\n\t\t\tforeach (var type in typeof(IHandler).Assembly.GetTypes())\n\t\t\t{\n\t\t\t\tif (typeof(IHandler).IsAssignableFrom(type) &&\n\t\t\t\t\t!type.IsInterface && !type.IsAbstract)\n\t\t\t\t{\n\t\t\t\t\tvar handler = (IHandler)Activator.CreateInstance(type);\n\t\t\t\t\thandlers.Add(handler.Type, handler);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static IHandler LookupHandler(BamlRecordType type)\n\t\t{\n#if DEBUG\n\t\t\tswitch (type)\n\t\t\t{\n\t\t\t\tcase BamlRecordType.AssemblyInfo:\n\t\t\t\tcase BamlRecordType.TypeInfo:\n\t\t\t\tcase BamlRecordType.AttributeInfo:\n\t\t\t\tcase BamlRecordType.StringInfo:\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tif (!handlers.ContainsKey(type))\n\t\t\t\t\t\tthrow new NotSupportedException(type.ToString());\n\t\t\t\t\tbreak;\n\t\t\t}\n#endif\n\t\t\treturn handlers.ContainsKey(type) ? handlers[type] : null;\n\t\t}\n\n\t\tpublic static void ProcessChildren(XamlContext ctx, BamlBlockNode node, BamlElement nodeElem)\n\t\t{\n\t\t\tctx.XmlNs.PushScope(nodeElem);\n\t\t\tif (nodeElem.Xaml.Element != null)\n\t\t\t\tnodeElem.Xaml.Element.AddAnnotation(ctx.XmlNs.CurrentScope);\n\t\t\tforeach (var child in node.Children)\n\t\t\t{\n\t\t\t\tvar handler = LookupHandler(child.Type);\n\t\t\t\tif (handler == null)\n\t\t\t\t{\n\t\t\t\t\tDebug.WriteLine(\"BAML Handler {0} not implemented.\", child.Type);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tvar elem = handler.Translate(ctx, (BamlNode)child, nodeElem);\n\t\t\t\tif (elem != null)\n\t\t\t\t{\n\t\t\t\t\tnodeElem.Children.Add(elem);\n\t\t\t\t\telem.Parent = nodeElem;\n\t\t\t\t}\n\n\t\t\t\tctx.CancellationToken.ThrowIfCancellationRequested();\n\t\t\t}\n\t\t\tctx.XmlNs.PopScope();\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/IRewritePass.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml.Linq;\n\nnamespace ICSharpCode.BamlDecompiler\n{\n\tinternal interface IRewritePass\n\t{\n\t\tvoid Run(XamlContext ctx, XDocument document);\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/PackageReadme.md",
    "content": "## About\n\nICSharpCode.BamlDecompiler is the library used by the BAML Addin in ILSpy to decompile BAML to XAML.\n"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Properties/AssemblyInfo.cs",
    "content": "#region Using directives\n\nusing System.Diagnostics.CodeAnalysis;\nusing System.Reflection;\nusing System.Runtime.InteropServices;\n\n#endregion\n\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// This sets the default COM visibility of types in the assembly to invisible.\n// If you need to expose a type to COM, use [ComVisible(true)] on that type.\n[assembly: ComVisible(false)]\n\n[assembly: AssemblyVersion(DecompilerVersionInfo.Major + \".\" + DecompilerVersionInfo.Minor + \".\" + DecompilerVersionInfo.Build + \".\" + DecompilerVersionInfo.Revision)]\n[assembly: AssemblyInformationalVersion(DecompilerVersionInfo.FullVersionWithCommitHash)]\n\n[assembly: SuppressMessage(\"Microsoft.Usage\", \"CA2243:AttributeStringLiteralsShouldParseCorrectly\",\n\tJustification = \"AssemblyInformationalVersion does not need to be a parsable version\")]\n\n"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Rewrite/AttributeRewritePass.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Collections.Generic;\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Xaml;\n\nnamespace ICSharpCode.BamlDecompiler.Rewrite\n{\n\tinternal class AttributeRewritePass : IRewritePass\n\t{\n\t\tXName key;\n\n\t\tpublic void Run(XamlContext ctx, XDocument document)\n\t\t{\n\t\t\tkey = ctx.GetKnownNamespace(\"Key\", XamlContext.KnownNamespace_Xaml);\n\n\t\t\tbool doWork;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tdoWork = false;\n\t\t\t\tforeach (var elem in document.Elements())\n\t\t\t\t{\n\t\t\t\t\tdoWork |= ProcessElement(ctx, elem);\n\t\t\t\t}\n\t\t\t} while (doWork);\n\t\t}\n\n\t\tbool ProcessElement(XamlContext ctx, XElement elem)\n\t\t{\n\t\t\tbool doWork = false;\n\t\t\tforeach (var child in elem.Elements())\n\t\t\t{\n\t\t\t\tdoWork |= RewriteElement(ctx, elem, child);\n\t\t\t\tdoWork |= ProcessElement(ctx, child);\n\t\t\t}\n\t\t\treturn doWork;\n\t\t}\n\n\t\tbool RewriteElement(XamlContext ctx, XElement parent, XElement elem)\n\t\t{\n\t\t\tvar property = elem.Annotation<XamlProperty>();\n\t\t\tif (property == null && elem.Name != key)\n\t\t\t\treturn false;\n\n\t\t\tif (elem.HasAttributes || elem.HasElements)\n\t\t\t\treturn false;\n\n\t\t\tctx.CancellationToken.ThrowIfCancellationRequested();\n\n\t\t\tvar value = elem.Value;\n\t\t\tvar attrName = elem.Name;\n\t\t\tif (attrName != key)\n\t\t\t\tattrName = property.ToXName(ctx, parent, property.IsAttachedTo(parent.Annotation<XamlType>()));\n\t\t\tvar attr = new XAttribute(attrName, value);\n\t\t\tvar list = new List<XAttribute>(parent.Attributes());\n\t\t\tif (attrName == key)\n\t\t\t\tlist.Insert(0, attr);\n\t\t\telse\n\t\t\t\tlist.Add(attr);\n\t\t\tparent.RemoveAttributes();\n\t\t\tparent.ReplaceAttributes(list);\n\t\t\telem.Remove();\n\n\t\t\treturn true;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Rewrite/ConnectionIdRewritePass.cs",
    "content": "// Copyright (c) 2019 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Xaml;\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.BamlDecompiler.Rewrite\n{\n\tusing ICSharpCode.Decompiler.TypeSystem;\n\n\tinternal class ConnectionIdRewritePass : IRewritePass\n\t{\n\t\tstatic readonly TopLevelTypeName componentConnectorTypeName\n\t\t\t= new TopLevelTypeName(\"System.Windows.Markup\", \"IComponentConnector\");\n\t\tstatic readonly TopLevelTypeName styleConnectorTypeName\n\t\t\t= new TopLevelTypeName(\"System.Windows.Markup\", \"IStyleConnector\");\n\n\t\tpublic void Run(XamlContext ctx, XDocument document)\n\t\t{\n\t\t\tvar connections = DecompileConnections(ctx, document);\n\t\t\tProcessConnectionIds(ctx, document.Root, connections);\n\t\t}\n\n\t\tstatic void ProcessConnectionIds(XamlContext ctx, XElement element,\n\t\t\t(List<(LongSet key, FieldAssignment value)> fieldAssignments,\n\t\t\tList<(LongSet key, EventRegistration[] value)> eventMappings) connections)\n\t\t{\n\t\t\tforeach (var child in element.Elements())\n\t\t\t\tProcessConnectionIds(ctx, child, connections);\n\n\t\t\tvar fieldAssignments = connections.fieldAssignments;\n\t\t\tvar eventMappings = connections.eventMappings;\n\t\t\tforeach (var annotation in element.Annotations<BamlConnectionId>())\n\t\t\t{\n\t\t\t\tint index;\n\t\t\t\tbool found = false;\n\t\t\t\tif ((index = fieldAssignments.FindIndex(item => item.key.Contains(annotation.Id))) > -1)\n\t\t\t\t{\n\t\t\t\t\tvar xName = ctx.GetKnownNamespace(\"Name\", XamlContext.KnownNamespace_Xaml, element);\n\t\t\t\t\tFieldAssignment fieldAssignment = fieldAssignments[index].value;\n\t\t\t\t\tif (element.Attribute(\"Name\") is null && element.Attribute(xName) is null)\n\t\t\t\t\t{\n\t\t\t\t\t\telement.Add(new XAttribute(xName, fieldAssignment.Field.Name));\n\t\t\t\t\t}\n\t\t\t\t\t// x:FieldModifier can only be \"public\" or \"internal\" (in C#), where \"internal\" is the default and thus omitted\n\t\t\t\t\tif (fieldAssignment.Field.Accessibility is Accessibility.Public)\n\t\t\t\t\t{\n\t\t\t\t\t\telement.Add(new XAttribute(ctx.GetKnownNamespace(\"FieldModifier\", XamlContext.KnownNamespace_Xaml, element), \"public\"));\n\t\t\t\t\t}\n\t\t\t\t\tctx.GeneratedMembers.Add(fieldAssignment.Field.MetadataToken);\n\t\t\t\t\tfound = true;\n\t\t\t\t}\n\t\t\t\tif ((index = eventMappings.FindIndex(item => item.key.Contains(annotation.Id))) > -1)\n\t\t\t\t{\n\t\t\t\t\tforeach (var entry in eventMappings[index].value)\n\t\t\t\t\t{\n\t\t\t\t\t\tstring xmlns = \"\"; // TODO : implement xmlns resolver!\n\t\t\t\t\t\tvar type = element.Annotation<XamlType>();\n\t\t\t\t\t\tif (type?.TypeNamespace + \".\" + type?.TypeName == \"System.Windows.Style\")\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\telement.Add(new XElement(type.Namespace + \"EventSetter\",\n\t\t\t\t\t\t\t\tnew XAttribute(\"Event\", entry.EventName),\n\t\t\t\t\t\t\t\tnew XAttribute(\"Handler\", entry.MethodName)));\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\telement.Add(new XAttribute(xmlns + entry.EventName, entry.MethodName));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfound = true;\n\t\t\t\t}\n\t\t\t\tif (!found)\n\t\t\t\t{\n\t\t\t\t\telement.Add(new XComment($\"Unknown connection ID: {annotation.Id}\"));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t(List<(LongSet, FieldAssignment)>, List<(LongSet, EventRegistration[])>) DecompileConnections\n\t\t\t(XamlContext ctx, XDocument document)\n\t\t{\n\t\t\tvar fieldAssignments = new List<(LongSet key, FieldAssignment value)>();\n\t\t\tvar eventMappings = new List<(LongSet, EventRegistration[])>();\n\n\t\t\tvar xClass = document.Root\n\t\t\t\t.Elements().First()\n\t\t\t\t.Attribute(ctx.GetKnownNamespace(\"Class\", XamlContext.KnownNamespace_Xaml));\n\t\t\tif (xClass == null)\n\t\t\t\treturn (fieldAssignments, eventMappings);\n\n\t\t\tvar type = ctx.TypeSystem.FindType(new FullTypeName(xClass.Value)).GetDefinition();\n\t\t\tif (type == null)\n\t\t\t\treturn (fieldAssignments, eventMappings);\n\n\t\t\tDecompileConnections(ctx, fieldAssignments, eventMappings, componentConnectorTypeName, type);\n\t\t\tDecompileConnections(ctx, fieldAssignments, eventMappings, styleConnectorTypeName, type);\n\n\t\t\treturn (fieldAssignments, eventMappings);\n\t\t}\n\n\t\tvoid DecompileConnections(XamlContext ctx, List<(LongSet, FieldAssignment)> fieldAssignments,\n\t\t\tList<(LongSet, EventRegistration[])> eventMappings, FullTypeName connectorTypeName, ITypeDefinition type)\n\t\t{\n\t\t\tvar connectorInterface = ctx.TypeSystem.FindType(connectorTypeName).GetDefinition();\n\t\t\tif (connectorInterface == null)\n\t\t\t\treturn;\n\t\t\tvar connect = connectorInterface.GetMethods(m => m.Name == \"Connect\").SingleOrDefault();\n\n\t\t\tIMethod connectMethod = null;\n\t\t\tMethodDefinition connectMetadataEntry = default;\n\t\t\tvar module = ctx.TypeSystem.MainModule.MetadataFile;\n\n\t\t\tforeach (IMethod m in type.Methods)\n\t\t\t{\n\t\t\t\tif (connectMethod == null && m.ExplicitlyImplementedInterfaceMembers.Any(md => md.MemberDefinition.Equals(connect)))\n\t\t\t\t{\n\t\t\t\t\tconnectMethod = m;\n\t\t\t\t\tconnectMetadataEntry = module.Metadata\n\t\t\t\t\t\t.GetMethodDefinition((MethodDefinitionHandle)connectMethod.MetadataToken);\n\t\t\t\t}\n\t\t\t\telse if (m.Parameters.Count == 0\n\t\t\t\t\t&& m.ReturnType.Kind == TypeKind.Void\n\t\t\t\t\t&& !m.IsStatic\n\t\t\t\t\t&& m.Accessibility == Accessibility.Public\n\t\t\t\t\t&& m.Name == \"InitializeComponent\"\n\t\t\t\t\t&& m.GetAttributes().Any(a => a.AttributeType.ReflectionName == \"System.CodeDom.Compiler.GeneratedCodeAttribute\"))\n\t\t\t\t{\n\t\t\t\t\tctx.GeneratedMembers.Add(m.MetadataToken);\n\t\t\t\t}\n\t\t\t\telse if (m.Parameters.Count == 0\n\t\t\t\t\t&& m.ReturnType.Kind == TypeKind.Void\n\t\t\t\t\t&& m.IsStatic\n\t\t\t\t\t&& m.Accessibility == Accessibility.Public\n\t\t\t\t\t&& m.Name == \"Main\"\n\t\t\t\t\t&& m.DeclaringTypeDefinition.GetNonInterfaceBaseTypes().Any(t => t.ReflectionName == \"System.Windows.Application\")\n\t\t\t\t\t&& m.GetAttributes().Any(a => a.AttributeType.ReflectionName == \"System.CodeDom.Compiler.GeneratedCodeAttribute\"))\n\t\t\t\t{\n\t\t\t\t\tctx.GeneratedMembers.Add(m.MetadataToken);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (type.Fields.FirstOrDefault(f => f.Name == \"_contentLoaded\" && f.Type.IsKnownType(KnownTypeCode.Boolean)) is {\n\t\t\t\tAccessibility: Accessibility.Private, IsStatic: false\n\t\t\t} contentLoadedField)\n\t\t\t{\n\t\t\t\tctx.GeneratedMembers.Add(contentLoadedField.MetadataToken);\n\t\t\t}\n\n\t\t\tif (connectMethod == null || connectMetadataEntry.RelativeVirtualAddress <= 0)\n\t\t\t\treturn;\n\n\t\t\tctx.GeneratedMembers.Add(connectMethod.MetadataToken);\n\n\t\t\tvar body = module.GetMethodBody(connectMetadataEntry.RelativeVirtualAddress);\n\t\t\tvar genericContext = new GenericContext(\n\t\t\t\tclassTypeParameters: connectMethod.DeclaringType?.TypeParameters,\n\t\t\t\tmethodTypeParameters: connectMethod.TypeParameters);\n\n\t\t\t// decompile method and optimize the switch\n\t\t\tvar ilReader = new ILReader(ctx.TypeSystem.MainModule);\n\t\t\tvar function = ilReader.ReadIL((MethodDefinitionHandle)connectMethod.MetadataToken, body, genericContext,\n\t\t\t\tILFunctionKind.TopLevelFunction, ctx.CancellationToken);\n\n\t\t\tvar context = new ILTransformContext(function, ctx.TypeSystem, null) {\n\t\t\t\tCancellationToken = ctx.CancellationToken\n\t\t\t};\n\t\t\tfunction.RunTransforms(CSharpDecompiler.GetILTransforms(), context);\n\n\t\t\tvar block = function.Body.Children.OfType<Block>().First();\n\t\t\tvar ilSwitch = block.Descendants.OfType<SwitchInstruction>().FirstOrDefault();\n\n\t\t\tvar events = new List<EventRegistration>();\n\t\t\tif (ilSwitch != null)\n\t\t\t{\n\t\t\t\tforeach (var section in ilSwitch.Sections)\n\t\t\t\t{\n\t\t\t\t\tAdd(section.Labels, section.Body);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tforeach (var ifInst in function.Descendants.OfType<IfInstruction>())\n\t\t\t\t{\n\t\t\t\t\tif (!(ifInst.Condition is Comp comp))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tif (comp.Kind != ComparisonKind.Inequality && comp.Kind != ComparisonKind.Equality)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tif (!comp.Right.MatchLdcI4(out int id))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tvar inst = comp.Kind == ComparisonKind.Inequality\n\t\t\t\t\t\t? ifInst.FalseInst\n\t\t\t\t\t\t: ifInst.TrueInst;\n\n\t\t\t\t\tAdd(new LongSet(id), inst);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid Add(LongSet ids, ILInstruction inst)\n\t\t\t{\n\t\t\t\tvar field = FindField(inst);\n\t\t\t\tif (!(field is null))\n\t\t\t\t{\n\t\t\t\t\tfieldAssignments.Add((ids, field));\n\t\t\t\t}\n\t\t\t\tevents.Clear();\n\t\t\t\tFindEvents(inst, events);\n\t\t\t\tif (events.Count > 0)\n\t\t\t\t{\n\t\t\t\t\teventMappings.Add((ids, events.ToArray()));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tFieldAssignment FindField(ILInstruction inst)\n\t\t{\n\t\t\tswitch (inst)\n\t\t\t{\n\t\t\t\tcase Block b:\n\t\t\t\t\tvar t = b.Instructions.FirstOrDefault();\n\t\t\t\t\tif (!(t is null) && MatchFieldAssignment(t, out var field))\n\t\t\t\t\t\treturn field;\n\t\t\t\t\treturn null;\n\t\t\t\tcase Branch br:\n\t\t\t\t\treturn FindField(br.TargetBlock);\n\t\t\t\tdefault:\n\t\t\t\t\tif (MatchFieldAssignment(inst, out field))\n\t\t\t\t\t\treturn field;\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tbool MatchFieldAssignment(ILInstruction inst, out FieldAssignment field)\n\t\t{\n\t\t\tfield = null;\n\t\t\tif (!inst.MatchStFld(out _, out var fld, out var value) || !value.MatchCastClass(out var arg, out _)\n\t\t\t\t|| !(arg.MatchLdLoc(out var t) && t.Kind == VariableKind.Parameter && t.Index == 1))\n\t\t\t\treturn false;\n\n\t\t\tfield = new FieldAssignment { Field = fld };\n\t\t\treturn true;\n\t\t}\n\n\t\tvoid FindEvents(ILInstruction inst, List<EventRegistration> events)\n\t\t{\n\t\t\tEventRegistration @event;\n\t\t\tswitch (inst)\n\t\t\t{\n\t\t\t\tcase Block b:\n\t\t\t\t\tfor (int i = 0; i < b.Instructions.Count;)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (MatchEventSetterCreation(b, ref i, out @event))\n\t\t\t\t\t\t\tevents.Add(@event);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\ti++;\n\t\t\t\t\t}\n\t\t\t\t\tforeach (var node in b.Instructions)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (MatchSimpleEventRegistration(node, out @event))\n\t\t\t\t\t\t\tevents.Add(@event);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase Branch br:\n\t\t\t\t\tFindEvents(br.TargetBlock, events);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tif (MatchSimpleEventRegistration(inst, out @event))\n\t\t\t\t\t\tevents.Add(@event);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// stloc v(newobj EventSetter..ctor())\n\t\t// callvirt set_Event(ldloc v, ldsfld eventName)\n\t\t// callvirt set_Handler(ldloc v, newobj RoutedEventHandler..ctor(ldloc this, ldftn eventHandler))\n\t\t// callvirt Add(callvirt get_Setters(castclass System.Windows.Style(ldloc target)), ldloc v)\n\t\tbool MatchEventSetterCreation(Block b, ref int pos, out EventRegistration @event)\n\t\t{\n\t\t\t@event = null;\n\t\t\tif (!b.FinalInstruction.MatchNop())\n\t\t\t{\n\t\t\t\tpos = b.Instructions.Count;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar instr = b.Instructions;\n\t\t\t// stloc v(newobj EventSetter..ctor())\n\t\t\tif (!instr[pos + 0].MatchStLoc(out var v, out var initializer))\n\t\t\t\treturn false;\n\t\t\tif (!(initializer is NewObj newObj\n\t\t\t\t&& newObj.Method.DeclaringType.FullName == \"System.Windows.EventSetter\"\n\t\t\t\t&& newObj.Arguments.Count == 0))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t//callvirt set_Event(ldloc v, ldsfld eventName)\n\t\t\tif (!(instr[pos + 1] is CallVirt setEventCall && setEventCall.Arguments.Count == 2))\n\t\t\t\treturn false;\n\t\t\tif (!setEventCall.Method.IsAccessor)\n\t\t\t\treturn false;\n\t\t\tif (!setEventCall.Arguments[0].MatchLdLoc(v))\n\t\t\t\treturn false;\n\t\t\tif (setEventCall.Method.Name != \"set_Event\")\n\t\t\t\treturn false;\n\t\t\tif (!setEventCall.Arguments[1].MatchLdsFld(out var eventField))\n\t\t\t\treturn false;\n\t\t\tstring eventName = eventField.Name;\n\t\t\tif (eventName.EndsWith(\"Event\"))\n\t\t\t{\n\t\t\t\teventName = eventName.Remove(eventName.Length - \"Event\".Length);\n\t\t\t}\n\t\t\t// callvirt set_Handler(ldloc v, newobj RoutedEventHandler..ctor(ldloc this, ldftn eventHandler))\n\t\t\tif (!(instr[pos + 2] is CallVirt setHandlerCall && setHandlerCall.Arguments.Count == 2))\n\t\t\t\treturn false;\n\t\t\tif (!setHandlerCall.Method.IsAccessor)\n\t\t\t\treturn false;\n\t\t\tif (!setHandlerCall.Arguments[0].MatchLdLoc(v))\n\t\t\t\treturn false;\n\t\t\tif (setHandlerCall.Method.Name != \"set_Handler\")\n\t\t\t\treturn false;\n\t\t\tif (!MatchEventHandlerCreation(setHandlerCall.Arguments[1], out string handlerName))\n\t\t\t\treturn false;\n\t\t\t@event = new EventRegistration { EventName = eventName, MethodName = handlerName };\n\t\t\t// callvirt Add(callvirt get_Setters(castclass System.Windows.Style(ldloc target)), ldloc v)\n\t\t\tif (!(instr[pos + 3] is CallVirt addCall && addCall.Arguments.Count == 2))\n\t\t\t\treturn false;\n\t\t\tif (addCall.Method.Name != \"Add\")\n\t\t\t\treturn false;\n\t\t\tif (!(addCall.Arguments[0] is CallVirt getSettersCall && getSettersCall.Arguments.Count == 1))\n\t\t\t\treturn false;\n\t\t\tif (!getSettersCall.Method.IsAccessor)\n\t\t\t\treturn false;\n\t\t\tif (getSettersCall.Method.Name != \"get_Setters\")\n\t\t\t\treturn false;\n\t\t\tif (!getSettersCall.Arguments[0].MatchCastClass(out var arg, out var type))\n\t\t\t\treturn false;\n\t\t\tif (type.FullName != \"System.Windows.Style\")\n\t\t\t\treturn false;\n\t\t\tif (!(arg.MatchLdLoc(out var t) && t.Kind == VariableKind.Parameter && t.Index == 1))\n\t\t\t\treturn false;\n\t\t\tif (!addCall.Arguments[1].MatchLdLoc(v))\n\t\t\t\treturn false;\n\t\t\tpos += 4;\n\t\t\treturn true;\n\t\t}\n\n\t\tbool MatchSimpleEventRegistration(ILInstruction inst, out EventRegistration @event)\n\t\t{\n\t\t\t@event = null;\n\t\t\tif (!(inst is CallInstruction call) || call.OpCode == OpCode.NewObj)\n\t\t\t\treturn false;\n\n\t\t\tif (!IsAddEvent(call, out string eventName, out string handlerName)\n\t\t\t\t&& !IsAddAttachedEvent(call, out eventName, out handlerName))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t@event = new EventRegistration { EventName = eventName, MethodName = handlerName };\n\t\t\treturn true;\n\t\t}\n\n\t\tbool IsAddAttachedEvent(CallInstruction call, out string eventName, out string handlerName)\n\t\t{\n\t\t\teventName = \"\";\n\t\t\thandlerName = \"\";\n\n\t\t\tif (call.Arguments.Count == 3)\n\t\t\t{\n\t\t\t\tvar addMethod = call.Method;\n\t\t\t\tif (addMethod.Name != \"AddHandler\" || addMethod.Parameters.Count != 2)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!call.Arguments[1].MatchLdsFld(out IField field))\n\t\t\t\t\treturn false;\n\t\t\t\teventName = field.DeclaringType.Name + \".\" + field.Name;\n\t\t\t\tif (eventName.EndsWith(\"Event\", StringComparison.Ordinal)\n\t\t\t\t\t&& eventName.Length > \"Event\".Length)\n\t\t\t\t{\n\t\t\t\t\teventName = eventName.Remove(eventName.Length - \"Event\".Length);\n\t\t\t\t}\n\t\t\t\treturn MatchEventHandlerCreation(call.Arguments[2], out handlerName);\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tbool IsAddEvent(CallInstruction call, out string eventName, out string handlerName)\n\t\t{\n\t\t\teventName = \"\";\n\t\t\thandlerName = \"\";\n\n\t\t\tif (call.Arguments.Count == 2)\n\t\t\t{\n\t\t\t\tvar addMethod = call.Method;\n\t\t\t\tif (!addMethod.Name.StartsWith(\"add_\", StringComparison.Ordinal)\n\t\t\t\t\t|| addMethod.Parameters.Count != 1)\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\teventName = addMethod.Name.Substring(\"add_\".Length);\n\t\t\t\treturn MatchEventHandlerCreation(call.Arguments[1], out handlerName);\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tbool MatchEventHandlerCreation(ILInstruction inst, out string handlerName)\n\t\t{\n\t\t\thandlerName = \"\";\n\t\t\tif (!(inst is NewObj newObj) || newObj.Arguments.Count != 2)\n\t\t\t\treturn false;\n\t\t\tvar ldftn = newObj.Arguments[1];\n\t\t\tif (ldftn.OpCode != OpCode.LdFtn && ldftn.OpCode != OpCode.LdVirtFtn)\n\t\t\t\treturn false;\n\t\t\thandlerName = ((IInstructionWithMethodOperand)ldftn).Method.Name;\n\t\t\thandlerName = XamlUtils.EscapeName(handlerName);\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Rewrite/DocumentRewritePass.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Xml.Linq;\n\nnamespace ICSharpCode.BamlDecompiler.Rewrite\n{\n\tinternal class DocumentRewritePass : IRewritePass\n\t{\n\t\tpublic void Run(XamlContext ctx, XDocument document)\n\t\t{\n\t\t\tforeach (var elem in document.Elements(ctx.GetPseudoName(\"Document\")).ToList())\n\t\t\t{\n\t\t\t\tif (elem.Elements().Count() != 1)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tvar docElem = elem.Elements().Single();\n\t\t\t\tforeach (var attr in elem.Attributes())\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(attr.IsNamespaceDeclaration);\n\t\t\t\t\tattr.Remove();\n\t\t\t\t\tdocElem.Add(attr);\n\t\t\t\t}\n\t\t\t\telem.ReplaceWith(docElem);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Rewrite/MarkupExtensionRewritePass.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Xml.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nusing ICSharpCode.BamlDecompiler.Xaml;\n\nnamespace ICSharpCode.BamlDecompiler.Rewrite\n{\n\tinternal class MarkupExtensionRewritePass : IRewritePass\n\t{\n\t\tXName key;\n\t\tXName ctor;\n\n\t\tpublic void Run(XamlContext ctx, XDocument document)\n\t\t{\n\t\t\tkey = ctx.GetKnownNamespace(\"Key\", XamlContext.KnownNamespace_Xaml);\n\t\t\tctor = ctx.GetPseudoName(\"Ctor\");\n\n\t\t\tbool doWork;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tdoWork = false;\n\t\t\t\tforeach (var elem in document.Elements())\n\t\t\t\t{\n\t\t\t\t\tdoWork |= ProcessElement(ctx, elem);\n\t\t\t\t}\n\t\t\t} while (doWork);\n\t\t}\n\n\t\tbool ProcessElement(XamlContext ctx, XElement elem)\n\t\t{\n\t\t\tbool doWork = false;\n\t\t\tforeach (var child in elem.Elements())\n\t\t\t{\n\t\t\t\tdoWork |= RewriteElement(ctx, elem, child);\n\t\t\t\tdoWork |= ProcessElement(ctx, child);\n\t\t\t}\n\t\t\treturn doWork;\n\t\t}\n\n\t\tbool RewriteElement(XamlContext ctx, XElement parent, XElement elem)\n\t\t{\n\t\t\tvar type = parent.Annotation<XamlType>();\n\t\t\tvar property = elem.Annotation<XamlProperty>();\n\n\t\t\tif (elem.Name != key)\n\t\t\t{\n\t\t\t\tif (property == null || type == null)\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (property.ResolvedMember is IProperty { CanSet: false })\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (elem.Elements().Count() != 1 || elem.Attributes().Any(t => t.Name.Namespace != XNamespace.Xmlns))\n\t\t\t\treturn false;\n\n\t\t\tvar value = elem.Elements().Single();\n\n\t\t\tif (!CanInlineExt(ctx, value))\n\t\t\t\treturn false;\n\n\t\t\tvar ext = InlineExtension(ctx, value);\n\t\t\tif (ext == null)\n\t\t\t\treturn false;\n\n\t\t\tctx.CancellationToken.ThrowIfCancellationRequested();\n\n\t\t\tvar extValue = ext.ToString(ctx, parent);\n\n\t\t\tvar attrName = elem.Name;\n\t\t\tif (attrName != key)\n\t\t\t\tattrName = property.ToXName(ctx, parent, property.IsAttachedTo(type));\n\t\t\tif (!parent.Attributes(attrName).Any())\n\t\t\t{\n\t\t\t\tvar attr = new XAttribute(attrName, extValue);\n\t\t\t\tvar list = new List<XAttribute>(parent.Attributes());\n\t\t\t\tif (attrName == key)\n\t\t\t\t\tlist.Insert(0, attr);\n\t\t\t\telse\n\t\t\t\t\tlist.Add(attr);\n\t\t\t\tparent.RemoveAttributes();\n\t\t\t\tparent.ReplaceAttributes(list);\n\t\t\t}\n\t\t\telem.Remove();\n\n\t\t\treturn true;\n\t\t}\n\n\t\tbool CanInlineExt(XamlContext ctx, XElement ctxElement)\n\t\t{\n\t\t\tvar type = ctxElement.Annotation<XamlType>();\n\t\t\tif (type != null && type.ResolvedType != null)\n\t\t\t{\n\t\t\t\tvar typeDef = type.ResolvedType.GetDefinition()?.DirectBaseTypes.FirstOrDefault();\n\t\t\t\tbool isExt = false;\n\t\t\t\twhile (typeDef != null)\n\t\t\t\t{\n\t\t\t\t\tif (typeDef.FullName == \"System.Windows.Markup.MarkupExtension\")\n\t\t\t\t\t{\n\t\t\t\t\t\tisExt = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\ttypeDef = typeDef.DirectBaseTypes.FirstOrDefault();\n\t\t\t\t}\n\t\t\t\tif (!isExt)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (ctxElement.Annotation<XamlProperty>() == null &&\n\t\t\t\t\t ctxElement.Name != ctor)\n\t\t\t\treturn false;\n\n\t\t\tforeach (var child in ctxElement.Elements())\n\t\t\t{\n\t\t\t\tif (!CanInlineExt(ctx, child))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tobject InlineObject(XamlContext ctx, XNode obj)\n\t\t{\n\t\t\tif (obj is XText)\n\t\t\t\treturn ((XText)obj).Value;\n\t\t\telse if (obj is XElement)\n\t\t\t\treturn InlineExtension(ctx, (XElement)obj);\n\t\t\telse\n\t\t\t\treturn null;\n\t\t}\n\n\t\tobject[] InlineCtor(XamlContext ctx, XElement ctor)\n\t\t{\n\t\t\tif (ctor.HasAttributes)\n\t\t\t\treturn null;\n\t\t\tvar args = new List<object>();\n\t\t\tforeach (var child in ctor.Nodes())\n\t\t\t{\n\t\t\t\tvar arg = InlineObject(ctx, child);\n\t\t\t\tif (arg == null)\n\t\t\t\t\treturn null;\n\t\t\t\targs.Add(arg);\n\t\t\t}\n\t\t\treturn args.ToArray();\n\t\t}\n\n\t\tXamlExtension InlineExtension(XamlContext ctx, XElement ctxElement)\n\t\t{\n\t\t\tvar type = ctxElement.Annotation<XamlType>();\n\t\t\tif (type == null)\n\t\t\t\treturn null;\n\n\t\t\tvar ext = new XamlExtension(type);\n\n\t\t\tforeach (var attr in ctxElement.Attributes().Where(attr => attr.Name.Namespace != XNamespace.Xmlns))\n\t\t\t\text.NamedArguments[attr.Name.LocalName] = attr.Value;\n\n\t\t\tforeach (var child in ctxElement.Nodes())\n\t\t\t{\n\t\t\t\tvar elem = child as XElement;\n\t\t\t\tif (elem == null)\n\t\t\t\t\treturn null;\n\n\t\t\t\tif (elem.Name == ctor)\n\t\t\t\t{\n\t\t\t\t\tif (ext.Initializer != null)\n\t\t\t\t\t\treturn null;\n\n\t\t\t\t\tvar args = InlineCtor(ctx, elem);\n\t\t\t\t\tif (args == null)\n\t\t\t\t\t\treturn null;\n\n\t\t\t\t\text.Initializer = args;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tvar property = elem.Annotation<XamlProperty>();\n\t\t\t\tif (property == null || elem.Nodes().Count() != 1 ||\n\t\t\t\t\telem.Attributes().Any(attr => attr.Name.Namespace != XNamespace.Xmlns))\n\t\t\t\t\treturn null;\n\n\t\t\t\tvar name = property.PropertyName;\n\t\t\t\tvar value = InlineObject(ctx, elem.Nodes().Single());\n\t\t\t\text.NamedArguments[name] = value;\n\t\t\t}\n\t\t\treturn ext;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Rewrite/XClassRewritePass.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Linq;\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Xaml;\n\nnamespace ICSharpCode.BamlDecompiler.Rewrite\n{\n\tinternal class XClassRewritePass : IRewritePass\n\t{\n\t\tpublic void Run(XamlContext ctx, XDocument document)\n\t\t{\n\t\t\tforeach (var elem in document.Elements(ctx.GetPseudoName(\"Document\")).Elements())\n\t\t\t\tRewriteClass(ctx, elem);\n\t\t}\n\n\t\tvoid RewriteClass(XamlContext ctx, XElement elem)\n\t\t{\n\t\t\tvar type = elem.Annotation<XamlType>();\n\t\t\tif (type == null || type.ResolvedType == null)\n\t\t\t\treturn;\n\n\t\t\tvar typeDef = type.ResolvedType.GetDefinition();\n\t\t\tif (typeDef == null || !typeDef.ParentModule.IsMainModule)\n\t\t\t\treturn;\n\n\t\t\tvar newType = typeDef.DirectBaseTypes.First().GetDefinition();\n\t\t\tif (newType == null)\n\t\t\t\treturn;\n\t\t\tvar xamlType = new XamlType(newType.ParentModule, newType.ParentModule.FullAssemblyName, newType.Namespace, newType.Name);\n\t\t\txamlType.ResolveNamespace(elem, ctx);\n\n\t\t\telem.Name = xamlType.ToXName(ctx);\n\n\t\t\tvar attrName = ctx.GetKnownNamespace(\"Class\", XamlContext.KnownNamespace_Xaml, elem);\n\n\t\t\tvar attrs = elem.Attributes().ToList();\n\t\t\tif (typeDef.Accessibility != ICSharpCode.Decompiler.TypeSystem.Accessibility.Public)\n\t\t\t{\n\t\t\t\tvar classModifierName = ctx.GetKnownNamespace(\"ClassModifier\", XamlContext.KnownNamespace_Xaml, elem);\n\t\t\t\tattrs.Insert(0, new XAttribute(classModifierName, \"internal\"));\n\t\t\t}\n\t\t\tattrs.Insert(0, new XAttribute(attrName, type.ResolvedType.FullName));\n\t\t\tctx.XClassNames.Add(type.ResolvedType.FullName);\n\t\t\telem.ReplaceAttributes(attrs);\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Xaml/NamespaceMap.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.BamlDecompiler.Xaml\n{\n\tinternal class NamespaceMap\n\t{\n\t\tpublic string XmlnsPrefix { get; set; }\n\t\tpublic string FullAssemblyName { get; set; }\n\t\tpublic string XMLNamespace { get; set; }\n\t\tpublic string CLRNamespace { get; set; }\n\n\t\tpublic NamespaceMap(string prefix, string fullAssemblyName, string xmlNs)\n\t\t\t: this(prefix, fullAssemblyName, xmlNs, null)\n\t\t{\n\t\t}\n\n\t\tpublic NamespaceMap(string prefix, string fullAssemblyName, string xmlNs, string clrNs)\n\t\t{\n\t\t\tXmlnsPrefix = prefix;\n\t\t\tFullAssemblyName = fullAssemblyName;\n\t\t\tXMLNamespace = xmlNs;\n\t\t\tCLRNamespace = clrNs;\n\t\t}\n\n\t\tpublic override string ToString() => $\"{XmlnsPrefix}:[{FullAssemblyName}|{CLRNamespace ?? XMLNamespace}]\";\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Xaml/XamlExtension.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Xml.Linq;\n\nnamespace ICSharpCode.BamlDecompiler.Xaml\n{\n\tinternal class XamlExtension\n\t{\n\t\tpublic XamlType ExtensionType { get; }\n\t\tpublic object[] Initializer { get; set; }\n\t\tpublic IDictionary<string, object> NamedArguments { get; }\n\n\t\tpublic XamlExtension(XamlType type)\n\t\t{\n\t\t\tExtensionType = type;\n\t\t\tNamedArguments = new Dictionary<string, object>();\n\t\t}\n\n\t\tstatic void WriteObject(StringBuilder sb, XamlContext ctx, XElement ctxElement, object value)\n\t\t{\n\t\t\tif (value is XamlExtension)\n\t\t\t\tsb.Append(((XamlExtension)value).ToString(ctx, ctxElement));\n\t\t\telse\n\t\t\t\tsb.Append(value.ToString());\n\t\t}\n\n\t\tpublic string ToString(XamlContext ctx, XElement ctxElement)\n\t\t{\n\t\t\tvar sb = new StringBuilder();\n\t\t\tsb.Append('{');\n\n\t\t\tvar typeName = ctx.ToString(ctxElement, ExtensionType);\n\t\t\tif (typeName.EndsWith(\"Extension\"))\n\t\t\t\tsb.Append(typeName.Substring(0, typeName.Length - 9));\n\t\t\telse\n\t\t\t\tsb.Append(typeName);\n\n\t\t\tbool comma = false;\n\t\t\tif (Initializer != null && Initializer.Length > 0)\n\t\t\t{\n\t\t\t\tsb.Append(' ');\n\t\t\t\tfor (int i = 0; i < Initializer.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tif (comma)\n\t\t\t\t\t\tsb.Append(\", \");\n\t\t\t\t\tWriteObject(sb, ctx, ctxElement, Initializer[i]);\n\t\t\t\t\tcomma = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (NamedArguments.Count > 0)\n\t\t\t{\n\t\t\t\tforeach (var kvp in NamedArguments)\n\t\t\t\t{\n\t\t\t\t\tif (comma)\n\t\t\t\t\t\tsb.Append(\", \");\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tsb.Append(' ');\n\t\t\t\t\t\tcomma = true;\n\t\t\t\t\t}\n\t\t\t\t\tsb.AppendFormat(\"{0}=\", kvp.Key);\n\t\t\t\t\tWriteObject(sb, ctx, ctxElement, kvp.Value);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsb.Append('}');\n\t\t\treturn sb.ToString();\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Xaml/XamlPathDeserializer.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.IO;\nusing System.Text;\n\nnamespace ICSharpCode.BamlDecompiler.Xaml\n{\n\tclass XamlPathDeserializer\n\t{\n\t\tenum PathOpCodes\n\t\t{\n\t\t\tBeginFigure,\n\t\t\tLineTo,\n\t\t\tQuadraticBezierTo,\n\t\t\tBezierTo,\n\t\t\tPolyLineTo,\n\t\t\tPolyQuadraticBezierTo,\n\t\t\tPolyBezierTo,\n\t\t\tArcTo,\n\t\t\tClosed,\n\t\t\tFillRule\n\t\t}\n\n\t\treadonly struct Point\n\t\t{\n\t\t\tpublic readonly double X;\n\t\t\tpublic readonly double Y;\n\n\t\t\tpublic Point(double x, double y)\n\t\t\t{\n\t\t\t\tX = x;\n\t\t\t\tY = y;\n\t\t\t}\n\n\t\t\tpublic override string ToString() => string.Format(CultureInfo.InvariantCulture, \"{0:R},{1:R}\", X, Y);\n\t\t}\n\n\t\tstatic void UnpackBools(byte b, out bool b1, out bool b2, out bool b3, out bool b4)\n\t\t{\n\t\t\tb1 = (b & 0x10) != 0;\n\t\t\tb2 = (b & 0x20) != 0;\n\t\t\tb3 = (b & 0x40) != 0;\n\t\t\tb4 = (b & 0x80) != 0;\n\t\t}\n\n\t\tstatic Point ReadPoint(BinaryReader reader) => new Point(reader.ReadXamlDouble(), reader.ReadXamlDouble());\n\n\t\tstatic void ReadPointBoolBool(BinaryReader reader, byte b, out Point pt, out bool b1, out bool b2)\n\t\t{\n\t\t\tUnpackBools(b, out b1, out b2, out bool sx, out bool sy);\n\n\t\t\tpt = new Point(reader.ReadXamlDouble(sx), reader.ReadXamlDouble(sy));\n\t\t}\n\n\t\tstatic IList<Point> ReadPointsBoolBool(BinaryReader reader, byte b, out bool b1, out bool b2)\n\t\t{\n\t\t\tUnpackBools(b, out b1, out b2, out bool b3, out bool b4);\n\n\t\t\tvar count = reader.ReadInt32();\n\t\t\tvar pts = new List<Point>();\n\t\t\tfor (int i = 0; i < count; i++)\n\t\t\t\tpts.Add(ReadPoint(reader));\n\n\t\t\treturn pts;\n\t\t}\n\n\t\tpublic static string Deserialize(BinaryReader reader)\n\t\t{\n\t\t\tbool end = false;\n\t\t\tvar sb = new StringBuilder();\n\n\t\t\tPoint pt1, pt2, pt3;\n\t\t\tIList<Point> pts;\n\n\t\t\twhile (!end)\n\t\t\t{\n\t\t\t\tvar b = reader.ReadByte();\n\n\t\t\t\tswitch ((PathOpCodes)(b & 0xf))\n\t\t\t\t{\n\t\t\t\t\tcase PathOpCodes.BeginFigure:\n\t\t\t\t\t{\n\t\t\t\t\t\tReadPointBoolBool(reader, b, out pt1, out bool filled, out bool closed);\n\n\t\t\t\t\t\tsb.AppendFormat(\"M{0} \", pt1);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase PathOpCodes.LineTo:\n\t\t\t\t\t{\n\t\t\t\t\t\tReadPointBoolBool(reader, b, out pt1, out bool stroked, out bool smoothJoin);\n\n\t\t\t\t\t\tsb.AppendFormat(\"L{0} \", pt1);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase PathOpCodes.QuadraticBezierTo:\n\t\t\t\t\t{\n\t\t\t\t\t\tReadPointBoolBool(reader, b, out pt1, out bool stroked, out bool smoothJoin);\n\t\t\t\t\t\tpt2 = ReadPoint(reader);\n\n\t\t\t\t\t\tsb.AppendFormat(\"Q{0} {1} \", pt1, pt2);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase PathOpCodes.BezierTo:\n\t\t\t\t\t{\n\t\t\t\t\t\tReadPointBoolBool(reader, b, out pt1, out bool stroked, out bool smoothJoin);\n\t\t\t\t\t\tpt2 = ReadPoint(reader);\n\t\t\t\t\t\tpt3 = ReadPoint(reader);\n\n\t\t\t\t\t\tsb.AppendFormat(\"C{0} {1} {2} \", pt1, pt2, pt3);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase PathOpCodes.PolyLineTo:\n\t\t\t\t\t{\n\t\t\t\t\t\tpts = ReadPointsBoolBool(reader, b, out bool stroked, out bool smoothJoin);\n\n\t\t\t\t\t\tsb.Append('L');\n\t\t\t\t\t\tforeach (var pt in pts)\n\t\t\t\t\t\t\tsb.AppendFormat(\"{0} \", pt);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase PathOpCodes.PolyQuadraticBezierTo:\n\t\t\t\t\t{\n\t\t\t\t\t\tpts = ReadPointsBoolBool(reader, b, out bool stroked, out bool smoothJoin);\n\n\t\t\t\t\t\tsb.Append('Q');\n\t\t\t\t\t\tforeach (var pt in pts)\n\t\t\t\t\t\t\tsb.AppendFormat(\"{0} \", pt);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase PathOpCodes.PolyBezierTo:\n\t\t\t\t\t{\n\t\t\t\t\t\tpts = ReadPointsBoolBool(reader, b, out bool stroked, out bool smoothJoin);\n\n\t\t\t\t\t\tsb.Append('C');\n\t\t\t\t\t\tforeach (var pt in pts)\n\t\t\t\t\t\t\tsb.AppendFormat(\"{0} \", pt);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase PathOpCodes.ArcTo:\n\t\t\t\t\t{\n\t\t\t\t\t\tReadPointBoolBool(reader, b, out pt1, out bool stroked, out bool smoothJoin);\n\t\t\t\t\t\tbyte b2 = reader.ReadByte();\n\t\t\t\t\t\tbool largeArc = (b2 & 0x0f) != 0;\n\t\t\t\t\t\tbool sweepDirection = (b2 & 0xf0) != 0;\n\t\t\t\t\t\tvar size = ReadPoint(reader);\n\t\t\t\t\t\tdouble angle = reader.ReadXamlDouble();\n\n\t\t\t\t\t\tsb.AppendFormat(CultureInfo.InvariantCulture, \"A{0} {1:R} {2} {3} {4}\",\n\t\t\t\t\t\t\tsize, angle, largeArc ? '1' : '0', sweepDirection ? '1' : '0', pt1);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase PathOpCodes.Closed:\n\t\t\t\t\t\tend = true;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase PathOpCodes.FillRule:\n\t\t\t\t\t{\n\t\t\t\t\t\tUnpackBools(b, out bool fillRule, out bool b2, out bool b3, out bool b4);\n\t\t\t\t\t\tif (fillRule)\n\t\t\t\t\t\t\tsb.Insert(0, \"F1 \");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn sb.ToString().Trim();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Xaml/XamlProperty.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Linq;\nusing System.Xml;\nusing System.Xml.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.BamlDecompiler.Xaml\n{\n\tinternal class XamlProperty\n\t{\n\t\tpublic XamlType DeclaringType { get; }\n\t\tpublic string PropertyName { get; }\n\n\t\tpublic IMember ResolvedMember { get; set; }\n\n\t\tpublic XamlProperty(XamlType type, string name)\n\t\t{\n\t\t\tDeclaringType = type;\n\t\t\tPropertyName = name;\n\t\t}\n\n\t\tpublic void TryResolve()\n\t\t{\n\t\t\tif (ResolvedMember != null)\n\t\t\t\treturn;\n\n\t\t\tvar typeDef = DeclaringType.ResolvedType.GetDefinition();\n\t\t\tif (typeDef == null)\n\t\t\t\treturn;\n\n\t\t\tResolvedMember = typeDef.GetProperties(p => p.Name == PropertyName).FirstOrDefault();\n\t\t\tif (ResolvedMember != null)\n\t\t\t\treturn;\n\n\t\t\tResolvedMember = typeDef.GetFields(f => f.Name == PropertyName + \"Property\").FirstOrDefault();\n\t\t\tif (ResolvedMember != null)\n\t\t\t\treturn;\n\n\t\t\tResolvedMember = typeDef.GetEvents(e => e.Name == PropertyName).FirstOrDefault();\n\t\t\tif (ResolvedMember != null)\n\t\t\t\treturn;\n\n\t\t\tResolvedMember = typeDef.GetFields(f => f.Name == PropertyName + \"Event\").FirstOrDefault();\n\t\t}\n\n\t\tpublic bool IsAttachedTo(XamlType type)\n\t\t{\n\t\t\tif (type == null || ResolvedMember == null || type.ResolvedType == null)\n\t\t\t\treturn true;\n\n\t\t\tvar declType = ResolvedMember.DeclaringType;\n\t\t\tvar t = type.ResolvedType;\n\n\t\t\tdo\n\t\t\t{\n\t\t\t\tif (t.FullName == declType.FullName && t.TypeParameterCount == declType.TypeParameterCount)\n\t\t\t\t\treturn false;\n\t\t\t\tt = t.DirectBaseTypes.FirstOrDefault();\n\t\t\t} while (t != null);\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic XName ToXName(XamlContext ctx, XElement parent, bool isFullName = true)\n\t\t{\n\t\t\tvar typeName = DeclaringType.ToXName(ctx);\n\t\t\tXName name;\n\t\t\tif (!isFullName)\n\t\t\t\tname = XmlConvert.EncodeLocalName(PropertyName);\n\t\t\telse\n\t\t\t{\n\t\t\t\tname = typeName.LocalName + \".\" + XmlConvert.EncodeLocalName(PropertyName);\n\t\t\t\tif (parent == null || parent.GetDefaultNamespace() != typeName.Namespace)\n\t\t\t\t\tname = typeName.Namespace + name.LocalName;\n\t\t\t}\n\n\t\t\treturn name;\n\t\t}\n\n\t\tpublic override string ToString() => PropertyName;\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Xaml/XamlResourceKey.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\n\nusing ICSharpCode.BamlDecompiler.Baml;\n\nnamespace ICSharpCode.BamlDecompiler.Xaml\n{\n\tinternal class XamlResourceKey\n\t{\n\t\tXamlResourceKey(BamlNode node)\n\t\t{\n\t\t\tKeyNode = node;\n\t\t\tStaticResources = new List<BamlNode>();\n\n\t\t\tIBamlDeferRecord keyRecord;\n\t\t\tif (node is BamlBlockNode)\n\t\t\t\tkeyRecord = (IBamlDeferRecord)((BamlBlockNode)node).Header;\n\t\t\telse\n\t\t\t\tkeyRecord = (IBamlDeferRecord)((BamlRecordNode)node).Record;\n\n\t\t\tif (keyRecord.Record.Type == BamlRecordType.ElementEnd)\n\t\t\t{\n\t\t\t\tDebug.Assert(node.Parent.Footer == keyRecord.Record);\n\t\t\t\tnode.Parent.Annotation = this;\n\t\t\t\tnode.Annotation = this;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (keyRecord.Record.Type != BamlRecordType.ElementStart && node.Parent.Type == BamlRecordType.ElementStart)\n\t\t\t{\n\t\t\t\tnode.Parent.Annotation = this;\n\t\t\t\tnode.Annotation = this;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (keyRecord.Record.Type != BamlRecordType.ElementStart)\n\t\t\t{\n\t\t\t\tDebug.WriteLine($\"Key record @{keyRecord.Position} must be attached to ElementStart (actual {keyRecord.Record.Type})\");\n\t\t\t}\n\n\t\t\tforeach (var child in node.Parent.Children)\n\t\t\t{\n\t\t\t\tif (child.Record != keyRecord.Record)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tchild.Annotation = this;\n\t\t\t\tnode.Annotation = this;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tDebug.WriteLine(\"Cannot find corresponding value element of key record @\" + keyRecord.Position);\n\t\t}\n\n\t\tpublic static XamlResourceKey Create(BamlNode node) => new XamlResourceKey(node);\n\n\t\tpublic BamlNode KeyNode { get; set; }\n\t\tpublic BamlElement KeyElement { get; set; }\n\t\tpublic IList<BamlNode> StaticResources { get; }\n\n\t\tpublic static XamlResourceKey FindKeyInSiblings(BamlNode node)\n\t\t{\n\t\t\tvar children = node.Parent.Children;\n\t\t\tvar index = children.IndexOf(node);\n\t\t\tfor (int i = index; i >= 0; i--)\n\t\t\t{\n\t\t\t\tif (children[i].Annotation is XamlResourceKey)\n\t\t\t\t\treturn (XamlResourceKey)children[i].Annotation;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static XamlResourceKey FindKeyInAncestors(BamlNode node) => FindKeyInAncestors(node, out var found);\n\n\t\tpublic static XamlResourceKey FindKeyInAncestors(BamlNode node, out BamlNode found)\n\t\t{\n\t\t\tBamlNode n = node;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tif (n.Annotation is XamlResourceKey)\n\t\t\t\t{\n\t\t\t\t\tfound = n;\n\t\t\t\t\treturn (XamlResourceKey)n.Annotation;\n\t\t\t\t}\n\t\t\t\tn = n.Parent;\n\t\t\t} while (n != null);\n\t\t\tfound = null;\n\t\t\treturn null;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Xaml/XamlType.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Xml;\nusing System.Xml.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.BamlDecompiler.Xaml\n{\n\tinternal class XamlType\n\t{\n\t\t/// <summary>\n\t\t/// Assembly that contains the type defintion. Can be null.\n\t\t/// </summary>\n\t\tpublic IModule Assembly { get; }\n\t\tpublic string FullAssemblyName { get; }\n\t\tpublic string TypeNamespace { get; }\n\t\tpublic string TypeName { get; }\n\n\t\tpublic XNamespace Namespace { get; private set; }\n\t\tpublic IType ResolvedType { get; set; }\n\n\t\tpublic XamlType(IModule assembly, string fullAssemblyName, string ns, string name)\n\t\t\t: this(assembly, fullAssemblyName, ns, name, null)\n\t\t{\n\t\t}\n\n\t\tpublic XamlType(IModule assembly, string fullAssemblyName, string ns, string name, XNamespace xmlns)\n\t\t{\n\t\t\tAssembly = assembly;\n\t\t\tFullAssemblyName = fullAssemblyName;\n\t\t\tTypeNamespace = ns;\n\t\t\tTypeName = name;\n\t\t\tNamespace = xmlns;\n\t\t}\n\n\t\tpublic void ResolveNamespace(XElement elem, XamlContext ctx)\n\t\t{\n\t\t\tif (Namespace != null)\n\t\t\t\treturn;\n\n\t\t\t// Since XmlnsProperty records are inside the element,\n\t\t\t// the namespace is resolved after processing the element body.\n\n\t\t\tstring xmlNs = null;\n\t\t\tif (elem.Annotation<XmlnsScope>() != null)\n\t\t\t\txmlNs = elem.Annotation<XmlnsScope>().LookupXmlns(FullAssemblyName, TypeNamespace);\n\t\t\tif (xmlNs == null)\n\t\t\t\txmlNs = ctx.XmlNs.LookupXmlns(FullAssemblyName, TypeNamespace);\n\t\t\t// Sometimes there's no reference to System.Xaml even if x:Type is used\n\t\t\tif (xmlNs == null)\n\t\t\t\txmlNs = ctx.TryGetXmlNamespace(Assembly, TypeNamespace);\n\n\t\t\tif (xmlNs == null)\n\t\t\t{\n\t\t\t\tif (FullAssemblyName == ctx.TypeSystem.MainModule.FullAssemblyName)\n\t\t\t\t\txmlNs = $\"clr-namespace:{TypeNamespace}\";\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar name = ICSharpCode.Decompiler.Metadata.AssemblyNameReference.Parse(FullAssemblyName);\n\t\t\t\t\txmlNs = $\"clr-namespace:{TypeNamespace};assembly={name.Name}\";\n\t\t\t\t}\n\n\t\t\t\tvar nsSeg = TypeNamespace.Split('.');\n\t\t\t\tvar prefix = nsSeg[nsSeg.Length - 1].ToLowerInvariant();\n\t\t\t\tif (string.IsNullOrEmpty(prefix))\n\t\t\t\t{\n\t\t\t\t\tif (string.IsNullOrEmpty(TypeNamespace))\n\t\t\t\t\t\tprefix = \"global\";\n\t\t\t\t\telse\n\t\t\t\t\t\tprefix = \"empty\";\n\t\t\t\t}\n\t\t\t\tint count = 0;\n\t\t\t\tvar truePrefix = prefix;\n\t\t\t\tXNamespace prefixNs, ns = ctx.GetXmlNamespace(xmlNs);\n\t\t\t\twhile ((prefixNs = elem.GetNamespaceOfPrefix(truePrefix)) != null && prefixNs != ns)\n\t\t\t\t{\n\t\t\t\t\tcount++;\n\t\t\t\t\ttruePrefix = prefix + count;\n\t\t\t\t}\n\n\t\t\t\tif (prefixNs == null)\n\t\t\t\t{\n\t\t\t\t\telem.Add(new XAttribute(XNamespace.Xmlns + XmlConvert.EncodeLocalName(truePrefix), ns));\n\t\t\t\t\tif (string.IsNullOrEmpty(TypeNamespace))\n\t\t\t\t\t\telem.AddBeforeSelf(new XComment(string.Format(\"'{0}' is prefix for the global namespace\", truePrefix)));\n\t\t\t\t}\n\t\t\t}\n\t\t\tNamespace = ctx.GetXmlNamespace(xmlNs);\n\t\t}\n\n\t\tpublic XName ToXName(XamlContext ctx)\n\t\t{\n\t\t\tif (Namespace == null)\n\t\t\t\treturn XmlConvert.EncodeLocalName(TypeName);\n\t\t\treturn Namespace + XmlConvert.EncodeLocalName(TypeName);\n\t\t}\n\n\t\tpublic override string ToString() => TypeName;\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/Xaml/XamlUtils.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.IO;\nusing System.Text;\nusing System.Xml.Linq;\n\nnamespace ICSharpCode.BamlDecompiler.Xaml\n{\n\tinternal static class XamlUtils\n\t{\n\t\tpublic static string Escape(string value)\n\t\t{\n\t\t\tif (value.Length == 0)\n\t\t\t\treturn value;\n\t\t\tif (value[0] == '{')\n\t\t\t\treturn \"{}\" + value;\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic static string ToString(this XamlContext ctx, XElement elem, XamlType type)\n\t\t{\n\t\t\ttype.ResolveNamespace(elem, ctx);\n\t\t\treturn ctx.ToString(elem, type.ToXName(ctx));\n\t\t}\n\n\t\tpublic static string ToString(this XamlContext ctx, XElement elem, XName name)\n\t\t{\n\t\t\tvar sb = new StringBuilder();\n\t\t\tif (name.Namespace != elem.GetDefaultNamespace())\n\t\t\t{\n\t\t\t\tvar prefix = elem.GetPrefixOfNamespace(name.Namespace);\n\t\t\t\tif (!string.IsNullOrEmpty(prefix))\n\t\t\t\t{\n\t\t\t\t\tsb.Append(prefix);\n\t\t\t\t\tsb.Append(':');\n\t\t\t\t}\n\t\t\t}\n\t\t\tsb.Append(name.LocalName);\n\t\t\treturn sb.ToString();\n\t\t}\n\n\t\tpublic static double ReadXamlDouble(this BinaryReader reader, bool scaledInt = false)\n\t\t{\n\t\t\tif (!scaledInt)\n\t\t\t{\n\t\t\t\tswitch (reader.ReadByte())\n\t\t\t\t{\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\treturn 0;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\treturn -1;\n\t\t\t\t\tcase 4:\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 5:\n\t\t\t\t\t\treturn reader.ReadDouble();\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new InvalidDataException(\"Unknown double type.\");\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Dividing by 1000000.0 is important to get back the original numbers, we can't\n\t\t\t// multiply by the inverse of it (0.000001).\n\t\t\t// (11700684 * 0.000001) != (11700684 / 1000000.0) => 11.700683999999999 != 11.700684\n\t\t\treturn reader.ReadInt32() / 1000000.0;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Escape characters that cannot be used in XML.\n\t\t/// </summary>\n\t\tpublic static StringBuilder EscapeName(StringBuilder sb, string name)\n\t\t{\n\t\t\tforeach (char ch in name)\n\t\t\t{\n\t\t\t\tif (char.IsWhiteSpace(ch) || char.IsControl(ch) || char.IsSurrogate(ch))\n\t\t\t\t\tsb.AppendFormat(\"\\\\u{0:x4}\", (int)ch);\n\t\t\t\telse\n\t\t\t\t\tsb.Append(ch);\n\t\t\t}\n\t\t\treturn sb;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Escape characters that cannot be displayed in the UI.\n\t\t/// </summary>\n\t\tpublic static string EscapeName(string name)\n\t\t{\n\t\t\treturn EscapeName(new StringBuilder(name.Length), name).ToString();\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/XamlContext.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Threading;\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler.Baml;\nusing ICSharpCode.BamlDecompiler.Xaml;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.BamlDecompiler\n{\n\tinternal class XamlContext\n\t{\n\t\tXamlContext(IDecompilerTypeSystem typeSystem)\n\t\t{\n\t\t\tTypeSystem = typeSystem;\n\t\t\tNodeMap = new Dictionary<BamlRecord, BamlBlockNode>();\n\t\t\tXmlNs = new XmlnsDictionary();\n\t\t\tGeneratedMembers = new List<EntityHandle>();\n\t\t\tXClassNames = new List<string>();\n\t\t}\n\n\t\tDictionary<ushort, XamlType> typeMap = new Dictionary<ushort, XamlType>();\n\t\tDictionary<ushort, XamlProperty> propertyMap = new Dictionary<ushort, XamlProperty>();\n\t\tDictionary<string, XNamespace> xmlnsMap = new Dictionary<string, XNamespace>();\n\n\t\tpublic IDecompilerTypeSystem TypeSystem { get; }\n\t\tpublic CancellationToken CancellationToken { get; private set; }\n\t\tpublic BamlDecompilerSettings Settings { get; private set; }\n\n\t\tpublic BamlContext Baml { get; private set; }\n\t\tpublic BamlNode RootNode { get; private set; }\n\t\tpublic IDictionary<BamlRecord, BamlBlockNode> NodeMap { get; }\n\n\t\tpublic List<string> XClassNames { get; }\n\n\t\tpublic List<EntityHandle> GeneratedMembers { get; }\n\n\t\tpublic XmlnsDictionary XmlNs { get; }\n\n\t\tpublic static XamlContext Construct(IDecompilerTypeSystem typeSystem, BamlDocument document, CancellationToken token, BamlDecompilerSettings bamlDecompilerOptions)\n\t\t{\n\t\t\tvar ctx = new XamlContext(typeSystem);\n\t\t\tctx.CancellationToken = token;\n\t\t\tctx.Settings = bamlDecompilerOptions ?? new BamlDecompilerSettings();\n\n\t\t\tctx.Baml = BamlContext.ConstructContext(typeSystem, document, token);\n\t\t\tctx.RootNode = BamlNode.Parse(document, token);\n\n\t\t\tctx.BuildPIMappings(document);\n\t\t\tctx.BuildNodeMap(ctx.RootNode as BamlBlockNode);\n\n\t\t\treturn ctx;\n\t\t}\n\n\t\tvoid BuildNodeMap(BamlBlockNode node)\n\t\t{\n\t\t\tif (node == null)\n\t\t\t\treturn;\n\n\t\t\tNodeMap[node.Header] = node;\n\n\t\t\tforeach (var child in node.Children)\n\t\t\t{\n\t\t\t\tif (child is BamlBlockNode childBlock)\n\t\t\t\t\tBuildNodeMap(childBlock);\n\t\t\t}\n\t\t}\n\n\t\tvoid BuildPIMappings(BamlDocument document)\n\t\t{\n\t\t\tforeach (var record in document)\n\t\t\t{\n\t\t\t\tvar piMap = record as PIMappingRecord;\n\t\t\t\tif (piMap == null)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tXmlNs.SetPIMapping(piMap.XmlNamespace, piMap.ClrNamespace, Baml.ResolveAssembly(piMap.AssemblyId).FullAssemblyName);\n\t\t\t}\n\t\t}\n\n\t\tpublic XamlType ResolveType(ushort id)\n\t\t{\n\t\t\tif (typeMap.TryGetValue(id, out var xamlType))\n\t\t\t\treturn xamlType;\n\n\t\t\tIType type;\n\t\t\tIModule assembly;\n\t\t\tstring fullAssemblyName;\n\n\t\t\tif (id > 0x7fff)\n\t\t\t{\n\t\t\t\ttype = Baml.KnownThings.Types((KnownTypes)(short)-unchecked((short)id));\n\t\t\t\tassembly = type.GetDefinition().ParentModule;\n\t\t\t\tfullAssemblyName = assembly.FullAssemblyName;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar typeRec = Baml.TypeIdMap[id];\n\t\t\t\t(fullAssemblyName, assembly) = Baml.ResolveAssembly(typeRec.AssemblyId);\n\t\t\t\ttype = ReflectionHelper.ParseReflectionName(typeRec.TypeFullName, new SimpleTypeResolveContext(TypeSystem));\n\t\t\t}\n\n\t\t\tvar clrNs = type.Namespace;\n\t\t\tvar xmlNs = XmlNs.LookupXmlns(fullAssemblyName, clrNs);\n\n\t\t\ttypeMap[id] = xamlType = new XamlType(assembly, fullAssemblyName, clrNs, type.Name, GetXmlNamespace(xmlNs)) {\n\t\t\t\tResolvedType = type\n\t\t\t};\n\n\t\t\treturn xamlType;\n\t\t}\n\n\t\tpublic XamlProperty ResolveProperty(ushort id)\n\t\t{\n\t\t\tif (propertyMap.TryGetValue(id, out var xamlProp))\n\t\t\t\treturn xamlProp;\n\n\t\t\tXamlType type;\n\t\t\tstring name;\n\t\t\tIMember member;\n\n\t\t\tif (id > 0x7fff)\n\t\t\t{\n\t\t\t\tvar knownProp = Baml.KnownThings.Members((KnownMembers)unchecked((short)-(short)id));\n\t\t\t\ttype = ResolveType(unchecked((ushort)(short)-(short)knownProp.Parent));\n\t\t\t\tname = knownProp.Name;\n\t\t\t\tmember = knownProp.Property;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar attrRec = Baml.AttributeIdMap[id];\n\t\t\t\ttype = ResolveType(attrRec.OwnerTypeId);\n\t\t\t\tname = attrRec.Name;\n\n\t\t\t\tmember = null;\n\t\t\t}\n\n\t\t\tpropertyMap[id] = xamlProp = new XamlProperty(type, name) {\n\t\t\t\tResolvedMember = member\n\t\t\t};\n\t\t\txamlProp.TryResolve();\n\n\t\t\treturn xamlProp;\n\t\t}\n\n\t\tpublic string ResolveString(ushort id)\n\t\t{\n\t\t\tif (id > 0x7fff)\n\t\t\t\treturn Baml.KnownThings.Strings(unchecked((short)-id));\n\t\t\telse if (Baml.StringIdMap.ContainsKey(id))\n\t\t\t\treturn Baml.StringIdMap[id].Value;\n\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic XNamespace GetXmlNamespace(string xmlns)\n\t\t{\n\t\t\tif (xmlns == null)\n\t\t\t\treturn null;\n\n\t\t\tif (!xmlnsMap.TryGetValue(xmlns, out var ns))\n\t\t\t\txmlnsMap[xmlns] = ns = XNamespace.Get(xmlns);\n\t\t\treturn ns;\n\t\t}\n\n\t\tpublic const string KnownNamespace_Xaml = \"http://schemas.microsoft.com/winfx/2006/xaml\";\n\t\tpublic const string KnownNamespace_Presentation = \"http://schemas.microsoft.com/winfx/2006/xaml/presentation\";\n\t\tpublic const string KnownNamespace_PresentationOptions = \"http://schemas.microsoft.com/winfx/2006/xaml/presentation/options\";\n\n\t\tpublic string TryGetXmlNamespace(IModule assembly, string typeNamespace)\n\t\t{\n\t\t\tif (assembly == null)\n\t\t\t\treturn null;\n\n\t\t\tHashSet<string> possibleXmlNs = new HashSet<string>();\n\n\t\t\tforeach (var attr in assembly.GetAssemblyAttributes().Where(a => a.AttributeType.FullName == \"System.Windows.Markup.XmlnsDefinitionAttribute\"))\n\t\t\t{\n\t\t\t\tDebug.Assert(attr.FixedArguments.Length == 2);\n\t\t\t\tif (attr.FixedArguments.Length != 2)\n\t\t\t\t\tcontinue;\n\t\t\t\tvar xmlNs = attr.FixedArguments[0].Value as string;\n\t\t\t\tvar typeNs = attr.FixedArguments[1].Value as string;\n\t\t\t\tDebug.Assert((object)xmlNs != null && (object)typeNs != null);\n\t\t\t\tif ((object)xmlNs == null || (object)typeNs == null)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (typeNamespace == typeNs)\n\t\t\t\t\tpossibleXmlNs.Add(xmlNs);\n\t\t\t}\n\n\t\t\tif (possibleXmlNs.Contains(KnownNamespace_Presentation))\n\t\t\t\treturn KnownNamespace_Presentation;\n\n\t\t\treturn possibleXmlNs.FirstOrDefault();\n\t\t}\n\n\t\tpublic XName GetKnownNamespace(string name, string xmlNamespace, XElement context = null)\n\t\t{\n\t\t\tvar xNs = GetXmlNamespace(xmlNamespace);\n\t\t\tXName xName;\n\t\t\tif (context != null && xNs == context.GetDefaultNamespace())\n\t\t\t\txName = name;\n\t\t\telse\n\t\t\t\txName = xNs + name;\n\t\t\treturn xName;\n\t\t}\n\n\t\tpublic XName GetPseudoName(string name) => XNamespace.Get(\"https://github.com/icsharpcode/ILSpy\").GetName(name);\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/XamlDecompiler.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.PortableExecutable;\nusing System.Threading;\nusing System.Xml.Linq;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nusing ICSharpCode.BamlDecompiler.Baml;\nusing ICSharpCode.BamlDecompiler.Rewrite;\n\nnamespace ICSharpCode.BamlDecompiler\n{\n\tpublic class XamlDecompiler\n\t{\n\t\tstatic readonly IRewritePass[] rewritePasses = new IRewritePass[] {\n\t\t\tnew XClassRewritePass(),\n\t\t\tnew MarkupExtensionRewritePass(),\n\t\t\tnew AttributeRewritePass(),\n\t\t\tnew ConnectionIdRewritePass(),\n\t\t\tnew DocumentRewritePass(),\n\t\t};\n\n\t\tprivate BamlDecompilerTypeSystem typeSystem;\n\t\tprivate BamlDecompilerSettings settings;\n\t\tprivate MetadataModule module;\n\n\t\tpublic BamlDecompilerSettings Settings {\n\t\t\tget { return settings; }\n\t\t\tset { settings = value; }\n\t\t}\n\n\t\tpublic CancellationToken CancellationToken { get; set; }\n\n\t\tpublic XamlDecompiler(string fileName, BamlDecompilerSettings settings)\n\t\t\t: this(CreateTypeSystemFromFile(fileName, settings), settings)\n\t\t{\n\t\t}\n\n\t\tpublic XamlDecompiler(string fileName, IAssemblyResolver assemblyResolver, BamlDecompilerSettings settings)\n\t\t\t: this(LoadPEFile(fileName, settings), assemblyResolver, settings)\n\t\t{\n\t\t}\n\n\t\tpublic XamlDecompiler(PEFile module, IAssemblyResolver assemblyResolver, BamlDecompilerSettings settings)\n\t\t\t: this(new BamlDecompilerTypeSystem(module, assemblyResolver), settings)\n\t\t{\n\t\t}\n\n\t\tpublic XamlDecompiler(BamlDecompilerTypeSystem typeSystem, BamlDecompilerSettings settings)\n\t\t{\n\t\t\tthis.typeSystem = typeSystem ?? throw new ArgumentNullException(nameof(typeSystem));\n\t\t\tthis.settings = settings;\n\t\t\tthis.module = typeSystem.MainModule;\n\t\t\tif (module.TypeSystemOptions.HasFlag(TypeSystemOptions.Uncached))\n\t\t\t\tthrow new ArgumentException(\"Cannot use an uncached type system in the decompiler.\");\n\t\t}\n\n\t\tstatic PEFile LoadPEFile(string fileName, BamlDecompilerSettings settings)\n\t\t{\n\t\t\treturn new PEFile(\n\t\t\t\tfileName,\n\t\t\t\tnew FileStream(fileName, FileMode.Open, FileAccess.Read),\n\t\t\t\tstreamOptions: PEStreamOptions.PrefetchEntireImage,\n\t\t\t\tmetadataOptions: MetadataReaderOptions.None\n\t\t\t);\n\t\t}\n\n\t\tstatic BamlDecompilerTypeSystem CreateTypeSystemFromFile(string fileName, BamlDecompilerSettings settings)\n\t\t{\n\t\t\tvar file = LoadPEFile(fileName, settings);\n\t\t\tvar resolver = new UniversalAssemblyResolver(fileName, settings.ThrowOnAssemblyResolveErrors,\n\t\t\t\tfile.DetectTargetFrameworkId(), file.DetectRuntimePack(),\n\t\t\t\tPEStreamOptions.PrefetchMetadata,\n\t\t\t\tMetadataReaderOptions.None);\n\t\t\treturn new BamlDecompilerTypeSystem(file, resolver);\n\t\t}\n\n\t\tpublic BamlDecompilationResult Decompile(Stream stream)\n\t\t{\n\t\t\tvar ct = CancellationToken;\n\t\t\tvar document = BamlReader.ReadDocument(stream, ct);\n\t\t\tvar ctx = XamlContext.Construct(typeSystem, document, ct, settings);\n\n\t\t\tvar handler = HandlerMap.LookupHandler(ctx.RootNode.Type);\n\t\t\tvar elem = handler.Translate(ctx, ctx.RootNode, null);\n\n\t\t\tvar xaml = new XDocument();\n\t\t\txaml.Add(elem.Xaml.Element);\n\n\t\t\tforeach (var pass in rewritePasses)\n\t\t\t{\n\t\t\t\tct.ThrowIfCancellationRequested();\n\t\t\t\tpass.Run(ctx, xaml);\n\t\t\t}\n\n\t\t\tvar assemblyReferences = ctx.Baml.AssemblyIdMap.Select(a => a.Value.AssemblyFullName);\n\t\t\tvar typeName = ctx.XClassNames.FirstOrDefault() is string s ? (FullTypeName?)new FullTypeName(s) : null;\n\t\t\treturn new BamlDecompilationResult(xaml, typeName, assemblyReferences, ctx.GeneratedMembers);\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/XmlnsDictionary.cs",
    "content": "/*\n\tCopyright (c) 2015 Ki\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy\n\tof this software and associated documentation files (the \"Software\"), to deal\n\tin the Software without restriction, including without limitation the rights\n\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\tcopies of the Software, and to permit persons to whom the Software is\n\tfurnished to do so, subject to the following conditions:\n\n\tThe above copyright notice and this permission notice shall be included in\n\tall copies or substantial portions of the Software.\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\tTHE SOFTWARE.\n*/\n\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nusing ICSharpCode.BamlDecompiler.Xaml;\n\nnamespace ICSharpCode.BamlDecompiler\n{\n\tinternal class XmlnsScope : List<NamespaceMap>\n\t{\n\t\tpublic BamlElement Element { get; }\n\t\tpublic XmlnsScope PreviousScope { get; }\n\n\t\tpublic XmlnsScope(XmlnsScope prev, BamlElement elem)\n\t\t{\n\t\t\tPreviousScope = prev;\n\t\t\tElement = elem;\n\t\t}\n\n\t\tpublic string LookupXmlns(string fullAssemblyName, string clrNs)\n\t\t{\n\t\t\tforeach (var ns in this)\n\t\t\t{\n\t\t\t\tif (fullAssemblyName == ns.FullAssemblyName && ns.CLRNamespace == clrNs)\n\t\t\t\t\treturn ns.XMLNamespace;\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tinternal class XmlnsDictionary\n\t{\n\t\tDictionary<string, NamespaceMap> piMappings = new Dictionary<string, NamespaceMap>();\n\n\t\tpublic XmlnsDictionary() => CurrentScope = null;\n\n\t\tpublic XmlnsScope CurrentScope { get; set; }\n\n\t\tpublic void PushScope(BamlElement element) => CurrentScope = new XmlnsScope(CurrentScope, element);\n\n\t\tpublic void PopScope() => CurrentScope = CurrentScope.PreviousScope;\n\n\t\tpublic void Add(NamespaceMap map) => CurrentScope.Add(map);\n\n\t\tpublic void SetPIMapping(string xmlNs, string clrNs, string fullAssemblyName)\n\t\t{\n\t\t\tif (!piMappings.ContainsKey(xmlNs))\n\t\t\t{\n\t\t\t\tvar map = new NamespaceMap(null, fullAssemblyName, xmlNs, clrNs);\n\t\t\t\tpiMappings[xmlNs] = map;\n\t\t\t}\n\t\t}\n\n\t\tNamespaceMap PIFixup(NamespaceMap map)\n\t\t{\n\t\t\tif (piMappings.TryGetValue(map.XMLNamespace, out var piMap))\n\t\t\t{\n\t\t\t\tmap.FullAssemblyName = piMap.FullAssemblyName;\n\t\t\t\tmap.CLRNamespace = piMap.CLRNamespace;\n\t\t\t}\n\t\t\treturn map;\n\t\t}\n\n\t\tpublic NamespaceMap LookupNamespaceFromPrefix(string prefix)\n\t\t{\n\t\t\tvar scope = CurrentScope;\n\t\t\twhile (scope != null)\n\t\t\t{\n\t\t\t\tforeach (var ns in scope)\n\t\t\t\t{\n\t\t\t\t\tif (ns.XmlnsPrefix == prefix)\n\t\t\t\t\t\treturn PIFixup(ns);\n\t\t\t\t}\n\n\t\t\t\tscope = scope.PreviousScope;\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic NamespaceMap LookupNamespaceFromXmlns(string xmlNs)\n\t\t{\n\t\t\tvar scope = CurrentScope;\n\t\t\twhile (scope != null)\n\t\t\t{\n\t\t\t\tforeach (var ns in scope)\n\t\t\t\t{\n\t\t\t\t\tif (ns.XMLNamespace == xmlNs)\n\t\t\t\t\t\treturn ns;\n\t\t\t\t}\n\n\t\t\t\tscope = scope.PreviousScope;\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic string LookupXmlns(string fullAssemblyName, string clrNs)\n\t\t{\n\t\t\tforeach (var map in piMappings)\n\t\t\t{\n\t\t\t\tif (fullAssemblyName == map.Value.FullAssemblyName && map.Value.CLRNamespace == clrNs)\n\t\t\t\t\treturn map.Key;\n\t\t\t}\n\n\t\t\tvar scope = CurrentScope;\n\t\t\twhile (scope != null)\n\t\t\t{\n\t\t\t\tforeach (var ns in scope)\n\t\t\t\t{\n\t\t\t\t\tif (fullAssemblyName == ns.FullAssemblyName && ns.CLRNamespace == clrNs)\n\t\t\t\t\t\treturn ns.XMLNamespace;\n\t\t\t\t}\n\n\t\t\t\tscope = scope.PreviousScope;\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.BamlDecompiler/packages.lock.json",
    "content": "{\n  \"version\": 2,\n  \"dependencies\": {\n    \"net10.0\": {\n      \"Microsoft.Sbom.Targets\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[4.1.5, )\",\n        \"resolved\": \"4.1.5\",\n        \"contentHash\": \"i5z+cNu/cOcdO0AgFB8aXk8w6In2H+haaDfSgd9ImvQIK+rSHavHZIogVoAZLL8jLwYx4bAcs5b7EyuMMG4mQQ==\"\n      },\n      \"TomsToolbox.Composition.Analyzer\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[2.22.2, )\",\n        \"resolved\": \"2.22.2\",\n        \"contentHash\": \"7gYo8ZR2eq3XkrilvUpLbTypeZy6IlD5FB8jah0YPhMOmDGhya4jJ3kfDMTTRt5m258Ou78P69mHMkG6DKZXsg==\"\n      },\n      \"icsharpcode.decompiler\": {\n        \"type\": \"Project\",\n        \"dependencies\": {\n          \"System.Collections.Immutable\": \"[9.0.0, )\",\n          \"System.Reflection.Metadata\": \"[9.0.0, )\"\n        }\n      },\n      \"System.Collections.Immutable\": {\n        \"type\": \"CentralTransitive\",\n        \"requested\": \"[10.0.5, )\",\n        \"resolved\": \"9.0.0\",\n        \"contentHash\": \"QhkXUl2gNrQtvPmtBTQHb0YsUrDiDQ2QS09YbtTTiSjGcf7NBqtYbrG/BE06zcBPCKEwQGzIv13IVdXNOSub2w==\"\n      },\n      \"System.Reflection.Metadata\": {\n        \"type\": \"CentralTransitive\",\n        \"requested\": \"[10.0.5, )\",\n        \"resolved\": \"9.0.0\",\n        \"contentHash\": \"ANiqLu3DxW9kol/hMmTWbt3414t9ftdIuiIU7j80okq2YzAueo120M442xk1kDJWtmZTqWQn7wHDvMRipVOEOQ==\"\n      }\n    }\n  }\n}"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Annotations.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Resolver;\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp\n{\n\t// Annotations:\n\t//  * AstNodes should be annotated with the corresponding ILInstruction\n\t//  * AstNodes referring to other entities should be annotated with the IEntity\n\t//  * Expression type information is currently only available in the ExpressionBuilder, but we might\n\t//    change 'WithTypeInfo()' to use an annotation in the future\n\t//  * IntroduceUnsafeModifier.PointerArithmeticAnnotation is placed on arithmetic operators that operate\n\t//    on pointers.\n\t//    TODO: actually, we could use the type info instead?\n\t//  * AddCheckedBlocks.CheckedAnnotation / AddCheckedBlocks.UnCheckedAnnotation is used on\n\t//    checked/unchecked integer arithmetic\n\t//    TODO: here the info is also redundant, we could peek at the BinaryNumericInstruction instead\n\t//          but on the other hand, some unchecked casts are not backed by any BinaryNumericInstruction\n\n\t/// <summary>\n\t/// Currently unused; we'll probably use the LdToken ILInstruction as annotation instead when LdToken\n\t/// support gets reimplemented.\n\t/// </summary>\n\tpublic class LdTokenAnnotation { }\n\n\tpublic static class AnnotationExtensions\n\t{\n\t\tinternal static ExpressionWithILInstruction WithILInstruction(this Expression expression,\n\t\t\tILInstruction instruction)\n\t\t{\n\t\t\texpression.AddAnnotation(instruction);\n\t\t\treturn new ExpressionWithILInstruction(expression);\n\t\t}\n\n\t\tinternal static ExpressionWithILInstruction WithILInstruction(this Expression expression,\n\t\t\tIEnumerable<ILInstruction> instructions)\n\t\t{\n\t\t\tforeach (var inst in instructions)\n\t\t\t\texpression.AddAnnotation(inst);\n\t\t\treturn new ExpressionWithILInstruction(expression);\n\t\t}\n\n\t\tinternal static ExpressionWithILInstruction WithoutILInstruction(this Expression expression)\n\t\t{\n\t\t\treturn new ExpressionWithILInstruction(expression);\n\t\t}\n\n\t\tinternal static TranslatedStatement WithILInstruction(this Statement statement,\n\t\t\tILInstruction instruction)\n\t\t{\n\t\t\tstatement.AddAnnotation(instruction);\n\t\t\treturn new TranslatedStatement(statement);\n\t\t}\n\n\t\tinternal static TranslatedStatement WithILInstruction(this Statement statement,\n\t\t\tIEnumerable<ILInstruction> instructions)\n\t\t{\n\t\t\tforeach (var inst in instructions)\n\t\t\t\tstatement.AddAnnotation(inst);\n\t\t\treturn new TranslatedStatement(statement);\n\t\t}\n\n\t\tinternal static TranslatedStatement WithoutILInstruction(this Statement statement)\n\t\t{\n\t\t\treturn new TranslatedStatement(statement);\n\t\t}\n\n\t\tinternal static TranslatedExpression WithILInstruction(this ExpressionWithResolveResult expression,\n\t\t\tILInstruction instruction)\n\t\t{\n\t\t\texpression.Expression.AddAnnotation(instruction);\n\t\t\treturn new TranslatedExpression(expression.Expression, expression.ResolveResult);\n\t\t}\n\n\t\tinternal static TranslatedExpression WithILInstruction(this ExpressionWithResolveResult expression,\n\t\t\tIEnumerable<ILInstruction> instructions)\n\t\t{\n\t\t\tforeach (var inst in instructions)\n\t\t\t\texpression.Expression.AddAnnotation(inst);\n\t\t\treturn new TranslatedExpression(expression.Expression, expression.ResolveResult);\n\t\t}\n\n\t\tinternal static TranslatedExpression WithILInstruction(this TranslatedExpression expression,\n\t\t\tILInstruction instruction)\n\t\t{\n\t\t\texpression.Expression.AddAnnotation(instruction);\n\t\t\treturn expression;\n\t\t}\n\n\t\tinternal static TranslatedExpression WithoutILInstruction(this ExpressionWithResolveResult expression)\n\t\t{\n\t\t\treturn new TranslatedExpression(expression.Expression, expression.ResolveResult);\n\t\t}\n\n\t\tinternal static ExpressionWithResolveResult WithRR(this Expression expression,\n\t\t\tResolveResult resolveResult)\n\t\t{\n\t\t\texpression.AddAnnotation(resolveResult);\n\t\t\treturn new ExpressionWithResolveResult(expression, resolveResult);\n\t\t}\n\n\t\tinternal static TranslatedExpression WithRR(this ExpressionWithILInstruction expression,\n\t\t\tResolveResult resolveResult)\n\t\t{\n\t\t\texpression.Expression.AddAnnotation(resolveResult);\n\t\t\treturn new TranslatedExpression(expression, resolveResult);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Retrieves the <see cref=\"ISymbol\"/> associated with this AstNode, or null if no symbol\n\t\t/// is associated with the node.\n\t\t/// </summary>\n\t\tpublic static ISymbol GetSymbol(this AstNode node)\n\t\t{\n\t\t\tvar rr = node.Annotation<ResolveResult>();\n\t\t\tif (rr is MethodGroupResolveResult mgrr)\n\t\t\t{\n\t\t\t\treturn mgrr.ChosenMethod;\n\t\t\t}\n\t\t\treturn rr?.GetSymbol();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Retrieves the <see cref=\"ResolveResult\"/> associated with this <see cref=\"AstNode\"/>,\n\t\t/// or <see cref=\"ErrorResolveResult.UnknownError\"/> if no resolve result is associated with the node.\n\t\t/// </summary>\n\t\tpublic static ResolveResult GetResolveResult(this AstNode node)\n\t\t{\n\t\t\treturn node.Annotation<ResolveResult>() ?? ErrorResolveResult.UnknownError;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Retrieves the <see cref=\"ILVariable\"/> associated with this <see cref=\"IdentifierExpression\"/>,\n\t\t/// or <c>null</c> if no variable is associated with this identifier.\n\t\t/// </summary>\n\t\tpublic static ILVariable GetILVariable(this IdentifierExpression expr)\n\t\t{\n\t\t\tif (expr.Annotation<ResolveResult>() is ILVariableResolveResult rr)\n\t\t\t\treturn rr.Variable;\n\t\t\telse\n\t\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Retrieves the <see cref=\"ILVariable\"/> associated with this <see cref=\"VariableInitializer\"/>,\n\t\t/// or <c>null</c> if no variable is associated with this initializer.\n\t\t/// </summary>\n\t\tpublic static ILVariable GetILVariable(this VariableInitializer vi)\n\t\t{\n\t\t\tif (vi.Annotation<ResolveResult>() is ILVariableResolveResult rr)\n\t\t\t\treturn rr.Variable;\n\t\t\telse\n\t\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Retrieves the <see cref=\"ILVariable\"/> associated with this <see cref=\"ForeachStatement\"/>,\n\t\t/// or <c>null</c> if no variable is associated with this foreach statement.\n\t\t/// </summary>\n\t\tpublic static ILVariable GetILVariable(this ForeachStatement loop)\n\t\t{\n\t\t\tif (loop.Annotation<ResolveResult>() is ILVariableResolveResult rr)\n\t\t\t\treturn rr.Variable;\n\t\t\telse\n\t\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Adds an <see cref=\"ILVariable\"/> to this initializer.\n\t\t/// </summary>\n\t\tpublic static VariableInitializer WithILVariable(this VariableInitializer vi, ILVariable v)\n\t\t{\n\t\t\tvi.AddAnnotation(new ILVariableResolveResult(v, v.Type));\n\t\t\treturn vi;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Adds an <see cref=\"ILVariable\"/> to this foreach statement.\n\t\t/// </summary>\n\t\tpublic static ForeachStatement WithILVariable(this ForeachStatement loop, ILVariable v)\n\t\t{\n\t\t\tloop.AddAnnotation(new ILVariableResolveResult(v, v.Type));\n\t\t\treturn loop;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Copies all annotations from <paramref name=\"other\"/> to <paramref name=\"node\"/>.\n\t\t/// </summary>\n\t\tpublic static T CopyAnnotationsFrom<T>(this T node, AstNode other) where T : AstNode\n\t\t{\n\t\t\tforeach (object annotation in other.Annotations)\n\t\t\t{\n\t\t\t\tnode.AddAnnotation(annotation);\n\t\t\t}\n\t\t\treturn node;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Copies all <see cref=\"ILInstruction\"/> annotations from <paramref name=\"other\"/>\n\t\t/// to <paramref name=\"node\"/>.\n\t\t/// </summary>\n\t\tpublic static T CopyInstructionsFrom<T>(this T node, AstNode other) where T : AstNode\n\t\t{\n\t\t\tforeach (object annotation in other.Annotations.OfType<ILInstruction>())\n\t\t\t{\n\t\t\t\tnode.AddAnnotation(annotation);\n\t\t\t}\n\t\t\treturn node;\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Represents a reference to a local variable.\n\t/// </summary>\n\tpublic class ILVariableResolveResult : ResolveResult\n\t{\n\t\tpublic readonly ILVariable Variable;\n\n\t\tpublic ILVariableResolveResult(ILVariable v) : base(v.Type)\n\t\t{\n\t\t\tthis.Variable = v;\n\t\t}\n\n\t\tpublic ILVariableResolveResult(ILVariable v, IType type) : base(type)\n\t\t{\n\t\t\tthis.Variable = v ?? throw new ArgumentNullException(nameof(v));\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Annotates a <see cref=\"ForeachStatement\"/> with the instructions for the GetEnumerator, MoveNext\n\t/// and get_Current calls.\n\t/// </summary>\n\tpublic class ForeachAnnotation\n\t{\n\t\tpublic readonly ILInstruction GetEnumeratorCall;\n\t\tpublic readonly ILInstruction MoveNextCall;\n\t\tpublic readonly ILInstruction GetCurrentCall;\n\n\t\tpublic ForeachAnnotation(ILInstruction getEnumeratorCall, ILInstruction moveNextCall,\n\t\t\tILInstruction getCurrentCall)\n\t\t{\n\t\t\tGetEnumeratorCall = getEnumeratorCall;\n\t\t\tMoveNextCall = moveNextCall;\n\t\t\tGetCurrentCall = getCurrentCall;\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Annotates the top-level block statement of a function\n\t/// with the implicitly executed return/yield break.\n\t/// </summary>\n\tpublic class ImplicitReturnAnnotation\n\t{\n\t\tpublic readonly Leave Leave;\n\n\t\tpublic ImplicitReturnAnnotation(Leave leave)\n\t\t{\n\t\t\tthis.Leave = leave;\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Annotates an expression when an implicit user-defined conversion was omitted.\n\t/// </summary>\n\tpublic class ImplicitConversionAnnotation\n\t{\n\t\tpublic readonly ConversionResolveResult ConversionResolveResult;\n\t\tpublic IType TargetType => ConversionResolveResult.Type;\n\n\t\tpublic ImplicitConversionAnnotation(ConversionResolveResult conversionResolveResult)\n\t\t{\n\t\t\tthis.ConversionResolveResult = conversionResolveResult;\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Annotates a QueryGroupClause with the ILFunctions of each (implicit lambda) expression.\n\t/// </summary>\n\tpublic class QueryGroupClauseAnnotation\n\t{\n\t\tpublic readonly ILFunction KeyLambda;\n\t\tpublic readonly ILFunction ProjectionLambda;\n\n\t\tpublic QueryGroupClauseAnnotation(ILFunction key, ILFunction projection)\n\t\t{\n\t\t\tthis.KeyLambda = key;\n\t\t\tthis.ProjectionLambda = projection;\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Annotates a QueryJoinClause with the ILFunctions of each (implicit lambda) expression.\n\t/// </summary>\n\tpublic class QueryJoinClauseAnnotation\n\t{\n\t\tpublic readonly ILFunction OnLambda;\n\t\tpublic readonly ILFunction EqualsLambda;\n\n\t\tpublic QueryJoinClauseAnnotation(ILFunction on, ILFunction equals)\n\t\t{\n\t\t\tthis.OnLambda = on;\n\t\t\tthis.EqualsLambda = equals;\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Annotates an out DirectionExpression if the out variable can be declared implicitly typed.\n\t/// </summary>\n\tpublic class UseImplicitlyTypedOutAnnotation\n\t{\n\t\tpublic static readonly UseImplicitlyTypedOutAnnotation Instance = new UseImplicitlyTypedOutAnnotation();\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.PortableExecutable;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\nusing ICSharpCode.Decompiler.CSharp.Resolver;\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.CSharp.Transforms;\nusing ICSharpCode.Decompiler.CSharp.TypeSystem;\nusing ICSharpCode.Decompiler.DebugInfo;\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Documentation;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.IL.ControlFlow;\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nusing SRM = System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.CSharp\n{\n\t/// <summary>\n\t/// Main class of the C# decompiler engine.\n\t/// </summary>\n\t/// <remarks>\n\t/// Instances of this class are not thread-safe. Use separate instances to decompile multiple members in parallel.\n\t/// (in particular, the transform instances are not thread-safe)\n\t/// </remarks>\n\tpublic class CSharpDecompiler\n\t{\n\t\treadonly IDecompilerTypeSystem typeSystem;\n\t\treadonly MetadataModule module;\n\t\treadonly MetadataReader metadata;\n\t\treadonly DecompilerSettings settings;\n\t\tSyntaxTree syntaxTree;\n\n\t\tList<IILTransform> ilTransforms = GetILTransforms();\n\n\t\t/// <summary>\n\t\t/// Pre-yield/await transforms.\n\t\t/// </summary>\n\t\tinternal static List<IILTransform> EarlyILTransforms(bool aggressivelyDuplicateReturnBlocks = false)\n\t\t{\n\t\t\treturn new List<IILTransform> {\n\t\t\t\tnew ControlFlowSimplification {\n\t\t\t\t\taggressivelyDuplicateReturnBlocks = aggressivelyDuplicateReturnBlocks\n\t\t\t\t},\n\t\t\t\tnew SplitVariables(),\n\t\t\t\tnew ILInlining(),\n\t\t\t};\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns all built-in transforms of the ILAst pipeline.\n\t\t/// </summary>\n\t\tpublic static List<IILTransform> GetILTransforms()\n\t\t{\n\t\t\treturn new List<IILTransform> {\n\t\t\t\tnew ControlFlowSimplification(),\n\t\t\t\t// Run SplitVariables only after ControlFlowSimplification duplicates return blocks,\n\t\t\t\t// so that the return variable is split and can be inlined.\n\t\t\t\tnew SplitVariables(),\n\t\t\t\tnew ILInlining(),\n\t\t\t\tnew InlineReturnTransform(), // must run before DetectPinnedRegions\n\t\t\t\tnew RemoveInfeasiblePathTransform(),\n\t\t\t\tnew DetectPinnedRegions(), // must run after inlining but before non-critical control flow transforms\n\t\t\t\tnew YieldReturnDecompiler(), // must run after inlining but before loop detection\n\t\t\t\tnew AsyncAwaitDecompiler(),  // must run after inlining but before loop detection\n\t\t\t\tnew DetectCatchWhenConditionBlocks(), // must run after inlining but before loop detection\n\t\t\t\tnew DetectExitPoints(),\n\t\t\t\tnew LdLocaDupInitObjTransform(),\n\t\t\t\tnew EarlyExpressionTransforms(),\n\t\t\t\tnew SplitVariables(), // split variables once again, because the stobj(ldloca V, ...) may open up new replacements\n\t\t\t\t// RemoveDeadVariableInit must run after EarlyExpressionTransforms so that stobj(ldloca V, ...)\n\t\t\t\t// is already collapsed into stloc(V, ...).\n\t\t\t\tnew RemoveDeadVariableInit(),\n\t\t\t\tnew ControlFlowSimplification(), //split variables may enable new branch to leave inlining\n\t\t\t\tnew DynamicCallSiteTransform(),\n\t\t\t\tnew SwitchDetection(),\n\t\t\t\tnew SwitchOnStringTransform(),\n\t\t\t\tnew SwitchOnNullableTransform(),\n\t\t\t\tnew SplitVariables(), // split variables once again, because SwitchOnNullableTransform eliminates ldloca \n\t\t\t\tnew IntroduceRefReadOnlyModifierOnLocals(),\n\t\t\t\tnew BlockILTransform { // per-block transforms\n\t\t\t\t\tPostOrderTransforms = {\n\t\t\t\t\t\t// Even though it's a post-order block-transform as most other transforms,\n\t\t\t\t\t\t// let's keep LoopDetection separate for now until there's a compelling\n\t\t\t\t\t\t// reason to combine it with the other block transforms.\n\t\t\t\t\t\t// If we ran loop detection after some if structures are already detected,\n\t\t\t\t\t\t// we might make our life introducing good exit points more difficult.\n\t\t\t\t\t\tnew LoopDetection()\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t// re-run DetectExitPoints after loop detection\n\t\t\t\tnew DetectExitPoints(),\n\t\t\t\tnew PatternMatchingTransform(), // must run after LoopDetection and before ConditionDetection\n\t\t\t\tnew BlockILTransform { // per-block transforms\n\t\t\t\t\tPostOrderTransforms = {\n\t\t\t\t\t\tnew ConditionDetection(),\n\t\t\t\t\t\tnew LockTransform(),\n\t\t\t\t\t\tnew UsingTransform(),\n\t\t\t\t\t\t// CachedDelegateInitialization must run after ConditionDetection and before/in LoopingBlockTransform\n\t\t\t\t\t\t// and must run before NullCoalescingTransform\n\t\t\t\t\t\tnew CachedDelegateInitialization(),\n\t\t\t\t\t\tnew StatementTransform(\n\t\t\t\t\t\t\t// per-block transforms that depend on each other, and thus need to\n\t\t\t\t\t\t\t// run interleaved (statement by statement).\n\t\t\t\t\t\t\t// Pretty much all transforms that open up new expression inlining\n\t\t\t\t\t\t\t// opportunities belong in this category.\n\t\t\t\t\t\t\tnew ILInlining() { options = InliningOptions.AllowInliningOfLdloca },\n\t\t\t\t\t\t\t// Inlining must be first, because it doesn't trigger re-runs.\n\t\t\t\t\t\t\t// Any other transform that opens up new inlining opportunities should call RequestRerun().\n\t\t\t\t\t\t\tnew ExpressionTransforms(),\n\t\t\t\t\t\t\tnew DynamicIsEventAssignmentTransform(),\n\t\t\t\t\t\t\tnew TransformAssignment(), // inline and compound assignments\n\t\t\t\t\t\t\tnew NullCoalescingTransform(),\n\t\t\t\t\t\t\tnew NullableLiftingStatementTransform(),\n\t\t\t\t\t\t\tnew NullPropagationStatementTransform(),\n\t\t\t\t\t\t\tnew TransformArrayInitializers(),\n\t\t\t\t\t\t\tnew TransformCollectionAndObjectInitializers(),\n\t\t\t\t\t\t\tnew TransformExpressionTrees(),\n\t\t\t\t\t\t\tnew IndexRangeTransform(),\n\t\t\t\t\t\t\tnew DeconstructionTransform(),\n\t\t\t\t\t\t\tnew NamedArgumentTransform(),\n\t\t\t\t\t\t\tnew RemoveUnconstrainedGenericReferenceTypeCheck(),\n\t\t\t\t\t\t\tnew UserDefinedLogicTransform(),\n\t\t\t\t\t\t\tnew InterpolatedStringTransform()\n\t\t\t\t\t\t),\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tnew ProxyCallReplacer(),\n\t\t\t\tnew FixRemainingIncrements(),\n\t\t\t\tnew CopyPropagation(),\n\t\t\t\tnew DelegateConstruction(),\n\t\t\t\tnew LocalFunctionDecompiler(),\n\t\t\t\tnew TransformDisplayClassUsage(),\n\t\t\t\tnew HighLevelLoopTransform(),\n\t\t\t\tnew ReduceNestingTransform(),\n\t\t\t\tnew RemoveRedundantReturn(),\n\t\t\t\tnew IntroduceDynamicTypeOnLocals(),\n\t\t\t\tnew IntroduceNativeIntTypeOnLocals(),\n\t\t\t\tnew AssignVariableNames(),\n\t\t\t};\n\t\t}\n\n\t\tList<IAstTransform> astTransforms = GetAstTransforms();\n\n\t\t/// <summary>\n\t\t/// Returns all built-in transforms of the C# AST pipeline.\n\t\t/// </summary>\n\t\tpublic static List<IAstTransform> GetAstTransforms()\n\t\t{\n\t\t\treturn new List<IAstTransform> {\n\t\t\t\tnew PatternStatementTransform(),\n\t\t\t\tnew ReplaceMethodCallsWithOperators(), // must run before DeclareVariables.EnsureExpressionStatementsAreValid\n\t\t\t\tnew IntroduceUnsafeModifier(),\n\t\t\t\tnew AddCheckedBlocks(),\n\t\t\t\tnew DeclareVariables(), // should run after most transforms that modify statements\n\t\t\t\tnew TransformFieldAndConstructorInitializers(), // must run after DeclareVariables\n\t\t\t\tnew PrettifyAssignments(), // must run after DeclareVariables\n\t\t\t\tnew IntroduceUsingDeclarations(),\n\t\t\t\tnew IntroduceExtensionMethods(), // must run after IntroduceUsingDeclarations\n\t\t\t\tnew IntroduceQueryExpressions(), // must run after IntroduceExtensionMethods\n\t\t\t\tnew CombineQueryExpressions(),\n\t\t\t\tnew NormalizeBlockStatements(),\n\t\t\t\tnew FlattenSwitchBlocks(),\n\t\t\t\tnew FixNameCollisions(),\n\t\t\t\tnew AddXmlDocumentationTransform(),\n\t\t\t};\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Token to check for requested cancellation of the decompilation.\n\t\t/// </summary>\n\t\tpublic CancellationToken CancellationToken { get; set; }\n\n\t\t/// <summary>\n\t\t/// The type system created from the main module and referenced modules.\n\t\t/// </summary>\n\t\tpublic IDecompilerTypeSystem TypeSystem => typeSystem;\n\n\t\t/// <summary>\n\t\t/// Gets or sets the optional provider for debug info.\n\t\t/// </summary>\n\t\tpublic IDebugInfoProvider DebugInfoProvider { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets or sets the optional provider for XML documentation strings.\n\t\t/// </summary>\n\t\tpublic IDocumentationProvider DocumentationProvider { get; set; }\n\n\t\t/// <summary>\n\t\t/// IL transforms.\n\t\t/// </summary>\n\t\tpublic IList<IILTransform> ILTransforms {\n\t\t\tget { return ilTransforms; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// C# AST transforms.\n\t\t/// </summary>\n\t\tpublic IList<IAstTransform> AstTransforms {\n\t\t\tget { return astTransforms; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a new <see cref=\"CSharpDecompiler\"/> instance from the given <paramref name=\"fileName\"/> using the given <paramref name=\"settings\"/>.\n\t\t/// </summary>\n\t\tpublic CSharpDecompiler(string fileName, DecompilerSettings settings)\n\t\t\t: this(CreateTypeSystemFromFile(fileName, settings), settings)\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a new <see cref=\"CSharpDecompiler\"/> instance from the given <paramref name=\"fileName\"/> using the given <paramref name=\"assemblyResolver\"/> and <paramref name=\"settings\"/>.\n\t\t/// </summary>\n\t\tpublic CSharpDecompiler(string fileName, IAssemblyResolver assemblyResolver, DecompilerSettings settings)\n\t\t\t: this(LoadPEFile(fileName, settings), assemblyResolver, settings)\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a new <see cref=\"CSharpDecompiler\"/> instance from the given <paramref name=\"module\"/> using the given <paramref name=\"assemblyResolver\"/> and <paramref name=\"settings\"/>.\n\t\t/// </summary>\n\t\tpublic CSharpDecompiler(MetadataFile module, IAssemblyResolver assemblyResolver, DecompilerSettings settings)\n\t\t\t: this(new DecompilerTypeSystem(module, assemblyResolver, settings), settings)\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a new <see cref=\"CSharpDecompiler\"/> instance from the given <paramref name=\"typeSystem\"/> and the given <paramref name=\"settings\"/>.\n\t\t/// </summary>\n\t\tpublic CSharpDecompiler(IDecompilerTypeSystem typeSystem, DecompilerSettings settings)\n\t\t{\n\t\t\tthis.typeSystem = typeSystem ?? throw new ArgumentNullException(nameof(typeSystem));\n\t\t\tthis.settings = settings;\n\t\t\tthis.module = typeSystem.MainModule;\n\t\t\tthis.metadata = module.MetadataFile.Metadata;\n\t\t\tif (module.TypeSystemOptions.HasFlag(TypeSystemOptions.Uncached))\n\t\t\t\tthrow new ArgumentException(\"Cannot use an uncached type system in the decompiler.\");\n\t\t}\n\n\t\t#region MemberIsHidden\n\t\t/// <summary>\n\t\t/// Determines whether a <paramref name=\"member\"/> should be hidden from the decompiled code. This is used to exclude compiler-generated code that is handled by transforms from the output.\n\t\t/// </summary>\n\t\t/// <param name=\"module\">The module containing the member.</param>\n\t\t/// <param name=\"member\">The metadata token/handle of the member. Can be a TypeDef, MethodDef or FieldDef.</param>\n\t\t/// <param name=\"settings\">THe settings used to determine whether code should be hidden. E.g. if async methods are not transformed, async state machines are included in the decompiled code.</param>\n\t\tpublic static bool MemberIsHidden(MetadataFile module, EntityHandle member, DecompilerSettings settings)\n\t\t{\n\t\t\tif (module == null || member.IsNil)\n\t\t\t\treturn false;\n\t\t\tvar metadata = module.Metadata;\n\t\t\tstring name;\n\t\t\tswitch (member.Kind)\n\t\t\t{\n\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\tvar methodHandle = (MethodDefinitionHandle)member;\n\t\t\t\t\tvar method = metadata.GetMethodDefinition(methodHandle);\n\t\t\t\t\tvar methodSemantics = module.MethodSemanticsLookup.GetSemantics(methodHandle).Item2;\n\t\t\t\t\tif (methodSemantics != 0 && methodSemantics != System.Reflection.MethodSemanticsAttributes.Other)\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tname = metadata.GetString(method.Name);\n\t\t\t\t\tif (name == \".ctor\" && method.RelativeVirtualAddress == 0 && metadata.GetTypeDefinition(method.GetDeclaringType()).Attributes.HasFlag(System.Reflection.TypeAttributes.Import))\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tif (settings.LocalFunctions && LocalFunctionDecompiler.IsLocalFunctionMethod(module, methodHandle))\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tif (settings.AnonymousMethods && methodHandle.HasGeneratedName(metadata) && methodHandle.IsCompilerGenerated(metadata))\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tif (settings.AsyncAwait && AsyncAwaitDecompiler.IsCompilerGeneratedMainMethod(module, methodHandle))\n\t\t\t\t\t\treturn true;\n\t\t\t\t\treturn false;\n\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\t\tvar typeHandle = (TypeDefinitionHandle)member;\n\t\t\t\t\tvar type = metadata.GetTypeDefinition(typeHandle);\n\t\t\t\t\tname = metadata.GetString(type.Name);\n\t\t\t\t\tif (!type.GetDeclaringType().IsNil)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (settings.LocalFunctions && LocalFunctionDecompiler.IsLocalFunctionDisplayClass(module, typeHandle))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tif (settings.AnonymousMethods && IsClosureType(type, metadata))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tif (settings.YieldReturn && YieldReturnDecompiler.IsCompilerGeneratorEnumerator(typeHandle, metadata))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tif (settings.AsyncAwait && AsyncAwaitDecompiler.IsCompilerGeneratedStateMachine(typeHandle, metadata))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tif (settings.AsyncEnumerator && AsyncAwaitDecompiler.IsCompilerGeneratorAsyncEnumerator(typeHandle, metadata))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tif (settings.FixedBuffers && name.StartsWith(\"<\", StringComparison.Ordinal) && name.Contains(\"__FixedBuffer\"))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tif (settings.InlineArrays && name.StartsWith(\"<>y__InlineArray\", StringComparison.Ordinal) && name.EndsWith(\"`1\", StringComparison.Ordinal))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tif (settings.ExtensionMembers && name.StartsWith(\"<>E__\", StringComparison.Ordinal))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\telse if (type.IsCompilerGenerated(metadata))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (settings.ArrayInitializers && name.StartsWith(\"<PrivateImplementationDetails>\", StringComparison.Ordinal))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tif (settings.AnonymousTypes && type.IsAnonymousType(metadata))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tif (settings.Dynamic && type.IsDelegate(metadata) && (name.StartsWith(\"<>A\", StringComparison.Ordinal) || name.StartsWith(\"<>F\", StringComparison.Ordinal)))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tif (settings.ArrayInitializers && settings.SwitchStatementOnString && name.StartsWith(\"<PrivateImplementationDetails>\", StringComparison.Ordinal))\n\t\t\t\t\t\treturn true;\n\t\t\t\t\treturn false;\n\t\t\t\tcase HandleKind.FieldDefinition:\n\t\t\t\t\tvar fieldHandle = (FieldDefinitionHandle)member;\n\t\t\t\t\tvar field = metadata.GetFieldDefinition(fieldHandle);\n\t\t\t\t\tname = metadata.GetString(field.Name);\n\t\t\t\t\tif (field.IsCompilerGenerated(metadata))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (settings.AnonymousMethods && IsAnonymousMethodCacheField(field, metadata))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tif (settings.UsePrimaryConstructorSyntaxForNonRecordTypes && IsPrimaryConstructorParameterBackingField(field, metadata))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tif (settings.AutomaticProperties && module.PropertyAndEventBackingFieldLookup.IsPropertyBackingField(fieldHandle, out var propertyHandle))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!settings.GetterOnlyAutomaticProperties)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tPropertyAccessors accessors = metadata.GetPropertyDefinition(propertyHandle).GetAccessors();\n\t\t\t\t\t\t\t\tif (!accessors.Getter.IsNil && accessors.Setter.IsNil)\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (settings.SwitchStatementOnString && IsSwitchOnStringCache(field, metadata))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\t// event-fields are not [CompilerGenerated]\n\t\t\t\t\tif (settings.AutomaticEvents && module.PropertyAndEventBackingFieldLookup.IsEventBackingField(fieldHandle, out _))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tif (settings.ArrayInitializers && metadata.GetString(metadata.GetTypeDefinition(field.GetDeclaringType()).Name).StartsWith(\"<PrivateImplementationDetails>\", StringComparison.Ordinal))\n\t\t\t\t\t{\n\t\t\t\t\t\t// only hide fields starting with '__StaticArrayInit'\n\t\t\t\t\t\tif (name.StartsWith(\"__StaticArrayInit\", StringComparison.Ordinal))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t// hide fields starting with '$$method'\n\t\t\t\t\t\tif (name.StartsWith(\"$$method\", StringComparison.Ordinal))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tif (field.DecodeSignature(new Metadata.FullTypeNameSignatureDecoder(metadata), default).ToString().StartsWith(\"__StaticArrayInit\", StringComparison.Ordinal))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\t\tstatic bool IsPrimaryConstructorParameterBackingField(SRM.FieldDefinition field, MetadataReader metadata)\n\t\t{\n\t\t\tvar name = metadata.GetString(field.Name);\n\t\t\treturn name.StartsWith(\"<\", StringComparison.Ordinal) && name.EndsWith(\">P\", StringComparison.Ordinal);\n\t\t}\n\n\t\tstatic bool IsSwitchOnStringCache(SRM.FieldDefinition field, MetadataReader metadata)\n\t\t{\n\t\t\treturn metadata.GetString(field.Name).StartsWith(\"<>f__switch\", StringComparison.Ordinal);\n\t\t}\n\n\t\tinternal static bool IsEventBackingFieldName(string fieldName, string eventName, out int suffixLength)\n\t\t{\n\t\t\tsuffixLength = 0;\n\t\t\tif (fieldName == eventName)\n\t\t\t\treturn true;\n\t\t\tvar vbSuffixLength = \"Event\".Length;\n\t\t\tif (fieldName.Length == eventName.Length + vbSuffixLength && fieldName.StartsWith(eventName, StringComparison.Ordinal) && fieldName.EndsWith(\"Event\", StringComparison.Ordinal))\n\t\t\t{\n\t\t\t\tsuffixLength = vbSuffixLength;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tstatic bool IsAnonymousMethodCacheField(SRM.FieldDefinition field, MetadataReader metadata)\n\t\t{\n\t\t\tvar name = metadata.GetString(field.Name);\n\t\t\treturn name.StartsWith(\"CS$<>\", StringComparison.Ordinal) || name.StartsWith(\"<>f__am\", StringComparison.Ordinal) || name.StartsWith(\"<>f__mg\", StringComparison.Ordinal);\n\t\t}\n\n\t\tstatic bool IsClosureType(SRM.TypeDefinition type, MetadataReader metadata)\n\t\t{\n\t\t\tvar name = metadata.GetString(type.Name);\n\t\t\tif (!type.Name.IsGeneratedName(metadata) || !type.IsCompilerGenerated(metadata))\n\t\t\t\treturn false;\n\t\t\tif (name.Contains(\"DisplayClass\") || name.Contains(\"AnonStorey\") || name.Contains(\"Closure$\"))\n\t\t\t\treturn true;\n\t\t\treturn type.BaseType.IsKnownType(metadata, KnownTypeCode.Object) && !type.GetInterfaceImplementations().Any();\n\t\t}\n\n\t\tinternal static bool IsTransparentIdentifier(string identifier)\n\t\t{\n\t\t\treturn identifier.StartsWith(\"<>\", StringComparison.Ordinal)\n\t\t\t\t&& (identifier.Contains(\"TransparentIdentifier\") || identifier.Contains(\"TranspIdent\"));\n\t\t}\n\t\t#endregion\n\n\t\t#region NativeOrdering\n\n\t\t/// <summary>\n\t\t/// Determines whether a given type requires that its methods be ordered precisely as they were originally defined.\n\t\t/// </summary>\n\t\t/// <param name=\"typeDef\">The type whose members may need native ordering.</param>\n\t\tinternal bool RequiresNativeOrdering(ITypeDefinition typeDef)\n\t\t{\n\t\t\t// The main scenario for requiring the native method ordering is COM interop, where the V-table is fixed by the ABI\n\t\t\treturn ComHelper.IsComImport(typeDef);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Compare handles with the method definition ordering intact by using the underlying method's MetadataToken,\n\t\t/// which is defined as the index into a given metadata table. This should equate to the original order that\n\t\t/// methods and properties were defined by the author.\n\t\t/// </summary>\n\t\t/// <param name=\"typeDef\">The type whose members to order using their method's MetadataToken</param>\n\t\t/// <returns>A sequence of all members ordered by MetadataToken</returns>\n\t\tinternal IEnumerable<IMember> GetMembersWithNativeOrdering(ITypeDefinition typeDef)\n\t\t{\n\t\t\tEntityHandle GetOrderingHandle(IMember member)\n\t\t\t{\n\t\t\t\t// Note! Technically COM interfaces could define property getters and setters out of order or interleaved with other\n\t\t\t\t// methods, but C# doesn't support this so we can't define it that way.\n\n\t\t\t\tif (member is IMethod)\n\t\t\t\t\treturn member.MetadataToken;\n\t\t\t\telse if (member is IProperty property)\n\t\t\t\t\treturn property.Getter?.MetadataToken ?? property.Setter?.MetadataToken ?? property.MetadataToken;\n\t\t\t\telse if (member is IEvent @event)\n\t\t\t\t\treturn @event.AddAccessor?.MetadataToken ?? @event.RemoveAccessor?.MetadataToken ?? @event.InvokeAccessor?.MetadataToken ?? @event.MetadataToken;\n\t\t\t\telse\n\t\t\t\t\treturn member.MetadataToken;\n\t\t\t}\n\n\t\t\treturn typeDef.Fields.Concat<IMember>(typeDef.Properties).Concat(typeDef.Methods).Concat(typeDef.Events).OrderBy((member) => GetOrderingHandle(member), HandleComparer.Default);\n\t\t}\n\n\t\t#endregion\n\n\t\tstatic PEFile LoadPEFile(string fileName, DecompilerSettings settings)\n\t\t{\n\t\t\tsettings.LoadInMemory = true;\n\t\t\treturn new PEFile(\n\t\t\t\tfileName,\n\t\t\t\tnew FileStream(fileName, FileMode.Open, FileAccess.Read),\n\t\t\t\tstreamOptions: PEStreamOptions.PrefetchEntireImage,\n\t\t\t\tmetadataOptions: settings.ApplyWindowsRuntimeProjections ? MetadataReaderOptions.ApplyWindowsRuntimeProjections : MetadataReaderOptions.None\n\t\t\t);\n\t\t}\n\n\t\tstatic DecompilerTypeSystem CreateTypeSystemFromFile(string fileName, DecompilerSettings settings)\n\t\t{\n\t\t\tsettings.LoadInMemory = true;\n\t\t\tvar file = LoadPEFile(fileName, settings);\n\t\t\tvar resolver = new UniversalAssemblyResolver(fileName, settings.ThrowOnAssemblyResolveErrors,\n\t\t\t\tfile.DetectTargetFrameworkId(), file.DetectRuntimePack(),\n\t\t\t\tsettings.LoadInMemory ? PEStreamOptions.PrefetchMetadata : PEStreamOptions.Default,\n\t\t\t\tsettings.ApplyWindowsRuntimeProjections ? MetadataReaderOptions.ApplyWindowsRuntimeProjections : MetadataReaderOptions.None);\n\t\t\treturn new DecompilerTypeSystem(file, resolver, settings);\n\t\t}\n\n\t\tstatic TypeSystemAstBuilder CreateAstBuilder(DecompilerSettings settings)\n\t\t{\n\t\t\tvar typeSystemAstBuilder = new TypeSystemAstBuilder();\n\t\t\ttypeSystemAstBuilder.ShowAttributes = true;\n\t\t\ttypeSystemAstBuilder.UsePrivateProtectedAccessibility = settings.IntroducePrivateProtectedAccessibility;\n\t\t\ttypeSystemAstBuilder.SortAttributes = settings.SortCustomAttributes;\n\t\t\ttypeSystemAstBuilder.AlwaysUseShortTypeNames = true;\n\t\t\ttypeSystemAstBuilder.AddResolveResultAnnotations = true;\n\t\t\ttypeSystemAstBuilder.UseNullableSpecifierForValueTypes = settings.LiftNullables;\n\t\t\ttypeSystemAstBuilder.SupportInitAccessors = settings.InitAccessors;\n\t\t\ttypeSystemAstBuilder.SupportRecordClasses = settings.RecordClasses;\n\t\t\ttypeSystemAstBuilder.SupportRecordStructs = settings.RecordStructs;\n\t\t\ttypeSystemAstBuilder.SupportUnsignedRightShift = settings.UnsignedRightShift;\n\t\t\ttypeSystemAstBuilder.SupportOperatorChecked = settings.CheckedOperators;\n\t\t\ttypeSystemAstBuilder.AlwaysUseGlobal = settings.AlwaysUseGlobal;\n\t\t\treturn typeSystemAstBuilder;\n\t\t}\n\n\t\tIDocumentationProvider CreateDefaultDocumentationProvider()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn XmlDocLoader.LoadDocumentation(module.MetadataFile);\n\t\t\t}\n\t\t\tcatch (System.Xml.XmlException)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tDecompileRun CreateDecompileRun(HashSet<string> namespaces)\n\t\t{\n\t\t\tList<INamespace> resolvedNamespaces = new List<INamespace>();\n\t\t\tforeach (var ns in namespaces)\n\t\t\t{\n\t\t\t\tvar resolvedNamespace = typeSystem.GetNamespaceByFullName(ns);\n\t\t\t\tif (resolvedNamespace != null)\n\t\t\t\t{\n\t\t\t\t\tresolvedNamespaces.Add(resolvedNamespace);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tUsingScope usingScope = new UsingScope(\n\t\t\t\tnew CSharpTypeResolveContext(typeSystem.MainModule),\n\t\t\t\ttypeSystem.RootNamespace,\n\t\t\t\tresolvedNamespaces.ToImmutableArray()\n\t\t\t);\n\n\t\t\treturn new DecompileRun(settings, usingScope) {\n\t\t\t\tDocumentationProvider = DocumentationProvider ?? CreateDefaultDocumentationProvider(),\n\t\t\t\tCancellationToken = CancellationToken,\n\t\t\t\tNamespaces = namespaces\n\t\t\t};\n\t\t}\n\n\t\tvoid RunTransforms(AstNode rootNode, DecompileRun decompileRun, ITypeResolveContext decompilationContext)\n\t\t{\n\t\t\tvar typeSystemAstBuilder = CreateAstBuilder(decompileRun.Settings);\n\t\t\tvar context = new TransformContext(typeSystem, decompileRun, decompilationContext, typeSystemAstBuilder);\n\t\t\tforeach (var transform in astTransforms)\n\t\t\t{\n\t\t\t\tCancellationToken.ThrowIfCancellationRequested();\n\t\t\t\ttransform.Run(rootNode, context);\n\t\t\t}\n\t\t\tCancellationToken.ThrowIfCancellationRequested();\n\t\t\trootNode.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true });\n\t\t\tCancellationToken.ThrowIfCancellationRequested();\n\t\t\tGenericGrammarAmbiguityVisitor.ResolveAmbiguities(rootNode);\n\t\t}\n\n\t\tstring SyntaxTreeToString(SyntaxTree syntaxTree)\n\t\t{\n\t\t\tStringWriter w = new StringWriter();\n\t\t\tsyntaxTree.AcceptVisitor(new CSharpOutputVisitor(w, settings.CSharpFormattingOptions));\n\t\t\treturn w.ToString();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Decompile assembly and module attributes.\n\t\t/// </summary>\n\t\tpublic SyntaxTree DecompileModuleAndAssemblyAttributes()\n\t\t{\n\t\t\tvar decompilationContext = new SimpleTypeResolveContext(typeSystem.MainModule);\n\t\t\tvar namespaces = new HashSet<string>();\n\t\t\tsyntaxTree = new SyntaxTree();\n\t\t\tRequiredNamespaceCollector.CollectAttributeNamespaces(module, namespaces);\n\t\t\tDecompileRun decompileRun = CreateDecompileRun(namespaces);\n\t\t\tDoDecompileModuleAndAssemblyAttributes(decompileRun, decompilationContext, syntaxTree);\n\t\t\tRunTransforms(syntaxTree, decompileRun, decompilationContext);\n\t\t\treturn syntaxTree;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Decompile assembly and module attributes.\n\t\t/// </summary>\n\t\tpublic string DecompileModuleAndAssemblyAttributesToString()\n\t\t{\n\t\t\treturn SyntaxTreeToString(DecompileModuleAndAssemblyAttributes());\n\t\t}\n\n\t\tvoid DoDecompileModuleAndAssemblyAttributes(DecompileRun decompileRun, ITypeResolveContext decompilationContext, SyntaxTree syntaxTree)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tforeach (var a in typeSystem.MainModule.GetAssemblyAttributes())\n\t\t\t\t{\n\t\t\t\t\tvar astBuilder = CreateAstBuilder(decompileRun.Settings);\n\t\t\t\t\tvar attrSection = new AttributeSection(astBuilder.ConvertAttribute(a));\n\t\t\t\t\tattrSection.AttributeTarget = \"assembly\";\n\t\t\t\t\tsyntaxTree.AddChild(attrSection, SyntaxTree.MemberRole);\n\t\t\t\t}\n\t\t\t\tforeach (var a in typeSystem.MainModule.GetModuleAttributes())\n\t\t\t\t{\n\t\t\t\t\tvar astBuilder = CreateAstBuilder(decompileRun.Settings);\n\t\t\t\t\tvar attrSection = new AttributeSection(astBuilder.ConvertAttribute(a));\n\t\t\t\t\tattrSection.AttributeTarget = \"module\";\n\t\t\t\t\tsyntaxTree.AddChild(attrSection, SyntaxTree.MemberRole);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (Exception innerException) when (!(innerException is OperationCanceledException || innerException is DecompilerException))\n\t\t\t{\n\t\t\t\tthrow new DecompilerException(module, null, innerException, \"Error decompiling module and assembly attributes of \" + module.AssemblyName);\n\t\t\t}\n\t\t}\n\n\t\tvoid DoDecompileTypes(IEnumerable<TypeDefinitionHandle> types, DecompileRun decompileRun, ITypeResolveContext decompilationContext, SyntaxTree syntaxTree)\n\t\t{\n\t\t\tstring currentNamespace = null;\n\t\t\tAstNode groupNode = null;\n\t\t\tforeach (var typeDefHandle in types)\n\t\t\t{\n\t\t\t\tvar typeDef = module.GetDefinition(typeDefHandle);\n\t\t\t\tif (typeDef.Name == \"<Module>\" && typeDef.Members.Count == 0)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (MemberIsHidden(module.MetadataFile, typeDefHandle, settings))\n\t\t\t\t\tcontinue;\n\t\t\t\tif (string.IsNullOrEmpty(typeDef.Namespace))\n\t\t\t\t{\n\t\t\t\t\tgroupNode = syntaxTree;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (currentNamespace != typeDef.Namespace)\n\t\t\t\t\t{\n\t\t\t\t\t\tgroupNode = new NamespaceDeclaration(typeDef.Namespace);\n\t\t\t\t\t\tsyntaxTree.AddChild(groupNode, SyntaxTree.MemberRole);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcurrentNamespace = typeDef.Namespace;\n\t\t\t\tvar typeDecl = DoDecompile(typeDef, decompileRun, decompilationContext.WithCurrentTypeDefinition(typeDef));\n\t\t\t\tgroupNode.AddChild(typeDecl, SyntaxTree.MemberRole);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Decompiles the whole module into a single syntax tree.\n\t\t/// </summary>\n\t\tpublic SyntaxTree DecompileWholeModuleAsSingleFile()\n\t\t{\n\t\t\treturn DecompileWholeModuleAsSingleFile(false);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Decompiles the whole module into a single syntax tree.\n\t\t/// </summary>\n\t\t/// <param name=\"sortTypes\">If true, top-level-types are emitted sorted by namespace/name.\n\t\t/// If false, types are emitted in metadata order.</param>\n\t\tpublic SyntaxTree DecompileWholeModuleAsSingleFile(bool sortTypes)\n\t\t{\n\t\t\tvar decompilationContext = new SimpleTypeResolveContext(typeSystem.MainModule);\n\t\t\tsyntaxTree = new SyntaxTree();\n\t\t\tvar namespaces = new HashSet<string>();\n\t\t\tRequiredNamespaceCollector.CollectNamespaces(module, namespaces);\n\t\t\tvar decompileRun = CreateDecompileRun(namespaces);\n\t\t\tDoDecompileModuleAndAssemblyAttributes(decompileRun, decompilationContext, syntaxTree);\n\t\t\tvar typeDefs = metadata.GetTopLevelTypeDefinitions();\n\t\t\tif (sortTypes)\n\t\t\t{\n\t\t\t\ttypeDefs = typeDefs.OrderBy(td => {\n\t\t\t\t\tvar typeDef = module.metadata.GetTypeDefinition(td);\n\t\t\t\t\treturn (module.metadata.GetString(typeDef.Namespace), module.metadata.GetString(typeDef.Name));\n\t\t\t\t});\n\t\t\t}\n\t\t\tDoDecompileTypes(typeDefs, decompileRun, decompilationContext, syntaxTree);\n\t\t\tRunTransforms(syntaxTree, decompileRun, decompilationContext);\n\t\t\treturn syntaxTree;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates an <see cref=\"ILTransformContext\"/> for the given <paramref name=\"function\"/>.\n\t\t/// </summary>\n\t\tpublic ILTransformContext CreateILTransformContext(ILFunction function)\n\t\t{\n\t\t\tvar namespaces = new HashSet<string>();\n\t\t\tRequiredNamespaceCollector.CollectNamespaces(function.Method, module, namespaces);\n\t\t\tvar decompileRun = CreateDecompileRun(namespaces);\n\t\t\treturn new ILTransformContext(function, typeSystem, DebugInfoProvider, settings) {\n\t\t\t\tCancellationToken = CancellationToken,\n\t\t\t\tDecompileRun = decompileRun\n\t\t\t};\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Determines the \"code-mappings\" for a given TypeDef or MethodDef. See <see cref=\"CodeMappingInfo\"/> for more information.\n\t\t/// </summary>\n\t\tpublic static CodeMappingInfo GetCodeMappingInfo(MetadataFile module, EntityHandle member)\n\t\t{\n\t\t\tvar declaringType = (TypeDefinitionHandle)member.GetDeclaringType(module.Metadata);\n\n\t\t\tif (declaringType.IsNil && member.Kind == HandleKind.TypeDefinition)\n\t\t\t{\n\t\t\t\tdeclaringType = (TypeDefinitionHandle)member;\n\t\t\t}\n\n\t\t\tvar info = new CodeMappingInfo(module, declaringType);\n\n\t\t\tvar td = module.Metadata.GetTypeDefinition(declaringType);\n\n\t\t\tforeach (var method in td.GetMethods())\n\t\t\t{\n\t\t\t\tvar parent = method;\n\t\t\t\tvar part = method;\n\n\t\t\t\tvar connectedMethods = new Queue<MethodDefinitionHandle>();\n\t\t\t\tvar processedMethods = new HashSet<MethodDefinitionHandle>();\n\t\t\t\tvar processedNestedTypes = new HashSet<TypeDefinitionHandle>();\n\t\t\t\tconnectedMethods.Enqueue(part);\n\n\t\t\t\twhile (connectedMethods.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tpart = connectedMethods.Dequeue();\n\t\t\t\t\tif (!processedMethods.Add(part))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tReadCodeMappingInfo(module, info, parent, part, connectedMethods, processedNestedTypes);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t{\n\t\t\t\t\t\t// ignore invalid IL\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn info;\n\t\t}\n\n\t\tprivate static void ReadCodeMappingInfo(MetadataFile module, CodeMappingInfo info, MethodDefinitionHandle parent, MethodDefinitionHandle part, Queue<MethodDefinitionHandle> connectedMethods, HashSet<TypeDefinitionHandle> processedNestedTypes)\n\t\t{\n\t\t\tvar md = module.Metadata.GetMethodDefinition(part);\n\n\t\t\tif (!md.HasBody())\n\t\t\t{\n\t\t\t\tinfo.AddMapping(parent, part);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar declaringType = md.GetDeclaringType();\n\n\t\t\tvar blob = module.GetMethodBody(md.RelativeVirtualAddress).GetILReader();\n\t\t\twhile (blob.RemainingBytes > 0)\n\t\t\t{\n\t\t\t\tvar code = blob.DecodeOpCode();\n\t\t\t\tswitch (code)\n\t\t\t\t{\n\t\t\t\t\tcase ILOpCode.Newobj:\n\t\t\t\t\tcase ILOpCode.Stfld:\n\t\t\t\t\t\t// async and yield fsms:\n\t\t\t\t\t\tvar token = MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32());\n\t\t\t\t\t\tif (token.IsNil)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tTypeDefinitionHandle fsmTypeDef;\n\t\t\t\t\t\tswitch (token.Kind)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\t\t\t\tvar fsmMethod = module.Metadata.GetMethodDefinition((MethodDefinitionHandle)token);\n\t\t\t\t\t\t\t\tfsmTypeDef = fsmMethod.GetDeclaringType();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase HandleKind.FieldDefinition:\n\t\t\t\t\t\t\t\tvar fsmField = module.Metadata.GetFieldDefinition((FieldDefinitionHandle)token);\n\t\t\t\t\t\t\t\tfsmTypeDef = fsmField.GetDeclaringType();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase HandleKind.MemberReference:\n\t\t\t\t\t\t\t\tvar memberRef = module.Metadata.GetMemberReference((MemberReferenceHandle)token);\n\t\t\t\t\t\t\t\tfsmTypeDef = ExtractDeclaringType(memberRef);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!fsmTypeDef.IsNil)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar fsmType = module.Metadata.GetTypeDefinition(fsmTypeDef);\n\t\t\t\t\t\t\t// Must be a nested type of the containing type.\n\t\t\t\t\t\t\tif (fsmType.GetDeclaringType() != declaringType)\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tif (YieldReturnDecompiler.IsCompilerGeneratorEnumerator(fsmTypeDef, module.Metadata)\n\t\t\t\t\t\t\t\t|| AsyncAwaitDecompiler.IsCompilerGeneratedStateMachine(fsmTypeDef, module.Metadata))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (!processedNestedTypes.Add(fsmTypeDef))\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tforeach (var h in fsmType.GetMethods())\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif (module.MethodSemanticsLookup.GetSemantics(h).Item2 != 0)\n\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\tvar otherMethod = module.Metadata.GetMethodDefinition(h);\n\t\t\t\t\t\t\t\t\tif (!otherMethod.GetCustomAttributes().HasKnownAttribute(module.Metadata, KnownAttribute.DebuggerHidden))\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tconnectedMethods.Enqueue(h);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase ILOpCode.Ldftn:\n\t\t\t\t\t\t// deal with ldftn instructions, i.e., lambdas\n\t\t\t\t\t\ttoken = MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32());\n\t\t\t\t\t\tif (token.IsNil)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tTypeDefinitionHandle closureTypeHandle;\n\t\t\t\t\t\tswitch (token.Kind)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\t\t\t\tif (((MethodDefinitionHandle)token).IsCompilerGeneratedOrIsInCompilerGeneratedClass(module.Metadata))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tconnectedMethods.Enqueue((MethodDefinitionHandle)token);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\tcase HandleKind.MemberReference:\n\t\t\t\t\t\t\t\tvar memberRef = module.Metadata.GetMemberReference((MemberReferenceHandle)token);\n\t\t\t\t\t\t\t\tif (memberRef.GetKind() != MemberReferenceKind.Method)\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\tclosureTypeHandle = ExtractDeclaringType(memberRef);\n\t\t\t\t\t\t\t\tif (!closureTypeHandle.IsNil)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tvar closureType = module.Metadata.GetTypeDefinition(closureTypeHandle);\n\t\t\t\t\t\t\t\t\tif (closureTypeHandle != declaringType)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t// Must be a nested type of the containing type.\n\t\t\t\t\t\t\t\t\t\tif (closureType.GetDeclaringType() != declaringType)\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\tif (!processedNestedTypes.Add(closureTypeHandle))\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\tforeach (var m in closureType.GetMethods())\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tconnectedMethods.Enqueue(m);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t// Delegate body is declared in the same type\n\t\t\t\t\t\t\t\t\t\tforeach (var m in closureType.GetMethods())\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tvar methodDef = module.Metadata.GetMethodDefinition(m);\n\t\t\t\t\t\t\t\t\t\t\tif (methodDef.Name == memberRef.Name && m.IsCompilerGeneratedOrIsInCompilerGeneratedClass(module.Metadata))\n\t\t\t\t\t\t\t\t\t\t\t\tconnectedMethods.Enqueue(m);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase ILOpCode.Call:\n\t\t\t\t\tcase ILOpCode.Callvirt:\n\t\t\t\t\t\t// deal with call/callvirt instructions, i.e., local function invocations\n\t\t\t\t\t\ttoken = MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32());\n\t\t\t\t\t\tif (token.IsNil)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tswitch (token.Kind)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase HandleKind.MethodSpecification:\n\t\t\t\t\t\t\t\tvar methodSpec = module.Metadata.GetMethodSpecification((MethodSpecificationHandle)token);\n\t\t\t\t\t\t\t\tif (methodSpec.Method.IsNil || methodSpec.Method.Kind != HandleKind.MethodDefinition)\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\ttoken = methodSpec.Method;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (LocalFunctionDecompiler.IsLocalFunctionMethod(module, (MethodDefinitionHandle)token))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconnectedMethods.Enqueue((MethodDefinitionHandle)token);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tblob.SkipOperand(code);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tinfo.AddMapping(parent, part);\n\n\t\t\tTypeDefinitionHandle ExtractDeclaringType(MemberReference memberRef)\n\t\t\t{\n\t\t\t\tswitch (memberRef.Parent.Kind)\n\t\t\t\t{\n\t\t\t\t\tcase HandleKind.TypeReference:\n\t\t\t\t\t\t// This should never happen in normal code, because we are looking at nested types\n\t\t\t\t\t\t// If it's not a nested type, it can't be a reference to the state machine or lambda anyway, and\n\t\t\t\t\t\t// those should be either TypeDef or TypeSpec.\n\t\t\t\t\t\treturn default;\n\t\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\t\t\treturn (TypeDefinitionHandle)memberRef.Parent;\n\t\t\t\t\tcase HandleKind.TypeSpecification:\n\t\t\t\t\t\tvar ts = module.Metadata.GetTypeSpecification((TypeSpecificationHandle)memberRef.Parent);\n\t\t\t\t\t\t// Only read the generic type, ignore the type arguments\n\t\t\t\t\t\tvar genericType = ts.GetGenericType(module.Metadata);\n\t\t\t\t\t\t// Again, we assume this is a type def, because we are only looking at nested types\n\t\t\t\t\t\tif (genericType.Kind != HandleKind.TypeDefinition)\n\t\t\t\t\t\t\treturn default;\n\t\t\t\t\t\treturn (TypeDefinitionHandle)genericType;\n\t\t\t\t}\n\t\t\t\treturn default;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Decompiles the whole module into a single string.\n\t\t/// </summary>\n\t\tpublic string DecompileWholeModuleAsString()\n\t\t{\n\t\t\treturn SyntaxTreeToString(DecompileWholeModuleAsSingleFile());\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Decompile the given types.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Unlike Decompile(IMemberDefinition[]), this method will add namespace declarations around the type definitions.\n\t\t/// </remarks>\n\t\tpublic SyntaxTree DecompileTypes(IEnumerable<TypeDefinitionHandle> types)\n\t\t{\n\t\t\tif (types == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(types));\n\t\t\tvar decompilationContext = new SimpleTypeResolveContext(typeSystem.MainModule);\n\t\t\tsyntaxTree = new SyntaxTree();\n\t\t\tvar namespaces = new HashSet<string>();\n\t\t\tforeach (var type in types)\n\t\t\t{\n\t\t\t\tCancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tif (type.IsNil)\n\t\t\t\t\tthrow new ArgumentException(\"types contains null element\");\n\t\t\t\tRequiredNamespaceCollector.CollectNamespaces(type, module, namespaces);\n\t\t\t}\n\n\t\t\tvar decompileRun = CreateDecompileRun(namespaces);\n\t\t\tDoDecompileTypes(types, decompileRun, decompilationContext, syntaxTree);\n\t\t\tRunTransforms(syntaxTree, decompileRun, decompilationContext);\n\t\t\treturn syntaxTree;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Decompile the given types.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Unlike Decompile(IMemberDefinition[]), this method will add namespace declarations around the type definitions.\n\t\t/// </remarks>\n\t\tpublic string DecompileTypesAsString(IEnumerable<TypeDefinitionHandle> types)\n\t\t{\n\t\t\treturn SyntaxTreeToString(DecompileTypes(types));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Decompile the given type.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Unlike Decompile(IMemberDefinition[]), this method will add namespace declarations around the type definition.\n\t\t/// Note that decompiling types from modules other than the main module is not supported.\n\t\t/// </remarks>\n\t\tpublic SyntaxTree DecompileType(FullTypeName fullTypeName)\n\t\t{\n\t\t\tvar type = typeSystem.FindType(fullTypeName.TopLevelTypeName).GetDefinition();\n\t\t\tif (type == null)\n\t\t\t\tthrow new InvalidOperationException($\"Could not find type definition {fullTypeName} in type system.\");\n\t\t\tif (type.ParentModule != typeSystem.MainModule)\n\t\t\t\tthrow new NotSupportedException($\"Type {fullTypeName} was not found in the module being decompiled, but only in {type.ParentModule.Name}\");\n\t\t\tvar decompilationContext = new SimpleTypeResolveContext(typeSystem.MainModule);\n\t\t\tvar namespaces = new HashSet<string>();\n\t\t\tsyntaxTree = new SyntaxTree();\n\t\t\tRequiredNamespaceCollector.CollectNamespaces(type.MetadataToken, module, namespaces);\n\t\t\tvar decompileRun = CreateDecompileRun(namespaces);\n\t\t\tDoDecompileTypes(new[] { (TypeDefinitionHandle)type.MetadataToken }, decompileRun, decompilationContext, syntaxTree);\n\t\t\tRunTransforms(syntaxTree, decompileRun, decompilationContext);\n\t\t\treturn syntaxTree;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Decompile the given type.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Unlike Decompile(IMemberDefinition[]), this method will add namespace declarations around the type definition.\n\t\t/// </remarks>\n\t\tpublic string DecompileTypeAsString(FullTypeName fullTypeName)\n\t\t{\n\t\t\treturn SyntaxTreeToString(DecompileType(fullTypeName));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Decompile the specified types and/or members.\n\t\t/// </summary>\n\t\tpublic SyntaxTree Decompile(params EntityHandle[] definitions)\n\t\t{\n\t\t\treturn Decompile((IEnumerable<EntityHandle>)definitions);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Decompile the specified types and/or members.\n\t\t/// </summary>\n\t\tpublic SyntaxTree Decompile(IEnumerable<EntityHandle> definitions)\n\t\t{\n\t\t\tif (definitions == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(definitions));\n\t\t\tsyntaxTree = new SyntaxTree();\n\t\t\tvar namespaces = new HashSet<string>();\n\t\t\tforeach (var entity in definitions)\n\t\t\t{\n\t\t\t\tif (entity.IsNil)\n\t\t\t\t\tthrow new ArgumentException(\"definitions contains null element\");\n\t\t\t\tRequiredNamespaceCollector.CollectNamespaces(entity, module, namespaces);\n\t\t\t}\n\t\t\tvar decompileRun = CreateDecompileRun(namespaces);\n\n\t\t\tbool first = true;\n\t\t\tITypeDefinition parentTypeDef = null;\n\n\t\t\tforeach (var entity in definitions)\n\t\t\t{\n\t\t\t\tswitch (entity.Kind)\n\t\t\t\t{\n\t\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\t\t\tITypeDefinition typeDef = module.GetDefinition((TypeDefinitionHandle)entity);\n\t\t\t\t\t\tsyntaxTree.Members.Add(DoDecompile(typeDef, decompileRun, new SimpleTypeResolveContext(typeDef)));\n\t\t\t\t\t\tif (first)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tparentTypeDef = typeDef.DeclaringTypeDefinition;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (parentTypeDef != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tparentTypeDef = FindCommonDeclaringTypeDefinition(parentTypeDef, typeDef.DeclaringTypeDefinition);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\t\tIMethod method = module.GetDefinition((MethodDefinitionHandle)entity);\n\t\t\t\t\t\tsyntaxTree.Members.Add(DoDecompile(method, decompileRun, new SimpleTypeResolveContext(method), null));\n\t\t\t\t\t\tif (first)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tparentTypeDef = method.DeclaringTypeDefinition;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (parentTypeDef != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tparentTypeDef = FindCommonDeclaringTypeDefinition(parentTypeDef, method.DeclaringTypeDefinition);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HandleKind.FieldDefinition:\n\t\t\t\t\t\tIField field = module.GetDefinition((FieldDefinitionHandle)entity);\n\t\t\t\t\t\tsyntaxTree.Members.Add(DoDecompile(field, decompileRun, new SimpleTypeResolveContext(field)));\n\t\t\t\t\t\tparentTypeDef = field.DeclaringTypeDefinition;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HandleKind.PropertyDefinition:\n\t\t\t\t\t\tIProperty property = module.GetDefinition((PropertyDefinitionHandle)entity);\n\t\t\t\t\t\tsyntaxTree.Members.Add(DoDecompile(property, decompileRun, new SimpleTypeResolveContext(property), null));\n\t\t\t\t\t\tif (first)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tparentTypeDef = property.DeclaringTypeDefinition;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (parentTypeDef != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tparentTypeDef = FindCommonDeclaringTypeDefinition(parentTypeDef, property.DeclaringTypeDefinition);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HandleKind.EventDefinition:\n\t\t\t\t\t\tIEvent ev = module.GetDefinition((EventDefinitionHandle)entity);\n\t\t\t\t\t\tsyntaxTree.Members.Add(DoDecompile(ev, decompileRun, new SimpleTypeResolveContext(ev)));\n\t\t\t\t\t\tif (first)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tparentTypeDef = ev.DeclaringTypeDefinition;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (parentTypeDef != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tparentTypeDef = FindCommonDeclaringTypeDefinition(parentTypeDef, ev.DeclaringTypeDefinition);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new NotSupportedException(entity.Kind.ToString());\n\t\t\t\t}\n\t\t\t\tfirst = false;\n\t\t\t}\n\t\t\tRunTransforms(syntaxTree, decompileRun, parentTypeDef != null ? new SimpleTypeResolveContext(parentTypeDef) : new SimpleTypeResolveContext(typeSystem.MainModule));\n\t\t\treturn syntaxTree;\n\t\t}\n\n\t\tITypeDefinition FindCommonDeclaringTypeDefinition(ITypeDefinition a, ITypeDefinition b)\n\t\t{\n\t\t\tif (a == null || b == null)\n\t\t\t\treturn null;\n\t\t\tvar declaringTypes = a.GetDeclaringTypeDefinitions();\n\t\t\tvar set = new HashSet<ITypeDefinition>(b.GetDeclaringTypeDefinitions());\n\t\t\treturn declaringTypes.FirstOrDefault(set.Contains);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Decompile the specified types and/or members.\n\t\t/// </summary>\n\t\tpublic string DecompileAsString(params EntityHandle[] definitions)\n\t\t{\n\t\t\treturn SyntaxTreeToString(Decompile(definitions));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Decompile the specified types and/or members.\n\t\t/// </summary>\n\t\tpublic string DecompileAsString(IEnumerable<EntityHandle> definitions)\n\t\t{\n\t\t\treturn SyntaxTreeToString(Decompile(definitions));\n\t\t}\n\n\t\treadonly Dictionary<TypeDefinitionHandle, PartialTypeInfo> partialTypes = new();\n\n\t\tpublic void AddPartialTypeDefinition(PartialTypeInfo info)\n\t\t{\n\t\t\tif (!partialTypes.TryGetValue(info.DeclaringTypeDefinitionHandle, out var existingInfo))\n\t\t\t{\n\t\t\t\tpartialTypes.Add(info.DeclaringTypeDefinitionHandle, info);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\texistingInfo.AddDeclaredMembers(info);\n\t\t\t}\n\t\t}\n\n\t\tIEnumerable<EntityDeclaration> AddInterfaceImplHelpers(\n\t\t\tEntityDeclaration memberDecl, IMethod method,\n\t\t\tTypeSystemAstBuilder astBuilder)\n\t\t{\n\t\t\tif (!memberDecl.GetChildByRole(EntityDeclaration.PrivateImplementationTypeRole).IsNull)\n\t\t\t{\n\t\t\t\tyield break; // cannot create forwarder for existing explicit interface impl\n\t\t\t}\n\t\t\tif (method.IsStatic)\n\t\t\t{\n\t\t\t\tyield break; // cannot create forwarder for static interface impl\n\t\t\t}\n\t\t\tif (memberDecl.HasModifier(Modifiers.Extern))\n\t\t\t{\n\t\t\t\tyield break; // cannot create forwarder for extern method\n\t\t\t}\n\t\t\tvar genericContext = new Decompiler.TypeSystem.GenericContext(method);\n\t\t\tvar methodHandle = (MethodDefinitionHandle)method.MetadataToken;\n\t\t\tforeach (var h in methodHandle.GetMethodImplementations(metadata))\n\t\t\t{\n\t\t\t\tvar mi = metadata.GetMethodImplementation(h);\n\t\t\t\tIMethod m = module.ResolveMethod(mi.MethodDeclaration, genericContext);\n\t\t\t\tif (m == null || m.DeclaringType.Kind != TypeKind.Interface)\n\t\t\t\t\tcontinue;\n\t\t\t\tvar methodDecl = new MethodDeclaration();\n\t\t\t\tmethodDecl.ReturnType = memberDecl.ReturnType.Clone();\n\t\t\t\tmethodDecl.PrivateImplementationType = astBuilder.ConvertType(m.DeclaringType);\n\t\t\t\tmethodDecl.Name = m.Name;\n\t\t\t\tmethodDecl.TypeParameters.AddRange(memberDecl.GetChildrenByRole(Roles.TypeParameter)\n\t\t\t\t\t\t\t\t\t\t\t\t   .Select(n => (TypeParameterDeclaration)n.Clone()));\n\t\t\t\tmethodDecl.Parameters.AddRange(memberDecl.GetChildrenByRole(Roles.Parameter).Select(n => n.Clone()));\n\t\t\t\t// Constraints are not copied because explicit interface implementations cannot have constraints. CS0460\n\n\t\t\t\tmethodDecl.Body = new BlockStatement();\n\t\t\t\tmethodDecl.Body.AddChild(new Comment(\n\t\t\t\t\t\"ILSpy generated this explicit interface implementation from .override directive in \" + memberDecl.Name),\n\t\t\t\t\t\t\t\t\t\t Roles.Comment);\n\t\t\t\tvar forwardingCall = new InvocationExpression(new MemberReferenceExpression(new ThisReferenceExpression(), memberDecl.Name,\n\t\t\t\t\tmethodDecl.TypeParameters.Select(tp => new SimpleType(tp.Name))),\n\t\t\t\t\tmethodDecl.Parameters.Select(ForwardParameter)\n\t\t\t\t);\n\t\t\t\tif (m.ReturnType.IsKnownType(KnownTypeCode.Void))\n\t\t\t\t{\n\t\t\t\t\tmethodDecl.Body.Add(new ExpressionStatement(forwardingCall));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tmethodDecl.Body.Add(new ReturnStatement(forwardingCall));\n\t\t\t\t}\n\t\t\t\tyield return methodDecl;\n\t\t\t}\n\t\t}\n\n\t\tExpression ForwardParameter(ParameterDeclaration p)\n\t\t{\n\t\t\tswitch (p.ParameterModifier)\n\t\t\t{\n\t\t\t\tcase ReferenceKind.None:\n\t\t\t\t\treturn new IdentifierExpression(p.Name);\n\t\t\t\tcase ReferenceKind.Ref:\n\t\t\t\tcase ReferenceKind.RefReadOnly:\n\t\t\t\t\treturn new DirectionExpression(FieldDirection.Ref, new IdentifierExpression(p.Name));\n\t\t\t\tcase ReferenceKind.Out:\n\t\t\t\t\treturn new DirectionExpression(FieldDirection.Out, new IdentifierExpression(p.Name));\n\t\t\t\tcase ReferenceKind.In:\n\t\t\t\t\treturn new DirectionExpression(FieldDirection.In, new IdentifierExpression(p.Name));\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException();\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Sets new modifier if the member hides some other member from a base type.\n\t\t/// </summary>\n\t\t/// <param name=\"member\">The node of the member which new modifier state should be determined.</param>\n\t\tvoid SetNewModifier(EntityDeclaration member)\n\t\t{\n\t\t\tvar entity = (IEntity)member.GetSymbol();\n\t\t\tvar lookup = new MemberLookup(entity.DeclaringTypeDefinition, entity.ParentModule);\n\n\t\t\tvar baseTypes = entity.DeclaringType.GetNonInterfaceBaseTypes().Where(t => entity.DeclaringType != t).ToList();\n\n\t\t\t// A constant, field, property, event, or type introduced in a class or struct hides all base class members with the same name.\n\t\t\tbool hideBasedOnSignature = !(entity is ITypeDefinition\n\t\t\t\t|| entity.SymbolKind == SymbolKind.Field\n\t\t\t\t|| entity.SymbolKind == SymbolKind.Property\n\t\t\t\t|| entity.SymbolKind == SymbolKind.Event);\n\n\t\t\tconst GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions;\n\n\t\t\tif (HidesMemberOrTypeOfBaseType())\n\t\t\t\tmember.Modifiers |= Modifiers.New;\n\n\t\t\tbool HidesMemberOrTypeOfBaseType()\n\t\t\t{\n\t\t\t\tvar parameterListComparer = ParameterListComparer.WithOptions(includeModifiers: true);\n\n\t\t\t\tforeach (IType baseType in baseTypes)\n\t\t\t\t{\n\t\t\t\t\tif (!hideBasedOnSignature)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (baseType.GetNestedTypes(t => t.Name == entity.Name && lookup.IsAccessible(t, true), options).Any())\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tif (baseType.GetMembers(m => m.Name == entity.Name && m.SymbolKind != SymbolKind.Indexer && lookup.IsAccessible(m, true), options).Any())\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif (entity.SymbolKind == SymbolKind.Indexer)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// An indexer introduced in a class or struct hides all base class indexers with the same signature (parameter count and types).\n\t\t\t\t\t\t\tif (baseType.GetProperties(p => p.SymbolKind == SymbolKind.Indexer && lookup.IsAccessible(p, true))\n\t\t\t\t\t\t\t\t\t.Any(p => parameterListComparer.Equals(((IProperty)entity).Parameters, p.Parameters)))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (entity.SymbolKind == SymbolKind.Method)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// A method introduced in a class or struct hides all non-method base class members with the same name, and all\n\t\t\t\t\t\t\t// base class methods with the same signature (method name and parameter count, modifiers, and types).\n\t\t\t\t\t\t\tif (baseType.GetMembers(m => m.SymbolKind != SymbolKind.Indexer\n\t\t\t\t\t\t\t\t\t\t\t\t\t&& m.SymbolKind != SymbolKind.Constructor\n\t\t\t\t\t\t\t\t\t\t\t\t\t&& m.SymbolKind != SymbolKind.Destructor\n\t\t\t\t\t\t\t\t\t\t\t\t\t&& m.Name == entity.Name && lookup.IsAccessible(m, true))\n\t\t\t\t\t\t\t\t.Any(m => m.SymbolKind != SymbolKind.Method ||\n\t\t\t\t\t\t\t\t\t(((IMethod)entity).TypeParameters.Count == ((IMethod)m).TypeParameters.Count\n\t\t\t\t\t\t\t\t\t\t&& parameterListComparer.Equals(((IMethod)entity).Parameters, ((IMethod)m).Parameters))))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tvoid FixParameterNames(EntityDeclaration entity)\n\t\t{\n\t\t\tint i = 0;\n\t\t\tforeach (var parameter in entity.GetChildrenByRole(Roles.Parameter))\n\t\t\t{\n\t\t\t\tif (string.IsNullOrWhiteSpace(parameter.Name) && !parameter.Type.IsArgList())\n\t\t\t\t{\n\t\t\t\t\t// needs to be consistent with logic in ILReader.CreateILVariable\n\t\t\t\t\tparameter.Name = \"P_\" + i;\n\t\t\t\t}\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\n\t\tEntityDeclaration DoDecompile(ITypeDefinition typeDef, DecompileRun decompileRun, ITypeResolveContext decompilationContext)\n\t\t{\n\t\t\tDebug.Assert(decompilationContext.CurrentTypeDefinition == typeDef);\n\t\t\tvar watch = System.Diagnostics.Stopwatch.StartNew();\n\t\t\tvar entityMap = new MultiDictionary<IEntity, EntityDeclaration>();\n\t\t\tvar workList = new Queue<IEntity>();\n\t\t\tTypeSystemAstBuilder typeSystemAstBuilder;\n\t\t\ttry\n\t\t\t{\n\t\t\t\ttypeSystemAstBuilder = CreateAstBuilder(decompileRun.Settings);\n\t\t\t\tvar entityDecl = typeSystemAstBuilder.ConvertEntity(typeDef);\n\t\t\t\tif (entityDecl is DelegateDeclaration delegateDeclaration)\n\t\t\t\t{\n\t\t\t\t\t// Fix empty parameter names in delegate declarations\n\t\t\t\t\tFixParameterNames(delegateDeclaration);\n\t\t\t\t}\n\t\t\t\tvar typeDecl = entityDecl as TypeDeclaration;\n\t\t\t\tif (typeDecl == null)\n\t\t\t\t{\n\t\t\t\t\t// e.g. DelegateDeclaration\n\t\t\t\t\treturn entityDecl;\n\t\t\t\t}\n\t\t\t\tbool isRecord = typeDef.Kind switch {\n\t\t\t\t\tTypeKind.Class => settings.RecordClasses && typeDef.IsRecord,\n\t\t\t\t\tTypeKind.Struct => settings.RecordStructs && typeDef.IsRecord,\n\t\t\t\t\t_ => false,\n\t\t\t\t};\n\t\t\t\tRecordDecompiler recordDecompiler = isRecord ? new RecordDecompiler(typeSystem, typeDef, settings, CancellationToken) : null;\n\t\t\t\tif (recordDecompiler != null)\n\t\t\t\t\tdecompileRun.RecordDecompilers.Add(typeDef, recordDecompiler);\n\n\t\t\t\t// With C# 9 records, the relative order of fields and properties matters:\n\t\t\t\tIEnumerable<IMember> fieldsAndProperties = isRecord\n\t\t\t\t\t? recordDecompiler.FieldsAndProperties\n\t\t\t\t\t: typeDef.Fields.Concat<IMember>(typeDef.Properties);\n\n\t\t\t\t// For COM interop scenarios, the relative order of virtual functions/properties matters:\n\t\t\t\tIEnumerable<IMember> allOrderedMembers = RequiresNativeOrdering(typeDef) ? GetMembersWithNativeOrdering(typeDef) :\n\t\t\t\t\tfieldsAndProperties.Concat(typeDef.Events).Concat(typeDef.Methods);\n\n\t\t\t\tvar allOrderedEntities = typeDef.NestedTypes.Concat<IEntity>(allOrderedMembers).ToArray();\n\n\t\t\t\tif (!partialTypes.TryGetValue((TypeDefinitionHandle)typeDef.MetadataToken, out var partialTypeInfo))\n\t\t\t\t{\n\t\t\t\t\tpartialTypeInfo = null;\n\t\t\t\t}\n\n\t\t\t\tif (settings.ExtensionMembers)\n\t\t\t\t{\n\t\t\t\t\tforeach (var group in typeDef.ExtensionInfo?.GetGroups() ?? [])\n\t\t\t\t\t{\n\t\t\t\t\t\tvar ext = new ExtensionDeclaration();\n\t\t\t\t\t\tITypeParameter[] typeParameters = group.Key.TypeParameters;\n\t\t\t\t\t\tvar subst = new TypeParameterSubstitution(typeParameters, null);\n\t\t\t\t\t\text.TypeParameters.AddRange(typeParameters.Select(tp => typeSystemAstBuilder.ConvertTypeParameter(tp)));\n\t\t\t\t\t\tvar marker = group.Key.Marker.Specialize(subst);\n\t\t\t\t\t\text.ReceiverParameters.Add(typeSystemAstBuilder.ConvertParameter(marker.Parameters.Single()));\n\t\t\t\t\t\text.Constraints.AddRange(typeParameters.Select(c => typeSystemAstBuilder.ConvertTypeParameterConstraint(c)));\n\n\t\t\t\t\t\tforeach (var member in group)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tIMember extMember = member.ExtensionMember.Specialize(subst);\n\t\t\t\t\t\t\tif (member.ExtensionMember.IsAccessor)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\textMember = member.ExtensionMember.AccessorOwner;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (entityMap.Contains(extMember) || extMember.MetadataToken.IsNil)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// Member is already decompiled.\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tEntityDeclaration extMemberDecl = DoDecompileExtensionMember(extMember, typeDef.ExtensionInfo, decompileRun, decompilationContext);\n\t\t\t\t\t\t\text.Members.Add(extMemberDecl);\n\t\t\t\t\t\t\tentityMap.Add(extMember, extMemberDecl);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttypeDecl.Members.Add(ext);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Decompile members that are not compiler-generated.\n\t\t\t\tforeach (var entity in allOrderedEntities)\n\t\t\t\t{\n\t\t\t\t\tif (entity.MetadataToken.IsNil || MemberIsHidden(module.MetadataFile, entity.MetadataToken, settings))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tDoDecompileMember(entity, recordDecompiler, partialTypeInfo, typeDef.ExtensionInfo);\n\t\t\t\t}\n\n\t\t\t\t// Decompile compiler-generated members that are still needed.\n\t\t\t\twhile (workList.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tvar entity = workList.Dequeue();\n\t\t\t\t\tif (entityMap.Contains(entity) || entity.MetadataToken.IsNil)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Member is already decompiled.\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tDoDecompileMember(entity, recordDecompiler, partialTypeInfo, typeDef.ExtensionInfo);\n\t\t\t\t}\n\n\t\t\t\t// Add all decompiled members to syntax tree in the correct order.\n\t\t\t\tforeach (var member in allOrderedEntities)\n\t\t\t\t{\n\t\t\t\t\ttypeDecl.Members.AddRange(entityMap[member]);\n\t\t\t\t}\n\n\t\t\t\tif (typeDecl.Members.OfType<IndexerDeclaration>().Any(idx => idx.PrivateImplementationType.IsNull))\n\t\t\t\t{\n\t\t\t\t\t// Remove the [DefaultMember] attribute if the class contains indexers\n\t\t\t\t\tRemoveAttribute(typeDecl, KnownAttribute.DefaultMember);\n\t\t\t\t}\n\t\t\t\tif (partialTypeInfo != null)\n\t\t\t\t{\n\t\t\t\t\ttypeDecl.Modifiers |= Modifiers.Partial;\n\t\t\t\t}\n\t\t\t\tif (settings.IntroduceRefModifiersOnStructs)\n\t\t\t\t{\n\t\t\t\t\tRemoveObsoleteAttribute(typeDecl, \"Types with embedded references are not supported in this version of your compiler.\");\n\t\t\t\t\tRemoveCompilerFeatureRequiredAttribute(typeDecl, \"RefStructs\");\n\t\t\t\t}\n\t\t\t\tif (settings.RequiredMembers)\n\t\t\t\t{\n\t\t\t\t\tRemoveAttribute(typeDecl, KnownAttribute.Required);\n\t\t\t\t}\n\t\t\t\tif (typeDecl.ClassType == ClassType.Enum)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(typeDef.Kind == TypeKind.Enum);\n\t\t\t\t\tEnumValueDisplayMode displayMode = DetectBestEnumValueDisplayMode(typeDef, module.MetadataFile);\n\t\t\t\t\tswitch (displayMode)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase EnumValueDisplayMode.FirstOnly:\n\t\t\t\t\t\t\tforeach (var enumMember in typeDecl.Members.OfType<EnumMemberDeclaration>().Skip(1))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tenumMember.Initializer = null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase EnumValueDisplayMode.None:\n\t\t\t\t\t\t\tforeach (var enumMember in typeDecl.Members.OfType<EnumMemberDeclaration>())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tenumMember.Initializer = null;\n\t\t\t\t\t\t\t\tif (enumMember.GetSymbol() is IField f && f.GetConstantValue() == null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttypeDecl.InsertChildBefore(enumMember, new Comment(\" error: enumerator has no value\"), Roles.Comment);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase EnumValueDisplayMode.All:\n\t\t\t\t\t\t\t// nothing needs to be changed.\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase EnumValueDisplayMode.AllHex:\n\t\t\t\t\t\t\tforeach (var enumMember in typeDecl.Members.OfType<EnumMemberDeclaration>())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvar constantValue = (enumMember.GetSymbol() as IField).GetConstantValue();\n\t\t\t\t\t\t\t\tif (constantValue == null || enumMember.Initializer is not PrimitiveExpression pe)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tlong initValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, constantValue, false);\n\t\t\t\t\t\t\t\tif (initValue >= 10)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tpe.Format = LiteralFormat.HexadecimalNumber;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t\t\t}\n\t\t\t\t\tforeach (var item in typeDecl.Members)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (item is not EnumMemberDeclaration)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttypeDecl.InsertChildBefore(item, new Comment(\" error: nested types are not permitted in C#.\"), Roles.Comment);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn typeDecl;\n\t\t\t}\n\t\t\tcatch (Exception innerException) when (!(innerException is OperationCanceledException || innerException is DecompilerException))\n\t\t\t{\n\t\t\t\tthrow new DecompilerException(module, typeDef, innerException);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\twatch.Stop();\n\t\t\t\tInstrumentation.DecompilerEventSource.Log.DoDecompileTypeDefinition(typeDef.FullName, watch.ElapsedMilliseconds);\n\t\t\t}\n\n\t\t\tvoid DoDecompileMember(IEntity entity, RecordDecompiler recordDecompiler, PartialTypeInfo partialType, ExtensionInfo extensionInfo)\n\t\t\t{\n\t\t\t\tif (partialType != null && partialType.IsDeclaredMember(entity.MetadataToken))\n\t\t\t\t{\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (settings.ExtensionMembers && extensionInfo != null)\n\t\t\t\t{\n\t\t\t\t\tswitch (entity)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase ITypeDefinition td when extensionInfo.IsExtensionGroupingType(td):\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\tcase IMethod m when extensionInfo.InfoOfImplementationMember(m).HasValue:\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tEntityDeclaration entityDecl;\n\t\t\t\tswitch (entity)\n\t\t\t\t{\n\t\t\t\t\tcase IField field:\n\t\t\t\t\t\tif (typeDef.Kind == TypeKind.Enum && !field.IsConst)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (TransformFieldAndConstructorInitializers.IsGeneratedPrimaryConstructorBackingField(field))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tentityDecl = DoDecompile(field, decompileRun, decompilationContext.WithCurrentMember(field));\n\t\t\t\t\t\tentityMap.Add(field, entityDecl);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase IProperty property:\n\t\t\t\t\t\tif (recordDecompiler?.PropertyIsGenerated(property) == true)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tentityDecl = DoDecompile(property, decompileRun, decompilationContext.WithCurrentMember(property), null);\n\t\t\t\t\t\tentityMap.Add(property, entityDecl);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase IMethod method:\n\t\t\t\t\t\tif (recordDecompiler?.MethodIsGenerated(method) == true)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tentityDecl = DoDecompile(method, decompileRun, decompilationContext.WithCurrentMember(method), null);\n\t\t\t\t\t\tentityMap.Add(method, entityDecl);\n\t\t\t\t\t\tforeach (var helper in AddInterfaceImplHelpers(entityDecl, method, typeSystemAstBuilder))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tentityMap.Add(method, helper);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase IEvent @event:\n\t\t\t\t\t\tentityDecl = DoDecompile(@event, decompileRun, decompilationContext.WithCurrentMember(@event));\n\t\t\t\t\t\tentityMap.Add(@event, entityDecl);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase ITypeDefinition type:\n\t\t\t\t\t\tentityDecl = DoDecompile(type, decompileRun, decompilationContext.WithCurrentTypeDefinition(type));\n\t\t\t\t\t\tSetNewModifier(entityDecl);\n\t\t\t\t\t\tentityMap.Add(type, entityDecl);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new ArgumentOutOfRangeException(\"Unexpected member type\");\n\t\t\t\t}\n\n\t\t\t\tforeach (var node in entityDecl.Descendants)\n\t\t\t\t{\n\t\t\t\t\tvar rr = node.GetResolveResult();\n\t\t\t\t\tif (rr is MemberResolveResult mrr\n\t\t\t\t\t\t&& mrr.Member.DeclaringTypeDefinition == typeDef\n\t\t\t\t\t\t&& !(mrr.Member is IMethod { IsLocalFunction: true }))\n\t\t\t\t\t{\n\t\t\t\t\t\tworkList.Enqueue(mrr.Member);\n\t\t\t\t\t}\n\t\t\t\t\telse if (rr is TypeResolveResult trr\n\t\t\t\t\t\t&& trr.Type.GetDefinition()?.DeclaringTypeDefinition == typeDef)\n\t\t\t\t\t{\n\t\t\t\t\t\tworkList.Enqueue(trr.Type.GetDefinition());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate EntityDeclaration DoDecompileExtensionMember(IMember extMember, ExtensionInfo info, DecompileRun decompileRun, ITypeResolveContext decompilationContext)\n\t\t{\n\t\t\tswitch (extMember)\n\t\t\t{\n\t\t\t\tcase IProperty p:\n\t\t\t\t\tvar prop = DoDecompile(p, decompileRun, decompilationContext.WithCurrentMember(p), info);\n\t\t\t\t\tRemoveAttribute(prop, KnownAttribute.ExtensionMarker);\n\t\t\t\t\tif (p.Getter != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tRemoveAttribute(prop.GetChildByRole(PropertyDeclaration.GetterRole), KnownAttribute.ExtensionMarker);\n\t\t\t\t\t}\n\t\t\t\t\tif (p.Setter != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tRemoveAttribute(prop.GetChildByRole(PropertyDeclaration.SetterRole), KnownAttribute.ExtensionMarker);\n\t\t\t\t\t}\n\t\t\t\t\treturn prop;\n\t\t\t\tcase IMethod m:\n\t\t\t\t\tvar meth = DoDecompile(m, decompileRun, decompilationContext.WithCurrentMember(m), info);\n\t\t\t\t\tRemoveAttribute(meth, KnownAttribute.ExtensionMarker);\n\t\t\t\t\treturn meth;\n\t\t\t}\n\n\t\t\tthrow new NotSupportedException($\"Extension member {extMember} is not supported for decompilation.\");\n\t\t}\n\n\t\tEnumValueDisplayMode DetectBestEnumValueDisplayMode(ITypeDefinition typeDef, MetadataFile module)\n\t\t{\n\t\t\tif (typeDef.HasAttribute(KnownAttribute.Flags))\n\t\t\t\treturn EnumValueDisplayMode.AllHex;\n\t\t\tbool first = true;\n\t\t\tlong firstValue = 0, previousValue = 0;\n\t\t\tbool allPowersOfTwo = true;\n\t\t\tbool allConsecutive = true;\n\t\t\tforeach (var field in typeDef.Fields)\n\t\t\t{\n\t\t\t\tif (MemberIsHidden(module, field.MetadataToken, settings))\n\t\t\t\t\tcontinue;\n\t\t\t\tobject constantValue = field.GetConstantValue();\n\t\t\t\tif (constantValue == null)\n\t\t\t\t\tcontinue;\n\t\t\t\tlong currentValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, constantValue, false);\n\t\t\t\tallConsecutive = allConsecutive && (first || previousValue + 1 == currentValue);\n\t\t\t\t// N & (N - 1) == 0, iff N is a power of 2, for all N != 0.\n\t\t\t\t// We define that 0 is a power of 2 in the context of enum values.\n\t\t\t\tallPowersOfTwo = allPowersOfTwo && unchecked(currentValue & (currentValue - 1)) == 0;\n\t\t\t\tif (first)\n\t\t\t\t{\n\t\t\t\t\tfirstValue = currentValue;\n\t\t\t\t\tfirst = false;\n\t\t\t\t}\n\t\t\t\telse if (currentValue <= previousValue)\n\t\t\t\t{\n\t\t\t\t\t// If the values are out of order, we fallback to displaying all values.\n\t\t\t\t\treturn EnumValueDisplayMode.All;\n\t\t\t\t}\n\t\t\t\telse if (!allConsecutive && !allPowersOfTwo)\n\t\t\t\t{\n\t\t\t\t\t// We already know that the values are neither consecutive nor all powers of 2,\n\t\t\t\t\t// so we can abort, and just display all values as-is.\n\t\t\t\t\treturn EnumValueDisplayMode.All;\n\t\t\t\t}\n\t\t\t\tpreviousValue = currentValue;\n\t\t\t}\n\t\t\tif (allPowersOfTwo)\n\t\t\t{\n\t\t\t\tif (previousValue > 8)\n\t\t\t\t{\n\t\t\t\t\t// If all values are powers of 2 and greater 8, display all enum values, but use hex.\n\t\t\t\t\treturn EnumValueDisplayMode.AllHex;\n\t\t\t\t}\n\t\t\t\telse if (!allConsecutive)\n\t\t\t\t{\n\t\t\t\t\t// If all values are powers of 2, display all enum values.\n\t\t\t\t\treturn EnumValueDisplayMode.All;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (settings.AlwaysShowEnumMemberValues)\n\t\t\t{\n\t\t\t\t// The user always wants to see all enum values, but we know hex is not necessary.\n\t\t\t\treturn EnumValueDisplayMode.All;\n\t\t\t}\n\t\t\t// We know that all values are consecutive, so if the first value is not 0\n\t\t\t// display the first enum value only.\n\t\t\treturn firstValue == 0 ? EnumValueDisplayMode.None : EnumValueDisplayMode.FirstOnly;\n\t\t}\n\n\t\tEntityDeclaration DoDecompile(IMethod method, DecompileRun decompileRun, ITypeResolveContext decompilationContext, ExtensionInfo extensionInfo)\n\t\t{\n\t\t\tDebug.Assert(decompilationContext.CurrentMember == method);\n\t\t\tvar watch = System.Diagnostics.Stopwatch.StartNew();\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar typeSystemAstBuilder = CreateAstBuilder(decompileRun.Settings);\n\t\t\t\tvar methodDecl = typeSystemAstBuilder.ConvertEntity(method);\n\t\t\t\tint lastDot = method.Name.LastIndexOf('.');\n\t\t\t\tif (methodDecl is not OperatorDeclaration && method.IsExplicitInterfaceImplementation && lastDot >= 0)\n\t\t\t\t{\n\t\t\t\t\tmethodDecl.Name = method.Name.Substring(lastDot + 1);\n\t\t\t\t}\n\t\t\t\tFixParameterNames(methodDecl);\n\t\t\t\tvar methodDefinition = metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken);\n\t\t\t\tif (!settings.LocalFunctions && LocalFunctionDecompiler.LocalFunctionNeedsAccessibilityChange(method.ParentModule.MetadataFile, (MethodDefinitionHandle)method.MetadataToken))\n\t\t\t\t{\n\t\t\t\t\t// if local functions are not active and we're dealing with a local function,\n\t\t\t\t\t// reduce the visibility of the method to private,\n\t\t\t\t\t// otherwise this leads to compile errors because the display classes have lesser accessibility.\n\t\t\t\t\t// Note: removing and then adding the static modifier again is necessary to set the private modifier before all other modifiers.\n\t\t\t\t\tmethodDecl.Modifiers &= ~(Modifiers.Internal | Modifiers.Static);\n\t\t\t\t\tmethodDecl.Modifiers |= Modifiers.Private | (method.IsStatic ? Modifiers.Static : 0);\n\t\t\t\t}\n\t\t\t\tif (methodDefinition.HasBody())\n\t\t\t\t{\n\t\t\t\t\tDecompileBody(method, methodDecl, decompileRun, decompilationContext, extensionInfo);\n\t\t\t\t}\n\t\t\t\telse if (!method.IsAbstract && method.DeclaringType.Kind != TypeKind.Interface)\n\t\t\t\t{\n\t\t\t\t\tmethodDecl.Modifiers |= Modifiers.Extern;\n\t\t\t\t}\n\t\t\t\tif (method.SymbolKind == SymbolKind.Method && !method.IsExplicitInterfaceImplementation\n\t\t\t\t\t&& methodDefinition.HasFlag(System.Reflection.MethodAttributes.Virtual) == methodDefinition.HasFlag(System.Reflection.MethodAttributes.NewSlot))\n\t\t\t\t{\n\t\t\t\t\tSetNewModifier(methodDecl);\n\t\t\t\t}\n\t\t\t\telse if (!method.IsStatic && !method.IsExplicitInterfaceImplementation\n\t\t\t\t\t&& !method.IsVirtual && method.IsOverride\n\t\t\t\t\t&& InheritanceHelper.GetBaseMember(method) == null && IsTypeHierarchyKnown(method.DeclaringType))\n\t\t\t\t{\n\t\t\t\t\tmethodDecl.Modifiers &= ~Modifiers.Override;\n\t\t\t\t\tif (!method.DeclaringTypeDefinition.IsSealed)\n\t\t\t\t\t{\n\t\t\t\t\t\tmethodDecl.Modifiers |= Modifiers.Virtual;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (IsCovariantReturnOverride(method))\n\t\t\t\t{\n\t\t\t\t\tRemoveAttribute(methodDecl, KnownAttribute.PreserveBaseOverrides);\n\t\t\t\t\tmethodDecl.Modifiers &= ~(Modifiers.New | Modifiers.Virtual);\n\t\t\t\t\tmethodDecl.Modifiers |= Modifiers.Override;\n\t\t\t\t}\n\t\t\t\tif (method.IsConstructor && settings.RequiredMembers && RemoveCompilerFeatureRequiredAttribute(methodDecl, \"RequiredMembers\"))\n\t\t\t\t{\n\t\t\t\t\tRemoveObsoleteAttribute(methodDecl, \"Constructors of types with required members are not supported in this version of your compiler.\");\n\t\t\t\t}\n\t\t\t\treturn methodDecl;\n\n\t\t\t\tbool IsTypeHierarchyKnown(IType type)\n\t\t\t\t{\n\t\t\t\t\tvar definition = type.GetDefinition();\n\t\t\t\t\tif (definition == null)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (decompileRun.TypeHierarchyIsKnown.TryGetValue(definition, out var value))\n\t\t\t\t\t\treturn value;\n\t\t\t\t\tvalue = method.DeclaringType.GetNonInterfaceBaseTypes().All(t => t.Kind != TypeKind.Unknown);\n\t\t\t\t\tdecompileRun.TypeHierarchyIsKnown.Add(definition, value);\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\twatch.Stop();\n\t\t\t\tInstrumentation.DecompilerEventSource.Log.DoDecompileMethod(method.FullName, watch.ElapsedMilliseconds);\n\t\t\t}\n\t\t}\n\n\t\tprivate bool IsCovariantReturnOverride(IEntity entity)\n\t\t{\n\t\t\tif (!settings.CovariantReturns)\n\t\t\t\treturn false;\n\t\t\tif (!entity.HasAttribute(KnownAttribute.PreserveBaseOverrides))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tinternal static bool IsWindowsFormsInitializeComponentMethod(IMethod method)\n\t\t{\n\t\t\treturn method.ReturnType.Kind == TypeKind.Void && method.Name == \"InitializeComponent\" && method.DeclaringTypeDefinition.GetNonInterfaceBaseTypes().Any(t => t.FullName == \"System.Windows.Forms.Control\");\n\t\t}\n\n\t\tvoid DecompileBody(IMethod method, EntityDeclaration entityDecl, DecompileRun decompileRun, ITypeResolveContext decompilationContext, ExtensionInfo extensionInfo)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar ilReader = new ILReader(typeSystem.MainModule) {\n\t\t\t\t\tUseDebugSymbols = settings.UseDebugSymbols,\n\t\t\t\t\tUseRefLocalsForAccurateOrderOfEvaluation = settings.UseRefLocalsForAccurateOrderOfEvaluation,\n\t\t\t\t\tDebugInfo = DebugInfoProvider\n\t\t\t\t};\n\t\t\t\tint parameterOffset = 0;\n\t\t\t\tif (extensionInfo != null)\n\t\t\t\t{\n\t\t\t\t\tif (!method.IsStatic)\n\t\t\t\t\t\tparameterOffset = 1; // implementation method has an additional receiver parameter\n\t\t\t\t\tmethod = extensionInfo.InfoOfExtensionMember((IMethod)method.MemberDefinition).Value.ImplementationMethod;\n\t\t\t\t}\n\n\t\t\t\tvar methodDef = metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken);\n\t\t\t\tvar body = BlockStatement.Null;\n\t\t\t\tMethodBodyBlock methodBody;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tmethodBody = module.MetadataFile.GetMethodBody(methodDef.RelativeVirtualAddress);\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException ex)\n\t\t\t\t{\n\t\t\t\t\tbody = new BlockStatement();\n\t\t\t\t\tbody.AddChild(new Comment(\"Invalid MethodBodyBlock: \" + ex.Message), Roles.Comment);\n\t\t\t\t\t// insert explicit rbrace token to make the comment appear within the braces\n\t\t\t\t\tbody.AddChild(new CSharpTokenNode(TextLocation.Empty, Roles.RBrace), Roles.RBrace);\n\t\t\t\t\tentityDecl.AddChild(body, Roles.Body);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tvar function = ilReader.ReadIL((MethodDefinitionHandle)method.MetadataToken, methodBody, cancellationToken: CancellationToken);\n\t\t\t\tfunction.CheckInvariant(ILPhase.Normal);\n\n\t\t\t\tAddAnnotationsToDeclaration(method, entityDecl, function, parameterOffset);\n\n\t\t\t\tvar localSettings = settings.Clone();\n\t\t\t\tif (IsWindowsFormsInitializeComponentMethod(method))\n\t\t\t\t{\n\t\t\t\t\tlocalSettings.UseImplicitMethodGroupConversion = false;\n\t\t\t\t\tlocalSettings.UsingDeclarations = false;\n\t\t\t\t\tlocalSettings.AlwaysCastTargetsOfExplicitInterfaceImplementationCalls = true;\n\t\t\t\t\tlocalSettings.NamedArguments = false;\n\t\t\t\t\tlocalSettings.AlwaysQualifyMemberReferences = true;\n\t\t\t\t}\n\n\t\t\t\tvar context = new ILTransformContext(function, typeSystem, DebugInfoProvider, localSettings) {\n\t\t\t\t\tCancellationToken = CancellationToken,\n\t\t\t\t\tDecompileRun = decompileRun\n\t\t\t\t};\n\t\t\t\tforeach (var transform in ilTransforms)\n\t\t\t\t{\n\t\t\t\t\tCancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\ttransform.Run(function, context);\n\t\t\t\t\tfunction.CheckInvariant(ILPhase.Normal);\n\t\t\t\t\t// When decompiling definitions only, we can cancel decompilation of all steps\n\t\t\t\t\t// after yield and async detection, because only those are needed to properly set\n\t\t\t\t\t// IsAsync/IsIterator flags on ILFunction.\n\t\t\t\t\tif (!localSettings.DecompileMemberBodies && transform is AsyncAwaitDecompiler)\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// Generate C# AST only if bodies should be displayed.\n\t\t\t\tif (localSettings.DecompileMemberBodies)\n\t\t\t\t{\n\t\t\t\t\tAddDefinesForConditionalAttributes(function, decompileRun);\n\t\t\t\t\tvar statementBuilder = new StatementBuilder(\n\t\t\t\t\t\ttypeSystem,\n\t\t\t\t\t\tdecompilationContext,\n\t\t\t\t\t\tfunction,\n\t\t\t\t\t\tlocalSettings,\n\t\t\t\t\t\tdecompileRun,\n\t\t\t\t\t\tCancellationToken\n\t\t\t\t\t);\n\t\t\t\t\tbody = statementBuilder.ConvertAsBlock(function.Body);\n\n\t\t\t\t\tComment prev = null;\n\t\t\t\t\tforeach (string warning in function.Warnings)\n\t\t\t\t\t{\n\t\t\t\t\t\tbody.InsertChildAfter(prev, prev = new Comment(warning), Roles.Comment);\n\t\t\t\t\t}\n\n\t\t\t\t\tentityDecl.AddChild(body, Roles.Body);\n\t\t\t\t}\n\n\t\t\t\tCleanUpMethodDeclaration(entityDecl, body, function, localSettings.DecompileMemberBodies);\n\t\t\t}\n\t\t\tcatch (Exception innerException) when (!(innerException is OperationCanceledException || innerException is DecompilerException))\n\t\t\t{\n\t\t\t\tthrow new DecompilerException(module, method, innerException);\n\t\t\t}\n\t\t}\n\n\t\tinternal static void AddAnnotationsToDeclaration(IMethod method, EntityDeclaration entityDecl, ILFunction function, int parameterOffset = 0)\n\t\t{\n\t\t\tint i = parameterOffset;\n\t\t\tvar parameters = function.Variables.Where(v => v.Kind == VariableKind.Parameter).ToDictionary(v => v.Index);\n\t\t\tforeach (var parameter in entityDecl.GetChildrenByRole(Roles.Parameter))\n\t\t\t{\n\t\t\t\tif (parameters.TryGetValue(i, out var v))\n\t\t\t\t\tparameter.AddAnnotation(new ILVariableResolveResult(v, method.Parameters[i].Type));\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tentityDecl.AddAnnotation(function);\n\t\t}\n\n\t\tinternal static void CleanUpMethodDeclaration(EntityDeclaration entityDecl, BlockStatement body, ILFunction function, bool decompileBody = true)\n\t\t{\n\t\t\tif (function.IsIterator)\n\t\t\t{\n\t\t\t\tif (decompileBody && !body.Descendants.Any(d => d is YieldReturnStatement || d is YieldBreakStatement))\n\t\t\t\t{\n\t\t\t\t\tbody.Add(new YieldBreakStatement());\n\t\t\t\t}\n\t\t\t\tif (function.IsAsync)\n\t\t\t\t{\n\t\t\t\t\tRemoveAttribute(entityDecl, KnownAttribute.AsyncIteratorStateMachine);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tRemoveAttribute(entityDecl, KnownAttribute.IteratorStateMachine);\n\t\t\t\t}\n\t\t\t\tif (function.StateMachineCompiledWithMono)\n\t\t\t\t{\n\t\t\t\t\tRemoveAttribute(entityDecl, KnownAttribute.DebuggerHidden);\n\t\t\t\t}\n\t\t\t\tif (function.StateMachineCompiledWithLegacyVisualBasic)\n\t\t\t\t{\n\t\t\t\t\tRemoveAttribute(entityDecl, KnownAttribute.DebuggerStepThrough);\n\t\t\t\t\tif (function.Method?.IsAccessor == true && entityDecl.Parent is EntityDeclaration parentDecl)\n\t\t\t\t\t{\n\t\t\t\t\t\tRemoveAttribute(parentDecl, KnownAttribute.DebuggerStepThrough);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (function.IsAsync)\n\t\t\t{\n\t\t\t\tentityDecl.Modifiers |= Modifiers.Async;\n\t\t\t\tRemoveAttribute(entityDecl, KnownAttribute.AsyncStateMachine);\n\t\t\t\tRemoveAttribute(entityDecl, KnownAttribute.DebuggerStepThrough);\n\t\t\t}\n\t\t}\n\n\t\tinternal static bool RemoveAttribute(EntityDeclaration entityDecl, KnownAttribute attributeType)\n\t\t{\n\t\t\tbool found = false;\n\t\t\tforeach (var section in entityDecl.Attributes)\n\t\t\t{\n\t\t\t\tforeach (var attr in section.Attributes)\n\t\t\t\t{\n\t\t\t\t\tvar symbol = attr.Type.GetSymbol();\n\t\t\t\t\tif (symbol is ITypeDefinition td && td.FullTypeName == attributeType.GetTypeName())\n\t\t\t\t\t{\n\t\t\t\t\t\tattr.Remove();\n\t\t\t\t\t\tfound = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (section.Attributes.Count == 0)\n\t\t\t\t{\n\t\t\t\t\tsection.Remove();\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn found;\n\t\t}\n\n\t\tinternal static bool RemoveCompilerFeatureRequiredAttribute(EntityDeclaration entityDecl, string feature)\n\t\t{\n\t\t\tbool found = false;\n\t\t\tforeach (var section in entityDecl.Attributes)\n\t\t\t{\n\t\t\t\tforeach (var attr in section.Attributes)\n\t\t\t\t{\n\t\t\t\t\tvar symbol = attr.Type.GetSymbol();\n\t\t\t\t\tif (symbol is ITypeDefinition td && td.FullTypeName == KnownAttribute.CompilerFeatureRequired.GetTypeName()\n\t\t\t\t\t\t&& attr.Arguments.Count == 1 && attr.Arguments.SingleOrDefault() is PrimitiveExpression pe\n\t\t\t\t\t\t&& pe.Value is string s && s == feature)\n\t\t\t\t\t{\n\t\t\t\t\t\tattr.Remove();\n\t\t\t\t\t\tfound = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (section.Attributes.Count == 0)\n\t\t\t\t{\n\t\t\t\t\tsection.Remove();\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn found;\n\t\t}\n\n\t\tinternal static bool RemoveObsoleteAttribute(EntityDeclaration entityDecl, string message)\n\t\t{\n\t\t\tbool found = false;\n\t\t\tforeach (var section in entityDecl.Attributes)\n\t\t\t{\n\t\t\t\tforeach (var attr in section.Attributes)\n\t\t\t\t{\n\t\t\t\t\tvar symbol = attr.Type.GetSymbol();\n\t\t\t\t\tif (symbol is ITypeDefinition td && td.FullTypeName == KnownAttribute.Obsolete.GetTypeName()\n\t\t\t\t\t\t&& attr.Arguments.Count >= 1 && attr.Arguments.First() is PrimitiveExpression pe\n\t\t\t\t\t\t&& pe.Value is string s && s == message)\n\t\t\t\t\t{\n\t\t\t\t\t\tattr.Remove();\n\t\t\t\t\t\tfound = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (section.Attributes.Count == 0)\n\t\t\t\t{\n\t\t\t\t\tsection.Remove();\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn found;\n\t\t}\n\n\t\tbool FindAttribute(EntityDeclaration entityDecl, KnownAttribute attributeType, out Syntax.Attribute attribute)\n\t\t{\n\t\t\tattribute = null;\n\t\t\tforeach (var section in entityDecl.Attributes)\n\t\t\t{\n\t\t\t\tforeach (var attr in section.Attributes)\n\t\t\t\t{\n\t\t\t\t\tvar symbol = attr.Type.GetSymbol();\n\t\t\t\t\tif (symbol is ITypeDefinition td && td.FullTypeName == attributeType.GetTypeName())\n\t\t\t\t\t{\n\t\t\t\t\t\tattribute = attr;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tvoid AddDefinesForConditionalAttributes(ILFunction function, DecompileRun decompileRun)\n\t\t{\n\t\t\tforeach (var call in function.Descendants.OfType<CallInstruction>())\n\t\t\t{\n\t\t\t\tvar attr = call.Method.GetAttribute(KnownAttribute.Conditional, inherit: true);\n\t\t\t\tvar symbolName = attr?.FixedArguments.FirstOrDefault().Value as string;\n\t\t\t\tif (symbolName == null || !decompileRun.DefinedSymbols.Add(symbolName))\n\t\t\t\t\tcontinue;\n\t\t\t\tsyntaxTree.InsertChildAfter(null, new PreProcessorDirective(PreProcessorDirectiveType.Define, symbolName), Roles.PreProcessorDirective);\n\t\t\t}\n\t\t}\n\n\t\tEntityDeclaration DoDecompile(IField field, DecompileRun decompileRun, ITypeResolveContext decompilationContext)\n\t\t{\n\t\t\tDebug.Assert(decompilationContext.CurrentMember == field);\n\t\t\tvar watch = System.Diagnostics.Stopwatch.StartNew();\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar typeSystemAstBuilder = CreateAstBuilder(decompileRun.Settings);\n\t\t\t\tif (decompilationContext.CurrentTypeDefinition.Kind == TypeKind.Enum && field.IsConst)\n\t\t\t\t{\n\t\t\t\t\tvar enumDec = new EnumMemberDeclaration { Name = field.Name };\n\t\t\t\t\tobject constantValue = field.GetConstantValue();\n\t\t\t\t\tif (constantValue != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tenumDec.Initializer = typeSystemAstBuilder.ConvertConstantValue(decompilationContext.CurrentTypeDefinition.EnumUnderlyingType, constantValue);\n\t\t\t\t\t}\n\t\t\t\t\tenumDec.Attributes.AddRange(field.GetAttributes().Select(a => new AttributeSection(typeSystemAstBuilder.ConvertAttribute(a))));\n\t\t\t\t\tenumDec.AddAnnotation(new MemberResolveResult(null, field));\n\t\t\t\t\treturn enumDec;\n\t\t\t\t}\n\t\t\t\tbool isMathPIOrE = ((field.Name == \"PI\" || field.Name == \"E\") && (field.DeclaringType.FullName == \"System.Math\" || field.DeclaringType.FullName == \"System.MathF\"));\n\t\t\t\ttypeSystemAstBuilder.UseSpecialConstants = !(field.DeclaringType.Equals(field.ReturnType) || isMathPIOrE);\n\t\t\t\tvar fieldDecl = typeSystemAstBuilder.ConvertEntity(field);\n\t\t\t\tSetNewModifier(fieldDecl);\n\t\t\t\tif (settings.RequiredMembers && RemoveAttribute(fieldDecl, KnownAttribute.Required))\n\t\t\t\t{\n\t\t\t\t\tfieldDecl.Modifiers |= Modifiers.Required;\n\t\t\t\t}\n\t\t\t\tif (settings.FixedBuffers && IsFixedField(field, out var elementType, out var elementCount))\n\t\t\t\t{\n\t\t\t\t\tvar fixedFieldDecl = new FixedFieldDeclaration();\n\t\t\t\t\tfieldDecl.Attributes.MoveTo(fixedFieldDecl.Attributes);\n\t\t\t\t\tfixedFieldDecl.Modifiers = fieldDecl.Modifiers;\n\t\t\t\t\tfixedFieldDecl.ReturnType = typeSystemAstBuilder.ConvertType(elementType);\n\t\t\t\t\tfixedFieldDecl.Variables.Add(new FixedVariableInitializer(field.Name, new PrimitiveExpression(elementCount)));\n\t\t\t\t\tfixedFieldDecl.Variables.Single().CopyAnnotationsFrom(((FieldDeclaration)fieldDecl).Variables.Single());\n\t\t\t\t\tfixedFieldDecl.CopyAnnotationsFrom(fieldDecl);\n\t\t\t\t\tRemoveAttribute(fixedFieldDecl, KnownAttribute.FixedBuffer);\n\t\t\t\t\treturn fixedFieldDecl;\n\t\t\t\t}\n\t\t\t\tvar fieldDefinition = metadata.GetFieldDefinition((FieldDefinitionHandle)field.MetadataToken);\n\t\t\t\tif (fieldDefinition.HasFlag(System.Reflection.FieldAttributes.HasFieldRVA))\n\t\t\t\t{\n\t\t\t\t\t// Field data as specified in II.16.3.1 of ECMA-335 6th edition:\n\t\t\t\t\t// .data I_X = int32(123)\n\t\t\t\t\t// .field public static int32 _x at I_X\n\t\t\t\t\tstring message;\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tvar initVal = fieldDefinition.GetInitialValue(module.MetadataFile, TypeSystem);\n\t\t\t\t\t\tmessage = string.Format(\" Not supported: data({0}) \", BitConverter.ToString(initVal.ReadBytes(initVal.RemainingBytes)).Replace('-', ' '));\n\t\t\t\t\t}\n\t\t\t\t\tcatch (BadImageFormatException ex)\n\t\t\t\t\t{\n\t\t\t\t\t\tmessage = ex.Message;\n\t\t\t\t\t}\n\t\t\t\t\t((FieldDeclaration)fieldDecl).Variables.Single().AddChild(new Comment(message, CommentType.MultiLine), Roles.Comment);\n\t\t\t\t}\n\t\t\t\treturn fieldDecl;\n\t\t\t}\n\t\t\tcatch (Exception innerException) when (!(innerException is OperationCanceledException || innerException is DecompilerException))\n\t\t\t{\n\t\t\t\tthrow new DecompilerException(module, field, innerException);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\twatch.Stop();\n\t\t\t\tInstrumentation.DecompilerEventSource.Log.DoDecompileField(field.FullName, watch.ElapsedMilliseconds);\n\t\t\t}\n\t\t}\n\n\t\tinternal static bool IsFixedField(IField field, out IType type, out int elementCount)\n\t\t{\n\t\t\ttype = null;\n\t\t\telementCount = 0;\n\t\t\tIAttribute attr = field.GetAttribute(KnownAttribute.FixedBuffer);\n\t\t\tif (attr != null && attr.FixedArguments.Length == 2)\n\t\t\t{\n\t\t\t\tif (attr.FixedArguments[0].Value is IType trr && attr.FixedArguments[1].Value is int length)\n\t\t\t\t{\n\t\t\t\t\ttype = trr;\n\t\t\t\t\telementCount = length;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tEntityDeclaration DoDecompile(IProperty property, DecompileRun decompileRun, ITypeResolveContext decompilationContext, ExtensionInfo extensionInfo)\n\t\t{\n\t\t\tDebug.Assert(decompilationContext.CurrentMember == property);\n\t\t\tvar watch = System.Diagnostics.Stopwatch.StartNew();\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar typeSystemAstBuilder = CreateAstBuilder(decompileRun.Settings);\n\t\t\t\tEntityDeclaration propertyDecl = typeSystemAstBuilder.ConvertEntity(property);\n\t\t\t\tif (property.IsExplicitInterfaceImplementation && !property.IsIndexer)\n\t\t\t\t{\n\t\t\t\t\tint lastDot = property.Name.LastIndexOf('.');\n\t\t\t\t\tpropertyDecl.Name = property.Name.Substring(lastDot + 1);\n\t\t\t\t}\n\t\t\t\tFixParameterNames(propertyDecl);\n\t\t\t\tAccessor getter, setter;\n\t\t\t\tif (propertyDecl is PropertyDeclaration)\n\t\t\t\t{\n\t\t\t\t\tgetter = ((PropertyDeclaration)propertyDecl).Getter;\n\t\t\t\t\tsetter = ((PropertyDeclaration)propertyDecl).Setter;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tgetter = ((IndexerDeclaration)propertyDecl).Getter;\n\t\t\t\t\tsetter = ((IndexerDeclaration)propertyDecl).Setter;\n\t\t\t\t}\n\n\t\t\t\tbool getterHasBody = property.CanGet && property.Getter.HasBody;\n\t\t\t\tbool setterHasBody = property.CanSet && property.Setter.HasBody;\n\t\t\t\tif (getterHasBody)\n\t\t\t\t{\n\t\t\t\t\tDecompileBody(property.Getter, getter, decompileRun, decompilationContext, extensionInfo);\n\t\t\t\t}\n\t\t\t\tif (setterHasBody)\n\t\t\t\t{\n\t\t\t\t\tDecompileBody(property.Setter, setter, decompileRun, decompilationContext, extensionInfo);\n\t\t\t\t}\n\t\t\t\tif (!getterHasBody && !setterHasBody && !property.IsAbstract && property.DeclaringType.Kind != TypeKind.Interface)\n\t\t\t\t{\n\t\t\t\t\tpropertyDecl.Modifiers |= Modifiers.Extern;\n\t\t\t\t}\n\t\t\t\tvar accessorHandle = (MethodDefinitionHandle)(property.Getter ?? property.Setter).MetadataToken;\n\t\t\t\tvar accessor = metadata.GetMethodDefinition(accessorHandle);\n\t\t\t\tif (!accessorHandle.GetMethodImplementations(metadata).Any() && accessor.HasFlag(System.Reflection.MethodAttributes.Virtual) == accessor.HasFlag(System.Reflection.MethodAttributes.NewSlot))\n\t\t\t\t{\n\t\t\t\t\tSetNewModifier(propertyDecl);\n\t\t\t\t}\n\t\t\t\tif (property.CanGet && IsCovariantReturnOverride(property.Getter))\n\t\t\t\t{\n\t\t\t\t\tRemoveAttribute(getter, KnownAttribute.PreserveBaseOverrides);\n\t\t\t\t\tpropertyDecl.Modifiers &= ~(Modifiers.New | Modifiers.Virtual);\n\t\t\t\t\tpropertyDecl.Modifiers |= Modifiers.Override;\n\t\t\t\t}\n\t\t\t\tif (settings.RequiredMembers && RemoveAttribute(propertyDecl, KnownAttribute.Required))\n\t\t\t\t{\n\t\t\t\t\tpropertyDecl.Modifiers |= Modifiers.Required;\n\t\t\t\t}\n\t\t\t\treturn propertyDecl;\n\t\t\t}\n\t\t\tcatch (Exception innerException) when (!(innerException is OperationCanceledException || innerException is DecompilerException))\n\t\t\t{\n\t\t\t\tthrow new DecompilerException(module, property, innerException);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\twatch.Stop();\n\t\t\t\tInstrumentation.DecompilerEventSource.Log.DoDecompileProperty(property.FullName, watch.ElapsedMilliseconds);\n\t\t\t}\n\t\t}\n\n\t\tEntityDeclaration DoDecompile(IEvent ev, DecompileRun decompileRun, ITypeResolveContext decompilationContext)\n\t\t{\n\t\t\tDebug.Assert(decompilationContext.CurrentMember == ev);\n\t\t\tvar watch = System.Diagnostics.Stopwatch.StartNew();\n\t\t\ttry\n\t\t\t{\n\t\t\t\tbool adderHasBody = ev.CanAdd && ev.AddAccessor.HasBody;\n\t\t\t\tbool removerHasBody = ev.CanRemove && ev.RemoveAccessor.HasBody;\n\t\t\t\tvar typeSystemAstBuilder = CreateAstBuilder(decompileRun.Settings);\n\t\t\t\ttypeSystemAstBuilder.UseCustomEvents = ev.DeclaringTypeDefinition.Kind != TypeKind.Interface\n\t\t\t\t\t|| ev.IsExplicitInterfaceImplementation\n\t\t\t\t\t|| adderHasBody\n\t\t\t\t\t|| removerHasBody;\n\t\t\t\tvar eventDecl = typeSystemAstBuilder.ConvertEntity(ev);\n\t\t\t\tint lastDot = ev.Name.LastIndexOf('.');\n\t\t\t\tif (ev.IsExplicitInterfaceImplementation)\n\t\t\t\t{\n\t\t\t\t\teventDecl.Name = ev.Name.Substring(lastDot + 1);\n\t\t\t\t}\n\t\t\t\tif (adderHasBody)\n\t\t\t\t{\n\t\t\t\t\tDecompileBody(ev.AddAccessor, ((CustomEventDeclaration)eventDecl).AddAccessor, decompileRun, decompilationContext, null);\n\t\t\t\t}\n\t\t\t\tif (removerHasBody)\n\t\t\t\t{\n\t\t\t\t\tDecompileBody(ev.RemoveAccessor, ((CustomEventDeclaration)eventDecl).RemoveAccessor, decompileRun, decompilationContext, null);\n\t\t\t\t}\n\t\t\t\tif (!adderHasBody && !removerHasBody && !ev.IsAbstract && ev.DeclaringType.Kind != TypeKind.Interface)\n\t\t\t\t{\n\t\t\t\t\teventDecl.Modifiers |= Modifiers.Extern;\n\t\t\t\t}\n\t\t\t\tvar accessor = metadata.GetMethodDefinition((MethodDefinitionHandle)(ev.AddAccessor ?? ev.RemoveAccessor).MetadataToken);\n\t\t\t\tif (accessor.HasFlag(System.Reflection.MethodAttributes.Virtual) == accessor.HasFlag(System.Reflection.MethodAttributes.NewSlot))\n\t\t\t\t{\n\t\t\t\t\tSetNewModifier(eventDecl);\n\t\t\t\t}\n\t\t\t\treturn eventDecl;\n\t\t\t}\n\t\t\tcatch (Exception innerException) when (!(innerException is OperationCanceledException || innerException is DecompilerException))\n\t\t\t{\n\t\t\t\tthrow new DecompilerException(module, ev, innerException);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\twatch.Stop();\n\t\t\t\tInstrumentation.DecompilerEventSource.Log.DoDecompileEvent(ev.FullName, watch.ElapsedMilliseconds);\n\t\t\t}\n\t\t}\n\n\t\t#region Sequence Points\n\t\t/// <summary>\n\t\t/// Creates sequence points for the given syntax tree.\n\t\t/// \n\t\t/// This only works correctly when the nodes in the syntax tree have line/column information.\n\t\t/// </summary>\n\t\tpublic Dictionary<ILFunction, List<DebugInfo.SequencePoint>> CreateSequencePoints(SyntaxTree syntaxTree)\n\t\t{\n\t\t\tSequencePointBuilder spb = new SequencePointBuilder();\n\t\t\tsyntaxTree.AcceptVisitor(spb);\n\t\t\treturn spb.GetSequencePoints();\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/CSharpLanguageVersion.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp\n{\n\tpublic enum LanguageVersion\n\t{\n\t\tCSharp1 = 1,\n\t\tCSharp2 = 2,\n\t\tCSharp3 = 3,\n\t\tCSharp4 = 4,\n\t\tCSharp5 = 5,\n\t\tCSharp6 = 6,\n\t\tCSharp7 = 7,\n\t\tCSharp7_1 = 701,\n\t\tCSharp7_2 = 702,\n\t\tCSharp7_3 = 703,\n\t\tCSharp8_0 = 800,\n\t\tCSharp9_0 = 900,\n\t\tCSharp10_0 = 1000,\n\t\tCSharp11_0 = 1100,\n\t\tCSharp12_0 = 1200,\n\t\tCSharp13_0 = 1300,\n\t\tCSharp14_0 = 1400,\n\t\tPreview = 1400,\n\t\tLatest = 0x7FFFFFFF\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/CallBuilder.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.CSharp.Resolver;\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp\n{\n\tstruct CallBuilder\n\t{\n\t\tstruct ExpectedTargetDetails\n\t\t{\n\t\t\tpublic OpCode CallOpCode;\n\t\t\tpublic bool NeedsBoxingConversion;\n\t\t}\n\n\t\tstruct ArgumentList\n\t\t{\n\t\t\tpublic TranslatedExpression[] Arguments;\n\t\t\tpublic IParameter[] ExpectedParameters;\n\t\t\tpublic string[] ParameterNames;\n\t\t\tpublic string[] ArgumentNames;\n\t\t\tpublic int FirstOptionalArgumentIndex;\n\t\t\tpublic BitSet IsPrimitiveValue;\n\t\t\tpublic IReadOnlyList<int> ArgumentToParameterMap;\n\n\t\t\tpublic bool AddNamesToPrimitiveValues;\n\t\t\tpublic bool UseImplicitlyTypedOut;\n\t\t\tpublic bool IsExpandedForm;\n\t\t\tpublic int Length => Arguments.Length;\n\n\t\t\tprivate int GetActualArgumentCount()\n\t\t\t{\n\t\t\t\tif (FirstOptionalArgumentIndex < 0)\n\t\t\t\t\treturn Arguments.Length;\n\t\t\t\treturn FirstOptionalArgumentIndex;\n\t\t\t}\n\n\t\t\tpublic string[] GetArgumentNames(int skipCount = 0)\n\t\t\t{\n\t\t\t\tstring[] argumentNames = ArgumentNames;\n\t\t\t\tif (AddNamesToPrimitiveValues && IsPrimitiveValue.Any() && !IsExpandedForm\n\t\t\t\t\t\t&& !ParameterNames.Any(string.IsNullOrEmpty))\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(skipCount == 0);\n\t\t\t\t\tif (argumentNames == null)\n\t\t\t\t\t{\n\t\t\t\t\t\targumentNames = new string[Arguments.Length];\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (int i = 0; i < Arguments.Length; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (IsPrimitiveValue[i] && argumentNames[i] == null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\targumentNames[i] = ParameterNames[i];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn argumentNames;\n\t\t\t}\n\n\t\t\tpublic IList<ResolveResult> GetArgumentResolveResults(int skipCount = 0)\n\t\t\t{\n\t\t\t\tvar expectedParameters = ExpectedParameters;\n\t\t\t\tvar useImplicitlyTypedOut = UseImplicitlyTypedOut;\n\n\t\t\t\treturn Arguments\n\t\t\t\t\t.SelectWithIndex(GetResolveResult)\n\t\t\t\t\t.Skip(skipCount)\n\t\t\t\t\t.Take(GetActualArgumentCount())\n\t\t\t\t\t.ToArray();\n\n\t\t\t\tResolveResult GetResolveResult(int index, TranslatedExpression expression)\n\t\t\t\t{\n\t\t\t\t\tvar param = expectedParameters[index];\n\t\t\t\t\tif (useImplicitlyTypedOut && param.ReferenceKind == ReferenceKind.Out && expression.Type is ByReferenceType brt)\n\t\t\t\t\t\treturn new OutVarResolveResult(brt.ElementType);\n\t\t\t\t\treturn expression.ResolveResult;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic IList<ResolveResult> GetArgumentResolveResultsDirect(int skipCount = 0)\n\t\t\t{\n\t\t\t\treturn Arguments\n\t\t\t\t\t.Skip(skipCount)\n\t\t\t\t\t.Take(GetActualArgumentCount())\n\t\t\t\t\t.Select(a => a.ResolveResult)\n\t\t\t\t\t.ToArray();\n\t\t\t}\n\n\t\t\tpublic IEnumerable<Expression> GetArgumentExpressions(int skipCount = 0)\n\t\t\t{\n\t\t\t\tvar argumentNames = GetArgumentNames(skipCount);\n\t\t\t\tint argumentCount = GetActualArgumentCount();\n\t\t\t\tvar useImplicitlyTypedOut = UseImplicitlyTypedOut;\n\t\t\t\tif (argumentNames == null)\n\t\t\t\t{\n\t\t\t\t\treturn Arguments.Skip(skipCount).Take(argumentCount).Select(arg => AddAnnotations(arg.Expression));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(skipCount == 0);\n\t\t\t\t\treturn Arguments.Take(argumentCount).Zip(argumentNames.Take(argumentCount),\n\t\t\t\t\t\t(arg, name) => {\n\t\t\t\t\t\t\tif (name == null)\n\t\t\t\t\t\t\t\treturn AddAnnotations(arg.Expression);\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\treturn new NamedArgumentExpression(name, AddAnnotations(arg.Expression));\n\t\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tExpression AddAnnotations(Expression expression)\n\t\t\t\t{\n\t\t\t\t\tif (!useImplicitlyTypedOut)\n\t\t\t\t\t\treturn expression;\n\t\t\t\t\tif (expression.GetResolveResult() is ByReferenceResolveResult { ReferenceKind: ReferenceKind.Out } brrr)\n\t\t\t\t\t{\n\t\t\t\t\t\texpression.AddAnnotation(UseImplicitlyTypedOutAnnotation.Instance);\n\t\t\t\t\t}\n\t\t\t\t\treturn expression;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic bool CanInferAnonymousTypePropertyNamesFromArguments()\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < Arguments.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tstring inferredName;\n\t\t\t\t\tswitch (Arguments[i].Expression)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase IdentifierExpression identifier:\n\t\t\t\t\t\t\tinferredName = identifier.Identifier;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase MemberReferenceExpression member:\n\t\t\t\t\t\t\tinferredName = member.MemberName;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tinferredName = null;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (inferredName != ExpectedParameters[i].Name)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t[Conditional(\"DEBUG\")]\n\t\t\tpublic void CheckNoNamedOrOptionalArguments()\n\t\t\t{\n\t\t\t\tDebug.Assert(ArgumentToParameterMap == null && ArgumentNames == null && FirstOptionalArgumentIndex < 0);\n\t\t\t}\n\t\t}\n\n\t\treadonly DecompilerSettings settings;\n\t\treadonly ExpressionBuilder expressionBuilder;\n\t\treadonly CSharpResolver resolver;\n\t\treadonly IDecompilerTypeSystem typeSystem;\n\n\t\tpublic CallBuilder(ExpressionBuilder expressionBuilder, IDecompilerTypeSystem typeSystem, DecompilerSettings settings)\n\t\t{\n\t\t\tthis.expressionBuilder = expressionBuilder;\n\t\t\tthis.resolver = expressionBuilder.resolver;\n\t\t\tthis.settings = settings;\n\t\t\tthis.typeSystem = typeSystem;\n\t\t}\n\n\t\tpublic TranslatedExpression Build(CallInstruction inst, IType typeHint = null)\n\t\t{\n\t\t\tif (inst is NewObj newobj && IL.Transforms.DelegateConstruction.MatchDelegateConstruction(newobj, out _, out _, out _))\n\t\t\t{\n\t\t\t\treturn HandleDelegateConstruction(newobj);\n\t\t\t}\n\t\t\tif (settings.TupleTypes && TupleTransform.MatchTupleConstruction(inst as NewObj, out var tupleElements) && tupleElements.Length >= 2)\n\t\t\t{\n\t\t\t\tvar elementTypes = TupleType.GetTupleElementTypes(inst.Method.DeclaringType);\n\t\t\t\tvar elementNames = typeHint is TupleType tt ? tt.ElementNames : default;\n\t\t\t\tDebug.Assert(!elementTypes.IsDefault, \"MatchTupleConstruction should not succeed unless we got a valid tuple type.\");\n\t\t\t\tDebug.Assert(elementTypes.Length == tupleElements.Length);\n\t\t\t\tvar tuple = new TupleExpression();\n\t\t\t\tvar elementRRs = new List<ResolveResult>();\n\t\t\t\tforeach (var (index, element, elementType) in tupleElements.ZipWithIndex(elementTypes))\n\t\t\t\t{\n\t\t\t\t\tvar translatedElement = expressionBuilder.Translate(element, elementType)\n\t\t\t\t\t\t.ConvertTo(elementType, expressionBuilder, allowImplicitConversion: true);\n\t\t\t\t\tif (elementNames.IsDefaultOrEmpty || elementNames.ElementAtOrDefault(index) is not string { Length: > 0 } name)\n\t\t\t\t\t{\n\t\t\t\t\t\ttuple.Elements.Add(translatedElement.Expression);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\ttuple.Elements.Add(new NamedArgumentExpression(name, translatedElement.Expression));\n\t\t\t\t\t}\n\t\t\t\t\telementRRs.Add(translatedElement.ResolveResult);\n\t\t\t\t}\n\t\t\t\treturn tuple.WithRR(new TupleResolveResult(\n\t\t\t\t\texpressionBuilder.compilation,\n\t\t\t\t\telementRRs.ToImmutableArray(),\n\t\t\t\t\telementNames,\n\t\t\t\t\tvalueTupleAssembly: inst.Method.DeclaringType.GetDefinition()?.ParentModule\n\t\t\t\t)).WithILInstruction(inst);\n\t\t\t}\n\t\t\tif (settings.StringConcat && IsSpanBasedStringConcat(inst, out var operands))\n\t\t\t{\n\t\t\t\treturn BuildStringConcat(inst.Method, operands).WithILInstruction(inst);\n\t\t\t}\n\t\t\treturn Build(inst.OpCode, inst.Method, inst.Arguments, constrainedTo: inst.ConstrainedTo)\n\t\t\t\t.WithILInstruction(inst);\n\t\t}\n\n\t\tprivate ExpressionWithResolveResult BuildStringConcat(IMethod method, List<(ILInstruction Instruction, KnownTypeCode TypeCode)> operands)\n\t\t{\n\t\t\tIType type = typeSystem.FindType(operands[0].TypeCode);\n\t\t\tExpressionWithResolveResult result = expressionBuilder.Translate(operands[0].Instruction, type).ConvertTo(type, expressionBuilder);\n\t\t\tvar rr = new MemberResolveResult(null, method);\n\n\t\t\tfor (int i = 1; i < operands.Count; i++)\n\t\t\t{\n\t\t\t\ttype = typeSystem.FindType(operands[i].TypeCode);\n\t\t\t\tvar expr = expressionBuilder.Translate(operands[i].Instruction, type).ConvertTo(type, expressionBuilder);\n\t\t\t\tresult = new BinaryOperatorExpression(result.Expression, BinaryOperatorType.Add, expr).WithRR(rr);\n\t\t\t}\n\n\t\t\treturn result;\n\t\t}\n\n\t\tstatic bool IsSpanBasedStringConcat(CallInstruction call, out List<(ILInstruction, KnownTypeCode)> operands)\n\t\t{\n\t\t\toperands = null;\n\n\t\t\tif (!IsSpanBasedStringConcat(call.Method))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tint? firstStringArgumentIndex = null;\n\t\t\toperands = new();\n\n\t\t\tforeach (var arg in call.Arguments)\n\t\t\t{\n\t\t\t\tif (arg is Call opImplicit && IsStringToReadOnlySpanCharImplicitConversion(opImplicit.Method))\n\t\t\t\t{\n\t\t\t\t\tfirstStringArgumentIndex ??= arg.ChildIndex;\n\t\t\t\t\toperands.Add((opImplicit.Arguments.Single(), KnownTypeCode.String));\n\t\t\t\t}\n\t\t\t\telse if (arg is NewObj { Arguments: [AddressOf addressOf] } newObj && ILInlining.IsReadOnlySpanCharCtor(newObj.Method))\n\t\t\t\t{\n\t\t\t\t\toperands.Add((addressOf.Value, KnownTypeCode.Char));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn call.Arguments.Count >= 2 && firstStringArgumentIndex <= 1;\n\t\t}\n\n\t\tinternal static bool IsSpanBasedStringConcat(IMethod method)\n\t\t{\n\t\t\tif (method is not { Name: \"Concat\", IsStatic: true })\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!method.DeclaringType.IsKnownType(KnownTypeCode.String))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tforeach (var p in method.Parameters)\n\t\t\t{\n\t\t\t\tif (!p.Type.IsKnownType(KnownTypeCode.ReadOnlySpanOfT))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!p.Type.TypeArguments[0].IsKnownType(KnownTypeCode.Char))\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tinternal static bool IsStringToReadOnlySpanCharImplicitConversion(IMethod method)\n\t\t{\n\t\t\treturn method.IsOperator\n\t\t\t\t&& method.Name == \"op_Implicit\"\n\t\t\t\t&& method.Parameters.Count == 1\n\t\t\t\t&& method.ReturnType.IsKnownType(KnownTypeCode.ReadOnlySpanOfT)\n\t\t\t\t&& method.ReturnType.TypeArguments[0].IsKnownType(KnownTypeCode.Char)\n\t\t\t\t&& method.Parameters[0].Type.IsKnownType(KnownTypeCode.String);\n\t\t}\n\n\t\tpublic ExpressionWithResolveResult Build(OpCode callOpCode, IMethod method,\n\t\t\tIReadOnlyList<ILInstruction> callArguments,\n\t\t\tIReadOnlyList<int> argumentToParameterMap = null,\n\t\t\tIType constrainedTo = null)\n\t\t{\n\t\t\tif (method.IsExplicitInterfaceImplementation && callOpCode == OpCode.Call)\n\t\t\t{\n\t\t\t\t// Direct non-virtual call to explicit interface implementation.\n\t\t\t\t// This can't really be represented in C#, but at least in the case where\n\t\t\t\t// the class is sealed, we can equivalently call the interface member instead:\n\t\t\t\tvar interfaceMembers = method.ExplicitlyImplementedInterfaceMembers.ToList();\n\t\t\t\tif (method.DeclaringTypeDefinition?.Kind == TypeKind.Class && method.DeclaringTypeDefinition.IsSealed && interfaceMembers.Count == 1)\n\t\t\t\t{\n\t\t\t\t\tmethod = (IMethod)interfaceMembers.Single();\n\t\t\t\t\tcallOpCode = OpCode.CallVirt;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Used for Call, CallVirt and NewObj\n\t\t\tvar expectedTargetDetails = new ExpectedTargetDetails {\n\t\t\t\tCallOpCode = callOpCode\n\t\t\t};\n\t\t\tILFunction localFunction = null;\n\t\t\tif (method.IsLocalFunction)\n\t\t\t{\n\t\t\t\tlocalFunction = expressionBuilder.ResolveLocalFunction(method);\n\t\t\t\tDebug.Assert(localFunction != null);\n\t\t\t}\n\t\t\tTranslatedExpression target;\n\t\t\tif (callOpCode == OpCode.NewObj)\n\t\t\t{\n\t\t\t\ttarget = default(TranslatedExpression); // no target\n\t\t\t}\n\t\t\telse if (localFunction != null)\n\t\t\t{\n\t\t\t\tvar ide = new IdentifierExpression(localFunction.Name);\n\t\t\t\tif (method.TypeArguments.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tide.TypeArguments.AddRange(method.TypeArguments.Select(expressionBuilder.ConvertType));\n\t\t\t\t}\n\t\t\t\tide.AddAnnotation(localFunction);\n\t\t\t\ttarget = ide.WithoutILInstruction()\n\t\t\t\t\t.WithRR(ToMethodGroup(method, localFunction));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar thisArg = callArguments.FirstOrDefault();\n\t\t\t\tif (thisArg is LdObjIfRef ldObjIfRef)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(constrainedTo != null);\n\t\t\t\t\tthisArg = ldObjIfRef.Target;\n\t\t\t\t}\n\t\t\t\ttarget = expressionBuilder.TranslateTarget(\n\t\t\t\t\tthisArg,\n\t\t\t\t\tnonVirtualInvocation: callOpCode == OpCode.Call || method.IsConstructor,\n\t\t\t\t\tmemberStatic: method.IsStatic,\n\t\t\t\t\tmemberDeclaringType: method.DeclaringType,\n\t\t\t\t\tconstrainedTo: constrainedTo);\n\t\t\t\tif (constrainedTo == null\n\t\t\t\t\t&& target.Expression is CastExpression cast\n\t\t\t\t\t&& target.ResolveResult is ConversionResolveResult conversion\n\t\t\t\t\t&& target.Type.IsKnownType(KnownTypeCode.Object)\n\t\t\t\t\t&& conversion.Conversion.IsBoxingConversion)\n\t\t\t\t{\n\t\t\t\t\t// boxing conversion on call target?\n\t\t\t\t\t// let's see if we can make that implicit:\n\t\t\t\t\ttarget = target.UnwrapChild(cast.Expression);\n\t\t\t\t\t// we'll need to make sure the boxing effect is preserved\n\t\t\t\t\texpectedTargetDetails.NeedsBoxingConversion = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tint firstParamIndex = (method.IsStatic || callOpCode == OpCode.NewObj) ? 0 : 1;\n\t\t\tDebug.Assert(firstParamIndex == 0 || argumentToParameterMap == null\n\t\t\t\t|| argumentToParameterMap[0] == -1);\n\n\t\t\tvar argumentList = BuildArgumentList(expectedTargetDetails, target.ResolveResult, method,\n\t\t\t\tfirstParamIndex, callArguments, argumentToParameterMap);\n\n\t\t\tif (localFunction != null)\n\t\t\t{\n\t\t\t\treturn new InvocationExpression(target, argumentList.GetArgumentExpressions())\n\t\t\t\t\t.WithRR(new CSharpInvocationResolveResult(target.ResolveResult, method,\n\t\t\t\t\t\targumentList.GetArgumentResolveResults(), isExpandedForm: argumentList.IsExpandedForm));\n\t\t\t}\n\n\t\t\tif (method is VarArgInstanceMethod)\n\t\t\t{\n\t\t\t\targumentList.FirstOptionalArgumentIndex = -1;\n\t\t\t\targumentList.AddNamesToPrimitiveValues = false;\n\t\t\t\targumentList.UseImplicitlyTypedOut = false;\n\t\t\t\tint regularParameterCount = ((VarArgInstanceMethod)method).RegularParameterCount;\n\t\t\t\tvar argListArg = new UndocumentedExpression();\n\t\t\t\targListArg.UndocumentedExpressionType = UndocumentedExpressionType.ArgList;\n\t\t\t\tint paramIndex = regularParameterCount;\n\t\t\t\tvar builder = expressionBuilder;\n\t\t\t\tDebug.Assert(argumentToParameterMap == null && argumentList.ArgumentNames == null);\n\t\t\t\targListArg.Arguments.AddRange(argumentList.Arguments.Skip(regularParameterCount).Select(arg => arg.ConvertTo(argumentList.ExpectedParameters[paramIndex++].Type, builder).Expression));\n\t\t\t\tvar argListRR = new ResolveResult(SpecialType.ArgList);\n\t\t\t\targumentList.Arguments = argumentList.Arguments.Take(regularParameterCount)\n\t\t\t\t\t.Concat(new[] { argListArg.WithoutILInstruction().WithRR(argListRR) }).ToArray();\n\t\t\t\tmethod = ((VarArgInstanceMethod)method).BaseMethod;\n\t\t\t\targumentList.ExpectedParameters = method.Parameters.ToArray();\n\t\t\t}\n\n\t\t\tif (settings.Ranges)\n\t\t\t{\n\t\t\t\tif (HandleRangeConstruction(out var result, callOpCode, method, target, argumentList))\n\t\t\t\t{\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (callOpCode == OpCode.NewObj)\n\t\t\t{\n\t\t\t\treturn HandleConstructorCall(expectedTargetDetails, target.ResolveResult, method, argumentList);\n\t\t\t}\n\n\t\t\tif (method.Name == \"Invoke\" && method.DeclaringType.Kind == TypeKind.Delegate && !IsNullConditional(target))\n\t\t\t{\n\t\t\t\treturn new InvocationExpression(target, argumentList.GetArgumentExpressions())\n\t\t\t\t\t.WithRR(new CSharpInvocationResolveResult(target.ResolveResult, method,\n\t\t\t\t\t\targumentList.GetArgumentResolveResults(), isExpandedForm: argumentList.IsExpandedForm, isDelegateInvocation: true));\n\t\t\t}\n\n\t\t\tif (settings.StringInterpolation && IsInterpolatedStringCreation(method, argumentList))\n\t\t\t{\n\t\t\t\tvar result = HandleStringInterpolation(method, argumentList);\n\t\t\t\tif (result.Expression != null)\n\t\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tint allowedParamCount = (method.ReturnType.IsKnownType(KnownTypeCode.Void) ? 1 : 0);\n\t\t\tif (method.IsAccessor && (method.AccessorOwner.SymbolKind == SymbolKind.Indexer || argumentList.ExpectedParameters.Length == allowedParamCount))\n\t\t\t{\n\t\t\t\targumentList.CheckNoNamedOrOptionalArguments();\n\t\t\t\treturn HandleAccessorCall(expectedTargetDetails, method, target, argumentList.Arguments.ToList(), argumentList.ArgumentNames);\n\t\t\t}\n\n\t\t\tif (IsDelegateEqualityComparison(method, argumentList.Arguments))\n\t\t\t{\n\t\t\t\targumentList.CheckNoNamedOrOptionalArguments();\n\t\t\t\treturn HandleDelegateEqualityComparison(method, argumentList.Arguments)\n\t\t\t\t\t.WithRR(new CSharpInvocationResolveResult(target.ResolveResult, method,\n\t\t\t\t\t\targumentList.GetArgumentResolveResults(), isExpandedForm: argumentList.IsExpandedForm));\n\t\t\t}\n\n\t\t\tif (method.IsOperator && method.Name == \"op_Implicit\" && argumentList.Length == 1)\n\t\t\t{\n\t\t\t\targumentList.CheckNoNamedOrOptionalArguments();\n\t\t\t\treturn HandleImplicitConversion(method, argumentList.Arguments[0]);\n\t\t\t}\n\n\t\t\tif (settings.InlineArrays\n\t\t\t\t&& method is { DeclaringType.FullName: \"<PrivateImplementationDetails>\", Name: \"InlineArrayAsSpan\" or \"InlineArrayAsReadOnlySpan\" }\n\t\t\t\t&& argumentList.Length == 2)\n\t\t\t{\n\t\t\t\targumentList.CheckNoNamedOrOptionalArguments();\n\t\t\t\tvar arrayType = method.TypeArguments[0];\n\t\t\t\tvar arrayLength = arrayType.GetInlineArrayLength();\n\t\t\t\tvar arrayElementType = arrayType.GetInlineArrayElementType();\n\t\t\t\tvar argument = argumentList.Arguments[0];\n\t\t\t\tvar spanLengthExpr = argumentList.Arguments[1];\n\t\t\t\tvar targetType = method.ReturnType;\n\t\t\t\tvar spanType = typeSystem.FindType(KnownTypeCode.SpanOfT);\n\t\t\t\tif (argument.Expression is DirectionExpression { FieldDirection: FieldDirection.In or FieldDirection.Ref, Expression: var lvalueExpr })\n\t\t\t\t{\n\t\t\t\t\t// `(TargetType)(in arg)` is invalid syntax.\n\t\t\t\t\t// Also, `f(in arg)` is invalid when there's an implicit conversion involved.\n\t\t\t\t\targument = argument.UnwrapChild(lvalueExpr);\n\t\t\t\t}\n\t\t\t\tif (spanLengthExpr.ResolveResult.ConstantValue is int spanLength && spanLength <= arrayLength)\n\t\t\t\t{\n\t\t\t\t\tif (spanLength < arrayLength)\n\t\t\t\t\t{\n\t\t\t\t\t\targument = new IndexerExpression(argument.Expression, new BinaryOperatorExpression {\n\t\t\t\t\t\t\tOperator = BinaryOperatorType.Range,\n\t\t\t\t\t\t\tRight = spanLengthExpr.Expression\n\t\t\t\t\t\t}).WithRR(new ResolveResult(new ParameterizedType(spanType, arrayElementType))).WithoutILInstruction();\n\t\t\t\t\t\tif (targetType.IsKnownType(KnownTypeCode.SpanOfT))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn argument;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn new CastExpression(expressionBuilder.ConvertType(targetType), argument.Expression)\n\t\t\t\t\t.WithRR(new ConversionResolveResult(targetType, argument.ResolveResult, Conversion.InlineArrayConversion));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (settings.LiftNullables && method.Name == \"GetValueOrDefault\"\n\t\t\t\t&& method.DeclaringType.IsKnownType(KnownTypeCode.NullableOfT)\n\t\t\t\t&& method.DeclaringType.TypeArguments[0].IsKnownType(KnownTypeCode.Boolean)\n\t\t\t\t&& argumentList.Length == 0)\n\t\t\t{\n\t\t\t\targumentList.CheckNoNamedOrOptionalArguments();\n\t\t\t\treturn new BinaryOperatorExpression(\n\t\t\t\t\ttarget.Expression,\n\t\t\t\t\tBinaryOperatorType.Equality,\n\t\t\t\t\tnew PrimitiveExpression(true))\n\t\t\t\t\t.WithRR(new CSharpInvocationResolveResult(target.ResolveResult, method,\n\t\t\t\t\t\targumentList.GetArgumentResolveResults(), isExpandedForm: argumentList.IsExpandedForm));\n\t\t\t}\n\n\t\t\tvar transform = GetRequiredTransformationsForCall(expectedTargetDetails, method, ref target,\n\t\t\t\tref argumentList, CallTransformation.All, out IParameterizedMember foundMethod);\n\n\t\t\t// Note: after this, 'method' and 'foundMethod' may differ,\n\t\t\t// but as far as allowed by IsAppropriateCallTarget().\n\n\t\t\t// Need to update list of parameter names, because foundMethod is different and thus might use different names.\n\t\t\tif (!method.Equals(foundMethod) && argumentList.ParameterNames.Length >= foundMethod.Parameters.Count)\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < foundMethod.Parameters.Count; i++)\n\t\t\t\t{\n\t\t\t\t\targumentList.ParameterNames[i] = foundMethod.Parameters[i].Name;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tExpression targetExpr;\n\t\t\tstring methodName = method.Name;\n\t\t\tAstNodeCollection<AstType> typeArgumentList;\n\t\t\tif ((transform & CallTransformation.NoNamedArgsForPrettiness) != 0)\n\t\t\t{\n\t\t\t\targumentList.AddNamesToPrimitiveValues = false;\n\t\t\t}\n\t\t\tif ((transform & CallTransformation.NoOptionalArgumentAllowed) != 0)\n\t\t\t{\n\t\t\t\targumentList.FirstOptionalArgumentIndex = -1;\n\t\t\t}\n\t\t\tif ((transform & CallTransformation.RequireTarget) != 0)\n\t\t\t{\n\t\t\t\ttargetExpr = new MemberReferenceExpression(target.Expression, methodName);\n\t\t\t\ttypeArgumentList = ((MemberReferenceExpression)targetExpr).TypeArguments;\n\n\t\t\t\t// HACK : convert this.Dispose() to ((IDisposable)this).Dispose(), if Dispose is an explicitly implemented interface method.\n\t\t\t\t// settings.AlwaysCastTargetsOfExplicitInterfaceImplementationCalls == true is used in Windows Forms' InitializeComponent methods.\n\t\t\t\tif (method.IsExplicitInterfaceImplementation && (target.Expression is ThisReferenceExpression || settings.AlwaysCastTargetsOfExplicitInterfaceImplementationCalls))\n\t\t\t\t{\n\t\t\t\t\tvar interfaceMember = method.ExplicitlyImplementedInterfaceMembers.First();\n\t\t\t\t\tvar castExpression = new CastExpression(expressionBuilder.ConvertType(interfaceMember.DeclaringType), target.Expression.Detach());\n\t\t\t\t\tmethodName = interfaceMember.Name;\n\t\t\t\t\ttargetExpr = new MemberReferenceExpression(castExpression, methodName);\n\t\t\t\t\ttypeArgumentList = ((MemberReferenceExpression)targetExpr).TypeArguments;\n\t\t\t\t}\n\t\t\t\tif (constrainedTo != null && targetExpr is MemberReferenceExpression { Target: CastExpression cast })\n\t\t\t\t{\n\t\t\t\t\tcast.AddChild(new Comment(\"cast due to .constrained prefix\", CommentType.MultiLine), Roles.Comment);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttargetExpr = new IdentifierExpression(methodName);\n\t\t\t\ttypeArgumentList = ((IdentifierExpression)targetExpr).TypeArguments;\n\t\t\t}\n\n\t\t\tif ((transform & CallTransformation.RequireTypeArguments) != 0 && (!settings.AnonymousTypes || !method.TypeArguments.Any(a => a.ContainsAnonymousType())))\n\t\t\t\ttypeArgumentList.AddRange(method.TypeArguments.Select(expressionBuilder.ConvertType));\n\t\t\treturn new InvocationExpression(targetExpr, argumentList.GetArgumentExpressions())\n\t\t\t\t.WithRR(new CSharpInvocationResolveResult(target.ResolveResult, foundMethod,\n\t\t\t\t\targumentList.GetArgumentResolveResultsDirect(), isExpandedForm: argumentList.IsExpandedForm));\n\t\t}\n\n\t\tprivate ExpressionWithResolveResult HandleStringInterpolation(IMethod method, ArgumentList argumentList)\n\t\t{\n\t\t\tif (!TryGetStringInterpolationTokens(argumentList, out string format, out var tokens))\n\t\t\t\treturn default;\n\n\t\t\tvar arguments = argumentList.Arguments;\n\t\t\tvar content = new List<InterpolatedStringContent>();\n\n\t\t\tbool unpackSingleElementArray = !argumentList.IsExpandedForm && argumentList.Length == 2\n\t\t\t\t&& argumentList.Arguments[1].Expression is ArrayCreateExpression ace\n\t\t\t\t&& ace.Initializer?.Elements.Count == 1;\n\n\t\t\tvoid UnpackSingleElementArray(ref TranslatedExpression argument)\n\t\t\t{\n\t\t\t\tif (!unpackSingleElementArray)\n\t\t\t\t\treturn;\n\t\t\t\tvar arrayCreation = (ArrayCreateExpression)argumentList.Arguments[1].Expression;\n\t\t\t\tvar arrayCreationRR = (ArrayCreateResolveResult)argumentList.Arguments[1].ResolveResult;\n\t\t\t\tvar element = arrayCreation.Initializer.Elements.First().Detach();\n\t\t\t\targument = new TranslatedExpression(element, arrayCreationRR.InitializerElements.First());\n\t\t\t}\n\n\t\t\tif (tokens.Count == 0)\n\t\t\t{\n\t\t\t\treturn default;\n\t\t\t}\n\n\t\t\tforeach (var (kind, index, alignment, text) in tokens)\n\t\t\t{\n\t\t\t\tTranslatedExpression argument;\n\t\t\t\tswitch (kind)\n\t\t\t\t{\n\t\t\t\t\tcase TokenKind.String:\n\t\t\t\t\t\tcontent.Add(new InterpolatedStringText(text));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TokenKind.Argument:\n\t\t\t\t\t\targument = arguments[index + 1];\n\t\t\t\t\t\tUnpackSingleElementArray(ref argument);\n\t\t\t\t\t\tcontent.Add(new Interpolation(argument));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TokenKind.ArgumentWithFormat:\n\t\t\t\t\t\targument = arguments[index + 1];\n\t\t\t\t\t\tUnpackSingleElementArray(ref argument);\n\t\t\t\t\t\tcontent.Add(new Interpolation(argument, suffix: text));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TokenKind.ArgumentWithAlignment:\n\t\t\t\t\t\targument = arguments[index + 1];\n\t\t\t\t\t\tUnpackSingleElementArray(ref argument);\n\t\t\t\t\t\tcontent.Add(new Interpolation(argument, alignment));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TokenKind.ArgumentWithAlignmentAndFormat:\n\t\t\t\t\t\targument = arguments[index + 1];\n\t\t\t\t\t\tUnpackSingleElementArray(ref argument);\n\t\t\t\t\t\tcontent.Add(new Interpolation(argument, alignment, text));\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar formattableStringType = expressionBuilder.compilation.FindType(KnownTypeCode.FormattableString);\n\t\t\tvar isrr = new InterpolatedStringResolveResult(expressionBuilder.compilation.FindType(KnownTypeCode.String),\n\t\t\t\tformat, argumentList.GetArgumentResolveResults(1).ToArray());\n\t\t\tvar expr = new InterpolatedStringExpression();\n\t\t\texpr.Content.AddRange(content);\n\t\t\tif (method.Name == \"Format\")\n\t\t\t\treturn expr.WithRR(isrr);\n\t\t\treturn new CastExpression(expressionBuilder.ConvertType(formattableStringType),\n\t\t\t\texpr.WithRR(isrr))\n\t\t\t\t.WithRR(new ConversionResolveResult(formattableStringType, isrr, Conversion.ImplicitInterpolatedStringConversion));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts a call to an Add method to a collection initializer expression.\n\t\t/// </summary>\n\t\tpublic ExpressionWithResolveResult BuildCollectionInitializerExpression(OpCode callOpCode, IMethod method,\n\t\t\tInitializedObjectResolveResult target, IReadOnlyList<ILInstruction> callArguments)\n\t\t{\n\t\t\t// (see ECMA-334, section 12.7.11.4):\n\t\t\t// The collection object to which a collection initializer is applied shall be of a type that implements\n\t\t\t// System.Collections.IEnumerable or a compile-time error occurs. For each specified element in order,\n\t\t\t// the collection initializer invokes an Add method on the target object with the expression list of the\n\t\t\t// element initializer as argument list, applying normal overload resolution for each invocation. Thus, the\n\t\t\t// collection object shall contain an applicable Add method for each element initializer.\n\n\t\t\t// The list of applicable methods includes all methods (as of C# 6.0 extension methods, too) named 'Add'\n\t\t\t// that can be invoked on the target object, with the following exceptions:\n\t\t\t// - Methods with ref or out parameters may not be used,\n\t\t\t// - methods that have type parameters, that cannot be inferred from the parameter list may not be used,\n\t\t\t// - vararg methods may not be used.\n\t\t\t// - named arguments are not supported.\n\t\t\t// However, note that params methods may be used.\n\n\t\t\t// At this point, we assume that 'method' fulfills all the conditions mentioned above. We just need to make\n\t\t\t// sure that the correct method is called by resolving any ambiguities by inserting casts, if necessary.\n\n\t\t\tExpectedTargetDetails expectedTargetDetails = new ExpectedTargetDetails { CallOpCode = callOpCode };\n\t\t\tvar unused = new IdentifierExpression(\"initializedObject\").WithRR(target).WithoutILInstruction();\n\t\t\tvar args = callArguments.ToList();\n\t\t\tif (method.IsExtensionMethod)\n\t\t\t\targs.Insert(0, new Nop());\n\n\t\t\tvar argumentList = BuildArgumentList(expectedTargetDetails, target, method,\n\t\t\t\tfirstParamIndex: 0, args, null);\n\t\t\targumentList.ArgumentNames = null;\n\t\t\targumentList.AddNamesToPrimitiveValues = false;\n\t\t\targumentList.UseImplicitlyTypedOut = false;\n\t\t\tvar transform = GetRequiredTransformationsForCall(expectedTargetDetails, method, ref unused,\n\t\t\t\tref argumentList, CallTransformation.None, out _);\n\t\t\tDebug.Assert((transform & ~(CallTransformation.NoOptionalArgumentAllowed | CallTransformation.NoNamedArgsForPrettiness)) == 0);\n\n\t\t\t// Calls with only one argument do not need an array initializer expression to wrap them.\n\t\t\t// Any special cases are handled by the caller (i.e., ExpressionBuilder.TranslateObjectAndCollectionInitializer)\n\t\t\t// Note: we intentionally ignore the firstOptionalArgumentIndex in this case.\n\t\t\tint skipCount;\n\t\t\tif (method.IsExtensionMethod)\n\t\t\t{\n\t\t\t\tif (argumentList.Arguments.Length == 2)\n\t\t\t\t\treturn argumentList.Arguments[1];\n\t\t\t\tskipCount = 1;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (argumentList.Arguments.Length == 1)\n\t\t\t\t\treturn argumentList.Arguments[0];\n\t\t\t\tskipCount = 0;\n\t\t\t}\n\n\t\t\tif ((transform & CallTransformation.NoOptionalArgumentAllowed) != 0)\n\t\t\t\targumentList.FirstOptionalArgumentIndex = -1;\n\n\t\t\treturn new ArrayInitializerExpression(argumentList.GetArgumentExpressions(skipCount))\n\t\t\t\t.WithRR(new CSharpInvocationResolveResult(target, method, argumentList.GetArgumentResolveResults(skipCount).ToArray(),\n\t\t\t\t\tisExtensionMethodInvocation: method.IsExtensionMethod, isExpandedForm: argumentList.IsExpandedForm));\n\t\t}\n\n\t\tpublic ExpressionWithResolveResult BuildDictionaryInitializerExpression(OpCode callOpCode, IMethod method,\n\t\t\tInitializedObjectResolveResult target, IReadOnlyList<ILInstruction> indices, ILInstruction value = null)\n\t\t{\n\t\t\tif (method is null)\n\t\t\t\tthrow new ArgumentNullException(nameof(method));\n\t\t\tExpectedTargetDetails expectedTargetDetails = new ExpectedTargetDetails { CallOpCode = callOpCode };\n\n\t\t\tvar callArguments = new List<ILInstruction>();\n\t\t\tcallArguments.Add(new LdNull());\n\t\t\tcallArguments.AddRange(indices);\n\t\t\tcallArguments.Add(value ?? new Nop());\n\n\t\t\tvar argumentList = BuildArgumentList(expectedTargetDetails, target, method, 1, callArguments, null);\n\t\t\tvar unused = new IdentifierExpression(\"initializedObject\").WithRR(target).WithoutILInstruction();\n\n\t\t\tvar assignment = HandleAccessorCall(expectedTargetDetails, method, unused,\n\t\t\t\targumentList.Arguments.ToList(), argumentList.ArgumentNames);\n\n\t\t\tif (((AssignmentExpression)assignment).Left is IndexerExpression indexer && !indexer.Target.IsNull)\n\t\t\t\tindexer.Target.Remove();\n\n\t\t\tif (value != null)\n\t\t\t\treturn assignment;\n\n\t\t\treturn new ExpressionWithResolveResult(((AssignmentExpression)assignment).Left.Detach());\n\t\t}\n\n\t\tprivate static bool IsInterpolatedStringCreation(IMethod method, ArgumentList argumentList)\n\t\t{\n\t\t\treturn method.IsStatic && (\n\t\t\t\t(method.DeclaringType.IsKnownType(KnownTypeCode.String) && method.Name == \"Format\") ||\n\t\t\t\t(method.Name == \"Create\" && method.DeclaringType.Name == \"FormattableStringFactory\" &&\n\t\t\t\t\tmethod.DeclaringType.Namespace == \"System.Runtime.CompilerServices\")\n\t\t\t)\n\t\t\t&& argumentList.ArgumentNames == null // Argument names are not allowed\n\t\t\t&& (\n\t\t\t\targumentList.IsExpandedForm // Must be expanded form\n\t\t\t\t|| !method.Parameters.Last().IsParams // -or- not a params overload\n\t\t\t\t|| (argumentList.Length == 2 && argumentList.Arguments[1].Expression is ArrayCreateExpression) // -or- an array literal\n\t\t\t);\n\t\t}\n\n\t\tprivate bool TryGetStringInterpolationTokens(ArgumentList argumentList, out string format, out List<(TokenKind Kind, int Index, int Alignment, string Format)> tokens)\n\t\t{\n\t\t\ttokens = null;\n\t\t\tformat = null;\n\t\t\tTranslatedExpression[] arguments = argumentList.Arguments;\n\t\t\tif (arguments.Length == 0 || argumentList.ArgumentNames != null || argumentList.ArgumentToParameterMap != null)\n\t\t\t\treturn false;\n\t\t\tif (!(arguments[(int)0].ResolveResult is ConstantResolveResult crr && crr.Type.IsKnownType((KnownTypeCode)KnownTypeCode.String)))\n\t\t\t\treturn false;\n\t\t\tif (!arguments.Skip(1).All(a => !a.Expression.DescendantsAndSelf.OfType<PrimitiveExpression>().Any(p => p.Value is string)))\n\t\t\t\treturn false;\n\t\t\ttokens = new List<(TokenKind Kind, int Index, int Alignment, string Format)>();\n\t\t\tint i = 0;\n\t\t\tformat = (string)crr.ConstantValue;\n\t\t\tforeach (var (kind, data) in TokenizeFormatString(format))\n\t\t\t{\n\t\t\t\tint index;\n\t\t\t\tstring[] arg;\n\t\t\t\tswitch (kind)\n\t\t\t\t{\n\t\t\t\t\tcase TokenKind.Error:\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcase TokenKind.String:\n\t\t\t\t\t\ttokens.Add((kind, -1, 0, data));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TokenKind.Argument:\n\t\t\t\t\t\tif (!int.TryParse(data, out index) || index != i)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\ti++;\n\t\t\t\t\t\ttokens.Add((kind, index, 0, null));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TokenKind.ArgumentWithFormat:\n\t\t\t\t\t\targ = data.Split(new[] { ':' }, 2);\n\t\t\t\t\t\tif (arg.Length != 2 || arg[1].Length == 0)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!int.TryParse(arg[0], out index) || index != i)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\ti++;\n\t\t\t\t\t\ttokens.Add((kind, index, 0, arg[1]));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TokenKind.ArgumentWithAlignment:\n\t\t\t\t\t\targ = data.Split(new[] { ',' }, 2);\n\t\t\t\t\t\tif (arg.Length != 2 || arg[1].Length == 0)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!int.TryParse(arg[0], out index) || index != i)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!int.TryParse(arg[1], out int alignment))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\ti++;\n\t\t\t\t\t\ttokens.Add((kind, index, alignment, null));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TokenKind.ArgumentWithAlignmentAndFormat:\n\t\t\t\t\t\targ = data.Split(new[] { ',', ':' }, 3);\n\t\t\t\t\t\tif (arg.Length != 3 || arg[1].Length == 0 || arg[2].Length == 0)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!int.TryParse(arg[0], out index) || index != i)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!int.TryParse(arg[1], out alignment))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\ti++;\n\t\t\t\t\t\ttokens.Add((kind, index, alignment, arg[2]));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn i == arguments.Length - 1;\n\t\t}\n\n\t\tprivate enum TokenKind\n\t\t{\n\t\t\tError,\n\t\t\tString,\n\t\t\tArgument,\n\t\t\tArgumentWithFormat,\n\t\t\tArgumentWithAlignment,\n\t\t\tArgumentWithAlignmentAndFormat,\n\t\t}\n\n\t\tprivate IEnumerable<(TokenKind, string)> TokenizeFormatString(string value)\n\t\t{\n\t\t\tint pos = -1;\n\n\t\t\tint Peek(int steps = 1)\n\t\t\t{\n\t\t\t\tif (pos + steps < value.Length)\n\t\t\t\t\treturn value[pos + steps];\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\tint Next()\n\t\t\t{\n\t\t\t\tint val = Peek();\n\t\t\t\tpos++;\n\t\t\t\treturn val;\n\t\t\t}\n\n\t\t\tint next;\n\t\t\tTokenKind kind = TokenKind.String;\n\t\t\tStringBuilder sb = new StringBuilder();\n\n\t\t\twhile ((next = Next()) > -1)\n\t\t\t{\n\t\t\t\tswitch ((char)next)\n\t\t\t\t{\n\t\t\t\t\tcase '{':\n\t\t\t\t\t\tif (Peek() == '{')\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tkind = TokenKind.String;\n\t\t\t\t\t\t\tsb.Append(\"{{\");\n\t\t\t\t\t\t\tNext();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (sb.Length > 0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tyield return (kind, sb.ToString());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tkind = TokenKind.Argument;\n\t\t\t\t\t\t\tsb.Clear();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '}':\n\t\t\t\t\t\tif (kind != TokenKind.String)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tyield return (kind, sb.ToString());\n\t\t\t\t\t\t\tsb.Clear();\n\t\t\t\t\t\t\tkind = TokenKind.String;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (Peek() == '}')\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsb.Append(\"}}\");\n\t\t\t\t\t\t\tNext();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tyield return (TokenKind.Error, null);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase ':':\n\t\t\t\t\t\tif (kind == TokenKind.Argument)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tkind = TokenKind.ArgumentWithFormat;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (kind == TokenKind.ArgumentWithAlignment)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tkind = TokenKind.ArgumentWithAlignmentAndFormat;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsb.Append(':');\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase ',':\n\t\t\t\t\t\tif (kind == TokenKind.Argument)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tkind = TokenKind.ArgumentWithAlignment;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsb.Append(',');\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tsb.Append((char)next);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (sb.Length > 0)\n\t\t\t{\n\t\t\t\tif (kind == TokenKind.String)\n\t\t\t\t\tyield return (kind, sb.ToString());\n\t\t\t\telse\n\t\t\t\t\tyield return (TokenKind.Error, null);\n\t\t\t}\n\t\t}\n\n\t\tprivate ArgumentList BuildArgumentList(ExpectedTargetDetails expectedTargetDetails, ResolveResult target, IMethod method,\n\t\t\tint firstParamIndex, IReadOnlyList<ILInstruction> callArguments, IReadOnlyList<int> argumentToParameterMap)\n\t\t{\n\t\t\tArgumentList list = new ArgumentList();\n\n\t\t\t// Translate arguments to the expected parameter types\n\t\t\tvar arguments = new List<TranslatedExpression>(method.Parameters.Count);\n\t\t\tstring[] argumentNames = null;\n\t\t\tDebug.Assert(callArguments.Count == firstParamIndex + method.Parameters.Count);\n\t\t\tvar expectedParameters = new List<IParameter>(method.Parameters.Count); // parameters, but in argument order\n\t\t\tbool isExpandedForm = false;\n\t\t\tBitSet isPrimitiveValue = new BitSet(method.Parameters.Count);\n\n\t\t\t// Optional arguments:\n\t\t\t// This value has the following values:\n\t\t\t// -2 - there are no optional arguments\n\t\t\t// -1 - optional arguments are forbidden\n\t\t\t// >= 0 - the index of the first argument that can be removed, because it is optional\n\t\t\t// and is the default value of the parameter. \n\t\t\tint firstOptionalArgumentIndex = expressionBuilder.settings.OptionalArguments ? -2 : -1;\n\t\t\tfor (int i = firstParamIndex; i < callArguments.Count; i++)\n\t\t\t{\n\t\t\t\tIParameter parameter;\n\t\t\t\tif (argumentToParameterMap != null)\n\t\t\t\t{\n\t\t\t\t\tif (argumentNames == null && argumentToParameterMap[i] != i - firstParamIndex)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Starting at the first argument that is out-of-place,\n\t\t\t\t\t\t// assign names to that argument and all following arguments:\n\t\t\t\t\t\targumentNames = new string[method.Parameters.Count];\n\t\t\t\t\t}\n\t\t\t\t\tparameter = method.Parameters[argumentToParameterMap[i]];\n\t\t\t\t\tif (argumentNames != null && AssignVariableNames.IsValidName(parameter.Name))\n\t\t\t\t\t{\n\t\t\t\t\t\targumentNames[arguments.Count] = parameter.Name;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tparameter = method.Parameters[i - firstParamIndex];\n\t\t\t\t}\n\t\t\t\tvar arg = expressionBuilder.Translate(callArguments[i], parameter.Type);\n\t\t\t\tif (IsPrimitiveValueThatShouldBeNamedArgument(arg, method, parameter))\n\t\t\t\t{\n\t\t\t\t\tisPrimitiveValue.Set(arguments.Count);\n\t\t\t\t}\n\t\t\t\tif (IsOptionalArgument(parameter, arg))\n\t\t\t\t{\n\t\t\t\t\tif (firstOptionalArgumentIndex == -2)\n\t\t\t\t\t\tfirstOptionalArgumentIndex = i - firstParamIndex;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (firstOptionalArgumentIndex != -1)\n\t\t\t\t\t\tfirstOptionalArgumentIndex = -2;\n\t\t\t\t}\n\t\t\t\tif (expressionBuilder.settings.ExpandParamsArguments && parameter.IsParams && i + 1 == callArguments.Count && argumentToParameterMap == null)\n\t\t\t\t{\n\t\t\t\t\t// Parameter is marked params\n\t\t\t\t\t// If the argument is an array creation, inline all elements into the call and add missing default values.\n\t\t\t\t\t// Otherwise handle it normally.\n\t\t\t\t\tif (TransformParamsArgument(expectedTargetDetails, target, method, parameter,\n\t\t\t\t\t\targ, ref expectedParameters, ref arguments))\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(argumentNames == null);\n\t\t\t\t\t\tfirstOptionalArgumentIndex = -1;\n\t\t\t\t\t\tisExpandedForm = true;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tIType parameterType;\n\t\t\t\tif (parameter.Type.Kind == TypeKind.Dynamic)\n\t\t\t\t{\n\t\t\t\t\tparameterType = expressionBuilder.compilation.FindType(KnownTypeCode.Object);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tparameterType = parameter.Type;\n\t\t\t\t}\n\n\t\t\t\targ = arg.ConvertTo(parameterType, expressionBuilder, allowImplicitConversion: arg.Type.Kind != TypeKind.Dynamic);\n\n\t\t\t\tif (parameter.ReferenceKind != ReferenceKind.None)\n\t\t\t\t{\n\t\t\t\t\targ = ExpressionBuilder.ChangeDirectionExpressionTo(arg, parameter.ReferenceKind, callArguments[i] is AddressOf);\n\t\t\t\t}\n\n\t\t\t\targuments.Add(arg);\n\t\t\t\texpectedParameters.Add(parameter);\n\t\t\t}\n\n\t\t\tlist.ExpectedParameters = expectedParameters.ToArray();\n\t\t\tlist.Arguments = arguments.ToArray();\n\t\t\tlist.ParameterNames = expectedParameters.SelectArray(p => p.Name);\n\t\t\tlist.ArgumentNames = argumentNames;\n\t\t\tlist.ArgumentToParameterMap = argumentToParameterMap;\n\t\t\tlist.IsExpandedForm = isExpandedForm;\n\t\t\tlist.IsPrimitiveValue = isPrimitiveValue;\n\t\t\tlist.FirstOptionalArgumentIndex = firstOptionalArgumentIndex;\n\t\t\tlist.UseImplicitlyTypedOut = true;\n\t\t\tlist.AddNamesToPrimitiveValues = expressionBuilder.settings.NamedArguments && expressionBuilder.settings.NonTrailingNamedArguments;\n\t\t\treturn list;\n\t\t}\n\n\t\tprivate bool IsPrimitiveValueThatShouldBeNamedArgument(TranslatedExpression arg, IMethod method, IParameter p)\n\t\t{\n\t\t\tif (!arg.ResolveResult.IsCompileTimeConstant || method.DeclaringType.IsKnownType(KnownTypeCode.NullableOfT))\n\t\t\t\treturn false;\n\t\t\treturn p.Type.IsKnownType(KnownTypeCode.Boolean);\n\t\t}\n\n\t\tprivate bool TransformParamsArgument(ExpectedTargetDetails expectedTargetDetails, ResolveResult targetResolveResult,\n\t\t\tIMethod method, IParameter parameter, TranslatedExpression paramsArgument, ref List<IParameter> expectedParameters,\n\t\t\tref List<TranslatedExpression> arguments)\n\t\t{\n\t\t\tvar expressionBuilder = this.expressionBuilder;\n\t\t\tif (ExtractArguments(out IType elementType, out var expandedParameters, out var expandedArguments))\n\t\t\t{\n\t\t\t\texpandedParameters.InsertRange(0, expectedParameters);\n\t\t\t\texpandedArguments.InsertRange(0, arguments);\n\t\t\t\tif (IsUnambiguousCall(expectedTargetDetails, method, targetResolveResult, Empty<IType>.Array,\n\t\t\t\t\texpandedArguments.SelectArray(a => a.ResolveResult), argumentNames: null,\n\t\t\t\t\tfirstOptionalArgumentIndex: -1, out _,\n\t\t\t\t\tout var bestCandidateIsExpandedForm) == OverloadResolutionErrors.None && bestCandidateIsExpandedForm)\n\t\t\t\t{\n\t\t\t\t\texpectedParameters = expandedParameters;\n\t\t\t\t\targuments = expandedArguments.SelectList(a => new TranslatedExpression(a.Expression.Detach()));\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\n\t\t\tbool ExtractArguments(out IType elementType, out List<IParameter> parameters, out List<TranslatedExpression> arguments)\n\t\t\t{\n\t\t\t\telementType = null;\n\t\t\t\tparameters = null;\n\t\t\t\targuments = null;\n\t\t\t\tswitch (paramsArgument.ResolveResult)\n\t\t\t\t{\n\t\t\t\t\tcase CSharpInvocationResolveResult { Member: IMethod method, Arguments: var args }:\n\t\t\t\t\t\t// match System.Array.Empty<T>()\n\t\t\t\t\t\tif (args is [] && method is { IsStatic: true, FullName: \"System.Array.Empty\", TypeArguments: [var type] })\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\telementType = type;\n\t\t\t\t\t\t\targuments = new();\n\t\t\t\t\t\t\tparameters = new();\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// match System.ReadOnlySpan<T>..ctor(ref readonly T)\n\t\t\t\t\t\tif (paramsArgument.Expression is ObjectCreateExpression oce\n\t\t\t\t\t\t\t&& method is {\n\t\t\t\t\t\t\t\tIsConstructor: true,\n\t\t\t\t\t\t\t\tParameters: [{ ReferenceKind: ReferenceKind.RefReadOnly, Type: ByReferenceType { ElementType: var paramType } }],\n\t\t\t\t\t\t\t\tDeclaringType: { TypeArguments: [var type2] } declaringType\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t&& declaringType.IsKnownType(KnownTypeCode.ReadOnlySpanOfT)\n\t\t\t\t\t\t\t&& paramType.Equals(type2))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\telementType = type2;\n\t\t\t\t\t\t\targuments = new() { new TranslatedExpression(oce.Arguments.Single()) };\n\t\t\t\t\t\t\tparameters = new() { new DefaultParameter(type2, string.Empty) };\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcase ArrayCreateResolveResult { Type: ArrayType { ElementType: var type3 }, SizeArguments: [{ ConstantValue: int arrayLength }] }:\n\t\t\t\t\t\telementType = type3;\n\t\t\t\t\t\targuments = new(((ArrayCreateExpression)paramsArgument.Expression).Initializer.Elements.Select(e => new TranslatedExpression(e)));\n\t\t\t\t\t\tparameters = new List<IParameter>(arrayLength);\n\t\t\t\t\t\tfor (int i = 0; i < arrayLength; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tparameters.Add(new DefaultParameter(type3, string.Empty));\n\t\t\t\t\t\t\tif (arguments.Count <= i)\n\t\t\t\t\t\t\t\targuments.Add(new TranslatedExpression(expressionBuilder.GetDefaultValueExpression(type3).WithoutILInstruction()));\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool IsOptionalArgument(IParameter parameter, TranslatedExpression arg)\n\t\t{\n\t\t\tif (!parameter.IsOptional)\n\t\t\t\treturn false;\n\n\t\t\tif (!arg.ResolveResult.IsCompileTimeConstant && arg.ResolveResult is not ConversionResolveResult { Conversion.IsNullLiteralConversion: true })\n\t\t\t\treturn false;\n\t\t\tif (parameter.GetAttributes().Any(a => a.AttributeType.IsKnownType(KnownAttribute.CallerMemberName)\n\t\t\t\t|| a.AttributeType.IsKnownType(KnownAttribute.CallerFilePath)\n\t\t\t\t|| a.AttributeType.IsKnownType(KnownAttribute.CallerLineNumber)))\n\t\t\t\treturn false;\n\t\t\treturn object.Equals(parameter.GetConstantValue(), arg.ResolveResult.ConstantValue);\n\t\t}\n\n\t\t[Flags]\n\t\tenum CallTransformation\n\t\t{\n\t\t\tNone = 0,\n\t\t\tRequireTarget = 1,\n\t\t\tRequireTypeArguments = 2,\n\t\t\tNoOptionalArgumentAllowed = 4,\n\t\t\t/// <summary>\n\t\t\t/// Add calls to AsRefReadOnly for in parameters that did not have an explicit DirectionExpression yet.\n\t\t\t/// </summary>\n\t\t\tEnforceExplicitIn = 8,\n\t\t\tNoNamedArgsForPrettiness = 0x10,\n\t\t\tAll = 0x1f,\n\t\t}\n\n\t\tprivate CallTransformation GetRequiredTransformationsForCall(ExpectedTargetDetails expectedTargetDetails, IMethod method,\n\t\t\tref TranslatedExpression target, ref ArgumentList argumentList, CallTransformation allowedTransforms, out IParameterizedMember foundMethod)\n\t\t{\n\t\t\tCallTransformation transform = CallTransformation.None;\n\n\t\t\t// initialize requireTarget flag\n\t\t\tbool requireTarget;\n\t\t\tResolveResult targetResolveResult;\n\t\t\tif ((allowedTransforms & CallTransformation.RequireTarget) != 0)\n\t\t\t{\n\t\t\t\tif (settings.AlwaysQualifyMemberReferences || expressionBuilder.HidesVariableWithName(method.Name))\n\t\t\t\t{\n\t\t\t\t\trequireTarget = true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (method.IsLocalFunction)\n\t\t\t\t\t\trequireTarget = false;\n\t\t\t\t\telse if (method.IsStatic)\n\t\t\t\t\t\trequireTarget = !expressionBuilder.IsCurrentOrContainingType(method.DeclaringTypeDefinition) || method.Name == \".cctor\";\n\t\t\t\t\telse if (method.Name == \".ctor\")\n\t\t\t\t\t\trequireTarget = true; // always use target for base/this-ctor-call, the constructor initializer pattern depends on this\n\t\t\t\t\telse if (target.Expression is BaseReferenceExpression)\n\t\t\t\t\t\trequireTarget = (expectedTargetDetails.CallOpCode != OpCode.CallVirt && method.IsVirtual);\n\t\t\t\t\telse\n\t\t\t\t\t\trequireTarget = target.Expression is not ThisReferenceExpression;\n\t\t\t\t}\n\t\t\t\ttargetResolveResult = requireTarget ? target.ResolveResult : null;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// HACK: this is a special case for collection initializer calls, they do not allow a target to be\n\t\t\t\t// emitted, but we still need it for overload resolution.\n\t\t\t\trequireTarget = true;\n\t\t\t\ttargetResolveResult = target.ResolveResult;\n\t\t\t}\n\n\t\t\t// initialize requireTypeArguments flag\n\t\t\tbool requireTypeArguments;\n\t\t\tIType[] typeArguments;\n\t\t\tbool appliedRequireTypeArgumentsShortcut = false;\n\t\t\tif (method.TypeParameters.Count > 0 && (allowedTransforms & CallTransformation.RequireTypeArguments) != 0\n\t\t\t\t&& !IsPossibleExtensionMethodCallOnNull(method, argumentList.Arguments))\n\t\t\t{\n\t\t\t\t// The ambiguity resolution below only adds type arguments as last resort measure, however there are\n\t\t\t\t// methods, such as Enumerable.OfType<TResult>(IEnumerable input) that always require type arguments,\n\t\t\t\t// as those cannot be inferred from the parameters, which leads to bloated expressions full of extra casts\n\t\t\t\t// that are no longer required once we add the type arguments.\n\t\t\t\t// We lend overload resolution a hand by detecting such cases beforehand and requiring type arguments,\n\t\t\t\t// if necessary.\n\t\t\t\tif (!CanInferTypeArgumentsFromArguments(method, argumentList, expressionBuilder.typeInference))\n\t\t\t\t{\n\t\t\t\t\trequireTypeArguments = true;\n\t\t\t\t\ttypeArguments = method.TypeArguments.ToArray();\n\t\t\t\t\tappliedRequireTypeArgumentsShortcut = true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\trequireTypeArguments = false;\n\t\t\t\t\ttypeArguments = Empty<IType>.Array;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\trequireTypeArguments = false;\n\t\t\t\ttypeArguments = Empty<IType>.Array;\n\t\t\t}\n\n\t\t\tbool targetCasted = false;\n\t\t\tbool argumentsCasted = false;\n\t\t\tbool originalRequireTarget = requireTarget;\n\t\t\tbool skipTargetCast = method.Accessibility <= Accessibility.Protected && expressionBuilder.IsBaseTypeOfCurrentType(method.DeclaringTypeDefinition);\n\t\t\tOverloadResolutionErrors errors;\n\t\t\twhile ((errors = IsUnambiguousCall(expectedTargetDetails, method, targetResolveResult, typeArguments,\n\t\t\t\targumentList.GetArgumentResolveResults().ToArray(), argumentList.GetArgumentNames(), argumentList.FirstOptionalArgumentIndex, out foundMethod,\n\t\t\t\tout var bestCandidateIsExpandedForm)) != OverloadResolutionErrors.None || bestCandidateIsExpandedForm != argumentList.IsExpandedForm)\n\t\t\t{\n\t\t\t\tswitch (errors)\n\t\t\t\t{\n\t\t\t\t\tcase OverloadResolutionErrors.OutVarTypeMismatch:\n\t\t\t\t\t\tDebug.Assert(argumentList.UseImplicitlyTypedOut);\n\t\t\t\t\t\targumentList.UseImplicitlyTypedOut = false;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tcase OverloadResolutionErrors.TypeInferenceFailed:\n\t\t\t\t\t\tif ((allowedTransforms & CallTransformation.RequireTypeArguments) != 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tgoto case OverloadResolutionErrors.WrongNumberOfTypeArguments;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tgoto default;\n\t\t\t\t\tcase OverloadResolutionErrors.WrongNumberOfTypeArguments:\n\t\t\t\t\t\tDebug.Assert((allowedTransforms & CallTransformation.RequireTypeArguments) != 0);\n\t\t\t\t\t\tif (requireTypeArguments)\n\t\t\t\t\t\t\tgoto default;\n\t\t\t\t\t\trequireTypeArguments = true;\n\t\t\t\t\t\ttypeArguments = method.TypeArguments.ToArray();\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tcase OverloadResolutionErrors.MissingArgumentForRequiredParameter:\n\t\t\t\t\t\tif (argumentList.FirstOptionalArgumentIndex == -1)\n\t\t\t\t\t\t\tgoto default;\n\t\t\t\t\t\targumentList.FirstOptionalArgumentIndex = -1;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// TODO : implement some more intelligent algorithm that decides which of these fixes (cast args, add target, cast target, add type args)\n\t\t\t\t\t\t// is best in this case. Additionally we should not cast all arguments at once, but step-by-step try to add only a minimal number of casts.\n\t\t\t\t\t\tif (argumentList.AddNamesToPrimitiveValues)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\targumentList.AddNamesToPrimitiveValues = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (argumentList.FirstOptionalArgumentIndex >= 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\targumentList.FirstOptionalArgumentIndex = -1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (!argumentsCasted)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// If we added type arguments beforehand, but that didn't make the code any better,\n\t\t\t\t\t\t\t// undo that decision and add casts first.\n\t\t\t\t\t\t\tif (appliedRequireTypeArgumentsShortcut)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\trequireTypeArguments = false;\n\t\t\t\t\t\t\t\ttypeArguments = Empty<IType>.Array;\n\t\t\t\t\t\t\t\tappliedRequireTypeArgumentsShortcut = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\targumentsCasted = true;\n\t\t\t\t\t\t\targumentList.UseImplicitlyTypedOut = false;\n\t\t\t\t\t\t\tCastArguments(argumentList.Arguments, argumentList.ExpectedParameters);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if ((allowedTransforms & CallTransformation.RequireTarget) != 0 && !requireTarget)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\trequireTarget = true;\n\t\t\t\t\t\t\ttargetResolveResult = target.ResolveResult;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if ((allowedTransforms & CallTransformation.RequireTarget) != 0 && !targetCasted)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (skipTargetCast && requireTarget != originalRequireTarget)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\trequireTarget = originalRequireTarget;\n\t\t\t\t\t\t\t\tif (!originalRequireTarget)\n\t\t\t\t\t\t\t\t\ttargetResolveResult = null;\n\t\t\t\t\t\t\t\tallowedTransforms &= ~CallTransformation.RequireTarget;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttargetCasted = true;\n\t\t\t\t\t\t\t\ttarget = target.ConvertTo(method.DeclaringType, expressionBuilder);\n\t\t\t\t\t\t\t\ttargetResolveResult = target.ResolveResult;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if ((allowedTransforms & CallTransformation.RequireTypeArguments) != 0 && !requireTypeArguments)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\trequireTypeArguments = true;\n\t\t\t\t\t\t\ttypeArguments = method.TypeArguments.ToArray();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if ((allowedTransforms & CallTransformation.EnforceExplicitIn) != 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tEnforceExplicitIn(argumentList.Arguments, argumentList.ExpectedParameters);\n\t\t\t\t\t\t\tallowedTransforms &= ~CallTransformation.EnforceExplicitIn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// We've given up.\n\t\t\t\tfoundMethod = method;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ((allowedTransforms & CallTransformation.RequireTarget) != 0 && requireTarget)\n\t\t\t\ttransform |= CallTransformation.RequireTarget;\n\t\t\tif ((allowedTransforms & CallTransformation.RequireTypeArguments) != 0 && requireTypeArguments)\n\t\t\t\ttransform |= CallTransformation.RequireTypeArguments;\n\t\t\tif (argumentList.FirstOptionalArgumentIndex < 0)\n\t\t\t\ttransform |= CallTransformation.NoOptionalArgumentAllowed;\n\t\t\tif (!argumentList.AddNamesToPrimitiveValues)\n\t\t\t\ttransform |= CallTransformation.NoNamedArgsForPrettiness;\n\t\t\treturn transform;\n\t\t}\n\n\t\tprivate void EnforceExplicitIn(TranslatedExpression[] arguments, IParameter[] expectedParameters)\n\t\t{\n\t\t\tfor (int i = 0; i < arguments.Length; i++)\n\t\t\t{\n\t\t\t\tif (expectedParameters[i].ReferenceKind != ReferenceKind.In)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (arguments[i].Expression is DirectionExpression)\n\t\t\t\t\tcontinue;\n\n\t\t\t\targuments[i] = WrapInAsRefReadOnly(arguments[i]);\n\t\t\t\texpressionBuilder.statementBuilder.EmitAsRefReadOnly = true;\n\t\t\t}\n\t\t}\n\n\t\tprivate TranslatedExpression WrapInAsRefReadOnly(TranslatedExpression arg)\n\t\t{\n\t\t\treturn new DirectionExpression(\n\t\t\t\tFieldDirection.In,\n\t\t\t\tnew InvocationExpression {\n\t\t\t\t\tTarget = new IdentifierExpression(\"ILSpyHelper_AsRefReadOnly\"),\n\t\t\t\t\tArguments = { arg.Expression }\n\t\t\t\t}\n\t\t\t).WithRR(new ByReferenceResolveResult(arg.Type, ReferenceKind.In))\n\t\t\t.WithoutILInstruction();\n\t\t}\n\n\t\tprivate bool IsPossibleExtensionMethodCallOnNull(IMethod method, IList<TranslatedExpression> arguments)\n\t\t{\n\t\t\treturn method.IsExtensionMethod && arguments.Count > 0 && arguments[0].Expression is NullReferenceExpression;\n\t\t}\n\n\t\tstatic bool CanInferTypeArgumentsFromArguments(IMethod method, ArgumentList argumentList, TypeInference typeInference)\n\t\t{\n\t\t\tif (method.TypeParameters.Count == 0)\n\t\t\t\treturn true;\n\t\t\t// always use unspecialized member, otherwise type inference fails\n\t\t\tmethod = (IMethod)method.MemberDefinition;\n\t\t\tIReadOnlyList<IType> paramTypesInArgumentOrder;\n\t\t\tif (argumentList.ArgumentToParameterMap == null)\n\t\t\t\tparamTypesInArgumentOrder = method.Parameters.SelectReadOnlyArray(p => p.Type);\n\t\t\telse\n\t\t\t\tparamTypesInArgumentOrder = argumentList.ArgumentToParameterMap\n\t\t\t\t\t.SelectReadOnlyArray(\n\t\t\t\t\t\tindex => index >= 0 ? method.Parameters[index].Type : SpecialType.UnknownType\n\t\t\t\t\t);\n\t\t\ttypeInference.InferTypeArguments(method.TypeParameters,\n\t\t\t\targumentList.Arguments.SelectReadOnlyArray(a => a.ResolveResult), paramTypesInArgumentOrder,\n\t\t\t\tout bool success);\n\t\t\treturn success;\n\t\t}\n\n\t\tprivate void CastArguments(IList<TranslatedExpression> arguments, IList<IParameter> expectedParameters)\n\t\t{\n\t\t\tfor (int i = 0; i < arguments.Count; i++)\n\t\t\t{\n\t\t\t\tif (settings.AnonymousTypes && expectedParameters[i].Type.ContainsAnonymousType())\n\t\t\t\t{\n\t\t\t\t\tif (arguments[i].Expression is LambdaExpression lambda)\n\t\t\t\t\t{\n\t\t\t\t\t\tModifyReturnTypeOfLambda(lambda);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tIParameter parameter = expectedParameters[i];\n\t\t\t\t\tIType parameterType;\n\t\t\t\t\tif (parameter.Type.Kind == TypeKind.Dynamic)\n\t\t\t\t\t{\n\t\t\t\t\t\tparameterType = expressionBuilder.compilation.FindType(KnownTypeCode.Object);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tparameterType = parameter.Type;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (parameter.ReferenceKind == ReferenceKind.In && parameterType is ByReferenceType brt && arguments[i].Type is not ByReferenceType)\n\t\t\t\t\t{\n\t\t\t\t\t\tparameterType = brt.ElementType;\n\t\t\t\t\t}\n\n\t\t\t\t\targuments[i] = arguments[i].ConvertTo(parameterType, expressionBuilder, allowImplicitConversion: false);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic bool IsNullConditional(Expression expr)\n\t\t{\n\t\t\treturn expr is UnaryOperatorExpression uoe && uoe.Operator == UnaryOperatorType.NullConditional;\n\t\t}\n\n\t\tprivate void ModifyReturnTypeOfLambda(LambdaExpression lambda)\n\t\t{\n\t\t\tvar resolveResult = (DecompiledLambdaResolveResult)lambda.GetResolveResult();\n\t\t\tif (lambda.Body is Expression exprBody)\n\t\t\t\tlambda.Body = new TranslatedExpression(exprBody.Detach()).ConvertTo(resolveResult.ReturnType, expressionBuilder);\n\t\t\telse\n\t\t\t\tModifyReturnStatementInsideLambda(resolveResult.ReturnType, lambda);\n\t\t\tresolveResult.InferredReturnType = resolveResult.ReturnType;\n\t\t}\n\n\t\tprivate void ModifyReturnStatementInsideLambda(IType returnType, AstNode parent)\n\t\t{\n\t\t\tforeach (var child in parent.Children)\n\t\t\t{\n\t\t\t\tif (child is LambdaExpression || child is AnonymousMethodExpression)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (child is ReturnStatement ret)\n\t\t\t\t{\n\t\t\t\t\tret.Expression = new TranslatedExpression(ret.Expression.Detach()).ConvertTo(returnType, expressionBuilder);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tModifyReturnStatementInsideLambda(returnType, child);\n\t\t\t}\n\t\t}\n\n\t\tprivate bool IsDelegateEqualityComparison(IMethod method, IList<TranslatedExpression> arguments)\n\t\t{\n\t\t\t// Comparison on a delegate type is a C# builtin operator\n\t\t\t// that compiles down to a Delegate.op_Equality call.\n\t\t\t// We handle this as a special case to avoid inserting a cast to System.Delegate.\n\t\t\treturn method.IsOperator\n\t\t\t\t&& method.DeclaringType.IsKnownType(KnownTypeCode.Delegate)\n\t\t\t\t&& (method.Name == \"op_Equality\" || method.Name == \"op_Inequality\")\n\t\t\t\t&& arguments.Count == 2\n\t\t\t\t&& arguments[0].Type.Kind == TypeKind.Delegate\n\t\t\t\t&& arguments[1].Type.Equals(arguments[0].Type);\n\t\t}\n\n\t\tprivate Expression HandleDelegateEqualityComparison(IMethod method, IList<TranslatedExpression> arguments)\n\t\t{\n\t\t\treturn new BinaryOperatorExpression(\n\t\t\t\targuments[0],\n\t\t\t\tmethod.Name == \"op_Equality\" ? BinaryOperatorType.Equality : BinaryOperatorType.InEquality,\n\t\t\t\targuments[1]\n\t\t\t);\n\t\t}\n\n\t\tprivate ExpressionWithResolveResult HandleImplicitConversion(IMethod method, TranslatedExpression argument)\n\t\t{\n\t\t\tvar conversions = CSharpConversions.Get(expressionBuilder.compilation);\n\t\t\tIType targetType = method.ReturnType;\n\t\t\tvar conv = conversions.ImplicitConversion(argument.Type, targetType);\n\t\t\tif (!(conv.IsUserDefined && conv.IsValid && conv.Method.Equals(method, NormalizeTypeVisitor.TypeErasure)))\n\t\t\t{\n\t\t\t\t// implicit conversion to targetType isn't directly possible, so first insert a cast to the argument type\n\t\t\t\targument = argument.ConvertTo(method.Parameters[0].Type, expressionBuilder);\n\t\t\t\tconv = conversions.ImplicitConversion(argument.Type, targetType);\n\t\t\t}\n\t\t\tif (argument.Expression is DirectionExpression { FieldDirection: FieldDirection.In, Expression: var lvalueExpr })\n\t\t\t{\n\t\t\t\t// `(TargetType)(in arg)` is invalid syntax.\n\t\t\t\t// Also, `f(in arg)` is invalid when there's an implicit conversion involved.\n\t\t\t\targument = argument.UnwrapChild(lvalueExpr);\n\t\t\t}\n\t\t\treturn new CastExpression(expressionBuilder.ConvertType(targetType), argument.Expression)\n\t\t\t\t.WithRR(new ConversionResolveResult(targetType, argument.ResolveResult, conv));\n\t\t}\n\n\t\tOverloadResolutionErrors IsUnambiguousCall(ExpectedTargetDetails expectedTargetDetails, IMethod method,\n\t\t\tResolveResult target, IType[] typeArguments, ResolveResult[] arguments,\n\t\t\tstring[] argumentNames, int firstOptionalArgumentIndex,\n\t\t\tout IParameterizedMember foundMember, out bool bestCandidateIsExpandedForm)\n\t\t{\n\t\t\tfoundMember = null;\n\t\t\tbestCandidateIsExpandedForm = false;\n\t\t\tvar currentTypeDefinition = resolver.CurrentTypeDefinition;\n\t\t\tvar lookup = new MemberLookup(currentTypeDefinition, currentTypeDefinition.ParentModule);\n\n\t\t\tLog.WriteLine(\"IsUnambiguousCall: Performing overload resolution for \" + method);\n\t\t\tLog.WriteCollection(\"  Arguments: \", arguments);\n\n\t\t\targumentNames = firstOptionalArgumentIndex < 0 || argumentNames == null\n\t\t\t\t? argumentNames\n\t\t\t\t: argumentNames.Take(firstOptionalArgumentIndex).ToArray();\n\n\t\t\tvar or = new OverloadResolution(resolver.Compilation,\n\t\t\t\targuments, argumentNames, typeArguments,\n\t\t\t\tconversions: expressionBuilder.resolver.conversions);\n\t\t\tif (expectedTargetDetails.CallOpCode == OpCode.NewObj)\n\t\t\t{\n\t\t\t\tforeach (IMethod ctor in method.DeclaringType.GetConstructors())\n\t\t\t\t{\n\t\t\t\t\tbool allowProtectedAccess =\n\t\t\t\t\t\tresolver.CurrentTypeDefinition == method.DeclaringTypeDefinition;\n\t\t\t\t\tif (lookup.IsAccessible(ctor, allowProtectedAccess))\n\t\t\t\t\t{\n\t\t\t\t\t\tLog.Indent();\n\t\t\t\t\t\tOverloadResolutionErrors errors = or.AddCandidate(ctor);\n\t\t\t\t\t\tLog.Unindent();\n\t\t\t\t\t\tor.LogCandidateAddingResult(\"  Candidate\", ctor, errors);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (method.IsOperator)\n\t\t\t{\n\t\t\t\tIEnumerable<IParameterizedMember> operatorCandidates;\n\t\t\t\tif (arguments.Length == 1)\n\t\t\t\t{\n\t\t\t\t\tIType argType = NullableType.GetUnderlyingType(arguments[0].Type);\n\t\t\t\t\toperatorCandidates = resolver.GetUserDefinedOperatorCandidates(argType, method.Name);\n\t\t\t\t\tif (method.Name == \"op_Explicit\")\n\t\t\t\t\t{\n\t\t\t\t\t\t// For casts, also consider candidates from the target type we are casting to.\n\t\t\t\t\t\tvar hashSet = new HashSet<IParameterizedMember>(operatorCandidates);\n\t\t\t\t\t\tIType targetType = NullableType.GetUnderlyingType(method.ReturnType);\n\t\t\t\t\t\thashSet.UnionWith(\n\t\t\t\t\t\t\tresolver.GetUserDefinedOperatorCandidates(targetType, method.Name)\n\t\t\t\t\t\t);\n\t\t\t\t\t\toperatorCandidates = hashSet;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (arguments.Length == 2)\n\t\t\t\t{\n\t\t\t\t\tIType lhsType = NullableType.GetUnderlyingType(arguments[0].Type);\n\t\t\t\t\tIType rhsType = NullableType.GetUnderlyingType(arguments[1].Type);\n\t\t\t\t\tvar hashSet = new HashSet<IParameterizedMember>();\n\t\t\t\t\thashSet.UnionWith(resolver.GetUserDefinedOperatorCandidates(lhsType, method.Name));\n\t\t\t\t\thashSet.UnionWith(resolver.GetUserDefinedOperatorCandidates(rhsType, method.Name));\n\t\t\t\t\toperatorCandidates = hashSet;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\toperatorCandidates = EmptyList<IParameterizedMember>.Instance;\n\t\t\t\t}\n\t\t\t\tforeach (var m in operatorCandidates)\n\t\t\t\t{\n\t\t\t\t\tor.AddCandidate(m);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (target == null)\n\t\t\t{\n\t\t\t\tvar result = resolver.ResolveSimpleName(method.Name, typeArguments, isInvocationTarget: true)\n\t\t\t\t\tas MethodGroupResolveResult;\n\t\t\t\tif (result == null)\n\t\t\t\t\treturn OverloadResolutionErrors.AmbiguousMatch;\n\t\t\t\tor.AddMethodLists(result.MethodsGroupedByDeclaringType.ToArray());\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar result = lookup.Lookup(target, method.Name, typeArguments, isInvocation: true) as MethodGroupResolveResult;\n\t\t\t\tif (result == null)\n\t\t\t\t\treturn OverloadResolutionErrors.AmbiguousMatch;\n\t\t\t\tor.AddMethodLists(result.MethodsGroupedByDeclaringType.ToArray());\n\t\t\t}\n\t\t\tbestCandidateIsExpandedForm = or.BestCandidateIsExpandedForm;\n\t\t\tif (or.BestCandidateErrors != OverloadResolutionErrors.None)\n\t\t\t\treturn or.BestCandidateErrors;\n\t\t\tif (or.IsAmbiguous)\n\t\t\t\treturn OverloadResolutionErrors.AmbiguousMatch;\n\t\t\tfoundMember = or.GetBestCandidateWithSubstitutedTypeArguments();\n\t\t\tif (!IsAppropriateCallTarget(expectedTargetDetails, method, foundMember))\n\t\t\t\treturn OverloadResolutionErrors.AmbiguousMatch;\n\t\t\tvar map = or.GetArgumentToParameterMap();\n\t\t\tfor (int i = 0; i < arguments.Length; i++)\n\t\t\t{\n\t\t\t\tResolveResult arg = arguments[i];\n\t\t\t\tint parameterIndex = map[i];\n\t\t\t\tif (arg is OutVarResolveResult rr && parameterIndex >= 0)\n\t\t\t\t{\n\t\t\t\t\tvar param = foundMember.Parameters[parameterIndex];\n\t\t\t\t\tvar paramType = param.Type.UnwrapByRef();\n\t\t\t\t\tif (!paramType.Equals(rr.OriginalVariableType))\n\t\t\t\t\t\treturn OverloadResolutionErrors.OutVarTypeMismatch;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn OverloadResolutionErrors.None;\n\t\t}\n\n\t\tbool IsUnambiguousAccess(ExpectedTargetDetails expectedTargetDetails, ResolveResult target, IMethod method,\n\t\t\tIList<TranslatedExpression> arguments, string[] argumentNames, out IMember foundMember)\n\t\t{\n\t\t\tLog.WriteLine(\"IsUnambiguousAccess: Performing overload resolution for \" + method);\n\t\t\tLog.WriteCollection(\"  Arguments: \", arguments.Select(a => a.ResolveResult));\n\n\t\t\tfoundMember = null;\n\t\t\tif (target == null)\n\t\t\t{\n\t\t\t\tvar result = resolver.ResolveSimpleName(method.AccessorOwner.Name,\n\t\t\t\t\tEmptyList<IType>.Instance,\n\t\t\t\t\tisInvocationTarget: false) as MemberResolveResult;\n\t\t\t\tif (result == null || result.IsError)\n\t\t\t\t\treturn false;\n\t\t\t\tfoundMember = result.Member;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentModule);\n\t\t\t\tif (method.AccessorOwner.SymbolKind == SymbolKind.Indexer)\n\t\t\t\t{\n\t\t\t\t\tvar or = new OverloadResolution(resolver.Compilation,\n\t\t\t\t\t\targuments.SelectArray(a => a.ResolveResult),\n\t\t\t\t\t\targumentNames: argumentNames,\n\t\t\t\t\t\ttypeArguments: Empty<IType>.Array,\n\t\t\t\t\t\tconversions: expressionBuilder.resolver.conversions);\n\t\t\t\t\tor.AddMethodLists(lookup.LookupIndexers(target));\n\t\t\t\t\tif (or.BestCandidateErrors != OverloadResolutionErrors.None)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (or.IsAmbiguous)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tfoundMember = or.GetBestCandidateWithSubstitutedTypeArguments();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar result = lookup.Lookup(target,\n\t\t\t\t\t\tmethod.AccessorOwner.Name,\n\t\t\t\t\t\tEmptyList<IType>.Instance,\n\t\t\t\t\t\tisInvocation: false) as MemberResolveResult;\n\t\t\t\t\tif (result == null || result.IsError)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tfoundMember = result.Member;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn foundMember != null && IsAppropriateCallTarget(expectedTargetDetails, method.AccessorOwner, foundMember);\n\t\t}\n\n\t\tExpressionWithResolveResult HandleAccessorCall(ExpectedTargetDetails expectedTargetDetails, IMethod method,\n\t\t\tTranslatedExpression target, List<TranslatedExpression> arguments, string[] argumentNames)\n\t\t{\n\t\t\tbool requireTarget;\n\t\t\tif (settings.AlwaysQualifyMemberReferences || method.AccessorOwner.SymbolKind == SymbolKind.Indexer || expressionBuilder.HidesVariableWithName(method.AccessorOwner.Name))\n\t\t\t\trequireTarget = true;\n\t\t\telse if (method.IsStatic)\n\t\t\t\trequireTarget = !expressionBuilder.IsCurrentOrContainingType(method.DeclaringTypeDefinition);\n\t\t\telse\n\t\t\t\trequireTarget = !(target.Expression is ThisReferenceExpression);\n\t\t\tbool targetCasted = false;\n\t\t\tbool isSetter = method.ReturnType.IsKnownType(KnownTypeCode.Void);\n\t\t\tbool argumentsCasted = (isSetter && method.Parameters.Count == 1) || (!isSetter && method.Parameters.Count == 0);\n\t\t\tvar targetResolveResult = requireTarget ? target.ResolveResult : null;\n\n\t\t\tTranslatedExpression value = default(TranslatedExpression);\n\t\t\tif (isSetter)\n\t\t\t{\n\t\t\t\tvalue = arguments.Last();\n\t\t\t\targuments.Remove(value);\n\t\t\t}\n\n\t\t\tIMember foundMember;\n\t\t\twhile (!IsUnambiguousAccess(expectedTargetDetails, targetResolveResult, method, arguments, argumentNames, out foundMember))\n\t\t\t{\n\t\t\t\tif (!argumentsCasted)\n\t\t\t\t{\n\t\t\t\t\targumentsCasted = true;\n\t\t\t\t\tCastArguments(arguments, method.Parameters.ToList());\n\t\t\t\t}\n\t\t\t\telse if (!requireTarget)\n\t\t\t\t{\n\t\t\t\t\trequireTarget = true;\n\t\t\t\t\ttargetResolveResult = target.ResolveResult;\n\t\t\t\t}\n\t\t\t\telse if (!targetCasted)\n\t\t\t\t{\n\t\t\t\t\ttargetCasted = true;\n\t\t\t\t\ttarget = target.ConvertTo(method.AccessorOwner.DeclaringType, expressionBuilder);\n\t\t\t\t\ttargetResolveResult = target.ResolveResult;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfoundMember = method.AccessorOwner;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar rr = new MemberResolveResult(target.ResolveResult, foundMember);\n\n\t\t\tif (isSetter)\n\t\t\t{\n\t\t\t\tTranslatedExpression expr;\n\n\t\t\t\tif (arguments.Count != 0)\n\t\t\t\t{\n\t\t\t\t\texpr = new IndexerExpression(target.ResolveResult is InitializedObjectResolveResult ? null : target.Expression, arguments.Select(a => a.Expression))\n\t\t\t\t\t\t.WithoutILInstruction().WithRR(rr);\n\t\t\t\t}\n\t\t\t\telse if (requireTarget)\n\t\t\t\t{\n\t\t\t\t\texpr = new MemberReferenceExpression(target.Expression, method.AccessorOwner.Name)\n\t\t\t\t\t\t.WithoutILInstruction().WithRR(rr);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\texpr = new IdentifierExpression(method.AccessorOwner.Name)\n\t\t\t\t\t\t.WithoutILInstruction().WithRR(rr);\n\t\t\t\t}\n\n\t\t\t\tvar op = AssignmentOperatorType.Assign;\n\t\t\t\tif (method.AccessorOwner is IEvent parentEvent)\n\t\t\t\t{\n\t\t\t\t\tif (method.Equals(parentEvent.AddAccessor))\n\t\t\t\t\t{\n\t\t\t\t\t\top = AssignmentOperatorType.Add;\n\t\t\t\t\t}\n\t\t\t\t\tif (method.Equals(parentEvent.RemoveAccessor))\n\t\t\t\t\t{\n\t\t\t\t\t\top = AssignmentOperatorType.Subtract;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn new AssignmentExpression(expr, op, value.Expression).WithRR(new TypeResolveResult(method.AccessorOwner.ReturnType));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (arguments.Count != 0)\n\t\t\t\t{\n\t\t\t\t\treturn new IndexerExpression(target.Expression, arguments.Select(a => a.Expression))\n\t\t\t\t\t\t.WithoutILInstruction().WithRR(rr);\n\t\t\t\t}\n\t\t\t\telse if (requireTarget)\n\t\t\t\t{\n\t\t\t\t\treturn new MemberReferenceExpression(target.Expression, method.AccessorOwner.Name)\n\t\t\t\t\t\t.WithoutILInstruction().WithRR(rr);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn new IdentifierExpression(method.AccessorOwner.Name)\n\t\t\t\t\t\t.WithoutILInstruction().WithRR(rr);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool IsAppropriateCallTarget(ExpectedTargetDetails expectedTargetDetails, IMember expectedTarget, IMember actualTarget)\n\t\t{\n\t\t\tif (expectedTarget.Equals(actualTarget, NormalizeTypeVisitor.TypeErasure))\n\t\t\t\treturn true;\n\n\t\t\tif (expectedTargetDetails.CallOpCode == OpCode.CallVirt && actualTarget.IsOverride)\n\t\t\t{\n\t\t\t\tif (expectedTargetDetails.NeedsBoxingConversion && actualTarget.DeclaringType.IsReferenceType != true)\n\t\t\t\t\treturn false;\n\t\t\t\tforeach (var possibleTarget in InheritanceHelper.GetBaseMembers(actualTarget, false))\n\t\t\t\t{\n\t\t\t\t\tif (expectedTarget.Equals(possibleTarget, NormalizeTypeVisitor.TypeErasure))\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tif (!possibleTarget.IsOverride)\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tExpressionWithResolveResult HandleConstructorCall(ExpectedTargetDetails expectedTargetDetails, ResolveResult target, IMethod method, ArgumentList argumentList)\n\t\t{\n\t\t\tif (settings.AnonymousTypes && method.DeclaringType.IsAnonymousType())\n\t\t\t{\n\t\t\t\tDebug.Assert(argumentList.ArgumentToParameterMap == null && argumentList.ArgumentNames == null && argumentList.FirstOptionalArgumentIndex < 0);\n\t\t\t\tvar atce = new AnonymousTypeCreateExpression();\n\t\t\t\tif (argumentList.CanInferAnonymousTypePropertyNamesFromArguments())\n\t\t\t\t{\n\t\t\t\t\tatce.Initializers.AddRange(argumentList.GetArgumentExpressions());\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfor (int i = 0; i < argumentList.Length; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tatce.Initializers.Add(\n\t\t\t\t\t\t\tnew NamedExpression {\n\t\t\t\t\t\t\t\tName = argumentList.ExpectedParameters[i].Name,\n\t\t\t\t\t\t\t\tExpression = argumentList.Arguments[i].ConvertTo(argumentList.ExpectedParameters[i].Type, expressionBuilder)\n\t\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn atce.WithRR(new CSharpInvocationResolveResult(\n\t\t\t\t\ttarget, method, argumentList.GetArgumentResolveResults(),\n\t\t\t\t\tisExpandedForm: argumentList.IsExpandedForm, argumentToParameterMap: argumentList.ArgumentToParameterMap\n\t\t\t\t));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\twhile (IsUnambiguousCall(expectedTargetDetails, method, null, Empty<IType>.Array,\n\t\t\t\t\targumentList.GetArgumentResolveResults().ToArray(),\n\t\t\t\t\targumentList.GetArgumentNames(), argumentList.FirstOptionalArgumentIndex, out _,\n\t\t\t\t\tout var bestCandidateIsExpandedForm) != OverloadResolutionErrors.None || bestCandidateIsExpandedForm != argumentList.IsExpandedForm)\n\t\t\t\t{\n\t\t\t\t\tif (argumentList.AddNamesToPrimitiveValues)\n\t\t\t\t\t{\n\t\t\t\t\t\targumentList.AddNamesToPrimitiveValues = false;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (argumentList.FirstOptionalArgumentIndex >= 0)\n\t\t\t\t\t{\n\t\t\t\t\t\targumentList.FirstOptionalArgumentIndex = -1;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tCastArguments(argumentList.Arguments, argumentList.ExpectedParameters);\n\t\t\t\t\tbreak; // make sure that we don't not end up in an infinite loop\n\t\t\t\t}\n\t\t\t\tIType returnTypeOverride = null;\n\t\t\t\tif (typeSystem.MainModule.TypeSystemOptions.HasFlag(TypeSystemOptions.NativeIntegersWithoutAttribute))\n\t\t\t\t{\n\t\t\t\t\t// For DeclaringType, we don't use nint/nuint (so that DeclaringType.GetConstructors etc. works),\n\t\t\t\t\t// but in NativeIntegersWithoutAttribute mode we must use nint/nuint for expression types,\n\t\t\t\t\t// so that the appropriate set of conversions is used for further overload resolution.\n\t\t\t\t\tif (method.DeclaringType.IsKnownType(KnownTypeCode.IntPtr))\n\t\t\t\t\t\treturnTypeOverride = SpecialType.NInt;\n\t\t\t\t\telse if (method.DeclaringType.IsKnownType(KnownTypeCode.UIntPtr))\n\t\t\t\t\t\treturnTypeOverride = SpecialType.NUInt;\n\t\t\t\t}\n\t\t\t\treturn new ObjectCreateExpression(\n\t\t\t\t\texpressionBuilder.ConvertType(method.DeclaringType),\n\t\t\t\t\targumentList.GetArgumentExpressions()\n\t\t\t\t).WithRR(new CSharpInvocationResolveResult(\n\t\t\t\t\ttarget, method, argumentList.GetArgumentResolveResults().ToArray(),\n\t\t\t\t\tisExpandedForm: argumentList.IsExpandedForm,\n\t\t\t\t\targumentToParameterMap: argumentList.ArgumentToParameterMap,\n\t\t\t\t\treturnTypeOverride: returnTypeOverride\n\t\t\t\t));\n\t\t\t}\n\t\t}\n\n\t\tTranslatedExpression HandleDelegateConstruction(CallInstruction inst)\n\t\t{\n\t\t\tILInstruction thisArg = inst.Arguments[0];\n\t\t\tILInstruction func = inst.Arguments[1];\n\t\t\tIMethod method;\n\t\t\tExpectedTargetDetails expectedTargetDetails = default;\n\t\t\tswitch (func.OpCode)\n\t\t\t{\n\t\t\t\tcase OpCode.LdFtn:\n\t\t\t\t\tmethod = ((LdFtn)func).Method;\n\t\t\t\t\texpectedTargetDetails.CallOpCode = OpCode.Call;\n\t\t\t\t\tbreak;\n\t\t\t\tcase OpCode.LdVirtFtn:\n\t\t\t\t\tmethod = ((LdVirtFtn)func).Method;\n\t\t\t\t\texpectedTargetDetails.CallOpCode = OpCode.CallVirt;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentException($\"Unknown instruction type: {func.OpCode}\");\n\t\t\t}\n\t\t\tif (CanUseDelegateConstruction(method, thisArg, inst.Method.DeclaringType.GetDelegateInvokeMethod()))\n\t\t\t{\n\t\t\t\treturn HandleDelegateConstruction(inst.Method.DeclaringType, method, expectedTargetDetails, thisArg, inst);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar argumentList = BuildArgumentList(expectedTargetDetails, null, inst.Method,\n\t\t\t\t\t0, inst.Arguments, null);\n\t\t\t\treturn HandleConstructorCall(new ExpectedTargetDetails { CallOpCode = OpCode.NewObj }, null, inst.Method, argumentList).WithILInstruction(inst);\n\t\t\t}\n\t\t}\n\n\t\tprivate bool CanUseDelegateConstruction(IMethod targetMethod, ILInstruction thisArg, IMethod invokeMethod)\n\t\t{\n\t\t\t// Accessors cannot be directly referenced as method group in C#\n\t\t\t// see https://github.com/icsharpcode/ILSpy/issues/1741#issuecomment-540179101\n\t\t\tif (targetMethod.IsAccessor)\n\t\t\t\treturn false;\n\t\t\tif (targetMethod.IsStatic)\n\t\t\t{\n\t\t\t\t// If the invoke method is known, we can compare the parameter counts to figure out whether the\n\t\t\t\t// delegate is static or binds the first argument\n\t\t\t\tif (invokeMethod != null)\n\t\t\t\t{\n\t\t\t\t\tif (invokeMethod.Parameters.Count == targetMethod.Parameters.Count)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn thisArg.MatchLdNull();\n\t\t\t\t\t}\n\t\t\t\t\telse if (targetMethod.IsExtensionMethod && invokeMethod.Parameters.Count == targetMethod.Parameters.Count - 1)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// delegate type unknown:\n\t\t\t\t\treturn thisArg.MatchLdNull() || targetMethod.IsExtensionMethod;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// targetMethod is instance method\n\t\t\t\tif (invokeMethod != null && invokeMethod.Parameters.Count != targetMethod.Parameters.Count)\n\t\t\t\t\treturn false;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tinternal TranslatedExpression Build(LdVirtDelegate inst)\n\t\t{\n\t\t\treturn HandleDelegateConstruction(inst.Type, inst.Method, new ExpectedTargetDetails { CallOpCode = OpCode.CallVirt }, inst.Argument, inst);\n\t\t}\n\n\t\tinternal ExpressionWithResolveResult BuildMethodReference(IMethod method, bool isVirtual)\n\t\t{\n\t\t\tvar expr = BuildDelegateReference(method, invokeMethod: null, new ExpectedTargetDetails { CallOpCode = isVirtual ? OpCode.CallVirt : OpCode.Call }, thisArg: null);\n\t\t\texpr.Expression.RemoveAnnotations<ResolveResult>();\n\t\t\treturn expr.Expression.WithRR(new MemberResolveResult(null, method));\n\t\t}\n\n\t\tExpressionWithResolveResult BuildDelegateReference(IMethod method, IMethod invokeMethod, ExpectedTargetDetails expectedTargetDetails, ILInstruction thisArg)\n\t\t{\n\t\t\tExpressionBuilder expressionBuilder = this.expressionBuilder;\n\t\t\tExpressionWithResolveResult targetExpression;\n\t\t\t(TranslatedExpression target, bool addTypeArguments, string methodName, ResolveResult result) = DisambiguateDelegateReference(method, invokeMethod, expectedTargetDetails, thisArg);\n\t\t\tif (target.Expression != null)\n\t\t\t{\n\t\t\t\tvar mre = new MemberReferenceExpression(target, methodName);\n\t\t\t\tif (addTypeArguments)\n\t\t\t\t{\n\t\t\t\t\tmre.TypeArguments.AddRange(method.TypeArguments.Select(expressionBuilder.ConvertType));\n\t\t\t\t}\n\t\t\t\ttargetExpression = mre.WithRR(result);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar ide = new IdentifierExpression(methodName);\n\t\t\t\tif (addTypeArguments)\n\t\t\t\t{\n\t\t\t\t\tide.TypeArguments.AddRange(method.TypeArguments.Select(expressionBuilder.ConvertType));\n\t\t\t\t}\n\t\t\t\ttargetExpression = ide.WithRR(result);\n\t\t\t}\n\t\t\treturn targetExpression;\n\n\t\t}\n\n\t\t(TranslatedExpression target, bool addTypeArguments, string methodName, ResolveResult result) DisambiguateDelegateReference(IMethod method, IMethod invokeMethod, ExpectedTargetDetails expectedTargetDetails, ILInstruction thisArg)\n\t\t{\n\t\t\tif (method.IsLocalFunction)\n\t\t\t{\n\t\t\t\tILFunction localFunction = expressionBuilder.ResolveLocalFunction(method);\n\t\t\t\tDebug.Assert(localFunction != null);\n\t\t\t\treturn (default, addTypeArguments: true, localFunction.Name, ToMethodGroup(method, localFunction));\n\t\t\t}\n\t\t\tif (method.IsExtensionMethod && method.Parameters.Count - 1 == invokeMethod?.Parameters.Count)\n\t\t\t{\n\t\t\t\tIType targetType = method.Parameters[0].Type;\n\t\t\t\tif (targetType.Kind == TypeKind.ByReference && thisArg is Box thisArgBox)\n\t\t\t\t{\n\t\t\t\t\ttargetType = ((ByReferenceType)targetType).ElementType;\n\t\t\t\t\tthisArg = thisArgBox.Argument;\n\t\t\t\t}\n\t\t\t\tTranslatedExpression target = expressionBuilder.Translate(thisArg, targetType);\n\t\t\t\tvar currentTarget = target;\n\t\t\t\tbool targetCasted = false;\n\t\t\t\tbool addTypeArguments = false;\n\t\t\t\t// Initial inputs for IsUnambiguousMethodReference:\n\t\t\t\tResolveResult targetResolveResult = target.ResolveResult;\n\t\t\t\tIReadOnlyList<IType> typeArguments = EmptyList<IType>.Instance;\n\t\t\t\tif (thisArg.MatchLdNull())\n\t\t\t\t{\n\t\t\t\t\ttargetCasted = true;\n\t\t\t\t\tcurrentTarget = currentTarget.ConvertTo(targetType, expressionBuilder);\n\t\t\t\t\ttargetResolveResult = currentTarget.ResolveResult;\n\t\t\t\t}\n\t\t\t\t// Find somewhat minimal solution:\n\t\t\t\tResolveResult result;\n\t\t\t\twhile (!IsUnambiguousMethodReference(expectedTargetDetails, method, targetResolveResult, typeArguments, true, out result))\n\t\t\t\t{\n\t\t\t\t\tif (!targetCasted)\n\t\t\t\t\t{\n\t\t\t\t\t\t// try casting target\n\t\t\t\t\t\ttargetCasted = true;\n\t\t\t\t\t\tcurrentTarget = currentTarget.ConvertTo(targetType, expressionBuilder);\n\t\t\t\t\t\ttargetResolveResult = currentTarget.ResolveResult;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (!addTypeArguments)\n\t\t\t\t\t{\n\t\t\t\t\t\t// try adding type arguments\n\t\t\t\t\t\taddTypeArguments = true;\n\t\t\t\t\t\ttypeArguments = method.TypeArguments;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treturn (currentTarget, addTypeArguments, method.Name, result);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Prepare call target\n\t\t\t\tIType targetType = method.DeclaringType;\n\t\t\t\tif (targetType.IsReferenceType == false && thisArg is Box thisArgBox)\n\t\t\t\t{\n\t\t\t\t\t// Normal struct instance method calls (which TranslateTarget is meant for) expect a 'ref T',\n\t\t\t\t\t// but delegate construction uses a 'box T'.\n\t\t\t\t\tif (thisArgBox.Argument is LdObj ldobj)\n\t\t\t\t\t{\n\t\t\t\t\t\tthisArg = ldobj.Target;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tthisArg = new AddressOf(thisArgBox.Argument, thisArgBox.Type);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tTranslatedExpression target = expressionBuilder.TranslateTarget(thisArg,\n\t\t\t\t\tnonVirtualInvocation: expectedTargetDetails.CallOpCode == OpCode.Call,\n\t\t\t\t\tmemberStatic: method.IsStatic,\n\t\t\t\t\tmemberDeclaringType: method.DeclaringType);\n\t\t\t\t// check if target is required\n\t\t\t\tbool requireTarget = expressionBuilder.HidesVariableWithName(method.Name)\n\t\t\t\t\t|| (method.IsStatic ? !expressionBuilder.IsCurrentOrContainingType(method.DeclaringTypeDefinition) : !(target.Expression is ThisReferenceExpression));\n\t\t\t\t// Try to find minimal expression\n\t\t\t\t// If target is required, include it from the start\n\t\t\t\tbool targetAdded = requireTarget;\n\t\t\t\tTranslatedExpression currentTarget = targetAdded ? target : default;\n\t\t\t\t// Remember other decisions:\n\t\t\t\tbool targetCasted = false;\n\t\t\t\tbool addTypeArguments = false;\n\t\t\t\t// Initial inputs for IsUnambiguousMethodReference:\n\t\t\t\tResolveResult targetResolveResult = targetAdded ? target.ResolveResult : null;\n\t\t\t\tIReadOnlyList<IType> typeArguments = EmptyList<IType>.Instance;\n\t\t\t\t// Find somewhat minimal solution:\n\t\t\t\tResolveResult result;\n\t\t\t\twhile (!IsUnambiguousMethodReference(expectedTargetDetails, method, targetResolveResult, typeArguments, false, out result))\n\t\t\t\t{\n\t\t\t\t\tif (!addTypeArguments)\n\t\t\t\t\t{\n\t\t\t\t\t\t// try adding type arguments\n\t\t\t\t\t\taddTypeArguments = true;\n\t\t\t\t\t\ttypeArguments = method.TypeArguments;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (!targetAdded)\n\t\t\t\t\t{\n\t\t\t\t\t\t// try adding target\n\t\t\t\t\t\ttargetAdded = true;\n\t\t\t\t\t\tcurrentTarget = target;\n\t\t\t\t\t\ttargetResolveResult = target.ResolveResult;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (!targetCasted)\n\t\t\t\t\t{\n\t\t\t\t\t\t// try casting target\n\t\t\t\t\t\ttargetCasted = true;\n\t\t\t\t\t\tcurrentTarget = currentTarget.ConvertTo(targetType, expressionBuilder);\n\t\t\t\t\t\ttargetResolveResult = currentTarget.ResolveResult;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (result is MethodGroupResolveResult mgrr)\n\t\t\t\t{\n\t\t\t\t\tresult = mgrr.WithChosenMethod(method);\n\t\t\t\t}\n\t\t\t\treturn (currentTarget, addTypeArguments, method.Name, result);\n\t\t\t}\n\t\t}\n\n\t\tTranslatedExpression HandleDelegateConstruction(IType delegateType, IMethod method, ExpectedTargetDetails expectedTargetDetails, ILInstruction thisArg, ILInstruction inst)\n\t\t{\n\t\t\tvar invokeMethod = delegateType.GetDelegateInvokeMethod();\n\t\t\tvar targetExpression = BuildDelegateReference(method, invokeMethod, expectedTargetDetails, thisArg);\n\t\t\tvar oce = new ObjectCreateExpression(expressionBuilder.ConvertType(delegateType), targetExpression)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new ConversionResolveResult(\n\t\t\t\t\tdelegateType,\n\t\t\t\t\ttargetExpression.ResolveResult,\n\t\t\t\t\tConversion.MethodGroupConversion(method, expectedTargetDetails.CallOpCode == OpCode.CallVirt, false)));\n\t\t\treturn oce;\n\t\t}\n\n\t\tbool IsUnambiguousMethodReference(ExpectedTargetDetails expectedTargetDetails, IMethod method, ResolveResult target, IReadOnlyList<IType> typeArguments, bool isExtensionMethodReference, out ResolveResult result)\n\t\t{\n\t\t\tLog.WriteLine(\"IsUnambiguousMethodReference: Performing overload resolution for \" + method);\n\n\t\t\tvar lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentModule);\n\t\t\tOverloadResolution or;\n\n\t\t\tif (isExtensionMethodReference)\n\t\t\t{\n\t\t\t\tresult = resolver.ResolveMemberAccess(target, method.Name, typeArguments, NameLookupMode.InvocationTarget) as MethodGroupResolveResult;\n\t\t\t\tif (result == null)\n\t\t\t\t\treturn false;\n\t\t\t\tor = ((MethodGroupResolveResult)result).PerformOverloadResolution(resolver.CurrentTypeResolveContext.Compilation,\n\t\t\t\t\tmethod.Parameters.SelectReadOnlyArray(p => new TypeResolveResult(p.Type)),\n\t\t\t\t\targumentNames: null, allowExtensionMethods: true);\n\t\t\t\tif (or == null || or.IsAmbiguous)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tor = new OverloadResolution(resolver.Compilation,\n\t\t\t\t\targuments: method.Parameters.SelectReadOnlyArray(p => new TypeResolveResult(p.Type)), // there are no arguments, use parameter types\n\t\t\t\t\targumentNames: null, // argument names are not possible\n\t\t\t\t\ttypeArguments.ToArray(),\n\t\t\t\t\tconversions: expressionBuilder.resolver.conversions\n\t\t\t\t);\n\t\t\t\tif (target == null)\n\t\t\t\t{\n\t\t\t\t\tresult = resolver.ResolveSimpleName(method.Name, typeArguments, isInvocationTarget: false);\n\t\t\t\t\tif (!(result is MethodGroupResolveResult mgrr))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tor.AddMethodLists(mgrr.MethodsGroupedByDeclaringType.ToArray());\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tresult = lookup.Lookup(target, method.Name, typeArguments, isInvocation: false);\n\t\t\t\t\tif (!(result is MethodGroupResolveResult mgrr))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tor.AddMethodLists(mgrr.MethodsGroupedByDeclaringType.ToArray());\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar foundMethod = or.GetBestCandidateWithSubstitutedTypeArguments();\n\t\t\tif (!IsAppropriateCallTarget(expectedTargetDetails, method, foundMethod))\n\t\t\t\treturn false;\n\t\t\treturn result is MethodGroupResolveResult;\n\t\t}\n\n\t\tstatic MethodGroupResolveResult ToMethodGroup(IMethod method, ILFunction localFunction)\n\t\t{\n\t\t\treturn new MethodGroupResolveResult(\n\t\t\t\tnull,\n\t\t\t\tlocalFunction.Name,\n\t\t\t\tnew[] {\n\t\t\t\t\tnew MethodListWithDeclaringType(\n\t\t\t\t\t\tmethod.DeclaringType,\n\t\t\t\t\t\tnew IParameterizedMember[] { method }\n\t\t\t\t\t)\n\t\t\t\t}, method.TypeArguments\n\t\t\t);\n\t\t}\n\n\t\tinternal TranslatedExpression CallWithNamedArgs(Block block)\n\t\t{\n\t\t\tDebug.Assert(block.Kind == BlockKind.CallWithNamedArgs);\n\t\t\tvar call = (CallInstruction)block.FinalInstruction;\n\t\t\tvar arguments = new ILInstruction[call.Arguments.Count];\n\t\t\tvar argumentToParameterMap = new int[arguments.Length];\n\t\t\tint firstParamIndex = call.IsInstanceCall ? 1 : 0;\n\t\t\t// Arguments from temporary variables (VariableKind.NamedArgument):\n\t\t\tint pos = 0;\n\t\t\tforeach (StLoc stloc in block.Instructions)\n\t\t\t{\n\t\t\t\tDebug.Assert(stloc.Variable.LoadInstructions.Single().Parent == call);\n\t\t\t\targuments[pos] = stloc.Value;\n\t\t\t\targumentToParameterMap[pos] = stloc.Variable.LoadInstructions.Single().ChildIndex - firstParamIndex;\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\t// Remaining argument:\n\t\t\tforeach (var arg in call.Arguments)\n\t\t\t{\n\t\t\t\tif (arg.MatchLdLoc(out var v) && v.Kind == VariableKind.NamedArgument)\n\t\t\t\t{\n\t\t\t\t\tcontinue; // already handled in loop above\n\t\t\t\t}\n\t\t\t\targuments[pos] = arg;\n\t\t\t\targumentToParameterMap[pos] = arg.ChildIndex - firstParamIndex;\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\tDebug.Assert(pos == arguments.Length);\n\t\t\treturn Build(call.OpCode, call.Method, arguments, argumentToParameterMap, call.ConstrainedTo)\n\t\t\t\t.WithILInstruction(call).WithILInstruction(block);\n\t\t}\n\n\t\tprivate bool HandleRangeConstruction(out ExpressionWithResolveResult result, OpCode callOpCode, IMethod method, TranslatedExpression target, ArgumentList argumentList)\n\t\t{\n\t\t\tresult = default;\n\t\t\tif (argumentList.ArgumentNames != null)\n\t\t\t{\n\t\t\t\treturn false; // range syntax doesn't support named arguments\n\t\t\t}\n\t\t\tif (method.DeclaringType.IsKnownType(KnownTypeCode.Range))\n\t\t\t{\n\t\t\t\tif (callOpCode == OpCode.NewObj && argumentList.Length == 2)\n\t\t\t\t{\n\t\t\t\t\tresult = new BinaryOperatorExpression(argumentList.Arguments[0], BinaryOperatorType.Range, argumentList.Arguments[1])\n\t\t\t\t\t\t.WithRR(new MemberResolveResult(null, method));\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse if (callOpCode == OpCode.Call && method.Name == \"get_All\" && argumentList.Length == 0)\n\t\t\t\t{\n\t\t\t\t\tresult = new BinaryOperatorExpression(Expression.Null, BinaryOperatorType.Range, Expression.Null)\n\t\t\t\t\t\t.WithRR(new MemberResolveResult(null, method.AccessorOwner ?? method));\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse if (callOpCode == OpCode.Call && method.Name == \"StartAt\" && argumentList.Length == 1)\n\t\t\t\t{\n\t\t\t\t\tresult = new BinaryOperatorExpression(argumentList.Arguments[0], BinaryOperatorType.Range, Expression.Null)\n\t\t\t\t\t\t.WithRR(new MemberResolveResult(null, method));\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse if (callOpCode == OpCode.Call && method.Name == \"EndAt\" && argumentList.Length == 1)\n\t\t\t\t{\n\t\t\t\t\tresult = new BinaryOperatorExpression(Expression.Null, BinaryOperatorType.Range, argumentList.Arguments[0])\n\t\t\t\t\t\t.WithRR(new MemberResolveResult(null, method));\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (callOpCode == OpCode.NewObj && method.DeclaringType.IsKnownType(KnownTypeCode.Index))\n\t\t\t{\n\t\t\t\tif (argumentList.Length != 2)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(argumentList.Arguments[1].Expression is PrimitiveExpression pe && pe.Value is true))\n\t\t\t\t\treturn false;\n\t\t\t\tresult = new UnaryOperatorExpression(UnaryOperatorType.IndexFromEnd, argumentList.Arguments[0])\n\t\t\t\t\t.WithRR(new MemberResolveResult(null, method));\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (method is SyntheticRangeIndexAccessor rangeIndexAccessor && rangeIndexAccessor.IsSlicing)\n\t\t\t{\n\t\t\t\t// For slicing the method is called Slice()/Substring(), but we still need to output indexer notation.\n\t\t\t\t// So special-case range-based slicing here.\n\t\t\t\tresult = new IndexerExpression(target, argumentList.Arguments.Select(a => a.Expression))\n\t\t\t\t\t.WithRR(new MemberResolveResult(target.ResolveResult, method));\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs",
    "content": "// Copyright (c) 2014-2020 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.CSharp.Resolver;\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.CSharp.Transforms;\nusing ICSharpCode.Decompiler.CSharp.TypeSystem;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nusing ExpressionType = System.Linq.Expressions.ExpressionType;\nusing PrimitiveType = ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveType;\n\nnamespace ICSharpCode.Decompiler.CSharp\n{\n\t/// <summary>\n\t/// Translates from ILAst to C# expressions.\n\t/// </summary>\n\t/// <remarks>\n\t/// Every translated expression must have:\n\t/// * an ILInstruction annotation\n\t/// * a ResolveResult annotation\n\t/// Post-condition for Translate() calls:\n\t///   * The type of the ResolveResult must match the StackType of the corresponding ILInstruction,\n\t///     except that the width of integer types does not need to match (I4, I and I8 count as the same stack type here)\n\t///   * Evaluating the resulting C# expression shall produce the same side effects as evaluating the ILInstruction.\n\t///   * If the IL instruction has <c>ResultType == StackType.Void</c>, the C# expression may evaluate to an arbitrary type and value.\n\t///   * Otherwise, evaluating the resulting C# expression shall produce a similar value as evaluating the ILInstruction.\n\t///      * If the IL instruction evaluates to an integer stack type (I4, I, or I8),\n\t///        the C# type of the resulting expression shall also be an integer (or enum/pointer/char/bool) type.\n\t///        * If sizeof(C# type) == sizeof(IL stack type), the values must be the same.\n\t///        * If sizeof(C# type) > sizeof(IL stack type), the C# value truncated to the width of the IL stack type must equal the IL value.\n\t///        * If sizeof(C# type) &lt; sizeof(IL stack type), the C# value (sign/zero-)extended to the width of the IL stack type\n\t///          must equal the IL value.\n\t///          Whether sign or zero extension is used depends on the sign of the C# type (as determined by <c>IType.GetSign()</c>).\n\t///      * If the IL instruction is a lifted nullable operation, and the underlying operation evaluates to an integer stack type,\n\t///        the C# type of the resulting expression shall be Nullable{T}, where T is an integer type (as above).\n\t///        The C# value shall be null iff the IL-level value evaluates to null, and otherwise the values shall correspond\n\t///        as with non-lifted integer operations.\n\t///      * If the IL instruction evaluates to a managed reference (Ref) created by starting tracking of an unmanaged reference,\n\t///        the C# instruction may evaluate to any integral/enum/pointer type that when converted to pointer type\n\t///        is equivalent to the managed reference.\n\t///      * Otherwise, the C# type of the resulting expression shall match the IL stack type,\n\t///        and the evaluated values shall be the same.\n\t/// </remarks>\n\tsealed class ExpressionBuilder : ILVisitor<TranslationContext, TranslatedExpression>\n\t{\n\t\tinternal readonly StatementBuilder statementBuilder;\n\t\treadonly IDecompilerTypeSystem typeSystem;\n\t\tinternal readonly ITypeResolveContext decompilationContext;\n\t\tinternal readonly ILFunction currentFunction;\n\t\tinternal readonly ICompilation compilation;\n\t\tinternal readonly CSharpResolver resolver;\n\t\tinternal readonly TypeSystemAstBuilder astBuilder;\n\t\tinternal readonly TypeInference typeInference;\n\t\tinternal readonly DecompilerSettings settings;\n\t\treadonly CancellationToken cancellationToken;\n\n\t\tpublic ExpressionBuilder(StatementBuilder statementBuilder, IDecompilerTypeSystem typeSystem,\n\t\t\tITypeResolveContext decompilationContext, ILFunction currentFunction, DecompilerSettings settings,\n\t\t\tDecompileRun decompileRun, CancellationToken cancellationToken)\n\t\t{\n\t\t\tDebug.Assert(decompilationContext != null);\n\t\t\tthis.statementBuilder = statementBuilder;\n\t\t\tthis.typeSystem = typeSystem;\n\t\t\tthis.decompilationContext = decompilationContext;\n\t\t\tthis.currentFunction = currentFunction;\n\t\t\tthis.settings = settings;\n\t\t\tthis.cancellationToken = cancellationToken;\n\t\t\tthis.compilation = decompilationContext.Compilation;\n\t\t\tthis.resolver = new CSharpResolver(new CSharpTypeResolveContext(\n\t\t\t\tcompilation.MainModule,\n\t\t\t\tdecompileRun.UsingScope,\n\t\t\t\tdecompilationContext.CurrentTypeDefinition,\n\t\t\t\tdecompilationContext.CurrentMember\n\t\t\t\t));\n\t\t\tthis.astBuilder = new TypeSystemAstBuilder(resolver);\n\t\t\tthis.astBuilder.AlwaysUseShortTypeNames = true;\n\t\t\tthis.astBuilder.AddResolveResultAnnotations = true;\n\t\t\tthis.astBuilder.ShowAttributes = true;\n\t\t\tthis.astBuilder.UseNullableSpecifierForValueTypes = settings.LiftNullables;\n\t\t\tthis.astBuilder.AlwaysUseGlobal = settings.AlwaysUseGlobal;\n\t\t\tthis.typeInference = new TypeInference(compilation) { Algorithm = TypeInferenceAlgorithm.Improved };\n\t\t}\n\n\t\tpublic AstType ConvertType(IType type)\n\t\t{\n\t\t\tvar astType = astBuilder.ConvertType(type);\n\t\t\tDebug.Assert(astType.Annotation<TypeResolveResult>() != null);\n\t\t\treturn astType;\n\t\t}\n\n\t\tpublic ExpressionWithResolveResult ConvertConstantValue(ResolveResult rr, bool allowImplicitConversion = false)\n\t\t{\n\t\t\tvar expr = astBuilder.ConvertConstantValue(rr);\n\t\t\tif (!allowImplicitConversion)\n\t\t\t{\n\t\t\t\tif (expr is NullReferenceExpression && rr.Type.Kind != TypeKind.Null)\n\t\t\t\t{\n\t\t\t\t\texpr = new CastExpression(ConvertType(rr.Type), expr);\n\t\t\t\t}\n\t\t\t\telse if (rr.Type.IsCSharpSmallIntegerType())\n\t\t\t\t{\n\t\t\t\t\texpr = new CastExpression(new PrimitiveType(KnownTypeReference.GetCSharpNameByTypeCode(rr.Type.GetDefinition().KnownTypeCode)), expr);\n\t\t\t\t\t// Note: no unchecked annotation necessary, because the constant was folded to be in-range\n\t\t\t\t}\n\t\t\t\telse if (rr.Type.IsCSharpNativeIntegerType())\n\t\t\t\t{\n\t\t\t\t\texpr = new CastExpression(new PrimitiveType(rr.Type.Name), expr);\n\t\t\t\t\t// Note: no unchecked annotation necessary, because the rr wouldn't be a constant if the value wasn't in-range on 32bit\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar exprRR = expr.Annotation<ResolveResult>();\n\t\t\tif (exprRR == null)\n\t\t\t{\n\t\t\t\texprRR = rr;\n\t\t\t\texpr.AddAnnotation(rr);\n\t\t\t}\n\t\t\treturn new ExpressionWithResolveResult(expr, exprRR);\n\t\t}\n\n\t\tpublic ExpressionWithResolveResult ConvertConstantValue(ResolveResult rr,\n\t\t\tbool allowImplicitConversion = false, bool displayAsHex = false)\n\t\t{\n\t\t\tastBuilder.PrintIntegralValuesAsHex = displayAsHex;\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn ConvertConstantValue(rr, allowImplicitConversion);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tastBuilder.PrintIntegralValuesAsHex = false;\n\t\t\t}\n\t\t}\n\n\t\tpublic TranslatedExpression Translate(ILInstruction inst, IType typeHint = null)\n\t\t{\n\t\t\tDebug.Assert(inst != null);\n\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\tTranslationContext context = new TranslationContext {\n\t\t\t\tTypeHint = typeHint ?? SpecialType.UnknownType\n\t\t\t};\n\t\t\tvar cexpr = inst.AcceptVisitor(this, context);\n#if DEBUG\n\t\t\tif (inst.ResultType != StackType.Void && cexpr.Type.Kind != TypeKind.Unknown && inst.ResultType != StackType.Unknown && cexpr.Type.Kind != TypeKind.None)\n\t\t\t{\n\t\t\t\t// Validate the Translate post-condition (documented at beginning of this file):\n\t\t\t\tif (inst.ResultType.IsIntegerType())\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(cexpr.Type.GetStackType().IsIntegerType(), \"IL instructions of integer type must convert into C# expressions of integer type\");\n\t\t\t\t\tDebug.Assert(cexpr.Type.GetSign() != Sign.None, \"Must have a sign specified for zero/sign-extension\");\n\t\t\t\t}\n\t\t\t\telse if (inst is ILiftableInstruction liftable && liftable.IsLifted)\n\t\t\t\t{\n\t\t\t\t\tif (liftable.UnderlyingResultType != StackType.Unknown)\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(NullableType.IsNullable(cexpr.Type));\n\t\t\t\t\t\tIType underlying = NullableType.GetUnderlyingType(cexpr.Type);\n\t\t\t\t\t\tif (liftable.UnderlyingResultType.IsIntegerType())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tDebug.Assert(underlying.GetStackType().IsIntegerType(), \"IL instructions of integer type must convert into C# expressions of integer type\");\n\t\t\t\t\t\t\tDebug.Assert(underlying.GetSign() != Sign.None, \"Must have a sign specified for zero/sign-extension\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tDebug.Assert(underlying.GetStackType() == liftable.UnderlyingResultType);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (inst.ResultType == StackType.Ref)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(cexpr.Type.GetStackType() == StackType.Ref || cexpr.Type.GetStackType().IsIntegerType());\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(cexpr.Type.GetStackType() == inst.ResultType);\n\t\t\t\t}\n\t\t\t}\n#endif\n\t\t\treturn cexpr;\n\t\t}\n\n\t\tpublic TranslatedExpression TranslateCondition(ILInstruction condition, bool negate = false)\n\t\t{\n\t\t\tDebug.Assert(condition.ResultType == StackType.I4);\n\t\t\tvar expr = Translate(condition, compilation.FindType(KnownTypeCode.Boolean));\n\t\t\tif (expr.Type.GetStackType().GetSize() > 4)\n\t\t\t{\n\t\t\t\texpr = expr.ConvertTo(FindType(StackType.I4, expr.Type.GetSign()), this);\n\t\t\t}\n\t\t\treturn expr.ConvertToBoolean(this, negate);\n\t\t}\n\n\t\tinternal ExpressionWithResolveResult ConvertVariable(ILVariable variable)\n\t\t{\n\t\t\tExpression expr;\n\t\t\tif (variable.Kind == VariableKind.Parameter && variable.Index < 0)\n\t\t\t\texpr = new ThisReferenceExpression();\n\t\t\telse\n\t\t\t\texpr = new IdentifierExpression(variable.Name);\n\t\t\tif (variable.Type.Kind == TypeKind.ByReference)\n\t\t\t{\n\t\t\t\t// When loading a by-ref parameter, use 'ref paramName'.\n\t\t\t\t// We'll strip away the 'ref' when dereferencing.\n\n\t\t\t\t// Ensure that the IdentifierExpression itself also gets a resolve result, as that might\n\t\t\t\t// get used after the 'ref' is stripped away:\n\t\t\t\tvar elementType = ((ByReferenceType)variable.Type).ElementType;\n\t\t\t\tvar elementRR = new ILVariableResolveResult(variable, elementType);\n\t\t\t\texpr.WithRR(elementRR);\n\n\t\t\t\texpr = new DirectionExpression(FieldDirection.Ref, expr);\n\t\t\t\treturn expr.WithRR(new ByReferenceResolveResult(elementRR, ReferenceKind.Ref));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn expr.WithRR(new ILVariableResolveResult(variable, variable.Type));\n\t\t\t}\n\t\t}\n\n\t\tinternal bool HidesVariableWithName(string name)\n\t\t{\n\t\t\treturn HidesVariableWithName(currentFunction, name);\n\t\t}\n\n\t\tinternal static bool HidesVariableWithName(ILFunction currentFunction, string name)\n\t\t{\n\t\t\treturn currentFunction.Ancestors.OfType<ILFunction>().Any(HidesVariableOrNestedFunction);\n\n\t\t\tbool HidesVariableOrNestedFunction(ILFunction function)\n\t\t\t{\n\t\t\t\tforeach (var v in function.Variables)\n\t\t\t\t{\n\t\t\t\t\tif (v.Name == name)\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tforeach (var f in function.LocalFunctions)\n\t\t\t\t{\n\t\t\t\t\tif (f.Name == name)\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tinternal ILFunction ResolveLocalFunction(IMethod method)\n\t\t{\n\t\t\tDebug.Assert(method.IsLocalFunction);\n\t\t\tmethod = (IMethod)((IMethod)method.MemberDefinition).ReducedFrom.MemberDefinition;\n\t\t\tforeach (var parent in currentFunction.Ancestors.OfType<ILFunction>())\n\t\t\t{\n\t\t\t\tvar definition = parent.LocalFunctions.FirstOrDefault(f => f.Method.MemberDefinition.Equals(method));\n\t\t\t\tif (definition != null)\n\t\t\t\t{\n\t\t\t\t\treturn definition;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tbool RequiresQualifier(IMember member, TranslatedExpression target)\n\t\t{\n\t\t\tif (settings.AlwaysQualifyMemberReferences || HidesVariableWithName(member.Name))\n\t\t\t\treturn true;\n\t\t\tif (member.IsStatic)\n\t\t\t\treturn !IsCurrentOrContainingType(member.DeclaringTypeDefinition);\n\t\t\treturn !(target.Expression is ThisReferenceExpression || target.Expression is BaseReferenceExpression);\n\t\t}\n\n\t\tExpressionWithResolveResult ConvertField(IField field, ILInstruction targetInstruction = null)\n\t\t{\n\t\t\tvar target = TranslateTarget(targetInstruction,\n\t\t\t\tnonVirtualInvocation: true,\n\t\t\t\tmemberStatic: field.IsStatic,\n\t\t\t\tmemberDeclaringType: field.DeclaringType);\n\t\t\tbool requireTarget;\n\t\t\t// If this is a reference to the backing field of an automatic property and we're going to transform automatic properties\n\t\t\t// in PatternStatementTransform, then we have to do the \"requires qualifier\"-check based on the property instead of the field.\n\t\t\t// It is easier to solve this special case here than in PatternStatementTransform, because here we perform all resolver checks.\n\t\t\t// It feels a bit hacky, though.\n\t\t\tif (settings.AutomaticProperties\n\t\t\t\t&& PatternStatementTransform.IsBackingFieldOfAutomaticProperty(field, out var property)\n\t\t\t\t&& decompilationContext.CurrentMember != property\n\t\t\t\t&& (property.CanSet || settings.GetterOnlyAutomaticProperties))\n\t\t\t{\n\t\t\t\trequireTarget = RequiresQualifier(property, target);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\trequireTarget = RequiresQualifier(field, target);\n\t\t\t}\n\t\t\tbool targetCasted = false;\n\t\t\tvar targetResolveResult = requireTarget ? target.ResolveResult : null;\n\n\t\t\tbool IsAmbiguousAccess(out MemberResolveResult result)\n\t\t\t{\n\t\t\t\tif (targetResolveResult == null)\n\t\t\t\t{\n\t\t\t\t\tresult = resolver.ResolveSimpleName(field.Name, EmptyList<IType>.Instance, isInvocationTarget: false) as MemberResolveResult;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentModule);\n\t\t\t\t\tresult = lookup.Lookup(target.ResolveResult, field.Name, EmptyList<IType>.Instance, isInvocation: false) as MemberResolveResult;\n\t\t\t\t}\n\t\t\t\treturn result == null || result.IsError || !result.Member.Equals(field, NormalizeTypeVisitor.TypeErasure);\n\t\t\t}\n\n\t\t\tMemberResolveResult mrr;\n\t\t\twhile (IsAmbiguousAccess(out mrr))\n\t\t\t{\n\t\t\t\tif (!requireTarget)\n\t\t\t\t{\n\t\t\t\t\trequireTarget = true;\n\t\t\t\t\ttargetResolveResult = target.ResolveResult;\n\t\t\t\t}\n\t\t\t\telse if (!targetCasted)\n\t\t\t\t{\n\t\t\t\t\ttargetCasted = true;\n\t\t\t\t\ttarget = target.ConvertTo(field.DeclaringType, this);\n\t\t\t\t\ttargetResolveResult = target.ResolveResult;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// the field reference is still ambiguous, however, mrr might refer to a different member,\n\t\t\t\t\t// e.g., in the case of auto events, their backing fields have the same name.\n\t\t\t\t\t// \"this.Event\" is ambiguous, but should refer to the field, not the event.\n\t\t\t\t\tmrr = null;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (mrr == null)\n\t\t\t{\n\t\t\t\tmrr = new MemberResolveResult(target.ResolveResult, field);\n\t\t\t}\n\n\t\t\tvar expr = requireTarget\n\t\t\t\t? new MemberReferenceExpression(target, field.Name).WithRR(mrr)\n\t\t\t\t: new IdentifierExpression(field.Name).WithRR(mrr);\n\n\t\t\tif (field.Type.Kind == TypeKind.ByReference)\n\t\t\t{\n\t\t\t\texpr = new DirectionExpression(FieldDirection.Ref, expr)\n\t\t\t\t\t.WithRR(new ByReferenceResolveResult(mrr, ReferenceKind.Ref));\n\t\t\t}\n\n\t\t\treturn expr;\n\t\t}\n\n\t\tTranslatedExpression IsType(IsInst inst)\n\t\t{\n\t\t\tvar arg = Translate(inst.Argument);\n\t\t\targ = UnwrapBoxingConversion(arg);\n\t\t\treturn new IsExpression(arg.Expression, ConvertType(inst.Type.TupleUnderlyingTypeOrSelf()))\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new TypeIsResolveResult(arg.ResolveResult, inst.Type, compilation.FindType(TypeCode.Boolean)));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitIsInst(IsInst inst, TranslationContext context)\n\t\t{\n\t\t\tvar arg = Translate(inst.Argument);\n\t\t\tif (inst.Type.IsReferenceType != true)\n\t\t\t{\n\t\t\t\t// isinst with a value type results in an expression of \"boxed value type\",\n\t\t\t\t// which is not supported in C#.\n\t\t\t\t// It's also not supported for unconstrained generic types.\n\t\t\t\t// Note that several other instructions special-case isinst arguments:\n\t\t\t\t//  unbox.any T(isinst T(expr)) ==> \"expr as T\" for nullable value types and class-constrained generic types\n\t\t\t\t//  comp(isinst T(expr) != null) ==> \"expr is T\"\n\t\t\t\t//  on block level (StatementBuilder.VisitIsInst) => \"expr is T\"\n\t\t\t\tif (SemanticHelper.IsPure(inst.Argument.Flags) || (inst.Argument is Box box && SemanticHelper.IsPure(box.Argument.Flags)))\n\t\t\t\t{\n\t\t\t\t\t// We can emulate isinst using\n\t\t\t\t\t//   expr is T ? expr : null\n\t\t\t\t\t// (doubling the boxing side-effect is harmless because the \"expr is T\" part won't observe object identity,\n\t\t\t\t\t//  and we need to support this because Roslyn pattern matching sometimes generates such code.)\n\t\t\t\t\treturn new ConditionalExpression(\n\t\t\t\t\t\tnew IsExpression(arg, ConvertType(inst.Type)).WithILInstruction(inst),\n\t\t\t\t\t\targ.Expression.Clone(),\n\t\t\t\t\t\tnew NullReferenceExpression()\n\t\t\t\t\t).WithoutILInstruction().WithRR(new ResolveResult(arg.Type));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn ErrorExpression(\"isinst with value type is only supported in some contexts\");\n\t\t\t\t}\n\t\t\t}\n\t\t\targ = UnwrapBoxingConversion(arg);\n\t\t\treturn new AsExpression(arg.Expression, ConvertType(inst.Type))\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new ConversionResolveResult(inst.Type, arg.ResolveResult, Conversion.TryCast));\n\t\t}\n\n\t\tinternal static TranslatedExpression UnwrapBoxingConversion(TranslatedExpression arg)\n\t\t{\n\t\t\tif (arg.Expression is CastExpression cast\n\t\t\t\t\t&& arg.Type.IsKnownType(KnownTypeCode.Object)\n\t\t\t\t\t&& arg.ResolveResult is ConversionResolveResult crr\n\t\t\t\t\t&& crr.Conversion.IsBoxingConversion)\n\t\t\t{\n\t\t\t\t// When 'is' or 'as' is used with a value type or type parameter,\n\t\t\t\t// the C# compiler implicitly boxes the input.\n\t\t\t\targ = arg.UnwrapChild(cast.Expression);\n\t\t\t}\n\n\t\t\treturn arg;\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitNewObj(NewObj inst, TranslationContext context)\n\t\t{\n\t\t\tvar type = inst.Method.DeclaringType;\n\t\t\tif (type.IsKnownType(KnownTypeCode.SpanOfT) || type.IsKnownType(KnownTypeCode.ReadOnlySpanOfT))\n\t\t\t{\n\t\t\t\tif (inst.Arguments.Count == 2 && inst.Arguments[0] is Block b && b.Kind == BlockKind.StackAllocInitializer)\n\t\t\t\t{\n\t\t\t\t\treturn TranslateStackAllocInitializer(b, type.TypeArguments[0]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn new CallBuilder(this, typeSystem, settings).Build(inst, context.TypeHint);\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLdVirtDelegate(LdVirtDelegate inst, TranslationContext context)\n\t\t{\n\t\t\treturn new CallBuilder(this, typeSystem, settings).Build(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitNewArr(NewArr inst, TranslationContext context)\n\t\t{\n\t\t\tvar dimensions = inst.Indices.Count;\n\t\t\tvar args = inst.Indices.Select(arg => TranslateArrayIndex(arg)).ToArray();\n\t\t\tvar expr = new ArrayCreateExpression { Type = ConvertType(inst.Type) };\n\t\t\tif (expr.Type is ComposedType ct)\n\t\t\t{\n\t\t\t\t// change \"new (int[,])[10] to new int[10][,]\"\n\t\t\t\tct.ArraySpecifiers.MoveTo(expr.AdditionalArraySpecifiers);\n\t\t\t}\n\t\t\texpr.Arguments.AddRange(args.Select(arg => arg.Expression));\n\t\t\treturn expr.WithILInstruction(inst)\n\t\t\t\t.WithRR(new ArrayCreateResolveResult(new ArrayType(compilation, inst.Type, dimensions), args.Select(a => a.ResolveResult).ToList(), Empty<ResolveResult>.Array));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLocAlloc(LocAlloc inst, TranslationContext context)\n\t\t{\n\t\t\treturn TranslateLocAlloc(inst, context.TypeHint, out var elementType)\n\t\t\t\t.WithILInstruction(inst).WithRR(new ResolveResult(new PointerType(elementType)));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLocAllocSpan(LocAllocSpan inst, TranslationContext context)\n\t\t{\n\t\t\treturn TranslateLocAllocSpan(inst, context.TypeHint, out _)\n\t\t\t\t.WithILInstruction(inst).WithRR(new ResolveResult(inst.Type));\n\t\t}\n\n\t\tStackAllocExpression TranslateLocAllocSpan(LocAllocSpan inst, IType typeHint, out IType elementType)\n\t\t{\n\t\t\telementType = inst.Type.TypeArguments[0];\n\t\t\tTranslatedExpression countExpression = Translate(inst.Argument)\n\t\t\t\t.ConvertTo(compilation.FindType(KnownTypeCode.Int32), this);\n\t\t\treturn new StackAllocExpression {\n\t\t\t\tType = ConvertType(elementType),\n\t\t\t\tCountExpression = countExpression\n\t\t\t};\n\t\t}\n\n\t\tStackAllocExpression TranslateLocAlloc(LocAlloc inst, IType typeHint, out IType elementType)\n\t\t{\n\t\t\tTranslatedExpression countExpression;\n\t\t\tPointerType pointerType;\n\t\t\tif (inst.Argument.MatchBinaryNumericInstruction(BinaryNumericOperator.Mul, out var left, out var right)\n\t\t\t\t&& right.UnwrapConv(ConversionKind.SignExtend).UnwrapConv(ConversionKind.ZeroExtend).MatchSizeOf(out elementType))\n\t\t\t{\n\t\t\t\t// Determine the element type from the sizeof\n\t\t\t\tcountExpression = Translate(left.UnwrapConv(ConversionKind.ZeroExtend));\n\t\t\t\tpointerType = new PointerType(elementType);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Determine the element type from the expected pointer type in this context\n\t\t\t\tpointerType = typeHint as PointerType;\n\t\t\t\tif (pointerType != null && GetPointerArithmeticOffset(\n\t\t\t\t\t\tinst.Argument, Translate(inst.Argument),\n\t\t\t\t\t\tpointerType.ElementType, checkForOverflow: true,\n\t\t\t\t\t\tunwrapZeroExtension: true\n\t\t\t\t\t) is TranslatedExpression offset)\n\t\t\t\t{\n\t\t\t\t\tcountExpression = offset;\n\t\t\t\t\telementType = pointerType.ElementType;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\telementType = compilation.FindType(KnownTypeCode.Byte);\n\t\t\t\t\tpointerType = new PointerType(elementType);\n\t\t\t\t\tcountExpression = Translate(inst.Argument);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcountExpression = countExpression.ConvertTo(compilation.FindType(KnownTypeCode.Int32), this);\n\t\t\treturn new StackAllocExpression {\n\t\t\t\tType = ConvertType(elementType),\n\t\t\t\tCountExpression = countExpression\n\t\t\t};\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLdcI4(LdcI4 inst, TranslationContext context)\n\t\t{\n\t\t\tResolveResult rr;\n\t\t\tif (context.TypeHint.GetSign() == Sign.Unsigned)\n\t\t\t{\n\t\t\t\trr = new ConstantResolveResult(\n\t\t\t\t\tcompilation.FindType(KnownTypeCode.UInt32),\n\t\t\t\t\tunchecked((uint)inst.Value)\n\t\t\t\t);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\trr = new ConstantResolveResult(\n\t\t\t\t\tcompilation.FindType(KnownTypeCode.Int32),\n\t\t\t\t\tinst.Value\n\t\t\t\t);\n\t\t\t}\n\t\t\trr = AdjustConstantToType(rr, context.TypeHint);\n\t\t\treturn ConvertConstantValue(\n\t\t\t\trr,\n\t\t\t\tallowImplicitConversion: true\n\t\t\t).WithILInstruction(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLdcI8(LdcI8 inst, TranslationContext context)\n\t\t{\n\t\t\tResolveResult rr;\n\t\t\tif (context.TypeHint.GetSign() == Sign.Unsigned)\n\t\t\t{\n\t\t\t\trr = new ConstantResolveResult(\n\t\t\t\t\tcompilation.FindType(KnownTypeCode.UInt64),\n\t\t\t\t\tunchecked((ulong)inst.Value)\n\t\t\t\t);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\trr = new ConstantResolveResult(\n\t\t\t\t\tcompilation.FindType(KnownTypeCode.Int64),\n\t\t\t\t\tinst.Value\n\t\t\t\t);\n\t\t\t}\n\t\t\trr = AdjustConstantToType(rr, context.TypeHint);\n\t\t\treturn ConvertConstantValue(\n\t\t\t\trr,\n\t\t\t\tallowImplicitConversion: true\n\t\t\t).WithILInstruction(inst);\n\t\t}\n\n\t\tprivate bool ShouldDisplayAsHex(long value, IType type)\n\t\t{\n\t\t\tif (value >= 0 && value <= 9)\n\t\t\t\treturn false;\n\t\t\tif (value < 0 && type.GetSign() == Sign.Signed)\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLdcF4(LdcF4 inst, TranslationContext context)\n\t\t{\n\t\t\tvar expr = astBuilder.ConvertConstantValue(compilation.FindType(KnownTypeCode.Single), inst.Value);\n\t\t\treturn new TranslatedExpression(expr.WithILInstruction(inst));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLdcF8(LdcF8 inst, TranslationContext context)\n\t\t{\n\t\t\tvar expr = astBuilder.ConvertConstantValue(compilation.FindType(KnownTypeCode.Double), inst.Value);\n\t\t\treturn new TranslatedExpression(expr.WithILInstruction(inst));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLdcDecimal(LdcDecimal inst, TranslationContext context)\n\t\t{\n\t\t\tvar expr = astBuilder.ConvertConstantValue(compilation.FindType(KnownTypeCode.Decimal), inst.Value);\n\t\t\treturn new TranslatedExpression(expr.WithILInstruction(inst));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLdStr(LdStr inst, TranslationContext context)\n\t\t{\n\t\t\treturn new PrimitiveExpression(inst.Value)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new ConstantResolveResult(compilation.FindType(KnownTypeCode.String), inst.Value));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLdStrUtf8(LdStrUtf8 inst, TranslationContext context)\n\t\t{\n\t\t\tvar type = new ParameterizedType(compilation.FindType(KnownTypeCode.ReadOnlySpanOfT), new[] { compilation.FindType(KnownTypeCode.Byte) });\n\t\t\treturn new PrimitiveExpression(inst.Value, LiteralFormat.Utf8Literal)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new ConstantResolveResult(type, inst.Value));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLdNull(LdNull inst, TranslationContext context)\n\t\t{\n\t\t\treturn GetDefaultValueExpression(SpecialType.NullType).WithILInstruction(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitDefaultValue(DefaultValue inst, TranslationContext context)\n\t\t{\n\t\t\treturn GetDefaultValueExpression(inst.Type).WithILInstruction(inst);\n\t\t}\n\n\t\tinternal ExpressionWithResolveResult GetDefaultValueExpression(IType type)\n\t\t{\n\t\t\tExpression expr;\n\t\t\tIType constantType;\n\t\t\tobject constantValue;\n\t\t\tif (type.IsReferenceType == true)\n\t\t\t{\n\t\t\t\texpr = new NullReferenceExpression();\n\t\t\t\tconstantType = SpecialType.NullType;\n\t\t\t\tconstantValue = null;\n\t\t\t\treturn expr.WithRR(new ConstantResolveResult(constantType, constantValue));\n\t\t\t}\n\t\t\telse if (type.IsKnownType(KnownTypeCode.NullableOfT))\n\t\t\t{\n\t\t\t\texpr = new NullReferenceExpression();\n\t\t\t\tconstantType = SpecialType.NullType;\n\t\t\t\tconstantValue = null;\n\t\t\t\tvar crr = new ConstantResolveResult(constantType, constantValue);\n\t\t\t\treturn new CastExpression(ConvertType(type), expr.WithRR(crr))\n\t\t\t\t\t.WithRR(new ConversionResolveResult(type, crr, Conversion.NullLiteralConversion));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\texpr = new DefaultValueExpression(ConvertType(type));\n\t\t\t\tconstantType = type;\n\t\t\t\tconstantValue = CSharpResolver.GetDefaultValue(type);\n\t\t\t\treturn expr.WithRR(new ConstantResolveResult(constantType, constantValue));\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitSizeOf(SizeOf inst, TranslationContext context)\n\t\t{\n\t\t\tif (inst.Type.IsUnmanagedType(allowGenerics: settings.IntroduceUnmanagedConstraint))\n\t\t\t{\n\t\t\t\treturn new SizeOfExpression(ConvertType(inst.Type))\n\t\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t\t.WithRR(new SizeOfResolveResult(compilation.FindType(KnownTypeCode.Int32), inst.Type, null));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn CallUnsafeIntrinsic(\n\t\t\t\t\tname: \"SizeOf\",\n\t\t\t\t\targuments: Array.Empty<Expression>(),\n\t\t\t\t\treturnType: compilation.FindType(KnownTypeCode.Int32),\n\t\t\t\t\tinst: inst,\n\t\t\t\t\ttypeArguments: new[] { inst.Type }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLdTypeToken(LdTypeToken inst, TranslationContext context)\n\t\t{\n\t\t\tvar typeofExpr = new TypeOfExpression(ConvertType(inst.Type))\n\t\t\t\t.WithRR(new TypeOfResolveResult(compilation.FindType(KnownTypeCode.Type), inst.Type));\n\t\t\treturn new MemberReferenceExpression(typeofExpr, \"TypeHandle\")\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new TypeOfResolveResult(compilation.FindType(new TopLevelTypeName(\"System\", \"RuntimeTypeHandle\")), inst.Type));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitBitNot(BitNot inst, TranslationContext context)\n\t\t{\n\t\t\tvar argument = Translate(inst.Argument);\n\t\t\tvar argUType = NullableType.GetUnderlyingType(argument.Type);\n\n\t\t\tif (argUType.GetStackType().GetSize() < inst.UnderlyingResultType.GetSize()\n\t\t\t\t|| argUType.Kind == TypeKind.Enum && argUType.IsSmallIntegerType()\n\t\t\t\t|| (argUType.GetStackType() == StackType.I && !argUType.IsCSharpNativeIntegerType())\n\t\t\t\t|| argUType.IsKnownType(KnownTypeCode.Boolean)\n\t\t\t\t|| argUType.IsKnownType(KnownTypeCode.Char))\n\t\t\t{\n\t\t\t\t// Argument is undersized (even after implicit integral promotion to I4)\n\t\t\t\t// -> we need to perform sign/zero-extension before the BitNot.\n\t\t\t\t// Same if the argument is an enum based on a small integer type\n\t\t\t\t// (those don't undergo numeric promotion in C# the way non-enum small integer types do).\n\t\t\t\t// Same if the type is one that does not support ~ (IntPtr, bool and char).\n\t\t\t\tSign sign = context.TypeHint.GetSign();\n\t\t\t\tif (sign == Sign.None)\n\t\t\t\t{\n\t\t\t\t\tsign = argUType.GetSign();\n\t\t\t\t}\n\t\t\t\tIType targetType = FindArithmeticType(inst.UnderlyingResultType, sign);\n\t\t\t\tif (inst.IsLifted)\n\t\t\t\t{\n\t\t\t\t\ttargetType = NullableType.Create(compilation, targetType);\n\t\t\t\t}\n\t\t\t\targument = argument.ConvertTo(targetType, this);\n\t\t\t}\n\n\t\t\treturn new UnaryOperatorExpression(UnaryOperatorType.BitNot, argument)\n\t\t\t\t.WithRR(resolver.ResolveUnaryOperator(UnaryOperatorType.BitNot, argument.ResolveResult))\n\t\t\t\t.WithILInstruction(inst);\n\t\t}\n\n\t\tinternal ExpressionWithResolveResult LogicNot(TranslatedExpression expr)\n\t\t{\n\t\t\t// \"!expr\" implicitly converts to bool so we can remove the cast;\n\t\t\t// but only if doing so wouldn't cause us to call a user-defined \"operator !\"\n\t\t\texpr = expr.UnwrapImplicitBoolConversion(type => !type.GetMethods(m => m.IsOperator && m.Name == \"op_LogicalNot\").Any());\n\t\t\treturn new UnaryOperatorExpression(UnaryOperatorType.Not, expr.Expression)\n\t\t\t\t.WithRR(new OperatorResolveResult(compilation.FindType(KnownTypeCode.Boolean), ExpressionType.Not, expr.ResolveResult));\n\t\t}\n\n\t\treadonly HashSet<ILVariable> loadedVariablesSet = new HashSet<ILVariable>();\n\n\t\tprotected internal override TranslatedExpression VisitLdLoc(LdLoc inst, TranslationContext context)\n\t\t{\n\t\t\tif (inst.Variable.Kind == VariableKind.StackSlot && inst.Variable.IsSingleDefinition)\n\t\t\t{\n\t\t\t\tloadedVariablesSet.Add(inst.Variable);\n\t\t\t}\n\t\t\treturn ConvertVariable(inst.Variable).WithILInstruction(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLdLoca(LdLoca inst, TranslationContext context)\n\t\t{\n\t\t\tvar expr = ConvertVariable(inst.Variable).WithILInstruction(inst);\n\t\t\t// Note that we put the instruction on the IdentifierExpression instead of the DirectionExpression,\n\t\t\t// because the DirectionExpression might get removed by dereferencing instructions such as LdObj\n\t\t\treturn new DirectionExpression(FieldDirection.Ref, expr.Expression)\n\t\t\t\t.WithoutILInstruction()\n\t\t\t\t.WithRR(new ByReferenceResolveResult(expr.ResolveResult, ReferenceKind.Ref));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitStLoc(StLoc inst, TranslationContext context)\n\t\t{\n\t\t\tvar translatedValue = Translate(inst.Value, typeHint: inst.Variable.Type);\n\t\t\tif (inst.Variable.Kind == VariableKind.StackSlot && !loadedVariablesSet.Contains(inst.Variable))\n\t\t\t{\n\t\t\t\t// Stack slots in the ILAst have inaccurate types (e.g. System.Object for StackType.O)\n\t\t\t\t// so we should replace them with more accurate types where possible:\n\t\t\t\tif (CanUseTypeForStackSlot(inst.Variable, translatedValue.Type)\n\t\t\t\t\t\t&& inst.Variable.StackType == translatedValue.Type.GetStackType()\n\t\t\t\t\t\t&& translatedValue.Type.Kind != TypeKind.Null)\n\t\t\t\t{\n\t\t\t\t\tinst.Variable.Type = translatedValue.Type;\n\t\t\t\t}\n\t\t\t\telse if (inst.Value.MatchDefaultValue(out var type) && IsOtherValueType(type))\n\t\t\t\t{\n\t\t\t\t\tinst.Variable.Type = type;\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar lhs = ConvertVariable(inst.Variable).WithoutILInstruction();\n\t\t\tif (lhs.Expression is DirectionExpression dirExpr && lhs.ResolveResult is ByReferenceResolveResult lhsRefRR)\n\t\t\t{\n\t\t\t\t// ref (re-)assignment, emit \"ref (a = ref b)\".\n\t\t\t\tlhs = lhs.UnwrapChild(dirExpr.Expression);\n\t\t\t\ttranslatedValue = translatedValue.ConvertTo(lhsRefRR.Type, this, allowImplicitConversion: true);\n\t\t\t\tvar assign = new AssignmentExpression(lhs.Expression, translatedValue.Expression)\n\t\t\t\t\t.WithRR(new OperatorResolveResult(lhs.Type, ExpressionType.Assign, lhsRefRR, translatedValue.ResolveResult));\n\t\t\t\treturn new DirectionExpression(FieldDirection.Ref, assign)\n\t\t\t\t\t.WithoutILInstruction().WithRR(lhsRefRR);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn Assignment(lhs, translatedValue).WithILInstruction(inst);\n\t\t\t}\n\n\t\t\tbool CanUseTypeForStackSlot(ILVariable v, IType type)\n\t\t\t{\n\t\t\t\treturn v.IsSingleDefinition\n\t\t\t\t\t|| IsOtherValueType(type)\n\t\t\t\t\t|| v.StackType == StackType.Ref\n\t\t\t\t\t|| AllStoresUseConsistentType(v.StoreInstructions, type);\n\t\t\t}\n\n\t\t\tbool IsOtherValueType(IType type)\n\t\t\t{\n\t\t\t\treturn type.IsReferenceType == false && type.GetStackType() == StackType.O;\n\t\t\t}\n\n\t\t\tbool AllStoresUseConsistentType(IReadOnlyList<IStoreInstruction> storeInstructions, IType expectedType)\n\t\t\t{\n\t\t\t\texpectedType = expectedType.AcceptVisitor(NormalizeTypeVisitor.TypeErasure);\n\t\t\t\tforeach (var store in storeInstructions)\n\t\t\t\t{\n\t\t\t\t\tif (!(store is StLoc stloc))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tIType type = stloc.Value.InferType(compilation).AcceptVisitor(NormalizeTypeVisitor.TypeErasure);\n\t\t\t\t\tif (!type.Equals(expectedType))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitComp(Comp inst, TranslationContext context)\n\t\t{\n\t\t\tif (inst.LiftingKind == ComparisonLiftingKind.ThreeValuedLogic)\n\t\t\t{\n\t\t\t\tif (inst.Kind == ComparisonKind.Equality && inst.Right.MatchLdcI4(0))\n\t\t\t\t{\n\t\t\t\t\t// lifted logic.not\n\t\t\t\t\tvar targetType = NullableType.Create(compilation, compilation.FindType(KnownTypeCode.Boolean));\n\t\t\t\t\tvar arg = Translate(inst.Left, targetType).ConvertTo(targetType, this);\n\t\t\t\t\treturn new UnaryOperatorExpression(UnaryOperatorType.Not, arg.Expression)\n\t\t\t\t\t\t.WithRR(new OperatorResolveResult(targetType, ExpressionType.Not, arg.ResolveResult))\n\t\t\t\t\t\t.WithILInstruction(inst);\n\t\t\t\t}\n\t\t\t\treturn ErrorExpression(\"Nullable comparisons with three-valued-logic not supported in C#\");\n\t\t\t}\n\t\t\tif (inst.InputType == StackType.Ref)\n\t\t\t{\n\t\t\t\t// Reference comparison using Unsafe intrinsics\n\t\t\t\tDebug.Assert(!inst.IsLifted);\n\t\t\t\t(string methodName, bool negate) = inst.Kind switch {\n\t\t\t\t\tComparisonKind.Equality => (\"AreSame\", false),\n\t\t\t\t\tComparisonKind.Inequality => (\"AreSame\", true),\n\t\t\t\t\tComparisonKind.LessThan => (\"IsAddressLessThan\", false),\n\t\t\t\t\tComparisonKind.LessThanOrEqual => (\"IsAddressGreaterThan\", true),\n\t\t\t\t\tComparisonKind.GreaterThan => (\"IsAddressGreaterThan\", false),\n\t\t\t\t\tComparisonKind.GreaterThanOrEqual => (\"IsAddressLessThan\", true),\n\t\t\t\t\t_ => throw new InvalidOperationException(\"Invalid ComparisonKind\")\n\t\t\t\t};\n\t\t\t\tvar left = Translate(inst.Left);\n\t\t\t\tvar right = Translate(inst.Right);\n\t\t\t\tif (left.Type.Kind != TypeKind.ByReference || !NormalizeTypeVisitor.TypeErasure.EquivalentTypes(left.Type, right.Type))\n\t\t\t\t{\n\t\t\t\t\tIType commonRefType = new ByReferenceType(compilation.FindType(KnownTypeCode.Byte));\n\t\t\t\t\tleft = left.ConvertTo(commonRefType, this);\n\t\t\t\t\tright = right.ConvertTo(commonRefType, this);\n\t\t\t\t}\n\t\t\t\tIType boolType = compilation.FindType(KnownTypeCode.Boolean);\n\t\t\t\tTranslatedExpression expr = CallUnsafeIntrinsic(\n\t\t\t\t\tname: methodName,\n\t\t\t\t\targuments: new Expression[] { left, right },\n\t\t\t\t\treturnType: boolType,\n\t\t\t\t\tinst: inst\n\t\t\t\t);\n\t\t\t\tif (negate)\n\t\t\t\t{\n\t\t\t\t\texpr = new UnaryOperatorExpression(UnaryOperatorType.Not, expr)\n\t\t\t\t\t\t.WithoutILInstruction().WithRR(new ResolveResult(boolType));\n\t\t\t\t}\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\tif (inst.Kind.IsEqualityOrInequality())\n\t\t\t{\n\t\t\t\tvar result = TranslateCeq(inst, out bool negateOutput);\n\t\t\t\tif (negateOutput)\n\t\t\t\t\treturn LogicNot(result).WithILInstruction(inst);\n\t\t\t\telse\n\t\t\t\t\treturn result;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn TranslateComp(inst);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Translates the equality comparison between left and right.\n\t\t/// </summary>\n\t\tTranslatedExpression TranslateCeq(Comp inst, out bool negateOutput)\n\t\t{\n\t\t\tDebug.Assert(inst.Kind.IsEqualityOrInequality());\n\t\t\t// Translate '(e as T) == null' to '!(e is T)'.\n\t\t\t// This is necessary for correctness when T is a value type.\n\t\t\tif (inst.Left.OpCode == OpCode.IsInst && inst.Right.OpCode == OpCode.LdNull)\n\t\t\t{\n\t\t\t\tnegateOutput = inst.Kind == ComparisonKind.Equality;\n\t\t\t\treturn IsType((IsInst)inst.Left);\n\t\t\t}\n\t\t\telse if (inst.Right.OpCode == OpCode.IsInst && inst.Left.OpCode == OpCode.LdNull)\n\t\t\t{\n\t\t\t\tnegateOutput = inst.Kind == ComparisonKind.Equality;\n\t\t\t\treturn IsType((IsInst)inst.Right);\n\t\t\t}\n\n\t\t\tvar left = Translate(inst.Left);\n\t\t\tvar right = Translate(inst.Right);\n\n\t\t\t// Remove redundant bool comparisons\n\t\t\tif (left.Type.IsKnownType(KnownTypeCode.Boolean))\n\t\t\t{\n\t\t\t\tif (inst.Right.MatchLdcI4(0))\n\t\t\t\t{\n\t\t\t\t\t// 'b == 0' => '!b'\n\t\t\t\t\t// 'b != 0' => 'b'\n\t\t\t\t\tnegateOutput = inst.Kind == ComparisonKind.Equality;\n\t\t\t\t\treturn left;\n\t\t\t\t}\n\t\t\t\tif (inst.Right.MatchLdcI4(1))\n\t\t\t\t{\n\t\t\t\t\t// 'b == 1' => 'b'\n\t\t\t\t\t// 'b != 1' => '!b'\n\t\t\t\t\tnegateOutput = inst.Kind == ComparisonKind.Inequality;\n\t\t\t\t\treturn left;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (right.Type.IsKnownType(KnownTypeCode.Boolean))\n\t\t\t{\n\t\t\t\tif (inst.Left.MatchLdcI4(0))\n\t\t\t\t{\n\t\t\t\t\t// '0 == b' => '!b'\n\t\t\t\t\t// '0 != b' => 'b'\n\t\t\t\t\tnegateOutput = inst.Kind == ComparisonKind.Equality;\n\t\t\t\t\treturn right;\n\t\t\t\t}\n\t\t\t\tif (inst.Left.MatchLdcI4(1))\n\t\t\t\t{\n\t\t\t\t\t// '1 == b' => 'b'\n\t\t\t\t\t// '1 != b' => '!b'\n\t\t\t\t\tnegateOutput = inst.Kind == ComparisonKind.Inequality;\n\t\t\t\t\treturn right;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Handle comparisons between unsafe pointers and null:\n\t\t\tif (left.Type.Kind == TypeKind.Pointer && inst.Right.MatchLdcI(0))\n\t\t\t{\n\t\t\t\tnegateOutput = false;\n\t\t\t\tright = new NullReferenceExpression().WithRR(new ConstantResolveResult(SpecialType.NullType, null))\n\t\t\t\t\t.WithILInstruction(inst.Right);\n\t\t\t\treturn CreateBuiltinBinaryOperator(left, inst.Kind.ToBinaryOperatorType(), right)\n\t\t\t\t\t.WithILInstruction(inst);\n\t\t\t}\n\t\t\telse if (right.Type.Kind == TypeKind.Pointer && inst.Left.MatchLdcI(0))\n\t\t\t{\n\t\t\t\tnegateOutput = false;\n\t\t\t\tleft = new NullReferenceExpression().WithRR(new ConstantResolveResult(SpecialType.NullType, null))\n\t\t\t\t\t.WithILInstruction(inst.Left);\n\t\t\t\treturn CreateBuiltinBinaryOperator(left, inst.Kind.ToBinaryOperatorType(), right)\n\t\t\t\t\t.WithILInstruction(inst);\n\t\t\t}\n\n\t\t\t// Special case comparisons with enum and char literals\n\t\t\tleft = TryUniteEqualityOperandType(left, right);\n\t\t\tright = TryUniteEqualityOperandType(right, left);\n\n\t\t\tif (IsSpecialCasedReferenceComparisonWithNull(left, right))\n\t\t\t{\n\t\t\t\t// When comparing a string/delegate with null, the C# compiler generates a reference comparison.\n\t\t\t\tnegateOutput = false;\n\t\t\t\treturn CreateBuiltinBinaryOperator(left, inst.Kind.ToBinaryOperatorType(), right)\n\t\t\t\t\t.WithILInstruction(inst);\n\t\t\t}\n\n\t\t\tOperatorResolveResult rr = resolver.ResolveBinaryOperator(inst.Kind.ToBinaryOperatorType(), left.ResolveResult, right.ResolveResult) as OperatorResolveResult;\n\t\t\tif (rr == null || rr.IsError || rr.UserDefinedOperatorMethod != null\n\t\t\t\t|| NullableType.GetUnderlyingType(rr.Operands[0].Type).GetStackType() != inst.InputType\n\t\t\t\t|| !rr.Type.IsKnownType(KnownTypeCode.Boolean))\n\t\t\t{\n\t\t\t\tIType targetType;\n\t\t\t\tif (inst.InputType == StackType.O)\n\t\t\t\t{\n\t\t\t\t\ttargetType = compilation.FindType(KnownTypeCode.Object);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar leftUType = NullableType.GetUnderlyingType(left.Type);\n\t\t\t\t\tvar rightUType = NullableType.GetUnderlyingType(right.Type);\n\t\t\t\t\tif (leftUType.GetStackType() == inst.InputType && !leftUType.IsSmallIntegerType())\n\t\t\t\t\t{\n\t\t\t\t\t\ttargetType = leftUType;\n\t\t\t\t\t}\n\t\t\t\t\telse if (rightUType.GetStackType() == inst.InputType && !rightUType.IsSmallIntegerType())\n\t\t\t\t\t{\n\t\t\t\t\t\ttargetType = rightUType;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\ttargetType = FindType(inst.InputType, leftUType.GetSign());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (inst.IsLifted)\n\t\t\t\t{\n\t\t\t\t\ttargetType = NullableType.Create(compilation, targetType);\n\t\t\t\t}\n\t\t\t\tif (targetType.Equals(left.Type))\n\t\t\t\t{\n\t\t\t\t\tright = right.ConvertTo(targetType, this);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tleft = left.ConvertTo(targetType, this);\n\t\t\t\t}\n\t\t\t\trr = resolver.ResolveBinaryOperator(inst.Kind.ToBinaryOperatorType(),\n\t\t\t\t\tleft.ResolveResult, right.ResolveResult) as OperatorResolveResult;\n\t\t\t\tif (rr == null || rr.IsError || rr.UserDefinedOperatorMethod != null\n\t\t\t\t\t|| NullableType.GetUnderlyingType(rr.Operands[0].Type).GetStackType() != inst.InputType\n\t\t\t\t\t|| !rr.Type.IsKnownType(KnownTypeCode.Boolean))\n\t\t\t\t{\n\t\t\t\t\t// If converting one input wasn't sufficient, convert both:\n\t\t\t\t\tleft = left.ConvertTo(targetType, this);\n\t\t\t\t\tright = right.ConvertTo(targetType, this);\n\t\t\t\t\trr = new OperatorResolveResult(\n\t\t\t\t\t\tcompilation.FindType(KnownTypeCode.Boolean),\n\t\t\t\t\t\tBinaryOperatorExpression.GetLinqNodeType(inst.Kind.ToBinaryOperatorType(), false),\n\t\t\t\t\t\tleft.ResolveResult, right.ResolveResult);\n\t\t\t\t}\n\t\t\t}\n\t\t\tnegateOutput = false;\n\t\t\treturn new BinaryOperatorExpression(left.Expression, inst.Kind.ToBinaryOperatorType(), right.Expression)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(rr);\n\t\t}\n\n\t\tTranslatedExpression TryUniteEqualityOperandType(TranslatedExpression left, TranslatedExpression right)\n\t\t{\n\t\t\t// Special case for enum flag check \"(enum & EnumType.SomeValue) == 0\"\n\t\t\t// so that the const 0 value is printed as 0 integer and not as enum type, e.g. EnumType.None\n\t\t\tif (left.ResolveResult.IsCompileTimeConstant &&\n\t\t\t\tleft.ResolveResult.Type.IsCSharpPrimitiveIntegerType() &&\n\t\t\t\t(left.ResolveResult.ConstantValue as int?) == 0 &&\n\t\t\t\tNullableType.GetUnderlyingType(right.Type).Kind == TypeKind.Enum &&\n\t\t\t\tright.Expression is BinaryOperatorExpression binaryExpr &&\n\t\t\t\tbinaryExpr.Operator == BinaryOperatorType.BitwiseAnd)\n\t\t\t{\n\t\t\t\treturn AdjustConstantExpressionToType(left, compilation.FindType(KnownTypeCode.Int32));\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn AdjustConstantExpressionToType(left, right.Type);\n\t\t}\n\n\t\tbool IsSpecialCasedReferenceComparisonWithNull(TranslatedExpression lhs, TranslatedExpression rhs)\n\t\t{\n\t\t\tif (lhs.Type.Kind == TypeKind.Null)\n\t\t\t\tExtensionMethods.Swap(ref lhs, ref rhs);\n\t\t\treturn rhs.Type.Kind == TypeKind.Null\n\t\t\t\t&& (lhs.Type.Kind == TypeKind.Delegate || lhs.Type.IsKnownType(KnownTypeCode.String))\n\t\t\t\t&& lhs.Type.GetDefinition() != decompilationContext.CurrentTypeDefinition;\n\t\t}\n\n\t\tExpressionWithResolveResult CreateBuiltinBinaryOperator(\n\t\t\tTranslatedExpression left, BinaryOperatorType type, TranslatedExpression right,\n\t\t\tbool checkForOverflow = false)\n\t\t{\n\t\t\treturn new BinaryOperatorExpression(left.Expression, type, right.Expression)\n\t\t\t.WithRR(new OperatorResolveResult(\n\t\t\t\tcompilation.FindType(KnownTypeCode.Boolean),\n\t\t\t\tBinaryOperatorExpression.GetLinqNodeType(type, checkForOverflow),\n\t\t\t\tleft.ResolveResult, right.ResolveResult));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Handle Comp instruction, operators other than equality/inequality.\n\t\t/// </summary>\n\t\tTranslatedExpression TranslateComp(Comp inst)\n\t\t{\n\t\t\tvar op = inst.Kind.ToBinaryOperatorType();\n\t\t\tvar left = Translate(inst.Left);\n\t\t\tvar right = Translate(inst.Right);\n\n\t\t\tif (left.Type.Kind == TypeKind.Pointer && right.Type.Kind == TypeKind.Pointer)\n\t\t\t{\n\t\t\t\treturn CreateBuiltinBinaryOperator(left, op, right)\n\t\t\t\t\t.WithILInstruction(inst);\n\t\t\t}\n\n\t\t\tleft = PrepareArithmeticArgument(left, inst.InputType, inst.Sign, inst.IsLifted);\n\t\t\tright = PrepareArithmeticArgument(right, inst.InputType, inst.Sign, inst.IsLifted);\n\n\t\t\t// Special case comparisons with enum and char literals\n\t\t\tleft = AdjustConstantExpressionToType(left, right.Type);\n\t\t\tright = AdjustConstantExpressionToType(right, left.Type);\n\n\t\t\t// attempt comparison without any additional casts\n\t\t\tvar rr = resolver.ResolveBinaryOperator(inst.Kind.ToBinaryOperatorType(), left.ResolveResult, right.ResolveResult)\n\t\t\t\tas OperatorResolveResult;\n\t\t\tif (rr != null && !rr.IsError)\n\t\t\t{\n\t\t\t\tIType compUType = NullableType.GetUnderlyingType(rr.Operands[0].Type);\n\t\t\t\tif (compUType.GetSign() == inst.Sign && compUType.GetStackType() == inst.InputType)\n\t\t\t\t{\n\t\t\t\t\treturn new BinaryOperatorExpression(left.Expression, op, right.Expression)\n\t\t\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t\t\t.WithRR(rr);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (inst.InputType.IsIntegerType())\n\t\t\t{\n\t\t\t\t// Ensure the inputs have the correct sign:\n\t\t\t\tIType inputType = FindArithmeticType(inst.InputType, inst.Sign);\n\t\t\t\tif (inst.IsLifted)\n\t\t\t\t{\n\t\t\t\t\tinputType = NullableType.Create(compilation, inputType);\n\t\t\t\t}\n\t\t\t\tleft = left.ConvertTo(inputType, this);\n\t\t\t\tright = right.ConvertTo(inputType, this);\n\t\t\t}\n\t\t\telse if (inst.InputType == StackType.O)\n\t\t\t{\n\t\t\t\t// Unsafe.As<object, UIntPtr>(ref left) op Unsafe.As<object, UIntPtr>(ref right)\n\t\t\t\t// TTo Unsafe.As<TFrom, TTo>(ref TFrom source)\n\t\t\t\tvar integerType = compilation.FindType(inst.Sign == Sign.Signed ? KnownTypeCode.IntPtr : KnownTypeCode.UIntPtr);\n\t\t\t\tleft = WrapInUnsafeAs(left, inst.Left);\n\t\t\t\tright = WrapInUnsafeAs(right, inst.Right);\n\n\t\t\t\tTranslatedExpression WrapInUnsafeAs(TranslatedExpression expr, ILInstruction inst)\n\t\t\t\t{\n\t\t\t\t\tvar type = expr.Type;\n\t\t\t\t\texpr = WrapInRef(expr, new ByReferenceType(type));\n\t\t\t\t\treturn CallUnsafeIntrinsic(\"As\", [expr], integerType, typeArguments: [type, integerType]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn new BinaryOperatorExpression(left.Expression, op, right.Expression)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new OperatorResolveResult(compilation.FindType(TypeCode.Boolean),\n\t\t\t\t\t\t\t\t\t\t\t\t  BinaryOperatorExpression.GetLinqNodeType(op, false),\n\t\t\t\t\t\t\t\t\t\t\t\t  left.ResolveResult, right.ResolveResult));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitThreeValuedBoolAnd(ThreeValuedBoolAnd inst, TranslationContext context)\n\t\t{\n\t\t\treturn HandleThreeValuedLogic(inst, BinaryOperatorType.BitwiseAnd, ExpressionType.And);\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitThreeValuedBoolOr(ThreeValuedBoolOr inst, TranslationContext context)\n\t\t{\n\t\t\treturn HandleThreeValuedLogic(inst, BinaryOperatorType.BitwiseOr, ExpressionType.Or);\n\t\t}\n\n\t\tTranslatedExpression HandleThreeValuedLogic(BinaryInstruction inst, BinaryOperatorType op, ExpressionType eop)\n\t\t{\n\t\t\tvar left = Translate(inst.Left);\n\t\t\tvar right = Translate(inst.Right);\n\t\t\tIType boolType = compilation.FindType(KnownTypeCode.Boolean);\n\t\t\tIType nullableBoolType = NullableType.Create(compilation, boolType);\n\t\t\tif (NullableType.IsNullable(left.Type))\n\t\t\t{\n\t\t\t\tleft = left.ConvertTo(nullableBoolType, this);\n\t\t\t\tif (NullableType.IsNullable(right.Type))\n\t\t\t\t{\n\t\t\t\t\tright = right.ConvertTo(nullableBoolType, this);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tright = right.ConvertTo(boolType, this);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tleft = left.ConvertTo(boolType, this);\n\t\t\t\tright = right.ConvertTo(nullableBoolType, this);\n\t\t\t}\n\t\t\treturn new BinaryOperatorExpression(left.Expression, op, right.Expression)\n\t\t\t\t.WithRR(new OperatorResolveResult(nullableBoolType, eop, null, true, new[] { left.ResolveResult, right.ResolveResult }))\n\t\t\t\t.WithILInstruction(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitThrow(Throw inst, TranslationContext context)\n\t\t{\n\t\t\treturn new ThrowExpression(Translate(inst.Argument))\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new ThrowResolveResult());\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitUserDefinedLogicOperator(UserDefinedLogicOperator inst, TranslationContext context)\n\t\t{\n\t\t\tvar left = Translate(inst.Left, inst.Method.Parameters[0].Type).ConvertTo(inst.Method.Parameters[0].Type, this);\n\t\t\tvar right = Translate(inst.Right, inst.Method.Parameters[1].Type).ConvertTo(inst.Method.Parameters[1].Type, this);\n\t\t\tBinaryOperatorType op;\n\t\t\tif (inst.Method.Name == \"op_BitwiseAnd\")\n\t\t\t{\n\t\t\t\top = BinaryOperatorType.ConditionalAnd;\n\t\t\t}\n\t\t\telse if (inst.Method.Name == \"op_BitwiseOr\")\n\t\t\t{\n\t\t\t\top = BinaryOperatorType.ConditionalOr;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthrow new InvalidOperationException(\"Invalid method name\");\n\t\t\t}\n\t\t\treturn new BinaryOperatorExpression(left.Expression, op, right.Expression)\n\t\t\t\t.WithRR(new InvocationResolveResult(null, inst.Method, new ResolveResult[] { left.ResolveResult, right.ResolveResult }))\n\t\t\t\t.WithILInstruction(inst);\n\t\t}\n\n\t\tExpressionWithResolveResult Assignment(TranslatedExpression left, TranslatedExpression right)\n\t\t{\n\t\t\tright = right.ConvertTo(left.Type, this, allowImplicitConversion: true);\n\t\t\treturn new AssignmentExpression(left.Expression, right.Expression)\n\t\t\t\t.WithRR(new OperatorResolveResult(left.Type, ExpressionType.Assign, left.ResolveResult, right.ResolveResult));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitBinaryNumericInstruction(BinaryNumericInstruction inst, TranslationContext context)\n\t\t{\n\t\t\tswitch (inst.Operator)\n\t\t\t{\n\t\t\t\tcase BinaryNumericOperator.Add:\n\t\t\t\t\treturn HandleBinaryNumeric(inst, BinaryOperatorType.Add, context);\n\t\t\t\tcase BinaryNumericOperator.Sub:\n\t\t\t\t\treturn HandleBinaryNumeric(inst, BinaryOperatorType.Subtract, context);\n\t\t\t\tcase BinaryNumericOperator.Mul:\n\t\t\t\t\treturn HandleBinaryNumeric(inst, BinaryOperatorType.Multiply, context);\n\t\t\t\tcase BinaryNumericOperator.Div:\n\t\t\t\t\treturn HandlePointerSubtraction(inst)\n\t\t\t\t\t\t?? HandleBinaryNumeric(inst, BinaryOperatorType.Divide, context);\n\t\t\t\tcase BinaryNumericOperator.Rem:\n\t\t\t\t\treturn HandleBinaryNumeric(inst, BinaryOperatorType.Modulus, context);\n\t\t\t\tcase BinaryNumericOperator.BitAnd:\n\t\t\t\t\treturn HandleBinaryNumeric(inst, BinaryOperatorType.BitwiseAnd, context);\n\t\t\t\tcase BinaryNumericOperator.BitOr:\n\t\t\t\t\treturn HandleBinaryNumeric(inst, BinaryOperatorType.BitwiseOr, context);\n\t\t\t\tcase BinaryNumericOperator.BitXor:\n\t\t\t\t\treturn HandleBinaryNumeric(inst, BinaryOperatorType.ExclusiveOr, context);\n\t\t\t\tcase BinaryNumericOperator.ShiftLeft:\n\t\t\t\t\treturn HandleShift(inst, BinaryOperatorType.ShiftLeft, context);\n\t\t\t\tcase BinaryNumericOperator.ShiftRight:\n\t\t\t\t\treturn HandleShift(inst, BinaryOperatorType.ShiftRight, context);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Translates pointer arithmetic:\n\t\t///   ptr + int\n\t\t///   int + ptr\n\t\t///   ptr - int\n\t\t/// Returns null if 'inst' is not performing pointer arithmetic.\n\t\t/// 'ptr - ptr' is not handled here, but in HandlePointerSubtraction()!\n\t\t/// </summary>\n\t\tTranslatedExpression? HandlePointerArithmetic(BinaryNumericInstruction inst, TranslatedExpression left, TranslatedExpression right, TranslationContext context)\n\t\t{\n\t\t\tif (!(inst.Operator == BinaryNumericOperator.Add || inst.Operator == BinaryNumericOperator.Sub))\n\t\t\t\treturn null;\n\t\t\tif (inst.CheckForOverflow || inst.IsLifted)\n\t\t\t\treturn null;\n\t\t\tif (!(inst.LeftInputType == StackType.I && inst.RightInputType == StackType.I))\n\t\t\t\treturn null;\n\t\t\tPointerType pointerType;\n\t\t\tILInstruction byteOffsetInst;\n\t\t\tTranslatedExpression byteOffsetExpr;\n\t\t\tif (left.Type.Kind == TypeKind.Pointer)\n\t\t\t{\n\t\t\t\tbyteOffsetInst = inst.Right;\n\t\t\t\tbyteOffsetExpr = right;\n\t\t\t\tpointerType = (PointerType)left.Type;\n\t\t\t}\n\t\t\telse if (right.Type.Kind == TypeKind.Pointer)\n\t\t\t{\n\t\t\t\tif (inst.Operator != BinaryNumericOperator.Add)\n\t\t\t\t\treturn null;\n\t\t\t\tbyteOffsetInst = inst.Left;\n\t\t\t\tbyteOffsetExpr = left;\n\t\t\t\tpointerType = (PointerType)right.Type;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tTranslatedExpression? offsetExpressionFromTypeHint = null;\n\t\t\tif (context.TypeHint.Kind == TypeKind.Pointer)\n\t\t\t{\n\t\t\t\t// We use the type hint if one of the following is true:\n\t\t\t\t// * The current element type is a non-primitive struct.\n\t\t\t\t// * The current element type has a different size than the type hint element type.\n\t\t\t\t// This prevents the type hint from overriding in undesirable situations (eg changing char* to short*).\n\n\t\t\t\tvar typeHint = (PointerType)context.TypeHint;\n\t\t\t\tint elementTypeSize = pointerType.ElementType.GetSize();\n\t\t\t\tif (elementTypeSize == 0 || typeHint.ElementType.GetSize() != elementTypeSize)\n\t\t\t\t{\n\t\t\t\t\toffsetExpressionFromTypeHint = GetPointerArithmeticOffset(byteOffsetInst, byteOffsetExpr, typeHint.ElementType, inst.CheckForOverflow);\n\t\t\t\t\tif (offsetExpressionFromTypeHint != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tpointerType = typeHint;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tTranslatedExpression offsetExpr = offsetExpressionFromTypeHint\n\t\t\t\t?? GetPointerArithmeticOffset(byteOffsetInst, byteOffsetExpr, pointerType.ElementType, inst.CheckForOverflow)\n\t\t\t\t?? FallBackToBytePointer();\n\n\t\t\tif (left.Type.Kind == TypeKind.Pointer)\n\t\t\t{\n\t\t\t\tDebug.Assert(inst.Operator == BinaryNumericOperator.Add || inst.Operator == BinaryNumericOperator.Sub);\n\t\t\t\tleft = left.ConvertTo(pointerType, this);\n\t\t\t\tright = offsetExpr;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDebug.Assert(inst.Operator == BinaryNumericOperator.Add);\n\t\t\t\tDebug.Assert(right.Type.Kind == TypeKind.Pointer);\n\t\t\t\tleft = offsetExpr;\n\t\t\t\tright = right.ConvertTo(pointerType, this);\n\t\t\t}\n\t\t\tvar operatorType = inst.Operator == BinaryNumericOperator.Add ? BinaryOperatorType.Add : BinaryOperatorType.Subtract;\n\t\t\treturn new BinaryOperatorExpression(left, operatorType, right)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new OperatorResolveResult(\n\t\t\t\t\tpointerType, BinaryOperatorExpression.GetLinqNodeType(operatorType, inst.CheckForOverflow),\n\t\t\t\t\tleft.ResolveResult, right.ResolveResult));\n\n\t\t\tTranslatedExpression FallBackToBytePointer()\n\t\t\t{\n\t\t\t\tpointerType = new PointerType(compilation.FindType(KnownTypeCode.Byte));\n\t\t\t\treturn EnsureIntegerType(byteOffsetExpr);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Translates pointer arithmetic with managed pointers:\n\t\t///   ref + int\n\t\t///   int + ref\n\t\t///   ref - int\n\t\t///   ref - ref\n\t\t/// </summary>\n\t\tTranslatedExpression? HandleManagedPointerArithmetic(BinaryNumericInstruction inst, TranslatedExpression left, TranslatedExpression right)\n\t\t{\n\t\t\tif (!(inst.Operator == BinaryNumericOperator.Add || inst.Operator == BinaryNumericOperator.Sub))\n\t\t\t\treturn null;\n\t\t\tif (inst.CheckForOverflow || inst.IsLifted)\n\t\t\t\treturn null;\n\t\t\tif (inst.Operator == BinaryNumericOperator.Sub && inst.LeftInputType == StackType.Ref && inst.RightInputType == StackType.Ref)\n\t\t\t{\n\t\t\t\t// ref - ref => i\n\t\t\t\treturn CallUnsafeIntrinsic(\"ByteOffset\", new[] { \n\t\t\t\t\t// ByteOffset() expects the parameters the wrong way around, so order using named arguments\n\t\t\t\t\tnew NamedArgumentExpression(\"target\", left.Expression),\n\t\t\t\t\tnew NamedArgumentExpression(\"origin\", right.Expression)\n\t\t\t\t}, compilation.FindType(KnownTypeCode.IntPtr), inst);\n\t\t\t}\n\t\t\tif (inst.LeftInputType == StackType.Ref && inst.RightInputType.IsIntegerType())\n\t\t\t{\n\t\t\t\t// ref [+-] int\n\t\t\t\tvar brt = left.Type as ByReferenceType;\n\t\t\t\tif (brt == null)\n\t\t\t\t{\n\t\t\t\t\tbrt = GetReferenceType(left.Type);\n\t\t\t\t\tleft = left.ConvertTo(brt, this);\n\t\t\t\t}\n\t\t\t\tstring name = (inst.Operator == BinaryNumericOperator.Sub ? \"Subtract\" : \"Add\");\n\t\t\t\tILInstruction offsetInst = PointerArithmeticOffset.Detect(inst.Right, brt?.ElementType, inst.CheckForOverflow);\n\t\t\t\tif (offsetInst != null)\n\t\t\t\t{\n\t\t\t\t\tif (settings.FixedBuffers && inst.Operator == BinaryNumericOperator.Add && inst.Left is LdFlda ldFlda\n\t\t\t\t\t\t&& ldFlda.Target is LdFlda nestedLdFlda && CSharpDecompiler.IsFixedField(nestedLdFlda.Field, out var elementType, out _))\n\t\t\t\t\t{\n\t\t\t\t\t\tExpression fieldAccess = ConvertField(nestedLdFlda.Field, nestedLdFlda.Target);\n\t\t\t\t\t\tvar mrr = (MemberResolveResult)fieldAccess.GetResolveResult();\n\t\t\t\t\t\tfieldAccess.RemoveAnnotations<ResolveResult>();\n\t\t\t\t\t\tvar result = fieldAccess.WithRR(new MemberResolveResult(mrr.TargetResult, mrr.Member, new PointerType(elementType)))\n\t\t\t\t\t\t\t.WithILInstruction(inst);\n\t\t\t\t\t\tright = TranslateArrayIndex(offsetInst);\n\t\t\t\t\t\tTranslatedExpression expr = new IndexerExpression(result.Expression, right.Expression)\n\t\t\t\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t\t\t\t.WithRR(new ResolveResult(elementType));\n\t\t\t\t\t\treturn new DirectionExpression(FieldDirection.Ref, expr)\n\t\t\t\t\t\t\t.WithoutILInstruction().WithRR(new ByReferenceResolveResult(expr.ResolveResult, ReferenceKind.Ref));\n\t\t\t\t\t}\n\t\t\t\t\tright = Translate(offsetInst);\n\t\t\t\t\tright = ConvertArrayIndex(right, inst.RightInputType, allowIntPtr: true);\n\t\t\t\t\treturn CallUnsafeIntrinsic(name, new[] { left.Expression, right.Expression }, brt, inst);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tright = ConvertArrayIndex(right, inst.RightInputType, allowIntPtr: true);\n\t\t\t\t\treturn CallUnsafeIntrinsic(name + \"ByteOffset\", new[] { left.Expression, right.Expression }, brt, inst);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (inst.LeftInputType == StackType.I && inst.RightInputType == StackType.Ref\n\t\t\t\t&& inst.Operator == BinaryNumericOperator.Add)\n\t\t\t{\n\t\t\t\t// int + ref\n\t\t\t\tvar brt = right.Type as ByReferenceType;\n\t\t\t\tif (brt == null)\n\t\t\t\t{\n\t\t\t\t\tbrt = GetReferenceType(right.Type);\n\t\t\t\t\tright = right.ConvertTo(brt, this);\n\t\t\t\t}\n\t\t\t\tILInstruction offsetInst = PointerArithmeticOffset.Detect(inst.Left, brt.ElementType, inst.CheckForOverflow);\n\t\t\t\tif (offsetInst != null)\n\t\t\t\t{\n\t\t\t\t\tleft = Translate(offsetInst);\n\t\t\t\t\tleft = ConvertArrayIndex(left, inst.LeftInputType, allowIntPtr: true);\n\t\t\t\t\treturn CallUnsafeIntrinsic(\"Add\", new[] {\n\t\t\t\t\t\tnew NamedArgumentExpression(\"elementOffset\", left),\n\t\t\t\t\t\tnew NamedArgumentExpression(\"source\", right)\n\t\t\t\t\t}, brt, inst);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tleft = ConvertArrayIndex(left, inst.LeftInputType, allowIntPtr: true);\n\t\t\t\t\treturn CallUnsafeIntrinsic(\"AddByteOffset\", new[] {\n\t\t\t\t\t\tnew NamedArgumentExpression(\"byteOffset\", left.Expression),\n\t\t\t\t\t\tnew NamedArgumentExpression(\"source\", right)\n\t\t\t\t\t}, brt, inst);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\n\t\t\tByReferenceType GetReferenceType(IType type)\n\t\t\t{\n\t\t\t\tif (type is PointerType pt)\n\t\t\t\t{\n\t\t\t\t\treturn new ByReferenceType(pt.ElementType);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn new ByReferenceType(compilation.FindType(KnownTypeCode.Byte));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tinternal TranslatedExpression CallUnsafeIntrinsic(string name, Expression[] arguments, IType returnType, ILInstruction inst = null, IEnumerable<IType> typeArguments = null)\n\t\t{\n\t\t\tvar target = new MemberReferenceExpression {\n\t\t\t\tTarget = new TypeReferenceExpression(astBuilder.ConvertType(compilation.FindType(KnownTypeCode.Unsafe))),\n\t\t\t\tMemberName = name\n\t\t\t};\n\t\t\tif (typeArguments != null)\n\t\t\t{\n\t\t\t\ttarget.TypeArguments.AddRange(typeArguments.Select(astBuilder.ConvertType));\n\t\t\t}\n\t\t\tvar invocationExpr = new InvocationExpression(target, arguments);\n\t\t\tvar invocation = inst != null ? invocationExpr.WithILInstruction(inst) : invocationExpr.WithoutILInstruction();\n\t\t\tif (returnType is ByReferenceType brt)\n\t\t\t{\n\t\t\t\treturn WrapInRef(invocation.WithRR(new ResolveResult(brt.ElementType)), brt);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn invocation.WithRR(new ResolveResult(returnType));\n\t\t\t}\n\t\t}\n\n\t\tTranslatedExpression EnsureIntegerType(TranslatedExpression expr)\n\t\t{\n\t\t\tif (!expr.Type.IsCSharpPrimitiveIntegerType() && !expr.Type.IsCSharpNativeIntegerType())\n\t\t\t{\n\t\t\t\t// pointer arithmetic accepts all primitive integer types, but no enums etc.\n\t\t\t\texpr = expr.ConvertTo(FindArithmeticType(expr.Type.GetStackType(), expr.Type.GetSign()), this);\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\n\t\tTranslatedExpression? GetPointerArithmeticOffset(ILInstruction byteOffsetInst, TranslatedExpression byteOffsetExpr,\n\t\t\tIType pointerElementType, bool checkForOverflow, bool unwrapZeroExtension = false)\n\t\t{\n\t\t\tvar countOffsetInst = PointerArithmeticOffset.Detect(byteOffsetInst, pointerElementType,\n\t\t\t\tcheckForOverflow: checkForOverflow,\n\t\t\t\tunwrapZeroExtension: unwrapZeroExtension);\n\t\t\tif (countOffsetInst == null)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (countOffsetInst == byteOffsetInst)\n\t\t\t{\n\t\t\t\treturn EnsureIntegerType(byteOffsetExpr);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tTranslatedExpression expr = Translate(countOffsetInst);\n\t\t\t\t// Keep original ILInstruction as annotation\n\t\t\t\texpr.Expression.RemoveAnnotations<ILInstruction>();\n\t\t\t\treturn EnsureIntegerType(expr.WithILInstruction(byteOffsetInst));\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Called for divisions, detect and handles the code pattern:\n\t\t///   div(sub(a, b), sizeof(T))\n\t\t/// when a,b are of type T*.\n\t\t/// This is what the C# compiler generates for pointer subtraction.\n\t\t/// </summary>\n\t\tTranslatedExpression? HandlePointerSubtraction(BinaryNumericInstruction inst)\n\t\t{\n\t\t\tDebug.Assert(inst.Operator == BinaryNumericOperator.Div);\n\t\t\tif (inst.CheckForOverflow || inst.LeftInputType != StackType.I)\n\t\t\t\treturn null;\n\t\t\tif (!(inst.Left is BinaryNumericInstruction sub && sub.Operator == BinaryNumericOperator.Sub))\n\t\t\t\treturn null;\n\t\t\tif (sub.CheckForOverflow)\n\t\t\t\treturn null;\n\t\t\t// First, attempt to parse the 'sizeof' on the RHS\n\t\t\tIType elementType;\n\t\t\tif (inst.Right.MatchLdcI(out long elementSize))\n\t\t\t{\n\t\t\t\telementType = null;\n\t\t\t\t// OK, might be pointer subtraction if the element size matches\n\t\t\t}\n\t\t\telse if (inst.Right.UnwrapConv(ConversionKind.SignExtend).MatchSizeOf(out elementType))\n\t\t\t{\n\t\t\t\t// OK, might be pointer subtraction if the element type matches\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tvar left = Translate(sub.Left);\n\t\t\tvar right = Translate(sub.Right);\n\t\t\tIType pointerType;\n\t\t\tif (IsMatchingPointerType(left.Type))\n\t\t\t{\n\t\t\t\tpointerType = left.Type;\n\t\t\t}\n\t\t\telse if (IsMatchingPointerType(right.Type))\n\t\t\t{\n\t\t\t\tpointerType = right.Type;\n\t\t\t}\n\t\t\telse if (elementSize == 1 && left.Type.Kind == TypeKind.Pointer && right.Type.Kind == TypeKind.Pointer)\n\t\t\t{\n\t\t\t\t// two pointers (neither matching), we're dividing by 1 (debug builds only),\n\t\t\t\t// -> subtract two byte pointers\n\t\t\t\tpointerType = new PointerType(compilation.FindType(KnownTypeCode.Byte));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// neither is a matching pointer type\n\t\t\t\t// -> not a pointer subtraction after all\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\t// We got a pointer subtraction.\n\t\t\tleft = left.ConvertTo(pointerType, this);\n\t\t\tright = right.ConvertTo(pointerType, this);\n\t\t\tvar rr = new OperatorResolveResult(\n\t\t\t\tcompilation.FindType(KnownTypeCode.Int64),\n\t\t\t\tExpressionType.Subtract,\n\t\t\t\tleft.ResolveResult, right.ResolveResult\n\t\t\t);\n\t\t\tvar result = new BinaryOperatorExpression(\n\t\t\t\tleft.Expression, BinaryOperatorType.Subtract, right.Expression\n\t\t\t).WithILInstruction(new[] { inst, sub })\n\t\t\t .WithRR(rr);\n\t\t\treturn result;\n\n\t\t\tbool IsMatchingPointerType(IType type)\n\t\t\t{\n\t\t\t\tif (type is PointerType pt)\n\t\t\t\t{\n\t\t\t\t\tif (elementType != null)\n\t\t\t\t\t\treturn elementType.Equals(pt.ElementType);\n\t\t\t\t\telse if (elementSize > 0)\n\t\t\t\t\t\treturn PointerArithmeticOffset.ComputeSizeOf(pt.ElementType) == elementSize;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tTranslatedExpression HandleBinaryNumeric(BinaryNumericInstruction inst, BinaryOperatorType op, TranslationContext context)\n\t\t{\n\t\t\tvar resolverWithOverflowCheck = resolver.WithCheckForOverflow(inst.CheckForOverflow);\n\t\t\tbool propagateTypeHint = op.IsBitwise() && inst.LeftInputType != inst.RightInputType;\n\t\t\tvar left = Translate(inst.Left, propagateTypeHint ? context.TypeHint : null);\n\t\t\tvar right = Translate(inst.Right, propagateTypeHint ? context.TypeHint : null);\n\n\t\t\tif (inst.UnderlyingResultType == StackType.Ref)\n\t\t\t{\n\t\t\t\tvar ptrResult = HandleManagedPointerArithmetic(inst, left, right);\n\t\t\t\tif (ptrResult != null)\n\t\t\t\t\treturn ptrResult.Value;\n\t\t\t}\n\t\t\tif (left.Type.Kind == TypeKind.Pointer || right.Type.Kind == TypeKind.Pointer)\n\t\t\t{\n\t\t\t\tvar ptrResult = HandlePointerArithmetic(inst, left, right, context);\n\t\t\t\tif (ptrResult != null)\n\t\t\t\t\treturn ptrResult.Value;\n\t\t\t}\n\n\t\t\tleft = PrepareArithmeticArgument(left, inst.LeftInputType, inst.Sign, inst.IsLifted);\n\t\t\tright = PrepareArithmeticArgument(right, inst.RightInputType, inst.Sign, inst.IsLifted);\n\n\t\t\tif (op == BinaryOperatorType.Subtract && inst.Left.MatchLdcI(0))\n\t\t\t{\n\t\t\t\tIType rightUType = NullableType.GetUnderlyingType(right.Type);\n\t\t\t\tif (rightUType.IsKnownType(KnownTypeCode.Int32) || rightUType.IsKnownType(KnownTypeCode.Int64)\n\t\t\t\t\t|| rightUType.IsCSharpSmallIntegerType() || rightUType.Kind == TypeKind.NInt)\n\t\t\t\t{\n\t\t\t\t\t// unary minus is supported on signed int, nint and long, and on the small integer types (since they promote to int)\n\t\t\t\t\tvar uoe = new UnaryOperatorExpression(UnaryOperatorType.Minus, right.Expression);\n\t\t\t\t\tuoe.AddAnnotation(inst.CheckForOverflow ? AddCheckedBlocks.CheckedAnnotation : AddCheckedBlocks.UncheckedAnnotation);\n\t\t\t\t\tvar resultType = FindArithmeticType(inst.RightInputType, Sign.Signed);\n\t\t\t\t\tif (inst.IsLifted)\n\t\t\t\t\t\tresultType = NullableType.Create(compilation, resultType);\n\t\t\t\t\treturn uoe.WithILInstruction(inst).WithRR(new OperatorResolveResult(\n\t\t\t\t\t\tresultType,\n\t\t\t\t\t\tinst.CheckForOverflow ? ExpressionType.NegateChecked : ExpressionType.Negate,\n\t\t\t\t\t\tright.ResolveResult));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (op.IsBitwise()\n\t\t\t\t&& left.Type.IsKnownType(KnownTypeCode.Boolean)\n\t\t\t\t&& right.Type.IsKnownType(KnownTypeCode.Boolean)\n\t\t\t\t&& SemanticHelper.IsPure(inst.Right.Flags))\n\t\t\t{\n\t\t\t\t// Undo the C# compiler's optimization of \"a && b\" to \"a & b\".\n\t\t\t\tif (op == BinaryOperatorType.BitwiseAnd)\n\t\t\t\t{\n\t\t\t\t\top = BinaryOperatorType.ConditionalAnd;\n\t\t\t\t}\n\t\t\t\telse if (op == BinaryOperatorType.BitwiseOr)\n\t\t\t\t{\n\t\t\t\t\top = BinaryOperatorType.ConditionalOr;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (op.IsBitwise() && (left.Type.Kind == TypeKind.Enum || right.Type.Kind == TypeKind.Enum))\n\t\t\t{\n\t\t\t\tleft = AdjustConstantExpressionToType(left, right.Type);\n\t\t\t\tright = AdjustConstantExpressionToType(right, left.Type);\n\t\t\t}\n\n\t\t\tvar rr = resolverWithOverflowCheck.ResolveBinaryOperator(op, left.ResolveResult, right.ResolveResult);\n\t\t\tif (rr.IsError || NullableType.GetUnderlyingType(rr.Type).GetStackType() != inst.UnderlyingResultType\n\t\t\t\t|| !IsCompatibleWithSign(rr.Type, inst.Sign))\n\t\t\t{\n\t\t\t\t// Left and right operands are incompatible, so convert them to a common type\n\t\t\t\tSign sign = inst.Sign;\n\t\t\t\tif (sign == Sign.None)\n\t\t\t\t{\n\t\t\t\t\t// If the sign doesn't matter, try to use the same sign as expected by the context\n\t\t\t\t\tsign = context.TypeHint.GetSign();\n\t\t\t\t\tif (sign == Sign.None)\n\t\t\t\t\t{\n\t\t\t\t\t\tsign = op.IsBitwise() ? Sign.Unsigned : Sign.Signed;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tIType targetType = FindArithmeticType(inst.UnderlyingResultType, sign);\n\t\t\t\tleft = left.ConvertTo(NullableType.IsNullable(left.Type) ? NullableType.Create(compilation, targetType) : targetType, this);\n\t\t\t\tright = right.ConvertTo(NullableType.IsNullable(right.Type) ? NullableType.Create(compilation, targetType) : targetType, this);\n\t\t\t\trr = resolverWithOverflowCheck.ResolveBinaryOperator(op, left.ResolveResult, right.ResolveResult);\n\t\t\t}\n\t\t\tif (op.IsBitwise())\n\t\t\t{\n\t\t\t\tif (left.ResolveResult.ConstantValue != null)\n\t\t\t\t{\n\t\t\t\t\tlong value = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, left.ResolveResult.ConstantValue, checkForOverflow: false);\n\n\t\t\t\t\tleft = ConvertConstantValue(\n\t\t\t\t\t\tleft.ResolveResult,\n\t\t\t\t\t\tallowImplicitConversion: false,\n\t\t\t\t\t\tShouldDisplayAsHex(value, left.Type)\n\t\t\t\t\t).WithILInstruction(left.ILInstructions);\n\t\t\t\t}\n\t\t\t\tif (right.ResolveResult.ConstantValue != null)\n\t\t\t\t{\n\t\t\t\t\tlong value = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, right.ResolveResult.ConstantValue, checkForOverflow: false);\n\n\t\t\t\t\tright = ConvertConstantValue(\n\t\t\t\t\t\tright.ResolveResult,\n\t\t\t\t\t\tallowImplicitConversion: false,\n\t\t\t\t\t\tShouldDisplayAsHex(value, right.Type)\n\t\t\t\t\t).WithILInstruction(right.ILInstructions);\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar resultExpr = new BinaryOperatorExpression(left.Expression, op, right.Expression)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(rr);\n\t\t\tif (BinaryOperatorMightCheckForOverflow(op) && !inst.UnderlyingResultType.IsFloatType())\n\t\t\t{\n\t\t\t\tresultExpr.Expression.AddAnnotation(inst.CheckForOverflow ? AddCheckedBlocks.CheckedAnnotation : AddCheckedBlocks.UncheckedAnnotation);\n\t\t\t}\n\t\t\treturn resultExpr;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a type matching the stack type and sign.\n\t\t/// </summary>\n\t\tIType FindType(StackType stackType, Sign sign)\n\t\t{\n\t\t\tif (stackType == StackType.I && settings.NativeIntegers)\n\t\t\t{\n\t\t\t\treturn sign == Sign.Unsigned ? SpecialType.NUInt : SpecialType.NInt;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn compilation.FindType(stackType, sign);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a type used for performing arithmetic with the stack type and sign.\n\t\t/// \n\t\t/// This may result in a larger type than requested when the selected C# version\n\t\t/// doesn't support native integers.\n\t\t/// Should only be used after a call to PrepareArithmeticArgument()\n\t\t/// to ensure that we're not preserving extra bits from an oversized TranslatedExpression.\n\t\t/// </summary>\n\t\tIType FindArithmeticType(StackType stackType, Sign sign)\n\t\t{\n\t\t\tif (stackType == StackType.I)\n\t\t\t{\n\t\t\t\tif (settings.NativeIntegers)\n\t\t\t\t{\n\t\t\t\t\treturn sign == Sign.Unsigned ? SpecialType.NUInt : SpecialType.NInt;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// If native integers are not available, use 64-bit arithmetic instead\n\t\t\t\t\tstackType = StackType.I8;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn compilation.FindType(stackType, sign);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Handle oversized arguments needing truncation; and avoid IntPtr/pointers in arguments.\n\t\t/// </summary>\n\t\tTranslatedExpression PrepareArithmeticArgument(TranslatedExpression arg, StackType argStackType, Sign sign, bool isLifted)\n\t\t{\n\t\t\tif (isLifted && !NullableType.IsNullable(arg.Type))\n\t\t\t{\n\t\t\t\tisLifted = false; // don't cast to nullable if this input wasn't already nullable\n\t\t\t}\n\t\t\tIType argUType = isLifted ? NullableType.GetUnderlyingType(arg.Type) : arg.Type;\n\t\t\tif (argStackType.IsIntegerType() && argStackType.GetSize() < argUType.GetSize())\n\t\t\t{\n\t\t\t\t// If the argument is oversized (needs truncation to match stack size of its ILInstruction),\n\t\t\t\t// perform the truncation now.\n\t\t\t\tIType targetType = FindType(argStackType, sign);\n\t\t\t\targUType = targetType;\n\t\t\t\tif (isLifted)\n\t\t\t\t\ttargetType = NullableType.Create(compilation, targetType);\n\t\t\t\targ = arg.ConvertTo(targetType, this);\n\t\t\t}\n\t\t\tif (argUType.IsKnownType(KnownTypeCode.IntPtr) || argUType.IsKnownType(KnownTypeCode.UIntPtr))\n\t\t\t{\n\t\t\t\t// None of the operators we might want to apply are supported by IntPtr/UIntPtr.\n\t\t\t\t// Also, pointer arithmetic has different semantics (works in number of elements, not bytes).\n\t\t\t\t// So any inputs of size StackType.I must be converted to long/ulong.\n\t\t\t\tIType targetType = FindArithmeticType(StackType.I, sign);\n\t\t\t\tif (isLifted)\n\t\t\t\t\ttargetType = NullableType.Create(compilation, targetType);\n\t\t\t\targ = arg.ConvertTo(targetType, this);\n\t\t\t}\n\t\t\treturn arg;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether <paramref name=\"type\"/> has the specified <paramref name=\"sign\"/>.\n\t\t/// If <paramref name=\"sign\"/> is None, always returns true.\n\t\t/// </summary>\n\t\tstatic bool IsCompatibleWithSign(IType type, Sign sign)\n\t\t{\n\t\t\treturn sign == Sign.None || NullableType.GetUnderlyingType(type).GetSign() == sign;\n\t\t}\n\n\t\tstatic bool BinaryOperatorMightCheckForOverflow(BinaryOperatorType op)\n\t\t{\n\t\t\tswitch (op)\n\t\t\t{\n\t\t\t\tcase BinaryOperatorType.BitwiseAnd:\n\t\t\t\tcase BinaryOperatorType.BitwiseOr:\n\t\t\t\tcase BinaryOperatorType.ExclusiveOr:\n\t\t\t\tcase BinaryOperatorType.ShiftLeft:\n\t\t\t\tcase BinaryOperatorType.ShiftRight:\n\t\t\t\tcase BinaryOperatorType.UnsignedShiftRight:\n\t\t\t\t\treturn false;\n\t\t\t\tdefault:\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tTranslatedExpression HandleShift(BinaryNumericInstruction inst, BinaryOperatorType op, TranslationContext context)\n\t\t{\n\t\t\tvar left = Translate(inst.Left);\n\t\t\tvar right = Translate(inst.Right);\n\n\t\t\tleft = PrepareArithmeticArgument(left, inst.LeftInputType, inst.Sign, inst.IsLifted);\n\n\t\t\tSign sign = inst.Sign;\n\t\t\tvar leftUType = NullableType.GetUnderlyingType(left.Type);\n\t\t\tbool couldUseUnsignedRightShift = (\n\t\t\t\tsign == Sign.Unsigned && op == BinaryOperatorType.ShiftRight && settings.UnsignedRightShift\n\t\t\t\t&& (leftUType.IsCSharpPrimitiveIntegerType() || leftUType.IsCSharpNativeIntegerType())\n\t\t\t\t// If we need to cast to unsigned anyway, don't use >>> operator.\n\t\t\t\t&& context.TypeHint.GetSign() != Sign.Unsigned\n\t\t\t);\n\t\t\tif (leftUType.IsCSharpSmallIntegerType() && inst.UnderlyingResultType == StackType.I4 &&\n\t\t\t\t(sign != Sign.Unsigned || couldUseUnsignedRightShift))\n\t\t\t{\n\t\t\t\t// With small integer types, C# will promote to int and perform signed shifts.\n\t\t\t\t// We thus don't need any casts in this case.\n\t\t\t\t// The >>> operator also promotes to signed int, but then performs an unsigned shift.\n\t\t\t\tif (sign == Sign.Unsigned)\n\t\t\t\t{\n\t\t\t\t\top = BinaryOperatorType.UnsignedShiftRight;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (couldUseUnsignedRightShift && leftUType.GetSize() == inst.UnderlyingResultType.GetSize() && leftUType.GetSign() == Sign.Signed)\n\t\t\t{\n\t\t\t\t// Use C# 11 unsigned right shift operator. We don't need any casts in this case.\n\t\t\t\top = BinaryOperatorType.UnsignedShiftRight;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Insert cast to target type.\n\t\t\t\tif (sign == Sign.None)\n\t\t\t\t{\n\t\t\t\t\t// if we don't need a specific sign, prefer keeping that of the input:\n\t\t\t\t\tsign = leftUType.GetSign();\n\t\t\t\t}\n\t\t\t\tIType targetType = FindArithmeticType(inst.UnderlyingResultType, sign);\n\t\t\t\tif (NullableType.IsNullable(left.Type))\n\t\t\t\t{\n\t\t\t\t\ttargetType = NullableType.Create(compilation, targetType);\n\t\t\t\t}\n\t\t\t\tleft = left.ConvertTo(targetType, this);\n\t\t\t}\n\n\t\t\t// Shift operators in C# always expect type 'int' on the right-hand-side\n\t\t\tif (NullableType.IsNullable(right.Type))\n\t\t\t{\n\t\t\t\tright = right.ConvertTo(NullableType.Create(compilation, compilation.FindType(KnownTypeCode.Int32)), this);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tright = right.ConvertTo(compilation.FindType(KnownTypeCode.Int32), this);\n\t\t\t}\n\n\t\t\treturn new BinaryOperatorExpression(left.Expression, op, right.Expression)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(resolver.ResolveBinaryOperator(op, left.ResolveResult, right.ResolveResult));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitUserDefinedCompoundAssign(UserDefinedCompoundAssign inst, TranslationContext context)\n\t\t{\n\t\t\tIType loadType;\n\t\t\tbool isSpanBasedStringConcat = CallBuilder.IsSpanBasedStringConcat(inst.Method);\n\t\t\tif (isSpanBasedStringConcat)\n\t\t\t{\n\t\t\t\tloadType = typeSystem.FindType(KnownTypeCode.String);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tloadType = inst.Method.Parameters[0].Type;\n\t\t\t}\n\n\t\t\tExpressionWithResolveResult target;\n\t\t\tif (inst.TargetKind == CompoundTargetKind.Address)\n\t\t\t{\n\t\t\t\ttarget = LdObj(inst.Target, loadType);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttarget = Translate(inst.Target, loadType);\n\t\t\t}\n\t\t\tvar opType = OperatorDeclaration.GetOperatorType(inst.Method.Name);\n\t\t\tif (opType != null && OperatorDeclaration.IsChecked(opType.Value))\n\t\t\t{\n\t\t\t\ttarget.Expression.AddAnnotation(AddCheckedBlocks.CheckedAnnotation);\n\t\t\t}\n\t\t\telse if (ReplaceMethodCallsWithOperators.HasCheckedEquivalent(inst.Method))\n\t\t\t{\n\t\t\t\ttarget.Expression.AddAnnotation(AddCheckedBlocks.UncheckedAnnotation);\n\t\t\t}\n\t\t\tif (UserDefinedCompoundAssign.IsStringConcat(inst.Method))\n\t\t\t{\n\t\t\t\tDebug.Assert(inst.Method.Parameters.Count == 2);\n\t\t\t\tExpression valueExpr;\n\t\t\t\tResolveResult valueResolveResult;\n\t\t\t\tif (isSpanBasedStringConcat && inst.Value is NewObj { Arguments: [AddressOf addressOf] })\n\t\t\t\t{\n\t\t\t\t\tIType charType = typeSystem.FindType(KnownTypeCode.Char);\n\t\t\t\t\tvar value = Translate(addressOf.Value, charType).ConvertTo(charType, this);\n\t\t\t\t\tvalueExpr = value.Expression;\n\t\t\t\t\tvalueResolveResult = value.ResolveResult;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar value = Translate(inst.Value).ConvertTo(inst.Method.Parameters[1].Type, this, allowImplicitConversion: true);\n\t\t\t\t\tvalueExpr = ReplaceMethodCallsWithOperators.RemoveRedundantToStringInConcat(value, inst.Method, isLastArgument: true).Detach();\n\t\t\t\t\tvalueResolveResult = value.ResolveResult;\n\t\t\t\t}\n\t\t\t\treturn new AssignmentExpression(target, AssignmentOperatorType.Add, valueExpr)\n\t\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t\t.WithRR(new OperatorResolveResult(inst.Method.ReturnType, ExpressionType.AddAssign, inst.Method, inst.IsLifted, new[] { target.ResolveResult, valueResolveResult }));\n\t\t\t}\n\t\t\telse if (inst.Method.Parameters.Count == 2)\n\t\t\t{\n\t\t\t\tvar value = Translate(inst.Value).ConvertTo(inst.Method.Parameters[1].Type, this);\n\t\t\t\tAssignmentOperatorType? op = GetAssignmentOperatorTypeFromMetadataName(inst.Method.Name, settings);\n\t\t\t\tDebug.Assert(op != null);\n\n\t\t\t\treturn new AssignmentExpression(target, op.Value, value)\n\t\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t\t.WithRR(new OperatorResolveResult(inst.Method.ReturnType, AssignmentExpression.GetLinqNodeType(op.Value, false), inst.Method, inst.IsLifted, new[] { target.ResolveResult, value.ResolveResult }));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tUnaryOperatorType? op = GetUnaryOperatorTypeFromMetadataName(inst.Method.Name, inst.EvalMode == CompoundEvalMode.EvaluatesToOldValue);\n\t\t\t\tDebug.Assert(op != null);\n\n\t\t\t\treturn new UnaryOperatorExpression(op.Value, target)\n\t\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t\t.WithRR(new OperatorResolveResult(inst.Method.ReturnType, UnaryOperatorExpression.GetLinqNodeType(op.Value, false), inst.Method, inst.IsLifted, new[] { target.ResolveResult }));\n\t\t\t}\n\t\t}\n\n\t\tinternal static AssignmentOperatorType? GetAssignmentOperatorTypeFromMetadataName(string name, DecompilerSettings settings)\n\t\t{\n\t\t\tswitch (name)\n\t\t\t{\n\t\t\t\tcase \"op_Addition\":\n\t\t\t\t\treturn AssignmentOperatorType.Add;\n\t\t\t\tcase \"op_Subtraction\":\n\t\t\t\t\treturn AssignmentOperatorType.Subtract;\n\t\t\t\tcase \"op_Multiply\":\n\t\t\t\t\treturn AssignmentOperatorType.Multiply;\n\t\t\t\tcase \"op_Division\":\n\t\t\t\t\treturn AssignmentOperatorType.Divide;\n\t\t\t\tcase \"op_Modulus\":\n\t\t\t\t\treturn AssignmentOperatorType.Modulus;\n\t\t\t\tcase \"op_BitwiseAnd\":\n\t\t\t\t\treturn AssignmentOperatorType.BitwiseAnd;\n\t\t\t\tcase \"op_BitwiseOr\":\n\t\t\t\t\treturn AssignmentOperatorType.BitwiseOr;\n\t\t\t\tcase \"op_ExclusiveOr\":\n\t\t\t\t\treturn AssignmentOperatorType.ExclusiveOr;\n\t\t\t\tcase \"op_LeftShift\":\n\t\t\t\t\treturn AssignmentOperatorType.ShiftLeft;\n\t\t\t\tcase \"op_RightShift\":\n\t\t\t\t\treturn AssignmentOperatorType.ShiftRight;\n\t\t\t\tcase \"op_UnsignedRightShift\" when settings.UnsignedRightShift:\n\t\t\t\t\treturn AssignmentOperatorType.UnsignedShiftRight;\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tinternal static UnaryOperatorType? GetUnaryOperatorTypeFromMetadataName(string name, bool isPostfix)\n\t\t{\n\t\t\tswitch (name)\n\t\t\t{\n\t\t\t\tcase \"op_Increment\":\n\t\t\t\tcase \"op_CheckedIncrement\":\n\t\t\t\t\treturn isPostfix ? UnaryOperatorType.PostIncrement : UnaryOperatorType.Increment;\n\t\t\t\tcase \"op_Decrement\":\n\t\t\t\tcase \"op_CheckedDecrement\":\n\t\t\t\t\treturn isPostfix ? UnaryOperatorType.PostDecrement : UnaryOperatorType.Decrement;\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitNumericCompoundAssign(NumericCompoundAssign inst, TranslationContext context)\n\t\t{\n\t\t\tswitch (inst.Operator)\n\t\t\t{\n\t\t\t\tcase BinaryNumericOperator.Add:\n\t\t\t\t\treturn HandleCompoundAssignment(inst, AssignmentOperatorType.Add);\n\t\t\t\tcase BinaryNumericOperator.Sub:\n\t\t\t\t\treturn HandleCompoundAssignment(inst, AssignmentOperatorType.Subtract);\n\t\t\t\tcase BinaryNumericOperator.Mul:\n\t\t\t\t\treturn HandleCompoundAssignment(inst, AssignmentOperatorType.Multiply);\n\t\t\t\tcase BinaryNumericOperator.Div:\n\t\t\t\t\treturn HandleCompoundAssignment(inst, AssignmentOperatorType.Divide);\n\t\t\t\tcase BinaryNumericOperator.Rem:\n\t\t\t\t\treturn HandleCompoundAssignment(inst, AssignmentOperatorType.Modulus);\n\t\t\t\tcase BinaryNumericOperator.BitAnd:\n\t\t\t\t\treturn HandleCompoundAssignment(inst, AssignmentOperatorType.BitwiseAnd);\n\t\t\t\tcase BinaryNumericOperator.BitOr:\n\t\t\t\t\treturn HandleCompoundAssignment(inst, AssignmentOperatorType.BitwiseOr);\n\t\t\t\tcase BinaryNumericOperator.BitXor:\n\t\t\t\t\treturn HandleCompoundAssignment(inst, AssignmentOperatorType.ExclusiveOr);\n\t\t\t\tcase BinaryNumericOperator.ShiftLeft:\n\t\t\t\t\treturn HandleCompoundShift(inst, AssignmentOperatorType.ShiftLeft);\n\t\t\t\tcase BinaryNumericOperator.ShiftRight:\n\t\t\t\t\tif (inst.Sign == Sign.Unsigned && inst.Type.GetSign() == Sign.Signed)\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(settings.UnsignedRightShift);\n\t\t\t\t\t\treturn HandleCompoundShift(inst, AssignmentOperatorType.UnsignedShiftRight);\n\t\t\t\t\t}\n\t\t\t\t\telse if (inst.Sign == Sign.Unsigned && inst.Type.IsCSharpSmallIntegerType() && settings.UnsignedRightShift)\n\t\t\t\t\t{\n\t\t\t\t\t\t// For small unsigned integer types promoted to signed int, the sign bit will be zero,\n\t\t\t\t\t\t// so there is no difference between signed and unsigned shift.\n\t\t\t\t\t\t// However the IL still indicates which C# operator was used, so preserve that if the setting allows us to.\n\t\t\t\t\t\treturn HandleCompoundShift(inst, AssignmentOperatorType.UnsignedShiftRight);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn HandleCompoundShift(inst, AssignmentOperatorType.ShiftRight);\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t}\n\t\t}\n\n\t\tTranslatedExpression HandleCompoundAssignment(NumericCompoundAssign inst, AssignmentOperatorType op)\n\t\t{\n\t\t\tExpressionWithResolveResult target;\n\t\t\tif (inst.TargetKind == CompoundTargetKind.Address)\n\t\t\t{\n\t\t\t\ttarget = LdObj(inst.Target, inst.Type);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttarget = Translate(inst.Target, inst.Type);\n\t\t\t}\n\n\t\t\tTranslatedExpression resultExpr;\n\t\t\tif (inst.EvalMode == CompoundEvalMode.EvaluatesToOldValue)\n\t\t\t{\n\t\t\t\tDebug.Assert(op == AssignmentOperatorType.Add || op == AssignmentOperatorType.Subtract);\n#if DEBUG\n\t\t\t\tif (target.Type is PointerType ptrType)\n\t\t\t\t{\n\t\t\t\t\tILInstruction instValue = PointerArithmeticOffset.Detect(inst.Value, ptrType.ElementType, inst.CheckForOverflow);\n\t\t\t\t\tDebug.Assert(instValue is not null);\n\t\t\t\t\tDebug.Assert(instValue.MatchLdcI(1));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tDebug.Assert(inst.Value.MatchLdcI(1) || inst.Value.MatchLdcF4(1) || inst.Value.MatchLdcF8(1));\n#endif\n\t\t\t\tUnaryOperatorType unary;\n\t\t\t\tExpressionType exprType;\n\t\t\t\tif (op == AssignmentOperatorType.Add)\n\t\t\t\t{\n\t\t\t\t\tunary = UnaryOperatorType.PostIncrement;\n\t\t\t\t\texprType = ExpressionType.PostIncrementAssign;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tunary = UnaryOperatorType.PostDecrement;\n\t\t\t\t\texprType = ExpressionType.PostDecrementAssign;\n\t\t\t\t}\n\t\t\t\tresultExpr = new UnaryOperatorExpression(unary, target)\n\t\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t\t.WithRR(new OperatorResolveResult(target.Type, exprType, target.ResolveResult));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar value = Translate(inst.Value);\n\t\t\t\tvalue = PrepareArithmeticArgument(value, inst.RightInputType, inst.Sign, inst.IsLifted);\n\t\t\t\tswitch (op)\n\t\t\t\t{\n\t\t\t\t\tcase AssignmentOperatorType.Add:\n\t\t\t\t\tcase AssignmentOperatorType.Subtract:\n\t\t\t\t\t\tif (target.Type.Kind == TypeKind.Pointer)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar pao = GetPointerArithmeticOffset(inst.Value, value, ((PointerType)target.Type).ElementType, inst.CheckForOverflow);\n\t\t\t\t\t\t\tif (pao != null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvalue = pao.Value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvalue.Expression.AddChild(new Comment(\"ILSpy Error: GetPointerArithmeticOffset() failed\", CommentType.MultiLine), Roles.Comment);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tIType targetType = NullableType.GetUnderlyingType(target.Type).GetEnumUnderlyingType();\n\t\t\t\t\t\t\tvalue = ConvertValue(value, targetType);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssignmentOperatorType.Multiply:\n\t\t\t\t\tcase AssignmentOperatorType.Divide:\n\t\t\t\t\tcase AssignmentOperatorType.Modulus:\n\t\t\t\t\tcase AssignmentOperatorType.BitwiseAnd:\n\t\t\t\t\tcase AssignmentOperatorType.BitwiseOr:\n\t\t\t\t\tcase AssignmentOperatorType.ExclusiveOr:\n\t\t\t\t\t{\n\t\t\t\t\t\tIType targetType = NullableType.GetUnderlyingType(target.Type);\n\t\t\t\t\t\tvalue = ConvertValue(value, targetType);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tresultExpr = new AssignmentExpression(target.Expression, op, value.Expression)\n\t\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t\t.WithRR(new OperatorResolveResult(target.Type, AssignmentExpression.GetLinqNodeType(op, inst.CheckForOverflow), target.ResolveResult, value.ResolveResult));\n\t\t\t}\n\t\t\tif (AssignmentOperatorMightCheckForOverflow(op) && !inst.UnderlyingResultType.IsFloatType())\n\t\t\t{\n\t\t\t\tresultExpr.Expression.AddAnnotation(inst.CheckForOverflow ? AddCheckedBlocks.CheckedAnnotation : AddCheckedBlocks.UncheckedAnnotation);\n\t\t\t}\n\t\t\treturn resultExpr;\n\n\t\t\tTranslatedExpression ConvertValue(TranslatedExpression value, IType targetType)\n\t\t\t{\n\t\t\t\tbool allowImplicitConversion = true;\n\t\t\t\tif (targetType.GetStackType() == StackType.I)\n\t\t\t\t{\n\t\t\t\t\t// Force explicit cast for (U)IntPtr, keep allowing implicit conversion only for n(u)int\n\t\t\t\t\tallowImplicitConversion = targetType.IsCSharpNativeIntegerType();\n\t\t\t\t\ttargetType = targetType.GetSign() == Sign.Unsigned ? SpecialType.NUInt : SpecialType.NInt;\n\t\t\t\t}\n\t\t\t\tif (NullableType.IsNullable(value.Type))\n\t\t\t\t{\n\t\t\t\t\ttargetType = NullableType.Create(compilation, targetType);\n\t\t\t\t}\n\t\t\t\treturn value.ConvertTo(targetType, this, inst.CheckForOverflow, allowImplicitConversion);\n\t\t\t}\n\t\t}\n\n\t\tTranslatedExpression HandleCompoundShift(NumericCompoundAssign inst, AssignmentOperatorType op)\n\t\t{\n\t\t\tDebug.Assert(inst.EvalMode == CompoundEvalMode.EvaluatesToNewValue);\n\t\t\tExpressionWithResolveResult target;\n\t\t\tif (inst.TargetKind == CompoundTargetKind.Address)\n\t\t\t{\n\t\t\t\ttarget = LdObj(inst.Target, inst.Type);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttarget = Translate(inst.Target, inst.Type);\n\t\t\t}\n\t\t\tvar value = Translate(inst.Value);\n\n\t\t\t// Shift operators in C# always expect type 'int' on the right-hand-side\n\t\t\tif (NullableType.IsNullable(value.Type))\n\t\t\t{\n\t\t\t\tvalue = value.ConvertTo(NullableType.Create(compilation, compilation.FindType(KnownTypeCode.Int32)), this);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvalue = value.ConvertTo(compilation.FindType(KnownTypeCode.Int32), this);\n\t\t\t}\n\n\t\t\treturn new AssignmentExpression(target.Expression, op, value.Expression)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(resolver.ResolveAssignment(op, target.ResolveResult, value.ResolveResult));\n\t\t}\n\n\t\tstatic bool AssignmentOperatorMightCheckForOverflow(AssignmentOperatorType op)\n\t\t{\n\t\t\tswitch (op)\n\t\t\t{\n\t\t\t\tcase AssignmentOperatorType.BitwiseAnd:\n\t\t\t\tcase AssignmentOperatorType.BitwiseOr:\n\t\t\t\tcase AssignmentOperatorType.ExclusiveOr:\n\t\t\t\tcase AssignmentOperatorType.ShiftLeft:\n\t\t\t\tcase AssignmentOperatorType.ShiftRight:\n\t\t\t\t\treturn false;\n\t\t\t\tdefault:\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitConv(Conv inst, TranslationContext context)\n\t\t{\n\t\t\tSign hintSign = inst.InputSign;\n\t\t\tif (hintSign == Sign.None)\n\t\t\t{\n\t\t\t\thintSign = context.TypeHint.GetSign();\n\t\t\t}\n\t\t\tvar arg = Translate(inst.Argument, typeHint: FindArithmeticType(inst.InputType, hintSign));\n\t\t\tIType inputType = NullableType.GetUnderlyingType(arg.Type);\n\t\t\tStackType inputStackType = inst.InputType;\n\t\t\t// Note: we're dealing with two conversions here:\n\t\t\t// a) the implicit conversion from `inputType` to `inputStackType`\n\t\t\t//    (due to the ExpressionBuilder post-condition being flexible with regards to the integer type width)\n\t\t\t//    If this is a widening conversion, I'm calling the argument C# type \"oversized\".\n\t\t\t//    If this is a narrowing conversion, I'm calling the argument C# type \"undersized\".\n\t\t\t// b) the actual conversion instruction from `inputStackType` to `inst.TargetType`\n\n\t\t\t// Also, we need to be very careful with regards to the conversions we emit:\n\t\t\t// In C#, zero vs. sign-extension depends on the input type,\n\t\t\t// but in the ILAst conv instruction it depends on the output type.\n\t\t\t// However, in the conv.ovf instructions, the .NET runtime behavior seems to depend on the input type,\n\t\t\t// in violation of the ECMA-335 spec!\n\n\t\t\tIType GetType(KnownTypeCode typeCode)\n\t\t\t{\n\t\t\t\tIType type = compilation.FindType(typeCode);\n\t\t\t\t// Prefer n(u)int over (U)IntPtr\n\t\t\t\tif (typeCode == KnownTypeCode.IntPtr && settings.NativeIntegers && !type.Equals(context.TypeHint))\n\t\t\t\t{\n\t\t\t\t\ttype = SpecialType.NInt;\n\t\t\t\t}\n\t\t\t\telse if (typeCode == KnownTypeCode.UIntPtr && settings.NativeIntegers && !type.Equals(context.TypeHint))\n\t\t\t\t{\n\t\t\t\t\ttype = SpecialType.NUInt;\n\t\t\t\t}\n\t\t\t\tif (inst.IsLifted)\n\t\t\t\t{\n\t\t\t\t\ttype = NullableType.Create(compilation, type);\n\t\t\t\t}\n\t\t\t\treturn type;\n\t\t\t}\n\n\t\t\tif (inst.CheckForOverflow || inst.Kind == ConversionKind.IntToFloat)\n\t\t\t{\n\t\t\t\t// We need to first convert the argument to the expected sign.\n\t\t\t\t// We also need to perform any input narrowing conversion so that it doesn't get mixed up with the overflow check.\n\t\t\t\tDebug.Assert(inst.InputSign != Sign.None);\n\t\t\t\tif (inputType.GetSize() > inputStackType.GetSize() || inputType.GetSign() != inst.InputSign)\n\t\t\t\t{\n\t\t\t\t\targ = arg.ConvertTo(GetType(inputStackType.ToKnownTypeCode(inst.InputSign)), this);\n\t\t\t\t}\n\t\t\t\t// Because casts with overflow check match C# semantics (zero/sign-extension depends on source type),\n\t\t\t\t// we can just directly cast to the target type.\n\t\t\t\treturn arg.ConvertTo(GetType(inst.TargetType.ToKnownTypeCode()), this, inst.CheckForOverflow)\n\t\t\t\t\t.WithILInstruction(inst);\n\t\t\t}\n\n\t\t\tswitch (inst.Kind)\n\t\t\t{\n\t\t\t\tcase ConversionKind.StartGCTracking:\n\t\t\t\t\t// A \"start gc tracking\" conversion is inserted in the ILAst whenever\n\t\t\t\t\t// some instruction expects a managed pointer, but we pass an unmanaged pointer.\n\t\t\t\t\t// We'll leave the C#-level conversion (from T* to ref T) to the consumer that expects the managed pointer.\n\t\t\t\t\treturn arg;\n\t\t\t\tcase ConversionKind.StopGCTracking:\n\t\t\t\t\tif (inputType.Kind == TypeKind.ByReference)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (PointerArithmeticOffset.IsFixedVariable(inst.Argument))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// cast to corresponding pointer type:\n\t\t\t\t\t\t\tvar pointerType = new PointerType(((ByReferenceType)inputType).ElementType);\n\t\t\t\t\t\t\treturn arg.ConvertTo(pointerType, this).WithILInstruction(inst);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// emit Unsafe.AsPointer() intrinsic:\n\t\t\t\t\t\t\treturn CallUnsafeIntrinsic(\"AsPointer\",\n\t\t\t\t\t\t\t\targuments: new Expression[] { arg },\n\t\t\t\t\t\t\t\treturnType: new PointerType(compilation.FindType(KnownTypeCode.Void)),\n\t\t\t\t\t\t\t\tinst: inst);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (arg.Type.GetStackType().IsIntegerType())\n\t\t\t\t\t{\n\t\t\t\t\t\t// ConversionKind.StopGCTracking should only be used with managed references,\n\t\t\t\t\t\t// but it's possible that we're supposed to stop tracking something we just started to track.\n\t\t\t\t\t\treturn arg;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tgoto default;\n\t\t\t\t\t}\n\t\t\t\tcase ConversionKind.SignExtend:\n\t\t\t\t\t// We just need to ensure the input type before the conversion is signed.\n\t\t\t\t\t// Also, if the argument was translated into an oversized C# type,\n\t\t\t\t\t// we need to perform the truncatation to the input stack type.\n\t\t\t\t\tif (inputType.GetSign() != Sign.Signed || ValueMightBeOversized(arg.ResolveResult, inputStackType))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Note that an undersized C# type is handled just fine:\n\t\t\t\t\t\t// If it is unsigned we'll zero-extend it to the width of the inputStackType here,\n\t\t\t\t\t\t// and it is signed we just combine the two sign-extensions into a single sign-extending conversion.\n\t\t\t\t\t\targ = arg.ConvertTo(GetType(inputStackType.ToKnownTypeCode(Sign.Signed)), this);\n\t\t\t\t\t}\n\t\t\t\t\t// Then, we can just return the argument as-is: the ExpressionBuilder post-condition allows us\n\t\t\t\t\t// to force our parent instruction to handle the actual sign-extension conversion.\n\t\t\t\t\t// (our caller may have more information to pick a better fitting target type)\n\t\t\t\t\treturn arg.WithILInstruction(inst);\n\t\t\t\tcase ConversionKind.ZeroExtend:\n\t\t\t\t\t// If overflow check cannot fail, handle this just like sign extension (except for swapped signs)\n\t\t\t\t\tif (inputType.GetSign() != Sign.Unsigned || inputType.GetSize() > inputStackType.GetSize())\n\t\t\t\t\t{\n\t\t\t\t\t\targ = arg.ConvertTo(GetType(inputStackType.ToKnownTypeCode(Sign.Unsigned)), this);\n\t\t\t\t\t}\n\t\t\t\t\treturn arg.WithILInstruction(inst);\n\t\t\t\tcase ConversionKind.Nop:\n\t\t\t\t\t// no need to generate any C# code for a nop conversion\n\t\t\t\t\treturn arg.WithILInstruction(inst);\n\t\t\t\tcase ConversionKind.Truncate:\n\t\t\t\t\t// Note: there are three sizes involved here:\n\t\t\t\t\t// A = inputType.GetSize()\n\t\t\t\t\t// B = inputStackType.GetSize()\n\t\t\t\t\t// C = inst.TargetType.GetSize().\n\t\t\t\t\t// We know that C < B (otherwise this wouldn't be the truncation case).\n\t\t\t\t\t// 1) If C < B < A, we just combine the two truncations into one.\n\t\t\t\t\t// 2) If C < B = A, there's no input conversion, just the truncation\n\t\t\t\t\t// 3) If C <= A < B, all the extended bits get removed again by the truncation.\n\t\t\t\t\t// 4) If A < C < B, some extended bits remain even after truncation.\n\t\t\t\t\t// In cases 1-3, the overall conversion is a truncation or no-op.\n\t\t\t\t\t// In case 4, the overall conversion is a zero/sign extension, but to a smaller\n\t\t\t\t\t// size than the original conversion.\n\t\t\t\t\tif (inst.TargetType.IsSmallIntegerType())\n\t\t\t\t\t{\n\t\t\t\t\t\t// If the target type is a small integer type, IL will implicitly sign- or zero-extend\n\t\t\t\t\t\t// the result after the truncation back to StackType.I4.\n\t\t\t\t\t\t// (which means there's actually 3 conversions involved!)\n\t\t\t\t\t\t// Note that we must handle truncation to small integer types ourselves:\n\t\t\t\t\t\t// our caller only sees the StackType.I4 and doesn't know to truncate to the small type.\n\n\t\t\t\t\t\tif (inputType.GetSize() <= inst.TargetType.GetSize() && inputType.GetSign() == inst.TargetType.GetSign())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// There's no actual truncation involved, and the result of the Conv instruction is extended\n\t\t\t\t\t\t\t// the same way as the original instruction\n\t\t\t\t\t\t\t// -> we can return arg directly\n\t\t\t\t\t\t\treturn arg.WithILInstruction(inst);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// We need to actually truncate; *or* we need to change the sign for the remaining extension to I4.\n\t\t\t\t\t\t\tgoto default; // Emit simple cast to inst.TargetType\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(inst.TargetType.GetSize() == inst.UnderlyingResultType.GetSize());\n\t\t\t\t\t\t// For non-small integer types, we can let the whole unchecked truncation\n\t\t\t\t\t\t// get handled by our caller (using the ExpressionBuilder post-condition).\n\n\t\t\t\t\t\t// Case 4 (left-over extension from implicit conversion) can also be handled by our caller.\n\t\t\t\t\t\treturn arg.WithILInstruction(inst);\n\t\t\t\t\t}\n\t\t\t\tcase ConversionKind.Invalid:\n\t\t\t\t\tif (inst.InputType == StackType.Unknown && inst.TargetType == IL.PrimitiveType.None && arg.Type.Kind == TypeKind.Unknown)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Unknown -> O conversion.\n\t\t\t\t\t\t// Our post-condition allows us to also use expressions with unknown type where O is expected,\n\t\t\t\t\t\t// so avoid introducing an `(object)` cast because we're likely to cast back to the same unknown type,\n\t\t\t\t\t\t// just in a signature context where we know that it's a class type.\n\t\t\t\t\t\treturn arg.WithILInstruction(inst);\n\t\t\t\t\t}\n\t\t\t\t\tgoto default;\n\t\t\t\tdefault:\n\t\t\t\t{\n\t\t\t\t\t// We need to convert to inst.TargetType, or to an equivalent type.\n\t\t\t\t\tIType targetType;\n\t\t\t\t\tif (inst.TargetType == NullableType.GetUnderlyingType(context.TypeHint).ToPrimitiveType()\n\t\t\t\t\t\t&& NullableType.IsNullable(context.TypeHint) == inst.IsLifted)\n\t\t\t\t\t{\n\t\t\t\t\t\ttargetType = context.TypeHint;\n\t\t\t\t\t}\n\t\t\t\t\telse if (inst.TargetType == IL.PrimitiveType.Ref)\n\t\t\t\t\t{\n\t\t\t\t\t\t// converting to unknown ref-type\n\t\t\t\t\t\ttargetType = new ByReferenceType(compilation.FindType(KnownTypeCode.Byte));\n\t\t\t\t\t}\n\t\t\t\t\telse if (inst.TargetType == IL.PrimitiveType.None)\n\t\t\t\t\t{\n\t\t\t\t\t\t// convert to some object type\n\t\t\t\t\t\t// (e.g. invalid I4->O conversion)\n\t\t\t\t\t\ttargetType = compilation.FindType(KnownTypeCode.Object);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\ttargetType = GetType(inst.TargetType.ToKnownTypeCode());\n\t\t\t\t\t}\n\t\t\t\t\treturn arg.ConvertTo(targetType, this, inst.CheckForOverflow)\n\t\t\t\t\t\t.WithILInstruction(inst);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the ResolveResult computes a value that might be oversized for the specified stack type.\n\t\t/// </summary>\n\t\tbool ValueMightBeOversized(ResolveResult rr, StackType stackType)\n\t\t{\n\t\t\tIType inputType = NullableType.GetUnderlyingType(rr.Type);\n\t\t\tif (inputType.GetSize() <= stackType.GetSize())\n\t\t\t{\n\t\t\t\t// The input type is smaller or equal to the stack type,\n\t\t\t\t// it can't be an oversized value.\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (rr is OperatorResolveResult orr)\n\t\t\t{\n\t\t\t\tif (stackType == StackType.I && orr.OperatorType == ExpressionType.Subtract\n\t\t\t\t\t&& orr.Operands.Count == 2\n\t\t\t\t\t&& orr.Operands[0].Type.Kind == TypeKind.Pointer\n\t\t\t\t\t&& orr.Operands[1].Type.Kind == TypeKind.Pointer)\n\t\t\t\t{\n\t\t\t\t\t// Even though a pointer subtraction produces a value of type long in C#,\n\t\t\t\t\t// the value will always fit in a native int.\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// We don't have any information about the value, so it might be oversized.\n\t\t\treturn true;\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitCall(Call inst, TranslationContext context)\n\t\t{\n\t\t\treturn WrapInRef(new CallBuilder(this, typeSystem, settings).Build(inst), inst.Method.ReturnType);\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitCallVirt(CallVirt inst, TranslationContext context)\n\t\t{\n\t\t\treturn WrapInRef(new CallBuilder(this, typeSystem, settings).Build(inst), inst.Method.ReturnType);\n\t\t}\n\n\t\tTranslatedExpression WrapInRef(TranslatedExpression expr, IType type)\n\t\t{\n\t\t\tif (type.Kind == TypeKind.ByReference)\n\t\t\t{\n\t\t\t\treturn new DirectionExpression(FieldDirection.Ref, expr.Expression)\n\t\t\t\t\t.WithoutILInstruction()\n\t\t\t\t\t.WithRR(new ByReferenceResolveResult(expr.ResolveResult, ReferenceKind.Ref));\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\n\t\tinternal bool IsCurrentOrContainingType(ITypeDefinition type)\n\t\t{\n\t\t\tvar currentTypeDefinition = decompilationContext.CurrentTypeDefinition;\n\t\t\twhile (currentTypeDefinition != null)\n\t\t\t{\n\t\t\t\tif (type == currentTypeDefinition)\n\t\t\t\t\treturn true;\n\t\t\t\tcurrentTypeDefinition = currentTypeDefinition.DeclaringTypeDefinition;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tinternal bool IsBaseTypeOfCurrentType(ITypeDefinition type)\n\t\t{\n\t\t\treturn decompilationContext.CurrentTypeDefinition.GetAllBaseTypeDefinitions().Any(t => t == type);\n\t\t}\n\n\t\tinternal ExpressionWithResolveResult TranslateFunction(IType delegateType, ILFunction function)\n\t\t{\n\t\t\tvar method = function.Method?.MemberDefinition as IMethod;\n\n\t\t\t// Create AnonymousMethodExpression and prepare parameters\n\t\t\tAnonymousMethodExpression ame = new AnonymousMethodExpression();\n\t\t\tame.IsAsync = function.IsAsync;\n\t\t\tame.Parameters.AddRange(MakeParameters(function.Parameters, function));\n\t\t\tame.HasParameterList = ame.Parameters.Count > 0;\n\t\t\tvar builder = new StatementBuilder(\n\t\t\t\ttypeSystem,\n\t\t\t\tthis.decompilationContext,\n\t\t\t\tfunction,\n\t\t\t\tsettings,\n\t\t\t\tstatementBuilder.decompileRun,\n\t\t\t\tcancellationToken\n\t\t\t);\n\t\t\tvar body = builder.ConvertAsBlock(function.Body);\n\n\t\t\tComment prev = null;\n\t\t\tforeach (string warning in function.Warnings)\n\t\t\t{\n\t\t\t\tbody.InsertChildAfter(prev, prev = new Comment(warning), Roles.Comment);\n\t\t\t}\n\t\t\tvar attributeSections = new List<AttributeSection>();\n\t\t\tforeach (var attr in method?.GetAttributes() ?? Enumerable.Empty<IAttribute>())\n\t\t\t{\n\t\t\t\tif (attr.AttributeType.IsKnownType(KnownAttribute.CompilerGenerated))\n\t\t\t\t\tcontinue;\n\t\t\t\tif (function.IsAsync)\n\t\t\t\t{\n\t\t\t\t\tif (attr.AttributeType.IsKnownType(KnownAttribute.AsyncStateMachine))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tif (attr.AttributeType.IsKnownType(KnownAttribute.DebuggerStepThrough))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tattributeSections.Add(new AttributeSection(astBuilder.ConvertAttribute(attr)));\n\t\t\t}\n\t\t\tforeach (var attr in method?.GetReturnTypeAttributes() ?? Enumerable.Empty<IAttribute>())\n\t\t\t{\n\t\t\t\tattributeSections.Add(new AttributeSection(astBuilder.ConvertAttribute(attr)) { AttributeTarget = \"return\" });\n\t\t\t}\n\n\t\t\tbool isLambda = false;\n\t\t\tif (ame.Parameters.Any(p => p.Type.IsNull))\n\t\t\t{\n\t\t\t\t// if there is an anonymous type involved, we are forced to use a lambda expression.\n\t\t\t\tisLambda = true;\n\t\t\t}\n\t\t\telse if (attributeSections.Count > 0 || ame.Parameters.Any(p => p.Attributes.Any()))\n\t\t\t{\n\t\t\t\t// C# 10 lambdas can have attributes, but anonymous methods cannot\n\t\t\t\tisLambda = true;\n\t\t\t}\n\t\t\telse if (settings.UseLambdaSyntax && ame.Parameters.All(p => p.ParameterModifier == ReferenceKind.None && !p.IsParams))\n\t\t\t{\n\t\t\t\t// otherwise use lambda only if an expression lambda is possible\n\t\t\t\tisLambda = (body.Statements.Count == 1 && body.Statements.Single() is ReturnStatement);\n\t\t\t}\n\t\t\t// Remove the parameter list from an AnonymousMethodExpression if the parameters are not used in the method body\n\t\t\tvar parameterReferencingIdentifiers =\n\t\t\t\tfrom ident in body.Descendants.OfType<IdentifierExpression>()\n\t\t\t\tlet v = ident.GetILVariable()\n\t\t\t\twhere v != null && v.Function == function && v.Kind == VariableKind.Parameter\n\t\t\t\tselect ident;\n\t\t\tif (!isLambda && !parameterReferencingIdentifiers.Any())\n\t\t\t{\n\t\t\t\tame.Parameters.Clear();\n\t\t\t\tame.HasParameterList = false;\n\t\t\t}\n\n\t\t\tExpression replacement;\n\t\t\tIType inferredReturnType;\n\t\t\tif (isLambda)\n\t\t\t{\n\t\t\t\tLambdaExpression lambda = new LambdaExpression();\n\t\t\t\tlambda.Attributes.AddRange(attributeSections);\n\t\t\t\tlambda.IsAsync = ame.IsAsync;\n\t\t\t\tlambda.CopyAnnotationsFrom(ame);\n\t\t\t\tame.Parameters.MoveTo(lambda.Parameters);\n\t\t\t\tif (body.Statements.Count == 1 && body.Statements.Single() is ReturnStatement returnStmt)\n\t\t\t\t{\n\t\t\t\t\tlambda.Body = returnStmt.Expression.Detach();\n\t\t\t\t\tinferredReturnType = lambda.Body.GetResolveResult().Type;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tlambda.Body = body;\n\t\t\t\t\tinferredReturnType = InferReturnType(body);\n\t\t\t\t}\n\t\t\t\treplacement = lambda;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tame.Body = body;\n\t\t\t\tinferredReturnType = InferReturnType(body);\n\t\t\t\treplacement = ame;\n\t\t\t}\n\t\t\tif (ame.IsAsync)\n\t\t\t{\n\t\t\t\tinferredReturnType = GetTaskType(inferredReturnType);\n\t\t\t}\n\n\t\t\tvar rr = new DecompiledLambdaResolveResult(\n\t\t\t\tfunction, delegateType, inferredReturnType,\n\t\t\t\thasParameterList: isLambda || ame.HasParameterList,\n\t\t\t\tisAnonymousMethod: !isLambda,\n\t\t\t\tisImplicitlyTyped: ame.Parameters.Any(p => p.Type.IsNull));\n\n\t\t\tTranslatedExpression translatedLambda = replacement.WithILInstruction(function).WithRR(rr);\n\t\t\treturn new CastExpression(ConvertType(delegateType), translatedLambda)\n\t\t\t\t.WithRR(new ConversionResolveResult(delegateType, rr, LambdaConversion.Instance));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitILFunction(ILFunction function, TranslationContext context)\n\t\t{\n\t\t\treturn TranslateFunction(function.DelegateType, function)\n\t\t\t\t.WithILInstruction(function);\n\t\t}\n\n\t\tIType InferReturnType(BlockStatement body)\n\t\t{\n\t\t\tvar returnExpressions = new List<ResolveResult>();\n\t\t\tCollectReturnExpressions(body);\n\t\t\tvar ti = new TypeInference(compilation, resolver.conversions);\n\t\t\treturn ti.GetBestCommonType(returnExpressions, out _);\n\t\t\t// Failure to infer a return type does not make the lambda invalid,\n\t\t\t// so we can ignore the 'success' value\n\n\t\t\tvoid CollectReturnExpressions(AstNode node)\n\t\t\t{\n\t\t\t\tif (node is ReturnStatement ret)\n\t\t\t\t{\n\t\t\t\t\tif (!ret.Expression.IsNull)\n\t\t\t\t\t{\n\t\t\t\t\t\treturnExpressions.Add(ret.Expression.GetResolveResult());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (node is LambdaExpression || node is AnonymousMethodExpression)\n\t\t\t\t{\n\t\t\t\t\t// do not recurse into nested lambdas\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tforeach (var child in node.Children)\n\t\t\t\t{\n\t\t\t\t\tCollectReturnExpressions(child);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tIType GetTaskType(IType resultType)\n\t\t{\n\t\t\tif (resultType.Kind == TypeKind.Unknown)\n\t\t\t\treturn SpecialType.UnknownType;\n\t\t\tif (resultType.Kind == TypeKind.Void)\n\t\t\t\treturn compilation.FindType(KnownTypeCode.Task);\n\n\t\t\tITypeDefinition def = compilation.FindType(KnownTypeCode.TaskOfT).GetDefinition();\n\t\t\tif (def != null)\n\t\t\t\treturn new ParameterizedType(def, new[] { resultType });\n\t\t\telse\n\t\t\t\treturn SpecialType.UnknownType;\n\t\t}\n\n\t\tIEnumerable<ParameterDeclaration> MakeParameters(IReadOnlyList<IParameter> parameters, ILFunction function)\n\t\t{\n\t\t\tvar variables = function.Variables.Where(v => v.Kind == VariableKind.Parameter).ToDictionary(v => v.Index);\n\t\t\tint i = 0;\n\t\t\tforeach (var parameter in parameters)\n\t\t\t{\n\t\t\t\tvar pd = astBuilder.ConvertParameter(parameter);\n\t\t\t\tif (variables.TryGetValue(i, out var v))\n\t\t\t\t{\n\t\t\t\t\tpd.AddAnnotation(new ILVariableResolveResult(v, parameters[i].Type));\n\t\t\t\t\tpd.Name = v.Name;\n\t\t\t\t}\n\t\t\t\tif (string.IsNullOrEmpty(pd.Name) && !pd.Type.IsArgList())\n\t\t\t\t{\n\t\t\t\t\t// needs to be consistent with logic in ILReader.CreateILVariable\n\t\t\t\t\tpd.Name = \"P_\" + i;\n\t\t\t\t}\n\t\t\t\tif (settings.AnonymousTypes && parameter.Type.ContainsAnonymousType())\n\t\t\t\t\tpd.Type = null;\n\t\t\t\tyield return pd;\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitBlockContainer(BlockContainer container, TranslationContext context)\n\t\t{\n\t\t\tvar oldReturnContainer = statementBuilder.currentReturnContainer;\n\t\t\tvar oldResultType = statementBuilder.currentResultType;\n\t\t\tvar oldIsIterator = statementBuilder.currentIsIterator;\n\n\t\t\tstatementBuilder.currentReturnContainer = container;\n\t\t\tstatementBuilder.currentResultType = context.TypeHint;\n\t\t\tstatementBuilder.currentIsIterator = false;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar body = statementBuilder.ConvertAsBlock(container);\n\t\t\t\tvar comment = new Comment(\" Could not convert BlockContainer to single expression\");\n\t\t\t\tbody.InsertChildAfter(null, comment, Roles.Comment);\n\t\t\t\t// set ILVariable.UsesInitialValue for any variables being used inside the container\n\t\t\t\tforeach (var stloc in container.Descendants.OfType<StLoc>())\n\t\t\t\t\tstloc.Variable.UsesInitialValue = true;\n\t\t\t\tvar ame = new AnonymousMethodExpression { Body = body };\n\t\t\t\tvar systemFuncType = compilation.FindType(typeof(Func<>));\n\t\t\t\tvar blockReturnType = InferReturnType(body);\n\t\t\t\tvar delegateType = new ParameterizedType(systemFuncType, blockReturnType);\n\t\t\t\tvar invocationTarget = new CastExpression(ConvertType(delegateType), ame);\n\t\t\t\tResolveResult rr;\n\t\t\t\t// This might happen when trying to decompile an assembly built for a target framework\n\t\t\t\t// where System.Func<T> does not exist yet.\n\t\t\t\tif (systemFuncType.Kind == TypeKind.Unknown)\n\t\t\t\t{\n\t\t\t\t\trr = new ResolveResult(blockReturnType);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar invokeMethod = delegateType.GetDelegateInvokeMethod();\n\t\t\t\t\trr = new CSharpInvocationResolveResult(\n\t\t\t\t\t\tnew ResolveResult(delegateType),\n\t\t\t\t\t\tinvokeMethod,\n\t\t\t\t\t\tEmptyList<ResolveResult>.Instance);\n\t\t\t\t}\n\t\t\t\treturn new InvocationExpression(new MemberReferenceExpression(invocationTarget, \"Invoke\"))\n\t\t\t\t\t.WithILInstruction(container)\n\t\t\t\t\t.WithRR(rr);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tstatementBuilder.currentReturnContainer = oldReturnContainer;\n\t\t\t\tstatementBuilder.currentResultType = oldResultType;\n\t\t\t\tstatementBuilder.currentIsIterator = oldIsIterator;\n\t\t\t}\n\t\t}\n\n\t\tinternal TranslatedExpression TranslateTarget(ILInstruction target, bool nonVirtualInvocation,\n\t\t\tbool memberStatic, IType memberDeclaringType, IType constrainedTo = null)\n\t\t{\n\t\t\t// If references are missing member.IsStatic might not be set correctly.\n\t\t\t// Additionally check target for null, in order to avoid a crash.\n\t\t\tif (!memberStatic && target != null)\n\t\t\t{\n\t\t\t\tif (ShouldUseBaseReference())\n\t\t\t\t{\n\t\t\t\t\tvar baseReferenceType = resolver.CurrentTypeDefinition.DirectBaseTypes\n\t\t\t\t\t\t.FirstOrDefault(t => t.Kind != TypeKind.Interface);\n\t\t\t\t\treturn new BaseReferenceExpression()\n\t\t\t\t\t\t.WithILInstruction(target)\n\t\t\t\t\t\t.WithRR(new ThisResolveResult(baseReferenceType ?? memberDeclaringType, nonVirtualInvocation));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tIType targetTypeHint = constrainedTo ?? memberDeclaringType;\n\t\t\t\t\tif (CallInstruction.ExpectedTypeForThisPointer(memberDeclaringType, constrainedTo) == StackType.Ref)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (target.ResultType == StackType.Ref)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttargetTypeHint = new ByReferenceType(targetTypeHint);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttargetTypeHint = new PointerType(targetTypeHint);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tvar translatedTarget = Translate(target, targetTypeHint);\n\t\t\t\t\tif (CallInstruction.ExpectedTypeForThisPointer(memberDeclaringType, constrainedTo) == StackType.Ref)\n\t\t\t\t\t{\n\t\t\t\t\t\t// When accessing members on value types, ensure we use a reference of the correct type,\n\t\t\t\t\t\t// and not a pointer or a reference to a different type (issue #1333)\n\t\t\t\t\t\tif (!(translatedTarget.Type is ByReferenceType brt && NormalizeTypeVisitor.TypeErasure.EquivalentTypes(brt.ElementType, constrainedTo ?? memberDeclaringType)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttranslatedTarget = translatedTarget.ConvertTo(new ByReferenceType(constrainedTo ?? memberDeclaringType), this);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (translatedTarget.Expression is DirectionExpression)\n\t\t\t\t\t{\n\t\t\t\t\t\t// (ref x).member => x.member\n\t\t\t\t\t\ttranslatedTarget = translatedTarget.UnwrapChild(((DirectionExpression)translatedTarget).Expression);\n\t\t\t\t\t}\n\t\t\t\t\telse if (translatedTarget.Expression is UnaryOperatorExpression uoe\n\t\t\t\t\t  && uoe.Operator == UnaryOperatorType.NullConditional\n\t\t\t\t\t  && uoe.Expression is DirectionExpression)\n\t\t\t\t\t{\n\t\t\t\t\t\t// (ref x)?.member => x?.member\n\t\t\t\t\t\ttranslatedTarget = translatedTarget.UnwrapChild(((DirectionExpression)uoe.Expression).Expression);\n\t\t\t\t\t\t// note: we need to create a new ResolveResult for the null-conditional operator,\n\t\t\t\t\t\t// using the underlying type of the input expression without the DirectionExpression\n\t\t\t\t\t\ttranslatedTarget = new UnaryOperatorExpression(UnaryOperatorType.NullConditional, translatedTarget)\n\t\t\t\t\t\t\t.WithRR(new ResolveResult(NullableType.GetUnderlyingType(translatedTarget.Type)))\n\t\t\t\t\t\t\t.WithoutILInstruction();\n\t\t\t\t\t}\n\t\t\t\t\ttranslatedTarget = EnsureTargetNotNullable(translatedTarget, target);\n\t\t\t\t\treturn translatedTarget;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new TypeReferenceExpression(ConvertType(constrainedTo ?? memberDeclaringType))\n\t\t\t\t\t.WithoutILInstruction()\n\t\t\t\t\t.WithRR(new TypeResolveResult(constrainedTo ?? memberDeclaringType));\n\t\t\t}\n\n\t\t\tbool ShouldUseBaseReference()\n\t\t\t{\n\t\t\t\tif (!nonVirtualInvocation)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!MatchLdThis(target))\n\t\t\t\t\treturn false;\n\t\t\t\tif ((constrainedTo ?? memberDeclaringType).GetDefinition() == resolver.CurrentTypeDefinition)\n\t\t\t\t\treturn false;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tbool MatchLdThis(ILInstruction inst)\n\t\t\t{\n\t\t\t\t// ldloc this\n\t\t\t\tif (inst.MatchLdThis())\n\t\t\t\t\treturn true;\n\t\t\t\tif (resolver.CurrentTypeDefinition.Kind == TypeKind.Struct)\n\t\t\t\t{\n\t\t\t\t\t// box T(ldobj T(ldloc this))\n\t\t\t\t\tif (!inst.MatchBox(out var arg, out var type))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!arg.MatchLdObj(out var arg2, out var type2))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!type.Equals(type2) || !type.Equals(resolver.CurrentTypeDefinition))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn arg2.MatchLdThis();\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tprivate TranslatedExpression EnsureTargetNotNullable(TranslatedExpression expr, ILInstruction inst)\n\t\t{\n\t\t\t/*\n\t\t\t// TODO Improve nullability support so that we do not sprinkle ! operators everywhere.\n\t\t\t// inst is the instruction that got translated into expr.\n\t\t\tif (expr.Type.Nullability == Nullability.Nullable)\n\t\t\t{\n\t\t\t\tif (expr.Expression is UnaryOperatorExpression uoe && uoe.Operator == UnaryOperatorType.NullConditional)\n\t\t\t\t{\n\t\t\t\t\treturn expr;\n\t\t\t\t}\n\t\t\t\tif (inst.HasFlag(InstructionFlags.MayUnwrapNull))\n\t\t\t\t{\n\t\t\t\t\t// We can't use ! in the chain of operators after a NullConditional, due to\n\t\t\t\t\t// https://github.com/dotnet/roslyn/issues/43659\n\t\t\t\t\treturn expr;\n\t\t\t\t}\n\t\t\t\treturn new UnaryOperatorExpression(UnaryOperatorType.SuppressNullableWarning, expr)\n\t\t\t\t\t.WithRR(new ResolveResult(expr.Type.ChangeNullability(Nullability.Oblivious)))\n\t\t\t\t\t.WithoutILInstruction();\n\t\t\t}\n\t\t\t*/\n\t\t\treturn expr;\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLdObj(LdObj inst, TranslationContext context)\n\t\t{\n\t\t\tIType loadType = inst.Type;\n\t\t\tbool loadTypeUsedInGeneric = inst.UnalignedPrefix != 0 || inst.Target.ResultType == StackType.Ref;\n\t\t\tif (context.TypeHint.Kind != TypeKind.Unknown\n\t\t\t\t&& TypeUtils.IsCompatibleTypeForMemoryAccess(context.TypeHint, loadType)\n\t\t\t\t&& !(loadTypeUsedInGeneric && context.TypeHint.Kind.IsAnyPointer()))\n\t\t\t{\n\t\t\t\tloadType = context.TypeHint;\n\t\t\t}\n\t\t\tif (inst.UnalignedPrefix != 0)\n\t\t\t{\n\t\t\t\t// Use one of: Unsafe.ReadUnaligned<T>(void*)\n\t\t\t\t//         or: Unsafe.ReadUnaligned<T>(ref byte)\n\t\t\t\tvar pointer = Translate(inst.Target);\n\t\t\t\tif (pointer.Expression is DirectionExpression)\n\t\t\t\t{\n\t\t\t\t\tpointer = pointer.ConvertTo(new ByReferenceType(compilation.FindType(KnownTypeCode.Byte)), this);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tpointer = pointer.ConvertTo(new PointerType(compilation.FindType(KnownTypeCode.Void)), this, allowImplicitConversion: true);\n\t\t\t\t}\n\t\t\t\treturn CallUnsafeIntrinsic(\n\t\t\t\t\tname: \"ReadUnaligned\",\n\t\t\t\t\targuments: new Expression[] { pointer },\n\t\t\t\t\treturnType: loadType,\n\t\t\t\t\tinst: inst,\n\t\t\t\t\ttypeArguments: new IType[] { loadType }\n\t\t\t\t);\n\t\t\t}\n\t\t\tvar result = LdObj(inst.Target, loadType);\n\t\t\t//if (target.Type.IsSmallIntegerType() && loadType.IsSmallIntegerType() && target.Type.GetSign() != loadType.GetSign())\n\t\t\t//\treturn result.ConvertTo(loadType, this);\n\t\t\treturn result.WithILInstruction(inst);\n\t\t}\n\n\t\tExpressionWithResolveResult LdObj(ILInstruction address, IType loadType)\n\t\t{\n\t\t\tIType addressTypeHint = address.ResultType == StackType.Ref ? new ByReferenceType(loadType) : (IType)new PointerType(loadType);\n\t\t\tvar target = Translate(address, typeHint: addressTypeHint);\n\t\t\tif (TypeUtils.IsCompatiblePointerTypeForMemoryAccess(target.Type, loadType))\n\t\t\t{\n\t\t\t\tExpressionWithResolveResult result;\n\t\t\t\tif (target.Expression is DirectionExpression dirExpr)\n\t\t\t\t{\n\t\t\t\t\t// we can dereference the managed reference by stripping away the 'ref'\n\t\t\t\t\tresult = target.UnwrapChild(dirExpr.Expression);\n\t\t\t\t}\n\t\t\t\telse if (target.Type is PointerType pointerType)\n\t\t\t\t{\n\t\t\t\t\tif (target.Expression is UnaryOperatorExpression uoe && uoe.Operator == UnaryOperatorType.AddressOf)\n\t\t\t\t\t{\n\t\t\t\t\t\t// We can dereference the pointer by stripping away the '&'\n\t\t\t\t\t\tresult = target.UnwrapChild(uoe.Expression);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// Dereference the existing pointer\n\t\t\t\t\t\tresult = new UnaryOperatorExpression(UnaryOperatorType.Dereference, target.Expression)\n\t\t\t\t\t\t\t.WithRR(new ResolveResult(pointerType.ElementType));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// reference type behind non-DirectionExpression?\n\t\t\t\t\t// this case should be impossible, but we can use a pointer cast\n\t\t\t\t\t// just to make sure\n\t\t\t\t\ttarget = target.ConvertTo(new PointerType(loadType), this);\n\t\t\t\t\treturn new UnaryOperatorExpression(UnaryOperatorType.Dereference, target.Expression)\n\t\t\t\t\t\t.WithRR(new ResolveResult(loadType));\n\t\t\t\t}\n\t\t\t\t// we don't convert result to inst.Type, because the LdObj type\n\t\t\t\t// might be inaccurate (it's often System.Object for all reference types),\n\t\t\t\t// and our parent node should already insert casts where necessary\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// We need to cast the pointer type:\n\t\t\t\tif (target.Expression is DirectionExpression)\n\t\t\t\t{\n\t\t\t\t\ttarget = target.ConvertTo(new ByReferenceType(loadType), this);\n\t\t\t\t}\n\t\t\t\telse if (!loadType.IsUnmanagedType(settings.IntroduceUnmanagedConstraint))\n\t\t\t\t{\n\t\t\t\t\t// Use: Unsafe.Read<T>(void*)\n\t\t\t\t\ttarget = target.ConvertTo(new PointerType(compilation.FindType(KnownTypeCode.Void)), this, allowImplicitConversion: true);\n\t\t\t\t\treturn CallUnsafeIntrinsic(\n\t\t\t\t\t\tname: \"Read\",\n\t\t\t\t\t\targuments: new Expression[] { target },\n\t\t\t\t\t\treturnType: loadType,\n\t\t\t\t\t\ttypeArguments: new IType[] { loadType }\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ttarget = target.ConvertTo(new PointerType(loadType), this);\n\t\t\t\t}\n\t\t\t\tif (target.Expression is DirectionExpression dirExpr)\n\t\t\t\t{\n\t\t\t\t\treturn target.UnwrapChild(dirExpr.Expression);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn new UnaryOperatorExpression(UnaryOperatorType.Dereference, target.Expression)\n\t\t\t\t\t\t.WithRR(new ResolveResult(loadType));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitStObj(StObj inst, TranslationContext context)\n\t\t{\n\t\t\tif (inst.UnalignedPrefix != 0 || (inst.Target.ResultType != StackType.Ref && !inst.Type.IsUnmanagedType(settings.IntroduceUnmanagedConstraint)))\n\t\t\t{\n\t\t\t\treturn StObjViaHelperCall(inst);\n\t\t\t}\n\n\t\t\tIType pointerTypeHint = inst.Target.ResultType == StackType.Ref ? new ByReferenceType(inst.Type) : (IType)new PointerType(inst.Type);\n\t\t\tvar pointer = Translate(inst.Target, typeHint: pointerTypeHint);\n\t\t\tTranslatedExpression target;\n\t\t\tTranslatedExpression value = default;\n\t\t\tIType memoryType;\n\t\t\t// Check if we need to cast to pointer type:\n\t\t\tif (TypeUtils.IsCompatiblePointerTypeForMemoryAccess(pointer.Type, inst.Type))\n\t\t\t{\n\t\t\t\t// cast not necessary, we can use the existing type\n\t\t\t\tmemoryType = ((TypeWithElementType)pointer.Type).ElementType;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// We need to introduce a pointer cast\n\t\t\t\tvalue = Translate(inst.Value, typeHint: inst.Type);\n\t\t\t\tif (TypeUtils.IsCompatibleTypeForMemoryAccess(value.Type, inst.Type))\n\t\t\t\t{\n\t\t\t\t\tmemoryType = value.Type;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tmemoryType = inst.Type;\n\t\t\t\t}\n\t\t\t\tif (pointer.Expression is DirectionExpression)\n\t\t\t\t{\n\t\t\t\t\tpointer = pointer.ConvertTo(new ByReferenceType(memoryType), this);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tpointer = pointer.ConvertTo(new PointerType(memoryType), this);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (pointer.Expression is DirectionExpression)\n\t\t\t{\n\t\t\t\t// we can deference the managed reference by stripping away the 'ref'\n\t\t\t\ttarget = pointer.UnwrapChild(((DirectionExpression)pointer.Expression).Expression);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (pointer.Expression is UnaryOperatorExpression uoe && uoe.Operator == UnaryOperatorType.AddressOf)\n\t\t\t\t{\n\t\t\t\t\t// *&ptr -> ptr\n\t\t\t\t\ttarget = pointer.UnwrapChild(uoe.Expression);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ttarget = new UnaryOperatorExpression(UnaryOperatorType.Dereference, pointer.Expression)\n\t\t\t\t\t\t.WithoutILInstruction()\n\t\t\t\t\t\t.WithRR(new ResolveResult(memoryType));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (value.Expression == null)\n\t\t\t{\n\t\t\t\tvalue = Translate(inst.Value, typeHint: target.Type);\n\t\t\t}\n\t\t\tif (target.Expression is DirectionExpression dirExpr && target.ResolveResult is ByReferenceResolveResult lhsRefRR)\n\t\t\t{\n\t\t\t\t// ref (re-)assignment, emit \"ref (a = ref b)\".\n\t\t\t\ttarget = target.UnwrapChild(dirExpr.Expression);\n\t\t\t\tvalue = value.ConvertTo(lhsRefRR.Type, this, allowImplicitConversion: true);\n\t\t\t\tvar assign = new AssignmentExpression(target.Expression, value.Expression)\n\t\t\t\t\t.WithRR(new OperatorResolveResult(target.Type, ExpressionType.Assign, lhsRefRR, value.ResolveResult));\n\t\t\t\treturn new DirectionExpression(FieldDirection.Ref, assign)\n\t\t\t\t\t.WithoutILInstruction().WithRR(lhsRefRR);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn Assignment(target, value).WithILInstruction(inst);\n\t\t\t}\n\t\t}\n\n\t\tprivate TranslatedExpression StObjViaHelperCall(StObj inst)\n\t\t{\n\t\t\t// \"unaligned.1; stobj\" -> decompile to a call of\n\t\t\t//    Unsafe.WriteUnaligned<T>(void*, T)\n\t\t\t// or Unsafe.WriteUnaligned<T>(ref byte, T)\n\t\t\t// \"stobj ManagedType\" -> decompile to a call of\n\t\t\t//    Unsafe.Write<T>(void*, T)\n\t\t\tvar pointer = Translate(inst.Target);\n\t\t\tvar value = Translate(inst.Value, typeHint: inst.Type);\n\t\t\tif (pointer.Expression is DirectionExpression && inst.UnalignedPrefix != 0)\n\t\t\t{\n\t\t\t\tpointer = pointer.ConvertTo(new ByReferenceType(compilation.FindType(KnownTypeCode.Byte)), this);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tpointer = pointer.ConvertTo(new PointerType(compilation.FindType(KnownTypeCode.Void)), this, allowImplicitConversion: true);\n\t\t\t}\n\t\t\tif (!TypeUtils.IsCompatibleTypeForMemoryAccess(value.Type, inst.Type))\n\t\t\t{\n\t\t\t\tvalue = value.ConvertTo(inst.Type, this);\n\t\t\t}\n\t\t\tif (inst.UnalignedPrefix != 0)\n\t\t\t{\n\t\t\t\treturn CallUnsafeIntrinsic(\n\t\t\t\t\tname: \"WriteUnaligned\",\n\t\t\t\t\targuments: new Expression[] { pointer, value },\n\t\t\t\t\treturnType: compilation.FindType(KnownTypeCode.Void),\n\t\t\t\t\tinst: inst\n\t\t\t\t);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn CallUnsafeIntrinsic(\n\t\t\t\t\tname: \"Write\",\n\t\t\t\t\targuments: new Expression[] { pointer, value },\n\t\t\t\t\treturnType: inst.Type,\n\t\t\t\t\tinst: inst\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLdLen(LdLen inst, TranslationContext context)\n\t\t{\n\t\t\tIType arrayType = compilation.FindType(KnownTypeCode.Array);\n\t\t\tTranslatedExpression arrayExpr = Translate(inst.Array, typeHint: arrayType);\n\t\t\tif (arrayExpr.Type.Kind != TypeKind.Array)\n\t\t\t{\n\t\t\t\tarrayExpr = arrayExpr.ConvertTo(arrayType, this);\n\t\t\t}\n\t\t\tarrayExpr = EnsureTargetNotNullable(arrayExpr, inst.Array);\n\t\t\tstring memberName;\n\t\t\tKnownTypeCode code;\n\t\t\tif (inst.ResultType == StackType.I4)\n\t\t\t{\n\t\t\t\tmemberName = \"Length\";\n\t\t\t\tcode = KnownTypeCode.Int32;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tmemberName = \"LongLength\";\n\t\t\t\tcode = KnownTypeCode.Int64;\n\t\t\t}\n\t\t\tIProperty member = arrayType.GetProperties(p => p.Name == memberName).FirstOrDefault();\n\t\t\tResolveResult rr = member == null\n\t\t\t\t? new ResolveResult(compilation.FindType(code))\n\t\t\t\t: new MemberResolveResult(arrayExpr.ResolveResult, member);\n\t\t\treturn new MemberReferenceExpression(arrayExpr.Expression, memberName)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(rr);\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLdFlda(LdFlda inst, TranslationContext context)\n\t\t{\n\t\t\tif (settings.FixedBuffers && inst.Field.Name == \"FixedElementField\"\n\t\t\t\t&& inst.Target is LdFlda nestedLdFlda\n\t\t\t\t&& CSharpDecompiler.IsFixedField(nestedLdFlda.Field, out var elementType, out _))\n\t\t\t{\n\t\t\t\tExpression fieldAccess = ConvertField(nestedLdFlda.Field, nestedLdFlda.Target);\n\t\t\t\tvar mrr = (MemberResolveResult)fieldAccess.GetResolveResult();\n\t\t\t\tfieldAccess.RemoveAnnotations<ResolveResult>();\n\t\t\t\tvar result = fieldAccess.WithRR(new MemberResolveResult(mrr.TargetResult, mrr.Member, new PointerType(elementType)))\n\t\t\t\t\t.WithILInstruction(inst);\n\t\t\t\tif (inst.ResultType == StackType.Ref)\n\t\t\t\t{\n\t\t\t\t\t// `target.field` has pointer-type.\n\t\t\t\t\tif (inst.SlotInfo == PinnedRegion.InitSlot || inst.Parent is Conv { TargetType: IL.PrimitiveType.U })\n\t\t\t\t\t{\n\t\t\t\t\t\t// Convert pointer to ref if we're in a context where we're going to convert\n\t\t\t\t\t\t// the ref back to a pointer.\n\t\t\t\t\t\treturn result.ConvertTo(new ByReferenceType(elementType), this);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// We can't use `ref *target.field` unless `target` is non-movable,\n\t\t\t\t\t\t// but we can use `ref target.field[0]`.\n\t\t\t\t\t\tvar arrayAccess = new IndexerExpression(result, new PrimitiveExpression(0))\n\t\t\t\t\t\t\t.WithRR(new ResolveResult(elementType));\n\t\t\t\t\t\treturn new DirectionExpression(FieldDirection.Ref, arrayAccess)\n\t\t\t\t\t\t\t.WithoutILInstruction().WithRR(new ByReferenceResolveResult(arrayAccess.ResolveResult, ReferenceKind.Ref));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t}\n\t\t\tTranslatedExpression expr;\n\t\t\tif (TupleTransform.MatchTupleFieldAccess(inst, out IType underlyingTupleType, out var target, out int position))\n\t\t\t{\n\t\t\t\tvar translatedTarget = TranslateTarget(target,\n\t\t\t\t\tnonVirtualInvocation: true,\n\t\t\t\t\tmemberStatic: false,\n\t\t\t\t\tmemberDeclaringType: underlyingTupleType);\n\t\t\t\tif (translatedTarget.Type is TupleType tupleType && NormalizeTypeVisitor.TypeErasure.EquivalentTypes(tupleType, underlyingTupleType) && position <= tupleType.ElementNames.Length)\n\t\t\t\t{\n\t\t\t\t\tstring elementName = tupleType.ElementNames[position - 1];\n\t\t\t\t\tif (elementName == null)\n\t\t\t\t\t{\n\t\t\t\t\t\telementName = \"Item\" + position;\n\t\t\t\t\t}\n\t\t\t\t\t// tupleType.ElementTypes are more accurate w.r.t. nullability/dynamic than inst.Field.Type\n\t\t\t\t\tvar rr = new MemberResolveResult(translatedTarget.ResolveResult, inst.Field,\n\t\t\t\t\t\treturnTypeOverride: tupleType.ElementTypes[position - 1]);\n\t\t\t\t\texpr = new MemberReferenceExpression(translatedTarget, elementName)\n\t\t\t\t\t\t.WithRR(rr).WithILInstruction(inst);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\texpr = ConvertField(inst.Field, inst.Target).WithILInstruction(inst);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\texpr = ConvertField(inst.Field, inst.Target).WithILInstruction(inst);\n\t\t\t}\n\t\t\tif (inst.ResultType == StackType.I)\n\t\t\t{\n\t\t\t\t// ldflda producing native pointer\n\t\t\t\treturn new UnaryOperatorExpression(UnaryOperatorType.AddressOf, expr)\n\t\t\t\t\t.WithoutILInstruction().WithRR(new ResolveResult(new PointerType(expr.Type)));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// ldflda producing managed pointer\n\t\t\t\treturn new DirectionExpression(FieldDirection.Ref, expr)\n\t\t\t\t\t.WithoutILInstruction().WithRR(new ByReferenceResolveResult(expr.ResolveResult, ReferenceKind.Ref));\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLdsFlda(LdsFlda inst, TranslationContext context)\n\t\t{\n\t\t\tvar expr = ConvertField(inst.Field).WithILInstruction(inst);\n\t\t\treturn new DirectionExpression(FieldDirection.Ref, expr)\n\t\t\t\t.WithoutILInstruction().WithRR(new ByReferenceResolveResult(expr.ResolveResult, ReferenceKind.Ref));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLdElema(LdElema inst, TranslationContext context)\n\t\t{\n\t\t\tTranslatedExpression arrayExpr = Translate(inst.Array);\n\t\t\tvar arrayType = arrayExpr.Type as ArrayType;\n\t\t\tif (arrayType == null || !TypeUtils.IsCompatibleTypeForMemoryAccess(arrayType.ElementType, inst.Type))\n\t\t\t{\n\t\t\t\tarrayType = new ArrayType(compilation, inst.Type, inst.Indices.Count);\n\t\t\t\tarrayExpr = arrayExpr.ConvertTo(arrayType, this);\n\t\t\t}\n\t\t\tIndexerExpression indexerExpr;\n\t\t\tif (inst.WithSystemIndex)\n\t\t\t{\n\t\t\t\tvar systemIndex = compilation.FindType(KnownTypeCode.Index);\n\t\t\t\tindexerExpr = new IndexerExpression(\n\t\t\t\t\tarrayExpr, inst.Indices.Select(i => Translate(i, typeHint: systemIndex).ConvertTo(systemIndex, this).Expression)\n\t\t\t\t);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tindexerExpr = new IndexerExpression(\n\t\t\t\t\tarrayExpr, inst.Indices.Select(i => TranslateArrayIndex(i).Expression)\n\t\t\t\t);\n\t\t\t}\n\t\t\tTranslatedExpression expr = indexerExpr.WithILInstruction(inst).WithRR(new ResolveResult(arrayType.ElementType));\n\t\t\treturn new DirectionExpression(FieldDirection.Ref, expr)\n\t\t\t\t.WithoutILInstruction().WithRR(new ByReferenceResolveResult(expr.ResolveResult, ReferenceKind.Ref));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLdElemaInlineArray(LdElemaInlineArray inst, TranslationContext context)\n\t\t{\n\t\t\tTranslatedExpression arrayExpr = TranslateTarget(\n\t\t\t\tinst.Array,\n\t\t\t\tnonVirtualInvocation: true,\n\t\t\t\tmemberStatic: false,\n\t\t\t\tmemberDeclaringType: inst.Type\n\t\t\t);\n\t\t\tvar inlineArrayElementType = inst.Type.GetInlineArrayElementType();\n\t\t\tIndexerExpression indexerExpr = new IndexerExpression(\n\t\t\t\t\tarrayExpr, inst.Indices.Select(i => TranslateArrayIndex(i).Expression)\n\t\t\t);\n\t\t\tTranslatedExpression expr = indexerExpr.WithILInstruction(inst).WithRR(new ResolveResult(inlineArrayElementType));\n\t\t\treturn new DirectionExpression(FieldDirection.Ref, expr)\n\t\t\t\t.WithoutILInstruction().WithRR(new ByReferenceResolveResult(expr.ResolveResult, ReferenceKind.Ref));\n\t\t}\n\n\t\tTranslatedExpression TranslateArrayIndex(ILInstruction i)\n\t\t{\n\t\t\tvar input = Translate(i);\n\t\t\treturn ConvertArrayIndex(input, i.ResultType, allowIntPtr: false);\n\t\t}\n\n\t\tTranslatedExpression ConvertArrayIndex(TranslatedExpression input, StackType stackType, bool allowIntPtr)\n\t\t{\n\t\t\tif (input.Type.GetSize() > stackType.GetSize())\n\t\t\t{\n\t\t\t\t// truncate oversized result\n\t\t\t\treturn input.ConvertTo(FindType(stackType, input.Type.GetSign()), this);\n\t\t\t}\n\t\t\tif (input.Type.IsCSharpPrimitiveIntegerType() || input.Type.IsCSharpNativeIntegerType())\n\t\t\t{\n\t\t\t\t// can be used as array index as-is\n\t\t\t\treturn input;\n\t\t\t}\n\t\t\tif (allowIntPtr && (input.Type.IsKnownType(KnownTypeCode.IntPtr) || input.Type.IsKnownType(KnownTypeCode.UIntPtr)))\n\t\t\t{\n\t\t\t\treturn input;\n\t\t\t}\n\t\t\tif (stackType != StackType.I4 && input.Type.GetStackType() == StackType.I4)\n\t\t\t{\n\t\t\t\t// prefer casting to int if that's big enough\n\t\t\t\tstackType = StackType.I4;\n\t\t\t}\n\t\t\tIType targetType = FindArithmeticType(stackType, input.Type.GetSign());\n\t\t\treturn input.ConvertTo(targetType, this);\n\t\t}\n\n\t\tinternal static bool IsUnboxAnyWithIsInst(UnboxAny unboxAny, IType isInstType)\n\t\t{\n\t\t\treturn unboxAny.Type.Equals(isInstType)\n\t\t\t\t&& (unboxAny.Type.IsKnownType(KnownTypeCode.NullableOfT) || isInstType.IsReferenceType == true);\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitUnboxAny(UnboxAny inst, TranslationContext context)\n\t\t{\n\t\t\tTranslatedExpression arg;\n\t\t\tif (inst.Argument is IsInst isInst && IsUnboxAnyWithIsInst(inst, isInst.Type))\n\t\t\t{\n\t\t\t\t// unbox.any T(isinst T(expr)) ==> expr as T\n\t\t\t\t// This is used for generic types and nullable value types\n\t\t\t\targ = UnwrapBoxingConversion(Translate(isInst.Argument));\n\t\t\t\treturn new AsExpression(arg, ConvertType(inst.Type))\n\t\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t\t.WithRR(new ConversionResolveResult(inst.Type, arg.ResolveResult, Conversion.TryCast));\n\t\t\t}\n\n\t\t\targ = Translate(inst.Argument);\n\t\t\tIType targetType = inst.Type;\n\t\t\tif (targetType.Kind == TypeKind.TypeParameter)\n\t\t\t{\n\t\t\t\tvar rr = resolver.ResolveCast(targetType, arg.ResolveResult);\n\t\t\t\tif (rr.IsError)\n\t\t\t\t{\n\t\t\t\t\t// C# 6.2.7 Explicit conversions involving type parameters:\n\t\t\t\t\t// if we can't directly convert to a type parameter,\n\t\t\t\t\t// try via its effective base class.\n\t\t\t\t\targ = arg.ConvertTo(((ITypeParameter)targetType).EffectiveBaseClass, this);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Before unboxing arg must be a object\n\t\t\t\targ = arg.ConvertTo(compilation.FindType(KnownTypeCode.Object), this);\n\t\t\t}\n\n\t\t\treturn new CastExpression(ConvertType(targetType), arg.Expression)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new ConversionResolveResult(targetType, arg.ResolveResult, Conversion.UnboxingConversion));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitUnbox(Unbox inst, TranslationContext context)\n\t\t{\n\t\t\tvar arg = Translate(inst.Argument);\n\t\t\tvar castExpression = new CastExpression(ConvertType(inst.Type), arg.Expression)\n\t\t\t\t.WithRR(new ConversionResolveResult(inst.Type, arg.ResolveResult, Conversion.UnboxingConversion));\n\t\t\treturn new DirectionExpression(FieldDirection.Ref, castExpression)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new ByReferenceResolveResult(castExpression.ResolveResult, ReferenceKind.Ref));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitBox(Box inst, TranslationContext context)\n\t\t{\n\t\t\tIType targetType = inst.Type;\n\t\t\tvar arg = Translate(inst.Argument, typeHint: targetType);\n\t\t\tif (settings.NativeIntegers && !arg.Type.Equals(targetType))\n\t\t\t{\n\t\t\t\tif (targetType.IsKnownType(KnownTypeCode.IntPtr))\n\t\t\t\t{\n\t\t\t\t\ttargetType = SpecialType.NInt;\n\t\t\t\t}\n\t\t\t\telse if (targetType.IsKnownType(KnownTypeCode.UIntPtr))\n\t\t\t\t{\n\t\t\t\t\ttargetType = SpecialType.NUInt;\n\t\t\t\t}\n\t\t\t}\n\t\t\targ = arg.ConvertTo(targetType, this);\n\t\t\tvar obj = compilation.FindType(KnownTypeCode.Object);\n\t\t\treturn new CastExpression(ConvertType(obj), arg.Expression)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new ConversionResolveResult(obj, arg.ResolveResult, Conversion.BoxingConversion));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitCastClass(CastClass inst, TranslationContext context)\n\t\t{\n\t\t\treturn Translate(inst.Argument).ConvertTo(inst.Type, this);\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitExpressionTreeCast(ExpressionTreeCast inst, TranslationContext context)\n\t\t{\n\t\t\treturn Translate(inst.Argument).ConvertTo(inst.Type, this, inst.IsChecked);\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitArglist(Arglist inst, TranslationContext context)\n\t\t{\n\t\t\treturn new UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.ArgListAccess }\n\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new TypeResolveResult(compilation.FindType(new TopLevelTypeName(\"System\", \"RuntimeArgumentHandle\"))));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitMakeRefAny(MakeRefAny inst, TranslationContext context)\n\t\t{\n\t\t\tvar arg = Translate(inst.Argument).Expression;\n\t\t\tif (arg is DirectionExpression)\n\t\t\t{\n\t\t\t\targ = ((DirectionExpression)arg).Expression;\n\t\t\t}\n\t\t\treturn new UndocumentedExpression {\n\t\t\t\tUndocumentedExpressionType = UndocumentedExpressionType.MakeRef,\n\t\t\t\tArguments = { arg.Detach() }\n\t\t\t}\n\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new TypeResolveResult(compilation.FindType(new TopLevelTypeName(\"System\", \"TypedReference\"))));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitRefAnyType(RefAnyType inst, TranslationContext context)\n\t\t{\n\t\t\treturn new MemberReferenceExpression(new UndocumentedExpression {\n\t\t\t\tUndocumentedExpressionType = UndocumentedExpressionType.RefType,\n\t\t\t\tArguments = { Translate(inst.Argument).Expression.Detach() }\n\t\t\t}, \"TypeHandle\")\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new TypeResolveResult(compilation.FindType(new TopLevelTypeName(\"System\", \"RuntimeTypeHandle\"))));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitRefAnyValue(RefAnyValue inst, TranslationContext context)\n\t\t{\n\t\t\tvar expr = new UndocumentedExpression {\n\t\t\t\tUndocumentedExpressionType = UndocumentedExpressionType.RefValue,\n\t\t\t\tArguments = { Translate(inst.Argument).Expression, new TypeReferenceExpression(ConvertType(inst.Type)) }\n\t\t\t}.WithRR(new ResolveResult(inst.Type));\n\t\t\treturn new DirectionExpression(FieldDirection.Ref, expr.WithILInstruction(inst)).WithoutILInstruction()\n\t\t\t\t.WithRR(new ByReferenceResolveResult(expr.ResolveResult, ReferenceKind.Ref));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitBlock(Block block, TranslationContext context)\n\t\t{\n\t\t\tswitch (block.Kind)\n\t\t\t{\n\t\t\t\tcase BlockKind.ArrayInitializer:\n\t\t\t\t\treturn TranslateArrayInitializer(block);\n\t\t\t\tcase BlockKind.StackAllocInitializer:\n\t\t\t\t\treturn TranslateStackAllocInitializer(block, context.TypeHint);\n\t\t\t\tcase BlockKind.CollectionInitializer:\n\t\t\t\tcase BlockKind.ObjectInitializer:\n\t\t\t\t\treturn TranslateObjectAndCollectionInitializer(block);\n\t\t\t\tcase BlockKind.WithInitializer:\n\t\t\t\t\treturn TranslateWithInitializer(block);\n\t\t\t\tcase BlockKind.CallInlineAssign:\n\t\t\t\t\treturn TranslateSetterCallAssignment(block);\n\t\t\t\tcase BlockKind.CallWithNamedArgs:\n\t\t\t\t\treturn TranslateCallWithNamedArgs(block);\n\t\t\t\tcase BlockKind.InterpolatedString:\n\t\t\t\t\treturn TranslateInterpolatedString(block);\n\t\t\t\tdefault:\n\t\t\t\t\treturn ErrorExpression(\"Unknown block type: \" + block.Kind);\n\t\t\t}\n\t\t}\n\n\t\tprivate TranslatedExpression TranslateInterpolatedString(Block block)\n\t\t{\n\t\t\tvar content = new List<InterpolatedStringContent>();\n\n\t\t\tfor (int i = 1; i < block.Instructions.Count; i++)\n\t\t\t{\n\t\t\t\tvar call = (Call)block.Instructions[i];\n\n\t\t\t\tInterpolation BuildInterpolation(int alignment = 0, string suffix = null)\n\t\t\t\t{\n\t\t\t\t\treturn new Interpolation(Translate(call.Arguments[1]).ConvertTo(call.GetParameter(1).Type, this, allowImplicitConversion: true), alignment, suffix);\n\t\t\t\t}\n\n\t\t\t\tswitch (call.Method.Name)\n\t\t\t\t{\n\t\t\t\t\tcase \"AppendLiteral\":\n\t\t\t\t\t\tcontent.Add(new InterpolatedStringText(((LdStr)call.Arguments[1]).Value.Replace(\"{\", \"{{\").Replace(\"}\", \"}}\")));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"AppendFormatted\" when call.Arguments.Count == 2:\n\t\t\t\t\t\tcontent.Add(BuildInterpolation());\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"AppendFormatted\" when call.Arguments.Count == 3 && call.Arguments[2] is LdStr ldstr:\n\t\t\t\t\t\tcontent.Add(BuildInterpolation(suffix: ldstr.Value));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"AppendFormatted\" when call.Arguments.Count == 3 && call.Arguments[2] is LdcI4 ldci4:\n\t\t\t\t\t\tcontent.Add(BuildInterpolation(alignment: ldci4.Value));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"AppendFormatted\" when call.Arguments.Count == 4 && call.Arguments[2] is LdcI4 ldci4 && call.Arguments[3] is LdStr ldstr:\n\t\t\t\t\t\tcontent.Add(BuildInterpolation(ldci4.Value, ldstr.Value));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new NotSupportedException();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn new InterpolatedStringExpression(content)\n\t\t\t\t.WithILInstruction(block)\n\t\t\t\t.WithRR(new ResolveResult(compilation.FindType(KnownTypeCode.String)));\n\t\t}\n\n\t\tprivate TranslatedExpression TranslateCallWithNamedArgs(Block block)\n\t\t{\n\t\t\treturn WrapInRef(\n\t\t\t\tnew CallBuilder(this, typeSystem, settings).CallWithNamedArgs(block),\n\t\t\t\t((CallInstruction)block.FinalInstruction).Method.ReturnType);\n\t\t}\n\n\t\tprivate TranslatedExpression TranslateSetterCallAssignment(Block block)\n\t\t{\n\t\t\tif (!block.MatchInlineAssignBlock(out var call, out var value))\n\t\t\t{\n\t\t\t\t// should never happen unless the ILAst is invalid\n\t\t\t\treturn ErrorExpression(\"Error: MatchInlineAssignBlock() returned false\");\n\t\t\t}\n\t\t\tvar arguments = call.Arguments.ToList();\n\t\t\targuments[arguments.Count - 1] = value;\n\t\t\treturn new CallBuilder(this, typeSystem, settings)\n\t\t\t\t.Build(call.OpCode, call.Method, arguments)\n\t\t\t\t.WithILInstruction(call);\n\t\t}\n\n\t\tTranslatedExpression TranslateObjectAndCollectionInitializer(Block block)\n\t\t{\n\t\t\tvar stloc = block.Instructions.FirstOrDefault() as StLoc;\n\t\t\tvar final = block.FinalInstruction as LdLoc;\n\t\t\t// Check basic structure of block\n\t\t\tif (stloc == null || final == null || stloc.Variable != final.Variable\n\t\t\t\t|| stloc.Variable.Kind != VariableKind.InitializerTarget)\n\t\t\t\tthrow new ArgumentException(\"given Block is invalid!\");\n\t\t\tInitializedObjectResolveResult initObjRR;\n\t\t\tTranslatedExpression expr;\n\t\t\t// Detect type of initializer\n\t\t\tswitch (stloc.Value)\n\t\t\t{\n\t\t\t\tcase NewObj newObjInst:\n\t\t\t\t\tinitObjRR = new InitializedObjectResolveResult(newObjInst.Method.DeclaringType);\n\t\t\t\t\texpr = new CallBuilder(this, typeSystem, settings).Build(newObjInst);\n\t\t\t\t\tbreak;\n\t\t\t\tcase DefaultValue defaultVal:\n\t\t\t\t\tinitObjRR = new InitializedObjectResolveResult(defaultVal.Type);\n\t\t\t\t\texpr = new ObjectCreateExpression(ConvertType(defaultVal.Type))\n\t\t\t\t\t\t.WithILInstruction(defaultVal)\n\t\t\t\t\t\t.WithRR(new TypeResolveResult(defaultVal.Type));\n\t\t\t\t\tbreak;\n\t\t\t\tcase Block callWithNamedArgs when callWithNamedArgs.Kind == BlockKind.CallWithNamedArgs:\n\t\t\t\t\texpr = TranslateCallWithNamedArgs(callWithNamedArgs);\n\t\t\t\t\tinitObjRR = new InitializedObjectResolveResult(expr.Type);\n\t\t\t\t\tbreak;\n\t\t\t\tcase Call c when c.Method.FullNameIs(\"System.Activator\", \"CreateInstance\") && c.Method.TypeArguments.Count == 1:\n\t\t\t\t\tIType type = c.Method.TypeArguments[0];\n\t\t\t\t\tinitObjRR = new InitializedObjectResolveResult(type);\n\t\t\t\t\texpr = new ObjectCreateExpression(ConvertType(type))\n\t\t\t\t\t\t.WithILInstruction(c)\n\t\t\t\t\t\t.WithRR(new TypeResolveResult(type));\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentException(\"given Block is invalid!\");\n\t\t\t}\n\t\t\tvar oce = (ObjectCreateExpression)expr.Expression;\n\t\t\toce.Initializer = BuildArrayInitializerExpression(block, initObjRR);\n\t\t\treturn expr.WithILInstruction(block);\n\t\t}\n\n\t\tprivate ArrayInitializerExpression BuildArrayInitializerExpression(Block block, InitializedObjectResolveResult initObjRR)\n\t\t{\n\t\t\tvar elementsStack = new Stack<List<TranslatedExpression>>();\n\t\t\tvar elements = new List<TranslatedExpression>(block.Instructions.Count);\n\t\t\telementsStack.Push(elements);\n\t\t\tList<IL.Transforms.AccessPathElement> currentPath = null;\n\t\t\tvar indexVariables = new Dictionary<ILVariable, ILInstruction>();\n\t\t\tforeach (var inst in block.Instructions.Skip(1))\n\t\t\t{\n\t\t\t\t// Collect indexer variables (for C# 6 dictionary initializers)\n\t\t\t\tif (inst is StLoc indexStore)\n\t\t\t\t{\n\t\t\t\t\tindexVariables.Add(indexStore.Variable, indexStore.Value);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// Get current path\n\t\t\t\tvar info = IL.Transforms.AccessPathElement.GetAccessPath(inst, initObjRR.Type, settings: settings);\n\t\t\t\t// This should not happen, because the IL transform should not create invalid access paths,\n\t\t\t\t// but we leave it here as sanity check.\n\t\t\t\tif (info.Kind == IL.Transforms.AccessPathKind.Invalid)\n\t\t\t\t\tcontinue;\n\t\t\t\t// Calculate \"difference\" to previous path\n\t\t\t\tif (currentPath == null)\n\t\t\t\t{\n\t\t\t\t\tcurrentPath = info.Path;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tint minLen = Math.Min(currentPath.Count, info.Path.Count);\n\t\t\t\t\tint firstDifferenceIndex = 0;\n\t\t\t\t\twhile (firstDifferenceIndex < minLen && info.Path[firstDifferenceIndex] == currentPath[firstDifferenceIndex])\n\t\t\t\t\t\tfirstDifferenceIndex++;\n\t\t\t\t\twhile (elementsStack.Count - 1 > firstDifferenceIndex)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar methodElement = currentPath[elementsStack.Count - 1];\n\t\t\t\t\t\tvar pathElement = currentPath[elementsStack.Count - 2];\n\t\t\t\t\t\tvar values = elementsStack.Pop();\n\t\t\t\t\t\telementsStack.Peek().Add(MakeInitializerAssignment(initObjRR, methodElement, pathElement, values, indexVariables));\n\t\t\t\t\t}\n\t\t\t\t\tcurrentPath = info.Path;\n\t\t\t\t}\n\t\t\t\t// Fill the stack with empty expression lists\n\t\t\t\twhile (elementsStack.Count < currentPath.Count)\n\t\t\t\t\telementsStack.Push(new List<TranslatedExpression>());\n\t\t\t\tvar lastElement = currentPath.Last();\n\t\t\t\tvar memberRR = new MemberResolveResult(initObjRR, lastElement.Member);\n\t\t\t\tswitch (info.Kind)\n\t\t\t\t{\n\t\t\t\t\tcase IL.Transforms.AccessPathKind.Adder:\n\t\t\t\t\t\tDebug.Assert(lastElement.Member is IMethod);\n\t\t\t\t\t\telementsStack.Peek().Add(\n\t\t\t\t\t\t\tnew CallBuilder(this, typeSystem, settings)\n\t\t\t\t\t\t\t\t.BuildCollectionInitializerExpression(lastElement.OpCode, (IMethod)lastElement.Member, initObjRR, info.Values)\n\t\t\t\t\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase IL.Transforms.AccessPathKind.Setter:\n\t\t\t\t\t\tDebug.Assert(lastElement.Member is IProperty or IField);\n\t\t\t\t\t\tif (lastElement.Indices?.Length is var indices and > 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar property = (IProperty)lastElement.Member;\n\t\t\t\t\t\t\tDebug.Assert(property.Parameters.Count == indices);\n\t\t\t\t\t\t\tDebug.Assert(property.Setter != null, $\"Indexer property {property} has no setter\");\n\t\t\t\t\t\t\telementsStack.Peek().Add(\n\t\t\t\t\t\t\t\tnew CallBuilder(this, typeSystem, settings)\n\t\t\t\t\t\t\t\t\t.BuildDictionaryInitializerExpression(lastElement.OpCode, property.Setter, initObjRR, GetIndices(lastElement.Indices, indexVariables).ToList(), info.Values.Single())\n\t\t\t\t\t\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar value = Translate(info.Values.Single(), typeHint: memberRR.Type)\n\t\t\t\t\t\t\t\t.ConvertTo(memberRR.Type, this, allowImplicitConversion: true);\n\t\t\t\t\t\t\tvar assignment = new NamedExpression(lastElement.Member.Name, value)\n\t\t\t\t\t\t\t\t.WithILInstruction(inst).WithRR(memberRR);\n\t\t\t\t\t\t\telementsStack.Peek().Add(assignment);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\twhile (elementsStack.Count > 1)\n\t\t\t{\n\t\t\t\tvar methodElement = currentPath[elementsStack.Count - 1];\n\t\t\t\tvar pathElement = currentPath[elementsStack.Count - 2];\n\t\t\t\tvar values = elementsStack.Pop();\n\t\t\t\telementsStack.Peek().Add(\n\t\t\t\t\tMakeInitializerAssignment(initObjRR, methodElement, pathElement, values, indexVariables)\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn new ArrayInitializerExpression(elements.SelectArray(e => e.Expression));\n\t\t}\n\n\t\tIEnumerable<ILInstruction> GetIndices(IEnumerable<ILInstruction> indices, Dictionary<ILVariable, ILInstruction> indexVariables)\n\t\t{\n\t\t\tforeach (var inst in indices)\n\t\t\t{\n\t\t\t\tif (inst is LdLoc ld && indexVariables.TryGetValue(ld.Variable, out var newInst))\n\t\t\t\t\tyield return newInst;\n\t\t\t\telse\n\t\t\t\t\tyield return inst;\n\t\t\t}\n\t\t}\n\n\t\tTranslatedExpression MakeInitializerAssignment(InitializedObjectResolveResult rr, IL.Transforms.AccessPathElement memberPath,\n\t\t\tIL.Transforms.AccessPathElement valuePath, List<TranslatedExpression> values,\n\t\t\tDictionary<ILVariable, ILInstruction> indexVariables)\n\t\t{\n\t\t\tTranslatedExpression value;\n\t\t\tif (memberPath.Member is IMethod method && method.Name == \"Add\")\n\t\t\t{\n\t\t\t\tvalue = new ArrayInitializerExpression(values.Select(v => v.Expression))\n\t\t\t\t\t.WithRR(new ResolveResult(SpecialType.UnknownType))\n\t\t\t\t\t.WithoutILInstruction();\n\t\t\t}\n\t\t\telse if (values.Count == 1 && !(values[0].Expression is AssignmentExpression || values[0].Expression is NamedExpression))\n\t\t\t{\n\t\t\t\tvalue = values[0];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvalue = new ArrayInitializerExpression(values.Select(v => v.Expression))\n\t\t\t\t\t.WithRR(new ResolveResult(SpecialType.UnknownType))\n\t\t\t\t\t.WithoutILInstruction();\n\t\t\t}\n\t\t\tif (valuePath.Indices?.Length > 0)\n\t\t\t{\n\t\t\t\tExpression index = new IndexerExpression(null, GetIndices(valuePath.Indices, indexVariables).Select(i => Translate(i).Expression));\n\t\t\t\treturn new AssignmentExpression(index, value)\n\t\t\t\t\t.WithRR(new MemberResolveResult(rr, valuePath.Member))\n\t\t\t\t\t.WithoutILInstruction();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new NamedExpression(valuePath.Member.Name, value)\n\t\t\t\t\t.WithRR(new MemberResolveResult(rr, valuePath.Member))\n\t\t\t\t\t.WithoutILInstruction();\n\t\t\t}\n\t\t}\n\n\t\tclass ArrayInitializer\n\t\t{\n\t\t\tpublic ArrayInitializer(ArrayInitializerExpression expression)\n\t\t\t{\n\t\t\t\tthis.Expression = expression;\n\t\t\t\tthis.CurrentElementCount = 0;\n\t\t\t}\n\n\t\t\tpublic ArrayInitializerExpression Expression;\n\t\t\t// HACK: avoid using Expression.Elements.Count: https://github.com/icsharpcode/ILSpy/issues/1202\n\t\t\tpublic int CurrentElementCount;\n\t\t}\n\n\t\tTranslatedExpression TranslateArrayInitializer(Block block)\n\t\t{\n\t\t\tvar stloc = block.Instructions.FirstOrDefault() as StLoc;\n\t\t\tvar final = block.FinalInstruction as LdLoc;\n\t\t\tif (stloc == null || final == null || !stloc.Value.MatchNewArr(out IType type))\n\t\t\t\tthrow new ArgumentException(\"given Block is invalid!\");\n\t\t\tif (stloc.Variable != final.Variable || stloc.Variable.Kind != VariableKind.InitializerTarget)\n\t\t\t\tthrow new ArgumentException(\"given Block is invalid!\");\n\t\t\tvar newArr = (NewArr)stloc.Value;\n\n\t\t\tvar translatedDimensions = newArr.Indices.SelectArray(i => Translate(i));\n\n\t\t\tif (!translatedDimensions.All(dim => dim.ResolveResult.IsCompileTimeConstant))\n\t\t\t\tthrow new ArgumentException(\"given Block is invalid!\");\n\t\t\tint dimensions = newArr.Indices.Count;\n\t\t\tint[] dimensionSizes = translatedDimensions.SelectArray(dim => (int)dim.ResolveResult.ConstantValue);\n\t\t\tvar container = new Stack<ArrayInitializer>();\n\t\t\tvar root = new ArrayInitializer(new ArrayInitializerExpression());\n\t\t\tcontainer.Push(root);\n\t\t\tvar elementResolveResults = new List<ResolveResult>();\n\n\t\t\tfor (int i = 1; i < block.Instructions.Count; i++)\n\t\t\t{\n\t\t\t\tif (!block.Instructions[i].MatchStObj(out ILInstruction target, out ILInstruction value, out IType t) || !type.Equals(t))\n\t\t\t\t\tthrow new ArgumentException(\"given Block is invalid!\");\n\t\t\t\tif (!target.MatchLdElema(out t, out ILInstruction array) || !type.Equals(t))\n\t\t\t\t\tthrow new ArgumentException(\"given Block is invalid!\");\n\t\t\t\tif (!array.MatchLdLoc(out ILVariable v) || v != final.Variable)\n\t\t\t\t\tthrow new ArgumentException(\"given Block is invalid!\");\n\t\t\t\twhile (container.Count < dimensions)\n\t\t\t\t{\n\t\t\t\t\tvar aie = new ArrayInitializerExpression();\n\t\t\t\t\tvar parentInitializer = container.Peek();\n\t\t\t\t\tif (parentInitializer.CurrentElementCount > 0)\n\t\t\t\t\t\tparentInitializer.Expression.AddChild(new CSharpTokenNode(TextLocation.Empty, Roles.Comma), Roles.Comma);\n\t\t\t\t\tparentInitializer.Expression.Elements.Add(aie);\n\t\t\t\t\tparentInitializer.CurrentElementCount++;\n\t\t\t\t\tcontainer.Push(new ArrayInitializer(aie));\n\t\t\t\t}\n\t\t\t\tTranslatedExpression val;\n\t\t\t\tvar old = astBuilder.UseSpecialConstants;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tastBuilder.UseSpecialConstants = !type.IsCSharpPrimitiveIntegerType() && !type.IsKnownType(KnownTypeCode.Decimal);\n\t\t\t\t\tval = Translate(value, typeHint: type).ConvertTo(type, this, allowImplicitConversion: true);\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tastBuilder.UseSpecialConstants = old;\n\t\t\t\t}\n\t\t\t\tvar currentInitializer = container.Peek();\n\t\t\t\tif (currentInitializer.CurrentElementCount > 0)\n\t\t\t\t\tcurrentInitializer.Expression.AddChild(new CSharpTokenNode(TextLocation.Empty, Roles.Comma), Roles.Comma);\n\t\t\t\tcurrentInitializer.Expression.Elements.Add(val);\n\t\t\t\tcurrentInitializer.CurrentElementCount++;\n\t\t\t\telementResolveResults.Add(val.ResolveResult);\n\t\t\t\twhile (container.Count > 0 && container.Peek().CurrentElementCount == dimensionSizes[container.Count - 1])\n\t\t\t\t{\n\t\t\t\t\tcontainer.Pop();\n\t\t\t\t}\n\t\t\t}\n\t\t\tArraySpecifier[] additionalSpecifiers;\n\t\t\tAstType typeExpression;\n\t\t\tif (settings.AnonymousTypes && type.ContainsAnonymousType())\n\t\t\t{\n\t\t\t\ttypeExpression = null;\n\t\t\t\tadditionalSpecifiers = new[] { new ArraySpecifier() };\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttypeExpression = ConvertType(type);\n\t\t\t\tif (typeExpression is ComposedType compType && compType.ArraySpecifiers.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tadditionalSpecifiers = compType.ArraySpecifiers.Select(a => (ArraySpecifier)a.Clone()).ToArray();\n\t\t\t\t\tcompType.ArraySpecifiers.Clear();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tadditionalSpecifiers = Empty<ArraySpecifier>.Array;\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar expr = new ArrayCreateExpression {\n\t\t\t\tType = typeExpression,\n\t\t\t\tInitializer = root.Expression\n\t\t\t};\n\t\t\texpr.AdditionalArraySpecifiers.AddRange(additionalSpecifiers);\n\t\t\tif (!type.ContainsAnonymousType())\n\t\t\t\texpr.Arguments.AddRange(newArr.Indices.Select(i => Translate(i).Expression));\n\t\t\treturn expr.WithILInstruction(block)\n\t\t\t\t.WithRR(new ArrayCreateResolveResult(new ArrayType(compilation, type, dimensions), newArr.Indices.Select(i => Translate(i).ResolveResult).ToArray(), elementResolveResults));\n\t\t}\n\n\t\tTranslatedExpression TranslateStackAllocInitializer(Block block, IType typeHint)\n\t\t{\n\t\t\tvar stloc = block.Instructions.FirstOrDefault() as StLoc;\n\t\t\tvar final = block.FinalInstruction as LdLoc;\n\t\t\tif (stloc == null || final == null || stloc.Variable != final.Variable || stloc.Variable.Kind != VariableKind.InitializerTarget)\n\t\t\t\tthrow new ArgumentException(\"given Block is invalid!\");\n\t\t\tStackAllocExpression stackAllocExpression;\n\t\t\tIType elementType;\n\t\t\tif (block.Instructions.Count < 2 || !block.Instructions[1].MatchStObj(out _, out _, out var t))\n\t\t\t\tthrow new ArgumentException(\"given Block is invalid!\");\n\t\t\tif (typeHint is PointerType pt && !TypeUtils.IsCompatibleTypeForMemoryAccess(t, pt.ElementType))\n\t\t\t{\n\t\t\t\ttypeHint = new PointerType(t);\n\t\t\t}\n\t\t\tswitch (stloc.Value)\n\t\t\t{\n\t\t\t\tcase LocAlloc locAlloc:\n\t\t\t\t\tstackAllocExpression = TranslateLocAlloc(locAlloc, typeHint, out elementType);\n\t\t\t\t\tbreak;\n\t\t\t\tcase LocAllocSpan locAllocSpan:\n\t\t\t\t\tstackAllocExpression = TranslateLocAllocSpan(locAllocSpan, typeHint, out elementType);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentException(\"given Block is invalid!\");\n\t\t\t}\n\t\t\tvar initializer = stackAllocExpression.Initializer = new ArrayInitializerExpression();\n\t\t\tvar pointerType = new PointerType(elementType);\n\t\t\tlong expectedOffset = 0;\n\n\t\t\tfor (int i = 1; i < block.Instructions.Count; i++)\n\t\t\t{\n\t\t\t\t// stobj type(binary.add.i(ldloc I_0, conv i4->i <sign extend> (ldc.i4 offset)), value)\n\t\t\t\tif (!block.Instructions[i].MatchStObj(out var target, out var value, out t) || !TypeUtils.IsCompatibleTypeForMemoryAccess(elementType, t))\n\t\t\t\t\tthrow new ArgumentException(\"given Block is invalid!\");\n\t\t\t\tlong offset = 0;\n\t\t\t\ttarget = target.UnwrapConv(ConversionKind.StopGCTracking);\n\n\t\t\t\tif (!target.MatchLdLoc(stloc.Variable))\n\t\t\t\t{\n\t\t\t\t\tif (!target.MatchBinaryNumericInstruction(BinaryNumericOperator.Add, out var left, out var right))\n\t\t\t\t\t\tthrow new ArgumentException(\"given Block is invalid!\");\n\t\t\t\t\tvar binary = (BinaryNumericInstruction)target;\n\t\t\t\t\tleft = left.UnwrapConv(ConversionKind.StopGCTracking);\n\t\t\t\t\tvar offsetInst = PointerArithmeticOffset.Detect(right, pointerType.ElementType, binary.CheckForOverflow);\n\t\t\t\t\tif (!left.MatchLdLoc(final.Variable) || offsetInst == null)\n\t\t\t\t\t\tthrow new ArgumentException(\"given Block is invalid!\");\n\t\t\t\t\tif (!offsetInst.MatchLdcI(out offset))\n\t\t\t\t\t\tthrow new ArgumentException(\"given Block is invalid!\");\n\t\t\t\t}\n\t\t\t\twhile (expectedOffset < offset)\n\t\t\t\t{\n\t\t\t\t\tinitializer.Elements.Add(Translate(IL.Transforms.TransformArrayInitializers.GetNullExpression(elementType), typeHint: elementType));\n\t\t\t\t\texpectedOffset++;\n\t\t\t\t}\n\t\t\t\tvar val = Translate(value, typeHint: elementType).ConvertTo(elementType, this, allowImplicitConversion: true);\n\t\t\t\tinitializer.Elements.Add(val);\n\t\t\t\texpectedOffset++;\n\t\t\t}\n\t\t\treturn stackAllocExpression.WithILInstruction(block)\n\t\t\t\t.WithRR(new ResolveResult(stloc.Variable.Type));\n\t\t}\n\n\t\tTranslatedExpression TranslateWithInitializer(Block block)\n\t\t{\n\t\t\tvar stloc = block.Instructions.FirstOrDefault() as StLoc;\n\t\t\tvar final = block.FinalInstruction as LdLoc;\n\t\t\tif (stloc == null || final == null || stloc.Variable != final.Variable || stloc.Variable.Kind != VariableKind.InitializerTarget)\n\t\t\t\tthrow new ArgumentException(\"given Block is invalid!\");\n\n\t\t\tWithInitializerExpression withInitializerExpression = new WithInitializerExpression();\n\t\t\twithInitializerExpression.Expression = Translate(stloc.Value, stloc.Variable.Type);\n\t\t\twithInitializerExpression.Initializer = BuildArrayInitializerExpression(block, new InitializedObjectResolveResult(stloc.Variable.Type));\n\n\t\t\treturn withInitializerExpression.WithILInstruction(block)\n\t\t\t\t.WithRR(new ResolveResult(stloc.Variable.Type));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// If expr is a constant integer expression, and its value fits into type,\n\t\t/// convert the expression into the target type.\n\t\t/// Otherwise, returns the expression unmodified.\n\t\t/// </summary>\n\t\tTranslatedExpression AdjustConstantExpressionToType(TranslatedExpression expr, IType typeHint)\n\t\t{\n\t\t\tvar newRR = AdjustConstantToType(expr.ResolveResult, typeHint);\n\t\t\tif (newRR == expr.ResolveResult)\n\t\t\t{\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn ConvertConstantValue(newRR, allowImplicitConversion: true).WithILInstruction(expr.ILInstructions);\n\t\t\t}\n\t\t}\n\n\t\tprivate ResolveResult AdjustConstantToType(ResolveResult rr, IType typeHint)\n\t\t{\n\t\t\tif (!rr.IsCompileTimeConstant)\n\t\t\t{\n\t\t\t\treturn rr;\n\t\t\t}\n\t\t\ttypeHint = NullableType.GetUnderlyingType(typeHint);\n\t\t\tif (rr.Type.Equals(typeHint))\n\t\t\t{\n\t\t\t\treturn rr;\n\t\t\t}\n\t\t\t// Convert to type hint, if this is possible without loss of accuracy\n\t\t\tif (typeHint.IsKnownType(KnownTypeCode.Boolean))\n\t\t\t{\n\t\t\t\tif (object.Equals(rr.ConstantValue, 0) || object.Equals(rr.ConstantValue, 0u))\n\t\t\t\t{\n\t\t\t\t\trr = new ConstantResolveResult(typeHint, false);\n\t\t\t\t}\n\t\t\t\telse if (object.Equals(rr.ConstantValue, 1) || object.Equals(rr.ConstantValue, 1u))\n\t\t\t\t{\n\t\t\t\t\trr = new ConstantResolveResult(typeHint, true);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (typeHint.Kind == TypeKind.Enum || typeHint.IsKnownType(KnownTypeCode.Char) || typeHint.IsCSharpSmallIntegerType())\n\t\t\t{\n\t\t\t\tvar castRR = resolver.WithCheckForOverflow(true).ResolveCast(typeHint, rr);\n\t\t\t\tif (castRR.IsCompileTimeConstant && !castRR.IsError)\n\t\t\t\t{\n\t\t\t\t\trr = castRR;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (typeHint.Kind.IsAnyPointer() && (object.Equals(rr.ConstantValue, 0) || object.Equals(rr.ConstantValue, 0u)))\n\t\t\t{\n\t\t\t\trr = new ConstantResolveResult(typeHint, null);\n\t\t\t}\n\t\t\treturn rr;\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitNullCoalescingInstruction(NullCoalescingInstruction inst, TranslationContext context)\n\t\t{\n\t\t\tvar value = Translate(inst.ValueInst);\n\t\t\tvar fallback = Translate(inst.FallbackInst);\n\t\t\tfallback = AdjustConstantExpressionToType(fallback, value.Type);\n\t\t\tvar rr = resolver.ResolveBinaryOperator(BinaryOperatorType.NullCoalescing, value.ResolveResult, fallback.ResolveResult);\n\t\t\tif (rr.IsError)\n\t\t\t{\n\t\t\t\tIType targetType;\n\t\t\t\tif (fallback.Expression is ThrowExpression && fallback.Type.Equals(SpecialType.NoType))\n\t\t\t\t{\n\t\t\t\t\ttargetType = NullableType.GetUnderlyingType(value.Type);\n\t\t\t\t}\n\t\t\t\telse if (!value.Type.Equals(SpecialType.NullType) && !fallback.Type.Equals(SpecialType.NullType) && !value.Type.Equals(fallback.Type))\n\t\t\t\t{\n\t\t\t\t\ttargetType = compilation.FindType(inst.UnderlyingResultType);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ttargetType = value.Type.Equals(SpecialType.NullType) ? fallback.Type : value.Type;\n\t\t\t\t}\n\t\t\t\tif (inst.Kind != NullCoalescingKind.Ref)\n\t\t\t\t{\n\t\t\t\t\tvalue = value.ConvertTo(NullableType.Create(compilation, targetType), this);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvalue = value.ConvertTo(targetType, this);\n\t\t\t\t}\n\t\t\t\tif (inst.Kind == NullCoalescingKind.Nullable)\n\t\t\t\t{\n\t\t\t\t\tvalue = value.ConvertTo(NullableType.Create(compilation, targetType), this);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfallback = fallback.ConvertTo(targetType, this);\n\t\t\t\t}\n\t\t\t\trr = new ResolveResult(targetType);\n\t\t\t}\n\t\t\treturn new BinaryOperatorExpression(value, BinaryOperatorType.NullCoalescing, fallback)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(rr);\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitIfInstruction(IfInstruction inst, TranslationContext context)\n\t\t{\n\t\t\tvar condition = TranslateCondition(inst.Condition);\n\t\t\tvar trueBranch = Translate(inst.TrueInst, typeHint: context.TypeHint);\n\t\t\tvar falseBranch = Translate(inst.FalseInst, typeHint: context.TypeHint);\n\t\t\tBinaryOperatorType op = BinaryOperatorType.Any;\n\t\t\tTranslatedExpression rhs = default(TranslatedExpression);\n\n\t\t\tif (inst.MatchLogicAnd(out var lhsInst, out var rhsInst) && !rhsInst.MatchLdcI4(1))\n\t\t\t{\n\t\t\t\top = BinaryOperatorType.ConditionalAnd;\n\t\t\t\tDebug.Assert(rhsInst == inst.TrueInst);\n\t\t\t\trhs = trueBranch;\n\t\t\t}\n\t\t\telse if (inst.MatchLogicOr(out lhsInst, out rhsInst) && !rhsInst.MatchLdcI4(0))\n\t\t\t{\n\t\t\t\top = BinaryOperatorType.ConditionalOr;\n\t\t\t\tDebug.Assert(rhsInst == inst.FalseInst);\n\t\t\t\trhs = falseBranch;\n\t\t\t}\n\t\t\t// ILAst LogicAnd/LogicOr can return a different value than 0 or 1\n\t\t\t// if the rhs is evaluated.\n\t\t\t// We can only correctly translate it to C# if the rhs is of type boolean:\n\t\t\tif (op != BinaryOperatorType.Any && (rhs.Type.IsKnownType(KnownTypeCode.Boolean) || IfInstruction.IsInConditionSlot(inst)))\n\t\t\t{\n\t\t\t\tif (rhs.Type.GetStackType().GetSize() > 4)\n\t\t\t\t{\n\t\t\t\t\trhs = rhs.ConvertTo(FindType(StackType.I4, rhs.Type.GetSign()), this);\n\t\t\t\t}\n\t\t\t\trhs = rhs.ConvertToBoolean(this);\n\t\t\t\treturn new BinaryOperatorExpression(condition, op, rhs)\n\t\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t\t.WithRR(new ResolveResult(compilation.FindType(KnownTypeCode.Boolean)));\n\t\t\t}\n\n\t\t\tcondition = condition.UnwrapImplicitBoolConversion();\n\t\t\ttrueBranch = AdjustConstantExpressionToType(trueBranch, falseBranch.Type);\n\t\t\tfalseBranch = AdjustConstantExpressionToType(falseBranch, trueBranch.Type);\n\n\t\t\tvar rr = resolver.ResolveConditional(condition.ResolveResult, trueBranch.ResolveResult, falseBranch.ResolveResult);\n\t\t\tif (rr.IsError)\n\t\t\t{\n\t\t\t\tIType targetType;\n\t\t\t\tif (!trueBranch.Type.Equals(SpecialType.NullType) && !falseBranch.Type.Equals(SpecialType.NullType) && !trueBranch.Type.Equals(falseBranch.Type))\n\t\t\t\t{\n\t\t\t\t\ttargetType = typeInference.GetBestCommonType(new[] { trueBranch.ResolveResult, falseBranch.ResolveResult }, out bool success);\n\t\t\t\t\tif (!success || targetType.GetStackType() != inst.ResultType)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Figure out the target type based on inst.ResultType.\n\t\t\t\t\t\tif (context.TypeHint.Kind != TypeKind.Unknown && context.TypeHint.GetStackType() == inst.ResultType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttargetType = context.TypeHint;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (inst.ResultType == StackType.Ref)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// targetType should be a ref-type\n\t\t\t\t\t\t\tif (trueBranch.Type.Kind == TypeKind.ByReference)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttargetType = trueBranch.Type;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (falseBranch.Type.Kind == TypeKind.ByReference)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttargetType = falseBranch.Type;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// fall back to 'ref byte' if we can't determine a referenced type otherwise\n\t\t\t\t\t\t\t\ttargetType = new ByReferenceType(compilation.FindType(KnownTypeCode.Byte));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttargetType = FindType(inst.ResultType, context.TypeHint.GetSign());\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ttargetType = trueBranch.Type.Equals(SpecialType.NullType) ? falseBranch.Type : trueBranch.Type;\n\t\t\t\t}\n\t\t\t\ttrueBranch = trueBranch.ConvertTo(targetType, this);\n\t\t\t\tfalseBranch = falseBranch.ConvertTo(targetType, this);\n\t\t\t\trr = new ResolveResult(targetType);\n\t\t\t}\n\t\t\tif (rr.Type.Kind == TypeKind.ByReference)\n\t\t\t{\n\t\t\t\t// C# conditional ref looks like this:\n\t\t\t\t// ref (arr != null ? ref trueBranch : ref falseBranch);\n\t\t\t\tvar conditionalResolveResult = new ResolveResult(((ByReferenceType)rr.Type).ElementType);\n\t\t\t\treturn new DirectionExpression(FieldDirection.Ref,\n\t\t\t\t\tnew ConditionalExpression(condition.Expression, trueBranch.Expression, falseBranch.Expression)\n\t\t\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t\t\t.WithRR(conditionalResolveResult)\n\t\t\t\t).WithoutILInstruction().WithRR(new ByReferenceResolveResult(conditionalResolveResult, ReferenceKind.Ref));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new ConditionalExpression(condition.Expression, trueBranch.Expression, falseBranch.Expression)\n\t\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t\t.WithRR(rr);\n\t\t\t}\n\t\t}\n\n\t\tinternal (TranslatedExpression, IType, StringToInt) TranslateSwitchValue(SwitchInstruction inst, bool isExpressionContext)\n\t\t{\n\t\t\tTranslatedExpression value;\n\t\t\tIType governingType;\n\t\t\t// prepare expression and expected type\n\t\t\t// first try to guess a governing type\n\t\t\tif (inst.Value is StringToInt strToInt)\n\t\t\t{\n\t\t\t\tvalue = Translate(strToInt.Argument);\n\t\t\t\tgoverningType = strToInt.ExpectedType ?? compilation.FindType(KnownTypeCode.String);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tstrToInt = null;\n\t\t\t\tvalue = Translate(inst.Value);\n\t\t\t\tgoverningType = inst.Type ?? value.Type;\n\n\t\t\t\t// validate the governing type\n\t\t\t\tif (inst.Value.ResultType == StackType.I8)\n\t\t\t\t{\n\t\t\t\t\tif (governingType.GetStackType() != StackType.I8)\n\t\t\t\t\t\tgoverningType = FindType(StackType.I8, governingType.GetSign());\n\t\t\t\t}\n\t\t\t\telse if (inst.Value.ResultType == StackType.I4)\n\t\t\t\t{\n\t\t\t\t\tif (governingType.GetStackType() != StackType.I4)\n\t\t\t\t\t\tgoverningType = FindType(StackType.I4, governingType.GetSign());\n\t\t\t\t\tif (governingType.IsSmallIntegerType())\n\t\t\t\t\t{\n\t\t\t\t\t\tvar defaultSection = inst.GetDefaultSection();\n\t\t\t\t\t\tint bits = 8 * governingType.GetSize();\n\t\t\t\t\t\tint minValue = governingType.GetSign() == Sign.Unsigned ? 0 : -(1 << (bits - 1));\n\t\t\t\t\t\tint maxValue = governingType.GetSign() == Sign.Unsigned ? (1 << bits) - 1 : (1 << (bits - 1)) - 1;\n\t\t\t\t\t\tforeach (var section in inst.Sections)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (section == defaultSection)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\tLongInterval interval = section.Labels.ContainingInterval();\n\t\t\t\t\t\t\tif (interval.Start < minValue || interval.InclusiveEnd > maxValue)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// governing type is too small to hold all case values\n\t\t\t\t\t\t\t\tgoverningType = FindType(StackType.I4, Sign.Signed);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(inst.Value.ResultType == StackType.O);\n\t\t\t\t\tDebug.Assert(inst.IsLifted);\n\t\t\t\t\tDebug.Assert(inst.Type == governingType);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isExpressionContext)\n\t\t\t{\n\t\t\t\tvalue = value.ConvertTo(governingType, this, allowImplicitConversion: false);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvalue = value.ConvertTo(governingType, this, allowImplicitConversion: true);\n\n\t\t\t\tvar csharpGoverningType = GetCSharpSwitchGoverningType(value.Type);\n\t\t\t\tif (!csharpGoverningType.Equals(governingType))\n\t\t\t\t{\n\t\t\t\t\tvalue = value.ConvertTo(governingType, this, allowImplicitConversion: false);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar caseType = strToInt != null\n\t\t\t\t? compilation.FindType(KnownTypeCode.String)\n\t\t\t\t: governingType;\n\n\t\t\treturn (value, caseType, strToInt);\n\t\t}\n\n\t\tstatic IType GetCSharpSwitchGoverningType(IType type)\n\t\t{\n\t\t\tif (IsCompatibleWithSwitch(type))\n\t\t\t\treturn type;\n\n\t\t\tvar applicableImplicitConversionOperators = type.GetMethods(IsImplicitConversionOperator)\n\t\t\t\t.Where(m => IsCompatibleWithSwitch(m.ReturnType))\n\t\t\t\t.ToArray();\n\t\t\tif (applicableImplicitConversionOperators.Length != 1)\n\t\t\t\treturn type;\n\t\t\treturn applicableImplicitConversionOperators[0].ReturnType;\n\n\t\t\tstatic bool IsImplicitConversionOperator(IMethod operatorMethod)\n\t\t\t{\n\t\t\t\tif (!operatorMethod.IsOperator)\n\t\t\t\t\treturn false;\n\t\t\t\tif (operatorMethod.Name != \"op_Implicit\")\n\t\t\t\t\treturn false;\n\t\t\t\tif (operatorMethod.Parameters.Count != 1)\n\t\t\t\t\treturn false;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tstatic bool IsCompatibleWithSwitch(IType type)\n\t\t\t{\n\t\t\t\ttype = NullableType.GetUnderlyingType(type);\n\t\t\t\treturn type.IsKnownType(KnownTypeCode.Boolean)\n\t\t\t\t\t|| type.IsKnownType(KnownTypeCode.SByte)\n\t\t\t\t\t|| type.IsKnownType(KnownTypeCode.Byte)\n\t\t\t\t\t|| type.IsKnownType(KnownTypeCode.Int16)\n\t\t\t\t\t|| type.IsKnownType(KnownTypeCode.UInt16)\n\t\t\t\t\t|| type.IsKnownType(KnownTypeCode.Int32)\n\t\t\t\t\t|| type.IsKnownType(KnownTypeCode.UInt32)\n\t\t\t\t\t|| type.IsKnownType(KnownTypeCode.Int64)\n\t\t\t\t\t|| type.IsKnownType(KnownTypeCode.UInt64)\n\t\t\t\t\t|| type.IsKnownType(KnownTypeCode.Char)\n\t\t\t\t\t|| type.IsKnownType(KnownTypeCode.String);\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitSwitchInstruction(SwitchInstruction inst, TranslationContext context)\n\t\t{\n\t\t\t// switch-expression does not support implicit conversions\n\t\t\tvar (value, type, strToInt) = TranslateSwitchValue(inst, true);\n\n\t\t\tIL.SwitchSection defaultSection = inst.GetDefaultSection();\n\t\t\tSwitchExpression switchExpr = new SwitchExpression();\n\t\t\tswitchExpr.Expression = value;\n\t\t\tIType resultType;\n\t\t\tif (context.TypeHint.Kind != TypeKind.Unknown && context.TypeHint.GetStackType() == inst.ResultType)\n\t\t\t{\n\t\t\t\tresultType = context.TypeHint;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tresultType = compilation.FindType(inst.ResultType);\n\t\t\t}\n\n\t\t\tforeach (var section in inst.Sections)\n\t\t\t{\n\t\t\t\tif (section == defaultSection)\n\t\t\t\t\tcontinue;\n\t\t\t\tvar ses = new SwitchExpressionSection();\n\t\t\t\tif (section.HasNullLabel)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(section.Labels.IsEmpty);\n\t\t\t\t\tses.Pattern = new NullReferenceExpression();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tlong val = section.Labels.Values.Single();\n\t\t\t\t\tvar rr = statementBuilder.CreateTypedCaseLabel(val, type, strToInt?.Map).Single();\n\t\t\t\t\tses.Pattern = astBuilder.ConvertConstantValue(rr);\n\t\t\t\t}\n\t\t\t\tses.Body = TranslateSectionBody(section);\n\t\t\t\tswitchExpr.SwitchSections.Add(ses);\n\t\t\t}\n\n\t\t\tvar defaultSES = new SwitchExpressionSection();\n\t\t\tdefaultSES.Pattern = new IdentifierExpression(\"_\");\n\t\t\tdefaultSES.Body = TranslateSectionBody(defaultSection);\n\t\t\tswitchExpr.SwitchSections.Add(defaultSES);\n\n\t\t\treturn switchExpr.WithILInstruction(inst).WithRR(new ResolveResult(resultType));\n\n\t\t\tExpression TranslateSectionBody(IL.SwitchSection section)\n\t\t\t{\n\t\t\t\tvar body = Translate(section.Body, resultType);\n\t\t\t\treturn body.ConvertTo(resultType, this, allowImplicitConversion: true);\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitAddressOf(AddressOf inst, TranslationContext context)\n\t\t{\n\t\t\tvar classification = ILInlining.ClassifyExpression(inst.Value);\n\t\t\tvar value = Translate(inst.Value, inst.Type);\n\t\t\tvalue = value.ConvertTo(inst.Type, this);\n\t\t\t// ILAst AddressOf copies the value to a temporary, but when invoking a method in C#\n\t\t\t// on a mutable lvalue, we would end up modifying the original lvalue, not just the copy.\n\t\t\t// We solve this by introducing a \"redundant\" cast. Casts are classified as rvalue\n\t\t\t// and ensure that the C# compiler will also create a copy.\n\t\t\tif (classification == ExpressionClassification.MutableLValue\n\t\t\t\t&& !CanIgnoreCopy()\n\t\t\t\t&& value.Expression is not CastExpression)\n\t\t\t{\n\t\t\t\tvalue = new CastExpression(ConvertType(inst.Type), value.Expression)\n\t\t\t\t\t.WithoutILInstruction()\n\t\t\t\t\t.WithRR(new ConversionResolveResult(inst.Type, value.ResolveResult, Conversion.IdentityConversion));\n\t\t\t}\n\t\t\treturn new DirectionExpression(FieldDirection.Ref, value)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new ByReferenceResolveResult(value.ResolveResult, ReferenceKind.Ref));\n\n\t\t\tbool CanIgnoreCopy()\n\t\t\t{\n\t\t\t\tILInstruction loadAddress = inst;\n\t\t\t\twhile (loadAddress.Parent is LdFlda parent)\n\t\t\t\t{\n\t\t\t\t\tloadAddress = parent;\n\t\t\t\t}\n\t\t\t\tif (loadAddress.Parent is LdObj)\n\t\t\t\t{\n\t\t\t\t\t// Ignore copy, never introduce a cast\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitAwait(Await inst, TranslationContext context)\n\t\t{\n\t\t\tIType expectedType = null;\n\t\t\tif (inst.GetAwaiterMethod != null)\n\t\t\t{\n\t\t\t\tif (inst.GetAwaiterMethod.IsStatic)\n\t\t\t\t{\n\t\t\t\t\texpectedType = inst.GetAwaiterMethod.Parameters.FirstOrDefault()?.Type;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\texpectedType = inst.GetAwaiterMethod.DeclaringType;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar value = Translate(inst.Value, typeHint: expectedType);\n\t\t\tif (value.Expression is DirectionExpression)\n\t\t\t{\n\t\t\t\t// we can deference the managed reference by stripping away the 'ref'\n\t\t\t\tvalue = value.UnwrapChild(((DirectionExpression)value.Expression).Expression);\n\t\t\t}\n\t\t\tif (expectedType != null)\n\t\t\t{\n\t\t\t\tvalue = value.ConvertTo(expectedType, this, allowImplicitConversion: true);\n\t\t\t}\n\t\t\treturn new UnaryOperatorExpression(UnaryOperatorType.Await, value.Expression)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new ResolveResult(inst.GetResultMethod?.ReturnType ?? SpecialType.UnknownType));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitNullableRewrap(NullableRewrap inst, TranslationContext context)\n\t\t{\n\t\t\tvar arg = Translate(inst.Argument);\n\t\t\tIType type = arg.Type;\n\t\t\tif (NullableType.IsNonNullableValueType(type))\n\t\t\t{\n\t\t\t\ttype = NullableType.Create(compilation, type);\n\t\t\t}\n\t\t\treturn new UnaryOperatorExpression(UnaryOperatorType.NullConditionalRewrap, arg)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new ResolveResult(type));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitNullableUnwrap(NullableUnwrap inst, TranslationContext context)\n\t\t{\n\t\t\tvar arg = Translate(inst.Argument);\n\t\t\tif (inst.RefInput && !inst.RefOutput && arg.Expression is DirectionExpression dir)\n\t\t\t{\n\t\t\t\targ = arg.UnwrapChild(dir.Expression);\n\t\t\t}\n\t\t\treturn new UnaryOperatorExpression(UnaryOperatorType.NullConditional, arg)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new ResolveResult(NullableType.GetUnderlyingType(arg.Type)));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitDynamicConvertInstruction(DynamicConvertInstruction inst, TranslationContext context)\n\t\t{\n\t\t\tvar operand = Translate(inst.Argument).ConvertTo(SpecialType.Dynamic, this);\n\t\t\tvar result = new CastExpression(ConvertType(inst.Type), operand)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new ConversionResolveResult(\n\t\t\t\t\tinst.Type, operand.ResolveResult,\n\t\t\t\t\tinst.IsExplicit ? Conversion.ExplicitDynamicConversion : Conversion.ImplicitDynamicConversion\n\t\t\t\t));\n\t\t\tresult.Expression.AddAnnotation(inst.IsChecked ? AddCheckedBlocks.CheckedAnnotation : AddCheckedBlocks.UncheckedAnnotation);\n\t\t\treturn result;\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitDynamicGetIndexInstruction(DynamicGetIndexInstruction inst, TranslationContext context)\n\t\t{\n\t\t\tvar target = TranslateDynamicTarget(inst.Arguments[0], inst.ArgumentInfo[0]);\n\t\t\tvar arguments = TranslateDynamicArguments(inst.Arguments.Skip(1), inst.ArgumentInfo.Skip(1)).ToList();\n\t\t\treturn new IndexerExpression(target, arguments.Select(a => a.Expression))\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new DynamicInvocationResolveResult(target.ResolveResult, DynamicInvocationType.Indexing, arguments.Select(a => a.ResolveResult).ToArray()));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitDynamicGetMemberInstruction(DynamicGetMemberInstruction inst, TranslationContext context)\n\t\t{\n\t\t\tvar target = TranslateDynamicTarget(inst.Target, inst.TargetArgumentInfo);\n\t\t\treturn new MemberReferenceExpression(target, inst.Name)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new DynamicMemberResolveResult(target.ResolveResult, inst.Name));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitDynamicInvokeConstructorInstruction(DynamicInvokeConstructorInstruction inst, TranslationContext context)\n\t\t{\n\t\t\tif (!(inst.ArgumentInfo[0].HasFlag(CSharpArgumentInfoFlags.IsStaticType) && IL.Transforms.TransformExpressionTrees.MatchGetTypeFromHandle(inst.Arguments[0], out var constructorType)))\n\t\t\t\treturn ErrorExpression(\"Could not detect static type for DynamicInvokeConstructorInstruction\");\n\t\t\tvar arguments = TranslateDynamicArguments(inst.Arguments.Skip(1), inst.ArgumentInfo.Skip(1)).ToList();\n\t\t\t//var names = inst.ArgumentInfo.Skip(1).Select(a => a.Name).ToArray();\n\t\t\treturn new ObjectCreateExpression(ConvertType(constructorType), arguments.Select(a => a.Expression))\n\t\t\t\t.WithILInstruction(inst).WithRR(new ResolveResult(constructorType));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitDynamicInvokeMemberInstruction(DynamicInvokeMemberInstruction inst, TranslationContext context)\n\t\t{\n\t\t\tExpression targetExpr;\n\t\t\tvar target = TranslateDynamicTarget(inst.Arguments[0], inst.ArgumentInfo[0]);\n\t\t\tif (inst.BinderFlags.HasFlag(CSharpBinderFlags.InvokeSimpleName) && target.Expression is ThisReferenceExpression)\n\t\t\t{\n\t\t\t\ttargetExpr = new IdentifierExpression(inst.Name);\n\t\t\t\t((IdentifierExpression)targetExpr).TypeArguments.AddRange(inst.TypeArguments.Select(ConvertType));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttargetExpr = new MemberReferenceExpression(target, inst.Name, inst.TypeArguments.Select(ConvertType));\n\t\t\t}\n\t\t\tvar arguments = TranslateDynamicArguments(inst.Arguments.Skip(1), inst.ArgumentInfo.Skip(1)).ToList();\n\t\t\treturn new InvocationExpression(targetExpr, arguments.Select(a => a.Expression))\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new DynamicInvocationResolveResult(target.ResolveResult, DynamicInvocationType.Invocation, arguments.Select(a => a.ResolveResult).ToArray()));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitDynamicInvokeInstruction(DynamicInvokeInstruction inst, TranslationContext context)\n\t\t{\n\t\t\tvar target = TranslateDynamicTarget(inst.Arguments[0], inst.ArgumentInfo[0]);\n\t\t\tvar arguments = TranslateDynamicArguments(inst.Arguments.Skip(1), inst.ArgumentInfo.Skip(1)).ToList();\n\t\t\treturn new InvocationExpression(target, arguments.Select(a => a.Expression))\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new DynamicInvocationResolveResult(target.ResolveResult, DynamicInvocationType.Invocation, arguments.Select(a => a.ResolveResult).ToArray()));\n\t\t}\n\n\t\tTranslatedExpression TranslateDynamicTarget(ILInstruction inst, CSharpArgumentInfo argumentInfo)\n\t\t{\n\t\t\tDebug.Assert(!argumentInfo.HasFlag(CSharpArgumentInfoFlags.NamedArgument));\n\t\t\tDebug.Assert(!argumentInfo.HasFlag(CSharpArgumentInfoFlags.IsOut));\n\n\t\t\tif (argumentInfo.HasFlag(CSharpArgumentInfoFlags.IsStaticType) && IL.Transforms.TransformExpressionTrees.MatchGetTypeFromHandle(inst, out var callTargetType))\n\t\t\t{\n\t\t\t\treturn new TypeReferenceExpression(ConvertType(callTargetType))\n\t\t\t\t\t.WithoutILInstruction()\n\t\t\t\t\t.WithRR(new TypeResolveResult(callTargetType));\n\t\t\t}\n\n\t\t\tIType targetType = SpecialType.Dynamic;\n\t\t\tif (argumentInfo.HasFlag(CSharpArgumentInfoFlags.UseCompileTimeType))\n\t\t\t{\n\t\t\t\ttargetType = argumentInfo.CompileTimeType;\n\t\t\t}\n\n\t\t\tvar translatedTarget = Translate(inst, targetType).ConvertTo(targetType, this);\n\n\t\t\tif (argumentInfo.HasFlag(CSharpArgumentInfoFlags.IsRef) && translatedTarget.Expression is DirectionExpression)\n\t\t\t{\n\t\t\t\t// (ref x).member => x.member\n\t\t\t\ttranslatedTarget = translatedTarget.UnwrapChild(((DirectionExpression)translatedTarget).Expression);\n\t\t\t}\n\n\t\t\treturn translatedTarget;\n\t\t}\n\n\t\tIEnumerable<TranslatedExpression> TranslateDynamicArguments(IEnumerable<ILInstruction> arguments, IEnumerable<CSharpArgumentInfo> argumentInfo)\n\t\t{\n\t\t\tforeach (var (argument, info) in arguments.Zip(argumentInfo))\n\t\t\t{\n\t\t\t\tyield return TranslateDynamicArgument(argument, info);\n\t\t\t}\n\t\t}\n\n\t\tTranslatedExpression TranslateDynamicArgument(ILInstruction argument, CSharpArgumentInfo info)\n\t\t{\n\t\t\tDebug.Assert(!info.HasFlag(CSharpArgumentInfoFlags.IsStaticType));\n\n\t\t\tIType typeHint = SpecialType.Dynamic;\n\t\t\tif (info.HasFlag(CSharpArgumentInfoFlags.UseCompileTimeType))\n\t\t\t{\n\t\t\t\ttypeHint = info.CompileTimeType;\n\t\t\t}\n\t\t\tvar translatedExpression = Translate(argument, typeHint);\n\t\t\tif (!(typeHint.Equals(SpecialType.Dynamic) && translatedExpression.Type.Equals(SpecialType.NullType)))\n\t\t\t{\n\t\t\t\ttranslatedExpression = translatedExpression.ConvertTo(typeHint, this);\n\t\t\t}\n\t\t\tif (info.HasFlag(CSharpArgumentInfoFlags.IsOut))\n\t\t\t{\n\t\t\t\ttranslatedExpression = ChangeDirectionExpressionTo(translatedExpression, ReferenceKind.Out, argument is AddressOf);\n\t\t\t}\n\t\t\tif (info.HasFlag(CSharpArgumentInfoFlags.NamedArgument) && !string.IsNullOrWhiteSpace(info.Name))\n\t\t\t{\n\t\t\t\ttranslatedExpression = new TranslatedExpression(new NamedArgumentExpression(info.Name, translatedExpression.Expression));\n\t\t\t}\n\n\t\t\treturn translatedExpression;\n\t\t}\n\n\t\tinternal static TranslatedExpression ChangeDirectionExpressionTo(TranslatedExpression input, ReferenceKind kind, bool isAddressOf)\n\t\t{\n\t\t\tif (!(input.Expression is DirectionExpression dirExpr && input.ResolveResult is ByReferenceResolveResult brrr))\n\t\t\t\treturn input;\n\t\t\tif (isAddressOf && kind is ReferenceKind.In or ReferenceKind.RefReadOnly)\n\t\t\t{\n\t\t\t\treturn input.UnwrapChild(dirExpr.Expression);\n\t\t\t}\n\t\t\tdirExpr.FieldDirection = kind switch {\n\t\t\t\tReferenceKind.Ref => FieldDirection.Ref,\n\t\t\t\tReferenceKind.Out => FieldDirection.Out,\n\t\t\t\tReferenceKind.In => FieldDirection.In,\n\t\t\t\tReferenceKind.RefReadOnly => FieldDirection.In,\n\t\t\t\t_ => throw new NotSupportedException(\"Unsupported reference kind: \" + kind)\n\t\t\t};\n\t\t\tdirExpr.RemoveAnnotations<ByReferenceResolveResult>();\n\t\t\tif (brrr.ElementResult == null)\n\t\t\t\tbrrr = new ByReferenceResolveResult(brrr.ElementType, kind);\n\t\t\telse\n\t\t\t\tbrrr = new ByReferenceResolveResult(brrr.ElementResult, kind);\n\t\t\tdirExpr.AddAnnotation(brrr);\n\t\t\treturn new TranslatedExpression(dirExpr);\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitDynamicSetIndexInstruction(DynamicSetIndexInstruction inst, TranslationContext context)\n\t\t{\n\t\t\tDebug.Assert(inst.Arguments.Count >= 3);\n\t\t\tvar target = TranslateDynamicTarget(inst.Arguments[0], inst.ArgumentInfo[0]);\n\t\t\tvar arguments = TranslateDynamicArguments(inst.Arguments.Skip(1), inst.ArgumentInfo.Skip(1)).ToList();\n\t\t\tvar value = new TranslatedExpression(arguments.Last());\n\t\t\tvar indexer = new IndexerExpression(target, arguments.SkipLast(1).Select(a => a.Expression))\n\t\t\t\t.WithoutILInstruction()\n\t\t\t\t.WithRR(new DynamicInvocationResolveResult(target.ResolveResult, DynamicInvocationType.Indexing, arguments.SkipLast(1).Select(a => a.ResolveResult).ToArray()));\n\t\t\treturn Assignment(indexer, value).WithILInstruction(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitDynamicSetMemberInstruction(DynamicSetMemberInstruction inst, TranslationContext context)\n\t\t{\n\t\t\tvar target = TranslateDynamicTarget(inst.Target, inst.TargetArgumentInfo);\n\t\t\tvar value = TranslateDynamicArgument(inst.Value, inst.ValueArgumentInfo);\n\t\t\tvar member = new MemberReferenceExpression(target, inst.Name)\n\t\t\t\t.WithoutILInstruction()\n\t\t\t\t.WithRR(new DynamicMemberResolveResult(target.ResolveResult, inst.Name));\n\t\t\treturn Assignment(member, value).WithILInstruction(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitDynamicBinaryOperatorInstruction(DynamicBinaryOperatorInstruction inst, TranslationContext context)\n\t\t{\n\t\t\tswitch (inst.Operation)\n\t\t\t{\n\t\t\t\tcase ExpressionType.Add:\n\t\t\t\tcase ExpressionType.AddAssign:\n\t\t\t\t\treturn CreateBinaryOperator(BinaryOperatorType.Add, isChecked: inst.BinderFlags.HasFlag(CSharpBinderFlags.CheckedContext));\n\t\t\t\tcase ExpressionType.AddChecked:\n\t\t\t\tcase ExpressionType.AddAssignChecked:\n\t\t\t\t\treturn CreateBinaryOperator(BinaryOperatorType.Add, isChecked: true);\n\t\t\t\tcase ExpressionType.Subtract:\n\t\t\t\tcase ExpressionType.SubtractAssign:\n\t\t\t\t\treturn CreateBinaryOperator(BinaryOperatorType.Subtract, isChecked: inst.BinderFlags.HasFlag(CSharpBinderFlags.CheckedContext));\n\t\t\t\tcase ExpressionType.SubtractChecked:\n\t\t\t\tcase ExpressionType.SubtractAssignChecked:\n\t\t\t\t\treturn CreateBinaryOperator(BinaryOperatorType.Subtract, isChecked: true);\n\t\t\t\tcase ExpressionType.Multiply:\n\t\t\t\tcase ExpressionType.MultiplyAssign:\n\t\t\t\t\treturn CreateBinaryOperator(BinaryOperatorType.Multiply, isChecked: inst.BinderFlags.HasFlag(CSharpBinderFlags.CheckedContext));\n\t\t\t\tcase ExpressionType.MultiplyChecked:\n\t\t\t\tcase ExpressionType.MultiplyAssignChecked:\n\t\t\t\t\treturn CreateBinaryOperator(BinaryOperatorType.Multiply, isChecked: true);\n\t\t\t\tcase ExpressionType.Divide:\n\t\t\t\tcase ExpressionType.DivideAssign:\n\t\t\t\t\treturn CreateBinaryOperator(BinaryOperatorType.Divide);\n\t\t\t\tcase ExpressionType.Modulo:\n\t\t\t\tcase ExpressionType.ModuloAssign:\n\t\t\t\t\treturn CreateBinaryOperator(BinaryOperatorType.Modulus);\n\t\t\t\tcase ExpressionType.Equal:\n\t\t\t\t\treturn CreateBinaryOperator(BinaryOperatorType.Equality);\n\t\t\t\tcase ExpressionType.NotEqual:\n\t\t\t\t\treturn CreateBinaryOperator(BinaryOperatorType.InEquality);\n\t\t\t\tcase ExpressionType.LessThan:\n\t\t\t\t\treturn CreateBinaryOperator(BinaryOperatorType.LessThan);\n\t\t\t\tcase ExpressionType.LessThanOrEqual:\n\t\t\t\t\treturn CreateBinaryOperator(BinaryOperatorType.LessThanOrEqual);\n\t\t\t\tcase ExpressionType.GreaterThan:\n\t\t\t\t\treturn CreateBinaryOperator(BinaryOperatorType.GreaterThan);\n\t\t\t\tcase ExpressionType.GreaterThanOrEqual:\n\t\t\t\t\treturn CreateBinaryOperator(BinaryOperatorType.GreaterThanOrEqual);\n\t\t\t\tcase ExpressionType.And:\n\t\t\t\tcase ExpressionType.AndAssign:\n\t\t\t\t\treturn CreateBinaryOperator(BinaryOperatorType.BitwiseAnd);\n\t\t\t\tcase ExpressionType.Or:\n\t\t\t\tcase ExpressionType.OrAssign:\n\t\t\t\t\treturn CreateBinaryOperator(BinaryOperatorType.BitwiseOr);\n\t\t\t\tcase ExpressionType.ExclusiveOr:\n\t\t\t\tcase ExpressionType.ExclusiveOrAssign:\n\t\t\t\t\treturn CreateBinaryOperator(BinaryOperatorType.ExclusiveOr);\n\t\t\t\tcase ExpressionType.LeftShift:\n\t\t\t\tcase ExpressionType.LeftShiftAssign:\n\t\t\t\t\treturn CreateBinaryOperator(BinaryOperatorType.ShiftLeft);\n\t\t\t\tcase ExpressionType.RightShift:\n\t\t\t\tcase ExpressionType.RightShiftAssign:\n\t\t\t\t\treturn CreateBinaryOperator(BinaryOperatorType.ShiftRight);\n\t\t\t\tdefault:\n\t\t\t\t\treturn base.VisitDynamicBinaryOperatorInstruction(inst, context);\n\t\t\t}\n\n\t\t\tTranslatedExpression CreateBinaryOperator(BinaryOperatorType operatorType, bool? isChecked = null)\n\t\t\t{\n\t\t\t\tvar left = TranslateDynamicArgument(inst.Left, inst.LeftArgumentInfo);\n\t\t\t\tvar right = TranslateDynamicArgument(inst.Right, inst.RightArgumentInfo);\n\t\t\t\tvar boe = new BinaryOperatorExpression(left.Expression, operatorType, right.Expression);\n\t\t\t\tif (isChecked == true)\n\t\t\t\t\tboe.AddAnnotation(AddCheckedBlocks.CheckedAnnotation);\n\t\t\t\telse if (isChecked == false)\n\t\t\t\t\tboe.AddAnnotation(AddCheckedBlocks.UncheckedAnnotation);\n\t\t\t\treturn boe.WithILInstruction(inst).WithRR(new ResolveResult(SpecialType.Dynamic));\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitDynamicLogicOperatorInstruction(DynamicLogicOperatorInstruction inst, TranslationContext context)\n\t\t{\n\t\t\tBinaryOperatorType operatorType;\n\t\t\tif (inst.Operation == ExpressionType.AndAlso)\n\t\t\t{\n\t\t\t\toperatorType = BinaryOperatorType.ConditionalAnd;\n\t\t\t}\n\t\t\telse if (inst.Operation == ExpressionType.OrElse)\n\t\t\t{\n\t\t\t\toperatorType = BinaryOperatorType.ConditionalOr;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDebug.Fail(\"Unknown operation for DynamicLogicOperatorInstruction\");\n\t\t\t\treturn base.VisitDynamicLogicOperatorInstruction(inst, context);\n\t\t\t}\n\t\t\tvar left = TranslateDynamicArgument(inst.Left, inst.LeftArgumentInfo);\n\t\t\tvar right = TranslateDynamicArgument(inst.Right, inst.RightArgumentInfo);\n\t\t\tvar boe = new BinaryOperatorExpression(left.Expression, operatorType, right.Expression);\n\t\t\treturn boe.WithILInstruction(inst).WithRR(new ResolveResult(SpecialType.Dynamic));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitDynamicUnaryOperatorInstruction(DynamicUnaryOperatorInstruction inst, TranslationContext context)\n\t\t{\n\t\t\tswitch (inst.Operation)\n\t\t\t{\n\t\t\t\tcase ExpressionType.Not:\n\t\t\t\t\treturn CreateUnaryOperator(UnaryOperatorType.Not);\n\t\t\t\tcase ExpressionType.Decrement:\n\t\t\t\t\treturn CreateUnaryOperator(UnaryOperatorType.Decrement, isChecked: inst.BinderFlags.HasFlag(CSharpBinderFlags.CheckedContext));\n\t\t\t\tcase ExpressionType.Increment:\n\t\t\t\t\treturn CreateUnaryOperator(UnaryOperatorType.Increment, isChecked: inst.BinderFlags.HasFlag(CSharpBinderFlags.CheckedContext));\n\t\t\t\tcase ExpressionType.Negate:\n\t\t\t\t\treturn CreateUnaryOperator(UnaryOperatorType.Minus, isChecked: inst.BinderFlags.HasFlag(CSharpBinderFlags.CheckedContext));\n\t\t\t\tcase ExpressionType.NegateChecked:\n\t\t\t\t\treturn CreateUnaryOperator(UnaryOperatorType.Minus, isChecked: true);\n\t\t\t\tcase ExpressionType.UnaryPlus:\n\t\t\t\t\treturn CreateUnaryOperator(UnaryOperatorType.Plus, isChecked: inst.BinderFlags.HasFlag(CSharpBinderFlags.CheckedContext));\n\t\t\t\tcase ExpressionType.IsTrue:\n\t\t\t\t\tvar operand = TranslateDynamicArgument(inst.Operand, inst.OperandArgumentInfo);\n\t\t\t\t\tExpression expr;\n\t\t\t\t\tif (inst.SlotInfo == IfInstruction.ConditionSlot)\n\t\t\t\t\t{\n\t\t\t\t\t\t// We rely on the context implicitly invoking \"operator true\".\n\t\t\t\t\t\texpr = new UnaryOperatorExpression(UnaryOperatorType.IsTrue, operand);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// Create a dummy conditional to ensure \"operator true\" will be invoked.\n\t\t\t\t\t\texpr = new ConditionalExpression(operand, new PrimitiveExpression(true), new PrimitiveExpression(false));\n\t\t\t\t\t}\n\t\t\t\t\treturn expr.WithILInstruction(inst)\n\t\t\t\t\t\t.WithRR(new ResolveResult(compilation.FindType(KnownTypeCode.Boolean)));\n\t\t\t\tcase ExpressionType.IsFalse:\n\t\t\t\t\toperand = TranslateDynamicArgument(inst.Operand, inst.OperandArgumentInfo);\n\t\t\t\t\t// Create a dummy conditional to ensure \"operator false\" will be invoked.\n\t\t\t\t\texpr = new ConditionalExpression(operand, new PrimitiveExpression(false), new PrimitiveExpression(true));\n\t\t\t\t\treturn expr.WithILInstruction(inst)\n\t\t\t\t\t\t.WithRR(new ResolveResult(compilation.FindType(KnownTypeCode.Boolean)));\n\t\t\t\tdefault:\n\t\t\t\t\treturn base.VisitDynamicUnaryOperatorInstruction(inst, context);\n\t\t\t}\n\n\t\t\tTranslatedExpression CreateUnaryOperator(UnaryOperatorType operatorType, bool? isChecked = null)\n\t\t\t{\n\t\t\t\tvar operand = TranslateDynamicArgument(inst.Operand, inst.OperandArgumentInfo);\n\t\t\t\tvar uoe = new UnaryOperatorExpression(operatorType, operand.Expression);\n\t\t\t\tif (isChecked == true)\n\t\t\t\t\tuoe.AddAnnotation(AddCheckedBlocks.CheckedAnnotation);\n\t\t\t\telse if (isChecked == false)\n\t\t\t\t\tuoe.AddAnnotation(AddCheckedBlocks.UncheckedAnnotation);\n\t\t\t\treturn uoe.WithILInstruction(inst).WithRR(new ResolveResult(SpecialType.Dynamic));\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitDynamicCompoundAssign(DynamicCompoundAssign inst, TranslationContext context)\n\t\t{\n\t\t\tExpressionWithResolveResult target;\n\t\t\tif (inst.TargetKind == CompoundTargetKind.Address)\n\t\t\t{\n\t\t\t\ttarget = LdObj(inst.Target, SpecialType.Dynamic);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttarget = TranslateDynamicArgument(inst.Target, inst.TargetArgumentInfo);\n\t\t\t}\n\t\t\tvar value = TranslateDynamicArgument(inst.Value, inst.ValueArgumentInfo);\n\n\t\t\tvar ae = new AssignmentExpression(target, AssignmentExpression.GetAssignmentOperatorTypeFromExpressionType(inst.Operation).Value, value);\n\t\t\tif (inst.BinderFlags.HasFlag(CSharpBinderFlags.CheckedContext))\n\t\t\t\tae.AddAnnotation(AddCheckedBlocks.CheckedAnnotation);\n\t\t\telse\n\t\t\t\tae.AddAnnotation(AddCheckedBlocks.UncheckedAnnotation);\n\t\t\treturn ae.WithILInstruction(inst)\n\t\t\t\t.WithRR(new OperatorResolveResult(SpecialType.Dynamic, inst.Operation, new[] { target.ResolveResult, value.ResolveResult }));\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLdFtn(LdFtn inst, TranslationContext context)\n\t\t{\n\t\t\tExpressionWithResolveResult delegateRef = new CallBuilder(this, typeSystem, settings).BuildMethodReference(inst.Method, isVirtual: false);\n\t\t\tif (!inst.Method.IsStatic)\n\t\t\t{\n\t\t\t\t// C# 9 function pointers don't support instance methods\n\t\t\t\treturn new InvocationExpression(new IdentifierExpression(\"__ldftn\"), delegateRef)\n\t\t\t\t\t.WithRR(new ResolveResult(new PointerType(compilation.FindType(KnownTypeCode.Void))))\n\t\t\t\t\t.WithILInstruction(inst);\n\t\t\t}\n\t\t\t// C# 9 function pointer\n\t\t\tSignatureCallingConvention callingConvention = SignatureCallingConvention.Default;\n\t\t\tImmutableArray<IType> customCallingConventions;\n\t\t\tvar unmanagedCallersOnlyAttribute = inst.Method.GetAttributes().FirstOrDefault(m => m.AttributeType.IsKnownType(KnownAttribute.UnmanagedCallersOnly));\n\t\t\tif (unmanagedCallersOnlyAttribute != null)\n\t\t\t{\n\t\t\t\tcallingConvention = SignatureCallingConvention.Unmanaged;\n\n\t\t\t\tvar callingConventionsArgument = unmanagedCallersOnlyAttribute.NamedArguments.FirstOrDefault(a => a.Name == \"CallConvs\");\n\t\t\t\tif (callingConventionsArgument.Value is ImmutableArray<CustomAttributeTypedArgument<IType>> array)\n\t\t\t\t{\n\t\t\t\t\tvar builder = ImmutableArray.CreateBuilder<IType>(array.Length);\n\t\t\t\t\tforeach (var type in array.Select(a => a.Value).OfType<IType>())\n\t\t\t\t\t{\n\t\t\t\t\t\tSignatureCallingConvention? foundCallingConvention = type.Namespace is not \"System.Runtime.CompilerServices\" || callingConvention != SignatureCallingConvention.Unmanaged ? null : type.Name switch {\n\t\t\t\t\t\t\t\"CallConvCdecl\" => SignatureCallingConvention.CDecl,\n\t\t\t\t\t\t\t\"CallConvFastcall\" => SignatureCallingConvention.FastCall,\n\t\t\t\t\t\t\t\"CallConvStdcall\" => SignatureCallingConvention.StdCall,\n\t\t\t\t\t\t\t\"CallConvThiscall\" => SignatureCallingConvention.ThisCall,\n\t\t\t\t\t\t\t_ => null,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (foundCallingConvention is not null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcallingConvention = foundCallingConvention.Value;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbuilder.Add(type);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcustomCallingConventions = builder.ToImmutable();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcustomCallingConventions = [];\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tcallingConvention = SignatureCallingConvention.Default;\n\t\t\t\tcustomCallingConventions = [];\n\t\t\t}\n\t\t\tvar ftp = new FunctionPointerType(\n\t\t\t\ttypeSystem.MainModule,\n\t\t\t\tcallingConvention, customCallingConventions,\n\t\t\t\tinst.Method.ReturnType, inst.Method.ReturnTypeIsRefReadOnly,\n\t\t\t\tinst.Method.Parameters.SelectImmutableArray(p => p.Type),\n\t\t\t\tinst.Method.Parameters.SelectImmutableArray(p => p.ReferenceKind)\n\t\t\t);\n\t\t\tExpressionWithResolveResult addressOf = new UnaryOperatorExpression(\n\t\t\t\tUnaryOperatorType.AddressOf,\n\t\t\t\tdelegateRef\n\t\t\t).WithRR(new ResolveResult(SpecialType.NoType)).WithILInstruction(inst);\n\t\t\tvar conversion = Conversion.MethodGroupConversion(\n\t\t\t\tinst.Method, isVirtualMethodLookup: false, delegateCapturesFirstArgument: false);\n\t\t\treturn new CastExpression(ConvertType(ftp), addressOf)\n\t\t\t\t.WithRR(new ConversionResolveResult(ftp, addressOf.ResolveResult, conversion))\n\t\t\t\t.WithoutILInstruction();\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitLdVirtFtn(LdVirtFtn inst, TranslationContext context)\n\t\t{\n\t\t\t// C# 9 function pointers don't support instance methods\n\t\t\tExpressionWithResolveResult delegateRef = new CallBuilder(this, typeSystem, settings).BuildMethodReference(inst.Method, isVirtual: true);\n\t\t\treturn new InvocationExpression(new IdentifierExpression(\"__ldvirtftn\"), delegateRef)\n\t\t\t\t.WithRR(new ResolveResult(new PointerType(compilation.FindType(KnownTypeCode.Void))))\n\t\t\t\t.WithILInstruction(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitCallIndirect(CallIndirect inst, TranslationContext context)\n\t\t{\n\t\t\tif (inst.IsInstance)\n\t\t\t{\n\t\t\t\treturn ErrorExpression(\"calli with instance method signature not supportd\");\n\t\t\t}\n\n\t\t\tvar functionPointer = Translate(inst.FunctionPointer, typeHint: inst.FunctionPointerType);\n\t\t\tif (!NormalizeTypeVisitor.TypeErasure.EquivalentTypes(functionPointer.Type, inst.FunctionPointerType))\n\t\t\t{\n\t\t\t\tfunctionPointer = functionPointer.ConvertTo(inst.FunctionPointerType, this);\n\t\t\t}\n\t\t\tvar fpt = (FunctionPointerType)functionPointer.Type.SkipModifiers();\n\t\t\tvar invocation = new InvocationExpression();\n\t\t\tinvocation.Target = functionPointer;\n\t\t\tforeach (var (argInst, (paramType, paramRefKind)) in inst.Arguments.Zip(fpt.ParameterTypes.Zip(fpt.ParameterReferenceKinds)))\n\t\t\t{\n\t\t\t\tvar arg = Translate(argInst, typeHint: paramType).ConvertTo(paramType, this, allowImplicitConversion: true);\n\t\t\t\tif (paramRefKind != ReferenceKind.None)\n\t\t\t\t{\n\t\t\t\t\targ = ChangeDirectionExpressionTo(arg, paramRefKind, argInst is AddressOf);\n\t\t\t\t}\n\t\t\t\tinvocation.Arguments.Add(arg);\n\t\t\t}\n\t\t\tif (fpt.ReturnType.SkipModifiers() is ByReferenceType brt)\n\t\t\t{\n\t\t\t\tvar rr = new ResolveResult(brt.ElementType);\n\t\t\t\treturn new DirectionExpression(\n\t\t\t\t\tFieldDirection.Ref,\n\t\t\t\t\tinvocation.WithRR(rr).WithILInstruction(inst)\n\t\t\t\t).WithRR(new ByReferenceResolveResult(rr, ReferenceKind.Ref)).WithoutILInstruction();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn invocation.WithRR(new ResolveResult(fpt.ReturnType)).WithILInstruction(inst);\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitDeconstructInstruction(DeconstructInstruction inst, TranslationContext context)\n\t\t{\n\t\t\tIType rhsType = inst.Pattern.Variable.Type;\n\t\t\tvar rhs = Translate(inst.Pattern.TestedOperand, rhsType);\n\t\t\trhs = rhs.ConvertTo(rhsType, this); // TODO allowImplicitConversion\n\t\t\tvar assignments = inst.Assignments.Instructions;\n\t\t\tint assignmentPos = 0;\n\t\t\tvar inits = inst.Init;\n\t\t\tint initPos = 0;\n\n\t\t\tDictionary<ILVariable, ILVariable> conversionMapping = new Dictionary<ILVariable, ILVariable>();\n\n\t\t\tforeach (var conv in inst.Conversions.Instructions)\n\t\t\t{\n\t\t\t\tif (!DeconstructInstruction.IsConversionStLoc(conv, out var outputVariable, out var inputVariable))\n\t\t\t\t\tcontinue;\n\t\t\t\tconversionMapping.Add(inputVariable, outputVariable);\n\t\t\t}\n\n\t\t\tvar lhs = ConstructTuple(inst.Pattern);\n\t\t\treturn new AssignmentExpression(lhs, rhs)\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t\t.WithRR(new ResolveResult(compilation.FindType(KnownTypeCode.Void)));\n\n\t\t\tTupleExpression ConstructTuple(MatchInstruction matchInstruction)\n\t\t\t{\n\t\t\t\tvar expr = new TupleExpression();\n\t\t\t\tforeach (var subPattern in matchInstruction.SubPatterns.Cast<MatchInstruction>())\n\t\t\t\t{\n\t\t\t\t\tif (subPattern.IsVar)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (subPattern.HasDesignator)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!conversionMapping.TryGetValue(subPattern.Variable, out ILVariable value))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvalue = subPattern.Variable;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\texpr.Elements.Add(ConstructAssignmentTarget(assignments[assignmentPos], value));\n\t\t\t\t\t\t\tassignmentPos++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\texpr.Elements.Add(new IdentifierExpression(\"_\"));\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\texpr.Elements.Add(ConstructTuple(subPattern));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\texpr.AddAnnotation(matchInstruction);\n\t\t\t\treturn expr;\n\t\t\t}\n\n\t\t\tTranslatedExpression ConstructAssignmentTarget(ILInstruction assignment, ILVariable value)\n\t\t\t{\n\t\t\t\tswitch (assignment)\n\t\t\t\t{\n\t\t\t\t\tcase StLoc stloc:\n\t\t\t\t\t\tDebug.Assert(stloc.Value.MatchLdLoc(value));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase CallInstruction call:\n\t\t\t\t\t\tfor (int i = 0; i < call.Arguments.Count - 1; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tReplaceAssignmentTarget(call.Arguments[i]);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tDebug.Assert(call.Arguments.Last().MatchLdLoc(value));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase StObj stobj:\n\t\t\t\t\t\tvar target = stobj.Target;\n\t\t\t\t\t\twhile (target.MatchLdFlda(out var nestedTarget, out _))\n\t\t\t\t\t\t\ttarget = nestedTarget;\n\t\t\t\t\t\tReplaceAssignmentTarget(target);\n\t\t\t\t\t\tDebug.Assert(stobj.Value.MatchLdLoc(value));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new NotSupportedException();\n\t\t\t\t}\n\t\t\t\tvar expr = Translate(assignment);\n\t\t\t\treturn expr.UnwrapChild(((AssignmentExpression)expr).Left);\n\t\t\t}\n\n\t\t\tvoid ReplaceAssignmentTarget(ILInstruction target)\n\t\t\t{\n\t\t\t\tif (target.MatchLdLoc(out var v)\n\t\t\t\t\t&& v.Kind == VariableKind.DeconstructionInitTemporary)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(inits[initPos].Variable == v);\n\t\t\t\t\ttarget.ReplaceWith(inits[initPos].Value);\n\t\t\t\t\tinitPos++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitMatchInstruction(MatchInstruction inst, TranslationContext context)\n\t\t{\n\t\t\tvar left = Translate(inst.TestedOperand);\n\t\t\t// remove boxing conversion if possible, however, we still need a cast in\n\t\t\t// test case PatternMatching.GenericValueTypePatternStringRequiresCastToObject\n\t\t\tif (left.ResolveResult is ConversionResolveResult crr\n\t\t\t\t&& crr.Conversion.IsBoxingConversion\n\t\t\t\t&& left.Expression is CastExpression castExpr\n\t\t\t\t&& (crr.Input.Type.IsReferenceType != false || inst.Variable.Type.IsReferenceType == false))\n\t\t\t{\n\t\t\t\tleft = left.UnwrapChild(castExpr.Expression);\n\t\t\t}\n\t\t\tvar right = TranslatePattern(inst, left.Type);\n\n\t\t\treturn new BinaryOperatorExpression(left, BinaryOperatorType.IsPattern, right)\n\t\t\t\t.WithRR(new ResolveResult(compilation.FindType(KnownTypeCode.Boolean)))\n\t\t\t\t.WithILInstruction(inst);\n\t\t}\n\n\t\tExpressionWithILInstruction TranslatePattern(ILInstruction pattern, IType leftHandType)\n\t\t{\n\t\t\tswitch (pattern)\n\t\t\t{\n\t\t\t\tcase MatchInstruction matchInstruction:\n\t\t\t\t\tif (matchInstruction.IsDeconstructCall)\n\t\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t\tif (matchInstruction.IsDeconstructTuple)\n\t\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t\tif (matchInstruction.SubPatterns.Count > 0 || (matchInstruction.CheckNotNull && !matchInstruction.CheckType))\n\t\t\t\t\t{\n\t\t\t\t\t\tRecursivePatternExpression recursivePatternExpression = new();\n\t\t\t\t\t\tif (matchInstruction.CheckType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\trecursivePatternExpression.Type = ConvertType(matchInstruction.Variable.Type);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tDebug.Assert(matchInstruction.CheckNotNull || matchInstruction.Variable.Type.IsReferenceType == false);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tforeach (var subPattern in matchInstruction.SubPatterns)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!MatchInstruction.IsPatternMatch(subPattern, out var testedOperand, settings))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tDebug.Fail(\"Invalid sub pattern\");\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tIMember member;\n\t\t\t\t\t\t\tif (testedOperand is CallInstruction call)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmember = call.Method.AccessorOwner;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (testedOperand.MatchLdFld(out _, out var f))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmember = f;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tDebug.Fail(\"Invalid sub pattern\");\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\trecursivePatternExpression.SubPatterns.Add(\n\t\t\t\t\t\t\t\tnew NamedArgumentExpression { Name = member.Name, Expression = TranslatePattern(subPattern, member.ReturnType) }\n\t\t\t\t\t\t\t\t\t.WithRR(new MemberResolveResult(null, member))\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (matchInstruction.HasDesignator)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tSingleVariableDesignation designator = new SingleVariableDesignation { Identifier = matchInstruction.Variable.Name };\n\t\t\t\t\t\t\tdesignator.AddAnnotation(new ILVariableResolveResult(matchInstruction.Variable));\n\t\t\t\t\t\t\trecursivePatternExpression.Designation = designator;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn recursivePatternExpression.WithILInstruction(matchInstruction);\n\t\t\t\t\t}\n\t\t\t\t\telse if (matchInstruction.HasDesignator || !matchInstruction.CheckType)\n\t\t\t\t\t{\n\t\t\t\t\t\tSingleVariableDesignation designator = new SingleVariableDesignation { Identifier = matchInstruction.Variable.Name };\n\t\t\t\t\t\tdesignator.AddAnnotation(new ILVariableResolveResult(matchInstruction.Variable));\n\t\t\t\t\t\tAstType type;\n\t\t\t\t\t\tif (matchInstruction.CheckType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype = ConvertType(matchInstruction.Variable.Type);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tDebug.Assert(matchInstruction.IsVar);\n\t\t\t\t\t\t\ttype = new SimpleType(\"var\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn new DeclarationExpression {\n\t\t\t\t\t\t\tType = type,\n\t\t\t\t\t\t\tDesignation = designator\n\t\t\t\t\t\t}.WithILInstruction(matchInstruction);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(matchInstruction.CheckType);\n\t\t\t\t\t\treturn new TypeReferenceExpression(ConvertType(matchInstruction.Variable.Type))\n\t\t\t\t\t\t\t.WithILInstruction(matchInstruction);\n\t\t\t\t\t}\n\t\t\t\tcase Comp comp:\n\t\t\t\t\tvar constantValue = Translate(comp.Right, leftHandType);\n\t\t\t\t\tswitch (comp.Kind)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase ComparisonKind.Equality:\n\t\t\t\t\t\t\treturn constantValue\n\t\t\t\t\t\t\t\t.WithILInstruction(comp);\n\t\t\t\t\t\tcase ComparisonKind.Inequality:\n\t\t\t\t\t\t\treturn new UnaryOperatorExpression(UnaryOperatorType.PatternNot, constantValue)\n\t\t\t\t\t\t\t\t.WithILInstruction(comp);\n\t\t\t\t\t\tcase ComparisonKind.LessThan:\n\t\t\t\t\t\t\treturn new UnaryOperatorExpression(UnaryOperatorType.PatternRelationalLessThan, constantValue)\n\t\t\t\t\t\t\t\t.WithILInstruction(comp);\n\t\t\t\t\t\tcase ComparisonKind.LessThanOrEqual:\n\t\t\t\t\t\t\treturn new UnaryOperatorExpression(UnaryOperatorType.PatternRelationalLessThanOrEqual, constantValue)\n\t\t\t\t\t\t\t\t.WithILInstruction(comp);\n\t\t\t\t\t\tcase ComparisonKind.GreaterThan:\n\t\t\t\t\t\t\treturn new UnaryOperatorExpression(UnaryOperatorType.PatternRelationalGreaterThan, constantValue)\n\t\t\t\t\t\t\t\t.WithILInstruction(comp);\n\t\t\t\t\t\tcase ComparisonKind.GreaterThanOrEqual:\n\t\t\t\t\t\t\treturn new UnaryOperatorExpression(UnaryOperatorType.PatternRelationalGreaterThanOrEqual, constantValue)\n\t\t\t\t\t\t\t\t.WithILInstruction(comp);\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow new InvalidOperationException(\"Unexpected comparison kind: \" + comp.Kind);\n\t\t\t\t\t}\n\t\t\t\tcase Call call when MatchInstruction.IsCallToOpEquality(call, KnownTypeCode.String):\n\t\t\t\t\treturn Translate(call.Arguments[1]);\n\t\t\t\tcase Call call when MatchInstruction.IsCallToOpEquality(call, KnownTypeCode.Decimal):\n\t\t\t\t\treturn Translate(call.Arguments[1]);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitInvalidBranch(InvalidBranch inst, TranslationContext context)\n\t\t{\n\t\t\tstring message = \"Error\";\n\t\t\tif (inst.StartILOffset != 0)\n\t\t\t{\n\t\t\t\tmessage += $\" near IL_{inst.StartILOffset:x4}\";\n\t\t\t}\n\t\t\tif (!string.IsNullOrEmpty(inst.Message))\n\t\t\t{\n\t\t\t\tmessage += \": \" + inst.Message;\n\t\t\t}\n\t\t\treturn ErrorExpression(message);\n\t\t}\n\n\t\tprotected internal override TranslatedExpression VisitInvalidExpression(InvalidExpression inst, TranslationContext context)\n\t\t{\n\t\t\tstring message = inst.Severity;\n\t\t\tif (inst.StartILOffset != 0)\n\t\t\t{\n\t\t\t\tmessage += $\" near IL_{inst.StartILOffset:x4}\";\n\t\t\t}\n\t\t\tif (!string.IsNullOrEmpty(inst.Message))\n\t\t\t{\n\t\t\t\tmessage += \": \" + inst.Message;\n\t\t\t}\n\t\t\treturn ErrorExpression(message);\n\t\t}\n\n\t\tprotected override TranslatedExpression Default(ILInstruction inst, TranslationContext context)\n\t\t{\n\t\t\treturn ErrorExpression(\"OpCode not supported: \" + inst.OpCode);\n\t\t}\n\n\t\tstatic TranslatedExpression ErrorExpression(string message)\n\t\t{\n\t\t\tvar e = new ErrorExpression();\n\t\t\te.AddChild(new Comment(message, CommentType.MultiLine), Roles.Comment);\n\t\t\treturn e.WithoutILInstruction().WithRR(ErrorResolveResult.UnknownError);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.Output;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.CSharp.OutputVisitor\n{\n\t/// <summary>\n\t/// C# ambience. Used to convert type system symbols to text (usually for displaying the symbol to the user; e.g. in editor tooltips)\n\t/// </summary>\n\tpublic class CSharpAmbience : IAmbience\n\t{\n\t\tpublic ConversionFlags ConversionFlags { get; set; }\n\n\t\t#region ConvertSymbol\n\t\tpublic string ConvertSymbol(ISymbol symbol)\n\t\t{\n\t\t\tif (symbol == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(symbol));\n\n\t\t\tStringWriter writer = new StringWriter();\n\t\t\tConvertSymbol(symbol, new TextWriterTokenWriter(writer), FormattingOptionsFactory.CreateEmpty());\n\t\t\treturn writer.ToString();\n\t\t}\n\n\t\tpublic void ConvertSymbol(ISymbol symbol, TokenWriter writer, CSharpFormattingOptions formattingPolicy)\n\t\t{\n\t\t\tif (symbol == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(symbol));\n\t\t\tif (writer == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(writer));\n\t\t\tif (formattingPolicy == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(formattingPolicy));\n\n\t\t\tTypeSystemAstBuilder astBuilder = CreateAstBuilder();\n\t\t\tAstNode node = astBuilder.ConvertSymbol(symbol);\n\t\t\twriter.StartNode(node);\n\t\t\tif (node is EntityDeclaration entityDecl)\n\t\t\t\tPrintModifiers(entityDecl.Modifiers, writer);\n\n\t\t\tif ((ConversionFlags & ConversionFlags.ShowDefinitionKeyword) == ConversionFlags.ShowDefinitionKeyword)\n\t\t\t{\n\t\t\t\tif (node is TypeDeclaration)\n\t\t\t\t{\n\t\t\t\t\tswitch (((TypeDeclaration)node).ClassType)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase ClassType.Class:\n\t\t\t\t\t\t\twriter.WriteKeyword(Roles.ClassKeyword, \"class\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ClassType.Struct:\n\t\t\t\t\t\t\twriter.WriteKeyword(Roles.StructKeyword, \"struct\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ClassType.Interface:\n\t\t\t\t\t\t\twriter.WriteKeyword(Roles.InterfaceKeyword, \"interface\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ClassType.Enum:\n\t\t\t\t\t\t\twriter.WriteKeyword(Roles.EnumKeyword, \"enum\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ClassType.RecordClass:\n\t\t\t\t\t\t\twriter.WriteKeyword(Roles.RecordKeyword, \"record\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ClassType.RecordStruct:\n\t\t\t\t\t\t\twriter.WriteKeyword(Roles.RecordKeyword, \"record\");\n\t\t\t\t\t\t\twriter.Space();\n\t\t\t\t\t\t\twriter.WriteKeyword(Roles.StructKeyword, \"struct\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow new Exception(\"Invalid value for ClassType\");\n\t\t\t\t\t}\n\t\t\t\t\twriter.Space();\n\t\t\t\t}\n\t\t\t\telse if (node is DelegateDeclaration)\n\t\t\t\t{\n\t\t\t\t\twriter.WriteKeyword(Roles.DelegateKeyword, \"delegate\");\n\t\t\t\t\twriter.Space();\n\t\t\t\t}\n\t\t\t\telse if (node is EventDeclaration)\n\t\t\t\t{\n\t\t\t\t\twriter.WriteKeyword(EventDeclaration.EventKeywordRole, \"event\");\n\t\t\t\t\twriter.Space();\n\t\t\t\t}\n\t\t\t\telse if (node is NamespaceDeclaration)\n\t\t\t\t{\n\t\t\t\t\twriter.WriteKeyword(Roles.NamespaceKeyword, \"namespace\");\n\t\t\t\t\twriter.Space();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ((ConversionFlags & ConversionFlags.PlaceReturnTypeAfterParameterList) != ConversionFlags.PlaceReturnTypeAfterParameterList\n\t\t\t\t&& (ConversionFlags & ConversionFlags.ShowReturnType) == ConversionFlags.ShowReturnType)\n\t\t\t{\n\t\t\t\tvar rt = node.GetChildByRole(Roles.Type);\n\t\t\t\tif (!rt.IsNull)\n\t\t\t\t{\n\t\t\t\t\trt.AcceptVisitor(new CSharpOutputVisitor(writer, formattingPolicy));\n\t\t\t\t\twriter.Space();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (symbol is ITypeDefinition)\n\t\t\t\tWriteTypeDeclarationName((ITypeDefinition)symbol, writer, formattingPolicy);\n\t\t\telse if (symbol is IMember)\n\t\t\t\tWriteMemberDeclarationName((IMember)symbol, writer, formattingPolicy);\n\t\t\telse\n\t\t\t\twriter.WriteIdentifier(Identifier.Create(symbol.Name));\n\n\t\t\tif ((ConversionFlags & ConversionFlags.ShowParameterList) == ConversionFlags.ShowParameterList && HasParameters(symbol))\n\t\t\t{\n\t\t\t\twriter.WriteToken(symbol.SymbolKind == SymbolKind.Indexer ? Roles.LBracket : Roles.LPar, symbol.SymbolKind == SymbolKind.Indexer ? \"[\" : \"(\");\n\t\t\t\tbool first = true;\n\t\t\t\tforeach (var param in node.GetChildrenByRole(Roles.Parameter))\n\t\t\t\t{\n\t\t\t\t\tif ((ConversionFlags & ConversionFlags.ShowParameterModifiers) == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tparam.ParameterModifier = ReferenceKind.None;\n\t\t\t\t\t\tparam.IsScopedRef = false;\n\t\t\t\t\t\tparam.IsParams = false;\n\t\t\t\t\t}\n\t\t\t\t\tif ((ConversionFlags & ConversionFlags.ShowParameterDefaultValues) == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tparam.DefaultExpression.Detach();\n\t\t\t\t\t}\n\t\t\t\t\tif (first)\n\t\t\t\t\t{\n\t\t\t\t\t\tfirst = false;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\twriter.WriteToken(Roles.Comma, \",\");\n\t\t\t\t\t\twriter.Space();\n\t\t\t\t\t}\n\t\t\t\t\tparam.AcceptVisitor(new CSharpOutputVisitor(writer, formattingPolicy));\n\t\t\t\t}\n\t\t\t\twriter.WriteToken(symbol.SymbolKind == SymbolKind.Indexer ? Roles.RBracket : Roles.RPar, symbol.SymbolKind == SymbolKind.Indexer ? \"]\" : \")\");\n\t\t\t}\n\n\t\t\tif ((ConversionFlags & ConversionFlags.PlaceReturnTypeAfterParameterList) == ConversionFlags.PlaceReturnTypeAfterParameterList\n\t\t\t\t&& (ConversionFlags & ConversionFlags.ShowReturnType) == ConversionFlags.ShowReturnType)\n\t\t\t{\n\t\t\t\tvar rt = node.GetChildByRole(Roles.Type);\n\t\t\t\tif (!rt.IsNull)\n\t\t\t\t{\n\t\t\t\t\twriter.Space();\n\t\t\t\t\twriter.WriteToken(Roles.Colon, \":\");\n\t\t\t\t\twriter.Space();\n\t\t\t\t\tif (symbol is IField f && CSharpDecompiler.IsFixedField(f, out var type, out int elementCount))\n\t\t\t\t\t{\n\t\t\t\t\t\trt = astBuilder.ConvertType(type);\n\t\t\t\t\t\tnew IndexerExpression(new TypeReferenceExpression(rt), astBuilder.ConvertConstantValue(f.Compilation.FindType(KnownTypeCode.Int32), elementCount))\n\t\t\t\t\t\t\t.AcceptVisitor(new CSharpOutputVisitor(writer, formattingPolicy));\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\trt.AcceptVisitor(new CSharpOutputVisitor(writer, formattingPolicy));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ((ConversionFlags & ConversionFlags.ShowBody) == ConversionFlags.ShowBody && !(node is TypeDeclaration))\n\t\t\t{\n\t\t\t\tif (symbol is IProperty property)\n\t\t\t\t{\n\t\t\t\t\twriter.Space();\n\t\t\t\t\twriter.WriteToken(Roles.LBrace, \"{\");\n\t\t\t\t\twriter.Space();\n\t\t\t\t\tif (property.CanGet)\n\t\t\t\t\t{\n\t\t\t\t\t\twriter.WriteKeyword(PropertyDeclaration.GetKeywordRole, \"get\");\n\t\t\t\t\t\twriter.WriteToken(Roles.Semicolon, \";\");\n\t\t\t\t\t\twriter.Space();\n\t\t\t\t\t}\n\t\t\t\t\tif (property.CanSet)\n\t\t\t\t\t{\n\t\t\t\t\t\tif ((ConversionFlags & ConversionFlags.SupportInitAccessors) != 0 && property.Setter.IsInitOnly)\n\t\t\t\t\t\t\twriter.WriteKeyword(PropertyDeclaration.InitKeywordRole, \"init\");\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\twriter.WriteKeyword(PropertyDeclaration.SetKeywordRole, \"set\");\n\t\t\t\t\t\twriter.WriteToken(Roles.Semicolon, \";\");\n\t\t\t\t\t\twriter.Space();\n\t\t\t\t\t}\n\t\t\t\t\twriter.WriteToken(Roles.RBrace, \"}\");\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\twriter.WriteToken(Roles.Semicolon, \";\");\n\t\t\t\t}\n\t\t\t\twriter.EndNode(node);\n\t\t\t}\n\t\t}\n\n\t\tstatic bool HasParameters(ISymbol e)\n\t\t{\n\t\t\tswitch (e.SymbolKind)\n\t\t\t{\n\t\t\t\tcase SymbolKind.TypeDefinition:\n\t\t\t\t\treturn ((ITypeDefinition)e).Kind == TypeKind.Delegate;\n\t\t\t\tcase SymbolKind.Indexer:\n\t\t\t\tcase SymbolKind.Method:\n\t\t\t\tcase SymbolKind.Operator:\n\t\t\t\tcase SymbolKind.Constructor:\n\t\t\t\tcase SymbolKind.Destructor:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tTypeSystemAstBuilder CreateAstBuilder()\n\t\t{\n\t\t\tTypeSystemAstBuilder astBuilder = new TypeSystemAstBuilder();\n\t\t\tastBuilder.AddResolveResultAnnotations = true;\n\t\t\tastBuilder.ShowTypeParametersForUnboundTypes = true;\n\t\t\tastBuilder.ShowModifiers = (ConversionFlags & ConversionFlags.ShowModifiers) == ConversionFlags.ShowModifiers;\n\t\t\tastBuilder.ShowAccessibility = (ConversionFlags & ConversionFlags.ShowAccessibility) == ConversionFlags.ShowAccessibility;\n\t\t\tastBuilder.UsePrivateProtectedAccessibility = (ConversionFlags & ConversionFlags.UsePrivateProtectedAccessibility) == ConversionFlags.UsePrivateProtectedAccessibility;\n\t\t\tastBuilder.AlwaysUseShortTypeNames = (ConversionFlags & ConversionFlags.UseFullyQualifiedTypeNames) != ConversionFlags.UseFullyQualifiedTypeNames;\n\t\t\tastBuilder.ShowParameterNames = (ConversionFlags & ConversionFlags.ShowParameterNames) == ConversionFlags.ShowParameterNames;\n\t\t\tastBuilder.UseNullableSpecifierForValueTypes = (ConversionFlags & ConversionFlags.UseNullableSpecifierForValueTypes) != 0;\n\t\t\tastBuilder.SupportInitAccessors = (ConversionFlags & ConversionFlags.SupportInitAccessors) != 0;\n\t\t\tastBuilder.SupportRecordClasses = (ConversionFlags & ConversionFlags.SupportRecordClasses) != 0;\n\t\t\tastBuilder.SupportRecordStructs = (ConversionFlags & ConversionFlags.SupportRecordStructs) != 0;\n\t\t\tastBuilder.SupportUnsignedRightShift = (ConversionFlags & ConversionFlags.SupportUnsignedRightShift) != 0;\n\t\t\tastBuilder.SupportOperatorChecked = (ConversionFlags & ConversionFlags.SupportOperatorChecked) != 0;\n\t\t\treturn astBuilder;\n\t\t}\n\n\t\tvoid WriteTypeDeclarationName(ITypeDefinition typeDef, TokenWriter writer, CSharpFormattingOptions formattingPolicy)\n\t\t{\n\t\t\tTypeSystemAstBuilder astBuilder = CreateAstBuilder();\n\t\t\tEntityDeclaration node = astBuilder.ConvertEntity(typeDef);\n\t\t\tif (typeDef.DeclaringTypeDefinition != null &&\n\t\t\t\t((ConversionFlags & ConversionFlags.ShowDeclaringType) == ConversionFlags.ShowDeclaringType ||\n\t\t\t\t(ConversionFlags & ConversionFlags.UseFullyQualifiedEntityNames) == ConversionFlags.UseFullyQualifiedEntityNames))\n\t\t\t{\n\t\t\t\tWriteTypeDeclarationName(typeDef.DeclaringTypeDefinition, writer, formattingPolicy);\n\t\t\t\twriter.WriteToken(Roles.Dot, \".\");\n\t\t\t}\n\t\t\telse if ((ConversionFlags & ConversionFlags.UseFullyQualifiedEntityNames) == ConversionFlags.UseFullyQualifiedEntityNames)\n\t\t\t{\n\t\t\t\tif (!string.IsNullOrEmpty(typeDef.Namespace))\n\t\t\t\t{\n\t\t\t\t\tWriteQualifiedName(typeDef.Namespace, writer, formattingPolicy);\n\t\t\t\t\twriter.WriteToken(Roles.Dot, \".\");\n\t\t\t\t}\n\t\t\t}\n\t\t\twriter.WriteIdentifier(node.NameToken);\n\t\t\tWriteTypeParameters(node, writer, formattingPolicy);\n\t\t}\n\n\t\tvoid WriteMemberDeclarationName(IMember member, TokenWriter writer, CSharpFormattingOptions formattingPolicy)\n\t\t{\n\t\t\tTypeSystemAstBuilder astBuilder = CreateAstBuilder();\n\t\t\tEntityDeclaration node = astBuilder.ConvertEntity(member);\n\t\t\tif ((ConversionFlags & ConversionFlags.ShowDeclaringType) == ConversionFlags.ShowDeclaringType && member.DeclaringType != null && !(member is LocalFunctionMethod))\n\t\t\t{\n\t\t\t\tConvertType(member.DeclaringType, writer, formattingPolicy);\n\t\t\t\twriter.WriteToken(Roles.Dot, \".\");\n\t\t\t}\n\t\t\tIType? explicitInterfaceType = GetExplicitInterfaceType(member);\n\t\t\tstring name = member.Name;\n\t\t\tif (explicitInterfaceType != null)\n\t\t\t{\n\t\t\t\tname = name.Substring(name.LastIndexOf('.') + 1);\n\t\t\t}\n\t\t\tswitch (member.SymbolKind)\n\t\t\t{\n\t\t\t\tcase SymbolKind.Indexer:\n\t\t\t\t\tif (explicitInterfaceType != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tConvertType(explicitInterfaceType, writer, formattingPolicy);\n\t\t\t\t\t\twriter.WriteToken(Roles.Dot, \".\");\n\t\t\t\t\t}\n\t\t\t\t\twriter.WriteKeyword(Roles.Identifier, \"this\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase SymbolKind.Constructor:\n\t\t\t\t\tWriteQualifiedName(member.DeclaringType!.Name, writer, formattingPolicy);\n\t\t\t\t\tbreak;\n\t\t\t\tcase SymbolKind.Destructor:\n\t\t\t\t\twriter.WriteToken(DestructorDeclaration.TildeRole, \"~\");\n\t\t\t\t\tWriteQualifiedName(member.DeclaringType!.Name, writer, formattingPolicy);\n\t\t\t\t\tbreak;\n\t\t\t\tcase SymbolKind.Operator:\n\t\t\t\t\tswitch (name)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase \"op_Implicit\":\n\t\t\t\t\t\t\twriter.WriteKeyword(OperatorDeclaration.ImplicitRole, \"implicit\");\n\t\t\t\t\t\t\twriter.Space();\n\t\t\t\t\t\t\tif (explicitInterfaceType != null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tConvertType(explicitInterfaceType, writer, formattingPolicy);\n\t\t\t\t\t\t\t\twriter.WriteToken(Roles.Dot, \".\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\twriter.WriteKeyword(OperatorDeclaration.OperatorKeywordRole, \"operator\");\n\t\t\t\t\t\t\twriter.Space();\n\t\t\t\t\t\t\tConvertType(member.ReturnType, writer, formattingPolicy);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"op_Explicit\":\n\t\t\t\t\t\tcase \"op_CheckedExplicit\":\n\t\t\t\t\t\t\twriter.WriteKeyword(OperatorDeclaration.ExplicitRole, \"explicit\");\n\t\t\t\t\t\t\twriter.Space();\n\t\t\t\t\t\t\tif (explicitInterfaceType != null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tConvertType(explicitInterfaceType, writer, formattingPolicy);\n\t\t\t\t\t\t\t\twriter.WriteToken(Roles.Dot, \".\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\twriter.WriteKeyword(OperatorDeclaration.OperatorKeywordRole, \"operator\");\n\t\t\t\t\t\t\twriter.Space();\n\t\t\t\t\t\t\tif (name == \"op_CheckedExplicit\")\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\twriter.WriteToken(OperatorDeclaration.CheckedKeywordRole, \"checked\");\n\t\t\t\t\t\t\t\twriter.Space();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tConvertType(member.ReturnType, writer, formattingPolicy);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tif (explicitInterfaceType != null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tConvertType(explicitInterfaceType, writer, formattingPolicy);\n\t\t\t\t\t\t\t\twriter.WriteToken(Roles.Dot, \".\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\twriter.WriteKeyword(OperatorDeclaration.OperatorKeywordRole, \"operator\");\n\t\t\t\t\t\t\twriter.Space();\n\t\t\t\t\t\t\tvar operatorType = OperatorDeclaration.GetOperatorType(name);\n\t\t\t\t\t\t\tif (operatorType.HasValue && !((ConversionFlags & ConversionFlags.SupportOperatorChecked) == 0 && OperatorDeclaration.IsChecked(operatorType.Value)))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (OperatorDeclaration.IsChecked(operatorType.Value))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\twriter.WriteToken(OperatorDeclaration.CheckedKeywordRole, \"checked\");\n\t\t\t\t\t\t\t\t\twriter.Space();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twriter.WriteToken(OperatorDeclaration.GetRole(operatorType.Value), OperatorDeclaration.GetToken(operatorType.Value));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\twriter.WriteIdentifier(node.NameToken);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tif (explicitInterfaceType != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tConvertType(explicitInterfaceType, writer, formattingPolicy);\n\t\t\t\t\t\twriter.WriteToken(Roles.Dot, \".\");\n\t\t\t\t\t}\n\t\t\t\t\twriter.WriteIdentifier(Identifier.Create(name));\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tWriteTypeParameters(node, writer, formattingPolicy);\n\t\t}\n\n\t\tvoid WriteTypeParameters(EntityDeclaration node, TokenWriter writer, CSharpFormattingOptions formattingPolicy)\n\t\t{\n\t\t\tif ((ConversionFlags & ConversionFlags.ShowTypeParameterList) == ConversionFlags.ShowTypeParameterList)\n\t\t\t{\n\t\t\t\tvar outputVisitor = new CSharpOutputVisitor(writer, formattingPolicy);\n\t\t\t\tIEnumerable<TypeParameterDeclaration> typeParameters = node.GetChildrenByRole(Roles.TypeParameter);\n\t\t\t\tif ((ConversionFlags & ConversionFlags.ShowTypeParameterVarianceModifier) == 0)\n\t\t\t\t{\n\t\t\t\t\ttypeParameters = typeParameters.Select(RemoveVarianceModifier);\n\t\t\t\t}\n\t\t\t\toutputVisitor.WriteTypeParameters(typeParameters);\n\t\t\t}\n\n\t\t\tTypeParameterDeclaration RemoveVarianceModifier(TypeParameterDeclaration decl)\n\t\t\t{\n\t\t\t\tdecl.Variance = VarianceModifier.Invariant;\n\t\t\t\treturn decl;\n\t\t\t}\n\t\t}\n\n\t\tvoid PrintModifiers(Modifiers modifiers, TokenWriter writer)\n\t\t{\n\t\t\tforeach (var m in CSharpModifierToken.AllModifiers)\n\t\t\t{\n\t\t\t\tif ((modifiers & m) == m)\n\t\t\t\t{\n\t\t\t\t\twriter.WriteKeyword(EntityDeclaration.ModifierRole, CSharpModifierToken.GetModifierName(m));\n\t\t\t\t\twriter.Space();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid WriteQualifiedName(string name, TokenWriter writer, CSharpFormattingOptions formattingPolicy)\n\t\t{\n\t\t\tvar node = AstType.Create(name);\n\t\t\tvar outputVisitor = new CSharpOutputVisitor(writer, formattingPolicy);\n\t\t\tnode.AcceptVisitor(outputVisitor);\n\t\t}\n\t\t#endregion\n\n\t\tpublic string ConvertVariable(IVariable v)\n\t\t{\n\t\t\tTypeSystemAstBuilder astBuilder = CreateAstBuilder();\n\t\t\tAstNode astNode = astBuilder.ConvertVariable(v);\n\t\t\treturn astNode.ToString().TrimEnd(';', '\\r', '\\n', (char)8232);\n\t\t}\n\n\t\tpublic string ConvertType(IType type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\n\t\t\tTypeSystemAstBuilder astBuilder = CreateAstBuilder();\n\t\t\tastBuilder.AlwaysUseShortTypeNames = (ConversionFlags & ConversionFlags.UseFullyQualifiedEntityNames) != ConversionFlags.UseFullyQualifiedEntityNames;\n\t\t\tAstType astType = astBuilder.ConvertType(type);\n\t\t\treturn astType.ToString();\n\t\t}\n\n\t\tvoid ConvertType(IType type, TokenWriter writer, CSharpFormattingOptions formattingPolicy)\n\t\t{\n\t\t\tTypeSystemAstBuilder astBuilder = CreateAstBuilder();\n\t\t\tastBuilder.AlwaysUseShortTypeNames = (ConversionFlags & ConversionFlags.UseFullyQualifiedEntityNames) != ConversionFlags.UseFullyQualifiedEntityNames;\n\t\t\tAstType astType = astBuilder.ConvertType(type);\n\t\t\tastType.AcceptVisitor(new CSharpOutputVisitor(writer, formattingPolicy));\n\t\t}\n\n\t\tIType? GetExplicitInterfaceType(IMember member)\n\t\t{\n\t\t\tif (member.IsExplicitInterfaceImplementation)\n\t\t\t{\n\t\t\t\tvar baseMember = member.ExplicitlyImplementedInterfaceMembers.FirstOrDefault();\n\t\t\t\tif (baseMember != null)\n\t\t\t\t\treturn baseMember.DeclaringType;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic string ConvertConstantValue(object constantValue)\n\t\t{\n\t\t\treturn TextWriterTokenWriter.PrintPrimitiveValue(constantValue);\n\t\t}\n\n\t\tpublic string WrapComment(string comment)\n\t\t{\n\t\t\treturn \"// \" + comment;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpFormattingOptions.cs",
    "content": "// \n// CSharpFormattingOptions.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n//  \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System.ComponentModel;\n\nnamespace ICSharpCode.Decompiler.CSharp.OutputVisitor\n{\n\tpublic enum BraceStyle\n\t{\n\t\tEndOfLine,\n\t\tEndOfLineWithoutSpace,\n\t\tNextLine,\n\t\tNextLineShifted,\n\t\tNextLineShifted2,\n\t\tBannerStyle\n\t}\n\n\tpublic enum PropertyFormatting\n\t{\n\t\tSingleLine,\n\t\tMultipleLines\n\t}\n\n\tpublic enum Wrapping\n\t{\n\t\tDoNotWrap,\n\t\tWrapAlways,\n\t\tWrapIfTooLong\n\t}\n\n\tpublic enum NewLinePlacement\n\t{\n\t\tDoNotCare,\n\t\tNewLine,\n\t\tSameLine\n\t}\n\n\tpublic enum UsingPlacement\n\t{\n\t\tTopOfFile,\n\t\tInsideNamespace\n\t}\n\n\tpublic enum EmptyLineFormatting\n\t{\n\t\tDoNotChange,\n\t\tIndent,\n\t\tDoNotIndent\n\t}\n\n\t[TypeConverter(typeof(ExpandableObjectConverter))]\n\tpublic class CSharpFormattingOptions\n\t{\n\t\tpublic string Name {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool IsBuiltIn {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic CSharpFormattingOptions Clone()\n\t\t{\n\t\t\treturn (CSharpFormattingOptions)MemberwiseClone();\n\t\t}\n\n\t\t#region Indentation\n\t\tpublic string IndentationString { get; set; } = \"\\t\";\n\n\t\tpublic bool IndentNamespaceBody { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool IndentClassBody { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool IndentInterfaceBody { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool IndentStructBody { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool IndentEnumBody { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool IndentMethodBody { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool IndentPropertyBody { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool IndentEventBody { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool IndentBlocks { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool IndentSwitchBody { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool IndentCaseBody { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool IndentBreakStatements { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool AlignEmbeddedStatements { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool AlignElseInIfStatements {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic PropertyFormatting AutoPropertyFormatting { get; set; }\n\n\t\tpublic PropertyFormatting SimplePropertyFormatting { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic EmptyLineFormatting EmptyLineFormatting {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool IndentPreprocessorDirectives { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool AlignToMemberReferenceDot { // TODO!\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool IndentBlocksInsideExpressions {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\t\t#endregion\n\n\t\t#region Braces\n\t\tpublic BraceStyle NamespaceBraceStyle { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic BraceStyle ClassBraceStyle { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic BraceStyle InterfaceBraceStyle { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic BraceStyle StructBraceStyle { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic BraceStyle EnumBraceStyle { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic BraceStyle MethodBraceStyle { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic BraceStyle AnonymousMethodBraceStyle {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic BraceStyle ConstructorBraceStyle {  // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic BraceStyle DestructorBraceStyle { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic BraceStyle PropertyBraceStyle { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic BraceStyle PropertyGetBraceStyle { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic BraceStyle PropertySetBraceStyle { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic PropertyFormatting SimpleGetBlockFormatting { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic PropertyFormatting SimpleSetBlockFormatting { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic BraceStyle EventBraceStyle { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic BraceStyle EventAddBraceStyle { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic BraceStyle EventRemoveBraceStyle { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool AllowEventAddBlockInline { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool AllowEventRemoveBlockInline { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic BraceStyle StatementBraceStyle { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool AllowIfBlockInline {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tbool allowOneLinedArrayInitialziers = true;\n\t\tpublic bool AllowOneLinedArrayInitialziers {\n\t\t\tget {\n\t\t\t\treturn allowOneLinedArrayInitialziers;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tallowOneLinedArrayInitialziers = value;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region NewLines\n\t\tpublic NewLinePlacement ElseNewLinePlacement { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic NewLinePlacement ElseIfNewLinePlacement { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic NewLinePlacement CatchNewLinePlacement { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic NewLinePlacement FinallyNewLinePlacement { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic NewLinePlacement WhileNewLinePlacement { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tNewLinePlacement embeddedStatementPlacement = NewLinePlacement.NewLine;\n\t\tpublic NewLinePlacement EmbeddedStatementPlacement {\n\t\t\tget {\n\t\t\t\treturn embeddedStatementPlacement;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tembeddedStatementPlacement = value;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Spaces\n\t\tpublic bool SpaceBetweenParameterAttributeSections {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\t// Methods\n\t\tpublic bool SpaceBeforeMethodDeclarationParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBetweenEmptyMethodDeclarationParentheses {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeMethodDeclarationParameterComma { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAfterMethodDeclarationParameterComma { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceWithinMethodDeclarationParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\t// Method calls\n\t\tpublic bool SpaceBeforeMethodCallParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBetweenEmptyMethodCallParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeMethodCallParameterComma { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAfterMethodCallParameterComma { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceWithinMethodCallParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\t// fields\n\n\t\tpublic bool SpaceBeforeFieldDeclarationComma { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAfterFieldDeclarationComma { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\t// local variables\n\n\t\tpublic bool SpaceBeforeLocalVariableDeclarationComma { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAfterLocalVariableDeclarationComma { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\t// constructors\n\n\t\tpublic bool SpaceBeforeConstructorDeclarationParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBetweenEmptyConstructorDeclarationParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeConstructorDeclarationParameterComma { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAfterConstructorDeclarationParameterComma { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceWithinConstructorDeclarationParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic NewLinePlacement NewLineBeforeConstructorInitializerColon {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic NewLinePlacement NewLineAfterConstructorInitializerColon {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\t// indexer\n\t\tpublic bool SpaceBeforeIndexerDeclarationBracket { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceWithinIndexerDeclarationBracket { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeIndexerDeclarationParameterComma {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAfterIndexerDeclarationParameterComma {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\t// delegates\n\n\t\tpublic bool SpaceBeforeDelegateDeclarationParentheses {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBetweenEmptyDelegateDeclarationParentheses {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeDelegateDeclarationParameterComma {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAfterDelegateDeclarationParameterComma {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceWithinDelegateDeclarationParentheses {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeNewParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeIfParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeWhileParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeForParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeForeachParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeCatchParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeSwitchParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeLockParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeUsingParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAroundAssignment { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAroundLogicalOperator { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAroundEqualityOperator { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAroundRelationalOperator { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAroundBitwiseOperator { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAroundAdditiveOperator { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAroundMultiplicativeOperator { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAroundShiftOperator { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAroundNullCoalescingOperator { // Tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAfterUnsafeAddressOfOperator { // Tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAfterUnsafeAsteriskOfOperator { // Tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAroundUnsafeArrowOperator { // Tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpacesWithinParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpacesWithinIfParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpacesWithinWhileParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpacesWithinForParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpacesWithinForeachParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpacesWithinCatchParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpacesWithinSwitchParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpacesWithinLockParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpacesWithinUsingParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpacesWithinCastParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpacesWithinSizeOfParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeSizeOfParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpacesWithinTypeOfParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpacesWithinNewParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpacesBetweenEmptyNewParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeNewParameterComma { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAfterNewParameterComma { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeTypeOfParentheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpacesWithinCheckedExpressionParantheses { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeConditionalOperatorCondition { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAfterConditionalOperatorCondition { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeConditionalOperatorSeparator { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAfterConditionalOperatorSeparator { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeAnonymousMethodParentheses {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceWithinAnonymousMethodParentheses {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\t// brackets\n\t\tpublic bool SpacesWithinBrackets { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpacesBeforeBrackets { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeBracketComma { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAfterBracketComma { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeForSemicolon { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAfterForSemicolon { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceAfterTypecast { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeArrayDeclarationBrackets { // tested\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceInNamedArgumentAfterDoubleColon {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool RemoveEndOfLineWhiteSpace {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool SpaceBeforeSemicolon {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\t\t#endregion\n\n\t\t#region Blank Lines\n\t\tpublic int MinimumBlankLinesBeforeUsings {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic int MinimumBlankLinesAfterUsings {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic int MinimumBlankLinesBeforeFirstDeclaration {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic int MinimumBlankLinesBetweenTypes {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic int MinimumBlankLinesBetweenFields {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic int MinimumBlankLinesBetweenEventFields {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic int MinimumBlankLinesBetweenMembers {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic int MinimumBlankLinesAroundRegion {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic int MinimumBlankLinesInsideRegion {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Keep formatting\n\t\tpublic bool KeepCommentsAtFirstColumn {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\t\t#endregion\n\n\t\t#region Wrapping\n\n\t\tpublic Wrapping ArrayInitializerWrapping {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic BraceStyle ArrayInitializerBraceStyle {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic Wrapping ChainedMethodCallWrapping {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic Wrapping MethodCallArgumentWrapping {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic NewLinePlacement NewLineAferMethodCallOpenParentheses {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic NewLinePlacement MethodCallClosingParenthesesOnNewLine {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic Wrapping IndexerArgumentWrapping {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic NewLinePlacement NewLineAferIndexerOpenBracket {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic NewLinePlacement IndexerClosingBracketOnNewLine {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic Wrapping MethodDeclarationParameterWrapping {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic NewLinePlacement NewLineAferMethodDeclarationOpenParentheses {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic NewLinePlacement MethodDeclarationClosingParenthesesOnNewLine {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic Wrapping IndexerDeclarationParameterWrapping {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic NewLinePlacement NewLineAferIndexerDeclarationOpenBracket {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic NewLinePlacement IndexerDeclarationClosingBracketOnNewLine {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool AlignToFirstIndexerArgument {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool AlignToFirstIndexerDeclarationParameter {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool AlignToFirstMethodCallArgument {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic bool AlignToFirstMethodDeclarationParameter {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic NewLinePlacement NewLineBeforeNewQueryClause {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Using Declarations\n\t\tpublic UsingPlacement UsingPlacement {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\t\t#endregion\n\n\t\tinternal CSharpFormattingOptions()\n\t\t{\n\t\t}\n\n\t\t/*public static CSharpFormattingOptions Load (FilePath selectedFile)\n\t\t{\n\t\t\tusing (var stream = System.IO.File.OpenRead (selectedFile)) {\n\t\t\t\treturn Load (stream);\n\t\t\t}\n\t\t}\n\n\t\tpublic static CSharpFormattingOptions Load (System.IO.Stream input)\n\t\t{\n\t\t\tCSharpFormattingOptions result = FormattingOptionsFactory.CreateMonoOptions ();\n\t\t\tresult.Name = \"noname\";\n\t\t\tusing (XmlTextReader reader = new XmlTextReader (input)) {\n\t\t\t\twhile (reader.Read ()) {\n\t\t\t\t\tif (reader.NodeType == XmlNodeType.Element) {\n\t\t\t\t\t\tif (reader.LocalName == \"Property\") {\n\t\t\t\t\t\t\tvar info = typeof(CSharpFormattingOptions).GetProperty (reader.GetAttribute (\"name\"));\n\t\t\t\t\t\t\tstring valString = reader.GetAttribute (\"value\");\n\t\t\t\t\t\t\tobject value;\n\t\t\t\t\t\t\tif (info.PropertyType == typeof(bool)) {\n\t\t\t\t\t\t\t\tvalue = Boolean.Parse (valString);\n\t\t\t\t\t\t\t} else if (info.PropertyType == typeof(int)) {\n\t\t\t\t\t\t\t\tvalue = Int32.Parse (valString);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tvalue = Enum.Parse (info.PropertyType, valString);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tinfo.SetValue (result, value, null);\n\t\t\t\t\t\t} else if (reader.LocalName == \"FormattingProfile\") {\n\t\t\t\t\t\t\tresult.Name = reader.GetAttribute (\"name\");\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (reader.NodeType == XmlNodeType.EndElement && reader.LocalName == \"FormattingProfile\") {\n\t\t\t\t\t\t//Console.WriteLine (\"result:\" + result.Name);\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic void Save (string fileName)\n\t\t{\n\t\t\tusing (var writer = new XmlTextWriter (fileName, Encoding.Default)) {\n\t\t\t\twriter.Formatting = System.Xml.Formatting.Indented;\n\t\t\t\twriter.Indentation = 1;\n\t\t\t\twriter.IndentChar = '\\t';\n\t\t\t\twriter.WriteStartElement (\"FormattingProfile\");\n\t\t\t\twriter.WriteAttributeString (\"name\", Name);\n\t\t\t\tforeach (PropertyInfo info in typeof (CSharpFormattingOptions).GetProperties ()) {\n\t\t\t\t\tif (info.GetCustomAttributes (false).Any (o => o.GetType () == typeof(ItemPropertyAttribute))) {\n\t\t\t\t\t\twriter.WriteStartElement (\"Property\");\n\t\t\t\t\t\twriter.WriteAttributeString (\"name\", info.Name);\n\t\t\t\t\t\twriter.WriteAttributeString (\"value\", info.GetValue (this, null).ToString ());\n\t\t\t\t\t\twriter.WriteEndElement ();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\twriter.WriteEndElement ();\n\t\t\t}\n\t\t}\n\n\t\tpublic bool Equals (CSharpFormattingOptions other)\n\t\t{\n\t\t\tforeach (PropertyInfo info in typeof (CSharpFormattingOptions).GetProperties ()) {\n\t\t\t\tif (info.GetCustomAttributes (false).Any (o => o.GetType () == typeof(ItemPropertyAttribute))) {\n\t\t\t\t\tobject val = info.GetValue (this, null);\n\t\t\t\t\tobject otherVal = info.GetValue (other, null);\n\t\t\t\t\tif (val == null) {\n\t\t\t\t\t\tif (otherVal == null)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif (!val.Equals (otherVal)) {\n\t\t\t\t\t\t//Console.WriteLine (\"!equal\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t//Console.WriteLine (\"== equal\");\n\t\t\treturn true;\n\t\t}*/\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs",
    "content": "// Copyright (c) 2010-2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nusing Attribute = ICSharpCode.Decompiler.CSharp.Syntax.Attribute;\n\nnamespace ICSharpCode.Decompiler.CSharp.OutputVisitor\n{\n\t/// <summary>\n\t/// Outputs the AST.\n\t/// </summary>\n\tpublic class CSharpOutputVisitor : IAstVisitor\n\t{\n\t\treadonly protected TokenWriter writer;\n\t\treadonly protected CSharpFormattingOptions policy;\n\t\treadonly protected Stack<AstNode> containerStack = new Stack<AstNode>();\n\n\t\tpublic CSharpOutputVisitor(TextWriter textWriter, CSharpFormattingOptions formattingPolicy)\n\t\t{\n\t\t\tif (textWriter == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(textWriter));\n\t\t\t}\n\t\t\tif (formattingPolicy == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(formattingPolicy));\n\t\t\t}\n\t\t\tthis.writer = TokenWriter.Create(textWriter, formattingPolicy.IndentationString);\n\t\t\tthis.policy = formattingPolicy;\n\t\t}\n\n\t\tpublic CSharpOutputVisitor(TokenWriter writer, CSharpFormattingOptions formattingPolicy)\n\t\t{\n\t\t\tif (writer == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(writer));\n\t\t\t}\n\t\t\tif (formattingPolicy == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(formattingPolicy));\n\t\t\t}\n\t\t\tthis.writer = new InsertSpecialsDecorator(new InsertRequiredSpacesDecorator(writer));\n\t\t\tthis.policy = formattingPolicy;\n\t\t}\n\n\t\t#region StartNode/EndNode\n\t\tprotected virtual void StartNode(AstNode node)\n\t\t{\n\t\t\t// Ensure that nodes are visited in the proper nested order.\n\t\t\t// Jumps to different subtrees are allowed only for the child of a placeholder node.\n\t\t\tDebug.Assert(containerStack.Count == 0 || node.Parent == containerStack.Peek() || containerStack.Peek().NodeType == NodeType.Pattern);\n\t\t\tcontainerStack.Push(node);\n\t\t\twriter.StartNode(node);\n\t\t}\n\n\t\tprotected virtual void EndNode(AstNode node)\n\t\t{\n\t\t\tDebug.Assert(node == containerStack.Peek());\n\t\t\tcontainerStack.Pop();\n\t\t\twriter.EndNode(node);\n\t\t}\n\t\t#endregion\n\n\t\t#region Comma\n\t\t/// <summary>\n\t\t/// Writes a comma.\n\t\t/// </summary>\n\t\t/// <param name=\"nextNode\">The next node after the comma.</param>\n\t\t/// <param name=\"noSpaceAfterComma\">When set prevents printing a space after comma.</param>\n\t\tprotected virtual void Comma(AstNode nextNode, bool noSpaceAfterComma = false)\n\t\t{\n\t\t\tSpace(policy.SpaceBeforeBracketComma);\n\t\t\t// TODO: Comma policy has changed.\n\t\t\twriter.WriteToken(Roles.Comma, \",\");\n\t\t\tisAfterSpace = false;\n\t\t\tSpace(!noSpaceAfterComma && policy.SpaceAfterBracketComma);\n\t\t\t// TODO: Comma policy has changed.\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Writes an optional comma, e.g. at the end of an enum declaration or in an array initializer\n\t\t/// </summary>\n\t\tprotected virtual void OptionalComma(AstNode pos)\n\t\t{\n\t\t\t// Look if there's a comma after the current node, and insert it if it exists.\n\t\t\twhile (pos != null && pos.NodeType == NodeType.Whitespace)\n\t\t\t{\n\t\t\t\tpos = pos.NextSibling;\n\t\t\t}\n\t\t\tif (pos != null && pos.Role == Roles.Comma)\n\t\t\t{\n\t\t\t\tComma(null, noSpaceAfterComma: true);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Writes an optional semicolon, e.g. at the end of a type or namespace declaration.\n\t\t/// </summary>\n\t\tprotected virtual void OptionalSemicolon(AstNode pos)\n\t\t{\n\t\t\t// Look if there's a semicolon after the current node, and insert it if it exists.\n\t\t\twhile (pos != null && pos.NodeType == NodeType.Whitespace)\n\t\t\t{\n\t\t\t\tpos = pos.PrevSibling;\n\t\t\t}\n\t\t\tif (pos != null && pos.Role == Roles.Semicolon)\n\t\t\t{\n\t\t\t\tSemicolon();\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual void WriteCommaSeparatedList(IEnumerable<AstNode> list)\n\t\t{\n\t\t\tbool isFirst = true;\n\t\t\tforeach (AstNode node in list)\n\t\t\t{\n\t\t\t\tif (isFirst)\n\t\t\t\t{\n\t\t\t\t\tisFirst = false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tComma(node);\n\t\t\t\t}\n\t\t\t\tnode.AcceptVisitor(this);\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual void WriteCommaSeparatedListInParenthesis(IEnumerable<AstNode> list, bool spaceWithin)\n\t\t{\n\t\t\tLPar();\n\t\t\tif (list.Any())\n\t\t\t{\n\t\t\t\tSpace(spaceWithin);\n\t\t\t\tWriteCommaSeparatedList(list);\n\t\t\t\tSpace(spaceWithin);\n\t\t\t}\n\t\t\tRPar();\n\t\t}\n\n\t\tprotected virtual void WriteCommaSeparatedListInBrackets(IEnumerable<ParameterDeclaration> list, bool spaceWithin)\n\t\t{\n\t\t\tWriteToken(Roles.LBracket);\n\t\t\tif (list.Any())\n\t\t\t{\n\t\t\t\tSpace(spaceWithin);\n\t\t\t\tWriteCommaSeparatedList(list);\n\t\t\t\tSpace(spaceWithin);\n\t\t\t}\n\t\t\tWriteToken(Roles.RBracket);\n\t\t}\n\n\t\tprotected virtual void WriteCommaSeparatedListInBrackets(IEnumerable<Expression> list)\n\t\t{\n\t\t\tWriteToken(Roles.LBracket);\n\t\t\tif (list.Any())\n\t\t\t{\n\t\t\t\tSpace(policy.SpacesWithinBrackets);\n\t\t\t\tWriteCommaSeparatedList(list);\n\t\t\t\tSpace(policy.SpacesWithinBrackets);\n\t\t\t}\n\t\t\tWriteToken(Roles.RBracket);\n\t\t}\n\t\t#endregion\n\n\t\t#region Write tokens\n\t\tprotected bool isAtStartOfLine = true;\n\t\tprotected bool isAfterSpace;\n\n\t\t/// <summary>\n\t\t/// Writes a keyword, and all specials up to\n\t\t/// </summary>\n\t\tprotected virtual void WriteKeyword(TokenRole tokenRole)\n\t\t{\n\t\t\tWriteKeyword(tokenRole.Token, tokenRole);\n\t\t}\n\n\t\tprotected virtual void WriteKeyword(string token, Role tokenRole = null)\n\t\t{\n\t\t\twriter.WriteKeyword(tokenRole, token);\n\t\t\tisAtStartOfLine = false;\n\t\t\tisAfterSpace = false;\n\t\t}\n\n\t\tprotected virtual void WriteIdentifier(Identifier identifier)\n\t\t{\n\t\t\twriter.WriteIdentifier(identifier);\n\t\t\tisAtStartOfLine = false;\n\t\t\tisAfterSpace = false;\n\t\t}\n\n\t\tprotected virtual void WriteIdentifier(string identifier)\n\t\t{\n\t\t\tAstType.Create(identifier).AcceptVisitor(this);\n\t\t\tisAtStartOfLine = false;\n\t\t\tisAfterSpace = false;\n\t\t}\n\n\t\tprotected virtual void WriteToken(TokenRole tokenRole)\n\t\t{\n\t\t\tWriteToken(tokenRole.Token, tokenRole);\n\t\t}\n\n\t\tprotected virtual void WriteToken(string token, Role tokenRole)\n\t\t{\n\t\t\twriter.WriteToken(tokenRole, token);\n\t\t\tisAtStartOfLine = false;\n\t\t\tisAfterSpace = false;\n\t\t}\n\n\t\tprotected virtual void LPar()\n\t\t{\n\t\t\tWriteToken(Roles.LPar);\n\t\t}\n\n\t\tprotected virtual void RPar()\n\t\t{\n\t\t\tWriteToken(Roles.RPar);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Marks the end of a statement\n\t\t/// </summary>\n\t\tprotected virtual void Semicolon()\n\t\t{\n\t\t\t// get the role of the current node\n\t\t\tRole role = containerStack.Peek().Role;\n\t\t\tif (!SkipToken())\n\t\t\t{\n\t\t\t\tWriteToken(Roles.Semicolon);\n\t\t\t\tif (!SkipNewLine())\n\t\t\t\t\tNewLine();\n\t\t\t\telse\n\t\t\t\t\tSpace();\n\t\t\t}\n\n\t\t\tbool SkipToken()\n\t\t\t{\n\t\t\t\treturn role == ForStatement.InitializerRole\n\t\t\t\t\t|| role == ForStatement.IteratorRole\n\t\t\t\t\t|| role == UsingStatement.ResourceAcquisitionRole;\n\t\t\t}\n\n\t\t\tbool SkipNewLine()\n\t\t\t{\n\t\t\t\tif (containerStack.Peek() is not Accessor accessor)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(role == PropertyDeclaration.GetterRole || role == PropertyDeclaration.SetterRole))\n\t\t\t\t\treturn false;\n\t\t\t\tbool isAutoProperty = accessor.Body.IsNull\n\t\t\t\t\t&& !accessor.Attributes.Any()\n\t\t\t\t\t&& policy.AutoPropertyFormatting == PropertyFormatting.SingleLine;\n\t\t\t\treturn isAutoProperty;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Writes a space depending on policy.\n\t\t/// </summary>\n\t\tprotected virtual void Space(bool addSpace = true)\n\t\t{\n\t\t\tif (addSpace && !isAfterSpace)\n\t\t\t{\n\t\t\t\twriter.Space();\n\t\t\t\tisAfterSpace = true;\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual void NewLine()\n\t\t{\n\t\t\twriter.NewLine();\n\t\t\tisAtStartOfLine = true;\n\t\t\tisAfterSpace = false;\n\t\t}\n\n\t\tint GetCallChainLengthLimited(MemberReferenceExpression expr)\n\t\t{\n\t\t\tint callChainLength = 0;\n\t\t\tvar node = expr;\n\n\t\t\twhile (node.Target is InvocationExpression invocation && invocation.Target is MemberReferenceExpression mre && callChainLength < 4)\n\t\t\t{\n\t\t\t\tnode = mre;\n\t\t\t\tcallChainLength++;\n\t\t\t}\n\t\t\treturn callChainLength;\n\t\t}\n\n\t\tint ShouldInsertNewLineWhenInMethodCallChain(MemberReferenceExpression expr)\n\t\t{\n\t\t\tint callChainLength = GetCallChainLengthLimited(expr);\n\t\t\tif (callChainLength < 3)\n\t\t\t\treturn 0;\n\t\t\tif (expr.GetParent(n => n is Statement || n is LambdaExpression || n is InterpolatedStringContent) is InterpolatedStringContent)\n\t\t\t\treturn 0;\n\t\t\treturn callChainLength;\n\t\t}\n\n\t\tprotected virtual bool InsertNewLineWhenInMethodCallChain(MemberReferenceExpression expr)\n\t\t{\n\t\t\tint callChainLength = ShouldInsertNewLineWhenInMethodCallChain(expr);\n\t\t\tif (callChainLength == 0)\n\t\t\t\treturn false;\n\t\t\tif (callChainLength == 3)\n\t\t\t\twriter.Indent();\n\t\t\twriter.NewLine();\n\n\t\t\tisAtStartOfLine = true;\n\t\t\tisAfterSpace = false;\n\t\t\treturn true;\n\t\t}\n\n\t\tprotected virtual void OpenBrace(BraceStyle style, bool newLine = true)\n\t\t{\n\t\t\tswitch (style)\n\t\t\t{\n\t\t\t\tcase BraceStyle.EndOfLine:\n\t\t\t\tcase BraceStyle.BannerStyle:\n\t\t\t\t\tif (!isAtStartOfLine)\n\t\t\t\t\t\tSpace();\n\t\t\t\t\tWriteToken(\"{\", Roles.LBrace);\n\t\t\t\t\tbreak;\n\t\t\t\tcase BraceStyle.EndOfLineWithoutSpace:\n\t\t\t\t\tWriteToken(\"{\", Roles.LBrace);\n\t\t\t\t\tbreak;\n\t\t\t\tcase BraceStyle.NextLine:\n\t\t\t\t\tif (!isAtStartOfLine)\n\t\t\t\t\t\tNewLine();\n\t\t\t\t\tWriteToken(\"{\", Roles.LBrace);\n\t\t\t\t\tbreak;\n\t\t\t\tcase BraceStyle.NextLineShifted:\n\t\t\t\t\tNewLine();\n\t\t\t\t\twriter.Indent();\n\t\t\t\t\tWriteToken(\"{\", Roles.LBrace);\n\t\t\t\t\tNewLine();\n\t\t\t\t\treturn;\n\t\t\t\tcase BraceStyle.NextLineShifted2:\n\t\t\t\t\tNewLine();\n\t\t\t\t\twriter.Indent();\n\t\t\t\t\tWriteToken(\"{\", Roles.LBrace);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t}\n\t\t\tif (newLine)\n\t\t\t{\n\t\t\t\twriter.Indent();\n\t\t\t\tNewLine();\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual void CloseBrace(BraceStyle style, bool unindent = true)\n\t\t{\n\t\t\tswitch (style)\n\t\t\t{\n\t\t\t\tcase BraceStyle.EndOfLine:\n\t\t\t\tcase BraceStyle.EndOfLineWithoutSpace:\n\t\t\t\tcase BraceStyle.NextLine:\n\t\t\t\t\tif (unindent)\n\t\t\t\t\t\twriter.Unindent();\n\t\t\t\t\tWriteToken(\"}\", Roles.RBrace);\n\t\t\t\t\tbreak;\n\t\t\t\tcase BraceStyle.BannerStyle:\n\t\t\t\tcase BraceStyle.NextLineShifted:\n\t\t\t\t\tWriteToken(\"}\", Roles.RBrace);\n\t\t\t\t\tif (unindent)\n\t\t\t\t\t\twriter.Unindent();\n\t\t\t\t\tbreak;\n\t\t\t\tcase BraceStyle.NextLineShifted2:\n\t\t\t\t\tif (unindent)\n\t\t\t\t\t\twriter.Unindent();\n\t\t\t\t\tWriteToken(\"}\", Roles.RBrace);\n\t\t\t\t\tif (unindent)\n\t\t\t\t\t\twriter.Unindent();\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t}\n\t\t}\n\n\t\t#endregion\n\n\t\t#region IsKeyword Test\n\t\tstatic readonly HashSet<string> unconditionalKeywords = new HashSet<string> {\n\t\t\t\"abstract\", \"as\", \"base\", \"bool\", \"break\", \"byte\", \"case\", \"catch\",\n\t\t\t\"char\", \"checked\", \"class\", \"const\", \"continue\", \"decimal\", \"default\", \"delegate\",\n\t\t\t\"do\", \"double\", \"else\", \"enum\", \"event\", \"explicit\", \"extern\", \"false\",\n\t\t\t\"finally\", \"fixed\", \"float\", \"for\", \"foreach\", \"goto\", \"if\", \"implicit\",\n\t\t\t\"in\", \"int\", \"interface\", \"internal\", \"is\", \"lock\", \"long\", \"namespace\",\n\t\t\t\"new\", \"null\", \"object\", \"operator\", \"out\", \"override\", \"params\", \"private\",\n\t\t\t\"protected\", \"public\", \"readonly\", \"ref\", \"return\", \"sbyte\", \"sealed\", \"short\",\n\t\t\t\"sizeof\", \"stackalloc\", \"static\", \"string\", \"struct\", \"switch\", \"this\", \"throw\",\n\t\t\t\"true\", \"try\", \"typeof\", \"uint\", \"ulong\", \"unchecked\", \"unsafe\", \"ushort\",\n\t\t\t\"using\", \"virtual\", \"void\", \"volatile\", \"while\"\n\t\t};\n\t\tstatic readonly HashSet<string> queryKeywords = new HashSet<string> {\n\t\t\t\"from\", \"where\", \"join\", \"on\", \"equals\", \"into\", \"let\", \"orderby\",\n\t\t\t\"ascending\", \"descending\", \"select\", \"group\", \"by\"\n\t\t};\n\t\tstatic readonly int maxKeywordLength = unconditionalKeywords.Concat(queryKeywords).Max(s => s.Length);\n\n\t\t/// <summary>\n\t\t/// Determines whether the specified identifier is a keyword in the given context.\n\t\t/// If <paramref name=\"context\"/> is <see langword=\"null\" /> all keywords are treated as unconditional.\n\t\t/// </summary>\n\t\tpublic static bool IsKeyword(string identifier, AstNode context = null)\n\t\t{\n\t\t\t// only 2-10 char lower-case identifiers can be keywords\n\t\t\tif (identifier.Length > maxKeywordLength || identifier.Length < 2 || identifier[0] < 'a')\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (unconditionalKeywords.Contains(identifier))\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (queryKeywords.Contains(identifier))\n\t\t\t{\n\t\t\t\treturn context == null || context.Ancestors.Any(ancestor => ancestor is QueryExpression);\n\t\t\t}\n\t\t\tif (identifier == \"await\")\n\t\t\t{\n\t\t\t\tif (context == null)\n\t\t\t\t\treturn true;\n\t\t\t\tforeach (AstNode ancestor in context.Ancestors)\n\t\t\t\t{\n\t\t\t\t\t// with lambdas/anonymous methods,\n\t\t\t\t\tif (ancestor is LambdaExpression)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn ((LambdaExpression)ancestor).IsAsync;\n\t\t\t\t\t}\n\t\t\t\t\tif (ancestor is AnonymousMethodExpression)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn ((AnonymousMethodExpression)ancestor).IsAsync;\n\t\t\t\t\t}\n\t\t\t\t\tif (ancestor is EntityDeclaration)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn (((EntityDeclaration)ancestor).Modifiers & Modifiers.Async) == Modifiers.Async;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\t#endregion\n\n\t\t#region Write constructs\n\t\tprotected virtual void WriteTypeArguments(IEnumerable<AstType> typeArguments)\n\t\t{\n\t\t\tif (typeArguments.Any())\n\t\t\t{\n\t\t\t\tWriteToken(Roles.LChevron);\n\t\t\t\tWriteCommaSeparatedList(typeArguments);\n\t\t\t\tWriteToken(Roles.RChevron);\n\t\t\t}\n\t\t}\n\n\t\tpublic virtual void WriteTypeParameters(IEnumerable<TypeParameterDeclaration> typeParameters)\n\t\t{\n\t\t\tif (typeParameters.Any())\n\t\t\t{\n\t\t\t\tWriteToken(Roles.LChevron);\n\t\t\t\tWriteCommaSeparatedList(typeParameters);\n\t\t\t\tWriteToken(Roles.RChevron);\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual void WriteModifiers(IEnumerable<CSharpModifierToken> modifierTokens)\n\t\t{\n\t\t\tforeach (CSharpModifierToken modifier in modifierTokens)\n\t\t\t{\n\t\t\t\tmodifier.AcceptVisitor(this);\n\t\t\t\tSpace();\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual void WriteQualifiedIdentifier(IEnumerable<Identifier> identifiers)\n\t\t{\n\t\t\tbool first = true;\n\t\t\tforeach (Identifier ident in identifiers)\n\t\t\t{\n\t\t\t\tif (first)\n\t\t\t\t{\n\t\t\t\t\tfirst = false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\twriter.WriteToken(Roles.Dot, \".\");\n\t\t\t\t}\n\t\t\t\twriter.WriteIdentifier(ident);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Writes an embedded statement.\n\t\t/// </summary>\n\t\t/// <param name=\"embeddedStatement\">The statement to write.</param>\n\t\t/// <param name=\"nlp\">Determines whether a trailing newline should be written following a block.\n\t\t/// Non-blocks always write a trailing newline.</param>\n\t\t/// <remarks>\n\t\t/// Blocks may or may not write a leading newline depending on StatementBraceStyle.\n\t\t/// Non-blocks always write a leading newline.\n\t\t/// </remarks>\n\t\tprotected virtual void WriteEmbeddedStatement(Statement embeddedStatement, NewLinePlacement nlp = NewLinePlacement.NewLine)\n\t\t{\n\t\t\tif (embeddedStatement.IsNull)\n\t\t\t{\n\t\t\t\tNewLine();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tBlockStatement block = embeddedStatement as BlockStatement;\n\t\t\tif (block != null)\n\t\t\t{\n\t\t\t\tWriteBlock(block, policy.StatementBraceStyle);\n\t\t\t\tif (nlp == NewLinePlacement.SameLine)\n\t\t\t\t{\n\t\t\t\t\tSpace(); // if not a trailing newline, then at least a trailing space\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tNewLine();\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tNewLine();\n\t\t\t\twriter.Indent();\n\t\t\t\tembeddedStatement.AcceptVisitor(this);\n\t\t\t\twriter.Unindent();\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual void WriteMethodBody(BlockStatement body, BraceStyle style, bool newLine = true)\n\t\t{\n\t\t\tif (body.IsNull)\n\t\t\t{\n\t\t\t\tSemicolon();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tWriteBlock(body, style);\n\t\t\t\tNewLine();\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual void WriteAttributes(IEnumerable<AttributeSection> attributes)\n\t\t{\n\t\t\tforeach (AttributeSection attr in attributes)\n\t\t\t{\n\t\t\t\tattr.AcceptVisitor(this);\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual void WritePrivateImplementationType(AstType privateImplementationType)\n\t\t{\n\t\t\tif (!privateImplementationType.IsNull)\n\t\t\t{\n\t\t\t\tprivateImplementationType.AcceptVisitor(this);\n\t\t\t\tWriteToken(Roles.Dot);\n\t\t\t}\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Expressions\n\t\tpublic virtual void VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression)\n\t\t{\n\t\t\tStartNode(anonymousMethodExpression);\n\t\t\tif (anonymousMethodExpression.IsAsync)\n\t\t\t{\n\t\t\t\tWriteKeyword(AnonymousMethodExpression.AsyncModifierRole);\n\t\t\t\tSpace();\n\t\t\t}\n\t\t\tWriteKeyword(AnonymousMethodExpression.DelegateKeywordRole);\n\t\t\tif (anonymousMethodExpression.HasParameterList)\n\t\t\t{\n\t\t\t\tSpace(policy.SpaceBeforeAnonymousMethodParentheses);\n\t\t\t\tWriteCommaSeparatedListInParenthesis(anonymousMethodExpression.Parameters, policy.SpaceWithinAnonymousMethodParentheses);\n\t\t\t}\n\t\t\tWriteBlock(anonymousMethodExpression.Body, policy.AnonymousMethodBraceStyle);\n\t\t\tEndNode(anonymousMethodExpression);\n\t\t}\n\n\t\tpublic virtual void VisitUndocumentedExpression(UndocumentedExpression undocumentedExpression)\n\t\t{\n\t\t\tStartNode(undocumentedExpression);\n\t\t\tswitch (undocumentedExpression.UndocumentedExpressionType)\n\t\t\t{\n\t\t\t\tcase UndocumentedExpressionType.ArgList:\n\t\t\t\tcase UndocumentedExpressionType.ArgListAccess:\n\t\t\t\t\tWriteKeyword(UndocumentedExpression.ArglistKeywordRole);\n\t\t\t\t\tbreak;\n\t\t\t\tcase UndocumentedExpressionType.MakeRef:\n\t\t\t\t\tWriteKeyword(UndocumentedExpression.MakerefKeywordRole);\n\t\t\t\t\tbreak;\n\t\t\t\tcase UndocumentedExpressionType.RefType:\n\t\t\t\t\tWriteKeyword(UndocumentedExpression.ReftypeKeywordRole);\n\t\t\t\t\tbreak;\n\t\t\t\tcase UndocumentedExpressionType.RefValue:\n\t\t\t\t\tWriteKeyword(UndocumentedExpression.RefvalueKeywordRole);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (undocumentedExpression.UndocumentedExpressionType != UndocumentedExpressionType.ArgListAccess)\n\t\t\t{\n\t\t\t\tSpace(policy.SpaceBeforeMethodCallParentheses);\n\t\t\t\tWriteCommaSeparatedListInParenthesis(undocumentedExpression.Arguments, policy.SpaceWithinMethodCallParentheses);\n\t\t\t}\n\t\t\tEndNode(undocumentedExpression);\n\t\t}\n\n\t\tpublic virtual void VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression)\n\t\t{\n\t\t\tStartNode(arrayCreateExpression);\n\t\t\tWriteKeyword(ArrayCreateExpression.NewKeywordRole);\n\t\t\tarrayCreateExpression.Type.AcceptVisitor(this);\n\t\t\tif (arrayCreateExpression.Arguments.Count > 0)\n\t\t\t{\n\t\t\t\tWriteCommaSeparatedListInBrackets(arrayCreateExpression.Arguments);\n\t\t\t}\n\t\t\tforeach (var specifier in arrayCreateExpression.AdditionalArraySpecifiers)\n\t\t\t{\n\t\t\t\tspecifier.AcceptVisitor(this);\n\t\t\t}\n\t\t\tarrayCreateExpression.Initializer.AcceptVisitor(this);\n\t\t\tEndNode(arrayCreateExpression);\n\t\t}\n\n\t\tpublic virtual void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)\n\t\t{\n\t\t\tStartNode(arrayInitializerExpression);\n\t\t\t// \"new List<int> { { 1 } }\" and \"new List<int> { 1 }\" are the same semantically.\n\t\t\t// We also use the same AST for both: we always use two nested ArrayInitializerExpressions\n\t\t\t// for collection initializers, even if the user did not write nested brackets.\n\t\t\t// The output visitor will output nested braces only if they are necessary,\n\t\t\t// or if the braces tokens exist in the AST.\n\t\t\tbool bracesAreOptional = arrayInitializerExpression.Elements.Count == 1\n\t\t\t\t&& IsObjectOrCollectionInitializer(arrayInitializerExpression.Parent)\n\t\t\t\t&& !CanBeConfusedWithObjectInitializer(arrayInitializerExpression.Elements.Single());\n\t\t\tif (bracesAreOptional && arrayInitializerExpression.LBraceToken.IsNull)\n\t\t\t{\n\t\t\t\tarrayInitializerExpression.Elements.Single().AcceptVisitor(this);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tPrintInitializerElements(arrayInitializerExpression.Elements);\n\t\t\t}\n\t\t\tEndNode(arrayInitializerExpression);\n\t\t}\n\n\t\tprotected bool CanBeConfusedWithObjectInitializer(Expression expr)\n\t\t{\n\t\t\t// \"int a; new List<int> { a = 1 };\" is an object initalizers and invalid, but\n\t\t\t// \"int a; new List<int> { { a = 1 } };\" is a valid collection initializer.\n\t\t\tAssignmentExpression ae = expr as AssignmentExpression;\n\t\t\treturn ae != null && ae.Operator == AssignmentOperatorType.Assign;\n\t\t}\n\n\t\tprotected bool IsObjectOrCollectionInitializer(AstNode node)\n\t\t{\n\t\t\tif (!(node is ArrayInitializerExpression))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (node.Parent is ObjectCreateExpression)\n\t\t\t{\n\t\t\t\treturn node.Role == ObjectCreateExpression.InitializerRole;\n\t\t\t}\n\t\t\tif (node.Parent is NamedExpression)\n\t\t\t{\n\t\t\t\treturn node.Role == Roles.Expression;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tprotected virtual void PrintInitializerElements(AstNodeCollection<Expression> elements)\n\t\t{\n\t\t\tbool wrapAlways = policy.ArrayInitializerWrapping == Wrapping.WrapAlways\n\t\t\t\t|| (elements.Count > 1 && elements.Any(e => !IsSimpleExpression(e)))\n\t\t\t\t|| elements.Any(IsComplexExpression);\n\t\t\tbool wrap = wrapAlways\n\t\t\t\t|| elements.Count > 10;\n\t\t\tOpenBrace(wrap ? policy.ArrayInitializerBraceStyle : BraceStyle.EndOfLine, newLine: wrap);\n\t\t\tif (!wrap)\n\t\t\t\tSpace();\n\t\t\tAstNode last = null;\n\t\t\tforeach (var (idx, node) in elements.WithIndex())\n\t\t\t{\n\t\t\t\tif (idx > 0)\n\t\t\t\t{\n\t\t\t\t\tComma(node, noSpaceAfterComma: true);\n\t\t\t\t\tif (wrapAlways || idx % 10 == 0)\n\t\t\t\t\t\tNewLine();\n\t\t\t\t\telse\n\t\t\t\t\t\tSpace();\n\t\t\t\t}\n\t\t\t\tlast = node;\n\t\t\t\tnode.AcceptVisitor(this);\n\t\t\t}\n\t\t\tif (last != null)\n\t\t\t\tOptionalComma(last.NextSibling);\n\t\t\tif (wrap)\n\t\t\t\tNewLine();\n\t\t\telse\n\t\t\t\tSpace();\n\t\t\tCloseBrace(wrap ? policy.ArrayInitializerBraceStyle : BraceStyle.EndOfLine, unindent: wrap);\n\n\t\t\tbool IsSimpleExpression(Expression ex)\n\t\t\t{\n\t\t\t\tswitch (ex)\n\t\t\t\t{\n\t\t\t\t\tcase NullReferenceExpression _:\n\t\t\t\t\tcase ThisReferenceExpression _:\n\t\t\t\t\tcase PrimitiveExpression _:\n\t\t\t\t\tcase IdentifierExpression _:\n\t\t\t\t\tcase MemberReferenceExpression {\n\t\t\t\t\t\tTarget: ThisReferenceExpression\n\t\t\t\t\t\t\tor IdentifierExpression\n\t\t\t\t\t\t\tor BaseReferenceExpression\n\t\t\t\t\t} _:\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool IsComplexExpression(Expression ex)\n\t\t\t{\n\t\t\t\tswitch (ex)\n\t\t\t\t{\n\t\t\t\t\tcase AnonymousMethodExpression _:\n\t\t\t\t\tcase LambdaExpression _:\n\t\t\t\t\tcase AnonymousTypeCreateExpression _:\n\t\t\t\t\tcase ObjectCreateExpression _:\n\t\t\t\t\tcase NamedExpression _:\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic virtual void VisitAsExpression(AsExpression asExpression)\n\t\t{\n\t\t\tStartNode(asExpression);\n\t\t\tasExpression.Expression.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWriteKeyword(AsExpression.AsKeywordRole);\n\t\t\tSpace();\n\t\t\tasExpression.Type.AcceptVisitor(this);\n\t\t\tEndNode(asExpression);\n\t\t}\n\n\t\tpublic virtual void VisitAssignmentExpression(AssignmentExpression assignmentExpression)\n\t\t{\n\t\t\tStartNode(assignmentExpression);\n\t\t\tassignmentExpression.Left.AcceptVisitor(this);\n\t\t\tSpace(policy.SpaceAroundAssignment);\n\t\t\tWriteToken(AssignmentExpression.GetOperatorRole(assignmentExpression.Operator));\n\t\t\tSpace(policy.SpaceAroundAssignment);\n\t\t\tassignmentExpression.Right.AcceptVisitor(this);\n\t\t\tEndNode(assignmentExpression);\n\t\t}\n\n\t\tpublic virtual void VisitBaseReferenceExpression(BaseReferenceExpression baseReferenceExpression)\n\t\t{\n\t\t\tStartNode(baseReferenceExpression);\n\t\t\tWriteKeyword(\"base\", baseReferenceExpression.Role);\n\t\t\tEndNode(baseReferenceExpression);\n\t\t}\n\n\t\tpublic virtual void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)\n\t\t{\n\t\t\tStartNode(binaryOperatorExpression);\n\t\t\tbinaryOperatorExpression.Left.AcceptVisitor(this);\n\t\t\tbool spacePolicy;\n\t\t\tswitch (binaryOperatorExpression.Operator)\n\t\t\t{\n\t\t\t\tcase BinaryOperatorType.BitwiseAnd:\n\t\t\t\tcase BinaryOperatorType.BitwiseOr:\n\t\t\t\tcase BinaryOperatorType.ExclusiveOr:\n\t\t\t\t\tspacePolicy = policy.SpaceAroundBitwiseOperator;\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.ConditionalAnd:\n\t\t\t\tcase BinaryOperatorType.ConditionalOr:\n\t\t\t\t\tspacePolicy = policy.SpaceAroundLogicalOperator;\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.GreaterThan:\n\t\t\t\tcase BinaryOperatorType.GreaterThanOrEqual:\n\t\t\t\tcase BinaryOperatorType.LessThanOrEqual:\n\t\t\t\tcase BinaryOperatorType.LessThan:\n\t\t\t\t\tspacePolicy = policy.SpaceAroundRelationalOperator;\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.Equality:\n\t\t\t\tcase BinaryOperatorType.InEquality:\n\t\t\t\t\tspacePolicy = policy.SpaceAroundEqualityOperator;\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.Add:\n\t\t\t\tcase BinaryOperatorType.Subtract:\n\t\t\t\t\tspacePolicy = policy.SpaceAroundAdditiveOperator;\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.Multiply:\n\t\t\t\tcase BinaryOperatorType.Divide:\n\t\t\t\tcase BinaryOperatorType.Modulus:\n\t\t\t\t\tspacePolicy = policy.SpaceAroundMultiplicativeOperator;\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.ShiftLeft:\n\t\t\t\tcase BinaryOperatorType.ShiftRight:\n\t\t\t\tcase BinaryOperatorType.UnsignedShiftRight:\n\t\t\t\t\tspacePolicy = policy.SpaceAroundShiftOperator;\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.NullCoalescing:\n\t\t\t\tcase BinaryOperatorType.IsPattern:\n\t\t\t\t\tspacePolicy = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.Range:\n\t\t\t\t\tspacePolicy = false;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException(\"Invalid value for BinaryOperatorType\");\n\t\t\t}\n\t\t\tSpace(spacePolicy);\n\t\t\tTokenRole tokenRole = BinaryOperatorExpression.GetOperatorRole(binaryOperatorExpression.Operator);\n\t\t\tif (tokenRole == BinaryOperatorExpression.IsKeywordRole)\n\t\t\t{\n\t\t\t\tWriteKeyword(tokenRole);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tWriteToken(tokenRole);\n\t\t\t}\n\t\t\tSpace(spacePolicy);\n\t\t\tbinaryOperatorExpression.Right.AcceptVisitor(this);\n\t\t\tEndNode(binaryOperatorExpression);\n\t\t}\n\n\t\tpublic virtual void VisitCastExpression(CastExpression castExpression)\n\t\t{\n\t\t\tStartNode(castExpression);\n\t\t\tLPar();\n\t\t\tSpace(policy.SpacesWithinCastParentheses);\n\t\t\tcastExpression.Type.AcceptVisitor(this);\n\t\t\tSpace(policy.SpacesWithinCastParentheses);\n\t\t\tRPar();\n\t\t\tSpace(policy.SpaceAfterTypecast);\n\t\t\tcastExpression.Expression.AcceptVisitor(this);\n\t\t\tEndNode(castExpression);\n\t\t}\n\n\t\tpublic virtual void VisitCheckedExpression(CheckedExpression checkedExpression)\n\t\t{\n\t\t\tStartNode(checkedExpression);\n\t\t\tWriteKeyword(CheckedExpression.CheckedKeywordRole);\n\t\t\tLPar();\n\t\t\tSpace(policy.SpacesWithinCheckedExpressionParantheses);\n\t\t\tcheckedExpression.Expression.AcceptVisitor(this);\n\t\t\tSpace(policy.SpacesWithinCheckedExpressionParantheses);\n\t\t\tRPar();\n\t\t\tEndNode(checkedExpression);\n\t\t}\n\n\t\tpublic virtual void VisitConditionalExpression(ConditionalExpression conditionalExpression)\n\t\t{\n\t\t\tStartNode(conditionalExpression);\n\t\t\tconditionalExpression.Condition.AcceptVisitor(this);\n\n\t\t\tSpace(policy.SpaceBeforeConditionalOperatorCondition);\n\t\t\tWriteToken(ConditionalExpression.QuestionMarkRole);\n\t\t\tSpace(policy.SpaceAfterConditionalOperatorCondition);\n\n\t\t\tconditionalExpression.TrueExpression.AcceptVisitor(this);\n\n\t\t\tSpace(policy.SpaceBeforeConditionalOperatorSeparator);\n\t\t\tWriteToken(ConditionalExpression.ColonRole);\n\t\t\tSpace(policy.SpaceAfterConditionalOperatorSeparator);\n\n\t\t\tconditionalExpression.FalseExpression.AcceptVisitor(this);\n\n\t\t\tEndNode(conditionalExpression);\n\t\t}\n\n\t\tpublic virtual void VisitDefaultValueExpression(DefaultValueExpression defaultValueExpression)\n\t\t{\n\t\t\tStartNode(defaultValueExpression);\n\n\t\t\tWriteKeyword(DefaultValueExpression.DefaultKeywordRole);\n\t\t\tLPar();\n\t\t\tSpace(policy.SpacesWithinTypeOfParentheses);\n\t\t\tdefaultValueExpression.Type.AcceptVisitor(this);\n\t\t\tSpace(policy.SpacesWithinTypeOfParentheses);\n\t\t\tRPar();\n\n\t\t\tEndNode(defaultValueExpression);\n\t\t}\n\n\t\tpublic virtual void VisitDirectionExpression(DirectionExpression directionExpression)\n\t\t{\n\t\t\tStartNode(directionExpression);\n\n\t\t\tswitch (directionExpression.FieldDirection)\n\t\t\t{\n\t\t\t\tcase FieldDirection.Out:\n\t\t\t\t\tWriteKeyword(DirectionExpression.OutKeywordRole);\n\t\t\t\t\tbreak;\n\t\t\t\tcase FieldDirection.Ref:\n\t\t\t\t\tWriteKeyword(DirectionExpression.RefKeywordRole);\n\t\t\t\t\tbreak;\n\t\t\t\tcase FieldDirection.In:\n\t\t\t\t\tWriteKeyword(DirectionExpression.InKeywordRole);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException(\"Invalid value for FieldDirection\");\n\t\t\t}\n\t\t\tSpace();\n\t\t\tdirectionExpression.Expression.AcceptVisitor(this);\n\n\t\t\tEndNode(directionExpression);\n\t\t}\n\n\t\tpublic virtual void VisitDeclarationExpression(DeclarationExpression declarationExpression)\n\t\t{\n\t\t\tStartNode(declarationExpression);\n\n\t\t\tdeclarationExpression.Type.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tdeclarationExpression.Designation.AcceptVisitor(this);\n\n\t\t\tEndNode(declarationExpression);\n\t\t}\n\n\t\tpublic virtual void VisitRecursivePatternExpression(RecursivePatternExpression recursivePatternExpression)\n\t\t{\n\t\t\tStartNode(recursivePatternExpression);\n\n\t\t\trecursivePatternExpression.Type.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tif (recursivePatternExpression.IsPositional)\n\t\t\t{\n\t\t\t\tWriteToken(Roles.LPar);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tWriteToken(Roles.LBrace);\n\t\t\t}\n\t\t\tSpace();\n\t\t\tWriteCommaSeparatedList(recursivePatternExpression.SubPatterns);\n\t\t\tSpace();\n\t\t\tif (recursivePatternExpression.IsPositional)\n\t\t\t{\n\t\t\t\tWriteToken(Roles.RPar);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tWriteToken(Roles.RBrace);\n\t\t\t}\n\t\t\tif (!recursivePatternExpression.Designation.IsNull)\n\t\t\t{\n\t\t\t\tSpace();\n\t\t\t\trecursivePatternExpression.Designation.AcceptVisitor(this);\n\t\t\t}\n\n\t\t\tEndNode(recursivePatternExpression);\n\t\t}\n\n\t\tpublic virtual void VisitOutVarDeclarationExpression(OutVarDeclarationExpression outVarDeclarationExpression)\n\t\t{\n\t\t\tStartNode(outVarDeclarationExpression);\n\n\t\t\tWriteKeyword(OutVarDeclarationExpression.OutKeywordRole);\n\t\t\tSpace();\n\t\t\toutVarDeclarationExpression.Type.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\toutVarDeclarationExpression.Variable.AcceptVisitor(this);\n\n\t\t\tEndNode(outVarDeclarationExpression);\n\t\t}\n\n\t\tpublic virtual void VisitIdentifierExpression(IdentifierExpression identifierExpression)\n\t\t{\n\t\t\tStartNode(identifierExpression);\n\t\t\tWriteIdentifier(identifierExpression.IdentifierToken);\n\t\t\tWriteTypeArguments(identifierExpression.TypeArguments);\n\t\t\tEndNode(identifierExpression);\n\t\t}\n\n\t\tpublic virtual void VisitIndexerExpression(IndexerExpression indexerExpression)\n\t\t{\n\t\t\tStartNode(indexerExpression);\n\t\t\tindexerExpression.Target.AcceptVisitor(this);\n\t\t\tSpace(policy.SpaceBeforeMethodCallParentheses);\n\t\t\tWriteCommaSeparatedListInBrackets(indexerExpression.Arguments);\n\t\t\tEndNode(indexerExpression);\n\t\t}\n\n\t\tpublic virtual void VisitInvocationExpression(InvocationExpression invocationExpression)\n\t\t{\n\t\t\tStartNode(invocationExpression);\n\t\t\tinvocationExpression.Target.AcceptVisitor(this);\n\t\t\tSpace(policy.SpaceBeforeMethodCallParentheses);\n\t\t\tWriteCommaSeparatedListInParenthesis(invocationExpression.Arguments, policy.SpaceWithinMethodCallParentheses);\n\t\t\tif (!(invocationExpression.Parent is MemberReferenceExpression))\n\t\t\t{\n\t\t\t\tif (invocationExpression.Target is MemberReferenceExpression mre)\n\t\t\t\t{\n\t\t\t\t\tif (ShouldInsertNewLineWhenInMethodCallChain(mre) >= 3)\n\t\t\t\t\t\twriter.Unindent();\n\t\t\t\t}\n\t\t\t}\n\t\t\tEndNode(invocationExpression);\n\t\t}\n\n\t\tpublic virtual void VisitIsExpression(IsExpression isExpression)\n\t\t{\n\t\t\tStartNode(isExpression);\n\t\t\tisExpression.Expression.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWriteKeyword(IsExpression.IsKeywordRole);\n\t\t\tisExpression.Type.AcceptVisitor(this);\n\t\t\tEndNode(isExpression);\n\t\t}\n\n\t\tpublic virtual void VisitLambdaExpression(LambdaExpression lambdaExpression)\n\t\t{\n\t\t\tStartNode(lambdaExpression);\n\t\t\tWriteAttributes(lambdaExpression.Attributes);\n\t\t\tif (lambdaExpression.IsAsync)\n\t\t\t{\n\t\t\t\tWriteKeyword(LambdaExpression.AsyncModifierRole);\n\t\t\t\tSpace();\n\t\t\t}\n\t\t\tif (LambdaNeedsParenthesis(lambdaExpression))\n\t\t\t{\n\t\t\t\tWriteCommaSeparatedListInParenthesis(lambdaExpression.Parameters, policy.SpaceWithinMethodDeclarationParentheses);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tlambdaExpression.Parameters.Single().AcceptVisitor(this);\n\t\t\t}\n\t\t\tSpace();\n\t\t\tWriteToken(Roles.Arrow);\n\t\t\tif (lambdaExpression.Body is BlockStatement)\n\t\t\t{\n\t\t\t\tWriteBlock((BlockStatement)lambdaExpression.Body, policy.AnonymousMethodBraceStyle);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tSpace();\n\t\t\t\tlambdaExpression.Body.AcceptVisitor(this);\n\t\t\t}\n\t\t\tEndNode(lambdaExpression);\n\t\t}\n\n\t\tprotected bool LambdaNeedsParenthesis(LambdaExpression lambdaExpression)\n\t\t{\n\t\t\tif (lambdaExpression.Parameters.Count != 1)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvar p = lambdaExpression.Parameters.Single();\n\t\t\treturn !(p.Type.IsNull && p.ParameterModifier == ReferenceKind.None && !p.IsParams);\n\t\t}\n\n\t\tpublic virtual void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression)\n\t\t{\n\t\t\tStartNode(memberReferenceExpression);\n\t\t\tmemberReferenceExpression.Target.AcceptVisitor(this);\n\t\t\tbool insertedNewLine = InsertNewLineWhenInMethodCallChain(memberReferenceExpression);\n\t\t\tWriteToken(Roles.Dot);\n\t\t\tWriteIdentifier(memberReferenceExpression.MemberNameToken);\n\t\t\tWriteTypeArguments(memberReferenceExpression.TypeArguments);\n\t\t\tif (insertedNewLine && !(memberReferenceExpression.Parent is InvocationExpression))\n\t\t\t{\n\t\t\t\twriter.Unindent();\n\t\t\t}\n\t\t\tEndNode(memberReferenceExpression);\n\t\t}\n\n\t\tpublic virtual void VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression)\n\t\t{\n\t\t\tStartNode(namedArgumentExpression);\n\t\t\tWriteIdentifier(namedArgumentExpression.NameToken);\n\t\t\tWriteToken(Roles.Colon);\n\t\t\tSpace();\n\t\t\tnamedArgumentExpression.Expression.AcceptVisitor(this);\n\t\t\tEndNode(namedArgumentExpression);\n\t\t}\n\n\t\tpublic virtual void VisitNamedExpression(NamedExpression namedExpression)\n\t\t{\n\t\t\tStartNode(namedExpression);\n\t\t\tWriteIdentifier(namedExpression.NameToken);\n\t\t\tSpace();\n\t\t\tWriteToken(Roles.Assign);\n\t\t\tSpace();\n\t\t\tnamedExpression.Expression.AcceptVisitor(this);\n\t\t\tEndNode(namedExpression);\n\t\t}\n\n\t\tpublic virtual void VisitNullReferenceExpression(NullReferenceExpression nullReferenceExpression)\n\t\t{\n\t\t\tStartNode(nullReferenceExpression);\n\t\t\twriter.WritePrimitiveValue(null);\n\t\t\tisAfterSpace = false;\n\t\t\tEndNode(nullReferenceExpression);\n\t\t}\n\n\t\tpublic virtual void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression)\n\t\t{\n\t\t\tStartNode(objectCreateExpression);\n\t\t\tWriteKeyword(ObjectCreateExpression.NewKeywordRole);\n\t\t\tobjectCreateExpression.Type.AcceptVisitor(this);\n\t\t\tbool useParenthesis = objectCreateExpression.Arguments.Any() || objectCreateExpression.Initializer.IsNull;\n\t\t\t// also use parenthesis if there is an '(' token\n\t\t\tif (!objectCreateExpression.LParToken.IsNull)\n\t\t\t{\n\t\t\t\tuseParenthesis = true;\n\t\t\t}\n\t\t\tif (useParenthesis)\n\t\t\t{\n\t\t\t\tSpace(policy.SpaceBeforeMethodCallParentheses);\n\t\t\t\tWriteCommaSeparatedListInParenthesis(objectCreateExpression.Arguments, policy.SpaceWithinMethodCallParentheses);\n\t\t\t}\n\t\t\tobjectCreateExpression.Initializer.AcceptVisitor(this);\n\t\t\tEndNode(objectCreateExpression);\n\t\t}\n\n\t\tpublic virtual void VisitAnonymousTypeCreateExpression(AnonymousTypeCreateExpression anonymousTypeCreateExpression)\n\t\t{\n\t\t\tStartNode(anonymousTypeCreateExpression);\n\t\t\tWriteKeyword(AnonymousTypeCreateExpression.NewKeywordRole);\n\t\t\tPrintInitializerElements(anonymousTypeCreateExpression.Initializers);\n\t\t\tEndNode(anonymousTypeCreateExpression);\n\t\t}\n\n\t\tpublic virtual void VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression)\n\t\t{\n\t\t\tStartNode(parenthesizedExpression);\n\t\t\tLPar();\n\t\t\tSpace(policy.SpacesWithinParentheses);\n\t\t\tparenthesizedExpression.Expression.AcceptVisitor(this);\n\t\t\tSpace(policy.SpacesWithinParentheses);\n\t\t\tRPar();\n\t\t\tEndNode(parenthesizedExpression);\n\t\t}\n\n\t\tpublic virtual void VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression)\n\t\t{\n\t\t\tStartNode(pointerReferenceExpression);\n\t\t\tpointerReferenceExpression.Target.AcceptVisitor(this);\n\t\t\tWriteToken(PointerReferenceExpression.ArrowRole);\n\t\t\tWriteIdentifier(pointerReferenceExpression.MemberNameToken);\n\t\t\tWriteTypeArguments(pointerReferenceExpression.TypeArguments);\n\t\t\tEndNode(pointerReferenceExpression);\n\t\t}\n\n\t\t#region VisitPrimitiveExpression\n\t\tpublic virtual void VisitPrimitiveExpression(PrimitiveExpression primitiveExpression)\n\t\t{\n\t\t\tStartNode(primitiveExpression);\n\t\t\twriter.WritePrimitiveValue(primitiveExpression.Value, primitiveExpression.Format);\n\t\t\tisAfterSpace = false;\n\t\t\tEndNode(primitiveExpression);\n\t\t}\n\n\t\tpublic virtual void VisitInterpolatedStringExpression(InterpolatedStringExpression interpolatedStringExpression)\n\t\t{\n\t\t\tStartNode(interpolatedStringExpression);\n\n\t\t\twriter.WriteToken(InterpolatedStringExpression.OpenQuote, \"$\\\"\");\n\t\t\tforeach (var element in interpolatedStringExpression.Content)\n\t\t\t{\n\t\t\t\telement.AcceptVisitor(this);\n\t\t\t}\n\t\t\twriter.WriteToken(InterpolatedStringExpression.CloseQuote, \"\\\"\");\n\t\t\tisAfterSpace = false;\n\n\t\t\tEndNode(interpolatedStringExpression);\n\t\t}\n\n\t\tpublic virtual void VisitInterpolation(Interpolation interpolation)\n\t\t{\n\t\t\tStartNode(interpolation);\n\n\t\t\twriter.WriteToken(Interpolation.LBrace, \"{\");\n\t\t\tinterpolation.Expression.AcceptVisitor(this);\n\t\t\tif (interpolation.Alignment != 0)\n\t\t\t{\n\t\t\t\twriter.WriteToken(Roles.Comma, \",\");\n\t\t\t\twriter.WritePrimitiveValue(interpolation.Alignment);\n\t\t\t}\n\t\t\tif (interpolation.Suffix != null)\n\t\t\t{\n\t\t\t\twriter.WriteToken(Roles.Colon, \":\");\n\t\t\t\twriter.WriteInterpolatedText(interpolation.Suffix);\n\t\t\t}\n\t\t\twriter.WriteToken(Interpolation.RBrace, \"}\");\n\n\t\t\tEndNode(interpolation);\n\t\t}\n\n\t\tpublic virtual void VisitInterpolatedStringText(InterpolatedStringText interpolatedStringText)\n\t\t{\n\t\t\tStartNode(interpolatedStringText);\n\t\t\twriter.WriteInterpolatedText(interpolatedStringText.Text);\n\t\t\tEndNode(interpolatedStringText);\n\t\t}\n\t\t#endregion\n\n\t\tpublic virtual void VisitSizeOfExpression(SizeOfExpression sizeOfExpression)\n\t\t{\n\t\t\tStartNode(sizeOfExpression);\n\n\t\t\tWriteKeyword(SizeOfExpression.SizeofKeywordRole);\n\t\t\tLPar();\n\t\t\tSpace(policy.SpacesWithinSizeOfParentheses);\n\t\t\tsizeOfExpression.Type.AcceptVisitor(this);\n\t\t\tSpace(policy.SpacesWithinSizeOfParentheses);\n\t\t\tRPar();\n\n\t\t\tEndNode(sizeOfExpression);\n\t\t}\n\n\t\tpublic virtual void VisitStackAllocExpression(StackAllocExpression stackAllocExpression)\n\t\t{\n\t\t\tStartNode(stackAllocExpression);\n\t\t\tWriteKeyword(StackAllocExpression.StackallocKeywordRole);\n\t\t\tstackAllocExpression.Type.AcceptVisitor(this);\n\t\t\tWriteCommaSeparatedListInBrackets(new[] { stackAllocExpression.CountExpression });\n\t\t\tstackAllocExpression.Initializer.AcceptVisitor(this);\n\t\t\tEndNode(stackAllocExpression);\n\t\t}\n\n\t\tpublic virtual void VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression)\n\t\t{\n\t\t\tStartNode(thisReferenceExpression);\n\t\t\tWriteKeyword(\"this\", thisReferenceExpression.Role);\n\t\t\tEndNode(thisReferenceExpression);\n\t\t}\n\n\t\tpublic virtual void VisitThrowExpression(ThrowExpression throwExpression)\n\t\t{\n\t\t\tStartNode(throwExpression);\n\t\t\tWriteKeyword(ThrowExpression.ThrowKeywordRole);\n\t\t\tSpace();\n\t\t\tthrowExpression.Expression.AcceptVisitor(this);\n\t\t\tEndNode(throwExpression);\n\t\t}\n\n\t\tpublic virtual void VisitTupleExpression(TupleExpression tupleExpression)\n\t\t{\n\t\t\tDebug.Assert(tupleExpression.Elements.Count >= 2);\n\t\t\tStartNode(tupleExpression);\n\t\t\tLPar();\n\t\t\tWriteCommaSeparatedList(tupleExpression.Elements);\n\t\t\tRPar();\n\t\t\tEndNode(tupleExpression);\n\t\t}\n\n\t\tpublic virtual void VisitTypeOfExpression(TypeOfExpression typeOfExpression)\n\t\t{\n\t\t\tStartNode(typeOfExpression);\n\n\t\t\tWriteKeyword(TypeOfExpression.TypeofKeywordRole);\n\t\t\tLPar();\n\t\t\tSpace(policy.SpacesWithinTypeOfParentheses);\n\t\t\ttypeOfExpression.Type.AcceptVisitor(this);\n\t\t\tSpace(policy.SpacesWithinTypeOfParentheses);\n\t\t\tRPar();\n\n\t\t\tEndNode(typeOfExpression);\n\t\t}\n\n\t\tpublic virtual void VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression)\n\t\t{\n\t\t\tStartNode(typeReferenceExpression);\n\t\t\ttypeReferenceExpression.Type.AcceptVisitor(this);\n\t\t\tEndNode(typeReferenceExpression);\n\t\t}\n\n\t\tpublic virtual void VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression)\n\t\t{\n\t\t\tStartNode(unaryOperatorExpression);\n\t\t\tUnaryOperatorType opType = unaryOperatorExpression.Operator;\n\t\t\tvar opSymbol = UnaryOperatorExpression.GetOperatorRole(opType);\n\t\t\tif (opType is UnaryOperatorType.Await or UnaryOperatorType.PatternNot)\n\t\t\t{\n\t\t\t\tWriteKeyword(opSymbol);\n\t\t\t\tSpace();\n\t\t\t}\n\t\t\telse if (!IsPostfixOperator(opType) && opSymbol != null)\n\t\t\t{\n\t\t\t\tWriteToken(opSymbol);\n\t\t\t}\n\t\t\tunaryOperatorExpression.Expression.AcceptVisitor(this);\n\t\t\tif (IsPostfixOperator(opType))\n\t\t\t{\n\t\t\t\tWriteToken(opSymbol);\n\t\t\t}\n\t\t\tEndNode(unaryOperatorExpression);\n\t\t}\n\n\t\tstatic bool IsPostfixOperator(UnaryOperatorType op)\n\t\t{\n\t\t\treturn op == UnaryOperatorType.PostIncrement\n\t\t\t\t|| op == UnaryOperatorType.PostDecrement\n\t\t\t\t|| op == UnaryOperatorType.NullConditional\n\t\t\t\t|| op == UnaryOperatorType.SuppressNullableWarning;\n\t\t}\n\n\t\tpublic virtual void VisitUncheckedExpression(UncheckedExpression uncheckedExpression)\n\t\t{\n\t\t\tStartNode(uncheckedExpression);\n\t\t\tWriteKeyword(UncheckedExpression.UncheckedKeywordRole);\n\t\t\tLPar();\n\t\t\tSpace(policy.SpacesWithinCheckedExpressionParantheses);\n\t\t\tuncheckedExpression.Expression.AcceptVisitor(this);\n\t\t\tSpace(policy.SpacesWithinCheckedExpressionParantheses);\n\t\t\tRPar();\n\t\t\tEndNode(uncheckedExpression);\n\t\t}\n\n\t\tpublic virtual void VisitWithInitializerExpression(WithInitializerExpression withInitializerExpression)\n\t\t{\n\t\t\tStartNode(withInitializerExpression);\n\t\t\twithInitializerExpression.Expression.AcceptVisitor(this);\n\t\t\tWriteKeyword(\"with\", WithInitializerExpression.WithKeywordRole);\n\t\t\twithInitializerExpression.Initializer.AcceptVisitor(this);\n\t\t\tEndNode(withInitializerExpression);\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Query Expressions\n\t\tpublic virtual void VisitQueryExpression(QueryExpression queryExpression)\n\t\t{\n\t\t\tStartNode(queryExpression);\n\t\t\tif (queryExpression.Role != QueryContinuationClause.PrecedingQueryRole)\n\t\t\t\twriter.Indent();\n\t\t\tbool first = true;\n\t\t\tforeach (var clause in queryExpression.Clauses)\n\t\t\t{\n\t\t\t\tif (first)\n\t\t\t\t{\n\t\t\t\t\tfirst = false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (!(clause is QueryContinuationClause))\n\t\t\t\t\t{\n\t\t\t\t\t\tNewLine();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tclause.AcceptVisitor(this);\n\t\t\t}\n\t\t\tif (queryExpression.Role != QueryContinuationClause.PrecedingQueryRole)\n\t\t\t\twriter.Unindent();\n\t\t\tEndNode(queryExpression);\n\t\t}\n\n\t\tpublic virtual void VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause)\n\t\t{\n\t\t\tStartNode(queryContinuationClause);\n\t\t\tqueryContinuationClause.PrecedingQuery.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWriteKeyword(QueryContinuationClause.IntoKeywordRole);\n\t\t\tSpace();\n\t\t\tWriteIdentifier(queryContinuationClause.IdentifierToken);\n\t\t\tEndNode(queryContinuationClause);\n\t\t}\n\n\t\tpublic virtual void VisitQueryFromClause(QueryFromClause queryFromClause)\n\t\t{\n\t\t\tStartNode(queryFromClause);\n\t\t\tWriteKeyword(QueryFromClause.FromKeywordRole);\n\t\t\tqueryFromClause.Type.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWriteIdentifier(queryFromClause.IdentifierToken);\n\t\t\tSpace();\n\t\t\tWriteKeyword(QueryFromClause.InKeywordRole);\n\t\t\tSpace();\n\t\t\tqueryFromClause.Expression.AcceptVisitor(this);\n\t\t\tEndNode(queryFromClause);\n\t\t}\n\n\t\tpublic virtual void VisitQueryLetClause(QueryLetClause queryLetClause)\n\t\t{\n\t\t\tStartNode(queryLetClause);\n\t\t\tWriteKeyword(QueryLetClause.LetKeywordRole);\n\t\t\tSpace();\n\t\t\tWriteIdentifier(queryLetClause.IdentifierToken);\n\t\t\tSpace(policy.SpaceAroundAssignment);\n\t\t\tWriteToken(Roles.Assign);\n\t\t\tSpace(policy.SpaceAroundAssignment);\n\t\t\tqueryLetClause.Expression.AcceptVisitor(this);\n\t\t\tEndNode(queryLetClause);\n\t\t}\n\n\t\tpublic virtual void VisitQueryWhereClause(QueryWhereClause queryWhereClause)\n\t\t{\n\t\t\tStartNode(queryWhereClause);\n\t\t\tWriteKeyword(QueryWhereClause.WhereKeywordRole);\n\t\t\tSpace();\n\t\t\tqueryWhereClause.Condition.AcceptVisitor(this);\n\t\t\tEndNode(queryWhereClause);\n\t\t}\n\n\t\tpublic virtual void VisitQueryJoinClause(QueryJoinClause queryJoinClause)\n\t\t{\n\t\t\tStartNode(queryJoinClause);\n\t\t\tWriteKeyword(QueryJoinClause.JoinKeywordRole);\n\t\t\tqueryJoinClause.Type.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWriteIdentifier(queryJoinClause.JoinIdentifierToken);\n\t\t\tSpace();\n\t\t\tWriteKeyword(QueryJoinClause.InKeywordRole);\n\t\t\tSpace();\n\t\t\tqueryJoinClause.InExpression.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWriteKeyword(QueryJoinClause.OnKeywordRole);\n\t\t\tSpace();\n\t\t\tqueryJoinClause.OnExpression.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWriteKeyword(QueryJoinClause.EqualsKeywordRole);\n\t\t\tSpace();\n\t\t\tqueryJoinClause.EqualsExpression.AcceptVisitor(this);\n\t\t\tif (queryJoinClause.IsGroupJoin)\n\t\t\t{\n\t\t\t\tSpace();\n\t\t\t\tWriteKeyword(QueryJoinClause.IntoKeywordRole);\n\t\t\t\tWriteIdentifier(queryJoinClause.IntoIdentifierToken);\n\t\t\t}\n\t\t\tEndNode(queryJoinClause);\n\t\t}\n\n\t\tpublic virtual void VisitQueryOrderClause(QueryOrderClause queryOrderClause)\n\t\t{\n\t\t\tStartNode(queryOrderClause);\n\t\t\tWriteKeyword(QueryOrderClause.OrderbyKeywordRole);\n\t\t\tSpace();\n\t\t\tWriteCommaSeparatedList(queryOrderClause.Orderings);\n\t\t\tEndNode(queryOrderClause);\n\t\t}\n\n\t\tpublic virtual void VisitQueryOrdering(QueryOrdering queryOrdering)\n\t\t{\n\t\t\tStartNode(queryOrdering);\n\t\t\tqueryOrdering.Expression.AcceptVisitor(this);\n\t\t\tswitch (queryOrdering.Direction)\n\t\t\t{\n\t\t\t\tcase QueryOrderingDirection.Ascending:\n\t\t\t\t\tSpace();\n\t\t\t\t\tWriteKeyword(QueryOrdering.AscendingKeywordRole);\n\t\t\t\t\tbreak;\n\t\t\t\tcase QueryOrderingDirection.Descending:\n\t\t\t\t\tSpace();\n\t\t\t\t\tWriteKeyword(QueryOrdering.DescendingKeywordRole);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tEndNode(queryOrdering);\n\t\t}\n\n\t\tpublic virtual void VisitQuerySelectClause(QuerySelectClause querySelectClause)\n\t\t{\n\t\t\tStartNode(querySelectClause);\n\t\t\tWriteKeyword(QuerySelectClause.SelectKeywordRole);\n\t\t\tSpace();\n\t\t\tquerySelectClause.Expression.AcceptVisitor(this);\n\t\t\tEndNode(querySelectClause);\n\t\t}\n\n\t\tpublic virtual void VisitQueryGroupClause(QueryGroupClause queryGroupClause)\n\t\t{\n\t\t\tStartNode(queryGroupClause);\n\t\t\tWriteKeyword(QueryGroupClause.GroupKeywordRole);\n\t\t\tSpace();\n\t\t\tqueryGroupClause.Projection.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWriteKeyword(QueryGroupClause.ByKeywordRole);\n\t\t\tSpace();\n\t\t\tqueryGroupClause.Key.AcceptVisitor(this);\n\t\t\tEndNode(queryGroupClause);\n\t\t}\n\n\t\t#endregion\n\n\t\t#region GeneralScope\n\t\tpublic virtual void VisitAttribute(Attribute attribute)\n\t\t{\n\t\t\tStartNode(attribute);\n\t\t\tattribute.Type.AcceptVisitor(this);\n\t\t\tif (attribute.Arguments.Count != 0 || attribute.HasArgumentList)\n\t\t\t{\n\t\t\t\tSpace(policy.SpaceBeforeMethodCallParentheses);\n\t\t\t\tWriteCommaSeparatedListInParenthesis(attribute.Arguments, policy.SpaceWithinMethodCallParentheses);\n\t\t\t}\n\t\t\tEndNode(attribute);\n\t\t}\n\n\t\tpublic virtual void VisitAttributeSection(AttributeSection attributeSection)\n\t\t{\n\t\t\tStartNode(attributeSection);\n\t\t\tWriteToken(Roles.LBracket);\n\t\t\tif (!string.IsNullOrEmpty(attributeSection.AttributeTarget))\n\t\t\t{\n\t\t\t\tWriteKeyword(attributeSection.AttributeTarget, Roles.Identifier);\n\t\t\t\tWriteToken(Roles.Colon);\n\t\t\t\tSpace();\n\t\t\t}\n\t\t\tWriteCommaSeparatedList(attributeSection.Attributes);\n\t\t\tWriteToken(Roles.RBracket);\n\t\t\tswitch (attributeSection.Parent)\n\t\t\t{\n\t\t\t\tcase ParameterDeclaration pd:\n\t\t\t\t\tif (pd.Attributes.Last() != attributeSection)\n\t\t\t\t\t\tSpace(policy.SpaceBetweenParameterAttributeSections);\n\t\t\t\t\telse\n\t\t\t\t\t\tSpace();\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeParameterDeclaration _:\n\t\t\t\tcase ComposedType _:\n\t\t\t\tcase LambdaExpression _:\n\t\t\t\t\tSpace();\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tNewLine();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tEndNode(attributeSection);\n\t\t}\n\n\t\tpublic virtual void VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration)\n\t\t{\n\t\t\tStartNode(delegateDeclaration);\n\t\t\tWriteAttributes(delegateDeclaration.Attributes);\n\t\t\tWriteModifiers(delegateDeclaration.ModifierTokens);\n\t\t\tWriteKeyword(Roles.DelegateKeyword);\n\t\t\tdelegateDeclaration.ReturnType.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWriteIdentifier(delegateDeclaration.NameToken);\n\t\t\tWriteTypeParameters(delegateDeclaration.TypeParameters);\n\t\t\tSpace(policy.SpaceBeforeDelegateDeclarationParentheses);\n\t\t\tWriteCommaSeparatedListInParenthesis(delegateDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);\n\t\t\tforeach (Constraint constraint in delegateDeclaration.Constraints)\n\t\t\t{\n\t\t\t\tconstraint.AcceptVisitor(this);\n\t\t\t}\n\t\t\tSemicolon();\n\t\t\tEndNode(delegateDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)\n\t\t{\n\t\t\tStartNode(namespaceDeclaration);\n\t\t\tWriteKeyword(Roles.NamespaceKeyword);\n\t\t\tnamespaceDeclaration.NamespaceName.AcceptVisitor(this);\n\t\t\tif (namespaceDeclaration.IsFileScoped)\n\t\t\t{\n\t\t\t\tSemicolon();\n\t\t\t\tNewLine();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tOpenBrace(policy.NamespaceBraceStyle);\n\t\t\t}\n\t\t\tforeach (var member in namespaceDeclaration.Members)\n\t\t\t{\n\t\t\t\tmember.AcceptVisitor(this);\n\t\t\t\tMaybeNewLinesAfterUsings(member);\n\t\t\t}\n\t\t\tif (!namespaceDeclaration.IsFileScoped)\n\t\t\t{\n\t\t\t\tCloseBrace(policy.NamespaceBraceStyle);\n\t\t\t\tOptionalSemicolon(namespaceDeclaration.LastChild);\n\t\t\t\tNewLine();\n\t\t\t}\n\t\t\tEndNode(namespaceDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitTypeDeclaration(TypeDeclaration typeDeclaration)\n\t\t{\n\t\t\tStartNode(typeDeclaration);\n\t\t\tWriteAttributes(typeDeclaration.Attributes);\n\t\t\tWriteModifiers(typeDeclaration.ModifierTokens);\n\t\t\tBraceStyle braceStyle;\n\t\t\tswitch (typeDeclaration.ClassType)\n\t\t\t{\n\t\t\t\tcase ClassType.Enum:\n\t\t\t\t\tWriteKeyword(Roles.EnumKeyword);\n\t\t\t\t\tbraceStyle = policy.EnumBraceStyle;\n\t\t\t\t\tbreak;\n\t\t\t\tcase ClassType.Interface:\n\t\t\t\t\tWriteKeyword(Roles.InterfaceKeyword);\n\t\t\t\t\tbraceStyle = policy.InterfaceBraceStyle;\n\t\t\t\t\tbreak;\n\t\t\t\tcase ClassType.Struct:\n\t\t\t\t\tWriteKeyword(Roles.StructKeyword);\n\t\t\t\t\tbraceStyle = policy.StructBraceStyle;\n\t\t\t\t\tbreak;\n\t\t\t\tcase ClassType.RecordClass:\n\t\t\t\t\tWriteKeyword(Roles.RecordKeyword);\n\t\t\t\t\tbraceStyle = policy.ClassBraceStyle;\n\t\t\t\t\tbreak;\n\t\t\t\tcase ClassType.RecordStruct:\n\t\t\t\t\tWriteKeyword(Roles.RecordStructKeyword);\n\t\t\t\t\tWriteKeyword(Roles.StructKeyword);\n\t\t\t\t\tbraceStyle = policy.StructBraceStyle;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tWriteKeyword(Roles.ClassKeyword);\n\t\t\t\t\tbraceStyle = policy.ClassBraceStyle;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tWriteIdentifier(typeDeclaration.NameToken);\n\t\t\tWriteTypeParameters(typeDeclaration.TypeParameters);\n\t\t\tif (typeDeclaration.HasPrimaryConstructor)\n\t\t\t{\n\t\t\t\tSpace(policy.SpaceBeforeMethodDeclarationParentheses);\n\t\t\t\tWriteCommaSeparatedListInParenthesis(typeDeclaration.PrimaryConstructorParameters, policy.SpaceWithinMethodDeclarationParentheses);\n\t\t\t}\n\t\t\tif (typeDeclaration.BaseTypes.Any())\n\t\t\t{\n\t\t\t\tSpace();\n\t\t\t\tWriteToken(Roles.Colon);\n\t\t\t\tSpace();\n\t\t\t\tWriteCommaSeparatedList(typeDeclaration.BaseTypes);\n\t\t\t}\n\t\t\tforeach (Constraint constraint in typeDeclaration.Constraints)\n\t\t\t{\n\t\t\t\tconstraint.AcceptVisitor(this);\n\t\t\t}\n\t\t\tif (typeDeclaration.ClassType is (ClassType.RecordClass or ClassType.RecordStruct) && typeDeclaration.Members.Count == 0)\n\t\t\t{\n\t\t\t\tSemicolon();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tOpenBrace(braceStyle);\n\t\t\t\tif (typeDeclaration.ClassType == ClassType.Enum)\n\t\t\t\t{\n\t\t\t\t\tbool first = true;\n\t\t\t\t\tAstNode last = null;\n\t\t\t\t\tforeach (var member in typeDeclaration.Members)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (first)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfirst = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tComma(member, noSpaceAfterComma: true);\n\t\t\t\t\t\t\tNewLine();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlast = member;\n\t\t\t\t\t\tmember.AcceptVisitor(this);\n\t\t\t\t\t}\n\t\t\t\t\tif (last != null)\n\t\t\t\t\t\tOptionalComma(last.NextSibling);\n\t\t\t\t\tNewLine();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbool first = true;\n\t\t\t\t\tforeach (var member in typeDeclaration.Members)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!first)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfor (int i = 0; i < policy.MinimumBlankLinesBetweenMembers; i++)\n\t\t\t\t\t\t\t\tNewLine();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfirst = false;\n\t\t\t\t\t\tmember.AcceptVisitor(this);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tCloseBrace(braceStyle);\n\t\t\t\tOptionalSemicolon(typeDeclaration.LastChild);\n\t\t\t\tNewLine();\n\t\t\t}\n\t\t\tEndNode(typeDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitUsingAliasDeclaration(UsingAliasDeclaration usingAliasDeclaration)\n\t\t{\n\t\t\tStartNode(usingAliasDeclaration);\n\t\t\tWriteKeyword(UsingAliasDeclaration.UsingKeywordRole);\n\t\t\tWriteIdentifier(usingAliasDeclaration.GetChildByRole(UsingAliasDeclaration.AliasRole));\n\t\t\tSpace(policy.SpaceAroundEqualityOperator);\n\t\t\tWriteToken(Roles.Assign);\n\t\t\tSpace(policy.SpaceAroundEqualityOperator);\n\t\t\tusingAliasDeclaration.Import.AcceptVisitor(this);\n\t\t\tSemicolon();\n\t\t\tEndNode(usingAliasDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitUsingDeclaration(UsingDeclaration usingDeclaration)\n\t\t{\n\t\t\tStartNode(usingDeclaration);\n\t\t\tWriteKeyword(UsingDeclaration.UsingKeywordRole);\n\t\t\tusingDeclaration.Import.AcceptVisitor(this);\n\t\t\tSemicolon();\n\t\t\tEndNode(usingDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitExternAliasDeclaration(ExternAliasDeclaration externAliasDeclaration)\n\t\t{\n\t\t\tStartNode(externAliasDeclaration);\n\t\t\tWriteKeyword(Roles.ExternKeyword);\n\t\t\tSpace();\n\t\t\tWriteKeyword(Roles.AliasKeyword);\n\t\t\tSpace();\n\t\t\tWriteIdentifier(externAliasDeclaration.NameToken);\n\t\t\tSemicolon();\n\t\t\tEndNode(externAliasDeclaration);\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Statements\n\t\tpublic virtual void VisitBlockStatement(BlockStatement blockStatement)\n\t\t{\n\t\t\tWriteBlock(blockStatement, policy.StatementBraceStyle);\n\t\t\tNewLine();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Writes a block statement.\n\t\t/// Similar to VisitBlockStatement() except that:\n\t\t/// 1) it allows customizing the BraceStyle\n\t\t/// 2) it does not write a trailing newline after the '}' (this job is left to the caller)\n\t\t/// </summary>\n\t\tprotected virtual void WriteBlock(BlockStatement blockStatement, BraceStyle style)\n\t\t{\n\t\t\tStartNode(blockStatement);\n\t\t\tOpenBrace(style);\n\t\t\tforeach (var node in blockStatement.Statements)\n\t\t\t{\n\t\t\t\tnode.AcceptVisitor(this);\n\t\t\t}\n\t\t\tCloseBrace(style);\n\t\t\tEndNode(blockStatement);\n\t\t}\n\n\t\tpublic virtual void VisitBreakStatement(BreakStatement breakStatement)\n\t\t{\n\t\t\tStartNode(breakStatement);\n\t\t\tWriteKeyword(\"break\", BreakStatement.BreakKeywordRole);\n\t\t\tSemicolon();\n\t\t\tEndNode(breakStatement);\n\t\t}\n\n\t\tpublic virtual void VisitCheckedStatement(CheckedStatement checkedStatement)\n\t\t{\n\t\t\tStartNode(checkedStatement);\n\t\t\tWriteKeyword(CheckedStatement.CheckedKeywordRole);\n\t\t\tcheckedStatement.Body.AcceptVisitor(this);\n\t\t\tEndNode(checkedStatement);\n\t\t}\n\n\t\tpublic virtual void VisitContinueStatement(ContinueStatement continueStatement)\n\t\t{\n\t\t\tStartNode(continueStatement);\n\t\t\tWriteKeyword(\"continue\", ContinueStatement.ContinueKeywordRole);\n\t\t\tSemicolon();\n\t\t\tEndNode(continueStatement);\n\t\t}\n\n\t\tpublic virtual void VisitDoWhileStatement(DoWhileStatement doWhileStatement)\n\t\t{\n\t\t\tStartNode(doWhileStatement);\n\t\t\tWriteKeyword(DoWhileStatement.DoKeywordRole);\n\t\t\tWriteEmbeddedStatement(doWhileStatement.EmbeddedStatement, policy.WhileNewLinePlacement);\n\t\t\tWriteKeyword(DoWhileStatement.WhileKeywordRole);\n\t\t\tSpace(policy.SpaceBeforeWhileParentheses);\n\t\t\tLPar();\n\t\t\tSpace(policy.SpacesWithinWhileParentheses);\n\t\t\tdoWhileStatement.Condition.AcceptVisitor(this);\n\t\t\tSpace(policy.SpacesWithinWhileParentheses);\n\t\t\tRPar();\n\t\t\tSemicolon();\n\t\t\tEndNode(doWhileStatement);\n\t\t}\n\n\t\tpublic virtual void VisitEmptyStatement(EmptyStatement emptyStatement)\n\t\t{\n\t\t\tStartNode(emptyStatement);\n\t\t\tSemicolon();\n\t\t\tEndNode(emptyStatement);\n\t\t}\n\n\t\tpublic virtual void VisitExpressionStatement(ExpressionStatement expressionStatement)\n\t\t{\n\t\t\tStartNode(expressionStatement);\n\t\t\texpressionStatement.Expression.AcceptVisitor(this);\n\t\t\tSemicolon();\n\t\t\tEndNode(expressionStatement);\n\t\t}\n\n\t\tpublic virtual void VisitFixedStatement(FixedStatement fixedStatement)\n\t\t{\n\t\t\tStartNode(fixedStatement);\n\t\t\tWriteKeyword(FixedStatement.FixedKeywordRole);\n\t\t\tSpace(policy.SpaceBeforeUsingParentheses);\n\t\t\tLPar();\n\t\t\tSpace(policy.SpacesWithinUsingParentheses);\n\t\t\tfixedStatement.Type.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWriteCommaSeparatedList(fixedStatement.Variables);\n\t\t\tSpace(policy.SpacesWithinUsingParentheses);\n\t\t\tRPar();\n\t\t\tWriteEmbeddedStatement(fixedStatement.EmbeddedStatement);\n\t\t\tEndNode(fixedStatement);\n\t\t}\n\n\t\tpublic virtual void VisitForeachStatement(ForeachStatement foreachStatement)\n\t\t{\n\t\t\tStartNode(foreachStatement);\n\t\t\tif (foreachStatement.IsAsync)\n\t\t\t\tWriteKeyword(ForeachStatement.AwaitRole);\n\t\t\tWriteKeyword(ForeachStatement.ForeachKeywordRole);\n\t\t\tSpace(policy.SpaceBeforeForeachParentheses);\n\t\t\tLPar();\n\t\t\tSpace(policy.SpacesWithinForeachParentheses);\n\t\t\tforeachStatement.VariableType.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tforeachStatement.VariableDesignation.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWriteKeyword(ForeachStatement.InKeywordRole);\n\t\t\tSpace();\n\t\t\tforeachStatement.InExpression.AcceptVisitor(this);\n\t\t\tSpace(policy.SpacesWithinForeachParentheses);\n\t\t\tRPar();\n\t\t\tWriteEmbeddedStatement(foreachStatement.EmbeddedStatement);\n\t\t\tEndNode(foreachStatement);\n\t\t}\n\n\t\tpublic virtual void VisitForStatement(ForStatement forStatement)\n\t\t{\n\t\t\tStartNode(forStatement);\n\t\t\tWriteKeyword(ForStatement.ForKeywordRole);\n\t\t\tSpace(policy.SpaceBeforeForParentheses);\n\t\t\tLPar();\n\t\t\tSpace(policy.SpacesWithinForParentheses);\n\n\t\t\tWriteCommaSeparatedList(forStatement.Initializers);\n\t\t\tSpace(policy.SpaceBeforeForSemicolon);\n\t\t\tWriteToken(Roles.Semicolon);\n\t\t\tSpace(policy.SpaceAfterForSemicolon);\n\n\t\t\tforStatement.Condition.AcceptVisitor(this);\n\t\t\tSpace(policy.SpaceBeforeForSemicolon);\n\t\t\tWriteToken(Roles.Semicolon);\n\t\t\tif (forStatement.Iterators.Any())\n\t\t\t{\n\t\t\t\tSpace(policy.SpaceAfterForSemicolon);\n\t\t\t\tWriteCommaSeparatedList(forStatement.Iterators);\n\t\t\t}\n\n\t\t\tSpace(policy.SpacesWithinForParentheses);\n\t\t\tRPar();\n\t\t\tWriteEmbeddedStatement(forStatement.EmbeddedStatement);\n\t\t\tEndNode(forStatement);\n\t\t}\n\n\t\tpublic virtual void VisitGotoCaseStatement(GotoCaseStatement gotoCaseStatement)\n\t\t{\n\t\t\tStartNode(gotoCaseStatement);\n\t\t\tWriteKeyword(GotoCaseStatement.GotoKeywordRole);\n\t\t\tWriteKeyword(GotoCaseStatement.CaseKeywordRole);\n\t\t\tSpace();\n\t\t\tgotoCaseStatement.LabelExpression.AcceptVisitor(this);\n\t\t\tSemicolon();\n\t\t\tEndNode(gotoCaseStatement);\n\t\t}\n\n\t\tpublic virtual void VisitGotoDefaultStatement(GotoDefaultStatement gotoDefaultStatement)\n\t\t{\n\t\t\tStartNode(gotoDefaultStatement);\n\t\t\tWriteKeyword(GotoDefaultStatement.GotoKeywordRole);\n\t\t\tWriteKeyword(GotoDefaultStatement.DefaultKeywordRole);\n\t\t\tSemicolon();\n\t\t\tEndNode(gotoDefaultStatement);\n\t\t}\n\n\t\tpublic virtual void VisitGotoStatement(GotoStatement gotoStatement)\n\t\t{\n\t\t\tStartNode(gotoStatement);\n\t\t\tWriteKeyword(GotoStatement.GotoKeywordRole);\n\t\t\tWriteIdentifier(gotoStatement.GetChildByRole(Roles.Identifier));\n\t\t\tSemicolon();\n\t\t\tEndNode(gotoStatement);\n\t\t}\n\n\t\tpublic virtual void VisitIfElseStatement(IfElseStatement ifElseStatement)\n\t\t{\n\t\t\tStartNode(ifElseStatement);\n\t\t\tWriteKeyword(IfElseStatement.IfKeywordRole);\n\t\t\tSpace(policy.SpaceBeforeIfParentheses);\n\t\t\tLPar();\n\t\t\tSpace(policy.SpacesWithinIfParentheses);\n\t\t\tifElseStatement.Condition.AcceptVisitor(this);\n\t\t\tSpace(policy.SpacesWithinIfParentheses);\n\t\t\tRPar();\n\n\t\t\tif (ifElseStatement.FalseStatement.IsNull)\n\t\t\t{\n\t\t\t\tWriteEmbeddedStatement(ifElseStatement.TrueStatement);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tWriteEmbeddedStatement(ifElseStatement.TrueStatement, policy.ElseNewLinePlacement);\n\t\t\t\tWriteKeyword(IfElseStatement.ElseKeywordRole);\n\t\t\t\tif (ifElseStatement.FalseStatement is IfElseStatement)\n\t\t\t\t{\n\t\t\t\t\t// don't put newline between 'else' and 'if'\n\t\t\t\t\tifElseStatement.FalseStatement.AcceptVisitor(this);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tWriteEmbeddedStatement(ifElseStatement.FalseStatement);\n\t\t\t\t}\n\t\t\t}\n\t\t\tEndNode(ifElseStatement);\n\t\t}\n\n\t\tpublic virtual void VisitLabelStatement(LabelStatement labelStatement)\n\t\t{\n\t\t\tStartNode(labelStatement);\n\t\t\tWriteIdentifier(labelStatement.GetChildByRole(Roles.Identifier));\n\t\t\tWriteToken(Roles.Colon);\n\t\t\tbool foundLabelledStatement = false;\n\t\t\tfor (AstNode tmp = labelStatement.NextSibling; tmp != null; tmp = tmp.NextSibling)\n\t\t\t{\n\t\t\t\tif (tmp.Role == labelStatement.Role)\n\t\t\t\t{\n\t\t\t\t\tfoundLabelledStatement = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!foundLabelledStatement)\n\t\t\t{\n\t\t\t\t// introduce an EmptyStatement so that the output becomes syntactically valid\n\t\t\t\tWriteToken(Roles.Semicolon);\n\t\t\t}\n\t\t\tNewLine();\n\t\t\tEndNode(labelStatement);\n\t\t}\n\n\t\tpublic virtual void VisitLockStatement(LockStatement lockStatement)\n\t\t{\n\t\t\tStartNode(lockStatement);\n\t\t\tWriteKeyword(LockStatement.LockKeywordRole);\n\t\t\tSpace(policy.SpaceBeforeLockParentheses);\n\t\t\tLPar();\n\t\t\tSpace(policy.SpacesWithinLockParentheses);\n\t\t\tlockStatement.Expression.AcceptVisitor(this);\n\t\t\tSpace(policy.SpacesWithinLockParentheses);\n\t\t\tRPar();\n\t\t\tWriteEmbeddedStatement(lockStatement.EmbeddedStatement);\n\t\t\tEndNode(lockStatement);\n\t\t}\n\n\t\tpublic virtual void VisitReturnStatement(ReturnStatement returnStatement)\n\t\t{\n\t\t\tStartNode(returnStatement);\n\t\t\tWriteKeyword(ReturnStatement.ReturnKeywordRole);\n\t\t\tif (!returnStatement.Expression.IsNull)\n\t\t\t{\n\t\t\t\tSpace();\n\t\t\t\treturnStatement.Expression.AcceptVisitor(this);\n\t\t\t}\n\t\t\tSemicolon();\n\t\t\tEndNode(returnStatement);\n\t\t}\n\n\t\tpublic virtual void VisitSwitchStatement(SwitchStatement switchStatement)\n\t\t{\n\t\t\tStartNode(switchStatement);\n\t\t\tWriteKeyword(SwitchStatement.SwitchKeywordRole);\n\t\t\tSpace(policy.SpaceBeforeSwitchParentheses);\n\t\t\tLPar();\n\t\t\tSpace(policy.SpacesWithinSwitchParentheses);\n\t\t\tswitchStatement.Expression.AcceptVisitor(this);\n\t\t\tSpace(policy.SpacesWithinSwitchParentheses);\n\t\t\tRPar();\n\t\t\tOpenBrace(policy.StatementBraceStyle);\n\t\t\tif (!policy.IndentSwitchBody)\n\t\t\t{\n\t\t\t\twriter.Unindent();\n\t\t\t}\n\n\t\t\tforeach (var section in switchStatement.SwitchSections)\n\t\t\t{\n\t\t\t\tsection.AcceptVisitor(this);\n\t\t\t}\n\n\t\t\tif (!policy.IndentSwitchBody)\n\t\t\t{\n\t\t\t\twriter.Indent();\n\t\t\t}\n\t\t\tCloseBrace(policy.StatementBraceStyle);\n\t\t\tNewLine();\n\t\t\tEndNode(switchStatement);\n\t\t}\n\n\t\tpublic virtual void VisitSwitchSection(SwitchSection switchSection)\n\t\t{\n\t\t\tStartNode(switchSection);\n\t\t\tbool first = true;\n\t\t\tforeach (var label in switchSection.CaseLabels)\n\t\t\t{\n\t\t\t\tif (!first)\n\t\t\t\t{\n\t\t\t\t\tNewLine();\n\t\t\t\t}\n\t\t\t\tlabel.AcceptVisitor(this);\n\t\t\t\tfirst = false;\n\t\t\t}\n\t\t\tbool isBlock = switchSection.Statements.Count == 1 && switchSection.Statements.Single() is BlockStatement;\n\t\t\tif (policy.IndentCaseBody && !isBlock)\n\t\t\t{\n\t\t\t\twriter.Indent();\n\t\t\t}\n\n\t\t\tif (!isBlock)\n\t\t\t\tNewLine();\n\n\t\t\tforeach (var statement in switchSection.Statements)\n\t\t\t{\n\t\t\t\tstatement.AcceptVisitor(this);\n\t\t\t}\n\n\t\t\tif (policy.IndentCaseBody && !isBlock)\n\t\t\t{\n\t\t\t\twriter.Unindent();\n\t\t\t}\n\n\t\t\tEndNode(switchSection);\n\t\t}\n\n\t\tpublic virtual void VisitCaseLabel(CaseLabel caseLabel)\n\t\t{\n\t\t\tStartNode(caseLabel);\n\t\t\tif (caseLabel.Expression.IsNull)\n\t\t\t{\n\t\t\t\tWriteKeyword(CaseLabel.DefaultKeywordRole);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tWriteKeyword(CaseLabel.CaseKeywordRole);\n\t\t\t\tSpace();\n\t\t\t\tcaseLabel.Expression.AcceptVisitor(this);\n\t\t\t}\n\t\t\tWriteToken(Roles.Colon);\n\t\t\tEndNode(caseLabel);\n\t\t}\n\n\t\tpublic virtual void VisitSwitchExpression(SwitchExpression switchExpression)\n\t\t{\n\t\t\tStartNode(switchExpression);\n\t\t\tswitchExpression.Expression.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWriteKeyword(SwitchExpression.SwitchKeywordRole);\n\t\t\tOpenBrace(policy.ArrayInitializerBraceStyle);\n\t\t\tforeach (AstNode node in switchExpression.SwitchSections)\n\t\t\t{\n\t\t\t\tnode.AcceptVisitor(this);\n\t\t\t\tComma(node);\n\t\t\t\tNewLine();\n\t\t\t}\n\t\t\tCloseBrace(policy.ArrayInitializerBraceStyle);\n\t\t\tEndNode(switchExpression);\n\t\t}\n\n\t\tpublic virtual void VisitSwitchExpressionSection(SwitchExpressionSection switchExpressionSection)\n\t\t{\n\t\t\tStartNode(switchExpressionSection);\n\t\t\tswitchExpressionSection.Pattern.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWriteToken(Roles.Arrow);\n\t\t\tSpace();\n\t\t\tswitchExpressionSection.Body.AcceptVisitor(this);\n\t\t\tEndNode(switchExpressionSection);\n\t\t}\n\n\t\tpublic virtual void VisitThrowStatement(ThrowStatement throwStatement)\n\t\t{\n\t\t\tStartNode(throwStatement);\n\t\t\tWriteKeyword(ThrowStatement.ThrowKeywordRole);\n\t\t\tif (!throwStatement.Expression.IsNull)\n\t\t\t{\n\t\t\t\tSpace();\n\t\t\t\tthrowStatement.Expression.AcceptVisitor(this);\n\t\t\t}\n\t\t\tSemicolon();\n\t\t\tEndNode(throwStatement);\n\t\t}\n\n\t\tpublic virtual void VisitTryCatchStatement(TryCatchStatement tryCatchStatement)\n\t\t{\n\t\t\tStartNode(tryCatchStatement);\n\t\t\tWriteKeyword(TryCatchStatement.TryKeywordRole);\n\t\t\tWriteBlock(tryCatchStatement.TryBlock, policy.StatementBraceStyle);\n\t\t\tforeach (var catchClause in tryCatchStatement.CatchClauses)\n\t\t\t{\n\t\t\t\tif (policy.CatchNewLinePlacement == NewLinePlacement.SameLine)\n\t\t\t\t\tSpace();\n\t\t\t\telse\n\t\t\t\t\tNewLine();\n\t\t\t\tcatchClause.AcceptVisitor(this);\n\t\t\t}\n\t\t\tif (!tryCatchStatement.FinallyBlock.IsNull)\n\t\t\t{\n\t\t\t\tif (policy.FinallyNewLinePlacement == NewLinePlacement.SameLine)\n\t\t\t\t\tSpace();\n\t\t\t\telse\n\t\t\t\t\tNewLine();\n\t\t\t\tWriteKeyword(TryCatchStatement.FinallyKeywordRole);\n\t\t\t\tWriteBlock(tryCatchStatement.FinallyBlock, policy.StatementBraceStyle);\n\t\t\t}\n\t\t\tNewLine();\n\t\t\tEndNode(tryCatchStatement);\n\t\t}\n\n\t\tpublic virtual void VisitCatchClause(CatchClause catchClause)\n\t\t{\n\t\t\tStartNode(catchClause);\n\t\t\tWriteKeyword(CatchClause.CatchKeywordRole);\n\t\t\tif (!catchClause.Type.IsNull)\n\t\t\t{\n\t\t\t\tSpace(policy.SpaceBeforeCatchParentheses);\n\t\t\t\tLPar();\n\t\t\t\tSpace(policy.SpacesWithinCatchParentheses);\n\t\t\t\tcatchClause.Type.AcceptVisitor(this);\n\t\t\t\tif (!string.IsNullOrEmpty(catchClause.VariableName))\n\t\t\t\t{\n\t\t\t\t\tSpace();\n\t\t\t\t\tWriteIdentifier(catchClause.VariableNameToken);\n\t\t\t\t}\n\t\t\t\tSpace(policy.SpacesWithinCatchParentheses);\n\t\t\t\tRPar();\n\t\t\t}\n\t\t\tif (!catchClause.Condition.IsNull)\n\t\t\t{\n\t\t\t\tSpace();\n\t\t\t\tWriteKeyword(CatchClause.WhenKeywordRole);\n\t\t\t\tSpace(policy.SpaceBeforeIfParentheses);\n\t\t\t\tWriteToken(CatchClause.CondLPar);\n\t\t\t\tSpace(policy.SpacesWithinIfParentheses);\n\t\t\t\tcatchClause.Condition.AcceptVisitor(this);\n\t\t\t\tSpace(policy.SpacesWithinIfParentheses);\n\t\t\t\tWriteToken(CatchClause.CondRPar);\n\t\t\t}\n\t\t\tWriteBlock(catchClause.Body, policy.StatementBraceStyle);\n\t\t\tEndNode(catchClause);\n\t\t}\n\n\t\tpublic virtual void VisitUncheckedStatement(UncheckedStatement uncheckedStatement)\n\t\t{\n\t\t\tStartNode(uncheckedStatement);\n\t\t\tWriteKeyword(UncheckedStatement.UncheckedKeywordRole);\n\t\t\tuncheckedStatement.Body.AcceptVisitor(this);\n\t\t\tEndNode(uncheckedStatement);\n\t\t}\n\n\t\tpublic virtual void VisitUnsafeStatement(UnsafeStatement unsafeStatement)\n\t\t{\n\t\t\tStartNode(unsafeStatement);\n\t\t\tWriteKeyword(UnsafeStatement.UnsafeKeywordRole);\n\t\t\tunsafeStatement.Body.AcceptVisitor(this);\n\t\t\tEndNode(unsafeStatement);\n\t\t}\n\n\t\tpublic virtual void VisitUsingStatement(UsingStatement usingStatement)\n\t\t{\n\t\t\tStartNode(usingStatement);\n\t\t\tif (usingStatement.IsAsync)\n\t\t\t{\n\t\t\t\tWriteKeyword(UsingStatement.AwaitRole);\n\t\t\t}\n\t\t\tWriteKeyword(UsingStatement.UsingKeywordRole);\n\t\t\tif (usingStatement.IsEnhanced)\n\t\t\t{\n\t\t\t\tSpace();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tSpace(policy.SpaceBeforeUsingParentheses);\n\t\t\t\tLPar();\n\t\t\t\tSpace(policy.SpacesWithinUsingParentheses);\n\t\t\t}\n\n\t\t\tusingStatement.ResourceAcquisition.AcceptVisitor(this);\n\n\t\t\tif (usingStatement.IsEnhanced)\n\t\t\t{\n\t\t\t\tSemicolon();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tSpace(policy.SpacesWithinUsingParentheses);\n\t\t\t\tRPar();\n\t\t\t}\n\n\t\t\tif (usingStatement.IsEnhanced)\n\t\t\t{\n\t\t\t\tif (usingStatement.EmbeddedStatement is BlockStatement blockStatement)\n\t\t\t\t{\n\t\t\t\t\tStartNode(blockStatement);\n\t\t\t\t\tforeach (var node in blockStatement.Statements)\n\t\t\t\t\t{\n\t\t\t\t\t\tnode.AcceptVisitor(this);\n\t\t\t\t\t}\n\t\t\t\t\tEndNode(blockStatement);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tusingStatement.EmbeddedStatement.AcceptVisitor(this);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tWriteEmbeddedStatement(usingStatement.EmbeddedStatement);\n\t\t\t}\n\n\t\t\tEndNode(usingStatement);\n\t\t}\n\n\t\tpublic virtual void VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement)\n\t\t{\n\t\t\tStartNode(variableDeclarationStatement);\n\t\t\tWriteModifiers(variableDeclarationStatement.GetChildrenByRole(VariableDeclarationStatement.ModifierRole));\n\t\t\tvariableDeclarationStatement.Type.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWriteCommaSeparatedList(variableDeclarationStatement.Variables);\n\t\t\tSemicolon();\n\t\t\tEndNode(variableDeclarationStatement);\n\t\t}\n\n\t\tpublic virtual void VisitLocalFunctionDeclarationStatement(LocalFunctionDeclarationStatement localFunctionDeclarationStatement)\n\t\t{\n\t\t\tStartNode(localFunctionDeclarationStatement);\n\t\t\tlocalFunctionDeclarationStatement.Declaration.AcceptVisitor(this);\n\t\t\tEndNode(localFunctionDeclarationStatement);\n\t\t}\n\n\t\tpublic virtual void VisitWhileStatement(WhileStatement whileStatement)\n\t\t{\n\t\t\tStartNode(whileStatement);\n\t\t\tWriteKeyword(WhileStatement.WhileKeywordRole);\n\t\t\tSpace(policy.SpaceBeforeWhileParentheses);\n\t\t\tLPar();\n\t\t\tSpace(policy.SpacesWithinWhileParentheses);\n\t\t\twhileStatement.Condition.AcceptVisitor(this);\n\t\t\tSpace(policy.SpacesWithinWhileParentheses);\n\t\t\tRPar();\n\t\t\tWriteEmbeddedStatement(whileStatement.EmbeddedStatement);\n\t\t\tEndNode(whileStatement);\n\t\t}\n\n\t\tpublic virtual void VisitYieldBreakStatement(YieldBreakStatement yieldBreakStatement)\n\t\t{\n\t\t\tStartNode(yieldBreakStatement);\n\t\t\tWriteKeyword(YieldBreakStatement.YieldKeywordRole);\n\t\t\tWriteKeyword(YieldBreakStatement.BreakKeywordRole);\n\t\t\tSemicolon();\n\t\t\tEndNode(yieldBreakStatement);\n\t\t}\n\n\t\tpublic virtual void VisitYieldReturnStatement(YieldReturnStatement yieldReturnStatement)\n\t\t{\n\t\t\tStartNode(yieldReturnStatement);\n\t\t\tWriteKeyword(YieldReturnStatement.YieldKeywordRole);\n\t\t\tWriteKeyword(YieldReturnStatement.ReturnKeywordRole);\n\t\t\tSpace();\n\t\t\tyieldReturnStatement.Expression.AcceptVisitor(this);\n\t\t\tSemicolon();\n\t\t\tEndNode(yieldReturnStatement);\n\t\t}\n\n\t\t#endregion\n\n\t\t#region TypeMembers\n\t\tpublic virtual void VisitAccessor(Accessor accessor)\n\t\t{\n\t\t\tStartNode(accessor);\n\t\t\tWriteAttributes(accessor.Attributes);\n\t\t\tWriteModifiers(accessor.ModifierTokens);\n\t\t\tBraceStyle style = policy.StatementBraceStyle;\n\t\t\tif (accessor.Role == PropertyDeclaration.GetterRole)\n\t\t\t{\n\t\t\t\tWriteKeyword(\"get\", PropertyDeclaration.GetKeywordRole);\n\t\t\t\tstyle = policy.PropertyGetBraceStyle;\n\t\t\t}\n\t\t\telse if (accessor.Role == PropertyDeclaration.SetterRole)\n\t\t\t{\n\t\t\t\tif (accessor.Keyword.Role == PropertyDeclaration.InitKeywordRole)\n\t\t\t\t{\n\t\t\t\t\tWriteKeyword(\"init\", PropertyDeclaration.InitKeywordRole);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tWriteKeyword(\"set\", PropertyDeclaration.SetKeywordRole);\n\t\t\t\t}\n\t\t\t\tstyle = policy.PropertySetBraceStyle;\n\t\t\t}\n\t\t\telse if (accessor.Role == CustomEventDeclaration.AddAccessorRole)\n\t\t\t{\n\t\t\t\tWriteKeyword(\"add\", CustomEventDeclaration.AddKeywordRole);\n\t\t\t\tstyle = policy.EventAddBraceStyle;\n\t\t\t}\n\t\t\telse if (accessor.Role == CustomEventDeclaration.RemoveAccessorRole)\n\t\t\t{\n\t\t\t\tWriteKeyword(\"remove\", CustomEventDeclaration.RemoveKeywordRole);\n\t\t\t\tstyle = policy.EventRemoveBraceStyle;\n\t\t\t}\n\t\t\tWriteMethodBody(accessor.Body, style);\n\t\t\tEndNode(accessor);\n\t\t}\n\n\t\tpublic virtual void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)\n\t\t{\n\t\t\tStartNode(constructorDeclaration);\n\t\t\tWriteAttributes(constructorDeclaration.Attributes);\n\t\t\tWriteModifiers(constructorDeclaration.ModifierTokens);\n\t\t\tTypeDeclaration type = constructorDeclaration.Parent as TypeDeclaration;\n\t\t\tif (type != null && type.Name != constructorDeclaration.Name)\n\t\t\t\tWriteIdentifier((Identifier)type.NameToken.Clone());\n\t\t\telse\n\t\t\t\tWriteIdentifier(constructorDeclaration.NameToken);\n\t\t\tSpace(policy.SpaceBeforeConstructorDeclarationParentheses);\n\t\t\tWriteCommaSeparatedListInParenthesis(constructorDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);\n\t\t\tif (!constructorDeclaration.Initializer.IsNull)\n\t\t\t{\n\t\t\t\tNewLine();\n\t\t\t\twriter.Indent();\n\t\t\t\tconstructorDeclaration.Initializer.AcceptVisitor(this);\n\t\t\t\twriter.Unindent();\n\t\t\t}\n\t\t\tWriteMethodBody(constructorDeclaration.Body, policy.ConstructorBraceStyle);\n\t\t\tEndNode(constructorDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitConstructorInitializer(ConstructorInitializer constructorInitializer)\n\t\t{\n\t\t\tStartNode(constructorInitializer);\n\t\t\tWriteToken(Roles.Colon);\n\t\t\tSpace();\n\t\t\tif (constructorInitializer.ConstructorInitializerType == ConstructorInitializerType.This)\n\t\t\t{\n\t\t\t\tWriteKeyword(ConstructorInitializer.ThisKeywordRole);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tWriteKeyword(ConstructorInitializer.BaseKeywordRole);\n\t\t\t}\n\t\t\tSpace(policy.SpaceBeforeMethodCallParentheses);\n\t\t\tWriteCommaSeparatedListInParenthesis(constructorInitializer.Arguments, policy.SpaceWithinMethodCallParentheses);\n\t\t\tEndNode(constructorInitializer);\n\t\t}\n\n\t\tpublic virtual void VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration)\n\t\t{\n\t\t\tStartNode(destructorDeclaration);\n\t\t\tWriteAttributes(destructorDeclaration.Attributes);\n\t\t\tWriteModifiers(destructorDeclaration.ModifierTokens);\n\t\t\tif (destructorDeclaration.ModifierTokens.Any())\n\t\t\t{\n\t\t\t\tSpace();\n\t\t\t}\n\t\t\tWriteToken(DestructorDeclaration.TildeRole);\n\t\t\tTypeDeclaration type = destructorDeclaration.Parent as TypeDeclaration;\n\t\t\tif (type != null && type.Name != destructorDeclaration.Name)\n\t\t\t\tWriteIdentifier((Identifier)type.NameToken.Clone());\n\t\t\telse\n\t\t\t\tWriteIdentifier(destructorDeclaration.NameToken);\n\t\t\tSpace(policy.SpaceBeforeConstructorDeclarationParentheses);\n\t\t\tLPar();\n\t\t\tRPar();\n\t\t\tWriteMethodBody(destructorDeclaration.Body, policy.DestructorBraceStyle);\n\t\t\tEndNode(destructorDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration)\n\t\t{\n\t\t\tStartNode(enumMemberDeclaration);\n\t\t\tWriteAttributes(enumMemberDeclaration.Attributes);\n\t\t\tWriteModifiers(enumMemberDeclaration.ModifierTokens);\n\t\t\tWriteIdentifier(enumMemberDeclaration.NameToken);\n\t\t\tif (!enumMemberDeclaration.Initializer.IsNull)\n\t\t\t{\n\t\t\t\tSpace(policy.SpaceAroundAssignment);\n\t\t\t\tWriteToken(Roles.Assign);\n\t\t\t\tSpace(policy.SpaceAroundAssignment);\n\t\t\t\tenumMemberDeclaration.Initializer.AcceptVisitor(this);\n\t\t\t}\n\t\t\tEndNode(enumMemberDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitExtensionDeclaration(ExtensionDeclaration extensionDeclaration)\n\t\t{\n\t\t\tStartNode(extensionDeclaration);\n\t\t\tWriteAttributes(extensionDeclaration.Attributes);\n\t\t\tWriteModifiers(extensionDeclaration.ModifierTokens);\n\t\t\tWriteKeyword(ExtensionDeclaration.ExtensionKeywordRole);\n\t\t\tWriteTypeParameters(extensionDeclaration.TypeParameters);\n\t\t\tSpace(policy.SpaceBeforeMethodDeclarationParentheses);\n\t\t\tWriteCommaSeparatedListInParenthesis(extensionDeclaration.ReceiverParameters, policy.SpaceWithinMethodDeclarationParentheses);\n\t\t\tforeach (Constraint constraint in extensionDeclaration.Constraints)\n\t\t\t{\n\t\t\t\tconstraint.AcceptVisitor(this);\n\t\t\t}\n\t\t\tOpenBrace(policy.ClassBraceStyle);\n\t\t\tbool first = true;\n\t\t\tforeach (var member in extensionDeclaration.Members)\n\t\t\t{\n\t\t\t\tif (!first)\n\t\t\t\t{\n\t\t\t\t\tfor (int i = 0; i < policy.MinimumBlankLinesBetweenMembers; i++)\n\t\t\t\t\t\tNewLine();\n\t\t\t\t}\n\t\t\t\tfirst = false;\n\t\t\t\tmember.AcceptVisitor(this);\n\t\t\t}\n\t\t\tCloseBrace(policy.ClassBraceStyle);\n\t\t\tNewLine();\n\t\t\tEndNode(extensionDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitEventDeclaration(EventDeclaration eventDeclaration)\n\t\t{\n\t\t\tStartNode(eventDeclaration);\n\t\t\tWriteAttributes(eventDeclaration.Attributes);\n\t\t\tWriteModifiers(eventDeclaration.ModifierTokens);\n\t\t\tWriteKeyword(EventDeclaration.EventKeywordRole);\n\t\t\teventDeclaration.ReturnType.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWriteCommaSeparatedList(eventDeclaration.Variables);\n\t\t\tSemicolon();\n\t\t\tEndNode(eventDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitCustomEventDeclaration(CustomEventDeclaration customEventDeclaration)\n\t\t{\n\t\t\tStartNode(customEventDeclaration);\n\t\t\tWriteAttributes(customEventDeclaration.Attributes);\n\t\t\tWriteModifiers(customEventDeclaration.ModifierTokens);\n\t\t\tWriteKeyword(CustomEventDeclaration.EventKeywordRole);\n\t\t\tcustomEventDeclaration.ReturnType.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWritePrivateImplementationType(customEventDeclaration.PrivateImplementationType);\n\t\t\tWriteIdentifier(customEventDeclaration.NameToken);\n\t\t\tOpenBrace(policy.EventBraceStyle);\n\t\t\t// output add/remove in their original order\n\t\t\tforeach (AstNode node in customEventDeclaration.Children)\n\t\t\t{\n\t\t\t\tif (node.Role == CustomEventDeclaration.AddAccessorRole || node.Role == CustomEventDeclaration.RemoveAccessorRole)\n\t\t\t\t{\n\t\t\t\t\tnode.AcceptVisitor(this);\n\t\t\t\t}\n\t\t\t}\n\t\t\tCloseBrace(policy.EventBraceStyle);\n\t\t\tNewLine();\n\t\t\tEndNode(customEventDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitFieldDeclaration(FieldDeclaration fieldDeclaration)\n\t\t{\n\t\t\tStartNode(fieldDeclaration);\n\t\t\tWriteAttributes(fieldDeclaration.Attributes);\n\t\t\tWriteModifiers(fieldDeclaration.ModifierTokens);\n\t\t\tfieldDeclaration.ReturnType.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWriteCommaSeparatedList(fieldDeclaration.Variables);\n\t\t\tSemicolon();\n\t\t\tEndNode(fieldDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration)\n\t\t{\n\t\t\tStartNode(fixedFieldDeclaration);\n\t\t\tWriteAttributes(fixedFieldDeclaration.Attributes);\n\t\t\tWriteModifiers(fixedFieldDeclaration.ModifierTokens);\n\t\t\tWriteKeyword(FixedFieldDeclaration.FixedKeywordRole);\n\t\t\tSpace();\n\t\t\tfixedFieldDeclaration.ReturnType.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWriteCommaSeparatedList(fixedFieldDeclaration.Variables);\n\t\t\tSemicolon();\n\t\t\tEndNode(fixedFieldDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer)\n\t\t{\n\t\t\tStartNode(fixedVariableInitializer);\n\t\t\tWriteIdentifier(fixedVariableInitializer.NameToken);\n\t\t\tif (!fixedVariableInitializer.CountExpression.IsNull)\n\t\t\t{\n\t\t\t\tWriteToken(Roles.LBracket);\n\t\t\t\tSpace(policy.SpacesWithinBrackets);\n\t\t\t\tfixedVariableInitializer.CountExpression.AcceptVisitor(this);\n\t\t\t\tSpace(policy.SpacesWithinBrackets);\n\t\t\t\tWriteToken(Roles.RBracket);\n\t\t\t}\n\t\t\tEndNode(fixedVariableInitializer);\n\t\t}\n\n\t\tpublic virtual void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration)\n\t\t{\n\t\t\tStartNode(indexerDeclaration);\n\t\t\tWriteAttributes(indexerDeclaration.Attributes);\n\t\t\tWriteModifiers(indexerDeclaration.ModifierTokens);\n\t\t\tindexerDeclaration.ReturnType.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWritePrivateImplementationType(indexerDeclaration.PrivateImplementationType);\n\t\t\tWriteKeyword(IndexerDeclaration.ThisKeywordRole);\n\t\t\tSpace(policy.SpaceBeforeMethodDeclarationParentheses);\n\t\t\tWriteCommaSeparatedListInBrackets(indexerDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);\n\n\t\t\tif (indexerDeclaration.ExpressionBody.IsNull)\n\t\t\t{\n\t\t\t\tbool isSingleLine =\n\t\t\t\t\t(policy.AutoPropertyFormatting == PropertyFormatting.SingleLine)\n\t\t\t\t\t&& (indexerDeclaration.Getter.IsNull || indexerDeclaration.Getter.Body.IsNull)\n\t\t\t\t\t&& (indexerDeclaration.Setter.IsNull || indexerDeclaration.Setter.Body.IsNull)\n\t\t\t\t\t&& !indexerDeclaration.Getter.Attributes.Any()\n\t\t\t\t\t&& !indexerDeclaration.Setter.Attributes.Any();\n\t\t\t\tOpenBrace(isSingleLine ? BraceStyle.EndOfLine : policy.PropertyBraceStyle, newLine: !isSingleLine);\n\t\t\t\tif (isSingleLine)\n\t\t\t\t\tSpace();\n\t\t\t\t// output get/set in their original order\n\t\t\t\tforeach (AstNode node in indexerDeclaration.Children)\n\t\t\t\t{\n\t\t\t\t\tif (node.Role == IndexerDeclaration.GetterRole || node.Role == IndexerDeclaration.SetterRole)\n\t\t\t\t\t{\n\t\t\t\t\t\tnode.AcceptVisitor(this);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tCloseBrace(isSingleLine ? BraceStyle.EndOfLine : policy.PropertyBraceStyle, unindent: !isSingleLine);\n\t\t\t\tNewLine();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tSpace();\n\t\t\t\tWriteToken(Roles.Arrow);\n\t\t\t\tSpace();\n\t\t\t\tindexerDeclaration.ExpressionBody.AcceptVisitor(this);\n\t\t\t\tSemicolon();\n\t\t\t}\n\t\t\tEndNode(indexerDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitMethodDeclaration(MethodDeclaration methodDeclaration)\n\t\t{\n\t\t\tStartNode(methodDeclaration);\n\t\t\tWriteAttributes(methodDeclaration.Attributes);\n\t\t\tWriteModifiers(methodDeclaration.ModifierTokens);\n\t\t\tmethodDeclaration.ReturnType.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWritePrivateImplementationType(methodDeclaration.PrivateImplementationType);\n\t\t\tWriteIdentifier(methodDeclaration.NameToken);\n\t\t\tWriteTypeParameters(methodDeclaration.TypeParameters);\n\t\t\tSpace(policy.SpaceBeforeMethodDeclarationParentheses);\n\t\t\tWriteCommaSeparatedListInParenthesis(methodDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);\n\t\t\tforeach (Constraint constraint in methodDeclaration.Constraints)\n\t\t\t{\n\t\t\t\tconstraint.AcceptVisitor(this);\n\t\t\t}\n\t\t\tWriteMethodBody(methodDeclaration.Body, policy.MethodBraceStyle);\n\t\t\tEndNode(methodDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration)\n\t\t{\n\t\t\tStartNode(operatorDeclaration);\n\t\t\tWriteAttributes(operatorDeclaration.Attributes);\n\t\t\tWriteModifiers(operatorDeclaration.ModifierTokens);\n\t\t\tif (operatorDeclaration.OperatorType == OperatorType.Explicit || operatorDeclaration.OperatorType == OperatorType.CheckedExplicit)\n\t\t\t{\n\t\t\t\tWriteKeyword(OperatorDeclaration.ExplicitRole);\n\t\t\t}\n\t\t\telse if (operatorDeclaration.OperatorType == OperatorType.Implicit)\n\t\t\t{\n\t\t\t\tWriteKeyword(OperatorDeclaration.ImplicitRole);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\toperatorDeclaration.ReturnType.AcceptVisitor(this);\n\t\t\t}\n\t\t\tSpace();\n\t\t\tWritePrivateImplementationType(operatorDeclaration.PrivateImplementationType);\n\t\t\tWriteKeyword(OperatorDeclaration.OperatorKeywordRole);\n\t\t\tSpace();\n\t\t\tif (OperatorDeclaration.IsChecked(operatorDeclaration.OperatorType))\n\t\t\t{\n\t\t\t\tWriteKeyword(OperatorDeclaration.CheckedKeywordRole);\n\t\t\t\tSpace();\n\t\t\t}\n\t\t\tif (operatorDeclaration.OperatorType == OperatorType.Explicit\n\t\t\t\t|| operatorDeclaration.OperatorType == OperatorType.CheckedExplicit\n\t\t\t\t|| operatorDeclaration.OperatorType == OperatorType.Implicit)\n\t\t\t{\n\t\t\t\toperatorDeclaration.ReturnType.AcceptVisitor(this);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tWriteToken(OperatorDeclaration.GetToken(operatorDeclaration.OperatorType), OperatorDeclaration.GetRole(operatorDeclaration.OperatorType));\n\t\t\t}\n\t\t\tSpace(policy.SpaceBeforeMethodDeclarationParentheses);\n\t\t\tWriteCommaSeparatedListInParenthesis(operatorDeclaration.Parameters, policy.SpaceWithinMethodDeclarationParentheses);\n\t\t\tWriteMethodBody(operatorDeclaration.Body, policy.MethodBraceStyle);\n\t\t\tEndNode(operatorDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration)\n\t\t{\n\t\t\tStartNode(parameterDeclaration);\n\t\t\tWriteAttributes(parameterDeclaration.Attributes);\n\t\t\tif (parameterDeclaration.HasThisModifier)\n\t\t\t{\n\t\t\t\tWriteKeyword(ParameterDeclaration.ThisModifierRole);\n\t\t\t\tSpace();\n\t\t\t}\n\t\t\tif (parameterDeclaration.IsParams)\n\t\t\t{\n\t\t\t\tWriteKeyword(ParameterDeclaration.ParamsModifierRole);\n\t\t\t\tSpace();\n\t\t\t}\n\t\t\tif (parameterDeclaration.IsScopedRef)\n\t\t\t{\n\t\t\t\tWriteKeyword(ParameterDeclaration.ScopedRefRole);\n\t\t\t\tSpace();\n\t\t\t}\n\t\t\tswitch (parameterDeclaration.ParameterModifier)\n\t\t\t{\n\t\t\t\tcase ReferenceKind.Ref:\n\t\t\t\t\tWriteKeyword(ParameterDeclaration.RefModifierRole);\n\t\t\t\t\tSpace();\n\t\t\t\t\tbreak;\n\t\t\t\tcase ReferenceKind.RefReadOnly:\n\t\t\t\t\tWriteKeyword(ParameterDeclaration.RefModifierRole);\n\t\t\t\t\tWriteKeyword(ParameterDeclaration.ReadonlyModifierRole);\n\t\t\t\t\tSpace();\n\t\t\t\t\tbreak;\n\t\t\t\tcase ReferenceKind.Out:\n\t\t\t\t\tWriteKeyword(ParameterDeclaration.OutModifierRole);\n\t\t\t\t\tSpace();\n\t\t\t\t\tbreak;\n\t\t\t\tcase ReferenceKind.In:\n\t\t\t\t\tWriteKeyword(ParameterDeclaration.InModifierRole);\n\t\t\t\t\tSpace();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tparameterDeclaration.Type.AcceptVisitor(this);\n\t\t\tif (!parameterDeclaration.Type.IsNull && !string.IsNullOrEmpty(parameterDeclaration.Name))\n\t\t\t{\n\t\t\t\tSpace();\n\t\t\t}\n\t\t\tif (!string.IsNullOrEmpty(parameterDeclaration.Name))\n\t\t\t{\n\t\t\t\tWriteIdentifier(parameterDeclaration.NameToken);\n\t\t\t}\n\t\t\tif (!parameterDeclaration.DefaultExpression.IsNull)\n\t\t\t{\n\t\t\t\tSpace(policy.SpaceAroundAssignment);\n\t\t\t\tWriteToken(Roles.Assign);\n\t\t\t\tSpace(policy.SpaceAroundAssignment);\n\t\t\t\tparameterDeclaration.DefaultExpression.AcceptVisitor(this);\n\t\t\t}\n\t\t\tEndNode(parameterDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)\n\t\t{\n\t\t\tStartNode(propertyDeclaration);\n\t\t\tWriteAttributes(propertyDeclaration.Attributes);\n\t\t\tWriteModifiers(propertyDeclaration.ModifierTokens);\n\t\t\tpropertyDeclaration.ReturnType.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWritePrivateImplementationType(propertyDeclaration.PrivateImplementationType);\n\t\t\tWriteIdentifier(propertyDeclaration.NameToken);\n\t\t\tif (propertyDeclaration.ExpressionBody.IsNull)\n\t\t\t{\n\t\t\t\tbool isSingleLine =\n\t\t\t\t\t(policy.AutoPropertyFormatting == PropertyFormatting.SingleLine)\n\t\t\t\t\t&& (propertyDeclaration.Getter.IsNull || propertyDeclaration.Getter.Body.IsNull)\n\t\t\t\t\t&& (propertyDeclaration.Setter.IsNull || propertyDeclaration.Setter.Body.IsNull)\n\t\t\t\t\t&& !propertyDeclaration.Getter.Attributes.Any()\n\t\t\t\t\t&& !propertyDeclaration.Setter.Attributes.Any();\n\t\t\t\tOpenBrace(isSingleLine ? BraceStyle.EndOfLine : policy.PropertyBraceStyle, newLine: !isSingleLine);\n\t\t\t\tif (isSingleLine)\n\t\t\t\t\tSpace();\n\t\t\t\t// output get/set in their original order\n\t\t\t\tforeach (AstNode node in propertyDeclaration.Children)\n\t\t\t\t{\n\t\t\t\t\tif (node.Role == IndexerDeclaration.GetterRole || node.Role == IndexerDeclaration.SetterRole)\n\t\t\t\t\t{\n\t\t\t\t\t\tnode.AcceptVisitor(this);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tCloseBrace(isSingleLine ? BraceStyle.EndOfLine : policy.PropertyBraceStyle, unindent: !isSingleLine);\n\t\t\t\tif (!propertyDeclaration.Initializer.IsNull)\n\t\t\t\t{\n\t\t\t\t\tSpace(policy.SpaceAroundAssignment);\n\t\t\t\t\tWriteToken(Roles.Assign);\n\t\t\t\t\tSpace(policy.SpaceAroundAssignment);\n\t\t\t\t\tpropertyDeclaration.Initializer.AcceptVisitor(this);\n\t\t\t\t\tSemicolon();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// The call to Semicolon() above prints a newline too\n\t\t\t\t\tNewLine();\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tSpace();\n\t\t\t\tWriteToken(Roles.Arrow);\n\t\t\t\tSpace();\n\t\t\t\tpropertyDeclaration.ExpressionBody.AcceptVisitor(this);\n\t\t\t\tSemicolon();\n\t\t\t}\n\t\t\tEndNode(propertyDeclaration);\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Other nodes\n\t\tpublic virtual void VisitVariableInitializer(VariableInitializer variableInitializer)\n\t\t{\n\t\t\tStartNode(variableInitializer);\n\t\t\tWriteIdentifier(variableInitializer.NameToken);\n\t\t\tif (!variableInitializer.Initializer.IsNull)\n\t\t\t{\n\t\t\t\tSpace(policy.SpaceAroundAssignment);\n\t\t\t\tWriteToken(Roles.Assign);\n\t\t\t\tSpace(policy.SpaceAroundAssignment);\n\t\t\t\tvariableInitializer.Initializer.AcceptVisitor(this);\n\t\t\t}\n\t\t\tEndNode(variableInitializer);\n\t\t}\n\n\t\tvoid MaybeNewLinesAfterUsings(AstNode node)\n\t\t{\n\t\t\tvar nextSibling = node.NextSibling;\n\n\t\t\tif ((node is UsingDeclaration || node is UsingAliasDeclaration) && !(nextSibling is UsingDeclaration || nextSibling is UsingAliasDeclaration))\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < policy.MinimumBlankLinesAfterUsings; i++)\n\t\t\t\t\tNewLine();\n\t\t\t}\n\t\t}\n\n\t\tpublic virtual void VisitSyntaxTree(SyntaxTree syntaxTree)\n\t\t{\n\t\t\t// don't do node tracking as we visit all children directly\n\t\t\tforeach (AstNode node in syntaxTree.Children)\n\t\t\t{\n\t\t\t\tnode.AcceptVisitor(this);\n\t\t\t\tMaybeNewLinesAfterUsings(node);\n\t\t\t}\n\t\t}\n\n\t\tpublic virtual void VisitSimpleType(SimpleType simpleType)\n\t\t{\n\t\t\tStartNode(simpleType);\n\t\t\tWriteIdentifier(simpleType.IdentifierToken);\n\t\t\tWriteTypeArguments(simpleType.TypeArguments);\n\t\t\tEndNode(simpleType);\n\t\t}\n\n\t\tpublic virtual void VisitMemberType(MemberType memberType)\n\t\t{\n\t\t\tStartNode(memberType);\n\t\t\tmemberType.Target.AcceptVisitor(this);\n\t\t\tif (memberType.IsDoubleColon)\n\t\t\t{\n\t\t\t\tWriteToken(Roles.DoubleColon);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tWriteToken(Roles.Dot);\n\t\t\t}\n\t\t\tWriteIdentifier(memberType.MemberNameToken);\n\t\t\tWriteTypeArguments(memberType.TypeArguments);\n\t\t\tEndNode(memberType);\n\t\t}\n\n\t\tpublic virtual void VisitTupleType(TupleAstType tupleType)\n\t\t{\n\t\t\tDebug.Assert(tupleType.Elements.Count >= 2);\n\t\t\tStartNode(tupleType);\n\t\t\tLPar();\n\t\t\tWriteCommaSeparatedList(tupleType.Elements);\n\t\t\tRPar();\n\t\t\tEndNode(tupleType);\n\t\t}\n\n\t\tpublic virtual void VisitTupleTypeElement(TupleTypeElement tupleTypeElement)\n\t\t{\n\t\t\tStartNode(tupleTypeElement);\n\t\t\ttupleTypeElement.Type.AcceptVisitor(this);\n\t\t\tif (!tupleTypeElement.NameToken.IsNull)\n\t\t\t{\n\t\t\t\tSpace();\n\t\t\t\ttupleTypeElement.NameToken.AcceptVisitor(this);\n\t\t\t}\n\t\t\tEndNode(tupleTypeElement);\n\t\t}\n\n\t\tpublic virtual void VisitFunctionPointerType(FunctionPointerAstType functionPointerType)\n\t\t{\n\t\t\tStartNode(functionPointerType);\n\t\t\tWriteKeyword(Roles.DelegateKeyword);\n\t\t\tWriteToken(FunctionPointerAstType.PointerRole);\n\t\t\tif (functionPointerType.HasUnmanagedCallingConvention)\n\t\t\t{\n\t\t\t\tSpace();\n\t\t\t\tWriteKeyword(\"unmanaged\");\n\t\t\t}\n\t\t\tif (functionPointerType.CallingConventions.Any())\n\t\t\t{\n\t\t\t\tWriteToken(Roles.LBracket);\n\t\t\t\tWriteCommaSeparatedList(functionPointerType.CallingConventions);\n\t\t\t\tWriteToken(Roles.RBracket);\n\t\t\t}\n\t\t\tWriteToken(Roles.LChevron);\n\t\t\tWriteCommaSeparatedList(\n\t\t\t\tfunctionPointerType.Parameters.Concat<AstNode>(new[] { functionPointerType.ReturnType }));\n\t\t\tWriteToken(Roles.RChevron);\n\t\t\tEndNode(functionPointerType);\n\t\t}\n\n\t\tpublic virtual void VisitInvocationType(InvocationAstType invocationType)\n\t\t{\n\t\t\tStartNode(invocationType);\n\t\t\tinvocationType.BaseType.AcceptVisitor(this);\n\t\t\tWriteToken(Roles.LPar);\n\t\t\tWriteCommaSeparatedList(invocationType.Arguments);\n\t\t\tWriteToken(Roles.RPar);\n\t\t\tEndNode(invocationType);\n\t\t}\n\n\t\tpublic virtual void VisitComposedType(ComposedType composedType)\n\t\t{\n\t\t\tStartNode(composedType);\n\t\t\tif (composedType.Attributes.Any())\n\t\t\t{\n\t\t\t\tforeach (var attr in composedType.Attributes)\n\t\t\t\t{\n\t\t\t\t\tattr.AcceptVisitor(this);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (composedType.HasRefSpecifier)\n\t\t\t{\n\t\t\t\tWriteKeyword(ComposedType.RefRole);\n\t\t\t}\n\t\t\tif (composedType.HasReadOnlySpecifier)\n\t\t\t{\n\t\t\t\tWriteKeyword(ComposedType.ReadonlyRole);\n\t\t\t}\n\t\t\tcomposedType.BaseType.AcceptVisitor(this);\n\t\t\tif (composedType.HasNullableSpecifier)\n\t\t\t{\n\t\t\t\tWriteToken(ComposedType.NullableRole);\n\t\t\t}\n\t\t\tfor (int i = 0; i < composedType.PointerRank; i++)\n\t\t\t{\n\t\t\t\tWriteToken(ComposedType.PointerRole);\n\t\t\t}\n\t\t\tforeach (var node in composedType.ArraySpecifiers)\n\t\t\t{\n\t\t\t\tnode.AcceptVisitor(this);\n\t\t\t}\n\t\t\tEndNode(composedType);\n\t\t}\n\n\t\tpublic virtual void VisitArraySpecifier(ArraySpecifier arraySpecifier)\n\t\t{\n\t\t\tStartNode(arraySpecifier);\n\t\t\tWriteToken(Roles.LBracket);\n\t\t\tforeach (var comma in arraySpecifier.GetChildrenByRole(Roles.Comma))\n\t\t\t{\n\t\t\t\twriter.WriteToken(Roles.Comma, \",\");\n\t\t\t}\n\t\t\tWriteToken(Roles.RBracket);\n\t\t\tEndNode(arraySpecifier);\n\t\t}\n\n\t\tpublic virtual void VisitPrimitiveType(PrimitiveType primitiveType)\n\t\t{\n\t\t\tStartNode(primitiveType);\n\t\t\twriter.WritePrimitiveType(primitiveType.Keyword);\n\t\t\tisAfterSpace = false;\n\t\t\tEndNode(primitiveType);\n\t\t}\n\n\t\tpublic virtual void VisitSingleVariableDesignation(SingleVariableDesignation singleVariableDesignation)\n\t\t{\n\t\t\tStartNode(singleVariableDesignation);\n\t\t\tWriteIdentifier(singleVariableDesignation.IdentifierToken);\n\t\t\tEndNode(singleVariableDesignation);\n\t\t}\n\n\t\tpublic virtual void VisitParenthesizedVariableDesignation(ParenthesizedVariableDesignation parenthesizedVariableDesignation)\n\t\t{\n\t\t\tStartNode(parenthesizedVariableDesignation);\n\t\t\tLPar();\n\t\t\tWriteCommaSeparatedList(parenthesizedVariableDesignation.VariableDesignations);\n\t\t\tRPar();\n\t\t\tEndNode(parenthesizedVariableDesignation);\n\t\t}\n\n\t\tpublic virtual void VisitComment(Comment comment)\n\t\t{\n\t\t\twriter.StartNode(comment);\n\t\t\twriter.WriteComment(comment.CommentType, comment.Content);\n\t\t\twriter.EndNode(comment);\n\t\t}\n\n\t\tpublic virtual void VisitPreProcessorDirective(PreProcessorDirective preProcessorDirective)\n\t\t{\n\t\t\twriter.StartNode(preProcessorDirective);\n\t\t\twriter.WritePreProcessorDirective(preProcessorDirective.Type, preProcessorDirective.Argument);\n\t\t\twriter.EndNode(preProcessorDirective);\n\t\t}\n\n\t\tpublic virtual void VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration)\n\t\t{\n\t\t\tStartNode(typeParameterDeclaration);\n\t\t\tWriteAttributes(typeParameterDeclaration.Attributes);\n\t\t\tswitch (typeParameterDeclaration.Variance)\n\t\t\t{\n\t\t\t\tcase VarianceModifier.Invariant:\n\t\t\t\t\tbreak;\n\t\t\t\tcase VarianceModifier.Covariant:\n\t\t\t\t\tWriteKeyword(TypeParameterDeclaration.OutVarianceKeywordRole);\n\t\t\t\t\tbreak;\n\t\t\t\tcase VarianceModifier.Contravariant:\n\t\t\t\t\tWriteKeyword(TypeParameterDeclaration.InVarianceKeywordRole);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException(\"Invalid value for VarianceModifier\");\n\t\t\t}\n\t\t\tWriteIdentifier(typeParameterDeclaration.NameToken);\n\t\t\tEndNode(typeParameterDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitConstraint(Constraint constraint)\n\t\t{\n\t\t\tStartNode(constraint);\n\t\t\tSpace();\n\t\t\tWriteKeyword(Roles.WhereKeyword);\n\t\t\tconstraint.TypeParameter.AcceptVisitor(this);\n\t\t\tSpace();\n\t\t\tWriteToken(Roles.Colon);\n\t\t\tSpace();\n\t\t\tWriteCommaSeparatedList(constraint.BaseTypes);\n\t\t\tEndNode(constraint);\n\t\t}\n\n\t\tpublic virtual void VisitCSharpTokenNode(CSharpTokenNode cSharpTokenNode)\n\t\t{\n\t\t\tCSharpModifierToken mod = cSharpTokenNode as CSharpModifierToken;\n\t\t\tif (mod != null)\n\t\t\t{\n\t\t\t\t// ITokenWriter assumes that each node processed between a\n\t\t\t\t// StartNode(parentNode)-EndNode(parentNode)-pair is a child of parentNode.\n\t\t\t\tWriteKeyword(CSharpModifierToken.GetModifierName(mod.Modifier), cSharpTokenNode.Role);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthrow new NotSupportedException(\"Should never visit individual tokens\");\n\t\t\t}\n\t\t}\n\n\t\tpublic virtual void VisitIdentifier(Identifier identifier)\n\t\t{\n\t\t\t// Do not call StartNode and EndNode for Identifier, because they are handled by the ITokenWriter.\n\t\t\t// ITokenWriter assumes that each node processed between a\n\t\t\t// StartNode(parentNode)-EndNode(parentNode)-pair is a child of parentNode.\n\t\t\tWriteIdentifier(identifier);\n\t\t}\n\n\t\tvoid IAstVisitor.VisitNullNode(AstNode nullNode)\n\t\t{\n\t\t}\n\n\t\tvoid IAstVisitor.VisitErrorNode(AstNode errorNode)\n\t\t{\n\t\t\tStartNode(errorNode);\n\t\t\tEndNode(errorNode);\n\t\t}\n\t\t#endregion\n\n\t\t#region Pattern Nodes\n\t\tpublic virtual void VisitPatternPlaceholder(AstNode placeholder, Pattern pattern)\n\t\t{\n\t\t\tStartNode(placeholder);\n\t\t\tVisitNodeInPattern(pattern);\n\t\t\tEndNode(placeholder);\n\t\t}\n\n\t\tvoid VisitAnyNode(AnyNode anyNode)\n\t\t{\n\t\t\tif (!string.IsNullOrEmpty(anyNode.GroupName))\n\t\t\t{\n\t\t\t\tWriteIdentifier(anyNode.GroupName);\n\t\t\t\tWriteToken(Roles.Colon);\n\t\t\t}\n\t\t}\n\n\t\tvoid VisitBackreference(Backreference backreference)\n\t\t{\n\t\t\tWriteKeyword(\"backreference\");\n\t\t\tLPar();\n\t\t\tWriteIdentifier(backreference.ReferencedGroupName);\n\t\t\tRPar();\n\t\t}\n\n\t\tvoid VisitIdentifierExpressionBackreference(IdentifierExpressionBackreference identifierExpressionBackreference)\n\t\t{\n\t\t\tWriteKeyword(\"identifierBackreference\");\n\t\t\tLPar();\n\t\t\tWriteIdentifier(identifierExpressionBackreference.ReferencedGroupName);\n\t\t\tRPar();\n\t\t}\n\n\t\tvoid VisitChoice(Choice choice)\n\t\t{\n\t\t\tWriteKeyword(\"choice\");\n\t\t\tSpace();\n\t\t\tLPar();\n\t\t\tNewLine();\n\t\t\twriter.Indent();\n\t\t\tforeach (INode alternative in choice)\n\t\t\t{\n\t\t\t\tVisitNodeInPattern(alternative);\n\t\t\t\tif (alternative != choice.Last())\n\t\t\t\t{\n\t\t\t\t\tWriteToken(Roles.Comma);\n\t\t\t\t}\n\t\t\t\tNewLine();\n\t\t\t}\n\t\t\twriter.Unindent();\n\t\t\tRPar();\n\t\t}\n\n\t\tvoid VisitNamedNode(NamedNode namedNode)\n\t\t{\n\t\t\tif (!string.IsNullOrEmpty(namedNode.GroupName))\n\t\t\t{\n\t\t\t\tWriteIdentifier(namedNode.GroupName);\n\t\t\t\tWriteToken(Roles.Colon);\n\t\t\t}\n\t\t\tVisitNodeInPattern(namedNode.ChildNode);\n\t\t}\n\n\t\tvoid VisitRepeat(Repeat repeat)\n\t\t{\n\t\t\tWriteKeyword(\"repeat\");\n\t\t\tLPar();\n\t\t\tif (repeat.MinCount != 0 || repeat.MaxCount != int.MaxValue)\n\t\t\t{\n\t\t\t\tWriteIdentifier(repeat.MinCount.ToString());\n\t\t\t\tWriteToken(Roles.Comma);\n\t\t\t\tWriteIdentifier(repeat.MaxCount.ToString());\n\t\t\t\tWriteToken(Roles.Comma);\n\t\t\t}\n\t\t\tVisitNodeInPattern(repeat.ChildNode);\n\t\t\tRPar();\n\t\t}\n\n\t\tvoid VisitOptionalNode(OptionalNode optionalNode)\n\t\t{\n\t\t\tWriteKeyword(\"optional\");\n\t\t\tLPar();\n\t\t\tVisitNodeInPattern(optionalNode.ChildNode);\n\t\t\tRPar();\n\t\t}\n\n\t\tvoid VisitNodeInPattern(INode childNode)\n\t\t{\n\t\t\tif (childNode is AstNode)\n\t\t\t{\n\t\t\t\t((AstNode)childNode).AcceptVisitor(this);\n\t\t\t}\n\t\t\telse if (childNode is IdentifierExpressionBackreference)\n\t\t\t{\n\t\t\t\tVisitIdentifierExpressionBackreference((IdentifierExpressionBackreference)childNode);\n\t\t\t}\n\t\t\telse if (childNode is Choice)\n\t\t\t{\n\t\t\t\tVisitChoice((Choice)childNode);\n\t\t\t}\n\t\t\telse if (childNode is AnyNode)\n\t\t\t{\n\t\t\t\tVisitAnyNode((AnyNode)childNode);\n\t\t\t}\n\t\t\telse if (childNode is Backreference)\n\t\t\t{\n\t\t\t\tVisitBackreference((Backreference)childNode);\n\t\t\t}\n\t\t\telse if (childNode is NamedNode)\n\t\t\t{\n\t\t\t\tVisitNamedNode((NamedNode)childNode);\n\t\t\t}\n\t\t\telse if (childNode is OptionalNode)\n\t\t\t{\n\t\t\t\tVisitOptionalNode((OptionalNode)childNode);\n\t\t\t}\n\t\t\telse if (childNode is Repeat)\n\t\t\t{\n\t\t\t\tVisitRepeat((Repeat)childNode);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\twriter.WritePrimitiveValue(childNode);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Documentation Reference\n\t\tpublic virtual void VisitDocumentationReference(DocumentationReference documentationReference)\n\t\t{\n\t\t\tStartNode(documentationReference);\n\t\t\tif (!documentationReference.DeclaringType.IsNull)\n\t\t\t{\n\t\t\t\tdocumentationReference.DeclaringType.AcceptVisitor(this);\n\t\t\t\tif (documentationReference.SymbolKind != SymbolKind.TypeDefinition)\n\t\t\t\t{\n\t\t\t\t\tWriteToken(Roles.Dot);\n\t\t\t\t}\n\t\t\t}\n\t\t\tswitch (documentationReference.SymbolKind)\n\t\t\t{\n\t\t\t\tcase SymbolKind.TypeDefinition:\n\t\t\t\t\t// we already printed the DeclaringType\n\t\t\t\t\tbreak;\n\t\t\t\tcase SymbolKind.Indexer:\n\t\t\t\t\tWriteKeyword(IndexerDeclaration.ThisKeywordRole);\n\t\t\t\t\tbreak;\n\t\t\t\tcase SymbolKind.Operator:\n\t\t\t\t\tvar opType = documentationReference.OperatorType;\n\t\t\t\t\tif (opType == OperatorType.Explicit || opType == OperatorType.CheckedExplicit)\n\t\t\t\t\t{\n\t\t\t\t\t\tWriteKeyword(OperatorDeclaration.ExplicitRole);\n\t\t\t\t\t}\n\t\t\t\t\telse if (opType == OperatorType.Implicit)\n\t\t\t\t\t{\n\t\t\t\t\t\tWriteKeyword(OperatorDeclaration.ImplicitRole);\n\t\t\t\t\t}\n\t\t\t\t\tWriteKeyword(OperatorDeclaration.OperatorKeywordRole);\n\t\t\t\t\tSpace();\n\t\t\t\t\tif (OperatorDeclaration.IsChecked(opType))\n\t\t\t\t\t{\n\t\t\t\t\t\tWriteKeyword(OperatorDeclaration.CheckedKeywordRole);\n\t\t\t\t\t\tSpace();\n\t\t\t\t\t}\n\t\t\t\t\tif (opType == OperatorType.Explicit || opType == OperatorType.Implicit || opType == OperatorType.CheckedExplicit)\n\t\t\t\t\t{\n\t\t\t\t\t\tdocumentationReference.ConversionOperatorReturnType.AcceptVisitor(this);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tWriteToken(OperatorDeclaration.GetToken(opType), OperatorDeclaration.GetRole(opType));\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tWriteIdentifier(documentationReference.GetChildByRole(Roles.Identifier));\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tWriteTypeArguments(documentationReference.TypeArguments);\n\t\t\tif (documentationReference.HasParameterList)\n\t\t\t{\n\t\t\t\tSpace(policy.SpaceBeforeMethodDeclarationParentheses);\n\t\t\t\tif (documentationReference.SymbolKind == SymbolKind.Indexer)\n\t\t\t\t{\n\t\t\t\t\tWriteCommaSeparatedListInBrackets(documentationReference.Parameters, policy.SpaceWithinMethodDeclarationParentheses);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tWriteCommaSeparatedListInParenthesis(documentationReference.Parameters, policy.SpaceWithinMethodDeclarationParentheses);\n\t\t\t\t}\n\t\t\t}\n\t\t\tEndNode(documentationReference);\n\t\t}\n\t\t#endregion\n\n\t\t/// <summary>\n\t\t/// Converts special characters to escape sequences within the given string.\n\t\t/// </summary>\n\t\tpublic static string ConvertString(string text)\n\t\t{\n\t\t\treturn TextWriterTokenWriter.ConvertString(text);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/OutputVisitor/FormattingOptionsFactory.cs",
    "content": "// \n// FormattingOptionsFactory.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@xamarin.com>\n// \n// Copyright (c) 2012 Xamarin Inc. (http://xamarin.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.OutputVisitor\n{\n\t/// <summary>\n\t/// The formatting options factory creates pre defined formatting option styles.\n\t/// </summary>\n\tpublic static class FormattingOptionsFactory\n\t{\n\t\t/// <summary>\n\t\t/// Creates empty CSharpFormatting options.\n\t\t/// </summary>\n\t\tpublic static CSharpFormattingOptions CreateEmpty()\n\t\t{\n\t\t\treturn new CSharpFormattingOptions();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates mono indent style CSharpFormatting options.\n\t\t/// </summary>\n\t\tpublic static CSharpFormattingOptions CreateMono()\n\t\t{\n\t\t\treturn new CSharpFormattingOptions {\n\t\t\t\tIndentNamespaceBody = true,\n\t\t\t\tIndentClassBody = true,\n\t\t\t\tIndentInterfaceBody = true,\n\t\t\t\tIndentStructBody = true,\n\t\t\t\tIndentEnumBody = true,\n\t\t\t\tIndentMethodBody = true,\n\t\t\t\tIndentPropertyBody = true,\n\t\t\t\tIndentEventBody = true,\n\t\t\t\tIndentBlocks = true,\n\t\t\t\tIndentSwitchBody = false,\n\t\t\t\tIndentCaseBody = true,\n\t\t\t\tIndentBreakStatements = true,\n\t\t\t\tIndentPreprocessorDirectives = true,\n\t\t\t\tIndentBlocksInsideExpressions = false,\n\t\t\t\tNamespaceBraceStyle = BraceStyle.NextLine,\n\t\t\t\tClassBraceStyle = BraceStyle.NextLine,\n\t\t\t\tInterfaceBraceStyle = BraceStyle.NextLine,\n\t\t\t\tStructBraceStyle = BraceStyle.NextLine,\n\t\t\t\tEnumBraceStyle = BraceStyle.NextLine,\n\t\t\t\tMethodBraceStyle = BraceStyle.NextLine,\n\t\t\t\tConstructorBraceStyle = BraceStyle.NextLine,\n\t\t\t\tDestructorBraceStyle = BraceStyle.NextLine,\n\t\t\t\tAnonymousMethodBraceStyle = BraceStyle.EndOfLine,\n\n\t\t\t\tPropertyBraceStyle = BraceStyle.EndOfLine,\n\t\t\t\tPropertyGetBraceStyle = BraceStyle.EndOfLine,\n\t\t\t\tPropertySetBraceStyle = BraceStyle.EndOfLine,\n\t\t\t\tSimpleGetBlockFormatting = PropertyFormatting.SingleLine,\n\t\t\t\tSimpleSetBlockFormatting = PropertyFormatting.SingleLine,\n\n\t\t\t\tEventBraceStyle = BraceStyle.EndOfLine,\n\t\t\t\tEventAddBraceStyle = BraceStyle.EndOfLine,\n\t\t\t\tEventRemoveBraceStyle = BraceStyle.EndOfLine,\n\t\t\t\tAllowEventAddBlockInline = true,\n\t\t\t\tAllowEventRemoveBlockInline = true,\n\t\t\t\tStatementBraceStyle = BraceStyle.EndOfLine,\n\n\t\t\t\tElseNewLinePlacement = NewLinePlacement.SameLine,\n\t\t\t\tElseIfNewLinePlacement = NewLinePlacement.SameLine,\n\t\t\t\tCatchNewLinePlacement = NewLinePlacement.SameLine,\n\t\t\t\tFinallyNewLinePlacement = NewLinePlacement.SameLine,\n\t\t\t\tWhileNewLinePlacement = NewLinePlacement.SameLine,\n\t\t\t\tArrayInitializerWrapping = Wrapping.WrapIfTooLong,\n\t\t\t\tArrayInitializerBraceStyle = BraceStyle.EndOfLine,\n\t\t\t\tAllowOneLinedArrayInitialziers = true,\n\n\t\t\t\tSpaceBeforeMethodCallParentheses = true,\n\t\t\t\tSpaceBeforeMethodDeclarationParentheses = true,\n\t\t\t\tSpaceBeforeConstructorDeclarationParentheses = true,\n\t\t\t\tSpaceBeforeDelegateDeclarationParentheses = true,\n\t\t\t\tSpaceAfterMethodCallParameterComma = true,\n\t\t\t\tSpaceAfterConstructorDeclarationParameterComma = true,\n\n\t\t\t\tSpaceBeforeNewParentheses = true,\n\t\t\t\tSpacesWithinNewParentheses = false,\n\t\t\t\tSpacesBetweenEmptyNewParentheses = false,\n\t\t\t\tSpaceBeforeNewParameterComma = false,\n\t\t\t\tSpaceAfterNewParameterComma = true,\n\n\t\t\t\tSpaceBeforeIfParentheses = true,\n\t\t\t\tSpaceBeforeWhileParentheses = true,\n\t\t\t\tSpaceBeforeForParentheses = true,\n\t\t\t\tSpaceBeforeForeachParentheses = true,\n\t\t\t\tSpaceBeforeCatchParentheses = true,\n\t\t\t\tSpaceBeforeSwitchParentheses = true,\n\t\t\t\tSpaceBeforeLockParentheses = true,\n\t\t\t\tSpaceBeforeUsingParentheses = true,\n\t\t\t\tSpaceAroundAssignment = true,\n\t\t\t\tSpaceAroundLogicalOperator = true,\n\t\t\t\tSpaceAroundEqualityOperator = true,\n\t\t\t\tSpaceAroundRelationalOperator = true,\n\t\t\t\tSpaceAroundBitwiseOperator = true,\n\t\t\t\tSpaceAroundAdditiveOperator = true,\n\t\t\t\tSpaceAroundMultiplicativeOperator = true,\n\t\t\t\tSpaceAroundShiftOperator = true,\n\t\t\t\tSpaceAroundNullCoalescingOperator = true,\n\t\t\t\tSpacesWithinParentheses = false,\n\t\t\t\tSpaceWithinMethodCallParentheses = false,\n\t\t\t\tSpaceWithinMethodDeclarationParentheses = false,\n\t\t\t\tSpacesWithinIfParentheses = false,\n\t\t\t\tSpacesWithinWhileParentheses = false,\n\t\t\t\tSpacesWithinForParentheses = false,\n\t\t\t\tSpacesWithinForeachParentheses = false,\n\t\t\t\tSpacesWithinCatchParentheses = false,\n\t\t\t\tSpacesWithinSwitchParentheses = false,\n\t\t\t\tSpacesWithinLockParentheses = false,\n\t\t\t\tSpacesWithinUsingParentheses = false,\n\t\t\t\tSpacesWithinCastParentheses = false,\n\t\t\t\tSpacesWithinSizeOfParentheses = false,\n\t\t\t\tSpacesWithinTypeOfParentheses = false,\n\t\t\t\tSpacesWithinCheckedExpressionParantheses = false,\n\t\t\t\tSpaceBeforeConditionalOperatorCondition = true,\n\t\t\t\tSpaceAfterConditionalOperatorCondition = true,\n\t\t\t\tSpaceBeforeConditionalOperatorSeparator = true,\n\t\t\t\tSpaceAfterConditionalOperatorSeparator = true,\n\n\t\t\t\tSpacesWithinBrackets = false,\n\t\t\t\tSpacesBeforeBrackets = true,\n\t\t\t\tSpaceBeforeBracketComma = false,\n\t\t\t\tSpaceAfterBracketComma = true,\n\n\t\t\t\tSpaceBeforeForSemicolon = false,\n\t\t\t\tSpaceAfterForSemicolon = true,\n\t\t\t\tSpaceAfterTypecast = false,\n\n\t\t\t\tAlignEmbeddedStatements = true,\n\t\t\t\tSimplePropertyFormatting = PropertyFormatting.SingleLine,\n\t\t\t\tAutoPropertyFormatting = PropertyFormatting.SingleLine,\n\t\t\t\tEmptyLineFormatting = EmptyLineFormatting.DoNotIndent,\n\t\t\t\tSpaceBeforeMethodDeclarationParameterComma = false,\n\t\t\t\tSpaceAfterMethodDeclarationParameterComma = true,\n\t\t\t\tSpaceAfterDelegateDeclarationParameterComma = true,\n\t\t\t\tSpaceBeforeFieldDeclarationComma = false,\n\t\t\t\tSpaceAfterFieldDeclarationComma = true,\n\t\t\t\tSpaceBeforeLocalVariableDeclarationComma = false,\n\t\t\t\tSpaceAfterLocalVariableDeclarationComma = true,\n\n\t\t\t\tSpaceBeforeIndexerDeclarationBracket = true,\n\t\t\t\tSpaceWithinIndexerDeclarationBracket = false,\n\t\t\t\tSpaceBeforeIndexerDeclarationParameterComma = false,\n\t\t\t\tSpaceInNamedArgumentAfterDoubleColon = true,\n\t\t\t\tRemoveEndOfLineWhiteSpace = true,\n\n\t\t\t\tSpaceAfterIndexerDeclarationParameterComma = true,\n\n\t\t\t\tMinimumBlankLinesBeforeUsings = 0,\n\t\t\t\tMinimumBlankLinesAfterUsings = 1,\n\t\t\t\tUsingPlacement = UsingPlacement.TopOfFile,\n\n\t\t\t\tMinimumBlankLinesBeforeFirstDeclaration = 0,\n\t\t\t\tMinimumBlankLinesBetweenTypes = 1,\n\t\t\t\tMinimumBlankLinesBetweenFields = 0,\n\t\t\t\tMinimumBlankLinesBetweenEventFields = 0,\n\t\t\t\tMinimumBlankLinesBetweenMembers = 1,\n\t\t\t\tMinimumBlankLinesAroundRegion = 1,\n\t\t\t\tMinimumBlankLinesInsideRegion = 1,\n\t\t\t\tAlignToFirstIndexerArgument = false,\n\t\t\t\tAlignToFirstIndexerDeclarationParameter = true,\n\t\t\t\tAlignToFirstMethodCallArgument = false,\n\t\t\t\tAlignToFirstMethodDeclarationParameter = true,\n\t\t\t\tKeepCommentsAtFirstColumn = true,\n\t\t\t\tChainedMethodCallWrapping = Wrapping.DoNotWrap,\n\t\t\t\tMethodCallArgumentWrapping = Wrapping.DoNotWrap,\n\t\t\t\tNewLineAferMethodCallOpenParentheses = NewLinePlacement.DoNotCare,\n\t\t\t\tMethodCallClosingParenthesesOnNewLine = NewLinePlacement.DoNotCare,\n\n\t\t\t\tIndexerArgumentWrapping = Wrapping.DoNotWrap,\n\t\t\t\tNewLineAferIndexerOpenBracket = NewLinePlacement.DoNotCare,\n\t\t\t\tIndexerClosingBracketOnNewLine = NewLinePlacement.DoNotCare,\n\n\t\t\t\tNewLineBeforeNewQueryClause = NewLinePlacement.NewLine\n\t\t\t};\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates sharp develop indent style CSharpFormatting options.\n\t\t/// </summary>\n\t\tpublic static CSharpFormattingOptions CreateSharpDevelop()\n\t\t{\n\t\t\tvar baseOptions = CreateKRStyle();\n\t\t\treturn baseOptions;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// The K&amp;R style, so named because it was used in Kernighan and Ritchie's book The C Programming Language,\n\t\t/// is commonly used in C. It is less common for C++, C#, and others.\n\t\t/// </summary>\n\t\tpublic static CSharpFormattingOptions CreateKRStyle()\n\t\t{\n\t\t\treturn new CSharpFormattingOptions() {\n\t\t\t\tIndentNamespaceBody = true,\n\t\t\t\tIndentClassBody = true,\n\t\t\t\tIndentInterfaceBody = true,\n\t\t\t\tIndentStructBody = true,\n\t\t\t\tIndentEnumBody = true,\n\t\t\t\tIndentMethodBody = true,\n\t\t\t\tIndentPropertyBody = true,\n\t\t\t\tIndentEventBody = true,\n\t\t\t\tIndentBlocks = true,\n\t\t\t\tIndentSwitchBody = true,\n\t\t\t\tIndentCaseBody = true,\n\t\t\t\tIndentBreakStatements = true,\n\t\t\t\tIndentPreprocessorDirectives = true,\n\t\t\t\tNamespaceBraceStyle = BraceStyle.NextLine,\n\t\t\t\tClassBraceStyle = BraceStyle.NextLine,\n\t\t\t\tInterfaceBraceStyle = BraceStyle.NextLine,\n\t\t\t\tStructBraceStyle = BraceStyle.NextLine,\n\t\t\t\tEnumBraceStyle = BraceStyle.NextLine,\n\t\t\t\tMethodBraceStyle = BraceStyle.NextLine,\n\t\t\t\tConstructorBraceStyle = BraceStyle.NextLine,\n\t\t\t\tDestructorBraceStyle = BraceStyle.NextLine,\n\t\t\t\tAnonymousMethodBraceStyle = BraceStyle.EndOfLine,\n\t\t\t\tPropertyBraceStyle = BraceStyle.EndOfLine,\n\t\t\t\tPropertyGetBraceStyle = BraceStyle.EndOfLine,\n\t\t\t\tPropertySetBraceStyle = BraceStyle.EndOfLine,\n\t\t\t\tSimpleGetBlockFormatting = PropertyFormatting.SingleLine,\n\t\t\t\tSimpleSetBlockFormatting = PropertyFormatting.SingleLine,\n\n\t\t\t\tEventBraceStyle = BraceStyle.EndOfLine,\n\t\t\t\tEventAddBraceStyle = BraceStyle.EndOfLine,\n\t\t\t\tEventRemoveBraceStyle = BraceStyle.EndOfLine,\n\t\t\t\tAllowEventAddBlockInline = true,\n\t\t\t\tAllowEventRemoveBlockInline = true,\n\t\t\t\tStatementBraceStyle = BraceStyle.EndOfLine,\n\n\t\t\t\tElseNewLinePlacement = NewLinePlacement.SameLine,\n\t\t\t\tElseIfNewLinePlacement = NewLinePlacement.SameLine,\n\t\t\t\tCatchNewLinePlacement = NewLinePlacement.SameLine,\n\t\t\t\tFinallyNewLinePlacement = NewLinePlacement.SameLine,\n\t\t\t\tWhileNewLinePlacement = NewLinePlacement.SameLine,\n\t\t\t\tArrayInitializerWrapping = Wrapping.WrapIfTooLong,\n\t\t\t\tArrayInitializerBraceStyle = BraceStyle.EndOfLine,\n\n\t\t\t\tSpaceBeforeMethodCallParentheses = false,\n\t\t\t\tSpaceBeforeMethodDeclarationParentheses = false,\n\t\t\t\tSpaceBeforeConstructorDeclarationParentheses = false,\n\t\t\t\tSpaceBeforeDelegateDeclarationParentheses = false,\n\t\t\t\tSpaceBeforeIndexerDeclarationBracket = false,\n\t\t\t\tSpaceAfterMethodCallParameterComma = true,\n\t\t\t\tSpaceAfterConstructorDeclarationParameterComma = true,\n\t\t\t\tNewLineBeforeConstructorInitializerColon = NewLinePlacement.NewLine,\n\t\t\t\tNewLineAfterConstructorInitializerColon = NewLinePlacement.SameLine,\n\n\t\t\t\tSpaceBeforeNewParentheses = false,\n\t\t\t\tSpacesWithinNewParentheses = false,\n\t\t\t\tSpacesBetweenEmptyNewParentheses = false,\n\t\t\t\tSpaceBeforeNewParameterComma = false,\n\t\t\t\tSpaceAfterNewParameterComma = true,\n\n\t\t\t\tSpaceBeforeIfParentheses = true,\n\t\t\t\tSpaceBeforeWhileParentheses = true,\n\t\t\t\tSpaceBeforeForParentheses = true,\n\t\t\t\tSpaceBeforeForeachParentheses = true,\n\t\t\t\tSpaceBeforeCatchParentheses = true,\n\t\t\t\tSpaceBeforeSwitchParentheses = true,\n\t\t\t\tSpaceBeforeLockParentheses = true,\n\t\t\t\tSpaceBeforeUsingParentheses = true,\n\n\t\t\t\tSpaceAroundAssignment = true,\n\t\t\t\tSpaceAroundLogicalOperator = true,\n\t\t\t\tSpaceAroundEqualityOperator = true,\n\t\t\t\tSpaceAroundRelationalOperator = true,\n\t\t\t\tSpaceAroundBitwiseOperator = true,\n\t\t\t\tSpaceAroundAdditiveOperator = true,\n\t\t\t\tSpaceAroundMultiplicativeOperator = true,\n\t\t\t\tSpaceAroundShiftOperator = true,\n\t\t\t\tSpaceAroundNullCoalescingOperator = true,\n\t\t\t\tSpacesWithinParentheses = false,\n\t\t\t\tSpaceWithinMethodCallParentheses = false,\n\t\t\t\tSpaceWithinMethodDeclarationParentheses = false,\n\t\t\t\tSpacesWithinIfParentheses = false,\n\t\t\t\tSpacesWithinWhileParentheses = false,\n\t\t\t\tSpacesWithinForParentheses = false,\n\t\t\t\tSpacesWithinForeachParentheses = false,\n\t\t\t\tSpacesWithinCatchParentheses = false,\n\t\t\t\tSpacesWithinSwitchParentheses = false,\n\t\t\t\tSpacesWithinLockParentheses = false,\n\t\t\t\tSpacesWithinUsingParentheses = false,\n\t\t\t\tSpacesWithinCastParentheses = false,\n\t\t\t\tSpacesWithinSizeOfParentheses = false,\n\t\t\t\tSpacesWithinTypeOfParentheses = false,\n\t\t\t\tSpacesWithinCheckedExpressionParantheses = false,\n\t\t\t\tSpaceBeforeConditionalOperatorCondition = true,\n\t\t\t\tSpaceAfterConditionalOperatorCondition = true,\n\t\t\t\tSpaceBeforeConditionalOperatorSeparator = true,\n\t\t\t\tSpaceAfterConditionalOperatorSeparator = true,\n\t\t\t\tSpaceBeforeArrayDeclarationBrackets = false,\n\n\t\t\t\tSpacesWithinBrackets = false,\n\t\t\t\tSpacesBeforeBrackets = false,\n\t\t\t\tSpaceBeforeBracketComma = false,\n\t\t\t\tSpaceAfterBracketComma = true,\n\n\t\t\t\tSpaceBeforeForSemicolon = false,\n\t\t\t\tSpaceAfterForSemicolon = true,\n\t\t\t\tSpaceAfterTypecast = false,\n\n\t\t\t\tAlignEmbeddedStatements = true,\n\t\t\t\tSimplePropertyFormatting = PropertyFormatting.SingleLine,\n\t\t\t\tAutoPropertyFormatting = PropertyFormatting.SingleLine,\n\t\t\t\tEmptyLineFormatting = EmptyLineFormatting.DoNotIndent,\n\t\t\t\tSpaceBeforeMethodDeclarationParameterComma = false,\n\t\t\t\tSpaceAfterMethodDeclarationParameterComma = true,\n\t\t\t\tSpaceAfterDelegateDeclarationParameterComma = true,\n\t\t\t\tSpaceBeforeFieldDeclarationComma = false,\n\t\t\t\tSpaceAfterFieldDeclarationComma = true,\n\t\t\t\tSpaceBeforeLocalVariableDeclarationComma = false,\n\t\t\t\tSpaceAfterLocalVariableDeclarationComma = true,\n\n\t\t\t\tSpaceWithinIndexerDeclarationBracket = false,\n\t\t\t\tSpaceBeforeIndexerDeclarationParameterComma = false,\n\t\t\t\tSpaceInNamedArgumentAfterDoubleColon = true,\n\n\t\t\t\tSpaceAfterIndexerDeclarationParameterComma = true,\n\t\t\t\tRemoveEndOfLineWhiteSpace = true,\n\n\t\t\t\tMinimumBlankLinesBeforeUsings = 0,\n\t\t\t\tMinimumBlankLinesAfterUsings = 1,\n\n\t\t\t\tMinimumBlankLinesBeforeFirstDeclaration = 0,\n\t\t\t\tMinimumBlankLinesBetweenTypes = 1,\n\t\t\t\tMinimumBlankLinesBetweenFields = 0,\n\t\t\t\tMinimumBlankLinesBetweenEventFields = 0,\n\t\t\t\tMinimumBlankLinesBetweenMembers = 1,\n\t\t\t\tMinimumBlankLinesAroundRegion = 1,\n\t\t\t\tMinimumBlankLinesInsideRegion = 1,\n\n\t\t\t\tKeepCommentsAtFirstColumn = true,\n\t\t\t\tChainedMethodCallWrapping = Wrapping.DoNotWrap,\n\t\t\t\tMethodCallArgumentWrapping = Wrapping.DoNotWrap,\n\t\t\t\tNewLineAferMethodCallOpenParentheses = NewLinePlacement.DoNotCare,\n\t\t\t\tMethodCallClosingParenthesesOnNewLine = NewLinePlacement.DoNotCare,\n\n\t\t\t\tIndexerArgumentWrapping = Wrapping.DoNotWrap,\n\t\t\t\tNewLineAferIndexerOpenBracket = NewLinePlacement.DoNotCare,\n\t\t\t\tIndexerClosingBracketOnNewLine = NewLinePlacement.DoNotCare,\n\n\t\t\t\tNewLineBeforeNewQueryClause = NewLinePlacement.NewLine\n\t\t\t};\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates allman indent style CSharpFormatting options used in Visual Studio.\n\t\t/// </summary>\n\t\tpublic static CSharpFormattingOptions CreateAllman()\n\t\t{\n\t\t\tvar baseOptions = CreateKRStyle();\n\t\t\tbaseOptions.AnonymousMethodBraceStyle = BraceStyle.NextLine;\n\t\t\tbaseOptions.PropertyBraceStyle = BraceStyle.NextLine;\n\t\t\tbaseOptions.PropertyGetBraceStyle = BraceStyle.NextLine;\n\t\t\tbaseOptions.PropertySetBraceStyle = BraceStyle.NextLine;\n\n\t\t\tbaseOptions.EventBraceStyle = BraceStyle.NextLine;\n\t\t\tbaseOptions.EventAddBraceStyle = BraceStyle.NextLine;\n\t\t\tbaseOptions.EventRemoveBraceStyle = BraceStyle.NextLine;\n\t\t\tbaseOptions.StatementBraceStyle = BraceStyle.NextLine;\n\t\t\tbaseOptions.ArrayInitializerBraceStyle = BraceStyle.NextLine;\n\n\t\t\tbaseOptions.CatchNewLinePlacement = NewLinePlacement.NewLine;\n\t\t\tbaseOptions.ElseNewLinePlacement = NewLinePlacement.NewLine;\n\t\t\tbaseOptions.ElseIfNewLinePlacement = NewLinePlacement.SameLine;\n\n\t\t\tbaseOptions.FinallyNewLinePlacement = NewLinePlacement.NewLine;\n\t\t\tbaseOptions.WhileNewLinePlacement = NewLinePlacement.DoNotCare;\n\t\t\tbaseOptions.ArrayInitializerWrapping = Wrapping.DoNotWrap;\n\t\t\tbaseOptions.IndentBlocksInsideExpressions = true;\n\n\t\t\treturn baseOptions;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// The Whitesmiths style, also called Wishart style to a lesser extent, is less common today than the previous three. It was originally used in the documentation for the first commercial C compiler, the Whitesmiths Compiler.\n\t\t/// </summary>\n\t\tpublic static CSharpFormattingOptions CreateWhitesmiths()\n\t\t{\n\t\t\tvar baseOptions = CreateKRStyle();\n\n\t\t\tbaseOptions.NamespaceBraceStyle = BraceStyle.NextLineShifted;\n\t\t\tbaseOptions.ClassBraceStyle = BraceStyle.NextLineShifted;\n\t\t\tbaseOptions.InterfaceBraceStyle = BraceStyle.NextLineShifted;\n\t\t\tbaseOptions.StructBraceStyle = BraceStyle.NextLineShifted;\n\t\t\tbaseOptions.EnumBraceStyle = BraceStyle.NextLineShifted;\n\t\t\tbaseOptions.MethodBraceStyle = BraceStyle.NextLineShifted;\n\t\t\tbaseOptions.ConstructorBraceStyle = BraceStyle.NextLineShifted;\n\t\t\tbaseOptions.DestructorBraceStyle = BraceStyle.NextLineShifted;\n\t\t\tbaseOptions.AnonymousMethodBraceStyle = BraceStyle.NextLineShifted;\n\t\t\tbaseOptions.PropertyBraceStyle = BraceStyle.NextLineShifted;\n\t\t\tbaseOptions.PropertyGetBraceStyle = BraceStyle.NextLineShifted;\n\t\t\tbaseOptions.PropertySetBraceStyle = BraceStyle.NextLineShifted;\n\n\t\t\tbaseOptions.EventBraceStyle = BraceStyle.NextLineShifted;\n\t\t\tbaseOptions.EventAddBraceStyle = BraceStyle.NextLineShifted;\n\t\t\tbaseOptions.EventRemoveBraceStyle = BraceStyle.NextLineShifted;\n\t\t\tbaseOptions.StatementBraceStyle = BraceStyle.NextLineShifted;\n\t\t\tbaseOptions.IndentBlocksInsideExpressions = true;\n\t\t\treturn baseOptions;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Like the Allman and Whitesmiths styles, GNU style puts braces on a line by themselves, indented by 2 spaces,\n\t\t/// except when opening a function definition, where they are not indented.\n\t\t/// In either case, the contained code is indented by 2 spaces from the braces.\n\t\t/// Popularised by Richard Stallman, the layout may be influenced by his background of writing Lisp code.\n\t\t/// In Lisp the equivalent to a block (a progn) \n\t\t/// is a first class data entity and giving it its own indent level helps to emphasize that,\n\t\t/// whereas in C a block is just syntax.\n\t\t/// Although not directly related to indentation, GNU coding style also includes a space before the bracketed \n\t\t/// list of arguments to a function.\n\t\t/// </summary>\n\t\tpublic static CSharpFormattingOptions CreateGNU()\n\t\t{\n\t\t\tvar baseOptions = CreateAllman();\n\t\t\tbaseOptions.StatementBraceStyle = BraceStyle.NextLineShifted2;\n\t\t\treturn baseOptions;\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/OutputVisitor/GenericGrammarAmbiguityVisitor.cs",
    "content": "// Copyright (c) 2020 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\n\nnamespace ICSharpCode.Decompiler.CSharp.OutputVisitor\n{\n\t/// <summary>\n\t/// Used to test for the \"F(G&lt;A,B&gt;(7));\" grammar ambiguity.\n\t/// </summary>\n\tclass GenericGrammarAmbiguityVisitor : DepthFirstAstVisitor<bool>\n\t{\n\t\t/// <summary>\n\t\t/// Resolves ambiguities in the specified syntax tree.\n\t\t/// This method must be called after the InsertParenthesesVisitor, because the ambiguity depends on whether the\n\t\t/// final `>` in the possible-type-argument is followed by an opening parenthesis.\n\t\t/// </summary>\n\t\tpublic static void ResolveAmbiguities(AstNode rootNode)\n\t\t{\n\t\t\tforeach (var node in rootNode.Descendants.OfType<BinaryOperatorExpression>())\n\t\t\t{\n\t\t\t\tif (CausesAmbiguityWithGenerics(node))\n\t\t\t\t{\n\t\t\t\t\tnode.ReplaceWith(n => new ParenthesizedExpression(n));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static bool CausesAmbiguityWithGenerics(BinaryOperatorExpression binaryOperatorExpression)\n\t\t{\n\t\t\tif (binaryOperatorExpression.Operator != BinaryOperatorType.LessThan)\n\t\t\t\treturn false;\n\n\t\t\tvar v = new GenericGrammarAmbiguityVisitor();\n\t\t\tv.genericNestingLevel = 1;\n\n\t\t\tfor (AstNode node = binaryOperatorExpression.Right; node != null; node = node.GetNextNode())\n\t\t\t{\n\t\t\t\tif (node.AcceptVisitor(v))\n\t\t\t\t\treturn v.ambiguityFound;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tint genericNestingLevel;\n\t\tbool ambiguityFound;\n\n\t\tprotected override bool VisitChildren(AstNode node)\n\t\t{\n\t\t\t// unhandled node: probably not syntactically valid in a typename\n\n\t\t\t// These are preconditions for all recursive Visit() calls.\n\t\t\tDebug.Assert(genericNestingLevel > 0);\n\t\t\tDebug.Assert(!ambiguityFound);\n\n\t\t\t// The return value merely indicates whether to stop visiting.\n\t\t\treturn true; // stop visiting, no ambiguity found\n\t\t}\n\n\t\tpublic override bool VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)\n\t\t{\n\t\t\tif (binaryOperatorExpression.Left.AcceptVisitor(this))\n\t\t\t\treturn true;\n\t\t\tDebug.Assert(genericNestingLevel > 0);\n\t\t\tswitch (binaryOperatorExpression.Operator)\n\t\t\t{\n\t\t\t\tcase BinaryOperatorType.LessThan:\n\t\t\t\t\tgenericNestingLevel += 1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.GreaterThan:\n\t\t\t\t\tgenericNestingLevel--;\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.ShiftRight when genericNestingLevel >= 2:\n\t\t\t\t\tgenericNestingLevel -= 2;\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.UnsignedShiftRight when genericNestingLevel >= 3:\n\t\t\t\t\tgenericNestingLevel -= 3;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\treturn true; // stop visiting, no ambiguity found\n\t\t\t}\n\t\t\tif (genericNestingLevel == 0)\n\t\t\t{\n\t\t\t\t// Of the all tokens that might follow `>` and trigger the ambiguity to be resolved in favor of generics,\n\t\t\t\t// `(` is the only one that might start an expression.\n\t\t\t\tambiguityFound = binaryOperatorExpression.Right is ParenthesizedExpression;\n\t\t\t\treturn true; // stop visiting\n\t\t\t}\n\t\t\treturn binaryOperatorExpression.Right.AcceptVisitor(this);\n\t\t}\n\n\t\tpublic override bool VisitIdentifierExpression(IdentifierExpression identifierExpression)\n\t\t{\n\t\t\t// identifier could also be valid in a type argument\n\t\t\treturn false; // keep visiting\n\t\t}\n\n\t\tpublic override bool VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression)\n\t\t{\n\t\t\treturn false; // keep visiting\n\t\t}\n\n\t\tpublic override bool VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression)\n\t\t{\n\t\t\t// MRE could also be valid in a type argument\n\t\t\treturn memberReferenceExpression.Target.AcceptVisitor(this);\n\t\t}\n\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/OutputVisitor/ITokenWriter.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\n\nnamespace ICSharpCode.Decompiler.CSharp.OutputVisitor\n{\n\tpublic abstract class TokenWriter\n\t{\n\t\tpublic abstract void StartNode(AstNode node);\n\t\tpublic abstract void EndNode(AstNode node);\n\n\t\t/// <summary>\n\t\t/// Writes an identifier.\n\t\t/// </summary>\n\t\tpublic abstract void WriteIdentifier(Identifier identifier);\n\n\t\t/// <summary>\n\t\t/// Writes a keyword to the output.\n\t\t/// </summary>\n\t\tpublic abstract void WriteKeyword(Role role, string keyword);\n\n\t\t/// <summary>\n\t\t/// Writes a token to the output.\n\t\t/// </summary>\n\t\tpublic abstract void WriteToken(Role role, string token);\n\n\t\t/// <summary>\n\t\t/// Writes a primitive/literal value\n\t\t/// </summary>\n\t\tpublic abstract void WritePrimitiveValue(object value, LiteralFormat format = LiteralFormat.None);\n\n\t\tpublic abstract void WritePrimitiveType(string type);\n\n\t\t/// <summary>\n\t\t/// Write a piece of text in an interpolated string literal.\n\t\t/// </summary>\n\t\tpublic abstract void WriteInterpolatedText(string text);\n\n\t\tpublic abstract void Space();\n\t\tpublic abstract void Indent();\n\t\tpublic abstract void Unindent();\n\t\tpublic abstract void NewLine();\n\n\t\tpublic abstract void WriteComment(CommentType commentType, string content);\n\t\tpublic abstract void WritePreProcessorDirective(PreProcessorDirectiveType type, string argument);\n\n\t\tpublic static TokenWriter Create(TextWriter writer, string indentation = \"\\t\")\n\t\t{\n\t\t\treturn new InsertSpecialsDecorator(new InsertRequiredSpacesDecorator(new TextWriterTokenWriter(writer) { IndentationString = indentation }));\n\t\t}\n\n\t\tpublic static TokenWriter CreateWriterThatSetsLocationsInAST(TextWriter writer, string indentation = \"\\t\")\n\t\t{\n\t\t\tvar target = new TextWriterTokenWriter(writer) { IndentationString = indentation };\n\t\t\treturn new InsertSpecialsDecorator(new InsertRequiredSpacesDecorator(new InsertMissingTokensDecorator(target, target)));\n\t\t}\n\n\t\tpublic static TokenWriter InsertRequiredSpaces(TokenWriter writer)\n\t\t{\n\t\t\treturn new InsertRequiredSpacesDecorator(writer);\n\t\t}\n\n\t\tpublic static TokenWriter WrapInWriterThatSetsLocationsInAST(TokenWriter writer)\n\t\t{\n\t\t\tif (!(writer is ILocatable))\n\t\t\t\tthrow new InvalidOperationException(\"writer does not provide locations!\");\n\t\t\treturn new InsertMissingTokensDecorator(writer, (ILocatable)writer);\n\t\t}\n\t}\n\n\tpublic interface ILocatable\n\t{\n\t\tTextLocation Location { get; }\n\t\tint Length { get; }\n\t}\n\n\tpublic abstract class DecoratingTokenWriter : TokenWriter\n\t{\n\t\treadonly TokenWriter decoratedWriter;\n\n\t\tprotected DecoratingTokenWriter(TokenWriter decoratedWriter)\n\t\t{\n\t\t\tif (decoratedWriter == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(decoratedWriter));\n\t\t\tthis.decoratedWriter = decoratedWriter;\n\t\t}\n\n\t\tpublic override void StartNode(AstNode node)\n\t\t{\n\t\t\tdecoratedWriter.StartNode(node);\n\t\t}\n\n\t\tpublic override void EndNode(AstNode node)\n\t\t{\n\t\t\tdecoratedWriter.EndNode(node);\n\t\t}\n\n\t\tpublic override void WriteIdentifier(Identifier identifier)\n\t\t{\n\t\t\tdecoratedWriter.WriteIdentifier(identifier);\n\t\t}\n\n\t\tpublic override void WriteKeyword(Role role, string keyword)\n\t\t{\n\t\t\tdecoratedWriter.WriteKeyword(role, keyword);\n\t\t}\n\n\t\tpublic override void WriteToken(Role role, string token)\n\t\t{\n\t\t\tdecoratedWriter.WriteToken(role, token);\n\t\t}\n\n\t\tpublic override void WritePrimitiveValue(object value, LiteralFormat format = LiteralFormat.None)\n\t\t{\n\t\t\tdecoratedWriter.WritePrimitiveValue(value, format);\n\t\t}\n\n\t\tpublic override void WritePrimitiveType(string type)\n\t\t{\n\t\t\tdecoratedWriter.WritePrimitiveType(type);\n\t\t}\n\n\t\tpublic override void WriteInterpolatedText(string text)\n\t\t{\n\t\t\tdecoratedWriter.WriteInterpolatedText(text);\n\t\t}\n\n\t\tpublic override void Space()\n\t\t{\n\t\t\tdecoratedWriter.Space();\n\t\t}\n\n\t\tpublic override void Indent()\n\t\t{\n\t\t\tdecoratedWriter.Indent();\n\t\t}\n\n\t\tpublic override void Unindent()\n\t\t{\n\t\t\tdecoratedWriter.Unindent();\n\t\t}\n\n\t\tpublic override void NewLine()\n\t\t{\n\t\t\tdecoratedWriter.NewLine();\n\t\t}\n\n\t\tpublic override void WriteComment(CommentType commentType, string content)\n\t\t{\n\t\t\tdecoratedWriter.WriteComment(commentType, content);\n\t\t}\n\n\t\tpublic override void WritePreProcessorDirective(PreProcessorDirectiveType type, string argument)\n\t\t{\n\t\t\tdecoratedWriter.WritePreProcessorDirective(type, argument);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertMissingTokensDecorator.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\n\nnamespace ICSharpCode.Decompiler.CSharp.OutputVisitor\n{\n\tclass InsertMissingTokensDecorator : DecoratingTokenWriter\n\t{\n\t\treadonly Stack<List<AstNode>> nodes = new Stack<List<AstNode>>();\n\t\tList<AstNode> currentList;\n\t\treadonly ILocatable locationProvider;\n\n\t\tpublic InsertMissingTokensDecorator(TokenWriter writer, ILocatable locationProvider)\n\t\t\t: base(writer)\n\t\t{\n\t\t\tthis.locationProvider = locationProvider;\n\t\t\tcurrentList = new List<AstNode>();\n\t\t}\n\n\t\tpublic override void StartNode(AstNode node)\n\t\t{\n\t\t\t// ignore whitespace: these don't need to be processed.\n\t\t\t// StartNode/EndNode is only called for them to support folding of comments.\n\t\t\tif (node.NodeType != NodeType.Whitespace)\n\t\t\t{\n\t\t\t\tcurrentList.Add(node);\n\t\t\t\tnodes.Push(currentList);\n\t\t\t\tcurrentList = new List<AstNode>();\n\t\t\t}\n\t\t\telse if (node is Comment comment)\n\t\t\t{\n\t\t\t\tcomment.SetStartLocation(locationProvider.Location);\n\t\t\t}\n\t\t\tif (node is ErrorExpression error)\n\t\t\t{\n\t\t\t\terror.Location = locationProvider.Location;\n\t\t\t}\n\t\t\tbase.StartNode(node);\n\t\t}\n\n\t\tpublic override void EndNode(AstNode node)\n\t\t{\n\t\t\t// ignore whitespace: these don't need to be processed.\n\t\t\t// StartNode/EndNode is only called for them to support folding of comments.\n\t\t\tif (node.NodeType != NodeType.Whitespace)\n\t\t\t{\n\t\t\t\tSystem.Diagnostics.Debug.Assert(currentList != null);\n\t\t\t\tforeach (var removable in node.Children.Where(n => n is CSharpTokenNode))\n\t\t\t\t{\n\t\t\t\t\tremovable.Remove();\n\t\t\t\t}\n\t\t\t\tforeach (var child in currentList)\n\t\t\t\t{\n\t\t\t\t\tSystem.Diagnostics.Debug.Assert(child.Parent == null || node == child.Parent);\n\t\t\t\t\tchild.Remove();\n\t\t\t\t\tnode.AddChildWithExistingRole(child);\n\t\t\t\t}\n\t\t\t\tcurrentList = nodes.Pop();\n\t\t\t}\n\t\t\telse if (node is Comment comment)\n\t\t\t{\n\t\t\t\tcomment.SetEndLocation(locationProvider.Location);\n\t\t\t}\n\t\t\tbase.EndNode(node);\n\t\t}\n\n\t\tpublic override void WriteToken(Role role, string token)\n\t\t{\n\t\t\tswitch (nodes.Peek().LastOrDefault())\n\t\t\t{\n\t\t\t\tcase EmptyStatement emptyStatement:\n\t\t\t\t\temptyStatement.Location = locationProvider.Location;\n\t\t\t\t\tbreak;\n\t\t\t\tcase ErrorExpression errorExpression:\n\t\t\t\t\terrorExpression.Location = locationProvider.Location;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tCSharpTokenNode t = new CSharpTokenNode(locationProvider.Location, (TokenRole)role);\n\t\t\t\t\tt.Role = role;\n\t\t\t\t\tcurrentList.Add(t);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbase.WriteToken(role, token);\n\t\t}\n\n\t\tpublic override void WriteKeyword(Role role, string keyword)\n\t\t{\n\t\t\tTextLocation start = locationProvider.Location;\n\t\t\tCSharpTokenNode t = null;\n\t\t\tif (role is TokenRole)\n\t\t\t\tt = new CSharpTokenNode(start, (TokenRole)role);\n\t\t\telse if (role == EntityDeclaration.ModifierRole)\n\t\t\t\tt = new CSharpModifierToken(start, CSharpModifierToken.GetModifierValue(keyword));\n\t\t\telse if (keyword == \"this\")\n\t\t\t{\n\t\t\t\tThisReferenceExpression node = nodes.Peek().LastOrDefault() as ThisReferenceExpression;\n\t\t\t\tif (node != null)\n\t\t\t\t\tnode.Location = start;\n\t\t\t}\n\t\t\telse if (keyword == \"base\")\n\t\t\t{\n\t\t\t\tBaseReferenceExpression node = nodes.Peek().LastOrDefault() as BaseReferenceExpression;\n\t\t\t\tif (node != null)\n\t\t\t\t\tnode.Location = start;\n\t\t\t}\n\t\t\tif (t != null)\n\t\t\t{\n\t\t\t\tcurrentList.Add(t);\n\t\t\t\tt.Role = role;\n\t\t\t}\n\t\t\tbase.WriteKeyword(role, keyword);\n\t\t}\n\n\t\tpublic override void WriteIdentifier(Identifier identifier)\n\t\t{\n\t\t\tif (!identifier.IsNull)\n\t\t\t\tidentifier.SetStartLocation(locationProvider.Location);\n\t\t\tcurrentList.Add(identifier);\n\t\t\tbase.WriteIdentifier(identifier);\n\t\t}\n\n\t\tpublic override void WritePrimitiveValue(object value, LiteralFormat format = LiteralFormat.None)\n\t\t{\n\t\t\tExpression node = nodes.Peek().LastOrDefault() as Expression;\n\t\t\tvar startLocation = locationProvider.Location;\n\t\t\tbase.WritePrimitiveValue(value, format);\n\t\t\tif (node is PrimitiveExpression)\n\t\t\t{\n\t\t\t\t((PrimitiveExpression)node).SetLocation(startLocation, locationProvider.Location);\n\t\t\t}\n\t\t\tif (node is NullReferenceExpression)\n\t\t\t{\n\t\t\t\t((NullReferenceExpression)node).SetStartLocation(startLocation);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void WritePrimitiveType(string type)\n\t\t{\n\t\t\tPrimitiveType node = nodes.Peek().LastOrDefault() as PrimitiveType;\n\t\t\tif (node != null)\n\t\t\t\tnode.SetStartLocation(locationProvider.Location);\n\t\t\tbase.WritePrimitiveType(type);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertParenthesesVisitor.cs",
    "content": "// Copyright (c) 2010-2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\n\nnamespace ICSharpCode.Decompiler.CSharp.OutputVisitor\n{\n\t/// <summary>\n\t/// Inserts the parentheses into the AST that are needed to ensure the AST can be printed correctly.\n\t/// For example, if the AST contains\n\t/// BinaryOperatorExpresson(2, Mul, BinaryOperatorExpression(1, Add, 1))); printing that AST\n\t/// would incorrectly result in \"2 * 1 + 1\". By running InsertParenthesesVisitor, the necessary\n\t/// parentheses are inserted: \"2 * (1 + 1)\".\n\t/// </summary>\n\tpublic class InsertParenthesesVisitor : DepthFirstAstVisitor\n\t{\n\t\t/// <summary>\n\t\t/// Gets/Sets whether the visitor should insert parentheses to make the code better looking.\n\t\t/// If this property is false, it will insert parentheses only where strictly required by the language spec.\n\t\t/// </summary>\n\t\tpublic bool InsertParenthesesForReadability { get; set; }\n\n\t\tenum PrecedenceLevel\n\t\t{\n\t\t\t// Higher integer value = higher precedence.\n\t\t\tAssignment,\n\t\t\tConditional,    // ?:\n\t\t\tNullCoalescing, // ??\n\t\t\tConditionalOr,  // ||\n\t\t\tConditionalAnd, // &&\n\t\t\tBitwiseOr,      // |\n\t\t\tExclusiveOr,    // binary ^\n\t\t\tBitwiseAnd,     // binary &\n\t\t\tEquality,       // == !=\n\t\t\tRelationalAndTypeTesting, // < <= > >= is\n\t\t\tShift,          // << >>\n\t\t\tAdditive,       // binary + -\n\t\t\tMultiplicative, // * / %\n\t\t\tSwitch,         // C# 8 switch expression\n\t\t\tRange,          // ..\n\t\t\tUnary,\n\t\t\tQueryOrLambda,\n\t\t\tNullableRewrap,\n\t\t\tPrimary\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the row number in the C# 4.0 spec operator precedence table.\n\t\t/// </summary>\n\t\tstatic PrecedenceLevel GetPrecedence(Expression expr)\n\t\t{\n\t\t\t// Note: the operator precedence table on MSDN is incorrect\n\t\t\tif (expr is QueryExpression || expr is LambdaExpression)\n\t\t\t{\n\t\t\t\t// Not part of the table in the C# spec, but we need to ensure that queries within\n\t\t\t\t// primary expressions get parenthesized.\n\t\t\t\treturn PrecedenceLevel.QueryOrLambda;\n\t\t\t}\n\t\t\tif (expr is UnaryOperatorExpression uoe)\n\t\t\t{\n\t\t\t\tswitch (uoe.Operator)\n\t\t\t\t{\n\t\t\t\t\tcase UnaryOperatorType.PostDecrement:\n\t\t\t\t\tcase UnaryOperatorType.PostIncrement:\n\t\t\t\t\tcase UnaryOperatorType.NullConditional:\n\t\t\t\t\tcase UnaryOperatorType.SuppressNullableWarning:\n\t\t\t\t\t\treturn PrecedenceLevel.Primary;\n\t\t\t\t\tcase UnaryOperatorType.NullConditionalRewrap:\n\t\t\t\t\t\treturn PrecedenceLevel.NullableRewrap;\n\t\t\t\t\tcase UnaryOperatorType.IsTrue:\n\t\t\t\t\t\treturn PrecedenceLevel.Conditional;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn PrecedenceLevel.Unary;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (expr is CastExpression)\n\t\t\t\treturn PrecedenceLevel.Unary;\n\t\t\tif (expr is PrimitiveExpression primitive)\n\t\t\t{\n\t\t\t\tvar value = primitive.Value;\n\t\t\t\tif (value is int i && i < 0)\n\t\t\t\t\treturn PrecedenceLevel.Unary;\n\t\t\t\tif (value is long l && l < 0)\n\t\t\t\t\treturn PrecedenceLevel.Unary;\n\t\t\t\tif (value is float f && f < 0)\n\t\t\t\t\treturn PrecedenceLevel.Unary;\n\t\t\t\tif (value is double d && d < 0)\n\t\t\t\t\treturn PrecedenceLevel.Unary;\n\t\t\t\tif (value is decimal de && de < 0)\n\t\t\t\t\treturn PrecedenceLevel.Unary;\n\t\t\t\treturn PrecedenceLevel.Primary;\n\t\t\t}\n\t\t\tif (expr is BinaryOperatorExpression boe)\n\t\t\t{\n\t\t\t\tswitch (boe.Operator)\n\t\t\t\t{\n\t\t\t\t\tcase BinaryOperatorType.Range:\n\t\t\t\t\t\treturn PrecedenceLevel.Range;\n\t\t\t\t\tcase BinaryOperatorType.Multiply:\n\t\t\t\t\tcase BinaryOperatorType.Divide:\n\t\t\t\t\tcase BinaryOperatorType.Modulus:\n\t\t\t\t\t\treturn PrecedenceLevel.Multiplicative;\n\t\t\t\t\tcase BinaryOperatorType.Add:\n\t\t\t\t\tcase BinaryOperatorType.Subtract:\n\t\t\t\t\t\treturn PrecedenceLevel.Additive;\n\t\t\t\t\tcase BinaryOperatorType.ShiftLeft:\n\t\t\t\t\tcase BinaryOperatorType.ShiftRight:\n\t\t\t\t\tcase BinaryOperatorType.UnsignedShiftRight:\n\t\t\t\t\t\treturn PrecedenceLevel.Shift;\n\t\t\t\t\tcase BinaryOperatorType.GreaterThan:\n\t\t\t\t\tcase BinaryOperatorType.GreaterThanOrEqual:\n\t\t\t\t\tcase BinaryOperatorType.LessThan:\n\t\t\t\t\tcase BinaryOperatorType.LessThanOrEqual:\n\t\t\t\t\t\treturn PrecedenceLevel.RelationalAndTypeTesting;\n\t\t\t\t\tcase BinaryOperatorType.Equality:\n\t\t\t\t\tcase BinaryOperatorType.InEquality:\n\t\t\t\t\t\treturn PrecedenceLevel.Equality;\n\t\t\t\t\tcase BinaryOperatorType.BitwiseAnd:\n\t\t\t\t\t\treturn PrecedenceLevel.BitwiseAnd;\n\t\t\t\t\tcase BinaryOperatorType.ExclusiveOr:\n\t\t\t\t\t\treturn PrecedenceLevel.ExclusiveOr;\n\t\t\t\t\tcase BinaryOperatorType.BitwiseOr:\n\t\t\t\t\t\treturn PrecedenceLevel.BitwiseOr;\n\t\t\t\t\tcase BinaryOperatorType.ConditionalAnd:\n\t\t\t\t\t\treturn PrecedenceLevel.ConditionalAnd;\n\t\t\t\t\tcase BinaryOperatorType.ConditionalOr:\n\t\t\t\t\t\treturn PrecedenceLevel.ConditionalOr;\n\t\t\t\t\tcase BinaryOperatorType.NullCoalescing:\n\t\t\t\t\t\treturn PrecedenceLevel.NullCoalescing;\n\t\t\t\t\tcase BinaryOperatorType.IsPattern:\n\t\t\t\t\t\treturn PrecedenceLevel.RelationalAndTypeTesting;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new NotSupportedException(\"Invalid value for BinaryOperatorType\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (expr is SwitchExpression)\n\t\t\t\treturn PrecedenceLevel.Switch;\n\t\t\tif (expr is IsExpression || expr is AsExpression)\n\t\t\t\treturn PrecedenceLevel.RelationalAndTypeTesting;\n\t\t\tif (expr is ConditionalExpression || expr is DirectionExpression)\n\t\t\t\treturn PrecedenceLevel.Conditional;\n\t\t\tif (expr is AssignmentExpression)\n\t\t\t\treturn PrecedenceLevel.Assignment;\n\t\t\t// anything else: primary expression\n\t\t\treturn PrecedenceLevel.Primary;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Parenthesizes the expression if it does not have the minimum required precedence.\n\t\t/// </summary>\n\t\tstatic void ParenthesizeIfRequired(Expression expr, PrecedenceLevel minimumPrecedence)\n\t\t{\n\t\t\tif (GetPrecedence(expr) < minimumPrecedence)\n\t\t\t{\n\t\t\t\tParenthesize(expr);\n\t\t\t}\n\t\t}\n\n\t\tstatic void Parenthesize(Expression expr)\n\t\t{\n\t\t\texpr.ReplaceWith(e => new ParenthesizedExpression { Expression = e });\n\t\t}\n\n\t\t// Primary expressions\n\t\tpublic override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression)\n\t\t{\n\t\t\tParenthesizeIfRequired(memberReferenceExpression.Target, PrecedenceLevel.Primary);\n\t\t\tbase.VisitMemberReferenceExpression(memberReferenceExpression);\n\t\t}\n\n\t\tpublic override void VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression)\n\t\t{\n\t\t\tParenthesizeIfRequired(pointerReferenceExpression.Target, PrecedenceLevel.Primary);\n\t\t\tbase.VisitPointerReferenceExpression(pointerReferenceExpression);\n\t\t}\n\n\t\tpublic override void VisitInvocationExpression(InvocationExpression invocationExpression)\n\t\t{\n\t\t\tParenthesizeIfRequired(invocationExpression.Target, PrecedenceLevel.Primary);\n\t\t\tbase.VisitInvocationExpression(invocationExpression);\n\t\t}\n\n\t\tpublic override void VisitIndexerExpression(IndexerExpression indexerExpression)\n\t\t{\n\t\t\tParenthesizeIfRequired(indexerExpression.Target, PrecedenceLevel.Primary);\n\t\t\tswitch (indexerExpression.Target)\n\t\t\t{\n\t\t\t\tcase ArrayCreateExpression ace when InsertParenthesesForReadability || ace.Initializer.IsNull:\n\t\t\t\t\t// require parentheses for \"(new int[1])[0]\"\n\t\t\t\t\tParenthesize(indexerExpression.Target);\n\t\t\t\t\tbreak;\n\t\t\t\tcase StackAllocExpression sae when InsertParenthesesForReadability || sae.Initializer.IsNull:\n\t\t\t\t\t// require parentheses for \"(stackalloc int[1])[0]\"\n\t\t\t\t\tParenthesize(indexerExpression.Target);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbase.VisitIndexerExpression(indexerExpression);\n\t\t}\n\n\t\t// Unary expressions\n\t\tpublic override void VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression)\n\t\t{\n\t\t\tParenthesizeIfRequired(unaryOperatorExpression.Expression, GetPrecedence(unaryOperatorExpression));\n\t\t\tUnaryOperatorExpression child = unaryOperatorExpression.Expression as UnaryOperatorExpression;\n\t\t\tif (child != null && InsertParenthesesForReadability)\n\t\t\t\tParenthesize(child);\n\t\t\tbase.VisitUnaryOperatorExpression(unaryOperatorExpression);\n\t\t}\n\n\t\tpublic override void VisitCastExpression(CastExpression castExpression)\n\t\t{\n\t\t\t// Even in readability mode, don't parenthesize casts of casts.\n\t\t\tif (!(castExpression.Expression is CastExpression))\n\t\t\t{\n\t\t\t\tParenthesizeIfRequired(castExpression.Expression, InsertParenthesesForReadability ? PrecedenceLevel.NullableRewrap : PrecedenceLevel.Unary);\n\t\t\t}\n\t\t\t// There's a nasty issue in the C# grammar: cast expressions including certain operators are ambiguous in some cases\n\t\t\t// \"(int)-1\" is fine, but \"(A)-b\" is not a cast.\n\t\t\tUnaryOperatorExpression uoe = castExpression.Expression as UnaryOperatorExpression;\n\t\t\tif (uoe != null && !(uoe.Operator == UnaryOperatorType.BitNot || uoe.Operator == UnaryOperatorType.Not))\n\t\t\t{\n\t\t\t\tif (TypeCanBeMisinterpretedAsExpression(castExpression.Type))\n\t\t\t\t{\n\t\t\t\t\tParenthesize(castExpression.Expression);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// The above issue can also happen with PrimitiveExpressions representing negative values:\n\t\t\tPrimitiveExpression pe = castExpression.Expression as PrimitiveExpression;\n\t\t\tif (pe != null && pe.Value != null && TypeCanBeMisinterpretedAsExpression(castExpression.Type))\n\t\t\t{\n\t\t\t\tTypeCode typeCode = Type.GetTypeCode(pe.Value.GetType());\n\t\t\t\tswitch (typeCode)\n\t\t\t\t{\n\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\tif ((sbyte)pe.Value < 0)\n\t\t\t\t\t\t\tParenthesize(castExpression.Expression);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\tif ((short)pe.Value < 0)\n\t\t\t\t\t\t\tParenthesize(castExpression.Expression);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\tif ((int)pe.Value < 0)\n\t\t\t\t\t\t\tParenthesize(castExpression.Expression);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\tif ((long)pe.Value < 0)\n\t\t\t\t\t\t\tParenthesize(castExpression.Expression);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\tif ((float)pe.Value < 0)\n\t\t\t\t\t\t\tParenthesize(castExpression.Expression);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\tif ((double)pe.Value < 0)\n\t\t\t\t\t\t\tParenthesize(castExpression.Expression);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\tif ((decimal)pe.Value < 0)\n\t\t\t\t\t\t\tParenthesize(castExpression.Expression);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbase.VisitCastExpression(castExpression);\n\t\t}\n\n\t\tstatic bool TypeCanBeMisinterpretedAsExpression(AstType type)\n\t\t{\n\t\t\t// SimpleTypes can always be misinterpreted as IdentifierExpressions\n\t\t\t// MemberTypes can be misinterpreted as MemberReferenceExpressions if they don't use double colon\n\t\t\t// PrimitiveTypes or ComposedTypes can never be misinterpreted as expressions.\n\t\t\tMemberType mt = type as MemberType;\n\t\t\tif (mt != null)\n\t\t\t\treturn !mt.IsDoubleColon;\n\t\t\telse\n\t\t\t\treturn type is SimpleType;\n\t\t}\n\n\t\t// Binary Operators\n\t\tpublic override void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)\n\t\t{\n\t\t\tPrecedenceLevel precedence = GetPrecedence(binaryOperatorExpression);\n\t\t\tif (binaryOperatorExpression.Operator == BinaryOperatorType.NullCoalescing)\n\t\t\t{\n\t\t\t\tif (InsertParenthesesForReadability)\n\t\t\t\t{\n\t\t\t\t\tParenthesizeIfRequired(binaryOperatorExpression.Left, PrecedenceLevel.NullableRewrap);\n\t\t\t\t\tif (GetBinaryOperatorType(binaryOperatorExpression.Right) == BinaryOperatorType.NullCoalescing)\n\t\t\t\t\t{\n\t\t\t\t\t\tParenthesizeIfRequired(binaryOperatorExpression.Right, precedence);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tParenthesizeIfRequired(binaryOperatorExpression.Right, PrecedenceLevel.NullableRewrap);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// ?? is right-associative\n\t\t\t\t\tParenthesizeIfRequired(binaryOperatorExpression.Left, precedence + 1);\n\t\t\t\t\tParenthesizeIfRequired(binaryOperatorExpression.Right, precedence);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (InsertParenthesesForReadability && precedence < PrecedenceLevel.Equality)\n\t\t\t\t{\n\t\t\t\t\t// In readable mode, boost the priority of the left-hand side if the operator\n\t\t\t\t\t// there isn't the same as the operator on this expression.\n\t\t\t\t\tPrecedenceLevel boostTo = IsBitwise(binaryOperatorExpression.Operator) ? PrecedenceLevel.Unary : PrecedenceLevel.Equality;\n\t\t\t\t\tif (GetBinaryOperatorType(binaryOperatorExpression.Left) == binaryOperatorExpression.Operator)\n\t\t\t\t\t{\n\t\t\t\t\t\tParenthesizeIfRequired(binaryOperatorExpression.Left, precedence);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tParenthesizeIfRequired(binaryOperatorExpression.Left, boostTo);\n\t\t\t\t\t}\n\t\t\t\t\tParenthesizeIfRequired(binaryOperatorExpression.Right, boostTo);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// all other binary operators are left-associative\n\t\t\t\t\tParenthesizeIfRequired(binaryOperatorExpression.Left, precedence);\n\t\t\t\t\tParenthesizeIfRequired(binaryOperatorExpression.Right, precedence + 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbase.VisitBinaryOperatorExpression(binaryOperatorExpression);\n\t\t}\n\n\t\tstatic bool IsBitwise(BinaryOperatorType op)\n\t\t{\n\t\t\treturn op == BinaryOperatorType.BitwiseAnd\n\t\t\t\t|| op == BinaryOperatorType.BitwiseOr\n\t\t\t\t|| op == BinaryOperatorType.ExclusiveOr;\n\t\t}\n\n\t\tBinaryOperatorType? GetBinaryOperatorType(Expression expr)\n\t\t{\n\t\t\tBinaryOperatorExpression boe = expr as BinaryOperatorExpression;\n\t\t\tif (boe != null)\n\t\t\t\treturn boe.Operator;\n\t\t\telse\n\t\t\t\treturn null;\n\t\t}\n\n\t\tpublic override void VisitIsExpression(IsExpression isExpression)\n\t\t{\n\t\t\tif (InsertParenthesesForReadability)\n\t\t\t{\n\t\t\t\t// few people know the precedence of 'is', so always put parentheses in nice-looking mode.\n\t\t\t\tParenthesizeIfRequired(isExpression.Expression, PrecedenceLevel.NullableRewrap);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tParenthesizeIfRequired(isExpression.Expression, PrecedenceLevel.RelationalAndTypeTesting);\n\t\t\t}\n\t\t\tbase.VisitIsExpression(isExpression);\n\t\t}\n\n\t\tpublic override void VisitAsExpression(AsExpression asExpression)\n\t\t{\n\t\t\tif (InsertParenthesesForReadability)\n\t\t\t{\n\t\t\t\t// few people know the precedence of 'as', so always put parentheses in nice-looking mode.\n\t\t\t\tParenthesizeIfRequired(asExpression.Expression, PrecedenceLevel.NullableRewrap);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tParenthesizeIfRequired(asExpression.Expression, PrecedenceLevel.RelationalAndTypeTesting);\n\t\t\t}\n\t\t\tbase.VisitAsExpression(asExpression);\n\t\t}\n\n\t\tpublic override void VisitInterpolation(Interpolation interpolation)\n\t\t{\n\t\t\t// Need to do this first, in case the descendents parenthesize themselves.\n\t\t\tbase.VisitInterpolation(interpolation);\n\n\t\t\t// If an interpolation contains global::, we need to parenthesize the expression.\n\t\t\tif (InterpolationNeedsParenthesis(interpolation))\n\t\t\t\tParenthesize(interpolation.Expression);\n\n\t\t\tstatic bool InterpolationNeedsParenthesis(AstNode node)\n\t\t\t{\n\t\t\t\tif (node is MemberType { IsDoubleColon: true })\n\t\t\t\t\treturn true;\n\n\t\t\t\tif (node is ParenthesizedExpression)\n\t\t\t\t\treturn false;\n\t\t\t\tif (node is AnonymousMethodExpression or LambdaExpression { Body: BlockStatement })\n\t\t\t\t\treturn false;\n\t\t\t\tif (node is InvocationExpression invocation)\n\t\t\t\t\treturn InterpolationNeedsParenthesis(invocation.Target);\n\t\t\t\tif (node is CastExpression cast)\n\t\t\t\t\treturn InterpolationNeedsParenthesis(cast.Expression);\n\n\t\t\t\tforeach (var child in node.Children)\n\t\t\t\t{\n\t\t\t\t\tif (InterpolationNeedsParenthesis(child))\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Conditional operator\n\t\tpublic override void VisitConditionalExpression(ConditionalExpression conditionalExpression)\n\t\t{\n\t\t\t// Inside of string interpolation ?: always needs parentheses.\n\t\t\tif (conditionalExpression.Parent is Interpolation)\n\t\t\t{\n\t\t\t\tParenthesize(conditionalExpression);\n\t\t\t}\n\n\t\t\t// Associativity here is a bit tricky:\n\t\t\t// (a ? b : c ? d : e) == (a ? b : (c ? d : e))\n\t\t\t// (a ? b ? c : d : e) == (a ? (b ? c : d) : e)\n\t\t\t// Only ((a ? b : c) ? d : e) strictly needs the additional parentheses\n\t\t\tif (InsertParenthesesForReadability && !IsConditionalRefExpression(conditionalExpression))\n\t\t\t{\n\t\t\t\t// Precedence of ?: can be confusing; so always put parentheses in nice-looking mode.\n\t\t\t\tParenthesizeIfRequired(conditionalExpression.Condition, PrecedenceLevel.NullableRewrap);\n\t\t\t\tParenthesizeIfRequired(conditionalExpression.TrueExpression, PrecedenceLevel.NullableRewrap);\n\t\t\t\tParenthesizeIfRequired(conditionalExpression.FalseExpression, PrecedenceLevel.NullableRewrap);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tParenthesizeIfRequired(conditionalExpression.Condition, PrecedenceLevel.Conditional + 1);\n\t\t\t\tParenthesizeIfRequired(conditionalExpression.TrueExpression, PrecedenceLevel.Conditional);\n\t\t\t\tParenthesizeIfRequired(conditionalExpression.FalseExpression, PrecedenceLevel.Conditional);\n\t\t\t}\n\t\t\tbase.VisitConditionalExpression(conditionalExpression);\n\t\t}\n\n\t\tprivate bool IsConditionalRefExpression(ConditionalExpression conditionalExpression)\n\t\t{\n\t\t\treturn conditionalExpression.TrueExpression is DirectionExpression\n\t\t\t\t|| conditionalExpression.FalseExpression is DirectionExpression;\n\t\t}\n\n\t\tpublic override void VisitAssignmentExpression(AssignmentExpression assignmentExpression)\n\t\t{\n\t\t\t// Assignments in initializers need additional parentheses to disambiguate assignments\n\t\t\t// to variables and assignments to members of the initialized object.\n\t\t\t// This works without access to semantic information, because the ExpressionBuilder\n\t\t\t// uses NamedExpression for `Member = value` instead of AssignmentExpression.\n\t\t\tif (assignmentExpression.Parent is ArrayInitializerExpression\n\t\t\t\t&& assignmentExpression.Left is not IndexerExpression)\n\t\t\t{\n\t\t\t\tParenthesize(assignmentExpression);\n\t\t\t}\n\t\t\t// assignment is right-associative\n\t\t\tParenthesizeIfRequired(assignmentExpression.Left, PrecedenceLevel.Assignment + 1);\n\t\t\tHandleAssignmentRHS(assignmentExpression.Right);\n\t\t\tbase.VisitAssignmentExpression(assignmentExpression);\n\t\t}\n\n\t\tprivate void HandleAssignmentRHS(Expression right)\n\t\t{\n\t\t\tif (InsertParenthesesForReadability && !(right is DirectionExpression))\n\t\t\t{\n\t\t\t\tParenthesizeIfRequired(right, PrecedenceLevel.Conditional + 1);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tParenthesizeIfRequired(right, PrecedenceLevel.Assignment);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void VisitVariableInitializer(VariableInitializer variableInitializer)\n\t\t{\n\t\t\tif (!variableInitializer.Initializer.IsNull)\n\t\t\t\tHandleAssignmentRHS(variableInitializer.Initializer);\n\t\t\tbase.VisitVariableInitializer(variableInitializer);\n\t\t}\n\n\t\t// don't need to handle lambdas, they have lowest precedence and unambiguous associativity\n\t\tpublic override void VisitQueryExpression(QueryExpression queryExpression)\n\t\t{\n\t\t\t// Query expressions are strange beasts:\n\t\t\t// \"var a = -from b in c select d;\" is valid, so queries bind stricter than unary expressions.\n\t\t\t// However, the end of the query is greedy. So their start sort of has a high precedence,\n\t\t\t// while their end has a very low precedence. We handle this by checking whether a query is used\n\t\t\t// as left part of a binary operator, and parenthesize it if required.\n\t\t\tHandleLambdaOrQuery(queryExpression);\n\t\t\tbase.VisitQueryExpression(queryExpression);\n\t\t}\n\n\t\tpublic override void VisitLambdaExpression(LambdaExpression lambdaExpression)\n\t\t{\n\t\t\t// Lambdas are greedy in the same way as query expressions.\n\t\t\tHandleLambdaOrQuery(lambdaExpression);\n\t\t\tbase.VisitLambdaExpression(lambdaExpression);\n\t\t}\n\n\t\tvoid HandleLambdaOrQuery(Expression expr)\n\t\t{\n\t\t\tif (expr.Role == BinaryOperatorExpression.LeftRole)\n\t\t\t\tParenthesize(expr);\n\t\t\tif (expr.Parent is IsExpression || expr.Parent is AsExpression)\n\t\t\t\tParenthesize(expr);\n\t\t\tif (InsertParenthesesForReadability)\n\t\t\t{\n\t\t\t\t// when readability is desired, always parenthesize query expressions within unary or binary operators\n\t\t\t\tif (expr.Parent is UnaryOperatorExpression || expr.Parent is BinaryOperatorExpression)\n\t\t\t\t\tParenthesize(expr);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void VisitNamedExpression(NamedExpression namedExpression)\n\t\t{\n\t\t\tif (InsertParenthesesForReadability)\n\t\t\t{\n\t\t\t\tParenthesizeIfRequired(namedExpression.Expression, PrecedenceLevel.RelationalAndTypeTesting + 1);\n\t\t\t}\n\t\t\tbase.VisitNamedExpression(namedExpression);\n\t\t}\n\n\t\tpublic override void VisitSwitchExpression(SwitchExpression switchExpression)\n\t\t{\n\t\t\tParenthesizeIfRequired(switchExpression.Expression, PrecedenceLevel.Switch + 1);\n\t\t\tbase.VisitSwitchExpression(switchExpression);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertRequiredSpacesDecorator.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\n\nnamespace ICSharpCode.Decompiler.CSharp.OutputVisitor\n{\n\tclass InsertRequiredSpacesDecorator : DecoratingTokenWriter\n\t{\n\t\t/// <summary>\n\t\t/// Used to insert the minimal amount of spaces so that the lexer recognizes the tokens that were written.\n\t\t/// </summary>\n\t\tLastWritten lastWritten;\n\n\t\tenum LastWritten\n\t\t{\n\t\t\tWhitespace,\n\t\t\tOther,\n\t\t\tKeywordOrIdentifier,\n\t\t\tPlus,\n\t\t\tMinus,\n\t\t\tAmpersand,\n\t\t\tQuestionMark,\n\t\t\tDivision\n\t\t}\n\n\t\tpublic InsertRequiredSpacesDecorator(TokenWriter writer)\n\t\t\t: base(writer)\n\t\t{\n\t\t}\n\n\t\tpublic override void WriteIdentifier(Identifier identifier)\n\t\t{\n\t\t\tif (identifier.IsVerbatim || CSharpOutputVisitor.IsKeyword(identifier.Name, identifier))\n\t\t\t{\n\t\t\t\tif (lastWritten == LastWritten.KeywordOrIdentifier)\n\t\t\t\t{\n\t\t\t\t\t// this space is not strictly required, so we call Space()\n\t\t\t\t\tSpace();\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (lastWritten == LastWritten.KeywordOrIdentifier)\n\t\t\t{\n\t\t\t\t// this space is strictly required, so we directly call the formatter\n\t\t\t\tbase.Space();\n\t\t\t}\n\t\t\tbase.WriteIdentifier(identifier);\n\t\t\tlastWritten = LastWritten.KeywordOrIdentifier;\n\t\t}\n\n\t\tpublic override void WriteKeyword(Role role, string keyword)\n\t\t{\n\t\t\tif (lastWritten == LastWritten.KeywordOrIdentifier)\n\t\t\t{\n\t\t\t\tSpace();\n\t\t\t}\n\t\t\tbase.WriteKeyword(role, keyword);\n\t\t\tlastWritten = LastWritten.KeywordOrIdentifier;\n\t\t}\n\n\t\tpublic override void WriteToken(Role role, string token)\n\t\t{\n\t\t\t// Avoid that two +, - or ? tokens are combined into a ++, -- or ?? token.\n\t\t\t// Note that we don't need to handle tokens like = because there's no valid\n\t\t\t// C# program that contains the single token twice in a row.\n\t\t\t// (for +, - and &, this can happen with unary operators;\n\t\t\t// for ?, this can happen in \"a is int? ? b : c\" or \"a as int? ?? 0\";\n\t\t\t// and for /, this can happen with \"1/ *ptr\" or \"1/ //comment\".)\n\t\t\tif (lastWritten == LastWritten.Plus && token[0] == '+' ||\n\t\t\t\tlastWritten == LastWritten.Minus && token[0] == '-' ||\n\t\t\t\tlastWritten == LastWritten.Ampersand && token[0] == '&' ||\n\t\t\t\tlastWritten == LastWritten.QuestionMark && token[0] == '?' ||\n\t\t\t\tlastWritten == LastWritten.Division && token[0] == '*')\n\t\t\t{\n\t\t\t\tbase.Space();\n\t\t\t}\n\t\t\tbase.WriteToken(role, token);\n\t\t\tif (token == \"+\")\n\t\t\t{\n\t\t\t\tlastWritten = LastWritten.Plus;\n\t\t\t}\n\t\t\telse if (token == \"-\")\n\t\t\t{\n\t\t\t\tlastWritten = LastWritten.Minus;\n\t\t\t}\n\t\t\telse if (token == \"&\")\n\t\t\t{\n\t\t\t\tlastWritten = LastWritten.Ampersand;\n\t\t\t}\n\t\t\telse if (token == \"?\")\n\t\t\t{\n\t\t\t\tlastWritten = LastWritten.QuestionMark;\n\t\t\t}\n\t\t\telse if (token == \"/\")\n\t\t\t{\n\t\t\t\tlastWritten = LastWritten.Division;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tlastWritten = LastWritten.Other;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void Space()\n\t\t{\n\t\t\tbase.Space();\n\t\t\tlastWritten = LastWritten.Whitespace;\n\t\t}\n\n\t\tpublic override void NewLine()\n\t\t{\n\t\t\tbase.NewLine();\n\t\t\tlastWritten = LastWritten.Whitespace;\n\t\t}\n\n\t\tpublic override void WriteComment(CommentType commentType, string content)\n\t\t{\n\t\t\tif (lastWritten == LastWritten.Division)\n\t\t\t{\n\t\t\t\t// When there's a comment starting after a division operator\n\t\t\t\t// \"1.0 / /*comment*/a\", then we need to insert a space in front of the comment.\n\t\t\t\tbase.Space();\n\t\t\t}\n\t\t\tbase.WriteComment(commentType, content);\n\t\t\tlastWritten = LastWritten.Whitespace;\n\t\t}\n\n\t\tpublic override void WritePreProcessorDirective(PreProcessorDirectiveType type, string argument)\n\t\t{\n\t\t\tbase.WritePreProcessorDirective(type, argument);\n\t\t\tlastWritten = LastWritten.Whitespace;\n\t\t}\n\n\t\tpublic override void WritePrimitiveValue(object value, LiteralFormat format = LiteralFormat.None)\n\t\t{\n\t\t\tif (lastWritten == LastWritten.KeywordOrIdentifier)\n\t\t\t{\n\t\t\t\tSpace();\n\t\t\t}\n\t\t\tbase.WritePrimitiveValue(value, format);\n\t\t\tif (value == null || value is bool)\n\t\t\t\treturn;\n\t\t\tif (value is string)\n\t\t\t{\n\t\t\t\tif (format == LiteralFormat.VerbatimStringLiteral)\n\t\t\t\t\tlastWritten = LastWritten.KeywordOrIdentifier;\n\t\t\t\telse\n\t\t\t\t\tlastWritten = LastWritten.Other;\n\t\t\t}\n\t\t\telse if (value is char)\n\t\t\t{\n\t\t\t\tlastWritten = LastWritten.Other;\n\t\t\t}\n\t\t\telse if (value is decimal)\n\t\t\t{\n\t\t\t\tlastWritten = LastWritten.Other;\n\t\t\t}\n\t\t\telse if (value is float)\n\t\t\t{\n\t\t\t\tfloat f = (float)value;\n\t\t\t\tif (float.IsInfinity(f) || float.IsNaN(f))\n\t\t\t\t\treturn;\n\t\t\t\tlastWritten = LastWritten.Other;\n\t\t\t}\n\t\t\telse if (value is double)\n\t\t\t{\n\t\t\t\tdouble f = (double)value;\n\t\t\t\tif (double.IsInfinity(f) || double.IsNaN(f))\n\t\t\t\t\treturn;\n\t\t\t\t// needs space if identifier follows number;\n\t\t\t\t// this avoids mistaking the following identifier as type suffix\n\t\t\t\tlastWritten = LastWritten.KeywordOrIdentifier;\n\t\t\t}\n\t\t\telse if (value is IFormattable)\n\t\t\t{\n\t\t\t\t// needs space if identifier follows number;\n\t\t\t\t// this avoids mistaking the following identifier as type suffix\n\t\t\t\tlastWritten = LastWritten.KeywordOrIdentifier;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tlastWritten = LastWritten.Other;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void WritePrimitiveType(string type)\n\t\t{\n\t\t\tif (lastWritten == LastWritten.KeywordOrIdentifier)\n\t\t\t{\n\t\t\t\tSpace();\n\t\t\t}\n\t\t\tbase.WritePrimitiveType(type);\n\t\t\tif (type == \"new\")\n\t\t\t{\n\t\t\t\tlastWritten = LastWritten.Other;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tlastWritten = LastWritten.KeywordOrIdentifier;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/OutputVisitor/InsertSpecialsDecorator.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\n\nnamespace ICSharpCode.Decompiler.CSharp.OutputVisitor\n{\n\tclass InsertSpecialsDecorator : DecoratingTokenWriter\n\t{\n\t\treadonly Stack<AstNode> positionStack = new Stack<AstNode>();\n\t\tint visitorWroteNewLine = 0;\n\n\t\tpublic InsertSpecialsDecorator(TokenWriter writer) : base(writer)\n\t\t{\n\t\t}\n\n\t\tpublic override void StartNode(AstNode node)\n\t\t{\n\t\t\tif (positionStack.Count > 0)\n\t\t\t{\n\t\t\t\tWriteSpecialsUpToNode(node);\n\t\t\t}\n\t\t\tpositionStack.Push(node.FirstChild);\n\t\t\tbase.StartNode(node);\n\t\t}\n\n\t\tpublic override void EndNode(AstNode node)\n\t\t{\n\t\t\tbase.EndNode(node);\n\t\t\tAstNode pos = positionStack.Pop();\n\t\t\tDebug.Assert(pos == null || pos.Parent == node);\n\t\t\tWriteSpecials(pos, null);\n\t\t}\n\n\t\tpublic override void WriteKeyword(Role role, string keyword)\n\t\t{\n\t\t\tif (role != null)\n\t\t\t{\n\t\t\t\tWriteSpecialsUpToRole(role);\n\t\t\t}\n\t\t\tbase.WriteKeyword(role, keyword);\n\t\t}\n\n\t\tpublic override void WriteIdentifier(Identifier identifier)\n\t\t{\n\t\t\tWriteSpecialsUpToRole(identifier.Role ?? Roles.Identifier);\n\t\t\tbase.WriteIdentifier(identifier);\n\t\t}\n\n\t\tpublic override void WriteToken(Role role, string token)\n\t\t{\n\t\t\tWriteSpecialsUpToRole(role);\n\t\t\tbase.WriteToken(role, token);\n\t\t}\n\n\t\tpublic override void NewLine()\n\t\t{\n\t\t\tif (visitorWroteNewLine >= 0)\n\t\t\t\tbase.NewLine();\n\t\t\tvisitorWroteNewLine++;\n\t\t}\n\n\t\t#region WriteSpecials\n\t\t/// <summary>\n\t\t/// Writes all specials from start to end (exclusive). Does not touch the positionStack.\n\t\t/// </summary>\n\t\tvoid WriteSpecials(AstNode start, AstNode end)\n\t\t{\n\t\t\tfor (AstNode pos = start; pos != end; pos = pos.NextSibling)\n\t\t\t{\n\t\t\t\tif (pos.Role == Roles.Comment)\n\t\t\t\t{\n\t\t\t\t\tvar node = (Comment)pos;\n\t\t\t\t\tbase.StartNode(node);\n\t\t\t\t\tbase.WriteComment(node.CommentType, node.Content);\n\t\t\t\t\tbase.EndNode(node);\n\t\t\t\t}\n\t\t\t\t// see CSharpOutputVisitor.VisitNewLine()\n\t\t\t\t//\t\t\t\tif (pos.Role == Roles.NewLine) {\n\t\t\t\t//\t\t\t\t\tif (visitorWroteNewLine <= 0)\n\t\t\t\t//\t\t\t\t\t\tbase.NewLine();\n\t\t\t\t//\t\t\t\t\tvisitorWroteNewLine--;\n\t\t\t\t//\t\t\t\t}\n\t\t\t\tif (pos.Role == Roles.PreProcessorDirective)\n\t\t\t\t{\n\t\t\t\t\tvar node = (PreProcessorDirective)pos;\n\t\t\t\t\tbase.StartNode(node);\n\t\t\t\t\tbase.WritePreProcessorDirective(node.Type, node.Argument);\n\t\t\t\t\tbase.EndNode(node);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Writes all specials between the current position (in the positionStack) and the next\n\t\t/// node with the specified role. Advances the current position.\n\t\t/// </summary>\n\t\tvoid WriteSpecialsUpToRole(Role role)\n\t\t{\n\t\t\tWriteSpecialsUpToRole(role, null);\n\t\t}\n\n\t\tvoid WriteSpecialsUpToRole(Role role, AstNode nextNode)\n\t\t{\n\t\t\tif (positionStack.Count == 0)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Look for the role between the current position and the nextNode.\n\t\t\tfor (AstNode pos = positionStack.Peek(); pos != null && pos != nextNode; pos = pos.NextSibling)\n\t\t\t{\n\t\t\t\tif (pos.Role == role)\n\t\t\t\t{\n\t\t\t\t\tWriteSpecials(positionStack.Pop(), pos);\n\t\t\t\t\t// Push the next sibling because the node matching the role is not a special,\n\t\t\t\t\t// and should be considered to be already handled.\n\t\t\t\t\tpositionStack.Push(pos.NextSibling);\n\t\t\t\t\t// This is necessary for OptionalComma() to work correctly.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Writes all specials between the current position (in the positionStack) and the specified node.\n\t\t/// Advances the current position.\n\t\t/// </summary>\n\t\tvoid WriteSpecialsUpToNode(AstNode node)\n\t\t{\n\t\t\tif (positionStack.Count == 0)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (AstNode pos = positionStack.Peek(); pos != null; pos = pos.NextSibling)\n\t\t\t{\n\t\t\t\tif (pos == node)\n\t\t\t\t{\n\t\t\t\t\tWriteSpecials(positionStack.Pop(), pos);\n\t\t\t\t\t// Push the next sibling because the node itself is not a special,\n\t\t\t\t\t// and should be considered to be already handled.\n\t\t\t\t\tpositionStack.Push(pos.NextSibling);\n\t\t\t\t\t// This is necessary for OptionalComma() to work correctly.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/OutputVisitor/TextWriterTokenWriter.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Globalization;\nusing System.IO;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\n\nnamespace ICSharpCode.Decompiler.CSharp.OutputVisitor\n{\n\t/// <summary>\n\t/// Writes C# code into a TextWriter.\n\t/// </summary>\n\tpublic class TextWriterTokenWriter : TokenWriter, ILocatable\n\t{\n\t\treadonly TextWriter textWriter;\n\t\tbool needsIndent = true;\n\t\tbool isAtStartOfLine = true;\n\t\tint line, column;\n\n\t\tpublic int Indentation { get; set; }\n\n\t\tpublic TextLocation Location {\n\t\t\tget { return new TextLocation(line, column + (needsIndent ? Indentation * IndentationString.Length : 0)); }\n\t\t}\n\n\t\tpublic string IndentationString { get; set; }\n\n\t\tpublic int Length { get; private set; }\n\n\t\tpublic TextWriterTokenWriter(TextWriter textWriter)\n\t\t{\n\t\t\tif (textWriter == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(textWriter));\n\t\t\tthis.textWriter = textWriter;\n\t\t\tthis.IndentationString = \"\\t\";\n\t\t\tthis.line = 1;\n\t\t\tthis.column = 1;\n\t\t}\n\n\t\tpublic override void WriteIdentifier(Identifier identifier)\n\t\t{\n\t\t\tWriteIndentation();\n\t\t\tif (identifier.IsVerbatim || CSharpOutputVisitor.IsKeyword(identifier.Name, identifier))\n\t\t\t{\n\t\t\t\ttextWriter.Write('@');\n\t\t\t\tcolumn++;\n\t\t\t\tLength++;\n\t\t\t}\n\t\t\tstring name = EscapeIdentifier(identifier.Name);\n\t\t\ttextWriter.Write(name);\n\t\t\tcolumn += name.Length;\n\t\t\tLength += name.Length;\n\t\t\tisAtStartOfLine = false;\n\t\t}\n\n\t\tpublic override void WriteKeyword(Role role, string keyword)\n\t\t{\n\t\t\tWriteIndentation();\n\t\t\tcolumn += keyword.Length;\n\t\t\tLength += keyword.Length;\n\t\t\ttextWriter.Write(keyword);\n\t\t\tisAtStartOfLine = false;\n\t\t}\n\n\t\tpublic override void WriteToken(Role role, string token)\n\t\t{\n\t\t\tWriteIndentation();\n\t\t\tcolumn += token.Length;\n\t\t\tLength += token.Length;\n\t\t\ttextWriter.Write(token);\n\t\t\tisAtStartOfLine = false;\n\t\t}\n\n\t\tpublic override void Space()\n\t\t{\n\t\t\tWriteIndentation();\n\t\t\tcolumn++;\n\t\t\tLength++;\n\t\t\ttextWriter.Write(' ');\n\t\t}\n\n\t\tprotected void WriteIndentation()\n\t\t{\n\t\t\tif (needsIndent)\n\t\t\t{\n\t\t\t\tneedsIndent = false;\n\t\t\t\tfor (int i = 0; i < Indentation; i++)\n\t\t\t\t{\n\t\t\t\t\ttextWriter.Write(this.IndentationString);\n\t\t\t\t}\n\t\t\t\tcolumn += Indentation * IndentationString.Length;\n\t\t\t\tLength += Indentation * IndentationString.Length;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void NewLine()\n\t\t{\n\t\t\ttextWriter.WriteLine();\n\t\t\tcolumn = 1;\n\t\t\tline++;\n\t\t\tLength += textWriter.NewLine.Length;\n\t\t\tneedsIndent = true;\n\t\t\tisAtStartOfLine = true;\n\t\t}\n\n\t\tpublic override void Indent()\n\t\t{\n\t\t\tIndentation++;\n\t\t}\n\n\t\tpublic override void Unindent()\n\t\t{\n\t\t\tIndentation--;\n\t\t}\n\n\t\tpublic override void WriteComment(CommentType commentType, string content)\n\t\t{\n\t\t\tWriteIndentation();\n\t\t\tswitch (commentType)\n\t\t\t{\n\t\t\t\tcase CommentType.SingleLine:\n\t\t\t\t\ttextWriter.Write(\"//\");\n\t\t\t\t\ttextWriter.WriteLine(content);\n\t\t\t\t\tLength += 2 + content.Length + textWriter.NewLine.Length;\n\t\t\t\t\tcolumn = 1;\n\t\t\t\t\tline++;\n\t\t\t\t\tneedsIndent = true;\n\t\t\t\t\tisAtStartOfLine = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase CommentType.MultiLine:\n\t\t\t\t\ttextWriter.Write(\"/*\");\n\t\t\t\t\ttextWriter.Write(content);\n\t\t\t\t\ttextWriter.Write(\"*/\");\n\t\t\t\t\tLength += 4 + content.Length;\n\t\t\t\t\tcolumn += 2;\n\t\t\t\t\tUpdateEndLocation(content, ref line, ref column);\n\t\t\t\t\tcolumn += 2;\n\t\t\t\t\tisAtStartOfLine = false;\n\t\t\t\t\tbreak;\n\t\t\t\tcase CommentType.Documentation:\n\t\t\t\t\ttextWriter.Write(\"///\");\n\t\t\t\t\ttextWriter.WriteLine(content);\n\t\t\t\t\tLength += 3 + content.Length + textWriter.NewLine.Length;\n\t\t\t\t\tcolumn = 1;\n\t\t\t\t\tline++;\n\t\t\t\t\tneedsIndent = true;\n\t\t\t\t\tisAtStartOfLine = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase CommentType.MultiLineDocumentation:\n\t\t\t\t\ttextWriter.Write(\"/**\");\n\t\t\t\t\ttextWriter.Write(content);\n\t\t\t\t\ttextWriter.Write(\"*/\");\n\t\t\t\t\tLength += 5 + content.Length;\n\t\t\t\t\tcolumn += 3;\n\t\t\t\t\tUpdateEndLocation(content, ref line, ref column);\n\t\t\t\t\tcolumn += 2;\n\t\t\t\t\tisAtStartOfLine = false;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\ttextWriter.Write(content);\n\t\t\t\t\tcolumn += content.Length;\n\t\t\t\t\tLength += content.Length;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tstatic void UpdateEndLocation(string content, ref int line, ref int column)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(content))\n\t\t\t\treturn;\n\t\t\tfor (int i = 0; i < content.Length; i++)\n\t\t\t{\n\t\t\t\tchar ch = content[i];\n\t\t\t\tswitch (ch)\n\t\t\t\t{\n\t\t\t\t\tcase '\\r':\n\t\t\t\t\t\tif (i + 1 < content.Length && content[i + 1] == '\\n')\n\t\t\t\t\t\t\ti++;\n\t\t\t\t\t\tgoto case '\\n';\n\t\t\t\t\tcase '\\n':\n\t\t\t\t\t\tline++;\n\t\t\t\t\t\tcolumn = 0;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcolumn++;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void WritePreProcessorDirective(PreProcessorDirectiveType type, string argument)\n\t\t{\n\t\t\t// pre-processor directive must start on its own line\n\t\t\tif (!isAtStartOfLine)\n\t\t\t\tNewLine();\n\t\t\tWriteIndentation();\n\t\t\ttextWriter.Write('#');\n\t\t\tstring directive = type.ToString().ToLowerInvariant();\n\t\t\ttextWriter.Write(directive);\n\t\t\tcolumn += 1 + directive.Length;\n\t\t\tLength += 1 + directive.Length;\n\t\t\tif (!string.IsNullOrEmpty(argument))\n\t\t\t{\n\t\t\t\ttextWriter.Write(' ');\n\t\t\t\ttextWriter.Write(argument);\n\t\t\t\tcolumn += 1 + argument.Length;\n\t\t\t\tLength += 1 + argument.Length;\n\t\t\t}\n\t\t\tNewLine();\n\t\t}\n\n\t\tpublic static string PrintPrimitiveValue(object value)\n\t\t{\n\t\t\tTextWriter writer = new StringWriter();\n\t\t\tTextWriterTokenWriter tokenWriter = new TextWriterTokenWriter(writer);\n\t\t\ttokenWriter.WritePrimitiveValue(value);\n\t\t\treturn writer.ToString();\n\t\t}\n\n\t\tpublic override void WritePrimitiveValue(object value, LiteralFormat format = LiteralFormat.None)\n\t\t{\n\t\t\tif (value == null)\n\t\t\t{\n\t\t\t\t// usually NullReferenceExpression should be used for this, but we'll handle it anyways\n\t\t\t\ttextWriter.Write(\"null\");\n\t\t\t\tcolumn += 4;\n\t\t\t\tLength += 4;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (value is bool)\n\t\t\t{\n\t\t\t\tif ((bool)value)\n\t\t\t\t{\n\t\t\t\t\ttextWriter.Write(\"true\");\n\t\t\t\t\tcolumn += 4;\n\t\t\t\t\tLength += 4;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ttextWriter.Write(\"false\");\n\t\t\t\t\tcolumn += 5;\n\t\t\t\t\tLength += 5;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (value is string)\n\t\t\t{\n\t\t\t\tstring tmp = ConvertString(value.ToString());\n\t\t\t\tcolumn += tmp.Length + 2;\n\t\t\t\tLength += tmp.Length + 2;\n\t\t\t\ttextWriter.Write('\"');\n\t\t\t\ttextWriter.Write(tmp);\n\t\t\t\ttextWriter.Write('\"');\n\t\t\t\tif (format == LiteralFormat.Utf8Literal)\n\t\t\t\t{\n\t\t\t\t\ttextWriter.Write(\"u8\");\n\t\t\t\t\tcolumn += 2;\n\t\t\t\t\tLength += 2;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (value is char)\n\t\t\t{\n\t\t\t\tstring tmp = ConvertCharLiteral((char)value);\n\t\t\t\tcolumn += tmp.Length + 2;\n\t\t\t\tLength += tmp.Length + 2;\n\t\t\t\ttextWriter.Write('\\'');\n\t\t\t\ttextWriter.Write(tmp);\n\t\t\t\ttextWriter.Write('\\'');\n\t\t\t}\n\t\t\telse if (value is decimal)\n\t\t\t{\n\t\t\t\tstring str = ((decimal)value).ToString(NumberFormatInfo.InvariantInfo) + \"m\";\n\t\t\t\tcolumn += str.Length;\n\t\t\t\tLength += str.Length;\n\t\t\t\ttextWriter.Write(str);\n\t\t\t}\n\t\t\telse if (value is float)\n\t\t\t{\n\t\t\t\tfloat f = (float)value;\n\t\t\t\tif (float.IsInfinity(f) || float.IsNaN(f))\n\t\t\t\t{\n\t\t\t\t\t// Strictly speaking, these aren't PrimitiveExpressions;\n\t\t\t\t\t// but we still support writing these to make life easier for code generators.\n\t\t\t\t\ttextWriter.Write(\"float\");\n\t\t\t\t\tcolumn += 5;\n\t\t\t\t\tLength += 5;\n\t\t\t\t\tWriteToken(Roles.Dot, \".\");\n\t\t\t\t\tif (float.IsPositiveInfinity(f))\n\t\t\t\t\t{\n\t\t\t\t\t\ttextWriter.Write(\"PositiveInfinity\");\n\t\t\t\t\t\tcolumn += \"PositiveInfinity\".Length;\n\t\t\t\t\t\tLength += \"PositiveInfinity\".Length;\n\t\t\t\t\t}\n\t\t\t\t\telse if (float.IsNegativeInfinity(f))\n\t\t\t\t\t{\n\t\t\t\t\t\ttextWriter.Write(\"NegativeInfinity\");\n\t\t\t\t\t\tcolumn += \"NegativeInfinity\".Length;\n\t\t\t\t\t\tLength += \"NegativeInfinity\".Length;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\ttextWriter.Write(\"NaN\");\n\t\t\t\t\t\tcolumn += 3;\n\t\t\t\t\t\tLength += 3;\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tvar str = f.ToString(\"R\", NumberFormatInfo.InvariantInfo) + \"f\";\n\t\t\t\tif (f == 0 && 1 / f == float.NegativeInfinity && str[0] != '-')\n\t\t\t\t{\n\t\t\t\t\t// negative zero is a special case\n\t\t\t\t\t// (again, not a primitive expression, but it's better to handle\n\t\t\t\t\t// the special case here than to do it in all code generators)\n\t\t\t\t\tstr = '-' + str;\n\t\t\t\t}\n\t\t\t\tcolumn += str.Length;\n\t\t\t\tLength += str.Length;\n\t\t\t\ttextWriter.Write(str);\n\t\t\t}\n\t\t\telse if (value is double)\n\t\t\t{\n\t\t\t\tdouble f = (double)value;\n\t\t\t\tif (double.IsInfinity(f) || double.IsNaN(f))\n\t\t\t\t{\n\t\t\t\t\t// Strictly speaking, these aren't PrimitiveExpressions;\n\t\t\t\t\t// but we still support writing these to make life easier for code generators.\n\t\t\t\t\ttextWriter.Write(\"double\");\n\t\t\t\t\tcolumn += 6;\n\t\t\t\t\tLength += 6;\n\t\t\t\t\tWriteToken(Roles.Dot, \".\");\n\t\t\t\t\tif (double.IsPositiveInfinity(f))\n\t\t\t\t\t{\n\t\t\t\t\t\ttextWriter.Write(\"PositiveInfinity\");\n\t\t\t\t\t\tcolumn += \"PositiveInfinity\".Length;\n\t\t\t\t\t\tLength += \"PositiveInfinity\".Length;\n\t\t\t\t\t}\n\t\t\t\t\telse if (double.IsNegativeInfinity(f))\n\t\t\t\t\t{\n\t\t\t\t\t\ttextWriter.Write(\"NegativeInfinity\");\n\t\t\t\t\t\tcolumn += \"NegativeInfinity\".Length;\n\t\t\t\t\t\tLength += \"NegativeInfinity\".Length;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\ttextWriter.Write(\"NaN\");\n\t\t\t\t\t\tcolumn += 3;\n\t\t\t\t\t\tLength += 3;\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tstring number = f.ToString(\"R\", NumberFormatInfo.InvariantInfo);\n\t\t\t\tif (f == 0 && 1 / f == double.NegativeInfinity && number[0] != '-')\n\t\t\t\t{\n\t\t\t\t\t// negative zero is a special case\n\t\t\t\t\t// (again, not a primitive expression, but it's better to handle\n\t\t\t\t\t// the special case here than to do it in all code generators)\n\t\t\t\t\tnumber = '-' + number;\n\t\t\t\t}\n\t\t\t\tif (number.IndexOf('.') < 0 && number.IndexOf('E') < 0)\n\t\t\t\t{\n\t\t\t\t\tnumber += \".0\";\n\t\t\t\t}\n\t\t\t\ttextWriter.Write(number);\n\t\t\t\tcolumn += number.Length;\n\t\t\t\tLength += number.Length;\n\t\t\t}\n\t\t\telse if (value is IFormattable)\n\t\t\t{\n\t\t\t\tStringBuilder b = new StringBuilder();\n\t\t\t\tif (format == LiteralFormat.HexadecimalNumber)\n\t\t\t\t{\n\t\t\t\t\tb.Append(\"0x\");\n\t\t\t\t\tb.Append(((IFormattable)value).ToString(\"X\", NumberFormatInfo.InvariantInfo));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tb.Append(((IFormattable)value).ToString(null, NumberFormatInfo.InvariantInfo));\n\t\t\t\t}\n\t\t\t\tif (value is uint || value is ulong)\n\t\t\t\t{\n\t\t\t\t\tb.Append(\"u\");\n\t\t\t\t}\n\t\t\t\tif (value is long || value is ulong)\n\t\t\t\t{\n\t\t\t\t\tb.Append(\"L\");\n\t\t\t\t}\n\t\t\t\ttextWriter.Write(b.ToString());\n\t\t\t\tcolumn += b.Length;\n\t\t\t\tLength += b.Length;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttextWriter.Write(value.ToString());\n\t\t\t\tint length = value.ToString().Length;\n\t\t\t\tcolumn += length;\n\t\t\t\tLength += length;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void WriteInterpolatedText(string text)\n\t\t{\n\t\t\ttextWriter.Write(ConvertString(text));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the escape sequence for the specified character within a char literal.\n\t\t/// Does not include the single quotes surrounding the char literal.\n\t\t/// </summary>\n\t\tpublic static string ConvertCharLiteral(char ch)\n\t\t{\n\t\t\tif (ch == '\\'')\n\t\t\t{\n\t\t\t\treturn \"\\\\'\";\n\t\t\t}\n\t\t\treturn ConvertChar(ch) ?? ch.ToString();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the escape sequence for the specified character.\n\t\t/// </summary>\n\t\t/// <remarks>This method does not convert ' or \".</remarks>\n\t\tstatic string ConvertChar(char ch)\n\t\t{\n\t\t\tswitch (ch)\n\t\t\t{\n\t\t\t\tcase '\\\\':\n\t\t\t\t\treturn \"\\\\\\\\\";\n\t\t\t\tcase '\\0':\n\t\t\t\t\treturn \"\\\\0\";\n\t\t\t\tcase '\\a':\n\t\t\t\t\treturn \"\\\\a\";\n\t\t\t\tcase '\\b':\n\t\t\t\t\treturn \"\\\\b\";\n\t\t\t\tcase '\\f':\n\t\t\t\t\treturn \"\\\\f\";\n\t\t\t\tcase '\\n':\n\t\t\t\t\treturn \"\\\\n\";\n\t\t\t\tcase '\\r':\n\t\t\t\t\treturn \"\\\\r\";\n\t\t\t\tcase '\\t':\n\t\t\t\t\treturn \"\\\\t\";\n\t\t\t\tcase '\\v':\n\t\t\t\t\treturn \"\\\\v\";\n\t\t\t\tcase ' ':\n\t\t\t\tcase '_':\n\t\t\t\tcase '`':\n\t\t\t\tcase '^':\n\t\t\t\t\t// ASCII characters we allow directly in the output even though we don't use\n\t\t\t\t\t// other Unicode characters of the same category.\n\t\t\t\t\treturn null;\n\t\t\t\tcase '\\ufffd':\n\t\t\t\t\treturn \"\\\\u\" + ((int)ch).ToString(\"x4\");\n\t\t\t\tdefault:\n\t\t\t\t\tswitch (char.GetUnicodeCategory(ch))\n\t\t\t\t\t{\n\t\t\t\t\t\tcase UnicodeCategory.NonSpacingMark:\n\t\t\t\t\t\tcase UnicodeCategory.SpacingCombiningMark:\n\t\t\t\t\t\tcase UnicodeCategory.EnclosingMark:\n\t\t\t\t\t\tcase UnicodeCategory.LineSeparator:\n\t\t\t\t\t\tcase UnicodeCategory.ParagraphSeparator:\n\t\t\t\t\t\tcase UnicodeCategory.Control:\n\t\t\t\t\t\tcase UnicodeCategory.Format:\n\t\t\t\t\t\tcase UnicodeCategory.Surrogate:\n\t\t\t\t\t\tcase UnicodeCategory.PrivateUse:\n\t\t\t\t\t\tcase UnicodeCategory.ConnectorPunctuation:\n\t\t\t\t\t\tcase UnicodeCategory.ModifierSymbol:\n\t\t\t\t\t\tcase UnicodeCategory.OtherNotAssigned:\n\t\t\t\t\t\tcase UnicodeCategory.SpaceSeparator:\n\t\t\t\t\t\t\treturn \"\\\\u\" + ((int)ch).ToString(\"x4\");\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts special characters to escape sequences within the given string.\n\t\t/// </summary>\n\t\tpublic static string ConvertString(string str)\n\t\t{\n\t\t\tStringBuilder sb = new StringBuilder();\n\t\t\tforeach (char ch in str)\n\t\t\t{\n\t\t\t\tstring s = ch == '\"' ? \"\\\\\\\"\" : ConvertChar(ch);\n\t\t\t\tif (s != null)\n\t\t\t\t\tsb.Append(s);\n\t\t\t\telse\n\t\t\t\t\tsb.Append(ch);\n\t\t\t}\n\t\t\treturn sb.ToString();\n\t\t}\n\n\t\tpublic static string EscapeIdentifier(string identifier)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(identifier))\n\t\t\t\treturn identifier;\n\t\t\tStringBuilder sb = new StringBuilder();\n\t\t\tfor (int i = 0; i < identifier.Length; i++)\n\t\t\t{\n\t\t\t\tif (IsPrintableIdentifierChar(identifier, i))\n\t\t\t\t{\n\t\t\t\t\tif (char.IsSurrogatePair(identifier, i))\n\t\t\t\t\t{\n\t\t\t\t\t\tsb.Append(identifier.Substring(i, 2));\n\t\t\t\t\t\ti++;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tsb.Append(identifier[i]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (char.IsSurrogatePair(identifier, i))\n\t\t\t\t\t{\n\t\t\t\t\t\tsb.AppendFormat(\"\\\\U{0:x8}\", char.ConvertToUtf32(identifier, i));\n\t\t\t\t\t\ti++;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tsb.AppendFormat(\"\\\\u{0:x4}\", (int)identifier[i]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn sb.ToString();\n\t\t}\n\n\t\tpublic static bool ContainsNonPrintableIdentifierChar(string identifier)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(identifier))\n\t\t\t\treturn false;\n\n\t\t\tfor (int i = 0; i < identifier.Length; i++)\n\t\t\t{\n\t\t\t\tif (char.IsWhiteSpace(identifier[i]))\n\t\t\t\t\treturn true;\n\t\t\t\tif (!IsPrintableIdentifierChar(identifier, i))\n\t\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tstatic bool IsPrintableIdentifierChar(string identifier, int index)\n\t\t{\n\t\t\tswitch (identifier[index])\n\t\t\t{\n\t\t\t\tcase '\\\\':\n\t\t\t\t\treturn false;\n\t\t\t\tcase ' ':\n\t\t\t\tcase '_':\n\t\t\t\tcase '`':\n\t\t\t\tcase '^':\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\tswitch (char.GetUnicodeCategory(identifier, index))\n\t\t\t{\n\t\t\t\tcase UnicodeCategory.NonSpacingMark:\n\t\t\t\tcase UnicodeCategory.SpacingCombiningMark:\n\t\t\t\tcase UnicodeCategory.EnclosingMark:\n\t\t\t\tcase UnicodeCategory.LineSeparator:\n\t\t\t\tcase UnicodeCategory.ParagraphSeparator:\n\t\t\t\tcase UnicodeCategory.Control:\n\t\t\t\tcase UnicodeCategory.Format:\n\t\t\t\tcase UnicodeCategory.Surrogate:\n\t\t\t\tcase UnicodeCategory.PrivateUse:\n\t\t\t\tcase UnicodeCategory.ConnectorPunctuation:\n\t\t\t\tcase UnicodeCategory.ModifierSymbol:\n\t\t\t\tcase UnicodeCategory.OtherNotAssigned:\n\t\t\t\tcase UnicodeCategory.SpaceSeparator:\n\t\t\t\t\treturn false;\n\t\t\t\tdefault:\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void WritePrimitiveType(string type)\n\t\t{\n\t\t\ttextWriter.Write(type);\n\t\t\tcolumn += type.Length;\n\t\t\tLength += type.Length;\n\t\t\tif (type == \"new\")\n\t\t\t{\n\t\t\t\ttextWriter.Write(\"()\");\n\t\t\t\tcolumn += 2;\n\t\t\t\tLength += 2;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void StartNode(AstNode node)\n\t\t{\n\t\t\t// Write out the indentation, so that overrides of this method\n\t\t\t// can rely use the current output length to identify the position of the node\n\t\t\t// in the output.\n\t\t\tWriteIndentation();\n\t\t}\n\n\t\tpublic override void EndNode(AstNode node)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/ProjectDecompiler/IProjectFileWriter.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.IO;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler\n{\n\t/// <summary>\n\t/// An interface for a service that creates and writes a project file structure\n\t/// for a specific module being decompiled.\n\t/// </summary>\n\tpublic interface IProjectFileWriter\n\t{\n\t\t/// <summary>\n\t\t/// Writes the content of a new project file for the specified <paramref name=\"module\"/> being decompiled.\n\t\t/// </summary>\n\t\t/// <param name=\"target\">The target to write to.</param>\n\t\t/// <param name=\"project\">The information about the project being created.</param>\n\t\t/// <param name=\"files\">A collection of source files to be included into the project.</param>\n\t\t/// <param name=\"module\">The module being decompiled.</param>\n\t\tvoid Write(TextWriter target, IProjectInfoProvider project, IEnumerable<ProjectItemInfo> files, MetadataFile module);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/ProjectDecompiler/IProjectInfoProvider.cs",
    "content": "// Copyright (c) 2020 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler\n{\n\t/// <summary>\n\t/// An interface that provides common information for a project being decompiled to.\n\t/// </summary>\n\tpublic interface IProjectInfoProvider\n\t{\n\t\t/// <summary>\n\t\t/// Gets the assembly resolver active for the project.\n\t\t/// </summary>\n\t\tIAssemblyResolver AssemblyResolver { get; }\n\n\t\tAssemblyReferenceClassifier AssemblyReferenceClassifier { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the C# language version of the project.\n\t\t/// </summary>\n\t\tLanguageVersion LanguageVersion { get; }\n\n\t\t/// <summary>\n\t\t/// Check for overflow and underflow in operators.\n\t\t/// </summary>\n\t\tbool CheckForOverflowUnderflow { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the unique ID of the project.\n\t\t/// </summary>\n\t\tGuid ProjectGuid { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the target directory of the project\n\t\t/// </summary>\n\t\tstring TargetDirectory { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the name of the key file being used for strong name signing. Can be null if no file is available.\n\t\t/// </summary>\n\t\tstring StrongNameKeyFile { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterDefault.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection.PortableExecutable;\nusing System.Xml;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Solution;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler\n{\n\t/// <summary>\n\t/// A <see cref=\"IProjectFileWriter\"/> implementation that creates the projects in the default format.\n\t/// </summary>\n\tsealed class ProjectFileWriterDefault : IProjectFileWriter\n\t{\n\t\t/// <summary>\n\t\t/// Creates a new instance of the <see cref=\"ProjectFileWriterDefault\"/> class.\n\t\t/// </summary>\n\t\t/// <returns>A new instance of the <see cref=\"ProjectFileWriterDefault\"/> class.</returns>\n\t\tpublic static IProjectFileWriter Create() => new ProjectFileWriterDefault();\n\n\t\t/// <inheritdoc />\n\t\tpublic void Write(\n\t\t\tTextWriter target,\n\t\t\tIProjectInfoProvider project,\n\t\t\tIEnumerable<ProjectItemInfo> files,\n\t\t\tMetadataFile module)\n\t\t{\n\t\t\tconst string ns = \"http://schemas.microsoft.com/developer/msbuild/2003\";\n\t\t\tstring platformName = module is PEFile peFile ? TargetServices.GetPlatformName(peFile) : \"AnyCPU\";\n\t\t\tvar targetFramework = TargetServices.DetectTargetFramework(module);\n\t\t\tif (targetFramework.Identifier == \".NETFramework\" && targetFramework.VersionNumber == 200)\n\t\t\t\ttargetFramework = TargetServices.DetectTargetFrameworkNET20(module, project.AssemblyResolver, targetFramework);\n\n\t\t\tList<Guid> typeGuids = new List<Guid>();\n\t\t\tif (targetFramework.IsPortableClassLibrary)\n\t\t\t\ttypeGuids.Add(ProjectTypeGuids.PortableLibrary);\n\t\t\ttypeGuids.Add(ProjectTypeGuids.CSharpWindows);\n\n\t\t\tusing (XmlTextWriter w = new XmlTextWriter(target))\n\t\t\t{\n\t\t\t\tw.Formatting = Formatting.Indented;\n\t\t\t\tw.WriteStartDocument();\n\t\t\t\tw.WriteStartElement(\"Project\", ns);\n\t\t\t\tw.WriteAttributeString(\"ToolsVersion\", \"4.0\");\n\t\t\t\tw.WriteAttributeString(\"DefaultTargets\", \"Build\");\n\n\t\t\t\tw.WriteStartElement(\"PropertyGroup\");\n\t\t\t\tw.WriteElementString(\"ProjectGuid\", project.ProjectGuid.ToString(\"B\").ToUpperInvariant());\n\t\t\t\tw.WriteElementString(\"ProjectTypeGuids\", string.Join(\";\", typeGuids.Select(g => g.ToString(\"B\").ToUpperInvariant())));\n\n\t\t\t\tw.WriteStartElement(\"Configuration\");\n\t\t\t\tw.WriteAttributeString(\"Condition\", \" '$(Configuration)' == '' \");\n\t\t\t\tw.WriteValue(\"Debug\");\n\t\t\t\tw.WriteEndElement(); // </Configuration>\n\n\t\t\t\tw.WriteStartElement(\"Platform\");\n\t\t\t\tw.WriteAttributeString(\"Condition\", \" '$(Platform)' == '' \");\n\t\t\t\tw.WriteValue(platformName);\n\t\t\t\tw.WriteEndElement(); // </Platform>\n\n\t\t\t\tstring outputType;\n\t\t\t\tPEHeaders headers = (module as PEFile)?.Reader.PEHeaders;\n\n\t\t\t\tswitch (headers?.PEHeader.Subsystem)\n\t\t\t\t{\n\t\t\t\t\tcase Subsystem.WindowsGui when !headers.IsDll:\n\t\t\t\t\t\toutputType = \"WinExe\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase Subsystem.WindowsCui when !headers.IsDll:\n\t\t\t\t\t\toutputType = \"Exe\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\toutputType = \"Library\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tw.WriteElementString(\"OutputType\", outputType);\n\t\t\t\tw.WriteElementString(\"LangVersion\", project.LanguageVersion.ToString().Replace(\"CSharp\", \"\").Replace('_', '.'));\n\t\t\t\tw.WriteElementString(\"CheckForOverflowUnderflow\", project.CheckForOverflowUnderflow ? \"true\" : \"false\");\n\n\t\t\t\tw.WriteElementString(\"AssemblyName\", module.Name);\n\t\t\t\tif (targetFramework.Identifier != null)\n\t\t\t\t\tw.WriteElementString(\"TargetFrameworkIdentifier\", targetFramework.Identifier);\n\t\t\t\tif (targetFramework.VersionString != null)\n\t\t\t\t\tw.WriteElementString(\"TargetFrameworkVersion\", targetFramework.VersionString);\n\t\t\t\tif (targetFramework.Profile != null)\n\t\t\t\t\tw.WriteElementString(\"TargetFrameworkProfile\", targetFramework.Profile);\n\t\t\t\tw.WriteElementString(\"WarningLevel\", \"4\");\n\t\t\t\tw.WriteElementString(\"AllowUnsafeBlocks\", \"True\");\n\n\t\t\t\tif (project.StrongNameKeyFile != null)\n\t\t\t\t{\n\t\t\t\t\tw.WriteElementString(\"SignAssembly\", \"True\");\n\t\t\t\t\tw.WriteElementString(\"AssemblyOriginatorKeyFile\", Path.GetFileName(project.StrongNameKeyFile));\n\t\t\t\t}\n\n\t\t\t\tw.WriteEndElement(); // </PropertyGroup>\n\n\t\t\t\tw.WriteStartElement(\"PropertyGroup\"); // platform-specific\n\t\t\t\tw.WriteAttributeString(\"Condition\", \" '$(Platform)' == '\" + platformName + \"' \");\n\t\t\t\tw.WriteElementString(\"PlatformTarget\", platformName);\n\t\t\t\tif (targetFramework.VersionNumber > 400 && platformName == \"AnyCPU\"\n\t\t\t\t\t&& ((module as PEFile)?.Reader.PEHeaders.CorHeader.Flags & CorFlags.Prefers32Bit) == 0)\n\t\t\t\t{\n\t\t\t\t\tw.WriteElementString(\"Prefer32Bit\", \"false\");\n\t\t\t\t}\n\t\t\t\tw.WriteEndElement(); // </PropertyGroup> (platform-specific)\n\n\t\t\t\tw.WriteStartElement(\"PropertyGroup\"); // Debug\n\t\t\t\tw.WriteAttributeString(\"Condition\", \" '$(Configuration)' == 'Debug' \");\n\t\t\t\tw.WriteElementString(\"OutputPath\", \"bin\\\\Debug\\\\\");\n\t\t\t\tw.WriteElementString(\"DebugSymbols\", \"true\");\n\t\t\t\tw.WriteElementString(\"DebugType\", \"full\");\n\t\t\t\tw.WriteElementString(\"Optimize\", \"false\");\n\t\t\t\tw.WriteEndElement(); // </PropertyGroup> (Debug)\n\n\t\t\t\tw.WriteStartElement(\"PropertyGroup\"); // Release\n\t\t\t\tw.WriteAttributeString(\"Condition\", \" '$(Configuration)' == 'Release' \");\n\t\t\t\tw.WriteElementString(\"OutputPath\", \"bin\\\\Release\\\\\");\n\t\t\t\tw.WriteElementString(\"DebugSymbols\", \"true\");\n\t\t\t\tw.WriteElementString(\"DebugType\", \"pdbonly\");\n\t\t\t\tw.WriteElementString(\"Optimize\", \"true\");\n\t\t\t\tw.WriteEndElement(); // </PropertyGroup> (Release)\n\n\t\t\t\tw.WriteStartElement(\"ItemGroup\"); // References\n\t\t\t\tforeach (var r in module.AssemblyReferences)\n\t\t\t\t{\n\t\t\t\t\tif (r.Name != \"mscorlib\")\n\t\t\t\t\t{\n\t\t\t\t\t\tw.WriteStartElement(\"Reference\");\n\t\t\t\t\t\tw.WriteAttributeString(\"Include\", r.Name);\n\t\t\t\t\t\tvar asm = project.AssemblyResolver.Resolve(r);\n\t\t\t\t\t\tif (asm != null && !project.AssemblyReferenceClassifier.IsGacAssembly(r))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tw.WriteElementString(\"HintPath\", asm.FileName);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tw.WriteEndElement();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tw.WriteEndElement(); // </ItemGroup> (References)\n\n\t\t\t\tforeach (IGrouping<string, ProjectItemInfo> gr in files.GroupBy(f => f.ItemType).OrderBy(g => g.Key))\n\t\t\t\t{\n\t\t\t\t\tw.WriteStartElement(\"ItemGroup\");\n\t\t\t\t\tforeach (var item in gr.OrderBy(f => f.FileName, StringComparer.OrdinalIgnoreCase))\n\t\t\t\t\t{\n\t\t\t\t\t\tw.WriteStartElement(gr.Key);\n\t\t\t\t\t\tw.WriteAttributeString(\"Include\", item.FileName);\n\t\t\t\t\t\tif (item.AdditionalProperties != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tforeach (var (key, value) in item.AdditionalProperties)\n\t\t\t\t\t\t\t\tw.WriteAttributeString(key, value);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tw.WriteEndElement();\n\t\t\t\t\t}\n\t\t\t\t\tw.WriteEndElement();\n\t\t\t\t}\n\t\t\t\tif (targetFramework.IsPortableClassLibrary)\n\t\t\t\t{\n\t\t\t\t\tw.WriteStartElement(\"Import\");\n\t\t\t\t\tw.WriteAttributeString(\"Project\", \"$(MSBuildExtensionsPath32)\\\\Microsoft\\\\Portable\\\\$(TargetFrameworkVersion)\\\\Microsoft.Portable.CSharp.targets\");\n\t\t\t\t\tw.WriteEndElement();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tw.WriteStartElement(\"Import\");\n\t\t\t\t\tw.WriteAttributeString(\"Project\", \"$(MSBuildToolsPath)\\\\Microsoft.CSharp.targets\");\n\t\t\t\t\tw.WriteEndElement();\n\t\t\t\t}\n\n\t\t\t\tw.WriteEndDocument();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterSdkStyle.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection.PortableExecutable;\nusing System.Xml;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler\n{\n\t/// <summary>\n\t/// A <see cref=\"IProjectFileWriter\"/> implementation that creates the projects in the SDK style format.\n\t/// </summary>\n\tsealed class ProjectFileWriterSdkStyle : IProjectFileWriter\n\t{\n\t\tconst string AspNetCorePrefix = \"Microsoft.AspNetCore\";\n\t\tconst string PresentationFrameworkName = \"PresentationFramework\";\n\t\tconst string WindowsFormsName = \"System.Windows.Forms\";\n\t\tconst string TrueString = \"True\";\n\t\tconst string FalseString = \"False\";\n\t\tconst string AnyCpuString = \"AnyCPU\";\n\n\t\tstatic readonly HashSet<string> ImplicitReferences = new HashSet<string> {\n\t\t\t\"mscorlib\",\n\t\t\t\"netstandard\",\n\t\t\t\"PresentationFramework\",\n\t\t\t\"System\",\n\t\t\t\"System.Diagnostics.Debug\",\n\t\t\t\"System.Diagnostics.Tools\",\n\t\t\t\"System.Drawing\",\n\t\t\t\"System.Runtime\",\n\t\t\t\"System.Runtime.Extensions\",\n\t\t\t\"System.Windows.Forms\",\n\t\t\t\"System.Xaml\",\n\t\t};\n\n\t\tenum ProjectType { Default, WinForms, Wpf, Web }\n\n\t\t/// <summary>\n\t\t/// Creates a new instance of the <see cref=\"ProjectFileWriterSdkStyle\"/> class.\n\t\t/// </summary>\n\t\t/// <returns>A new instance of the <see cref=\"ProjectFileWriterSdkStyle\"/> class.</returns>\n\t\tpublic static IProjectFileWriter Create() => new ProjectFileWriterSdkStyle();\n\n\t\t/// <inheritdoc />\n\t\tpublic void Write(\n\t\t\tTextWriter target,\n\t\t\tIProjectInfoProvider project,\n\t\t\tIEnumerable<ProjectItemInfo> files,\n\t\t\tMetadataFile module)\n\t\t{\n\t\t\tusing (XmlTextWriter xmlWriter = new XmlTextWriter(target))\n\t\t\t{\n\t\t\t\txmlWriter.Formatting = Formatting.Indented;\n\t\t\t\tWrite(xmlWriter, project, files, module);\n\t\t\t}\n\t\t}\n\n\t\tstatic void Write(XmlTextWriter xml, IProjectInfoProvider project, IEnumerable<ProjectItemInfo> files, MetadataFile module)\n\t\t{\n\t\t\txml.WriteStartElement(\"Project\");\n\n\t\t\tvar projectType = GetProjectType(module);\n\t\t\txml.WriteAttributeString(\"Sdk\", GetSdkString(projectType));\n\n\t\t\tPlaceIntoTag(\"PropertyGroup\", xml, () => WriteAssemblyInfo(xml, module, project, projectType));\n\t\t\tPlaceIntoTag(\"PropertyGroup\", xml, () => WriteProjectInfo(xml, project));\n\t\t\tPlaceIntoTag(\"PropertyGroup\", xml, () => WriteMiscellaneousPropertyGroup(xml, files));\n\t\t\tPlaceIntoTag(\"ItemGroup\", xml, () => WriteResources(xml, files));\n\t\t\tPlaceIntoTag(\"ItemGroup\", xml, () => WriteReferences(xml, module, project, projectType));\n\n\t\t\txml.WriteEndElement();\n\t\t}\n\n\t\tstatic void PlaceIntoTag(string tagName, XmlTextWriter xml, Action content)\n\t\t{\n\t\t\txml.WriteStartElement(tagName);\n\t\t\ttry\n\t\t\t{\n\t\t\t\tcontent();\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\txml.WriteEndElement();\n\t\t\t}\n\t\t}\n\n\t\tstatic void WriteAssemblyInfo(XmlTextWriter xml, MetadataFile module, IProjectInfoProvider project, ProjectType projectType)\n\t\t{\n\t\t\txml.WriteElementString(\"AssemblyName\", module.Name);\n\n\t\t\t// Since we create AssemblyInfo.cs manually, we need to disable the auto-generation\n\t\t\txml.WriteElementString(\"GenerateAssemblyInfo\", FalseString);\n\n\t\t\tstring platformName;\n\t\t\tCorFlags flags;\n\t\t\tif (module is PEFile { Reader.PEHeaders: var headers } peFile)\n\t\t\t{\n\t\t\t\tWriteOutputType(xml, headers.IsDll, headers.PEHeader.Subsystem, projectType);\n\t\t\t\tplatformName = TargetServices.GetPlatformName(peFile);\n\t\t\t\tflags = headers.CorHeader.Flags;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tWriteOutputType(xml, isDll: true, Subsystem.Unknown, projectType);\n\t\t\t\tplatformName = AnyCpuString;\n\t\t\t\tflags = 0;\n\t\t\t}\n\n\t\t\tWriteDesktopExtensions(xml, projectType);\n\n\t\t\tvar targetFramework = TargetServices.DetectTargetFramework(module);\n\t\t\tif (targetFramework.Identifier == \".NETFramework\" && targetFramework.VersionNumber == 200)\n\t\t\t\ttargetFramework = TargetServices.DetectTargetFrameworkNET20(module, project.AssemblyResolver, targetFramework);\n\n\t\t\tif (targetFramework.Moniker == null)\n\t\t\t{\n\t\t\t\tthrow new NotSupportedException($\"Cannot decompile this assembly to a SDK style project. Use default project format instead.\");\n\t\t\t}\n\n\t\t\txml.WriteElementString(\"TargetFramework\", targetFramework.Moniker);\n\n\t\t\t// 'AnyCPU' is default, so only need to specify platform if it differs\n\t\t\tif (platformName != AnyCpuString)\n\t\t\t{\n\t\t\t\txml.WriteElementString(\"PlatformTarget\", platformName);\n\t\t\t}\n\n\t\t\tif (platformName == AnyCpuString && (flags & CorFlags.Prefers32Bit) != 0)\n\t\t\t{\n\t\t\t\txml.WriteElementString(\"Prefer32Bit\", TrueString);\n\t\t\t}\n\t\t}\n\n\t\tstatic void WriteOutputType(XmlTextWriter xml, bool isDll, Subsystem moduleSubsystem, ProjectType projectType)\n\t\t{\n\t\t\tif (!isDll)\n\t\t\t{\n\t\t\t\tswitch (moduleSubsystem)\n\t\t\t\t{\n\t\t\t\t\tcase Subsystem.WindowsGui:\n\t\t\t\t\t\txml.WriteElementString(\"OutputType\", \"WinExe\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase Subsystem.WindowsCui:\n\t\t\t\t\t\txml.WriteElementString(\"OutputType\", \"Exe\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// 'Library' is default, so only need to specify output type for executables (excludes ProjectType.Web)\n\t\t\t\tif (projectType == ProjectType.Web)\n\t\t\t\t{\n\t\t\t\t\txml.WriteElementString(\"OutputType\", \"Library\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic void WriteDesktopExtensions(XmlTextWriter xml, ProjectType projectType)\n\t\t{\n\t\t\tif (projectType == ProjectType.Wpf)\n\t\t\t{\n\t\t\t\txml.WriteElementString(\"UseWPF\", TrueString);\n\t\t\t}\n\t\t\telse if (projectType == ProjectType.WinForms)\n\t\t\t{\n\t\t\t\txml.WriteElementString(\"UseWindowsForms\", TrueString);\n\t\t\t}\n\t\t}\n\n\t\tstatic void WriteProjectInfo(XmlTextWriter xml, IProjectInfoProvider project)\n\t\t{\n\t\t\txml.WriteElementString(\"LangVersion\", project.LanguageVersion.ToString().Replace(\"CSharp\", \"\").Replace('_', '.'));\n\t\t\txml.WriteElementString(\"AllowUnsafeBlocks\", TrueString);\n\t\t\txml.WriteElementString(\"CheckForOverflowUnderflow\", project.CheckForOverflowUnderflow ? TrueString : FalseString);\n\n\t\t\tif (project.StrongNameKeyFile != null)\n\t\t\t{\n\t\t\t\txml.WriteElementString(\"SignAssembly\", TrueString);\n\t\t\t\txml.WriteElementString(\"AssemblyOriginatorKeyFile\", Path.GetFileName(project.StrongNameKeyFile));\n\t\t\t}\n\t\t}\n\n\t\tstatic void WriteMiscellaneousPropertyGroup(XmlTextWriter xml, IEnumerable<ProjectItemInfo> files)\n\t\t{\n\t\t\tvar (itemType, fileName) = files.FirstOrDefault(t => t.ItemType == \"ApplicationIcon\");\n\t\t\tif (fileName != null)\n\t\t\t\txml.WriteElementString(\"ApplicationIcon\", fileName);\n\n\t\t\t(itemType, fileName) = files.FirstOrDefault(t => t.ItemType == \"ApplicationManifest\");\n\t\t\tif (fileName != null)\n\t\t\t\txml.WriteElementString(\"ApplicationManifest\", fileName);\n\n\t\t\tif (files.Any(t => t.ItemType == \"EmbeddedResource\"))\n\t\t\t\txml.WriteElementString(\"RootNamespace\", string.Empty);\n\t\t\t// TODO: We should add CustomToolNamespace for resources, otherwise we should add empty RootNamespace\n\t\t}\n\n\t\tstatic void WriteResources(XmlTextWriter xml, IEnumerable<ProjectItemInfo> files)\n\t\t{\n\t\t\t// remove phase\n\t\t\tforeach (var item in files.Where(t => t.ItemType == \"EmbeddedResource\"))\n\t\t\t{\n\t\t\t\tstring buildAction = Path.GetExtension(item.FileName).ToUpperInvariant() switch {\n\t\t\t\t\t\".CS\" => \"Compile\",\n\t\t\t\t\t\".RESX\" => \"EmbeddedResource\",\n\t\t\t\t\t_ => \"None\"\n\t\t\t\t};\n\t\t\t\tif (buildAction == \"EmbeddedResource\")\n\t\t\t\t\tcontinue;\n\n\t\t\t\txml.WriteStartElement(buildAction);\n\t\t\t\txml.WriteAttributeString(\"Remove\", item.FileName);\n\t\t\t\txml.WriteEndElement();\n\t\t\t}\n\n\t\t\t// include phase\n\t\t\tforeach (var item in files.Where(t => t.ItemType == \"EmbeddedResource\"))\n\t\t\t{\n\t\t\t\tif (Path.GetExtension(item.FileName) == \".resx\")\n\t\t\t\t\tcontinue;\n\n\t\t\t\txml.WriteStartElement(\"EmbeddedResource\");\n\t\t\t\txml.WriteAttributeString(\"Include\", item.FileName);\n\t\t\t\tif (item.AdditionalProperties != null)\n\t\t\t\t{\n\t\t\t\t\tforeach (var (key, value) in item.AdditionalProperties)\n\t\t\t\t\t\txml.WriteAttributeString(key, value);\n\t\t\t\t}\n\t\t\t\txml.WriteEndElement();\n\t\t\t}\n\t\t}\n\n\t\tstatic void WriteReferences(XmlTextWriter xml, MetadataFile module, IProjectInfoProvider project, ProjectType projectType)\n\t\t{\n\t\t\tbool isNetCoreApp = TargetServices.DetectTargetFramework(module).Identifier == \".NETCoreApp\";\n\t\t\tvar targetPacks = new HashSet<string>();\n\t\t\tif (isNetCoreApp)\n\t\t\t{\n\t\t\t\ttargetPacks.Add(\"Microsoft.NETCore.App\");\n\t\t\t\tswitch (projectType)\n\t\t\t\t{\n\t\t\t\t\tcase ProjectType.WinForms:\n\t\t\t\t\tcase ProjectType.Wpf:\n\t\t\t\t\t\ttargetPacks.Add(\"Microsoft.WindowsDesktop.App\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase ProjectType.Web:\n\t\t\t\t\t\ttargetPacks.Add(\"Microsoft.AspNetCore.App\");\n\t\t\t\t\t\ttargetPacks.Add(\"Microsoft.AspNetCore.All\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach (var reference in module.AssemblyReferences.Where(r => !ImplicitReferences.Contains(r.Name)))\n\t\t\t{\n\t\t\t\tif (isNetCoreApp && project.AssemblyReferenceClassifier.IsSharedAssembly(reference, out string runtimePack) && targetPacks.Contains(runtimePack))\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\txml.WriteStartElement(\"Reference\");\n\t\t\t\txml.WriteAttributeString(\"Include\", reference.Name);\n\n\t\t\t\tvar asembly = project.AssemblyResolver.Resolve(reference);\n\t\t\t\tif (asembly != null && !project.AssemblyReferenceClassifier.IsGacAssembly(reference))\n\t\t\t\t{\n\t\t\t\t\txml.WriteElementString(\"HintPath\", FileUtility.GetRelativePath(project.TargetDirectory, asembly.FileName));\n\t\t\t\t}\n\n\t\t\t\txml.WriteEndElement();\n\t\t\t}\n\t\t}\n\n\t\tstatic string GetSdkString(ProjectType projectType)\n\t\t{\n\t\t\tswitch (projectType)\n\t\t\t{\n\t\t\t\tcase ProjectType.WinForms:\n\t\t\t\tcase ProjectType.Wpf:\n\t\t\t\t\treturn \"Microsoft.NET.Sdk.WindowsDesktop\";\n\t\t\t\tcase ProjectType.Web:\n\t\t\t\t\treturn \"Microsoft.NET.Sdk.Web\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Microsoft.NET.Sdk\";\n\t\t\t}\n\t\t}\n\n\t\tstatic ProjectType GetProjectType(MetadataFile module)\n\t\t{\n\t\t\tforeach (var referenceName in module.AssemblyReferences.Select(r => r.Name))\n\t\t\t{\n\t\t\t\tif (referenceName.StartsWith(AspNetCorePrefix, StringComparison.Ordinal))\n\t\t\t\t{\n\t\t\t\t\treturn ProjectType.Web;\n\t\t\t\t}\n\n\t\t\t\tif (referenceName == PresentationFrameworkName)\n\t\t\t\t{\n\t\t\t\t\treturn ProjectType.Wpf;\n\t\t\t\t}\n\n\t\t\t\tif (referenceName == WindowsFormsName)\n\t\t\t\t{\n\t\t\t\t\treturn ProjectType.WinForms;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn ProjectType.Default;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/ProjectDecompiler/TargetFramework.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler\n{\n\t/// <summary>\n\t/// A class describing the target framework of a module.\n\t/// </summary>\n\tpublic class TargetFramework\n\t{\n\t\tconst string DotNetPortableIdentifier = \".NETPortable\";\n\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"TargetFramework\"/> class.\n\t\t/// </summary>\n\t\t/// <param name=\"identifier\">The framework identifier string. Can be null.</param>\n\t\t/// <param name=\"version\">The framework version string. Must be greater than 100 (where 100 corresponds to v1.0).</param>\n\t\t/// <param name=\"profile\">The framework profile. Can be null.</param>\n\t\tpublic TargetFramework(string identifier, int version, string profile)\n\t\t{\n\t\t\tif (version < 100)\n\t\t\t{\n\t\t\t\tthrow new ArgumentException(\"The version number must be greater than or equal to 100\", nameof(version));\n\t\t\t}\n\n\t\t\tIdentifier = identifier;\n\t\t\tVersionNumber = version;\n\t\t\tVersionString = \"v\" + GetVersionString(version, withDots: true);\n\t\t\tMoniker = GetTargetFrameworkMoniker(Identifier, version);\n\t\t\tProfile = profile;\n\t\t\tIsPortableClassLibrary = identifier == DotNetPortableIdentifier;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the target framework identifier. Can be null if not defined.\n\t\t/// </summary>\n\t\tpublic string Identifier { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the target framework moniker. Can be null if not supported.\n\t\t/// </summary>\n\t\tpublic string Moniker { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the target framework version, e.g. \"v4.5\".\n\t\t/// </summary>\n\t\tpublic string VersionString { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the target framework version as integer (multiplied by 100), e.g. 450.\n\t\t/// </summary>\n\t\tpublic int VersionNumber { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the target framework profile. Can be null if not set or not available.\n\t\t/// </summary>\n\t\tpublic string Profile { get; }\n\n\t\t/// <summary>\n\t\t/// Gets a value indicating whether the target is a portable class library (PCL).\n\t\t/// </summary>\n\t\tpublic bool IsPortableClassLibrary { get; }\n\n\t\tstatic string GetTargetFrameworkMoniker(string frameworkIdentifier, int version)\n\t\t{\n\t\t\t// Reference: https://docs.microsoft.com/en-us/dotnet/standard/frameworks\n\t\t\tswitch (frameworkIdentifier)\n\t\t\t{\n\t\t\t\tcase null:\n\t\t\t\tcase \".NETFramework\":\n\t\t\t\t\treturn \"net\" + GetVersionString(version, withDots: false);\n\n\t\t\t\tcase \".NETCoreApp\":\n\t\t\t\t\tif (version >= 500)\n\t\t\t\t\t\treturn \"net\" + GetVersionString(version, withDots: true);\n\t\t\t\t\treturn \"netcoreapp\" + GetVersionString(version, withDots: true);\n\n\t\t\t\tcase \".NETStandard\":\n\t\t\t\t\treturn \"netstandard\" + GetVersionString(version, withDots: true);\n\n\t\t\t\tcase \"Silverlight\":\n\t\t\t\t\treturn \"sl\" + version / 100;\n\n\t\t\t\tcase \".NETCore\":\n\t\t\t\t\treturn \"netcore\" + GetVersionString(version, withDots: false);\n\n\t\t\t\tcase \"WindowsPhone\":\n\t\t\t\t\treturn \"wp\" + GetVersionString(version, withDots: false, omitMinorWhenZero: true);\n\n\t\t\t\tcase \".NETMicroFramework\":\n\t\t\t\t\treturn \"netmf\";\n\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tstatic string GetVersionString(int version, bool withDots, bool omitMinorWhenZero = false)\n\t\t{\n\t\t\tint major = version / 100;\n\t\t\tint minor = version % 100 / 10;\n\t\t\tint patch = version % 10;\n\n\t\t\tif (omitMinorWhenZero && minor == 0 && patch == 0)\n\t\t\t{\n\t\t\t\treturn major.ToString();\n\t\t\t}\n\n\t\t\tvar versionBuilder = new StringBuilder(8);\n\t\t\tversionBuilder.Append(major);\n\n\t\t\tif (withDots)\n\t\t\t{\n\t\t\t\tversionBuilder.Append('.');\n\t\t\t}\n\n\t\t\tversionBuilder.Append(minor);\n\n\t\t\tif (patch != 0)\n\t\t\t{\n\t\t\t\tif (withDots)\n\t\t\t\t{\n\t\t\t\t\tversionBuilder.Append('.');\n\t\t\t\t}\n\n\t\t\t\tversionBuilder.Append(patch);\n\t\t\t}\n\n\t\t\treturn versionBuilder.ToString();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/ProjectDecompiler/TargetServices.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection.PortableExecutable;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler\n{\n\t/// <summary>\n\t/// Helper services for determining the target framework and platform of a module.\n\t/// </summary>\n\tpublic static class TargetServices\n\t{\n\t\tconst string VersionToken = \"Version=\";\n\t\tconst string ProfileToken = \"Profile=\";\n\n\t\t/// <summary>\n\t\t/// Gets the <see cref=\"TargetFramework\"/> for the specified <paramref name=\"module\"/>.\n\t\t/// </summary>\n\t\t/// <param name=\"module\">The module to get the target framework description for. Cannot be null.</param>\n\t\t/// <returns>A new instance of the <see cref=\"TargetFramework\"/> class that describes the specified <paramref name=\"module\"/>.\n\t\t/// </returns>\n\t\tpublic static TargetFramework DetectTargetFramework(MetadataFile module)\n\t\t{\n\t\t\tif (module is null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(module));\n\t\t\t}\n\n\t\t\tint versionNumber;\n\t\t\tswitch (module.GetRuntime())\n\t\t\t{\n\t\t\t\tcase TargetRuntime.Net_1_0:\n\t\t\t\t\tversionNumber = 100;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase TargetRuntime.Net_1_1:\n\t\t\t\t\tversionNumber = 110;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase TargetRuntime.Net_2_0:\n\t\t\t\t\tversionNumber = 200;\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tversionNumber = 400;\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tstring targetFrameworkIdentifier = null;\n\t\t\tstring targetFrameworkProfile = null;\n\n\t\t\tstring targetFramework = module.DetectTargetFrameworkId();\n\t\t\tif (!string.IsNullOrEmpty(targetFramework))\n\t\t\t{\n\t\t\t\tstring[] frameworkParts = targetFramework.Split(',');\n\t\t\t\ttargetFrameworkIdentifier = frameworkParts.FirstOrDefault(a => !a.StartsWith(VersionToken, StringComparison.OrdinalIgnoreCase) && !a.StartsWith(ProfileToken, StringComparison.OrdinalIgnoreCase));\n\t\t\t\tstring frameworkVersion = frameworkParts.FirstOrDefault(a => a.StartsWith(VersionToken, StringComparison.OrdinalIgnoreCase));\n\n\t\t\t\tif (frameworkVersion != null && Version.TryParse(frameworkVersion.Substring(VersionToken.Length).Replace(\"v\", \"\"), out var version))\n\t\t\t\t{\n\t\t\t\t\tversionNumber = version.Major * 100 + version.Minor * 10;\n\t\t\t\t\tif (version.Build > 0)\n\t\t\t\t\t\tversionNumber += version.Build;\n\t\t\t\t}\n\n\t\t\t\tstring frameworkProfile = frameworkParts.FirstOrDefault(a => a.StartsWith(ProfileToken, StringComparison.OrdinalIgnoreCase));\n\t\t\t\tif (frameworkProfile != null)\n\t\t\t\t\ttargetFrameworkProfile = frameworkProfile.Substring(ProfileToken.Length);\n\t\t\t}\n\n\t\t\treturn new TargetFramework(targetFrameworkIdentifier, versionNumber, targetFrameworkProfile);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the string representation (name) of the target platform of the specified <paramref name=\"module\"/>.\n\t\t/// </summary>\n\t\t/// <param name=\"module\">The module to get the target framework description for. Cannot be null.</param>\n\t\t/// <returns>The platform name, e.g. \"AnyCPU\" or \"x86\".</returns>\n\t\tpublic static string GetPlatformName(PEFile module)\n\t\t{\n\t\t\tif (module is null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(module));\n\t\t\t}\n\n\t\t\tvar headers = module.Reader.PEHeaders;\n\t\t\tvar architecture = headers.CoffHeader.Machine;\n\t\t\tvar characteristics = headers.CoffHeader.Characteristics;\n\t\t\tvar corflags = headers.CorHeader.Flags;\n\n\t\t\tswitch (architecture)\n\t\t\t{\n\t\t\t\tcase Machine.I386:\n\t\t\t\t\tif ((corflags & CorFlags.Prefers32Bit) != 0)\n\t\t\t\t\t\treturn \"AnyCPU\";\n\n\t\t\t\t\tif ((corflags & CorFlags.Requires32Bit) != 0)\n\t\t\t\t\t\treturn \"x86\";\n\n\t\t\t\t\t// According to ECMA-335, II.25.3.3.1 CorFlags.Requires32Bit and Characteristics.Bit32Machine must be in sync\n\t\t\t\t\t// for assemblies containing managed code. However, this is not true for C++/CLI assemblies.\n\t\t\t\t\tif ((corflags & CorFlags.ILOnly) == 0 && (characteristics & Characteristics.Bit32Machine) != 0)\n\t\t\t\t\t\treturn \"x86\";\n\t\t\t\t\treturn \"AnyCPU\";\n\n\t\t\t\tcase Machine.Amd64:\n\t\t\t\t\treturn \"x64\";\n\n\t\t\t\tcase Machine.IA64:\n\t\t\t\t\treturn \"Itanium\";\n\n\t\t\t\tdefault:\n\t\t\t\t\treturn architecture.ToString();\n\t\t\t}\n\t\t}\n\n\t\tstatic HashSet<string> dotNet30Assemblies = new HashSet<string>(StringComparer.OrdinalIgnoreCase) {\n\t\t\t\"ComSvcConfig, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\n\t\t\t\"infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"Microsoft.Transactions.Bridge, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\n\t\t\t\"Microsoft.Transactions.Bridge.Dtc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\n\t\t\t\"PresentationBuildTasks, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"PresentationCFFRasterizer, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"PresentationFramework.Aero, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"PresentationFramework.Classic, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"PresentationFramework.Luna, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"PresentationFramework.Royale, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"PresentationUI, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"ReachFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"ServiceModelReg, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\n\t\t\t\"SMSvcHost, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\n\t\t\t\"System.IdentityModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.IdentityModel.Selectors, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.IO.Log, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\n\t\t\t\"System.Printing, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"System.Runtime.Serialization, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.ServiceModel.Install, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.ServiceModel.WasHosting, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.Speech, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"System.Workflow.Activities, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"System.Workflow.ComponentModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"UIAutomationClient, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"UIAutomationClientsideProviders, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"UIAutomationProvider, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"UIAutomationTypes, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"WindowsBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"WindowsFormsIntegration, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"WsatConfig, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\n\t\t};\n\n\t\tstatic HashSet<string> dotNet35Assemblies = new HashSet<string>(StringComparer.OrdinalIgnoreCase) {\n\t\t\t\"AddInProcess, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"AddInProcess32, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"AddInUtil, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"DataSvcUtil, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"EdmGen, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"Microsoft.Build.Conversion.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\n\t\t\t\"Microsoft.Build.Engine, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\n\t\t\t\"Microsoft.Build.Framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\n\t\t\t\"Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\n\t\t\t\"Microsoft.Build.Utilities.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\n\t\t\t\"Microsoft.Data.Entity.Build.Tasks, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\n\t\t\t\"Microsoft.VisualC.STLCLR, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\n\t\t\t\"MSBuild, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\n\t\t\t\"Sentinel.v3.5Client, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\n\t\t\t\"System.AddIn, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.AddIn.Contract, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\n\t\t\t\"System.ComponentModel.DataAnnotations, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.Data.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.Data.Entity.Design, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.Data.Services, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.Data.Services.Client, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.Data.Services.Design, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.DirectoryServices.AccountManagement, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.Management.Instrumentation, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.Net, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\",\n\t\t\t\"System.ServiceModel.Web, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"System.Web.Abstractions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"System.Web.DynamicData, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"System.Web.DynamicData.Design, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"System.Web.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.Web.Entity.Design, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"System.Web.Extensions.Design, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"System.Windows.Presentation, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t\t\"System.WorkflowServices, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\",\n\t\t\t\"System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\",\n\t\t};\n\n\t\t/// <summary>\n\t\t/// Gets exact <see cref=\"TargetFramework\"/> if <see cref=\"MetadataFile.GetRuntime\"/> is <see cref=\"TargetRuntime.Net_2_0\"/>\n\t\t/// </summary>\n\t\tpublic static TargetFramework DetectTargetFrameworkNET20(MetadataFile module, IAssemblyResolver assemblyResolver, TargetFramework targetFramework)\n\t\t{\n\t\t\tvar resolvedAssemblies = new HashSet<string>();\n\t\t\tint version = 200;\n\t\t\tGetFrameworkVersionNET20(module, assemblyResolver, resolvedAssemblies, ref version);\n\t\t\treturn new TargetFramework(targetFramework.Identifier, version, targetFramework.Profile);\n\t\t}\n\n\t\tstatic void GetFrameworkVersionNET20(MetadataFile module, IAssemblyResolver assemblyResolver, HashSet<string> resolvedAssemblies, ref int version)\n\t\t{\n\t\t\tforeach (var r in module.Metadata.AssemblyReferences)\n\t\t\t{\n\t\t\t\tvar reference = new AssemblyReference(module, r);\n\t\t\t\tif (!resolvedAssemblies.Add(reference.FullName))\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (dotNet30Assemblies.Contains(reference.FullName))\n\t\t\t\t{\n\t\t\t\t\tversion = 300;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\telse if (dotNet35Assemblies.Contains(reference.FullName))\n\t\t\t\t{\n\t\t\t\t\tversion = 350;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tMetadataFile resolvedReference;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tresolvedReference = assemblyResolver.Resolve(reference);\n\t\t\t\t}\n\t\t\t\tcatch (ResolutionException)\n\t\t\t\t{\n\t\t\t\t\tresolvedReference = null;\n\t\t\t\t}\n\t\t\t\tif (resolvedReference == null)\n\t\t\t\t\tcontinue;\n\t\t\t\tresolvedAssemblies.Add(resolvedReference.FullName);\n\t\t\t\tGetFrameworkVersionNET20(resolvedReference, assemblyResolver, resolvedAssemblies, ref version);\n\t\t\t\tif (version == 350)\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs",
    "content": "// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Runtime.InteropServices;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.CSharp.Transforms;\nusing ICSharpCode.Decompiler.DebugInfo;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.Solution;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nusing static ICSharpCode.Decompiler.Metadata.MetadataExtensions;\n\nnamespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler\n{\n\t/// <summary>\n\t/// Decompiles an assembly into a visual studio project file.\n\t/// </summary>\n\tpublic class WholeProjectDecompiler : IProjectInfoProvider\n\t{\n\t\tconst int maxSegmentLength = 255;\n\n\t\t#region Settings\n\t\t/// <summary>\n\t\t/// Gets the setting this instance uses for decompiling.\n\t\t/// </summary>\n\t\tpublic DecompilerSettings Settings { get; }\n\n\t\tLanguageVersion? languageVersion;\n\n\t\tpublic LanguageVersion LanguageVersion {\n\t\t\tget { return languageVersion ?? Settings.GetMinimumRequiredVersion(); }\n\t\t\tset {\n\t\t\t\tvar minVersion = Settings.GetMinimumRequiredVersion();\n\t\t\t\tif (value < minVersion)\n\t\t\t\t\tthrow new InvalidOperationException($\"The chosen settings require at least {minVersion}.\" +\n\t\t\t\t\t\t$\" Please change the DecompilerSettings accordingly.\");\n\t\t\t\tlanguageVersion = value;\n\t\t\t}\n\t\t}\n\n\t\tbool IProjectInfoProvider.CheckForOverflowUnderflow => Settings.CheckForOverflowUnderflow;\n\n\t\tpublic IAssemblyResolver AssemblyResolver { get; }\n\n\t\tpublic AssemblyReferenceClassifier AssemblyReferenceClassifier { get; }\n\n\t\tpublic IDebugInfoProvider DebugInfoProvider { get; }\n\n\t\t/// <summary>\n\t\t/// The MSBuild ProjectGuid to use for the new project.\n\t\t/// </summary>\n\t\tpublic Guid ProjectGuid { get; }\n\n\t\t/// <summary>\n\t\t/// The target directory that the decompiled files are written to.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This property is set by DecompileProject() and protected so that overridden protected members\n\t\t/// can access it.\n\t\t/// </remarks>\n\t\tpublic string TargetDirectory { get; protected set; }\n\n\t\t/// <summary>\n\t\t/// Path to the snk file to use for signing.\n\t\t/// <c>null</c> to not sign.\n\t\t/// </summary>\n\t\tpublic string StrongNameKeyFile { get; set; }\n\n\t\tpublic int MaxDegreeOfParallelism { get; set; } = Environment.ProcessorCount;\n\n\t\tpublic IProgress<DecompilationProgress> ProgressIndicator { get; set; }\n\t\t#endregion\n\n\t\tpublic WholeProjectDecompiler(IAssemblyResolver assemblyResolver)\n\t\t\t: this(new DecompilerSettings(), assemblyResolver, projectWriter: null, assemblyReferenceClassifier: null, debugInfoProvider: null)\n\t\t{\n\t\t}\n\n\t\tpublic WholeProjectDecompiler(\n\t\t\tDecompilerSettings settings,\n\t\t\tIAssemblyResolver assemblyResolver,\n\t\t\tIProjectFileWriter projectWriter,\n\t\t\tAssemblyReferenceClassifier assemblyReferenceClassifier,\n\t\t\tIDebugInfoProvider debugInfoProvider)\n\t\t\t: this(settings, Guid.NewGuid(), assemblyResolver, projectWriter, assemblyReferenceClassifier, debugInfoProvider)\n\t\t{\n\t\t}\n\n\t\tprotected WholeProjectDecompiler(\n\t\t\tDecompilerSettings settings,\n\t\t\tGuid projectGuid,\n\t\t\tIAssemblyResolver assemblyResolver,\n\t\t\tIProjectFileWriter projectWriter,\n\t\t\tAssemblyReferenceClassifier assemblyReferenceClassifier,\n\t\t\tIDebugInfoProvider debugInfoProvider)\n\t\t{\n\t\t\tSettings = settings ?? throw new ArgumentNullException(nameof(settings));\n\t\t\tProjectGuid = projectGuid;\n\t\t\tAssemblyResolver = assemblyResolver ?? throw new ArgumentNullException(nameof(assemblyResolver));\n\t\t\tAssemblyReferenceClassifier = assemblyReferenceClassifier ?? new AssemblyReferenceClassifier();\n\t\t\tDebugInfoProvider = debugInfoProvider;\n\t\t\tthis.projectWriter = projectWriter ?? (Settings.UseSdkStyleProjectFormat ? ProjectFileWriterSdkStyle.Create() : ProjectFileWriterDefault.Create());\n\t\t}\n\n\t\t// per-run members\n\t\tHashSet<string> directories = new HashSet<string>(Platform.FileNameComparer);\n\t\treadonly IProjectFileWriter projectWriter;\n\n\t\tpublic void DecompileProject(MetadataFile file, string targetDirectory, CancellationToken cancellationToken = default(CancellationToken))\n\t\t{\n\t\t\tstring projectFileName = Path.Combine(targetDirectory, CleanUpFileName(file.Name, \".csproj\"));\n\t\t\tusing (var writer = CreateFile(projectFileName))\n\t\t\t{\n\t\t\t\tDecompileProject(file, targetDirectory, writer, cancellationToken);\n\t\t\t}\n\t\t}\n\n\t\tpublic ProjectId DecompileProject(MetadataFile file, string targetDirectory, TextWriter projectFileWriter, CancellationToken cancellationToken = default(CancellationToken))\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(targetDirectory))\n\t\t\t{\n\t\t\t\tthrow new InvalidOperationException(\"Must set TargetDirectory\");\n\t\t\t}\n\t\t\tTargetDirectory = targetDirectory;\n\t\t\tdirectories.Clear();\n\t\t\tvar resources = WriteResourceFilesInProject(file).ToList();\n\t\t\tvar files = WriteCodeFilesInProject(file, resources.SelectMany(r => r.PartialTypes ?? Enumerable.Empty<PartialTypeInfo>()).ToList(), cancellationToken).ToList();\n\t\t\tfiles.AddRange(resources);\n\t\t\tvar module = file as PEFile;\n\t\t\tif (module != null)\n\t\t\t{\n\t\t\t\tfiles.AddRange(WriteMiscellaneousFilesInProject(module));\n\t\t\t}\n\t\t\tif (StrongNameKeyFile != null)\n\t\t\t{\n\t\t\t\tFile.Copy(StrongNameKeyFile, Path.Combine(targetDirectory, Path.GetFileName(StrongNameKeyFile)), overwrite: true);\n\t\t\t}\n\n\t\t\tprojectWriter.Write(projectFileWriter, this, files, file);\n\n\t\t\tstring platformName = module != null ? TargetServices.GetPlatformName(module) : \"AnyCPU\";\n\t\t\treturn new ProjectId(platformName, ProjectGuid, ProjectTypeGuids.CSharpWindows);\n\t\t}\n\n\t\t#region WriteCodeFilesInProject\n\t\tprotected virtual bool IncludeTypeWhenDecompilingProject(MetadataFile module, TypeDefinitionHandle type)\n\t\t{\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar typeDef = metadata.GetTypeDefinition(type);\n\t\t\tstring name = metadata.GetString(typeDef.Name);\n\t\t\tstring ns = metadata.GetString(typeDef.Namespace);\n\t\t\tif (name == \"<Module>\" || CSharpDecompiler.MemberIsHidden(module, type, Settings))\n\t\t\t\treturn false;\n\t\t\tif (ns == \"XamlGeneratedNamespace\" && name == \"GeneratedInternalTypeHelper\")\n\t\t\t\treturn false;\n\t\t\tif (!typeDef.IsNested && RemoveEmbeddedAttributes.attributeNames.Contains(ns + \".\" + name))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tprotected virtual TextWriter CreateFile(string path)\n\t\t{\n\t\t\treturn new StreamWriter(path);\n\t\t}\n\n\t\tprotected virtual void CreateDirectory(string path)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tDirectory.CreateDirectory(path);\n\t\t\t}\n\t\t\tcatch (IOException)\n\t\t\t{\n\t\t\t\tFile.Delete(path);\n\t\t\t\tDirectory.CreateDirectory(path);\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual CSharpDecompiler CreateDecompiler(DecompilerTypeSystem ts)\n\t\t{\n\t\t\tvar decompiler = new CSharpDecompiler(ts, Settings);\n\t\t\tdecompiler.DebugInfoProvider = DebugInfoProvider;\n\t\t\tdecompiler.AstTransforms.Add(new EscapeInvalidIdentifiers());\n\t\t\tdecompiler.AstTransforms.Add(new RemoveCLSCompliantAttribute());\n\t\t\treturn decompiler;\n\t\t}\n\n\t\tIEnumerable<ProjectItemInfo> WriteAssemblyInfo(DecompilerTypeSystem ts, CancellationToken cancellationToken)\n\t\t{\n\t\t\tvar decompiler = CreateDecompiler(ts);\n\t\t\tdecompiler.CancellationToken = cancellationToken;\n\t\t\tdecompiler.AstTransforms.Add(new RemoveCompilerGeneratedAssemblyAttributes());\n\t\t\tSyntaxTree syntaxTree = decompiler.DecompileModuleAndAssemblyAttributes();\n\n\t\t\tconst string prop = \"Properties\";\n\t\t\tif (directories.Add(prop))\n\t\t\t\tCreateDirectory(Path.Combine(TargetDirectory, prop));\n\t\t\tstring assemblyInfo = Path.Combine(prop, \"AssemblyInfo.cs\");\n\t\t\tusing (var w = CreateFile(Path.Combine(TargetDirectory, assemblyInfo)))\n\t\t\t{\n\t\t\t\tsyntaxTree.AcceptVisitor(new CSharpOutputVisitor(w, Settings.CSharpFormattingOptions));\n\t\t\t}\n\t\t\treturn new[] { new ProjectItemInfo(\"Compile\", assemblyInfo) };\n\t\t}\n\n\t\tIEnumerable<ProjectItemInfo> WriteCodeFilesInProject(MetadataFile module, IList<PartialTypeInfo> partialTypes, CancellationToken cancellationToken)\n\t\t{\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar files = module.Metadata.GetTopLevelTypeDefinitions().Where(td => IncludeTypeWhenDecompilingProject(module, td))\n\t\t\t\t.GroupBy(GetFileFileNameForHandle, StringComparer.OrdinalIgnoreCase).ToList();\n\t\t\tvar progressReporter = ProgressIndicator;\n\t\t\tvar progress = new DecompilationProgress { TotalUnits = files.Count, Title = \"Exporting project...\" };\n\t\t\tDecompilerTypeSystem ts = new DecompilerTypeSystem(module, AssemblyResolver, Settings);\n\t\t\tvar workList = new HashSet<TypeDefinitionHandle>();\n\t\t\tvar processedTypes = new HashSet<TypeDefinitionHandle>();\n\t\t\tProcessFiles(files);\n\t\t\twhile (workList.Count > 0)\n\t\t\t{\n\t\t\t\tvar additionalFiles = workList\n\t\t\t\t\t.GroupBy(GetFileFileNameForHandle, StringComparer.OrdinalIgnoreCase).ToList();\n\t\t\t\tworkList.Clear();\n\t\t\t\tProcessFiles(additionalFiles);\n\t\t\t\tfiles.AddRange(additionalFiles);\n\t\t\t\tprogress.TotalUnits = files.Count;\n\t\t\t}\n\n\t\t\treturn files.Select(f => new ProjectItemInfo(\"Compile\", f.Key)).Concat(WriteAssemblyInfo(ts, cancellationToken));\n\n\t\t\tstring GetFileFileNameForHandle(TypeDefinitionHandle h)\n\t\t\t{\n\t\t\t\tvar type = metadata.GetTypeDefinition(h);\n\t\t\t\tstring file = CleanUpFileName(metadata.GetString(type.Name), \".cs\");\n\t\t\t\tstring ns = metadata.GetString(type.Namespace);\n\t\t\t\tif (string.IsNullOrEmpty(ns))\n\t\t\t\t{\n\t\t\t\t\treturn file;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tstring dir = Settings.UseNestedDirectoriesForNamespaces ? CleanUpPath(ns) : CleanUpDirectoryName(ns);\n\t\t\t\t\tif (directories.Add(dir))\n\t\t\t\t\t{\n\t\t\t\t\t\tvar path = Path.Combine(TargetDirectory, dir);\n\t\t\t\t\t\tCreateDirectory(path);\n\t\t\t\t\t}\n\t\t\t\t\treturn Path.Combine(dir, file);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid ProcessFiles(List<IGrouping<string, TypeDefinitionHandle>> files)\n\t\t\t{\n\t\t\t\tprocessedTypes.AddRange(files.SelectMany(f => f));\n\t\t\t\tParallel.ForEach(\n\t\t\t\t\tPartitioner.Create(files, loadBalance: true),\n\t\t\t\t\tnew ParallelOptions {\n\t\t\t\t\t\tMaxDegreeOfParallelism = this.MaxDegreeOfParallelism,\n\t\t\t\t\t\tCancellationToken = cancellationToken\n\t\t\t\t\t},\n\t\t\t\t\tdelegate (IGrouping<string, TypeDefinitionHandle> file) {\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tusing var w = CreateFile(Path.Combine(TargetDirectory, file.Key));\n\t\t\t\t\t\t\tCSharpDecompiler decompiler = CreateDecompiler(ts);\n\n\t\t\t\t\t\t\tforeach (var partialType in partialTypes)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdecompiler.AddPartialTypeDefinition(partialType);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tdecompiler.CancellationToken = cancellationToken;\n\t\t\t\t\t\t\tvar declaredTypes = file.ToArray();\n\t\t\t\t\t\t\tvar syntaxTree = decompiler.DecompileTypes(declaredTypes);\n\n\t\t\t\t\t\t\tforeach (var node in syntaxTree.Descendants)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvar td = (node.GetResolveResult() as TypeResolveResult)?.Type.GetDefinition();\n\t\t\t\t\t\t\t\tif (td?.ParentModule != ts.MainModule)\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\twhile (td?.DeclaringTypeDefinition != null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttd = td.DeclaringTypeDefinition;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (td != null && td.MetadataToken is { IsNil: false } token && !processedTypes.Contains((TypeDefinitionHandle)token))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlock (workList)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tworkList.Add((TypeDefinitionHandle)token);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tsyntaxTree.AcceptVisitor(new CSharpOutputVisitor(w, Settings.CSharpFormattingOptions));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (Exception innerException) when (!(innerException is OperationCanceledException || innerException is DecompilerException))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tthrow new DecompilerException(module, $\"Error decompiling for '{file.Key}'\", innerException);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tprogress.Status = file.Key;\n\t\t\t\t\t\tInterlocked.Increment(ref progress.UnitsCompleted);\n\t\t\t\t\t\tprogressReporter?.Report(progress);\n\t\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region WriteResourceFilesInProject\n\t\tprotected virtual IEnumerable<ProjectItemInfo> WriteResourceFilesInProject(MetadataFile module)\n\t\t{\n\t\t\tforeach (var r in module.Resources.Where(r => r.ResourceType == ResourceType.Embedded))\n\t\t\t{\n\t\t\t\tStream stream = r.TryOpenStream();\n\t\t\t\tif (stream == null)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tstream.Position = 0;\n\n\t\t\t\tif (r.Name.EndsWith(\".resources\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t{\n\t\t\t\t\tbool decodedIntoIndividualFiles;\n\t\t\t\t\tvar individualResources = new List<ProjectItemInfo>();\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tvar resourcesFile = new ResourcesFile(stream);\n\t\t\t\t\t\tif (resourcesFile.AllEntriesAreStreams())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tforeach (var (name, value) in resourcesFile)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstring fileName = SanitizeFileName(name);\n\t\t\t\t\t\t\t\tstring dirName = Path.GetDirectoryName(fileName);\n\t\t\t\t\t\t\t\tif (!string.IsNullOrEmpty(dirName) && directories.Add(dirName))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tCreateDirectory(Path.Combine(TargetDirectory, dirName));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tStream entryStream = (Stream)value;\n\t\t\t\t\t\t\t\tentryStream.Position = 0;\n\t\t\t\t\t\t\t\tindividualResources.AddRange(\n\t\t\t\t\t\t\t\t\tWriteResourceToFile(fileName, name, entryStream));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tdecodedIntoIndividualFiles = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdecodedIntoIndividualFiles = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t{\n\t\t\t\t\t\tdecodedIntoIndividualFiles = false;\n\t\t\t\t\t}\n\t\t\t\t\tcatch (EndOfStreamException)\n\t\t\t\t\t{\n\t\t\t\t\t\tdecodedIntoIndividualFiles = false;\n\t\t\t\t\t}\n\t\t\t\t\tif (decodedIntoIndividualFiles)\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var entry in individualResources)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tyield return entry;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tstream.Position = 0;\n\t\t\t\t\t\tstring fileName = GetFileNameForResource(r.Name);\n\t\t\t\t\t\tforeach (var entry in WriteResourceToFile(fileName, r.Name, stream))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tyield return entry;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tstring fileName = GetFileNameForResource(r.Name);\n\t\t\t\t\tusing (FileStream fs = new FileStream(Path.Combine(TargetDirectory, fileName), FileMode.Create, FileAccess.Write))\n\t\t\t\t\t{\n\t\t\t\t\t\tstream.Position = 0;\n\t\t\t\t\t\tstream.CopyTo(fs);\n\t\t\t\t\t}\n\t\t\t\t\tyield return new ProjectItemInfo(\"EmbeddedResource\", fileName).With(\"LogicalName\", r.Name);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual IEnumerable<ProjectItemInfo> WriteResourceToFile(string fileName, string resourceName, Stream entryStream)\n\t\t{\n\t\t\tif (fileName.EndsWith(\".resources\", StringComparison.OrdinalIgnoreCase))\n\t\t\t{\n\t\t\t\tstring resx = Path.ChangeExtension(fileName, \".resx\");\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tusing (FileStream fs = new FileStream(Path.Combine(TargetDirectory, resx), FileMode.Create, FileAccess.Write))\n\t\t\t\t\tusing (ResXResourceWriter writer = new ResXResourceWriter(fs))\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var entry in new ResourcesFile(entryStream))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\twriter.AddResource(entry.Key, entry.Value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn new[] { new ProjectItemInfo(\"EmbeddedResource\", resx).With(\"LogicalName\", resourceName) };\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\t// if the .resources can't be decoded, just save them as-is\n\t\t\t\t}\n\t\t\t\tcatch (EndOfStreamException)\n\t\t\t\t{\n\t\t\t\t\t// if the .resources can't be decoded, just save them as-is\n\t\t\t\t}\n\t\t\t}\n\t\t\tusing (FileStream fs = new FileStream(Path.Combine(TargetDirectory, fileName), FileMode.Create, FileAccess.Write))\n\t\t\t{\n\t\t\t\tentryStream.CopyTo(fs);\n\t\t\t}\n\t\t\treturn new[] { new ProjectItemInfo(\"EmbeddedResource\", fileName).With(\"LogicalName\", resourceName) };\n\t\t}\n\n\t\tstring GetFileNameForResource(string fullName)\n\t\t{\n\t\t\t// Clean up the name first and ensure the length does not exceed the maximum length\n\t\t\t// supported by the OS.\n\t\t\tfullName = SanitizeFileName(fullName);\n\t\t\t// The purpose of the below algorithm is to \"maximize\" the directory name and \"minimize\" the file name.\n\t\t\t// That is, a full name of the form \"Namespace1.Namespace2{...}.NamespaceN.ResourceName\" is split such that\n\t\t\t// the directory part Namespace1\\Namespace2\\... reuses as many existing directories as\n\t\t\t// possible, and only the remaining name parts are used as prefix for the filename.\n\t\t\t// This is not affected by the UseNestedDirectoriesForNamespaces setting.\n\t\t\tstring[] splitName = fullName.Split('\\\\', '/');\n\t\t\tstring fileName = string.Join(\".\", splitName);\n\t\t\tstring separator = Path.DirectorySeparatorChar.ToString();\n\t\t\tfor (int i = splitName.Length - 1; i > 0; i--)\n\t\t\t{\n\t\t\t\tstring ns = string.Join(separator, splitName, 0, i);\n\t\t\t\tif (directories.Contains(ns))\n\t\t\t\t{\n\t\t\t\t\tstring name = string.Join(\".\", splitName, i, splitName.Length - i);\n\t\t\t\t\tfileName = Path.Combine(ns, name);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn fileName;\n\t\t}\n\t\t#endregion\n\n\t\t#region WriteMiscellaneousFilesInProject\n\t\tprotected virtual IEnumerable<ProjectItemInfo> WriteMiscellaneousFilesInProject(PEFile module)\n\t\t{\n\t\t\tvar resources = module.Reader.ReadWin32Resources();\n\t\t\tif (resources == null)\n\t\t\t\tyield break;\n\n\t\t\tbyte[] appIcon = CreateApplicationIcon(resources);\n\t\t\tif (appIcon != null)\n\t\t\t{\n\t\t\t\tFile.WriteAllBytes(Path.Combine(TargetDirectory, \"app.ico\"), appIcon);\n\t\t\t\tyield return new ProjectItemInfo(\"ApplicationIcon\", \"app.ico\");\n\t\t\t}\n\n\t\t\tbyte[] appManifest = CreateApplicationManifest(resources);\n\t\t\tif (appManifest != null && !IsDefaultApplicationManifest(appManifest))\n\t\t\t{\n\t\t\t\tFile.WriteAllBytes(Path.Combine(TargetDirectory, \"app.manifest\"), appManifest);\n\t\t\t\tyield return new ProjectItemInfo(\"ApplicationManifest\", \"app.manifest\");\n\t\t\t}\n\n\t\t\tvar appConfig = module.FileName + \".config\";\n\t\t\tif (File.Exists(appConfig))\n\t\t\t{\n\t\t\t\tFile.Copy(appConfig, Path.Combine(TargetDirectory, \"app.config\"), overwrite: true);\n\t\t\t\tyield return new ProjectItemInfo(\"ApplicationConfig\", Path.GetFileName(appConfig));\n\t\t\t}\n\t\t}\n\n\t\tconst int RT_ICON = 3;\n\t\tconst int RT_GROUP_ICON = 14;\n\n\t\tunsafe static byte[] CreateApplicationIcon(Win32ResourceDirectory resources)\n\t\t{\n\t\t\tvar iconGroup = resources.Find(new Win32ResourceName(RT_GROUP_ICON))?.FirstDirectory()?.FirstData()?.Data;\n\t\t\tif (iconGroup == null)\n\t\t\t\treturn null;\n\n\t\t\tvar iconDir = resources.Find(new Win32ResourceName(RT_ICON));\n\t\t\tif (iconDir == null)\n\t\t\t\treturn null;\n\n\t\t\tusing var outStream = new MemoryStream();\n\t\t\tusing var writer = new BinaryWriter(outStream);\n\t\t\tfixed (byte* pIconGroupData = iconGroup)\n\t\t\t{\n\t\t\t\tvar pIconGroup = (GRPICONDIR*)pIconGroupData;\n\t\t\t\twriter.Write(pIconGroup->idReserved);\n\t\t\t\twriter.Write(pIconGroup->idType);\n\t\t\t\twriter.Write(pIconGroup->idCount);\n\n\t\t\t\tint iconCount = pIconGroup->idCount;\n\t\t\t\tuint offset = (2 * 3) + ((uint)iconCount * 0x10);\n\t\t\t\tfor (int i = 0; i < iconCount; i++)\n\t\t\t\t{\n\t\t\t\t\tvar pIconEntry = pIconGroup->idEntries + i;\n\t\t\t\t\twriter.Write(pIconEntry->bWidth);\n\t\t\t\t\twriter.Write(pIconEntry->bHeight);\n\t\t\t\t\twriter.Write(pIconEntry->bColorCount);\n\t\t\t\t\twriter.Write(pIconEntry->bReserved);\n\t\t\t\t\twriter.Write(pIconEntry->wPlanes);\n\t\t\t\t\twriter.Write(pIconEntry->wBitCount);\n\t\t\t\t\twriter.Write(pIconEntry->dwBytesInRes);\n\t\t\t\t\twriter.Write(offset);\n\t\t\t\t\toffset += pIconEntry->dwBytesInRes;\n\t\t\t\t}\n\n\t\t\t\tfor (int i = 0; i < iconCount; i++)\n\t\t\t\t{\n\t\t\t\t\tvar icon = iconDir.FindDirectory(new Win32ResourceName(pIconGroup->idEntries[i].nID))?.FirstData()?.Data;\n\t\t\t\t\tif (icon == null)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\twriter.Write(icon);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn outStream.ToArray();\n\t\t}\n\n\t\t[StructLayout(LayoutKind.Sequential, Pack = 2)]\n\t\tunsafe struct GRPICONDIR\n\t\t{\n\t\t\tpublic ushort idReserved;\n\t\t\tpublic ushort idType;\n\t\t\tpublic ushort idCount;\n\t\t\tprivate fixed byte _idEntries[1];\n\t\t\t[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Style\", \"IDE1006:Naming Styles\", Justification = \"<Pending>\")]\n\t\t\tpublic GRPICONDIRENTRY* idEntries {\n\t\t\t\tget {\n\t\t\t\t\tfixed (byte* p = _idEntries)\n\t\t\t\t\t\treturn (GRPICONDIRENTRY*)p;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t[StructLayout(LayoutKind.Sequential, Pack = 2)]\n\t\tstruct GRPICONDIRENTRY\n\t\t{\n\t\t\tpublic byte bWidth;\n\t\t\tpublic byte bHeight;\n\t\t\tpublic byte bColorCount;\n\t\t\tpublic byte bReserved;\n\t\t\tpublic ushort wPlanes;\n\t\t\tpublic ushort wBitCount;\n\t\t\tpublic uint dwBytesInRes;\n\t\t\tpublic short nID;\n\t\t};\n\n\t\tconst int RT_MANIFEST = 24;\n\n\t\tunsafe static byte[] CreateApplicationManifest(Win32ResourceDirectory resources)\n\t\t{\n\t\t\treturn resources.Find(new Win32ResourceName(RT_MANIFEST))?.FirstDirectory()?.FirstData()?.Data;\n\t\t}\n\n\t\tstatic bool IsDefaultApplicationManifest(byte[] appManifest)\n\t\t{\n\t\t\tconst string DEFAULT_APPMANIFEST =\n\t\t\t\t\"<?xmlversion=\\\"1.0\\\"encoding=\\\"UTF-8\\\"standalone=\\\"yes\\\"?><assemblyxmlns=\\\"urn:schemas-microsoft-com\" +\n\t\t\t\t\":asm.v1\\\"manifestVersion=\\\"1.0\\\"><assemblyIdentityversion=\\\"1.0.0.0\\\"name=\\\"MyApplication.app\\\"/><tr\" +\n\t\t\t\t\"ustInfoxmlns=\\\"urn:schemas-microsoft-com:asm.v2\\\"><security><requestedPrivilegesxmlns=\\\"urn:schemas-\" +\n\t\t\t\t\"microsoft-com:asm.v3\\\"><requestedExecutionLevellevel=\\\"asInvoker\\\"uiAccess=\\\"false\\\"/></requestedPri\" +\n\t\t\t\t\"vileges></security></trustInfo></assembly>\";\n\n\t\t\tstring s = CleanUpApplicationManifest(appManifest);\n\t\t\treturn s == DEFAULT_APPMANIFEST;\n\t\t}\n\n\t\tstatic string CleanUpApplicationManifest(byte[] appManifest)\n\t\t{\n\t\t\tbool bom = appManifest.Length >= 3 && appManifest[0] == 0xEF && appManifest[1] == 0xBB && appManifest[2] == 0xBF;\n\t\t\tstring s = Encoding.UTF8.GetString(appManifest, bom ? 3 : 0, appManifest.Length - (bom ? 3 : 0));\n\t\t\tvar sb = new StringBuilder(s.Length);\n\t\t\tfor (int i = 0; i < s.Length; i++)\n\t\t\t{\n\t\t\t\tchar c = s[i];\n\t\t\t\tswitch (c)\n\t\t\t\t{\n\t\t\t\t\tcase '\\t':\n\t\t\t\t\tcase '\\n':\n\t\t\t\t\tcase '\\r':\n\t\t\t\t\tcase ' ':\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tsb.Append(c);\n\t\t\t}\n\t\t\treturn sb.ToString();\n\t\t}\n\t\t#endregion\n\n\t\t/// <summary>\n\t\t/// Cleans up a node name for use as a file name.\n\t\t/// </summary>\n\t\tpublic static string CleanUpFileName(string text, string extension)\n\t\t{\n\t\t\tDebug.Assert(!string.IsNullOrEmpty(extension));\n\t\t\tif (!extension.StartsWith(\".\"))\n\t\t\t\textension = \".\" + extension;\n\t\t\ttext = text + extension;\n\n\t\t\treturn CleanUpName(text, separateAtDots: false, treatAsFileName: !string.IsNullOrEmpty(extension), treatAsPath: false);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Removes invalid characters from file names and reduces their length,\n\t\t/// but keeps file extensions and path structure intact.\n\t\t/// </summary>\n\t\tpublic static string SanitizeFileName(string fileName)\n\t\t{\n\t\t\treturn CleanUpName(fileName, separateAtDots: false, treatAsFileName: true, treatAsPath: true);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Cleans up a node name for use as a file system name. If <paramref name=\"separateAtDots\"/> is active,\n\t\t/// dots are seen as segment separators. Each segment is limited to maxSegmentLength characters.\n\t\t/// If <paramref name=\"treatAsFileName\"/> is active, we check for file a extension and try to preserve it,\n\t\t/// if it's valid.\n\t\t/// </summary>\n\t\tstatic string CleanUpName(string text, bool separateAtDots, bool treatAsFileName, bool treatAsPath)\n\t\t{\n\t\t\tstring extension = null;\n\t\t\tint currentSegmentLength = 0;\n\t\t\t// Extract extension from the end of the name, if valid\n\t\t\tif (treatAsFileName)\n\t\t\t{\n\t\t\t\t// Check if input is a file name, i.e., has a valid extension\n\t\t\t\t// If yes, preserve extension and append it at the end.\n\t\t\t\t// But only, if the extension length does not exceed maxSegmentLength,\n\t\t\t\t// if that's the case we just give up and treat the extension no different\n\t\t\t\t// from the file name.\n\t\t\t\tint lastDot = text.LastIndexOf('.');\n\t\t\t\tif (lastDot >= 0 && text.Length - lastDot < maxSegmentLength)\n\t\t\t\t{\n\t\t\t\t\tstring originalText = text;\n\t\t\t\t\textension = text.Substring(lastDot);\n\t\t\t\t\ttext = text.Remove(lastDot);\n\t\t\t\t\tforeach (var c in extension)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!(char.IsLetterOrDigit(c) || c == '-' || c == '_' || c == '.'))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// extension contains an invalid character, therefore cannot be a valid extension.\n\t\t\t\t\t\t\textension = null;\n\t\t\t\t\t\t\ttext = originalText;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Remove anything that could be confused with a rooted path.\n\t\t\tint pos = text.IndexOf(':');\n\t\t\tif (pos > 0)\n\t\t\t\ttext = text.Substring(0, pos);\n\t\t\ttext = text.Trim();\n\t\t\t// Remove generics\n\t\t\tpos = text.IndexOf('`');\n\t\t\tif (pos > 0)\n\t\t\t{\n\t\t\t\ttext = text.Substring(0, pos).Trim();\n\t\t\t}\n\t\t\t// Whitelist allowed characters, replace everything else:\n\t\t\tStringBuilder b = new StringBuilder(text.Length + (extension?.Length ?? 0));\n\t\t\tbool countBytes = !RuntimeInformation.IsOSPlatform(OSPlatform.Windows);\n\t\t\tforeach (var c in text)\n\t\t\t{\n\t\t\t\tif (char.IsLetterOrDigit(c) || c == '-' || c == '_')\n\t\t\t\t{\n\t\t\t\t\tunsafe\n\t\t\t\t\t{\n\t\t\t\t\t\tcurrentSegmentLength += countBytes ? Encoding.UTF8.GetByteCount(&c, 1) : 1;\n\t\t\t\t\t}\n\t\t\t\t\t// if the current segment exceeds maxSegmentLength characters,\n\t\t\t\t\t// skip until the end of the segment.\n\t\t\t\t\tif (currentSegmentLength <= maxSegmentLength)\n\t\t\t\t\t\tb.Append(c);\n\t\t\t\t}\n\t\t\t\telse if (c == '.' && b.Length > 0 && b[^1] != '.')\n\t\t\t\t{\n\t\t\t\t\tcurrentSegmentLength++;\n\t\t\t\t\t// if the current segment exceeds maxSegmentLength characters,\n\t\t\t\t\t// skip until the end of the segment.\n\t\t\t\t\tif (separateAtDots || currentSegmentLength <= maxSegmentLength)\n\t\t\t\t\t\tb.Append('.'); // allow dot, but never two in a row\n\n\t\t\t\t\t// Reset length at end of segment.\n\t\t\t\t\tif (separateAtDots)\n\t\t\t\t\t\tcurrentSegmentLength = 0;\n\t\t\t\t}\n\t\t\t\telse if (treatAsPath && (c is '/' or '\\\\') && currentSegmentLength > 0)\n\t\t\t\t{\n\t\t\t\t\t// if we treat this as a file name, we've started a new segment\n\t\t\t\t\tb.Append(Path.DirectorySeparatorChar);\n\t\t\t\t\tcurrentSegmentLength = 0;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (char.IsHighSurrogate(c))\n\t\t\t\t\t{\n\t\t\t\t\t\t// only add one replacement character for surrogate pairs\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tcurrentSegmentLength++;\n\t\t\t\t\t// if the current segment exceeds maxSegmentLength characters,\n\t\t\t\t\t// skip until the end of the segment.\n\t\t\t\t\tif (currentSegmentLength <= maxSegmentLength)\n\t\t\t\t\t\tb.Append('-');\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (b.Length == 0)\n\t\t\t\tb.Append('-');\n\t\t\tstring name = b.ToString();\n\t\t\tif (extension != null)\n\t\t\t{\n\t\t\t\t// make sure that adding the extension to the filename\n\t\t\t\t// does not exceed maxSegmentLength.\n\t\t\t\t// trim the name, if necessary.\n\t\t\t\tif (name.Length + extension.Length > maxSegmentLength)\n\t\t\t\t\tname = name.Remove(name.Length - extension.Length);\n\t\t\t\tname += extension;\n\t\t\t}\n\n\t\t\tif (IsReservedFileSystemName(name))\n\t\t\t\treturn name + \"_\";\n\t\t\telse if (name == \".\")\n\t\t\t\treturn \"_\";\n\t\t\telse\n\t\t\t\treturn name;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Cleans up a node name for use as a directory name.\n\t\t/// </summary>\n\t\tpublic static string CleanUpDirectoryName(string text)\n\t\t{\n\t\t\treturn CleanUpName(text, separateAtDots: false, treatAsFileName: false, treatAsPath: false);\n\t\t}\n\n\t\tpublic static string CleanUpPath(string text)\n\t\t{\n\t\t\treturn CleanUpName(text, separateAtDots: true, treatAsFileName: false, treatAsPath: true)\n\t\t\t\t.Replace('.', Path.DirectorySeparatorChar);\n\t\t}\n\n\t\tstatic bool IsReservedFileSystemName(string name)\n\t\t{\n\t\t\tswitch (name.ToUpperInvariant())\n\t\t\t{\n\t\t\t\tcase \"AUX\":\n\t\t\t\tcase \"COM1\":\n\t\t\t\tcase \"COM2\":\n\t\t\t\tcase \"COM3\":\n\t\t\t\tcase \"COM4\":\n\t\t\t\tcase \"COM5\":\n\t\t\t\tcase \"COM6\":\n\t\t\t\tcase \"COM7\":\n\t\t\t\tcase \"COM8\":\n\t\t\t\tcase \"COM9\":\n\t\t\t\tcase \"CON\":\n\t\t\t\tcase \"LPT1\":\n\t\t\t\tcase \"LPT2\":\n\t\t\t\tcase \"LPT3\":\n\t\t\t\tcase \"LPT4\":\n\t\t\t\tcase \"LPT5\":\n\t\t\t\tcase \"LPT6\":\n\t\t\t\tcase \"LPT7\":\n\t\t\t\tcase \"LPT8\":\n\t\t\t\tcase \"LPT9\":\n\t\t\t\tcase \"NUL\":\n\t\t\t\tcase \"PRN\":\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic static bool CanUseSdkStyleProjectFormat(MetadataFile module)\n\t\t{\n\t\t\treturn TargetServices.DetectTargetFramework(module).Moniker != null;\n\t\t}\n\t}\n\n\tpublic record struct ProjectItemInfo(string ItemType, string FileName)\n\t{\n\t\tpublic List<PartialTypeInfo> PartialTypes { get; set; } = null;\n\n\t\tpublic Dictionary<string, string> AdditionalProperties { get; set; } = null;\n\n\t\tpublic ProjectItemInfo With(string name, string value)\n\t\t{\n\t\t\tAdditionalProperties ??= new Dictionary<string, string>();\n\t\t\tAdditionalProperties.Add(name, value);\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic ProjectItemInfo With(IEnumerable<KeyValuePair<string, string>> pairs)\n\t\t{\n\t\t\tAdditionalProperties ??= new Dictionary<string, string>();\n\t\t\tAdditionalProperties.AddRange(pairs);\n\t\t\treturn this;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/RecordDecompiler.cs",
    "content": "// Copyright (c) 2020 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp\n{\n\tclass RecordDecompiler\n\t{\n\t\treadonly IDecompilerTypeSystem typeSystem;\n\t\treadonly ITypeDefinition recordTypeDef;\n\t\treadonly DecompilerSettings settings;\n\t\treadonly CancellationToken cancellationToken;\n\t\treadonly List<IMember> orderedMembers;\n\t\treadonly bool isInheritedRecord;\n\t\treadonly bool isStruct;\n\t\treadonly bool isSealed;\n\t\treadonly IMethod? primaryCtor;\n\t\treadonly IType? baseClass;\n\t\treadonly Dictionary<IField, IProperty> backingFieldToAutoProperty = new Dictionary<IField, IProperty>();\n\t\treadonly Dictionary<IProperty, IField> autoPropertyToBackingField = new Dictionary<IProperty, IField>();\n\t\treadonly Dictionary<IParameter, IProperty> primaryCtorParameterToAutoProperty = new Dictionary<IParameter, IProperty>();\n\t\treadonly Dictionary<IProperty, IParameter> autoPropertyToPrimaryCtorParameter = new Dictionary<IProperty, IParameter>();\n\n\t\tpublic RecordDecompiler(IDecompilerTypeSystem dts, ITypeDefinition recordTypeDef, DecompilerSettings settings, CancellationToken cancellationToken)\n\t\t{\n\t\t\tthis.typeSystem = dts;\n\t\t\tthis.recordTypeDef = recordTypeDef;\n\t\t\tthis.settings = settings;\n\t\t\tthis.cancellationToken = cancellationToken;\n\t\t\tthis.baseClass = recordTypeDef.DirectBaseTypes.FirstOrDefault(b => b.Kind == TypeKind.Class);\n\t\t\tthis.isStruct = baseClass?.IsKnownType(KnownTypeCode.ValueType) ?? false;\n\t\t\tthis.isInheritedRecord = !isStruct && !(baseClass?.IsKnownType(KnownTypeCode.Object) ?? false);\n\t\t\tthis.isSealed = recordTypeDef.IsSealed;\n\t\t\tDetectAutomaticProperties();\n\t\t\tthis.orderedMembers = DetectMemberOrder(recordTypeDef, backingFieldToAutoProperty);\n\t\t\tthis.primaryCtor = DetectPrimaryConstructor();\n\t\t}\n\n\t\tvoid DetectAutomaticProperties()\n\t\t{\n\t\t\tvar subst = recordTypeDef.AsParameterizedType().GetSubstitution();\n\t\t\tforeach (var property in recordTypeDef.Properties)\n\t\t\t{\n\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tvar p = (IProperty)property.Specialize(subst);\n\t\t\t\tif (IsAutoProperty(p, out var field))\n\t\t\t\t{\n\t\t\t\t\tbackingFieldToAutoProperty.Add(field, p);\n\t\t\t\t\tautoPropertyToBackingField.Add(p, field);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool IsAutoProperty(IProperty p, [NotNullWhen(true)] out IField? field)\n\t\t\t{\n\t\t\t\tfield = null;\n\t\t\t\tif (p.IsStatic)\n\t\t\t\t\treturn false;\n\t\t\t\tif (p.Parameters.Count != 0)\n\t\t\t\t\treturn false;\n\t\t\t\tif (p.Getter != null)\n\t\t\t\t{\n\t\t\t\t\tif (!IsAutoGetter(p.Getter, out field))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (p.Setter != null)\n\t\t\t\t{\n\t\t\t\t\tif (!IsAutoSetter(p.Setter, out var field2))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (field != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!field.Equals(field2))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tfield = field2;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (field == null)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!IsRecordType(field.DeclaringType))\n\t\t\t\t\treturn false;\n\t\t\t\treturn field.Name == $\"<{p.Name}>k__BackingField\";\n\t\t\t}\n\n\t\t\tbool IsAutoGetter(IMethod method, [NotNullWhen(true)] out IField? field)\n\t\t\t{\n\t\t\t\tfield = null;\n\t\t\t\tvar body = DecompileBody(method);\n\t\t\t\tif (body == null)\n\t\t\t\t\treturn false;\n\t\t\t\t// return this.field;\n\t\t\t\tif (!body.Instructions[0].MatchReturn(out var retVal))\n\t\t\t\t\treturn false;\n\t\t\t\tif (method.IsStatic)\n\t\t\t\t{\n\t\t\t\t\treturn retVal.MatchLdsFld(out field);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (!retVal.MatchLdFld(out var target, out field))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn target.MatchLdThis();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool IsAutoSetter(IMethod method, [NotNullWhen(true)] out IField? field)\n\t\t\t{\n\t\t\t\tfield = null;\n\t\t\t\tDebug.Assert(!method.IsStatic);\n\t\t\t\tvar body = DecompileBody(method);\n\t\t\t\tif (body == null)\n\t\t\t\t\treturn false;\n\t\t\t\t// this.field = value;\n\t\t\t\tILInstruction? valueInst;\n\t\t\t\tif (method.IsStatic)\n\t\t\t\t{\n\t\t\t\t\tif (!body.Instructions[0].MatchStsFld(out field, out valueInst))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (!body.Instructions[0].MatchStFld(out var target, out field, out valueInst))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!target.MatchLdThis())\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (!valueInst.MatchLdLoc(out var value))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(value.Kind == VariableKind.Parameter && value.Index == 0))\n\t\t\t\t\treturn false;\n\t\t\t\treturn body.Instructions[1].MatchReturn(out var retVal) && retVal.MatchNop();\n\t\t\t}\n\t\t}\n\n\t\tIMethod? DetectPrimaryConstructor()\n\t\t{\n\t\t\tDebug.Assert(recordTypeDef.IsRecord);\n\t\t\tif (!settings.UsePrimaryConstructorSyntax)\n\t\t\t\treturn null;\n\n\t\t\tvar subst = recordTypeDef.AsParameterizedType().GetSubstitution();\n\n\t\t\tDictionary<string, IMember> nameToMemberMap = new Dictionary<string, IMember>(StringComparer.Ordinal);\n\t\t\tDictionary<IMethod, IMethod?> ctorChainMap = new Dictionary<IMethod, IMethod?>();\n\n\t\t\tforeach (IMember m in recordTypeDef.GetMembers(m => m.SymbolKind is SymbolKind.Property or SymbolKind.Field, GetMemberOptions.ReturnMemberDefinitions))\n\t\t\t{\n\t\t\t\tnameToMemberMap[m.Name] = m;\n\t\t\t}\n\n\t\t\tIMethod? guessedPrimaryCtor = null;\n\n\t\t\tforeach (var method in recordTypeDef.Methods)\n\t\t\t{\n\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tif (method.IsStatic || !method.IsConstructor)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (IsCopyConstructor(method))\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tvar body = DecompileBody(method);\n\t\t\t\tif (body == null)\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tIMethod? chainedCtor = (IMethod?)FindChainedCtor(body)?.MemberDefinition;\n\t\t\t\tctorChainMap[method] = chainedCtor;\n\n\t\t\t\tif (chainedCtor != null && chainedCtor.DeclaringTypeDefinition!.Equals(recordTypeDef))\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tvar m = method.Specialize(subst);\n\t\t\t\tif (IsPrimaryConstructor(body, m, method))\n\t\t\t\t{\n\t\t\t\t\tif (guessedPrimaryCtor == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tguessedPrimaryCtor = method;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// Multiple primary constructor candidates found - give up\n\t\t\t\t\t\tguessedPrimaryCtor = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (guessedPrimaryCtor != null)\n\t\t\t{\n\t\t\t\tforeach (var (source, target) in ctorChainMap)\n\t\t\t\t{\n\t\t\t\t\tif (guessedPrimaryCtor.Equals(source))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t// in a record with a primary ctor every other ctor must call the primary ctor\n\t\t\t\t\t// at the end of the ctor chain.\n\t\t\t\t\t// if the target is null or a ctor of another type, we found a ctor that does not\n\t\t\t\t\t// follow this rule.\n\t\t\t\t\t// we don't have to check the full chain, because the C# compiler enforces that\n\t\t\t\t\t// there are no loops in the ctor call graph.\n\t\t\t\t\tif (target == null || !target.DeclaringTypeDefinition!.Equals(recordTypeDef))\n\t\t\t\t\t{\n\t\t\t\t\t\tguessedPrimaryCtor = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (guessedPrimaryCtor == null)\n\t\t\t{\n\t\t\t\tprimaryCtorParameterToAutoProperty.Clear();\n\t\t\t}\n\n\t\t\tforeach (var (parameter, property) in primaryCtorParameterToAutoProperty.ToArray())\n\t\t\t{\n\t\t\t\tif (!parameter.Owner!.Equals(guessedPrimaryCtor))\n\t\t\t\t{\n\t\t\t\t\tprimaryCtorParameterToAutoProperty.Remove(parameter);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tautoPropertyToPrimaryCtorParameter.Add(property, parameter);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn guessedPrimaryCtor;\n\n\t\t\tbool IsPrimaryConstructor(Block body, IMethod method, IMethod unspecializedMethod)\n\t\t\t{\n\t\t\t\tforeach (IParameter p in unspecializedMethod.Parameters)\n\t\t\t\t{\n\t\t\t\t\t// ref and out are not valid modifiers in this context\n\t\t\t\t\tif (p.ReferenceKind is ReferenceKind.Ref or ReferenceKind.Out)\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\t// for each positional parameter there must be a field or property of the same name and type\n\t\t\t\t\tif (!nameToMemberMap.TryGetValue(p.Name, out var member))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tvar paramType = p.ReferenceKind != ReferenceKind.None ? p.Type.UnwrapByRef() : p.Type;\n\t\t\t\t\tif (!NormalizeTypeVisitor.TypeErasure.EquivalentTypes(paramType, member.ReturnType))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (!isStruct)\n\t\t\t\t{\n\t\t\t\t\tif (body.Instructions.SecondToLastOrDefault() is not CallInstruction baseCtorCall)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tvar baseCtor = baseCtorCall.Method;\n\t\t\t\t\tif (!baseCtor.IsConstructor)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (baseCtor.DeclaringType.Equals(method.DeclaringType))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tvar addonInst = isStruct ? 1 : 2;\n\n\t\t\t\tif (body.Instructions.Count < addonInst)\n\t\t\t\t\treturn false;\n\n\t\t\t\tint parameterIndex = 0;\n\n\t\t\t\tfor (int i = 0; i < body.Instructions.Count - addonInst; i++)\n\t\t\t\t{\n\t\t\t\t\tif (!body.Instructions[i].MatchStFld(out var target, out var field, out var valueInst))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!target.MatchLdThis())\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t// allow assignments to fields that are not backing fields of auto-properties\n\t\t\t\t\tif (!backingFieldToAutoProperty.TryGetValue(field, out var property))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tif (valueInst.MatchLdLoc(out var v))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!ValidateParameter(v, parameterIndex))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tparameterIndex = v.Index!.Value;\n\t\t\t\t\t}\n\t\t\t\t\telse if (valueInst.MatchLdObj(out valueInst, out _) && valueInst.MatchLdLoc(out v))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!ValidateParameter(v, parameterIndex))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tparameterIndex = v.Index!.Value;\n\t\t\t\t\t\tif (method.Parameters[parameterIndex].ReferenceKind is ReferenceKind.None)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tIParameter parameter = unspecializedMethod.Parameters[parameterIndex];\n\t\t\t\t\tif (primaryCtorParameterToAutoProperty.ContainsKey(parameter))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (recordTypeDef.Kind != TypeKind.Struct)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!(property.CanSet && property.Setter.IsInitOnly))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tprimaryCtorParameterToAutoProperty.Add(parameter, property);\n\t\t\t\t}\n\n\t\t\t\tvar returnInst = body.Instructions.LastOrDefault();\n\t\t\t\treturn returnInst != null && returnInst.MatchReturn(out var retVal) && retVal.MatchNop();\n\n\t\t\t\tbool ValidateParameter(ILVariable v, int expectedMinimumIndex)\n\t\t\t\t{\n\t\t\t\t\tif (v.Kind != VariableKind.Parameter)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tDebug.Assert(v.Index.HasValue);\n\t\t\t\t\tif (v.Index < 0 || v.Index >= unspecializedMethod.Parameters.Count)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tvar parameter = unspecializedMethod.Parameters[v.Index.Value];\n\t\t\t\t\tif (primaryCtorParameterToAutoProperty.ContainsKey(parameter))\n\t\t\t\t\t\treturn true;\n\t\t\t\t\treturn v.Index >= expectedMinimumIndex;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tIMethod? FindChainedCtor(Block body)\n\t\t\t{\n\t\t\t\t// look for a call instruction or assignment to a chained constructor\n\t\t\t\tforeach (var inst in body.Instructions)\n\t\t\t\t{\n\t\t\t\t\tswitch (inst)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase Call { Method: { IsConstructor: true } ctor }:\n\t\t\t\t\t\t\treturn ctor;\n\t\t\t\t\t\tcase StObj { Value: NewObj { Method: var ctor } } stObj when stObj.Target.MatchLdThis():\n\t\t\t\t\t\t\treturn ctor;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tstatic List<IMember> DetectMemberOrder(ITypeDefinition recordTypeDef, Dictionary<IField, IProperty> backingFieldToAutoProperty)\n\t\t{\n\t\t\t// For records, the order of members is important:\n\t\t\t// Equals/GetHashCode/PrintMembers must agree on an order of fields+properties.\n\t\t\t// The IL metadata has the order of fields and the order of properties, but we\n\t\t\t// need to detect the correct interleaving.\n\t\t\t// We could try to detect this from the PrintMembers body, but let's initially\n\t\t\t// restrict ourselves to the common case where the record only uses properties.\n\t\t\tvar subst = recordTypeDef.AsParameterizedType().GetSubstitution();\n\t\t\treturn recordTypeDef.Properties.Select(p => p.Specialize(subst)).Concat(\n\t\t\t\trecordTypeDef.Fields.Select(f => (IField)f.Specialize(subst)).Where(f => !backingFieldToAutoProperty.ContainsKey(f))\n\t\t\t).ToList();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the fields and properties of the record type, interleaved as necessary to\n\t\t/// maintain Equals/ToString/etc. semantics.\n\t\t/// </summary>\n\t\tpublic IEnumerable<IMember> FieldsAndProperties => orderedMembers;\n\n\t\t/// <summary>\n\t\t/// Gets the detected primary constructor. Returns null, if there was no primary constructor detected.\n\t\t/// </summary>\n\t\tpublic IMethod? PrimaryConstructor => primaryCtor;\n\n\t\tpublic bool IsInheritedRecord => isInheritedRecord;\n\n\t\tbool IsRecordType(IType type)\n\t\t{\n\t\t\treturn type.GetDefinition() == recordTypeDef\n\t\t\t\t&& type.TypeArguments.SequenceEqual(recordTypeDef.TypeParameters);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the member of the record type will be automatically generated by the compiler.\n\t\t/// </summary>\n\t\tpublic bool MethodIsGenerated(IMethod method)\n\t\t{\n\t\t\tif (IsCopyConstructor(method))\n\t\t\t{\n\t\t\t\treturn IsGeneratedCopyConstructor(method);\n\t\t\t}\n\n\t\t\tswitch (method.Name)\n\t\t\t{\n\t\t\t\t// Some members in records are always compiler-generated and lead to a\n\t\t\t\t// \"duplicate definition\" error if we emit the generated code.\n\t\t\t\tcase \"op_Equality\":\n\t\t\t\tcase \"op_Inequality\":\n\t\t\t\t{\n\t\t\t\t\t// Don't emit comparison operators into C# record definition\n\t\t\t\t\t// Note: user can declare additional operator== as long as they have\n\t\t\t\t\t// different parameter types.\n\t\t\t\t\treturn method.Parameters.Count == 2\n\t\t\t\t\t\t&& method.Parameters.All(p => IsRecordType(p.Type));\n\t\t\t\t}\n\t\t\t\tcase \"Equals\" when method.Parameters.Count == 1:\n\t\t\t\t{\n\t\t\t\t\tIType paramType = method.Parameters[0].Type;\n\t\t\t\t\tif (paramType.IsKnownType(KnownTypeCode.Object) && method.IsOverride)\n\t\t\t\t\t{\n\t\t\t\t\t\t// override bool Equals(object? obj): always generated\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\telse if (IsRecordType(paramType))\n\t\t\t\t\t{\n\t\t\t\t\t\t// virtual bool Equals(R? other): generated unless user-declared\n\t\t\t\t\t\treturn IsGeneratedEquals(method);\n\t\t\t\t\t}\n\t\t\t\t\telse if (isInheritedRecord && baseClass != null && NormalizeTypeVisitor.TypeErasure.EquivalentTypes(paramType, baseClass) && method.IsOverride)\n\t\t\t\t\t{\n\t\t\t\t\t\t// override bool Equals(BaseClass? obj): always generated\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcase \"GetHashCode\":\n\t\t\t\t\treturn IsGeneratedGetHashCode(method);\n\t\t\t\tcase \"<Clone>$\" when method.Parameters.Count == 0:\n\t\t\t\t\t// Always generated; Method name cannot be expressed in C#\n\t\t\t\t\treturn true;\n\t\t\t\tcase \"PrintMembers\":\n\t\t\t\t\treturn IsGeneratedPrintMembers(method);\n\t\t\t\tcase \"ToString\" when method.Parameters.Count == 0:\n\t\t\t\t\treturn IsGeneratedToString(method);\n\t\t\t\tcase \"Deconstruct\" when primaryCtor != null && method.Parameters.Count == primaryCtor.Parameters.Count:\n\t\t\t\t\treturn IsGeneratedDeconstruct(method);\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tinternal bool PropertyIsGenerated(IProperty property)\n\t\t{\n\t\t\tif (!recordTypeDef.IsRecord)\n\t\t\t\treturn false;\n\n\t\t\tswitch (property.Name)\n\t\t\t{\n\t\t\t\tcase \"EqualityContract\" when !isStruct:\n\t\t\t\t\treturn IsGeneratedEqualityContract(property);\n\t\t\t\tdefault:\n\t\t\t\t\treturn IsPropertyDeclaredByPrimaryConstructor(property);\n\t\t\t}\n\t\t}\n\n\t\tpublic bool IsPropertyDeclaredByPrimaryConstructor(IProperty property)\n\t\t{\n\t\t\tvar subst = recordTypeDef.AsParameterizedType().GetSubstitution();\n\t\t\treturn primaryCtor != null\n\t\t\t\t&& autoPropertyToPrimaryCtorParameter.ContainsKey((IProperty)property.Specialize(subst));\n\t\t}\n\n\t\tinternal Dictionary<IParameter, (IProperty?, IField)> GetParameterToBackingStoreMap()\n\t\t{\n\t\t\tvar result = new Dictionary<IParameter, (IProperty?, IField)>();\n\t\t\tforeach (var (parameter, property) in primaryCtorParameterToAutoProperty)\n\t\t\t{\n\t\t\t\tresult.Add(parameter, (property, autoPropertyToBackingField[property]));\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic bool IsCopyConstructor(IMethod method)\n\t\t{\n\t\t\tif (method == null)\n\t\t\t\treturn false;\n\n\t\t\tDebug.Assert(method.DeclaringTypeDefinition == recordTypeDef);\n\n\t\t\treturn method.IsConstructor\n\t\t\t\t&& method.Parameters.Count == 1\n\t\t\t\t&& (recordTypeDef.IsSealed\n\t\t\t\t? (method.Accessibility == Accessibility.Private)\n\t\t\t\t: (method.Accessibility == Accessibility.Protected))\n\t\t\t\t&& IsRecordType(method.Parameters[0].Type);\n\t\t}\n\n\t\tprivate bool IsAllowedAttribute(IAttribute attribute)\n\t\t{\n\t\t\tswitch (attribute.AttributeType.ReflectionName)\n\t\t\t{\n\t\t\t\tcase \"System.Runtime.CompilerServices.CompilerGeneratedAttribute\":\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tprivate bool IsGeneratedCopyConstructor(IMethod method)\n\t\t{\n\t\t\t/* \n\t\t\t\tcall BaseClass..ctor(ldloc this, ldloc original)\n\t\t\t\tstfld <X>k__BackingField(ldloc this, ldfld <X>k__BackingField(ldloc original))\n\t\t\t\tleave IL_0000 (nop)\n\t\t\t */\n\t\t\tDebug.Assert(method.IsConstructor && method.Parameters.Count == 1);\n\t\t\tif (method.GetAttributes().Any(attr => !IsAllowedAttribute(attr)) || method.GetReturnTypeAttributes().Any())\n\t\t\t\treturn false;\n\t\t\tif (method.Accessibility != Accessibility.Protected && (!isSealed || method.Accessibility != Accessibility.Private))\n\t\t\t\treturn false;\n\t\t\tif (orderedMembers == null)\n\t\t\t\treturn false;\n\t\t\tvar body = DecompileBody(method);\n\t\t\tif (body == null)\n\t\t\t\treturn false;\n\t\t\tvar variables = body.Ancestors.OfType<ILFunction>().Single().Variables;\n\t\t\tvar other = variables.Single(v => v.Kind == VariableKind.Parameter && v.Index == 0);\n\t\t\tDebug.Assert(IsRecordType(other.Type));\n\t\t\tint pos = 0;\n\t\t\t// First instruction is the base constructor call\n\t\t\tif (!(body.Instructions[pos] is Call { Method: { IsConstructor: true } } baseCtorCall))\n\t\t\t\treturn false;\n\t\t\tif (!object.Equals(baseCtorCall.Method.DeclaringType, baseClass))\n\t\t\t\treturn false;\n\t\t\tif (baseCtorCall.Arguments.Count != (isInheritedRecord ? 2 : 1))\n\t\t\t\treturn false;\n\t\t\tif (!baseCtorCall.Arguments[0].MatchLdThis())\n\t\t\t\treturn false;\n\t\t\tif (isInheritedRecord)\n\t\t\t{\n\t\t\t\tif (!baseCtorCall.Arguments[1].MatchLdLoc(other))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tpos++;\n\t\t\t// Then all the fields are copied over\n\t\t\tforeach (var member in orderedMembers)\n\t\t\t{\n\t\t\t\tif (member.IsStatic)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (member is not IField field)\n\t\t\t\t{\n\t\t\t\t\tif (!autoPropertyToBackingField.TryGetValue((IProperty)member, out field!))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (pos >= body.Instructions.Count)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!body.Instructions[pos].MatchStFld(out var lhsTarget, out var lhsField, out var valueInst))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!lhsTarget.MatchLdThis())\n\t\t\t\t\treturn false;\n\t\t\t\tif (!lhsField.Equals(field))\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (!valueInst.MatchLdFld(out var rhsTarget, out var rhsField))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!rhsTarget.MatchLdLoc(other))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!rhsField.Equals(field))\n\t\t\t\t\treturn false;\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\treturn body.Instructions[pos] is Leave;\n\t\t}\n\n\t\tprivate bool IsGeneratedEqualityContract(IProperty property)\n\t\t{\n\t\t\t// Generated member:\n\t\t\t// protected virtual Type EqualityContract {\n\t\t\t//    [CompilerGenerated] get => typeof(R);\n\t\t\t// }\n\t\t\tDebug.Assert(!isStruct && property.Name == \"EqualityContract\");\n\t\t\tif (property.Accessibility != Accessibility.Protected && (!isSealed || property.Accessibility != Accessibility.Private))\n\t\t\t\treturn false;\n\t\t\tif (!(isSealed || property.IsVirtual || property.IsOverride))\n\t\t\t\treturn false;\n\t\t\tif (property.IsSealed)\n\t\t\t\treturn false;\n\t\t\tvar getter = property.Getter;\n\t\t\tif (!(getter != null && !property.CanSet))\n\t\t\t\treturn false;\n\t\t\tvar attrs = property.GetAttributes().ToList();\n\t\t\tswitch (attrs.Count)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\t// Roslyn 3.x does not emit a CompilerGeneratedAttribute on the property itself.\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\t// Roslyn 4.4 started doing so.\n\t\t\t\t\tif (!attrs[0].AttributeType.IsKnownType(KnownAttribute.CompilerGenerated))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (getter.GetReturnTypeAttributes().Any())\n\t\t\t\treturn false;\n\t\t\tattrs = getter.GetAttributes().ToList();\n\t\t\tif (attrs.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (!attrs[0].AttributeType.IsKnownType(KnownAttribute.CompilerGenerated))\n\t\t\t\treturn false;\n\t\t\tvar body = DecompileBody(getter);\n\t\t\tif (body == null || body.Instructions.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (!(body.Instructions.Single() is Leave leave))\n\t\t\t\treturn false;\n\t\t\t// leave IL_0000 (call GetTypeFromHandle(ldtypetoken R))\n\t\t\tif (!TransformExpressionTrees.MatchGetTypeFromHandle(leave.Value, out IType ty))\n\t\t\t\treturn false;\n\t\t\treturn IsRecordType(ty);\n\t\t}\n\n\t\tprivate bool IsGeneratedPrintMembers(IMethod method)\n\t\t{\n\t\t\tDebug.Assert(method.Name == \"PrintMembers\");\n\t\t\tif (method.Parameters.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (!isSealed && !method.IsOverridable)\n\t\t\t\treturn false;\n\t\t\tif (method.GetAttributes().Any(attr => !IsAllowedAttribute(attr)) || method.GetReturnTypeAttributes().Any())\n\t\t\t\treturn false;\n\t\t\tif (method.Accessibility != Accessibility.Protected && (!isSealed || method.Accessibility != Accessibility.Private))\n\t\t\t\treturn false;\n\t\t\tif (orderedMembers == null)\n\t\t\t\treturn false;\n\t\t\tvar body = DecompileBody(method);\n\t\t\tif (body == null)\n\t\t\t\treturn false;\n\t\t\tvar variables = body.Ancestors.OfType<ILFunction>().Single().Variables;\n\t\t\tvar builder = variables.Single(v => v.Kind == VariableKind.Parameter && v.Index == 0);\n\t\t\tif (builder.Type.ReflectionName != \"System.Text.StringBuilder\")\n\t\t\t\treturn false;\n\t\t\tint pos = 0;\n\t\t\t//Roslyn 4.0.0-3.final start to insert an call to RuntimeHelpers.EnsureSufficientExecutionStack()\n\t\t\tif (!isStruct && !isInheritedRecord && body.Instructions[pos] is Call {\n\t\t\t\tArguments: { Count: 0 },\n\t\t\t\tMethod: { Name: \"EnsureSufficientExecutionStack\", DeclaringType: { Namespace: \"System.Runtime.CompilerServices\", Name: \"RuntimeHelpers\" } }\n\t\t\t})\n\t\t\t{\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\tif (isInheritedRecord)\n\t\t\t{\n\t\t\t\t// Special case: inherited record adding no new members\n\t\t\t\tif (body.Instructions[pos].MatchReturn(out var returnValue)\n\t\t\t\t\t&& IsBaseCall(returnValue) && !orderedMembers.Any(IsPrintedMember))\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\t// if (call PrintMembers(ldloc this, ldloc builder)) Block IL_000f {\n\t\t\t\t//   callvirt Append(ldloc builder, ldstr \", \")\n\t\t\t\t// }\n\t\t\t\tif (!body.Instructions[pos].MatchIfInstruction(out var condition, out var trueInst))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!IsBaseCall(condition))\n\t\t\t\t\treturn false;\n\t\t\t\t// trueInst = callvirt Append(ldloc builder, ldstr \", \")\n\t\t\t\ttrueInst = Block.Unwrap(trueInst);\n\t\t\t\tif (!MatchStringBuilderAppend(trueInst, builder, out var val))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(val.MatchLdStr(out string? text) && text == \", \"))\n\t\t\t\t\treturn false;\n\t\t\t\tpos++;\n\n\t\t\t\tbool IsBaseCall(ILInstruction inst)\n\t\t\t\t{\n\t\t\t\t\tif (!(inst is CallInstruction { Method: { Name: \"PrintMembers\" } } call))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (call.Arguments.Count != 2)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!call.Arguments[0].MatchLdThis())\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!call.Arguments[1].MatchLdLoc(builder))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbool needsComma = false;\n\t\t\tforeach (var member in orderedMembers)\n\t\t\t{\n\t\t\t\tif (!IsPrintedMember(member))\n\t\t\t\t\tcontinue;\n\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t/* \n\t\t\t\tcallvirt Append(ldloc builder, ldstr \"A\")\n\t\t\t\tcallvirt Append(ldloc builder, ldstr \" = \")\n\t\t\t\tcallvirt Append(ldloc builder, constrained[System.Int32].callvirt ToString(addressof System.Int32(call get_A(ldloc this))))\n\t\t\t\tcallvirt Append(ldloc builder, ldstr \", \")\n\t\t\t\tcallvirt Append(ldloc builder, ldstr \"B\")\n\t\t\t\tcallvirt Append(ldloc builder, ldstr \" = \")\n\t\t\t\tcallvirt Append(ldloc builder, constrained[System.Int32].callvirt ToString(ldflda B(ldloc this)))\n\t\t\t\tleave IL_0000 (ldc.i4 1) */\n\t\t\t\tif (!MatchStringBuilderAppendConstant(out string? text))\n\t\t\t\t\treturn false;\n\t\t\t\tstring expectedText = (needsComma ? \", \" : \"\") + member.Name + \" = \";\n\t\t\t\tif (text != expectedText)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!MatchStringBuilderAppend(body.Instructions[pos], builder, out var val))\n\t\t\t\t\treturn false;\n\t\t\t\tif (val is CallInstruction { Method: { Name: \"ToString\", IsStatic: false } } toStringCall)\n\t\t\t\t{\n\t\t\t\t\tif (toStringCall.Arguments.Count != 1)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tval = toStringCall.Arguments[0];\n\t\t\t\t\tif (val is AddressOf addressOf)\n\t\t\t\t\t{\n\t\t\t\t\t\tval = addressOf.Value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (val is Box box)\n\t\t\t\t{\n\t\t\t\t\tif (!NormalizeTypeVisitor.TypeErasure.EquivalentTypes(box.Type, member.ReturnType))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tval = box.Argument;\n\t\t\t\t}\n\t\t\t\tif (val is CallInstruction getterCall && member is IProperty property)\n\t\t\t\t{\n\t\t\t\t\tif (!getterCall.Method.Equals(property.Getter))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (getterCall.Arguments.Count != 1)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!getterCall.Arguments[0].MatchLdThis())\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse if (val.MatchLdFld(out var target, out var field) || val.MatchLdFlda(out target, out field))\n\t\t\t\t{\n\t\t\t\t\tif (!target.MatchLdThis())\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!field.Equals(member))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tpos++;\n\t\t\t\tneedsComma = true;\n\t\t\t}\n\t\t\t// leave IL_0000 (ldc.i4 1)\n\t\t\treturn body.Instructions[pos].MatchReturn(out var retVal)\n\t\t\t\t&& retVal.MatchLdcI4(needsComma ? 1 : 0);\n\n\t\t\tbool IsPrintedMember(IMember member)\n\t\t\t{\n\t\t\t\tif (member.IsStatic)\n\t\t\t\t{\n\t\t\t\t\treturn false; // static fields/properties are not printed\n\t\t\t\t}\n\t\t\t\tif (member.Accessibility != Accessibility.Public)\n\t\t\t\t{\n\t\t\t\t\treturn false; // non-public fields/properties are not printed\n\t\t\t\t}\n\t\t\t\tif (!isStruct && member.Name == \"EqualityContract\")\n\t\t\t\t{\n\t\t\t\t\treturn false; // EqualityContract is never printed\n\t\t\t\t}\n\t\t\t\tif (member.IsExplicitInterfaceImplementation)\n\t\t\t\t{\n\t\t\t\t\treturn false; // explicit interface impls are not printed\n\t\t\t\t}\n\t\t\t\tif (member.IsOverride)\n\t\t\t\t{\n\t\t\t\t\treturn false; // override is not printed (again), the virtual base property was already printed\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tbool MatchStringBuilderAppendConstant([NotNullWhen(true)] out string? text)\n\t\t\t{\n\t\t\t\ttext = null;\n\t\t\t\twhile (MatchStringBuilderAppend(body.Instructions[pos], builder, out var val) && val.MatchLdStr(out string? valText))\n\t\t\t\t{\n\t\t\t\t\ttext += valText;\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t\treturn text != null;\n\t\t\t}\n\t\t}\n\n\t\tprivate bool MatchStringBuilderAppend(ILInstruction inst, ILVariable sb, [NotNullWhen(true)] out ILInstruction? val)\n\t\t{\n\t\t\tval = null;\n\t\t\tif (!(inst is CallVirt { Method: { Name: \"Append\", DeclaringType: { Namespace: \"System.Text\", Name: \"StringBuilder\" } } } call))\n\t\t\t\treturn false;\n\t\t\tif (call.Arguments.Count != 2)\n\t\t\t\treturn false;\n\t\t\tif (!call.Arguments[0].MatchLdLoc(sb))\n\t\t\t\treturn false;\n\t\t\tval = call.Arguments[1];\n\t\t\treturn true;\n\t\t}\n\n\t\tprivate bool IsGeneratedToString(IMethod method)\n\t\t{\n\t\t\tDebug.Assert(method.Name == \"ToString\" && method.Parameters.Count == 0);\n\t\t\tif (!method.IsOverride)\n\t\t\t\treturn false;\n\t\t\tif (method.IsSealed)\n\t\t\t\treturn false;\n\t\t\tif (method.GetAttributes().Any(attr => !IsAllowedAttribute(attr)) || method.GetReturnTypeAttributes().Any())\n\t\t\t\treturn false;\n\t\t\tvar body = DecompileBody(method);\n\t\t\tif (body == null)\n\t\t\t\treturn false;\n\t\t\t// stloc stringBuilder(newobj StringBuilder..ctor())\n\t\t\tif (!body.Instructions[0].MatchStLoc(out var stringBuilder, out var stringBuilderInit))\n\t\t\t\treturn false;\n\t\t\tif (!(stringBuilderInit is NewObj { Arguments: { Count: 0 }, Method: { DeclaringTypeDefinition: { Name: \"StringBuilder\", Namespace: \"System.Text\" } } }))\n\t\t\t\treturn false;\n\t\t\t// callvirt Append(ldloc stringBuilder, ldstr \"R\")\n\t\t\tif (!MatchAppendCallWithValue(body.Instructions[1], recordTypeDef.Name))\n\t\t\t\treturn false;\n\t\t\t// callvirt Append(ldloc stringBuilder, ldstr \" { \")\n\t\t\tif (!MatchAppendCallWithValue(body.Instructions[2], \" { \"))\n\t\t\t\treturn false;\n\t\t\t// if (callvirt PrintMembers(ldloc this, ldloc stringBuilder)) { trueInst }\n\t\t\tif (!body.Instructions[3].MatchIfInstruction(out var condition, out var trueInst))\n\t\t\t\treturn true;\n\t\t\tif (!((condition is CallInstruction { Method: { Name: \"PrintMembers\" } } printMembersCall) &&\n\t\t\t\t(condition is CallVirt || (isSealed && condition is Call))))\n\t\t\t\treturn false;\n\t\t\tif (printMembersCall.Arguments.Count != 2)\n\t\t\t\treturn false;\n\t\t\tif (!printMembersCall.Arguments[0].MatchLdThis())\n\t\t\t\treturn false;\n\t\t\tif (!printMembersCall.Arguments[1].MatchLdLoc(stringBuilder))\n\t\t\t\treturn false;\n\t\t\t// trueInst: callvirt Append(ldloc stringBuilder, ldstr \" \")\n\t\t\tif (!MatchAppendCallWithValue(Block.Unwrap(trueInst), \" \"))\n\t\t\t\treturn false;\n\t\t\t// callvirt Append(ldloc stringBuilder, ldstr \"}\")\n\t\t\tif (!MatchAppendCallWithValue(body.Instructions[4], \"}\"))\n\t\t\t\treturn false;\n\t\t\t// leave IL_0000 (callvirt ToString(ldloc stringBuilder))\n\t\t\tif (!(body.Instructions[5] is Leave leave))\n\t\t\t\treturn false;\n\t\t\tif (!(leave.Value is CallVirt { Method: { Name: \"ToString\" } } toStringCall))\n\t\t\t\treturn false;\n\t\t\tif (toStringCall.Arguments.Count != 1)\n\t\t\t\treturn false;\n\t\t\treturn toStringCall.Arguments[0].MatchLdLoc(stringBuilder);\n\n\t\t\tbool MatchAppendCallWithValue(ILInstruction inst, string val)\n\t\t\t{\n\t\t\t\tif (!(inst is CallVirt { Method: { Name: \"Append\" } } call))\n\t\t\t\t\treturn false;\n\t\t\t\tif (call.Arguments.Count != 2)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!call.Arguments[0].MatchLdLoc(stringBuilder))\n\t\t\t\t\treturn false;\n\t\t\t\t//Roslyn 4.0.0-3.final start to use char for 1 length string\n\t\t\t\tif (call.Method.Parameters[0].Type.IsKnownType(KnownTypeCode.Char))\n\t\t\t\t{\n\t\t\t\t\treturn val != null && val.Length == 1 && call.Arguments[1].MatchLdcI4(val[0]);\n\t\t\t\t}\n\t\t\t\treturn call.Arguments[1].MatchLdStr(out string? val1) && val1 == val;\n\t\t\t}\n\t\t}\n\n\t\tprivate bool IsGeneratedEquals(IMethod method)\n\t\t{\n\t\t\t// virtual bool Equals(R? other) {\n\t\t\t//    return other != null && EqualityContract == other.EqualityContract && EqualityComparer<int>.Default.Equals(A, other.A) && ...;\n\t\t\t// }\n\t\t\t// Starting with Roslyn 3.10, it's:\n\t\t\t// virtual bool Equals(R? other) {\n\t\t\t//    return this == other || other != null && EqualityContract == other.EqualityContract && EqualityComparer<int>.Default.Equals(A, other.A) && ...;\n\t\t\t// }\n\t\t\tDebug.Assert(method.Name == \"Equals\" && method.Parameters.Count == 1);\n\t\t\tif (method.Parameters.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (!isSealed && !method.IsOverridable)\n\t\t\t\treturn false;\n\t\t\tif (method.GetAttributes().Any(attr => !IsAllowedAttribute(attr)) || method.GetReturnTypeAttributes().Any())\n\t\t\t\treturn false;\n\t\t\tif (orderedMembers == null)\n\t\t\t\treturn false;\n\t\t\tvar body = DecompileBody(method);\n\t\t\tif (body == null)\n\t\t\t\treturn false;\n\t\t\tif (!body.Instructions[0].MatchReturn(out var returnValue))\n\t\t\t\treturn false;\n\t\t\t// special case for empty record struct; always returns true;\n\t\t\tif (returnValue.MatchLdcI4(1))\n\t\t\t\treturn true;\n\t\t\tvar variables = body.Ancestors.OfType<ILFunction>().Single().Variables;\n\t\t\tvar other = variables.Single(v => v.Kind == VariableKind.Parameter && v.Index == 0);\n\t\t\tDebug.Assert(IsRecordType(other.Type));\n\t\t\tif (returnValue.MatchLogicOr(out var lhs, out var rhs))\n\t\t\t{\n\t\t\t\t// this == other || ...\n\t\t\t\tif (!lhs.MatchCompEquals(out var compLeft, out var compRight))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!compLeft.MatchLdThis())\n\t\t\t\t\treturn false;\n\t\t\t\tif (!compRight.MatchLdLoc(other))\n\t\t\t\t\treturn false;\n\t\t\t\treturnValue = rhs;\n\t\t\t}\n\t\t\tvar conditions = UnpackLogicAndChain(returnValue);\n\t\t\tDebug.Assert(conditions.Count >= 1);\n\t\t\tint pos = 0;\n\t\t\tif (!isStruct)\n\t\t\t{\n\t\t\t\tif (isInheritedRecord)\n\t\t\t\t{\n\t\t\t\t\t// call BaseClass::Equals(ldloc this, ldloc other)\n\t\t\t\t\tif (pos >= conditions.Count)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!(conditions[pos] is Call { Method: { Name: \"Equals\" } } call))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (baseClass != null && !NormalizeTypeVisitor.TypeErasure.EquivalentTypes(call.Method.DeclaringType, baseClass))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (call.Arguments.Count != 2)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!call.Arguments[0].MatchLdThis())\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!call.Arguments[1].MatchLdLoc(other))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// comp.o(ldloc other != ldnull)\n\t\t\t\t\tif (pos >= conditions.Count)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!conditions[pos].MatchCompNotEqualsNull(out var arg))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!arg.MatchLdLoc(other))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tpos++;\n\t\t\t\t\t// call op_Equality(callvirt get_EqualityContract(ldloc this), callvirt get_EqualityContract(ldloc other))\n\t\t\t\t\t// Special-cased because Roslyn isn't using EqualityComparer<T> here.\n\t\t\t\t\tif (pos >= conditions.Count)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!(conditions[pos] is Call { Method: { IsOperator: true, Name: \"op_Equality\" } } opEqualityCall))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!opEqualityCall.Method.DeclaringType.IsKnownType(KnownTypeCode.Type))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (opEqualityCall.Arguments.Count != 2)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!MatchGetEqualityContract(opEqualityCall.Arguments[0], out var target1))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!MatchGetEqualityContract(opEqualityCall.Arguments[1], out var target2))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!target1.MatchLdThis())\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!target2.MatchLdLoc(other))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tforeach (var member in orderedMembers)\n\t\t\t{\n\t\t\t\tif (!MemberConsideredForEquality(member))\n\t\t\t\t\tcontinue;\n\t\t\t\tif (!isStruct && member.Name == \"EqualityContract\")\n\t\t\t\t{\n\t\t\t\t\tcontinue; // already special-cased\n\t\t\t\t}\n\t\t\t\t// EqualityComparer<int>.Default.Equals(A, other.A)\n\t\t\t\t// callvirt Equals(call get_Default(), ldfld <A>k__BackingField(ldloc this), ldfld <A>k__BackingField(ldloc other))\n\t\t\t\tif (pos >= conditions.Count)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(conditions[pos] is CallVirt { Method: { Name: \"Equals\" } } equalsCall))\n\t\t\t\t\treturn false;\n\t\t\t\tif (equalsCall.Arguments.Count != 3)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!IsEqualityComparerGetDefaultCall(equalsCall.Arguments[0], member.ReturnType))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!MatchMemberAccess(equalsCall.Arguments[1], out var target1, out var member1))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!MatchMemberAccess(equalsCall.Arguments[2], out var target2, out var member2))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!target1.MatchLdThis())\n\t\t\t\t\treturn false;\n\t\t\t\tif (!member1.Equals(member))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(isStruct ? target2.MatchLdLoca(other) : target2.MatchLdLoc(other)))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!member2.Equals(member))\n\t\t\t\t\treturn false;\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\treturn pos == conditions.Count;\n\t\t}\n\n\t\tstatic List<ILInstruction> UnpackLogicAndChain(ILInstruction rootOfChain)\n\t\t{\n\t\t\tvar result = new List<ILInstruction>();\n\t\t\tVisit(rootOfChain);\n\t\t\treturn result;\n\n\t\t\tvoid Visit(ILInstruction inst)\n\t\t\t{\n\t\t\t\tif (inst.MatchLogicAnd(out var lhs, out var rhs))\n\t\t\t\t{\n\t\t\t\t\tVisit(lhs);\n\t\t\t\t\tVisit(rhs);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tresult.Add(inst);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate bool MatchGetEqualityContract(ILInstruction inst, [NotNullWhen(true)] out ILInstruction? target)\n\t\t{\n\t\t\ttarget = null;\n\t\t\tif (!(inst is CallInstruction { Method: { Name: \"get_EqualityContract\" } } call))\n\t\t\t\treturn false;\n\t\t\tif (!(inst is CallVirt || (isSealed && inst is Call)))\n\t\t\t\treturn false;\n\t\t\tif (call.Arguments.Count != 1)\n\t\t\t\treturn false;\n\t\t\ttarget = call.Arguments[0];\n\t\t\treturn true;\n\t\t}\n\n\t\tprivate static bool IsEqualityComparerGetDefaultCall(ILInstruction inst, IType type)\n\t\t{\n\t\t\tif (!(inst is Call { Method: { Name: \"get_Default\", IsStatic: true } } call))\n\t\t\t\treturn false;\n\t\t\tif (!(call.Method.DeclaringType is { Name: \"EqualityComparer\", Namespace: \"System.Collections.Generic\" }))\n\t\t\t\treturn false;\n\t\t\tif (call.Method.DeclaringType.TypeArguments.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (!NormalizeTypeVisitor.TypeErasure.EquivalentTypes(call.Method.DeclaringType.TypeArguments[0], type))\n\t\t\t\treturn false;\n\t\t\treturn call.Arguments.Count == 0;\n\t\t}\n\n\t\tbool MemberConsideredForEquality(IMember member)\n\t\t{\n\t\t\tif (member.IsStatic)\n\t\t\t\treturn false;\n\t\t\tif (member is IProperty property)\n\t\t\t{\n\t\t\t\tif (!isStruct && property.Name == \"EqualityContract\")\n\t\t\t\t\treturn !isInheritedRecord;\n\t\t\t\treturn autoPropertyToBackingField.ContainsKey(property);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn member is IField;\n\t\t\t}\n\t\t}\n\n\t\tbool IsGeneratedGetHashCode(IMethod method)\n\t\t{\n\t\t\t/*\n\t\t\t return (\n\t\t\t\t(\n\t\t\t\t\tEqualityComparer<Type>.Default.GetHashCode(EqualityContract) * -1521134295 + EqualityComparer<int>.Default.GetHashCode(A)\n\t\t\t\t) * -1521134295 + EqualityComparer<int>.Default.GetHashCode(B)\n\t\t\t ) * -1521134295 + EqualityComparer<object>.Default.GetHashCode(C);\n\t\t\t*/\n\t\t\tDebug.Assert(method.Name == \"GetHashCode\");\n\t\t\tif (method.Parameters.Count != 0)\n\t\t\t\treturn false;\n\t\t\tif (!method.IsOverride || method.IsSealed)\n\t\t\t\treturn false;\n\t\t\tif (method.GetAttributes().Any(attr => !IsAllowedAttribute(attr)) || method.GetReturnTypeAttributes().Any())\n\t\t\t\treturn false;\n\t\t\tif (orderedMembers == null)\n\t\t\t\treturn false;\n\t\t\tvar body = DecompileBody(method);\n\t\t\tif (body == null)\n\t\t\t\treturn false;\n\t\t\tif (!body.Instructions[0].MatchReturn(out var returnValue))\n\t\t\t\treturn false;\n\t\t\t// special case for empty record struct; always returns false;\n\t\t\tif (returnValue.MatchLdcI4(0))\n\t\t\t\treturn true;\n\t\t\tvar hashedMembers = new List<IMember>();\n\t\t\tbool foundBaseClassHash = false;\n\t\t\tif (!Visit(returnValue))\n\t\t\t\treturn false;\n\t\t\tif (foundBaseClassHash != isInheritedRecord)\n\t\t\t\treturn false;\n\t\t\treturn orderedMembers.Where(MemberConsideredForEquality).SequenceEqual(hashedMembers);\n\n\t\t\tbool Visit(ILInstruction inst)\n\t\t\t{\n\t\t\t\tif (inst is BinaryNumericInstruction {\n\t\t\t\t\tOperator: BinaryNumericOperator.Add,\n\t\t\t\t\tCheckForOverflow: false,\n\t\t\t\t\tLeft: BinaryNumericInstruction {\n\t\t\t\t\t\tOperator: BinaryNumericOperator.Mul,\n\t\t\t\t\t\tCheckForOverflow: false,\n\t\t\t\t\t\tLeft: var left,\n\t\t\t\t\t\tRight: LdcI4 { Value: -1521134295 }\n\t\t\t\t\t},\n\t\t\t\t\tRight: var right\n\t\t\t\t})\n\t\t\t\t{\n\t\t\t\t\tif (!Visit(left))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn ProcessIndividualHashCode(right);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn ProcessIndividualHashCode(inst);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool ProcessIndividualHashCode(ILInstruction inst)\n\t\t\t{\n\t\t\t\t// base.GetHashCode(): call GetHashCode(ldloc this)\n\t\t\t\tif (inst is Call { Method: { Name: \"GetHashCode\" } } baseHashCodeCall)\n\t\t\t\t{\n\t\t\t\t\tif (baseHashCodeCall.Arguments.Count != 1)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!baseHashCodeCall.Arguments[0].MatchLdThis())\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (foundBaseClassHash || hashedMembers.Count > 0)\n\t\t\t\t\t\treturn false; // must be first\n\t\t\t\t\tfoundBaseClassHash = true;\n\t\t\t\t\treturn baseHashCodeCall.Method.DeclaringType.Equals(baseClass);\n\t\t\t\t}\n\t\t\t\t// callvirt GetHashCode(call get_Default(), callvirt get_EqualityContract(ldloc this))\n\t\t\t\t// callvirt GetHashCode(call get_Default(), ldfld <A>k__BackingField(ldloc this)))\n\t\t\t\tif (!(inst is CallVirt { Method: { Name: \"GetHashCode\" } } getHashCodeCall))\n\t\t\t\t\treturn false;\n\t\t\t\tif (getHashCodeCall.Arguments.Count != 2)\n\t\t\t\t\treturn false;\n\t\t\t\t// getHashCodeCall.Arguments[0] checked later\n\t\t\t\tif (!MatchMemberAccess(getHashCodeCall.Arguments[1], out var target, out var member))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!target.MatchLdThis())\n\t\t\t\t\treturn false;\n\t\t\t\tif (!IsEqualityComparerGetDefaultCall(getHashCodeCall.Arguments[0], member.ReturnType))\n\t\t\t\t\treturn false;\n\t\t\t\thashedMembers.Add(member);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tbool IsGeneratedDeconstruct(IMethod method)\n\t\t{\n\t\t\tDebug.Assert(method.Name == \"Deconstruct\" && method.Parameters.Count == primaryCtor?.Parameters.Count);\n\n\t\t\tif (!method.ReturnType.IsKnownType(KnownTypeCode.Void))\n\t\t\t\treturn false;\n\n\t\t\tfor (int i = 0; i < method.Parameters.Count; i++)\n\t\t\t{\n\t\t\t\tvar deconstruct = method.Parameters[i];\n\t\t\t\tvar ctor = primaryCtor.Parameters[i];\n\n\t\t\t\tif (deconstruct.ReferenceKind != ReferenceKind.Out)\n\t\t\t\t\treturn false;\n\n\t\t\t\tIType ctorType = ctor.Type;\n\t\t\t\tif (ctor.ReferenceKind is ReferenceKind.In or ReferenceKind.RefReadOnly)\n\t\t\t\t\tctorType = ((ByReferenceType)ctorType).ElementType;\n\t\t\t\tif (!ctorType.Equals(((ByReferenceType)deconstruct.Type).ElementType))\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (ctor.Name != deconstruct.Name)\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar body = DecompileBody(method);\n\t\t\tif (body == null || body.Instructions.Count != method.Parameters.Count + 1)\n\t\t\t\treturn false;\n\n\t\t\tfor (int i = 0; i < body.Instructions.Count - 1; i++)\n\t\t\t{\n\t\t\t\t// stobj T(ldloc parameter, call getter(ldloc this))\n\t\t\t\tif (!body.Instructions[i].MatchStObj(out var targetInst, out var getter, out _))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!targetInst.MatchLdLoc(out var target))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(target.Kind == VariableKind.Parameter && target.Index == i))\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (getter is not Call call || call.Arguments.Count != 1)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!call.Arguments[0].MatchLdThis())\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (!call.Method.IsAccessor)\n\t\t\t\t\treturn false;\n\t\t\t\tvar autoProperty = (IProperty)call.Method.AccessorOwner;\n\t\t\t\tif (!autoPropertyToBackingField.ContainsKey(autoProperty))\n\t\t\t\t{\n\t\t\t\t\tif (autoProperty.DeclaringTypeDefinition == recordTypeDef)\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar returnInst = body.Instructions.LastOrDefault();\n\t\t\treturn returnInst != null && returnInst.MatchReturn(out var retVal) && retVal.MatchNop();\n\t\t}\n\n\t\tbool MatchMemberAccess(ILInstruction inst, [NotNullWhen(true)] out ILInstruction? target, [NotNullWhen(true)] out IMember? member)\n\t\t{\n\t\t\ttarget = null;\n\t\t\tmember = null;\n\t\t\tif (inst is CallInstruction {\n\t\t\t\tMethod: {\n\t\t\t\t\tAccessorKind: System.Reflection.MethodSemanticsAttributes.Getter,\n\t\t\t\t\tAccessorOwner: IProperty property\n\t\t\t\t}\n\t\t\t} call && (call is CallVirt || (isSealed && call is Call)))\n\t\t\t{\n\t\t\t\tif (call.Arguments.Count != 1)\n\t\t\t\t\treturn false;\n\t\t\t\ttarget = call.Arguments[0];\n\t\t\t\tmember = property;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (inst.MatchLdFld(out target, out IField? field))\n\t\t\t{\n\t\t\t\tif (backingFieldToAutoProperty.TryGetValue(field, out property!))\n\t\t\t\t\tmember = property;\n\t\t\t\telse\n\t\t\t\t\tmember = field;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tBlock? DecompileBody(IMethod method)\n\t\t{\n\t\t\tif (method == null || method.MetadataToken.IsNil)\n\t\t\t\treturn null;\n\t\t\tvar metadata = typeSystem.MainModule.metadata;\n\n\t\t\tvar methodDefHandle = (MethodDefinitionHandle)method.MetadataToken;\n\t\t\tvar methodDef = metadata.GetMethodDefinition(methodDefHandle);\n\t\t\tif (!methodDef.HasBody())\n\t\t\t\treturn null;\n\n\t\t\tvar genericContext = new GenericContext(\n\t\t\t\tclassTypeParameters: recordTypeDef.TypeParameters,\n\t\t\t\tmethodTypeParameters: null);\n\t\t\tvar body = typeSystem.MainModule.MetadataFile.GetMethodBody(methodDef.RelativeVirtualAddress);\n\t\t\tvar ilReader = new ILReader(typeSystem.MainModule);\n\t\t\tvar il = ilReader.ReadIL(methodDefHandle, body, genericContext, ILFunctionKind.TopLevelFunction, cancellationToken);\n\t\t\tvar settings = new DecompilerSettings(LanguageVersion.CSharp1);\n\t\t\tvar transforms = CSharpDecompiler.GetILTransforms();\n\t\t\t// Remove the last couple transforms -- we don't need variable names etc. here\n\t\t\tint lastBlockTransform = transforms.FindLastIndex(t => t is BlockILTransform);\n\t\t\ttransforms.RemoveRange(lastBlockTransform + 1, transforms.Count - (lastBlockTransform + 1));\n\t\t\t// Use CombineExitsTransform so that \"return other != null && ...;\" is a single statement even in release builds\n\t\t\ttransforms.Add(new CombineExitsTransform());\n\t\t\til.RunTransforms(transforms,\n\t\t\t\tnew ILTransformContext(il, typeSystem, debugInfo: null, settings) {\n\t\t\t\t\tCancellationToken = cancellationToken\n\t\t\t\t});\n\t\t\tif (il.Body is BlockContainer container)\n\t\t\t{\n\t\t\t\treturn container.EntryPoint;\n\t\t\t}\n\t\t\telse if (il.Body is Block block)\n\t\t\t{\n\t\t\t\treturn block;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nusing static ICSharpCode.Decompiler.Metadata.ILOpCodeExtensions;\n\nnamespace ICSharpCode.Decompiler.CSharp\n{\n\tclass RequiredNamespaceCollector\n\t{\n\t\tstatic readonly Decompiler.TypeSystem.GenericContext genericContext = default;\n\n\t\treadonly HashSet<string> namespaces;\n\t\treadonly HashSet<IType> visitedTypes = new HashSet<IType>();\n\n\t\tpublic RequiredNamespaceCollector(HashSet<string> namespaces)\n\t\t{\n\t\t\tthis.namespaces = namespaces;\n\t\t\tfor (int i = 0; i < KnownTypeReference.KnownTypeCodeCount; i++)\n\t\t\t{\n\t\t\t\tvar ktr = KnownTypeReference.Get((KnownTypeCode)i);\n\t\t\t\tif (ktr == null)\n\t\t\t\t\tcontinue;\n\t\t\t\tnamespaces.Add(ktr.Namespace);\n\t\t\t}\n\t\t}\n\n\t\tpublic static void CollectNamespaces(MetadataModule module, HashSet<string> namespaces)\n\t\t{\n\t\t\tvar collector = new RequiredNamespaceCollector(namespaces);\n\t\t\tforeach (var type in module.TypeDefinitions)\n\t\t\t{\n\t\t\t\tcollector.CollectNamespaces(type, module, (CodeMappingInfo)null);\n\t\t\t}\n\t\t\tcollector.HandleAttributes(module.GetAssemblyAttributes());\n\t\t\tcollector.HandleAttributes(module.GetModuleAttributes());\n\t\t}\n\n\t\tpublic static void CollectAttributeNamespaces(MetadataModule module, HashSet<string> namespaces)\n\t\t{\n\t\t\tvar collector = new RequiredNamespaceCollector(namespaces);\n\t\t\tcollector.HandleAttributes(module.GetAssemblyAttributes());\n\t\t\tcollector.HandleAttributes(module.GetModuleAttributes());\n\t\t}\n\n\t\tpublic static void CollectNamespaces(IEntity entity, MetadataModule module, HashSet<string> namespaces)\n\t\t{\n\t\t\tvar collector = new RequiredNamespaceCollector(namespaces);\n\t\t\tcollector.CollectNamespaces(entity, module);\n\t\t}\n\n\t\tvoid CollectNamespaces(IEntity entity, MetadataModule module, CodeMappingInfo mappingInfo = null)\n\t\t{\n\t\t\tif (entity == null || entity.MetadataToken.IsNil || module.MetadataFile is not MetadataFile corFile)\n\t\t\t\treturn;\n\t\t\tif (mappingInfo == null)\n\t\t\t\tmappingInfo = CSharpDecompiler.GetCodeMappingInfo(corFile, entity.MetadataToken);\n\t\t\tswitch (entity)\n\t\t\t{\n\t\t\t\tcase ITypeDefinition td:\n\t\t\t\t\tnamespaces.Add(td.Namespace);\n\t\t\t\t\tHandleAttributes(td.GetAttributes());\n\t\t\t\t\tHandleTypeParameters(td.TypeParameters);\n\n\t\t\t\t\tforeach (var baseType in td.DirectBaseTypes)\n\t\t\t\t\t{\n\t\t\t\t\t\tCollectNamespacesForTypeReference(baseType);\n\t\t\t\t\t}\n\n\t\t\t\t\tforeach (var nestedType in td.NestedTypes)\n\t\t\t\t\t{\n\t\t\t\t\t\tCollectNamespaces(nestedType, module, mappingInfo);\n\t\t\t\t\t}\n\n\t\t\t\t\tforeach (var field in td.Fields)\n\t\t\t\t\t{\n\t\t\t\t\t\tCollectNamespaces(field, module, mappingInfo);\n\t\t\t\t\t}\n\n\t\t\t\t\tforeach (var property in td.Properties)\n\t\t\t\t\t{\n\t\t\t\t\t\tCollectNamespaces(property, module, mappingInfo);\n\t\t\t\t\t}\n\n\t\t\t\t\tforeach (var @event in td.Events)\n\t\t\t\t\t{\n\t\t\t\t\t\tCollectNamespaces(@event, module, mappingInfo);\n\t\t\t\t\t}\n\n\t\t\t\t\tforeach (var method in td.Methods)\n\t\t\t\t\t{\n\t\t\t\t\t\tCollectNamespaces(method, module, mappingInfo);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase IField field:\n\t\t\t\t\tHandleAttributes(field.GetAttributes());\n\t\t\t\t\tCollectNamespacesForTypeReference(field.ReturnType);\n\t\t\t\t\tbreak;\n\t\t\t\tcase IMethod method:\n\t\t\t\t\tvar parts = mappingInfo.GetMethodParts((MethodDefinitionHandle)method.MetadataToken).ToList();\n\t\t\t\t\tforeach (var part in parts)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar partMethod = module.ResolveMethod(part, genericContext);\n\t\t\t\t\t\tHandleAttributes(partMethod.GetAttributes());\n\t\t\t\t\t\tHandleAttributes(partMethod.GetReturnTypeAttributes());\n\t\t\t\t\t\tCollectNamespacesForTypeReference(partMethod.ReturnType);\n\t\t\t\t\t\tforeach (var param in partMethod.Parameters)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tHandleAttributes(param.GetAttributes());\n\t\t\t\t\t\t\tCollectNamespacesForTypeReference(param.Type);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tHandleTypeParameters(partMethod.TypeParameters);\n\t\t\t\t\t\tHandleOverrides(part.GetMethodImplementations(module.metadata), module);\n\t\t\t\t\t\tvar methodDef = module.metadata.GetMethodDefinition(part);\n\t\t\t\t\t\tif (method.HasBody)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tMethodBodyBlock body;\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tbody = module.MetadataFile.GetMethodBody(methodDef.RelativeVirtualAddress);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tCollectNamespacesFromMethodBody(body, module);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase IProperty property:\n\t\t\t\t\tHandleAttributes(property.GetAttributes());\n\t\t\t\t\tCollectNamespacesForTypeReference(property.ReturnType);\n\t\t\t\t\tCollectNamespaces(property.Getter, module, mappingInfo);\n\t\t\t\t\tCollectNamespaces(property.Setter, module, mappingInfo);\n\t\t\t\t\tbreak;\n\t\t\t\tcase IEvent @event:\n\t\t\t\t\tHandleAttributes(@event.GetAttributes());\n\t\t\t\t\tCollectNamespacesForTypeReference(@event.ReturnType);\n\t\t\t\t\tCollectNamespaces(@event.AddAccessor, module, mappingInfo);\n\t\t\t\t\tCollectNamespaces(@event.RemoveAccessor, module, mappingInfo);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tvoid HandleOverrides(ImmutableArray<MethodImplementationHandle> immutableArray, MetadataModule module)\n\t\t{\n\t\t\tforeach (var h in immutableArray)\n\t\t\t{\n\t\t\t\tvar methodImpl = module.metadata.GetMethodImplementation(h);\n\t\t\t\tCollectNamespacesForTypeReference(module.ResolveType(methodImpl.Type, genericContext));\n\t\t\t\tCollectNamespacesForMemberReference(module.ResolveMethod(methodImpl.MethodBody, genericContext));\n\t\t\t\tCollectNamespacesForMemberReference(module.ResolveMethod(methodImpl.MethodDeclaration, genericContext));\n\t\t\t}\n\t\t}\n\n\t\tvoid CollectNamespacesForTypeReference(IType type)\n\t\t{\n\t\t\tif (!visitedTypes.Add(type))\n\t\t\t\treturn;\n\t\t\tswitch (type)\n\t\t\t{\n\t\t\t\tcase ParameterizedType parameterizedType:\n\t\t\t\t\tnamespaces.Add(parameterizedType.Namespace);\n\t\t\t\t\tCollectNamespacesForTypeReference(parameterizedType.GenericType);\n\t\t\t\t\tforeach (var arg in parameterizedType.TypeArguments)\n\t\t\t\t\t\tCollectNamespacesForTypeReference(arg);\n\t\t\t\t\treturn; // no need to collect base types again\n\t\t\t\tcase TypeWithElementType typeWithElementType:\n\t\t\t\t\tCollectNamespacesForTypeReference(typeWithElementType.ElementType);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TupleType tupleType:\n\t\t\t\t\tforeach (var elementType in tupleType.ElementTypes)\n\t\t\t\t\t{\n\t\t\t\t\t\tCollectNamespacesForTypeReference(elementType);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase FunctionPointerType fnPtrType:\n\t\t\t\t\tCollectNamespacesForTypeReference(fnPtrType.ReturnType);\n\t\t\t\t\tforeach (var paramType in fnPtrType.ParameterTypes)\n\t\t\t\t\t{\n\t\t\t\t\t\tCollectNamespacesForTypeReference(paramType);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tnamespaces.Add(type.Namespace);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tforeach (var baseType in type.GetAllBaseTypes())\n\t\t\t{\n\t\t\t\tnamespaces.Add(baseType.Namespace);\n\t\t\t}\n\t\t}\n\n\t\tpublic static void CollectNamespaces(EntityHandle entity, MetadataModule module, HashSet<string> namespaces)\n\t\t{\n\t\t\tif (entity.IsNil)\n\t\t\t\treturn;\n\t\t\tCollectNamespaces(module.ResolveEntity(entity, genericContext), module, namespaces);\n\t\t}\n\n\t\tvoid HandleAttributes(IEnumerable<IAttribute> attributes)\n\t\t{\n\t\t\tforeach (var attr in attributes)\n\t\t\t{\n\t\t\t\tnamespaces.Add(attr.AttributeType.Namespace);\n\t\t\t\tforeach (var arg in attr.FixedArguments)\n\t\t\t\t{\n\t\t\t\t\tHandleAttributeValue(arg.Type, arg.Value);\n\t\t\t\t}\n\t\t\t\tforeach (var arg in attr.NamedArguments)\n\t\t\t\t{\n\t\t\t\t\tHandleAttributeValue(arg.Type, arg.Value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid HandleAttributeValue(IType type, object value)\n\t\t{\n\t\t\tCollectNamespacesForTypeReference(type);\n\t\t\tif (value is IType typeofType)\n\t\t\t\tCollectNamespacesForTypeReference(typeofType);\n\t\t\tif (value is ImmutableArray<CustomAttributeTypedArgument<IType>> arr)\n\t\t\t{\n\t\t\t\tforeach (var element in arr)\n\t\t\t\t{\n\t\t\t\t\tHandleAttributeValue(element.Type, element.Value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid HandleTypeParameters(IEnumerable<ITypeParameter> typeParameters)\n\t\t{\n\t\t\tforeach (var typeParam in typeParameters)\n\t\t\t{\n\t\t\t\tHandleAttributes(typeParam.GetAttributes());\n\n\t\t\t\tforeach (var constraint in typeParam.DirectBaseTypes)\n\t\t\t\t{\n\t\t\t\t\tCollectNamespacesForTypeReference(constraint);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid CollectNamespacesFromMethodBody(MethodBodyBlock method, MetadataModule module)\n\t\t{\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar instructions = method.GetILReader();\n\n\t\t\tif (!method.LocalSignature.IsNil)\n\t\t\t{\n\t\t\t\tImmutableArray<IType> localSignature;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tlocalSignature = module.DecodeLocalSignature(method.LocalSignature, genericContext);\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\t// Issue #1211: ignore invalid local signatures\n\t\t\t\t\tlocalSignature = ImmutableArray<IType>.Empty;\n\t\t\t\t}\n\t\t\t\tforeach (var type in localSignature)\n\t\t\t\t\tCollectNamespacesForTypeReference(type);\n\t\t\t}\n\n\t\t\tforeach (var region in method.ExceptionRegions)\n\t\t\t{\n\t\t\t\tif (region.CatchType.IsNil)\n\t\t\t\t\tcontinue;\n\t\t\t\tIType ty;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tty = module.ResolveType(region.CatchType, genericContext);\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tCollectNamespacesForTypeReference(ty);\n\t\t\t}\n\n\t\t\twhile (instructions.RemainingBytes > 0)\n\t\t\t{\n\t\t\t\tILOpCode opCode;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\topCode = instructions.DecodeOpCode();\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tswitch (opCode.GetOperandType())\n\t\t\t\t{\n\t\t\t\t\tcase OperandType.Field:\n\t\t\t\t\tcase OperandType.Method:\n\t\t\t\t\tcase OperandType.Sig:\n\t\t\t\t\tcase OperandType.Tok:\n\t\t\t\t\tcase OperandType.Type:\n\t\t\t\t\t\tEntityHandle handle;\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\thandle = MetadataTokenHelpers.EntityHandleOrNil(instructions.ReadInt32());\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (handle.IsNil)\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tswitch (handle.Kind)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\t\t\t\tcase HandleKind.TypeReference:\n\t\t\t\t\t\t\tcase HandleKind.TypeSpecification:\n\t\t\t\t\t\t\t\tIType type;\n\t\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttype = module.ResolveType(handle, genericContext);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tCollectNamespacesForTypeReference(type);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase HandleKind.FieldDefinition:\n\t\t\t\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\t\t\tcase HandleKind.MethodSpecification:\n\t\t\t\t\t\t\tcase HandleKind.MemberReference:\n\t\t\t\t\t\t\t\tIMember member;\n\t\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tmember = module.ResolveEntity(handle, genericContext) as IMember;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tCollectNamespacesForMemberReference(member);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase HandleKind.StandaloneSignature:\n\t\t\t\t\t\t\t\tStandaloneSignature sig;\n\t\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tsig = metadata.GetStandaloneSignature((StandaloneSignatureHandle)handle);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (sig.GetKind() == StandaloneSignatureKind.Method)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tFunctionPointerType fpt;\n\t\t\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t(_, fpt) = module.DecodeMethodSignature((StandaloneSignatureHandle)handle, genericContext);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tCollectNamespacesForTypeReference(fpt);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tinstructions.SkipOperand(opCode);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid CollectNamespacesForMemberReference(IMember member)\n\t\t{\n\t\t\tswitch (member)\n\t\t\t{\n\t\t\t\tcase IField field:\n\t\t\t\t\tCollectNamespacesForTypeReference(field.DeclaringType);\n\t\t\t\t\tCollectNamespacesForTypeReference(field.ReturnType);\n\t\t\t\t\tbreak;\n\t\t\t\tcase IMethod method:\n\t\t\t\t\tCollectNamespacesForTypeReference(method.DeclaringType);\n\t\t\t\t\tCollectNamespacesForTypeReference(method.ReturnType);\n\t\t\t\t\tforeach (var param in method.Parameters)\n\t\t\t\t\t\tCollectNamespacesForTypeReference(param.Type);\n\t\t\t\t\tforeach (var arg in method.TypeArguments)\n\t\t\t\t\t\tCollectNamespacesForTypeReference(arg);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Resolver/AliasNamespaceResolveResult.cs",
    "content": "//\n// AliasResolveResult.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@xamarin.com>\n//\n// Copyright (c) 2013 Xamarin Inc. (http://xamarin.com)\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.Semantics;\n\nnamespace ICSharpCode.Decompiler.CSharp.Resolver\n{\n\t/// <summary>\n\t/// Represents a namespace resolve result that's resolved using an alias.\n\t/// </summary>\n\tpublic class AliasNamespaceResolveResult : NamespaceResolveResult\n\t{\n\t\t/// <summary>\n\t\t/// The alias used.\n\t\t/// </summary>\n\t\tpublic string Alias {\n\t\t\tget;\n\t\t\tprivate set;\n\t\t}\n\n\t\tpublic AliasNamespaceResolveResult(string alias, NamespaceResolveResult underlyingResult) : base(underlyingResult.Namespace)\n\t\t{\n\t\t\tthis.Alias = alias;\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Resolver/AliasTypeResolveResult.cs",
    "content": "//\n// AliasTypeResolveResult.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@xamarin.com>\n//\n// Copyright (c) 2013 Xamarin Inc. (http://xamarin.com)\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.Semantics;\n\nnamespace ICSharpCode.Decompiler.CSharp.Resolver\n{\n\t/// <summary>\n\t/// Represents a type resolve result that's resolved using an alias.\n\t/// </summary>\n\tpublic class AliasTypeResolveResult : TypeResolveResult\n\t{\n\t\t/// <summary>\n\t\t/// The alias used.\n\t\t/// </summary>\n\t\tpublic string Alias {\n\t\t\tget;\n\t\t\tprivate set;\n\t\t}\n\n\t\tpublic AliasTypeResolveResult(string alias, TypeResolveResult underlyingResult) : base(underlyingResult.Type)\n\t\t{\n\t\t\tthis.Alias = alias;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Resolver/AwaitResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Resolver\n{\n\t/// <summary>\n\t/// Represents the result of an await expression.\n\t/// </summary>\n\tpublic class AwaitResolveResult : ResolveResult\n\t{\n\t\t/// <summary>\n\t\t/// The method representing the GetAwaiter() call. Can be an <see cref=\"InvocationResolveResult\"/> or a <see cref=\"DynamicInvocationResolveResult\"/>.\n\t\t/// </summary>\n\t\tpublic readonly ResolveResult GetAwaiterInvocation;\n\n\t\t/// <summary>\n\t\t/// Awaiter type. Will not be null (but can be UnknownType).\n\t\t/// </summary>\n\t\tpublic readonly IType AwaiterType;\n\n\t\t/// <summary>\n\t\t/// Property representing the IsCompleted property on the awaiter type. Can be null if the awaiter type or the property was not found, or when awaiting a dynamic expression.\n\t\t/// </summary>\n\t\tpublic readonly IProperty IsCompletedProperty;\n\n\t\t/// <summary>\n\t\t/// Method representing the OnCompleted method on the awaiter type. Can be null if the awaiter type or the method was not found, or when awaiting a dynamic expression.\n\t\t/// This can also refer to an UnsafeOnCompleted method, if the awaiter type implements <c>System.Runtime.CompilerServices.ICriticalNotifyCompletion</c>.\n\t\t/// </summary>\n\t\tpublic readonly IMethod OnCompletedMethod;\n\n\t\t/// <summary>\n\t\t/// Method representing the GetResult method on the awaiter type. Can be null if the awaiter type or the method was not found, or when awaiting a dynamic expression.\n\t\t/// </summary>\n\t\tpublic readonly IMethod GetResultMethod;\n\n\t\tpublic AwaitResolveResult(IType resultType, ResolveResult getAwaiterInvocation, IType awaiterType, IProperty isCompletedProperty, IMethod onCompletedMethod, IMethod getResultMethod)\n\t\t\t: base(resultType)\n\t\t{\n\t\t\tif (awaiterType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(awaiterType));\n\t\t\tif (getAwaiterInvocation == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(getAwaiterInvocation));\n\t\t\tthis.GetAwaiterInvocation = getAwaiterInvocation;\n\t\t\tthis.AwaiterType = awaiterType;\n\t\t\tthis.IsCompletedProperty = isCompletedProperty;\n\t\t\tthis.OnCompletedMethod = onCompletedMethod;\n\t\t\tthis.GetResultMethod = getResultMethod;\n\t\t}\n\n\t\tpublic override bool IsError {\n\t\t\tget { return this.GetAwaiterInvocation.IsError || (AwaiterType.Kind != TypeKind.Dynamic && (this.IsCompletedProperty == null || this.OnCompletedMethod == null || this.GetResultMethod == null)); }\n\t\t}\n\n\t\tpublic override IEnumerable<ResolveResult> GetChildResults()\n\t\t{\n\t\t\treturn new[] { GetAwaiterInvocation };\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Resolver/CSharpConversions.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp.Resolver\n{\n\t/// <summary>\n\t/// Contains logic that determines whether an implicit conversion exists between two types.\n\t/// </summary>\n\t/// <remarks>\n\t/// This class is thread-safe.\n\t/// </remarks>\n\tpublic sealed class CSharpConversions\n\t{\n\t\treadonly ConcurrentDictionary<TypePair, Conversion> implicitConversionCache = new ConcurrentDictionary<TypePair, Conversion>();\n\t\treadonly ICompilation compilation;\n\n\t\tpublic CSharpConversions(ICompilation compilation)\n\t\t{\n\t\t\tif (compilation == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(compilation));\n\t\t\tthis.compilation = compilation;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the Conversions instance for the specified <see cref=\"ICompilation\"/>.\n\t\t/// This will make use of the context's cache manager to reuse the Conversions instance.\n\t\t/// </summary>\n\t\tpublic static CSharpConversions Get(ICompilation compilation)\n\t\t{\n\t\t\tif (compilation == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(compilation));\n\t\t\tCacheManager cache = compilation.CacheManager;\n\t\t\tCSharpConversions operators = (CSharpConversions)cache.GetShared(typeof(CSharpConversions));\n\t\t\tif (operators == null)\n\t\t\t{\n\t\t\t\toperators = (CSharpConversions)cache.GetOrAddShared(typeof(CSharpConversions), new CSharpConversions(compilation));\n\t\t\t}\n\t\t\treturn operators;\n\t\t}\n\n\t\t#region TypePair (for caching)\n\t\tstruct TypePair : IEquatable<TypePair>\n\t\t{\n\t\t\tpublic readonly IType FromType;\n\t\t\tpublic readonly IType ToType;\n\n\t\t\tpublic TypePair(IType fromType, IType toType)\n\t\t\t{\n\t\t\t\tDebug.Assert(fromType != null && toType != null);\n\t\t\t\tthis.FromType = fromType;\n\t\t\t\tthis.ToType = toType;\n\t\t\t}\n\n\t\t\tpublic override bool Equals(object obj)\n\t\t\t{\n\t\t\t\treturn (obj is TypePair) && Equals((TypePair)obj);\n\t\t\t}\n\n\t\t\tpublic bool Equals(TypePair other)\n\t\t\t{\n\t\t\t\treturn object.Equals(this.FromType, other.FromType) && object.Equals(this.ToType, other.ToType);\n\t\t\t}\n\n\t\t\tpublic override int GetHashCode()\n\t\t\t{\n\t\t\t\tunchecked\n\t\t\t\t{\n\t\t\t\t\treturn 1000000007 * FromType.GetHashCode() + 1000000009 * ToType.GetHashCode();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region ImplicitConversion\n\t\tprivate Conversion ImplicitConversion(ResolveResult resolveResult, IType toType, bool allowUserDefined, bool allowTuple)\n\t\t{\n\t\t\tConversion c;\n\t\t\tif (resolveResult.IsCompileTimeConstant)\n\t\t\t{\n\t\t\t\tc = ImplicitEnumerationConversion(resolveResult, toType);\n\t\t\t\tif (c.IsValid)\n\t\t\t\t\treturn c;\n\t\t\t\tif (ImplicitConstantExpressionConversion(resolveResult, toType))\n\t\t\t\t\treturn Conversion.ImplicitConstantExpressionConversion;\n\t\t\t}\n\t\t\t// C# 9.0 spec: §10.2.5\n\t\t\tif (resolveResult is InterpolatedStringResolveResult)\n\t\t\t{\n\t\t\t\tif (toType.IsKnownType(KnownTypeCode.IFormattable) || toType.IsKnownType(KnownTypeCode.FormattableString))\n\t\t\t\t\treturn Conversion.ImplicitInterpolatedStringConversion;\n\t\t\t}\n\t\t\tif (resolveResult.Type.Kind == TypeKind.Dynamic)\n\t\t\t\treturn Conversion.ImplicitDynamicConversion;\n\t\t\tc = AnonymousFunctionConversion(resolveResult, toType);\n\t\t\tif (c != Conversion.None)\n\t\t\t\treturn c;\n\t\t\tc = MethodGroupConversion(resolveResult, toType);\n\t\t\tif (c != Conversion.None)\n\t\t\t\treturn c;\n\t\t\t// C# 9.0 spec: §10.2.16 default literal conversions\n\t\t\t// TODO\n\t\t\tif (resolveResult.IsCompileTimeConstant)\n\t\t\t{\n\t\t\t\tc = StandardImplicitConversion(resolveResult.Type, toType, allowTuple);\n\t\t\t\tif (c != Conversion.None)\n\t\t\t\t\treturn c;\n\t\t\t\tif (allowUserDefined)\n\t\t\t\t{\n\t\t\t\t\tc = UserDefinedImplicitConversion(resolveResult, resolveResult.Type, toType);\n\t\t\t\t\tif (c != Conversion.None)\n\t\t\t\t\t\treturn c;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (allowTuple && resolveResult is TupleResolveResult tupleRR)\n\t\t\t\t{\n\t\t\t\t\tc = TupleConversion(tupleRR, toType, isExplicit: false);\n\t\t\t\t\tif (c != Conversion.None)\n\t\t\t\t\t\treturn c;\n\t\t\t\t}\n\t\t\t\t// C# 9.0 spec: §10.2.17\n\t\t\t\tif (resolveResult is ThrowResolveResult)\n\t\t\t\t{\n\t\t\t\t\treturn Conversion.ThrowExpressionConversion;\n\t\t\t\t}\n\t\t\t\tif (allowUserDefined && allowTuple)\n\t\t\t\t{\n\t\t\t\t\t// if allowUserDefined and allowTuple are true, we might as well use the cache\n\t\t\t\t\tc = ImplicitConversion(resolveResult.Type, toType);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tc = ImplicitConversion(resolveResult.Type, toType, allowUserDefined, allowTuple);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn c;\n\t\t}\n\n\t\tprivate Conversion ImplicitConversion(IType fromType, IType toType, bool allowUserDefined, bool allowTuple)\n\t\t{\n\t\t\t// C# 4.0 spec: §6.1\n\t\t\tvar c = StandardImplicitConversion(fromType, toType, allowTuple);\n\t\t\tif (c == Conversion.None && allowUserDefined)\n\t\t\t{\n\t\t\t\tc = UserDefinedImplicitConversion(null, fromType, toType);\n\t\t\t}\n\t\t\treturn c;\n\t\t}\n\n\t\tpublic Conversion ImplicitConversion(ResolveResult resolveResult, IType toType)\n\t\t{\n\t\t\tif (resolveResult == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(resolveResult));\n\t\t\treturn ImplicitConversion(resolveResult, toType, allowUserDefined: true, allowTuple: true);\n\t\t}\n\n\t\tpublic Conversion ImplicitConversion(IType fromType, IType toType)\n\t\t{\n\t\t\tif (fromType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(fromType));\n\t\t\tif (toType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(toType));\n\n\t\t\tTypePair pair = new TypePair(fromType, toType);\n\t\t\tif (implicitConversionCache.TryGetValue(pair, out Conversion c))\n\t\t\t\treturn c;\n\n\t\t\tc = ImplicitConversion(fromType, toType, allowUserDefined: true, allowTuple: true);\n\n\t\t\timplicitConversionCache[pair] = c;\n\t\t\treturn c;\n\t\t}\n\n\t\tpublic Conversion StandardImplicitConversion(IType fromType, IType toType)\n\t\t{\n\t\t\tif (fromType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(fromType));\n\t\t\tif (toType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(toType));\n\t\t\treturn StandardImplicitConversion(fromType, toType, allowTupleConversion: true);\n\t\t}\n\n\t\tConversion StandardImplicitConversion(IType fromType, IType toType, bool allowTupleConversion)\n\t\t{\n\t\t\t// C# 9.0 spec: §10.4.2\n\t\t\tif (IdentityConversion(fromType, toType))\n\t\t\t\treturn Conversion.IdentityConversion;\n\t\t\tif (ImplicitNumericConversion(fromType, toType))\n\t\t\t\treturn Conversion.ImplicitNumericConversion;\n\t\t\tConversion c = ImplicitNullableConversion(fromType, toType);\n\t\t\tif (c != Conversion.None)\n\t\t\t\treturn c;\n\t\t\tif (NullLiteralConversion(fromType, toType))\n\t\t\t\treturn Conversion.NullLiteralConversion;\n\t\t\tif (ImplicitReferenceConversion(fromType, toType, 0))\n\t\t\t\treturn Conversion.ImplicitReferenceConversion;\n\t\t\tif (IsBoxingConversion(fromType, toType))\n\t\t\t\treturn Conversion.BoxingConversion;\n\t\t\tif (ImplicitTypeParameterConversion(fromType, toType))\n\t\t\t{\n\t\t\t\t// Implicit type parameter conversions that aren't also\n\t\t\t\t// reference conversions are considered to be boxing conversions\n\t\t\t\treturn Conversion.BoxingConversion;\n\t\t\t}\n\t\t\tif (ImplicitPointerConversion(fromType, toType))\n\t\t\t\treturn Conversion.ImplicitPointerConversion;\n\t\t\tif (allowTupleConversion)\n\t\t\t{\n\t\t\t\t// TODO are tuple conversions really standard implicit conversions?\n\t\t\t\t// the C# 9.0 spec doesn't list them as standard implicit conversions.\n\t\t\t\tc = TupleConversion(fromType, toType, isExplicit: false);\n\t\t\t\tif (c != Conversion.None)\n\t\t\t\t\treturn c;\n\t\t\t}\n\t\t\tif ((toType.IsKnownType(KnownTypeCode.SpanOfT) || toType.IsKnownType(KnownTypeCode.ReadOnlySpanOfT))\n\t\t\t\t&& fromType.IsInlineArrayType())\n\t\t\t{\n\t\t\t\tvar elementType = fromType.GetInlineArrayElementType();\n\t\t\t\tvar spanElementType = toType.TypeArguments[0];\n\t\t\t\tif (IdentityConversion(elementType, spanElementType))\n\t\t\t\t\treturn Conversion.InlineArrayConversion;\n\t\t\t}\n\t\t\tif (IsImplicitSpanConversion(fromType, toType))\n\t\t\t{\n\t\t\t\treturn Conversion.ImplicitSpanConversion;\n\t\t\t}\n\t\t\treturn Conversion.None;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the type 'fromType' is convertible to 'toType'\n\t\t/// using one of the conversions allowed when satisfying constraints (§4.4.4)\n\t\t/// </summary>\n\t\tpublic bool IsConstraintConvertible(IType fromType, IType toType)\n\t\t{\n\t\t\tif (fromType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(fromType));\n\t\t\tif (toType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(toType));\n\n\t\t\tif (IdentityConversion(fromType, toType))\n\t\t\t\treturn true;\n\t\t\tif (ImplicitReferenceConversion(fromType, toType, 0))\n\t\t\t\treturn true;\n\t\t\tif (NullableType.IsNullable(fromType))\n\t\t\t{\n\t\t\t\t// An 'object' constraint still allows nullable value types\n\t\t\t\t// (object constraints don't exist in C#, but are inserted by DefaultResolvedTypeParameter.DirectBaseTypes)\n\t\t\t\tif (toType.IsKnownType(KnownTypeCode.Object))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (IsBoxingConversion(fromType, toType))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (ImplicitTypeParameterConversion(fromType, toType))\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\t\t#endregion\n\n\t\t#region ExplicitConversion\n\t\tpublic Conversion ExplicitConversion(ResolveResult resolveResult, IType toType)\n\t\t{\n\t\t\tif (resolveResult == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(resolveResult));\n\t\t\tif (toType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(toType));\n\n\t\t\tif (resolveResult.Type.Kind == TypeKind.Dynamic)\n\t\t\t\treturn Conversion.ExplicitDynamicConversion;\n\t\t\tConversion c = ImplicitConversion(resolveResult, toType, allowUserDefined: false, allowTuple: false);\n\t\t\tif (c != Conversion.None)\n\t\t\t\treturn c;\n\t\t\tif (resolveResult is TupleResolveResult tupleRR)\n\t\t\t{\n\t\t\t\tc = TupleConversion(tupleRR, toType, isExplicit: true);\n\t\t\t\tif (c != Conversion.None)\n\t\t\t\t\treturn c;\n\t\t\t}\n\t\t\tc = ExplicitConversionImpl(resolveResult.Type, toType);\n\t\t\tif (c != Conversion.None)\n\t\t\t\treturn c;\n\t\t\treturn UserDefinedExplicitConversion(resolveResult, resolveResult.Type, toType);\n\t\t}\n\n\t\tpublic Conversion ExplicitConversion(IType fromType, IType toType)\n\t\t{\n\t\t\tif (fromType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(fromType));\n\t\t\tif (toType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(toType));\n\n\t\t\tConversion c = ImplicitConversion(fromType, toType, allowUserDefined: false, allowTuple: false);\n\t\t\tif (c != Conversion.None)\n\t\t\t\treturn c;\n\t\t\tc = ExplicitConversionImpl(fromType, toType);\n\t\t\tif (c != Conversion.None)\n\t\t\t\treturn c;\n\t\t\treturn UserDefinedExplicitConversion(null, fromType, toType);\n\t\t}\n\n\t\tConversion ExplicitConversionNotUserDefined(IType fromType, IType toType)\n\t\t{\n\t\t\tConversion c = ImplicitConversion(fromType, toType, allowUserDefined: false, allowTuple: false);\n\t\t\tif (c != Conversion.None)\n\t\t\t\treturn c;\n\t\t\treturn ExplicitConversionImpl(fromType, toType);\n\t\t}\n\n\t\tConversion ExplicitConversionImpl(IType fromType, IType toType)\n\t\t{\n\t\t\t// This method is called after we already checked for implicit conversions,\n\t\t\t// so any remaining conversions must be explicit.\n\t\t\tif (AnyNumericConversion(fromType, toType))\n\t\t\t\treturn Conversion.ExplicitNumericConversion;\n\t\t\tif (ExplicitEnumerationConversion(fromType, toType))\n\t\t\t\treturn Conversion.EnumerationConversion(false, false);\n\t\t\tConversion c = ExplicitNullableConversion(fromType, toType);\n\t\t\tif (c != Conversion.None)\n\t\t\t\treturn c;\n\t\t\tif (ExplicitReferenceConversion(fromType, toType))\n\t\t\t\treturn Conversion.ExplicitReferenceConversion;\n\t\t\tif (UnboxingConversion(fromType, toType))\n\t\t\t\treturn Conversion.UnboxingConversion;\n\t\t\tc = ExplicitTypeParameterConversion(fromType, toType);\n\t\t\tif (c != Conversion.None)\n\t\t\t\treturn c;\n\t\t\tif (ExplicitPointerConversion(fromType, toType))\n\t\t\t\treturn Conversion.ExplicitPointerConversion;\n\t\t\treturn TupleConversion(fromType, toType, isExplicit: true);\n\t\t}\n\t\t#endregion\n\n\t\t#region Identity Conversion\n\t\t/// <summary>\n\t\t/// Gets whether there is an identity conversion from <paramref name=\"fromType\"/> to <paramref name=\"toType\"/>\n\t\t/// </summary>\n\t\tpublic bool IdentityConversion(IType fromType, IType toType)\n\t\t{\n\t\t\t// C# 4.0 spec: §6.1.1\n\t\t\tfromType = fromType.AcceptVisitor(NormalizeTypeVisitor.TypeErasure);\n\t\t\ttoType = toType.AcceptVisitor(NormalizeTypeVisitor.TypeErasure);\n\t\t\treturn fromType.Equals(toType);\n\t\t}\n\t\t#endregion\n\n\t\t#region Numeric Conversions\n\t\tstatic readonly bool[,] implicitNumericConversionLookup = {\n\t\t\t//       to:   short  ushort  int   uint   long   ulong\n\t\t\t// from:\n\t\t\t/* char   */ { false, true , true , true , true , true  },\n\t\t\t/* sbyte  */ { true , false, true , false, true , false },\n\t\t\t/* byte   */ { true , true , true , true , true , true  },\n\t\t\t/* short  */ { true , false, true , false, true , false },\n\t\t\t/* ushort */ { false, true , true , true , true , true  },\n\t\t\t/* int    */ { false, false, true , false, true , false },\n\t\t\t/* uint   */ { false, false, false, true , true , true  },\n\t\t\t/* long   */ { false, false, false, false, true , false },\n\t\t\t/* ulong  */ { false, false, false, false, false, true  },\n\t\t};\n\n\t\tbool ImplicitNumericConversion(IType fromType, IType toType)\n\t\t{\n\t\t\t// C# 9.0 spec: §10.2.3\n\n\t\t\tTypeCode from = ReflectionHelper.GetTypeCode(fromType);\n\t\t\tif (from == TypeCode.Empty)\n\t\t\t{\n\t\t\t\t// When converting from a native-sized integer, treat it as 64-bits\n\t\t\t\tswitch (fromType.Kind)\n\t\t\t\t{\n\t\t\t\t\tcase TypeKind.NInt:\n\t\t\t\t\t\tfrom = TypeCode.Int64;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeKind.NUInt:\n\t\t\t\t\t\tfrom = TypeCode.UInt64;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tTypeCode to = ReflectionHelper.GetTypeCode(toType);\n\t\t\tif (to == TypeCode.Empty)\n\t\t\t{\n\t\t\t\t// When converting to a native-sized integer, only 32-bits can be stored safely\n\t\t\t\tswitch (toType.Kind)\n\t\t\t\t{\n\t\t\t\t\tcase TypeKind.NInt:\n\t\t\t\t\t\tto = TypeCode.Int32;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeKind.NUInt:\n\t\t\t\t\t\tto = TypeCode.UInt32;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (to >= TypeCode.Single && to <= TypeCode.Decimal)\n\t\t\t{\n\t\t\t\t// Conversions to float/double/decimal exist from all integral types,\n\t\t\t\t// and there's a conversion from float to double.\n\t\t\t\treturn from >= TypeCode.Char && from <= TypeCode.UInt64\n\t\t\t\t\t|| from == TypeCode.Single && to == TypeCode.Double;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Conversions to integral types: look at the table\n\t\t\t\treturn from >= TypeCode.Char && from <= TypeCode.UInt64\n\t\t\t\t\t&& to >= TypeCode.Int16 && to <= TypeCode.UInt64\n\t\t\t\t\t&& implicitNumericConversionLookup[from - TypeCode.Char, to - TypeCode.Int16];\n\t\t\t}\n\t\t}\n\n\t\tbool IsNumericType(IType type)\n\t\t{\n\t\t\tswitch (type.Kind)\n\t\t\t{\n\t\t\t\tcase TypeKind.NInt:\n\t\t\t\tcase TypeKind.NUInt:\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\tTypeCode c = ReflectionHelper.GetTypeCode(type);\n\t\t\treturn c >= TypeCode.Char && c <= TypeCode.Decimal;\n\t\t}\n\n\t\tbool AnyNumericConversion(IType fromType, IType toType)\n\t\t{\n\t\t\t// C# 4.0 spec: §6.1.2 + §6.2.1\n\t\t\treturn IsNumericType(fromType) && IsNumericType(toType);\n\t\t}\n\t\t#endregion\n\n\t\t#region Enumeration Conversions\n\t\tConversion ImplicitEnumerationConversion(ResolveResult rr, IType toType)\n\t\t{\n\t\t\t// C# 9.0 spec: §10.2.4 + enum part of §10.2.6 (Nullable conversions)\n\t\t\tDebug.Assert(rr.IsCompileTimeConstant);\n\t\t\tTypeCode constantType = ReflectionHelper.GetTypeCode(rr.Type);\n\t\t\tif (constantType >= TypeCode.SByte && constantType <= TypeCode.Decimal && Convert.ToDouble(rr.ConstantValue) == 0)\n\t\t\t{\n\t\t\t\tif (NullableType.GetUnderlyingType(toType).Kind == TypeKind.Enum)\n\t\t\t\t{\n\t\t\t\t\treturn Conversion.EnumerationConversion(true, NullableType.IsNullable(toType));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn Conversion.None;\n\t\t}\n\n\t\tbool ExplicitEnumerationConversion(IType fromType, IType toType)\n\t\t{\n\t\t\t// C# 4.0 spec: §6.2.2\n\t\t\tif (fromType.Kind == TypeKind.Enum)\n\t\t\t{\n\t\t\t\treturn toType.Kind == TypeKind.Enum || IsNumericType(toType);\n\t\t\t}\n\t\t\telse if (IsNumericType(fromType))\n\t\t\t{\n\t\t\t\treturn toType.Kind == TypeKind.Enum;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\t#endregion\n\n\t\t#region Nullable Conversions\n\t\tConversion ImplicitNullableConversion(IType fromType, IType toType)\n\t\t{\n\t\t\t// C# 9.0 spec: §10.2.6\n\t\t\tif (NullableType.IsNullable(toType))\n\t\t\t{\n\t\t\t\tIType t = NullableType.GetUnderlyingType(toType);\n\t\t\t\tIType s = NullableType.GetUnderlyingType(fromType); // might or might not be nullable\n\t\t\t\tif (IdentityConversion(s, t))\n\t\t\t\t\treturn Conversion.ImplicitNullableConversion;\n\t\t\t\tif (ImplicitNumericConversion(s, t))\n\t\t\t\t\treturn Conversion.ImplicitLiftedNumericConversion;\n\t\t\t}\n\t\t\treturn Conversion.None;\n\t\t}\n\n\t\tConversion ExplicitNullableConversion(IType fromType, IType toType)\n\t\t{\n\t\t\t// C# 4.0 spec: §6.1.4\n\t\t\tif (NullableType.IsNullable(toType) || NullableType.IsNullable(fromType))\n\t\t\t{\n\t\t\t\tIType t = NullableType.GetUnderlyingType(toType);\n\t\t\t\tIType s = NullableType.GetUnderlyingType(fromType);\n\t\t\t\tif (IdentityConversion(s, t))\n\t\t\t\t\treturn Conversion.ExplicitNullableConversion;\n\t\t\t\tif (AnyNumericConversion(s, t))\n\t\t\t\t\treturn Conversion.ExplicitLiftedNumericConversion;\n\t\t\t\tif (ExplicitEnumerationConversion(s, t))\n\t\t\t\t\treturn Conversion.EnumerationConversion(false, true);\n\t\t\t}\n\t\t\treturn Conversion.None;\n\t\t}\n\t\t#endregion\n\n\t\t#region Null Literal Conversion\n\t\tbool NullLiteralConversion(IType fromType, IType toType)\n\t\t{\n\t\t\t// C# 9.0 spec: §10.2.7\n\t\t\tif (fromType.Kind == TypeKind.Null)\n\t\t\t{\n\t\t\t\treturn NullableType.IsNullable(toType) || toType.IsReferenceType == true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Implicit Reference Conversion\n\t\tpublic bool IsImplicitReferenceConversion(IType fromType, IType toType)\n\t\t{\n\t\t\treturn ImplicitReferenceConversion(fromType, toType, 0);\n\t\t}\n\n\t\tbool ImplicitReferenceConversion(IType fromType, IType toType, int subtypeCheckNestingDepth)\n\t\t{\n\t\t\t// C# 9.0 spec: §10.2.8\n\n\t\t\t// reference conversions are possible:\n\t\t\t// - if both types are known to be reference types\n\t\t\t// - if both types are type parameters and fromType has a class constraint\n\t\t\t//     (ImplicitTypeParameterConversionWithClassConstraintOnlyOnT)\n\t\t\tif (!(fromType.IsReferenceType == true && toType.IsReferenceType != false))\n\t\t\t\treturn false;\n\n\t\t\tArrayType fromArray = fromType as ArrayType;\n\t\t\tif (fromArray != null)\n\t\t\t{\n\t\t\t\tArrayType toArray = toType as ArrayType;\n\t\t\t\tif (toArray != null)\n\t\t\t\t{\n\t\t\t\t\t// array covariance (the broken kind)\n\t\t\t\t\treturn fromArray.Dimensions == toArray.Dimensions\n\t\t\t\t\t\t&& ImplicitReferenceConversion(fromArray.ElementType, toArray.ElementType, subtypeCheckNestingDepth);\n\t\t\t\t}\n\t\t\t\t// conversion from single-dimensional array S[] to IList<T>/IReadOnlyList<T> + base interfaces:\n\t\t\t\tIType toTypeArgument = UnpackGenericArrayInterface(toType);\n\t\t\t\tif (fromArray.Dimensions == 1 && toTypeArgument != null)\n\t\t\t\t{\n\t\t\t\t\t// array covariance plays a part here as well (string[] is IList<object>)\n\t\t\t\t\treturn IdentityConversion(fromArray.ElementType, toTypeArgument)\n\t\t\t\t\t\t|| ImplicitReferenceConversion(fromArray.ElementType, toTypeArgument, subtypeCheckNestingDepth);\n\t\t\t\t}\n\t\t\t\t// conversion from any array to System.Array and the interfaces it implements:\n\t\t\t\tIType systemArray = compilation.FindType(KnownTypeCode.Array);\n\t\t\t\treturn ImplicitReferenceConversion(systemArray, toType, subtypeCheckNestingDepth);\n\t\t\t}\n\n\t\t\t// now comes the hard part: traverse the inheritance chain and figure out generics+variance\n\t\t\treturn IsSubtypeOf(fromType, toType, subtypeCheckNestingDepth);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// For <see cref=\"IList{T}\"/>, <see cref=\"ICollection{T}\"/>, <see cref=\"IEnumerable{T}\"/> and <see cref=\"IReadOnlyList{T}\"/>, returns T.\n\t\t/// Otherwise, returns null.\n\t\t/// </summary>\n\t\tIType UnpackGenericArrayInterface(IType interfaceType)\n\t\t{\n\t\t\tif (interfaceType is ParameterizedType pt)\n\t\t\t{\n\t\t\t\tswitch (pt.GetDefinition()?.KnownTypeCode)\n\t\t\t\t{\n\t\t\t\t\tcase KnownTypeCode.IListOfT:\n\t\t\t\t\tcase KnownTypeCode.ICollectionOfT:\n\t\t\t\t\tcase KnownTypeCode.IEnumerableOfT:\n\t\t\t\t\tcase KnownTypeCode.IReadOnlyListOfT:\n\t\t\t\t\tcase KnownTypeCode.IReadOnlyCollectionOfT:\n\t\t\t\t\t\treturn pt.GetTypeArgument(0);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\t// Determines whether s is a subtype of t.\n\t\t// Helper method used for ImplicitReferenceConversion, BoxingConversion and ImplicitTypeParameterConversion\n\n\t\tbool IsSubtypeOf(IType s, IType t, int subtypeCheckNestingDepth)\n\t\t{\n\t\t\t// conversion to dynamic + object are always possible\n\t\t\tif (t.Kind == TypeKind.Dynamic || t.IsKnownType(KnownTypeCode.Object))\n\t\t\t\treturn true;\n\t\t\tif (subtypeCheckNestingDepth > 10)\n\t\t\t{\n\t\t\t\t// Subtyping in C# is undecidable\n\t\t\t\t// (see \"On Decidability of Nominal Subtyping with Variance\" by Andrew J. Kennedy and Benjamin C. Pierce),\n\t\t\t\t// so we'll prevent infinite recursions by putting a limit on the nesting depth of variance conversions.\n\n\t\t\t\t// No real C# code should use generics nested more than 10 levels deep, and even if they do, most of\n\t\t\t\t// those nestings should not involve variance.\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// let GetAllBaseTypes do the work for us\n\t\t\tforeach (IType baseType in s.GetAllBaseTypes())\n\t\t\t{\n\t\t\t\tif (IdentityOrVarianceConversion(baseType, t, subtypeCheckNestingDepth + 1))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tbool IdentityOrVarianceConversion(IType s, IType t, int subtypeCheckNestingDepth)\n\t\t{\n\t\t\tITypeDefinition def = s.GetDefinition();\n\t\t\tif (def != null)\n\t\t\t{\n\t\t\t\tif (!def.Equals(t.GetDefinition()))\n\t\t\t\t\treturn false;\n\t\t\t\tParameterizedType ps = s as ParameterizedType;\n\t\t\t\tParameterizedType pt = t as ParameterizedType;\n\t\t\t\tif (ps != null && pt != null)\n\t\t\t\t{\n\t\t\t\t\t// C# 4.0 spec: §13.1.3.2 Variance Conversion\n\t\t\t\t\tfor (int i = 0; i < def.TypeParameters.Count; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tIType si = ps.GetTypeArgument(i);\n\t\t\t\t\t\tIType ti = pt.GetTypeArgument(i);\n\t\t\t\t\t\tif (IdentityConversion(si, ti))\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tITypeParameter xi = def.TypeParameters[i];\n\t\t\t\t\t\tswitch (xi.Variance)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase VarianceModifier.Covariant:\n\t\t\t\t\t\t\t\tif (!ImplicitReferenceConversion(si, ti, subtypeCheckNestingDepth))\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase VarianceModifier.Contravariant:\n\t\t\t\t\t\t\t\tif (!ImplicitReferenceConversion(ti, si, subtypeCheckNestingDepth))\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (ps != null || pt != null)\n\t\t\t\t{\n\t\t\t\t\treturn false; // only of of them is parameterized, or counts don't match? -> not valid conversion\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// not type definitions? we still need to check for equal types (e.g. s and t might be type parameters)\n\t\t\t\treturn s.Equals(t);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Explicit Reference Conversion\n\t\tbool ExplicitReferenceConversion(IType fromType, IType toType)\n\t\t{\n\t\t\t// C# 4.0 spec: §6.2.4\n\n\t\t\t// test that the types are reference types:\n\t\t\tif (toType.IsReferenceType != true)\n\t\t\t\treturn false;\n\t\t\tif (fromType.IsReferenceType != true)\n\t\t\t{\n\t\t\t\t// special case:\n\t\t\t\t// converting from F to T is a reference conversion where T : class, F\n\t\t\t\t// (because F actually must be a reference type as well, even though C# doesn't treat it as one)\n\t\t\t\tif (fromType.Kind == TypeKind.TypeParameter)\n\t\t\t\t\treturn IsSubtypeOf(toType, fromType, 0);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (toType.Kind == TypeKind.Array)\n\t\t\t{\n\t\t\t\tArrayType toArray = (ArrayType)toType;\n\t\t\t\tif (fromType.Kind == TypeKind.Array)\n\t\t\t\t{\n\t\t\t\t\t// Array covariance\n\t\t\t\t\tArrayType fromArray = (ArrayType)fromType;\n\t\t\t\t\tif (fromArray.Dimensions != toArray.Dimensions)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn ExplicitReferenceConversion(fromArray.ElementType, toArray.ElementType);\n\t\t\t\t}\n\t\t\t\tIType fromTypeArgument = UnpackGenericArrayInterface(fromType);\n\t\t\t\tif (fromTypeArgument != null && toArray.Dimensions == 1)\n\t\t\t\t{\n\t\t\t\t\treturn ExplicitReferenceConversion(fromTypeArgument, toArray.ElementType)\n\t\t\t\t\t\t|| IdentityConversion(fromTypeArgument, toArray.ElementType);\n\t\t\t\t}\n\t\t\t\t// Otherwise treat the array like a sealed class - require implicit conversion in the opposite direction\n\t\t\t\treturn IsImplicitReferenceConversion(toType, fromType);\n\t\t\t}\n\t\t\telse if (fromType.Kind == TypeKind.Array)\n\t\t\t{\n\t\t\t\tArrayType fromArray = (ArrayType)fromType;\n\t\t\t\tIType toTypeArgument = UnpackGenericArrayInterface(toType);\n\t\t\t\tif (toTypeArgument != null && fromArray.Dimensions == 1)\n\t\t\t\t{\n\t\t\t\t\treturn ExplicitReferenceConversion(fromArray.ElementType, toTypeArgument);\n\t\t\t\t}\n\t\t\t\t// Otherwise treat the array like a sealed class\n\t\t\t\treturn IsImplicitReferenceConversion(fromType, toType);\n\t\t\t}\n\t\t\telse if (fromType.Kind == TypeKind.Delegate && toType.Kind == TypeKind.Delegate)\n\t\t\t{\n\t\t\t\tITypeDefinition def = fromType.GetDefinition();\n\t\t\t\tif (def == null || !def.Equals(toType.GetDefinition()))\n\t\t\t\t\treturn false;\n\t\t\t\tParameterizedType ps = fromType as ParameterizedType;\n\t\t\t\tParameterizedType pt = toType as ParameterizedType;\n\t\t\t\tif (ps == null || pt == null)\n\t\t\t\t{\n\t\t\t\t\t// non-generic delegate - return true for the identity conversion\n\t\t\t\t\treturn ps == null && pt == null;\n\t\t\t\t}\n\t\t\t\tfor (int i = 0; i < def.TypeParameters.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tIType si = ps.GetTypeArgument(i);\n\t\t\t\t\tIType ti = pt.GetTypeArgument(i);\n\t\t\t\t\tif (IdentityConversion(si, ti))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tITypeParameter xi = def.TypeParameters[i];\n\t\t\t\t\tswitch (xi.Variance)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase VarianceModifier.Covariant:\n\t\t\t\t\t\t\tif (!ExplicitReferenceConversion(si, ti))\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase VarianceModifier.Contravariant:\n\t\t\t\t\t\t\tif (!(si.IsReferenceType == true && ti.IsReferenceType == true))\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (IsSealedReferenceType(fromType))\n\t\t\t{\n\t\t\t\t// If the source type is sealed, explicit conversions can't do anything more than implicit ones\n\t\t\t\treturn IsImplicitReferenceConversion(fromType, toType);\n\t\t\t}\n\t\t\telse if (IsSealedReferenceType(toType))\n\t\t\t{\n\t\t\t\t// The the target type is sealed, there must be an implicit conversion in the opposite direction\n\t\t\t\treturn IsImplicitReferenceConversion(toType, fromType);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (fromType.Kind == TypeKind.Interface || toType.Kind == TypeKind.Interface)\n\t\t\t\t\treturn true;\n\t\t\t\telse\n\t\t\t\t\treturn IsImplicitReferenceConversion(toType, fromType)\n\t\t\t\t\t\t|| IsImplicitReferenceConversion(fromType, toType);\n\t\t\t}\n\t\t}\n\n\t\tbool IsSealedReferenceType(IType type)\n\t\t{\n\t\t\tTypeKind kind = type.Kind;\n\t\t\treturn kind == TypeKind.Class && type.GetDefinition().IsSealed\n\t\t\t\t|| kind == TypeKind.Delegate;\n\t\t}\n\t\t#endregion\n\n\t\t#region Boxing Conversions\n\t\tbool IsBoxingConversion(IType fromType, IType toType)\n\t\t{\n\t\t\t// C# 9.0 spec: §10.2.9\n\t\t\tfromType = NullableType.GetUnderlyingType(fromType);\n\t\t\tif (fromType.IsReferenceType == false && !fromType.IsByRefLike && toType.IsReferenceType == true)\n\t\t\t\treturn IsSubtypeOf(fromType, toType, 0);\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the conversion from fromType to toType is a boxing conversion,\n\t\t/// or an implicit conversion involving a type parameter that might be\n\t\t/// a boxing conversion when instantiated with a value type.\n\t\t/// </summary>\n\t\tpublic bool IsBoxingConversionOrInvolvingTypeParameter(IType fromType, IType toType)\n\t\t{\n\t\t\treturn IsBoxingConversion(fromType, toType)\n\t\t\t\t|| ImplicitTypeParameterConversion(fromType, toType);\n\t\t}\n\n\t\tbool UnboxingConversion(IType fromType, IType toType)\n\t\t{\n\t\t\t// C# 4.0 spec: §6.2.5\n\t\t\ttoType = NullableType.GetUnderlyingType(toType);\n\t\t\tif (fromType.IsReferenceType == true && toType.IsReferenceType == false)\n\t\t\t\treturn IsSubtypeOf(toType, fromType, 0);\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\t#endregion\n\n\t\t#region Implicit Constant-Expression Conversion\n\t\tbool ImplicitConstantExpressionConversion(ResolveResult rr, IType toType)\n\t\t{\n\t\t\tif (rr == null || !rr.IsCompileTimeConstant)\n\t\t\t\treturn false;\n\t\t\t// C# 9.0 spec: §10.2.11 + part of §10.2.6 (Nullable conversions)\n\t\t\tTypeCode fromTypeCode = ReflectionHelper.GetTypeCode(rr.Type);\n\t\t\ttoType = NullableType.GetUnderlyingType(toType);\n\t\t\tTypeCode toTypeCode = ReflectionHelper.GetTypeCode(toType);\n\t\t\tif (toType.Kind == TypeKind.NUInt)\n\t\t\t{\n\t\t\t\ttoTypeCode = TypeCode.UInt32;\n\t\t\t}\n\t\t\tif (fromTypeCode == TypeCode.Int64)\n\t\t\t{\n\t\t\t\tlong val = (long)rr.ConstantValue;\n\t\t\t\treturn val >= 0 && toTypeCode == TypeCode.UInt64;\n\t\t\t}\n\t\t\telse if (fromTypeCode == TypeCode.Int32)\n\t\t\t{\n\t\t\t\tobject cv = rr.ConstantValue;\n\t\t\t\tif (cv == null)\n\t\t\t\t\treturn false;\n\t\t\t\tint val = (int)cv;\n\t\t\t\tswitch (toTypeCode)\n\t\t\t\t{\n\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\treturn val >= SByte.MinValue && val <= SByte.MaxValue;\n\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\treturn val >= Byte.MinValue && val <= Byte.MaxValue;\n\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\treturn val >= Int16.MinValue && val <= Int16.MaxValue;\n\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\treturn val >= UInt16.MinValue && val <= UInt16.MaxValue;\n\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\treturn val >= 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\t#endregion\n\n\t\t#region Conversions involving type parameters\n\t\t/// <summary>\n\t\t/// Implicit conversions involving type parameters.\n\t\t/// </summary>\n\t\tbool ImplicitTypeParameterConversion(IType fromType, IType toType)\n\t\t{\n\t\t\t// C# 9.0 spec: §10.2.12\n\t\t\tif (fromType.Kind != TypeKind.TypeParameter)\n\t\t\t\treturn false; // not a type parameter\n\t\t\tif (fromType.IsReferenceType.HasValue)\n\t\t\t\treturn false; // already handled by ImplicitReferenceConversion/BoxingConversion\n\t\t\treturn IsSubtypeOf(fromType, toType, 0);\n\t\t}\n\n\t\tConversion ExplicitTypeParameterConversion(IType fromType, IType toType)\n\t\t{\n\t\t\tif (toType.Kind == TypeKind.TypeParameter)\n\t\t\t{\n\t\t\t\t// Explicit type parameter conversions that aren't also\n\t\t\t\t// reference conversions are considered to be unboxing conversions\n\t\t\t\tif (fromType.Kind == TypeKind.Interface || IsSubtypeOf(toType, fromType, 0))\n\t\t\t\t\treturn Conversion.UnboxingConversion;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (fromType.Kind == TypeKind.TypeParameter && toType.Kind == TypeKind.Interface)\n\t\t\t\t\treturn Conversion.BoxingConversion;\n\t\t\t}\n\t\t\treturn Conversion.None;\n\t\t}\n\t\t#endregion\n\n\t\t#region Pointer Conversions\n\t\tbool ImplicitPointerConversion(IType fromType, IType toType)\n\t\t{\n\t\t\t// C# 4.0 spec: §18.4 Pointer conversions\n\t\t\tif (fromType.Kind.IsAnyPointer() && toType is PointerType && toType.ReflectionName == \"System.Void*\")\n\t\t\t\treturn true;\n\t\t\tif (fromType.Kind == TypeKind.Null && toType.Kind.IsAnyPointer())\n\t\t\t\treturn true;\n\t\t\tif (fromType is FunctionPointerType fromFnPtr && toType is FunctionPointerType toFnPtr\n\t\t\t\t&& fromFnPtr.CallingConvention == toFnPtr.CallingConvention\n\t\t\t\t&& fromFnPtr.ParameterTypes.Length == toFnPtr.ParameterTypes.Length)\n\t\t\t{\n\t\t\t\t// Variance applies to function pointer types\n\t\t\t\tconst int nestingDepth = 0;\n\t\t\t\tif (!(IdentityConversion(fromFnPtr.ReturnType, toFnPtr.ReturnType)\n\t\t\t\t\t|| ImplicitReferenceConversion(fromFnPtr.ReturnType, toFnPtr.ReturnType, nestingDepth)))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tforeach (var (fromPT, toPT) in fromFnPtr.ParameterTypes.Zip(toFnPtr.ParameterTypes))\n\t\t\t\t{\n\t\t\t\t\tif (!(IdentityConversion(toPT, fromPT)\n\t\t\t\t\t\t|| ImplicitReferenceConversion(toPT, fromPT, nestingDepth)))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tbool ExplicitPointerConversion(IType fromType, IType toType)\n\t\t{\n\t\t\t// C# 4.0 spec: §18.4 Pointer conversions\n\t\t\tif (fromType.Kind.IsAnyPointer())\n\t\t\t{\n\t\t\t\treturn toType.Kind.IsAnyPointer() || IsIntegerType(toType);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn toType.Kind.IsAnyPointer() && IsIntegerType(fromType);\n\t\t\t}\n\t\t}\n\n\t\tbool IsIntegerType(IType type)\n\t\t{\n\t\t\tswitch (type.Kind)\n\t\t\t{\n\t\t\t\tcase TypeKind.NInt:\n\t\t\t\tcase TypeKind.NUInt:\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\tTypeCode c = ReflectionHelper.GetTypeCode(type);\n\t\t\treturn c >= TypeCode.SByte && c <= TypeCode.UInt64;\n\t\t}\n\t\t#endregion\n\n\t\t#region User-Defined Conversions\n\t\t/// <summary>\n\t\t/// Gets whether type A is encompassed by type B.\n\t\t/// </summary>\n\t\tbool IsEncompassedBy(IType a, IType b)\n\t\t{\n\t\t\treturn StandardImplicitConversion(a, b).IsValid;\n\t\t}\n\n\t\tbool IsEncompassingOrEncompassedBy(IType a, IType b)\n\t\t{\n\t\t\treturn (StandardImplicitConversion(a, b).IsValid || StandardImplicitConversion(b, a).IsValid);\n\t\t}\n\n\t\tIType FindMostEncompassedType(IEnumerable<IType> candidates)\n\t\t{\n\t\t\tIType best = null;\n\t\t\tforeach (var current in candidates)\n\t\t\t{\n\t\t\t\tif (best == null || IsEncompassedBy(current, best))\n\t\t\t\t\tbest = current;\n\t\t\t\telse if (!IsEncompassedBy(best, current))\n\t\t\t\t\treturn null;    // Ambiguous\n\t\t\t}\n\t\t\treturn best;\n\t\t}\n\n\t\tIType FindMostEncompassingType(IEnumerable<IType> candidates)\n\t\t{\n\t\t\tIType best = null;\n\t\t\tforeach (var current in candidates)\n\t\t\t{\n\t\t\t\tif (best == null || IsEncompassedBy(best, current))\n\t\t\t\t\tbest = current;\n\t\t\t\telse if (!IsEncompassedBy(current, best))\n\t\t\t\t\treturn null;    // Ambiguous\n\t\t\t}\n\t\t\treturn best;\n\t\t}\n\n\t\tConversion SelectOperator(IType mostSpecificSource, IType mostSpecificTarget, IList<OperatorInfo> operators, bool isImplicit, IType source, IType target)\n\t\t{\n\t\t\tvar selected = operators.Where(op => op.SourceType.Equals(mostSpecificSource) && op.TargetType.Equals(mostSpecificTarget)).ToList();\n\t\t\tif (selected.Count == 0)\n\t\t\t\treturn Conversion.None;\n\n\t\t\tif (selected.Count == 1)\n\t\t\t{\n\t\t\t\treturn Conversion.UserDefinedConversion(selected[0].Method,\n\t\t\t\t\tisLifted: selected[0].IsLifted,\n\t\t\t\t\tisImplicit: isImplicit,\n\t\t\t\t\tconversionBeforeUserDefinedOperator: ExplicitConversionNotUserDefined(source, mostSpecificSource),\n\t\t\t\t\tconversionAfterUserDefinedOperator: ExplicitConversionNotUserDefined(mostSpecificTarget, target));\n\t\t\t}\n\n\t\t\tint nNonLifted = selected.Count(s => !s.IsLifted);\n\t\t\tif (nNonLifted == 1)\n\t\t\t{\n\t\t\t\tvar op = selected.First(s => !s.IsLifted);\n\t\t\t\treturn Conversion.UserDefinedConversion(op.Method,\n\t\t\t\t\tisLifted: op.IsLifted,\n\t\t\t\t\tisImplicit: isImplicit,\n\t\t\t\t\tconversionBeforeUserDefinedOperator: ExplicitConversionNotUserDefined(source, mostSpecificSource),\n\t\t\t\t\tconversionAfterUserDefinedOperator: ExplicitConversionNotUserDefined(mostSpecificTarget, target));\n\t\t\t}\n\n\t\t\treturn Conversion.UserDefinedConversion(selected[0].Method,\n\t\t\t\tisLifted: selected[0].IsLifted,\n\t\t\t\tisImplicit: isImplicit,\n\t\t\t\tisAmbiguous: true,\n\t\t\t\tconversionBeforeUserDefinedOperator: ExplicitConversionNotUserDefined(source, mostSpecificSource),\n\t\t\t\tconversionAfterUserDefinedOperator: ExplicitConversionNotUserDefined(mostSpecificTarget, target));\n\t\t}\n\n\t\tConversion UserDefinedImplicitConversion(ResolveResult fromResult, IType fromType, IType toType)\n\t\t{\n\t\t\t// C# 4.0 spec §6.4.4 User-defined implicit conversions\n\n\t\t\t// user-defined conversions are not supported with interfaces\n\t\t\tif (fromType.Kind == TypeKind.Interface || toType.Kind == TypeKind.Interface)\n\t\t\t{\n\t\t\t\treturn Conversion.None;\n\t\t\t}\n\n\t\t\tvar operators = GetApplicableConversionOperators(fromResult, fromType, toType, false);\n\n\t\t\tif (operators.Count > 0)\n\t\t\t{\n\t\t\t\tvar mostSpecificSource = operators.Any(op => op.SourceType.Equals(fromType)) ? fromType : FindMostEncompassedType(operators.Select(op => op.SourceType));\n\t\t\t\tif (mostSpecificSource == null)\n\t\t\t\t\treturn Conversion.UserDefinedConversion(operators[0].Method, isImplicit: true, isLifted: operators[0].IsLifted, isAmbiguous: true, conversionBeforeUserDefinedOperator: Conversion.None, conversionAfterUserDefinedOperator: Conversion.None);\n\t\t\t\tvar mostSpecificTarget = operators.Any(op => op.TargetType.Equals(toType)) ? toType : FindMostEncompassingType(operators.Select(op => op.TargetType));\n\t\t\t\tif (mostSpecificTarget == null)\n\t\t\t\t{\n\t\t\t\t\tif (NullableType.IsNullable(toType))\n\t\t\t\t\t\treturn UserDefinedImplicitConversion(fromResult, fromType, NullableType.GetUnderlyingType(toType));\n\t\t\t\t\telse\n\t\t\t\t\t\treturn Conversion.UserDefinedConversion(operators[0].Method, isImplicit: true, isLifted: operators[0].IsLifted, isAmbiguous: true, conversionBeforeUserDefinedOperator: Conversion.None, conversionAfterUserDefinedOperator: Conversion.None);\n\t\t\t\t}\n\n\t\t\t\tvar selected = SelectOperator(mostSpecificSource, mostSpecificTarget, operators, true, fromType, toType);\n\t\t\t\tif (selected != Conversion.None)\n\t\t\t\t{\n\t\t\t\t\tif (selected.IsLifted && NullableType.IsNullable(toType))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Prefer A -> B -> B? over A -> A? -> B?\n\t\t\t\t\t\tvar other = UserDefinedImplicitConversion(fromResult, fromType, NullableType.GetUnderlyingType(toType));\n\t\t\t\t\t\tif (other != Conversion.None)\n\t\t\t\t\t\t\treturn other;\n\t\t\t\t\t}\n\t\t\t\t\treturn selected;\n\t\t\t\t}\n\t\t\t\telse if (NullableType.IsNullable(toType))\n\t\t\t\t\treturn UserDefinedImplicitConversion(fromResult, fromType, NullableType.GetUnderlyingType(toType));\n\t\t\t\telse\n\t\t\t\t\treturn Conversion.None;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn Conversion.None;\n\t\t\t}\n\t\t}\n\n\t\tConversion UserDefinedExplicitConversion(ResolveResult fromResult, IType fromType, IType toType)\n\t\t{\n\t\t\t// C# 4.0 spec §6.4.5 User-defined explicit conversions\n\n\t\t\t// user-defined conversions are not supported with interfaces\n\t\t\tif (fromType.Kind == TypeKind.Interface || toType.Kind == TypeKind.Interface)\n\t\t\t{\n\t\t\t\treturn Conversion.None;\n\t\t\t}\n\n\t\t\tvar operators = GetApplicableConversionOperators(fromResult, fromType, toType, true);\n\t\t\tif (operators.Count > 0)\n\t\t\t{\n\t\t\t\tIType mostSpecificSource;\n\t\t\t\tif (operators.Any(op => op.SourceType.Equals(fromType)))\n\t\t\t\t{\n\t\t\t\t\tmostSpecificSource = fromType;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar operatorsWithSourceEncompassingFromType = operators.Where(op => IsEncompassedBy(fromType, op.SourceType) || ImplicitConstantExpressionConversion(fromResult, NullableType.GetUnderlyingType(op.SourceType))).ToList();\n\t\t\t\t\tif (operatorsWithSourceEncompassingFromType.Any())\n\t\t\t\t\t\tmostSpecificSource = FindMostEncompassedType(operatorsWithSourceEncompassingFromType.Select(op => op.SourceType));\n\t\t\t\t\telse\n\t\t\t\t\t\tmostSpecificSource = FindMostEncompassingType(operators.Select(op => op.SourceType));\n\t\t\t\t}\n\t\t\t\tif (mostSpecificSource == null)\n\t\t\t\t\treturn Conversion.UserDefinedConversion(operators[0].Method, isImplicit: false, isLifted: operators[0].IsLifted, isAmbiguous: true, conversionBeforeUserDefinedOperator: Conversion.None, conversionAfterUserDefinedOperator: Conversion.None);\n\n\t\t\t\tIType mostSpecificTarget;\n\t\t\t\tif (operators.Any(op => op.TargetType.Equals(toType)))\n\t\t\t\t\tmostSpecificTarget = toType;\n\t\t\t\telse if (operators.Any(op => IsEncompassedBy(op.TargetType, toType)))\n\t\t\t\t\tmostSpecificTarget = FindMostEncompassingType(operators.Where(op => IsEncompassedBy(op.TargetType, toType)).Select(op => op.TargetType));\n\t\t\t\telse\n\t\t\t\t\tmostSpecificTarget = FindMostEncompassedType(operators.Select(op => op.TargetType));\n\t\t\t\tif (mostSpecificTarget == null)\n\t\t\t\t{\n\t\t\t\t\tif (NullableType.IsNullable(toType))\n\t\t\t\t\t\treturn UserDefinedExplicitConversion(fromResult, fromType, NullableType.GetUnderlyingType(toType));\n\t\t\t\t\telse\n\t\t\t\t\t\treturn Conversion.UserDefinedConversion(operators[0].Method, isImplicit: false, isLifted: operators[0].IsLifted, isAmbiguous: true, conversionBeforeUserDefinedOperator: Conversion.None, conversionAfterUserDefinedOperator: Conversion.None);\n\t\t\t\t}\n\n\t\t\t\tvar selected = SelectOperator(mostSpecificSource, mostSpecificTarget, operators, false, fromType, toType);\n\t\t\t\tif (selected != Conversion.None)\n\t\t\t\t{\n\t\t\t\t\tif (selected.IsLifted && NullableType.IsNullable(toType))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Prefer A -> B -> B? over A -> A? -> B?\n\t\t\t\t\t\tvar other = UserDefinedImplicitConversion(fromResult, fromType, NullableType.GetUnderlyingType(toType));\n\t\t\t\t\t\tif (other != Conversion.None)\n\t\t\t\t\t\t\treturn other;\n\t\t\t\t\t}\n\t\t\t\t\treturn selected;\n\t\t\t\t}\n\t\t\t\telse if (NullableType.IsNullable(toType))\n\t\t\t\t\treturn UserDefinedExplicitConversion(fromResult, fromType, NullableType.GetUnderlyingType(toType));\n\t\t\t\telse if (NullableType.IsNullable(fromType))\n\t\t\t\t\treturn UserDefinedExplicitConversion(null, NullableType.GetUnderlyingType(fromType), toType);   // A? -> A -> B\n\t\t\t\telse\n\t\t\t\t\treturn Conversion.None;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn Conversion.None;\n\t\t\t}\n\t\t}\n\n\t\tclass OperatorInfo\n\t\t{\n\t\t\tpublic readonly IMethod Method;\n\t\t\tpublic readonly IType SourceType;\n\t\t\tpublic readonly IType TargetType;\n\t\t\tpublic readonly bool IsLifted;\n\n\t\t\tpublic OperatorInfo(IMethod method, IType sourceType, IType targetType, bool isLifted)\n\t\t\t{\n\t\t\t\tthis.Method = method;\n\t\t\t\tthis.SourceType = sourceType;\n\t\t\t\tthis.TargetType = targetType;\n\t\t\t\tthis.IsLifted = isLifted;\n\t\t\t}\n\t\t}\n\n\t\tstatic IType UnderlyingTypeForConversion(IType type)\n\t\t{\n\t\t\tif (type.Kind == TypeKind.ByReference)\n\t\t\t{\n\t\t\t\ttype = ((ByReferenceType)type).ElementType;\n\t\t\t}\n\t\t\treturn NullableType.GetUnderlyingType(type);\n\t\t}\n\n\t\tList<OperatorInfo> GetApplicableConversionOperators(ResolveResult fromResult, IType fromType, IType toType, bool isExplicit)\n\t\t{\n\t\t\t// Find the candidate operators:\n\t\t\tPredicate<IMethod> opFilter;\n\t\t\tif (isExplicit)\n\t\t\t\topFilter = m => m.IsStatic && m.IsOperator && (m.Name == \"op_Explicit\" || m.Name == \"op_Implicit\") && m.Parameters.Count == 1;\n\t\t\telse\n\t\t\t\topFilter = m => m.IsStatic && m.IsOperator && m.Name == \"op_Implicit\" && m.Parameters.Count == 1;\n\n\t\t\tvar operators = UnderlyingTypeForConversion(fromType).GetMethods(opFilter)\n\t\t\t\t.Concat(UnderlyingTypeForConversion(toType).GetMethods(opFilter)).Distinct();\n\t\t\t// Determine whether one of them is applicable:\n\t\t\tList<OperatorInfo> result = new List<OperatorInfo>();\n\t\t\tforeach (IMethod op in operators)\n\t\t\t{\n\t\t\t\tIType sourceType = op.Parameters[0].Type;\n\t\t\t\tif (sourceType.Kind == TypeKind.ByReference && op.Parameters[0].ReferenceKind == ReferenceKind.In && fromType.Kind != TypeKind.ByReference)\n\t\t\t\t{\n\t\t\t\t\tsourceType = ((ByReferenceType)sourceType).ElementType;\n\t\t\t\t}\n\t\t\t\tIType targetType = op.ReturnType;\n\t\t\t\t// Try if the operator is applicable:\n\t\t\t\tbool isApplicable;\n\t\t\t\tif (isExplicit)\n\t\t\t\t{\n\t\t\t\t\tisApplicable = (IsEncompassingOrEncompassedBy(fromType, sourceType) || ImplicitConstantExpressionConversion(fromResult, sourceType))\n\t\t\t\t\t\t&& IsEncompassingOrEncompassedBy(targetType, toType);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tisApplicable = (IsEncompassedBy(fromType, sourceType) || ImplicitConstantExpressionConversion(fromResult, sourceType))\n\t\t\t\t\t\t&& IsEncompassedBy(targetType, toType);\n\t\t\t\t}\n\t\t\t\t// Try if the operator is applicable in lifted form:\n\t\t\t\tif (isApplicable)\n\t\t\t\t{\n\t\t\t\t\tresult.Add(new OperatorInfo(op, sourceType, targetType, false));\n\t\t\t\t}\n\t\t\t\tif (NullableType.IsNonNullableValueType(sourceType))\n\t\t\t\t{\n\t\t\t\t\t// An operator can be applicable in both lifted and non-lifted form in case of explicit conversions\n\t\t\t\t\tIType liftedSourceType = NullableType.Create(compilation, sourceType);\n\t\t\t\t\tIType liftedTargetType = NullableType.IsNonNullableValueType(targetType) ? NullableType.Create(compilation, targetType) : targetType;\n\t\t\t\t\tif (isExplicit)\n\t\t\t\t\t{\n\t\t\t\t\t\tisApplicable = IsEncompassingOrEncompassedBy(fromType, liftedSourceType)\n\t\t\t\t\t\t\t&& IsEncompassingOrEncompassedBy(liftedTargetType, toType);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tisApplicable = IsEncompassedBy(fromType, liftedSourceType) && IsEncompassedBy(liftedTargetType, toType);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isApplicable)\n\t\t\t\t\t{\n\t\t\t\t\t\tresult.Add(new OperatorInfo(op, liftedSourceType, liftedTargetType, true));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t\t#endregion\n\n\t\t#region Implicit Span Conversion\n\n\t\tbool IsImplicitSpanConversion(IType fromType, IType toType)\n\t\t{\n\t\t\tif (!compilation.TypeSystemOptions.HasFlag(TypeSystemOptions.FirstClassSpanTypes))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// An implicit span conversion permits array_types, System.Span<T>, System.ReadOnlySpan<T>,\n\t\t\t// and string to be converted between each other \n\t\t\t// see https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-14.0/first-class-span-types#span-conversions\n\n\t\t\tswitch (fromType)\n\t\t\t{\n\t\t\t\tcase ArrayType { Dimensions: 1, ElementType: var elementType }:\n\t\t\t\t\tif (toType.IsKnownType(KnownTypeCode.SpanOfT))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn IdentityConversion(elementType, toType.TypeArguments[0]);\n\t\t\t\t\t}\n\t\t\t\t\tif (toType.IsKnownType(KnownTypeCode.ReadOnlySpanOfT))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn IdentityConversion(elementType, toType.TypeArguments[0])\n\t\t\t\t\t\t\t|| IsImplicitReferenceConversion(elementType, toType.TypeArguments[0]);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase ParameterizedType pt when pt.IsKnownType(KnownTypeCode.SpanOfT) || pt.IsKnownType(KnownTypeCode.ReadOnlySpanOfT):\n\t\t\t\t\tif (toType.IsKnownType(KnownTypeCode.ReadOnlySpanOfT))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn IdentityConversion(pt.TypeArguments[0], toType.TypeArguments[0])\n\t\t\t\t\t\t\t|| IsImplicitReferenceConversion(pt.TypeArguments[0], toType.TypeArguments[0]);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase var s when s.IsKnownType(KnownTypeCode.String):\n\t\t\t\t\treturn toType.IsKnownType(KnownTypeCode.ReadOnlySpanOfT)\n\t\t\t\t\t\t&& toType.TypeArguments[0].IsKnownType(KnownTypeCode.Char);\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\t#endregion\n\n\t\t#region AnonymousFunctionConversion\n\t\tConversion AnonymousFunctionConversion(ResolveResult resolveResult, IType toType)\n\t\t{\n\t\t\t// C# 9.0 spec §10.7 Anonymous function conversions\n\t\t\tLambdaResolveResult f = resolveResult as LambdaResolveResult;\n\t\t\tif (f == null)\n\t\t\t\treturn Conversion.None;\n\t\t\tif (!f.IsAnonymousMethod)\n\t\t\t{\n\t\t\t\t// It's a lambda, so conversions to expression trees exist\n\t\t\t\t// (even if the conversion leads to a compile-time error, e.g. for statement lambdas)\n\t\t\t\ttoType = UnpackExpressionTreeType(toType);\n\t\t\t}\n\t\t\tIMethod d = toType.GetDelegateInvokeMethod();\n\t\t\tif (d == null)\n\t\t\t\treturn Conversion.None;\n\n\t\t\tIType[] dParamTypes = new IType[d.Parameters.Count];\n\t\t\tfor (int i = 0; i < dParamTypes.Length; i++)\n\t\t\t{\n\t\t\t\tdParamTypes[i] = d.Parameters[i].Type;\n\t\t\t}\n\t\t\tIType dReturnType = d.ReturnType;\n\n\t\t\tif (f.HasParameterList)\n\t\t\t{\n\t\t\t\t// If F contains an anonymous-function-signature, then D and F have the same number of parameters.\n\t\t\t\tif (d.Parameters.Count != f.Parameters.Count)\n\t\t\t\t\treturn Conversion.None;\n\n\t\t\t\tif (f.IsImplicitlyTyped)\n\t\t\t\t{\n\t\t\t\t\t// If F has an implicitly typed parameter list, D has no ref or out parameters.\n\t\t\t\t\t// TODO: what about in parameters?\n\t\t\t\t\tforeach (IParameter p in d.Parameters)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (p.ReferenceKind != ReferenceKind.None)\n\t\t\t\t\t\t\treturn Conversion.None;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// If F has an explicitly typed parameter list, each parameter in D has the same type\n\t\t\t\t\t// and modifiers as the corresponding parameter in F.\n\t\t\t\t\tfor (int i = 0; i < f.Parameters.Count; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tIParameter pD = d.Parameters[i];\n\t\t\t\t\t\tIParameter pF = f.Parameters[i];\n\t\t\t\t\t\tif (pD.ReferenceKind != pF.ReferenceKind)\n\t\t\t\t\t\t\treturn Conversion.None;\n\t\t\t\t\t\tif (!IdentityConversion(dParamTypes[i], pF.Type))\n\t\t\t\t\t\t\treturn Conversion.None;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// If F does not contain an anonymous-function-signature, then D may have zero or more parameters of any\n\t\t\t\t// type, as long as no parameter of D has the out parameter modifier.\n\t\t\t\tforeach (IParameter p in d.Parameters)\n\t\t\t\t{\n\t\t\t\t\tif (p.ReferenceKind == ReferenceKind.Out)\n\t\t\t\t\t\treturn Conversion.None;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn f.IsValid(dParamTypes, dReturnType, this);\n\t\t}\n\n\t\tstatic IType UnpackExpressionTreeType(IType type)\n\t\t{\n\t\t\tParameterizedType pt = type as ParameterizedType;\n\t\t\tif (pt != null && pt.TypeParameterCount == 1 && pt.Name == \"Expression\" && pt.Namespace == \"System.Linq.Expressions\")\n\t\t\t{\n\t\t\t\treturn pt.GetTypeArgument(0);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn type;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region MethodGroupConversion\n\t\tConversion MethodGroupConversion(ResolveResult resolveResult, IType toType)\n\t\t{\n\t\t\t// C# 9.0 spec §10.8 Method group conversions\n\t\t\tif (resolveResult is not MethodGroupResolveResult rr)\n\t\t\t\treturn Conversion.None;\n\t\t\tIMethod invoke = toType.GetDelegateInvokeMethod();\n\t\t\tif (invoke == null)\n\t\t\t\treturn Conversion.None;\n\n\t\t\tResolveResult[] args = new ResolveResult[invoke.Parameters.Count];\n\t\t\tfor (int i = 0; i < args.Length; i++)\n\t\t\t{\n\t\t\t\tIParameter param = invoke.Parameters[i];\n\t\t\t\tIType parameterType = param.Type;\n\t\t\t\tif (param.ReferenceKind != ReferenceKind.None && parameterType.Kind == TypeKind.ByReference)\n\t\t\t\t{\n\t\t\t\t\tparameterType = ((ByReferenceType)parameterType).ElementType;\n\t\t\t\t\targs[i] = new ByReferenceResolveResult(parameterType, param.ReferenceKind);\n\t\t\t\t}\n\t\t\t\telse if (param.Type.Kind == TypeKind.Dynamic)\n\t\t\t\t{\n\t\t\t\t\targs[i] = new ResolveResult(compilation.FindType(KnownTypeCode.Object));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\targs[i] = new ResolveResult(parameterType);\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar or = rr.PerformOverloadResolution(\n\t\t\t\tcompilation, args,\n\t\t\t\tallowExpandingParams: false,\n\t\t\t\tallowOptionalParameters: false,\n\t\t\t\tallowImplicitIn: false,\n\t\t\t\tconversions: this\n\t\t\t);\n\t\t\tif (or.FoundApplicableCandidate)\n\t\t\t{\n\t\t\t\tIMethod method = (IMethod)or.GetBestCandidateWithSubstitutedTypeArguments();\n\t\t\t\tbool isVirtual = method.IsOverridable && !(rr.TargetResult is ThisResolveResult { CausesNonVirtualInvocation: true });\n\t\t\t\tbool isValid = !or.IsAmbiguous && IsDelegateCompatible(method, invoke, or.IsExtensionMethodInvocation);\n\t\t\t\tbool delegateCapturesFirstArgument = or.IsExtensionMethodInvocation || !method.IsStatic;\n\t\t\t\tif (isValid)\n\t\t\t\t\treturn Conversion.MethodGroupConversion(method, isVirtual, delegateCapturesFirstArgument);\n\t\t\t\telse\n\t\t\t\t\treturn Conversion.InvalidMethodGroupConversion(method, isVirtual, delegateCapturesFirstArgument);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn Conversion.None;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether a <paramref name=\"method\"/> is compatible with a delegate type.\n\t\t/// §15.2 Delegate compatibility\n\t\t/// </summary>\n\t\t/// <param name=\"method\">The method to test for compatibility</param>\n\t\t/// <param name=\"delegateType\">The delegate type</param>\n\t\tpublic bool IsDelegateCompatible(IMethod method, IType delegateType)\n\t\t{\n\t\t\tif (method == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(method));\n\t\t\tif (delegateType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(delegateType));\n\t\t\tIMethod invoke = delegateType.GetDelegateInvokeMethod();\n\t\t\tif (invoke == null)\n\t\t\t\treturn false;\n\t\t\treturn IsDelegateCompatible(method, invoke, false);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether a method <paramref name=\"m\"/> is compatible with a delegate type.\n\t\t/// </summary>\n\t\t/// <param name=\"m\">The method to test for compatibility</param>\n\t\t/// <param name=\"d\">The invoke method of the delegate</param>\n\t\t/// <param name=\"isExtensionMethodInvocation\">Gets whether m is accessed using extension method syntax.\n\t\t/// If this parameter is true, the first parameter of <paramref name=\"m\"/> will be ignored.</param>\n\t\tbool IsDelegateCompatible(IMethod m, IMethod d, bool isExtensionMethodInvocation)\n\t\t{\n\t\t\t// C# 9.0 §20.4 Delegate compatibility\n\t\t\tif (m == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(m));\n\t\t\tif (d == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(d));\n\t\t\tint firstParameterInM = isExtensionMethodInvocation ? 1 : 0;\n\t\t\tif (m.Parameters.Count - firstParameterInM != d.Parameters.Count)\n\t\t\t\treturn false;\n\t\t\tfor (int i = 0; i < d.Parameters.Count; i++)\n\t\t\t{\n\t\t\t\tvar pm = m.Parameters[firstParameterInM + i];\n\t\t\t\tvar pd = d.Parameters[i];\n\t\t\t\t// ret/out/in must match\n\t\t\t\tif (pm.ReferenceKind != pd.ReferenceKind)\n\t\t\t\t\treturn false;\n\t\t\t\tif (pm.ReferenceKind != ReferenceKind.None)\n\t\t\t\t{\n\t\t\t\t\t// ref/out/in parameters must have same types\n\t\t\t\t\t// according to the spec, but Roslyn seems to allow identity conversions\n\t\t\t\t\tif (!IdentityConversion(pd.Type, pm.Type))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// non-ref/out parameters must have an identity or reference conversion from pd to pm\n\t\t\t\t\tif (!IdentityConversion(pd.Type, pm.Type) && !IsImplicitReferenceConversion(pd.Type, pm.Type))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (m.ReturnTypeIsRefReadOnly != d.ReturnTypeIsRefReadOnly)\n\t\t\t\treturn false;\n\t\t\t// check return type compatibility\n\t\t\treturn IdentityConversion(m.ReturnType, d.ReturnType)\n\t\t\t\t|| IsImplicitReferenceConversion(m.ReturnType, d.ReturnType);\n\t\t}\n\t\t#endregion\n\n\t\t#region Tuple Conversion\n\t\tConversion TupleConversion(TupleResolveResult fromRR, IType toType, bool isExplicit)\n\t\t{\n\t\t\t// C# 9.0 spec: §10.2.13 (implicit tuple conversions) + $10.3.6 (explicit tuple conversions)\n\t\t\tvar fromElements = fromRR.Elements;\n\t\t\tvar toElements = TupleType.GetTupleElementTypes(toType);\n\t\t\tif (toElements.IsDefault || fromElements.Length != toElements.Length)\n\t\t\t\treturn Conversion.None;\n\t\t\tConversion[] elementConversions = new Conversion[fromElements.Length];\n\t\t\tfor (int i = 0; i < elementConversions.Length; i++)\n\t\t\t{\n\t\t\t\tConversion c;\n\t\t\t\tif (isExplicit)\n\t\t\t\t{\n\t\t\t\t\tc = ExplicitConversion(fromElements[i], toElements[i]);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tc = ImplicitConversion(fromElements[i], toElements[i]);\n\t\t\t\t}\n\t\t\t\tif (!c.IsValid)\n\t\t\t\t\treturn Conversion.None;\n\t\t\t\telementConversions[i] = c;\n\t\t\t}\n\t\t\treturn Conversion.TupleConversion(elementConversions.ToImmutableArray());\n\t\t}\n\n\t\tConversion TupleConversion(IType fromType, IType toType, bool isExplicit)\n\t\t{\n\t\t\t// C# 9.0 spec: §10.2.13 (implicit tuple conversions) + $10.3.6 (explicit tuple conversions)\n\t\t\tvar fromElements = TupleType.GetTupleElementTypes(fromType);\n\t\t\tif (fromElements.IsDefaultOrEmpty)\n\t\t\t\treturn Conversion.None;\n\t\t\tvar toElements = TupleType.GetTupleElementTypes(toType);\n\t\t\tif (toElements.IsDefault || fromElements.Length != toElements.Length)\n\t\t\t\treturn Conversion.None;\n\t\t\tConversion[] elementConversions = new Conversion[fromElements.Length];\n\t\t\tfor (int i = 0; i < elementConversions.Length; i++)\n\t\t\t{\n\t\t\t\tConversion c;\n\t\t\t\tif (isExplicit)\n\t\t\t\t{\n\t\t\t\t\tc = ExplicitConversion(fromElements[i], toElements[i]);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tc = ImplicitConversion(fromElements[i], toElements[i]);\n\t\t\t\t}\n\t\t\t\tif (!c.IsValid)\n\t\t\t\t\treturn Conversion.None;\n\t\t\t\telementConversions[i] = c;\n\t\t\t}\n\t\t\treturn Conversion.TupleConversion(elementConversions.ToImmutableArray());\n\t\t}\n\t\t#endregion\n\n\t\t#region BetterConversion\n\t\t/// <summary>\n\t\t/// Gets the better conversion (from expression) (C# 8.0 spec, §12.6.4.5)\n\t\t/// </summary>\n\t\t/// <returns>0 = neither is better; 1 = t1 is better; 2 = t2 is better</returns>\n\t\tpublic int BetterConversion(ResolveResult resolveResult, IType t1, IType t2)\n\t\t{\n\t\t\tbool t1Exact = IsExactlyMatching(resolveResult, t1);\n\t\t\tbool t2Exact = IsExactlyMatching(resolveResult, t2);\n\t\t\tif (t1Exact && !t2Exact)\n\t\t\t\treturn 1;\n\t\t\tif (t2Exact && !t1Exact)\n\t\t\t\treturn 2;\n\t\t\tif (!t1Exact && !t2Exact)\n\t\t\t{\n\t\t\t\tbool c1ImplicitSpanConversion = IsImplicitSpanConversion(resolveResult.Type, t1);\n\t\t\t\tbool c2ImplicitSpanConversion = IsImplicitSpanConversion(resolveResult.Type, t2);\n\t\t\t\tif (c1ImplicitSpanConversion && !c2ImplicitSpanConversion)\n\t\t\t\t\treturn 1;\n\t\t\t\tif (c2ImplicitSpanConversion && !c1ImplicitSpanConversion)\n\t\t\t\t\treturn 2;\n\t\t\t}\n\t\t\tif (t1Exact == t2Exact)\n\t\t\t{\n\t\t\t\tint r = BetterConversionTarget(t1, t2);\n\t\t\t\tif (r != 0)\n\t\t\t\t\treturn r;\n\t\t\t}\n\t\t\tLambdaResolveResult lambda = resolveResult as LambdaResolveResult;\n\t\t\tif (lambda != null)\n\t\t\t{\n\t\t\t\tif (!lambda.IsAnonymousMethod)\n\t\t\t\t{\n\t\t\t\t\tt1 = UnpackExpressionTreeType(t1);\n\t\t\t\t\tt2 = UnpackExpressionTreeType(t2);\n\t\t\t\t}\n\t\t\t\tIMethod m1 = t1.GetDelegateInvokeMethod();\n\t\t\t\tIMethod m2 = t2.GetDelegateInvokeMethod();\n\t\t\t\tif (m1 == null || m2 == null)\n\t\t\t\t\treturn 0;\n\t\t\t\tif (m1.Parameters.Count != m2.Parameters.Count)\n\t\t\t\t\treturn 0;\n\t\t\t\tIType[] parameterTypes = new IType[m1.Parameters.Count];\n\t\t\t\tfor (int i = 0; i < parameterTypes.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tparameterTypes[i] = m1.Parameters[i].Type;\n\t\t\t\t\tif (!parameterTypes[i].Equals(m2.Parameters[i].Type))\n\t\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t\tif (lambda.HasParameterList && parameterTypes.Length != lambda.Parameters.Count)\n\t\t\t\t\treturn 0;\n\n\t\t\t\tIType ret1 = m1.ReturnType;\n\t\t\t\tIType ret2 = m2.ReturnType;\n\t\t\t\tif (ret1.Kind == TypeKind.Void && ret2.Kind != TypeKind.Void)\n\t\t\t\t\treturn 2;\n\t\t\t\tif (ret1.Kind != TypeKind.Void && ret2.Kind == TypeKind.Void)\n\t\t\t\t\treturn 1;\n\n\t\t\t\tIType inferredRet = lambda.GetInferredReturnType(parameterTypes);\n\t\t\t\tint r = BetterConversion(inferredRet, ret1, ret2);\n\t\t\t\tif (r == 0 && lambda.IsAsync)\n\t\t\t\t{\n\t\t\t\t\tret1 = UnpackTask(ret1);\n\t\t\t\t\tret2 = UnpackTask(ret2);\n\t\t\t\t\tinferredRet = UnpackTask(inferredRet);\n\t\t\t\t\tif (ret1 != null && ret2 != null && inferredRet != null)\n\t\t\t\t\t\tr = BetterConversion(inferredRet, ret1, ret2);\n\t\t\t\t}\n\t\t\t\treturn r;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn BetterConversion(resolveResult.Type, t1, t2);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether an expression E exactly matches a type T (C# 8.0 spec, §12.6.4.6)\n\t\t/// </summary>\n\t\tbool IsExactlyMatching(ResolveResult e, IType t)\n\t\t{\n\t\t\tvar s = e.Type;\n\t\t\tif (IdentityConversion(s, t))\n\t\t\t\treturn true;\n\t\t\tif (e is LambdaResolveResult lambda)\n\t\t\t{\n\t\t\t\tif (!lambda.IsAnonymousMethod)\n\t\t\t\t{\n\t\t\t\t\tt = UnpackExpressionTreeType(t);\n\t\t\t\t}\n\t\t\t\tIMethod m = t.GetDelegateInvokeMethod();\n\t\t\t\tif (m == null)\n\t\t\t\t\treturn false;\n\t\t\t\tIType[] parameterTypes = new IType[m.Parameters.Count];\n\t\t\t\tfor (int i = 0; i < parameterTypes.Length; i++)\n\t\t\t\t\tparameterTypes[i] = m.Parameters[i].Type;\n\t\t\t\tvar x = lambda.GetInferredReturnType(parameterTypes);\n\t\t\t\tvar y = m.ReturnType;\n\t\t\t\tif (IdentityConversion(x, y))\n\t\t\t\t\treturn true;\n\t\t\t\tif (lambda.IsAsync)\n\t\t\t\t{\n\t\t\t\t\tx = UnpackTask(x);\n\t\t\t\t\ty = UnpackTask(y);\n\t\t\t\t}\n\t\t\t\tif (x != null && y != null)\n\t\t\t\t\treturn IsExactlyMatching(new ResolveResult(x), y);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Unpacks the generic TaskType[T]. Returns null if the input is not TaskType[T].\n\t\t/// </summary>\n\t\tstatic IType UnpackTask(IType type)\n\t\t{\n\t\t\treturn (TaskType.IsTask(type) || TaskType.IsCustomTask(type, out _)) && type.TypeParameterCount == 1\n\t\t\t\t? type.TypeArguments[0]\n\t\t\t\t: null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the better conversion (from type) (C# 4.0 spec, §7.5.3.4)\n\t\t/// </summary>\n\t\t/// <returns>0 = neither is better; 1 = t1 is better; 2 = t2 is better</returns>\n\t\tpublic int BetterConversion(IType s, IType t1, IType t2)\n\t\t{\n\t\t\tbool ident1 = IdentityConversion(s, t1);\n\t\t\tbool ident2 = IdentityConversion(s, t2);\n\t\t\tif (ident1 && !ident2)\n\t\t\t\treturn 1;\n\t\t\tif (ident2 && !ident1)\n\t\t\t\treturn 2;\n\t\t\treturn BetterConversionTarget(t1, t2);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the better conversion target (C# 9.0 spec, §12.6.4.7)\n\t\t/// </summary>\n\t\t/// <returns>0 = neither is better; 1 = t1 is better; 2 = t2 is better</returns>\n\t\tint BetterConversionTarget(IType t1, IType t2)\n\t\t{\n\t\t\tif (t1.IsKnownType(KnownTypeCode.ReadOnlySpanOfT))\n\t\t\t{\n\t\t\t\tif (t2.IsKnownType(KnownTypeCode.SpanOfT))\n\t\t\t\t{\n\t\t\t\t\tif (IdentityConversion(t1.TypeArguments[0], t2.TypeArguments[0]))\n\t\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\tif (t2.IsKnownType(KnownTypeCode.ReadOnlySpanOfT))\n\t\t\t\t{\n\t\t\t\t\tbool t1To2 = ImplicitConversion(t1.TypeArguments[0], t2.TypeArguments[0]).IsValid;\n\t\t\t\t\tbool t2To1 = ImplicitConversion(t2.TypeArguments[0], t1.TypeArguments[0]).IsValid;\n\t\t\t\t\tif (t1To2 && !t2To1)\n\t\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (t2.IsKnownType(KnownTypeCode.ReadOnlySpanOfT))\n\t\t\t{\n\t\t\t\tif (t1.IsKnownType(KnownTypeCode.SpanOfT))\n\t\t\t\t{\n\t\t\t\t\tif (IdentityConversion(t2.TypeArguments[0], t1.TypeArguments[0]))\n\t\t\t\t\t\treturn 2;\n\t\t\t\t}\n\t\t\t\tif (t1.IsKnownType(KnownTypeCode.ReadOnlySpanOfT))\n\t\t\t\t{\n\t\t\t\t\tbool t1To2 = ImplicitConversion(t1.TypeArguments[0], t2.TypeArguments[0]).IsValid;\n\t\t\t\t\tbool t2To1 = ImplicitConversion(t2.TypeArguments[0], t1.TypeArguments[0]).IsValid;\n\t\t\t\t\tif (t2To1 && !t1To2)\n\t\t\t\t\t\treturn 2;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t{\n\t\t\t\tbool t1To2 = ImplicitConversion(t1, t2).IsValid;\n\t\t\t\tbool t2To1 = ImplicitConversion(t2, t1).IsValid;\n\t\t\t\tif (t1To2 && !t2To1)\n\t\t\t\t\treturn 1;\n\t\t\t\tif (t2To1 && !t1To2)\n\t\t\t\t\treturn 2;\n\t\t\t}\n\n\t\t\tvar s1 = UnpackTask(t1);\n\t\t\tvar s2 = UnpackTask(t2);\n\t\t\tif (s1 != null && s2 != null)\n\t\t\t\treturn BetterConversionTarget(s1, s2);\n\n\t\t\tTypeCode t1Code = ReflectionHelper.GetTypeCode(t1);\n\t\t\tTypeCode t2Code = ReflectionHelper.GetTypeCode(t2);\n\t\t\tif (IsBetterIntegralType(t1Code, t2Code))\n\t\t\t\treturn 1;\n\t\t\tif (IsBetterIntegralType(t2Code, t1Code))\n\t\t\t\treturn 2;\n\t\t\treturn 0;\n\t\t}\n\n\t\tbool IsBetterIntegralType(TypeCode t1, TypeCode t2)\n\t\t{\n\t\t\t// signed types are better than unsigned types\n\t\t\tswitch (t1)\n\t\t\t{\n\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\treturn t2 == TypeCode.Byte || t2 == TypeCode.UInt16 || t2 == TypeCode.UInt32 || t2 == TypeCode.UInt64;\n\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\treturn t2 == TypeCode.UInt16 || t2 == TypeCode.UInt32 || t2 == TypeCode.UInt64;\n\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\treturn t2 == TypeCode.UInt32 || t2 == TypeCode.UInt64;\n\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\treturn t2 == TypeCode.UInt64;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Resolver/CSharpInvocationResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Resolver\n{\n\t/// <summary>\n\t/// Represents the result of a method, constructor or indexer invocation.\n\t/// Provides additional C#-specific information for InvocationResolveResult.\n\t/// </summary>\n\tpublic class CSharpInvocationResolveResult : InvocationResolveResult\n\t{\n\t\tpublic readonly OverloadResolutionErrors OverloadResolutionErrors;\n\n\t\t/// <summary>\n\t\t/// Gets whether this invocation is calling an extension method using extension method syntax.\n\t\t/// </summary>\n\t\tpublic readonly bool IsExtensionMethodInvocation;\n\n\t\t/// <summary>\n\t\t/// Gets whether this invocation is calling a delegate (without explicitly calling \".Invoke()\").\n\t\t/// </summary>\n\t\tpublic readonly bool IsDelegateInvocation;\n\n\t\t/// <summary>\n\t\t/// Gets whether a params-Array is being used in its expanded form.\n\t\t/// </summary>\n\t\tpublic readonly bool IsExpandedForm;\n\n\t\treadonly IReadOnlyList<int> argumentToParameterMap;\n\n\t\tpublic CSharpInvocationResolveResult(\n\t\t\tResolveResult targetResult, IParameterizedMember member,\n\t\t\tIList<ResolveResult> arguments,\n\t\t\tOverloadResolutionErrors overloadResolutionErrors = OverloadResolutionErrors.None,\n\t\t\tbool isExtensionMethodInvocation = false,\n\t\t\tbool isExpandedForm = false,\n\t\t\tbool isDelegateInvocation = false,\n\t\t\tIReadOnlyList<int> argumentToParameterMap = null,\n\t\t\tIList<ResolveResult> initializerStatements = null,\n\t\t\tIType returnTypeOverride = null\n\t\t)\n\t\t\t: base(targetResult, member, arguments, initializerStatements, returnTypeOverride)\n\t\t{\n\t\t\tthis.OverloadResolutionErrors = overloadResolutionErrors;\n\t\t\tthis.IsExtensionMethodInvocation = isExtensionMethodInvocation;\n\t\t\tthis.IsExpandedForm = isExpandedForm;\n\t\t\tthis.IsDelegateInvocation = isDelegateInvocation;\n\t\t\tthis.argumentToParameterMap = argumentToParameterMap;\n\t\t}\n\n\t\tpublic override bool IsError {\n\t\t\tget { return this.OverloadResolutionErrors != OverloadResolutionErrors.None; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets an array that maps argument indices to parameter indices.\n\t\t/// For arguments that could not be mapped to any parameter, the value will be -1.\n\t\t/// \n\t\t/// parameterIndex = ArgumentToParameterMap[argumentIndex]\n\t\t/// </summary>\n\t\tpublic IReadOnlyList<int> GetArgumentToParameterMap()\n\t\t{\n\t\t\treturn argumentToParameterMap;\n\t\t}\n\n\t\tpublic override IList<ResolveResult> GetArgumentsForCall()\n\t\t{\n\t\t\tResolveResult[] results = new ResolveResult[Member.Parameters.Count];\n\t\t\tList<ResolveResult> paramsArguments = IsExpandedForm ? new List<ResolveResult>() : null;\n\t\t\t// map arguments to parameters:\n\t\t\tfor (int i = 0; i < Arguments.Count; i++)\n\t\t\t{\n\t\t\t\tint mappedTo;\n\t\t\t\tif (argumentToParameterMap != null)\n\t\t\t\t\tmappedTo = argumentToParameterMap[i];\n\t\t\t\telse\n\t\t\t\t\tmappedTo = IsExpandedForm ? Math.Min(i, results.Length - 1) : i;\n\n\t\t\t\tif (mappedTo >= 0 && mappedTo < results.Length)\n\t\t\t\t{\n\t\t\t\t\tif (IsExpandedForm && mappedTo == results.Length - 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tparamsArguments.Add(Arguments[i]);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tvar narr = Arguments[i] as NamedArgumentResolveResult;\n\t\t\t\t\t\tif (narr != null)\n\t\t\t\t\t\t\tresults[mappedTo] = narr.Argument;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tresults[mappedTo] = Arguments[i];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (IsExpandedForm)\n\t\t\t{\n\t\t\t\tIType arrayType = Member.Parameters.Last().Type;\n\t\t\t\tIType int32 = Member.Compilation.FindType(KnownTypeCode.Int32);\n\t\t\t\tResolveResult[] sizeArguments = { new ConstantResolveResult(int32, paramsArguments.Count) };\n\t\t\t\tresults[results.Length - 1] = new ArrayCreateResolveResult(arrayType, sizeArguments, paramsArguments);\n\t\t\t}\n\n\t\t\tfor (int i = 0; i < results.Length; i++)\n\t\t\t{\n\t\t\t\tif (results[i] == null)\n\t\t\t\t{\n\t\t\t\t\tif (Member.Parameters[i].IsOptional)\n\t\t\t\t\t{\n\t\t\t\t\t\tresults[i] = new ConstantResolveResult(Member.Parameters[i].Type, Member.Parameters[i].GetConstantValue());\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tresults[i] = ErrorResolveResult.UnknownError;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn results;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Resolver/CSharpOperators.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp.Resolver\n{\n\tsealed class CSharpOperators\n\t{\n\t\treadonly ICompilation compilation;\n\n\t\tprivate CSharpOperators(ICompilation compilation)\n\t\t{\n\t\t\tthis.compilation = compilation;\n\t\t\tInitParameterArrays();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the CSharpOperators instance for the specified <see cref=\"ICompilation\"/>.\n\t\t/// This will make use of the context's cache manager (if available) to reuse the CSharpOperators instance.\n\t\t/// </summary>\n\t\tpublic static CSharpOperators Get(ICompilation compilation)\n\t\t{\n\t\t\tCacheManager cache = compilation.CacheManager;\n\t\t\tCSharpOperators? operators = (CSharpOperators?)cache.GetShared(typeof(CSharpOperators));\n\t\t\tif (operators == null)\n\t\t\t{\n\t\t\t\toperators = (CSharpOperators)cache.GetOrAddShared(typeof(CSharpOperators), new CSharpOperators(compilation));\n\t\t\t}\n\t\t\treturn operators;\n\t\t}\n\n\t\t#region class OperatorMethod\n\t\tOperatorMethod[] Lift(params OperatorMethod[] methods)\n\t\t{\n\t\t\tList<OperatorMethod> result = new List<OperatorMethod>(methods);\n\t\t\tforeach (OperatorMethod method in methods)\n\t\t\t{\n\t\t\t\tOperatorMethod? lifted = method.Lift(this);\n\t\t\t\tif (lifted != null)\n\t\t\t\t\tresult.Add(lifted);\n\t\t\t}\n\t\t\treturn result.ToArray();\n\t\t}\n\n\t\tIParameter[] normalParameters = new IParameter[(int)(TypeCode.String + 1 - TypeCode.Object)];\n\t\tIParameter[] nullableParameters = new IParameter[(int)(TypeCode.Decimal + 1 - TypeCode.Boolean)];\n\n\t\tvoid InitParameterArrays()\n\t\t{\n\t\t\tfor (TypeCode i = TypeCode.Object; i <= TypeCode.String; i++)\n\t\t\t{\n\t\t\t\tnormalParameters[i - TypeCode.Object] = new DefaultParameter(compilation.FindType(i), string.Empty);\n\t\t\t}\n\t\t\tfor (TypeCode i = TypeCode.Boolean; i <= TypeCode.Decimal; i++)\n\t\t\t{\n\t\t\t\tIType type = NullableType.Create(compilation, compilation.FindType(i));\n\t\t\t\tnullableParameters[i - TypeCode.Boolean] = new DefaultParameter(type, string.Empty);\n\t\t\t}\n\t\t}\n\n\t\tIParameter MakeParameter(TypeCode code)\n\t\t{\n\t\t\treturn normalParameters[code - TypeCode.Object];\n\t\t}\n\n\t\tIParameter MakeNullableParameter(IParameter normalParameter)\n\t\t{\n\t\t\tfor (TypeCode i = TypeCode.Boolean; i <= TypeCode.Decimal; i++)\n\t\t\t{\n\t\t\t\tif (normalParameter == normalParameters[i - TypeCode.Object])\n\t\t\t\t\treturn nullableParameters[i - TypeCode.Boolean];\n\t\t\t}\n\t\t\tthrow new ArgumentException();\n\t\t}\n\n\t\tinternal class OperatorMethod : IParameterizedMember\n\t\t{\n\t\t\treadonly ICompilation compilation;\n\t\t\tinternal readonly List<IParameter> parameters = new List<IParameter>();\n\n\t\t\tprotected OperatorMethod(ICompilation compilation)\n\t\t\t{\n\t\t\t\tthis.compilation = compilation;\n\t\t\t}\n\n\t\t\tpublic IReadOnlyList<IParameter> Parameters {\n\t\t\t\tget { return parameters; }\n\t\t\t}\n\n\t\t\tpublic IType ReturnType { get; internal set; } = null!; // initialized by derived class ctor\n\n\t\t\tpublic ICompilation Compilation {\n\t\t\t\tget { return compilation; }\n\t\t\t}\n\n\t\t\tpublic virtual OperatorMethod? Lift(CSharpOperators operators)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tpublic System.Reflection.Metadata.EntityHandle MetadataToken => default;\n\n\t\t\tITypeDefinition? IEntity.DeclaringTypeDefinition {\n\t\t\t\tget { return null; }\n\t\t\t}\n\n\t\t\tpublic IType DeclaringType => SpecialType.UnknownType;\n\n\t\t\tIMember IMember.MemberDefinition {\n\t\t\t\tget { return this; }\n\t\t\t}\n\n\t\t\tIEnumerable<IMember> IMember.ExplicitlyImplementedInterfaceMembers {\n\t\t\t\tget { return EmptyList<IMember>.Instance; }\n\t\t\t}\n\n\t\t\tbool IMember.IsVirtual {\n\t\t\t\tget { return false; }\n\t\t\t}\n\n\t\t\tbool IMember.IsOverride {\n\t\t\t\tget { return false; }\n\t\t\t}\n\n\t\t\tbool IMember.IsOverridable {\n\t\t\t\tget { return false; }\n\t\t\t}\n\n\t\t\tSymbolKind ISymbol.SymbolKind {\n\t\t\t\tget { return SymbolKind.Operator; }\n\t\t\t}\n\n\t\t\tIEnumerable<IAttribute> IEntity.GetAttributes() => EmptyList<IAttribute>.Instance;\n\t\t\tbool IEntity.HasAttribute(KnownAttribute attribute) => false;\n\t\t\tIAttribute? IEntity.GetAttribute(KnownAttribute attribute) => null;\n\n\t\t\tAccessibility IEntity.Accessibility {\n\t\t\t\tget { return Accessibility.Public; }\n\t\t\t}\n\n\t\t\tbool IEntity.IsStatic {\n\t\t\t\tget { return true; }\n\t\t\t}\n\n\t\t\tbool IEntity.IsAbstract {\n\t\t\t\tget { return false; }\n\t\t\t}\n\n\t\t\tbool IEntity.IsSealed {\n\t\t\t\tget { return false; }\n\t\t\t}\n\n\t\t\tbool IMember.IsExplicitInterfaceImplementation {\n\t\t\t\tget { return false; }\n\t\t\t}\n\n\t\t\tIModule IEntity.ParentModule {\n\t\t\t\tget { return compilation.MainModule; }\n\t\t\t}\n\n\t\t\tTypeParameterSubstitution IMember.Substitution {\n\t\t\t\tget {\n\t\t\t\t\treturn TypeParameterSubstitution.Identity;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tIMember IMember.Specialize(TypeParameterSubstitution substitution)\n\t\t\t{\n\t\t\t\tif (TypeParameterSubstitution.Identity.Equals(substitution))\n\t\t\t\t\treturn this;\n\t\t\t\tthrow new NotSupportedException();\n\t\t\t}\n\n\t\t\tstring INamedElement.FullName {\n\t\t\t\tget { return \"operator\"; }\n\t\t\t}\n\n\t\t\tpublic string Name {\n\t\t\t\tget { return \"operator\"; }\n\t\t\t}\n\n\t\t\tstring INamedElement.Namespace {\n\t\t\t\tget { return string.Empty; }\n\t\t\t}\n\n\t\t\tstring INamedElement.ReflectionName {\n\t\t\t\tget { return \"operator\"; }\n\t\t\t}\n\n\t\t\tpublic override string ToString()\n\t\t\t{\n\t\t\t\tStringBuilder b = new StringBuilder();\n\t\t\t\tb.Append(ReturnType + \" operator(\");\n\t\t\t\tfor (int i = 0; i < parameters.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\tb.Append(\", \");\n\t\t\t\t\tb.Append(parameters[i].Type);\n\t\t\t\t}\n\t\t\t\tb.Append(')');\n\t\t\t\treturn b.ToString();\n\t\t\t}\n\n\t\t\tbool IMember.Equals(IMember? obj, TypeVisitor? typeNormalization)\n\t\t\t{\n\t\t\t\treturn this == obj;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Unary operator class definitions\n\t\tinternal class UnaryOperatorMethod : OperatorMethod\n\t\t{\n\t\t\tpublic virtual bool CanEvaluateAtCompileTime { get { return false; } }\n\n\t\t\tpublic virtual object? Invoke(CSharpResolver resolver, object? input)\n\t\t\t{\n\t\t\t\tthrow new NotSupportedException();\n\t\t\t}\n\n\t\t\tpublic UnaryOperatorMethod(ICompilation compilation) : base(compilation)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tsealed class LambdaUnaryOperatorMethod<T> : UnaryOperatorMethod\n\t\t{\n\t\t\treadonly Func<T, T> func;\n\n\t\t\tpublic LambdaUnaryOperatorMethod(CSharpOperators operators, Func<T, T> func)\n\t\t\t\t: base(operators.compilation)\n\t\t\t{\n\t\t\t\tTypeCode typeCode = Type.GetTypeCode(typeof(T));\n\t\t\t\tthis.ReturnType = operators.compilation.FindType(typeCode);\n\t\t\t\tparameters.Add(operators.MakeParameter(typeCode));\n\t\t\t\tthis.func = func;\n\t\t\t}\n\n\t\t\tpublic override bool CanEvaluateAtCompileTime {\n\t\t\t\tget { return true; }\n\t\t\t}\n\n\t\t\tpublic override object? Invoke(CSharpResolver resolver, object? input)\n\t\t\t{\n\t\t\t\tif (input == null)\n\t\t\t\t\treturn null;\n\t\t\t\treturn func((T)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T)), input));\n\t\t\t}\n\n\t\t\tpublic override OperatorMethod Lift(CSharpOperators operators)\n\t\t\t{\n\t\t\t\treturn new LiftedUnaryOperatorMethod(operators, this);\n\t\t\t}\n\t\t}\n\n\t\tsealed class LiftedUnaryOperatorMethod : UnaryOperatorMethod, ILiftedOperator\n\t\t{\n\t\t\tUnaryOperatorMethod baseMethod;\n\n\t\t\tpublic LiftedUnaryOperatorMethod(CSharpOperators operators, UnaryOperatorMethod baseMethod) : base(operators.compilation)\n\t\t\t{\n\t\t\t\tthis.baseMethod = baseMethod;\n\t\t\t\tthis.ReturnType = NullableType.Create(baseMethod.Compilation, baseMethod.ReturnType);\n\t\t\t\tparameters.Add(operators.MakeNullableParameter(baseMethod.Parameters[0]));\n\t\t\t}\n\n\t\t\tpublic IReadOnlyList<IParameter> NonLiftedParameters => baseMethod.Parameters;\n\t\t\tpublic IType NonLiftedReturnType => baseMethod.ReturnType;\n\t\t}\n\t\t#endregion\n\n\t\t#region Unary operator definitions\n\t\t// C# 4.0 spec: §7.7.1 Unary plus operator\n\t\tOperatorMethod[]? unaryPlusOperators;\n\n\t\tpublic OperatorMethod[] UnaryPlusOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref unaryPlusOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref unaryPlusOperators, Lift(\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<int>(this, i => +i),\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<uint>(this, i => +i),\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<long>(this, i => +i),\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<ulong>(this, i => +i),\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<float>(this, i => +i),\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<double>(this, i => +i),\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<decimal>(this, i => +i)\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// C# 4.0 spec: §7.7.2 Unary minus operator\n\t\tOperatorMethod[]? uncheckedUnaryMinusOperators;\n\n\t\tpublic OperatorMethod[] UncheckedUnaryMinusOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref uncheckedUnaryMinusOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref uncheckedUnaryMinusOperators, Lift(\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<int>(this, i => unchecked(-i)),\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<long>(this, i => unchecked(-i)),\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<float>(this, i => unchecked(-i)),\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<double>(this, i => unchecked(-i)),\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<decimal>(this, i => unchecked(-i))\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tOperatorMethod[]? checkedUnaryMinusOperators;\n\n\t\tpublic OperatorMethod[] CheckedUnaryMinusOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref checkedUnaryMinusOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref checkedUnaryMinusOperators, Lift(\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<int>(this, i => checked(-i)),\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<long>(this, i => checked(-i)),\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<float>(this, i => checked(-i)),\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<double>(this, i => checked(-i)),\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<decimal>(this, i => checked(-i))\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// C# 4.0 spec: §7.7.3 Logical negation operator\n\t\tOperatorMethod[]? logicalNegationOperators;\n\n\t\tpublic OperatorMethod[] LogicalNegationOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref logicalNegationOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref logicalNegationOperators, Lift(\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<bool>(this, b => !b)\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// C# 4.0 spec: §7.7.4 Bitwise complement operator\n\t\tOperatorMethod[]? bitwiseComplementOperators;\n\n\t\tpublic OperatorMethod[] BitwiseComplementOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref bitwiseComplementOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref bitwiseComplementOperators, Lift(\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<int>(this, i => ~i),\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<uint>(this, i => ~i),\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<long>(this, i => ~i),\n\t\t\t\t\t\tnew LambdaUnaryOperatorMethod<ulong>(this, i => ~i)\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Binary operator class definitions\n\t\tinternal class BinaryOperatorMethod : OperatorMethod\n\t\t{\n\t\t\tpublic virtual bool CanEvaluateAtCompileTime { get { return false; } }\n\t\t\tpublic virtual object? Invoke(CSharpResolver resolver, object? lhs, object? rhs)\n\t\t\t{\n\t\t\t\tthrow new NotSupportedException();\n\t\t\t}\n\n\t\t\tpublic BinaryOperatorMethod(ICompilation compilation) : base(compilation) { }\n\t\t}\n\n\t\tsealed class LambdaBinaryOperatorMethod<T1, T2> : BinaryOperatorMethod\n\t\t{\n\t\t\treadonly Func<T1, T2, T1> checkedFunc;\n\t\t\treadonly Func<T1, T2, T1> uncheckedFunc;\n\n\t\t\tpublic LambdaBinaryOperatorMethod(CSharpOperators operators, Func<T1, T2, T1> func)\n\t\t\t\t: this(operators, func, func)\n\t\t\t{\n\t\t\t}\n\n\t\t\tpublic LambdaBinaryOperatorMethod(CSharpOperators operators, Func<T1, T2, T1> checkedFunc, Func<T1, T2, T1> uncheckedFunc)\n\t\t\t\t: base(operators.compilation)\n\t\t\t{\n\t\t\t\tTypeCode t1 = Type.GetTypeCode(typeof(T1));\n\t\t\t\tthis.ReturnType = operators.compilation.FindType(t1);\n\t\t\t\tparameters.Add(operators.MakeParameter(t1));\n\t\t\t\tparameters.Add(operators.MakeParameter(Type.GetTypeCode(typeof(T2))));\n\t\t\t\tthis.checkedFunc = checkedFunc;\n\t\t\t\tthis.uncheckedFunc = uncheckedFunc;\n\t\t\t}\n\n\t\t\tpublic override bool CanEvaluateAtCompileTime {\n\t\t\t\tget { return true; }\n\t\t\t}\n\n\t\t\tpublic override object? Invoke(CSharpResolver resolver, object? lhs, object? rhs)\n\t\t\t{\n\t\t\t\tif (lhs == null || rhs == null)\n\t\t\t\t\treturn null;\n\t\t\t\tFunc<T1, T2, T1> func = resolver.CheckForOverflow ? checkedFunc : uncheckedFunc;\n\t\t\t\treturn func((T1)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T1)), lhs),\n\t\t\t\t\t\t\t(T2)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T2)), rhs));\n\t\t\t}\n\n\t\t\tpublic override OperatorMethod Lift(CSharpOperators operators)\n\t\t\t{\n\t\t\t\treturn new LiftedBinaryOperatorMethod(operators, this);\n\t\t\t}\n\t\t}\n\n\t\tsealed class LiftedBinaryOperatorMethod : BinaryOperatorMethod, ILiftedOperator\n\t\t{\n\t\t\treadonly BinaryOperatorMethod baseMethod;\n\n\t\t\tpublic LiftedBinaryOperatorMethod(CSharpOperators operators, BinaryOperatorMethod baseMethod)\n\t\t\t\t: base(operators.compilation)\n\t\t\t{\n\t\t\t\tthis.baseMethod = baseMethod;\n\t\t\t\tthis.ReturnType = NullableType.Create(operators.compilation, baseMethod.ReturnType);\n\t\t\t\tparameters.Add(operators.MakeNullableParameter(baseMethod.Parameters[0]));\n\t\t\t\tparameters.Add(operators.MakeNullableParameter(baseMethod.Parameters[1]));\n\t\t\t}\n\n\t\t\tpublic IReadOnlyList<IParameter> NonLiftedParameters => baseMethod.Parameters;\n\t\t\tpublic IType NonLiftedReturnType => baseMethod.ReturnType;\n\t\t}\n\t\t#endregion\n\n\t\t#region Arithmetic operators\n\t\t// C# 4.0 spec: §7.8.1 Multiplication operator\n\n\t\tOperatorMethod[]? multiplicationOperators;\n\n\t\tpublic OperatorMethod[] MultiplicationOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref multiplicationOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref multiplicationOperators, Lift(\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<int, int>(this, (a, b) => checked(a * b), (a, b) => unchecked(a * b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<uint, uint>(this, (a, b) => checked(a * b), (a, b) => unchecked(a * b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<long, long>(this, (a, b) => checked(a * b), (a, b) => unchecked(a * b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<ulong, ulong>(this, (a, b) => checked(a * b), (a, b) => unchecked(a * b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<float, float>(this, (a, b) => checked(a * b), (a, b) => unchecked(a * b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<double, double>(this, (a, b) => checked(a * b), (a, b) => unchecked(a * b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<decimal, decimal>(this, (a, b) => checked(a * b), (a, b) => unchecked(a * b))\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// C# 4.0 spec: §7.8.2 Division operator\n\t\tOperatorMethod[]? divisionOperators;\n\n\t\tpublic OperatorMethod[] DivisionOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref divisionOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref divisionOperators, Lift(\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<int, int>(this, (a, b) => checked(a / b), (a, b) => unchecked(a / b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<uint, uint>(this, (a, b) => checked(a / b), (a, b) => unchecked(a / b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<long, long>(this, (a, b) => checked(a / b), (a, b) => unchecked(a / b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<ulong, ulong>(this, (a, b) => checked(a / b), (a, b) => unchecked(a / b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<float, float>(this, (a, b) => checked(a / b), (a, b) => unchecked(a / b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<double, double>(this, (a, b) => checked(a / b), (a, b) => unchecked(a / b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<decimal, decimal>(this, (a, b) => checked(a / b), (a, b) => unchecked(a / b))\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// C# 4.0 spec: §7.8.3 Remainder operator\n\t\tOperatorMethod[]? remainderOperators;\n\n\t\tpublic OperatorMethod[] RemainderOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref remainderOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref remainderOperators, Lift(\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<int, int>(this, (a, b) => checked(a % b), (a, b) => unchecked(a % b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<uint, uint>(this, (a, b) => checked(a % b), (a, b) => unchecked(a % b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<long, long>(this, (a, b) => checked(a % b), (a, b) => unchecked(a % b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<ulong, ulong>(this, (a, b) => checked(a % b), (a, b) => unchecked(a % b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<float, float>(this, (a, b) => checked(a % b), (a, b) => unchecked(a % b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<double, double>(this, (a, b) => checked(a % b), (a, b) => unchecked(a % b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<decimal, decimal>(this, (a, b) => checked(a % b), (a, b) => unchecked(a % b))\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// C# 4.0 spec: §7.8.3 Addition operator\n\t\tOperatorMethod[]? additionOperators;\n\n\t\tpublic OperatorMethod[] AdditionOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref additionOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref additionOperators, Lift(\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<int, int>(this, (a, b) => checked(a + b), (a, b) => unchecked(a + b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<uint, uint>(this, (a, b) => checked(a + b), (a, b) => unchecked(a + b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<long, long>(this, (a, b) => checked(a + b), (a, b) => unchecked(a + b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<ulong, ulong>(this, (a, b) => checked(a + b), (a, b) => unchecked(a + b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<float, float>(this, (a, b) => checked(a + b), (a, b) => unchecked(a + b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<double, double>(this, (a, b) => checked(a + b), (a, b) => unchecked(a + b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<decimal, decimal>(this, (a, b) => checked(a + b), (a, b) => unchecked(a + b)),\n\t\t\t\t\t\tnew StringConcatenation(this, TypeCode.String, TypeCode.String),\n\t\t\t\t\t\tnew StringConcatenation(this, TypeCode.String, TypeCode.Object),\n\t\t\t\t\t\tnew StringConcatenation(this, TypeCode.Object, TypeCode.String)\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// not in this list, but handled manually: enum addition, delegate combination\n\t\tsealed class StringConcatenation : BinaryOperatorMethod\n\t\t{\n\t\t\tbool canEvaluateAtCompileTime;\n\n\t\t\tpublic StringConcatenation(CSharpOperators operators, TypeCode p1, TypeCode p2)\n\t\t\t\t: base(operators.compilation)\n\t\t\t{\n\t\t\t\tthis.canEvaluateAtCompileTime = p1 == TypeCode.String && p2 == TypeCode.String;\n\t\t\t\tthis.ReturnType = operators.compilation.FindType(KnownTypeCode.String);\n\t\t\t\tparameters.Add(operators.MakeParameter(p1));\n\t\t\t\tparameters.Add(operators.MakeParameter(p2));\n\t\t\t}\n\n\t\t\tpublic override bool CanEvaluateAtCompileTime {\n\t\t\t\tget { return canEvaluateAtCompileTime; }\n\t\t\t}\n\n\t\t\tpublic override object? Invoke(CSharpResolver? resolver, object? lhs, object? rhs)\n\t\t\t{\n\t\t\t\treturn string.Concat(lhs, rhs);\n\t\t\t}\n\t\t}\n\n\t\t// C# 4.0 spec: §7.8.4 Subtraction operator\n\t\tOperatorMethod[]? subtractionOperators;\n\n\t\tpublic OperatorMethod[] SubtractionOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref subtractionOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref subtractionOperators, Lift(\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<int, int>(this, (a, b) => checked(a - b), (a, b) => unchecked(a - b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<uint, uint>(this, (a, b) => checked(a - b), (a, b) => unchecked(a - b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<long, long>(this, (a, b) => checked(a - b), (a, b) => unchecked(a - b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<ulong, ulong>(this, (a, b) => checked(a - b), (a, b) => unchecked(a - b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<float, float>(this, (a, b) => checked(a - b), (a, b) => unchecked(a - b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<double, double>(this, (a, b) => checked(a - b), (a, b) => unchecked(a - b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<decimal, decimal>(this, (a, b) => checked(a - b), (a, b) => unchecked(a - b))\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// C# 4.0 spec: §7.8.5 Shift operators\n\t\tOperatorMethod[]? shiftLeftOperators;\n\n\t\tpublic OperatorMethod[] ShiftLeftOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref shiftLeftOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref shiftLeftOperators, Lift(\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<int, int>(this, (a, b) => a << b),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<uint, int>(this, (a, b) => a << b),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<long, int>(this, (a, b) => a << b),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<ulong, int>(this, (a, b) => a << b)\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tOperatorMethod[]? shiftRightOperators;\n\n\t\tpublic OperatorMethod[] ShiftRightOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref shiftRightOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref shiftRightOperators, Lift(\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<int, int>(this, (a, b) => a >> b),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<uint, int>(this, (a, b) => a >> b),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<long, int>(this, (a, b) => a >> b),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<ulong, int>(this, (a, b) => a >> b)\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tOperatorMethod[]? unsignedShiftRightOperators;\n\n\t\tpublic OperatorMethod[] UnsignedShiftRightOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref unsignedShiftRightOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref unsignedShiftRightOperators, Lift(\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<int, int>(this, (a, b) => (int)((uint)a >> b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<uint, int>(this, (a, b) => a >> b),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<long, int>(this, (a, b) => (long)((ulong)a >> b)),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<ulong, int>(this, (a, b) => a >> b)\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Equality operators\n\t\tsealed class EqualityOperatorMethod : BinaryOperatorMethod\n\t\t{\n\t\t\tpublic readonly TypeCode Type;\n\t\t\tpublic readonly bool Negate;\n\n\t\t\tpublic EqualityOperatorMethod(CSharpOperators operators, TypeCode type, bool negate)\n\t\t\t\t: base(operators.compilation)\n\t\t\t{\n\t\t\t\tthis.Negate = negate;\n\t\t\t\tthis.Type = type;\n\t\t\t\tthis.ReturnType = operators.compilation.FindType(KnownTypeCode.Boolean);\n\t\t\t\tparameters.Add(operators.MakeParameter(type));\n\t\t\t\tparameters.Add(operators.MakeParameter(type));\n\t\t\t}\n\n\t\t\tpublic override bool CanEvaluateAtCompileTime {\n\t\t\t\tget { return Type != TypeCode.Object; }\n\t\t\t}\n\n\t\t\tpublic override object Invoke(CSharpResolver resolver, object? lhs, object? rhs)\n\t\t\t{\n\t\t\t\tif (lhs == null && rhs == null)\n\t\t\t\t\treturn !Negate; // ==: true; !=: false\n\t\t\t\tif (lhs == null || rhs == null)\n\t\t\t\t\treturn Negate; // ==: false; !=: true\n\t\t\t\tlhs = resolver.CSharpPrimitiveCast(Type, lhs);\n\t\t\t\trhs = resolver.CSharpPrimitiveCast(Type, rhs);\n\t\t\t\tbool equal;\n\t\t\t\tif (Type == TypeCode.Single)\n\t\t\t\t{\n\t\t\t\t\tequal = (float)lhs == (float)rhs;\n\t\t\t\t}\n\t\t\t\telse if (Type == TypeCode.Double)\n\t\t\t\t{\n\t\t\t\t\tequal = (double)lhs == (double)rhs;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tequal = object.Equals(lhs, rhs);\n\t\t\t\t}\n\t\t\t\treturn equal ^ Negate;\n\t\t\t}\n\n\t\t\tpublic override OperatorMethod? Lift(CSharpOperators operators)\n\t\t\t{\n\t\t\t\tif (Type == TypeCode.Object || Type == TypeCode.String)\n\t\t\t\t\treturn null;\n\t\t\t\telse\n\t\t\t\t\treturn new LiftedEqualityOperatorMethod(operators, this);\n\t\t\t}\n\t\t}\n\n\t\tsealed class LiftedEqualityOperatorMethod : BinaryOperatorMethod, ILiftedOperator\n\t\t{\n\t\t\treadonly EqualityOperatorMethod baseMethod;\n\n\t\t\tpublic LiftedEqualityOperatorMethod(CSharpOperators operators, EqualityOperatorMethod baseMethod)\n\t\t\t\t: base(operators.compilation)\n\t\t\t{\n\t\t\t\tthis.baseMethod = baseMethod;\n\t\t\t\tthis.ReturnType = baseMethod.ReturnType;\n\t\t\t\tIParameter p = operators.MakeNullableParameter(baseMethod.Parameters[0]);\n\t\t\t\tparameters.Add(p);\n\t\t\t\tparameters.Add(p);\n\t\t\t}\n\n\t\t\tpublic override bool CanEvaluateAtCompileTime {\n\t\t\t\tget { return baseMethod.CanEvaluateAtCompileTime; }\n\t\t\t}\n\n\t\t\tpublic override object Invoke(CSharpResolver resolver, object? lhs, object? rhs)\n\t\t\t{\n\t\t\t\treturn baseMethod.Invoke(resolver, lhs, rhs);\n\t\t\t}\n\n\t\t\tpublic IReadOnlyList<IParameter> NonLiftedParameters => baseMethod.Parameters;\n\t\t\tpublic IType NonLiftedReturnType => baseMethod.ReturnType;\n\t\t}\n\n\t\t// C# 4.0 spec: §7.10 Relational and type-testing operators\n\t\tstatic readonly TypeCode[] valueEqualityOperatorsFor = {\n\t\t\tTypeCode.Int32, TypeCode.UInt32,\n\t\t\tTypeCode.Int64, TypeCode.UInt64,\n\t\t\tTypeCode.Single, TypeCode.Double,\n\t\t\tTypeCode.Decimal,\n\t\t\tTypeCode.Boolean\n\t\t};\n\n\t\tOperatorMethod[]? valueEqualityOperators;\n\n\t\tpublic OperatorMethod[] ValueEqualityOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref valueEqualityOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref valueEqualityOperators, Lift(\n\t\t\t\t\t\tvalueEqualityOperatorsFor.Select(c => new EqualityOperatorMethod(this, c, false)).ToArray()\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tOperatorMethod[]? valueInequalityOperators;\n\n\t\tpublic OperatorMethod[] ValueInequalityOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref valueInequalityOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref valueInequalityOperators, Lift(\n\t\t\t\t\t\tvalueEqualityOperatorsFor.Select(c => new EqualityOperatorMethod(this, c, true)).ToArray()\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tOperatorMethod[]? referenceEqualityOperators;\n\n\t\tpublic OperatorMethod[] ReferenceEqualityOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref referenceEqualityOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref referenceEqualityOperators, Lift(\n\t\t\t\t\t\tnew EqualityOperatorMethod(this, TypeCode.Object, false),\n\t\t\t\t\t\tnew EqualityOperatorMethod(this, TypeCode.String, false)\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tOperatorMethod[]? referenceInequalityOperators;\n\n\t\tpublic OperatorMethod[] ReferenceInequalityOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref referenceInequalityOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref referenceInequalityOperators, Lift(\n\t\t\t\t\t\tnew EqualityOperatorMethod(this, TypeCode.Object, true),\n\t\t\t\t\t\tnew EqualityOperatorMethod(this, TypeCode.String, true)\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Relational Operators\n\t\tsealed class RelationalOperatorMethod<T1, T2> : BinaryOperatorMethod\n\t\t{\n\t\t\treadonly Func<T1, T2, bool> func;\n\n\t\t\tpublic RelationalOperatorMethod(CSharpOperators operators, Func<T1, T2, bool> func)\n\t\t\t\t: base(operators.compilation)\n\t\t\t{\n\t\t\t\tthis.ReturnType = operators.compilation.FindType(KnownTypeCode.Boolean);\n\t\t\t\tparameters.Add(operators.MakeParameter(Type.GetTypeCode(typeof(T1))));\n\t\t\t\tparameters.Add(operators.MakeParameter(Type.GetTypeCode(typeof(T2))));\n\t\t\t\tthis.func = func;\n\t\t\t}\n\n\t\t\tpublic override bool CanEvaluateAtCompileTime {\n\t\t\t\tget { return true; }\n\t\t\t}\n\n\t\t\tpublic override object? Invoke(CSharpResolver resolver, object? lhs, object? rhs)\n\t\t\t{\n\t\t\t\tif (lhs == null || rhs == null)\n\t\t\t\t\treturn null;\n\t\t\t\treturn func((T1)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T1)), lhs),\n\t\t\t\t\t\t\t(T2)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T2)), rhs));\n\t\t\t}\n\n\t\t\tpublic override OperatorMethod Lift(CSharpOperators operators)\n\t\t\t{\n\t\t\t\tvar lifted = new LiftedBinaryOperatorMethod(operators, this);\n\t\t\t\tlifted.ReturnType = this.ReturnType; // don't lift the return type for relational operators\n\t\t\t\treturn lifted;\n\t\t\t}\n\t\t}\n\n\t\tOperatorMethod[]? lessThanOperators;\n\n\t\tpublic OperatorMethod[] LessThanOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref lessThanOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref lessThanOperators, Lift(\n\t\t\t\t\t\tnew RelationalOperatorMethod<int, int>(this, (a, b) => a < b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<uint, uint>(this, (a, b) => a < b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<long, long>(this, (a, b) => a < b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<ulong, ulong>(this, (a, b) => a < b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<float, float>(this, (a, b) => a < b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<double, double>(this, (a, b) => a < b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<decimal, decimal>(this, (a, b) => a < b)\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tOperatorMethod[]? lessThanOrEqualOperators;\n\n\t\tpublic OperatorMethod[] LessThanOrEqualOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref lessThanOrEqualOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref lessThanOrEqualOperators, Lift(\n\t\t\t\t\t\tnew RelationalOperatorMethod<int, int>(this, (a, b) => a <= b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<uint, uint>(this, (a, b) => a <= b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<long, long>(this, (a, b) => a <= b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<ulong, ulong>(this, (a, b) => a <= b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<float, float>(this, (a, b) => a <= b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<double, double>(this, (a, b) => a <= b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<decimal, decimal>(this, (a, b) => a <= b)\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tOperatorMethod[]? greaterThanOperators;\n\n\t\tpublic OperatorMethod[] GreaterThanOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref greaterThanOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref greaterThanOperators, Lift(\n\t\t\t\t\t\tnew RelationalOperatorMethod<int, int>(this, (a, b) => a > b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<uint, uint>(this, (a, b) => a > b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<long, long>(this, (a, b) => a > b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<ulong, ulong>(this, (a, b) => a > b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<float, float>(this, (a, b) => a > b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<double, double>(this, (a, b) => a > b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<decimal, decimal>(this, (a, b) => a > b)\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tOperatorMethod[]? greaterThanOrEqualOperators;\n\n\t\tpublic OperatorMethod[] GreaterThanOrEqualOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref greaterThanOrEqualOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref greaterThanOrEqualOperators, Lift(\n\t\t\t\t\t\tnew RelationalOperatorMethod<int, int>(this, (a, b) => a >= b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<uint, uint>(this, (a, b) => a >= b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<long, long>(this, (a, b) => a >= b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<ulong, ulong>(this, (a, b) => a >= b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<float, float>(this, (a, b) => a >= b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<double, double>(this, (a, b) => a >= b),\n\t\t\t\t\t\tnew RelationalOperatorMethod<decimal, decimal>(this, (a, b) => a >= b)\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Bitwise operators\n\t\tOperatorMethod[]? logicalAndOperators;\n\n\t\tpublic OperatorMethod[] LogicalAndOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref logicalAndOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref logicalAndOperators, new OperatorMethod[] {\n\t\t\t\t\t\t\t\t\t\t\t\t new LambdaBinaryOperatorMethod<bool, bool>(this, (a, b) => a & b)\n\t\t\t\t\t\t\t\t\t\t\t });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tOperatorMethod[]? bitwiseAndOperators;\n\n\t\tpublic OperatorMethod[] BitwiseAndOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref bitwiseAndOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref bitwiseAndOperators, Lift(\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<int, int>(this, (a, b) => a & b),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<uint, uint>(this, (a, b) => a & b),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<long, long>(this, (a, b) => a & b),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<ulong, ulong>(this, (a, b) => a & b),\n\t\t\t\t\t\tthis.LogicalAndOperators[0]\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tOperatorMethod[]? logicalOrOperators;\n\n\t\tpublic OperatorMethod[] LogicalOrOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref logicalOrOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref logicalOrOperators, new OperatorMethod[] {\n\t\t\t\t\t\t\t\t\t\t\t\t new LambdaBinaryOperatorMethod<bool, bool>(this, (a, b) => a | b)\n\t\t\t\t\t\t\t\t\t\t\t });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tOperatorMethod[]? bitwiseOrOperators;\n\n\t\tpublic OperatorMethod[] BitwiseOrOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref bitwiseOrOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref bitwiseOrOperators, Lift(\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<int, int>(this, (a, b) => a | b),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<uint, uint>(this, (a, b) => a | b),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<long, long>(this, (a, b) => a | b),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<ulong, ulong>(this, (a, b) => a | b),\n\t\t\t\t\t\tthis.LogicalOrOperators[0]\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Note: the logic for the lifted bool? bitwise operators is wrong;\n\t\t// we produce \"true | null\" = \"null\" when it should be true. However, this is irrelevant\n\t\t// because bool? cannot be a compile-time type.\n\n\t\tOperatorMethod[]? bitwiseXorOperators;\n\n\t\tpublic OperatorMethod[] BitwiseXorOperators {\n\t\t\tget {\n\t\t\t\tOperatorMethod[]? ops = LazyInit.VolatileRead(ref bitwiseXorOperators);\n\t\t\t\tif (ops != null)\n\t\t\t\t{\n\t\t\t\t\treturn ops;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn LazyInit.GetOrSet(ref bitwiseXorOperators, Lift(\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<int, int>(this, (a, b) => a ^ b),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<uint, uint>(this, (a, b) => a ^ b),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<long, long>(this, (a, b) => a ^ b),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<ulong, ulong>(this, (a, b) => a ^ b),\n\t\t\t\t\t\tnew LambdaBinaryOperatorMethod<bool, bool>(this, (a, b) => a ^ b)\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region User-defined operators\n\t\tpublic static IMethod? LiftUserDefinedOperator(IMethod m)\n\t\t{\n\t\t\tif (IsComparisonOperator(m))\n\t\t\t{\n\t\t\t\tif (!m.ReturnType.IsKnownType(KnownTypeCode.Boolean))\n\t\t\t\t\treturn null; // cannot lift this operator\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (!NullableType.IsNonNullableValueType(m.ReturnType))\n\t\t\t\t\treturn null; // cannot lift this operator\n\t\t\t}\n\t\t\tfor (int i = 0; i < m.Parameters.Count; i++)\n\t\t\t{\n\t\t\t\tif (!NullableType.IsNonNullableValueType(m.Parameters[i].Type))\n\t\t\t\t\treturn null; // cannot lift this operator\n\t\t\t}\n\t\t\treturn new LiftedUserDefinedOperator(m);\n\t\t}\n\n\t\tinternal static bool IsComparisonOperator(IMethod m)\n\t\t{\n\t\t\treturn m.IsOperator && m.Parameters.Count == 2\n\t\t\t\t&& (OperatorDeclaration.GetOperatorType(m.Name)?.IsComparisonOperator() ?? false);\n\t\t}\n\n\t\tsealed class LiftedUserDefinedOperator : SpecializedMethod, ILiftedOperator\n\t\t{\n\t\t\tinternal readonly IParameterizedMember nonLiftedOperator;\n\n\t\t\tpublic LiftedUserDefinedOperator(IMethod nonLiftedMethod)\n\t\t\t\t: base((IMethod)nonLiftedMethod.MemberDefinition, nonLiftedMethod.Substitution)\n\t\t\t{\n\t\t\t\tthis.nonLiftedOperator = nonLiftedMethod;\n\t\t\t\tvar compilation = nonLiftedMethod.Compilation;\n\t\t\t\tvar substitution = nonLiftedMethod.Substitution;\n\t\t\t\tthis.Parameters = base.CreateParameters(\n\t\t\t\t\ttype => NullableType.Create(compilation, type.AcceptVisitor(substitution)));\n\t\t\t\t// Comparison operators keep the 'bool' return type even when lifted.\n\t\t\t\tif (IsComparisonOperator(nonLiftedMethod))\n\t\t\t\t\tthis.ReturnType = nonLiftedMethod.ReturnType;\n\t\t\t\telse\n\t\t\t\t\tthis.ReturnType = NullableType.Create(compilation, nonLiftedMethod.ReturnType.AcceptVisitor(substitution));\n\t\t\t}\n\n\t\t\tpublic IReadOnlyList<IParameter> NonLiftedParameters => nonLiftedOperator.Parameters;\n\t\t\tpublic IType NonLiftedReturnType => nonLiftedOperator.ReturnType;\n\n\t\t\tpublic override bool Equals(object? obj)\n\t\t\t{\n\t\t\t\tLiftedUserDefinedOperator? op = obj as LiftedUserDefinedOperator;\n\t\t\t\treturn op != null && this.nonLiftedOperator.Equals(op.nonLiftedOperator);\n\t\t\t}\n\n\t\t\tpublic override int GetHashCode()\n\t\t\t{\n\t\t\t\treturn nonLiftedOperator.GetHashCode() ^ 0x7191254;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\t}\n\n\t/// <summary>\n\t/// Implement this interface to give overload resolution a hint that the member represents a lifted operator,\n\t/// which is used in the tie-breaking rules.\n\t/// </summary>\n\tpublic interface ILiftedOperator : IParameterizedMember\n\t{\n\t\tIType NonLiftedReturnType { get; }\n\t\tIReadOnlyList<IParameter> NonLiftedParameters { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Resolver/CSharpResolver.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.CSharp.TypeSystem;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp.Resolver\n{\n\t/// <summary>\n\t/// Contains the main resolver logic.\n\t/// </summary>\n\t/// <remarks>\n\t/// This class is thread-safe.\n\t/// </remarks>\n\tpublic class CSharpResolver : ICodeContext\n\t{\n\t\tstatic readonly ResolveResult ErrorResult = ErrorResolveResult.UnknownError;\n\t\treadonly ICompilation compilation;\n\t\tinternal readonly CSharpConversions conversions;\n\t\treadonly CSharpTypeResolveContext context;\n\t\treadonly bool checkForOverflow;\n\t\treadonly bool isWithinLambdaExpression;\n\n\t\t#region Constructor\n\t\tpublic CSharpResolver(ICompilation compilation)\n\t\t{\n\t\t\tif (compilation == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(compilation));\n\t\t\tthis.compilation = compilation;\n\t\t\tthis.conversions = CSharpConversions.Get(compilation);\n\t\t\tthis.context = new CSharpTypeResolveContext(compilation.MainModule);\n\t\t}\n\n\t\tpublic CSharpResolver(CSharpTypeResolveContext context)\n\t\t{\n\t\t\tif (context == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(context));\n\t\t\tthis.compilation = context.Compilation;\n\t\t\tthis.conversions = CSharpConversions.Get(compilation);\n\t\t\tthis.context = context;\n\t\t\tif (context.CurrentTypeDefinition != null)\n\t\t\t\tcurrentTypeDefinitionCache = new TypeDefinitionCache(context.CurrentTypeDefinition);\n\t\t}\n\n\t\tprivate CSharpResolver(ICompilation compilation, CSharpConversions conversions, CSharpTypeResolveContext context, bool checkForOverflow, bool isWithinLambdaExpression, TypeDefinitionCache currentTypeDefinitionCache, ImmutableStack<Dictionary<string, IVariable>> localVariableStack, ObjectInitializerContext objectInitializerStack)\n\t\t{\n\t\t\tthis.compilation = compilation;\n\t\t\tthis.conversions = conversions;\n\t\t\tthis.context = context;\n\t\t\tthis.checkForOverflow = checkForOverflow;\n\t\t\tthis.isWithinLambdaExpression = isWithinLambdaExpression;\n\t\t\tthis.currentTypeDefinitionCache = currentTypeDefinitionCache;\n\t\t\tthis.localVariableStack = localVariableStack;\n\t\t\tthis.objectInitializerStack = objectInitializerStack;\n\t\t}\n\t\t#endregion\n\n\t\t#region Properties\n\t\t/// <summary>\n\t\t/// Gets the compilation used by the resolver.\n\t\t/// </summary>\n\t\tpublic ICompilation Compilation {\n\t\t\tget { return compilation; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the current type resolve context.\n\t\t/// </summary>\n\t\tpublic CSharpTypeResolveContext CurrentTypeResolveContext {\n\t\t\tget { return context; }\n\t\t}\n\n\t\tIModule ITypeResolveContext.CurrentModule {\n\t\t\tget { return context.CurrentModule; }\n\t\t}\n\n\t\tCSharpResolver WithContext(CSharpTypeResolveContext newContext)\n\t\t{\n\t\t\treturn new CSharpResolver(compilation, conversions, newContext, checkForOverflow, isWithinLambdaExpression, currentTypeDefinitionCache, localVariableStack, objectInitializerStack);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the current context is <c>checked</c>.\n\t\t/// </summary>\n\t\tpublic bool CheckForOverflow {\n\t\t\tget { return checkForOverflow; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Sets whether the current context is <c>checked</c>.\n\t\t/// </summary>\n\t\tpublic CSharpResolver WithCheckForOverflow(bool checkForOverflow)\n\t\t{\n\t\t\tif (checkForOverflow == this.checkForOverflow)\n\t\t\t\treturn this;\n\t\t\treturn new CSharpResolver(compilation, conversions, context, checkForOverflow, isWithinLambdaExpression, currentTypeDefinitionCache, localVariableStack, objectInitializerStack);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the resolver is currently within a lambda expression or anonymous method.\n\t\t/// </summary>\n\t\tpublic bool IsWithinLambdaExpression {\n\t\t\tget { return isWithinLambdaExpression; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Sets whether the resolver is currently within a lambda expression.\n\t\t/// </summary>\n\t\tpublic CSharpResolver WithIsWithinLambdaExpression(bool isWithinLambdaExpression)\n\t\t{\n\t\t\treturn new CSharpResolver(compilation, conversions, context, checkForOverflow, isWithinLambdaExpression, currentTypeDefinitionCache, localVariableStack, objectInitializerStack);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the current member definition that is used to look up identifiers as parameters\n\t\t/// or type parameters.\n\t\t/// </summary>\n\t\tpublic IMember CurrentMember {\n\t\t\tget { return context.CurrentMember; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Sets the current member definition.\n\t\t/// </summary>\n\t\t/// <remarks>Don't forget to also set CurrentTypeDefinition when setting CurrentMember;\n\t\t/// setting one of the properties does not automatically set the other.</remarks>\n\t\tpublic CSharpResolver WithCurrentMember(IMember member)\n\t\t{\n\t\t\treturn WithContext(context.WithCurrentMember(member));\n\t\t}\n\n\t\tITypeResolveContext ITypeResolveContext.WithCurrentMember(IMember member)\n\t\t{\n\t\t\treturn WithCurrentMember(member);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the current using scope that is used to look up identifiers as class names.\n\t\t/// </summary>\n\t\tpublic UsingScope CurrentUsingScope {\n\t\t\tget { return context.CurrentUsingScope; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Sets the current using scope that is used to look up identifiers as class names.\n\t\t/// </summary>\n\t\tpublic CSharpResolver WithCurrentUsingScope(UsingScope usingScope)\n\t\t{\n\t\t\treturn WithContext(context.WithUsingScope(usingScope));\n\t\t}\n\t\t#endregion\n\n\t\t#region Per-CurrentTypeDefinition Cache\n\t\treadonly TypeDefinitionCache currentTypeDefinitionCache;\n\n\t\t/// <summary>\n\t\t/// Gets the current type definition.\n\t\t/// </summary>\n\t\tpublic ITypeDefinition CurrentTypeDefinition {\n\t\t\tget { return context.CurrentTypeDefinition; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Sets the current type definition.\n\t\t/// </summary>\n\t\tpublic CSharpResolver WithCurrentTypeDefinition(ITypeDefinition typeDefinition)\n\t\t{\n\t\t\tif (this.CurrentTypeDefinition == typeDefinition)\n\t\t\t\treturn this;\n\n\t\t\tTypeDefinitionCache newTypeDefinitionCache;\n\t\t\tif (typeDefinition != null)\n\t\t\t\tnewTypeDefinitionCache = new TypeDefinitionCache(typeDefinition);\n\t\t\telse\n\t\t\t\tnewTypeDefinitionCache = null;\n\n\t\t\treturn new CSharpResolver(compilation, conversions, context.WithCurrentTypeDefinition(typeDefinition),\n\t\t\t\t\t\t\t\t\t  checkForOverflow, isWithinLambdaExpression, newTypeDefinitionCache, localVariableStack, objectInitializerStack);\n\t\t}\n\n\t\tITypeResolveContext ITypeResolveContext.WithCurrentTypeDefinition(ITypeDefinition typeDefinition)\n\t\t{\n\t\t\treturn WithCurrentTypeDefinition(typeDefinition);\n\t\t}\n\n\t\tsealed class TypeDefinitionCache\n\t\t{\n\t\t\tpublic readonly ITypeDefinition TypeDefinition;\n\t\t\tpublic readonly Dictionary<string, ResolveResult> SimpleNameLookupCacheExpression = new Dictionary<string, ResolveResult>();\n\t\t\tpublic readonly Dictionary<string, ResolveResult> SimpleNameLookupCacheInvocationTarget = new Dictionary<string, ResolveResult>();\n\t\t\tpublic readonly Dictionary<string, ResolveResult> SimpleTypeLookupCache = new Dictionary<string, ResolveResult>();\n\n\t\t\tpublic TypeDefinitionCache(ITypeDefinition typeDefinition)\n\t\t\t{\n\t\t\t\tthis.TypeDefinition = typeDefinition;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Local Variable Management\n\n\t\t// We store the local variables in an immutable stack.\n\t\t// The beginning of a block is marked by a null entry.\n\n\t\t// This data structure is used to allow efficient cloning of the resolver with its local variable context.\n\t\treadonly ImmutableStack<Dictionary<string, IVariable>> localVariableStack = ImmutableStack<Dictionary<string, IVariable>>.Empty;\n\n\t\tCSharpResolver WithLocalVariableStack(ImmutableStack<Dictionary<string, IVariable>> stack)\n\t\t{\n\t\t\treturn new CSharpResolver(compilation, conversions, context, checkForOverflow, isWithinLambdaExpression, currentTypeDefinitionCache, stack, objectInitializerStack);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Adds new variableŝ or lambda parameters to the current block.\n\t\t/// </summary>\n\t\tpublic CSharpResolver AddVariables(Dictionary<string, IVariable> variables)\n\t\t{\n\t\t\tif (variables == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(variables));\n\t\t\treturn WithLocalVariableStack(localVariableStack.Push(variables));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets all currently visible local variables and lambda parameters.\n\t\t/// Does not include method parameters.\n\t\t/// </summary>\n\t\tpublic IEnumerable<IVariable> LocalVariables {\n\t\t\tget {\n\t\t\t\treturn localVariableStack.SelectMany(s => s.Values);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Object Initializer Context\n\t\tsealed class ObjectInitializerContext\n\t\t{\n\t\t\tinternal readonly ResolveResult initializedObject;\n\t\t\tinternal readonly ObjectInitializerContext prev;\n\n\t\t\tpublic ObjectInitializerContext(ResolveResult initializedObject, CSharpResolver.ObjectInitializerContext prev)\n\t\t\t{\n\t\t\t\tthis.initializedObject = initializedObject;\n\t\t\t\tthis.prev = prev;\n\t\t\t}\n\t\t}\n\n\t\treadonly ObjectInitializerContext objectInitializerStack;\n\n\t\tCSharpResolver WithObjectInitializerStack(ObjectInitializerContext stack)\n\t\t{\n\t\t\treturn new CSharpResolver(compilation, conversions, context, checkForOverflow, isWithinLambdaExpression, currentTypeDefinitionCache, localVariableStack, stack);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Pushes the type of the object that is currently being initialized.\n\t\t/// </summary>\n\t\tpublic CSharpResolver PushObjectInitializer(ResolveResult initializedObject)\n\t\t{\n\t\t\tif (initializedObject == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(initializedObject));\n\t\t\treturn WithObjectInitializerStack(new ObjectInitializerContext(initializedObject, objectInitializerStack));\n\t\t}\n\n\t\tpublic CSharpResolver PopObjectInitializer()\n\t\t{\n\t\t\tif (objectInitializerStack == null)\n\t\t\t\tthrow new InvalidOperationException();\n\t\t\treturn WithObjectInitializerStack(objectInitializerStack.prev);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this context is within an object initializer.\n\t\t/// </summary>\n\t\tpublic bool IsInObjectInitializer {\n\t\t\tget { return objectInitializerStack != null; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the current object initializer. This usually is an <see cref=\"InitializedObjectResolveResult\"/>\n\t\t/// or (for nested initializers) a semantic tree based on an <see cref=\"InitializedObjectResolveResult\"/>.\n\t\t/// Returns ErrorResolveResult if there is no object initializer.\n\t\t/// </summary>\n\t\tpublic ResolveResult CurrentObjectInitializer {\n\t\t\tget {\n\t\t\t\treturn objectInitializerStack != null ? objectInitializerStack.initializedObject : ErrorResult;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the type of the object currently being initialized.\n\t\t/// Returns SharedTypes.Unknown if no object initializer is currently open (or if the object initializer\n\t\t/// has unknown type).\n\t\t/// </summary>\n\t\tpublic IType CurrentObjectInitializerType {\n\t\t\tget { return CurrentObjectInitializer.Type; }\n\t\t}\n\t\t#endregion\n\n\t\t#region ResolveUnaryOperator\n\t\t#region ResolveUnaryOperator method\n\t\tpublic ResolveResult ResolveUnaryOperator(UnaryOperatorType op, ResolveResult expression)\n\t\t{\n\t\t\tif (expression.Type.Kind == TypeKind.Dynamic)\n\t\t\t{\n\t\t\t\tif (op == UnaryOperatorType.Await)\n\t\t\t\t{\n\t\t\t\t\treturn new AwaitResolveResult(SpecialType.Dynamic, new DynamicInvocationResolveResult(new DynamicMemberResolveResult(expression, \"GetAwaiter\"), DynamicInvocationType.Invocation, EmptyList<ResolveResult>.Instance), SpecialType.Dynamic, null, null, null);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn UnaryOperatorResolveResult(SpecialType.Dynamic, op, expression);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// C# 4.0 spec: §7.3.3 Unary operator overload resolution\n\t\t\tstring overloadableOperatorName = GetOverloadableOperatorName(op);\n\t\t\tif (overloadableOperatorName == null)\n\t\t\t{\n\t\t\t\tswitch (op)\n\t\t\t\t{\n\t\t\t\t\tcase UnaryOperatorType.Dereference:\n\t\t\t\t\t\tPointerType p = expression.Type as PointerType;\n\t\t\t\t\t\tif (p != null)\n\t\t\t\t\t\t\treturn UnaryOperatorResolveResult(p.ElementType, op, expression);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\treturn ErrorResult;\n\t\t\t\t\tcase UnaryOperatorType.AddressOf:\n\t\t\t\t\t\treturn UnaryOperatorResolveResult(new PointerType(expression.Type), op, expression);\n\t\t\t\t\tcase UnaryOperatorType.Await:\n\t\t\t\t\t{\n\t\t\t\t\t\tResolveResult getAwaiterMethodGroup = ResolveMemberAccess(expression, \"GetAwaiter\", EmptyList<IType>.Instance, NameLookupMode.InvocationTarget);\n\t\t\t\t\t\tResolveResult getAwaiterInvocation = ResolveInvocation(getAwaiterMethodGroup, Empty<ResolveResult>.Array, argumentNames: null, allowOptionalParameters: false);\n\n\t\t\t\t\t\tvar lookup = CreateMemberLookup();\n\t\t\t\t\t\tIMethod getResultMethod;\n\t\t\t\t\t\tIType awaitResultType;\n\t\t\t\t\t\tvar getResultMethodGroup = lookup.Lookup(getAwaiterInvocation, \"GetResult\", EmptyList<IType>.Instance, true) as MethodGroupResolveResult;\n\t\t\t\t\t\tif (getResultMethodGroup != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar getResultOR = getResultMethodGroup.PerformOverloadResolution(compilation, Empty<ResolveResult>.Array, allowExtensionMethods: false, conversions: conversions);\n\t\t\t\t\t\t\tgetResultMethod = getResultOR.FoundApplicableCandidate ? getResultOR.GetBestCandidateWithSubstitutedTypeArguments() as IMethod : null;\n\t\t\t\t\t\t\tawaitResultType = getResultMethod != null ? getResultMethod.ReturnType : SpecialType.UnknownType;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tgetResultMethod = null;\n\t\t\t\t\t\t\tawaitResultType = SpecialType.UnknownType;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar isCompletedRR = lookup.Lookup(getAwaiterInvocation, \"IsCompleted\", EmptyList<IType>.Instance, false);\n\t\t\t\t\t\tvar isCompletedProperty = (isCompletedRR is MemberResolveResult ? ((MemberResolveResult)isCompletedRR).Member as IProperty : null);\n\t\t\t\t\t\tif (isCompletedProperty != null && (!isCompletedProperty.ReturnType.IsKnownType(KnownTypeCode.Boolean) || !isCompletedProperty.CanGet))\n\t\t\t\t\t\t\tisCompletedProperty = null;\n\t\t\t\t\t\t/*\n\t\t\t\t\t\tvar interfaceOnCompleted = compilation.FindType(KnownTypeCode.INotifyCompletion).GetMethods().FirstOrDefault(x => x.Name == \"OnCompleted\");\n\t\t\t\t\t\tvar interfaceUnsafeOnCompleted = compilation.FindType(KnownTypeCode.ICriticalNotifyCompletion).GetMethods().FirstOrDefault(x => x.Name == \"UnsafeOnCompleted\");\n\n\t\t\t\t\t\tIMethod onCompletedMethod = null;\n\t\t\t\t\t\tvar candidates = getAwaiterInvocation.Type.GetMethods().Where(x => x.ImplementedInterfaceMembers.Select(y => y.MemberDefinition).Contains(interfaceUnsafeOnCompleted)).ToList();\n\t\t\t\t\t\tif (candidates.Count == 0) {\n\t\t\t\t\t\t\tcandidates = getAwaiterInvocation.Type.GetMethods().Where(x => x.ImplementedInterfaceMembers.Select(y => y.MemberDefinition).Contains(interfaceOnCompleted)).ToList();\n\t\t\t\t\t\t\tif (candidates.Count == 1)\n\t\t\t\t\t\t\t\tonCompletedMethod = candidates[0];\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (candidates.Count == 1) {\n\t\t\t\t\t\t\tonCompletedMethod = candidates[0];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn new AwaitResolveResult(awaitResultType, getAwaiterInvocation, getAwaiterInvocation.Type, isCompletedProperty, onCompletedMethod, getResultMethod);\n\t\t\t\t\t\t*/\n\t\t\t\t\t\t// Not adjusted to TS changes for interface impls\n\t\t\t\t\t\t// But I believe this is dead code for ILSpy anyways...\n\t\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t\t}\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn ErrorResolveResult.UnknownError;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If the type is nullable, get the underlying type:\n\t\t\tIType type = NullableType.GetUnderlyingType(expression.Type);\n\t\t\tbool isNullable = NullableType.IsNullable(expression.Type);\n\n\t\t\t// the operator is overloadable:\n\t\t\tOverloadResolution userDefinedOperatorOR = CreateOverloadResolution(new[] { expression });\n\t\t\tforeach (var candidate in GetUserDefinedOperatorCandidates(type, overloadableOperatorName))\n\t\t\t{\n\t\t\t\tuserDefinedOperatorOR.AddCandidate(candidate);\n\t\t\t}\n\t\t\tif (userDefinedOperatorOR.FoundApplicableCandidate)\n\t\t\t{\n\t\t\t\treturn CreateResolveResultForUserDefinedOperator(userDefinedOperatorOR, UnaryOperatorExpression.GetLinqNodeType(op, this.CheckForOverflow));\n\t\t\t}\n\n\t\t\texpression = UnaryNumericPromotion(op, ref type, isNullable, expression);\n\t\t\tCSharpOperators.OperatorMethod[] methodGroup;\n\t\t\tCSharpOperators operators = CSharpOperators.Get(compilation);\n\t\t\tswitch (op)\n\t\t\t{\n\t\t\t\tcase UnaryOperatorType.Increment:\n\t\t\t\tcase UnaryOperatorType.Decrement:\n\t\t\t\tcase UnaryOperatorType.PostIncrement:\n\t\t\t\tcase UnaryOperatorType.PostDecrement:\n\t\t\t\t\t// C# 4.0 spec: §7.6.9 Postfix increment and decrement operators\n\t\t\t\t\t// C# 4.0 spec: §7.7.5 Prefix increment and decrement operators\n\t\t\t\t\tTypeCode code = ReflectionHelper.GetTypeCode(type);\n\t\t\t\t\tif ((code >= TypeCode.Char && code <= TypeCode.Decimal) || type.Kind == TypeKind.Enum || type.Kind == TypeKind.Pointer || type.IsCSharpNativeIntegerType())\n\t\t\t\t\t\treturn UnaryOperatorResolveResult(expression.Type, op, expression, isNullable);\n\t\t\t\t\telse\n\t\t\t\t\t\treturn new ErrorResolveResult(expression.Type);\n\t\t\t\tcase UnaryOperatorType.Plus:\n\t\t\t\t\tif (type.IsCSharpNativeIntegerType())\n\t\t\t\t\t{\n\t\t\t\t\t\treturn UnaryOperatorResolveResult(expression.Type, op, expression, isNullable);\n\t\t\t\t\t}\n\t\t\t\t\tmethodGroup = operators.UnaryPlusOperators;\n\t\t\t\t\tbreak;\n\t\t\t\tcase UnaryOperatorType.Minus:\n\t\t\t\t\tif (type.IsCSharpNativeIntegerType())\n\t\t\t\t\t{\n\t\t\t\t\t\treturn UnaryOperatorResolveResult(expression.Type, op, expression, isNullable);\n\t\t\t\t\t}\n\t\t\t\t\tmethodGroup = CheckForOverflow ? operators.CheckedUnaryMinusOperators : operators.UncheckedUnaryMinusOperators;\n\t\t\t\t\tbreak;\n\t\t\t\tcase UnaryOperatorType.Not:\n\t\t\t\t\tmethodGroup = operators.LogicalNegationOperators;\n\t\t\t\t\tbreak;\n\t\t\t\tcase UnaryOperatorType.BitNot:\n\t\t\t\t\tif (type.Kind == TypeKind.Enum)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (expression.IsCompileTimeConstant && !isNullable && expression.ConstantValue != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// evaluate as (E)(~(U)x);\n\t\t\t\t\t\t\tvar U = compilation.FindType(expression.ConstantValue.GetType());\n\t\t\t\t\t\t\tvar unpackedEnum = new ConstantResolveResult(U, expression.ConstantValue);\n\t\t\t\t\t\t\tvar rr = ResolveUnaryOperator(op, unpackedEnum);\n\t\t\t\t\t\t\trr = WithCheckForOverflow(false).ResolveCast(type, rr);\n\t\t\t\t\t\t\tif (rr.IsCompileTimeConstant)\n\t\t\t\t\t\t\t\treturn rr;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn UnaryOperatorResolveResult(expression.Type, op, expression, isNullable);\n\t\t\t\t\t}\n\t\t\t\t\telse if (type.IsCSharpNativeIntegerType())\n\t\t\t\t\t{\n\t\t\t\t\t\treturn UnaryOperatorResolveResult(expression.Type, op, expression, isNullable);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tmethodGroup = operators.BitwiseComplementOperators;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new InvalidOperationException();\n\t\t\t}\n\t\t\tOverloadResolution builtinOperatorOR = CreateOverloadResolution(new[] { expression });\n\t\t\tforeach (var candidate in methodGroup)\n\t\t\t{\n\t\t\t\tbuiltinOperatorOR.AddCandidate(candidate);\n\t\t\t}\n\t\t\tCSharpOperators.UnaryOperatorMethod m = (CSharpOperators.UnaryOperatorMethod)builtinOperatorOR.BestCandidate;\n\t\t\tIType resultType = m.ReturnType;\n\t\t\tif (builtinOperatorOR.BestCandidateErrors != OverloadResolutionErrors.None)\n\t\t\t{\n\t\t\t\tif (userDefinedOperatorOR.BestCandidate != null)\n\t\t\t\t{\n\t\t\t\t\t// If there are any user-defined operators, prefer those over the built-in operators.\n\t\t\t\t\t// It'll be a more informative error.\n\t\t\t\t\treturn CreateResolveResultForUserDefinedOperator(userDefinedOperatorOR, UnaryOperatorExpression.GetLinqNodeType(op, this.CheckForOverflow));\n\t\t\t\t}\n\t\t\t\telse if (builtinOperatorOR.BestCandidateAmbiguousWith != null)\n\t\t\t\t{\n\t\t\t\t\t// If the best candidate is ambiguous, just use the input type instead\n\t\t\t\t\t// of picking one of the ambiguous overloads.\n\t\t\t\t\treturn new ErrorResolveResult(expression.Type);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn new ErrorResolveResult(resultType);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (expression.IsCompileTimeConstant && m.CanEvaluateAtCompileTime)\n\t\t\t{\n\t\t\t\tobject val;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tval = m.Invoke(this, expression.ConstantValue);\n\t\t\t\t}\n\t\t\t\tcatch (ArithmeticException)\n\t\t\t\t{\n\t\t\t\t\treturn new ErrorResolveResult(resultType);\n\t\t\t\t}\n\t\t\t\treturn new ConstantResolveResult(resultType, val);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\texpression = Convert(expression, m.Parameters[0].Type, builtinOperatorOR.ArgumentConversions[0]);\n\t\t\t\treturn UnaryOperatorResolveResult(resultType, op, expression,\n\t\t\t\t\t\t\t\t\t\t\t\t  builtinOperatorOR.BestCandidate is ILiftedOperator);\n\t\t\t}\n\t\t}\n\n\t\tOperatorResolveResult UnaryOperatorResolveResult(IType resultType, UnaryOperatorType op, ResolveResult expression, bool isLifted = false)\n\t\t{\n\t\t\treturn new OperatorResolveResult(\n\t\t\t\tresultType, UnaryOperatorExpression.GetLinqNodeType(op, this.CheckForOverflow),\n\t\t\t\tnull, isLifted, new[] { expression });\n\t\t}\n\t\t#endregion\n\n\t\t#region UnaryNumericPromotion\n\t\tResolveResult UnaryNumericPromotion(UnaryOperatorType op, ref IType type, bool isNullable, ResolveResult expression)\n\t\t{\n\t\t\t// C# 4.0 spec: §7.3.6.1\n\t\t\tTypeCode code = ReflectionHelper.GetTypeCode(type);\n\t\t\tif (isNullable && type.Kind == TypeKind.Null)\n\t\t\t\tcode = TypeCode.SByte; // cause promotion of null to int32\n\t\t\tswitch (op)\n\t\t\t{\n\t\t\t\tcase UnaryOperatorType.Minus:\n\t\t\t\t\tif (code == TypeCode.UInt32)\n\t\t\t\t\t{\n\t\t\t\t\t\ttype = compilation.FindType(KnownTypeCode.Int64);\n\t\t\t\t\t\treturn Convert(expression, MakeNullable(type, isNullable),\n\t\t\t\t\t\t\t\t\t   isNullable ? Conversion.ImplicitNullableConversion : Conversion.ImplicitNumericConversion);\n\t\t\t\t\t}\n\t\t\t\t\tgoto case UnaryOperatorType.Plus;\n\t\t\t\tcase UnaryOperatorType.Plus:\n\t\t\t\tcase UnaryOperatorType.BitNot:\n\t\t\t\t\tif (code >= TypeCode.Char && code <= TypeCode.UInt16)\n\t\t\t\t\t{\n\t\t\t\t\t\ttype = compilation.FindType(KnownTypeCode.Int32);\n\t\t\t\t\t\treturn Convert(expression, MakeNullable(type, isNullable),\n\t\t\t\t\t\t\t\t\t   isNullable ? Conversion.ImplicitNullableConversion : Conversion.ImplicitNumericConversion);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn expression;\n\t\t}\n\t\t#endregion\n\n\t\t#region GetOverloadableOperatorName\n\t\tstatic string GetOverloadableOperatorName(UnaryOperatorType op)\n\t\t{\n\t\t\tswitch (op)\n\t\t\t{\n\t\t\t\tcase UnaryOperatorType.Not:\n\t\t\t\t\treturn \"op_LogicalNot\";\n\t\t\t\tcase UnaryOperatorType.BitNot:\n\t\t\t\t\treturn \"op_OnesComplement\";\n\t\t\t\tcase UnaryOperatorType.Minus:\n\t\t\t\t\treturn \"op_UnaryNegation\";\n\t\t\t\tcase UnaryOperatorType.Plus:\n\t\t\t\t\treturn \"op_UnaryPlus\";\n\t\t\t\tcase UnaryOperatorType.Increment:\n\t\t\t\tcase UnaryOperatorType.PostIncrement:\n\t\t\t\t\treturn \"op_Increment\";\n\t\t\t\tcase UnaryOperatorType.Decrement:\n\t\t\t\tcase UnaryOperatorType.PostDecrement:\n\t\t\t\t\treturn \"op_Decrement\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\t\t#endregion\n\n\t\t#region ResolveBinaryOperator\n\t\t#region ResolveBinaryOperator method\n\t\tpublic ResolveResult ResolveBinaryOperator(BinaryOperatorType op, ResolveResult lhs, ResolveResult rhs)\n\t\t{\n\t\t\tif (lhs.Type.Kind == TypeKind.Dynamic || rhs.Type.Kind == TypeKind.Dynamic)\n\t\t\t{\n\t\t\t\tlhs = Convert(lhs, SpecialType.Dynamic);\n\t\t\t\trhs = Convert(rhs, SpecialType.Dynamic);\n\t\t\t\treturn BinaryOperatorResolveResult(SpecialType.Dynamic, lhs, op, rhs);\n\t\t\t}\n\n\t\t\t// C# 4.0 spec: §7.3.4 Binary operator overload resolution\n\t\t\tstring overloadableOperatorName = GetOverloadableOperatorName(op);\n\t\t\tif (overloadableOperatorName == null)\n\t\t\t{\n\n\t\t\t\t// Handle logical and/or exactly as bitwise and/or:\n\t\t\t\t// - If the user overloads a bitwise operator, that implicitly creates the corresponding logical operator.\n\t\t\t\t// - If both inputs are compile-time constants, it doesn't matter that we don't short-circuit.\n\t\t\t\t// - If inputs aren't compile-time constants, we don't evaluate anything, so again it doesn't matter that we don't short-circuit\n\t\t\t\tif (op == BinaryOperatorType.ConditionalAnd)\n\t\t\t\t{\n\t\t\t\t\toverloadableOperatorName = GetOverloadableOperatorName(BinaryOperatorType.BitwiseAnd);\n\t\t\t\t}\n\t\t\t\telse if (op == BinaryOperatorType.ConditionalOr)\n\t\t\t\t{\n\t\t\t\t\toverloadableOperatorName = GetOverloadableOperatorName(BinaryOperatorType.BitwiseOr);\n\t\t\t\t}\n\t\t\t\telse if (op == BinaryOperatorType.NullCoalescing)\n\t\t\t\t{\n\t\t\t\t\t// null coalescing operator is not overloadable and needs to be handled separately\n\t\t\t\t\treturn ResolveNullCoalescingOperator(lhs, rhs);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn ErrorResolveResult.UnknownError;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If the type is nullable, get the underlying type:\n\t\t\tbool isNullable = NullableType.IsNullable(lhs.Type) || NullableType.IsNullable(rhs.Type);\n\t\t\tIType lhsType = NullableType.GetUnderlyingType(lhs.Type);\n\t\t\tIType rhsType = NullableType.GetUnderlyingType(rhs.Type);\n\n\t\t\t// the operator is overloadable:\n\t\t\tOverloadResolution userDefinedOperatorOR = CreateOverloadResolution(new[] { lhs, rhs });\n\t\t\tHashSet<IParameterizedMember> userOperatorCandidates = new HashSet<IParameterizedMember>();\n\t\t\tuserOperatorCandidates.UnionWith(GetUserDefinedOperatorCandidates(lhsType, overloadableOperatorName));\n\t\t\tuserOperatorCandidates.UnionWith(GetUserDefinedOperatorCandidates(rhsType, overloadableOperatorName));\n\t\t\tforeach (var candidate in userOperatorCandidates)\n\t\t\t{\n\t\t\t\tuserDefinedOperatorOR.AddCandidate(candidate);\n\t\t\t}\n\t\t\tif (userDefinedOperatorOR.FoundApplicableCandidate)\n\t\t\t{\n\t\t\t\treturn CreateResolveResultForUserDefinedOperator(userDefinedOperatorOR, BinaryOperatorExpression.GetLinqNodeType(op, this.CheckForOverflow));\n\t\t\t}\n\n\t\t\tif (lhsType.Kind == TypeKind.Null && rhsType.IsReferenceType == false\n\t\t\t\t|| lhsType.IsReferenceType == false && rhsType.Kind == TypeKind.Null)\n\t\t\t{\n\t\t\t\tisNullable = true;\n\t\t\t}\n\t\t\tif (op == BinaryOperatorType.ShiftLeft || op == BinaryOperatorType.ShiftRight || op == BinaryOperatorType.UnsignedShiftRight)\n\t\t\t{\n\t\t\t\t// special case: the shift operators allow \"var x = null << null\", producing int?.\n\t\t\t\tif (lhsType.Kind == TypeKind.Null && rhsType.Kind == TypeKind.Null)\n\t\t\t\t\tisNullable = true;\n\t\t\t\t// for shift operators, do unary promotion independently on both arguments\n\t\t\t\tlhs = UnaryNumericPromotion(UnaryOperatorType.Plus, ref lhsType, isNullable, lhs);\n\t\t\t\trhs = UnaryNumericPromotion(UnaryOperatorType.Plus, ref rhsType, isNullable, rhs);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbool allowNullableConstants = op == BinaryOperatorType.Equality || op == BinaryOperatorType.InEquality;\n\t\t\t\tif (!BinaryNumericPromotion(isNullable, ref lhs, ref rhs, allowNullableConstants))\n\t\t\t\t\treturn new ErrorResolveResult(lhs.Type);\n\t\t\t}\n\t\t\t// re-read underlying types after numeric promotion\n\t\t\tlhsType = NullableType.GetUnderlyingType(lhs.Type);\n\t\t\trhsType = NullableType.GetUnderlyingType(rhs.Type);\n\n\t\t\tIEnumerable<CSharpOperators.OperatorMethod> methodGroup;\n\t\t\tCSharpOperators operators = CSharpOperators.Get(compilation);\n\t\t\tswitch (op)\n\t\t\t{\n\t\t\t\tcase BinaryOperatorType.Multiply:\n\t\t\t\t\tmethodGroup = operators.MultiplicationOperators;\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.Divide:\n\t\t\t\t\tmethodGroup = operators.DivisionOperators;\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.Modulus:\n\t\t\t\t\tmethodGroup = operators.RemainderOperators;\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.Add:\n\t\t\t\t\tmethodGroup = operators.AdditionOperators;\n\t\t\t\t\t{\n\t\t\t\t\t\tif (lhsType.Kind == TypeKind.Enum)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// E operator +(E x, U y);\n\t\t\t\t\t\t\tIType underlyingType = MakeNullable(GetEnumUnderlyingType(lhsType), isNullable);\n\t\t\t\t\t\t\tif (TryConvertEnum(ref rhs, underlyingType, ref isNullable, ref lhs))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn HandleEnumOperator(isNullable, lhsType, op, lhs, rhs);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (rhsType.Kind == TypeKind.Enum)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// E operator +(U x, E y);\n\t\t\t\t\t\t\tIType underlyingType = MakeNullable(GetEnumUnderlyingType(rhsType), isNullable);\n\t\t\t\t\t\t\tif (TryConvertEnum(ref lhs, underlyingType, ref isNullable, ref rhs))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn HandleEnumOperator(isNullable, rhsType, op, lhs, rhs);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (lhsType.Kind == TypeKind.Delegate && TryConvert(ref rhs, lhsType))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn BinaryOperatorResolveResult(lhsType, lhs, op, rhs);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (rhsType.Kind == TypeKind.Delegate && TryConvert(ref lhs, rhsType))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn BinaryOperatorResolveResult(rhsType, lhs, op, rhs);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (lhsType.Kind == TypeKind.Null && rhsType.Kind == TypeKind.Null)\n\t\t\t\t\t\t\treturn new ErrorResolveResult(SpecialType.NullType);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.Subtract:\n\t\t\t\t\tmethodGroup = operators.SubtractionOperators;\n\t\t\t\t\t{\n\t\t\t\t\t\tif (lhsType.Kind == TypeKind.Enum)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// U operator –(E x, E y);\n\t\t\t\t\t\t\tif (TryConvertEnum(ref rhs, lhs.Type, ref isNullable, ref lhs, allowConversionFromConstantZero: false))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn HandleEnumSubtraction(isNullable, lhsType, lhs, rhs);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// E operator –(E x, U y);\n\t\t\t\t\t\t\tIType underlyingType = MakeNullable(GetEnumUnderlyingType(lhsType), isNullable);\n\t\t\t\t\t\t\tif (TryConvertEnum(ref rhs, underlyingType, ref isNullable, ref lhs))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn HandleEnumOperator(isNullable, lhsType, op, lhs, rhs);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (rhsType.Kind == TypeKind.Enum)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// U operator –(E x, E y);\n\t\t\t\t\t\t\tif (TryConvertEnum(ref lhs, rhs.Type, ref isNullable, ref rhs))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn HandleEnumSubtraction(isNullable, rhsType, lhs, rhs);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// E operator -(U x, E y);\n\t\t\t\t\t\t\tIType underlyingType = MakeNullable(GetEnumUnderlyingType(rhsType), isNullable);\n\t\t\t\t\t\t\tif (TryConvertEnum(ref lhs, underlyingType, ref isNullable, ref rhs))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn HandleEnumOperator(isNullable, rhsType, op, lhs, rhs);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (lhsType.Kind == TypeKind.Delegate && TryConvert(ref rhs, lhsType))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn BinaryOperatorResolveResult(lhsType, lhs, op, rhs);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (rhsType.Kind == TypeKind.Delegate && TryConvert(ref lhs, rhsType))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn BinaryOperatorResolveResult(rhsType, lhs, op, rhs);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (lhsType.Kind == TypeKind.Null && rhsType.Kind == TypeKind.Null)\n\t\t\t\t\t\t\treturn new ErrorResolveResult(SpecialType.NullType);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.ShiftLeft:\n\t\t\t\t\tmethodGroup = operators.ShiftLeftOperators;\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.ShiftRight:\n\t\t\t\t\tmethodGroup = operators.ShiftRightOperators;\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.UnsignedShiftRight:\n\t\t\t\t\tmethodGroup = operators.UnsignedShiftRightOperators;\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.Equality:\n\t\t\t\tcase BinaryOperatorType.InEquality:\n\t\t\t\tcase BinaryOperatorType.LessThan:\n\t\t\t\tcase BinaryOperatorType.GreaterThan:\n\t\t\t\tcase BinaryOperatorType.LessThanOrEqual:\n\t\t\t\tcase BinaryOperatorType.GreaterThanOrEqual:\n\t\t\t\t{\n\t\t\t\t\tif (lhsType.Kind == TypeKind.Enum && TryConvert(ref rhs, lhs.Type))\n\t\t\t\t\t{\n\t\t\t\t\t\t// bool operator op(E x, E y);\n\t\t\t\t\t\treturn HandleEnumComparison(op, lhsType, isNullable, lhs, rhs);\n\t\t\t\t\t}\n\t\t\t\t\telse if (rhsType.Kind == TypeKind.Enum && TryConvert(ref lhs, rhs.Type))\n\t\t\t\t\t{\n\t\t\t\t\t\t// bool operator op(E x, E y);\n\t\t\t\t\t\treturn HandleEnumComparison(op, rhsType, isNullable, lhs, rhs);\n\t\t\t\t\t}\n\t\t\t\t\telse if (lhsType is PointerType && rhsType is PointerType)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn BinaryOperatorResolveResult(compilation.FindType(KnownTypeCode.Boolean), lhs, op, rhs);\n\t\t\t\t\t}\n\t\t\t\t\telse if (lhsType.IsCSharpNativeIntegerType() || rhsType.IsCSharpNativeIntegerType())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (lhsType.Equals(rhsType))\n\t\t\t\t\t\t\treturn BinaryOperatorResolveResult(compilation.FindType(KnownTypeCode.Boolean), lhs, op, rhs, isLifted: isNullable);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\treturn new ErrorResolveResult(compilation.FindType(KnownTypeCode.Boolean));\n\t\t\t\t\t}\n\t\t\t\t\tif (op == BinaryOperatorType.Equality || op == BinaryOperatorType.InEquality)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (lhsType.IsReferenceType == true && rhsType.IsReferenceType == true && lhsType.Kind != TypeKind.Null && rhsType.Kind != TypeKind.Null\n\t\t\t\t\t\t\t&& (conversions.IdentityConversion(lhsType, rhsType)\n\t\t\t\t\t\t\t\t|| conversions.ExplicitConversion(lhsType, rhsType).IsReferenceConversion\n\t\t\t\t\t\t\t\t|| conversions.ExplicitConversion(rhsType, lhsType).IsReferenceConversion))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// If it's a reference comparison\n\t\t\t\t\t\t\tif (op == BinaryOperatorType.Equality)\n\t\t\t\t\t\t\t\tmethodGroup = operators.ReferenceEqualityOperators;\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tmethodGroup = operators.ReferenceInequalityOperators;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (lhsType.Kind == TypeKind.Null && IsNullableTypeOrNonValueType(rhs.Type)\n\t\t\t\t\t\t\t\t || IsNullableTypeOrNonValueType(lhs.Type) && rhsType.Kind == TypeKind.Null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// compare type parameter or nullable type with the null literal\n\t\t\t\t\t\t\treturn BinaryOperatorResolveResult(compilation.FindType(KnownTypeCode.Boolean), lhs, op, rhs);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tswitch (op)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase BinaryOperatorType.Equality:\n\t\t\t\t\t\t\tmethodGroup = operators.ValueEqualityOperators;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase BinaryOperatorType.InEquality:\n\t\t\t\t\t\t\tmethodGroup = operators.ValueInequalityOperators;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase BinaryOperatorType.LessThan:\n\t\t\t\t\t\t\tmethodGroup = operators.LessThanOperators;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase BinaryOperatorType.GreaterThan:\n\t\t\t\t\t\t\tmethodGroup = operators.GreaterThanOperators;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase BinaryOperatorType.LessThanOrEqual:\n\t\t\t\t\t\t\tmethodGroup = operators.LessThanOrEqualOperators;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase BinaryOperatorType.GreaterThanOrEqual:\n\t\t\t\t\t\t\tmethodGroup = operators.GreaterThanOrEqualOperators;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow new InvalidOperationException();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.BitwiseAnd:\n\t\t\t\tcase BinaryOperatorType.BitwiseOr:\n\t\t\t\tcase BinaryOperatorType.ExclusiveOr:\n\t\t\t\t{\n\t\t\t\t\tif (lhsType.Kind == TypeKind.Enum)\n\t\t\t\t\t{\n\t\t\t\t\t\t// bool operator op(E x, E y);\n\t\t\t\t\t\tif (TryConvertEnum(ref rhs, lhs.Type, ref isNullable, ref lhs))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn HandleEnumOperator(isNullable, lhsType, op, lhs, rhs);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (rhsType.Kind == TypeKind.Enum)\n\t\t\t\t\t{\n\t\t\t\t\t\t// bool operator op(E x, E y);\n\t\t\t\t\t\tif (TryConvertEnum(ref lhs, rhs.Type, ref isNullable, ref rhs))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn HandleEnumOperator(isNullable, rhsType, op, lhs, rhs);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tswitch (op)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase BinaryOperatorType.BitwiseAnd:\n\t\t\t\t\t\t\tmethodGroup = operators.BitwiseAndOperators;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase BinaryOperatorType.BitwiseOr:\n\t\t\t\t\t\t\tmethodGroup = operators.BitwiseOrOperators;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase BinaryOperatorType.ExclusiveOr:\n\t\t\t\t\t\t\tmethodGroup = operators.BitwiseXorOperators;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow new InvalidOperationException();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.ConditionalAnd:\n\t\t\t\t\tmethodGroup = operators.LogicalAndOperators;\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryOperatorType.ConditionalOr:\n\t\t\t\t\tmethodGroup = operators.LogicalOrOperators;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new InvalidOperationException();\n\t\t\t}\n\t\t\tif (lhsType.IsCSharpNativeIntegerType() || rhsType.IsCSharpNativeIntegerType())\n\t\t\t{\n\t\t\t\tif (lhsType.Equals(rhsType))\n\t\t\t\t{\n\t\t\t\t\treturn BinaryOperatorResolveResult(\n\t\t\t\t\t\tisNullable ? NullableType.Create(compilation, lhsType) : lhsType,\n\t\t\t\t\t\tlhs, op, rhs, isLifted: isNullable);\n\t\t\t\t}\n\t\t\t\t// mixing nint/nuint is not allowed\n\t\t\t\treturn new ErrorResolveResult(lhsType);\n\t\t\t}\n\t\t\tOverloadResolution builtinOperatorOR = CreateOverloadResolution(new[] { lhs, rhs });\n\t\t\tforeach (var candidate in methodGroup)\n\t\t\t{\n\t\t\t\tbuiltinOperatorOR.AddCandidate(candidate);\n\t\t\t}\n\t\t\tCSharpOperators.BinaryOperatorMethod m = (CSharpOperators.BinaryOperatorMethod)builtinOperatorOR.BestCandidate;\n\t\t\tIType resultType = m.ReturnType;\n\t\t\tif (builtinOperatorOR.BestCandidateErrors != OverloadResolutionErrors.None)\n\t\t\t{\n\t\t\t\t// If there are any user-defined operators, prefer those over the built-in operators.\n\t\t\t\t// It'll be a more informative error.\n\t\t\t\tif (userDefinedOperatorOR.BestCandidate != null)\n\t\t\t\t\treturn CreateResolveResultForUserDefinedOperator(userDefinedOperatorOR, BinaryOperatorExpression.GetLinqNodeType(op, this.CheckForOverflow));\n\t\t\t\telse\n\t\t\t\t\treturn new ErrorResolveResult(resultType);\n\t\t\t}\n\t\t\telse if (lhs.IsCompileTimeConstant && rhs.IsCompileTimeConstant && m.CanEvaluateAtCompileTime)\n\t\t\t{\n\t\t\t\tobject val;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tval = m.Invoke(this, lhs.ConstantValue, rhs.ConstantValue);\n\t\t\t\t}\n\t\t\t\tcatch (ArithmeticException)\n\t\t\t\t{\n\t\t\t\t\treturn new ErrorResolveResult(resultType);\n\t\t\t\t}\n\t\t\t\treturn new ConstantResolveResult(resultType, val);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tlhs = Convert(lhs, m.Parameters[0].Type, builtinOperatorOR.ArgumentConversions[0]);\n\t\t\t\trhs = Convert(rhs, m.Parameters[1].Type, builtinOperatorOR.ArgumentConversions[1]);\n\t\t\t\treturn BinaryOperatorResolveResult(resultType, lhs, op, rhs,\n\t\t\t\t\t\t\t\t\t\t\t\t   builtinOperatorOR.BestCandidate is ILiftedOperator);\n\t\t\t}\n\t\t}\n\n\t\tbool IsNullableTypeOrNonValueType(IType type)\n\t\t{\n\t\t\treturn NullableType.IsNullable(type) || type.IsReferenceType != false;\n\t\t}\n\n\t\tResolveResult BinaryOperatorResolveResult(IType resultType, ResolveResult lhs, BinaryOperatorType op, ResolveResult rhs, bool isLifted = false)\n\t\t{\n\t\t\treturn new OperatorResolveResult(\n\t\t\t\tresultType, BinaryOperatorExpression.GetLinqNodeType(op, this.CheckForOverflow),\n\t\t\t\tnull, isLifted, new[] { lhs, rhs });\n\t\t}\n\t\t#endregion\n\n\t\t#region Pointer arithmetic\n\t\tCSharpOperators.BinaryOperatorMethod PointerArithmeticOperator(IType resultType, IType inputType1, KnownTypeCode inputType2)\n\t\t{\n\t\t\treturn PointerArithmeticOperator(resultType, inputType1, compilation.FindType(inputType2));\n\t\t}\n\n\t\tCSharpOperators.BinaryOperatorMethod PointerArithmeticOperator(IType resultType, KnownTypeCode inputType1, IType inputType2)\n\t\t{\n\t\t\treturn PointerArithmeticOperator(resultType, compilation.FindType(inputType1), inputType2);\n\t\t}\n\n\t\tCSharpOperators.BinaryOperatorMethod PointerArithmeticOperator(IType resultType, IType inputType1, IType inputType2)\n\t\t{\n\t\t\treturn new CSharpOperators.BinaryOperatorMethod(compilation) {\n\t\t\t\tReturnType = resultType,\n\t\t\t\tparameters = {\n\t\t\t\t\tnew DefaultParameter(inputType1, string.Empty),\n\t\t\t\t\tnew DefaultParameter(inputType2, string.Empty)\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\t#endregion\n\n\t\t#region Enum helper methods\n\t\tIType GetEnumUnderlyingType(IType enumType)\n\t\t{\n\t\t\tITypeDefinition def = enumType.GetDefinition();\n\t\t\treturn def != null ? def.EnumUnderlyingType : SpecialType.UnknownType;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Handle the case where an enum value is compared with another enum value\n\t\t/// bool operator op(E x, E y);\n\t\t/// </summary>\n\t\tResolveResult HandleEnumComparison(BinaryOperatorType op, IType enumType, bool isNullable, ResolveResult lhs, ResolveResult rhs)\n\t\t{\n\t\t\t// evaluate as ((U)x op (U)y)\n\t\t\tIType elementType = GetEnumUnderlyingType(enumType);\n\t\t\tif (lhs.IsCompileTimeConstant && rhs.IsCompileTimeConstant && !isNullable && elementType.Kind != TypeKind.Enum)\n\t\t\t{\n\t\t\t\tvar rr = ResolveBinaryOperator(op, ResolveCast(elementType, lhs), ResolveCast(elementType, rhs));\n\t\t\t\tif (rr.IsCompileTimeConstant)\n\t\t\t\t\treturn rr;\n\t\t\t}\n\t\t\tIType resultType = compilation.FindType(KnownTypeCode.Boolean);\n\t\t\treturn BinaryOperatorResolveResult(resultType, lhs, op, rhs, isNullable);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Handle the case where an enum value is subtracted from another enum value\n\t\t/// U operator –(E x, E y);\n\t\t/// </summary>\n\t\tResolveResult HandleEnumSubtraction(bool isNullable, IType enumType, ResolveResult lhs, ResolveResult rhs)\n\t\t{\n\t\t\t// evaluate as (U)((U)x – (U)y)\n\t\t\tIType elementType = GetEnumUnderlyingType(enumType);\n\t\t\tif (lhs.IsCompileTimeConstant && rhs.IsCompileTimeConstant && !isNullable && elementType.Kind != TypeKind.Enum)\n\t\t\t{\n\t\t\t\tvar rr = ResolveBinaryOperator(BinaryOperatorType.Subtract, ResolveCast(elementType, lhs), ResolveCast(elementType, rhs));\n\t\t\t\trr = WithCheckForOverflow(false).ResolveCast(elementType, rr);\n\t\t\t\tif (rr.IsCompileTimeConstant)\n\t\t\t\t\treturn rr;\n\t\t\t}\n\t\t\tIType resultType = MakeNullable(elementType, isNullable);\n\t\t\treturn BinaryOperatorResolveResult(resultType, lhs, BinaryOperatorType.Subtract, rhs, isNullable);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Handle the following enum operators:\n\t\t/// E operator +(E x, U y);\n\t\t/// E operator +(U x, E y);\n\t\t/// E operator –(E x, U y);\n\t\t/// E operator &amp;(E x, E y);\n\t\t/// E operator |(E x, E y);\n\t\t/// E operator ^(E x, E y);\n\t\t/// </summary>\n\t\tResolveResult HandleEnumOperator(bool isNullable, IType enumType, BinaryOperatorType op, ResolveResult lhs, ResolveResult rhs)\n\t\t{\n\t\t\t// evaluate as (E)((U)x op (U)y)\n\t\t\tif (lhs.IsCompileTimeConstant && rhs.IsCompileTimeConstant && !isNullable)\n\t\t\t{\n\t\t\t\tIType elementType = GetEnumUnderlyingType(enumType);\n\t\t\t\tif (elementType.Kind != TypeKind.Enum)\n\t\t\t\t{\n\t\t\t\t\tvar rr = ResolveBinaryOperator(op, ResolveCast(elementType, lhs), ResolveCast(elementType, rhs));\n\t\t\t\t\trr = WithCheckForOverflow(false).ResolveCast(enumType, rr);\n\t\t\t\t\tif (rr.IsCompileTimeConstant) // only report result if it's a constant; use the regular OperatorResolveResult codepath otherwise\n\t\t\t\t\t\treturn rr;\n\t\t\t\t}\n\t\t\t}\n\t\t\tIType resultType = MakeNullable(enumType, isNullable);\n\t\t\treturn BinaryOperatorResolveResult(resultType, lhs, op, rhs, isNullable);\n\t\t}\n\n\t\tIType MakeNullable(IType type, bool isNullable)\n\t\t{\n\t\t\tif (isNullable)\n\t\t\t\treturn NullableType.Create(compilation, type);\n\t\t\telse\n\t\t\t\treturn type;\n\t\t}\n\t\t#endregion\n\n\t\t#region BinaryNumericPromotion\n\t\tbool BinaryNumericPromotion(bool isNullable, ref ResolveResult lhs, ref ResolveResult rhs, bool allowNullableConstants)\n\t\t{\n\t\t\t// C# 4.0 spec: §7.3.6.2\n\t\t\tvar lhsUType = NullableType.GetUnderlyingType(lhs.Type);\n\t\t\tvar rhsUType = NullableType.GetUnderlyingType(rhs.Type);\n\t\t\tTypeCode lhsCode = ReflectionHelper.GetTypeCode(lhsUType);\n\t\t\tTypeCode rhsCode = ReflectionHelper.GetTypeCode(rhsUType);\n\t\t\t// Treat C# 9 native integers as falling between int and long.\n\t\t\t// However they don't have a TypeCode, so we hack around that here:\n\t\t\tif (lhsUType.Kind == TypeKind.NInt)\n\t\t\t{\n\t\t\t\tlhsCode = TypeCode.Int32;\n\t\t\t}\n\t\t\telse if (lhsUType.Kind == TypeKind.NUInt)\n\t\t\t{\n\t\t\t\tlhsCode = TypeCode.UInt32;\n\t\t\t}\n\t\t\tif (rhsUType.Kind == TypeKind.NInt)\n\t\t\t{\n\t\t\t\trhsCode = TypeCode.Int32;\n\t\t\t}\n\t\t\telse if (rhsUType.Kind == TypeKind.NUInt)\n\t\t\t{\n\t\t\t\trhsCode = TypeCode.UInt32;\n\t\t\t}\n\t\t\t// if one of the inputs is the null literal, promote that to the type of the other operand\n\t\t\tif (isNullable && lhs.Type.Kind == TypeKind.Null && rhsCode >= TypeCode.Boolean && rhsCode <= TypeCode.Decimal)\n\t\t\t{\n\t\t\t\tlhs = CastTo(rhsCode, isNullable, lhs, allowNullableConstants);\n\t\t\t\tlhsCode = rhsCode;\n\t\t\t}\n\t\t\telse if (isNullable && rhs.Type.Kind == TypeKind.Null && lhsCode >= TypeCode.Boolean && lhsCode <= TypeCode.Decimal)\n\t\t\t{\n\t\t\t\trhs = CastTo(lhsCode, isNullable, rhs, allowNullableConstants);\n\t\t\t\trhsCode = lhsCode;\n\t\t\t}\n\t\t\tbool bindingError = false;\n\t\t\tif (lhsCode >= TypeCode.Char && lhsCode <= TypeCode.Decimal\n\t\t\t\t&& rhsCode >= TypeCode.Char && rhsCode <= TypeCode.Decimal)\n\t\t\t{\n\t\t\t\tTypeCode targetType;\n\t\t\t\tif (lhsCode == TypeCode.Decimal || rhsCode == TypeCode.Decimal)\n\t\t\t\t{\n\t\t\t\t\ttargetType = TypeCode.Decimal;\n\t\t\t\t\tbindingError = (lhsCode == TypeCode.Single || lhsCode == TypeCode.Double\n\t\t\t\t\t\t\t\t\t|| rhsCode == TypeCode.Single || rhsCode == TypeCode.Double);\n\t\t\t\t}\n\t\t\t\telse if (lhsCode == TypeCode.Double || rhsCode == TypeCode.Double)\n\t\t\t\t{\n\t\t\t\t\ttargetType = TypeCode.Double;\n\t\t\t\t}\n\t\t\t\telse if (lhsCode == TypeCode.Single || rhsCode == TypeCode.Single)\n\t\t\t\t{\n\t\t\t\t\ttargetType = TypeCode.Single;\n\t\t\t\t}\n\t\t\t\telse if (lhsCode == TypeCode.UInt64 || rhsCode == TypeCode.UInt64)\n\t\t\t\t{\n\t\t\t\t\ttargetType = TypeCode.UInt64;\n\t\t\t\t\tbindingError = IsSigned(lhsCode, lhs) || IsSigned(rhsCode, rhs);\n\t\t\t\t}\n\t\t\t\telse if (lhsUType.Kind == TypeKind.NUInt || rhsUType.Kind == TypeKind.NUInt)\n\t\t\t\t{\n\t\t\t\t\tbindingError = IsSigned(lhsCode, lhs) || IsSigned(rhsCode, rhs);\n\t\t\t\t\tlhs = CastTo(SpecialType.NUInt, isNullable, lhs, allowNullableConstants);\n\t\t\t\t\trhs = CastTo(SpecialType.NUInt, isNullable, rhs, allowNullableConstants);\n\t\t\t\t\treturn !bindingError;\n\t\t\t\t}\n\t\t\t\telse if (lhsCode == TypeCode.UInt32 || rhsCode == TypeCode.UInt32)\n\t\t\t\t{\n\t\t\t\t\ttargetType = (IsSigned(lhsCode, lhs) || IsSigned(rhsCode, rhs)) ? TypeCode.Int64 : TypeCode.UInt32;\n\t\t\t\t}\n\t\t\t\telse if (lhsCode == TypeCode.Int64 || rhsCode == TypeCode.Int64)\n\t\t\t\t{\n\t\t\t\t\ttargetType = TypeCode.Int64;\n\t\t\t\t}\n\t\t\t\telse if (lhsUType.Kind == TypeKind.NInt || rhsUType.Kind == TypeKind.NInt)\n\t\t\t\t{\n\t\t\t\t\tlhs = CastTo(SpecialType.NInt, isNullable, lhs, allowNullableConstants);\n\t\t\t\t\trhs = CastTo(SpecialType.NInt, isNullable, rhs, allowNullableConstants);\n\t\t\t\t\treturn !bindingError;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ttargetType = TypeCode.Int32;\n\t\t\t\t}\n\t\t\t\tlhs = CastTo(targetType, isNullable, lhs, allowNullableConstants);\n\t\t\t\trhs = CastTo(targetType, isNullable, rhs, allowNullableConstants);\n\t\t\t}\n\t\t\treturn !bindingError;\n\t\t}\n\n\t\tbool IsSigned(TypeCode code, ResolveResult rr)\n\t\t{\n\t\t\t// Determine whether the rr with code==ReflectionHelper.GetTypeCode(NullableType.GetUnderlyingType(rr.Type))\n\t\t\t// is a signed primitive type.\n\t\t\tswitch (code)\n\t\t\t{\n\t\t\t\tcase TypeCode.SByte:\n\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\treturn true;\n\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t// for int, consider implicit constant expression conversion\n\t\t\t\t\tif (rr.IsCompileTimeConstant && rr.ConstantValue != null && (int)rr.ConstantValue >= 0)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn true;\n\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t// for long, consider implicit constant expression conversion\n\t\t\t\t\tif (rr.IsCompileTimeConstant && rr.ConstantValue != null && (long)rr.ConstantValue >= 0)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tResolveResult CastTo(TypeCode targetType, bool isNullable, ResolveResult expression, bool allowNullableConstants)\n\t\t{\n\t\t\treturn CastTo(compilation.FindType(targetType), isNullable, expression, allowNullableConstants);\n\t\t}\n\n\t\tResolveResult CastTo(IType targetType, bool isNullable, ResolveResult expression, bool allowNullableConstants)\n\t\t{\n\t\t\tIType nullableType = MakeNullable(targetType, isNullable);\n\t\t\tif (nullableType.Equals(expression.Type))\n\t\t\t\treturn expression;\n\t\t\tif (allowNullableConstants && expression.IsCompileTimeConstant)\n\t\t\t{\n\t\t\t\tif (expression.ConstantValue == null)\n\t\t\t\t\treturn new ConstantResolveResult(nullableType, null);\n\t\t\t\tResolveResult rr = ResolveCast(targetType, expression);\n\t\t\t\tif (rr.IsError)\n\t\t\t\t\treturn rr;\n\t\t\t\tif (rr.IsCompileTimeConstant)\n\t\t\t\t\treturn new ConstantResolveResult(nullableType, rr.ConstantValue);\n\t\t\t}\n\t\t\treturn Convert(expression, nullableType,\n\t\t\t\t\t\t\tisNullable ? Conversion.ImplicitNullableConversion : Conversion.ImplicitNumericConversion);\n\t\t}\n\t\t#endregion\n\n\t\t#region GetOverloadableOperatorName\n\t\tstatic string GetOverloadableOperatorName(BinaryOperatorType op)\n\t\t{\n\t\t\tswitch (op)\n\t\t\t{\n\t\t\t\tcase BinaryOperatorType.Add:\n\t\t\t\t\treturn \"op_Addition\";\n\t\t\t\tcase BinaryOperatorType.Subtract:\n\t\t\t\t\treturn \"op_Subtraction\";\n\t\t\t\tcase BinaryOperatorType.Multiply:\n\t\t\t\t\treturn \"op_Multiply\";\n\t\t\t\tcase BinaryOperatorType.Divide:\n\t\t\t\t\treturn \"op_Division\";\n\t\t\t\tcase BinaryOperatorType.Modulus:\n\t\t\t\t\treturn \"op_Modulus\";\n\t\t\t\tcase BinaryOperatorType.BitwiseAnd:\n\t\t\t\t\treturn \"op_BitwiseAnd\";\n\t\t\t\tcase BinaryOperatorType.BitwiseOr:\n\t\t\t\t\treturn \"op_BitwiseOr\";\n\t\t\t\tcase BinaryOperatorType.ExclusiveOr:\n\t\t\t\t\treturn \"op_ExclusiveOr\";\n\t\t\t\tcase BinaryOperatorType.ShiftLeft:\n\t\t\t\t\treturn \"op_LeftShift\";\n\t\t\t\tcase BinaryOperatorType.ShiftRight:\n\t\t\t\t\treturn \"op_RightShift\";\n\t\t\t\tcase BinaryOperatorType.UnsignedShiftRight:\n\t\t\t\t\treturn \"op_UnsignedRightShift\";\n\t\t\t\tcase BinaryOperatorType.Equality:\n\t\t\t\t\treturn \"op_Equality\";\n\t\t\t\tcase BinaryOperatorType.InEquality:\n\t\t\t\t\treturn \"op_Inequality\";\n\t\t\t\tcase BinaryOperatorType.GreaterThan:\n\t\t\t\t\treturn \"op_GreaterThan\";\n\t\t\t\tcase BinaryOperatorType.LessThan:\n\t\t\t\t\treturn \"op_LessThan\";\n\t\t\t\tcase BinaryOperatorType.GreaterThanOrEqual:\n\t\t\t\t\treturn \"op_GreaterThanOrEqual\";\n\t\t\t\tcase BinaryOperatorType.LessThanOrEqual:\n\t\t\t\t\treturn \"op_LessThanOrEqual\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Null coalescing operator\n\t\tResolveResult ResolveNullCoalescingOperator(ResolveResult lhs, ResolveResult rhs)\n\t\t{\n\t\t\tif (NullableType.IsNullable(lhs.Type))\n\t\t\t{\n\t\t\t\tIType a0 = NullableType.GetUnderlyingType(lhs.Type);\n\t\t\t\tif (TryConvert(ref rhs, a0))\n\t\t\t\t{\n\t\t\t\t\treturn BinaryOperatorResolveResult(a0, lhs, BinaryOperatorType.NullCoalescing, rhs);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (TryConvert(ref rhs, lhs.Type))\n\t\t\t{\n\t\t\t\treturn BinaryOperatorResolveResult(lhs.Type, lhs, BinaryOperatorType.NullCoalescing, rhs);\n\t\t\t}\n\t\t\tif (TryConvert(ref lhs, rhs.Type))\n\t\t\t{\n\t\t\t\treturn BinaryOperatorResolveResult(rhs.Type, lhs, BinaryOperatorType.NullCoalescing, rhs);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new ErrorResolveResult(lhs.Type);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\t\t#endregion\n\n\t\t#region Get user-defined operator candidates\n\t\tpublic IEnumerable<IParameterizedMember> GetUserDefinedOperatorCandidates(IType type, string operatorName)\n\t\t{\n\t\t\tif (operatorName == null)\n\t\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t\tTypeCode c = ReflectionHelper.GetTypeCode(type);\n\t\t\tif (TypeCode.Boolean <= c && c <= TypeCode.Decimal)\n\t\t\t{\n\t\t\t\t// The .NET framework contains some of C#'s built-in operators as user-defined operators.\n\t\t\t\t// However, we must not use those as user-defined operators (we would skip numeric promotion).\n\t\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t\t}\n\t\t\t// C# 4.0 spec: §7.3.5 Candidate user-defined operators\n\t\t\tvar operators = type.GetMethods(m => m.IsOperator && m.Name == operatorName).ToList();\n\t\t\tLiftUserDefinedOperators(operators);\n\t\t\treturn operators;\n\t\t}\n\n\t\tvoid LiftUserDefinedOperators(List<IMethod> operators)\n\t\t{\n\t\t\tint nonLiftedMethodCount = operators.Count;\n\t\t\t// Construct lifted operators\n\t\t\tfor (int i = 0; i < nonLiftedMethodCount; i++)\n\t\t\t{\n\t\t\t\tvar liftedMethod = CSharpOperators.LiftUserDefinedOperator(operators[i]);\n\t\t\t\tif (liftedMethod != null)\n\t\t\t\t\toperators.Add(liftedMethod);\n\t\t\t}\n\t\t}\n\n\t\tResolveResult CreateResolveResultForUserDefinedOperator(OverloadResolution r, System.Linq.Expressions.ExpressionType operatorType)\n\t\t{\n\t\t\tif (r.BestCandidateErrors != OverloadResolutionErrors.None)\n\t\t\t\treturn r.CreateResolveResult(null);\n\t\t\tIMethod method = (IMethod)r.BestCandidate;\n\t\t\treturn new OperatorResolveResult(method.ReturnType, operatorType, method,\n\t\t\t\t\t\t\t\t\t\t\t isLiftedOperator: method is ILiftedOperator,\n\t\t\t\t\t\t\t\t\t\t\t operands: r.GetArgumentsWithConversions());\n\t\t}\n\t\t#endregion\n\n\t\t#region ResolveCast\n\t\tbool TryConvert(ref ResolveResult rr, IType targetType)\n\t\t{\n\t\t\tConversion c = conversions.ImplicitConversion(rr, targetType);\n\t\t\tif (c.IsValid)\n\t\t\t{\n\t\t\t\trr = Convert(rr, targetType, c);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// \n\t\t/// </summary>\n\t\t/// <param name=\"rr\">The input resolve result that should be converted.\n\t\t/// If a conversion exists, it is applied to the resolve result</param>\n\t\t/// <param name=\"targetType\">The target type that we should convert to</param>\n\t\t/// <param name=\"isNullable\">Whether we are dealing with a lifted operator</param>\n\t\t/// <param name=\"enumRR\">The resolve result that is enum-typed.\n\t\t/// If necessary, a nullable conversion is applied.</param>\n\t\t/// <param name=\"allowConversionFromConstantZero\">\n\t\t/// Whether the conversion from the constant zero is allowed.\n\t\t/// </param>\n\t\t/// <returns>True if the conversion is successful; false otherwise.\n\t\t/// If the conversion is not successful, the ref parameters will not be modified.</returns>\n\t\tbool TryConvertEnum(ref ResolveResult rr, IType targetType, ref bool isNullable, ref ResolveResult enumRR, bool allowConversionFromConstantZero = true)\n\t\t{\n\t\t\tConversion c;\n\t\t\tif (!isNullable)\n\t\t\t{\n\t\t\t\t// Try non-nullable\n\t\t\t\tc = conversions.ImplicitConversion(rr, targetType);\n\t\t\t\tif (c.IsValid && (allowConversionFromConstantZero || !c.IsEnumerationConversion))\n\t\t\t\t{\n\t\t\t\t\trr = Convert(rr, targetType, c);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// make targetType nullable if it isn't already:\n\t\t\tif (!targetType.IsKnownType(KnownTypeCode.NullableOfT))\n\t\t\t\ttargetType = NullableType.Create(compilation, targetType);\n\n\t\t\tc = conversions.ImplicitConversion(rr, targetType);\n\t\t\tif (c.IsValid && (allowConversionFromConstantZero || !c.IsEnumerationConversion))\n\t\t\t{\n\t\t\t\trr = Convert(rr, targetType, c);\n\t\t\t\tisNullable = true;\n\t\t\t\t// Also convert the enum-typed RR to nullable, if it isn't already\n\t\t\t\tif (!enumRR.Type.IsKnownType(KnownTypeCode.NullableOfT))\n\t\t\t\t{\n\t\t\t\t\tvar nullableType = NullableType.Create(compilation, enumRR.Type);\n\t\t\t\t\tenumRR = new ConversionResolveResult(nullableType, enumRR, Conversion.ImplicitNullableConversion);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tResolveResult Convert(ResolveResult rr, IType targetType)\n\t\t{\n\t\t\treturn Convert(rr, targetType, conversions.ImplicitConversion(rr, targetType));\n\t\t}\n\n\t\tResolveResult Convert(ResolveResult rr, IType targetType, Conversion c)\n\t\t{\n\t\t\tif (c == Conversion.IdentityConversion)\n\t\t\t\treturn rr;\n\t\t\telse if (rr.IsCompileTimeConstant && c != Conversion.None && !c.IsUserDefined)\n\t\t\t\treturn ResolveCast(targetType, rr);\n\t\t\telse\n\t\t\t\treturn new ConversionResolveResult(targetType, rr, c, checkForOverflow);\n\t\t}\n\n\t\tpublic ResolveResult ResolveCast(IType targetType, ResolveResult expression)\n\t\t{\n\t\t\t// C# 4.0 spec: §7.7.6 Cast expressions\n\t\t\tConversion c = conversions.ExplicitConversion(expression, targetType);\n\t\t\tif (expression.IsCompileTimeConstant && !c.IsUserDefined)\n\t\t\t{\n\t\t\t\tIType underlyingType = targetType.GetEnumUnderlyingType();\n\t\t\t\tTypeCode code = ReflectionHelper.GetTypeCode(underlyingType);\n\t\t\t\tif (code >= TypeCode.Boolean && code <= TypeCode.Decimal && expression.ConstantValue != null)\n\t\t\t\t{\n\t\t\t\t\tif (expression.ConstantValue is string)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new ErrorResolveResult(targetType);\n\t\t\t\t\t}\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new ConstantResolveResult(targetType, CSharpPrimitiveCast(code, expression.ConstantValue));\n\t\t\t\t\t}\n\t\t\t\t\tcatch (OverflowException)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new ErrorResolveResult(targetType);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (InvalidCastException)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new ErrorResolveResult(targetType);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (code == TypeCode.String)\n\t\t\t\t{\n\t\t\t\t\tif (expression.ConstantValue == null || expression.ConstantValue is string)\n\t\t\t\t\t\treturn new ConstantResolveResult(targetType, expression.ConstantValue);\n\t\t\t\t\telse\n\t\t\t\t\t\treturn new ErrorResolveResult(targetType);\n\t\t\t\t}\n\t\t\t\telse if ((underlyingType.Kind == TypeKind.NInt || underlyingType.Kind == TypeKind.NUInt) && expression.ConstantValue != null)\n\t\t\t\t{\n\t\t\t\t\tif (expression.ConstantValue is string)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new ErrorResolveResult(targetType);\n\t\t\t\t\t}\n\t\t\t\t\tcode = (underlyingType.Kind == TypeKind.NInt ? TypeCode.Int32 : TypeCode.UInt32);\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new ConstantResolveResult(targetType, Util.CSharpPrimitiveCast.Cast(code, expression.ConstantValue, checkForOverflow: true));\n\t\t\t\t\t}\n\t\t\t\t\tcatch (OverflowException)\n\t\t\t\t\t{\n\t\t\t\t\t\t// If constant value doesn't fit into 32-bits, the conversion is not a compile-time constant\n\t\t\t\t\t\treturn new ConversionResolveResult(targetType, expression, c, checkForOverflow);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (InvalidCastException)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new ErrorResolveResult(targetType);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn new ConversionResolveResult(targetType, expression, c, checkForOverflow);\n\t\t}\n\n\t\tinternal object CSharpPrimitiveCast(TypeCode targetType, object input)\n\t\t{\n\t\t\treturn Util.CSharpPrimitiveCast.Cast(targetType, input, this.CheckForOverflow);\n\t\t}\n\t\t#endregion\n\n\t\t#region ResolveSimpleName\n\t\tpublic ResolveResult ResolveSimpleName(string identifier, IReadOnlyList<IType> typeArguments, bool isInvocationTarget = false)\n\t\t{\n\t\t\t// C# 4.0 spec: §7.6.2 Simple Names\n\n\t\t\treturn LookupSimpleNameOrTypeName(\n\t\t\t\tidentifier, typeArguments,\n\t\t\t\tisInvocationTarget ? NameLookupMode.InvocationTarget : NameLookupMode.Expression);\n\t\t}\n\n\t\tpublic ResolveResult LookupSimpleNameOrTypeName(string identifier, IReadOnlyList<IType> typeArguments, NameLookupMode lookupMode)\n\t\t{\n\t\t\t// C# 4.0 spec: §3.8 Namespace and type names; §7.6.2 Simple Names\n\n\t\t\tif (identifier == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(identifier));\n\t\t\tif (typeArguments == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(typeArguments));\n\n\t\t\tint k = typeArguments.Count;\n\n\t\t\tif (k == 0)\n\t\t\t{\n\t\t\t\tif (lookupMode == NameLookupMode.Expression || lookupMode == NameLookupMode.InvocationTarget)\n\t\t\t\t{\n\t\t\t\t\t// Look in local variables\n\t\t\t\t\tforeach (Dictionary<string, IVariable> variables in localVariableStack)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (variables.TryGetValue(identifier, out var v))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn new LocalResolveResult(v);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// Look in parameters of current method\n\t\t\t\t\tIParameterizedMember parameterizedMember = this.CurrentMember as IParameterizedMember;\n\t\t\t\t\tif (parameterizedMember != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (IParameter p in parameterizedMember.Parameters)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (p.Name == identifier)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn new LocalResolveResult(p);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// look in type parameters of current method\n\t\t\t\tIMethod m = this.CurrentMember as IMethod;\n\t\t\t\tif (m != null)\n\t\t\t\t{\n\t\t\t\t\tforeach (ITypeParameter tp in m.TypeParameters)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (tp.Name == identifier)\n\t\t\t\t\t\t\treturn new TypeResolveResult(tp);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool parameterizeResultType = !(typeArguments.Count != 0 && typeArguments.All(t => t.Kind == TypeKind.UnboundTypeArgument));\n\n\t\t\tResolveResult r = null;\n\t\t\tif (currentTypeDefinitionCache != null)\n\t\t\t{\n\t\t\t\tDictionary<string, ResolveResult> cache = null;\n\t\t\t\tbool foundInCache = false;\n\t\t\t\tif (k == 0)\n\t\t\t\t{\n\t\t\t\t\tswitch (lookupMode)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase NameLookupMode.Expression:\n\t\t\t\t\t\t\tcache = currentTypeDefinitionCache.SimpleNameLookupCacheExpression;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase NameLookupMode.InvocationTarget:\n\t\t\t\t\t\t\tcache = currentTypeDefinitionCache.SimpleNameLookupCacheInvocationTarget;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase NameLookupMode.Type:\n\t\t\t\t\t\t\tcache = currentTypeDefinitionCache.SimpleTypeLookupCache;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (cache != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tlock (cache)\n\t\t\t\t\t\t\tfoundInCache = cache.TryGetValue(identifier, out r);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (foundInCache)\n\t\t\t\t{\n\t\t\t\t\tr = (r != null ? r.ShallowClone() : null);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tr = LookInCurrentType(identifier, typeArguments, lookupMode, parameterizeResultType);\n\t\t\t\t\tif (cache != null)\n\t\t\t\t\t{\n\t\t\t\t\t\t// also cache missing members (r==null)\n\t\t\t\t\t\tlock (cache)\n\t\t\t\t\t\t\tcache[identifier] = r;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (r != null)\n\t\t\t\t\treturn r;\n\t\t\t}\n\n\t\t\tif (context.CurrentUsingScope == null)\n\t\t\t{\n\t\t\t\t// If no using scope was specified, we still need to look in the global namespace:\n\t\t\t\tr = LookInUsingScopeNamespace(null, compilation.RootNamespace, identifier, typeArguments, parameterizeResultType);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (k == 0 && lookupMode != NameLookupMode.TypeInUsingDeclaration)\n\t\t\t\t{\n\t\t\t\t\tif (context.CurrentUsingScope.ResolveCache.TryGetValue(identifier, out r))\n\t\t\t\t\t{\n\t\t\t\t\t\tr = (r != null ? r.ShallowClone() : null);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tr = LookInCurrentUsingScope(identifier, typeArguments, false, false);\n\t\t\t\t\t\tcontext.CurrentUsingScope.ResolveCache.TryAdd(identifier, r);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tr = LookInCurrentUsingScope(identifier, typeArguments, lookupMode == NameLookupMode.TypeInUsingDeclaration, parameterizeResultType);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (r != null)\n\t\t\t\treturn r;\n\n\t\t\tif (typeArguments.Count == 0 && identifier == \"dynamic\")\n\t\t\t{\n\t\t\t\treturn new TypeResolveResult(SpecialType.Dynamic);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new UnknownIdentifierResolveResult(identifier, typeArguments.Count);\n\t\t\t}\n\t\t}\n\n\t\tpublic bool IsVariableReferenceWithSameType(ResolveResult rr, string identifier, out TypeResolveResult trr)\n\t\t{\n\t\t\tif (!(rr is MemberResolveResult || rr is LocalResolveResult))\n\t\t\t{\n\t\t\t\ttrr = null;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\ttrr = LookupSimpleNameOrTypeName(identifier, EmptyList<IType>.Instance, NameLookupMode.Type) as TypeResolveResult;\n\t\t\treturn trr != null && trr.Type.Equals(rr.Type);\n\t\t}\n\n\t\tResolveResult LookInCurrentType(string identifier, IReadOnlyList<IType> typeArguments, NameLookupMode lookupMode, bool parameterizeResultType)\n\t\t{\n\t\t\tint k = typeArguments.Count;\n\t\t\tMemberLookup lookup = CreateMemberLookup(lookupMode);\n\t\t\t// look in current type definitions\n\t\t\tfor (ITypeDefinition t = this.CurrentTypeDefinition; t != null; t = t.DeclaringTypeDefinition)\n\t\t\t{\n\t\t\t\tif (k == 0)\n\t\t\t\t{\n\t\t\t\t\t// Look for type parameter with that name\n\t\t\t\t\tvar typeParameters = t.TypeParameters;\n\t\t\t\t\t// Look at all type parameters, including those copied from outer classes,\n\t\t\t\t\t// so that we can fetch the version with the correct owner.\n\t\t\t\t\tfor (int i = 0; i < typeParameters.Count; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (typeParameters[i].Name == identifier)\n\t\t\t\t\t\t\treturn new TypeResolveResult(typeParameters[i]);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (lookupMode == NameLookupMode.BaseTypeReference && t == this.CurrentTypeDefinition)\n\t\t\t\t{\n\t\t\t\t\t// don't look in current type when resolving a base type reference\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tResolveResult r;\n\t\t\t\tif (lookupMode == NameLookupMode.Expression || lookupMode == NameLookupMode.InvocationTarget)\n\t\t\t\t{\n\t\t\t\t\tvar targetResolveResult = (t == this.CurrentTypeDefinition ? ResolveThisReference() : new TypeResolveResult(t));\n\t\t\t\t\tr = lookup.Lookup(targetResolveResult, identifier, typeArguments, lookupMode == NameLookupMode.InvocationTarget);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tr = lookup.LookupType(t, identifier, typeArguments, parameterizeResultType);\n\t\t\t\t}\n\t\t\t\tif (!(r is UnknownMemberResolveResult)) // but do return AmbiguousMemberResolveResult\n\t\t\t\t\treturn r;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tResolveResult LookInCurrentUsingScope(string identifier, IReadOnlyList<IType> typeArguments, bool isInUsingDeclaration, bool parameterizeResultType)\n\t\t{\n\t\t\t// look in current namespace definitions\n\t\t\tUsingScope currentUsingScope = this.CurrentUsingScope;\n\t\t\tfor (UsingScope u = currentUsingScope; u != null; u = u.Parent)\n\t\t\t{\n\t\t\t\tvar resultInNamespace = LookInUsingScopeNamespace(u, u.Namespace, identifier, typeArguments, parameterizeResultType);\n\t\t\t\tif (resultInNamespace != null)\n\t\t\t\t\treturn resultInNamespace;\n\t\t\t\t// then look for aliases:\n\t\t\t\tif (typeArguments.Count == 0)\n\t\t\t\t{\n\t\t\t\t\tif (u.ExternAliases.Contains(identifier))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn ResolveExternAlias(identifier);\n\t\t\t\t\t}\n\t\t\t\t\tif (!(isInUsingDeclaration && u == currentUsingScope))\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var pair in u.UsingAliases)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (pair.Key == identifier)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn pair.Value.ShallowClone();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// finally, look in the imported namespaces:\n\t\t\t\tif (!(isInUsingDeclaration && u == currentUsingScope))\n\t\t\t\t{\n\t\t\t\t\tIType firstResult = null;\n\t\t\t\t\tforeach (var importedNamespace in u.Usings)\n\t\t\t\t\t{\n\t\t\t\t\t\tITypeDefinition def = importedNamespace.GetTypeDefinition(identifier, typeArguments.Count);\n\t\t\t\t\t\tif (def != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tIType resultType;\n\t\t\t\t\t\t\tif (parameterizeResultType && typeArguments.Count > 0)\n\t\t\t\t\t\t\t\tresultType = new ParameterizedType(def, typeArguments);\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tresultType = def;\n\n\t\t\t\t\t\t\tif (firstResult == null || !TopLevelTypeDefinitionIsAccessible(firstResult.GetDefinition()))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (TopLevelTypeDefinitionIsAccessible(resultType.GetDefinition()))\n\t\t\t\t\t\t\t\t\tfirstResult = resultType;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (TopLevelTypeDefinitionIsAccessible(def))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn new AmbiguousTypeResolveResult(firstResult);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (firstResult != null)\n\t\t\t\t\t\treturn new TypeResolveResult(firstResult);\n\t\t\t\t}\n\t\t\t\t// if we didn't find anything: repeat lookup with parent namespace\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tResolveResult LookInUsingScopeNamespace(UsingScope usingScope, INamespace n, string identifier, IReadOnlyList<IType> typeArguments, bool parameterizeResultType)\n\t\t{\n\t\t\tif (n == null)\n\t\t\t\treturn null;\n\t\t\t// first look for a namespace\n\t\t\tint k = typeArguments.Count;\n\t\t\tif (k == 0)\n\t\t\t{\n\t\t\t\tINamespace childNamespace = n.GetChildNamespace(identifier);\n\t\t\t\tif (childNamespace != null)\n\t\t\t\t{\n\t\t\t\t\tif (usingScope != null && usingScope.HasAlias(identifier))\n\t\t\t\t\t\treturn new AmbiguousTypeResolveResult(new UnknownType(null, identifier));\n\t\t\t\t\treturn new NamespaceResolveResult(childNamespace);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// then look for a type\n\t\t\tITypeDefinition def = n.GetTypeDefinition(identifier, k);\n\t\t\tif (def != null && TopLevelTypeDefinitionIsAccessible(def))\n\t\t\t{\n\t\t\t\tIType result = def;\n\t\t\t\tif (parameterizeResultType && k > 0)\n\t\t\t\t{\n\t\t\t\t\tresult = new ParameterizedType(def, typeArguments);\n\t\t\t\t}\n\t\t\t\tif (usingScope != null && usingScope.HasAlias(identifier))\n\t\t\t\t\treturn new AmbiguousTypeResolveResult(result);\n\t\t\t\telse\n\t\t\t\t\treturn new TypeResolveResult(result);\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tbool TopLevelTypeDefinitionIsAccessible(ITypeDefinition typeDef)\n\t\t{\n\t\t\tif (typeDef.Accessibility == Accessibility.Internal)\n\t\t\t{\n\t\t\t\treturn typeDef.ParentModule.InternalsVisibleTo(compilation.MainModule);\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Looks up an alias (identifier in front of :: operator)\n\t\t/// </summary>\n\t\tpublic ResolveResult ResolveAlias(string identifier)\n\t\t{\n\t\t\tif (identifier == \"global\")\n\t\t\t\treturn new NamespaceResolveResult(compilation.RootNamespace);\n\n\t\t\tfor (UsingScope n = this.CurrentUsingScope; n != null; n = n.Parent)\n\t\t\t{\n\t\t\t\tif (n.ExternAliases.Contains(identifier))\n\t\t\t\t{\n\t\t\t\t\treturn ResolveExternAlias(identifier);\n\t\t\t\t}\n\t\t\t\tforeach (var pair in n.UsingAliases)\n\t\t\t\t{\n\t\t\t\t\tif (pair.Key == identifier)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn (pair.Value as NamespaceResolveResult) ?? ErrorResult;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ErrorResult;\n\t\t}\n\n\t\tResolveResult ResolveExternAlias(string alias)\n\t\t{\n\t\t\tINamespace ns = compilation.GetNamespaceForExternAlias(alias);\n\t\t\tif (ns != null)\n\t\t\t\treturn new NamespaceResolveResult(ns);\n\t\t\telse\n\t\t\t\treturn ErrorResult;\n\t\t}\n\t\t#endregion\n\n\t\t#region ResolveMemberAccess\n\t\tpublic ResolveResult ResolveMemberAccess(ResolveResult target, string identifier, IReadOnlyList<IType> typeArguments, NameLookupMode lookupMode = NameLookupMode.Expression)\n\t\t{\n\t\t\t// C# 4.0 spec: §7.6.4\n\n\t\t\tbool parameterizeResultType = !(typeArguments.Count != 0 && typeArguments.All(t => t.Kind == TypeKind.UnboundTypeArgument));\n\t\t\tNamespaceResolveResult nrr = target as NamespaceResolveResult;\n\t\t\tif (nrr != null)\n\t\t\t{\n\t\t\t\treturn ResolveMemberAccessOnNamespace(nrr, identifier, typeArguments, parameterizeResultType);\n\t\t\t}\n\n\t\t\tif (target.Type.Kind == TypeKind.Dynamic)\n\t\t\t\treturn new DynamicMemberResolveResult(target, identifier);\n\n\t\t\tMemberLookup lookup = CreateMemberLookup(lookupMode);\n\t\t\tResolveResult result;\n\t\t\tswitch (lookupMode)\n\t\t\t{\n\t\t\t\tcase NameLookupMode.Expression:\n\t\t\t\t\tresult = lookup.Lookup(target, identifier, typeArguments, isInvocation: false);\n\t\t\t\t\tbreak;\n\t\t\t\tcase NameLookupMode.InvocationTarget:\n\t\t\t\t\tresult = lookup.Lookup(target, identifier, typeArguments, isInvocation: true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase NameLookupMode.Type:\n\t\t\t\tcase NameLookupMode.TypeInUsingDeclaration:\n\t\t\t\tcase NameLookupMode.BaseTypeReference:\n\t\t\t\t\t// Don't do the UnknownMemberResolveResult/MethodGroupResolveResult processing,\n\t\t\t\t\t// it's only relevant for expressions.\n\t\t\t\t\treturn lookup.LookupType(target.Type, identifier, typeArguments, parameterizeResultType);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException(\"Invalid value for NameLookupMode\");\n\t\t\t}\n\t\t\tif (result is UnknownMemberResolveResult)\n\t\t\t{\n\t\t\t\t// We intentionally use all extension methods here, not just the eligible ones.\n\t\t\t\t// Proper eligibility checking is only possible for the full invocation\n\t\t\t\t// (after we know the remaining arguments).\n\t\t\t\t// The eligibility check in GetExtensionMethods is only intended for code completion.\n\t\t\t\tvar extensionMethods = GetExtensionMethods(identifier, typeArguments);\n\t\t\t\tif (extensionMethods.Count > 0)\n\t\t\t\t{\n\t\t\t\t\treturn new MethodGroupResolveResult(target, identifier, EmptyList<MethodListWithDeclaringType>.Instance, typeArguments) {\n\t\t\t\t\t\textensionMethods = extensionMethods\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tMethodGroupResolveResult mgrr = result as MethodGroupResolveResult;\n\t\t\t\tif (mgrr != null)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(mgrr.extensionMethods == null);\n\t\t\t\t\t// set the values that are necessary to make MethodGroupResolveResult.GetExtensionMethods() work\n\t\t\t\t\tmgrr.resolver = this;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tResolveResult ResolveMemberAccessOnNamespace(NamespaceResolveResult nrr, string identifier, IReadOnlyList<IType> typeArguments, bool parameterizeResultType)\n\t\t{\n\t\t\tif (typeArguments.Count == 0)\n\t\t\t{\n\t\t\t\tINamespace childNamespace = nrr.Namespace.GetChildNamespace(identifier);\n\t\t\t\tif (childNamespace != null)\n\t\t\t\t\treturn new NamespaceResolveResult(childNamespace);\n\t\t\t}\n\t\t\tITypeDefinition def = nrr.Namespace.GetTypeDefinition(identifier, typeArguments.Count);\n\t\t\tif (def != null)\n\t\t\t{\n\t\t\t\tif (parameterizeResultType && typeArguments.Count > 0)\n\t\t\t\t\treturn new TypeResolveResult(new ParameterizedType(def, typeArguments));\n\t\t\t\telse\n\t\t\t\t\treturn new TypeResolveResult(def);\n\t\t\t}\n\t\t\treturn ErrorResult;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a MemberLookup instance using this resolver's settings.\n\t\t/// </summary>\n\t\tpublic MemberLookup CreateMemberLookup()\n\t\t{\n\t\t\tITypeDefinition currentTypeDefinition = this.CurrentTypeDefinition;\n\t\t\tbool isInEnumMemberInitializer = this.CurrentMember != null && this.CurrentMember.SymbolKind == SymbolKind.Field\n\t\t\t\t&& currentTypeDefinition != null && currentTypeDefinition.Kind == TypeKind.Enum;\n\t\t\treturn new MemberLookup(currentTypeDefinition, this.Compilation.MainModule, isInEnumMemberInitializer);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a MemberLookup instance using this resolver's settings.\n\t\t/// </summary>\n\t\tpublic MemberLookup CreateMemberLookup(NameLookupMode lookupMode)\n\t\t{\n\t\t\tif (lookupMode == NameLookupMode.BaseTypeReference && this.CurrentTypeDefinition != null)\n\t\t\t{\n\t\t\t\t// When looking up a base type reference, treat us as being outside the current type definition\n\t\t\t\t// for accessibility purposes.\n\t\t\t\t// This avoids a stack overflow when referencing a protected class nested inside the base class\n\t\t\t\t// of a parent class. (NameLookupTests.InnerClassInheritingFromProtectedBaseInnerClassShouldNotCauseStackOverflow)\n\t\t\t\treturn new MemberLookup(this.CurrentTypeDefinition.DeclaringTypeDefinition, this.Compilation.MainModule, false);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn CreateMemberLookup();\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region ResolveIdentifierInObjectInitializer\n\t\tpublic ResolveResult ResolveIdentifierInObjectInitializer(string identifier)\n\t\t{\n\t\t\tMemberLookup memberLookup = CreateMemberLookup();\n\t\t\treturn memberLookup.Lookup(this.CurrentObjectInitializer, identifier, EmptyList<IType>.Instance, false);\n\t\t}\n\t\t#endregion\n\n\t\t#region ResolveForeach\n\t\tpublic ForEachResolveResult ResolveForeach(ResolveResult expression)\n\t\t{\n\t\t\tvar memberLookup = CreateMemberLookup();\n\n\t\t\tIType collectionType, enumeratorType, elementType;\n\t\t\tResolveResult getEnumeratorInvocation;\n\t\t\tResolveResult currentRR = null;\n\t\t\t// C# 4.0 spec: §8.8.4 The foreach statement\n\t\t\tif (expression.Type.Kind == TypeKind.Array || expression.Type.Kind == TypeKind.Dynamic)\n\t\t\t{\n\t\t\t\tcollectionType = compilation.FindType(KnownTypeCode.IEnumerable);\n\t\t\t\tenumeratorType = compilation.FindType(KnownTypeCode.IEnumerator);\n\t\t\t\tif (expression.Type.Kind == TypeKind.Array)\n\t\t\t\t{\n\t\t\t\t\telementType = ((ArrayType)expression.Type).ElementType;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\telementType = SpecialType.Dynamic;\n\t\t\t\t}\n\t\t\t\tgetEnumeratorInvocation = ResolveCast(collectionType, expression);\n\t\t\t\tgetEnumeratorInvocation = ResolveMemberAccess(getEnumeratorInvocation, \"GetEnumerator\", EmptyList<IType>.Instance, NameLookupMode.InvocationTarget);\n\t\t\t\tgetEnumeratorInvocation = ResolveInvocation(getEnumeratorInvocation, Empty<ResolveResult>.Array);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar getEnumeratorMethodGroup = memberLookup.Lookup(expression, \"GetEnumerator\", EmptyList<IType>.Instance, true) as MethodGroupResolveResult;\n\t\t\t\tif (getEnumeratorMethodGroup != null)\n\t\t\t\t{\n\t\t\t\t\tvar or = getEnumeratorMethodGroup.PerformOverloadResolution(\n\t\t\t\t\t\tcompilation, Empty<ResolveResult>.Array,\n\t\t\t\t\t\tallowExtensionMethods: false, allowExpandingParams: false, allowOptionalParameters: false);\n\t\t\t\t\tif (or.FoundApplicableCandidate && !or.IsAmbiguous && !or.BestCandidate.IsStatic && or.BestCandidate.Accessibility == Accessibility.Public)\n\t\t\t\t\t{\n\t\t\t\t\t\tcollectionType = expression.Type;\n\t\t\t\t\t\tgetEnumeratorInvocation = or.CreateResolveResult(expression);\n\t\t\t\t\t\tenumeratorType = getEnumeratorInvocation.Type;\n\t\t\t\t\t\tcurrentRR = memberLookup.Lookup(new ResolveResult(enumeratorType), \"Current\", EmptyList<IType>.Instance, false);\n\t\t\t\t\t\telementType = currentRR.Type;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tCheckForEnumerableInterface(expression, out collectionType, out enumeratorType, out elementType, out getEnumeratorInvocation);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tCheckForEnumerableInterface(expression, out collectionType, out enumeratorType, out elementType, out getEnumeratorInvocation);\n\t\t\t\t}\n\t\t\t}\n\t\t\tIMethod moveNextMethod = null;\n\t\t\tvar moveNextMethodGroup = memberLookup.Lookup(new ResolveResult(enumeratorType), \"MoveNext\", EmptyList<IType>.Instance, false) as MethodGroupResolveResult;\n\t\t\tif (moveNextMethodGroup != null)\n\t\t\t{\n\t\t\t\tvar or = moveNextMethodGroup.PerformOverloadResolution(\n\t\t\t\t\tcompilation, Empty<ResolveResult>.Array,\n\t\t\t\t\tallowExtensionMethods: false, allowExpandingParams: false, allowOptionalParameters: false);\n\t\t\t\tmoveNextMethod = or.GetBestCandidateWithSubstitutedTypeArguments() as IMethod;\n\t\t\t}\n\n\t\t\tif (currentRR == null)\n\t\t\t\tcurrentRR = memberLookup.Lookup(new ResolveResult(enumeratorType), \"Current\", EmptyList<IType>.Instance, false);\n\t\t\tIProperty currentProperty = null;\n\t\t\tif (currentRR is MemberResolveResult)\n\t\t\t\tcurrentProperty = ((MemberResolveResult)currentRR).Member as IProperty;\n\n\t\t\tvar voidType = compilation.FindType(KnownTypeCode.Void);\n\t\t\treturn new ForEachResolveResult(getEnumeratorInvocation, collectionType, enumeratorType, elementType,\n\t\t\t\t\t\t\t\t\t\t\tcurrentProperty, moveNextMethod, voidType);\n\t\t}\n\n\t\tvoid CheckForEnumerableInterface(ResolveResult expression, out IType collectionType, out IType enumeratorType, out IType elementType, out ResolveResult getEnumeratorInvocation)\n\t\t{\n\t\t\telementType = expression.Type.GetElementTypeFromIEnumerable(compilation, false, out bool? isGeneric);\n\t\t\tif (isGeneric == true)\n\t\t\t{\n\t\t\t\tITypeDefinition enumerableOfT = compilation.FindType(KnownTypeCode.IEnumerableOfT).GetDefinition();\n\t\t\t\tif (enumerableOfT != null)\n\t\t\t\t\tcollectionType = new ParameterizedType(enumerableOfT, new[] { elementType });\n\t\t\t\telse\n\t\t\t\t\tcollectionType = SpecialType.UnknownType;\n\n\t\t\t\tITypeDefinition enumeratorOfT = compilation.FindType(KnownTypeCode.IEnumeratorOfT).GetDefinition();\n\t\t\t\tif (enumeratorOfT != null)\n\t\t\t\t\tenumeratorType = new ParameterizedType(enumeratorOfT, new[] { elementType });\n\t\t\t\telse\n\t\t\t\t\tenumeratorType = SpecialType.UnknownType;\n\t\t\t}\n\t\t\telse if (isGeneric == false)\n\t\t\t{\n\t\t\t\tcollectionType = compilation.FindType(KnownTypeCode.IEnumerable);\n\t\t\t\tenumeratorType = compilation.FindType(KnownTypeCode.IEnumerator);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tcollectionType = SpecialType.UnknownType;\n\t\t\t\tenumeratorType = SpecialType.UnknownType;\n\t\t\t}\n\t\t\tgetEnumeratorInvocation = ResolveCast(collectionType, expression);\n\t\t\tgetEnumeratorInvocation = ResolveMemberAccess(getEnumeratorInvocation, \"GetEnumerator\", EmptyList<IType>.Instance, NameLookupMode.InvocationTarget);\n\t\t\tgetEnumeratorInvocation = ResolveInvocation(getEnumeratorInvocation, Empty<ResolveResult>.Array);\n\t\t}\n\t\t#endregion\n\n\t\t#region GetExtensionMethods\n\t\t/// <summary>\n\t\t/// Gets all extension methods that are available in the current context.\n\t\t/// </summary>\n\t\t/// <param name=\"name\">Name of the extension method. Pass null to retrieve all extension methods.</param>\n\t\t/// <param name=\"typeArguments\">Explicitly provided type arguments.\n\t\t/// An empty list will return all matching extension method definitions;\n\t\t/// a non-empty list will return <see cref=\"SpecializedMethod\"/>s for all extension methods\n\t\t/// with the matching number of type parameters.</param>\n\t\t/// <remarks>\n\t\t/// The results are stored in nested lists because they are grouped by using scope.\n\t\t/// That is, for \"using SomeExtensions; namespace X { using MoreExtensions; ... }\",\n\t\t/// the return value will be\n\t\t/// new List {\n\t\t///    new List { all extensions from MoreExtensions },\n\t\t///    new List { all extensions from SomeExtensions }\n\t\t/// }\n\t\t/// </remarks>\n\t\tpublic List<List<IMethod>> GetExtensionMethods(string name = null, IReadOnlyList<IType> typeArguments = null)\n\t\t{\n\t\t\treturn GetExtensionMethods(null, name, typeArguments);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the extension methods that are called 'name'\n\t\t/// and are applicable with a first argument type of 'targetType'.\n\t\t/// </summary>\n\t\t/// <param name=\"targetType\">Type of the 'this' argument</param>\n\t\t/// <param name=\"name\">Name of the extension method. Pass null to retrieve all extension methods.</param>\n\t\t/// <param name=\"typeArguments\">Explicitly provided type arguments.\n\t\t/// An empty list will return all matching extension method definitions;\n\t\t/// a non-empty list will return <see cref=\"SpecializedMethod\"/>s for all extension methods\n\t\t/// with the matching number of type parameters.</param>\n\t\t/// <param name=\"substituteInferredTypes\">\n\t\t/// Specifies whether to produce a <see cref=\"SpecializedMethod\"/>\n\t\t/// when type arguments could be inferred from <paramref name=\"targetType\"/>. This parameter\n\t\t/// is only used for inferred types and has no effect if <paramref name=\"typeArguments\"/> is non-empty.\n\t\t/// </param>\n\t\t/// <remarks>\n\t\t/// The results are stored in nested lists because they are grouped by using scope.\n\t\t/// That is, for \"using SomeExtensions; namespace X { using MoreExtensions; ... }\",\n\t\t/// the return value will be\n\t\t/// new List {\n\t\t///    new List { all extensions from MoreExtensions },\n\t\t///    new List { all extensions from SomeExtensions }\n\t\t/// }\n\t\t/// </remarks>\n\t\tpublic List<List<IMethod>> GetExtensionMethods(IType targetType, string name = null, IReadOnlyList<IType> typeArguments = null, bool substituteInferredTypes = false)\n\t\t{\n\t\t\tvar lookup = CreateMemberLookup();\n\t\t\tList<List<IMethod>> extensionMethodGroups = new List<List<IMethod>>();\n\t\t\tforeach (var inputGroup in GetAllExtensionMethods(lookup))\n\t\t\t{\n\t\t\t\tList<IMethod> outputGroup = new List<IMethod>();\n\t\t\t\tforeach (var method in inputGroup)\n\t\t\t\t{\n\t\t\t\t\tif (name != null && method.Name != name)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tif (!lookup.IsAccessible(method, false))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tIType[] inferredTypes;\n\t\t\t\t\tif (typeArguments != null && typeArguments.Count > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (method.TypeParameters.Count != typeArguments.Count)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tvar sm = method.Specialize(new TypeParameterSubstitution(null, typeArguments));\n\t\t\t\t\t\tif (IsEligibleExtensionMethod(compilation, conversions, targetType, sm, false, out inferredTypes))\n\t\t\t\t\t\t\toutputGroup.Add(sm);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif (IsEligibleExtensionMethod(compilation, conversions, targetType, method, true, out inferredTypes))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (substituteInferredTypes && inferredTypes != null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutputGroup.Add(method.Specialize(new TypeParameterSubstitution(null, inferredTypes)));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutputGroup.Add(method);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (outputGroup.Count > 0)\n\t\t\t\t\textensionMethodGroups.Add(outputGroup);\n\t\t\t}\n\t\t\treturn extensionMethodGroups;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Checks whether the specified extension method is eligible on the target type.\n\t\t/// </summary>\n\t\t/// <param name=\"targetType\">Target type that is passed as first argument to the extension method.</param>\n\t\t/// <param name=\"method\">The extension method.</param>\n\t\t/// <param name=\"useTypeInference\">Whether to perform type inference for the method.\n\t\t/// Use <c>false</c> if <paramref name=\"method\"/> is already parameterized (e.g. when type arguments were given explicitly).\n\t\t/// Otherwise, use <c>true</c>.\n\t\t/// </param>\n\t\t/// <param name=\"outInferredTypes\">If the method is generic and <paramref name=\"useTypeInference\"/> is <c>true</c>,\n\t\t/// and at least some of the type arguments could be inferred, this parameter receives the inferred type arguments.\n\t\t/// Since only the type for the first parameter is considered, not all type arguments may be inferred.\n\t\t/// If an array is returned, any slot with an uninferred type argument will be set to the method's\n\t\t/// corresponding type parameter.\n\t\t/// </param>\n\t\tpublic static bool IsEligibleExtensionMethod(IType targetType, IMethod method, bool useTypeInference, out IType[] outInferredTypes)\n\t\t{\n\t\t\tif (targetType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(targetType));\n\t\t\tif (method == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(method));\n\t\t\tvar compilation = method.Compilation;\n\t\t\treturn IsEligibleExtensionMethod(compilation, CSharpConversions.Get(compilation), targetType, method, useTypeInference, out outInferredTypes);\n\t\t}\n\n\t\tstatic bool IsEligibleExtensionMethod(ICompilation compilation, CSharpConversions conversions, IType targetType, IMethod method, bool useTypeInference, out IType[] outInferredTypes)\n\t\t{\n\t\t\toutInferredTypes = null;\n\t\t\tif (targetType == null)\n\t\t\t\treturn true;\n\t\t\tif (method.Parameters.Count == 0)\n\t\t\t\treturn false;\n\t\t\tIType thisParameterType = method.Parameters[0].Type;\n\t\t\tif (thisParameterType.Kind == TypeKind.ByReference)\n\t\t\t{\n\t\t\t\t// extension method with `this in` or `this ref`\n\t\t\t\tthisParameterType = ((ByReferenceType)thisParameterType).ElementType;\n\t\t\t}\n\t\t\tif (useTypeInference && method.TypeParameters.Count > 0)\n\t\t\t{\n\t\t\t\t// We need to infer type arguments from targetType:\n\t\t\t\tTypeInference ti = new TypeInference(compilation, conversions);\n\t\t\t\tResolveResult[] arguments = { new ResolveResult(targetType) };\n\t\t\t\tIType[] parameterTypes = { thisParameterType };\n\t\t\t\tvar inferredTypes = ti.InferTypeArguments(method.TypeParameters, arguments, parameterTypes, out _);\n\t\t\t\tvar substitution = new TypeParameterSubstitution(null, inferredTypes);\n\t\t\t\t// Validate that the types that could be inferred (aren't unknown) satisfy the constraints:\n\t\t\t\tbool hasInferredTypes = false;\n\t\t\t\tfor (int i = 0; i < inferredTypes.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tif (inferredTypes[i].Kind != TypeKind.Unknown && inferredTypes[i].Kind != TypeKind.UnboundTypeArgument)\n\t\t\t\t\t{\n\t\t\t\t\t\thasInferredTypes = true;\n\t\t\t\t\t\tif (!OverloadResolution.ValidateConstraints(method.TypeParameters[i], inferredTypes[i], substitution, conversions))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tinferredTypes[i] = method.TypeParameters[i]; // do not substitute types that could not be inferred\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (hasInferredTypes)\n\t\t\t\t\toutInferredTypes = inferredTypes;\n\t\t\t\tthisParameterType = thisParameterType.AcceptVisitor(substitution);\n\t\t\t}\n\t\t\tConversion c = conversions.ImplicitConversion(targetType, thisParameterType);\n\t\t\treturn c.IsValid && (c.IsIdentityConversion || c.IsReferenceConversion || c.IsBoxingConversion || c.IsImplicitSpanConversion);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets all extension methods available in the current using scope.\n\t\t/// This list includes inaccessible methods.\n\t\t/// </summary>\n\t\tIList<List<IMethod>> GetAllExtensionMethods(MemberLookup lookup)\n\t\t{\n\t\t\tvar currentUsingScope = context.CurrentUsingScope;\n\t\t\tif (currentUsingScope == null)\n\t\t\t\treturn EmptyList<List<IMethod>>.Instance;\n\t\t\tList<List<IMethod>> extensionMethodGroups = LazyInit.VolatileRead(ref currentUsingScope.AllExtensionMethods);\n\t\t\tif (extensionMethodGroups != null)\n\t\t\t{\n\t\t\t\treturn extensionMethodGroups;\n\t\t\t}\n\t\t\textensionMethodGroups = new List<List<IMethod>>();\n\t\t\tList<IMethod> m;\n\t\t\tfor (UsingScope scope = currentUsingScope; scope != null; scope = scope.Parent)\n\t\t\t{\n\t\t\t\tINamespace ns = scope.Namespace;\n\t\t\t\tif (ns != null)\n\t\t\t\t{\n\t\t\t\t\tm = GetExtensionMethods(lookup, ns).ToList();\n\t\t\t\t\tif (m.Count > 0)\n\t\t\t\t\t\textensionMethodGroups.Add(m);\n\t\t\t\t}\n\n\t\t\t\tm = scope.Usings\n\t\t\t\t\t.Distinct()\n\t\t\t\t\t.SelectMany(importedNamespace => GetExtensionMethods(lookup, importedNamespace))\n\t\t\t\t\t.ToList();\n\t\t\t\tif (m.Count > 0)\n\t\t\t\t\textensionMethodGroups.Add(m);\n\t\t\t}\n\t\t\treturn LazyInit.GetOrSet(ref currentUsingScope.AllExtensionMethods, extensionMethodGroups);\n\t\t}\n\n\t\tIEnumerable<IMethod> GetExtensionMethods(MemberLookup lookup, INamespace ns)\n\t\t{\n\t\t\t// TODO: maybe make this a property on INamespace?\n\t\t\treturn\n\t\t\t\tfrom c in ns.Types\n\t\t\t\twhere c.IsStatic && c.HasExtensions && c.TypeParameters.Count == 0 && lookup.IsAccessible(c, false)\n\t\t\t\tfrom m in c.Methods\n\t\t\t\twhere m.IsExtensionMethod\n\t\t\t\tselect m;\n\t\t}\n\t\t#endregion\n\n\t\t#region ResolveInvocation\n\n\t\tIList<ResolveResult> AddArgumentNamesIfNecessary(ResolveResult[] arguments, string[] argumentNames)\n\t\t{\n\t\t\tif (argumentNames == null)\n\t\t\t{\n\t\t\t\treturn arguments;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar result = new ResolveResult[arguments.Length];\n\t\t\t\tfor (int i = 0; i < arguments.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tresult[i] = (argumentNames[i] != null ? new NamedArgumentResolveResult(argumentNames[i], arguments[i]) : arguments[i]);\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\n\t\tprivate ResolveResult ResolveInvocation(ResolveResult target, ResolveResult[] arguments, string[] argumentNames, bool allowOptionalParameters)\n\t\t{\n\t\t\t// C# 4.0 spec: §7.6.5\n\n\t\t\tif (target.Type.Kind == TypeKind.Dynamic)\n\t\t\t{\n\t\t\t\treturn new DynamicInvocationResolveResult(target, DynamicInvocationType.Invocation, AddArgumentNamesIfNecessary(arguments, argumentNames));\n\t\t\t}\n\n\t\t\tbool isDynamic = arguments.Any(a => a.Type.Kind == TypeKind.Dynamic);\n\t\t\tMethodGroupResolveResult mgrr = target as MethodGroupResolveResult;\n\t\t\tif (mgrr != null)\n\t\t\t{\n\t\t\t\tif (isDynamic)\n\t\t\t\t{\n\t\t\t\t\t// If we have dynamic arguments, we need to represent the invocation as a dynamic invocation if there is more than one applicable method.\n\t\t\t\t\tvar or2 = CreateOverloadResolution(arguments, argumentNames, mgrr.TypeArguments.ToArray());\n\t\t\t\t\tvar applicableMethods = mgrr.MethodsGroupedByDeclaringType.SelectMany(m => m, (x, m) => new { x.DeclaringType, Method = m }).Where(x => OverloadResolution.IsApplicable(or2.AddCandidate(x.Method))).ToList();\n\n\t\t\t\t\tif (applicableMethods.Count > 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tResolveResult actualTarget;\n\t\t\t\t\t\tif (applicableMethods.All(x => x.Method.IsStatic) && !(mgrr.TargetResult is TypeResolveResult))\n\t\t\t\t\t\t\tactualTarget = new TypeResolveResult(mgrr.TargetType);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tactualTarget = mgrr.TargetResult;\n\n\t\t\t\t\t\tvar l = new List<MethodListWithDeclaringType>();\n\t\t\t\t\t\tforeach (var m in applicableMethods)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (l.Count == 0 || l[l.Count - 1].DeclaringType != m.DeclaringType)\n\t\t\t\t\t\t\t\tl.Add(new MethodListWithDeclaringType(m.DeclaringType));\n\t\t\t\t\t\t\tl[l.Count - 1].Add(m.Method);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn new DynamicInvocationResolveResult(new MethodGroupResolveResult(actualTarget, mgrr.MethodName, l, mgrr.TypeArguments), DynamicInvocationType.Invocation, AddArgumentNamesIfNecessary(arguments, argumentNames));\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tOverloadResolution or = mgrr.PerformOverloadResolution(compilation, arguments, argumentNames, checkForOverflow: checkForOverflow, conversions: conversions, allowOptionalParameters: allowOptionalParameters);\n\t\t\t\tif (or.BestCandidate != null)\n\t\t\t\t{\n\t\t\t\t\tif (or.BestCandidate.IsStatic && !or.IsExtensionMethodInvocation && !(mgrr.TargetResult is TypeResolveResult))\n\t\t\t\t\t\treturn or.CreateResolveResult(new TypeResolveResult(mgrr.TargetType), returnTypeOverride: isDynamic ? SpecialType.Dynamic : null);\n\t\t\t\t\telse\n\t\t\t\t\t\treturn or.CreateResolveResult(mgrr.TargetResult, returnTypeOverride: isDynamic ? SpecialType.Dynamic : null);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// No candidate found at all (not even an inapplicable one).\n\t\t\t\t\t// This can happen with empty method groups (as sometimes used with extension methods)\n\t\t\t\t\treturn new UnknownMethodResolveResult(\n\t\t\t\t\t\tmgrr.TargetType, mgrr.MethodName, mgrr.TypeArguments, CreateParameters(arguments, argumentNames));\n\t\t\t\t}\n\t\t\t}\n\t\t\tUnknownMemberResolveResult umrr = target as UnknownMemberResolveResult;\n\t\t\tif (umrr != null)\n\t\t\t{\n\t\t\t\treturn new UnknownMethodResolveResult(umrr.TargetType, umrr.MemberName, umrr.TypeArguments, CreateParameters(arguments, argumentNames));\n\t\t\t}\n\t\t\tUnknownIdentifierResolveResult uirr = target as UnknownIdentifierResolveResult;\n\t\t\tif (uirr != null && CurrentTypeDefinition != null)\n\t\t\t{\n\t\t\t\treturn new UnknownMethodResolveResult(CurrentTypeDefinition, uirr.Identifier, EmptyList<IType>.Instance, CreateParameters(arguments, argumentNames));\n\t\t\t}\n\t\t\tIMethod invokeMethod = target.Type.GetDelegateInvokeMethod();\n\t\t\tif (invokeMethod != null)\n\t\t\t{\n\t\t\t\tOverloadResolution or = CreateOverloadResolution(arguments, argumentNames);\n\t\t\t\tor.AddCandidate(invokeMethod);\n\t\t\t\treturn new CSharpInvocationResolveResult(\n\t\t\t\t\ttarget, invokeMethod, //invokeMethod.ReturnType.Resolve(context),\n\t\t\t\t\tor.GetArgumentsWithConversionsAndNames(), or.BestCandidateErrors,\n\t\t\t\t\tisExpandedForm: or.BestCandidateIsExpandedForm,\n\t\t\t\t\tisDelegateInvocation: true,\n\t\t\t\t\targumentToParameterMap: or.GetArgumentToParameterMap(),\n\t\t\t\t\treturnTypeOverride: isDynamic ? SpecialType.Dynamic : null);\n\t\t\t}\n\t\t\treturn ErrorResult;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Resolves an invocation.\n\t\t/// </summary>\n\t\t/// <param name=\"target\">The target of the invocation. Usually a MethodGroupResolveResult.</param>\n\t\t/// <param name=\"arguments\">\n\t\t/// Arguments passed to the method.\n\t\t/// The resolver may mutate this array to wrap elements in <see cref=\"ConversionResolveResult\"/>s!\n\t\t/// </param>\n\t\t/// <param name=\"argumentNames\">\n\t\t/// The argument names. Pass the null string for positional arguments.\n\t\t/// </param>\n\t\t/// <returns>InvocationResolveResult or UnknownMethodResolveResult</returns>\n\t\tpublic ResolveResult ResolveInvocation(ResolveResult target, ResolveResult[] arguments, string[] argumentNames = null)\n\t\t{\n\t\t\treturn ResolveInvocation(target, arguments, argumentNames, allowOptionalParameters: true);\n\t\t}\n\n\t\tList<IParameter> CreateParameters(ResolveResult[] arguments, string[] argumentNames)\n\t\t{\n\t\t\tList<IParameter> list = new List<IParameter>();\n\t\t\tif (argumentNames == null)\n\t\t\t{\n\t\t\t\targumentNames = new string[arguments.Length];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (argumentNames.Length != arguments.Length)\n\t\t\t\t\tthrow new ArgumentException();\n\t\t\t\targumentNames = (string[])argumentNames.Clone();\n\t\t\t}\n\t\t\tfor (int i = 0; i < arguments.Length; i++)\n\t\t\t{\n\t\t\t\t// invent argument names where necessary:\n\t\t\t\tif (argumentNames[i] == null)\n\t\t\t\t{\n\t\t\t\t\tstring newArgumentName = GuessParameterName(arguments[i]);\n\t\t\t\t\tif (argumentNames.Contains(newArgumentName))\n\t\t\t\t\t{\n\t\t\t\t\t\t// disambiguate argument name (e.g. add a number)\n\t\t\t\t\t\tint num = 1;\n\t\t\t\t\t\tstring newName;\n\t\t\t\t\t\tdo\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnewName = newArgumentName + num.ToString();\n\t\t\t\t\t\t\tnum++;\n\t\t\t\t\t\t} while (argumentNames.Contains(newName));\n\t\t\t\t\t\tnewArgumentName = newName;\n\t\t\t\t\t}\n\t\t\t\t\targumentNames[i] = newArgumentName;\n\t\t\t\t}\n\n\t\t\t\t// create the parameter:\n\t\t\t\tByReferenceResolveResult brrr = arguments[i] as ByReferenceResolveResult;\n\t\t\t\tif (brrr != null)\n\t\t\t\t{\n\t\t\t\t\tlist.Add(new DefaultParameter(arguments[i].Type, argumentNames[i], referenceKind: brrr.ReferenceKind));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// argument might be a lambda or delegate type, so we have to try to guess the delegate type\n\t\t\t\t\tIType type = arguments[i].Type;\n\t\t\t\t\tif (type.Kind == TypeKind.Null || type.Kind == TypeKind.None)\n\t\t\t\t\t{\n\t\t\t\t\t\tlist.Add(new DefaultParameter(compilation.FindType(KnownTypeCode.Object), argumentNames[i]));\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tlist.Add(new DefaultParameter(type, argumentNames[i]));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tstatic string GuessParameterName(ResolveResult rr)\n\t\t{\n\t\t\tMemberResolveResult mrr = rr as MemberResolveResult;\n\t\t\tif (mrr != null)\n\t\t\t\treturn mrr.Member.Name;\n\n\t\t\tUnknownMemberResolveResult umrr = rr as UnknownMemberResolveResult;\n\t\t\tif (umrr != null)\n\t\t\t\treturn umrr.MemberName;\n\n\t\t\tMethodGroupResolveResult mgrr = rr as MethodGroupResolveResult;\n\t\t\tif (mgrr != null)\n\t\t\t\treturn mgrr.MethodName;\n\n\t\t\tLocalResolveResult vrr = rr as LocalResolveResult;\n\t\t\tif (vrr != null)\n\t\t\t\treturn MakeParameterName(vrr.Variable.Name);\n\n\t\t\tif (rr.Type.Kind != TypeKind.Unknown && !string.IsNullOrEmpty(rr.Type.Name))\n\t\t\t{\n\t\t\t\treturn MakeParameterName(rr.Type.Name);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn \"parameter\";\n\t\t\t}\n\t\t}\n\n\t\tstatic string MakeParameterName(string variableName)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(variableName))\n\t\t\t\treturn \"parameter\";\n\t\t\tif (variableName.Length > 1 && variableName[0] == '_')\n\t\t\t\tvariableName = variableName.Substring(1);\n\t\t\treturn char.ToLower(variableName[0]) + variableName.Substring(1);\n\t\t}\n\n\t\tOverloadResolution CreateOverloadResolution(ResolveResult[] arguments, string[] argumentNames = null, IType[] typeArguments = null)\n\t\t{\n\t\t\tvar or = new OverloadResolution(compilation, arguments, argumentNames, typeArguments, conversions);\n\t\t\tor.CheckForOverflow = checkForOverflow;\n\t\t\treturn or;\n\t\t}\n\t\t#endregion\n\n\t\t#region ResolveIndexer\n\t\t/// <summary>\n\t\t/// Resolves an indexer access.\n\t\t/// </summary>\n\t\t/// <param name=\"target\">Target expression.</param>\n\t\t/// <param name=\"arguments\">\n\t\t/// Arguments passed to the indexer.\n\t\t/// The resolver may mutate this array to wrap elements in <see cref=\"ConversionResolveResult\"/>s!\n\t\t/// </param>\n\t\t/// <param name=\"argumentNames\">\n\t\t/// The argument names. Pass the null string for positional arguments.\n\t\t/// </param>\n\t\t/// <returns>ArrayAccessResolveResult, InvocationResolveResult, or ErrorResolveResult</returns>\n\t\tpublic ResolveResult ResolveIndexer(ResolveResult target, ResolveResult[] arguments, string[] argumentNames = null)\n\t\t{\n\t\t\tswitch (target.Type.Kind)\n\t\t\t{\n\t\t\t\tcase TypeKind.Dynamic:\n\t\t\t\t\treturn new DynamicInvocationResolveResult(target, DynamicInvocationType.Indexing, AddArgumentNamesIfNecessary(arguments, argumentNames));\n\n\t\t\t\tcase TypeKind.Array:\n\t\t\t\tcase TypeKind.Pointer:\n\t\t\t\t\t// §7.6.6.1 Array access / §18.5.3 Pointer element access\n\t\t\t\t\tAdjustArrayAccessArguments(arguments);\n\t\t\t\t\treturn new ArrayAccessResolveResult(((TypeWithElementType)target.Type).ElementType, target, arguments);\n\t\t\t}\n\n\t\t\t// §7.6.6.2 Indexer access\n\n\t\t\tMemberLookup lookup = CreateMemberLookup();\n\t\t\tvar indexers = lookup.LookupIndexers(target);\n\n\t\t\tif (arguments.Any(a => a.Type.Kind == TypeKind.Dynamic))\n\t\t\t{\n\t\t\t\t// If we have dynamic arguments, we need to represent the invocation as a dynamic invocation if there is more than one applicable indexer.\n\t\t\t\tvar or2 = CreateOverloadResolution(arguments, argumentNames, null);\n\t\t\t\tvar applicableIndexers = indexers.SelectMany(x => x).Where(m => OverloadResolution.IsApplicable(or2.AddCandidate(m))).ToList();\n\n\t\t\t\tif (applicableIndexers.Count > 1)\n\t\t\t\t{\n\t\t\t\t\treturn new DynamicInvocationResolveResult(target, DynamicInvocationType.Indexing, AddArgumentNamesIfNecessary(arguments, argumentNames));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tOverloadResolution or = CreateOverloadResolution(arguments, argumentNames);\n\t\t\tor.AddMethodLists(indexers);\n\t\t\tif (or.BestCandidate != null)\n\t\t\t{\n\t\t\t\treturn or.CreateResolveResult(target);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn ErrorResult;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts all arguments to int,uint,long or ulong.\n\t\t/// </summary>\n\t\tvoid AdjustArrayAccessArguments(ResolveResult[] arguments)\n\t\t{\n\t\t\tfor (int i = 0; i < arguments.Length; i++)\n\t\t\t{\n\t\t\t\tif (!(TryConvert(ref arguments[i], compilation.FindType(KnownTypeCode.Int32)) ||\n\t\t\t\t\t  TryConvert(ref arguments[i], compilation.FindType(KnownTypeCode.UInt32)) ||\n\t\t\t\t\t  TryConvert(ref arguments[i], compilation.FindType(KnownTypeCode.Int64)) ||\n\t\t\t\t\t  TryConvert(ref arguments[i], compilation.FindType(KnownTypeCode.UInt64))))\n\t\t\t\t{\n\t\t\t\t\t// conversion failed\n\t\t\t\t\targuments[i] = Convert(arguments[i], compilation.FindType(KnownTypeCode.Int32), Conversion.None);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region ResolveObjectCreation\n\t\t/// <summary>\n\t\t/// Resolves an object creation.\n\t\t/// </summary>\n\t\t/// <param name=\"type\">Type of the object to create.</param>\n\t\t/// <param name=\"arguments\">\n\t\t/// Arguments passed to the constructor.\n\t\t/// The resolver may mutate this array to wrap elements in <see cref=\"ConversionResolveResult\"/>s!\n\t\t/// </param>\n\t\t/// <param name=\"argumentNames\">\n\t\t/// The argument names. Pass the null string for positional arguments.\n\t\t/// </param>\n\t\t/// <param name=\"allowProtectedAccess\">\n\t\t/// Whether to allow calling protected constructors.\n\t\t/// This should be false except when resolving constructor initializers.\n\t\t/// </param>\n\t\t/// <param name=\"initializerStatements\">\n\t\t/// Statements for Objects/Collections initializer.\n\t\t/// <see cref=\"InvocationResolveResult.InitializerStatements\"/>\n\t\t/// </param>\n\t\t/// <returns>InvocationResolveResult or ErrorResolveResult</returns>\n\t\tpublic ResolveResult ResolveObjectCreation(IType type, ResolveResult[] arguments, string[] argumentNames = null, bool allowProtectedAccess = false, IList<ResolveResult> initializerStatements = null)\n\t\t{\n\t\t\tif (type.Kind == TypeKind.Delegate && arguments.Length == 1)\n\t\t\t{\n\t\t\t\tResolveResult input = arguments[0];\n\t\t\t\tIMethod invoke = input.Type.GetDelegateInvokeMethod();\n\t\t\t\tif (invoke != null)\n\t\t\t\t{\n\t\t\t\t\tinput = new MethodGroupResolveResult(\n\t\t\t\t\t\tinput, invoke.Name,\n\t\t\t\t\t\tmethods: new[] { new MethodListWithDeclaringType(input.Type) { invoke } },\n\t\t\t\t\t\ttypeArguments: EmptyList<IType>.Instance\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn Convert(input, type);\n\t\t\t}\n\t\t\tOverloadResolution or = CreateOverloadResolution(arguments, argumentNames);\n\t\t\tMemberLookup lookup = CreateMemberLookup();\n\t\t\tvar allApplicable = (arguments.Any(a => a.Type.Kind == TypeKind.Dynamic) ? new List<IMethod>() : null);\n\t\t\tforeach (IMethod ctor in type.GetConstructors())\n\t\t\t{\n\t\t\t\tif (lookup.IsAccessible(ctor, allowProtectedAccess))\n\t\t\t\t{\n\t\t\t\t\tvar orErrors = or.AddCandidate(ctor);\n\t\t\t\t\tif (allApplicable != null && OverloadResolution.IsApplicable(orErrors))\n\t\t\t\t\t\tallApplicable.Add(ctor);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tor.AddCandidate(ctor, OverloadResolutionErrors.Inaccessible);\n\t\t\t}\n\n\t\t\tif (allApplicable != null && allApplicable.Count > 1)\n\t\t\t{\n\t\t\t\t// If we have dynamic arguments, we need to represent the invocation as a dynamic invocation if there is more than one applicable constructor.\n\t\t\t\treturn new DynamicInvocationResolveResult(new MethodGroupResolveResult(null, allApplicable[0].Name, new[] { new MethodListWithDeclaringType(type, allApplicable) }, null), DynamicInvocationType.ObjectCreation, AddArgumentNamesIfNecessary(arguments, argumentNames), initializerStatements);\n\t\t\t}\n\n\t\t\tif (or.BestCandidate != null)\n\t\t\t{\n\t\t\t\treturn or.CreateResolveResult(null, initializerStatements);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new ErrorResolveResult(type);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region ResolveSizeOf\n\t\t/// <summary>\n\t\t/// Resolves 'sizeof(type)'.\n\t\t/// </summary>\n\t\tpublic ResolveResult ResolveSizeOf(IType type)\n\t\t{\n\t\t\tIType int32 = compilation.FindType(KnownTypeCode.Int32);\n\t\t\tint? size = null;\n\t\t\tvar typeForConstant = (type.Kind == TypeKind.Enum) ? type.GetDefinition().EnumUnderlyingType : type;\n\n\t\t\tswitch (ReflectionHelper.GetTypeCode(typeForConstant))\n\t\t\t{\n\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\tcase TypeCode.SByte:\n\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\tsize = 1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.Char:\n\t\t\t\tcase TypeCode.Int16:\n\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\tsize = 2;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.Int32:\n\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\tsize = 4;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeCode.Int64:\n\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\tsize = 8;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn new SizeOfResolveResult(int32, type, size);\n\t\t}\n\t\t#endregion\n\n\t\t#region Resolve This/Base Reference\n\t\t/// <summary>\n\t\t/// Resolves 'this'.\n\t\t/// </summary>\n\t\tpublic ResolveResult ResolveThisReference()\n\t\t{\n\t\t\tITypeDefinition t = CurrentTypeDefinition;\n\t\t\tif (t != null)\n\t\t\t{\n\t\t\t\tif (t.TypeParameterCount != 0)\n\t\t\t\t{\n\t\t\t\t\t// Self-parameterize the type\n\t\t\t\t\treturn new ThisResolveResult(new ParameterizedType(t, t.TypeParameters));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn new ThisResolveResult(t);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ErrorResult;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Resolves 'base'.\n\t\t/// </summary>\n\t\tpublic ResolveResult ResolveBaseReference()\n\t\t{\n\t\t\tITypeDefinition t = CurrentTypeDefinition;\n\t\t\tif (t != null)\n\t\t\t{\n\t\t\t\tforeach (IType baseType in t.DirectBaseTypes)\n\t\t\t\t{\n\t\t\t\t\tif (baseType.Kind != TypeKind.Unknown && baseType.Kind != TypeKind.Interface)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new ThisResolveResult(baseType, causesNonVirtualInvocation: true);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ErrorResult;\n\t\t}\n\t\t#endregion\n\n\t\t#region ResolveConditional\n\t\t/// <summary>\n\t\t/// Converts the input to <c>bool</c> using the rules for boolean expressions.\n\t\t/// That is, <c>operator true</c> is used if a regular conversion to <c>bool</c> is not possible.\n\t\t/// </summary>\n\t\tpublic ResolveResult ResolveCondition(ResolveResult input)\n\t\t{\n\t\t\tif (input == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(input));\n\t\t\tIType boolean = compilation.FindType(KnownTypeCode.Boolean);\n\t\t\tConversion c = conversions.ImplicitConversion(input, boolean);\n\t\t\tif (!c.IsValid)\n\t\t\t{\n\t\t\t\tvar opTrue = input.Type.GetMethods(m => m.IsOperator && m.Name == \"op_True\").FirstOrDefault();\n\t\t\t\tif (opTrue != null)\n\t\t\t\t{\n\t\t\t\t\tc = Conversion.UserDefinedConversion(opTrue, isImplicit: true, conversionBeforeUserDefinedOperator: Conversion.None, conversionAfterUserDefinedOperator: Conversion.None);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn Convert(input, boolean, c);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the negated input to <c>bool</c> using the rules for boolean expressions.\n\t\t/// Computes <c>!(bool)input</c> if the implicit cast to bool is valid; otherwise\n\t\t/// computes <c>input.operator false()</c>.\n\t\t/// </summary>\n\t\tpublic ResolveResult ResolveConditionFalse(ResolveResult input)\n\t\t{\n\t\t\tif (input == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(input));\n\t\t\tIType boolean = compilation.FindType(KnownTypeCode.Boolean);\n\t\t\tConversion c = conversions.ImplicitConversion(input, boolean);\n\t\t\tif (!c.IsValid)\n\t\t\t{\n\t\t\t\tvar opFalse = input.Type.GetMethods(m => m.IsOperator && m.Name == \"op_False\").FirstOrDefault();\n\t\t\t\tif (opFalse != null)\n\t\t\t\t{\n\t\t\t\t\tc = Conversion.UserDefinedConversion(opFalse, isImplicit: true, conversionBeforeUserDefinedOperator: Conversion.None, conversionAfterUserDefinedOperator: Conversion.None);\n\t\t\t\t\treturn Convert(input, boolean, c);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ResolveUnaryOperator(UnaryOperatorType.Not, Convert(input, boolean, c));\n\t\t}\n\n\t\tpublic ResolveResult ResolveConditional(ResolveResult condition, ResolveResult trueExpression, ResolveResult falseExpression)\n\t\t{\n\t\t\t// C# 4.0 spec §7.14: Conditional operator\n\n\t\t\tbool isValid;\n\t\t\tIType resultType;\n\t\t\tif (trueExpression.Type.Kind == TypeKind.Dynamic || falseExpression.Type.Kind == TypeKind.Dynamic)\n\t\t\t{\n\t\t\t\tresultType = SpecialType.Dynamic;\n\t\t\t\tisValid = TryConvert(ref trueExpression, resultType) & TryConvert(ref falseExpression, resultType);\n\t\t\t}\n\t\t\telse if (HasType(trueExpression) && HasType(falseExpression))\n\t\t\t{\n\t\t\t\tConversion t2f = conversions.ImplicitConversion(trueExpression, falseExpression.Type);\n\t\t\t\tConversion f2t = conversions.ImplicitConversion(falseExpression, trueExpression.Type);\n\t\t\t\t// The operator is valid:\n\t\t\t\t// a) if there's a conversion in one direction but not the other\n\t\t\t\t// b) if there are conversions in both directions, and the types are equivalent\n\t\t\t\tif (IsBetterConditionalConversion(t2f, f2t))\n\t\t\t\t{\n\t\t\t\t\tresultType = falseExpression.Type;\n\t\t\t\t\tisValid = true;\n\t\t\t\t\ttrueExpression = Convert(trueExpression, resultType, t2f);\n\t\t\t\t}\n\t\t\t\telse if (IsBetterConditionalConversion(f2t, t2f))\n\t\t\t\t{\n\t\t\t\t\tresultType = trueExpression.Type;\n\t\t\t\t\tisValid = true;\n\t\t\t\t\tfalseExpression = Convert(falseExpression, resultType, f2t);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tresultType = trueExpression.Type;\n\t\t\t\t\tisValid = trueExpression.Type.Equals(falseExpression.Type);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (HasType(trueExpression))\n\t\t\t{\n\t\t\t\tresultType = trueExpression.Type;\n\t\t\t\tisValid = TryConvert(ref falseExpression, resultType);\n\t\t\t}\n\t\t\telse if (HasType(falseExpression))\n\t\t\t{\n\t\t\t\tresultType = falseExpression.Type;\n\t\t\t\tisValid = TryConvert(ref trueExpression, resultType);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn ErrorResult;\n\t\t\t}\n\t\t\tcondition = ResolveCondition(condition);\n\t\t\tif (isValid)\n\t\t\t{\n\t\t\t\tif (condition.IsCompileTimeConstant && trueExpression.IsCompileTimeConstant && falseExpression.IsCompileTimeConstant)\n\t\t\t\t{\n\t\t\t\t\tbool? val = condition.ConstantValue as bool?;\n\t\t\t\t\tif (val == true)\n\t\t\t\t\t\treturn trueExpression;\n\t\t\t\t\telse if (val == false)\n\t\t\t\t\t\treturn falseExpression;\n\t\t\t\t}\n\t\t\t\treturn new OperatorResolveResult(resultType, System.Linq.Expressions.ExpressionType.Conditional,\n\t\t\t\t\t\t\t\t\t\t\t\t condition, trueExpression, falseExpression);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new ErrorResolveResult(resultType);\n\t\t\t}\n\t\t}\n\n\t\tbool IsBetterConditionalConversion(Conversion c1, Conversion c2)\n\t\t{\n\t\t\t// Valid is better than ImplicitConstantExpressionConversion is better than invalid\n\t\t\tif (!c1.IsValid)\n\t\t\t\treturn false;\n\t\t\tif (c1 != Conversion.ImplicitConstantExpressionConversion && c2 == Conversion.ImplicitConstantExpressionConversion)\n\t\t\t\treturn true;\n\t\t\treturn !c2.IsValid;\n\t\t}\n\n\t\tbool HasType(ResolveResult r)\n\t\t{\n\t\t\treturn r.Type.Kind != TypeKind.None && r.Type.Kind != TypeKind.Null;\n\t\t}\n\t\t#endregion\n\n\t\t#region ResolvePrimitive\n\t\tpublic ResolveResult ResolvePrimitive(object value)\n\t\t{\n\t\t\tif (value == null)\n\t\t\t{\n\t\t\t\treturn new ResolveResult(SpecialType.NullType);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tTypeCode typeCode = Type.GetTypeCode(value.GetType());\n\t\t\t\tIType type = compilation.FindType(typeCode);\n\t\t\t\treturn new ConstantResolveResult(type, value);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region ResolveDefaultValue\n\t\tpublic ResolveResult ResolveDefaultValue(IType type)\n\t\t{\n\t\t\treturn new ConstantResolveResult(type, GetDefaultValue(type));\n\t\t}\n\n\t\tpublic static object GetDefaultValue(IType type)\n\t\t{\n\t\t\tITypeDefinition typeDef = type.GetDefinition();\n\t\t\tif (typeDef == null)\n\t\t\t\treturn null;\n\t\t\tif (typeDef.Kind == TypeKind.Enum)\n\t\t\t{\n\t\t\t\ttypeDef = typeDef.EnumUnderlyingType.GetDefinition();\n\t\t\t\tif (typeDef == null)\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t\tswitch (typeDef.KnownTypeCode)\n\t\t\t{\n\t\t\t\tcase KnownTypeCode.Boolean:\n\t\t\t\t\treturn false;\n\t\t\t\tcase KnownTypeCode.Char:\n\t\t\t\t\treturn '\\0';\n\t\t\t\tcase KnownTypeCode.SByte:\n\t\t\t\t\treturn (sbyte)0;\n\t\t\t\tcase KnownTypeCode.Byte:\n\t\t\t\t\treturn (byte)0;\n\t\t\t\tcase KnownTypeCode.Int16:\n\t\t\t\t\treturn (short)0;\n\t\t\t\tcase KnownTypeCode.UInt16:\n\t\t\t\t\treturn (ushort)0;\n\t\t\t\tcase KnownTypeCode.Int32:\n\t\t\t\t\treturn 0;\n\t\t\t\tcase KnownTypeCode.UInt32:\n\t\t\t\t\treturn 0U;\n\t\t\t\tcase KnownTypeCode.Int64:\n\t\t\t\t\treturn 0L;\n\t\t\t\tcase KnownTypeCode.UInt64:\n\t\t\t\t\treturn 0UL;\n\t\t\t\tcase KnownTypeCode.Single:\n\t\t\t\t\treturn 0f;\n\t\t\t\tcase KnownTypeCode.Double:\n\t\t\t\t\treturn 0.0;\n\t\t\t\tcase KnownTypeCode.Decimal:\n\t\t\t\t\treturn 0m;\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region ResolveArrayCreation\n\t\t/// <summary>\n\t\t/// Resolves an array creation.\n\t\t/// </summary>\n\t\t/// <param name=\"elementType\">\n\t\t/// The array element type.\n\t\t/// Pass null to resolve an implicitly-typed array creation.\n\t\t/// </param>\n\t\t/// <param name=\"sizeArguments\">\n\t\t/// The size arguments.\n\t\t/// The length of this array will be used as the number of dimensions of the array type.\n\t\t/// Negative values will be treated as errors.\n\t\t/// </param>\n\t\t/// <param name=\"initializerElements\">\n\t\t/// The initializer elements. May be null if no array initializer was specified.\n\t\t/// The resolver may mutate this array to wrap elements in <see cref=\"ConversionResolveResult\"/>s!\n\t\t/// </param>\n\t\tpublic ArrayCreateResolveResult ResolveArrayCreation(IType elementType, int[] sizeArguments, ResolveResult[] initializerElements = null)\n\t\t{\n\t\t\tResolveResult[] sizeArgResults = new ResolveResult[sizeArguments.Length];\n\t\t\tfor (int i = 0; i < sizeArguments.Length; i++)\n\t\t\t{\n\t\t\t\tif (sizeArguments[i] < 0)\n\t\t\t\t\tsizeArgResults[i] = ErrorResolveResult.UnknownError;\n\t\t\t\telse\n\t\t\t\t\tsizeArgResults[i] = new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), sizeArguments[i]);\n\t\t\t}\n\t\t\treturn ResolveArrayCreation(elementType, sizeArgResults, initializerElements);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Resolves an array creation.\n\t\t/// </summary>\n\t\t/// <param name=\"elementType\">\n\t\t/// The array element type.\n\t\t/// Pass null to resolve an implicitly-typed array creation.\n\t\t/// </param>\n\t\t/// <param name=\"sizeArguments\">\n\t\t/// The size arguments.\n\t\t/// The length of this array will be used as the number of dimensions of the array type.\n\t\t/// The resolver may mutate this array to wrap elements in <see cref=\"ConversionResolveResult\"/>s!\n\t\t/// </param>\n\t\t/// <param name=\"initializerElements\">\n\t\t/// The initializer elements. May be null if no array initializer was specified.\n\t\t/// The resolver may mutate this array to wrap elements in <see cref=\"ConversionResolveResult\"/>s!\n\t\t/// </param>\n\t\tpublic ArrayCreateResolveResult ResolveArrayCreation(IType elementType, ResolveResult[] sizeArguments, ResolveResult[] initializerElements = null)\n\t\t{\n\t\t\tint dimensions = sizeArguments.Length;\n\t\t\tif (dimensions == 0)\n\t\t\t\tthrow new ArgumentException(\"sizeArguments.Length must not be 0\");\n\t\t\tif (elementType == null)\n\t\t\t{\n\t\t\t\tTypeInference typeInference = new TypeInference(compilation, conversions);\n\t\t\t\telementType = typeInference.GetBestCommonType(initializerElements, out _);\n\t\t\t}\n\t\t\tIType arrayType = new ArrayType(compilation, elementType, dimensions);\n\n\t\t\tAdjustArrayAccessArguments(sizeArguments);\n\n\t\t\tif (initializerElements != null)\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < initializerElements.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tinitializerElements[i] = Convert(initializerElements[i], elementType);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn new ArrayCreateResolveResult(arrayType, sizeArguments, initializerElements);\n\t\t}\n\t\t#endregion\n\n\t\tpublic ResolveResult ResolveTypeOf(IType referencedType)\n\t\t{\n\t\t\treturn new TypeOfResolveResult(compilation.FindType(KnownTypeCode.Type), referencedType);\n\t\t}\n\n\t\t#region ResolveAssignment\n\t\tpublic ResolveResult ResolveAssignment(AssignmentOperatorType op, ResolveResult lhs, ResolveResult rhs)\n\t\t{\n\t\t\tvar linqOp = AssignmentExpression.GetLinqNodeType(op, this.CheckForOverflow);\n\t\t\tvar bop = AssignmentExpression.GetCorrespondingBinaryOperator(op);\n\t\t\tif (bop == null)\n\t\t\t{\n\t\t\t\treturn new OperatorResolveResult(lhs.Type, linqOp, lhs, this.Convert(rhs, lhs.Type));\n\t\t\t}\n\t\t\tResolveResult bopResult = ResolveBinaryOperator(bop.Value, lhs, rhs);\n\t\t\tOperatorResolveResult opResult = bopResult as OperatorResolveResult;\n\t\t\tif (opResult == null || opResult.Operands.Count != 2)\n\t\t\t\treturn bopResult;\n\t\t\treturn new OperatorResolveResult(lhs.Type, linqOp, opResult.UserDefinedOperatorMethod, opResult.IsLiftedOperator,\n\t\t\t\t\t\t\t\t\t\t\t new[] { lhs, opResult.Operands[1] });\n\t\t}\n\t\t#endregion\n\n\t\t#region CanTransformToExtensionMethodCall\n\t\tpublic bool CanTransformToExtensionMethodCall(IMethod method,\n\tIReadOnlyList<IType> typeArguments, ResolveResult target, ResolveResult[] arguments, string[] argumentNames)\n\t\t{\n\t\t\tif (target is LambdaResolveResult)\n\t\t\t\treturn false;\n\t\t\tvar rr = ResolveMemberAccess(target, method.Name, typeArguments, NameLookupMode.InvocationTarget) as MethodGroupResolveResult;\n\t\t\tif (rr == null)\n\t\t\t\treturn false;\n\t\t\tvar or = rr.PerformOverloadResolution(CurrentTypeResolveContext.Compilation, arguments, argumentNames, allowExtensionMethods: true);\n\t\t\tif (or == null || or.IsAmbiguous)\n\t\t\t\treturn false;\n\t\t\treturn method.Equals(or.GetBestCandidateWithSubstitutedTypeArguments())\n\t\t\t\t&& CSharpResolver.IsEligibleExtensionMethod(target.Type, method, useTypeInference: false, out _);\n\t\t}\n\n\t\tpublic bool CanTransformToExtensionMethodCall(IMethod method, bool ignoreTypeArguments = false, bool ignoreArgumentNames = true)\n\t\t{\n\t\t\tif (method.Parameters.Count == 0)\n\t\t\t\treturn false;\n\t\t\tvar targetType = method.Parameters.Select(p => new ResolveResult(p.Type)).First();\n\t\t\tvar paramTypes = method.Parameters.Skip(1).Select(p => new ResolveResult(p.Type)).ToArray();\n\t\t\tvar paramNames = ignoreArgumentNames ? null : method.Parameters.SelectReadOnlyArray(p => p.Name);\n\t\t\tvar typeArgs = ignoreTypeArguments ? Empty<IType>.Array : method.TypeArguments.ToArray();\n\t\t\treturn CanTransformToExtensionMethodCall(method, typeArgs, targetType, paramTypes, argumentNames: paramNames);\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Resolver/DynamicInvocationResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Globalization;\n\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp.Resolver\n{\n\tpublic enum DynamicInvocationType\n\t{\n\t\t/// <summary>\n\t\t/// The invocation is a normal invocation ( 'a(b)' ).\n\t\t/// </summary>\n\t\tInvocation,\n\n\t\t/// <summary>\n\t\t/// The invocation is an indexing ( 'a[b]' ).\n\t\t/// </summary>\n\t\tIndexing,\n\n\t\t/// <summary>\n\t\t/// The invocation is an object creation ( 'new a(b)' ).\n\t\t/// </summary>\n\t\tObjectCreation,\n\t}\n\n\t/// <summary>\n\t/// Represents the result of an invocation of a member of a dynamic object.\n\t/// </summary>\n\tpublic class DynamicInvocationResolveResult : ResolveResult\n\t{\n\t\t/// <summary>\n\t\t/// Target of the invocation. Can be a dynamic expression or a <see cref=\"MethodGroupResolveResult\"/>.\n\t\t/// </summary>\n\t\tpublic readonly ResolveResult Target;\n\n\t\t/// <summary>\n\t\t/// Type of the invocation.\n\t\t/// </summary>\n\t\tpublic readonly DynamicInvocationType InvocationType;\n\n\t\t/// <summary>\n\t\t/// Arguments for the call. Named arguments will be instances of <see cref=\"NamedArgumentResolveResult\"/>.\n\t\t/// </summary>\n\t\tpublic readonly IList<ResolveResult> Arguments;\n\n\t\t/// <summary>\n\t\t/// Gets the list of initializer statements that are appplied to the result of this invocation.\n\t\t/// This is used to represent object and collection initializers.\n\t\t/// With the initializer statements, the <see cref=\"InitializedObjectResolveResult\"/> is used\n\t\t/// to refer to the result of this invocation.\n\t\t/// Initializer statements can only exist if the <see cref=\"InvocationType\"/> is <see cref=\"DynamicInvocationType.ObjectCreation\"/>.\n\t\t/// </summary>\n\t\tpublic readonly IList<ResolveResult> InitializerStatements;\n\n\t\tpublic DynamicInvocationResolveResult(ResolveResult target, DynamicInvocationType invocationType, IList<ResolveResult> arguments, IList<ResolveResult> initializerStatements = null) : base(SpecialType.Dynamic)\n\t\t{\n\t\t\tthis.Target = target;\n\t\t\tthis.InvocationType = invocationType;\n\t\t\tthis.Arguments = arguments ?? EmptyList<ResolveResult>.Instance;\n\t\t\tthis.InitializerStatements = initializerStatements ?? EmptyList<ResolveResult>.Instance;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(CultureInfo.InvariantCulture, \"[Dynamic invocation ]\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Resolver/DynamicMemberResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Globalization;\n\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Resolver\n{\n\t/// <summary>\n\t/// Represents the result of an access to a member of a dynamic object.\n\t/// </summary>\n\tpublic class DynamicMemberResolveResult : ResolveResult\n\t{\n\t\t/// <summary>\n\t\t/// Target of the member access (a dynamic object).\n\t\t/// </summary>\n\t\tpublic readonly ResolveResult Target;\n\n\t\t/// <summary>\n\t\t/// Name of the accessed member.\n\t\t/// </summary>\n\t\tpublic readonly string Member;\n\n\t\tpublic DynamicMemberResolveResult(ResolveResult target, string member) : base(SpecialType.Dynamic)\n\t\t{\n\t\t\tthis.Target = target;\n\t\t\tthis.Member = member;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(CultureInfo.InvariantCulture, \"[Dynamic member '{0}']\", Member);\n\t\t}\n\n\t\tpublic override IEnumerable<ResolveResult> GetChildResults()\n\t\t{\n\t\t\treturn new[] { Target };\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Resolver/LambdaResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Resolver\n{\n\t/// <summary>\n\t/// Represents an anonymous method or lambda expression.\n\t/// Note: the lambda has no type.\n\t/// To retrieve the delegate type, look at the anonymous function conversion.\n\t/// </summary>\n\tpublic abstract class LambdaResolveResult : ResolveResult\n\t{\n\t\tprotected LambdaResolveResult() : base(SpecialType.NoType)\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether there is a parameter list.\n\t\t/// This property always returns true for C# 3.0-lambdas, but may return false\n\t\t/// for C# 2.0 anonymous methods.\n\t\t/// </summary>\n\t\tpublic abstract bool HasParameterList { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether this lambda is using the C# 2.0 anonymous method syntax.\n\t\t/// </summary>\n\t\tpublic abstract bool IsAnonymousMethod { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether the lambda parameters are implicitly typed.\n\t\t/// </summary>\n\t\t/// <remarks>This property returns false for anonymous methods without parameter list.</remarks>\n\t\tpublic abstract bool IsImplicitlyTyped { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether the lambda is async.\n\t\t/// </summary>\n\t\tpublic abstract bool IsAsync { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the return type inferred when the parameter types are inferred to be <paramref name=\"parameterTypes\"/>\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This method determines the return type inferred from the lambda body, which is used as part of C# type inference.\n\t\t/// Use the <see cref=\"ReturnType\"/> property to retrieve the actual return type as determined by the target delegate type.\n\t\t/// </remarks>\n\t\tpublic abstract IType GetInferredReturnType(IType[] parameterTypes);\n\n\t\t/// <summary>\n\t\t/// Gets the list of parameters.\n\t\t/// </summary>\n\t\tpublic abstract IReadOnlyList<IParameter> Parameters { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the return type of the lambda.\n\t\t/// \n\t\t/// If the lambda is async, the return type includes <code>Task&lt;T&gt;</code>\n\t\t/// </summary>\n\t\tpublic abstract IType ReturnType { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether the lambda body is valid for the given parameter types and return type.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// Produces a conversion with <see cref=\"Conversion.IsAnonymousFunctionConversion\"/>=<c>true</c> if the lambda is valid;\n\t\t/// otherwise returns <see cref=\"Conversion.None\"/>.\n\t\t/// </returns>\n\t\tpublic abstract Conversion IsValid(IType[] parameterTypes, IType returnType, CSharpConversions conversions);\n\n\t\t/// <summary>\n\t\t/// Gets the resolve result for the lambda body.\n\t\t/// Returns a resolve result for 'void' for statement lambdas.\n\t\t/// </summary>\n\t\tpublic abstract ResolveResult Body { get; }\n\n\t\tpublic override IEnumerable<ResolveResult> GetChildResults()\n\t\t{\n\t\t\treturn new[] { this.Body };\n\t\t}\n\t}\n\n\tsealed class DecompiledLambdaResolveResult : LambdaResolveResult\n\t{\n\t\treadonly IL.ILFunction function;\n\t\tpublic readonly IType DelegateType;\n\n\t\t/// <summary>\n\t\t/// The inferred return type.\n\t\t/// Can differ from <c>ReturnType</c> if a return statement\n\t\t/// performs an implicit conversion.\n\t\t/// </summary>\n\t\tpublic IType InferredReturnType;\n\n\t\tpublic DecompiledLambdaResolveResult(IL.ILFunction function,\n\t\t\tIType delegateType,\n\t\t\tIType inferredReturnType,\n\t\t\tbool hasParameterList,\n\t\t\tbool isAnonymousMethod,\n\t\t\tbool isImplicitlyTyped)\n\t\t{\n\t\t\tthis.function = function ?? throw new ArgumentNullException(nameof(function));\n\t\t\tthis.DelegateType = delegateType ?? throw new ArgumentNullException(nameof(delegateType));\n\t\t\tthis.InferredReturnType = inferredReturnType ?? throw new ArgumentNullException(nameof(inferredReturnType));\n\t\t\tthis.HasParameterList = hasParameterList;\n\t\t\tthis.IsAnonymousMethod = isAnonymousMethod;\n\t\t\tthis.IsImplicitlyTyped = isImplicitlyTyped;\n\t\t\tthis.Body = new ResolveResult(SpecialType.UnknownType);\n\t\t}\n\n\t\tpublic override bool HasParameterList { get; }\n\t\tpublic override bool IsAnonymousMethod { get; }\n\t\tpublic override bool IsImplicitlyTyped { get; }\n\t\tpublic override bool IsAsync => function.IsAsync;\n\n\t\tpublic override IReadOnlyList<IParameter> Parameters => function.Parameters;\n\t\tpublic override IType ReturnType => function.ReturnType;\n\n\t\tpublic override ResolveResult Body { get; }\n\n\t\tpublic override IType GetInferredReturnType(IType[] parameterTypes)\n\t\t{\n\t\t\t// We don't know how to compute which type would be inferred if\n\t\t\t// given other parameter types.\n\t\t\t// Let's hope this is good enough:\n\t\t\treturn InferredReturnType;\n\t\t}\n\n\t\tpublic override Conversion IsValid(IType[] parameterTypes, IType returnType, CSharpConversions conversions)\n\t\t{\n\t\t\t// Anonymous method expressions without parameter lists are applicable to any parameter list.\n\t\t\tif (HasParameterList)\n\t\t\t{\n\t\t\t\tif (this.Parameters.Count != parameterTypes.Length)\n\t\t\t\t\treturn Conversion.None;\n\t\t\t\tfor (int i = 0; i < parameterTypes.Length; ++i)\n\t\t\t\t{\n\t\t\t\t\tif (!conversions.IdentityConversion(parameterTypes[i], this.Parameters[i].Type))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (IsImplicitlyTyped)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// it's possible that different parameter types also lead to a valid conversion\n\t\t\t\t\t\t\treturn LambdaConversion.Instance;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn Conversion.None;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (conversions.IdentityConversion(this.ReturnType, returnType)\n\t\t\t\t|| conversions.ImplicitConversion(this.InferredReturnType, returnType).IsValid)\n\t\t\t{\n\t\t\t\treturn LambdaConversion.Instance;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn Conversion.None;\n\t\t\t}\n\t\t}\n\t}\n\n\tclass LambdaConversion : Conversion\n\t{\n\t\tpublic static readonly LambdaConversion Instance = new LambdaConversion();\n\n\t\tpublic override bool IsAnonymousFunctionConversion => true;\n\t\tpublic override bool IsImplicit => true;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Resolver/Log.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nnamespace ICSharpCode.Decompiler.CSharp.Resolver\n{\n\t/// <summary>\n\t/// Resolver logging helper.\n\t/// Wraps System.Diagnostics.Debug so that resolver-specific logging can be enabled/disabled on demand.\n\t/// (it's a huge amount of debug spew and slows down the resolver quite a bit)\n\t/// </summary>\n\tstatic class Log\n\t{\n\t\tconst bool logEnabled = false;\n#if __MonoCS__\n\t\t[Conditional(\"MCS_DEBUG\")]\n#else\n\t\t[Conditional(logEnabled ? \"DEBUG\" : \"LOG_DISABLED\")]\n#endif\n\t\tinternal static void WriteLine(string text)\n\t\t{\n\t\t\tDebug.WriteLine(text);\n\t\t}\n\n#if __MonoCS__\n\t\t[Conditional(\"MCS_DEBUG\")]\n#else\n\t\t[Conditional(logEnabled ? \"DEBUG\" : \"LOG_DISABLED\")]\n#endif\n\t\tinternal static void WriteLine(string format, params object[] args)\n\t\t{\n\t\t\tDebug.WriteLine(format, args);\n\t\t}\n\n#if __MonoCS__\n\t\t[Conditional(\"MCS_DEBUG\")]\n#else\n\t\t[Conditional(logEnabled ? \"DEBUG\" : \"LOG_DISABLED\")]\n#endif\n\t\tinternal static void WriteCollection<T>(string text, IEnumerable<T> lines)\n\t\t{\n#if DEBUG\n\t\t\tT[] arr = lines.ToArray();\n\t\t\tif (arr.Length == 0)\n\t\t\t{\n\t\t\t\tDebug.WriteLine(text + \"<empty collection>\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDebug.WriteLine(text + (arr[0] != null ? arr[0].ToString() : \"<null>\"));\n\t\t\t\tfor (int i = 1; i < arr.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tDebug.WriteLine(new string(' ', text.Length) + (arr[i] != null ? arr[i].ToString() : \"<null>\"));\n\t\t\t\t}\n\t\t\t}\n#endif\n\t\t}\n\n#if __MonoCS__\n\t\t[Conditional(\"MCS_DEBUG\")]\n#else\n\t\t[Conditional(logEnabled ? \"DEBUG\" : \"LOG_DISABLED\")]\n#endif\n\t\tpublic static void Indent()\n\t\t{\n\t\t\tDebug.Indent();\n\t\t}\n\n#if __MonoCS__\n\t\t[Conditional(\"MCS_DEBUG\")]\n#else\n\t\t[Conditional(logEnabled ? \"DEBUG\" : \"LOG_DISABLED\")]\n#endif\n\t\tpublic static void Unindent()\n\t\t{\n\t\t\tDebug.Unindent();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Resolver/MemberLookup.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Resolver\n{\n\t/// <summary>\n\t/// Implementation of member lookup (C# 4.0 spec, §7.4).\n\t/// </summary>\n\tpublic class MemberLookup\n\t{\n\t\t#region Static helper methods\n\t\t/// <summary>\n\t\t/// Gets whether the member is considered to be invocable.\n\t\t/// </summary>\n\t\tpublic static bool IsInvocable(IMember member)\n\t\t{\n\t\t\tif (member == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(member));\n\t\t\t// C# 4.0 spec, §7.4 member lookup\n\t\t\tif (member is IEvent || member is IMethod)\n\t\t\t\treturn true;\n\t\t\tIType returnType = member.ReturnType;\n\t\t\treturn returnType.Kind == TypeKind.Dynamic || returnType.Kind == TypeKind.Delegate\n\t\t\t\t|| returnType.Kind == TypeKind.FunctionPointer;\n\t\t}\n\t\t#endregion\n\n\t\treadonly ITypeDefinition currentTypeDefinition;\n\t\treadonly IModule currentModule;\n\t\treadonly bool isInEnumMemberInitializer;\n\n\t\tpublic MemberLookup(ITypeDefinition currentTypeDefinition, IModule currentModule, bool isInEnumMemberInitializer = false)\n\t\t{\n\t\t\tthis.currentTypeDefinition = currentTypeDefinition;\n\t\t\tthis.currentModule = currentModule;\n\t\t\tthis.isInEnumMemberInitializer = isInEnumMemberInitializer;\n\t\t}\n\n\t\t#region IsAccessible\n\t\t/// <summary>\n\t\t/// Gets whether access to protected instance members of the target expression is possible.\n\t\t/// </summary>\n\t\tpublic bool IsProtectedAccessAllowed(ResolveResult targetResolveResult)\n\t\t{\n\t\t\treturn targetResolveResult is ThisResolveResult || IsProtectedAccessAllowed(targetResolveResult.Type);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether access to protected instance members of the target type is possible.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This method does not consider the special case of the 'base' reference. If possible, use the\n\t\t/// <c>IsProtectedAccessAllowed(ResolveResult)</c> overload instead.\n\t\t/// </remarks>\n\t\tpublic bool IsProtectedAccessAllowed(IType targetType)\n\t\t{\n\t\t\tif (targetType.Kind == TypeKind.TypeParameter)\n\t\t\t\ttargetType = ((ITypeParameter)targetType).EffectiveBaseClass;\n\t\t\tITypeDefinition typeDef = targetType.GetDefinition();\n\t\t\tif (typeDef == null)\n\t\t\t\treturn false;\n\t\t\tfor (ITypeDefinition c = currentTypeDefinition; c != null; c = c.DeclaringTypeDefinition)\n\t\t\t{\n\t\t\t\tif (typeDef.IsDerivedFrom(c))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether <paramref name=\"entity\"/> is accessible in the current class.\n\t\t/// </summary>\n\t\t/// <param name=\"entity\">The entity to test</param>\n\t\t/// <param name=\"allowProtectedAccess\">\n\t\t/// Whether protected access to instance members is allowed.\n\t\t/// True if the type of the reference is derived from the current class.\n\t\t/// Protected static members may be accessible even if false is passed for this parameter.\n\t\t/// </param>\n\t\tpublic bool IsAccessible(IEntity entity, bool allowProtectedAccess)\n\t\t{\n\t\t\tif (entity == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(entity));\n\t\t\t// C# 4.0 spec, §3.5.2 Accessiblity domains\n\t\t\tswitch (entity.Accessibility)\n\t\t\t{\n\t\t\t\tcase Accessibility.None:\n\t\t\t\t\treturn false;\n\t\t\t\tcase Accessibility.Private:\n\t\t\t\t\t// check for members of outer classes (private members of outer classes can be accessed)\n\t\t\t\t\tfor (var t = currentTypeDefinition; t != null; t = t.DeclaringTypeDefinition)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (t.Equals(entity.DeclaringTypeDefinition))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\tcase Accessibility.Public:\n\t\t\t\t\treturn true;\n\t\t\t\tcase Accessibility.Protected:\n\t\t\t\t\treturn IsProtectedAccessible(allowProtectedAccess, entity);\n\t\t\t\tcase Accessibility.Internal:\n\t\t\t\t\treturn IsInternalAccessible(entity.ParentModule);\n\t\t\t\tcase Accessibility.ProtectedOrInternal:\n\t\t\t\t\treturn IsInternalAccessible(entity.ParentModule) || IsProtectedAccessible(allowProtectedAccess, entity);\n\t\t\t\tcase Accessibility.ProtectedAndInternal:\n\t\t\t\t\treturn IsInternalAccessible(entity.ParentModule) && IsProtectedAccessible(allowProtectedAccess, entity);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Exception(\"Invalid value for Accessibility\");\n\t\t\t}\n\t\t}\n\n\t\tbool IsInternalAccessible(IModule module)\n\t\t{\n\t\t\treturn module != null && currentModule != null && module.InternalsVisibleTo(currentModule);\n\t\t}\n\n\t\tbool IsProtectedAccessible(bool allowProtectedAccess, IEntity entity)\n\t\t{\n\t\t\t// For static members and type definitions, we do not require the qualifying reference\n\t\t\t// to be derived from the current class (allowProtectedAccess).\n\t\t\tif (entity.IsStatic || entity.SymbolKind == SymbolKind.TypeDefinition)\n\t\t\t\tallowProtectedAccess = true;\n\n\t\t\tfor (var t = currentTypeDefinition; t != null; t = t.DeclaringTypeDefinition)\n\t\t\t{\n\t\t\t\tif (t.Equals(entity.DeclaringTypeDefinition))\n\t\t\t\t\treturn true;\n\n\t\t\t\t// PERF: this might hurt performance as this method is called several times (once for each member)\n\t\t\t\t// make sure resolving base types is cheap (caches?) or cache within the MemberLookup instance\n\t\t\t\tif (allowProtectedAccess && t.IsDerivedFrom(entity.DeclaringTypeDefinition))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\t#endregion\n\n\t\t#region GetAccessibleMembers\n\t\t/// <summary>\n\t\t/// Retrieves all members that are accessible and not hidden (by being overridden or shadowed).\n\t\t/// Returns both members and nested type definitions. Does not include extension methods.\n\t\t/// </summary>\n\t\tpublic IEnumerable<IEntity> GetAccessibleMembers(ResolveResult targetResolveResult)\n\t\t{\n\t\t\tif (targetResolveResult == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(targetResolveResult));\n\n\t\t\tbool targetIsTypeParameter = targetResolveResult.Type.Kind == TypeKind.TypeParameter;\n\t\t\tbool allowProtectedAccess = IsProtectedAccessAllowed(targetResolveResult);\n\n\t\t\t// maps the member name to the list of lookup groups\n\t\t\tvar lookupGroupDict = new Dictionary<string, List<LookupGroup>>();\n\n\t\t\t// This loop will handle base types before derived types.\n\t\t\t// The loop performs three jobs:\n\t\t\t// 1) It marks entries in lookup groups from base classes as removed when those members\n\t\t\t//    are hidden by a derived class.\n\t\t\t// 2) It adds a new lookup group with the members from a declaring type.\n\t\t\t// 3) It replaces virtual members with the overridden version, placing the override in the\n\t\t\t//    lookup group belonging to the base class.\n\t\t\tforeach (IType type in targetResolveResult.Type.GetNonInterfaceBaseTypes())\n\t\t\t{\n\n\t\t\t\tList<IEntity> entities = new List<IEntity>();\n\t\t\t\tentities.AddRange(type.GetMembers(options: GetMemberOptions.IgnoreInheritedMembers));\n\t\t\t\tif (!targetIsTypeParameter)\n\t\t\t\t{\n\t\t\t\t\tvar nestedTypes = type.GetNestedTypes(options: GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions);\n\t\t\t\t\t// GetDefinition() might return null if some IType has a strange implementation of GetNestedTypes.\n\t\t\t\t\tentities.AddRange(nestedTypes.Select(t => t.GetDefinition()).Where(td => td != null));\n\t\t\t\t}\n\n\t\t\t\tforeach (var entityGroup in entities.GroupBy(e => e.Name))\n\t\t\t\t{\n\n\t\t\t\t\tList<LookupGroup> lookupGroups = new List<LookupGroup>();\n\t\t\t\t\tif (!lookupGroupDict.TryGetValue(entityGroup.Key, out lookupGroups))\n\t\t\t\t\t\tlookupGroupDict.Add(entityGroup.Key, lookupGroups = new List<LookupGroup>());\n\n\t\t\t\t\tList<IType> newNestedTypes = null;\n\t\t\t\t\tList<IParameterizedMember> newMethods = null;\n\t\t\t\t\tIMember newNonMethod = null;\n\n\t\t\t\t\tIEnumerable<IType> typeBaseTypes = null;\n\n\t\t\t\t\tif (!targetIsTypeParameter)\n\t\t\t\t\t{\n\t\t\t\t\t\tAddNestedTypes(type, entityGroup.OfType<IType>(), 0, lookupGroups, ref typeBaseTypes, ref newNestedTypes);\n\t\t\t\t\t}\n\t\t\t\t\tAddMembers(type, entityGroup.OfType<IMember>(), allowProtectedAccess, lookupGroups, false, ref typeBaseTypes, ref newMethods, ref newNonMethod);\n\n\t\t\t\t\tif (newNestedTypes != null || newMethods != null || newNonMethod != null)\n\t\t\t\t\t\tlookupGroups.Add(new LookupGroup(type, newNestedTypes, newMethods, newNonMethod));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach (List<LookupGroup> lookupGroups in lookupGroupDict.Values)\n\t\t\t{\n\t\t\t\t// Remove interface members hidden by class members.\n\t\t\t\tif (targetIsTypeParameter)\n\t\t\t\t{\n\t\t\t\t\t// This can happen only with type parameters.\n\t\t\t\t\tRemoveInterfaceMembersHiddenByClassMembers(lookupGroups);\n\t\t\t\t}\n\n\t\t\t\t// Now report the results:\n\t\t\t\tforeach (LookupGroup lookupGroup in lookupGroups)\n\t\t\t\t{\n\t\t\t\t\tif (!lookupGroup.MethodsAreHidden)\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (IMethod method in lookupGroup.Methods)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tyield return method;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (!lookupGroup.NonMethodIsHidden)\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return lookupGroup.NonMethod;\n\t\t\t\t\t}\n\t\t\t\t\tif (lookupGroup.NestedTypes != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (IType type in lookupGroup.NestedTypes)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tITypeDefinition typeDef = type.GetDefinition();\n\t\t\t\t\t\t\tif (typeDef != null)\n\t\t\t\t\t\t\t\tyield return typeDef;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region class LookupGroup\n\t\tsealed class LookupGroup\n\t\t{\n\t\t\tpublic readonly IType DeclaringType;\n\n\t\t\t// When a nested type is hidden, it is simply removed from the list.\n\t\t\tpublic List<IType> NestedTypes;\n\n\t\t\t// When members are hidden, they are merely marked as hidden.\n\t\t\t// We still need to store the hidden methods so that the 'override' processing can\n\t\t\t// find them, so that it won't introduce the override as a new method.\n\t\t\tpublic readonly List<IParameterizedMember> Methods;\n\t\t\tpublic bool MethodsAreHidden;\n\n\t\t\tpublic IMember NonMethod;\n\t\t\tpublic bool NonMethodIsHidden;\n\n\t\t\tpublic LookupGroup(IType declaringType, List<IType> nestedTypes, List<IParameterizedMember> methods, IMember nonMethod)\n\t\t\t{\n\t\t\t\tthis.DeclaringType = declaringType;\n\t\t\t\tthis.NestedTypes = nestedTypes;\n\t\t\t\tthis.Methods = methods;\n\t\t\t\tthis.NonMethod = nonMethod;\n\t\t\t\tthis.MethodsAreHidden = (methods == null || methods.Count == 0);\n\t\t\t\tthis.NonMethodIsHidden = (nonMethod == null);\n\t\t\t}\n\n\t\t\tpublic bool AllHidden {\n\t\t\t\tget {\n\t\t\t\t\tif (NestedTypes != null && NestedTypes.Count > 0)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn NonMethodIsHidden && MethodsAreHidden;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region LookupType\n\t\tpublic ResolveResult LookupType(IType declaringType, string name, IReadOnlyList<IType> typeArguments, bool parameterizeResultType = true)\n\t\t{\n\t\t\tif (declaringType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(declaringType));\n\t\t\tif (name == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(name));\n\t\t\tif (typeArguments == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(typeArguments));\n\n\t\t\tint typeArgumentCount = typeArguments.Count;\n\t\t\tPredicate<ITypeDefinition> filter = delegate (ITypeDefinition d) {\n\t\t\t\treturn InnerTypeParameterCount(d) == typeArgumentCount && d.Name == name && IsAccessible(d, true);\n\t\t\t};\n\n\t\t\tList<LookupGroup> lookupGroups = new List<LookupGroup>();\n\t\t\tif (declaringType.Kind != TypeKind.TypeParameter)\n\t\t\t{\n\t\t\t\tforeach (IType type in declaringType.GetNonInterfaceBaseTypes())\n\t\t\t\t{\n\t\t\t\t\tList<IType> newNestedTypes = null;\n\t\t\t\t\tIEnumerable<IType> typeBaseTypes = null;\n\n\t\t\t\t\tIEnumerable<IType> nestedTypes;\n\t\t\t\t\tif (parameterizeResultType)\n\t\t\t\t\t{\n\t\t\t\t\t\tnestedTypes = type.GetNestedTypes(typeArguments, filter, GetMemberOptions.IgnoreInheritedMembers);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tnestedTypes = type.GetNestedTypes(filter, GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions);\n\t\t\t\t\t}\n\t\t\t\t\tAddNestedTypes(type, nestedTypes, typeArgumentCount, lookupGroups, ref typeBaseTypes, ref newNestedTypes);\n\n\t\t\t\t\tif (newNestedTypes != null)\n\t\t\t\t\t\tlookupGroups.Add(new LookupGroup(type, newNestedTypes, null, null));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlookupGroups.RemoveAll(g => g.AllHidden);\n\t\t\tDebug.Assert(lookupGroups.All(g => g.NestedTypes != null && g.NestedTypes.Count > 0));\n\n\t\t\tif (lookupGroups.Count == 0)\n\t\t\t{\n\t\t\t\treturn new UnknownMemberResolveResult(declaringType, name, typeArguments);\n\t\t\t}\n\n\t\t\tLookupGroup resultGroup = lookupGroups[lookupGroups.Count - 1];\n\n\t\t\tif (resultGroup.NestedTypes.Count > 1 || lookupGroups.Count > 1)\n\t\t\t\treturn new AmbiguousTypeResolveResult(resultGroup.NestedTypes[0]);\n\t\t\telse\n\t\t\t\treturn new TypeResolveResult(resultGroup.NestedTypes[0]);\n\t\t}\n\n\t\tstatic int InnerTypeParameterCount(IType type)\n\t\t{\n\t\t\t// inner types contain the type parameters of outer types. therefore this count has to been adjusted.\n\t\t\treturn type.TypeParameterCount - (type.DeclaringType != null ? type.DeclaringType.TypeParameterCount : 0);\n\t\t}\n\t\t#endregion\n\n\t\t#region Lookup\n\t\t/// <summary>\n\t\t/// Performs a member lookup.\n\t\t/// </summary>\n\t\tpublic ResolveResult Lookup(ResolveResult targetResolveResult, string name, IReadOnlyList<IType> typeArguments, bool isInvocation)\n\t\t{\n\t\t\tif (targetResolveResult == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(targetResolveResult));\n\t\t\tif (name == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(name));\n\t\t\tif (typeArguments == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(typeArguments));\n\n\t\t\tbool targetIsTypeParameter = targetResolveResult.Type.Kind == TypeKind.TypeParameter;\n\n\t\t\tbool allowProtectedAccess = IsProtectedAccessAllowed(targetResolveResult);\n\t\t\tPredicate<ITypeDefinition> nestedTypeFilter = delegate (ITypeDefinition entity) {\n\t\t\t\treturn entity.Name == name && IsAccessible(entity, allowProtectedAccess);\n\t\t\t};\n\t\t\tPredicate<IMember> memberFilter = delegate (IMember entity) {\n\t\t\t\t// NOTE: Atm destructors can be looked up with 'Finalize'\n\t\t\t\treturn entity.SymbolKind != SymbolKind.Indexer &&\n\t\t\t\t\t   entity.SymbolKind != SymbolKind.Operator &&\n\t\t\t\t\t   entity.Name == name;\n\t\t\t};\n\n\t\t\tList<LookupGroup> lookupGroups = new List<LookupGroup>();\n\t\t\t// This loop will handle base types before derived types.\n\t\t\t// The loop performs three jobs:\n\t\t\t// 1) It marks entries in lookup groups from base classes as removed when those members\n\t\t\t//    are hidden by a derived class.\n\t\t\t// 2) It adds a new lookup group with the members from a declaring type.\n\t\t\t// 3) It replaces virtual members with the overridden version, placing the override in the\n\t\t\t//    lookup group belonging to the base class.\n\t\t\tforeach (IType type in targetResolveResult.Type.GetNonInterfaceBaseTypes())\n\t\t\t{\n\n\t\t\t\tList<IType> newNestedTypes = null;\n\t\t\t\tList<IParameterizedMember> newMethods = null;\n\t\t\t\tIMember newNonMethod = null;\n\n\t\t\t\tIEnumerable<IType> typeBaseTypes = null;\n\n\t\t\t\tif (!isInvocation && !targetIsTypeParameter)\n\t\t\t\t{\n\t\t\t\t\t// Consider nested types only if it's not an invocation.\n\t\t\t\t\t// type.GetNestedTypes() is checking the type parameter count for an exact match,\n\t\t\t\t\t// so we don't need to do that in our filter.\n\t\t\t\t\tvar nestedTypes = type.GetNestedTypes(typeArguments, nestedTypeFilter, GetMemberOptions.IgnoreInheritedMembers);\n\t\t\t\t\tAddNestedTypes(type, nestedTypes, typeArguments.Count, lookupGroups, ref typeBaseTypes, ref newNestedTypes);\n\t\t\t\t}\n\n\t\t\t\tIEnumerable<IMember> members;\n\t\t\t\tif (typeArguments.Count == 0)\n\t\t\t\t{\n\t\t\t\t\t// Note: IsInvocable-checking cannot be done as part of the filter;\n\t\t\t\t\t// because it must be done after type substitution.\n\t\t\t\t\tmembers = type.GetMembers(memberFilter, GetMemberOptions.IgnoreInheritedMembers);\n\t\t\t\t\tif (isInvocation)\n\t\t\t\t\t\tmembers = members.Where(m => IsInvocable(m));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// No need to check for isInvocation/isInvocable here:\n\t\t\t\t\t// we only fetch methods\n\t\t\t\t\tmembers = type.GetMethods(typeArguments, memberFilter, GetMemberOptions.IgnoreInheritedMembers);\n\t\t\t\t}\n\t\t\t\tAddMembers(type, members, allowProtectedAccess, lookupGroups, false, ref typeBaseTypes, ref newMethods, ref newNonMethod);\n\n\t\t\t\tif (newNestedTypes != null || newMethods != null || newNonMethod != null)\n\t\t\t\t\tlookupGroups.Add(new LookupGroup(type, newNestedTypes, newMethods, newNonMethod));\n\t\t\t}\n\n\t\t\t// Remove interface members hidden by class members.\n\t\t\tif (targetIsTypeParameter)\n\t\t\t{\n\t\t\t\t// This can happen only with type parameters.\n\t\t\t\tRemoveInterfaceMembersHiddenByClassMembers(lookupGroups);\n\t\t\t}\n\n\t\t\treturn CreateResult(targetResolveResult, lookupGroups, name, typeArguments);\n\t\t}\n\t\t#endregion\n\n\t\t#region Lookup Indexer\n\t\t/// <summary>\n\t\t/// Looks up the indexers on the target type.\n\t\t/// </summary>\n\t\tpublic IReadOnlyList<MethodListWithDeclaringType> LookupIndexers(ResolveResult targetResolveResult)\n\t\t{\n\t\t\tif (targetResolveResult == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(targetResolveResult));\n\n\t\t\tIType targetType = targetResolveResult.Type;\n\t\t\tbool allowProtectedAccess = IsProtectedAccessAllowed(targetResolveResult);\n\t\t\tPredicate<IProperty> filter = p => p.IsIndexer && !p.IsExplicitInterfaceImplementation;\n\n\t\t\tList<LookupGroup> lookupGroups = new List<LookupGroup>();\n\t\t\tforeach (IType type in targetType.GetNonInterfaceBaseTypes())\n\t\t\t{\n\t\t\t\tList<IParameterizedMember> newMethods = null;\n\t\t\t\tIMember newNonMethod = null;\n\n\t\t\t\tIEnumerable<IType> typeBaseTypes = null;\n\n\t\t\t\tvar members = type.GetProperties(filter, GetMemberOptions.IgnoreInheritedMembers);\n\t\t\t\tAddMembers(type, members, allowProtectedAccess, lookupGroups, true, ref typeBaseTypes, ref newMethods, ref newNonMethod);\n\n\t\t\t\tif (newMethods != null || newNonMethod != null)\n\t\t\t\t\tlookupGroups.Add(new LookupGroup(type, null, newMethods, newNonMethod));\n\t\t\t}\n\n\t\t\t// Remove interface members hidden by class members.\n\t\t\tif (targetType.Kind == TypeKind.TypeParameter)\n\t\t\t{\n\t\t\t\t// This can happen only with type parameters.\n\t\t\t\tRemoveInterfaceMembersHiddenByClassMembers(lookupGroups);\n\t\t\t}\n\n\t\t\t// Remove all hidden groups\n\t\t\tlookupGroups.RemoveAll(g => g.MethodsAreHidden || g.Methods.Count == 0);\n\n\t\t\tMethodListWithDeclaringType[] methodLists = new MethodListWithDeclaringType[lookupGroups.Count];\n\t\t\tfor (int i = 0; i < methodLists.Length; i++)\n\t\t\t{\n\t\t\t\tmethodLists[i] = new MethodListWithDeclaringType(lookupGroups[i].DeclaringType, lookupGroups[i].Methods);\n\t\t\t}\n\t\t\treturn methodLists;\n\t\t}\n\t\t#endregion\n\n\t\t#region AddNestedTypes\n\t\t/// <summary>\n\t\t/// Adds the nested types to 'newNestedTypes' and removes any hidden members from the existing lookup groups.\n\t\t/// </summary>\n\t\t/// <param name=\"type\">Declaring type of the nested types</param>\n\t\t/// <param name=\"nestedTypes\">List of nested types to add.</param>\n\t\t/// <param name=\"typeArgumentCount\">The number of type arguments - used for hiding types from the base class</param>\n\t\t/// <param name=\"lookupGroups\">List of existing lookup groups</param>\n\t\t/// <param name=\"typeBaseTypes\">The base types of 'type' (initialized on demand)</param>\n\t\t/// <param name=\"newNestedTypes\">The target list (created on demand).</param>\n\t\tvoid AddNestedTypes(IType type, IEnumerable<IType> nestedTypes, int typeArgumentCount,\n\t\t\t\t\t\t\tList<LookupGroup> lookupGroups,\n\t\t\t\t\t\t\tref IEnumerable<IType> typeBaseTypes,\n\t\t\t\t\t\t\tref List<IType> newNestedTypes)\n\t\t{\n\t\t\tforeach (IType nestedType in nestedTypes)\n\t\t\t{\n\t\t\t\t// Remove all non-types declared in a base type of 'type',\n\t\t\t\t// and all types with same number of type parameters declared in a base type of 'type'.\n\t\t\t\tforeach (var lookupGroup in lookupGroups)\n\t\t\t\t{\n\t\t\t\t\tif (lookupGroup.AllHidden)\n\t\t\t\t\t\tcontinue; // everything is already hidden\n\t\t\t\t\tif (typeBaseTypes == null)\n\t\t\t\t\t\ttypeBaseTypes = type.GetNonInterfaceBaseTypes();\n\n\t\t\t\t\tif (typeBaseTypes.Contains(lookupGroup.DeclaringType))\n\t\t\t\t\t{\n\t\t\t\t\t\tlookupGroup.MethodsAreHidden = true;\n\t\t\t\t\t\tlookupGroup.NonMethodIsHidden = true;\n\t\t\t\t\t\tif (lookupGroup.NestedTypes != null)\n\t\t\t\t\t\t\tlookupGroup.NestedTypes.RemoveAll(t => InnerTypeParameterCount(t) == typeArgumentCount);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Add the new nested type.\n\t\t\t\tif (newNestedTypes == null)\n\t\t\t\t\tnewNestedTypes = new List<IType>();\n\t\t\t\tnewNestedTypes.Add(nestedType);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region AddMembers\n\t\t/// <summary>\n\t\t/// Adds members to 'newMethods'/'newNonMethod'.\n\t\t/// Removes any members in the existing lookup groups that were hidden by added members.\n\t\t/// Substitutes 'virtual' members in the existing lookup groups for added 'override' members.\n\t\t/// </summary>\n\t\t/// <param name=\"type\">Declaring type of the members</param>\n\t\t/// <param name=\"members\">List of members to add.</param>\n\t\t/// <param name=\"allowProtectedAccess\">Whether protected members are accessible</param>\n\t\t/// <param name=\"lookupGroups\">List of existing lookup groups</param>\n\t\t/// <param name=\"treatAllParameterizedMembersAsMethods\">Whether to treat properties as methods</param>\n\t\t/// <param name=\"typeBaseTypes\">The base types of 'type' (initialized on demand)</param>\n\t\t/// <param name=\"newMethods\">The target list for methods (created on demand).</param>\n\t\t/// <param name=\"newNonMethod\">The target variable for non-method members.</param>\n\t\tvoid AddMembers(IType type, IEnumerable<IMember> members,\n\t\t\t\t\t\tbool allowProtectedAccess,\n\t\t\t\t\t\tList<LookupGroup> lookupGroups,\n\t\t\t\t\t\tbool treatAllParameterizedMembersAsMethods,\n\t\t\t\t\t\tref IEnumerable<IType> typeBaseTypes, ref List<IParameterizedMember> newMethods, ref IMember newNonMethod)\n\t\t{\n\t\t\tforeach (IMember member in members)\n\t\t\t{\n\t\t\t\tif (!IsAccessible(member, allowProtectedAccess))\n\t\t\t\t\tcontinue;\n\n\t\t\t\tIParameterizedMember method;\n\t\t\t\tif (treatAllParameterizedMembersAsMethods)\n\t\t\t\t\tmethod = member as IParameterizedMember;\n\t\t\t\telse\n\t\t\t\t\tmethod = member as IMethod;\n\n\t\t\t\tbool replacedVirtualMemberWithOverride = false;\n\t\t\t\tif (member.IsOverride)\n\t\t\t\t{\n\t\t\t\t\t// Replacing virtual member with override:\n\n\t\t\t\t\t// Go backwards so that we find the corresponding virtual member\n\t\t\t\t\t// in the most-derived type\n\t\t\t\t\tfor (int i = lookupGroups.Count - 1; i >= 0 && !replacedVirtualMemberWithOverride; i--)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (typeBaseTypes == null)\n\t\t\t\t\t\t\ttypeBaseTypes = type.GetNonInterfaceBaseTypes();\n\n\t\t\t\t\t\tvar lookupGroup = lookupGroups[i];\n\t\t\t\t\t\tif (typeBaseTypes.Contains(lookupGroup.DeclaringType))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (method != null && !lookupGroup.MethodsAreHidden)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// Find the matching method, and replace it with the override\n\t\t\t\t\t\t\t\tfor (int j = 0; j < lookupGroup.Methods.Count; j++)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif (SignatureComparer.Ordinal.Equals(method, lookupGroup.Methods[j]))\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tlookupGroup.Methods[j] = method;\n\t\t\t\t\t\t\t\t\t\treplacedVirtualMemberWithOverride = true;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// If the member type matches, replace it with the override\n\t\t\t\t\t\t\t\tif (lookupGroup.NonMethod != null && lookupGroup.NonMethod.SymbolKind == member.SymbolKind)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlookupGroup.NonMethod = member;\n\t\t\t\t\t\t\t\t\treplacedVirtualMemberWithOverride = true;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// If the member wasn't an override, or if we didn't find any matching virtual method,\n\t\t\t\t// proceed to add the member.\n\t\t\t\tif (!replacedVirtualMemberWithOverride)\n\t\t\t\t{\n\t\t\t\t\t// Make the member hide other members:\n\t\t\t\t\tforeach (var lookupGroup in lookupGroups)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (lookupGroup.AllHidden)\n\t\t\t\t\t\t\tcontinue; // everything is already hidden\n\t\t\t\t\t\tif (typeBaseTypes == null)\n\t\t\t\t\t\t\ttypeBaseTypes = type.GetNonInterfaceBaseTypes();\n\n\t\t\t\t\t\tif (typeBaseTypes.Contains(lookupGroup.DeclaringType))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Methods hide all non-methods; Non-methods hide everything\n\t\t\t\t\t\t\tlookupGroup.NestedTypes = null;\n\t\t\t\t\t\t\tlookupGroup.NonMethodIsHidden = true;\n\t\t\t\t\t\t\tif (method == null)\n\t\t\t\t\t\t\t{ // !(member is IMethod)\n\t\t\t\t\t\t\t\tlookupGroup.MethodsAreHidden = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Add the new member\n\t\t\t\t\tif (method != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (newMethods == null)\n\t\t\t\t\t\t\tnewMethods = new List<IParameterizedMember>();\n\t\t\t\t\t\tnewMethods.Add(method);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tnewNonMethod = member;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region RemoveInterfaceMembersHiddenByClassMembers\n\t\tvoid RemoveInterfaceMembersHiddenByClassMembers(List<LookupGroup> lookupGroups)\n\t\t{\n\t\t\tforeach (var classLookupGroup in lookupGroups)\n\t\t\t{\n\t\t\t\tif (IsInterfaceOrSystemObject(classLookupGroup.DeclaringType))\n\t\t\t\t\tcontinue;\n\t\t\t\t// The current lookup groups contains class members that might hide interface members\n\t\t\t\tbool hasNestedTypes = classLookupGroup.NestedTypes != null && classLookupGroup.NestedTypes.Count > 0;\n\t\t\t\tif (hasNestedTypes || !classLookupGroup.NonMethodIsHidden)\n\t\t\t\t{\n\t\t\t\t\t// Hide all members from interface types\n\t\t\t\t\tforeach (var interfaceLookupGroup in lookupGroups)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (IsInterfaceOrSystemObject(interfaceLookupGroup.DeclaringType))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tinterfaceLookupGroup.NestedTypes = null;\n\t\t\t\t\t\t\tinterfaceLookupGroup.NonMethodIsHidden = true;\n\t\t\t\t\t\t\tinterfaceLookupGroup.MethodsAreHidden = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (!classLookupGroup.MethodsAreHidden)\n\t\t\t\t{\n\t\t\t\t\tforeach (var classMethod in classLookupGroup.Methods)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Hide all non-methods from interface types, and all methods with the same signature\n\t\t\t\t\t\t// as a method in this class type.\n\t\t\t\t\t\tforeach (var interfaceLookupGroup in lookupGroups)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (IsInterfaceOrSystemObject(interfaceLookupGroup.DeclaringType))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tinterfaceLookupGroup.NestedTypes = null;\n\t\t\t\t\t\t\t\tinterfaceLookupGroup.NonMethodIsHidden = true;\n\t\t\t\t\t\t\t\tif (interfaceLookupGroup.Methods != null && !interfaceLookupGroup.MethodsAreHidden)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t// The mapping of virtual to overridden methods is already done,\n\t\t\t\t\t\t\t\t\t// so we can simply remove the methods from the collection\n\t\t\t\t\t\t\t\t\tinterfaceLookupGroup.Methods.RemoveAll(\n\t\t\t\t\t\t\t\t\t\tm => SignatureComparer.Ordinal.Equals(classMethod, m));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic bool IsInterfaceOrSystemObject(IType type)\n\t\t{\n\t\t\t// return true if type is an interface or System.Object\n\t\t\tif (type.Kind == TypeKind.Interface)\n\t\t\t\treturn true;\n\t\t\tITypeDefinition d = type.GetDefinition();\n\t\t\treturn d != null && d.KnownTypeCode == KnownTypeCode.Object;\n\t\t}\n\t\t#endregion\n\n\t\t#region CreateResult\n\t\tResolveResult CreateResult(ResolveResult targetResolveResult, List<LookupGroup> lookupGroups, string name, IReadOnlyList<IType> typeArguments)\n\t\t{\n\t\t\t// Remove all hidden groups\n\t\t\tlookupGroups.RemoveAll(g => g.AllHidden);\n\n\t\t\tif (lookupGroups.Count == 0)\n\t\t\t{\n\t\t\t\t// No members found\n\t\t\t\treturn new UnknownMemberResolveResult(targetResolveResult.Type, name, typeArguments);\n\t\t\t}\n\n\t\t\tif (lookupGroups.Any(g => !g.MethodsAreHidden && g.Methods.Count > 0))\n\t\t\t{\n\t\t\t\t// If there are methods, make a MethodGroupResolveResult.\n\t\t\t\t// Note that a conflict between a member and a method (possible with multiple interface inheritance)\n\t\t\t\t// is only a warning, not an error, and the C# compiler will prefer the method group.\n\t\t\t\tList<MethodListWithDeclaringType> methodLists = new List<MethodListWithDeclaringType>();\n\t\t\t\tforeach (var lookupGroup in lookupGroups)\n\t\t\t\t{\n\t\t\t\t\tif (!lookupGroup.MethodsAreHidden && lookupGroup.Methods.Count > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar methodListWithDeclType = new MethodListWithDeclaringType(lookupGroup.DeclaringType);\n\t\t\t\t\t\tforeach (var method in lookupGroup.Methods)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmethodListWithDeclType.Add((IMethod)method);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmethodLists.Add(methodListWithDeclType);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn new MethodGroupResolveResult(targetResolveResult, name, methodLists, typeArguments);\n\t\t\t}\n\n\t\t\t// If there are ambiguities, report the most-derived result (last group)\n\t\t\tLookupGroup resultGroup = lookupGroups[lookupGroups.Count - 1];\n\t\t\tif (resultGroup.NestedTypes != null && resultGroup.NestedTypes.Count > 0)\n\t\t\t{\n\t\t\t\tif (resultGroup.NestedTypes.Count > 1 || !resultGroup.NonMethodIsHidden || lookupGroups.Count > 1)\n\t\t\t\t\treturn new AmbiguousTypeResolveResult(resultGroup.NestedTypes[0]);\n\t\t\t\telse\n\t\t\t\t\treturn new TypeResolveResult(resultGroup.NestedTypes[0]);\n\t\t\t}\n\n\t\t\tif (resultGroup.NonMethod.IsStatic && targetResolveResult is ThisResolveResult)\n\t\t\t{\n\t\t\t\ttargetResolveResult = new TypeResolveResult(targetResolveResult.Type);\n\t\t\t}\n\n\t\t\tif (lookupGroups.Count > 1)\n\t\t\t{\n\t\t\t\treturn new AmbiguousMemberResolveResult(targetResolveResult, resultGroup.NonMethod);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (isInEnumMemberInitializer)\n\t\t\t\t{\n\t\t\t\t\tIField field = resultGroup.NonMethod as IField;\n\t\t\t\t\tif (field != null && field.DeclaringTypeDefinition != null && field.DeclaringTypeDefinition.Kind == TypeKind.Enum)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new MemberResolveResult(\n\t\t\t\t\t\t\ttargetResolveResult, field,\n\t\t\t\t\t\t\tfield.DeclaringTypeDefinition.EnumUnderlyingType,\n\t\t\t\t\t\t\tfield.IsConst, field.GetConstantValue());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn new MemberResolveResult(targetResolveResult, resultGroup.NonMethod);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Resolver/MethodGroupResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Net.NetworkInformation;\n\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp.Resolver\n{\n\t/// <summary>\n\t/// A method list that belongs to a declaring type.\n\t/// </summary>\n\tpublic class MethodListWithDeclaringType : List<IParameterizedMember>\n\t{\n\t\treadonly IType declaringType;\n\n\t\t/// <summary>\n\t\t/// The declaring type.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Not all methods in this list necessarily have this as their declaring type.\n\t\t/// For example, this program:\n\t\t/// <code>\n\t\t///  class Base {\n\t\t///    public virtual void M() {}\n\t\t///  }\n\t\t///  class Derived : Base {\n\t\t///    public override void M() {}\n\t\t///    public void M(int i) {}\n\t\t///  }\n\t\t/// </code>\n\t\t/// results in two lists:\n\t\t///  <c>new MethodListWithDeclaringType(Base) { Derived.M() }</c>,\n\t\t///  <c>new MethodListWithDeclaringType(Derived) { Derived.M(int) }</c>\n\t\t/// </remarks>\n\t\tpublic IType DeclaringType {\n\t\t\tget { return declaringType; }\n\t\t}\n\n\t\tpublic MethodListWithDeclaringType(IType declaringType)\n\t\t{\n\t\t\tthis.declaringType = declaringType;\n\t\t}\n\n\t\tpublic MethodListWithDeclaringType(IType declaringType, IEnumerable<IParameterizedMember> methods)\n\t\t\t: base(methods)\n\t\t{\n\t\t\tthis.declaringType = declaringType;\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Represents a group of methods.\n\t/// A method reference used to create a delegate is resolved to a MethodGroupResolveResult.\n\t/// The MethodGroupResolveResult has no type.\n\t/// To retrieve the delegate type or the chosen overload, look at the method group conversion.\n\t/// </summary>\n\tpublic class MethodGroupResolveResult : ResolveResult\n\t{\n\t\treadonly IReadOnlyList<MethodListWithDeclaringType> methodLists;\n\t\treadonly IReadOnlyList<IType> typeArguments;\n\t\treadonly ResolveResult targetResult;\n\t\treadonly string methodName;\n\t\tIMethod chosenMethod;\n\n\t\tpublic MethodGroupResolveResult(ResolveResult targetResult, string methodName,\n\t\t\tIReadOnlyList<MethodListWithDeclaringType> methods, IReadOnlyList<IType> typeArguments)\n\t\t\t: base(SpecialType.NoType)\n\t\t{\n\t\t\tif (methods == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(methods));\n\t\t\tthis.targetResult = targetResult;\n\t\t\tthis.methodName = methodName;\n\t\t\tthis.methodLists = methods;\n\t\t\tthis.typeArguments = typeArguments ?? EmptyList<IType>.Instance;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the resolve result for the target object.\n\t\t/// </summary>\n\t\tpublic ResolveResult TargetResult {\n\t\t\tget { return targetResult; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the type of the reference to the target object.\n\t\t/// </summary>\n\t\tpublic IType TargetType {\n\t\t\tget { return targetResult != null ? targetResult.Type : SpecialType.UnknownType; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the name of the methods in this group.\n\t\t/// </summary>\n\t\tpublic string MethodName {\n\t\t\tget { return methodName; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the methods that were found.\n\t\t/// This list does not include extension methods.\n\t\t/// </summary>\n\t\tpublic IEnumerable<IMethod> Methods {\n\t\t\tget { return methodLists.SelectMany(m => m.Cast<IMethod>()); }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the methods that were found, grouped by their declaring type.\n\t\t/// This list does not include extension methods.\n\t\t/// Base types come first in the list.\n\t\t/// </summary>\n\t\tpublic IEnumerable<MethodListWithDeclaringType> MethodsGroupedByDeclaringType {\n\t\t\tget { return methodLists; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the type arguments that were explicitly provided.\n\t\t/// </summary>\n\t\tpublic IReadOnlyList<IType> TypeArguments {\n\t\t\tget { return typeArguments; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// List of extension methods, used to avoid re-calculating it in ResolveInvocation() when it was already\n\t\t/// calculated by ResolveMemberAccess().\n\t\t/// </summary>\n\t\tinternal List<List<IMethod>> extensionMethods;\n\n\t\t// the resolver is used to fetch extension methods on demand\n\t\tinternal CSharpResolver resolver;\n\n\t\t/// <summary>\n\t\t/// Gets the method that was chosen for this group.\n\t\t/// \n\t\t/// Only set for MethodGroupResolveResults found in ILSpy AST annotations.\n\t\t/// </summary>\n\t\tpublic IMethod ChosenMethod => chosenMethod;\n\n\t\tpublic MethodGroupResolveResult WithChosenMethod(IMethod method)\n\t\t{\n\t\t\tvar result = (MethodGroupResolveResult)ShallowClone();\n\t\t\tresult.chosenMethod = method;\n\t\t\treturn result;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets all candidate extension methods.\n\t\t/// Note: this includes candidates that are not eligible due to an inapplicable\n\t\t/// this argument.\n\t\t/// The candidates will only be specialized if the type arguments were provided explicitly.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// The results are stored in nested lists because they are grouped by using scope.\n\t\t/// That is, for \"using SomeExtensions; namespace X { using MoreExtensions; ... }\",\n\t\t/// the return value will be\n\t\t/// new List {\n\t\t///    new List { all extensions from MoreExtensions },\n\t\t///    new List { all extensions from SomeExtensions }\n\t\t/// }\n\t\t/// </remarks>\n\t\tpublic IEnumerable<IEnumerable<IMethod>> GetExtensionMethods()\n\t\t{\n\t\t\tif (resolver != null)\n\t\t\t{\n\t\t\t\tDebug.Assert(extensionMethods == null);\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\textensionMethods = resolver.GetExtensionMethods(methodName, typeArguments);\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tresolver = null;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn extensionMethods ?? Enumerable.Empty<IEnumerable<IMethod>>();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the eligible extension methods.\n\t\t/// </summary>\n\t\t/// <param name=\"substituteInferredTypes\">\n\t\t/// Specifies whether to produce a <c>SpecializedMethod</c>\n\t\t/// when type arguments could be inferred from <see cref=\"TargetType\"/>.\n\t\t/// This setting is only used for inferred types and has no effect if the type parameters are\n\t\t/// specified explicitly.\n\t\t/// </param>\n\t\t/// <remarks>\n\t\t/// The results are stored in nested lists because they are grouped by using scope.\n\t\t/// That is, for \"using SomeExtensions; namespace X { using MoreExtensions; ... }\",\n\t\t/// the return value will be\n\t\t/// new List {\n\t\t///    new List { all extensions from MoreExtensions },\n\t\t///    new List { all extensions from SomeExtensions }\n\t\t/// }\n\t\t/// </remarks>\n\t\tpublic IEnumerable<IEnumerable<IMethod>> GetEligibleExtensionMethods(bool substituteInferredTypes)\n\t\t{\n\t\t\tvar result = new List<List<IMethod>>();\n\t\t\tforeach (var methodGroup in GetExtensionMethods())\n\t\t\t{\n\t\t\t\tvar outputGroup = new List<IMethod>();\n\t\t\t\tforeach (var method in methodGroup)\n\t\t\t\t{\n\t\t\t\t\tif (CSharpResolver.IsEligibleExtensionMethod(this.TargetType, method, true, out IType[] inferredTypes))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (substituteInferredTypes && inferredTypes != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toutputGroup.Add(method.Specialize(new TypeParameterSubstitution(null, inferredTypes)));\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toutputGroup.Add(method);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (outputGroup.Count > 0)\n\t\t\t\t\tresult.Add(outputGroup);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(\"[{0} with {1} method(s)]\", GetType().Name, this.Methods.Count());\n\t\t}\n\n\t\tpublic OverloadResolution PerformOverloadResolution(ICompilation compilation, ResolveResult[] arguments, string[] argumentNames = null,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tbool allowExtensionMethods = true,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tbool allowExpandingParams = true,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tbool allowOptionalParameters = true,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tbool allowImplicitIn = true,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tbool checkForOverflow = false, CSharpConversions conversions = null)\n\t\t{\n\t\t\tLog.WriteLine(\"Performing overload resolution for \" + this);\n\t\t\tLog.WriteCollection(\"  Arguments: \", arguments);\n\n\t\t\tvar typeArgumentArray = this.TypeArguments.ToArray();\n\t\t\tOverloadResolution or = new OverloadResolution(compilation, arguments, argumentNames, typeArgumentArray, conversions);\n\t\t\tor.AllowExpandingParams = allowExpandingParams;\n\t\t\tor.AllowOptionalParameters = allowOptionalParameters;\n\t\t\tor.CheckForOverflow = checkForOverflow;\n\t\t\tor.AllowImplicitIn = allowImplicitIn;\n\n\t\t\tor.AddMethodLists(methodLists);\n\n\t\t\tif (allowExtensionMethods && !or.FoundApplicableCandidate)\n\t\t\t{\n\t\t\t\t// No applicable match found, so let's try extension methods.\n\n\t\t\t\tvar extensionMethods = this.GetExtensionMethods();\n\n\t\t\t\tif (extensionMethods.Any())\n\t\t\t\t{\n\t\t\t\t\tLog.WriteLine(\"No candidate is applicable, trying {0} extension methods groups...\", extensionMethods.Count());\n\t\t\t\t\tResolveResult[] extArguments = new ResolveResult[arguments.Length + 1];\n\t\t\t\t\textArguments[0] = new ResolveResult(this.TargetType);\n\t\t\t\t\targuments.CopyTo(extArguments, 1);\n\t\t\t\t\tstring[] extArgumentNames = null;\n\t\t\t\t\tif (argumentNames != null)\n\t\t\t\t\t{\n\t\t\t\t\t\textArgumentNames = new string[argumentNames.Length + 1];\n\t\t\t\t\t\targumentNames.CopyTo(extArgumentNames, 1);\n\t\t\t\t\t}\n\t\t\t\t\tvar extOr = new OverloadResolution(compilation, extArguments, extArgumentNames, typeArgumentArray, conversions);\n\t\t\t\t\textOr.AllowExpandingParams = allowExpandingParams;\n\t\t\t\t\textOr.AllowOptionalParameters = allowOptionalParameters;\n\t\t\t\t\textOr.IsExtensionMethodInvocation = true;\n\t\t\t\t\textOr.CheckForOverflow = checkForOverflow;\n\t\t\t\t\textOr.AllowImplicitIn = allowImplicitIn;\n\n\t\t\t\t\tforeach (var g in extensionMethods)\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var method in g)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tLog.Indent();\n\t\t\t\t\t\t\tOverloadResolutionErrors errors = extOr.AddCandidate(method);\n\t\t\t\t\t\t\tLog.Unindent();\n\t\t\t\t\t\t\tor.LogCandidateAddingResult(\"  Extension\", method, errors);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (extOr.FoundApplicableCandidate)\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\t// For the lack of a better comparison function (the one within OverloadResolution\n\t\t\t\t\t// cannot be used as it depends on the argument set):\n\t\t\t\t\tif (extOr.FoundApplicableCandidate || or.BestCandidate == null)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Consider an extension method result better than the normal result only\n\t\t\t\t\t\t// if it's applicable; or if there is no normal result.\n\t\t\t\t\t\tor = extOr;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tLog.WriteLine(\"Overload resolution finished, best candidate is {0}.\", or.GetBestCandidateWithSubstitutedTypeArguments());\n\t\t\treturn or;\n\t\t}\n\n\t\tpublic override IEnumerable<ResolveResult> GetChildResults()\n\t\t{\n\t\t\tif (targetResult != null)\n\t\t\t\treturn new[] { targetResult };\n\t\t\telse\n\t\t\t\treturn Enumerable.Empty<ResolveResult>();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Resolver/NameLookupMode.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Resolver\n{\n\tpublic enum NameLookupMode\n\t{\n\t\t/// <summary>\n\t\t/// Normal name lookup in expressions\n\t\t/// </summary>\n\t\tExpression,\n\t\t/// <summary>\n\t\t/// Name lookup in expression, where the expression is the target of an invocation.\n\t\t/// Such a lookup will only return methods and delegate-typed fields.\n\t\t/// </summary>\n\t\tInvocationTarget,\n\t\t/// <summary>\n\t\t/// Normal name lookup in type references.\n\t\t/// </summary>\n\t\tType,\n\t\t/// <summary>\n\t\t/// Name lookup in the type reference inside a using declaration.\n\t\t/// </summary>\n\t\tTypeInUsingDeclaration,\n\t\t/// <summary>\n\t\t/// Name lookup for base type references.\n\t\t/// </summary>\n\t\tBaseTypeReference\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Resolver/OverloadResolution.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp.Resolver\n{\n\t/// <summary>\n\t/// C# overload resolution (C# 4.0 spec: §7.5).\n\t/// </summary>\n\tpublic class OverloadResolution\n\t{\n\t\tsealed class Candidate\n\t\t{\n\t\t\tpublic readonly IParameterizedMember Member;\n\n\t\t\t/// <summary>\n\t\t\t/// Returns the normal form candidate, if this is an expanded candidate.\n\t\t\t/// </summary>\n\t\t\tpublic readonly bool IsExpandedForm;\n\n\t\t\t/// <summary>\n\t\t\t/// Gets the parameter types. In the first step, these are the types without any substitution.\n\t\t\t/// After type inference, substitutions will be performed.\n\t\t\t/// </summary>\n\t\t\tpublic readonly IType[] ParameterTypes;\n\n\t\t\t/// <summary>\n\t\t\t/// argument index -> parameter index; -1 for arguments that could not be mapped\n\t\t\t/// </summary>\n\t\t\tpublic int[] ArgumentToParameterMap;\n\n\t\t\tpublic OverloadResolutionErrors Errors;\n\t\t\tpublic int ErrorCount;\n\n\t\t\tpublic bool HasUnmappedOptionalParameters;\n\n\t\t\tpublic IType[] InferredTypes;\n\n\t\t\t/// <summary>\n\t\t\t/// Gets the original member parameters (before any substitution!)\n\t\t\t/// </summary>\n\t\t\tpublic readonly IReadOnlyList<IParameter> Parameters;\n\n\t\t\t/// <summary>\n\t\t\t/// Gets the original method type parameters (before any substitution!)\n\t\t\t/// </summary>\n\t\t\tpublic readonly IReadOnlyList<ITypeParameter> TypeParameters;\n\n\t\t\t/// <summary>\n\t\t\t/// Conversions applied to the arguments.\n\t\t\t/// This field is set by the CheckApplicability step.\n\t\t\t/// </summary>\n\t\t\tpublic Conversion[] ArgumentConversions;\n\n\t\t\t/// <summary>\n\t\t\t/// Gets the type of the collection that is used for the 'params' parameter (before any substitution!).\n\t\t\t/// Otherwise returns SpecialType.UnknownType.\n\t\t\t/// </summary>\n\t\t\tpublic IType ParamsCollectionType {\n\t\t\t\tget {\n\t\t\t\t\tif (IsExpandedForm && Parameters.Count > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tIParameter lastParameter = Parameters[Parameters.Count - 1];\n\t\t\t\t\t\tif (lastParameter.IsParams)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn lastParameter.Type;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn SpecialType.UnknownType;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic bool IsGenericMethod {\n\t\t\t\tget {\n\t\t\t\t\tIMethod method = Member as IMethod;\n\t\t\t\t\treturn method != null && method.TypeParameters.Count > 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic int ArgumentsPassedToParams {\n\t\t\t\tget {\n\t\t\t\t\tint count = 0;\n\t\t\t\t\tif (IsExpandedForm)\n\t\t\t\t\t{\n\t\t\t\t\t\tint paramsParameterIndex = this.Parameters.Count - 1;\n\t\t\t\t\t\tforeach (int parameterIndex in ArgumentToParameterMap)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (parameterIndex == paramsParameterIndex)\n\t\t\t\t\t\t\t\tcount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn count;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic Candidate(IParameterizedMember member, bool isExpanded)\n\t\t\t{\n\t\t\t\tthis.Member = member;\n\t\t\t\tthis.IsExpandedForm = isExpanded;\n\t\t\t\tIParameterizedMember memberDefinition = (IParameterizedMember)member.MemberDefinition;\n\t\t\t\t// For specialized methods, go back to the original parameters:\n\t\t\t\t// (without any type parameter substitution, not even class type parameters)\n\t\t\t\t// We'll re-substitute them as part of RunTypeInference().\n\t\t\t\tthis.Parameters = memberDefinition.Parameters;\n\t\t\t\tIMethod methodDefinition = memberDefinition as IMethod;\n\t\t\t\tif (methodDefinition != null && methodDefinition.TypeParameters.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tthis.TypeParameters = methodDefinition.TypeParameters;\n\t\t\t\t}\n\t\t\t\tthis.ParameterTypes = new IType[this.Parameters.Count];\n\t\t\t}\n\n\t\t\tpublic void AddError(OverloadResolutionErrors newError)\n\t\t\t{\n\t\t\t\tthis.Errors |= newError;\n\t\t\t\tif (!IsApplicable(newError))\n\t\t\t\t\tthis.ErrorCount++;\n\t\t\t}\n\t\t}\n\n\t\treadonly ICompilation compilation;\n\t\treadonly ResolveResult[] arguments;\n\t\treadonly string[] argumentNames;\n\t\treadonly CSharpConversions conversions;\n\t\t//List<Candidate> candidates = new List<Candidate>();\n\t\tCandidate bestCandidate;\n\t\tCandidate bestCandidateAmbiguousWith;\n\t\tIType[] explicitlyGivenTypeArguments;\n\t\tbool bestCandidateWasValidated;\n\t\tOverloadResolutionErrors bestCandidateValidationResult;\n\n\t\t#region Constructor\n\t\tpublic OverloadResolution(ICompilation compilation, ResolveResult[] arguments, string[] argumentNames = null, IType[] typeArguments = null, CSharpConversions conversions = null)\n\t\t{\n\t\t\tif (compilation == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(compilation));\n\t\t\tif (arguments == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(arguments));\n\t\t\tif (argumentNames == null)\n\t\t\t\targumentNames = new string[arguments.Length];\n\t\t\telse if (argumentNames.Length != arguments.Length)\n\t\t\t\tthrow new ArgumentException(\"argumentsNames.Length must be equal to arguments.Length\");\n\t\t\tthis.compilation = compilation;\n\t\t\tthis.arguments = arguments;\n\t\t\tthis.argumentNames = argumentNames;\n\n\t\t\t// keep explicitlyGivenTypeArguments==null when no type arguments were specified\n\t\t\tif (typeArguments != null && typeArguments.Length > 0)\n\t\t\t\tthis.explicitlyGivenTypeArguments = typeArguments;\n\n\t\t\tthis.conversions = conversions ?? CSharpConversions.Get(compilation);\n\t\t\tthis.AllowExpandingParams = true;\n\t\t\tthis.AllowOptionalParameters = true;\n\t\t}\n\t\t#endregion\n\n\t\t#region Input Properties\n\t\t/// <summary>\n\t\t/// Gets/Sets whether the methods are extension methods that are being called using extension method syntax.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Setting this property to true restricts the possible conversions on the first argument to\n\t\t/// implicit identity, reference, or boxing conversions.\n\t\t/// </remarks>\n\t\tpublic bool IsExtensionMethodInvocation { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether expanding 'params' into individual elements is allowed.\n\t\t/// The default value is true.\n\t\t/// </summary>\n\t\tpublic bool AllowExpandingParams { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether optional parameters may be left at their default value.\n\t\t/// The default value is true.\n\t\t/// If this property is set to false, optional parameters will be treated like regular parameters.\n\t\t/// </summary>\n\t\tpublic bool AllowOptionalParameters { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether a value argument can be passed to an `in` reference parameter.\n\t\t/// </summary>\n\t\tpublic bool AllowImplicitIn { get; set; } = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether ConversionResolveResults created by this OverloadResolution\n\t\t/// instance apply overflow checking.\n\t\t/// The default value is false.\n\t\t/// </summary>\n\t\tpublic bool CheckForOverflow { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets the arguments for which this OverloadResolution instance was created.\n\t\t/// </summary>\n\t\tpublic IList<ResolveResult> Arguments {\n\t\t\tget { return arguments; }\n\t\t}\n\t\t#endregion\n\n\t\t#region AddCandidate\n\t\t/// <summary>\n\t\t/// Adds a candidate to overload resolution.\n\t\t/// </summary>\n\t\t/// <param name=\"member\">The candidate member to add.</param>\n\t\t/// <returns>The errors that prevent the member from being applicable, if any.\n\t\t/// Note: this method does not return errors that do not affect applicability.</returns>\n\t\tpublic OverloadResolutionErrors AddCandidate(IParameterizedMember member)\n\t\t{\n\t\t\treturn AddCandidate(member, OverloadResolutionErrors.None);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Adds a candidate to overload resolution.\n\t\t/// </summary>\n\t\t/// <param name=\"member\">The candidate member to add.</param>\n\t\t/// <param name=\"additionalErrors\">Additional errors that apply to the candidate.\n\t\t/// This is used to represent errors during member lookup (e.g. OverloadResolutionErrors.Inaccessible)\n\t\t/// in overload resolution.</param>\n\t\t/// <returns>The errors that prevent the member from being applicable, if any.\n\t\t/// Note: this method does not return errors that do not affect applicability.</returns>\n\t\tpublic OverloadResolutionErrors AddCandidate(IParameterizedMember member, OverloadResolutionErrors additionalErrors)\n\t\t{\n\t\t\tif (member == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(member));\n\n\t\t\tCandidate c = new Candidate(member, false);\n\t\t\tc.AddError(additionalErrors);\n\t\t\tif (CalculateCandidate(c))\n\t\t\t{\n\t\t\t\t//candidates.Add(c);\n\t\t\t}\n\n\t\t\tif (this.AllowExpandingParams && member.Parameters.Count > 0\n\t\t\t\t&& member.Parameters[member.Parameters.Count - 1].IsParams)\n\t\t\t{\n\t\t\t\tCandidate expandedCandidate = new Candidate(member, true);\n\t\t\t\texpandedCandidate.AddError(additionalErrors);\n\t\t\t\t// consider expanded form only if it isn't obviously wrong\n\t\t\t\tif (CalculateCandidate(expandedCandidate))\n\t\t\t\t{\n\t\t\t\t\t//candidates.Add(expandedCandidate);\n\n\t\t\t\t\tif (expandedCandidate.ErrorCount < c.ErrorCount)\n\t\t\t\t\t\treturn expandedCandidate.Errors;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn c.Errors;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Calculates applicability etc. for the candidate.\n\t\t/// </summary>\n\t\t/// <returns>True if the calculation was successful, false if the candidate should be removed without reporting an error</returns>\n\t\tbool CalculateCandidate(Candidate candidate)\n\t\t{\n\t\t\tif (!ResolveParameterTypes(candidate, false))\n\t\t\t\treturn false;\n\t\t\tMapCorrespondingParameters(candidate);\n\t\t\tRunTypeInference(candidate);\n\t\t\tCheckApplicability(candidate);\n\t\t\tConsiderIfNewCandidateIsBest(candidate);\n\t\t\treturn true;\n\t\t}\n\n\t\tbool ResolveParameterTypes(Candidate candidate, bool useSpecializedParameters)\n\t\t{\n\t\t\tfor (int i = 0; i < candidate.Parameters.Count; i++)\n\t\t\t{\n\t\t\t\tIType type;\n\t\t\t\tif (useSpecializedParameters)\n\t\t\t\t{\n\t\t\t\t\t// Use the parameter type of the specialized non-generic method or indexer\n\t\t\t\t\tDebug.Assert(!candidate.IsGenericMethod);\n\t\t\t\t\ttype = candidate.Member.Parameters[i].Type;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Use the type of the original formal parameter\n\t\t\t\t\ttype = candidate.Parameters[i].Type;\n\t\t\t\t}\n\t\t\t\tif (candidate.IsExpandedForm && i == candidate.Parameters.Count - 1)\n\t\t\t\t{\n\t\t\t\t\tif (type is ArrayType arrayType && arrayType.Dimensions == 1)\n\t\t\t\t\t\ttype = arrayType.ElementType;\n\t\t\t\t\telse if (type.IsKnownType(KnownTypeCode.ReadOnlySpanOfT) || type.IsKnownType(KnownTypeCode.SpanOfT))\n\t\t\t\t\t\ttype = type.TypeArguments[0];\n\t\t\t\t\telse if (type.IsArrayInterfaceType())\n\t\t\t\t\t\ttype = type.TypeArguments[0];\n\t\t\t\t\telse\n\t\t\t\t\t\treturn false; // error: cannot unpack params-array. abort considering the expanded form for this candidate\n\t\t\t\t}\n\t\t\t\tcandidate.ParameterTypes[i] = type;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\t#endregion\n\n\t\t#region AddMethodLists\n\t\t/// <summary>\n\t\t/// Adds all candidates from the method lists.\n\t\t/// \n\t\t/// This method implements the logic that causes applicable methods in derived types to hide\n\t\t/// all methods in base types.\n\t\t/// </summary>\n\t\t/// <param name=\"methodLists\">The methods, grouped by declaring type. Base types must come first in the list.</param>\n\t\tpublic void AddMethodLists(IReadOnlyList<MethodListWithDeclaringType> methodLists)\n\t\t{\n\t\t\tif (methodLists == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(methodLists));\n\t\t\t// Base types come first, so go through the list backwards (derived types first)\n\t\t\tbool[] isHiddenByDerivedType;\n\t\t\tif (methodLists.Count > 1)\n\t\t\t\tisHiddenByDerivedType = new bool[methodLists.Count];\n\t\t\telse\n\t\t\t\tisHiddenByDerivedType = null;\n\t\t\tfor (int i = methodLists.Count - 1; i >= 0; i--)\n\t\t\t{\n\t\t\t\tif (isHiddenByDerivedType != null && isHiddenByDerivedType[i])\n\t\t\t\t{\n\t\t\t\t\tLog.WriteLine(\"  Skipping methods in {0} because they are hidden by an applicable method in a derived type\", methodLists[i].DeclaringType);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tMethodListWithDeclaringType methodList = methodLists[i];\n\t\t\t\tbool foundApplicableCandidateInCurrentList = false;\n\n\t\t\t\tfor (int j = 0; j < methodList.Count; j++)\n\t\t\t\t{\n\t\t\t\t\tIParameterizedMember method = methodList[j];\n\t\t\t\t\tLog.Indent();\n\t\t\t\t\tOverloadResolutionErrors errors = AddCandidate(method);\n\t\t\t\t\tLog.Unindent();\n\t\t\t\t\tLogCandidateAddingResult(\"  Candidate\", method, errors);\n\n\t\t\t\t\tfoundApplicableCandidateInCurrentList |= IsApplicable(errors);\n\t\t\t\t}\n\n\t\t\t\tif (foundApplicableCandidateInCurrentList && i > 0)\n\t\t\t\t{\n\t\t\t\t\tforeach (IType baseType in methodList.DeclaringType.GetAllBaseTypes())\n\t\t\t\t\t{\n\t\t\t\t\t\tfor (int j = 0; j < i; j++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!isHiddenByDerivedType[j] && baseType.Equals(methodLists[j].DeclaringType))\n\t\t\t\t\t\t\t\tisHiddenByDerivedType[j] = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t[Conditional(\"DEBUG\")]\n\t\tinternal void LogCandidateAddingResult(string text, IParameterizedMember method, OverloadResolutionErrors errors)\n\t\t{\n#if DEBUG\n\t\t\tLog.WriteLine(string.Format(\"{0} {1} = {2}{3}\",\n\t\t\t\t\t\t\t\t\t\ttext, method,\n\t\t\t\t\t\t\t\t\t\terrors == OverloadResolutionErrors.None ? \"Success\" : errors.ToString(),\n\t\t\t\t\t\t\t\t\t\tthis.BestCandidate == method ? \" (best candidate so far)\" :\n\t\t\t\t\t\t\t\t\t\tthis.BestCandidateAmbiguousWith == method ? \" (ambiguous)\" : \"\"\n\t\t\t\t\t\t\t\t\t   ));\n#endif\n\t\t}\n\t\t#endregion\n\n\t\t#region MapCorrespondingParameters\n\t\tvoid MapCorrespondingParameters(Candidate candidate)\n\t\t{\n\t\t\t// C# 4.0 spec: §7.5.1.1 Corresponding parameters\n\t\t\t// Updated for C# 7.2 non-trailing named arguments\n\t\t\tcandidate.ArgumentToParameterMap = new int[arguments.Length];\n\t\t\tbool hasPositionalArgument = false;\n\t\t\t// go backwards, so that hasPositionalArgument tells us whether there\n\t\t\t// are non-trailing named arguments\n\t\t\tfor (int i = arguments.Length - 1; i >= 0; i--)\n\t\t\t{\n\t\t\t\tcandidate.ArgumentToParameterMap[i] = -1;\n\t\t\t\tif (argumentNames[i] == null || hasPositionalArgument)\n\t\t\t\t{\n\t\t\t\t\thasPositionalArgument = true;\n\t\t\t\t\t// positional argument or non-trailing named argument\n\t\t\t\t\tif (i < candidate.ParameterTypes.Length)\n\t\t\t\t\t{\n\t\t\t\t\t\tcandidate.ArgumentToParameterMap[i] = i;\n\t\t\t\t\t\tif (argumentNames[i] != null && argumentNames[i] != candidate.Parameters[i].Name)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// non-trailing named argument must match name\n\t\t\t\t\t\t\tcandidate.AddError(OverloadResolutionErrors.NoParameterFoundForNamedArgument);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (candidate.IsExpandedForm)\n\t\t\t\t\t{\n\t\t\t\t\t\tcandidate.ArgumentToParameterMap[i] = candidate.ParameterTypes.Length - 1;\n\t\t\t\t\t\tif (argumentNames[i] != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// can't use non-trailing named argument here\n\t\t\t\t\t\t\tcandidate.AddError(OverloadResolutionErrors.NoParameterFoundForNamedArgument);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tcandidate.AddError(OverloadResolutionErrors.TooManyPositionalArguments);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// (trailing) named argument\n\t\t\t\t\tfor (int j = 0; j < candidate.Parameters.Count; j++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (argumentNames[i] == candidate.Parameters[j].Name)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcandidate.ArgumentToParameterMap[i] = j;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (candidate.ArgumentToParameterMap[i] < 0)\n\t\t\t\t\t\tcandidate.AddError(OverloadResolutionErrors.NoParameterFoundForNamedArgument);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region RunTypeInference\n\t\tvoid RunTypeInference(Candidate candidate)\n\t\t{\n\t\t\tif (candidate.TypeParameters == null)\n\t\t\t{\n\t\t\t\tif (explicitlyGivenTypeArguments != null)\n\t\t\t\t{\n\t\t\t\t\t// method does not expect type arguments, but was given some\n\t\t\t\t\tcandidate.AddError(OverloadResolutionErrors.WrongNumberOfTypeArguments);\n\t\t\t\t}\n\t\t\t\t// Grab new parameter types:\n\t\t\t\tResolveParameterTypes(candidate, true);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tParameterizedType parameterizedDeclaringType = candidate.Member.DeclaringType as ParameterizedType;\n\t\t\tIReadOnlyList<IType> classTypeArguments;\n\t\t\tif (parameterizedDeclaringType != null)\n\t\t\t{\n\t\t\t\tclassTypeArguments = parameterizedDeclaringType.TypeArguments;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tclassTypeArguments = null;\n\t\t\t}\n\t\t\t// The method is generic:\n\t\t\tif (explicitlyGivenTypeArguments != null)\n\t\t\t{\n\t\t\t\tif (explicitlyGivenTypeArguments.Length == candidate.TypeParameters.Count)\n\t\t\t\t{\n\t\t\t\t\tcandidate.InferredTypes = explicitlyGivenTypeArguments;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcandidate.AddError(OverloadResolutionErrors.WrongNumberOfTypeArguments);\n\t\t\t\t\t// wrong number of type arguments given, so truncate the list or pad with UnknownType\n\t\t\t\t\tcandidate.InferredTypes = new IType[candidate.TypeParameters.Count];\n\t\t\t\t\tfor (int i = 0; i < candidate.InferredTypes.Length; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (i < explicitlyGivenTypeArguments.Length)\n\t\t\t\t\t\t\tcandidate.InferredTypes[i] = explicitlyGivenTypeArguments[i];\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tcandidate.InferredTypes[i] = SpecialType.UnknownType;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tTypeInference ti = new TypeInference(compilation, conversions);\n\t\t\t\tIType[] parameterTypes = candidate.ArgumentToParameterMap\n\t\t\t\t\t.SelectReadOnlyArray(parameterIndex => parameterIndex >= 0 ? candidate.ParameterTypes[parameterIndex] : SpecialType.UnknownType);\n\t\t\t\tbool success;\n\t\t\t\tcandidate.InferredTypes = ti.InferTypeArguments(candidate.TypeParameters, arguments, parameterTypes, out success, classTypeArguments);\n\t\t\t\tif (!success)\n\t\t\t\t\tcandidate.AddError(OverloadResolutionErrors.TypeInferenceFailed);\n\t\t\t}\n\t\t\t// Now substitute in the formal parameters:\n\t\t\tvar substitution = new ConstraintValidatingSubstitution(classTypeArguments, candidate.InferredTypes, this);\n\t\t\tfor (int i = 0; i < candidate.ParameterTypes.Length; i++)\n\t\t\t{\n\t\t\t\tcandidate.ParameterTypes[i] = candidate.ParameterTypes[i].AcceptVisitor(substitution);\n\t\t\t}\n\t\t\tif (!substitution.ConstraintsValid)\n\t\t\t\tcandidate.AddError(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint);\n\t\t}\n\n\t\tsealed class ConstraintValidatingSubstitution : TypeParameterSubstitution\n\t\t{\n\t\t\treadonly CSharpConversions conversions;\n\t\t\tpublic bool ConstraintsValid = true;\n\n\t\t\tpublic ConstraintValidatingSubstitution(IReadOnlyList<IType> classTypeArguments, IReadOnlyList<IType> methodTypeArguments, OverloadResolution overloadResolution)\n\t\t\t\t: base(classTypeArguments, methodTypeArguments)\n\t\t\t{\n\t\t\t\tthis.conversions = overloadResolution.conversions;\n\t\t\t}\n\n\t\t\tpublic override IType VisitParameterizedType(ParameterizedType type)\n\t\t\t{\n\t\t\t\tIType newType = base.VisitParameterizedType(type);\n\t\t\t\tif (newType != type && ConstraintsValid)\n\t\t\t\t{\n\t\t\t\t\t// something was changed, so we need to validate the constraints\n\t\t\t\t\tParameterizedType newParameterizedType = newType as ParameterizedType;\n\t\t\t\t\tif (newParameterizedType != null)\n\t\t\t\t\t{\n\t\t\t\t\t\t// C# 4.0 spec: §4.4.4 Satisfying constraints\n\t\t\t\t\t\tvar typeParameters = newParameterizedType.TypeParameters;\n\t\t\t\t\t\tvar substitution = newParameterizedType.GetSubstitution();\n\t\t\t\t\t\tfor (int i = 0; i < typeParameters.Count; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!ValidateConstraints(typeParameters[i], newParameterizedType.GetTypeArgument(i), substitution, conversions))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tConstraintsValid = false;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn newType;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Validate Constraints\n\t\tOverloadResolutionErrors ValidateMethodConstraints(Candidate candidate)\n\t\t{\n\t\t\t// If type inference already failed, we won't check the constraints:\n\t\t\tif ((candidate.Errors & OverloadResolutionErrors.TypeInferenceFailed) != 0)\n\t\t\t\treturn OverloadResolutionErrors.None;\n\n\t\t\tif (candidate.TypeParameters == null || candidate.TypeParameters.Count == 0)\n\t\t\t\treturn OverloadResolutionErrors.None; // the method isn't generic\n\t\t\tvar substitution = GetSubstitution(candidate);\n\t\t\tfor (int i = 0; i < candidate.TypeParameters.Count; i++)\n\t\t\t{\n\t\t\t\tif (!ValidateConstraints(candidate.TypeParameters[i], substitution.MethodTypeArguments[i], substitution))\n\t\t\t\t\treturn OverloadResolutionErrors.MethodConstraintsNotSatisfied;\n\t\t\t}\n\t\t\treturn OverloadResolutionErrors.None;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Validates whether the given type argument satisfies the constraints for the given type parameter.\n\t\t/// </summary>\n\t\t/// <param name=\"typeParameter\">The type parameter.</param>\n\t\t/// <param name=\"typeArgument\">The type argument.</param>\n\t\t/// <param name=\"substitution\">The substitution that defines how type parameters are replaced with type arguments.\n\t\t/// The substitution is used to check constraints that depend on other type parameters (or recursively on the same type parameter).\n\t\t/// May be null if no substitution should be used.</param>\n\t\t/// <returns>True if the constraints are satisfied; false otherwise.</returns>\n\t\tpublic static bool ValidateConstraints(ITypeParameter typeParameter, IType typeArgument, TypeVisitor substitution = null)\n\t\t{\n\t\t\tif (typeParameter == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(typeParameter));\n\t\t\tif (typeArgument == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(typeArgument));\n\t\t\treturn ValidateConstraints(typeParameter, typeArgument, substitution, CSharpConversions.Get(typeParameter.Owner.Compilation));\n\t\t}\n\n\t\tinternal static bool ValidateConstraints(ITypeParameter typeParameter, IType typeArgument, TypeVisitor substitution, CSharpConversions conversions)\n\t\t{\n\t\t\tswitch (typeArgument.Kind)\n\t\t\t{ // void, null, and pointers cannot be used as type arguments\n\t\t\t\tcase TypeKind.Void:\n\t\t\t\tcase TypeKind.Null:\n\t\t\t\tcase TypeKind.Pointer:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (typeParameter.HasReferenceTypeConstraint)\n\t\t\t{\n\t\t\t\tif (typeArgument.IsReferenceType != true)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (typeParameter.HasValueTypeConstraint)\n\t\t\t{\n\t\t\t\tif (!NullableType.IsNonNullableValueType(typeArgument))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (typeParameter.HasDefaultConstructorConstraint)\n\t\t\t{\n\t\t\t\tITypeDefinition def = typeArgument.GetDefinition();\n\t\t\t\tif (def != null && def.IsAbstract)\n\t\t\t\t\treturn false;\n\t\t\t\tvar ctors = typeArgument.GetConstructors(\n\t\t\t\t\tm => m.Parameters.Count == 0 && m.Accessibility == Accessibility.Public,\n\t\t\t\t\tGetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions\n\t\t\t\t);\n\t\t\t\tif (!ctors.Any())\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tforeach (IType constraintType in typeParameter.DirectBaseTypes)\n\t\t\t{\n\t\t\t\tIType c = constraintType;\n\t\t\t\tif (substitution != null)\n\t\t\t\t\tc = c.AcceptVisitor(substitution);\n\t\t\t\tif (!conversions.IsConstraintConvertible(typeArgument, c))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\t#endregion\n\n\t\t#region CheckApplicability\n\t\t/// <summary>\n\t\t/// Returns whether a candidate with the given errors is still considered to be applicable.\n\t\t/// </summary>\n\t\tpublic static bool IsApplicable(OverloadResolutionErrors errors)\n\t\t{\n\t\t\tconst OverloadResolutionErrors errorsThatDoNotMatterForApplicability =\n\t\t\t\tOverloadResolutionErrors.AmbiguousMatch | OverloadResolutionErrors.MethodConstraintsNotSatisfied;\n\t\t\treturn (errors & ~errorsThatDoNotMatterForApplicability) == OverloadResolutionErrors.None;\n\t\t}\n\n\t\tvoid CheckApplicability(Candidate candidate)\n\t\t{\n\t\t\t// C# 4.0 spec: §7.5.3.1 Applicable function member\n\n\t\t\t// Test whether parameters were mapped the correct number of arguments:\n\t\t\tint[] argumentCountPerParameter = new int[candidate.ParameterTypes.Length];\n\t\t\tforeach (int parameterIndex in candidate.ArgumentToParameterMap)\n\t\t\t{\n\t\t\t\tif (parameterIndex >= 0)\n\t\t\t\t\targumentCountPerParameter[parameterIndex]++;\n\t\t\t}\n\t\t\tfor (int i = 0; i < argumentCountPerParameter.Length; i++)\n\t\t\t{\n\t\t\t\tif (candidate.IsExpandedForm && i == argumentCountPerParameter.Length - 1)\n\t\t\t\t\tcontinue; // any number of arguments is fine for the params-array\n\t\t\t\tif (argumentCountPerParameter[i] == 0)\n\t\t\t\t{\n\t\t\t\t\tif (this.AllowOptionalParameters && candidate.Parameters[i].IsOptional)\n\t\t\t\t\t\tcandidate.HasUnmappedOptionalParameters = true;\n\t\t\t\t\telse\n\t\t\t\t\t\tcandidate.AddError(OverloadResolutionErrors.MissingArgumentForRequiredParameter);\n\t\t\t\t}\n\t\t\t\telse if (argumentCountPerParameter[i] > 1)\n\t\t\t\t{\n\t\t\t\t\tcandidate.AddError(OverloadResolutionErrors.MultipleArgumentsForSingleParameter);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcandidate.ArgumentConversions = new Conversion[arguments.Length];\n\t\t\t// Test whether argument passing mode matches the parameter passing mode\n\t\t\tfor (int i = 0; i < arguments.Length; i++)\n\t\t\t{\n\t\t\t\tint parameterIndex = candidate.ArgumentToParameterMap[i];\n\t\t\t\tif (parameterIndex < 0)\n\t\t\t\t{\n\t\t\t\t\tcandidate.ArgumentConversions[i] = Conversion.None;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tReferenceKind paramRefKind = candidate.Parameters[parameterIndex].ReferenceKind;\n\t\t\t\tif (arguments[i] is ByReferenceResolveResult brrr)\n\t\t\t\t{\n\t\t\t\t\tif (brrr.ReferenceKind != paramRefKind)\n\t\t\t\t\t\tcandidate.AddError(OverloadResolutionErrors.ParameterPassingModeMismatch);\n\t\t\t\t}\n\t\t\t\telse if (arguments[i] is OutVarResolveResult)\n\t\t\t\t{\n\t\t\t\t\tif (paramRefKind != ReferenceKind.Out)\n\t\t\t\t\t\tcandidate.AddError(OverloadResolutionErrors.ParameterPassingModeMismatch);\n\t\t\t\t\t// 'out var decl' arguments are compatible with any out parameter\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// AllowImplicitIn: `in` parameters can be filled implicitly without `in` DirectionExpression\n\t\t\t\t\t// IsExtensionMethodInvocation: `this ref` and `this in` parameters can be filled implicitly\n\t\t\t\t\tif (((paramRefKind is ReferenceKind.In or ReferenceKind.RefReadOnly && AllowImplicitIn)\n\t\t\t\t\t\t|| (IsExtensionMethodInvocation && parameterIndex == 0 && (paramRefKind is ReferenceKind.In or ReferenceKind.Ref or ReferenceKind.RefReadOnly))\n\t\t\t\t\t\t) && candidate.ParameterTypes[parameterIndex].SkipModifiers() is ByReferenceType brt)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Treat the parameter as if it was not declared \"in\" for the following steps\n\t\t\t\t\t\t// (applicability + better function member)\n\t\t\t\t\t\tcandidate.ParameterTypes[parameterIndex] = brt.ElementType;\n\t\t\t\t\t}\n\t\t\t\t\telse if (paramRefKind != ReferenceKind.None)\n\t\t\t\t\t{\n\t\t\t\t\t\tcandidate.AddError(OverloadResolutionErrors.ParameterPassingModeMismatch);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tIType parameterType = candidate.ParameterTypes[parameterIndex];\n\t\t\t\tConversion c = conversions.ImplicitConversion(arguments[i], parameterType);\n\t\t\t\tcandidate.ArgumentConversions[i] = c;\n\t\t\t\tif (IsExtensionMethodInvocation && parameterIndex == 0)\n\t\t\t\t{\n\t\t\t\t\t// First parameter to extension method must be an identity, reference, boxing or span conversion\n\t\t\t\t\tif (!(c == Conversion.IdentityConversion || c == Conversion.ImplicitReferenceConversion || c == Conversion.BoxingConversion || c == Conversion.ImplicitSpanConversion))\n\t\t\t\t\t\tcandidate.AddError(OverloadResolutionErrors.ArgumentTypeMismatch);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif ((!c.IsValid && !c.IsUserDefined && !c.IsMethodGroupConversion) && parameterType.Kind != TypeKind.Unknown)\n\t\t\t\t\t\tcandidate.AddError(OverloadResolutionErrors.ArgumentTypeMismatch);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region BetterFunctionMember\n\t\t/// <summary>\n\t\t/// Returns 1 if c1 is better than c2; 2 if c2 is better than c1; or 0 if neither is better.\n\t\t/// </summary>\n\t\tint BetterFunctionMember(Candidate c1, Candidate c2)\n\t\t{\n\t\t\t// prefer applicable members (part of heuristic that produces a best candidate even if none is applicable)\n\t\t\tif (c1.ErrorCount == 0 && c2.ErrorCount > 0)\n\t\t\t\treturn 1;\n\t\t\tif (c1.ErrorCount > 0 && c2.ErrorCount == 0)\n\t\t\t\treturn 2;\n\n\t\t\t// C# 4.0 spec: §7.5.3.2 Better function member\n\t\t\tbool c1IsBetter = false;\n\t\t\tbool c2IsBetter = false;\n\t\t\tbool parameterTypesEqual = true;\n\t\t\tfor (int i = 0; i < arguments.Length; i++)\n\t\t\t{\n\t\t\t\tint p1 = c1.ArgumentToParameterMap[i];\n\t\t\t\tint p2 = c2.ArgumentToParameterMap[i];\n\t\t\t\tif (p1 >= 0 && p2 < 0)\n\t\t\t\t{\n\t\t\t\t\tc1IsBetter = true;\n\t\t\t\t}\n\t\t\t\telse if (p1 < 0 && p2 >= 0)\n\t\t\t\t{\n\t\t\t\t\tc2IsBetter = true;\n\t\t\t\t}\n\t\t\t\telse if (p1 >= 0 && p2 >= 0)\n\t\t\t\t{\n\t\t\t\t\tif (!conversions.IdentityConversion(c1.ParameterTypes[p1], c2.ParameterTypes[p2]))\n\t\t\t\t\t\tparameterTypesEqual = false;\n\t\t\t\t\tswitch (conversions.BetterConversion(arguments[i], c1.ParameterTypes[p1], c2.ParameterTypes[p2]))\n\t\t\t\t\t{\n\t\t\t\t\t\tcase 1:\n\t\t\t\t\t\t\tc1IsBetter = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\tc2IsBetter = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (c1IsBetter && !c2IsBetter)\n\t\t\t\treturn 1;\n\t\t\tif (!c1IsBetter && c2IsBetter)\n\t\t\t\treturn 2;\n\n\t\t\t// prefer members with less errors (part of heuristic that produces a best candidate even if none is applicable)\n\t\t\tif (c1.ErrorCount < c2.ErrorCount)\n\t\t\t\treturn 1;\n\t\t\tif (c1.ErrorCount > c2.ErrorCount)\n\t\t\t\treturn 2;\n\n\t\t\tif (!c1IsBetter && !c2IsBetter && parameterTypesEqual)\n\t\t\t{\n\t\t\t\t// we need the tie-breaking rules\n\n\t\t\t\t// non-generic methods are better\n\t\t\t\tif (!c1.IsGenericMethod && c2.IsGenericMethod)\n\t\t\t\t\treturn 1;\n\t\t\t\telse if (c1.IsGenericMethod && !c2.IsGenericMethod)\n\t\t\t\t\treturn 2;\n\n\t\t\t\t// non-expanded members are better\n\t\t\t\tif (!c1.IsExpandedForm && c2.IsExpandedForm)\n\t\t\t\t\treturn 1;\n\t\t\t\telse if (c1.IsExpandedForm && !c2.IsExpandedForm)\n\t\t\t\t\treturn 2;\n\n\t\t\t\t// prefer the member with less arguments mapped to the params-collection\n\t\t\t\tint r = c1.ArgumentsPassedToParams.CompareTo(c2.ArgumentsPassedToParams);\n\t\t\t\tif (r < 0)\n\t\t\t\t\treturn 1;\n\t\t\t\telse if (r > 0)\n\t\t\t\t\treturn 2;\n\n\t\t\t\t// prefer the member where no default values need to be substituted\n\t\t\t\tif (!c1.HasUnmappedOptionalParameters && c2.HasUnmappedOptionalParameters)\n\t\t\t\t\treturn 1;\n\t\t\t\telse if (c1.HasUnmappedOptionalParameters && !c2.HasUnmappedOptionalParameters)\n\t\t\t\t\treturn 2;\n\n\t\t\t\t// compare the formal parameters\n\t\t\t\tr = MoreSpecificFormalParameters(c1, c2);\n\t\t\t\tif (r != 0)\n\t\t\t\t\treturn r;\n\n\t\t\t\t// prefer non-lifted operators\n\t\t\t\tILiftedOperator lift1 = c1.Member as ILiftedOperator;\n\t\t\t\tILiftedOperator lift2 = c2.Member as ILiftedOperator;\n\t\t\t\tif (lift1 == null && lift2 != null)\n\t\t\t\t\treturn 1;\n\t\t\t\tif (lift1 != null && lift2 == null)\n\t\t\t\t\treturn 2;\n\n\t\t\t\t// prefer by-value parameters over in-parameters\n\t\t\t\tr = BetterParameterPassingChoice(c1, c2);\n\t\t\t\tif (r != 0)\n\t\t\t\t\treturn r;\n\n\t\t\t\tif (c1.IsExpandedForm)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(c2.IsExpandedForm);\n\t\t\t\t\tr = BetterParamsCollectionType(c1.ParamsCollectionType, c2.ParamsCollectionType);\n\t\t\t\t\tif (r != 0)\n\t\t\t\t\t\treturn r;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\n\t\tint BetterParamsCollectionType(IType paramsCollectionType1, IType paramsCollectionType2)\n\t\t{\n\t\t\t// see https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-13.0/params-collections#better-function-member\n\t\t\tbool isSpan1 = paramsCollectionType1.IsKnownType(KnownTypeCode.SpanOfT) || paramsCollectionType1.IsKnownType(KnownTypeCode.ReadOnlySpanOfT);\n\t\t\tbool isSpan2 = paramsCollectionType2.IsKnownType(KnownTypeCode.SpanOfT) || paramsCollectionType2.IsKnownType(KnownTypeCode.ReadOnlySpanOfT);\n\t\t\tif (!isSpan1 && !isSpan2)\n\t\t\t{\n\t\t\t\tbool implicitConversion1to2 = conversions.ImplicitConversion(paramsCollectionType1, paramsCollectionType2).IsValid;\n\t\t\t\tbool implicitConversion2to1 = conversions.ImplicitConversion(paramsCollectionType2, paramsCollectionType1).IsValid;\n\t\t\t\tif (implicitConversion1to2 && !implicitConversion2to1)\n\t\t\t\t\treturn 1;\n\t\t\t\tif (!implicitConversion1to2 && implicitConversion2to1)\n\t\t\t\t\treturn 2;\n\t\t\t}\n\t\t\telse if (paramsCollectionType1.IsKnownType(KnownTypeCode.ReadOnlySpanOfT) && paramsCollectionType2.IsKnownType(KnownTypeCode.SpanOfT))\n\t\t\t{\n\t\t\t\tif (conversions.IdentityConversion(paramsCollectionType1.TypeArguments[0], paramsCollectionType2.TypeArguments[0]))\n\t\t\t\t\treturn 1; // ReadOnlySpan<T> is better than Span<T> if there exists an identity conversion between the element types\n\t\t\t}\n\t\t\telse if (paramsCollectionType2.IsKnownType(KnownTypeCode.ReadOnlySpanOfT) && paramsCollectionType1.IsKnownType(KnownTypeCode.SpanOfT))\n\t\t\t{\n\t\t\t\tif (conversions.IdentityConversion(paramsCollectionType2.TypeArguments[0], paramsCollectionType1.TypeArguments[0]))\n\t\t\t\t\treturn 2; // ReadOnlySpan<T> is better than Span<T> if there exists an identity conversion between the element types\n\t\t\t}\n\t\t\telse if (isSpan1 && IsArrayOrArrayInterfaceType(paramsCollectionType2, out var elementType2))\n\t\t\t{\n\t\t\t\tif (conversions.IdentityConversion(paramsCollectionType1.TypeArguments[0], elementType2))\n\t\t\t\t\treturn 1; // Span<T> is better than an array type if there exists an identity conversion between the element types\n\t\t\t}\n\t\t\telse if (isSpan2 && IsArrayOrArrayInterfaceType(paramsCollectionType1, out var elementType1))\n\t\t\t{\n\t\t\t\tif (conversions.IdentityConversion(paramsCollectionType2.TypeArguments[0], elementType1))\n\t\t\t\t\treturn 2; // Span<T> is better than an array type if there exists an identity conversion between the element types\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\n\t\tbool IsArrayOrArrayInterfaceType(IType type, out IType elementType)\n\t\t{\n\t\t\telementType = null;\n\t\t\tif (type is ArrayType arrayType)\n\t\t\t{\n\t\t\t\telementType = arrayType.ElementType;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (type.IsArrayInterfaceType())\n\t\t\t{\n\t\t\t\telementType = type.TypeArguments[0];\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tint BetterParameterPassingChoice(Candidate c1, Candidate c2)\n\t\t{\n\t\t\tDebug.Assert(c1.Parameters.Count == c2.Parameters.Count, \"c1 and c2 must have the same number of parameters\");\n\n\t\t\tbool c1IsBetter = false;\n\t\t\tbool c2IsBetter = false;\n\n\t\t\tfor (int i = 0; i < c1.Parameters.Count; i++)\n\t\t\t{\n\t\t\t\tReferenceKind refKind1 = c1.Parameters[i].ReferenceKind;\n\t\t\t\tReferenceKind refKind2 = c2.Parameters[i].ReferenceKind;\n\n\t\t\t\tif (refKind1 == ReferenceKind.None && refKind2 == ReferenceKind.In)\n\t\t\t\t\tc1IsBetter = true; // by-value is better than in\n\t\t\t\tif (refKind1 == ReferenceKind.In && refKind2 == ReferenceKind.None)\n\t\t\t\t\tc2IsBetter = true;\n\t\t\t}\n\n\t\t\tif (c1IsBetter && !c2IsBetter)\n\t\t\t\treturn 1;\n\t\t\tif (!c1IsBetter && c2IsBetter)\n\t\t\t\treturn 2;\n\n\t\t\treturn 0;\n\t\t}\n\n\t\tint MoreSpecificFormalParameters(Candidate c1, Candidate c2)\n\t\t{\n\t\t\t// prefer the member with more formal parameters (in case both have different number of optional parameters)\n\t\t\tint r = c1.Parameters.Count.CompareTo(c2.Parameters.Count);\n\t\t\tif (r > 0)\n\t\t\t\treturn 1;\n\t\t\telse if (r < 0)\n\t\t\t\treturn 2;\n\n\t\t\treturn MoreSpecificFormalParameters(c1.Parameters.Select(p => p.Type), c2.Parameters.Select(p => p.Type));\n\t\t}\n\n\t\tstatic int MoreSpecificFormalParameters(IEnumerable<IType> t1, IEnumerable<IType> t2)\n\t\t{\n\t\t\tbool c1IsBetter = false;\n\t\t\tbool c2IsBetter = false;\n\t\t\tforeach (var pair in t1.Zip(t2, (a, b) => new { Item1 = a, Item2 = b }))\n\t\t\t{\n\t\t\t\tswitch (MoreSpecificFormalParameter(pair.Item1, pair.Item2))\n\t\t\t\t{\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tc1IsBetter = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tc2IsBetter = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (c1IsBetter && !c2IsBetter)\n\t\t\t\treturn 1;\n\t\t\tif (!c1IsBetter && c2IsBetter)\n\t\t\t\treturn 2;\n\t\t\treturn 0;\n\t\t}\n\n\t\tstatic int MoreSpecificFormalParameter(IType t1, IType t2)\n\t\t{\n\t\t\tif ((t1 is ITypeParameter) && !(t2 is ITypeParameter))\n\t\t\t\treturn 2;\n\t\t\tif ((t2 is ITypeParameter) && !(t1 is ITypeParameter))\n\t\t\t\treturn 1;\n\n\t\t\tParameterizedType p1 = t1 as ParameterizedType;\n\t\t\tParameterizedType p2 = t2 as ParameterizedType;\n\t\t\tif (p1 != null && p2 != null && p1.TypeParameterCount == p2.TypeParameterCount)\n\t\t\t{\n\t\t\t\tint r = MoreSpecificFormalParameters(p1.TypeArguments, p2.TypeArguments);\n\t\t\t\tif (r > 0)\n\t\t\t\t\treturn r;\n\t\t\t}\n\t\t\tTypeWithElementType tew1 = t1 as TypeWithElementType;\n\t\t\tTypeWithElementType tew2 = t2 as TypeWithElementType;\n\t\t\tif (tew1 != null && tew2 != null)\n\t\t\t{\n\t\t\t\treturn MoreSpecificFormalParameter(tew1.ElementType, tew2.ElementType);\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\t\t#endregion\n\n\t\t#region ConsiderIfNewCandidateIsBest\n\t\tvoid ConsiderIfNewCandidateIsBest(Candidate candidate)\n\t\t{\n\t\t\tif (bestCandidate == null)\n\t\t\t{\n\t\t\t\tbestCandidate = candidate;\n\t\t\t\tbestCandidateWasValidated = false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tswitch (BetterFunctionMember(candidate, bestCandidate))\n\t\t\t\t{\n\t\t\t\t\tcase 0:\n\t\t\t\t\t\t// Overwrite 'bestCandidateAmbiguousWith' so that API users can\n\t\t\t\t\t\t// detect the set of all ambiguous methods if they look at\n\t\t\t\t\t\t// bestCandidateAmbiguousWith after each step.\n\t\t\t\t\t\tbestCandidateAmbiguousWith = candidate;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tbestCandidate = candidate;\n\t\t\t\t\t\tbestCandidateWasValidated = false;\n\t\t\t\t\t\tbestCandidateAmbiguousWith = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t// case 2: best candidate stays best\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Output Properties\n\t\tpublic IParameterizedMember BestCandidate {\n\t\t\tget { return bestCandidate != null ? bestCandidate.Member : null; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the errors that apply to the best candidate.\n\t\t/// This includes additional errors that do not affect applicability (e.g. AmbiguousMatch, MethodConstraintsNotSatisfied)\n\t\t/// </summary>\n\t\tpublic OverloadResolutionErrors BestCandidateErrors {\n\t\t\tget {\n\t\t\t\tif (bestCandidate == null)\n\t\t\t\t\treturn OverloadResolutionErrors.None;\n\t\t\t\tif (!bestCandidateWasValidated)\n\t\t\t\t{\n\t\t\t\t\tbestCandidateValidationResult = ValidateMethodConstraints(bestCandidate);\n\t\t\t\t\tbestCandidateWasValidated = true;\n\t\t\t\t}\n\t\t\t\tOverloadResolutionErrors err = bestCandidate.Errors | bestCandidateValidationResult;\n\t\t\t\tif (bestCandidateAmbiguousWith != null)\n\t\t\t\t\terr |= OverloadResolutionErrors.AmbiguousMatch;\n\t\t\t\treturn err;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool FoundApplicableCandidate {\n\t\t\tget { return bestCandidate != null && IsApplicable(bestCandidate.Errors); }\n\t\t}\n\n\t\tpublic IParameterizedMember BestCandidateAmbiguousWith {\n\t\t\tget { return bestCandidateAmbiguousWith != null ? bestCandidateAmbiguousWith.Member : null; }\n\t\t}\n\n\t\tpublic bool BestCandidateIsExpandedForm {\n\t\t\tget { return bestCandidate != null ? bestCandidate.IsExpandedForm : false; }\n\t\t}\n\n\t\tpublic bool IsAmbiguous {\n\t\t\tget { return bestCandidateAmbiguousWith != null; }\n\t\t}\n\n\t\tpublic IReadOnlyList<IType> InferredTypeArguments {\n\t\t\tget {\n\t\t\t\tif (bestCandidate != null && bestCandidate.InferredTypes != null)\n\t\t\t\t\treturn bestCandidate.InferredTypes;\n\t\t\t\telse\n\t\t\t\t\treturn EmptyList<IType>.Instance;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the implicit conversions that are being applied to the arguments.\n\t\t/// </summary>\n\t\tpublic IList<Conversion> ArgumentConversions {\n\t\t\tget {\n\t\t\t\tif (bestCandidate != null && bestCandidate.ArgumentConversions != null)\n\t\t\t\t\treturn bestCandidate.ArgumentConversions;\n\t\t\t\telse\n\t\t\t\t\treturn Enumerable.Repeat(Conversion.None, arguments.Length).ToList();\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets an array that maps argument indices to parameter indices.\n\t\t/// For arguments that could not be mapped to any parameter, the value will be -1.\n\t\t/// \n\t\t/// parameterIndex = GetArgumentToParameterMap()[argumentIndex]\n\t\t/// </summary>\n\t\tpublic IReadOnlyList<int> GetArgumentToParameterMap()\n\t\t{\n\t\t\tif (bestCandidate != null)\n\t\t\t\treturn bestCandidate.ArgumentToParameterMap;\n\t\t\telse\n\t\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the arguments for the method call in the order they were provided (not in the order of the parameters).\n\t\t/// Arguments are wrapped in a <see cref=\"ConversionResolveResult\"/> if an implicit conversion is being applied\n\t\t/// to them when calling the method.\n\t\t/// </summary>\n\t\tpublic IList<ResolveResult> GetArgumentsWithConversions()\n\t\t{\n\t\t\tif (bestCandidate == null)\n\t\t\t\treturn arguments;\n\t\t\telse\n\t\t\t\treturn GetArgumentsWithConversions(null, null);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the arguments for the method call in the order they were provided (not in the order of the parameters).\n\t\t/// Arguments are wrapped in a <see cref=\"ConversionResolveResult\"/> if an implicit conversion is being applied\n\t\t/// to them when calling the method.\n\t\t/// For arguments where an explicit argument name was provided, the argument will\n\t\t/// be wrapped in a <see cref=\"NamedArgumentResolveResult\"/>.\n\t\t/// </summary>\n\t\tpublic IList<ResolveResult> GetArgumentsWithConversionsAndNames()\n\t\t{\n\t\t\tif (bestCandidate == null)\n\t\t\t\treturn arguments;\n\t\t\telse\n\t\t\t\treturn GetArgumentsWithConversions(null, GetBestCandidateWithSubstitutedTypeArguments());\n\t\t}\n\n\t\tIList<ResolveResult> GetArgumentsWithConversions(ResolveResult targetResolveResult, IParameterizedMember bestCandidateForNamedArguments)\n\t\t{\n\t\t\tvar conversions = this.ArgumentConversions;\n\t\t\tResolveResult[] args = new ResolveResult[arguments.Length];\n\t\t\tfor (int i = 0; i < args.Length; i++)\n\t\t\t{\n\t\t\t\tvar argument = arguments[i];\n\t\t\t\tif (this.IsExtensionMethodInvocation && i == 0 && targetResolveResult != null)\n\t\t\t\t\targument = targetResolveResult;\n\t\t\t\tint parameterIndex = bestCandidate.ArgumentToParameterMap[i];\n\t\t\t\tif (parameterIndex >= 0 && conversions[i] != Conversion.IdentityConversion)\n\t\t\t\t{\n\t\t\t\t\t// Wrap argument in ConversionResolveResult\n\t\t\t\t\tIType parameterType = bestCandidate.ParameterTypes[parameterIndex];\n\t\t\t\t\tif (parameterType.Kind != TypeKind.Unknown)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (arguments[i].IsCompileTimeConstant && conversions[i].IsValid && !conversions[i].IsUserDefined)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\targument = new CSharpResolver(compilation).WithCheckForOverflow(CheckForOverflow).ResolveCast(parameterType, argument);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\targument = new ConversionResolveResult(parameterType, argument, conversions[i], CheckForOverflow);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (bestCandidateForNamedArguments != null && argumentNames[i] != null)\n\t\t\t\t{\n\t\t\t\t\t// Wrap argument in NamedArgumentResolveResult\n\t\t\t\t\tif (parameterIndex >= 0)\n\t\t\t\t\t{\n\t\t\t\t\t\targument = new NamedArgumentResolveResult(bestCandidateForNamedArguments.Parameters[parameterIndex], argument, bestCandidateForNamedArguments);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\targument = new NamedArgumentResolveResult(argumentNames[i], argument);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\targs[i] = argument;\n\t\t\t}\n\t\t\treturn args;\n\t\t}\n\n\t\tpublic IParameterizedMember GetBestCandidateWithSubstitutedTypeArguments()\n\t\t{\n\t\t\tif (bestCandidate == null)\n\t\t\t\treturn null;\n\t\t\tIMethod method = bestCandidate.Member as IMethod;\n\t\t\tif (method != null && method.TypeParameters.Count > 0)\n\t\t\t{\n\t\t\t\treturn ((IMethod)method.MemberDefinition).Specialize(GetSubstitution(bestCandidate));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn bestCandidate.Member;\n\t\t\t}\n\t\t}\n\n\t\tTypeParameterSubstitution GetSubstitution(Candidate candidate)\n\t\t{\n\t\t\t// Do not compose the substitutions, but merge them.\n\t\t\t// This is required for InvocationTests.SubstituteClassAndMethodTypeParametersAtOnce\n\t\t\treturn new TypeParameterSubstitution(candidate.Member.Substitution.ClassTypeArguments, candidate.InferredTypes);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a ResolveResult representing the result of overload resolution.\n\t\t/// </summary>\n\t\t/// <param name=\"targetResolveResult\">\n\t\t/// The target expression of the call. May be <c>null</c> for static methods/constructors.\n\t\t/// </param>\n\t\t/// <param name=\"initializerStatements\">\n\t\t/// Statements for Objects/Collections initializer.\n\t\t/// <see cref=\"InvocationResolveResult.InitializerStatements\"/>\n\t\t/// </param>\n\t\t/// <param name=\"returnTypeOverride\">\n\t\t/// If not null, use this instead of the ReturnType of the member as the type of the created resolve result.\n\t\t/// </param>\n\t\tpublic CSharpInvocationResolveResult CreateResolveResult(ResolveResult targetResolveResult, IList<ResolveResult> initializerStatements = null, IType returnTypeOverride = null)\n\t\t{\n\t\t\tIParameterizedMember member = GetBestCandidateWithSubstitutedTypeArguments();\n\t\t\tif (member == null)\n\t\t\t\tthrow new InvalidOperationException();\n\n\t\t\treturn new CSharpInvocationResolveResult(\n\t\t\t\tthis.IsExtensionMethodInvocation ? new TypeResolveResult(member.DeclaringType ?? SpecialType.UnknownType) : targetResolveResult,\n\t\t\t\tmember,\n\t\t\t\tGetArgumentsWithConversions(targetResolveResult, member),\n\t\t\t\tthis.BestCandidateErrors,\n\t\t\t\tthis.IsExtensionMethodInvocation,\n\t\t\t\tthis.BestCandidateIsExpandedForm,\n\t\t\t\tisDelegateInvocation: false,\n\t\t\t\targumentToParameterMap: this.GetArgumentToParameterMap(),\n\t\t\t\tinitializerStatements: initializerStatements,\n\t\t\t\treturnTypeOverride: returnTypeOverride);\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Resolver/OverloadResolutionErrors.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.CSharp.Resolver\n{\n\t[Flags]\n\tpublic enum OverloadResolutionErrors\n\t{\n\t\tNone = 0,\n\t\t/// <summary>\n\t\t/// Too many positional arguments (some could not be mapped to any parameter).\n\t\t/// </summary>\n\t\tTooManyPositionalArguments = 0x0001,\n\t\t/// <summary>\n\t\t/// A named argument could not be mapped to any parameter\n\t\t/// </summary>\n\t\tNoParameterFoundForNamedArgument = 0x0002,\n\t\t/// <summary>\n\t\t/// Type inference failed for a generic method.\n\t\t/// </summary>\n\t\tTypeInferenceFailed = 0x0004,\n\t\t/// <summary>\n\t\t/// Type arguments were explicitly specified, but did not match the number of type parameters.\n\t\t/// </summary>\n\t\tWrongNumberOfTypeArguments = 0x0008,\n\t\t/// <summary>\n\t\t/// After substituting type parameters with the inferred types; a constructed type within the formal parameters\n\t\t/// does not satisfy its constraint.\n\t\t/// </summary>\n\t\tConstructedTypeDoesNotSatisfyConstraint = 0x0010,\n\t\t/// <summary>\n\t\t/// No argument was mapped to a non-optional parameter\n\t\t/// </summary>\n\t\tMissingArgumentForRequiredParameter = 0x0020,\n\t\t/// <summary>\n\t\t/// Several arguments were mapped to a single (non-params-array) parameter\n\t\t/// </summary>\n\t\tMultipleArgumentsForSingleParameter = 0x0040,\n\t\t/// <summary>\n\t\t/// 'ref'/'out' passing mode doesn't match for at least 1 parameter\n\t\t/// </summary>\n\t\tParameterPassingModeMismatch = 0x0080,\n\t\t/// <summary>\n\t\t/// Argument type cannot be converted to parameter type\n\t\t/// </summary>\n\t\tArgumentTypeMismatch = 0x0100,\n\t\t/// <summary>\n\t\t/// There is no unique best overload.\n\t\t/// This error does not apply to any single candidate, but only to the overall result of overload resolution.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This error does not prevent a candidate from being applicable.\n\t\t/// </remarks>\n\t\tAmbiguousMatch = 0x0200,\n\t\t/// <summary>\n\t\t/// The member is not accessible.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This error is generated by member lookup; not by overload resolution.\n\t\t/// </remarks>\n\t\tInaccessible = 0x0400,\n\t\t/// <summary>\n\t\t/// A generic method \n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This error does not prevent a candidate from being applicable.\n\t\t/// </remarks>\n\t\tMethodConstraintsNotSatisfied = 0x0800,\n\t\t/// <summary>\n\t\t/// Using 'out var' instead of 'out T' would result in loss of type information.\n\t\t/// </summary>\n\t\tOutVarTypeMismatch = 0x1000,\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Resolver/TypeInference.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp.Resolver\n{\n\tpublic enum TypeInferenceAlgorithm\n\t{\n\t\t/// <summary>\n\t\t/// C# 4.0 type inference.\n\t\t/// </summary>\n\t\tCSharp4,\n\t\t/// <summary>\n\t\t/// Improved algorithm (not part of any specification) using FindTypeInBounds for fixing.\n\t\t/// </summary>\n\t\tImproved,\n\t\t/// <summary>\n\t\t/// Improved algorithm (not part of any specification) using FindTypeInBounds for fixing;\n\t\t/// uses <see cref=\"IntersectionType\"/> to report all results (in case of ambiguities).\n\t\t/// </summary>\n\t\tImprovedReturnAllResults\n\t}\n\n\t/// <summary>\n\t/// Implements C# 4.0 Type Inference (§7.5.2).\n\t/// </summary>\n\tpublic sealed class TypeInference\n\t{\n\t\treadonly ICompilation compilation;\n\t\treadonly CSharpConversions conversions;\n\t\tTypeInferenceAlgorithm algorithm = TypeInferenceAlgorithm.CSharp4;\n\n\t\t// determines the maximum generic nesting level; necessary to avoid infinite recursion in 'Improved' mode.\n\t\tconst int maxNestingLevel = 5;\n\t\tint nestingLevel;\n\n\t\t#region Constructor\n\t\tpublic TypeInference(ICompilation compilation)\n\t\t{\n\t\t\tif (compilation == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(compilation));\n\t\t\tthis.compilation = compilation;\n\t\t\tthis.conversions = CSharpConversions.Get(compilation);\n\t\t}\n\n\t\tinternal TypeInference(ICompilation compilation, CSharpConversions conversions)\n\t\t{\n\t\t\tDebug.Assert(compilation != null);\n\t\t\tDebug.Assert(conversions != null);\n\t\t\tthis.compilation = compilation;\n\t\t\tthis.conversions = conversions;\n\t\t}\n\t\t#endregion\n\n\t\t#region Properties\n\t\t/// <summary>\n\t\t/// Gets/Sets the type inference algorithm used.\n\t\t/// </summary>\n\t\tpublic TypeInferenceAlgorithm Algorithm {\n\t\t\tget { return algorithm; }\n\t\t\tset { algorithm = value; }\n\t\t}\n\n\t\tTypeInference CreateNestedInstance()\n\t\t{\n\t\t\tTypeInference c = new TypeInference(compilation, conversions);\n\t\t\tc.algorithm = algorithm;\n\t\t\tc.nestingLevel = nestingLevel + 1;\n\t\t\treturn c;\n\t\t}\n\t\t#endregion\n\n\t\tTP[] typeParameters;\n\t\tIType[] parameterTypes;\n\t\tResolveResult[] arguments;\n\t\tbool[,] dependencyMatrix;\n\t\tIReadOnlyList<IType> classTypeArguments;\n\n\t\t#region InferTypeArguments (main function)\n\t\t/// <summary>\n\t\t/// Performs type inference.\n\t\t/// </summary>\n\t\t/// <param name=\"typeParameters\">The method type parameters that should be inferred.</param>\n\t\t/// <param name=\"arguments\">The arguments passed to the method.</param>\n\t\t/// <param name=\"parameterTypes\">The parameter types of the method.</param>\n\t\t/// <param name=\"success\">Out: whether type inference was successful</param>\n\t\t/// <param name=\"classTypeArguments\">\n\t\t/// Class type arguments. These are substituted for class type parameters in the formal parameter types\n\t\t/// when inferring a method group or lambda.\n\t\t/// </param>\n\t\t/// <returns>The inferred type arguments.</returns>\n\t\tpublic IType[] InferTypeArguments(IReadOnlyList<ITypeParameter> typeParameters, IReadOnlyList<ResolveResult> arguments, IReadOnlyList<IType> parameterTypes, out bool success, IReadOnlyList<IType> classTypeArguments = null)\n\t\t{\n\t\t\tif (typeParameters == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(typeParameters));\n\t\t\tif (arguments == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(arguments));\n\t\t\tif (parameterTypes == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(parameterTypes));\n\t\t\ttry\n\t\t\t{\n\t\t\t\tthis.typeParameters = new TP[typeParameters.Count];\n\t\t\t\tfor (int i = 0; i < this.typeParameters.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tif (i != typeParameters[i].Index)\n\t\t\t\t\t\tthrow new ArgumentException(\"Type parameter has wrong index\");\n\t\t\t\t\tif (typeParameters[i].OwnerType != SymbolKind.Method)\n\t\t\t\t\t\tthrow new ArgumentException(\"Type parameter must be owned by a method\");\n\t\t\t\t\tthis.typeParameters[i] = new TP(typeParameters[i]);\n\t\t\t\t}\n\t\t\t\tthis.parameterTypes = new IType[Math.Min(arguments.Count, parameterTypes.Count)];\n\t\t\t\tthis.arguments = new ResolveResult[this.parameterTypes.Length];\n\t\t\t\tfor (int i = 0; i < this.parameterTypes.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tif (arguments[i] == null || parameterTypes[i] == null)\n\t\t\t\t\t\tthrow new ArgumentNullException();\n\t\t\t\t\tthis.arguments[i] = arguments[i];\n\t\t\t\t\tthis.parameterTypes[i] = parameterTypes[i];\n\t\t\t\t}\n\t\t\t\tthis.classTypeArguments = classTypeArguments;\n\t\t\t\tLog.WriteLine(\"Type Inference\");\n\t\t\t\tLog.WriteLine(\"  Signature: M<\" + string.Join<TP>(\", \", this.typeParameters) + \">\"\n\t\t\t\t\t\t\t  + \"(\" + string.Join<IType>(\", \", this.parameterTypes) + \")\");\n\t\t\t\tLog.WriteCollection(\"  Arguments: \", arguments);\n\t\t\t\tLog.Indent();\n\n\t\t\t\tPhaseOne();\n\t\t\t\tsuccess = PhaseTwo();\n\n\t\t\t\tLog.Unindent();\n\t\t\t\tLog.WriteLine(\"  Type inference finished \" + (success ? \"successfully\" : \"with errors\") + \": \" +\n\t\t\t\t\t\t\t  \"M<\" + string.Join(\", \", this.typeParameters.Select(tp => tp.FixedTo ?? SpecialType.UnknownType)) + \">\");\n\t\t\t\treturn this.typeParameters.Select(tp => tp.FixedTo ?? SpecialType.UnknownType).ToArray();\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tReset();\n\t\t\t}\n\t\t}\n\n\t\tvoid Reset()\n\t\t{\n\t\t\t// clean up so that memory used by the operation can be garbage collected as soon as possible\n\t\t\tthis.typeParameters = null;\n\t\t\tthis.parameterTypes = null;\n\t\t\tthis.arguments = null;\n\t\t\tthis.dependencyMatrix = null;\n\t\t\tthis.classTypeArguments = null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Infers type arguments for the <paramref name=\"typeParameters\"/> occurring in the <paramref name=\"targetType\"/>\n\t\t/// so that the resulting type (after substition) satisfies the given bounds.\n\t\t/// </summary>\n\t\tpublic IType[] InferTypeArgumentsFromBounds(IReadOnlyList<ITypeParameter> typeParameters, IType targetType, IEnumerable<IType> lowerBounds, IEnumerable<IType> upperBounds, out bool success)\n\t\t{\n\t\t\tif (typeParameters == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(typeParameters));\n\t\t\tif (targetType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(targetType));\n\t\t\tif (lowerBounds == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(lowerBounds));\n\t\t\tif (upperBounds == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(upperBounds));\n\t\t\tthis.typeParameters = new TP[typeParameters.Count];\n\t\t\tfor (int i = 0; i < this.typeParameters.Length; i++)\n\t\t\t{\n\t\t\t\tif (i != typeParameters[i].Index)\n\t\t\t\t\tthrow new ArgumentException(\"Type parameter has wrong index\");\n\t\t\t\tthis.typeParameters[i] = new TP(typeParameters[i]);\n\t\t\t}\n\t\t\tforeach (IType b in lowerBounds)\n\t\t\t{\n\t\t\t\tMakeLowerBoundInference(b, targetType);\n\t\t\t}\n\t\t\tforeach (IType b in upperBounds)\n\t\t\t{\n\t\t\t\tMakeUpperBoundInference(b, targetType);\n\t\t\t}\n\t\t\tIType[] result = new IType[this.typeParameters.Length];\n\t\t\tsuccess = true;\n\t\t\tfor (int i = 0; i < result.Length; i++)\n\t\t\t{\n\t\t\t\tsuccess &= Fix(this.typeParameters[i]);\n\t\t\t\tresult[i] = this.typeParameters[i].FixedTo ?? SpecialType.UnknownType;\n\t\t\t}\n\t\t\tReset();\n\t\t\treturn result;\n\t\t}\n\t\t#endregion\n\n\t\tsealed class TP\n\t\t{\n\t\t\tpublic readonly HashSet<IType> LowerBounds = new HashSet<IType>();\n\t\t\tpublic readonly HashSet<IType> UpperBounds = new HashSet<IType>();\n\t\t\tpublic IType ExactBound;\n\t\t\tpublic bool MultipleDifferentExactBounds;\n\t\t\tpublic readonly ITypeParameter TypeParameter;\n\t\t\tpublic IType FixedTo;\n\n\t\t\tpublic bool IsFixed {\n\t\t\t\tget { return FixedTo != null; }\n\t\t\t}\n\n\t\t\tpublic bool HasBounds {\n\t\t\t\tget { return LowerBounds.Count > 0 || UpperBounds.Count > 0 || ExactBound != null; }\n\t\t\t}\n\n\t\t\tpublic TP(ITypeParameter typeParameter)\n\t\t\t{\n\t\t\t\tif (typeParameter == null)\n\t\t\t\t\tthrow new ArgumentNullException(nameof(typeParameter));\n\t\t\t\tthis.TypeParameter = typeParameter;\n\t\t\t}\n\n\t\t\tpublic void AddExactBound(IType type)\n\t\t\t{\n\t\t\t\t// Exact bounds need to stored separately, not just as Lower+Upper bounds,\n\t\t\t\t// due to TypeInferenceTests.GenericArgumentImplicitlyConvertibleToAndFromAnotherTypeList (see #281)\n\t\t\t\tif (ExactBound == null)\n\t\t\t\t\tExactBound = type;\n\t\t\t\telse if (!ExactBound.Equals(type))\n\t\t\t\t\tMultipleDifferentExactBounds = true;\n\t\t\t}\n\n\t\t\tpublic override string ToString()\n\t\t\t{\n\t\t\t\treturn TypeParameter.Name;\n\t\t\t}\n\t\t}\n\n\t\tsealed class OccursInVisitor : TypeVisitor\n\t\t{\n\t\t\treadonly TP[] tp;\n\t\t\tpublic readonly bool[] Occurs;\n\n\t\t\tpublic OccursInVisitor(TypeInference typeInference)\n\t\t\t{\n\t\t\t\tthis.tp = typeInference.typeParameters;\n\t\t\t\tthis.Occurs = new bool[tp.Length];\n\t\t\t}\n\n\t\t\tpublic override IType VisitTypeParameter(ITypeParameter type)\n\t\t\t{\n\t\t\t\tint index = type.Index;\n\t\t\t\tif (index < tp.Length && tp[index].TypeParameter == type)\n\t\t\t\t\tOccurs[index] = true;\n\t\t\t\treturn base.VisitTypeParameter(type);\n\t\t\t}\n\t\t}\n\n\t\t#region Inference Phases\n\t\tvoid PhaseOne()\n\t\t{\n\t\t\t// C# 4.0 spec: §7.5.2.1 The first phase\n\t\t\tLog.WriteLine(\"Phase One\");\n\t\t\tfor (int i = 0; i < arguments.Length; i++)\n\t\t\t{\n\t\t\t\tResolveResult Ei = arguments[i];\n\t\t\t\tIType Ti = parameterTypes[i];\n\n\t\t\t\tLambdaResolveResult lrr = Ei as LambdaResolveResult;\n\t\t\t\tif (lrr != null)\n\t\t\t\t{\n\t\t\t\t\tMakeExplicitParameterTypeInference(lrr, Ti);\n\t\t\t\t}\n\t\t\t\tif (lrr != null || Ei is MethodGroupResolveResult)\n\t\t\t\t{\n\t\t\t\t\t// this is not in the spec???\n\t\t\t\t\tif (OutputTypeContainsUnfixed(Ei, Ti) && !InputTypesContainsUnfixed(Ei, Ti))\n\t\t\t\t\t{\n\t\t\t\t\t\tMakeOutputTypeInference(Ei, Ti);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (IsValidType(Ei.Type))\n\t\t\t\t{\n\t\t\t\t\tif (Ti is ByReferenceType)\n\t\t\t\t\t{\n\t\t\t\t\t\tMakeExactInference(Ei.Type, Ti);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tMakeLowerBoundInference(Ei.Type, Ti);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic bool IsValidType(IType type)\n\t\t{\n\t\t\treturn type.Kind != TypeKind.Unknown && type.Kind != TypeKind.Null && type.Kind != TypeKind.None;\n\t\t}\n\n\t\tbool PhaseTwo()\n\t\t{\n\t\t\t// C# 4.0 spec: §7.5.2.2 The second phase\n\t\t\tLog.WriteLine(\"Phase Two\");\n\t\t\t// All unfixed type variables Xi which do not depend on any Xj are fixed.\n\t\t\tList<TP> typeParametersToFix = new List<TP>();\n\t\t\tforeach (TP Xi in typeParameters)\n\t\t\t{\n\t\t\t\tif (Xi.IsFixed == false)\n\t\t\t\t{\n\t\t\t\t\tif (!typeParameters.Any((TP Xj) => !Xj.IsFixed && DependsOn(Xi, Xj)))\n\t\t\t\t\t{\n\t\t\t\t\t\ttypeParametersToFix.Add(Xi);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If no such type variables exist, all unfixed type variables Xi are fixed for which all of the following hold:\n\t\t\tif (typeParametersToFix.Count == 0)\n\t\t\t{\n\t\t\t\tLog.WriteLine(\"Type parameters cannot be fixed due to dependency cycles\");\n\t\t\t\tLog.WriteLine(\"Trying to break the cycle by fixing any TPs that have non-empty bounds...\");\n\t\t\t\tforeach (TP Xi in typeParameters)\n\t\t\t\t{\n\t\t\t\t\t// Xi has a non­empty set of bounds\n\t\t\t\t\tif (!Xi.IsFixed && Xi.HasBounds)\n\t\t\t\t\t{\n\t\t\t\t\t\t// There is at least one type variable Xj that depends on Xi\n\t\t\t\t\t\tif (typeParameters.Any((TP Xj) => DependsOn(Xj, Xi)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttypeParametersToFix.Add(Xi);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// now fix 'em\n\t\t\tbool errorDuringFix = false;\n\t\t\tforeach (TP tp in typeParametersToFix)\n\t\t\t{\n\t\t\t\tif (!Fix(tp))\n\t\t\t\t\terrorDuringFix = true;\n\t\t\t}\n\t\t\tif (errorDuringFix)\n\t\t\t\treturn false;\n\t\t\tbool unfixedTypeVariablesExist = typeParameters.Any((TP X) => X.IsFixed == false);\n\t\t\tif (typeParametersToFix.Count == 0 && unfixedTypeVariablesExist)\n\t\t\t{\n\t\t\t\t// If no such type variables exist and there are still unfixed type variables, type inference fails.\n\t\t\t\tLog.WriteLine(\"Type inference fails: there are still unfixed TPs remaining\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (!unfixedTypeVariablesExist)\n\t\t\t{\n\t\t\t\t// Otherwise, if no further unfixed type variables exist, type inference succeeds.\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Otherwise, for all arguments ei with corresponding parameter type Ti\n\t\t\t\tfor (int i = 0; i < arguments.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tResolveResult Ei = arguments[i];\n\t\t\t\t\tIType Ti = parameterTypes[i];\n\t\t\t\t\t// where the output types (§7.4.2.4) contain unfixed type variables Xj\n\t\t\t\t\t// but the input types (§7.4.2.3) do not\n\t\t\t\t\tif (OutputTypeContainsUnfixed(Ei, Ti) && !InputTypesContainsUnfixed(Ei, Ti))\n\t\t\t\t\t{\n\t\t\t\t\t\t// an output type inference (§7.4.2.6) is made for ei with type Ti.\n\t\t\t\t\t\tLog.WriteLine(\"MakeOutputTypeInference for argument #\" + i);\n\t\t\t\t\t\tMakeOutputTypeInference(Ei, Ti);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Then the second phase is repeated.\n\t\t\t\treturn PhaseTwo();\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Input Types / Output Types (§7.5.2.3 + §7.5.2.4)\n\t\tIType[] InputTypes(ResolveResult e, IType t)\n\t\t{\n\t\t\t// C# 4.0 spec: §7.5.2.3 Input types\n\t\t\tLambdaResolveResult lrr = e as LambdaResolveResult;\n\t\t\tif (lrr != null && lrr.IsImplicitlyTyped || e is MethodGroupResolveResult)\n\t\t\t{\n\t\t\t\tIMethod m = GetDelegateOrExpressionTreeSignature(t);\n\t\t\t\tif (m != null)\n\t\t\t\t{\n\t\t\t\t\tIType[] inputTypes = new IType[m.Parameters.Count];\n\t\t\t\t\tfor (int i = 0; i < inputTypes.Length; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tinputTypes[i] = m.Parameters[i].Type;\n\t\t\t\t\t}\n\t\t\t\t\treturn inputTypes;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn Empty<IType>.Array;\n\t\t}\n\n\t\tIType[] OutputTypes(ResolveResult e, IType t)\n\t\t{\n\t\t\t// C# 4.0 spec: §7.5.2.4 Output types\n\t\t\tLambdaResolveResult lrr = e as LambdaResolveResult;\n\t\t\tif (lrr != null || e is MethodGroupResolveResult)\n\t\t\t{\n\t\t\t\tIMethod m = GetDelegateOrExpressionTreeSignature(t);\n\t\t\t\tif (m != null)\n\t\t\t\t{\n\t\t\t\t\treturn new[] { m.ReturnType };\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn Empty<IType>.Array;\n\t\t}\n\n\t\tstatic IMethod GetDelegateOrExpressionTreeSignature(IType t)\n\t\t{\n\t\t\tif (t.TypeParameterCount == 1 && t.Name == \"Expression\"\n\t\t\t\t&& t.Namespace == \"System.Linq.Expressions\")\n\t\t\t{\n\t\t\t\tt = t.TypeArguments[0];\n\t\t\t}\n\t\t\treturn t.GetDelegateInvokeMethod();\n\t\t}\n\n\t\tbool InputTypesContainsUnfixed(ResolveResult argument, IType parameterType)\n\t\t{\n\t\t\treturn AnyTypeContainsUnfixedParameter(InputTypes(argument, parameterType));\n\t\t}\n\n\t\tbool OutputTypeContainsUnfixed(ResolveResult argument, IType parameterType)\n\t\t{\n\t\t\treturn AnyTypeContainsUnfixedParameter(OutputTypes(argument, parameterType));\n\t\t}\n\n\t\tbool AnyTypeContainsUnfixedParameter(IEnumerable<IType> types)\n\t\t{\n\t\t\tOccursInVisitor o = new OccursInVisitor(this);\n\t\t\tforeach (var type in types)\n\t\t\t{\n\t\t\t\ttype.AcceptVisitor(o);\n\t\t\t}\n\t\t\tfor (int i = 0; i < typeParameters.Length; i++)\n\t\t\t{\n\t\t\t\tif (!typeParameters[i].IsFixed && o.Occurs[i])\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\t#endregion\n\n\t\t#region DependsOn (§7.5.2.5)\n\t\t// C# 4.0 spec: §7.5.2.5 Dependance\n\n\t\tvoid CalculateDependencyMatrix()\n\t\t{\n\t\t\tint n = typeParameters.Length;\n\t\t\tdependencyMatrix = new bool[n, n];\n\t\t\tfor (int k = 0; k < arguments.Length; k++)\n\t\t\t{\n\t\t\t\tOccursInVisitor input = new OccursInVisitor(this);\n\t\t\t\tOccursInVisitor output = new OccursInVisitor(this);\n\t\t\t\tforeach (var type in InputTypes(arguments[k], parameterTypes[k]))\n\t\t\t\t{\n\t\t\t\t\ttype.AcceptVisitor(input);\n\t\t\t\t}\n\t\t\t\tforeach (var type in OutputTypes(arguments[k], parameterTypes[k]))\n\t\t\t\t{\n\t\t\t\t\ttype.AcceptVisitor(output);\n\t\t\t\t}\n\t\t\t\tfor (int i = 0; i < n; i++)\n\t\t\t\t{\n\t\t\t\t\tfor (int j = 0; j < n; j++)\n\t\t\t\t\t{\n\t\t\t\t\t\tdependencyMatrix[i, j] |= input.Occurs[j] && output.Occurs[i];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// calculate transitive closure using Warshall's algorithm:\n\t\t\tfor (int i = 0; i < n; i++)\n\t\t\t{\n\t\t\t\tfor (int j = 0; j < n; j++)\n\t\t\t\t{\n\t\t\t\t\tif (dependencyMatrix[i, j])\n\t\t\t\t\t{\n\t\t\t\t\t\tfor (int k = 0; k < n; k++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (dependencyMatrix[j, k])\n\t\t\t\t\t\t\t\tdependencyMatrix[i, k] = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool DependsOn(TP x, TP y)\n\t\t{\n\t\t\tif (dependencyMatrix == null)\n\t\t\t\tCalculateDependencyMatrix();\n\t\t\t// x depends on y\n\t\t\treturn dependencyMatrix[x.TypeParameter.Index, y.TypeParameter.Index];\n\t\t}\n\t\t#endregion\n\n\t\t#region MakeOutputTypeInference (§7.5.2.6)\n\t\tvoid MakeOutputTypeInference(ResolveResult e, IType t)\n\t\t{\n\t\t\tLog.WriteLine(\" MakeOutputTypeInference from \" + e + \" to \" + t);\n\t\t\t// If E is an anonymous function with inferred return type  U (§7.5.2.12) and T is a delegate type or expression\n\t\t\t// tree type with return type Tb, then a lower-bound inference (§7.5.2.9) is made from U to Tb.\n\t\t\tLambdaResolveResult lrr = e as LambdaResolveResult;\n\t\t\tif (lrr != null)\n\t\t\t{\n\t\t\t\tIMethod m = GetDelegateOrExpressionTreeSignature(t);\n\t\t\t\tif (m != null)\n\t\t\t\t{\n\t\t\t\t\tIType inferredReturnType;\n\t\t\t\t\tif (lrr.IsImplicitlyTyped)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (m.Parameters.Count != lrr.Parameters.Count)\n\t\t\t\t\t\t\treturn; // cannot infer due to mismatched parameter lists\n\t\t\t\t\t\tTypeParameterSubstitution substitution = GetSubstitutionForFixedTPs();\n\t\t\t\t\t\tIType[] inferredParameterTypes = new IType[m.Parameters.Count];\n\t\t\t\t\t\tfor (int i = 0; i < inferredParameterTypes.Length; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tIType parameterType = m.Parameters[i].Type;\n\t\t\t\t\t\t\tinferredParameterTypes[i] = parameterType.AcceptVisitor(substitution);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tinferredReturnType = lrr.GetInferredReturnType(inferredParameterTypes);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tinferredReturnType = lrr.GetInferredReturnType(null);\n\t\t\t\t\t}\n\t\t\t\t\tMakeLowerBoundInference(inferredReturnType, m.ReturnType);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Otherwise, if E is a method group and T is a delegate type or expression tree type\n\t\t\t// with parameter types T1…Tk and return type Tb, and overload resolution\n\t\t\t// of E with the types T1…Tk yields a single method with return type U, then a lower­-bound\n\t\t\t// inference is made from U to Tb.\n\t\t\tMethodGroupResolveResult mgrr = e as MethodGroupResolveResult;\n\t\t\tif (mgrr != null)\n\t\t\t{\n\t\t\t\tIMethod m = GetDelegateOrExpressionTreeSignature(t);\n\t\t\t\tif (m != null)\n\t\t\t\t{\n\t\t\t\t\tResolveResult[] args = new ResolveResult[m.Parameters.Count];\n\t\t\t\t\tTypeParameterSubstitution substitution = GetSubstitutionForFixedTPs();\n\t\t\t\t\tfor (int i = 0; i < args.Length; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tIParameter param = m.Parameters[i];\n\t\t\t\t\t\tIType parameterType = param.Type.AcceptVisitor(substitution);\n\t\t\t\t\t\tif ((param.ReferenceKind != ReferenceKind.None) && parameterType.Kind == TypeKind.ByReference)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tparameterType = ((ByReferenceType)parameterType).ElementType;\n\t\t\t\t\t\t\targs[i] = new ByReferenceResolveResult(parameterType, param.ReferenceKind);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\targs[i] = new ResolveResult(parameterType);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tvar or = mgrr.PerformOverloadResolution(\n\t\t\t\t\t\tcompilation, args,\n\t\t\t\t\t\tallowExpandingParams: false,\n\t\t\t\t\t\tallowOptionalParameters: false,\n\t\t\t\t\t\tallowImplicitIn: false\n\t\t\t\t\t);\n\t\t\t\t\tif (or.FoundApplicableCandidate && or.BestCandidateAmbiguousWith == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tIType returnType = or.GetBestCandidateWithSubstitutedTypeArguments().ReturnType;\n\t\t\t\t\t\tMakeLowerBoundInference(returnType, m.ReturnType);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Otherwise, if E is an expression with type U, then a lower-bound inference is made from U to T.\n\t\t\tif (IsValidType(e.Type))\n\t\t\t{\n\t\t\t\tMakeLowerBoundInference(e.Type, t);\n\t\t\t}\n\t\t}\n\n\t\tTypeParameterSubstitution GetSubstitutionForFixedTPs()\n\t\t{\n\t\t\tIType[] fixedTypes = new IType[typeParameters.Length];\n\t\t\tfor (int i = 0; i < fixedTypes.Length; i++)\n\t\t\t{\n\t\t\t\tfixedTypes[i] = typeParameters[i].FixedTo ?? SpecialType.UnknownType;\n\t\t\t}\n\t\t\treturn new TypeParameterSubstitution(classTypeArguments, fixedTypes);\n\t\t}\n\t\t#endregion\n\n\t\t#region MakeExplicitParameterTypeInference (§7.5.2.7)\n\t\tvoid MakeExplicitParameterTypeInference(LambdaResolveResult e, IType t)\n\t\t{\n\t\t\t// C# 4.0 spec: §7.5.2.7 Explicit parameter type inferences\n\t\t\tif (e.IsImplicitlyTyped || !e.HasParameterList)\n\t\t\t\treturn;\n\t\t\tLog.WriteLine(\" MakeExplicitParameterTypeInference from \" + e + \" to \" + t);\n\t\t\tIMethod m = GetDelegateOrExpressionTreeSignature(t);\n\t\t\tif (m == null)\n\t\t\t\treturn;\n\t\t\tfor (int i = 0; i < e.Parameters.Count && i < m.Parameters.Count; i++)\n\t\t\t{\n\t\t\t\tMakeExactInference(e.Parameters[i].Type, m.Parameters[i].Type);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region MakeExactInference (§7.5.2.8)\n\t\t/// <summary>\n\t\t/// Make exact inference from U to V.\n\t\t/// C# 4.0 spec: §7.5.2.8 Exact inferences\n\t\t/// </summary>\n\t\tvoid MakeExactInference(IType U, IType V)\n\t\t{\n\t\t\tLog.WriteLine(\"MakeExactInference from \" + U + \" to \" + V);\n\n\t\t\tif (U.Nullability == V.Nullability)\n\t\t\t{\n\t\t\t\tU = U.WithoutNullability();\n\t\t\t\tV = V.WithoutNullability();\n\t\t\t}\n\n\t\t\t// If V is one of the unfixed Xi then U is added to the set of bounds for Xi.\n\t\t\tTP tp = GetTPForType(V);\n\t\t\tif (tp != null && tp.IsFixed == false)\n\t\t\t{\n\t\t\t\tLog.WriteLine(\" Add exact bound '\" + U + \"' to \" + tp);\n\t\t\t\ttp.AddExactBound(U);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle by reference types:\n\t\t\tByReferenceType brU = U as ByReferenceType;\n\t\t\tByReferenceType brV = V as ByReferenceType;\n\t\t\tif (brU != null && brV != null)\n\t\t\t{\n\t\t\t\tMakeExactInference(brU.ElementType, brV.ElementType);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle array types:\n\t\t\tU = U.TupleUnderlyingTypeOrSelf();\n\t\t\tV = V.TupleUnderlyingTypeOrSelf();\n\t\t\tswitch ((U, V))\n\t\t\t{\n\t\t\t\tcase (ArrayType arrU, ArrayType arrV) when arrU.Dimensions == arrV.Dimensions:\n\t\t\t\t\tMakeExactInference(arrU.ElementType, arrV.ElementType);\n\t\t\t\t\treturn;\n\t\t\t\tcase (ArrayType arrU, ParameterizedType spanV) when compilation.TypeSystemOptions.HasFlag(TypeSystemOptions.FirstClassSpanTypes) && spanV.IsKnownType(KnownTypeCode.SpanOfT):\n\t\t\t\t\tMakeExactInference(arrU.ElementType, spanV.TypeArguments[0]);\n\t\t\t\t\treturn;\n\t\t\t\tcase (ParameterizedType spanU, ParameterizedType spanV) when compilation.TypeSystemOptions.HasFlag(TypeSystemOptions.FirstClassSpanTypes) && spanU.IsKnownType(KnownTypeCode.SpanOfT) && spanV.IsKnownType(KnownTypeCode.SpanOfT):\n\t\t\t\t\tMakeExactInference(spanU.TypeArguments[0], spanV.TypeArguments[0]);\n\t\t\t\t\treturn;\n\t\t\t\tcase (ArrayType arrU, ParameterizedType rosV) when compilation.TypeSystemOptions.HasFlag(TypeSystemOptions.FirstClassSpanTypes) && rosV.IsKnownType(KnownTypeCode.ReadOnlySpanOfT):\n\t\t\t\t\tMakeExactInference(arrU.ElementType, rosV.TypeArguments[0]);\n\t\t\t\t\treturn;\n\t\t\t\tcase (ParameterizedType spanU, ParameterizedType rosV) when compilation.TypeSystemOptions.HasFlag(TypeSystemOptions.FirstClassSpanTypes) && spanU.IsKnownType(KnownTypeCode.SpanOfT) && rosV.IsKnownType(KnownTypeCode.ReadOnlySpanOfT):\n\t\t\t\t\tMakeExactInference(spanU.TypeArguments[0], rosV.TypeArguments[0]);\n\t\t\t\t\treturn;\n\t\t\t\tcase (ParameterizedType rosU, ParameterizedType rosV) when compilation.TypeSystemOptions.HasFlag(TypeSystemOptions.FirstClassSpanTypes) && rosU.IsKnownType(KnownTypeCode.ReadOnlySpanOfT) && rosV.IsKnownType(KnownTypeCode.ReadOnlySpanOfT):\n\t\t\t\t\tMakeExactInference(rosU.TypeArguments[0], rosV.TypeArguments[0]);\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle parameterized type:\n\t\t\tif (U is ParameterizedType pU && V is ParameterizedType pV\n\t\t\t\t&& object.Equals(pU.GenericType, pV.GenericType)\n\t\t\t\t&& pU.TypeParameterCount == pV.TypeParameterCount)\n\t\t\t{\n\t\t\t\tLog.Indent();\n\t\t\t\tfor (int i = 0; i < pU.TypeParameterCount; i++)\n\t\t\t\t{\n\t\t\t\t\tMakeExactInference(pU.GetTypeArgument(i), pV.GetTypeArgument(i));\n\t\t\t\t}\n\t\t\t\tLog.Unindent();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle pointer types:\n\t\t\tif (U is PointerType ptrU && V is PointerType ptrV)\n\t\t\t{\n\t\t\t\tMakeExactInference(ptrU.ElementType, ptrV.ElementType);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (U is FunctionPointerType fnPtrU && V is FunctionPointerType fnPtrV)\n\t\t\t{\n\t\t\t\tMakeExactInference(fnPtrU.ReturnType, fnPtrV.ReturnType);\n\t\t\t\tforeach (var (ptU, ptV) in fnPtrU.ParameterTypes.Zip(fnPtrV.ParameterTypes))\n\t\t\t\t{\n\t\t\t\t\tMakeExactInference(ptU, ptV);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tTP GetTPForType(IType v)\n\t\t{\n\t\t\tif (v is NullabilityAnnotatedTypeParameter natp)\n\t\t\t{\n\t\t\t\tv = natp.OriginalTypeParameter;\n\t\t\t}\n\t\t\tif (v is ITypeParameter p)\n\t\t\t{\n\t\t\t\tint index = p.Index;\n\t\t\t\tif (index < typeParameters.Length && typeParameters[index].TypeParameter == p)\n\t\t\t\t\treturn typeParameters[index];\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\t#endregion\n\n\t\t#region MakeLowerBoundInference (§7.5.2.9)\n\t\t/// <summary>\n\t\t/// Make lower bound inference from U to V.\n\t\t/// C# 4.0 spec: §7.5.2.9 Lower-bound inferences\n\t\t/// </summary>\n\t\tvoid MakeLowerBoundInference(IType U, IType V)\n\t\t{\n\t\t\tLog.WriteLine(\" MakeLowerBoundInference from \" + U + \" to \" + V);\n\t\t\tif (U.Nullability == V.Nullability)\n\t\t\t{\n\t\t\t\tU = U.WithoutNullability();\n\t\t\t\tV = V.WithoutNullability();\n\t\t\t}\n\n\t\t\t// If V is one of the unfixed Xi then U is added to the set of bounds for Xi.\n\t\t\tTP tp = GetTPForType(V);\n\t\t\tif (tp != null && tp.IsFixed == false)\n\t\t\t{\n\t\t\t\tLog.WriteLine(\"  Add lower bound '\" + U + \"' to \" + tp);\n\t\t\t\ttp.LowerBounds.Add(U);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle nullable covariance:\n\t\t\tif (NullableType.IsNullable(U) && NullableType.IsNullable(V))\n\t\t\t{\n\t\t\t\tMakeLowerBoundInference(NullableType.GetUnderlyingType(U), NullableType.GetUnderlyingType(V));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle by reference types:\n\t\t\tByReferenceType brU = U as ByReferenceType;\n\t\t\tByReferenceType brV = V as ByReferenceType;\n\t\t\tif (brU != null && brV != null)\n\t\t\t{\n\t\t\t\tMakeExactInference(brU.ElementType, brV.ElementType);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle array types:\n\t\t\tV = V.TupleUnderlyingTypeOrSelf();\n\t\t\tswitch ((U, V))\n\t\t\t{\n\t\t\t\tcase (ArrayType arrU, ArrayType arrV) when arrU.Dimensions == arrV.Dimensions:\n\t\t\t\t\tMakeLowerBoundInference(arrU.ElementType, arrV.ElementType);\n\t\t\t\t\treturn;\n\t\t\t\tcase (ArrayType arrU, ParameterizedType spanV) when compilation.TypeSystemOptions.HasFlag(TypeSystemOptions.FirstClassSpanTypes) && spanV.IsKnownType(KnownTypeCode.SpanOfT):\n\t\t\t\t\tMakeLowerBoundInference(arrU.ElementType, spanV.TypeArguments[0]);\n\t\t\t\t\treturn;\n\t\t\t\tcase (ParameterizedType spanU, ParameterizedType spanV) when compilation.TypeSystemOptions.HasFlag(TypeSystemOptions.FirstClassSpanTypes) && spanU.IsKnownType(KnownTypeCode.SpanOfT) && spanV.IsKnownType(KnownTypeCode.SpanOfT):\n\t\t\t\t\tMakeLowerBoundInference(spanU.TypeArguments[0], spanV.TypeArguments[0]);\n\t\t\t\t\treturn;\n\t\t\t\tcase (ArrayType arrU, ParameterizedType rosV) when compilation.TypeSystemOptions.HasFlag(TypeSystemOptions.FirstClassSpanTypes) && rosV.IsKnownType(KnownTypeCode.ReadOnlySpanOfT):\n\t\t\t\t\tMakeLowerBoundInference(arrU.ElementType, rosV.TypeArguments[0]);\n\t\t\t\t\treturn;\n\t\t\t\tcase (ParameterizedType spanU, ParameterizedType rosV) when compilation.TypeSystemOptions.HasFlag(TypeSystemOptions.FirstClassSpanTypes) && spanU.IsKnownType(KnownTypeCode.SpanOfT) && rosV.IsKnownType(KnownTypeCode.ReadOnlySpanOfT):\n\t\t\t\t\tMakeLowerBoundInference(spanU.TypeArguments[0], rosV.TypeArguments[0]);\n\t\t\t\t\treturn;\n\t\t\t\tcase (ParameterizedType rosU, ParameterizedType rosV) when compilation.TypeSystemOptions.HasFlag(TypeSystemOptions.FirstClassSpanTypes) && rosU.IsKnownType(KnownTypeCode.ReadOnlySpanOfT) && rosV.IsKnownType(KnownTypeCode.ReadOnlySpanOfT):\n\t\t\t\t\tMakeLowerBoundInference(rosU.TypeArguments[0], rosV.TypeArguments[0]);\n\t\t\t\t\treturn;\n\t\t\t\tcase (ArrayType arrU, ParameterizedType arrIntfV) when arrIntfV.IsArrayInterfaceType() && arrU.Dimensions == 1:\n\t\t\t\t\tMakeLowerBoundInference(arrU.ElementType, arrIntfV.TypeArguments[0]);\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle parameterized types:\n\t\t\tif (V is ParameterizedType pV)\n\t\t\t{\n\t\t\t\tParameterizedType uniqueBaseType = null;\n\t\t\t\tforeach (IType baseU in U.GetAllBaseTypes())\n\t\t\t\t{\n\t\t\t\t\tParameterizedType pU = baseU.TupleUnderlyingTypeOrSelf() as ParameterizedType;\n\t\t\t\t\tif (pU != null && object.Equals(pU.GenericType, pV.GenericType) && pU.TypeParameterCount == pV.TypeParameterCount)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (uniqueBaseType == null)\n\t\t\t\t\t\t\tuniqueBaseType = pU;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\treturn; // cannot make an inference because it's not unique\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tLog.Indent();\n\t\t\t\tif (uniqueBaseType != null)\n\t\t\t\t{\n\t\t\t\t\tfor (int i = 0; i < uniqueBaseType.TypeParameterCount; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tIType Ui = uniqueBaseType.GetTypeArgument(i);\n\t\t\t\t\t\tIType Vi = pV.GetTypeArgument(i);\n\t\t\t\t\t\tif (Ui.IsReferenceType == true)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// look for variance\n\t\t\t\t\t\t\tITypeParameter Xi = pV.TypeParameters[i];\n\t\t\t\t\t\t\tswitch (Xi.Variance)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcase VarianceModifier.Covariant:\n\t\t\t\t\t\t\t\t\tMakeLowerBoundInference(Ui, Vi);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase VarianceModifier.Contravariant:\n\t\t\t\t\t\t\t\t\tMakeUpperBoundInference(Ui, Vi);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tdefault: // invariant\n\t\t\t\t\t\t\t\t\tMakeExactInference(Ui, Vi);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// not known to be a reference type\n\t\t\t\t\t\t\tMakeExactInference(Ui, Vi);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tLog.Unindent();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle pointer types:\n\t\t\tif (U is PointerType ptrU && V is PointerType ptrV)\n\t\t\t{\n\t\t\t\tMakeExactInference(ptrU.ElementType, ptrV.ElementType);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (U is FunctionPointerType fnPtrU && V is FunctionPointerType fnPtrV)\n\t\t\t{\n\t\t\t\tMakeLowerBoundInference(fnPtrU.ReturnType, fnPtrV.ReturnType);\n\t\t\t\tforeach (var (ptU, ptV) in fnPtrU.ParameterTypes.Zip(fnPtrV.ParameterTypes))\n\t\t\t\t{\n\t\t\t\t\tMakeUpperBoundInference(ptU, ptV);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region MakeUpperBoundInference (§7.5.2.10)\n\t\t/// <summary>\n\t\t/// Make upper bound inference from U to V.\n\t\t/// C# 4.0 spec: §7.5.2.10 Upper-bound inferences\n\t\t/// </summary>\n\t\tvoid MakeUpperBoundInference(IType U, IType V)\n\t\t{\n\t\t\tLog.WriteLine(\" MakeUpperBoundInference from \" + U + \" to \" + V);\n\t\t\tif (U.Nullability == V.Nullability)\n\t\t\t{\n\t\t\t\tU = U.WithoutNullability();\n\t\t\t\tV = V.WithoutNullability();\n\t\t\t}\n\n\t\t\t// If V is one of the unfixed Xi then U is added to the set of bounds for Xi.\n\t\t\tTP tp = GetTPForType(V);\n\t\t\tif (tp != null && tp.IsFixed == false)\n\t\t\t{\n\t\t\t\tLog.WriteLine(\"  Add upper bound '\" + U + \"' to \" + tp);\n\t\t\t\ttp.UpperBounds.Add(U);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Handle array types:\n\t\t\tArrayType arrU = U as ArrayType;\n\t\t\tArrayType arrV = V as ArrayType;\n\t\t\tParameterizedType pU = U.TupleUnderlyingTypeOrSelf() as ParameterizedType;\n\t\t\tif (arrV != null && arrU != null && arrU.Dimensions == arrV.Dimensions)\n\t\t\t{\n\t\t\t\tMakeUpperBoundInference(arrU.ElementType, arrV.ElementType);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\telse if (arrV != null && pU.IsArrayInterfaceType() && arrV.Dimensions == 1)\n\t\t\t{\n\t\t\t\tMakeUpperBoundInference(pU.GetTypeArgument(0), arrV.ElementType);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle parameterized types:\n\t\t\tif (pU != null)\n\t\t\t{\n\t\t\t\tParameterizedType uniqueBaseType = null;\n\t\t\t\tforeach (IType baseV in V.GetAllBaseTypes())\n\t\t\t\t{\n\t\t\t\t\tParameterizedType pV = baseV.TupleUnderlyingTypeOrSelf() as ParameterizedType;\n\t\t\t\t\tif (pV != null && object.Equals(pU.GenericType, pV.GenericType) && pU.TypeParameterCount == pV.TypeParameterCount)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (uniqueBaseType == null)\n\t\t\t\t\t\t\tuniqueBaseType = pV;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\treturn; // cannot make an inference because it's not unique\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tLog.Indent();\n\t\t\t\tif (uniqueBaseType != null)\n\t\t\t\t{\n\t\t\t\t\tfor (int i = 0; i < uniqueBaseType.TypeParameterCount; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tIType Ui = pU.GetTypeArgument(i);\n\t\t\t\t\t\tIType Vi = uniqueBaseType.GetTypeArgument(i);\n\t\t\t\t\t\tif (Ui.IsReferenceType == true)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// look for variance\n\t\t\t\t\t\t\tITypeParameter Xi = pU.TypeParameters[i];\n\t\t\t\t\t\t\tswitch (Xi.Variance)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcase VarianceModifier.Covariant:\n\t\t\t\t\t\t\t\t\tMakeUpperBoundInference(Ui, Vi);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase VarianceModifier.Contravariant:\n\t\t\t\t\t\t\t\t\tMakeLowerBoundInference(Ui, Vi);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tdefault: // invariant\n\t\t\t\t\t\t\t\t\tMakeExactInference(Ui, Vi);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// not known to be a reference type\n\t\t\t\t\t\t\tMakeExactInference(Ui, Vi);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tLog.Unindent();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle pointer types:\n\t\t\tif (U is PointerType ptrU && V is PointerType ptrV)\n\t\t\t{\n\t\t\t\tMakeExactInference(ptrU.ElementType, ptrV.ElementType);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (U is FunctionPointerType fnPtrU && V is FunctionPointerType fnPtrV)\n\t\t\t{\n\t\t\t\tMakeUpperBoundInference(fnPtrU.ReturnType, fnPtrV.ReturnType);\n\t\t\t\tforeach (var (ptU, ptV) in fnPtrU.ParameterTypes.Zip(fnPtrV.ParameterTypes))\n\t\t\t\t{\n\t\t\t\t\tMakeLowerBoundInference(ptU, ptV);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Fixing (§7.5.2.11)\n\t\tbool Fix(TP tp)\n\t\t{\n\t\t\tLog.WriteLine(\" Trying to fix \" + tp);\n\t\t\tDebug.Assert(!tp.IsFixed);\n\t\t\tif (tp.ExactBound != null)\n\t\t\t{\n\t\t\t\t// the exact bound will always be the result\n\t\t\t\ttp.FixedTo = tp.ExactBound;\n\t\t\t\t// check validity\n\t\t\t\tif (tp.MultipleDifferentExactBounds)\n\t\t\t\t\treturn false;\n\t\t\t\treturn tp.LowerBounds.All(b => conversions.ImplicitConversion(b, tp.FixedTo).IsValid)\n\t\t\t\t\t&& tp.UpperBounds.All(b => conversions.ImplicitConversion(tp.FixedTo, b).IsValid);\n\t\t\t}\n\t\t\tLog.Indent();\n\t\t\tvar types = CreateNestedInstance().FindTypesInBounds(tp.LowerBounds.ToArray(), tp.UpperBounds.ToArray());\n\t\t\tLog.Unindent();\n\t\t\tif (algorithm == TypeInferenceAlgorithm.ImprovedReturnAllResults)\n\t\t\t{\n\t\t\t\ttp.FixedTo = IntersectionType.Create(types);\n\t\t\t\tLog.WriteLine(\"  T was fixed \" + (types.Count >= 1 ? \"successfully\" : \"(with errors)\") + \" to \" + tp.FixedTo);\n\t\t\t\treturn types.Count >= 1;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttp.FixedTo = GetFirstTypePreferNonInterfaces(types);\n\t\t\t\tLog.WriteLine(\"  T was fixed \" + (types.Count == 1 ? \"successfully\" : \"(with errors)\") + \" to \" + tp.FixedTo);\n\t\t\t\treturn types.Count == 1;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Finding the best common type of a set of expresssions\n\t\t/// <summary>\n\t\t/// Gets the best common type (C# 4.0 spec: §7.5.2.14) of a set of expressions.\n\t\t/// </summary>\n\t\tpublic IType GetBestCommonType(IList<ResolveResult> expressions, out bool success)\n\t\t{\n\t\t\tif (expressions == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(expressions));\n\t\t\tif (expressions.Count == 1)\n\t\t\t{\n\t\t\t\tsuccess = IsValidType(expressions[0].Type);\n\t\t\t\treturn expressions[0].Type;\n\t\t\t}\n\t\t\tLog.WriteCollection(\"GetBestCommonType() for \", expressions);\n\t\t\ttry\n\t\t\t{\n\t\t\t\tITypeParameter tp = DummyTypeParameter.GetMethodTypeParameter(0);\n\t\t\t\tthis.typeParameters = new TP[1] { new TP(tp) };\n\t\t\t\tforeach (ResolveResult r in expressions)\n\t\t\t\t{\n\t\t\t\t\tMakeOutputTypeInference(r, tp);\n\t\t\t\t}\n\t\t\t\tsuccess = Fix(typeParameters[0]);\n\t\t\t\treturn typeParameters[0].FixedTo ?? SpecialType.UnknownType;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tReset();\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region FindTypeInBounds\n\t\t/// <summary>\n\t\t/// Finds a type that satisfies the given lower and upper bounds.\n\t\t/// </summary>\n\t\tpublic IType FindTypeInBounds(IReadOnlyList<IType> lowerBounds, IReadOnlyList<IType> upperBounds)\n\t\t{\n\t\t\tif (lowerBounds == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(lowerBounds));\n\t\t\tif (upperBounds == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(upperBounds));\n\n\t\t\tvar result = FindTypesInBounds(lowerBounds, upperBounds);\n\n\t\t\tif (algorithm == TypeInferenceAlgorithm.ImprovedReturnAllResults)\n\t\t\t{\n\t\t\t\treturn IntersectionType.Create(result);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// return any of the candidates (prefer non-interfaces)\n\t\t\t\treturn GetFirstTypePreferNonInterfaces(result);\n\t\t\t}\n\t\t}\n\n\t\tstatic IType GetFirstTypePreferNonInterfaces(IReadOnlyList<IType> result)\n\t\t{\n\t\t\treturn result.FirstOrDefault(c => c.Kind != TypeKind.Interface)\n\t\t\t\t?? result.FirstOrDefault() ?? SpecialType.UnknownType;\n\t\t}\n\n\t\tIReadOnlyList<IType> FindTypesInBounds(IReadOnlyList<IType> lowerBounds, IReadOnlyList<IType> upperBounds)\n\t\t{\n\t\t\t// If there's only a single type; return that single type.\n\t\t\t// If both inputs are empty, return the empty list.\n\t\t\tif (lowerBounds.Count == 0 && upperBounds.Count <= 1)\n\t\t\t\treturn upperBounds;\n\t\t\tif (upperBounds.Count == 0 && lowerBounds.Count <= 1)\n\t\t\t\treturn lowerBounds;\n\t\t\tif (nestingLevel > maxNestingLevel)\n\t\t\t\treturn EmptyList<IType>.Instance;\n\n\t\t\t// Finds a type X so that \"LB <: X <: UB\"\n\t\t\tLog.WriteCollection(\"FindTypesInBound, LowerBounds=\", lowerBounds);\n\t\t\tLog.WriteCollection(\"FindTypesInBound, UpperBounds=\", upperBounds);\n\n\t\t\t// First try the Fixing algorithm from the C# spec (§7.5.2.11)\n\t\t\tList<IType> candidateTypes = lowerBounds.Union(upperBounds)\n\t\t\t\t.Where(c => lowerBounds.All(b => conversions.ImplicitConversion(b, c).IsValid))\n\t\t\t\t.Where(c => upperBounds.All(b => conversions.ImplicitConversion(c, b).IsValid))\n\t\t\t\t.ToList(); // evaluate the query only once\n\n\t\t\tLog.WriteCollection(\"FindTypesInBound, Candidates=\", candidateTypes);\n\n\t\t\t// According to the C# specification, we need to pick the most specific\n\t\t\t// of the candidate types. (the type which has conversions to all others)\n\t\t\t// However, csc actually seems to choose the least specific.\n\t\t\tcandidateTypes = candidateTypes.Where(\n\t\t\t\tc => candidateTypes.All(o => conversions.ImplicitConversion(o, c).IsValid)\n\t\t\t).ToList();\n\n\t\t\t// If the specified algorithm produces a single candidate, we return\n\t\t\t// that candidate.\n\t\t\t// We also return the whole candidate list if we're not using the improved\n\t\t\t// algorithm.\n\t\t\tif (candidateTypes.Count == 1 || !(algorithm == TypeInferenceAlgorithm.Improved || algorithm == TypeInferenceAlgorithm.ImprovedReturnAllResults))\n\t\t\t{\n\t\t\t\treturn candidateTypes;\n\t\t\t}\n\t\t\tcandidateTypes.Clear();\n\n\t\t\t// Now try the improved algorithm\n\t\t\tLog.Indent();\n\t\t\tList<ITypeDefinition> candidateTypeDefinitions;\n\t\t\tif (lowerBounds.Count > 0)\n\t\t\t{\n\t\t\t\t// Find candidates by using the lower bounds:\n\t\t\t\tvar hashSet = new HashSet<ITypeDefinition>(lowerBounds[0].GetAllBaseTypeDefinitions());\n\t\t\t\tfor (int i = 1; i < lowerBounds.Count; i++)\n\t\t\t\t{\n\t\t\t\t\thashSet.IntersectWith(lowerBounds[i].GetAllBaseTypeDefinitions());\n\t\t\t\t}\n\t\t\t\tcandidateTypeDefinitions = hashSet.ToList();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Find candidates by looking at all classes in the project:\n\t\t\t\tcandidateTypeDefinitions = compilation.GetAllTypeDefinitions().ToList();\n\t\t\t}\n\n\t\t\t// Now filter out candidates that violate the upper bounds:\n\t\t\tforeach (IType ub in upperBounds)\n\t\t\t{\n\t\t\t\tITypeDefinition ubDef = ub.GetDefinition();\n\t\t\t\tif (ubDef != null)\n\t\t\t\t{\n\t\t\t\t\tcandidateTypeDefinitions.RemoveAll(c => !c.IsDerivedFrom(ubDef));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach (ITypeDefinition candidateDef in candidateTypeDefinitions)\n\t\t\t{\n\t\t\t\t// determine the type parameters for the candidate:\n\t\t\t\tIType candidate;\n\t\t\t\tif (candidateDef.TypeParameterCount == 0)\n\t\t\t\t{\n\t\t\t\t\tcandidate = candidateDef;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tLog.WriteLine(\"Inferring arguments for candidate type definition: \" + candidateDef);\n\t\t\t\t\tbool success;\n\t\t\t\t\tIType[] result = InferTypeArgumentsFromBounds(\n\t\t\t\t\t\tcandidateDef.TypeParameters,\n\t\t\t\t\t\tnew ParameterizedType(candidateDef, candidateDef.TypeParameters),\n\t\t\t\t\t\tlowerBounds, upperBounds,\n\t\t\t\t\t\tout success);\n\t\t\t\t\tif (success)\n\t\t\t\t\t{\n\t\t\t\t\t\tcandidate = new ParameterizedType(candidateDef, result);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tLog.WriteLine(\"Inference failed; ignoring candidate\");\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tLog.WriteLine(\"Candidate type: \" + candidate);\n\n\t\t\t\tif (upperBounds.Count == 0)\n\t\t\t\t{\n\t\t\t\t\t// if there were only lower bounds, we aim for the most specific candidate:\n\n\t\t\t\t\t// if this candidate isn't made redundant by an existing, more specific candidate:\n\t\t\t\t\tif (!candidateTypes.Any(c => c.GetDefinition().IsDerivedFrom(candidateDef)))\n\t\t\t\t\t{\n\t\t\t\t\t\t// remove all existing candidates made redundant by this candidate:\n\t\t\t\t\t\tcandidateTypes.RemoveAll(c => candidateDef.IsDerivedFrom(c.GetDefinition()));\n\t\t\t\t\t\t// add new candidate\n\t\t\t\t\t\tcandidateTypes.Add(candidate);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// if there were upper bounds, we aim for the least specific candidate:\n\n\t\t\t\t\t// if this candidate isn't made redundant by an existing, less specific candidate:\n\t\t\t\t\tif (!candidateTypes.Any(c => candidateDef.IsDerivedFrom(c.GetDefinition())))\n\t\t\t\t\t{\n\t\t\t\t\t\t// remove all existing candidates made redundant by this candidate:\n\t\t\t\t\t\tcandidateTypes.RemoveAll(c => c.GetDefinition().IsDerivedFrom(candidateDef));\n\t\t\t\t\t\t// add new candidate\n\t\t\t\t\t\tcandidateTypes.Add(candidate);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tLog.Unindent();\n\t\t\treturn candidateTypes;\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs",
    "content": "// Copyright (c) 2017 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.DebugInfo;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp\n{\n\t/// <summary>\n\t/// Given a SyntaxTree that was output from the decompiler, constructs the list of sequence points.\n\t/// </summary>\n\t// Each statement / expression AST node is annotated with the ILInstruction(s) it was constructed from.\n\t// Each ILInstruction has a list of IL offsets corresponding to the original IL range(s). Note that the ILAst\n\t// instructions form a tree.\n\t//\n\t// This visitor constructs a list of sequence points from the syntax tree by visiting each node,\n\t// calling\n\t// 1. StartSequencePoint(AstNode)\n\t// 2. AddToSequencePoint(AstNode) (possibly multiple times)\n\t// 3. EndSequencePoint(TextLocation, TextLocation)\n\t// on each node.\n\t//\n\t// The VisitAsSequencePoint(AstNode) method encapsulates the steps above.\n\t//\n\t// The state we record for each sequence point is decribed in StatePerSequencePoint:\n\t// 1. primary AST node\n\t// 2. IL range intervals\n\t// 3. parent ILFunction (either a method or lambda)\n\t//\n\t// For each statement (at least) one sequence point is created and all expressions and their IL ranges\n\t// are added to it. Currently the debugger seems not to support breakpoints at an expression level, so\n\t// we stop at the statement level and add all sub-expressions to the same sequence point.\n\t//\n\t// LambdaExpression is one exception: we create new sequence points for the expression/statements of the lambda,\n\t// note however, that these are added to a different ILFunction.\n\t//\n\t// AddToSequencePoint(AstNode) handles the list of ILInstructions and visits each ILInstruction and its descendants.\n\t// We do not descend into nested ILFunctions as these create their own list of sequence points.\n\tclass SequencePointBuilder : DepthFirstAstVisitor\n\t{\n\t\tstruct StatePerSequencePoint\n\t\t{\n\t\t\t/// <summary>\n\t\t\t/// Main AST node associated with this sequence point.\n\t\t\t/// </summary>\n\t\t\tinternal readonly AstNode PrimaryNode;\n\n\t\t\t/// <summary>\n\t\t\t/// List of IL intervals that are associated with this sequence point.\n\t\t\t/// </summary>\n\t\t\tinternal readonly List<Interval> Intervals;\n\n\t\t\t/// <summary>\n\t\t\t/// The function containing this sequence point.\n\t\t\t/// </summary>\n\t\t\tinternal ILFunction Function;\n\n\t\t\tpublic StatePerSequencePoint(AstNode primaryNode)\n\t\t\t{\n\t\t\t\tthis.PrimaryNode = primaryNode;\n\t\t\t\tthis.Intervals = new List<Interval>();\n\t\t\t\tthis.Function = null;\n\t\t\t}\n\t\t}\n\n\t\treadonly List<(ILFunction, DebugInfo.SequencePoint)> sequencePoints = new List<(ILFunction, DebugInfo.SequencePoint)>();\n\t\treadonly HashSet<ILInstruction> mappedInstructions = new HashSet<ILInstruction>();\n\n\t\t// Stack holding information for outer statements.\n\t\treadonly Stack<StatePerSequencePoint> outerStates = new Stack<StatePerSequencePoint>();\n\n\t\t// Collects information for the current sequence point.\n\t\tStatePerSequencePoint current;\n\n\t\tvoid VisitAsSequencePoint(AstNode node)\n\t\t{\n\t\t\tif (node.IsNull)\n\t\t\t\treturn;\n\t\t\tStartSequencePoint(node);\n\t\t\tnode.AcceptVisitor(this);\n\t\t\tEndSequencePoint(node.StartLocation, node.EndLocation);\n\t\t}\n\n\t\tprotected override void VisitChildren(AstNode node)\n\t\t{\n\t\t\tbase.VisitChildren(node);\n\t\t\tAddToSequencePoint(node);\n\t\t}\n\n\t\tpublic override void VisitBlockStatement(BlockStatement blockStatement)\n\t\t{\n\t\t\t// enhanced using variables need special-casing here, because we omit the block syntax from the\n\t\t\t// text output, so we cannot use positions of opening/closing braces here.\n\t\t\tbool isEnhancedUsing = blockStatement.Parent is UsingStatement us && us.IsEnhanced;\n\t\t\tif (!isEnhancedUsing)\n\t\t\t{\n\t\t\t\tvar blockContainer = blockStatement.Annotation<BlockContainer>();\n\t\t\t\tif (blockContainer != null)\n\t\t\t\t{\n\t\t\t\t\tStartSequencePoint(blockStatement.LBraceToken);\n\t\t\t\t\tint intervalStart;\n\t\t\t\t\tif (blockContainer.Parent is TryCatchHandler handler && !handler.ExceptionSpecifierILRange.IsEmpty)\n\t\t\t\t\t{\n\t\t\t\t\t\t// if this block container is part of a TryCatchHandler, do not steal the\n\t\t\t\t\t\t// exception-specifier IL range\n\t\t\t\t\t\tintervalStart = handler.ExceptionSpecifierILRange.End;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tintervalStart = blockContainer.StartILOffset;\n\t\t\t\t\t}\n\t\t\t\t\t// The end will be set to the first sequence point candidate location before the first\n\t\t\t\t\t// statement of the function when the seqeunce point is adjusted\n\t\t\t\t\tint intervalEnd = intervalStart + 1;\n\n\t\t\t\t\tInterval interval = new Interval(intervalStart, intervalEnd);\n\t\t\t\t\tList<Interval> intervals = new List<Interval>();\n\t\t\t\t\tintervals.Add(interval);\n\t\t\t\t\tcurrent.Intervals.AddRange(intervals);\n\t\t\t\t\tcurrent.Function = blockContainer.Ancestors.OfType<ILFunction>().FirstOrDefault();\n\t\t\t\t\tEndSequencePoint(blockStatement.LBraceToken.StartLocation, blockStatement.LBraceToken.EndLocation);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Ideally, we'd be able to address this case. Blocks that are not the top-level function\n\t\t\t\t\t// block have no ILInstruction annotations. It isn't clear to me how to determine the il range.\n\t\t\t\t\t// For now, do not add the opening brace sequence in this case.\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach (var stmt in blockStatement.Statements)\n\t\t\t{\n\t\t\t\tVisitAsSequencePoint(stmt);\n\t\t\t}\n\t\t\tvar implicitReturn = blockStatement.Annotation<ImplicitReturnAnnotation>();\n\t\t\tif (implicitReturn != null && !isEnhancedUsing)\n\t\t\t{\n\t\t\t\tStartSequencePoint(blockStatement.RBraceToken);\n\t\t\t\tAddToSequencePoint(implicitReturn.Leave);\n\t\t\t\tEndSequencePoint(blockStatement.RBraceToken.StartLocation, blockStatement.RBraceToken.EndLocation);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)\n\t\t{\n\t\t\tif (!propertyDeclaration.ExpressionBody.IsNull)\n\t\t\t{\n\t\t\t\tVisitAsSequencePoint(propertyDeclaration.ExpressionBody);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbase.VisitPropertyDeclaration(propertyDeclaration);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration)\n\t\t{\n\t\t\tif (!indexerDeclaration.ExpressionBody.IsNull)\n\t\t\t{\n\t\t\t\tVisitAsSequencePoint(indexerDeclaration.ExpressionBody);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbase.VisitIndexerDeclaration(indexerDeclaration);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void VisitForStatement(ForStatement forStatement)\n\t\t{\n\t\t\t// Every element of a for-statement is its own sequence point.\n\t\t\tforeach (var init in forStatement.Initializers)\n\t\t\t{\n\t\t\t\tVisitAsSequencePoint(init);\n\t\t\t}\n\t\t\tVisitAsSequencePoint(forStatement.Condition);\n\t\t\tforeach (var inc in forStatement.Iterators)\n\t\t\t{\n\t\t\t\tVisitAsSequencePoint(inc);\n\t\t\t}\n\t\t\tVisitAsSequencePoint(forStatement.EmbeddedStatement);\n\t\t}\n\n\t\tpublic override void VisitSwitchStatement(SwitchStatement switchStatement)\n\t\t{\n\t\t\tStartSequencePoint(switchStatement);\n\t\t\tswitchStatement.Expression.AcceptVisitor(this);\n\t\t\tforeach (var section in switchStatement.SwitchSections)\n\t\t\t{\n\t\t\t\t// note: sections will not contribute to the current sequence point\n\t\t\t\tsection.AcceptVisitor(this);\n\t\t\t}\n\t\t\t// add switch statement itself to sequence point\n\t\t\t// (call only after the sections are visited)\n\t\t\tAddToSequencePoint(switchStatement);\n\t\t\tEndSequencePoint(switchStatement.StartLocation, switchStatement.RParToken.EndLocation);\n\t\t}\n\n\t\tpublic override void VisitSwitchSection(Syntax.SwitchSection switchSection)\n\t\t{\n\t\t\t// every statement in the switch section is its own sequence point\n\t\t\tforeach (var stmt in switchSection.Statements)\n\t\t\t{\n\t\t\t\tVisitAsSequencePoint(stmt);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void VisitLambdaExpression(LambdaExpression lambdaExpression)\n\t\t{\n\t\t\tAddToSequencePoint(lambdaExpression);\n\t\t\tVisitAsSequencePoint(lambdaExpression.Body);\n\t\t}\n\n\t\tpublic override void VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause)\n\t\t{\n\t\t\tAddToSequencePoint(queryContinuationClause);\n\t\t\tVisitAsSequencePoint(queryContinuationClause.PrecedingQuery);\n\t\t}\n\n\t\tpublic override void VisitQueryFromClause(QueryFromClause queryFromClause)\n\t\t{\n\t\t\tif (queryFromClause.Parent.FirstChild != queryFromClause)\n\t\t\t{\n\t\t\t\tAddToSequencePoint(queryFromClause);\n\t\t\t\tVisitAsSequencePoint(queryFromClause.Expression);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbase.VisitQueryFromClause(queryFromClause);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void VisitQueryGroupClause(QueryGroupClause queryGroupClause)\n\t\t{\n\t\t\tAddToSequencePoint(queryGroupClause);\n\t\t\tVisitAsSequencePoint(queryGroupClause.Projection);\n\t\t\tVisitAsSequencePoint(queryGroupClause.Key);\n\t\t}\n\n\t\tpublic override void VisitQueryJoinClause(QueryJoinClause queryJoinClause)\n\t\t{\n\t\t\tAddToSequencePoint(queryJoinClause);\n\t\t\tVisitAsSequencePoint(queryJoinClause.OnExpression);\n\t\t\tVisitAsSequencePoint(queryJoinClause.EqualsExpression);\n\t\t}\n\n\t\tpublic override void VisitQueryLetClause(QueryLetClause queryLetClause)\n\t\t{\n\t\t\tAddToSequencePoint(queryLetClause);\n\t\t\tVisitAsSequencePoint(queryLetClause.Expression);\n\t\t}\n\n\t\tpublic override void VisitQueryOrdering(QueryOrdering queryOrdering)\n\t\t{\n\t\t\tAddToSequencePoint(queryOrdering);\n\t\t\tVisitAsSequencePoint(queryOrdering.Expression);\n\t\t}\n\n\t\tpublic override void VisitQuerySelectClause(QuerySelectClause querySelectClause)\n\t\t{\n\t\t\tAddToSequencePoint(querySelectClause);\n\t\t\tVisitAsSequencePoint(querySelectClause.Expression);\n\t\t}\n\n\t\tpublic override void VisitQueryWhereClause(QueryWhereClause queryWhereClause)\n\t\t{\n\t\t\tAddToSequencePoint(queryWhereClause);\n\t\t\tVisitAsSequencePoint(queryWhereClause.Condition);\n\t\t}\n\n\t\tpublic override void VisitUsingStatement(UsingStatement usingStatement)\n\t\t{\n\t\t\tStartSequencePoint(usingStatement);\n\t\t\tusingStatement.ResourceAcquisition.AcceptVisitor(this);\n\t\t\tVisitAsSequencePoint(usingStatement.EmbeddedStatement);\n\t\t\tAddToSequencePoint(usingStatement);\n\t\t\tif (usingStatement.IsEnhanced)\n\t\t\t\tEndSequencePoint(usingStatement.StartLocation, usingStatement.ResourceAcquisition.EndLocation);\n\t\t\telse\n\t\t\t\tEndSequencePoint(usingStatement.StartLocation, usingStatement.RParToken.EndLocation);\n\t\t}\n\n\t\tpublic override void VisitForeachStatement(ForeachStatement foreachStatement)\n\t\t{\n\t\t\tvar foreachInfo = foreachStatement.Annotation<ForeachAnnotation>();\n\t\t\tif (foreachInfo == null)\n\t\t\t{\n\t\t\t\tbase.VisitForeachStatement(foreachStatement);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// TODO : Add a sequence point on foreach token (mapped to nop before using instruction).\n\t\t\tStartSequencePoint(foreachStatement);\n\t\t\tforeachStatement.InExpression.AcceptVisitor(this);\n\t\t\tAddToSequencePoint(foreachInfo.GetEnumeratorCall);\n\t\t\tEndSequencePoint(foreachStatement.InExpression.StartLocation, foreachStatement.InExpression.EndLocation);\n\n\t\t\tStartSequencePoint(foreachStatement);\n\t\t\tAddToSequencePoint(foreachInfo.MoveNextCall);\n\t\t\tEndSequencePoint(foreachStatement.InToken.StartLocation, foreachStatement.InToken.EndLocation);\n\n\t\t\tStartSequencePoint(foreachStatement);\n\t\t\tAddToSequencePoint(foreachInfo.GetCurrentCall);\n\t\t\tEndSequencePoint(foreachStatement.VariableType.StartLocation, foreachStatement.VariableDesignation.EndLocation);\n\n\t\t\tVisitAsSequencePoint(foreachStatement.EmbeddedStatement);\n\t\t}\n\n\t\tpublic override void VisitLockStatement(LockStatement lockStatement)\n\t\t{\n\t\t\tStartSequencePoint(lockStatement);\n\t\t\tlockStatement.Expression.AcceptVisitor(this);\n\t\t\tVisitAsSequencePoint(lockStatement.EmbeddedStatement);\n\t\t\tAddToSequencePoint(lockStatement);\n\t\t\tEndSequencePoint(lockStatement.StartLocation, lockStatement.RParToken.EndLocation);\n\t\t}\n\n\t\tpublic override void VisitIfElseStatement(IfElseStatement ifElseStatement)\n\t\t{\n\t\t\tStartSequencePoint(ifElseStatement);\n\t\t\tifElseStatement.Condition.AcceptVisitor(this);\n\t\t\tVisitAsSequencePoint(ifElseStatement.TrueStatement);\n\t\t\tVisitAsSequencePoint(ifElseStatement.FalseStatement);\n\t\t\tAddToSequencePoint(ifElseStatement);\n\t\t\tEndSequencePoint(ifElseStatement.StartLocation, ifElseStatement.RParToken.EndLocation);\n\t\t}\n\n\t\tpublic override void VisitWhileStatement(WhileStatement whileStatement)\n\t\t{\n\t\t\tStartSequencePoint(whileStatement);\n\t\t\twhileStatement.Condition.AcceptVisitor(this);\n\t\t\tVisitAsSequencePoint(whileStatement.EmbeddedStatement);\n\t\t\tAddToSequencePoint(whileStatement);\n\t\t\tEndSequencePoint(whileStatement.StartLocation, whileStatement.RParToken.EndLocation);\n\t\t}\n\n\t\tpublic override void VisitDoWhileStatement(DoWhileStatement doWhileStatement)\n\t\t{\n\t\t\tStartSequencePoint(doWhileStatement);\n\t\t\tVisitAsSequencePoint(doWhileStatement.EmbeddedStatement);\n\t\t\tdoWhileStatement.Condition.AcceptVisitor(this);\n\t\t\tAddToSequencePoint(doWhileStatement);\n\t\t\tEndSequencePoint(doWhileStatement.WhileToken.StartLocation, doWhileStatement.RParToken.EndLocation);\n\t\t}\n\n\t\tpublic override void VisitFixedStatement(FixedStatement fixedStatement)\n\t\t{\n\t\t\tforeach (var v in fixedStatement.Variables)\n\t\t\t{\n\t\t\t\tVisitAsSequencePoint(v);\n\t\t\t}\n\t\t\tVisitAsSequencePoint(fixedStatement.EmbeddedStatement);\n\t\t}\n\n\t\tpublic override void VisitTryCatchStatement(TryCatchStatement tryCatchStatement)\n\t\t{\n\t\t\tVisitAsSequencePoint(tryCatchStatement.TryBlock);\n\t\t\tforeach (var c in tryCatchStatement.CatchClauses)\n\t\t\t{\n\t\t\t\tVisitAsSequencePoint(c);\n\t\t\t}\n\t\t\tVisitAsSequencePoint(tryCatchStatement.FinallyBlock);\n\t\t}\n\n\t\tpublic override void VisitCatchClause(CatchClause catchClause)\n\t\t{\n\t\t\tif (catchClause.Condition.IsNull)\n\t\t\t{\n\t\t\t\tvar tryCatchHandler = catchClause.Annotation<TryCatchHandler>();\n\t\t\t\tif (tryCatchHandler != null && !tryCatchHandler.ExceptionSpecifierILRange.IsEmpty)\n\t\t\t\t{\n\t\t\t\t\tStartSequencePoint(catchClause.CatchToken);\n\t\t\t\t\tvar function = tryCatchHandler.Ancestors.OfType<ILFunction>().FirstOrDefault();\n\t\t\t\t\tAddToSequencePointRaw(function, new[] { tryCatchHandler.ExceptionSpecifierILRange });\n\t\t\t\t\tEndSequencePoint(catchClause.CatchToken.StartLocation, catchClause.RParToken.IsNull ? catchClause.CatchToken.EndLocation : catchClause.RParToken.EndLocation);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tStartSequencePoint(catchClause.WhenToken);\n\t\t\t\tAddToSequencePoint(catchClause.Condition);\n\t\t\t\tEndSequencePoint(catchClause.WhenToken.StartLocation, catchClause.CondRParToken.EndLocation);\n\t\t\t}\n\t\t\tVisitAsSequencePoint(catchClause.Body);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Start a new C# statement = new sequence point.\n\t\t/// </summary>\n\t\tvoid StartSequencePoint(AstNode primaryNode)\n\t\t{\n\t\t\touterStates.Push(current);\n\t\t\tcurrent = new StatePerSequencePoint(primaryNode);\n\t\t}\n\n\t\tvoid EndSequencePoint(TextLocation startLocation, TextLocation endLocation)\n\t\t{\n\t\t\tDebug.Assert(!startLocation.IsEmpty, \"missing startLocation\");\n\t\t\tDebug.Assert(!endLocation.IsEmpty, \"missing endLocation\");\n\t\t\tif (current.Intervals.Count > 0 && current.Function != null)\n\t\t\t{\n\t\t\t\t// use LongSet to deduplicate and merge the intervals\n\t\t\t\tvar longSet = new LongSet(current.Intervals.Select(i => new LongInterval(i.Start, i.End)));\n\t\t\t\tDebug.Assert(!longSet.IsEmpty);\n\t\t\t\tsequencePoints.Add((current.Function, new DebugInfo.SequencePoint {\n\t\t\t\t\tOffset = (int)longSet.Intervals[0].Start,\n\t\t\t\t\tEndOffset = (int)longSet.Intervals[0].End,\n\t\t\t\t\tStartLine = startLocation.Line,\n\t\t\t\t\tStartColumn = startLocation.Column,\n\t\t\t\t\tEndLine = endLocation.Line,\n\t\t\t\t\tEndColumn = endLocation.Column\n\t\t\t\t}));\n\t\t\t}\n\t\t\tcurrent = outerStates.Pop();\n\t\t}\n\n\t\tvoid AddToSequencePointRaw(ILFunction function, IEnumerable<Interval> ranges)\n\t\t{\n\t\t\tcurrent.Intervals.AddRange(ranges);\n\t\t\tDebug.Assert(current.Function == null || current.Function == function);\n\t\t\tcurrent.Function = function;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Add the ILAst instruction associated with the AstNode to the sequence point.\n\t\t/// Also add all its ILAst sub-instructions (unless they were already added to another sequence point).\n\t\t/// </summary>\n\t\tvoid AddToSequencePoint(AstNode node)\n\t\t{\n\t\t\tforeach (var inst in node.Annotations.OfType<ILInstruction>())\n\t\t\t{\n\t\t\t\tAddToSequencePoint(inst);\n\t\t\t}\n\t\t}\n\n\t\tvoid AddToSequencePoint(ILInstruction inst)\n\t\t{\n\t\t\tif (!mappedInstructions.Add(inst))\n\t\t\t{\n\t\t\t\t// inst was already used by a nested sequence point within this sequence point\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Add the IL range associated with this instruction to the current sequence point.\n\t\t\tif (HasUsableILRange(inst) && current.Intervals != null)\n\t\t\t{\n\t\t\t\tcurrent.Intervals.AddRange(inst.ILRanges);\n\t\t\t\tvar function = inst.Parent.Ancestors.OfType<ILFunction>().FirstOrDefault();\n\t\t\t\tDebug.Assert(current.Function == null || current.Function == function);\n\t\t\t\tcurrent.Function = function;\n\t\t\t}\n\n\t\t\t// Do not add instructions of lambdas/delegates.\n\t\t\tif (inst is ILFunction)\n\t\t\t\treturn;\n\n\t\t\t// Also add the child IL instructions, unless they were already processed by\n\t\t\t// another C# expression.\n\t\t\tforeach (var child in inst.Children)\n\t\t\t{\n\t\t\t\tAddToSequencePoint(child);\n\t\t\t}\n\t\t}\n\n\t\tinternal static bool HasUsableILRange(ILInstruction inst)\n\t\t{\n\t\t\tif (inst.ILRangeIsEmpty)\n\t\t\t\treturn false;\n\t\t\tif (inst.Parent == null)\n\t\t\t\treturn false;\n\t\t\treturn !(inst is BlockContainer || inst is Block);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Called after the visitor is done to return the results.\n\t\t/// </summary>\n\t\tinternal Dictionary<ILFunction, List<DebugInfo.SequencePoint>> GetSequencePoints()\n\t\t{\n\t\t\tvar dict = new Dictionary<ILFunction, List<DebugInfo.SequencePoint>>();\n\t\t\tforeach (var (function, sequencePoint) in this.sequencePoints)\n\t\t\t{\n\t\t\t\tif (!dict.TryGetValue(function, out var list))\n\t\t\t\t{\n\t\t\t\t\tdict.Add(function, list = new List<DebugInfo.SequencePoint>());\n\t\t\t\t}\n\t\t\t\tlist.Add(sequencePoint);\n\t\t\t}\n\n\t\t\tforeach (var (function, list) in dict.ToList())\n\t\t\t{\n\t\t\t\t// For each function, sort sequence points and fix overlaps\n\t\t\t\tvar newList = new List<DebugInfo.SequencePoint>();\n\t\t\t\tint pos = 0;\n\t\t\t\tIOrderedEnumerable<DebugInfo.SequencePoint> currFunctionSequencePoints = list.OrderBy(sp => sp.Offset).ThenBy(sp => sp.EndOffset);\n\t\t\t\tforeach (DebugInfo.SequencePoint sequencePoint in currFunctionSequencePoints)\n\t\t\t\t{\n\t\t\t\t\tif (sequencePoint.Offset < pos)\n\t\t\t\t\t{\n\t\t\t\t\t\t// overlapping sequence point?\n\t\t\t\t\t\t// delete previous sequence points that are after sequencePoint.Offset\n\t\t\t\t\t\twhile (newList.Count > 0 && newList.Last().EndOffset > sequencePoint.Offset)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar last = newList.Last();\n\t\t\t\t\t\t\tif (last.Offset >= sequencePoint.Offset)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tnewList.RemoveAt(newList.Count - 1);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlast.EndOffset = sequencePoint.Offset;\n\t\t\t\t\t\t\t\tnewList[newList.Count - 1] = last;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tnewList.Add(sequencePoint);\n\t\t\t\t\tpos = sequencePoint.EndOffset;\n\t\t\t\t}\n\t\t\t\t// Add a hidden sequence point to account for the epilog of the function\n\t\t\t\tif (pos < function.CodeSize)\n\t\t\t\t{\n\t\t\t\t\tvar hidden = new DebugInfo.SequencePoint();\n\t\t\t\t\thidden.Offset = pos;\n\t\t\t\t\thidden.EndOffset = function.CodeSize;\n\t\t\t\t\thidden.SetHidden();\n\t\t\t\t\tnewList.Add(hidden);\n\t\t\t\t}\n\n\t\t\t\tList<int> sequencePointCandidates = function.SequencePointCandidates;\n\t\t\t\tint currSPCandidateIndex = 0;\n\n\t\t\t\tfor (int i = 0; i < newList.Count - 1; i++)\n\t\t\t\t{\n\t\t\t\t\tDebugInfo.SequencePoint currSequencePoint = newList[i];\n\t\t\t\t\tDebugInfo.SequencePoint nextSequencePoint = newList[i + 1];\n\n\t\t\t\t\t// Adjust the end offset of the current sequence point to the closest sequence point candidate\n\t\t\t\t\t// but do not create an overlapping sequence point. Moving the start of the current sequence\n\t\t\t\t\t// point is not required as it is 0 for the first sequence point and is moved during the last \n\t\t\t\t\t// iteration for all others.\n\t\t\t\t\twhile (currSPCandidateIndex < sequencePointCandidates.Count &&\n\t\t\t\t\t\tsequencePointCandidates[currSPCandidateIndex] < currSequencePoint.EndOffset)\n\t\t\t\t\t{\n\t\t\t\t\t\tcurrSPCandidateIndex++;\n\t\t\t\t\t}\n\t\t\t\t\tif (currSPCandidateIndex < sequencePointCandidates.Count && sequencePointCandidates[currSPCandidateIndex] <= nextSequencePoint.Offset)\n\t\t\t\t\t{\n\t\t\t\t\t\tcurrSequencePoint.EndOffset = sequencePointCandidates[currSPCandidateIndex];\n\t\t\t\t\t}\n\n\t\t\t\t\t// Adjust the start offset of the next sequence point to the closest previous sequence point candidate\n\t\t\t\t\t// but do not create an overlapping sequence point. \n\t\t\t\t\twhile (currSPCandidateIndex < sequencePointCandidates.Count &&\n\t\t\t\t\t\tsequencePointCandidates[currSPCandidateIndex] < nextSequencePoint.Offset)\n\t\t\t\t\t{\n\t\t\t\t\t\tcurrSPCandidateIndex++;\n\t\t\t\t\t}\n\t\t\t\t\tif (currSPCandidateIndex < sequencePointCandidates.Count && sequencePointCandidates[currSPCandidateIndex - 1] >= currSequencePoint.EndOffset)\n\t\t\t\t\t{\n\t\t\t\t\t\tnextSequencePoint.Offset = sequencePointCandidates[currSPCandidateIndex - 1];\n\t\t\t\t\t\tcurrSPCandidateIndex--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fill in any gaps with a hidden sequence point\n\t\t\t\t\tif (currSequencePoint.EndOffset != nextSequencePoint.Offset)\n\t\t\t\t\t{\n\t\t\t\t\t\tSequencePoint newSP = new SequencePoint() { Offset = currSequencePoint.EndOffset, EndOffset = nextSequencePoint.Offset };\n\t\t\t\t\t\tnewSP.SetHidden();\n\t\t\t\t\t\tnewList.Insert(++i, newSP);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdict[function] = newList;\n\t\t\t}\n\n\t\t\treturn dict;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/StatementBuilder.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp\n{\n\tsealed class StatementBuilder : ILVisitor<TranslatedStatement>\n\t{\n\t\tinternal readonly ExpressionBuilder exprBuilder;\n\t\treadonly ILFunction currentFunction;\n\t\treadonly IDecompilerTypeSystem typeSystem;\n\t\tinternal readonly DecompileRun decompileRun;\n\t\treadonly DecompilerSettings settings;\n\t\treadonly CancellationToken cancellationToken;\n\n\t\tinternal BlockContainer currentReturnContainer;\n\t\tinternal IType currentResultType;\n\t\tinternal bool currentIsIterator;\n\n\t\tinternal bool EmitAsRefReadOnly;\n\n\t\tpublic StatementBuilder(IDecompilerTypeSystem typeSystem, ITypeResolveContext decompilationContext,\n\t\t\tILFunction currentFunction, DecompilerSettings settings, DecompileRun decompileRun,\n\t\t\tCancellationToken cancellationToken)\n\t\t{\n\t\t\tDebug.Assert(typeSystem != null && decompilationContext != null);\n\t\t\tthis.exprBuilder = new ExpressionBuilder(\n\t\t\t\tthis,\n\t\t\t\ttypeSystem,\n\t\t\t\tdecompilationContext,\n\t\t\t\tcurrentFunction,\n\t\t\t\tsettings,\n\t\t\t\tdecompileRun,\n\t\t\t\tcancellationToken\n\t\t\t);\n\t\t\tthis.currentFunction = currentFunction;\n\t\t\tthis.currentReturnContainer = (BlockContainer)currentFunction.Body;\n\t\t\tthis.currentIsIterator = currentFunction.IsIterator;\n\t\t\tthis.currentResultType = currentFunction.IsAsync\n\t\t\t\t? currentFunction.AsyncReturnType\n\t\t\t\t: currentFunction.ReturnType;\n\t\t\tthis.typeSystem = typeSystem;\n\t\t\tthis.settings = settings;\n\t\t\tthis.decompileRun = decompileRun;\n\t\t\tthis.cancellationToken = cancellationToken;\n\t\t}\n\n\t\tpublic Statement Convert(ILInstruction inst)\n\t\t{\n\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\treturn inst.AcceptVisitor(this);\n\t\t}\n\n\t\tpublic BlockStatement ConvertAsBlock(ILInstruction inst)\n\t\t{\n\t\t\tStatement stmt = Convert(inst).WithILInstruction(inst);\n\t\t\treturn stmt as BlockStatement ?? new BlockStatement { stmt };\n\t\t}\n\n\t\tprotected override TranslatedStatement Default(ILInstruction inst)\n\t\t{\n\t\t\treturn new ExpressionStatement(exprBuilder.Translate(inst))\n\t\t\t\t.WithILInstruction(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedStatement VisitIsInst(IsInst inst)\n\t\t{\n\t\t\t// isinst on top-level (unused result) can be translated in general\n\t\t\t// (even for value types) by using \"is\" instead of \"as\"\n\t\t\t// This can happen when the result of \"expr is T\" is unused\n\t\t\t// and the C# compiler optimizes away the null check portion of the \"is\" operator.\n\t\t\tvar arg = exprBuilder.Translate(inst.Argument);\n\t\t\targ = ExpressionBuilder.UnwrapBoxingConversion(arg);\n\t\t\treturn new ExpressionStatement(\n\t\t\t\tnew IsExpression(\n\t\t\t\t\targ,\n\t\t\t\t\texprBuilder.ConvertType(inst.Type)\n\t\t\t\t)\n\t\t\t\t.WithRR(new ResolveResult(exprBuilder.compilation.FindType(KnownTypeCode.Boolean)))\n\t\t\t\t.WithILInstruction(inst)\n\t\t\t)\n\t\t\t.WithILInstruction(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedStatement VisitStLoc(StLoc inst)\n\t\t{\n\t\t\tvar expr = exprBuilder.Translate(inst);\n\t\t\t// strip top-level ref on ref re-assignment\n\t\t\tif (expr.Expression is DirectionExpression dirExpr)\n\t\t\t{\n\t\t\t\texpr = expr.UnwrapChild(dirExpr.Expression);\n\t\t\t}\n\t\t\treturn new ExpressionStatement(expr).WithILInstruction(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedStatement VisitStObj(StObj inst)\n\t\t{\n\t\t\tvar expr = exprBuilder.Translate(inst);\n\t\t\t// strip top-level ref on ref re-assignment\n\t\t\tif (expr.Expression is DirectionExpression dirExpr)\n\t\t\t{\n\t\t\t\texpr = expr.UnwrapChild(dirExpr.Expression);\n\t\t\t}\n\t\t\treturn new ExpressionStatement(expr).WithILInstruction(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedStatement VisitNop(Nop inst)\n\t\t{\n\t\t\tvar stmt = new EmptyStatement();\n\t\t\tif (inst.Comment != null)\n\t\t\t{\n\t\t\t\tstmt.AddChild(new Comment(inst.Comment), Roles.Comment);\n\t\t\t}\n\t\t\treturn stmt.WithILInstruction(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedStatement VisitIfInstruction(IfInstruction inst)\n\t\t{\n\t\t\tvar condition = exprBuilder.TranslateCondition(inst.Condition);\n\t\t\tvar trueStatement = Convert(inst.TrueInst);\n\t\t\tvar falseStatement = inst.FalseInst.OpCode == OpCode.Nop ? null : Convert(inst.FalseInst);\n\t\t\treturn new IfElseStatement(condition, trueStatement, falseStatement).WithILInstruction(inst);\n\t\t}\n\n\t\tinternal IEnumerable<ConstantResolveResult> CreateTypedCaseLabel(long i, IType type, List<(string Key, int Value)> map = null)\n\t\t{\n\t\t\tobject value;\n\t\t\t// unpack nullable type, if necessary:\n\t\t\t// we need to do this in all cases, because there are nullable bools and enum types as well.\n\t\t\ttype = NullableType.GetUnderlyingType(type);\n\n\t\t\tif (type.IsKnownType(KnownTypeCode.Boolean))\n\t\t\t{\n\t\t\t\tvalue = i != 0;\n\t\t\t}\n\t\t\telse if (map != null)\n\t\t\t{\n\t\t\t\tDebug.Assert(type.IsKnownType(KnownTypeCode.String));\n\t\t\t\tvar keys = map.Where(entry => entry.Value == i).Select(entry => entry.Key);\n\t\t\t\tforeach (var key in keys)\n\t\t\t\t\tyield return new ConstantResolveResult(type, key);\n\t\t\t\tyield break;\n\t\t\t}\n\t\t\telse if (type.Kind == TypeKind.Enum)\n\t\t\t{\n\t\t\t\tvar enumType = type.GetDefinition().EnumUnderlyingType;\n\t\t\t\tTypeCode typeCode = ReflectionHelper.GetTypeCode(enumType);\n\t\t\t\tif (typeCode != TypeCode.Empty)\n\t\t\t\t{\n\t\t\t\t\tvalue = CSharpPrimitiveCast.Cast(typeCode, i, false);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvalue = i;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tTypeCode typeCode = ReflectionHelper.GetTypeCode(type);\n\t\t\t\tif (typeCode != TypeCode.Empty)\n\t\t\t\t{\n\t\t\t\t\tvalue = CSharpPrimitiveCast.Cast(typeCode, i, false);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvalue = i;\n\t\t\t\t}\n\t\t\t}\n\t\t\tyield return new ConstantResolveResult(type, value);\n\t\t}\n\n\t\tprotected internal override TranslatedStatement VisitSwitchInstruction(SwitchInstruction inst)\n\t\t{\n\t\t\treturn TranslateSwitch(null, inst).WithILInstruction(inst);\n\t\t}\n\n\t\tSwitchStatement TranslateSwitch(BlockContainer switchContainer, SwitchInstruction inst)\n\t\t{\n\t\t\tvar oldBreakTarget = breakTarget;\n\t\t\tbreakTarget = switchContainer; // 'break' within a switch would only leave the switch\n\t\t\tvar oldCaseLabelMapping = caseLabelMapping;\n\t\t\tcaseLabelMapping = new Dictionary<Block, ConstantResolveResult>();\n\n\t\t\tvar (value, type, strToInt) = exprBuilder.TranslateSwitchValue(inst, false);\n\n\t\t\tIL.SwitchSection defaultSection = inst.GetDefaultSection();\n\n\t\t\tvar stmt = new SwitchStatement() { Expression = value };\n\t\t\tDictionary<IL.SwitchSection, Syntax.SwitchSection> translationDictionary = new Dictionary<IL.SwitchSection, Syntax.SwitchSection>();\n\t\t\t// initialize C# switch sections.\n\t\t\tforeach (var section in inst.Sections)\n\t\t\t{\n\t\t\t\t// This is used in the block-label mapping.\n\t\t\t\tConstantResolveResult firstValueResolveResult;\n\t\t\t\tvar astSection = new Syntax.SwitchSection();\n\t\t\t\t// Create case labels:\n\t\t\t\tif (section == defaultSection)\n\t\t\t\t{\n\t\t\t\t\tastSection.CaseLabels.Add(new CaseLabel());\n\t\t\t\t\tfirstValueResolveResult = null;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar values = section.Labels.Values.SelectMany(i => CreateTypedCaseLabel(i, type, strToInt?.Map)).ToArray();\n\t\t\t\t\tif (section.HasNullLabel)\n\t\t\t\t\t{\n\t\t\t\t\t\tastSection.CaseLabels.Add(new CaseLabel(new NullReferenceExpression()));\n\t\t\t\t\t\tfirstValueResolveResult = new ConstantResolveResult(SpecialType.NullType, null);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(values.Length > 0);\n\t\t\t\t\t\tfirstValueResolveResult = values[0];\n\t\t\t\t\t}\n\t\t\t\t\tastSection.CaseLabels.AddRange(values.Select(label => new CaseLabel(exprBuilder.ConvertConstantValue(label, allowImplicitConversion: true))));\n\t\t\t\t}\n\t\t\t\tswitch (section.Body)\n\t\t\t\t{\n\t\t\t\t\tcase Branch br:\n\t\t\t\t\t\t// we can only inline the block, if all branches are in the switchContainer.\n\t\t\t\t\t\tif (br.TargetContainer == switchContainer && switchContainer.Descendants.OfType<Branch>().Where(b => b.TargetBlock == br.TargetBlock).All(b => BlockContainer.FindClosestSwitchContainer(b) == switchContainer))\n\t\t\t\t\t\t\tcaseLabelMapping.Add(br.TargetBlock, firstValueResolveResult);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\ttranslationDictionary.Add(section, astSection);\n\t\t\t\tstmt.SwitchSections.Add(astSection);\n\t\t\t}\n\t\t\tforeach (var section in inst.Sections)\n\t\t\t{\n\t\t\t\tvar astSection = translationDictionary[section];\n\t\t\t\tswitch (section.Body)\n\t\t\t\t{\n\t\t\t\t\tcase Branch br:\n\t\t\t\t\t\t// we can only inline the block, if all branches are in the switchContainer.\n\t\t\t\t\t\tif (br.TargetContainer == switchContainer && switchContainer.Descendants.OfType<Branch>().Where(b => b.TargetBlock == br.TargetBlock).All(b => BlockContainer.FindClosestSwitchContainer(b) == switchContainer))\n\t\t\t\t\t\t\tConvertSwitchSectionBody(astSection, br.TargetBlock);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tConvertSwitchSectionBody(astSection, section.Body);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase Leave leave:\n\t\t\t\t\t\tif (astSection.CaseLabels.Count == 1 && astSection.CaseLabels.First().Expression.IsNull && leave.TargetContainer == switchContainer)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstmt.SwitchSections.Remove(astSection);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tgoto default;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tConvertSwitchSectionBody(astSection, section.Body);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (switchContainer != null && stmt.SwitchSections.Count > 0)\n\t\t\t{\n\t\t\t\t// Translate any remaining blocks:\n\t\t\t\tvar lastSectionStatements = stmt.SwitchSections.Last().Statements;\n\t\t\t\tforeach (var block in switchContainer.Blocks.Skip(1))\n\t\t\t\t{\n\t\t\t\t\tif (caseLabelMapping.ContainsKey(block))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tlastSectionStatements.Add(new LabelStatement { Label = EnsureUniqueLabel(block) });\n\t\t\t\t\tforeach (var nestedInst in block.Instructions)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar nestedStmt = Convert(nestedInst);\n\t\t\t\t\t\tif (nestedStmt is BlockStatement b)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tforeach (var nested in b.Statements)\n\t\t\t\t\t\t\t\tlastSectionStatements.Add(nested.Detach());\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlastSectionStatements.Add(nestedStmt);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tDebug.Assert(block.FinalInstruction.OpCode == OpCode.Nop);\n\t\t\t\t}\n\t\t\t\tif (endContainerLabels.TryGetValue(switchContainer, out string label))\n\t\t\t\t{\n\t\t\t\t\tlastSectionStatements.Add(new LabelStatement { Label = label });\n\t\t\t\t\tlastSectionStatements.Add(new BreakStatement());\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbreakTarget = oldBreakTarget;\n\t\t\tcaseLabelMapping = oldCaseLabelMapping;\n\t\t\treturn stmt;\n\t\t}\n\n\t\tprivate void ConvertSwitchSectionBody(Syntax.SwitchSection astSection, ILInstruction bodyInst)\n\t\t{\n\t\t\tvar body = Convert(bodyInst);\n\t\t\tastSection.Statements.Add(body);\n\t\t\tif (!bodyInst.HasFlag(InstructionFlags.EndPointUnreachable))\n\t\t\t{\n\t\t\t\t// we need to insert 'break;'\n\t\t\t\tBlockStatement block = body as BlockStatement;\n\t\t\t\tif (block != null)\n\t\t\t\t{\n\t\t\t\t\tblock.Add(new BreakStatement());\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tastSection.Statements.Add(new BreakStatement());\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>Target block that a 'continue;' statement would jump to</summary>\n\t\tBlock continueTarget;\n\t\t/// <summary>Number of ContinueStatements that were created for the current continueTarget</summary>\n\t\tint continueCount;\n\t\t/// <summary>Maps blocks to cases.</summary>\n\t\tDictionary<Block, ConstantResolveResult> caseLabelMapping;\n\n\t\tprotected internal override TranslatedStatement VisitBranch(Branch inst)\n\t\t{\n\t\t\tif (inst.TargetBlock == continueTarget)\n\t\t\t{\n\t\t\t\tcontinueCount++;\n\t\t\t\treturn new ContinueStatement().WithILInstruction(inst);\n\t\t\t}\n\t\t\tif (caseLabelMapping != null && caseLabelMapping.TryGetValue(inst.TargetBlock, out var label))\n\t\t\t{\n\t\t\t\tif (label == null)\n\t\t\t\t\treturn new GotoDefaultStatement().WithILInstruction(inst);\n\t\t\t\treturn new GotoCaseStatement() { LabelExpression = exprBuilder.ConvertConstantValue(label, allowImplicitConversion: true) }\n\t\t\t\t\t.WithILInstruction(inst);\n\t\t\t}\n\t\t\treturn new GotoStatement(EnsureUniqueLabel(inst.TargetBlock)).WithILInstruction(inst);\n\t\t}\n\n\t\t/// <summary>Target container that a 'break;' statement would break out of</summary>\n\t\tBlockContainer breakTarget;\n\t\t/// <summary>Dictionary from BlockContainer to label name for 'goto of_container';</summary>\n\t\treadonly Dictionary<BlockContainer, string> endContainerLabels = new Dictionary<BlockContainer, string>();\n\n\t\tprotected internal override TranslatedStatement VisitLeave(Leave inst)\n\t\t{\n\t\t\tif (inst.TargetContainer == breakTarget)\n\t\t\t\treturn new BreakStatement().WithILInstruction(inst);\n\t\t\tif (inst.TargetContainer == currentReturnContainer)\n\t\t\t{\n\t\t\t\tif (currentIsIterator)\n\t\t\t\t\treturn new YieldBreakStatement().WithILInstruction(inst);\n\t\t\t\telse if (!inst.Value.MatchNop())\n\t\t\t\t{\n\t\t\t\t\tbool isLambdaOrExprTree = currentFunction.Kind is ILFunctionKind.ExpressionTree or ILFunctionKind.Delegate;\n\t\t\t\t\tvar expr = exprBuilder.Translate(inst.Value, typeHint: currentResultType)\n\t\t\t\t\t\t.ConvertTo(currentResultType, exprBuilder, allowImplicitConversion: true);\n\t\t\t\t\tif (isLambdaOrExprTree && IsPossibleLossOfTypeInformation(expr.Type, currentResultType))\n\t\t\t\t\t{\n\t\t\t\t\t\texpr = new CastExpression(exprBuilder.ConvertType(currentResultType), expr)\n\t\t\t\t\t\t\t.WithRR(new ConversionResolveResult(currentResultType, expr.ResolveResult, Conversion.IdentityConversion)).WithoutILInstruction();\n\t\t\t\t\t}\n\t\t\t\t\treturn new ReturnStatement(expr).WithILInstruction(inst);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\treturn new ReturnStatement().WithILInstruction(inst);\n\t\t\t}\n\t\t\tif (!endContainerLabels.TryGetValue(inst.TargetContainer, out string label))\n\t\t\t{\n\t\t\t\tlabel = \"end_\" + inst.TargetLabel;\n\t\t\t\tif (!duplicateLabels.TryGetValue(label, out int count))\n\t\t\t\t{\n\t\t\t\t\tduplicateLabels.Add(label, 1);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tduplicateLabels[label]++;\n\t\t\t\t\tlabel += \"_\" + (count + 1);\n\t\t\t\t}\n\t\t\t\tendContainerLabels.Add(inst.TargetContainer, label);\n\t\t\t}\n\t\t\treturn new GotoStatement(label).WithILInstruction(inst);\n\t\t}\n\n\t\tprivate bool IsPossibleLossOfTypeInformation(IType givenType, IType expectedType)\n\t\t{\n\t\t\tif (NormalizeTypeVisitor.IgnoreNullability.EquivalentTypes(givenType, expectedType))\n\t\t\t\treturn false;\n\t\t\tif (expectedType is TupleType { ElementNames.IsEmpty: false })\n\t\t\t\treturn true;\n\t\t\tif (expectedType == SpecialType.Dynamic)\n\t\t\t\treturn true;\n\t\t\tif (givenType == SpecialType.NullType)\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\n\t\tprotected internal override TranslatedStatement VisitThrow(Throw inst)\n\t\t{\n\t\t\treturn new ThrowStatement(exprBuilder.Translate(inst.Argument)).WithILInstruction(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedStatement VisitRethrow(Rethrow inst)\n\t\t{\n\t\t\treturn new ThrowStatement().WithILInstruction(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedStatement VisitYieldReturn(YieldReturn inst)\n\t\t{\n\t\t\tvar elementType = currentFunction.ReturnType.GetElementTypeFromIEnumerable(typeSystem, true, out var isGeneric);\n\t\t\tvar expr = exprBuilder.Translate(inst.Value, typeHint: elementType)\n\t\t\t\t.ConvertTo(elementType, exprBuilder, allowImplicitConversion: true);\n\t\t\treturn new YieldReturnStatement {\n\t\t\t\tExpression = expr\n\t\t\t}.WithILInstruction(inst);\n\t\t}\n\n\t\tTryCatchStatement MakeTryCatch(ILInstruction tryBlock)\n\t\t{\n\t\t\tvar tryBlockConverted = Convert(tryBlock);\n\t\t\tvar tryCatch = tryBlockConverted as TryCatchStatement;\n\t\t\tif (tryCatch != null && tryCatch.FinallyBlock.IsNull)\n\t\t\t\treturn tryCatch; // extend existing try-catch\n\t\t\ttryCatch = new TryCatchStatement();\n\t\t\ttryCatch.TryBlock = tryBlockConverted as BlockStatement ?? new BlockStatement { tryBlockConverted };\n\t\t\treturn tryCatch;\n\t\t}\n\n\t\tprotected internal override TranslatedStatement VisitTryCatch(TryCatch inst)\n\t\t{\n\t\t\tvar tryCatch = new TryCatchStatement();\n\t\t\ttryCatch.TryBlock = ConvertAsBlock(inst.TryBlock);\n\t\t\tforeach (var handler in inst.Handlers)\n\t\t\t{\n\t\t\t\tvar catchClause = new CatchClause();\n\t\t\t\tcatchClause.AddAnnotation(handler);\n\t\t\t\tvar v = handler.Variable;\n\t\t\t\tif (v != null)\n\t\t\t\t{\n\t\t\t\t\tcatchClause.AddAnnotation(new ILVariableResolveResult(v, v.Type));\n\t\t\t\t\tif (v.StoreCount > 1 || v.LoadCount > 0 || v.AddressCount > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tcatchClause.VariableName = v.Name;\n\t\t\t\t\t\tcatchClause.Type = exprBuilder.ConvertType(v.Type);\n\t\t\t\t\t}\n\t\t\t\t\telse if (!v.Type.IsKnownType(KnownTypeCode.Object))\n\t\t\t\t\t{\n\t\t\t\t\t\tcatchClause.Type = exprBuilder.ConvertType(v.Type);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!handler.Filter.MatchLdcI4(1))\n\t\t\t\t\tcatchClause.Condition = exprBuilder.TranslateCondition(handler.Filter);\n\t\t\t\tcatchClause.Body = ConvertAsBlock(handler.Body);\n\t\t\t\ttryCatch.CatchClauses.Add(catchClause);\n\t\t\t}\n\t\t\treturn tryCatch.WithILInstruction(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedStatement VisitTryFinally(TryFinally inst)\n\t\t{\n\t\t\tvar tryCatch = MakeTryCatch(inst.TryBlock);\n\t\t\ttryCatch.FinallyBlock = ConvertAsBlock(inst.FinallyBlock);\n\t\t\treturn tryCatch.WithILInstruction(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedStatement VisitTryFault(TryFault inst)\n\t\t{\n\t\t\tvar tryCatch = new TryCatchStatement();\n\t\t\ttryCatch.TryBlock = ConvertAsBlock(inst.TryBlock);\n\t\t\tvar faultBlock = ConvertAsBlock(inst.FaultBlock);\n\t\t\tfaultBlock.InsertChildAfter(null, new Comment(\"try-fault\"), Roles.Comment);\n\t\t\tfaultBlock.Add(new ThrowStatement());\n\t\t\ttryCatch.CatchClauses.Add(new CatchClause { Body = faultBlock });\n\t\t\treturn tryCatch.WithILInstruction(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedStatement VisitLockInstruction(LockInstruction inst)\n\t\t{\n\t\t\treturn new LockStatement {\n\t\t\t\tExpression = exprBuilder.Translate(inst.OnExpression),\n\t\t\t\tEmbeddedStatement = ConvertAsBlock(inst.Body)\n\t\t\t}.WithILInstruction(inst);\n\t\t}\n\n\t\t#region foreach construction\n\t\tstatic readonly InvocationExpression getEnumeratorPattern = new InvocationExpression(\n\t\t\tnew Choice {\n\t\t\t\tnew MemberReferenceExpression(new AnyNode(\"collection\").ToExpression(), \"GetEnumerator\"),\n\t\t\t\tnew MemberReferenceExpression(new AnyNode(\"collection\").ToExpression(), \"GetAsyncEnumerator\")\n\t\t\t}\n\t\t);\n\t\tstatic readonly InvocationExpression extensionGetEnumeratorPattern = new InvocationExpression(\n\t\t\tnew Choice {\n\t\t\t\tnew MemberReferenceExpression(new AnyNode(\"type\").ToExpression(), \"GetEnumerator\"),\n\t\t\t\tnew MemberReferenceExpression(new AnyNode(\"type\").ToExpression(), \"GetAsyncEnumerator\")\n\t\t\t},\n\t\t\tnew AnyNode(\"collection\")\n\t\t);\n\t\tstatic readonly Expression moveNextConditionPattern = new Choice {\n\t\t\tnew InvocationExpression(new MemberReferenceExpression(new NamedNode(\"enumerator\", new IdentifierExpression(Pattern.AnyString)), \"MoveNext\")),\n\t\t\tnew UnaryOperatorExpression(UnaryOperatorType.Await, new InvocationExpression(new MemberReferenceExpression(new NamedNode(\"enumerator\", new IdentifierExpression(Pattern.AnyString)), \"MoveNextAsync\")))\n\t\t};\n\n\t\tprotected internal override TranslatedStatement VisitUsingInstruction(UsingInstruction inst)\n\t\t{\n\t\t\tvar resource = exprBuilder.Translate(inst.ResourceExpression).Expression;\n\t\t\tvar transformed = TransformToForeach(inst, resource);\n\t\t\tif (transformed != null)\n\t\t\t\treturn transformed.WithILInstruction(inst);\n\t\t\tAstNode usingInit = resource;\n\t\t\tvar var = inst.Variable;\n\t\t\tKnownTypeCode knownTypeCode;\n\t\t\tIType disposeType;\n\t\t\tstring disposeTypeMethodName;\n\t\t\tif (inst.IsAsync)\n\t\t\t{\n\t\t\t\tknownTypeCode = KnownTypeCode.IAsyncDisposable;\n\t\t\t\tdisposeType = exprBuilder.compilation.FindType(KnownTypeCode.IAsyncDisposable);\n\t\t\t\tdisposeTypeMethodName = \"DisposeAsync\";\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tknownTypeCode = KnownTypeCode.IDisposable;\n\t\t\t\tdisposeType = exprBuilder.compilation.FindType(KnownTypeCode.IDisposable);\n\t\t\t\tdisposeTypeMethodName = \"Dispose\";\n\t\t\t}\n\t\t\tif (!IsValidInCSharp(inst, knownTypeCode))\n\t\t\t{\n\t\t\t\tDebug.Assert(var.Kind == VariableKind.UsingLocal);\n\t\t\t\tvar.Kind = VariableKind.Local;\n\t\t\t\tvar disposeVariable = currentFunction.RegisterVariable(\n\t\t\t\t\tVariableKind.Local, disposeType,\n\t\t\t\t\tAssignVariableNames.GenerateVariableName(currentFunction, disposeType, decompileRun.UsingScope)\n\t\t\t\t);\n\t\t\t\tExpression disposeInvocation = new InvocationExpression(new MemberReferenceExpression(exprBuilder.ConvertVariable(disposeVariable).Expression, disposeTypeMethodName));\n\t\t\t\tif (inst.IsAsync)\n\t\t\t\t{\n\t\t\t\t\tdisposeInvocation = new UnaryOperatorExpression { Expression = disposeInvocation, Operator = UnaryOperatorType.Await };\n\t\t\t\t}\n\t\t\t\treturn new BlockStatement {\n\t\t\t\t\tnew ExpressionStatement(new AssignmentExpression(exprBuilder.ConvertVariable(var).Expression, resource.Detach())),\n\t\t\t\t\tnew TryCatchStatement {\n\t\t\t\t\t\tTryBlock = ConvertAsBlock(inst.Body),\n\t\t\t\t\t\tFinallyBlock = new BlockStatement() {\n\t\t\t\t\t\t\tnew ExpressionStatement(new AssignmentExpression(exprBuilder.ConvertVariable(disposeVariable).Expression, new AsExpression(exprBuilder.ConvertVariable(var).Expression, exprBuilder.ConvertType(disposeType)))),\n\t\t\t\t\t\t\tnew IfElseStatement {\n\t\t\t\t\t\t\t\tCondition = new BinaryOperatorExpression(exprBuilder.ConvertVariable(disposeVariable), BinaryOperatorType.InEquality, new NullReferenceExpression()),\n\t\t\t\t\t\t\t\tTrueStatement = new ExpressionStatement(disposeInvocation)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t}.WithILInstruction(inst);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (var.LoadCount > 0 || var.AddressCount > 0)\n\t\t\t\t{\n\t\t\t\t\tvar type = settings.AnonymousTypes && var.Type.ContainsAnonymousType() ? new SimpleType(\"var\") : exprBuilder.ConvertType(var.Type);\n\t\t\t\t\tvar vds = new VariableDeclarationStatement(type, var.Name, resource);\n\t\t\t\t\tvds.Variables.Single().AddAnnotation(new ILVariableResolveResult(var, var.Type));\n\t\t\t\t\tusingInit = vds;\n\t\t\t\t}\n\t\t\t\treturn new UsingStatement {\n\t\t\t\t\tResourceAcquisition = usingInit,\n\t\t\t\t\tIsAsync = inst.IsAsync,\n\t\t\t\t\tEmbeddedStatement = ConvertAsBlock(inst.Body)\n\t\t\t\t}.WithILInstruction(inst);\n\t\t\t}\n\n\t\t\tbool IsValidInCSharp(UsingInstruction inst, KnownTypeCode code)\n\t\t\t{\n\t\t\t\tif (inst.ResourceExpression.MatchLdNull())\n\t\t\t\t\treturn true;\n\t\t\t\tif (inst.IsRefStruct)\n\t\t\t\t\treturn true;\n\t\t\t\treturn NullableType.GetUnderlyingType(var.Type).GetAllBaseTypes().Any(b => b.IsKnownType(code));\n\t\t\t}\n\t\t}\n\n\t\tStatement TransformToForeach(UsingInstruction inst, Expression resource)\n\t\t{\n\t\t\tif (!settings.ForEachStatement)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tMatch m;\n\t\t\tif (settings.ExtensionMethods && settings.ForEachWithGetEnumeratorExtension)\n\t\t\t{\n\t\t\t\t// Check if the using resource matches the GetEnumerator pattern ...\n\t\t\t\tm = getEnumeratorPattern.Match(resource);\n\t\t\t\tif (!m.Success)\n\t\t\t\t{\n\t\t\t\t\t// ... or the extension GetEnumeratorPattern.\n\t\t\t\t\tm = extensionGetEnumeratorPattern.Match(resource);\n\t\t\t\t\tif (!m.Success)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t// Validate that the invocation is an extension method invocation.\n\t\t\t\t\tif (!(resource.GetSymbol() is IMethod method\n\t\t\t\t\t\t&& exprBuilder.resolver.CanTransformToExtensionMethodCall(method, true)))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Check if the using resource matches the GetEnumerator pattern.\n\t\t\t\tm = getEnumeratorPattern.Match(resource);\n\t\t\t\tif (!m.Success)\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t\t// The using body must be a BlockContainer.\n\t\t\tif (!(inst.Body is BlockContainer container))\n\t\t\t\treturn null;\n\t\t\tbool isAsync = ((MemberReferenceExpression)((InvocationExpression)resource).Target).MemberName == \"GetAsyncEnumerator\";\n\t\t\tif (isAsync != inst.IsAsync)\n\t\t\t\treturn null;\n\t\t\t// The using-variable is the enumerator.\n\t\t\tvar enumeratorVar = inst.Variable;\n\t\t\t// If there's another BlockContainer nested in this container and it only has one child block, unwrap it.\n\t\t\t// If there's an extra leave inside the block, extract it into optionalReturnAfterLoop.\n\t\t\tvar loopContainer = UnwrapNestedContainerIfPossible(container, out var optionalLeaveAfterLoop);\n\t\t\t// Detect whether we're dealing with a while loop with multiple embedded statements.\n\t\t\tif (loopContainer.Kind != ContainerKind.While)\n\t\t\t\treturn null;\n\t\t\tif (!loopContainer.MatchConditionBlock(loopContainer.EntryPoint, out var conditionInst, out var body))\n\t\t\t\treturn null;\n\t\t\t// The loop condition must be a call to enumerator.MoveNext()\n\t\t\tvar condition = exprBuilder.TranslateCondition(conditionInst);\n\t\t\tvar m2 = moveNextConditionPattern.Match(condition.Expression);\n\t\t\tif (!m2.Success)\n\t\t\t\treturn null;\n\t\t\tif (condition.Expression is UnaryOperatorExpression { Operator: UnaryOperatorType.Await } != isAsync)\n\t\t\t\treturn null;\n\t\t\t// Check enumerator variable references.\n\t\t\tvar enumeratorVar2 = m2.Get<IdentifierExpression>(\"enumerator\").Single().GetILVariable();\n\t\t\tif (enumeratorVar2 != enumeratorVar)\n\t\t\t\treturn null;\n\t\t\t// Detect which foreach-variable transformation is necessary/possible.\n\t\t\tvar transformation = DetectGetCurrentTransformation(container, body, loopContainer, enumeratorVar, conditionInst, out var singleGetter, out var foreachVariable);\n\t\t\tif (transformation == RequiredGetCurrentTransformation.NoForeach)\n\t\t\t\treturn null;\n\t\t\t// Extract in-expression\n\t\t\tvar collectionExpr = m.Get<Expression>(\"collection\").Single();\n\t\t\t// Special case: foreach (var item in this) is decompiled as foreach (var item in base)\n\t\t\t// but a base reference is not valid in this context.\n\t\t\tif (collectionExpr is BaseReferenceExpression)\n\t\t\t{\n\t\t\t\tcollectionExpr = new ThisReferenceExpression().CopyAnnotationsFrom(collectionExpr);\n\t\t\t}\n\t\t\telse if (IsDynamicCastToIEnumerable(collectionExpr, out var dynamicExpr))\n\t\t\t{\n\t\t\t\tcollectionExpr = dynamicExpr.Detach();\n\t\t\t}\n\t\t\t// Handle explicit casts:\n\t\t\t// This is the case if an explicit type different from the collection-item-type was used.\n\t\t\t// For example: foreach (ClassA item in nonGenericEnumerable)\n\t\t\tvar type = singleGetter.Method.ReturnType;\n\t\t\tILInstruction instToReplace = singleGetter;\n\t\t\tbool useVar = false;\n\t\t\tswitch (instToReplace.Parent)\n\t\t\t{\n\t\t\t\tcase CastClass cc:\n\t\t\t\t\ttype = cc.Type;\n\t\t\t\t\tinstToReplace = cc;\n\t\t\t\t\tbreak;\n\t\t\t\tcase UnboxAny ua:\n\t\t\t\t\ttype = ua.Type;\n\t\t\t\t\tinstToReplace = ua;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tif (TupleType.IsTupleCompatible(type, out _))\n\t\t\t\t\t{\n\t\t\t\t\t\t// foreach with get_Current returning a tuple type, let's check which type \"var\" would infer:\n\t\t\t\t\t\tvar foreachRR = exprBuilder.resolver.ResolveForeach(collectionExpr.GetResolveResult());\n\t\t\t\t\t\tif (EqualErasedType(type, foreachRR.ElementType))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype = foreachRR.ElementType;\n\t\t\t\t\t\t\tuseVar = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tVariableDesignation designation = null;\n\n\t\t\t// Handle the required foreach-variable transformation:\n\t\t\tswitch (transformation)\n\t\t\t{\n\t\t\t\tcase RequiredGetCurrentTransformation.UseExistingVariable:\n\t\t\t\t\tif (foreachVariable.Type.Kind != TypeKind.Dynamic)\n\t\t\t\t\t\tforeachVariable.Type = type;\n\t\t\t\t\tforeachVariable.Kind = VariableKind.ForeachLocal;\n\t\t\t\t\tforeachVariable.Name = AssignVariableNames.GenerateForeachVariableName(currentFunction, collectionExpr.Annotation<ILInstruction>(), decompileRun.UsingScope, foreachVariable);\n\t\t\t\t\tbreak;\n\t\t\t\tcase RequiredGetCurrentTransformation.IntroduceNewVariable:\n\t\t\t\t\tforeachVariable = currentFunction.RegisterVariable(\n\t\t\t\t\t\tVariableKind.ForeachLocal, type,\n\t\t\t\t\t\tAssignVariableNames.GenerateForeachVariableName(currentFunction, collectionExpr.Annotation<ILInstruction>(), decompileRun.UsingScope)\n\t\t\t\t\t);\n\t\t\t\t\tinstToReplace.ReplaceWith(new LdLoc(foreachVariable));\n\t\t\t\t\tbody.Instructions.Insert(0, new StLoc(foreachVariable, instToReplace));\n\t\t\t\t\tbreak;\n\t\t\t\tcase RequiredGetCurrentTransformation.IntroduceNewVariableAndLocalCopy:\n\t\t\t\t\tforeachVariable = currentFunction.RegisterVariable(\n\t\t\t\t\t\tVariableKind.ForeachLocal, type,\n\t\t\t\t\t\tAssignVariableNames.GenerateForeachVariableName(currentFunction, collectionExpr.Annotation<ILInstruction>(), decompileRun.UsingScope)\n\t\t\t\t\t);\n\t\t\t\t\tvar localCopyVariable = currentFunction.RegisterVariable(\n\t\t\t\t\t\tVariableKind.Local, type,\n\t\t\t\t\t\tAssignVariableNames.GenerateVariableName(currentFunction, type, decompileRun.UsingScope)\n\t\t\t\t\t);\n\t\t\t\t\tinstToReplace.Parent.ReplaceWith(new LdLoca(localCopyVariable));\n\t\t\t\t\tbody.Instructions.Insert(0, new StLoc(localCopyVariable, new LdLoc(foreachVariable)));\n\t\t\t\t\tbody.Instructions.Insert(0, new StLoc(foreachVariable, instToReplace));\n\t\t\t\t\tbreak;\n\t\t\t\tcase RequiredGetCurrentTransformation.Deconstruction:\n\t\t\t\t\tuseVar = true;\n\t\t\t\t\tdesignation = TranslateDeconstructionDesignation((DeconstructInstruction)body.Instructions[0], isForeach: true);\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (designation == null)\n\t\t\t{\n\t\t\t\tdesignation = new SingleVariableDesignation { Identifier = foreachVariable.Name };\n\t\t\t\t// Add the variable annotation for highlighting\n\t\t\t\tdesignation.AddAnnotation(new ILVariableResolveResult(foreachVariable, foreachVariable.Type));\n\t\t\t}\n\n\t\t\t// Convert the modified body to C# AST:\n\t\t\tvar whileLoopBlock = ConvertAsBlock(container);\n\t\t\tvar whileLoop = (WhileStatement)whileLoopBlock.First();\n\t\t\tvar foreachBody = (BlockStatement)whileLoop.EmbeddedStatement.Detach();\n\n\t\t\t// Remove the first statement, as it is the foreachVariable = enumerator.Current; statement.\n\t\t\tStatement firstStatement = foreachBody.Statements.First();\n\t\t\tif (firstStatement is LabelStatement)\n\t\t\t{\n\t\t\t\t// skip the entry-point label, if any\n\t\t\t\tfirstStatement = firstStatement.GetNextStatement();\n\t\t\t}\n\t\t\tDebug.Assert(firstStatement is ExpressionStatement);\n\t\t\tfirstStatement.Remove();\n\n\t\t\tif (settings.AnonymousTypes && type.ContainsAnonymousType())\n\t\t\t\tuseVar = true;\n\n\t\t\t// Construct the foreach loop.\n\t\t\tvar foreachStmt = new ForeachStatement {\n\t\t\t\tIsAsync = isAsync,\n\t\t\t\tVariableType = useVar ? new SimpleType(\"var\") : exprBuilder.ConvertType(foreachVariable.Type),\n\t\t\t\tVariableDesignation = designation,\n\t\t\t\tInExpression = collectionExpr.Detach(),\n\t\t\t\tEmbeddedStatement = foreachBody\n\t\t\t};\n\t\t\tforeachStmt.AddAnnotation(new ForeachAnnotation(inst.ResourceExpression, conditionInst, singleGetter));\n\t\t\tforeachStmt.CopyAnnotationsFrom(whileLoop);\n\t\t\t// If there was an optional return statement, return it as well.\n\t\t\t// If there were labels or any other statements in the whileLoopBlock, move them after the foreach\n\t\t\t// loop.\n\t\t\tif (optionalLeaveAfterLoop != null || whileLoopBlock.Statements.Count > 1)\n\t\t\t{\n\t\t\t\tvar block = new BlockStatement {\n\t\t\t\t\tStatements = {\n\t\t\t\t\t\tforeachStmt\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tif (optionalLeaveAfterLoop != null)\n\t\t\t\t{\n\t\t\t\t\tblock.Statements.Add(optionalLeaveAfterLoop.AcceptVisitor(this));\n\t\t\t\t}\n\t\t\t\tif (whileLoopBlock.Statements.Count > 1)\n\t\t\t\t{\n\t\t\t\t\tblock.Statements.AddRange(whileLoopBlock.Statements\n\t\t\t\t\t\t.Skip(1)\n\t\t\t\t\t\t.SkipWhile(s => s.Annotations.Any(a => a == optionalLeaveAfterLoop))\n\t\t\t\t\t\t.Select(SyntaxExtensions.Detach));\n\t\t\t\t}\n\t\t\t\treturn block;\n\t\t\t}\n\t\t\treturn foreachStmt;\n\t\t}\n\n\t\tinternal static VariableDesignation TranslateDeconstructionDesignation(DeconstructInstruction inst, bool isForeach)\n\t\t{\n\t\t\tvar assignments = inst.Assignments.Instructions;\n\t\t\tint assignmentPos = 0;\n\n\t\t\treturn ConstructDesignation(inst.Pattern);\n\n\t\t\tVariableDesignation ConstructDesignation(MatchInstruction matchInstruction)\n\t\t\t{\n\t\t\t\tvar designations = new ParenthesizedVariableDesignation();\n\t\t\t\tforeach (var subPattern in matchInstruction.SubPatterns.Cast<MatchInstruction>())\n\t\t\t\t{\n\t\t\t\t\tif (subPattern.IsVar)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar designation = new SingleVariableDesignation();\n\t\t\t\t\t\tif (subPattern.HasDesignator)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tILVariable v = ((StLoc)assignments[assignmentPos]).Variable;\n\t\t\t\t\t\t\tif (isForeach)\n\t\t\t\t\t\t\t\tv.Kind = VariableKind.ForeachLocal;\n\t\t\t\t\t\t\tdesignation.Identifier = v.Name;\n\t\t\t\t\t\t\tdesignation.AddAnnotation(new ILVariableResolveResult(v));\n\t\t\t\t\t\t\tassignmentPos++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdesignation.Identifier = \"_\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdesignations.VariableDesignations.Add(designation);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tdesignations.VariableDesignations.Add(ConstructDesignation(subPattern));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdesignations.AddAnnotation(matchInstruction);\n\t\t\t\treturn designations;\n\t\t\t}\n\t\t}\n\n\t\tstatic bool EqualErasedType(IType a, IType b)\n\t\t{\n\t\t\treturn NormalizeTypeVisitor.TypeErasure.EquivalentTypes(a, b);\n\t\t}\n\n\t\tprivate bool IsDynamicCastToIEnumerable(Expression expr, out Expression dynamicExpr)\n\t\t{\n\t\t\tif (!(expr is CastExpression cast))\n\t\t\t{\n\t\t\t\tdynamicExpr = null;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tdynamicExpr = cast.Expression;\n\t\t\tif (!(expr.GetResolveResult() is ConversionResolveResult crr))\n\t\t\t\treturn false;\n\t\t\tif (!crr.Type.IsKnownType(KnownTypeCode.IEnumerable))\n\t\t\t\treturn false;\n\t\t\treturn crr.Input.Type.Kind == TypeKind.Dynamic;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Unwraps a nested BlockContainer, if container contains only a single block,\n\t\t/// and that single block contains only a BlockContainer followed by a Leave instruction.\n\t\t/// If the leave instruction is a return that carries a value, the container is unwrapped only\n\t\t/// if the value has no side-effects.\n\t\t/// Otherwise returns the unmodified container.\n\t\t/// </summary>\n\t\t/// <param name=\"optionalLeaveInst\">If the leave is a return/break and has no side-effects, we can move the return out of the using-block and put it after the loop, otherwise returns null.</param>\n\t\tBlockContainer UnwrapNestedContainerIfPossible(BlockContainer container, out Leave optionalLeaveInst)\n\t\t{\n\t\t\toptionalLeaveInst = null;\n\t\t\t// Check block structure:\n\t\t\tif (container.Blocks.Count != 1)\n\t\t\t\treturn container;\n\t\t\tvar nestedBlock = container.Blocks[0];\n\t\t\tif (nestedBlock.Instructions.Count != 2 ||\n\t\t\t\t!(nestedBlock.Instructions[0] is BlockContainer nestedContainer) ||\n\t\t\t\t!(nestedBlock.Instructions[1] is Leave leave))\n\t\t\t\treturn container;\n\t\t\t// If the leave has no value, just unwrap the BlockContainer.\n\t\t\tif (leave.MatchLeave(container))\n\t\t\t\treturn nestedContainer;\n\t\t\t// If the leave is a return/break, we can move it out of the using-block and put it after the loop\n\t\t\t// (but only if the value doesn't have side-effects)\n\t\t\tif (SemanticHelper.IsPure(leave.Value.Flags))\n\t\t\t{\n\t\t\t\toptionalLeaveInst = leave;\n\t\t\t\treturn nestedContainer;\n\t\t\t}\n\t\t\treturn container;\n\t\t}\n\n\t\tenum RequiredGetCurrentTransformation\n\t\t{\n\t\t\t/// <summary>\n\t\t\t/// Foreach transformation not possible.\n\t\t\t/// </summary>\n\t\t\tNoForeach,\n\t\t\t/// <summary>\n\t\t\t/// Uninline the stloc foreachVar(call get_Current()) and insert it as first statement in the loop body.\n\t\t\t/// <code>\n\t\t\t///\t... (stloc foreachVar(call get_Current()) ...\n\t\t\t///\t=>\n\t\t\t///\tstloc foreachVar(call get_Current())\n\t\t\t///\t... (ldloc foreachVar) ...\n\t\t\t/// </code>\n\t\t\t/// </summary>\n\t\t\tUseExistingVariable,\n\t\t\t/// <summary>\n\t\t\t/// No store was found, thus create a new variable and use it as foreach variable.\n\t\t\t/// <code>\n\t\t\t///\t... (call get_Current()) ...\n\t\t\t///\t=>\n\t\t\t///\tstloc foreachVar(call get_Current())\n\t\t\t///\t... (ldloc foreachVar) ...\n\t\t\t/// </code>\n\t\t\t/// </summary>\n\t\t\tIntroduceNewVariable,\n\t\t\t/// <summary>\n\t\t\t/// No store was found, thus create a new variable and use it as foreach variable.\n\t\t\t/// Additionally it is necessary to copy the value of the foreach variable to another local\n\t\t\t/// to allow safe modification of its value.\n\t\t\t/// <code>\n\t\t\t///\t... addressof(call get_Current()) ...\n\t\t\t///\t=>\n\t\t\t///\tstloc foreachVar(call get_Current())\n\t\t\t///\tstloc copy(ldloc foreachVar)\n\t\t\t///\t... (ldloca copy) ...\n\t\t\t/// </code>\n\t\t\t/// </summary>\n\t\t\tIntroduceNewVariableAndLocalCopy,\n\t\t\t/// <summary>\n\t\t\t/// call get_Current() is the tested operand of a deconstruct instruction.\n\t\t\t/// and the deconstruct instruction is the first statement in the loop body.\n\t\t\t/// </summary>\n\t\t\tDeconstruction,\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Determines whether <paramref name=\"enumerator\"/> is only used once inside <paramref name=\"loopBody\"/> for accessing the Current property.\n\t\t/// </summary>\n\t\t/// <param name=\"usingContainer\">The using body container. This is only used for variable usage checks.</param>\n\t\t/// <param name=\"loopBody\">The loop body. The first statement of this block is analyzed.</param>\n\t\t/// <param name=\"enumerator\">The current enumerator.</param>\n\t\t/// <param name=\"moveNextUsage\">The call MoveNext(ldloc enumerator) pattern.</param>\n\t\t/// <param name=\"singleGetter\">Returns the call instruction invoking Current's getter.</param>\n\t\t/// <param name=\"foreachVariable\">Returns the the foreach variable, if a suitable was found. This variable is only assigned once and its assignment is the first statement in <paramref name=\"loopBody\"/>.</param>\n\t\t/// <returns><see cref=\"RequiredGetCurrentTransformation\"/> for details.</returns>\n\t\tRequiredGetCurrentTransformation DetectGetCurrentTransformation(BlockContainer usingContainer, Block loopBody, BlockContainer loopContainer, ILVariable enumerator, ILInstruction moveNextUsage, out CallInstruction singleGetter, out ILVariable foreachVariable)\n\t\t{\n\t\t\tsingleGetter = null;\n\t\t\tforeachVariable = null;\n\t\t\tvar loads = enumerator.LoadInstructions.OfType<ILInstruction>()\n\t\t\t\t.Concat(enumerator.AddressInstructions.OfType<ILInstruction>())\n\t\t\t\t.Where(ld => !ld.IsDescendantOf(moveNextUsage))\n\t\t\t\t.ToArray();\n\t\t\t// enumerator is used in multiple locations or not in conjunction with get_Current\n\t\t\t// => no foreach\n\t\t\tif (loads.Length != 1 || !ParentIsCurrentGetter(loads[0]))\n\t\t\t\treturn RequiredGetCurrentTransformation.NoForeach;\n\t\t\tsingleGetter = (CallInstruction)loads[0].Parent;\n\t\t\t// singleGetter is not part of the first instruction in body or cannot be uninlined\n\t\t\t// => no foreach\n\t\t\tif (!(singleGetter.IsDescendantOf(loopBody.Instructions[0])\n\t\t\t\t&& ILInlining.CanUninline(singleGetter, loopBody.Instructions[0])))\n\t\t\t{\n\t\t\t\treturn RequiredGetCurrentTransformation.NoForeach;\n\t\t\t}\n\t\t\tif (loopBody.Instructions[0] is DeconstructInstruction deconstruction\n\t\t\t\t&& CanBeDeconstructedInForeach(deconstruction, singleGetter, usingContainer, loopContainer))\n\t\t\t{\n\t\t\t\treturn RequiredGetCurrentTransformation.Deconstruction;\n\t\t\t}\n\t\t\tILInstruction inst = singleGetter;\n\t\t\t// in some cases, i.e. foreach variable with explicit type different from the collection-item-type,\n\t\t\t// the result of call get_Current is casted.\n\t\t\twhile (inst.Parent is UnboxAny || inst.Parent is CastClass)\n\t\t\t\tinst = inst.Parent;\n\t\t\t// One variable was found.\n\t\t\tif (inst.Parent is StLoc stloc && (stloc.Variable.Kind == VariableKind.Local || stloc.Variable.Kind == VariableKind.StackSlot))\n\t\t\t{\n\t\t\t\t// Must be a plain assignment expression and variable must only be used in 'body' + only assigned once.\n\t\t\t\tif (stloc.Parent == loopBody && VariableIsOnlyUsedInBlock(stloc, usingContainer, loopContainer))\n\t\t\t\t{\n\t\t\t\t\tforeachVariable = stloc.Variable;\n\t\t\t\t\treturn RequiredGetCurrentTransformation.UseExistingVariable;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// In optimized Roslyn code it can happen that the foreach variable is referenced via addressof\n\t\t\t// We only do this unwrapping if where dealing with a custom struct type.\n\t\t\tif (CurrentIsStructSetterTarget(inst, singleGetter))\n\t\t\t{\n\t\t\t\treturn RequiredGetCurrentTransformation.IntroduceNewVariableAndLocalCopy;\n\t\t\t}\n\t\t\t// No suitable variable was found: we need a new one.\n\t\t\treturn RequiredGetCurrentTransformation.IntroduceNewVariable;\n\t\t}\n\n\t\tbool CanBeDeconstructedInForeach(DeconstructInstruction deconstruction, ILInstruction singleGetter, BlockContainer usingContainer, BlockContainer loopContainer)\n\t\t{\n\t\t\tILInstruction testedOperand = deconstruction.Pattern.TestedOperand;\n\t\t\tif (testedOperand != singleGetter)\n\t\t\t{\n\t\t\t\tif (!(testedOperand is AddressOf addressOf && addressOf.Value == singleGetter))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (deconstruction.Init.Count > 0)\n\t\t\t\treturn false;\n\t\t\tif (deconstruction.Conversions.Instructions.Count > 0)\n\t\t\t\treturn false;\n\t\t\tvar operandType = singleGetter.InferType(this.typeSystem);\n\t\t\tvar expectedType = deconstruction.Pattern.Variable.Type;\n\t\t\tif (!NormalizeTypeVisitor.TypeErasure.EquivalentTypes(operandType, expectedType))\n\t\t\t\treturn false;\n\t\t\tvar usedVariables = new HashSet<ILVariable>(ILVariableEqualityComparer.Instance);\n\t\t\tforeach (var item in deconstruction.Assignments.Instructions)\n\t\t\t{\n\t\t\t\tif (!item.MatchStLoc(out var v, out var value))\n\t\t\t\t\treturn false;\n\t\t\t\texpectedType = ((LdLoc)value).Variable.Type;\n\t\t\t\tif (!NormalizeTypeVisitor.TypeErasure.EquivalentTypes(v.Type, expectedType))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(v.Kind == VariableKind.StackSlot || v.Kind == VariableKind.Local))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!VariableIsOnlyUsedInBlock((StLoc)item, usingContainer, loopContainer))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(v.CaptureScope == null || v.CaptureScope == usingContainer))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!usedVariables.Add(v))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Determines whether storeInst.Variable is only assigned once and used only inside <paramref name=\"usingContainer\"/>.\n\t\t/// Loads by reference (ldloca) are only allowed in the context of this pointer in call instructions,\n\t\t/// or as target of ldobj.\n\t\t/// (This only applies to value types.)\n\t\t/// </summary>\n\t\tbool VariableIsOnlyUsedInBlock(StLoc storeInst, BlockContainer usingContainer, BlockContainer loopContainer)\n\t\t{\n\t\t\tif (storeInst.Variable.LoadInstructions.Any(ld => !ld.IsDescendantOf(usingContainer)))\n\t\t\t\treturn false;\n\t\t\tif (storeInst.Variable.AddressInstructions.Any(inst => !AddressUseAllowed(inst)))\n\t\t\t\treturn false;\n\t\t\tif (storeInst.Variable.StoreInstructions.OfType<ILInstruction>().Any(st => st != storeInst))\n\t\t\t\treturn false;\n\t\t\tif (!(storeInst.Variable.CaptureScope == null || storeInst.Variable.CaptureScope == loopContainer))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\n\t\t\tbool AddressUseAllowed(LdLoca la)\n\t\t\t{\n\t\t\t\tif (!la.IsDescendantOf(usingContainer))\n\t\t\t\t\treturn false;\n\t\t\t\tif (ILInlining.IsUsedAsThisPointerInCall(la) && !IsTargetOfSetterCall(la, la.Variable.Type))\n\t\t\t\t\treturn true;\n\t\t\t\tvar current = la.Parent;\n\t\t\t\twhile (current is LdFlda next)\n\t\t\t\t{\n\t\t\t\t\tcurrent = next.Parent;\n\t\t\t\t}\n\t\t\t\treturn current is LdObj;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns true if singleGetter is a value type and its address is used as setter target.\n\t\t/// </summary>\n\t\tbool CurrentIsStructSetterTarget(ILInstruction inst, CallInstruction singleGetter)\n\t\t{\n\t\t\tif (!(inst.Parent is AddressOf addr))\n\t\t\t\treturn false;\n\t\t\treturn IsTargetOfSetterCall(addr, singleGetter.Method.ReturnType);\n\t\t}\n\n\t\tbool IsTargetOfSetterCall(ILInstruction inst, IType targetType)\n\t\t{\n\t\t\tif (inst.ChildIndex != 0)\n\t\t\t\treturn false;\n\t\t\tif (targetType.IsReferenceType ?? false)\n\t\t\t\treturn false;\n\t\t\tswitch (inst.Parent.OpCode)\n\t\t\t{\n\t\t\t\tcase OpCode.Call:\n\t\t\t\tcase OpCode.CallVirt:\n\t\t\t\t\tvar targetMethod = ((CallInstruction)inst.Parent).Method;\n\t\t\t\t\tif (!targetMethod.IsAccessor || targetMethod.IsStatic)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tswitch (targetMethod.AccessorOwner)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase IProperty p:\n\t\t\t\t\t\t\treturn targetMethod.AccessorKind == System.Reflection.MethodSemanticsAttributes.Setter;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tbool ParentIsCurrentGetter(ILInstruction inst)\n\t\t{\n\t\t\treturn inst.Parent is CallInstruction cv && cv.Method.IsAccessor &&\n\t\t\t\tcv.Method.AccessorKind == System.Reflection.MethodSemanticsAttributes.Getter;\n\t\t}\n\t\t#endregion\n\n\t\tprotected internal override TranslatedStatement VisitPinnedRegion(PinnedRegion inst)\n\t\t{\n\t\t\tvar fixedStmt = new FixedStatement();\n\t\t\tfixedStmt.Type = exprBuilder.ConvertType(inst.Variable.Type);\n\t\t\tExpression initExpr;\n\t\t\tif (inst.Init is GetPinnableReference gpr)\n\t\t\t{\n\t\t\t\tif (gpr.Method != null)\n\t\t\t\t{\n\t\t\t\t\tIType expectedType = gpr.Method.IsStatic ? gpr.Method.Parameters[0].Type : gpr.Method.DeclaringType;\n\t\t\t\t\tinitExpr = exprBuilder.Translate(gpr.Argument, typeHint: expectedType).ConvertTo(expectedType, exprBuilder);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tinitExpr = exprBuilder.Translate(gpr.Argument);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tIType refType = inst.Variable.Type;\n\t\t\t\tif (refType is PointerType pointerType)\n\t\t\t\t{\n\t\t\t\t\trefType = new ByReferenceType(pointerType.ElementType);\n\t\t\t\t}\n\t\t\t\tinitExpr = exprBuilder.Translate(inst.Init, typeHint: refType).ConvertTo(refType, exprBuilder);\n\t\t\t\tif (initExpr is DirectionExpression dirExpr)\n\t\t\t\t{\n\t\t\t\t\tif (dirExpr.Expression is UnaryOperatorExpression uoe && uoe.Operator == UnaryOperatorType.Dereference)\n\t\t\t\t\t{\n\t\t\t\t\t\tinitExpr = uoe.Expression.Detach();\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tinitExpr = new UnaryOperatorExpression(UnaryOperatorType.AddressOf, dirExpr.Expression.Detach())\n\t\t\t\t\t\t\t.WithRR(new ResolveResult(inst.Variable.Type));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (initExpr.GetResolveResult()?.Type.Kind == TypeKind.Pointer\n\t\t\t\t\t&& !IsAddressOfMoveableVar(initExpr)\n\t\t\t\t\t&& !IsFixedSizeBuffer(initExpr)\n\t\t\t\t\t&& refType is ByReferenceType brt)\n\t\t\t\t{\n\t\t\t\t\t// C# doesn't allow pinning an already-unmanaged pointer\n\t\t\t\t\t//   fixed (int* ptr = existing_ptr) {} -> invalid\n\t\t\t\t\t//   fixed (int* ptr = &existing_ptr->field) {} -> invalid\n\t\t\t\t\t//   fixed (int* ptr = &local_var) {} -> invalid\n\t\t\t\t\t// We work around this by instead doing:\n\t\t\t\t\t//   fixed (int* ptr = &Unsafe.AsRef<int>(existing_ptr))\n\t\t\t\t\tvar asRefCall = exprBuilder.CallUnsafeIntrinsic(\n\t\t\t\t\t\tname: \"AsRef\",\n\t\t\t\t\t\targuments: new Expression[] { initExpr },\n\t\t\t\t\t\treturnType: brt.ElementType,\n\t\t\t\t\t\ttypeArguments: new IType[] { brt.ElementType }\n\t\t\t\t\t);\n\t\t\t\t\tinitExpr = new UnaryOperatorExpression(UnaryOperatorType.AddressOf, asRefCall)\n\t\t\t\t\t\t\t.WithRR(new ResolveResult(inst.Variable.Type));\n\t\t\t\t}\n\t\t\t}\n\t\t\tfixedStmt.Variables.Add(new VariableInitializer(inst.Variable.Name, initExpr).WithILVariable(inst.Variable));\n\t\t\tfixedStmt.EmbeddedStatement = Convert(inst.Body);\n\t\t\treturn fixedStmt.WithILInstruction(inst);\n\t\t}\n\n\t\tprivate static bool IsAddressOfMoveableVar(Expression initExpr)\n\t\t{\n\t\t\tif (initExpr is UnaryOperatorExpression { Operator: UnaryOperatorType.AddressOf } uoe)\n\t\t\t{\n\t\t\t\tvar inst = uoe.Expression.Annotation<ILInstruction>();\n\t\t\t\treturn !(inst != null && PointerArithmeticOffset.IsFixedVariable(inst));\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tprivate static bool IsFixedSizeBuffer(Expression initExpr)\n\t\t{\n\t\t\tvar mrr = initExpr.GetResolveResult() as MemberResolveResult;\n\t\t\treturn mrr?.Member is IField f && CSharpDecompiler.IsFixedField(f, out _, out _);\n\t\t}\n\n\t\tprotected internal override TranslatedStatement VisitBlock(Block block)\n\t\t{\n\t\t\tif (block.Kind != BlockKind.ControlFlow)\n\t\t\t\treturn Default(block);\n\t\t\t// Block without container\n\t\t\tBlockStatement blockStatement = new BlockStatement();\n\t\t\tforeach (var inst in block.Instructions)\n\t\t\t{\n\t\t\t\tblockStatement.Add(Convert(inst));\n\t\t\t}\n\t\t\tif (block.FinalInstruction.OpCode != OpCode.Nop)\n\t\t\t\tblockStatement.Add(Convert(block.FinalInstruction));\n\t\t\treturn blockStatement.WithILInstruction(block);\n\t\t}\n\n\t\tprotected internal override TranslatedStatement VisitBlockContainer(BlockContainer container)\n\t\t{\n\t\t\tif (container.Kind != ContainerKind.Normal && container.EntryPoint.IncomingEdgeCount > 1)\n\t\t\t{\n\t\t\t\tvar oldContinueTarget = continueTarget;\n\t\t\t\tvar oldContinueCount = continueCount;\n\t\t\t\tvar oldBreakTarget = breakTarget;\n\t\t\t\tvar loop = ConvertLoop(container);\n\t\t\t\tloop.AddAnnotation(container);\n\t\t\t\tcontinueTarget = oldContinueTarget;\n\t\t\t\tcontinueCount = oldContinueCount;\n\t\t\t\tbreakTarget = oldBreakTarget;\n\t\t\t\treturn loop.WithILInstruction(container);\n\t\t\t}\n\t\t\telse if (container.EntryPoint.Instructions.Count == 1 && container.EntryPoint.Instructions[0] is SwitchInstruction switchInst)\n\t\t\t{\n\t\t\t\treturn TranslateSwitch(container, switchInst).WithILInstruction(container);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar blockStmt = ConvertBlockContainer(container, false);\n\t\t\t\treturn blockStmt.WithILInstruction(container);\n\t\t\t}\n\t\t}\n\n\t\tStatement ConvertLoop(BlockContainer container)\n\t\t{\n\t\t\tILInstruction condition;\n\t\t\tBlock loopBody;\n\t\t\tBlockStatement blockStatement;\n\t\t\tcontinueCount = 0;\n\t\t\tbreakTarget = container;\n\t\t\tswitch (container.Kind)\n\t\t\t{\n\t\t\t\tcase ContainerKind.Loop:\n\t\t\t\t\tcontinueTarget = container.EntryPoint;\n\t\t\t\t\tblockStatement = ConvertBlockContainer(container, true);\n\t\t\t\t\tDebug.Assert(continueCount < container.EntryPoint.IncomingEdgeCount);\n\t\t\t\t\tDebug.Assert(blockStatement.Statements.First() is LabelStatement);\n\t\t\t\t\tif (container.EntryPoint.IncomingEdgeCount == continueCount + 1)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Remove the entrypoint label if all jumps to the label were replaced with 'continue;' statements\n\t\t\t\t\t\tblockStatement.Statements.First().Remove();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (blockStatement.LastOrDefault() is ContinueStatement continueStmt)\n\t\t\t\t\t\tcontinueStmt.Remove();\n\t\t\t\t\tDeclareLocalFunctions(currentFunction, container, blockStatement);\n\t\t\t\t\treturn new WhileStatement(new PrimitiveExpression(true), blockStatement);\n\t\t\t\tcase ContainerKind.While:\n\t\t\t\t\tcontinueTarget = container.EntryPoint;\n\t\t\t\t\tif (!container.MatchConditionBlock(continueTarget, out condition, out loopBody))\n\t\t\t\t\t\tthrow new NotSupportedException(\"Invalid condition block in while loop.\");\n\t\t\t\t\tblockStatement = ConvertAsBlock(loopBody);\n\t\t\t\t\tif (!loopBody.HasFlag(InstructionFlags.EndPointUnreachable))\n\t\t\t\t\t\tblockStatement.Add(new BreakStatement());\n\t\t\t\t\tblockStatement = ConvertBlockContainer(blockStatement, container, container.Blocks.Skip(1).Except(new[] { loopBody }), true);\n\t\t\t\t\tDebug.Assert(continueCount < container.EntryPoint.IncomingEdgeCount);\n\t\t\t\t\tif (continueCount + 1 < container.EntryPoint.IncomingEdgeCount)\n\t\t\t\t\t{\n\t\t\t\t\t\t// There's an incoming edge to the entry point (=while condition) that wasn't represented as \"continue;\"\n\t\t\t\t\t\t// -> emit a real label\n\t\t\t\t\t\t// We'll also remove any \"continue;\" in front of the label, as it's redundant.\n\t\t\t\t\t\tif (blockStatement.LastOrDefault() is ContinueStatement)\n\t\t\t\t\t\t\tblockStatement.Last().Remove();\n\t\t\t\t\t\tblockStatement.Add(new LabelStatement { Label = EnsureUniqueLabel(container.EntryPoint) });\n\t\t\t\t\t}\n\n\t\t\t\t\tif (blockStatement.LastOrDefault() is ContinueStatement continueStmt2)\n\t\t\t\t\t\tcontinueStmt2.Remove();\n\t\t\t\t\tDeclareLocalFunctions(currentFunction, container, blockStatement);\n\t\t\t\t\treturn new WhileStatement(exprBuilder.TranslateCondition(condition), blockStatement);\n\t\t\t\tcase ContainerKind.DoWhile:\n\t\t\t\t\tcontinueTarget = container.Blocks.Last();\n\t\t\t\t\tif (!container.MatchConditionBlock(continueTarget, out condition, out _))\n\t\t\t\t\t\tthrow new NotSupportedException(\"Invalid condition block in do-while loop.\");\n\t\t\t\t\tblockStatement = ConvertBlockContainer(new BlockStatement(), container, container.Blocks.SkipLast(1), true);\n\t\t\t\t\tif (container.EntryPoint.IncomingEdgeCount == 2)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Remove the entry-point label, if there are only two jumps to the entry-point:\n\t\t\t\t\t\t// from outside the loop and from the condition-block.\n\t\t\t\t\t\tblockStatement.Statements.First().Remove();\n\t\t\t\t\t}\n\t\t\t\t\tif (blockStatement.LastOrDefault() is ContinueStatement continueStmt3)\n\t\t\t\t\t\tcontinueStmt3.Remove();\n\t\t\t\t\tif (continueTarget.IncomingEdgeCount > continueCount)\n\t\t\t\t\t{\n\t\t\t\t\t\t// if there are branches to the condition block, that were not converted\n\t\t\t\t\t\t// to continue statements, we have to introduce an extra label.\n\t\t\t\t\t\tblockStatement.Add(new LabelStatement { Label = EnsureUniqueLabel(continueTarget) });\n\t\t\t\t\t}\n\t\t\t\t\tDeclareLocalFunctions(currentFunction, container, blockStatement);\n\t\t\t\t\tif (blockStatement.Statements.Count == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new WhileStatement {\n\t\t\t\t\t\t\tCondition = exprBuilder.TranslateCondition(condition),\n\t\t\t\t\t\t\tEmbeddedStatement = blockStatement\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\treturn new DoWhileStatement {\n\t\t\t\t\t\tEmbeddedStatement = blockStatement,\n\t\t\t\t\t\tCondition = exprBuilder.TranslateCondition(condition)\n\t\t\t\t\t};\n\t\t\t\tcase ContainerKind.For:\n\t\t\t\t\tcontinueTarget = container.Blocks.Last();\n\t\t\t\t\tif (!container.MatchConditionBlock(container.EntryPoint, out condition, out loopBody))\n\t\t\t\t\t\tthrow new NotSupportedException(\"Invalid condition block in for loop.\");\n\t\t\t\t\tblockStatement = ConvertAsBlock(loopBody);\n\t\t\t\t\tif (!loopBody.HasFlag(InstructionFlags.EndPointUnreachable))\n\t\t\t\t\t\tblockStatement.Add(new BreakStatement());\n\t\t\t\t\tif (!container.MatchIncrementBlock(continueTarget))\n\t\t\t\t\t\tthrow new NotSupportedException(\"Invalid increment block in for loop.\");\n\t\t\t\t\tblockStatement = ConvertBlockContainer(blockStatement, container, container.Blocks.SkipLast(1).Skip(1).Except(new[] { loopBody }), true);\n\t\t\t\t\tvar forStmt = new ForStatement() {\n\t\t\t\t\t\tCondition = exprBuilder.TranslateCondition(condition),\n\t\t\t\t\t\tEmbeddedStatement = blockStatement\n\t\t\t\t\t};\n\t\t\t\t\tif (blockStatement.LastOrDefault() is ContinueStatement continueStmt4)\n\t\t\t\t\t\tcontinueStmt4.Remove();\n\t\t\t\t\tfor (int i = 0; i < continueTarget.Instructions.Count - 1; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tforStmt.Iterators.Add(Convert(continueTarget.Instructions[i]));\n\t\t\t\t\t}\n\t\t\t\t\tif (continueTarget.IncomingEdgeCount > continueCount)\n\t\t\t\t\t\tblockStatement.Add(new LabelStatement { Label = EnsureUniqueLabel(continueTarget) });\n\t\t\t\t\tDeclareLocalFunctions(currentFunction, container, blockStatement);\n\t\t\t\t\treturn forStmt;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t}\n\t\t}\n\n\t\tBlockStatement ConvertBlockContainer(BlockContainer container, bool isLoop)\n\t\t{\n\t\t\tvar blockStatement = ConvertBlockContainer(new BlockStatement(), container, container.Blocks, isLoop);\n\t\t\tDeclareLocalFunctions(currentFunction, container, blockStatement);\n\t\t\tif (currentFunction.Body == container)\n\t\t\t{\n\t\t\t\tif (EmitAsRefReadOnly)\n\t\t\t\t{\n\t\t\t\t\tvar methodDecl = new MethodDeclaration();\n\t\t\t\t\tif (settings.StaticLocalFunctions)\n\t\t\t\t\t{\n\t\t\t\t\t\tmethodDecl.Modifiers = Modifiers.Static;\n\t\t\t\t\t}\n\n\t\t\t\t\tmethodDecl.ReturnType = new ComposedType() { HasReadOnlySpecifier = true, HasRefSpecifier = true, BaseType = new SimpleType(\"T\") };\n\t\t\t\t\tmethodDecl.Name = \"ILSpyHelper_AsRefReadOnly\";\n\t\t\t\t\tmethodDecl.TypeParameters.Add(new TypeParameterDeclaration(\"T\"));\n\t\t\t\t\tmethodDecl.Parameters.Add(new ParameterDeclaration { ParameterModifier = ReferenceKind.In, Type = new SimpleType(\"T\"), Name = \"temp\" });\n\n\t\t\t\t\tmethodDecl.Body = new BlockStatement();\n\t\t\t\t\tmethodDecl.Body.AddChild(new Comment(\n\t\t\t\t\t\t\"ILSpy generated this function to help ensure overload resolution can pick the overload using 'in'\"),\n\t\t\t\t\t\t\t\t\t\t\t Roles.Comment);\n\t\t\t\t\tmethodDecl.Body.Add(new ReturnStatement(new DirectionExpression(FieldDirection.Ref, new IdentifierExpression(\"temp\"))));\n\n\t\t\t\t\tblockStatement.Statements.Add(\n\t\t\t\t\t\tnew LocalFunctionDeclarationStatement(methodDecl)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn blockStatement;\n\t\t}\n\n\t\tvoid DeclareLocalFunctions(ILFunction currentFunction, BlockContainer container, BlockStatement blockStatement)\n\t\t{\n\t\t\tforeach (var localFunction in currentFunction.LocalFunctions.OrderBy(f => f.Name))\n\t\t\t{\n\t\t\t\tif (localFunction.DeclarationScope != container)\n\t\t\t\t\tcontinue;\n\t\t\t\tblockStatement.Add(TranslateFunction(localFunction));\n\t\t\t}\n\n\t\t\tLocalFunctionDeclarationStatement TranslateFunction(ILFunction function)\n\t\t\t{\n\t\t\t\tvar astBuilder = exprBuilder.astBuilder;\n\t\t\t\tvar method = (MethodDeclaration)astBuilder.ConvertEntity(function.ReducedMethod);\n\n\t\t\t\tvar variables = function.Variables.Where(v => v.Kind == VariableKind.Parameter).ToDictionary(v => v.Index);\n\n\t\t\t\tforeach (var (i, p) in method.Parameters.WithIndex())\n\t\t\t\t{\n\t\t\t\t\tif (variables.TryGetValue(i, out var v))\n\t\t\t\t\t{\n\t\t\t\t\t\tp.Name = v.Name;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (function.Method.HasBody)\n\t\t\t\t{\n\t\t\t\t\tvar nestedBuilder = new StatementBuilder(\n\t\t\t\t\t\ttypeSystem,\n\t\t\t\t\t\texprBuilder.decompilationContext,\n\t\t\t\t\t\tfunction,\n\t\t\t\t\t\tsettings,\n\t\t\t\t\t\tdecompileRun,\n\t\t\t\t\t\tcancellationToken\n\t\t\t\t\t);\n\n\t\t\t\t\tmethod.Body = nestedBuilder.ConvertAsBlock(function.Body);\n\n\t\t\t\t\tComment prev = null;\n\t\t\t\t\tforeach (string warning in function.Warnings)\n\t\t\t\t\t{\n\t\t\t\t\t\tmethod.Body.InsertChildAfter(prev, prev = new Comment(warning), Roles.Comment);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tmethod.Modifiers |= Modifiers.Extern;\n\t\t\t\t}\n\n\t\t\t\tCSharpDecompiler.AddAnnotationsToDeclaration(function.ReducedMethod, method, function);\n\t\t\t\tCSharpDecompiler.CleanUpMethodDeclaration(method, method.Body, function, function.Method.HasBody);\n\t\t\t\tCSharpDecompiler.RemoveAttribute(method, KnownAttribute.CompilerGenerated);\n\t\t\t\tvar stmt = new LocalFunctionDeclarationStatement(method);\n\t\t\t\tstmt.AddAnnotation(new MemberResolveResult(null, function.ReducedMethod));\n\t\t\t\tstmt.WithILInstruction(function);\n\t\t\t\treturn stmt;\n\t\t\t}\n\t\t}\n\n\t\tBlockStatement ConvertBlockContainer(BlockStatement blockStatement, BlockContainer container, IEnumerable<Block> blocks, bool isLoop)\n\t\t{\n\t\t\tforeach (var block in blocks)\n\t\t\t{\n\t\t\t\tif (block.IncomingEdgeCount > 1 || block != container.EntryPoint)\n\t\t\t\t{\n\t\t\t\t\t// If there are any incoming branches to this block, add a label:\n\t\t\t\t\tblockStatement.Add(new LabelStatement { Label = EnsureUniqueLabel(block) });\n\t\t\t\t}\n\t\t\t\tforeach (var inst in block.Instructions)\n\t\t\t\t{\n\t\t\t\t\tif (!isLoop && inst is Leave leave && IsFinalLeave(leave))\n\t\t\t\t\t{\n\t\t\t\t\t\t// skip the final 'leave' instruction and just fall out of the BlockStatement\n\t\t\t\t\t\tblockStatement.AddAnnotation(new ImplicitReturnAnnotation(leave));\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tvar stmt = Convert(inst);\n\t\t\t\t\tif (stmt is BlockStatement b)\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var nested in b.Statements)\n\t\t\t\t\t\t\tblockStatement.Add(nested.Detach());\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tblockStatement.Add(stmt.Detach());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (block.FinalInstruction.OpCode != OpCode.Nop)\n\t\t\t\t{\n\t\t\t\t\tblockStatement.Add(Convert(block.FinalInstruction));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (endContainerLabels.TryGetValue(container, out string label))\n\t\t\t{\n\t\t\t\tif (isLoop && !(blockStatement.LastOrDefault() is ContinueStatement))\n\t\t\t\t{\n\t\t\t\t\tblockStatement.Add(new ContinueStatement());\n\t\t\t\t}\n\t\t\t\tblockStatement.Add(new LabelStatement { Label = label });\n\t\t\t\tif (isLoop)\n\t\t\t\t{\n\t\t\t\t\tblockStatement.Add(new BreakStatement());\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn blockStatement;\n\t\t}\n\n\t\treadonly Dictionary<Block, string> labels = new Dictionary<Block, string>();\n\t\treadonly Dictionary<string, int> duplicateLabels = new Dictionary<string, int>();\n\n\t\tstring EnsureUniqueLabel(Block block)\n\t\t{\n\t\t\tif (labels.TryGetValue(block, out string label))\n\t\t\t\treturn label;\n\t\t\tif (!duplicateLabels.TryGetValue(block.Label, out int count))\n\t\t\t{\n\t\t\t\tlabels.Add(block, block.Label);\n\t\t\t\tduplicateLabels.Add(block.Label, 1);\n\t\t\t\treturn block.Label;\n\t\t\t}\n\t\t\tlabel = $\"{block.Label}_{count + 1}\";\n\t\t\tduplicateLabels[block.Label]++;\n\t\t\tlabels.Add(block, label);\n\t\t\treturn label;\n\t\t}\n\n\t\tstatic bool IsFinalLeave(Leave leave)\n\t\t{\n\t\t\tif (!leave.Value.MatchNop())\n\t\t\t\treturn false;\n\t\t\tBlock block = (Block)leave.Parent;\n\t\t\tif (leave.ChildIndex != block.Instructions.Count - 1 || block.FinalInstruction.OpCode != OpCode.Nop)\n\t\t\t\treturn false;\n\t\t\tBlockContainer container = (BlockContainer)block.Parent;\n\t\t\treturn block.ChildIndex == container.Blocks.Count - 1\n\t\t\t\t&& container == leave.TargetContainer;\n\t\t}\n\n\t\tprotected internal override TranslatedStatement VisitInitblk(Initblk inst)\n\t\t{\n\t\t\tvar stmt = new ExpressionStatement(\n\t\t\t\texprBuilder.CallUnsafeIntrinsic(\n\t\t\t\t\tinst.UnalignedPrefix != 0 ? \"InitBlockUnaligned\" : \"InitBlock\",\n\t\t\t\t\tnew Expression[] {\n\t\t\t\t\t\texprBuilder.Translate(inst.Address),\n\t\t\t\t\t\texprBuilder.Translate(inst.Value),\n\t\t\t\t\t\texprBuilder.Translate(inst.Size)\n\t\t\t\t\t},\n\t\t\t\t\texprBuilder.compilation.FindType(KnownTypeCode.Void),\n\t\t\t\t\tinst\n\t\t\t\t)\n\t\t\t);\n\t\t\tstmt.InsertChildAfter(null, new Comment(\" IL initblk instruction\"), Roles.Comment);\n\t\t\treturn stmt.WithILInstruction(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedStatement VisitCpblk(Cpblk inst)\n\t\t{\n\t\t\tvar stmt = new ExpressionStatement(\n\t\t\t\texprBuilder.CallUnsafeIntrinsic(\n\t\t\t\t\tinst.UnalignedPrefix != 0 ? \"CopyBlockUnaligned\" : \"CopyBlock\",\n\t\t\t\t\tnew Expression[] {\n\t\t\t\t\t\texprBuilder.Translate(inst.DestAddress),\n\t\t\t\t\t\texprBuilder.Translate(inst.SourceAddress),\n\t\t\t\t\t\texprBuilder.Translate(inst.Size)\n\t\t\t\t\t},\n\t\t\t\t\texprBuilder.compilation.FindType(KnownTypeCode.Void),\n\t\t\t\t\tinst\n\t\t\t\t)\n\t\t\t);\n\t\t\tstmt.InsertChildAfter(null, new Comment(\" IL cpblk instruction\"), Roles.Comment);\n\t\t\treturn stmt.WithILInstruction(inst);\n\t\t}\n\n\t\tprotected internal override TranslatedStatement VisitCkfinite(Ckfinite inst)\n\t\t{\n\t\t\tvar isFiniteCall = new InvocationExpression {\n\t\t\t\tTarget = new MemberReferenceExpression {\n\t\t\t\t\tTarget = new TypeReferenceExpression(new Syntax.PrimitiveType(\"float\")),\n\t\t\t\t\tMemberName = \"IsFinite\"\n\t\t\t\t},\n\t\t\t\tArguments = {\n\t\t\t\t\texprBuilder.Translate(inst.Argument)\n\t\t\t\t}\n\t\t\t};\n\t\t\tvar arithmeticException = typeSystem.FindType(typeof(ArithmeticException));\n\t\t\tvar arithmeticExceptionSyntax = new SimpleType(\"ArithmeticException\");\n\t\t\tarithmeticExceptionSyntax.AddAnnotation(new TypeResolveResult(arithmeticException));\n\t\t\treturn new IfElseStatement {\n\t\t\t\tCondition = new UnaryOperatorExpression {\n\t\t\t\t\tOperator = UnaryOperatorType.Not,\n\t\t\t\t\tExpression = isFiniteCall\n\t\t\t\t},\n\t\t\t\tTrueStatement = new ThrowStatement(\n\t\t\t\t\tnew ObjectCreateExpression {\n\t\t\t\t\t\tType = arithmeticExceptionSyntax\n\t\t\t\t\t}\n\t\t\t\t),\n\t\t\t}.WithILInstruction(inst);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/AstNode.cs",
    "content": "#nullable enable\n// \n// AstNode.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic abstract class AstNode : AbstractAnnotatable, IFreezable, INode, ICloneable\n\t{\n\t\t// the Root role must be available when creating the null nodes, so we can't put it in the Roles class\n\t\tinternal static readonly Role<AstNode?> RootRole = new Role<AstNode?>(\"Root\", null);\n\n\t\t#region Null\n\t\tpublic static readonly AstNode Null = new NullAstNode();\n\n\t\tsealed class NullAstNode : AstNode\n\t\t{\n\t\t\tpublic override NodeType NodeType {\n\t\t\t\tget {\n\t\t\t\t\treturn NodeType.Unknown;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override bool IsNull {\n\t\t\t\tget {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode? other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn other == null || other.IsNull;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region PatternPlaceholder\n\t\tpublic static implicit operator AstNode?(PatternMatching.Pattern? pattern)\n\t\t{\n\t\t\treturn pattern != null ? new PatternPlaceholder(pattern) : null;\n\t\t}\n\n\t\tsealed class PatternPlaceholder : AstNode, INode\n\t\t{\n\t\t\treadonly PatternMatching.Pattern child;\n\n\t\t\tpublic PatternPlaceholder(PatternMatching.Pattern child)\n\t\t\t{\n\t\t\t\tthis.child = child;\n\t\t\t}\n\n\t\t\tpublic override NodeType NodeType {\n\t\t\t\tget { return NodeType.Pattern; }\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode? other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn child.DoMatch(other, match);\n\t\t\t}\n\n\t\t\tbool PatternMatching.INode.DoMatchCollection(Role? role, PatternMatching.INode? pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)\n\t\t\t{\n\t\t\t\treturn child.DoMatchCollection(role, pos, match, backtrackingInfo);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tAstNode? parent;\n\t\tAstNode? prevSibling;\n\t\tAstNode? nextSibling;\n\t\tAstNode? firstChild;\n\t\tAstNode? lastChild;\n\n\t\t// Flags, from least significant to most significant bits:\n\t\t// - Role.RoleIndexBits: role index\n\t\t// - 1 bit: IsFrozen\n\t\tprotected uint flags = RootRole.Index;\n\t\t// Derived classes may also use a few bits,\n\t\t// for example Identifier uses 1 bit for IsVerbatim\n\n\t\tconst uint roleIndexMask = (1u << Role.RoleIndexBits) - 1;\n\t\tconst uint frozenBit = 1u << Role.RoleIndexBits;\n\t\tprotected const int AstNodeFlagsUsedBits = Role.RoleIndexBits + 1;\n\n\t\tprotected AstNode()\n\t\t{\n\t\t\tif (IsNull)\n\t\t\t\tFreeze();\n\t\t}\n\n\t\tpublic bool IsFrozen {\n\t\t\tget { return (flags & frozenBit) != 0; }\n\t\t}\n\n\t\tpublic void Freeze()\n\t\t{\n\t\t\tif (!IsFrozen)\n\t\t\t{\n\t\t\t\tfor (AstNode? child = firstChild; child != null; child = child.nextSibling)\n\t\t\t\t\tchild.Freeze();\n\t\t\t\tflags |= frozenBit;\n\t\t\t}\n\t\t}\n\n\t\tprotected void ThrowIfFrozen()\n\t\t{\n\t\t\tif (IsFrozen)\n\t\t\t\tthrow new InvalidOperationException(\"Cannot mutate frozen \" + GetType().Name);\n\t\t}\n\n\t\tpublic abstract NodeType NodeType {\n\t\t\tget;\n\t\t}\n\n\t\tpublic virtual bool IsNull {\n\t\t\tget {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic virtual TextLocation StartLocation {\n\t\t\tget {\n\t\t\t\tvar child = firstChild;\n\t\t\t\tif (child == null)\n\t\t\t\t\treturn TextLocation.Empty;\n\t\t\t\treturn child.StartLocation;\n\t\t\t}\n\t\t}\n\n\t\tpublic virtual TextLocation EndLocation {\n\t\t\tget {\n\t\t\t\tvar child = lastChild;\n\t\t\t\tif (child == null)\n\t\t\t\t\treturn TextLocation.Empty;\n\t\t\t\treturn child.EndLocation;\n\t\t\t}\n\t\t}\n\n\t\tpublic AstNode? Parent {\n\t\t\tget { return parent; }\n\t\t}\n\n\t\tpublic Role Role {\n\t\t\tget {\n\t\t\t\treturn Role.GetByIndex(flags & roleIndexMask);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tif (value == null)\n\t\t\t\t\tthrow new ArgumentNullException(nameof(value));\n\t\t\t\tif (!value.IsValid(this))\n\t\t\t\t\tthrow new ArgumentException(\"This node is not valid in the new role.\");\n\t\t\t\tThrowIfFrozen();\n\t\t\t\tSetRole(value);\n\t\t\t}\n\t\t}\n\n\t\tinternal uint RoleIndex {\n\t\t\tget { return flags & roleIndexMask; }\n\t\t}\n\n\t\tvoid SetRole(Role role)\n\t\t{\n\t\t\tflags = (flags & ~roleIndexMask) | role.Index;\n\t\t}\n\n\t\tpublic AstNode? NextSibling {\n\t\t\tget { return nextSibling; }\n\t\t}\n\n\t\tpublic AstNode? PrevSibling {\n\t\t\tget { return prevSibling; }\n\t\t}\n\n\t\tpublic AstNode? FirstChild {\n\t\t\tget { return firstChild; }\n\t\t}\n\n\t\tpublic AstNode? LastChild {\n\t\t\tget { return lastChild; }\n\t\t}\n\n\t\tpublic bool HasChildren {\n\t\t\tget {\n\t\t\t\treturn firstChild != null;\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable<AstNode> Children {\n\t\t\tget {\n\t\t\t\tAstNode? next;\n\t\t\t\tfor (AstNode? cur = firstChild; cur != null; cur = next)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(cur.parent == this);\n\t\t\t\t\t// Remember next before yielding cur.\n\t\t\t\t\t// This allows removing/replacing nodes while iterating through the list.\n\t\t\t\t\tnext = cur.nextSibling;\n\t\t\t\t\tyield return cur;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the ancestors of this node (excluding this node itself)\n\t\t/// </summary>\n\t\tpublic IEnumerable<AstNode> Ancestors {\n\t\t\tget {\n\t\t\t\tfor (AstNode? cur = parent; cur != null; cur = cur.parent)\n\t\t\t\t{\n\t\t\t\t\tyield return cur;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the ancestors of this node (including this node itself)\n\t\t/// </summary>\n\t\tpublic IEnumerable<AstNode> AncestorsAndSelf {\n\t\t\tget {\n\t\t\t\tfor (AstNode? cur = this; cur != null; cur = cur.parent)\n\t\t\t\t{\n\t\t\t\t\tyield return cur;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets all descendants of this node (excluding this node itself) in pre-order.\n\t\t/// </summary>\n\t\tpublic IEnumerable<AstNode> Descendants {\n\t\t\tget { return GetDescendantsImpl(false); }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets all descendants of this node (including this node itself) in pre-order.\n\t\t/// </summary>\n\t\tpublic IEnumerable<AstNode> DescendantsAndSelf {\n\t\t\tget { return GetDescendantsImpl(true); }\n\t\t}\n\n\t\tpublic IEnumerable<AstNode> DescendantNodes(Func<AstNode, bool>? descendIntoChildren = null)\n\t\t{\n\t\t\treturn GetDescendantsImpl(false, descendIntoChildren);\n\t\t}\n\n\t\tpublic IEnumerable<AstNode> DescendantNodesAndSelf(Func<AstNode, bool>? descendIntoChildren = null)\n\t\t{\n\t\t\treturn GetDescendantsImpl(true, descendIntoChildren);\n\t\t}\n\n\t\tIEnumerable<AstNode> GetDescendantsImpl(bool includeSelf, Func<AstNode, bool>? descendIntoChildren = null)\n\t\t{\n\t\t\tif (includeSelf)\n\t\t\t{\n\t\t\t\tyield return this;\n\t\t\t\tif (descendIntoChildren != null && !descendIntoChildren(this))\n\t\t\t\t\tyield break;\n\t\t\t}\n\n\t\t\tStack<AstNode?> nextStack = new Stack<AstNode?>();\n\t\t\tnextStack.Push(null);\n\t\t\tAstNode? pos = firstChild;\n\t\t\twhile (pos != null)\n\t\t\t{\n\t\t\t\t// Remember next before yielding pos.\n\t\t\t\t// This allows removing/replacing nodes while iterating through the list.\n\t\t\t\tif (pos.nextSibling != null)\n\t\t\t\t\tnextStack.Push(pos.nextSibling);\n\t\t\t\tyield return pos;\n\t\t\t\tif (pos.firstChild != null && (descendIntoChildren == null || descendIntoChildren(pos)))\n\t\t\t\t\tpos = pos.firstChild;\n\t\t\t\telse\n\t\t\t\t\tpos = nextStack.Pop();\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the first child with the specified role.\n\t\t/// Returns the role's null object if the child is not found.\n\t\t/// </summary>\n\t\tpublic T GetChildByRole<T>(Role<T> role) where T : AstNode?\n\t\t{\n\t\t\tif (role == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(role));\n\t\t\tuint roleIndex = role.Index;\n\t\t\tfor (var cur = firstChild; cur != null; cur = cur.nextSibling)\n\t\t\t{\n\t\t\t\tif ((cur.flags & roleIndexMask) == roleIndex)\n\t\t\t\t\treturn (T)cur;\n\t\t\t}\n\t\t\treturn role.NullObject;\n\t\t}\n\n\t\tpublic T? GetParent<T>() where T : AstNode\n\t\t{\n\t\t\treturn Ancestors.OfType<T>().FirstOrDefault();\n\t\t}\n\n\t\tpublic AstNode? GetParent(Func<AstNode, bool>? pred)\n\t\t{\n\t\t\treturn pred != null ? Ancestors.FirstOrDefault(pred) : Ancestors.FirstOrDefault();\n\t\t}\n\n\t\tpublic AstNodeCollection<T> GetChildrenByRole<T>(Role<T> role) where T : AstNode\n\t\t{\n\t\t\treturn new AstNodeCollection<T>(this, role);\n\t\t}\n\n\t\tprotected void SetChildByRole<T>(Role<T> role, T newChild) where T : AstNode\n\t\t{\n\t\t\tAstNode oldChild = GetChildByRole(role);\n\t\t\tif (oldChild.IsNull)\n\t\t\t\tAddChild(newChild, role);\n\t\t\telse\n\t\t\t\toldChild.ReplaceWith(newChild);\n\t\t}\n\n\t\tpublic void AddChild<T>(T child, Role<T> role) where T : AstNode\n\t\t{\n\t\t\tif (role == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(role));\n\t\t\tif (child == null || child.IsNull)\n\t\t\t\treturn;\n\t\t\tThrowIfFrozen();\n\t\t\tif (child == this)\n\t\t\t\tthrow new ArgumentException(\"Cannot add a node to itself as a child.\", nameof(child));\n\t\t\tif (child.parent != null)\n\t\t\t\tthrow new ArgumentException(\"Node is already used in another tree.\", nameof(child));\n\t\t\tif (child.IsFrozen)\n\t\t\t\tthrow new ArgumentException(\"Cannot add a frozen node.\", nameof(child));\n\t\t\tAddChildUnsafe(child, role);\n\t\t}\n\n\t\tpublic void AddChildWithExistingRole(AstNode? child)\n\t\t{\n\t\t\tif (child == null || child.IsNull)\n\t\t\t\treturn;\n\t\t\tThrowIfFrozen();\n\t\t\tif (child == this)\n\t\t\t\tthrow new ArgumentException(\"Cannot add a node to itself as a child.\", nameof(child));\n\t\t\tif (child.parent != null)\n\t\t\t\tthrow new ArgumentException(\"Node is already used in another tree.\", nameof(child));\n\t\t\tif (child.IsFrozen)\n\t\t\t\tthrow new ArgumentException(\"Cannot add a frozen node.\", nameof(child));\n\t\t\tAddChildUnsafe(child, child.Role);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Adds a child without performing any safety checks.\n\t\t/// </summary>\n\t\tinternal void AddChildUnsafe(AstNode child, Role role)\n\t\t{\n\t\t\tchild.parent = this;\n\t\t\tchild.SetRole(role);\n\t\t\tif (firstChild == null)\n\t\t\t{\n\t\t\t\tlastChild = firstChild = child;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tlastChild!.nextSibling = child;\n\t\t\t\tchild.prevSibling = lastChild;\n\t\t\t\tlastChild = child;\n\t\t\t}\n\t\t}\n\n\t\tpublic void InsertChildBefore<T>(AstNode? nextSibling, T child, Role<T> role) where T : AstNode\n\t\t{\n\t\t\tif (role == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(role));\n\t\t\tif (nextSibling == null || nextSibling.IsNull)\n\t\t\t{\n\t\t\t\tAddChild(child, role);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (child == null || child.IsNull)\n\t\t\t\treturn;\n\t\t\tThrowIfFrozen();\n\t\t\tif (child.parent != null)\n\t\t\t\tthrow new ArgumentException(\"Node is already used in another tree.\", nameof(child));\n\t\t\tif (child.IsFrozen)\n\t\t\t\tthrow new ArgumentException(\"Cannot add a frozen node.\", nameof(child));\n\t\t\tif (nextSibling.parent != this)\n\t\t\t\tthrow new ArgumentException(\"NextSibling is not a child of this node.\", nameof(nextSibling));\n\t\t\t// No need to test for \"Cannot add children to null nodes\",\n\t\t\t// as there isn't any valid nextSibling in null nodes.\n\t\t\tInsertChildBeforeUnsafe(nextSibling, child, role);\n\t\t}\n\n\t\tinternal void InsertChildBeforeUnsafe(AstNode nextSibling, AstNode child, Role role)\n\t\t{\n\t\t\tchild.parent = this;\n\t\t\tchild.SetRole(role);\n\t\t\tchild.nextSibling = nextSibling;\n\t\t\tchild.prevSibling = nextSibling.prevSibling;\n\n\t\t\tif (nextSibling.prevSibling != null)\n\t\t\t{\n\t\t\t\tDebug.Assert(nextSibling.prevSibling.nextSibling == nextSibling);\n\t\t\t\tnextSibling.prevSibling.nextSibling = child;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDebug.Assert(firstChild == nextSibling);\n\t\t\t\tfirstChild = child;\n\t\t\t}\n\t\t\tnextSibling.prevSibling = child;\n\t\t}\n\n\t\tpublic void InsertChildAfter<T>(AstNode? prevSibling, T child, Role<T> role) where T : AstNode\n\t\t{\n\t\t\tInsertChildBefore((prevSibling == null || prevSibling.IsNull) ? firstChild : prevSibling.nextSibling, child, role);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Removes this node from its parent.\n\t\t/// </summary>\n\t\tpublic void Remove()\n\t\t{\n\t\t\tif (parent != null)\n\t\t\t{\n\t\t\t\tThrowIfFrozen();\n\t\t\t\tif (prevSibling != null)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(prevSibling.nextSibling == this);\n\t\t\t\t\tprevSibling.nextSibling = nextSibling;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(parent.firstChild == this);\n\t\t\t\t\tparent.firstChild = nextSibling;\n\t\t\t\t}\n\t\t\t\tif (nextSibling != null)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(nextSibling.prevSibling == this);\n\t\t\t\t\tnextSibling.prevSibling = prevSibling;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(parent.lastChild == this);\n\t\t\t\t\tparent.lastChild = prevSibling;\n\t\t\t\t}\n\t\t\t\tparent = null;\n\t\t\t\tprevSibling = null;\n\t\t\t\tnextSibling = null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Replaces this node with the new node.\n\t\t/// </summary>\n\t\tpublic void ReplaceWith(AstNode? newNode)\n\t\t{\n\t\t\tif (newNode == null || newNode.IsNull)\n\t\t\t{\n\t\t\t\tRemove();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (newNode == this)\n\t\t\t\treturn; // nothing to do...\n\t\t\tif (parent == null)\n\t\t\t{\n\t\t\t\tthrow new InvalidOperationException(this.IsNull ? \"Cannot replace the null nodes\" : \"Cannot replace the root node\");\n\t\t\t}\n\t\t\tThrowIfFrozen();\n\t\t\t// Because this method doesn't statically check the new node's type with the role,\n\t\t\t// we perform a runtime test:\n\t\t\tif (!this.Role.IsValid(newNode))\n\t\t\t{\n\t\t\t\tthrow new ArgumentException(string.Format(\"The new node '{0}' is not valid in the role {1}\", newNode.GetType().Name, this.Role.ToString()), nameof(newNode));\n\t\t\t}\n\t\t\tif (newNode.parent != null)\n\t\t\t{\n\t\t\t\t// newNode is used within this tree?\n\t\t\t\tif (newNode.Ancestors.Contains(this))\n\t\t\t\t{\n\t\t\t\t\t// e.g. \"parenthesizedExpr.ReplaceWith(parenthesizedExpr.Expression);\"\n\t\t\t\t\t// enable automatic removal\n\t\t\t\t\tnewNode.Remove();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthrow new ArgumentException(\"Node is already used in another tree.\", nameof(newNode));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (newNode.IsFrozen)\n\t\t\t\tthrow new ArgumentException(\"Cannot add a frozen node.\", nameof(newNode));\n\n\t\t\tnewNode.parent = parent;\n\t\t\tnewNode.SetRole(this.Role);\n\t\t\tnewNode.prevSibling = prevSibling;\n\t\t\tnewNode.nextSibling = nextSibling;\n\n\t\t\tif (prevSibling != null)\n\t\t\t{\n\t\t\t\tDebug.Assert(prevSibling.nextSibling == this);\n\t\t\t\tprevSibling.nextSibling = newNode;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDebug.Assert(parent.firstChild == this);\n\t\t\t\tparent.firstChild = newNode;\n\t\t\t}\n\t\t\tif (nextSibling != null)\n\t\t\t{\n\t\t\t\tDebug.Assert(nextSibling.prevSibling == this);\n\t\t\t\tnextSibling.prevSibling = newNode;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDebug.Assert(parent.lastChild == this);\n\t\t\t\tparent.lastChild = newNode;\n\t\t\t}\n\t\t\tparent = null;\n\t\t\tprevSibling = null;\n\t\t\tnextSibling = null;\n\t\t}\n\n\t\tpublic AstNode? ReplaceWith(Func<AstNode, AstNode?> replaceFunction)\n\t\t{\n\t\t\tif (replaceFunction == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(replaceFunction));\n\t\t\tif (parent == null)\n\t\t\t{\n\t\t\t\tthrow new InvalidOperationException(this.IsNull ? \"Cannot replace the null nodes\" : \"Cannot replace the root node\");\n\t\t\t}\n\t\t\tAstNode oldParent = parent;\n\t\t\tAstNode? oldSuccessor = nextSibling;\n\t\t\tRole oldRole = this.Role;\n\t\t\tRemove();\n\t\t\tAstNode? replacement = replaceFunction(this);\n\t\t\tif (oldSuccessor != null && oldSuccessor.parent != oldParent)\n\t\t\t\tthrow new InvalidOperationException(\"replace function changed nextSibling of node being replaced?\");\n\t\t\tif (!(replacement == null || replacement.IsNull))\n\t\t\t{\n\t\t\t\tif (replacement.parent != null)\n\t\t\t\t\tthrow new InvalidOperationException(\"replace function must return the root of a tree\");\n\t\t\t\tif (!oldRole.IsValid(replacement))\n\t\t\t\t{\n\t\t\t\t\tthrow new InvalidOperationException(string.Format(\"The new node '{0}' is not valid in the role {1}\", replacement.GetType().Name, oldRole.ToString()));\n\t\t\t\t}\n\n\t\t\t\tif (oldSuccessor != null)\n\t\t\t\t\toldParent.InsertChildBeforeUnsafe(oldSuccessor, replacement, oldRole);\n\t\t\t\telse\n\t\t\t\t\toldParent.AddChildUnsafe(replacement, oldRole);\n\t\t\t}\n\t\t\treturn replacement;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Clones the whole subtree starting at this AST node.\n\t\t/// </summary>\n\t\t/// <remarks>Annotations are copied over to the new nodes; and any annotations implementing ICloneable will be cloned.</remarks>\n\t\tpublic AstNode Clone()\n\t\t{\n\t\t\tAstNode copy = (AstNode)MemberwiseClone();\n\t\t\t// First, reset the shallow pointer copies\n\t\t\tcopy.parent = null;\n\t\t\tcopy.firstChild = null;\n\t\t\tcopy.lastChild = null;\n\t\t\tcopy.prevSibling = null;\n\t\t\tcopy.nextSibling = null;\n\t\t\tcopy.flags &= ~frozenBit; // unfreeze the copy\n\n\t\t\t// Then perform a deep copy:\n\t\t\tfor (AstNode? cur = firstChild; cur != null; cur = cur.nextSibling)\n\t\t\t{\n\t\t\t\tcopy.AddChildUnsafe(cur.Clone(), cur.Role);\n\t\t\t}\n\n\t\t\t// Finally, clone the annotation, if necessary\n\t\t\tcopy.CloneAnnotations();\n\n\t\t\treturn copy;\n\t\t}\n\n\t\tobject ICloneable.Clone()\n\t\t{\n\t\t\treturn Clone();\n\t\t}\n\n\t\tpublic abstract void AcceptVisitor(IAstVisitor visitor);\n\n\t\tpublic abstract T AcceptVisitor<T>(IAstVisitor<T> visitor);\n\n\t\tpublic abstract S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data);\n\n\t\t#region Pattern Matching\n\t\tprotected static bool MatchString(string? pattern, string? text)\n\t\t{\n\t\t\treturn PatternMatching.Pattern.MatchString(pattern, text);\n\t\t}\n\n\t\tprotected internal abstract bool DoMatch(AstNode? other, PatternMatching.Match match);\n\n\t\tbool PatternMatching.INode.DoMatch(PatternMatching.INode? other, PatternMatching.Match match)\n\t\t{\n\t\t\tAstNode? o = other as AstNode;\n\t\t\t// try matching if other is null, or if other is an AstNode\n\t\t\treturn (other == null || o != null) && DoMatch(o, match);\n\t\t}\n\n\t\tbool PatternMatching.INode.DoMatchCollection(Role? role, PatternMatching.INode? pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo? backtrackingInfo)\n\t\t{\n\t\t\tAstNode? o = pos as AstNode;\n\t\t\treturn (pos == null || o != null) && DoMatch(o, match);\n\t\t}\n\n\t\tPatternMatching.INode? PatternMatching.INode.NextSibling {\n\t\t\tget { return nextSibling; }\n\t\t}\n\n\t\tPatternMatching.INode? PatternMatching.INode.FirstChild {\n\t\t\tget { return firstChild; }\n\t\t}\n\n\t\t#endregion\n\n\t\tpublic AstNode? GetNextNode()\n\t\t{\n\t\t\tif (NextSibling != null)\n\t\t\t\treturn NextSibling;\n\t\t\tif (Parent != null)\n\t\t\t\treturn Parent.GetNextNode();\n\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the next node which fullfills a given predicate\n\t\t/// </summary>\n\t\t/// <returns>The next node.</returns>\n\t\t/// <param name=\"pred\">The predicate.</param>\n\t\tpublic AstNode? GetNextNode(Func<AstNode, bool> pred)\n\t\t{\n\t\t\tvar next = GetNextNode();\n\t\t\twhile (next != null && !pred(next))\n\t\t\t\tnext = next.GetNextNode();\n\t\t\treturn next;\n\t\t}\n\n\t\tpublic AstNode? GetPrevNode()\n\t\t{\n\t\t\tif (PrevSibling != null)\n\t\t\t\treturn PrevSibling;\n\t\t\tif (Parent != null)\n\t\t\t\treturn Parent.GetPrevNode();\n\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the previous node which fullfills a given predicate\n\t\t/// </summary>\n\t\t/// <returns>The next node.</returns>\n\t\t/// <param name=\"pred\">The predicate.</param>\n\t\tpublic AstNode? GetPrevNode(Func<AstNode, bool> pred)\n\t\t{\n\t\t\tvar prev = GetPrevNode();\n\t\t\twhile (prev != null && !pred(prev))\n\t\t\t\tprev = prev.GetPrevNode();\n\t\t\treturn prev;\n\t\t}\n\t\t// filters all non c# nodes (comments, white spaces or pre processor directives)\n\t\tpublic AstNode? GetCSharpNodeBefore(AstNode node)\n\t\t{\n\t\t\tvar n = node.PrevSibling;\n\t\t\twhile (n != null)\n\t\t\t{\n\t\t\t\tif (n.Role != Roles.Comment)\n\t\t\t\t\treturn n;\n\t\t\t\tn = n.GetPrevNode();\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the next sibling which fullfills a given predicate\n\t\t/// </summary>\n\t\t/// <returns>The next node.</returns>\n\t\t/// <param name=\"pred\">The predicate.</param>\n\t\tpublic AstNode? GetNextSibling(Func<AstNode, bool> pred)\n\t\t{\n\t\t\tvar next = NextSibling;\n\t\t\twhile (next != null && !pred(next))\n\t\t\t\tnext = next.NextSibling;\n\t\t\treturn next;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the next sibling which fullfills a given predicate\n\t\t/// </summary>\n\t\t/// <returns>The next node.</returns>\n\t\t/// <param name=\"pred\">The predicate.</param>\n\t\tpublic AstNode? GetPrevSibling(Func<AstNode, bool> pred)\n\t\t{\n\t\t\tvar prev = PrevSibling;\n\t\t\twhile (prev != null && !pred(prev))\n\t\t\t\tprev = prev.PrevSibling;\n\t\t\treturn prev;\n\t\t}\n\n\t\t#region GetNodeAt\n\t\t/// <summary>\n\t\t/// Gets the node specified by T at the location line, column. This is useful for getting a specific node from the tree. For example searching\n\t\t/// the current method declaration.\n\t\t/// (End exclusive)\n\t\t/// </summary>\n\t\tpublic AstNode? GetNodeAt(int line, int column, Predicate<AstNode>? pred = null)\n\t\t{\n\t\t\treturn GetNodeAt(new TextLocation(line, column), pred);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the node specified by pred at location. This is useful for getting a specific node from the tree. For example searching\n\t\t/// the current method declaration.\n\t\t/// (End exclusive)\n\t\t/// </summary>\n\t\tpublic AstNode? GetNodeAt(TextLocation location, Predicate<AstNode>? pred = null)\n\t\t{\n\t\t\tAstNode? result = null;\n\t\t\tAstNode node = this;\n\t\t\twhile (node.LastChild != null)\n\t\t\t{\n\t\t\t\tvar child = node.LastChild;\n\t\t\t\twhile (child != null && child.StartLocation > location)\n\t\t\t\t\tchild = child.prevSibling;\n\t\t\t\tif (child != null && location < child.EndLocation)\n\t\t\t\t{\n\t\t\t\t\tif (pred == null || pred(child))\n\t\t\t\t\t\tresult = child;\n\t\t\t\t\tnode = child;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// found no better child node - therefore the parent is the right one.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the node specified by T at the location line, column. This is useful for getting a specific node from the tree. For example searching\n\t\t/// the current method declaration.\n\t\t/// (End exclusive)\n\t\t/// </summary>\n\t\tpublic T? GetNodeAt<T>(int line, int column) where T : AstNode\n\t\t{\n\t\t\treturn GetNodeAt<T>(new TextLocation(line, column));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the node specified by T at location. This is useful for getting a specific node from the tree. For example searching\n\t\t/// the current method declaration.\n\t\t/// (End exclusive)\n\t\t/// </summary>\n\t\tpublic T? GetNodeAt<T>(TextLocation location) where T : AstNode\n\t\t{\n\t\t\tT? result = null;\n\t\t\tAstNode node = this;\n\t\t\twhile (node.LastChild != null)\n\t\t\t{\n\t\t\t\tvar child = node.LastChild;\n\t\t\t\twhile (child != null && child.StartLocation > location)\n\t\t\t\t\tchild = child.prevSibling;\n\t\t\t\tif (child != null && location < child.EndLocation)\n\t\t\t\t{\n\t\t\t\t\tif (child is T)\n\t\t\t\t\t\tresult = (T)child;\n\t\t\t\t\tnode = child;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// found no better child node - therefore the parent is the right one.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\t#endregion\n\n\t\t#region GetAdjacentNodeAt\n\t\t/// <summary>\n\t\t/// Gets the node specified by pred at the location line, column. This is useful for getting a specific node from the tree. For example searching\n\t\t/// the current method declaration.\n\t\t/// (End inclusive)\n\t\t/// </summary>\n\t\tpublic AstNode? GetAdjacentNodeAt(int line, int column, Predicate<AstNode>? pred = null)\n\t\t{\n\t\t\treturn GetAdjacentNodeAt(new TextLocation(line, column), pred);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the node specified by pred at location. This is useful for getting a specific node from the tree. For example searching\n\t\t/// the current method declaration.\n\t\t/// (End inclusive)\n\t\t/// </summary>\n\t\tpublic AstNode? GetAdjacentNodeAt(TextLocation location, Predicate<AstNode>? pred = null)\n\t\t{\n\t\t\tAstNode? result = null;\n\t\t\tAstNode node = this;\n\t\t\twhile (node.LastChild != null)\n\t\t\t{\n\t\t\t\tvar child = node.LastChild;\n\t\t\t\twhile (child != null && child.StartLocation > location)\n\t\t\t\t\tchild = child.prevSibling;\n\t\t\t\tif (child != null && location <= child.EndLocation)\n\t\t\t\t{\n\t\t\t\t\tif (pred == null || pred(child))\n\t\t\t\t\t\tresult = child;\n\t\t\t\t\tnode = child;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// found no better child node - therefore the parent is the right one.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the node specified by T at the location line, column. This is useful for getting a specific node from the tree. For example searching\n\t\t/// the current method declaration.\n\t\t/// (End inclusive)\n\t\t/// </summary>\n\t\tpublic T? GetAdjacentNodeAt<T>(int line, int column) where T : AstNode\n\t\t{\n\t\t\treturn GetAdjacentNodeAt<T>(new TextLocation(line, column));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the node specified by T at location. This is useful for getting a specific node from the tree. For example searching\n\t\t/// the current method declaration.\n\t\t/// (End inclusive)\n\t\t/// </summary>\n\t\tpublic T? GetAdjacentNodeAt<T>(TextLocation location) where T : AstNode\n\t\t{\n\t\t\tT? result = null;\n\t\t\tAstNode node = this;\n\t\t\twhile (node.LastChild != null)\n\t\t\t{\n\t\t\t\tvar child = node.LastChild;\n\t\t\t\twhile (child != null && child.StartLocation > location)\n\t\t\t\t\tchild = child.prevSibling;\n\t\t\t\tif (child != null && location <= child.EndLocation)\n\t\t\t\t{\n\t\t\t\t\tif (child is T t)\n\t\t\t\t\t\tresult = t;\n\t\t\t\t\tnode = child;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// found no better child node - therefore the parent is the right one.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t\t#endregion\n\n\t\t/// <summary>\n\t\t/// Gets the node that fully contains the range from startLocation to endLocation.\n\t\t/// </summary>\n\t\tpublic AstNode GetNodeContaining(TextLocation startLocation, TextLocation endLocation)\n\t\t{\n\t\t\tfor (AstNode? child = firstChild; child != null; child = child.nextSibling)\n\t\t\t{\n\t\t\t\tif (child.StartLocation <= startLocation && endLocation <= child.EndLocation)\n\t\t\t\t\treturn child.GetNodeContaining(startLocation, endLocation);\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the root nodes of all subtrees that are fully contained in the specified region.\n\t\t/// </summary>\n\t\tpublic IEnumerable<AstNode> GetNodesBetween(int startLine, int startColumn, int endLine, int endColumn)\n\t\t{\n\t\t\treturn GetNodesBetween(new TextLocation(startLine, startColumn), new TextLocation(endLine, endColumn));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the root nodes of all subtrees that are fully contained between <paramref name=\"start\"/> and <paramref name=\"end\"/> (inclusive).\n\t\t/// </summary>\n\t\tpublic IEnumerable<AstNode> GetNodesBetween(TextLocation start, TextLocation end)\n\t\t{\n\t\t\tAstNode? node = this;\n\t\t\twhile (node != null)\n\t\t\t{\n\t\t\t\tAstNode? next;\n\t\t\t\tif (start <= node.StartLocation && node.EndLocation <= end)\n\t\t\t\t{\n\t\t\t\t\t// Remember next before yielding node.\n\t\t\t\t\t// This allows iteration to continue when the caller removes/replaces the node.\n\t\t\t\t\tnext = node.GetNextNode();\n\t\t\t\t\tyield return node;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (node.EndLocation <= start)\n\t\t\t\t\t{\n\t\t\t\t\t\tnext = node.GetNextNode();\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tnext = node.FirstChild;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (next != null && next.StartLocation > end)\n\t\t\t\t\tyield break;\n\t\t\t\tnode = next;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the node as formatted C# output.\n\t\t/// </summary>\n\t\t/// <param name='formattingOptions'>\n\t\t/// Formatting options.\n\t\t/// </param>\n\t\tpublic virtual string ToString(CSharpFormattingOptions? formattingOptions)\n\t\t{\n\t\t\tif (IsNull)\n\t\t\t\treturn \"\";\n\t\t\tvar w = new StringWriter();\n\t\t\tAcceptVisitor(new CSharpOutputVisitor(w, formattingOptions ?? FormattingOptionsFactory.CreateMono()));\n\t\t\treturn w.ToString();\n\t\t}\n\n\t\tpublic sealed override string ToString()\n\t\t{\n\t\t\treturn ToString(null);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns true, if the given coordinates (line, column) are in the node.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// True, if the given coordinates are between StartLocation and EndLocation (exclusive); otherwise, false.\n\t\t/// </returns>\n\t\tpublic bool Contains(int line, int column)\n\t\t{\n\t\t\treturn Contains(new TextLocation(line, column));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns true, if the given coordinates are in the node.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// True, if location is between StartLocation and EndLocation (exclusive); otherwise, false.\n\t\t/// </returns>\n\t\tpublic bool Contains(TextLocation location)\n\t\t{\n\t\t\treturn this.StartLocation <= location && location < this.EndLocation;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns true, if the given coordinates (line, column) are in the node.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// True, if the given coordinates are between StartLocation and EndLocation (inclusive); otherwise, false.\n\t\t/// </returns>\n\t\tpublic bool IsInside(int line, int column)\n\t\t{\n\t\t\treturn IsInside(new TextLocation(line, column));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns true, if the given coordinates are in the node.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// True, if location is between StartLocation and EndLocation (inclusive); otherwise, false.\n\t\t/// </returns>\n\t\tpublic bool IsInside(TextLocation location)\n\t\t{\n\t\t\treturn this.StartLocation <= location && location <= this.EndLocation;\n\t\t}\n\n\t\tpublic override void AddAnnotation(object annotation)\n\t\t{\n\t\t\tif (this.IsNull)\n\t\t\t\tthrow new InvalidOperationException(\"Cannot add annotations to the null node\");\n\t\t\tbase.AddAnnotation(annotation);\n\t\t}\n\n\t\tinternal string DebugToString()\n\t\t{\n\t\t\tif (IsNull)\n\t\t\t\treturn \"Null\";\n\t\t\tstring text = ToString();\n\t\t\ttext = text.TrimEnd().Replace(\"\\t\", \"\").Replace(Environment.NewLine, \" \");\n\t\t\tif (text.Length > 100)\n\t\t\t\treturn text.Substring(0, 97) + \"...\";\n\t\t\telse\n\t\t\t\treturn text;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/AstNodeCollection.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Represents the children of an AstNode that have a specific role.\n\t/// </summary>\n\tpublic class AstNodeCollection<T> : ICollection<T>, IReadOnlyCollection<T>\n\t\twhere T : AstNode\n\t{\n\t\treadonly AstNode node;\n\t\treadonly Role<T> role;\n\n\t\tpublic AstNodeCollection(AstNode node, Role<T> role)\n\t\t{\n\t\t\tif (node == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(node));\n\t\t\tif (role == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(role));\n\t\t\tthis.node = node;\n\t\t\tthis.role = role;\n\t\t}\n\n\t\tpublic int Count {\n\t\t\tget {\n\t\t\t\tint count = 0;\n\t\t\t\tuint roleIndex = role.Index;\n\t\t\t\tfor (AstNode cur = node.FirstChild; cur != null; cur = cur.NextSibling)\n\t\t\t\t{\n\t\t\t\t\tif (cur.RoleIndex == roleIndex)\n\t\t\t\t\t\tcount++;\n\t\t\t\t}\n\t\t\t\treturn count;\n\t\t\t}\n\t\t}\n\n\t\tpublic void Add(T element)\n\t\t{\n\t\t\tnode.AddChild(element, role);\n\t\t}\n\n\t\tpublic void AddRange(IEnumerable<T> nodes)\n\t\t{\n\t\t\t// Evaluate 'nodes' first, since it might change when we add the new children\n\t\t\t// Example: collection.AddRange(collection);\n\t\t\tif (nodes != null)\n\t\t\t{\n\t\t\t\tforeach (T node in nodes.ToList())\n\t\t\t\t\tAdd(node);\n\t\t\t}\n\t\t}\n\n\t\tpublic void AddRange(T[] nodes)\n\t\t{\n\t\t\t// Fast overload for arrays - we don't need to create a copy\n\t\t\tif (nodes != null)\n\t\t\t{\n\t\t\t\tforeach (T node in nodes)\n\t\t\t\t\tAdd(node);\n\t\t\t}\n\t\t}\n\n\t\tpublic void ReplaceWith(IEnumerable<T> nodes)\n\t\t{\n\t\t\t// Evaluate 'nodes' first, since it might change when we call Clear()\n\t\t\t// Example: collection.ReplaceWith(collection);\n\t\t\tif (nodes != null)\n\t\t\t\tnodes = nodes.ToList();\n\t\t\tClear();\n\t\t\tif (nodes != null)\n\t\t\t{\n\t\t\t\tforeach (T node in nodes)\n\t\t\t\t\tAdd(node);\n\t\t\t}\n\t\t}\n\n\t\tpublic void MoveTo(ICollection<T> targetCollection)\n\t\t{\n\t\t\tif (targetCollection == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(targetCollection));\n\t\t\tforeach (T node in this)\n\t\t\t{\n\t\t\t\tnode.Remove();\n\t\t\t\ttargetCollection.Add(node);\n\t\t\t}\n\t\t}\n\n\t\tpublic bool Contains(T element)\n\t\t{\n\t\t\treturn element != null && element.Parent == node && element.RoleIndex == role.Index;\n\t\t}\n\n\t\tpublic bool Remove(T element)\n\t\t{\n\t\t\tif (Contains(element))\n\t\t\t{\n\t\t\t\telement.Remove();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic void CopyTo(T[] array, int arrayIndex)\n\t\t{\n\t\t\tforeach (T item in this)\n\t\t\t\tarray[arrayIndex++] = item;\n\t\t}\n\n\t\tpublic void Clear()\n\t\t{\n\t\t\tforeach (T item in this)\n\t\t\t\titem.Remove();\n\t\t}\n\n\t\tpublic IEnumerable<T> Detach()\n\t\t{\n\t\t\tforeach (T item in this)\n\t\t\t\tyield return item.Detach();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the first element for which the predicate returns true,\n\t\t/// or the null node (AstNode with IsNull=true) if no such object is found.\n\t\t/// </summary>\n\t\tpublic T FirstOrNullObject(Func<T, bool> predicate = null)\n\t\t{\n\t\t\tforeach (T item in this)\n\t\t\t\tif (predicate == null || predicate(item))\n\t\t\t\t\treturn item;\n\t\t\treturn role.NullObject;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the last element for which the predicate returns true,\n\t\t/// or the null node (AstNode with IsNull=true) if no such object is found.\n\t\t/// </summary>\n\t\tpublic T LastOrNullObject(Func<T, bool> predicate = null)\n\t\t{\n\t\t\tT result = role.NullObject;\n\t\t\tforeach (T item in this)\n\t\t\t\tif (predicate == null || predicate(item))\n\t\t\t\t\tresult = item;\n\t\t\treturn result;\n\t\t}\n\n\t\tbool ICollection<T>.IsReadOnly {\n\t\t\tget { return false; }\n\t\t}\n\n\t\tpublic IEnumerator<T> GetEnumerator()\n\t\t{\n\t\t\tuint roleIndex = role.Index;\n\t\t\tAstNode next;\n\t\t\tfor (AstNode cur = node.FirstChild; cur != null; cur = next)\n\t\t\t{\n\t\t\t\tDebug.Assert(cur.Parent == node);\n\t\t\t\t// Remember next before yielding cur.\n\t\t\t\t// This allows removing/replacing nodes while iterating through the list.\n\t\t\t\tnext = cur.NextSibling;\n\t\t\t\tif (cur.RoleIndex == roleIndex)\n\t\t\t\t\tyield return (T)cur;\n\t\t\t}\n\t\t}\n\n\t\tIEnumerator IEnumerable.GetEnumerator()\n\t\t{\n\t\t\treturn GetEnumerator();\n\t\t}\n\n\t\t#region Equals and GetHashCode implementation\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn node.GetHashCode() ^ role.GetHashCode();\n\t\t}\n\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\tAstNodeCollection<T> other = obj as AstNodeCollection<T>;\n\t\t\tif (other == null)\n\t\t\t\treturn false;\n\t\t\treturn this.node == other.node && this.role == other.role;\n\t\t}\n\t\t#endregion\n\n\t\tinternal bool DoMatch(AstNodeCollection<T> other, Match match)\n\t\t{\n\t\t\treturn Pattern.DoMatchCollection(role, node.FirstChild, other.node.FirstChild, match);\n\t\t}\n\n\t\tpublic void InsertAfter(T existingItem, T newItem)\n\t\t{\n\t\t\tnode.InsertChildAfter(existingItem, newItem, role);\n\t\t}\n\n\t\tpublic void InsertBefore(T existingItem, T newItem)\n\t\t{\n\t\t\tnode.InsertChildBefore(existingItem, newItem, role);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Applies the <paramref name=\"visitor\"/> to all nodes in this collection.\n\t\t/// </summary>\n\t\tpublic void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tuint roleIndex = role.Index;\n\t\t\tAstNode next;\n\t\t\tfor (AstNode cur = node.FirstChild; cur != null; cur = next)\n\t\t\t{\n\t\t\t\tDebug.Assert(cur.Parent == node);\n\t\t\t\t// Remember next before yielding cur.\n\t\t\t\t// This allows removing/replacing nodes while iterating through the list.\n\t\t\t\tnext = cur.NextSibling;\n\t\t\t\tif (cur.RoleIndex == roleIndex)\n\t\t\t\t\tcur.AcceptVisitor(visitor);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/AstType.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.CSharp.Resolver;\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// A type reference in the C# AST.\n\t/// </summary>\n\tpublic abstract class AstType : AstNode\n\t{\n\t\t#region Null\n\t\tpublic new static readonly AstType Null = new NullAstType();\n\n\t\tsealed class NullAstType : AstType\n\t\t{\n\t\t\tpublic override bool IsNull {\n\t\t\t\tget {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn other == null || other.IsNull;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region PatternPlaceholder\n\t\tpublic static implicit operator AstType(PatternMatching.Pattern pattern)\n\t\t{\n\t\t\treturn pattern != null ? new PatternPlaceholder(pattern) : null;\n\t\t}\n\n\t\tsealed class PatternPlaceholder : AstType, INode\n\t\t{\n\t\t\treadonly PatternMatching.Pattern child;\n\n\t\t\tpublic PatternPlaceholder(PatternMatching.Pattern child)\n\t\t\t{\n\t\t\t\tthis.child = child;\n\t\t\t}\n\n\t\t\tpublic override NodeType NodeType {\n\t\t\t\tget { return NodeType.Pattern; }\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn child.DoMatch(other, match);\n\t\t\t}\n\n\t\t\tbool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)\n\t\t\t{\n\t\t\t\treturn child.DoMatchCollection(role, pos, match, backtrackingInfo);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget { return NodeType.TypeReference; }\n\t\t}\n\n\t\tpublic new AstType Clone()\n\t\t{\n\t\t\treturn (AstType)base.Clone();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this type is a SimpleType \"var\".\n\t\t/// </summary>\n\t\tpublic bool IsVar()\n\t\t{\n\t\t\tSimpleType st = this as SimpleType;\n\t\t\treturn st != null && st.Identifier == \"var\" && st.TypeArguments.Count == 0;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the name lookup mode from the context (looking at the ancestors of this <see cref=\"AstType\"/>).\n\t\t/// </summary>\n\t\tpublic NameLookupMode GetNameLookupMode()\n\t\t{\n\t\t\tAstType outermostType = this;\n\t\t\twhile (outermostType.Parent is AstType)\n\t\t\t\toutermostType = (AstType)outermostType.Parent;\n\n\t\t\tif (outermostType.Parent is UsingDeclaration || outermostType.Parent is UsingAliasDeclaration)\n\t\t\t{\n\t\t\t\treturn NameLookupMode.TypeInUsingDeclaration;\n\t\t\t}\n\t\t\telse if (outermostType.Role == Roles.BaseType)\n\t\t\t{\n\t\t\t\t// Use BaseTypeReference for a type's base type, and for a constraint on a type.\n\t\t\t\t// Do not use it for a constraint on a method.\n\t\t\t\tif (outermostType.Parent is TypeDeclaration || (outermostType.Parent is Constraint && outermostType.Parent.Parent is TypeDeclaration))\n\t\t\t\t\treturn NameLookupMode.BaseTypeReference;\n\t\t\t}\n\t\t\treturn NameLookupMode.Type;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a pointer type from this type by nesting it in a <see cref=\"ComposedType\"/>.\n\t\t/// If this type already is a pointer type, this method just increases the PointerRank of the existing pointer type.\n\t\t/// </summary>\n\t\tpublic virtual AstType MakePointerType()\n\t\t{\n\t\t\treturn new ComposedType { BaseType = this }.MakePointerType();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates an array type from this type by nesting it in a <see cref=\"ComposedType\"/>.\n\t\t/// If this type already is an array type, the additional rank is prepended to the existing array specifier list.\n\t\t/// Thus, <c>new SimpleType(\"T\").MakeArrayType(1).MakeArrayType(2)</c> will result in \"T[,][]\".\n\t\t/// </summary>\n\t\tpublic virtual AstType MakeArrayType(int rank = 1)\n\t\t{\n\t\t\treturn new ComposedType { BaseType = this }.MakeArrayType(rank);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a nullable type from this type by nesting it in a <see cref=\"ComposedType\"/>.\n\t\t/// </summary>\n\t\tpublic AstType MakeNullableType()\n\t\t{\n\t\t\treturn new ComposedType { BaseType = this, HasNullableSpecifier = true };\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a C# 7 ref type from this type by nesting it in a <see cref=\"ComposedType\"/>.\n\t\t/// </summary>\n\t\tpublic virtual AstType MakeRefType()\n\t\t{\n\t\t\treturn new ComposedType { BaseType = this, HasRefSpecifier = true };\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Builds an expression that can be used to access a static member on this type.\n\t\t/// </summary>\n\t\tpublic MemberType MemberType(string memberName, params AstType[] typeArguments)\n\t\t{\n\t\t\tvar memberType = new MemberType(this, memberName);\n\t\t\tmemberType.TypeArguments.AddRange(typeArguments);\n\t\t\treturn memberType;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Builds an expression that can be used to access a static member on this type.\n\t\t/// </summary>\n\t\tpublic MemberType MemberType(string memberName, IEnumerable<AstType> typeArguments)\n\t\t{\n\t\t\tvar memberType = new MemberType(this, memberName);\n\t\t\tmemberType.TypeArguments.AddRange(typeArguments);\n\t\t\treturn memberType;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a simple AstType from a dotted name.\n\t\t/// Does not support generics, arrays, etc. - just simple dotted names,\n\t\t/// e.g. namespace names.\n\t\t/// </summary>\n\t\tpublic static AstType Create(string dottedName)\n\t\t{\n\t\t\tstring[] parts = dottedName.Split('.');\n\t\t\tAstType type = new SimpleType(parts[0]);\n\t\t\tfor (int i = 1; i < parts.Length; i++)\n\t\t\t{\n\t\t\t\ttype = new MemberType(type, parts[i]);\n\t\t\t}\n\t\t\treturn type;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/CSharpModifierToken.cs",
    "content": "// \n// CSharpModifierToken.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System;\nusing System.Collections.Immutable;\n\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class CSharpModifierToken : CSharpTokenNode\n\t{\n\t\tModifiers modifier;\n\n\t\tpublic Modifiers Modifier {\n\t\t\tget { return modifier; }\n\t\t\tset {\n\t\t\t\tThrowIfFrozen();\n\t\t\t\tthis.modifier = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic override TextLocation EndLocation {\n\t\t\tget {\n\t\t\t\treturn new TextLocation(StartLocation.Line, StartLocation.Column + GetModifierLength(Modifier));\n\t\t\t}\n\t\t}\n\n\t\tpublic override string ToString(CSharpFormattingOptions formattingOptions)\n\t\t{\n\t\t\treturn GetModifierName(Modifier);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tCSharpModifierToken o = other as CSharpModifierToken;\n\t\t\treturn o != null && this.modifier == o.modifier;\n\t\t}\n\n\t\t// Not worth using a dictionary for such few elements.\n\t\t// This table is sorted in the order that modifiers should be output when generating code.\n\t\tpublic static ImmutableArray<Modifiers> AllModifiers { get; } = ImmutableArray.Create(\n\t\t\tModifiers.Public, Modifiers.Private, Modifiers.Protected, Modifiers.Internal,\n\t\t\tModifiers.New,\n\t\t\tModifiers.Unsafe,\n\t\t\tModifiers.Static, Modifiers.Abstract, Modifiers.Virtual, Modifiers.Sealed, Modifiers.Override,\n\t\t\tModifiers.Required, Modifiers.Readonly, Modifiers.Volatile,\n\t\t\tModifiers.Ref,\n\t\t\tModifiers.Extern, Modifiers.Partial, Modifiers.Const,\n\t\t\tModifiers.Async,\n\t\t\tModifiers.Any\n\t\t);\n\n\t\tpublic CSharpModifierToken(TextLocation location, Modifiers modifier) : base(location, null)\n\t\t{\n\t\t\tthis.Modifier = modifier;\n\t\t}\n\n\t\tpublic static string GetModifierName(Modifiers modifier)\n\t\t{\n\t\t\tswitch (modifier)\n\t\t\t{\n\t\t\t\tcase Modifiers.Private:\n\t\t\t\t\treturn \"private\";\n\t\t\t\tcase Modifiers.Internal:\n\t\t\t\t\treturn \"internal\";\n\t\t\t\tcase Modifiers.Protected:\n\t\t\t\t\treturn \"protected\";\n\t\t\t\tcase Modifiers.Public:\n\t\t\t\t\treturn \"public\";\n\t\t\t\tcase Modifiers.Abstract:\n\t\t\t\t\treturn \"abstract\";\n\t\t\t\tcase Modifiers.Virtual:\n\t\t\t\t\treturn \"virtual\";\n\t\t\t\tcase Modifiers.Sealed:\n\t\t\t\t\treturn \"sealed\";\n\t\t\t\tcase Modifiers.Static:\n\t\t\t\t\treturn \"static\";\n\t\t\t\tcase Modifiers.Override:\n\t\t\t\t\treturn \"override\";\n\t\t\t\tcase Modifiers.Readonly:\n\t\t\t\t\treturn \"readonly\";\n\t\t\t\tcase Modifiers.Const:\n\t\t\t\t\treturn \"const\";\n\t\t\t\tcase Modifiers.New:\n\t\t\t\t\treturn \"new\";\n\t\t\t\tcase Modifiers.Partial:\n\t\t\t\t\treturn \"partial\";\n\t\t\t\tcase Modifiers.Extern:\n\t\t\t\t\treturn \"extern\";\n\t\t\t\tcase Modifiers.Volatile:\n\t\t\t\t\treturn \"volatile\";\n\t\t\t\tcase Modifiers.Unsafe:\n\t\t\t\t\treturn \"unsafe\";\n\t\t\t\tcase Modifiers.Async:\n\t\t\t\t\treturn \"async\";\n\t\t\t\tcase Modifiers.Ref:\n\t\t\t\t\treturn \"ref\";\n\t\t\t\tcase Modifiers.Required:\n\t\t\t\t\treturn \"required\";\n\t\t\t\tcase Modifiers.Any:\n\t\t\t\t\t// even though it's used for pattern matching only, 'any' needs to be in this list to be usable in the AST\n\t\t\t\t\treturn \"any\";\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException(\"Invalid value for Modifiers\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static int GetModifierLength(Modifiers modifier)\n\t\t{\n\t\t\treturn GetModifierName(modifier).Length;\n\t\t}\n\n\t\tpublic static Modifiers GetModifierValue(string modifier)\n\t\t{\n\t\t\tswitch (modifier)\n\t\t\t{\n\t\t\t\tcase \"private\":\n\t\t\t\t\treturn Modifiers.Private;\n\t\t\t\tcase \"internal\":\n\t\t\t\t\treturn Modifiers.Internal;\n\t\t\t\tcase \"protected\":\n\t\t\t\t\treturn Modifiers.Protected;\n\t\t\t\tcase \"public\":\n\t\t\t\t\treturn Modifiers.Public;\n\t\t\t\tcase \"abstract\":\n\t\t\t\t\treturn Modifiers.Abstract;\n\t\t\t\tcase \"virtual\":\n\t\t\t\t\treturn Modifiers.Virtual;\n\t\t\t\tcase \"sealed\":\n\t\t\t\t\treturn Modifiers.Sealed;\n\t\t\t\tcase \"static\":\n\t\t\t\t\treturn Modifiers.Static;\n\t\t\t\tcase \"override\":\n\t\t\t\t\treturn Modifiers.Override;\n\t\t\t\tcase \"readonly\":\n\t\t\t\t\treturn Modifiers.Readonly;\n\t\t\t\tcase \"const\":\n\t\t\t\t\treturn Modifiers.Const;\n\t\t\t\tcase \"new\":\n\t\t\t\t\treturn Modifiers.New;\n\t\t\t\tcase \"partial\":\n\t\t\t\t\treturn Modifiers.Partial;\n\t\t\t\tcase \"extern\":\n\t\t\t\t\treturn Modifiers.Extern;\n\t\t\t\tcase \"volatile\":\n\t\t\t\t\treturn Modifiers.Volatile;\n\t\t\t\tcase \"unsafe\":\n\t\t\t\t\treturn Modifiers.Unsafe;\n\t\t\t\tcase \"async\":\n\t\t\t\t\treturn Modifiers.Async;\n\t\t\t\tcase \"ref\":\n\t\t\t\t\treturn Modifiers.Ref;\n\t\t\t\tcase \"required\":\n\t\t\t\t\treturn Modifiers.Required;\n\t\t\t\tcase \"any\":\n\t\t\t\t\t// even though it's used for pattern matching only, 'any' needs to be in this list to be usable in the AST\n\t\t\t\t\treturn Modifiers.Any;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException(\"Invalid value for Modifiers\");\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/CSharpTokenNode.cs",
    "content": "// \n// TokenNode.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Represents a token in C#. Note that the type of the token is defined through the TokenRole.\n\t/// </summary>\n\t/// <remarks>\n\t/// In all non null c# token nodes the Role of a CSharpToken must be a TokenRole.\n\t/// </remarks>\n\tpublic class CSharpTokenNode : AstNode\n\t{\n\t\tpublic static new readonly CSharpTokenNode Null = new NullCSharpTokenNode();\n\t\tclass NullCSharpTokenNode : CSharpTokenNode\n\t\t{\n\t\t\tpublic override bool IsNull {\n\t\t\t\tget {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic NullCSharpTokenNode() : base(TextLocation.Empty, null)\n\t\t\t{\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn other == null || other.IsNull;\n\t\t\t}\n\t\t}\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget {\n\t\t\t\treturn NodeType.Token;\n\t\t\t}\n\t\t}\n\n\t\tTextLocation startLocation;\n\t\tpublic override TextLocation StartLocation {\n\t\t\tget {\n\t\t\t\treturn startLocation;\n\t\t\t}\n\t\t}\n\n\t\tint TokenLength {\n\t\t\tget {\n\t\t\t\tuint tokenRoleIndex = (this.flags >> AstNodeFlagsUsedBits);\n\t\t\t\tif (Role.GetByIndex(tokenRoleIndex) is TokenRole r)\n\t\t\t\t{\n\t\t\t\t\treturn r.Length;\n\t\t\t\t}\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\n\t\tpublic override TextLocation EndLocation {\n\t\t\tget {\n\t\t\t\treturn new TextLocation(StartLocation.Line, StartLocation.Column + TokenLength);\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode(TextLocation location, TokenRole role)\n\t\t{\n\t\t\tthis.startLocation = location;\n\t\t\tif (role != null)\n\t\t\t\tthis.flags |= role.Index << AstNodeFlagsUsedBits;\n\t\t}\n\n\t\tpublic override string ToString(CSharpFormattingOptions formattingOptions)\n\t\t{\n\t\t\tuint tokenRoleIndex = (this.flags >> AstNodeFlagsUsedBits);\n\t\t\tif (Role.GetByIndex(tokenRoleIndex) is TokenRole r)\n\t\t\t{\n\t\t\t\treturn r.Token;\n\t\t\t}\n\t\t\treturn string.Empty;\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitCSharpTokenNode(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitCSharpTokenNode(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitCSharpTokenNode(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tCSharpTokenNode o = other as CSharpTokenNode;\n\t\t\treturn o != null && !o.IsNull && !(o is CSharpModifierToken);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/ComposedType.cs",
    "content": "// \n// ComposedType.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System;\nusing System.Linq;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class ComposedType : AstType\n\t{\n\t\tpublic static readonly Role<AttributeSection> AttributeRole = EntityDeclaration.AttributeRole;\n\t\tpublic static readonly TokenRole RefRole = new TokenRole(\"ref\");\n\t\tpublic static readonly TokenRole ReadonlyRole = new TokenRole(\"readonly\");\n\t\tpublic static readonly TokenRole NullableRole = new TokenRole(\"?\");\n\t\tpublic static readonly TokenRole PointerRole = new TokenRole(\"*\");\n\t\tpublic static readonly Role<ArraySpecifier> ArraySpecifierRole = new Role<ArraySpecifier>(\"ArraySpecifier\", null);\n\t\tpublic AstNodeCollection<AttributeSection> Attributes {\n\t\t\tget { return base.GetChildrenByRole(AttributeRole); }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets/sets whether this type has a 'ref' specifier.\n\t\t/// This is used for C# 7 ref locals/ref return.\n\t\t/// Parameters use ParameterDeclaration.ParameterModifier instead.\n\t\t/// </summary>\n\t\tpublic bool HasRefSpecifier {\n\t\t\tget {\n\t\t\t\treturn !GetChildByRole(RefRole).IsNull;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(RefRole, value ? new CSharpTokenNode(TextLocation.Empty, null) : null);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets/sets whether this type has a 'readonly' specifier.\n\t\t/// This is used for C# 7.2 'ref readonly' locals/ref return.\n\t\t/// Parameters use ParameterDeclaration.ParameterModifier instead.\n\t\t/// </summary>\n\t\tpublic bool HasReadOnlySpecifier {\n\t\t\tget {\n\t\t\t\treturn !GetChildByRole(ReadonlyRole).IsNull;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(ReadonlyRole, value ? new CSharpTokenNode(TextLocation.Empty, null) : null);\n\t\t\t}\n\t\t}\n\n\t\tpublic AstType BaseType {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic bool HasNullableSpecifier {\n\t\t\tget {\n\t\t\t\treturn !GetChildByRole(NullableRole).IsNull;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(NullableRole, value ? new CSharpTokenNode(TextLocation.Empty, null) : null);\n\t\t\t}\n\t\t}\n\n\t\tpublic bool HasOnlyNullableSpecifier {\n\t\t\tget {\n\t\t\t\treturn HasNullableSpecifier && !HasRefSpecifier && !HasReadOnlySpecifier && PointerRank == 0 && ArraySpecifiers.Count == 0;\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode NullableSpecifierToken {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(NullableRole);\n\t\t\t}\n\t\t}\n\n\t\tpublic int PointerRank {\n\t\t\tget {\n\t\t\t\treturn GetChildrenByRole(PointerRole).Count;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tif (value < 0)\n\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t\tint d = this.PointerRank;\n\t\t\t\twhile (d > value)\n\t\t\t\t{\n\t\t\t\t\tGetChildByRole(PointerRole).Remove();\n\t\t\t\t\td--;\n\t\t\t\t}\n\t\t\t\twhile (d < value)\n\t\t\t\t{\n\t\t\t\t\tInsertChildBefore(GetChildByRole(PointerRole), new CSharpTokenNode(TextLocation.Empty, PointerRole), PointerRole);\n\t\t\t\t\td++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic AstNodeCollection<ArraySpecifier> ArraySpecifiers {\n\t\t\tget { return GetChildrenByRole(ArraySpecifierRole); }\n\t\t}\n\n\t\tpublic AstNodeCollection<CSharpTokenNode> PointerTokens {\n\t\t\tget { return GetChildrenByRole(PointerRole); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitComposedType(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitComposedType(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitComposedType(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tComposedType o = other as ComposedType;\n\t\t\treturn o != null\n\t\t\t\t&& this.HasNullableSpecifier == o.HasNullableSpecifier\n\t\t\t\t&& this.PointerRank == o.PointerRank\n\t\t\t\t&& this.HasRefSpecifier == o.HasRefSpecifier\n\t\t\t\t&& this.HasReadOnlySpecifier == o.HasReadOnlySpecifier\n\t\t\t\t&& this.BaseType.DoMatch(o.BaseType, match)\n\t\t\t\t&& this.ArraySpecifiers.DoMatch(o.ArraySpecifiers, match);\n\t\t}\n\n\t\tpublic override string ToString(CSharpFormattingOptions formattingOptions)\n\t\t{\n\t\t\tStringBuilder b = new StringBuilder();\n\t\t\tif (this.HasRefSpecifier)\n\t\t\t\tb.Append(\"ref \");\n\t\t\tif (this.HasReadOnlySpecifier)\n\t\t\t\tb.Append(\"readonly \");\n\t\t\tb.Append(this.BaseType.ToString());\n\t\t\tif (this.HasNullableSpecifier)\n\t\t\t\tb.Append('?');\n\t\t\tb.Append('*', this.PointerRank);\n\t\t\tforeach (var arraySpecifier in this.ArraySpecifiers)\n\t\t\t{\n\t\t\t\tb.Append('[');\n\t\t\t\tb.Append(',', arraySpecifier.Dimensions - 1);\n\t\t\t\tb.Append(']');\n\t\t\t}\n\t\t\treturn b.ToString();\n\t\t}\n\n\t\tpublic override AstType MakePointerType()\n\t\t{\n\t\t\tif (ArraySpecifiers.Any())\n\t\t\t{\n\t\t\t\treturn base.MakePointerType();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.PointerRank++;\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}\n\n\t\tpublic override AstType MakeArrayType(int dimensions)\n\t\t{\n\t\t\tInsertChildBefore(this.ArraySpecifiers.FirstOrDefault(), new ArraySpecifier(dimensions), ArraySpecifierRole);\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic override AstType MakeRefType()\n\t\t{\n\t\t\tthis.HasRefSpecifier = true;\n\t\t\treturn this;\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// [,,,]\n\t/// </summary>\n\tpublic class ArraySpecifier : AstNode\n\t{\n\t\tpublic override NodeType NodeType {\n\t\t\tget {\n\t\t\t\treturn NodeType.Unknown;\n\t\t\t}\n\t\t}\n\n\t\tpublic ArraySpecifier()\n\t\t{\n\t\t}\n\n\t\tpublic ArraySpecifier(int dimensions)\n\t\t{\n\t\t\tthis.Dimensions = dimensions;\n\t\t}\n\n\t\tpublic CSharpTokenNode LBracketToken {\n\t\t\tget { return GetChildByRole(Roles.LBracket); }\n\t\t}\n\n\t\tpublic int Dimensions {\n\t\t\tget { return 1 + GetChildrenByRole(Roles.Comma).Count; }\n\t\t\tset {\n\t\t\t\tint d = this.Dimensions;\n\t\t\t\twhile (d > value)\n\t\t\t\t{\n\t\t\t\t\tGetChildByRole(Roles.Comma).Remove();\n\t\t\t\t\td--;\n\t\t\t\t}\n\t\t\t\twhile (d < value)\n\t\t\t\t{\n\t\t\t\t\tInsertChildBefore(GetChildByRole(Roles.Comma), new CSharpTokenNode(TextLocation.Empty, Roles.Comma), Roles.Comma);\n\t\t\t\t\td++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode RBracketToken {\n\t\t\tget { return GetChildByRole(Roles.RBracket); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitArraySpecifier(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitArraySpecifier(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitArraySpecifier(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tArraySpecifier o = other as ArraySpecifier;\n\t\t\treturn o != null && this.Dimensions == o.Dimensions;\n\t\t}\n\n\t\tpublic override string ToString(CSharpFormattingOptions formattingOptions)\n\t\t{\n\t\t\treturn \"[\" + new string(',', this.Dimensions - 1) + \"]\";\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/DepthFirstAstVisitor.cs",
    "content": "// \n// IAstVisitor.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// AST visitor with a default implementation that visits all node depth-first.\n\t/// </summary>\n\tpublic abstract class DepthFirstAstVisitor : IAstVisitor\n\t{\n\t\tprotected virtual void VisitChildren(AstNode node)\n\t\t{\n\t\t\tAstNode next;\n\t\t\tfor (var child = node.FirstChild; child != null; child = next)\n\t\t\t{\n\t\t\t\t// Store next to allow the loop to continue\n\t\t\t\t// if the visitor removes/replaces child.\n\t\t\t\tnext = child.NextSibling;\n\t\t\t\tchild.AcceptVisitor(this);\n\t\t\t}\n\t\t}\n\n\t\tpublic virtual void VisitNullNode(AstNode nullNode)\n\t\t{\n\t\t\t// Should we call VisitChildren here?\n\t\t\t// We usually want to ignore null nodes.\n\t\t\t// Older NR versions (before VisitNullNode was introduced) didn't call VisitChildren() with null nodes;\n\t\t\t// so changing this might break VisitChildren() overrides that expect the node to be part of the AST.\n\t\t}\n\n\t\tpublic virtual void VisitSyntaxTree(SyntaxTree syntaxTree)\n\t\t{\n\t\t\tVisitChildren(syntaxTree);\n\t\t}\n\n\t\tpublic virtual void VisitComment(Comment comment)\n\t\t{\n\t\t\tVisitChildren(comment);\n\t\t}\n\n\t\tpublic virtual void VisitDocumentationReference(DocumentationReference documentationReference)\n\t\t{\n\t\t\tVisitChildren(documentationReference);\n\t\t}\n\n\t\tpublic virtual void VisitPreProcessorDirective(PreProcessorDirective preProcessorDirective)\n\t\t{\n\t\t\tVisitChildren(preProcessorDirective);\n\t\t}\n\n\t\tpublic virtual void VisitIdentifier(Identifier identifier)\n\t\t{\n\t\t\tVisitChildren(identifier);\n\t\t}\n\n\t\tpublic virtual void VisitCSharpTokenNode(CSharpTokenNode token)\n\t\t{\n\t\t\tVisitChildren(token);\n\t\t}\n\n\t\tpublic virtual void VisitPrimitiveType(PrimitiveType primitiveType)\n\t\t{\n\t\t\tVisitChildren(primitiveType);\n\t\t}\n\n\t\tpublic virtual void VisitComposedType(ComposedType composedType)\n\t\t{\n\t\t\tVisitChildren(composedType);\n\t\t}\n\n\t\tpublic virtual void VisitSimpleType(SimpleType simpleType)\n\t\t{\n\t\t\tVisitChildren(simpleType);\n\t\t}\n\n\t\tpublic virtual void VisitMemberType(MemberType memberType)\n\t\t{\n\t\t\tVisitChildren(memberType);\n\t\t}\n\n\t\tpublic virtual void VisitTupleType(TupleAstType tupleType)\n\t\t{\n\t\t\tVisitChildren(tupleType);\n\t\t}\n\n\t\tpublic virtual void VisitTupleTypeElement(TupleTypeElement tupleTypeElement)\n\t\t{\n\t\t\tVisitChildren(tupleTypeElement);\n\t\t}\n\n\t\tpublic virtual void VisitFunctionPointerType(FunctionPointerAstType functionPointerType)\n\t\t{\n\t\t\tVisitChildren(functionPointerType);\n\t\t}\n\n\t\tpublic virtual void VisitInvocationType(InvocationAstType invocationType)\n\t\t{\n\t\t\tVisitChildren(invocationType);\n\t\t}\n\n\t\tpublic virtual void VisitAttribute(Attribute attribute)\n\t\t{\n\t\t\tVisitChildren(attribute);\n\t\t}\n\n\t\tpublic virtual void VisitAttributeSection(AttributeSection attributeSection)\n\t\t{\n\t\t\tVisitChildren(attributeSection);\n\t\t}\n\n\t\tpublic virtual void VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration)\n\t\t{\n\t\t\tVisitChildren(delegateDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)\n\t\t{\n\t\t\tVisitChildren(namespaceDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitTypeDeclaration(TypeDeclaration typeDeclaration)\n\t\t{\n\t\t\tVisitChildren(typeDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration)\n\t\t{\n\t\t\tVisitChildren(typeParameterDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration)\n\t\t{\n\t\t\tVisitChildren(enumMemberDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitExtensionDeclaration(ExtensionDeclaration extensionDeclaration)\n\t\t{\n\t\t\tVisitChildren(extensionDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitUsingDeclaration(UsingDeclaration usingDeclaration)\n\t\t{\n\t\t\tVisitChildren(usingDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitUsingAliasDeclaration(UsingAliasDeclaration usingDeclaration)\n\t\t{\n\t\t\tVisitChildren(usingDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitExternAliasDeclaration(ExternAliasDeclaration externAliasDeclaration)\n\t\t{\n\t\t\tVisitChildren(externAliasDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)\n\t\t{\n\t\t\tVisitChildren(constructorDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitConstructorInitializer(ConstructorInitializer constructorInitializer)\n\t\t{\n\t\t\tVisitChildren(constructorInitializer);\n\t\t}\n\n\t\tpublic virtual void VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration)\n\t\t{\n\t\t\tVisitChildren(destructorDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitEventDeclaration(EventDeclaration eventDeclaration)\n\t\t{\n\t\t\tVisitChildren(eventDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitCustomEventDeclaration(CustomEventDeclaration eventDeclaration)\n\t\t{\n\t\t\tVisitChildren(eventDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitFieldDeclaration(FieldDeclaration fieldDeclaration)\n\t\t{\n\t\t\tVisitChildren(fieldDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration)\n\t\t{\n\t\t\tVisitChildren(fixedFieldDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer)\n\t\t{\n\t\t\tVisitChildren(fixedVariableInitializer);\n\t\t}\n\n\t\tpublic virtual void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration)\n\t\t{\n\t\t\tVisitChildren(indexerDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitMethodDeclaration(MethodDeclaration methodDeclaration)\n\t\t{\n\t\t\tVisitChildren(methodDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration)\n\t\t{\n\t\t\tVisitChildren(operatorDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)\n\t\t{\n\t\t\tVisitChildren(propertyDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitAccessor(Accessor accessor)\n\t\t{\n\t\t\tVisitChildren(accessor);\n\t\t}\n\n\t\tpublic virtual void VisitVariableInitializer(VariableInitializer variableInitializer)\n\t\t{\n\t\t\tVisitChildren(variableInitializer);\n\t\t}\n\n\t\tpublic virtual void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration)\n\t\t{\n\t\t\tVisitChildren(parameterDeclaration);\n\t\t}\n\n\t\tpublic virtual void VisitConstraint(Constraint constraint)\n\t\t{\n\t\t\tVisitChildren(constraint);\n\t\t}\n\n\t\tpublic virtual void VisitBlockStatement(BlockStatement blockStatement)\n\t\t{\n\t\t\tVisitChildren(blockStatement);\n\t\t}\n\n\t\tpublic virtual void VisitExpressionStatement(ExpressionStatement expressionStatement)\n\t\t{\n\t\t\tVisitChildren(expressionStatement);\n\t\t}\n\n\t\tpublic virtual void VisitBreakStatement(BreakStatement breakStatement)\n\t\t{\n\t\t\tVisitChildren(breakStatement);\n\t\t}\n\n\t\tpublic virtual void VisitCheckedStatement(CheckedStatement checkedStatement)\n\t\t{\n\t\t\tVisitChildren(checkedStatement);\n\t\t}\n\n\t\tpublic virtual void VisitContinueStatement(ContinueStatement continueStatement)\n\t\t{\n\t\t\tVisitChildren(continueStatement);\n\t\t}\n\n\t\tpublic virtual void VisitDoWhileStatement(DoWhileStatement doWhileStatement)\n\t\t{\n\t\t\tVisitChildren(doWhileStatement);\n\t\t}\n\n\t\tpublic virtual void VisitEmptyStatement(EmptyStatement emptyStatement)\n\t\t{\n\t\t\tVisitChildren(emptyStatement);\n\t\t}\n\n\t\tpublic virtual void VisitFixedStatement(FixedStatement fixedStatement)\n\t\t{\n\t\t\tVisitChildren(fixedStatement);\n\t\t}\n\n\t\tpublic virtual void VisitForeachStatement(ForeachStatement foreachStatement)\n\t\t{\n\t\t\tVisitChildren(foreachStatement);\n\t\t}\n\n\t\tpublic virtual void VisitForStatement(ForStatement forStatement)\n\t\t{\n\t\t\tVisitChildren(forStatement);\n\t\t}\n\n\t\tpublic virtual void VisitGotoCaseStatement(GotoCaseStatement gotoCaseStatement)\n\t\t{\n\t\t\tVisitChildren(gotoCaseStatement);\n\t\t}\n\n\t\tpublic virtual void VisitGotoDefaultStatement(GotoDefaultStatement gotoDefaultStatement)\n\t\t{\n\t\t\tVisitChildren(gotoDefaultStatement);\n\t\t}\n\n\t\tpublic virtual void VisitGotoStatement(GotoStatement gotoStatement)\n\t\t{\n\t\t\tVisitChildren(gotoStatement);\n\t\t}\n\n\t\tpublic virtual void VisitIfElseStatement(IfElseStatement ifElseStatement)\n\t\t{\n\t\t\tVisitChildren(ifElseStatement);\n\t\t}\n\n\t\tpublic virtual void VisitLabelStatement(LabelStatement labelStatement)\n\t\t{\n\t\t\tVisitChildren(labelStatement);\n\t\t}\n\n\t\tpublic virtual void VisitLockStatement(LockStatement lockStatement)\n\t\t{\n\t\t\tVisitChildren(lockStatement);\n\t\t}\n\n\t\tpublic virtual void VisitReturnStatement(ReturnStatement returnStatement)\n\t\t{\n\t\t\tVisitChildren(returnStatement);\n\t\t}\n\n\t\tpublic virtual void VisitSwitchStatement(SwitchStatement switchStatement)\n\t\t{\n\t\t\tVisitChildren(switchStatement);\n\t\t}\n\n\t\tpublic virtual void VisitSwitchSection(SwitchSection switchSection)\n\t\t{\n\t\t\tVisitChildren(switchSection);\n\t\t}\n\n\t\tpublic virtual void VisitCaseLabel(CaseLabel caseLabel)\n\t\t{\n\t\t\tVisitChildren(caseLabel);\n\t\t}\n\n\t\tpublic virtual void VisitSwitchExpression(SwitchExpression switchExpression)\n\t\t{\n\t\t\tVisitChildren(switchExpression);\n\t\t}\n\n\t\tpublic virtual void VisitSwitchExpressionSection(SwitchExpressionSection switchExpressionSection)\n\t\t{\n\t\t\tVisitChildren(switchExpressionSection);\n\t\t}\n\n\t\tpublic virtual void VisitThrowStatement(ThrowStatement throwStatement)\n\t\t{\n\t\t\tVisitChildren(throwStatement);\n\t\t}\n\n\t\tpublic virtual void VisitTryCatchStatement(TryCatchStatement tryCatchStatement)\n\t\t{\n\t\t\tVisitChildren(tryCatchStatement);\n\t\t}\n\n\t\tpublic virtual void VisitCatchClause(CatchClause catchClause)\n\t\t{\n\t\t\tVisitChildren(catchClause);\n\t\t}\n\n\t\tpublic virtual void VisitUncheckedStatement(UncheckedStatement uncheckedStatement)\n\t\t{\n\t\t\tVisitChildren(uncheckedStatement);\n\t\t}\n\n\t\tpublic virtual void VisitUnsafeStatement(UnsafeStatement unsafeStatement)\n\t\t{\n\t\t\tVisitChildren(unsafeStatement);\n\t\t}\n\n\t\tpublic virtual void VisitUsingStatement(UsingStatement usingStatement)\n\t\t{\n\t\t\tVisitChildren(usingStatement);\n\t\t}\n\n\t\tpublic virtual void VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement)\n\t\t{\n\t\t\tVisitChildren(variableDeclarationStatement);\n\t\t}\n\n\t\tpublic virtual void VisitLocalFunctionDeclarationStatement(LocalFunctionDeclarationStatement localFunctionDeclarationStatement)\n\t\t{\n\t\t\tVisitChildren(localFunctionDeclarationStatement);\n\t\t}\n\n\t\tpublic virtual void VisitWhileStatement(WhileStatement whileStatement)\n\t\t{\n\t\t\tVisitChildren(whileStatement);\n\t\t}\n\n\t\tpublic virtual void VisitYieldBreakStatement(YieldBreakStatement yieldBreakStatement)\n\t\t{\n\t\t\tVisitChildren(yieldBreakStatement);\n\t\t}\n\n\t\tpublic virtual void VisitYieldReturnStatement(YieldReturnStatement yieldReturnStatement)\n\t\t{\n\t\t\tVisitChildren(yieldReturnStatement);\n\t\t}\n\n\t\tpublic virtual void VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression)\n\t\t{\n\t\t\tVisitChildren(anonymousMethodExpression);\n\t\t}\n\n\t\tpublic virtual void VisitLambdaExpression(LambdaExpression lambdaExpression)\n\t\t{\n\t\t\tVisitChildren(lambdaExpression);\n\t\t}\n\n\t\tpublic virtual void VisitAssignmentExpression(AssignmentExpression assignmentExpression)\n\t\t{\n\t\t\tVisitChildren(assignmentExpression);\n\t\t}\n\n\t\tpublic virtual void VisitBaseReferenceExpression(BaseReferenceExpression baseReferenceExpression)\n\t\t{\n\t\t\tVisitChildren(baseReferenceExpression);\n\t\t}\n\n\t\tpublic virtual void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)\n\t\t{\n\t\t\tVisitChildren(binaryOperatorExpression);\n\t\t}\n\n\t\tpublic virtual void VisitCastExpression(CastExpression castExpression)\n\t\t{\n\t\t\tVisitChildren(castExpression);\n\t\t}\n\n\t\tpublic virtual void VisitCheckedExpression(CheckedExpression checkedExpression)\n\t\t{\n\t\t\tVisitChildren(checkedExpression);\n\t\t}\n\n\t\tpublic virtual void VisitConditionalExpression(ConditionalExpression conditionalExpression)\n\t\t{\n\t\t\tVisitChildren(conditionalExpression);\n\t\t}\n\n\t\tpublic virtual void VisitIdentifierExpression(IdentifierExpression identifierExpression)\n\t\t{\n\t\t\tVisitChildren(identifierExpression);\n\t\t}\n\n\t\tpublic virtual void VisitIndexerExpression(IndexerExpression indexerExpression)\n\t\t{\n\t\t\tVisitChildren(indexerExpression);\n\t\t}\n\n\t\tpublic virtual void VisitInterpolatedStringExpression(InterpolatedStringExpression interpolatedStringExpression)\n\t\t{\n\t\t\tVisitChildren(interpolatedStringExpression);\n\t\t}\n\n\t\tpublic virtual void VisitInterpolation(Interpolation interpolation)\n\t\t{\n\t\t\tVisitChildren(interpolation);\n\t\t}\n\n\t\tpublic virtual void VisitInterpolatedStringText(InterpolatedStringText interpolatedStringText)\n\t\t{\n\t\t\tVisitChildren(interpolatedStringText);\n\t\t}\n\n\t\tpublic virtual void VisitInvocationExpression(InvocationExpression invocationExpression)\n\t\t{\n\t\t\tVisitChildren(invocationExpression);\n\t\t}\n\n\t\tpublic virtual void VisitDirectionExpression(DirectionExpression directionExpression)\n\t\t{\n\t\t\tVisitChildren(directionExpression);\n\t\t}\n\n\t\tpublic virtual void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression)\n\t\t{\n\t\t\tVisitChildren(memberReferenceExpression);\n\t\t}\n\n\t\tpublic virtual void VisitNullReferenceExpression(NullReferenceExpression nullReferenceExpression)\n\t\t{\n\t\t\tVisitChildren(nullReferenceExpression);\n\t\t}\n\n\t\tpublic virtual void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression)\n\t\t{\n\t\t\tVisitChildren(objectCreateExpression);\n\t\t}\n\n\t\tpublic virtual void VisitDeclarationExpression(DeclarationExpression declarationExpression)\n\t\t{\n\t\t\tVisitChildren(declarationExpression);\n\t\t}\n\n\t\tpublic virtual void VisitRecursivePatternExpression(RecursivePatternExpression recursivePatternExpression)\n\t\t{\n\t\t\tVisitChildren(recursivePatternExpression);\n\t\t}\n\n\t\tpublic virtual void VisitOutVarDeclarationExpression(OutVarDeclarationExpression outVarDeclarationExpression)\n\t\t{\n\t\t\tVisitChildren(outVarDeclarationExpression);\n\t\t}\n\n\t\tpublic virtual void VisitAnonymousTypeCreateExpression(AnonymousTypeCreateExpression anonymousTypeCreateExpression)\n\t\t{\n\t\t\tVisitChildren(anonymousTypeCreateExpression);\n\t\t}\n\n\t\tpublic virtual void VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression)\n\t\t{\n\t\t\tVisitChildren(arrayCreateExpression);\n\t\t}\n\n\t\tpublic virtual void VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression)\n\t\t{\n\t\t\tVisitChildren(parenthesizedExpression);\n\t\t}\n\n\t\tpublic virtual void VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression)\n\t\t{\n\t\t\tVisitChildren(pointerReferenceExpression);\n\t\t}\n\n\t\tpublic virtual void VisitPrimitiveExpression(PrimitiveExpression primitiveExpression)\n\t\t{\n\t\t\tVisitChildren(primitiveExpression);\n\t\t}\n\n\t\tpublic virtual void VisitSizeOfExpression(SizeOfExpression sizeOfExpression)\n\t\t{\n\t\t\tVisitChildren(sizeOfExpression);\n\t\t}\n\n\t\tpublic virtual void VisitStackAllocExpression(StackAllocExpression stackAllocExpression)\n\t\t{\n\t\t\tVisitChildren(stackAllocExpression);\n\t\t}\n\n\t\tpublic virtual void VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression)\n\t\t{\n\t\t\tVisitChildren(thisReferenceExpression);\n\t\t}\n\n\t\tpublic virtual void VisitThrowExpression(ThrowExpression throwExpression)\n\t\t{\n\t\t\tVisitChildren(throwExpression);\n\t\t}\n\n\t\tpublic virtual void VisitTupleExpression(TupleExpression tupleExpression)\n\t\t{\n\t\t\tVisitChildren(tupleExpression);\n\t\t}\n\n\t\tpublic virtual void VisitTypeOfExpression(TypeOfExpression typeOfExpression)\n\t\t{\n\t\t\tVisitChildren(typeOfExpression);\n\t\t}\n\n\t\tpublic virtual void VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression)\n\t\t{\n\t\t\tVisitChildren(typeReferenceExpression);\n\t\t}\n\n\t\tpublic virtual void VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression)\n\t\t{\n\t\t\tVisitChildren(unaryOperatorExpression);\n\t\t}\n\n\t\tpublic virtual void VisitUncheckedExpression(UncheckedExpression uncheckedExpression)\n\t\t{\n\t\t\tVisitChildren(uncheckedExpression);\n\t\t}\n\n\t\tpublic virtual void VisitQueryExpression(QueryExpression queryExpression)\n\t\t{\n\t\t\tVisitChildren(queryExpression);\n\t\t}\n\n\t\tpublic virtual void VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause)\n\t\t{\n\t\t\tVisitChildren(queryContinuationClause);\n\t\t}\n\n\t\tpublic virtual void VisitQueryFromClause(QueryFromClause queryFromClause)\n\t\t{\n\t\t\tVisitChildren(queryFromClause);\n\t\t}\n\n\t\tpublic virtual void VisitQueryLetClause(QueryLetClause queryLetClause)\n\t\t{\n\t\t\tVisitChildren(queryLetClause);\n\t\t}\n\n\t\tpublic virtual void VisitQueryWhereClause(QueryWhereClause queryWhereClause)\n\t\t{\n\t\t\tVisitChildren(queryWhereClause);\n\t\t}\n\n\t\tpublic virtual void VisitQueryJoinClause(QueryJoinClause queryJoinClause)\n\t\t{\n\t\t\tVisitChildren(queryJoinClause);\n\t\t}\n\n\t\tpublic virtual void VisitQueryOrderClause(QueryOrderClause queryOrderClause)\n\t\t{\n\t\t\tVisitChildren(queryOrderClause);\n\t\t}\n\n\t\tpublic virtual void VisitQueryOrdering(QueryOrdering queryOrdering)\n\t\t{\n\t\t\tVisitChildren(queryOrdering);\n\t\t}\n\n\t\tpublic virtual void VisitQuerySelectClause(QuerySelectClause querySelectClause)\n\t\t{\n\t\t\tVisitChildren(querySelectClause);\n\t\t}\n\n\t\tpublic virtual void VisitQueryGroupClause(QueryGroupClause queryGroupClause)\n\t\t{\n\t\t\tVisitChildren(queryGroupClause);\n\t\t}\n\n\t\tpublic virtual void VisitAsExpression(AsExpression asExpression)\n\t\t{\n\t\t\tVisitChildren(asExpression);\n\t\t}\n\n\t\tpublic virtual void VisitIsExpression(IsExpression isExpression)\n\t\t{\n\t\t\tVisitChildren(isExpression);\n\t\t}\n\n\t\tpublic virtual void VisitDefaultValueExpression(DefaultValueExpression defaultValueExpression)\n\t\t{\n\t\t\tVisitChildren(defaultValueExpression);\n\t\t}\n\n\t\tpublic virtual void VisitUndocumentedExpression(UndocumentedExpression undocumentedExpression)\n\t\t{\n\t\t\tVisitChildren(undocumentedExpression);\n\t\t}\n\n\t\tpublic virtual void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)\n\t\t{\n\t\t\tVisitChildren(arrayInitializerExpression);\n\t\t}\n\n\t\tpublic virtual void VisitArraySpecifier(ArraySpecifier arraySpecifier)\n\t\t{\n\t\t\tVisitChildren(arraySpecifier);\n\t\t}\n\n\t\tpublic virtual void VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression)\n\t\t{\n\t\t\tVisitChildren(namedArgumentExpression);\n\t\t}\n\n\t\tpublic virtual void VisitNamedExpression(NamedExpression namedExpression)\n\t\t{\n\t\t\tVisitChildren(namedExpression);\n\t\t}\n\n\t\tpublic virtual void VisitSingleVariableDesignation(SingleVariableDesignation singleVariableDesignation)\n\t\t{\n\t\t\tVisitChildren(singleVariableDesignation);\n\t\t}\n\n\t\tpublic virtual void VisitParenthesizedVariableDesignation(ParenthesizedVariableDesignation parenthesizedVariableDesignation)\n\t\t{\n\t\t\tVisitChildren(parenthesizedVariableDesignation);\n\t\t}\n\n\t\tpublic virtual void VisitErrorNode(AstNode errorNode)\n\t\t{\n\t\t\tVisitChildren(errorNode);\n\t\t}\n\n\t\tpublic virtual void VisitPatternPlaceholder(AstNode placeholder, PatternMatching.Pattern pattern)\n\t\t{\n\t\t\tVisitChildren(placeholder);\n\t\t}\n\n\t\tpublic virtual void VisitWithInitializerExpression(WithInitializerExpression withInitializerExpression)\n\t\t{\n\t\t\tVisitChildren(withInitializerExpression);\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// AST visitor with a default implementation that visits all node depth-first.\n\t/// </summary>\n\tpublic abstract class DepthFirstAstVisitor<T> : IAstVisitor<T>\n\t{\n\t\tprotected virtual T VisitChildren(AstNode node)\n\t\t{\n\t\t\tAstNode next;\n\t\t\tfor (var child = node.FirstChild; child != null; child = next)\n\t\t\t{\n\t\t\t\t// Store next to allow the loop to continue\n\t\t\t\t// if the visitor removes/replaces child.\n\t\t\t\tnext = child.NextSibling;\n\t\t\t\tchild.AcceptVisitor(this);\n\t\t\t}\n\t\t\treturn default(T);\n\t\t}\n\n\t\tpublic virtual T VisitNullNode(AstNode nullNode)\n\t\t{\n\t\t\t// Should we call VisitChildren here?\n\t\t\t// We usually want to ignore null nodes.\n\t\t\t// Older NR versions (before VisitNullNode was introduced) didn't call VisitChildren() with null nodes;\n\t\t\t// so changing this might break VisitChildren() overrides that expect the node to be part of the AST.\n\t\t\treturn default(T);\n\t\t}\n\n\t\tpublic virtual T VisitSyntaxTree(SyntaxTree unit)\n\t\t{\n\t\t\treturn VisitChildren(unit);\n\t\t}\n\n\t\tpublic virtual T VisitComment(Comment comment)\n\t\t{\n\t\t\treturn VisitChildren(comment);\n\t\t}\n\n\t\tpublic virtual T VisitDocumentationReference(DocumentationReference documentationReference)\n\t\t{\n\t\t\treturn VisitChildren(documentationReference);\n\t\t}\n\n\t\tpublic virtual T VisitPreProcessorDirective(PreProcessorDirective preProcessorDirective)\n\t\t{\n\t\t\treturn VisitChildren(preProcessorDirective);\n\t\t}\n\n\t\tpublic virtual T VisitIdentifier(Identifier identifier)\n\t\t{\n\t\t\treturn VisitChildren(identifier);\n\t\t}\n\n\t\tpublic virtual T VisitCSharpTokenNode(CSharpTokenNode token)\n\t\t{\n\t\t\treturn VisitChildren(token);\n\t\t}\n\n\t\tpublic virtual T VisitPrimitiveType(PrimitiveType primitiveType)\n\t\t{\n\t\t\treturn VisitChildren(primitiveType);\n\t\t}\n\n\t\tpublic virtual T VisitComposedType(ComposedType composedType)\n\t\t{\n\t\t\treturn VisitChildren(composedType);\n\t\t}\n\n\t\tpublic virtual T VisitSimpleType(SimpleType simpleType)\n\t\t{\n\t\t\treturn VisitChildren(simpleType);\n\t\t}\n\n\t\tpublic virtual T VisitMemberType(MemberType memberType)\n\t\t{\n\t\t\treturn VisitChildren(memberType);\n\t\t}\n\n\t\tpublic virtual T VisitTupleType(TupleAstType tupleType)\n\t\t{\n\t\t\treturn VisitChildren(tupleType);\n\t\t}\n\n\t\tpublic virtual T VisitTupleTypeElement(TupleTypeElement tupleTypeElement)\n\t\t{\n\t\t\treturn VisitChildren(tupleTypeElement);\n\t\t}\n\n\t\tpublic virtual T VisitFunctionPointerType(FunctionPointerAstType functionPointerType)\n\t\t{\n\t\t\treturn VisitChildren(functionPointerType);\n\t\t}\n\n\t\tpublic virtual T VisitInvocationType(InvocationAstType invocationType)\n\t\t{\n\t\t\treturn VisitChildren(invocationType);\n\t\t}\n\n\t\tpublic virtual T VisitAttribute(Attribute attribute)\n\t\t{\n\t\t\treturn VisitChildren(attribute);\n\t\t}\n\n\t\tpublic virtual T VisitAttributeSection(AttributeSection attributeSection)\n\t\t{\n\t\t\treturn VisitChildren(attributeSection);\n\t\t}\n\n\t\tpublic virtual T VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(delegateDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(namespaceDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitTypeDeclaration(TypeDeclaration typeDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(typeDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(typeParameterDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(enumMemberDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitExtensionDeclaration(ExtensionDeclaration extensionDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(extensionDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitUsingDeclaration(UsingDeclaration usingDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(usingDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitUsingAliasDeclaration(UsingAliasDeclaration usingDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(usingDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitExternAliasDeclaration(ExternAliasDeclaration externAliasDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(externAliasDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(constructorDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitConstructorInitializer(ConstructorInitializer constructorInitializer)\n\t\t{\n\t\t\treturn VisitChildren(constructorInitializer);\n\t\t}\n\n\t\tpublic virtual T VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(destructorDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitEventDeclaration(EventDeclaration eventDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(eventDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitCustomEventDeclaration(CustomEventDeclaration eventDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(eventDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitFieldDeclaration(FieldDeclaration fieldDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(fieldDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(fixedFieldDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer)\n\t\t{\n\t\t\treturn VisitChildren(fixedVariableInitializer);\n\t\t}\n\n\t\tpublic virtual T VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(indexerDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitMethodDeclaration(MethodDeclaration methodDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(methodDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(operatorDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(propertyDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitAccessor(Accessor accessor)\n\t\t{\n\t\t\treturn VisitChildren(accessor);\n\t\t}\n\n\t\tpublic virtual T VisitVariableInitializer(VariableInitializer variableInitializer)\n\t\t{\n\t\t\treturn VisitChildren(variableInitializer);\n\t\t}\n\n\t\tpublic virtual T VisitParameterDeclaration(ParameterDeclaration parameterDeclaration)\n\t\t{\n\t\t\treturn VisitChildren(parameterDeclaration);\n\t\t}\n\n\t\tpublic virtual T VisitConstraint(Constraint constraint)\n\t\t{\n\t\t\treturn VisitChildren(constraint);\n\t\t}\n\n\t\tpublic virtual T VisitBlockStatement(BlockStatement blockStatement)\n\t\t{\n\t\t\treturn VisitChildren(blockStatement);\n\t\t}\n\n\t\tpublic virtual T VisitExpressionStatement(ExpressionStatement expressionStatement)\n\t\t{\n\t\t\treturn VisitChildren(expressionStatement);\n\t\t}\n\n\t\tpublic virtual T VisitBreakStatement(BreakStatement breakStatement)\n\t\t{\n\t\t\treturn VisitChildren(breakStatement);\n\t\t}\n\n\t\tpublic virtual T VisitCheckedStatement(CheckedStatement checkedStatement)\n\t\t{\n\t\t\treturn VisitChildren(checkedStatement);\n\t\t}\n\n\t\tpublic virtual T VisitContinueStatement(ContinueStatement continueStatement)\n\t\t{\n\t\t\treturn VisitChildren(continueStatement);\n\t\t}\n\n\t\tpublic virtual T VisitDoWhileStatement(DoWhileStatement doWhileStatement)\n\t\t{\n\t\t\treturn VisitChildren(doWhileStatement);\n\t\t}\n\n\t\tpublic virtual T VisitEmptyStatement(EmptyStatement emptyStatement)\n\t\t{\n\t\t\treturn VisitChildren(emptyStatement);\n\t\t}\n\n\t\tpublic virtual T VisitFixedStatement(FixedStatement fixedStatement)\n\t\t{\n\t\t\treturn VisitChildren(fixedStatement);\n\t\t}\n\n\t\tpublic virtual T VisitForeachStatement(ForeachStatement foreachStatement)\n\t\t{\n\t\t\treturn VisitChildren(foreachStatement);\n\t\t}\n\n\t\tpublic virtual T VisitForStatement(ForStatement forStatement)\n\t\t{\n\t\t\treturn VisitChildren(forStatement);\n\t\t}\n\n\t\tpublic virtual T VisitGotoCaseStatement(GotoCaseStatement gotoCaseStatement)\n\t\t{\n\t\t\treturn VisitChildren(gotoCaseStatement);\n\t\t}\n\n\t\tpublic virtual T VisitGotoDefaultStatement(GotoDefaultStatement gotoDefaultStatement)\n\t\t{\n\t\t\treturn VisitChildren(gotoDefaultStatement);\n\t\t}\n\n\t\tpublic virtual T VisitGotoStatement(GotoStatement gotoStatement)\n\t\t{\n\t\t\treturn VisitChildren(gotoStatement);\n\t\t}\n\n\t\tpublic virtual T VisitIfElseStatement(IfElseStatement ifElseStatement)\n\t\t{\n\t\t\treturn VisitChildren(ifElseStatement);\n\t\t}\n\n\t\tpublic virtual T VisitLabelStatement(LabelStatement labelStatement)\n\t\t{\n\t\t\treturn VisitChildren(labelStatement);\n\t\t}\n\n\t\tpublic virtual T VisitLockStatement(LockStatement lockStatement)\n\t\t{\n\t\t\treturn VisitChildren(lockStatement);\n\t\t}\n\n\t\tpublic virtual T VisitReturnStatement(ReturnStatement returnStatement)\n\t\t{\n\t\t\treturn VisitChildren(returnStatement);\n\t\t}\n\n\t\tpublic virtual T VisitSwitchStatement(SwitchStatement switchStatement)\n\t\t{\n\t\t\treturn VisitChildren(switchStatement);\n\t\t}\n\n\t\tpublic virtual T VisitSwitchSection(SwitchSection switchSection)\n\t\t{\n\t\t\treturn VisitChildren(switchSection);\n\t\t}\n\n\t\tpublic virtual T VisitCaseLabel(CaseLabel caseLabel)\n\t\t{\n\t\t\treturn VisitChildren(caseLabel);\n\t\t}\n\n\t\tpublic virtual T VisitSwitchExpression(SwitchExpression switchExpression)\n\t\t{\n\t\t\treturn VisitChildren(switchExpression);\n\t\t}\n\n\t\tpublic virtual T VisitSwitchExpressionSection(SwitchExpressionSection switchExpressionSection)\n\t\t{\n\t\t\treturn VisitChildren(switchExpressionSection);\n\t\t}\n\n\t\tpublic virtual T VisitThrowStatement(ThrowStatement throwStatement)\n\t\t{\n\t\t\treturn VisitChildren(throwStatement);\n\t\t}\n\n\t\tpublic virtual T VisitTryCatchStatement(TryCatchStatement tryCatchStatement)\n\t\t{\n\t\t\treturn VisitChildren(tryCatchStatement);\n\t\t}\n\n\t\tpublic virtual T VisitCatchClause(CatchClause catchClause)\n\t\t{\n\t\t\treturn VisitChildren(catchClause);\n\t\t}\n\n\t\tpublic virtual T VisitUncheckedStatement(UncheckedStatement uncheckedStatement)\n\t\t{\n\t\t\treturn VisitChildren(uncheckedStatement);\n\t\t}\n\n\t\tpublic virtual T VisitUnsafeStatement(UnsafeStatement unsafeStatement)\n\t\t{\n\t\t\treturn VisitChildren(unsafeStatement);\n\t\t}\n\n\t\tpublic virtual T VisitUsingStatement(UsingStatement usingStatement)\n\t\t{\n\t\t\treturn VisitChildren(usingStatement);\n\t\t}\n\n\t\tpublic virtual T VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement)\n\t\t{\n\t\t\treturn VisitChildren(variableDeclarationStatement);\n\t\t}\n\n\t\tpublic virtual T VisitLocalFunctionDeclarationStatement(LocalFunctionDeclarationStatement localFunctionDeclarationStatement)\n\t\t{\n\t\t\treturn VisitChildren(localFunctionDeclarationStatement);\n\t\t}\n\n\t\tpublic virtual T VisitWhileStatement(WhileStatement whileStatement)\n\t\t{\n\t\t\treturn VisitChildren(whileStatement);\n\t\t}\n\n\t\tpublic virtual T VisitYieldBreakStatement(YieldBreakStatement yieldBreakStatement)\n\t\t{\n\t\t\treturn VisitChildren(yieldBreakStatement);\n\t\t}\n\n\t\tpublic virtual T VisitYieldReturnStatement(YieldReturnStatement yieldReturnStatement)\n\t\t{\n\t\t\treturn VisitChildren(yieldReturnStatement);\n\t\t}\n\n\t\tpublic virtual T VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression)\n\t\t{\n\t\t\treturn VisitChildren(anonymousMethodExpression);\n\t\t}\n\n\t\tpublic virtual T VisitLambdaExpression(LambdaExpression lambdaExpression)\n\t\t{\n\t\t\treturn VisitChildren(lambdaExpression);\n\t\t}\n\n\t\tpublic virtual T VisitAssignmentExpression(AssignmentExpression assignmentExpression)\n\t\t{\n\t\t\treturn VisitChildren(assignmentExpression);\n\t\t}\n\n\t\tpublic virtual T VisitBaseReferenceExpression(BaseReferenceExpression baseReferenceExpression)\n\t\t{\n\t\t\treturn VisitChildren(baseReferenceExpression);\n\t\t}\n\n\t\tpublic virtual T VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)\n\t\t{\n\t\t\treturn VisitChildren(binaryOperatorExpression);\n\t\t}\n\n\t\tpublic virtual T VisitCastExpression(CastExpression castExpression)\n\t\t{\n\t\t\treturn VisitChildren(castExpression);\n\t\t}\n\n\t\tpublic virtual T VisitCheckedExpression(CheckedExpression checkedExpression)\n\t\t{\n\t\t\treturn VisitChildren(checkedExpression);\n\t\t}\n\n\t\tpublic virtual T VisitConditionalExpression(ConditionalExpression conditionalExpression)\n\t\t{\n\t\t\treturn VisitChildren(conditionalExpression);\n\t\t}\n\n\t\tpublic virtual T VisitIdentifierExpression(IdentifierExpression identifierExpression)\n\t\t{\n\t\t\treturn VisitChildren(identifierExpression);\n\t\t}\n\n\t\tpublic virtual T VisitIndexerExpression(IndexerExpression indexerExpression)\n\t\t{\n\t\t\treturn VisitChildren(indexerExpression);\n\t\t}\n\n\t\tpublic virtual T VisitInterpolatedStringExpression(InterpolatedStringExpression interpolatedStringExpression)\n\t\t{\n\t\t\treturn VisitChildren(interpolatedStringExpression);\n\t\t}\n\n\t\tpublic virtual T VisitInterpolation(Interpolation interpolation)\n\t\t{\n\t\t\treturn VisitChildren(interpolation);\n\t\t}\n\n\t\tpublic virtual T VisitInterpolatedStringText(InterpolatedStringText interpolatedStringText)\n\t\t{\n\t\t\treturn VisitChildren(interpolatedStringText);\n\t\t}\n\n\t\tpublic virtual T VisitInvocationExpression(InvocationExpression invocationExpression)\n\t\t{\n\t\t\treturn VisitChildren(invocationExpression);\n\t\t}\n\n\t\tpublic virtual T VisitDirectionExpression(DirectionExpression directionExpression)\n\t\t{\n\t\t\treturn VisitChildren(directionExpression);\n\t\t}\n\n\t\tpublic virtual T VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression)\n\t\t{\n\t\t\treturn VisitChildren(memberReferenceExpression);\n\t\t}\n\n\t\tpublic virtual T VisitNullReferenceExpression(NullReferenceExpression nullReferenceExpression)\n\t\t{\n\t\t\treturn VisitChildren(nullReferenceExpression);\n\t\t}\n\n\t\tpublic virtual T VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression)\n\t\t{\n\t\t\treturn VisitChildren(objectCreateExpression);\n\t\t}\n\n\t\tpublic virtual T VisitDeclarationExpression(DeclarationExpression declarationExpression)\n\t\t{\n\t\t\treturn VisitChildren(declarationExpression);\n\t\t}\n\n\t\tpublic virtual T VisitRecursivePatternExpression(RecursivePatternExpression recursivePatternExpression)\n\t\t{\n\t\t\treturn VisitChildren(recursivePatternExpression);\n\t\t}\n\n\t\tpublic virtual T VisitOutVarDeclarationExpression(OutVarDeclarationExpression outVarDeclarationExpression)\n\t\t{\n\t\t\treturn VisitChildren(outVarDeclarationExpression);\n\t\t}\n\n\t\tpublic virtual T VisitAnonymousTypeCreateExpression(AnonymousTypeCreateExpression anonymousTypeCreateExpression)\n\t\t{\n\t\t\treturn VisitChildren(anonymousTypeCreateExpression);\n\t\t}\n\n\t\tpublic virtual T VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression)\n\t\t{\n\t\t\treturn VisitChildren(arrayCreateExpression);\n\t\t}\n\n\t\tpublic virtual T VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression)\n\t\t{\n\t\t\treturn VisitChildren(parenthesizedExpression);\n\t\t}\n\n\t\tpublic virtual T VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression)\n\t\t{\n\t\t\treturn VisitChildren(pointerReferenceExpression);\n\t\t}\n\n\t\tpublic virtual T VisitPrimitiveExpression(PrimitiveExpression primitiveExpression)\n\t\t{\n\t\t\treturn VisitChildren(primitiveExpression);\n\t\t}\n\n\t\tpublic virtual T VisitSizeOfExpression(SizeOfExpression sizeOfExpression)\n\t\t{\n\t\t\treturn VisitChildren(sizeOfExpression);\n\t\t}\n\n\t\tpublic virtual T VisitStackAllocExpression(StackAllocExpression stackAllocExpression)\n\t\t{\n\t\t\treturn VisitChildren(stackAllocExpression);\n\t\t}\n\n\t\tpublic virtual T VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression)\n\t\t{\n\t\t\treturn VisitChildren(thisReferenceExpression);\n\t\t}\n\n\t\tpublic virtual T VisitThrowExpression(ThrowExpression throwExpression)\n\t\t{\n\t\t\treturn VisitChildren(throwExpression);\n\t\t}\n\n\t\tpublic virtual T VisitTupleExpression(TupleExpression tupleExpression)\n\t\t{\n\t\t\treturn VisitChildren(tupleExpression);\n\t\t}\n\n\t\tpublic virtual T VisitTypeOfExpression(TypeOfExpression typeOfExpression)\n\t\t{\n\t\t\treturn VisitChildren(typeOfExpression);\n\t\t}\n\n\t\tpublic virtual T VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression)\n\t\t{\n\t\t\treturn VisitChildren(typeReferenceExpression);\n\t\t}\n\n\t\tpublic virtual T VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression)\n\t\t{\n\t\t\treturn VisitChildren(unaryOperatorExpression);\n\t\t}\n\n\t\tpublic virtual T VisitUncheckedExpression(UncheckedExpression uncheckedExpression)\n\t\t{\n\t\t\treturn VisitChildren(uncheckedExpression);\n\t\t}\n\n\t\tpublic virtual T VisitQueryExpression(QueryExpression queryExpression)\n\t\t{\n\t\t\treturn VisitChildren(queryExpression);\n\t\t}\n\n\t\tpublic virtual T VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause)\n\t\t{\n\t\t\treturn VisitChildren(queryContinuationClause);\n\t\t}\n\n\t\tpublic virtual T VisitQueryFromClause(QueryFromClause queryFromClause)\n\t\t{\n\t\t\treturn VisitChildren(queryFromClause);\n\t\t}\n\n\t\tpublic virtual T VisitQueryLetClause(QueryLetClause queryLetClause)\n\t\t{\n\t\t\treturn VisitChildren(queryLetClause);\n\t\t}\n\n\t\tpublic virtual T VisitQueryWhereClause(QueryWhereClause queryWhereClause)\n\t\t{\n\t\t\treturn VisitChildren(queryWhereClause);\n\t\t}\n\n\t\tpublic virtual T VisitQueryJoinClause(QueryJoinClause queryJoinClause)\n\t\t{\n\t\t\treturn VisitChildren(queryJoinClause);\n\t\t}\n\n\t\tpublic virtual T VisitQueryOrderClause(QueryOrderClause queryOrderClause)\n\t\t{\n\t\t\treturn VisitChildren(queryOrderClause);\n\t\t}\n\n\t\tpublic virtual T VisitQueryOrdering(QueryOrdering queryOrdering)\n\t\t{\n\t\t\treturn VisitChildren(queryOrdering);\n\t\t}\n\n\t\tpublic virtual T VisitQuerySelectClause(QuerySelectClause querySelectClause)\n\t\t{\n\t\t\treturn VisitChildren(querySelectClause);\n\t\t}\n\n\t\tpublic virtual T VisitQueryGroupClause(QueryGroupClause queryGroupClause)\n\t\t{\n\t\t\treturn VisitChildren(queryGroupClause);\n\t\t}\n\n\t\tpublic virtual T VisitAsExpression(AsExpression asExpression)\n\t\t{\n\t\t\treturn VisitChildren(asExpression);\n\t\t}\n\n\t\tpublic virtual T VisitIsExpression(IsExpression isExpression)\n\t\t{\n\t\t\treturn VisitChildren(isExpression);\n\t\t}\n\n\t\tpublic virtual T VisitDefaultValueExpression(DefaultValueExpression defaultValueExpression)\n\t\t{\n\t\t\treturn VisitChildren(defaultValueExpression);\n\t\t}\n\n\t\tpublic virtual T VisitUndocumentedExpression(UndocumentedExpression undocumentedExpression)\n\t\t{\n\t\t\treturn VisitChildren(undocumentedExpression);\n\t\t}\n\n\t\tpublic virtual T VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)\n\t\t{\n\t\t\treturn VisitChildren(arrayInitializerExpression);\n\t\t}\n\n\t\tpublic virtual T VisitArraySpecifier(ArraySpecifier arraySpecifier)\n\t\t{\n\t\t\treturn VisitChildren(arraySpecifier);\n\t\t}\n\n\t\tpublic virtual T VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression)\n\t\t{\n\t\t\treturn VisitChildren(namedArgumentExpression);\n\t\t}\n\n\t\tpublic virtual T VisitNamedExpression(NamedExpression namedExpression)\n\t\t{\n\t\t\treturn VisitChildren(namedExpression);\n\t\t}\n\n\t\tpublic virtual T VisitSingleVariableDesignation(SingleVariableDesignation singleVariableDesignation)\n\t\t{\n\t\t\treturn VisitChildren(singleVariableDesignation);\n\t\t}\n\n\t\tpublic virtual T VisitParenthesizedVariableDesignation(ParenthesizedVariableDesignation parenthesizedVariableDesignation)\n\t\t{\n\t\t\treturn VisitChildren(parenthesizedVariableDesignation);\n\t\t}\n\n\t\tpublic virtual T VisitErrorNode(AstNode errorNode)\n\t\t{\n\t\t\treturn VisitChildren(errorNode);\n\t\t}\n\n\t\tpublic virtual T VisitPatternPlaceholder(AstNode placeholder, PatternMatching.Pattern pattern)\n\t\t{\n\t\t\treturn VisitChildren(placeholder);\n\t\t}\n\n\t\tpublic virtual T VisitWithInitializerExpression(WithInitializerExpression withInitializerExpression)\n\t\t{\n\t\t\treturn VisitChildren(withInitializerExpression);\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// AST visitor with a default implementation that visits all node depth-first.\n\t/// </summary>\n\tpublic abstract class DepthFirstAstVisitor<T, S> : IAstVisitor<T, S>\n\t{\n\t\tprotected virtual S VisitChildren(AstNode node, T data)\n\t\t{\n\t\t\tAstNode next;\n\t\t\tfor (var child = node.FirstChild; child != null; child = next)\n\t\t\t{\n\t\t\t\t// Store next to allow the loop to continue\n\t\t\t\t// if the visitor removes/replaces child.\n\t\t\t\tnext = child.NextSibling;\n\t\t\t\tchild.AcceptVisitor(this, data);\n\t\t\t}\n\t\t\treturn default(S);\n\t\t}\n\n\t\tpublic virtual S VisitNullNode(AstNode nullNode, T data)\n\t\t{\n\t\t\t// Should we call VisitChildren here?\n\t\t\t// We usually want to ignore null nodes.\n\t\t\t// Older NR versions (before VisitNullNode was introduced) didn't call VisitChildren() with null nodes;\n\t\t\t// so changing this might break VisitChildren() overrides that expect the node to be part of the AST.\n\t\t\treturn default(S);\n\t\t}\n\n\t\tpublic virtual S VisitSyntaxTree(SyntaxTree unit, T data)\n\t\t{\n\t\t\treturn VisitChildren(unit, data);\n\t\t}\n\n\t\tpublic virtual S VisitComment(Comment comment, T data)\n\t\t{\n\t\t\treturn VisitChildren(comment, data);\n\t\t}\n\n\t\tpublic virtual S VisitDocumentationReference(DocumentationReference documentationReference, T data)\n\t\t{\n\t\t\treturn VisitChildren(documentationReference, data);\n\t\t}\n\n\t\tpublic virtual S VisitPreProcessorDirective(PreProcessorDirective preProcessorDirective, T data)\n\t\t{\n\t\t\treturn VisitChildren(preProcessorDirective, data);\n\t\t}\n\n\t\tpublic virtual S VisitIdentifier(Identifier identifier, T data)\n\t\t{\n\t\t\treturn VisitChildren(identifier, data);\n\t\t}\n\n\t\tpublic virtual S VisitCSharpTokenNode(CSharpTokenNode token, T data)\n\t\t{\n\t\t\treturn VisitChildren(token, data);\n\t\t}\n\n\t\tpublic virtual S VisitPrimitiveType(PrimitiveType primitiveType, T data)\n\t\t{\n\t\t\treturn VisitChildren(primitiveType, data);\n\t\t}\n\n\t\tpublic virtual S VisitComposedType(ComposedType composedType, T data)\n\t\t{\n\t\t\treturn VisitChildren(composedType, data);\n\t\t}\n\n\t\tpublic virtual S VisitSimpleType(SimpleType simpleType, T data)\n\t\t{\n\t\t\treturn VisitChildren(simpleType, data);\n\t\t}\n\n\t\tpublic virtual S VisitMemberType(MemberType memberType, T data)\n\t\t{\n\t\t\treturn VisitChildren(memberType, data);\n\t\t}\n\n\t\tpublic virtual S VisitTupleType(TupleAstType tupleType, T data)\n\t\t{\n\t\t\treturn VisitChildren(tupleType, data);\n\t\t}\n\n\t\tpublic virtual S VisitTupleTypeElement(TupleTypeElement tupleTypeElement, T data)\n\t\t{\n\t\t\treturn VisitChildren(tupleTypeElement, data);\n\t\t}\n\n\t\tpublic virtual S VisitFunctionPointerType(FunctionPointerAstType functionPointerType, T data)\n\t\t{\n\t\t\treturn VisitChildren(functionPointerType, data);\n\t\t}\n\n\t\tpublic virtual S VisitInvocationType(InvocationAstType invocationType, T data)\n\t\t{\n\t\t\treturn VisitChildren(invocationType, data);\n\t\t}\n\n\t\tpublic virtual S VisitAttribute(Attribute attribute, T data)\n\t\t{\n\t\t\treturn VisitChildren(attribute, data);\n\t\t}\n\n\t\tpublic virtual S VisitAttributeSection(AttributeSection attributeSection, T data)\n\t\t{\n\t\t\treturn VisitChildren(attributeSection, data);\n\t\t}\n\n\t\tpublic virtual S VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(delegateDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(namespaceDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitTypeDeclaration(TypeDeclaration typeDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(typeDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(typeParameterDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(enumMemberDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitExtensionDeclaration(ExtensionDeclaration extensionDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(extensionDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitUsingDeclaration(UsingDeclaration usingDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(usingDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitUsingAliasDeclaration(UsingAliasDeclaration usingDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(usingDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitExternAliasDeclaration(ExternAliasDeclaration externAliasDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(externAliasDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(constructorDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitConstructorInitializer(ConstructorInitializer constructorInitializer, T data)\n\t\t{\n\t\t\treturn VisitChildren(constructorInitializer, data);\n\t\t}\n\n\t\tpublic virtual S VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(destructorDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitEventDeclaration(EventDeclaration eventDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(eventDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitCustomEventDeclaration(CustomEventDeclaration eventDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(eventDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitFieldDeclaration(FieldDeclaration fieldDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(fieldDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(fixedFieldDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer, T data)\n\t\t{\n\t\t\treturn VisitChildren(fixedVariableInitializer, data);\n\t\t}\n\n\t\tpublic virtual S VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(indexerDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitMethodDeclaration(MethodDeclaration methodDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(methodDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(operatorDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(propertyDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitAccessor(Accessor accessor, T data)\n\t\t{\n\t\t\treturn VisitChildren(accessor, data);\n\t\t}\n\n\t\tpublic virtual S VisitVariableInitializer(VariableInitializer variableInitializer, T data)\n\t\t{\n\t\t\treturn VisitChildren(variableInitializer, data);\n\t\t}\n\n\t\tpublic virtual S VisitParameterDeclaration(ParameterDeclaration parameterDeclaration, T data)\n\t\t{\n\t\t\treturn VisitChildren(parameterDeclaration, data);\n\t\t}\n\n\t\tpublic virtual S VisitConstraint(Constraint constraint, T data)\n\t\t{\n\t\t\treturn VisitChildren(constraint, data);\n\t\t}\n\n\t\tpublic virtual S VisitBlockStatement(BlockStatement blockStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(blockStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitExpressionStatement(ExpressionStatement expressionStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(expressionStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitBreakStatement(BreakStatement breakStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(breakStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitCheckedStatement(CheckedStatement checkedStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(checkedStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitContinueStatement(ContinueStatement continueStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(continueStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitDoWhileStatement(DoWhileStatement doWhileStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(doWhileStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitEmptyStatement(EmptyStatement emptyStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(emptyStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitFixedStatement(FixedStatement fixedStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(fixedStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitForeachStatement(ForeachStatement foreachStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(foreachStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitForStatement(ForStatement forStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(forStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitGotoCaseStatement(GotoCaseStatement gotoCaseStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(gotoCaseStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitGotoDefaultStatement(GotoDefaultStatement gotoDefaultStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(gotoDefaultStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitGotoStatement(GotoStatement gotoStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(gotoStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitIfElseStatement(IfElseStatement ifElseStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(ifElseStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitLabelStatement(LabelStatement labelStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(labelStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitLockStatement(LockStatement lockStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(lockStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitReturnStatement(ReturnStatement returnStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(returnStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitSwitchStatement(SwitchStatement switchStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(switchStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitSwitchSection(SwitchSection switchSection, T data)\n\t\t{\n\t\t\treturn VisitChildren(switchSection, data);\n\t\t}\n\n\t\tpublic virtual S VisitCaseLabel(CaseLabel caseLabel, T data)\n\t\t{\n\t\t\treturn VisitChildren(caseLabel, data);\n\t\t}\n\n\t\tpublic virtual S VisitSwitchExpression(SwitchExpression switchExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(switchExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitSwitchExpressionSection(SwitchExpressionSection switchExpressionSection, T data)\n\t\t{\n\t\t\treturn VisitChildren(switchExpressionSection, data);\n\t\t}\n\n\t\tpublic virtual S VisitThrowStatement(ThrowStatement throwStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(throwStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitTryCatchStatement(TryCatchStatement tryCatchStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(tryCatchStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitCatchClause(CatchClause catchClause, T data)\n\t\t{\n\t\t\treturn VisitChildren(catchClause, data);\n\t\t}\n\n\t\tpublic virtual S VisitUncheckedStatement(UncheckedStatement uncheckedStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(uncheckedStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitUnsafeStatement(UnsafeStatement unsafeStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(unsafeStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitUsingStatement(UsingStatement usingStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(usingStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(variableDeclarationStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitLocalFunctionDeclarationStatement(LocalFunctionDeclarationStatement localFunctionDeclarationStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(localFunctionDeclarationStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitWhileStatement(WhileStatement whileStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(whileStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitYieldBreakStatement(YieldBreakStatement yieldBreakStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(yieldBreakStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitYieldReturnStatement(YieldReturnStatement yieldReturnStatement, T data)\n\t\t{\n\t\t\treturn VisitChildren(yieldReturnStatement, data);\n\t\t}\n\n\t\tpublic virtual S VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(anonymousMethodExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitLambdaExpression(LambdaExpression lambdaExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(lambdaExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitAssignmentExpression(AssignmentExpression assignmentExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(assignmentExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitBaseReferenceExpression(BaseReferenceExpression baseReferenceExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(baseReferenceExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(binaryOperatorExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitCastExpression(CastExpression castExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(castExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitCheckedExpression(CheckedExpression checkedExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(checkedExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitConditionalExpression(ConditionalExpression conditionalExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(conditionalExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitIdentifierExpression(IdentifierExpression identifierExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(identifierExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitIndexerExpression(IndexerExpression indexerExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(indexerExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitInterpolatedStringExpression(InterpolatedStringExpression interpolatedStringExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(interpolatedStringExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitInterpolation(Interpolation interpolation, T data)\n\t\t{\n\t\t\treturn VisitChildren(interpolation, data);\n\t\t}\n\n\t\tpublic virtual S VisitInterpolatedStringText(InterpolatedStringText interpolatedStringText, T data)\n\t\t{\n\t\t\treturn VisitChildren(interpolatedStringText, data);\n\t\t}\n\n\t\tpublic virtual S VisitInvocationExpression(InvocationExpression invocationExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(invocationExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitDirectionExpression(DirectionExpression directionExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(directionExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(memberReferenceExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitNullReferenceExpression(NullReferenceExpression nullReferenceExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(nullReferenceExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(objectCreateExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitDeclarationExpression(DeclarationExpression declarationExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(declarationExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitRecursivePatternExpression(RecursivePatternExpression recursivePatternExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(recursivePatternExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitOutVarDeclarationExpression(OutVarDeclarationExpression outVarDeclarationExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(outVarDeclarationExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitAnonymousTypeCreateExpression(AnonymousTypeCreateExpression anonymousTypeCreateExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(anonymousTypeCreateExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(arrayCreateExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(parenthesizedExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(pointerReferenceExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(primitiveExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitSizeOfExpression(SizeOfExpression sizeOfExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(sizeOfExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitStackAllocExpression(StackAllocExpression stackAllocExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(stackAllocExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(thisReferenceExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitThrowExpression(ThrowExpression throwExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(throwExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitTupleExpression(TupleExpression tupleExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(tupleExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitTypeOfExpression(TypeOfExpression typeOfExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(typeOfExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(typeReferenceExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(unaryOperatorExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitUncheckedExpression(UncheckedExpression uncheckedExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(uncheckedExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitQueryExpression(QueryExpression queryExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(queryExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause, T data)\n\t\t{\n\t\t\treturn VisitChildren(queryContinuationClause, data);\n\t\t}\n\n\t\tpublic virtual S VisitQueryFromClause(QueryFromClause queryFromClause, T data)\n\t\t{\n\t\t\treturn VisitChildren(queryFromClause, data);\n\t\t}\n\n\t\tpublic virtual S VisitQueryLetClause(QueryLetClause queryLetClause, T data)\n\t\t{\n\t\t\treturn VisitChildren(queryLetClause, data);\n\t\t}\n\n\t\tpublic virtual S VisitQueryWhereClause(QueryWhereClause queryWhereClause, T data)\n\t\t{\n\t\t\treturn VisitChildren(queryWhereClause, data);\n\t\t}\n\n\t\tpublic virtual S VisitQueryJoinClause(QueryJoinClause queryJoinClause, T data)\n\t\t{\n\t\t\treturn VisitChildren(queryJoinClause, data);\n\t\t}\n\n\t\tpublic virtual S VisitQueryOrderClause(QueryOrderClause queryOrderClause, T data)\n\t\t{\n\t\t\treturn VisitChildren(queryOrderClause, data);\n\t\t}\n\n\t\tpublic virtual S VisitQueryOrdering(QueryOrdering queryOrdering, T data)\n\t\t{\n\t\t\treturn VisitChildren(queryOrdering, data);\n\t\t}\n\n\t\tpublic virtual S VisitQuerySelectClause(QuerySelectClause querySelectClause, T data)\n\t\t{\n\t\t\treturn VisitChildren(querySelectClause, data);\n\t\t}\n\n\t\tpublic virtual S VisitQueryGroupClause(QueryGroupClause queryGroupClause, T data)\n\t\t{\n\t\t\treturn VisitChildren(queryGroupClause, data);\n\t\t}\n\n\t\tpublic virtual S VisitAsExpression(AsExpression asExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(asExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitIsExpression(IsExpression isExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(isExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitDefaultValueExpression(DefaultValueExpression defaultValueExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(defaultValueExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitUndocumentedExpression(UndocumentedExpression undocumentedExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(undocumentedExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(arrayInitializerExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitArraySpecifier(ArraySpecifier arraySpecifier, T data)\n\t\t{\n\t\t\treturn VisitChildren(arraySpecifier, data);\n\t\t}\n\n\t\tpublic virtual S VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(namedArgumentExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitNamedExpression(NamedExpression namedExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(namedExpression, data);\n\t\t}\n\n\t\tpublic virtual S VisitSingleVariableDesignation(SingleVariableDesignation singleVariableDesignation, T data)\n\t\t{\n\t\t\treturn VisitChildren(singleVariableDesignation, data);\n\t\t}\n\n\t\tpublic virtual S VisitParenthesizedVariableDesignation(ParenthesizedVariableDesignation parenthesizedVariableDesignation, T data)\n\t\t{\n\t\t\treturn VisitChildren(parenthesizedVariableDesignation, data);\n\t\t}\n\n\t\tpublic virtual S VisitErrorNode(AstNode errorNode, T data)\n\t\t{\n\t\t\treturn VisitChildren(errorNode, data);\n\t\t}\n\n\t\tpublic virtual S VisitPatternPlaceholder(AstNode placeholder, PatternMatching.Pattern pattern, T data)\n\t\t{\n\t\t\treturn VisitChildren(placeholder, data);\n\t\t}\n\n\t\tpublic virtual S VisitWithInitializerExpression(WithInitializerExpression withInitializerExpression, T data)\n\t\t{\n\t\t\treturn VisitChildren(withInitializerExpression, data);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/DocumentationReference.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Represents a 'cref' reference in XML documentation.\n\t/// </summary>\n\tpublic class DocumentationReference : AstNode\n\t{\n\t\tpublic static readonly Role<AstType> DeclaringTypeRole = new Role<AstType>(\"DeclaringType\", AstType.Null);\n\t\tpublic static readonly Role<AstType> ConversionOperatorReturnTypeRole = new Role<AstType>(\"ConversionOperatorReturnType\", AstType.Null);\n\n\t\tSymbolKind symbolKind;\n\t\tOperatorType operatorType;\n\t\tbool hasParameterList;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the entity type.\n\t\t/// Possible values are:\n\t\t///   <c>SymbolKind.Operator</c> for operators,\n\t\t///   <c>SymbolKind.Indexer</c> for indexers,\n\t\t///   <c>SymbolKind.TypeDefinition</c> for references to primitive types,\n\t\t///   and <c>SymbolKind.None</c> for everything else.\n\t\t/// </summary>\n\t\tpublic SymbolKind SymbolKind {\n\t\t\tget { return symbolKind; }\n\t\t\tset {\n\t\t\t\tThrowIfFrozen();\n\t\t\t\tsymbolKind = value;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the operator type.\n\t\t/// This property is only used when SymbolKind==Operator.\n\t\t/// </summary>\n\t\tpublic OperatorType OperatorType {\n\t\t\tget { return operatorType; }\n\t\t\tset {\n\t\t\t\tThrowIfFrozen();\n\t\t\t\toperatorType = value;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether a parameter list was provided.\n\t\t/// </summary>\n\t\tpublic bool HasParameterList {\n\t\t\tget { return hasParameterList; }\n\t\t\tset {\n\t\t\t\tThrowIfFrozen();\n\t\t\t\thasParameterList = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget { return NodeType.Unknown; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the declaring type.\n\t\t/// </summary>\n\t\tpublic AstType DeclaringType {\n\t\t\tget { return GetChildByRole(DeclaringTypeRole); }\n\t\t\tset { SetChildByRole(DeclaringTypeRole, value); }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets/sets the member name.\n\t\t/// This property is only used when SymbolKind==None.\n\t\t/// </summary>\n\t\tpublic string MemberName {\n\t\t\tget { return GetChildByRole(Roles.Identifier).Name; }\n\t\t\tset { SetChildByRole(Roles.Identifier, Identifier.Create(value)); }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the return type of conversion operators.\n\t\t/// This property is only used when SymbolKind==Operator and OperatorType is explicit or implicit.\n\t\t/// </summary>\n\t\tpublic AstType ConversionOperatorReturnType {\n\t\t\tget { return GetChildByRole(ConversionOperatorReturnTypeRole); }\n\t\t\tset { SetChildByRole(ConversionOperatorReturnTypeRole, value); }\n\t\t}\n\n\t\tpublic AstNodeCollection<AstType> TypeArguments {\n\t\t\tget { return GetChildrenByRole(Roles.TypeArgument); }\n\t\t}\n\n\t\tpublic AstNodeCollection<ParameterDeclaration> Parameters {\n\t\t\tget { return GetChildrenByRole(Roles.Parameter); }\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tDocumentationReference o = other as DocumentationReference;\n\t\t\tif (!(o != null && this.SymbolKind == o.SymbolKind && this.HasParameterList == o.HasParameterList))\n\t\t\t\treturn false;\n\t\t\tif (this.SymbolKind == SymbolKind.Operator)\n\t\t\t{\n\t\t\t\tif (this.OperatorType != o.OperatorType)\n\t\t\t\t\treturn false;\n\t\t\t\tif (this.OperatorType == OperatorType.Implicit || this.OperatorType == OperatorType.Explicit)\n\t\t\t\t{\n\t\t\t\t\tif (!this.ConversionOperatorReturnType.DoMatch(o.ConversionOperatorReturnType, match))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (this.SymbolKind == SymbolKind.None)\n\t\t\t{\n\t\t\t\tif (!MatchString(this.MemberName, o.MemberName))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!this.TypeArguments.DoMatch(o.TypeArguments, match))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn this.Parameters.DoMatch(o.Parameters, match);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDocumentationReference(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDocumentationReference(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitDocumentationReference(this, data);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/AnonymousMethodExpression.cs",
    "content": "// \n// AnonymousMethodExpression.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// [async] delegate(Parameters) {Body}\n\t/// </summary>\n\tpublic class AnonymousMethodExpression : Expression\n\t{\n\t\tpublic readonly static TokenRole DelegateKeywordRole = new TokenRole(\"delegate\");\n\t\tpublic readonly static TokenRole AsyncModifierRole = LambdaExpression.AsyncModifierRole;\n\n\t\tbool isAsync;\n\n\t\tpublic bool IsAsync {\n\t\t\tget { return isAsync; }\n\t\t\tset { ThrowIfFrozen(); isAsync = value; }\n\t\t}\n\n\t\t// used to tell the difference between delegate {} and delegate () {}\n\t\tbool hasParameterList;\n\n\t\tpublic bool HasParameterList {\n\t\t\tget { return hasParameterList || Parameters.Any(); }\n\t\t\tset { ThrowIfFrozen(); hasParameterList = value; }\n\t\t}\n\n\t\tpublic CSharpTokenNode DelegateToken {\n\t\t\tget { return GetChildByRole(DelegateKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstNodeCollection<ParameterDeclaration> Parameters {\n\t\t\tget { return GetChildrenByRole(Roles.Parameter); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic BlockStatement Body {\n\t\t\tget { return GetChildByRole(Roles.Body); }\n\t\t\tset { SetChildByRole(Roles.Body, value); }\n\t\t}\n\n\t\tpublic AnonymousMethodExpression()\n\t\t{\n\t\t}\n\n\t\tpublic AnonymousMethodExpression(BlockStatement body, IEnumerable<ParameterDeclaration> parameters = null)\n\t\t{\n\t\t\tif (parameters != null)\n\t\t\t{\n\t\t\t\thasParameterList = true;\n\t\t\t\tforeach (var parameter in parameters)\n\t\t\t\t{\n\t\t\t\t\tAddChild(parameter, Roles.Parameter);\n\t\t\t\t}\n\t\t\t}\n\t\t\tAddChild(body, Roles.Body);\n\t\t}\n\n\t\tpublic AnonymousMethodExpression(BlockStatement body, params ParameterDeclaration[] parameters) : this(body, (IEnumerable<ParameterDeclaration>)parameters)\n\t\t{\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitAnonymousMethodExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitAnonymousMethodExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitAnonymousMethodExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tAnonymousMethodExpression o = other as AnonymousMethodExpression;\n\t\t\treturn o != null && this.IsAsync == o.IsAsync && this.HasParameterList == o.HasParameterList\n\t\t\t\t&& this.Parameters.DoMatch(o.Parameters, match) && this.Body.DoMatch(o.Body, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/AnonymousTypeCreateExpression.cs",
    "content": "// \n// AnonymousTypeCreateExpression.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2011 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// new { [ExpressionList] }\n\t/// </summary>\n\tpublic class AnonymousTypeCreateExpression : Expression\n\t{\n\t\tpublic readonly static TokenRole NewKeywordRole = new TokenRole(\"new\");\n\n\t\tpublic CSharpTokenNode NewToken {\n\t\t\tget { return GetChildByRole(NewKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstNodeCollection<Expression> Initializers {\n\t\t\tget { return GetChildrenByRole(Roles.Expression); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic AnonymousTypeCreateExpression()\n\t\t{\n\t\t}\n\n\t\tpublic AnonymousTypeCreateExpression(IEnumerable<Expression> initializers)\n\t\t{\n\t\t\tforeach (var ini in initializers)\n\t\t\t{\n\t\t\t\tAddChild(ini, Roles.Expression);\n\t\t\t}\n\t\t}\n\n\t\tpublic AnonymousTypeCreateExpression(params Expression[] initializer) : this((IEnumerable<Expression>)initializer)\n\t\t{\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitAnonymousTypeCreateExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitAnonymousTypeCreateExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitAnonymousTypeCreateExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tvar o = other as AnonymousTypeCreateExpression;\n\t\t\treturn o != null && this.Initializers.DoMatch(o.Initializers, match);\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/ArrayCreateExpression.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// new Type[Dimensions]\n\t/// </summary>\n\tpublic class ArrayCreateExpression : Expression\n\t{\n\t\tpublic readonly static TokenRole NewKeywordRole = new TokenRole(\"new\");\n\t\tpublic readonly static Role<ArraySpecifier> AdditionalArraySpecifierRole = new Role<ArraySpecifier>(\"AdditionalArraySpecifier\", null);\n\t\tpublic readonly static Role<ArrayInitializerExpression> InitializerRole = new Role<ArrayInitializerExpression>(\"Initializer\", ArrayInitializerExpression.Null);\n\n\t\tpublic CSharpTokenNode NewToken {\n\t\t\tget { return GetChildByRole(NewKeywordRole); }\n\t\t}\n\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic AstNodeCollection<Expression> Arguments {\n\t\t\tget { return GetChildrenByRole(Roles.Argument); }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets additional array ranks (those without size info).\n\t\t/// Empty for \"new int[5,1]\"; will contain a single element for \"new int[5][]\".\n\t\t/// </summary>\n\t\tpublic AstNodeCollection<ArraySpecifier> AdditionalArraySpecifiers {\n\t\t\tget { return GetChildrenByRole(AdditionalArraySpecifierRole); }\n\t\t}\n\n\t\tpublic ArrayInitializerExpression Initializer {\n\t\t\tget { return GetChildByRole(InitializerRole); }\n\t\t\tset { SetChildByRole(InitializerRole, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitArrayCreateExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitArrayCreateExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitArrayCreateExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tArrayCreateExpression o = other as ArrayCreateExpression;\n\t\t\treturn o != null && this.Type.DoMatch(o.Type, match)\n\t\t\t\t&& this.Arguments.DoMatch(o.Arguments, match)\n\t\t\t\t&& this.AdditionalArraySpecifiers.DoMatch(o.AdditionalArraySpecifiers, match)\n\t\t\t\t&& this.Initializer.DoMatch(o.Initializer, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/ArrayInitializerExpression.cs",
    "content": "// \n// ArrayInitializerExpression.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// { Elements }\n\t/// </summary>\n\tpublic class ArrayInitializerExpression : Expression\n\t{\n\t\t/// <summary>\n\t\t/// For ease of use purposes in the resolver the ast representation\n\t\t/// of { a, b, c }  is { {a}, {b}, {c} }.\n\t\t/// If IsSingleElement is true then this array initializer expression is a generated one.\n\t\t/// That has no meaning in the source code (and contains no brace tokens).\n\t\t/// </summary>\n\t\tpublic virtual bool IsSingleElement {\n\t\t\tget {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic ArrayInitializerExpression()\n\t\t{\n\t\t}\n\n\t\tpublic ArrayInitializerExpression(IEnumerable<Expression> elements)\n\t\t{\n\t\t\tthis.Elements.AddRange(elements);\n\t\t}\n\n\t\tpublic ArrayInitializerExpression(params Expression[] elements)\n\t\t{\n\t\t\tthis.Elements.AddRange(elements);\n\t\t}\n\n\t\t#region Null\n\t\tpublic new static readonly ArrayInitializerExpression Null = new NullArrayInitializerExpression();\n\n\t\tsealed class NullArrayInitializerExpression : ArrayInitializerExpression\n\t\t{\n\t\t\tpublic override bool IsNull {\n\t\t\t\tget {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn other == null || other.IsNull;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic CSharpTokenNode LBraceToken {\n\t\t\tget { return GetChildByRole(Roles.LBrace); }\n\t\t}\n\n\t\tpublic AstNodeCollection<Expression> Elements {\n\t\t\tget { return GetChildrenByRole(Roles.Expression); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RBraceToken {\n\t\t\tget { return GetChildByRole(Roles.RBrace); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitArrayInitializerExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitArrayInitializerExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitArrayInitializerExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tArrayInitializerExpression o = other as ArrayInitializerExpression;\n\t\t\treturn o != null && this.Elements.DoMatch(o.Elements, match);\n\t\t}\n\n\t\tpublic static ArrayInitializerExpression CreateSingleElementInitializer()\n\t\t{\n\t\t\treturn new SingleArrayInitializerExpression();\n\t\t}\n\t\t/// <summary>\n\t\t/// Single elements in array initializers are represented with this special class.\n\t\t/// </summary>\n\t\tclass SingleArrayInitializerExpression : ArrayInitializerExpression\n\t\t{\n\t\t\tpublic override bool IsSingleElement {\n\t\t\t\tget {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\t#region PatternPlaceholder\n\t\tpublic static implicit operator ArrayInitializerExpression(PatternMatching.Pattern pattern)\n\t\t{\n\t\t\treturn pattern != null ? new PatternPlaceholder(pattern) : null;\n\t\t}\n\n\t\tsealed class PatternPlaceholder : ArrayInitializerExpression, PatternMatching.INode\n\t\t{\n\t\t\treadonly PatternMatching.Pattern child;\n\n\t\t\tpublic PatternPlaceholder(PatternMatching.Pattern child)\n\t\t\t{\n\t\t\t\tthis.child = child;\n\t\t\t}\n\n\t\t\tpublic override NodeType NodeType {\n\t\t\t\tget { return NodeType.Pattern; }\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn child.DoMatch(other, match);\n\t\t\t}\n\n\t\t\tbool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)\n\t\t\t{\n\t\t\t\treturn child.DoMatchCollection(role, pos, match, backtrackingInfo);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/AsExpression.cs",
    "content": "// \n// AsExpression.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Expression as TypeReference\n\t/// </summary>\n\tpublic class AsExpression : Expression\n\t{\n\t\tpublic readonly static TokenRole AsKeywordRole = new TokenRole(\"as\");\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode AsToken {\n\t\t\tget { return GetChildByRole(AsKeywordRole); }\n\t\t}\n\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic AsExpression()\n\t\t{\n\t\t}\n\n\t\tpublic AsExpression(Expression expression, AstType type)\n\t\t{\n\t\t\tAddChild(expression, Roles.Expression);\n\t\t\tAddChild(type, Roles.Type);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitAsExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitAsExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitAsExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tAsExpression o = other as AsExpression;\n\t\t\treturn o != null && this.Expression.DoMatch(o.Expression, match) && this.Type.DoMatch(o.Type, match);\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/AssignmentExpression.cs",
    "content": "// \n// AssignmentExpression.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq.Expressions;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Left Operator= Right\n\t/// </summary>\n\tpublic class AssignmentExpression : Expression\n\t{\n\t\t// reuse roles from BinaryOperatorExpression\n\t\tpublic readonly static Role<Expression> LeftRole = BinaryOperatorExpression.LeftRole;\n\t\tpublic readonly static Role<Expression> RightRole = BinaryOperatorExpression.RightRole;\n\n\t\tpublic readonly static TokenRole AssignRole = new TokenRole(\"=\");\n\t\tpublic readonly static TokenRole AddRole = new TokenRole(\"+=\");\n\t\tpublic readonly static TokenRole SubtractRole = new TokenRole(\"-=\");\n\t\tpublic readonly static TokenRole MultiplyRole = new TokenRole(\"*=\");\n\t\tpublic readonly static TokenRole DivideRole = new TokenRole(\"/=\");\n\t\tpublic readonly static TokenRole ModulusRole = new TokenRole(\"%=\");\n\t\tpublic readonly static TokenRole ShiftLeftRole = new TokenRole(\"<<=\");\n\t\tpublic readonly static TokenRole ShiftRightRole = new TokenRole(\">>=\");\n\t\tpublic readonly static TokenRole UnsignedShiftRightRole = new TokenRole(\">>>=\");\n\t\tpublic readonly static TokenRole BitwiseAndRole = new TokenRole(\"&=\");\n\t\tpublic readonly static TokenRole BitwiseOrRole = new TokenRole(\"|=\");\n\t\tpublic readonly static TokenRole ExclusiveOrRole = new TokenRole(\"^=\");\n\n\t\tpublic AssignmentExpression()\n\t\t{\n\t\t}\n\n\t\tpublic AssignmentExpression(Expression left, Expression right)\n\t\t{\n\t\t\tthis.Left = left;\n\t\t\tthis.Right = right;\n\t\t}\n\n\t\tpublic AssignmentExpression(Expression left, AssignmentOperatorType op, Expression right)\n\t\t{\n\t\t\tthis.Left = left;\n\t\t\tthis.Operator = op;\n\t\t\tthis.Right = right;\n\t\t}\n\n\t\tpublic AssignmentOperatorType Operator {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic Expression Left {\n\t\t\tget { return GetChildByRole(LeftRole); }\n\t\t\tset { SetChildByRole(LeftRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode OperatorToken {\n\t\t\tget { return GetChildByRole(GetOperatorRole(Operator)); }\n\t\t}\n\n\t\tpublic Expression Right {\n\t\t\tget { return GetChildByRole(RightRole); }\n\t\t\tset { SetChildByRole(RightRole, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitAssignmentExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitAssignmentExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitAssignmentExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tAssignmentExpression o = other as AssignmentExpression;\n\t\t\treturn o != null && (this.Operator == AssignmentOperatorType.Any || this.Operator == o.Operator)\n\t\t\t\t&& this.Left.DoMatch(o.Left, match) && this.Right.DoMatch(o.Right, match);\n\t\t}\n\n\t\tpublic static TokenRole GetOperatorRole(AssignmentOperatorType op)\n\t\t{\n\t\t\tswitch (op)\n\t\t\t{\n\t\t\t\tcase AssignmentOperatorType.Assign:\n\t\t\t\t\treturn AssignRole;\n\t\t\t\tcase AssignmentOperatorType.Add:\n\t\t\t\t\treturn AddRole;\n\t\t\t\tcase AssignmentOperatorType.Subtract:\n\t\t\t\t\treturn SubtractRole;\n\t\t\t\tcase AssignmentOperatorType.Multiply:\n\t\t\t\t\treturn MultiplyRole;\n\t\t\t\tcase AssignmentOperatorType.Divide:\n\t\t\t\t\treturn DivideRole;\n\t\t\t\tcase AssignmentOperatorType.Modulus:\n\t\t\t\t\treturn ModulusRole;\n\t\t\t\tcase AssignmentOperatorType.ShiftLeft:\n\t\t\t\t\treturn ShiftLeftRole;\n\t\t\t\tcase AssignmentOperatorType.ShiftRight:\n\t\t\t\t\treturn ShiftRightRole;\n\t\t\t\tcase AssignmentOperatorType.UnsignedShiftRight:\n\t\t\t\t\treturn UnsignedShiftRightRole;\n\t\t\t\tcase AssignmentOperatorType.BitwiseAnd:\n\t\t\t\t\treturn BitwiseAndRole;\n\t\t\t\tcase AssignmentOperatorType.BitwiseOr:\n\t\t\t\t\treturn BitwiseOrRole;\n\t\t\t\tcase AssignmentOperatorType.ExclusiveOr:\n\t\t\t\t\treturn ExclusiveOrRole;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException(\"Invalid value for AssignmentOperatorType\");\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the binary operator for the specified compound assignment operator.\n\t\t/// Returns null if 'op' is not a compound assignment.\n\t\t/// </summary>\n\t\tpublic static BinaryOperatorType? GetCorrespondingBinaryOperator(AssignmentOperatorType op)\n\t\t{\n\t\t\tswitch (op)\n\t\t\t{\n\t\t\t\tcase AssignmentOperatorType.Assign:\n\t\t\t\t\treturn null;\n\t\t\t\tcase AssignmentOperatorType.Add:\n\t\t\t\t\treturn BinaryOperatorType.Add;\n\t\t\t\tcase AssignmentOperatorType.Subtract:\n\t\t\t\t\treturn BinaryOperatorType.Subtract;\n\t\t\t\tcase AssignmentOperatorType.Multiply:\n\t\t\t\t\treturn BinaryOperatorType.Multiply;\n\t\t\t\tcase AssignmentOperatorType.Divide:\n\t\t\t\t\treturn BinaryOperatorType.Divide;\n\t\t\t\tcase AssignmentOperatorType.Modulus:\n\t\t\t\t\treturn BinaryOperatorType.Modulus;\n\t\t\t\tcase AssignmentOperatorType.ShiftLeft:\n\t\t\t\t\treturn BinaryOperatorType.ShiftLeft;\n\t\t\t\tcase AssignmentOperatorType.ShiftRight:\n\t\t\t\t\treturn BinaryOperatorType.ShiftRight;\n\t\t\t\tcase AssignmentOperatorType.UnsignedShiftRight:\n\t\t\t\t\treturn BinaryOperatorType.UnsignedShiftRight;\n\t\t\t\tcase AssignmentOperatorType.BitwiseAnd:\n\t\t\t\t\treturn BinaryOperatorType.BitwiseAnd;\n\t\t\t\tcase AssignmentOperatorType.BitwiseOr:\n\t\t\t\t\treturn BinaryOperatorType.BitwiseOr;\n\t\t\t\tcase AssignmentOperatorType.ExclusiveOr:\n\t\t\t\t\treturn BinaryOperatorType.ExclusiveOr;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException(\"Invalid value for AssignmentOperatorType\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static ExpressionType GetLinqNodeType(AssignmentOperatorType op, bool checkForOverflow)\n\t\t{\n\t\t\tswitch (op)\n\t\t\t{\n\t\t\t\tcase AssignmentOperatorType.Assign:\n\t\t\t\t\treturn ExpressionType.Assign;\n\t\t\t\tcase AssignmentOperatorType.Add:\n\t\t\t\t\treturn checkForOverflow ? ExpressionType.AddAssignChecked : ExpressionType.AddAssign;\n\t\t\t\tcase AssignmentOperatorType.Subtract:\n\t\t\t\t\treturn checkForOverflow ? ExpressionType.SubtractAssignChecked : ExpressionType.SubtractAssign;\n\t\t\t\tcase AssignmentOperatorType.Multiply:\n\t\t\t\t\treturn checkForOverflow ? ExpressionType.MultiplyAssignChecked : ExpressionType.MultiplyAssign;\n\t\t\t\tcase AssignmentOperatorType.Divide:\n\t\t\t\t\treturn ExpressionType.DivideAssign;\n\t\t\t\tcase AssignmentOperatorType.Modulus:\n\t\t\t\t\treturn ExpressionType.ModuloAssign;\n\t\t\t\tcase AssignmentOperatorType.ShiftLeft:\n\t\t\t\t\treturn ExpressionType.LeftShiftAssign;\n\t\t\t\tcase AssignmentOperatorType.ShiftRight:\n\t\t\t\t\treturn ExpressionType.RightShiftAssign;\n\t\t\t\tcase AssignmentOperatorType.UnsignedShiftRight:\n\t\t\t\t\treturn ExpressionType.Extension;\n\t\t\t\tcase AssignmentOperatorType.BitwiseAnd:\n\t\t\t\t\treturn ExpressionType.AndAssign;\n\t\t\t\tcase AssignmentOperatorType.BitwiseOr:\n\t\t\t\t\treturn ExpressionType.OrAssign;\n\t\t\t\tcase AssignmentOperatorType.ExclusiveOr:\n\t\t\t\t\treturn ExpressionType.ExclusiveOrAssign;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException(\"Invalid value for AssignmentOperatorType\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static AssignmentOperatorType? GetAssignmentOperatorTypeFromExpressionType(ExpressionType expressionType)\n\t\t{\n\t\t\tswitch (expressionType)\n\t\t\t{\n\t\t\t\tcase ExpressionType.AddAssign:\n\t\t\t\tcase ExpressionType.AddAssignChecked:\n\t\t\t\t\treturn AssignmentOperatorType.Add;\n\t\t\t\tcase ExpressionType.AndAssign:\n\t\t\t\t\treturn AssignmentOperatorType.BitwiseAnd;\n\t\t\t\tcase ExpressionType.DivideAssign:\n\t\t\t\t\treturn AssignmentOperatorType.Divide;\n\t\t\t\tcase ExpressionType.ExclusiveOrAssign:\n\t\t\t\t\treturn AssignmentOperatorType.ExclusiveOr;\n\t\t\t\tcase ExpressionType.LeftShiftAssign:\n\t\t\t\t\treturn AssignmentOperatorType.ShiftLeft;\n\t\t\t\tcase ExpressionType.ModuloAssign:\n\t\t\t\t\treturn AssignmentOperatorType.Modulus;\n\t\t\t\tcase ExpressionType.MultiplyAssign:\n\t\t\t\tcase ExpressionType.MultiplyAssignChecked:\n\t\t\t\t\treturn AssignmentOperatorType.Multiply;\n\t\t\t\tcase ExpressionType.OrAssign:\n\t\t\t\t\treturn AssignmentOperatorType.BitwiseOr;\n\t\t\t\tcase ExpressionType.RightShiftAssign:\n\t\t\t\t\treturn AssignmentOperatorType.ShiftRight;\n\t\t\t\tcase ExpressionType.SubtractAssign:\n\t\t\t\tcase ExpressionType.SubtractAssignChecked:\n\t\t\t\t\treturn AssignmentOperatorType.Subtract;\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic enum AssignmentOperatorType\n\t{\n\t\t/// <summary>left = right</summary>\n\t\tAssign,\n\n\t\t/// <summary>left += right</summary>\n\t\tAdd,\n\t\t/// <summary>left -= right</summary>\n\t\tSubtract,\n\t\t/// <summary>left *= right</summary>\n\t\tMultiply,\n\t\t/// <summary>left /= right</summary>\n\t\tDivide,\n\t\t/// <summary>left %= right</summary>\n\t\tModulus,\n\n\t\t/// <summary>left &lt;&lt;= right</summary>\n\t\tShiftLeft,\n\t\t/// <summary>left >>= right</summary>\n\t\tShiftRight,\n\t\t/// <summary>left >>>= right</summary>\n\t\tUnsignedShiftRight,\n\n\t\t/// <summary>left &amp;= right</summary>\n\t\tBitwiseAnd,\n\t\t/// <summary>left |= right</summary>\n\t\tBitwiseOr,\n\t\t/// <summary>left ^= right</summary>\n\t\tExclusiveOr,\n\n\t\t/// <summary>Any operator (for pattern matching)</summary>\n\t\tAny\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/BaseReferenceExpression.cs",
    "content": "// \n// BaseReferenceExpression.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// base\n\t/// </summary>\n\tpublic class BaseReferenceExpression : Expression\n\t{\n\t\tpublic TextLocation Location {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic override TextLocation StartLocation {\n\t\t\tget {\n\t\t\t\treturn Location;\n\t\t\t}\n\t\t}\n\t\tpublic override TextLocation EndLocation {\n\t\t\tget {\n\t\t\t\treturn new TextLocation(Location.Line, Location.Column + \"base\".Length);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitBaseReferenceExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitBaseReferenceExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitBaseReferenceExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tBaseReferenceExpression o = other as BaseReferenceExpression;\n\t\t\treturn o != null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/BinaryOperatorExpression.cs",
    "content": "// \n// BinaryOperatorExpression.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System;\nusing System.Linq.Expressions;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Left Operator Right\n\t/// </summary>\n\tpublic class BinaryOperatorExpression : Expression\n\t{\n\t\tpublic readonly static TokenRole BitwiseAndRole = new TokenRole(\"&\");\n\t\tpublic readonly static TokenRole BitwiseOrRole = new TokenRole(\"|\");\n\t\tpublic readonly static TokenRole ConditionalAndRole = new TokenRole(\"&&\");\n\t\tpublic readonly static TokenRole ConditionalOrRole = new TokenRole(\"||\");\n\t\tpublic readonly static TokenRole ExclusiveOrRole = new TokenRole(\"^\");\n\t\tpublic readonly static TokenRole GreaterThanRole = new TokenRole(\">\");\n\t\tpublic readonly static TokenRole GreaterThanOrEqualRole = new TokenRole(\">=\");\n\t\tpublic readonly static TokenRole EqualityRole = new TokenRole(\"==\");\n\t\tpublic readonly static TokenRole InEqualityRole = new TokenRole(\"!=\");\n\t\tpublic readonly static TokenRole LessThanRole = new TokenRole(\"<\");\n\t\tpublic readonly static TokenRole LessThanOrEqualRole = new TokenRole(\"<=\");\n\t\tpublic readonly static TokenRole AddRole = new TokenRole(\"+\");\n\t\tpublic readonly static TokenRole SubtractRole = new TokenRole(\"-\");\n\t\tpublic readonly static TokenRole MultiplyRole = new TokenRole(\"*\");\n\t\tpublic readonly static TokenRole DivideRole = new TokenRole(\"/\");\n\t\tpublic readonly static TokenRole ModulusRole = new TokenRole(\"%\");\n\t\tpublic readonly static TokenRole ShiftLeftRole = new TokenRole(\"<<\");\n\t\tpublic readonly static TokenRole ShiftRightRole = new TokenRole(\">>\");\n\t\tpublic readonly static TokenRole UnsignedShiftRightRole = new TokenRole(\">>>\");\n\t\tpublic readonly static TokenRole NullCoalescingRole = new TokenRole(\"??\");\n\t\tpublic readonly static TokenRole RangeRole = new TokenRole(\"..\");\n\t\tpublic readonly static TokenRole IsKeywordRole = IsExpression.IsKeywordRole;\n\n\t\tpublic readonly static Role<Expression> LeftRole = new Role<Expression>(\"Left\", Expression.Null);\n\t\tpublic readonly static Role<Expression> RightRole = new Role<Expression>(\"Right\", Expression.Null);\n\n\t\tpublic BinaryOperatorExpression()\n\t\t{\n\t\t}\n\n\t\tpublic BinaryOperatorExpression(Expression left, BinaryOperatorType op, Expression right)\n\t\t{\n\t\t\tthis.Left = left;\n\t\t\tthis.Operator = op;\n\t\t\tthis.Right = right;\n\t\t}\n\n\t\tpublic BinaryOperatorType Operator {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic Expression Left {\n\t\t\tget { return GetChildByRole(LeftRole); }\n\t\t\tset { SetChildByRole(LeftRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode OperatorToken {\n\t\t\tget { return GetChildByRole(GetOperatorRole(Operator)); }\n\t\t}\n\n\t\tpublic Expression Right {\n\t\t\tget { return GetChildByRole(RightRole); }\n\t\t\tset { SetChildByRole(RightRole, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitBinaryOperatorExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitBinaryOperatorExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitBinaryOperatorExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tBinaryOperatorExpression o = other as BinaryOperatorExpression;\n\t\t\treturn o != null && (this.Operator == BinaryOperatorType.Any || this.Operator == o.Operator)\n\t\t\t\t&& this.Left.DoMatch(o.Left, match) && this.Right.DoMatch(o.Right, match);\n\t\t}\n\n\t\tpublic static TokenRole GetOperatorRole(BinaryOperatorType op)\n\t\t{\n\t\t\tswitch (op)\n\t\t\t{\n\t\t\t\tcase BinaryOperatorType.BitwiseAnd:\n\t\t\t\t\treturn BitwiseAndRole;\n\t\t\t\tcase BinaryOperatorType.BitwiseOr:\n\t\t\t\t\treturn BitwiseOrRole;\n\t\t\t\tcase BinaryOperatorType.ConditionalAnd:\n\t\t\t\t\treturn ConditionalAndRole;\n\t\t\t\tcase BinaryOperatorType.ConditionalOr:\n\t\t\t\t\treturn ConditionalOrRole;\n\t\t\t\tcase BinaryOperatorType.ExclusiveOr:\n\t\t\t\t\treturn ExclusiveOrRole;\n\t\t\t\tcase BinaryOperatorType.GreaterThan:\n\t\t\t\t\treturn GreaterThanRole;\n\t\t\t\tcase BinaryOperatorType.GreaterThanOrEqual:\n\t\t\t\t\treturn GreaterThanOrEqualRole;\n\t\t\t\tcase BinaryOperatorType.Equality:\n\t\t\t\t\treturn EqualityRole;\n\t\t\t\tcase BinaryOperatorType.InEquality:\n\t\t\t\t\treturn InEqualityRole;\n\t\t\t\tcase BinaryOperatorType.LessThan:\n\t\t\t\t\treturn LessThanRole;\n\t\t\t\tcase BinaryOperatorType.LessThanOrEqual:\n\t\t\t\t\treturn LessThanOrEqualRole;\n\t\t\t\tcase BinaryOperatorType.Add:\n\t\t\t\t\treturn AddRole;\n\t\t\t\tcase BinaryOperatorType.Subtract:\n\t\t\t\t\treturn SubtractRole;\n\t\t\t\tcase BinaryOperatorType.Multiply:\n\t\t\t\t\treturn MultiplyRole;\n\t\t\t\tcase BinaryOperatorType.Divide:\n\t\t\t\t\treturn DivideRole;\n\t\t\t\tcase BinaryOperatorType.Modulus:\n\t\t\t\t\treturn ModulusRole;\n\t\t\t\tcase BinaryOperatorType.ShiftLeft:\n\t\t\t\t\treturn ShiftLeftRole;\n\t\t\t\tcase BinaryOperatorType.ShiftRight:\n\t\t\t\t\treturn ShiftRightRole;\n\t\t\t\tcase BinaryOperatorType.UnsignedShiftRight:\n\t\t\t\t\treturn UnsignedShiftRightRole;\n\t\t\t\tcase BinaryOperatorType.NullCoalescing:\n\t\t\t\t\treturn NullCoalescingRole;\n\t\t\t\tcase BinaryOperatorType.Range:\n\t\t\t\t\treturn RangeRole;\n\t\t\t\tcase BinaryOperatorType.IsPattern:\n\t\t\t\t\treturn IsKeywordRole;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException(\"Invalid value for BinaryOperatorType\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static ExpressionType GetLinqNodeType(BinaryOperatorType op, bool checkForOverflow)\n\t\t{\n\t\t\tswitch (op)\n\t\t\t{\n\t\t\t\tcase BinaryOperatorType.BitwiseAnd:\n\t\t\t\t\treturn ExpressionType.And;\n\t\t\t\tcase BinaryOperatorType.BitwiseOr:\n\t\t\t\t\treturn ExpressionType.Or;\n\t\t\t\tcase BinaryOperatorType.ConditionalAnd:\n\t\t\t\t\treturn ExpressionType.AndAlso;\n\t\t\t\tcase BinaryOperatorType.ConditionalOr:\n\t\t\t\t\treturn ExpressionType.OrElse;\n\t\t\t\tcase BinaryOperatorType.ExclusiveOr:\n\t\t\t\t\treturn ExpressionType.ExclusiveOr;\n\t\t\t\tcase BinaryOperatorType.GreaterThan:\n\t\t\t\t\treturn ExpressionType.GreaterThan;\n\t\t\t\tcase BinaryOperatorType.GreaterThanOrEqual:\n\t\t\t\t\treturn ExpressionType.GreaterThanOrEqual;\n\t\t\t\tcase BinaryOperatorType.Equality:\n\t\t\t\t\treturn ExpressionType.Equal;\n\t\t\t\tcase BinaryOperatorType.InEquality:\n\t\t\t\t\treturn ExpressionType.NotEqual;\n\t\t\t\tcase BinaryOperatorType.LessThan:\n\t\t\t\t\treturn ExpressionType.LessThan;\n\t\t\t\tcase BinaryOperatorType.LessThanOrEqual:\n\t\t\t\t\treturn ExpressionType.LessThanOrEqual;\n\t\t\t\tcase BinaryOperatorType.Add:\n\t\t\t\t\treturn checkForOverflow ? ExpressionType.AddChecked : ExpressionType.Add;\n\t\t\t\tcase BinaryOperatorType.Subtract:\n\t\t\t\t\treturn checkForOverflow ? ExpressionType.SubtractChecked : ExpressionType.Subtract;\n\t\t\t\tcase BinaryOperatorType.Multiply:\n\t\t\t\t\treturn checkForOverflow ? ExpressionType.MultiplyChecked : ExpressionType.Multiply;\n\t\t\t\tcase BinaryOperatorType.Divide:\n\t\t\t\t\treturn ExpressionType.Divide;\n\t\t\t\tcase BinaryOperatorType.Modulus:\n\t\t\t\t\treturn ExpressionType.Modulo;\n\t\t\t\tcase BinaryOperatorType.ShiftLeft:\n\t\t\t\t\treturn ExpressionType.LeftShift;\n\t\t\t\tcase BinaryOperatorType.ShiftRight:\n\t\t\t\t\treturn ExpressionType.RightShift;\n\t\t\t\tcase BinaryOperatorType.NullCoalescing:\n\t\t\t\t\treturn ExpressionType.Coalesce;\n\t\t\t\tcase BinaryOperatorType.Range:\n\t\t\t\tcase BinaryOperatorType.UnsignedShiftRight:\n\t\t\t\t\treturn ExpressionType.Extension;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException(\"Invalid value for BinaryOperatorType\");\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic enum BinaryOperatorType\n\t{\n\t\t/// <summary>\n\t\t/// Any binary operator (used in pattern matching)\n\t\t/// </summary>\n\t\tAny,\n\n\t\t// We avoid 'logical or' on purpose, because it's not clear if that refers to the bitwise\n\t\t// or to the short-circuiting (conditional) operator:\n\t\t// MCS and old NRefactory used bitwise='|', logical='||'\n\t\t// but the C# spec uses logical='|', conditional='||'\n\t\t/// <summary>left &amp; right</summary>\n\t\tBitwiseAnd,\n\t\t/// <summary>left | right</summary>\n\t\tBitwiseOr,\n\t\t/// <summary>left &amp;&amp; right</summary>\n\t\tConditionalAnd,\n\t\t/// <summary>left || right</summary>\n\t\tConditionalOr,\n\t\t/// <summary>left ^ right</summary>\n\t\tExclusiveOr,\n\n\t\t/// <summary>left &gt; right</summary>\n\t\tGreaterThan,\n\t\t/// <summary>left &gt;= right</summary>\n\t\tGreaterThanOrEqual,\n\t\t/// <summary>left == right</summary>\n\t\tEquality,\n\t\t/// <summary>left != right</summary>\n\t\tInEquality,\n\t\t/// <summary>left &lt; right</summary>\n\t\tLessThan,\n\t\t/// <summary>left &lt;= right</summary>\n\t\tLessThanOrEqual,\n\n\t\t/// <summary>left + right</summary>\n\t\tAdd,\n\t\t/// <summary>left - right</summary>\n\t\tSubtract,\n\t\t/// <summary>left * right</summary>\n\t\tMultiply,\n\t\t/// <summary>left / right</summary>\n\t\tDivide,\n\t\t/// <summary>left % right</summary>\n\t\tModulus,\n\n\t\t/// <summary>left &lt;&lt; right</summary>\n\t\tShiftLeft,\n\t\t/// <summary>left &gt;&gt; right</summary>\n\t\tShiftRight,\n\t\t/// <summary>left &gt;&gt;&gt; right</summary>\n\t\tUnsignedShiftRight,\n\n\t\t/// <summary>left ?? right</summary>\n\t\tNullCoalescing,\n\t\t/// <summary>left .. right</summary>\n\t\t/// <remarks>left and right are optional = may be Expression.Null</remarks>\n\t\tRange,\n\n\t\t/// <summary>left is right</summary>\n\t\t/// <remarks>right must be a pattern</remarks>\n\t\tIsPattern,\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/CastExpression.cs",
    "content": "// \n// CastExpression.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// (CastTo)Expression\n\t/// </summary>\n\tpublic class CastExpression : Expression\n\t{\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic CastExpression()\n\t\t{\n\t\t}\n\n\t\tpublic CastExpression(AstType castToType, Expression expression)\n\t\t{\n\t\t\tAddChild(castToType, Roles.Type);\n\t\t\tAddChild(expression, Roles.Expression);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitCastExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitCastExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitCastExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tCastExpression o = other as CastExpression;\n\t\t\treturn o != null && this.Type.DoMatch(o.Type, match) && this.Expression.DoMatch(o.Expression, match);\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/CheckedExpression.cs",
    "content": "// \n// CheckedExpression.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// checked(Expression)\n\t/// </summary>\n\tpublic class CheckedExpression : Expression\n\t{\n\t\tpublic readonly static TokenRole CheckedKeywordRole = new TokenRole(\"checked\");\n\n\t\tpublic CSharpTokenNode CheckedToken {\n\t\t\tget { return GetChildByRole(CheckedKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic CheckedExpression()\n\t\t{\n\t\t}\n\n\t\tpublic CheckedExpression(Expression expression)\n\t\t{\n\t\t\tAddChild(expression, Roles.Expression);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitCheckedExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitCheckedExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitCheckedExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tCheckedExpression o = other as CheckedExpression;\n\t\t\treturn o != null && this.Expression.DoMatch(o.Expression, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/ConditionalExpression.cs",
    "content": "// \n// ConditionalExpression.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Condition ? TrueExpression : FalseExpression\n\t/// </summary>\n\tpublic class ConditionalExpression : Expression\n\t{\n\t\tpublic readonly static Role<Expression> ConditionRole = Roles.Condition;\n\t\tpublic readonly static TokenRole QuestionMarkRole = new TokenRole(\"?\");\n\t\tpublic readonly static Role<Expression> TrueRole = new Role<Expression>(\"True\", Expression.Null);\n\t\tpublic readonly static TokenRole ColonRole = Roles.Colon;\n\t\tpublic readonly static Role<Expression> FalseRole = new Role<Expression>(\"False\", Expression.Null);\n\n\t\tpublic Expression Condition {\n\t\t\tget { return GetChildByRole(ConditionRole); }\n\t\t\tset { SetChildByRole(ConditionRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode QuestionMarkToken {\n\t\t\tget { return GetChildByRole(QuestionMarkRole); }\n\t\t}\n\n\t\tpublic Expression TrueExpression {\n\t\t\tget { return GetChildByRole(TrueRole); }\n\t\t\tset { SetChildByRole(TrueRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode ColonToken {\n\t\t\tget { return GetChildByRole(ColonRole); }\n\t\t}\n\n\t\tpublic Expression FalseExpression {\n\t\t\tget { return GetChildByRole(FalseRole); }\n\t\t\tset { SetChildByRole(FalseRole, value); }\n\t\t}\n\n\t\tpublic ConditionalExpression()\n\t\t{\n\t\t}\n\n\t\tpublic ConditionalExpression(Expression condition, Expression trueExpression, Expression falseExpression)\n\t\t{\n\t\t\tAddChild(condition, ConditionRole);\n\t\t\tAddChild(trueExpression, TrueRole);\n\t\t\tAddChild(falseExpression, FalseRole);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitConditionalExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitConditionalExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitConditionalExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tConditionalExpression o = other as ConditionalExpression;\n\t\t\treturn o != null && this.Condition.DoMatch(o.Condition, match) && this.TrueExpression.DoMatch(o.TrueExpression, match) && this.FalseExpression.DoMatch(o.FalseExpression, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/DeclarationExpression.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// TypeName VariableDesignation\n\t/// </summary>\n\tpublic class DeclarationExpression : Expression\n\t{\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic VariableDesignation Designation {\n\t\t\tget { return GetChildByRole(Roles.VariableDesignationRole); }\n\t\t\tset { SetChildByRole(Roles.VariableDesignationRole, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDeclarationExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDeclarationExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitDeclarationExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, Match match)\n\t\t{\n\t\t\treturn other is DeclarationExpression o\n\t\t\t\t&& Type.DoMatch(o.Type, match)\n\t\t\t\t&& Designation.DoMatch(o.Designation, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/DefaultValueExpression.cs",
    "content": "// \n// DefaultValueExpression.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// default(Type)\n\t/// </summary>\n\tpublic class DefaultValueExpression : Expression\n\t{\n\t\tpublic readonly static TokenRole DefaultKeywordRole = new TokenRole(\"default\");\n\n\t\tpublic CSharpTokenNode DefaultToken {\n\t\t\tget { return GetChildByRole(DefaultKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic DefaultValueExpression()\n\t\t{\n\t\t}\n\n\t\tpublic DefaultValueExpression(AstType type)\n\t\t{\n\t\t\tAddChild(type, Roles.Type);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDefaultValueExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDefaultValueExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitDefaultValueExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tDefaultValueExpression o = other as DefaultValueExpression;\n\t\t\treturn o != null && this.Type.DoMatch(o.Type, match);\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/DirectionExpression.cs",
    "content": "// \n// DirectionExpression.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic enum FieldDirection\n\t{\n\t\tNone,\n\t\tOut,\n\t\tRef,\n\t\tIn\n\t}\n\n\t/// <summary>\n\t/// ref Expression\n\t/// </summary>\n\tpublic class DirectionExpression : Expression\n\t{\n\t\tpublic readonly static TokenRole RefKeywordRole = new TokenRole(\"ref\");\n\t\tpublic readonly static TokenRole OutKeywordRole = new TokenRole(\"out\");\n\t\tpublic readonly static TokenRole InKeywordRole = new TokenRole(\"in\");\n\n\t\tpublic FieldDirection FieldDirection {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic CSharpTokenNode FieldDirectionToken {\n\t\t\tget {\n\t\t\t\tswitch (FieldDirection)\n\t\t\t\t{\n\t\t\t\t\tcase FieldDirection.Ref:\n\t\t\t\t\t\treturn GetChildByRole(RefKeywordRole);\n\t\t\t\t\tcase FieldDirection.In:\n\t\t\t\t\t\treturn GetChildByRole(InKeywordRole);\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn GetChildByRole(OutKeywordRole);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic DirectionExpression()\n\t\t{\n\t\t}\n\n\t\tpublic DirectionExpression(FieldDirection direction, Expression expression)\n\t\t{\n\t\t\tthis.FieldDirection = direction;\n\t\t\tAddChild(expression, Roles.Expression);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDirectionExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDirectionExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitDirectionExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tDirectionExpression o = other as DirectionExpression;\n\t\t\treturn o != null && this.FieldDirection == o.FieldDirection && this.Expression.DoMatch(o.Expression, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/ErrorExpression.cs",
    "content": "// \n// ErrorExpression.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@xamarin.com>\n// \n// Copyright (c) 2011 Xamarin Inc.\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\nusing System;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class ErrorExpression : Expression\n\t{\n\t\tpublic TextLocation Location { get; set; }\n\n\t\tpublic override TextLocation StartLocation {\n\t\t\tget {\n\t\t\t\treturn Location;\n\t\t\t}\n\t\t}\n\n\t\tpublic override TextLocation EndLocation {\n\t\t\tget {\n\t\t\t\treturn Location;\n\t\t\t}\n\t\t}\n\n\t\tpublic string Error {\n\t\t\tget;\n\t\t\tprivate set;\n\t\t}\n\n\t\tpublic ErrorExpression()\n\t\t{\n\t\t}\n\n\t\tpublic ErrorExpression(string error)\n\t\t{\n\t\t\tAddChild(new Comment(error, CommentType.MultiLine), Roles.Comment);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitErrorNode(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitErrorNode(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitErrorNode(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tvar o = other as ErrorExpression;\n\t\t\treturn o != null;\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/Expression.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Base class for expressions.\n\t/// </summary>\n\t/// <remarks>\n\t/// This class is useful even though it doesn't provide any additional functionality:\n\t/// It can be used to communicate more information in APIs, e.g. \"this subnode will always be an expression\"\n\t/// </remarks>\n\tpublic abstract class Expression : AstNode\n\t{\n\t\t#region Null\n\t\tpublic new static readonly Expression Null = new NullExpression();\n\n\t\tsealed class NullExpression : Expression\n\t\t{\n\t\t\tpublic override bool IsNull {\n\t\t\t\tget {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn other == null || other.IsNull;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region PatternPlaceholder\n\t\tpublic static implicit operator Expression(PatternMatching.Pattern pattern)\n\t\t{\n\t\t\treturn pattern != null ? new PatternPlaceholder(pattern) : null;\n\t\t}\n\n\t\tsealed class PatternPlaceholder : Expression, PatternMatching.INode\n\t\t{\n\t\t\treadonly PatternMatching.Pattern child;\n\n\t\t\tpublic PatternPlaceholder(PatternMatching.Pattern child)\n\t\t\t{\n\t\t\t\tthis.child = child;\n\t\t\t}\n\n\t\t\tpublic override NodeType NodeType {\n\t\t\t\tget { return NodeType.Pattern; }\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn child.DoMatch(other, match);\n\t\t\t}\n\n\t\t\tbool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)\n\t\t\t{\n\t\t\t\treturn child.DoMatchCollection(role, pos, match, backtrackingInfo);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget {\n\t\t\t\treturn NodeType.Expression;\n\t\t\t}\n\t\t}\n\n\t\tpublic new Expression Clone()\n\t\t{\n\t\t\treturn (Expression)base.Clone();\n\t\t}\n\n\t\tpublic Expression ReplaceWith(Func<Expression, Expression> replaceFunction)\n\t\t{\n\t\t\tif (replaceFunction == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(replaceFunction));\n\t\t\treturn (Expression)base.ReplaceWith(node => replaceFunction((Expression)node));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/IdentifierExpression.cs",
    "content": "// \n// IdentifierExpression.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class IdentifierExpression : Expression\n\t{\n\t\tpublic IdentifierExpression()\n\t\t{\n\t\t}\n\n\t\tpublic IdentifierExpression(string identifier)\n\t\t{\n\t\t\tthis.Identifier = identifier;\n\t\t}\n\n\t\tpublic IdentifierExpression(string identifier, TextLocation location)\n\t\t{\n\t\t\tSetChildByRole(Roles.Identifier, Decompiler.CSharp.Syntax.Identifier.Create(identifier, location));\n\t\t}\n\n\t\tpublic string Identifier {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, Decompiler.CSharp.Syntax.Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier IdentifierToken {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, value);\n\t\t\t}\n\t\t}\n\n\t\tpublic AstNodeCollection<AstType> TypeArguments {\n\t\t\tget { return GetChildrenByRole(Roles.TypeArgument); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitIdentifierExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitIdentifierExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitIdentifierExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tIdentifierExpression o = other as IdentifierExpression;\n\t\t\treturn o != null && MatchString(this.Identifier, o.Identifier) && this.TypeArguments.DoMatch(o.TypeArguments, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/IndexerExpression.cs",
    "content": "// \n// IndexerExpression.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Target[Arguments]\n\t/// </summary>\n\tpublic class IndexerExpression : Expression\n\t{\n\t\tpublic Expression Target {\n\t\t\tget { return GetChildByRole(Roles.TargetExpression); }\n\t\t\tset { SetChildByRole(Roles.TargetExpression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LBracketToken {\n\t\t\tget { return GetChildByRole(Roles.LBracket); }\n\t\t}\n\n\t\tpublic AstNodeCollection<Expression> Arguments {\n\t\t\tget { return GetChildrenByRole<Expression>(Roles.Argument); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RBracketToken {\n\t\t\tget { return GetChildByRole(Roles.RBracket); }\n\t\t}\n\n\t\tpublic IndexerExpression()\n\t\t{\n\t\t}\n\n\t\tpublic IndexerExpression(Expression target, IEnumerable<Expression> arguments)\n\t\t{\n\t\t\tAddChild(target, Roles.TargetExpression);\n\t\t\tif (arguments != null)\n\t\t\t{\n\t\t\t\tforeach (var arg in arguments)\n\t\t\t\t{\n\t\t\t\t\tAddChild(arg, Roles.Argument);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic IndexerExpression(Expression target, params Expression[] arguments) : this(target, (IEnumerable<Expression>)arguments)\n\t\t{\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitIndexerExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitIndexerExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitIndexerExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tIndexerExpression o = other as IndexerExpression;\n\t\t\treturn o != null && this.Target.DoMatch(o.Target, match) && this.Arguments.DoMatch(o.Arguments, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/InterpolatedStringExpression.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class InterpolatedStringExpression : Expression\n\t{\n\t\tpublic static readonly TokenRole OpenQuote = new TokenRole(\"$\\\"\");\n\t\tpublic static readonly TokenRole CloseQuote = new TokenRole(\"\\\"\");\n\n\t\tpublic AstNodeCollection<InterpolatedStringContent> Content {\n\t\t\tget { return GetChildrenByRole(InterpolatedStringContent.Role); }\n\t\t}\n\n\t\tpublic InterpolatedStringExpression()\n\t\t{\n\n\t\t}\n\n\t\tpublic InterpolatedStringExpression(IList<InterpolatedStringContent> content)\n\t\t{\n\t\t\tContent.AddRange(content);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitInterpolatedStringExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitInterpolatedStringExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitInterpolatedStringExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, Match match)\n\t\t{\n\t\t\tInterpolatedStringExpression o = other as InterpolatedStringExpression;\n\t\t\treturn o != null && !o.IsNull && this.Content.DoMatch(o.Content, match);\n\t\t}\n\t}\n\n\tpublic abstract class InterpolatedStringContent : AstNode\n\t{\n\t\t#region Null\n\t\tpublic new static readonly InterpolatedStringContent Null = new NullInterpolatedStringContent();\n\n\t\tsealed class NullInterpolatedStringContent : InterpolatedStringContent\n\t\t{\n\t\t\tpublic override bool IsNull {\n\t\t\t\tget {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn other == null || other.IsNull;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic new static readonly Role<InterpolatedStringContent> Role = new Role<InterpolatedStringContent>(\"InterpolatedStringContent\", Syntax.InterpolatedStringContent.Null);\n\n\t\tpublic override NodeType NodeType => NodeType.Unknown;\n\t}\n\n\t/// <summary>\n\t/// { Expression , Alignment : Suffix }\n\t/// </summary>\n\tpublic class Interpolation : InterpolatedStringContent\n\t{\n\t\tpublic static readonly TokenRole LBrace = new TokenRole(\"{\");\n\t\tpublic static readonly TokenRole RBrace = new TokenRole(\"}\");\n\n\t\tpublic CSharpTokenNode LBraceToken {\n\t\t\tget { return GetChildByRole(LBrace); }\n\t\t}\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic int Alignment { get; }\n\n\t\tpublic string Suffix { get; }\n\n\t\tpublic CSharpTokenNode RBraceToken {\n\t\t\tget { return GetChildByRole(RBrace); }\n\t\t}\n\n\t\tpublic Interpolation()\n\t\t{\n\n\t\t}\n\n\t\tpublic Interpolation(Expression expression, int alignment = 0, string suffix = null)\n\t\t{\n\t\t\tExpression = expression;\n\t\t\tAlignment = alignment;\n\t\t\tSuffix = suffix;\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitInterpolation(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitInterpolation(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitInterpolation(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, Match match)\n\t\t{\n\t\t\tInterpolation o = other as Interpolation;\n\t\t\treturn o != null && this.Expression.DoMatch(o.Expression, match);\n\t\t}\n\t}\n\n\tpublic class InterpolatedStringText : InterpolatedStringContent\n\t{\n\t\tpublic string Text { get; set; }\n\n\t\tpublic InterpolatedStringText()\n\t\t{\n\n\t\t}\n\n\t\tpublic InterpolatedStringText(string text)\n\t\t{\n\t\t\tText = text;\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitInterpolatedStringText(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitInterpolatedStringText(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitInterpolatedStringText(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, Match match)\n\t\t{\n\t\t\tInterpolatedStringText o = other as InterpolatedStringText;\n\t\t\treturn o != null && o.Text == this.Text;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/InvocationExpression.cs",
    "content": "// \n// InvocationExpression.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Target(Arguments)\n\t/// </summary>\n\tpublic class InvocationExpression : Expression\n\t{\n\t\tpublic Expression Target {\n\t\t\tget { return GetChildByRole(Roles.TargetExpression); }\n\t\t\tset { SetChildByRole(Roles.TargetExpression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstNodeCollection<Expression> Arguments {\n\t\t\tget { return GetChildrenByRole<Expression>(Roles.Argument); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitInvocationExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitInvocationExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitInvocationExpression(this, data);\n\t\t}\n\n\t\tpublic InvocationExpression()\n\t\t{\n\t\t}\n\n\t\tpublic InvocationExpression(Expression target, IEnumerable<Expression> arguments)\n\t\t{\n\t\t\tAddChild(target, Roles.TargetExpression);\n\t\t\tif (arguments != null)\n\t\t\t{\n\t\t\t\tforeach (var arg in arguments)\n\t\t\t\t{\n\t\t\t\t\tAddChild(arg, Roles.Argument);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic InvocationExpression(Expression target, params Expression[] arguments) : this(target, (IEnumerable<Expression>)arguments)\n\t\t{\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tInvocationExpression o = other as InvocationExpression;\n\t\t\treturn o != null && this.Target.DoMatch(o.Target, match) && this.Arguments.DoMatch(o.Arguments, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/IsExpression.cs",
    "content": "// \n// TypeOfIsExpression.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Expression is Type\n\t/// </summary>\n\tpublic class IsExpression : Expression\n\t{\n\t\tpublic readonly static TokenRole IsKeywordRole = new TokenRole(\"is\");\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode IsToken {\n\t\t\tget { return GetChildByRole(IsKeywordRole); }\n\t\t}\n\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic IsExpression()\n\t\t{\n\t\t}\n\n\t\tpublic IsExpression(Expression expression, AstType type)\n\t\t{\n\t\t\tAddChild(expression, Roles.Expression);\n\t\t\tAddChild(type, Roles.Type);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitIsExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitIsExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitIsExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tIsExpression o = other as IsExpression;\n\t\t\treturn o != null && this.Expression.DoMatch(o.Expression, match) && this.Type.DoMatch(o.Type, match);\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/LambdaExpression.cs",
    "content": "// \n// LambdaExpression.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// [async] Parameters => Body\n\t/// </summary>\n\tpublic class LambdaExpression : Expression\n\t{\n\t\tpublic static readonly Role<AttributeSection> AttributeRole = new Role<AttributeSection>(\"Attribute\", null);\n\t\tpublic readonly static TokenRole AsyncModifierRole = new TokenRole(\"async\");\n\t\tpublic static readonly Role<AstNode> BodyRole = new Role<AstNode>(\"Body\", AstNode.Null);\n\n\t\tbool isAsync;\n\n\t\tpublic AstNodeCollection<AttributeSection> Attributes {\n\t\t\tget { return base.GetChildrenByRole(AttributeRole); }\n\t\t}\n\n\t\tpublic bool IsAsync {\n\t\t\tget { return isAsync; }\n\t\t\tset { ThrowIfFrozen(); isAsync = value; }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstNodeCollection<ParameterDeclaration> Parameters {\n\t\t\tget { return GetChildrenByRole(Roles.Parameter); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic CSharpTokenNode ArrowToken {\n\t\t\tget { return GetChildByRole(Roles.Arrow); }\n\t\t}\n\n\t\tpublic AstNode Body {\n\t\t\tget { return GetChildByRole(BodyRole); }\n\t\t\tset { SetChildByRole(BodyRole, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLambdaExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLambdaExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitLambdaExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tLambdaExpression o = other as LambdaExpression;\n\t\t\treturn o != null && this.IsAsync == o.IsAsync && this.Parameters.DoMatch(o.Parameters, match) && this.Body.DoMatch(o.Body, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/MemberReferenceExpression.cs",
    "content": "// \n// MemberReferenceExpression.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Target.MemberName\n\t/// </summary>\n\tpublic class MemberReferenceExpression : Expression\n\t{\n\t\tpublic Expression Target {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.TargetExpression);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.TargetExpression, value);\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode DotToken {\n\t\t\tget { return GetChildByRole(Roles.Dot); }\n\t\t}\n\n\t\tpublic string MemberName {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier MemberNameToken {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, value);\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode LChevronToken {\n\t\t\tget { return GetChildByRole(Roles.LChevron); }\n\t\t}\n\n\t\tpublic AstNodeCollection<AstType> TypeArguments {\n\t\t\tget { return GetChildrenByRole(Roles.TypeArgument); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RChevronToken {\n\t\t\tget { return GetChildByRole(Roles.RChevron); }\n\t\t}\n\n\t\tpublic MemberReferenceExpression()\n\t\t{\n\t\t}\n\n\t\tpublic MemberReferenceExpression(Expression target, string memberName, IEnumerable<AstType> arguments = null)\n\t\t{\n\t\t\tAddChild(target, Roles.TargetExpression);\n\t\t\tMemberName = memberName;\n\t\t\tif (arguments != null)\n\t\t\t{\n\t\t\t\tforeach (var arg in arguments)\n\t\t\t\t{\n\t\t\t\t\tAddChild(arg, Roles.TypeArgument);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic MemberReferenceExpression(Expression target, string memberName, params AstType[] arguments) : this(target, memberName, (IEnumerable<AstType>)arguments)\n\t\t{\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitMemberReferenceExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitMemberReferenceExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitMemberReferenceExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tMemberReferenceExpression o = other as MemberReferenceExpression;\n\t\t\treturn o != null && this.Target.DoMatch(o.Target, match) && MatchString(this.MemberName, o.MemberName) && this.TypeArguments.DoMatch(o.TypeArguments, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/NamedArgumentExpression.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Represents a named argument passed to a method or attribute.\n\t/// name: expression\n\t/// </summary>\n\tpublic class NamedArgumentExpression : Expression\n\t{\n\t\tpublic NamedArgumentExpression()\n\t\t{\n\t\t}\n\n\t\tpublic NamedArgumentExpression(string name, Expression expression)\n\t\t{\n\t\t\tthis.Name = name;\n\t\t\tthis.Expression = expression;\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier NameToken {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, value);\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode ColonToken {\n\t\t\tget { return GetChildByRole(Roles.Colon); }\n\t\t}\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitNamedArgumentExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitNamedArgumentExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitNamedArgumentExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tNamedArgumentExpression o = other as NamedArgumentExpression;\n\t\t\treturn o != null && MatchString(this.Name, o.Name) && this.Expression.DoMatch(o.Expression, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/NamedExpression.cs",
    "content": "// \n// NamedExpression.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@xamarin.com>\n// \n// Copyright (c) 2011 Xamarin\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// name = expression\n\t/// This isn't the same as 'assign' even though it has the same syntax.\n\t/// This expression is used in object initializers and for named attribute arguments [Attr(FieldName = value)].\n\t/// </summary>\n\tpublic class NamedExpression : Expression\n\t{\n\t\tpublic NamedExpression()\n\t\t{\n\t\t}\n\n\t\tpublic NamedExpression(string name, Expression expression)\n\t\t{\n\t\t\tthis.Name = name;\n\t\t\tthis.Expression = expression;\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier NameToken {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, value);\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode AssignToken {\n\t\t\tget { return GetChildByRole(Roles.Assign); }\n\t\t}\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitNamedExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitNamedExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitNamedExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tvar o = other as NamedExpression;\n\t\t\treturn o != null && MatchString(this.Name, o.Name) && this.Expression.DoMatch(o.Expression, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/NullReferenceExpression.cs",
    "content": "// \n// NullReferenceExpression.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// null\n\t/// </summary>\n\tpublic class NullReferenceExpression : Expression\n\t{\n\t\tTextLocation location;\n\t\tpublic override TextLocation StartLocation {\n\t\t\tget {\n\t\t\t\treturn location;\n\t\t\t}\n\t\t}\n\n\t\tinternal void SetStartLocation(TextLocation value)\n\t\t{\n\t\t\tThrowIfFrozen();\n\t\t\tthis.location = value;\n\t\t}\n\n\t\tpublic override TextLocation EndLocation {\n\t\t\tget {\n\t\t\t\treturn new TextLocation(location.Line, location.Column + \"null\".Length);\n\t\t\t}\n\t\t}\n\n\t\tpublic NullReferenceExpression()\n\t\t{\n\t\t}\n\n\t\tpublic NullReferenceExpression(TextLocation location)\n\t\t{\n\t\t\tthis.location = location;\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitNullReferenceExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitNullReferenceExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitNullReferenceExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tNullReferenceExpression o = other as NullReferenceExpression;\n\t\t\treturn o != null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/ObjectCreateExpression.cs",
    "content": "// \n// ObjectCreateExpression.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// new Type(Arguments) { Initializer }\n\t/// </summary>\n\tpublic class ObjectCreateExpression : Expression\n\t{\n\t\tpublic readonly static TokenRole NewKeywordRole = new TokenRole(\"new\");\n\t\tpublic readonly static Role<ArrayInitializerExpression> InitializerRole = ArrayCreateExpression.InitializerRole;\n\n\t\tpublic CSharpTokenNode NewToken {\n\t\t\tget { return GetChildByRole(NewKeywordRole); }\n\t\t}\n\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstNodeCollection<Expression> Arguments {\n\t\t\tget { return GetChildrenByRole(Roles.Argument); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic ArrayInitializerExpression Initializer {\n\t\t\tget { return GetChildByRole(InitializerRole); }\n\t\t\tset { SetChildByRole(InitializerRole, value); }\n\t\t}\n\n\t\tpublic ObjectCreateExpression()\n\t\t{\n\t\t}\n\n\t\tpublic ObjectCreateExpression(AstType type, IEnumerable<Expression> arguments = null)\n\t\t{\n\t\t\tAddChild(type, Roles.Type);\n\t\t\tif (arguments != null)\n\t\t\t{\n\t\t\t\tforeach (var arg in arguments)\n\t\t\t\t{\n\t\t\t\t\tAddChild(arg, Roles.Argument);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic ObjectCreateExpression(AstType type, params Expression[] arguments) : this(type, (IEnumerable<Expression>)arguments)\n\t\t{\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitObjectCreateExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitObjectCreateExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitObjectCreateExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tObjectCreateExpression o = other as ObjectCreateExpression;\n\t\t\treturn o != null && this.Type.DoMatch(o.Type, match) && this.Arguments.DoMatch(o.Arguments, match) && this.Initializer.DoMatch(o.Initializer, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/OutVarDeclarationExpression.cs",
    "content": "// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// out type expression\n\t/// </summary>\n\tpublic class OutVarDeclarationExpression : Expression\n\t{\n\t\tpublic readonly static TokenRole OutKeywordRole = DirectionExpression.OutKeywordRole;\n\n\t\tpublic CSharpTokenNode OutKeywordToken {\n\t\t\tget { return GetChildByRole(OutKeywordRole); }\n\t\t}\n\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic VariableInitializer Variable {\n\t\t\tget { return GetChildByRole(Roles.Variable); }\n\t\t\tset { SetChildByRole(Roles.Variable, value); }\n\t\t}\n\n\t\tpublic OutVarDeclarationExpression()\n\t\t{\n\t\t}\n\n\t\tpublic OutVarDeclarationExpression(AstType type, string name)\n\t\t{\n\t\t\tthis.Type = type;\n\t\t\tthis.Variable = new VariableInitializer(name);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitOutVarDeclarationExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitOutVarDeclarationExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitOutVarDeclarationExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tvar o = other as OutVarDeclarationExpression;\n\t\t\treturn o != null && this.Type.DoMatch(o.Type, match) && this.Variable.DoMatch(o.Variable, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/ParenthesizedExpression.cs",
    "content": "// \n// ParenthesizedExpression.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// ( Expression )\n\t/// </summary>\n\tpublic class ParenthesizedExpression : Expression\n\t{\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic ParenthesizedExpression()\n\t\t{\n\t\t}\n\n\t\tpublic ParenthesizedExpression(Expression expr)\n\t\t{\n\t\t\tExpression = expr;\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitParenthesizedExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitParenthesizedExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitParenthesizedExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tParenthesizedExpression o = other as ParenthesizedExpression;\n\t\t\treturn o != null && this.Expression.DoMatch(o.Expression, match);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the expression acts like a parenthesized expression,\n\t\t/// i.e. whether information about the expected type (for lambda type inference) flows\n\t\t/// into the inner expression.\n\t\t/// </summary>\n\t\t/// <returns>Returns true for ParenthesizedExpression, CheckedExpression or UncheckedExpression; false otherwise.</returns>\n\t\tpublic static bool ActsAsParenthesizedExpression(AstNode expression)\n\t\t{\n\t\t\treturn expression is ParenthesizedExpression || expression is CheckedExpression || expression is UncheckedExpression;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Unpacks the given expression if it is a ParenthesizedExpression, CheckedExpression or UncheckedExpression.\n\t\t/// </summary>\n\t\tpublic static Expression UnpackParenthesizedExpression(Expression expr)\n\t\t{\n\t\t\twhile (ActsAsParenthesizedExpression(expr))\n\t\t\t\texpr = expr.GetChildByRole(Roles.Expression);\n\t\t\treturn expr;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/PointerReferenceExpression.cs",
    "content": "// \n// PointerReferenceExpression.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Target->MemberName\n\t/// </summary>\n\tpublic class PointerReferenceExpression : Expression\n\t{\n\t\tpublic readonly static TokenRole ArrowRole = new TokenRole(\"->\");\n\n\t\tpublic Expression Target {\n\t\t\tget { return GetChildByRole(Roles.TargetExpression); }\n\t\t\tset { SetChildByRole(Roles.TargetExpression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode ArrowToken {\n\t\t\tget { return GetChildByRole(ArrowRole); }\n\t\t}\n\n\t\tpublic string MemberName {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier MemberNameToken {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, value);\n\t\t\t}\n\t\t}\n\n\t\tpublic AstNodeCollection<AstType> TypeArguments {\n\t\t\tget { return GetChildrenByRole(Roles.TypeArgument); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitPointerReferenceExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitPointerReferenceExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitPointerReferenceExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tPointerReferenceExpression o = other as PointerReferenceExpression;\n\t\t\treturn o != null && MatchString(this.MemberName, o.MemberName) && this.TypeArguments.DoMatch(o.TypeArguments, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/PrimitiveExpression.cs",
    "content": "// \n// PrimitiveExpression.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Form of a C# literal.\n\t/// </summary>\n\tpublic enum LiteralFormat : byte\n\t{\n\t\tNone,\n\t\tDecimalNumber,\n\t\tHexadecimalNumber,\n\t\tBinaryNumber,\n\t\tStringLiteral,\n\t\tVerbatimStringLiteral,\n\t\tCharLiteral,\n\t\tUtf8Literal,\n\t}\n\n\t/// <summary>\n\t/// Represents a literal value.\n\t/// </summary>\n\tpublic class PrimitiveExpression : Expression\n\t{\n\t\tpublic static readonly object AnyValue = new object();\n\n\t\tTextLocation startLocation;\n\t\tTextLocation endLocation;\n\t\tpublic override TextLocation StartLocation => startLocation;\n\t\tpublic override TextLocation EndLocation => endLocation;\n\n\t\tinternal void SetLocation(TextLocation startLocation, TextLocation endLocation)\n\t\t{\n\t\t\tThrowIfFrozen();\n\t\t\tthis.startLocation = startLocation;\n\t\t\tthis.endLocation = endLocation;\n\t\t}\n\n\t\tobject value;\n\t\tLiteralFormat format;\n\n\t\tpublic object Value {\n\t\t\tget { return this.value; }\n\t\t\tset {\n\t\t\t\tThrowIfFrozen();\n\t\t\t\tthis.value = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic LiteralFormat Format {\n\t\t\tget { return format; }\n\t\t\tset {\n\t\t\t\tThrowIfFrozen();\n\t\t\t\tformat = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic PrimitiveExpression(object value)\n\t\t{\n\t\t\tthis.Value = value;\n\t\t}\n\n\t\tpublic PrimitiveExpression(object value, LiteralFormat format)\n\t\t{\n\t\t\tthis.Value = value;\n\t\t\tthis.format = format;\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitPrimitiveExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitPrimitiveExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitPrimitiveExpression(this, data);\n\t\t}\n\n\t\tunsafe static TextLocation AdvanceLocation(TextLocation startLocation, string str)\n\t\t{\n\t\t\tint line = startLocation.Line;\n\t\t\tint col = startLocation.Column;\n\t\t\tfixed (char* start = str)\n\t\t\t{\n\t\t\t\tchar* p = start;\n\t\t\t\tchar* endPtr = start + str.Length;\n\t\t\t\twhile (p < endPtr)\n\t\t\t\t{\n\t\t\t\t\tvar nl = NewLine.GetDelimiterLength(*p, () => {\n\t\t\t\t\t\tchar* nextp = p + 1;\n\t\t\t\t\t\tif (nextp < endPtr)\n\t\t\t\t\t\t\treturn *nextp;\n\t\t\t\t\t\treturn '\\0';\n\t\t\t\t\t});\n\t\t\t\t\tif (nl > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tline++;\n\t\t\t\t\t\tcol = 1;\n\t\t\t\t\t\tif (nl == 2)\n\t\t\t\t\t\t\tp++;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tcol++;\n\t\t\t\t\t}\n\t\t\t\t\tp++;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn new TextLocation(line, col);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tPrimitiveExpression o = other as PrimitiveExpression;\n\t\t\treturn o != null && (this.Value == AnyValue || object.Equals(this.Value, o.Value));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/QueryExpression.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class QueryExpression : Expression\n\t{\n\t\tpublic static readonly Role<QueryClause> ClauseRole = new Role<QueryClause>(\"Clause\", null);\n\n\t\t#region Null\n\t\tpublic new static readonly QueryExpression Null = new NullQueryExpression();\n\n\t\tsealed class NullQueryExpression : QueryExpression\n\t\t{\n\t\t\tpublic override bool IsNull {\n\t\t\t\tget {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn other == null || other.IsNull;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic AstNodeCollection<QueryClause> Clauses {\n\t\t\tget { return GetChildrenByRole(ClauseRole); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitQueryExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitQueryExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitQueryExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tQueryExpression o = other as QueryExpression;\n\t\t\treturn o != null && !o.IsNull && this.Clauses.DoMatch(o.Clauses, match);\n\t\t}\n\t}\n\n\tpublic abstract class QueryClause : AstNode\n\t{\n\t\tpublic override NodeType NodeType {\n\t\t\tget { return NodeType.QueryClause; }\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Represents a query continuation.\n\t/// \"(from .. select ..) into Identifier\" or \"(from .. group .. by ..) into Identifier\"\n\t/// Note that \"join .. into ..\" is not a query continuation!\n\t/// \n\t/// This is always the first(!!) clause in a query expression.\n\t/// The tree for \"from a in b select c into d select e\" looks like this:\n\t/// new QueryExpression {\n\t/// \tnew QueryContinuationClause {\n\t/// \t\tPrecedingQuery = new QueryExpression {\n\t/// \t\t\tnew QueryFromClause(a in b),\n\t/// \t\t\tnew QuerySelectClause(c)\n\t/// \t\t},\n\t/// \t\tIdentifier = d\n\t/// \t},\n\t/// \tnew QuerySelectClause(e)\n\t/// }\n\t/// </summary>\n\tpublic class QueryContinuationClause : QueryClause\n\t{\n\t\tpublic static readonly Role<QueryExpression> PrecedingQueryRole = new Role<QueryExpression>(\"PrecedingQuery\", QueryExpression.Null);\n\t\tpublic static readonly TokenRole IntoKeywordRole = new TokenRole(\"into\");\n\n\t\tpublic QueryExpression PrecedingQuery {\n\t\t\tget { return GetChildByRole(PrecedingQueryRole); }\n\t\t\tset { SetChildByRole(PrecedingQueryRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode IntoKeyword {\n\t\t\tget { return GetChildByRole(IntoKeywordRole); }\n\t\t}\n\n\t\tpublic string Identifier {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, Decompiler.CSharp.Syntax.Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier IdentifierToken {\n\t\t\tget { return GetChildByRole(Roles.Identifier); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitQueryContinuationClause(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitQueryContinuationClause(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitQueryContinuationClause(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tQueryContinuationClause o = other as QueryContinuationClause;\n\t\t\treturn o != null && MatchString(this.Identifier, o.Identifier) && this.PrecedingQuery.DoMatch(o.PrecedingQuery, match);\n\t\t}\n\t}\n\n\tpublic class QueryFromClause : QueryClause\n\t{\n\t\tpublic static readonly TokenRole FromKeywordRole = new TokenRole(\"from\");\n\t\tpublic static readonly TokenRole InKeywordRole = new TokenRole(\"in\");\n\n\t\tpublic CSharpTokenNode FromKeyword {\n\t\t\tget { return GetChildByRole(FromKeywordRole); }\n\t\t}\n\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic string Identifier {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, Decompiler.CSharp.Syntax.Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier IdentifierToken {\n\t\t\tget { return GetChildByRole(Roles.Identifier); }\n\t\t}\n\n\t\tpublic CSharpTokenNode InKeyword {\n\t\t\tget { return GetChildByRole(InKeywordRole); }\n\t\t}\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitQueryFromClause(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitQueryFromClause(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitQueryFromClause(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tQueryFromClause o = other as QueryFromClause;\n\t\t\treturn o != null && this.Type.DoMatch(o.Type, match) && MatchString(this.Identifier, o.Identifier)\n\t\t\t\t&& this.Expression.DoMatch(o.Expression, match);\n\t\t}\n\t}\n\n\tpublic class QueryLetClause : QueryClause\n\t{\n\t\tpublic readonly static TokenRole LetKeywordRole = new TokenRole(\"let\");\n\n\t\tpublic CSharpTokenNode LetKeyword {\n\t\t\tget { return GetChildByRole(LetKeywordRole); }\n\t\t}\n\n\t\tpublic string Identifier {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, Decompiler.CSharp.Syntax.Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier IdentifierToken {\n\t\t\tget { return GetChildByRole(Roles.Identifier); }\n\t\t}\n\n\t\tpublic CSharpTokenNode AssignToken {\n\t\t\tget { return GetChildByRole(Roles.Assign); }\n\t\t}\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitQueryLetClause(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitQueryLetClause(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitQueryLetClause(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tQueryLetClause o = other as QueryLetClause;\n\t\t\treturn o != null && MatchString(this.Identifier, o.Identifier) && this.Expression.DoMatch(o.Expression, match);\n\t\t}\n\t}\n\n\tpublic class QueryWhereClause : QueryClause\n\t{\n\t\tpublic readonly static TokenRole WhereKeywordRole = new TokenRole(\"where\");\n\n\t\tpublic CSharpTokenNode WhereKeyword {\n\t\t\tget { return GetChildByRole(WhereKeywordRole); }\n\t\t}\n\n\t\tpublic Expression Condition {\n\t\t\tget { return GetChildByRole(Roles.Condition); }\n\t\t\tset { SetChildByRole(Roles.Condition, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitQueryWhereClause(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitQueryWhereClause(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitQueryWhereClause(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tQueryWhereClause o = other as QueryWhereClause;\n\t\t\treturn o != null && this.Condition.DoMatch(o.Condition, match);\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Represents a join or group join clause.\n\t/// </summary>\n\tpublic class QueryJoinClause : QueryClause\n\t{\n\t\tpublic static readonly TokenRole JoinKeywordRole = new TokenRole(\"join\");\n\t\tpublic static readonly Role<AstType> TypeRole = Roles.Type;\n\t\tpublic static readonly Role<Identifier> JoinIdentifierRole = Roles.Identifier;\n\t\tpublic static readonly TokenRole InKeywordRole = new TokenRole(\"in\");\n\t\tpublic static readonly Role<Expression> InExpressionRole = Roles.Expression;\n\t\tpublic static readonly TokenRole OnKeywordRole = new TokenRole(\"on\");\n\t\tpublic static readonly Role<Expression> OnExpressionRole = new Role<Expression>(\"OnExpression\", Expression.Null);\n\t\tpublic static readonly TokenRole EqualsKeywordRole = new TokenRole(\"equals\");\n\t\tpublic static readonly Role<Expression> EqualsExpressionRole = new Role<Expression>(\"EqualsExpression\", Expression.Null);\n\t\tpublic static readonly TokenRole IntoKeywordRole = new TokenRole(\"into\");\n\t\tpublic static readonly Role<Identifier> IntoIdentifierRole = new Role<Identifier>(\"IntoIdentifier\", Identifier.Null);\n\n\t\tpublic bool IsGroupJoin {\n\t\t\tget { return !string.IsNullOrEmpty(this.IntoIdentifier); }\n\t\t}\n\n\t\tpublic CSharpTokenNode JoinKeyword {\n\t\t\tget { return GetChildByRole(JoinKeywordRole); }\n\t\t}\n\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(TypeRole); }\n\t\t\tset { SetChildByRole(TypeRole, value); }\n\t\t}\n\n\t\tpublic string JoinIdentifier {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(JoinIdentifierRole).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(JoinIdentifierRole, Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier JoinIdentifierToken {\n\t\t\tget { return GetChildByRole(JoinIdentifierRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode InKeyword {\n\t\t\tget { return GetChildByRole(InKeywordRole); }\n\t\t}\n\n\t\tpublic Expression InExpression {\n\t\t\tget { return GetChildByRole(InExpressionRole); }\n\t\t\tset { SetChildByRole(InExpressionRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode OnKeyword {\n\t\t\tget { return GetChildByRole(OnKeywordRole); }\n\t\t}\n\n\t\tpublic Expression OnExpression {\n\t\t\tget { return GetChildByRole(OnExpressionRole); }\n\t\t\tset { SetChildByRole(OnExpressionRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode EqualsKeyword {\n\t\t\tget { return GetChildByRole(EqualsKeywordRole); }\n\t\t}\n\n\t\tpublic Expression EqualsExpression {\n\t\t\tget { return GetChildByRole(EqualsExpressionRole); }\n\t\t\tset { SetChildByRole(EqualsExpressionRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode IntoKeyword {\n\t\t\tget { return GetChildByRole(IntoKeywordRole); }\n\t\t}\n\n\t\tpublic string IntoIdentifier {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(IntoIdentifierRole).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(IntoIdentifierRole, Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier IntoIdentifierToken {\n\t\t\tget { return GetChildByRole(IntoIdentifierRole); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitQueryJoinClause(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitQueryJoinClause(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitQueryJoinClause(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tQueryJoinClause o = other as QueryJoinClause;\n\t\t\treturn o != null && this.IsGroupJoin == o.IsGroupJoin\n\t\t\t\t&& this.Type.DoMatch(o.Type, match) && MatchString(this.JoinIdentifier, o.JoinIdentifier)\n\t\t\t\t&& this.InExpression.DoMatch(o.InExpression, match) && this.OnExpression.DoMatch(o.OnExpression, match)\n\t\t\t\t&& this.EqualsExpression.DoMatch(o.EqualsExpression, match)\n\t\t\t\t&& MatchString(this.IntoIdentifier, o.IntoIdentifier);\n\t\t}\n\t}\n\n\tpublic class QueryOrderClause : QueryClause\n\t{\n\t\tpublic static readonly TokenRole OrderbyKeywordRole = new TokenRole(\"orderby\");\n\t\tpublic static readonly Role<QueryOrdering> OrderingRole = new Role<QueryOrdering>(\"Ordering\", null);\n\n\t\tpublic CSharpTokenNode OrderbyToken {\n\t\t\tget { return GetChildByRole(OrderbyKeywordRole); }\n\t\t}\n\n\t\tpublic AstNodeCollection<QueryOrdering> Orderings {\n\t\t\tget { return GetChildrenByRole(OrderingRole); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitQueryOrderClause(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitQueryOrderClause(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitQueryOrderClause(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tQueryOrderClause o = other as QueryOrderClause;\n\t\t\treturn o != null && this.Orderings.DoMatch(o.Orderings, match);\n\t\t}\n\t}\n\n\tpublic class QueryOrdering : AstNode\n\t{\n\t\tpublic readonly static TokenRole AscendingKeywordRole = new TokenRole(\"ascending\");\n\t\tpublic readonly static TokenRole DescendingKeywordRole = new TokenRole(\"descending\");\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget { return NodeType.Unknown; }\n\t\t}\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic QueryOrderingDirection Direction {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic CSharpTokenNode DirectionToken {\n\t\t\tget { return Direction == QueryOrderingDirection.Ascending ? GetChildByRole(AscendingKeywordRole) : GetChildByRole(DescendingKeywordRole); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitQueryOrdering(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitQueryOrdering(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitQueryOrdering(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tQueryOrdering o = other as QueryOrdering;\n\t\t\treturn o != null && this.Direction == o.Direction && this.Expression.DoMatch(o.Expression, match);\n\t\t}\n\t}\n\n\tpublic enum QueryOrderingDirection\n\t{\n\t\tNone,\n\t\tAscending,\n\t\tDescending\n\t}\n\n\tpublic class QuerySelectClause : QueryClause\n\t{\n\t\tpublic readonly static TokenRole SelectKeywordRole = new TokenRole(\"select\");\n\n\t\tpublic CSharpTokenNode SelectKeyword {\n\t\t\tget { return GetChildByRole(SelectKeywordRole); }\n\t\t}\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitQuerySelectClause(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitQuerySelectClause(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitQuerySelectClause(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tQuerySelectClause o = other as QuerySelectClause;\n\t\t\treturn o != null && this.Expression.DoMatch(o.Expression, match);\n\t\t}\n\t}\n\n\tpublic class QueryGroupClause : QueryClause\n\t{\n\t\tpublic static readonly TokenRole GroupKeywordRole = new TokenRole(\"group\");\n\t\tpublic static readonly Role<Expression> ProjectionRole = new Role<Expression>(\"Projection\", Expression.Null);\n\t\tpublic static readonly TokenRole ByKeywordRole = new TokenRole(\"by\");\n\t\tpublic static readonly Role<Expression> KeyRole = new Role<Expression>(\"Key\", Expression.Null);\n\n\t\tpublic CSharpTokenNode GroupKeyword {\n\t\t\tget { return GetChildByRole(GroupKeywordRole); }\n\t\t}\n\n\t\tpublic Expression Projection {\n\t\t\tget { return GetChildByRole(ProjectionRole); }\n\t\t\tset { SetChildByRole(ProjectionRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode ByKeyword {\n\t\t\tget { return GetChildByRole(ByKeywordRole); }\n\t\t}\n\n\t\tpublic Expression Key {\n\t\t\tget { return GetChildByRole(KeyRole); }\n\t\t\tset { SetChildByRole(KeyRole, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitQueryGroupClause(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitQueryGroupClause(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitQueryGroupClause(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tQueryGroupClause o = other as QueryGroupClause;\n\t\t\treturn o != null && this.Projection.DoMatch(o.Projection, match) && this.Key.DoMatch(o.Key, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/RecursivePatternExpression.cs",
    "content": "// Copyright (c) 2023 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class RecursivePatternExpression : Expression\n\t{\n\t\tpublic static readonly Role<Expression> SubPatternRole = new Role<Expression>(\"SubPattern\", Syntax.Expression.Null);\n\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic AstNodeCollection<Expression> SubPatterns {\n\t\t\tget { return GetChildrenByRole(SubPatternRole); }\n\t\t}\n\n\t\tpublic VariableDesignation Designation {\n\t\t\tget { return GetChildByRole(Roles.VariableDesignationRole); }\n\t\t\tset { SetChildByRole(Roles.VariableDesignationRole, value); }\n\t\t}\n\n\t\tpublic bool IsPositional { get; set; }\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitRecursivePatternExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitRecursivePatternExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitRecursivePatternExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, Match match)\n\t\t{\n\t\t\treturn other is RecursivePatternExpression o\n\t\t\t\t&& Type.DoMatch(o.Type, match)\n\t\t\t\t&& IsPositional == o.IsPositional\n\t\t\t\t&& SubPatterns.DoMatch(o.SubPatterns, match)\n\t\t\t\t&& Designation.DoMatch(o.Designation, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/SizeOfExpression.cs",
    "content": "// \n// SizeOfExpression.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// sizeof(Type)\n\t/// </summary>\n\tpublic class SizeOfExpression : Expression\n\t{\n\t\tpublic readonly static TokenRole SizeofKeywordRole = new TokenRole(\"sizeof\");\n\n\t\tpublic CSharpTokenNode SizeOfToken {\n\t\t\tget { return GetChildByRole(SizeofKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic SizeOfExpression()\n\t\t{\n\t\t}\n\n\t\tpublic SizeOfExpression(AstType type)\n\t\t{\n\t\t\tAddChild(type, Roles.Type);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitSizeOfExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitSizeOfExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitSizeOfExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tSizeOfExpression o = other as SizeOfExpression;\n\t\t\treturn o != null && this.Type.DoMatch(o.Type, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/StackAllocExpression.cs",
    "content": "// \n// StackAllocExpression.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// stackalloc Type[Count]\n\t/// </summary>\n\tpublic class StackAllocExpression : Expression\n\t{\n\t\tpublic readonly static TokenRole StackallocKeywordRole = new TokenRole(\"stackalloc\");\n\t\tpublic readonly static Role<ArrayInitializerExpression> InitializerRole = new Role<ArrayInitializerExpression>(\"Initializer\", ArrayInitializerExpression.Null);\n\n\t\tpublic CSharpTokenNode StackAllocToken {\n\t\t\tget { return GetChildByRole(StackallocKeywordRole); }\n\t\t}\n\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LBracketToken {\n\t\t\tget { return GetChildByRole(Roles.LBracket); }\n\t\t}\n\n\t\tpublic Expression CountExpression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RBracketToken {\n\t\t\tget { return GetChildByRole(Roles.RBracket); }\n\t\t}\n\n\t\tpublic ArrayInitializerExpression Initializer {\n\t\t\tget { return GetChildByRole(InitializerRole); }\n\t\t\tset { SetChildByRole(InitializerRole, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitStackAllocExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitStackAllocExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitStackAllocExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tStackAllocExpression o = other as StackAllocExpression;\n\t\t\treturn o != null && this.Type.DoMatch(o.Type, match)\n\t\t\t\t&& this.CountExpression.DoMatch(o.CountExpression, match)\n\t\t\t\t&& this.Initializer.DoMatch(o.Initializer, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/SwitchExpression.cs",
    "content": "// Copyright (c) 2020 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Expression switch { SwitchSections }\n\t/// </summary>\n\tpublic class SwitchExpression : Expression\n\t{\n\t\tpublic static readonly TokenRole SwitchKeywordRole = new TokenRole(\"switch\");\n\t\tpublic static readonly Role<SwitchExpressionSection> SwitchSectionRole = new Role<SwitchExpressionSection>(\"SwitchSection\", null);\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode SwitchToken {\n\t\t\tget { return GetChildByRole(SwitchKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LBraceToken {\n\t\t\tget { return GetChildByRole(Roles.LBrace); }\n\t\t}\n\n\t\tpublic AstNodeCollection<SwitchExpressionSection> SwitchSections {\n\t\t\tget { return GetChildrenByRole(SwitchSectionRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RBraceToken {\n\t\t\tget { return GetChildByRole(Roles.RBrace); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitSwitchExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitSwitchExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitSwitchExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tSwitchExpression o = other as SwitchExpression;\n\t\t\treturn o != null && this.Expression.DoMatch(o.Expression, match) && this.SwitchSections.DoMatch(o.SwitchSections, match);\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Pattern => Expression\n\t/// </summary>\n\tpublic class SwitchExpressionSection : AstNode\n\t{\n\t\tpublic static readonly Role<Expression> PatternRole = new Role<Expression>(\"Pattern\", Expression.Null);\n\t\tpublic static readonly Role<Expression> BodyRole = new Role<Expression>(\"Body\", Expression.Null);\n\n\t\tpublic Expression Pattern {\n\t\t\tget { return GetChildByRole(PatternRole); }\n\t\t\tset { SetChildByRole(PatternRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode ArrowToken {\n\t\t\tget { return GetChildByRole(Roles.Arrow); }\n\t\t}\n\n\t\tpublic Expression Body {\n\t\t\tget { return GetChildByRole(BodyRole); }\n\t\t\tset { SetChildByRole(BodyRole, value); }\n\t\t}\n\n\t\tpublic override NodeType NodeType => NodeType.Unknown;\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitSwitchExpressionSection(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitSwitchExpressionSection(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitSwitchExpressionSection(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tSwitchExpressionSection o = other as SwitchExpressionSection;\n\t\t\treturn o != null && this.Pattern.DoMatch(o.Pattern, match) && this.Body.DoMatch(o.Body, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/ThisReferenceExpression.cs",
    "content": "// \n// ThisReferenceExpression.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// this\n\t/// </summary>\n\tpublic class ThisReferenceExpression : Expression\n\t{\n\t\tpublic TextLocation Location {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic override TextLocation StartLocation {\n\t\t\tget {\n\t\t\t\treturn Location;\n\t\t\t}\n\t\t}\n\t\tpublic override TextLocation EndLocation {\n\t\t\tget {\n\t\t\t\treturn new TextLocation(Location.Line, Location.Column + \"this\".Length);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitThisReferenceExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitThisReferenceExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitThisReferenceExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tThisReferenceExpression o = other as ThisReferenceExpression;\n\t\t\treturn o != null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/ThrowExpression.cs",
    "content": "// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// throw Expression\n\t/// </summary>\n\tpublic class ThrowExpression : Expression\n\t{\n\t\tpublic static readonly TokenRole ThrowKeywordRole = ThrowStatement.ThrowKeywordRole;\n\n\t\tpublic CSharpTokenNode ThrowToken {\n\t\t\tget { return GetChildByRole(ThrowKeywordRole); }\n\t\t}\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic ThrowExpression()\n\t\t{\n\t\t}\n\n\t\tpublic ThrowExpression(Expression expression)\n\t\t{\n\t\t\tAddChild(expression, Roles.Expression);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitThrowExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitThrowExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitThrowExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tThrowExpression o = other as ThrowExpression;\n\t\t\treturn o != null && this.Expression.DoMatch(o.Expression, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/TupleExpression.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class TupleExpression : Expression\n\t{\n\t\tpublic AstNodeCollection<Expression> Elements {\n\t\t\tget { return GetChildrenByRole(Roles.Expression); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitTupleExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitTupleExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitTupleExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, Match match)\n\t\t{\n\t\t\treturn other is TupleExpression tuple\n\t\t\t\t&& Elements.DoMatch(tuple.Elements, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/TypeOfExpression.cs",
    "content": "// \n// TypeOfExpression.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// typeof(Type)\n\t/// </summary>\n\tpublic class TypeOfExpression : Expression\n\t{\n\t\tpublic readonly static TokenRole TypeofKeywordRole = new TokenRole(\"typeof\");\n\n\t\tpublic CSharpTokenNode TypeOfToken {\n\t\t\tget { return GetChildByRole(TypeofKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic TypeOfExpression()\n\t\t{\n\t\t}\n\n\t\tpublic TypeOfExpression(AstType type)\n\t\t{\n\t\t\tAddChild(type, Roles.Type);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitTypeOfExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitTypeOfExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitTypeOfExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tTypeOfExpression o = other as TypeOfExpression;\n\t\t\treturn o != null && this.Type.DoMatch(o.Type, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/TypeReferenceExpression.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Represents an AstType as an expression.\n\t/// This is used when calling a method on a primitive type: \"int.Parse()\"\n\t/// </summary>\n\tpublic class TypeReferenceExpression : Expression\n\t{\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitTypeReferenceExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitTypeReferenceExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitTypeReferenceExpression(this, data);\n\t\t}\n\n\t\tpublic TypeReferenceExpression()\n\t\t{\n\t\t}\n\n\t\tpublic TypeReferenceExpression(AstType type)\n\t\t{\n\t\t\tAddChild(type, Roles.Type);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tTypeReferenceExpression o = other as TypeReferenceExpression;\n\t\t\treturn o != null && this.Type.DoMatch(o.Type, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/UnaryOperatorExpression.cs",
    "content": "// \n// UnaryOperatorExpression.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System;\nusing System.Linq.Expressions;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Operator Expression\n\t/// </summary>\n\tpublic class UnaryOperatorExpression : Expression\n\t{\n\t\tpublic readonly static TokenRole NotRole = new TokenRole(\"!\");\n\t\tpublic readonly static TokenRole BitNotRole = new TokenRole(\"~\");\n\t\tpublic readonly static TokenRole MinusRole = new TokenRole(\"-\");\n\t\tpublic readonly static TokenRole PlusRole = new TokenRole(\"+\");\n\t\tpublic readonly static TokenRole IncrementRole = new TokenRole(\"++\");\n\t\tpublic readonly static TokenRole DecrementRole = new TokenRole(\"--\");\n\t\tpublic readonly static TokenRole DereferenceRole = new TokenRole(\"*\");\n\t\tpublic readonly static TokenRole AddressOfRole = new TokenRole(\"&\");\n\t\tpublic readonly static TokenRole AwaitRole = new TokenRole(\"await\");\n\t\tpublic readonly static TokenRole NullConditionalRole = new TokenRole(\"?\");\n\t\tpublic readonly static TokenRole SuppressNullableWarningRole = new TokenRole(\"!\");\n\t\tpublic readonly static TokenRole IndexFromEndRole = new TokenRole(\"^\");\n\t\tpublic readonly static TokenRole PatternNotRole = new TokenRole(\"not\");\n\n\t\tpublic UnaryOperatorExpression()\n\t\t{\n\t\t}\n\n\t\tpublic UnaryOperatorExpression(UnaryOperatorType op, Expression expression)\n\t\t{\n\t\t\tthis.Operator = op;\n\t\t\tthis.Expression = expression;\n\t\t}\n\n\t\tpublic UnaryOperatorType Operator {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic CSharpTokenNode OperatorToken {\n\t\t\tget { return GetChildByRole(GetOperatorRole(Operator)); }\n\t\t}\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitUnaryOperatorExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitUnaryOperatorExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitUnaryOperatorExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tUnaryOperatorExpression o = other as UnaryOperatorExpression;\n\t\t\treturn o != null && (this.Operator == UnaryOperatorType.Any || this.Operator == o.Operator)\n\t\t\t\t&& this.Expression.DoMatch(o.Expression, match);\n\t\t}\n\n\t\tpublic static TokenRole GetOperatorRole(UnaryOperatorType op)\n\t\t{\n\t\t\tswitch (op)\n\t\t\t{\n\t\t\t\tcase UnaryOperatorType.Not:\n\t\t\t\t\treturn NotRole;\n\t\t\t\tcase UnaryOperatorType.BitNot:\n\t\t\t\t\treturn BitNotRole;\n\t\t\t\tcase UnaryOperatorType.Minus:\n\t\t\t\t\treturn MinusRole;\n\t\t\t\tcase UnaryOperatorType.Plus:\n\t\t\t\t\treturn PlusRole;\n\t\t\t\tcase UnaryOperatorType.Increment:\n\t\t\t\tcase UnaryOperatorType.PostIncrement:\n\t\t\t\t\treturn IncrementRole;\n\t\t\t\tcase UnaryOperatorType.PostDecrement:\n\t\t\t\tcase UnaryOperatorType.Decrement:\n\t\t\t\t\treturn DecrementRole;\n\t\t\t\tcase UnaryOperatorType.Dereference:\n\t\t\t\t\treturn DereferenceRole;\n\t\t\t\tcase UnaryOperatorType.AddressOf:\n\t\t\t\t\treturn AddressOfRole;\n\t\t\t\tcase UnaryOperatorType.Await:\n\t\t\t\t\treturn AwaitRole;\n\t\t\t\tcase UnaryOperatorType.NullConditional:\n\t\t\t\t\treturn NullConditionalRole;\n\t\t\t\tcase UnaryOperatorType.NullConditionalRewrap:\n\t\t\t\tcase UnaryOperatorType.IsTrue:\n\t\t\t\t\treturn null; // no syntax\n\t\t\t\tcase UnaryOperatorType.SuppressNullableWarning:\n\t\t\t\t\treturn SuppressNullableWarningRole;\n\t\t\t\tcase UnaryOperatorType.IndexFromEnd:\n\t\t\t\t\treturn IndexFromEndRole;\n\t\t\t\tcase UnaryOperatorType.PatternNot:\n\t\t\t\t\treturn PatternNotRole;\n\t\t\t\tcase UnaryOperatorType.PatternRelationalLessThan:\n\t\t\t\t\treturn BinaryOperatorExpression.LessThanRole;\n\t\t\t\tcase UnaryOperatorType.PatternRelationalLessThanOrEqual:\n\t\t\t\t\treturn BinaryOperatorExpression.LessThanOrEqualRole;\n\t\t\t\tcase UnaryOperatorType.PatternRelationalGreaterThan:\n\t\t\t\t\treturn BinaryOperatorExpression.GreaterThanRole;\n\t\t\t\tcase UnaryOperatorType.PatternRelationalGreaterThanOrEqual:\n\t\t\t\t\treturn BinaryOperatorExpression.GreaterThanOrEqualRole;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException(\"Invalid value for UnaryOperatorType\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static ExpressionType GetLinqNodeType(UnaryOperatorType op, bool checkForOverflow)\n\t\t{\n\t\t\tswitch (op)\n\t\t\t{\n\t\t\t\tcase UnaryOperatorType.Not:\n\t\t\t\t\treturn ExpressionType.Not;\n\t\t\t\tcase UnaryOperatorType.BitNot:\n\t\t\t\t\treturn ExpressionType.OnesComplement;\n\t\t\t\tcase UnaryOperatorType.Minus:\n\t\t\t\t\treturn checkForOverflow ? ExpressionType.NegateChecked : ExpressionType.Negate;\n\t\t\t\tcase UnaryOperatorType.Plus:\n\t\t\t\t\treturn ExpressionType.UnaryPlus;\n\t\t\t\tcase UnaryOperatorType.Increment:\n\t\t\t\t\treturn ExpressionType.PreIncrementAssign;\n\t\t\t\tcase UnaryOperatorType.Decrement:\n\t\t\t\t\treturn ExpressionType.PreDecrementAssign;\n\t\t\t\tcase UnaryOperatorType.PostIncrement:\n\t\t\t\t\treturn ExpressionType.PostIncrementAssign;\n\t\t\t\tcase UnaryOperatorType.PostDecrement:\n\t\t\t\t\treturn ExpressionType.PostDecrementAssign;\n\t\t\t\tcase UnaryOperatorType.Dereference:\n\t\t\t\tcase UnaryOperatorType.AddressOf:\n\t\t\t\tcase UnaryOperatorType.Await:\n\t\t\t\tcase UnaryOperatorType.SuppressNullableWarning:\n\t\t\t\tcase UnaryOperatorType.IndexFromEnd:\n\t\t\t\tcase UnaryOperatorType.PatternNot:\n\t\t\t\tcase UnaryOperatorType.PatternRelationalLessThan:\n\t\t\t\tcase UnaryOperatorType.PatternRelationalLessThanOrEqual:\n\t\t\t\tcase UnaryOperatorType.PatternRelationalGreaterThan:\n\t\t\t\tcase UnaryOperatorType.PatternRelationalGreaterThanOrEqual:\n\t\t\t\t\treturn ExpressionType.Extension;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException(\"Invalid value for UnaryOperatorType\");\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic enum UnaryOperatorType\n\t{\n\t\t/// <summary>\n\t\t/// Any unary operator (used in pattern matching)\n\t\t/// </summary>\n\t\tAny,\n\n\t\t/// <summary>Logical not (!a)</summary>\n\t\tNot,\n\t\t/// <summary>Bitwise not (~a)</summary>\n\t\tBitNot,\n\t\t/// <summary>Unary minus (-a)</summary>\n\t\tMinus,\n\t\t/// <summary>Unary plus (+a)</summary>\n\t\tPlus,\n\t\t/// <summary>Pre increment (++a)</summary>\n\t\tIncrement,\n\t\t/// <summary>Pre decrement (--a)</summary>\n\t\tDecrement,\n\t\t/// <summary>Post increment (a++)</summary>\n\t\tPostIncrement,\n\t\t/// <summary>Post decrement (a--)</summary>\n\t\tPostDecrement,\n\t\t/// <summary>Dereferencing (*a)</summary>\n\t\tDereference,\n\t\t/// <summary>Get address (&amp;a)</summary>\n\t\tAddressOf,\n\t\t/// <summary>C# 5.0 await</summary>\n\t\tAwait,\n\t\t/// <summary>C# 6 null-conditional operator.\n\t\t/// Occurs as target of member reference or indexer expressions\n\t\t/// to indicate <c>?.</c> or <c>?[]</c>.\n\t\t/// Corresponds to <c>nullable.unwrap</c> in ILAst.\n\t\t/// </summary>\n\t\tNullConditional,\n\t\t/// <summary>\n\t\t/// Wrapper around a primary expression containing a null conditional operator.\n\t\t/// Corresponds to <c>nullable.rewrap</c> in ILAst.\n\t\t/// This has no syntax in C#, but the node is used to ensure parentheses are inserted where necessary.\n\t\t/// </summary>\n\t\tNullConditionalRewrap,\n\t\t/// <summary>\n\t\t/// Implicit call of \"operator true\".\n\t\t/// </summary>\n\t\tIsTrue,\n\t\t/// <summary>\n\t\t/// C# 8 postfix ! operator (dammit operator)\n\t\t/// </summary>\n\t\tSuppressNullableWarning,\n\t\t/// <summary>\n\t\t/// C# 8 prefix ^ operator\n\t\t/// </summary>\n\t\tIndexFromEnd,\n\t\t/// <summary>\n\t\t/// C# 9 not pattern\n\t\t/// </summary>\n\t\tPatternNot,\n\t\t/// <summary>\n\t\t/// C# 9 relational pattern\n\t\t/// </summary>\n\t\tPatternRelationalLessThan,\n\t\t/// <summary>\n\t\t/// C# 9 relational pattern\n\t\t/// </summary>\n\t\tPatternRelationalLessThanOrEqual,\n\t\t/// <summary>\n\t\t/// C# 9 relational pattern\n\t\t/// </summary>\n\t\tPatternRelationalGreaterThan,\n\t\t/// <summary>\n\t\t/// C# 9 relational pattern\n\t\t/// </summary>\n\t\tPatternRelationalGreaterThanOrEqual,\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/UncheckedExpression.cs",
    "content": "// \n// UncheckedExpression.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// unchecked(Expression)\n\t/// </summary>\n\tpublic class UncheckedExpression : Expression\n\t{\n\t\tpublic readonly static TokenRole UncheckedKeywordRole = new TokenRole(\"unchecked\");\n\n\t\tpublic CSharpTokenNode UncheckedToken {\n\t\t\tget { return GetChildByRole(UncheckedKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic UncheckedExpression()\n\t\t{\n\t\t}\n\n\t\tpublic UncheckedExpression(Expression expression)\n\t\t{\n\t\t\tAddChild(expression, Roles.Expression);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitUncheckedExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitUncheckedExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitUncheckedExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tUncheckedExpression o = other as UncheckedExpression;\n\t\t\treturn o != null && this.Expression.DoMatch(o.Expression, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/UndocumentedExpression.cs",
    "content": "// \n// UndocumentedExpression.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic enum UndocumentedExpressionType\n\t{\n\t\tArgListAccess, // __arglist\n\t\tArgList, // __arglist (a1, a2, ..., an)\n\t\tRefValue, // __refvalue (expr , type)\n\t\tRefType, // __reftype (expr)\n\t\tMakeRef // __makeref (expr)\n\t}\n\n\t/// <summary>\n\t/// Represents undocumented expressions.\n\t/// </summary>\n\tpublic class UndocumentedExpression : Expression\n\t{\n\t\tpublic readonly static TokenRole ArglistKeywordRole = new TokenRole(\"__arglist\");\n\t\tpublic readonly static TokenRole RefvalueKeywordRole = new TokenRole(\"__refvalue\");\n\t\tpublic readonly static TokenRole ReftypeKeywordRole = new TokenRole(\"__reftype\");\n\t\tpublic readonly static TokenRole MakerefKeywordRole = new TokenRole(\"__makeref\");\n\n\t\tpublic UndocumentedExpressionType UndocumentedExpressionType {\n\t\t\tget; set;\n\t\t}\n\n\t\tpublic CSharpTokenNode UndocumentedToken {\n\t\t\tget {\n\t\t\t\tswitch (UndocumentedExpressionType)\n\t\t\t\t{\n\t\t\t\t\tcase UndocumentedExpressionType.ArgListAccess:\n\t\t\t\t\tcase UndocumentedExpressionType.ArgList:\n\t\t\t\t\t\treturn GetChildByRole(ArglistKeywordRole);\n\t\t\t\t\tcase UndocumentedExpressionType.RefValue:\n\t\t\t\t\t\treturn GetChildByRole(RefvalueKeywordRole);\n\t\t\t\t\tcase UndocumentedExpressionType.RefType:\n\t\t\t\t\t\treturn GetChildByRole(ReftypeKeywordRole);\n\t\t\t\t\tcase UndocumentedExpressionType.MakeRef:\n\t\t\t\t\t\treturn GetChildByRole(MakerefKeywordRole);\n\t\t\t\t}\n\t\t\t\treturn CSharpTokenNode.Null;\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstNodeCollection<Expression> Arguments {\n\t\t\tget { return GetChildrenByRole(Roles.Argument); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitUndocumentedExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitUndocumentedExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitUndocumentedExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tUndocumentedExpression o = other as UndocumentedExpression;\n\t\t\treturn o != null && this.UndocumentedExpressionType == o.UndocumentedExpressionType && this.Arguments.DoMatch(o.Arguments, match);\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Expressions/WithInitializerExpression.cs",
    "content": "// Copyright (c) 2010-2021 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Expression with Initializer\n\t/// </summary>\n\tpublic class WithInitializerExpression : Expression\n\t{\n\t\tpublic readonly static TokenRole WithKeywordRole = new TokenRole(\"with\");\n\t\tpublic readonly static Role<ArrayInitializerExpression> InitializerRole = ArrayCreateExpression.InitializerRole;\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode WithToken {\n\t\t\tget { return GetChildByRole(WithKeywordRole); }\n\t\t}\n\n\t\tpublic ArrayInitializerExpression Initializer {\n\t\t\tget { return GetChildByRole(InitializerRole); }\n\t\t\tset { SetChildByRole(InitializerRole, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitWithInitializerExpression(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitWithInitializerExpression(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitWithInitializerExpression(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, Match match)\n\t\t{\n\t\t\treturn other is WithInitializerExpression o\n\t\t\t\t&& this.Expression.DoMatch(o.Expression, match)\n\t\t\t\t&& this.Initializer.DoMatch(o.Initializer, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/FunctionPointerAstType.cs",
    "content": "// \n// FullTypeName.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class FunctionPointerAstType : AstType\n\t{\n\t\tpublic static readonly TokenRole PointerRole = new TokenRole(\"*\");\n\t\tpublic static readonly Role<AstType> CallingConventionRole = new Role<AstType>(\"CallConv\", AstType.Null);\n\n\t\tpublic bool HasUnmanagedCallingConvention { get; set; }\n\n\t\tpublic AstNodeCollection<AstType> CallingConventions {\n\t\t\tget { return GetChildrenByRole(CallingConventionRole); }\n\t\t}\n\n\t\tpublic AstNodeCollection<ParameterDeclaration> Parameters {\n\t\t\tget { return GetChildrenByRole(Roles.Parameter); }\n\t\t}\n\n\t\tpublic AstType ReturnType {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitFunctionPointerType(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitFunctionPointerType(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitFunctionPointerType(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\treturn other is FunctionPointerAstType o\n\t\t\t\t&& this.CallingConventions.DoMatch(o.CallingConventions, match)\n\t\t\t\t&& this.Parameters.DoMatch(o.Parameters, match)\n\t\t\t\t&& this.ReturnType.DoMatch(o.ReturnType, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/Attribute.cs",
    "content": "// \n// Attribute.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Attribute(Arguments)\n\t/// </summary>\n\tpublic class Attribute : AstNode\n\t{\n\t\tpublic override NodeType NodeType {\n\t\t\tget {\n\t\t\t\treturn NodeType.Unknown;\n\t\t\t}\n\t\t}\n\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstNodeCollection<Expression> Arguments {\n\t\t\tget { return base.GetChildrenByRole(Roles.Argument); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\t// HasArgumentList == false: [Empty]\n\t\tpublic bool HasArgumentList {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitAttribute(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitAttribute(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitAttribute(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tAttribute o = other as Attribute;\n\t\t\treturn o != null && this.Type.DoMatch(o.Type, match) && this.Arguments.DoMatch(o.Arguments, match);\n\t\t}\n\n\t\tpublic override string ToString(CSharpFormattingOptions formattingOptions)\n\t\t{\n\t\t\tif (IsNull)\n\t\t\t\treturn \"Null\";\n\t\t\treturn base.ToString(formattingOptions);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/AttributeSection.cs",
    "content": "// \n// AttributeSection.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// [AttributeTarget: Attributes]\n\t/// </summary>\n\tpublic class AttributeSection : AstNode\n\t{\n\t\t#region PatternPlaceholder\n\t\tpublic static implicit operator AttributeSection(PatternMatching.Pattern pattern)\n\t\t{\n\t\t\treturn pattern != null ? new PatternPlaceholder(pattern) : null;\n\t\t}\n\n\t\tsealed class PatternPlaceholder : AttributeSection, PatternMatching.INode\n\t\t{\n\t\t\treadonly PatternMatching.Pattern child;\n\n\t\t\tpublic PatternPlaceholder(PatternMatching.Pattern child)\n\t\t\t{\n\t\t\t\tthis.child = child;\n\t\t\t}\n\n\t\t\tpublic override NodeType NodeType {\n\t\t\t\tget { return NodeType.Pattern; }\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn child.DoMatch(other, match);\n\t\t\t}\n\n\t\t\tbool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)\n\t\t\t{\n\t\t\t\treturn child.DoMatchCollection(role, pos, match, backtrackingInfo);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget {\n\t\t\t\treturn NodeType.Unknown;\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode LBracketToken {\n\t\t\tget { return GetChildByRole(Roles.LBracket); }\n\t\t}\n\n\t\tpublic string AttributeTarget {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier AttributeTargetToken {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, value);\n\t\t\t}\n\t\t}\n\n\t\tpublic AstNodeCollection<Attribute> Attributes {\n\t\t\tget { return base.GetChildrenByRole(Roles.Attribute); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RBracketToken {\n\t\t\tget { return GetChildByRole(Roles.RBracket); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitAttributeSection(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitAttributeSection(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitAttributeSection(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tAttributeSection o = other as AttributeSection;\n\t\t\treturn o != null && MatchString(this.AttributeTarget, o.AttributeTarget) && this.Attributes.DoMatch(o.Attributes, match);\n\t\t}\n\n\t\tpublic AttributeSection()\n\t\t{\n\t\t}\n\n\t\tpublic AttributeSection(Attribute attr)\n\t\t{\n\t\t\tthis.Attributes.Add(attr);\n\t\t}\n\n\t\t//\t\tpublic static string GetAttributeTargetName(AttributeTarget attributeTarget)\n\t\t//\t\t{\n\t\t//\t\t\tswitch (attributeTarget) {\n\t\t//\t\t\t\tcase AttributeTarget.None:\n\t\t//\t\t\t\t\treturn null;\n\t\t//\t\t\t\tcase AttributeTarget.Assembly:\n\t\t//\t\t\t\t\treturn \"assembly\";\n\t\t//\t\t\t\tcase AttributeTarget.Module:\n\t\t//\t\t\t\t\treturn \"module\";\n\t\t//\t\t\t\tcase AttributeTarget.Type:\n\t\t//\t\t\t\t\treturn \"type\";\n\t\t//\t\t\t\tcase AttributeTarget.Param:\n\t\t//\t\t\t\t\treturn \"param\";\n\t\t//\t\t\t\tcase AttributeTarget.Field:\n\t\t//\t\t\t\t\treturn \"field\";\n\t\t//\t\t\t\tcase AttributeTarget.Return:\n\t\t//\t\t\t\t\treturn \"return\";\n\t\t//\t\t\t\tcase AttributeTarget.Method:\n\t\t//\t\t\t\t\treturn \"method\";\n\t\t//\t\t\t\tdefault:\n\t\t//\t\t\t\t\tthrow new NotSupportedException(\"Invalid value for AttributeTarget\");\n\t\t//\t\t\t}\n\t\t//\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/Comment.cs",
    "content": "// \n// Comment.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic enum CommentType\n\t{\n\t\t/// <summary>\n\t\t/// \"//\" comment\n\t\t/// </summary>\n\t\tSingleLine,\n\t\t/// <summary>\n\t\t/// \"/* */\" comment\n\t\t/// </summary>\n\t\tMultiLine,\n\t\t/// <summary>\n\t\t/// \"///\" comment\n\t\t/// </summary>\n\t\tDocumentation,\n\t\t/// <summary>\n\t\t/// Inactive code (code in non-taken \"#if\")\n\t\t/// </summary>\n\t\tInactiveCode,\n\t\t/// <summary>\n\t\t/// \"/** */\" comment\n\t\t/// </summary>\n\t\tMultiLineDocumentation\n\t}\n\n\tpublic class Comment : AstNode\n\t{\n\t\tpublic override NodeType NodeType {\n\t\t\tget {\n\t\t\t\treturn NodeType.Whitespace;\n\t\t\t}\n\t\t}\n\n\t\tCommentType commentType;\n\n\t\tpublic CommentType CommentType {\n\t\t\tget { return commentType; }\n\t\t\tset { ThrowIfFrozen(); commentType = value; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns true if the <see cref=\"CommentType\"/> is Documentation or MultiLineDocumentation.\n\t\t/// </summary>\n\t\tpublic bool IsDocumentation {\n\t\t\tget {\n\t\t\t\treturn commentType == CommentType.Documentation || commentType == CommentType.MultiLineDocumentation;\n\t\t\t}\n\t\t}\n\n\t\tbool startsLine;\n\n\t\tpublic bool StartsLine {\n\t\t\tget { return startsLine; }\n\t\t\tset { ThrowIfFrozen(); startsLine = value; }\n\t\t}\n\n\t\tstring content;\n\n\t\tpublic string Content {\n\t\t\tget { return content; }\n\t\t\tset { ThrowIfFrozen(); content = value; }\n\t\t}\n\n\t\tTextLocation startLocation;\n\t\tpublic override TextLocation StartLocation {\n\t\t\tget {\n\t\t\t\treturn startLocation;\n\t\t\t}\n\t\t}\n\n\t\tTextLocation endLocation;\n\t\tpublic override TextLocation EndLocation {\n\t\t\tget {\n\t\t\t\treturn endLocation;\n\t\t\t}\n\t\t}\n\n\t\tinternal void SetStartLocation(TextLocation value)\n\t\t{\n\t\t\tThrowIfFrozen();\n\t\t\tthis.startLocation = value;\n\t\t}\n\n\t\tinternal void SetEndLocation(TextLocation value)\n\t\t{\n\t\t\tThrowIfFrozen();\n\t\t\tthis.endLocation = value;\n\t\t}\n\n\t\tpublic Comment(string content, CommentType type = CommentType.SingleLine)\n\t\t{\n\t\t\tthis.CommentType = type;\n\t\t\tthis.Content = content;\n\t\t}\n\n\t\tpublic Comment(CommentType commentType, TextLocation startLocation, TextLocation endLocation)\n\t\t{\n\t\t\tthis.CommentType = commentType;\n\t\t\tthis.startLocation = startLocation;\n\t\t\tthis.endLocation = endLocation;\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitComment(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitComment(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitComment(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tComment o = other as Comment;\n\t\t\treturn o != null && this.CommentType == o.CommentType && MatchString(this.Content, o.Content);\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/Constraint.cs",
    "content": "// \n// Constraint.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// where TypeParameter : BaseTypes\n\t/// </summary>\n\t/// <remarks>\n\t/// new(), struct and class constraints are represented using a PrimitiveType \"new\", \"struct\" or \"class\"\n\t/// </remarks>\n\tpublic class Constraint : AstNode\n\t{\n\t\tpublic override NodeType NodeType {\n\t\t\tget { return NodeType.Unknown; }\n\t\t}\n\n\t\tpublic CSharpTokenNode WhereKeyword {\n\t\t\tget { return GetChildByRole(Roles.WhereKeyword); }\n\t\t}\n\n\t\tpublic SimpleType TypeParameter {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.ConstraintTypeParameter);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.ConstraintTypeParameter, value);\n\t\t\t}\n\t\t}\n\n\t\tpublic AstNodeCollection<AstType> BaseTypes {\n\t\t\tget {\n\t\t\t\treturn GetChildrenByRole(Roles.BaseType);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitConstraint(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitConstraint(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitConstraint(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tConstraint o = other as Constraint;\n\t\t\treturn o != null && this.TypeParameter.DoMatch(o.TypeParameter, match) && this.BaseTypes.DoMatch(o.BaseTypes, match);\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/DelegateDeclaration.cs",
    "content": "// \n// DelegateDeclaration.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// delegate ReturnType Name&lt;TypeParameters&gt;(Parameters) where Constraints;\n\t/// </summary>\n\tpublic class DelegateDeclaration : EntityDeclaration\n\t{\n\t\tpublic override NodeType NodeType {\n\t\t\tget { return NodeType.TypeDeclaration; }\n\t\t}\n\n\t\tpublic override SymbolKind SymbolKind {\n\t\t\tget { return SymbolKind.TypeDefinition; }\n\t\t}\n\n\t\tpublic CSharpTokenNode DelegateToken {\n\t\t\tget { return GetChildByRole(Roles.DelegateKeyword); }\n\t\t}\n\n\t\tpublic AstNodeCollection<TypeParameterDeclaration> TypeParameters {\n\t\t\tget { return GetChildrenByRole(Roles.TypeParameter); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstNodeCollection<ParameterDeclaration> Parameters {\n\t\t\tget { return GetChildrenByRole(Roles.Parameter); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic AstNodeCollection<Constraint> Constraints {\n\t\t\tget { return GetChildrenByRole(Roles.Constraint); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDelegateDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDelegateDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitDelegateDeclaration(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tDelegateDeclaration o = other as DelegateDeclaration;\n\t\t\treturn o != null && MatchString(this.Name, o.Name)\n\t\t\t\t&& this.MatchAttributesAndModifiers(o, match) && this.ReturnType.DoMatch(o.ReturnType, match)\n\t\t\t\t&& this.TypeParameters.DoMatch(o.TypeParameters, match) && this.Parameters.DoMatch(o.Parameters, match)\n\t\t\t\t&& this.Constraints.DoMatch(o.Constraints, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/ExternAliasDeclaration.cs",
    "content": "// \n// ExternAliasDeclaration.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2011 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// extern alias IDENTIFIER;\n\t/// </summary>\n\tpublic class ExternAliasDeclaration : AstNode\n\t{\n\t\tpublic override NodeType NodeType {\n\t\t\tget {\n\t\t\t\treturn NodeType.Unknown;\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode ExternToken {\n\t\t\tget { return GetChildByRole(Roles.ExternKeyword); }\n\t\t}\n\n\t\tpublic CSharpTokenNode AliasToken {\n\t\t\tget { return GetChildByRole(Roles.AliasKeyword); }\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier NameToken {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, value);\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode SemicolonToken {\n\t\t\tget { return GetChildByRole(Roles.Semicolon); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitExternAliasDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitExternAliasDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitExternAliasDeclaration(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tvar o = other as ExternAliasDeclaration;\n\t\t\treturn o != null && MatchString(this.Name, o.Name);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/NamespaceDeclaration.cs",
    "content": "// \n// NamespaceDeclaration.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// namespace Name { Members }\n\t/// </summary>\n\tpublic class NamespaceDeclaration : AstNode\n\t{\n\t\tpublic static readonly Role<AstNode> MemberRole = SyntaxTree.MemberRole;\n\t\tpublic static readonly Role<AstType> NamespaceNameRole = new Role<AstType>(\"NamespaceName\", AstType.Null);\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget {\n\t\t\t\treturn NodeType.Unknown;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool IsFileScoped { get; set; }\n\n\t\tpublic CSharpTokenNode NamespaceToken {\n\t\t\tget { return GetChildByRole(Roles.NamespaceKeyword); }\n\t\t}\n\n\t\tpublic AstType NamespaceName {\n\t\t\tget { return GetChildByRole(NamespaceNameRole) ?? AstType.Null; }\n\t\t\tset { SetChildByRole(NamespaceNameRole, value); }\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget {\n\t\t\t\treturn UsingDeclaration.ConstructNamespace(NamespaceName);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tvar arr = value.Split('.');\n\t\t\t\tNamespaceName = ConstructType(arr, arr.Length - 1);\n\t\t\t}\n\t\t}\n\n\t\tstatic AstType ConstructType(string[] arr, int i)\n\t\t{\n\t\t\tif (i < 0 || i >= arr.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(i));\n\t\t\tif (i == 0)\n\t\t\t\treturn new SimpleType(arr[i]);\n\t\t\treturn new MemberType(ConstructType(arr, i - 1), arr[i]);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the full namespace name (including any parent namespaces)\n\t\t/// </summary>\n\t\tpublic string FullName {\n\t\t\tget {\n\t\t\t\tNamespaceDeclaration parentNamespace = Parent as NamespaceDeclaration;\n\t\t\t\tif (parentNamespace != null)\n\t\t\t\t\treturn BuildQualifiedName(parentNamespace.FullName, Name);\n\t\t\t\treturn Name;\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable<string> Identifiers {\n\t\t\tget {\n\t\t\t\tvar result = new Stack<string>();\n\t\t\t\tAstType type = NamespaceName;\n\t\t\t\twhile (type is MemberType)\n\t\t\t\t{\n\t\t\t\t\tvar mt = (MemberType)type;\n\t\t\t\t\tresult.Push(mt.MemberName);\n\t\t\t\t\ttype = mt.Target;\n\t\t\t\t}\n\t\t\t\tif (type is SimpleType)\n\t\t\t\t\tresult.Push(((SimpleType)type).Identifier);\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode LBraceToken {\n\t\t\tget { return GetChildByRole(Roles.LBrace); }\n\t\t}\n\n\t\tpublic AstNodeCollection<AstNode> Members {\n\t\t\tget { return GetChildrenByRole(MemberRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RBraceToken {\n\t\t\tget { return GetChildByRole(Roles.RBrace); }\n\t\t}\n\n\t\tpublic NamespaceDeclaration()\n\t\t{\n\t\t}\n\n\t\tpublic NamespaceDeclaration(string name)\n\t\t{\n\t\t\tthis.Name = name;\n\t\t}\n\n\t\tpublic static string BuildQualifiedName(string name1, string name2)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(name1))\n\t\t\t\treturn name2;\n\t\t\tif (string.IsNullOrEmpty(name2))\n\t\t\t\treturn name1;\n\t\t\treturn name1 + \".\" + name2;\n\t\t}\n\n\t\tpublic void AddMember(AstNode child)\n\t\t{\n\t\t\tAddChild(child, MemberRole);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitNamespaceDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitNamespaceDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitNamespaceDeclaration(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tNamespaceDeclaration o = other as NamespaceDeclaration;\n\t\t\treturn o != null && MatchString(this.Name, o.Name) && this.Members.DoMatch(o.Members, match);\n\t\t}\n\t}\n};\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/PreProcessorDirective.cs",
    "content": "// \n// PreProcessorDirective.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@xamarin.com>\n// \n// Copyright (c) 2011 Xamarin Inc.\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\nusing System.Linq;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic enum PreProcessorDirectiveType : byte\n\t{\n\t\tInvalid = 0,\n\t\tRegion = 1,\n\t\tEndregion = 2,\n\n\t\tIf = 3,\n\t\tEndif = 4,\n\t\tElif = 5,\n\t\tElse = 6,\n\n\t\tDefine = 7,\n\t\tUndef = 8,\n\t\tError = 9,\n\t\tWarning = 10,\n\t\tPragma = 11,\n\t\tLine = 12\n\t}\n\n\tpublic class LinePreprocessorDirective : PreProcessorDirective\n\t{\n\t\tpublic int LineNumber {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic string FileName {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic LinePreprocessorDirective(TextLocation startLocation, TextLocation endLocation) : base(PreProcessorDirectiveType.Line, startLocation, endLocation)\n\t\t{\n\t\t}\n\n\t\tpublic LinePreprocessorDirective(string argument = null) : base(PreProcessorDirectiveType.Line, argument)\n\t\t{\n\t\t}\n\t}\n\n\tpublic class PragmaWarningPreprocessorDirective : PreProcessorDirective\n\t{\n\t\tpublic static readonly Role<PrimitiveExpression> WarningRole = new Role<PrimitiveExpression>(\"Warning\", null);\n\n\t\tpublic static readonly TokenRole PragmaKeywordRole = new TokenRole(\"#pragma\");\n\t\tpublic static readonly TokenRole WarningKeywordRole = new TokenRole(\"warning\");\n\t\tpublic static readonly TokenRole DisableKeywordRole = new TokenRole(\"disable\");\n\t\tpublic static readonly TokenRole RestoreKeywordRole = new TokenRole(\"restore\");\n\n\t\tpublic bool Disable {\n\t\t\tget {\n\t\t\t\treturn !DisableToken.IsNull;\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode PragmaToken {\n\t\t\tget { return GetChildByRole(PragmaKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode WarningToken {\n\t\t\tget { return GetChildByRole(WarningKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode DisableToken {\n\t\t\tget { return GetChildByRole(DisableKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RestoreToken {\n\t\t\tget { return GetChildByRole(RestoreKeywordRole); }\n\t\t}\n\n\t\tpublic AstNodeCollection<PrimitiveExpression> Warnings {\n\t\t\tget { return GetChildrenByRole(WarningRole); }\n\t\t}\n\n\t\tpublic override TextLocation EndLocation {\n\t\t\tget {\n\t\t\t\tvar child = LastChild;\n\t\t\t\tif (child == null)\n\t\t\t\t\treturn base.EndLocation;\n\t\t\t\treturn child.EndLocation;\n\t\t\t}\n\t\t}\n\n\t\tpublic PragmaWarningPreprocessorDirective(TextLocation startLocation, TextLocation endLocation) : base(PreProcessorDirectiveType.Pragma, startLocation, endLocation)\n\t\t{\n\t\t}\n\n\t\tpublic PragmaWarningPreprocessorDirective(string argument = null) : base(PreProcessorDirectiveType.Pragma, argument)\n\t\t{\n\t\t}\n\n\t\tpublic bool IsDefined(int pragmaWarning)\n\t\t{\n\t\t\treturn Warnings.Select(w => (int)w.Value).Any(n => n == pragmaWarning);\n\t\t}\n\t}\n\n\tpublic class PreProcessorDirective : AstNode\n\t{\n\t\tpublic override NodeType NodeType {\n\t\t\tget {\n\t\t\t\treturn NodeType.Whitespace;\n\t\t\t}\n\t\t}\n\n\t\tpublic PreProcessorDirectiveType Type {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic string Argument {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// For an '#if' directive, specifies whether the condition evaluated to true.\n\t\t/// </summary>\n\t\tpublic bool Take {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tTextLocation startLocation;\n\t\tpublic override TextLocation StartLocation {\n\t\t\tget {\n\t\t\t\treturn startLocation;\n\t\t\t}\n\t\t}\n\n\t\tTextLocation endLocation;\n\t\tpublic override TextLocation EndLocation {\n\t\t\tget {\n\t\t\t\treturn endLocation;\n\t\t\t}\n\t\t}\n\n\t\tpublic PreProcessorDirective(PreProcessorDirectiveType type, TextLocation startLocation, TextLocation endLocation)\n\t\t{\n\t\t\tthis.Type = type;\n\t\t\tthis.startLocation = startLocation;\n\t\t\tthis.endLocation = endLocation;\n\t\t}\n\n\t\tpublic PreProcessorDirective(PreProcessorDirectiveType type, string argument = null)\n\t\t{\n\t\t\tthis.Type = type;\n\t\t\tthis.Argument = argument;\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitPreProcessorDirective(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitPreProcessorDirective(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitPreProcessorDirective(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tPreProcessorDirective o = other as PreProcessorDirective;\n\t\t\treturn o != null && Type == o.Type && MatchString(Argument, o.Argument);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/TypeDeclaration.cs",
    "content": "// \n// TypeDeclaration.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic enum ClassType\n\t{\n\t\tClass,\n\t\tStruct,\n\t\tInterface,\n\t\tEnum,\n\t\t/// <summary>\n\t\t/// C# 9 'record class'\n\t\t/// </summary>\n\t\tRecordClass,\n\t\t/// <summary>\n\t\t/// C# 10 'record struct'\n\t\t/// </summary>\n\t\tRecordStruct,\n\t}\n\n\t/// <summary>\n\t/// class Name&lt;TypeParameters&gt; : BaseTypes where Constraints;\n\t/// </summary>\n\tpublic class TypeDeclaration : EntityDeclaration\n\t{\n\t\tpublic override NodeType NodeType {\n\t\t\tget { return NodeType.TypeDeclaration; }\n\t\t}\n\n\t\tpublic override SymbolKind SymbolKind {\n\t\t\tget { return SymbolKind.TypeDefinition; }\n\t\t}\n\n\t\tClassType classType;\n\n\t\tpublic CSharpTokenNode TypeKeyword {\n\t\t\tget {\n\t\t\t\tswitch (classType)\n\t\t\t\t{\n\t\t\t\t\tcase ClassType.Class:\n\t\t\t\t\t\treturn GetChildByRole(Roles.ClassKeyword);\n\t\t\t\t\tcase ClassType.Struct:\n\t\t\t\t\tcase ClassType.RecordStruct:\n\t\t\t\t\t\treturn GetChildByRole(Roles.StructKeyword);\n\t\t\t\t\tcase ClassType.Interface:\n\t\t\t\t\t\treturn GetChildByRole(Roles.InterfaceKeyword);\n\t\t\t\t\tcase ClassType.Enum:\n\t\t\t\t\t\treturn GetChildByRole(Roles.EnumKeyword);\n\t\t\t\t\tcase ClassType.RecordClass:\n\t\t\t\t\t\treturn GetChildByRole(Roles.RecordKeyword);\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn CSharpTokenNode.Null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic ClassType ClassType {\n\t\t\tget { return classType; }\n\t\t\tset {\n\t\t\t\tThrowIfFrozen();\n\t\t\t\tclassType = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode LChevronToken {\n\t\t\tget { return GetChildByRole(Roles.LChevron); }\n\t\t}\n\n\t\tpublic AstNodeCollection<TypeParameterDeclaration> TypeParameters {\n\t\t\tget { return GetChildrenByRole(Roles.TypeParameter); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RChevronToken {\n\t\t\tget { return GetChildByRole(Roles.RChevron); }\n\t\t}\n\n\t\tpublic CSharpTokenNode ColonToken {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Colon);\n\t\t\t}\n\t\t}\n\n\t\tpublic bool HasPrimaryConstructor { get; set; }\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstNodeCollection<ParameterDeclaration> PrimaryConstructorParameters {\n\t\t\tget { return GetChildrenByRole(Roles.Parameter); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic AstNodeCollection<AstType> BaseTypes {\n\t\t\tget { return GetChildrenByRole(Roles.BaseType); }\n\t\t}\n\n\t\tpublic AstNodeCollection<Constraint> Constraints {\n\t\t\tget { return GetChildrenByRole(Roles.Constraint); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LBraceToken {\n\t\t\tget { return GetChildByRole(Roles.LBrace); }\n\t\t}\n\n\t\tpublic AstNodeCollection<EntityDeclaration> Members {\n\t\t\tget { return GetChildrenByRole(Roles.TypeMemberRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RBraceToken {\n\t\t\tget { return GetChildByRole(Roles.RBrace); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitTypeDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitTypeDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitTypeDeclaration(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tTypeDeclaration o = other as TypeDeclaration;\n\t\t\treturn o != null && this.ClassType == o.ClassType && MatchString(this.Name, o.Name)\n\t\t\t\t&& this.MatchAttributesAndModifiers(o, match) && this.TypeParameters.DoMatch(o.TypeParameters, match)\n\t\t\t\t&& this.BaseTypes.DoMatch(o.BaseTypes, match) && this.Constraints.DoMatch(o.Constraints, match)\n\t\t\t\t&& this.HasPrimaryConstructor == o.HasPrimaryConstructor\n\t\t\t\t&& this.PrimaryConstructorParameters.DoMatch(o.PrimaryConstructorParameters, match)\n\t\t\t\t&& this.Members.DoMatch(o.Members, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/TypeParameterDeclaration.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// [in|out] Name\n\t/// \n\t/// Represents a type parameter.\n\t/// Note: mirroring the C# syntax, constraints are not part of the type parameter declaration, but belong\n\t/// to the parent type or method.\n\t/// </summary>\n\tpublic class TypeParameterDeclaration : AstNode\n\t{\n\t\tpublic static readonly Role<AttributeSection> AttributeRole = EntityDeclaration.AttributeRole;\n\t\tpublic static readonly TokenRole OutVarianceKeywordRole = new TokenRole(\"out\");\n\t\tpublic static readonly TokenRole InVarianceKeywordRole = new TokenRole(\"in\");\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget { return NodeType.Unknown; }\n\t\t}\n\n\t\tpublic AstNodeCollection<AttributeSection> Attributes {\n\t\t\tget { return GetChildrenByRole(AttributeRole); }\n\t\t}\n\n\t\tVarianceModifier variance;\n\n\t\tpublic VarianceModifier Variance {\n\t\t\tget { return variance; }\n\t\t\tset { ThrowIfFrozen(); variance = value; }\n\t\t}\n\n\t\tpublic CSharpTokenNode VarianceToken {\n\t\t\tget {\n\t\t\t\tswitch (Variance)\n\t\t\t\t{\n\t\t\t\t\tcase VarianceModifier.Covariant:\n\t\t\t\t\t\treturn GetChildByRole(OutVarianceKeywordRole);\n\t\t\t\t\tcase VarianceModifier.Contravariant:\n\t\t\t\t\t\treturn GetChildByRole(InVarianceKeywordRole);\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn CSharpTokenNode.Null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier NameToken {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, value);\n\t\t\t}\n\t\t}\n\n\t\tpublic TypeParameterDeclaration()\n\t\t{\n\t\t}\n\n\t\tpublic TypeParameterDeclaration(string name)\n\t\t{\n\t\t\tName = name;\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitTypeParameterDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitTypeParameterDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitTypeParameterDeclaration(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tTypeParameterDeclaration o = other as TypeParameterDeclaration;\n\t\t\treturn o != null && this.Variance == o.Variance && MatchString(this.Name, o.Name) && this.Attributes.DoMatch(o.Attributes, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/UsingAliasDeclaration.cs",
    "content": "// \n// UsingAliasDeclaration.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// using Alias = Import;\n\t/// </summary>\n\tpublic class UsingAliasDeclaration : AstNode\n\t{\n\t\tpublic static readonly TokenRole UsingKeywordRole = new TokenRole(\"using\");\n\t\tpublic static readonly Role<Identifier> AliasRole = new Role<Identifier>(\"Alias\", Identifier.Null);\n\t\tpublic static readonly Role<AstType> ImportRole = UsingDeclaration.ImportRole;\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget {\n\t\t\t\treturn NodeType.Unknown;\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode UsingToken {\n\t\t\tget { return GetChildByRole(UsingKeywordRole); }\n\t\t}\n\n\t\tpublic string Alias {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(AliasRole).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(AliasRole, Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode AssignToken {\n\t\t\tget { return GetChildByRole(Roles.Assign); }\n\t\t}\n\n\t\tpublic AstType Import {\n\t\t\tget { return GetChildByRole(ImportRole); }\n\t\t\tset { SetChildByRole(ImportRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode SemicolonToken {\n\t\t\tget { return GetChildByRole(Roles.Semicolon); }\n\t\t}\n\n\t\tpublic UsingAliasDeclaration()\n\t\t{\n\t\t}\n\n\t\tpublic UsingAliasDeclaration(string alias, string nameSpace)\n\t\t{\n\t\t\tAddChild(Identifier.Create(alias), AliasRole);\n\t\t\tAddChild(new SimpleType(nameSpace), ImportRole);\n\t\t}\n\n\t\tpublic UsingAliasDeclaration(string alias, AstType import)\n\t\t{\n\t\t\tAddChild(Identifier.Create(alias), AliasRole);\n\t\t\tAddChild(import, ImportRole);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitUsingAliasDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitUsingAliasDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitUsingAliasDeclaration(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tUsingAliasDeclaration o = other as UsingAliasDeclaration;\n\t\t\treturn o != null && MatchString(this.Alias, o.Alias) && this.Import.DoMatch(o.Import, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/GeneralScope/UsingDeclaration.cs",
    "content": "// \n// UsingDeclaration.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// using Import;\n\t/// </summary>\n\tpublic class UsingDeclaration : AstNode\n\t{\n\t\tpublic static readonly TokenRole UsingKeywordRole = new TokenRole(\"using\");\n\t\tpublic static readonly Role<AstType> ImportRole = new Role<AstType>(\"Import\", AstType.Null);\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget {\n\t\t\t\treturn NodeType.Unknown;\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode UsingToken {\n\t\t\tget { return GetChildByRole(UsingKeywordRole); }\n\t\t}\n\n\t\tpublic AstType Import {\n\t\t\tget { return GetChildByRole(ImportRole); }\n\t\t\tset { SetChildByRole(ImportRole, value); }\n\t\t}\n\n\t\tpublic string Namespace {\n\t\t\tget { return ConstructNamespace(Import); }\n\t\t}\n\n\t\tinternal static string ConstructNamespace(AstType type)\n\t\t{\n\t\t\tvar stack = new Stack<string>();\n\t\t\twhile (type is MemberType)\n\t\t\t{\n\t\t\t\tvar mt = (MemberType)type;\n\t\t\t\tstack.Push(mt.MemberName);\n\t\t\t\ttype = mt.Target;\n\t\t\t\tif (mt.IsDoubleColon)\n\t\t\t\t{\n\t\t\t\t\tstack.Push(\"::\");\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tstack.Push(\".\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (type is SimpleType)\n\t\t\t\tstack.Push(((SimpleType)type).Identifier);\n\n\t\t\tvar result = new StringBuilder();\n\t\t\twhile (stack.Count > 0)\n\t\t\t\tresult.Append(stack.Pop());\n\t\t\treturn result.ToString();\n\t\t}\n\n\t\tpublic CSharpTokenNode SemicolonToken {\n\t\t\tget { return GetChildByRole(Roles.Semicolon); }\n\t\t}\n\n\t\tpublic UsingDeclaration()\n\t\t{\n\t\t}\n\n\t\tpublic UsingDeclaration(string nameSpace)\n\t\t{\n\t\t\tAddChild(AstType.Create(nameSpace), ImportRole);\n\t\t}\n\n\t\tpublic UsingDeclaration(AstType import)\n\t\t{\n\t\t\tAddChild(import, ImportRole);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitUsingDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitUsingDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitUsingDeclaration(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tUsingDeclaration o = other as UsingDeclaration;\n\t\t\treturn o != null && this.Import.DoMatch(o.Import, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/IAnnotatable.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Provides an interface to handle annotations in an object.\n\t/// </summary>\n\tpublic interface IAnnotatable\n\t{\n\t\t/// <summary>\n\t\t/// Gets all annotations stored on this IAnnotatable.\n\t\t/// </summary>\n\t\tIEnumerable<object> Annotations {\n\t\t\tget;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the first annotation of the specified type.\n\t\t/// Returns null if no matching annotation exists.\n\t\t/// </summary>\n\t\t/// <typeparam name='T'>\n\t\t/// The type of the annotation.\n\t\t/// </typeparam>\n\t\tT Annotation<T>() where T : class;\n\n\t\t/// <summary>\n\t\t/// Gets the first annotation of the specified type.\n\t\t/// Returns null if no matching annotation exists.\n\t\t/// </summary>\n\t\t/// <param name='type'>\n\t\t/// The type of the annotation.\n\t\t/// </param>\n\t\tobject Annotation(Type type);\n\n\t\t/// <summary>\n\t\t/// Adds an annotation to this instance.\n\t\t/// </summary>\n\t\t/// <param name='annotation'>\n\t\t/// The annotation to add.\n\t\t/// </param>\n\t\tvoid AddAnnotation(object annotation);\n\n\t\t/// <summary>\n\t\t/// Removes all annotations of the specified type.\n\t\t/// </summary>\n\t\t/// <typeparam name='T'>\n\t\t/// The type of the annotations to remove.\n\t\t/// </typeparam>\n\t\tvoid RemoveAnnotations<T>() where T : class;\n\n\t\t/// <summary>\n\t\t/// Removes all annotations of the specified type.\n\t\t/// </summary>\n\t\t/// <param name='type'>\n\t\t/// The type of the annotations to remove.\n\t\t/// </param>\n\t\tvoid RemoveAnnotations(Type type);\n\t}\n\n\t/// <summary>\n\t/// Base class used to implement the IAnnotatable interface.\n\t/// This implementation is thread-safe.\n\t/// </summary>\n\t[Serializable]\n\tpublic abstract class AbstractAnnotatable : IAnnotatable\n\t{\n\t\t// Annotations: points either null (no annotations), to the single annotation,\n\t\t// or to an AnnotationList.\n\t\t// Once it is pointed at an AnnotationList, it will never change (this allows thread-safety support by locking the list)\n\n\t\tobject annotations;\n\n\t\t/// <summary>\n\t\t/// Clones all annotations.\n\t\t/// This method is intended to be called by Clone() implementations in derived classes.\n\t\t/// <code>\n\t\t/// AstNode copy = (AstNode)MemberwiseClone();\n\t\t/// copy.CloneAnnotations();\n\t\t/// </code>\n\t\t/// </summary>\n\t\tprotected void CloneAnnotations()\n\t\t{\n\t\t\tICloneable cloneable = annotations as ICloneable;\n\t\t\tif (cloneable != null)\n\t\t\t\tannotations = cloneable.Clone();\n\t\t}\n\n\t\tsealed class AnnotationList : List<object>, ICloneable\n\t\t{\n\t\t\t// There are two uses for this custom list type:\n\t\t\t// 1) it's private, and thus (unlike List<object>) cannot be confused with real annotations\n\t\t\t// 2) It allows us to simplify the cloning logic by making the list behave the same as a clonable annotation.\n\t\t\tpublic AnnotationList(int initialCapacity) : base(initialCapacity)\n\t\t\t{\n\t\t\t}\n\n\t\t\tpublic object Clone()\n\t\t\t{\n\t\t\t\tlock (this)\n\t\t\t\t{\n\t\t\t\t\tAnnotationList copy = new AnnotationList(this.Count);\n\t\t\t\t\tfor (int i = 0; i < this.Count; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tobject obj = this[i];\n\t\t\t\t\t\tICloneable c = obj as ICloneable;\n\t\t\t\t\t\tcopy.Add(c != null ? c.Clone() : obj);\n\t\t\t\t\t}\n\t\t\t\t\treturn copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic virtual void AddAnnotation(object annotation)\n\t\t{\n\t\t\tif (annotation == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(annotation));\n\t\t\tretry: // Retry until successful\n\t\t\tobject oldAnnotation = Interlocked.CompareExchange(ref this.annotations, annotation, null);\n\t\t\tif (oldAnnotation == null)\n\t\t\t{\n\t\t\t\treturn; // we successfully added a single annotation\n\t\t\t}\n\t\t\tAnnotationList list = oldAnnotation as AnnotationList;\n\t\t\tif (list == null)\n\t\t\t{\n\t\t\t\t// we need to transform the old annotation into a list\n\t\t\t\tlist = new AnnotationList(4);\n\t\t\t\tlist.Add(oldAnnotation);\n\t\t\t\tlist.Add(annotation);\n\t\t\t\tif (Interlocked.CompareExchange(ref this.annotations, list, oldAnnotation) != oldAnnotation)\n\t\t\t\t{\n\t\t\t\t\t// the transformation failed (some other thread wrote to this.annotations first)\n\t\t\t\t\tgoto retry;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// once there's a list, use simple locking\n\t\t\t\tlock (list)\n\t\t\t\t{\n\t\t\t\t\tlist.Add(annotation);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic virtual void RemoveAnnotations<T>() where T : class\n\t\t{\n\t\t\tretry: // Retry until successful\n\t\t\tobject oldAnnotations = this.annotations;\n\t\t\tAnnotationList list = oldAnnotations as AnnotationList;\n\t\t\tif (list != null)\n\t\t\t{\n\t\t\t\tlock (list)\n\t\t\t\t\tlist.RemoveAll(obj => obj is T);\n\t\t\t}\n\t\t\telse if (oldAnnotations is T)\n\t\t\t{\n\t\t\t\tif (Interlocked.CompareExchange(ref this.annotations, null, oldAnnotations) != oldAnnotations)\n\t\t\t\t{\n\t\t\t\t\t// Operation failed (some other thread wrote to this.annotations first)\n\t\t\t\t\tgoto retry;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic virtual void RemoveAnnotations(Type type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tretry: // Retry until successful\n\t\t\tobject oldAnnotations = this.annotations;\n\t\t\tAnnotationList list = oldAnnotations as AnnotationList;\n\t\t\tif (list != null)\n\t\t\t{\n\t\t\t\tlock (list)\n\t\t\t\t\tlist.RemoveAll(type.IsInstanceOfType);\n\t\t\t}\n\t\t\telse if (type.IsInstanceOfType(oldAnnotations))\n\t\t\t{\n\t\t\t\tif (Interlocked.CompareExchange(ref this.annotations, null, oldAnnotations) != oldAnnotations)\n\t\t\t\t{\n\t\t\t\t\t// Operation failed (some other thread wrote to this.annotations first)\n\t\t\t\t\tgoto retry;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic T Annotation<T>() where T : class\n\t\t{\n\t\t\tobject annotations = this.annotations;\n\t\t\tAnnotationList list = annotations as AnnotationList;\n\t\t\tif (list != null)\n\t\t\t{\n\t\t\t\tlock (list)\n\t\t\t\t{\n\t\t\t\t\tforeach (object obj in list)\n\t\t\t\t\t{\n\t\t\t\t\t\tT t = obj as T;\n\t\t\t\t\t\tif (t != null)\n\t\t\t\t\t\t\treturn t;\n\t\t\t\t\t}\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn annotations as T;\n\t\t\t}\n\t\t}\n\n\t\tpublic object Annotation(Type type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tobject annotations = this.annotations;\n\t\t\tAnnotationList list = annotations as AnnotationList;\n\t\t\tif (list != null)\n\t\t\t{\n\t\t\t\tlock (list)\n\t\t\t\t{\n\t\t\t\t\tforeach (object obj in list)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (type.IsInstanceOfType(obj))\n\t\t\t\t\t\t\treturn obj;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (type.IsInstanceOfType(annotations))\n\t\t\t\t\treturn annotations;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets all annotations stored on this AstNode.\n\t\t/// </summary>\n\t\tpublic IEnumerable<object> Annotations {\n\t\t\tget {\n\t\t\t\tobject annotations = this.annotations;\n\t\t\t\tAnnotationList list = annotations as AnnotationList;\n\t\t\t\tif (list != null)\n\t\t\t\t{\n\t\t\t\t\tlock (list)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn list.ToArray();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (annotations != null)\n\t\t\t\t\t\treturn new object[] { annotations };\n\t\t\t\t\telse\n\t\t\t\t\t\treturn Enumerable.Empty<object>();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/IAstVisitor.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// AST visitor.\n\t/// </summary>\n\tpublic interface IAstVisitor\n\t{\n\t\tvoid VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression);\n\t\tvoid VisitAnonymousTypeCreateExpression(AnonymousTypeCreateExpression anonymousTypeCreateExpression);\n\t\tvoid VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression);\n\t\tvoid VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression);\n\t\tvoid VisitAsExpression(AsExpression asExpression);\n\t\tvoid VisitAssignmentExpression(AssignmentExpression assignmentExpression);\n\t\tvoid VisitBaseReferenceExpression(BaseReferenceExpression baseReferenceExpression);\n\t\tvoid VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression);\n\t\tvoid VisitCastExpression(CastExpression castExpression);\n\t\tvoid VisitCheckedExpression(CheckedExpression checkedExpression);\n\t\tvoid VisitConditionalExpression(ConditionalExpression conditionalExpression);\n\t\tvoid VisitDeclarationExpression(DeclarationExpression declarationExpression);\n\t\tvoid VisitRecursivePatternExpression(RecursivePatternExpression recursivePatternExpression);\n\t\tvoid VisitDefaultValueExpression(DefaultValueExpression defaultValueExpression);\n\t\tvoid VisitDirectionExpression(DirectionExpression directionExpression);\n\t\tvoid VisitIdentifierExpression(IdentifierExpression identifierExpression);\n\t\tvoid VisitIndexerExpression(IndexerExpression indexerExpression);\n\t\tvoid VisitInterpolatedStringExpression(InterpolatedStringExpression interpolatedStringExpression);\n\t\tvoid VisitInvocationExpression(InvocationExpression invocationExpression);\n\t\tvoid VisitIsExpression(IsExpression isExpression);\n\t\tvoid VisitLambdaExpression(LambdaExpression lambdaExpression);\n\t\tvoid VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression);\n\t\tvoid VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression);\n\t\tvoid VisitNamedExpression(NamedExpression namedExpression);\n\t\tvoid VisitNullReferenceExpression(NullReferenceExpression nullReferenceExpression);\n\t\tvoid VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression);\n\t\tvoid VisitOutVarDeclarationExpression(OutVarDeclarationExpression outVarDeclarationExpression);\n\t\tvoid VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression);\n\t\tvoid VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression);\n\t\tvoid VisitPrimitiveExpression(PrimitiveExpression primitiveExpression);\n\t\tvoid VisitSizeOfExpression(SizeOfExpression sizeOfExpression);\n\t\tvoid VisitStackAllocExpression(StackAllocExpression stackAllocExpression);\n\t\tvoid VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression);\n\t\tvoid VisitThrowExpression(ThrowExpression throwExpression);\n\t\tvoid VisitTupleExpression(TupleExpression tupleExpression);\n\t\tvoid VisitTypeOfExpression(TypeOfExpression typeOfExpression);\n\t\tvoid VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression);\n\t\tvoid VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression);\n\t\tvoid VisitUncheckedExpression(UncheckedExpression uncheckedExpression);\n\t\tvoid VisitUndocumentedExpression(UndocumentedExpression undocumentedExpression);\n\t\tvoid VisitWithInitializerExpression(WithInitializerExpression withInitializerExpression);\n\n\t\tvoid VisitQueryExpression(QueryExpression queryExpression);\n\t\tvoid VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause);\n\t\tvoid VisitQueryFromClause(QueryFromClause queryFromClause);\n\t\tvoid VisitQueryLetClause(QueryLetClause queryLetClause);\n\t\tvoid VisitQueryWhereClause(QueryWhereClause queryWhereClause);\n\t\tvoid VisitQueryJoinClause(QueryJoinClause queryJoinClause);\n\t\tvoid VisitQueryOrderClause(QueryOrderClause queryOrderClause);\n\t\tvoid VisitQueryOrdering(QueryOrdering queryOrdering);\n\t\tvoid VisitQuerySelectClause(QuerySelectClause querySelectClause);\n\t\tvoid VisitQueryGroupClause(QueryGroupClause queryGroupClause);\n\n\t\tvoid VisitAttribute(Attribute attribute);\n\t\tvoid VisitAttributeSection(AttributeSection attributeSection);\n\t\tvoid VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration);\n\t\tvoid VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration);\n\t\tvoid VisitTypeDeclaration(TypeDeclaration typeDeclaration);\n\t\tvoid VisitUsingAliasDeclaration(UsingAliasDeclaration usingAliasDeclaration);\n\t\tvoid VisitUsingDeclaration(UsingDeclaration usingDeclaration);\n\t\tvoid VisitExternAliasDeclaration(ExternAliasDeclaration externAliasDeclaration);\n\n\t\tvoid VisitBlockStatement(BlockStatement blockStatement);\n\t\tvoid VisitBreakStatement(BreakStatement breakStatement);\n\t\tvoid VisitCheckedStatement(CheckedStatement checkedStatement);\n\t\tvoid VisitContinueStatement(ContinueStatement continueStatement);\n\t\tvoid VisitDoWhileStatement(DoWhileStatement doWhileStatement);\n\t\tvoid VisitEmptyStatement(EmptyStatement emptyStatement);\n\t\tvoid VisitExpressionStatement(ExpressionStatement expressionStatement);\n\t\tvoid VisitFixedStatement(FixedStatement fixedStatement);\n\t\tvoid VisitForeachStatement(ForeachStatement foreachStatement);\n\t\tvoid VisitForStatement(ForStatement forStatement);\n\t\tvoid VisitGotoCaseStatement(GotoCaseStatement gotoCaseStatement);\n\t\tvoid VisitGotoDefaultStatement(GotoDefaultStatement gotoDefaultStatement);\n\t\tvoid VisitGotoStatement(GotoStatement gotoStatement);\n\t\tvoid VisitIfElseStatement(IfElseStatement ifElseStatement);\n\t\tvoid VisitLabelStatement(LabelStatement labelStatement);\n\t\tvoid VisitLockStatement(LockStatement lockStatement);\n\t\tvoid VisitReturnStatement(ReturnStatement returnStatement);\n\t\tvoid VisitSwitchStatement(SwitchStatement switchStatement);\n\t\tvoid VisitSwitchSection(SwitchSection switchSection);\n\t\tvoid VisitCaseLabel(CaseLabel caseLabel);\n\t\tvoid VisitSwitchExpression(SwitchExpression switchExpression);\n\t\tvoid VisitSwitchExpressionSection(SwitchExpressionSection switchExpressionSection);\n\t\tvoid VisitThrowStatement(ThrowStatement throwStatement);\n\t\tvoid VisitTryCatchStatement(TryCatchStatement tryCatchStatement);\n\t\tvoid VisitCatchClause(CatchClause catchClause);\n\t\tvoid VisitUncheckedStatement(UncheckedStatement uncheckedStatement);\n\t\tvoid VisitUnsafeStatement(UnsafeStatement unsafeStatement);\n\t\tvoid VisitUsingStatement(UsingStatement usingStatement);\n\t\tvoid VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement);\n\t\tvoid VisitLocalFunctionDeclarationStatement(LocalFunctionDeclarationStatement localFunctionDeclarationStatement);\n\t\tvoid VisitWhileStatement(WhileStatement whileStatement);\n\t\tvoid VisitYieldBreakStatement(YieldBreakStatement yieldBreakStatement);\n\t\tvoid VisitYieldReturnStatement(YieldReturnStatement yieldReturnStatement);\n\n\t\tvoid VisitAccessor(Accessor accessor);\n\t\tvoid VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration);\n\t\tvoid VisitConstructorInitializer(ConstructorInitializer constructorInitializer);\n\t\tvoid VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration);\n\t\tvoid VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration);\n\t\tvoid VisitEventDeclaration(EventDeclaration eventDeclaration);\n\t\tvoid VisitCustomEventDeclaration(CustomEventDeclaration customEventDeclaration);\n\t\tvoid VisitFieldDeclaration(FieldDeclaration fieldDeclaration);\n\t\tvoid VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration);\n\t\tvoid VisitMethodDeclaration(MethodDeclaration methodDeclaration);\n\t\tvoid VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration);\n\t\tvoid VisitParameterDeclaration(ParameterDeclaration parameterDeclaration);\n\t\tvoid VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration);\n\t\tvoid VisitVariableInitializer(VariableInitializer variableInitializer);\n\t\tvoid VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration);\n\t\tvoid VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer);\n\t\tvoid VisitExtensionDeclaration(ExtensionDeclaration extensionDeclaration);\n\n\t\tvoid VisitSyntaxTree(SyntaxTree syntaxTree);\n\t\tvoid VisitSimpleType(SimpleType simpleType);\n\t\tvoid VisitMemberType(MemberType memberType);\n\t\tvoid VisitTupleType(TupleAstType tupleType);\n\t\tvoid VisitTupleTypeElement(TupleTypeElement tupleTypeElement);\n\t\tvoid VisitFunctionPointerType(FunctionPointerAstType functionPointerType);\n\t\tvoid VisitInvocationType(InvocationAstType invocationType);\n\t\tvoid VisitComposedType(ComposedType composedType);\n\t\tvoid VisitArraySpecifier(ArraySpecifier arraySpecifier);\n\t\tvoid VisitPrimitiveType(PrimitiveType primitiveType);\n\n\t\tvoid VisitComment(Comment comment);\n\t\tvoid VisitPreProcessorDirective(PreProcessorDirective preProcessorDirective);\n\t\tvoid VisitDocumentationReference(DocumentationReference documentationReference);\n\n\t\tvoid VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration);\n\t\tvoid VisitConstraint(Constraint constraint);\n\t\tvoid VisitCSharpTokenNode(CSharpTokenNode cSharpTokenNode);\n\t\tvoid VisitIdentifier(Identifier identifier);\n\n\t\tvoid VisitInterpolation(Interpolation interpolation);\n\t\tvoid VisitInterpolatedStringText(InterpolatedStringText interpolatedStringText);\n\n\t\tvoid VisitSingleVariableDesignation(SingleVariableDesignation singleVariableDesignation);\n\t\tvoid VisitParenthesizedVariableDesignation(ParenthesizedVariableDesignation parenthesizedVariableDesignation);\n\n\t\tvoid VisitNullNode(AstNode nullNode);\n\t\tvoid VisitErrorNode(AstNode errorNode);\n\t\tvoid VisitPatternPlaceholder(AstNode placeholder, PatternMatching.Pattern pattern);\n\t}\n\n\t/// <summary>\n\t/// AST visitor.\n\t/// </summary>\n\tpublic interface IAstVisitor<out S>\n\t{\n\t\tS VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression);\n\t\tS VisitAnonymousTypeCreateExpression(AnonymousTypeCreateExpression anonymousTypeCreateExpression);\n\t\tS VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression);\n\t\tS VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression);\n\t\tS VisitAsExpression(AsExpression asExpression);\n\t\tS VisitAssignmentExpression(AssignmentExpression assignmentExpression);\n\t\tS VisitBaseReferenceExpression(BaseReferenceExpression baseReferenceExpression);\n\t\tS VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression);\n\t\tS VisitCastExpression(CastExpression castExpression);\n\t\tS VisitCheckedExpression(CheckedExpression checkedExpression);\n\t\tS VisitConditionalExpression(ConditionalExpression conditionalExpression);\n\t\tS VisitDeclarationExpression(DeclarationExpression declarationExpression);\n\t\tS VisitRecursivePatternExpression(RecursivePatternExpression recursivePatternExpression);\n\t\tS VisitDefaultValueExpression(DefaultValueExpression defaultValueExpression);\n\t\tS VisitDirectionExpression(DirectionExpression directionExpression);\n\t\tS VisitIdentifierExpression(IdentifierExpression identifierExpression);\n\t\tS VisitIndexerExpression(IndexerExpression indexerExpression);\n\t\tS VisitInterpolatedStringExpression(InterpolatedStringExpression interpolatedStringExpression);\n\t\tS VisitInvocationExpression(InvocationExpression invocationExpression);\n\t\tS VisitIsExpression(IsExpression isExpression);\n\t\tS VisitLambdaExpression(LambdaExpression lambdaExpression);\n\t\tS VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression);\n\t\tS VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression);\n\t\tS VisitNamedExpression(NamedExpression namedExpression);\n\t\tS VisitNullReferenceExpression(NullReferenceExpression nullReferenceExpression);\n\t\tS VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression);\n\t\tS VisitOutVarDeclarationExpression(OutVarDeclarationExpression outVarDeclarationExpression);\n\t\tS VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression);\n\t\tS VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression);\n\t\tS VisitPrimitiveExpression(PrimitiveExpression primitiveExpression);\n\t\tS VisitSizeOfExpression(SizeOfExpression sizeOfExpression);\n\t\tS VisitStackAllocExpression(StackAllocExpression stackAllocExpression);\n\t\tS VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression);\n\t\tS VisitThrowExpression(ThrowExpression throwExpression);\n\t\tS VisitTupleExpression(TupleExpression tupleExpression);\n\t\tS VisitTypeOfExpression(TypeOfExpression typeOfExpression);\n\t\tS VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression);\n\t\tS VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression);\n\t\tS VisitUncheckedExpression(UncheckedExpression uncheckedExpression);\n\t\tS VisitUndocumentedExpression(UndocumentedExpression undocumentedExpression);\n\t\tS VisitWithInitializerExpression(WithInitializerExpression withInitializerExpression);\n\n\t\tS VisitQueryExpression(QueryExpression queryExpression);\n\t\tS VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause);\n\t\tS VisitQueryFromClause(QueryFromClause queryFromClause);\n\t\tS VisitQueryLetClause(QueryLetClause queryLetClause);\n\t\tS VisitQueryWhereClause(QueryWhereClause queryWhereClause);\n\t\tS VisitQueryJoinClause(QueryJoinClause queryJoinClause);\n\t\tS VisitQueryOrderClause(QueryOrderClause queryOrderClause);\n\t\tS VisitQueryOrdering(QueryOrdering queryOrdering);\n\t\tS VisitQuerySelectClause(QuerySelectClause querySelectClause);\n\t\tS VisitQueryGroupClause(QueryGroupClause queryGroupClause);\n\n\t\tS VisitAttribute(Attribute attribute);\n\t\tS VisitAttributeSection(AttributeSection attributeSection);\n\t\tS VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration);\n\t\tS VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration);\n\t\tS VisitTypeDeclaration(TypeDeclaration typeDeclaration);\n\t\tS VisitUsingAliasDeclaration(UsingAliasDeclaration usingAliasDeclaration);\n\t\tS VisitUsingDeclaration(UsingDeclaration usingDeclaration);\n\t\tS VisitExternAliasDeclaration(ExternAliasDeclaration externAliasDeclaration);\n\n\t\tS VisitBlockStatement(BlockStatement blockStatement);\n\t\tS VisitBreakStatement(BreakStatement breakStatement);\n\t\tS VisitCheckedStatement(CheckedStatement checkedStatement);\n\t\tS VisitContinueStatement(ContinueStatement continueStatement);\n\t\tS VisitDoWhileStatement(DoWhileStatement doWhileStatement);\n\t\tS VisitEmptyStatement(EmptyStatement emptyStatement);\n\t\tS VisitExpressionStatement(ExpressionStatement expressionStatement);\n\t\tS VisitFixedStatement(FixedStatement fixedStatement);\n\t\tS VisitForeachStatement(ForeachStatement foreachStatement);\n\t\tS VisitForStatement(ForStatement forStatement);\n\t\tS VisitGotoCaseStatement(GotoCaseStatement gotoCaseStatement);\n\t\tS VisitGotoDefaultStatement(GotoDefaultStatement gotoDefaultStatement);\n\t\tS VisitGotoStatement(GotoStatement gotoStatement);\n\t\tS VisitIfElseStatement(IfElseStatement ifElseStatement);\n\t\tS VisitLabelStatement(LabelStatement labelStatement);\n\t\tS VisitLockStatement(LockStatement lockStatement);\n\t\tS VisitReturnStatement(ReturnStatement returnStatement);\n\t\tS VisitSwitchStatement(SwitchStatement switchStatement);\n\t\tS VisitSwitchSection(SwitchSection switchSection);\n\t\tS VisitCaseLabel(CaseLabel caseLabel);\n\t\tS VisitSwitchExpression(SwitchExpression switchExpression);\n\t\tS VisitSwitchExpressionSection(SwitchExpressionSection switchExpressionSection);\n\t\tS VisitThrowStatement(ThrowStatement throwStatement);\n\t\tS VisitTryCatchStatement(TryCatchStatement tryCatchStatement);\n\t\tS VisitCatchClause(CatchClause catchClause);\n\t\tS VisitUncheckedStatement(UncheckedStatement uncheckedStatement);\n\t\tS VisitUnsafeStatement(UnsafeStatement unsafeStatement);\n\t\tS VisitUsingStatement(UsingStatement usingStatement);\n\t\tS VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement);\n\t\tS VisitLocalFunctionDeclarationStatement(LocalFunctionDeclarationStatement localFunctionDeclarationStatement);\n\t\tS VisitWhileStatement(WhileStatement whileStatement);\n\t\tS VisitYieldBreakStatement(YieldBreakStatement yieldBreakStatement);\n\t\tS VisitYieldReturnStatement(YieldReturnStatement yieldReturnStatement);\n\n\t\tS VisitAccessor(Accessor accessor);\n\t\tS VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration);\n\t\tS VisitConstructorInitializer(ConstructorInitializer constructorInitializer);\n\t\tS VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration);\n\t\tS VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration);\n\t\tS VisitEventDeclaration(EventDeclaration eventDeclaration);\n\t\tS VisitCustomEventDeclaration(CustomEventDeclaration customEventDeclaration);\n\t\tS VisitFieldDeclaration(FieldDeclaration fieldDeclaration);\n\t\tS VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration);\n\t\tS VisitMethodDeclaration(MethodDeclaration methodDeclaration);\n\t\tS VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration);\n\t\tS VisitParameterDeclaration(ParameterDeclaration parameterDeclaration);\n\t\tS VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration);\n\t\tS VisitVariableInitializer(VariableInitializer variableInitializer);\n\t\tS VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration);\n\t\tS VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer);\n\t\tS VisitExtensionDeclaration(ExtensionDeclaration extensionDeclaration);\n\n\t\tS VisitSyntaxTree(SyntaxTree syntaxTree);\n\t\tS VisitSimpleType(SimpleType simpleType);\n\t\tS VisitMemberType(MemberType memberType);\n\t\tS VisitTupleType(TupleAstType tupleType);\n\t\tS VisitTupleTypeElement(TupleTypeElement tupleTypeElement);\n\t\tS VisitFunctionPointerType(FunctionPointerAstType functionPointerType);\n\t\tS VisitInvocationType(InvocationAstType invocationType);\n\t\tS VisitComposedType(ComposedType composedType);\n\t\tS VisitArraySpecifier(ArraySpecifier arraySpecifier);\n\t\tS VisitPrimitiveType(PrimitiveType primitiveType);\n\n\t\tS VisitComment(Comment comment);\n\t\tS VisitPreProcessorDirective(PreProcessorDirective preProcessorDirective);\n\t\tS VisitDocumentationReference(DocumentationReference documentationReference);\n\n\t\tS VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration);\n\t\tS VisitConstraint(Constraint constraint);\n\t\tS VisitCSharpTokenNode(CSharpTokenNode cSharpTokenNode);\n\t\tS VisitIdentifier(Identifier identifier);\n\n\t\tS VisitInterpolation(Interpolation interpolation);\n\t\tS VisitInterpolatedStringText(InterpolatedStringText interpolatedStringText);\n\n\t\tS VisitSingleVariableDesignation(SingleVariableDesignation singleVariableDesignation);\n\t\tS VisitParenthesizedVariableDesignation(ParenthesizedVariableDesignation parenthesizedVariableDesignation);\n\n\t\tS VisitNullNode(AstNode nullNode);\n\t\tS VisitErrorNode(AstNode errorNode);\n\t\tS VisitPatternPlaceholder(AstNode placeholder, PatternMatching.Pattern pattern);\n\t}\n\n\t/// <summary>\n\t/// AST visitor.\n\t/// </summary>\n\tpublic interface IAstVisitor<in T, out S>\n\t{\n\t\tS VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression, T data);\n\t\tS VisitAnonymousTypeCreateExpression(AnonymousTypeCreateExpression anonymousTypeCreateExpression, T data);\n\t\tS VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression, T data);\n\t\tS VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression, T data);\n\t\tS VisitAsExpression(AsExpression asExpression, T data);\n\t\tS VisitAssignmentExpression(AssignmentExpression assignmentExpression, T data);\n\t\tS VisitBaseReferenceExpression(BaseReferenceExpression baseReferenceExpression, T data);\n\t\tS VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, T data);\n\t\tS VisitCastExpression(CastExpression castExpression, T data);\n\t\tS VisitCheckedExpression(CheckedExpression checkedExpression, T data);\n\t\tS VisitConditionalExpression(ConditionalExpression conditionalExpression, T data);\n\t\tS VisitDeclarationExpression(DeclarationExpression declarationExpression, T data);\n\t\tS VisitRecursivePatternExpression(RecursivePatternExpression recursivePatternExpression, T data);\n\t\tS VisitDefaultValueExpression(DefaultValueExpression defaultValueExpression, T data);\n\t\tS VisitDirectionExpression(DirectionExpression directionExpression, T data);\n\t\tS VisitIdentifierExpression(IdentifierExpression identifierExpression, T data);\n\t\tS VisitIndexerExpression(IndexerExpression indexerExpression, T data);\n\t\tS VisitInterpolatedStringExpression(InterpolatedStringExpression interpolatedStringExpression, T data);\n\t\tS VisitInvocationExpression(InvocationExpression invocationExpression, T data);\n\t\tS VisitIsExpression(IsExpression isExpression, T data);\n\t\tS VisitLambdaExpression(LambdaExpression lambdaExpression, T data);\n\t\tS VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, T data);\n\t\tS VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression, T data);\n\t\tS VisitNamedExpression(NamedExpression namedExpression, T data);\n\t\tS VisitNullReferenceExpression(NullReferenceExpression nullReferenceExpression, T data);\n\t\tS VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, T data);\n\t\tS VisitOutVarDeclarationExpression(OutVarDeclarationExpression outVarDeclarationExpression, T data);\n\t\tS VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression, T data);\n\t\tS VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression, T data);\n\t\tS VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, T data);\n\t\tS VisitSizeOfExpression(SizeOfExpression sizeOfExpression, T data);\n\t\tS VisitStackAllocExpression(StackAllocExpression stackAllocExpression, T data);\n\t\tS VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, T data);\n\t\tS VisitThrowExpression(ThrowExpression throwExpression, T data);\n\t\tS VisitTupleExpression(TupleExpression tupleExpression, T data);\n\t\tS VisitTypeOfExpression(TypeOfExpression typeOfExpression, T data);\n\t\tS VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression, T data);\n\t\tS VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, T data);\n\t\tS VisitUncheckedExpression(UncheckedExpression uncheckedExpression, T data);\n\t\tS VisitUndocumentedExpression(UndocumentedExpression undocumentedExpression, T data);\n\t\tS VisitWithInitializerExpression(WithInitializerExpression withInitializerExpression, T data);\n\n\t\tS VisitQueryExpression(QueryExpression queryExpression, T data);\n\t\tS VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause, T data);\n\t\tS VisitQueryFromClause(QueryFromClause queryFromClause, T data);\n\t\tS VisitQueryLetClause(QueryLetClause queryLetClause, T data);\n\t\tS VisitQueryWhereClause(QueryWhereClause queryWhereClause, T data);\n\t\tS VisitQueryJoinClause(QueryJoinClause queryJoinClause, T data);\n\t\tS VisitQueryOrderClause(QueryOrderClause queryOrderClause, T data);\n\t\tS VisitQueryOrdering(QueryOrdering queryOrdering, T data);\n\t\tS VisitQuerySelectClause(QuerySelectClause querySelectClause, T data);\n\t\tS VisitQueryGroupClause(QueryGroupClause queryGroupClause, T data);\n\n\t\tS VisitAttribute(Attribute attribute, T data);\n\t\tS VisitAttributeSection(AttributeSection attributeSection, T data);\n\t\tS VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration, T data);\n\t\tS VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, T data);\n\t\tS VisitTypeDeclaration(TypeDeclaration typeDeclaration, T data);\n\t\tS VisitUsingAliasDeclaration(UsingAliasDeclaration usingAliasDeclaration, T data);\n\t\tS VisitUsingDeclaration(UsingDeclaration usingDeclaration, T data);\n\t\tS VisitExternAliasDeclaration(ExternAliasDeclaration externAliasDeclaration, T data);\n\n\t\tS VisitBlockStatement(BlockStatement blockStatement, T data);\n\t\tS VisitBreakStatement(BreakStatement breakStatement, T data);\n\t\tS VisitCheckedStatement(CheckedStatement checkedStatement, T data);\n\t\tS VisitContinueStatement(ContinueStatement continueStatement, T data);\n\t\tS VisitDoWhileStatement(DoWhileStatement doWhileStatement, T data);\n\t\tS VisitEmptyStatement(EmptyStatement emptyStatement, T data);\n\t\tS VisitExpressionStatement(ExpressionStatement expressionStatement, T data);\n\t\tS VisitFixedStatement(FixedStatement fixedStatement, T data);\n\t\tS VisitForeachStatement(ForeachStatement foreachStatement, T data);\n\t\tS VisitForStatement(ForStatement forStatement, T data);\n\t\tS VisitGotoCaseStatement(GotoCaseStatement gotoCaseStatement, T data);\n\t\tS VisitGotoDefaultStatement(GotoDefaultStatement gotoDefaultStatement, T data);\n\t\tS VisitGotoStatement(GotoStatement gotoStatement, T data);\n\t\tS VisitIfElseStatement(IfElseStatement ifElseStatement, T data);\n\t\tS VisitLabelStatement(LabelStatement labelStatement, T data);\n\t\tS VisitLockStatement(LockStatement lockStatement, T data);\n\t\tS VisitReturnStatement(ReturnStatement returnStatement, T data);\n\t\tS VisitSwitchStatement(SwitchStatement switchStatement, T data);\n\t\tS VisitSwitchSection(SwitchSection switchSection, T data);\n\t\tS VisitCaseLabel(CaseLabel caseLabel, T data);\n\t\tS VisitSwitchExpression(SwitchExpression switchExpression, T data);\n\t\tS VisitSwitchExpressionSection(SwitchExpressionSection switchExpressionSection, T data);\n\t\tS VisitThrowStatement(ThrowStatement throwStatement, T data);\n\t\tS VisitTryCatchStatement(TryCatchStatement tryCatchStatement, T data);\n\t\tS VisitCatchClause(CatchClause catchClause, T data);\n\t\tS VisitUncheckedStatement(UncheckedStatement uncheckedStatement, T data);\n\t\tS VisitUnsafeStatement(UnsafeStatement unsafeStatement, T data);\n\t\tS VisitUsingStatement(UsingStatement usingStatement, T data);\n\t\tS VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement, T data);\n\t\tS VisitLocalFunctionDeclarationStatement(LocalFunctionDeclarationStatement localFunctionDeclarationStatement, T data);\n\t\tS VisitWhileStatement(WhileStatement whileStatement, T data);\n\t\tS VisitYieldBreakStatement(YieldBreakStatement yieldBreakStatement, T data);\n\t\tS VisitYieldReturnStatement(YieldReturnStatement yieldReturnStatement, T data);\n\n\t\tS VisitAccessor(Accessor accessor, T data);\n\t\tS VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration, T data);\n\t\tS VisitConstructorInitializer(ConstructorInitializer constructorInitializer, T data);\n\t\tS VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration, T data);\n\t\tS VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration, T data);\n\t\tS VisitEventDeclaration(EventDeclaration eventDeclaration, T data);\n\t\tS VisitCustomEventDeclaration(CustomEventDeclaration customEventDeclaration, T data);\n\t\tS VisitFieldDeclaration(FieldDeclaration fieldDeclaration, T data);\n\t\tS VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration, T data);\n\t\tS VisitMethodDeclaration(MethodDeclaration methodDeclaration, T data);\n\t\tS VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration, T data);\n\t\tS VisitParameterDeclaration(ParameterDeclaration parameterDeclaration, T data);\n\t\tS VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, T data);\n\t\tS VisitVariableInitializer(VariableInitializer variableInitializer, T data);\n\t\tS VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration, T data);\n\t\tS VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer, T data);\n\t\tS VisitExtensionDeclaration(ExtensionDeclaration extensionDeclaration, T data);\n\n\t\tS VisitSyntaxTree(SyntaxTree syntaxTree, T data);\n\t\tS VisitSimpleType(SimpleType simpleType, T data);\n\t\tS VisitMemberType(MemberType memberType, T data);\n\t\tS VisitTupleType(TupleAstType tupleType, T data);\n\t\tS VisitTupleTypeElement(TupleTypeElement tupleTypeElement, T data);\n\t\tS VisitFunctionPointerType(FunctionPointerAstType functionPointerType, T data);\n\t\tS VisitInvocationType(InvocationAstType invocationType, T data);\n\t\tS VisitComposedType(ComposedType composedType, T data);\n\t\tS VisitArraySpecifier(ArraySpecifier arraySpecifier, T data);\n\t\tS VisitPrimitiveType(PrimitiveType primitiveType, T data);\n\n\t\tS VisitComment(Comment comment, T data);\n\t\tS VisitPreProcessorDirective(PreProcessorDirective preProcessorDirective, T data);\n\t\tS VisitDocumentationReference(DocumentationReference documentationReference, T data);\n\n\t\tS VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration, T data);\n\t\tS VisitConstraint(Constraint constraint, T data);\n\t\tS VisitCSharpTokenNode(CSharpTokenNode cSharpTokenNode, T data);\n\t\tS VisitIdentifier(Identifier identifier, T data);\n\n\t\tS VisitInterpolation(Interpolation interpolation, T data);\n\t\tS VisitInterpolatedStringText(InterpolatedStringText interpolatedStringText, T data);\n\n\t\tS VisitSingleVariableDesignation(SingleVariableDesignation singleVariableDesignation, T data);\n\t\tS VisitParenthesizedVariableDesignation(ParenthesizedVariableDesignation parenthesizedVariableDesignation, T data);\n\n\t\tS VisitNullNode(AstNode nullNode, T data);\n\t\tS VisitErrorNode(AstNode errorNode, T data);\n\t\tS VisitPatternPlaceholder(AstNode placeholder, PatternMatching.Pattern pattern, T data);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Identifier.cs",
    "content": "// \n// Identifier.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class Identifier : AstNode\n\t{\n\t\tpublic new static readonly Identifier Null = new NullIdentifier();\n\t\tsealed class NullIdentifier : Identifier\n\t\t{\n\t\t\tpublic override bool IsNull {\n\t\t\t\tget {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn other == null || other.IsNull;\n\t\t\t}\n\t\t}\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget {\n\t\t\t\treturn NodeType.Token;\n\t\t\t}\n\t\t}\n\n\t\tstring name;\n\t\tpublic string Name {\n\t\t\tget { return this.name; }\n\t\t\tset {\n\t\t\t\tif (value == null)\n\t\t\t\t\tthrow new ArgumentNullException(nameof(value));\n\t\t\t\tThrowIfFrozen();\n\t\t\t\tthis.name = value;\n\t\t\t}\n\t\t}\n\n\t\tTextLocation startLocation;\n\t\tpublic override TextLocation StartLocation {\n\t\t\tget {\n\t\t\t\treturn startLocation;\n\t\t\t}\n\t\t}\n\n\t\tinternal void SetStartLocation(TextLocation value)\n\t\t{\n\t\t\tThrowIfFrozen();\n\t\t\tthis.startLocation = value;\n\t\t}\n\n\t\tconst uint verbatimBit = 1u << AstNodeFlagsUsedBits;\n\n\t\tpublic bool IsVerbatim {\n\t\t\tget {\n\t\t\t\treturn (flags & verbatimBit) != 0;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tThrowIfFrozen();\n\t\t\t\tif (value)\n\t\t\t\t\tflags |= verbatimBit;\n\t\t\t\telse\n\t\t\t\t\tflags &= ~verbatimBit;\n\t\t\t}\n\t\t}\n\n\t\tpublic override TextLocation EndLocation {\n\t\t\tget {\n\t\t\t\treturn new TextLocation(StartLocation.Line, StartLocation.Column + (Name ?? \"\").Length + (IsVerbatim ? 1 : 0));\n\t\t\t}\n\t\t}\n\n\t\tIdentifier()\n\t\t{\n\t\t\tthis.name = string.Empty;\n\t\t}\n\n\t\tprotected Identifier(string name, TextLocation location)\n\t\t{\n\t\t\tif (name == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(name));\n\t\t\tthis.Name = name;\n\t\t\tthis.startLocation = location;\n\t\t}\n\n\t\tpublic static Identifier Create(string name)\n\t\t{\n\t\t\treturn Create(name, TextLocation.Empty);\n\t\t}\n\n\t\tpublic static Identifier Create(string name, TextLocation location)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(name))\n\t\t\t\treturn Identifier.Null;\n\t\t\tif (name[0] == '@')\n\t\t\t\treturn new Identifier(name.Substring(1), new TextLocation(location.Line, location.Column + 1)) { IsVerbatim = true };\n\t\t\telse\n\t\t\t\treturn new Identifier(name, location);\n\t\t}\n\n\t\tpublic static Identifier Create(string name, TextLocation location, bool isVerbatim)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(name))\n\t\t\t\treturn Identifier.Null;\n\n\t\t\tif (isVerbatim)\n\t\t\t\treturn new Identifier(name, location) { IsVerbatim = true };\n\t\t\treturn new Identifier(name, location);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitIdentifier(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitIdentifier(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitIdentifier(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tIdentifier o = other as Identifier;\n\t\t\treturn o != null && !o.IsNull && MatchString(this.Name, o.Name);\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/IdentifierExpressionBackreference.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Linq;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Matches identifier expressions that have the same identifier as the referenced variable/type definition/method definition.\n\t/// </summary>\n\tpublic class IdentifierExpressionBackreference : PatternMatching.Pattern\n\t{\n\t\treadonly string referencedGroupName;\n\n\t\tpublic string ReferencedGroupName {\n\t\t\tget { return referencedGroupName; }\n\t\t}\n\n\t\tpublic IdentifierExpressionBackreference(string referencedGroupName)\n\t\t{\n\t\t\tif (referencedGroupName == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(referencedGroupName));\n\t\t\tthis.referencedGroupName = referencedGroupName;\n\t\t}\n\n\t\tpublic override bool DoMatch(PatternMatching.INode other, PatternMatching.Match match)\n\t\t{\n\t\t\tIdentifierExpression ident = other as IdentifierExpression;\n\t\t\tif (ident == null || ident.TypeArguments.Any())\n\t\t\t\treturn false;\n\t\t\tAstNode referenced = (AstNode)match.Get(referencedGroupName).Last();\n\t\t\tif (referenced == null)\n\t\t\t\treturn false;\n\t\t\treturn ident.Identifier == referenced.GetChildByRole(Roles.Identifier).Name;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/InvocationAstType.cs",
    "content": "// Copyright (c) 2021 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// BaseType \"(\" Argument { \",\" Argument } \")\"\n\t/// </summary>\n\tpublic class InvocationAstType : AstType\n\t{\n\t\tpublic AstNodeCollection<Expression> Arguments {\n\t\t\tget { return GetChildrenByRole(Roles.Expression); }\n\t\t}\n\n\t\tpublic AstType BaseType {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitInvocationType(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitInvocationType(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitInvocationType(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, Match match)\n\t\t{\n\t\t\treturn other is InvocationAstType o\n\t\t\t\t&& this.BaseType.DoMatch(o.BaseType, match)\n\t\t\t\t&& this.Arguments.DoMatch(o.Arguments, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/MemberType.cs",
    "content": "// \n// FullTypeName.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class MemberType : AstType\n\t{\n\t\tpublic static readonly Role<AstType> TargetRole = new Role<AstType>(\"Target\", AstType.Null);\n\n\t\tbool isDoubleColon;\n\n\t\tpublic bool IsDoubleColon {\n\t\t\tget { return isDoubleColon; }\n\t\t\tset {\n\t\t\t\tThrowIfFrozen();\n\t\t\t\tisDoubleColon = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic AstType Target {\n\t\t\tget { return GetChildByRole(TargetRole); }\n\t\t\tset { SetChildByRole(TargetRole, value); }\n\t\t}\n\n\t\tpublic string MemberName {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier MemberNameToken {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, value);\n\t\t\t}\n\t\t}\n\n\t\tpublic AstNodeCollection<AstType> TypeArguments {\n\t\t\tget { return GetChildrenByRole(Roles.TypeArgument); }\n\t\t}\n\n\t\tpublic MemberType()\n\t\t{\n\t\t}\n\n\t\tpublic MemberType(AstType target, string memberName)\n\t\t{\n\t\t\tthis.Target = target;\n\t\t\tthis.MemberName = memberName;\n\t\t}\n\n\t\tpublic MemberType(AstType target, string memberName, IEnumerable<AstType> typeArguments)\n\t\t{\n\t\t\tthis.Target = target;\n\t\t\tthis.MemberName = memberName;\n\t\t\tforeach (var arg in typeArguments)\n\t\t\t{\n\t\t\t\tAddChild(arg, Roles.TypeArgument);\n\t\t\t}\n\t\t}\n\n\t\tpublic MemberType(AstType target, string memberName, params AstType[] typeArguments) : this(target, memberName, (IEnumerable<AstType>)typeArguments)\n\t\t{\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitMemberType(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitMemberType(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitMemberType(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tMemberType o = other as MemberType;\n\t\t\treturn o != null && this.IsDoubleColon == o.IsDoubleColon\n\t\t\t\t&& MatchString(this.MemberName, o.MemberName) && this.Target.DoMatch(o.Target, match)\n\t\t\t\t&& this.TypeArguments.DoMatch(o.TypeArguments, match);\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Modifiers.cs",
    "content": "//\n// Modifiers.cs\n//\n// Author:\n//   Mike Krüger <mkrueger@novell.com>\n//\n// Copyright (C) 2008 Novell, Inc (http://www.novell.com)\n//\n// Permission is hereby granted, free of charge, to any person obtaining\n// a copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to\n// permit persons to whom the Software is furnished to do so, subject to\n// the following conditions:\n// \n// The above copyright notice and this permission notice shall be\n// included in all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t[Flags]\n\tpublic enum Modifiers\n\t{\n\t\tNone = 0,\n\n\t\tPrivate = 0x0001,\n\t\tInternal = 0x0002,\n\t\tProtected = 0x0004,\n\t\tPublic = 0x0008,\n\n\t\tAbstract = 0x0010,\n\t\tVirtual = 0x0020,\n\t\tSealed = 0x0040,\n\t\tStatic = 0x0080,\n\t\tOverride = 0x0100,\n\t\tReadonly = 0x0200,\n\t\tConst = 0x0400,\n\t\tNew = 0x0800,\n\t\tPartial = 0x1000,\n\n\t\tExtern = 0x2000,\n\t\tVolatile = 0x4000,\n\t\tUnsafe = 0x8000,\n\t\tAsync = 0x10000,\n\t\tRef = 0x20000,\n\t\tRequired = 0x40000,\n\n\t\tVisibilityMask = Private | Internal | Protected | Public,\n\n\t\t/// <summary>\n\t\t/// Special value used to match any modifiers during pattern matching.\n\t\t/// </summary>\n\t\tAny = unchecked((int)0x80000000)\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/NodeType.cs",
    "content": "// \n// NodeType.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic enum NodeType\n\t{\n\t\tUnknown,\n\t\t/// <summary>\n\t\t/// AstType\n\t\t/// </summary>\n\t\tTypeReference,\n\t\t/// <summary>\n\t\t/// Type or delegate declaration\n\t\t/// </summary>\n\t\tTypeDeclaration,\n\t\tMember,\n\t\tStatement,\n\t\tExpression,\n\t\tToken,\n\t\tQueryClause,\n\t\t/// <summary>\n\t\t/// Comment or whitespace or pre-processor directive \n\t\t/// </summary>\n\t\tWhitespace,\n\t\t/// <summary>\n\t\t/// Placeholder for a pattern\n\t\t/// </summary>\n\t\tPattern\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/PatternMatching/AnyNode.cs",
    "content": "// Copyright (c) 2011-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching\n{\n\t/// <summary>\n\t/// Matches any node.\n\t/// </summary>\n\t/// <remarks>Does not match null nodes.</remarks>\n\tpublic class AnyNode : Pattern\n\t{\n\t\treadonly string groupName;\n\n\t\tpublic string GroupName {\n\t\t\tget { return groupName; }\n\t\t}\n\n\t\tpublic AnyNode(string groupName = null)\n\t\t{\n\t\t\tthis.groupName = groupName;\n\t\t}\n\n\t\tpublic override bool DoMatch(INode other, Match match)\n\t\t{\n\t\t\tmatch.Add(this.groupName, other);\n\t\t\treturn other != null && !other.IsNull;\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/PatternMatching/AnyNodeOrNull.cs",
    "content": "//\n// AnyNodeOrNull.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@xamarin.com>\n//\n// Copyright (c) 2013 Xamarin Inc. (http://xamarin.com)\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching\n{\n\t/// <summary>\n\t/// Matches any node.\n\t/// </summary>\n\t/// <remarks>Does not match null nodes.</remarks>\n\tpublic class AnyNodeOrNull : Pattern\n\t{\n\t\treadonly string groupName;\n\n\t\tpublic string GroupName {\n\t\t\tget { return groupName; }\n\t\t}\n\n\t\tpublic AnyNodeOrNull(string groupName = null)\n\t\t{\n\t\t\tthis.groupName = groupName;\n\t\t}\n\n\t\tpublic override bool DoMatch(INode other, Match match)\n\t\t{\n\t\t\tif (other == null)\n\t\t\t{\n\t\t\t\tmatch.AddNull(this.groupName);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tmatch.Add(this.groupName, other);\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/PatternMatching/Backreference.cs",
    "content": "// Copyright (c) 2011-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Linq;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching\n{\n\t/// <summary>\n\t/// Matches the last entry in the specified named group.\n\t/// </summary>\n\tpublic class Backreference : Pattern\n\t{\n\t\treadonly string referencedGroupName;\n\n\t\tpublic string ReferencedGroupName {\n\t\t\tget { return referencedGroupName; }\n\t\t}\n\n\t\tpublic Backreference(string referencedGroupName)\n\t\t{\n\t\t\tif (referencedGroupName == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(referencedGroupName));\n\t\t\tthis.referencedGroupName = referencedGroupName;\n\t\t}\n\n\t\tpublic override bool DoMatch(INode other, Match match)\n\t\t{\n\t\t\tvar last = match.Get(referencedGroupName).LastOrDefault();\n\t\t\tif (last == null && other == null)\n\t\t\t\treturn true;\n\t\t\treturn last.IsMatch(other);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/PatternMatching/BacktrackingInfo.cs",
    "content": "// Copyright (c) 2011-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching\n{\n\t/// <summary>\n\t/// Container for the backtracking info.\n\t/// </summary>\n\tpublic class BacktrackingInfo\n\t{\n\t\tinternal Stack<Pattern.PossibleMatch> backtrackingStack = new Stack<Pattern.PossibleMatch>();\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/PatternMatching/Choice.cs",
    "content": "// Copyright (c) 2011-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching\n{\n\t/// <summary>\n\t/// Matches one of several alternatives.\n\t/// </summary>\n\tpublic class Choice : Pattern, IEnumerable<INode>\n\t{\n\t\treadonly List<INode> alternatives = new List<INode>();\n\n\t\tpublic void Add(string name, INode alternative)\n\t\t{\n\t\t\tif (alternative == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(alternative));\n\t\t\talternatives.Add(new NamedNode(name, alternative));\n\t\t}\n\n\t\tpublic void Add(INode alternative)\n\t\t{\n\t\t\tif (alternative == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(alternative));\n\t\t\talternatives.Add(alternative);\n\t\t}\n\n\t\tpublic override bool DoMatch(INode other, Match match)\n\t\t{\n\t\t\tvar checkPoint = match.CheckPoint();\n\t\t\tforeach (INode alt in alternatives)\n\t\t\t{\n\t\t\t\tif (alt.DoMatch(other, match))\n\t\t\t\t\treturn true;\n\t\t\t\telse\n\t\t\t\t\tmatch.RestoreCheckPoint(checkPoint);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tIEnumerator<INode> IEnumerable<INode>.GetEnumerator()\n\t\t{\n\t\t\treturn alternatives.GetEnumerator();\n\t\t}\n\n\t\tIEnumerator IEnumerable.GetEnumerator()\n\t\t{\n\t\t\treturn alternatives.GetEnumerator();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/PatternMatching/INode.cs",
    "content": "// Copyright (c) 2011-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching\n{\n\t/// <summary>\n\t/// AST node that supports pattern matching.\n\t/// </summary>\n\tpublic interface INode\n\t{\n\t\tRole Role { get; }\n\t\tINode FirstChild { get; }\n\t\tINode NextSibling { get; }\n\t\tbool IsNull { get; }\n\n\t\tbool DoMatch(INode other, Match match);\n\t\tbool DoMatchCollection(Role role, INode pos, Match match, BacktrackingInfo backtrackingInfo);\n\t}\n\n\tpublic static class PatternExtensions\n\t{\n\t\t/// <summary>\n\t\t/// Performs a pattern matching operation.\n\t\t/// <c>this</c> is the pattern, <paramref name=\"other\"/> is the AST that is being matched.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// A match object. Check <see cref=\"PatternMatching.Match.Success\"/> to see whether the match was successful.\n\t\t/// </returns>\n\t\t/// <remarks>\n\t\t/// Patterns are ASTs that contain special pattern nodes (from the PatternMatching namespace).\n\t\t/// However, it is also possible to match two ASTs without any pattern nodes -\n\t\t/// doing so will produce a successful match if the two ASTs are structurally identical.\n\t\t/// </remarks>\n\t\tpublic static Match Match(this INode pattern, INode other)\n\t\t{\n\t\t\tif (pattern == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(pattern));\n\t\t\tMatch match = PatternMatching.Match.CreateNew();\n\t\t\tif (pattern.DoMatch(other, match))\n\t\t\t\treturn match;\n\t\t\telse\n\t\t\t\treturn default(PatternMatching.Match);\n\t\t}\n\n\t\tpublic static bool IsMatch(this INode pattern, INode other)\n\t\t{\n\t\t\tif (pattern == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(pattern));\n\t\t\treturn pattern.DoMatch(other, PatternMatching.Match.CreateNew());\n\t\t}\n\n\t\tpublic static AstType ToType(this Pattern pattern)\n\t\t{\n\t\t\treturn pattern;\n\t\t}\n\n\t\tpublic static Expression ToExpression(this Pattern pattern)\n\t\t{\n\t\t\treturn pattern;\n\t\t}\n\n\t\tpublic static Statement ToStatement(this Pattern pattern)\n\t\t{\n\t\t\treturn pattern;\n\t\t}\n\n\t\tpublic static Expression WithName(this Expression node, string patternGroupName)\n\t\t{\n\t\t\treturn new NamedNode(patternGroupName, node);\n\t\t}\n\n\t\tpublic static Statement WithName(this Statement node, string patternGroupName)\n\t\t{\n\t\t\treturn new NamedNode(patternGroupName, node);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/PatternMatching/Match.cs",
    "content": "// Copyright (c) 2011-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching\n{\n\t/// <summary>\n\t/// Represents the result of a pattern matching operation.\n\t/// </summary>\n\tpublic struct Match\n\t{\n\t\t// TODO: maybe we should add an implicit Match->bool conversion? (implicit operator bool(Match m) { return m != null; })\n\n\t\tList<KeyValuePair<string, INode>> results;\n\n\t\tpublic bool Success {\n\t\t\tget { return results != null; }\n\t\t}\n\n\t\tinternal static Match CreateNew()\n\t\t{\n\t\t\tMatch m;\n\t\t\tm.results = new List<KeyValuePair<string, INode>>();\n\t\t\treturn m;\n\t\t}\n\n\t\tinternal int CheckPoint()\n\t\t{\n\t\t\treturn results.Count;\n\t\t}\n\n\t\tinternal void RestoreCheckPoint(int checkPoint)\n\t\t{\n\t\t\tresults.RemoveRange(checkPoint, results.Count - checkPoint);\n\t\t}\n\n\t\tpublic IEnumerable<INode> Get(string groupName)\n\t\t{\n\t\t\tif (results == null)\n\t\t\t\tyield break;\n\t\t\tforeach (var pair in results)\n\t\t\t{\n\t\t\t\tif (pair.Key == groupName)\n\t\t\t\t\tyield return pair.Value;\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable<T> Get<T>(string groupName) where T : INode\n\t\t{\n\t\t\tif (results == null)\n\t\t\t\tyield break;\n\t\t\tforeach (var pair in results)\n\t\t\t{\n\t\t\t\tif (pair.Key == groupName)\n\t\t\t\t\tyield return (T)pair.Value;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool Has(string groupName)\n\t\t{\n\t\t\tif (results == null)\n\t\t\t\treturn false;\n\t\t\tforeach (var pair in results)\n\t\t\t{\n\t\t\t\tif (pair.Key == groupName)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic void Add(string groupName, INode node)\n\t\t{\n\t\t\tif (groupName != null && node != null)\n\t\t\t{\n\t\t\t\tresults.Add(new KeyValuePair<string, INode>(groupName, node));\n\t\t\t}\n\t\t}\n\n\t\tinternal void AddNull(string groupName)\n\t\t{\n\t\t\tif (groupName != null)\n\t\t\t{\n\t\t\t\tresults.Add(new KeyValuePair<string, INode>(groupName, null));\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/PatternMatching/NamedNode.cs",
    "content": "// Copyright (c) 2011-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching\n{\n\t/// <summary>\n\t/// Represents a named node within a pattern.\n\t/// </summary>\n\tpublic class NamedNode : Pattern\n\t{\n\t\treadonly string groupName;\n\t\treadonly INode childNode;\n\n\t\tpublic string GroupName {\n\t\t\tget { return groupName; }\n\t\t}\n\n\t\tpublic INode ChildNode {\n\t\t\tget { return childNode; }\n\t\t}\n\n\t\tpublic NamedNode(string groupName, INode childNode)\n\t\t{\n\t\t\tif (childNode == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(childNode));\n\t\t\tthis.groupName = groupName;\n\t\t\tthis.childNode = childNode;\n\t\t}\n\n\t\tpublic override bool DoMatch(INode other, Match match)\n\t\t{\n\t\t\tmatch.Add(this.groupName, other);\n\t\t\treturn childNode.DoMatch(other, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/PatternMatching/OptionalNode.cs",
    "content": "// Copyright (c) 2011-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching\n{\n\tpublic class OptionalNode : Pattern\n\t{\n\t\treadonly INode childNode;\n\n\t\tpublic INode ChildNode {\n\t\t\tget { return childNode; }\n\t\t}\n\n\t\tpublic OptionalNode(INode childNode)\n\t\t{\n\t\t\tif (childNode == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(childNode));\n\t\t\tthis.childNode = childNode;\n\t\t}\n\n\t\tpublic OptionalNode(string groupName, INode childNode) : this(new NamedNode(groupName, childNode))\n\t\t{\n\t\t}\n\n\t\tpublic override bool DoMatchCollection(Role role, INode pos, Match match, BacktrackingInfo backtrackingInfo)\n\t\t{\n\t\t\tbacktrackingInfo.backtrackingStack.Push(new PossibleMatch(pos, match.CheckPoint()));\n\t\t\treturn childNode.DoMatch(pos, match);\n\t\t}\n\n\t\tpublic override bool DoMatch(INode other, Match match)\n\t\t{\n\t\t\tif (other == null || other.IsNull)\n\t\t\t\treturn true;\n\t\t\telse\n\t\t\t\treturn childNode.DoMatch(other, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/PatternMatching/Pattern.cs",
    "content": "// Copyright (c) 2011-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching\n{\n\t/// <summary>\n\t/// Base class for all patterns.\n\t/// </summary>\n\tpublic abstract class Pattern : INode\n\t{\n\t\t/// <summary>\n\t\t/// Gets the string that matches any string.\n\t\t/// </summary>\n\t\tpublic static readonly string AnyString = \"$any$\";\n\n\t\tpublic static bool MatchString(string pattern, string text)\n\t\t{\n\t\t\treturn pattern == AnyString || pattern == text;\n\t\t}\n\n\t\tinternal struct PossibleMatch\n\t\t{\n\t\t\tpublic readonly INode NextOther; // next node after the last matched node\n\t\t\tpublic readonly int Checkpoint; // checkpoint\n\n\t\t\tpublic PossibleMatch(INode nextOther, int checkpoint)\n\t\t\t{\n\t\t\t\tthis.NextOther = nextOther;\n\t\t\t\tthis.Checkpoint = checkpoint;\n\t\t\t}\n\t\t}\n\n\t\tbool INode.IsNull {\n\t\t\tget { return false; }\n\t\t}\n\n\t\tRole INode.Role {\n\t\t\tget { return null; }\n\t\t}\n\n\t\tINode INode.NextSibling {\n\t\t\tget { return null; }\n\t\t}\n\n\t\tINode INode.FirstChild {\n\t\t\tget { return null; }\n\t\t}\n\n\t\tpublic abstract bool DoMatch(INode other, Match match);\n\n\t\tpublic virtual bool DoMatchCollection(Role role, INode pos, Match match, BacktrackingInfo backtrackingInfo)\n\t\t{\n\t\t\treturn DoMatch(pos, match);\n\t\t}\n\n\t\tpublic static bool DoMatchCollection(Role role, INode firstPatternChild, INode firstOtherChild, Match match)\n\t\t{\n\t\t\tBacktrackingInfo backtrackingInfo = new BacktrackingInfo();\n\t\t\tStack<INode> patternStack = new Stack<INode>();\n\t\t\tStack<PossibleMatch> stack = backtrackingInfo.backtrackingStack;\n\t\t\tpatternStack.Push(firstPatternChild);\n\t\t\tstack.Push(new PossibleMatch(firstOtherChild, match.CheckPoint()));\n\t\t\twhile (stack.Count > 0)\n\t\t\t{\n\t\t\t\tINode cur1 = patternStack.Pop();\n\t\t\t\tINode cur2 = stack.Peek().NextOther;\n\t\t\t\tmatch.RestoreCheckPoint(stack.Pop().Checkpoint);\n\t\t\t\tbool success = true;\n\t\t\t\twhile (cur1 != null && success)\n\t\t\t\t{\n\t\t\t\t\twhile (cur1 != null && cur1.Role != role)\n\t\t\t\t\t\tcur1 = cur1.NextSibling;\n\t\t\t\t\twhile (cur2 != null && cur2.Role != role)\n\t\t\t\t\t\tcur2 = cur2.NextSibling;\n\t\t\t\t\tif (cur1 == null)\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tDebug.Assert(stack.Count == patternStack.Count);\n\t\t\t\t\tsuccess = cur1.DoMatchCollection(role, cur2, match, backtrackingInfo);\n\t\t\t\t\tDebug.Assert(stack.Count >= patternStack.Count);\n\t\t\t\t\twhile (stack.Count > patternStack.Count)\n\t\t\t\t\t\tpatternStack.Push(cur1.NextSibling);\n\n\t\t\t\t\tcur1 = cur1.NextSibling;\n\t\t\t\t\tif (cur2 != null)\n\t\t\t\t\t\tcur2 = cur2.NextSibling;\n\t\t\t\t}\n\t\t\t\twhile (cur2 != null && cur2.Role != role)\n\t\t\t\t\tcur2 = cur2.NextSibling;\n\t\t\t\tif (success && cur2 == null)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/PatternMatching/Repeat.cs",
    "content": "// Copyright (c) 2011-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching\n{\n\t/// <summary>\n\t/// Represents an optional node.\n\t/// </summary>\n\tpublic class Repeat : Pattern\n\t{\n\t\treadonly INode childNode;\n\n\t\tpublic int MinCount { get; set; }\n\t\tpublic int MaxCount { get; set; }\n\n\t\tpublic INode ChildNode {\n\t\t\tget { return childNode; }\n\t\t}\n\n\t\tpublic Repeat(INode childNode)\n\t\t{\n\t\t\tif (childNode == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(childNode));\n\t\t\tthis.childNode = childNode;\n\t\t\tthis.MinCount = 0;\n\t\t\tthis.MaxCount = int.MaxValue;\n\t\t}\n\n\t\tpublic override bool DoMatchCollection(Role role, INode pos, Match match, BacktrackingInfo backtrackingInfo)\n\t\t{\n\t\t\tvar backtrackingStack = backtrackingInfo.backtrackingStack;\n\t\t\tDebug.Assert(pos == null || pos.Role == role);\n\t\t\tint matchCount = 0;\n\t\t\tif (this.MinCount <= 0)\n\t\t\t\tbacktrackingStack.Push(new PossibleMatch(pos, match.CheckPoint()));\n\t\t\twhile (matchCount < this.MaxCount && pos != null && childNode.DoMatch(pos, match))\n\t\t\t{\n\t\t\t\tmatchCount++;\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tpos = pos.NextSibling;\n\t\t\t\t} while (pos != null && pos.Role != role);\n\t\t\t\tif (matchCount >= this.MinCount)\n\t\t\t\t\tbacktrackingStack.Push(new PossibleMatch(pos, match.CheckPoint()));\n\t\t\t}\n\t\t\treturn false; // never do a normal (single-element) match; always make the caller look at the results on the back-tracking stack.\n\t\t}\n\n\t\tpublic override bool DoMatch(INode other, Match match)\n\t\t{\n\t\t\tif (other == null || other.IsNull)\n\t\t\t\treturn this.MinCount <= 0;\n\t\t\telse\n\t\t\t\treturn this.MaxCount >= 1 && childNode.DoMatch(other, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/PrimitiveType.cs",
    "content": "// \n// FullTypeName.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class PrimitiveType : AstType\n\t{\n\t\tTextLocation location;\n\t\tstring keyword = string.Empty;\n\n\t\tpublic string Keyword {\n\t\t\tget { return keyword; }\n\t\t\tset {\n\t\t\t\tif (value == null)\n\t\t\t\t\tthrow new ArgumentNullException();\n\t\t\t\tThrowIfFrozen();\n\t\t\t\tkeyword = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic KnownTypeCode KnownTypeCode {\n\t\t\tget { return GetTypeCodeForPrimitiveType(this.Keyword); }\n\t\t}\n\n\t\tpublic PrimitiveType()\n\t\t{\n\t\t}\n\n\t\tpublic PrimitiveType(string keyword)\n\t\t{\n\t\t\tthis.Keyword = keyword;\n\t\t}\n\n\t\tpublic PrimitiveType(string keyword, TextLocation location)\n\t\t{\n\t\t\tthis.Keyword = keyword;\n\t\t\tthis.location = location;\n\t\t}\n\n\t\tpublic override TextLocation StartLocation {\n\t\t\tget {\n\t\t\t\treturn location;\n\t\t\t}\n\t\t}\n\n\t\tinternal void SetStartLocation(TextLocation value)\n\t\t{\n\t\t\tThrowIfFrozen();\n\t\t\tthis.location = value;\n\t\t}\n\n\t\tpublic override TextLocation EndLocation {\n\t\t\tget {\n\t\t\t\treturn new TextLocation(location.Line, location.Column + keyword.Length);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitPrimitiveType(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitPrimitiveType(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitPrimitiveType(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tPrimitiveType o = other as PrimitiveType;\n\t\t\treturn o != null && MatchString(this.Keyword, o.Keyword);\n\t\t}\n\n\t\tpublic override string ToString(CSharpFormattingOptions formattingOptions)\n\t\t{\n\t\t\treturn Keyword;\n\t\t}\n\n\t\tpublic static KnownTypeCode GetTypeCodeForPrimitiveType(string keyword)\n\t\t{\n\t\t\tswitch (keyword)\n\t\t\t{\n\t\t\t\tcase \"string\":\n\t\t\t\t\treturn KnownTypeCode.String;\n\t\t\t\tcase \"int\":\n\t\t\t\t\treturn KnownTypeCode.Int32;\n\t\t\t\tcase \"uint\":\n\t\t\t\t\treturn KnownTypeCode.UInt32;\n\t\t\t\tcase \"object\":\n\t\t\t\t\treturn KnownTypeCode.Object;\n\t\t\t\tcase \"bool\":\n\t\t\t\t\treturn KnownTypeCode.Boolean;\n\t\t\t\tcase \"sbyte\":\n\t\t\t\t\treturn KnownTypeCode.SByte;\n\t\t\t\tcase \"byte\":\n\t\t\t\t\treturn KnownTypeCode.Byte;\n\t\t\t\tcase \"short\":\n\t\t\t\t\treturn KnownTypeCode.Int16;\n\t\t\t\tcase \"ushort\":\n\t\t\t\t\treturn KnownTypeCode.UInt16;\n\t\t\t\tcase \"long\":\n\t\t\t\t\treturn KnownTypeCode.Int64;\n\t\t\t\tcase \"ulong\":\n\t\t\t\t\treturn KnownTypeCode.UInt64;\n\t\t\t\tcase \"float\":\n\t\t\t\t\treturn KnownTypeCode.Single;\n\t\t\t\tcase \"double\":\n\t\t\t\t\treturn KnownTypeCode.Double;\n\t\t\t\tcase \"decimal\":\n\t\t\t\t\treturn KnownTypeCode.Decimal;\n\t\t\t\tcase \"char\":\n\t\t\t\t\treturn KnownTypeCode.Char;\n\t\t\t\tcase \"void\":\n\t\t\t\t\treturn KnownTypeCode.Void;\n\t\t\t\tdefault:\n\t\t\t\t\treturn KnownTypeCode.None;\n\t\t\t}\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Role.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Threading;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Represents the role a node plays within its parent.\n\t/// </summary>\n\tpublic abstract class Role\n\t{\n\t\tpublic const int RoleIndexBits = 9;\n\n\t\tstatic readonly Role[] roles = new Role[1 << RoleIndexBits];\n\t\tstatic int nextRoleIndex = 0;\n\n\t\treadonly uint index;\n\n\t\tpublic uint Index {\n\t\t\tget { return index; }\n\t\t}\n\n\t\t// don't allow NRefactory consumers to derive from Role\n\t\tinternal Role()\n\t\t{\n\t\t\tthis.index = (uint)Interlocked.Increment(ref nextRoleIndex);\n\t\t\tif (this.index >= roles.Length)\n\t\t\t\tthrow new InvalidOperationException(\"Too many roles\");\n\t\t\troles[this.index] = this;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the specified node is valid in this role.\n\t\t/// </summary>\n\t\tpublic abstract bool IsValid(object node);\n\n\t\t/// <summary>\n\t\t/// Gets the role with the specified index.\n\t\t/// </summary>\n\t\tpublic static Role GetByIndex(uint index)\n\t\t{\n\t\t\treturn roles[index];\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Represents the role a node plays within its parent.\n\t/// All nodes with this role have type T.\n\t/// </summary>\n\tpublic class Role<T> : Role where T : class?\n\t{\n\t\treadonly string name; // helps with debugging the AST\n\t\treadonly T nullObject;\n\n\t\t/// <summary>\n\t\t/// Gets the null object used when there's no node with this role.\n\t\t/// Not every role has a null object; this property returns null for roles without a null object.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Roles used for non-collections should always have a null object, so that no AST property returns null.\n\t\t/// However, if a role used for collections only, it may leave out the null object.\n\t\t/// </remarks>\n\t\tpublic T NullObject {\n\t\t\tget { return nullObject; }\n\t\t}\n\n\t\tpublic override bool IsValid(object node)\n\t\t{\n\t\t\treturn node is T;\n\t\t}\n\n\t\t[Obsolete(\"Use the other overload explicitly specifying the nullObject.\")]\n\t\tpublic Role(string name)\n\t\t{\n\t\t\tif (name == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(name));\n\t\t\tthis.name = name;\n\t\t\tthis.nullObject = null!;\n\t\t}\n\n\t\tpublic Role(string name, T nullObject)\n\t\t{\n\t\t\tthis.name = name ?? throw new ArgumentNullException(nameof(name));\n\t\t\tthis.nullObject = nullObject;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn name;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Roles.cs",
    "content": "// \n// Roles.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@xamarin.com>\n// \n// Copyright (c) 2012 Xamarin <http://xamarin.com>\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic static class Roles\n\t{\n\t\tpublic static readonly Role<AstNode> Root = AstNode.RootRole;\n\n\t\t// some pre defined constants for common roles\n\t\tpublic static readonly Role<Identifier> Identifier = new Role<Identifier>(\"Identifier\", Syntax.Identifier.Null);\n\t\tpublic static readonly Role<BlockStatement> Body = new Role<BlockStatement>(\"Body\", BlockStatement.Null);\n\t\tpublic static readonly Role<ParameterDeclaration> Parameter = new Role<ParameterDeclaration>(\"Parameter\", null);\n\t\tpublic static readonly Role<Expression> Argument = new Role<Expression>(\"Argument\", Syntax.Expression.Null);\n\t\tpublic static readonly Role<AstType> Type = new Role<AstType>(\"Type\", AstType.Null);\n\t\tpublic static readonly Role<Expression> Expression = new Role<Expression>(\"Expression\", Syntax.Expression.Null);\n\t\tpublic static readonly Role<Expression> TargetExpression = new Role<Expression>(\"Target\", Syntax.Expression.Null);\n\t\tpublic readonly static Role<Expression> Condition = new Role<Expression>(\"Condition\", Syntax.Expression.Null);\n\t\tpublic static readonly Role<TypeParameterDeclaration> TypeParameter = new Role<TypeParameterDeclaration>(\"TypeParameter\", null);\n\t\tpublic static readonly Role<AstType> TypeArgument = new Role<AstType>(\"TypeArgument\", AstType.Null);\n\t\tpublic readonly static Role<Constraint> Constraint = new Role<Constraint>(\"Constraint\", null);\n\t\tpublic static readonly Role<VariableInitializer> Variable = new Role<VariableInitializer>(\"Variable\", VariableInitializer.Null);\n\t\tpublic static readonly Role<Statement> EmbeddedStatement = new Role<Statement>(\"EmbeddedStatement\", Statement.Null);\n\t\tpublic readonly static Role<EntityDeclaration> TypeMemberRole = new Role<EntityDeclaration>(\"TypeMember\", null);\n\n\t\tpublic static readonly Role<VariableDesignation> VariableDesignationRole = new Role<VariableDesignation>(\"VariableDesignation\", VariableDesignation.Null);\n\n\t\t//\t\t\tpublic static readonly TokenRole Keyword = new TokenRole (\"Keyword\", CSharpTokenNode.Null);\n\t\t//\t\t\tpublic static readonly TokenRole InKeyword = new TokenRole (\"InKeyword\", CSharpTokenNode.Null);\n\n\t\t// some pre defined constants for most used punctuation\n\t\tpublic static readonly TokenRole LPar = new TokenRole(\"(\");\n\t\tpublic static readonly TokenRole RPar = new TokenRole(\")\");\n\t\tpublic static readonly TokenRole LBracket = new TokenRole(\"[\");\n\t\tpublic static readonly TokenRole RBracket = new TokenRole(\"]\");\n\t\tpublic static readonly TokenRole LBrace = new TokenRole(\"{\");\n\t\tpublic static readonly TokenRole RBrace = new TokenRole(\"}\");\n\t\tpublic static readonly TokenRole LChevron = new TokenRole(\"<\");\n\t\tpublic static readonly TokenRole RChevron = new TokenRole(\">\");\n\t\tpublic static readonly TokenRole Comma = new TokenRole(\",\");\n\t\tpublic static readonly TokenRole Dot = new TokenRole(\".\");\n\t\tpublic static readonly TokenRole Semicolon = new TokenRole(\";\");\n\t\tpublic static readonly TokenRole Assign = new TokenRole(\"=\");\n\t\tpublic static readonly TokenRole Colon = new TokenRole(\":\");\n\t\tpublic static readonly TokenRole DoubleColon = new TokenRole(\"::\");\n\t\tpublic static readonly TokenRole Arrow = new TokenRole(\"=>\");\n\t\tpublic static readonly Role<Comment> Comment = new Role<Comment>(\"Comment\", null);\n\t\tpublic static readonly Role<PreProcessorDirective> PreProcessorDirective = new Role<PreProcessorDirective>(\"PreProcessorDirective\", null);\n\n\t\tpublic readonly static Role<AstType> BaseType = new Role<AstType>(\"BaseType\", AstType.Null);\n\n\t\tpublic static readonly Role<Attribute> Attribute = new Role<Attribute>(\"Attribute\", null);\n\t\tpublic static readonly Role<CSharpTokenNode> AttributeTargetRole = new Role<CSharpTokenNode>(\"AttributeTarget\", CSharpTokenNode.Null);\n\n\t\tpublic readonly static TokenRole WhereKeyword = new TokenRole(\"where\");\n\t\tpublic readonly static Role<SimpleType> ConstraintTypeParameter = new Role<SimpleType>(\"TypeParameter\", SimpleType.Null);\n\t\tpublic readonly static TokenRole DelegateKeyword = new TokenRole(\"delegate\");\n\t\tpublic static readonly TokenRole ExternKeyword = new TokenRole(\"extern\");\n\t\tpublic static readonly TokenRole AliasKeyword = new TokenRole(\"alias\");\n\t\tpublic static readonly TokenRole NamespaceKeyword = new TokenRole(\"namespace\");\n\n\t\tpublic static readonly TokenRole EnumKeyword = new TokenRole(\"enum\");\n\t\tpublic static readonly TokenRole InterfaceKeyword = new TokenRole(\"interface\");\n\t\tpublic static readonly TokenRole StructKeyword = new TokenRole(\"struct\");\n\t\tpublic static readonly TokenRole ClassKeyword = new TokenRole(\"class\");\n\t\tpublic static readonly TokenRole RecordKeyword = new TokenRole(\"record\");\n\t\tpublic static readonly TokenRole RecordStructKeyword = new TokenRole(\"record\");\n\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/SimpleType.cs",
    "content": "// \n// FullTypeName.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class SimpleType : AstType\n\t{\n\t\t#region Null\n\t\tpublic new static readonly SimpleType Null = new NullSimpleType();\n\n\t\tsealed class NullSimpleType : SimpleType\n\t\t{\n\t\t\tpublic override bool IsNull {\n\t\t\t\tget {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn other == null || other.IsNull;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic SimpleType()\n\t\t{\n\t\t}\n\n\t\tpublic SimpleType(string identifier)\n\t\t{\n\t\t\tthis.Identifier = identifier;\n\t\t}\n\n\t\tpublic SimpleType(Identifier identifier)\n\t\t{\n\t\t\tthis.IdentifierToken = identifier;\n\t\t}\n\n\t\tpublic SimpleType(string identifier, TextLocation location)\n\t\t{\n\t\t\tSetChildByRole(Roles.Identifier, Syntax.Identifier.Create(identifier, location));\n\t\t}\n\n\t\tpublic SimpleType(string identifier, IEnumerable<AstType> typeArguments)\n\t\t{\n\t\t\tthis.Identifier = identifier;\n\t\t\tforeach (var arg in typeArguments)\n\t\t\t{\n\t\t\t\tAddChild(arg, Roles.TypeArgument);\n\t\t\t}\n\t\t}\n\n\t\tpublic SimpleType(string identifier, params AstType[] typeArguments) : this(identifier, (IEnumerable<AstType>)typeArguments)\n\t\t{\n\t\t}\n\n\t\tpublic string Identifier {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, Syntax.Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier IdentifierToken {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, value);\n\t\t\t}\n\t\t}\n\n\t\tpublic AstNodeCollection<AstType> TypeArguments {\n\t\t\tget { return GetChildrenByRole(Roles.TypeArgument); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitSimpleType(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitSimpleType(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitSimpleType(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tSimpleType o = other as SimpleType;\n\t\t\treturn o != null && MatchString(this.Identifier, o.Identifier) && this.TypeArguments.DoMatch(o.TypeArguments, match);\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/BlockStatement.cs",
    "content": "// \n// BlockStatement.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// { Statements }\n\t/// </summary>\n\tpublic class BlockStatement : Statement, IEnumerable<Statement>\n\t{\n\t\tpublic static readonly Role<Statement> StatementRole = new Role<Statement>(\"Statement\", Statement.Null);\n\n\t\t#region Null\n\t\tpublic static readonly new BlockStatement Null = new NullBlockStatement();\n\t\tsealed class NullBlockStatement : BlockStatement\n\t\t{\n\t\t\tpublic override bool IsNull {\n\t\t\t\tget {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn other == null || other.IsNull;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region PatternPlaceholder\n\t\tpublic static implicit operator BlockStatement(PatternMatching.Pattern pattern)\n\t\t{\n\t\t\treturn pattern != null ? new PatternPlaceholder(pattern) : null;\n\t\t}\n\n\t\tsealed class PatternPlaceholder : BlockStatement, PatternMatching.INode\n\t\t{\n\t\t\treadonly PatternMatching.Pattern child;\n\n\t\t\tpublic PatternPlaceholder(PatternMatching.Pattern child)\n\t\t\t{\n\t\t\t\tthis.child = child;\n\t\t\t}\n\n\t\t\tpublic override NodeType NodeType {\n\t\t\t\tget { return NodeType.Pattern; }\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn child.DoMatch(other, match);\n\t\t\t}\n\n\t\t\tbool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)\n\t\t\t{\n\t\t\t\treturn child.DoMatchCollection(role, pos, match, backtrackingInfo);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic CSharpTokenNode LBraceToken {\n\t\t\tget { return GetChildByRole(Roles.LBrace); }\n\t\t}\n\n\t\tpublic AstNodeCollection<Statement> Statements {\n\t\t\tget { return GetChildrenByRole(StatementRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RBraceToken {\n\t\t\tget { return GetChildByRole(Roles.RBrace); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitBlockStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitBlockStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitBlockStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tBlockStatement o = other as BlockStatement;\n\t\t\treturn o != null && !o.IsNull && this.Statements.DoMatch(o.Statements, match);\n\t\t}\n\n\t\tpublic void Add(Statement statement)\n\t\t{\n\t\t\tAddChild(statement, StatementRole);\n\t\t}\n\n\t\tpublic void Add(Expression expression)\n\t\t{\n\t\t\tAddChild(new ExpressionStatement(expression), StatementRole);\n\t\t}\n\n\t\tIEnumerator<Statement> IEnumerable<Statement>.GetEnumerator()\n\t\t{\n\t\t\treturn this.Statements.GetEnumerator();\n\t\t}\n\n\t\tSystem.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\n\t\t{\n\t\t\treturn this.Statements.GetEnumerator();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/BreakStatement.cs",
    "content": "// \n// BreakStatement.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// break;\n\t/// </summary>\n\tpublic class BreakStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole BreakKeywordRole = new TokenRole(\"break\");\n\n\t\tpublic CSharpTokenNode BreakToken {\n\t\t\tget { return GetChildByRole(BreakKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode SemicolonToken {\n\t\t\tget { return GetChildByRole(Roles.Semicolon); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitBreakStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitBreakStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitBreakStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tBreakStatement o = other as BreakStatement;\n\t\t\treturn o != null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/CheckedStatement.cs",
    "content": "// \n// CheckedStatement.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// checked BodyBlock\n\t/// </summary>\n\tpublic class CheckedStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole CheckedKeywordRole = new TokenRole(\"checked\");\n\n\t\tpublic CSharpTokenNode CheckedToken {\n\t\t\tget { return GetChildByRole(CheckedKeywordRole); }\n\t\t}\n\n\t\tpublic BlockStatement Body {\n\t\t\tget { return GetChildByRole(Roles.Body); }\n\t\t\tset { SetChildByRole(Roles.Body, value); }\n\t\t}\n\n\t\tpublic CheckedStatement()\n\t\t{\n\t\t}\n\n\t\tpublic CheckedStatement(BlockStatement body)\n\t\t{\n\t\t\tAddChild(body, Roles.Body);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitCheckedStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitCheckedStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitCheckedStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tCheckedStatement o = other as CheckedStatement;\n\t\t\treturn o != null && this.Body.DoMatch(o.Body, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/ContinueStatement.cs",
    "content": "// \n// ContinueStatement.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// continue;\n\t/// </summary>\n\tpublic class ContinueStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole ContinueKeywordRole = new TokenRole(\"continue\");\n\n\t\tpublic CSharpTokenNode ContinueToken {\n\t\t\tget { return GetChildByRole(ContinueKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode SemicolonToken {\n\t\t\tget { return GetChildByRole(Roles.Semicolon); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitContinueStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitContinueStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitContinueStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tContinueStatement o = other as ContinueStatement;\n\t\t\treturn o != null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/DoWhileStatement.cs",
    "content": "// \n// DoWhileStatement.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2011 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// \"do EmbeddedStatement while(Condition);\"\n\t/// </summary>\n\tpublic class DoWhileStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole DoKeywordRole = new TokenRole(\"do\");\n\t\tpublic static readonly TokenRole WhileKeywordRole = new TokenRole(\"while\");\n\n\t\tpublic CSharpTokenNode DoToken {\n\t\t\tget { return GetChildByRole(DoKeywordRole); }\n\t\t}\n\n\t\tpublic Statement EmbeddedStatement {\n\t\t\tget { return GetChildByRole(Roles.EmbeddedStatement); }\n\t\t\tset { SetChildByRole(Roles.EmbeddedStatement, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode WhileToken {\n\t\t\tget { return GetChildByRole(WhileKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic Expression Condition {\n\t\t\tget { return GetChildByRole(Roles.Condition); }\n\t\t\tset { SetChildByRole(Roles.Condition, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic CSharpTokenNode SemicolonToken {\n\t\t\tget { return GetChildByRole(Roles.Semicolon); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDoWhileStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDoWhileStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitDoWhileStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tDoWhileStatement o = other as DoWhileStatement;\n\t\t\treturn o != null && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match) && this.Condition.DoMatch(o.Condition, match);\n\t\t}\n\n\t\tpublic DoWhileStatement()\n\t\t{\n\t\t}\n\n\t\tpublic DoWhileStatement(Expression condition, Statement embeddedStatement)\n\t\t{\n\t\t\tthis.Condition = condition;\n\t\t\tthis.EmbeddedStatement = embeddedStatement;\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/EmptyStatement.cs",
    "content": "// \n// EmptyStatement.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// ;\n\t/// </summary>\n\tpublic class EmptyStatement : Statement\n\t{\n\t\tpublic TextLocation Location {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic override TextLocation StartLocation {\n\t\t\tget {\n\t\t\t\treturn Location;\n\t\t\t}\n\t\t}\n\n\t\tpublic override TextLocation EndLocation {\n\t\t\tget {\n\t\t\t\treturn new TextLocation(Location.Line, Location.Column + 1);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitEmptyStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitEmptyStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitEmptyStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tEmptyStatement o = other as EmptyStatement;\n\t\t\treturn o != null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/ExpressionStatement.cs",
    "content": "// \n// ExpressionStatement.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Expression;\n\t/// </summary>\n\tpublic class ExpressionStatement : Statement\n\t{\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode SemicolonToken {\n\t\t\tget { return GetChildByRole(Roles.Semicolon); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitExpressionStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitExpressionStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitExpressionStatement(this, data);\n\t\t}\n\n\t\tpublic ExpressionStatement()\n\t\t{\n\t\t}\n\n\t\tpublic ExpressionStatement(Expression expression)\n\t\t{\n\t\t\tthis.Expression = expression;\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tExpressionStatement o = other as ExpressionStatement;\n\t\t\treturn o != null && this.Expression.DoMatch(o.Expression, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/FixedStatement.cs",
    "content": "// \n// FixedStatement.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// fixed (Type Variables) EmbeddedStatement\n\t/// </summary>\n\tpublic class FixedStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole FixedKeywordRole = new TokenRole(\"fixed\");\n\n\t\tpublic CSharpTokenNode FixedToken {\n\t\t\tget { return GetChildByRole(FixedKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic AstNodeCollection<VariableInitializer> Variables {\n\t\t\tget { return GetChildrenByRole(Roles.Variable); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic Statement EmbeddedStatement {\n\t\t\tget { return GetChildByRole(Roles.EmbeddedStatement); }\n\t\t\tset { SetChildByRole(Roles.EmbeddedStatement, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitFixedStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitFixedStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitFixedStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tFixedStatement o = other as FixedStatement;\n\t\t\treturn o != null && this.Type.DoMatch(o.Type, match) && this.Variables.DoMatch(o.Variables, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/ForStatement.cs",
    "content": "// \n// ForStatement.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// for (Initializers; Condition; Iterators) EmbeddedStatement\n\t/// </summary>\n\tpublic class ForStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole ForKeywordRole = new TokenRole(\"for\");\n\t\tpublic readonly static Role<Statement> InitializerRole = new Role<Statement>(\"Initializer\", Statement.Null);\n\t\tpublic readonly static Role<Statement> IteratorRole = new Role<Statement>(\"Iterator\", Statement.Null);\n\n\t\tpublic CSharpTokenNode ForToken {\n\t\t\tget { return GetChildByRole(ForKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the list of initializer statements.\n\t\t/// Note: this contains multiple statements for \"for (a = 2, b = 1; a > b; a--)\", but contains\n\t\t/// only a single statement for \"for (int a = 2, b = 1; a > b; a--)\" (a single VariableDeclarationStatement with two variables)\n\t\t/// </summary>\n\t\tpublic AstNodeCollection<Statement> Initializers {\n\t\t\tget { return GetChildrenByRole(InitializerRole); }\n\t\t}\n\n\t\tpublic Expression Condition {\n\t\t\tget { return GetChildByRole(Roles.Condition); }\n\t\t\tset { SetChildByRole(Roles.Condition, value); }\n\t\t}\n\n\t\tpublic AstNodeCollection<Statement> Iterators {\n\t\t\tget { return GetChildrenByRole(IteratorRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic Statement EmbeddedStatement {\n\t\t\tget { return GetChildByRole(Roles.EmbeddedStatement); }\n\t\t\tset { SetChildByRole(Roles.EmbeddedStatement, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitForStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitForStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitForStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tForStatement o = other as ForStatement;\n\t\t\treturn o != null && this.Initializers.DoMatch(o.Initializers, match) && this.Condition.DoMatch(o.Condition, match)\n\t\t\t\t&& this.Iterators.DoMatch(o.Iterators, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/ForeachStatement.cs",
    "content": "// \n// ForeachStatement.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// foreach (Type VariableName in InExpression) EmbeddedStatement\n\t/// </summary>\n\tpublic class ForeachStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole AwaitRole = UnaryOperatorExpression.AwaitRole;\n\t\tpublic static readonly TokenRole ForeachKeywordRole = new TokenRole(\"foreach\");\n\t\tpublic static readonly TokenRole InKeywordRole = new TokenRole(\"in\");\n\n\t\tpublic CSharpTokenNode AwaitToken {\n\t\t\tget { return GetChildByRole(AwaitRole); }\n\t\t}\n\n\t\tpublic bool IsAsync {\n\t\t\tget { return !GetChildByRole(AwaitRole).IsNull; }\n\t\t\tset { SetChildByRole(AwaitRole, value ? new CSharpTokenNode(TextLocation.Empty, null) : null); }\n\t\t}\n\n\t\tpublic CSharpTokenNode ForeachToken {\n\t\t\tget { return GetChildByRole(ForeachKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstType VariableType {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic VariableDesignation VariableDesignation {\n\t\t\tget { return GetChildByRole(Roles.VariableDesignationRole); }\n\t\t\tset { SetChildByRole(Roles.VariableDesignationRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode InToken {\n\t\t\tget { return GetChildByRole(InKeywordRole); }\n\t\t}\n\n\t\tpublic Expression InExpression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic Statement EmbeddedStatement {\n\t\t\tget { return GetChildByRole(Roles.EmbeddedStatement); }\n\t\t\tset { SetChildByRole(Roles.EmbeddedStatement, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitForeachStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitForeachStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitForeachStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tForeachStatement o = other as ForeachStatement;\n\t\t\treturn o != null && this.VariableType.DoMatch(o.VariableType, match) && this.VariableDesignation.DoMatch(o.VariableDesignation, match)\n\t\t\t\t&& this.InExpression.DoMatch(o.InExpression, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/GotoStatement.cs",
    "content": "// \n// GotoStatement.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// \"goto Label;\"\n\t/// </summary>\n\tpublic class GotoStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole GotoKeywordRole = new TokenRole(\"goto\");\n\n\t\tpublic GotoStatement()\n\t\t{\n\t\t}\n\n\t\tpublic GotoStatement(string label)\n\t\t{\n\t\t\tthis.Label = label;\n\t\t}\n\n\t\tpublic CSharpTokenNode GotoToken {\n\t\t\tget { return GetChildByRole(GotoKeywordRole); }\n\t\t}\n\n\t\tpublic string Label {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tif (string.IsNullOrEmpty(value))\n\t\t\t\t\tSetChildByRole(Roles.Identifier, null);\n\t\t\t\telse\n\t\t\t\t\tSetChildByRole(Roles.Identifier, Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode SemicolonToken {\n\t\t\tget { return GetChildByRole(Roles.Semicolon); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitGotoStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitGotoStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitGotoStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tGotoStatement o = other as GotoStatement;\n\t\t\treturn o != null && MatchString(this.Label, o.Label);\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// or \"goto case LabelExpression;\"\n\t/// </summary>\n\tpublic class GotoCaseStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole GotoKeywordRole = new TokenRole(\"goto\");\n\t\tpublic static readonly TokenRole CaseKeywordRole = new TokenRole(\"case\");\n\n\t\tpublic CSharpTokenNode GotoToken {\n\t\t\tget { return GetChildByRole(GotoKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode CaseToken {\n\t\t\tget { return GetChildByRole(CaseKeywordRole); }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Used for \"goto case LabelExpression;\"\n\t\t/// </summary>\n\t\tpublic Expression LabelExpression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode SemicolonToken {\n\t\t\tget { return GetChildByRole(Roles.Semicolon); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitGotoCaseStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitGotoCaseStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitGotoCaseStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tGotoCaseStatement o = other as GotoCaseStatement;\n\t\t\treturn o != null && this.LabelExpression.DoMatch(o.LabelExpression, match);\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// or \"goto default;\"\n\t/// </summary>\n\tpublic class GotoDefaultStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole GotoKeywordRole = new TokenRole(\"goto\");\n\t\tpublic static readonly TokenRole DefaultKeywordRole = new TokenRole(\"default\");\n\n\t\tpublic CSharpTokenNode GotoToken {\n\t\t\tget { return GetChildByRole(GotoKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode DefaultToken {\n\t\t\tget { return GetChildByRole(DefaultKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode SemicolonToken {\n\t\t\tget { return GetChildByRole(Roles.Semicolon); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitGotoDefaultStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitGotoDefaultStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitGotoDefaultStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tGotoDefaultStatement o = other as GotoDefaultStatement;\n\t\t\treturn o != null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/IfElseStatement.cs",
    "content": "// \n// IfElseStatement.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// if (Condition) TrueStatement else FalseStatement\n\t/// </summary>\n\tpublic class IfElseStatement : Statement\n\t{\n\t\tpublic readonly static TokenRole IfKeywordRole = new TokenRole(\"if\");\n\t\tpublic readonly static Role<Expression> ConditionRole = Roles.Condition;\n\t\tpublic readonly static Role<Statement> TrueRole = new Role<Statement>(\"True\", Statement.Null);\n\t\tpublic readonly static TokenRole ElseKeywordRole = new TokenRole(\"else\");\n\t\tpublic readonly static Role<Statement> FalseRole = new Role<Statement>(\"False\", Statement.Null);\n\n\t\tpublic CSharpTokenNode IfToken {\n\t\t\tget { return GetChildByRole(IfKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic Expression Condition {\n\t\t\tget { return GetChildByRole(ConditionRole); }\n\t\t\tset { SetChildByRole(ConditionRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic Statement TrueStatement {\n\t\t\tget { return GetChildByRole(TrueRole); }\n\t\t\tset { SetChildByRole(TrueRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode ElseToken {\n\t\t\tget { return GetChildByRole(ElseKeywordRole); }\n\t\t}\n\n\t\tpublic Statement FalseStatement {\n\t\t\tget { return GetChildByRole(FalseRole); }\n\t\t\tset { SetChildByRole(FalseRole, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitIfElseStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitIfElseStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitIfElseStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tIfElseStatement o = other as IfElseStatement;\n\t\t\treturn o != null && this.Condition.DoMatch(o.Condition, match) && this.TrueStatement.DoMatch(o.TrueStatement, match) && this.FalseStatement.DoMatch(o.FalseStatement, match);\n\t\t}\n\n\t\tpublic IfElseStatement()\n\t\t{\n\t\t}\n\n\t\tpublic IfElseStatement(Expression condition, Statement trueStatement, Statement falseStatement = null)\n\t\t{\n\t\t\tthis.Condition = condition;\n\t\t\tthis.TrueStatement = trueStatement;\n\t\t\tthis.FalseStatement = falseStatement;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/LabelStatement.cs",
    "content": "// \n// LabelStatement.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Label:\n\t/// </summary>\n\tpublic class LabelStatement : Statement\n\t{\n\t\tpublic string Label {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier LabelToken {\n\t\t\tget { return GetChildByRole(Roles.Identifier); }\n\t\t\tset { SetChildByRole(Roles.Identifier, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode ColonToken {\n\t\t\tget { return GetChildByRole(Roles.Colon); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLabelStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLabelStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitLabelStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tLabelStatement o = other as LabelStatement;\n\t\t\treturn o != null && MatchString(this.Label, o.Label);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/LocalFunctionDeclarationStatement.cs",
    "content": "// Copyright (c) 2019 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class LocalFunctionDeclarationStatement : Statement\n\t{\n\t\tpublic static readonly Role<MethodDeclaration> MethodDeclarationRole = new Role<MethodDeclaration>(\"Method\", null);\n\n\t\tpublic MethodDeclaration Declaration {\n\t\t\tget { return GetChildByRole(MethodDeclarationRole); }\n\t\t\tset { SetChildByRole(MethodDeclarationRole, value); }\n\t\t}\n\n\t\tpublic LocalFunctionDeclarationStatement(MethodDeclaration methodDeclaration)\n\t\t{\n\t\t\tAddChild(methodDeclaration, MethodDeclarationRole);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLocalFunctionDeclarationStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLocalFunctionDeclarationStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitLocalFunctionDeclarationStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, Match match)\n\t\t{\n\t\t\treturn other is LocalFunctionDeclarationStatement o && Declaration.DoMatch(o.Declaration, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/LockStatement.cs",
    "content": "// \n// LockStatement.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// lock (Expression) EmbeddedStatement;\n\t/// </summary>\n\tpublic class LockStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole LockKeywordRole = new TokenRole(\"lock\");\n\n\t\tpublic CSharpTokenNode LockToken {\n\t\t\tget { return GetChildByRole(LockKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic Statement EmbeddedStatement {\n\t\t\tget { return GetChildByRole(Roles.EmbeddedStatement); }\n\t\t\tset { SetChildByRole(Roles.EmbeddedStatement, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLockStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLockStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitLockStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tLockStatement o = other as LockStatement;\n\t\t\treturn o != null && this.Expression.DoMatch(o.Expression, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/ReturnStatement.cs",
    "content": "// \n// ReturnStatement.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// return Expression;\n\t/// </summary>\n\tpublic class ReturnStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole ReturnKeywordRole = new TokenRole(\"return\");\n\n\t\tpublic CSharpTokenNode ReturnToken {\n\t\t\tget { return GetChildByRole(ReturnKeywordRole); }\n\t\t}\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode SemicolonToken {\n\t\t\tget { return GetChildByRole(Roles.Semicolon); }\n\t\t}\n\n\t\tpublic ReturnStatement()\n\t\t{\n\t\t}\n\n\t\tpublic ReturnStatement(Expression returnExpression)\n\t\t{\n\t\t\tAddChild(returnExpression, Roles.Expression);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitReturnStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitReturnStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitReturnStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tReturnStatement o = other as ReturnStatement;\n\t\t\treturn o != null && this.Expression.DoMatch(o.Expression, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/Statement.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Base class for statements.\n\t/// </summary>\n\t/// <remarks>\n\t/// This class is useful even though it doesn't provide any additional functionality:\n\t/// It can be used to communicate more information in APIs, e.g. \"this subnode will always be a statement\"\n\t/// </remarks>\n\tpublic abstract class Statement : AstNode\n\t{\n\t\t#region Null\n\t\tpublic new static readonly Statement Null = new NullStatement();\n\n\t\tsealed class NullStatement : Statement\n\t\t{\n\t\t\tpublic override bool IsNull {\n\t\t\t\tget {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn other == null || other.IsNull;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region PatternPlaceholder\n\t\tpublic static implicit operator Statement(PatternMatching.Pattern pattern)\n\t\t{\n\t\t\treturn pattern != null ? new PatternPlaceholder(pattern) : null;\n\t\t}\n\n\t\tsealed class PatternPlaceholder : Statement, PatternMatching.INode\n\t\t{\n\t\t\treadonly PatternMatching.Pattern child;\n\n\t\t\tpublic PatternPlaceholder(PatternMatching.Pattern child)\n\t\t\t{\n\t\t\t\tthis.child = child;\n\t\t\t}\n\n\t\t\tpublic override NodeType NodeType {\n\t\t\t\tget { return NodeType.Pattern; }\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn child.DoMatch(other, match);\n\t\t\t}\n\n\t\t\tbool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)\n\t\t\t{\n\t\t\t\treturn child.DoMatchCollection(role, pos, match, backtrackingInfo);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic new Statement Clone()\n\t\t{\n\t\t\treturn (Statement)base.Clone();\n\t\t}\n\n\t\tpublic Statement ReplaceWith(Func<Statement, Statement> replaceFunction)\n\t\t{\n\t\t\tif (replaceFunction == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(replaceFunction));\n\t\t\treturn (Statement)base.ReplaceWith(node => replaceFunction((Statement)node));\n\t\t}\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget { return NodeType.Statement; }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/SwitchStatement.cs",
    "content": "// \n// SwitchStatement.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// switch (Expression) { SwitchSections }\n\t/// </summary>\n\tpublic class SwitchStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole SwitchKeywordRole = new TokenRole(\"switch\");\n\t\tpublic static readonly Role<SwitchSection> SwitchSectionRole = new Role<SwitchSection>(\"SwitchSection\", null);\n\n\t\tpublic CSharpTokenNode SwitchToken {\n\t\t\tget { return GetChildByRole(SwitchKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LBraceToken {\n\t\t\tget { return GetChildByRole(Roles.LBrace); }\n\t\t}\n\n\t\tpublic AstNodeCollection<SwitchSection> SwitchSections {\n\t\t\tget { return GetChildrenByRole(SwitchSectionRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RBraceToken {\n\t\t\tget { return GetChildByRole(Roles.RBrace); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitSwitchStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitSwitchStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitSwitchStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tSwitchStatement o = other as SwitchStatement;\n\t\t\treturn o != null && this.Expression.DoMatch(o.Expression, match) && this.SwitchSections.DoMatch(o.SwitchSections, match);\n\t\t}\n\t}\n\n\tpublic class SwitchSection : AstNode\n\t{\n\t\t#region PatternPlaceholder\n\t\tpublic static implicit operator SwitchSection(PatternMatching.Pattern pattern)\n\t\t{\n\t\t\treturn pattern != null ? new PatternPlaceholder(pattern) : null;\n\t\t}\n\n\t\tsealed class PatternPlaceholder : SwitchSection, PatternMatching.INode\n\t\t{\n\t\t\treadonly PatternMatching.Pattern child;\n\n\t\t\tpublic PatternPlaceholder(PatternMatching.Pattern child)\n\t\t\t{\n\t\t\t\tthis.child = child;\n\t\t\t}\n\n\t\t\tpublic override NodeType NodeType {\n\t\t\t\tget { return NodeType.Pattern; }\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn child.DoMatch(other, match);\n\t\t\t}\n\n\t\t\tbool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)\n\t\t\t{\n\t\t\t\treturn child.DoMatchCollection(role, pos, match, backtrackingInfo);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic static readonly Role<CaseLabel> CaseLabelRole = new Role<CaseLabel>(\"CaseLabel\", null);\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget {\n\t\t\t\treturn NodeType.Unknown;\n\t\t\t}\n\t\t}\n\n\t\tpublic AstNodeCollection<CaseLabel> CaseLabels {\n\t\t\tget { return GetChildrenByRole(CaseLabelRole); }\n\t\t}\n\n\t\tpublic AstNodeCollection<Statement> Statements {\n\t\t\tget { return GetChildrenByRole(Roles.EmbeddedStatement); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitSwitchSection(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitSwitchSection(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitSwitchSection(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tSwitchSection o = other as SwitchSection;\n\t\t\treturn o != null && this.CaseLabels.DoMatch(o.CaseLabels, match) && this.Statements.DoMatch(o.Statements, match);\n\t\t}\n\t}\n\n\tpublic class CaseLabel : AstNode\n\t{\n\t\tpublic static readonly TokenRole CaseKeywordRole = new TokenRole(\"case\");\n\t\tpublic static readonly TokenRole DefaultKeywordRole = new TokenRole(\"default\");\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget {\n\t\t\t\treturn NodeType.Unknown;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets or sets the expression. The expression can be null - if the expression is null, it's the default switch section.\n\t\t/// </summary>\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode ColonToken {\n\t\t\tget { return GetChildByRole(Roles.Colon); }\n\t\t}\n\n\t\tpublic CaseLabel()\n\t\t{\n\t\t}\n\n\t\tpublic CaseLabel(Expression expression)\n\t\t{\n\t\t\tthis.Expression = expression;\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitCaseLabel(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitCaseLabel(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitCaseLabel(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tCaseLabel o = other as CaseLabel;\n\t\t\treturn o != null && this.Expression.DoMatch(o.Expression, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/ThrowStatement.cs",
    "content": "// \n// ThrowStatement.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// throw Expression;\n\t/// </summary>\n\tpublic class ThrowStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole ThrowKeywordRole = new TokenRole(\"throw\");\n\n\t\tpublic CSharpTokenNode ThrowToken {\n\t\t\tget { return GetChildByRole(ThrowKeywordRole); }\n\t\t}\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode SemicolonToken {\n\t\t\tget { return GetChildByRole(Roles.Semicolon); }\n\t\t}\n\n\t\tpublic ThrowStatement()\n\t\t{\n\t\t}\n\n\t\tpublic ThrowStatement(Expression expression)\n\t\t{\n\t\t\tAddChild(expression, Roles.Expression);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitThrowStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitThrowStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitThrowStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tThrowStatement o = other as ThrowStatement;\n\t\t\treturn o != null && this.Expression.DoMatch(o.Expression, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/TryCatchStatement.cs",
    "content": "// \n// TryCatchStatement.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// try TryBlock CatchClauses finally FinallyBlock\n\t/// </summary>\n\tpublic class TryCatchStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole TryKeywordRole = new TokenRole(\"try\");\n\t\tpublic static readonly Role<BlockStatement> TryBlockRole = new Role<BlockStatement>(\"TryBlock\", BlockStatement.Null);\n\t\tpublic static readonly Role<CatchClause> CatchClauseRole = new Role<CatchClause>(\"CatchClause\", CatchClause.Null);\n\t\tpublic static readonly TokenRole FinallyKeywordRole = new TokenRole(\"finally\");\n\t\tpublic static readonly Role<BlockStatement> FinallyBlockRole = new Role<BlockStatement>(\"FinallyBlock\", BlockStatement.Null);\n\n\t\tpublic CSharpTokenNode TryToken {\n\t\t\tget { return GetChildByRole(TryKeywordRole); }\n\t\t}\n\n\t\tpublic BlockStatement TryBlock {\n\t\t\tget { return GetChildByRole(TryBlockRole); }\n\t\t\tset { SetChildByRole(TryBlockRole, value); }\n\t\t}\n\n\t\tpublic AstNodeCollection<CatchClause> CatchClauses {\n\t\t\tget { return GetChildrenByRole(CatchClauseRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode FinallyToken {\n\t\t\tget { return GetChildByRole(FinallyKeywordRole); }\n\t\t}\n\n\t\tpublic BlockStatement FinallyBlock {\n\t\t\tget { return GetChildByRole(FinallyBlockRole); }\n\t\t\tset { SetChildByRole(FinallyBlockRole, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitTryCatchStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitTryCatchStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitTryCatchStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tTryCatchStatement o = other as TryCatchStatement;\n\t\t\treturn o != null && this.TryBlock.DoMatch(o.TryBlock, match) && this.CatchClauses.DoMatch(o.CatchClauses, match) && this.FinallyBlock.DoMatch(o.FinallyBlock, match);\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// catch (Type VariableName) { Body }\n\t/// </summary>\n\tpublic class CatchClause : AstNode\n\t{\n\t\tpublic static readonly TokenRole CatchKeywordRole = new TokenRole(\"catch\");\n\t\tpublic static readonly TokenRole WhenKeywordRole = new TokenRole(\"when\");\n\t\tpublic static readonly Role<Expression> ConditionRole = Roles.Condition;\n\t\tpublic static readonly TokenRole CondLPar = new TokenRole(\"(\");\n\t\tpublic static readonly TokenRole CondRPar = new TokenRole(\")\");\n\n\t\t#region Null\n\t\tpublic new static readonly CatchClause Null = new NullCatchClause();\n\n\t\tsealed class NullCatchClause : CatchClause\n\t\t{\n\t\t\tpublic override bool IsNull {\n\t\t\t\tget {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn other == null || other.IsNull;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region PatternPlaceholder\n\t\tpublic static implicit operator CatchClause(PatternMatching.Pattern pattern)\n\t\t{\n\t\t\treturn pattern != null ? new PatternPlaceholder(pattern) : null;\n\t\t}\n\n\t\tsealed class PatternPlaceholder : CatchClause, PatternMatching.INode\n\t\t{\n\t\t\treadonly PatternMatching.Pattern child;\n\n\t\t\tpublic PatternPlaceholder(PatternMatching.Pattern child)\n\t\t\t{\n\t\t\t\tthis.child = child;\n\t\t\t}\n\n\t\t\tpublic override NodeType NodeType {\n\t\t\t\tget { return NodeType.Pattern; }\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn child.DoMatch(other, match);\n\t\t\t}\n\n\t\t\tbool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)\n\t\t\t{\n\t\t\t\treturn child.DoMatchCollection(role, pos, match, backtrackingInfo);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget {\n\t\t\t\treturn NodeType.Unknown;\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode CatchToken {\n\t\t\tget { return GetChildByRole(CatchKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic string VariableName {\n\t\t\tget { return GetChildByRole(Roles.Identifier).Name; }\n\t\t\tset {\n\t\t\t\tif (string.IsNullOrEmpty(value))\n\t\t\t\t\tSetChildByRole(Roles.Identifier, null);\n\t\t\t\telse\n\t\t\t\t\tSetChildByRole(Roles.Identifier, Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier VariableNameToken {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, value);\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic CSharpTokenNode WhenToken {\n\t\t\tget { return GetChildByRole(WhenKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode CondLParToken {\n\t\t\tget { return GetChildByRole(CondLPar); }\n\t\t}\n\n\t\tpublic Expression Condition {\n\t\t\tget { return GetChildByRole(ConditionRole); }\n\t\t\tset { SetChildByRole(ConditionRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode CondRParToken {\n\t\t\tget { return GetChildByRole(CondRPar); }\n\t\t}\n\n\t\tpublic BlockStatement Body {\n\t\t\tget { return GetChildByRole(Roles.Body); }\n\t\t\tset { SetChildByRole(Roles.Body, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitCatchClause(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitCatchClause(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitCatchClause(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tCatchClause o = other as CatchClause;\n\t\t\treturn o != null && this.Type.DoMatch(o.Type, match) && MatchString(this.VariableName, o.VariableName) && this.Body.DoMatch(o.Body, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/UncheckedStatement.cs",
    "content": "// \n// UncheckedStatement.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// unchecked BodyBlock\n\t/// </summary>\n\tpublic class UncheckedStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole UncheckedKeywordRole = new TokenRole(\"unchecked\");\n\n\t\tpublic CSharpTokenNode UncheckedToken {\n\t\t\tget { return GetChildByRole(UncheckedKeywordRole); }\n\t\t}\n\n\t\tpublic BlockStatement Body {\n\t\t\tget { return GetChildByRole(Roles.Body); }\n\t\t\tset { SetChildByRole(Roles.Body, value); }\n\t\t}\n\n\t\tpublic UncheckedStatement()\n\t\t{\n\t\t}\n\n\t\tpublic UncheckedStatement(BlockStatement body)\n\t\t{\n\t\t\tAddChild(body, Roles.Body);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitUncheckedStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitUncheckedStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitUncheckedStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tUncheckedStatement o = other as UncheckedStatement;\n\t\t\treturn o != null && this.Body.DoMatch(o.Body, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/UnsafeStatement.cs",
    "content": "// \n// UnsafeStatement.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// unsafe { Body }\n\t/// </summary>\n\tpublic class UnsafeStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole UnsafeKeywordRole = new TokenRole(\"unsafe\");\n\n\t\tpublic CSharpTokenNode UnsafeToken {\n\t\t\tget { return GetChildByRole(UnsafeKeywordRole); }\n\t\t}\n\n\t\tpublic BlockStatement Body {\n\t\t\tget { return GetChildByRole(Roles.Body); }\n\t\t\tset { SetChildByRole(Roles.Body, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitUnsafeStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitUnsafeStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitUnsafeStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tUnsafeStatement o = other as UnsafeStatement;\n\t\t\treturn o != null && this.Body.DoMatch(o.Body, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/UsingStatement.cs",
    "content": "// \n// UsingStatement.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// [ await ] using (ResourceAcquisition) EmbeddedStatement\n\t/// </summary>\n\tpublic class UsingStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole UsingKeywordRole = new TokenRole(\"using\");\n\t\tpublic static readonly TokenRole AwaitRole = UnaryOperatorExpression.AwaitRole;\n\t\tpublic static readonly Role<AstNode> ResourceAcquisitionRole = new Role<AstNode>(\"ResourceAcquisition\", AstNode.Null);\n\n\t\tpublic CSharpTokenNode UsingToken {\n\t\t\tget { return GetChildByRole(UsingKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode AwaitToken {\n\t\t\tget { return GetChildByRole(AwaitRole); }\n\t\t}\n\n\t\tpublic bool IsAsync {\n\t\t\tget { return !GetChildByRole(AwaitRole).IsNull; }\n\t\t\tset { SetChildByRole(AwaitRole, value ? new CSharpTokenNode(TextLocation.Empty, null) : null); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic bool IsEnhanced { get; set; }\n\n\t\t/// <summary>\n\t\t/// Either a VariableDeclarationStatement, or an Expression.\n\t\t/// </summary>\n\t\tpublic AstNode ResourceAcquisition {\n\t\t\tget { return GetChildByRole(ResourceAcquisitionRole); }\n\t\t\tset { SetChildByRole(ResourceAcquisitionRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic Statement EmbeddedStatement {\n\t\t\tget { return GetChildByRole(Roles.EmbeddedStatement); }\n\t\t\tset { SetChildByRole(Roles.EmbeddedStatement, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitUsingStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitUsingStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitUsingStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tUsingStatement o = other as UsingStatement;\n\t\t\treturn o != null && this.IsAsync == o.IsAsync && this.ResourceAcquisition.DoMatch(o.ResourceAcquisition, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/VariableDeclarationStatement.cs",
    "content": "// \n// VariableDeclarationStatement.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class VariableDeclarationStatement : Statement\n\t{\n\t\tpublic static readonly Role<CSharpModifierToken> ModifierRole = EntityDeclaration.ModifierRole;\n\n\t\tpublic VariableDeclarationStatement()\n\t\t{\n\t\t}\n\n\t\tpublic VariableDeclarationStatement(AstType type, string name, Expression initializer = null)\n\t\t{\n\t\t\tthis.Type = type;\n\t\t\tthis.Variables.Add(new VariableInitializer(name, initializer));\n\t\t}\n\n\t\tpublic Modifiers Modifiers {\n\t\t\tget { return EntityDeclaration.GetModifiers(this); }\n\t\t\tset { EntityDeclaration.SetModifiers(this, value); }\n\t\t}\n\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic AstNodeCollection<VariableInitializer> Variables {\n\t\t\tget { return GetChildrenByRole(Roles.Variable); }\n\t\t}\n\n\t\tpublic CSharpTokenNode SemicolonToken {\n\t\t\tget { return GetChildByRole(Roles.Semicolon); }\n\t\t}\n\n\t\tpublic VariableInitializer GetVariable(string name)\n\t\t{\n\t\t\treturn Variables.FirstOrNullObject(vi => vi.Name == name);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitVariableDeclarationStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitVariableDeclarationStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitVariableDeclarationStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tVariableDeclarationStatement o = other as VariableDeclarationStatement;\n\t\t\treturn o != null && this.Modifiers == o.Modifiers && this.Type.DoMatch(o.Type, match) && this.Variables.DoMatch(o.Variables, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/WhileStatement.cs",
    "content": "// \n// WhileStatement.cs\n//  \n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// \"while (Condition) EmbeddedStatement\"\n\t/// </summary>\n\tpublic class WhileStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole WhileKeywordRole = new TokenRole(\"while\");\n\n\t\tpublic CSharpTokenNode WhileToken {\n\t\t\tget { return GetChildByRole(WhileKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic Expression Condition {\n\t\t\tget { return GetChildByRole(Roles.Condition); }\n\t\t\tset { SetChildByRole(Roles.Condition, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic Statement EmbeddedStatement {\n\t\t\tget { return GetChildByRole(Roles.EmbeddedStatement); }\n\t\t\tset { SetChildByRole(Roles.EmbeddedStatement, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitWhileStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitWhileStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitWhileStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tWhileStatement o = other as WhileStatement;\n\t\t\treturn o != null && this.Condition.DoMatch(o.Condition, match) && this.EmbeddedStatement.DoMatch(o.EmbeddedStatement, match);\n\t\t}\n\n\t\tpublic WhileStatement()\n\t\t{\n\t\t}\n\n\t\tpublic WhileStatement(Expression condition, Statement embeddedStatement)\n\t\t{\n\t\t\tthis.Condition = condition;\n\t\t\tthis.EmbeddedStatement = embeddedStatement;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/YieldBreakStatement.cs",
    "content": "// \n// YieldBreakStatement.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2011 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// yield break;\n\t/// </summary>\n\tpublic class YieldBreakStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole YieldKeywordRole = new TokenRole(\"yield\");\n\t\tpublic static readonly TokenRole BreakKeywordRole = new TokenRole(\"break\");\n\n\t\tpublic CSharpTokenNode YieldToken {\n\t\t\tget { return GetChildByRole(YieldKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode BreakToken {\n\t\t\tget { return GetChildByRole(BreakKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode SemicolonToken {\n\t\t\tget { return GetChildByRole(Roles.Semicolon); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitYieldBreakStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitYieldBreakStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitYieldBreakStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tYieldBreakStatement o = other as YieldBreakStatement;\n\t\t\treturn o != null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/Statements/YieldReturnStatement.cs",
    "content": "// \n// YieldStatement.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// yield return Expression;\n\t/// </summary>\n\tpublic class YieldReturnStatement : Statement\n\t{\n\t\tpublic static readonly TokenRole YieldKeywordRole = new TokenRole(\"yield\");\n\t\tpublic static readonly TokenRole ReturnKeywordRole = new TokenRole(\"return\");\n\n\t\tpublic CSharpTokenNode YieldToken {\n\t\t\tget { return GetChildByRole(YieldKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode ReturnToken {\n\t\t\tget { return GetChildByRole(ReturnKeywordRole); }\n\t\t}\n\n\t\tpublic Expression Expression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode SemicolonToken {\n\t\t\tget { return GetChildByRole(Roles.Semicolon); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitYieldReturnStatement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitYieldReturnStatement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitYieldReturnStatement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tYieldReturnStatement o = other as YieldReturnStatement;\n\t\t\treturn o != null && this.Expression.DoMatch(o.Expression, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/SyntaxExtensions.cs",
    "content": "// Copyright (c) 2013 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Extension methods for the syntax tree.\n\t/// </summary>\n\tpublic static class SyntaxExtensions\n\t{\n\t\tpublic static bool IsComparisonOperator(this OperatorType operatorType)\n\t\t{\n\t\t\tswitch (operatorType)\n\t\t\t{\n\t\t\t\tcase OperatorType.Equality:\n\t\t\t\tcase OperatorType.Inequality:\n\t\t\t\tcase OperatorType.GreaterThan:\n\t\t\t\tcase OperatorType.LessThan:\n\t\t\t\tcase OperatorType.GreaterThanOrEqual:\n\t\t\t\tcase OperatorType.LessThanOrEqual:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns true if <paramref name=\"operatorType\"/> is bitwise and, bitwise or, or exclusive or.\n\t\t/// </summary>\n\t\tpublic static bool IsBitwise(this BinaryOperatorType operatorType)\n\t\t{\n\t\t\treturn operatorType == BinaryOperatorType.BitwiseAnd\n\t\t\t\t|| operatorType == BinaryOperatorType.BitwiseOr\n\t\t\t\t|| operatorType == BinaryOperatorType.ExclusiveOr;\n\t\t}\n\n\t\tpublic static Statement GetNextStatement(this Statement statement)\n\t\t{\n\t\t\tAstNode next = statement.NextSibling;\n\t\t\twhile (next != null && !(next is Statement))\n\t\t\t\tnext = next.NextSibling;\n\t\t\treturn (Statement)next;\n\t\t}\n\n\t\tpublic static bool IsArgList(this AstType type)\n\t\t{\n\t\t\tvar simpleType = type as SimpleType;\n\t\t\treturn simpleType != null && simpleType.Identifier == \"__arglist\";\n\t\t}\n\n\t\tpublic static void AddNamedArgument(this Syntax.Attribute attribute, string name, Expression argument)\n\t\t{\n\t\t\tattribute.Arguments.Add(new AssignmentExpression(new IdentifierExpression(name), argument));\n\t\t}\n\n\t\tpublic static T Detach<T>(this T node) where T : AstNode\n\t\t{\n\t\t\tnode.Remove();\n\t\t\treturn node;\n\t\t}\n\n\t\tpublic static Expression UnwrapInDirectionExpression(this Expression expr)\n\t\t{\n\t\t\tif (!(expr is DirectionExpression dir && dir.FieldDirection == FieldDirection.In))\n\t\t\t\treturn expr;\n\t\t\treturn dir.Expression.Detach();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/SyntaxTree.cs",
    "content": "// \n// SyntaxTree.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class SyntaxTree : AstNode\n\t{\n\t\tpublic static readonly Role<AstNode> MemberRole = new Role<AstNode>(\"Member\", AstNode.Null);\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget {\n\t\t\t\treturn NodeType.Unknown;\n\t\t\t}\n\t\t}\n\n\t\tstring fileName;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the file name of this syntax tree.\n\t\t/// </summary>\n\t\tpublic string FileName {\n\t\t\tget { return fileName; }\n\t\t\tset {\n\t\t\t\tThrowIfFrozen();\n\t\t\t\tfileName = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic AstNodeCollection<AstNode> Members {\n\t\t\tget { return GetChildrenByRole(MemberRole); }\n\t\t}\n\n\t\tIList<string> conditionalSymbols = null;\n\n\t\t/// <summary>\n\t\t/// Gets the conditional symbols used to parse the source file. Note that this list contains\n\t\t/// the conditional symbols at the start of the first token in the file - including the ones defined\n\t\t/// in the source file.\n\t\t/// </summary>\n\t\tpublic IList<string> ConditionalSymbols {\n\t\t\tget {\n\t\t\t\treturn conditionalSymbols ?? EmptyList<string>.Instance;\n\t\t\t}\n\t\t\tinternal set {\n\t\t\t\tconditionalSymbols = value;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the expression that was on top of the parse stack.\n\t\t/// This is the only way to get an expression that isn't part of a statment.\n\t\t/// (eg. when an error follows an expression).\n\t\t/// \n\t\t/// This is used for code completion to 'get the expression before a token - like ., &lt;, ('.\n\t\t/// </summary>\n\t\tpublic AstNode TopExpression {\n\t\t\tget;\n\t\t\tinternal set;\n\t\t}\n\n\t\tpublic SyntaxTree()\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets all defined types in this syntax tree.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// A list containing <see cref=\"TypeDeclaration\"/> or <see cref=\"DelegateDeclaration\"/> nodes.\n\t\t/// </returns>\n\t\tpublic IEnumerable<EntityDeclaration> GetTypes(bool includeInnerTypes = false)\n\t\t{\n\t\t\tStack<AstNode> nodeStack = new Stack<AstNode>();\n\t\t\tnodeStack.Push(this);\n\t\t\twhile (nodeStack.Count > 0)\n\t\t\t{\n\t\t\t\tvar curNode = nodeStack.Pop();\n\t\t\t\tif (curNode is TypeDeclaration || curNode is DelegateDeclaration)\n\t\t\t\t{\n\t\t\t\t\tyield return (EntityDeclaration)curNode;\n\t\t\t\t}\n\t\t\t\tforeach (var child in curNode.Children)\n\t\t\t\t{\n\t\t\t\t\tif (!(child is Statement || child is Expression) &&\n\t\t\t\t\t\t(child.Role != Roles.TypeMemberRole || ((child is TypeDeclaration || child is DelegateDeclaration) && includeInnerTypes)))\n\t\t\t\t\t\tnodeStack.Push(child);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tSyntaxTree o = other as SyntaxTree;\n\t\t\treturn o != null && this.Members.DoMatch(o.Members, match);\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitSyntaxTree(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitSyntaxTree(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitSyntaxTree(this, data);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TextLocation.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.ComponentModel;\nusing System.Globalization;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// A line/column position.\n\t/// Text editor lines/columns are counted started from one.\n\t/// </summary>\n\t[Serializable]\n\t[TypeConverter(typeof(TextLocationConverter))]\n\tpublic struct TextLocation : IComparable<TextLocation>, IEquatable<TextLocation>\n\t{\n\t\t/// <summary>\n\t\t/// Represents no text location (0, 0).\n\t\t/// </summary>\n\t\tpublic static readonly TextLocation Empty = new TextLocation(0, 0);\n\n\t\t/// <summary>\n\t\t/// Constant of the minimum line.\n\t\t/// </summary>\n\t\tpublic const int MinLine = 1;\n\n\t\t/// <summary>\n\t\t/// Constant of the minimum column.\n\t\t/// </summary>\n\t\tpublic const int MinColumn = 1;\n\n\t\t/// <summary>\n\t\t/// Creates a TextLocation instance.\n\t\t/// </summary>\n\t\tpublic TextLocation(int line, int column)\n\t\t{\n\t\t\tthis.line = line;\n\t\t\tthis.column = column;\n\t\t}\n\n\t\tint column, line;\n\n\t\t/// <summary>\n\t\t/// Gets the line number.\n\t\t/// </summary>\n\t\tpublic int Line {\n\t\t\tget { return line; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the column number.\n\t\t/// </summary>\n\t\tpublic int Column {\n\t\t\tget { return column; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the TextLocation instance is empty.\n\t\t/// </summary>\n\t\tpublic bool IsEmpty {\n\t\t\tget {\n\t\t\t\treturn column < MinLine && line < MinColumn;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a string representation for debugging purposes.\n\t\t/// </summary>\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(CultureInfo.InvariantCulture, \"(Line {1}, Col {0})\", this.column, this.line);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a hash code.\n\t\t/// </summary>\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn unchecked(191 * column.GetHashCode() ^ line.GetHashCode());\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Equality test.\n\t\t/// </summary>\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\tif (!(obj is TextLocation))\n\t\t\t\treturn false;\n\t\t\treturn (TextLocation)obj == this;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Equality test.\n\t\t/// </summary>\n\t\tpublic bool Equals(TextLocation other)\n\t\t{\n\t\t\treturn this == other;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Equality test.\n\t\t/// </summary>\n\t\tpublic static bool operator ==(TextLocation left, TextLocation right)\n\t\t{\n\t\t\treturn left.column == right.column && left.line == right.line;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Inequality test.\n\t\t/// </summary>\n\t\tpublic static bool operator !=(TextLocation left, TextLocation right)\n\t\t{\n\t\t\treturn left.column != right.column || left.line != right.line;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Compares two text locations.\n\t\t/// </summary>\n\t\tpublic static bool operator <(TextLocation left, TextLocation right)\n\t\t{\n\t\t\tif (left.line < right.line)\n\t\t\t\treturn true;\n\t\t\telse if (left.line == right.line)\n\t\t\t\treturn left.column < right.column;\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Compares two text locations.\n\t\t/// </summary>\n\t\tpublic static bool operator >(TextLocation left, TextLocation right)\n\t\t{\n\t\t\tif (left.line > right.line)\n\t\t\t\treturn true;\n\t\t\telse if (left.line == right.line)\n\t\t\t\treturn left.column > right.column;\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Compares two text locations.\n\t\t/// </summary>\n\t\tpublic static bool operator <=(TextLocation left, TextLocation right)\n\t\t{\n\t\t\treturn !(left > right);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Compares two text locations.\n\t\t/// </summary>\n\t\tpublic static bool operator >=(TextLocation left, TextLocation right)\n\t\t{\n\t\t\treturn !(left < right);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Compares two text locations.\n\t\t/// </summary>\n\t\tpublic int CompareTo(TextLocation other)\n\t\t{\n\t\t\tif (this == other)\n\t\t\t\treturn 0;\n\t\t\tif (this < other)\n\t\t\t\treturn -1;\n\t\t\telse\n\t\t\t\treturn 1;\n\t\t}\n\t}\n\n\tpublic class TextLocationConverter : TypeConverter\n\t{\n\t\tpublic override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)\n\t\t{\n\t\t\treturn sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);\n\t\t}\n\n\t\tpublic override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)\n\t\t{\n\t\t\treturn destinationType == typeof(TextLocation) || base.CanConvertTo(context, destinationType);\n\t\t}\n\n\t\tpublic override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)\n\t\t{\n\t\t\tif (value is string)\n\t\t\t{\n\t\t\t\tstring[] parts = ((string)value).Split(';', ',');\n\t\t\t\tif (parts.Length == 2)\n\t\t\t\t{\n\t\t\t\t\treturn new TextLocation(int.Parse(parts[0]), int.Parse(parts[1]));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn base.ConvertFrom(context, culture, value);\n\t\t}\n\n\t\tpublic override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)\n\t\t{\n\t\t\tif (value is TextLocation)\n\t\t\t{\n\t\t\t\tvar loc = (TextLocation)value;\n\t\t\t\treturn loc.Line + \";\" + loc.Column;\n\t\t\t}\n\t\t\treturn base.ConvertTo(context, culture, value, destinationType);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TokenRole.cs",
    "content": "namespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// A specific role only used for C# tokens\n\t/// </summary>\n\tpublic sealed class TokenRole : Role<CSharpTokenNode>\n\t{\n\t\t/// <summary>\n\t\t/// Gets the token as string. Note that the token Name and Token value may differ.\n\t\t/// </summary>\n\t\tpublic string Token { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the char length of the token.\n\t\t/// </summary>\n\t\tpublic int Length { get; }\n\n\t\tpublic TokenRole(string token) : base(token, CSharpTokenNode.Null)\n\t\t{\n\t\t\tthis.Token = token;\n\t\t\tthis.Length = token.Length;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TupleAstType.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class TupleAstType : AstType\n\t{\n\t\tpublic static readonly Role<TupleTypeElement> ElementRole = new Role<TupleTypeElement>(\"Element\", TupleTypeElement.Null);\n\n\t\tpublic AstNodeCollection<TupleTypeElement> Elements {\n\t\t\tget { return GetChildrenByRole(ElementRole); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitTupleType(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitTupleType(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitTupleType(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, Match match)\n\t\t{\n\t\t\treturn other is TupleAstType o && Elements.DoMatch(o.Elements, match);\n\t\t}\n\t}\n\n\tpublic class TupleTypeElement : AstNode\n\t{\n\t\t#region Null\n\t\tpublic new static readonly TupleTypeElement Null = new TupleTypeElement();\n\n\t\tsealed class NullTupleTypeElement : TupleTypeElement\n\t\t{\n\t\t\tpublic override bool IsNull {\n\t\t\t\tget {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn other == null || other.IsNull;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget { return GetChildByRole(Roles.Identifier).Name; }\n\t\t\tset { SetChildByRole(Roles.Identifier, Identifier.Create(value)); }\n\t\t}\n\n\t\tpublic Identifier NameToken {\n\t\t\tget { return GetChildByRole(Roles.Identifier); }\n\t\t\tset { SetChildByRole(Roles.Identifier, value); }\n\t\t}\n\n\t\tpublic override NodeType NodeType => NodeType.Unknown;\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitTupleTypeElement(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitTupleTypeElement(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitTupleTypeElement(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, Match match)\n\t\t{\n\t\t\treturn other is TupleTypeElement o\n\t\t\t\t&& Type.DoMatch(o.Type, match)\n\t\t\t\t&& MatchString(Name, o.Name);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/Accessor.cs",
    "content": "// \n// PropertyDeclaration.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// get/set/init/add/remove\n\t/// </summary>\n\tpublic class Accessor : EntityDeclaration\n\t{\n\t\tpublic static readonly new Accessor Null = new NullAccessor();\n\t\tsealed class NullAccessor : Accessor\n\t\t{\n\t\t\tpublic override bool IsNull {\n\t\t\t\tget {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn other == null || other.IsNull;\n\t\t\t}\n\t\t}\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget { return NodeType.Unknown; }\n\t\t}\n\n\t\tpublic override SymbolKind SymbolKind {\n\t\t\tget { return SymbolKind.Method; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the 'get'/'set'/'init'/'add'/'remove' keyword\n\t\t/// </summary>\n\t\tpublic CSharpTokenNode Keyword {\n\t\t\tget {\n\t\t\t\tfor (AstNode child = this.FirstChild; child != null; child = child.NextSibling)\n\t\t\t\t{\n\t\t\t\t\tif (child.Role == PropertyDeclaration.GetKeywordRole || child.Role == PropertyDeclaration.SetKeywordRole\n\t\t\t\t\t\t|| child.Role == PropertyDeclaration.InitKeywordRole\n\t\t\t\t\t\t|| child.Role == CustomEventDeclaration.AddKeywordRole || child.Role == CustomEventDeclaration.RemoveKeywordRole)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn (CSharpTokenNode)child;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn CSharpTokenNode.Null;\n\t\t\t}\n\t\t}\n\n\t\tpublic BlockStatement Body {\n\t\t\tget { return GetChildByRole(Roles.Body); }\n\t\t\tset { SetChildByRole(Roles.Body, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitAccessor(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitAccessor(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitAccessor(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tAccessor o = other as Accessor;\n\t\t\treturn o != null && !o.IsNull && this.MatchAttributesAndModifiers(o, match) && this.Body.DoMatch(o.Body, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/ConstructorDeclaration.cs",
    "content": "// \n// ConstructorDeclaration.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class ConstructorDeclaration : EntityDeclaration\n\t{\n\t\tpublic static readonly Role<ConstructorInitializer> InitializerRole = new Role<ConstructorInitializer>(\"Initializer\", ConstructorInitializer.Null);\n\n\t\tpublic override SymbolKind SymbolKind {\n\t\t\tget { return SymbolKind.Constructor; }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstNodeCollection<ParameterDeclaration> Parameters {\n\t\t\tget { return GetChildrenByRole(Roles.Parameter); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic CSharpTokenNode ColonToken {\n\t\t\tget { return GetChildByRole(Roles.Colon); }\n\t\t}\n\n\t\tpublic ConstructorInitializer Initializer {\n\t\t\tget { return GetChildByRole(InitializerRole); }\n\t\t\tset { SetChildByRole(InitializerRole, value); }\n\t\t}\n\n\t\tpublic BlockStatement Body {\n\t\t\tget { return GetChildByRole(Roles.Body); }\n\t\t\tset { SetChildByRole(Roles.Body, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitConstructorDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitConstructorDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitConstructorDeclaration(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tConstructorDeclaration o = other as ConstructorDeclaration;\n\t\t\treturn o != null && this.MatchAttributesAndModifiers(o, match) && this.Parameters.DoMatch(o.Parameters, match)\n\t\t\t\t&& this.Initializer.DoMatch(o.Initializer, match) && this.Body.DoMatch(o.Body, match);\n\t\t}\n\t}\n\n\tpublic enum ConstructorInitializerType\n\t{\n\t\tAny,\n\t\tBase,\n\t\tThis\n\t}\n\n\tpublic class ConstructorInitializer : AstNode\n\t{\n\t\tpublic static readonly TokenRole BaseKeywordRole = new TokenRole(\"base\");\n\t\tpublic static readonly TokenRole ThisKeywordRole = new TokenRole(\"this\");\n\n\t\tpublic static readonly new ConstructorInitializer Null = new NullConstructorInitializer();\n\t\tclass NullConstructorInitializer : ConstructorInitializer\n\t\t{\n\t\t\tpublic override NodeType NodeType {\n\t\t\t\tget {\n\t\t\t\t\treturn NodeType.Unknown;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override bool IsNull {\n\t\t\t\tget {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn other == null || other.IsNull;\n\t\t\t}\n\t\t}\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget {\n\t\t\t\treturn NodeType.Unknown;\n\t\t\t}\n\t\t}\n\n\t\tpublic ConstructorInitializerType ConstructorInitializerType {\n\t\t\tget;\n\t\t\tset;\n\t\t}\n\n\t\tpublic CSharpTokenNode Keyword {\n\t\t\tget {\n\t\t\t\tif (ConstructorInitializerType == ConstructorInitializerType.Base)\n\t\t\t\t\treturn GetChildByRole(BaseKeywordRole);\n\t\t\t\telse\n\t\t\t\t\treturn GetChildByRole(ThisKeywordRole);\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstNodeCollection<Expression> Arguments {\n\t\t\tget { return GetChildrenByRole(Roles.Argument); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitConstructorInitializer(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitConstructorInitializer(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitConstructorInitializer(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tConstructorInitializer o = other as ConstructorInitializer;\n\t\t\treturn o != null && !o.IsNull\n\t\t\t\t&& (this.ConstructorInitializerType == ConstructorInitializerType.Any || this.ConstructorInitializerType == o.ConstructorInitializerType)\n\t\t\t\t&& this.Arguments.DoMatch(o.Arguments, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/DestructorDeclaration.cs",
    "content": "// \n// DestructorDeclaration.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class DestructorDeclaration : EntityDeclaration\n\t{\n\t\tpublic static readonly TokenRole TildeRole = new TokenRole(\"~\");\n\n\t\tpublic CSharpTokenNode TildeToken {\n\t\t\tget { return GetChildByRole(TildeRole); }\n\t\t}\n\n\t\tpublic override SymbolKind SymbolKind {\n\t\t\tget { return SymbolKind.Destructor; }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\t\tpublic BlockStatement Body {\n\t\t\tget { return GetChildByRole(Roles.Body); }\n\t\t\tset { SetChildByRole(Roles.Body, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDestructorDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDestructorDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitDestructorDeclaration(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tDestructorDeclaration o = other as DestructorDeclaration;\n\t\t\treturn o != null && this.MatchAttributesAndModifiers(o, match) && this.Body.DoMatch(o.Body, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/EntityDeclaration.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic abstract class EntityDeclaration : AstNode\n\t{\n\t\tpublic static readonly Role<AttributeSection> AttributeRole = new Role<AttributeSection>(\"Attribute\", null);\n\t\tpublic static readonly Role<CSharpModifierToken> ModifierRole = new Role<CSharpModifierToken>(\"Modifier\", null);\n\t\tpublic static readonly Role<AstType> PrivateImplementationTypeRole = new Role<AstType>(\"PrivateImplementationType\", AstType.Null);\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget { return NodeType.Member; }\n\t\t}\n\n\t\tpublic abstract SymbolKind SymbolKind { get; }\n\n\t\tpublic AstNodeCollection<AttributeSection> Attributes {\n\t\t\tget { return base.GetChildrenByRole(AttributeRole); }\n\t\t}\n\n\t\tpublic Modifiers Modifiers {\n\t\t\tget { return GetModifiers(this); }\n\t\t\tset { SetModifiers(this, value); }\n\t\t}\n\n\t\tpublic bool HasModifier(Modifiers mod)\n\t\t{\n\t\t\treturn (Modifiers & mod) == mod;\n\t\t}\n\n\t\tpublic IEnumerable<CSharpModifierToken> ModifierTokens {\n\t\t\tget { return GetChildrenByRole(ModifierRole); }\n\t\t}\n\n\t\tpublic virtual string Name {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, Identifier.Create(value, TextLocation.Empty));\n\t\t\t}\n\t\t}\n\n\t\tpublic virtual Identifier NameToken {\n\t\t\tget { return GetChildByRole(Roles.Identifier); }\n\t\t\tset { SetChildByRole(Roles.Identifier, value); }\n\t\t}\n\n\t\tpublic virtual AstType ReturnType {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode SemicolonToken {\n\t\t\tget { return GetChildByRole(Roles.Semicolon); }\n\t\t}\n\n\t\tinternal static Modifiers GetModifiers(AstNode node)\n\t\t{\n\t\t\tModifiers m = 0;\n\t\t\tforeach (CSharpModifierToken t in node.GetChildrenByRole(ModifierRole))\n\t\t\t{\n\t\t\t\tm |= t.Modifier;\n\t\t\t}\n\t\t\treturn m;\n\t\t}\n\n\t\tinternal static void SetModifiers(AstNode node, Modifiers newValue)\n\t\t{\n\t\t\tModifiers oldValue = GetModifiers(node);\n\t\t\tAstNode insertionPos = node.GetChildrenByRole(AttributeRole).LastOrDefault();\n\t\t\tforeach (Modifiers m in CSharpModifierToken.AllModifiers)\n\t\t\t{\n\t\t\t\tif ((m & newValue) != 0)\n\t\t\t\t{\n\t\t\t\t\tif ((m & oldValue) == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Modifier was added\n\t\t\t\t\t\tvar newToken = new CSharpModifierToken(TextLocation.Empty, m);\n\t\t\t\t\t\tnode.InsertChildAfter(insertionPos, newToken, ModifierRole);\n\t\t\t\t\t\tinsertionPos = newToken;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// Modifier already exists\n\t\t\t\t\t\tinsertionPos = node.GetChildrenByRole(ModifierRole).First(t => t.Modifier == m);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif ((m & oldValue) != 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Modifier was removed\n\t\t\t\t\t\tnode.GetChildrenByRole(ModifierRole).First(t => t.Modifier == m).Remove();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected bool MatchAttributesAndModifiers(EntityDeclaration o, PatternMatching.Match match)\n\t\t{\n\t\t\treturn (this.Modifiers == Modifiers.Any || this.Modifiers == o.Modifiers) && this.Attributes.DoMatch(o.Attributes, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/EnumMemberDeclaration.cs",
    "content": "// \n// EnumMemberDeclaration.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class EnumMemberDeclaration : EntityDeclaration\n\t{\n\t\tpublic static readonly Role<Expression> InitializerRole = new Role<Expression>(\"Initializer\", Expression.Null);\n\n\t\tpublic override SymbolKind SymbolKind {\n\t\t\tget { return SymbolKind.Field; }\n\t\t}\n\n\t\tpublic CSharpTokenNode AssignToken {\n\t\t\tget { return GetChildByRole(Roles.Assign); }\n\t\t}\n\n\t\tpublic Expression Initializer {\n\t\t\tget { return GetChildByRole(InitializerRole); }\n\t\t\tset { SetChildByRole(InitializerRole, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitEnumMemberDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitEnumMemberDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitEnumMemberDeclaration(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tEnumMemberDeclaration o = other as EnumMemberDeclaration;\n\t\t\treturn o != null && this.MatchAttributesAndModifiers(o, match)\n\t\t\t\t&& MatchString(this.Name, o.Name) && this.Initializer.DoMatch(o.Initializer, match);\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/EventDeclaration.cs",
    "content": "// \n// EventDeclaration.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System;\nusing System.ComponentModel;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class EventDeclaration : EntityDeclaration\n\t{\n\t\tpublic static readonly TokenRole EventKeywordRole = new TokenRole(\"event\");\n\n\t\tpublic override SymbolKind SymbolKind {\n\t\t\tget { return SymbolKind.Event; }\n\t\t}\n\n\t\tpublic CSharpTokenNode EventToken {\n\t\t\tget { return GetChildByRole(EventKeywordRole); }\n\t\t}\n\n\t\tpublic AstNodeCollection<VariableInitializer> Variables {\n\t\t\tget { return GetChildrenByRole(Roles.Variable); }\n\t\t}\n\n\t\t// Hide .Name and .NameToken from users; the actual field names\n\t\t// are stored in the VariableInitializer.\n\t\t[EditorBrowsable(EditorBrowsableState.Never)]\n\t\tpublic override string Name {\n\t\t\tget { return string.Empty; }\n\t\t\tset { throw new NotSupportedException(); }\n\t\t}\n\n\t\t[EditorBrowsable(EditorBrowsableState.Never)]\n\t\tpublic override Identifier NameToken {\n\t\t\tget { return Identifier.Null; }\n\t\t\tset { throw new NotSupportedException(); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitEventDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitEventDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitEventDeclaration(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tEventDeclaration o = other as EventDeclaration;\n\t\t\treturn o != null && this.MatchAttributesAndModifiers(o, match)\n\t\t\t\t&& this.ReturnType.DoMatch(o.ReturnType, match) && this.Variables.DoMatch(o.Variables, match);\n\t\t}\n\t}\n\n\tpublic class CustomEventDeclaration : EntityDeclaration\n\t{\n\t\tpublic static readonly TokenRole EventKeywordRole = new TokenRole(\"event\");\n\t\tpublic static readonly TokenRole AddKeywordRole = new TokenRole(\"add\");\n\t\tpublic static readonly TokenRole RemoveKeywordRole = new TokenRole(\"remove\");\n\n\t\tpublic static readonly Role<Accessor> AddAccessorRole = new Role<Accessor>(\"AddAccessor\", Accessor.Null);\n\t\tpublic static readonly Role<Accessor> RemoveAccessorRole = new Role<Accessor>(\"RemoveAccessor\", Accessor.Null);\n\n\t\tpublic override SymbolKind SymbolKind {\n\t\t\tget { return SymbolKind.Event; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the type reference of the interface that is explicitly implemented.\n\t\t/// Null node if this member is not an explicit interface implementation.\n\t\t/// </summary>\n\t\tpublic AstType PrivateImplementationType {\n\t\t\tget { return GetChildByRole(PrivateImplementationTypeRole); }\n\t\t\tset { SetChildByRole(PrivateImplementationTypeRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LBraceToken {\n\t\t\tget { return GetChildByRole(Roles.LBrace); }\n\t\t}\n\n\t\tpublic Accessor AddAccessor {\n\t\t\tget { return GetChildByRole(AddAccessorRole); }\n\t\t\tset { SetChildByRole(AddAccessorRole, value); }\n\t\t}\n\n\t\tpublic Accessor RemoveAccessor {\n\t\t\tget { return GetChildByRole(RemoveAccessorRole); }\n\t\t\tset { SetChildByRole(RemoveAccessorRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RBraceToken {\n\t\t\tget { return GetChildByRole(Roles.RBrace); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitCustomEventDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitCustomEventDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitCustomEventDeclaration(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tCustomEventDeclaration o = other as CustomEventDeclaration;\n\t\t\treturn o != null && MatchString(this.Name, o.Name)\n\t\t\t\t&& this.MatchAttributesAndModifiers(o, match) && this.ReturnType.DoMatch(o.ReturnType, match)\n\t\t\t\t&& this.PrivateImplementationType.DoMatch(o.PrivateImplementationType, match)\n\t\t\t\t&& this.AddAccessor.DoMatch(o.AddAccessor, match) && this.RemoveAccessor.DoMatch(o.RemoveAccessor, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/ExtensionDeclaration.cs",
    "content": "// Copyright (c) 2025 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class ExtensionDeclaration : EntityDeclaration\n\t{\n\t\tpublic readonly static TokenRole ExtensionKeywordRole = new TokenRole(\"extension\");\n\n\t\tpublic override SymbolKind SymbolKind => throw new System.NotImplementedException();\n\n\t\tpublic AstNodeCollection<TypeParameterDeclaration> TypeParameters {\n\t\t\tget { return GetChildrenByRole(Roles.TypeParameter); }\n\t\t}\n\n\t\tpublic AstNodeCollection<ParameterDeclaration> ReceiverParameters {\n\t\t\tget { return GetChildrenByRole(Roles.Parameter); }\n\t\t}\n\n\t\tpublic AstNodeCollection<Constraint> Constraints {\n\t\t\tget { return GetChildrenByRole(Roles.Constraint); }\n\t\t}\n\n\t\tpublic AstNodeCollection<EntityDeclaration> Members {\n\t\t\tget { return GetChildrenByRole(Roles.TypeMemberRole); }\n\t\t}\n\n\t\tpublic ExtensionDeclaration()\n\t\t{\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitExtensionDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitExtensionDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitExtensionDeclaration(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tvar o = other as ExtensionDeclaration;\n\t\t\treturn o != null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/FieldDeclaration.cs",
    "content": "// \n// FieldDeclaration.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System;\nusing System.ComponentModel;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class FieldDeclaration : EntityDeclaration\n\t{\n\t\tpublic override SymbolKind SymbolKind {\n\t\t\tget { return SymbolKind.Field; }\n\t\t}\n\n\t\tpublic AstNodeCollection<VariableInitializer> Variables {\n\t\t\tget { return GetChildrenByRole(Roles.Variable); }\n\t\t}\n\n\t\t// Hide .Name and .NameToken from users; the actual field names\n\t\t// are stored in the VariableInitializer.\n\t\t[EditorBrowsable(EditorBrowsableState.Never)]\n\t\tpublic override string Name {\n\t\t\tget { return string.Empty; }\n\t\t\tset { throw new NotSupportedException(); }\n\t\t}\n\n\t\t[EditorBrowsable(EditorBrowsableState.Never)]\n\t\tpublic override Identifier NameToken {\n\t\t\tget { return Identifier.Null; }\n\t\t\tset { throw new NotSupportedException(); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitFieldDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitFieldDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitFieldDeclaration(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tFieldDeclaration o = other as FieldDeclaration;\n\t\t\treturn o != null && this.MatchAttributesAndModifiers(o, match)\n\t\t\t\t&& this.ReturnType.DoMatch(o.ReturnType, match) && this.Variables.DoMatch(o.Variables, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/FixedFieldDeclaration.cs",
    "content": "// \n// FixedFieldDeclaration.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2011 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class FixedFieldDeclaration : EntityDeclaration\n\t{\n\t\tpublic static readonly TokenRole FixedKeywordRole = new TokenRole(\"fixed\");\n\t\tpublic static readonly Role<FixedVariableInitializer> VariableRole = new Role<FixedVariableInitializer>(\"FixedVariable\", null);\n\n\t\tpublic override SymbolKind SymbolKind {\n\t\t\tget { return SymbolKind.Field; }\n\t\t}\n\n\t\tpublic CSharpTokenNode FixedToken {\n\t\t\tget { return GetChildByRole(FixedKeywordRole); }\n\t\t}\n\n\t\tpublic AstNodeCollection<FixedVariableInitializer> Variables {\n\t\t\tget { return GetChildrenByRole(VariableRole); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitFixedFieldDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitFixedFieldDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitFixedFieldDeclaration(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tvar o = other as FixedFieldDeclaration;\n\t\t\treturn o != null && this.MatchAttributesAndModifiers(o, match)\n\t\t\t\t&& this.ReturnType.DoMatch(o.ReturnType, match) && this.Variables.DoMatch(o.Variables, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/FixedVariableInitializer.cs",
    "content": "// \n// FixedFieldDeclaration.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2011 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Name [ CountExpression ]\n\t/// </summary>\n\tpublic class FixedVariableInitializer : AstNode\n\t{\n\t\tpublic override NodeType NodeType {\n\t\t\tget {\n\t\t\t\treturn NodeType.Unknown;\n\t\t\t}\n\t\t}\n\n\t\tpublic FixedVariableInitializer()\n\t\t{\n\t\t}\n\n\t\tpublic FixedVariableInitializer(string name, Expression initializer = null)\n\t\t{\n\t\t\tthis.Name = name;\n\t\t\tthis.CountExpression = initializer;\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier NameToken {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, value);\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode LBracketToken {\n\t\t\tget { return GetChildByRole(Roles.LBracket); }\n\t\t}\n\n\t\tpublic Expression CountExpression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RBracketToken {\n\t\t\tget { return GetChildByRole(Roles.RBracket); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitFixedVariableInitializer(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitFixedVariableInitializer(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitFixedVariableInitializer(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tvar o = other as FixedVariableInitializer;\n\t\t\treturn o != null && MatchString(this.Name, o.Name) && this.CountExpression.DoMatch(o.CountExpression, match);\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/IndexerDeclaration.cs",
    "content": "// \n// IndexerDeclaration.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System;\nusing System.ComponentModel;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class IndexerDeclaration : EntityDeclaration\n\t{\n\t\tpublic static readonly TokenRole ThisKeywordRole = new TokenRole(\"this\");\n\t\tpublic static readonly Role<Accessor> GetterRole = PropertyDeclaration.GetterRole;\n\t\tpublic static readonly Role<Accessor> SetterRole = PropertyDeclaration.SetterRole;\n\t\tpublic static readonly Role<Expression> ExpressionBodyRole = new Role<Expression>(\"ExpressionBody\", Expression.Null);\n\n\t\tpublic override SymbolKind SymbolKind {\n\t\t\tget { return SymbolKind.Indexer; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the type reference of the interface that is explicitly implemented.\n\t\t/// Null node if this member is not an explicit interface implementation.\n\t\t/// </summary>\n\t\tpublic AstType PrivateImplementationType {\n\t\t\tget { return GetChildByRole(PrivateImplementationTypeRole); }\n\t\t\tset { SetChildByRole(PrivateImplementationTypeRole, value); }\n\t\t}\n\n\t\tpublic override string Name {\n\t\t\tget { return \"Item\"; }\n\t\t\tset { throw new NotSupportedException(); }\n\t\t}\n\n\t\t[EditorBrowsable(EditorBrowsableState.Never)]\n\t\tpublic override Identifier NameToken {\n\t\t\tget { return Identifier.Null; }\n\t\t\tset { throw new NotSupportedException(); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LBracketToken {\n\t\t\tget { return GetChildByRole(Roles.LBracket); }\n\t\t}\n\n\t\tpublic CSharpTokenNode ThisToken {\n\t\t\tget { return GetChildByRole(ThisKeywordRole); }\n\t\t}\n\n\t\tpublic AstNodeCollection<ParameterDeclaration> Parameters {\n\t\t\tget { return GetChildrenByRole(Roles.Parameter); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RBracketToken {\n\t\t\tget { return GetChildByRole(Roles.RBracket); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LBraceToken {\n\t\t\tget { return GetChildByRole(Roles.LBrace); }\n\t\t}\n\n\t\tpublic Accessor Getter {\n\t\t\tget { return GetChildByRole(GetterRole); }\n\t\t\tset { SetChildByRole(GetterRole, value); }\n\t\t}\n\n\t\tpublic Accessor Setter {\n\t\t\tget { return GetChildByRole(SetterRole); }\n\t\t\tset { SetChildByRole(SetterRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RBraceToken {\n\t\t\tget { return GetChildByRole(Roles.RBrace); }\n\t\t}\n\n\t\tpublic Expression ExpressionBody {\n\t\t\tget { return GetChildByRole(ExpressionBodyRole); }\n\t\t\tset { SetChildByRole(ExpressionBodyRole, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitIndexerDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitIndexerDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitIndexerDeclaration(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tIndexerDeclaration o = other as IndexerDeclaration;\n\t\t\treturn o != null\n\t\t\t\t&& this.MatchAttributesAndModifiers(o, match) && this.ReturnType.DoMatch(o.ReturnType, match)\n\t\t\t\t&& this.PrivateImplementationType.DoMatch(o.PrivateImplementationType, match)\n\t\t\t\t&& this.Parameters.DoMatch(o.Parameters, match)\n\t\t\t\t&& this.Getter.DoMatch(o.Getter, match) && this.Setter.DoMatch(o.Setter, match)\n\t\t\t\t&& this.ExpressionBody.DoMatch(o.ExpressionBody, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/MethodDeclaration.cs",
    "content": "// \n// MethodDeclaration.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class MethodDeclaration : EntityDeclaration\n\t{\n\t\tpublic override SymbolKind SymbolKind {\n\t\t\tget { return SymbolKind.Method; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the type reference of the interface that is explicitly implemented.\n\t\t/// Null node if this member is not an explicit interface implementation.\n\t\t/// </summary>\n\t\tpublic AstType PrivateImplementationType {\n\t\t\tget { return GetChildByRole(PrivateImplementationTypeRole); }\n\t\t\tset { SetChildByRole(PrivateImplementationTypeRole, value); }\n\t\t}\n\n\t\tpublic AstNodeCollection<TypeParameterDeclaration> TypeParameters {\n\t\t\tget { return GetChildrenByRole(Roles.TypeParameter); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstNodeCollection<ParameterDeclaration> Parameters {\n\t\t\tget { return GetChildrenByRole(Roles.Parameter); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic AstNodeCollection<Constraint> Constraints {\n\t\t\tget { return GetChildrenByRole(Roles.Constraint); }\n\t\t}\n\n\t\tpublic BlockStatement Body {\n\t\t\tget { return GetChildByRole(Roles.Body); }\n\t\t\tset { SetChildByRole(Roles.Body, value); }\n\t\t}\n\n\t\tpublic bool IsExtensionMethod {\n\t\t\tget {\n\t\t\t\tParameterDeclaration pd = (ParameterDeclaration)GetChildByRole(Roles.Parameter);\n\t\t\t\treturn pd != null && pd.HasThisModifier;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitMethodDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitMethodDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitMethodDeclaration(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tMethodDeclaration o = other as MethodDeclaration;\n\t\t\treturn o != null && MatchString(this.Name, o.Name)\n\t\t\t\t&& this.MatchAttributesAndModifiers(o, match) && this.ReturnType.DoMatch(o.ReturnType, match)\n\t\t\t\t&& this.PrivateImplementationType.DoMatch(o.PrivateImplementationType, match)\n\t\t\t\t&& this.TypeParameters.DoMatch(o.TypeParameters, match)\n\t\t\t\t&& this.Parameters.DoMatch(o.Parameters, match) && this.Constraints.DoMatch(o.Constraints, match)\n\t\t\t\t&& this.Body.DoMatch(o.Body, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/OperatorDeclaration.cs",
    "content": "// \n// OperatorDeclaration.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing System;\nusing System.ComponentModel;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic enum OperatorType\n\t{\n\t\t// Unary operators\n\t\tLogicalNot,\n\t\tOnesComplement,\n\t\tIncrement,\n\t\tCheckedIncrement,\n\t\tDecrement,\n\t\tCheckedDecrement,\n\t\tTrue,\n\t\tFalse,\n\n\t\tUnaryPlus,\n\t\tUnaryNegation,\n\t\tCheckedUnaryNegation,\n\n\t\t// Binary operators\n\t\tAddition,\n\t\tCheckedAddition,\n\t\tSubtraction,\n\t\tCheckedSubtraction,\n\t\tMultiply,\n\t\tCheckedMultiply,\n\t\tDivision,\n\t\tCheckedDivision,\n\t\tModulus,\n\t\tBitwiseAnd,\n\t\tBitwiseOr,\n\t\tExclusiveOr,\n\t\tLeftShift,\n\t\tRightShift,\n\t\tUnsignedRightShift,\n\t\tEquality,\n\t\tInequality,\n\t\tGreaterThan,\n\t\tLessThan,\n\t\tGreaterThanOrEqual,\n\t\tLessThanOrEqual,\n\n\t\t// Implicit and Explicit\n\t\tImplicit,\n\t\tExplicit,\n\t\tCheckedExplicit\n\t}\n\n\tpublic class OperatorDeclaration : EntityDeclaration\n\t{\n\t\tpublic static readonly TokenRole OperatorKeywordRole = new TokenRole(\"operator\");\n\t\tpublic static readonly TokenRole CheckedKeywordRole = new TokenRole(\"checked\");\n\n\t\t// Unary operators\n\t\tpublic static readonly TokenRole LogicalNotRole = new TokenRole(\"!\");\n\t\tpublic static readonly TokenRole OnesComplementRole = new TokenRole(\"~\");\n\t\tpublic static readonly TokenRole IncrementRole = new TokenRole(\"++\");\n\t\tpublic static readonly TokenRole DecrementRole = new TokenRole(\"--\");\n\t\tpublic static readonly TokenRole TrueRole = new TokenRole(\"true\");\n\t\tpublic static readonly TokenRole FalseRole = new TokenRole(\"false\");\n\n\t\t// Unary and Binary operators\n\t\tpublic static readonly TokenRole AdditionRole = new TokenRole(\"+\");\n\t\tpublic static readonly TokenRole SubtractionRole = new TokenRole(\"-\");\n\n\t\t// Binary operators\n\t\tpublic static readonly TokenRole MultiplyRole = new TokenRole(\"*\");\n\t\tpublic static readonly TokenRole DivisionRole = new TokenRole(\"/\");\n\t\tpublic static readonly TokenRole ModulusRole = new TokenRole(\"%\");\n\t\tpublic static readonly TokenRole BitwiseAndRole = new TokenRole(\"&\");\n\t\tpublic static readonly TokenRole BitwiseOrRole = new TokenRole(\"|\");\n\t\tpublic static readonly TokenRole ExclusiveOrRole = new TokenRole(\"^\");\n\t\tpublic static readonly TokenRole LeftShiftRole = new TokenRole(\"<<\");\n\t\tpublic static readonly TokenRole RightShiftRole = new TokenRole(\">>\");\n\t\tpublic static readonly TokenRole UnsignedRightShiftRole = new TokenRole(\">>>\");\n\t\tpublic static readonly TokenRole EqualityRole = new TokenRole(\"==\");\n\t\tpublic static readonly TokenRole InequalityRole = new TokenRole(\"!=\");\n\t\tpublic static readonly TokenRole GreaterThanRole = new TokenRole(\">\");\n\t\tpublic static readonly TokenRole LessThanRole = new TokenRole(\"<\");\n\t\tpublic static readonly TokenRole GreaterThanOrEqualRole = new TokenRole(\">=\");\n\t\tpublic static readonly TokenRole LessThanOrEqualRole = new TokenRole(\"<=\");\n\n\t\tpublic static readonly TokenRole ExplicitRole = new TokenRole(\"explicit\");\n\t\tpublic static readonly TokenRole ImplicitRole = new TokenRole(\"implicit\");\n\n\t\tstatic readonly string[][] names;\n\n\t\tstatic OperatorDeclaration()\n\t\t{\n\t\t\tnames = new string[(int)OperatorType.CheckedExplicit + 1][];\n\t\t\tnames[(int)OperatorType.LogicalNot] = new string[] { \"!\", \"op_LogicalNot\" };\n\t\t\tnames[(int)OperatorType.OnesComplement] = new string[] { \"~\", \"op_OnesComplement\" };\n\t\t\tnames[(int)OperatorType.Increment] = new string[] { \"++\", \"op_Increment\" };\n\t\t\tnames[(int)OperatorType.CheckedIncrement] = new string[] { \"++\", \"op_CheckedIncrement\" };\n\t\t\tnames[(int)OperatorType.Decrement] = new string[] { \"--\", \"op_Decrement\" };\n\t\t\tnames[(int)OperatorType.CheckedDecrement] = new string[] { \"--\", \"op_CheckedDecrement\" };\n\t\t\tnames[(int)OperatorType.True] = new string[] { \"true\", \"op_True\" };\n\t\t\tnames[(int)OperatorType.False] = new string[] { \"false\", \"op_False\" };\n\t\t\tnames[(int)OperatorType.UnaryPlus] = new string[] { \"+\", \"op_UnaryPlus\" };\n\t\t\tnames[(int)OperatorType.UnaryNegation] = new string[] { \"-\", \"op_UnaryNegation\" };\n\t\t\tnames[(int)OperatorType.CheckedUnaryNegation] = new string[] { \"-\", \"op_CheckedUnaryNegation\" };\n\t\t\tnames[(int)OperatorType.Addition] = new string[] { \"+\", \"op_Addition\" };\n\t\t\tnames[(int)OperatorType.CheckedAddition] = new string[] { \"+\", \"op_CheckedAddition\" };\n\t\t\tnames[(int)OperatorType.Subtraction] = new string[] { \"-\", \"op_Subtraction\" };\n\t\t\tnames[(int)OperatorType.CheckedSubtraction] = new string[] { \"-\", \"op_CheckedSubtraction\" };\n\t\t\tnames[(int)OperatorType.Multiply] = new string[] { \"*\", \"op_Multiply\" };\n\t\t\tnames[(int)OperatorType.CheckedMultiply] = new string[] { \"*\", \"op_CheckedMultiply\" };\n\t\t\tnames[(int)OperatorType.Division] = new string[] { \"/\", \"op_Division\" };\n\t\t\tnames[(int)OperatorType.CheckedDivision] = new string[] { \"/\", \"op_CheckedDivision\" };\n\t\t\tnames[(int)OperatorType.Modulus] = new string[] { \"%\", \"op_Modulus\" };\n\t\t\tnames[(int)OperatorType.BitwiseAnd] = new string[] { \"&\", \"op_BitwiseAnd\" };\n\t\t\tnames[(int)OperatorType.BitwiseOr] = new string[] { \"|\", \"op_BitwiseOr\" };\n\t\t\tnames[(int)OperatorType.ExclusiveOr] = new string[] { \"^\", \"op_ExclusiveOr\" };\n\t\t\tnames[(int)OperatorType.LeftShift] = new string[] { \"<<\", \"op_LeftShift\" };\n\t\t\tnames[(int)OperatorType.RightShift] = new string[] { \">>\", \"op_RightShift\" };\n\t\t\tnames[(int)OperatorType.UnsignedRightShift] = new string[] { \">>>\", \"op_UnsignedRightShift\" };\n\t\t\tnames[(int)OperatorType.Equality] = new string[] { \"==\", \"op_Equality\" };\n\t\t\tnames[(int)OperatorType.Inequality] = new string[] { \"!=\", \"op_Inequality\" };\n\t\t\tnames[(int)OperatorType.GreaterThan] = new string[] { \">\", \"op_GreaterThan\" };\n\t\t\tnames[(int)OperatorType.LessThan] = new string[] { \"<\", \"op_LessThan\" };\n\t\t\tnames[(int)OperatorType.GreaterThanOrEqual] = new string[] { \">=\", \"op_GreaterThanOrEqual\" };\n\t\t\tnames[(int)OperatorType.LessThanOrEqual] = new string[] { \"<=\", \"op_LessThanOrEqual\" };\n\t\t\tnames[(int)OperatorType.Implicit] = new string[] { \"implicit\", \"op_Implicit\" };\n\t\t\tnames[(int)OperatorType.Explicit] = new string[] { \"explicit\", \"op_Explicit\" };\n\t\t\tnames[(int)OperatorType.CheckedExplicit] = new string[] { \"explicit\", \"op_CheckedExplicit\" };\n\t\t}\n\n\t\tpublic override SymbolKind SymbolKind {\n\t\t\tget { return SymbolKind.Operator; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the type reference of the interface that is explicitly implemented.\n\t\t/// Null node if this member is not an explicit interface implementation.\n\t\t/// </summary>\n\t\tpublic AstType PrivateImplementationType {\n\t\t\tget { return GetChildByRole(PrivateImplementationTypeRole); }\n\t\t\tset { SetChildByRole(PrivateImplementationTypeRole, value); }\n\t\t}\n\n\t\tOperatorType operatorType;\n\n\t\tpublic OperatorType OperatorType {\n\t\t\tget { return operatorType; }\n\t\t\tset {\n\t\t\t\tThrowIfFrozen();\n\t\t\t\toperatorType = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode OperatorToken {\n\t\t\tget { return GetChildByRole(OperatorKeywordRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode OperatorTypeToken {\n\t\t\tget { return GetChildByRole(GetRole(OperatorType)); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstNodeCollection<ParameterDeclaration> Parameters {\n\t\t\tget { return GetChildrenByRole(Roles.Parameter); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic BlockStatement Body {\n\t\t\tget { return GetChildByRole(Roles.Body); }\n\t\t\tset { SetChildByRole(Roles.Body, value); }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the operator type from the method name, or null, if the method does not represent one of the known operator types.\n\t\t/// </summary>\n\t\tpublic static OperatorType? GetOperatorType(string methodName)\n\t\t{\n\t\t\tfor (int i = 0; i < names.Length; ++i)\n\t\t\t{\n\t\t\t\tif (names[i][1] == methodName)\n\t\t\t\t\treturn (OperatorType)i;\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static TokenRole GetRole(OperatorType type)\n\t\t{\n\t\t\tswitch (type)\n\t\t\t{\n\t\t\t\tcase OperatorType.LogicalNot:\n\t\t\t\t\treturn LogicalNotRole;\n\t\t\t\tcase OperatorType.OnesComplement:\n\t\t\t\t\treturn OnesComplementRole;\n\t\t\t\tcase OperatorType.Increment:\n\t\t\t\tcase OperatorType.CheckedIncrement:\n\t\t\t\t\treturn IncrementRole;\n\t\t\t\tcase OperatorType.Decrement:\n\t\t\t\tcase OperatorType.CheckedDecrement:\n\t\t\t\t\treturn DecrementRole;\n\t\t\t\tcase OperatorType.True:\n\t\t\t\t\treturn TrueRole;\n\t\t\t\tcase OperatorType.False:\n\t\t\t\t\treturn FalseRole;\n\n\t\t\t\tcase OperatorType.Addition:\n\t\t\t\tcase OperatorType.CheckedAddition:\n\t\t\t\tcase OperatorType.UnaryPlus:\n\t\t\t\t\treturn AdditionRole;\n\t\t\t\tcase OperatorType.Subtraction:\n\t\t\t\tcase OperatorType.CheckedSubtraction:\n\t\t\t\tcase OperatorType.UnaryNegation:\n\t\t\t\tcase OperatorType.CheckedUnaryNegation:\n\t\t\t\t\treturn SubtractionRole;\n\n\t\t\t\tcase OperatorType.Multiply:\n\t\t\t\tcase OperatorType.CheckedMultiply:\n\t\t\t\t\treturn MultiplyRole;\n\t\t\t\tcase OperatorType.Division:\n\t\t\t\tcase OperatorType.CheckedDivision:\n\t\t\t\t\treturn DivisionRole;\n\t\t\t\tcase OperatorType.Modulus:\n\t\t\t\t\treturn ModulusRole;\n\t\t\t\tcase OperatorType.BitwiseAnd:\n\t\t\t\t\treturn BitwiseAndRole;\n\t\t\t\tcase OperatorType.BitwiseOr:\n\t\t\t\t\treturn BitwiseOrRole;\n\t\t\t\tcase OperatorType.ExclusiveOr:\n\t\t\t\t\treturn ExclusiveOrRole;\n\t\t\t\tcase OperatorType.LeftShift:\n\t\t\t\t\treturn LeftShiftRole;\n\t\t\t\tcase OperatorType.RightShift:\n\t\t\t\t\treturn RightShiftRole;\n\t\t\t\tcase OperatorType.UnsignedRightShift:\n\t\t\t\t\treturn UnsignedRightShiftRole;\n\t\t\t\tcase OperatorType.Equality:\n\t\t\t\t\treturn EqualityRole;\n\t\t\t\tcase OperatorType.Inequality:\n\t\t\t\t\treturn InequalityRole;\n\t\t\t\tcase OperatorType.GreaterThan:\n\t\t\t\t\treturn GreaterThanRole;\n\t\t\t\tcase OperatorType.LessThan:\n\t\t\t\t\treturn LessThanRole;\n\t\t\t\tcase OperatorType.GreaterThanOrEqual:\n\t\t\t\t\treturn GreaterThanOrEqualRole;\n\t\t\t\tcase OperatorType.LessThanOrEqual:\n\t\t\t\t\treturn LessThanOrEqualRole;\n\n\t\t\t\tcase OperatorType.Implicit:\n\t\t\t\t\treturn ImplicitRole;\n\t\t\t\tcase OperatorType.Explicit:\n\t\t\t\tcase OperatorType.CheckedExplicit:\n\t\t\t\t\treturn ExplicitRole;\n\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new System.ArgumentOutOfRangeException();\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the method name for the operator type. (\"op_Addition\", \"op_Implicit\", etc.)\n\t\t/// </summary>\n\t\tpublic static string GetName(OperatorType? type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\treturn null;\n\t\t\treturn names[(int)type][1];\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the operator type is a C# 11 \"operator checked\".\n\t\t/// </summary>\n\t\tpublic static bool IsChecked(OperatorType type)\n\t\t{\n\t\t\treturn type switch {\n\t\t\t\tOperatorType.CheckedAddition => true,\n\t\t\t\tOperatorType.CheckedSubtraction => true,\n\t\t\t\tOperatorType.CheckedMultiply => true,\n\t\t\t\tOperatorType.CheckedDivision => true,\n\t\t\t\tOperatorType.CheckedUnaryNegation => true,\n\t\t\t\tOperatorType.CheckedIncrement => true,\n\t\t\t\tOperatorType.CheckedDecrement => true,\n\t\t\t\tOperatorType.CheckedExplicit => true,\n\t\t\t\t_ => false,\n\t\t\t};\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the token for the operator type (\"+\", \"implicit\", etc.).\n\t\t/// Does not include the \"checked\" modifier.\n\t\t/// </summary>\n\t\tpublic static string GetToken(OperatorType type)\n\t\t{\n\t\t\treturn names[(int)type][0];\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitOperatorDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitOperatorDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitOperatorDeclaration(this, data);\n\t\t}\n\n\t\tpublic override string Name {\n\t\t\tget { return GetName(this.OperatorType); }\n\t\t\tset { throw new NotSupportedException(); }\n\t\t}\n\n\t\t[EditorBrowsable(EditorBrowsableState.Never)]\n\t\tpublic override Identifier NameToken {\n\t\t\tget { return Identifier.Null; }\n\t\t\tset { throw new NotSupportedException(); }\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tOperatorDeclaration o = other as OperatorDeclaration;\n\t\t\treturn o != null && this.MatchAttributesAndModifiers(o, match)\n\t\t\t\t&& this.PrivateImplementationType.DoMatch(o.PrivateImplementationType, match)\n\t\t\t\t&& this.OperatorType == o.OperatorType\n\t\t\t\t&& this.ReturnType.DoMatch(o.ReturnType, match)\n\t\t\t\t&& this.Parameters.DoMatch(o.Parameters, match) && this.Body.DoMatch(o.Body, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/ParameterDeclaration.cs",
    "content": "// \n// ParameterDeclarationExpression.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2010 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\n#nullable enable\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class ParameterDeclaration : AstNode\n\t{\n\t\tpublic static readonly Role<AttributeSection> AttributeRole = EntityDeclaration.AttributeRole;\n\t\tpublic static readonly TokenRole ThisModifierRole = new TokenRole(\"this\");\n\t\tpublic static readonly TokenRole ScopedRefRole = new TokenRole(\"scoped\");\n\t\tpublic static readonly TokenRole RefModifierRole = new TokenRole(\"ref\");\n\t\tpublic static readonly TokenRole ReadonlyModifierRole = ComposedType.ReadonlyRole;\n\t\tpublic static readonly TokenRole OutModifierRole = new TokenRole(\"out\");\n\t\tpublic static readonly TokenRole InModifierRole = new TokenRole(\"in\");\n\t\tpublic static readonly TokenRole ParamsModifierRole = new TokenRole(\"params\");\n\n\t\t#region PatternPlaceholder\n\t\tpublic static implicit operator ParameterDeclaration?(PatternMatching.Pattern pattern)\n\t\t{\n\t\t\treturn pattern != null ? new PatternPlaceholder(pattern) : null;\n\t\t}\n\n\t\tsealed class PatternPlaceholder : ParameterDeclaration, PatternMatching.INode\n\t\t{\n\t\t\treadonly PatternMatching.Pattern child;\n\n\t\t\tpublic PatternPlaceholder(PatternMatching.Pattern child)\n\t\t\t{\n\t\t\t\tthis.child = child;\n\t\t\t}\n\n\t\t\tpublic override NodeType NodeType {\n\t\t\t\tget { return NodeType.Pattern; }\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode? other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn child.DoMatch(other, match);\n\t\t\t}\n\n\t\t\tbool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)\n\t\t\t{\n\t\t\t\treturn child.DoMatchCollection(role, pos, match, backtrackingInfo);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic override NodeType NodeType => NodeType.Unknown;\n\n\t\tpublic AstNodeCollection<AttributeSection> Attributes {\n\t\t\tget { return GetChildrenByRole(AttributeRole); }\n\t\t}\n\n\t\tbool hasThisModifier;\n\t\tbool isParams;\n\t\tbool isScopedRef;\n\n\t\tpublic CSharpTokenNode ThisKeyword {\n\t\t\tget {\n\t\t\t\tif (hasThisModifier)\n\t\t\t\t{\n\t\t\t\t\treturn GetChildByRole(ThisModifierRole);\n\t\t\t\t}\n\t\t\t\treturn CSharpTokenNode.Null;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool HasThisModifier {\n\t\t\tget { return hasThisModifier; }\n\t\t\tset {\n\t\t\t\tThrowIfFrozen();\n\t\t\t\thasThisModifier = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool IsParams {\n\t\t\tget { return isParams; }\n\t\t\tset {\n\t\t\t\tThrowIfFrozen();\n\t\t\t\tisParams = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool IsScopedRef {\n\t\t\tget { return isScopedRef; }\n\t\t\tset {\n\t\t\t\tThrowIfFrozen();\n\t\t\t\tisScopedRef = value;\n\t\t\t}\n\t\t}\n\n\t\tReferenceKind parameterModifier;\n\n\t\tpublic ReferenceKind ParameterModifier {\n\t\t\tget { return parameterModifier; }\n\t\t\tset {\n\t\t\t\tThrowIfFrozen();\n\t\t\t\tparameterModifier = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic AstType Type {\n\t\t\tget { return GetChildByRole(Roles.Type); }\n\t\t\tset { SetChildByRole(Roles.Type, value); }\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier NameToken {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, value);\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode AssignToken {\n\t\t\tget { return GetChildByRole(Roles.Assign); }\n\t\t}\n\n\t\tpublic Expression DefaultExpression {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitParameterDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitParameterDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitParameterDeclaration(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode? other, PatternMatching.Match match)\n\t\t{\n\t\t\tvar o = other as ParameterDeclaration;\n\t\t\treturn o != null && this.Attributes.DoMatch(o.Attributes, match) && this.ParameterModifier == o.ParameterModifier\n\t\t\t\t&& this.Type.DoMatch(o.Type, match) && MatchString(this.Name, o.Name)\n\t\t\t\t&& this.DefaultExpression.DoMatch(o.DefaultExpression, match);\n\t\t}\n\n\t\tpublic ParameterDeclaration()\n\t\t{\n\t\t}\n\n\t\tpublic new ParameterDeclaration Clone()\n\t\t{\n\t\t\treturn (ParameterDeclaration)base.Clone();\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/PropertyDeclaration.cs",
    "content": "// \n// PropertyDeclaration.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class PropertyDeclaration : EntityDeclaration\n\t{\n\t\tpublic static readonly TokenRole GetKeywordRole = new TokenRole(\"get\");\n\t\tpublic static readonly TokenRole SetKeywordRole = new TokenRole(\"set\");\n\t\tpublic static readonly TokenRole InitKeywordRole = new TokenRole(\"init\");\n\t\tpublic static readonly Role<Accessor> GetterRole = new Role<Accessor>(\"Getter\", Accessor.Null);\n\t\tpublic static readonly Role<Accessor> SetterRole = new Role<Accessor>(\"Setter\", Accessor.Null);\n\t\tpublic static readonly Role<Expression> ExpressionBodyRole = new Role<Expression>(\"ExpressionBody\", Expression.Null);\n\n\t\tpublic override SymbolKind SymbolKind {\n\t\t\tget { return SymbolKind.Property; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the type reference of the interface that is explicitly implemented.\n\t\t/// Null node if this member is not an explicit interface implementation.\n\t\t/// </summary>\n\t\tpublic AstType PrivateImplementationType {\n\t\t\tget { return GetChildByRole(PrivateImplementationTypeRole); }\n\t\t\tset { SetChildByRole(PrivateImplementationTypeRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode LBraceToken {\n\t\t\tget { return GetChildByRole(Roles.LBrace); }\n\t\t}\n\n\t\tpublic Accessor Getter {\n\t\t\tget { return GetChildByRole(GetterRole); }\n\t\t\tset { SetChildByRole(GetterRole, value); }\n\t\t}\n\n\t\tpublic Accessor Setter {\n\t\t\tget { return GetChildByRole(SetterRole); }\n\t\t\tset { SetChildByRole(SetterRole, value); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RBraceToken {\n\t\t\tget { return GetChildByRole(Roles.RBrace); }\n\t\t}\n\n\t\tpublic CSharpTokenNode AssignToken {\n\t\t\tget { return GetChildByRole(Roles.Assign); }\n\t\t}\n\n\t\tpublic Expression Initializer {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic Expression ExpressionBody {\n\t\t\tget { return GetChildByRole(ExpressionBodyRole); }\n\t\t\tset { SetChildByRole(ExpressionBodyRole, value); }\n\t\t}\n\n\t\tpublic bool IsAutomaticProperty {\n\t\t\tget {\n\t\t\t\tif (!Getter.IsNull && !Getter.Body.IsNull)\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (!Setter.IsNull && !Setter.Body.IsNull)\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitPropertyDeclaration(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitPropertyDeclaration(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitPropertyDeclaration(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tPropertyDeclaration o = other as PropertyDeclaration;\n\t\t\treturn o != null && MatchString(this.Name, o.Name)\n\t\t\t\t&& this.MatchAttributesAndModifiers(o, match) && this.ReturnType.DoMatch(o.ReturnType, match)\n\t\t\t\t&& this.PrivateImplementationType.DoMatch(o.PrivateImplementationType, match)\n\t\t\t\t&& this.Getter.DoMatch(o.Getter, match) && this.Setter.DoMatch(o.Setter, match)\n\t\t\t\t&& this.Initializer.DoMatch(o.Initializer, match)\n\t\t\t\t&& this.ExpressionBody.DoMatch(o.ExpressionBody, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/VariableInitializer.cs",
    "content": "// \n// VariableInitializer.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@novell.com>\n// \n// Copyright (c) 2009 Novell, Inc (http://www.novell.com)\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic class VariableInitializer : AstNode\n\t{\n\t\t#region Null\n\t\tpublic new static readonly VariableInitializer Null = new NullVariableInitializer();\n\n\t\tsealed class NullVariableInitializer : VariableInitializer\n\t\t{\n\t\t\tpublic override bool IsNull {\n\t\t\t\tget {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn other == null || other.IsNull;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region PatternPlaceholder\n\t\tpublic static implicit operator VariableInitializer(PatternMatching.Pattern pattern)\n\t\t{\n\t\t\treturn pattern != null ? new PatternPlaceholder(pattern) : null;\n\t\t}\n\n\t\tsealed class PatternPlaceholder : VariableInitializer, PatternMatching.INode\n\t\t{\n\t\t\treadonly PatternMatching.Pattern child;\n\n\t\t\tpublic PatternPlaceholder(PatternMatching.Pattern child)\n\t\t\t{\n\t\t\t\tthis.child = child;\n\t\t\t}\n\n\t\t\tpublic override NodeType NodeType {\n\t\t\t\tget { return NodeType.Pattern; }\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitPatternPlaceholder(this, child, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn child.DoMatch(other, match);\n\t\t\t}\n\n\t\t\tbool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)\n\t\t\t{\n\t\t\t\treturn child.DoMatchCollection(role, pos, match, backtrackingInfo);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic override NodeType NodeType {\n\t\t\tget {\n\t\t\t\treturn NodeType.Unknown;\n\t\t\t}\n\t\t}\n\n\t\tpublic VariableInitializer()\n\t\t{\n\t\t}\n\n\t\tpublic VariableInitializer(string name, Expression initializer = null)\n\t\t{\n\t\t\tthis.Name = name;\n\t\t\tthis.Initializer = initializer;\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier).Name;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, Identifier.Create(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic Identifier NameToken {\n\t\t\tget {\n\t\t\t\treturn GetChildByRole(Roles.Identifier);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSetChildByRole(Roles.Identifier, value);\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharpTokenNode AssignToken {\n\t\t\tget { return GetChildByRole(Roles.Assign); }\n\t\t}\n\n\t\tpublic Expression Initializer {\n\t\t\tget { return GetChildByRole(Roles.Expression); }\n\t\t\tset { SetChildByRole(Roles.Expression, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitVariableInitializer(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitVariableInitializer(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitVariableInitializer(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t{\n\t\t\tVariableInitializer o = other as VariableInitializer;\n\t\t\treturn o != null && MatchString(this.Name, o.Name) && this.Initializer.DoMatch(o.Initializer, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\n\nusing ICSharpCode.Decompiler.CSharp.Resolver;\nusing ICSharpCode.Decompiler.CSharp.TypeSystem;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\t/// <summary>\n\t/// Converts from type system to the C# AST.\n\t/// </summary>\n\tpublic class TypeSystemAstBuilder\n\t{\n\t\treadonly CSharpResolver resolver;\n\n\t\t#region Constructor\n\t\t/// <summary>\n\t\t/// Creates a new TypeSystemAstBuilder.\n\t\t/// </summary>\n\t\t/// <param name=\"resolver\">\n\t\t/// A resolver initialized for the position where the type will be inserted.\n\t\t/// </param>\n\t\tpublic TypeSystemAstBuilder(CSharpResolver resolver)\n\t\t{\n\t\t\tif (resolver == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(resolver));\n\t\t\tthis.resolver = resolver;\n\t\t\tInitProperties();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a new TypeSystemAstBuilder.\n\t\t/// </summary>\n\t\tpublic TypeSystemAstBuilder()\n\t\t{\n\t\t\tInitProperties();\n\t\t}\n\t\t#endregion\n\n\t\t#region Properties\n\t\tvoid InitProperties()\n\t\t{\n\t\t\tthis.UseKeywordsForBuiltinTypes = true;\n\t\t\tthis.UseNullableSpecifierForValueTypes = true;\n\t\t\tthis.ShowAccessibility = true;\n\t\t\tthis.UsePrivateProtectedAccessibility = true;\n\t\t\tthis.ShowModifiers = true;\n\t\t\tthis.ShowBaseTypes = true;\n\t\t\tthis.ShowTypeParameters = true;\n\t\t\tthis.ShowTypeParameterConstraints = true;\n\t\t\tthis.ShowParameterNames = true;\n\t\t\tthis.ShowConstantValues = true;\n\t\t\tthis.UseAliases = true;\n\t\t\tthis.UseSpecialConstants = true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Specifies whether the ast builder should add annotations to type references.\n\t\t/// The default value is <see langword=\"false\" />.\n\t\t/// </summary>\n\t\tpublic bool AddTypeReferenceAnnotations { get; set; }\n\n\t\t/// <summary>\n\t\t/// Specifies whether the ast builder should add ResolveResult annotations to AST nodes.\n\t\t/// The default value is <see langword=\"false\" />.\n\t\t/// </summary>\n\t\tpublic bool AddResolveResultAnnotations { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether accessibility modifiers are shown.\n\t\t/// The default value is <see langword=\"true\" />.\n\t\t/// </summary>\n\t\tpublic bool ShowAccessibility { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether \"private protected\" accessibility modifiers are shown.\n\t\t/// The default value is <see langword=\"true\" />.\n\t\t/// </summary>\n\t\tpublic bool UsePrivateProtectedAccessibility { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether non-accessibility modifiers are shown.\n\t\t/// The default value is <see langword=\"true\" />.\n\t\t/// </summary>\n\t\tpublic bool ShowModifiers { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether base type references are shown.\n\t\t/// The default value is <see langword=\"true\" />.\n\t\t/// </summary>\n\t\tpublic bool ShowBaseTypes { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether type parameter declarations are shown.\n\t\t/// The default value is <see langword=\"true\" />.\n\t\t/// </summary>\n\t\tpublic bool ShowTypeParameters { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether type parameter names are shown for unbound types.\n\t\t/// The default value is <see langword=\"false\" />.\n\t\t/// </summary>\n\t\tpublic bool ShowTypeParametersForUnboundTypes { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether constraints on type parameter declarations are shown.\n\t\t/// Has no effect if ShowTypeParameters is false.\n\t\t/// The default value is <see langword=\"true\" />.\n\t\t/// </summary>\n\t\tpublic bool ShowTypeParameterConstraints { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether the names of parameters are shown.\n\t\t/// The default value is <see langword=\"true\" />.\n\t\t/// </summary>\n\t\tpublic bool ShowParameterNames { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether to show default values of optional parameters, and the values of constant fields.\n\t\t/// The default value is <see langword=\"true\" />.\n\t\t/// </summary>\n\t\tpublic bool ShowConstantValues { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether to show attributes.\n\t\t/// The default value is <see langword=\"false\" />.\n\t\t/// </summary>\n\t\tpublic bool ShowAttributes { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether to sort attributes, if set to <see langword=\"false\" /> attributes are shown in metadata order.\n\t\t/// The default value is <see langword=\"false\" />.\n\t\t/// </summary>\n\t\tpublic bool SortAttributes { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether to use fully-qualified type names or short type names.\n\t\t/// The default value is <see langword=\"false\" />.\n\t\t/// </summary>\n\t\tpublic bool AlwaysUseShortTypeNames { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether to use keywords for builtin types.\n\t\t/// The default value is <see langword=\"true\" />.\n\t\t/// </summary>\n\t\tpublic bool UseKeywordsForBuiltinTypes { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether to use <c>T?</c> or <c>Nullable&lt;T&gt;</c> for nullable value types.\n\t\t/// The default value is <see langword=\"true\" />.\n\t\t/// </summary>\n\t\tpublic bool UseNullableSpecifierForValueTypes { get; set; }\n\n\t\t/// <summary>\n\t\t/// Determines the name lookup mode for converting a type name.\n\t\t/// \n\t\t/// The default value is <c>NameLookupMode.Expression</c>, which means the name is disambiguated\n\t\t/// for use in expression context.\n\t\t/// </summary>\n\t\tpublic NameLookupMode NameLookupMode { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether to generate a body that throws a <c>System.NotImplementedException</c>.\n\t\t/// The default value is <see langword=\"false\" />.\n\t\t/// </summary>\n\t\tpublic bool GenerateBody { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether to generate custom events.\n\t\t/// The default value is <see langword=\"false\" />.\n\t\t/// </summary>\n\t\tpublic bool UseCustomEvents { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether unbound type argument names are inserted in the ast or not.\n\t\t/// The default value is <see langword=\"false\" />.\n\t\t/// </summary>\n\t\tpublic bool ConvertUnboundTypeArguments { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether aliases should be used inside the type name or not.\n\t\t/// The default value is <see langword=\"true\" />.\n\t\t/// </summary>\n\t\tpublic bool UseAliases { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether constants like <c>int.MaxValue</c> are converted to a <see cref=\"MemberReferenceExpression\"/> or <see cref=\"PrimitiveExpression\" />.\n\t\t/// The default value is <see langword=\"true\" />.\n\t\t/// </summary>\n\t\tpublic bool UseSpecialConstants { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether integral constants should be printed in hexadecimal format.\n\t\t/// The default value is <see langword=\"false\" />.\n\t\t/// </summary>\n\t\tpublic bool PrintIntegralValuesAsHex { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether C# 9 \"init;\" accessors are supported.\n\t\t/// If disabled, emits \"set /*init*/;\" instead.\n\t\t/// </summary>\n\t\tpublic bool SupportInitAccessors { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether C# 9 \"record\" class types are supported.\n\t\t/// </summary>\n\t\tpublic bool SupportRecordClasses { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether C# 10 \"record\" struct types are supported.\n\t\t/// </summary>\n\t\tpublic bool SupportRecordStructs { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether C# 11 \"operator >>>\" is supported.\n\t\t/// </summary>\n\t\tpublic bool SupportUnsignedRightShift { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether C# 11 \"operator checked\" is supported.\n\t\t/// </summary>\n\t\tpublic bool SupportOperatorChecked { get; set; }\n\n\t\t/// <summary>\n\t\t/// Controls whether all fully qualified type names should be prefixed with \"global::\".\n\t\t/// </summary>\n\t\tpublic bool AlwaysUseGlobal { get; set; }\n\t\t#endregion\n\n\t\t#region Convert Type\n\t\tpublic AstType ConvertType(IType type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tAstType astType = ConvertTypeHelper(type);\n\t\t\tAddTypeAnnotation(astType, type);\n\t\t\treturn astType;\n\t\t}\n\n\t\tprivate void AddTypeAnnotation(AstType astType, IType type)\n\t\t{\n\t\t\tif (AddResolveResultAnnotations)\n\t\t\t\tastType.AddAnnotation(new TypeResolveResult(type));\n\t\t}\n\n\t\tpublic AstType ConvertType(FullTypeName fullTypeName)\n\t\t{\n\t\t\tif (resolver != null)\n\t\t\t{\n\t\t\t\tforeach (var asm in resolver.Compilation.Modules)\n\t\t\t\t{\n\t\t\t\t\tvar def = asm.GetTypeDefinition(fullTypeName);\n\t\t\t\t\tif (def != null)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn ConvertType(def);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tTopLevelTypeName top = fullTypeName.TopLevelTypeName;\n\t\t\tAstType type;\n\t\t\tif (string.IsNullOrEmpty(top.Namespace))\n\t\t\t{\n\t\t\t\ttype = MakeSimpleType(top.Name);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttype = MakeMemberType(MakeSimpleType(top.Namespace), top.Name);\n\t\t\t}\n\t\t\tfor (int i = 0; i < fullTypeName.NestingLevel; i++)\n\t\t\t{\n\t\t\t\ttype = MakeMemberType(type, fullTypeName.GetNestedTypeName(i));\n\t\t\t}\n\t\t\treturn type;\n\t\t}\n\n\t\tAstType ConvertTypeHelper(IType type)\n\t\t{\n\t\t\tif (type is TypeWithElementType typeWithElementType)\n\t\t\t{\n\t\t\t\tif (typeWithElementType is PointerType)\n\t\t\t\t{\n\t\t\t\t\treturn ConvertType(typeWithElementType.ElementType).MakePointerType();\n\t\t\t\t}\n\t\t\t\telse if (typeWithElementType is ArrayType)\n\t\t\t\t{\n\t\t\t\t\tvar astType = ConvertType(typeWithElementType.ElementType).MakeArrayType(((ArrayType)type).Dimensions);\n\t\t\t\t\tif (type.Nullability == Nullability.Nullable)\n\t\t\t\t\t\treturn astType.MakeNullableType();\n\t\t\t\t\telse\n\t\t\t\t\t\treturn astType;\n\t\t\t\t}\n\t\t\t\telse if (typeWithElementType is ByReferenceType)\n\t\t\t\t{\n\t\t\t\t\treturn ConvertType(typeWithElementType.ElementType).MakeRefType();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// not supported as type in C#\n\t\t\t\t\treturn ConvertType(typeWithElementType.ElementType);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (type is NullabilityAnnotatedType nat)\n\t\t\t{\n\t\t\t\tvar astType = ConvertType(nat.TypeWithoutAnnotation);\n\t\t\t\tif (nat.Nullability == Nullability.Nullable)\n\t\t\t\t\tastType = astType.MakeNullableType();\n\t\t\t\treturn astType;\n\t\t\t}\n\t\t\telse if (type is TupleType tuple)\n\t\t\t{\n\t\t\t\tvar astType = new TupleAstType();\n\t\t\t\tforeach (var (etype, ename) in tuple.ElementTypes.Zip(tuple.ElementNames))\n\t\t\t\t{\n\t\t\t\t\tastType.Elements.Add(new TupleTypeElement {\n\t\t\t\t\t\tType = ConvertType(etype),\n\t\t\t\t\t\tName = ename\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn astType;\n\t\t\t}\n\t\t\telse if (type is FunctionPointerType fpt)\n\t\t\t{\n\t\t\t\tvar astType = new FunctionPointerAstType();\n\t\t\t\tif (fpt.CallingConvention == System.Reflection.Metadata.SignatureCallingConvention.Unmanaged)\n\t\t\t\t{\n\t\t\t\t\tastType.HasUnmanagedCallingConvention = true;\n\t\t\t\t}\n\t\t\t\telse if (fpt.CallingConvention != System.Reflection.Metadata.SignatureCallingConvention.Default)\n\t\t\t\t{\n\t\t\t\t\tstring callconvName = fpt.CallingConvention switch {\n\t\t\t\t\t\tSystem.Reflection.Metadata.SignatureCallingConvention.CDecl => \"Cdecl\",\n\t\t\t\t\t\tSystem.Reflection.Metadata.SignatureCallingConvention.StdCall => \"Stdcall\",\n\t\t\t\t\t\tSystem.Reflection.Metadata.SignatureCallingConvention.ThisCall => \"Thiscall\",\n\t\t\t\t\t\tSystem.Reflection.Metadata.SignatureCallingConvention.FastCall => \"Fastcall\",\n\t\t\t\t\t\tSystem.Reflection.Metadata.SignatureCallingConvention.VarArgs => \"Varargs\",\n\t\t\t\t\t\t_ => fpt.CallingConvention.ToString()\n\t\t\t\t\t};\n\t\t\t\t\tastType.HasUnmanagedCallingConvention = true;\n\t\t\t\t\tastType.CallingConventions.Add(new PrimitiveType(callconvName));\n\t\t\t\t}\n\t\t\t\tforeach (var customCallConv in fpt.CustomCallingConventions)\n\t\t\t\t{\n\t\t\t\t\tAstType callConvSyntax;\n\t\t\t\t\tif (customCallConv.Namespace == \"System.Runtime.CompilerServices\" && customCallConv.Name.StartsWith(\"CallConv\", StringComparison.Ordinal) && customCallConv.Name.Length > 8)\n\t\t\t\t\t{\n\t\t\t\t\t\tcallConvSyntax = new PrimitiveType(customCallConv.Name.Substring(8));\n\t\t\t\t\t\tif (AddResolveResultAnnotations)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcallConvSyntax.AddAnnotation(new TypeResolveResult(customCallConv));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tcallConvSyntax = ConvertType(customCallConv);\n\t\t\t\t\t}\n\t\t\t\t\tastType.CallingConventions.Add(callConvSyntax);\n\t\t\t\t}\n\t\t\t\tfor (int i = 0; i < fpt.ParameterTypes.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tvar paramDecl = new ParameterDeclaration();\n\t\t\t\t\tparamDecl.ParameterModifier = fpt.ParameterReferenceKinds[i];\n\t\t\t\t\tIType parameterType = fpt.ParameterTypes[i];\n\t\t\t\t\tif (paramDecl.ParameterModifier != ReferenceKind.None && parameterType is ByReferenceType brt)\n\t\t\t\t\t{\n\t\t\t\t\t\tparamDecl.Type = ConvertType(brt.ElementType);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tparamDecl.Type = ConvertType(parameterType);\n\t\t\t\t\t}\n\t\t\t\t\tastType.Parameters.Add(paramDecl);\n\t\t\t\t}\n\t\t\t\tastType.ReturnType = ConvertType(fpt.ReturnType);\n\t\t\t\tif (fpt.ReturnIsRefReadOnly && astType.ReturnType is ComposedType ct && ct.HasRefSpecifier)\n\t\t\t\t{\n\t\t\t\t\tct.HasReadOnlySpecifier = true;\n\t\t\t\t}\n\t\t\t\tITypeDefinition treatedAs = fpt.GetDefinition();\n\t\t\t\tif (treatedAs != null)\n\t\t\t\t{\n\t\t\t\t\tvar result = ConvertTypeHelper(treatedAs);\n\t\t\t\t\tresult.AddChild(new Comment(astType.ToString(), CommentType.MultiLine), Roles.Comment);\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn astType;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tAstType astType;\n\t\t\t\tswitch (type)\n\t\t\t\t{\n\t\t\t\t\tcase ITypeDefinition _:\n\t\t\t\t\tcase UnknownType _:\n\t\t\t\t\t\tif (type.IsUnbound())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (ShowTypeParametersForUnboundTypes)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tastType = ConvertTypeHelper(type, type.TypeArguments);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tIType[] typeArguments = new IType[type.TypeParameterCount];\n\t\t\t\t\t\t\t\tfor (int i = 0; i < typeArguments.Length; i++)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttypeArguments[i] = SpecialType.UnboundTypeArgument;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tastType = ConvertTypeHelper(type, typeArguments);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tastType = ConvertTypeHelper(type, EmptyList<IType>.Instance);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase ParameterizedType pt:\n\t\t\t\t\t\tif (UseNullableSpecifierForValueTypes && pt.IsKnownType(KnownTypeCode.NullableOfT))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn ConvertType(pt.TypeArguments[0]).MakeNullableType();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tastType = ConvertTypeHelper(pt.GenericType, pt.TypeArguments);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tswitch (type.Kind)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeKind.Dynamic:\n\t\t\t\t\t\t\tcase TypeKind.NInt:\n\t\t\t\t\t\t\tcase TypeKind.NUInt:\n\t\t\t\t\t\t\t\tastType = new PrimitiveType(type.Name);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tastType = MakeSimpleType(type.Name);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (type.Nullability == Nullability.Nullable)\n\t\t\t\t{\n\t\t\t\t\tAddTypeAnnotation(astType, type.ChangeNullability(Nullability.Oblivious));\n\t\t\t\t\tastType = astType.MakeNullableType();\n\t\t\t\t}\n\t\t\t\treturn astType;\n\t\t\t}\n\t\t}\n\n\t\tAstType ConvertTypeHelper(IType genericType, IReadOnlyList<IType> typeArguments)\n\t\t{\n\t\t\tITypeDefinition typeDef = genericType.GetDefinition();\n\t\t\tDebug.Assert(typeDef != null || genericType.Kind == TypeKind.Unknown);\n\t\t\tDebug.Assert(typeArguments.Count >= genericType.TypeParameterCount);\n\n\t\t\tif (UseKeywordsForBuiltinTypes && typeDef != null)\n\t\t\t{\n\t\t\t\tstring keyword = KnownTypeReference.GetCSharpNameByTypeCode(typeDef.KnownTypeCode);\n\t\t\t\tif (keyword != null)\n\t\t\t\t{\n\t\t\t\t\treturn new PrimitiveType(keyword);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// The number of type parameters belonging to outer classes\n\t\t\tint outerTypeParameterCount = genericType.DeclaringType?.TypeParameterCount ?? 0;\n\n\t\t\tif (resolver != null && typeDef != null)\n\t\t\t{\n\t\t\t\t// Look if there's an alias to the target type\n\t\t\t\tif (UseAliases)\n\t\t\t\t{\n\t\t\t\t\tfor (UsingScope usingScope = resolver.CurrentUsingScope; usingScope != null; usingScope = usingScope.Parent)\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var pair in usingScope.UsingAliases)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (pair.Value is TypeResolveResult)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (TypeMatches(pair.Value.Type, typeDef, typeArguments))\n\t\t\t\t\t\t\t\t\treturn MakeSimpleType(pair.Key);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tIType[] localTypeArguments;\n\t\t\t\tif (typeDef.TypeParameterCount > outerTypeParameterCount)\n\t\t\t\t{\n\t\t\t\t\tlocalTypeArguments = new IType[typeDef.TypeParameterCount - outerTypeParameterCount];\n\t\t\t\t\tfor (int i = 0; i < localTypeArguments.Length; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tlocalTypeArguments[i] = typeArguments[outerTypeParameterCount + i];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tlocalTypeArguments = Empty<IType>.Array;\n\t\t\t\t}\n\t\t\t\tResolveResult rr = resolver.LookupSimpleNameOrTypeName(typeDef.Name, localTypeArguments, NameLookupMode);\n\t\t\t\tTypeResolveResult trr = rr as TypeResolveResult;\n\t\t\t\tif (trr != null || (localTypeArguments.Length == 0 && resolver.IsVariableReferenceWithSameType(rr, typeDef.Name, out trr)))\n\t\t\t\t{\n\t\t\t\t\tif (!trr.IsError && TypeMatches(trr.Type, typeDef, typeArguments))\n\t\t\t\t\t{\n\t\t\t\t\t\t// We can use the short type name\n\t\t\t\t\t\tSimpleType shortResult = MakeSimpleType(typeDef.Name);\n\t\t\t\t\t\tAddTypeArguments(shortResult, typeDef.TypeParameters, typeArguments, outerTypeParameterCount, typeDef.TypeParameterCount);\n\t\t\t\t\t\treturn shortResult;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (AlwaysUseShortTypeNames || (typeDef == null && genericType.DeclaringType == null))\n\t\t\t{\n\t\t\t\tvar shortResult = MakeSimpleType(genericType.Name);\n\t\t\t\tAddTypeArguments(shortResult, genericType.TypeParameters, typeArguments, outerTypeParameterCount, genericType.TypeParameterCount);\n\t\t\t\treturn shortResult;\n\t\t\t}\n\t\t\tMemberType result = new MemberType();\n\t\t\tif (genericType.DeclaringType != null)\n\t\t\t{\n\t\t\t\t// Handle nested types\n\t\t\t\tresult.Target = ConvertTypeHelper(genericType.DeclaringType, typeArguments);\n\t\t\t\t// Use correct number of type arguments on the declaring type\n\t\t\t\tvar declaringType = genericType.DeclaringType;\n\t\t\t\tif (outerTypeParameterCount > 0)\n\t\t\t\t{\n\t\t\t\t\tdeclaringType = new ParameterizedType(genericType.DeclaringType, typeArguments.Take(outerTypeParameterCount));\n\t\t\t\t}\n\t\t\t\tAddTypeAnnotation(result.Target, declaringType);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Handle top-level types\n\t\t\t\tif (string.IsNullOrEmpty(genericType.Namespace))\n\t\t\t\t{\n\t\t\t\t\tresult.Target = MakeGlobal();\n\t\t\t\t\tresult.IsDoubleColon = true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tresult.Target = ConvertNamespace(genericType.Namespace,\n\t\t\t\t\t\tout _, AlwaysUseGlobal || genericType.Namespace == genericType.Name);\n\t\t\t\t}\n\t\t\t}\n\t\t\tresult.MemberName = genericType.Name;\n\t\t\tAddTypeArguments(result, genericType.TypeParameters, typeArguments, outerTypeParameterCount, genericType.TypeParameterCount);\n\t\t\treturn result;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether 'type' is the same as 'typeDef' parameterized with the given type arguments.\n\t\t/// </summary>\n\t\tbool TypeMatches(IType type, ITypeDefinition typeDef, IReadOnlyList<IType> typeArguments)\n\t\t{\n\t\t\tif (typeDef.TypeParameterCount == 0)\n\t\t\t{\n\t\t\t\treturn TypeDefMatches(typeDef, type);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (!TypeDefMatches(typeDef, type.GetDefinition()))\n\t\t\t\t\treturn false;\n\t\t\t\tParameterizedType pt = type as ParameterizedType;\n\t\t\t\tif (pt == null)\n\t\t\t\t{\n\t\t\t\t\treturn typeArguments.All(t => t.Kind == TypeKind.UnboundTypeArgument);\n\t\t\t\t}\n\t\t\t\tvar ta = pt.TypeArguments;\n\t\t\t\tfor (int i = 0; i < ta.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (!ta[i].Equals(typeArguments[i]))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tbool TypeDefMatches(ITypeDefinition typeDef, IType type)\n\t\t{\n\t\t\tif (type == null || type.Name != typeDef.Name || type.Namespace != typeDef.Namespace || type.TypeParameterCount != typeDef.TypeParameterCount)\n\t\t\t\treturn false;\n\t\t\tbool defIsNested = typeDef.DeclaringTypeDefinition != null;\n\t\t\tbool typeIsNested = type.DeclaringType != null;\n\t\t\tif (defIsNested && typeIsNested)\n\t\t\t\treturn TypeDefMatches(typeDef.DeclaringTypeDefinition, type.DeclaringType);\n\t\t\telse\n\t\t\t\treturn defIsNested == typeIsNested;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Adds type arguments to the result type.\n\t\t/// </summary>\n\t\t/// <param name=\"result\">The result AST node (a SimpleType or MemberType)</param>\n\t\t/// <param name=\"typeParameters\">The type parameters</param>\n\t\t/// <param name=\"typeArguments\">The list of type arguments</param>\n\t\t/// <param name=\"startIndex\">Index of first type argument to add</param>\n\t\t/// <param name=\"endIndex\">Index after last type argument to add</param>\n\t\tvoid AddTypeArguments(AstType result, IReadOnlyList<ITypeParameter> typeParameters, IReadOnlyList<IType> typeArguments, int startIndex, int endIndex)\n\t\t{\n\t\t\tDebug.Assert(endIndex <= typeParameters.Count);\n\t\t\tfor (int i = startIndex; i < endIndex; i++)\n\t\t\t{\n\t\t\t\tif (ConvertUnboundTypeArguments && typeArguments[i].Kind == TypeKind.UnboundTypeArgument)\n\t\t\t\t{\n\t\t\t\t\tresult.AddChild(MakeSimpleType(typeParameters[i].Name), Roles.TypeArgument);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tresult.AddChild(ConvertType(typeArguments[i]), Roles.TypeArgument);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic AstType ConvertNamespace(string namespaceName, out NamespaceResolveResult nrr)\n\t\t{\n\t\t\treturn ConvertNamespace(namespaceName, out nrr, requiresGlobalPrefix: false);\n\t\t}\n\n\t\tAstType ConvertNamespace(string namespaceName, out NamespaceResolveResult nrr, bool requiresGlobalPrefix)\n\t\t{\n\t\t\tif (resolver != null)\n\t\t\t{\n\t\t\t\t// Look if there's an alias to the target namespace\n\t\t\t\tif (UseAliases)\n\t\t\t\t{\n\t\t\t\t\tfor (UsingScope usingScope = resolver.CurrentUsingScope; usingScope != null; usingScope = usingScope.Parent)\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var pair in usingScope.UsingAliases)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnrr = pair.Value as NamespaceResolveResult;\n\t\t\t\t\t\t\tif (nrr != null && nrr.NamespaceName == namespaceName)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvar ns = MakeSimpleType(pair.Key);\n\t\t\t\t\t\t\t\tif (AddResolveResultAnnotations)\n\t\t\t\t\t\t\t\t\tns.AddAnnotation(nrr);\n\t\t\t\t\t\t\t\treturn ns;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tint pos = namespaceName.LastIndexOf('.');\n\t\t\tif (pos < 0)\n\t\t\t{\n\t\t\t\tif (IsValidNamespace(namespaceName, out nrr))\n\t\t\t\t{\n\t\t\t\t\tAstType ns;\n\t\t\t\t\tif (requiresGlobalPrefix)\n\t\t\t\t\t{\n\t\t\t\t\t\tns = new MemberType {\n\t\t\t\t\t\t\tTarget = MakeGlobal(),\n\t\t\t\t\t\t\tIsDoubleColon = true,\n\t\t\t\t\t\t\tMemberName = namespaceName\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tns = MakeSimpleType(namespaceName);\n\t\t\t\t\t}\n\t\t\t\t\tif (AddResolveResultAnnotations && nrr != null)\n\t\t\t\t\t\tns.AddAnnotation(nrr);\n\t\t\t\t\treturn ns;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar ns = new MemberType {\n\t\t\t\t\t\tTarget = MakeGlobal(),\n\t\t\t\t\t\tIsDoubleColon = true,\n\t\t\t\t\t\tMemberName = namespaceName\n\t\t\t\t\t};\n\t\t\t\t\tif (AddResolveResultAnnotations)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar @namespace = resolver.Compilation.RootNamespace.GetChildNamespace(namespaceName);\n\t\t\t\t\t\tif (@namespace != null)\n\t\t\t\t\t\t\tns.AddAnnotation(nrr = new NamespaceResolveResult(@namespace));\n\t\t\t\t\t}\n\t\t\t\t\treturn ns;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tstring parentNamespace = namespaceName.Substring(0, pos);\n\t\t\t\tstring localNamespace = namespaceName.Substring(pos + 1);\n\t\t\t\tvar parentNS = ConvertNamespace(parentNamespace, out var parentNRR, requiresGlobalPrefix);\n\t\t\t\tvar ns = new MemberType {\n\t\t\t\t\tTarget = parentNS,\n\t\t\t\t\tMemberName = localNamespace\n\t\t\t\t};\n\t\t\t\tnrr = null;\n\t\t\t\tif (AddResolveResultAnnotations && parentNRR != null)\n\t\t\t\t{\n\t\t\t\t\tvar newNamespace = parentNRR.Namespace.GetChildNamespace(localNamespace);\n\t\t\t\t\tif (newNamespace != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tns.AddAnnotation(nrr = new NamespaceResolveResult(newNamespace));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn ns;\n\t\t\t}\n\t\t}\n\n\t\tbool IsValidNamespace(string firstNamespacePart, out NamespaceResolveResult nrr)\n\t\t{\n\t\t\tnrr = null;\n\t\t\tif (resolver == null)\n\t\t\t\treturn true; // just assume namespaces are valid if we don't have a resolver\n\t\t\tnrr = resolver.ResolveSimpleName(firstNamespacePart, EmptyList<IType>.Instance) as NamespaceResolveResult;\n\t\t\treturn nrr != null && !nrr.IsError && nrr.NamespaceName == firstNamespacePart;\n\t\t}\n\n\t\tstatic SimpleType MakeSimpleType(string name)\n\t\t{\n\t\t\tif (name == \"_\")\n\t\t\t\treturn new SimpleType(\"@_\");\n\t\t\treturn new SimpleType(name);\n\t\t}\n\n\t\tSimpleType MakeGlobal()\n\t\t{\n\t\t\tvar global = new SimpleType(\"global\");\n\t\t\tif (AddResolveResultAnnotations && resolver != null)\n\t\t\t\tglobal.AddAnnotation(new NamespaceResolveResult(resolver.Compilation.RootNamespace));\n\t\t\treturn global;\n\t\t}\n\n\t\tstatic MemberType MakeMemberType(AstType target, string name)\n\t\t{\n\t\t\tif (name == \"_\")\n\t\t\t\treturn new MemberType(target, \"@_\");\n\t\t\treturn new MemberType(target, name);\n\t\t}\n\t\t#endregion\n\n\t\t#region Convert Attribute\n\t\tpublic Attribute ConvertAttribute(IAttribute attribute)\n\t\t{\n\t\t\tAttribute attr = new Attribute();\n\t\t\tattr.Type = ConvertAttributeType(attribute.AttributeType);\n\t\t\tswitch (attr.Type)\n\t\t\t{\n\t\t\t\tcase SimpleType st:\n\t\t\t\t\tif (st.Identifier.EndsWith(\"Attribute\", StringComparison.Ordinal))\n\t\t\t\t\t\tst.Identifier = st.Identifier.Substring(0, st.Identifier.Length - 9);\n\t\t\t\t\tbreak;\n\t\t\t\tcase MemberType mt:\n\t\t\t\t\tif (mt.MemberName.EndsWith(\"Attribute\", StringComparison.Ordinal))\n\t\t\t\t\t\tmt.MemberName = mt.MemberName.Substring(0, mt.MemberName.Length - 9);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (AddResolveResultAnnotations && attribute.Constructor != null)\n\t\t\t{\n\t\t\t\tattr.AddAnnotation(new MemberResolveResult(null, attribute.Constructor));\n\t\t\t}\n\t\t\tvar parameters = attribute.Constructor?.Parameters ?? EmptyList<IParameter>.Instance;\n\t\t\tfor (int i = 0; i < attribute.FixedArguments.Length; i++)\n\t\t\t{\n\t\t\t\tvar arg = attribute.FixedArguments[i];\n\t\t\t\tvar p = (i < parameters.Count) ? parameters[i] : null;\n\t\t\t\tattr.Arguments.Add(ConvertConstantValue(p?.Type ?? arg.Type, arg.Type, arg.Value));\n\t\t\t}\n\t\t\tif (attribute.NamedArguments.Length > 0)\n\t\t\t{\n\t\t\t\tInitializedObjectResolveResult targetResult = new InitializedObjectResolveResult(attribute.AttributeType);\n\t\t\t\tforeach (var namedArg in attribute.NamedArguments)\n\t\t\t\t{\n\t\t\t\t\tNamedExpression namedArgument = new NamedExpression(namedArg.Name, ConvertConstantValue(namedArg.Type, namedArg.Value));\n\t\t\t\t\tif (AddResolveResultAnnotations)\n\t\t\t\t\t{\n\t\t\t\t\t\tIMember member = CustomAttribute.MemberForNamedArgument(attribute.AttributeType, namedArg);\n\t\t\t\t\t\tif (member != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnamedArgument.AddAnnotation(new MemberResolveResult(targetResult, member));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tattr.Arguments.Add(namedArgument);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (attribute.HasDecodeErrors)\n\t\t\t{\n\t\t\t\tattr.HasArgumentList = true;\n\t\t\t\tattr.AddChild(new Comment(\"Could not decode attribute arguments.\", CommentType.MultiLine), Roles.Comment);\n\t\t\t\t// insert explicit rpar token to make the comment appear within the parentheses\n\t\t\t\tattr.AddChild(new CSharpTokenNode(TextLocation.Empty, Roles.RPar), Roles.RPar);\n\t\t\t}\n\t\t\treturn attr;\n\t\t}\n\n\t\tprivate IEnumerable<AttributeSection> ConvertAttributes(IEnumerable<IAttribute> attributes, string target = null)\n\t\t{\n\t\t\tif (SortAttributes)\n\t\t\t\tattributes = attributes.OrderBy(a => a, new DelegateComparer<IAttribute>(CompareAttribute));\n\t\t\treturn attributes.Select(a => {\n\t\t\t\tvar section = new AttributeSection(ConvertAttribute(a));\n\t\t\t\tif (target != null)\n\t\t\t\t\tsection.AttributeTarget = target;\n\t\t\t\treturn section;\n\t\t\t});\n\n\t\t\tstatic int CompareAttribute(IAttribute a, IAttribute b)\n\t\t\t{\n\t\t\t\tint result = CompareType(a.AttributeType, b.AttributeType);\n\t\t\t\tif (result != 0)\n\t\t\t\t\treturn result;\n\t\t\t\tif (a.HasDecodeErrors && b.HasDecodeErrors)\n\t\t\t\t\treturn 0;\n\t\t\t\tif (a.HasDecodeErrors)\n\t\t\t\t\treturn -1;\n\t\t\t\tif (b.HasDecodeErrors)\n\t\t\t\t\treturn 1;\n\t\t\t\tresult = a.FixedArguments.Length - b.FixedArguments.Length;\n\t\t\t\tif (result != 0)\n\t\t\t\t\treturn result;\n\t\t\t\tfor (int i = 0; i < a.FixedArguments.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tvar argA = a.FixedArguments[i];\n\t\t\t\t\tvar argB = b.FixedArguments[i];\n\t\t\t\t\tresult = CompareType(argA.Type, argB.Type);\n\t\t\t\t\tif (result != 0)\n\t\t\t\t\t\treturn result;\n\t\t\t\t\tif (argA.Value is IComparable compA && argB.Value is IComparable compB)\n\t\t\t\t\t\tresult = compA.CompareTo(compB);\n\t\t\t\t\telse\n\t\t\t\t\t\tresult = 0;\n\t\t\t\t\tif (result != 0)\n\t\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t\tresult = a.NamedArguments.Length - b.NamedArguments.Length;\n\t\t\t\tif (result != 0)\n\t\t\t\t\treturn result;\n\t\t\t\tfor (int i = 0; i < a.NamedArguments.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tvar argA = a.NamedArguments[i];\n\t\t\t\t\tvar argB = b.NamedArguments[i];\n\t\t\t\t\tresult = argA.Name.CompareTo(argB.Name);\n\t\t\t\t\tif (result != 0)\n\t\t\t\t\t\treturn result;\n\t\t\t\t\tresult = CompareType(argA.Type, argB.Type);\n\t\t\t\t\tif (result != 0)\n\t\t\t\t\t\treturn result;\n\t\t\t\t\tif (argA.Value is IComparable compA && argB.Value is IComparable compB)\n\t\t\t\t\t\tresult = compA.CompareTo(compB);\n\t\t\t\t\telse\n\t\t\t\t\t\tresult = 0;\n\t\t\t\t\tif (result != 0)\n\t\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tstatic int CompareType(IType a, IType b)\n\t\t\t{\n\t\t\t\treturn a.FullName.CompareTo(b.FullName);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Convert Attribute Type\n\t\tpublic AstType ConvertAttributeType(IType type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tAstType astType = ConvertTypeHelper(type);\n\n\t\t\tstring shortName = null;\n\t\t\tif (type.Name.Length > 9 && type.Name.EndsWith(\"Attribute\", StringComparison.Ordinal))\n\t\t\t{\n\t\t\t\tshortName = type.Name.Remove(type.Name.Length - 9);\n\t\t\t}\n\t\t\tif (AlwaysUseShortTypeNames)\n\t\t\t{\n\t\t\t\tswitch (astType)\n\t\t\t\t{\n\t\t\t\t\tcase SimpleType st:\n\t\t\t\t\t\tst.Identifier = shortName;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MemberType mt:\n\t\t\t\t\t\tmt.MemberName = shortName;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (resolver != null)\n\t\t\t{\n\t\t\t\tApplyShortAttributeNameIfPossible(type, astType, shortName);\n\t\t\t}\n\t\t\tAddTypeAnnotation(astType, type);\n\n\t\t\treturn astType;\n\t\t}\n\n\t\tprivate void ApplyShortAttributeNameIfPossible(IType type, AstType astType, string shortName)\n\t\t{\n\t\t\tswitch (astType)\n\t\t\t{\n\t\t\t\tcase SimpleType st:\n\t\t\t\t\tResolveResult shortRR = null;\n\t\t\t\t\tResolveResult withExtraAttrSuffix = resolver.LookupSimpleNameOrTypeName(type.Name + \"Attribute\", EmptyList<IType>.Instance, NameLookupMode.Type);\n\t\t\t\t\tif (shortName != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tshortRR = resolver.LookupSimpleNameOrTypeName(shortName, EmptyList<IType>.Instance, NameLookupMode.Type);\n\t\t\t\t\t}\n\t\t\t\t\t// short type is either unknown or not an attribute type -> we can use the short name.\n\t\t\t\t\tif (shortRR != null && (shortRR is UnknownIdentifierResolveResult || !IsAttributeType(shortRR)))\n\t\t\t\t\t{\n\t\t\t\t\t\tst.Identifier = shortName;\n\t\t\t\t\t}\n\t\t\t\t\telse if (IsAttributeType(withExtraAttrSuffix))\n\t\t\t\t\t{\n\t\t\t\t\t\t// typeName + \"Attribute\" is an attribute type -> we cannot use long type name, add '@' to disable implicit \"Attribute\" suffix.\n\t\t\t\t\t\tst.Identifier = '@' + st.Identifier;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase MemberType mt:\n\t\t\t\t\tif (type.DeclaringType != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar declaringTypeDef = type.DeclaringType.GetDefinition();\n\t\t\t\t\t\tif (declaringTypeDef != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (shortName != null && !declaringTypeDef.GetNestedTypes(t => t.TypeParameterCount == 0 && t.Name == shortName).Any(IsAttributeType))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmt.MemberName = shortName;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (declaringTypeDef.GetNestedTypes(t => t.TypeParameterCount == 0 && t.Name == type.Name + \"Attribute\").Any(IsAttributeType))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmt.MemberName = '@' + mt.MemberName;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (mt.Target.GetResolveResult() is NamespaceResolveResult nrr)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (shortName != null && !IsAttributeType(nrr.Namespace.GetTypeDefinition(shortName, 0)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmt.MemberName = shortName;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (IsAttributeType(nrr.Namespace.GetTypeDefinition(type.Name + \"Attribute\", 0)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmt.MemberName = '@' + mt.MemberName;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tprivate bool IsAttributeType(IType type)\n\t\t{\n\t\t\treturn type != null && type.GetNonInterfaceBaseTypes().Any(t => t.IsKnownType(KnownTypeCode.Attribute));\n\t\t}\n\n\t\tprivate bool IsAttributeType(ResolveResult rr)\n\t\t{\n\t\t\treturn rr is TypeResolveResult trr && IsAttributeType(trr.Type);\n\t\t}\n\t\t#endregion\n\n\t\t#region Convert Constant Value\n\t\t/// <summary>\n\t\t/// Creates an Expression for the given constant value.\n\t\t/// \n\t\t/// Note: the returned expression is not necessarily of the desired type.\n\t\t/// However, the returned expression will always be implicitly convertible to <c>rr.Type</c>,\n\t\t/// and will have the correct value when being converted in this way.\n\t\t/// </summary>\n\t\tpublic Expression ConvertConstantValue(ResolveResult rr)\n\t\t{\n\t\t\tif (rr == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(rr));\n\t\t\tbool isBoxing = false;\n\t\t\tif (rr is ConversionResolveResult crr)\n\t\t\t{\n\t\t\t\t// unpack ConversionResolveResult if necessary\n\t\t\t\t// (e.g. a boxing conversion or string->object reference conversion)\n\t\t\t\trr = crr.Input;\n\t\t\t\tisBoxing = crr.Conversion.IsBoxingConversion;\n\t\t\t}\n\n\t\t\tif (rr is TypeOfResolveResult)\n\t\t\t{\n\t\t\t\tvar expr = new TypeOfExpression(ConvertType(((TypeOfResolveResult)rr).ReferencedType));\n\t\t\t\tif (AddResolveResultAnnotations)\n\t\t\t\t\texpr.AddAnnotation(rr);\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\telse if (rr is ArrayCreateResolveResult acrr)\n\t\t\t{\n\t\t\t\tArrayCreateExpression ace = new ArrayCreateExpression();\n\t\t\t\tace.Type = ConvertType(acrr.Type);\n\t\t\t\tif (ace.Type is ComposedType composedType)\n\t\t\t\t{\n\t\t\t\t\tcomposedType.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);\n\t\t\t\t\tif (!composedType.HasNullableSpecifier && composedType.PointerRank == 0)\n\t\t\t\t\t\tace.Type = composedType.BaseType;\n\t\t\t\t}\n\n\t\t\t\tif (acrr.SizeArguments != null && acrr.InitializerElements == null)\n\t\t\t\t{\n\t\t\t\t\tace.AdditionalArraySpecifiers.FirstOrNullObject().Remove();\n\t\t\t\t\tace.Arguments.AddRange(acrr.SizeArguments.Select(ConvertConstantValue));\n\t\t\t\t}\n\t\t\t\tif (acrr.InitializerElements != null)\n\t\t\t\t{\n\t\t\t\t\tArrayInitializerExpression initializer = new ArrayInitializerExpression();\n\t\t\t\t\tinitializer.Elements.AddRange(acrr.InitializerElements.Select(ConvertConstantValue));\n\t\t\t\t\tace.Initializer = initializer;\n\t\t\t\t}\n\t\t\t\tif (AddResolveResultAnnotations)\n\t\t\t\t\tace.AddAnnotation(rr);\n\t\t\t\treturn ace;\n\t\t\t}\n\t\t\telse if (rr.IsCompileTimeConstant)\n\t\t\t{\n\t\t\t\tvar expr = ConvertConstantValue(rr.Type, rr.ConstantValue);\n\t\t\t\tif (isBoxing && (rr.Type.IsCSharpSmallIntegerType() || rr.Type.IsCSharpNativeIntegerType()))\n\t\t\t\t{\n\t\t\t\t\t// C# does not have small integer literal types.\n\t\t\t\t\t// We need to add a cast so that the integer literal gets boxed as the correct type.\n\t\t\t\t\texpr = new CastExpression(ConvertType(rr.Type), expr);\n\t\t\t\t\tif (AddResolveResultAnnotations)\n\t\t\t\t\t\texpr.AddAnnotation(rr);\n\t\t\t\t}\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new ErrorExpression();\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates an Expression for the given constant value.\n\t\t/// \n\t\t/// Note: the returned expression is not necessarily of the specified <paramref name=\"type\"/>:\n\t\t/// For example, <c>ConvertConstantValue(typeof(string), null)</c> results in a <c>null</c> literal,\n\t\t/// without a cast to <c>string</c>.\n\t\t/// Similarly, <c>ConvertConstantValue(typeof(short), 1)</c> results in the literal <c>1</c>,\n\t\t/// which is of type <c>int</c>.\n\t\t/// However, the returned expression will always be implicitly convertible to <paramref name=\"type\"/>.\n\t\t/// </summary>\n\t\tpublic Expression ConvertConstantValue(IType type, object constantValue)\n\t\t{\n\t\t\treturn ConvertConstantValue(type, type, constantValue);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates an Expression for the given constant value.\n\t\t/// </summary>\n\t\tpublic Expression ConvertConstantValue(IType expectedType, IType type, object constantValue)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tif (constantValue == null)\n\t\t\t{\n\t\t\t\tif (type.IsReferenceType == true || type.IsKnownType(KnownTypeCode.NullableOfT) || type.Kind.IsAnyPointer())\n\t\t\t\t{\n\t\t\t\t\tvar expr = new NullReferenceExpression();\n\t\t\t\t\tif (AddResolveResultAnnotations)\n\t\t\t\t\t\texpr.AddAnnotation(new ConstantResolveResult(SpecialType.NullType, null));\n\t\t\t\t\treturn expr;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar expr = new DefaultValueExpression(ConvertType(type));\n\t\t\t\t\tif (AddResolveResultAnnotations)\n\t\t\t\t\t\texpr.AddAnnotation(new ConstantResolveResult(type, null));\n\t\t\t\t\treturn expr;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (constantValue is IType typeofType)\n\t\t\t{\n\t\t\t\tvar expr = new TypeOfExpression(ConvertType(typeofType));\n\t\t\t\tif (AddResolveResultAnnotations)\n\t\t\t\t\texpr.AddAnnotation(new TypeOfResolveResult(type, typeofType));\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\telse if (constantValue is ImmutableArray<System.Reflection.Metadata.CustomAttributeTypedArgument<IType>> arr)\n\t\t\t{\n\t\t\t\tvar elementType = (type as ArrayType)?.ElementType ?? SpecialType.UnknownType;\n\t\t\t\tvar expr = new ArrayCreateExpression();\n\t\t\t\texpr.Type = ConvertType(type);\n\t\t\t\tif (expr.Type is ComposedType composedType)\n\t\t\t\t{\n\t\t\t\t\tcomposedType.ArraySpecifiers.MoveTo(expr.AdditionalArraySpecifiers);\n\t\t\t\t\tif (!composedType.HasNullableSpecifier && composedType.PointerRank == 0)\n\t\t\t\t\t\texpr.Type = composedType.BaseType;\n\t\t\t\t}\n\t\t\t\texpr.Initializer = new ArrayInitializerExpression(arr.Select(e => ConvertConstantValue(elementType, e.Type, e.Value)));\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tIType underlyingType = NullableType.GetUnderlyingType(type);\n\t\t\t\tif (underlyingType.Kind == TypeKind.Enum)\n\t\t\t\t{\n\t\t\t\t\treturn ConvertEnumValue(underlyingType, (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, constantValue, false));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (!(PrintIntegralValuesAsHex && underlyingType.IsCSharpPrimitiveIntegerType())\n\t\t\t\t\t\t&& IsSpecialConstant(underlyingType, constantValue, out var expr))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn expr;\n\t\t\t\t\t}\n\t\t\t\t\tif (underlyingType.IsKnownType(KnownTypeCode.Double) || underlyingType.IsKnownType(KnownTypeCode.Single))\n\t\t\t\t\t\treturn ConvertFloatingPointLiteral(underlyingType, constantValue);\n\t\t\t\t\tIType literalType = underlyingType;\n\t\t\t\t\tbool integerTypeMismatch = underlyingType.IsCSharpSmallIntegerType() || underlyingType.IsCSharpNativeIntegerType();\n\t\t\t\t\tif (integerTypeMismatch)\n\t\t\t\t\t{\n\t\t\t\t\t\t// C# does not have integer literals of small integer types,\n\t\t\t\t\t\t// use `int` literal instead.\n\t\t\t\t\t\t// It also doesn't have native integer literals, those also use `int` (or `uint` for `nuint`).\n\t\t\t\t\t\tbool unsigned = underlyingType.Kind == TypeKind.NUInt;\n\t\t\t\t\t\tconstantValue = CSharpPrimitiveCast.Cast(unsigned ? TypeCode.UInt32 : TypeCode.Int32, constantValue, false);\n\t\t\t\t\t\tvar compilation = resolver?.Compilation ?? expectedType.GetDefinition()?.Compilation;\n\t\t\t\t\t\tliteralType = compilation?.FindType(unsigned ? KnownTypeCode.UInt32 : KnownTypeCode.Int32);\n\t\t\t\t\t}\n\t\t\t\t\tLiteralFormat format = LiteralFormat.None;\n\t\t\t\t\tif (PrintIntegralValuesAsHex)\n\t\t\t\t\t{\n\t\t\t\t\t\tformat = LiteralFormat.HexadecimalNumber;\n\t\t\t\t\t}\n\t\t\t\t\texpr = new PrimitiveExpression(constantValue, format);\n\t\t\t\t\tif (AddResolveResultAnnotations && literalType != null)\n\t\t\t\t\t\texpr.AddAnnotation(new ConstantResolveResult(literalType, constantValue));\n\t\t\t\t\tif (integerTypeMismatch && !type.Equals(expectedType) || underlyingType.Kind == TypeKind.Unknown)\n\t\t\t\t\t{\n\t\t\t\t\t\texpr = new CastExpression(ConvertType(type), expr);\n\t\t\t\t\t}\n\t\t\t\t\treturn expr;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool IsSpecialConstant(IType expectedType, object constant, out Expression expression)\n\t\t{\n\t\t\texpression = null;\n\t\t\tif (!specialConstants.TryGetValue(constant, out var info))\n\t\t\t\treturn false;\n\t\t\t// find IType of constant in compilation.\n\t\t\tvar constantType = expectedType;\n\t\t\tif (!expectedType.IsKnownType(info.Type))\n\t\t\t{\n\t\t\t\tvar compilation = resolver?.Compilation ?? expectedType.GetDefinition()?.Compilation;\n\t\t\t\tif (compilation == null)\n\t\t\t\t\treturn false;\n\t\t\t\tconstantType = compilation.FindType(info.Type);\n\t\t\t}\n\t\t\t// if the field definition cannot be found, do not generate a reference to the field.\n\t\t\tvar field = constantType.GetFields(p => p.Name == info.Member).SingleOrDefault();\n\t\t\tif (!UseSpecialConstants || field == null)\n\t\t\t{\n\t\t\t\t// +Infty, -Infty and NaN, cannot be represented in their encoded form.\n\t\t\t\t// Use an equivalent arithmetic expression instead.\n\t\t\t\tif (info.Type == KnownTypeCode.Double)\n\t\t\t\t{\n\t\t\t\t\tswitch ((double)constant)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase double.NegativeInfinity: // (-1.0 / 0.0)\n\t\t\t\t\t\t\tvar left = new PrimitiveExpression(-1.0).WithoutILInstruction().WithRR(new ConstantResolveResult(constantType, -1.0));\n\t\t\t\t\t\t\tvar right = new PrimitiveExpression(0.0).WithoutILInstruction().WithRR(new ConstantResolveResult(constantType, 0.0));\n\t\t\t\t\t\t\texpression = new BinaryOperatorExpression(left, BinaryOperatorType.Divide, right).WithoutILInstruction()\n\t\t\t\t\t\t\t\t.WithRR(new ConstantResolveResult(constantType, double.NegativeInfinity));\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tcase double.PositiveInfinity: // (1.0 / 0.0)\n\t\t\t\t\t\t\tleft = new PrimitiveExpression(1.0).WithoutILInstruction().WithRR(new ConstantResolveResult(constantType, 1.0));\n\t\t\t\t\t\t\tright = new PrimitiveExpression(0.0).WithoutILInstruction().WithRR(new ConstantResolveResult(constantType, 0.0));\n\t\t\t\t\t\t\texpression = new BinaryOperatorExpression(left, BinaryOperatorType.Divide, right).WithoutILInstruction()\n\t\t\t\t\t\t\t\t.WithRR(new ConstantResolveResult(constantType, double.PositiveInfinity));\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tcase double.NaN: // (0.0 / 0.0)\n\t\t\t\t\t\t\tleft = new PrimitiveExpression(0.0).WithoutILInstruction().WithRR(new ConstantResolveResult(constantType, 0.0));\n\t\t\t\t\t\t\tright = new PrimitiveExpression(0.0).WithoutILInstruction().WithRR(new ConstantResolveResult(constantType, 0.0));\n\t\t\t\t\t\t\texpression = new BinaryOperatorExpression(left, BinaryOperatorType.Divide, right).WithoutILInstruction()\n\t\t\t\t\t\t\t\t.WithRR(new ConstantResolveResult(constantType, double.NaN));\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (info.Type == KnownTypeCode.Single)\n\t\t\t\t{\n\t\t\t\t\tswitch ((float)constant)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase float.NegativeInfinity: // (-1.0f / 0.0f)\n\t\t\t\t\t\t\tvar left = new PrimitiveExpression(-1.0f).WithoutILInstruction().WithRR(new ConstantResolveResult(constantType, -1.0f));\n\t\t\t\t\t\t\tvar right = new PrimitiveExpression(0.0f).WithoutILInstruction().WithRR(new ConstantResolveResult(constantType, 0.0f));\n\t\t\t\t\t\t\texpression = new BinaryOperatorExpression(left, BinaryOperatorType.Divide, right).WithoutILInstruction()\n\t\t\t\t\t\t\t\t.WithRR(new ConstantResolveResult(constantType, float.NegativeInfinity));\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tcase float.PositiveInfinity: // (1.0f / 0.0f)\n\t\t\t\t\t\t\tleft = new PrimitiveExpression(1.0f).WithoutILInstruction().WithRR(new ConstantResolveResult(constantType, 1.0f));\n\t\t\t\t\t\t\tright = new PrimitiveExpression(0.0f).WithoutILInstruction().WithRR(new ConstantResolveResult(constantType, 0.0f));\n\t\t\t\t\t\t\texpression = new BinaryOperatorExpression(left, BinaryOperatorType.Divide, right).WithoutILInstruction()\n\t\t\t\t\t\t\t\t.WithRR(new ConstantResolveResult(constantType, float.PositiveInfinity));\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tcase float.NaN: // (0.0f / 0.0f)\n\t\t\t\t\t\t\tleft = new PrimitiveExpression(0.0f).WithoutILInstruction().WithRR(new ConstantResolveResult(constantType, 0.0f));\n\t\t\t\t\t\t\tright = new PrimitiveExpression(0.0f).WithoutILInstruction().WithRR(new ConstantResolveResult(constantType, 0.0f));\n\t\t\t\t\t\t\texpression = new BinaryOperatorExpression(left, BinaryOperatorType.Divide, right).WithoutILInstruction()\n\t\t\t\t\t\t\t\t.WithRR(new ConstantResolveResult(constantType, float.NaN));\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\texpression = new TypeReferenceExpression(ConvertType(constantType));\n\n\t\t\tif (AddResolveResultAnnotations)\n\t\t\t\texpression.AddAnnotation(new TypeResolveResult(constantType));\n\n\t\t\texpression = new MemberReferenceExpression(expression, info.Member);\n\n\t\t\tif (AddResolveResultAnnotations)\n\t\t\t\texpression.AddAnnotation(new MemberResolveResult(new TypeResolveResult(constantType), field));\n\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic readonly Dictionary<object, (KnownTypeCode Type, string Member)> specialConstants = new Dictionary<object, (KnownTypeCode Type, string Member)>() {\n\t\t\t// byte:\n\t\t\t{ byte.MaxValue, (KnownTypeCode.Byte, \"MaxValue\") },\n\t\t\t// sbyte:\n\t\t\t{ sbyte.MinValue, (KnownTypeCode.SByte, \"MinValue\") },\n\t\t\t{ sbyte.MaxValue, (KnownTypeCode.SByte, \"MaxValue\") },\n\t\t\t// short:\n\t\t\t{ short.MinValue, (KnownTypeCode.Int16, \"MinValue\") },\n\t\t\t{ short.MaxValue, (KnownTypeCode.Int16, \"MaxValue\") },\n\t\t\t// ushort:\n\t\t\t{ ushort.MaxValue, (KnownTypeCode.UInt16, \"MaxValue\") },\n\t\t\t// int:\n\t\t\t{ int.MinValue, (KnownTypeCode.Int32, \"MinValue\") },\n\t\t\t{ int.MaxValue, (KnownTypeCode.Int32, \"MaxValue\") },\n\t\t\t// uint:\n\t\t\t{ uint.MaxValue, (KnownTypeCode.UInt32, \"MaxValue\") },\n\t\t\t// long:\n\t\t\t{ long.MinValue, (KnownTypeCode.Int64, \"MinValue\") },\n\t\t\t{ long.MaxValue, (KnownTypeCode.Int64, \"MaxValue\") },\n\t\t\t// ulong:\n\t\t\t{ ulong.MaxValue, (KnownTypeCode.UInt64, \"MaxValue\") },\n\t\t\t// float:\n\t\t\t{ float.NaN, (KnownTypeCode.Single, \"NaN\") },\n\t\t\t{ float.NegativeInfinity, (KnownTypeCode.Single, \"NegativeInfinity\") },\n\t\t\t{ float.PositiveInfinity, (KnownTypeCode.Single, \"PositiveInfinity\") },\n\t\t\t{ float.MinValue, (KnownTypeCode.Single, \"MinValue\") },\n\t\t\t{ float.MaxValue, (KnownTypeCode.Single, \"MaxValue\") },\n\t\t\t{ float.Epsilon, (KnownTypeCode.Single, \"Epsilon\") },\n\t\t\t// double:\n\t\t\t{ double.NaN, (KnownTypeCode.Double, \"NaN\") },\n\t\t\t{ double.NegativeInfinity, (KnownTypeCode.Double, \"NegativeInfinity\") },\n\t\t\t{ double.PositiveInfinity, (KnownTypeCode.Double, \"PositiveInfinity\") },\n\t\t\t{ double.MinValue, (KnownTypeCode.Double, \"MinValue\") },\n\t\t\t{ double.MaxValue, (KnownTypeCode.Double, \"MaxValue\") },\n\t\t\t{ double.Epsilon, (KnownTypeCode.Double, \"Epsilon\") },\n\t\t\t// decimal:\n\t\t\t{ decimal.MinValue, (KnownTypeCode.Decimal, \"MinValue\") },\n\t\t\t{ decimal.MaxValue, (KnownTypeCode.Decimal, \"MaxValue\") },\n\t\t};\n\n\t\tbool IsFlagsEnum(ITypeDefinition type)\n\t\t{\n\t\t\treturn type.HasAttribute(KnownAttribute.Flags);\n\t\t}\n\n\t\tExpression ConvertEnumValue(IType type, long val)\n\t\t{\n\t\t\tITypeDefinition enumDefinition = type.GetDefinition();\n\t\t\tTypeCode enumBaseTypeCode = ReflectionHelper.GetTypeCode(enumDefinition.EnumUnderlyingType);\n\t\t\tvar fields = enumDefinition.Fields\n\t\t\t\t.Select(PrepareConstant)\n\t\t\t\t.Where(f => f.field != null)\n\t\t\t\t.ToArray();\n\t\t\tforeach (var (value, field) in fields)\n\t\t\t{\n\t\t\t\tif (value == val)\n\t\t\t\t{\n\t\t\t\t\tvar mre = new MemberReferenceExpression(new TypeReferenceExpression(ConvertType(type)), field.Name);\n\t\t\t\t\tif (AddResolveResultAnnotations)\n\t\t\t\t\t\tmre.AddAnnotation(new MemberResolveResult(mre.Target.GetResolveResult(), field));\n\t\t\t\t\treturn mre;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (IsFlagsEnum(enumDefinition))\n\t\t\t{\n\t\t\t\tlong enumValue = val;\n\t\t\t\tExpression expr = null;\n\t\t\t\tlong negatedEnumValue = ~val;\n\t\t\t\t// limit negatedEnumValue to the appropriate range\n\t\t\t\tswitch (enumBaseTypeCode)\n\t\t\t\t{\n\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\tnegatedEnumValue &= byte.MaxValue;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\tnegatedEnumValue &= ushort.MaxValue;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\tnegatedEnumValue &= uint.MaxValue;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tExpression negatedExpr = null;\n\t\t\t\tforeach (var (fieldValue, field) in fields.OrderByDescending(f => CalculateHammingWeight(unchecked((ulong)f.value))))\n\t\t\t\t{\n\t\t\t\t\tif (fieldValue == 0)\n\t\t\t\t\t\tcontinue;   // skip None enum value\n\n\t\t\t\t\tif ((fieldValue & enumValue) == fieldValue)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar fieldExpression = new MemberReferenceExpression(new TypeReferenceExpression(ConvertType(type)), field.Name);\n\t\t\t\t\t\tif (expr == null)\n\t\t\t\t\t\t\texpr = fieldExpression;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\texpr = new BinaryOperatorExpression(expr, BinaryOperatorType.BitwiseOr, fieldExpression);\n\n\t\t\t\t\t\tenumValue &= ~fieldValue;\n\t\t\t\t\t}\n\t\t\t\t\tif ((fieldValue & negatedEnumValue) == fieldValue)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar fieldExpression = new MemberReferenceExpression(new TypeReferenceExpression(ConvertType(type)), field.Name);\n\t\t\t\t\t\tif (negatedExpr == null)\n\t\t\t\t\t\t\tnegatedExpr = fieldExpression;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tnegatedExpr = new BinaryOperatorExpression(negatedExpr, BinaryOperatorType.BitwiseOr, fieldExpression);\n\n\t\t\t\t\t\tnegatedEnumValue &= ~fieldValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (enumValue == 0 && expr != null)\n\t\t\t\t{\n\t\t\t\t\tif (!(negatedEnumValue == 0 && negatedExpr != null && negatedExpr.Descendants.Count() < expr.Descendants.Count()))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn expr;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (negatedEnumValue == 0 && negatedExpr != null)\n\t\t\t\t{\n\t\t\t\t\treturn new UnaryOperatorExpression(UnaryOperatorType.BitNot, negatedExpr);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn new CastExpression(ConvertType(type), new PrimitiveExpression(CSharpPrimitiveCast.Cast(enumBaseTypeCode, val, false)));\n\n\t\t\t(long value, IField field) PrepareConstant(IField field)\n\t\t\t{\n\t\t\t\tif (!field.IsConst)\n\t\t\t\t\treturn (-1, null);\n\t\t\t\tobject constantValue = field.GetConstantValue();\n\t\t\t\tif (constantValue == null)\n\t\t\t\t\treturn (-1, null);\n\t\t\t\treturn ((long)CSharpPrimitiveCast.Cast(TypeCode.Int64, constantValue, checkForOverflow: false), field);\n\t\t\t}\n\n\t\t\t// see https://en.wikipedia.org/wiki/Hamming_weight\n\t\t\tint CalculateHammingWeight(ulong value)\n\t\t\t{\n\t\t\t\tconst ulong m1 = 0x5555555555555555; //binary: 0101...\n\t\t\t\tconst ulong m2 = 0x3333333333333333; //binary: 00110011..\n\t\t\t\tconst ulong m4 = 0x0f0f0f0f0f0f0f0f; //binary:  4 zeros,  4 ones ...\n\t\t\t\tconst ulong h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3...\n\t\t\t\tulong x = value - ((value >> 1) & m1); //put count of each 2 bits into those 2 bits\n\t\t\t\tx = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits \n\t\t\t\tx = (x + (x >> 4)) & m4;        //put count of each 8 bits into those 8 bits \n\t\t\t\treturn unchecked((int)((x * h01) >> 56));  //returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ... \n\t\t\t}\n\t\t}\n\n\t\tstatic bool IsValidFraction(long num, long den)\n\t\t{\n\t\t\tif (!(den > 0 && num != 0))\n\t\t\t\treturn false;\n\n\t\t\tif (den == 1 || Math.Abs(num) == 1)\n\t\t\t\treturn true;\n\t\t\treturn Math.Abs(num) < den && new int[] { 2, 3, 5 }.Any(x => den % x == 0);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.NoInlining)]\n\t\tstatic bool EqualDoubles(in double val1, in double val2)\n\t\t{\n\t\t\t// We use `in double` to pass the floats through memory,\n\t\t\t// which ensures we won't get more than 64bits of precision\n\t\t\treturn val1 == val2;\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.NoInlining)]\n\t\tstatic bool EqualFloats(in float val1, in float val2)\n\t\t{\n\t\t\t// We use `in float` to pass the floats through memory,\n\t\t\t// which ensures we won't get more than 32bits of precision\n\t\t\treturn val1 == val2;\n\t\t}\n\n\t\tstatic bool IsEqual(long num, long den, object constantValue, bool isDouble)\n\t\t{\n\t\t\tif (isDouble)\n\t\t\t{\n\t\t\t\treturn EqualDoubles((double)constantValue, num / (double)den);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn EqualFloats((float)constantValue, num / (float)den);\n\t\t\t}\n\t\t}\n\n\t\tconst int MAX_DENOMINATOR_DOUBLE = 1000;\n\t\tconst int MAX_DENOMINATOR_FLOAT = 360;\n\n\t\tExpression ConvertFloatingPointLiteral(IType type, object constantValue)\n\t\t{\n\t\t\t// Coerce constantValue to either float or double:\n\t\t\t// There are compilers that embed 0 (and possible other values) as int into constant value signatures,\n\t\t\t// even if the expected type is float or double.\n\t\t\tconstantValue = CSharpPrimitiveCast.Cast(type.GetTypeCode(), constantValue, false);\n\t\t\tbool isDouble = type.IsKnownType(KnownTypeCode.Double);\n\t\t\tICompilation compilation = type.GetDefinition().Compilation;\n\t\t\tExpression expr = null;\n\n\t\t\tstring str;\n\t\t\tif (isDouble)\n\t\t\t{\n\t\t\t\tif (Math.Floor((double)constantValue) == (double)constantValue)\n\t\t\t\t{\n\t\t\t\t\texpr = new PrimitiveExpression(constantValue);\n\t\t\t\t}\n\n\t\t\t\tstr = ((double)constantValue).ToString(\"r\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (Math.Floor((float)constantValue) == (float)constantValue)\n\t\t\t\t{\n\t\t\t\t\texpr = new PrimitiveExpression(constantValue);\n\t\t\t\t}\n\n\t\t\t\tstr = ((float)constantValue).ToString(\"r\");\n\t\t\t}\n\n\t\t\tbool useFraction = (str.Length - (str.StartsWith(\"-\", StringComparison.OrdinalIgnoreCase) ? 2 : 1) > 5);\n\n\t\t\tif (useFraction && expr == null)\n\t\t\t{\n\t\t\t\tDebug.Assert(200 < MAX_DENOMINATOR_FLOAT);\n\t\t\t\t// For fractions not involving PI, use a smaller MAX_DENOMINATOR\n\t\t\t\t// to avoid coincidences such as (1f/MathF.PI) == (113f/355f)\n\t\t\t\t(long num, long den) = isDouble\n\t\t\t\t\t? FractionApprox((double)constantValue, MAX_DENOMINATOR_DOUBLE)\n\t\t\t\t\t: FractionApprox((float)constantValue, 200);\n\n\t\t\t\tif (IsValidFraction(num, den) && IsEqual(num, den, constantValue, isDouble) && Math.Abs(den) != 1)\n\t\t\t\t{\n\t\t\t\t\tvar left = MakeConstant(type, num);\n\t\t\t\t\tvar right = MakeConstant(type, den);\n\t\t\t\t\texpr = new BinaryOperatorExpression(left, BinaryOperatorType.Divide, right);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (useFraction && expr == null && UseSpecialConstants)\n\t\t\t{\n\t\t\t\tIType mathType;\n\t\t\t\tif (isDouble)\n\t\t\t\t\tmathType = compilation.FindType(typeof(Math));\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tmathType = compilation.FindType(new TopLevelTypeName(\"System\", \"MathF\"));\n\t\t\t\t\tvar typeDef = mathType.GetDefinition();\n\t\t\t\t\tif (typeDef == null\n\t\t\t\t\t\t|| !typeDef.IsDirectImportOf(compilation.MainModule)\n\t\t\t\t\t\t|| !typeDef.GetFields(f => f.Name == \"PI\" && f.IsConst).Any() || !typeDef.GetFields(f => f.Name == \"E\" && f.IsConst).Any())\n\t\t\t\t\t{\n\t\t\t\t\t\tmathType = compilation.FindType(typeof(Math));\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\texpr = TryExtractExpression(mathType, type, constantValue, \"PI\", isDouble)\n\t\t\t\t\t?? TryExtractExpression(mathType, type, constantValue, \"E\", isDouble);\n\t\t\t}\n\n\t\t\tif (expr == null)\n\t\t\t\texpr = new PrimitiveExpression(constantValue);\n\n\t\t\tif (AddResolveResultAnnotations)\n\t\t\t\texpr.AddAnnotation(new ConstantResolveResult(type, constantValue));\n\n\t\t\treturn expr;\n\t\t}\n\n\t\tExpression MakeConstant(IType type, long c)\n\t\t{\n\t\t\treturn new PrimitiveExpression(CSharpPrimitiveCast.Cast(type.GetTypeCode(), c, checkForOverflow: true));\n\t\t}\n\n\t\tconst float MathF_PI = 3.14159274f;\n\t\tconst float MathF_E = 2.71828175f;\n\n\t\tExpression TryExtractExpression(IType mathType, IType type, object literalValue, string memberName, bool isDouble)\n\t\t{\n\t\t\tExpression MakeFieldReference()\n\t\t\t{\n\t\t\t\tAstType mathAstType = ConvertType(mathType);\n\t\t\t\tvar fieldRef = new MemberReferenceExpression(new TypeReferenceExpression(mathAstType), memberName);\n\t\t\t\tif (AddResolveResultAnnotations)\n\t\t\t\t{\n\t\t\t\t\tvar field = mathType.GetFields(f => f.Name == memberName).FirstOrDefault();\n\t\t\t\t\tif (field != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tfieldRef.WithRR(new MemberResolveResult(mathAstType.GetResolveResult(), field));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (type.IsKnownType(KnownTypeCode.Double))\n\t\t\t\t\treturn fieldRef;\n\t\t\t\tif (mathType.Name == \"MathF\")\n\t\t\t\t\treturn fieldRef;\n\t\t\t\treturn new CastExpression(ConvertType(type), fieldRef);\n\t\t\t}\n\n\t\t\tExpression ExtractExpression(long n, long d)\n\t\t\t{\n\t\t\t\tExpression fieldReference = MakeFieldReference();\n\n\t\t\t\t// Math.PI or Math.E or (float)Math.PI or (float)Math.E or MathF.PI or MathF.E\n\t\t\t\tExpression expr = fieldReference;\n\n\t\t\t\tif (n != 1)\n\t\t\t\t{\n\t\t\t\t\tif (n == -1)\n\t\t\t\t\t{\n\t\t\t\t\t\t// -field\n\t\t\t\t\t\texpr = new UnaryOperatorExpression(UnaryOperatorType.Minus, expr);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// field * n\n\t\t\t\t\t\texpr = new BinaryOperatorExpression(expr, BinaryOperatorType.Multiply, MakeConstant(type, n));\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (d != 1)\n\t\t\t\t{\n\t\t\t\t\t// field * n / d or -field / d or field / d\n\t\t\t\t\texpr = new BinaryOperatorExpression(expr, BinaryOperatorType.Divide, MakeConstant(type, d));\n\t\t\t\t}\n\n\t\t\t\tif (isDouble)\n\t\t\t\t{\n\t\t\t\t\tdouble field = memberName == \"PI\" ? Math.PI : Math.E;\n\t\t\t\t\tdouble approxValue = field * n / d;\n\t\t\t\t\tif (EqualDoubles(approxValue, (double)literalValue))\n\t\t\t\t\t\treturn expr;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfloat field = memberName == \"PI\" ? MathF_PI : MathF_E;\n\t\t\t\t\tfloat approxValue = field * n / d;\n\t\t\t\t\tif (EqualFloats(approxValue, (float)literalValue))\n\t\t\t\t\t\treturn expr;\n\t\t\t\t}\n\n\t\t\t\t// Math.PI or Math.E or (float)Math.PI or (float)Math.E or MathF.PI or MathF.E\n\t\t\t\texpr = fieldReference.Detach();\n\n\t\t\t\tif (d == 1)\n\t\t\t\t{\n\t\t\t\t\t// n / field\n\t\t\t\t\texpr = new BinaryOperatorExpression(MakeConstant(type, n), BinaryOperatorType.Divide, expr);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// n / (d * field)\n\t\t\t\t\texpr = new BinaryOperatorExpression(MakeConstant(type, d), BinaryOperatorType.Multiply, expr);\n\t\t\t\t\texpr = new BinaryOperatorExpression(MakeConstant(type, n), BinaryOperatorType.Divide, expr);\n\t\t\t\t}\n\n\t\t\t\tif (isDouble)\n\t\t\t\t{\n\t\t\t\t\tdouble field = memberName == \"PI\" ? Math.PI : Math.E;\n\t\t\t\t\tdouble approxValue = (double)n / ((double)d * field);\n\t\t\t\t\tif (EqualDoubles(approxValue, (double)literalValue))\n\t\t\t\t\t\treturn expr;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfloat field = memberName == \"PI\" ? MathF_PI : MathF_E;\n\t\t\t\t\tfloat approxValue = (float)n / ((float)d * field);\n\t\t\t\t\tif (EqualFloats(approxValue, (float)literalValue))\n\t\t\t\t\t\treturn expr;\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t(long num, long den) = isDouble\n\t\t\t\t? FractionApprox((double)literalValue / (memberName == \"PI\" ? Math.PI : Math.E), MAX_DENOMINATOR_DOUBLE)\n\t\t\t\t: FractionApprox((float)literalValue / (memberName == \"PI\" ? MathF_PI : MathF_E), MAX_DENOMINATOR_FLOAT);\n\n\t\t\tif (IsValidFraction(num, den))\n\t\t\t{\n\t\t\t\tvar expr = ExtractExpression(num, den);\n\t\t\t\tif (expr != null)\n\t\t\t\t\treturn expr;\n\t\t\t}\n\n\t\t\t(num, den) = isDouble\n\t\t\t\t? FractionApprox((double)literalValue * (memberName == \"PI\" ? Math.PI : Math.E), MAX_DENOMINATOR_DOUBLE)\n\t\t\t\t: FractionApprox((float)literalValue * (memberName == \"PI\" ? MathF_PI : MathF_E), MAX_DENOMINATOR_FLOAT);\n\n\t\t\tif (IsValidFraction(num, den))\n\t\t\t{\n\t\t\t\treturn ExtractExpression(num, den);\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\t// based on https://www.ics.uci.edu/~eppstein/numth/frap.c\n\t\t// find rational approximation to given real number\n\t\t// David Eppstein / UC Irvine / 8 Aug 1993\n\t\t// \n\t\t// With corrections from Arno Formella, May 2008\n\t\t// \n\t\t// usage: a.out r d\n\t\t//   r is real number to approx\n\t\t//   d is the maximum denominator allowed\n\t\t// \n\t\t// based on the theory of continued fractions\n\t\t// if x = a1 + 1/(a2 + 1/(a3 + 1/(a4 + ...)))\n\t\t// then best approximation is found by truncating this series\n\t\t// (with some adjustments in the last term).\n\t\t// \n\t\t// Note the fraction can be recovered as the first column of the matrix\n\t\t//  ( a1 1 ) ( a2 1 ) ( a3 1 ) ...\n\t\t//  ( 1  0 ) ( 1  0 ) ( 1  0 )\n\t\t// Instead of keeping the sequence of continued fraction terms,\n\t\t// we just keep the last partial product of these matrices.\n\t\tstatic (long Num, long Den) FractionApprox(double value, int maxDenominator)\n\t\t{\n\t\t\tif (value > 0x7FFFFFFF)\n\t\t\t\treturn (0, 0);\n\n\t\t\tdouble startValue = value;\n\t\t\tif (value < 0)\n\t\t\t\tvalue = -value;\n\n\t\t\tlong ai;\n\t\t\tlong[,] m = new long[2, 2];\n\n\t\t\tm[0, 0] = m[1, 1] = 1;\n\t\t\tm[0, 1] = m[1, 0] = 0;\n\n\t\t\tdouble v = value;\n\n\t\t\twhile (m[1, 0] * (ai = (long)v) + m[1, 1] <= maxDenominator)\n\t\t\t{\n\t\t\t\tlong t = m[0, 0] * ai + m[0, 1];\n\t\t\t\tm[0, 1] = m[0, 0];\n\t\t\t\tm[0, 0] = t;\n\t\t\t\tt = m[1, 0] * ai + m[1, 1];\n\t\t\t\tm[1, 1] = m[1, 0];\n\t\t\t\tm[1, 0] = t;\n\t\t\t\tif (v - ai == 0)\n\t\t\t\t\tbreak;\n\t\t\t\tv = 1 / (v - ai);\n\t\t\t\tif (Math.Abs(v) >= long.MaxValue)\n\t\t\t\t{\n\t\t\t\t\t// values greater than long.MaxValue cannot be stored in fraction without overflow.\n\t\t\t\t\t// Because the implicit conversion of long.MaxValue to double loses precision,\n\t\t\t\t\t// it's possible that a value v that is strictly greater than long.MaxValue will\n\t\t\t\t\t// nevertheless compare equal, so we use \">=\" to compensate.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (m[1, 0] == 0)\n\t\t\t\treturn (0, 0);\n\n\t\t\tlong firstN = m[0, 0];\n\t\t\tlong firstD = m[1, 0];\n\n\t\t\tai = (maxDenominator - m[1, 1]) / m[1, 0];\n\t\t\tlong secondN = m[0, 0] * ai + m[0, 1];\n\t\t\tlong secondD = m[1, 0] * ai + m[1, 1];\n\n\t\t\tdouble firstDelta = Math.Abs(value - firstN / (double)firstD);\n\t\t\tdouble secondDelta = Math.Abs(value - secondN / (double)secondD);\n\n\t\t\tif (firstDelta < secondDelta)\n\t\t\t\treturn (startValue < 0 ? -firstN : firstN, firstD);\n\t\t\treturn (startValue < 0 ? -secondN : secondN, secondD);\n\t\t}\n\t\t#endregion\n\n\t\t#region Convert Parameter\n\t\tpublic ParameterDeclaration ConvertParameter(IParameter parameter)\n\t\t{\n\t\t\tif (parameter == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(parameter));\n\t\t\tParameterDeclaration decl = new ParameterDeclaration();\n\t\t\tdecl.ParameterModifier = parameter.ReferenceKind;\n\t\t\tdecl.IsParams = parameter.IsParams;\n\t\t\tdecl.IsScopedRef = parameter.Lifetime.ScopedRef;\n\t\t\tif (ShowAttributes)\n\t\t\t{\n\t\t\t\tdecl.Attributes.AddRange(ConvertAttributes(parameter.GetAttributes()));\n\t\t\t}\n\t\t\tIType parameterType;\n\t\t\tif (parameter.Type.Kind == TypeKind.ByReference)\n\t\t\t{\n\t\t\t\t// avoid 'out ref'\n\t\t\t\tparameterType = ((ByReferenceType)parameter.Type).ElementType;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tparameterType = parameter.Type;\n\t\t\t}\n\t\t\tdecl.Type = ConvertType(parameterType);\n\t\t\tif (this.ShowParameterNames)\n\t\t\t{\n\t\t\t\tdecl.Name = parameter.Name;\n\t\t\t}\n\t\t\tif (parameter.IsDefaultValueAssignmentAllowed() && this.ShowConstantValues)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tdecl.DefaultExpression = ConvertConstantValue(parameterType, parameter.GetConstantValue(throwOnInvalidMetadata: true));\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException ex)\n\t\t\t\t{\n\t\t\t\t\tdecl.DefaultExpression = new ErrorExpression(ex.Message);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn decl;\n\t\t}\n\t\t#endregion\n\n\t\t#region Convert Entity\n\t\tpublic AstNode ConvertSymbol(ISymbol symbol)\n\t\t{\n\t\t\tif (symbol == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(symbol));\n\t\t\tswitch (symbol.SymbolKind)\n\t\t\t{\n\t\t\t\tcase SymbolKind.Namespace:\n\t\t\t\t\treturn ConvertNamespaceDeclaration((INamespace)symbol);\n\t\t\t\tcase SymbolKind.Variable:\n\t\t\t\t\treturn ConvertVariable((IVariable)symbol);\n\t\t\t\tcase SymbolKind.Parameter:\n\t\t\t\t\treturn ConvertParameter((IParameter)symbol);\n\t\t\t\tcase SymbolKind.TypeParameter:\n\t\t\t\t\treturn ConvertTypeParameter((ITypeParameter)symbol);\n\t\t\t\tdefault:\n\t\t\t\t\tIEntity entity = symbol as IEntity;\n\t\t\t\t\tif (entity != null)\n\t\t\t\t\t\treturn ConvertEntity(entity);\n\t\t\t\t\tthrow new ArgumentException(\"Invalid value for SymbolKind: \" + symbol.SymbolKind);\n\t\t\t}\n\t\t}\n\n\t\tpublic EntityDeclaration ConvertEntity(IEntity entity)\n\t\t{\n\t\t\tif (entity == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(entity));\n\t\t\tswitch (entity.SymbolKind)\n\t\t\t{\n\t\t\t\tcase SymbolKind.TypeDefinition:\n\t\t\t\t\treturn ConvertTypeDefinition((ITypeDefinition)entity);\n\t\t\t\tcase SymbolKind.Field:\n\t\t\t\t\treturn ConvertField((IField)entity);\n\t\t\t\tcase SymbolKind.Property:\n\t\t\t\t\treturn ConvertProperty((IProperty)entity);\n\t\t\t\tcase SymbolKind.Indexer:\n\t\t\t\t\treturn ConvertIndexer((IProperty)entity);\n\t\t\t\tcase SymbolKind.Event:\n\t\t\t\t\treturn ConvertEvent((IEvent)entity);\n\t\t\t\tcase SymbolKind.Method:\n\t\t\t\t\treturn ConvertMethod((IMethod)entity);\n\t\t\t\tcase SymbolKind.Operator:\n\t\t\t\t\treturn ConvertOperator((IMethod)entity);\n\t\t\t\tcase SymbolKind.Constructor:\n\t\t\t\t\treturn ConvertConstructor((IMethod)entity);\n\t\t\t\tcase SymbolKind.Destructor:\n\t\t\t\t\treturn ConvertDestructor((IMethod)entity);\n\t\t\t\tcase SymbolKind.Accessor:\n\t\t\t\t\tIMethod accessor = (IMethod)entity;\n\t\t\t\t\tAccessibility ownerAccessibility = accessor.AccessorOwner?.Accessibility ?? Accessibility.None;\n\t\t\t\t\treturn ConvertAccessor(accessor, accessor.AccessorKind, ownerAccessibility, false);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentException(\"Invalid value for SymbolKind: \" + entity.SymbolKind);\n\t\t\t}\n\t\t}\n\n\t\tEntityDeclaration ConvertTypeDefinition(ITypeDefinition typeDefinition)\n\t\t{\n\t\t\tModifiers modifiers = Modifiers.None;\n\t\t\tif (this.ShowAccessibility)\n\t\t\t{\n\t\t\t\tmodifiers |= ModifierFromAccessibility(typeDefinition.Accessibility, UsePrivateProtectedAccessibility);\n\t\t\t}\n\t\t\tif (this.ShowModifiers)\n\t\t\t{\n\t\t\t\tif (typeDefinition.IsStatic)\n\t\t\t\t{\n\t\t\t\t\tmodifiers |= Modifiers.Static;\n\t\t\t\t}\n\t\t\t\telse if (typeDefinition.IsAbstract)\n\t\t\t\t{\n\t\t\t\t\tmodifiers |= Modifiers.Abstract;\n\t\t\t\t}\n\t\t\t\telse if (typeDefinition.IsSealed)\n\t\t\t\t{\n\t\t\t\t\tmodifiers |= Modifiers.Sealed;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tClassType classType;\n\t\t\tswitch (typeDefinition.Kind)\n\t\t\t{\n\t\t\t\tcase TypeKind.Struct:\n\t\t\t\tcase TypeKind.Void:\n\t\t\t\t\tclassType = ClassType.Struct;\n\t\t\t\t\tmodifiers &= ~Modifiers.Sealed;\n\t\t\t\t\tif (ShowModifiers)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (typeDefinition.IsReadOnly)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmodifiers |= Modifiers.Readonly;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (typeDefinition.IsByRefLike)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmodifiers |= Modifiers.Ref;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (SupportRecordStructs && typeDefinition.IsRecord)\n\t\t\t\t\t{\n\t\t\t\t\t\tclassType = ClassType.RecordStruct;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeKind.Enum:\n\t\t\t\t\tclassType = ClassType.Enum;\n\t\t\t\t\tmodifiers &= ~Modifiers.Sealed;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeKind.Interface:\n\t\t\t\t\tclassType = ClassType.Interface;\n\t\t\t\t\tmodifiers &= ~Modifiers.Abstract;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeKind.Delegate:\n\t\t\t\t\tIMethod invoke = typeDefinition.GetDelegateInvokeMethod();\n\t\t\t\t\tif (invoke != null)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn ConvertDelegate(invoke, modifiers);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tgoto default;\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\tclassType = ClassType.Class;\n\t\t\t\t\tif (SupportRecordClasses && typeDefinition.IsRecord)\n\t\t\t\t\t{\n\t\t\t\t\t\tclassType = ClassType.RecordClass;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tvar decl = new TypeDeclaration();\n\t\t\tdecl.ClassType = classType;\n\t\t\tdecl.Modifiers = modifiers;\n\t\t\tif (ShowAttributes)\n\t\t\t{\n\t\t\t\tdecl.Attributes.AddRange(ConvertAttributes(typeDefinition.GetAttributes()));\n\t\t\t}\n\t\t\tif (AddResolveResultAnnotations)\n\t\t\t{\n\t\t\t\tdecl.AddAnnotation(new TypeResolveResult(typeDefinition));\n\t\t\t}\n\t\t\tdecl.Name = typeDefinition.Name == \"_\" ? \"@_\" : typeDefinition.Name;\n\n\t\t\tint outerTypeParameterCount = (typeDefinition.DeclaringTypeDefinition == null) ? 0 : typeDefinition.DeclaringTypeDefinition.TypeParameterCount;\n\n\t\t\tif (this.ShowTypeParameters)\n\t\t\t{\n\t\t\t\tforeach (ITypeParameter tp in typeDefinition.TypeParameters.Skip(outerTypeParameterCount))\n\t\t\t\t{\n\t\t\t\t\tdecl.TypeParameters.Add(ConvertTypeParameter(tp));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.ShowBaseTypes)\n\t\t\t{\n\t\t\t\tforeach (IType baseType in typeDefinition.DirectBaseTypes)\n\t\t\t\t{\n\t\t\t\t\tif (typeDefinition.Kind == TypeKind.Enum && baseType.IsKnownType(KnownTypeCode.Enum))\n\t\t\t\t\t{\n\t\t\t\t\t\t// if the declared type is an enum, replace all references to System.Enum with the enum-underlying type\n\t\t\t\t\t\tif (!typeDefinition.EnumUnderlyingType.IsKnownType(KnownTypeCode.Int32))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdecl.BaseTypes.Add(ConvertType(typeDefinition.EnumUnderlyingType));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if ((typeDefinition.Kind == TypeKind.Struct || typeDefinition.Kind == TypeKind.Void) && baseType.IsKnownType(KnownTypeCode.ValueType))\n\t\t\t\t\t{\n\t\t\t\t\t\t// if the declared type is a struct, ignore System.ValueType\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\telse if (baseType.IsKnownType(KnownTypeCode.Object))\n\t\t\t\t\t{\n\t\t\t\t\t\t// always ignore System.Object\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\telse if (SupportRecordClasses && typeDefinition.IsRecord\n\t\t\t\t\t\t&& baseType.Name == \"IEquatable\" && baseType.Namespace == \"System\"\n\t\t\t\t\t\t&& baseType.TypeArguments.Count == 1\n\t\t\t\t\t\t&& baseType.TypeArguments[0].Equals(typeDefinition.AsParameterizedType()))\n\t\t\t\t\t{\n\t\t\t\t\t\t// omit \"IEquatable<R>\" in records\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tdecl.BaseTypes.Add(ConvertType(baseType));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.ShowTypeParameters && this.ShowTypeParameterConstraints)\n\t\t\t{\n\t\t\t\tforeach (ITypeParameter tp in typeDefinition.TypeParameters.Skip(outerTypeParameterCount))\n\t\t\t\t{\n\t\t\t\t\tvar constraint = ConvertTypeParameterConstraint(tp);\n\t\t\t\t\tif (constraint != null)\n\t\t\t\t\t\tdecl.Constraints.Add(constraint);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn decl;\n\t\t}\n\n\t\tDelegateDeclaration ConvertDelegate(IMethod invokeMethod, Modifiers modifiers)\n\t\t{\n\t\t\tITypeDefinition d = invokeMethod.DeclaringTypeDefinition;\n\n\t\t\tDelegateDeclaration decl = new DelegateDeclaration();\n\t\t\tdecl.Modifiers = modifiers & ~Modifiers.Sealed;\n\t\t\tif (ShowAttributes)\n\t\t\t{\n\t\t\t\tdecl.Attributes.AddRange(ConvertAttributes(d.GetAttributes()));\n\t\t\t\tdecl.Attributes.AddRange(ConvertAttributes(invokeMethod.GetReturnTypeAttributes(), \"return\"));\n\t\t\t}\n\t\t\tif (AddResolveResultAnnotations)\n\t\t\t{\n\t\t\t\tdecl.AddAnnotation(new TypeResolveResult(d));\n\t\t\t}\n\t\t\tdecl.ReturnType = ConvertType(invokeMethod.ReturnType);\n\t\t\tif (invokeMethod.ReturnTypeIsRefReadOnly && decl.ReturnType is ComposedType ct && ct.HasRefSpecifier)\n\t\t\t{\n\t\t\t\tct.HasReadOnlySpecifier = true;\n\t\t\t}\n\t\t\tdecl.Name = d.Name;\n\n\t\t\tint outerTypeParameterCount = (d.DeclaringTypeDefinition == null) ? 0 : d.DeclaringTypeDefinition.TypeParameterCount;\n\n\t\t\tif (this.ShowTypeParameters)\n\t\t\t{\n\t\t\t\tforeach (ITypeParameter tp in d.TypeParameters.Skip(outerTypeParameterCount))\n\t\t\t\t{\n\t\t\t\t\tdecl.TypeParameters.Add(ConvertTypeParameter(tp));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach (IParameter p in invokeMethod.Parameters)\n\t\t\t{\n\t\t\t\tdecl.Parameters.Add(ConvertParameter(p));\n\t\t\t}\n\n\t\t\tif (this.ShowTypeParameters && this.ShowTypeParameterConstraints)\n\t\t\t{\n\t\t\t\tforeach (ITypeParameter tp in d.TypeParameters.Skip(outerTypeParameterCount))\n\t\t\t\t{\n\t\t\t\t\tvar constraint = ConvertTypeParameterConstraint(tp);\n\t\t\t\t\tif (constraint != null)\n\t\t\t\t\t\tdecl.Constraints.Add(constraint);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn decl;\n\t\t}\n\n\t\tFieldDeclaration ConvertField(IField field)\n\t\t{\n\t\t\tFieldDeclaration decl = new FieldDeclaration();\n\t\t\tif (ShowModifiers)\n\t\t\t{\n\t\t\t\tModifiers m = GetMemberModifiers(field);\n\t\t\t\tif (field.IsConst)\n\t\t\t\t{\n\t\t\t\t\tm &= ~Modifiers.Static;\n\t\t\t\t\tm |= Modifiers.Const;\n\t\t\t\t}\n\t\t\t\telse if (field.IsReadOnly)\n\t\t\t\t{\n\t\t\t\t\tm |= Modifiers.Readonly;\n\t\t\t\t}\n\t\t\t\telse if (field.IsVolatile)\n\t\t\t\t{\n\t\t\t\t\tm |= Modifiers.Volatile;\n\t\t\t\t}\n\t\t\t\tdecl.Modifiers = m;\n\t\t\t}\n\t\t\tif (ShowAttributes)\n\t\t\t{\n\t\t\t\tdecl.Attributes.AddRange(ConvertAttributes(field.GetAttributes()));\n\t\t\t}\n\t\t\tif (AddResolveResultAnnotations)\n\t\t\t{\n\t\t\t\tdecl.AddAnnotation(new MemberResolveResult(null, field));\n\t\t\t}\n\t\t\tdecl.ReturnType = ConvertType(field.ReturnType);\n\t\t\tif (decl.ReturnType is ComposedType ct && ct.HasRefSpecifier && field.ReturnTypeIsRefReadOnly)\n\t\t\t{\n\t\t\t\tct.HasReadOnlySpecifier = true;\n\t\t\t}\n\t\t\tExpression initializer = null;\n\t\t\tif (field.IsConst && this.ShowConstantValues)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tinitializer = ConvertConstantValue(field.Type, field.GetConstantValue(throwOnInvalidMetadata: true));\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException ex)\n\t\t\t\t{\n\t\t\t\t\tinitializer = new ErrorExpression(ex.Message);\n\t\t\t\t}\n\t\t\t}\n\t\t\tdecl.Variables.Add(new VariableInitializer(field.Name, initializer));\n\t\t\treturn decl;\n\t\t}\n\n\t\tBlockStatement GenerateBodyBlock()\n\t\t{\n\t\t\tif (GenerateBody)\n\t\t\t{\n\t\t\t\treturn new BlockStatement {\n\t\t\t\t\tnew ThrowStatement(new ObjectCreateExpression(ConvertType(new TopLevelTypeName(\"System\", \"NotImplementedException\", 0))))\n\t\t\t\t};\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn BlockStatement.Null;\n\t\t\t}\n\t\t}\n\n\t\tAccessor ConvertAccessor(IMethod accessor, MethodSemanticsAttributes kind, Accessibility ownerAccessibility, bool addParameterAttribute)\n\t\t{\n\t\t\tif (accessor == null)\n\t\t\t\treturn Accessor.Null;\n\t\t\tAccessor decl = new Accessor();\n\t\t\tif (ShowAttributes)\n\t\t\t{\n\t\t\t\tdecl.Attributes.AddRange(ConvertAttributes(accessor.GetAttributes()));\n\t\t\t\tdecl.Attributes.AddRange(ConvertAttributes(accessor.GetReturnTypeAttributes(), \"return\"));\n\t\t\t\tif (addParameterAttribute && accessor.Parameters.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tdecl.Attributes.AddRange(ConvertAttributes(accessor.Parameters.Last().GetAttributes(), \"param\"));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (this.ShowAccessibility && accessor.Accessibility != ownerAccessibility)\n\t\t\t\tdecl.Modifiers = ModifierFromAccessibility(accessor.Accessibility, UsePrivateProtectedAccessibility);\n\t\t\tif (this.ShowModifiers && accessor.HasReadonlyModifier())\n\t\t\t\tdecl.Modifiers |= Modifiers.Readonly;\n\t\t\tTokenRole keywordRole = kind switch {\n\t\t\t\tMethodSemanticsAttributes.Getter => PropertyDeclaration.GetKeywordRole,\n\t\t\t\tMethodSemanticsAttributes.Setter => PropertyDeclaration.SetKeywordRole,\n\t\t\t\tMethodSemanticsAttributes.Adder => CustomEventDeclaration.AddKeywordRole,\n\t\t\t\tMethodSemanticsAttributes.Remover => CustomEventDeclaration.RemoveKeywordRole,\n\t\t\t\t_ => null\n\t\t\t};\n\t\t\tif (kind == MethodSemanticsAttributes.Setter && SupportInitAccessors && accessor.IsInitOnly)\n\t\t\t{\n\t\t\t\tkeywordRole = PropertyDeclaration.InitKeywordRole;\n\t\t\t}\n\t\t\tif (keywordRole != null)\n\t\t\t{\n\t\t\t\tdecl.AddChild(new CSharpTokenNode(TextLocation.Empty, keywordRole), keywordRole);\n\t\t\t}\n\t\t\tif (accessor.IsInitOnly && keywordRole != PropertyDeclaration.InitKeywordRole)\n\t\t\t{\n\t\t\t\tdecl.AddChild(new Comment(\"init\", CommentType.MultiLine), Roles.Comment);\n\t\t\t}\n\t\t\tif (AddResolveResultAnnotations)\n\t\t\t{\n\t\t\t\tdecl.AddAnnotation(new MemberResolveResult(null, accessor));\n\t\t\t}\n\t\t\tif (GenerateBody)\n\t\t\t{\n\t\t\t\tdecl.Body = GenerateBodyBlock();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tdecl.AddChild(new CSharpTokenNode(TextLocation.Empty, Roles.Semicolon), Roles.Semicolon);\n\t\t\t}\n\t\t\treturn decl;\n\t\t}\n\n\t\tPropertyDeclaration ConvertProperty(IProperty property)\n\t\t{\n\t\t\tPropertyDeclaration decl = new PropertyDeclaration();\n\t\t\tdecl.Modifiers = GetMemberModifiers(property);\n\t\t\tif (ShowAttributes)\n\t\t\t{\n\t\t\t\tdecl.Attributes.AddRange(ConvertAttributes(property.GetAttributes()));\n\t\t\t}\n\t\t\tif (AddResolveResultAnnotations)\n\t\t\t{\n\t\t\t\tdecl.AddAnnotation(new MemberResolveResult(null, property));\n\t\t\t}\n\t\t\tdecl.ReturnType = ConvertType(property.ReturnType);\n\t\t\tif (property.ReturnTypeIsRefReadOnly && decl.ReturnType is ComposedType ct && ct.HasRefSpecifier)\n\t\t\t{\n\t\t\t\tct.HasReadOnlySpecifier = true;\n\t\t\t}\n\t\t\tdecl.Name = property.Name;\n\t\t\tdecl.Getter = ConvertAccessor(property.Getter, MethodSemanticsAttributes.Getter, property.Accessibility, false);\n\t\t\tdecl.Setter = ConvertAccessor(property.Setter, MethodSemanticsAttributes.Setter, property.Accessibility, true);\n\t\t\tdecl.PrivateImplementationType = GetExplicitInterfaceType(property);\n\t\t\tMergeReadOnlyModifiers(decl, decl.Getter, decl.Setter);\n\t\t\treturn decl;\n\t\t}\n\n\t\tstatic void MergeReadOnlyModifiers(EntityDeclaration decl, Accessor accessor1, Accessor accessor2)\n\t\t{\n\t\t\tif (accessor1.HasModifier(Modifiers.Readonly) && accessor2.IsNull)\n\t\t\t{\n\t\t\t\taccessor1.Modifiers &= ~Modifiers.Readonly;\n\t\t\t\tdecl.Modifiers |= Modifiers.Readonly;\n\t\t\t}\n\t\t\telse if (accessor1.HasModifier(Modifiers.Readonly) && accessor2.HasModifier(Modifiers.Readonly))\n\t\t\t{\n\t\t\t\taccessor1.Modifiers &= ~Modifiers.Readonly;\n\t\t\t\taccessor2.Modifiers &= ~Modifiers.Readonly;\n\t\t\t\tdecl.Modifiers |= Modifiers.Readonly;\n\t\t\t}\n\t\t}\n\n\t\tIndexerDeclaration ConvertIndexer(IProperty indexer)\n\t\t{\n\t\t\tIndexerDeclaration decl = new IndexerDeclaration();\n\t\t\tdecl.Modifiers = GetMemberModifiers(indexer);\n\t\t\tif (ShowAttributes)\n\t\t\t{\n\t\t\t\tdecl.Attributes.AddRange(ConvertAttributes(indexer.GetAttributes()));\n\t\t\t}\n\t\t\tif (AddResolveResultAnnotations)\n\t\t\t{\n\t\t\t\tdecl.AddAnnotation(new MemberResolveResult(null, indexer));\n\t\t\t}\n\t\t\tdecl.ReturnType = ConvertType(indexer.ReturnType);\n\t\t\tif (indexer.ReturnTypeIsRefReadOnly && decl.ReturnType is ComposedType ct && ct.HasRefSpecifier)\n\t\t\t{\n\t\t\t\tct.HasReadOnlySpecifier = true;\n\t\t\t}\n\t\t\tforeach (IParameter p in indexer.Parameters)\n\t\t\t{\n\t\t\t\tdecl.Parameters.Add(ConvertParameter(p));\n\t\t\t}\n\t\t\tdecl.Getter = ConvertAccessor(indexer.Getter, MethodSemanticsAttributes.Getter, indexer.Accessibility, false);\n\t\t\tdecl.Setter = ConvertAccessor(indexer.Setter, MethodSemanticsAttributes.Setter, indexer.Accessibility, true);\n\t\t\tdecl.PrivateImplementationType = GetExplicitInterfaceType(indexer);\n\t\t\tMergeReadOnlyModifiers(decl, decl.Getter, decl.Setter);\n\t\t\treturn decl;\n\t\t}\n\n\t\tEntityDeclaration ConvertEvent(IEvent ev)\n\t\t{\n\t\t\tif (this.UseCustomEvents)\n\t\t\t{\n\t\t\t\tCustomEventDeclaration decl = new CustomEventDeclaration();\n\t\t\t\tdecl.Modifiers = GetMemberModifiers(ev);\n\t\t\t\tif (ShowAttributes)\n\t\t\t\t{\n\t\t\t\t\tdecl.Attributes.AddRange(ConvertAttributes(ev.GetAttributes()));\n\t\t\t\t}\n\t\t\t\tif (AddResolveResultAnnotations)\n\t\t\t\t{\n\t\t\t\t\tdecl.AddAnnotation(new MemberResolveResult(null, ev));\n\t\t\t\t}\n\t\t\t\tdecl.ReturnType = ConvertType(ev.ReturnType);\n\t\t\t\tdecl.Name = ev.Name;\n\t\t\t\tdecl.AddAccessor = ConvertAccessor(ev.AddAccessor, MethodSemanticsAttributes.Adder, ev.Accessibility, true);\n\t\t\t\tdecl.RemoveAccessor = ConvertAccessor(ev.RemoveAccessor, MethodSemanticsAttributes.Remover, ev.Accessibility, true);\n\t\t\t\tdecl.PrivateImplementationType = GetExplicitInterfaceType(ev);\n\t\t\t\tMergeReadOnlyModifiers(decl, decl.AddAccessor, decl.RemoveAccessor);\n\t\t\t\treturn decl;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tEventDeclaration decl = new EventDeclaration();\n\t\t\t\tdecl.Modifiers = GetMemberModifiers(ev);\n\t\t\t\tif (ShowAttributes)\n\t\t\t\t{\n\t\t\t\t\tdecl.Attributes.AddRange(ConvertAttributes(ev.GetAttributes()));\n\t\t\t\t}\n\t\t\t\tif (AddResolveResultAnnotations)\n\t\t\t\t{\n\t\t\t\t\tdecl.AddAnnotation(new MemberResolveResult(null, ev));\n\t\t\t\t}\n\t\t\t\tdecl.ReturnType = ConvertType(ev.ReturnType);\n\t\t\t\tdecl.Variables.Add(new VariableInitializer(ev.Name));\n\t\t\t\treturn decl;\n\t\t\t}\n\t\t}\n\n\t\tMethodDeclaration ConvertMethod(IMethod method)\n\t\t{\n\t\t\tMethodDeclaration decl = new MethodDeclaration();\n\t\t\tdecl.Modifiers = GetMemberModifiers(method);\n\t\t\tif (ShowAttributes)\n\t\t\t{\n\t\t\t\tdecl.Attributes.AddRange(ConvertAttributes(method.GetAttributes()));\n\t\t\t\tdecl.Attributes.AddRange(ConvertAttributes(method.GetReturnTypeAttributes(), \"return\"));\n\t\t\t}\n\t\t\tif (AddResolveResultAnnotations)\n\t\t\t{\n\t\t\t\tdecl.AddAnnotation(new MemberResolveResult(null, method));\n\t\t\t}\n\t\t\tdecl.ReturnType = ConvertType(method.ReturnType);\n\t\t\tif (method.ReturnTypeIsRefReadOnly && decl.ReturnType is ComposedType ct && ct.HasRefSpecifier)\n\t\t\t{\n\t\t\t\tct.HasReadOnlySpecifier = true;\n\t\t\t}\n\t\t\tdecl.Name = method.Name;\n\n\t\t\tif (this.ShowTypeParameters)\n\t\t\t{\n\t\t\t\tforeach (ITypeParameter tp in method.TypeParameters)\n\t\t\t\t{\n\t\t\t\t\tdecl.TypeParameters.Add(ConvertTypeParameter(tp));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach (IParameter p in method.Parameters)\n\t\t\t{\n\t\t\t\tdecl.Parameters.Add(ConvertParameter(p));\n\t\t\t}\n\t\t\tif (method.IsExtensionMethod && method.ReducedFrom == null && decl.Parameters.Any())\n\t\t\t\tdecl.Parameters.First().HasThisModifier = true;\n\n\t\t\tif (this.ShowTypeParameters && this.ShowTypeParameterConstraints && !method.IsOverride && !method.IsExplicitInterfaceImplementation)\n\t\t\t{\n\t\t\t\tforeach (ITypeParameter tp in method.TypeParameters)\n\t\t\t\t{\n\t\t\t\t\tvar constraint = ConvertTypeParameterConstraint(tp);\n\t\t\t\t\tif (constraint != null)\n\t\t\t\t\t\tdecl.Constraints.Add(constraint);\n\t\t\t\t}\n\t\t\t}\n\t\t\tdecl.Body = GenerateBodyBlock();\n\t\t\tdecl.PrivateImplementationType = GetExplicitInterfaceType(method);\n\t\t\treturn decl;\n\t\t}\n\n\t\tEntityDeclaration ConvertOperator(IMethod op)\n\t\t{\n\t\t\tint dot = op.Name.LastIndexOf('.');\n\t\t\tstring name = op.Name.Substring(dot + 1);\n\t\t\tOperatorType? opType = OperatorDeclaration.GetOperatorType(name);\n\t\t\tif (opType == null)\n\t\t\t\treturn ConvertMethod(op);\n\t\t\tif (opType == OperatorType.UnsignedRightShift && !SupportUnsignedRightShift)\n\t\t\t\treturn ConvertMethod(op);\n\t\t\tif (!SupportOperatorChecked && OperatorDeclaration.IsChecked(opType.Value))\n\t\t\t\treturn ConvertMethod(op);\n\n\t\t\tOperatorDeclaration decl = new OperatorDeclaration();\n\t\t\tdecl.Modifiers = GetMemberModifiers(op);\n\t\t\tdecl.OperatorType = opType.Value;\n\t\t\tdecl.ReturnType = ConvertType(op.ReturnType);\n\t\t\tif (op.ReturnTypeIsRefReadOnly && decl.ReturnType is ComposedType ct && ct.HasRefSpecifier)\n\t\t\t{\n\t\t\t\tct.HasReadOnlySpecifier = true;\n\t\t\t}\n\t\t\tforeach (IParameter p in op.Parameters)\n\t\t\t{\n\t\t\t\tdecl.Parameters.Add(ConvertParameter(p));\n\t\t\t}\n\t\t\tif (ShowAttributes)\n\t\t\t{\n\t\t\t\tdecl.Attributes.AddRange(ConvertAttributes(op.GetAttributes()));\n\t\t\t\tdecl.Attributes.AddRange(ConvertAttributes(op.GetReturnTypeAttributes(), \"return\"));\n\t\t\t}\n\t\t\tif (AddResolveResultAnnotations)\n\t\t\t{\n\t\t\t\tdecl.AddAnnotation(new MemberResolveResult(null, op));\n\t\t\t}\n\t\t\tdecl.Body = GenerateBodyBlock();\n\t\t\tdecl.PrivateImplementationType = GetExplicitInterfaceType(op);\n\t\t\treturn decl;\n\t\t}\n\n\t\tConstructorDeclaration ConvertConstructor(IMethod ctor)\n\t\t{\n\t\t\tConstructorDeclaration decl = new ConstructorDeclaration();\n\t\t\tdecl.Modifiers = GetMemberModifiers(ctor);\n\t\t\tif (ShowAttributes)\n\t\t\t\tdecl.Attributes.AddRange(ConvertAttributes(ctor.GetAttributes()));\n\t\t\tif (ctor.DeclaringTypeDefinition != null)\n\t\t\t\tdecl.Name = ctor.DeclaringTypeDefinition.Name;\n\t\t\tforeach (IParameter p in ctor.Parameters)\n\t\t\t{\n\t\t\t\tdecl.Parameters.Add(ConvertParameter(p));\n\t\t\t}\n\t\t\tif (AddResolveResultAnnotations)\n\t\t\t{\n\t\t\t\tdecl.AddAnnotation(new MemberResolveResult(null, ctor));\n\t\t\t}\n\t\t\tdecl.Body = GenerateBodyBlock();\n\t\t\treturn decl;\n\t\t}\n\n\t\tDestructorDeclaration ConvertDestructor(IMethod dtor)\n\t\t{\n\t\t\tDestructorDeclaration decl = new DestructorDeclaration();\n\t\t\tif (ShowAttributes)\n\t\t\t\tdecl.Attributes.AddRange(ConvertAttributes(dtor.GetAttributes()));\n\t\t\tif (dtor.DeclaringTypeDefinition != null)\n\t\t\t\tdecl.Name = dtor.DeclaringTypeDefinition.Name;\n\t\t\tif (AddResolveResultAnnotations)\n\t\t\t{\n\t\t\t\tdecl.AddAnnotation(new MemberResolveResult(null, dtor));\n\t\t\t}\n\t\t\tdecl.Body = GenerateBodyBlock();\n\t\t\treturn decl;\n\t\t}\n\t\t#endregion\n\n\t\t#region Convert Modifiers\n\t\tpublic static Modifiers ModifierFromAccessibility(Accessibility accessibility, bool usePrivateProtected)\n\t\t{\n\t\t\tswitch (accessibility)\n\t\t\t{\n\t\t\t\tcase Accessibility.Private:\n\t\t\t\t\treturn Modifiers.Private;\n\t\t\t\tcase Accessibility.Public:\n\t\t\t\t\treturn Modifiers.Public;\n\t\t\t\tcase Accessibility.Protected:\n\t\t\t\t\treturn Modifiers.Protected;\n\t\t\t\tcase Accessibility.Internal:\n\t\t\t\t\treturn Modifiers.Internal;\n\t\t\t\tcase Accessibility.ProtectedOrInternal:\n\t\t\t\t\treturn Modifiers.Protected | Modifiers.Internal;\n\t\t\t\tcase Accessibility.ProtectedAndInternal:\n\t\t\t\t\treturn usePrivateProtected ? Modifiers.Private | Modifiers.Protected : Modifiers.Protected;\n\t\t\t\tdefault:\n\t\t\t\t\treturn Modifiers.None;\n\t\t\t}\n\t\t}\n\n\t\tbool NeedsAccessibility(IMember member)\n\t\t{\n\t\t\tvar declaringType = member.DeclaringType;\n\t\t\tif (member.IsExplicitInterfaceImplementation)\n\t\t\t\treturn false;\n\t\t\tswitch (member.SymbolKind)\n\t\t\t{\n\t\t\t\tcase SymbolKind.Constructor:\n\t\t\t\t\treturn !member.IsStatic;\n\t\t\t\tcase SymbolKind.Destructor:\n\t\t\t\t\treturn false;\n\t\t\t\tdefault:\n\t\t\t\t\tif (declaringType?.Kind == TypeKind.Interface)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn member.Accessibility != Accessibility.Public;\n\t\t\t\t\t}\n\t\t\t\t\treturn member is not IMethod method || !method.IsLocalFunction;\n\t\t\t}\n\t\t}\n\n\t\tModifiers GetMemberModifiers(IMember member)\n\t\t{\n\t\t\tModifiers m = Modifiers.None;\n\t\t\tif (this.ShowAccessibility && NeedsAccessibility(member))\n\t\t\t{\n\t\t\t\tm |= ModifierFromAccessibility(member.Accessibility, UsePrivateProtectedAccessibility);\n\t\t\t}\n\t\t\tif (this.ShowModifiers)\n\t\t\t{\n\t\t\t\tif (member is LocalFunctionMethod localFunction)\n\t\t\t\t{\n\t\t\t\t\tif (localFunction.IsStaticLocalFunction)\n\t\t\t\t\t{\n\t\t\t\t\t\tm |= Modifiers.Static;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (member.IsStatic)\n\t\t\t\t\t{\n\t\t\t\t\t\tm |= Modifiers.Static;\n\t\t\t\t\t}\n\t\t\t\t\tif (member is IMethod method && method.ThisIsRefReadOnly\n\t\t\t\t\t\t&& method.DeclaringTypeDefinition?.IsReadOnly == false)\n\t\t\t\t\t{\n\t\t\t\t\t\tm |= Modifiers.Readonly;\n\t\t\t\t\t}\n\n\t\t\t\t\tvar declaringType = member.DeclaringType;\n\t\t\t\t\tif (declaringType.Kind == TypeKind.Interface)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!member.IsStatic && !member.IsVirtual && !member.IsAbstract && !member.IsOverride\n\t\t\t\t\t\t\t&& member.Accessibility != Accessibility.Private\n\t\t\t\t\t\t\t&& member is IMethod method2 && method2.HasBody)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tm |= Modifiers.Sealed;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (member.IsStatic)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// modifiers of static members in interfaces:\n\t\t\t\t\t\t\tif (member.IsAbstract)\n\t\t\t\t\t\t\t\tm |= Modifiers.Abstract;\n\t\t\t\t\t\t\telse if (member.IsVirtual && !member.IsOverride)\n\t\t\t\t\t\t\t\tm |= Modifiers.Virtual;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif (member.IsAbstract)\n\t\t\t\t\t\t\tm |= Modifiers.Abstract;\n\t\t\t\t\t\telse if (member.IsVirtual && !member.IsOverride)\n\t\t\t\t\t\t\tm |= Modifiers.Virtual;\n\t\t\t\t\t\tif (member.IsOverride && !member.IsExplicitInterfaceImplementation)\n\t\t\t\t\t\t\tm |= Modifiers.Override;\n\t\t\t\t\t\tif (member.IsSealed && !member.IsExplicitInterfaceImplementation)\n\t\t\t\t\t\t\tm |= Modifiers.Sealed;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn m;\n\t\t}\n\t\t#endregion\n\n\t\t#region Convert Type Parameter\n\t\tinternal TypeParameterDeclaration ConvertTypeParameter(ITypeParameter tp)\n\t\t{\n\t\t\tTypeParameterDeclaration decl = new TypeParameterDeclaration();\n\t\t\tdecl.Variance = tp.Variance;\n\t\t\tdecl.Name = tp.Name;\n\t\t\tif (ShowAttributes)\n\t\t\t\tdecl.Attributes.AddRange(ConvertAttributes(tp.GetAttributes()));\n\t\t\treturn decl;\n\t\t}\n\n\t\tinternal Constraint ConvertTypeParameterConstraint(ITypeParameter tp)\n\t\t{\n\t\t\tif (!tp.HasDefaultConstructorConstraint && !tp.HasReferenceTypeConstraint && !tp.HasValueTypeConstraint && !tp.AllowsRefLikeType && tp.NullabilityConstraint != Nullability.NotNullable && tp.DirectBaseTypes.All(IsObjectOrValueType))\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tConstraint c = new Constraint();\n\t\t\tc.TypeParameter = MakeSimpleType(tp.Name);\n\t\t\tif (tp.HasReferenceTypeConstraint)\n\t\t\t{\n\t\t\t\tif (tp.NullabilityConstraint == Nullability.Nullable)\n\t\t\t\t{\n\t\t\t\t\tc.BaseTypes.Add(new PrimitiveType(\"class\").MakeNullableType());\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tc.BaseTypes.Add(new PrimitiveType(\"class\"));\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (tp.HasValueTypeConstraint)\n\t\t\t{\n\t\t\t\tif (tp.HasUnmanagedConstraint)\n\t\t\t\t{\n\t\t\t\t\tc.BaseTypes.Add(new PrimitiveType(\"unmanaged\"));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tc.BaseTypes.Add(new PrimitiveType(\"struct\"));\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (tp.NullabilityConstraint == Nullability.NotNullable)\n\t\t\t{\n\t\t\t\tc.BaseTypes.Add(new PrimitiveType(\"notnull\"));\n\t\t\t}\n\t\t\tforeach (TypeConstraint t in tp.TypeConstraints)\n\t\t\t{\n\t\t\t\tif (!IsObjectOrValueType(t.Type) || t.Attributes.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tAstType astType = ConvertType(t.Type);\n\t\t\t\t\tif (t.Attributes.Count > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar attrSection = new AttributeSection();\n\t\t\t\t\t\tattrSection.Attributes.AddRange(t.Attributes.Select(ConvertAttribute));\n\t\t\t\t\t\tastType = new ComposedType {\n\t\t\t\t\t\t\tAttributes = { attrSection },\n\t\t\t\t\t\t\tBaseType = astType\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tc.BaseTypes.Add(astType);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (tp.HasDefaultConstructorConstraint && !tp.HasValueTypeConstraint)\n\t\t\t{\n\t\t\t\tc.BaseTypes.Add(new PrimitiveType(\"new\"));\n\t\t\t}\n\t\t\tif (tp.AllowsRefLikeType)\n\t\t\t{\n\t\t\t\tc.BaseTypes.Add(new PrimitiveType(\"allows ref struct\"));\n\t\t\t}\n\t\t\treturn c;\n\t\t}\n\n\t\tstatic bool IsObjectOrValueType(IType type)\n\t\t{\n\t\t\tITypeDefinition d = type.GetDefinition();\n\t\t\treturn d != null && (d.KnownTypeCode == KnownTypeCode.Object || d.KnownTypeCode == KnownTypeCode.ValueType);\n\t\t}\n\t\t#endregion\n\n\t\t#region Convert Variable\n\t\tpublic VariableDeclarationStatement ConvertVariable(IVariable v)\n\t\t{\n\t\t\tVariableDeclarationStatement decl = new VariableDeclarationStatement();\n\t\t\tdecl.Modifiers = v.IsConst ? Modifiers.Const : Modifiers.None;\n\t\t\tdecl.Type = ConvertType(v.Type);\n\t\t\tExpression initializer = null;\n\t\t\tif (v.IsConst)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tinitializer = ConvertConstantValue(v.Type, v.GetConstantValue(throwOnInvalidMetadata: true));\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException ex)\n\t\t\t\t{\n\t\t\t\t\tinitializer = new ErrorExpression(ex.Message);\n\t\t\t\t}\n\t\t\t}\n\t\t\tdecl.Variables.Add(new VariableInitializer(v.Name, initializer));\n\t\t\treturn decl;\n\t\t}\n\t\t#endregion\n\n\t\tNamespaceDeclaration ConvertNamespaceDeclaration(INamespace ns)\n\t\t{\n\t\t\treturn new NamespaceDeclaration(ns.FullName);\n\t\t}\n\n\t\tAstType GetExplicitInterfaceType(IMember member)\n\t\t{\n\t\t\tif (member.IsExplicitInterfaceImplementation)\n\t\t\t{\n\t\t\t\tvar baseMember = member.ExplicitlyImplementedInterfaceMembers.FirstOrDefault();\n\t\t\t\tif (baseMember != null)\n\t\t\t\t\treturn ConvertType(baseMember.DeclaringType);\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Syntax/VariableDesignation.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\n\nnamespace ICSharpCode.Decompiler.CSharp.Syntax\n{\n\tpublic abstract class VariableDesignation : AstNode\n\t{\n\t\tpublic override NodeType NodeType => NodeType.Unknown;\n\n\t\t#region Null\n\t\tpublic new static readonly VariableDesignation Null = new NullVariableDesignation();\n\n\t\tsealed class NullVariableDesignation : VariableDesignation\n\t\t{\n\t\t\tpublic override bool IsNull {\n\t\t\t\tget {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t\t{\n\t\t\t\tvisitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this);\n\t\t\t}\n\n\t\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t\t{\n\t\t\t\treturn visitor.VisitNullNode(this, data);\n\t\t\t}\n\n\t\t\tprotected internal override bool DoMatch(AstNode other, PatternMatching.Match match)\n\t\t\t{\n\t\t\t\treturn other == null || other.IsNull;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t}\n\n\t/// <summary>\n\t/// Identifier\n\t/// </summary>\n\tpublic class SingleVariableDesignation : VariableDesignation\n\t{\n\n\t\tpublic string Identifier {\n\t\t\tget { return GetChildByRole(Roles.Identifier).Name; }\n\t\t\tset { SetChildByRole(Roles.Identifier, Syntax.Identifier.Create(value)); }\n\t\t}\n\n\t\tpublic Identifier IdentifierToken {\n\t\t\tget { return GetChildByRole(Roles.Identifier); }\n\t\t\tset { SetChildByRole(Roles.Identifier, value); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitSingleVariableDesignation(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitSingleVariableDesignation(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitSingleVariableDesignation(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, Match match)\n\t\t{\n\t\t\treturn other is SingleVariableDesignation o && MatchString(this.Identifier, o.Identifier);\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// ( VariableDesignation (, VariableDesignation)* )\n\t/// </summary>\n\tpublic class ParenthesizedVariableDesignation : VariableDesignation\n\t{\n\n\t\tpublic CSharpTokenNode LParToken {\n\t\t\tget { return GetChildByRole(Roles.LPar); }\n\t\t}\n\n\t\tpublic AstNodeCollection<VariableDesignation> VariableDesignations {\n\t\t\tget { return GetChildrenByRole(Roles.VariableDesignationRole); }\n\t\t}\n\n\t\tpublic CSharpTokenNode RParToken {\n\t\t\tget { return GetChildByRole(Roles.RPar); }\n\t\t}\n\n\t\tpublic override void AcceptVisitor(IAstVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitParenthesizedVariableDesignation(this);\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(IAstVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitParenthesizedVariableDesignation(this);\n\t\t}\n\n\t\tpublic override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)\n\t\t{\n\t\t\treturn visitor.VisitParenthesizedVariableDesignation(this, data);\n\t\t}\n\n\t\tprotected internal override bool DoMatch(AstNode other, Match match)\n\t\t{\n\t\t\treturn other is ParenthesizedVariableDesignation o && VariableDesignations.DoMatch(o.VariableDesignations, match);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/AddCheckedBlocks.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\t/// <summary>\n\t/// Add checked/unchecked blocks.\n\t/// </summary>\n\tpublic class AddCheckedBlocks : IAstTransform\n\t{\n\t\t#region Annotation\n\t\tsealed class CheckedUncheckedAnnotation\n\t\t{\n\t\t\t/// <summary>\n\t\t\t/// true=checked, false=unchecked\n\t\t\t/// </summary>\n\t\t\tpublic bool IsChecked;\n\n\t\t\t/// <summary>\n\t\t\t/// Require an explicit unchecked block (can't rely on the project-level unchecked context)\n\t\t\t/// </summary>\n\t\t\tpublic bool IsExplicit;\n\t\t}\n\n\t\tpublic static readonly object CheckedAnnotation = new CheckedUncheckedAnnotation { IsChecked = true };\n\t\tpublic static readonly object UncheckedAnnotation = new CheckedUncheckedAnnotation { IsChecked = false };\n\t\tpublic static readonly object ExplicitUncheckedAnnotation = new CheckedUncheckedAnnotation { IsChecked = false, IsExplicit = true };\n\t\t#endregion\n\n\t\t/* \n\t\t\tWe treat placing checked/unchecked blocks as an optimization problem, with the following goals:\n\t\t\t\t1. Use minimum number of checked blocks+expressions\n\t\t\t\t2. Prefer checked expressions over checked blocks\n\t\t\t\t3. Make the scope of checked expressions as small as possible\n\t\t\t\t4. Open checked blocks as late as possible, and close checked blocks as late as possible\n\t\t\t\t(where goal 1 has the highest priority)\n\t\t\t\t\n\t\t\t\tGoal 4a (open checked blocks as late as possible) is necessary so that we don't move variable declarations\n\t\t\t\t  into checked blocks, as the variable might still be used after the checked block.\n\t\t\t\t  (this could cause DeclareVariables to omit the variable declaration, producing incorrect code)\n\t\t\t\tGoal 4b (close checked blocks as late as possible) makes the code look nicer in this case:\n\t\t\t\t\tchecked {\n\t\t\t\t\t\tint c = a + b;\n\t\t\t\t\t\tint r = a + c;\n\t\t\t\t\t\treturn r;\n\t\t\t\t\t}\n\t\t\t\tIf the checked block was closed as early as possible, the variable r would have to be declared outside\n\t\t\t\t  (this would work, but look badly)\n\t\t */\n\n\t\t#region struct Cost\n\t\tstruct Cost\n\t\t{\n\t\t\t// highest possible cost so that the Blocks+Expressions addition doesn't overflow\n\t\t\tpublic static readonly Cost Infinite = new Cost(0x3fffffff, 0x3fffffff);\n\n\t\t\tpublic readonly int Blocks;\n\t\t\tpublic readonly int Expressions;\n\n\t\t\tpublic Cost(int blocks, int expressions)\n\t\t\t{\n\t\t\t\tthis.Blocks = blocks;\n\t\t\t\tthis.Expressions = expressions;\n\t\t\t}\n\n\t\t\tpublic static bool operator <(Cost a, Cost b)\n\t\t\t{\n\t\t\t\treturn a.Blocks + a.Expressions < b.Blocks + b.Expressions\n\t\t\t\t\t|| a.Blocks + a.Expressions == b.Blocks + b.Expressions && a.Blocks < b.Blocks;\n\t\t\t}\n\n\t\t\tpublic static bool operator >(Cost a, Cost b)\n\t\t\t{\n\t\t\t\treturn a.Blocks + a.Expressions > b.Blocks + b.Expressions\n\t\t\t\t\t|| a.Blocks + a.Expressions == b.Blocks + b.Expressions && a.Blocks > b.Blocks;\n\t\t\t}\n\n\t\t\tpublic static bool operator <=(Cost a, Cost b)\n\t\t\t{\n\t\t\t\treturn a.Blocks + a.Expressions < b.Blocks + b.Expressions\n\t\t\t\t\t|| a.Blocks + a.Expressions == b.Blocks + b.Expressions && a.Blocks <= b.Blocks;\n\t\t\t}\n\n\t\t\tpublic static bool operator >=(Cost a, Cost b)\n\t\t\t{\n\t\t\t\treturn a.Blocks + a.Expressions > b.Blocks + b.Expressions\n\t\t\t\t\t|| a.Blocks + a.Expressions == b.Blocks + b.Expressions && a.Blocks >= b.Blocks;\n\t\t\t}\n\n\t\t\tpublic static Cost operator +(Cost a, Cost b)\n\t\t\t{\n\t\t\t\treturn new Cost(a.Blocks + b.Blocks, a.Expressions + b.Expressions);\n\t\t\t}\n\n\t\t\tpublic override string ToString()\n\t\t\t{\n\t\t\t\treturn string.Format(\"[{0} + {1}]\", Blocks, Expressions);\n\t\t\t}\n\n\t\t\t/// <summary>\n\t\t\t/// Gets the new cost if an expression with this cost is wrapped in a checked/unchecked expression.\n\t\t\t/// </summary>\n\t\t\tinternal Cost WrapInCheckedExpr()\n\t\t\t{\n\t\t\t\tif (Expressions == 0)\n\t\t\t\t{\n\t\t\t\t\treturn new Cost(Blocks, 1);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// hack: penalize multiple layers of nested expressions\n\t\t\t\t\t// This doesn't really fit into the original idea of minimizing the number of block+expressions;\n\t\t\t\t\t// but tends to produce better-looking results due to less nesting.\n\t\t\t\t\treturn new Cost(Blocks, Expressions + 2);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region class InsertedNode\n\t\t/// <summary>\n\t\t/// Holds the blocks and expressions that should be inserted\n\t\t/// </summary>\n\t\tabstract class InsertedNode\n\t\t{\n\t\t\tpublic static InsertedNode operator +(InsertedNode a, InsertedNode b)\n\t\t\t{\n\t\t\t\tif (a == null)\n\t\t\t\t\treturn b;\n\t\t\t\tif (b == null)\n\t\t\t\t\treturn a;\n\t\t\t\treturn new InsertedNodeList(a, b);\n\t\t\t}\n\n\t\t\tpublic abstract void Insert();\n\t\t}\n\n\t\tclass InsertedNodeList : InsertedNode\n\t\t{\n\t\t\treadonly InsertedNode child1, child2;\n\n\t\t\tpublic InsertedNodeList(AddCheckedBlocks.InsertedNode child1, AddCheckedBlocks.InsertedNode child2)\n\t\t\t{\n\t\t\t\tthis.child1 = child1;\n\t\t\t\tthis.child2 = child2;\n\t\t\t}\n\n\t\t\tpublic override void Insert()\n\t\t\t{\n\t\t\t\tchild1.Insert();\n\t\t\t\tchild2.Insert();\n\t\t\t}\n\t\t}\n\n\t\tclass InsertedExpression : InsertedNode\n\t\t{\n\t\t\treadonly Expression expression;\n\t\t\treadonly bool isChecked;\n\n\t\t\tpublic InsertedExpression(Expression expression, bool isChecked)\n\t\t\t{\n\t\t\t\tthis.expression = expression;\n\t\t\t\tthis.isChecked = isChecked;\n\t\t\t}\n\n\t\t\tpublic override void Insert()\n\t\t\t{\n\t\t\t\tif (isChecked)\n\t\t\t\t\texpression.ReplaceWith(e => new CheckedExpression { Expression = e });\n\t\t\t\telse\n\t\t\t\t\texpression.ReplaceWith(e => new UncheckedExpression { Expression = e });\n\t\t\t}\n\t\t}\n\n\t\tclass InsertedBlock : InsertedNode\n\t\t{\n\t\t\treadonly Statement firstStatement; // inclusive\n\t\t\treadonly Statement lastStatement; // exclusive\n\t\t\treadonly bool isChecked;\n\n\t\t\tpublic InsertedBlock(Statement firstStatement, Statement lastStatement, bool isChecked)\n\t\t\t{\n\t\t\t\tthis.firstStatement = firstStatement;\n\t\t\t\tthis.lastStatement = lastStatement;\n\t\t\t\tthis.isChecked = isChecked;\n\t\t\t}\n\n\t\t\tpublic override void Insert()\n\t\t\t{\n\t\t\t\tBlockStatement newBlock = new BlockStatement();\n\t\t\t\t// Move all statements except for the first\n\t\t\t\tStatement next;\n\t\t\t\tfor (Statement stmt = firstStatement.GetNextStatement(); stmt != lastStatement; stmt = next)\n\t\t\t\t{\n\t\t\t\t\tnext = stmt.GetNextStatement();\n\t\t\t\t\tnewBlock.Add(stmt.Detach());\n\t\t\t\t}\n\t\t\t\t// Replace the first statement with the new (un)checked block\n\t\t\t\tif (isChecked)\n\t\t\t\t\tfirstStatement.ReplaceWith(new CheckedStatement { Body = newBlock });\n\t\t\t\telse\n\t\t\t\t\tfirstStatement.ReplaceWith(new UncheckedStatement { Body = newBlock });\n\t\t\t\t// now also move the first node into the new block\n\t\t\t\tnewBlock.Statements.InsertAfter(null, firstStatement);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region class Result\n\t\t/// <summary>\n\t\t/// Holds the result of an insertion operation.\n\t\t/// </summary>\n\t\tclass Result\n\t\t{\n\t\t\tpublic Cost CostInCheckedContext;\n\t\t\tpublic InsertedNode NodesToInsertInCheckedContext;\n\t\t\tpublic Cost CostInUncheckedContext;\n\t\t\tpublic InsertedNode NodesToInsertInUncheckedContext;\n\t\t}\n\t\t#endregion\n\n\t\tpublic void Run(AstNode node, TransformContext context)\n\t\t{\n\t\t\tBlockStatement block = node as BlockStatement;\n\t\t\tif (block == null)\n\t\t\t{\n\t\t\t\tfor (AstNode child = node.FirstChild; child != null; child = child.NextSibling)\n\t\t\t\t{\n\t\t\t\t\tRun(child, context);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tResult r = GetResultFromBlock(block);\n\t\t\t\tif (context.DecompileRun.Settings.CheckForOverflowUnderflow)\n\t\t\t\t{\n\t\t\t\t\tr.NodesToInsertInCheckedContext?.Insert();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tr.NodesToInsertInUncheckedContext?.Insert();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tResult GetResultFromBlock(BlockStatement block)\n\t\t{\n\t\t\t// For a block, we are tracking 4 possibilities:\n\t\t\t// a) context is checked, no unchecked block open\n\t\t\tCost costCheckedContext = new Cost(0, 0);\n\t\t\tInsertedNode nodesCheckedContext = null;\n\t\t\t// b) context is checked, an unchecked block is open\n\t\t\tCost costCheckedContextUncheckedBlockOpen = Cost.Infinite;\n\t\t\tInsertedNode nodesCheckedContextUncheckedBlockOpen = null;\n\t\t\tStatement uncheckedBlockStart = null;\n\t\t\t// c) context is unchecked, no checked block open\n\t\t\tCost costUncheckedContext = new Cost(0, 0);\n\t\t\tInsertedNode nodesUncheckedContext = null;\n\t\t\t// d) context is unchecked, a checked block is open\n\t\t\tCost costUncheckedContextCheckedBlockOpen = Cost.Infinite;\n\t\t\tInsertedNode nodesUncheckedContextCheckedBlockOpen = null;\n\t\t\tStatement checkedBlockStart = null;\n\n\t\t\tStatement statement = block.Statements.FirstOrDefault();\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\t// Blocks can be closed 'for free'. We use '<=' so that blocks are closed as late as possible (goal 4b)\n\t\t\t\tif (costCheckedContextUncheckedBlockOpen <= costCheckedContext)\n\t\t\t\t{\n\t\t\t\t\tcostCheckedContext = costCheckedContextUncheckedBlockOpen;\n\t\t\t\t\tnodesCheckedContext = nodesCheckedContextUncheckedBlockOpen + new InsertedBlock(uncheckedBlockStart, statement, false);\n\t\t\t\t}\n\t\t\t\tif (costUncheckedContextCheckedBlockOpen <= costUncheckedContext)\n\t\t\t\t{\n\t\t\t\t\tcostUncheckedContext = costUncheckedContextCheckedBlockOpen;\n\t\t\t\t\tnodesUncheckedContext = nodesUncheckedContextCheckedBlockOpen + new InsertedBlock(checkedBlockStart, statement, true);\n\t\t\t\t}\n\t\t\t\tif (statement == null)\n\t\t\t\t\tbreak;\n\t\t\t\t// Now try opening blocks. We use '<=' so that blocks are opened as late as possible. (goal 4a)\n\t\t\t\tif (costCheckedContext + new Cost(1, 0) <= costCheckedContextUncheckedBlockOpen)\n\t\t\t\t{\n\t\t\t\t\tcostCheckedContextUncheckedBlockOpen = costCheckedContext + new Cost(1, 0);\n\t\t\t\t\tnodesCheckedContextUncheckedBlockOpen = nodesCheckedContext;\n\t\t\t\t\tuncheckedBlockStart = statement;\n\t\t\t\t}\n\t\t\t\tif (costUncheckedContext + new Cost(1, 0) <= costUncheckedContextCheckedBlockOpen)\n\t\t\t\t{\n\t\t\t\t\tcostUncheckedContextCheckedBlockOpen = costUncheckedContext + new Cost(1, 0);\n\t\t\t\t\tnodesUncheckedContextCheckedBlockOpen = nodesUncheckedContext;\n\t\t\t\t\tcheckedBlockStart = statement;\n\t\t\t\t}\n\t\t\t\t// Now handle the statement\n\t\t\t\tResult stmtResult = GetResult(statement);\n\n\t\t\t\tcostCheckedContext += stmtResult.CostInCheckedContext;\n\t\t\t\tnodesCheckedContext += stmtResult.NodesToInsertInCheckedContext;\n\t\t\t\tcostCheckedContextUncheckedBlockOpen += stmtResult.CostInUncheckedContext;\n\t\t\t\tnodesCheckedContextUncheckedBlockOpen += stmtResult.NodesToInsertInUncheckedContext;\n\t\t\t\tcostUncheckedContext += stmtResult.CostInUncheckedContext;\n\t\t\t\tnodesUncheckedContext += stmtResult.NodesToInsertInUncheckedContext;\n\t\t\t\tcostUncheckedContextCheckedBlockOpen += stmtResult.CostInCheckedContext;\n\t\t\t\tnodesUncheckedContextCheckedBlockOpen += stmtResult.NodesToInsertInCheckedContext;\n\n\t\t\t\tif (statement is LabelStatement || statement is LocalFunctionDeclarationStatement)\n\t\t\t\t{\n\t\t\t\t\t// We can't move labels into blocks because that might cause goto-statements\n\t\t\t\t\t// to be unable to jump to the labels.\n\t\t\t\t\t// Also, we can't move local functions into blocks, because that might cause\n\t\t\t\t\t// them to become out of scope from the call-sites.\n\t\t\t\t\tcostCheckedContextUncheckedBlockOpen = Cost.Infinite;\n\t\t\t\t\tcostUncheckedContextCheckedBlockOpen = Cost.Infinite;\n\t\t\t\t}\n\n\t\t\t\tstatement = statement.GetNextStatement();\n\t\t\t}\n\n\t\t\treturn new Result {\n\t\t\t\tCostInCheckedContext = costCheckedContext, NodesToInsertInCheckedContext = nodesCheckedContext,\n\t\t\t\tCostInUncheckedContext = costUncheckedContext, NodesToInsertInUncheckedContext = nodesUncheckedContext\n\t\t\t};\n\t\t}\n\n\t\tResult GetResult(AstNode node)\n\t\t{\n\t\t\tif (node is BlockStatement)\n\t\t\t\treturn GetResultFromBlock((BlockStatement)node);\n\t\t\tResult result = new Result();\n\t\t\tfor (AstNode child = node.FirstChild; child != null; child = child.NextSibling)\n\t\t\t{\n\t\t\t\tResult childResult = GetResult(child);\n\t\t\t\tresult.CostInCheckedContext += childResult.CostInCheckedContext;\n\t\t\t\tresult.NodesToInsertInCheckedContext += childResult.NodesToInsertInCheckedContext;\n\t\t\t\tresult.CostInUncheckedContext += childResult.CostInUncheckedContext;\n\t\t\t\tresult.NodesToInsertInUncheckedContext += childResult.NodesToInsertInUncheckedContext;\n\t\t\t}\n\t\t\tExpression expr = node as Expression;\n\t\t\tif (expr != null)\n\t\t\t{\n\t\t\t\tCheckedUncheckedAnnotation annotation = expr.Annotation<CheckedUncheckedAnnotation>();\n\t\t\t\tif (annotation != null)\n\t\t\t\t{\n\t\t\t\t\tif (annotation.IsExplicit)\n\t\t\t\t\t{\n\t\t\t\t\t\t// We don't yet support distinguishing CostInUncheckedContext vs. CostInExplicitUncheckedContext,\n\t\t\t\t\t\t// so we always force an unchecked() expression here.\n\t\t\t\t\t\tif (annotation.IsChecked)\n\t\t\t\t\t\t\tthrow new NotImplementedException(\"explicit checked\"); // should not be needed\n\t\t\t\t\t\tresult.CostInCheckedContext = result.CostInUncheckedContext.WrapInCheckedExpr();\n\t\t\t\t\t\tresult.CostInUncheckedContext = result.CostInUncheckedContext.WrapInCheckedExpr();\n\t\t\t\t\t\tresult.NodesToInsertInUncheckedContext += new InsertedExpression(expr, annotation.IsChecked);\n\t\t\t\t\t\tresult.NodesToInsertInCheckedContext = result.NodesToInsertInUncheckedContext;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// If the annotation requires this node to be in a specific context, add a huge cost to the other context\n\t\t\t\t\t\t// That huge cost gives us the option to ignore a required checked/unchecked expression when there wouldn't be any\n\t\t\t\t\t\t// solution otherwise. (e.g. \"for (checked(M().x += 1); true; unchecked(M().x += 2)) {}\")\n\t\t\t\t\t\tif (annotation.IsChecked)\n\t\t\t\t\t\t\tresult.CostInUncheckedContext += new Cost(10000, 0);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tresult.CostInCheckedContext += new Cost(10000, 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Embed this node in an checked/unchecked expression:\n\t\t\t\tif (expr.Parent is ExpressionStatement)\n\t\t\t\t{\n\t\t\t\t\t// We cannot use checked/unchecked for top-level-expressions.\n\t\t\t\t}\n\t\t\t\telse if (expr.Role.IsValid(Expression.Null))\n\t\t\t\t{\n\t\t\t\t\t// We use '<' so that expressions are introduced on the deepest level possible (goal 3)\n\t\t\t\t\tvar costIfWrapWithChecked = result.CostInCheckedContext.WrapInCheckedExpr();\n\t\t\t\t\tvar costIfWrapWithUnchecked = result.CostInUncheckedContext.WrapInCheckedExpr();\n\t\t\t\t\tif (costIfWrapWithChecked < result.CostInUncheckedContext)\n\t\t\t\t\t{\n\t\t\t\t\t\tresult.CostInUncheckedContext = costIfWrapWithChecked;\n\t\t\t\t\t\tresult.NodesToInsertInUncheckedContext = result.NodesToInsertInCheckedContext + new InsertedExpression(expr, true);\n\t\t\t\t\t}\n\t\t\t\t\telse if (costIfWrapWithUnchecked < result.CostInCheckedContext)\n\t\t\t\t\t{\n\t\t\t\t\t\tresult.CostInCheckedContext = costIfWrapWithUnchecked;\n\t\t\t\t\t\tresult.NodesToInsertInCheckedContext = result.NodesToInsertInUncheckedContext + new InsertedExpression(expr, false);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/AddXmlDocumentationTransform.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Xml;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.Documentation;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\t/// <summary>\n\t/// Adds XML documentation for member definitions.\n\t/// </summary>\n\tpublic class AddXmlDocumentationTransform : IAstTransform\n\t{\n\t\tpublic void Run(AstNode rootNode, TransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.ShowXmlDocumentation || context.DecompileRun.DocumentationProvider == null)\n\t\t\t\treturn;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar provider = context.DecompileRun.DocumentationProvider;\n\t\t\t\tforeach (var entityDecl in rootNode.DescendantsAndSelf.OfType<EntityDeclaration>())\n\t\t\t\t{\n\t\t\t\t\tif (!(entityDecl.GetSymbol() is IEntity entity))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tstring doc = provider.GetDocumentation(entity);\n\t\t\t\t\tif (doc != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tInsertXmlDocumentation(entityDecl, new StringReader(doc));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (XmlException ex)\n\t\t\t{\n\t\t\t\tstring[] msg = (\" Exception while reading XmlDoc: \" + ex).Split(new[] { '\\r', '\\n' }, StringSplitOptions.RemoveEmptyEntries);\n\t\t\t\tvar insertionPoint = rootNode.FirstChild;\n\t\t\t\tfor (int i = 0; i < msg.Length; i++)\n\t\t\t\t\trootNode.InsertChildBefore(insertionPoint, new Comment(msg[i], CommentType.Documentation), Roles.Comment);\n\t\t\t}\n\t\t}\n\n\t\tstatic void InsertXmlDocumentation(AstNode node, StringReader r)\n\t\t{\n\t\t\t// Find the first non-empty line:\n\t\t\tstring firstLine;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tfirstLine = r.ReadLine();\n\t\t\t\tif (firstLine == null)\n\t\t\t\t\treturn;\n\t\t\t} while (string.IsNullOrWhiteSpace(firstLine));\n\t\t\tstring indentation = firstLine.Substring(0, firstLine.Length - firstLine.TrimStart().Length);\n\t\t\tstring line = firstLine;\n\t\t\tint skippedWhitespaceLines = 0;\n\t\t\t// Copy all lines from input to output, except for empty lines at the end.\n\t\t\twhile (line != null)\n\t\t\t{\n\t\t\t\tif (string.IsNullOrWhiteSpace(line))\n\t\t\t\t{\n\t\t\t\t\tskippedWhitespaceLines++;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\twhile (skippedWhitespaceLines > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tComment emptyLine = new Comment(string.Empty, CommentType.Documentation);\n\t\t\t\t\t\temptyLine.AddAnnotation(node.GetResolveResult());\n\t\t\t\t\t\tnode.Parent.InsertChildBefore(node, emptyLine, Roles.Comment);\n\t\t\t\t\t\tskippedWhitespaceLines--;\n\t\t\t\t\t}\n\t\t\t\t\tif (line.StartsWith(indentation, StringComparison.Ordinal))\n\t\t\t\t\t\tline = line.Substring(indentation.Length);\n\t\t\t\t\tComment comment = new Comment(\" \" + line, CommentType.Documentation);\n\t\t\t\t\tcomment.AddAnnotation(node.GetResolveResult());\n\t\t\t\t\tnode.Parent.InsertChildBefore(node, comment, Roles.Comment);\n\t\t\t\t}\n\t\t\t\tline = r.ReadLine();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/CombineQueryExpressions.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\t/// <summary>\n\t/// Combines query expressions and removes transparent identifiers.\n\t/// </summary>\n\tpublic class CombineQueryExpressions : IAstTransform\n\t{\n\t\tpublic void Run(AstNode rootNode, TransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.QueryExpressions)\n\t\t\t\treturn;\n\t\t\tCombineQueries(rootNode, new Dictionary<string, object>());\n\t\t}\n\n\t\tstatic readonly InvocationExpression castPattern = new InvocationExpression {\n\t\t\tTarget = new MemberReferenceExpression {\n\t\t\t\tTarget = new AnyNode(\"inExpr\"),\n\t\t\t\tMemberName = \"Cast\",\n\t\t\t\tTypeArguments = { new AnyNode(\"targetType\") }\n\t\t\t}\n\t\t};\n\n\t\tvoid CombineQueries(AstNode node, Dictionary<string, object> fromOrLetIdentifiers)\n\t\t{\n\t\t\tAstNode next;\n\t\t\tfor (AstNode child = node.FirstChild; child != null; child = next)\n\t\t\t{\n\t\t\t\t// store reference to next child before transformation\n\t\t\t\tnext = child.NextSibling;\n\t\t\t\tCombineQueries(child, fromOrLetIdentifiers);\n\t\t\t}\n\t\t\tif (node is QueryExpression query)\n\t\t\t{\n\t\t\t\tQueryFromClause fromClause = (QueryFromClause)query.Clauses.First();\n\t\t\t\tif (fromClause.Expression is QueryExpression innerQuery)\n\t\t\t\t{\n\t\t\t\t\tif (TryRemoveTransparentIdentifier(query, fromClause, innerQuery, fromOrLetIdentifiers))\n\t\t\t\t\t{\n\t\t\t\t\t\tRemoveTransparentIdentifierReferences(query, fromOrLetIdentifiers);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tQueryContinuationClause continuation = new QueryContinuationClause();\n\t\t\t\t\t\tcontinuation.PrecedingQuery = innerQuery.Detach();\n\t\t\t\t\t\tcontinuation.Identifier = fromClause.Identifier;\n\t\t\t\t\t\tcontinuation.CopyAnnotationsFrom(fromClause);\n\t\t\t\t\t\tfromClause.ReplaceWith(continuation);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tMatch m = castPattern.Match(fromClause.Expression);\n\t\t\t\t\tif (m.Success)\n\t\t\t\t\t{\n\t\t\t\t\t\tfromClause.Type = m.Get<AstType>(\"targetType\").Single().Detach();\n\t\t\t\t\t\tfromClause.Expression = m.Get<Expression>(\"inExpr\").Single().Detach();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic readonly QuerySelectClause selectTransparentIdentifierPattern = new QuerySelectClause {\n\t\t\tExpression = new AnonymousTypeCreateExpression {\n\t\t\t\tInitializers = {\n\t\t\t\t\tnew Repeat(\n\t\t\t\t\t\tnew Choice {\n\t\t\t\t\t\t\tnew IdentifierExpression(Pattern.AnyString).WithName(\"expr\"), // name is equivalent to name = name\n\t\t\t\t\t\t\tnew MemberReferenceExpression(new AnyNode(), Pattern.AnyString).WithName(\"expr\"), // expr.name is equivalent to name = expr.name\n\t\t\t\t\t\t\tnew NamedExpression {\n\t\t\t\t\t\t\t\tName = Pattern.AnyString,\n\t\t\t\t\t\t\t\tExpression = new AnyNode()\n\t\t\t\t\t\t\t}.WithName(\"expr\")\n\t\t\t\t\t\t}\n\t\t\t\t\t) { MinCount = 1 }\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tbool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery, Dictionary<string, object> letClauses)\n\t\t{\n\t\t\tif (!CSharpDecompiler.IsTransparentIdentifier(fromClause.Identifier))\n\t\t\t\treturn false;\n\t\t\tQuerySelectClause selectClause = innerQuery.Clauses.Last() as QuerySelectClause;\n\t\t\tMatch match = selectTransparentIdentifierPattern.Match(selectClause);\n\t\t\tif (!match.Success)\n\t\t\t\treturn false;\n\n\t\t\t// from * in (from x in ... select new { members of anonymous type }) ...\n\t\t\t// =>\n\t\t\t// from x in ... { let x = ... } ...\n\t\t\tfromClause.Remove();\n\t\t\tselectClause.Remove();\n\t\t\t// Move clauses from innerQuery to query\n\t\t\tQueryClause insertionPos = null;\n\t\t\tforeach (var clause in innerQuery.Clauses)\n\t\t\t{\n\t\t\t\tquery.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach());\n\t\t\t}\n\n\t\t\tforeach (var expr in match.Get<Expression>(\"expr\"))\n\t\t\t{\n\t\t\t\tswitch (expr)\n\t\t\t\t{\n\t\t\t\t\tcase IdentifierExpression identifier:\n\t\t\t\t\t\tletClauses[identifier.Identifier] = identifier.Annotation<ILVariableResolveResult>();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MemberReferenceExpression member:\n\t\t\t\t\t\tAddQueryLetClause(member.MemberName, member);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase NamedExpression namedExpression:\n\t\t\t\t\t\tif (namedExpression.Expression is IdentifierExpression identifierExpression && namedExpression.Name == identifierExpression.Identifier)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tletClauses[namedExpression.Name] = identifierExpression.Annotation<ILVariableResolveResult>();\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tAddQueryLetClause(namedExpression.Name, namedExpression.Expression);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\n\t\t\tvoid AddQueryLetClause(string name, Expression expression)\n\t\t\t{\n\t\t\t\tQueryLetClause letClause = new QueryLetClause { Identifier = name, Expression = expression.Detach() };\n\t\t\t\tvar annotation = new LetIdentifierAnnotation();\n\t\t\t\tletClause.AddAnnotation(annotation);\n\t\t\t\tletClauses[name] = annotation;\n\t\t\t\tquery.Clauses.InsertAfter(insertionPos, letClause);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Removes all occurrences of transparent identifiers\n\t\t/// </summary>\n\t\tvoid RemoveTransparentIdentifierReferences(AstNode node, Dictionary<string, object> fromOrLetIdentifiers)\n\t\t{\n\t\t\tforeach (AstNode child in node.Children)\n\t\t\t{\n\t\t\t\tRemoveTransparentIdentifierReferences(child, fromOrLetIdentifiers);\n\t\t\t}\n\t\t\tif (node is MemberReferenceExpression mre && mre.Target is IdentifierExpression ident\n\t\t\t\t&& CSharpDecompiler.IsTransparentIdentifier(ident.Identifier))\n\t\t\t{\n\t\t\t\tIdentifierExpression newIdent = new IdentifierExpression(mre.MemberName);\n\t\t\t\tmre.TypeArguments.MoveTo(newIdent.TypeArguments);\n\t\t\t\tnewIdent.CopyAnnotationsFrom(mre);\n\t\t\t\tnewIdent.RemoveAnnotations<Semantics.MemberResolveResult>(); // remove the reference to the property of the anonymous type\n\t\t\t\tif (fromOrLetIdentifiers.TryGetValue(mre.MemberName, out var annotation))\n\t\t\t\t\tnewIdent.AddAnnotation(annotation);\n\t\t\t\tmre.ReplaceWith(newIdent);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic class LetIdentifierAnnotation\n\t{\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/ContextTrackingVisitor.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\t/// <summary>\n\t/// Base class for AST visitors that need the current type/method context info.\n\t/// </summary>\n\tpublic abstract class ContextTrackingVisitor<TResult> : DepthFirstAstVisitor<TResult>\n\t{\n\t\tprotected ITypeDefinition currentTypeDefinition;\n\t\tprotected IMethod currentMethod;\n\n\t\tprotected void Initialize(TransformContext context)\n\t\t{\n\t\t\tcurrentTypeDefinition = context.CurrentTypeDefinition;\n\t\t\tcurrentMethod = context.CurrentMember as IMethod;\n\t\t}\n\n\t\tprotected void Uninitialize()\n\t\t{\n\t\t\tcurrentTypeDefinition = null;\n\t\t\tcurrentMethod = null;\n\t\t}\n\n\t\tpublic override TResult VisitTypeDeclaration(TypeDeclaration typeDeclaration)\n\t\t{\n\t\t\tITypeDefinition oldType = currentTypeDefinition;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tcurrentTypeDefinition = typeDeclaration.GetSymbol() as ITypeDefinition;\n\t\t\t\treturn base.VisitTypeDeclaration(typeDeclaration);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tcurrentTypeDefinition = oldType;\n\t\t\t}\n\t\t}\n\n\t\tpublic override TResult VisitMethodDeclaration(MethodDeclaration methodDeclaration)\n\t\t{\n\t\t\tvar oldMethod = currentMethod;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tcurrentMethod = methodDeclaration.GetSymbol() as IMethod;\n\t\t\t\treturn base.VisitMethodDeclaration(methodDeclaration);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tcurrentMethod = oldMethod;\n\t\t\t}\n\t\t}\n\n\t\tpublic override TResult VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)\n\t\t{\n\t\t\tvar oldMethod = currentMethod;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tcurrentMethod = constructorDeclaration.GetSymbol() as IMethod;\n\t\t\t\treturn base.VisitConstructorDeclaration(constructorDeclaration);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tcurrentMethod = oldMethod;\n\t\t\t}\n\t\t}\n\n\t\tpublic override TResult VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration)\n\t\t{\n\t\t\tvar oldMethod = currentMethod;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tcurrentMethod = destructorDeclaration.GetSymbol() as IMethod;\n\t\t\t\treturn base.VisitDestructorDeclaration(destructorDeclaration);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tcurrentMethod = oldMethod;\n\t\t\t}\n\t\t}\n\n\t\tpublic override TResult VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration)\n\t\t{\n\t\t\tvar oldMethod = currentMethod;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tcurrentMethod = operatorDeclaration.GetSymbol() as IMethod;\n\t\t\t\treturn base.VisitOperatorDeclaration(operatorDeclaration);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tcurrentMethod = oldMethod;\n\t\t\t}\n\t\t}\n\n\t\tpublic override TResult VisitAccessor(Accessor accessor)\n\t\t{\n\t\t\tvar oldMethod = currentMethod;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tcurrentMethod = accessor.GetSymbol() as IMethod;\n\t\t\t\treturn base.VisitAccessor(accessor);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tcurrentMethod = oldMethod;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/CustomPatterns.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\nusing ICSharpCode.Decompiler.Semantics;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\tsealed class TypePattern : Pattern\n\t{\n\t\treadonly string ns;\n\t\treadonly string name;\n\n\t\tpublic TypePattern(Type type)\n\t\t{\n\t\t\tthis.ns = type.Namespace;\n\t\t\tthis.name = type.Name;\n\t\t}\n\n\t\tpublic override bool DoMatch(INode other, Match match)\n\t\t{\n\t\t\tComposedType ct = other as ComposedType;\n\t\t\tAstType o;\n\t\t\tif (ct != null && !ct.HasRefSpecifier && !ct.HasNullableSpecifier && ct.PointerRank == 0 && !ct.ArraySpecifiers.Any())\n\t\t\t{\n\t\t\t\t// Special case: ILSpy sometimes produces a ComposedType but then removed all array specifiers\n\t\t\t\t// from it. In that case, we need to look at the base type for the annotations.\n\t\t\t\to = ct.BaseType;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\to = other as AstType;\n\t\t\t\tif (o == null)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar trr = o.GetResolveResult() as TypeResolveResult;\n\t\t\treturn trr != null && trr.Type.Namespace == ns && trr.Type.Name == name;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn name;\n\t\t}\n\t}\n\n\tsealed class LdTokenPattern : Pattern\n\t{\n\t\tAnyNode childNode;\n\n\t\tpublic LdTokenPattern(string groupName)\n\t\t{\n\t\t\tthis.childNode = new AnyNode(groupName);\n\t\t}\n\n\t\tpublic override bool DoMatch(INode other, Match match)\n\t\t{\n\t\t\tInvocationExpression ie = other as InvocationExpression;\n\t\t\tif (ie != null && ie.Annotation<LdTokenAnnotation>() != null && ie.Arguments.Count == 1)\n\t\t\t{\n\t\t\t\treturn childNode.DoMatch(ie.Arguments.Single(), match);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn \"ldtoken(...)\";\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// typeof-Pattern that applies on the expanded form of typeof (prior to ReplaceMethodCallsWithOperators)\n\t/// </summary>\n\tsealed class TypeOfPattern : Pattern\n\t{\n\t\tINode childNode;\n\n\t\tpublic TypeOfPattern(string groupName)\n\t\t{\n\t\t\tchildNode = new MemberReferenceExpression(\n\t\t\t\tnew InvocationExpression(\n\t\t\t\t\tnew MemberReferenceExpression(\n\t\t\t\t\t\tnew TypeReferenceExpression { Type = new TypePattern(typeof(Type)).ToType() },\n\t\t\t\t\t\t\"GetTypeFromHandle\"),\n\t\t\t\t\tnew TypeOfExpression(new AnyNode(groupName))\n\t\t\t\t), \"TypeHandle\");\n\t\t}\n\n\t\tpublic override bool DoMatch(INode other, Match match)\n\t\t{\n\t\t\treturn childNode.DoMatch(other, match);\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn \"typeof(...)\";\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\t/// <summary>\n\t/// Insert variable declarations.\n\t/// </summary>\n\tpublic class DeclareVariables : IAstTransform\n\t{\n\t\t/// <summary>\n\t\t/// Represents a position immediately before nextNode.\n\t\t/// nextNode is either an ExpressionStatement in a BlockStatement, or an initializer in a for-loop.\n\t\t/// </summary>\n\t\t[DebuggerDisplay(\"level = {level}, nextNode = {nextNode}\")]\n\t\tstruct InsertionPoint\n\t\t{\n\t\t\t/// <summary>\n\t\t\t/// The nesting level of `nextNode` within the AST.\n\t\t\t/// Used to speed up FindCommonParent().\n\t\t\t/// </summary>\n\t\t\tinternal int level;\n\t\t\tinternal AstNode nextNode;\n\n\t\t\t/// <summary>Go up one level</summary>\n\t\t\tinternal InsertionPoint Up()\n\t\t\t{\n\t\t\t\treturn new InsertionPoint {\n\t\t\t\t\tlevel = level - 1,\n\t\t\t\t\tnextNode = nextNode.Parent\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tinternal InsertionPoint UpTo(int targetLevel)\n\t\t\t{\n\t\t\t\tInsertionPoint result = this;\n\t\t\t\twhile (result.level > targetLevel)\n\t\t\t\t{\n\t\t\t\t\tresult.nextNode = result.nextNode.Parent;\n\t\t\t\t\tresult.level -= 1;\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\n\t\tenum VariableInitKind\n\t\t{\n\t\t\tNone,\n\t\t\tNeedsDefaultValue,\n\t\t\tNeedsSkipInit\n\t\t}\n\n\t\t[DebuggerDisplay(\"VariableToDeclare(Name={Name})\")]\n\t\tclass VariableToDeclare\n\t\t{\n\t\t\tpublic readonly ILVariable ILVariable;\n\t\t\tpublic IType Type => ILVariable.Type;\n\t\t\tpublic string Name => ILVariable.Name;\n\n\t\t\t/// <summary>\n\t\t\t/// Whether the variable needs to be default-initialized.\n\t\t\t/// </summary>\n\t\t\tpublic VariableInitKind DefaultInitialization;\n\n\t\t\t/// <summary>\n\t\t\t/// Integer value that can be used to compare to VariableToDeclare instances\n\t\t\t/// to determine which variable was used first in the source code.\n\t\t\t/// \n\t\t\t/// The variable with the lower SourceOrder value has the insertion point\n\t\t\t/// that comes first in the source code.\n\t\t\t/// </summary>\n\t\t\tpublic int SourceOrder;\n\n\t\t\t/// <summary>\n\t\t\t/// The insertion point, i.e. the node before which the variable declaration should be inserted.\n\t\t\t/// </summary>\n\t\t\tpublic InsertionPoint InsertionPoint;\n\n\t\t\t/// <summary>\n\t\t\t/// The first use of the variable.\n\t\t\t/// </summary>\n\t\t\tpublic IdentifierExpression FirstUse;\n\n\t\t\tpublic VariableToDeclare ReplacementDueToCollision;\n\t\t\tpublic bool InvolvedInCollision;\n\t\t\tpublic bool RemovedDueToCollision => ReplacementDueToCollision != null;\n\t\t\tpublic bool DeclaredInDeconstruction;\n\n\t\t\tpublic VariableToDeclare(ILVariable variable, InsertionPoint insertionPoint, IdentifierExpression firstUse, int sourceOrder)\n\t\t\t{\n\t\t\t\tthis.ILVariable = variable;\n\t\t\t\tif (variable.UsesInitialValue)\n\t\t\t\t{\n\t\t\t\t\tif (variable.InitialValueIsInitialized)\n\t\t\t\t\t{\n\t\t\t\t\t\tthis.DefaultInitialization = VariableInitKind.NeedsDefaultValue;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tthis.DefaultInitialization = VariableInitKind.NeedsSkipInit;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthis.DefaultInitialization = VariableInitKind.None;\n\t\t\t\t}\n\t\t\t\tthis.InsertionPoint = insertionPoint;\n\t\t\t\tthis.FirstUse = firstUse;\n\t\t\t\tthis.SourceOrder = sourceOrder;\n\t\t\t}\n\t\t}\n\n\t\treadonly Dictionary<ILVariable, VariableToDeclare> variableDict = new Dictionary<ILVariable, VariableToDeclare>();\n\t\tTransformContext context;\n\n\t\tpublic void Run(AstNode rootNode, TransformContext context)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (this.context != null)\n\t\t\t\t\tthrow new InvalidOperationException(\"Reentrancy in DeclareVariables?\");\n\t\t\t\tthis.context = context;\n\t\t\t\tvariableDict.Clear();\n\t\t\t\tEnsureExpressionStatementsAreValid(rootNode);\n\t\t\t\tFindInsertionPoints(rootNode, 0);\n\t\t\t\tResolveCollisions();\n\t\t\t\tInsertDeconstructionVariableDeclarations();\n\t\t\t\tInsertVariableDeclarations(context);\n\t\t\t\tUpdateAnnotations(rootNode);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tthis.context = null;\n\t\t\t\tvariableDict.Clear();\n\t\t\t}\n\t\t}\n\t\t/// <summary>\n\t\t/// Analyze the input AST (containing undeclared variables)\n\t\t/// for where those variables would be declared by this transform.\n\t\t/// Analysis does not modify the AST.\n\t\t/// </summary>\n\t\tpublic void Analyze(AstNode rootNode)\n\t\t{\n\t\t\tvariableDict.Clear();\n\t\t\tFindInsertionPoints(rootNode, 0);\n\t\t\tResolveCollisions();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Get the position where the declaration for the variable will be inserted.\n\t\t/// </summary>\n\t\tpublic AstNode GetDeclarationPoint(ILVariable variable)\n\t\t{\n\t\t\tVariableToDeclare v = variableDict[variable];\n\t\t\twhile (v.ReplacementDueToCollision != null)\n\t\t\t{\n\t\t\t\tv = v.ReplacementDueToCollision;\n\t\t\t}\n\t\t\treturn v.InsertionPoint.nextNode;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Determines whether a variable was merged with other variables.\n\t\t/// </summary>\n\t\tpublic bool WasMerged(ILVariable variable)\n\t\t{\n\t\t\tVariableToDeclare v = variableDict[variable];\n\t\t\treturn v.InvolvedInCollision || v.RemovedDueToCollision;\n\t\t}\n\n\t\tpublic void ClearAnalysisResults()\n\t\t{\n\t\t\tvariableDict.Clear();\n\t\t}\n\n\t\t#region EnsureExpressionStatementsAreValid\n\t\tvoid EnsureExpressionStatementsAreValid(AstNode rootNode)\n\t\t{\n\t\t\tforeach (var stmt in rootNode.DescendantsAndSelf.OfType<ExpressionStatement>())\n\t\t\t{\n\t\t\t\tif (stmt.Expression is DirectionExpression dir && IsValidInStatementExpression(dir.Expression))\n\t\t\t\t{\n\t\t\t\t\tstmt.Expression = dir.Expression.Detach();\n\t\t\t\t}\n\t\t\t\telse if (!IsValidInStatementExpression(stmt.Expression))\n\t\t\t\t{\n\t\t\t\t\t// fetch ILFunction\n\t\t\t\t\tvar function = stmt.Ancestors.SelectMany(a => a.Annotations.OfType<ILFunction>()).First(f => f.Parent == null);\n\t\t\t\t\t// if possible use C# 7.0 discard-assignment\n\t\t\t\t\tif (context.Settings.Discards && !ExpressionBuilder.HidesVariableWithName(function, \"_\"))\n\t\t\t\t\t{\n\t\t\t\t\t\tstmt.Expression = new AssignmentExpression(\n\t\t\t\t\t\t\tnew IdentifierExpression(\"_\"), // no ResolveResult\n\t\t\t\t\t\t\tstmt.Expression.Detach());\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// assign result to dummy variable\n\t\t\t\t\t\tvar type = stmt.Expression.GetResolveResult().Type;\n\t\t\t\t\t\tvar v = function.RegisterVariable(\n\t\t\t\t\t\t\tVariableKind.StackSlot,\n\t\t\t\t\t\t\ttype,\n\t\t\t\t\t\t\tAssignVariableNames.GenerateVariableName(function, type, context.DecompileRun.UsingScope,\n\t\t\t\t\t\t\t\tstmt.Expression.Annotations.OfType<ILInstruction>()\n\t\t\t\t\t\t\t\t\t.Where(AssignVariableNames.IsSupportedInstruction).FirstOrDefault(),\n\t\t\t\t\t\t\t\tmustResolveConflicts: true)\n\t\t\t\t\t\t);\n\t\t\t\t\t\tstmt.Expression = new AssignmentExpression(\n\t\t\t\t\t\t\tnew IdentifierExpression(v.Name).WithRR(new ILVariableResolveResult(v, v.Type)),\n\t\t\t\t\t\t\tstmt.Expression.Detach());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate static bool IsValidInStatementExpression(Expression expr)\n\t\t{\n\t\t\tswitch (expr)\n\t\t\t{\n\t\t\t\tcase InvocationExpression _:\n\t\t\t\tcase ObjectCreateExpression _:\n\t\t\t\tcase AssignmentExpression _:\n\t\t\t\tcase ErrorExpression _:\n\t\t\t\t\treturn true;\n\t\t\t\tcase UnaryOperatorExpression uoe:\n\t\t\t\t\tswitch (uoe.Operator)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase UnaryOperatorType.PostIncrement:\n\t\t\t\t\t\tcase UnaryOperatorType.PostDecrement:\n\t\t\t\t\t\tcase UnaryOperatorType.Increment:\n\t\t\t\t\t\tcase UnaryOperatorType.Decrement:\n\t\t\t\t\t\tcase UnaryOperatorType.Await:\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tcase UnaryOperatorType.NullConditionalRewrap:\n\t\t\t\t\t\t\treturn IsValidInStatementExpression(uoe.Expression);\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region FindInsertionPoints\n\t\tList<(InsertionPoint InsertionPoint, BlockContainer Scope)> scopeTracking = new List<(InsertionPoint, BlockContainer)>();\n\n\t\t/// <summary>\n\t\t/// Finds insertion points for all variables used within `node`\n\t\t/// and adds them to the variableDict.\n\t\t/// \n\t\t/// `level` == nesting depth of `node` within root node.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Insertion point for a variable = common parent of all uses of that variable\n\t\t/// = smallest possible scope that contains all the uses of the variable\n\t\t/// </remarks>\n\t\tvoid FindInsertionPoints(AstNode node, int nodeLevel)\n\t\t{\n\t\t\tBlockContainer scope = node.Annotation<BlockContainer>();\n\t\t\tif (scope != null && IsRelevantScope(scope))\n\t\t\t{\n\t\t\t\t// track loops and function bodies as scopes, for comparison with CaptureScope.\n\t\t\t\tscopeTracking.Add((new InsertionPoint { level = nodeLevel, nextNode = node }, scope));\n\t\t\t}\n\t\t\telse if (node is LambdaExpression { Body: Expression expr })\n\t\t\t{\n\t\t\t\t// expression-bodied lambdas don't have a BlockStatement linking to the BlockContainer\n\t\t\t\tscope = node.Annotation<ILFunction>()?.Body as BlockContainer;\n\t\t\t\tif (scope != null)\n\t\t\t\t{\n\t\t\t\t\tscopeTracking.Add((new InsertionPoint { level = nodeLevel + 1, nextNode = expr }, scope));\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tscope = null; // don't remove a scope if we didn't add one\n\t\t\t}\n\t\t\ttry\n\t\t\t{\n\t\t\t\tfor (AstNode child = node.FirstChild; child != null; child = child.NextSibling)\n\t\t\t\t{\n\t\t\t\t\tFindInsertionPoints(child, nodeLevel + 1);\n\t\t\t\t}\n\t\t\t\tif (node is IdentifierExpression identExpr)\n\t\t\t\t{\n\t\t\t\t\tvar rr = identExpr.GetResolveResult() as ILVariableResolveResult;\n\t\t\t\t\tif (rr != null && VariableNeedsDeclaration(rr.Variable.Kind))\n\t\t\t\t\t{\n\t\t\t\t\t\tFindInsertionPointForVariable(rr.Variable);\n\t\t\t\t\t}\n\t\t\t\t\telse if (identExpr.Annotation<ILFunction>() is ILFunction localFunction && localFunction.Kind == ILFunctionKind.LocalFunction)\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var v in localFunction.CapturedVariables)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (VariableNeedsDeclaration(v.Kind))\n\t\t\t\t\t\t\t\tFindInsertionPointForVariable(v);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tvoid FindInsertionPointForVariable(ILVariable variable)\n\t\t\t\t\t{\n\t\t\t\t\t\tInsertionPoint newPoint;\n\t\t\t\t\t\tint startIndex = scopeTracking.Count - 1;\n\t\t\t\t\t\tBlockContainer captureScope = variable.CaptureScope;\n\t\t\t\t\t\twhile (captureScope != null && !IsRelevantScope(captureScope))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcaptureScope = BlockContainer.FindClosestContainer(captureScope.Parent);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (captureScope != null && startIndex > 0 && captureScope != scopeTracking[startIndex].Scope)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\twhile (startIndex > 0 && scopeTracking[startIndex].Scope != captureScope)\n\t\t\t\t\t\t\t\tstartIndex--;\n\t\t\t\t\t\t\tnewPoint = scopeTracking[startIndex + 1].InsertionPoint;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnewPoint = new InsertionPoint { level = nodeLevel, nextNode = identExpr };\n\t\t\t\t\t\t\tif (variable.UsesInitialValue)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// Uninitialized variables are logically initialized at the beginning of the function\n\t\t\t\t\t\t\t\t// Because it's possible that the variable has a loop-carried dependency,\n\t\t\t\t\t\t\t\t// declare it outside of any loops.\n\t\t\t\t\t\t\t\twhile (startIndex >= 0)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif (scopeTracking[startIndex].Scope.EntryPoint.IncomingEdgeCount > 1)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t// declare variable outside of loop\n\t\t\t\t\t\t\t\t\t\tnewPoint = scopeTracking[startIndex].InsertionPoint;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse if (scopeTracking[startIndex].Scope.Parent is ILFunction)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t// stop at beginning of function\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tstartIndex--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (variableDict.TryGetValue(variable, out VariableToDeclare v))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tv.InsertionPoint = FindCommonParent(v.InsertionPoint, newPoint);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tv = new VariableToDeclare(variable, newPoint,\n\t\t\t\t\t\t\t\tidentExpr, sourceOrder: variableDict.Count);\n\t\t\t\t\t\t\tvariableDict.Add(variable, v);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tif (scope != null)\n\t\t\t\t\tscopeTracking.RemoveAt(scopeTracking.Count - 1);\n\t\t\t}\n\t\t}\n\n\t\tprivate static bool IsRelevantScope(BlockContainer scope)\n\t\t{\n\t\t\treturn scope.EntryPoint.IncomingEdgeCount > 1 || scope.Parent is ILFunction;\n\t\t}\n\n\t\tinternal static bool VariableNeedsDeclaration(VariableKind kind)\n\t\t{\n\t\t\tswitch (kind)\n\t\t\t{\n\t\t\t\tcase VariableKind.PinnedRegionLocal:\n\t\t\t\tcase VariableKind.Parameter:\n\t\t\t\tcase VariableKind.ExceptionLocal:\n\t\t\t\tcase VariableKind.ExceptionStackSlot:\n\t\t\t\tcase VariableKind.UsingLocal:\n\t\t\t\tcase VariableKind.ForeachLocal:\n\t\t\t\tcase VariableKind.PatternLocal:\n\t\t\t\t\treturn false;\n\t\t\t\tdefault:\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Finds an insertion point in a common parent instruction.\n\t\t/// </summary>\n\t\tInsertionPoint FindCommonParent(InsertionPoint oldPoint, InsertionPoint newPoint)\n\t\t{\n\t\t\t// First ensure we're looking at nodes on the same level:\n\t\t\toldPoint = oldPoint.UpTo(newPoint.level);\n\t\t\tnewPoint = newPoint.UpTo(oldPoint.level);\n\t\t\tDebug.Assert(newPoint.level == oldPoint.level);\n\t\t\t// Then go up the tree until both points share the same parent:\n\t\t\twhile (oldPoint.nextNode.Parent != newPoint.nextNode.Parent)\n\t\t\t{\n\t\t\t\toldPoint = oldPoint.Up();\n\t\t\t\tnewPoint = newPoint.Up();\n\t\t\t}\n\t\t\t// return oldPoint as that one comes first in the source code\n\t\t\treturn oldPoint;\n\t\t}\n\t\t#endregion\n\n\t\t/// <summary>\n\t\t/// Some variable declarations in C# are illegal (colliding),\n\t\t/// even though the variable live ranges are not overlapping.\n\t\t/// \n\t\t/// Multiple declarations in same block:\n\t\t/// <code>\n\t\t/// int i = 1; use(1);\n\t\t/// int i = 2; use(2);\n\t\t/// </code>\n\t\t/// \n\t\t/// \"Hiding\" declaration in nested block:\n\t\t/// <code>\n\t\t/// int i = 1; use(1);\n\t\t/// if (...) {\n\t\t///   int i = 2; use(2);\n\t\t/// }\n\t\t/// </code>\n\t\t/// \n\t\t/// Nested blocks are illegal even if the parent block\n\t\t/// declares the variable later:\n\t\t/// <code>\n\t\t/// if (...) {\n\t\t///   int i = 1; use(i);\n\t\t/// }\n\t\t/// int i = 2; use(i);\n\t\t/// </code>\n\t\t/// \n\t\t/// ResolveCollisions() detects all these cases, and combines the variable declarations\n\t\t/// to a single declaration that is usable for the combined scopes.\n\t\t/// </summary>\n\t\tvoid ResolveCollisions()\n\t\t{\n\t\t\tvar multiDict = new MultiDictionary<string, VariableToDeclare>();\n\t\t\tforeach (var v in variableDict.Values)\n\t\t\t{\n\t\t\t\t// We can only insert variable declarations in blocks, but FindInsertionPoints() didn't\n\t\t\t\t// guarantee that it finds only blocks.\n\t\t\t\t// Fix that up now.\n\t\t\t\twhile (!(v.InsertionPoint.nextNode.Parent is BlockStatement or LambdaExpression))\n\t\t\t\t{\n\t\t\t\t\tif (v.InsertionPoint.nextNode.Parent is ForStatement f && v.InsertionPoint.nextNode == f.Initializers.FirstOrDefault() && IsMatchingAssignment(v, out _))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Special case: the initializer of a ForStatement can also declare a variable (with scope local to the for loop).\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tv.InsertionPoint = v.InsertionPoint.Up();\n\t\t\t\t}\n\t\t\t\t// Note: 'out var', pattern matching etc. is not considered a valid insertion point here, because the scope of the\n\t\t\t\t// resulting variable is not restricted to the parent node of the insertion point, but extends to the whole BlockStatement.\n\t\t\t\t// We moved up the insertion point to the whole BlockStatement so that we can resolve collisions,\n\t\t\t\t// later we might decide to declare the variable more locally (as 'out var') instead if still possible.\n\n\t\t\t\t// Go through all potentially colliding variables:\n\t\t\t\tforeach (var prev in multiDict[v.Name])\n\t\t\t\t{\n\t\t\t\t\tif (prev.RemovedDueToCollision)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t// Go up until both nodes are on the same level:\n\t\t\t\t\tInsertionPoint point1 = prev.InsertionPoint.UpTo(v.InsertionPoint.level);\n\t\t\t\t\tInsertionPoint point2 = v.InsertionPoint.UpTo(prev.InsertionPoint.level);\n\t\t\t\t\tDebug.Assert(point1.level == point2.level);\n\t\t\t\t\tif (point1.nextNode.Parent == point2.nextNode.Parent)\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(prev.Type.Equals(v.Type));\n\t\t\t\t\t\t// We found a collision!\n\t\t\t\t\t\tv.InvolvedInCollision = true;\n\t\t\t\t\t\tprev.ReplacementDueToCollision = v;\n\t\t\t\t\t\t// Continue checking other entries in multiDict against the new position of `v`.\n\t\t\t\t\t\tif (prev.SourceOrder < v.SourceOrder)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Switch v's insertion point to prev's insertion point:\n\t\t\t\t\t\t\tv.InsertionPoint = point1;\n\t\t\t\t\t\t\t// Since prev was first, it has the correct SourceOrder/FirstUse values\n\t\t\t\t\t\t\t// for the new combined variable:\n\t\t\t\t\t\t\tv.SourceOrder = prev.SourceOrder;\n\t\t\t\t\t\t\tv.FirstUse = prev.FirstUse;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// v is first in source order, so it keeps its old insertion point\n\t\t\t\t\t\t\t// (and other properties), except that the insertion point is\n\t\t\t\t\t\t\t// moved up to prev's level.\n\t\t\t\t\t\t\tv.InsertionPoint = point2;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tv.DefaultInitialization |= prev.DefaultInitialization;\n\t\t\t\t\t\t// I think we don't need to re-check the dict entries that we already checked earlier,\n\t\t\t\t\t\t// because the new v.InsertionPoint only collides with another point x if either\n\t\t\t\t\t\t// the old v.InsertionPoint or the old prev.InsertionPoint already collided with x.\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tmultiDict.Add(v.Name, v);\n\t\t\t}\n\t\t}\n\n\t\tprivate void InsertDeconstructionVariableDeclarations()\n\t\t{\n\t\t\tvar usedVariables = new HashSet<ILVariable>();\n\t\t\tforeach (var g in variableDict.Values.GroupBy(v => v.InsertionPoint.nextNode))\n\t\t\t{\n\t\t\t\tif (!(g.Key is ExpressionStatement { Expression: AssignmentExpression { Left: TupleExpression left, Operator: AssignmentOperatorType.Assign } assignment }))\n\t\t\t\t\tcontinue;\n\t\t\t\tusedVariables.Clear();\n\t\t\t\tvar deconstruct = assignment.Annotation<DeconstructInstruction>();\n\t\t\t\tif (deconstruct == null || deconstruct.Init.Count > 0 || deconstruct.Conversions.Instructions.Count > 0)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (!deconstruct.Assignments.Instructions.All(IsDeclarableVariable))\n\t\t\t\t\tcontinue;\n\n\t\t\t\tvar designation = StatementBuilder.TranslateDeconstructionDesignation(deconstruct, isForeach: false);\n\t\t\t\tleft.ReplaceWith(new DeclarationExpression { Type = new SimpleType(\"var\"), Designation = designation });\n\n\t\t\t\tforeach (var v in usedVariables)\n\t\t\t\t{\n\t\t\t\t\tvariableDict[v].DeclaredInDeconstruction = true;\n\t\t\t\t}\n\n\t\t\t\tbool IsDeclarableVariable(ILInstruction inst)\n\t\t\t\t{\n\t\t\t\t\tif (!inst.MatchStLoc(out var v, out var value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!g.Any(vd => vd.ILVariable == v && !vd.RemovedDueToCollision))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!usedVariables.Add(v))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tvar expectedType = ((LdLoc)value).Variable.Type;\n\t\t\t\t\tif (!v.Type.Equals(expectedType))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!(v.Kind == VariableKind.StackSlot || v.Kind == VariableKind.Local))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool IsMatchingAssignment(VariableToDeclare v, out AssignmentExpression assignment)\n\t\t{\n\t\t\tassignment = v.InsertionPoint.nextNode as AssignmentExpression;\n\t\t\tif (assignment == null)\n\t\t\t{\n\t\t\t\tassignment = (v.InsertionPoint.nextNode as ExpressionStatement)?.Expression as AssignmentExpression;\n\t\t\t\tif (assignment == null)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn assignment.Operator == AssignmentOperatorType.Assign\n\t\t\t\t&& assignment.Left is IdentifierExpression identExpr\n\t\t\t\t&& identExpr.Identifier == v.Name\n\t\t\t\t&& identExpr.TypeArguments.Count == 0;\n\t\t}\n\n\t\tbool CombineDeclarationAndInitializer(VariableToDeclare v, TransformContext context)\n\t\t{\n\t\t\tif (v.Type.IsByRefLike)\n\t\t\t\treturn true; // by-ref-like variables always must be initialized at their declaration.\n\n\t\t\tif (v.InsertionPoint.nextNode.Role == ForStatement.InitializerRole)\n\t\t\t\treturn true; // for-statement initializers always should combine declaration and initialization.\n\n\t\t\treturn !context.Settings.SeparateLocalVariableDeclarations;\n\t\t}\n\n\t\tvoid InsertVariableDeclarations(TransformContext context)\n\t\t{\n\t\t\tvar replacements = new List<(AstNode, AstNode)>();\n\t\t\tforeach (var (ilVariable, v) in variableDict)\n\t\t\t{\n\t\t\t\tif (v.RemovedDueToCollision || v.DeclaredInDeconstruction)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (CombineDeclarationAndInitializer(v, context) && IsMatchingAssignment(v, out AssignmentExpression assignment))\n\t\t\t\t{\n\t\t\t\t\t// 'int v; v = expr;' can be combined to 'int v = expr;'\n\t\t\t\t\tAstType type;\n\t\t\t\t\tif (context.Settings.AnonymousTypes && v.Type.ContainsAnonymousType())\n\t\t\t\t\t{\n\t\t\t\t\t\ttype = new SimpleType(\"var\");\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\ttype = context.TypeSystemAstBuilder.ConvertType(v.Type);\n\t\t\t\t\t}\n\t\t\t\t\tif (v.ILVariable.IsRefReadOnly && type is ComposedType composedType && composedType.HasRefSpecifier)\n\t\t\t\t\t{\n\t\t\t\t\t\tcomposedType.HasReadOnlySpecifier = true;\n\t\t\t\t\t}\n\t\t\t\t\tif (v.ILVariable.Kind == VariableKind.PinnedLocal)\n\t\t\t\t\t{\n\t\t\t\t\t\ttype.InsertChildAfter(null, new Comment(\"pinned\", CommentType.MultiLine), Roles.Comment);\n\t\t\t\t\t}\n\t\t\t\t\tvar vds = new VariableDeclarationStatement(type, v.Name, assignment.Right.Detach());\n\t\t\t\t\tvar init = vds.Variables.Single();\n\t\t\t\t\tinit.AddAnnotation(assignment.Left.GetResolveResult());\n\t\t\t\t\tforeach (object annotation in assignment.Left.Annotations.Concat(assignment.Annotations))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!(annotation is ResolveResult))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tinit.AddAnnotation(annotation);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treplacements.Add((v.InsertionPoint.nextNode, vds));\n\t\t\t\t}\n\t\t\t\telse if (CanBeDeclaredAsOutVariable(v, out var dirExpr))\n\t\t\t\t{\n\t\t\t\t\t// 'T v; SomeCall(out v);' can be combined to 'SomeCall(out T v);'\n\t\t\t\t\tAstType type;\n\t\t\t\t\tbool isOutVar = false;\n\t\t\t\t\tif (context.Settings.AnonymousTypes && v.Type.ContainsAnonymousType())\n\t\t\t\t\t{\n\t\t\t\t\t\ttype = new SimpleType(\"var\");\n\t\t\t\t\t\tisOutVar = true;\n\t\t\t\t\t}\n\t\t\t\t\telse if (dirExpr.Annotation<UseImplicitlyTypedOutAnnotation>() != null)\n\t\t\t\t\t{\n\t\t\t\t\t\ttype = new SimpleType(\"var\");\n\t\t\t\t\t\tisOutVar = true;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\ttype = context.TypeSystemAstBuilder.ConvertType(v.Type);\n\t\t\t\t\t}\n\t\t\t\t\tstring name;\n\t\t\t\t\t// Variable is not used and discards are allowed, we can simplify this to 'out T _'.\n\t\t\t\t\t// TODO: if no variable named _ is declared and var is used instead of T, use out _.\n\t\t\t\t\t// Note: ExpressionBuilder.HidesVariableWithName produces inaccurate results, because it\n\t\t\t\t\t// does not take lambdas and local functions into account, that are defined in the same\n\t\t\t\t\t// scope as v.\n\t\t\t\t\tif (context.Settings.Discards && v.ILVariable.LoadCount == 0\n\t\t\t\t\t\t&& v.ILVariable.StoreCount == 0 && v.ILVariable.AddressCount == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tname = \"_\";\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tname = v.Name;\n\t\t\t\t\t}\n\t\t\t\t\tvar ovd = new OutVarDeclarationExpression(type, name);\n\t\t\t\t\tovd.Variable.AddAnnotation(new ILVariableResolveResult(ilVariable));\n\t\t\t\t\tovd.CopyAnnotationsFrom(dirExpr);\n\t\t\t\t\tif (isOutVar)\n\t\t\t\t\t{\n\t\t\t\t\t\tovd.RemoveAnnotations<ResolveResult>();\n\t\t\t\t\t\tovd.AddAnnotation(new OutVarResolveResult(v.Type));\n\t\t\t\t\t}\n\t\t\t\t\treplacements.Add((dirExpr, ovd));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Insert a separate declaration statement.\n\t\t\t\t\tExpression initializer = null;\n\t\t\t\t\tAstType type = context.TypeSystemAstBuilder.ConvertType(v.Type);\n\t\t\t\t\tif (v.DefaultInitialization == VariableInitKind.NeedsDefaultValue)\n\t\t\t\t\t{\n\t\t\t\t\t\tinitializer = new DefaultValueExpression(type.Clone());\n\t\t\t\t\t}\n\t\t\t\t\tvar vds = new VariableDeclarationStatement(type, v.Name, initializer);\n\t\t\t\t\tvds.Variables.Single().AddAnnotation(new ILVariableResolveResult(ilVariable));\n\t\t\t\t\tif (v.InsertionPoint.nextNode.Parent is LambdaExpression lambda)\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(lambda.Body is not BlockStatement);\n\t\t\t\t\t\tlambda.Body = new BlockStatement() {\n\t\t\t\t\t\t\tnew ReturnStatement((Expression)lambda.Body.Detach())\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tif (v.InsertionPoint.nextNode.Parent is ReturnStatement)\n\t\t\t\t\t{\n\t\t\t\t\t\tv.InsertionPoint = v.InsertionPoint.Up();\n\t\t\t\t\t}\n\t\t\t\t\tDebug.Assert(v.InsertionPoint.nextNode.Role == BlockStatement.StatementRole);\n\t\t\t\t\tif (v.DefaultInitialization == VariableInitKind.NeedsSkipInit)\n\t\t\t\t\t{\n\t\t\t\t\t\tAstType unsafeType = context.TypeSystemAstBuilder.ConvertType(\n\t\t\t\t\t\t\tcontext.TypeSystem.FindType(KnownTypeCode.Unsafe));\n\t\t\t\t\t\tif (context.Settings.OutVariables)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar outVarDecl = new OutVarDeclarationExpression(type.Clone(), v.Name);\n\t\t\t\t\t\t\toutVarDecl.Variable.AddAnnotation(new ILVariableResolveResult(ilVariable));\n\t\t\t\t\t\t\tv.InsertionPoint.nextNode.Parent.InsertChildBefore(\n\t\t\t\t\t\t\t\tv.InsertionPoint.nextNode,\n\t\t\t\t\t\t\t\tnew ExpressionStatement {\n\t\t\t\t\t\t\t\t\tExpression = new InvocationExpression {\n\t\t\t\t\t\t\t\t\t\tTarget = new MemberReferenceExpression {\n\t\t\t\t\t\t\t\t\t\t\tTarget = new TypeReferenceExpression(unsafeType),\n\t\t\t\t\t\t\t\t\t\t\tMemberName = \"SkipInit\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tArguments = {\n\t\t\t\t\t\t\t\t\t\t\toutVarDecl\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tBlockStatement.StatementRole);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tv.InsertionPoint.nextNode.Parent.InsertChildBefore(\n\t\t\t\t\t\t\t\tv.InsertionPoint.nextNode,\n\t\t\t\t\t\t\t\tvds,\n\t\t\t\t\t\t\t\tBlockStatement.StatementRole);\n\t\t\t\t\t\t\tv.InsertionPoint.nextNode.Parent.InsertChildBefore(\n\t\t\t\t\t\t\t\tv.InsertionPoint.nextNode,\n\t\t\t\t\t\t\t\tnew ExpressionStatement {\n\t\t\t\t\t\t\t\t\tExpression = new InvocationExpression {\n\t\t\t\t\t\t\t\t\t\tTarget = new MemberReferenceExpression {\n\t\t\t\t\t\t\t\t\t\t\tTarget = new TypeReferenceExpression(unsafeType),\n\t\t\t\t\t\t\t\t\t\t\tMemberName = \"SkipInit\"\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\tArguments = {\n\t\t\t\t\t\t\t\t\t\t\tnew DirectionExpression(\n\t\t\t\t\t\t\t\t\t\t\t\tFieldDirection.Out,\n\t\t\t\t\t\t\t\t\t\t\t\tnew IdentifierExpression(v.Name)\n\t\t\t\t\t\t\t\t\t\t\t\t\t.WithRR(new ILVariableResolveResult(ilVariable))\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tBlockStatement.StatementRole);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tv.InsertionPoint.nextNode.Parent.InsertChildBefore(\n\t\t\t\t\t\t\tv.InsertionPoint.nextNode,\n\t\t\t\t\t\t\tvds,\n\t\t\t\t\t\t\tBlockStatement.StatementRole);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// perform replacements at end, so that we don't replace a node while it is still referenced by a VariableToDeclare\n\t\t\tforeach (var (oldNode, newNode) in replacements)\n\t\t\t{\n\t\t\t\toldNode.ReplaceWith(newNode);\n\t\t\t}\n\t\t}\n\n\t\tprivate bool CanBeDeclaredAsOutVariable(VariableToDeclare v, out DirectionExpression dirExpr)\n\t\t{\n\t\t\tdirExpr = v.FirstUse.Parent as DirectionExpression;\n\t\t\tif (dirExpr == null || dirExpr.FieldDirection != FieldDirection.Out)\n\t\t\t\treturn false;\n\t\t\tif (!context.Settings.OutVariables)\n\t\t\t\treturn false;\n\t\t\tif (v.DefaultInitialization != VariableInitKind.None)\n\t\t\t\treturn false;\n\t\t\tfor (AstNode node = v.FirstUse; node != null; node = node.Parent)\n\t\t\t{\n\t\t\t\tif (node.Role == Roles.EmbeddedStatement)\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tswitch (node)\n\t\t\t\t{\n\t\t\t\t\tcase IfElseStatement:  // variable declared in if condition appears in parent scope\n\t\t\t\t\tcase ExpressionStatement:\n\t\t\t\t\t\treturn node == v.InsertionPoint.nextNode;\n\t\t\t\t\tcase Statement:\n\t\t\t\t\t\treturn false; // other statements (e.g. while) don't allow variables to be promoted to parent scope\n\t\t\t\t\tcase LambdaExpression lambda:\n\t\t\t\t\t\treturn lambda.Body == v.InsertionPoint.nextNode;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Update ILVariableResolveResult annotations of all ILVariables that have been replaced by ResolveCollisions.\n\t\t/// </summary>\n\t\tvoid UpdateAnnotations(AstNode rootNode)\n\t\t{\n\t\t\tforeach (var node in rootNode.Descendants)\n\t\t\t{\n\t\t\t\tILVariable ilVar;\n\t\t\t\tswitch (node)\n\t\t\t\t{\n\t\t\t\t\tcase IdentifierExpression id:\n\t\t\t\t\t\tilVar = id.GetILVariable();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase VariableInitializer vi:\n\t\t\t\t\t\tilVar = vi.GetILVariable();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (ilVar == null || !VariableNeedsDeclaration(ilVar.Kind))\n\t\t\t\t\tcontinue;\n\t\t\t\tvar v = variableDict[ilVar];\n\t\t\t\tif (!v.RemovedDueToCollision)\n\t\t\t\t\tcontinue;\n\t\t\t\twhile (v.RemovedDueToCollision)\n\t\t\t\t{\n\t\t\t\t\tv = v.ReplacementDueToCollision;\n\t\t\t\t}\n\t\t\t\tnode.RemoveAnnotations<ILVariableResolveResult>();\n\t\t\t\tnode.AddAnnotation(new ILVariableResolveResult(v.ILVariable, v.Type));\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/EscapeInvalidIdentifiers.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\t/// <summary>\n\t/// Escape invalid identifiers.\n\t/// </summary>\n\t/// <remarks>\n\t/// This transform is not enabled by default.\n\t/// </remarks>\n\tpublic class EscapeInvalidIdentifiers : IAstTransform\n\t{\n\t\tbool IsValid(char ch)\n\t\t{\n\t\t\tif (char.IsLetterOrDigit(ch))\n\t\t\t\treturn true;\n\t\t\tif (ch == '_')\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\n\t\tstring ReplaceInvalid(string s)\n\t\t{\n\t\t\tstring name = string.Concat(s.Select(ch => IsValid(ch) ? ch.ToString() : string.Format(\"_{0:X4}\", (int)ch)));\n\t\t\tif (name.Length >= 1 && !(char.IsLetter(name[0]) || name[0] == '_'))\n\t\t\t\tname = \"_\" + name;\n\t\t\treturn name;\n\t\t}\n\n\t\tpublic void Run(AstNode rootNode, TransformContext context)\n\t\t{\n\t\t\tforeach (var ident in rootNode.DescendantsAndSelf.OfType<Identifier>())\n\t\t\t{\n\t\t\t\tident.Name = ReplaceInvalid(ident.Name);\n\t\t\t}\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// This transform is used to remove assembly-attributes that are generated by the compiler,\n\t/// thus don't need to be declared. (We have to remove them, in order to avoid conflicts while compiling.)\n\t/// </summary>\n\t/// <remarks>This transform is only enabled, when exporting a full assembly as project.</remarks>\n\tpublic class RemoveCompilerGeneratedAssemblyAttributes : IAstTransform\n\t{\n\t\tpublic void Run(AstNode rootNode, TransformContext context)\n\t\t{\n\t\t\tforeach (var section in rootNode.Children.OfType<AttributeSection>())\n\t\t\t{\n\t\t\t\tif (section.AttributeTarget == \"assembly\")\n\t\t\t\t{\n\t\t\t\t\tforeach (var attribute in section.Attributes)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar trr = attribute.Type.Annotation<TypeResolveResult>();\n\t\t\t\t\t\tif (trr == null)\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\tstring fullName = trr.Type.FullName;\n\t\t\t\t\t\tvar arguments = attribute.Arguments;\n\t\t\t\t\t\tswitch (fullName)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase \"System.Diagnostics.DebuggableAttribute\":\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tattribute.Remove();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcase \"System.Runtime.CompilerServices.CompilationRelaxationsAttribute\":\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (arguments.Count == 1 && arguments.First() is PrimitiveExpression expr && expr.Value is int value && value == 8)\n\t\t\t\t\t\t\t\t\tattribute.Remove();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcase \"System.Runtime.CompilerServices.RuntimeCompatibilityAttribute\":\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (arguments.Count != 1)\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tif (!(arguments.First() is NamedExpression expr1) || expr1.Name != \"WrapNonExceptionThrows\")\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tif (!(expr1.Expression is PrimitiveExpression expr2) || !(expr2.Value is bool value) || value != true)\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tattribute.Remove();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcase \"System.Runtime.Versioning.TargetFrameworkAttribute\":\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tattribute.Remove();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcase \"System.Security.Permissions.SecurityPermissionAttribute\":\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (arguments.Count != 2)\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tif (!(arguments.First() is MemberReferenceExpression expr1) || expr1.MemberName != \"RequestMinimum\")\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tif (!(expr1.NextSibling is NamedExpression expr2) || expr2.Name != \"SkipVerification\")\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tif (!(expr2.Expression is PrimitiveExpression expr3) || !(expr3.Value is bool value2) || value2 != true)\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tattribute.Remove();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (section.AttributeTarget == \"module\")\n\t\t\t\t{\n\t\t\t\t\tforeach (var attribute in section.Attributes)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar trr = attribute.Type.Annotation<TypeResolveResult>();\n\t\t\t\t\t\tif (trr == null)\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\tswitch (trr.Type.FullName)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase \"System.Security.UnverifiableCodeAttribute\":\n\t\t\t\t\t\t\tcase \"System.Runtime.CompilerServices.RefSafetyRulesAttribute\":\n\t\t\t\t\t\t\t\tattribute.Remove();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (section.Attributes.Count == 0)\n\t\t\t\t{\n\t\t\t\t\tsection.Remove();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// This transform is used to remove attributes that are embedded \n\t/// </summary>\n\tpublic class RemoveEmbeddedAttributes : DepthFirstAstVisitor, IAstTransform\n\t{\n\t\tinternal static readonly HashSet<string> attributeNames = new HashSet<string>() {\n\t\t\t\"System.Runtime.CompilerServices.IsReadOnlyAttribute\",\n\t\t\t\"System.Runtime.CompilerServices.IsByRefLikeAttribute\",\n\t\t\t\"System.Runtime.CompilerServices.IsUnmanagedAttribute\",\n\t\t\t\"System.Runtime.CompilerServices.NullableAttribute\",\n\t\t\t\"System.Runtime.CompilerServices.NullableContextAttribute\",\n\t\t\t\"System.Runtime.CompilerServices.NativeIntegerAttribute\",\n\t\t\t\"System.Runtime.CompilerServices.ParamCollectionAttribute\",\n\t\t\t\"System.Runtime.CompilerServices.RefSafetyRulesAttribute\",\n\t\t\t\"System.Runtime.CompilerServices.ScopedRefAttribute\",\n\t\t\t\"System.Runtime.CompilerServices.RequiresLocationAttribute\",\n\t\t\t\"Microsoft.CodeAnalysis.EmbeddedAttribute\",\n\t\t};\n\n\t\tinternal static readonly HashSet<string> nonEmbeddedAttributeNames = new HashSet<string>() {\n\t\t\t// non-embedded attributes, but we still want to remove them\n\t\t\t\"System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute\",\n\t\t\t\"System.Runtime.CompilerServices.RequiredMemberAttribute\",\n\t\t\t\"System.Runtime.CompilerServices.IsExternalInit\",\n\t\t};\n\n\t\tpublic override void VisitTypeDeclaration(TypeDeclaration typeDeclaration)\n\t\t{\n\t\t\tvar typeDefinition = typeDeclaration.GetSymbol() as ITypeDefinition;\n\t\t\tif (typeDefinition == null)\n\t\t\t\treturn;\n\n\t\t\tif (attributeNames.Contains(typeDefinition.FullName))\n\t\t\t{\n\t\t\t\tif (!typeDefinition.HasAttribute(KnownAttribute.Embedded))\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t\telse if (!nonEmbeddedAttributeNames.Contains(typeDefinition.FullName))\n\t\t\t\treturn;\n\n\t\t\tif (typeDeclaration.Parent is NamespaceDeclaration ns && ns.Members.Count == 1)\n\t\t\t\tns.Remove();\n\t\t\telse\n\t\t\t\ttypeDeclaration.Remove();\n\t\t}\n\n\t\tpublic void Run(AstNode rootNode, TransformContext context)\n\t\t{\n\t\t\trootNode.AcceptVisitor(this);\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/FixNameCollisions.cs",
    "content": "// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\t/// <summary>\n\t/// Rename entities to solve name collisions that make the code uncompilable.\n\t/// </summary>\n\t/// <remarks>\n\t/// Currently, we only rename private fields that collide with property or event names.\n\t/// This helps especially with compiler-generated events that were not detected as a pattern.\n\t/// </remarks>\n\tpublic class FixNameCollisions : IAstTransform\n\t{\n\t\tpublic void Run(AstNode rootNode, TransformContext context)\n\t\t{\n\t\t\tvar renamedSymbols = new Dictionary<ISymbol, string>();\n\t\t\tforeach (var typeDecl in rootNode.DescendantsAndSelf.OfType<TypeDeclaration>())\n\t\t\t{\n\t\t\t\tvar memberNames = typeDecl.Members.Select(m => {\n\t\t\t\t\tvar type = m.GetChildByRole(EntityDeclaration.PrivateImplementationTypeRole);\n\t\t\t\t\treturn type.IsNull ? m.Name : type + \".\" + m.Name;\n\t\t\t\t}).ToHashSet();\n\t\t\t\t// memberNames does not include fields or non-custom events because those\n\t\t\t\t// don't have a single name, but a list of VariableInitializers.\n\t\t\t\tforeach (var fieldDecl in typeDecl.Members.OfType<FieldDeclaration>())\n\t\t\t\t{\n\t\t\t\t\tif (fieldDecl.Variables.Count != 1)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tstring oldName = fieldDecl.Variables.Single().Name;\n\t\t\t\t\tISymbol symbol = fieldDecl.GetSymbol();\n\t\t\t\t\tif (memberNames.Contains(oldName) && ((IField)symbol).Accessibility == Accessibility.Private)\n\t\t\t\t\t{\n\t\t\t\t\t\tstring newName = PickNewName(memberNames, oldName);\n\t\t\t\t\t\tif (symbol != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfieldDecl.Variables.Single().Name = newName;\n\t\t\t\t\t\t\trenamedSymbols[symbol] = newName;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach (var node in rootNode.DescendantsAndSelf)\n\t\t\t{\n\t\t\t\tif (node is IdentifierExpression || node is MemberReferenceExpression)\n\t\t\t\t{\n\t\t\t\t\tISymbol symbol = node.GetSymbol();\n\t\t\t\t\tif (symbol != null && renamedSymbols.TryGetValue(symbol, out string newName))\n\t\t\t\t\t{\n\t\t\t\t\t\tnode.GetChildByRole(Roles.Identifier).Name = newName;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstring PickNewName(ISet<string> memberNames, string name)\n\t\t{\n\t\t\tif (!memberNames.Contains(\"m_\" + name))\n\t\t\t\treturn \"m_\" + name;\n\t\t\tfor (int num = 2; ; num++)\n\t\t\t{\n\t\t\t\tstring newName = name + num;\n\t\t\t\tif (!memberNames.Contains(newName))\n\t\t\t\t\treturn newName;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/FlattenSwitchBlocks.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\tclass FlattenSwitchBlocks : IAstTransform\n\t{\n\t\tpublic void Run(AstNode rootNode, TransformContext context)\n\t\t{\n\t\t\tforeach (var switchSection in rootNode.Descendants.OfType<SwitchSection>())\n\t\t\t{\n\t\t\t\tif (switchSection.Statements.Count != 1)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tvar blockStatement = switchSection.Statements.First() as BlockStatement;\n\t\t\t\tif (blockStatement == null || blockStatement.Statements.Any(ContainsLocalDeclaration))\n\t\t\t\t\tcontinue;\n\n\t\t\t\tblockStatement.Remove();\n\t\t\t\tblockStatement.Statements.MoveTo(switchSection.Statements);\n\t\t\t}\n\n\t\t\tbool ContainsLocalDeclaration(AstNode node)\n\t\t\t{\n\t\t\t\tif (node is VariableDeclarationStatement || node is LocalFunctionDeclarationStatement || node is OutVarDeclarationExpression)\n\t\t\t\t\treturn true;\n\t\t\t\tif (node is BlockStatement)\n\t\t\t\t\treturn false;\n\t\t\t\tforeach (var child in node.Children)\n\t\t\t\t{\n\t\t\t\t\tif (ContainsLocalDeclaration(child))\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/IAstTransform.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\tpublic interface IAstTransform\n\t{\n\t\tvoid Run(AstNode rootNode, TransformContext context);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/IntroduceExtensionMethods.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Resolver;\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.CSharp.TypeSystem;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\t/// <summary>\n\t/// Converts extension method calls into infix syntax.\n\t/// </summary>\n\tpublic class IntroduceExtensionMethods : DepthFirstAstVisitor, IAstTransform\n\t{\n\t\tTransformContext context;\n\t\tCSharpResolver resolver;\n\t\tCSharpConversions conversions;\n\n\t\tpublic void Run(AstNode rootNode, TransformContext context)\n\t\t{\n\t\t\tthis.context = context;\n\t\t\tthis.conversions = CSharpConversions.Get(context.TypeSystem);\n\t\t\tInitializeContext(rootNode.Annotation<UsingScope>());\n\t\t\trootNode.AcceptVisitor(this);\n\t\t}\n\n\t\tvoid InitializeContext(UsingScope usingScope)\n\t\t{\n\t\t\tif (!string.IsNullOrEmpty(context.CurrentTypeDefinition?.Namespace))\n\t\t\t{\n\t\t\t\tforeach (string ns in context.CurrentTypeDefinition.Namespace.Split('.'))\n\t\t\t\t{\n\t\t\t\t\tusingScope = usingScope.WithNestedNamespace(ns);\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar currentContext = new CSharpTypeResolveContext(context.TypeSystem.MainModule, usingScope, context.CurrentTypeDefinition);\n\t\t\tthis.resolver = new CSharpResolver(currentContext);\n\t\t}\n\n\t\tpublic override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)\n\t\t{\n\t\t\tvar usingScope = resolver.CurrentUsingScope;\n\t\t\tforeach (string ident in namespaceDeclaration.Identifiers)\n\t\t\t{\n\t\t\t\tusingScope = usingScope.WithNestedNamespace(ident);\n\t\t\t}\n\t\t\tvar previousResolver = this.resolver;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tthis.resolver = this.resolver.WithCurrentUsingScope(usingScope);\n\t\t\t\tbase.VisitNamespaceDeclaration(namespaceDeclaration);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tthis.resolver = previousResolver;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void VisitTypeDeclaration(TypeDeclaration typeDeclaration)\n\t\t{\n\t\t\tvar previousResolver = this.resolver;\n\t\t\tthis.resolver = resolver.WithCurrentTypeDefinition(typeDeclaration.GetSymbol() as ITypeDefinition);\n\t\t\ttry\n\t\t\t{\n\t\t\t\tbase.VisitTypeDeclaration(typeDeclaration);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tthis.resolver = previousResolver;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void VisitInvocationExpression(InvocationExpression invocationExpression)\n\t\t{\n\t\t\tbase.VisitInvocationExpression(invocationExpression);\n\t\t\tif (!CanTransformToExtensionMethodCall(resolver, invocationExpression, out var memberRefExpr,\n\t\t\t\tout var target, out var firstArgument))\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar method = (IMethod)invocationExpression.GetSymbol();\n\t\t\tif (firstArgument is DirectionExpression dirExpr)\n\t\t\t{\n\t\t\t\tif (!context.Settings.RefExtensionMethods || dirExpr.FieldDirection == FieldDirection.Out)\n\t\t\t\t\treturn;\n\t\t\t\tfirstArgument = dirExpr.Expression;\n\t\t\t\ttarget = firstArgument.GetResolveResult();\n\t\t\t\tdirExpr.Detach();\n\t\t\t}\n\t\t\telse if (firstArgument is NullReferenceExpression)\n\t\t\t{\n\t\t\t\tDebug.Assert(context.RequiredNamespacesSuperset.Contains(method.Parameters[0].Type.Namespace));\n\t\t\t\tfirstArgument = firstArgument.ReplaceWith(expr => new CastExpression(context.TypeSystemAstBuilder.ConvertType(method.Parameters[0].Type), expr.Detach()));\n\t\t\t}\n\t\t\tif (invocationExpression.Target is IdentifierExpression identifierExpression)\n\t\t\t{\n\t\t\t\tidentifierExpression.Detach();\n\t\t\t\tmemberRefExpr = new MemberReferenceExpression(firstArgument.Detach(), method.Name, identifierExpression.TypeArguments.Detach());\n\t\t\t\tinvocationExpression.Target = memberRefExpr;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tmemberRefExpr.Target = firstArgument.Detach();\n\t\t\t}\n\t\t\tif (invocationExpression.GetResolveResult() is CSharpInvocationResolveResult irr)\n\t\t\t{\n\t\t\t\t// do not forget to update the CSharpInvocationResolveResult => set IsExtensionMethodInvocation == true\n\t\t\t\tinvocationExpression.RemoveAnnotations<CSharpInvocationResolveResult>();\n\t\t\t\tvar newResolveResult = new CSharpInvocationResolveResult(\n\t\t\t\t\tirr.TargetResult, irr.Member, irr.Arguments, irr.OverloadResolutionErrors,\n\t\t\t\t\tisExtensionMethodInvocation: true, irr.IsExpandedForm, irr.IsDelegateInvocation,\n\t\t\t\t\tirr.GetArgumentToParameterMap(), irr.InitializerStatements);\n\t\t\t\tinvocationExpression.AddAnnotation(newResolveResult);\n\t\t\t}\n\t\t}\n\n\t\tstatic bool CanTransformToExtensionMethodCall(CSharpResolver resolver,\n\t\t\tInvocationExpression invocationExpression, out MemberReferenceExpression memberRefExpr,\n\t\t\tout ResolveResult target,\n\t\t\tout Expression firstArgument)\n\t\t{\n\t\t\tvar method = invocationExpression.GetSymbol() as IMethod;\n\t\t\tmemberRefExpr = null;\n\t\t\ttarget = null;\n\t\t\tfirstArgument = null;\n\t\t\tif (method == null || !method.IsExtensionMethod || !invocationExpression.Arguments.Any())\n\t\t\t\treturn false;\n\t\t\tIReadOnlyList<IType> typeArguments;\n\t\t\tswitch (invocationExpression.Target)\n\t\t\t{\n\t\t\t\tcase MemberReferenceExpression mre:\n\t\t\t\t\ttypeArguments = mre.TypeArguments.Any() ? method.TypeArguments : EmptyList<IType>.Instance;\n\t\t\t\t\tmemberRefExpr = mre;\n\t\t\t\t\tbreak;\n\t\t\t\tcase IdentifierExpression ide:\n\t\t\t\t\ttypeArguments = ide.TypeArguments.Any() ? method.TypeArguments : EmptyList<IType>.Instance;\n\t\t\t\t\tmemberRefExpr = null;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tfirstArgument = invocationExpression.Arguments.First();\n\t\t\tif (firstArgument is NamedArgumentExpression)\n\t\t\t\treturn false;\n\t\t\ttarget = firstArgument.GetResolveResult();\n\t\t\tif (target is ConstantResolveResult crr && crr.ConstantValue == null)\n\t\t\t{\n\t\t\t\ttarget = new ConversionResolveResult(method.Parameters[0].Type, crr, Conversion.NullLiteralConversion);\n\t\t\t}\n\t\t\telse if (firstArgument is DirectionExpression de)\n\t\t\t{\n\t\t\t\ttarget = de.Expression.GetResolveResult();\n\t\t\t}\n\t\t\tDebug.Assert(target != null);\n\t\t\tResolveResult[] args = new ResolveResult[invocationExpression.Arguments.Count - 1];\n\t\t\tstring[] argNames = null;\n\t\t\tint pos = 0;\n\t\t\tforeach (var arg in invocationExpression.Arguments.Skip(1))\n\t\t\t{\n\t\t\t\tif (arg is NamedArgumentExpression nae)\n\t\t\t\t{\n\t\t\t\t\tif (argNames == null)\n\t\t\t\t\t{\n\t\t\t\t\t\targNames = new string[args.Length];\n\t\t\t\t\t}\n\t\t\t\t\targNames[pos] = nae.Name;\n\t\t\t\t\targs[pos] = nae.Expression.GetResolveResult();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\targs[pos] = arg.GetResolveResult();\n\t\t\t\t}\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\treturn resolver.CanTransformToExtensionMethodCall(method, typeArguments, target, args, argNames);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/IntroduceQueryExpressions.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.IL;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\t/// <summary>\n\t/// Decompiles query expressions.\n\t/// Based on C# 4.0 spec, §7.16.2 Query expression translation\n\t/// </summary>\n\tpublic class IntroduceQueryExpressions : IAstTransform\n\t{\n\t\tTransformContext context;\n\n\t\tpublic void Run(AstNode rootNode, TransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.QueryExpressions)\n\t\t\t\treturn;\n\t\t\tthis.context = context;\n\t\t\tDecompileQueries(rootNode);\n\t\t\t// After all queries were decompiled, detect degenerate queries (queries not property terminated with 'select' or 'group')\n\t\t\t// and fix them, either by adding a degenerate select, or by combining them with another query.\n\t\t\tforeach (QueryExpression query in rootNode.Descendants.OfType<QueryExpression>())\n\t\t\t{\n\t\t\t\tQueryFromClause fromClause = (QueryFromClause)query.Clauses.First();\n\t\t\t\tif (IsDegenerateQuery(query))\n\t\t\t\t{\n\t\t\t\t\t// introduce select for degenerate query\n\t\t\t\t\tquery.Clauses.Add(new QuerySelectClause { Expression = new IdentifierExpression(fromClause.Identifier).CopyAnnotationsFrom(fromClause) });\n\t\t\t\t}\n\t\t\t\t// See if the data source of this query is a degenerate query,\n\t\t\t\t// and combine the queries if possible.\n\t\t\t\tQueryExpression innerQuery = fromClause.Expression as QueryExpression;\n\t\t\t\twhile (IsDegenerateQuery(innerQuery))\n\t\t\t\t{\n\t\t\t\t\tQueryFromClause innerFromClause = (QueryFromClause)innerQuery.Clauses.First();\n\t\t\t\t\tILVariable innerVariable = innerFromClause.Annotation<ILVariableResolveResult>()?.Variable;\n\t\t\t\t\tILVariable rangeVariable = fromClause.Annotation<ILVariableResolveResult>()?.Variable;\n\t\t\t\t\t// Replace the fromClause with all clauses from the inner query\n\t\t\t\t\tfromClause.Remove();\n\t\t\t\t\tQueryClause insertionPos = null;\n\t\t\t\t\tforeach (var clause in innerQuery.Clauses)\n\t\t\t\t\t{\n\t\t\t\t\t\tCombineRangeVariables(clause, innerVariable, rangeVariable);\n\t\t\t\t\t\tquery.Clauses.InsertAfter(insertionPos, insertionPos = clause.Detach());\n\t\t\t\t\t}\n\t\t\t\t\tfromClause = innerFromClause;\n\t\t\t\t\tinnerQuery = fromClause.Expression as QueryExpression;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate void CombineRangeVariables(QueryClause clause, ILVariable oldVariable, ILVariable newVariable)\n\t\t{\n\t\t\tforeach (var identifier in clause.DescendantNodes().OfType<Identifier>())\n\t\t\t{\n\t\t\t\tvar variable = identifier.Parent.Annotation<ILVariableResolveResult>()?.Variable;\n\t\t\t\tif (variable == oldVariable)\n\t\t\t\t{\n\t\t\t\t\tidentifier.Parent.RemoveAnnotations<ILVariableResolveResult>();\n\t\t\t\t\tidentifier.Parent.AddAnnotation(new ILVariableResolveResult(newVariable));\n\t\t\t\t\tidentifier.ReplaceWith(Identifier.Create(newVariable.Name));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool IsDegenerateQuery(QueryExpression query)\n\t\t{\n\t\t\tif (query == null)\n\t\t\t\treturn false;\n\t\t\tvar lastClause = query.Clauses.LastOrDefault();\n\t\t\treturn !(lastClause is QuerySelectClause || lastClause is QueryGroupClause);\n\t\t}\n\n\t\tvoid DecompileQueries(AstNode node)\n\t\t{\n\t\t\tExpression query = DecompileQuery(node as InvocationExpression);\n\t\t\tif (query != null)\n\t\t\t{\n\t\t\t\tif (node.Parent is ExpressionStatement && CanUseDiscardAssignment())\n\t\t\t\t\tquery = new AssignmentExpression(new IdentifierExpression(\"_\"), query);\n\t\t\t\tnode.ReplaceWith(query);\n\t\t\t}\n\n\t\t\tAstNode next;\n\t\t\tfor (AstNode child = (query ?? node).FirstChild; child != null; child = next)\n\t\t\t{\n\t\t\t\t// store reference to next child before transformation\n\t\t\t\tnext = child.NextSibling;\n\t\t\t\tDecompileQueries(child);\n\t\t\t}\n\t\t}\n\n\t\tbool CanUseDiscardAssignment()\n\t\t{\n\t\t\t// TODO : check whether there exists a variable named '_' in scope.\n\t\t\treturn context.Settings.Discards;\n\t\t}\n\n\t\tQueryExpression DecompileQuery(InvocationExpression invocation)\n\t\t{\n\t\t\tif (invocation == null)\n\t\t\t\treturn null;\n\t\t\tMemberReferenceExpression mre = invocation.Target as MemberReferenceExpression;\n\t\t\tif (mre == null || IsNullConditional(mre.Target))\n\t\t\t\treturn null;\n\t\t\tswitch (mre.MemberName)\n\t\t\t{\n\t\t\t\tcase \"Select\":\n\t\t\t\t{\n\t\t\t\t\tif (invocation.Arguments.Count != 1)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tif (!IsComplexQuery(mre))\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tExpression expr = invocation.Arguments.Single();\n\t\t\t\t\tif (MatchSimpleLambda(expr, out ParameterDeclaration parameter, out Expression body))\n\t\t\t\t\t{\n\t\t\t\t\t\tQueryExpression query = new QueryExpression();\n\t\t\t\t\t\tquery.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach()));\n\t\t\t\t\t\tquery.Clauses.Add(new QuerySelectClause { Expression = WrapExpressionInParenthesesIfNecessary(body.Detach(), parameter.Name) }.CopyAnnotationsFrom(expr));\n\t\t\t\t\t\treturn query;\n\t\t\t\t\t}\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tcase \"GroupBy\":\n\t\t\t\t{\n\t\t\t\t\tif (invocation.Arguments.Count == 2)\n\t\t\t\t\t{\n\t\t\t\t\t\tExpression keyLambda = invocation.Arguments.ElementAt(0);\n\t\t\t\t\t\tExpression projectionLambda = invocation.Arguments.ElementAt(1);\n\t\t\t\t\t\tif (MatchSimpleLambda(keyLambda, out ParameterDeclaration parameter1, out Expression keySelector)\n\t\t\t\t\t\t\t&& MatchSimpleLambda(projectionLambda, out ParameterDeclaration parameter2, out Expression elementSelector)\n\t\t\t\t\t\t\t&& parameter1.Name == parameter2.Name)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tQueryExpression query = new QueryExpression();\n\t\t\t\t\t\t\tquery.Clauses.Add(MakeFromClause(parameter1, mre.Target.Detach()));\n\t\t\t\t\t\t\tvar queryGroupClause = new QueryGroupClause {\n\t\t\t\t\t\t\t\tProjection = elementSelector.Detach(),\n\t\t\t\t\t\t\t\tKey = keySelector.Detach()\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tqueryGroupClause.AddAnnotation(new QueryGroupClauseAnnotation(keyLambda.Annotation<IL.ILFunction>(), projectionLambda.Annotation<IL.ILFunction>()));\n\t\t\t\t\t\t\tquery.Clauses.Add(queryGroupClause);\n\t\t\t\t\t\t\treturn query;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (invocation.Arguments.Count == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tExpression lambda = invocation.Arguments.Single();\n\t\t\t\t\t\tif (MatchSimpleLambda(lambda, out ParameterDeclaration parameter, out Expression keySelector))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tQueryExpression query = new QueryExpression();\n\t\t\t\t\t\t\tquery.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach()));\n\t\t\t\t\t\t\tquery.Clauses.Add(new QueryGroupClause { Projection = new IdentifierExpression(parameter.Name).CopyAnnotationsFrom(parameter), Key = keySelector.Detach() });\n\t\t\t\t\t\t\treturn query;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tcase \"SelectMany\":\n\t\t\t\t{\n\t\t\t\t\tif (invocation.Arguments.Count != 2)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tvar fromExpressionLambda = invocation.Arguments.ElementAt(0);\n\t\t\t\t\tif (!MatchSimpleLambda(fromExpressionLambda, out ParameterDeclaration parameter, out Expression collectionSelector))\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tif (IsNullConditional(collectionSelector))\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tLambdaExpression lambda = invocation.Arguments.ElementAt(1) as LambdaExpression;\n\t\t\t\t\tif (lambda != null && lambda.Parameters.Count == 2 && lambda.Body is Expression)\n\t\t\t\t\t{\n\t\t\t\t\t\tParameterDeclaration p1 = lambda.Parameters.ElementAt(0);\n\t\t\t\t\t\tParameterDeclaration p2 = lambda.Parameters.ElementAt(1);\n\t\t\t\t\t\tif (p1.Name == parameter.Name)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tQueryExpression query = new QueryExpression();\n\t\t\t\t\t\t\tquery.Clauses.Add(MakeFromClause(p1, mre.Target.Detach()));\n\t\t\t\t\t\t\tquery.Clauses.Add(MakeFromClause(p2, collectionSelector.Detach()).CopyAnnotationsFrom(fromExpressionLambda));\n\t\t\t\t\t\t\tquery.Clauses.Add(new QuerySelectClause { Expression = WrapExpressionInParenthesesIfNecessary(((Expression)lambda.Body).Detach(), parameter.Name) });\n\t\t\t\t\t\t\treturn query;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tcase \"Where\":\n\t\t\t\t{\n\t\t\t\t\tif (invocation.Arguments.Count != 1)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tif (!IsComplexQuery(mre))\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tExpression expr = invocation.Arguments.Single();\n\t\t\t\t\tif (MatchSimpleLambda(expr, out ParameterDeclaration parameter, out Expression body))\n\t\t\t\t\t{\n\t\t\t\t\t\tQueryExpression query = new QueryExpression();\n\t\t\t\t\t\tquery.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach()));\n\t\t\t\t\t\tquery.Clauses.Add(new QueryWhereClause { Condition = body.Detach() }.CopyAnnotationsFrom(expr));\n\t\t\t\t\t\treturn query;\n\t\t\t\t\t}\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tcase \"OrderBy\":\n\t\t\t\tcase \"OrderByDescending\":\n\t\t\t\tcase \"ThenBy\":\n\t\t\t\tcase \"ThenByDescending\":\n\t\t\t\t{\n\t\t\t\t\tif (invocation.Arguments.Count != 1)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tif (!IsComplexQuery(mre))\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tvar lambda = invocation.Arguments.Single();\n\t\t\t\t\tif (MatchSimpleLambda(lambda, out ParameterDeclaration parameter, out Expression orderExpression))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (ValidateThenByChain(invocation, parameter.Name))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tQueryOrderClause orderClause = new QueryOrderClause();\n\t\t\t\t\t\t\twhile (mre.MemberName == \"ThenBy\" || mre.MemberName == \"ThenByDescending\")\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// insert new ordering at beginning\n\t\t\t\t\t\t\t\torderClause.Orderings.InsertAfter(\n\t\t\t\t\t\t\t\t\tnull, new QueryOrdering {\n\t\t\t\t\t\t\t\t\t\tExpression = orderExpression.Detach(),\n\t\t\t\t\t\t\t\t\t\tDirection = (mre.MemberName == \"ThenBy\" ? QueryOrderingDirection.None : QueryOrderingDirection.Descending)\n\t\t\t\t\t\t\t\t\t}.CopyAnnotationsFrom(lambda));\n\n\t\t\t\t\t\t\t\tInvocationExpression tmp = (InvocationExpression)mre.Target;\n\t\t\t\t\t\t\t\tmre = (MemberReferenceExpression)tmp.Target;\n\t\t\t\t\t\t\t\tlambda = tmp.Arguments.Single();\n\t\t\t\t\t\t\t\tMatchSimpleLambda(lambda, out parameter, out orderExpression);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// insert new ordering at beginning\n\t\t\t\t\t\t\torderClause.Orderings.InsertAfter(\n\t\t\t\t\t\t\t\tnull, new QueryOrdering {\n\t\t\t\t\t\t\t\t\tExpression = orderExpression.Detach(),\n\t\t\t\t\t\t\t\t\tDirection = (mre.MemberName == \"OrderBy\" ? QueryOrderingDirection.None : QueryOrderingDirection.Descending)\n\t\t\t\t\t\t\t\t}.CopyAnnotationsFrom(lambda));\n\n\t\t\t\t\t\t\tQueryExpression query = new QueryExpression();\n\t\t\t\t\t\t\tquery.Clauses.Add(MakeFromClause(parameter, mre.Target.Detach()));\n\t\t\t\t\t\t\tquery.Clauses.Add(orderClause);\n\t\t\t\t\t\t\treturn query;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tcase \"Join\":\n\t\t\t\tcase \"GroupJoin\":\n\t\t\t\t{\n\t\t\t\t\tif (invocation.Arguments.Count != 4)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tExpression source1 = mre.Target;\n\t\t\t\t\tExpression source2 = invocation.Arguments.ElementAt(0);\n\t\t\t\t\tif (IsNullConditional(source2))\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tExpression outerLambda = invocation.Arguments.ElementAt(1);\n\t\t\t\t\tif (!MatchSimpleLambda(outerLambda, out ParameterDeclaration element1, out Expression key1))\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tExpression innerLambda = invocation.Arguments.ElementAt(2);\n\t\t\t\t\tif (!MatchSimpleLambda(innerLambda, out ParameterDeclaration element2, out Expression key2))\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tLambdaExpression lambda = invocation.Arguments.ElementAt(3) as LambdaExpression;\n\t\t\t\t\tif (lambda != null && lambda.Parameters.Count == 2 && lambda.Body is Expression)\n\t\t\t\t\t{\n\t\t\t\t\t\tParameterDeclaration p1 = lambda.Parameters.ElementAt(0);\n\t\t\t\t\t\tParameterDeclaration p2 = lambda.Parameters.ElementAt(1);\n\t\t\t\t\t\tif (ValidateParameter(p1) && ValidateParameter(p2)\n\t\t\t\t\t\t\t&& p1.Name == element1.Name && (p2.Name == element2.Name || mre.MemberName == \"GroupJoin\"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tQueryExpression query = new QueryExpression();\n\t\t\t\t\t\t\tquery.Clauses.Add(MakeFromClause(element1, source1.Detach()));\n\t\t\t\t\t\t\tQueryJoinClause joinClause = new QueryJoinClause();\n\t\t\t\t\t\t\tjoinClause.JoinIdentifier = element2.Name;    // join elementName2\n\t\t\t\t\t\t\tjoinClause.JoinIdentifierToken.CopyAnnotationsFrom(element2);\n\t\t\t\t\t\t\tjoinClause.InExpression = source2.Detach();  // in source2\n\t\t\t\t\t\t\tjoinClause.OnExpression = key1.Detach();     // on key1\n\t\t\t\t\t\t\tjoinClause.EqualsExpression = key2.Detach(); // equals key2\n\t\t\t\t\t\t\tif (mre.MemberName == \"GroupJoin\")\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tjoinClause.IntoIdentifier = p2.Name; // into p2.Name\n\t\t\t\t\t\t\t\tjoinClause.IntoIdentifierToken.CopyAnnotationsFrom(p2);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tjoinClause.AddAnnotation(new QueryJoinClauseAnnotation(outerLambda.Annotation<IL.ILFunction>(), innerLambda.Annotation<IL.ILFunction>()));\n\t\t\t\t\t\t\tquery.Clauses.Add(joinClause);\n\t\t\t\t\t\t\tquery.Clauses.Add(new QuerySelectClause { Expression = ((Expression)lambda.Body).Detach() }.CopyAnnotationsFrom(lambda));\n\t\t\t\t\t\t\treturn query;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tstatic bool IsComplexQuery(MemberReferenceExpression mre)\n\t\t{\n\t\t\treturn ((mre.Target is InvocationExpression && mre.Parent is InvocationExpression) || mre.Parent?.Parent is QueryClause);\n\t\t}\n\n\t\tQueryFromClause MakeFromClause(ParameterDeclaration parameter, Expression body)\n\t\t{\n\t\t\tQueryFromClause fromClause = new QueryFromClause {\n\t\t\t\tIdentifier = parameter.Name,\n\t\t\t\tExpression = body\n\t\t\t};\n\t\t\tfromClause.CopyAnnotationsFrom(parameter);\n\t\t\treturn fromClause;\n\t\t}\n\n\t\tclass ApplyAnnotationVisitor : DepthFirstAstVisitor<AstNode>\n\t\t{\n\t\t\tprivate LetIdentifierAnnotation annotation;\n\t\t\tprivate string identifier;\n\n\t\t\tpublic ApplyAnnotationVisitor(LetIdentifierAnnotation annotation, string identifier)\n\t\t\t{\n\t\t\t\tthis.annotation = annotation;\n\t\t\t\tthis.identifier = identifier;\n\t\t\t}\n\n\t\t\tpublic override AstNode VisitIdentifier(Identifier identifier)\n\t\t\t{\n\t\t\t\tif (identifier.Name == this.identifier)\n\t\t\t\t\tidentifier.AddAnnotation(annotation);\n\t\t\t\treturn identifier;\n\t\t\t}\n\t\t}\n\n\t\tbool IsNullConditional(Expression target)\n\t\t{\n\t\t\treturn target is UnaryOperatorExpression uoe && uoe.Operator == UnaryOperatorType.NullConditional;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// This fixes #437: Decompilation of query expression loses material parentheses\n\t\t/// We wrap the expression in parentheses if:\n\t\t/// - the Select-call is explicit (see caller(s))\n\t\t/// - the expression is a plain identifier matching the parameter name\n\t\t/// </summary>\n\t\tExpression WrapExpressionInParenthesesIfNecessary(Expression expression, string parameterName)\n\t\t{\n\t\t\tif (expression is IdentifierExpression ident && parameterName.Equals(ident.Identifier, StringComparison.Ordinal))\n\t\t\t\treturn new ParenthesizedExpression(expression);\n\t\t\treturn expression;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Ensure that all ThenBy's are correct, and that the list of ThenBy's is terminated by an 'OrderBy' invocation.\n\t\t/// </summary>\n\t\tbool ValidateThenByChain(InvocationExpression invocation, string expectedParameterName)\n\t\t{\n\t\t\tif (invocation == null || invocation.Arguments.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (!(invocation.Target is MemberReferenceExpression mre))\n\t\t\t\treturn false;\n\t\t\tif (!MatchSimpleLambda(invocation.Arguments.Single(), out ParameterDeclaration parameter, out _))\n\t\t\t\treturn false;\n\t\t\tif (parameter.Name != expectedParameterName)\n\t\t\t\treturn false;\n\n\t\t\tif (mre.MemberName == \"OrderBy\" || mre.MemberName == \"OrderByDescending\")\n\t\t\t\treturn !IsNullConditional(mre.Target);\n\t\t\telse if (mre.MemberName == \"ThenBy\" || mre.MemberName == \"ThenByDescending\")\n\t\t\t\treturn ValidateThenByChain(mre.Target as InvocationExpression, expectedParameterName);\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>Matches simple lambdas of the form \"a => b\"</summary>\n\t\tbool MatchSimpleLambda(Expression expr, out ParameterDeclaration parameter, out Expression body)\n\t\t{\n\t\t\tif (expr is LambdaExpression lambda && lambda.Parameters.Count == 1 && lambda.Body is Expression)\n\t\t\t{\n\t\t\t\tParameterDeclaration p = lambda.Parameters.Single();\n\t\t\t\tif (ValidateParameter(p))\n\t\t\t\t{\n\t\t\t\t\tparameter = p;\n\t\t\t\t\tbody = (Expression)lambda.Body;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tparameter = null;\n\t\t\tbody = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tprivate static bool ValidateParameter(ParameterDeclaration p)\n\t\t{\n\t\t\treturn p.ParameterModifier == Decompiler.TypeSystem.ReferenceKind.None && p.Attributes.Count == 0;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUnsafeModifier.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Resolver;\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\tpublic class IntroduceUnsafeModifier : DepthFirstAstVisitor<bool>, IAstTransform\n\t{\n\t\tpublic void Run(AstNode compilationUnit, TransformContext context)\n\t\t{\n\t\t\tcompilationUnit.AcceptVisitor(this);\n\t\t}\n\n\t\tpublic static bool IsUnsafe(AstNode node)\n\t\t{\n\t\t\treturn node.AcceptVisitor(new IntroduceUnsafeModifier());\n\t\t}\n\n\t\tprotected override bool VisitChildren(AstNode node)\n\t\t{\n\t\t\tbool result = false;\n\t\t\tAstNode next;\n\t\t\tfor (AstNode child = node.FirstChild; child != null; child = next)\n\t\t\t{\n\t\t\t\t// Store next to allow the loop to continue\n\t\t\t\t// if the visitor removes/replaces child.\n\t\t\t\tnext = child.NextSibling;\n\t\t\t\tresult |= child.AcceptVisitor(this);\n\t\t\t}\n\t\t\tif (result && node is EntityDeclaration && !(node is Accessor))\n\t\t\t{\n\t\t\t\t((EntityDeclaration)node).Modifiers |= Modifiers.Unsafe;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic override bool VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression)\n\t\t{\n\t\t\tbase.VisitPointerReferenceExpression(pointerReferenceExpression);\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic override bool VisitSizeOfExpression(SizeOfExpression sizeOfExpression)\n\t\t{\n\t\t\t// C# sizeof(MyStruct) requires unsafe{}\n\t\t\t// (not for sizeof(int), but that gets constant-folded and thus decompiled to 4)\n\t\t\tbase.VisitSizeOfExpression(sizeOfExpression);\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic override bool VisitComposedType(ComposedType composedType)\n\t\t{\n\t\t\tif (composedType.PointerRank > 0)\n\t\t\t\treturn true;\n\t\t\telse\n\t\t\t\treturn base.VisitComposedType(composedType);\n\t\t}\n\n\t\tpublic override bool VisitFunctionPointerType(FunctionPointerAstType functionPointerType)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic override bool VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression)\n\t\t{\n\t\t\tbool result = base.VisitUnaryOperatorExpression(unaryOperatorExpression);\n\t\t\tif (unaryOperatorExpression.Operator == UnaryOperatorType.Dereference)\n\t\t\t{\n\t\t\t\tvar bop = unaryOperatorExpression.Expression as BinaryOperatorExpression;\n\t\t\t\tif (bop != null && bop.Operator == BinaryOperatorType.Add\n\t\t\t\t\t&& bop.GetResolveResult() is OperatorResolveResult orr\n\t\t\t\t\t&& orr.Operands.FirstOrDefault()?.Type.Kind == TypeKind.Pointer)\n\t\t\t\t{\n\t\t\t\t\t// transform \"*(ptr + int)\" to \"ptr[int]\"\n\t\t\t\t\tIndexerExpression indexer = new IndexerExpression();\n\t\t\t\t\tindexer.Target = bop.Left.Detach();\n\t\t\t\t\tindexer.Arguments.Add(bop.Right.Detach());\n\t\t\t\t\tindexer.CopyAnnotationsFrom(unaryOperatorExpression);\n\t\t\t\t\tindexer.CopyAnnotationsFrom(bop);\n\t\t\t\t\tunaryOperatorExpression.ReplaceWith(indexer);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (unaryOperatorExpression.Operator == UnaryOperatorType.AddressOf)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression)\n\t\t{\n\t\t\tbool result = base.VisitMemberReferenceExpression(memberReferenceExpression);\n\t\t\tUnaryOperatorExpression uoe = memberReferenceExpression.Target as UnaryOperatorExpression;\n\t\t\tif (uoe != null && uoe.Operator == UnaryOperatorType.Dereference)\n\t\t\t{\n\t\t\t\tPointerReferenceExpression pre = new PointerReferenceExpression();\n\t\t\t\tpre.Target = uoe.Expression.Detach();\n\t\t\t\tpre.MemberName = memberReferenceExpression.MemberName;\n\t\t\t\tmemberReferenceExpression.TypeArguments.MoveTo(pre.TypeArguments);\n\t\t\t\tpre.CopyAnnotationsFrom(uoe);\n\t\t\t\tpre.RemoveAnnotations<ResolveResult>(); // only copy the ResolveResult from the MRE\n\t\t\t\tpre.CopyAnnotationsFrom(memberReferenceExpression);\n\t\t\t\tmemberReferenceExpression.ReplaceWith(pre);\n\t\t\t}\n\t\t\tif (HasUnsafeResolveResult(memberReferenceExpression))\n\t\t\t\treturn true;\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic override bool VisitIdentifierExpression(IdentifierExpression identifierExpression)\n\t\t{\n\t\t\tbool result = base.VisitIdentifierExpression(identifierExpression);\n\t\t\tif (HasUnsafeResolveResult(identifierExpression))\n\t\t\t\treturn true;\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic override bool VisitStackAllocExpression(StackAllocExpression stackAllocExpression)\n\t\t{\n\t\t\tbool result = base.VisitStackAllocExpression(stackAllocExpression);\n\t\t\tif (HasUnsafeResolveResult(stackAllocExpression))\n\t\t\t\treturn true;\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic override bool VisitInvocationExpression(InvocationExpression invocationExpression)\n\t\t{\n\t\t\tbool result = base.VisitInvocationExpression(invocationExpression);\n\t\t\tif (HasUnsafeResolveResult(invocationExpression))\n\t\t\t\treturn true;\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic override bool VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer)\n\t\t{\n\t\t\tbase.VisitFixedVariableInitializer(fixedVariableInitializer);\n\t\t\treturn true;\n\t\t}\n\n\t\tprivate bool HasUnsafeResolveResult(AstNode node)\n\t\t{\n\t\t\tvar rr = node.GetResolveResult();\n\t\t\tif (rr == null)\n\t\t\t\treturn false;\n\t\t\tif (IsUnsafeType(rr.Type))\n\t\t\t\treturn true;\n\t\t\tif ((rr as MemberResolveResult)?.Member is IParameterizedMember pm)\n\t\t\t{\n\t\t\t\tif (pm.Parameters.Any(p => IsUnsafeType(p.Type)))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (rr is MethodGroupResolveResult)\n\t\t\t{\n\t\t\t\tvar chosenMethod = node.GetSymbol();\n\t\t\t\tif (chosenMethod is IParameterizedMember pm2)\n\t\t\t\t{\n\t\t\t\t\tif (IsUnsafeType(pm2.ReturnType))\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tif (pm2.Parameters.Any(p => IsUnsafeType(p.Type)))\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tprivate bool IsUnsafeType(IType type)\n\t\t{\n\t\t\tswitch (type?.Kind)\n\t\t\t{\n\t\t\t\tcase TypeKind.Pointer:\n\t\t\t\tcase TypeKind.FunctionPointer:\n\t\t\t\t\treturn true;\n\t\t\t\tcase TypeKind.ByReference:\n\t\t\t\tcase TypeKind.Array:\n\t\t\t\t\treturn IsUnsafeType(((Decompiler.TypeSystem.Implementation.TypeWithElementType)type).ElementType);\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Resolver;\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.CSharp.TypeSystem;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\t/// <summary>\n\t/// Introduces using declarations.\n\t/// </summary>\n\tpublic class IntroduceUsingDeclarations : IAstTransform\n\t{\n\t\tpublic void Run(AstNode rootNode, TransformContext context)\n\t\t{\n\t\t\t// First determine all the namespaces that need to be imported:\n\t\t\tvar requiredImports = new FindRequiredImports(context);\n\t\t\trootNode.AcceptVisitor(requiredImports);\n\n\t\t\tList<INamespace> resolvedNamespaces = new List<INamespace>();\n\n\t\t\tif (context.Settings.UsingDeclarations)\n\t\t\t{\n\t\t\t\tvar insertionPoint = rootNode.Children.LastOrDefault(n => n is PreProcessorDirective p && p.Type == PreProcessorDirectiveType.Define);\n\n\t\t\t\t// Now add using declarations for those namespaces:\n\t\t\t\tIOrderedEnumerable<string> sortedImports = requiredImports.ImportedNamespaces\n\t\t\t\t\t.OrderBy(n => n.StartsWith(\"System\", StringComparison.Ordinal))\n\t\t\t\t\t.ThenByDescending(n => n);\n\t\t\t\tforeach (string ns in sortedImports)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(context.RequiredNamespacesSuperset.Contains(ns), $\"Should not insert using declaration for namespace that is missing from the superset: {ns}\");\n\t\t\t\t\t// we go backwards (OrderByDescending) through the list of namespaces because we insert them backwards\n\t\t\t\t\t// (always inserting at the start of the list)\n\t\t\t\t\tstring[] parts = ns.Split('.');\n\t\t\t\t\tAstType nsType = new SimpleType(parts[0]);\n\t\t\t\t\tfor (int i = 1; i < parts.Length; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tnsType = new MemberType { Target = nsType, MemberName = parts[i] };\n\t\t\t\t\t}\n\t\t\t\t\tvar resolvedNamespace = context.TypeSystem.GetNamespaceByFullName(ns);\n\t\t\t\t\tif (resolvedNamespace != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tresolvedNamespaces.Add(resolvedNamespace);\n\t\t\t\t\t}\n\t\t\t\t\trootNode.InsertChildAfter(insertionPoint, new UsingDeclaration { Import = nsType }, SyntaxTree.MemberRole);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar usingScope = new UsingScope(\n\t\t\t\tnew CSharpTypeResolveContext(context.TypeSystem.MainModule),\n\t\t\t\tcontext.TypeSystem.RootNamespace,\n\t\t\t\tresolvedNamespaces.ToImmutableArray()\n\t\t\t);\n\t\t\trootNode.AddAnnotation(usingScope);\n\n\t\t\t// verify that the SimpleTypes refer to the correct type (no ambiguities)\n\t\t\trootNode.AcceptVisitor(new FullyQualifyAmbiguousTypeNamesVisitor(context, usingScope));\n\t\t}\n\n\t\tsealed class FindRequiredImports : DepthFirstAstVisitor\n\t\t{\n\t\t\tstring currentNamespace;\n\n\t\t\tpublic readonly HashSet<string> DeclaredNamespaces = new HashSet<string>() { string.Empty };\n\t\t\tpublic readonly HashSet<string> ImportedNamespaces = new HashSet<string>();\n\n\t\t\tpublic FindRequiredImports(TransformContext context)\n\t\t\t{\n\t\t\t\tthis.currentNamespace = context.CurrentTypeDefinition?.Namespace ?? string.Empty;\n\t\t\t}\n\n\t\t\tbool IsParentOfCurrentNamespace(string ns)\n\t\t\t{\n\t\t\t\tif (ns.Length == 0)\n\t\t\t\t\treturn true;\n\t\t\t\tif (currentNamespace.StartsWith(ns, StringComparison.Ordinal))\n\t\t\t\t{\n\t\t\t\t\tif (currentNamespace.Length == ns.Length)\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tif (currentNamespace[ns.Length] == '.')\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tpublic override void VisitSimpleType(SimpleType simpleType)\n\t\t\t{\n\t\t\t\tvar trr = simpleType.Annotation<TypeResolveResult>();\n\t\t\t\tAddImportedNamespace(trr?.Type);\n\t\t\t\tbase.VisitSimpleType(simpleType); // also visit type arguments\n\t\t\t}\n\n\t\t\tprivate void AddImportedNamespace(IType type)\n\t\t\t{\n\t\t\t\tif (type != null && !IsParentOfCurrentNamespace(type.Namespace))\n\t\t\t\t{\n\t\t\t\t\tImportedNamespaces.Add(type.Namespace);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)\n\t\t\t{\n\t\t\t\tstring oldNamespace = currentNamespace;\n\t\t\t\tforeach (string ident in namespaceDeclaration.Identifiers)\n\t\t\t\t{\n\t\t\t\t\tcurrentNamespace = NamespaceDeclaration.BuildQualifiedName(currentNamespace, ident);\n\t\t\t\t\tDeclaredNamespaces.Add(currentNamespace);\n\t\t\t\t}\n\t\t\t\tbase.VisitNamespaceDeclaration(namespaceDeclaration);\n\t\t\t\tcurrentNamespace = oldNamespace;\n\t\t\t}\n\n\t\t\tpublic override void VisitForeachStatement(ForeachStatement foreachStatement)\n\t\t\t{\n\t\t\t\tvar annotation = foreachStatement.Annotation<ForeachAnnotation>();\n\t\t\t\tif (annotation?.GetEnumeratorCall is CallInstruction { Method: { IsExtensionMethod: true, DeclaringType: var type } })\n\t\t\t\t{\n\t\t\t\t\tAddImportedNamespace(type);\n\t\t\t\t}\n\t\t\t\tbase.VisitForeachStatement(foreachStatement);\n\t\t\t}\n\n\t\t\tpublic override void VisitParenthesizedVariableDesignation(ParenthesizedVariableDesignation parenthesizedVariableDesignation)\n\t\t\t{\n\t\t\t\tvar annotation = parenthesizedVariableDesignation.Annotation<MatchInstruction>();\n\t\t\t\tif (annotation?.Method is IMethod { DeclaringType: var type })\n\t\t\t\t{\n\t\t\t\t\tAddImportedNamespace(type);\n\t\t\t\t}\n\t\t\t\tbase.VisitParenthesizedVariableDesignation(parenthesizedVariableDesignation);\n\t\t\t}\n\n\t\t\tpublic override void VisitTupleExpression(TupleExpression tupleExpression)\n\t\t\t{\n\t\t\t\tvar annotation = tupleExpression.Annotation<MatchInstruction>();\n\t\t\t\tif (annotation?.Method is IMethod { DeclaringType: var type })\n\t\t\t\t{\n\t\t\t\t\tAddImportedNamespace(type);\n\t\t\t\t}\n\t\t\t\tbase.VisitTupleExpression(tupleExpression);\n\t\t\t}\n\n\t\t\tpublic override void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)\n\t\t\t{\n\t\t\t\tforeach (var item in arrayInitializerExpression.Elements)\n\t\t\t\t{\n\t\t\t\t\tvar optionalCall = item.Annotation<CallInstruction>();\n\t\t\t\t\tif (optionalCall?.Method is { IsExtensionMethod: true, Name: \"Add\" })\n\t\t\t\t\t{\n\t\t\t\t\t\tAddImportedNamespace(optionalCall.Method.DeclaringType);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbase.VisitArrayInitializerExpression(arrayInitializerExpression);\n\t\t\t}\n\t\t}\n\n\t\tsealed class FullyQualifyAmbiguousTypeNamesVisitor : DepthFirstAstVisitor\n\t\t{\n\t\t\treadonly bool ignoreUsingScope;\n\t\t\treadonly DecompilerSettings settings;\n\n\t\t\tCSharpResolver resolver;\n\t\t\tTypeSystemAstBuilder astBuilder;\n\n\t\t\tbool inPrimaryConstructor;\n\n\t\t\tpublic FullyQualifyAmbiguousTypeNamesVisitor(TransformContext context, UsingScope usingScope)\n\t\t\t{\n\t\t\t\tthis.ignoreUsingScope = !context.Settings.UsingDeclarations;\n\t\t\t\tthis.settings = context.Settings;\n\t\t\t\tthis.resolver = new CSharpResolver(new CSharpTypeResolveContext(context.TypeSystem.MainModule));\n\n\t\t\t\tif (!ignoreUsingScope)\n\t\t\t\t{\n\t\t\t\t\tif (!string.IsNullOrEmpty(context.CurrentTypeDefinition?.Namespace))\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (string ns in context.CurrentTypeDefinition.Namespace.Split('.'))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tusingScope = usingScope.WithNestedNamespace(ns);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis.resolver = this.resolver.WithCurrentUsingScope(usingScope)\n\t\t\t\t\t\t.WithCurrentTypeDefinition(context.CurrentTypeDefinition);\n\t\t\t\t}\n\t\t\t\tthis.astBuilder = CreateAstBuilder(resolver);\n\t\t\t}\n\n\t\t\tTypeSystemAstBuilder CreateAstBuilder(CSharpResolver resolver, IL.ILFunction function = null)\n\t\t\t{\n\t\t\t\tif (function != null)\n\t\t\t\t{\n\t\t\t\t\tvar variables = new Dictionary<string, IVariable>();\n\t\t\t\t\tforeach (var v in function.Variables)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (v.Kind != IL.VariableKind.Parameter && v.Name != null && !variables.ContainsKey(v.Name))\n\t\t\t\t\t\t\tvariables.Add(v.Name, new DefaultVariable(v.Type, v.Name));\n\t\t\t\t\t}\n\t\t\t\t\tresolver = resolver.AddVariables(variables);\n\t\t\t\t}\n\n\t\t\t\treturn new TypeSystemAstBuilder(resolver) {\n\t\t\t\t\tUseNullableSpecifierForValueTypes = settings.LiftNullables,\n\t\t\t\t\tAlwaysUseGlobal = settings.AlwaysUseGlobal,\n\t\t\t\t\tAddResolveResultAnnotations = true,\n\t\t\t\t\tUseAliases = true\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tpublic override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)\n\t\t\t{\n\t\t\t\tif (ignoreUsingScope)\n\t\t\t\t{\n\t\t\t\t\tbase.VisitNamespaceDeclaration(namespaceDeclaration);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tvar previousResolver = resolver;\n\t\t\t\tvar previousAstBuilder = astBuilder;\n\t\t\t\tvar usingScope = resolver.CurrentUsingScope;\n\t\t\t\tforeach (string ident in namespaceDeclaration.Identifiers)\n\t\t\t\t{\n\t\t\t\t\tusingScope = usingScope.WithNestedNamespace(ident);\n\t\t\t\t}\n\t\t\t\tresolver = resolver.WithCurrentUsingScope(usingScope);\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tastBuilder = CreateAstBuilder(resolver);\n\t\t\t\t\tbase.VisitNamespaceDeclaration(namespaceDeclaration);\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tastBuilder = previousAstBuilder;\n\t\t\t\t\tresolver = previousResolver;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void VisitTypeDeclaration(TypeDeclaration typeDeclaration)\n\t\t\t{\n\t\t\t\tif (ignoreUsingScope)\n\t\t\t\t{\n\t\t\t\t\tbase.VisitTypeDeclaration(typeDeclaration);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (typeDeclaration.HasPrimaryConstructor)\n\t\t\t\t{\n\t\t\t\t\tinPrimaryConstructor = true;\n\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\ttypeDeclaration.PrimaryConstructorParameters.AcceptVisitor(this);\n\t\t\t\t\t}\n\t\t\t\t\tfinally\n\t\t\t\t\t{\n\t\t\t\t\t\tinPrimaryConstructor = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar previousResolver = resolver;\n\t\t\t\tvar previousAstBuilder = astBuilder;\n\n\t\t\t\tresolver = resolver.WithCurrentTypeDefinition(typeDeclaration.GetSymbol() as ITypeDefinition);\n\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tastBuilder = CreateAstBuilder(resolver);\n\t\t\t\t\tbase.VisitTypeDeclaration(typeDeclaration);\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tastBuilder = previousAstBuilder;\n\t\t\t\t\tresolver = previousResolver;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration)\n\t\t\t{\n\t\t\t\t// Parameters of primary constructors are visited separately from the rest of the\n\t\t\t\t// type declaration since their types are at the same scope as the type declaration\n\t\t\t\t// and so need to use the outer resolver. This check ensures that the visitor only\n\t\t\t\t// runs once per parameter since their AstNodes will get revisited by the call to\n\t\t\t\t// `base.VisitTypeDeclaration(typeDeclaration)` in `VisitTypeDeclaration` above.\n\t\t\t\tif (inPrimaryConstructor || parameterDeclaration.Parent is not TypeDeclaration)\n\t\t\t\t\tbase.VisitParameterDeclaration(parameterDeclaration);\n\t\t\t}\n\n\t\t\tpublic override void VisitMethodDeclaration(MethodDeclaration methodDeclaration)\n\t\t\t{\n\t\t\t\tVisit(methodDeclaration, base.VisitMethodDeclaration);\n\t\t\t}\n\n\t\t\tpublic override void VisitAccessor(Accessor accessor)\n\t\t\t{\n\t\t\t\tVisit(accessor, base.VisitAccessor);\n\t\t\t}\n\n\t\t\tpublic override void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)\n\t\t\t{\n\t\t\t\tVisit(constructorDeclaration, base.VisitConstructorDeclaration);\n\t\t\t}\n\n\t\t\tpublic override void VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration)\n\t\t\t{\n\t\t\t\tVisit(destructorDeclaration, base.VisitDestructorDeclaration);\n\t\t\t}\n\n\t\t\tpublic override void VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration)\n\t\t\t{\n\t\t\t\tVisit(operatorDeclaration, base.VisitOperatorDeclaration);\n\t\t\t}\n\n\t\t\tvoid Visit<T>(T entityDeclaration, Action<T> baseCall) where T : EntityDeclaration\n\t\t\t{\n\t\t\t\tif (ignoreUsingScope)\n\t\t\t\t{\n\t\t\t\t\tbaseCall(entityDeclaration);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (entityDeclaration.GetSymbol() is IMethod method)\n\t\t\t\t{\n\t\t\t\t\tvar previousResolver = resolver;\n\t\t\t\t\tvar previousAstBuilder = astBuilder;\n\t\t\t\t\tif (CSharpDecompiler.IsWindowsFormsInitializeComponentMethod(method))\n\t\t\t\t\t{\n\t\t\t\t\t\tvar currentContext = new CSharpTypeResolveContext(previousResolver.Compilation.MainModule);\n\t\t\t\t\t\tresolver = new CSharpResolver(currentContext);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tresolver = resolver.WithCurrentMember(method);\n\t\t\t\t\t}\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tvar function = entityDeclaration.Annotation<IL.ILFunction>();\n\t\t\t\t\t\tastBuilder = CreateAstBuilder(resolver, function);\n\t\t\t\t\t\tbaseCall(entityDeclaration);\n\t\t\t\t\t}\n\t\t\t\t\tfinally\n\t\t\t\t\t{\n\t\t\t\t\t\tresolver = previousResolver;\n\t\t\t\t\t\tastBuilder = previousAstBuilder;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbaseCall(entityDeclaration);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override void VisitSimpleType(SimpleType simpleType)\n\t\t\t{\n\t\t\t\tTypeResolveResult rr;\n\t\t\t\tif ((rr = simpleType.Annotation<TypeResolveResult>()) == null)\n\t\t\t\t{\n\t\t\t\t\tbase.VisitSimpleType(simpleType);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tastBuilder.NameLookupMode = simpleType.GetNameLookupMode();\n\t\t\t\tif (astBuilder.NameLookupMode == NameLookupMode.Type)\n\t\t\t\t{\n\t\t\t\t\tAstType outermostType = simpleType;\n\t\t\t\t\twhile (outermostType.Parent is AstType)\n\t\t\t\t\t\toutermostType = (AstType)outermostType.Parent;\n\t\t\t\t\tif (outermostType.Parent is TypeReferenceExpression)\n\t\t\t\t\t{\n\t\t\t\t\t\t// ILSpy uses TypeReferenceExpression in expression context even when the C# parser\n\t\t\t\t\t\t// wouldn't know that it's a type reference.\n\t\t\t\t\t\t// Fall back to expression-mode lookup in these cases:\n\t\t\t\t\t\tastBuilder.NameLookupMode = NameLookupMode.Expression;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (simpleType.Parent is Syntax.Attribute)\n\t\t\t\t{\n\t\t\t\t\tsimpleType.ReplaceWith(astBuilder.ConvertAttributeType(rr.Type));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsimpleType.ReplaceWith(astBuilder.ConvertType(rr.Type));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/NormalizeBlockStatements.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\tclass NormalizeBlockStatements : DepthFirstAstVisitor, IAstTransform\n\t{\n\t\tTransformContext context;\n\t\tbool hasNamespace;\n\t\tNamespaceDeclaration singleNamespaceDeclaration;\n\n\t\tpublic override void VisitSyntaxTree(SyntaxTree syntaxTree)\n\t\t{\n\t\t\tsingleNamespaceDeclaration = null;\n\t\t\thasNamespace = false;\n\t\t\tbase.VisitSyntaxTree(syntaxTree);\n\t\t\tif (context.Settings.FileScopedNamespaces && singleNamespaceDeclaration != null)\n\t\t\t{\n\t\t\t\tsingleNamespaceDeclaration.IsFileScoped = true;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)\n\t\t{\n\t\t\tsingleNamespaceDeclaration = null;\n\t\t\tif (!hasNamespace)\n\t\t\t{\n\t\t\t\thasNamespace = true;\n\t\t\t\tsingleNamespaceDeclaration = namespaceDeclaration;\n\t\t\t}\n\t\t\tbase.VisitNamespaceDeclaration(namespaceDeclaration);\n\n\t\t}\n\n\t\tpublic override void VisitIfElseStatement(IfElseStatement ifElseStatement)\n\t\t{\n\t\t\tbase.VisitIfElseStatement(ifElseStatement);\n\t\t\tDoTransform(ifElseStatement.TrueStatement, ifElseStatement);\n\t\t\tDoTransform(ifElseStatement.FalseStatement, ifElseStatement);\n\t\t}\n\n\t\tpublic override void VisitWhileStatement(WhileStatement whileStatement)\n\t\t{\n\t\t\tbase.VisitWhileStatement(whileStatement);\n\t\t\tInsertBlock(whileStatement.EmbeddedStatement);\n\t\t}\n\n\t\tpublic override void VisitDoWhileStatement(DoWhileStatement doWhileStatement)\n\t\t{\n\t\t\tbase.VisitDoWhileStatement(doWhileStatement);\n\t\t\tInsertBlock(doWhileStatement.EmbeddedStatement);\n\t\t}\n\n\t\tpublic override void VisitForeachStatement(ForeachStatement foreachStatement)\n\t\t{\n\t\t\tbase.VisitForeachStatement(foreachStatement);\n\t\t\tInsertBlock(foreachStatement.EmbeddedStatement);\n\t\t}\n\n\t\tpublic override void VisitForStatement(ForStatement forStatement)\n\t\t{\n\t\t\tbase.VisitForStatement(forStatement);\n\t\t\tInsertBlock(forStatement.EmbeddedStatement);\n\t\t}\n\n\t\tpublic override void VisitFixedStatement(FixedStatement fixedStatement)\n\t\t{\n\t\t\tbase.VisitFixedStatement(fixedStatement);\n\t\t\tInsertBlock(fixedStatement.EmbeddedStatement);\n\t\t}\n\n\t\tpublic override void VisitLockStatement(LockStatement lockStatement)\n\t\t{\n\t\t\tbase.VisitLockStatement(lockStatement);\n\t\t\tInsertBlock(lockStatement.EmbeddedStatement);\n\t\t}\n\n\t\tpublic override void VisitUsingStatement(UsingStatement usingStatement)\n\t\t{\n\t\t\tbase.VisitUsingStatement(usingStatement);\n\t\t\tDoTransform(usingStatement.EmbeddedStatement, usingStatement);\n\t\t}\n\n\t\tvoid DoTransform(Statement statement, Statement parent)\n\t\t{\n\t\t\tif (statement.IsNull)\n\t\t\t\treturn;\n\t\t\tif (context.Settings.AlwaysUseBraces)\n\t\t\t{\n\t\t\t\tif (!IsElseIf(statement, parent))\n\t\t\t\t{\n\t\t\t\t\tInsertBlock(statement);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (statement is BlockStatement b && b.Statements.Count == 1 && IsAllowedAsEmbeddedStatement(b.Statements.First(), parent))\n\t\t\t\t{\n\t\t\t\t\tstatement.ReplaceWith(b.Statements.First().Detach());\n\t\t\t\t}\n\t\t\t\telse if (!IsAllowedAsEmbeddedStatement(statement, parent))\n\t\t\t\t{\n\t\t\t\t\tInsertBlock(statement);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool IsElseIf(Statement statement, Statement parent)\n\t\t{\n\t\t\treturn parent is IfElseStatement && statement.Role == IfElseStatement.FalseRole;\n\t\t}\n\n\t\tstatic void InsertBlock(Statement statement)\n\t\t{\n\t\t\tif (statement.IsNull)\n\t\t\t\treturn;\n\t\t\tif (!(statement is BlockStatement))\n\t\t\t{\n\t\t\t\tvar b = new BlockStatement();\n\t\t\t\tstatement.ReplaceWith(b);\n\t\t\t\tif (statement is EmptyStatement && !statement.Children.Any())\n\t\t\t\t{\n\t\t\t\t\tb.CopyAnnotationsFrom(statement);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tb.Add(statement);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool IsAllowedAsEmbeddedStatement(Statement statement, Statement parent)\n\t\t{\n\t\t\tswitch (statement)\n\t\t\t{\n\t\t\t\tcase IfElseStatement ies:\n\t\t\t\t\treturn parent is IfElseStatement && ies.Role == IfElseStatement.FalseRole;\n\t\t\t\tcase VariableDeclarationStatement vds:\n\t\t\t\tcase WhileStatement ws:\n\t\t\t\tcase DoWhileStatement dws:\n\t\t\t\tcase SwitchStatement ss:\n\t\t\t\tcase ForeachStatement fes:\n\t\t\t\tcase ForStatement fs:\n\t\t\t\tcase LockStatement ls:\n\t\t\t\tcase FixedStatement fxs:\n\t\t\t\t\treturn false;\n\t\t\t\tcase UsingStatement us:\n\t\t\t\t\treturn parent is UsingStatement && !us.IsEnhanced;\n\t\t\t\tdefault:\n\t\t\t\t\treturn !(parent?.Parent is IfElseStatement);\n\t\t\t}\n\t\t}\n\n\t\tvoid IAstTransform.Run(AstNode rootNode, TransformContext context)\n\t\t{\n\t\t\tthis.context = context;\n\t\t\trootNode.AcceptVisitor(this);\n\t\t}\n\n\t\tpublic override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)\n\t\t{\n\t\t\tif (context.Settings.UseExpressionBodyForCalculatedGetterOnlyProperties)\n\t\t\t{\n\t\t\t\tSimplifyPropertyDeclaration(propertyDeclaration);\n\t\t\t}\n\t\t\tbase.VisitPropertyDeclaration(propertyDeclaration);\n\t\t}\n\n\t\tpublic override void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration)\n\t\t{\n\t\t\tif (context.Settings.UseExpressionBodyForCalculatedGetterOnlyProperties)\n\t\t\t{\n\t\t\t\tSimplifyIndexerDeclaration(indexerDeclaration);\n\t\t\t}\n\t\t\tbase.VisitIndexerDeclaration(indexerDeclaration);\n\t\t}\n\n\t\tstatic readonly PropertyDeclaration CalculatedGetterOnlyPropertyPattern = new PropertyDeclaration() {\n\t\t\tAttributes = { new Repeat(new AnyNode()) },\n\t\t\tModifiers = Modifiers.Any,\n\t\t\tName = Pattern.AnyString,\n\t\t\tPrivateImplementationType = new AnyNodeOrNull(),\n\t\t\tReturnType = new AnyNode(),\n\t\t\tGetter = new Accessor() {\n\t\t\t\tModifiers = Modifiers.Any,\n\t\t\t\tBody = new BlockStatement() { new ReturnStatement(new AnyNode(\"expression\")) }\n\t\t\t}\n\t\t};\n\n\t\tstatic readonly IndexerDeclaration CalculatedGetterOnlyIndexerPattern = new IndexerDeclaration() {\n\t\t\tAttributes = { new Repeat(new AnyNode()) },\n\t\t\tModifiers = Modifiers.Any,\n\t\t\tPrivateImplementationType = new AnyNodeOrNull(),\n\t\t\tParameters = { new Repeat(new AnyNode()) },\n\t\t\tReturnType = new AnyNode(),\n\t\t\tGetter = new Accessor() {\n\t\t\t\tModifiers = Modifiers.Any,\n\t\t\t\tBody = new BlockStatement() { new ReturnStatement(new AnyNode(\"expression\")) }\n\t\t\t}\n\t\t};\n\n\t\t/// <summary>\n\t\t/// Modifiers that are emitted on accessors, but can be moved to the property declaration.\n\t\t/// </summary>\n\t\tconst Modifiers movableModifiers = Modifiers.Readonly;\n\n\t\tvoid SimplifyPropertyDeclaration(PropertyDeclaration propertyDeclaration)\n\t\t{\n\t\t\tvar m = CalculatedGetterOnlyPropertyPattern.Match(propertyDeclaration);\n\t\t\tif (!m.Success)\n\t\t\t\treturn;\n\t\t\tif ((propertyDeclaration.Getter.Modifiers & ~movableModifiers) != 0)\n\t\t\t\treturn;\n\t\t\tpropertyDeclaration.Modifiers |= propertyDeclaration.Getter.Modifiers;\n\t\t\tpropertyDeclaration.ExpressionBody = m.Get<Expression>(\"expression\").Single().Detach();\n\t\t\tpropertyDeclaration.CopyAnnotationsFrom(propertyDeclaration.Getter);\n\t\t\tpropertyDeclaration.Getter.Remove();\n\t\t}\n\n\t\tvoid SimplifyIndexerDeclaration(IndexerDeclaration indexerDeclaration)\n\t\t{\n\t\t\tvar m = CalculatedGetterOnlyIndexerPattern.Match(indexerDeclaration);\n\t\t\tif (!m.Success)\n\t\t\t\treturn;\n\t\t\tif ((indexerDeclaration.Getter.Modifiers & ~movableModifiers) != 0)\n\t\t\t\treturn;\n\t\t\tindexerDeclaration.Modifiers |= indexerDeclaration.Getter.Modifiers;\n\t\t\tindexerDeclaration.ExpressionBody = m.Get<Expression>(\"expression\").Single().Detach();\n\t\t\tindexerDeclaration.CopyAnnotationsFrom(indexerDeclaration.Getter);\n\t\t\tindexerDeclaration.Getter.Remove();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\t/// <summary>\n\t/// Finds the expanded form of using statements using pattern matching and replaces it with a UsingStatement.\n\t/// </summary>\n\tpublic sealed class PatternStatementTransform : ContextTrackingVisitor<AstNode>, IAstTransform\n\t{\n\t\treadonly DeclareVariables declareVariables = new DeclareVariables();\n\t\tTransformContext context;\n\n\t\tpublic void Run(AstNode rootNode, TransformContext context)\n\t\t{\n\t\t\tif (this.context != null)\n\t\t\t\tthrow new InvalidOperationException(\"Reentrancy in PatternStatementTransform.Run?\");\n\t\t\ttry\n\t\t\t{\n\t\t\t\tthis.context = context;\n\t\t\t\tbase.Initialize(context);\n\t\t\t\tdeclareVariables.Analyze(rootNode);\n\t\t\t\trootNode.AcceptVisitor(this);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tthis.context = null;\n\t\t\t\tbase.Uninitialize();\n\t\t\t\tdeclareVariables.ClearAnalysisResults();\n\t\t\t}\n\t\t}\n\n\t\t#region Visitor Overrides\n\t\tprotected override AstNode VisitChildren(AstNode node)\n\t\t{\n\t\t\t// Go through the children, and keep visiting a node as long as it changes.\n\t\t\t// Because some transforms delete/replace nodes before and after the node being transformed, we rely\n\t\t\t// on the transform's return value to know where we need to keep iterating.\n\t\t\tfor (AstNode child = node.FirstChild; child != null; child = child.NextSibling)\n\t\t\t{\n\t\t\t\tAstNode oldChild;\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\toldChild = child;\n\t\t\t\t\tchild = child.AcceptVisitor(this);\n\t\t\t\t\tDebug.Assert(child != null && child.Parent == node);\n\t\t\t\t} while (child != oldChild);\n\t\t\t}\n\t\t\treturn node;\n\t\t}\n\n\t\tpublic override AstNode VisitExpressionStatement(ExpressionStatement expressionStatement)\n\t\t{\n\t\t\tAstNode result = TransformForeachOnMultiDimArray(expressionStatement);\n\t\t\tif (result != null)\n\t\t\t\treturn result;\n\t\t\tresult = TransformFor(expressionStatement);\n\t\t\tif (result != null)\n\t\t\t\treturn result;\n\t\t\treturn base.VisitExpressionStatement(expressionStatement);\n\t\t}\n\n\t\tpublic override AstNode VisitForStatement(ForStatement forStatement)\n\t\t{\n\t\t\tAstNode result = TransformForeachOnArray(forStatement);\n\t\t\tif (result != null)\n\t\t\t\treturn result;\n\t\t\treturn base.VisitForStatement(forStatement);\n\t\t}\n\n\t\tpublic override AstNode VisitIfElseStatement(IfElseStatement ifElseStatement)\n\t\t{\n\t\t\tAstNode simplifiedIfElse = SimplifyCascadingIfElseStatements(ifElseStatement);\n\t\t\tif (simplifiedIfElse != null)\n\t\t\t\treturn simplifiedIfElse;\n\t\t\treturn base.VisitIfElseStatement(ifElseStatement);\n\t\t}\n\n\t\tpublic override AstNode VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)\n\t\t{\n\t\t\tif (context.Settings.AutomaticProperties\n\t\t\t\t&& (!propertyDeclaration.Setter.IsNull || context.Settings.GetterOnlyAutomaticProperties))\n\t\t\t{\n\t\t\t\tAstNode result = TransformAutomaticProperty(propertyDeclaration);\n\t\t\t\tif (result != null)\n\t\t\t\t\treturn result;\n\t\t\t}\n\t\t\treturn base.VisitPropertyDeclaration(propertyDeclaration);\n\t\t}\n\n\t\tpublic override AstNode VisitCustomEventDeclaration(CustomEventDeclaration eventDeclaration)\n\t\t{\n\t\t\t// first apply transforms to the accessor bodies\n\t\t\tbase.VisitCustomEventDeclaration(eventDeclaration);\n\t\t\tif (context.Settings.AutomaticEvents)\n\t\t\t{\n\t\t\t\tAstNode result = TransformAutomaticEvents(eventDeclaration);\n\t\t\t\tif (result != null)\n\t\t\t\t\treturn result;\n\t\t\t}\n\t\t\treturn eventDeclaration;\n\t\t}\n\n\t\tpublic override AstNode VisitMethodDeclaration(MethodDeclaration methodDeclaration)\n\t\t{\n\t\t\treturn TransformDestructor(methodDeclaration) ?? base.VisitMethodDeclaration(methodDeclaration);\n\t\t}\n\n\t\tpublic override AstNode VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration)\n\t\t{\n\t\t\treturn TransformDestructorBody(destructorDeclaration) ?? base.VisitDestructorDeclaration(destructorDeclaration);\n\t\t}\n\n\t\tpublic override AstNode VisitTryCatchStatement(TryCatchStatement tryCatchStatement)\n\t\t{\n\t\t\treturn TransformTryCatchFinally(tryCatchStatement) ?? base.VisitTryCatchStatement(tryCatchStatement);\n\t\t}\n\t\t#endregion\n\n\t\t/// <summary>\n\t\t/// $variable = $initializer;\n\t\t/// </summary>\n\t\tstatic readonly AstNode variableAssignPattern = new ExpressionStatement(\n\t\t\tnew AssignmentExpression(\n\t\t\t\tnew NamedNode(\"variable\", new IdentifierExpression(Pattern.AnyString)),\n\t\t\t\tnew AnyNode(\"initializer\")\n\t\t\t));\n\n\t\t#region for\n\t\tstatic readonly WhileStatement forPattern = new WhileStatement {\n\t\t\tCondition = new BinaryOperatorExpression {\n\t\t\t\tLeft = new NamedNode(\"ident\", new IdentifierExpression(Pattern.AnyString)),\n\t\t\t\tOperator = BinaryOperatorType.Any,\n\t\t\t\tRight = new AnyNode(\"endExpr\")\n\t\t\t},\n\t\t\tEmbeddedStatement = new BlockStatement {\n\t\t\t\tStatements = {\n\t\t\t\t\tnew Repeat(new AnyNode(\"statement\")),\n\t\t\t\t\tnew NamedNode(\n\t\t\t\t\t\t\"iterator\",\n\t\t\t\t\t\tnew ExpressionStatement(\n\t\t\t\t\t\t\tnew AssignmentExpression {\n\t\t\t\t\t\t\t\tLeft = new Backreference(\"ident\"),\n\t\t\t\t\t\t\t\tOperator = AssignmentOperatorType.Any,\n\t\t\t\t\t\t\t\tRight = new AnyNode()\n\t\t\t\t\t\t\t}))\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tpublic ForStatement TransformFor(ExpressionStatement node)\n\t\t{\n\t\t\tif (!context.Settings.ForStatement)\n\t\t\t\treturn null;\n\t\t\tMatch m1 = variableAssignPattern.Match(node);\n\t\t\tif (!m1.Success)\n\t\t\t\treturn null;\n\t\t\tvar variable = m1.Get<IdentifierExpression>(\"variable\").Single().GetILVariable();\n\t\t\tAstNode next = node.NextSibling;\n\t\t\tif (next is ForStatement forStatement && ForStatementUsesVariable(forStatement, variable))\n\t\t\t{\n\t\t\t\tnode.Remove();\n\t\t\t\tnext.InsertChildAfter(null, node, ForStatement.InitializerRole);\n\t\t\t\treturn (ForStatement)next;\n\t\t\t}\n\t\t\tMatch m3 = forPattern.Match(next);\n\t\t\tif (!m3.Success)\n\t\t\t\treturn null;\n\t\t\t// ensure the variable in the for pattern is the same as in the declaration\n\t\t\tif (variable != m3.Get<IdentifierExpression>(\"ident\").Single().GetILVariable())\n\t\t\t\treturn null;\n\t\t\tWhileStatement loop = (WhileStatement)next;\n\t\t\t// Cannot convert to for loop, if any variable that is used in the \"iterator\" part of the pattern,\n\t\t\t// will be declared in the body of the while-loop.\n\t\t\tvar iteratorStatement = m3.Get<Statement>(\"iterator\").Single();\n\t\t\tif (IteratorVariablesDeclaredInsideLoopBody(iteratorStatement))\n\t\t\t\treturn null;\n\t\t\t// Cannot convert to for loop, because that would change the semantics of the program.\n\t\t\t// continue in while jumps to the condition block.\n\t\t\t// Whereas continue in for jumps to the increment block.\n\t\t\tif (loop.DescendantNodes(DescendIntoStatement).OfType<Statement>().Any(s => s is ContinueStatement))\n\t\t\t\treturn null;\n\t\t\tnode.Remove();\n\t\t\tBlockStatement newBody = new BlockStatement();\n\t\t\tforeach (Statement stmt in m3.Get<Statement>(\"statement\"))\n\t\t\t\tnewBody.Add(stmt.Detach());\n\t\t\tforStatement = new ForStatement();\n\t\t\tforStatement.CopyAnnotationsFrom(loop);\n\t\t\tforStatement.Initializers.Add(node);\n\t\t\tforStatement.Condition = loop.Condition.Detach();\n\t\t\tforStatement.Iterators.Add(iteratorStatement.Detach());\n\t\t\tforStatement.EmbeddedStatement = newBody;\n\t\t\tloop.ReplaceWith(forStatement);\n\t\t\treturn forStatement;\n\t\t}\n\n\t\tbool DescendIntoStatement(AstNode node)\n\t\t{\n\t\t\tif (node is Expression || node is ExpressionStatement)\n\t\t\t\treturn false;\n\t\t\tif (node is WhileStatement || node is ForeachStatement || node is DoWhileStatement || node is ForStatement)\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tbool ForStatementUsesVariable(ForStatement statement, IL.ILVariable variable)\n\t\t{\n\t\t\tif (statement.Condition.DescendantsAndSelf.OfType<IdentifierExpression>().Any(ie => ie.GetILVariable() == variable))\n\t\t\t\treturn true;\n\t\t\tif (statement.Iterators.Any(i => i.DescendantsAndSelf.OfType<IdentifierExpression>().Any(ie => ie.GetILVariable() == variable)))\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\n\t\tbool IteratorVariablesDeclaredInsideLoopBody(Statement iteratorStatement)\n\t\t{\n\t\t\tforeach (var id in iteratorStatement.DescendantsAndSelf.OfType<IdentifierExpression>())\n\t\t\t{\n\t\t\t\tvar v = id.GetILVariable();\n\t\t\t\tif (v == null || !DeclareVariables.VariableNeedsDeclaration(v.Kind))\n\t\t\t\t\tcontinue;\n\t\t\t\tif (declareVariables.GetDeclarationPoint(v).Parent == iteratorStatement.Parent)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\t#endregion\n\n\t\t#region foreach\n\n\t\tstatic readonly ForStatement forOnArrayPattern = new ForStatement {\n\t\t\tInitializers = {\n\t\t\t\tnew ExpressionStatement(\n\t\t\t\tnew AssignmentExpression(\n\t\t\t\t\tnew NamedNode(\"indexVariable\", new IdentifierExpression(Pattern.AnyString)),\n\t\t\t\t\tnew PrimitiveExpression(0)\n\t\t\t\t))\n\t\t\t},\n\t\t\tCondition = new BinaryOperatorExpression(\n\t\t\t\tnew IdentifierExpressionBackreference(\"indexVariable\"),\n\t\t\t\tBinaryOperatorType.LessThan,\n\t\t\t\tnew MemberReferenceExpression(new NamedNode(\"arrayVariable\", new IdentifierExpression(Pattern.AnyString)), \"Length\")\n\t\t\t),\n\t\t\tIterators = {\n\t\t\t\tnew ExpressionStatement(\n\t\t\t\tnew AssignmentExpression(\n\t\t\t\t\tnew IdentifierExpressionBackreference(\"indexVariable\"),\n\t\t\t\t\tnew BinaryOperatorExpression(new IdentifierExpressionBackreference(\"indexVariable\"), BinaryOperatorType.Add, new PrimitiveExpression(1))\n\t\t\t\t))\n\t\t\t},\n\t\t\tEmbeddedStatement = new BlockStatement {\n\t\t\t\tStatements = {\n\t\t\t\t\tnew ExpressionStatement(new AssignmentExpression(\n\t\t\t\t\t\tnew NamedNode(\"itemVariable\", new IdentifierExpression(Pattern.AnyString)),\n\t\t\t\t\t\tnew IndexerExpression(new IdentifierExpressionBackreference(\"arrayVariable\"), new IdentifierExpressionBackreference(\"indexVariable\"))\n\t\t\t\t\t)),\n\t\t\t\t\tnew Repeat(new AnyNode(\"statements\"))\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tbool VariableCanBeUsedAsForeachLocal(IL.ILVariable itemVar, Statement loop)\n\t\t{\n\t\t\tif (itemVar == null || !(itemVar.Kind == IL.VariableKind.Local || itemVar.Kind == IL.VariableKind.StackSlot))\n\t\t\t{\n\t\t\t\t// only locals/temporaries can be converted into foreach loop variable\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar blockContainer = loop.Annotation<IL.BlockContainer>();\n\n\t\t\tif (!itemVar.IsSingleDefinition)\n\t\t\t{\n\t\t\t\t// foreach variable cannot be assigned to.\n\t\t\t\t// As a special case, we accept taking the address for a method call,\n\t\t\t\t// but only if the call is the only use, so that any mutation by the call\n\t\t\t\t// cannot be observed.\n\t\t\t\tif (!AddressUsedForSingleCall(itemVar, blockContainer))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (itemVar.CaptureScope != null && itemVar.CaptureScope != blockContainer)\n\t\t\t{\n\t\t\t\t// captured variables cannot be declared in the loop unless the loop is their capture scope\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tAstNode declPoint = declareVariables.GetDeclarationPoint(itemVar);\n\t\t\treturn declPoint.Ancestors.Contains(loop) && !declareVariables.WasMerged(itemVar);\n\t\t}\n\n\t\tstatic bool AddressUsedForSingleCall(IL.ILVariable v, IL.BlockContainer loop)\n\t\t{\n\t\t\tif (v.StoreCount == 1 && v.AddressCount == 1 && v.LoadCount == 0 && v.Type.IsReferenceType == false)\n\t\t\t{\n\t\t\t\tif (v.AddressInstructions[0].Parent is IL.Call call\n\t\t\t\t\t&& v.AddressInstructions[0].ChildIndex == 0\n\t\t\t\t\t&& !call.Method.IsStatic)\n\t\t\t\t{\n\t\t\t\t\t// used as this pointer for a method call\n\t\t\t\t\t// this is OK iff the call is not within a nested loop\n\t\t\t\t\tfor (var node = call.Parent; node != null; node = node.Parent)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (node == loop)\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\telse if (node is IL.BlockContainer)\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tStatement TransformForeachOnArray(ForStatement forStatement)\n\t\t{\n\t\t\tif (!context.Settings.ForEachStatement)\n\t\t\t\treturn null;\n\t\t\tMatch m = forOnArrayPattern.Match(forStatement);\n\t\t\tif (!m.Success)\n\t\t\t\treturn null;\n\t\t\tvar itemVariable = m.Get<IdentifierExpression>(\"itemVariable\").Single().GetILVariable();\n\t\t\tvar indexVariable = m.Get<IdentifierExpression>(\"indexVariable\").Single().GetILVariable();\n\t\t\tvar arrayVariable = m.Get<IdentifierExpression>(\"arrayVariable\").Single().GetILVariable();\n\t\t\tif (itemVariable == null || indexVariable == null || arrayVariable == null)\n\t\t\t\treturn null;\n\t\t\tif (arrayVariable.Type.Kind != TypeKind.Array && !arrayVariable.Type.IsKnownType(KnownTypeCode.String))\n\t\t\t\treturn null;\n\t\t\tif (!VariableCanBeUsedAsForeachLocal(itemVariable, forStatement))\n\t\t\t\treturn null;\n\t\t\tif (indexVariable.StoreCount != 2 || indexVariable.LoadCount != 3 || indexVariable.AddressCount != 0)\n\t\t\t\treturn null;\n\t\t\tvar body = new BlockStatement();\n\t\t\tforeach (var statement in m.Get<Statement>(\"statements\"))\n\t\t\t\tbody.Statements.Add(statement.Detach());\n\t\t\tvar foreachStmt = new ForeachStatement {\n\t\t\t\tVariableType = context.Settings.AnonymousTypes && itemVariable.Type.ContainsAnonymousType() ? new SimpleType(\"var\") : context.TypeSystemAstBuilder.ConvertType(itemVariable.Type),\n\t\t\t\tVariableDesignation = new SingleVariableDesignation { Identifier = itemVariable.Name },\n\t\t\t\tInExpression = m.Get<IdentifierExpression>(\"arrayVariable\").Single().Detach(),\n\t\t\t\tEmbeddedStatement = body\n\t\t\t};\n\t\t\tforeachStmt.CopyAnnotationsFrom(forStatement);\n\t\t\titemVariable.Kind = IL.VariableKind.ForeachLocal;\n\t\t\t// Add the variable annotation for highlighting (TokenTextWriter expects it directly on the ForeachStatement).\n\t\t\tforeachStmt.VariableDesignation.AddAnnotation(new ILVariableResolveResult(itemVariable, itemVariable.Type));\n\t\t\t// TODO : add ForeachAnnotation\n\t\t\tforStatement.ReplaceWith(foreachStmt);\n\t\t\treturn foreachStmt;\n\t\t}\n\n\t\tstatic readonly ForStatement forOnArrayMultiDimPattern = new ForStatement {\n\t\t\tInitializers = { },\n\t\t\tCondition = new BinaryOperatorExpression(\n\t\t\t\tnew NamedNode(\"indexVariable\", new IdentifierExpression(Pattern.AnyString)),\n\t\t\t\tBinaryOperatorType.LessThanOrEqual,\n\t\t\t\tnew NamedNode(\"upperBoundVariable\", new IdentifierExpression(Pattern.AnyString))\n\t\t\t),\n\t\t\tIterators = {\n\t\t\t\tnew ExpressionStatement(\n\t\t\t\tnew AssignmentExpression(\n\t\t\t\t\tnew IdentifierExpressionBackreference(\"indexVariable\"),\n\t\t\t\t\tnew BinaryOperatorExpression(new IdentifierExpressionBackreference(\"indexVariable\"), BinaryOperatorType.Add, new PrimitiveExpression(1))\n\t\t\t\t))\n\t\t\t},\n\t\t\tEmbeddedStatement = new BlockStatement { Statements = { new AnyNode(\"lowerBoundAssign\"), new Repeat(new AnyNode(\"statements\")) } }\n\t\t};\n\n\t\t/// <summary>\n\t\t/// $variable = $collection.GetUpperBound($index);\n\t\t/// </summary>\n\t\tstatic readonly AstNode variableAssignUpperBoundPattern = new ExpressionStatement(\n\t\t\tnew AssignmentExpression(\n\t\t\t\tnew NamedNode(\"variable\", new IdentifierExpression(Pattern.AnyString)),\n\t\t\t\tnew InvocationExpression(\n\t\t\t\t\tnew MemberReferenceExpression(\n\t\t\t\t\t\tnew NamedNode(\"collection\", new IdentifierExpression(Pattern.AnyString)),\n\t\t\t\t\t\t\"GetUpperBound\"\n\t\t\t\t\t),\n\t\t\t\t\tnew NamedNode(\"index\", new PrimitiveExpression(PrimitiveExpression.AnyValue))\n\t\t\t)));\n\n\t\t/// <summary>\n\t\t/// $variable = $collection.GetLowerBound($index);\n\t\t/// </summary>\n\t\tstatic readonly ExpressionStatement variableAssignLowerBoundPattern = new ExpressionStatement(\n\t\t\tnew AssignmentExpression(\n\t\t\t\tnew NamedNode(\"variable\", new IdentifierExpression(Pattern.AnyString)),\n\t\t\t\tnew InvocationExpression(\n\t\t\t\t\tnew MemberReferenceExpression(\n\t\t\t\t\t\tnew NamedNode(\"collection\", new IdentifierExpression(Pattern.AnyString)),\n\t\t\t\t\t\t\"GetLowerBound\"\n\t\t\t\t\t),\n\t\t\t\t\tnew NamedNode(\"index\", new PrimitiveExpression(PrimitiveExpression.AnyValue))\n\t\t\t)));\n\n\t\t/// <summary>\n\t\t/// $variable = $collection[$index1, $index2, ...];\n\t\t/// </summary>\n\t\tstatic readonly ExpressionStatement foreachVariableOnMultArrayAssignPattern = new ExpressionStatement(\n\t\t\tnew AssignmentExpression(\n\t\t\t\tnew NamedNode(\"variable\", new IdentifierExpression(Pattern.AnyString)),\n\t\t\t\tnew IndexerExpression(\n\t\t\t\t\tnew NamedNode(\"collection\", new IdentifierExpression(Pattern.AnyString)),\n\t\t\t\t\tnew Repeat(new NamedNode(\"index\", new IdentifierExpression(Pattern.AnyString))\n\t\t\t\t)\n\t\t\t)));\n\n\t\tbool MatchLowerBound(int indexNum, out IL.ILVariable index, IL.ILVariable collection, Statement statement)\n\t\t{\n\t\t\tindex = null;\n\t\t\tvar m = variableAssignLowerBoundPattern.Match(statement);\n\t\t\tif (!m.Success)\n\t\t\t\treturn false;\n\t\t\tif (!int.TryParse(m.Get<PrimitiveExpression>(\"index\").Single().Value.ToString(), out int i) || indexNum != i)\n\t\t\t\treturn false;\n\t\t\tindex = m.Get<IdentifierExpression>(\"variable\").Single().GetILVariable();\n\t\t\treturn m.Get<IdentifierExpression>(\"collection\").Single().GetILVariable() == collection;\n\t\t}\n\n\t\tbool MatchForeachOnMultiDimArray(IL.ILVariable[] upperBounds, IL.ILVariable collection, Statement firstInitializerStatement, out IdentifierExpression foreachVariable, out IList<Statement> statements, out IL.ILVariable[] lowerBounds)\n\t\t{\n\t\t\tint i = 0;\n\t\t\tforeachVariable = null;\n\t\t\tstatements = null;\n\t\t\tlowerBounds = new IL.ILVariable[upperBounds.Length];\n\t\t\tStatement stmt = firstInitializerStatement;\n\t\t\tMatch m = default(Match);\n\t\t\twhile (i < upperBounds.Length && MatchLowerBound(i, out IL.ILVariable indexVariable, collection, stmt))\n\t\t\t{\n\t\t\t\tm = forOnArrayMultiDimPattern.Match(stmt.GetNextStatement());\n\t\t\t\tif (!m.Success)\n\t\t\t\t\treturn false;\n\t\t\t\tvar upperBound = m.Get<IdentifierExpression>(\"upperBoundVariable\").Single().GetILVariable();\n\t\t\t\tif (upperBounds[i] != upperBound)\n\t\t\t\t\treturn false;\n\t\t\t\tstmt = m.Get<Statement>(\"lowerBoundAssign\").Single();\n\t\t\t\tlowerBounds[i] = indexVariable;\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tif (collection.Type.Kind != TypeKind.Array)\n\t\t\t\treturn false;\n\t\t\tvar m2 = foreachVariableOnMultArrayAssignPattern.Match(stmt);\n\t\t\tif (!m2.Success)\n\t\t\t\treturn false;\n\t\t\tvar collection2 = m2.Get<IdentifierExpression>(\"collection\").Single().GetILVariable();\n\t\t\tif (collection2 != collection)\n\t\t\t\treturn false;\n\t\t\tforeachVariable = m2.Get<IdentifierExpression>(\"variable\").Single();\n\t\t\tstatements = m.Get<Statement>(\"statements\").ToList();\n\t\t\treturn true;\n\t\t}\n\n\t\tStatement TransformForeachOnMultiDimArray(ExpressionStatement expressionStatement)\n\t\t{\n\t\t\tif (!context.Settings.ForEachStatement)\n\t\t\t\treturn null;\n\t\t\tMatch m;\n\t\t\tStatement stmt = expressionStatement;\n\t\t\tIL.ILVariable collection = null;\n\t\t\tIL.ILVariable[] upperBounds = null;\n\t\t\tList<Statement> statementsToDelete = new List<Statement>();\n\t\t\tint i = 0;\n\t\t\t// first we look for all the upper bound initializations\n\t\t\tdo\n\t\t\t{\n\t\t\t\tm = variableAssignUpperBoundPattern.Match(stmt);\n\t\t\t\tif (!m.Success)\n\t\t\t\t\tbreak;\n\t\t\t\tif (upperBounds == null)\n\t\t\t\t{\n\t\t\t\t\tcollection = m.Get<IdentifierExpression>(\"collection\").Single().GetILVariable();\n\t\t\t\t\tif (!(collection?.Type is Decompiler.TypeSystem.ArrayType arrayType))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tupperBounds = new IL.ILVariable[arrayType.Dimensions];\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tstatementsToDelete.Add(stmt);\n\t\t\t\t}\n\t\t\t\tvar nextCollection = m.Get<IdentifierExpression>(\"collection\").Single().GetILVariable();\n\t\t\t\tif (nextCollection != collection)\n\t\t\t\t\tbreak;\n\t\t\t\tif (!int.TryParse(m.Get<PrimitiveExpression>(\"index\").Single().Value?.ToString() ?? \"\", out int index) || index != i)\n\t\t\t\t\tbreak;\n\t\t\t\tupperBounds[i] = m.Get<IdentifierExpression>(\"variable\").Single().GetILVariable();\n\t\t\t\tstmt = stmt.GetNextStatement();\n\t\t\t\ti++;\n\t\t\t} while (stmt != null && i < upperBounds.Length);\n\n\t\t\tif (upperBounds?.LastOrDefault() == null || collection == null)\n\t\t\t\treturn null;\n\t\t\tif (!MatchForeachOnMultiDimArray(upperBounds, collection, stmt, out var foreachVariable, out var statements, out var lowerBounds))\n\t\t\t\treturn null;\n\t\t\tstatementsToDelete.Add(stmt);\n\t\t\tstatementsToDelete.Add(stmt.GetNextStatement());\n\t\t\tvar itemVariable = foreachVariable.GetILVariable();\n\t\t\tif (itemVariable == null || !itemVariable.IsSingleDefinition\n\t\t\t\t|| (itemVariable.Kind != IL.VariableKind.Local && itemVariable.Kind != IL.VariableKind.StackSlot)\n\t\t\t\t|| !upperBounds.All(ub => ub.IsSingleDefinition && ub.LoadCount == 1)\n\t\t\t\t|| !lowerBounds.All(lb => lb.StoreCount == 2 && lb.LoadCount == 3 && lb.AddressCount == 0))\n\t\t\t\treturn null;\n\t\t\tvar body = new BlockStatement();\n\t\t\tforeach (var statement in statements)\n\t\t\t\tbody.Statements.Add(statement.Detach());\n\t\t\tvar foreachStmt = new ForeachStatement {\n\t\t\t\tVariableType = context.Settings.AnonymousTypes && itemVariable.Type.ContainsAnonymousType() ? new SimpleType(\"var\") : context.TypeSystemAstBuilder.ConvertType(itemVariable.Type),\n\t\t\t\tVariableDesignation = new SingleVariableDesignation { Identifier = itemVariable.Name },\n\t\t\t\tInExpression = m.Get<IdentifierExpression>(\"collection\").Single().Detach(),\n\t\t\t\tEmbeddedStatement = body\n\t\t\t};\n\t\t\tforeach (var statement in statementsToDelete)\n\t\t\t\tstatement.Detach();\n\t\t\t//foreachStmt.CopyAnnotationsFrom(forStatement);\n\t\t\titemVariable.Kind = IL.VariableKind.ForeachLocal;\n\t\t\t// Add the variable annotation for highlighting (TokenTextWriter expects it directly on the ForeachStatement).\n\t\t\tforeachStmt.VariableDesignation.AddAnnotation(new ILVariableResolveResult(itemVariable, itemVariable.Type));\n\t\t\t// TODO : add ForeachAnnotation\n\t\t\texpressionStatement.ReplaceWith(foreachStmt);\n\t\t\treturn foreachStmt;\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Automatic Properties\n\t\tstatic readonly PropertyDeclaration automaticPropertyPattern = new PropertyDeclaration {\n\t\t\tAttributes = { new Repeat(new AnyNode()) },\n\t\t\tModifiers = Modifiers.Any,\n\t\t\tReturnType = new AnyNode(),\n\t\t\tPrivateImplementationType = new OptionalNode(new AnyNode()),\n\t\t\tName = Pattern.AnyString,\n\t\t\tGetter = new Accessor {\n\t\t\t\tAttributes = { new Repeat(new AnyNode()) },\n\t\t\t\tModifiers = Modifiers.Any,\n\t\t\t\tBody = new BlockStatement {\n\t\t\t\t\tnew ReturnStatement {\n\t\t\t\t\t\tExpression = new AnyNode(\"fieldReference\")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tSetter = new Accessor {\n\t\t\t\tAttributes = { new Repeat(new AnyNode()) },\n\t\t\t\tModifiers = Modifiers.Any,\n\t\t\t\tBody = new BlockStatement {\n\t\t\t\t\tnew AssignmentExpression {\n\t\t\t\t\t\tLeft = new Backreference(\"fieldReference\"),\n\t\t\t\t\t\tRight = new IdentifierExpression(\"value\")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tstatic readonly PropertyDeclaration automaticReadonlyPropertyPattern = new PropertyDeclaration {\n\t\t\tAttributes = { new Repeat(new AnyNode()) },\n\t\t\tModifiers = Modifiers.Any,\n\t\t\tReturnType = new AnyNode(),\n\t\t\tPrivateImplementationType = new OptionalNode(new AnyNode()),\n\t\t\tName = Pattern.AnyString,\n\t\t\tGetter = new Accessor {\n\t\t\t\tAttributes = { new Repeat(new AnyNode()) },\n\t\t\t\tModifiers = Modifiers.Any,\n\t\t\t\tBody = new BlockStatement {\n\t\t\t\t\tnew ReturnStatement {\n\t\t\t\t\t\tExpression = new AnyNode(\"fieldReference\")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tbool CanTransformToAutomaticProperty(IProperty property, bool accessorsMustBeCompilerGenerated)\n\t\t{\n\t\t\tif (!property.CanGet)\n\t\t\t\treturn false;\n\t\t\tif (accessorsMustBeCompilerGenerated && !property.Getter.IsCompilerGenerated())\n\t\t\t\treturn false;\n\t\t\tif (property.Setter is IMethod setter)\n\t\t\t{\n\t\t\t\tif (accessorsMustBeCompilerGenerated && !setter.IsCompilerGenerated())\n\t\t\t\t\treturn false;\n\t\t\t\tif (setter.HasReadonlyModifier())\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tPropertyDeclaration TransformAutomaticProperty(PropertyDeclaration propertyDeclaration)\n\t\t{\n\t\t\tIProperty property = propertyDeclaration.GetSymbol() as IProperty;\n\t\t\tif (!CanTransformToAutomaticProperty(property, !property.DeclaringTypeDefinition.Fields.Any(f => f.Name == \"_\" + property.Name && f.IsCompilerGenerated())))\n\t\t\t\treturn null;\n\t\t\tIField field = null;\n\t\t\tMatch m = automaticPropertyPattern.Match(propertyDeclaration);\n\t\t\tif (m.Success)\n\t\t\t{\n\t\t\t\tfield = m.Get<AstNode>(\"fieldReference\").Single().GetSymbol() as IField;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tMatch m2 = automaticReadonlyPropertyPattern.Match(propertyDeclaration);\n\t\t\t\tif (m2.Success)\n\t\t\t\t{\n\t\t\t\t\tfield = m2.Get<AstNode>(\"fieldReference\").Single().GetSymbol() as IField;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (field == null || !NameCouldBeBackingFieldOfAutomaticProperty(field.Name, out _))\n\t\t\t\treturn null;\n\t\t\tif (propertyDeclaration.Setter.HasModifier(Modifiers.Readonly) || (propertyDeclaration.HasModifier(Modifiers.Readonly) && !propertyDeclaration.Setter.IsNull))\n\t\t\t\treturn null;\n\t\t\tif (field.IsCompilerGenerated() && field.DeclaringTypeDefinition == property.DeclaringTypeDefinition)\n\t\t\t{\n\t\t\t\tRemoveCompilerGeneratedAttribute(propertyDeclaration.Getter.Attributes);\n\t\t\t\tRemoveCompilerGeneratedAttribute(propertyDeclaration.Setter.Attributes);\n\t\t\t\tpropertyDeclaration.Getter.Body = null;\n\t\t\t\tpropertyDeclaration.Setter.Body = null;\n\t\t\t\tpropertyDeclaration.Modifiers &= ~Modifiers.Readonly;\n\t\t\t\tpropertyDeclaration.Getter.Modifiers &= ~Modifiers.Readonly;\n\n\t\t\t\tvar fieldDecl = propertyDeclaration.Parent?.Children.OfType<FieldDeclaration>()\n\t\t\t\t\t.FirstOrDefault(fd => field.Equals(fd.GetSymbol()));\n\t\t\t\tif (fieldDecl != null)\n\t\t\t\t{\n\t\t\t\t\tfieldDecl.Remove();\n\t\t\t\t\t// Add C# 7.3 attributes on backing field:\n\t\t\t\t\tCSharpDecompiler.RemoveAttribute(fieldDecl, KnownAttribute.CompilerGenerated);\n\t\t\t\t\tCSharpDecompiler.RemoveAttribute(fieldDecl, KnownAttribute.DebuggerBrowsable);\n\t\t\t\t\tforeach (var section in fieldDecl.Attributes)\n\t\t\t\t\t{\n\t\t\t\t\t\tsection.AttributeTarget = \"field\";\n\t\t\t\t\t\tpropertyDeclaration.Attributes.Add(section.Detach());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Since the property instance is not changed, we can continue in the visitor as usual, so return null\n\t\t\treturn null;\n\t\t}\n\n\t\tvoid RemoveCompilerGeneratedAttribute(AstNodeCollection<AttributeSection> attributeSections)\n\t\t{\n\t\t\tRemoveCompilerGeneratedAttribute(attributeSections, \"System.Runtime.CompilerServices.CompilerGeneratedAttribute\");\n\t\t}\n\n\t\tvoid RemoveCompilerGeneratedAttribute(AstNodeCollection<AttributeSection> attributeSections, params string[] attributesToRemove)\n\t\t{\n\t\t\tforeach (AttributeSection section in attributeSections)\n\t\t\t{\n\t\t\t\tforeach (var attr in section.Attributes)\n\t\t\t\t{\n\t\t\t\t\tvar tr = attr.Type.GetSymbol() as IType;\n\t\t\t\t\tif (tr != null && attributesToRemove.Contains(tr.FullName))\n\t\t\t\t\t{\n\t\t\t\t\t\tattr.Remove();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (section.Attributes.Count == 0)\n\t\t\t\t\tsection.Remove();\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic override AstNode VisitIdentifier(Identifier identifier)\n\t\t{\n\t\t\tif (context.Settings.AutomaticProperties)\n\t\t\t{\n\t\t\t\tvar newIdentifier = ReplaceBackingFieldUsage(identifier);\n\t\t\t\tif (newIdentifier != null)\n\t\t\t\t{\n\t\t\t\t\tidentifier.ReplaceWith(newIdentifier);\n\t\t\t\t\treturn newIdentifier;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (context.Settings.AutomaticEvents)\n\t\t\t{\n\t\t\t\tvar newIdentifier = ReplaceEventFieldAnnotation(identifier);\n\t\t\t\tif (newIdentifier != null)\n\t\t\t\t\treturn newIdentifier;\n\t\t\t}\n\t\t\treturn base.VisitIdentifier(identifier);\n\t\t}\n\n\t\tinternal static bool IsBackingFieldOfAutomaticProperty(IField field, out IProperty property)\n\t\t{\n\t\t\tproperty = null;\n\t\t\tif (!NameCouldBeBackingFieldOfAutomaticProperty(field.Name, out string propertyName))\n\t\t\t\treturn false;\n\t\t\tif (!field.IsCompilerGenerated())\n\t\t\t\treturn false;\n\t\t\tproperty = field.DeclaringTypeDefinition\n\t\t\t\t.GetProperties(p => p.Name == propertyName, GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t\t.FirstOrDefault();\n\t\t\treturn property != null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// This matches the following patterns\n\t\t/// <list type=\"bullet\">\n\t\t///\t\t<item>&lt;Property&gt;k__BackingField (used by C#)</item>\n\t\t///\t\t<item>_Property (used by VB)</item>\n\t\t/// </list>\n\t\t/// </summary>\n\t\tstatic readonly System.Text.RegularExpressions.Regex automaticPropertyBackingFieldNameRegex\n\t\t\t= new System.Text.RegularExpressions.Regex(@\"^(<(?<name>.+)>k__BackingField|_(?<name>.+))$\");\n\n\t\tstatic bool NameCouldBeBackingFieldOfAutomaticProperty(string name, out string propertyName)\n\t\t{\n\t\t\tpropertyName = null;\n\t\t\tvar m = automaticPropertyBackingFieldNameRegex.Match(name);\n\t\t\tif (!m.Success)\n\t\t\t\treturn false;\n\t\t\tpropertyName = m.Groups[\"name\"].Value;\n\t\t\treturn true;\n\t\t}\n\n\t\tIdentifier ReplaceBackingFieldUsage(Identifier identifier)\n\t\t{\n\t\t\tif (NameCouldBeBackingFieldOfAutomaticProperty(identifier.Name, out _))\n\t\t\t{\n\t\t\t\tvar parent = identifier.Parent;\n\t\t\t\tvar mrr = parent.Annotation<MemberResolveResult>();\n\t\t\t\tvar field = mrr?.Member as IField;\n\t\t\t\tif (field != null && IsBackingFieldOfAutomaticProperty(field, out var property)\n\t\t\t\t\t&& CanTransformToAutomaticProperty(property, !(field.IsCompilerGenerated() && field.Name == \"_\" + property.Name))\n\t\t\t\t\t&& currentMethod.AccessorOwner != property)\n\t\t\t\t{\n\t\t\t\t\tif (!property.CanSet && !context.Settings.GetterOnlyAutomaticProperties)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tparent.RemoveAnnotations<MemberResolveResult>();\n\t\t\t\t\tparent.AddAnnotation(new MemberResolveResult(mrr.TargetResult, property));\n\t\t\t\t\treturn Identifier.Create(property.Name);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tIdentifier ReplaceEventFieldAnnotation(Identifier identifier)\n\t\t{\n\t\t\tvar parent = identifier.Parent;\n\t\t\tvar mrr = parent.Annotation<MemberResolveResult>();\n\t\t\tif (mrr?.Member is not IField field || field.Accessibility != Accessibility.Private)\n\t\t\t\treturn null;\n\t\t\tvar module = field.ParentModule as MetadataModule;\n\t\t\tif (module == null)\n\t\t\t\treturn null;\n\t\t\tif (module.MetadataFile.PropertyAndEventBackingFieldLookup.IsEventBackingField((FieldDefinitionHandle)field.MetadataToken, out var eventHandle))\n\t\t\t{\n\t\t\t\tvar eventDef = module.ResolveEntity(eventHandle) as IEvent;\n\t\t\t\tif (eventDef != null && currentMethod.AccessorOwner != eventDef)\n\t\t\t\t{\n\t\t\t\t\tparent.RemoveAnnotations<MemberResolveResult>();\n\t\t\t\t\tparent.AddAnnotation(new MemberResolveResult(mrr.TargetResult, eventDef));\n\t\t\t\t\tidentifier.Name = eventDef.Name;\n\t\t\t\t\treturn identifier;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\t#region Automatic Events\n\t\tstatic readonly Expression fieldReferencePattern = new Choice {\n\t\t\tnew IdentifierExpression(Pattern.AnyString),\n\t\t\tnew MemberReferenceExpression {\n\t\t\t\tTarget = new Choice { new ThisReferenceExpression(), new TypeReferenceExpression { Type = new AnyNode() } },\n\t\t\t\tMemberName = Pattern.AnyString\n\t\t\t}\n\t\t};\n\n\t\tstatic readonly Accessor automaticEventPatternV2 = new Accessor {\n\t\t\tAttributes = { new Repeat(new AnyNode()) },\n\t\t\tBody = new BlockStatement {\n\t\t\t\tnew AssignmentExpression {\n\t\t\t\t\tLeft = new NamedNode(\"field\", fieldReferencePattern),\n\t\t\t\t\tOperator = AssignmentOperatorType.Assign,\n\t\t\t\t\tRight = new CastExpression(\n\t\t\t\t\t\tnew AnyNode(\"type\"),\n\t\t\t\t\t\tnew InvocationExpression(new AnyNode(\"delegateCombine\").ToExpression(), new Backreference(\"field\"), new IdentifierExpression(\"value\"))\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t}\n\t\t};\n\n\t\tstatic readonly Accessor automaticEventPatternV4 = new Accessor {\n\t\t\tAttributes = { new Repeat(new AnyNode()) },\n\t\t\tBody = new BlockStatement {\n\t\t\t\tnew AssignmentExpression {\n\t\t\t\t\tLeft = new NamedNode(\"var1\", new IdentifierExpression(Pattern.AnyString)),\n\t\t\t\t\tOperator = AssignmentOperatorType.Assign,\n\t\t\t\t\tRight = new NamedNode(\"field\", fieldReferencePattern)\n\t\t\t\t},\n\t\t\t\tnew DoWhileStatement {\n\t\t\t\t\tEmbeddedStatement = new BlockStatement {\n\t\t\t\t\t\tnew AssignmentExpression(new NamedNode(\"var2\", new IdentifierExpression(Pattern.AnyString)), new IdentifierExpressionBackreference(\"var1\")),\n\t\t\t\t\t\tnew AssignmentExpression {\n\t\t\t\t\t\t\tLeft = new NamedNode(\"var3\", new IdentifierExpression(Pattern.AnyString)),\n\t\t\t\t\t\t\tOperator = AssignmentOperatorType.Assign,\n\t\t\t\t\t\t\tRight = new CastExpression(new AnyNode(\"type\"), new InvocationExpression(new AnyNode(\"delegateCombine\").ToExpression(), new IdentifierExpressionBackreference(\"var2\"), new IdentifierExpression(\"value\")))\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnew AssignmentExpression {\n\t\t\t\t\t\t\tLeft = new IdentifierExpressionBackreference(\"var1\"),\n\t\t\t\t\t\t\tRight = new InvocationExpression(new MemberReferenceExpression(new TypeReferenceExpression(new TypePattern(typeof(System.Threading.Interlocked)).ToType()),\n\t\t\t\t\t\t\t\t\"CompareExchange\"),\n\t\t\t\t\t\t\t\tnew Expression[] { // arguments\n\t\t\t\t\t\t\t\t\tnew DirectionExpression { FieldDirection = FieldDirection.Ref, Expression = new Backreference(\"field\") },\n\t\t\t\t\t\t\t\t\tnew IdentifierExpressionBackreference(\"var3\"),\n\t\t\t\t\t\t\t\t\tnew IdentifierExpressionBackreference(\"var2\")\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t},\n\t\t\t\t\tCondition = new BinaryOperatorExpression {\n\t\t\t\t\t\tLeft = new CastExpression(new TypePattern(typeof(object)), new IdentifierExpressionBackreference(\"var1\")),\n\t\t\t\t\t\tOperator = BinaryOperatorType.InEquality,\n\t\t\t\t\t\tRight = new IdentifierExpressionBackreference(\"var2\")\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tstatic readonly Accessor automaticEventPatternV4AggressivelyInlined = new Accessor {\n\t\t\tAttributes = { new Repeat(new AnyNode()) },\n\t\t\tBody = new BlockStatement {\n\t\t\t\tnew AssignmentExpression {\n\t\t\t\t\tLeft = new NamedNode(\"var1\", new IdentifierExpression(Pattern.AnyString)),\n\t\t\t\t\tOperator = AssignmentOperatorType.Assign,\n\t\t\t\t\tRight = new NamedNode(\"field\", fieldReferencePattern)\n\t\t\t\t},\n\t\t\t\tnew DoWhileStatement {\n\t\t\t\t\tEmbeddedStatement = new BlockStatement {\n\t\t\t\t\t\tnew AssignmentExpression(new NamedNode(\"var2\", new IdentifierExpression(Pattern.AnyString)), new IdentifierExpressionBackreference(\"var1\")),\n\t\t\t\t\t\tnew AssignmentExpression {\n\t\t\t\t\t\t\tLeft = new IdentifierExpressionBackreference(\"var1\"),\n\t\t\t\t\t\t\tRight = new InvocationExpression(new MemberReferenceExpression(new TypeReferenceExpression(new TypePattern(typeof(System.Threading.Interlocked)).ToType()),\n\t\t\t\t\t\t\t\t\"CompareExchange\"),\n\t\t\t\t\t\t\t\tnew Expression[] { // arguments\n\t\t\t\t\t\t\t\t\tnew NamedArgumentExpression(\"value\", new CastExpression(new AnyNode(\"type\"), new InvocationExpression(new AnyNode(\"delegateCombine\").ToExpression(), new IdentifierExpressionBackreference(\"var2\"), new IdentifierExpression(\"value\")))),\n\t\t\t\t\t\t\t\t\tnew NamedArgumentExpression(\"location1\", new DirectionExpression { FieldDirection = FieldDirection.Ref, Expression = new Backreference(\"field\") }),\n\t\t\t\t\t\t\t\t\tnew NamedArgumentExpression(\"comparand\", new IdentifierExpressionBackreference(\"var2\"))\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t},\n\t\t\t\t\tCondition = new BinaryOperatorExpression {\n\t\t\t\t\t\tLeft = new CastExpression(new TypePattern(typeof(object)), new IdentifierExpressionBackreference(\"var1\")),\n\t\t\t\t\t\tOperator = BinaryOperatorType.InEquality,\n\t\t\t\t\t\tRight = new IdentifierExpressionBackreference(\"var2\")\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tstatic readonly Accessor automaticEventPatternV4MCS = new Accessor {\n\t\t\tAttributes = { new Repeat(new AnyNode()) },\n\t\t\tBody = new BlockStatement {\n\t\t\t\tnew AssignmentExpression {\n\t\t\t\t\tLeft = new NamedNode(\"var1\", new IdentifierExpression(Pattern.AnyString)),\n\t\t\t\t\tOperator = AssignmentOperatorType.Assign,\n\t\t\t\t\tRight = new NamedNode(\n\t\t\t\t\t\t\"field\",\n\t\t\t\t\t\tnew MemberReferenceExpression {\n\t\t\t\t\t\t\t\tTarget = new Choice { new ThisReferenceExpression(), new TypeReferenceExpression { Type = new AnyNode() } },\n\t\t\t\t\t\t\t\tMemberName = Pattern.AnyString\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t\tnew DoWhileStatement {\n\t\t\t\t\tEmbeddedStatement = new BlockStatement {\n\t\t\t\t\t\tnew AssignmentExpression(new NamedNode(\"var2\", new IdentifierExpression(Pattern.AnyString)), new IdentifierExpressionBackreference(\"var1\")),\n\t\t\t\t\t\tnew AssignmentExpression {\n\t\t\t\t\t\t\tLeft = new IdentifierExpressionBackreference(\"var1\"),\n\t\t\t\t\t\t\tRight = new InvocationExpression(new MemberReferenceExpression(new TypeReferenceExpression(new TypePattern(typeof(System.Threading.Interlocked)).ToType()),\n\t\t\t\t\t\t\t\t\"CompareExchange\",\n\t\t\t\t\t\t\t\tnew AstType[] { new Repeat(new AnyNode()) }), // optional type arguments\n\t\t\t\t\t\t\t\tnew Expression[] { // arguments\n\t\t\t\t\t\t\t\t\tnew DirectionExpression { FieldDirection = FieldDirection.Ref, Expression = new Backreference(\"field\") },\n\t\t\t\t\t\t\t\t\tnew CastExpression(new AnyNode(\"type\"), new InvocationExpression(new AnyNode(\"delegateCombine\").ToExpression(), new IdentifierExpressionBackreference(\"var2\"), new IdentifierExpression(\"value\"))),\n\t\t\t\t\t\t\t\t\tnew IdentifierExpressionBackreference(\"var1\")\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tCondition = new BinaryOperatorExpression {\n\t\t\t\t\t\tLeft = new CastExpression(new TypePattern(typeof(object)), new IdentifierExpressionBackreference(\"var1\")),\n\t\t\t\t\t\tOperator = BinaryOperatorType.InEquality,\n\t\t\t\t\t\tRight = new IdentifierExpressionBackreference(\"var2\")\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tbool CheckAutomaticEventMatch(Match m, CustomEventDeclaration ev, bool isAddAccessor)\n\t\t{\n\t\t\tif (!m.Success)\n\t\t\t\treturn false;\n\t\t\tExpression fieldExpression = m.Get<Expression>(\"field\").Single();\n\t\t\tIField eventField = fieldExpression.GetSymbol() as IField;\n\t\t\tif (eventField == null)\n\t\t\t\treturn false;\n\t\t\tvar module = eventField.ParentModule as MetadataModule;\n\t\t\tif (module == null)\n\t\t\t\treturn false;\n\t\t\tif (!module.MetadataFile.PropertyAndEventBackingFieldLookup.IsEventBackingField((FieldDefinitionHandle)eventField.MetadataToken, out _))\n\t\t\t\treturn false;\n\t\t\tvar returnType = ev.ReturnType.GetResolveResult().Type;\n\t\t\tvar eventType = m.Get<AstType>(\"type\").Single().GetResolveResult().Type;\n\t\t\t// ignore tuple element names, dynamic and nullability\n\t\t\tif (!NormalizeTypeVisitor.TypeErasure.EquivalentTypes(returnType, eventType))\n\t\t\t\treturn false;\n\t\t\tvar combineMethod = m.Get<AstNode>(\"delegateCombine\").Single().Parent.GetSymbol() as IMethod;\n\t\t\tif (combineMethod == null || combineMethod.Name != (isAddAccessor ? \"Combine\" : \"Remove\"))\n\t\t\t\treturn false;\n\t\t\treturn combineMethod.DeclaringType.FullName == \"System.Delegate\";\n\t\t}\n\n\t\tstatic readonly string[] attributeTypesToRemoveFromAutoEvents = new[] {\n\t\t\t\"System.Runtime.CompilerServices.CompilerGeneratedAttribute\",\n\t\t\t\"System.Diagnostics.DebuggerBrowsableAttribute\",\n\t\t\t\"System.Runtime.CompilerServices.MethodImplAttribute\"\n\t\t};\n\n\t\tinternal static readonly string[] attributeTypesToRemoveFromAutoProperties = new[] {\n\t\t\t\"System.Runtime.CompilerServices.CompilerGeneratedAttribute\",\n\t\t\t\"System.Diagnostics.DebuggerBrowsableAttribute\"\n\t\t};\n\n\t\tbool CheckAutomaticEventV4(CustomEventDeclaration ev)\n\t\t{\n\t\t\tMatch addMatch = automaticEventPatternV4.Match(ev.AddAccessor);\n\t\t\tif (!CheckAutomaticEventMatch(addMatch, ev, isAddAccessor: true))\n\t\t\t\treturn false;\n\t\t\tMatch removeMatch = automaticEventPatternV4.Match(ev.RemoveAccessor);\n\t\t\tif (!CheckAutomaticEventMatch(removeMatch, ev, isAddAccessor: false))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tbool CheckAutomaticEventV4AggressivelyInlined(CustomEventDeclaration ev)\n\t\t{\n\t\t\tif (!context.Settings.AggressiveInlining)\n\t\t\t\treturn false;\n\t\t\tMatch addMatch = automaticEventPatternV4AggressivelyInlined.Match(ev.AddAccessor);\n\t\t\tif (!CheckAutomaticEventMatch(addMatch, ev, isAddAccessor: true))\n\t\t\t\treturn false;\n\t\t\tMatch removeMatch = automaticEventPatternV4AggressivelyInlined.Match(ev.RemoveAccessor);\n\t\t\tif (!CheckAutomaticEventMatch(removeMatch, ev, isAddAccessor: false))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tbool CheckAutomaticEventV2(CustomEventDeclaration ev)\n\t\t{\n\t\t\tMatch addMatch = automaticEventPatternV2.Match(ev.AddAccessor);\n\t\t\tif (!CheckAutomaticEventMatch(addMatch, ev, isAddAccessor: true))\n\t\t\t\treturn false;\n\t\t\tMatch removeMatch = automaticEventPatternV2.Match(ev.RemoveAccessor);\n\t\t\tif (!CheckAutomaticEventMatch(removeMatch, ev, isAddAccessor: false))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tbool CheckAutomaticEventV4MCS(CustomEventDeclaration ev)\n\t\t{\n\t\t\tMatch addMatch = automaticEventPatternV4MCS.Match(ev.AddAccessor);\n\t\t\tif (!CheckAutomaticEventMatch(addMatch, ev, true))\n\t\t\t\treturn false;\n\t\t\tMatch removeMatch = automaticEventPatternV4MCS.Match(ev.RemoveAccessor);\n\t\t\tif (!CheckAutomaticEventMatch(removeMatch, ev, false))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tEventDeclaration TransformAutomaticEvents(CustomEventDeclaration ev)\n\t\t{\n\t\t\tif (!ev.PrivateImplementationType.IsNull)\n\t\t\t\treturn null;\n\t\t\tconst Modifiers withoutBody = Modifiers.Abstract | Modifiers.Extern;\n\t\t\tif (ev.GetSymbol() is not IEvent symbol)\n\t\t\t\treturn null;\n\t\t\tif ((ev.Modifiers & withoutBody) == 0)\n\t\t\t{\n\t\t\t\tif (!CheckAutomaticEventV4AggressivelyInlined(ev) && !CheckAutomaticEventV4(ev) && !CheckAutomaticEventV2(ev) && !CheckAutomaticEventV4MCS(ev))\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t\tRemoveCompilerGeneratedAttribute(ev.AddAccessor.Attributes, attributeTypesToRemoveFromAutoEvents);\n\t\t\tEventDeclaration ed = new EventDeclaration();\n\t\t\tev.Attributes.MoveTo(ed.Attributes);\n\t\t\tforeach (var attr in ev.AddAccessor.Attributes)\n\t\t\t{\n\t\t\t\tattr.AttributeTarget = \"method\";\n\t\t\t\ted.Attributes.Add(attr.Detach());\n\t\t\t}\n\t\t\ted.ReturnType = ev.ReturnType.Detach();\n\t\t\ted.Modifiers = ev.Modifiers;\n\t\t\ted.Variables.Add(new VariableInitializer(ev.Name));\n\t\t\ted.CopyAnnotationsFrom(ev);\n\n\t\t\tvar fieldDecl = ev.Parent?.Children.OfType<FieldDeclaration>()\n\t\t\t\t.FirstOrDefault(IsEventBackingField);\n\t\t\tif (fieldDecl != null)\n\t\t\t{\n\t\t\t\tfieldDecl.Remove();\n\t\t\t\tCSharpDecompiler.RemoveAttribute(fieldDecl, KnownAttribute.CompilerGenerated);\n\t\t\t\tCSharpDecompiler.RemoveAttribute(fieldDecl, KnownAttribute.DebuggerBrowsable);\n\t\t\t\tforeach (var section in fieldDecl.Attributes)\n\t\t\t\t{\n\t\t\t\t\tsection.AttributeTarget = \"field\";\n\t\t\t\t\ted.Attributes.Add(section.Detach());\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tev.ReplaceWith(ed);\n\t\t\treturn ed;\n\n\t\t\tbool IsEventBackingField(FieldDeclaration fd)\n\t\t\t{\n\t\t\t\tif (fd.Variables.Count > 1)\n\t\t\t\t\treturn false;\n\t\t\t\tif (fd.GetSymbol() is not IField f)\n\t\t\t\t\treturn false;\n\t\t\t\tif (f.ParentModule is not MetadataModule module)\n\t\t\t\t\treturn false;\n\t\t\t\treturn f.Accessibility == Accessibility.Private\n\t\t\t\t\t&& symbol.ReturnType.Equals(f.ReturnType)\n\t\t\t\t\t&& module.MetadataFile.PropertyAndEventBackingFieldLookup.IsEventBackingField((FieldDefinitionHandle)f.MetadataToken, out _);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Destructor\n\t\tstatic readonly BlockStatement destructorBodyPattern = new BlockStatement {\n\t\t\tnew TryCatchStatement {\n\t\t\t\tTryBlock = new AnyNode(\"body\"),\n\t\t\t\tFinallyBlock = new BlockStatement {\n\t\t\t\t\tnew InvocationExpression(new MemberReferenceExpression(new BaseReferenceExpression(), \"Finalize\"))\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tstatic readonly MethodDeclaration destructorPattern = new MethodDeclaration {\n\t\t\tAttributes = { new Repeat(new AnyNode()) },\n\t\t\tModifiers = Modifiers.Any,\n\t\t\tReturnType = new PrimitiveType(\"void\"),\n\t\t\tName = \"Finalize\",\n\t\t\tBody = destructorBodyPattern\n\t\t};\n\n\t\tDestructorDeclaration TransformDestructor(MethodDeclaration methodDef)\n\t\t{\n\t\t\tMatch m = destructorPattern.Match(methodDef);\n\t\t\tif (m.Success)\n\t\t\t{\n\t\t\t\tDestructorDeclaration dd = new DestructorDeclaration();\n\t\t\t\tmethodDef.Attributes.MoveTo(dd.Attributes);\n\t\t\t\tdd.CopyAnnotationsFrom(methodDef);\n\t\t\t\tdd.Modifiers = methodDef.Modifiers & ~(Modifiers.Protected | Modifiers.Override);\n\t\t\t\tdd.Body = m.Get<BlockStatement>(\"body\").Single().Detach();\n\t\t\t\tdd.Name = currentTypeDefinition?.Name;\n\t\t\t\tmethodDef.ReplaceWith(dd);\n\t\t\t\treturn dd;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tDestructorDeclaration TransformDestructorBody(DestructorDeclaration dtorDef)\n\t\t{\n\t\t\tMatch m = destructorBodyPattern.Match(dtorDef.Body);\n\t\t\tif (m.Success)\n\t\t\t{\n\t\t\t\tdtorDef.Body = m.Get<BlockStatement>(\"body\").Single().Detach();\n\t\t\t\treturn dtorDef;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\t#endregion\n\n\t\t#region Try-Catch-Finally\n\t\tstatic readonly TryCatchStatement tryCatchFinallyPattern = new TryCatchStatement {\n\t\t\tTryBlock = new BlockStatement {\n\t\t\t\tnew TryCatchStatement {\n\t\t\t\t\tTryBlock = new AnyNode(),\n\t\t\t\t\tCatchClauses = { new Repeat(new AnyNode()) }\n\t\t\t\t}\n\t\t\t},\n\t\t\tFinallyBlock = new AnyNode()\n\t\t};\n\n\t\t/// <summary>\n\t\t/// Simplify nested 'try { try {} catch {} } finally {}'.\n\t\t/// This transformation must run after the using/lock tranformations.\n\t\t/// </summary>\n\t\tTryCatchStatement TransformTryCatchFinally(TryCatchStatement tryFinally)\n\t\t{\n\t\t\tif (tryCatchFinallyPattern.IsMatch(tryFinally))\n\t\t\t{\n\t\t\t\tTryCatchStatement tryCatch = (TryCatchStatement)tryFinally.TryBlock.Statements.Single();\n\t\t\t\ttryFinally.TryBlock = tryCatch.TryBlock.Detach();\n\t\t\t\ttryCatch.CatchClauses.MoveTo(tryFinally.CatchClauses);\n\t\t\t}\n\t\t\t// Since the tryFinally instance is not changed, we can continue in the visitor as usual, so return null\n\t\t\treturn null;\n\t\t}\n\t\t#endregion\n\n\t\t#region Simplify cascading if-else-if statements\n\t\tstatic readonly IfElseStatement cascadingIfElsePattern = new IfElseStatement {\n\t\t\tCondition = new AnyNode(),\n\t\t\tTrueStatement = new AnyNode(),\n\t\t\tFalseStatement = new BlockStatement {\n\t\t\t\tStatements = {\n\t\t\t\t\tnew NamedNode(\n\t\t\t\t\t\t\"nestedIfStatement\",\n\t\t\t\t\t\tnew IfElseStatement {\n\t\t\t\t\t\t\tCondition = new AnyNode(),\n\t\t\t\t\t\t\tTrueStatement = new AnyNode(),\n\t\t\t\t\t\t\tFalseStatement = new OptionalNode(new AnyNode())\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tAstNode SimplifyCascadingIfElseStatements(IfElseStatement node)\n\t\t{\n\t\t\tMatch m = cascadingIfElsePattern.Match(node);\n\t\t\tif (m.Success)\n\t\t\t{\n\t\t\t\tIfElseStatement elseIf = m.Get<IfElseStatement>(\"nestedIfStatement\").Single();\n\t\t\t\tnode.FalseStatement = elseIf.Detach();\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Use associativity of logic operators to avoid parentheses.\n\t\t/// </summary>\n\t\tpublic override AstNode VisitBinaryOperatorExpression(BinaryOperatorExpression expr)\n\t\t{\n\t\t\tswitch (expr.Operator)\n\t\t\t{\n\t\t\t\tcase BinaryOperatorType.ConditionalAnd:\n\t\t\t\tcase BinaryOperatorType.ConditionalOr:\n\t\t\t\t\t// a && (b && c) ==> (a && b) && c\n\t\t\t\t\tvar bAndC = expr.Right as BinaryOperatorExpression;\n\t\t\t\t\tif (bAndC != null && bAndC.Operator == expr.Operator)\n\t\t\t\t\t{\n\t\t\t\t\t\t// make bAndC the parent and expr the child\n\t\t\t\t\t\tvar b = bAndC.Left.Detach();\n\t\t\t\t\t\tvar c = bAndC.Right.Detach();\n\t\t\t\t\t\texpr.ReplaceWith(bAndC.Detach());\n\t\t\t\t\t\tbAndC.Left = expr;\n\t\t\t\t\t\tbAndC.Right = c;\n\t\t\t\t\t\texpr.Right = b;\n\t\t\t\t\t\treturn base.VisitBinaryOperatorExpression(bAndC);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn base.VisitBinaryOperatorExpression(expr);\n\t\t}\n\n\t\tpublic override AstNode VisitUnaryOperatorExpression(UnaryOperatorExpression expr)\n\t\t{\n\t\t\tif (expr.Operator == UnaryOperatorType.Not && expr.Expression is BinaryOperatorExpression { Operator: BinaryOperatorType.Equality } binary)\n\t\t\t{\n\t\t\t\tbinary.Operator = BinaryOperatorType.InEquality;\n\t\t\t\texpr.ReplaceWith(binary.Detach());\n\t\t\t\treturn VisitBinaryOperatorExpression(binary);\n\t\t\t}\n\t\t\treturn base.VisitUnaryOperatorExpression(expr);\n\t\t}\n\t\t#endregion\n\n\t\t#region C# 7.3 pattern based fixed (for value types)\n\t\t// reference types are handled by DetectPinnedRegions.IsCustomRefPinPattern\n\t\tstatic readonly Expression addressOfPinnableReference = new UnaryOperatorExpression {\n\t\t\tOperator = UnaryOperatorType.AddressOf,\n\t\t\tExpression = new InvocationExpression {\n\t\t\t\tTarget = new MemberReferenceExpression(new AnyNode(\"target\"), \"GetPinnableReference\"),\n\t\t\t\tArguments = { }\n\t\t\t}\n\t\t};\n\n\t\tpublic override AstNode VisitFixedStatement(FixedStatement fixedStatement)\n\t\t{\n\t\t\tif (context.Settings.PatternBasedFixedStatement)\n\t\t\t{\n\t\t\t\tforeach (var v in fixedStatement.Variables)\n\t\t\t\t{\n\t\t\t\t\tvar m = addressOfPinnableReference.Match(v.Initializer);\n\t\t\t\t\tif (m.Success)\n\t\t\t\t\t{\n\t\t\t\t\t\tExpression target = m.Get<Expression>(\"target\").Single();\n\t\t\t\t\t\tif (target.GetResolveResult().Type.IsReferenceType == false)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tv.Initializer = target.Detach();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn base.VisitFixedStatement(fixedStatement);\n\t\t}\n\t\t#endregion\n\n\t\t#region C# 8.0 Using variables\n\t\tpublic override AstNode VisitUsingStatement(UsingStatement usingStatement)\n\t\t{\n\t\t\tusingStatement = (UsingStatement)base.VisitUsingStatement(usingStatement);\n\t\t\tif (!context.Settings.UseEnhancedUsing)\n\t\t\t\treturn usingStatement;\n\n\t\t\tif (usingStatement.GetNextStatement() != null || !(usingStatement.Parent is BlockStatement))\n\t\t\t\treturn usingStatement;\n\n\t\t\tif (!(usingStatement.ResourceAcquisition is VariableDeclarationStatement))\n\t\t\t\treturn usingStatement;\n\n\t\t\tusingStatement.IsEnhanced = true;\n\t\t\treturn usingStatement;\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/PrettifyAssignments.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Resolver;\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\t/// <summary>\n\t/// Simplifies \"x = x op y\" into \"x op= y\" where possible.\n\t/// </summary>\n\t/// <remarks>\n\t/// Because the two \"x\" in \"x = x op y\" may refer to different ILVariables,\n\t/// this transform must run after DeclareVariables.\n\t/// \n\t/// It must also run after ReplaceMethodCallsWithOperators (so that it can work for custom operator, too);\n\t/// and after AddCheckedBlocks (because \"for (;; x = unchecked(x op y))\" cannot be transformed into \"x += y\").\n\t/// </remarks>\n\tclass PrettifyAssignments : DepthFirstAstVisitor, IAstTransform\n\t{\n\t\tTransformContext context;\n\n\t\tpublic override void VisitAssignmentExpression(AssignmentExpression assignment)\n\t\t{\n\t\t\tbase.VisitAssignmentExpression(assignment);\n\t\t\t// Combine \"x = x op y\" into \"x op= y\"\n\t\t\t// Also supports \"x = (T)(x op y)\" -> \"x op= y\", if x.GetType() == T\n\t\t\t// and y is implicitly convertible to T.\n\t\t\tExpression rhs = assignment.Right;\n\t\t\tIType expectedType = null;\n\t\t\tif (assignment.Right is CastExpression { Type: var astType } cast)\n\t\t\t{\n\t\t\t\trhs = cast.Expression;\n\t\t\t\texpectedType = astType.GetResolveResult().Type;\n\t\t\t}\n\t\t\tif (rhs is BinaryOperatorExpression binary && assignment.Operator == AssignmentOperatorType.Assign)\n\t\t\t{\n\t\t\t\tif (CanConvertToCompoundAssignment(assignment.Left) && assignment.Left.IsMatch(binary.Left)\n\t\t\t\t\t&& IsImplicitlyConvertible(binary.Right, expectedType))\n\t\t\t\t{\n\t\t\t\t\tassignment.Operator = GetAssignmentOperatorForBinaryOperator(binary.Operator);\n\t\t\t\t\tif (assignment.Operator != AssignmentOperatorType.Assign)\n\t\t\t\t\t{\n\t\t\t\t\t\t// If we found a shorter operator, get rid of the BinaryOperatorExpression:\n\t\t\t\t\t\tassignment.CopyAnnotationsFrom(binary);\n\t\t\t\t\t\tassignment.Right = binary.Right;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (context.Settings.IntroduceIncrementAndDecrement && assignment.Operator == AssignmentOperatorType.Add || assignment.Operator == AssignmentOperatorType.Subtract)\n\t\t\t{\n\t\t\t\t// detect increment/decrement\n\t\t\t\tvar rr = assignment.Right.GetResolveResult();\n\t\t\t\tif (rr.IsCompileTimeConstant && rr.Type.IsCSharpPrimitiveIntegerType() && CSharpPrimitiveCast.Cast(rr.Type.GetTypeCode(), 1, false).Equals(rr.ConstantValue))\n\t\t\t\t{\n\t\t\t\t\t// only if it's not a custom operator\n\t\t\t\t\tif (assignment.Annotation<IL.CallInstruction>() == null && assignment.Annotation<IL.UserDefinedCompoundAssign>() == null && assignment.Annotation<IL.DynamicCompoundAssign>() == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tUnaryOperatorType type;\n\t\t\t\t\t\t// When the parent is an expression statement, pre- or post-increment doesn't matter;\n\t\t\t\t\t\t// so we can pick post-increment which is more commonly used (for (int i = 0; i < x; i++))\n\t\t\t\t\t\tif (assignment.Parent is ExpressionStatement)\n\t\t\t\t\t\t\ttype = (assignment.Operator == AssignmentOperatorType.Add) ? UnaryOperatorType.PostIncrement : UnaryOperatorType.PostDecrement;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\ttype = (assignment.Operator == AssignmentOperatorType.Add) ? UnaryOperatorType.Increment : UnaryOperatorType.Decrement;\n\t\t\t\t\t\tassignment.ReplaceWith(new UnaryOperatorExpression(type, assignment.Left.Detach()).CopyAnnotationsFrom(assignment));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool IsImplicitlyConvertible(Expression rhs, IType expectedType)\n\t\t\t{\n\t\t\t\tif (expectedType == null)\n\t\t\t\t\treturn true;\n\n\t\t\t\tvar conversions = CSharpConversions.Get(context.TypeSystem);\n\t\t\t\treturn conversions.ImplicitConversion(rhs.GetResolveResult(), expectedType).IsImplicit;\n\t\t\t}\n\t\t}\n\n\t\tpublic static AssignmentOperatorType GetAssignmentOperatorForBinaryOperator(BinaryOperatorType bop)\n\t\t{\n\t\t\tswitch (bop)\n\t\t\t{\n\t\t\t\tcase BinaryOperatorType.Add:\n\t\t\t\t\treturn AssignmentOperatorType.Add;\n\t\t\t\tcase BinaryOperatorType.Subtract:\n\t\t\t\t\treturn AssignmentOperatorType.Subtract;\n\t\t\t\tcase BinaryOperatorType.Multiply:\n\t\t\t\t\treturn AssignmentOperatorType.Multiply;\n\t\t\t\tcase BinaryOperatorType.Divide:\n\t\t\t\t\treturn AssignmentOperatorType.Divide;\n\t\t\t\tcase BinaryOperatorType.Modulus:\n\t\t\t\t\treturn AssignmentOperatorType.Modulus;\n\t\t\t\tcase BinaryOperatorType.ShiftLeft:\n\t\t\t\t\treturn AssignmentOperatorType.ShiftLeft;\n\t\t\t\tcase BinaryOperatorType.ShiftRight:\n\t\t\t\t\treturn AssignmentOperatorType.ShiftRight;\n\t\t\t\tcase BinaryOperatorType.UnsignedShiftRight:\n\t\t\t\t\treturn AssignmentOperatorType.UnsignedShiftRight;\n\t\t\t\tcase BinaryOperatorType.BitwiseAnd:\n\t\t\t\t\treturn AssignmentOperatorType.BitwiseAnd;\n\t\t\t\tcase BinaryOperatorType.BitwiseOr:\n\t\t\t\t\treturn AssignmentOperatorType.BitwiseOr;\n\t\t\t\tcase BinaryOperatorType.ExclusiveOr:\n\t\t\t\t\treturn AssignmentOperatorType.ExclusiveOr;\n\t\t\t\tdefault:\n\t\t\t\t\treturn AssignmentOperatorType.Assign;\n\t\t\t}\n\t\t}\n\n\t\tstatic bool CanConvertToCompoundAssignment(Expression left)\n\t\t{\n\t\t\tMemberReferenceExpression mre = left as MemberReferenceExpression;\n\t\t\tif (mre != null)\n\t\t\t\treturn IsWithoutSideEffects(mre.Target);\n\t\t\tIndexerExpression ie = left as IndexerExpression;\n\t\t\tif (ie != null)\n\t\t\t\treturn IsWithoutSideEffects(ie.Target) && ie.Arguments.All(IsWithoutSideEffects);\n\t\t\tUnaryOperatorExpression uoe = left as UnaryOperatorExpression;\n\t\t\tif (uoe != null && uoe.Operator == UnaryOperatorType.Dereference)\n\t\t\t\treturn IsWithoutSideEffects(uoe.Expression);\n\t\t\treturn IsWithoutSideEffects(left);\n\t\t}\n\n\t\tstatic bool IsWithoutSideEffects(Expression left)\n\t\t{\n\t\t\treturn left is ThisReferenceExpression || left is IdentifierExpression || left is TypeReferenceExpression || left is BaseReferenceExpression;\n\t\t}\n\n\t\tvoid IAstTransform.Run(AstNode node, TransformContext context)\n\t\t{\n\t\t\tthis.context = context;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tnode.AcceptVisitor(this);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tthis.context = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/RemoveCLSCompliantAttribute.cs",
    "content": "// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.Semantics;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\t/// <summary>\n\t/// This transform is used to remove CLSCompliant attributes added by the compiler. We remove them in order to get rid of many warnings.\n\t/// </summary>\n\t/// <remarks>This transform is only enabled, when exporting a full assembly as project.</remarks>\n\tpublic class RemoveCLSCompliantAttribute : IAstTransform\n\t{\n\t\tpublic void Run(AstNode rootNode, TransformContext context)\n\t\t{\n\t\t\tforeach (var section in rootNode.Children.OfType<AttributeSection>())\n\t\t\t{\n\t\t\t\tif (section.AttributeTarget == \"assembly\")\n\t\t\t\t\tcontinue;\n\t\t\t\tforeach (var attribute in section.Attributes)\n\t\t\t\t{\n\t\t\t\t\tvar trr = attribute.Type.Annotation<TypeResolveResult>();\n\t\t\t\t\tif (trr != null && trr.Type.FullName == \"System.CLSCompliantAttribute\")\n\t\t\t\t\t\tattribute.Remove();\n\t\t\t\t}\n\t\t\t\tif (section.Attributes.Count == 0)\n\t\t\t\t\tsection.Remove();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/ReplaceMethodCallsWithOperators.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Linq;\nusing System.Reflection;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\t/// <summary>\n\t/// Replaces method calls with the appropriate operator expressions.\n\t/// </summary>\n\tpublic class ReplaceMethodCallsWithOperators : DepthFirstAstVisitor, IAstTransform\n\t{\n\t\tstatic readonly MemberReferenceExpression typeHandleOnTypeOfPattern = new MemberReferenceExpression {\n\t\t\tTarget = new Choice {\n\t\t\t\tnew TypeOfExpression(new AnyNode()),\n\t\t\t\tnew UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.RefType, Arguments = { new AnyNode() } }\n\t\t\t},\n\t\t\tMemberName = \"TypeHandle\"\n\t\t};\n\n\t\tTransformContext context;\n\n\t\tpublic override void VisitInvocationExpression(InvocationExpression invocationExpression)\n\t\t{\n\t\t\tbase.VisitInvocationExpression(invocationExpression);\n\t\t\tProcessInvocationExpression(invocationExpression);\n\t\t}\n\n\t\tvoid ProcessInvocationExpression(InvocationExpression invocationExpression)\n\t\t{\n\t\t\tvar method = invocationExpression.GetSymbol() as IMethod;\n\t\t\tif (method == null)\n\t\t\t\treturn;\n\t\t\tvar arguments = invocationExpression.Arguments.ToArray();\n\n\t\t\t// Reduce \"String.Concat(a, b)\" to \"a + b\"\n\t\t\tif (IsStringConcat(method) && context.Settings.StringConcat)\n\t\t\t{\n\t\t\t\tif (arguments is [ArrayCreateExpression ace] && method.Parameters is [{ Type: ArrayType }])\n\t\t\t\t{\n\t\t\t\t\targuments = ace.Initializer.Elements.ToArray();\n\t\t\t\t}\n\n\t\t\t\tif (!CheckArgumentsForStringConcat(arguments))\n\t\t\t\t{\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tbool isInExpressionTree = invocationExpression.Ancestors.OfType<LambdaExpression>().Any(\n\t\t\t\t\tlambda => lambda.Annotation<IL.ILFunction>()?.Kind == IL.ILFunctionKind.ExpressionTree);\n\t\t\t\tExpression arg0 = arguments[0].Detach();\n\t\t\t\tExpression arg1 = arguments[1].Detach();\n\t\t\t\tif (!isInExpressionTree)\n\t\t\t\t{\n\t\t\t\t\targ1 = RemoveRedundantToStringInConcat(arg1, method, isLastArgument: arguments.Length == 2).Detach();\n\t\t\t\t\tif (arg1.GetResolveResult().Type.IsKnownType(KnownTypeCode.String))\n\t\t\t\t\t{\n\t\t\t\t\t\targ0 = RemoveRedundantToStringInConcat(arg0, method, isLastArgument: false).Detach();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvar expr = new BinaryOperatorExpression(arg0, BinaryOperatorType.Add, arg1);\n\t\t\t\tfor (int i = 2; i < arguments.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tvar arg = arguments[i].Detach();\n\t\t\t\t\tif (!isInExpressionTree)\n\t\t\t\t\t{\n\t\t\t\t\t\targ = RemoveRedundantToStringInConcat(arg, method, isLastArgument: i == arguments.Length - 1).Detach();\n\t\t\t\t\t}\n\t\t\t\t\texpr = new BinaryOperatorExpression(expr, BinaryOperatorType.Add, arg);\n\t\t\t\t}\n\t\t\t\texpr.CopyAnnotationsFrom(invocationExpression);\n\t\t\t\tinvocationExpression.ReplaceWith(expr);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tswitch (method.FullName)\n\t\t\t{\n\t\t\t\tcase \"System.Type.GetTypeFromHandle\":\n\t\t\t\t\tif (arguments.Length == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (typeHandleOnTypeOfPattern.IsMatch(arguments[0]))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tExpression target = ((MemberReferenceExpression)arguments[0]).Target;\n\t\t\t\t\t\t\ttarget.CopyInstructionsFrom(invocationExpression);\n\t\t\t\t\t\t\tinvocationExpression.ReplaceWith(target);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t/*\n\t\t\tcase \"System.Reflection.FieldInfo.GetFieldFromHandle\":\n\t\t\t\t// TODO : This is dead code because LdTokenAnnotation is not added anywhere:\n\t\t\t\tif (arguments.Length == 1) {\n\t\t\t\t\tMemberReferenceExpression mre = arguments[0] as MemberReferenceExpression;\n\t\t\t\t\tif (mre != null && mre.MemberName == \"FieldHandle\" && mre.Target.Annotation<LdTokenAnnotation>() != null) {\n\t\t\t\t\t\tinvocationExpression.ReplaceWith(mre.Target);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t} else if (arguments.Length == 2) {\n\t\t\t\t\tMemberReferenceExpression mre1 = arguments[0] as MemberReferenceExpression;\n\t\t\t\t\tMemberReferenceExpression mre2 = arguments[1] as MemberReferenceExpression;\n\t\t\t\t\tif (mre1 != null && mre1.MemberName == \"FieldHandle\" && mre1.Target.Annotation<LdTokenAnnotation>() != null) {\n\t\t\t\t\t\tif (mre2 != null && mre2.MemberName == \"TypeHandle\" && mre2.Target is TypeOfExpression) {\n\t\t\t\t\t\t\tExpression oldArg = ((InvocationExpression)mre1.Target).Arguments.Single();\n\t\t\t\t\t\t\tFieldReference field = oldArg.Annotation<FieldReference>();\n\t\t\t\t\t\t\tif (field != null) {\n\t\t\t\t\t\t\t\tAstType declaringType = ((TypeOfExpression)mre2.Target).Type.Detach();\n\t\t\t\t\t\t\t\toldArg.ReplaceWith(new MemberReferenceExpression(new TypeReferenceExpression(declaringType), field.Name).CopyAnnotationsFrom(oldArg));\n\t\t\t\t\t\t\t\tinvocationExpression.ReplaceWith(mre1.Target);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t\t*/\n\t\t\t\tcase \"System.Activator.CreateInstance\":\n\t\t\t\t\tif (context.Settings.UseObjectCreationOfGenericTypeParameter &&\n\t\t\t\t\t\targuments.Length == 0 &&\n\t\t\t\t\t\tmethod.TypeArguments.Count == 1 &&\n\t\t\t\t\t\tIsInstantiableTypeParameter(method.TypeArguments[0]))\n\t\t\t\t\t{\n\t\t\t\t\t\tinvocationExpression.ReplaceWith(new ObjectCreateExpression(context.TypeSystemAstBuilder.ConvertType(method.TypeArguments.First())));\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"System.Runtime.CompilerServices.RuntimeHelpers.GetSubArray\":\n\t\t\t\t\tif (arguments.Length == 2 && context.Settings.Ranges)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar slicing = new IndexerExpression(arguments[0].Detach(), arguments[1].Detach());\n\t\t\t\t\t\tslicing.CopyAnnotationsFrom(invocationExpression);\n\t\t\t\t\t\tinvocationExpression.ReplaceWith(slicing);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tbool isChecked;\n\t\t\tBinaryOperatorType? bop = GetBinaryOperatorTypeFromMetadataName(method.Name, out isChecked, context.Settings);\n\t\t\tif (bop != null && arguments.Length == 2)\n\t\t\t{\n\t\t\t\tinvocationExpression.Arguments.Clear(); // detach arguments from invocationExpression\n\t\t\t\tif (isChecked)\n\t\t\t\t{\n\t\t\t\t\tinvocationExpression.AddAnnotation(AddCheckedBlocks.CheckedAnnotation);\n\t\t\t\t}\n\t\t\t\telse if (HasCheckedEquivalent(method))\n\t\t\t\t{\n\t\t\t\t\tinvocationExpression.AddAnnotation(AddCheckedBlocks.UncheckedAnnotation);\n\t\t\t\t}\n\t\t\t\tinvocationExpression.ReplaceWith(\n\t\t\t\t\tnew BinaryOperatorExpression(\n\t\t\t\t\t\targuments[0].UnwrapInDirectionExpression(),\n\t\t\t\t\t\tbop.Value,\n\t\t\t\t\t\targuments[1].UnwrapInDirectionExpression()\n\t\t\t\t\t).CopyAnnotationsFrom(invocationExpression)\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tUnaryOperatorType? uop = GetUnaryOperatorTypeFromMetadataName(method.Name, out isChecked, context.Settings);\n\t\t\tif (uop != null && arguments.Length == 1)\n\t\t\t{\n\t\t\t\tif (isChecked)\n\t\t\t\t{\n\t\t\t\t\tinvocationExpression.AddAnnotation(AddCheckedBlocks.CheckedAnnotation);\n\t\t\t\t}\n\t\t\t\telse if (HasCheckedEquivalent(method))\n\t\t\t\t{\n\t\t\t\t\tinvocationExpression.AddAnnotation(AddCheckedBlocks.UncheckedAnnotation);\n\t\t\t\t}\n\t\t\t\tif (uop == UnaryOperatorType.Increment || uop == UnaryOperatorType.Decrement)\n\t\t\t\t{\n\t\t\t\t\t// `op_Increment(a)` is not equivalent to `++a`,\n\t\t\t\t\t// because it doesn't assign the incremented value to a.\n\t\t\t\t\tif (method.DeclaringType.IsKnownType(KnownTypeCode.Decimal))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Legacy csc optimizes \"d + 1m\" to \"op_Increment(d)\",\n\t\t\t\t\t\t// so reverse that optimization here:\n\t\t\t\t\t\tinvocationExpression.ReplaceWith(\n\t\t\t\t\t\t\tnew BinaryOperatorExpression(\n\t\t\t\t\t\t\t\targuments[0].UnwrapInDirectionExpression().Detach(),\n\t\t\t\t\t\t\t\t(uop == UnaryOperatorType.Increment ? BinaryOperatorType.Add : BinaryOperatorType.Subtract),\n\t\t\t\t\t\t\t\tnew PrimitiveExpression(1m)\n\t\t\t\t\t\t\t).CopyAnnotationsFrom(invocationExpression)\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\targuments[0].Remove(); // detach argument\n\t\t\t\t\tinvocationExpression.ReplaceWith(\n\t\t\t\t\t\tnew UnaryOperatorExpression(uop.Value, arguments[0].UnwrapInDirectionExpression()).CopyAnnotationsFrom(invocationExpression)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (method.Name is \"op_Explicit\" or \"op_CheckedExplicit\" && arguments.Length == 1)\n\t\t\t{\n\t\t\t\targuments[0].Remove(); // detach argument\n\t\t\t\tif (method.Name == \"op_CheckedExplicit\")\n\t\t\t\t{\n\t\t\t\t\tinvocationExpression.AddAnnotation(AddCheckedBlocks.CheckedAnnotation);\n\t\t\t\t}\n\t\t\t\telse if (HasCheckedEquivalent(method))\n\t\t\t\t{\n\t\t\t\t\tinvocationExpression.AddAnnotation(AddCheckedBlocks.UncheckedAnnotation);\n\t\t\t\t}\n\t\t\t\tinvocationExpression.ReplaceWith(\n\t\t\t\t\tnew CastExpression(context.TypeSystemAstBuilder.ConvertType(method.ReturnType), arguments[0].UnwrapInDirectionExpression())\n\t\t\t\t\t\t.CopyAnnotationsFrom(invocationExpression)\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (method.Name == \"op_True\" && arguments.Length == 1 && invocationExpression.Role == Roles.Condition)\n\t\t\t{\n\t\t\t\tinvocationExpression.ReplaceWith(arguments[0].UnwrapInDirectionExpression());\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tinternal static bool HasCheckedEquivalent(IMethod method)\n\t\t{\n\t\t\tstring name = method.Name;\n\t\t\tif (name.StartsWith(\"op_\", StringComparison.Ordinal))\n\t\t\t\tname = \"op_Checked\" + name.Substring(3);\n\t\t\treturn method.DeclaringType.GetMethods(m => m.IsOperator && m.Name == name).Any();\n\t\t}\n\n\t\tbool IsInstantiableTypeParameter(IType type)\n\t\t{\n\t\t\treturn type is ITypeParameter tp && tp.HasDefaultConstructorConstraint;\n\t\t}\n\n\t\tbool CheckArgumentsForStringConcat(Expression[] arguments)\n\t\t{\n\t\t\tif (arguments.Length < 2)\n\t\t\t\treturn false;\n\n\t\t\tif (arguments.Any(arg => arg is NamedArgumentExpression))\n\t\t\t\treturn false;\n\n\t\t\t// The evaluation order when the object.ToString() calls happen is a mess:\n\t\t\t// The C# spec says the evaluation for order for each individual string + should be:\n\t\t\t//   * evaluate left argument\n\t\t\t//   * evaluate right argument\n\t\t\t//   * call ToString() on object argument\n\t\t\t// What actually happens pre-VS2019.3:\n\t\t\t//   * evaluate all arguments in chain of + operators from left to right\n\t\t\t//   * call ToString() on all object arguments from left to right\n\t\t\t// What happens in VS2019.3:\n\t\t\t//   * for each argument in chain of + operators fom left to right:\n\t\t\t//       * evaluate argument\n\t\t\t//       * call ToString() on object argument\n\t\t\t// See https://github.com/dotnet/roslyn/issues/38641 for details.\n\t\t\t// To ensure the decompiled code's behavior matches the original IL behavior,\n\t\t\t// no matter which compiler is used to recompile it, we require that all\n\t\t\t// implicit ToString() calls except for the last are free of side effects.\n\t\t\tforeach (var arg in arguments.SkipLast(1))\n\t\t\t{\n\t\t\t\tif (!ToStringIsKnownEffectFree(arg.GetResolveResult().Type))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tforeach (var arg in arguments)\n\t\t\t{\n\t\t\t\tvar rr = arg.GetResolveResult();\n\t\t\t\tif (rr is InvocationResolveResult irr && IsStringConcat(irr.Member))\n\t\t\t\t{\n\t\t\t\t\t// Roslyn + mcs also flatten nested string.Concat() invocations within a operator+ use,\n\t\t\t\t\t// which causes it to use the incorrect evaluation order despite the code using an\n\t\t\t\t\t// explicit string.Concat() call.\n\t\t\t\t\t// This problem is avoided if the outer call remains string.Concat() as well.\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (rr.Type.IsByRefLike)\n\t\t\t\t{\n\t\t\t\t\t// ref structs cannot be converted to object for use with +\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// One of the first two arguments must be string, otherwise the + operator\n\t\t\t// won't resolve to a string concatenation.\n\t\t\treturn arguments[0].GetResolveResult().Type.IsKnownType(KnownTypeCode.String)\n\t\t\t\t|| arguments[1].GetResolveResult().Type.IsKnownType(KnownTypeCode.String);\n\t\t}\n\n\t\tprivate bool IsStringConcat(IParameterizedMember member)\n\t\t{\n\t\t\treturn member is IMethod method\n\t\t\t\t&& method.Name == \"Concat\"\n\t\t\t\t&& method.DeclaringType.IsKnownType(KnownTypeCode.String);\n\t\t}\n\n\t\tstatic readonly Pattern ToStringCallPattern = new Choice {\n\t\t\t// target.ToString()\n\t\t\tnew InvocationExpression(new MemberReferenceExpression(new AnyNode(\"target\"), \"ToString\")).WithName(\"call\"),\n\t\t\t// target?.ToString()\n\t\t\tnew UnaryOperatorExpression(\n\t\t\t\tUnaryOperatorType.NullConditionalRewrap,\n\t\t\t\tnew InvocationExpression(\n\t\t\t\t\tnew MemberReferenceExpression(\n\t\t\t\t\t\tnew UnaryOperatorExpression(UnaryOperatorType.NullConditional, new AnyNode(\"target\")),\n\t\t\t\t\t\t\"ToString\")\n\t\t\t\t).WithName(\"call\")\n\t\t\t).WithName(\"nullConditional\")\n\t\t};\n\n\t\tinternal static Expression RemoveRedundantToStringInConcat(Expression expr, IMethod concatMethod, bool isLastArgument)\n\t\t{\n\t\t\tvar m = ToStringCallPattern.Match(expr);\n\t\t\tif (!m.Success)\n\t\t\t\treturn expr;\n\n\t\t\tif (!concatMethod.Parameters.All(IsStringParameter))\n\t\t\t{\n\t\t\t\t// If we're using a string.Concat() overload involving object parameters,\n\t\t\t\t// string.Concat() itself already calls ToString() so the C# compiler shouldn't\n\t\t\t\t// generate additional ToString() calls in this case.\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\tvar toStringMethod = m.Get<Expression>(\"call\").Single().GetSymbol() as IMethod;\n\t\t\tvar target = m.Get<Expression>(\"target\").Single();\n\t\t\tvar type = target.GetResolveResult().Type;\n\t\t\tif (!(isLastArgument || ToStringIsKnownEffectFree(type)))\n\t\t\t{\n\t\t\t\t// ToString() order of evaluation matters, see CheckArgumentsForStringConcat().\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\tif (type.IsReferenceType != false && !m.Has(\"nullConditional\"))\n\t\t\t{\n\t\t\t\t// ToString() might throw NullReferenceException, but the builtin operator+ doesn't.\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\tif (!ToStringIsKnownEffectFree(type) && toStringMethod != null && IL.Transforms.ILInlining.MethodRequiresCopyForReadonlyLValue(toStringMethod))\n\t\t\t{\n\t\t\t\t// ToString() on a struct may mutate the struct.\n\t\t\t\t// For operator+ the C# compiler creates a temporary copy before implicitly calling ToString(),\n\t\t\t\t// whereas an explicit ToString() call would mutate the original lvalue.\n\t\t\t\t// So we can't remove the compiler-generated ToString() call in cases where this might make a difference.\n\t\t\t\treturn expr;\n\t\t\t}\n\n\t\t\t// All checks succeeded, we can eliminate the ToString() call.\n\t\t\t// The C# compiler will generate an equivalent call if the code is recompiled.\n\t\t\treturn target;\n\n\t\t\tbool IsStringParameter(IParameter p)\n\t\t\t{\n\t\t\t\tIType ty = p.Type;\n\t\t\t\tif (p.IsParams && ty.Kind == TypeKind.Array)\n\t\t\t\t\tty = ((ArrayType)ty).ElementType;\n\t\t\t\treturn ty.IsKnownType(KnownTypeCode.String);\n\t\t\t}\n\t\t}\n\n\t\tstatic bool ToStringIsKnownEffectFree(IType type)\n\t\t{\n\t\t\ttype = NullableType.GetUnderlyingType(type);\n\t\t\tswitch (type.GetDefinition()?.KnownTypeCode)\n\t\t\t{\n\t\t\t\tcase KnownTypeCode.Boolean:\n\t\t\t\tcase KnownTypeCode.Char:\n\t\t\t\tcase KnownTypeCode.SByte:\n\t\t\t\tcase KnownTypeCode.Byte:\n\t\t\t\tcase KnownTypeCode.Int16:\n\t\t\t\tcase KnownTypeCode.UInt16:\n\t\t\t\tcase KnownTypeCode.Int32:\n\t\t\t\tcase KnownTypeCode.UInt32:\n\t\t\t\tcase KnownTypeCode.Int64:\n\t\t\t\tcase KnownTypeCode.UInt64:\n\t\t\t\tcase KnownTypeCode.Single:\n\t\t\t\tcase KnownTypeCode.Double:\n\t\t\t\tcase KnownTypeCode.Decimal:\n\t\t\t\tcase KnownTypeCode.IntPtr:\n\t\t\t\tcase KnownTypeCode.UIntPtr:\n\t\t\t\tcase KnownTypeCode.String:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tstatic BinaryOperatorType? GetBinaryOperatorTypeFromMetadataName(string name, out bool isChecked, DecompilerSettings settings)\n\t\t{\n\t\t\tisChecked = false;\n\t\t\tswitch (name)\n\t\t\t{\n\t\t\t\tcase \"op_Addition\":\n\t\t\t\t\treturn BinaryOperatorType.Add;\n\t\t\t\tcase \"op_Subtraction\":\n\t\t\t\t\treturn BinaryOperatorType.Subtract;\n\t\t\t\tcase \"op_Multiply\":\n\t\t\t\t\treturn BinaryOperatorType.Multiply;\n\t\t\t\tcase \"op_Division\":\n\t\t\t\t\treturn BinaryOperatorType.Divide;\n\t\t\t\tcase \"op_CheckedAddition\" when settings.CheckedOperators:\n\t\t\t\t\tisChecked = true;\n\t\t\t\t\treturn BinaryOperatorType.Add;\n\t\t\t\tcase \"op_CheckedSubtraction\" when settings.CheckedOperators:\n\t\t\t\t\tisChecked = true;\n\t\t\t\t\treturn BinaryOperatorType.Subtract;\n\t\t\t\tcase \"op_CheckedMultiply\" when settings.CheckedOperators:\n\t\t\t\t\tisChecked = true;\n\t\t\t\t\treturn BinaryOperatorType.Multiply;\n\t\t\t\tcase \"op_CheckedDivision\" when settings.CheckedOperators:\n\t\t\t\t\tisChecked = true;\n\t\t\t\t\treturn BinaryOperatorType.Divide;\n\t\t\t\tcase \"op_Modulus\":\n\t\t\t\t\treturn BinaryOperatorType.Modulus;\n\t\t\t\tcase \"op_BitwiseAnd\":\n\t\t\t\t\treturn BinaryOperatorType.BitwiseAnd;\n\t\t\t\tcase \"op_BitwiseOr\":\n\t\t\t\t\treturn BinaryOperatorType.BitwiseOr;\n\t\t\t\tcase \"op_ExclusiveOr\":\n\t\t\t\t\treturn BinaryOperatorType.ExclusiveOr;\n\t\t\t\tcase \"op_LeftShift\":\n\t\t\t\t\treturn BinaryOperatorType.ShiftLeft;\n\t\t\t\tcase \"op_RightShift\":\n\t\t\t\t\treturn BinaryOperatorType.ShiftRight;\n\t\t\t\tcase \"op_UnsignedRightShift\" when settings.UnsignedRightShift:\n\t\t\t\t\treturn BinaryOperatorType.UnsignedShiftRight;\n\t\t\t\tcase \"op_Equality\":\n\t\t\t\t\treturn BinaryOperatorType.Equality;\n\t\t\t\tcase \"op_Inequality\":\n\t\t\t\t\treturn BinaryOperatorType.InEquality;\n\t\t\t\tcase \"op_LessThan\":\n\t\t\t\t\treturn BinaryOperatorType.LessThan;\n\t\t\t\tcase \"op_LessThanOrEqual\":\n\t\t\t\t\treturn BinaryOperatorType.LessThanOrEqual;\n\t\t\t\tcase \"op_GreaterThan\":\n\t\t\t\t\treturn BinaryOperatorType.GreaterThan;\n\t\t\t\tcase \"op_GreaterThanOrEqual\":\n\t\t\t\t\treturn BinaryOperatorType.GreaterThanOrEqual;\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tstatic UnaryOperatorType? GetUnaryOperatorTypeFromMetadataName(string name, out bool isChecked, DecompilerSettings settings)\n\t\t{\n\t\t\tisChecked = false;\n\t\t\tswitch (name)\n\t\t\t{\n\t\t\t\tcase \"op_LogicalNot\":\n\t\t\t\t\treturn UnaryOperatorType.Not;\n\t\t\t\tcase \"op_OnesComplement\":\n\t\t\t\t\treturn UnaryOperatorType.BitNot;\n\t\t\t\tcase \"op_UnaryNegation\":\n\t\t\t\t\treturn UnaryOperatorType.Minus;\n\t\t\t\tcase \"op_CheckedUnaryNegation\" when settings.CheckedOperators:\n\t\t\t\t\tisChecked = true;\n\t\t\t\t\treturn UnaryOperatorType.Minus;\n\t\t\t\tcase \"op_UnaryPlus\":\n\t\t\t\t\treturn UnaryOperatorType.Plus;\n\t\t\t\tcase \"op_Increment\":\n\t\t\t\t\treturn UnaryOperatorType.Increment;\n\t\t\t\tcase \"op_Decrement\":\n\t\t\t\t\treturn UnaryOperatorType.Decrement;\n\t\t\t\tcase \"op_CheckedIncrement\" when settings.CheckedOperators:\n\t\t\t\t\tisChecked = true;\n\t\t\t\t\treturn UnaryOperatorType.Increment;\n\t\t\t\tcase \"op_CheckedDecrement\" when settings.CheckedOperators:\n\t\t\t\t\tisChecked = true;\n\t\t\t\t\treturn UnaryOperatorType.Decrement;\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tstatic readonly Expression getMethodOrConstructorFromHandlePattern =\n\t\t\tnew CastExpression(new Choice {\n\t\t\t\t\t new TypePattern(typeof(MethodInfo)),\n\t\t\t\t\t new TypePattern(typeof(ConstructorInfo))\n\t\t\t\t }, new InvocationExpression(new MemberReferenceExpression(new TypeReferenceExpression(new TypePattern(typeof(MethodBase)).ToType()), \"GetMethodFromHandle\"),\n\t\t\t\tnew NamedNode(\"ldtokenNode\", new MemberReferenceExpression(new LdTokenPattern(\"method\").ToExpression(), \"MethodHandle\")),\n\t\t\t\tnew OptionalNode(new MemberReferenceExpression(new TypeOfExpression(new AnyNode(\"declaringType\")), \"TypeHandle\"))\n\t\t\t));\n\n\t\tpublic override void VisitCastExpression(CastExpression castExpression)\n\t\t{\n\t\t\tbase.VisitCastExpression(castExpression);\n\t\t\t// Handle methodof\n\t\t\tMatch m = getMethodOrConstructorFromHandlePattern.Match(castExpression);\n\t\t\tif (m.Success)\n\t\t\t{\n\t\t\t\tIMethod method = m.Get<AstNode>(\"method\").Single().GetSymbol() as IMethod;\n\t\t\t\tif (m.Has(\"declaringType\") && method != null)\n\t\t\t\t{\n\t\t\t\t\tExpression newNode = new MemberReferenceExpression(new TypeReferenceExpression(m.Get<AstType>(\"declaringType\").Single().Detach()), method.Name);\n\t\t\t\t\tnewNode = new InvocationExpression(newNode, method.Parameters.Select(p => new TypeReferenceExpression(context.TypeSystemAstBuilder.ConvertType(p.Type))));\n\t\t\t\t\tm.Get<AstNode>(\"method\").Single().ReplaceWith(newNode);\n\t\t\t\t}\n\t\t\t\tcastExpression.ReplaceWith(m.Get<AstNode>(\"ldtokenNode\").Single().CopyAnnotationsFrom(castExpression));\n\t\t\t}\n\t\t}\n\n\t\tvoid IAstTransform.Run(AstNode rootNode, TransformContext context)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tthis.context = context;\n\t\t\t\trootNode.AcceptVisitor(this);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tthis.context = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/TransformContext.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Immutable;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\t/// <summary>\n\t/// Parameters for IAstTransform.\n\t/// </summary>\n\tpublic class TransformContext\n\t{\n\t\tpublic readonly IDecompilerTypeSystem TypeSystem;\n\t\tpublic readonly CancellationToken CancellationToken;\n\t\tpublic readonly TypeSystemAstBuilder TypeSystemAstBuilder;\n\t\tpublic readonly DecompilerSettings Settings;\n\t\tinternal readonly DecompileRun DecompileRun;\n\n\t\treadonly ITypeResolveContext decompilationContext;\n\n\t\t/// <summary>\n\t\t/// Returns the current member; or null if a whole type or module is being decompiled.\n\t\t/// </summary>\n\t\tpublic IMember CurrentMember => decompilationContext.CurrentMember;\n\n\t\t/// <summary>\n\t\t/// Returns the current type definition; or null if a module is being decompiled.\n\t\t/// </summary>\n\t\tpublic ITypeDefinition CurrentTypeDefinition => decompilationContext.CurrentTypeDefinition;\n\n\t\t/// <summary>\n\t\t/// Returns the module that is being decompiled.\n\t\t/// </summary>\n\t\tpublic IModule CurrentModule => decompilationContext.CurrentModule;\n\n\t\t/// <summary>\n\t\t/// Returns the max possible set of namespaces that will be used during decompilation.\n\t\t/// </summary>\n\t\tpublic IImmutableSet<string> RequiredNamespacesSuperset => DecompileRun.Namespaces.ToImmutableHashSet();\n\n\t\tinternal TransformContext(IDecompilerTypeSystem typeSystem, DecompileRun decompileRun, ITypeResolveContext decompilationContext, TypeSystemAstBuilder typeSystemAstBuilder)\n\t\t{\n\t\t\tthis.TypeSystem = typeSystem;\n\t\t\tthis.DecompileRun = decompileRun;\n\t\t\tthis.decompilationContext = decompilationContext;\n\t\t\tthis.TypeSystemAstBuilder = typeSystemAstBuilder;\n\t\t\tthis.CancellationToken = decompileRun.CancellationToken;\n\t\t\tthis.Settings = decompileRun.Settings;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/Transforms/TransformFieldAndConstructorInitializers.cs",
    "content": "// Copyright (c) 2025 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.CSharp.Resolver;\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nusing SRM = System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.CSharp.Transforms\n{\n\t/// <summary>\n\t/// This transform moves field initializers at the start of constructors to their respective field declarations\n\t/// and transforms this-/base-ctor calls in constructors to constructor initializers.\n\t/// </summary>\n\tpublic class TransformFieldAndConstructorInitializers : IAstTransform\n\t{\n\t\t/// <summary>\n\t\t/// Pattern for reference types:\n\t\t/// this..ctor(...);\n\t\t/// </summary>\n\t\tinternal static readonly AstNode ThisCallClassPattern = new ExpressionStatement(\n\t\t\tnew NamedNode(\"invocation\", new InvocationExpression(\n\t\t\t\tnew MemberReferenceExpression(\n\t\t\t\t\tnew Choice {\n\t\t\t\t\t\tnew NamedNode(\"target\", new ThisReferenceExpression()),\n\t\t\t\t\t\tnew NamedNode(\"target\", new BaseReferenceExpression()),\n\t\t\t\t\t\tnew CastExpression {\n\t\t\t\t\t\t\tType = new AnyNode(),\n\t\t\t\t\t\t\tExpression = new Choice {\n\t\t\t\t\t\t\tnew NamedNode(\"target\", new ThisReferenceExpression()),\n\t\t\t\t\t\t\t\tnew NamedNode(\"target\", new BaseReferenceExpression()),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}, \".ctor\"),\n\t\t\t\tnew Repeat(new AnyNode()))\n\t\t\t)\n\t\t);\n\n\t\t/// <summary>\n\t\t/// Pattern for value types:\n\t\t/// this = new TSelf(...);\n\t\t/// </summary>\n\t\tinternal static readonly AstNode ThisCallStructPattern = new ExpressionStatement(\n\t\t\t\tnew AssignmentExpression(\n\t\t\t\t\tnew NamedNode(\"target\", new ThisReferenceExpression()),\n\t\t\t\t\tnew NamedNode(\"invocation\", new ObjectCreateExpression(new AnyNode(), new Repeat(new AnyNode())))\n\t\t\t\t)\n\t\t);\n\n\t\tinternal static bool IsGeneratedPrimaryConstructorBackingField(IField field)\n\t\t{\n\t\t\tvar name = field.Name;\n\t\t\treturn name.StartsWith(\"<\", StringComparison.Ordinal)\n\t\t\t\t&& name.EndsWith(\">P\", StringComparison.Ordinal)\n\t\t\t\t&& field.IsCompilerGenerated();\n\t\t}\n\n\t\tenum InitializerKind\n\t\t{\n\t\t\tStatic,\n\t\t\tInstance,\n\t\t\tPrimary\n\t\t}\n\n\t\tclass InitializerSequence\n\t\t{\n\t\t\tstatic readonly ExpressionStatement memberInitializerPattern = new() {\n\t\t\t\tExpression = new AssignmentExpression(\n\t\t\t\t\tnew Choice {\n\t\t\t\t\t\t\tnew NamedNode(\"fieldAccess\", new MemberReferenceExpression {\n\t\t\t\t\t\t\t\tTarget = new ThisReferenceExpression(),\n\t\t\t\t\t\t\t\tMemberName = Pattern.AnyString\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tnew NamedNode(\"fieldAccess\", new IdentifierExpression(Pattern.AnyString))\n\t\t\t\t\t},\n\t\t\t\t\tnew AnyNode(\"initializer\")\n\t\t\t\t)\n\t\t\t};\n\n\t\t\t[AllowNull]\n\t\t\tpublic List<(Statement Statement, IMember Member, Expression Initializer, bool DependsOnConstructorBody)> Statements;\n\n\t\t\tpublic Dictionary<Statement, List<Statement>>? StatementToOtherCtorsMap;\n\n\t\t\tpublic bool HasDuplicateAssignments { get; private set; }\n\t\t\tpublic bool IsUnsafe { get; private set; }\n\t\t\tpublic bool CoversFullBody { get; private set; }\n\n\t\t\tpublic static InitializerSequence? Analyze(ConstructorInitializerAnalyzer context, ConstructorDeclaration ctor, IMethod ctorMethod)\n\t\t\t{\n\t\t\t\tvar sequence = new InitializerSequence() {\n\t\t\t\t\tStatements = [],\n\t\t\t\t\tIsUnsafe = ctor.HasModifier(Modifiers.Unsafe)\n\t\t\t\t};\n\t\t\t\tvar initializedMembers = new HashSet<IMember>();\n\t\t\t\tvar function = ctor.Annotation<ILFunction>();\n\t\t\t\tvar isStruct = ctorMethod.DeclaringType.Kind == TypeKind.Struct;\n\n\t\t\t\tbool onlyMoveConstants = !context.context.Settings.AlwaysMoveInitializer\n\t\t\t\t\t&& !context.IsBeforeFieldInit && ctorMethod.IsStatic;\n\t\t\t\tbool skippedStmts = false;\n\n\t\t\t\tStatement? stmt;\n\t\t\t\tfor (stmt = ctor.Body.Statements.FirstOrDefault(); stmt != null; stmt = stmt.GetNextStatement())\n\t\t\t\t{\n\t\t\t\t\tvar m = memberInitializerPattern.Match(stmt);\n\t\t\t\t\tif (!m.Success)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tvar fieldAccess = m.Get<AstNode>(\"fieldAccess\").Single();\n\t\t\t\t\tvar initializer = m.Get<Expression>(\"initializer\").Single();\n\t\t\t\t\tvar member = (fieldAccess.GetSymbol() as IMember)?.MemberDefinition;\n\t\t\t\t\tif (member == null || !CanHaveInitializer(member, context))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tif (onlyMoveConstants && member is not IField { IsConst: true })\n\t\t\t\t\t{\n\t\t\t\t\t\tskippedStmts = true;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (!initializedMembers.Add(member))\n\t\t\t\t\t\tsequence.HasDuplicateAssignments = true;\n\n\t\t\t\t\tbool dependsOnBody = false;\n\n\t\t\t\t\tforeach (var instruction in initializer.Annotations.OfType<ILInstruction>())\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var inst in instruction.Descendants)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (inst is IInstructionWithVariableOperand { Variable: var v }\n\t\t\t\t\t\t\t\t&& v.Function == function && v.Kind == VariableKind.Parameter)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdependsOnBody = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tsequence.Statements.Add((stmt, member, initializer, dependsOnBody));\n\t\t\t\t}\n\n\t\t\t\tif (!skippedStmts)\n\t\t\t\t{\n\t\t\t\t\tif (stmt == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tsequence.CoversFullBody = true;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tvar m = isStruct\n\t\t\t\t\t\t\t? ThisCallStructPattern.Match(stmt)\n\t\t\t\t\t\t\t: ThisCallClassPattern.Match(stmt);\n\t\t\t\t\t\tif (m.Success)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsequence.CoversFullBody = stmt.GetNextStatement() == null;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn sequence;\n\t\t\t}\n\n\t\t\tprivate static bool CanHaveInitializer(IMember member, ConstructorInitializerAnalyzer context)\n\t\t\t{\n\t\t\t\tif (context.MemberToDeclaringSyntaxNodeMap == null)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!context.MemberToDeclaringSyntaxNodeMap.TryGetValue(member, out var declaringSyntaxNode))\n\t\t\t\t\treturn true;\n\t\t\t\treturn declaringSyntaxNode is FieldDeclaration\n\t\t\t\t\tor PropertyDeclaration { IsAutomaticProperty: true }\n\t\t\t\t\tor EventDeclaration;\n\t\t\t}\n\n\t\t\tpublic bool IsMatch(ConstructorDeclaration ctor)\n\t\t\t{\n\t\t\t\tvar stmts = ctor.Body.Statements;\n\t\t\t\tvar otherStmt = stmts.FirstOrDefault();\n\t\t\t\tforeach (var (stmt, member, initializer, _) in Statements)\n\t\t\t\t{\n\t\t\t\t\tvar m = memberInitializerPattern.Match(otherStmt);\n\t\t\t\t\tif (!m.Success)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tDebug.Assert(otherStmt != null); // because m.Success\n\t\t\t\t\tvar fieldAccess = m.Get<AstNode>(\"fieldAccess\").Single();\n\t\t\t\t\tvar otherMember = (fieldAccess.GetSymbol() as IMember)?.MemberDefinition;\n\t\t\t\t\tif (!member.Equals(otherMember))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tvar otherInitializer = m.Get<Expression>(\"initializer\").Single();\n\t\t\t\t\tif (!initializer.IsMatch(otherInitializer))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tStatementToOtherCtorsMap ??= [];\n\t\t\t\t\tif (!StatementToOtherCtorsMap.TryGetValue(stmt, out var list))\n\t\t\t\t\t{\n\t\t\t\t\t\tlist = [];\n\t\t\t\t\t\tStatementToOtherCtorsMap[stmt] = list;\n\t\t\t\t\t}\n\t\t\t\t\tlist.Add(otherStmt);\n\t\t\t\t\totherStmt = otherStmt.GetNextStatement();\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tclass ConstructorInitializerAnalyzer\n\t\t{\n\t\t\tinternal readonly TransformContext context;\n\t\t\tpublic readonly ITypeDefinition TypeDefinition;\n\t\t\tpublic readonly TypeDeclaration? TypeDeclaration;\n\t\t\tpublic readonly RecordDecompiler? RecordDecompiler;\n\n\t\t\t[AllowNull]\n\t\t\tpublic Dictionary<IMember, EntityDeclaration> MemberToDeclaringSyntaxNodeMap;\n\n\t\t\tpublic Dictionary<IParameter, (IProperty?, IField)>? PrimaryConstructorParameterToBackingStoreMap;\n\t\t\tpublic Dictionary<IField, ILVariable>? BackingFieldToPrimaryConstructorParameterVariableMap;\n\n\t\t\tpublic InitializerSequence? InstanceInitializers;\n\t\t\tpublic InitializerSequence? StaticInitializers;\n\t\t\tpublic InitializerSequence? PrimaryConstructorInitializers;\n\n\t\t\tpublic IMethod? StaticConstructor;\n\t\t\tpublic ConstructorDeclaration? StaticConstructorDecl;\n\n\t\t\tpublic IMethod? RecordCopyConstructor;\n\t\t\tpublic ConstructorDeclaration? RecordCopyConstructorDecl;\n\n\t\t\tpublic IMethod? PrimaryConstructor;\n\t\t\tpublic ConstructorDeclaration? PrimaryConstructorDecl;\n\n\t\t\t[AllowNull]\n\t\t\tpublic ConstructorDeclaration[] InstanceConstructors;\n\n\t\t\tpublic bool IsBeforeFieldInit {\n\t\t\t\tget {\n\t\t\t\t\tif (TypeDefinition?.MetadataToken.IsNil != false)\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tvar metadata = context.TypeSystem.MainModule.MetadataFile.Metadata;\n\t\t\t\t\tvar td = metadata.GetTypeDefinition((SRM.TypeDefinitionHandle)TypeDefinition.MetadataToken);\n\n\t\t\t\t\treturn td.HasFlag(TypeAttributes.BeforeFieldInit);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic ConstructorInitializerAnalyzer(TransformContext context, ITypeDefinition typeDefinition, TypeDeclaration? typeDeclaration)\n\t\t\t{\n\t\t\t\tthis.context = context;\n\t\t\t\tTypeDefinition = typeDefinition;\n\t\t\t\tTypeDeclaration = typeDeclaration;\n\t\t\t\tRecordDecompiler = context.DecompileRun.RecordDecompilers.TryGetValue(typeDefinition, out var record) ? record : null;\n\t\t\t}\n\n\t\t\tpublic bool Analyze(IEnumerable<AstNode> members)\n\t\t\t{\n\t\t\t\tMemberToDeclaringSyntaxNodeMap = members\n\t\t\t\t\t.Select(m => (symbol: m.GetSymbol(), entity: (EntityDeclaration)m))\n\t\t\t\t\t.Where(_ => _.symbol is IMember)\n\t\t\t\t\t.ToDictionary(_ => (IMember)_.symbol, _ => _.entity);\n\n\t\t\t\tList<ConstructorDeclaration> constructorsNotChainedWithThis = [];\n\t\t\t\tList<ConstructorDeclaration> allCtors = [];\n\n\t\t\t\t// we use the row number of the first method in the metadata table as a heuristic\n\t\t\t\t// to determine the primary constructor in non-record structs.\n\t\t\t\t// This is not completely reliable, but works.\n\t\t\t\tvar metadata = context.TypeSystem.MainModule.metadata;\n\t\t\t\tvar typeDef = metadata.GetTypeDefinition((SRM.TypeDefinitionHandle)TypeDefinition.MetadataToken);\n\t\t\t\tvar firstMethodRowNumber = MetadataTokens.GetRowNumber(typeDef.GetMethods().FirstOrDefault());\n\n\t\t\t\tforeach (var ctor in members.OfType<ConstructorDeclaration>())\n\t\t\t\t{\n\t\t\t\t\tvar ctorMethod = (IMethod)ctor.GetSymbol();\n\t\t\t\t\tDebug.Assert(ctorMethod.IsConstructor);\n\t\t\t\t\tDebug.Assert(ctorMethod.MetadataToken.IsNil == false);\n\n\t\t\t\t\tint rowNumber = MetadataTokens.GetRowNumber(ctorMethod.MetadataToken);\n\t\t\t\t\tDebug.Assert(rowNumber > 0);\n\n\t\t\t\t\tif (ctorMethod.Equals(RecordDecompiler?.PrimaryConstructor))\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(PrimaryConstructorDecl == null);\n\t\t\t\t\t\tPrimaryConstructor = ctorMethod;\n\t\t\t\t\t\tPrimaryConstructorDecl = ctor;\n\t\t\t\t\t\tPrimaryConstructorParameterToBackingStoreMap = RecordDecompiler.GetParameterToBackingStoreMap();\n\t\t\t\t\t\tconstructorsNotChainedWithThis.Add(ctor);\n\t\t\t\t\t}\n\t\t\t\t\telse if (ctorMethod.IsStatic)\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(StaticConstructorDecl == null);\n\t\t\t\t\t\tStaticConstructor = ctorMethod;\n\t\t\t\t\t\tStaticConstructorDecl = ctor;\n\t\t\t\t\t}\n\t\t\t\t\telse if (RecordDecompiler != null && RecordDecompiler.IsCopyConstructor(ctorMethod))\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(RecordCopyConstructorDecl == null);\n\t\t\t\t\t\tRecordCopyConstructor = ctorMethod;\n\t\t\t\t\t\tRecordCopyConstructorDecl = ctor;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// find this-ctor call\n\t\t\t\t\t\tvar stmt = ctor.Body.Statements.FirstOrDefault();\n\t\t\t\t\t\tvar m = ctorMethod.DeclaringType.Kind == TypeKind.Struct\n\t\t\t\t\t\t\t? ThisCallStructPattern.Match(stmt)\n\t\t\t\t\t\t\t: ThisCallClassPattern.Match(stmt);\n\n\t\t\t\t\t\tallCtors.Add(ctor);\n\n\t\t\t\t\t\tif (m.Success && m.Get<Expression>(\"target\").Single() is ThisReferenceExpression)\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\tconstructorsNotChainedWithThis.Add(ctor);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (context.Settings.UsePrimaryConstructorSyntaxForNonRecordTypes\n\t\t\t\t\t&& RecordDecompiler == null && constructorsNotChainedWithThis.Count == 1)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(PrimaryConstructor == null);\n\n\t\t\t\t\t// this constructor could be converted to a primary constructor\n\t\t\t\t\tvar ctor = constructorsNotChainedWithThis[0];\n\t\t\t\t\tvar ctorMethod = (IMethod)constructorsNotChainedWithThis[0].GetSymbol();\n\n\t\t\t\t\tvar initializer = InitializerSequence.Analyze(this, ctor, ctorMethod);\n\n\t\t\t\t\tif (initializer is { CoversFullBody: true, HasDuplicateAssignments: false, Statements.Count: > 0 })\n\t\t\t\t\t{\n\t\t\t\t\t\tbool transformToPrimaryConstructor = MetadataTokens.GetRowNumber(ctorMethod.MetadataToken) == firstMethodRowNumber;\n\n\t\t\t\t\t\tif (ctorMethod.Parameters.Count == 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttransformToPrimaryConstructor = false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tforeach (var (stmt, member, expr, dependsOnBody) in initializer.Statements)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (member is IField f && IsGeneratedPrimaryConstructorBackingField(f))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvar variable = expr.Annotation<ILVariableResolveResult>()?.Variable;\n\t\t\t\t\t\t\t\tif (variable is { Kind: VariableKind.Parameter, Index: >= 0 and int index })\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tvar p = ctorMethod.Parameters[index];\n\t\t\t\t\t\t\t\t\tPrimaryConstructorParameterToBackingStoreMap ??= [];\n\t\t\t\t\t\t\t\t\tBackingFieldToPrimaryConstructorParameterVariableMap ??= [];\n\t\t\t\t\t\t\t\t\tPrimaryConstructorParameterToBackingStoreMap[p] = (null, f);\n\t\t\t\t\t\t\t\t\tBackingFieldToPrimaryConstructorParameterVariableMap[f] = variable;\n\t\t\t\t\t\t\t\t\ttransformToPrimaryConstructor = true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (context.Settings.ShowXmlDocumentation && context.DecompileRun.DocumentationProvider is { } provider)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar classDoc = provider.GetDocumentation(ctorMethod.DeclaringTypeDefinition);\n\t\t\t\t\t\t\tvar ctorDoc = provider.GetDocumentation(ctorMethod);\n\n\t\t\t\t\t\t\tif (ctorDoc != null && ctorDoc != classDoc)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttransformToPrimaryConstructor = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (transformToPrimaryConstructor)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPrimaryConstructorParameterToBackingStoreMap ??= [];\n\t\t\t\t\t\t\tPrimaryConstructorDecl = ctor;\n\t\t\t\t\t\t\tPrimaryConstructor = ctorMethod;\n\t\t\t\t\t\t\tPrimaryConstructorInitializers = initializer;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (StaticConstructor != null)\n\t\t\t\t{\n\t\t\t\t\tStaticInitializers = InitializerSequence.Analyze(this, StaticConstructorDecl!, StaticConstructor);\n\t\t\t\t}\n\n\t\t\t\tif (PrimaryConstructor != null)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(PrimaryConstructorDecl != null);\n\n\t\t\t\t\t// if there exists a primary constructor, all other constructors must call it\n\t\t\t\t\tDebug.Assert(constructorsNotChainedWithThis.Count == 1);\n\n\t\t\t\t\tPrimaryConstructorInitializers ??= InitializerSequence.Analyze(this, PrimaryConstructorDecl, PrimaryConstructor);\n\t\t\t\t}\n\n\t\t\t\tif (constructorsNotChainedWithThis.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tif (TypeDefinition?.Kind != TypeKind.Struct || (context.Settings.StructDefaultConstructorsAndFieldInitializers && !TypeDefinition.IsRecord))\n\t\t\t\t\t{\n\t\t\t\t\t\tbool isPrimaryCtor = constructorsNotChainedWithThis[0] == PrimaryConstructorDecl;\n\t\t\t\t\t\tvar sequence = isPrimaryCtor\n\t\t\t\t\t\t\t? PrimaryConstructorInitializers\n\t\t\t\t\t\t\t: InitializerSequence.Analyze(this, constructorsNotChainedWithThis[0], (IMethod)constructorsNotChainedWithThis[0].GetSymbol());\n\n\t\t\t\t\t\tif (sequence == null)\n\t\t\t\t\t\t\treturn false;\n\n\t\t\t\t\t\tfor (int i = 1; i < constructorsNotChainedWithThis.Count; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!sequence.IsMatch(constructorsNotChainedWithThis[i]))\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!isPrimaryCtor)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!sequence.Statements.Any(s => s.DependsOnConstructorBody))\n\t\t\t\t\t\t\t\tInstanceInitializers = sequence;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tInstanceConstructors = allCtors.ToArray();\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tpublic bool MoveConstructorInitializer(ConstructorDeclaration constructorDeclaration, IMethod ctorMethod)\n\t\t\t{\n\t\t\t\tStatement stmt = constructorDeclaration.Body.Statements.FirstOrDefault()!;\n\t\t\t\tvar isValueType = ctorMethod.DeclaringType.Kind == TypeKind.Struct;\n\n\t\t\t\t// value types may omit the constructor initializer completely\n\t\t\t\tif (stmt == null && isValueType)\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tvar m = isValueType\n\t\t\t\t\t? ThisCallStructPattern.Match(stmt)\n\t\t\t\t\t: ThisCallClassPattern.Match(stmt);\n\n\t\t\t\tif (!m.Success)\n\t\t\t\t\treturn isValueType;\n\n\t\t\t\tDebug.Assert(stmt != null); // because m.Success\n\n\t\t\t\tAstNode invocation = m.Get<AstNode>(\"invocation\").Single();\n\t\t\t\tif (invocation.GetSymbol() is not IMethod { IsConstructor: true } ctor)\n\t\t\t\t\treturn false;\n\n\t\t\t\tConstructorInitializerType type = ctor.DeclaringTypeDefinition == ctorMethod.DeclaringTypeDefinition\n\t\t\t\t\t? ConstructorInitializerType.This\n\t\t\t\t\t: ConstructorInitializerType.Base;\n\n\t\t\t\tvar ci = new ConstructorInitializer { ConstructorInitializerType = type };\n\n\t\t\t\t// Move arguments from invocation to initializer:\n\t\t\t\tinvocation.GetChildrenByRole(Roles.Argument).MoveTo(ci.Arguments);\n\t\t\t\t// Add the initializer: (unless it is the default 'base()')\n\t\t\t\tif (!(ci.ConstructorInitializerType == ConstructorInitializerType.Base && ci.Arguments.Count == 0))\n\t\t\t\t\tconstructorDeclaration.Initializer = ci.CopyAnnotationsFrom(invocation);\n\n\t\t\t\t// Remove the statement\n\t\t\t\tstmt.Remove();\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tpublic bool MoveFieldInitializersToDeclarations(InitializerSequence sequence, InitializerKind kind)\n\t\t\t{\n\t\t\t\tforeach (var (stmt, member, initializer, dependsOnBody) in sequence.Statements)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(!dependsOnBody || kind is InitializerKind.Primary);\n\n\t\t\t\t\tif (!MemberToDeclaringSyntaxNodeMap.TryGetValue(member, out var declaringSyntaxNode))\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(kind is InitializerKind.Primary);\n\t\t\t\t\t\tstmt.Remove();\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tVariableInitializer v;\n\t\t\t\t\tswitch (declaringSyntaxNode)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase FieldDeclaration fd:\n\t\t\t\t\t\t\tv = fd.Variables.Single();\n\t\t\t\t\t\t\tif (v.Initializer.IsNull)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tv.Initializer = initializer.Detach();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (kind == InitializerKind.Static)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// decimal constants already have an initializer in the AST at this point,\n\t\t\t\t\t\t\t\t// because it was added in CSharpDecompiler.DoDecompile(IField, ...)\n\t\t\t\t\t\t\t\tvar constant = v.Initializer.GetResolveResult();\n\t\t\t\t\t\t\t\tvar expression = initializer.GetResolveResult();\n\t\t\t\t\t\t\t\tif (constant.IsCompileTimeConstant && TryEvaluateDecimalConstant(expression, out decimal value))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t// decimal values do not match, skip transformation?\n\t\t\t\t\t\t\t\t\tif (!value.Equals(constant.ConstantValue))\n\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t// already has an initializer - do not modify\n\t\t\t\t\t\t\t\t\tDebug.Fail(\"Field already has an initializer\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// already has an initializer - do not modify\n\t\t\t\t\t\t\t\tDebug.Fail(\"Field already has an initializer\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase PropertyDeclaration pd:\n\t\t\t\t\t\t\tDebug.Assert(pd.IsAutomaticProperty);\n\t\t\t\t\t\t\tif (pd.Initializer.IsNull)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tpd.Initializer = initializer.Detach();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// already has an initializer - do not modify\n\t\t\t\t\t\t\t\tDebug.Fail(\"Property already has an initializer\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase EventDeclaration ev:\n\t\t\t\t\t\t\tv = ev.Variables.Single();\n\t\t\t\t\t\t\tif (v.Initializer.IsNull)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tv.Initializer = initializer.Detach();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// already has an initializer - do not modify\n\t\t\t\t\t\t\t\tDebug.Fail(\"Event already has an initializer\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t// cannot move initializer\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\t// Remove the statement from all constructors\n\t\t\t\t\tstmt.Remove();\n\n\t\t\t\t\tif (sequence.StatementToOtherCtorsMap != null &&\n\t\t\t\t\t\tsequence.StatementToOtherCtorsMap.TryGetValue(stmt, out var otherStmts))\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var otherStmt in otherStmts)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\totherStmt.Remove();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (sequence.IsUnsafe && IntroduceUnsafeModifier.IsUnsafe(initializer))\n\t\t\t\t\t{\n\t\t\t\t\t\tdeclaringSyntaxNode.Modifiers |= Modifiers.Unsafe;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tpublic void RemoveImplicitConstructor()\n\t\t\t{\n\t\t\t\tDebug.Assert(MemberToDeclaringSyntaxNodeMap != null);\n\t\t\t\tDebug.Assert(TypeDefinition != null);\n\n\t\t\t\t// We do not want to hide the constructor if the user explicitly selected it in the tree view.\n\t\t\t\tif (TypeDeclaration == null)\n\t\t\t\t\treturn;\n\n\t\t\t\t// Remove primary constructor body\n\t\t\t\tif (PrimaryConstructor != null)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(PrimaryConstructorDecl != null);\n\n\t\t\t\t\tthis.TypeDeclaration.HasPrimaryConstructor = PrimaryConstructor.Parameters.Any()\n\t\t\t\t\t\t|| !PrimaryConstructorDecl.Initializer.IsNull\n\t\t\t\t\t\t|| TypeDefinition.Kind == TypeKind.Struct;\n\n\t\t\t\t\t// HACK: because our current AST model doesn't allow specifying an explicit order of roles,\n\t\t\t\t\t// we have to explicitly insert the primary constructor parameters,\n\t\t\t\t\t// MoveTo would just append the parameters to the list of children\n\t\t\t\t\tif (PrimaryConstructorDecl.Parameters.Count > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar insertionPoint = (AstNode?)this.TypeDeclaration.TypeParameters.LastOrDefault() ?? this.TypeDeclaration.NameToken;\n\t\t\t\t\t\tforeach (var param in PrimaryConstructorDecl.Parameters)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tparam.Remove();\n\t\t\t\t\t\t\tthis.TypeDeclaration.InsertChildAfter(insertionPoint, param, Roles.Parameter);\n\t\t\t\t\t\t\tinsertionPoint = param;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tDebug.Assert(PrimaryConstructorParameterToBackingStoreMap != null);\n\n\t\t\t\t\tforeach (var pd in this.TypeDeclaration.PrimaryConstructorParameters)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar v = pd.Annotation<ILVariableResolveResult>()?.Variable;\n\t\t\t\t\t\tDebug.Assert(v?.Index >= 0);\n\t\t\t\t\t\tvar p = PrimaryConstructor.Parameters[v.Index.Value];\n\n\t\t\t\t\t\tif (!PrimaryConstructorParameterToBackingStoreMap.TryGetValue(p, out var backingStore))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// no backing store, constructor parameter was left unassigned or\n\t\t\t\t\t\t\t// assigned to a different member in a sub-expression:\n\t\t\t\t\t\t\t// private int someField = param + param2;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar (prop, field) = backingStore;\n\n\t\t\t\t\t\tif (prop != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar attributes = prop?.GetAttributes().Select(attr => context.TypeSystemAstBuilder.ConvertAttribute(attr)).ToArray();\n\t\t\t\t\t\t\tif (attributes?.Length > 0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvar section = new AttributeSection {\n\t\t\t\t\t\t\t\t\tAttributeTarget = \"property\"\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tsection.Attributes.AddRange(attributes);\n\t\t\t\t\t\t\t\tpd.Attributes.Add(section);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (field != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar attributes = field.GetAttributes()\n\t\t\t\t\t\t\t\t.Where(a => !PatternStatementTransform.attributeTypesToRemoveFromAutoProperties.Contains(a.AttributeType.FullName))\n\t\t\t\t\t\t\t\t.Select(attr => context.TypeSystemAstBuilder.ConvertAttribute(attr)).ToArray();\n\t\t\t\t\t\t\tif (attributes.Length > 0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvar section = new AttributeSection {\n\t\t\t\t\t\t\t\t\tAttributeTarget = \"field\"\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tsection.Attributes.AddRange(attributes);\n\t\t\t\t\t\t\t\tpd.Attributes.Add(section);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (PrimaryConstructorDecl.HasModifier(Modifiers.Unsafe))\n\t\t\t\t\t{\n\t\t\t\t\t\tthis.TypeDeclaration.Modifiers |= Modifiers.Unsafe;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!PrimaryConstructorDecl.Initializer.IsNull && TypeDeclaration is { BaseTypes.Count: > 0 })\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(PrimaryConstructorDecl.Initializer is { ConstructorInitializerType: ConstructorInitializerType.Base });\n\n\t\t\t\t\t\tvar baseType = TypeDeclaration.BaseTypes.First();\n\t\t\t\t\t\tvar newBaseType = new InvocationAstType();\n\t\t\t\t\t\tbaseType.ReplaceWith(newBaseType);\n\t\t\t\t\t\tnewBaseType.BaseType = baseType;\n\t\t\t\t\t\tPrimaryConstructorDecl.Initializer.GetChildrenByRole(Roles.Argument).MoveTo(newBaseType.Arguments);\n\t\t\t\t\t}\n\n\t\t\t\t\tPrimaryConstructorDecl.Remove();\n\t\t\t\t}\n\n\t\t\t\t// Remove static constructor\n\t\t\t\tif (StaticConstructor != null)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(StaticConstructorDecl != null);\n\n\t\t\t\t\tif (IsBeforeFieldInit && StaticConstructorDecl.Body.Statements.Count == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tStaticConstructorDecl.Remove();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// More than one constructor - do not remove anything\n\t\t\t\tif (InstanceConstructors.Length != 1)\n\t\t\t\t\treturn;\n\n\t\t\t\tvar ctor = InstanceConstructors[0];\n\t\t\t\tvar ctorMethod = (IMethod)ctor.GetSymbol();\n\n\t\t\t\tif (TypeDefinition.Kind == TypeKind.Struct && ctorMethod.Parameters.Count == 0 && InstanceInitializers != null)\n\t\t\t\t{\n\t\t\t\t\t// struct constructor with initializers is not optional\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// dynamically create a pattern of an empty ctor\n\t\t\t\tConstructorDeclaration emptyCtorPattern = new ConstructorDeclaration();\n\t\t\t\temptyCtorPattern.Modifiers = TypeDefinition.IsAbstract ? Modifiers.Protected : Modifiers.Public;\n\t\t\t\tif (ctor.HasModifier(Modifiers.Unsafe))\n\t\t\t\t\temptyCtorPattern.Modifiers |= Modifiers.Unsafe;\n\t\t\t\temptyCtorPattern.Body = new BlockStatement();\n\n\t\t\t\tif (emptyCtorPattern.IsMatch(ctor))\n\t\t\t\t{\n\t\t\t\t\tbool retainBecauseOfDocumentation = context.Settings.ShowXmlDocumentation\n\t\t\t\t\t\t&& context.DecompileRun.DocumentationProvider?.GetDocumentation(ctorMethod) != null;\n\t\t\t\t\tif (!retainBecauseOfDocumentation)\n\t\t\t\t\t\tctor.Remove();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/// <summary>\n\t\t\t/// Evaluates a call to the decimal-ctor.\n\t\t\t/// </summary>\n\t\t\tprivate static bool TryEvaluateDecimalConstant(Semantics.ResolveResult expression, out decimal value)\n\t\t\t{\n\t\t\t\tvalue = 0;\n\t\t\t\tif (!expression.Type.IsKnownType(KnownTypeCode.Decimal))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tswitch (expression)\n\t\t\t\t{\n\t\t\t\t\tcase CSharpInvocationResolveResult rr:\n\t\t\t\t\t\tif (!(rr.GetSymbol() is IMethod { SymbolKind: SymbolKind.Constructor } ctor))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tvar args = rr.GetArgumentsForCall();\n\t\t\t\t\t\tif (args.Count == 1)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tswitch (args[0].ConstantValue)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcase double d:\n\t\t\t\t\t\t\t\t\tvalue = new decimal(d);\n\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\tcase float f:\n\t\t\t\t\t\t\t\t\tvalue = new decimal(f);\n\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\tcase long l:\n\t\t\t\t\t\t\t\t\tvalue = new decimal(l);\n\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\tcase int i:\n\t\t\t\t\t\t\t\t\tvalue = new decimal(i);\n\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\tcase ulong ul:\n\t\t\t\t\t\t\t\t\tvalue = new decimal(ul);\n\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\tcase uint ui:\n\t\t\t\t\t\t\t\t\tvalue = new decimal(ui);\n\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\tcase int[] bits when bits.Length == 4 && (bits[3] & 0x7F00FFFF) == 0 && (bits[3] & 0xFF000000) <= 0x1C000000:\n\t\t\t\t\t\t\t\t\tvalue = new decimal(bits);\n\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (args.Count == 5 &&\n\t\t\t\t\t\t\targs[0].ConstantValue is int lo &&\n\t\t\t\t\t\t\targs[1].ConstantValue is int mid &&\n\t\t\t\t\t\t\targs[2].ConstantValue is int hi &&\n\t\t\t\t\t\t\targs[3].ConstantValue is bool isNegative &&\n\t\t\t\t\t\t\targs[4].ConstantValue is byte scale)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue = new decimal(lo, mid, hi, isNegative, scale);\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif (expression.ConstantValue is decimal v)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue = v;\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t[AllowNull]\n\t\tTransformContext context;\n\n\t\tpublic void Run(AstNode node, TransformContext context)\n\t\t{\n\t\t\tthis.context = context;\n\n\t\t\tif (context.CurrentTypeDefinition != null)\n\t\t\t{\n\t\t\t\tTransformDeclaration(context.CurrentTypeDefinition, node, node.Children.OfType<EntityDeclaration>());\n\t\t\t}\n\n\t\t\tforeach (var typeDeclaration in node.Descendants.OfType<TypeDeclaration>())\n\t\t\t{\n\t\t\t\tvar currentTypeDefinition = (ITypeDefinition)typeDeclaration.GetSymbol();\n\t\t\t\tTransformDeclaration(currentTypeDefinition, typeDeclaration, typeDeclaration.Members);\n\t\t\t}\n\t\t}\n\n\t\tprivate bool TransformDeclaration(ITypeDefinition currentTypeDefinition, AstNode node, IEnumerable<EntityDeclaration> members)\n\t\t{\n\t\t\tvar analyzer = new ConstructorInitializerAnalyzer(context, currentTypeDefinition, node as TypeDeclaration);\n\n\t\t\tif (!analyzer.Analyze(members))\n\t\t\t\treturn false;\n\n\t\t\tif (analyzer.PrimaryConstructorInitializers is { HasDuplicateAssignments: false })\n\t\t\t{\n\t\t\t\tanalyzer.MoveFieldInitializersToDeclarations(analyzer.PrimaryConstructorInitializers, InitializerKind.Primary);\n\t\t\t}\n\t\t\telse if (analyzer.InstanceInitializers is { HasDuplicateAssignments: false })\n\t\t\t{\n\t\t\t\tanalyzer.MoveFieldInitializersToDeclarations(analyzer.InstanceInitializers, InitializerKind.Instance);\n\t\t\t}\n\n\t\t\tif (analyzer.StaticInitializers is { HasDuplicateAssignments: false })\n\t\t\t{\n\t\t\t\tanalyzer.MoveFieldInitializersToDeclarations(analyzer.StaticInitializers, InitializerKind.Static);\n\t\t\t}\n\n\t\t\tforeach (var constructorDeclaration in members.OfType<ConstructorDeclaration>())\n\t\t\t{\n\t\t\t\tanalyzer.MoveConstructorInitializer(constructorDeclaration, (IMethod)constructorDeclaration.GetSymbol());\n\t\t\t}\n\n\t\t\tanalyzer.RemoveImplicitConstructor();\n\n\t\t\tif (analyzer.BackingFieldToPrimaryConstructorParameterVariableMap == null)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tforeach (Identifier identifier in node.Descendants.OfType<Identifier>())\n\t\t\t{\n\t\t\t\tif (identifier.Parent?.GetSymbol() is not IField field)\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!analyzer.BackingFieldToPrimaryConstructorParameterVariableMap.TryGetValue((IField)field.MemberDefinition, out var v))\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tidentifier.Parent.RemoveAnnotations<MemberResolveResult>();\n\t\t\t\tidentifier.Parent.AddAnnotation(new ILVariableResolveResult(v));\n\t\t\t\tidentifier.ReplaceWith(Identifier.Create(v.Name));\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.CSharp.Transforms;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.CSharp\n{\n\t/// <summary>\n\t/// Helper struct so that the compiler can ensure we don't forget both the ILInstruction annotation and the ResolveResult annotation.\n\t/// Use '.WithILInstruction(...)' or '.WithoutILInstruction()' to create an instance of this struct.\n\t/// </summary>\n\tstruct ExpressionWithILInstruction\n\t{\n\t\tpublic readonly Expression Expression;\n\n\t\tpublic IEnumerable<ILInstruction> ILInstructions {\n\t\t\tget { return Expression.Annotations.OfType<ILInstruction>(); }\n\t\t}\n\n\t\tinternal ExpressionWithILInstruction(Expression expression)\n\t\t{\n\t\t\tDebug.Assert(expression != null);\n\t\t\tthis.Expression = expression;\n\t\t}\n\n\t\tpublic static implicit operator Expression(ExpressionWithILInstruction expression)\n\t\t{\n\t\t\treturn expression.Expression;\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Helper struct so that the compiler can ensure we don't forget both the ILInstruction annotation and the ResolveResult annotation.\n\t/// Use '.WithRR(...)'.\n\t/// </summary>\n\tstruct ExpressionWithResolveResult\n\t{\n\t\tpublic readonly Expression Expression;\n\n\t\t// Because ResolveResult is frequently accessed within the ExpressionBuilder, we put it directly\n\t\t// in this struct instead of accessing it through the list of annotations.\n\t\tpublic readonly ResolveResult ResolveResult;\n\n\t\tpublic IType Type {\n\t\t\tget { return ResolveResult.Type; }\n\t\t}\n\n\t\tinternal ExpressionWithResolveResult(Expression expression)\n\t\t{\n\t\t\tDebug.Assert(expression != null);\n\t\t\tthis.Expression = expression;\n\t\t\tthis.ResolveResult = expression.Annotation<ResolveResult>() ?? ErrorResolveResult.UnknownError;\n\t\t}\n\n\t\tinternal ExpressionWithResolveResult(Expression expression, ResolveResult resolveResult)\n\t\t{\n\t\t\tDebug.Assert(expression != null && resolveResult != null);\n\t\t\tDebug.Assert(expression.Annotation<ResolveResult>() == resolveResult);\n\t\t\tthis.Expression = expression;\n\t\t\tthis.ResolveResult = resolveResult;\n\t\t}\n\n\t\tpublic static implicit operator Expression(ExpressionWithResolveResult expression)\n\t\t{\n\t\t\treturn expression.Expression;\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Output of C# ExpressionBuilder -- a decompiled C# expression that has both a resolve result and ILInstruction annotation.\n\t/// </summary>\n\t/// <remarks>\n\t/// The resolve result is also always available as annotation on the expression, but having\n\t/// TranslatedExpression as a separate type is still useful to ensure that no case in the expression builder\n\t/// forgets to add the annotation.\n\t/// </remarks>\n\t[DebuggerDisplay(\"{Expression} : {ResolveResult}\")]\n\tstruct TranslatedExpression\n\t{\n\t\tpublic readonly Expression Expression;\n\n\t\t// Because ResolveResult is frequently accessed within the ExpressionBuilder, we put it directly\n\t\t// in this struct instead of accessing it through the list of annotations.\n\t\tpublic readonly ResolveResult ResolveResult;\n\n\t\tpublic IEnumerable<ILInstruction> ILInstructions {\n\t\t\tget { return Expression.Annotations.OfType<ILInstruction>(); }\n\t\t}\n\n\t\tpublic IType Type {\n\t\t\tget { return ResolveResult.Type; }\n\t\t}\n\n\t\tinternal TranslatedExpression(Expression expression)\n\t\t{\n\t\t\tDebug.Assert(expression != null);\n\t\t\tthis.Expression = expression;\n\t\t\tthis.ResolveResult = expression.Annotation<ResolveResult>() ?? ErrorResolveResult.UnknownError;\n\t\t}\n\n\t\tinternal TranslatedExpression(Expression expression, ResolveResult resolveResult)\n\t\t{\n\t\t\tDebug.Assert(expression != null && resolveResult != null);\n\t\t\tDebug.Assert(expression.Annotation<ResolveResult>() == resolveResult);\n\t\t\tthis.ResolveResult = resolveResult;\n\t\t\tthis.Expression = expression;\n\t\t}\n\n\t\tpublic static implicit operator Expression(TranslatedExpression expression)\n\t\t{\n\t\t\treturn expression.Expression;\n\t\t}\n\n\t\tpublic static implicit operator ExpressionWithResolveResult(TranslatedExpression expression)\n\t\t{\n\t\t\treturn new ExpressionWithResolveResult(expression.Expression, expression.ResolveResult);\n\t\t}\n\n\t\tpublic static implicit operator ExpressionWithILInstruction(TranslatedExpression expression)\n\t\t{\n\t\t\treturn new ExpressionWithILInstruction(expression.Expression);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns a new TranslatedExpression that represents the specified descendant expression.\n\t\t/// All ILInstruction annotations from the current expression are copied to the descendant expression.\n\t\t/// The descendant expression is detached from the AST.\n\t\t/// </summary>\n\t\tpublic TranslatedExpression UnwrapChild(Expression descendant)\n\t\t{\n\t\t\tif (descendant == Expression)\n\t\t\t\treturn this;\n\t\t\tfor (AstNode parent = descendant.Parent; parent != null; parent = parent.Parent)\n\t\t\t{\n\t\t\t\tforeach (var inst in parent.Annotations.OfType<ILInstruction>())\n\t\t\t\t\tdescendant.AddAnnotation(inst);\n\t\t\t\tif (parent == Expression)\n\t\t\t\t\treturn new TranslatedExpression(descendant.Detach());\n\t\t\t}\n\t\t\tthrow new ArgumentException(\"descendant must be a descendant of the current node\");\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Adds casts (if necessary) to convert this expression to the specified target type.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// If the target type is narrower than the source type, the value is truncated.\n\t\t/// If the target type is wider than the source type, the value is sign- or zero-extended based on the\n\t\t/// sign of the source type.\n\t\t/// This fits with the ExpressionBuilder's post-condition, so e.g. an assignment can simply\n\t\t/// call <c>Translate(stloc.Value).ConvertTo(stloc.Variable.Type)</c> and have the overall C# semantics match the IL semantics.\n\t\t/// \n\t\t/// From the caller's perspective, IntPtr/UIntPtr behave like normal C# integers except that they have native int size.\n\t\t/// All the special cases necessary to make IntPtr/UIntPtr behave sanely are handled internally in ConvertTo().\n\t\t/// \n\t\t/// Post-condition:\n\t\t///    The \"expected evaluation result\" is the value computed by <c>this.Expression</c>,\n\t\t///    converted to targetType via an IL conv instruction.\n\t\t/// \n\t\t///    ConvertTo(targetType, allowImplicitConversion=false).Type must be equal to targetType (modulo identity conversions).\n\t\t///      The value computed by the converted expression must match the \"expected evaluation result\".\n\t\t/// \n\t\t///    ConvertTo(targetType, allowImplicitConversion=true) must produce an expression that,\n\t\t///      when evaluated in a context where it will be implicitly converted to targetType,\n\t\t///      evaluates to the \"expected evaluation result\".\n\t\t/// </remarks>\n\t\tpublic TranslatedExpression ConvertTo(IType targetType, ExpressionBuilder expressionBuilder, bool checkForOverflow = false, bool allowImplicitConversion = false)\n\t\t{\n\t\t\tvar type = this.Type;\n\t\t\tif (NormalizeTypeVisitor.IgnoreNullabilityAndTuples.EquivalentTypes(type, targetType))\n\t\t\t{\n\t\t\t\t// Make explicit conversion implicit, if possible\n\t\t\t\tif (allowImplicitConversion)\n\t\t\t\t{\n\t\t\t\t\tswitch (ResolveResult)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase ConversionResolveResult conversion:\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (Expression is CastExpression cast && CastCanBeMadeImplicit(\n\t\t\t\t\t\t\t\t\tResolver.CSharpConversions.Get(expressionBuilder.compilation),\n\t\t\t\t\t\t\t\t\tconversion.Conversion,\n\t\t\t\t\t\t\t\t\tconversion.Input.Type,\n\t\t\t\t\t\t\t\t\ttype, targetType\n\t\t\t\t\t\t\t\t))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvar result = this.UnwrapChild(cast.Expression);\n\t\t\t\t\t\t\t\tif (conversion.Conversion.IsUserDefined)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tresult.Expression.AddAnnotation(new ImplicitConversionAnnotation(conversion));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn result;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (Expression is ObjectCreateExpression oce && conversion.Conversion.IsMethodGroupConversion\n\t\t\t\t\t\t\t\t  && oce.Arguments.Count == 1 && expressionBuilder.settings.UseImplicitMethodGroupConversion)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn this.UnwrapChild(oce.Arguments.Single());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase InvocationResolveResult invocation:\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (Expression is ObjectCreateExpression oce && oce.Arguments.Count == 1\n\t\t\t\t\t\t\t\t&& invocation.Type.IsKnownType(KnownTypeCode.NullableOfT))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn this.UnwrapChild(oce.Arguments.Single());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t\tif (targetType.Kind == TypeKind.Void || targetType.Kind == TypeKind.None)\n\t\t\t{\n\t\t\t\treturn this; // don't attempt to insert cast to '?' or 'void' as these are not valid.\n\t\t\t}\n\t\t\telse if (targetType.Kind == TypeKind.Unknown)\n\t\t\t{\n\t\t\t\t// don't attempt cast to '?', or casts between an unknown type and a known type with same name\n\t\t\t\tif (targetType.Name == \"?\" || targetType.ReflectionName == type.ReflectionName)\n\t\t\t\t{\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\t// However we still want explicit casts to types that are merely unresolved\n\t\t\t}\n\t\t\tvar convAnnotation = this.Expression.Annotation<ImplicitConversionAnnotation>();\n\t\t\tif (convAnnotation != null)\n\t\t\t{\n\t\t\t\t// If an implicit user-defined conversion was stripped from this expression;\n\t\t\t\t// it needs to be re-introduced before we can apply other casts to this expression.\n\t\t\t\t// This happens when the CallBuilder discovers that the conversion is necessary in\n\t\t\t\t// order to choose the correct overload.\n\t\t\t\tthis.Expression.RemoveAnnotations<ImplicitConversionAnnotation>();\n\t\t\t\treturn new CastExpression(expressionBuilder.ConvertType(convAnnotation.TargetType), Expression)\n\t\t\t\t\t.WithoutILInstruction()\n\t\t\t\t\t.WithRR(convAnnotation.ConversionResolveResult)\n\t\t\t\t\t.ConvertTo(targetType, expressionBuilder, checkForOverflow, allowImplicitConversion);\n\t\t\t}\n\t\t\tif (Expression is ThrowExpression && allowImplicitConversion)\n\t\t\t{\n\t\t\t\treturn this; // Throw expressions have no type and are implicitly convertible to any type\n\t\t\t}\n\t\t\tif (Expression is TupleExpression tupleExpr && targetType is TupleType targetTupleType\n\t\t\t\t&& tupleExpr.Elements.Count == targetTupleType.ElementTypes.Length)\n\t\t\t{\n\t\t\t\t// Conversion of a tuple literal: convert element-wise\n\t\t\t\tvar newTupleExpr = new TupleExpression();\n\t\t\t\tvar newElementRRs = new List<ResolveResult>();\n\t\t\t\t// element names: discard existing names and use targetTupleType instead\n\t\t\t\tvar newElementNames = targetTupleType.ElementNames;\n\t\t\t\tforeach (var (index, elementExpr, elementTargetType) in tupleExpr.Elements.ZipWithIndex(targetTupleType.ElementTypes))\n\t\t\t\t{\n\t\t\t\t\tvar newElementExpr = new TranslatedExpression((elementExpr is NamedArgumentExpression nae ? nae.Expression : elementExpr).Detach())\n\t\t\t\t\t\t.ConvertTo(elementTargetType, expressionBuilder, checkForOverflow, allowImplicitConversion);\n\t\t\t\t\tif (newElementNames.IsDefaultOrEmpty || newElementNames.ElementAtOrDefault(index) is not string { Length: > 0 } name)\n\t\t\t\t\t{\n\t\t\t\t\t\tnewTupleExpr.Elements.Add(newElementExpr.Expression);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tnewTupleExpr.Elements.Add(new NamedArgumentExpression(name, newElementExpr.Expression));\n\t\t\t\t\t}\n\t\t\t\t\tnewElementRRs.Add(newElementExpr.ResolveResult);\n\t\t\t\t}\n\t\t\t\treturn newTupleExpr.WithILInstruction(this.ILInstructions)\n\t\t\t\t\t.WithRR(new TupleResolveResult(\n\t\t\t\t\t\texpressionBuilder.compilation, newElementRRs.ToImmutableArray(),\n\t\t\t\t\t\tvalueTupleAssembly: targetTupleType.GetDefinition()?.ParentModule\n\t\t\t\t\t));\n\t\t\t}\n\t\t\tvar compilation = expressionBuilder.compilation;\n\t\t\tvar conversions = Resolver.CSharpConversions.Get(compilation);\n\t\t\tif (ResolveResult is ConversionResolveResult conv && Expression is CastExpression cast2\n\t\t\t\t&& !conv.Conversion.IsUserDefined\n\t\t\t\t&& CastCanBeMadeImplicit(conversions, conv.Conversion, conv.Input.Type, type, targetType))\n\t\t\t{\n\t\t\t\tvar unwrapped = this.UnwrapChild(cast2.Expression);\n\t\t\t\tif (allowImplicitConversion)\n\t\t\t\t\treturn unwrapped;\n\t\t\t\treturn unwrapped.ConvertTo(targetType, expressionBuilder, checkForOverflow, allowImplicitConversion);\n\t\t\t}\n\t\t\tif (Expression is UnaryOperatorExpression uoe && uoe.Operator == UnaryOperatorType.NullConditional && targetType.IsReferenceType == true)\n\t\t\t{\n\t\t\t\t// \"(T)(x?).AccessChain\" is invalid, but \"((T)x)?.AccessChain\" is valid and equivalent\n\t\t\t\treturn new UnaryOperatorExpression(\n\t\t\t\t\tUnaryOperatorType.NullConditional,\n\t\t\t\t\tUnwrapChild(uoe.Expression).ConvertTo(targetType, expressionBuilder, checkForOverflow, allowImplicitConversion)\n\t\t\t\t).WithRR(new ResolveResult(targetType)).WithoutILInstruction();\n\t\t\t}\n\t\t\tIType utype = NullableType.GetUnderlyingType(type);\n\t\t\tIType targetUType = NullableType.GetUnderlyingType(targetType);\n\t\t\tif (type.IsKnownType(KnownTypeCode.Boolean) && !targetUType.IsKnownType(KnownTypeCode.Boolean)\n\t\t\t\t&& targetUType.GetStackType().IsIntegerType())\n\t\t\t{\n\t\t\t\t// convert from boolean to integer (or enum)\n\t\t\t\treturn new ConditionalExpression(\n\t\t\t\t\tthis.Expression,\n\t\t\t\t\tLdcI4(compilation, 1).ConvertTo(targetType, expressionBuilder, checkForOverflow),\n\t\t\t\t\tLdcI4(compilation, 0).ConvertTo(targetType, expressionBuilder, checkForOverflow)\n\t\t\t\t).WithoutILInstruction().WithRR(new ResolveResult(targetType));\n\t\t\t}\n\t\t\tif (targetType.IsKnownType(KnownTypeCode.Boolean))\n\t\t\t{\n\t\t\t\t// convert to boolean through byte, to simulate the truncation to 8 bits\n\t\t\t\treturn this.ConvertTo(compilation.FindType(KnownTypeCode.Byte), expressionBuilder, checkForOverflow)\n\t\t\t\t\t.ConvertToBoolean(expressionBuilder);\n\t\t\t}\n\n\t\t\t// Special-case IntPtr and UIntPtr: they behave extremely weird, see IntPtr.txt for details.\n\t\t\tif (type.IsKnownType(KnownTypeCode.IntPtr))\n\t\t\t{ // Conversion from IntPtr\n\t\t\t  // Direct cast only works correctly for IntPtr -> long.\n\t\t\t  // IntPtr -> int works correctly only in checked context.\n\t\t\t  // Everything else can be worked around by casting via long.\n\t\t\t\tif (!(targetType.IsKnownType(KnownTypeCode.Int64) || targetType.Kind == TypeKind.NInt\n\t\t\t\t\t|| (checkForOverflow && targetType.IsKnownType(KnownTypeCode.Int32))\n\t\t\t\t\t|| targetType.Kind.IsAnyPointer() || targetType.Kind == TypeKind.ByReference))\n\t\t\t\t{\n\t\t\t\t\tvar convertVia = expressionBuilder.settings.NativeIntegers ? SpecialType.NInt : compilation.FindType(KnownTypeCode.Int64);\n\t\t\t\t\treturn this.ConvertTo(convertVia, expressionBuilder, checkForOverflow)\n\t\t\t\t\t\t.ConvertTo(targetType, expressionBuilder, checkForOverflow, allowImplicitConversion);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (type.IsKnownType(KnownTypeCode.UIntPtr))\n\t\t\t{ // Conversion from UIntPtr\n\t\t\t  // Direct cast only works correctly for UIntPtr -> ulong.\n\t\t\t  // UIntPtr -> uint works correctly only in checked context.\n\t\t\t  // Everything else can be worked around by casting via ulong.\n\t\t\t\tif (!(targetType.IsKnownType(KnownTypeCode.UInt64) || targetType.Kind == TypeKind.NUInt\n\t\t\t\t\t|| (checkForOverflow && targetType.IsKnownType(KnownTypeCode.UInt32))\n\t\t\t\t\t|| targetType.Kind.IsAnyPointer() || targetType.Kind == TypeKind.ByReference))\n\t\t\t\t{\n\t\t\t\t\tvar convertVia = expressionBuilder.settings.NativeIntegers ? SpecialType.NUInt : compilation.FindType(KnownTypeCode.UInt64);\n\t\t\t\t\treturn this.ConvertTo(convertVia, expressionBuilder, checkForOverflow)\n\t\t\t\t\t\t.ConvertTo(targetType, expressionBuilder, checkForOverflow, allowImplicitConversion);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (targetUType.IsKnownType(KnownTypeCode.IntPtr) && utype.GetStackType().IsIntegerType())\n\t\t\t{ // Conversion to IntPtr\n\t\t\t\tif (type.IsKnownType(KnownTypeCode.Int32) || type.Kind == TypeKind.NInt)\n\t\t\t\t{\n\t\t\t\t\t// normal casts work for int/nint (both in checked and unchecked context)\n\t\t\t\t\t// note that pointers only allow normal casts in unchecked contexts\n\t\t\t\t}\n\t\t\t\telse if (expressionBuilder.settings.NativeIntegers)\n\t\t\t\t{\n\t\t\t\t\t// if native integer types are available, prefer using those\n\t\t\t\t\treturn this.ConvertTo(SpecialType.NInt, expressionBuilder, checkForOverflow)\n\t\t\t\t\t\t.ConvertTo(targetType, expressionBuilder, checkForOverflow, allowImplicitConversion);\n\t\t\t\t}\n\t\t\t\telse if (checkForOverflow)\n\t\t\t\t{\n\t\t\t\t\t// if overflow-checking is enabled, we can simply cast via long:\n\t\t\t\t\t// (and long itself works directly in checked context)\n\t\t\t\t\tif (!type.IsKnownType(KnownTypeCode.Int64))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn this.ConvertTo(compilation.FindType(KnownTypeCode.Int64), expressionBuilder, checkForOverflow)\n\t\t\t\t\t\t\t.ConvertTo(targetType, expressionBuilder, checkForOverflow);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (!type.Kind.IsAnyPointer())\n\t\t\t\t{\n\t\t\t\t\t// If overflow-checking is disabled, the only way to truncate to native size\n\t\t\t\t\t// without throwing an exception in 32-bit mode is to use a pointer type.\n\t\t\t\t\treturn this.ConvertTo(new PointerType(compilation.FindType(KnownTypeCode.Void)), expressionBuilder, checkForOverflow)\n\t\t\t\t\t\t.ConvertTo(targetType, expressionBuilder, checkForOverflow);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (targetUType.IsKnownType(KnownTypeCode.UIntPtr) && utype.GetStackType().IsIntegerType())\n\t\t\t{ // Conversion to UIntPtr\n\t\t\t\tif (type.IsKnownType(KnownTypeCode.UInt32) || type.Kind.IsAnyPointer() || type.Kind == TypeKind.NUInt)\n\t\t\t\t{\n\t\t\t\t\t// normal casts work for uint/nuint and pointers (both in checked and unchecked context)\n\t\t\t\t}\n\t\t\t\telse if (expressionBuilder.settings.NativeIntegers)\n\t\t\t\t{\n\t\t\t\t\t// if native integer types are available, prefer using those\n\t\t\t\t\treturn this.ConvertTo(SpecialType.NUInt, expressionBuilder, checkForOverflow)\n\t\t\t\t\t\t.ConvertTo(targetType, expressionBuilder, checkForOverflow, allowImplicitConversion);\n\t\t\t\t}\n\t\t\t\telse if (checkForOverflow)\n\t\t\t\t{\n\t\t\t\t\t// if overflow-checking is enabled, we can simply cast via ulong:\n\t\t\t\t\t// (and ulong itself works directly in checked context)\n\t\t\t\t\tif (!type.IsKnownType(KnownTypeCode.UInt64))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn this.ConvertTo(compilation.FindType(KnownTypeCode.UInt64), expressionBuilder, checkForOverflow)\n\t\t\t\t\t\t\t.ConvertTo(targetType, expressionBuilder, checkForOverflow);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// If overflow-checking is disabled, the only way to truncate to native size\n\t\t\t\t\t// without throwing an exception in 32-bit mode is to use a pointer type.\n\t\t\t\t\treturn this.ConvertTo(new PointerType(compilation.FindType(KnownTypeCode.Void)), expressionBuilder, checkForOverflow)\n\t\t\t\t\t\t.ConvertTo(targetType, expressionBuilder, checkForOverflow);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (targetType.Kind.IsAnyPointer() && type.Kind == TypeKind.Enum)\n\t\t\t{\n\t\t\t\t// enum to pointer: C# doesn't allow such casts\n\t\t\t\t// -> convert via underlying type\n\t\t\t\treturn this.ConvertTo(type.GetEnumUnderlyingType(), expressionBuilder, checkForOverflow)\n\t\t\t\t\t.ConvertTo(targetType, expressionBuilder, checkForOverflow);\n\t\t\t}\n\t\t\telse if (targetUType.Kind == TypeKind.Enum && type.Kind.IsAnyPointer())\n\t\t\t{\n\t\t\t\t// pointer to enum: C# doesn't allow such casts\n\t\t\t\t// -> convert via underlying type\n\t\t\t\treturn this.ConvertTo(targetUType.GetEnumUnderlyingType(), expressionBuilder, checkForOverflow)\n\t\t\t\t\t.ConvertTo(targetType, expressionBuilder, checkForOverflow);\n\t\t\t}\n\t\t\tif (targetType.Kind.IsAnyPointer() && type.IsKnownType(KnownTypeCode.Char)\n\t\t\t   || targetUType.IsKnownType(KnownTypeCode.Char) && type.Kind.IsAnyPointer())\n\t\t\t{\n\t\t\t\t// char <-> pointer: C# doesn't allow such casts\n\t\t\t\t// -> convert via ushort\n\t\t\t\treturn this.ConvertTo(compilation.FindType(KnownTypeCode.UInt16), expressionBuilder, checkForOverflow)\n\t\t\t\t\t.ConvertTo(targetType, expressionBuilder, checkForOverflow);\n\t\t\t}\n\t\t\tif (targetType.Kind == TypeKind.Pointer && type.Kind == TypeKind.ByReference && Expression is DirectionExpression)\n\t\t\t{\n\t\t\t\t// convert from reference to pointer\n\t\t\t\tExpression arg = ((DirectionExpression)Expression).Expression.Detach();\n\t\t\t\tvar pointerType = new PointerType(((ByReferenceType)type).ElementType);\n\t\t\t\tif (arg is UnaryOperatorExpression argUOE && argUOE.Operator == UnaryOperatorType.Dereference)\n\t\t\t\t{\n\t\t\t\t\t// &*ptr -> ptr\n\t\t\t\t\treturn new TranslatedExpression(argUOE).UnwrapChild(argUOE.Expression)\n\t\t\t\t\t\t.ConvertTo(targetType, expressionBuilder);\n\t\t\t\t}\n\t\t\t\tvar pointerExpr = new UnaryOperatorExpression(UnaryOperatorType.AddressOf, arg)\n\t\t\t\t\t.WithILInstruction(this.ILInstructions)\n\t\t\t\t\t.WithRR(new ResolveResult(pointerType));\n\t\t\t\t// perform remaining pointer cast, if necessary\n\t\t\t\treturn pointerExpr.ConvertTo(targetType, expressionBuilder);\n\t\t\t}\n\t\t\tExpression expr;\n\t\t\tif (targetType.Kind == TypeKind.ByReference)\n\t\t\t{\n\t\t\t\tif (NormalizeTypeVisitor.TypeErasure.EquivalentTypes(targetType, this.Type))\n\t\t\t\t{\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tvar elementType = ((ByReferenceType)targetType).ElementType;\n\t\t\t\tif (this.Expression is DirectionExpression thisDir && this.ILInstructions.Any(i => i.OpCode == OpCode.AddressOf)\n\t\t\t\t\t&& thisDir.Expression.GetResolveResult()?.Type.GetStackType() == elementType.GetStackType())\n\t\t\t\t{\n\t\t\t\t\t// When converting a reference to a temporary to a different type,\n\t\t\t\t\t// apply the cast to the temporary instead.\n\t\t\t\t\tvar convertedTemp = this.UnwrapChild(thisDir.Expression).ConvertTo(elementType, expressionBuilder, checkForOverflow);\n\t\t\t\t\treturn new DirectionExpression(FieldDirection.Ref, convertedTemp)\n\t\t\t\t\t\t.WithILInstruction(this.ILInstructions)\n\t\t\t\t\t\t.WithRR(new ByReferenceResolveResult(convertedTemp.ResolveResult, ReferenceKind.Ref));\n\t\t\t\t}\n\t\t\t\tif (this.Type.Kind == TypeKind.ByReference && !IsFixedVariable())\n\t\t\t\t{\n\t\t\t\t\t// Convert between managed reference types.\n\t\t\t\t\t// We can't do this by going through a pointer type because that would temporarily stop GC tracking.\n\t\t\t\t\t// Instead, emit `ref Unsafe.As<T>(ref expr)`\n\t\t\t\t\treturn expressionBuilder.CallUnsafeIntrinsic(\"As\", new[] { this.Expression },\n\t\t\t\t\t\ttypeArguments: new IType[] { ((ByReferenceType)this.Type).ElementType, elementType },\n\t\t\t\t\t\treturnType: targetType);\n\t\t\t\t}\n\t\t\t\t// Convert from integer/pointer to reference.\n\t\t\t\t// First, convert to the corresponding pointer type:\n\t\t\t\tvar arg = this.ConvertTo(new PointerType(elementType), expressionBuilder, checkForOverflow);\n\t\t\t\tResolveResult elementRR;\n\t\t\t\tif (arg.Expression is UnaryOperatorExpression unary && unary.Operator == UnaryOperatorType.AddressOf)\n\t\t\t\t{\n\t\t\t\t\t// If we already have an address -> unwrap\n\t\t\t\t\texpr = arg.UnwrapChild(unary.Expression);\n\t\t\t\t\telementRR = expr.GetResolveResult();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Otherwise dereference the pointer:\n\t\t\t\t\texpr = new UnaryOperatorExpression(UnaryOperatorType.Dereference, arg.Expression);\n\t\t\t\t\telementRR = new ResolveResult(elementType);\n\t\t\t\t\texpr.AddAnnotation(elementRR);\n\t\t\t\t}\n\t\t\t\t// And then take a reference:\n\t\t\t\treturn new DirectionExpression(FieldDirection.Ref, expr)\n\t\t\t\t\t.WithoutILInstruction()\n\t\t\t\t\t.WithRR(new ByReferenceResolveResult(elementRR, ReferenceKind.Ref));\n\t\t\t}\n\t\t\tif (this.ResolveResult.IsCompileTimeConstant && this.ResolveResult.ConstantValue != null\n\t\t\t\t&& NullableType.IsNullable(targetType) && !utype.Equals(targetUType)\n\t\t\t\t&& targetUType.GetStackType().IsIntegerType())\n\t\t\t{\n\t\t\t\t// Casts like `(uint?)-1` are only valid in an explicitly unchecked context, but we\n\t\t\t\t// don't have logic to ensure such a context (usually we emit into an implicitly unchecked context).\n\t\t\t\t// This only applies with constants as input (int->uint? is fine in implicitly unchecked context).\n\t\t\t\t// We use an intermediate cast to the nullable's underlying type, which results\n\t\t\t\t// in a constant conversion, so the final output will be something like `(uint?)uint.MaxValue`\n\t\t\t\treturn ConvertTo(targetUType, expressionBuilder, checkForOverflow, allowImplicitConversion: false)\n\t\t\t\t\t.ConvertTo(targetType, expressionBuilder, checkForOverflow, allowImplicitConversion);\n\t\t\t}\n\t\t\tvar rr = expressionBuilder.resolver.WithCheckForOverflow(checkForOverflow).ResolveCast(targetType, ResolveResult);\n\t\t\tif (rr.IsCompileTimeConstant && !rr.IsError)\n\t\t\t{\n\t\t\t\tvar convertedResult = expressionBuilder.ConvertConstantValue(rr, allowImplicitConversion)\n\t\t\t\t\t.WithILInstruction(this.ILInstructions);\n\t\t\t\tif (convertedResult.Expression is PrimitiveExpression outputLiteral && this.Expression is PrimitiveExpression inputLiteral)\n\t\t\t\t{\n\t\t\t\t\toutputLiteral.Format = inputLiteral.Format;\n\t\t\t\t}\n\t\t\t\treturn convertedResult;\n\t\t\t}\n\t\t\telse if (rr.IsError && targetType.IsReferenceType == true && type.IsReferenceType == true)\n\t\t\t{\n\t\t\t\t// Conversion between two reference types, but no direct cast allowed? cast via object\n\t\t\t\t// Just make sure we avoid infinite recursion even if the resolver falsely claims we can't cast directly:\n\t\t\t\tif (!(targetType.IsKnownType(KnownTypeCode.Object) || type.IsKnownType(KnownTypeCode.Object)))\n\t\t\t\t{\n\t\t\t\t\treturn this.ConvertTo(compilation.FindType(KnownTypeCode.Object), expressionBuilder)\n\t\t\t\t\t\t.ConvertTo(targetType, expressionBuilder, checkForOverflow, allowImplicitConversion);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (type.Kind == TypeKind.Dynamic && targetType.IsReferenceType == true && !targetType.IsKnownType(KnownTypeCode.Object))\n\t\t\t{\n\t\t\t\t// \"static\" conversion between dynamic and a reference type requires us to add a cast to object,\n\t\t\t\t// otherwise recompilation would produce a dynamic cast.\n\t\t\t\t// (T)dynamicExpression is a \"dynamic\" cast\n\t\t\t\t// (T)(object)dynamicExpression is a \"static\" cast\n\t\t\t\t// as \"dynamic\" casts are handled differently by ExpressionBuilder.VisitDynamicConvertInstruction\n\t\t\t\t// we can always insert the cast to object, if we encounter a conversion from any reference type to dynamic.\n\t\t\t\treturn this.ConvertTo(compilation.FindType(KnownTypeCode.Object), expressionBuilder)\n\t\t\t\t\t.ConvertTo(targetType, expressionBuilder, checkForOverflow, allowImplicitConversion);\n\t\t\t}\n\t\t\tif (targetType.Kind.IsAnyPointer() && (0.Equals(ResolveResult.ConstantValue) || 0u.Equals(ResolveResult.ConstantValue)))\n\t\t\t{\n\t\t\t\tif (allowImplicitConversion)\n\t\t\t\t{\n\t\t\t\t\treturn new NullReferenceExpression()\n\t\t\t\t\t\t.WithILInstruction(this.ILInstructions)\n\t\t\t\t\t\t.WithRR(new ConstantResolveResult(SpecialType.NullType, null));\n\t\t\t\t}\n\t\t\t\treturn new CastExpression(expressionBuilder.ConvertType(targetType), new NullReferenceExpression())\n\t\t\t\t\t.WithILInstruction(this.ILInstructions)\n\t\t\t\t\t.WithRR(new ConstantResolveResult(targetType, null));\n\t\t\t}\n\t\t\tif (allowImplicitConversion)\n\t\t\t{\n\t\t\t\tif (conversions.ImplicitConversion(ResolveResult, targetType).IsValid)\n\t\t\t\t{\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (NormalizeTypeVisitor.IgnoreNullabilityAndTuples.EquivalentTypes(type, targetType))\n\t\t\t\t{\n\t\t\t\t\t// avoid an explicit cast when types differ only in nullability of reference types\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// BaseReferenceExpression must not be used with CastExpressions\n\t\t\texpr = Expression is BaseReferenceExpression\n\t\t\t\t? new ThisReferenceExpression().WithILInstruction(this.ILInstructions)\n\t\t\t\t: Expression;\n\t\t\tvar castExpr = new CastExpression(expressionBuilder.ConvertType(targetType), expr);\n\t\t\tbool needsCheckAnnotation = targetUType.GetStackType().IsIntegerType();\n\t\t\tif (needsCheckAnnotation)\n\t\t\t{\n\t\t\t\tif (checkForOverflow)\n\t\t\t\t{\n\t\t\t\t\tcastExpr.AddAnnotation(AddCheckedBlocks.CheckedAnnotation);\n\t\t\t\t}\n\t\t\t\telse if (ResolveResult.IsCompileTimeConstant && targetUType.IsCSharpNativeIntegerType())\n\t\t\t\t{\n\t\t\t\t\t// unchecked potentially-overflowing cast of constant to n(u)int:\n\t\t\t\t\t// Placement in implicitly unchecked context is not good enough when applied to compile-time constant,\n\t\t\t\t\t// the constant must be placed into an explicit unchecked block.\n\t\t\t\t\t// (note that non-potentially-overflowing casts will be handled by constant folding and won't get here)\n\t\t\t\t\tcastExpr.AddAnnotation(AddCheckedBlocks.ExplicitUncheckedAnnotation);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcastExpr.AddAnnotation(AddCheckedBlocks.UncheckedAnnotation);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn castExpr.WithoutILInstruction().WithRR(rr);\n\t\t}\n\n\t\tbool IsFixedVariable()\n\t\t{\n\t\t\tif (this.Expression is DirectionExpression dirExpr)\n\t\t\t{\n\t\t\t\tvar inst = dirExpr.Expression.Annotation<ILInstruction>();\n\t\t\t\treturn inst != null && PointerArithmeticOffset.IsFixedVariable(inst);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether an implicit conversion from 'inputType' to 'newTargetType'\n\t\t/// would have the same semantics as the existing cast from 'inputType' to 'oldTargetType'.\n\t\t/// The existing cast is classified in 'conversion'.\n\t\t/// </summary>\n\t\tbool CastCanBeMadeImplicit(Resolver.CSharpConversions conversions, Conversion conversion, IType inputType, IType oldTargetType, IType newTargetType)\n\t\t{\n\t\t\tif (!conversion.IsImplicit)\n\t\t\t{\n\t\t\t\t// If the cast was required for the old conversion, avoid making it implicit.\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (oldTargetType.Kind == TypeKind.NInt || oldTargetType.Kind == TypeKind.NUInt\n\t\t\t\t|| newTargetType.Kind == TypeKind.NInt || newTargetType.Kind == TypeKind.NUInt)\n\t\t\t{\n\t\t\t\t// nint has identity conversion with IntPtr, but the two have different implicit conversions\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (conversion.IsBoxingConversion)\n\t\t\t{\n\t\t\t\treturn conversions.IsBoxingConversionOrInvolvingTypeParameter(inputType, newTargetType);\n\t\t\t}\n\t\t\tif (conversion.IsInterpolatedStringConversion)\n\t\t\t{\n\t\t\t\treturn newTargetType.IsKnownType(KnownTypeCode.FormattableString)\n\t\t\t\t\t|| newTargetType.IsKnownType(KnownTypeCode.IFormattable);\n\t\t\t}\n\t\t\treturn conversions.IdentityConversion(oldTargetType, newTargetType);\n\t\t}\n\n\t\tTranslatedExpression LdcI4(ICompilation compilation, int val)\n\t\t{\n\t\t\treturn new PrimitiveExpression(val)\n\t\t\t\t.WithoutILInstruction()\n\t\t\t\t.WithRR(new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), val));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// In conditional contexts, remove the bool-cast emitted when converting\n\t\t/// an \"implicit operator bool\" invocation.\n\t\t/// </summary>\n\t\tpublic TranslatedExpression UnwrapImplicitBoolConversion(Func<IType, bool> typeFilter = null)\n\t\t{\n\t\t\tif (!this.Type.IsKnownType(KnownTypeCode.Boolean))\n\t\t\t\treturn this;\n\t\t\tif (!(this.ResolveResult is ConversionResolveResult rr))\n\t\t\t\treturn this;\n\t\t\tif (!(rr.Conversion.IsUserDefined && rr.Conversion.IsImplicit))\n\t\t\t\treturn this;\n\t\t\tif (typeFilter != null && !typeFilter(rr.Input.Type))\n\t\t\t\treturn this;\n\t\t\tif (this.Expression is CastExpression cast)\n\t\t\t{\n\t\t\t\treturn this.UnwrapChild(cast.Expression);\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts this expression to a boolean expression.\n\t\t/// \n\t\t/// Expects that the input expression is an integer expression; produces an expression\n\t\t/// that returns <c>true</c> iff the integer value is not 0.\n\t\t/// \n\t\t/// If negate is true, instead produces an expression that returns <c>true</c> iff the integer value is 0.\n\t\t/// </summary>\n\t\tpublic TranslatedExpression ConvertToBoolean(ExpressionBuilder expressionBuilder, bool negate = false)\n\t\t{\n\t\t\tif (Type.IsKnownType(KnownTypeCode.Boolean) || Type.Kind == TypeKind.Unknown)\n\t\t\t{\n\t\t\t\tif (negate)\n\t\t\t\t{\n\t\t\t\t\treturn expressionBuilder.LogicNot(this).WithoutILInstruction();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t}\n\t\t\tDebug.Assert(Type.GetStackType().IsIntegerType());\n\t\t\tIType boolType = expressionBuilder.compilation.FindType(KnownTypeCode.Boolean);\n\t\t\tif (ResolveResult.IsCompileTimeConstant && ResolveResult.ConstantValue is int)\n\t\t\t{\n\t\t\t\tbool val = (int)ResolveResult.ConstantValue != 0;\n\t\t\t\tval ^= negate;\n\t\t\t\treturn new PrimitiveExpression(val)\n\t\t\t\t\t.WithILInstruction(this.ILInstructions)\n\t\t\t\t\t.WithRR(new ConstantResolveResult(boolType, val));\n\t\t\t}\n\t\t\telse if (ResolveResult.IsCompileTimeConstant && ResolveResult.ConstantValue is byte)\n\t\t\t{\n\t\t\t\tbool val = (byte)ResolveResult.ConstantValue != 0;\n\t\t\t\tval ^= negate;\n\t\t\t\treturn new PrimitiveExpression(val)\n\t\t\t\t\t.WithILInstruction(this.ILInstructions)\n\t\t\t\t\t.WithRR(new ConstantResolveResult(boolType, val));\n\t\t\t}\n\t\t\telse if (Type.Kind == TypeKind.Pointer)\n\t\t\t{\n\t\t\t\tvar nullRef = new NullReferenceExpression()\n\t\t\t\t\t.WithoutILInstruction()\n\t\t\t\t\t.WithRR(new ConstantResolveResult(SpecialType.NullType, null));\n\t\t\t\tvar op = negate ? BinaryOperatorType.Equality : BinaryOperatorType.InEquality;\n\t\t\t\treturn new BinaryOperatorExpression(Expression, op, nullRef.Expression)\n\t\t\t\t\t.WithoutILInstruction()\n\t\t\t\t\t.WithRR(new OperatorResolveResult(boolType, System.Linq.Expressions.ExpressionType.NotEqual,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  this.ResolveResult, nullRef.ResolveResult));\n\t\t\t}\n\t\t\telse if (Type.Kind == TypeKind.Enum && Type.GetDefinition() is { } typeDef &&\n\t\t\t\t\t typeDef.Fields.Any(f => f.GetConstantValue() is { } val && (ulong)CSharpPrimitiveCast.Cast(TypeCode.UInt64, val, false) == 0L))\n\t\t\t{\n\t\t\t\tvar zero = expressionBuilder\n\t\t\t\t\t.ConvertConstantValue(new ConstantResolveResult(Type, 0), allowImplicitConversion: true);\n\t\t\t\tvar op = negate ? BinaryOperatorType.Equality : BinaryOperatorType.InEquality;\n\t\t\t\treturn new BinaryOperatorExpression(Expression, op, zero.Expression)\n\t\t\t\t\t.WithoutILInstruction()\n\t\t\t\t\t.WithRR(new OperatorResolveResult(boolType, System.Linq.Expressions.ExpressionType.NotEqual,\n\t\t\t\t\t\tthis.ResolveResult, zero.ResolveResult));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar zero = new PrimitiveExpression(0)\n\t\t\t\t\t.WithoutILInstruction()\n\t\t\t\t\t.WithRR(new ConstantResolveResult(expressionBuilder.compilation.FindType(KnownTypeCode.Int32), 0));\n\t\t\t\tvar op = negate ? BinaryOperatorType.Equality : BinaryOperatorType.InEquality;\n\t\t\t\treturn new BinaryOperatorExpression(Expression, op, zero.Expression)\n\t\t\t\t\t.WithoutILInstruction()\n\t\t\t\t\t.WithRR(new OperatorResolveResult(boolType, System.Linq.Expressions.ExpressionType.NotEqual,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  this.ResolveResult, zero.ResolveResult));\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/TranslatedStatement.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.IL;\n\nnamespace ICSharpCode.Decompiler.CSharp\n{\n\t[DebuggerDisplay(\"{Statement}\")]\n\tstruct TranslatedStatement\n\t{\n\t\tpublic readonly Statement Statement;\n\n\t\tpublic IEnumerable<ILInstruction> ILInstructions {\n\t\t\tget { return Statement.Annotations.OfType<ILInstruction>(); }\n\t\t}\n\n\t\tinternal TranslatedStatement(Statement statement)\n\t\t{\n\t\t\tDebug.Assert(statement != null);\n\t\t\tthis.Statement = statement;\n\t\t}\n\n\t\tpublic static implicit operator Statement(TranslatedStatement statement)\n\t\t{\n\t\t\treturn statement.Statement;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/TranslationContext.cs",
    "content": "// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp\n{\n\t/// <summary>\n\t/// Context struct passed in to ExpressionBuilder.Visit() methods.\n\t/// </summary>\n\tpublic struct TranslationContext\n\t{\n\t\t/// <summary>\n\t\t/// The expected type during ILAst->C# translation; or <c>SpecialType.Unknown</c>\n\t\t/// if no specific type is expected.\n\t\t/// </summary>\n\t\tpublic IType TypeHint;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/TypeSystem/CSharpTypeResolveContext.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.CSharp.TypeSystem\n{\n\tpublic sealed class CSharpTypeResolveContext : ITypeResolveContext\n\t{\n\t\treadonly IModule module;\n\t\treadonly UsingScope currentUsingScope;\n\t\treadonly ITypeDefinition currentTypeDefinition;\n\t\treadonly IMember currentMember;\n\t\treadonly string[] methodTypeParameterNames;\n\n\t\tpublic CSharpTypeResolveContext(IModule module, UsingScope usingScope = null, ITypeDefinition typeDefinition = null, IMember member = null)\n\t\t{\n\t\t\tif (module == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(module));\n\t\t\tthis.module = module;\n\t\t\tthis.currentUsingScope = usingScope;\n\t\t\tthis.currentTypeDefinition = typeDefinition;\n\t\t\tthis.currentMember = member;\n\t\t}\n\n\t\tprivate CSharpTypeResolveContext(IModule module, UsingScope usingScope, ITypeDefinition typeDefinition, IMember member, string[] methodTypeParameterNames)\n\t\t{\n\t\t\tthis.module = module;\n\t\t\tthis.currentUsingScope = usingScope;\n\t\t\tthis.currentTypeDefinition = typeDefinition;\n\t\t\tthis.currentMember = member;\n\t\t\tthis.methodTypeParameterNames = methodTypeParameterNames;\n\t\t}\n\n\t\tpublic UsingScope CurrentUsingScope {\n\t\t\tget { return currentUsingScope; }\n\t\t}\n\n\t\tpublic ICompilation Compilation {\n\t\t\tget { return module.Compilation; }\n\t\t}\n\n\t\tpublic IModule CurrentModule {\n\t\t\tget { return module; }\n\t\t}\n\n\t\tpublic ITypeDefinition CurrentTypeDefinition {\n\t\t\tget { return currentTypeDefinition; }\n\t\t}\n\n\t\tpublic IMember CurrentMember {\n\t\t\tget { return currentMember; }\n\t\t}\n\n\t\tpublic CSharpTypeResolveContext WithCurrentTypeDefinition(ITypeDefinition typeDefinition)\n\t\t{\n\t\t\treturn new CSharpTypeResolveContext(module, currentUsingScope, typeDefinition, currentMember, methodTypeParameterNames);\n\t\t}\n\n\t\tITypeResolveContext ITypeResolveContext.WithCurrentTypeDefinition(ITypeDefinition typeDefinition)\n\t\t{\n\t\t\treturn WithCurrentTypeDefinition(typeDefinition);\n\t\t}\n\n\t\tpublic CSharpTypeResolveContext WithCurrentMember(IMember member)\n\t\t{\n\t\t\treturn new CSharpTypeResolveContext(module, currentUsingScope, currentTypeDefinition, member, methodTypeParameterNames);\n\t\t}\n\n\t\tITypeResolveContext ITypeResolveContext.WithCurrentMember(IMember member)\n\t\t{\n\t\t\treturn WithCurrentMember(member);\n\t\t}\n\n\t\tpublic CSharpTypeResolveContext WithUsingScope(UsingScope usingScope)\n\t\t{\n\t\t\treturn new CSharpTypeResolveContext(module, usingScope, currentTypeDefinition, currentMember, methodTypeParameterNames);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/CSharp/TypeSystem/UsingScope.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\n#nullable enable\n\nnamespace ICSharpCode.Decompiler.CSharp.TypeSystem\n{\n\t/// <summary>\n\t/// Represents a scope that contains \"using\" statements.\n\t/// This is either the mo itself, or a namespace declaration.\n\t/// </summary>\n\tpublic class UsingScope\n\t{\n\t\treadonly CSharpTypeResolveContext parentContext;\n\n\t\tinternal readonly ConcurrentDictionary<string, ResolveResult> ResolveCache = new ConcurrentDictionary<string, ResolveResult>();\n\t\tinternal List<List<IMethod>>? AllExtensionMethods;\n\n\t\tpublic UsingScope(CSharpTypeResolveContext context, INamespace @namespace, ImmutableArray<INamespace> usings)\n\t\t{\n\t\t\tthis.parentContext = context ?? throw new ArgumentNullException(nameof(context));\n\t\t\tthis.Usings = usings;\n\t\t\tthis.Namespace = @namespace ?? throw new ArgumentNullException(nameof(@namespace));\n\t\t}\n\n\t\tpublic INamespace Namespace { get; }\n\n\t\tpublic UsingScope Parent {\n\t\t\tget { return parentContext.CurrentUsingScope; }\n\t\t}\n\n\t\tpublic ImmutableArray<INamespace> Usings { get; }\n\n\t\tpublic IReadOnlyList<KeyValuePair<string, ResolveResult>> UsingAliases => [];\n\n\t\tpublic IReadOnlyList<string> ExternAliases => [];\n\n\t\t/// <summary>\n\t\t/// Gets whether this using scope has an alias (either using or extern)\n\t\t/// with the specified name.\n\t\t/// </summary>\n\t\tpublic bool HasAlias(string identifier) => false;\n\n\t\tinternal UsingScope WithNestedNamespace(string simpleName)\n\t\t{\n\t\t\tvar ns = Namespace.GetChildNamespace(simpleName) ?? new DummyNamespace(Namespace, simpleName);\n\t\t\treturn new UsingScope(\n\t\t\t\tparentContext.WithUsingScope(this),\n\t\t\t\tns,\n\t\t\t\t[]);\n\t\t}\n\n\t\tsealed class DummyNamespace : INamespace\n\t\t{\n\t\t\treadonly INamespace parentNamespace;\n\t\t\treadonly string name;\n\n\t\t\tpublic DummyNamespace(INamespace parentNamespace, string name)\n\t\t\t{\n\t\t\t\tthis.parentNamespace = parentNamespace;\n\t\t\t\tthis.name = name;\n\t\t\t}\n\n\t\t\tstring INamespace.ExternAlias => \"\";\n\n\t\t\tstring INamespace.FullName {\n\t\t\t\tget { return NamespaceDeclaration.BuildQualifiedName(parentNamespace.FullName, name); }\n\t\t\t}\n\n\t\t\tpublic string Name {\n\t\t\t\tget { return name; }\n\t\t\t}\n\n\t\t\tSymbolKind ISymbol.SymbolKind {\n\t\t\t\tget { return SymbolKind.Namespace; }\n\t\t\t}\n\n\t\t\tINamespace INamespace.ParentNamespace {\n\t\t\t\tget { return parentNamespace; }\n\t\t\t}\n\n\t\t\tIEnumerable<INamespace> INamespace.ChildNamespaces {\n\t\t\t\tget { return EmptyList<INamespace>.Instance; }\n\t\t\t}\n\n\t\t\tIEnumerable<ITypeDefinition> INamespace.Types {\n\t\t\t\tget { return EmptyList<ITypeDefinition>.Instance; }\n\t\t\t}\n\n\t\t\tIEnumerable<IModule> INamespace.ContributingModules {\n\t\t\t\tget { return EmptyList<IModule>.Instance; }\n\t\t\t}\n\n\t\t\tICompilation ICompilationProvider.Compilation {\n\t\t\t\tget { return parentNamespace.Compilation; }\n\t\t\t}\n\n\t\t\tINamespace? INamespace.GetChildNamespace(string name)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tITypeDefinition? INamespace.GetTypeDefinition(string name, int typeParameterCount)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/DebugInfo/AsyncDebugInfo.cs",
    "content": "using System;\nusing System.Collections.Immutable;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nnamespace ICSharpCode.Decompiler.DebugInfo\n{\n\tpublic readonly struct AsyncDebugInfo\n\t{\n\t\tpublic readonly int CatchHandlerOffset;\n\t\tpublic readonly ImmutableArray<Await> Awaits;\n\n\t\tpublic AsyncDebugInfo(int catchHandlerOffset, ImmutableArray<Await> awaits)\n\t\t{\n\t\t\tthis.CatchHandlerOffset = catchHandlerOffset;\n\t\t\tthis.Awaits = awaits;\n\t\t}\n\n\t\tpublic readonly struct Await\n\t\t{\n\t\t\tpublic readonly int YieldOffset;\n\t\t\tpublic readonly int ResumeOffset;\n\n\t\t\tpublic Await(int yieldOffset, int resumeOffset)\n\t\t\t{\n\t\t\t\tthis.YieldOffset = yieldOffset;\n\t\t\t\tthis.ResumeOffset = resumeOffset;\n\t\t\t}\n\t\t}\n\n\t\tpublic BlobBuilder BuildBlob(MethodDefinitionHandle moveNext)\n\t\t{\n\t\t\tBlobBuilder blob = new BlobBuilder();\n\t\t\tblob.WriteUInt32((uint)CatchHandlerOffset);\n\t\t\tforeach (var await in Awaits)\n\t\t\t{\n\t\t\t\tblob.WriteUInt32((uint)await.YieldOffset);\n\t\t\t\tblob.WriteUInt32((uint)await.ResumeOffset);\n\t\t\t\tblob.WriteCompressedInteger(MetadataTokens.GetRowNumber(moveNext));\n\t\t\t}\n\t\t\treturn blob;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/DebugInfo/DebugInfoGenerator.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.DebugInfo\n{\n\t/// <summary>\n\t/// Visitor that generates debug information.\n\t/// \n\t/// The intended usage is to create a new instance for each source file,\n\t/// and call syntaxTree.AcceptVisitor(debugInfoGenerator) to fill the internal debug info tables.\n\t/// This can happen concurrently for multiple source files.\n\t/// Then the main thread calls Generate() to write out the results into the PDB.\n\t/// </summary>\n\tclass DebugInfoGenerator : DepthFirstAstVisitor\n\t{\n\t\tstatic readonly KeyComparer<ILVariable, int> ILVariableKeyComparer = new KeyComparer<ILVariable, int>(l => l.Index.Value, Comparer<int>.Default, EqualityComparer<int>.Default);\n\n\t\tIDecompilerTypeSystem typeSystem;\n\t\treadonly ImportScopeInfo globalImportScope = new ImportScopeInfo();\n\t\tImportScopeInfo currentImportScope;\n\t\tList<ImportScopeInfo> importScopes = new List<ImportScopeInfo>();\n\t\tinternal List<(MethodDefinitionHandle Method, ImportScopeInfo Import, int Offset, int Length, HashSet<ILVariable> Locals)> LocalScopes { get; } = new List<(MethodDefinitionHandle Method, ImportScopeInfo Import, int Offset, int Length, HashSet<ILVariable> Locals)>();\n\t\tList<ILFunction> functions = new List<ILFunction>();\n\n\t\t/// <summary>\n\t\t/// Gets all functions with bodies that were seen by the visitor so far.\n\t\t/// </summary>\n\t\tpublic IReadOnlyList<ILFunction> Functions {\n\t\t\tget => functions;\n\t\t}\n\n\t\tpublic DebugInfoGenerator(IDecompilerTypeSystem typeSystem)\n\t\t{\n\t\t\tthis.typeSystem = typeSystem ?? throw new ArgumentNullException(nameof(typeSystem));\n\t\t\tthis.currentImportScope = globalImportScope;\n\t\t}\n\n\t\tpublic void GenerateImportScopes(MetadataBuilder metadata, ImportScopeHandle globalImportScope)\n\t\t{\n\t\t\tforeach (var scope in importScopes)\n\t\t\t{\n\t\t\t\tvar blob = EncodeImports(metadata, scope);\n\t\t\t\tscope.Handle = metadata.AddImportScope(scope.Parent == null ? globalImportScope : scope.Parent.Handle, blob);\n\t\t\t}\n\t\t}\n\n\t\tstatic BlobHandle EncodeImports(MetadataBuilder metadata, ImportScopeInfo scope)\n\t\t{\n\t\t\tvar writer = new BlobBuilder();\n\n\t\t\tforeach (var import in scope.Imports)\n\t\t\t{\n\t\t\t\twriter.WriteByte((byte)ImportDefinitionKind.ImportNamespace);\n\t\t\t\twriter.WriteCompressedInteger(MetadataTokens.GetHeapOffset(metadata.GetOrAddBlobUTF8(import)));\n\t\t\t}\n\n\t\t\treturn metadata.GetOrAddBlob(writer);\n\t\t}\n\n\t\tpublic override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)\n\t\t{\n\t\t\tvar parentImportScope = currentImportScope;\n\t\t\tcurrentImportScope = new ImportScopeInfo(parentImportScope);\n\t\t\timportScopes.Add(currentImportScope);\n\t\t\tbase.VisitNamespaceDeclaration(namespaceDeclaration);\n\t\t\tcurrentImportScope = parentImportScope;\n\t\t}\n\n\t\tpublic override void VisitUsingDeclaration(UsingDeclaration usingDeclaration)\n\t\t{\n\t\t\tcurrentImportScope.Imports.Add(usingDeclaration.Namespace);\n\t\t}\n\n\t\tpublic override void VisitMethodDeclaration(MethodDeclaration methodDeclaration)\n\t\t{\n\t\t\tHandleMethod(methodDeclaration);\n\t\t}\n\n\t\tpublic override void VisitAccessor(Accessor accessor)\n\t\t{\n\t\t\tHandleMethod(accessor);\n\t\t}\n\n\t\tpublic override void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)\n\t\t{\n\t\t\tHandleMethod(constructorDeclaration);\n\t\t}\n\n\t\tpublic override void VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration)\n\t\t{\n\t\t\tHandleMethod(destructorDeclaration);\n\t\t}\n\n\t\tpublic override void VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration)\n\t\t{\n\t\t\tHandleMethod(operatorDeclaration);\n\t\t}\n\n\t\tpublic override void VisitLambdaExpression(LambdaExpression lambdaExpression)\n\t\t{\n\t\t\tHandleMethod(lambdaExpression);\n\t\t}\n\n\t\tpublic override void VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression)\n\t\t{\n\t\t\tHandleMethod(anonymousMethodExpression);\n\t\t}\n\n\t\tpublic override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)\n\t\t{\n\t\t\tif (!propertyDeclaration.ExpressionBody.IsNull)\n\t\t\t{\n\t\t\t\tHandleMethod(propertyDeclaration.ExpressionBody, propertyDeclaration.Annotation<ILFunction>());\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbase.VisitPropertyDeclaration(propertyDeclaration);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration)\n\t\t{\n\t\t\tif (!indexerDeclaration.ExpressionBody.IsNull)\n\t\t\t{\n\t\t\t\tHandleMethod(indexerDeclaration.ExpressionBody, indexerDeclaration.Annotation<ILFunction>());\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbase.VisitIndexerDeclaration(indexerDeclaration);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void VisitQueryFromClause(QueryFromClause queryFromClause)\n\t\t{\n\t\t\tif (queryFromClause.Parent.FirstChild != queryFromClause)\n\t\t\t{\n\t\t\t\tHandleMethod(queryFromClause);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbase.VisitQueryFromClause(queryFromClause);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void VisitQueryGroupClause(QueryGroupClause queryGroupClause)\n\t\t{\n\t\t\tvar annotation = queryGroupClause.Annotation<QueryGroupClauseAnnotation>();\n\t\t\tif (annotation == null)\n\t\t\t{\n\t\t\t\tbase.VisitQueryGroupClause(queryGroupClause);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tHandleMethod(queryGroupClause.Projection, annotation.ProjectionLambda);\n\t\t\tHandleMethod(queryGroupClause.Key, annotation.KeyLambda);\n\t\t}\n\n\t\tpublic override void VisitQueryJoinClause(QueryJoinClause queryJoinClause)\n\t\t{\n\t\t\tvar annotation = queryJoinClause.Annotation<QueryJoinClauseAnnotation>();\n\t\t\tif (annotation == null)\n\t\t\t{\n\t\t\t\tbase.VisitQueryJoinClause(queryJoinClause);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tHandleMethod(queryJoinClause.OnExpression, annotation.OnLambda);\n\t\t\tHandleMethod(queryJoinClause.EqualsExpression, annotation.EqualsLambda);\n\t\t}\n\n\t\tpublic override void VisitQueryLetClause(QueryLetClause queryLetClause)\n\t\t{\n\t\t\tHandleMethod(queryLetClause);\n\t\t}\n\n\t\tpublic override void VisitQueryOrdering(QueryOrdering queryOrdering)\n\t\t{\n\t\t\tHandleMethod(queryOrdering);\n\t\t}\n\n\t\tpublic override void VisitQuerySelectClause(QuerySelectClause querySelectClause)\n\t\t{\n\t\t\tHandleMethod(querySelectClause);\n\t\t}\n\n\t\tpublic override void VisitQueryWhereClause(QueryWhereClause queryWhereClause)\n\t\t{\n\t\t\tHandleMethod(queryWhereClause);\n\t\t}\n\n\t\tvoid HandleMethod(AstNode node)\n\t\t{\n\t\t\tHandleMethod(node, node.Annotation<ILFunction>());\n\t\t}\n\n\t\tvoid HandleMethod(AstNode node, ILFunction function)\n\t\t{\n\t\t\t// Look into method body, e.g. in order to find lambdas\n\t\t\tVisitChildren(node);\n\n\t\t\tif (function == null || function.Method == null || function.Method.MetadataToken.IsNil)\n\t\t\t\treturn;\n\t\t\tthis.functions.Add(function);\n\t\t\tvar method = function.MoveNextMethod ?? function.Method;\n\t\t\tMethodDefinitionHandle handle = (MethodDefinitionHandle)method.MetadataToken;\n\t\t\tvar file = typeSystem.MainModule.MetadataFile;\n\t\t\tMethodDefinition md = file.Metadata.GetMethodDefinition(handle);\n\t\t\tif (md.HasBody())\n\t\t\t{\n\t\t\t\tHandleMethodBody(function, file.GetMethodBody(md.RelativeVirtualAddress));\n\t\t\t}\n\t\t}\n\n\t\tvoid HandleMethodBody(ILFunction function, MethodBodyBlock methodBody)\n\t\t{\n\t\t\tvar method = function.MoveNextMethod ?? function.Method;\n\t\t\tvar localVariables = new HashSet<ILVariable>(ILVariableKeyComparer);\n\n\t\t\tif (!methodBody.LocalSignature.IsNil)\n\t\t\t{\n#if DEBUG\n\t\t\t\tvar types = typeSystem.MainModule.DecodeLocalSignature(methodBody.LocalSignature,\n\t\t\t\t\tnew TypeSystem.GenericContext(method));\n#endif\n\n\t\t\t\tforeach (var v in function.Variables)\n\t\t\t\t{\n\t\t\t\t\tif (v.Index != null && v.Kind.IsLocal())\n\t\t\t\t\t{\n#if DEBUG\n\t\t\t\t\t\tDebug.Assert(v.Index < types.Length && NormalizeTypeVisitor.TypeErasure.EquivalentTypes(v.Type, types[v.Index.Value]));\n#endif\n\t\t\t\t\t\tlocalVariables.Add(v);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tLocalScopes.Add(((MethodDefinitionHandle)method.MetadataToken, currentImportScope,\n\t\t\t\t0, methodBody.GetCodeSize(), localVariables));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/DebugInfo/IDebugInfoProvider.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler.DebugInfo\n{\n\tpublic struct Variable\n\t{\n\t\tpublic Variable(int index, string name)\n\t\t{\n\t\t\tIndex = index;\n\t\t\tName = name;\n\t\t}\n\n\t\tpublic int Index { get; }\n\t\tpublic string Name { get; }\n\t}\n\n\tpublic struct PdbExtraTypeInfo\n\t{\n\t\tpublic string[] TupleElementNames;\n\t\tpublic bool[] DynamicFlags;\n\t}\n\n\tpublic interface IDebugInfoProvider\n\t{\n\t\tstring Description { get; }\n\t\tIList<SequencePoint> GetSequencePoints(MethodDefinitionHandle method);\n\t\tIList<Variable> GetVariables(MethodDefinitionHandle method);\n\t\tbool TryGetName(MethodDefinitionHandle method, int index, out string name);\n\t\tbool TryGetExtraTypeInfo(MethodDefinitionHandle method, int index, out PdbExtraTypeInfo extraTypeInfo);\n\t\tstring SourceFileName { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/DebugInfo/ImportScopeInfo.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.DebugInfo\n{\n\tclass ImportScopeInfo\n\t{\n\t\tpublic readonly ImportScopeInfo Parent;\n\t\tpublic ImportScopeHandle Handle;\n\t\tpublic readonly HashSet<string> Imports = new HashSet<string>();\n\n\t\tpublic ImportScopeInfo()\n\t\t{\n\t\t\tParent = null;\n\t\t}\n\n\t\tpublic ImportScopeInfo(ImportScopeInfo parent)\n\t\t{\n\t\t\tParent = parent;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/DebugInfo/KnownGuids.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler.DebugInfo\n{\n\tpublic static class KnownGuids\n\t{\n\t\tpublic static readonly Guid CSharpLanguageGuid = new Guid(\"3f5162f8-07c6-11d3-9053-00c04fa302a1\");\n\t\tpublic static readonly Guid VBLanguageGuid = new Guid(\"3a12d0b8-c26c-11d0-b442-00a0244a1dd2\");\n\t\tpublic static readonly Guid FSharpLanguageGuid = new Guid(\"ab4f38c9-b6e6-43ba-be3b-58080b2ccce3\");\n\n\t\t// https://github.com/dotnet/roslyn/blob/main/src/Dependencies/CodeAnalysis.Debugging/PortableCustomDebugInfoKinds.cs\n\t\tpublic static readonly Guid StateMachineHoistedLocalScopes = new Guid(\"6DA9A61E-F8C7-4874-BE62-68BC5630DF71\");\n\t\tpublic static readonly Guid DynamicLocalVariables = new Guid(\"83C563C4-B4F3-47D5-B824-BA5441477EA8\");\n\t\tpublic static readonly Guid DefaultNamespaces = new Guid(\"58b2eab6-209f-4e4e-a22c-b2d0f910c782\");\n\t\tpublic static readonly Guid EditAndContinueLocalSlotMap = new Guid(\"755F52A8-91C5-45BE-B4B8-209571E552BD\");\n\t\tpublic static readonly Guid EditAndContinueLambdaAndClosureMap = new Guid(\"A643004C-0240-496F-A783-30D64F4979DE\");\n\t\tpublic static readonly Guid EncStateMachineStateMap = new Guid(\"8B78CD68-2EDE-420B-980B-E15884B8AAA3\");\n\t\tpublic static readonly Guid EmbeddedSource = new Guid(\"0e8a571b-6926-466e-b4ad-8ab04611f5fe\");\n\t\tpublic static readonly Guid SourceLink = new Guid(\"CC110556-A091-4D38-9FEC-25AB9A351A6A\");\n\t\tpublic static readonly Guid MethodSteppingInformation = new Guid(\"54FD2AC5-E925-401A-9C2A-F94F171072F8\");\n\t\tpublic static readonly Guid CompilationOptions = new Guid(\"B5FEEC05-8CD0-4A83-96DA-466284BB4BD8\");\n\t\tpublic static readonly Guid CompilationMetadataReferences = new Guid(\"7E4D4708-096E-4C5C-AEDA-CB10BA6A740D\");\n\t\tpublic static readonly Guid TupleElementNames = new Guid(\"ED9FDF71-8879-4747-8ED3-FE5EDE3CE710\");\n\t\tpublic static readonly Guid TypeDefinitionDocuments = new Guid(\"932E74BC-DBA9-4478-8D46-0F32A7BAB3D3\");\n\n\t\tpublic static readonly Guid HashAlgorithmSHA1 = new Guid(\"ff1816ec-aa5e-4d10-87f7-6f4963833460\");\n\t\tpublic static readonly Guid HashAlgorithmSHA256 = new Guid(\"8829d00f-11b8-4213-878b-770e8597ac16\");\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.IO;\nusing System.IO.Compression;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Reflection.PortableExecutable;\nusing System.Security.Cryptography;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\nusing ICSharpCode.Decompiler.CSharp.ProjectDecompiler;\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.CSharp.Transforms;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.DebugInfo\n{\n\tpublic class PortablePdbWriter\n\t{\n\t\tconst string decompilerVersion = DecompilerVersionInfo.Version;\n\n\t\tpublic static bool HasCodeViewDebugDirectoryEntry(PEFile file)\n\t\t{\n\t\t\treturn file != null && file.Reader.ReadDebugDirectory().Any(entry => entry.Type == DebugDirectoryEntryType.CodeView);\n\t\t}\n\n\t\tprivate static bool IncludeTypeWhenGeneratingPdb(PEFile module, TypeDefinitionHandle type, DecompilerSettings settings)\n\t\t{\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar typeDef = metadata.GetTypeDefinition(type);\n\t\t\tstring name = metadata.GetString(typeDef.Name);\n\t\t\tstring ns = metadata.GetString(typeDef.Namespace);\n\t\t\tif (name == \"<Module>\" || CSharpDecompiler.MemberIsHidden(module, type, settings))\n\t\t\t\treturn false;\n\t\t\tif (ns == \"XamlGeneratedNamespace\" && name == \"GeneratedInternalTypeHelper\")\n\t\t\t\treturn false;\n\t\t\tif (!typeDef.IsNested && RemoveEmbeddedAttributes.attributeNames.Contains(ns + \".\" + name))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic static void WritePdb(\n\t\t\tPEFile file,\n\t\t\tCSharpDecompiler decompiler,\n\t\t\tDecompilerSettings settings,\n\t\t\tStream targetStream,\n\t\t\tbool noLogo = false,\n\t\t\tBlobContentId? pdbId = null,\n\t\t\tIProgress<DecompilationProgress> progress = null,\n\t\t\tstring currentProgressTitle = \"Generating portable PDB...\")\n\t\t{\n\t\t\tMetadataBuilder metadata = new MetadataBuilder();\n\t\t\tMetadataReader reader = file.Metadata;\n\t\t\tvar entrypointHandle = MetadataTokens.MethodDefinitionHandle(file.Reader.PEHeaders.CorHeader.EntryPointTokenOrRelativeVirtualAddress);\n\n\t\t\tvar sequencePointBlobs = new Dictionary<MethodDefinitionHandle, (DocumentHandle Document, BlobHandle SequencePoints)>();\n\t\t\tvar emptyList = new List<SequencePoint>();\n\t\t\tvar localScopes = new List<(MethodDefinitionHandle Method, ImportScopeInfo Import, int Offset, int Length, HashSet<ILVariable> Locals)>();\n\t\t\tvar stateMachineMethods = new List<(MethodDefinitionHandle MoveNextMethod, MethodDefinitionHandle KickoffMethod)>();\n\t\t\tvar customDebugInfo = new List<(EntityHandle Parent, GuidHandle Guid, BlobHandle Blob)>();\n\t\t\tvar customMethodDebugInfo = new List<(MethodDefinitionHandle Parent, GuidHandle Guid, BlobHandle Blob)>();\n\t\t\tvar globalImportScope = metadata.AddImportScope(default, default);\n\n\t\t\tstring BuildFileNameFromTypeName(TypeDefinitionHandle handle)\n\t\t\t{\n\t\t\t\tvar typeName = handle.GetFullTypeName(reader).TopLevelTypeName;\n\t\t\t\tstring ns = settings.UseNestedDirectoriesForNamespaces\n\t\t\t\t\t? WholeProjectDecompiler.CleanUpPath(typeName.Namespace)\n\t\t\t\t\t: WholeProjectDecompiler.CleanUpDirectoryName(typeName.Namespace);\n\t\t\t\treturn Path.Combine(ns, WholeProjectDecompiler.CleanUpFileName(typeName.Name, \".cs\"));\n\t\t\t}\n\n\t\t\tvar sourceFiles = reader.GetTopLevelTypeDefinitions().Where(t => IncludeTypeWhenGeneratingPdb(file, t, settings)).GroupBy(BuildFileNameFromTypeName).ToList();\n\t\t\tDecompilationProgress currentProgress = new() {\n\t\t\t\tTotalUnits = sourceFiles.Count,\n\t\t\t\tUnitsCompleted = 0,\n\t\t\t\tTitle = currentProgressTitle\n\t\t\t};\n\n\t\t\tforeach (var sourceFile in sourceFiles)\n\t\t\t{\n\t\t\t\t// Generate syntax tree\n\t\t\t\tvar syntaxTree = decompiler.DecompileTypes(sourceFile);\n\n\t\t\t\tif (progress != null)\n\t\t\t\t{\n\t\t\t\t\tcurrentProgress.UnitsCompleted++;\n\t\t\t\t\tprogress.Report(currentProgress);\n\t\t\t\t}\n\n\t\t\t\tif (!syntaxTree.HasChildren)\n\t\t\t\t\tcontinue;\n\n\t\t\t\t// Generate source and checksum\n\t\t\t\tif (!noLogo)\n\t\t\t\t\tsyntaxTree.InsertChildAfter(null, new Comment(\" PDB and source generated by ICSharpCode.Decompiler \" + decompilerVersion), Roles.Comment);\n\t\t\t\tvar sourceText = SyntaxTreeToString(syntaxTree, settings);\n\n\t\t\t\t// Generate sequence points for the syntax tree\n\t\t\t\tvar sequencePoints = decompiler.CreateSequencePoints(syntaxTree);\n\n\t\t\t\t// Generate other debug information\n\t\t\t\tvar debugInfoGen = new DebugInfoGenerator(decompiler.TypeSystem);\n\t\t\t\tsyntaxTree.AcceptVisitor(debugInfoGen);\n\n\t\t\t\tlock (metadata)\n\t\t\t\t{\n\t\t\t\t\tvar sourceBlob = WriteSourceToBlob(metadata, sourceText, out var sourceCheckSum);\n\t\t\t\t\tvar name = metadata.GetOrAddDocumentName(sourceFile.Key);\n\n\t\t\t\t\t// Create Document(Handle)\n\t\t\t\t\tvar document = metadata.AddDocument(name,\n\t\t\t\t\t\thashAlgorithm: metadata.GetOrAddGuid(KnownGuids.HashAlgorithmSHA256),\n\t\t\t\t\t\thash: metadata.GetOrAddBlob(sourceCheckSum),\n\t\t\t\t\t\tlanguage: metadata.GetOrAddGuid(KnownGuids.CSharpLanguageGuid));\n\n\t\t\t\t\t// Add embedded source to the PDB\n\t\t\t\t\tcustomDebugInfo.Add((document,\n\t\t\t\t\t\tmetadata.GetOrAddGuid(KnownGuids.EmbeddedSource),\n\t\t\t\t\t\tsourceBlob));\n\n\t\t\t\t\tdebugInfoGen.GenerateImportScopes(metadata, globalImportScope);\n\n\t\t\t\t\tlocalScopes.AddRange(debugInfoGen.LocalScopes);\n\n\t\t\t\t\tforeach (var function in debugInfoGen.Functions)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar method = function.MoveNextMethod ?? function.Method;\n\t\t\t\t\t\tvar methodHandle = (MethodDefinitionHandle)method.MetadataToken;\n\t\t\t\t\t\tsequencePoints.TryGetValue(function, out var points);\n\t\t\t\t\t\tProcessMethod(methodHandle, document, points, syntaxTree);\n\t\t\t\t\t\tif (function.MoveNextMethod != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstateMachineMethods.Add((\n\t\t\t\t\t\t\t\t(MethodDefinitionHandle)function.MoveNextMethod.MetadataToken,\n\t\t\t\t\t\t\t\t(MethodDefinitionHandle)function.Method.MetadataToken\n\t\t\t\t\t\t\t));\n\t\t\t\t\t\t\tcustomDebugInfo.Add((\n\t\t\t\t\t\t\t\tfunction.MoveNextMethod.MetadataToken,\n\t\t\t\t\t\t\t\tmetadata.GetOrAddGuid(KnownGuids.StateMachineHoistedLocalScopes),\n\t\t\t\t\t\t\t\tmetadata.GetOrAddBlob(BuildStateMachineHoistedLocalScopes(function))\n\t\t\t\t\t\t\t));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (function.IsAsync)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcustomMethodDebugInfo.Add((methodHandle,\n\t\t\t\t\t\t\t\tmetadata.GetOrAddGuid(KnownGuids.MethodSteppingInformation),\n\t\t\t\t\t\t\t\tmetadata.GetOrAddBlob(function.AsyncDebugInfo.BuildBlob(methodHandle))));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach (var method in reader.MethodDefinitions)\n\t\t\t{\n\t\t\t\tvar md = reader.GetMethodDefinition(method);\n\n\t\t\t\tif (sequencePointBlobs.TryGetValue(method, out var info))\n\t\t\t\t{\n\t\t\t\t\tmetadata.AddMethodDebugInformation(info.Document, info.SequencePoints);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tmetadata.AddMethodDebugInformation(default, default);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlocalScopes.Sort((x, y) => {\n\t\t\t\tif (x.Method != y.Method)\n\t\t\t\t{\n\t\t\t\t\treturn MetadataTokens.GetRowNumber(x.Method) - MetadataTokens.GetRowNumber(y.Method);\n\t\t\t\t}\n\t\t\t\tif (x.Offset != y.Offset)\n\t\t\t\t{\n\t\t\t\t\treturn x.Offset - y.Offset;\n\t\t\t\t}\n\t\t\t\treturn y.Length - x.Length;\n\t\t\t});\n\t\t\tforeach (var localScope in localScopes)\n\t\t\t{\n\t\t\t\tint nextRow = metadata.GetRowCount(TableIndex.LocalVariable) + 1;\n\t\t\t\tvar firstLocalVariable = MetadataTokens.LocalVariableHandle(nextRow);\n\n\t\t\t\tforeach (var local in localScope.Locals.OrderBy(l => l.Index))\n\t\t\t\t{\n\t\t\t\t\tvar localVarName = local.Name != null ? metadata.GetOrAddString(local.Name) : default;\n\t\t\t\t\tmetadata.AddLocalVariable(LocalVariableAttributes.None, local.Index.Value, localVarName);\n\t\t\t\t}\n\n\t\t\t\tmetadata.AddLocalScope(localScope.Method, localScope.Import.Handle, firstLocalVariable,\n\t\t\t\t\tdefault, localScope.Offset, localScope.Length);\n\t\t\t}\n\n\t\t\tstateMachineMethods.SortBy(row => MetadataTokens.GetRowNumber(row.MoveNextMethod));\n\t\t\tforeach (var row in stateMachineMethods)\n\t\t\t{\n\t\t\t\tmetadata.AddStateMachineMethod(row.MoveNextMethod, row.KickoffMethod);\n\t\t\t}\n\t\t\tcustomMethodDebugInfo.SortBy(row => MetadataTokens.GetRowNumber(row.Parent));\n\t\t\tforeach (var row in customMethodDebugInfo)\n\t\t\t{\n\t\t\t\tmetadata.AddCustomDebugInformation(row.Parent, row.Guid, row.Blob);\n\t\t\t}\n\t\t\tcustomDebugInfo.SortBy(row => MetadataTokens.GetRowNumber(row.Parent));\n\t\t\tforeach (var row in customDebugInfo)\n\t\t\t{\n\t\t\t\tmetadata.AddCustomDebugInformation(row.Parent, row.Guid, row.Blob);\n\t\t\t}\n\n\t\t\tif (pdbId == null)\n\t\t\t{\n\t\t\t\tvar debugDir = file.Reader.ReadDebugDirectory().LastOrDefault(dir => dir.Type == DebugDirectoryEntryType.CodeView);\n\t\t\t\tvar portable = file.Reader.ReadCodeViewDebugDirectoryData(debugDir);\n\t\t\t\tDebug.Assert(!portable.Path.EndsWith(\".ni.pdb\"));\n\t\t\t\tpdbId = new BlobContentId(portable.Guid, debugDir.Stamp);\n\t\t\t}\n\n\t\t\tPortablePdbBuilder serializer = new PortablePdbBuilder(metadata, GetRowCounts(reader), entrypointHandle, blobs => pdbId.Value);\n\t\t\tBlobBuilder blobBuilder = new BlobBuilder();\n\t\t\tserializer.Serialize(blobBuilder);\n\t\t\tblobBuilder.WriteContentTo(targetStream);\n\n\t\t\tvoid ProcessMethod(MethodDefinitionHandle method, DocumentHandle document,\n\t\t\t\tList<SequencePoint> sequencePoints, SyntaxTree syntaxTree)\n\t\t\t{\n\t\t\t\tvar methodDef = reader.GetMethodDefinition(method);\n\t\t\t\tint localSignatureRowId;\n\t\t\t\tMethodBodyBlock methodBody;\n\t\t\t\tif (methodDef.RelativeVirtualAddress != 0)\n\t\t\t\t{\n\t\t\t\t\tmethodBody = file.Reader.GetMethodBody(methodDef.RelativeVirtualAddress);\n\t\t\t\t\tlocalSignatureRowId = methodBody.LocalSignature.IsNil ? 0 : MetadataTokens.GetRowNumber(methodBody.LocalSignature);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tmethodBody = null;\n\t\t\t\t\tlocalSignatureRowId = 0;\n\t\t\t\t}\n\n\t\t\t\t// Check if sequence points were already processed - ILFunction gets defined in C# twice:\n\t\t\t\t// This may happen if a compiler-generated function gets transformed into a lambda expression,\n\t\t\t\t// but its method definition is not removed from the syntax tree.\n\t\t\t\tif (!sequencePointBlobs.ContainsKey(method))\n\t\t\t\t{\n\t\t\t\t\tif (sequencePoints?.Count > 0)\n\t\t\t\t\t\tsequencePointBlobs.Add(method, (document, EncodeSequencePoints(metadata, localSignatureRowId, sequencePoints)));\n\t\t\t\t\telse\n\t\t\t\t\t\tsequencePointBlobs.Add(method, (default, default));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(false, \"Duplicate sequence point definition detected: \" + MetadataTokens.GetToken(method).ToString(\"X8\"));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic BlobBuilder BuildStateMachineHoistedLocalScopes(ILFunction function)\n\t\t{\n\t\t\tvar builder = new BlobBuilder();\n\t\t\tforeach (var variable in function.Variables.Where(v => v.StateMachineField != null).OrderBy(v => MetadataTokens.GetRowNumber(v.StateMachineField.MetadataToken)))\n\t\t\t{\n\t\t\t\tbuilder.WriteUInt32(0);\n\t\t\t\tbuilder.WriteUInt32((uint)function.CodeSize);\n\t\t\t}\n\t\t\treturn builder;\n\t\t}\n\n\t\tstatic BlobHandle WriteSourceToBlob(MetadataBuilder metadata, string sourceText, out byte[] sourceCheckSum)\n\t\t{\n\t\t\tvar builder = new BlobBuilder();\n\t\t\tusing (var memory = new MemoryStream())\n\t\t\t{\n\t\t\t\tvar deflate = new DeflateStream(memory, CompressionLevel.Optimal, leaveOpen: true);\n\t\t\t\tbyte[] bytes = Encoding.UTF8.GetBytes(sourceText);\n\t\t\t\tdeflate.Write(bytes, 0, bytes.Length);\n\t\t\t\tdeflate.Close();\n\t\t\t\tbyte[] buffer = memory.ToArray();\n\t\t\t\tbuilder.WriteInt32(bytes.Length); // compressed\n\t\t\t\tbuilder.WriteBytes(buffer);\n\t\t\t\tusing (var hasher = SHA256.Create())\n\t\t\t\t{\n\t\t\t\t\tsourceCheckSum = hasher.ComputeHash(bytes);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn metadata.GetOrAddBlob(builder);\n\t\t}\n\n\t\tstatic BlobHandle EncodeSequencePoints(MetadataBuilder metadata, int localSignatureRowId, List<SequencePoint> sequencePoints)\n\t\t{\n\t\t\tif (sequencePoints.Count == 0)\n\t\t\t\treturn default;\n\t\t\tvar writer = new BlobBuilder();\n\t\t\t// header:\n\t\t\twriter.WriteCompressedInteger(localSignatureRowId);\n\n\t\t\tint previousOffset = -1;\n\t\t\tint previousStartLine = -1;\n\t\t\tint previousStartColumn = -1;\n\n\t\t\tfor (int i = 0; i < sequencePoints.Count; i++)\n\t\t\t{\n\t\t\t\tvar sequencePoint = sequencePoints[i];\n\t\t\t\t// delta IL offset:\n\t\t\t\tif (i > 0)\n\t\t\t\t\twriter.WriteCompressedInteger(sequencePoint.Offset - previousOffset);\n\t\t\t\telse\n\t\t\t\t\twriter.WriteCompressedInteger(sequencePoint.Offset);\n\t\t\t\tpreviousOffset = sequencePoint.Offset;\n\n\t\t\t\tif (sequencePoint.IsHidden)\n\t\t\t\t{\n\t\t\t\t\twriter.WriteInt16(0);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tint lineDelta = sequencePoint.EndLine - sequencePoint.StartLine;\n\t\t\t\tint columnDelta = sequencePoint.EndColumn - sequencePoint.StartColumn;\n\n\t\t\t\twriter.WriteCompressedInteger(lineDelta);\n\n\t\t\t\tif (lineDelta == 0)\n\t\t\t\t{\n\t\t\t\t\twriter.WriteCompressedInteger(columnDelta);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\twriter.WriteCompressedSignedInteger(columnDelta);\n\t\t\t\t}\n\n\t\t\t\tif (previousStartLine < 0)\n\t\t\t\t{\n\t\t\t\t\twriter.WriteCompressedInteger(sequencePoint.StartLine);\n\t\t\t\t\twriter.WriteCompressedInteger(sequencePoint.StartColumn);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\twriter.WriteCompressedSignedInteger(sequencePoint.StartLine - previousStartLine);\n\t\t\t\t\twriter.WriteCompressedSignedInteger(sequencePoint.StartColumn - previousStartColumn);\n\t\t\t\t}\n\n\t\t\t\tpreviousStartLine = sequencePoint.StartLine;\n\t\t\t\tpreviousStartColumn = sequencePoint.StartColumn;\n\t\t\t}\n\n\t\t\treturn metadata.GetOrAddBlob(writer);\n\t\t}\n\n\t\tstatic ImmutableArray<int> GetRowCounts(MetadataReader reader)\n\t\t{\n\t\t\tvar builder = ImmutableArray.CreateBuilder<int>(MetadataTokens.TableCount);\n\t\t\tfor (int i = 0; i < MetadataTokens.TableCount; i++)\n\t\t\t{\n\t\t\t\tbuilder.Add(reader.GetTableRowCount((TableIndex)i));\n\t\t\t}\n\n\t\t\treturn builder.MoveToImmutable();\n\t\t}\n\n\t\tstatic string SyntaxTreeToString(SyntaxTree syntaxTree, DecompilerSettings settings)\n\t\t{\n\t\t\tStringWriter w = new StringWriter();\n\t\t\tTokenWriter tokenWriter = new TextWriterTokenWriter(w);\n\t\t\ttokenWriter = TokenWriter.WrapInWriterThatSetsLocationsInAST(tokenWriter);\n\t\t\tsyntaxTree.AcceptVisitor(new CSharpOutputVisitor(tokenWriter, settings.CSharpFormattingOptions));\n\t\t\treturn w.ToString();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/DebugInfo/SequencePoint.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\n\nnamespace ICSharpCode.Decompiler.DebugInfo\n{\n\t/// <summary>\n\t/// A sequence point read from a PDB file or produced by the decompiler.\n\t/// </summary>\n\t[DebuggerDisplay(\"SequencePoint IL_{Offset,h}-IL_{EndOffset,h}, {StartLine}:{StartColumn}-{EndLine}:{EndColumn}, IsHidden={IsHidden}\")]\n\tpublic class SequencePoint\n\t{\n\t\t/// <summary>\n\t\t/// IL start offset.\n\t\t/// </summary>\n\t\tpublic int Offset { get; set; }\n\n\t\t/// <summary>\n\t\t/// IL end offset.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This does not get stored in debug information;\n\t\t/// it is used internally to create hidden sequence points\n\t\t/// for the IL fragments not covered by any sequence point.\n\t\t/// </remarks>\n\t\tpublic int EndOffset { get; set; }\n\n\t\tpublic int StartLine { get; set; }\n\t\tpublic int StartColumn { get; set; }\n\t\tpublic int EndLine { get; set; }\n\t\tpublic int EndColumn { get; set; }\n\n\t\tpublic bool IsHidden {\n\t\t\tget { return StartLine == 0xfeefee && StartLine == EndLine; }\n\t\t}\n\n\t\tpublic string DocumentUrl { get; set; }\n\n\t\tinternal void SetHidden()\n\t\t{\n\t\t\tStartLine = EndLine = 0xfeefee;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/DecompilationProgress.cs",
    "content": "// Copyright (c) 2022 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nnamespace ICSharpCode.Decompiler\n{\n\t/// <summary>\n\t/// Information used for (optional) progress reporting by the decompiler.\n\t/// </summary>\n\tpublic struct DecompilationProgress\n\t{\n\t\t/// <summary>\n\t\t/// The total number of units to process. If set to a value &lt;= 0, an indeterminate progress bar is displayed.\n\t\t/// </summary>\n\t\tpublic int TotalUnits;\n\n\t\t/// <summary>\n\t\t/// The number of units currently completed. Should be a positive number.\n\t\t/// </summary>\n\t\tpublic int UnitsCompleted;\n\n\t\t/// <summary>\n\t\t/// Optional information displayed alongside the progress bar.\n\t\t/// </summary>\n\t\tpublic string? Status;\n\n\t\t/// <summary>\n\t\t/// Optional custom title for the operation.\n\t\t/// </summary>\n\t\tpublic string? Title;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/DecompileRun.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.Documentation;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler\n{\n\tinternal class DecompileRun\n\t{\n\t\tpublic HashSet<string> DefinedSymbols { get; } = new HashSet<string>();\n\t\tpublic HashSet<string> Namespaces { get; set; }\n\t\tpublic CancellationToken CancellationToken { get; set; }\n\t\tpublic DecompilerSettings Settings { get; }\n\t\tpublic IDocumentationProvider DocumentationProvider { get; set; }\n\t\tpublic Dictionary<ITypeDefinition, RecordDecompiler> RecordDecompilers { get; } = new Dictionary<ITypeDefinition, RecordDecompiler>();\n\n\t\tpublic Dictionary<ITypeDefinition, bool> TypeHierarchyIsKnown { get; } = new();\n\n\t\tpublic CSharp.TypeSystem.UsingScope UsingScope { get; }\n\n\t\tpublic DecompileRun(DecompilerSettings settings, CSharp.TypeSystem.UsingScope usingScope)\n\t\t{\n\t\t\tthis.Settings = settings ?? throw new ArgumentNullException(nameof(settings));\n\t\t\tthis.UsingScope = usingScope ?? throw new ArgumentNullException(nameof(usingScope));\n\t\t}\n\t}\n\n\tenum EnumValueDisplayMode\n\t{\n\t\tNone,\n\t\tAll,\n\t\tAllHex,\n\t\tFirstOnly\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/DecompilerException.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Reflection;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Runtime.InteropServices;\nusing System.Runtime.Serialization;\nusing System.Security;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler\n{\n\t/// <summary>\n\t/// Description of DecompilerException.\n\t/// </summary>\n\tpublic class DecompilerException : Exception, ISerializable\n\t{\n\t\tpublic string AssemblyName => File.Name;\n\n\t\tpublic string FileName => File.FileName;\n\n\t\tpublic IEntity DecompiledEntity { get; }\n\t\tpublic IModule Module { get; }\n\t\tpublic MetadataFile File { get; }\n\n\t\tpublic DecompilerException(MetadataModule module, IEntity decompiledEntity,\n\t\t\tException innerException, string message = null)\n\t\t\t: base(message ?? GetDefaultMessage(decompiledEntity), innerException)\n\t\t{\n\t\t\tthis.File = module.MetadataFile;\n\t\t\tthis.Module = module;\n\t\t\tthis.DecompiledEntity = decompiledEntity;\n\t\t}\n\n\t\tpublic DecompilerException(MetadataFile file, string message, Exception innerException)\n\t\t\t: base(message, innerException)\n\t\t{\n\t\t\tthis.File = file;\n\t\t}\n\n\t\tstatic string GetDefaultMessage(IEntity entity)\n\t\t{\n\t\t\tif (entity == null)\n\t\t\t\treturn \"Error decompiling\";\n\t\t\treturn $\"Error decompiling @{MetadataTokens.GetToken(entity.MetadataToken):X8} {entity.FullName}\";\n\t\t}\n\n\t\t// This constructor is needed for serialization.\n\t\tprotected DecompilerException(SerializationInfo info, StreamingContext context) : base(info, context)\n\t\t{\n\t\t}\n\n\t\tpublic override string StackTrace => GetStackTrace(this);\n\n\t\tpublic override string ToString() => ToString(this);\n\n\t\tstring ToString(Exception exception)\n\t\t{\n\t\t\tif (exception == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(exception));\n\t\t\tstring exceptionType = GetTypeName(exception);\n\t\t\tstring stacktrace = GetStackTrace(exception);\n\t\t\twhile (exception.InnerException != null)\n\t\t\t{\n\t\t\t\texception = exception.InnerException;\n\n\t\t\t\tstacktrace = GetStackTrace(exception) + Environment.NewLine\n\t\t\t\t\t+ \"-- continuing with outer exception (\" + exceptionType + \") --\" + Environment.NewLine\n\t\t\t\t\t+ stacktrace;\n\t\t\t\texceptionType = GetTypeName(exception);\n\t\t\t}\n\t\t\treturn this.Message + Environment.NewLine\n\t\t\t\t+ $\"in assembly \\\"{this.FileName}\\\"\" + Environment.NewLine\n\t\t\t\t+ \" ---> \" + exceptionType + \": \" + exception.Message + Environment.NewLine\n\t\t\t\t+ stacktrace;\n\t\t}\n\n\t\tstatic string GetTypeName(Exception exception)\n\t\t{\n\t\t\tstring type = exception.GetType().FullName;\n\t\t\tif (exception is ExternalException || exception is IOException)\n\t\t\t\treturn type + \" (\" + Marshal.GetHRForException(exception).ToString(\"x8\") + \")\";\n\t\t\telse\n\t\t\t\treturn type;\n\t\t}\n\n\t\tstatic string GetStackTrace(Exception exception)\n\t\t{\n\t\t\t// Output stacktrace in custom format (very similar to Exception.StackTrace\n\t\t\t// property on English systems).\n\t\t\t// Include filenames where available, but no paths.\n\t\t\tStackTrace stackTrace = new StackTrace(exception, true);\n\t\t\tStringBuilder b = new StringBuilder();\n\t\t\tfor (int i = 0; i < stackTrace.FrameCount; i++)\n\t\t\t{\n\t\t\t\tStackFrame frame = stackTrace.GetFrame(i);\n\t\t\t\tMethodBase method = frame.GetMethod();\n\t\t\t\tif (method == null)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (b.Length > 0)\n\t\t\t\t\tb.AppendLine();\n\n\t\t\t\tb.Append(\"   at \");\n\t\t\t\tType declaringType = method.DeclaringType;\n\t\t\t\tif (declaringType != null)\n\t\t\t\t{\n\t\t\t\t\tb.Append(declaringType.FullName.Replace('+', '.'));\n\t\t\t\t\tb.Append('.');\n\t\t\t\t}\n\t\t\t\tb.Append(method.Name);\n\t\t\t\t// output type parameters, if any\n\t\t\t\tif ((method is MethodInfo) && ((MethodInfo)method).IsGenericMethod)\n\t\t\t\t{\n\t\t\t\t\tType[] genericArguments = ((MethodInfo)method).GetGenericArguments();\n\t\t\t\t\tb.Append('[');\n\t\t\t\t\tfor (int j = 0; j < genericArguments.Length; j++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (j > 0)\n\t\t\t\t\t\t\tb.Append(',');\n\t\t\t\t\t\tb.Append(genericArguments[j].Name);\n\t\t\t\t\t}\n\t\t\t\t\tb.Append(']');\n\t\t\t\t}\n\n\t\t\t\t// output parameters, if any\n\t\t\t\tb.Append('(');\n\t\t\t\tParameterInfo[] parameters = method.GetParameters();\n\t\t\t\tfor (int j = 0; j < parameters.Length; j++)\n\t\t\t\t{\n\t\t\t\t\tif (j > 0)\n\t\t\t\t\t\tb.Append(\", \");\n\t\t\t\t\tif (parameters[j].ParameterType != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tb.Append(parameters[j].ParameterType.Name);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tb.Append('?');\n\t\t\t\t\t}\n\t\t\t\t\tif (!string.IsNullOrEmpty(parameters[j].Name))\n\t\t\t\t\t{\n\t\t\t\t\t\tb.Append(' ');\n\t\t\t\t\t\tb.Append(parameters[j].Name);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tb.Append(')');\n\n\t\t\t\t// source location\n\t\t\t\tif (frame.GetILOffset() >= 0)\n\t\t\t\t{\n\t\t\t\t\tstring filename = null;\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tstring fullpath = frame.GetFileName();\n\t\t\t\t\t\tif (fullpath != null)\n\t\t\t\t\t\t\tfilename = Path.GetFileName(fullpath);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (SecurityException)\n\t\t\t\t\t{\n\t\t\t\t\t\t// StackFrame.GetFileName requires PathDiscovery permission\n\t\t\t\t\t}\n\t\t\t\t\tcatch (ArgumentException)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Path.GetFileName might throw on paths with invalid chars\n\t\t\t\t\t}\n\t\t\t\t\tb.Append(\" in \");\n\t\t\t\t\tif (filename != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tb.Append(filename);\n\t\t\t\t\t\tb.Append(\":line \");\n\t\t\t\t\t\tb.Append(frame.GetFileLineNumber());\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tb.Append(\"offset \");\n\t\t\t\t\t\tb.Append(frame.GetILOffset());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn b.ToString();\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler/DecompilerSettings.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.ComponentModel;\nusing System.Runtime.CompilerServices;\n\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\n\nnamespace ICSharpCode.Decompiler\n{\n\t/// <summary>\n\t/// Settings for the decompiler.\n\t/// </summary>\n\tpublic class DecompilerSettings : INotifyPropertyChanged\n\t{\n\t\t/// <summary>\n\t\t/// Equivalent to <c>new DecompilerSettings(LanguageVersion.Latest)</c>\n\t\t/// </summary>\n\t\tpublic DecompilerSettings()\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a new DecompilerSettings instance with initial settings\n\t\t/// appropriate for the specified language version.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This does not imply that the resulting code strictly uses only language features from\n\t\t/// that version. Language constructs like generics or ref locals cannot be removed from\n\t\t/// the compiled code.\n\t\t/// </remarks>\n\t\tpublic DecompilerSettings(CSharp.LanguageVersion languageVersion)\n\t\t{\n\t\t\tSetLanguageVersion(languageVersion);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Deactivates all language features from versions newer than <paramref name=\"languageVersion\"/>.\n\t\t/// </summary>\n\t\tpublic void SetLanguageVersion(CSharp.LanguageVersion languageVersion)\n\t\t{\n\t\t\t// By default, all decompiler features are enabled.\n\t\t\t// Disable some of them based on language version:\n\t\t\tif (languageVersion < CSharp.LanguageVersion.CSharp2)\n\t\t\t{\n\t\t\t\tanonymousMethods = false;\n\t\t\t\tliftNullables = false;\n\t\t\t\tyieldReturn = false;\n\t\t\t\tuseImplicitMethodGroupConversion = false;\n\t\t\t\tuseObjectCreationOfGenericTypeParameter = false;\n\t\t\t}\n\t\t\tif (languageVersion < CSharp.LanguageVersion.CSharp3)\n\t\t\t{\n\t\t\t\tanonymousTypes = false;\n\t\t\t\tuseLambdaSyntax = false;\n\t\t\t\tobjectCollectionInitializers = false;\n\t\t\t\tautomaticProperties = false;\n\t\t\t\textensionMethods = false;\n\t\t\t\tqueryExpressions = false;\n\t\t\t\texpressionTrees = false;\n\t\t\t}\n\t\t\tif (languageVersion < CSharp.LanguageVersion.CSharp4)\n\t\t\t{\n\t\t\t\tdynamic = false;\n\t\t\t\tnamedArguments = false;\n\t\t\t\toptionalArguments = false;\n\t\t\t}\n\t\t\tif (languageVersion < CSharp.LanguageVersion.CSharp5)\n\t\t\t{\n\t\t\t\tasyncAwait = false;\n\t\t\t}\n\t\t\tif (languageVersion < CSharp.LanguageVersion.CSharp6)\n\t\t\t{\n\t\t\t\tawaitInCatchFinally = false;\n\t\t\t\tuseExpressionBodyForCalculatedGetterOnlyProperties = false;\n\t\t\t\tnullPropagation = false;\n\t\t\t\tstringInterpolation = false;\n\t\t\t\tdictionaryInitializers = false;\n\t\t\t\textensionMethodsInCollectionInitializers = false;\n\t\t\t\tgetterOnlyAutomaticProperties = false;\n\t\t\t}\n\t\t\tif (languageVersion < CSharp.LanguageVersion.CSharp7)\n\t\t\t{\n\t\t\t\toutVariables = false;\n\t\t\t\tthrowExpressions = false;\n\t\t\t\ttupleTypes = false;\n\t\t\t\ttupleConversions = false;\n\t\t\t\tdiscards = false;\n\t\t\t\tlocalFunctions = false;\n\t\t\t\tdeconstruction = false;\n\t\t\t\tpatternMatching = false;\n\t\t\t\tuseRefLocalsForAccurateOrderOfEvaluation = false;\n\t\t\t}\n\t\t\tif (languageVersion < CSharp.LanguageVersion.CSharp7_2)\n\t\t\t{\n\t\t\t\tintroduceReadonlyAndInModifiers = false;\n\t\t\t\tintroduceRefModifiersOnStructs = false;\n\t\t\t\tnonTrailingNamedArguments = false;\n\t\t\t\trefExtensionMethods = false;\n\t\t\t\tintroducePrivateProtectedAccessibilty = false;\n\t\t\t}\n\t\t\tif (languageVersion < CSharp.LanguageVersion.CSharp7_3)\n\t\t\t{\n\t\t\t\tintroduceUnmanagedConstraint = false;\n\t\t\t\tstackAllocInitializers = false;\n\t\t\t\ttupleComparisons = false;\n\t\t\t\tpatternBasedFixedStatement = false;\n\t\t\t}\n\t\t\tif (languageVersion < CSharp.LanguageVersion.CSharp8_0)\n\t\t\t{\n\t\t\t\tnullableReferenceTypes = false;\n\t\t\t\treadOnlyMethods = false;\n\t\t\t\tasyncUsingAndForEachStatement = false;\n\t\t\t\tasyncEnumerator = false;\n\t\t\t\tuseEnhancedUsing = false;\n\t\t\t\tstaticLocalFunctions = false;\n\t\t\t\tranges = false;\n\t\t\t\tswitchExpressions = false;\n\t\t\t\trecursivePatternMatching = false;\n\t\t\t}\n\t\t\tif (languageVersion < CSharp.LanguageVersion.CSharp9_0)\n\t\t\t{\n\t\t\t\tnativeIntegers = false;\n\t\t\t\tinitAccessors = false;\n\t\t\t\tfunctionPointers = false;\n\t\t\t\tforEachWithGetEnumeratorExtension = false;\n\t\t\t\trecordClasses = false;\n\t\t\t\twithExpressions = false;\n\t\t\t\tusePrimaryConstructorSyntax = false;\n\t\t\t\tcovariantReturns = false;\n\t\t\t\trelationalPatterns = false;\n\t\t\t\tpatternCombinators = false;\n\t\t\t}\n\t\t\tif (languageVersion < CSharp.LanguageVersion.CSharp10_0)\n\t\t\t{\n\t\t\t\tfileScopedNamespaces = false;\n\t\t\t\trecordStructs = false;\n\t\t\t\tstructDefaultConstructorsAndFieldInitializers = false;\n\t\t\t}\n\t\t\tif (languageVersion < CSharp.LanguageVersion.CSharp11_0)\n\t\t\t{\n\t\t\t\tscopedRef = false;\n\t\t\t\trequiredMembers = false;\n\t\t\t\tnumericIntPtr = false;\n\t\t\t\tutf8StringLiterals = false;\n\t\t\t\tunsignedRightShift = false;\n\t\t\t\tcheckedOperators = false;\n\t\t\t}\n\t\t\tif (languageVersion < CSharp.LanguageVersion.CSharp12_0)\n\t\t\t{\n\t\t\t\trefReadOnlyParameters = false;\n\t\t\t\tusePrimaryConstructorSyntaxForNonRecordTypes = false;\n\t\t\t\tinlineArrays = false;\n\t\t\t}\n\t\t\tif (languageVersion < CSharp.LanguageVersion.CSharp13_0)\n\t\t\t{\n\t\t\t\tparamsCollections = false;\n\t\t\t}\n\t\t\tif (languageVersion < CSharp.LanguageVersion.CSharp14_0)\n\t\t\t{\n\t\t\t\textensionMembers = false;\n\t\t\t\tfirstClassSpanTypes = false;\n\t\t\t}\n\t\t}\n\n\t\tpublic CSharp.LanguageVersion GetMinimumRequiredVersion()\n\t\t{\n\t\t\tif (extensionMembers || firstClassSpanTypes)\n\t\t\t\treturn CSharp.LanguageVersion.CSharp14_0;\n\t\t\tif (paramsCollections)\n\t\t\t\treturn CSharp.LanguageVersion.CSharp13_0;\n\t\t\tif (refReadOnlyParameters || usePrimaryConstructorSyntaxForNonRecordTypes || inlineArrays)\n\t\t\t\treturn CSharp.LanguageVersion.CSharp12_0;\n\t\t\tif (scopedRef || requiredMembers || numericIntPtr || utf8StringLiterals || unsignedRightShift || checkedOperators)\n\t\t\t\treturn CSharp.LanguageVersion.CSharp11_0;\n\t\t\tif (fileScopedNamespaces || recordStructs || structDefaultConstructorsAndFieldInitializers)\n\t\t\t\treturn CSharp.LanguageVersion.CSharp10_0;\n\t\t\tif (nativeIntegers || initAccessors || functionPointers || forEachWithGetEnumeratorExtension\n\t\t\t\t|| recordClasses || withExpressions || usePrimaryConstructorSyntax || covariantReturns\n\t\t\t\t|| relationalPatterns || patternCombinators)\n\t\t\t\treturn CSharp.LanguageVersion.CSharp9_0;\n\t\t\tif (nullableReferenceTypes || readOnlyMethods || asyncEnumerator || asyncUsingAndForEachStatement\n\t\t\t\t|| staticLocalFunctions || ranges || switchExpressions || recursivePatternMatching)\n\t\t\t\treturn CSharp.LanguageVersion.CSharp8_0;\n\t\t\tif (introduceUnmanagedConstraint || tupleComparisons || stackAllocInitializers\n\t\t\t\t|| patternBasedFixedStatement)\n\t\t\t\treturn CSharp.LanguageVersion.CSharp7_3;\n\t\t\tif (introduceRefModifiersOnStructs || introduceReadonlyAndInModifiers\n\t\t\t\t|| nonTrailingNamedArguments || refExtensionMethods || introducePrivateProtectedAccessibilty)\n\t\t\t\treturn CSharp.LanguageVersion.CSharp7_2;\n\t\t\t// C# 7.1 missing\n\t\t\tif (outVariables || throwExpressions || tupleTypes || tupleConversions\n\t\t\t\t|| discards || localFunctions || deconstruction || patternMatching || useRefLocalsForAccurateOrderOfEvaluation)\n\t\t\t\treturn CSharp.LanguageVersion.CSharp7;\n\t\t\tif (awaitInCatchFinally || useExpressionBodyForCalculatedGetterOnlyProperties || nullPropagation\n\t\t\t\t|| stringInterpolation || dictionaryInitializers || extensionMethodsInCollectionInitializers\n\t\t\t\t|| getterOnlyAutomaticProperties)\n\t\t\t\treturn CSharp.LanguageVersion.CSharp6;\n\t\t\tif (asyncAwait)\n\t\t\t\treturn CSharp.LanguageVersion.CSharp5;\n\t\t\tif (dynamic || namedArguments || optionalArguments)\n\t\t\t\treturn CSharp.LanguageVersion.CSharp4;\n\t\t\tif (anonymousTypes || objectCollectionInitializers || automaticProperties\n\t\t\t\t|| queryExpressions || expressionTrees)\n\t\t\t\treturn CSharp.LanguageVersion.CSharp3;\n\t\t\tif (anonymousMethods || liftNullables || yieldReturn || useImplicitMethodGroupConversion || useObjectCreationOfGenericTypeParameter)\n\t\t\t\treturn CSharp.LanguageVersion.CSharp2;\n\t\t\treturn CSharp.LanguageVersion.CSharp1;\n\t\t}\n\n\t\tbool nativeIntegers = true;\n\n\t\t/// <summary>\n\t\t/// Use C# 9 <c>nint</c>/<c>nuint</c> types.\n\t\t/// </summary>\n\t\t[Category(\"C# 9.0 / VS 2019.8\")]\n\t\t[Description(\"DecompilerSettings.NativeIntegers\")]\n\t\tpublic bool NativeIntegers {\n\t\t\tget { return nativeIntegers; }\n\t\t\tset {\n\t\t\t\tif (nativeIntegers != value)\n\t\t\t\t{\n\t\t\t\t\tnativeIntegers = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool numericIntPtr = true;\n\n\t\t/// <summary>\n\t\t/// Treat <c>IntPtr</c>/<c>UIntPtr</c> as <c>nint</c>/<c>nuint</c>.\n\t\t/// </summary>\n\t\t[Category(\"C# 11.0 / VS 2022.4\")]\n\t\t[Description(\"DecompilerSettings.NumericIntPtr\")]\n\t\tpublic bool NumericIntPtr {\n\t\t\tget { return numericIntPtr; }\n\t\t\tset {\n\t\t\t\tif (numericIntPtr != value)\n\t\t\t\t{\n\t\t\t\t\tnumericIntPtr = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool covariantReturns = true;\n\n\t\t/// <summary>\n\t\t/// Decompile C# 9 covariant return types.\n\t\t/// </summary>\n\t\t[Category(\"C# 9.0 / VS 2019.8\")]\n\t\t[Description(\"DecompilerSettings.CovariantReturns\")]\n\t\tpublic bool CovariantReturns {\n\t\t\tget { return covariantReturns; }\n\t\t\tset {\n\t\t\t\tif (covariantReturns != value)\n\t\t\t\t{\n\t\t\t\t\tcovariantReturns = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool initAccessors = true;\n\n\t\t/// <summary>\n\t\t/// Use C# 9 <c>init;</c> property accessors.\n\t\t/// </summary>\n\t\t[Category(\"C# 9.0 / VS 2019.8\")]\n\t\t[Description(\"DecompilerSettings.InitAccessors\")]\n\t\tpublic bool InitAccessors {\n\t\t\tget { return initAccessors; }\n\t\t\tset {\n\t\t\t\tif (initAccessors != value)\n\t\t\t\t{\n\t\t\t\t\tinitAccessors = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool recordClasses = true;\n\n\t\t/// <summary>\n\t\t/// Use C# 9 <c>record</c> classes.\n\t\t/// </summary>\n\t\t[Category(\"C# 9.0 / VS 2019.8\")]\n\t\t[Description(\"DecompilerSettings.RecordClasses\")]\n\t\tpublic bool RecordClasses {\n\t\t\tget { return recordClasses; }\n\t\t\tset {\n\t\t\t\tif (recordClasses != value)\n\t\t\t\t{\n\t\t\t\t\trecordClasses = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool recordStructs = true;\n\n\t\t/// <summary>\n\t\t/// Use C# 10 <c>record</c> structs.\n\t\t/// </summary>\n\t\t[Category(\"C# 10.0 / VS 2022\")]\n\t\t[Description(\"DecompilerSettings.RecordStructs\")]\n\t\tpublic bool RecordStructs {\n\t\t\tget { return recordStructs; }\n\t\t\tset {\n\t\t\t\tif (recordStructs != value)\n\t\t\t\t{\n\t\t\t\t\trecordStructs = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool structDefaultConstructorsAndFieldInitializers = true;\n\n\t\t/// <summary>\n\t\t/// Use field initializers in structs.\n\t\t/// </summary>\n\t\t[Category(\"C# 10.0 / VS 2022\")]\n\t\t[Description(\"DecompilerSettings.StructDefaultConstructorsAndFieldInitializers\")]\n\t\tpublic bool StructDefaultConstructorsAndFieldInitializers {\n\t\t\tget { return structDefaultConstructorsAndFieldInitializers; }\n\t\t\tset {\n\t\t\t\tif (structDefaultConstructorsAndFieldInitializers != value)\n\t\t\t\t{\n\t\t\t\t\tstructDefaultConstructorsAndFieldInitializers = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool withExpressions = true;\n\n\t\t/// <summary>\n\t\t/// Use C# 9 <c>with</c> initializer expressions.\n\t\t/// </summary>\n\t\t[Category(\"C# 9.0 / VS 2019.8\")]\n\t\t[Description(\"DecompilerSettings.WithExpressions\")]\n\t\tpublic bool WithExpressions {\n\t\t\tget { return withExpressions; }\n\t\t\tset {\n\t\t\t\tif (withExpressions != value)\n\t\t\t\t{\n\t\t\t\t\twithExpressions = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool usePrimaryConstructorSyntax = true;\n\n\t\t/// <summary>\n\t\t/// Use primary constructor syntax with records.\n\t\t/// </summary>\n\t\t[Category(\"C# 9.0 / VS 2019.8\")]\n\t\t[Description(\"DecompilerSettings.UsePrimaryConstructorSyntax\")]\n\t\tpublic bool UsePrimaryConstructorSyntax {\n\t\t\tget { return usePrimaryConstructorSyntax; }\n\t\t\tset {\n\t\t\t\tif (usePrimaryConstructorSyntax != value)\n\t\t\t\t{\n\t\t\t\t\tusePrimaryConstructorSyntax = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool functionPointers = true;\n\n\t\t/// <summary>\n\t\t/// Use C# 9 <c>delegate* unmanaged</c> types.\n\t\t/// If this option is disabled, function pointers will instead be decompiled with type `IntPtr`.\n\t\t/// </summary>\n\t\t[Category(\"C# 9.0 / VS 2019.8\")]\n\t\t[Description(\"DecompilerSettings.FunctionPointers\")]\n\t\tpublic bool FunctionPointers {\n\t\t\tget { return functionPointers; }\n\t\t\tset {\n\t\t\t\tif (functionPointers != value)\n\t\t\t\t{\n\t\t\t\t\tfunctionPointers = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool scopedRef = true;\n\n\t\t/// <summary>\n\t\t/// Use C# 11 <c>scoped</c> modifier.\n\t\t/// </summary>\n\t\t[Category(\"C# 11.0 / VS 2022.4\")]\n\t\t[Description(\"DecompilerSettings.ScopedRef\")]\n\t\tpublic bool ScopedRef {\n\t\t\tget { return scopedRef; }\n\t\t\tset {\n\t\t\t\tif (scopedRef != value)\n\t\t\t\t{\n\t\t\t\t\tscopedRef = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t[Obsolete(\"Renamed to ScopedRef. This property will be removed in a future version of the decompiler.\")]\n\t\t[Browsable(false)]\n\t\tpublic bool LifetimeAnnotations {\n\t\t\tget { return ScopedRef; }\n\t\t\tset { ScopedRef = value; }\n\t\t}\n\n\t\tbool requiredMembers = true;\n\n\t\t/// <summary>\n\t\t/// Use C# 11 <c>required</c> modifier.\n\t\t/// </summary>\n\t\t[Category(\"C# 11.0 / VS 2022.4\")]\n\t\t[Description(\"DecompilerSettings.RequiredMembers\")]\n\t\tpublic bool RequiredMembers {\n\t\t\tget { return requiredMembers; }\n\t\t\tset {\n\t\t\t\tif (requiredMembers != value)\n\t\t\t\t{\n\t\t\t\t\trequiredMembers = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool switchExpressions = true;\n\n\t\t/// <summary>\n\t\t/// Use C# 8 switch expressions.\n\t\t/// </summary>\n\t\t[Category(\"C# 8.0 / VS 2019\")]\n\t\t[Description(\"DecompilerSettings.SwitchExpressions\")]\n\t\tpublic bool SwitchExpressions {\n\t\t\tget { return switchExpressions; }\n\t\t\tset {\n\t\t\t\tif (switchExpressions != value)\n\t\t\t\t{\n\t\t\t\t\tswitchExpressions = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool fileScopedNamespaces = true;\n\n\t\t/// <summary>\n\t\t/// Use C# 10 file-scoped namespaces.\n\t\t/// </summary>\n\t\t[Category(\"C# 10.0 / VS 2022\")]\n\t\t[Description(\"DecompilerSettings.FileScopedNamespaces\")]\n\t\tpublic bool FileScopedNamespaces {\n\t\t\tget { return fileScopedNamespaces; }\n\t\t\tset {\n\t\t\t\tif (fileScopedNamespaces != value)\n\t\t\t\t{\n\t\t\t\t\tfileScopedNamespaces = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool anonymousMethods = true;\n\n\t\t/// <summary>\n\t\t/// Decompile anonymous methods/lambdas.\n\t\t/// </summary>\n\t\t[Category(\"C# 2.0 / VS 2005\")]\n\t\t[Description(\"DecompilerSettings.DecompileAnonymousMethodsLambdas\")]\n\t\tpublic bool AnonymousMethods {\n\t\t\tget { return anonymousMethods; }\n\t\t\tset {\n\t\t\t\tif (anonymousMethods != value)\n\t\t\t\t{\n\t\t\t\t\tanonymousMethods = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool anonymousTypes = true;\n\n\t\t/// <summary>\n\t\t/// Decompile anonymous types.\n\t\t/// </summary>\n\t\t[Category(\"C# 3.0 / VS 2008\")]\n\t\t[Description(\"DecompilerSettings.DecompileAnonymousTypes\")]\n\t\tpublic bool AnonymousTypes {\n\t\t\tget { return anonymousTypes; }\n\t\t\tset {\n\t\t\t\tif (anonymousTypes != value)\n\t\t\t\t{\n\t\t\t\t\tanonymousTypes = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool useLambdaSyntax = true;\n\n\t\t/// <summary>\n\t\t/// Use C# 3 lambda syntax if possible.\n\t\t/// </summary>\n\t\t[Category(\"C# 3.0 / VS 2008\")]\n\t\t[Description(\"DecompilerSettings.UseLambdaSyntaxIfPossible\")]\n\t\tpublic bool UseLambdaSyntax {\n\t\t\tget { return useLambdaSyntax; }\n\t\t\tset {\n\t\t\t\tif (useLambdaSyntax != value)\n\t\t\t\t{\n\t\t\t\t\tuseLambdaSyntax = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool expressionTrees = true;\n\n\t\t/// <summary>\n\t\t/// Decompile expression trees.\n\t\t/// </summary>\n\t\t[Category(\"C# 3.0 / VS 2008\")]\n\t\t[Description(\"DecompilerSettings.DecompileExpressionTrees\")]\n\t\tpublic bool ExpressionTrees {\n\t\t\tget { return expressionTrees; }\n\t\t\tset {\n\t\t\t\tif (expressionTrees != value)\n\t\t\t\t{\n\t\t\t\t\texpressionTrees = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool yieldReturn = true;\n\n\t\t/// <summary>\n\t\t/// Decompile enumerators.\n\t\t/// </summary>\n\t\t[Category(\"C# 2.0 / VS 2005\")]\n\t\t[Description(\"DecompilerSettings.DecompileEnumeratorsYieldReturn\")]\n\t\tpublic bool YieldReturn {\n\t\t\tget { return yieldReturn; }\n\t\t\tset {\n\t\t\t\tif (yieldReturn != value)\n\t\t\t\t{\n\t\t\t\t\tyieldReturn = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool dynamic = true;\n\n\t\t/// <summary>\n\t\t/// Decompile use of the 'dynamic' type.\n\t\t/// </summary>\n\t\t[Category(\"C# 4.0 / VS 2010\")]\n\t\t[Description(\"DecompilerSettings.DecompileUseOfTheDynamicType\")]\n\t\tpublic bool Dynamic {\n\t\t\tget { return dynamic; }\n\t\t\tset {\n\t\t\t\tif (dynamic != value)\n\t\t\t\t{\n\t\t\t\t\tdynamic = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool asyncAwait = true;\n\n\t\t/// <summary>\n\t\t/// Decompile async methods.\n\t\t/// </summary>\n\t\t[Category(\"C# 5.0 / VS 2012\")]\n\t\t[Description(\"DecompilerSettings.DecompileAsyncMethods\")]\n\t\tpublic bool AsyncAwait {\n\t\t\tget { return asyncAwait; }\n\t\t\tset {\n\t\t\t\tif (asyncAwait != value)\n\t\t\t\t{\n\t\t\t\t\tasyncAwait = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool awaitInCatchFinally = true;\n\n\t\t/// <summary>\n\t\t/// Decompile await in catch/finally blocks.\n\t\t/// Only has an effect if <see cref=\"AsyncAwait\"/> is enabled.\n\t\t/// </summary>\n\t\t[Category(\"C# 6.0 / VS 2015\")]\n\t\t[Description(\"DecompilerSettings.DecompileAwaitInCatchFinallyBlocks\")]\n\t\tpublic bool AwaitInCatchFinally {\n\t\t\tget { return awaitInCatchFinally; }\n\t\t\tset {\n\t\t\t\tif (awaitInCatchFinally != value)\n\t\t\t\t{\n\t\t\t\t\tawaitInCatchFinally = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool asyncEnumerator = true;\n\n\t\t/// <summary>\n\t\t/// Decompile IAsyncEnumerator/IAsyncEnumerable.\n\t\t/// Only has an effect if <see cref=\"AsyncAwait\"/> is enabled.\n\t\t/// </summary>\n\t\t[Category(\"C# 8.0 / VS 2019\")]\n\t\t[Description(\"DecompilerSettings.AsyncEnumerator\")]\n\t\tpublic bool AsyncEnumerator {\n\t\t\tget { return asyncEnumerator; }\n\t\t\tset {\n\t\t\t\tif (asyncEnumerator != value)\n\t\t\t\t{\n\t\t\t\t\tasyncEnumerator = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool decimalConstants = true;\n\n\t\t/// <summary>\n\t\t/// Decompile [DecimalConstant(...)] as simple literal values.\n\t\t/// </summary>\n\t\t[Category(\"C# 1.0 / VS .NET\")]\n\t\t[Description(\"DecompilerSettings.DecompileDecimalConstantAsSimpleLiteralValues\")]\n\t\tpublic bool DecimalConstants {\n\t\t\tget { return decimalConstants; }\n\t\t\tset {\n\t\t\t\tif (decimalConstants != value)\n\t\t\t\t{\n\t\t\t\t\tdecimalConstants = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool fixedBuffers = true;\n\n\t\t/// <summary>\n\t\t/// Decompile C# 1.0 'public unsafe fixed int arr[10];' members.\n\t\t/// </summary>\n\t\t[Category(\"C# 1.0 / VS .NET\")]\n\t\t[Description(\"DecompilerSettings.DecompileC10PublicUnsafeFixedIntArr10Members\")]\n\t\tpublic bool FixedBuffers {\n\t\t\tget { return fixedBuffers; }\n\t\t\tset {\n\t\t\t\tif (fixedBuffers != value)\n\t\t\t\t{\n\t\t\t\t\tfixedBuffers = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool stringConcat = true;\n\n\t\t/// <summary>\n\t\t/// Decompile 'string.Concat(a, b)' calls into 'a + b'.\n\t\t/// </summary>\n\t\t[Category(\"C# 1.0 / VS .NET\")]\n\t\t[Description(\"DecompilerSettings.StringConcat\")]\n\t\tpublic bool StringConcat {\n\t\t\tget { return stringConcat; }\n\t\t\tset {\n\t\t\t\tif (stringConcat != value)\n\t\t\t\t{\n\t\t\t\t\tstringConcat = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool liftNullables = true;\n\n\t\t/// <summary>\n\t\t/// Use lifted operators for nullables.\n\t\t/// </summary>\n\t\t[Category(\"C# 2.0 / VS 2005\")]\n\t\t[Description(\"DecompilerSettings.UseLiftedOperatorsForNullables\")]\n\t\tpublic bool LiftNullables {\n\t\t\tget { return liftNullables; }\n\t\t\tset {\n\t\t\t\tif (liftNullables != value)\n\t\t\t\t{\n\t\t\t\t\tliftNullables = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool nullPropagation = true;\n\n\t\t/// <summary>\n\t\t/// Decompile C# 6 ?. and ?[] operators.\n\t\t/// </summary>\n\t\t[Category(\"C# 6.0 / VS 2015\")]\n\t\t[Description(\"DecompilerSettings.NullPropagation\")]\n\t\tpublic bool NullPropagation {\n\t\t\tget { return nullPropagation; }\n\t\t\tset {\n\t\t\t\tif (nullPropagation != value)\n\t\t\t\t{\n\t\t\t\t\tnullPropagation = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool automaticProperties = true;\n\n\t\t/// <summary>\n\t\t/// Decompile automatic properties\n\t\t/// </summary>\n\t\t[Category(\"C# 3.0 / VS 2008\")]\n\t\t[Description(\"DecompilerSettings.DecompileAutomaticProperties\")]\n\t\tpublic bool AutomaticProperties {\n\t\t\tget { return automaticProperties; }\n\t\t\tset {\n\t\t\t\tif (automaticProperties != value)\n\t\t\t\t{\n\t\t\t\t\tautomaticProperties = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool getterOnlyAutomaticProperties = true;\n\n\t\t/// <summary>\n\t\t/// Decompile getter-only automatic properties\n\t\t/// </summary>\n\t\t[Category(\"C# 6.0 / VS 2015\")]\n\t\t[Description(\"DecompilerSettings.GetterOnlyAutomaticProperties\")]\n\t\tpublic bool GetterOnlyAutomaticProperties {\n\t\t\tget { return getterOnlyAutomaticProperties; }\n\t\t\tset {\n\t\t\t\tif (getterOnlyAutomaticProperties != value)\n\t\t\t\t{\n\t\t\t\t\tgetterOnlyAutomaticProperties = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool automaticEvents = true;\n\n\t\t/// <summary>\n\t\t/// Decompile automatic events\n\t\t/// </summary>\n\t\t[Category(\"C# 1.0 / VS .NET\")]\n\t\t[Description(\"DecompilerSettings.DecompileAutomaticEvents\")]\n\t\tpublic bool AutomaticEvents {\n\t\t\tget { return automaticEvents; }\n\t\t\tset {\n\t\t\t\tif (automaticEvents != value)\n\t\t\t\t{\n\t\t\t\t\tautomaticEvents = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool usingStatement = true;\n\n\t\t/// <summary>\n\t\t/// Decompile using statements.\n\t\t/// </summary>\n\t\t[Category(\"C# 1.0 / VS .NET\")]\n\t\t[Description(\"DecompilerSettings.DetectUsingStatements\")]\n\t\tpublic bool UsingStatement {\n\t\t\tget { return usingStatement; }\n\t\t\tset {\n\t\t\t\tif (usingStatement != value)\n\t\t\t\t{\n\t\t\t\t\tusingStatement = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool useEnhancedUsing = true;\n\n\t\t/// <summary>\n\t\t/// Use enhanced using statements.\n\t\t/// </summary>\n\t\t[Category(\"C# 8.0 / VS 2019\")]\n\t\t[Description(\"DecompilerSettings.UseEnhancedUsing\")]\n\t\tpublic bool UseEnhancedUsing {\n\t\t\tget { return useEnhancedUsing; }\n\t\t\tset {\n\t\t\t\tif (useEnhancedUsing != value)\n\t\t\t\t{\n\t\t\t\t\tuseEnhancedUsing = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool alwaysUseBraces = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to use braces for single-statement-blocks. \n\t\t/// </summary>\n\t\t[Category(\"DecompilerSettings.Other\")]\n\t\t[Description(\"DecompilerSettings.AlwaysUseBraces\")]\n\t\tpublic bool AlwaysUseBraces {\n\t\t\tget { return alwaysUseBraces; }\n\t\t\tset {\n\t\t\t\tif (alwaysUseBraces != value)\n\t\t\t\t{\n\t\t\t\t\talwaysUseBraces = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool forEachStatement = true;\n\n\t\t/// <summary>\n\t\t/// Decompile foreach statements.\n\t\t/// </summary>\n\t\t[Category(\"C# 1.0 / VS .NET\")]\n\t\t[Description(\"DecompilerSettings.DetectForeachStatements\")]\n\t\tpublic bool ForEachStatement {\n\t\t\tget { return forEachStatement; }\n\t\t\tset {\n\t\t\t\tif (forEachStatement != value)\n\t\t\t\t{\n\t\t\t\t\tforEachStatement = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool forEachWithGetEnumeratorExtension = true;\n\n\t\t/// <summary>\n\t\t/// Support GetEnumerator extension methods in foreach.\n\t\t/// </summary>\n\t\t[Category(\"C# 9.0 / VS 2019.8\")]\n\t\t[Description(\"DecompilerSettings.DecompileForEachWithGetEnumeratorExtension\")]\n\t\tpublic bool ForEachWithGetEnumeratorExtension {\n\t\t\tget { return forEachWithGetEnumeratorExtension; }\n\t\t\tset {\n\t\t\t\tif (forEachWithGetEnumeratorExtension != value)\n\t\t\t\t{\n\t\t\t\t\tforEachWithGetEnumeratorExtension = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool paramsCollections = true;\n\n\t\t/// <summary>\n\t\t/// Support params collections.\n\t\t/// </summary>\n\t\t[Category(\"C# 13.0 / VS 2022.12\")]\n\t\t[Description(\"DecompilerSettings.DecompileParamsCollections\")]\n\t\tpublic bool ParamsCollections {\n\t\t\tget { return paramsCollections; }\n\t\t\tset {\n\t\t\t\tif (paramsCollections != value)\n\t\t\t\t{\n\t\t\t\t\tparamsCollections = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool lockStatement = true;\n\n\t\t/// <summary>\n\t\t/// Decompile lock statements.\n\t\t/// </summary>\n\t\t[Category(\"C# 1.0 / VS .NET\")]\n\t\t[Description(\"DecompilerSettings.DetectLockStatements\")]\n\t\tpublic bool LockStatement {\n\t\t\tget { return lockStatement; }\n\t\t\tset {\n\t\t\t\tif (lockStatement != value)\n\t\t\t\t{\n\t\t\t\t\tlockStatement = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool switchStatementOnString = true;\n\n\t\t[Category(\"C# 1.0 / VS .NET\")]\n\t\t[Description(\"DecompilerSettings.DetectSwitchOnString\")]\n\t\tpublic bool SwitchStatementOnString {\n\t\t\tget { return switchStatementOnString; }\n\t\t\tset {\n\t\t\t\tif (switchStatementOnString != value)\n\t\t\t\t{\n\t\t\t\t\tswitchStatementOnString = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool sparseIntegerSwitch = true;\n\n\t\t[Category(\"C# 1.0 / VS .NET\")]\n\t\t[Description(\"DecompilerSettings.SparseIntegerSwitch\")]\n\t\tpublic bool SparseIntegerSwitch {\n\t\t\tget { return sparseIntegerSwitch; }\n\t\t\tset {\n\t\t\t\tif (sparseIntegerSwitch != value)\n\t\t\t\t{\n\t\t\t\t\tsparseIntegerSwitch = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool usingDeclarations = true;\n\n\t\t[Category(\"C# 1.0 / VS .NET\")]\n\t\t[Description(\"DecompilerSettings.InsertUsingDeclarations\")]\n\t\tpublic bool UsingDeclarations {\n\t\t\tget { return usingDeclarations; }\n\t\t\tset {\n\t\t\t\tif (usingDeclarations != value)\n\t\t\t\t{\n\t\t\t\t\tusingDeclarations = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool extensionMethods = true;\n\n\t\t[Category(\"C# 3.0 / VS 2008\")]\n\t\t[Description(\"DecompilerSettings.UseExtensionMethodSyntax\")]\n\t\tpublic bool ExtensionMethods {\n\t\t\tget { return extensionMethods; }\n\t\t\tset {\n\t\t\t\tif (extensionMethods != value)\n\t\t\t\t{\n\t\t\t\t\textensionMethods = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool queryExpressions = true;\n\n\t\t[Category(\"C# 3.0 / VS 2008\")]\n\t\t[Description(\"DecompilerSettings.UseLINQExpressionSyntax\")]\n\t\tpublic bool QueryExpressions {\n\t\t\tget { return queryExpressions; }\n\t\t\tset {\n\t\t\t\tif (queryExpressions != value)\n\t\t\t\t{\n\t\t\t\t\tqueryExpressions = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool useImplicitMethodGroupConversion = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to use C# 2.0 method group conversions.\n\t\t/// true: <c>EventHandler h = this.OnClick;</c>\n\t\t/// false: <c>EventHandler h = new EventHandler(this.OnClick);</c>\n\t\t/// </summary>\n\t\t[Category(\"C# 2.0 / VS 2005\")]\n\t\t[Description(\"DecompilerSettings.UseImplicitMethodGroupConversions\")]\n\t\tpublic bool UseImplicitMethodGroupConversion {\n\t\t\tget { return useImplicitMethodGroupConversion; }\n\t\t\tset {\n\t\t\t\tif (useImplicitMethodGroupConversion != value)\n\t\t\t\t{\n\t\t\t\t\tuseImplicitMethodGroupConversion = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool useObjectCreationOfGenericTypeParameter = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to use object creation expressions for generic types with <c>new()</c> constraint.\n\t\t/// true: <c>T t = new T();</c>\n\t\t/// false: <c>T t = Activator.CreateInstance&lt;T&gt;()</c>\n\t\t/// </summary>\n\t\t[Category(\"C# 2.0 / VS 2005\")]\n\t\t[Description(\"DecompilerSettings.UseObjectCreationOfGenericTypeParameter\")]\n\t\tpublic bool UseObjectCreationOfGenericTypeParameter {\n\t\t\tget { return useObjectCreationOfGenericTypeParameter; }\n\t\t\tset {\n\t\t\t\tif (useObjectCreationOfGenericTypeParameter != value)\n\t\t\t\t{\n\t\t\t\t\tuseObjectCreationOfGenericTypeParameter = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool alwaysCastTargetsOfExplicitInterfaceImplementationCalls = false;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to always cast targets to explicitly implemented methods.\n\t\t/// true: <c>((ISupportInitialize)pictureBox1).BeginInit();</c>\n\t\t/// false: <c>pictureBox1.BeginInit();</c>\n\t\t/// default: false\n\t\t/// </summary>\n\t\t[Category(\"Other\")]\n\t\t[Description(\"DecompilerSettings.AlwaysCastTargetsOfExplicitInterfaceImplementationCalls\")]\n\t\tpublic bool AlwaysCastTargetsOfExplicitInterfaceImplementationCalls {\n\t\t\tget { return alwaysCastTargetsOfExplicitInterfaceImplementationCalls; }\n\t\t\tset {\n\t\t\t\tif (alwaysCastTargetsOfExplicitInterfaceImplementationCalls != value)\n\t\t\t\t{\n\t\t\t\t\talwaysCastTargetsOfExplicitInterfaceImplementationCalls = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool alwaysQualifyMemberReferences = false;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to always qualify member references.\n\t\t/// true: <c>this.DoSomething();</c>\n\t\t/// false: <c>DoSomething();</c>\n\t\t/// default: false\n\t\t/// </summary>\n\t\t[Category(\"Other\")]\n\t\t[Description(\"DecompilerSettings.AlwaysQualifyMemberReferences\")]\n\t\tpublic bool AlwaysQualifyMemberReferences {\n\t\t\tget { return alwaysQualifyMemberReferences; }\n\t\t\tset {\n\t\t\t\tif (alwaysQualifyMemberReferences != value)\n\t\t\t\t{\n\t\t\t\t\talwaysQualifyMemberReferences = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool alwaysShowEnumMemberValues = false;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to always show enum member values.\n\t\t/// true: <c>enum Kind { A = 0, B = 1, C = 5 }</c>\n\t\t/// false: <c>enum Kind { A, B, C = 5 }</c>\n\t\t/// default: false\n\t\t/// </summary>\n\t\t[Category(\"Other\")]\n\t\t[Description(\"DecompilerSettings.AlwaysShowEnumMemberValues\")]\n\t\tpublic bool AlwaysShowEnumMemberValues {\n\t\t\tget { return alwaysShowEnumMemberValues; }\n\t\t\tset {\n\t\t\t\tif (alwaysShowEnumMemberValues != value)\n\t\t\t\t{\n\t\t\t\t\talwaysShowEnumMemberValues = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool useDebugSymbols = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to use variable names from debug symbols, if available.\n\t\t/// </summary>\n\t\t[Category(\"Other\")]\n\t\t[Description(\"DecompilerSettings.UseVariableNamesFromDebugSymbolsIfAvailable\")]\n\t\tpublic bool UseDebugSymbols {\n\t\t\tget { return useDebugSymbols; }\n\t\t\tset {\n\t\t\t\tif (useDebugSymbols != value)\n\t\t\t\t{\n\t\t\t\t\tuseDebugSymbols = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool arrayInitializers = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to use array initializers.\n\t\t/// If set to false, might produce non-compilable code.\n\t\t/// </summary>\n\t\t[Category(\"C# 1.0 / VS .NET\")]\n\t\t[Description(\"DecompilerSettings.ArrayInitializerExpressions\")]\n\t\tpublic bool ArrayInitializers {\n\t\t\tget { return arrayInitializers; }\n\t\t\tset {\n\t\t\t\tif (arrayInitializers != value)\n\t\t\t\t{\n\t\t\t\t\tarrayInitializers = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool objectCollectionInitializers = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to use C# 3.0 object/collection initializers.\n\t\t/// </summary>\n\t\t[Category(\"C# 3.0 / VS 2008\")]\n\t\t[Description(\"DecompilerSettings.ObjectCollectionInitializerExpressions\")]\n\t\tpublic bool ObjectOrCollectionInitializers {\n\t\t\tget { return objectCollectionInitializers; }\n\t\t\tset {\n\t\t\t\tif (objectCollectionInitializers != value)\n\t\t\t\t{\n\t\t\t\t\tobjectCollectionInitializers = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool dictionaryInitializers = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to use C# 6.0 dictionary initializers.\n\t\t/// Only has an effect if ObjectOrCollectionInitializers is enabled.\n\t\t/// </summary>\n\t\t[Category(\"C# 6.0 / VS 2015\")]\n\t\t[Description(\"DecompilerSettings.DictionaryInitializerExpressions\")]\n\t\tpublic bool DictionaryInitializers {\n\t\t\tget { return dictionaryInitializers; }\n\t\t\tset {\n\t\t\t\tif (dictionaryInitializers != value)\n\t\t\t\t{\n\t\t\t\t\tdictionaryInitializers = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool extensionMethodsInCollectionInitializers = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to use C# 6.0 Extension Add methods in collection initializers.\n\t\t/// Only has an effect if ObjectOrCollectionInitializers is enabled.\n\t\t/// </summary>\n\t\t[Category(\"C# 6.0 / VS 2015\")]\n\t\t[Description(\"DecompilerSettings.AllowExtensionAddMethodsInCollectionInitializerExpressions\")]\n\t\tpublic bool ExtensionMethodsInCollectionInitializers {\n\t\t\tget { return extensionMethodsInCollectionInitializers; }\n\t\t\tset {\n\t\t\t\tif (extensionMethodsInCollectionInitializers != value)\n\t\t\t\t{\n\t\t\t\t\textensionMethodsInCollectionInitializers = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool useRefLocalsForAccurateOrderOfEvaluation = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to use local ref variables in cases where this is necessary\n\t\t/// for re-compilation with a modern C# compiler to reproduce the same behavior\n\t\t/// as the original assembly produced with an old C# compiler that used an incorrect\n\t\t/// order of evaluation.\n\t\t/// See https://github.com/icsharpcode/ILSpy/issues/2050\n\t\t/// </summary>\n\t\t[Category(\"C# 7.0 / VS 2017\")]\n\t\t[Description(\"DecompilerSettings.UseRefLocalsForAccurateOrderOfEvaluation\")]\n\t\tpublic bool UseRefLocalsForAccurateOrderOfEvaluation {\n\t\t\tget { return useRefLocalsForAccurateOrderOfEvaluation; }\n\t\t\tset {\n\t\t\t\tif (useRefLocalsForAccurateOrderOfEvaluation != value)\n\t\t\t\t{\n\t\t\t\t\tuseRefLocalsForAccurateOrderOfEvaluation = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool refExtensionMethods = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to use C# 7.2 'ref' extension methods.\n\t\t/// </summary>\n\t\t[Category(\"C# 7.2 / VS 2017.4\")]\n\t\t[Description(\"DecompilerSettings.AllowExtensionMethodSyntaxOnRef\")]\n\t\tpublic bool RefExtensionMethods {\n\t\t\tget { return refExtensionMethods; }\n\t\t\tset {\n\t\t\t\tif (refExtensionMethods != value)\n\t\t\t\t{\n\t\t\t\t\trefExtensionMethods = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool stringInterpolation = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to use C# 6.0 string interpolation\n\t\t/// </summary>\n\t\t[Category(\"C# 6.0 / VS 2015\")]\n\t\t[Description(\"DecompilerSettings.UseStringInterpolation\")]\n\t\tpublic bool StringInterpolation {\n\t\t\tget { return stringInterpolation; }\n\t\t\tset {\n\t\t\t\tif (stringInterpolation != value)\n\t\t\t\t{\n\t\t\t\t\tstringInterpolation = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool utf8StringLiterals = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to use C# 11.0 UTF-8 string literals\n\t\t/// </summary>\n\t\t[Category(\"C# 11.0 / VS 2022.4\")]\n\t\t[Description(\"DecompilerSettings.Utf8StringLiterals\")]\n\t\tpublic bool Utf8StringLiterals {\n\t\t\tget { return utf8StringLiterals; }\n\t\t\tset {\n\t\t\t\tif (utf8StringLiterals != value)\n\t\t\t\t{\n\t\t\t\t\tutf8StringLiterals = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool switchOnReadOnlySpanChar = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to use C# 11.0 switch on (ReadOnly)Span&lt;char&gt;\n\t\t/// </summary>\n\t\t[Category(\"C# 11.0 / VS 2022.4\")]\n\t\t[Description(\"DecompilerSettings.SwitchOnReadOnlySpanChar\")]\n\t\tpublic bool SwitchOnReadOnlySpanChar {\n\t\t\tget { return switchOnReadOnlySpanChar; }\n\t\t\tset {\n\t\t\t\tif (switchOnReadOnlySpanChar != value)\n\t\t\t\t{\n\t\t\t\t\tswitchOnReadOnlySpanChar = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool unsignedRightShift = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to use C# 11.0 unsigned right shift operator.\n\t\t/// </summary>\n\t\t[Category(\"C# 11.0 / VS 2022.4\")]\n\t\t[Description(\"DecompilerSettings.UnsignedRightShift\")]\n\t\tpublic bool UnsignedRightShift {\n\t\t\tget { return unsignedRightShift; }\n\t\t\tset {\n\t\t\t\tif (unsignedRightShift != value)\n\t\t\t\t{\n\t\t\t\t\tunsignedRightShift = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool checkedOperators = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to use C# 11.0 user-defined checked operators.\n\t\t/// </summary>\n\t\t[Category(\"C# 11.0 / VS 2022.4\")]\n\t\t[Description(\"DecompilerSettings.CheckedOperators\")]\n\t\tpublic bool CheckedOperators {\n\t\t\tget { return checkedOperators; }\n\t\t\tset {\n\t\t\t\tif (checkedOperators != value)\n\t\t\t\t{\n\t\t\t\t\tcheckedOperators = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool showXmlDocumentation = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to include XML documentation comments in the decompiled code.\n\t\t/// </summary>\n\t\t[Category(\"DecompilerSettings.Other\")]\n\t\t[Description(\"DecompilerSettings.IncludeXMLDocumentationCommentsInTheDecompiledCode\")]\n\t\tpublic bool ShowXmlDocumentation {\n\t\t\tget { return showXmlDocumentation; }\n\t\t\tset {\n\t\t\t\tif (showXmlDocumentation != value)\n\t\t\t\t{\n\t\t\t\t\tshowXmlDocumentation = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool foldBraces = false;\n\n\t\t[Browsable(false)]\n\t\tpublic bool FoldBraces {\n\t\t\tget { return foldBraces; }\n\t\t\tset {\n\t\t\t\tif (foldBraces != value)\n\t\t\t\t{\n\t\t\t\t\tfoldBraces = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool expandMemberDefinitions = false;\n\n\t\t[Browsable(false)]\n\t\tpublic bool ExpandMemberDefinitions {\n\t\t\tget { return expandMemberDefinitions; }\n\t\t\tset {\n\t\t\t\tif (expandMemberDefinitions != value)\n\t\t\t\t{\n\t\t\t\t\texpandMemberDefinitions = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool expandUsingDeclarations = false;\n\n\t\t[Browsable(false)]\n\t\tpublic bool ExpandUsingDeclarations {\n\t\t\tget { return expandUsingDeclarations; }\n\t\t\tset {\n\t\t\t\tif (expandUsingDeclarations != value)\n\t\t\t\t{\n\t\t\t\t\texpandUsingDeclarations = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool decompileMemberBodies = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether member bodies should be decompiled.\n\t\t/// </summary>\n\t\t[Category(\"DecompilerSettings.Other\")]\n\t\t[Browsable(false)]\n\t\tpublic bool DecompileMemberBodies {\n\t\t\tget { return decompileMemberBodies; }\n\t\t\tset {\n\t\t\t\tif (decompileMemberBodies != value)\n\t\t\t\t{\n\t\t\t\t\tdecompileMemberBodies = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool useExpressionBodyForCalculatedGetterOnlyProperties = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether simple calculated getter-only property declarations\n\t\t/// should use expression body syntax.\n\t\t/// </summary>\n\t\t[Category(\"C# 6.0 / VS 2015\")]\n\t\t[Description(\"DecompilerSettings.UseExpressionBodiedMemberSyntaxForGetOnlyProperties\")]\n\t\tpublic bool UseExpressionBodyForCalculatedGetterOnlyProperties {\n\t\t\tget { return useExpressionBodyForCalculatedGetterOnlyProperties; }\n\t\t\tset {\n\t\t\t\tif (useExpressionBodyForCalculatedGetterOnlyProperties != value)\n\t\t\t\t{\n\t\t\t\t\tuseExpressionBodyForCalculatedGetterOnlyProperties = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool outVariables = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether out variable declarations should be used when possible.\n\t\t/// </summary>\n\t\t[Category(\"C# 7.0 / VS 2017\")]\n\t\t[Description(\"DecompilerSettings.UseOutVariableDeclarations\")]\n\t\tpublic bool OutVariables {\n\t\t\tget { return outVariables; }\n\t\t\tset {\n\t\t\t\tif (outVariables != value)\n\t\t\t\t{\n\t\t\t\t\toutVariables = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool discards = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether discards should be used when possible.\n\t\t/// Only has an effect if <see cref=\"OutVariables\"/> is enabled.\n\t\t/// </summary>\n\t\t[Category(\"C# 7.0 / VS 2017\")]\n\t\t[Description(\"DecompilerSettings.UseDiscards\")]\n\t\tpublic bool Discards {\n\t\t\tget { return discards; }\n\t\t\tset {\n\t\t\t\tif (discards != value)\n\t\t\t\t{\n\t\t\t\t\tdiscards = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool introduceRefModifiersOnStructs = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether IsByRefLikeAttribute should be replaced with 'ref' modifiers on structs.\n\t\t/// </summary>\n\t\t[Category(\"C# 7.2 / VS 2017.4\")]\n\t\t[Description(\"DecompilerSettings.IsByRefLikeAttributeShouldBeReplacedWithRefModifiersOnStructs\")]\n\t\tpublic bool IntroduceRefModifiersOnStructs {\n\t\t\tget { return introduceRefModifiersOnStructs; }\n\t\t\tset {\n\t\t\t\tif (introduceRefModifiersOnStructs != value)\n\t\t\t\t{\n\t\t\t\t\tintroduceRefModifiersOnStructs = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool introduceReadonlyAndInModifiers = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether IsReadOnlyAttribute should be replaced with 'readonly' modifiers on structs\n\t\t/// and with the 'in' modifier on parameters.\n\t\t/// </summary>\n\t\t[Category(\"C# 7.2 / VS 2017.4\")]\n\t\t[Description(\"DecompilerSettings.\" +\n\t\t\t\"IsReadOnlyAttributeShouldBeReplacedWithReadonlyInModifiersOnStructsParameters\")]\n\t\tpublic bool IntroduceReadonlyAndInModifiers {\n\t\t\tget { return introduceReadonlyAndInModifiers; }\n\t\t\tset {\n\t\t\t\tif (introduceReadonlyAndInModifiers != value)\n\t\t\t\t{\n\t\t\t\t\tintroduceReadonlyAndInModifiers = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool introducePrivateProtectedAccessibilty = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether \"private protected\" should be used.\n\t\t/// </summary>\n\t\t[Category(\"C# 7.2 / VS 2017.4\")]\n\t\t[Description(\"DecompilerSettings.IntroducePrivateProtectedAccessibility\")]\n\t\tpublic bool IntroducePrivateProtectedAccessibility {\n\t\t\tget { return introducePrivateProtectedAccessibilty; }\n\t\t\tset {\n\t\t\t\tif (introducePrivateProtectedAccessibilty != value)\n\t\t\t\t{\n\t\t\t\t\tintroducePrivateProtectedAccessibilty = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool readOnlyMethods = true;\n\n\t\t[Category(\"C# 8.0 / VS 2019\")]\n\t\t[Description(\"DecompilerSettings.ReadOnlyMethods\")]\n\t\tpublic bool ReadOnlyMethods {\n\t\t\tget { return readOnlyMethods; }\n\t\t\tset {\n\t\t\t\tif (readOnlyMethods != value)\n\t\t\t\t{\n\t\t\t\t\treadOnlyMethods = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool asyncUsingAndForEachStatement = true;\n\n\t\t[Category(\"C# 8.0 / VS 2019\")]\n\t\t[Description(\"DecompilerSettings.DetectAsyncUsingAndForeachStatements\")]\n\t\tpublic bool AsyncUsingAndForEachStatement {\n\t\t\tget { return asyncUsingAndForEachStatement; }\n\t\t\tset {\n\t\t\t\tif (asyncUsingAndForEachStatement != value)\n\t\t\t\t{\n\t\t\t\t\tasyncUsingAndForEachStatement = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool introduceUnmanagedConstraint = true;\n\n\t\t/// <summary>\n\t\t/// If this option is active, [IsUnmanagedAttribute] on type parameters\n\t\t/// is replaced with \"T : unmanaged\" constraints.\n\t\t/// </summary>\n\t\t[Category(\"C# 7.3 / VS 2017.7\")]\n\t\t[Description(\"DecompilerSettings.\" +\n\t\t\t\"IsUnmanagedAttributeOnTypeParametersShouldBeReplacedWithUnmanagedConstraints\")]\n\t\tpublic bool IntroduceUnmanagedConstraint {\n\t\t\tget { return introduceUnmanagedConstraint; }\n\t\t\tset {\n\t\t\t\tif (introduceUnmanagedConstraint != value)\n\t\t\t\t{\n\t\t\t\t\tintroduceUnmanagedConstraint = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool stackAllocInitializers = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether C# 7.3 stackalloc initializers should be used.\n\t\t/// </summary>\n\t\t[Category(\"C# 7.3 / VS 2017.7\")]\n\t\t[Description(\"DecompilerSettings.UseStackallocInitializerSyntax\")]\n\t\tpublic bool StackAllocInitializers {\n\t\t\tget { return stackAllocInitializers; }\n\t\t\tset {\n\t\t\t\tif (stackAllocInitializers != value)\n\t\t\t\t{\n\t\t\t\t\tstackAllocInitializers = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool patternBasedFixedStatement = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether C# 7.3 pattern based fixed statement should be used.\n\t\t/// </summary>\n\t\t[Category(\"C# 7.3 / VS 2017.7\")]\n\t\t[Description(\"DecompilerSettings.UsePatternBasedFixedStatement\")]\n\t\tpublic bool PatternBasedFixedStatement {\n\t\t\tget { return patternBasedFixedStatement; }\n\t\t\tset {\n\t\t\t\tif (patternBasedFixedStatement != value)\n\t\t\t\t{\n\t\t\t\t\tpatternBasedFixedStatement = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool tupleTypes = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether tuple type syntax <c>(int, string)</c>\n\t\t/// should be used for <c>System.ValueTuple</c>.\n\t\t/// </summary>\n\t\t[Category(\"C# 7.0 / VS 2017\")]\n\t\t[Description(\"DecompilerSettings.UseTupleTypeSyntax\")]\n\t\tpublic bool TupleTypes {\n\t\t\tget { return tupleTypes; }\n\t\t\tset {\n\t\t\t\tif (tupleTypes != value)\n\t\t\t\t{\n\t\t\t\t\ttupleTypes = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool throwExpressions = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether throw expressions should be used.\n\t\t/// </summary>\n\t\t[Category(\"C# 7.0 / VS 2017\")]\n\t\t[Description(\"DecompilerSettings.UseThrowExpressions\")]\n\t\tpublic bool ThrowExpressions {\n\t\t\tget { return throwExpressions; }\n\t\t\tset {\n\t\t\t\tif (throwExpressions != value)\n\t\t\t\t{\n\t\t\t\t\tthrowExpressions = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool tupleConversions = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether implicit conversions between tuples\n\t\t/// should be used in the decompiled output.\n\t\t/// </summary>\n\t\t[Category(\"C# 7.0 / VS 2017\")]\n\t\t[Description(\"DecompilerSettings.UseImplicitConversionsBetweenTupleTypes\")]\n\t\tpublic bool TupleConversions {\n\t\t\tget { return tupleConversions; }\n\t\t\tset {\n\t\t\t\tif (tupleConversions != value)\n\t\t\t\t{\n\t\t\t\t\ttupleConversions = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool tupleComparisons = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether tuple comparisons should be detected.\n\t\t/// </summary>\n\t\t[Category(\"C# 7.3 / VS 2017.7\")]\n\t\t[Description(\"DecompilerSettings.DetectTupleComparisons\")]\n\t\tpublic bool TupleComparisons {\n\t\t\tget { return tupleComparisons; }\n\t\t\tset {\n\t\t\t\tif (tupleComparisons != value)\n\t\t\t\t{\n\t\t\t\t\ttupleComparisons = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool namedArguments = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether named arguments should be used.\n\t\t/// </summary>\n\t\t[Category(\"C# 4.0 / VS 2010\")]\n\t\t[Description(\"DecompilerSettings.UseNamedArguments\")]\n\t\tpublic bool NamedArguments {\n\t\t\tget { return namedArguments; }\n\t\t\tset {\n\t\t\t\tif (namedArguments != value)\n\t\t\t\t{\n\t\t\t\t\tnamedArguments = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool nonTrailingNamedArguments = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether C# 7.2 non-trailing named arguments should be used.\n\t\t/// </summary>\n\t\t[Category(\"C# 7.2 / VS 2017.4\")]\n\t\t[Description(\"DecompilerSettings.UseNonTrailingNamedArguments\")]\n\t\tpublic bool NonTrailingNamedArguments {\n\t\t\tget { return nonTrailingNamedArguments; }\n\t\t\tset {\n\t\t\t\tif (nonTrailingNamedArguments != value)\n\t\t\t\t{\n\t\t\t\t\tnonTrailingNamedArguments = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool optionalArguments = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether optional arguments should be removed, if possible.\n\t\t/// </summary>\n\t\t[Category(\"C# 4.0 / VS 2010\")]\n\t\t[Description(\"DecompilerSettings.RemoveOptionalArgumentsIfPossible\")]\n\t\tpublic bool OptionalArguments {\n\t\t\tget { return optionalArguments; }\n\t\t\tset {\n\t\t\t\tif (optionalArguments != value)\n\t\t\t\t{\n\t\t\t\t\toptionalArguments = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool expandParamsArguments = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to expand <c>params</c> arguments by replacing explicit array creation\n\t\t/// with individual values in method calls.\n\t\t/// </summary>\n\t\t[Category(\"C# 1.0 / VS .NET\")]\n\t\t[Description(\"DecompilerSettings.ExpandParamsArguments\")]\n\t\tpublic bool ExpandParamsArguments {\n\t\t\tget { return expandParamsArguments; }\n\t\t\tset {\n\t\t\t\tif (expandParamsArguments != value)\n\t\t\t\t{\n\t\t\t\t\texpandParamsArguments = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool localFunctions = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether C# 7.0 local functions should be transformed.\n\t\t/// </summary>\n\t\t[Category(\"C# 7.0 / VS 2017\")]\n\t\t[Description(\"DecompilerSettings.IntroduceLocalFunctions\")]\n\t\tpublic bool LocalFunctions {\n\t\t\tget { return localFunctions; }\n\t\t\tset {\n\t\t\t\tif (localFunctions != value)\n\t\t\t\t{\n\t\t\t\t\tlocalFunctions = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool deconstruction = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether C# 7.0 deconstruction should be detected.\n\t\t/// </summary>\n\t\t[Category(\"C# 7.0 / VS 2017\")]\n\t\t[Description(\"DecompilerSettings.Deconstruction\")]\n\t\tpublic bool Deconstruction {\n\t\t\tget { return deconstruction; }\n\t\t\tset {\n\t\t\t\tif (deconstruction != value)\n\t\t\t\t{\n\t\t\t\t\tdeconstruction = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool patternMatching = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether C# 7.0 pattern matching should be detected.\n\t\t/// </summary>\n\t\t[Category(\"C# 7.0 / VS 2017\")]\n\t\t[Description(\"DecompilerSettings.PatternMatching\")]\n\t\tpublic bool PatternMatching {\n\t\t\tget { return patternMatching; }\n\t\t\tset {\n\t\t\t\tif (patternMatching != value)\n\t\t\t\t{\n\t\t\t\t\tpatternMatching = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool recursivePatternMatching = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether C# 8.0 recursive patterns should be detected.\n\t\t/// </summary>\n\t\t[Category(\"C# 8.0 / VS 2019\")]\n\t\t[Description(\"DecompilerSettings.RecursivePatternMatching\")]\n\t\tpublic bool RecursivePatternMatching {\n\t\t\tget { return recursivePatternMatching; }\n\t\t\tset {\n\t\t\t\tif (recursivePatternMatching != value)\n\t\t\t\t{\n\t\t\t\t\trecursivePatternMatching = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool patternCombinators = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether C# 9.0 and, or, not patterns should be detected.\n\t\t/// </summary>\n\t\t[Category(\"C# 9.0 / VS 2019.8\")]\n\t\t[Description(\"DecompilerSettings.PatternCombinators\")]\n\t\tpublic bool PatternCombinators {\n\t\t\tget { return patternCombinators; }\n\t\t\tset {\n\t\t\t\tif (patternCombinators != value)\n\t\t\t\t{\n\t\t\t\t\tpatternCombinators = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool relationalPatterns = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether C# 9.0 relational patterns should be detected.\n\t\t/// </summary>\n\t\t[Category(\"C# 9.0 / VS 2019.8\")]\n\t\t[Description(\"DecompilerSettings.RelationalPatterns\")]\n\t\tpublic bool RelationalPatterns {\n\t\t\tget { return relationalPatterns; }\n\t\t\tset {\n\t\t\t\tif (relationalPatterns != value)\n\t\t\t\t{\n\t\t\t\t\trelationalPatterns = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool staticLocalFunctions = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether C# 8.0 static local functions should be transformed.\n\t\t/// </summary>\n\t\t[Category(\"C# 8.0 / VS 2019\")]\n\t\t[Description(\"DecompilerSettings.IntroduceStaticLocalFunctions\")]\n\t\tpublic bool StaticLocalFunctions {\n\t\t\tget { return staticLocalFunctions; }\n\t\t\tset {\n\t\t\t\tif (staticLocalFunctions != value)\n\t\t\t\t{\n\t\t\t\t\tstaticLocalFunctions = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool ranges = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether C# 8.0 index and range syntax should be used.\n\t\t/// </summary>\n\t\t[Category(\"C# 8.0 / VS 2019\")]\n\t\t[Description(\"DecompilerSettings.Ranges\")]\n\t\tpublic bool Ranges {\n\t\t\tget { return ranges; }\n\t\t\tset {\n\t\t\t\tif (ranges != value)\n\t\t\t\t{\n\t\t\t\t\tranges = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool nullableReferenceTypes = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether C# 8.0 nullable reference types are enabled.\n\t\t/// </summary>\n\t\t[Category(\"C# 8.0 / VS 2019\")]\n\t\t[Description(\"DecompilerSettings.NullableReferenceTypes\")]\n\t\tpublic bool NullableReferenceTypes {\n\t\t\tget { return nullableReferenceTypes; }\n\t\t\tset {\n\t\t\t\tif (nullableReferenceTypes != value)\n\t\t\t\t{\n\t\t\t\t\tnullableReferenceTypes = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool showDebugInfo;\n\n\t\t[Category(\"DecompilerSettings.Other\")]\n\t\t[Description(\"DecompilerSettings.ShowInfoFromDebugSymbolsIfAvailable\")]\n\t\t[Browsable(false)]\n\t\tpublic bool ShowDebugInfo {\n\t\t\tget { return showDebugInfo; }\n\t\t\tset {\n\t\t\t\tif (showDebugInfo != value)\n\t\t\t\t{\n\t\t\t\t\tshowDebugInfo = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t#region Options to aid VB decompilation\n\t\tbool assumeArrayLengthFitsIntoInt32 = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether the decompiler can assume that 'ldlen; conv.i4.ovf'\n\t\t/// does not throw an overflow exception.\n\t\t/// </summary>\n\t\t[Category(\"DecompilerSettings.VBSpecificOptions\")]\n\t\t[Browsable(false)]\n\t\tpublic bool AssumeArrayLengthFitsIntoInt32 {\n\t\t\tget { return assumeArrayLengthFitsIntoInt32; }\n\t\t\tset {\n\t\t\t\tif (assumeArrayLengthFitsIntoInt32 != value)\n\t\t\t\t{\n\t\t\t\t\tassumeArrayLengthFitsIntoInt32 = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool introduceIncrementAndDecrement = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to use increment and decrement operators\n\t\t/// </summary>\n\t\t[Category(\"DecompilerSettings.VBSpecificOptions\")]\n\t\t[Browsable(false)]\n\t\tpublic bool IntroduceIncrementAndDecrement {\n\t\t\tget { return introduceIncrementAndDecrement; }\n\t\t\tset {\n\t\t\t\tif (introduceIncrementAndDecrement != value)\n\t\t\t\t{\n\t\t\t\t\tintroduceIncrementAndDecrement = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool makeAssignmentExpressions = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to use assignment expressions such as in while ((count = Do()) != 0) ;\n\t\t/// </summary>\n\t\t[Category(\"DecompilerSettings.VBSpecificOptions\")]\n\t\t[Browsable(false)]\n\t\tpublic bool MakeAssignmentExpressions {\n\t\t\tget { return makeAssignmentExpressions; }\n\t\t\tset {\n\t\t\t\tif (makeAssignmentExpressions != value)\n\t\t\t\t{\n\t\t\t\t\tmakeAssignmentExpressions = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Options to aid F# decompilation\n\t\tbool removeDeadCode = false;\n\n\t\t[Category(\"DecompilerSettings.FSpecificOptions\")]\n\t\t[Description(\"DecompilerSettings.RemoveDeadAndSideEffectFreeCodeUseWithCaution\")]\n\t\tpublic bool RemoveDeadCode {\n\t\t\tget { return removeDeadCode; }\n\t\t\tset {\n\t\t\t\tif (removeDeadCode != value)\n\t\t\t\t{\n\t\t\t\t\tremoveDeadCode = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool removeDeadStores = false;\n\n\t\t[Category(\"DecompilerSettings.FSpecificOptions\")]\n\t\t[Description(\"DecompilerSettings.RemoveDeadStores\")]\n\t\tpublic bool RemoveDeadStores {\n\t\t\tget { return removeDeadStores; }\n\t\t\tset {\n\t\t\t\tif (removeDeadStores != value)\n\t\t\t\t{\n\t\t\t\t\tremoveDeadStores = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Assembly Load and Resolve options\n\n\t\tbool loadInMemory = false;\n\n\t\t[Browsable(false)]\n\t\tpublic bool LoadInMemory {\n\t\t\tget { return loadInMemory; }\n\t\t\tset {\n\t\t\t\tif (loadInMemory != value)\n\t\t\t\t{\n\t\t\t\t\tloadInMemory = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool throwOnAssemblyResolveErrors = true;\n\n\t\t[Browsable(false)]\n\t\tpublic bool ThrowOnAssemblyResolveErrors {\n\t\t\tget { return throwOnAssemblyResolveErrors; }\n\t\t\tset {\n\t\t\t\tif (throwOnAssemblyResolveErrors != value)\n\t\t\t\t{\n\t\t\t\t\tthrowOnAssemblyResolveErrors = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool applyWindowsRuntimeProjections = true;\n\n\t\t[Category(\"DecompilerSettings.Other\")]\n\t\t[Description(\"DecompilerSettings.ApplyWindowsRuntimeProjectionsOnLoadedAssemblies\")]\n\t\tpublic bool ApplyWindowsRuntimeProjections {\n\t\t\tget { return applyWindowsRuntimeProjections; }\n\t\t\tset {\n\t\t\t\tif (applyWindowsRuntimeProjections != value)\n\t\t\t\t{\n\t\t\t\t\tapplyWindowsRuntimeProjections = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool autoLoadAssemblyReferences = true;\n\n\t\t[Category(\"DecompilerSettings.Other\")]\n\t\t[Description(\"DecompilerSettings.AutoLoadAssemblyReferences\")]\n\t\tpublic bool AutoLoadAssemblyReferences {\n\t\t\tget { return autoLoadAssemblyReferences; }\n\t\t\tset {\n\t\t\t\tif (autoLoadAssemblyReferences != value)\n\t\t\t\t{\n\t\t\t\t\tautoLoadAssemblyReferences = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t#endregion\n\n\t\tbool forStatement = true;\n\n\t\t/// <summary>\n\t\t/// Gets/sets whether the decompiler should produce for loops.\n\t\t/// </summary>\n\t\t[Category(\"C# 1.0 / VS .NET\")]\n\t\t[Description(\"DecompilerSettings.ForStatement\")]\n\t\tpublic bool ForStatement {\n\t\t\tget { return forStatement; }\n\t\t\tset {\n\t\t\t\tif (forStatement != value)\n\t\t\t\t{\n\t\t\t\t\tforStatement = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool doWhileStatement = true;\n\n\t\t/// <summary>\n\t\t/// Gets/sets whether the decompiler should produce do-while loops.\n\t\t/// </summary>\n\t\t[Category(\"C# 1.0 / VS .NET\")]\n\t\t[Description(\"DecompilerSettings.DoWhileStatement\")]\n\t\tpublic bool DoWhileStatement {\n\t\t\tget { return doWhileStatement; }\n\t\t\tset {\n\t\t\t\tif (doWhileStatement != value)\n\t\t\t\t{\n\t\t\t\t\tdoWhileStatement = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool refReadOnlyParameters = true;\n\n\t\t/// <summary>\n\t\t/// Gets/sets whether RequiresLocationAttribute on parameters should be replaced with 'ref readonly' modifiers.\n\t\t/// </summary>\n\t\t[Category(\"C# 12.0 / VS 2022.8\")]\n\t\t[Description(\"DecompilerSettings.RefReadOnlyParameters\")]\n\t\tpublic bool RefReadOnlyParameters {\n\t\t\tget { return refReadOnlyParameters; }\n\t\t\tset {\n\t\t\t\tif (refReadOnlyParameters != value)\n\t\t\t\t{\n\t\t\t\t\trefReadOnlyParameters = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool usePrimaryConstructorSyntaxForNonRecordTypes = true;\n\n\t\t/// <summary>\n\t\t/// Use primary constructor syntax with classes and structs.\n\t\t/// </summary>\n\t\t[Category(\"C# 12.0 / VS 2022.8\")]\n\t\t[Description(\"DecompilerSettings.UsePrimaryConstructorSyntaxForNonRecordTypes\")]\n\t\tpublic bool UsePrimaryConstructorSyntaxForNonRecordTypes {\n\t\t\tget { return usePrimaryConstructorSyntaxForNonRecordTypes; }\n\t\t\tset {\n\t\t\t\tif (usePrimaryConstructorSyntaxForNonRecordTypes != value)\n\t\t\t\t{\n\t\t\t\t\tusePrimaryConstructorSyntaxForNonRecordTypes = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool inlineArrays = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether C# 12.0 inline array uses should be transformed.\n\t\t/// </summary>\n\t\t[Category(\"C# 12.0 / VS 2022.8\")]\n\t\t[Description(\"DecompilerSettings.InlineArrays\")]\n\t\tpublic bool InlineArrays {\n\t\t\tget { return inlineArrays; }\n\t\t\tset {\n\t\t\t\tif (inlineArrays != value)\n\t\t\t\t{\n\t\t\t\t\tinlineArrays = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool extensionMembers = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether C# 14.0 extension members should be transformed.\n\t\t/// </summary>\n\t\t[Category(\"C# 14.0 / VS 202x.yy\")]\n\t\t[Description(\"DecompilerSettings.ExtensionMembers\")]\n\t\tpublic bool ExtensionMembers {\n\t\t\tget { return extensionMembers; }\n\t\t\tset {\n\t\t\t\tif (extensionMembers != value)\n\t\t\t\t{\n\t\t\t\t\textensionMembers = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool firstClassSpanTypes = true;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether (ReadOnly)Span&lt;T&gt; should be treated like built-in types.\n\t\t/// </summary>\n\t\t[Category(\"C# 14.0 / VS 202x.yy\")]\n\t\t[Description(\"DecompilerSettings.FirstClassSpanTypes\")]\n\t\tpublic bool FirstClassSpanTypes {\n\t\t\tget { return firstClassSpanTypes; }\n\t\t\tset {\n\t\t\t\tif (firstClassSpanTypes != value)\n\t\t\t\t{\n\t\t\t\t\tfirstClassSpanTypes = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool separateLocalVariableDeclarations = false;\n\n\t\t/// <summary>\n\t\t/// Gets/sets whether the decompiler should separate local variable declarations\n\t\t/// from their initialization.\n\t\t/// </summary>\n\t\t[Category(\"DecompilerSettings.Other\")]\n\t\t[Description(\"DecompilerSettings.SeparateLocalVariableDeclarations\")]\n\t\tpublic bool SeparateLocalVariableDeclarations {\n\t\t\tget { return separateLocalVariableDeclarations; }\n\t\t\tset {\n\t\t\t\tif (separateLocalVariableDeclarations != value)\n\t\t\t\t{\n\t\t\t\t\tseparateLocalVariableDeclarations = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool useSdkStyleProjectFormat = true;\n\n\t\t/// <summary>\n\t\t/// Gets or sets a value indicating whether the new SDK style format\n\t\t/// shall be used for the generated project files.\n\t\t/// </summary>\n\t\t[Category(\"DecompilerSettings.ProjectExport\")]\n\t\t[Description(\"DecompilerSettings.UseSdkStyleProjectFormat\")]\n\t\tpublic bool UseSdkStyleProjectFormat {\n\t\t\tget { return useSdkStyleProjectFormat; }\n\t\t\tset {\n\t\t\t\tif (useSdkStyleProjectFormat != value)\n\t\t\t\t{\n\t\t\t\t\tuseSdkStyleProjectFormat = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool useNestedDirectoriesForNamespaces;\n\n\t\t/// <summary>\n\t\t/// Gets/sets whether namespaces and namespace-like identifiers should be split at '.'\n\t\t/// and each part should produce a new level of nesting in the output directory structure. \n\t\t/// </summary>\n\t\t[Category(\"DecompilerSettings.ProjectExport\")]\n\t\t[Description(\"DecompilerSettings.UseNestedDirectoriesForNamespaces\")]\n\t\tpublic bool UseNestedDirectoriesForNamespaces {\n\t\t\tget { return useNestedDirectoriesForNamespaces; }\n\t\t\tset {\n\t\t\t\tif (useNestedDirectoriesForNamespaces != value)\n\t\t\t\t{\n\t\t\t\t\tuseNestedDirectoriesForNamespaces = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool aggressiveScalarReplacementOfAggregates = false;\n\n\t\t[Category(\"DecompilerSettings.Other\")]\n\t\t[Description(\"DecompilerSettings.AggressiveScalarReplacementOfAggregates\")]\n\t\t// TODO : Remove once https://github.com/icsharpcode/ILSpy/issues/2032 is fixed.\n#if !DEBUG\n\t\t[Browsable(false)]\n#endif\n\t\tpublic bool AggressiveScalarReplacementOfAggregates {\n\t\t\tget { return aggressiveScalarReplacementOfAggregates; }\n\t\t\tset {\n\t\t\t\tif (aggressiveScalarReplacementOfAggregates != value)\n\t\t\t\t{\n\t\t\t\t\taggressiveScalarReplacementOfAggregates = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool aggressiveInlining = false;\n\n\t\t/// <summary>\n\t\t/// If set to false (the default), the decompiler will inline local variables only when they occur\n\t\t/// in a context where the C# compiler is known to emit compiler-generated locals.\n\t\t/// If set to true, the decompiler will inline local variables whenever possible.\n\t\t/// </summary>\n\t\t[Category(\"DecompilerSettings.Other\")]\n\t\t[Description(\"DecompilerSettings.AggressiveInlining\")]\n\t\tpublic bool AggressiveInlining {\n\t\t\tget { return aggressiveInlining; }\n\t\t\tset {\n\t\t\t\tif (aggressiveInlining != value)\n\t\t\t\t{\n\t\t\t\t\taggressiveInlining = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool alwaysUseGlobal = false;\n\n\t\t/// <summary>\n\t\t/// Always fully qualify namespaces using the \"global::\" prefix.\n\t\t/// </summary>\n\t\t[Category(\"DecompilerSettings.Other\")]\n\t\t[Description(\"DecompilerSettings.AlwaysUseGlobal\")]\n\t\tpublic bool AlwaysUseGlobal {\n\t\t\tget { return alwaysUseGlobal; }\n\t\t\tset {\n\t\t\t\tif (alwaysUseGlobal != value)\n\t\t\t\t{\n\t\t\t\t\talwaysUseGlobal = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool alwaysMoveInitializer = false;\n\n\t\t/// <summary>\n\t\t/// If set to false (the default), the decompiler will move field initializers at the start of constructors\n\t\t/// to their respective field declarations (TransformFieldAndConstructorInitializers) only when the declaring\n\t\t/// type has BeforeFieldInit or the member IsConst.\n\t\t/// If set true, the decompiler will always move them regardless of the flags.\n\t\t/// </summary>\n\t\t[Category(\"DecompilerSettings.Other\")]\n\t\t[Description(\"DecompilerSettings.AlwaysMoveInitializer\")]\n\t\tpublic bool AlwaysMoveInitializer {\n\t\t\tget { return alwaysMoveInitializer; }\n\t\t\tset {\n\t\t\t\tif (alwaysMoveInitializer != value)\n\t\t\t\t{\n\t\t\t\t\talwaysMoveInitializer = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool sortCustomAttributes = false;\n\n\t\t/// <summary>\n\t\t/// Sort custom attributes.\n\t\t/// </summary>\n\t\t[Category(\"DecompilerSettings.Other\")]\n\t\t[Description(\"DecompilerSettings.SortCustomAttributes\")]\n\t\tpublic bool SortCustomAttributes {\n\t\t\tget { return sortCustomAttributes; }\n\t\t\tset {\n\t\t\t\tif (sortCustomAttributes != value)\n\t\t\t\t{\n\t\t\t\t\tsortCustomAttributes = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool checkForOverflowUnderflow = false;\n\n\t\t/// <summary>\n\t\t/// Check for overflow and underflow in operators.\n\t\t/// </summary>\n\t\t[Category(\"DecompilerSettings.Other\")]\n\t\t[Description(\"DecompilerSettings.CheckForOverflowUnderflow\")]\n\t\tpublic bool CheckForOverflowUnderflow {\n\t\t\tget { return checkForOverflowUnderflow; }\n\t\t\tset {\n\t\t\t\tif (checkForOverflowUnderflow != value)\n\t\t\t\t{\n\t\t\t\t\tcheckForOverflowUnderflow = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tCSharpFormattingOptions csharpFormattingOptions;\n\n\t\t[Browsable(false)]\n\t\tpublic CSharpFormattingOptions CSharpFormattingOptions {\n\t\t\tget {\n\t\t\t\tif (csharpFormattingOptions == null)\n\t\t\t\t{\n\t\t\t\t\tcsharpFormattingOptions = FormattingOptionsFactory.CreateAllman();\n\t\t\t\t\tcsharpFormattingOptions.IndentSwitchBody = false;\n\t\t\t\t\tcsharpFormattingOptions.ArrayInitializerWrapping = Wrapping.WrapIfTooLong;\n\t\t\t\t\tcsharpFormattingOptions.AutoPropertyFormatting = PropertyFormatting.SingleLine;\n\t\t\t\t}\n\t\t\t\treturn csharpFormattingOptions;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tif (value == null)\n\t\t\t\t\tthrow new ArgumentNullException();\n\t\t\t\tif (csharpFormattingOptions != value)\n\t\t\t\t{\n\t\t\t\t\tcsharpFormattingOptions = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic event PropertyChangedEventHandler PropertyChanged;\n\n\t\tprotected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)\n\t\t{\n\t\t\tif (PropertyChanged != null)\n\t\t\t{\n\t\t\t\tPropertyChanged(this, new PropertyChangedEventArgs(propertyName));\n\t\t\t}\n\t\t}\n\n\t\tpublic virtual DecompilerSettings Clone()\n\t\t{\n\t\t\tDecompilerSettings settings = (DecompilerSettings)MemberwiseClone();\n\t\t\tif (csharpFormattingOptions != null)\n\t\t\t\tsettings.csharpFormattingOptions = csharpFormattingOptions.Clone();\n\t\t\tsettings.PropertyChanged = null;\n\t\t\treturn settings;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.Disassembler\n{\n\tpublic enum ILNameSyntax\n\t{\n\t\t/// <summary>\n\t\t/// class/valuetype + TypeName (built-in types use keyword syntax)\n\t\t/// </summary>\n\t\tSignature,\n\t\t/// <summary>\n\t\t/// Like signature, but always refers to type parameters using their position\n\t\t/// </summary>\n\t\tSignatureNoNamedTypeParameters,\n\t\t/// <summary>\n\t\t/// [assembly]Full.Type.Name (even for built-in types)\n\t\t/// </summary>\n\t\tTypeName,\n\t\t/// <summary>\n\t\t/// Name (but built-in types use keyword syntax)\n\t\t/// </summary>\n\t\tShortTypeName\n\t}\n\n\tpublic static class DisassemblerHelpers\n\t{\n\t\tstatic readonly char[] _validNonLetterIdentifierCharacter = new char[] { '_', '$', '@', '?', '`', '.' };\n\n\t\tpublic static string OffsetToString(int offset)\n\t\t{\n\t\t\treturn string.Format(\"IL_{0:x4}\", offset);\n\t\t}\n\n\t\tpublic static string OffsetToString(long offset)\n\t\t{\n\t\t\treturn string.Format(\"IL_{0:x4}\", offset);\n\t\t}\n\n\t\tpublic static void WriteOffsetReference(ITextOutput writer, int? offset)\n\t\t{\n\t\t\tif (offset == null)\n\t\t\t\twriter.Write(\"null\");\n\t\t\telse\n\t\t\t\twriter.WriteLocalReference(OffsetToString(offset.Value), offset);\n\t\t}\n\n\t\tpublic static void WriteTo(this ExceptionRegion exceptionHandler, MetadataFile module, MetadataGenericContext context, ITextOutput writer)\n\t\t{\n\t\t\twriter.Write(\".try \");\n\t\t\tWriteOffsetReference(writer, exceptionHandler.TryOffset);\n\t\t\twriter.Write('-');\n\t\t\tWriteOffsetReference(writer, exceptionHandler.TryOffset + exceptionHandler.TryLength);\n\t\t\twriter.Write(' ');\n\t\t\twriter.Write(exceptionHandler.Kind.ToString().ToLowerInvariant());\n\t\t\tif (exceptionHandler.FilterOffset != -1)\n\t\t\t{\n\t\t\t\twriter.Write(' ');\n\t\t\t\tWriteOffsetReference(writer, exceptionHandler.FilterOffset);\n\t\t\t\twriter.Write(\" handler \");\n\t\t\t}\n\t\t\tif (!exceptionHandler.CatchType.IsNil)\n\t\t\t{\n\t\t\t\twriter.Write(' ');\n\t\t\t\texceptionHandler.CatchType.WriteTo(module, writer, context);\n\t\t\t}\n\t\t\twriter.Write(' ');\n\t\t\tWriteOffsetReference(writer, exceptionHandler.HandlerOffset);\n\t\t\twriter.Write('-');\n\t\t\tWriteOffsetReference(writer, exceptionHandler.HandlerOffset + exceptionHandler.HandlerLength);\n\t\t}\n\n\t\tstatic string ToInvariantCultureString(object value)\n\t\t{\n\t\t\tIConvertible convertible = value as IConvertible;\n\t\t\treturn (null != convertible)\n\t\t\t\t? convertible.ToString(System.Globalization.CultureInfo.InvariantCulture)\n\t\t\t\t: value.ToString();\n\t\t}\n\n\t\tstatic bool IsValidIdentifierCharacter(char c)\n\t\t\t=> char.IsLetterOrDigit(c) || _validNonLetterIdentifierCharacter.IndexOf(c) >= 0;\n\n\t\tstatic bool IsValidIdentifier(string identifier)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(identifier))\n\t\t\t\treturn false;\n\n\t\t\tif (char.IsDigit(identifier[0]))\n\t\t\t\treturn false;\n\n\t\t\t// As a special case, .ctor and .cctor are valid despite starting with a dot\n\t\t\tif (identifier[0] == '.')\n\t\t\t\treturn identifier == \".ctor\" || identifier == \".cctor\";\n\n\t\t\tif (identifier.Contains(\"..\"))\n\t\t\t\treturn false;\n\n\t\t\tif (Metadata.ILOpCodeExtensions.ILKeywords.Contains(identifier))\n\t\t\t\treturn false;\n\n\t\t\treturn identifier.All(IsValidIdentifierCharacter);\n\t\t}\n\n\t\tpublic static string Escape(string identifier)\n\t\t{\n\t\t\tif (IsValidIdentifier(identifier))\n\t\t\t{\n\t\t\t\treturn identifier;\n\t\t\t}\n\n\t\t\t// The ECMA specification says that ' inside SQString should be ecaped using an octal escape sequence,\n\t\t\t// but we follow Microsoft's ILDasm and use \\'.\n\t\t\treturn $\"'{EscapeString(identifier).Replace(\"'\", \"\\\\'\")}'\";\n\t\t}\n\n\t\tpublic static void WriteParameterReference(ITextOutput writer, MetadataReader metadata, MethodDefinitionHandle handle, int index)\n\t\t{\n\t\t\tstring name = GetParameterName(index);\n\t\t\tif (name == null)\n\t\t\t{\n\t\t\t\twriter.WriteLocalReference(index.ToString(), \"param_\" + index);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\twriter.WriteLocalReference(name, \"param_\" + index);\n\t\t\t}\n\n\t\t\tstring GetParameterName(int parameterNumber)\n\t\t\t{\n\t\t\t\tvar methodDefinition = metadata.GetMethodDefinition(handle);\n\t\t\t\tif ((methodDefinition.Attributes & System.Reflection.MethodAttributes.Static) != 0)\n\t\t\t\t{\n\t\t\t\t\tparameterNumber++;\n\t\t\t\t}\n\t\t\t\tforeach (var p in methodDefinition.GetParameters())\n\t\t\t\t{\n\t\t\t\t\tvar param = metadata.GetParameter(p);\n\t\t\t\t\tif (param.SequenceNumber < parameterNumber)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\telse if (param.SequenceNumber == parameterNumber)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (param.Name.IsNil)\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\treturn Escape(metadata.GetString(param.Name));\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tpublic static void WriteVariableReference(ITextOutput writer, MetadataReader metadata, MethodDefinitionHandle handle, int index)\n\t\t{\n\t\t\twriter.WriteLocalReference(index.ToString(), \"loc_\" + index);\n\t\t}\n\n\t\tpublic static void WriteOperand(ITextOutput writer, object operand)\n\t\t{\n\t\t\tif (operand == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(operand));\n\n\t\t\tstring s = operand as string;\n\t\t\tif (s != null)\n\t\t\t{\n\t\t\t\tWriteOperand(writer, s);\n\t\t\t}\n\t\t\telse if (operand is char)\n\t\t\t{\n\t\t\t\twriter.Write(((int)(char)operand).ToString());\n\t\t\t}\n\t\t\telse if (operand is float)\n\t\t\t{\n\t\t\t\tWriteOperand(writer, (float)operand);\n\t\t\t}\n\t\t\telse if (operand is double)\n\t\t\t{\n\t\t\t\tWriteOperand(writer, (double)operand);\n\t\t\t}\n\t\t\telse if (operand is bool)\n\t\t\t{\n\t\t\t\twriter.Write((bool)operand ? \"true\" : \"false\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ts = ToInvariantCultureString(operand);\n\t\t\t\twriter.Write(s);\n\t\t\t}\n\t\t}\n\n\t\tpublic static void WriteOperand(ITextOutput writer, long val)\n\t\t{\n\t\t\twriter.Write(ToInvariantCultureString(val));\n\t\t}\n\n\t\tpublic static void WriteOperand(ITextOutput writer, float val)\n\t\t{\n\t\t\tif (val == 0)\n\t\t\t{\n\t\t\t\tif (1 / val == float.NegativeInfinity)\n\t\t\t\t{\n\t\t\t\t\t// negative zero is a special case\n\t\t\t\t\twriter.Write('-');\n\t\t\t\t}\n\t\t\t\twriter.Write(\"0.0\");\n\t\t\t}\n\t\t\telse if (float.IsInfinity(val) || float.IsNaN(val))\n\t\t\t{\n\t\t\t\tbyte[] data = BitConverter.GetBytes(val);\n\t\t\t\twriter.Write('(');\n\t\t\t\tfor (int i = 0; i < data.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\twriter.Write(' ');\n\t\t\t\t\twriter.Write(data[i].ToString(\"X2\"));\n\t\t\t\t}\n\t\t\t\twriter.Write(')');\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\twriter.Write(val.ToString(\"R\", System.Globalization.CultureInfo.InvariantCulture));\n\t\t\t}\n\t\t}\n\n\t\tpublic static void WriteOperand(ITextOutput writer, double val)\n\t\t{\n\t\t\tif (val == 0)\n\t\t\t{\n\t\t\t\tif (1 / val == double.NegativeInfinity)\n\t\t\t\t{\n\t\t\t\t\t// negative zero is a special case\n\t\t\t\t\twriter.Write('-');\n\t\t\t\t}\n\t\t\t\twriter.Write(\"0.0\");\n\t\t\t}\n\t\t\telse if (double.IsInfinity(val) || double.IsNaN(val))\n\t\t\t{\n\t\t\t\tbyte[] data = BitConverter.GetBytes(val);\n\t\t\t\twriter.Write('(');\n\t\t\t\tfor (int i = 0; i < data.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\twriter.Write(' ');\n\t\t\t\t\twriter.Write(data[i].ToString(\"X2\"));\n\t\t\t\t}\n\t\t\t\twriter.Write(')');\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\twriter.Write(val.ToString(\"R\", System.Globalization.CultureInfo.InvariantCulture));\n\t\t\t}\n\t\t}\n\n\t\tpublic static void WriteOperand(ITextOutput writer, string operand)\n\t\t{\n\t\t\twriter.Write('\"');\n\t\t\twriter.Write(EscapeString(operand));\n\t\t\twriter.Write('\"');\n\t\t}\n\n\t\tpublic static string EscapeString(string str)\n\t\t{\n\t\t\tvar sb = new StringBuilder();\n\t\t\tforeach (char ch in str)\n\t\t\t{\n\t\t\t\tswitch (ch)\n\t\t\t\t{\n\t\t\t\t\tcase '\"':\n\t\t\t\t\t\tsb.Append(\"\\\\\\\"\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\\\\':\n\t\t\t\t\t\tsb.Append(\"\\\\\\\\\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\\0':\n\t\t\t\t\t\tsb.Append(\"\\\\0\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\\a':\n\t\t\t\t\t\tsb.Append(\"\\\\a\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\\b':\n\t\t\t\t\t\tsb.Append(\"\\\\b\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\\f':\n\t\t\t\t\t\tsb.Append(\"\\\\f\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\\n':\n\t\t\t\t\t\tsb.Append(\"\\\\n\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\\r':\n\t\t\t\t\t\tsb.Append(\"\\\\r\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\\t':\n\t\t\t\t\t\tsb.Append(\"\\\\t\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\\v':\n\t\t\t\t\t\tsb.Append(\"\\\\v\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// print control characters and uncommon white spaces as numbers\n\t\t\t\t\t\tif (char.IsControl(ch) || char.IsSurrogate(ch) || (char.IsWhiteSpace(ch) && ch != ' '))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsb.AppendFormat(\"\\\\u{0:x4}\", (int)ch);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsb.Append(ch);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn sb.ToString();\n\t\t}\n\t\tpublic static string PrimitiveTypeName(string fullName)\n\t\t{\n\t\t\tswitch (fullName)\n\t\t\t{\n\t\t\t\tcase \"System.SByte\":\n\t\t\t\t\treturn \"int8\";\n\t\t\t\tcase \"System.Int16\":\n\t\t\t\t\treturn \"int16\";\n\t\t\t\tcase \"System.Int32\":\n\t\t\t\t\treturn \"int32\";\n\t\t\t\tcase \"System.Int64\":\n\t\t\t\t\treturn \"int64\";\n\t\t\t\tcase \"System.Byte\":\n\t\t\t\t\treturn \"uint8\";\n\t\t\t\tcase \"System.UInt16\":\n\t\t\t\t\treturn \"uint16\";\n\t\t\t\tcase \"System.UInt32\":\n\t\t\t\t\treturn \"uint32\";\n\t\t\t\tcase \"System.UInt64\":\n\t\t\t\t\treturn \"uint64\";\n\t\t\t\tcase \"System.Single\":\n\t\t\t\t\treturn \"float32\";\n\t\t\t\tcase \"System.Double\":\n\t\t\t\t\treturn \"float64\";\n\t\t\t\tcase \"System.Void\":\n\t\t\t\t\treturn \"void\";\n\t\t\t\tcase \"System.Boolean\":\n\t\t\t\t\treturn \"bool\";\n\t\t\t\tcase \"System.String\":\n\t\t\t\t\treturn \"string\";\n\t\t\t\tcase \"System.Char\":\n\t\t\t\t\treturn \"char\";\n\t\t\t\tcase \"System.Object\":\n\t\t\t\t\treturn \"object\";\n\t\t\t\tcase \"System.IntPtr\":\n\t\t\t\t\treturn \"native int\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Disassembler/DisassemblerSignatureTypeProvider.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Immutable;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.Decompiler.Disassembler\n{\n\tpublic class DisassemblerSignatureTypeProvider : ISignatureTypeProvider<Action<ILNameSyntax>, MetadataGenericContext>\n\t{\n\t\treadonly MetadataFile module;\n\t\treadonly MetadataReader metadata;\n\t\treadonly ITextOutput output;\n\n\t\tpublic DisassemblerSignatureTypeProvider(MetadataFile module, ITextOutput output)\n\t\t{\n\t\t\tthis.module = module ?? throw new ArgumentNullException(nameof(module));\n\t\t\tthis.output = output ?? throw new ArgumentNullException(nameof(output));\n\t\t\tthis.metadata = module.Metadata;\n\t\t}\n\n\t\tpublic Action<ILNameSyntax> GetArrayType(Action<ILNameSyntax> elementType, ArrayShape shape)\n\t\t{\n\t\t\treturn syntax => {\n\t\t\t\tvar syntaxForElementTypes = syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature;\n\t\t\t\telementType(syntaxForElementTypes);\n\t\t\t\toutput.Write('[');\n\t\t\t\tfor (int i = 0; i < shape.Rank; i++)\n\t\t\t\t{\n\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\toutput.Write(\", \");\n\t\t\t\t\tif (i < shape.LowerBounds.Length || i < shape.Sizes.Length)\n\t\t\t\t\t{\n\t\t\t\t\t\tint lower = 0;\n\t\t\t\t\t\tif (i < shape.LowerBounds.Length)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlower = shape.LowerBounds[i];\n\t\t\t\t\t\t\toutput.Write(lower.ToString());\n\t\t\t\t\t\t}\n\t\t\t\t\t\toutput.Write(\"...\");\n\t\t\t\t\t\tif (i < shape.Sizes.Length)\n\t\t\t\t\t\t\toutput.Write((lower + shape.Sizes[i] - 1).ToString());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\toutput.Write(']');\n\t\t\t};\n\t\t}\n\n\t\tpublic Action<ILNameSyntax> GetByReferenceType(Action<ILNameSyntax> elementType)\n\t\t{\n\t\t\treturn syntax => {\n\t\t\t\tvar syntaxForElementTypes = syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature;\n\t\t\t\telementType(syntaxForElementTypes);\n\t\t\t\toutput.Write('&');\n\t\t\t};\n\t\t}\n\n\t\tpublic Action<ILNameSyntax> GetFunctionPointerType(MethodSignature<Action<ILNameSyntax>> signature)\n\t\t{\n\t\t\treturn syntax => {\n\t\t\t\toutput.Write(\"method \");\n\t\t\t\tsignature.Header.WriteTo(output);\n\t\t\t\tsignature.ReturnType(syntax);\n\t\t\t\toutput.Write(\" *(\");\n\t\t\t\tfor (int i = 0; i < signature.ParameterTypes.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\toutput.Write(\", \");\n\t\t\t\t\tsignature.ParameterTypes[i](syntax);\n\t\t\t\t}\n\t\t\t\toutput.Write(')');\n\t\t\t};\n\t\t}\n\n\t\tpublic Action<ILNameSyntax> GetGenericInstantiation(Action<ILNameSyntax> genericType, ImmutableArray<Action<ILNameSyntax>> typeArguments)\n\t\t{\n\t\t\treturn syntax => {\n\t\t\t\tvar syntaxForElementTypes = syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature;\n\t\t\t\tgenericType(syntaxForElementTypes);\n\t\t\t\toutput.Write('<');\n\t\t\t\tfor (int i = 0; i < typeArguments.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\toutput.Write(\", \");\n\t\t\t\t\ttypeArguments[i](syntaxForElementTypes);\n\t\t\t\t}\n\t\t\t\toutput.Write('>');\n\t\t\t};\n\t\t}\n\n\t\tpublic Action<ILNameSyntax> GetGenericMethodParameter(MetadataGenericContext genericContext, int index)\n\t\t{\n\t\t\treturn syntax => {\n\t\t\t\toutput.Write(\"!!\");\n\t\t\t\tWriteTypeParameter(genericContext.GetGenericMethodTypeParameterHandleOrNull(index), index, syntax);\n\t\t\t};\n\t\t}\n\n\t\tpublic Action<ILNameSyntax> GetGenericTypeParameter(MetadataGenericContext genericContext, int index)\n\t\t{\n\t\t\treturn syntax => {\n\t\t\t\toutput.Write(\"!\");\n\t\t\t\tWriteTypeParameter(genericContext.GetGenericTypeParameterHandleOrNull(index), index, syntax);\n\t\t\t};\n\t\t}\n\n\t\tvoid WriteTypeParameter(GenericParameterHandle paramRef, int index, ILNameSyntax syntax)\n\t\t{\n\t\t\tif (paramRef.IsNil || syntax == ILNameSyntax.SignatureNoNamedTypeParameters)\n\t\t\t\toutput.Write(index.ToString());\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar param = metadata.GetGenericParameter(paramRef);\n\t\t\t\tif (param.Name.IsNil)\n\t\t\t\t\toutput.Write(param.Index.ToString());\n\t\t\t\telse\n\t\t\t\t\toutput.Write(DisassemblerHelpers.Escape(metadata.GetString(param.Name)));\n\t\t\t}\n\t\t}\n\n\t\tpublic Action<ILNameSyntax> GetModifiedType(Action<ILNameSyntax> modifier, Action<ILNameSyntax> unmodifiedType, bool isRequired)\n\t\t{\n\t\t\treturn syntax => {\n\t\t\t\tunmodifiedType(syntax);\n\t\t\t\tif (isRequired)\n\t\t\t\t\toutput.Write(\" modreq\");\n\t\t\t\telse\n\t\t\t\t\toutput.Write(\" modopt\");\n\t\t\t\toutput.Write('(');\n\t\t\t\tmodifier(ILNameSyntax.TypeName);\n\t\t\t\toutput.Write(')');\n\t\t\t};\n\t\t}\n\n\t\tpublic Action<ILNameSyntax> GetPinnedType(Action<ILNameSyntax> elementType)\n\t\t{\n\t\t\treturn syntax => {\n\t\t\t\tvar syntaxForElementTypes = syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature;\n\t\t\t\telementType(syntaxForElementTypes);\n\t\t\t\toutput.Write(\" pinned\");\n\t\t\t};\n\t\t}\n\n\t\tpublic Action<ILNameSyntax> GetPointerType(Action<ILNameSyntax> elementType)\n\t\t{\n\t\t\treturn syntax => {\n\t\t\t\tvar syntaxForElementTypes = syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature;\n\t\t\t\telementType(syntaxForElementTypes);\n\t\t\t\toutput.Write('*');\n\t\t\t};\n\t\t}\n\n\t\tpublic Action<ILNameSyntax> GetPrimitiveType(PrimitiveTypeCode typeCode)\n\t\t{\n\t\t\tswitch (typeCode)\n\t\t\t{\n\t\t\t\tcase PrimitiveTypeCode.SByte:\n\t\t\t\t\treturn syntax => output.Write(\"int8\");\n\t\t\t\tcase PrimitiveTypeCode.Int16:\n\t\t\t\t\treturn syntax => output.Write(\"int16\");\n\t\t\t\tcase PrimitiveTypeCode.Int32:\n\t\t\t\t\treturn syntax => output.Write(\"int32\");\n\t\t\t\tcase PrimitiveTypeCode.Int64:\n\t\t\t\t\treturn syntax => output.Write(\"int64\");\n\t\t\t\tcase PrimitiveTypeCode.Byte:\n\t\t\t\t\treturn syntax => output.Write(\"uint8\");\n\t\t\t\tcase PrimitiveTypeCode.UInt16:\n\t\t\t\t\treturn syntax => output.Write(\"uint16\");\n\t\t\t\tcase PrimitiveTypeCode.UInt32:\n\t\t\t\t\treturn syntax => output.Write(\"uint32\");\n\t\t\t\tcase PrimitiveTypeCode.UInt64:\n\t\t\t\t\treturn syntax => output.Write(\"uint64\");\n\t\t\t\tcase PrimitiveTypeCode.Single:\n\t\t\t\t\treturn syntax => output.Write(\"float32\");\n\t\t\t\tcase PrimitiveTypeCode.Double:\n\t\t\t\t\treturn syntax => output.Write(\"float64\");\n\t\t\t\tcase PrimitiveTypeCode.Void:\n\t\t\t\t\treturn syntax => output.Write(\"void\");\n\t\t\t\tcase PrimitiveTypeCode.Boolean:\n\t\t\t\t\treturn syntax => output.Write(\"bool\");\n\t\t\t\tcase PrimitiveTypeCode.String:\n\t\t\t\t\treturn syntax => output.Write(\"string\");\n\t\t\t\tcase PrimitiveTypeCode.Char:\n\t\t\t\t\treturn syntax => output.Write(\"char\");\n\t\t\t\tcase PrimitiveTypeCode.Object:\n\t\t\t\t\treturn syntax => output.Write(\"object\");\n\t\t\t\tcase PrimitiveTypeCode.IntPtr:\n\t\t\t\t\treturn syntax => output.Write(\"native int\");\n\t\t\t\tcase PrimitiveTypeCode.UIntPtr:\n\t\t\t\t\treturn syntax => output.Write(\"native uint\");\n\t\t\t\tcase PrimitiveTypeCode.TypedReference:\n\t\t\t\t\treturn syntax => output.Write(\"typedref\");\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t}\n\t\t}\n\n\t\tpublic Action<ILNameSyntax> GetSZArrayType(Action<ILNameSyntax> elementType)\n\t\t{\n\t\t\treturn syntax => {\n\t\t\t\tvar syntaxForElementTypes = syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature;\n\t\t\t\telementType(syntaxForElementTypes);\n\t\t\t\toutput.Write('[');\n\t\t\t\toutput.Write(']');\n\t\t\t};\n\t\t}\n\n\t\tpublic Action<ILNameSyntax> GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)\n\t\t{\n\t\t\treturn syntax => {\n\t\t\t\tswitch (rawTypeKind)\n\t\t\t\t{\n\t\t\t\t\tcase 0x00:\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 0x11:\n\t\t\t\t\t\toutput.Write(\"valuetype \");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 0x12:\n\t\t\t\t\t\toutput.Write(\"class \");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new BadImageFormatException($\"Unexpected rawTypeKind: {rawTypeKind} (0x{rawTypeKind:x})\");\n\t\t\t\t}\n\t\t\t\t((EntityHandle)handle).WriteTo(module, output, default);\n\t\t\t};\n\t\t}\n\n\t\tpublic Action<ILNameSyntax> GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)\n\t\t{\n\t\t\treturn syntax => {\n\t\t\t\tswitch (rawTypeKind)\n\t\t\t\t{\n\t\t\t\t\tcase 0x00:\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 0x11:\n\t\t\t\t\t\toutput.Write(\"valuetype \");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 0x12:\n\t\t\t\t\t\toutput.Write(\"class \");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new BadImageFormatException($\"Unexpected rawTypeKind: {rawTypeKind} (0x{rawTypeKind:x})\");\n\t\t\t\t}\n\t\t\t\t((EntityHandle)handle).WriteTo(module, output, default);\n\t\t\t};\n\t\t}\n\n\t\tpublic Action<ILNameSyntax> GetTypeFromSpecification(MetadataReader reader, MetadataGenericContext genericContext, TypeSpecificationHandle handle, byte rawTypeKind)\n\t\t{\n\t\t\treturn reader.GetTypeSpecification(handle).DecodeSignature(this, genericContext);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Disassembler/IEntityProcessor.cs",
    "content": "// Copyright (c) 2022 Tom Englert\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.Decompiler.Disassembler\n{\n\tpublic interface IEntityProcessor\n\t{\n\t\tIReadOnlyCollection<InterfaceImplementationHandle> Process(MetadataFile module, IReadOnlyCollection<InterfaceImplementationHandle> items);\n\n\t\tIReadOnlyCollection<TypeDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<TypeDefinitionHandle> items);\n\n\t\tIReadOnlyCollection<MethodDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<MethodDefinitionHandle> items);\n\n\t\tIReadOnlyCollection<PropertyDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<PropertyDefinitionHandle> items);\n\n\t\tIReadOnlyCollection<EventDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<EventDefinitionHandle> items);\n\n\t\tIReadOnlyCollection<FieldDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<FieldDefinitionHandle> items);\n\n\t\tIReadOnlyCollection<CustomAttributeHandle> Process(MetadataFile module, IReadOnlyCollection<CustomAttributeHandle> items);\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler/Disassembler/ILParser.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.Disassembler\n{\n\tpublic static class ILParser\n\t{\n\t\tpublic static ILOpCode DecodeOpCode(this ref BlobReader blob)\n\t\t{\n\t\t\tbyte opCodeByte = blob.ReadByte();\n\t\t\tif (opCodeByte == 0xFE && blob.RemainingBytes >= 1)\n\t\t\t{\n\t\t\t\treturn (ILOpCode)(0xFE00 + blob.ReadByte());\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn (ILOpCode)opCodeByte;\n\t\t\t}\n\t\t}\n\n\t\tinternal static int OperandSize(this OperandType opType)\n\t\t{\n\t\t\tswitch (opType)\n\t\t\t{\n\t\t\t\t// 64-bit\n\t\t\t\tcase OperandType.I8:\n\t\t\t\tcase OperandType.R:\n\t\t\t\t\treturn 8;\n\t\t\t\t// 32-bit\n\t\t\t\tcase OperandType.BrTarget:\n\t\t\t\tcase OperandType.Field:\n\t\t\t\tcase OperandType.Method:\n\t\t\t\tcase OperandType.I:\n\t\t\t\tcase OperandType.Sig:\n\t\t\t\tcase OperandType.String:\n\t\t\t\tcase OperandType.Tok:\n\t\t\t\tcase OperandType.Type:\n\t\t\t\tcase OperandType.ShortR:\n\t\t\t\t\treturn 4;\n\t\t\t\t// (n + 1) * 32-bit\n\t\t\t\tcase OperandType.Switch:\n\t\t\t\t\treturn 4; // minimum 4, usually more\n\t\t\t\tcase OperandType.Variable: // 16-bit\n\t\t\t\t\treturn 2;\n\t\t\t\t// 8-bit\n\t\t\t\tcase OperandType.ShortVariable:\n\t\t\t\tcase OperandType.ShortBrTarget:\n\t\t\t\tcase OperandType.ShortI:\n\t\t\t\t\treturn 1;\n\t\t\t\tdefault:\n\t\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SkipOperand(this ref BlobReader blob, ILOpCode opCode)\n\t\t{\n\t\t\tvar opType = opCode.GetOperandType();\n\t\t\tint operandSize;\n\t\t\tif (opType == OperandType.Switch)\n\t\t\t{\n\t\t\t\tuint n = blob.RemainingBytes >= 4 ? blob.ReadUInt32() : uint.MaxValue;\n\t\t\t\tif (n < int.MaxValue / 4)\n\t\t\t\t{\n\t\t\t\t\toperandSize = (int)(n * 4);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\toperandSize = int.MaxValue;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\toperandSize = opType.OperandSize();\n\t\t\t}\n\t\t\tif (operandSize <= blob.RemainingBytes)\n\t\t\t{\n\t\t\t\tblob.Offset += operandSize;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// ignore missing/partial operand at end of body\n\t\t\t\tblob.Offset = blob.Length;\n\t\t\t}\n\t\t}\n\n\t\tpublic static int DecodeBranchTarget(this ref BlobReader blob, ILOpCode opCode)\n\t\t{\n\t\t\tint opSize = opCode.GetBranchOperandSize();\n\t\t\tif (opSize <= blob.RemainingBytes)\n\t\t\t{\n\t\t\t\tint relOffset = opSize == 4 ? blob.ReadInt32() : blob.ReadSByte();\n\t\t\t\treturn unchecked(relOffset + blob.Offset);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn int.MinValue;\n\t\t\t}\n\t\t}\n\n\t\tpublic static int[] DecodeSwitchTargets(this ref BlobReader blob)\n\t\t{\n\t\t\tif (blob.RemainingBytes < 4)\n\t\t\t{\n\t\t\t\tblob.Offset += blob.RemainingBytes;\n\t\t\t\treturn new int[0];\n\t\t\t}\n\t\t\tuint numTargets = blob.ReadUInt32();\n\t\t\tbool numTargetOverflow = false;\n\t\t\tif (numTargets > blob.RemainingBytes / 4)\n\t\t\t{\n\t\t\t\tnumTargets = (uint)(blob.RemainingBytes / 4);\n\t\t\t\tnumTargetOverflow = true;\n\t\t\t}\n\t\t\tint[] targets = new int[numTargets];\n\t\t\tint offset = blob.Offset + 4 * targets.Length;\n\t\t\tfor (int i = 0; i < targets.Length; i++)\n\t\t\t{\n\t\t\t\ttargets[i] = unchecked(blob.ReadInt32() + offset);\n\t\t\t}\n\t\t\tif (numTargetOverflow)\n\t\t\t{\n\t\t\t\tblob.Offset += blob.RemainingBytes;\n\t\t\t}\n\t\t\treturn targets;\n\t\t}\n\n\t\tpublic static string DecodeUserString(this ref BlobReader blob, MetadataReader metadata)\n\t\t{\n\t\t\treturn metadata.GetUserString(MetadataTokens.UserStringHandle(blob.ReadInt32()));\n\t\t}\n\n\t\tpublic static int DecodeIndex(this ref BlobReader blob, ILOpCode opCode)\n\t\t{\n\t\t\tswitch (opCode.GetOperandType())\n\t\t\t{\n\t\t\t\tcase OperandType.ShortVariable:\n\t\t\t\t\treturn blob.ReadByte();\n\t\t\t\tcase OperandType.Variable:\n\t\t\t\t\treturn blob.ReadUInt16();\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentException($\"{opCode} not supported!\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static bool IsReturn(this ILOpCode opCode)\n\t\t{\n\t\t\treturn opCode == ILOpCode.Ret || opCode == ILOpCode.Endfilter || opCode == ILOpCode.Endfinally;\n\t\t}\n\n\t\tpublic static int GetHeaderSize(BlobReader bodyBlockReader)\n\t\t{\n\t\t\tbyte header = bodyBlockReader.ReadByte();\n\t\t\tif ((header & 3) == 3)\n\t\t\t{\n\t\t\t\t// fat\n\t\t\t\tushort largeHeader = (ushort)((bodyBlockReader.ReadByte() << 8) | header);\n\t\t\t\treturn (byte)(largeHeader >> 12) * 4;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// tiny\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SetBranchTargets(ref BlobReader blob, BitSet branchTargets)\n\t\t{\n\t\t\twhile (blob.RemainingBytes > 0)\n\t\t\t{\n\t\t\t\tvar opCode = DecodeOpCode(ref blob);\n\t\t\t\tif (opCode == ILOpCode.Switch)\n\t\t\t\t{\n\t\t\t\t\tforeach (var target in DecodeSwitchTargets(ref blob))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (target >= 0 && target < blob.Length)\n\t\t\t\t\t\t\tbranchTargets.Set(target);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (opCode.IsBranch())\n\t\t\t\t{\n\t\t\t\t\tint target = DecodeBranchTarget(ref blob, opCode);\n\t\t\t\t\tif (target >= 0 && target < blob.Length)\n\t\t\t\t\t\tbranchTargets.Set(target);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tSkipOperand(ref blob, opCode);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Disassembler/ILStructure.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.Disassembler\n{\n\t/// <summary>\n\t/// Specifies the type of an IL structure.\n\t/// </summary>\n\tpublic enum ILStructureType\n\t{\n\t\t/// <summary>\n\t\t/// The root block of the method\n\t\t/// </summary>\n\t\tRoot,\n\t\t/// <summary>\n\t\t/// A nested control structure representing a loop.\n\t\t/// </summary>\n\t\tLoop,\n\t\t/// <summary>\n\t\t/// A nested control structure representing a try block.\n\t\t/// </summary>\n\t\tTry,\n\t\t/// <summary>\n\t\t/// A nested control structure representing a catch, finally, or fault block.\n\t\t/// </summary>\n\t\tHandler,\n\t\t/// <summary>\n\t\t/// A nested control structure representing an exception filter block.\n\t\t/// </summary>\n\t\tFilter\n\t}\n\n\t/// <summary>\n\t/// An IL structure.\n\t/// </summary>\n\tpublic class ILStructure\n\t{\n\t\tpublic readonly MetadataFile Module;\n\t\tpublic readonly MethodDefinitionHandle MethodHandle;\n\t\tpublic readonly MetadataGenericContext GenericContext;\n\t\tpublic readonly ILStructureType Type;\n\n\t\t/// <summary>\n\t\t/// Start position of the structure.\n\t\t/// </summary>\n\t\tpublic readonly int StartOffset;\n\n\t\t/// <summary>\n\t\t/// End position of the structure. (exclusive)\n\t\t/// </summary>\n\t\tpublic readonly int EndOffset;\n\n\t\t/// <summary>\n\t\t/// The exception handler associated with the Try, Filter or Handler block.\n\t\t/// </summary>\n\t\tpublic readonly ExceptionRegion ExceptionHandler;\n\n\t\t/// <summary>\n\t\t/// The loop's entry point.\n\t\t/// </summary>\n\t\tpublic readonly int LoopEntryPointOffset;\n\n\t\t/// <summary>\n\t\t/// The list of child structures.\n\t\t/// </summary>\n\t\tpublic readonly List<ILStructure> Children = new List<ILStructure>();\n\n\t\tpublic ILStructure(MetadataFile module, MethodDefinitionHandle handle, MetadataGenericContext genericContext, MethodBodyBlock body)\n\t\t\t: this(module, handle, genericContext, ILStructureType.Root, 0, body.GetILReader().Length)\n\t\t{\n\t\t\t// Build the tree of exception structures:\n\t\t\tfor (int i = 0; i < body.ExceptionRegions.Length; i++)\n\t\t\t{\n\t\t\t\tExceptionRegion eh = body.ExceptionRegions[i];\n\t\t\t\tif (!body.ExceptionRegions.Take(i).Any(oldEh => oldEh.TryOffset == eh.TryOffset && oldEh.TryLength == eh.TryLength))\n\t\t\t\t\tAddNestedStructure(new ILStructure(module, handle, genericContext, ILStructureType.Try, eh.TryOffset, eh.TryOffset + eh.TryLength, eh));\n\t\t\t\tif (eh.Kind == ExceptionRegionKind.Filter)\n\t\t\t\t\tAddNestedStructure(new ILStructure(module, handle, genericContext, ILStructureType.Filter, eh.FilterOffset, eh.HandlerOffset, eh));\n\t\t\t\tAddNestedStructure(new ILStructure(module, handle, genericContext, ILStructureType.Handler, eh.HandlerOffset, eh.HandlerOffset + eh.HandlerLength, eh));\n\t\t\t}\n\t\t\t// Very simple loop detection: look for backward branches\n\t\t\t(var allBranches, var isAfterUnconditionalBranch) = FindAllBranches(body.GetILReader());\n\t\t\t// We go through the branches in reverse so that we find the biggest possible loop boundary first (think loops with \"continue;\")\n\t\t\tfor (int i = allBranches.Count - 1; i >= 0; i--)\n\t\t\t{\n\t\t\t\tint loopEnd = allBranches[i].Source.End;\n\t\t\t\tint loopStart = allBranches[i].Target;\n\t\t\t\tif (loopStart < loopEnd)\n\t\t\t\t{\n\t\t\t\t\t// We found a backward branch. This is a potential loop.\n\t\t\t\t\t// Check that is has only one entry point:\n\t\t\t\t\tint entryPoint = -1;\n\n\t\t\t\t\t// entry point is first instruction in loop if prev inst isn't an unconditional branch\n\t\t\t\t\tif (loopStart > 0 && !isAfterUnconditionalBranch[loopStart])\n\t\t\t\t\t\tentryPoint = allBranches[i].Target;\n\n\t\t\t\t\tbool multipleEntryPoints = false;\n\t\t\t\t\tforeach (var branch in allBranches)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (branch.Source.Start < loopStart || branch.Source.Start >= loopEnd)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (loopStart <= branch.Target && branch.Target < loopEnd)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// jump from outside the loop into the loop\n\t\t\t\t\t\t\t\tif (entryPoint < 0)\n\t\t\t\t\t\t\t\t\tentryPoint = branch.Target;\n\t\t\t\t\t\t\t\telse if (branch.Target != entryPoint)\n\t\t\t\t\t\t\t\t\tmultipleEntryPoints = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (!multipleEntryPoints)\n\t\t\t\t\t{\n\t\t\t\t\t\tAddNestedStructure(new ILStructure(module, handle, genericContext, ILStructureType.Loop, loopStart, loopEnd, entryPoint));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tSortChildren();\n\t\t}\n\n\t\tpublic ILStructure(MetadataFile module, MethodDefinitionHandle handle, MetadataGenericContext genericContext, ILStructureType type, int startOffset, int endOffset, ExceptionRegion handler = default)\n\t\t{\n\t\t\tDebug.Assert(startOffset < endOffset);\n\t\t\tthis.Module = module;\n\t\t\tthis.MethodHandle = handle;\n\t\t\tthis.GenericContext = genericContext;\n\t\t\tthis.Type = type;\n\t\t\tthis.StartOffset = startOffset;\n\t\t\tthis.EndOffset = endOffset;\n\t\t\tthis.ExceptionHandler = handler;\n\t\t}\n\n\t\tpublic ILStructure(MetadataFile module, MethodDefinitionHandle handle, MetadataGenericContext genericContext, ILStructureType type, int startOffset, int endOffset, int loopEntryPoint)\n\t\t{\n\t\t\tDebug.Assert(startOffset < endOffset);\n\t\t\tthis.Module = module;\n\t\t\tthis.MethodHandle = handle;\n\t\t\tthis.GenericContext = genericContext;\n\t\t\tthis.Type = type;\n\t\t\tthis.StartOffset = startOffset;\n\t\t\tthis.EndOffset = endOffset;\n\t\t\tthis.LoopEntryPointOffset = loopEntryPoint;\n\t\t}\n\n\t\tbool AddNestedStructure(ILStructure newStructure)\n\t\t{\n\t\t\t// special case: don't consider the loop-like structure of \"continue;\" statements to be nested loops\n\t\t\tif (this.Type == ILStructureType.Loop && newStructure.Type == ILStructureType.Loop && newStructure.StartOffset == this.StartOffset)\n\t\t\t\treturn false;\n\t\t\tif (newStructure.StartOffset < 0)\n\t\t\t\treturn false;\n\n\t\t\t// use <= for end-offset comparisons because both end and EndOffset are exclusive\n\t\t\tDebug.Assert(StartOffset <= newStructure.StartOffset && newStructure.EndOffset <= EndOffset);\n\t\t\tforeach (ILStructure child in this.Children)\n\t\t\t{\n\t\t\t\tif (child.StartOffset <= newStructure.StartOffset && newStructure.EndOffset <= child.EndOffset)\n\t\t\t\t{\n\t\t\t\t\treturn child.AddNestedStructure(newStructure);\n\t\t\t\t}\n\t\t\t\telse if (!(child.EndOffset <= newStructure.StartOffset || newStructure.EndOffset <= child.StartOffset))\n\t\t\t\t{\n\t\t\t\t\t// child and newStructure overlap\n\t\t\t\t\tif (!(newStructure.StartOffset <= child.StartOffset && child.EndOffset <= newStructure.EndOffset))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Invalid nesting, can't build a tree. -> Don't add the new structure.\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Move existing structures into the new structure:\n\t\t\tfor (int i = 0; i < this.Children.Count; i++)\n\t\t\t{\n\t\t\t\tILStructure child = this.Children[i];\n\t\t\t\tif (newStructure.StartOffset <= child.StartOffset && child.EndOffset <= newStructure.EndOffset)\n\t\t\t\t{\n\t\t\t\t\tthis.Children.RemoveAt(i--);\n\t\t\t\t\tnewStructure.Children.Add(child);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Add the structure here:\n\t\t\tthis.Children.Add(newStructure);\n\t\t\treturn true;\n\t\t}\n\n\t\tstruct Branch\n\t\t{\n\t\t\tpublic Interval Source;\n\t\t\tpublic int Target;\n\n\t\t\tpublic Branch(int start, int end, int target)\n\t\t\t{\n\t\t\t\tthis.Source = new Interval(start, end);\n\t\t\t\tthis.Target = target;\n\t\t\t}\n\n\t\t\tpublic override string ToString()\n\t\t\t{\n\t\t\t\treturn $\"[Branch Source={Source}, Target={Target}]\";\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Finds all branches. Returns list of source offset->target offset mapping.\n\t\t/// Multiple entries for the same source offset are possible (switch statements).\n\t\t/// The result is sorted by source offset.\n\t\t/// </summary>\n\t\t(List<Branch> Branches, BitSet IsAfterUnconditionalBranch) FindAllBranches(BlobReader body)\n\t\t{\n\t\t\tvar result = new List<Branch>();\n\t\t\tvar bitset = new BitSet(body.Length + 1);\n\t\t\tbody.Reset();\n\t\t\tint target;\n\t\t\twhile (body.RemainingBytes > 0)\n\t\t\t{\n\t\t\t\tvar offset = body.Offset;\n\t\t\t\tint endOffset;\n\t\t\t\tvar thisOpCode = body.DecodeOpCode();\n\t\t\t\tswitch (thisOpCode.GetOperandType())\n\t\t\t\t{\n\t\t\t\t\tcase OperandType.BrTarget:\n\t\t\t\t\tcase OperandType.ShortBrTarget:\n\t\t\t\t\t\ttarget = ILParser.DecodeBranchTarget(ref body, thisOpCode);\n\t\t\t\t\t\tendOffset = body.Offset;\n\t\t\t\t\t\tresult.Add(new Branch(offset, endOffset, target));\n\t\t\t\t\t\tbitset[endOffset] = IsUnconditionalBranch(thisOpCode);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase OperandType.Switch:\n\t\t\t\t\t\tvar targets = ILParser.DecodeSwitchTargets(ref body);\n\t\t\t\t\t\tforeach (int t in targets)\n\t\t\t\t\t\t\tresult.Add(new Branch(offset, body.Offset, t));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tILParser.SkipOperand(ref body, thisOpCode);\n\t\t\t\t\t\tbitset[body.Offset] = IsUnconditionalBranch(thisOpCode);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn (result, bitset);\n\t\t}\n\n\t\tstatic bool IsUnconditionalBranch(ILOpCode opCode)\n\t\t{\n\t\t\tswitch (opCode)\n\t\t\t{\n\t\t\t\tcase ILOpCode.Br:\n\t\t\t\tcase ILOpCode.Br_s:\n\t\t\t\tcase ILOpCode.Ret:\n\t\t\t\tcase ILOpCode.Endfilter:\n\t\t\t\tcase ILOpCode.Endfinally:\n\t\t\t\tcase ILOpCode.Throw:\n\t\t\t\tcase ILOpCode.Rethrow:\n\t\t\t\tcase ILOpCode.Leave:\n\t\t\t\tcase ILOpCode.Leave_s:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tvoid SortChildren()\n\t\t{\n\t\t\tChildren.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));\n\t\t\tforeach (ILStructure child in Children)\n\t\t\t\tchild.SortChildren();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the innermost structure containing the specified offset.\n\t\t/// </summary>\n\t\tpublic ILStructure GetInnermost(int offset)\n\t\t{\n\t\t\tDebug.Assert(StartOffset <= offset && offset < EndOffset);\n\t\t\tforeach (ILStructure child in this.Children)\n\t\t\t{\n\t\t\t\tif (child.StartOffset <= offset && offset < child.EndOffset)\n\t\t\t\t\treturn child.GetInnermost(offset);\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.DebugInfo;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.Disassembler\n{\n\t/// <summary>\n\t/// Disassembles a method body.\n\t/// </summary>\n\tpublic class MethodBodyDisassembler\n\t{\n\t\treadonly ITextOutput output;\n\t\treadonly CancellationToken cancellationToken;\n\n\t\t/// <summary>\n\t\t/// Show .try/finally as blocks in IL code; indent loops.\n\t\t/// </summary>\n\t\tpublic bool DetectControlStructure { get; set; } = true;\n\n\t\t/// <summary>\n\t\t/// Show sequence points if debug information is loaded in Cecil.\n\t\t/// </summary>\n\t\tpublic bool ShowSequencePoints { get; set; }\n\n\t\t/// <summary>\n\t\t/// Show metadata tokens for instructions with token operands.\n\t\t/// </summary>\n\t\tpublic bool ShowMetadataTokens { get; set; }\n\n\t\t/// <summary>\n\t\t/// Show metadata tokens for instructions with token operands in base 10.\n\t\t/// </summary>\n\t\tpublic bool ShowMetadataTokensInBase10 { get; set; }\n\n\t\t/// <summary>\n\t\t/// Show raw RVA offset and bytes before each instruction.\n\t\t/// </summary>\n\t\tpublic bool ShowRawRVAOffsetAndBytes { get; set; }\n\n\t\t/// <summary>\n\t\t/// Optional provider for sequence points.\n\t\t/// </summary>\n\t\tpublic IDebugInfoProvider DebugInfo { get; set; }\n\n\t\tIList<DebugInfo.SequencePoint> sequencePoints;\n\t\tint nextSequencePointIndex;\n\n\t\t// cache info\n\t\tMetadataFile module;\n\t\tMetadataReader metadata;\n\t\tMetadataGenericContext genericContext;\n\t\tDisassemblerSignatureTypeProvider signatureDecoder;\n\n\t\tpublic MethodBodyDisassembler(ITextOutput output, CancellationToken cancellationToken)\n\t\t{\n\t\t\tthis.output = output ?? throw new ArgumentNullException(nameof(output));\n\t\t\tthis.cancellationToken = cancellationToken;\n\t\t}\n\n\t\tpublic virtual void Disassemble(MetadataFile module, MethodDefinitionHandle handle)\n\t\t{\n\t\t\tthis.module = module ?? throw new ArgumentNullException(nameof(module));\n\t\t\tmetadata = module.Metadata;\n\t\t\tgenericContext = new MetadataGenericContext(handle, module);\n\t\t\tsignatureDecoder = new DisassemblerSignatureTypeProvider(module, output);\n\t\t\tvar methodDefinition = metadata.GetMethodDefinition(handle);\n\n\t\t\t// start writing IL code\n\t\t\toutput.WriteLine(\"// Method begins at RVA 0x{0:x4}\", methodDefinition.RelativeVirtualAddress);\n\t\t\tif (methodDefinition.RelativeVirtualAddress == 0)\n\t\t\t{\n\t\t\t\toutput.WriteLine(\"// Header size: {0}\", 0);\n\t\t\t\toutput.WriteLine(\"// Code size: {0} (0x{0:x})\", 0);\n\t\t\t\toutput.WriteLine(\".maxstack {0}\", 0);\n\t\t\t\toutput.WriteLine();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tMethodBodyBlock body;\n\t\t\tBlobReader bodyBlockReader;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tbody = module.GetMethodBody(methodDefinition.RelativeVirtualAddress);\n\t\t\t\tbodyBlockReader = module.GetSectionData(methodDefinition.RelativeVirtualAddress).GetReader();\n\t\t\t}\n\t\t\tcatch (BadImageFormatException ex)\n\t\t\t{\n\t\t\t\toutput.WriteLine(\"// {0}\", ex.Message);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar blob = body.GetILReader();\n\t\t\tint headerSize = ILParser.GetHeaderSize(bodyBlockReader);\n\t\t\toutput.WriteLine(\"// Header size: {0}\", headerSize);\n\t\t\toutput.WriteLine(\"// Code size: {0} (0x{0:x})\", blob.Length);\n\t\t\toutput.WriteLine(\".maxstack {0}\", body.MaxStack);\n\n\t\t\tvar entrypointHandle = MetadataTokens.MethodDefinitionHandle(module.CorHeader?.EntryPointTokenOrRelativeVirtualAddress ?? 0);\n\t\t\tif (handle == entrypointHandle)\n\t\t\t\toutput.WriteLine(\".entrypoint\");\n\n\t\t\tDisassembleLocalsBlock(handle, body);\n\t\t\toutput.WriteLine();\n\n\t\t\tsequencePoints = DebugInfo?.GetSequencePoints(handle) ?? EmptyList<DebugInfo.SequencePoint>.Instance;\n\t\t\tnextSequencePointIndex = 0;\n\t\t\tif (DetectControlStructure && blob.Length > 0)\n\t\t\t{\n\t\t\t\tblob.Reset();\n\t\t\t\tBitSet branchTargets = new(blob.Length);\n\t\t\t\tILParser.SetBranchTargets(ref blob, branchTargets);\n\t\t\t\tblob.Reset();\n\t\t\t\tWriteStructureBody(new ILStructure(module, handle, genericContext, body), branchTargets, ref blob, methodDefinition.RelativeVirtualAddress + headerSize);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\twhile (blob.RemainingBytes > 0)\n\t\t\t\t{\n\t\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tWriteInstruction(output, module, handle, ref blob, methodDefinition.RelativeVirtualAddress);\n\t\t\t\t}\n\t\t\t\tWriteExceptionHandlers(module, handle, body);\n\t\t\t}\n\t\t\tsequencePoints = null;\n\t\t}\n\n\t\tvoid DisassembleLocalsBlock(MethodDefinitionHandle method, MethodBodyBlock body)\n\t\t{\n\t\t\tif (body.LocalSignature.IsNil)\n\t\t\t\treturn;\n\t\t\toutput.Write(\".locals\");\n\t\t\tWriteMetadataToken(body.LocalSignature, spaceBefore: true);\n\t\t\tif (body.LocalVariablesInitialized)\n\t\t\t\toutput.Write(\" init\");\n\t\t\tvar blob = metadata.GetStandaloneSignature(body.LocalSignature);\n\t\t\tvar signature = ImmutableArray<Action<ILNameSyntax>>.Empty;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (blob.GetKind() == StandaloneSignatureKind.LocalVariables)\n\t\t\t\t{\n\t\t\t\t\tsignature = blob.DecodeLocalSignature(signatureDecoder, genericContext);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\" /* wrong signature kind */\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (BadImageFormatException ex)\n\t\t\t{\n\t\t\t\toutput.Write($\" /* {ex.Message} */\");\n\t\t\t}\n\t\t\toutput.Write(' ');\n\t\t\toutput.WriteLine(\"(\");\n\t\t\toutput.Indent();\n\t\t\tint index = 0;\n\t\t\tforeach (var v in signature)\n\t\t\t{\n\t\t\t\toutput.WriteLocalReference(\"[\" + index + \"]\", \"loc_\" + index, isDefinition: true);\n\t\t\t\toutput.Write(' ');\n\t\t\t\tv(ILNameSyntax.TypeName);\n\t\t\t\tif (DebugInfo != null && DebugInfo.TryGetName(method, index, out var name))\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\" \" + DisassemblerHelpers.Escape(name));\n\t\t\t\t}\n\t\t\t\tif (index + 1 < signature.Length)\n\t\t\t\t\toutput.Write(',');\n\t\t\t\toutput.WriteLine();\n\t\t\t\tindex++;\n\t\t\t}\n\t\t\toutput.Unindent();\n\t\t\toutput.WriteLine(\")\");\n\t\t}\n\n\t\tinternal void WriteExceptionHandlers(MetadataFile module, MethodDefinitionHandle handle, MethodBodyBlock body)\n\t\t{\n\t\t\tthis.module = module;\n\t\t\tmetadata = module.Metadata;\n\t\t\tgenericContext = new MetadataGenericContext(handle, module);\n\t\t\tsignatureDecoder = new DisassemblerSignatureTypeProvider(module, output);\n\t\t\tvar handlers = body.ExceptionRegions;\n\t\t\tif (!handlers.IsEmpty)\n\t\t\t{\n\t\t\t\toutput.WriteLine();\n\t\t\t\tforeach (var eh in handlers)\n\t\t\t\t{\n\t\t\t\t\teh.WriteTo(module, genericContext, output);\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid WriteStructureHeader(ILStructure s)\n\t\t{\n\t\t\tswitch (s.Type)\n\t\t\t{\n\t\t\t\tcase ILStructureType.Loop:\n\t\t\t\t\toutput.Write(\"// loop start\");\n\t\t\t\t\tif (s.LoopEntryPointOffset >= 0)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(\" (head: \");\n\t\t\t\t\t\tDisassemblerHelpers.WriteOffsetReference(output, s.LoopEntryPointOffset);\n\t\t\t\t\t\toutput.Write(')');\n\t\t\t\t\t}\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\tbreak;\n\t\t\t\tcase ILStructureType.Try:\n\t\t\t\t\toutput.WriteLine(\".try\");\n\t\t\t\t\toutput.WriteLine(\"{\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase ILStructureType.Handler:\n\t\t\t\t\tswitch (s.ExceptionHandler.Kind)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase ExceptionRegionKind.Filter:\n\t\t\t\t\t\t\t// handler block of filter block has no header\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ExceptionRegionKind.Catch:\n\t\t\t\t\t\t\toutput.Write(\"catch\");\n\t\t\t\t\t\t\tif (!s.ExceptionHandler.CatchType.IsNil)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t\t\t\ts.ExceptionHandler.CatchType.WriteTo(s.Module, output, s.GenericContext, ILNameSyntax.TypeName);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ExceptionRegionKind.Finally:\n\t\t\t\t\t\t\toutput.WriteLine(\"finally\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ExceptionRegionKind.Fault:\n\t\t\t\t\t\t\toutput.WriteLine(\"fault\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t\t\t}\n\t\t\t\t\toutput.WriteLine(\"{\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase ILStructureType.Filter:\n\t\t\t\t\toutput.WriteLine(\"filter\");\n\t\t\t\t\toutput.WriteLine(\"{\");\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t}\n\t\t\toutput.Indent();\n\t\t}\n\n\t\tvoid WriteStructureBody(ILStructure s, BitSet branchTargets, ref BlobReader body, int methodRva)\n\t\t{\n\t\t\tbool isFirstInstructionInStructure = true;\n\t\t\tbool prevInstructionWasBranch = false;\n\t\t\tint childIndex = 0;\n\t\t\twhile (body.RemainingBytes > 0 && body.Offset < s.EndOffset)\n\t\t\t{\n\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tint offset = body.Offset;\n\t\t\t\tif (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset)\n\t\t\t\t{\n\t\t\t\t\tILStructure child = s.Children[childIndex++];\n\t\t\t\t\tWriteStructureHeader(child);\n\t\t\t\t\tWriteStructureBody(child, branchTargets, ref body, methodRva);\n\t\t\t\t\tWriteStructureFooter(child);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets[offset]))\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.WriteLine(); // put an empty line after branches, and in front of branch targets\n\t\t\t\t\t}\n\t\t\t\t\tvar currentOpCode = ILParser.DecodeOpCode(ref body);\n\t\t\t\t\tbody.Offset = offset; // reset IL stream\n\t\t\t\t\tWriteInstruction(output, module, s.MethodHandle, ref body, methodRva);\n\t\t\t\t\tprevInstructionWasBranch = currentOpCode.IsBranch()\n\t\t\t\t\t\t|| currentOpCode.IsReturn()\n\t\t\t\t\t\t|| currentOpCode == ILOpCode.Throw\n\t\t\t\t\t\t|| currentOpCode == ILOpCode.Rethrow\n\t\t\t\t\t\t|| currentOpCode == ILOpCode.Switch;\n\t\t\t\t}\n\t\t\t\tisFirstInstructionInStructure = false;\n\t\t\t}\n\t\t}\n\n\t\tvoid WriteStructureFooter(ILStructure s)\n\t\t{\n\t\t\toutput.Unindent();\n\t\t\tswitch (s.Type)\n\t\t\t{\n\t\t\t\tcase ILStructureType.Loop:\n\t\t\t\t\toutput.WriteLine(\"// end loop\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase ILStructureType.Try:\n\t\t\t\t\toutput.WriteLine(\"} // end .try\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase ILStructureType.Handler:\n\t\t\t\t\toutput.WriteLine(\"} // end handler\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase ILStructureType.Filter:\n\t\t\t\t\toutput.WriteLine(\"} // end filter\");\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual void WriteInstruction(ITextOutput output, MetadataFile metadataFile, MethodDefinitionHandle methodHandle, ref BlobReader blob, int methodRva)\n\t\t{\n\t\t\tvar metadata = metadataFile.Metadata;\n\t\t\tint offset = blob.Offset;\n\t\t\tif (ShowSequencePoints && nextSequencePointIndex < sequencePoints?.Count)\n\t\t\t{\n\t\t\t\tvar sp = sequencePoints[nextSequencePointIndex];\n\t\t\t\tif (sp.Offset <= offset)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\"// sequence point: \");\n\t\t\t\t\tif (sp.Offset != offset)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(\"!! at \" + DisassemblerHelpers.OffsetToString(sp.Offset) + \" !!\");\n\t\t\t\t\t}\n\t\t\t\t\tif (sp.IsHidden)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.WriteLine(\"hidden\");\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.WriteLine($\"(line {sp.StartLine}, col {sp.StartColumn}) to (line {sp.EndLine}, col {sp.EndColumn}) in {sp.DocumentUrl}\");\n\t\t\t\t\t}\n\t\t\t\t\tnextSequencePointIndex++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tILOpCode opCode = ILParser.DecodeOpCode(ref blob);\n\t\t\tOperandType opType = opCode.GetOperandType();\n\t\t\tif (opCode.IsDefined() && opType.OperandSize() <= blob.RemainingBytes)\n\t\t\t{\n\t\t\t\tWriteRVA(blob, offset + methodRva, opCode);\n\t\t\t\toutput.WriteLocalReference(DisassemblerHelpers.OffsetToString(offset), offset, isDefinition: true);\n\t\t\t\toutput.Write(\": \");\n\t\t\t\tWriteOpCode(opCode);\n\t\t\t\tswitch (opCode.GetOperandType())\n\t\t\t\t{\n\t\t\t\t\tcase OperandType.BrTarget:\n\t\t\t\t\tcase OperandType.ShortBrTarget:\n\t\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t\tint targetOffset = ILParser.DecodeBranchTarget(ref blob, opCode);\n\t\t\t\t\t\toutput.WriteLocalReference($\"IL_{targetOffset:x4}\", targetOffset);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase OperandType.Field:\n\t\t\t\t\tcase OperandType.Method:\n\t\t\t\t\tcase OperandType.Sig:\n\t\t\t\t\tcase OperandType.Type:\n\t\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t\tint metadataToken = blob.ReadInt32();\n\t\t\t\t\t\tEntityHandle? handle = MetadataTokenHelpers.TryAsEntityHandle(metadataToken);\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\thandle?.WriteTo(module, output, genericContext);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\thandle = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tWriteMetadataToken(handle, metadataToken, spaceBefore: true);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase OperandType.Tok:\n\t\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t\tmetadataToken = blob.ReadInt32();\n\t\t\t\t\t\thandle = MetadataTokenHelpers.TryAsEntityHandle(metadataToken);\n\t\t\t\t\t\tswitch (handle?.Kind)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase HandleKind.MemberReference:\n\t\t\t\t\t\t\t\tswitch (metadata.GetMemberReference((MemberReferenceHandle)handle).GetKind())\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tcase MemberReferenceKind.Method:\n\t\t\t\t\t\t\t\t\t\toutput.Write(\"method \");\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase MemberReferenceKind.Field:\n\t\t\t\t\t\t\t\t\t\toutput.Write(\"field \");\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase HandleKind.FieldDefinition:\n\t\t\t\t\t\t\t\toutput.Write(\"field \");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\t\t\t\toutput.Write(\"method \");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\thandle?.WriteTo(module, output, genericContext);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\thandle = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tWriteMetadataToken(handle, metadataToken, spaceBefore: true);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase OperandType.ShortI:\n\t\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t\tDisassemblerHelpers.WriteOperand(output, blob.ReadSByte());\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase OperandType.I:\n\t\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t\tDisassemblerHelpers.WriteOperand(output, blob.ReadInt32());\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase OperandType.I8:\n\t\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t\tDisassemblerHelpers.WriteOperand(output, blob.ReadInt64());\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase OperandType.ShortR:\n\t\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t\tDisassemblerHelpers.WriteOperand(output, blob.ReadSingle());\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase OperandType.R:\n\t\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t\tDisassemblerHelpers.WriteOperand(output, blob.ReadDouble());\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase OperandType.String:\n\t\t\t\t\t\tmetadataToken = blob.ReadInt32();\n\t\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t\tUserStringHandle? userString;\n\t\t\t\t\t\tstring text;\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tuserString = MetadataTokens.UserStringHandle(metadataToken);\n\t\t\t\t\t\t\ttext = metadata.GetUserString(userString.Value);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tuserString = null;\n\t\t\t\t\t\t\ttext = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (userString != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tDisassemblerHelpers.WriteOperand(output, text);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tWriteMetadataToken(userString, metadataToken, spaceBefore: true);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase OperandType.Switch:\n\t\t\t\t\t\tvar tmp = blob;\n\t\t\t\t\t\tint[] targets = ILParser.DecodeSwitchTargets(ref blob);\n\t\t\t\t\t\tif (ShowRawRVAOffsetAndBytes)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toutput.WriteLine(\" (\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toutput.Write(\" (\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttmp.ReadInt32();\n\t\t\t\t\t\tfor (int i = 0; i < targets.Length; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (ShowRawRVAOffsetAndBytes)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\toutput.WriteLine(\",\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\toutput.Write(\", \");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (ShowRawRVAOffsetAndBytes)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutput.Write(\"/*              \");\n\t\t\t\t\t\t\t\toutput.Write($\"{tmp.ReadByte():X2}{tmp.ReadByte():X2}{tmp.ReadByte():X2}{tmp.ReadByte():X2}\");\n\t\t\t\t\t\t\t\toutput.Write(\"         */ \");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (ShowRawRVAOffsetAndBytes)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutput.Write(\"                 \");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\toutput.WriteLocalReference($\"IL_{targets[i]:x4}\", targets[i]);\n\t\t\t\t\t\t}\n\t\t\t\t\t\toutput.Write(\")\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase OperandType.Variable:\n\t\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t\tint index = blob.ReadUInt16();\n\t\t\t\t\t\tif (opCode == ILOpCode.Ldloc || opCode == ILOpCode.Ldloca || opCode == ILOpCode.Stloc)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tDisassemblerHelpers.WriteVariableReference(output, metadata, methodHandle, index);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tDisassemblerHelpers.WriteParameterReference(output, metadata, methodHandle, index);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase OperandType.ShortVariable:\n\t\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t\tindex = blob.ReadByte();\n\t\t\t\t\t\tif (opCode == ILOpCode.Ldloc_s || opCode == ILOpCode.Ldloca_s || opCode == ILOpCode.Stloc_s)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tDisassemblerHelpers.WriteVariableReference(output, metadata, methodHandle, index);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tDisassemblerHelpers.WriteParameterReference(output, metadata, methodHandle, index);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tushort opCodeValue = (ushort)opCode;\n\t\t\t\tif (opCodeValue > 0xFF)\n\t\t\t\t{\n\t\t\t\t\tif (ShowRawRVAOffsetAndBytes)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(\"/* \");\n\t\t\t\t\t\toutput.Write($\"0x{offset + methodRva:X8} {(ushort)opCode >> 8:X2}\");\n\t\t\t\t\t\toutput.Write(\"                 */ \");\n\t\t\t\t\t}\n\t\t\t\t\toutput.WriteLocalReference(DisassemblerHelpers.OffsetToString(offset), offset, isDefinition: true);\n\t\t\t\t\toutput.Write(\": \");\n\t\t\t\t\t// split 16-bit value into two emitbyte directives\n\t\t\t\t\toutput.WriteLine($\".emitbyte 0x{(byte)(opCodeValue >> 8):x}\");\n\t\t\t\t\tif (ShowRawRVAOffsetAndBytes)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(\"/* \");\n\t\t\t\t\t\toutput.Write($\"0x{offset + methodRva + 1:X8} {(ushort)opCode & 0xFF:X2}\");\n\t\t\t\t\t\toutput.Write(\"                 */ \");\n\t\t\t\t\t}\n\t\t\t\t\t// add label\n\t\t\t\t\toutput.WriteLocalReference(DisassemblerHelpers.OffsetToString(offset + 1), offset + 1, isDefinition: true);\n\t\t\t\t\toutput.Write(\": \");\n\t\t\t\t\toutput.Write($\".emitbyte 0x{(byte)(opCodeValue & 0xFF):x}\");\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (ShowRawRVAOffsetAndBytes)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(\"/* \");\n\t\t\t\t\t\toutput.Write($\"0x{offset + methodRva:X8} {(ushort)opCode & 0xFF:X2}\");\n\t\t\t\t\t\toutput.Write(\"                 */ \");\n\t\t\t\t\t}\n\t\t\t\t\toutput.WriteLocalReference(DisassemblerHelpers.OffsetToString(offset), offset, isDefinition: true);\n\t\t\t\t\toutput.Write(\": \");\n\t\t\t\t\toutput.Write($\".emitbyte 0x{(byte)opCodeValue:x}\");\n\t\t\t\t}\n\t\t\t}\n\t\t\toutput.WriteLine();\n\t\t}\n\n\t\tvoid WriteRVA(BlobReader blob, int offset, ILOpCode opCode)\n\t\t{\n\t\t\tif (ShowRawRVAOffsetAndBytes)\n\t\t\t{\n\t\t\t\toutput.Write(\"/* \");\n\t\t\t\tvar tmp = blob;\n\t\t\t\tif (opCode == ILOpCode.Switch)\n\t\t\t\t{\n\t\t\t\t\ttmp.ReadInt32();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tILParser.SkipOperand(ref tmp, opCode);\n\t\t\t\t}\n\t\t\t\toutput.Write($\"0x{offset:X8} {(ushort)opCode:X2}\");\n\t\t\t\tint appendSpaces = (ushort)opCode > 0xFF ? 14 : 16;\n\t\t\t\twhile (blob.Offset < tmp.Offset)\n\t\t\t\t{\n\t\t\t\t\toutput.Write($\"{blob.ReadByte():X2}\");\n\t\t\t\t\tappendSpaces -= 2;\n\t\t\t\t}\n\t\t\t\tif (appendSpaces > 0)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(new string(' ', appendSpaces));\n\t\t\t\t}\n\t\t\t\toutput.Write(\" */ \");\n\t\t\t}\n\t\t}\n\n\t\tprivate void WriteOpCode(ILOpCode opCode)\n\t\t{\n\t\t\tvar opCodeInfo = new OpCodeInfo(opCode, opCode.GetDisplayName());\n\t\t\tstring index;\n\t\t\tswitch (opCode)\n\t\t\t{\n\t\t\t\tcase ILOpCode.Ldarg_0:\n\t\t\t\tcase ILOpCode.Ldarg_1:\n\t\t\t\tcase ILOpCode.Ldarg_2:\n\t\t\t\tcase ILOpCode.Ldarg_3:\n\t\t\t\t\toutput.WriteReference(opCodeInfo, omitSuffix: true);\n\t\t\t\t\tindex = opCodeInfo.Name.Substring(6);\n\t\t\t\t\toutput.WriteLocalReference(index, \"param_\" + index);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ILOpCode.Ldloc_0:\n\t\t\t\tcase ILOpCode.Ldloc_1:\n\t\t\t\tcase ILOpCode.Ldloc_2:\n\t\t\t\tcase ILOpCode.Ldloc_3:\n\t\t\t\tcase ILOpCode.Stloc_0:\n\t\t\t\tcase ILOpCode.Stloc_1:\n\t\t\t\tcase ILOpCode.Stloc_2:\n\t\t\t\tcase ILOpCode.Stloc_3:\n\t\t\t\t\toutput.WriteReference(opCodeInfo, omitSuffix: true);\n\t\t\t\t\tindex = opCodeInfo.Name.Substring(6);\n\t\t\t\t\toutput.WriteLocalReference(index, \"loc_\" + index);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\toutput.WriteReference(opCodeInfo);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tprivate void WriteMetadataToken(EntityHandle handle, bool spaceBefore)\n\t\t{\n\t\t\tWriteMetadataToken(handle, MetadataTokens.GetToken(handle), spaceBefore);\n\t\t}\n\n\t\tprivate void WriteMetadataToken(Handle? handle, int metadataToken, bool spaceBefore)\n\t\t{\n\t\t\tReflectionDisassembler.WriteMetadataToken(output, module, handle, metadataToken,\n\t\t\t\tspaceAfter: false, spaceBefore, ShowMetadataTokens, ShowMetadataTokensInBase10);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Disassembler/OpCodeInfo.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.Decompiler.Disassembler\n{\n\tpublic struct OpCodeInfo : IEquatable<OpCodeInfo>\n\t{\n\t\tpublic readonly ILOpCode Code;\n\t\tpublic readonly string Name;\n\n\t\tstring encodedName;\n\n\t\tpublic OpCodeInfo(ILOpCode code, string name)\n\t\t{\n\t\t\tthis.Code = code;\n\t\t\tthis.Name = name ?? \"\";\n\t\t\tthis.encodedName = null;\n\t\t}\n\n\t\tpublic bool Equals(OpCodeInfo other)\n\t\t{\n\t\t\treturn other.Code == this.Code && other.Name == this.Name;\n\t\t}\n\n\t\tpublic static bool operator ==(OpCodeInfo lhs, OpCodeInfo rhs) => lhs.Equals(rhs);\n\t\tpublic static bool operator !=(OpCodeInfo lhs, OpCodeInfo rhs) => !(lhs == rhs);\n\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\tif (obj is OpCodeInfo opCode)\n\t\t\t\treturn Equals(opCode);\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn unchecked(982451629 * Code.GetHashCode() + 982451653 * Name.GetHashCode());\n\t\t}\n\n\t\tpublic string Link => \"https://docs.microsoft.com/dotnet/api/system.reflection.emit.opcodes.\" + EncodedName.ToLowerInvariant();\n\t\tpublic string EncodedName {\n\t\t\tget {\n\t\t\t\tif (encodedName != null)\n\t\t\t\t\treturn encodedName;\n\t\t\t\tswitch (Name)\n\t\t\t\t{\n\t\t\t\t\tcase \"constrained.\":\n\t\t\t\t\t\tencodedName = \"Constrained\";\n\t\t\t\t\t\treturn encodedName;\n\t\t\t\t\tcase \"no.\":\n\t\t\t\t\t\tencodedName = \"No\";\n\t\t\t\t\t\treturn encodedName;\n\t\t\t\t\tcase \"readonly.\":\n\t\t\t\t\t\tencodedName = \"Reaonly\";\n\t\t\t\t\t\treturn encodedName;\n\t\t\t\t\tcase \"tail.\":\n\t\t\t\t\t\tencodedName = \"Tailcall\";\n\t\t\t\t\t\treturn encodedName;\n\t\t\t\t\tcase \"unaligned.\":\n\t\t\t\t\t\tencodedName = \"Unaligned\";\n\t\t\t\t\t\treturn encodedName;\n\t\t\t\t\tcase \"volatile.\":\n\t\t\t\t\t\tencodedName = \"Volatile\";\n\t\t\t\t\t\treturn encodedName;\n\t\t\t\t}\n\t\t\t\tstring text = \"\";\n\t\t\t\tbool toUpperCase = true;\n\t\t\t\tforeach (var ch in Name)\n\t\t\t\t{\n\t\t\t\t\tif (ch == '.')\n\t\t\t\t\t{\n\t\t\t\t\t\ttext += '_';\n\t\t\t\t\t\ttoUpperCase = true;\n\t\t\t\t\t}\n\t\t\t\t\telse if (toUpperCase)\n\t\t\t\t\t{\n\t\t\t\t\t\ttext += char.ToUpperInvariant(ch);\n\t\t\t\t\t\ttoUpperCase = false;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\ttext += ch;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tencodedName = text;\n\t\t\t\treturn encodedName;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.DebugInfo;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Disassembler\n{\n\t/// <summary>\n\t/// Disassembles type and member definitions.\n\t/// </summary>\n\tpublic sealed class ReflectionDisassembler\n\t{\n\t\treadonly ITextOutput output;\n\t\tCancellationToken cancellationToken;\n\t\tbool isInType;   // whether we are currently disassembling a whole type (-> defaultCollapsed for foldings)\n\t\tMethodBodyDisassembler methodBodyDisassembler;\n\n\t\tpublic bool DetectControlStructure {\n\t\t\tget => methodBodyDisassembler.DetectControlStructure;\n\t\t\tset => methodBodyDisassembler.DetectControlStructure = value;\n\t\t}\n\n\t\tpublic bool ShowSequencePoints {\n\t\t\tget => methodBodyDisassembler.ShowSequencePoints;\n\t\t\tset => methodBodyDisassembler.ShowSequencePoints = value;\n\t\t}\n\n\t\tpublic bool ShowMetadataTokens {\n\t\t\tget => methodBodyDisassembler.ShowMetadataTokens;\n\t\t\tset => methodBodyDisassembler.ShowMetadataTokens = value;\n\t\t}\n\n\t\tpublic bool ShowMetadataTokensInBase10 {\n\t\t\tget => methodBodyDisassembler.ShowMetadataTokensInBase10;\n\t\t\tset => methodBodyDisassembler.ShowMetadataTokensInBase10 = value;\n\t\t}\n\n\t\tpublic bool ShowRawRVAOffsetAndBytes {\n\t\t\tget => methodBodyDisassembler.ShowRawRVAOffsetAndBytes;\n\t\t\tset => methodBodyDisassembler.ShowRawRVAOffsetAndBytes = value;\n\t\t}\n\n\t\tpublic IDebugInfoProvider DebugInfo {\n\t\t\tget => methodBodyDisassembler.DebugInfo;\n\t\t\tset => methodBodyDisassembler.DebugInfo = value;\n\t\t}\n\n\t\tpublic bool ExpandMemberDefinitions { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets or sets whether custom attribute blobs should be decoded or dumped as raw bytes. Default is <see langword=\"false\"/>.\n\t\t/// Setting this value to <see langword=\"true\"/> (roughly) corresponds to the <c>/CAVERBAL</c> switch of <c>ildasm</c>.\n\t\t/// </summary>\n\t\tpublic bool DecodeCustomAttributeBlobs { get; set; }\n\n\t\tpublic IAssemblyResolver AssemblyResolver { get; set; }\n\n\t\tpublic IEntityProcessor EntityProcessor { get; set; }\n\n\t\tpublic ReflectionDisassembler(ITextOutput output, CancellationToken cancellationToken)\n\t\t\t: this(output, new MethodBodyDisassembler(output, cancellationToken), cancellationToken)\n\t\t{\n\t\t}\n\n\t\tpublic ReflectionDisassembler(ITextOutput output, MethodBodyDisassembler methodBodyDisassembler, CancellationToken cancellationToken)\n\t\t{\n\t\t\tif (output == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(output));\n\t\t\tthis.output = output;\n\t\t\tthis.cancellationToken = cancellationToken;\n\t\t\tthis.methodBodyDisassembler = methodBodyDisassembler;\n\t\t}\n\n\t\t#region Disassemble Method\n\t\tinternal static readonly EnumNameCollection<MethodAttributes> methodAttributeFlags = new EnumNameCollection<MethodAttributes>() {\n\t\t\t{ MethodAttributes.Final, \"final\" },\n\t\t\t{ MethodAttributes.HideBySig, \"hidebysig\" },\n\t\t\t{ MethodAttributes.SpecialName, \"specialname\" },\n\t\t\t{ MethodAttributes.PinvokeImpl, null },\t// handled separately\n\t\t\t{ MethodAttributes.UnmanagedExport, \"export\" },\n\t\t\t{ MethodAttributes.RTSpecialName, \"rtspecialname\" },\n\t\t\t{ MethodAttributes.RequireSecObject, \"reqsecobj\" },\n\t\t\t{ MethodAttributes.NewSlot, \"newslot\" },\n\t\t\t{ MethodAttributes.CheckAccessOnOverride, \"strict\" },\n\t\t\t{ MethodAttributes.Abstract, \"abstract\" },\n\t\t\t{ MethodAttributes.Virtual, \"virtual\" },\n\t\t\t{ MethodAttributes.Static, \"static\" },\n\t\t\t{ MethodAttributes.HasSecurity, null },\t// ?? also invisible in ILDasm\n\t\t};\n\n\t\tinternal static readonly EnumNameCollection<MethodAttributes> methodVisibility = new EnumNameCollection<MethodAttributes>() {\n\t\t\t{ MethodAttributes.Private, \"private\" },\n\t\t\t{ MethodAttributes.FamANDAssem, \"famandassem\" },\n\t\t\t{ MethodAttributes.Assembly, \"assembly\" },\n\t\t\t{ MethodAttributes.Family, \"family\" },\n\t\t\t{ MethodAttributes.FamORAssem, \"famorassem\" },\n\t\t\t{ MethodAttributes.Public, \"public\" },\n\t\t};\n\n\t\tinternal static readonly EnumNameCollection<SignatureCallingConvention> callingConvention = new EnumNameCollection<SignatureCallingConvention>() {\n\t\t\t{ SignatureCallingConvention.CDecl, \"unmanaged cdecl\" },\n\t\t\t{ SignatureCallingConvention.StdCall, \"unmanaged stdcall\" },\n\t\t\t{ SignatureCallingConvention.ThisCall, \"unmanaged thiscall\" },\n\t\t\t{ SignatureCallingConvention.FastCall, \"unmanaged fastcall\" },\n\t\t\t{ SignatureCallingConvention.VarArgs, \"vararg\" },\n\t\t\t{ SignatureCallingConvention.Default, null },\n\t\t};\n\n\t\tinternal static readonly EnumNameCollection<MethodImplAttributes> methodCodeType = new EnumNameCollection<MethodImplAttributes>() {\n\t\t\t{ MethodImplAttributes.IL, \"cil\" },\n\t\t\t{ MethodImplAttributes.Native, \"native\" },\n\t\t\t{ MethodImplAttributes.OPTIL, \"optil\" },\n\t\t\t{ MethodImplAttributes.Runtime, \"runtime\" },\n\t\t};\n\n\t\tinternal static readonly EnumNameCollection<MethodImplAttributes> methodImpl = new EnumNameCollection<MethodImplAttributes>() {\n\t\t\t{ MethodImplAttributes.Synchronized, \"synchronized\" },\n\t\t\t{ MethodImplAttributes.NoInlining, \"noinlining\" },\n\t\t\t{ MethodImplAttributes.NoOptimization, \"nooptimization\" },\n\t\t\t{ MethodImplAttributes.PreserveSig, \"preservesig\" },\n\t\t\t{ MethodImplAttributes.InternalCall, \"internalcall\" },\n\t\t\t{ MethodImplAttributes.ForwardRef, \"forwardref\" },\n\t\t\t{ MethodImplAttributes.AggressiveInlining, \"aggressiveinlining\" },\n\t\t};\n\n\t\tpublic void DisassembleMethod(MetadataFile module, MethodDefinitionHandle handle)\n\t\t{\n\t\t\tvar genericContext = new MetadataGenericContext(handle, module);\n\t\t\t// write method header\n\t\t\toutput.WriteReference(module, handle, \".method\", isDefinition: true);\n\t\t\toutput.Write(\" \");\n\t\t\tDisassembleMethodHeaderInternal(module, handle, genericContext);\n\t\t\tDisassembleMethodBlock(module, handle, genericContext);\n\t\t}\n\n\t\tpublic void DisassembleMethodHeader(MetadataFile module, MethodDefinitionHandle handle)\n\t\t{\n\t\t\tvar genericContext = new MetadataGenericContext(handle, module);\n\t\t\t// write method header\n\t\t\toutput.WriteReference(module, handle, \".method\", isDefinition: true);\n\t\t\toutput.Write(\" \");\n\t\t\tDisassembleMethodHeaderInternal(module, handle, genericContext);\n\t\t}\n\n\t\tvoid DisassembleMethodHeaderInternal(MetadataFile module, MethodDefinitionHandle handle, MetadataGenericContext genericContext)\n\t\t{\n\t\t\tvar metadata = module.Metadata;\n\n\t\t\tWriteMetadataToken(output, module, handle, MetadataTokens.GetToken(handle),\n\t\t\t\tspaceAfter: true, spaceBefore: false, ShowMetadataTokens, ShowMetadataTokensInBase10);\n\t\t\tvar methodDefinition = metadata.GetMethodDefinition(handle);\n\t\t\t//    .method public hidebysig  specialname\n\t\t\t//               instance default class [mscorlib]System.IO.TextWriter get_BaseWriter ()  cil managed\n\t\t\t//\n\t\t\t//emit flags\n\t\t\tWriteEnum(methodDefinition.Attributes & MethodAttributes.MemberAccessMask, methodVisibility, output);\n\t\t\tWriteFlags(methodDefinition.Attributes & ~MethodAttributes.MemberAccessMask, methodAttributeFlags, output);\n\t\t\tbool isCompilerControlled = (methodDefinition.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope;\n\t\t\tif (isCompilerControlled)\n\t\t\t\toutput.Write(\"privatescope \");\n\n\t\t\tif ((methodDefinition.Attributes & MethodAttributes.PinvokeImpl) == MethodAttributes.PinvokeImpl)\n\t\t\t{\n\t\t\t\toutput.Write(\"pinvokeimpl\");\n\t\t\t\tvar info = methodDefinition.GetImport();\n\t\t\t\tif (!info.Module.IsNil)\n\t\t\t\t{\n\t\t\t\t\tvar moduleRef = metadata.GetModuleReference(info.Module);\n\t\t\t\t\toutput.Write(\"(\\\"\" + DisassemblerHelpers.EscapeString(metadata.GetString(moduleRef.Name)) + \"\\\"\");\n\n\t\t\t\t\tif (!info.Name.IsNil && metadata.GetString(info.Name) != metadata.GetString(methodDefinition.Name))\n\t\t\t\t\t\toutput.Write(\" as \\\"\" + DisassemblerHelpers.EscapeString(metadata.GetString(info.Name)) + \"\\\"\");\n\n\t\t\t\t\tif ((info.Attributes & MethodImportAttributes.ExactSpelling) == MethodImportAttributes.ExactSpelling)\n\t\t\t\t\t\toutput.Write(\" nomangle\");\n\n\t\t\t\t\tswitch (info.Attributes & MethodImportAttributes.CharSetMask)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase MethodImportAttributes.CharSetAnsi:\n\t\t\t\t\t\t\toutput.Write(\" ansi\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase MethodImportAttributes.CharSetAuto:\n\t\t\t\t\t\t\toutput.Write(\" autochar\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase MethodImportAttributes.CharSetUnicode:\n\t\t\t\t\t\t\toutput.Write(\" unicode\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ((info.Attributes & MethodImportAttributes.SetLastError) == MethodImportAttributes.SetLastError)\n\t\t\t\t\t\toutput.Write(\" lasterr\");\n\n\t\t\t\t\tswitch (info.Attributes & MethodImportAttributes.CallingConventionMask)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase MethodImportAttributes.CallingConventionCDecl:\n\t\t\t\t\t\t\toutput.Write(\" cdecl\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase MethodImportAttributes.CallingConventionFastCall:\n\t\t\t\t\t\t\toutput.Write(\" fastcall\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase MethodImportAttributes.CallingConventionStdCall:\n\t\t\t\t\t\t\toutput.Write(\" stdcall\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase MethodImportAttributes.CallingConventionThisCall:\n\t\t\t\t\t\t\toutput.Write(\" thiscall\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase MethodImportAttributes.CallingConventionWinApi:\n\t\t\t\t\t\t\toutput.Write(\" winapi\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\toutput.Write(')');\n\t\t\t\t}\n\t\t\t\toutput.Write(' ');\n\t\t\t}\n\n\t\t\toutput.WriteLine();\n\t\t\toutput.Indent();\n\t\t\tvar declaringType = methodDefinition.GetDeclaringType();\n\t\t\tMethodSignature<Action<ILNameSyntax>>? signature;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar signatureProvider = new DisassemblerSignatureTypeProvider(module, output);\n\t\t\t\tsignature = methodDefinition.DecodeSignature(signatureProvider, genericContext);\n\t\t\t\tif (signature.Value.Header.HasExplicitThis)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\"instance explicit \");\n\t\t\t\t}\n\t\t\t\telse if (signature.Value.Header.IsInstance)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\"instance \");\n\t\t\t\t}\n\n\t\t\t\t//call convention\n\t\t\t\tWriteEnum(signature.Value.Header.CallingConvention, callingConvention, output);\n\n\t\t\t\t//return type\n\t\t\t\tsignature.Value.ReturnType(ILNameSyntax.Signature);\n\t\t\t}\n\t\t\tcatch (BadImageFormatException)\n\t\t\t{\n\t\t\t\tsignature = null;\n\t\t\t\toutput.Write(\"<bad signature>\");\n\t\t\t}\n\t\t\toutput.Write(' ');\n\n\t\t\tvar parameters = methodDefinition.GetParameters();\n\t\t\tif (parameters.Count > 0)\n\t\t\t{\n\t\t\t\tvar firstParam = metadata.GetParameter(parameters.First());\n\t\t\t\tif (firstParam.SequenceNumber == 0)\n\t\t\t\t{\n\t\t\t\t\tvar marshallingDesc = firstParam.GetMarshallingDescriptor();\n\t\t\t\t\tif (!marshallingDesc.IsNil)\n\t\t\t\t\t{\n\t\t\t\t\t\tWriteMarshalInfo(metadata.GetBlobReader(marshallingDesc));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isCompilerControlled)\n\t\t\t{\n\t\t\t\toutput.Write(DisassemblerHelpers.Escape(metadata.GetString(methodDefinition.Name) + \"$PST\" + MetadataTokens.GetToken(handle).ToString(\"X8\")));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\toutput.Write(DisassemblerHelpers.Escape(metadata.GetString(methodDefinition.Name)));\n\t\t\t}\n\n\t\t\tWriteTypeParameters(output, module, genericContext, methodDefinition.GetGenericParameters());\n\n\t\t\t//( params )\n\t\t\toutput.Write(\" (\");\n\t\t\tif (signature?.ParameterTypes.Length > 0)\n\t\t\t{\n\t\t\t\toutput.WriteLine();\n\t\t\t\toutput.Indent();\n\t\t\t\tWriteParameters(metadata, parameters, signature.Value);\n\t\t\t\toutput.Unindent();\n\t\t\t}\n\t\t\toutput.Write(\") \");\n\t\t\t//cil managed\n\t\t\tWriteEnum(methodDefinition.ImplAttributes & MethodImplAttributes.CodeTypeMask, methodCodeType, output);\n\t\t\tif ((methodDefinition.ImplAttributes & MethodImplAttributes.ManagedMask) == MethodImplAttributes.Managed)\n\t\t\t\toutput.Write(\"managed \");\n\t\t\telse\n\t\t\t\toutput.Write(\"unmanaged \");\n\t\t\tWriteFlags(methodDefinition.ImplAttributes & ~(MethodImplAttributes.CodeTypeMask | MethodImplAttributes.ManagedMask), methodImpl, output);\n\n\t\t\toutput.Unindent();\n\t\t}\n\n\t\tinternal static void WriteMetadataToken(ITextOutput output, MetadataFile module, Handle? handle,\n\t\t\tint metadataToken, bool spaceAfter, bool spaceBefore, bool showMetadataTokens, bool base10)\n\t\t{\n\t\t\t// handle can be null in case of errors, if that's the case, we always want to print a comment,\n\t\t\t// with the metadataToken.\n\t\t\tif (showMetadataTokens || handle == null)\n\t\t\t{\n\t\t\t\tif (spaceBefore)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(' ');\n\t\t\t\t}\n\t\t\t\toutput.Write(\"/* \");\n\t\t\t\tstring format = base10 ? null : \"X8\";\n\t\t\t\tif (handle == null || !handle.Value.IsEntityHandle())\n\t\t\t\t{\n\t\t\t\t\toutput.Write(metadataToken.ToString(format));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\toutput.WriteReference(module, handle.GetValueOrDefault(),\n\t\t\t\t\t\tmetadataToken.ToString(format), \"metadata\");\n\t\t\t\t}\n\t\t\t\toutput.Write(\" */\");\n\t\t\t\tif (spaceAfter)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(' ');\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (spaceBefore && spaceAfter)\n\t\t\t{\n\t\t\t\toutput.Write(' ');\n\t\t\t}\n\t\t}\n\n\t\tvoid DisassembleMethodBlock(MetadataFile module, MethodDefinitionHandle handle,\n\t\t\tMetadataGenericContext genericContext)\n\t\t{\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar methodDefinition = metadata.GetMethodDefinition(handle);\n\n\t\t\tOpenBlock(defaultCollapsed: isInType);\n\t\t\tWriteAttributes(module, methodDefinition.GetCustomAttributes());\n\t\t\tforeach (var h in handle.GetMethodImplementations(metadata))\n\t\t\t{\n\t\t\t\tvar impl = metadata.GetMethodImplementation(h);\n\t\t\t\toutput.Write(\".override method \");\n\t\t\t\timpl.MethodDeclaration.WriteTo(module, output, genericContext);\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\n\t\t\tforeach (var p in methodDefinition.GetGenericParameters())\n\t\t\t{\n\t\t\t\tWriteGenericParametersAndAttributes(module, genericContext, p);\n\t\t\t}\n\t\t\tforeach (var p in methodDefinition.GetParameters())\n\t\t\t{\n\t\t\t\tWriteParameterAttributes(module, p);\n\t\t\t}\n\t\t\tWriteSecurityDeclarations(module, methodDefinition.GetDeclarativeSecurityAttributes());\n\n\t\t\tif (methodDefinition.HasBody())\n\t\t\t{\n\t\t\t\tmethodBodyDisassembler.Disassemble(module, handle);\n\t\t\t}\n\t\t\tvar declaringType = metadata.GetTypeDefinition(methodDefinition.GetDeclaringType());\n\t\t\tCloseBlock(\"end of method \" + DisassemblerHelpers.Escape(metadata.GetString(declaringType.Name))\n\t\t\t\t+ \"::\" + DisassemblerHelpers.Escape(metadata.GetString(methodDefinition.Name)));\n\t\t}\n\n\t\t#region Write Security Declarations\n\t\tvoid WriteSecurityDeclarations(MetadataFile module, DeclarativeSecurityAttributeHandleCollection secDeclProvider)\n\t\t{\n\t\t\tif (secDeclProvider.Count == 0)\n\t\t\t\treturn;\n\t\t\tforeach (var h in secDeclProvider)\n\t\t\t{\n\t\t\t\toutput.Write(\".permissionset \");\n\t\t\t\tvar secdecl = module.Metadata.GetDeclarativeSecurityAttribute(h);\n\t\t\t\tswitch ((ushort)secdecl.Action)\n\t\t\t\t{\n\t\t\t\t\tcase 1: // DeclarativeSecurityAction.Request\n\t\t\t\t\t\toutput.Write(\"request\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2: // DeclarativeSecurityAction.Demand\n\t\t\t\t\t\toutput.Write(\"demand\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 3: // DeclarativeSecurityAction.Assert\n\t\t\t\t\t\toutput.Write(\"assert\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 4: // DeclarativeSecurityAction.Deny\n\t\t\t\t\t\toutput.Write(\"deny\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 5: // DeclarativeSecurityAction.PermitOnly\n\t\t\t\t\t\toutput.Write(\"permitonly\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 6: // DeclarativeSecurityAction.LinkDemand\n\t\t\t\t\t\toutput.Write(\"linkcheck\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 7: // DeclarativeSecurityAction.InheritDemand\n\t\t\t\t\t\toutput.Write(\"inheritcheck\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 8: // DeclarativeSecurityAction.RequestMinimum\n\t\t\t\t\t\toutput.Write(\"reqmin\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 9: // DeclarativeSecurityAction.RequestOptional\n\t\t\t\t\t\toutput.Write(\"reqopt\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 10: // DeclarativeSecurityAction.RequestRefuse\n\t\t\t\t\t\toutput.Write(\"reqrefuse\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 11: // DeclarativeSecurityAction.PreJitGrant\n\t\t\t\t\t\toutput.Write(\"prejitgrant\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 12: // DeclarativeSecurityAction.PreJitDeny\n\t\t\t\t\t\toutput.Write(\"prejitdeny\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 13: // DeclarativeSecurityAction.NonCasDemand\n\t\t\t\t\t\toutput.Write(\"noncasdemand\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 14: // DeclarativeSecurityAction.NonCasLinkDemand\n\t\t\t\t\t\toutput.Write(\"noncaslinkdemand\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 15: // DeclarativeSecurityAction.NonCasInheritance\n\t\t\t\t\t\toutput.Write(\"noncasinheritance\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\toutput.Write(secdecl.Action.ToString());\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tvar blob = module.Metadata.GetBlobReader(secdecl.PermissionSet);\n\t\t\t\tif (AssemblyResolver == null)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\" = \");\n\t\t\t\t\tWriteBlob(blob);\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t}\n\t\t\t\telse if ((char)blob.ReadByte() != '.')\n\t\t\t\t{\n\t\t\t\t\tblob.Reset();\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\toutput.Indent();\n\t\t\t\t\toutput.Write(\"bytearray\");\n\t\t\t\t\tWriteBlob(blob);\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\toutput.Unindent();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar outputWithRollback = new TextOutputWithRollback(output);\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tTryDecodeSecurityDeclaration(outputWithRollback, blob, module);\n\t\t\t\t\t\toutputWithRollback.Commit();\n\t\t\t\t\t}\n\t\t\t\t\tcatch (Exception ex) when (ex is BadImageFormatException || ex is EnumUnderlyingTypeResolveException)\n\t\t\t\t\t{\n\t\t\t\t\t\tblob.Reset();\n\t\t\t\t\t\toutput.Write(\" = \");\n\t\t\t\t\t\tWriteBlob(blob);\n\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tclass SecurityDeclarationDecoder : ICustomAttributeTypeProvider<(PrimitiveTypeCode Code, string Name)>\n\t\t{\n\t\t\treadonly ITextOutput output;\n\t\t\treadonly IAssemblyResolver resolver;\n\t\t\treadonly MetadataFile module;\n\n\t\t\tpublic SecurityDeclarationDecoder(ITextOutput output, IAssemblyResolver resolver, MetadataFile module)\n\t\t\t{\n\t\t\t\tthis.output = output;\n\t\t\t\tthis.resolver = resolver;\n\t\t\t\tthis.module = module;\n\t\t\t}\n\n\t\t\tpublic (PrimitiveTypeCode, string) GetPrimitiveType(PrimitiveTypeCode typeCode)\n\t\t\t{\n\t\t\t\treturn (typeCode, null);\n\t\t\t}\n\n\t\t\tpublic (PrimitiveTypeCode, string) GetSystemType()\n\t\t\t{\n\t\t\t\treturn (0, \"type\");\n\t\t\t}\n\n\t\t\tpublic (PrimitiveTypeCode, string) GetSZArrayType((PrimitiveTypeCode, string) elementType)\n\t\t\t{\n\t\t\t\treturn (elementType.Item1, (elementType.Item2 ?? PrimitiveTypeCodeToString(elementType.Item1)) + \"[]\");\n\t\t\t}\n\n\t\t\tpublic (PrimitiveTypeCode, string) GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)\n\t\t\t{\n\t\t\t\tstring fullTypeName = handle.GetFullTypeName(reader).FullName;\n\t\t\t\tif (handle.IsEnum(reader, out var typeCode))\n\t\t\t\t\treturn (typeCode, \"enum \" + fullTypeName);\n\t\t\t\treturn (0, fullTypeName);\n\t\t\t}\n\n\t\t\tpublic (PrimitiveTypeCode, string) GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)\n\t\t\t{\n\t\t\t\tstring fullTypeName = handle.GetFullTypeName(reader).FullName;\n\t\t\t\tvar containingModule = GetDeclaringModule(handle);\n\n\t\t\t\tstring assemblyQualifiedTypeName = containingModule != null\n\t\t\t\t\t? fullTypeName + \", \" + containingModule\n\t\t\t\t\t: fullTypeName;\n\n\t\t\t\tPrimitiveTypeCode typeCode = 0;\n\t\t\t\tvar (targetModule, resolvedType) = ResolveType(assemblyQualifiedTypeName, module);\n\t\t\t\tif (targetModule != null)\n\t\t\t\t{\n\t\t\t\t\tif (!resolvedType.IsEnum(targetModule.Metadata, out typeCode))\n\t\t\t\t\t{\n\t\t\t\t\t\ttypeCode = 0;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tassemblyQualifiedTypeName = \"enum \" + assemblyQualifiedTypeName;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn (typeCode, assemblyQualifiedTypeName);\n\n\t\t\t\tstring GetDeclaringModule(TypeReferenceHandle handle)\n\t\t\t\t{\n\t\t\t\t\tvar tr = reader.GetTypeReference(handle);\n\t\t\t\t\tswitch (tr.ResolutionScope.Kind)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase HandleKind.TypeReference:\n\t\t\t\t\t\t\treturn GetDeclaringModule((TypeReferenceHandle)tr.ResolutionScope);\n\t\t\t\t\t\tcase HandleKind.AssemblyReference:\n\t\t\t\t\t\t\tvar asmRef = reader.GetAssemblyReference((AssemblyReferenceHandle)tr.ResolutionScope);\n\t\t\t\t\t\t\treturn asmRef.TryGetFullAssemblyName(reader, out var assemblyName) ? assemblyName : null;\n\t\t\t\t\t\tcase HandleKind.ModuleReference:\n\t\t\t\t\t\t\tvar modRef = reader.GetModuleReference((ModuleReferenceHandle)tr.ResolutionScope);\n\t\t\t\t\t\t\treturn reader.GetString(modRef.Name);\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic (PrimitiveTypeCode, string) GetTypeFromSerializedName(string name)\n\t\t\t{\n\t\t\t\tif (resolver == null)\n\t\t\t\t\tthrow new EnumUnderlyingTypeResolveException();\n\t\t\t\tvar (containingModule, typeDefHandle) = ResolveType(name, module);\n\t\t\t\tif (typeDefHandle.IsNil)\n\t\t\t\t\tthrow new EnumUnderlyingTypeResolveException();\n\t\t\t\tif (typeDefHandle.IsEnum(containingModule.Metadata, out var typeCode))\n\t\t\t\t\treturn (typeCode, \"enum \" + name);\n\t\t\t\treturn (0, name);\n\t\t\t}\n\n\t\t\tpublic PrimitiveTypeCode GetUnderlyingEnumType((PrimitiveTypeCode, string) type)\n\t\t\t{\n\t\t\t\treturn type.Item1;\n\t\t\t}\n\n\t\t\tpublic bool IsSystemType((PrimitiveTypeCode, string) type)\n\t\t\t{\n\t\t\t\treturn \"type\" == type.Item2;\n\t\t\t}\n\n\t\t\t(MetadataFile, TypeDefinitionHandle) ResolveType(string typeName, MetadataFile module)\n\t\t\t{\n\t\t\t\tstring[] nameParts = typeName.Split(new[] { \", \" }, 2, StringSplitOptions.None);\n\t\t\t\tstring[] typeNameParts = nameParts[0].Split('.');\n\t\t\t\tMetadataFile containingModule = null;\n\t\t\t\tTypeDefinitionHandle typeDefHandle = default;\n\t\t\t\t// if we deal with an assembly-qualified name, resolve the assembly\n\t\t\t\tif (nameParts.Length == 2)\n\t\t\t\t\tcontainingModule = resolver.Resolve(AssemblyNameReference.Parse(nameParts[1]));\n\t\t\t\tif (containingModule != null)\n\t\t\t\t{\n\t\t\t\t\t// try to find the type in the assembly\n\t\t\t\t\ttypeDefHandle = FindType(containingModule, typeNameParts);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// just fully-qualified name, try current assembly\n\t\t\t\t\ttypeDefHandle = FindType(module, typeNameParts);\n\t\t\t\t\tcontainingModule = module;\n\t\t\t\t\tif (typeDefHandle.IsNil && TryResolveMscorlib(out var mscorlib))\n\t\t\t\t\t{\n\t\t\t\t\t\t// otherwise try mscorlib\n\t\t\t\t\t\ttypeDefHandle = FindType(mscorlib, typeNameParts);\n\t\t\t\t\t\tcontainingModule = mscorlib;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn (containingModule, typeDefHandle);\n\n\t\t\t\tTypeDefinitionHandle FindType(MetadataFile currentModule, string[] name)\n\t\t\t\t{\n\t\t\t\t\tvar metadata = currentModule.Metadata;\n\t\t\t\t\tvar currentNamespace = metadata.GetNamespaceDefinitionRoot();\n\t\t\t\t\tImmutableArray<TypeDefinitionHandle> typeDefinitions = default;\n\n\t\t\t\t\tfor (int i = 0; i < name.Length; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tstring identifier = name[i];\n\t\t\t\t\t\tif (!typeDefinitions.IsDefault)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\trestart:\n\t\t\t\t\t\t\tforeach (var type in typeDefinitions)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvar typeDef = metadata.GetTypeDefinition(type);\n\t\t\t\t\t\t\t\tvar currentTypeName = metadata.GetString(typeDef.Name);\n\t\t\t\t\t\t\t\tif (identifier == currentTypeName)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif (i + 1 == name.Length)\n\t\t\t\t\t\t\t\t\t\treturn type;\n\t\t\t\t\t\t\t\t\ttypeDefinitions = typeDef.GetNestedTypes();\n\t\t\t\t\t\t\t\t\tgoto restart;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar next = currentNamespace.NamespaceDefinitions.FirstOrDefault(ns => metadata.StringComparer.Equals(metadata.GetNamespaceDefinition(ns).Name, identifier));\n\t\t\t\t\t\t\tif (!next.IsNil)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcurrentNamespace = metadata.GetNamespaceDefinition(next);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttypeDefinitions = currentNamespace.TypeDefinitions;\n\t\t\t\t\t\t\t\ti--;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn default;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tMetadataFile mscorlib;\n\n\t\t\tbool TryResolveMscorlib(out MetadataFile mscorlib)\n\t\t\t{\n\t\t\t\tmscorlib = null;\n\t\t\t\tif (this.mscorlib != null)\n\t\t\t\t{\n\t\t\t\t\tmscorlib = this.mscorlib;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (resolver == null)\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tthis.mscorlib = mscorlib = resolver.Resolve(AssemblyNameReference.Parse(\"mscorlib\"));\n\t\t\t\treturn this.mscorlib != null;\n\t\t\t}\n\t\t}\n\n\t\tvoid TryDecodeSecurityDeclaration(TextOutputWithRollback output, BlobReader blob, MetadataFile module)\n\t\t{\n\t\t\toutput.WriteLine(\" = {\");\n\t\t\toutput.Indent();\n\n\t\t\tstring currentAssemblyName = null;\n\t\t\tstring currentFullAssemblyName = null;\n\t\t\tif (module.Metadata.IsAssembly)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tcurrentAssemblyName = module.Metadata.GetString(module.Metadata.GetAssemblyDefinition().Name);\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\tcurrentAssemblyName = \"<ERR: invalid assembly name>\";\n\t\t\t\t}\n\t\t\t\tif (!module.Metadata.TryGetFullAssemblyName(out currentFullAssemblyName))\n\t\t\t\t{\n\t\t\t\t\tcurrentFullAssemblyName = \"<ERR: invalid assembly name>\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tint count = blob.ReadCompressedInteger();\n\t\t\tfor (int i = 0; i < count; i++)\n\t\t\t{\n\t\t\t\tvar fullTypeName = blob.ReadSerializedString();\n\t\t\t\tstring[] nameParts = fullTypeName.Split(new[] { \", \" }, StringSplitOptions.None);\n\t\t\t\tif (nameParts.Length < 2 || nameParts[1] == currentAssemblyName)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\"class \");\n\t\t\t\t\toutput.Write(DisassemblerHelpers.Escape(fullTypeName));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\toutput.Write('[');\n\t\t\t\t\toutput.Write(nameParts[1]);\n\t\t\t\t\toutput.Write(']');\n\t\t\t\t\toutput.Write(nameParts[0]);\n\t\t\t\t}\n\t\t\t\toutput.Write(\" = {\");\n\t\t\t\tblob.ReadCompressedInteger(); // ?\n\t\t\t\t\t\t\t\t\t\t\t  // The specification seems to be incorrect here, so I'm using the logic from Cecil instead.\n\t\t\t\tint argCount = blob.ReadCompressedInteger();\n\n\t\t\t\tvar decoder = new CustomAttributeDecoder<(PrimitiveTypeCode Code, string Name)>(new SecurityDeclarationDecoder(output, AssemblyResolver, module), module.Metadata, provideBoxingTypeInfo: true);\n\t\t\t\tvar arguments = decoder.DecodeNamedArguments(ref blob, argCount);\n\n\t\t\t\tif (argCount > 0)\n\t\t\t\t{\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\toutput.Indent();\n\t\t\t\t}\n\n\t\t\t\tforeach (var argument in arguments)\n\t\t\t\t{\n\t\t\t\t\tswitch (argument.Kind)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase CustomAttributeNamedArgumentKind.Field:\n\t\t\t\t\t\t\toutput.Write(\"field \");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase CustomAttributeNamedArgumentKind.Property:\n\t\t\t\t\t\t\toutput.Write(\"property \");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\toutput.Write(argument.Type.Name ?? PrimitiveTypeCodeToString(argument.Type.Code));\n\t\t\t\t\toutput.Write(\" \" + DisassemblerHelpers.Escape(argument.Name) + \" = \");\n\n\t\t\t\t\tWriteValue(output, argument.Type, argument.Value);\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t}\n\n\t\t\t\tif (argCount > 0)\n\t\t\t\t{\n\t\t\t\t\toutput.Unindent();\n\t\t\t\t}\n\n\t\t\t\toutput.Write('}');\n\n\t\t\t\tif (i + 1 < count)\n\t\t\t\t\toutput.Write(',');\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\n\t\t\toutput.Unindent();\n\t\t\toutput.WriteLine(\"}\");\n\t\t}\n\n\t\tvoid WriteValue(ITextOutput output, (PrimitiveTypeCode Code, string Name) type, object value)\n\t\t{\n\t\t\tif (value is CustomAttributeTypedArgument<(PrimitiveTypeCode, string)> boxedValue)\n\t\t\t{\n\t\t\t\toutput.Write(\"object(\");\n\t\t\t\tWriteValue(output, boxedValue.Type, boxedValue.Value);\n\t\t\t\toutput.Write(\")\");\n\t\t\t}\n\t\t\telse if (value is ImmutableArray<CustomAttributeTypedArgument<(PrimitiveTypeCode, string)>> arrayValue)\n\t\t\t{\n\t\t\t\tstring elementType = type.Name != null && !type.Name.StartsWith(\"enum \", StringComparison.Ordinal)\n\t\t\t\t\t\t\t\t\t? type.Name.Remove(type.Name.Length - 2) : PrimitiveTypeCodeToString(type.Code);\n\n\t\t\t\toutput.Write(elementType);\n\t\t\t\toutput.Write(\"[\");\n\t\t\t\toutput.Write(arrayValue.Length.ToString());\n\t\t\t\toutput.Write(\"](\");\n\t\t\t\tbool first = true;\n\t\t\t\tforeach (var item in arrayValue)\n\t\t\t\t{\n\t\t\t\t\tif (!first)\n\t\t\t\t\t\toutput.Write(\" \");\n\t\t\t\t\tif (item.Value is CustomAttributeTypedArgument<(PrimitiveTypeCode, string)> boxedItem)\n\t\t\t\t\t{\n\t\t\t\t\t\tWriteValue(output, boxedItem.Type, boxedItem.Value);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tWriteSimpleValue(output, item.Value, elementType);\n\t\t\t\t\t}\n\t\t\t\t\tfirst = false;\n\t\t\t\t}\n\t\t\t\toutput.Write(\")\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tstring typeName = type.Name != null && !type.Name.StartsWith(\"enum \", StringComparison.Ordinal)\n\t\t\t\t\t? type.Name : PrimitiveTypeCodeToString(type.Code);\n\n\t\t\t\toutput.Write(typeName);\n\t\t\t\toutput.Write(\"(\");\n\t\t\t\tWriteSimpleValue(output, value, typeName);\n\t\t\t\toutput.Write(\")\");\n\t\t\t}\n\t\t}\n\n\t\tprivate static void WriteSimpleValue(ITextOutput output, object value, string typeName)\n\t\t{\n\t\t\tswitch (typeName)\n\t\t\t{\n\t\t\t\tcase \"string\":\n\t\t\t\t\toutput.Write(\"'\" + DisassemblerHelpers.EscapeString(value.ToString()).Replace(\"'\", \"\\\\'\") + \"'\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"type\":\n\t\t\t\t\tvar info = ((PrimitiveTypeCode Code, string Name))value;\n\t\t\t\t\tif (info.Name.StartsWith(\"enum \", StringComparison.Ordinal))\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(info.Name.Substring(5));\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(info.Name);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tDisassemblerHelpers.WriteOperand(output, value);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tstatic string PrimitiveTypeCodeToString(PrimitiveTypeCode typeCode)\n\t\t{\n\t\t\tswitch (typeCode)\n\t\t\t{\n\t\t\t\tcase PrimitiveTypeCode.Boolean:\n\t\t\t\t\treturn \"bool\";\n\t\t\t\tcase PrimitiveTypeCode.Byte:\n\t\t\t\t\treturn \"uint8\";\n\t\t\t\tcase PrimitiveTypeCode.SByte:\n\t\t\t\t\treturn \"int8\";\n\t\t\t\tcase PrimitiveTypeCode.Char:\n\t\t\t\t\treturn \"char\";\n\t\t\t\tcase PrimitiveTypeCode.Int16:\n\t\t\t\t\treturn \"int16\";\n\t\t\t\tcase PrimitiveTypeCode.UInt16:\n\t\t\t\t\treturn \"uint16\";\n\t\t\t\tcase PrimitiveTypeCode.Int32:\n\t\t\t\t\treturn \"int32\";\n\t\t\t\tcase PrimitiveTypeCode.UInt32:\n\t\t\t\t\treturn \"uint32\";\n\t\t\t\tcase PrimitiveTypeCode.Int64:\n\t\t\t\t\treturn \"int64\";\n\t\t\t\tcase PrimitiveTypeCode.UInt64:\n\t\t\t\t\treturn \"uint64\";\n\t\t\t\tcase PrimitiveTypeCode.Single:\n\t\t\t\t\treturn \"float32\";\n\t\t\t\tcase PrimitiveTypeCode.Double:\n\t\t\t\t\treturn \"float64\";\n\t\t\t\tcase PrimitiveTypeCode.String:\n\t\t\t\t\treturn \"string\";\n\t\t\t\tcase PrimitiveTypeCode.Object:\n\t\t\t\t\treturn \"object\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"unknown\";\n\t\t\t}\n\t\t}\n\n\t\t#endregion\n\n\t\t#region WriteMarshalInfo\n\t\tvoid WriteMarshalInfo(BlobReader marshalInfo)\n\t\t{\n\t\t\toutput.Write(\"marshal(\");\n\t\t\tWriteNativeType(ref marshalInfo);\n\t\t\toutput.Write(\") \");\n\t\t}\n\n\t\tvoid WriteNativeType(ref BlobReader blob)\n\t\t{\n\t\t\tbyte type;\n\t\t\tswitch (type = blob.ReadByte())\n\t\t\t{\n\t\t\t\tcase 0x66: // None\n\t\t\t\tcase 0x50: // Max\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x02: // NATIVE_TYPE_BOOLEAN \n\t\t\t\t\toutput.Write(\"bool\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x03: // NATIVE_TYPE_I1\n\t\t\t\t\toutput.Write(\"int8\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x04: // NATIVE_TYPE_U1\n\t\t\t\t\toutput.Write(\"unsigned int8\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x05: // NATIVE_TYPE_I2\n\t\t\t\t\toutput.Write(\"int16\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x06: // NATIVE_TYPE_U2\n\t\t\t\t\toutput.Write(\"unsigned int16\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x07: // NATIVE_TYPE_I4\n\t\t\t\t\toutput.Write(\"int32\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x08: // NATIVE_TYPE_U4\n\t\t\t\t\toutput.Write(\"unsigned int32\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x09: // NATIVE_TYPE_I8\n\t\t\t\t\toutput.Write(\"int64\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x0a: // NATIVE_TYPE_U8\n\t\t\t\t\toutput.Write(\"unsigned int64\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x0b: // NATIVE_TYPE_R4\n\t\t\t\t\toutput.Write(\"float32\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x0c: // NATIVE_TYPE_R8\n\t\t\t\t\toutput.Write(\"float64\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x14: // NATIVE_TYPE_LPSTR\n\t\t\t\t\toutput.Write(\"lpstr\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x1f: // NATIVE_TYPE_INT\n\t\t\t\t\toutput.Write(\"int\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x20: // NATIVE_TYPE_UINT\n\t\t\t\t\toutput.Write(\"unsigned int\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x26: // NATIVE_TYPE_FUNC\n\t\t\t\t\toutput.Write(\"Func\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x2a: // NATIVE_TYPE_ARRAY\n\t\t\t\t\tif (blob.RemainingBytes > 0)\n\t\t\t\t\t\tWriteNativeType(ref blob);\n\t\t\t\t\toutput.Write('[');\n\t\t\t\t\tint sizeParameterIndex = blob.TryReadCompressedInteger(out int value) ? value : -1;\n\t\t\t\t\tint size = blob.TryReadCompressedInteger(out value) ? value : -1;\n\t\t\t\t\tint sizeParameterMultiplier = blob.TryReadCompressedInteger(out value) ? value : -1;\n\t\t\t\t\tif (size >= 0)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(size.ToString());\n\t\t\t\t\t}\n\t\t\t\t\tif (sizeParameterIndex >= 0 && sizeParameterMultiplier != 0)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(\" + \");\n\t\t\t\t\t\toutput.Write(sizeParameterIndex.ToString());\n\t\t\t\t\t}\n\t\t\t\t\toutput.Write(']');\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x0f: // Currency\n\t\t\t\t\toutput.Write(\"currency\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x13: // BStr\n\t\t\t\t\toutput.Write(\"bstr\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x15: // LPWStr\n\t\t\t\t\toutput.Write(\"lpwstr\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x16: // LPTStr\n\t\t\t\t\toutput.Write(\"lptstr\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x17: // FixedSysString\n\t\t\t\t\toutput.Write(\"fixed sysstring[{0}]\", blob.ReadCompressedInteger());\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x19: // IUnknown\n\t\t\t\t\toutput.Write(\"iunknown\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x1a: // IDispatch\n\t\t\t\t\toutput.Write(\"idispatch\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x1b: // Struct\n\t\t\t\t\toutput.Write(\"struct\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x1c: // IntF\n\t\t\t\t\toutput.Write(\"interface\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x1d: // SafeArray\n\t\t\t\t\toutput.Write(\"safearray \");\n\t\t\t\t\tif (blob.RemainingBytes > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tbyte elementType = blob.ReadByte();\n\t\t\t\t\t\tswitch (elementType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase 0: // None\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 2: // I2\n\t\t\t\t\t\t\t\toutput.Write(\"int16\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 3: // I4\n\t\t\t\t\t\t\t\toutput.Write(\"int32\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 4: // R4\n\t\t\t\t\t\t\t\toutput.Write(\"float32\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 5: // R8\n\t\t\t\t\t\t\t\toutput.Write(\"float64\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 6: // Currency\n\t\t\t\t\t\t\t\toutput.Write(\"currency\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 7: // Date\n\t\t\t\t\t\t\t\toutput.Write(\"date\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 8: // BStr\n\t\t\t\t\t\t\t\toutput.Write(\"bstr\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 9: // Dispatch\n\t\t\t\t\t\t\t\toutput.Write(\"idispatch\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 10: // Error\n\t\t\t\t\t\t\t\toutput.Write(\"error\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 11: // Bool\n\t\t\t\t\t\t\t\toutput.Write(\"bool\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 12: // Variant\n\t\t\t\t\t\t\t\toutput.Write(\"variant\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 13: // Unknown\n\t\t\t\t\t\t\t\toutput.Write(\"iunknown\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 14: // Decimal\n\t\t\t\t\t\t\t\toutput.Write(\"decimal\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 16: // I1\n\t\t\t\t\t\t\t\toutput.Write(\"int8\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 17: // UI1\n\t\t\t\t\t\t\t\toutput.Write(\"unsigned int8\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 18: // UI2\n\t\t\t\t\t\t\t\toutput.Write(\"unsigned int16\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 19: // UI4\n\t\t\t\t\t\t\t\toutput.Write(\"unsigned int32\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 22: // Int\n\t\t\t\t\t\t\t\toutput.Write(\"int\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 23: // UInt\n\t\t\t\t\t\t\t\toutput.Write(\"unsigned int\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\toutput.Write(elementType.ToString());\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x1e: // FixedArray\n\t\t\t\t\toutput.Write(\"fixed array\");\n\t\t\t\t\toutput.Write(\"[{0}]\", blob.TryReadCompressedInteger(out value) ? value : 0);\n\t\t\t\t\tif (blob.RemainingBytes > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t\tWriteNativeType(ref blob);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x22: // ByValStr\n\t\t\t\t\toutput.Write(\"byvalstr\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x23: // ANSIBStr\n\t\t\t\t\toutput.Write(\"ansi bstr\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x24: // TBStr\n\t\t\t\t\toutput.Write(\"tbstr\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x25: // VariantBool\n\t\t\t\t\toutput.Write(\"variant bool\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x28: // ASAny\n\t\t\t\t\toutput.Write(\"as any\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x2b: // LPStruct\n\t\t\t\t\toutput.Write(\"lpstruct\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x2c: // CustomMarshaler\n\t\t\t\t\tstring guidValue = blob.ReadSerializedString();\n\t\t\t\t\tstring unmanagedType = blob.ReadSerializedString();\n\t\t\t\t\tstring managedType = blob.ReadSerializedString();\n\t\t\t\t\tstring cookie = blob.ReadSerializedString();\n\n\t\t\t\t\tvar guid = !string.IsNullOrEmpty(guidValue) ? new Guid(guidValue) : Guid.Empty;\n\n\t\t\t\t\toutput.Write(\"custom(\\\"{0}\\\", \\\"{1}\\\"\",\n\t\t\t\t\t\t\t\t DisassemblerHelpers.EscapeString(managedType),\n\t\t\t\t\t\t\t\t DisassemblerHelpers.EscapeString(cookie));\n\t\t\t\t\tif (guid != Guid.Empty || !string.IsNullOrEmpty(unmanagedType))\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(\", \\\"{0}\\\", \\\"{1}\\\"\", guid.ToString(), DisassemblerHelpers.EscapeString(unmanagedType));\n\t\t\t\t\t}\n\t\t\t\t\toutput.Write(')');\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x2d: // Error\n\t\t\t\t\toutput.Write(\"error\");\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\toutput.Write(type.ToString());\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tvoid WriteParameters(MetadataReader metadata, IEnumerable<ParameterHandle> parameters, MethodSignature<Action<ILNameSyntax>> signature)\n\t\t{\n\t\t\tint i = 0;\n\t\t\tint offset = signature.Header.IsInstance ? 1 : 0;\n\n\t\t\tforeach (var h in parameters)\n\t\t\t{\n\t\t\t\tvar p = metadata.GetParameter(h);\n\t\t\t\t// skip return type parameter handle\n\t\t\t\tif (p.SequenceNumber == 0)\n\t\t\t\t\tcontinue;\n\n\t\t\t\t// fill gaps in parameter list\n\t\t\t\twhile (i < p.SequenceNumber - 1)\n\t\t\t\t{\n\t\t\t\t\tif (i > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(',');\n\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t}\n\t\t\t\t\tsignature.ParameterTypes[i](ILNameSyntax.Signature);\n\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\toutput.WriteLocalReference(\"''\", \"param_\" + (i + offset), isDefinition: true);\n\t\t\t\t\ti++;\n\t\t\t\t}\n\n\t\t\t\t// separator\n\t\t\t\tif (i > 0)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(',');\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t}\n\n\t\t\t\t// print parameter\n\t\t\t\tif ((p.Attributes & ParameterAttributes.In) == ParameterAttributes.In)\n\t\t\t\t\toutput.Write(\"[in] \");\n\t\t\t\tif ((p.Attributes & ParameterAttributes.Out) == ParameterAttributes.Out)\n\t\t\t\t\toutput.Write(\"[out] \");\n\t\t\t\tif ((p.Attributes & ParameterAttributes.Optional) == ParameterAttributes.Optional)\n\t\t\t\t\toutput.Write(\"[opt] \");\n\t\t\t\tsignature.ParameterTypes[i](ILNameSyntax.Signature);\n\t\t\t\toutput.Write(' ');\n\t\t\t\tvar md = p.GetMarshallingDescriptor();\n\t\t\t\tif (!md.IsNil)\n\t\t\t\t{\n\t\t\t\t\tWriteMarshalInfo(metadata.GetBlobReader(md));\n\t\t\t\t}\n\t\t\t\toutput.WriteLocalReference(DisassemblerHelpers.Escape(metadata.GetString(p.Name)), \"param_\" + (i + offset), isDefinition: true);\n\t\t\t\ti++;\n\t\t\t}\n\n\t\t\t// add remaining parameter types as unnamed parameters\n\t\t\twhile (i < signature.RequiredParameterCount)\n\t\t\t{\n\t\t\t\tif (i > 0)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(',');\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t}\n\t\t\t\tsignature.ParameterTypes[i](ILNameSyntax.Signature);\n\t\t\t\toutput.Write(' ');\n\t\t\t\toutput.WriteLocalReference(\"''\", \"param_\" + (i + offset), isDefinition: true);\n\t\t\t\ti++;\n\t\t\t}\n\n\t\t\toutput.WriteLine();\n\t\t}\n\n\t\tvoid WriteGenericParametersAndAttributes(MetadataFile module, MetadataGenericContext context, GenericParameterHandle handle)\n\t\t{\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar p = metadata.GetGenericParameter(handle);\n\t\t\tif (p.GetCustomAttributes().Count > 0)\n\t\t\t{\n\t\t\t\toutput.Write(\".param type {0}\", metadata.GetString(p.Name));\n\t\t\t\toutput.WriteLine();\n\t\t\t\toutput.Indent();\n\t\t\t\tWriteAttributes(module, p.GetCustomAttributes());\n\t\t\t\toutput.Unindent();\n\t\t\t}\n\t\t\tforeach (var constraintHandle in p.GetConstraints())\n\t\t\t{\n\t\t\t\tvar constraint = metadata.GetGenericParameterConstraint(constraintHandle);\n\t\t\t\tif (constraint.GetCustomAttributes().Count > 0)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\".param constraint {0}, \", metadata.GetString(p.Name));\n\t\t\t\t\tconstraint.Type.WriteTo(module, output, context, ILNameSyntax.TypeName);\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\toutput.Indent();\n\t\t\t\t\tWriteAttributes(module, constraint.GetCustomAttributes());\n\t\t\t\t\toutput.Unindent();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid WriteParameterAttributes(MetadataFile module, ParameterHandle handle)\n\t\t{\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar p = metadata.GetParameter(handle);\n\t\t\tif (p.GetDefaultValue().IsNil && p.GetCustomAttributes().Count == 0)\n\t\t\t\treturn;\n\t\t\toutput.Write(\".param [{0}]\", p.SequenceNumber);\n\t\t\tif (!p.GetDefaultValue().IsNil)\n\t\t\t{\n\t\t\t\toutput.Write(\" = \");\n\t\t\t\tWriteConstant(metadata, metadata.GetConstant(p.GetDefaultValue()));\n\t\t\t}\n\t\t\toutput.WriteLine();\n\t\t\toutput.Indent();\n\t\t\tWriteAttributes(module, p.GetCustomAttributes());\n\t\t\toutput.Unindent();\n\t\t}\n\n\t\tvoid WriteConstant(MetadataReader metadata, Constant constant)\n\t\t{\n\t\t\tswitch (constant.TypeCode)\n\t\t\t{\n\t\t\t\tcase ConstantTypeCode.NullReference:\n\t\t\t\t\toutput.Write(\"nullref\");\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tvar blob = metadata.GetBlobReader(constant.Value);\n\t\t\t\t\tobject value;\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue = blob.ReadConstant(constant.TypeCode);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (ArgumentOutOfRangeException)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write($\"/* Constant with invalid typecode: {constant.TypeCode} */\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (value is string)\n\t\t\t\t\t{\n\t\t\t\t\t\tDisassemblerHelpers.WriteOperand(output, value);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tstring typeName = DisassemblerHelpers.PrimitiveTypeName(value.GetType().FullName);\n\t\t\t\t\t\toutput.Write(typeName);\n\t\t\t\t\t\toutput.Write('(');\n\t\t\t\t\t\tfloat? cf = value as float?;\n\t\t\t\t\t\tdouble? cd = value as double?;\n\t\t\t\t\t\tif (cf.HasValue && (float.IsNaN(cf.Value) || float.IsInfinity(cf.Value)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toutput.Write(\"0x{0:x8}\", BitConverter.ToInt32(BitConverter.GetBytes(cf.Value), 0));\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (cd.HasValue && (double.IsNaN(cd.Value) || double.IsInfinity(cd.Value)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toutput.Write(\"0x{0:x16}\", BitConverter.DoubleToInt64Bits(cd.Value));\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tDisassemblerHelpers.WriteOperand(output, value);\n\t\t\t\t\t\t}\n\t\t\t\t\t\toutput.Write(')');\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Disassemble Field\n\t\tinternal static readonly EnumNameCollection<FieldAttributes> fieldVisibility = new EnumNameCollection<FieldAttributes>() {\n\t\t\t{ FieldAttributes.Private, \"private\" },\n\t\t\t{ FieldAttributes.FamANDAssem, \"famandassem\" },\n\t\t\t{ FieldAttributes.Assembly, \"assembly\" },\n\t\t\t{ FieldAttributes.Family, \"family\" },\n\t\t\t{ FieldAttributes.FamORAssem, \"famorassem\" },\n\t\t\t{ FieldAttributes.Public, \"public\" },\n\t\t};\n\n\t\tinternal static readonly EnumNameCollection<FieldAttributes> fieldAttributes = new EnumNameCollection<FieldAttributes>() {\n\t\t\t{ FieldAttributes.Static, \"static\" },\n\t\t\t{ FieldAttributes.Literal, \"literal\" },\n\t\t\t{ FieldAttributes.InitOnly, \"initonly\" },\n\t\t\t{ FieldAttributes.SpecialName, \"specialname\" },\n\t\t\t{ FieldAttributes.RTSpecialName, \"rtspecialname\" },\n\t\t\t{ FieldAttributes.NotSerialized, \"notserialized\" },\n\t\t};\n\n\t\tpublic void DisassembleField(MetadataFile module, FieldDefinitionHandle handle)\n\t\t{\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar fieldDefinition = metadata.GetFieldDefinition(handle);\n\t\t\tchar sectionPrefix = DisassembleFieldHeaderInternal(module, handle, metadata, fieldDefinition);\n\t\t\toutput.WriteLine();\n\t\t\tvar attributes = fieldDefinition.GetCustomAttributes();\n\t\t\tif (attributes.Count > 0)\n\t\t\t{\n\t\t\t\toutput.MarkFoldStart();\n\t\t\t\tWriteAttributes(module, fieldDefinition.GetCustomAttributes());\n\t\t\t\toutput.MarkFoldEnd();\n\t\t\t}\n\t\t\tif (fieldDefinition.HasFlag(FieldAttributes.HasFieldRVA))\n\t\t\t{\n\t\t\t\t// Field data as specified in II.16.3.1 of ECMA-335 6th edition\n\t\t\t\tint rva = fieldDefinition.GetRelativeVirtualAddress();\n\t\t\t\tint sectionIndex = module.GetContainingSectionIndex(rva);\n\t\t\t\tif (sectionIndex < 0)\n\t\t\t\t{\n\t\t\t\t\toutput.WriteLine($\"// RVA {rva:X8} invalid (not in any section)\");\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tBlobReader initVal;\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tinitVal = fieldDefinition.GetInitialValue(module, null);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (BadImageFormatException ex)\n\t\t\t\t\t{\n\t\t\t\t\t\tinitVal = default;\n\t\t\t\t\t\toutput.WriteLine(\"// .data {2}_{0:X8} = {1}\", fieldDefinition.GetRelativeVirtualAddress(), ex.Message, sectionPrefix);\n\t\t\t\t\t}\n\t\t\t\t\tif (initVal.Length > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar sectionHeader = module.SectionHeaders[sectionIndex];\n\t\t\t\t\t\toutput.Write(\".data \");\n\t\t\t\t\t\tif (sectionHeader.Name == \".text\")\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toutput.Write(\"cil \");\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (sectionHeader.Name == \".tls\")\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toutput.Write(\"tls \");\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (sectionHeader.Name is not (null or \".data\"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toutput.Write($\"/* {sectionHeader.Name} */ \");\n\t\t\t\t\t\t}\n\t\t\t\t\t\toutput.Write($\"{sectionPrefix}_{rva:X8} = bytearray \");\n\t\t\t\t\t\tWriteBlob(initVal);\n\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic void DisassembleFieldHeader(MetadataFile module, FieldDefinitionHandle handle)\n\t\t{\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar fieldDefinition = metadata.GetFieldDefinition(handle);\n\t\t\tDisassembleFieldHeaderInternal(module, handle, metadata, fieldDefinition);\n\t\t}\n\n\t\tprivate char DisassembleFieldHeaderInternal(MetadataFile module, FieldDefinitionHandle handle, MetadataReader metadata, FieldDefinition fieldDefinition)\n\t\t{\n\t\t\toutput.WriteReference(module, handle, \".field\", isDefinition: true);\n\t\t\tWriteMetadataToken(output, module, handle, MetadataTokens.GetToken(handle),\n\t\t\t\tspaceAfter: true, spaceBefore: true, ShowMetadataTokens, ShowMetadataTokensInBase10);\n\t\t\tint offset = fieldDefinition.GetOffset();\n\t\t\tif (offset > -1)\n\t\t\t{\n\t\t\t\toutput.Write(\"[\" + offset + \"] \");\n\t\t\t}\n\t\t\tWriteEnum(fieldDefinition.Attributes & FieldAttributes.FieldAccessMask, fieldVisibility, output);\n\t\t\tconst FieldAttributes hasXAttributes = FieldAttributes.HasDefault | FieldAttributes.HasFieldMarshal | FieldAttributes.HasFieldRVA;\n\t\t\tWriteFlags(fieldDefinition.Attributes & ~(FieldAttributes.FieldAccessMask | hasXAttributes), fieldAttributes, output);\n\n\t\t\tvar signature = fieldDefinition.DecodeSignature(new DisassemblerSignatureTypeProvider(module, output), new MetadataGenericContext(fieldDefinition.GetDeclaringType(), module));\n\n\t\t\tvar marshallingDescriptor = fieldDefinition.GetMarshallingDescriptor();\n\t\t\tif (!marshallingDescriptor.IsNil)\n\t\t\t{\n\t\t\t\tWriteMarshalInfo(metadata.GetBlobReader(marshallingDescriptor));\n\t\t\t}\n\n\t\t\tsignature(ILNameSyntax.Signature);\n\t\t\toutput.Write(' ');\n\t\t\tvar fieldName = metadata.GetString(fieldDefinition.Name);\n\t\t\toutput.Write(DisassemblerHelpers.Escape(fieldName));\n\t\t\tchar sectionPrefix = 'D';\n\t\t\tif (fieldDefinition.HasFlag(FieldAttributes.HasFieldRVA))\n\t\t\t{\n\t\t\t\tint rva = fieldDefinition.GetRelativeVirtualAddress();\n\t\t\t\tsectionPrefix = GetRVASectionPrefix(module, rva);\n\t\t\t\toutput.Write(\" at {1}_{0:X8}\", rva, sectionPrefix);\n\t\t\t}\n\n\t\t\tvar defaultValue = fieldDefinition.GetDefaultValue();\n\t\t\tif (!defaultValue.IsNil)\n\t\t\t{\n\t\t\t\toutput.Write(\" = \");\n\t\t\t\tWriteConstant(metadata, metadata.GetConstant(defaultValue));\n\t\t\t}\n\n\t\t\treturn sectionPrefix;\n\t\t}\n\n\t\tchar GetRVASectionPrefix(MetadataFile module, int rva)\n\t\t{\n\t\t\tif (module is not PEFile peFile)\n\t\t\t\tthrow new NotSupportedException(\"Cannot get RVA section prefix from module\");\n\t\t\tint sectionIndex = peFile.Reader.PEHeaders.GetContainingSectionIndex(rva);\n\t\t\tif (sectionIndex < 0)\n\t\t\t\treturn 'D';\n\t\t\tvar sectionHeader = peFile.Reader.PEHeaders.SectionHeaders[sectionIndex];\n\t\t\tswitch (sectionHeader.Name)\n\t\t\t{\n\t\t\t\tcase \".tls\":\n\t\t\t\t\treturn 'T';\n\t\t\t\tcase \".text\":\n\t\t\t\t\treturn 'I';\n\t\t\t\tdefault:\n\t\t\t\t\treturn 'D';\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Disassemble Property\n\t\tinternal static readonly EnumNameCollection<PropertyAttributes> propertyAttributes = new EnumNameCollection<PropertyAttributes>() {\n\t\t\t{ PropertyAttributes.SpecialName, \"specialname\" },\n\t\t\t{ PropertyAttributes.RTSpecialName, \"rtspecialname\" },\n\t\t\t{ PropertyAttributes.HasDefault, \"hasdefault\" },\n\t\t};\n\n\t\tpublic void DisassembleProperty(MetadataFile module, PropertyDefinitionHandle property)\n\t\t{\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar propertyDefinition = metadata.GetPropertyDefinition(property);\n\t\t\tPropertyAccessors accessors = DisassemblePropertyHeaderInternal(module, property, metadata, propertyDefinition);\n\n\t\t\tOpenBlock(false);\n\t\t\tWriteAttributes(module, propertyDefinition.GetCustomAttributes());\n\t\t\tWriteNestedMethod(\".get\", module, accessors.Getter);\n\t\t\tWriteNestedMethod(\".set\", module, accessors.Setter);\n\t\t\tforeach (var method in accessors.Others)\n\t\t\t{\n\t\t\t\tWriteNestedMethod(\".other\", module, method);\n\t\t\t}\n\t\t\tCloseBlock();\n\t\t}\n\n\t\tpublic void DisassemblePropertyHeader(MetadataFile module, PropertyDefinitionHandle property)\n\t\t{\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar propertyDefinition = metadata.GetPropertyDefinition(property);\n\t\t\tDisassemblePropertyHeaderInternal(module, property, metadata, propertyDefinition);\n\t\t}\n\n\t\tprivate PropertyAccessors DisassemblePropertyHeaderInternal(MetadataFile module, PropertyDefinitionHandle handle, MetadataReader metadata, PropertyDefinition propertyDefinition)\n\t\t{\n\t\t\toutput.WriteReference(module, handle, \".property\", isDefinition: true);\n\t\t\tWriteMetadataToken(output, module, handle, MetadataTokens.GetToken(handle),\n\t\t\t\tspaceAfter: true, spaceBefore: true, ShowMetadataTokens, ShowMetadataTokensInBase10);\n\t\t\tWriteFlags(propertyDefinition.Attributes, propertyAttributes, output);\n\t\t\tvar accessors = propertyDefinition.GetAccessors();\n\t\t\tvar declaringType = metadata.GetMethodDefinition(accessors.GetAny()).GetDeclaringType();\n\t\t\tvar signature = propertyDefinition.DecodeSignature(new DisassemblerSignatureTypeProvider(module, output), new MetadataGenericContext(declaringType, module));\n\n\t\t\tif (signature.Header.IsInstance)\n\t\t\t\toutput.Write(\"instance \");\n\t\t\tsignature.ReturnType(ILNameSyntax.Signature);\n\t\t\toutput.Write(' ');\n\t\t\toutput.Write(DisassemblerHelpers.Escape(metadata.GetString(propertyDefinition.Name)));\n\n\t\t\toutput.Write('(');\n\t\t\tif (signature.ParameterTypes.Length > 0)\n\t\t\t{\n\t\t\t\tvar parameters = metadata.GetMethodDefinition(accessors.GetAny()).GetParameters();\n\t\t\t\tint parametersCount = accessors.Getter.IsNil ? parameters.Count - 1 : parameters.Count;\n\n\t\t\t\toutput.WriteLine();\n\t\t\t\toutput.Indent();\n\t\t\t\tWriteParameters(metadata, parameters.Take(parametersCount), signature);\n\t\t\t\toutput.Unindent();\n\t\t\t}\n\t\t\toutput.Write(')');\n\t\t\treturn accessors;\n\t\t}\n\n\t\tvoid WriteNestedMethod(string keyword, MetadataFile module, MethodDefinitionHandle method)\n\t\t{\n\t\t\tif (method.IsNil)\n\t\t\t\treturn;\n\n\t\t\toutput.Write(keyword);\n\t\t\toutput.Write(' ');\n\t\t\t((EntityHandle)method).WriteTo(module, output, default);\n\t\t\toutput.WriteLine();\n\t\t}\n\t\t#endregion\n\n\t\t#region Disassemble Event\n\t\tinternal static readonly EnumNameCollection<EventAttributes> eventAttributes = new EnumNameCollection<EventAttributes>() {\n\t\t\t{ EventAttributes.SpecialName, \"specialname\" },\n\t\t\t{ EventAttributes.RTSpecialName, \"rtspecialname\" },\n\t\t};\n\n\t\tpublic void DisassembleEvent(MetadataFile module, EventDefinitionHandle handle)\n\t\t{\n\t\t\tvar eventDefinition = module.Metadata.GetEventDefinition(handle);\n\t\t\tvar accessors = eventDefinition.GetAccessors();\n\t\t\tDisassembleEventHeaderInternal(module, handle, eventDefinition, accessors);\n\t\t\tOpenBlock(false);\n\t\t\tWriteAttributes(module, eventDefinition.GetCustomAttributes());\n\t\t\tWriteNestedMethod(\".addon\", module, accessors.Adder);\n\t\t\tWriteNestedMethod(\".removeon\", module, accessors.Remover);\n\t\t\tWriteNestedMethod(\".fire\", module, accessors.Raiser);\n\t\t\tforeach (var method in accessors.Others)\n\t\t\t{\n\t\t\t\tWriteNestedMethod(\".other\", module, method);\n\t\t\t}\n\t\t\tCloseBlock();\n\t\t}\n\n\t\tpublic void DisassembleEventHeader(MetadataFile module, EventDefinitionHandle handle)\n\t\t{\n\t\t\tvar eventDefinition = module.Metadata.GetEventDefinition(handle);\n\t\t\tvar accessors = eventDefinition.GetAccessors();\n\t\t\tDisassembleEventHeaderInternal(module, handle, eventDefinition, accessors);\n\t\t}\n\n\t\tprivate void DisassembleEventHeaderInternal(MetadataFile module, EventDefinitionHandle handle, EventDefinition eventDefinition, EventAccessors accessors)\n\t\t{\n\t\t\tTypeDefinitionHandle declaringType;\n\t\t\tif (!accessors.Adder.IsNil)\n\t\t\t{\n\t\t\t\tdeclaringType = module.Metadata.GetMethodDefinition(accessors.Adder).GetDeclaringType();\n\t\t\t}\n\t\t\telse if (!accessors.Remover.IsNil)\n\t\t\t{\n\t\t\t\tdeclaringType = module.Metadata.GetMethodDefinition(accessors.Remover).GetDeclaringType();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tdeclaringType = module.Metadata.GetMethodDefinition(accessors.Raiser).GetDeclaringType();\n\t\t\t}\n\t\t\toutput.WriteReference(module, handle, \".event\", isDefinition: true);\n\t\t\tWriteMetadataToken(output, module, handle, MetadataTokens.GetToken(handle),\n\t\t\t\tspaceAfter: true, spaceBefore: true, ShowMetadataTokens, ShowMetadataTokensInBase10);\n\t\t\tWriteFlags(eventDefinition.Attributes, eventAttributes, output);\n\t\t\tvar provider = new DisassemblerSignatureTypeProvider(module, output);\n\t\t\tAction<ILNameSyntax> signature;\n\t\t\tswitch (eventDefinition.Type.Kind)\n\t\t\t{\n\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\t\tsignature = provider.GetTypeFromDefinition(module.Metadata, (TypeDefinitionHandle)eventDefinition.Type, 0);\n\t\t\t\t\tbreak;\n\t\t\t\tcase HandleKind.TypeReference:\n\t\t\t\t\tsignature = provider.GetTypeFromReference(module.Metadata, (TypeReferenceHandle)eventDefinition.Type, 0);\n\t\t\t\t\tbreak;\n\t\t\t\tcase HandleKind.TypeSpecification:\n\t\t\t\t\tsignature = provider.GetTypeFromSpecification(module.Metadata, new MetadataGenericContext(declaringType, module),\n\t\t\t\t\t\t(TypeSpecificationHandle)eventDefinition.Type, 0);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new BadImageFormatException(\"Expected a TypeDef, TypeRef or TypeSpec handle!\");\n\t\t\t}\n\t\t\tsignature(ILNameSyntax.TypeName);\n\t\t\toutput.Write(' ');\n\t\t\toutput.Write(DisassemblerHelpers.Escape(module.Metadata.GetString(eventDefinition.Name)));\n\t\t}\n\t\t#endregion\n\n\t\t#region Disassemble Type\n\t\tinternal static readonly EnumNameCollection<TypeAttributes> typeVisibility = new EnumNameCollection<TypeAttributes>() {\n\t\t\t{ TypeAttributes.Public, \"public\" },\n\t\t\t{ TypeAttributes.NotPublic, \"private\" },\n\t\t\t{ TypeAttributes.NestedPublic, \"nested public\" },\n\t\t\t{ TypeAttributes.NestedPrivate, \"nested private\" },\n\t\t\t{ TypeAttributes.NestedAssembly, \"nested assembly\" },\n\t\t\t{ TypeAttributes.NestedFamily, \"nested family\" },\n\t\t\t{ TypeAttributes.NestedFamANDAssem, \"nested famandassem\" },\n\t\t\t{ TypeAttributes.NestedFamORAssem, \"nested famorassem\" },\n\t\t};\n\n\t\tEnumNameCollection<TypeAttributes> typeLayout = new EnumNameCollection<TypeAttributes>() {\n\t\t\t{ TypeAttributes.AutoLayout, \"auto\" },\n\t\t\t{ TypeAttributes.SequentialLayout, \"sequential\" },\n\t\t\t{ TypeAttributes.ExplicitLayout, \"explicit\" },\n\t\t};\n\n\t\tEnumNameCollection<TypeAttributes> typeStringFormat = new EnumNameCollection<TypeAttributes>() {\n\t\t\t{ TypeAttributes.AutoClass, \"auto\" },\n\t\t\t{ TypeAttributes.AnsiClass, \"ansi\" },\n\t\t\t{ TypeAttributes.UnicodeClass, \"unicode\" },\n\t\t};\n\n\t\tinternal static readonly EnumNameCollection<TypeAttributes> typeAttributes = new EnumNameCollection<TypeAttributes>() {\n\t\t\t{ TypeAttributes.Abstract, \"abstract\" },\n\t\t\t{ TypeAttributes.Sealed, \"sealed\" },\n\t\t\t{ TypeAttributes.SpecialName, \"specialname\" },\n\t\t\t{ TypeAttributes.Import, \"import\" },\n\t\t\t{ TypeAttributes.Serializable, \"serializable\" },\n\t\t\t{ TypeAttributes.WindowsRuntime, \"windowsruntime\" },\n\t\t\t{ TypeAttributes.BeforeFieldInit, \"beforefieldinit\" },\n\t\t\t{ TypeAttributes.HasSecurity, null },\n\t\t};\n\n\t\tpublic void DisassembleType(MetadataFile module, TypeDefinitionHandle type)\n\t\t{\n\t\t\tvar typeDefinition = module.Metadata.GetTypeDefinition(type);\n\t\t\tMetadataGenericContext genericContext = new MetadataGenericContext(type, module);\n\n\t\t\tDisassembleTypeHeaderInternal(module, type, typeDefinition, genericContext);\n\n\t\t\tvar interfaces = Process(module, typeDefinition.GetInterfaceImplementations());\n\t\t\tif (interfaces.Count > 0)\n\t\t\t{\n\t\t\t\toutput.Indent();\n\t\t\t\tbool first = true;\n\t\t\t\tforeach (var i in interfaces)\n\t\t\t\t{\n\t\t\t\t\tif (!first)\n\t\t\t\t\t\toutput.WriteLine(\",\");\n\t\t\t\t\tif (first)\n\t\t\t\t\t\toutput.Write(\"implements \");\n\t\t\t\t\telse\n\t\t\t\t\t\toutput.Write(\"           \");\n\t\t\t\t\tfirst = false;\n\t\t\t\t\tvar iface = module.Metadata.GetInterfaceImplementation(i);\n\t\t\t\t\tiface.Interface.WriteTo(module, output, genericContext, ILNameSyntax.TypeName);\n\t\t\t\t}\n\t\t\t\toutput.WriteLine();\n\t\t\t\toutput.Unindent();\n\t\t\t}\n\n\t\t\toutput.WriteLine(\"{\");\n\t\t\toutput.Indent();\n\t\t\tbool oldIsInType = isInType;\n\t\t\tisInType = true;\n\t\t\tWriteAttributes(module, typeDefinition.GetCustomAttributes());\n\t\t\tWriteSecurityDeclarations(module, typeDefinition.GetDeclarativeSecurityAttributes());\n\t\t\tforeach (var tp in typeDefinition.GetGenericParameters())\n\t\t\t{\n\t\t\t\tWriteGenericParametersAndAttributes(module, genericContext, tp);\n\t\t\t}\n\t\t\tvar layout = typeDefinition.GetLayout();\n\t\t\tif (!layout.IsDefault)\n\t\t\t{\n\t\t\t\toutput.WriteLine(\".pack {0}\", layout.PackingSize);\n\t\t\t\toutput.WriteLine(\".size {0}\", layout.Size);\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t\tforeach (var ifaceHandle in interfaces)\n\t\t\t{\n\t\t\t\tvar iface = module.Metadata.GetInterfaceImplementation(ifaceHandle);\n\t\t\t\tvar customAttributes = iface.GetCustomAttributes();\n\t\t\t\tif (customAttributes.Count != 0)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\".interfaceimpl type \");\n\t\t\t\t\tiface.Interface.WriteTo(module, output, genericContext, ILNameSyntax.TypeName);\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\toutput.Indent();\n\t\t\t\t\tWriteAttributes(module, customAttributes);\n\t\t\t\t\toutput.Unindent();\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar nestedTypes = Process(module, typeDefinition.GetNestedTypes());\n\t\t\tif (nestedTypes.Any())\n\t\t\t{\n\t\t\t\toutput.WriteLine(\"// Nested Types\");\n\t\t\t\tforeach (var nestedType in nestedTypes)\n\t\t\t\t{\n\t\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tDisassembleType(module, nestedType);\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t}\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t\tvar fields = Process(module, typeDefinition.GetFields());\n\t\t\tif (fields.Any())\n\t\t\t{\n\t\t\t\toutput.WriteLine(\"// Fields\");\n\t\t\t\tforeach (var field in fields)\n\t\t\t\t{\n\t\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tDisassembleField(module, field);\n\t\t\t\t}\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t\tvar methods = Process(module, typeDefinition.GetMethods());\n\t\t\tif (methods.Any())\n\t\t\t{\n\t\t\t\toutput.WriteLine(\"// Methods\");\n\t\t\t\tforeach (var m in methods)\n\t\t\t\t{\n\t\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tDisassembleMethod(module, m);\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar events = Process(module, typeDefinition.GetEvents());\n\t\t\tif (events.Any())\n\t\t\t{\n\t\t\t\toutput.WriteLine(\"// Events\");\n\t\t\t\tforeach (var ev in events)\n\t\t\t\t{\n\t\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tDisassembleEvent(module, ev);\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t}\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t\tvar properties = Process(module, typeDefinition.GetProperties());\n\t\t\tif (properties.Any())\n\t\t\t{\n\t\t\t\toutput.WriteLine(\"// Properties\");\n\t\t\t\tforeach (var prop in properties)\n\t\t\t\t{\n\t\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tDisassembleProperty(module, prop);\n\t\t\t\t}\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t\tCloseBlock(\"end of class \" + (!typeDefinition.GetDeclaringType().IsNil ? module.Metadata.GetString(typeDefinition.Name) : typeDefinition.GetFullTypeName(module.Metadata).ToString()));\n\t\t\tisInType = oldIsInType;\n\t\t}\n\n\t\tpublic void DisassembleTypeHeader(MetadataFile module, TypeDefinitionHandle type)\n\t\t{\n\t\t\tvar typeDefinition = module.Metadata.GetTypeDefinition(type);\n\t\t\tMetadataGenericContext genericContext = new MetadataGenericContext(type, module);\n\t\t\tDisassembleTypeHeaderInternal(module, type, typeDefinition, genericContext);\n\t\t}\n\n\t\tprivate void DisassembleTypeHeaderInternal(MetadataFile module, TypeDefinitionHandle handle, TypeDefinition typeDefinition, MetadataGenericContext genericContext)\n\t\t{\n\t\t\toutput.WriteReference(module, handle, \".class\", isDefinition: true);\n\t\t\tWriteMetadataToken(output, module, handle, MetadataTokens.GetToken(handle),\n\t\t\t\tspaceAfter: true, spaceBefore: true, ShowMetadataTokens, ShowMetadataTokensInBase10);\n\t\t\tif ((typeDefinition.Attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface)\n\t\t\t\toutput.Write(\"interface \");\n\t\t\tWriteEnum(typeDefinition.Attributes & TypeAttributes.VisibilityMask, typeVisibility, output);\n\t\t\tWriteEnum(typeDefinition.Attributes & TypeAttributes.LayoutMask, typeLayout, output);\n\t\t\tWriteEnum(typeDefinition.Attributes & TypeAttributes.StringFormatMask, typeStringFormat, output);\n\t\t\tconst TypeAttributes masks = TypeAttributes.ClassSemanticsMask | TypeAttributes.VisibilityMask | TypeAttributes.LayoutMask | TypeAttributes.StringFormatMask;\n\t\t\tWriteFlags(typeDefinition.Attributes & ~masks, typeAttributes, output);\n\n\t\t\toutput.Write(typeDefinition.GetDeclaringType().IsNil ? typeDefinition.GetFullTypeName(module.Metadata).ToILNameString() : DisassemblerHelpers.Escape(module.Metadata.GetString(typeDefinition.Name)));\n\t\t\tWriteTypeParameters(output, module, genericContext, typeDefinition.GetGenericParameters());\n\t\t\toutput.MarkFoldStart(defaultCollapsed: !ExpandMemberDefinitions && isInType, isDefinition: isInType);\n\t\t\toutput.WriteLine();\n\n\t\t\tEntityHandle baseType = typeDefinition.GetBaseTypeOrNil();\n\t\t\tif (!baseType.IsNil)\n\t\t\t{\n\t\t\t\toutput.Indent();\n\t\t\t\toutput.Write(\"extends \");\n\t\t\t\tbaseType.WriteTo(module, output, genericContext, ILNameSyntax.TypeName);\n\t\t\t\toutput.WriteLine();\n\t\t\t\toutput.Unindent();\n\t\t\t}\n\t\t}\n\n\t\tvoid WriteTypeParameters(ITextOutput output, MetadataFile module, MetadataGenericContext context, GenericParameterHandleCollection p)\n\t\t{\n\t\t\tif (p.Count > 0)\n\t\t\t{\n\t\t\t\toutput.Write('<');\n\t\t\t\tvar metadata = module.Metadata;\n\t\t\t\tfor (int i = 0; i < p.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\toutput.Write(\", \");\n\t\t\t\t\tvar gp = metadata.GetGenericParameter(p[i]);\n\t\t\t\t\tif ((gp.Attributes & GenericParameterAttributes.ReferenceTypeConstraint) == GenericParameterAttributes.ReferenceTypeConstraint)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(\"class \");\n\t\t\t\t\t}\n\t\t\t\t\telse if ((gp.Attributes & GenericParameterAttributes.NotNullableValueTypeConstraint) == GenericParameterAttributes.NotNullableValueTypeConstraint)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(\"valuetype \");\n\t\t\t\t\t}\n\t\t\t\t\tif ((gp.Attributes & SRMExtensions.AllowByRefLike) == SRMExtensions.AllowByRefLike)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(\"byreflike \");\n\t\t\t\t\t}\n\t\t\t\t\tif ((gp.Attributes & GenericParameterAttributes.DefaultConstructorConstraint) == GenericParameterAttributes.DefaultConstructorConstraint)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(\".ctor \");\n\t\t\t\t\t}\n\t\t\t\t\tvar constraints = gp.GetConstraints();\n\t\t\t\t\tif (constraints.Count > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write('(');\n\t\t\t\t\t\tfor (int j = 0; j < constraints.Count; j++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (j > 0)\n\t\t\t\t\t\t\t\toutput.Write(\", \");\n\t\t\t\t\t\t\tvar constraint = metadata.GetGenericParameterConstraint(constraints[j]);\n\t\t\t\t\t\t\tconstraint.Type.WriteTo(module, output, context, ILNameSyntax.TypeName);\n\t\t\t\t\t\t}\n\t\t\t\t\t\toutput.Write(\") \");\n\t\t\t\t\t}\n\t\t\t\t\tif ((gp.Attributes & GenericParameterAttributes.Contravariant) == GenericParameterAttributes.Contravariant)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write('-');\n\t\t\t\t\t}\n\t\t\t\t\telse if ((gp.Attributes & GenericParameterAttributes.Covariant) == GenericParameterAttributes.Covariant)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write('+');\n\t\t\t\t\t}\n\t\t\t\t\toutput.Write(DisassemblerHelpers.Escape(metadata.GetString(gp.Name)));\n\t\t\t\t}\n\t\t\t\toutput.Write('>');\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Processing\n\n\t\tprivate IReadOnlyCollection<InterfaceImplementationHandle> Process(MetadataFile module, IReadOnlyCollection<InterfaceImplementationHandle> items)\n\t\t{\n\t\t\treturn EntityProcessor?.Process(module, items) ?? items;\n\t\t}\n\n\t\tprivate IReadOnlyCollection<TypeDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<TypeDefinitionHandle> items)\n\t\t{\n\t\t\treturn EntityProcessor?.Process(module, items) ?? items;\n\t\t}\n\n\t\tprivate IReadOnlyCollection<MethodDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<MethodDefinitionHandle> items)\n\t\t{\n\t\t\treturn EntityProcessor?.Process(module, items) ?? items;\n\t\t}\n\n\t\tprivate IReadOnlyCollection<PropertyDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<PropertyDefinitionHandle> items)\n\t\t{\n\t\t\treturn EntityProcessor?.Process(module, items) ?? items;\n\t\t}\n\n\t\tprivate IReadOnlyCollection<EventDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<EventDefinitionHandle> items)\n\t\t{\n\t\t\treturn EntityProcessor?.Process(module, items) ?? items;\n\t\t}\n\n\t\tprivate IReadOnlyCollection<FieldDefinitionHandle> Process(MetadataFile module, IReadOnlyCollection<FieldDefinitionHandle> items)\n\t\t{\n\t\t\treturn EntityProcessor?.Process(module, items) ?? items;\n\t\t}\n\n\t\tprivate IReadOnlyCollection<CustomAttributeHandle> Process(MetadataFile module, IReadOnlyCollection<CustomAttributeHandle> items)\n\t\t{\n\t\t\treturn EntityProcessor?.Process(module, items) ?? items;\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Helper methods\n\n\t\tvoid WriteAttributes(MetadataFile module, CustomAttributeHandleCollection attributes)\n\t\t{\n\t\t\tvar metadata = module.Metadata;\n\t\t\tforeach (CustomAttributeHandle a in Process(module, attributes))\n\t\t\t{\n\t\t\t\toutput.Write(\".custom \");\n\t\t\t\tWriteMetadataToken(output, module, a, MetadataTokens.GetToken(a),\n\t\t\t\t\tspaceAfter: true, spaceBefore: false, ShowMetadataTokens, ShowMetadataTokensInBase10);\n\t\t\t\tvar attr = metadata.GetCustomAttribute(a);\n\t\t\t\tattr.Constructor.WriteTo(module, output, default);\n\t\t\t\tif (!attr.Value.IsNil)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\" = \");\n\t\t\t\t\tif (DecodeCustomAttributeBlobs)\n\t\t\t\t\t\tWriteDecodedCustomAttributeBlob(attr, module);\n\t\t\t\t\telse\n\t\t\t\t\t\tWriteBlob(attr.Value, metadata);\n\t\t\t\t}\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t}\n\n\t\tvoid WriteDecodedCustomAttributeBlob(CustomAttribute attr, MetadataFile module)\n\t\t{\n\t\t\tCustomAttributeValue<(PrimitiveTypeCode Code, string Name)> value;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar provider = new SecurityDeclarationDecoder(output, AssemblyResolver, module);\n\t\t\t\tvalue = attr.DecodeValue(provider);\n\t\t\t}\n\t\t\tcatch (BadImageFormatException)\n\t\t\t{\n\t\t\t\toutput.Write(\"/* Could not decode attribute value */ \");\n\t\t\t\tWriteBlob(attr.Value, module.Metadata);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\toutput.Write(\"{\");\n\t\t\toutput.Indent();\n\n\t\t\tforeach (var arg in value.FixedArguments)\n\t\t\t{\n\t\t\t\toutput.WriteLine();\n\t\t\t\tWriteValue(output, arg.Type, arg.Value);\n\t\t\t}\n\n\t\t\tforeach (var arg in value.NamedArguments)\n\t\t\t{\n\t\t\t\toutput.WriteLine();\n\t\t\t\tswitch (arg.Kind)\n\t\t\t\t{\n\t\t\t\t\tcase CustomAttributeNamedArgumentKind.Field:\n\t\t\t\t\t\toutput.Write(\"field \");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase CustomAttributeNamedArgumentKind.Property:\n\t\t\t\t\t\toutput.Write(\"property \");\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\toutput.Write(arg.Type.Name ?? PrimitiveTypeCodeToString(arg.Type.Code));\n\t\t\t\toutput.Write(\" \" + DisassemblerHelpers.Escape(arg.Name) + \" = \");\n\t\t\t\tWriteValue(output, arg.Type, arg.Value);\n\t\t\t}\n\n\t\t\toutput.WriteLine();\n\t\t\toutput.Unindent();\n\t\t\toutput.Write(\"}\");\n\t\t}\n\n\t\tvoid WriteBlob(BlobHandle blob, MetadataReader metadata)\n\t\t{\n\t\t\tvar reader = metadata.GetBlobReader(blob);\n\t\t\tWriteBlob(reader);\n\t\t}\n\n\t\tvoid WriteBlob(BlobReader reader)\n\t\t{\n\t\t\toutput.Write(\"(\");\n\t\t\tif (reader.Length > 0)\n\t\t\t{\n\t\t\t\toutput.Indent();\n\n\t\t\t\tfor (int i = 0; i < reader.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tif (i % 16 == 0 && i < reader.Length - 1)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t}\n\t\t\t\t\toutput.Write(reader.ReadByte().ToString(\"x2\"));\n\t\t\t\t}\n\n\t\t\t\toutput.WriteLine();\n\t\t\t\toutput.Unindent();\n\t\t\t}\n\t\t\toutput.Write(\")\");\n\t\t}\n\n\t\tvoid OpenBlock(bool defaultCollapsed)\n\t\t{\n\t\t\toutput.MarkFoldStart(defaultCollapsed: !ExpandMemberDefinitions && defaultCollapsed, isDefinition: true);\n\t\t\toutput.WriteLine();\n\t\t\toutput.WriteLine(\"{\");\n\t\t\toutput.Indent();\n\t\t}\n\n\t\tvoid CloseBlock(string comment = null)\n\t\t{\n\t\t\toutput.Unindent();\n\t\t\toutput.Write(\"}\");\n\t\t\tif (comment != null)\n\t\t\t\toutput.Write(\" // \" + comment);\n\t\t\toutput.MarkFoldEnd();\n\t\t\toutput.WriteLine();\n\t\t}\n\n\t\tinternal static void WriteFlags<T>(T flags, EnumNameCollection<T> flagNames, ITextOutput output) where T : struct\n\t\t{\n\t\t\tlong val = Convert.ToInt64(flags);\n\t\t\tlong tested = 0;\n\t\t\tforeach (var pair in flagNames)\n\t\t\t{\n\t\t\t\ttested |= pair.Key;\n\t\t\t\tif ((val & pair.Key) != 0 && pair.Value != null)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(pair.Value);\n\t\t\t\t\toutput.Write(' ');\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ((val & ~tested) != 0)\n\t\t\t\toutput.Write(\"flags({0:x4}) \", val & ~tested);\n\t\t}\n\n\t\tinternal static void WriteEnum<T>(T enumValue, EnumNameCollection<T> enumNames, ITextOutput output) where T : struct\n\t\t{\n\t\t\tlong val = Convert.ToInt64(enumValue);\n\t\t\tforeach (var pair in enumNames)\n\t\t\t{\n\t\t\t\tif (pair.Key == val)\n\t\t\t\t{\n\t\t\t\t\tif (pair.Value != null)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(pair.Value);\n\t\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (val != 0)\n\t\t\t{\n\t\t\t\toutput.Write(\"flags({0:x4}) \", val);\n\t\t\t}\n\n\t\t}\n\n\t\tinternal struct EnumNameCollection<T> : IEnumerable<KeyValuePair<long, string>> where T : struct\n\t\t{\n\t\t\tList<KeyValuePair<long, string>> names = new List<KeyValuePair<long, string>>();\n\n\t\t\tpublic EnumNameCollection()\n\t\t\t{\n\t\t\t}\n\n\t\t\tpublic void Add(T flag, string name)\n\t\t\t{\n\t\t\t\tthis.names.Add(new KeyValuePair<long, string>(Convert.ToInt64(flag), name));\n\t\t\t}\n\n\t\t\tpublic IEnumerator<KeyValuePair<long, string>> GetEnumerator()\n\t\t\t{\n\t\t\t\treturn names.GetEnumerator();\n\t\t\t}\n\n\t\t\tSystem.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\n\t\t\t{\n\t\t\t\treturn names.GetEnumerator();\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic void DisassembleNamespace(string nameSpace, MetadataFile module, IEnumerable<TypeDefinitionHandle> types)\n\t\t{\n\t\t\tif (!string.IsNullOrEmpty(nameSpace))\n\t\t\t{\n\t\t\t\toutput.Write(\".namespace \" + DisassemblerHelpers.Escape(nameSpace));\n\t\t\t\tOpenBlock(false);\n\t\t\t}\n\t\t\tbool oldIsInType = isInType;\n\t\t\tisInType = true;\n\t\t\tforeach (var td in types)\n\t\t\t{\n\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tDisassembleType(module, td);\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t\tif (!string.IsNullOrEmpty(nameSpace))\n\t\t\t{\n\t\t\t\tCloseBlock();\n\t\t\t\tisInType = oldIsInType;\n\t\t\t}\n\t\t}\n\n\t\tpublic void WriteAssemblyHeader(MetadataFile module)\n\t\t{\n\t\t\tvar metadata = module.Metadata;\n\t\t\tif (!metadata.IsAssembly)\n\t\t\t\treturn;\n\t\t\toutput.Write(\".assembly \");\n\t\t\tvar asm = metadata.GetAssemblyDefinition();\n\t\t\tif ((asm.Flags & AssemblyFlags.WindowsRuntime) == AssemblyFlags.WindowsRuntime)\n\t\t\t\toutput.Write(\"windowsruntime \");\n\t\t\toutput.Write(DisassemblerHelpers.Escape(metadata.GetString(asm.Name)));\n\t\t\tOpenBlock(false);\n\t\t\tWriteAttributes(module, asm.GetCustomAttributes());\n\t\t\tWriteSecurityDeclarations(module, asm.GetDeclarativeSecurityAttributes());\n\t\t\tif (!asm.PublicKey.IsNil)\n\t\t\t{\n\t\t\t\toutput.Write(\".publickey = \");\n\t\t\t\tWriteBlob(asm.PublicKey, metadata);\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t\tif (asm.HashAlgorithm != AssemblyHashAlgorithm.None)\n\t\t\t{\n\t\t\t\toutput.Write(\".hash algorithm 0x{0:x8}\", (int)asm.HashAlgorithm);\n\t\t\t\tif (asm.HashAlgorithm == AssemblyHashAlgorithm.Sha1)\n\t\t\t\t\toutput.Write(\" // SHA1\");\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t\tVersion v = asm.Version;\n\t\t\tif (v != null)\n\t\t\t{\n\t\t\t\toutput.WriteLine(\".ver {0}:{1}:{2}:{3}\", v.Major, v.Minor, v.Build, v.Revision);\n\t\t\t}\n\t\t\tCloseBlock();\n\t\t}\n\n\t\tpublic void WriteAssemblyReferences(MetadataReader metadata)\n\t\t{\n\t\t\tforeach (var m in metadata.GetModuleReferences())\n\t\t\t{\n\t\t\t\tvar mref = metadata.GetModuleReference(m);\n\t\t\t\toutput.WriteLine(\".module extern {0}\", DisassemblerHelpers.Escape(metadata.GetString(mref.Name)));\n\t\t\t}\n\t\t\tforeach (var a in metadata.AssemblyReferences)\n\t\t\t{\n\t\t\t\tvar aref = metadata.GetAssemblyReference(a);\n\t\t\t\toutput.Write(\".assembly extern \");\n\t\t\t\tif ((aref.Flags & AssemblyFlags.WindowsRuntime) == AssemblyFlags.WindowsRuntime)\n\t\t\t\t\toutput.Write(\"windowsruntime \");\n\t\t\t\toutput.Write(DisassemblerHelpers.Escape(metadata.GetString(aref.Name)));\n\t\t\t\tOpenBlock(false);\n\t\t\t\tif (!aref.PublicKeyOrToken.IsNil)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\".publickeytoken = \");\n\t\t\t\t\tWriteBlob(aref.PublicKeyOrToken, metadata);\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t}\n\t\t\t\tif (aref.Version != null)\n\t\t\t\t{\n\t\t\t\t\toutput.WriteLine(\".ver {0}:{1}:{2}:{3}\", aref.Version.Major, aref.Version.Minor, aref.Version.Build, aref.Version.Revision);\n\t\t\t\t}\n\t\t\t\tCloseBlock();\n\t\t\t}\n\t\t}\n\n\t\tpublic void WriteModuleHeader(MetadataFile module, bool skipMVID = false)\n\t\t{\n\t\t\tvar metadata = module.Metadata;\n\n\t\t\tvoid WriteExportedType(ExportedType exportedType)\n\t\t\t{\n\t\t\t\tif (!exportedType.Namespace.IsNil)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(DisassemblerHelpers.Escape(metadata.GetString(exportedType.Namespace)));\n\t\t\t\t\toutput.Write('.');\n\t\t\t\t}\n\t\t\t\toutput.Write(DisassemblerHelpers.Escape(metadata.GetString(exportedType.Name)));\n\t\t\t}\n\n\t\t\tforeach (var et in metadata.ExportedTypes)\n\t\t\t{\n\t\t\t\tvar exportedType = metadata.GetExportedType(et);\n\t\t\t\toutput.Write(\".class extern \");\n\t\t\t\tif (exportedType.IsForwarder)\n\t\t\t\t\toutput.Write(\"forwarder \");\n\t\t\t\tWriteExportedType(exportedType);\n\t\t\t\tOpenBlock(false);\n\t\t\t\tswitch (exportedType.Implementation.Kind)\n\t\t\t\t{\n\t\t\t\t\tcase HandleKind.AssemblyFile:\n\t\t\t\t\t\tvar file = metadata.GetAssemblyFile((AssemblyFileHandle)exportedType.Implementation);\n\t\t\t\t\t\toutput.WriteLine(\".file {0}\", metadata.GetString(file.Name));\n\t\t\t\t\t\tint typeDefId = exportedType.GetTypeDefinitionId();\n\t\t\t\t\t\tif (typeDefId != 0)\n\t\t\t\t\t\t\toutput.WriteLine(\".class 0x{0:x8}\", typeDefId);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HandleKind.ExportedType:\n\t\t\t\t\t\toutput.Write(\".class extern \");\n\t\t\t\t\t\tvar declaringType = metadata.GetExportedType((ExportedTypeHandle)exportedType.Implementation);\n\t\t\t\t\t\twhile (true)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tWriteExportedType(declaringType);\n\t\t\t\t\t\t\tif (declaringType.Implementation.Kind == HandleKind.ExportedType)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdeclaringType = metadata.GetExportedType((ExportedTypeHandle)declaringType.Implementation);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HandleKind.AssemblyReference:\n\t\t\t\t\t\toutput.Write(\".assembly extern \");\n\t\t\t\t\t\tvar reference = metadata.GetAssemblyReference((AssemblyReferenceHandle)exportedType.Implementation);\n\t\t\t\t\t\toutput.Write(DisassemblerHelpers.Escape(metadata.GetString(reference.Name)));\n\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new BadImageFormatException(\"Implementation must either be an index into the File, ExportedType or AssemblyRef table.\");\n\t\t\t\t}\n\t\t\t\tCloseBlock();\n\t\t\t}\n\t\t\tvar moduleDefinition = metadata.GetModuleDefinition();\n\n\t\t\toutput.WriteLine(\".module {0}\", metadata.GetString(moduleDefinition.Name));\n\t\t\tif (!skipMVID)\n\t\t\t{\n\t\t\t\toutput.WriteLine(\"// MVID: {0}\", metadata.GetGuid(moduleDefinition.Mvid).ToString(\"B\").ToUpperInvariant());\n\t\t\t}\n\n\t\t\tif (module is PEFile peFile)\n\t\t\t{\n\t\t\t\tvar headers = peFile.Reader.PEHeaders;\n\t\t\t\toutput.WriteLine(\".imagebase 0x{0:x8}\", headers.PEHeader.ImageBase);\n\t\t\t\toutput.WriteLine(\".file alignment 0x{0:x8}\", headers.PEHeader.FileAlignment);\n\t\t\t\toutput.WriteLine(\".stackreserve 0x{0:x8}\", headers.PEHeader.SizeOfStackReserve);\n\t\t\t\toutput.WriteLine(\".subsystem 0x{0:x} // {1}\", headers.PEHeader.Subsystem, headers.PEHeader.Subsystem.ToString());\n\t\t\t\toutput.WriteLine(\".corflags 0x{0:x} // {1}\", headers.CorHeader.Flags, headers.CorHeader.Flags.ToString());\n\t\t\t}\n\n\t\t\tWriteAttributes(module, metadata.GetCustomAttributes(EntityHandle.ModuleDefinition));\n\t\t}\n\n\t\tpublic void WriteModuleContents(MetadataFile module)\n\t\t{\n\t\t\tforeach (var handle in Process(module, module.Metadata.GetTopLevelTypeDefinitions().ToArray()))\n\t\t\t{\n\t\t\t\tDisassembleType(module, handle);\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Disassembler/SortByNameProcessor.cs",
    "content": "// Copyright (c) 2022 Tom Englert\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.Decompiler.Disassembler\n{\n\tpublic class SortByNameProcessor : IEntityProcessor\n\t{\n\t\tpublic IReadOnlyCollection<InterfaceImplementationHandle> Process(MetadataFile module,\n\t\t\tIReadOnlyCollection<InterfaceImplementationHandle> items)\n\t\t{\n\t\t\treturn items.OrderBy(item => GetSortKey(item, module)).ToArray();\n\t\t}\n\n\t\tpublic IReadOnlyCollection<TypeDefinitionHandle> Process(MetadataFile module,\n\t\t\tIReadOnlyCollection<TypeDefinitionHandle> items)\n\t\t{\n\t\t\treturn items.OrderBy(item => GetSortKey(item, module)).ToArray();\n\t\t}\n\n\t\tpublic IReadOnlyCollection<MethodDefinitionHandle> Process(MetadataFile module,\n\t\t\tIReadOnlyCollection<MethodDefinitionHandle> items)\n\t\t{\n\t\t\treturn items.OrderBy(item => GetSortKey(item, module)).ToArray();\n\t\t}\n\n\t\tpublic IReadOnlyCollection<PropertyDefinitionHandle> Process(MetadataFile module,\n\t\t\tIReadOnlyCollection<PropertyDefinitionHandle> items)\n\t\t{\n\t\t\treturn items.OrderBy(item => GetSortKey(item, module)).ToArray();\n\t\t}\n\n\t\tpublic IReadOnlyCollection<EventDefinitionHandle> Process(MetadataFile module,\n\t\t\tIReadOnlyCollection<EventDefinitionHandle> items)\n\t\t{\n\t\t\treturn items.OrderBy(item => GetSortKey(item, module)).ToArray();\n\t\t}\n\n\t\tpublic IReadOnlyCollection<FieldDefinitionHandle> Process(MetadataFile module,\n\t\t\tIReadOnlyCollection<FieldDefinitionHandle> items)\n\t\t{\n\t\t\treturn items.OrderBy(item => GetSortKey(item, module)).ToArray();\n\t\t}\n\n\t\tpublic IReadOnlyCollection<CustomAttributeHandle> Process(MetadataFile module,\n\t\t\tIReadOnlyCollection<CustomAttributeHandle> items)\n\t\t{\n\t\t\treturn items.OrderBy(item => GetSortKey(item, module)).ToArray();\n\t\t}\n\n\t\tprivate static string GetSortKey(TypeDefinitionHandle handle, MetadataFile module) =>\n\t\t\thandle.GetFullTypeName(module.Metadata).ToILNameString();\n\n\t\tprivate static string GetSortKey(MethodDefinitionHandle handle, MetadataFile module)\n\t\t{\n\t\t\tPlainTextOutput output = new PlainTextOutput();\n\t\t\tMethodDefinition definition = module.Metadata.GetMethodDefinition(handle);\n\n\t\t\t// Start with the methods name, skip return type\n\t\t\toutput.Write(module.Metadata.GetString(definition.Name));\n\n\t\t\tDisassemblerSignatureTypeProvider signatureProvider = new DisassemblerSignatureTypeProvider(module, output);\n\t\t\tMethodSignature<Action<ILNameSyntax>> signature =\n\t\t\t\tdefinition.DecodeSignature(signatureProvider, new MetadataGenericContext(handle, module));\n\n\t\t\tif (signature.GenericParameterCount > 0)\n\t\t\t{\n\t\t\t\toutput.Write($\"`{signature.GenericParameterCount}\");\n\t\t\t}\n\n\t\t\tInstructionOutputExtensions.WriteParameterList(output, signature);\n\n\t\t\treturn output.ToString();\n\t\t}\n\n\t\tprivate static string GetSortKey(InterfaceImplementationHandle handle, MetadataFile module) =>\n\t\t\tmodule.Metadata.GetInterfaceImplementation(handle)\n\t\t\t\t.Interface\n\t\t\t\t.GetFullTypeName(module.Metadata)\n\t\t\t\t.ToILNameString();\n\n\t\tprivate static string GetSortKey(FieldDefinitionHandle handle, MetadataFile module) =>\n\t\t\tmodule.Metadata.GetString(module.Metadata.GetFieldDefinition(handle).Name);\n\n\t\tprivate static string GetSortKey(PropertyDefinitionHandle handle, MetadataFile module) =>\n\t\t\tmodule.Metadata.GetString(module.Metadata.GetPropertyDefinition(handle).Name);\n\n\t\tprivate static string GetSortKey(EventDefinitionHandle handle, MetadataFile module) =>\n\t\t\tmodule.Metadata.GetString(module.Metadata.GetEventDefinition(handle).Name);\n\n\t\tprivate static string GetSortKey(CustomAttributeHandle handle, MetadataFile module) =>\n\t\t\tmodule.Metadata.GetCustomAttribute(handle)\n\t\t\t\t.Constructor\n\t\t\t\t.GetDeclaringType(module.Metadata)\n\t\t\t\t.GetFullTypeName(module.Metadata)\n\t\t\t\t.ToILNameString();\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler/Documentation/GetPotentiallyNestedClassTypeReference.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.Documentation\n{\n\t/// <summary>\n\t/// A type reference of the form 'Some.Namespace.TopLevelType.NestedType`n'.\n\t/// We do not know the boundary between namespace name and top level type, so we have to try\n\t/// all possibilities.\n\t/// The type parameter count only applies to the innermost type, all outer types must be non-generic.\n\t/// </summary>\n\t[Serializable]\n\tpublic class GetPotentiallyNestedClassTypeReference : ITypeReference\n\t{\n\t\treadonly string typeName;\n\t\treadonly int typeParameterCount;\n\n\t\tpublic GetPotentiallyNestedClassTypeReference(string typeName, int typeParameterCount)\n\t\t{\n\t\t\tthis.typeName = typeName;\n\t\t\tthis.typeParameterCount = typeParameterCount;\n\t\t}\n\n\t\tpublic IType Resolve(ITypeResolveContext context)\n\t\t{\n\t\t\tstring[] parts = typeName.Split('.');\n\t\t\tvar assemblies = new[] { context.CurrentModule }.Concat(context.Compilation.Modules);\n\t\t\tfor (int i = parts.Length - 1; i >= 0; i--)\n\t\t\t{\n\t\t\t\tstring ns = string.Join(\".\", parts, 0, i);\n\t\t\t\tstring name = parts[i];\n\t\t\t\tint topLevelTPC = (i == parts.Length - 1 ? typeParameterCount : 0);\n\t\t\t\tforeach (var asm in assemblies)\n\t\t\t\t{\n\t\t\t\t\tif (asm == null)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tITypeDefinition typeDef = asm.GetTypeDefinition(new TopLevelTypeName(ns, name, topLevelTPC));\n\t\t\t\t\tfor (int j = i + 1; j < parts.Length && typeDef != null; j++)\n\t\t\t\t\t{\n\t\t\t\t\t\tint tpc = (j == parts.Length - 1 ? typeParameterCount : 0);\n\t\t\t\t\t\ttypeDef = typeDef.NestedTypes.FirstOrDefault(n => n.Name == parts[j] && n.TypeParameterCount == tpc);\n\t\t\t\t\t}\n\t\t\t\t\tif (typeDef != null)\n\t\t\t\t\t\treturn typeDef;\n\t\t\t\t}\n\t\t\t}\n\t\t\tint idx = typeName.LastIndexOf('.');\n\t\t\tif (idx < 0)\n\t\t\t\treturn new UnknownType(\"\", typeName, typeParameterCount);\n\t\t\t// give back a guessed namespace/type name\n\t\t\treturn new UnknownType(typeName.Substring(0, idx), typeName.Substring(idx + 1), typeParameterCount);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Resolves the type reference within the context of the given PE file.\n\t\t/// </summary>\n\t\t/// <returns>Either TypeDefinitionHandle, if the type is defined in the module or ExportedTypeHandle,\n\t\t/// if the module contains a type forwarder. Returns a nil handle, if the type was not found.</returns>\n\t\tpublic EntityHandle ResolveInPEFile(MetadataFile module)\n\t\t{\n\t\t\tstring[] parts = typeName.Split('.');\n\t\t\tfor (int i = parts.Length - 1; i >= 0; i--)\n\t\t\t{\n\t\t\t\tstring ns = string.Join(\".\", parts, 0, i);\n\t\t\t\tstring name = parts[i];\n\t\t\t\tint topLevelTPC = (i == parts.Length - 1 ? typeParameterCount : 0);\n\t\t\t\tvar topLevelName = new TopLevelTypeName(ns, name, topLevelTPC);\n\t\t\t\tvar typeHandle = module.GetTypeDefinition(topLevelName);\n\n\t\t\t\tfor (int j = i + 1; j < parts.Length && !typeHandle.IsNil; j++)\n\t\t\t\t{\n\t\t\t\t\tint tpc = (j == parts.Length - 1 ? typeParameterCount : 0);\n\t\t\t\t\tvar typeDef = module.Metadata.GetTypeDefinition(typeHandle);\n\t\t\t\t\tstring lookupName = parts[j] + (tpc > 0 ? \"`\" + tpc : \"\");\n\t\t\t\t\ttypeHandle = typeDef.GetNestedTypes().FirstOrDefault(n => IsEqualShortName(n, module.Metadata, lookupName));\n\t\t\t\t}\n\n\t\t\t\tif (!typeHandle.IsNil)\n\t\t\t\t\treturn typeHandle;\n\t\t\t\tFullTypeName typeName = topLevelName;\n\t\t\t\tfor (int j = i + 1; j < parts.Length; j++)\n\t\t\t\t{\n\t\t\t\t\tint tpc = (j == parts.Length - 1 ? typeParameterCount : 0);\n\t\t\t\t\ttypeName = typeName.NestedType(parts[j], tpc);\n\t\t\t\t}\n\n\t\t\t\tvar exportedType = module.GetTypeForwarder(typeName);\n\t\t\t\tif (!exportedType.IsNil)\n\t\t\t\t\treturn exportedType;\n\t\t\t}\n\n\t\t\treturn default;\n\n\t\t\tbool IsEqualShortName(TypeDefinitionHandle h, MetadataReader metadata, string name)\n\t\t\t{\n\t\t\t\tvar nestedType = metadata.GetTypeDefinition(h);\n\t\t\t\treturn metadata.StringComparer.Equals(nestedType.Name, name);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Documentation/IdStringMemberReference.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Documentation\n{\n\t[Serializable]\n\tclass IdStringMemberReference : IMemberReference\n\t{\n\t\treadonly ITypeReference declaringTypeReference;\n\t\treadonly char memberType;\n\t\treadonly string memberIdString;\n\n\t\tpublic IdStringMemberReference(ITypeReference declaringTypeReference, char memberType, string memberIdString)\n\t\t{\n\t\t\tthis.declaringTypeReference = declaringTypeReference;\n\t\t\tthis.memberType = memberType;\n\t\t\tthis.memberIdString = memberIdString;\n\t\t}\n\n\t\tbool CanMatch(IMember member)\n\t\t{\n\t\t\tswitch (member.SymbolKind)\n\t\t\t{\n\t\t\t\tcase SymbolKind.Field:\n\t\t\t\t\treturn memberType == 'F';\n\t\t\t\tcase SymbolKind.Property:\n\t\t\t\tcase SymbolKind.Indexer:\n\t\t\t\t\treturn memberType == 'P';\n\t\t\t\tcase SymbolKind.Event:\n\t\t\t\t\treturn memberType == 'E';\n\t\t\t\tcase SymbolKind.Method:\n\t\t\t\tcase SymbolKind.Operator:\n\t\t\t\tcase SymbolKind.Constructor:\n\t\t\t\tcase SymbolKind.Destructor:\n\t\t\t\t\treturn memberType == 'M';\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException(member.SymbolKind.ToString());\n\t\t\t}\n\t\t}\n\n\t\tpublic ITypeReference DeclaringTypeReference {\n\t\t\tget { return declaringTypeReference; }\n\t\t}\n\n\t\tpublic IMember Resolve(ITypeResolveContext context)\n\t\t{\n\t\t\tIType declaringType = declaringTypeReference.Resolve(context);\n\t\t\tforeach (var member in declaringType.GetMembers(CanMatch, GetMemberOptions.IgnoreInheritedMembers))\n\t\t\t{\n\t\t\t\tif (IdStringProvider.GetIdString(member) == memberIdString)\n\t\t\t\t\treturn member;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Documentation/IdStringProvider.cs",
    "content": "// Copyright (c) 2010-2018 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.Documentation\n{\n\t/// <summary>\n\t/// Provides ID strings for entities. (C# 4.0 spec, §A.3.1)\n\t/// ID strings are used to identify members in XML documentation files.\n\t/// </summary>\n\tpublic static class IdStringProvider\n\t{\n\t\t#region GetIdString\n\t\t/// <summary>\n\t\t/// Gets the ID string (C# 4.0 spec, §A.3.1) for the specified entity.\n\t\t/// </summary>\n\t\tpublic static string GetIdString(this IEntity entity)\n\t\t{\n\t\t\tStringBuilder b = new StringBuilder();\n\t\t\tswitch (entity.SymbolKind)\n\t\t\t{\n\t\t\t\tcase SymbolKind.TypeDefinition:\n\t\t\t\t\tb.Append(\"T:\");\n\t\t\t\t\tAppendTypeName(b, (ITypeDefinition)entity, false);\n\t\t\t\t\treturn b.ToString();\n\t\t\t\tcase SymbolKind.Field:\n\t\t\t\t\tb.Append(\"F:\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase SymbolKind.Property:\n\t\t\t\tcase SymbolKind.Indexer:\n\t\t\t\t\tb.Append(\"P:\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase SymbolKind.Event:\n\t\t\t\t\tb.Append(\"E:\");\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tb.Append(\"M:\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tIMember member = (IMember)entity;\n\t\t\tif (member.DeclaringType != null)\n\t\t\t{\n\t\t\t\tAppendTypeName(b, member.DeclaringType, false);\n\t\t\t\tb.Append('.');\n\t\t\t}\n\t\t\tif (member.IsExplicitInterfaceImplementation && member.Name.IndexOf('.') < 0 && member.ExplicitlyImplementedInterfaceMembers.Count() == 1)\n\t\t\t{\n\t\t\t\tAppendTypeName(b, member.ExplicitlyImplementedInterfaceMembers.First().DeclaringType, true);\n\t\t\t\tb.Append('#');\n\t\t\t}\n\t\t\tb.Append(member.Name.Replace('.', '#').Replace('<', '{').Replace('>', '}'));\n\t\t\tIMethod method = member as IMethod;\n\t\t\tif (method != null && method.TypeParameters.Count > 0)\n\t\t\t{\n\t\t\t\tb.Append(\"``\");\n\t\t\t\tb.Append(method.TypeParameters.Count);\n\t\t\t}\n\t\t\tIParameterizedMember parameterizedMember = member as IParameterizedMember;\n\t\t\tif (parameterizedMember != null && parameterizedMember.Parameters.Count > 0)\n\t\t\t{\n\t\t\t\tb.Append('(');\n\t\t\t\tvar parameters = parameterizedMember.Parameters;\n\t\t\t\tfor (int i = 0; i < parameters.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\tb.Append(',');\n\t\t\t\t\tAppendTypeName(b, parameters[i].Type, false);\n\t\t\t\t}\n\t\t\t\tb.Append(')');\n\t\t\t}\n\t\t\tif (member.SymbolKind == SymbolKind.Operator && (member.Name == \"op_Implicit\" || member.Name == \"op_Explicit\"))\n\t\t\t{\n\t\t\t\tb.Append('~');\n\t\t\t\tAppendTypeName(b, member.ReturnType, false);\n\t\t\t}\n\t\t\treturn b.ToString();\n\t\t}\n\t\t#endregion\n\n\t\t#region GetTypeName\n\t\tpublic static string GetTypeName(IType type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tStringBuilder b = new StringBuilder();\n\t\t\tAppendTypeName(b, type, false);\n\t\t\treturn b.ToString();\n\t\t}\n\n\t\tstatic void AppendTypeName(StringBuilder b, IType type, bool explicitInterfaceImpl)\n\t\t{\n\t\t\tswitch (type.Kind)\n\t\t\t{\n\t\t\t\tcase TypeKind.Dynamic:\n\t\t\t\t\tb.Append(explicitInterfaceImpl ? \"System#Object\" : \"System.Object\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeKind.TypeParameter:\n\t\t\t\t\tITypeParameter tp = (ITypeParameter)type;\n\t\t\t\t\tif (explicitInterfaceImpl)\n\t\t\t\t\t{\n\t\t\t\t\t\tb.Append(tp.Name);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tb.Append('`');\n\t\t\t\t\t\tif (tp.OwnerType == SymbolKind.Method)\n\t\t\t\t\t\t\tb.Append('`');\n\t\t\t\t\t\tb.Append(tp.Index);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeKind.Array:\n\t\t\t\t\tArrayType array = (ArrayType)type;\n\t\t\t\t\tAppendTypeName(b, array.ElementType, explicitInterfaceImpl);\n\t\t\t\t\tb.Append('[');\n\t\t\t\t\tif (array.Dimensions > 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tfor (int i = 0; i < array.Dimensions; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\t\t\tb.Append(explicitInterfaceImpl ? '@' : ',');\n\t\t\t\t\t\t\tif (!explicitInterfaceImpl)\n\t\t\t\t\t\t\t\tb.Append(\"0:\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tb.Append(']');\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeKind.Pointer:\n\t\t\t\t\tAppendTypeName(b, ((PointerType)type).ElementType, explicitInterfaceImpl);\n\t\t\t\t\tb.Append('*');\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeKind.ByReference:\n\t\t\t\t\tAppendTypeName(b, ((ByReferenceType)type).ElementType, explicitInterfaceImpl);\n\t\t\t\t\tb.Append('@');\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tIType declType = type.DeclaringType;\n\t\t\t\t\tif (declType != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tAppendTypeName(b, declType, explicitInterfaceImpl);\n\t\t\t\t\t\tb.Append(explicitInterfaceImpl ? '#' : '.');\n\t\t\t\t\t\tb.Append(type.Name);\n\t\t\t\t\t\tAppendTypeParameters(b, type, declType.TypeParameterCount, explicitInterfaceImpl);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif (explicitInterfaceImpl)\n\t\t\t\t\t\t\tb.Append(type.FullName.Replace('.', '#'));\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tb.Append(type.FullName);\n\t\t\t\t\t\tAppendTypeParameters(b, type, 0, explicitInterfaceImpl);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tstatic void AppendTypeParameters(StringBuilder b, IType type, int outerTypeParameterCount, bool explicitInterfaceImpl)\n\t\t{\n\t\t\tint tpc = type.TypeParameterCount - outerTypeParameterCount;\n\t\t\tif (tpc > 0)\n\t\t\t{\n\t\t\t\tParameterizedType pt = type as ParameterizedType;\n\t\t\t\tif (pt != null)\n\t\t\t\t{\n\t\t\t\t\tb.Append('{');\n\t\t\t\t\tvar ta = pt.TypeArguments;\n\t\t\t\t\tfor (int i = outerTypeParameterCount; i < ta.Count; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (i > outerTypeParameterCount)\n\t\t\t\t\t\t\tb.Append(explicitInterfaceImpl ? '@' : ',');\n\t\t\t\t\t\tAppendTypeName(b, ta[i], explicitInterfaceImpl);\n\t\t\t\t\t}\n\t\t\t\t\tb.Append('}');\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tb.Append('`');\n\t\t\t\t\tb.Append(tpc);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region ParseMemberName\n\t\t/// <summary>\n\t\t/// Parse the ID string into a member reference.\n\t\t/// </summary>\n\t\t/// <param name=\"memberIdString\">The ID string representing the member (with \"M:\", \"F:\", \"P:\" or \"E:\" prefix).</param>\n\t\t/// <returns>A member reference that represents the ID string.</returns>\n\t\t/// <exception cref=\"ReflectionNameParseException\">The syntax of the ID string is invalid</exception>\n\t\t/// <remarks>\n\t\t/// The member reference will look in <see cref=\"ITypeResolveContext.CurrentModule\"/> first,\n\t\t/// and if the member is not found there,\n\t\t/// it will look in all other assemblies of the compilation.\n\t\t/// </remarks>\n\t\tpublic static IMemberReference ParseMemberIdString(string memberIdString)\n\t\t{\n\t\t\tif (memberIdString == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(memberIdString));\n\t\t\tif (memberIdString.Length < 2 || memberIdString[1] != ':')\n\t\t\t\tthrow new ReflectionNameParseException(0, \"Missing type tag\");\n\t\t\tchar typeChar = memberIdString[0];\n\t\t\tint parenPos = memberIdString.IndexOf('(');\n\t\t\tif (parenPos < 0)\n\t\t\t\tparenPos = memberIdString.LastIndexOf('~');\n\t\t\tif (parenPos < 0)\n\t\t\t\tparenPos = memberIdString.Length;\n\t\t\tint dotPos = memberIdString.LastIndexOf('.', parenPos - 1);\n\t\t\tif (dotPos < 0)\n\t\t\t\tthrow new ReflectionNameParseException(0, \"Could not find '.' separating type name from member name\");\n\t\t\tstring typeName = memberIdString.Substring(0, dotPos);\n\t\t\tint pos = 2;\n\t\t\tITypeReference typeReference = ParseTypeName(typeName, ref pos);\n\t\t\tif (pos != typeName.Length)\n\t\t\t\tthrow new ReflectionNameParseException(pos, \"Expected end of type name\");\n\t\t\t//\t\t\tstring memberName = memberIDString.Substring(dotPos + 1, parenPos - (dotPos + 1));\n\t\t\t//\t\t\tpos = memberName.LastIndexOf(\"``\");\n\t\t\t//\t\t\tif (pos > 0)\n\t\t\t//\t\t\t\tmemberName = memberName.Substring(0, pos);\n\t\t\t//\t\t\tmemberName = memberName.Replace('#', '.');\n\t\t\treturn new IdStringMemberReference(typeReference, typeChar, memberIdString);\n\t\t}\n\t\t#endregion\n\n\t\t#region ParseTypeName\n\t\t/// <summary>\n\t\t/// Parse the ID string type name into a type reference.\n\t\t/// </summary>\n\t\t/// <param name=\"typeName\">The ID string representing the type (the \"T:\" prefix is optional).</param>\n\t\t/// <returns>A type reference that represents the ID string.</returns>\n\t\t/// <exception cref=\"ReflectionNameParseException\">The syntax of the ID string is invalid</exception>\n\t\t/// <remarks>\n\t\t/// <para>\n\t\t/// The type reference will look in <see cref=\"ITypeResolveContext.CurrentModule\"/> first,\n\t\t/// and if the type is not found there,\n\t\t/// it will look in all other assemblies of the compilation.\n\t\t/// </para>\n\t\t/// <para>\n\t\t/// If the type is open (contains type parameters '`0' or '``0'),\n\t\t/// an <see cref=\"ITypeResolveContext\"/> with the appropriate CurrentTypeDefinition/CurrentMember is required\n\t\t/// to resolve the reference to the ITypeParameter.\n\t\t/// </para>\n\t\t/// </remarks>\n\t\tpublic static ITypeReference ParseTypeName(string typeName)\n\t\t{\n\t\t\tif (typeName == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(typeName));\n\t\t\tint pos = 0;\n\t\t\tif (typeName.StartsWith(\"T:\", StringComparison.Ordinal))\n\t\t\t\tpos = 2;\n\t\t\tITypeReference r = ParseTypeName(typeName, ref pos);\n\t\t\tif (pos < typeName.Length)\n\t\t\t\tthrow new ReflectionNameParseException(pos, \"Expected end of type name\");\n\t\t\treturn r;\n\t\t}\n\n\t\tstatic bool IsIDStringSpecialCharacter(char c)\n\t\t{\n\t\t\tswitch (c)\n\t\t\t{\n\t\t\t\tcase ':':\n\t\t\t\tcase '{':\n\t\t\t\tcase '}':\n\t\t\t\tcase '[':\n\t\t\t\tcase ']':\n\t\t\t\tcase '(':\n\t\t\t\tcase ')':\n\t\t\t\tcase '`':\n\t\t\t\tcase '*':\n\t\t\t\tcase '@':\n\t\t\t\tcase ',':\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tstatic ITypeReference ParseTypeName(string typeName, ref int pos)\n\t\t{\n\t\t\tstring reflectionTypeName = typeName;\n\t\t\tif (pos == typeName.Length)\n\t\t\t\tthrow new ReflectionNameParseException(pos, \"Unexpected end\");\n\t\t\tITypeReference result;\n\t\t\tif (reflectionTypeName[pos] == '`')\n\t\t\t{\n\t\t\t\t// type parameter reference\n\t\t\t\tpos++;\n\t\t\t\tif (pos == reflectionTypeName.Length)\n\t\t\t\t\tthrow new ReflectionNameParseException(pos, \"Unexpected end\");\n\t\t\t\tif (reflectionTypeName[pos] == '`')\n\t\t\t\t{\n\t\t\t\t\t// method type parameter reference\n\t\t\t\t\tpos++;\n\t\t\t\t\tint index = ReflectionHelper.ReadTypeParameterCount(reflectionTypeName, ref pos);\n\t\t\t\t\tresult = TypeParameterReference.Create(SymbolKind.Method, index);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// class type parameter reference\n\t\t\t\t\tint index = ReflectionHelper.ReadTypeParameterCount(reflectionTypeName, ref pos);\n\t\t\t\t\tresult = TypeParameterReference.Create(SymbolKind.TypeDefinition, index);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// not a type parameter reference: read the actual type name\n\t\t\t\tList<ITypeReference> typeArguments = new List<ITypeReference>();\n\t\t\t\tstring typeNameWithoutSuffix = ReadTypeName(typeName, ref pos, true, out int typeParameterCount, typeArguments);\n\t\t\t\tresult = new GetPotentiallyNestedClassTypeReference(typeNameWithoutSuffix, typeParameterCount);\n\t\t\t\twhile (pos < typeName.Length && typeName[pos] == '.')\n\t\t\t\t{\n\t\t\t\t\tpos++;\n\t\t\t\t\tstring nestedTypeName = ReadTypeName(typeName, ref pos, false, out typeParameterCount, typeArguments);\n\t\t\t\t\tresult = new NestedTypeReference(result, nestedTypeName, typeParameterCount);\n\t\t\t\t}\n\t\t\t\tif (typeArguments.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tresult = new ParameterizedTypeReference(result, typeArguments);\n\t\t\t\t}\n\t\t\t}\n\t\t\twhile (pos < typeName.Length)\n\t\t\t{\n\t\t\t\tswitch (typeName[pos])\n\t\t\t\t{\n\t\t\t\t\tcase '[':\n\t\t\t\t\t\tint dimensions = 1;\n\t\t\t\t\t\tdo\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpos++;\n\t\t\t\t\t\t\tif (pos == typeName.Length)\n\t\t\t\t\t\t\t\tthrow new ReflectionNameParseException(pos, \"Unexpected end\");\n\t\t\t\t\t\t\tif (typeName[pos] == ',')\n\t\t\t\t\t\t\t\tdimensions++;\n\t\t\t\t\t\t} while (typeName[pos] != ']');\n\t\t\t\t\t\tresult = new ArrayTypeReference(result, dimensions);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '*':\n\t\t\t\t\t\tresult = new PointerTypeReference(result);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '@':\n\t\t\t\t\t\tresult = new ByReferenceTypeReference(result);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tstatic string ReadTypeName(string typeName, ref int pos, bool allowDottedName, out int typeParameterCount, List<ITypeReference> typeArguments)\n\t\t{\n\t\t\tint startPos = pos;\n\t\t\t// skip the simple name portion:\n\t\t\twhile (pos < typeName.Length && !IsIDStringSpecialCharacter(typeName[pos]) && (allowDottedName || typeName[pos] != '.'))\n\t\t\t\tpos++;\n\t\t\tif (pos == startPos)\n\t\t\t\tthrow new ReflectionNameParseException(pos, \"Expected type name\");\n\t\t\tstring shortTypeName = typeName.Substring(startPos, pos - startPos);\n\t\t\t// read type arguments:\n\t\t\ttypeParameterCount = 0;\n\t\t\tif (pos < typeName.Length && typeName[pos] == '`')\n\t\t\t{\n\t\t\t\t// unbound generic type\n\t\t\t\tpos++;\n\t\t\t\ttypeParameterCount = ReflectionHelper.ReadTypeParameterCount(typeName, ref pos);\n\t\t\t}\n\t\t\telse if (pos < typeName.Length && typeName[pos] == '{')\n\t\t\t{\n\t\t\t\t// bound generic type\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tpos++;\n\t\t\t\t\ttypeArguments.Add(ParseTypeName(typeName, ref pos));\n\t\t\t\t\ttypeParameterCount++;\n\t\t\t\t\tif (pos == typeName.Length)\n\t\t\t\t\t\tthrow new ReflectionNameParseException(pos, \"Unexpected end\");\n\t\t\t\t} while (typeName[pos] == ',');\n\t\t\t\tif (typeName[pos] != '}')\n\t\t\t\t\tthrow new ReflectionNameParseException(pos, \"Expected '}'\");\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\treturn shortTypeName;\n\t\t}\n\t\t#endregion\n\n\t\t#region FindEntity\n\t\t/// <summary>\n\t\t/// Finds the entity in the given type resolve context.\n\t\t/// </summary>\n\t\t/// <param name=\"idString\">ID string of the entity.</param>\n\t\t/// <param name=\"context\">Type resolve context</param>\n\t\t/// <returns>Returns the entity, or null if it is not found.</returns>\n\t\t/// <exception cref=\"ReflectionNameParseException\">The syntax of the ID string is invalid</exception>\n\t\tpublic static IEntity FindEntity(string idString, ITypeResolveContext context)\n\t\t{\n\t\t\tif (idString == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(idString));\n\t\t\tif (context == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(context));\n\t\t\tif (idString.StartsWith(\"T:\", StringComparison.Ordinal))\n\t\t\t{\n\t\t\t\treturn ParseTypeName(idString.Substring(2)).Resolve(context).GetDefinition();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn ParseMemberIdString(idString).Resolve(context);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Documentation/XmlDocLoader.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\nusing System.Globalization;\nusing System.IO;\nusing System.Runtime.CompilerServices;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.Decompiler.Documentation\n{\n\t/// <summary>\n\t/// Helps finding and loading .xml documentation.\n\t/// </summary>\n\tpublic static class XmlDocLoader\n\t{\n\t\tstatic readonly Lazy<XmlDocumentationProvider> mscorlibDocumentation = new Lazy<XmlDocumentationProvider>(LoadMscorlibDocumentation);\n\t\tstatic readonly ConditionalWeakTable<MetadataFile, XmlDocumentationProvider> cache = new();\n\n\t\tstatic XmlDocumentationProvider LoadMscorlibDocumentation()\n\t\t{\n\t\t\tstring xmlDocFile = FindXmlDocumentation(\"mscorlib.dll\", TargetRuntime.Net_4_0)\n\t\t\t\t?? FindXmlDocumentation(\"mscorlib.dll\", TargetRuntime.Net_2_0);\n\t\t\tif (xmlDocFile != null)\n\t\t\t\treturn new XmlDocumentationProvider(xmlDocFile);\n\t\t\telse\n\t\t\t\treturn null;\n\t\t}\n\n\t\tpublic static XmlDocumentationProvider MscorlibDocumentation {\n\t\t\tget { return mscorlibDocumentation.Value; }\n\t\t}\n\n\t\tpublic static XmlDocumentationProvider LoadDocumentation(MetadataFile module)\n\t\t{\n\t\t\tif (module == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(module));\n\t\t\tlock (cache)\n\t\t\t{\n\t\t\t\tif (!cache.TryGetValue(module, out XmlDocumentationProvider xmlDoc))\n\t\t\t\t{\n\t\t\t\t\tstring xmlDocFile = LookupLocalizedXmlDoc(module.FileName);\n\t\t\t\t\tif (xmlDocFile == null)\n\t\t\t\t\t{\n\t\t\t\t\t\txmlDocFile = FindXmlDocumentation(Path.GetFileName(module.FileName), module.GetRuntime());\n\t\t\t\t\t}\n\t\t\t\t\tif (xmlDocFile != null)\n\t\t\t\t\t{\n\t\t\t\t\t\txmlDoc = new XmlDocumentationProvider(xmlDocFile);\n\t\t\t\t\t\tcache.Add(module, xmlDoc);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tcache.Add(module, null); // add missing documentation files as well\n\t\t\t\t\t\txmlDoc = null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn xmlDoc;\n\t\t\t}\n\t\t}\n\n\t\tstatic readonly string referenceAssembliesPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @\"Reference Assemblies\\Microsoft\\\\Framework\");\n\t\tstatic readonly string frameworkPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), @\"Microsoft.NET\\Framework\");\n\n\t\tstatic string FindXmlDocumentation(string assemblyFileName, TargetRuntime runtime)\n\t\t{\n\t\t\tstring fileName;\n\t\t\tswitch (runtime)\n\t\t\t{\n\t\t\t\tcase TargetRuntime.Net_1_0:\n\t\t\t\t\tfileName = LookupLocalizedXmlDoc(Path.Combine(frameworkPath, \"v1.0.3705\", assemblyFileName));\n\t\t\t\t\tbreak;\n\t\t\t\tcase TargetRuntime.Net_1_1:\n\t\t\t\t\tfileName = LookupLocalizedXmlDoc(Path.Combine(frameworkPath, \"v1.1.4322\", assemblyFileName));\n\t\t\t\t\tbreak;\n\t\t\t\tcase TargetRuntime.Net_2_0:\n\t\t\t\t\tfileName = LookupLocalizedXmlDoc(Path.Combine(referenceAssembliesPath, \"v3.5\", assemblyFileName))\n\t\t\t\t\t\t?? LookupLocalizedXmlDoc(Path.Combine(referenceAssembliesPath, @\".NETFramework\\v3.5\\Profile\\Client\", assemblyFileName))\n\t\t\t\t\t\t?? LookupLocalizedXmlDoc(Path.Combine(referenceAssembliesPath, \"v3.0\", assemblyFileName))\n\t\t\t\t\t\t?? LookupLocalizedXmlDoc(Path.Combine(frameworkPath, \"v2.0.50727\", assemblyFileName));\n\t\t\t\t\tbreak;\n\t\t\t\tcase TargetRuntime.Net_4_0:\n\t\t\t\tdefault:\n\t\t\t\t\tfileName = LookupLocalizedXmlDoc(Path.Combine(referenceAssembliesPath, @\".NETFramework\\v4.8.1\", assemblyFileName))\n\t\t\t\t\t\t?? LookupLocalizedXmlDoc(Path.Combine(referenceAssembliesPath, @\".NETFramework\\v4.8\", assemblyFileName))\n\t\t\t\t\t\t?? LookupLocalizedXmlDoc(Path.Combine(referenceAssembliesPath, @\".NETFramework\\v4.7.2\", assemblyFileName))\n\t\t\t\t\t\t?? LookupLocalizedXmlDoc(Path.Combine(referenceAssembliesPath, @\".NETFramework\\v4.7.1\", assemblyFileName))\n\t\t\t\t\t\t?? LookupLocalizedXmlDoc(Path.Combine(referenceAssembliesPath, @\".NETFramework\\v4.7\", assemblyFileName))\n\t\t\t\t\t\t?? LookupLocalizedXmlDoc(Path.Combine(referenceAssembliesPath, @\".NETFramework\\v4.6.2\", assemblyFileName))\n\t\t\t\t\t\t?? LookupLocalizedXmlDoc(Path.Combine(referenceAssembliesPath, @\".NETFramework\\v4.6.1\", assemblyFileName))\n\t\t\t\t\t\t?? LookupLocalizedXmlDoc(Path.Combine(referenceAssembliesPath, @\".NETFramework\\v4.6\", assemblyFileName))\n\t\t\t\t\t\t?? LookupLocalizedXmlDoc(Path.Combine(referenceAssembliesPath, @\".NETFramework\\v4.5.2\", assemblyFileName))\n\t\t\t\t\t\t?? LookupLocalizedXmlDoc(Path.Combine(referenceAssembliesPath, @\".NETFramework\\v4.5.1\", assemblyFileName))\n\t\t\t\t\t\t?? LookupLocalizedXmlDoc(Path.Combine(referenceAssembliesPath, @\".NETFramework\\v4.5\", assemblyFileName))\n\t\t\t\t\t\t?? LookupLocalizedXmlDoc(Path.Combine(referenceAssembliesPath, @\".NETFramework\\v4.0\", assemblyFileName))\n\t\t\t\t\t\t?? LookupLocalizedXmlDoc(Path.Combine(frameworkPath, \"v4.0.30319\", assemblyFileName));\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn fileName;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Given the assembly file name, looks up the XML documentation file name.\n\t\t/// Returns null if no XML documentation file is found.\n\t\t/// </summary>\n\t\tinternal static string LookupLocalizedXmlDoc(string fileName)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(fileName))\n\t\t\t\treturn null;\n\n\t\t\tstring xmlFileName = Path.ChangeExtension(fileName, \".xml\");\n\n\t\t\tCultureInfo currentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture;\n\t\t\tstring localizedXmlDocFile = GetLocalizedName(xmlFileName, currentCulture.Name);\n\t\t\tstring localizedXmlDocFallbackFile = GetLocalizedName(xmlFileName, currentCulture.TwoLetterISOLanguageName);\n\n\t\t\t//Debug.WriteLine(\"Try find XMLDoc @\" + localizedXmlDocFile);\n\t\t\tif (File.Exists(localizedXmlDocFile))\n\t\t\t{\n\t\t\t\treturn localizedXmlDocFile;\n\t\t\t}\n\t\t\t//Debug.WriteLine(\"Try find XMLDoc @\" + localizedXmlDocFallbackFile);\n\t\t\tif (File.Exists(localizedXmlDocFallbackFile))\n\t\t\t{\n\t\t\t\treturn localizedXmlDocFallbackFile;\n\t\t\t}\n\t\t\t//Debug.WriteLine(\"Try find XMLDoc @\" + xmlFileName);\n\t\t\tif (File.Exists(xmlFileName))\n\t\t\t{\n\t\t\t\treturn xmlFileName;\n\t\t\t}\n\t\t\tif (currentCulture.TwoLetterISOLanguageName != \"en\")\n\t\t\t{\n\t\t\t\tstring englishXmlDocFile = GetLocalizedName(xmlFileName, \"en\");\n\t\t\t\t//Debug.WriteLine(\"Try find XMLDoc @\" + englishXmlDocFile);\n\t\t\t\tif (File.Exists(englishXmlDocFile))\n\t\t\t\t{\n\t\t\t\t\treturn englishXmlDocFile;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tprivate static string GetLocalizedName(string fileName, string language)\n\t\t{\n\t\t\treturn Path.Combine(Path.GetDirectoryName(fileName), language, Path.GetFileName(fileName));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Documentation/XmlDocumentationElement.cs",
    "content": "// Copyright (c) 2009-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading;\nusing System.Xml.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.Documentation\n{\n\t/// <summary>\n\t/// Represents an element in the XML documentation.\n\t/// Any occurrences of \"&lt;inheritdoc/>\" are replaced with the inherited documentation.\n\t/// </summary>\n\tpublic class XmlDocumentationElement\n\t{\n\t\treadonly XElement? element;\n\t\treadonly IEntity? declaringEntity;\n\t\treadonly Func<string, IEntity?>? crefResolver;\n\t\tvolatile string? textContent;\n\n\t\t/// <summary>\n\t\t/// Inheritance level; used to prevent cyclic doc inheritance.\n\t\t/// </summary>\n\t\tint nestingLevel;\n\n\t\t/// <summary>\n\t\t/// Creates a new documentation element.\n\t\t/// </summary>\n\t\tpublic XmlDocumentationElement(XElement element, IEntity? declaringEntity, Func<string, IEntity?>? crefResolver)\n\t\t{\n\t\t\tif (element == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(element));\n\t\t\tthis.element = element;\n\t\t\tthis.declaringEntity = declaringEntity;\n\t\t\tthis.crefResolver = crefResolver;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a new documentation element.\n\t\t/// </summary>\n\t\tpublic XmlDocumentationElement(string text, IEntity? declaringEntity)\n\t\t{\n\t\t\tif (text == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(text));\n\t\t\tthis.declaringEntity = declaringEntity;\n\t\t\tthis.textContent = text;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the entity on which this documentation was originally declared.\n\t\t/// May return null.\n\t\t/// </summary>\n\t\tpublic IEntity? DeclaringEntity {\n\t\t\tget { return declaringEntity; }\n\t\t}\n\n\t\tIEntity? referencedEntity;\n\t\tvolatile bool referencedEntityInitialized;\n\n\t\t/// <summary>\n\t\t/// Gets the entity referenced by the 'cref' attribute.\n\t\t/// May return null.\n\t\t/// </summary>\n\t\tpublic IEntity? ReferencedEntity {\n\t\t\tget {\n\t\t\t\tif (!referencedEntityInitialized)\n\t\t\t\t{\n\t\t\t\t\tstring? cref = GetAttribute(\"cref\");\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!string.IsNullOrEmpty(cref) && crefResolver != null)\n\t\t\t\t\t\t\treferencedEntity = crefResolver(cref!);\n\t\t\t\t\t}\n\t\t\t\t\tcatch\n\t\t\t\t\t{\n\t\t\t\t\t\treferencedEntity = null;\n\t\t\t\t\t}\n\t\t\t\t\treferencedEntityInitialized = true;\n\t\t\t\t}\n\t\t\t\treturn referencedEntity;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the element name.\n\t\t/// </summary>\n\t\tpublic string Name {\n\t\t\tget {\n\t\t\t\treturn element != null ? element.Name.LocalName : string.Empty;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the attribute value.\n\t\t/// </summary>\n\t\tpublic string? GetAttribute(string? name)\n\t\t{\n\t\t\treturn name == null ? null : element?.Attribute(name)?.Value;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this is a pure text node.\n\t\t/// </summary>\n\t\tpublic bool IsTextNode {\n\t\t\tget { return element == null; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the text content.\n\t\t/// </summary>\n\t\tpublic string TextContent {\n\t\t\tget {\n\t\t\t\tif (textContent == null)\n\t\t\t\t{\n\t\t\t\t\tStringBuilder b = new StringBuilder();\n\t\t\t\t\tforeach (var child in this.Children)\n\t\t\t\t\t\tb.Append(child.TextContent);\n\t\t\t\t\ttextContent = b.ToString();\n\t\t\t\t}\n\t\t\t\treturn textContent;\n\t\t\t}\n\t\t}\n\n\t\tIList<XmlDocumentationElement>? children;\n\n\t\t/// <summary>\n\t\t/// Gets the child elements.\n\t\t/// </summary>\n\t\tpublic IList<XmlDocumentationElement> Children {\n\t\t\tget {\n\t\t\t\tif (element == null)\n\t\t\t\t\treturn EmptyList<XmlDocumentationElement>.Instance;\n\t\t\t\treturn LazyInitializer.EnsureInitialized(\n\t\t\t\t\tref this.children,\n\t\t\t\t\t() => CreateElements(element.Nodes(), declaringEntity, crefResolver, nestingLevel))!;\n\t\t\t}\n\t\t}\n\n\t\tstatic readonly string[] doNotInheritIfAlreadyPresent = {\n\t\t\t\"example\", \"exclude\", \"filterpriority\", \"preliminary\", \"summary\",\n\t\t\t\"remarks\", \"returns\", \"threadsafety\", \"value\"\n\t\t};\n\n\t\tstatic List<XmlDocumentationElement> CreateElements(IEnumerable<XObject?> childObjects, IEntity? declaringEntity, Func<string, IEntity?>? crefResolver, int nestingLevel)\n\t\t{\n\t\t\tList<XmlDocumentationElement> list = new List<XmlDocumentationElement>();\n\t\t\tforeach (var child in childObjects)\n\t\t\t{\n\t\t\t\tvar childText = child as XText;\n\t\t\t\tvar childTag = child as XCData;\n\t\t\t\tvar childElement = child as XElement;\n\t\t\t\tif (childText != null)\n\t\t\t\t{\n\t\t\t\t\tlist.Add(new XmlDocumentationElement(childText.Value, declaringEntity));\n\t\t\t\t}\n\t\t\t\telse if (childTag != null)\n\t\t\t\t{\n\t\t\t\t\tlist.Add(new XmlDocumentationElement(childTag.Value, declaringEntity));\n\t\t\t\t}\n\t\t\t\telse if (childElement != null)\n\t\t\t\t{\n\t\t\t\t\tif (nestingLevel < 5 && childElement.Name == \"inheritdoc\")\n\t\t\t\t\t{\n\t\t\t\t\t\tstring? cref = childElement.Attribute(\"cref\")?.Value;\n\t\t\t\t\t\tIEntity? inheritedFrom = null;\n\t\t\t\t\t\tstring? inheritedDocumentation = null;\n\t\t\t\t\t\tif (cref != null && crefResolver != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tinheritedFrom = crefResolver(cref);\n\t\t\t\t\t\t\tif (inheritedFrom != null)\n\t\t\t\t\t\t\t\tinheritedDocumentation = \"<doc>\" + inheritedFrom.GetDocumentation() + \"</doc>\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (declaringEntity != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tforeach (IMember baseMember in InheritanceHelper.GetBaseMembers((IMember)declaringEntity, includeImplementedInterfaces: true))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tinheritedDocumentation = baseMember.GetDocumentation();\n\t\t\t\t\t\t\t\tif (inheritedDocumentation != null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tinheritedFrom = baseMember;\n\t\t\t\t\t\t\t\t\tinheritedDocumentation = \"<doc>\" + inheritedDocumentation + \"</doc>\";\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (inheritedDocumentation != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar doc = XDocument.Parse(inheritedDocumentation).Element(\"doc\");\n\n\t\t\t\t\t\t\t// XPath filter not yet implemented\n\t\t\t\t\t\t\tif (doc != null && childElement.Parent?.Parent == null && childElement.Attribute(\"select\")?.Value == null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// Inheriting documentation at the root level\n\t\t\t\t\t\t\t\tList<string> doNotInherit = new List<string>();\n\t\t\t\t\t\t\t\tdoNotInherit.Add(\"overloads\");\n\t\t\t\t\t\t\t\tdoNotInherit.AddRange(childObjects.OfType<XElement>().Select(e => e.Name.LocalName).Intersect(\n\t\t\t\t\t\t\t\t\tdoNotInheritIfAlreadyPresent));\n\n\t\t\t\t\t\t\t\tvar inheritedChildren = doc.Nodes().Where(\n\t\t\t\t\t\t\t\t\tinheritedObject => {\n\t\t\t\t\t\t\t\t\t\tXElement? inheritedElement = inheritedObject as XElement;\n\t\t\t\t\t\t\t\t\t\treturn !(inheritedElement != null && doNotInherit.Contains(inheritedElement.Name.LocalName));\n\t\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\tlist.AddRange(CreateElements(inheritedChildren, inheritedFrom, crefResolver, nestingLevel + 1));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tlist.Add(new XmlDocumentationElement(childElement, declaringEntity, crefResolver) { nestingLevel = nestingLevel });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (list.Count > 0 && list[0].IsTextNode)\n\t\t\t{\n\t\t\t\tif (string.IsNullOrWhiteSpace(list[0].textContent))\n\t\t\t\t\tlist.RemoveAt(0);\n\t\t\t\telse\n\t\t\t\t\tlist[0].textContent = list[0].textContent!.TrimStart();\n\t\t\t}\n\t\t\tif (list.Count > 0 && list[list.Count - 1].IsTextNode)\n\t\t\t{\n\t\t\t\tif (string.IsNullOrWhiteSpace(list[list.Count - 1].textContent))\n\t\t\t\t\tlist.RemoveAt(list.Count - 1);\n\t\t\t\telse\n\t\t\t\t\tlist[list.Count - 1].textContent = list[list.Count - 1].textContent!.TrimEnd();\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\t/// <inheritdoc/>\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tif (element != null)\n\t\t\t\treturn \"<\" + element.Name + \">\";\n\t\t\telse\n\t\t\t\treturn this.TextContent;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Documentation/XmlDocumentationProvider.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Runtime.Serialization;\nusing System.Text;\nusing System.Xml;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.Documentation\n{\n\t/// <summary>\n\t/// Provides XML documentation for type and member definitions in source code.\n\t/// </summary>\n\tpublic interface IDocumentationProvider\n\t{\n\t\t/// <summary>\n\t\t/// Returns the XML documentation for the given <paramref name=\"entity\"/>.\n\t\t/// May return null, if no documentation is present for the entity.\n\t\t/// </summary>\n\t\t/// <exception cref=\"ArgumentNullException\"><paramref name=\"entity\"/> is null.</exception>\n\t\tstring GetDocumentation(IEntity entity);\n\t}\n\n\t/// <summary>\n\t/// Provides documentation from an .xml file (as generated by the Microsoft C# compiler).\n\t/// </summary>\n\t/// <remarks>\n\t/// This class first creates an in-memory index of the .xml file, and then uses that to read only the requested members.\n\t/// This way, we avoid keeping all the documentation in memory.\n\t/// The .xml file is only opened when necessary, the file handle is not kept open all the time.\n\t/// If the .xml file is changed, the index will automatically be recreated.\n\t/// </remarks>\n\t[Serializable]\n\tpublic class XmlDocumentationProvider : IDeserializationCallback, IDocumentationProvider\n\t{\n\t\t#region Cache\n\t\tsealed class XmlDocumentationCache\n\t\t{\n\t\t\treadonly KeyValuePair<string, string>[] entries;\n\t\t\tint pos;\n\n\t\t\tpublic XmlDocumentationCache(int size = 50)\n\t\t\t{\n\t\t\t\tif (size <= 0)\n\t\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(size), size, \"Value must be positive\");\n\t\t\t\tthis.entries = new KeyValuePair<string, string>[size];\n\t\t\t}\n\n\t\t\tinternal bool TryGet(string key, out string value)\n\t\t\t{\n\t\t\t\tforeach (var pair in entries)\n\t\t\t\t{\n\t\t\t\t\tif (pair.Key == key)\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue = pair.Value;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvalue = null;\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tinternal void Add(string key, string value)\n\t\t\t{\n\t\t\t\tentries[pos++] = new KeyValuePair<string, string>(key, value);\n\t\t\t\tif (pos == entries.Length)\n\t\t\t\t\tpos = 0;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t[Serializable]\n\t\tstruct IndexEntry : IComparable<IndexEntry>\n\t\t{\n\t\t\t/// <summary>\n\t\t\t/// Hash code of the documentation tag\n\t\t\t/// </summary>\n\t\t\tinternal readonly int HashCode;\n\n\t\t\t/// <summary>\n\t\t\t/// Position in the .xml file where the documentation starts\n\t\t\t/// </summary>\n\t\t\tinternal readonly int PositionInFile;\n\n\t\t\tinternal IndexEntry(int hashCode, int positionInFile)\n\t\t\t{\n\t\t\t\tthis.HashCode = hashCode;\n\t\t\t\tthis.PositionInFile = positionInFile;\n\t\t\t}\n\n\t\t\tpublic int CompareTo(IndexEntry other)\n\t\t\t{\n\t\t\t\treturn this.HashCode.CompareTo(other.HashCode);\n\t\t\t}\n\t\t}\n\n\t\t[NonSerialized]\n\t\tXmlDocumentationCache cache = new XmlDocumentationCache();\n\n\t\treadonly string fileName;\n\t\treadonly Encoding encoding;\n\t\tvolatile IndexEntry[] index; // SORTED array of index entries\n\n\t\t#region Constructor / Redirection support\n\t\t/// <summary>\n\t\t/// Creates a new XmlDocumentationProvider.\n\t\t/// </summary>\n\t\t/// <param name=\"fileName\">Name of the .xml file.</param>\n\t\t/// <exception cref=\"IOException\">Error reading from XML file (or from redirected file)</exception>\n\t\t/// <exception cref=\"XmlException\">Invalid XML file</exception>\n\t\tpublic XmlDocumentationProvider(string fileName)\n\t\t{\n\t\t\tif (fileName == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(fileName));\n\n\t\t\tusing (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete))\n\t\t\t{\n\t\t\t\tusing (XmlTextReader xmlReader = new XmlTextReader(fs))\n\t\t\t\t{\n\t\t\t\t\txmlReader.XmlResolver = null; // no DTD resolving\n\t\t\t\t\txmlReader.MoveToContent();\n\t\t\t\t\tif (string.IsNullOrEmpty(xmlReader.GetAttribute(\"redirect\")))\n\t\t\t\t\t{\n\t\t\t\t\t\tthis.fileName = fileName;\n\t\t\t\t\t\tthis.encoding = xmlReader.Encoding;\n\t\t\t\t\t\tReadXmlDoc(xmlReader);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tstring redirectionTarget = GetRedirectionTarget(fileName, xmlReader.GetAttribute(\"redirect\"));\n\t\t\t\t\t\tif (redirectionTarget != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tDebug.WriteLine(\"XmlDoc \" + fileName + \" is redirecting to \" + redirectionTarget);\n\t\t\t\t\t\t\tusing (FileStream redirectedFs = new FileStream(redirectionTarget, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tusing (XmlTextReader redirectedXmlReader = new XmlTextReader(redirectedFs))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tredirectedXmlReader.XmlResolver = null; // no DTD resolving\n\t\t\t\t\t\t\t\t\tredirectedXmlReader.MoveToContent();\n\t\t\t\t\t\t\t\t\tthis.fileName = redirectionTarget;\n\t\t\t\t\t\t\t\t\tthis.encoding = redirectedXmlReader.Encoding;\n\t\t\t\t\t\t\t\t\tReadXmlDoc(redirectedXmlReader);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tthrow new XmlException(\"XmlDoc \" + fileName + \" is redirecting to \" + xmlReader.GetAttribute(\"redirect\") + \", but that file was not found.\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic string GetRedirectionTarget(string xmlFileName, string target)\n\t\t{\n\t\t\tstring programFilesDir = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);\n\t\t\tprogramFilesDir = AppendDirectorySeparator(programFilesDir);\n\n\t\t\tstring corSysDir = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();\n\t\t\tcorSysDir = AppendDirectorySeparator(corSysDir);\n\n\t\t\tvar fileName = target.Replace(\"%PROGRAMFILESDIR%\", programFilesDir)\n\t\t\t\t.Replace(\"%CORSYSDIR%\", corSysDir);\n\t\t\tif (!Path.IsPathRooted(fileName))\n\t\t\t\tfileName = Path.Combine(Path.GetDirectoryName(xmlFileName), fileName);\n\t\t\treturn XmlDocLoader.LookupLocalizedXmlDoc(fileName);\n\t\t}\n\n\t\tstatic string AppendDirectorySeparator(string dir)\n\t\t{\n\t\t\tif (dir.EndsWith(\"\\\\\", StringComparison.Ordinal) || dir.EndsWith(\"/\", StringComparison.Ordinal))\n\t\t\t\treturn dir;\n\t\t\telse\n\t\t\t\treturn dir + Path.DirectorySeparatorChar;\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Load / Create Index\n\t\tvoid ReadXmlDoc(XmlTextReader reader)\n\t\t{\n\t\t\t//lastWriteDate = File.GetLastWriteTimeUtc(fileName);\n\t\t\t// Open up a second file stream for the line<->position mapping\n\t\t\tusing (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete))\n\t\t\t{\n\t\t\t\tLinePositionMapper linePosMapper = new LinePositionMapper(fs, encoding);\n\t\t\t\tList<IndexEntry> indexList = new List<IndexEntry>();\n\t\t\t\twhile (reader.Read())\n\t\t\t\t{\n\t\t\t\t\tif (reader.IsStartElement())\n\t\t\t\t\t{\n\t\t\t\t\t\tswitch (reader.LocalName)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase \"members\":\n\t\t\t\t\t\t\t\tReadMembersSection(reader, linePosMapper, indexList);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tindexList.Sort();\n\t\t\t\tthis.index = indexList.ToArray(); // volatile write\n\t\t\t}\n\t\t}\n\n\t\tsealed class LinePositionMapper\n\t\t{\n\t\t\treadonly FileStream fs;\n\t\t\treadonly Decoder decoder;\n\t\t\tint currentLine = 1;\n\t\t\tchar prevChar = '\\0';\n\n\t\t\t// buffers for use with Decoder:\n\t\t\treadonly byte[] input = new byte[1];\n\t\t\treadonly char[] output = new char[2];\n\n\t\t\tpublic LinePositionMapper(FileStream fs, Encoding encoding)\n\t\t\t{\n\t\t\t\tthis.decoder = encoding.GetDecoder();\n\t\t\t\tthis.fs = fs;\n\t\t\t}\n\n\t\t\tpublic int GetPositionForLine(int line)\n\t\t\t{\n\t\t\t\tDebug.Assert(line >= currentLine);\n\t\t\t\twhile (line > currentLine)\n\t\t\t\t{\n\t\t\t\t\tint b = fs.ReadByte();\n\t\t\t\t\tif (b < 0)\n\t\t\t\t\t\tthrow new EndOfStreamException();\n\t\t\t\t\tinput[0] = (byte)b;\n\t\t\t\t\tdecoder.Convert(input, 0, 1, output, 0, output.Length, false, out int bytesUsed, out int charsUsed, out _);\n\t\t\t\t\tDebug.Assert(bytesUsed == 1);\n\t\t\t\t\tif (charsUsed == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tif ((prevChar != '\\r' && output[0] == '\\n') || output[0] == '\\r')\n\t\t\t\t\t\t\tcurrentLine++;\n\t\t\t\t\t\tprevChar = output[0];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn checked((int)fs.Position);\n\t\t\t}\n\t\t}\n\n\t\tstatic void ReadMembersSection(XmlTextReader reader, LinePositionMapper linePosMapper, List<IndexEntry> indexList)\n\t\t{\n\t\t\twhile (reader.Read())\n\t\t\t{\n\t\t\t\tswitch (reader.NodeType)\n\t\t\t\t{\n\t\t\t\t\tcase XmlNodeType.EndElement:\n\t\t\t\t\t\tif (reader.LocalName == \"members\")\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase XmlNodeType.Element:\n\t\t\t\t\t\tif (reader.LocalName == \"member\")\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tint pos = linePosMapper.GetPositionForLine(reader.LineNumber) + Math.Max(reader.LinePosition - 2, 0);\n\t\t\t\t\t\t\tstring memberAttr = reader.GetAttribute(\"name\");\n\t\t\t\t\t\t\tif (memberAttr != null)\n\t\t\t\t\t\t\t\tindexList.Add(new IndexEntry(GetHashCode(memberAttr), pos));\n\t\t\t\t\t\t\treader.Skip();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Hash algorithm used for the index.\n\t\t/// This is a custom implementation so that old index files work correctly\n\t\t/// even when the .NET string.GetHashCode implementation changes\n\t\t/// (e.g. due to .NET 4.5 hash randomization)\n\t\t/// </summary>\n\t\tstatic int GetHashCode(string key)\n\t\t{\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\tint h = 0;\n\t\t\t\tforeach (char c in key)\n\t\t\t\t{\n\t\t\t\t\th = (h << 5) - h + c;\n\t\t\t\t}\n\t\t\t\treturn h;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region GetDocumentation\n\t\t/// <summary>\n\t\t/// Get the documentation for the member with the specified documentation key.\n\t\t/// </summary>\n\t\tpublic string GetDocumentation(string key)\n\t\t{\n\t\t\tif (key == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(key));\n\t\t\treturn GetDocumentation(key, true);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Get the documentation for the specified member.\n\t\t/// </summary>\n\t\tpublic string GetDocumentation(IEntity entity)\n\t\t{\n\t\t\tif (entity == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(entity));\n\t\t\treturn GetDocumentation(entity.GetIdString());\n\t\t}\n\n\t\tstring GetDocumentation(string key, bool allowReload)\n\t\t{\n\t\t\tint hashcode = GetHashCode(key);\n\t\t\tvar index = this.index; // read volatile field\n\t\t\t\t\t\t\t\t\t// index is sorted, so we can use binary search\n\t\t\tint m = Array.BinarySearch(index, new IndexEntry(hashcode, 0));\n\t\t\tif (m < 0)\n\t\t\t\treturn null;\n\t\t\t// correct hash code found.\n\t\t\t// possibly there are multiple items with the same hash, so go to the first.\n\t\t\twhile (--m >= 0 && index[m].HashCode == hashcode)\n\t\t\t\t;\n\t\t\t// m is now 1 before the first item with the correct hash\n\n\t\t\tXmlDocumentationCache cache = this.cache;\n\t\t\tlock (cache)\n\t\t\t{\n\t\t\t\tif (!cache.TryGet(key, out string val))\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\t// go through all items that have the correct hash\n\t\t\t\t\t\twhile (++m < index.Length && index[m].HashCode == hashcode)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tval = LoadDocumentation(key, index[m].PositionInFile);\n\t\t\t\t\t\t\tif (val != null)\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// cache the result (even if it is null)\n\t\t\t\t\t\tcache.Add(key, val);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (IOException)\n\t\t\t\t\t{\n\t\t\t\t\t\t// may happen if the documentation file was deleted/is inaccessible/changed (EndOfStreamException)\n\t\t\t\t\t\treturn allowReload ? ReloadAndGetDocumentation(key) : null;\n\t\t\t\t\t}\n\t\t\t\t\tcatch (XmlException)\n\t\t\t\t\t{\n\t\t\t\t\t\t// may happen if the documentation file was changed so that the file position no longer starts on a valid XML element\n\t\t\t\t\t\treturn allowReload ? ReloadAndGetDocumentation(key) : null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn val;\n\t\t\t}\n\t\t}\n\n\t\tstring ReloadAndGetDocumentation(string key)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// Reload the index\n\t\t\t\tusing (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete))\n\t\t\t\t{\n\t\t\t\t\tusing (XmlTextReader xmlReader = new XmlTextReader(fs))\n\t\t\t\t\t{\n\t\t\t\t\t\txmlReader.XmlResolver = null; // no DTD resolving\n\t\t\t\t\t\txmlReader.MoveToContent();\n\t\t\t\t\t\tReadXmlDoc(xmlReader);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (IOException)\n\t\t\t{\n\t\t\t\t// Ignore errors on reload; IEntity.Documentation callers aren't prepared to handle exceptions\n\t\t\t\tthis.index = Empty<IndexEntry>.Array; // clear index to avoid future load attempts\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tcatch (XmlException)\n\t\t\t{\n\t\t\t\tthis.index = Empty<IndexEntry>.Array; // clear index to avoid future load attempts\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn GetDocumentation(key, allowReload: false); // prevent infinite reload loops\n\t\t}\n\t\t#endregion\n\n\t\t#region Load / Read XML\n\t\tstring LoadDocumentation(string key, int positionInFile)\n\t\t{\n\t\t\tusing (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete))\n\t\t\t{\n\t\t\t\tfs.Position = positionInFile;\n\t\t\t\tvar context = new XmlParserContext(null, null, null, XmlSpace.None) { Encoding = encoding };\n\t\t\t\tusing (XmlTextReader r = new XmlTextReader(fs, XmlNodeType.Element, context))\n\t\t\t\t{\n\t\t\t\t\tr.XmlResolver = null; // no DTD resolving\n\t\t\t\t\twhile (r.Read())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (r.NodeType == XmlNodeType.Element)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstring memberAttr = r.GetAttribute(\"name\");\n\t\t\t\t\t\t\tif (memberAttr == key)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn r.ReadInnerXml();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic virtual void OnDeserialization(object sender)\n\t\t{\n\t\t\tcache = new XmlDocumentationCache();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/FlowAnalysis/ControlFlowNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.FlowAnalysis\n{\n\t/// <summary>\n\t/// Represents a block in the control flow graph.\n\t/// </summary>\n\t[DebuggerDisplay(\"CFG UserIndex={UserIndex}, UserData={UserData}\")]\n\tpublic class ControlFlowNode\n\t{\n\t\t/// <summary>\n\t\t/// User index, can be used to look up additional information in an array.\n\t\t/// </summary>\n\t\tpublic int UserIndex;\n\n\t\t/// <summary>\n\t\t/// User data.\n\t\t/// </summary>\n\t\tpublic object UserData;\n\n\t\t/// <summary>\n\t\t/// Visited flag, used in various algorithms.\n\t\t/// </summary>\n\t\tpublic bool Visited;\n\n\t\t/// <summary>\n\t\t/// Gets the node index in a post-order traversal of the control flow graph, starting at the\n\t\t/// entry point. This field gets computed by dominance analysis.\n\t\t/// </summary>\n\t\tpublic int PostOrderNumber;\n\n\t\t/// <summary>\n\t\t/// Gets whether this node is reachable. Requires that dominance is computed!\n\t\t/// </summary>\n\t\tpublic bool IsReachable {\n\t\t\tget { return DominatorTreeChildren != null; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the immediate dominator (the parent in the dominator tree).\n\t\t/// Null if dominance has not been calculated; or if the node is unreachable.\n\t\t/// </summary>\n\t\tpublic ControlFlowNode ImmediateDominator { get; internal set; }\n\n\t\t/// <summary>\n\t\t/// List of children in the dominator tree.\n\t\t/// Null if dominance has not been calculated; or if the node is unreachable.\n\t\t/// </summary>\n\t\tpublic List<ControlFlowNode> DominatorTreeChildren { get; internal set; }\n\n\t\t/// <summary>\n\t\t/// List of incoming control flow edges.\n\t\t/// </summary>\n\t\tpublic readonly List<ControlFlowNode> Predecessors = new List<ControlFlowNode>();\n\n\t\t/// <summary>\n\t\t/// List of outgoing control flow edges.\n\t\t/// </summary>\n\t\tpublic readonly List<ControlFlowNode> Successors = new List<ControlFlowNode>();\n\n\t\tpublic void AddEdgeTo(ControlFlowNode target)\n\t\t{\n\t\t\tthis.Successors.Add(target);\n\t\t\ttarget.Predecessors.Add(this);\n\t\t}\n\n\t\tpublic void TraversePreOrder(Func<ControlFlowNode, IEnumerable<ControlFlowNode>> children, Action<ControlFlowNode> visitAction)\n\t\t{\n\t\t\tGraphTraversal.DepthFirstSearch(new[] { this }, Visit, children);\n\n\t\t\tbool Visit(ControlFlowNode node)\n\t\t\t{\n\t\t\t\tif (node.Visited)\n\t\t\t\t\treturn false;\n\t\t\t\tnode.Visited = true;\n\t\t\t\tvisitAction(node);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tpublic void TraversePostOrder(Func<ControlFlowNode, IEnumerable<ControlFlowNode>> children, Action<ControlFlowNode> visitAction)\n\t\t{\n\t\t\tGraphTraversal.DepthFirstSearch(new[] { this }, Visit, children, postorderAction: visitAction);\n\n\t\t\tbool Visit(ControlFlowNode node)\n\t\t\t{\n\t\t\t\tif (node.Visited)\n\t\t\t\t\treturn false;\n\t\t\t\tnode.Visited = true;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether <c>this</c> dominates <paramref name=\"node\"/>.\n\t\t/// </summary>\n\t\tpublic bool Dominates(ControlFlowNode node)\n\t\t{\n\t\t\t// TODO: this can be made O(1) by numbering the dominator tree\n\t\t\tControlFlowNode tmp = node;\n\t\t\twhile (tmp != null)\n\t\t\t{\n\t\t\t\tif (tmp == this)\n\t\t\t\t\treturn true;\n\t\t\t\ttmp = tmp.ImmediateDominator;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/FlowAnalysis/DataFlowVisitor.cs",
    "content": "// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\n\nusing ICSharpCode.Decompiler.IL;\n\nnamespace ICSharpCode.Decompiler.FlowAnalysis\n{\n\t/// <summary>\n\t/// Interface for use with DataFlowVisitor.\n\t/// \n\t/// A mutable container for the state tracked by the data flow analysis.\n\t/// </summary>\n\t/// <remarks>\n\t/// States must form a join-semilattice: https://en.wikipedia.org/wiki/Semilattice\n\t/// \n\t/// To handle <c>try{} finally{}</c> properly, states should implement <c>MeetWith()</c> as well,\n\t/// and thus should form a lattice.\n\t/// \n\t/// <c>DataFlowVisitor</c> expects the state to behave like a mutable reference type.\n\t/// It might still be a good idea to use a struct to implement it so that .NET uses static dispatch for\n\t/// method calls on the type parameter, but that struct must consist only of a <c>readonly</c> field\n\t/// referencing some mutable object, to ensure the type parameter behaves as it if was a mutable reference type.\n\t/// </remarks>\n\tpublic interface IDataFlowState<Self> where Self : IDataFlowState<Self>\n\t{\n\t\t/// <summary>\n\t\t/// Gets whether this state is \"less than\" (or equal to) another state.\n\t\t/// This is the partial order of the semi-lattice.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// The exact meaning of this relation is up to the concrete implementation,\n\t\t/// but usually \"less than\" means \"has less information than\".\n\t\t/// A given position in the code starts at the \"bottom state\" (=no information)\n\t\t/// and then adds more information as the analysis progresses.\n\t\t/// After each change to the state, the old state must be less than the new state,\n\t\t/// so that the analysis does not run into an infinite loop.\n\t\t/// The partially ordered set must also have finite height (no infinite ascending chains s1 &lt; s2 &lt; ...),\n\t\t/// to ensure the analysis terminates.\n\t\t/// </remarks>\n\t\t/// <example>\n\t\t/// The simplest possible non-trivial state, <c>bool isReachable</c>, would implement <c>LessThanOrEqual</c> as:\n\t\t/// <code>return (this.isReachable ? 1 : 0) &lt;= (otherState.isReachable ? 1 : 0);</code>\n\t\t/// <para>Which can be simpified to:</para>\n\t\t/// <code>return !this.isReachable || otherState.isReachable;</code>\n\t\t/// </example>\n\t\tbool LessThanOrEqual(Self otherState);\n\n\t\t/// <summary>\n\t\t/// Creates a new object with a copy of the state.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Mutating methods such as <c>ReplaceWith</c> or <c>JoinWith</c> modify the contents of a state object.\n\t\t/// Cloning the object allows the analysis to track multiple independent states,\n\t\t/// such as the\n\t\t/// </remarks>\n\t\t/// <example>\n\t\t/// The simple state \"<c>bool isReachable</c>\", would implement <c>Clone</c> as:\n\t\t/// <code>return new MyState(this.isReachable);</code>\n\t\t/// </example>\n\t\tSelf Clone();\n\n\t\t/// <summary>\n\t\t/// Replace the contents of this state object with a copy of those in <paramref name=\"newContent\"/>.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// <c>x = x.Clone(); x.ReplaceWith(newContent);</c>\n\t\t/// is equivalent to\n\t\t/// <c>x = newContent.Clone();</c>\n\t\t/// \n\t\t/// ReplaceWith() is used to avoid allocating new state objects where possible.\n\t\t/// </remarks>\n\t\t/// <example>\n\t\t/// The simple state \"<c>bool isReachable</c>\", would implement <c>ReplaceWith</c> as:\n\t\t/// <code>this.isReachable = newContent.isReachable;</code>\n\t\t/// </example>\n\t\tvoid ReplaceWith(Self newContent);\n\n\t\t/// <summary>\n\t\t/// Join the incomingState into this state.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Postcondition: <c>old(this).LessThanOrEqual(this) &amp;&amp; incomingState.LessThanOrEqual(this)</c>\n\t\t/// This method should set <c>this</c> to the smallest state that is greater than (or equal to)\n\t\t/// both input states.\n\t\t/// \n\t\t/// <c>JoinWith()</c> is used when multiple control flow paths are joined together.\n\t\t/// For example, it is used to combine the <c>thenState</c> with the <c>elseState</c>\n\t\t/// at the end of a if-else construct.\n\t\t/// </remarks>\n\t\t/// <example>\n\t\t/// The simple state \"<c>bool isReachable</c>\", would implement <c>JoinWith</c> as:\n\t\t/// <code>this.isReachable |= incomingState.isReachable;</code>\n\t\t/// </example>\n\t\tvoid JoinWith(Self incomingState);\n\n\t\t/// <summary>\n\t\t/// A special operation to merge the end-state of the finally-block with the end state of\n\t\t/// a branch leaving the try-block.\n\t\t/// \n\t\t/// If either input state is unreachable, this call must result in an unreachable state.\n\t\t/// </summary>\n\t\t/// <example>\n\t\t/// The simple state \"<c>bool isReachable</c>\", would implement <c>TriggerFinally</c> as:\n\t\t/// <code>this.isReachable &amp;= finallyState.isReachable;</code>\n\t\t/// </example>\n\t\tvoid TriggerFinally(Self finallyState);\n\n\t\t/// <summary>\n\t\t/// Gets whether this is the bottom state.\n\t\t/// \n\t\t/// The bottom state represents that the data flow analysis has not yet\n\t\t/// found a code path from the entry point to this state's position.\n\t\t/// It thus contains no information, and is \"less than\" all other states.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// The bottom state is the bottom element in the semi-lattice.\n\t\t/// \n\t\t/// Initially, all code blocks not yet visited by the analysis will be in the bottom state.\n\t\t/// Unreachable code will always remain in the bottom state.\n\t\t/// Some analyses may also use the bottom state for reachable code after it was processed by the analysis.\n\t\t/// For example, in <c>DefiniteAssignmentVisitor</c> the bottom states means\n\t\t/// \"either this code is unreachable, or all variables are definitely initialized\".\n\t\t/// </remarks>\n\t\t/// <example>\n\t\t/// The simple state \"<c>bool isReachable</c>\", would implement <c>IsBottom</c> as:\n\t\t/// <code>return !this.isReachable;</code>\n\t\t/// </example>\n\t\tbool IsBottom { get; }\n\n\t\t/// <summary>\n\t\t/// Equivalent to <c>this.ReplaceWith(bottomState)</c>, but may be implemented more efficiently.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Since the <c>DataFlowVisitor</c> can only create states by cloning from the initial state,\n\t\t/// this method is necessary for the <c>DataFlowVisitor</c> to gain access to the bottom element in\n\t\t/// the first place.\n\t\t/// </remarks>\n\t\t/// <example>\n\t\t/// The simple state \"<c>bool isReachable</c>\", would implement <c>ReplaceWithBottom</c> as:\n\t\t/// <code>this.isReachable = false;</code>\n\t\t/// </example>\n\t\tvoid ReplaceWithBottom();\n\t}\n\n\t/// <summary>\n\t/// Generic base class for forward data flow analyses.\n\t/// </summary>\n\t/// <typeparam name=\"State\">\n\t/// The state type used for the data flow analysis. See <see cref=\"IDataFlowState{Self}\"/> for details.\n\t/// </typeparam>\n\tpublic abstract class DataFlowVisitor<State> : ILVisitor\n\t\twhere State : IDataFlowState<State>\n\t{\n\t\t// The data flow analysis tracks a 'state'.\n\t\t// There are many states (one per source code position, i.e. ILInstruction), but we don't store all of them.\n\t\t// We only keep track of:\n\t\t//  a) the current state in the RDVisitor\n\t\t//     This state corresponds to the instruction currently being visited,\n\t\t//     and gets mutated as we traverse the ILAst.\n\t\t//  b) the input state for each control flow node\n\t\t//     These also gets mutated as the analysis learns about new control flow edges.\n\n\t\t/// <summary>\n\t\t/// The bottom state.\n\t\t/// Must not be mutated.\n\t\t/// </summary>\n\t\tState bottomState;\n\n\t\t/// <summary>\n\t\t/// Current state.\n\t\t/// \n\t\t/// Caution: any state object assigned to this member gets mutated as the visitor traverses the ILAst!\n\t\t/// </summary>\n\t\tprotected State state;\n\n\t\t/// <summary>\n\t\t/// Combined state of all possible exceptional control flow paths in the current try block.\n\t\t/// Serves as input state for catch blocks.\n\t\t/// \n\t\t/// Caution: any state object assigned to this member gets mutated as the visitor encounters instructions that may throw exceptions!\n\t\t/// \n\t\t/// Within a try block, <c>currentStateOnException == stateOnException[tryBlock.Parent]</c>.\n\t\t/// </summary>\n\t\t/// <seealso cref=\"PropagateStateOnException\"/>\n\t\tprotected State currentStateOnException;\n\n\t\tbool initialized;\n\n\t\t/// <summary>\n\t\t/// Initializes the DataFlowVisitor.\n\t\t/// This method must be called once before any Visit()-methods can be called.\n\t\t/// It must not be called more than once.\n\t\t/// </summary>\n\t\t/// <param name=\"initialState\">The initial state at the entry point of the analysis.</param>\n\t\t/// <remarks>\n\t\t/// This is a method instead of a constructor because derived classes might need complex initialization\n\t\t/// before they can construct the initial state.\n\t\t/// </remarks>\n\t\tprotected void Initialize(State initialState)\n\t\t{\n\t\t\tDebug.Assert(!initialized);\n\t\t\tinitialized = true;\n\t\t\tthis.state = initialState.Clone();\n\t\t\tthis.bottomState = initialState.Clone();\n\t\t\tthis.bottomState.ReplaceWithBottom();\n\t\t\tDebug.Assert(bottomState.IsBottom);\n\t\t\tthis.stateOnNullableRewrap = bottomState.Clone();\n\t\t\tthis.currentStateOnException = state.Clone();\n\t\t}\n\n#if DEBUG\n\t\t// For debugging, capture the input + output state at every instruction.\n\t\treadonly Dictionary<ILInstruction, State> debugInputState = new Dictionary<ILInstruction, State>();\n\t\treadonly Dictionary<ILInstruction, State> debugOutputState = new Dictionary<ILInstruction, State>();\n\n\t\tvoid DebugPoint(Dictionary<ILInstruction, State> debugDict, ILInstruction inst)\n\t\t{\n#if DEBUG\n\t\t\tDebug.Assert(initialized, \"Initialize() was not called\");\n\n\t\t\tif (debugDict.TryGetValue(inst, out State previousState))\n\t\t\t{\n\t\t\t\tDebug.Assert(previousState.LessThanOrEqual(state));\n\t\t\t\tpreviousState.JoinWith(state);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// limit the number of tracked instructions to make memory usage in debug builds less horrible\n\t\t\t\tif (debugDict.Count < 1000)\n\t\t\t\t{\n\t\t\t\t\tdebugDict.Add(inst, state.Clone());\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// currentStateOnException should be all states within the try block joined together\n\t\t\t// -> state should already have been joined into currentStateOnException.\n\t\t\tDebug.Assert(state.LessThanOrEqual(currentStateOnException));\n#endif\n\t\t}\n#endif\n\n\t\t[Conditional(\"DEBUG\")]\n\t\tprotected void DebugStartPoint(ILInstruction inst)\n\t\t{\n#if DEBUG\n\t\t\tDebugPoint(debugInputState, inst);\n#endif\n\t\t}\n\n\t\t[Conditional(\"DEBUG\")]\n\t\tprotected void DebugEndPoint(ILInstruction inst)\n\t\t{\n#if DEBUG\n\t\t\tDebugPoint(debugOutputState, inst);\n#endif\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Derived classes may add to this set of flags to ensure they don't forget to override an interesting method.\n\t\t/// </summary>\n\t\tprotected InstructionFlags flagsRequiringManualImpl = InstructionFlags.ControlFlow | InstructionFlags.MayBranch | InstructionFlags.MayUnwrapNull | InstructionFlags.EndPointUnreachable;\n\n\t\tprotected sealed override void Default(ILInstruction inst)\n\t\t{\n\t\t\tDebugStartPoint(inst);\n\t\t\t// This method assumes normal control flow and no branches.\n\t\t\tif ((inst.DirectFlags & flagsRequiringManualImpl) != 0)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException(GetType().Name + \" is missing implementation for \" + inst.GetType().Name);\n\t\t\t}\n\n\t\t\t// Since this instruction has normal control flow, we can evaluate our children left-to-right.\n\t\t\tforeach (var child in inst.Children)\n\t\t\t{\n\t\t\t\tchild.AcceptVisitor(this);\n\t\t\t\tDebug.Assert(state.IsBottom || !child.HasFlag(InstructionFlags.EndPointUnreachable),\n\t\t\t\t\t\t\t \"Unreachable code must be in the bottom state.\");\n\t\t\t}\n\n\t\t\tDebugEndPoint(inst);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Handle control flow when the current instruction throws an exception:\n\t\t/// joins the current state into the \"exception state\" of the current try block.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This should not only be called for instructions that may throw an exception,\n\t\t/// but for all instructions (due to async exceptions like ThreadAbortException)!\n\t\t/// \n\t\t/// To avoid redundant calls, every Visit() call may assume that the current state\n\t\t/// is already propagated, and has to guarantee the same at the end.\n\t\t/// This means this method should be called after every state change.\n\t\t/// Alternatively, derived classes may directly modify both <c>state</c>\n\t\t/// and <c>currentStateOnException</c>, so that a full <c>JoinWith()</c> call\n\t\t/// is not necessary.\n\t\t/// </remarks>\n\t\tprotected void PropagateStateOnException()\n\t\t{\n\t\t\tcurrentStateOnException.JoinWith(state);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Replace the current state with the bottom state.\n\t\t/// </summary>\n\t\tprotected void MarkUnreachable()\n\t\t{\n\t\t\tstate.ReplaceWithBottom();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Holds the state for incoming branches.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Only used for blocks in block containers; not for inline blocks.\n\t\t/// </remarks>\n\t\treadonly Dictionary<Block, State> stateOnBranch = new Dictionary<Block, State>();\n\n\t\t/// <summary>\n\t\t/// Holds the state at the block container end-point. (=state for incoming 'leave' instructions)\n\t\t/// </summary>\n\t\treadonly Dictionary<BlockContainer, State> stateOnLeave = new Dictionary<BlockContainer, State>();\n\n\t\t/// <summary>\n\t\t/// Gets the state object that holds the state for incoming branches to the block.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Returns the a clone of the bottom state on the first call for a given block,\n\t\t/// then returns the same object instance on further calls.\n\t\t/// The caller is expected to mutate the returned state by calling <c>JoinWith()</c>.\n\t\t/// </remarks>\n\t\tState GetBlockInputState(Block block)\n\t\t{\n\t\t\tif (stateOnBranch.TryGetValue(block, out State s))\n\t\t\t{\n\t\t\t\treturn s;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ts = bottomState.Clone();\n\t\t\t\tstateOnBranch.Add(block, s);\n\t\t\t\treturn s;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// For each block container, stores the set of blocks (via Block.ChildIndex)\n\t\t/// that had their incoming state changed and were not processed yet.\n\t\t/// </summary>\n\t\treadonly Dictionary<BlockContainer, SortedSet<int>> workLists = new Dictionary<BlockContainer, SortedSet<int>>();\n\n\t\tprotected internal override void VisitBlockContainer(BlockContainer container)\n\t\t{\n\t\t\tDebugStartPoint(container);\n\t\t\tSortedSet<int> worklist = new SortedSet<int>();\n\t\t\t// register work list so that branches within this container can add to it\n\t\t\tworkLists.Add(container, worklist);\n\t\t\tvar stateOnEntry = GetBlockInputState(container.EntryPoint);\n\t\t\tif (!state.LessThanOrEqual(stateOnEntry))\n\t\t\t{\n\t\t\t\t// If we have new information for the container's entry point,\n\t\t\t\t// add the container entry point to the work list.\n\t\t\t\tstateOnEntry.JoinWith(state);\n\t\t\t\tworklist.Add(0);\n\t\t\t}\n\n\t\t\t// To handle loops, we need to analyze the loop body before we can know the state for the loop backedge,\n\t\t\t// but we need to know the input state for the loop body (to which the backedge state contributes)\n\t\t\t// before we can analyze the loop body.\n\t\t\t// Solution: we repeat the analysis of the loop body multiple times, until the state no longer changes.\n\t\t\t// To make it terminate reasonably quickly, we need to process the control flow nodes in the correct order:\n\t\t\t// reverse post-order. We use a SortedSet<int> for this, and assume that the block indices used in the SortedSet\n\t\t\t// are ordered appropriately. The caller can use BlockContainer.SortBlocks() for this.\n\t\t\twhile (worklist.Count > 0)\n\t\t\t{\n\t\t\t\tint blockIndex = worklist.Min;\n\t\t\t\tworklist.Remove(blockIndex);\n\t\t\t\tBlock block = container.Blocks[blockIndex];\n\t\t\t\tstate.ReplaceWith(stateOnBranch[block]);\n\t\t\t\tblock.AcceptVisitor(this);\n\t\t\t}\n\t\t\tif (stateOnLeave.TryGetValue(container, out State stateOnExit))\n\t\t\t{\n\t\t\t\tstate.ReplaceWith(stateOnExit);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tMarkUnreachable();\n\t\t\t}\n\t\t\tDebugEndPoint(container);\n\t\t\tworkLists.Remove(container);\n\t\t}\n\n\t\treadonly List<(IBranchOrLeaveInstruction, State)> branchesTriggeringFinally = new List<(IBranchOrLeaveInstruction, State)>();\n\n\t\tprotected internal override void VisitBranch(Branch inst)\n\t\t{\n\t\t\tif (inst.TriggersFinallyBlock)\n\t\t\t{\n\t\t\t\tDebug.Assert(state.LessThanOrEqual(currentStateOnException));\n\t\t\t\tbranchesTriggeringFinally.Add((inst, state.Clone()));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tMergeBranchStateIntoTargetBlock(inst, state);\n\t\t\t}\n\t\t\tMarkUnreachable();\n\t\t}\n\n\t\tvoid MergeBranchStateIntoTargetBlock(Branch inst, State branchState)\n\t\t{\n\t\t\tvar targetBlock = inst.TargetBlock;\n\t\t\tvar targetState = GetBlockInputState(targetBlock);\n\t\t\tif (!branchState.LessThanOrEqual(targetState))\n\t\t\t{\n\t\t\t\ttargetState.JoinWith(branchState);\n\n\t\t\t\tBlockContainer container = (BlockContainer)targetBlock.Parent;\n\t\t\t\tif (workLists.TryGetValue(container, out var workList))\n\t\t\t\t{\n\t\t\t\t\tworkList.Add(targetBlock.ChildIndex);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tDebug.Fail(\"Failed to find target BlockContainer\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void VisitLeave(Leave inst)\n\t\t{\n\t\t\tinst.Value.AcceptVisitor(this);\n\t\t\tif (inst.TriggersFinallyBlock)\n\t\t\t{\n\t\t\t\tDebug.Assert(state.LessThanOrEqual(currentStateOnException));\n\t\t\t\tbranchesTriggeringFinally.Add((inst, state.Clone()));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tMergeBranchStateIntoStateOnLeave(inst, state);\n\t\t\t}\n\t\t\tMarkUnreachable();\n\t\t}\n\n\t\tvoid MergeBranchStateIntoStateOnLeave(Leave inst, State branchState)\n\t\t{\n\t\t\tif (stateOnLeave.TryGetValue(inst.TargetContainer, out State targetState))\n\t\t\t{\n\t\t\t\ttargetState.JoinWith(branchState);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tstateOnLeave.Add(inst.TargetContainer, branchState.Clone());\n\t\t\t}\n\t\t\t// Note: We don't have to put the block container onto the work queue,\n\t\t\t// because it's an ancestor of the Leave instruction, and hence\n\t\t\t// we are currently somewhere within the VisitBlockContainer() call.\n\t\t}\n\n\t\tprotected internal override void VisitThrow(Throw inst)\n\t\t{\n\t\t\tinst.Argument.AcceptVisitor(this);\n\t\t\tMarkUnreachable();\n\t\t}\n\n\t\tprotected internal override void VisitRethrow(Rethrow inst)\n\t\t{\n\t\t\tMarkUnreachable();\n\t\t}\n\n\t\tprotected internal override void VisitInvalidBranch(InvalidBranch inst)\n\t\t{\n\t\t\tMarkUnreachable();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Stores the stateOnException per try instruction.\n\t\t/// </summary>\n\t\treadonly Dictionary<TryInstruction, State> stateOnException = new Dictionary<TryInstruction, State>();\n\n\t\t/// <summary>\n\t\t/// Visits the TryBlock.\n\t\t/// \n\t\t/// Returns a new State object representing the exceptional control flow transfer out of the try block.\n\t\t/// </summary>\n\t\tprotected State HandleTryBlock(TryInstruction inst)\n\t\t{\n\t\t\tState oldStateOnException = currentStateOnException;\n\t\t\tif (stateOnException.TryGetValue(inst, out State newStateOnException))\n\t\t\t{\n\t\t\t\tnewStateOnException.JoinWith(state);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tnewStateOnException = state.Clone();\n\t\t\t\tstateOnException.Add(inst, newStateOnException);\n\t\t\t}\n\n\t\t\tcurrentStateOnException = newStateOnException;\n\t\t\tinst.TryBlock.AcceptVisitor(this);\n\t\t\t// swap back to the old object instance\n\t\t\tcurrentStateOnException = oldStateOnException;\n\n\t\t\t// No matter what kind of try-instruction this is, it's possible\n\t\t\t// that an async exception is thrown immediately in the handler block,\n\t\t\t// so propagate the state:\n\t\t\toldStateOnException.JoinWith(newStateOnException);\n\n\t\t\t// Return a copy, so that the caller mutating the returned state\n\t\t\t// does not influence the 'stateOnException' dict\n\t\t\treturn newStateOnException.Clone();\n\t\t}\n\n\t\tprotected internal override void VisitTryCatch(TryCatch inst)\n\t\t{\n\t\t\tDebugStartPoint(inst);\n\t\t\tState onException = HandleTryBlock(inst);\n\t\t\tState endpoint = state.Clone();\n\t\t\tforeach (var handler in inst.Handlers)\n\t\t\t{\n\t\t\t\tstate.ReplaceWith(onException);\n\t\t\t\tBeginTryCatchHandler(handler);\n\t\t\t\thandler.Filter.AcceptVisitor(this);\n\t\t\t\t// if the filter return false, any mutations done by the filter\n\t\t\t\t// will be visible by the remaining handlers\n\t\t\t\t// (but it's also possible that the filter didn't get executed at all\n\t\t\t\t// because the exception type doesn't match)\n\t\t\t\tonException.JoinWith(state);\n\n\t\t\t\thandler.Body.AcceptVisitor(this);\n\t\t\t\tendpoint.JoinWith(state);\n\t\t\t}\n\t\t\tstate = endpoint;\n\t\t\tDebugEndPoint(inst);\n\t\t}\n\n\t\tprotected virtual void BeginTryCatchHandler(TryCatchHandler inst)\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// TryCatchHandler is handled directly in VisitTryCatch\n\t\t/// </summary>\n\t\tprotected internal override sealed void VisitTryCatchHandler(TryCatchHandler inst)\n\t\t{\n\t\t\tthrow new NotSupportedException();\n\t\t}\n\n\t\tprotected internal override void VisitTryFinally(TryFinally inst)\n\t\t{\n\t\t\tDebugStartPoint(inst);\n\t\t\tint branchesTriggeringFinallyOldCount = branchesTriggeringFinally.Count;\n\t\t\t// At first, handle 'try { .. } finally { .. }' like 'try { .. } catch {} .. if (?) rethrow; }'\n\t\t\tState onException = HandleTryBlock(inst);\n\t\t\tState onSuccess = state.Clone();\n\t\t\tstate.JoinWith(onException);\n\t\t\tinst.FinallyBlock.AcceptVisitor(this);\n\t\t\t//PropagateStateOnException(); // rethrow the exception after the finally block -- should be redundant\n\t\t\tDebug.Assert(state.LessThanOrEqual(currentStateOnException));\n\n\t\t\tProcessBranchesLeavingTryFinally(inst, branchesTriggeringFinallyOldCount);\n\n\t\t\t// Use TriggerFinally() to ensure points after the try-finally are reachable only if both the\n\t\t\t// try and the finally endpoints are reachable.\n\t\t\tonSuccess.TriggerFinally(state);\n\t\t\tstate = onSuccess;\n\t\t\tDebugEndPoint(inst);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Process branches leaving the try-finally,\n\t\t///  * Calls TriggerFinally() on each branchesTriggeringFinally\n\t\t///  * Removes entries from branchesTriggeringFinally if they won't trigger additional finally blocks.\n\t\t///  * After all finallies are applied, the branch state is merged into the target block.\n\t\t/// </summary>\n\t\tvoid ProcessBranchesLeavingTryFinally(TryFinally tryFinally, int branchesTriggeringFinallyOldCount)\n\t\t{\n\t\t\tint outPos = branchesTriggeringFinallyOldCount;\n\t\t\tfor (int i = branchesTriggeringFinallyOldCount; i < branchesTriggeringFinally.Count; ++i)\n\t\t\t{\n\t\t\t\tvar (branch, stateOnBranch) = branchesTriggeringFinally[i];\n\t\t\t\tDebug.Assert(((ILInstruction)branch).IsDescendantOf(tryFinally));\n\t\t\t\tDebug.Assert(tryFinally.IsDescendantOf(branch.TargetContainer));\n\t\t\t\tstateOnBranch.TriggerFinally(state);\n\t\t\t\tbool triggersAnotherFinally = Branch.GetExecutesFinallyBlock(tryFinally, branch.TargetContainer);\n\t\t\t\tif (triggersAnotherFinally)\n\t\t\t\t{\n\t\t\t\t\tbranchesTriggeringFinally[outPos++] = (branch, stateOnBranch);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Merge state into target block.\n\t\t\t\t\tif (branch is Leave leave)\n\t\t\t\t\t{\n\t\t\t\t\t\tMergeBranchStateIntoStateOnLeave((Leave)branch, stateOnBranch);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tMergeBranchStateIntoTargetBlock((Branch)branch, stateOnBranch);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbranchesTriggeringFinally.RemoveRange(outPos, branchesTriggeringFinally.Count - outPos);\n\t\t}\n\n\t\tprotected internal override void VisitTryFault(TryFault inst)\n\t\t{\n\t\t\tDebugStartPoint(inst);\n\t\t\t// try-fault executes fault block if an exception occurs in try,\n\t\t\t// and always rethrows the exception at the end.\n\t\t\tState onException = HandleTryBlock(inst);\n\t\t\tState onSuccess = state;\n\t\t\tstate = onException;\n\t\t\tinst.FaultBlock.AcceptVisitor(this);\n\t\t\t//PropagateStateOnException(); // rethrow the exception after the fault block\n\t\t\tDebug.Assert(state.LessThanOrEqual(currentStateOnException));\n\n\t\t\t// try-fault exits normally only if no exception occurred\n\t\t\tstate = onSuccess;\n\t\t\tDebugEndPoint(inst);\n\t\t}\n\n\t\tprotected internal override void VisitIfInstruction(IfInstruction inst)\n\t\t{\n\t\t\tDebugStartPoint(inst);\n\t\t\tvar (beforeThen, beforeElse) = EvaluateCondition(inst.Condition);\n\t\t\tstate = beforeThen;\n\t\t\tinst.TrueInst.AcceptVisitor(this);\n\t\t\tState afterTrueState = state;\n\t\t\tstate = beforeElse;\n\t\t\tinst.FalseInst.AcceptVisitor(this);\n\t\t\tstate.JoinWith(afterTrueState);\n\t\t\tDebugEndPoint(inst);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Evaluates the condition of an if.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// A pair of:\n\t\t///  * The state after the condition evaluates to true\n\t\t///  * The state after the condition evaluates to false\n\t\t/// </returns>\n\t\t/// <remarks>\n\t\t/// <c>this.state</c> is invalid after this function was called, and must be overwritten\n\t\t/// with one of the return values.\n\t\t/// </remarks>\n\t\t(State OnTrue, State OnFalse) EvaluateCondition(ILInstruction inst)\n\t\t{\n\t\t\tif (inst is IfInstruction ifInst)\n\t\t\t{\n\t\t\t\t// 'if (a?b:c)' or similar.\n\t\t\t\t// This also includes conditions that are logic.not, logic.and, logic.or.\n\t\t\t\tDebugStartPoint(ifInst);\n\t\t\t\tvar (beforeThen, beforeElse) = EvaluateCondition(ifInst.Condition);\n\t\t\t\tstate = beforeThen;\n\t\t\t\tvar (afterThenTrue, afterThenFalse) = EvaluateCondition(ifInst.TrueInst);\n\t\t\t\tstate = beforeElse;\n\t\t\t\tvar (afterElseTrue, afterElseFalse) = EvaluateCondition(ifInst.FalseInst);\n\n\t\t\t\tvar onTrue = afterThenTrue;\n\t\t\t\tonTrue.JoinWith(afterElseTrue);\n\t\t\t\tvar onFalse = afterThenFalse;\n\t\t\t\tonFalse.JoinWith(afterElseFalse);\n\n\t\t\t\tDebugEndPoint(ifInst);\n\t\t\t\treturn (onTrue, onFalse);\n\t\t\t}\n\t\t\telse if (inst is LdcI4 constant)\n\t\t\t{\n\t\t\t\tif (constant.Value == 0)\n\t\t\t\t{\n\t\t\t\t\treturn (bottomState.Clone(), state);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn (state, bottomState.Clone());\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (inst is MatchInstruction match)\n\t\t\t{\n\t\t\t\treturn EvaluateMatch(match);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// other kind of condition\n\t\t\t\tinst.AcceptVisitor(this);\n\t\t\t\treturn (state, state.Clone());\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void VisitMatchInstruction(MatchInstruction inst)\n\t\t{\n\t\t\tvar (onTrue, onFalse) = EvaluateMatch(inst);\n\t\t\tstate = onTrue;\n\t\t\tstate.JoinWith(onFalse);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Evaluates a match instruction.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// A pair of:\n\t\t///  * The state after the pattern matches\n\t\t///  * The state after the pattern fails to match\n\t\t/// </returns>\n\t\t/// <remarks>\n\t\t/// <c>this.state</c> is invalid after this function was called, and must be overwritten\n\t\t/// with one of the return values.\n\t\t/// </remarks>\n\t\t(State OnTrue, State OnFalse) EvaluateMatch(MatchInstruction inst)\n\t\t{\n\t\t\tDebugStartPoint(inst);\n\t\t\tinst.TestedOperand.AcceptVisitor(this);\n\t\t\tState onFalse = state.Clone();\n\t\t\tif (!inst.CheckNotNull && !inst.CheckType)\n\t\t\t{\n\t\t\t\tonFalse.ReplaceWithBottom();\n\t\t\t}\n\t\t\tHandleMatchStore(inst);\n\t\t\tforeach (var subPattern in inst.SubPatterns)\n\t\t\t{\n\t\t\t\tvar (subTrue, subFalse) = EvaluateCondition(subPattern);\n\t\t\t\tonFalse.JoinWith(subFalse);\n\t\t\t\tstate = subTrue;\n\t\t\t}\n\t\t\tDebugEndPoint(inst);\n\t\t\treturn (state, onFalse);\n\t\t}\n\n\t\tprotected abstract void HandleMatchStore(MatchInstruction inst);\n\n\t\tprotected internal override void VisitNullCoalescingInstruction(NullCoalescingInstruction inst)\n\t\t{\n\t\t\tHandleBinaryWithOptionalEvaluation(inst, inst.ValueInst, inst.FallbackInst);\n\t\t}\n\n\t\tprotected internal override void VisitDynamicLogicOperatorInstruction(DynamicLogicOperatorInstruction inst)\n\t\t{\n\t\t\tHandleBinaryWithOptionalEvaluation(inst, inst.Left, inst.Right);\n\t\t}\n\n\t\tprotected internal override void VisitUserDefinedLogicOperator(UserDefinedLogicOperator inst)\n\t\t{\n\t\t\tHandleBinaryWithOptionalEvaluation(inst, inst.Left, inst.Right);\n\t\t}\n\n\t\tvoid HandleBinaryWithOptionalEvaluation(ILInstruction parent, ILInstruction left, ILInstruction right)\n\t\t{\n\t\t\tDebugStartPoint(parent);\n\t\t\tleft.AcceptVisitor(this);\n\t\t\tState branchState = state.Clone();\n\t\t\tright.AcceptVisitor(this);\n\t\t\tstate.JoinWith(branchState);\n\t\t\tDebugEndPoint(parent);\n\t\t}\n\n\t\tState stateOnNullableRewrap;\n\n\t\tprotected internal override void VisitNullableRewrap(NullableRewrap inst)\n\t\t{\n\t\t\tDebugStartPoint(inst);\n\t\t\tvar oldState = stateOnNullableRewrap.Clone();\n\t\t\tstateOnNullableRewrap.ReplaceWithBottom();\n\n\t\t\tinst.Argument.AcceptVisitor(this);\n\t\t\t// Join incoming control flow from the NullableUnwraps.\n\t\t\tstate.JoinWith(stateOnNullableRewrap);\n\n\t\t\tstateOnNullableRewrap = oldState;\n\t\t\tDebugEndPoint(inst);\n\t\t}\n\n\t\tprotected internal override void VisitNullableUnwrap(NullableUnwrap inst)\n\t\t{\n\t\t\tDebugStartPoint(inst);\n\t\t\tinst.Argument.AcceptVisitor(this);\n\t\t\t// Conditional control flow edge to the surrounding NullableRewrap.\n\t\t\tstateOnNullableRewrap.JoinWith(state);\n\t\t\tDebugEndPoint(inst);\n\t\t}\n\n\t\tprotected internal override void VisitSwitchInstruction(SwitchInstruction inst)\n\t\t{\n\t\t\tDebugStartPoint(inst);\n\t\t\tinst.Value.AcceptVisitor(this);\n\t\t\tState beforeSections = state.Clone();\n\t\t\tinst.Sections[0].AcceptVisitor(this);\n\t\t\tState afterSections = state.Clone();\n\t\t\tfor (int i = 1; i < inst.Sections.Count; ++i)\n\t\t\t{\n\t\t\t\tstate.ReplaceWith(beforeSections);\n\t\t\t\tinst.Sections[i].AcceptVisitor(this);\n\t\t\t\tafterSections.JoinWith(state);\n\t\t\t}\n\t\t\tstate = afterSections;\n\t\t\tDebugEndPoint(inst);\n\t\t}\n\n\t\tprotected internal override void VisitYieldReturn(YieldReturn inst)\n\t\t{\n\t\t\tDebugStartPoint(inst);\n\t\t\tinst.Value.AcceptVisitor(this);\n\t\t\tDebugEndPoint(inst);\n\t\t}\n\n\t\tprotected internal override void VisitUsingInstruction(UsingInstruction inst)\n\t\t{\n\t\t\tDebugStartPoint(inst);\n\t\t\tinst.ResourceExpression.AcceptVisitor(this);\n\t\t\tinst.Body.AcceptVisitor(this);\n\t\t\tDebugEndPoint(inst);\n\t\t}\n\n\t\tprotected internal override void VisitLockInstruction(LockInstruction inst)\n\t\t{\n\t\t\tDebugStartPoint(inst);\n\t\t\tinst.OnExpression.AcceptVisitor(this);\n\t\t\tinst.Body.AcceptVisitor(this);\n\t\t\tDebugEndPoint(inst);\n\t\t}\n\n\t\tprotected internal override void VisitILFunction(ILFunction function)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/FlowAnalysis/DefiniteAssignmentVisitor.cs",
    "content": "// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.FlowAnalysis\n{\n\t/// <summary>\n\t/// DataFlowVisitor that performs definite assignment analysis.\n\t/// </summary>\n\tclass DefiniteAssignmentVisitor : DataFlowVisitor<DefiniteAssignmentVisitor.State>\n\t{\n\t\t/// <summary>\n\t\t/// State for definite assignment analysis.\n\t\t/// </summary>\n\t\t[DebuggerDisplay(\"{bits}\")]\n\t\tpublic struct State : IDataFlowState<State>\n\t\t{\n\t\t\t/// <summary>\n\t\t\t/// bits[i]: There is a code path from the entry point to this state's position\n\t\t\t///          that does not write to function.Variables[i].\n\t\t\t///          (i.e. the variable is not definitely assigned at the state's position)\n\t\t\t/// \n\t\t\t/// Initial state: all bits set = nothing is definitely assigned\n\t\t\t/// Bottom state: all bits clear\n\t\t\t/// </summary>\n\t\t\treadonly BitSet bits;\n\n\t\t\t/// <summary>\n\t\t\t/// Creates the initial state.\n\t\t\t/// </summary>\n\t\t\tpublic State(int variableCount)\n\t\t\t{\n\t\t\t\tthis.bits = new BitSet(variableCount);\n\t\t\t\tthis.bits.Set(0, variableCount);\n\t\t\t}\n\n\t\t\tprivate State(BitSet bits)\n\t\t\t{\n\t\t\t\tthis.bits = bits;\n\t\t\t}\n\n\t\t\tpublic bool LessThanOrEqual(State otherState)\n\t\t\t{\n\t\t\t\treturn bits.IsSubsetOf(otherState.bits);\n\t\t\t}\n\n\t\t\tpublic State Clone()\n\t\t\t{\n\t\t\t\treturn new State(bits.Clone());\n\t\t\t}\n\n\t\t\tpublic void ReplaceWith(State newContent)\n\t\t\t{\n\t\t\t\tbits.ReplaceWith(newContent.bits);\n\t\t\t}\n\n\t\t\tpublic void JoinWith(State incomingState)\n\t\t\t{\n\t\t\t\tbits.UnionWith(incomingState.bits);\n\t\t\t}\n\n\t\t\tpublic void TriggerFinally(State finallyState)\n\t\t\t{\n\t\t\t\t// If there is no path to the end of the try-block that leaves a variable v\n\t\t\t\t// uninitialized, then there is no such path to the end of the whole try-finally either.\n\t\t\t\t// (the try-finally cannot complete successfully unless the try block does the same)\n\t\t\t\t// ==> any bits that are false in this.state must be false in the output state.\n\n\t\t\t\t// Or said otherwise: a variable is definitely assigned after try-finally if it is\n\t\t\t\t// definitely assigned in either the try or the finally block.\n\t\t\t\t// Given that the bits are the opposite of definite assignment, this gives us:\n\t\t\t\t//    !outputBits[i] == !bits[i] || !finallyState.bits[i].\n\t\t\t\t// and thus:\n\t\t\t\t//    outputBits[i] == bits[i] && finallyState.bits[i].\n\t\t\t\tbits.IntersectWith(finallyState.bits);\n\t\t\t}\n\n\t\t\tpublic void ReplaceWithBottom()\n\t\t\t{\n\t\t\t\tbits.ClearAll();\n\t\t\t}\n\n\t\t\tpublic bool IsBottom {\n\t\t\t\tget { return !bits.Any(); }\n\t\t\t}\n\n\t\t\tpublic void MarkVariableInitialized(int variableIndex)\n\t\t\t{\n\t\t\t\tbits.Clear(variableIndex);\n\t\t\t}\n\n\t\t\tpublic bool IsPotentiallyUninitialized(int variableIndex)\n\t\t\t{\n\t\t\t\treturn bits[variableIndex];\n\t\t\t}\n\t\t}\n\n\t\treadonly CancellationToken cancellationToken;\n\t\treadonly ILFunction scope;\n\t\treadonly BitSet variablesWithUninitializedUsage;\n\n\t\treadonly Dictionary<IMethod, State> stateOfLocalFunctionUse = new Dictionary<IMethod, State>();\n\t\treadonly HashSet<IMethod> localFunctionsNeedingAnalysis = new HashSet<IMethod>();\n\n\t\tpublic DefiniteAssignmentVisitor(ILFunction scope, CancellationToken cancellationToken)\n\t\t{\n\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\tthis.cancellationToken = cancellationToken;\n\t\t\tthis.scope = scope;\n\t\t\tthis.variablesWithUninitializedUsage = new BitSet(scope.Variables.Count);\n\t\t\tbase.flagsRequiringManualImpl |= InstructionFlags.MayReadLocals | InstructionFlags.MayWriteLocals;\n\t\t\tInitialize(new State(scope.Variables.Count));\n\t\t}\n\n\t\tpublic bool IsPotentiallyUsedUninitialized(ILVariable v)\n\t\t{\n\t\t\tDebug.Assert(v.Function == scope);\n\t\t\treturn variablesWithUninitializedUsage[v.IndexInFunction];\n\t\t}\n\n\t\tvoid HandleStore(ILVariable v)\n\t\t{\n\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\tif (v.Function == scope)\n\t\t\t{\n\t\t\t\t// Mark the variable as initialized:\n\t\t\t\tstate.MarkVariableInitialized(v.IndexInFunction);\n\t\t\t\t// Note that this gets called even if the store is in unreachable code,\n\t\t\t\t// but that's OK because bottomState.MarkVariableInitialized() has no effect.\n\n\t\t\t\t// After the state change, we have to call\n\t\t\t\t//  PropagateStateOnException() = currentStateOnException.JoinWith(state);\n\t\t\t\t// but because MarkVariableInitialized() only clears a bit,\n\t\t\t\t// this is guaranteed to be a no-op.\n\t\t\t}\n\t\t}\n\n\t\tvoid EnsureInitialized(ILVariable v)\n\t\t{\n\t\t\tif (v.Function == scope && state.IsPotentiallyUninitialized(v.IndexInFunction))\n\t\t\t{\n\t\t\t\tvariablesWithUninitializedUsage.Set(v.IndexInFunction);\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void VisitStLoc(StLoc inst)\n\t\t{\n\t\t\tinst.Value.AcceptVisitor(this);\n\t\t\tHandleStore(inst.Variable);\n\t\t}\n\n\t\tprotected override void HandleMatchStore(MatchInstruction inst)\n\t\t{\n\t\t\tHandleStore(inst.Variable);\n\t\t}\n\n\t\tprotected override void BeginTryCatchHandler(TryCatchHandler inst)\n\t\t{\n\t\t\tHandleStore(inst.Variable);\n\t\t\tbase.BeginTryCatchHandler(inst);\n\t\t}\n\n\t\tprotected internal override void VisitPinnedRegion(PinnedRegion inst)\n\t\t{\n\t\t\tinst.Init.AcceptVisitor(this);\n\t\t\tHandleStore(inst.Variable);\n\t\t\tinst.Body.AcceptVisitor(this);\n\t\t}\n\n\t\tprotected internal override void VisitLdLoc(LdLoc inst)\n\t\t{\n\t\t\tEnsureInitialized(inst.Variable);\n\t\t}\n\n\t\tprotected internal override void VisitLdLoca(LdLoca inst)\n\t\t{\n\t\t\t// A variable needs to be initialized before we can take it by reference.\n\t\t\t// The exception is if the variable is passed to an out parameter (handled in VisitCall).\n\t\t\tEnsureInitialized(inst.Variable);\n\t\t}\n\n\t\tprotected internal override void VisitCall(Call inst)\n\t\t{\n\t\t\tHandleCall(inst);\n\t\t}\n\n\t\tprotected internal override void VisitCallVirt(CallVirt inst)\n\t\t{\n\t\t\tHandleCall(inst);\n\t\t}\n\n\t\tprotected internal override void VisitNewObj(NewObj inst)\n\t\t{\n\t\t\tHandleCall(inst);\n\t\t}\n\n\t\tprotected internal override void VisitILFunction(ILFunction inst)\n\t\t{\n\t\t\tDebugStartPoint(inst);\n\t\t\tState stateBeforeFunction = state.Clone();\n\t\t\tState stateOnExceptionBeforeFunction = currentStateOnException.Clone();\n\t\t\t// Note: lambdas are handled at their point of declaration.\n\t\t\t// We immediately visit their body, because captured variables need to be definitely initialized at this point.\n\t\t\t// We ignore the state after the lambda body (by resetting to the state before), because we don't know\n\t\t\t// when the lambda will be invoked.\n\t\t\t// This also makes this logic unsuitable for reaching definitions, as we wouldn't see the effect of stores in lambdas.\n\t\t\t// Only the simpler case of definite assignment can support lambdas.\n\t\t\tinst.Body.AcceptVisitor(this);\n\n\t\t\t// For local functions, the situation is similar to lambdas.\n\t\t\t// However, we don't use the state of the declaration site when visiting local functions,\n\t\t\t// but instead the state(s) of their point of use.\n\t\t\t// Because we might discover additional points of use within the local functions,\n\t\t\t// we use a fixed-point iteration.\n\t\t\tbool changed;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tchanged = false;\n\t\t\t\tforeach (var nestedFunction in inst.LocalFunctions)\n\t\t\t\t{\n\t\t\t\t\tif (!localFunctionsNeedingAnalysis.Contains(nestedFunction.ReducedMethod))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tlocalFunctionsNeedingAnalysis.Remove(nestedFunction.ReducedMethod);\n\t\t\t\t\tState stateOnEntry = stateOfLocalFunctionUse[nestedFunction.ReducedMethod];\n\t\t\t\t\tthis.state.ReplaceWith(stateOnEntry);\n\t\t\t\t\tthis.currentStateOnException.ReplaceWith(stateOnEntry);\n\t\t\t\t\tnestedFunction.AcceptVisitor(this);\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\t\t\t} while (changed);\n\t\t\tcurrentStateOnException = stateOnExceptionBeforeFunction;\n\t\t\tstate = stateBeforeFunction;\n\t\t\tDebugEndPoint(inst);\n\t\t}\n\n\t\tvoid HandleCall(CallInstruction call)\n\t\t{\n\t\t\tDebugStartPoint(call);\n\t\t\tbool hasOutArgs = false;\n\t\t\tforeach (var arg in call.Arguments)\n\t\t\t{\n\t\t\t\tif (arg.MatchLdLoca(out var v) && call.GetParameter(arg.ChildIndex)?.ReferenceKind == ReferenceKind.Out)\n\t\t\t\t{\n\t\t\t\t\t// Visiting ldloca would require the variable to be initialized,\n\t\t\t\t\t// but we don't need out arguments to be initialized.\n\t\t\t\t\thasOutArgs = true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\targ.AcceptVisitor(this);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Mark out arguments as initialized, but only after the whole call:\n\t\t\tif (hasOutArgs)\n\t\t\t{\n\t\t\t\tforeach (var arg in call.Arguments)\n\t\t\t\t{\n\t\t\t\t\tif (arg.MatchLdLoca(out var v) && call.GetParameter(arg.ChildIndex)?.ReferenceKind == ReferenceKind.Out)\n\t\t\t\t\t{\n\t\t\t\t\t\tHandleStore(v);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tHandleLocalFunctionUse(call.Method);\n\t\t\tDebugEndPoint(call);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// For a use of a local function, remember the current state to use as stateOnEntry when\n\t\t/// later processing the local function body.\n\t\t/// </summary>\n\t\tvoid HandleLocalFunctionUse(IMethod method)\n\t\t{\n\t\t\tif (method.IsLocalFunction)\n\t\t\t{\n\t\t\t\tif (stateOfLocalFunctionUse.TryGetValue(method, out var stateOnEntry))\n\t\t\t\t{\n\t\t\t\t\tif (!state.LessThanOrEqual(stateOnEntry))\n\t\t\t\t\t{\n\t\t\t\t\t\tstateOnEntry.JoinWith(state);\n\t\t\t\t\t\tlocalFunctionsNeedingAnalysis.Add(method);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tstateOfLocalFunctionUse.Add(method, state.Clone());\n\t\t\t\t\tlocalFunctionsNeedingAnalysis.Add(method);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void VisitLdFtn(LdFtn inst)\n\t\t{\n\t\t\tDebugStartPoint(inst);\n\t\t\tHandleLocalFunctionUse(inst.Method);\n\t\t\tDebugEndPoint(inst);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/FlowAnalysis/Dominance.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.FlowAnalysis\n{\n\t/// <summary>\n\t/// Description of Dominance.\n\t/// </summary>\n\tpublic static class Dominance\n\t{\n\t\t/// <summary>\n\t\t/// Computes the dominator tree.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Precondition: the dominance tree is not already computed for some nodes reachable from entryPoint\n\t\t/// (i.e. ImmediateDominator and DominatorTreeChildren are both null),\n\t\t/// and the visited flag is false for any nodes reachable from entryPoint.\n\t\t/// \n\t\t/// Postcondition: a dominator tree is constructed for all nodes reachable from entryPoint,\n\t\t/// and the visited flag remains false.\n\t\t/// </remarks>\n\t\tpublic static void ComputeDominance(ControlFlowNode entryPoint, CancellationToken cancellationToken = default(CancellationToken))\n\t\t{\n\t\t\t// A Simple, Fast Dominance Algorithm\n\t\t\t// Keith D. Cooper, Timothy J. Harvey and Ken Kennedy\n\n\t\t\tvar nodes = new List<ControlFlowNode>();\n\t\t\tentryPoint.TraversePostOrder(n => n.Successors, nodes.Add);\n\t\t\tDebug.Assert(nodes.Last() == entryPoint);\n\t\t\tfor (int i = 0; i < nodes.Count; i++)\n\t\t\t{\n\t\t\t\tnodes[i].PostOrderNumber = i;\n\t\t\t}\n\n\t\t\t// For the purpose of this algorithm, make the entry point its own dominator.\n\t\t\t// We'll reset it back to null at the end of this function.\n\t\t\tentryPoint.ImmediateDominator = entryPoint;\n\t\t\tbool changed;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tchanged = false;\n\n\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\n\t\t\t\t// For all nodes b except the entry point (in reverse post-order)\n\t\t\t\tfor (int i = nodes.Count - 2; i >= 0; i--)\n\t\t\t\t{\n\t\t\t\t\tControlFlowNode b = nodes[i];\n\t\t\t\t\t// Compute new immediate dominator:\n\t\t\t\t\tControlFlowNode newIdom = null;\n\t\t\t\t\tforeach (var p in b.Predecessors)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Ignore predecessors that were not processed yet\n\t\t\t\t\t\tif (p.ImmediateDominator != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (newIdom == null)\n\t\t\t\t\t\t\t\tnewIdom = p;\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tnewIdom = FindCommonDominator(p, newIdom);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// The reverse post-order ensures at least one of our predecessors was processed.\n\t\t\t\t\tDebug.Assert(newIdom != null);\n\t\t\t\t\tif (newIdom != b.ImmediateDominator)\n\t\t\t\t\t{\n\t\t\t\t\t\tb.ImmediateDominator = newIdom;\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} while (changed);\n\t\t\t// Create dominator tree for all reachable nodes:\n\t\t\tforeach (ControlFlowNode node in nodes)\n\t\t\t{\n\t\t\t\tif (node.ImmediateDominator != null)\n\t\t\t\t\tnode.DominatorTreeChildren = new List<ControlFlowNode>();\n\t\t\t}\n\t\t\tentryPoint.ImmediateDominator = null;\n\t\t\tforeach (ControlFlowNode node in nodes)\n\t\t\t{\n\t\t\t\t// Create list of children in dominator tree\n\t\t\t\tif (node.ImmediateDominator != null)\n\t\t\t\t\tnode.ImmediateDominator.DominatorTreeChildren.Add(node);\n\t\t\t\t// Also reset the visited flag\n\t\t\t\tnode.Visited = false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the common ancestor of a and b in the dominator tree.\n\t\t/// \n\t\t/// Precondition: a and b are part of the same dominator tree.\n\t\t/// </summary>\n\t\tpublic static ControlFlowNode FindCommonDominator(ControlFlowNode a, ControlFlowNode b)\n\t\t{\n\t\t\twhile (a != b)\n\t\t\t{\n\t\t\t\twhile (a.PostOrderNumber < b.PostOrderNumber)\n\t\t\t\t\ta = a.ImmediateDominator;\n\t\t\t\twhile (b.PostOrderNumber < a.PostOrderNumber)\n\t\t\t\t\tb = b.ImmediateDominator;\n\t\t\t}\n\t\t\treturn a;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Computes a BitSet where\n\t\t/// <c>result[i] == true</c> iff cfg[i] is reachable and there is some node that is\n\t\t/// reachable from cfg[i] but not dominated by cfg[i].\n\t\t/// \n\t\t/// This is similar to \"does cfg[i] have a non-empty dominance frontier?\",\n\t\t/// except that it uses non-strict dominance where the definition of dominance frontiers\n\t\t/// uses \"strictly dominates\".\n\t\t/// \n\t\t/// Precondition:\n\t\t///  Dominance was computed for cfg and <c>cfg[i].UserIndex == i</c> for all i.\n\t\t/// </summary>\n\t\tpublic static BitSet MarkNodesWithReachableExits(ControlFlowNode[] cfg)\n\t\t{\n#if DEBUG\n\t\t\tfor (int i = 0; i < cfg.Length; i++)\n\t\t\t{\n\t\t\t\tDebug.Assert(cfg[i].UserIndex == i);\n\t\t\t}\n#endif\n\t\t\tBitSet nonEmpty = new BitSet(cfg.Length);\n\t\t\tforeach (var j in cfg)\n\t\t\t{\n\t\t\t\t// If j is a join-point (more than one incoming edge):\n\t\t\t\t// `j.IsReachable && j.ImmediateDominator == null` is the root node, which counts as an extra incoming edge\n\t\t\t\tif (j.IsReachable && (j.Predecessors.Count >= 2 || (j.Predecessors.Count >= 1 && j.ImmediateDominator == null)))\n\t\t\t\t{\n\t\t\t\t\t// Add j to frontier of all predecessors and their dominators up to j's immediate dominator.\n\t\t\t\t\tforeach (var p in j.Predecessors)\n\t\t\t\t\t{\n\t\t\t\t\t\tfor (var runner = p; runner != j.ImmediateDominator && runner != j && runner != null; runner = runner.ImmediateDominator)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnonEmpty.Set(runner.UserIndex);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nonEmpty;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/FlowAnalysis/ReachingDefinitionsVisitor.cs",
    "content": "// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.FlowAnalysis\n{\n\t/// <summary>\n\t/// Implements the \"reaching definitions\" analysis.\n\t/// \n\t/// https://en.wikipedia.org/wiki/Reaching_definition\n\t/// \n\t/// By \"definitions\", we mean stores to local variables.\n\t/// </summary>\n\t/// <remarks>\n\t/// Possible \"definitions\" that store to a variable are:\n\t/// * <c>StLoc</c>\n\t/// * <c>TryCatchHandler</c> (for the exception variable)\n\t/// * <c>ReachingDefinitionsVisitor.UninitializedVariable</c> for uninitialized variables.\n\t/// Note that we do not keep track of <c>LdLoca</c>/references/pointers.\n\t/// The analysis will likely be wrong/incomplete for variables with <c>AddressCount != 0</c>.\n\t/// \n\t/// Note: this class does not store the computed information, because doing so\n\t/// would significantly increase the number of states we need to store.\n\t/// The only way to get the computed information out of this class is to\n\t/// derive from the class and override the Visit methods at the points of interest\n\t/// (usually the load instructions).\n\t/// </remarks>\n\tclass ReachingDefinitionsVisitor : DataFlowVisitor<ReachingDefinitionsVisitor.State>\n\t{\n\t\t#region State representation\n\t\t/// <summary>\n\t\t/// The state during the reaching definitions analysis.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// A state can either be reachable, or unreachable:\n\t\t///  1) unreachable\n\t\t///     Note that during the analysis, \"unreachable\" just means we have not yet found a path\n\t\t///     from the entry point to the node. States transition from unreachable to reachable as\n\t\t///     the analysis processes more control flow paths.\n\t\t///  2) reachable\n\t\t///     In this case, the state contains, for each variable, the set of stores that might have\n\t\t///     written to the variable before the control flow reached the state's source code position.\n\t\t///     This set does not include stores that were definitely overwritten by other stores to the\n\t\t///     same variable.\n\t\t///     During the analysis, the set of stores gets extended as the analysis processes more code paths.\n\t\t/// \n\t\t/// The reachable state could be represented as a `Dictionary{ILVariable, ISet{ILInstruction}}`.\n\t\t/// To consume less memory, we instead assign an integer index to all stores in the analyzed function (\"store index\"),\n\t\t/// and store the state as a `BitSet` instead.\n\t\t/// Each bit in the set corresponds to one store instruction, and is `true` iff the store is a reaching definition\n\t\t/// for the variable it is storing to.\n\t\t/// The `allStores` array has the same length as the bit sets and holds the corresponding `ILInstruction` objects (store instructions).\n\t\t/// All stores for a single variable occupy a contiguous segment of the `allStores` array (and thus also of the `state`),\n\t\t/// which allows us to efficient clear out all stores that get overwritten by a new store.\n\t\t/// </remarks>\n\t\t[DebuggerDisplay(\"{bits}\")]\n\t\tpublic struct State : IDataFlowState<State>\n\t\t{\n\t\t\t/// <summary>\n\t\t\t/// This bitset contains three different kinds of bits:\n\t\t\t/// Reachable bit: (bit 0)\n\t\t\t///     This state's position is reachable from the entry point.\n\t\t\t/// \n\t\t\t/// Reaching uninitialized variable bit: (bit si, where si > 0 and <c>allStores[si] == null</c>)\n\t\t\t///     There is a code path from the scope's entry point to this state's position\n\t\t\t///     that does not pass through any store to the variable.\n\t\t\t/// \n\t\t\t/// <c>firstStoreIndexForVariable[v.IndexInScope]</c> gives the index of that variable's uninitialized bit.\n\t\t\t/// \n\t\t\t/// Reaching store bit (bit si, where <c>allStores[si] != null</c>):\n\t\t\t///     There is a code path from the entry point to this state's position\n\t\t\t///     that passes through through <c>allStores[si]</c> and does not pass through another\n\t\t\t///     store to <c>allStores[si].Variable</c>.\n\t\t\t/// \n\t\t\t/// The indices for a variable's reaching store bits are between <c>firstStoreIndexForVariable[v.IndexInScope]</c>\n\t\t\t/// to <c>firstStoreIndexForVariable[v.IndexInScope + 1]</c> (both endpoints exclusive!).\n\t\t\t/// </summary>\n\t\t\t/// <remarks>\n\t\t\t/// The initial state has the \"reachable bit\" and the \"reaching uninitialized variable bits\" set,\n\t\t\t/// and the \"reaching store bits\" unset.\n\t\t\t/// \n\t\t\t/// The bottom state has all bits unset.\n\t\t\t/// </remarks>\n\t\t\treadonly BitSet bits;\n\n\t\t\tpublic State(BitSet bits)\n\t\t\t{\n\t\t\t\tthis.bits = bits;\n\t\t\t}\n\n\t\t\tpublic bool LessThanOrEqual(State otherState)\n\t\t\t{\n\t\t\t\treturn bits.IsSubsetOf(otherState.bits);\n\t\t\t}\n\n\t\t\tpublic State Clone()\n\t\t\t{\n\t\t\t\treturn new State(bits.Clone());\n\t\t\t}\n\n\t\t\tpublic void ReplaceWith(State newContent)\n\t\t\t{\n\t\t\t\tbits.ReplaceWith(newContent.bits);\n\t\t\t}\n\n\t\t\tpublic void JoinWith(State incomingState)\n\t\t\t{\n\t\t\t\t// When control flow is joined together, we can simply union our bitsets.\n\t\t\t\t// (a store is reachable iff it is reachable through either incoming path)\n\t\t\t\tbits.UnionWith(incomingState.bits);\n\t\t\t}\n\n\t\t\tpublic void TriggerFinally(State finallyState)\n\t\t\t{\n\t\t\t\t// Some cases to consider:\n\t\t\t\t//   try { v = 1; } finally { v = 2; }\n\t\t\t\t//     => only the store 2 is visible after the try-finally\n\t\t\t\t//   v = 1; try { v = 2; } finally { }\n\t\t\t\t//     => both stores are visible after the try-finally\n\t\t\t\t// In general, we're looking for the post-state of the finally-block\n\t\t\t\t// assume the finally-block was entered without throwing an exception.\n\t\t\t\t// But we don't have that information (it would require analyzing the finally block twice),\n\t\t\t\t// so the next best thing is to approximate it by just keeping the state after the finally\n\t\t\t\t// (i.e. doing nothing at all).\n\t\t\t\t// However, the DataFlowVisitor requires us to return bottom if the end-state of the\n\t\t\t\t// try-block was unreachable, so let's so at least that.\n\t\t\t\t// (note that in principle we could just AND the reachable and uninitialized bits,\n\t\t\t\t//  but we don't have a good solution for the normal store bits)\n\t\t\t\tif (IsReachable)\n\t\t\t\t{\n\t\t\t\t\tReplaceWith(finallyState);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic bool IsBottom {\n\t\t\t\tget { return !bits[ReachableBit]; }\n\t\t\t}\n\n\t\t\tpublic void ReplaceWithBottom()\n\t\t\t{\n\t\t\t\t// We need to clear all bits, not just ReachableBit, so that\n\t\t\t\t// the bottom state behaves as expected in joins.\n\t\t\t\tbits.ClearAll();\n\t\t\t}\n\n\t\t\tpublic bool IsReachable {\n\t\t\t\tget { return bits[ReachableBit]; }\n\t\t\t}\n\n\t\t\t/// <summary>\n\t\t\t/// Clears all store bits between startStoreIndex (incl.) and endStoreIndex (excl.)\n\t\t\t/// </summary>\n\t\t\tpublic void KillStores(int startStoreIndex, int endStoreIndex)\n\t\t\t{\n\t\t\t\tDebug.Assert(startStoreIndex >= FirstStoreIndex);\n\t\t\t\tDebug.Assert(endStoreIndex >= startStoreIndex);\n\t\t\t\tbits.Clear(startStoreIndex, endStoreIndex);\n\t\t\t}\n\n\t\t\tpublic bool IsReachingStore(int storeIndex)\n\t\t\t{\n\t\t\t\treturn bits[storeIndex];\n\t\t\t}\n\n\t\t\tpublic int NextReachingStore(int startIndex, int endIndex)\n\t\t\t{\n\t\t\t\treturn bits.NextSetBit(startIndex, endIndex);\n\t\t\t}\n\n\t\t\tpublic void SetStore(int storeIndex)\n\t\t\t{\n\t\t\t\tDebug.Assert(storeIndex >= FirstStoreIndex);\n\t\t\t\tbits.Set(storeIndex);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// To distinguish unreachable from reachable states, we use the first bit in the bitset to store the 'reachable bit'.\n\t\t/// If this bit is set, the state is reachable, and the remaining bits\n\t\t/// </summary>\n\t\tconst int ReachableBit = 0;\n\n\t\t/// <summary>\n\t\t/// Because bit number 0 is the ReachableBit, we start counting store indices at 1.\n\t\t/// </summary>\n\t\tconst int FirstStoreIndex = 1;\n\t\t#endregion\n\n\t\t#region Documentation + member fields\n\t\tprotected readonly CancellationToken cancellationToken;\n\n\t\t/// <summary>\n\t\t/// The function being analyzed.\n\t\t/// </summary>\n\t\tprotected readonly ILFunction scope;\n\n\t\t/// <summary>\n\t\t/// All stores for all variables in the scope.\n\t\t/// \n\t\t/// <c>state[storeIndex]</c> is true iff <c>allStores[storeIndex]</c> is a reaching definition.\n\t\t/// Invariant: <c>state.bits.Length == allStores.Length</c>.\n\t\t/// </summary>\n\t\treadonly ILInstruction[] allStores;\n\n\t\t/// <summary>\n\t\t/// Maps instructions appearing in <c>allStores</c> to their index.\n\t\t/// \n\t\t/// Invariant: <c>allStores[storeIndexMap[inst]] == inst</c>\n\t\t/// \n\t\t/// Does not contain <c>UninitializedVariable</c> (as that special instruction has multiple store indices, one per variable)\n\t\t/// </summary>\n\t\treadonly Dictionary<ILInstruction, int> storeIndexMap = new Dictionary<ILInstruction, int>();\n\n\t\t/// <summary>\n\t\t/// For all variables <c>v</c>: <c>allStores[firstStoreIndexForVariable[v.IndexInScope]]</c> is the <c>UninitializedVariable</c> entry for <c>v</c>.\n\t\t/// The next few stores (up to <c>firstStoreIndexForVariable[v.IndexInScope + 1]</c>, exclusive) are the full list of stores for <c>v</c>.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Invariant: <c>firstStoreIndexForVariable[scope.Variables.Count] == allStores.Length</c>\n\t\t/// </remarks>\n\t\treadonly int[] firstStoreIndexForVariable;\n\n\t\t/// <summary>\n\t\t/// <c>analyzedVariables[v.IndexInScope]</c> is true iff RD analysis is enabled for the variable.\n\t\t/// </summary>\n\t\treadonly BitSet analyzedVariables;\n\t\t#endregion\n\n\t\t#region Constructor\n\t\t/// <summary>\n\t\t/// Prepare reaching definitions analysis for the specified variable scope.\n\t\t/// \n\t\t/// The analysis will track all variables in the scope for which the predicate returns true\n\t\t/// (\"analyzed variables\").\n\t\t/// </summary>\n\t\tpublic ReachingDefinitionsVisitor(ILFunction scope, Predicate<ILVariable> pred, CancellationToken cancellationToken)\n\t\t\t: this(scope, GetActiveVariableBitSet(scope, pred), cancellationToken)\n\t\t{\n\t\t\tthis.cancellationToken = cancellationToken;\n\t\t}\n\n\t\tstatic BitSet GetActiveVariableBitSet(ILFunction scope, Predicate<ILVariable> pred)\n\t\t{\n\t\t\tif (scope == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(scope));\n\t\t\tBitSet activeVariables = new BitSet(scope.Variables.Count);\n\t\t\tfor (int vi = 0; vi < scope.Variables.Count; vi++)\n\t\t\t{\n\t\t\t\tactiveVariables[vi] = pred(scope.Variables[vi]);\n\t\t\t}\n\t\t\treturn activeVariables;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Prepare reaching definitions analysis for the specified variable scope.\n\t\t/// \n\t\t/// The analysis will track all variables in the scope for which <c>analyzedVariables[v.IndexInScope]</c> is true.\n\t\t/// </summary>\n\t\tpublic ReachingDefinitionsVisitor(ILFunction scope, BitSet analyzedVariables, CancellationToken cancellationToken)\n\t\t{\n\t\t\tif (scope == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(scope));\n\t\t\tif (analyzedVariables == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(analyzedVariables));\n\t\t\tthis.scope = scope;\n\t\t\tthis.analyzedVariables = analyzedVariables;\n\t\t\tbase.flagsRequiringManualImpl |= InstructionFlags.MayWriteLocals;\n\n\t\t\t// Fill `allStores` and `storeIndexMap` and `firstStoreIndexForVariable`.\n\t\t\tvar storesByVar = FindAllStoresByVariable(scope, analyzedVariables, cancellationToken);\n\t\t\tallStores = new ILInstruction[FirstStoreIndex + storesByVar.Sum(l => l != null ? l.Count : 0)];\n\t\t\tfirstStoreIndexForVariable = new int[scope.Variables.Count + 1];\n\t\t\tint si = FirstStoreIndex;\n\t\t\tfor (int vi = 0; vi < storesByVar.Length; vi++)\n\t\t\t{\n\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tfirstStoreIndexForVariable[vi] = si;\n\t\t\t\tvar stores = storesByVar[vi];\n\t\t\t\tif (stores != null)\n\t\t\t\t{\n\t\t\t\t\tint expectedStoreCount = scope.Variables[vi].StoreInstructions.Count;\n\t\t\t\t\t// Extra store for the uninitialized state.\n\t\t\t\t\texpectedStoreCount += 1;\n\t\t\t\t\tDebug.Assert(stores.Count == expectedStoreCount);\n\t\t\t\t\tstores.CopyTo(allStores, si);\n\t\t\t\t\t// Add all stores except for the first (representing the uninitialized state)\n\t\t\t\t\t// to storeIndexMap.\n\t\t\t\t\tfor (int i = 1; i < stores.Count; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tstoreIndexMap.Add(stores[i], si + i);\n\t\t\t\t\t}\n\t\t\t\t\tsi += stores.Count;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfirstStoreIndexForVariable[scope.Variables.Count] = si;\n\t\t\tDebug.Assert(si == allStores.Length);\n\n\t\t\tInitialize(CreateInitialState());\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Fill <c>allStores</c> and <c>storeIndexMap</c>.\n\t\t/// </summary>\n\t\tstatic List<ILInstruction>[] FindAllStoresByVariable(ILFunction scope, BitSet activeVariables, CancellationToken cancellationToken)\n\t\t{\n\t\t\t// For each variable, find the list of ILInstructions storing to that variable\n\t\t\tList<ILInstruction>[] storesByVar = new List<ILInstruction>[scope.Variables.Count];\n\t\t\tfor (int vi = 0; vi < storesByVar.Length; vi++)\n\t\t\t{\n\t\t\t\tif (activeVariables[vi])\n\t\t\t\t\tstoresByVar[vi] = new List<ILInstruction> { null };\n\t\t\t}\n\t\t\tforeach (var inst in scope.Descendants)\n\t\t\t{\n\t\t\t\tif (inst.HasDirectFlag(InstructionFlags.MayWriteLocals))\n\t\t\t\t{\n\t\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tILVariable v = ((IInstructionWithVariableOperand)inst).Variable;\n\t\t\t\t\tif (v.Function == scope && activeVariables[v.IndexInFunction])\n\t\t\t\t\t{\n\t\t\t\t\t\tstoresByVar[v.IndexInFunction].Add(inst);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn storesByVar;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Create the initial state (reachable bit + uninit variable bits set, store bits unset).\n\t\t/// </summary>\n\t\tState CreateInitialState()\n\t\t{\n\t\t\tBitSet initialState = new BitSet(allStores.Length);\n\t\t\tinitialState.Set(ReachableBit);\n\t\t\tfor (int vi = 0; vi < scope.Variables.Count; vi++)\n\t\t\t{\n\t\t\t\tif (analyzedVariables[vi])\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(allStores[firstStoreIndexForVariable[vi]] == null);\n\t\t\t\t\tinitialState.Set(firstStoreIndexForVariable[vi]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn new State(initialState);\n\t\t}\n\t\t#endregion\n\n\t\t#region Analysis\n\t\tvoid HandleStore(ILInstruction inst, ILVariable v)\n\t\t{\n\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\tif (v.Function == scope && analyzedVariables[v.IndexInFunction] && state.IsReachable)\n\t\t\t{\n\t\t\t\t// Clear the set of stores for this variable:\n\t\t\t\tstate.KillStores(firstStoreIndexForVariable[v.IndexInFunction], firstStoreIndexForVariable[v.IndexInFunction + 1]);\n\t\t\t\t// And replace it with this store:\n\t\t\t\tint si = storeIndexMap[inst];\n\t\t\t\tstate.SetStore(si);\n\n\t\t\t\t// We should call PropagateStateOnException() here because we changed the state.\n\t\t\t\t// But that's equal to: currentStateOnException.UnionWith(state);\n\n\t\t\t\t// Because we're already guaranteed that state.LessThanOrEqual(currentStateOnException)\n\t\t\t\t// when entering HandleStore(), all we really need to do to achieve what PropagateStateOnException() does\n\t\t\t\t// is to add the single additional store to the exceptional state as well:\n\t\t\t\tcurrentStateOnException.SetStore(si);\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void VisitStLoc(StLoc inst)\n\t\t{\n\t\t\tinst.Value.AcceptVisitor(this);\n\t\t\tHandleStore(inst, inst.Variable);\n\t\t}\n\n\t\tprotected override void HandleMatchStore(MatchInstruction inst)\n\t\t{\n\t\t\tHandleStore(inst, inst.Variable);\n\t\t}\n\n\t\tprotected override void BeginTryCatchHandler(TryCatchHandler inst)\n\t\t{\n\t\t\tbase.BeginTryCatchHandler(inst);\n\t\t\tHandleStore(inst, inst.Variable);\n\t\t}\n\n\t\tprotected internal override void VisitPinnedRegion(PinnedRegion inst)\n\t\t{\n\t\t\tinst.Init.AcceptVisitor(this);\n\t\t\tHandleStore(inst, inst.Variable);\n\t\t\tinst.Body.AcceptVisitor(this);\n\t\t}\n\n\t\tpublic bool IsAnalyzedVariable(ILVariable v)\n\t\t{\n\t\t\treturn v.Function == scope && analyzedVariables[v.IndexInFunction];\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets all stores to <c>v</c> that reach the specified state.\n\t\t/// \n\t\t/// Precondition: v is an analyzed variable.\n\t\t/// </summary>\n\t\tprotected IEnumerable<ILInstruction> GetStores(State state, ILVariable v)\n\t\t{\n\t\t\tDebug.Assert(v.Function == scope && analyzedVariables[v.IndexInFunction]);\n\t\t\tint startIndex = firstStoreIndexForVariable[v.IndexInFunction] + 1;\n\t\t\tint endIndex = firstStoreIndexForVariable[v.IndexInFunction + 1];\n\t\t\twhile (startIndex < endIndex)\n\t\t\t{\n\t\t\t\tint nextReachingStore = state.NextReachingStore(startIndex, endIndex);\n\t\t\t\tif (nextReachingStore == -1)\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tDebug.Assert(((IInstructionWithVariableOperand)allStores[nextReachingStore]).Variable == v);\n\t\t\t\tyield return allStores[nextReachingStore];\n\t\t\t\tstartIndex = nextReachingStore + 1;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether <c>v</c> is potentially uninitialized in the specified state.\n\t\t/// \n\t\t/// Precondition: v is an analyzed variable.\n\t\t/// </summary>\n\t\tprotected bool IsPotentiallyUninitialized(State state, ILVariable v)\n\t\t{\n\t\t\tDebug.Assert(v.Function == scope && analyzedVariables[v.IndexInFunction]);\n\t\t\treturn state.IsReachingStore(firstStoreIndexForVariable[v.IndexInFunction]);\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Humanizer/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2013 Scott Kirkland\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "ICSharpCode.Decompiler/Humanizer/StringHumanizeExtensions.cs",
    "content": "namespace Humanizer.Inflections;\n\nusing CharSpan = System.ReadOnlySpan<System.Char>;\n\n/// <summary>\n/// Contains extension methods for humanizing string values.\n/// </summary>\ninternal static class StringHumanizeExtensions\n{\n\tinternal static unsafe string Concat(CharSpan left, CharSpan right)\n\t{\n\t\tvar result = new string('\\0', left.Length + right.Length);\n\t\tfixed (char* pResult = result)\n\t\t{\n\t\t\tleft.CopyTo(new(pResult, left.Length));\n\t\t\tright.CopyTo(new(pResult + left.Length, right.Length));\n\t\t}\n\t\treturn result;\n\t}\n\n\tinternal static unsafe string Concat(char left, CharSpan right) =>\n\t\tConcat(new CharSpan(&left, 1), right);\n}"
  },
  {
    "path": "ICSharpCode.Decompiler/Humanizer/Vocabularies.cs",
    "content": "using System;\nusing System.Threading;\n\nnamespace Humanizer.Inflections;\n\n/// <summary>\n/// Container for registered Vocabularies.  At present, only a single vocabulary is supported: Default.\n/// </summary>\ninternal static class Vocabularies\n{\n\tstatic readonly Lazy<Vocabulary> Instance = new(BuildDefault, LazyThreadSafetyMode.PublicationOnly);\n\n\t/// <summary>\n\t/// The default vocabulary used for singular/plural irregularities.\n\t/// Rules can be added to this vocabulary and will be picked up by called to Singularize() and Pluralize().\n\t/// At this time, multiple vocabularies and removing existing rules are not supported.\n\t/// </summary>\n\tpublic static Vocabulary Default => Instance.Value;\n\n\tstatic Vocabulary BuildDefault()\n\t{\n\t\tvar _default = new Vocabulary();\n\n\t\t_default.AddPlural(\"$\", \"s\");\n\t\t_default.AddPlural(\"s$\", \"s\");\n\t\t_default.AddPlural(\"(ax|test)is$\", \"$1es\");\n\t\t_default.AddPlural(\"(octop|vir|alumn|fung|cact|foc|hippopotam|radi|stimul|syllab|nucle)us$\", \"$1i\");\n\t\t_default.AddPlural(\"(alias|bias|iris|status|campus|apparatus|virus|walrus|trellis)$\", \"$1es\");\n\t\t_default.AddPlural(\"(buffal|tomat|volcan|ech|embarg|her|mosquit|potat|torped|vet)o$\", \"$1oes\");\n\t\t_default.AddPlural(\"([dti])um$\", \"$1a\");\n\t\t_default.AddPlural(\"sis$\", \"ses\");\n\t\t_default.AddPlural(\"(?:([^f])fe|([lr])f)$\", \"$1$2ves\");\n\t\t_default.AddPlural(\"(hive)$\", \"$1s\");\n\t\t_default.AddPlural(\"([^aeiouy]|qu)y$\", \"$1ies\");\n\t\t_default.AddPlural(\"(x|ch|ss|sh)$\", \"$1es\");\n\t\t_default.AddPlural(\"(matr|vert|ind|d)(ix|ex)$\", \"$1ices\");\n\t\t_default.AddPlural(\"(^[m|l])ouse$\", \"$1ice\");\n\t\t_default.AddPlural(\"^(ox)$\", \"$1en\");\n\t\t_default.AddPlural(\"(quiz)$\", \"$1zes\");\n\t\t_default.AddPlural(\"(buz|blit|walt)z$\", \"$1zes\");\n\t\t_default.AddPlural(\"(hoo|lea|loa|thie)f$\", \"$1ves\");\n\t\t_default.AddPlural(\"(alumn|alg|larv|vertebr)a$\", \"$1ae\");\n\t\t_default.AddPlural(\"(criteri|phenomen)on$\", \"$1a\");\n\n\t\t_default.AddSingular(\"s$\", \"\");\n\t\t_default.AddSingular(\"(n)ews$\", \"$1ews\");\n\t\t_default.AddSingular(\"([dti])a$\", \"$1um\");\n\t\t_default.AddSingular(\"(analy|ba|diagno|parenthe|progno|synop|the|ellip|empha|neuro|oa|paraly)ses$\", \"$1sis\");\n\t\t_default.AddSingular(\"([^f])ves$\", \"$1fe\");\n\t\t_default.AddSingular(\"(hive)s$\", \"$1\");\n\t\t_default.AddSingular(\"(tive)s$\", \"$1\");\n\t\t_default.AddSingular(\"([lr]|hoo|lea|loa|thie)ves$\", \"$1f\");\n\t\t_default.AddSingular(\"(^zomb)?([^aeiouy]|qu)ies$\", \"$2y\");\n\t\t_default.AddSingular(\"(s)eries$\", \"$1eries\");\n\t\t_default.AddSingular(\"(m)ovies$\", \"$1ovie\");\n\t\t_default.AddSingular(\"(x|ch|ss|sh)es$\", \"$1\");\n\t\t_default.AddSingular(\"(^[m|l])ice$\", \"$1ouse\");\n\t\t_default.AddSingular(\"(?<!^[a-z])(o)es$\", \"$1\");\n\t\t_default.AddSingular(\"(shoe)s$\", \"$1\");\n\t\t_default.AddSingular(\"(cris|ax|test)es$\", \"$1is\");\n\t\t_default.AddSingular(\"(octop|vir|alumn|fung|cact|foc|hippopotam|radi|stimul|syllab|nucle)i$\", \"$1us\");\n\t\t_default.AddSingular(\"(alias|bias|iris|status|campus|apparatus|virus|walrus|trellis)es$\", \"$1\");\n\t\t_default.AddSingular(\"^(ox)en\", \"$1\");\n\t\t_default.AddSingular(\"(matr|d)ices$\", \"$1ix\");\n\t\t_default.AddSingular(\"(vert|ind)ices$\", \"$1ex\");\n\t\t_default.AddSingular(\"(quiz)zes$\", \"$1\");\n\t\t_default.AddSingular(\"(buz|blit|walt)zes$\", \"$1z\");\n\t\t_default.AddSingular(\"(alumn|alg|larv|vertebr)ae$\", \"$1a\");\n\t\t_default.AddSingular(\"(criteri|phenomen)a$\", \"$1on\");\n\t\t_default.AddSingular(\"([b|r|c]ook|room|smooth)ies$\", \"$1ie\");\n\n\t\t_default.AddIrregular(\"person\", \"people\");\n\t\t_default.AddIrregular(\"man\", \"men\");\n\t\t_default.AddIrregular(\"human\", \"humans\");\n\t\t_default.AddIrregular(\"child\", \"children\");\n\t\t_default.AddIrregular(\"sex\", \"sexes\");\n\t\t_default.AddIrregular(\"glove\", \"gloves\");\n\t\t_default.AddIrregular(\"move\", \"moves\");\n\t\t_default.AddIrregular(\"goose\", \"geese\");\n\t\t_default.AddIrregular(\"wave\", \"waves\");\n\t\t_default.AddIrregular(\"foot\", \"feet\");\n\t\t_default.AddIrregular(\"tooth\", \"teeth\");\n\t\t_default.AddIrregular(\"curriculum\", \"curricula\");\n\t\t_default.AddIrregular(\"database\", \"databases\");\n\t\t_default.AddIrregular(\"zombie\", \"zombies\");\n\t\t_default.AddIrregular(\"personnel\", \"personnel\");\n\t\t_default.AddIrregular(\"cache\", \"caches\");\n\t\t_default.AddIrregular(\"ex\", \"exes\", matchEnding: false);\n\t\t_default.AddIrregular(\"is\", \"are\", matchEnding: false);\n\t\t_default.AddIrregular(\"was\", \"were\", matchEnding: false);\n\t\t_default.AddIrregular(\"that\", \"those\", matchEnding: false);\n\t\t_default.AddIrregular(\"this\", \"these\", matchEnding: false);\n\t\t_default.AddIrregular(\"bus\", \"buses\", matchEnding: false);\n\t\t_default.AddIrregular(\"die\", \"dice\", matchEnding: false);\n\t\t_default.AddIrregular(\"tie\", \"ties\", matchEnding: false);\n\t\t_default.AddIrregular(\"lens\", \"lenses\");\n\t\t_default.AddIrregular(\"clove\", \"cloves\");\n\t\t_default.AddIrregular(\"valve\", \"valves\");\n\t\t_default.AddIrregular(\"explosive\", \"explosives\");\n\n\t\t_default.AddUncountable(\"staff\");\n\t\t_default.AddUncountable(\"training\");\n\t\t_default.AddUncountable(\"equipment\");\n\t\t_default.AddUncountable(\"information\");\n\t\t_default.AddUncountable(\"corn\");\n\t\t_default.AddUncountable(\"milk\");\n\t\t_default.AddUncountable(\"rice\");\n\t\t_default.AddUncountable(\"money\");\n\t\t_default.AddUncountable(\"species\");\n\t\t_default.AddUncountable(\"series\");\n\t\t_default.AddUncountable(\"fish\");\n\t\t_default.AddUncountable(\"sheep\");\n\t\t_default.AddUncountable(\"deer\");\n\t\t_default.AddUncountable(\"aircraft\");\n\t\t_default.AddUncountable(\"oz\");\n\t\t_default.AddUncountable(\"tsp\");\n\t\t_default.AddUncountable(\"tbsp\");\n\t\t_default.AddUncountable(\"ml\");\n\t\t_default.AddUncountable(\"l\");\n\t\t_default.AddUncountable(\"water\");\n\t\t_default.AddUncountable(\"waters\");\n\t\t_default.AddUncountable(\"semen\");\n\t\t_default.AddUncountable(\"sperm\");\n\t\t_default.AddUncountable(\"bison\");\n\t\t_default.AddUncountable(\"grass\");\n\t\t_default.AddUncountable(\"hair\");\n\t\t_default.AddUncountable(\"mud\");\n\t\t_default.AddUncountable(\"elk\");\n\t\t_default.AddUncountable(\"luggage\");\n\t\t_default.AddUncountable(\"moose\");\n\t\t_default.AddUncountable(\"offspring\");\n\t\t_default.AddUncountable(\"salmon\");\n\t\t_default.AddUncountable(\"shrimp\");\n\t\t_default.AddUncountable(\"someone\");\n\t\t_default.AddUncountable(\"swine\");\n\t\t_default.AddUncountable(\"trout\");\n\t\t_default.AddUncountable(\"tuna\");\n\t\t_default.AddUncountable(\"corps\");\n\t\t_default.AddUncountable(\"scissors\");\n\t\t_default.AddUncountable(\"means\");\n\t\t_default.AddUncountable(\"mail\");\n\t\t_default.AddUncountable(\"pliers\");\n\t\t_default.AddUncountable(\"sheers\");\n\t\t_default.AddUncountable(\"clothes\");\n\t\t_default.AddUncountable(\"apparatus\");\n\t\t_default.AddUncountable(\"chassis\");\n\t\t_default.AddUncountable(\"debris\");\n\n\t\t//Fix 1132\n\t\t_default.AddUncountable(\"metadata\");\n\n\t\treturn _default;\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler/Humanizer/Vocabulary.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Text.RegularExpressions;\n\nnamespace Humanizer.Inflections;\n\n#nullable enable\n\n/// <summary>\n/// A container for exceptions to simple pluralization/singularization rules.\n/// Vocabularies.Default contains an extensive list of rules for US English.\n/// At this time, multiple vocabularies and removing existing rules are not supported.\n/// </summary>\ninternal class Vocabulary\n{\n\tinternal Vocabulary()\n\t{\n\t}\n\n\treadonly List<Rule> plurals = [];\n\treadonly List<Rule> singulars = [];\n\treadonly HashSet<string> uncountables = new(StringComparer.CurrentCultureIgnoreCase);\n\treadonly Regex letterS = new(\"^([sS])[sS]*$\");\n\n\t/// <summary>\n\t/// Adds a word to the vocabulary which cannot easily be pluralized/singularized by RegEx, e.g. \"person\" and \"people\".\n\t/// </summary>\n\t/// <param name=\"singular\">The singular form of the irregular word, e.g. \"person\".</param>\n\t/// <param name=\"plural\">The plural form of the irregular word, e.g. \"people\".</param>\n\t/// <param name=\"matchEnding\">True to match these words on their own as well as at the end of longer words. False, otherwise.</param>\n\tpublic void AddIrregular(string singular, string plural, bool matchEnding = true)\n\t{\n\t\tif (matchEnding)\n\t\t{\n\t\t\tvar singularSubstring = singular.Substring(1);\n\t\t\tvar pluralSubString = plural.Substring(1);\n\t\t\tAddPlural($\"({singular[0]}){singularSubstring}$\", $\"$1{pluralSubString}\");\n\t\t\tAddSingular($\"({plural[0]}){pluralSubString}$\", $\"$1{singularSubstring}\");\n\t\t}\n\t\telse\n\t\t{\n\t\t\tAddPlural($\"^{singular}$\", plural);\n\t\t\tAddSingular($\"^{plural}$\", singular);\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Adds an uncountable word to the vocabulary, e.g. \"fish\".  Will be ignored when plurality is changed.\n\t/// </summary>\n\t/// <param name=\"word\">Word to be added to the list of uncountables.</param>\n\tpublic void AddUncountable(string word) =>\n\t\tuncountables.Add(word);\n\n\t/// <summary>\n\t/// Adds a rule to the vocabulary that does not follow trivial rules for pluralization, e.g. \"bus\" -> \"buses\"\n\t/// </summary>\n\t/// <param name=\"rule\">RegEx to be matched, case insensitive, e.g. \"(bus)es$\"</param>\n\t/// <param name=\"replacement\">RegEx replacement  e.g. \"$1\"</param>\n\tpublic void AddPlural(string rule, string replacement) =>\n\t\tplurals.Add(new(rule, replacement));\n\n\t/// <summary>\n\t/// Adds a rule to the vocabulary that does not follow trivial rules for singularization, e.g. \"vertices/indices -> \"vertex/index\"\n\t/// </summary>\n\t/// <param name=\"rule\">RegEx to be matched, case insensitive, e.g. \"\"(vert|ind)ices$\"\"</param>\n\t/// <param name=\"replacement\">RegEx replacement  e.g. \"$1ex\"</param>\n\tpublic void AddSingular(string rule, string replacement) =>\n\t\tsingulars.Add(new(rule, replacement));\n\n\t/// <summary>\n\t/// Pluralizes the provided input considering irregular words\n\t/// </summary>\n\t/// <param name=\"word\">Word to be pluralized</param>\n\t/// <param name=\"inputIsKnownToBeSingular\">Normally you call Pluralize on singular words; but if you're unsure call it with false</param>\n\t[return: NotNullIfNotNull(nameof(word))]\n\tpublic string? Pluralize(string? word, bool inputIsKnownToBeSingular = true)\n\t{\n\t\tif (word == null)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tvar s = LetterS(word);\n\t\tif (s != null)\n\t\t{\n\t\t\treturn s + \"s\";\n\t\t}\n\n\t\tvar result = ApplyRules(plurals, word, false);\n\n\t\tif (inputIsKnownToBeSingular)\n\t\t{\n\t\t\treturn result ?? word;\n\t\t}\n\n\t\tvar asSingular = ApplyRules(singulars, word, false);\n\t\tvar asSingularAsPlural = ApplyRules(plurals, asSingular, false);\n\t\tif (asSingular != null &&\n\t\t\tasSingular != word &&\n\t\t\tasSingular + \"s\" != word &&\n\t\t\tasSingularAsPlural == word &&\n\t\t\tresult != word)\n\t\t{\n\t\t\treturn word;\n\t\t}\n\n\t\treturn result!;\n\t}\n\n\t/// <summary>\n\t/// Singularizes the provided input considering irregular words\n\t/// </summary>\n\t/// <param name=\"word\">Word to be singularized</param>\n\t/// <param name=\"inputIsKnownToBePlural\">Normally you call Singularize on plural words; but if you're unsure call it with false</param>\n\t/// <param name=\"skipSimpleWords\">Skip singularizing single words that have an 's' on the end</param>\n\t[return: NotNullIfNotNull(nameof(word))]\n\tpublic string? Singularize(string? word, bool inputIsKnownToBePlural = true, bool skipSimpleWords = false)\n\t{\n\t\tif (word == null)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\t\tvar s = LetterS(word);\n\t\tif (s != null)\n\t\t{\n\t\t\treturn s;\n\t\t}\n\n\t\tvar result = ApplyRules(singulars, word, skipSimpleWords);\n\n\t\tif (inputIsKnownToBePlural)\n\t\t{\n\t\t\treturn result ?? word;\n\t\t}\n\n\t\t// the Plurality is unknown so we should check all possibilities\n\t\tvar asPlural = ApplyRules(plurals, word, false);\n\t\tif (asPlural == word ||\n\t\t\tword + \"s\" == asPlural)\n\t\t{\n\t\t\treturn result ?? word;\n\t\t}\n\n\t\tvar asPluralAsSingular = ApplyRules(singulars, asPlural, false);\n\t\tif (asPluralAsSingular != word ||\n\t\t\tresult == word)\n\t\t{\n\t\t\treturn result ?? word;\n\t\t}\n\n\t\treturn word;\n\t}\n\n\tstring? ApplyRules(IList<Rule> rules, string? word, bool skipFirstRule)\n\t{\n\t\tif (word == null)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tif (word.Length < 1)\n\t\t{\n\t\t\treturn word;\n\t\t}\n\n\t\tif (IsUncountable(word))\n\t\t{\n\t\t\treturn word;\n\t\t}\n\n\t\tvar result = word;\n\t\tvar end = skipFirstRule ? 1 : 0;\n\t\tfor (var i = rules.Count - 1; i >= end; i--)\n\t\t{\n\t\t\tif ((result = rules[i].Apply(word)) != null)\n\t\t\t{\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (result == null)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\treturn MatchUpperCase(word, result);\n\t}\n\n\tbool IsUncountable(string word) =>\n\t\tuncountables.Contains(word);\n\n\tstatic string MatchUpperCase(string word, string replacement) =>\n\t\tchar.IsUpper(word[0]) &&\n\t\tchar.IsLower(replacement[0]) ? StringHumanizeExtensions.Concat(char.ToUpper(replacement[0]), replacement.AsSpan(1)) : replacement;\n\n\t/// <summary>\n\t/// If the word is the letter s, singular or plural, return the letter s singular\n\t/// </summary>\n\tstring? LetterS(string word)\n\t{\n\t\tvar s = letterS.Match(word);\n\t\treturn s.Groups.Count > 1 ? s.Groups[1].Value : null;\n\t}\n\n\tclass Rule(string pattern, string replacement)\n\t{\n\t\treadonly Regex regex = new(pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);\n\n\t\tpublic string? Apply(string word)\n\t\t{\n\t\t\tif (!regex.IsMatch(word))\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn regex.Replace(word, replacement);\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <TargetFramework>netstandard2.0</TargetFramework>\r\n\r\n    <PackageId>ICSharpCode.Decompiler</PackageId>\r\n    <PackageVersion>8.0.0.0-noversion</PackageVersion>\r\n    <Title>ILSpy Decompiler Engine</Title>\r\n    <Authors>ILSpy Contributors</Authors>\r\n    <PackageLicenseExpression>MIT</PackageLicenseExpression>\r\n    <PackageProjectUrl>https://github.com/icsharpcode/ILSpy/</PackageProjectUrl>\r\n    <Description>ICSharpCode.Decompiler is the decompiler engine used in ILSpy.</Description>\r\n    <PackageReadmeFile>PackageReadme.md</PackageReadmeFile>\r\n    <Company>ic#code</Company>\r\n    <Product>ILSpy</Product>\r\n    <RepositoryType>git</RepositoryType>\r\n    <RepositoryUrl>https://github.com/icsharpcode/ILSpy.git</RepositoryUrl>\r\n    <PackageIcon>DecompilerNuGetPackageIcon.png</PackageIcon>\r\n    <PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>\r\n    <Copyright>Copyright 2011-$([System.DateTime]::Now.Year) AlphaSierraPapa</Copyright>\r\n    <PackageTags>C# Decompiler ILSpy</PackageTags>\r\n    <GenerateSBOM>true</GenerateSBOM>\r\n\r\n    <NeutralLanguage>en-US</NeutralLanguage>\r\n    <GenerateAssemblyVersionAttribute>False</GenerateAssemblyVersionAttribute>\r\n    <GenerateAssemblyFileVersionAttribute>False</GenerateAssemblyFileVersionAttribute>\r\n    <GenerateAssemblyInformationalVersionAttribute>False</GenerateAssemblyInformationalVersionAttribute>\r\n\r\n    <EnableDefaultItems>false</EnableDefaultItems>\r\n    <LangVersion>13</LangVersion>\r\n    <GenerateDocumentationFile>true</GenerateDocumentationFile>\r\n    <SignAssembly>True</SignAssembly>\r\n    <AssemblyOriginatorKeyFile>ICSharpCode.Decompiler.snk</AssemblyOriginatorKeyFile>\r\n    <NoWarn>$(NoWarn);1701;1702;1591;1573</NoWarn>\r\n    <WarningsAsErrors>nullable</WarningsAsErrors>\r\n\r\n    <DebugType>embedded</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n    <EmbedUntrackedSources>true</EmbedUntrackedSources>\r\n    <PublishRepositoryUrl>true</PublishRepositoryUrl>\r\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <None Include=\"PackageReadme.md\" Pack=\"true\" PackagePath=\"\\\" />\r\n    <None Include=\"DecompilerNuGetPackageIcon.png\" Pack=\"true\" PackagePath=\"\\\" />\r\n  </ItemGroup>\r\n  \r\n  <!-- https://devblogs.microsoft.com/nuget/enable-repeatable-package-restores-using-a-lock-file/ -->\r\n  <PropertyGroup>\r\n    <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>\r\n\t<RestoreLockedMode>true</RestoreLockedMode>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Debug'\">\r\n    <CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>\r\n    <DefineConstants>$(DefineConstants);STEP</DefineConstants>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(GITHUB_ACTIONS)' == 'true'\">\r\n    <ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>\r\n  </PropertyGroup>\r\n\r\n  <!-- Inject ILSpyUpdateAssemblyInfo as dependency of the GetPackageVersion\r\n    target so Pack uses the generated version when evaluating project references. -->\r\n  <PropertyGroup>\r\n    <GetPackageVersionDependsOn>\r\n      ILSpyUpdateAssemblyInfo;\r\n      $(GetPackageVersionDependsOn)\r\n    </GetPackageVersionDependsOn>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup>\r\n    <ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"Microsoft.Sbom.Targets\" Version=\"4.1.5\">\r\n      <PrivateAssets>all</PrivateAssets>\r\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\r\n    </PackageReference>\r\n    <PackageReference Include=\"System.Collections.Immutable\" Version=\"9.0.0\" />\r\n    <PackageReference Include=\"System.Reflection.Metadata\" Version=\"9.0.0\" />\r\n    <PackageReference Include=\"Microsoft.SourceLink.GitHub\" Version=\"10.0.201\">\r\n      <PrivateAssets>all</PrivateAssets>\r\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\r\n    </PackageReference>\r\n    <PackageReference Include=\"Microsoft.CodeAnalysis.NetAnalyzers\" Version=\"10.0.201\">\r\n      <PrivateAssets>all</PrivateAssets>\r\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>\r\n    </PackageReference>\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"TunnelVisionLabs.ReferenceAssemblyAnnotator\" Version=\"1.0.0-alpha.160\" PrivateAssets=\"all\" />\r\n\r\n    <!-- Specifies the version of Microsoft.NETCore.App.Ref to obtain nullability information from. -->\r\n    <PackageDownload Include=\"Microsoft.NETCore.App.Ref\" Version=\"[8.0.0]\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <Compile Include=\"CSharp\\Annotations.cs\" />\r\n    <Compile Include=\"CSharp\\CallBuilder.cs\" />\r\n    <Compile Include=\"CSharp\\CSharpLanguageVersion.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\RecursivePatternExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TypeMembers\\ExtensionDeclaration.cs\" />\r\n    <Compile Include=\"DecompilationProgress.cs\" />\r\n    <Compile Include=\"Disassembler\\IEntityProcessor.cs\" />\r\n    <Compile Include=\"Disassembler\\SortByNameProcessor.cs\" />\r\n    <Compile Include=\"Humanizer\\StringHumanizeExtensions.cs\" />\r\n    <Compile Include=\"IL\\ILAmbience.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\InlineArrayTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\RemoveUnconstrainedGenericReferenceTypeCheck.cs\" />\r\n    <Compile Include=\"Metadata\\MetadataFile.cs\" />\r\n    <Compile Include=\"Metadata\\ModuleReferenceMetadata.cs\" />\r\n    <Compile Include=\"Metadata\\PropertyAndEventBackingFieldLookup.cs\" />\r\n    <Compile Include=\"NRTAttributes.cs\" />\r\n    <Compile Include=\"PartialTypeInfo.cs\" />\r\n    <Compile Include=\"CSharp\\ProjectDecompiler\\IProjectFileWriter.cs\" />\r\n    <Compile Include=\"CSharp\\OutputVisitor\\GenericGrammarAmbiguityVisitor.cs\" />\r\n    <Compile Include=\"CSharp\\ProjectDecompiler\\IProjectInfoProvider.cs\" />\r\n    <Compile Include=\"CSharp\\ProjectDecompiler\\ProjectFileWriterSdkStyle.cs\" />\r\n    <Compile Include=\"CSharp\\ProjectDecompiler\\ProjectFileWriterDefault.cs\" />\r\n    <Compile Include=\"CSharp\\RecordDecompiler.cs\" />\r\n    <Compile Include=\"CSharp\\RequiredNamespaceCollector.cs\" />\r\n    <Compile Include=\"CSharp\\SequencePointBuilder.cs\" />\r\n    <Compile Include=\"CSharp\\ProjectDecompiler\\TargetFramework.cs\" />\r\n    <Compile Include=\"CSharp\\ProjectDecompiler\\TargetServices.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\DeclarationExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\SwitchExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\WithInitializerExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\FunctionPointerAstType.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\InvocationAstType.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\VariableDesignation.cs\" />\r\n    <Compile Include=\"Humanizer\\Vocabularies.cs\" />\r\n    <Compile Include=\"Humanizer\\Vocabulary.cs\" />\r\n    <Compile Include=\"IL\\ControlFlow\\RemoveRedundantReturn.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\DeconstructionTransform.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\DeconstructInstruction.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\DeconstructResultInstruction.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\MatchInstruction.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\IndexRangeTransform.cs\" />\r\n    <Compile Include=\"CSharp\\TranslatedStatement.cs\" />\r\n    <Compile Include=\"DebugInfo\\KnownGuids.cs\" />\r\n    <Compile Include=\"Disassembler\\DisassemblerSignatureTypeProvider.cs\" />\r\n    <Compile Include=\"Documentation\\XmlDocumentationElement.cs\" />\r\n    <Compile Include=\"IL\\ControlFlow\\AwaitInFinallyTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\InterpolatedStringTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\IntroduceNativeIntTypeOnLocals.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\LdLocaDupInitObjTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\PatternMatchingTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\RemoveInfeasiblePathTransform.cs\" />\r\n    <Compile Include=\"Instrumentation\\DecompilerEventSource.cs\" />\r\n    <Compile Include=\"Metadata\\FindTypeDecoder.cs\" />\r\n    <Compile Include=\"Metadata\\FullTypeNameSignatureDecoder.cs\" />\r\n    <Compile Include=\"Metadata\\MetadataGenericContext.cs\" />\r\n    <Compile Include=\"Metadata\\ReferenceLoadInfo.cs\" />\r\n    <Compile Include=\"Properties\\DecompilerVersionInfo.cs\" />\r\n    <Compile Include=\"TypeSystem\\ExtensionInfo.cs\" />\r\n    <Compile Include=\"TypeSystem\\ITypeDefinitionOrUnknown.cs\" />\r\n    <Compile Include=\"Util\\BitOperations.cs\" />\r\n    <Compile Include=\"Util\\DelegateComparer.cs\" />\r\n    <Compile Include=\"Util\\Index.cs\" />\r\n    <Compile Include=\"Metadata\\WebCilFile.cs\" />\r\n    <None Include=\"Properties\\DecompilerVersionInfo.template.cs\" />\r\n    <Compile Include=\"Semantics\\OutVarResolveResult.cs\" />\r\n    <Compile Include=\"SingleFileBundle.cs\" />\r\n    <Compile Include=\"Solution\\ProjectId.cs\" />\r\n    <Compile Include=\"Solution\\ProjectItem.cs\" />\r\n    <Compile Include=\"Solution\\SolutionCreator.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\AstNode.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\AstNodeCollection.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\AstType.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\ComposedType.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\CSharpModifierToken.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\CSharpTokenNode.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\DepthFirstAstVisitor.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\DocumentationReference.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\AnonymousMethodExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\AnonymousTypeCreateExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\ArrayCreateExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\ArrayInitializerExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\AsExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\AssignmentExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\BaseReferenceExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\BinaryOperatorExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\CastExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\CheckedExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\ConditionalExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\DefaultValueExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\DirectionExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\ErrorExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\Expression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\IdentifierExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\IndexerExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\InterpolatedStringExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\InvocationExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\IsExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\LambdaExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\MemberReferenceExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\NamedArgumentExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\NamedExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\NullReferenceExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\ObjectCreateExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\OutVarDeclarationExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\ParenthesizedExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\PointerReferenceExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\PrimitiveExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\QueryExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\SizeOfExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\StackAllocExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\ThisReferenceExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\ThrowExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\TupleExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\TypeOfExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\TypeReferenceExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\UnaryOperatorExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\UncheckedExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Expressions\\UndocumentedExpression.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\GeneralScope\\Attribute.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\GeneralScope\\AttributeSection.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\GeneralScope\\Comment.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\GeneralScope\\Constraint.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\GeneralScope\\DelegateDeclaration.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\GeneralScope\\ExternAliasDeclaration.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\GeneralScope\\NamespaceDeclaration.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\GeneralScope\\PreProcessorDirective.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\GeneralScope\\TypeDeclaration.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\GeneralScope\\TypeParameterDeclaration.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\GeneralScope\\UsingAliasDeclaration.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\GeneralScope\\UsingDeclaration.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\IAstVisitor.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Identifier.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\IdentifierExpressionBackreference.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\MemberType.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Modifiers.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\NodeType.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\PatternMatching\\AnyNode.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\PatternMatching\\AnyNodeOrNull.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\PatternMatching\\Backreference.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\PatternMatching\\BacktrackingInfo.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\PatternMatching\\Choice.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\PatternMatching\\INode.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\PatternMatching\\Match.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\PatternMatching\\NamedNode.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\PatternMatching\\OptionalNode.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\PatternMatching\\Pattern.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\PatternMatching\\Repeat.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\PrimitiveType.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Role.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Roles.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\SimpleType.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\BlockStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\BreakStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\CheckedStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\ContinueStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\DoWhileStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\EmptyStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\ExpressionStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\FixedStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\ForeachStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\ForStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\GotoStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\IfElseStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\LabelStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\LocalFunctionDeclarationStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\LockStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\ReturnStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\Statement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\SwitchStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\ThrowStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\TryCatchStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\UncheckedStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\UnsafeStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\UsingStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\VariableDeclarationStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\WhileStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\YieldBreakStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\Statements\\YieldReturnStatement.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\SyntaxExtensions.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\SyntaxTree.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TextLocation.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TokenRole.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TupleAstType.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TypeMembers\\Accessor.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TypeMembers\\ConstructorDeclaration.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TypeMembers\\DestructorDeclaration.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TypeMembers\\EntityDeclaration.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TypeMembers\\EnumMemberDeclaration.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TypeMembers\\EventDeclaration.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TypeMembers\\FieldDeclaration.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TypeMembers\\FixedFieldDeclaration.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TypeMembers\\FixedVariableInitializer.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TypeMembers\\IndexerDeclaration.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TypeMembers\\MethodDeclaration.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TypeMembers\\OperatorDeclaration.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TypeMembers\\ParameterDeclaration.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TypeMembers\\PropertyDeclaration.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TypeMembers\\VariableInitializer.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\TypeSystemAstBuilder.cs\" />\r\n    <Compile Include=\"CSharp\\OutputVisitor\\CSharpAmbience.cs\" />\r\n    <Compile Include=\"CSharp\\OutputVisitor\\CSharpFormattingOptions.cs\" />\r\n    <Compile Include=\"CSharp\\OutputVisitor\\CSharpOutputVisitor.cs\" />\r\n    <Compile Include=\"CSharp\\OutputVisitor\\FormattingOptionsFactory.cs\" />\r\n    <Compile Include=\"CSharp\\OutputVisitor\\InsertMissingTokensDecorator.cs\" />\r\n    <Compile Include=\"CSharp\\OutputVisitor\\InsertParenthesesVisitor.cs\" />\r\n    <Compile Include=\"CSharp\\OutputVisitor\\InsertRequiredSpacesDecorator.cs\" />\r\n    <Compile Include=\"CSharp\\OutputVisitor\\InsertSpecialsDecorator.cs\" />\r\n    <Compile Include=\"CSharp\\OutputVisitor\\ITokenWriter.cs\" />\r\n    <Compile Include=\"CSharp\\OutputVisitor\\TextWriterTokenWriter.cs\" />\r\n    <Compile Include=\"CSharp\\Resolver\\AliasNamespaceResolveResult.cs\" />\r\n    <Compile Include=\"CSharp\\Resolver\\AliasTypeResolveResult.cs\" />\r\n    <Compile Include=\"CSharp\\Resolver\\AwaitResolveResult.cs\" />\r\n    <Compile Include=\"CSharp\\Resolver\\CSharpConversions.cs\" />\r\n    <Compile Include=\"CSharp\\Resolver\\CSharpInvocationResolveResult.cs\" />\r\n    <Compile Include=\"CSharp\\Resolver\\CSharpOperators.cs\" />\r\n    <Compile Include=\"CSharp\\Resolver\\CSharpResolver.cs\" />\r\n    <Compile Include=\"CSharp\\Resolver\\DynamicInvocationResolveResult.cs\" />\r\n    <Compile Include=\"CSharp\\Resolver\\DynamicMemberResolveResult.cs\" />\r\n    <Compile Include=\"CSharp\\Resolver\\LambdaResolveResult.cs\" />\r\n    <Compile Include=\"CSharp\\Resolver\\Log.cs\" />\r\n    <Compile Include=\"CSharp\\Resolver\\MemberLookup.cs\" />\r\n    <Compile Include=\"CSharp\\Resolver\\MethodGroupResolveResult.cs\" />\r\n    <Compile Include=\"CSharp\\Resolver\\NameLookupMode.cs\" />\r\n    <Compile Include=\"CSharp\\Resolver\\OverloadResolution.cs\" />\r\n    <Compile Include=\"CSharp\\Resolver\\OverloadResolutionErrors.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\FixRemainingIncrements.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\ILExtraction.cs\" />\r\n    <Compile Include=\"TypeSystem\\FunctionPointerType.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\LocalFunctionMethod.cs\" />\r\n    <Compile Include=\"CSharp\\Resolver\\TypeInference.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\CombineQueryExpressions.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\FlattenSwitchBlocks.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\IntroduceExtensionMethods.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\IntroduceQueryExpressions.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\NormalizeBlockStatements.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\PrettifyAssignments.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\RemoveCLSCompliantAttribute.cs\" />\r\n    <Compile Include=\"CSharp\\TranslationContext.cs\" />\r\n    <Compile Include=\"CSharp\\TypeSystem\\CSharpTypeResolveContext.cs\" />\r\n    <Compile Include=\"CSharp\\TypeSystem\\UsingScope.cs\" />\r\n    <Compile Include=\"DebugInfo\\AsyncDebugInfo.cs\" />\r\n    <Compile Include=\"DebugInfo\\ImportScopeInfo.cs\" />\r\n    <Compile Include=\"DebugInfo\\DebugInfoGenerator.cs\" />\r\n    <Compile Include=\"DecompilerException.cs\" />\r\n    <Compile Include=\"DecompilerSettings.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\ContextTrackingVisitor.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\DeclareVariables.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\EscapeInvalidIdentifiers.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\FixNameCollisions.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\IntroduceUsingDeclarations.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\PatternStatementTransform.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\TransformContext.cs\" />\r\n    <Compile Include=\"CSharp\\TranslatedExpression.cs\" />\r\n    <Compile Include=\"CSharp\\CSharpDecompiler.cs\" />\r\n    <Compile Include=\"CSharp\\ExpressionBuilder.cs\" />\r\n    <Compile Include=\"CSharp\\StatementBuilder.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\AddCheckedBlocks.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\TransformFieldAndConstructorInitializers.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\CustomPatterns.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\IAstTransform.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\IntroduceUnsafeModifier.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\ReplaceMethodCallsWithOperators.cs\" />\r\n    <Compile Include=\"CSharp\\ProjectDecompiler\\WholeProjectDecompiler.cs\" />\r\n    <Compile Include=\"CSharp\\Transforms\\AddXmlDocumentationTransform.cs\" />\r\n    <Compile Include=\"DecompileRun.cs\" />\r\n    <Compile Include=\"Disassembler\\ILParser.cs\" />\r\n    <Compile Include=\"IL\\ILInstructionExtensions.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\CombineExitsTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\DynamicIsEventAssignmentTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\ReduceNestingTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\LocalFunctionDecompiler.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\TransformDisplayClassUsage.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\UserDefinedLogicTransform.cs\" />\r\n    <Compile Include=\"Metadata\\AssemblyReferences.cs\" />\r\n    <Compile Include=\"Metadata\\ExportedTypeMetadata.cs\" />\r\n    <Compile Include=\"Metadata\\MemberReferenceMetadata.cs\" />\r\n    <Compile Include=\"Metadata\\TypeReferenceMetadata.cs\" />\r\n    <Compile Include=\"Metadata\\CodeMappingInfo.cs\" />\r\n    <Compile Include=\"Metadata\\EnumUnderlyingTypeResolveException.cs\" />\r\n    <Compile Include=\"Metadata\\MetadataTokenHelpers.cs\" />\r\n    <Compile Include=\"Disassembler\\OpCodeInfo.cs\" />\r\n    <Compile Include=\"Documentation\\GetPotentiallyNestedClassTypeReference.cs\" />\r\n    <Compile Include=\"Documentation\\IdStringMemberReference.cs\" />\r\n    <Compile Include=\"Documentation\\IdStringProvider.cs\" />\r\n    <Compile Include=\"Documentation\\XmlDocLoader.cs\" />\r\n    <Compile Include=\"Documentation\\XmlDocumentationProvider.cs\" />\r\n    <Compile Include=\"IL\\ControlFlow\\AsyncAwaitDecompiler.cs\" />\r\n    <Compile Include=\"IL\\ControlFlow\\AwaitInCatchTransform.cs\" />\r\n    <Compile Include=\"IL\\ControlFlow\\YieldReturnDecompiler.cs\" />\r\n    <Compile Include=\"Metadata\\CustomAttributeDecoder.cs\" />\r\n    <Compile Include=\"Metadata\\Resource.cs\" />\r\n    <Compile Include=\"Metadata\\DotNetCorePathFinder.cs\" />\r\n    <Compile Include=\"Metadata\\DotNetCorePathFinderExtensions.cs\" />\r\n    <Compile Include=\"Metadata\\LightJson\\JsonArray.cs\" />\r\n    <Compile Include=\"Metadata\\LightJson\\JsonObject.cs\" />\r\n    <Compile Include=\"Metadata\\LightJson\\JsonValue.cs\" />\r\n    <Compile Include=\"Metadata\\LightJson\\JsonValueType.cs\" />\r\n    <Compile Include=\"Metadata\\LightJson\\Serialization\\JsonParseException.cs\" />\r\n    <Compile Include=\"Metadata\\LightJson\\Serialization\\JsonReader.cs\" />\r\n    <Compile Include=\"Metadata\\LightJson\\Serialization\\TextPosition.cs\" />\r\n    <Compile Include=\"Metadata\\LightJson\\Serialization\\TextScanner.cs\" />\r\n    <Compile Include=\"Metadata\\MethodSemanticsLookup.cs\" />\r\n    <Compile Include=\"Metadata\\OperandType.cs\" />\r\n    <Compile Include=\"Metadata\\PEFile.cs\" />\r\n    <Compile Include=\"Metadata\\SignatureBlobComparer.cs\" />\r\n    <Compile Include=\"Metadata\\UniversalAssemblyResolver.cs\" />\r\n    <Compile Include=\"Metadata\\UnresolvedAssemblyNameReference.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\DynamicInstructions.cs\" />\r\n    <Compile Include=\"IL\\PointerArithmeticOffset.cs\" />\r\n    <Compile Include=\"IL\\ILAstWritingOptions.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\LdFlda.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\NullableInstructions.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\StLoc.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\IsInst.cs\" />\r\n    <Compile Include=\"DebugInfo\\SequencePoint.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\CallIndirect.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\DefaultValue.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\DynamicCallSiteTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\EarlyExpressionTransforms.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\ExpressionTreeCast.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\HighLevelLoopTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\NamedArgumentTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\IntroduceDynamicTypeOnLocals.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\IntroduceRefReadOnlyModifierOnLocals.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\NullPropagationTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\ProxyCallReplacer.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\StringToInt.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\UsingInstruction.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\InlineReturnTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\SwitchOnNullableTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\SwitchOnStringTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\TransformExpressionTrees.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\TupleTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\UsingTransform.cs\" />\r\n    <Compile Include=\"IL\\ControlFlow\\ControlFlowGraph.cs\" />\r\n    <Compile Include=\"IL\\ControlFlow\\StateRangeAnalysis.cs\" />\r\n    <Compile Include=\"IL\\ControlFlow\\SymbolicExecution.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\Await.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\ILVariableCollection.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\LockInstruction.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\NullCoalescingInstruction.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\LogicInstructions.cs\" />\r\n    <Compile Include=\"IL\\Patterns\\AnyNode.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\AssignVariableNames.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\DetectCatchWhenConditionBlocks.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\LockTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\NullableLiftingTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\NullCoalescingTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\StatementTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\TransformCollectionAndObjectInitializers.cs\" />\r\n    <Compile Include=\"Output\\TextTokenWriter.cs\" />\r\n    <Compile Include=\"DebugInfo\\IDebugInfoProvider.cs\" />\r\n    <Compile Include=\"DebugInfo\\PortablePdbWriter.cs\" />\r\n    <Compile Include=\"Semantics\\InterpolatedStringResolveResult.cs\" />\r\n    <Compile Include=\"SRMExtensions.cs\" />\r\n    <Compile Include=\"SRMHacks.cs\" />\r\n    <Compile Include=\"TypeSystem\\ApplyAttributeTypeVisitor.cs\" />\r\n    <Compile Include=\"TypeSystem\\GenericContext.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\AttributeListBuilder.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\CustomAttribute.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\DecimalConstantHelper.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\DecoratedType.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\DefaultTypeParameter.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\FakeMember.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\KnownAttributes.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\MetadataField.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\MetadataMethod.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\MetadataNamespace.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\MetadataParameter.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\MetadataEvent.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\MetadataProperty.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\MetadataTypeDefinition.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\MetadataTypeParameter.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\SpecializedParameter.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\SyntheticRangeIndexer.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\ThreeState.cs\" />\r\n    <Compile Include=\"TypeSystem\\MetadataModule.cs\" />\r\n    <Compile Include=\"TypeSystem\\ModifiedType.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\PinnedType.cs\" />\r\n    <Compile Include=\"Metadata\\MetadataExtensions.cs\" />\r\n    <Compile Include=\"Semantics\\ThrowResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\TupleResolveResult.cs\" />\r\n    <Compile Include=\"TypeSystem\\NormalizeTypeVisitor.cs\" />\r\n    <Compile Include=\"TypeSystem\\Nullability.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\NullabilityAnnotatedType.cs\" />\r\n    <Compile Include=\"TypeSystem\\TupleType.cs\" />\r\n    <Compile Include=\"TypeSystem\\TypeProvider.cs\" />\r\n    <Compile Include=\"Util\\FileUtility.cs\" />\r\n    <Compile Include=\"Util\\KeyComparer.cs\" />\r\n    <Compile Include=\"Util\\LongDict.cs\" />\r\n    <Compile Include=\"Util\\ResourcesFile.cs\" />\r\n    <Compile Include=\"Util\\ResXResourceWriter.cs\" />\r\n    <Compile Include=\"Util\\UnicodeNewline.cs\" />\r\n    <Compile Include=\"FlowAnalysis\\ControlFlowNode.cs\" />\r\n    <Compile Include=\"FlowAnalysis\\DataFlowVisitor.cs\" />\r\n    <Compile Include=\"FlowAnalysis\\DefiniteAssignmentVisitor.cs\" />\r\n    <Compile Include=\"FlowAnalysis\\Dominance.cs\" />\r\n    <Compile Include=\"FlowAnalysis\\ReachingDefinitionsVisitor.cs\" />\r\n    <Compile Include=\"CSharp\\Syntax\\IAnnotatable.cs\" />\r\n    <Compile Include=\"IL\\ControlFlow\\ConditionDetection.cs\" />\r\n    <Compile Include=\"IL\\ControlFlow\\ControlFlowSimplification.cs\" />\r\n    <Compile Include=\"IL\\ControlFlow\\DetectPinnedRegions.cs\" />\r\n    <Compile Include=\"IL\\ControlFlow\\ExitPoints.cs\" />\r\n    <Compile Include=\"IL\\ControlFlow\\LoopDetection.cs\" />\r\n    <Compile Include=\"IL\\ControlFlow\\SwitchAnalysis.cs\" />\r\n    <Compile Include=\"IL\\ControlFlow\\SwitchDetection.cs\" />\r\n    <Compile Include=\"IL\\Instructions.cs\">\r\n      <AutoGen>True</AutoGen>\r\n      <DesignTime>True</DesignTime>\r\n      <DependentUpon>Instructions.tt</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"IL\\Instructions\\Comp.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\BinaryNumericInstruction.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\Block.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\BlockContainer.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\Branch.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\CallInstruction.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\CompoundAssignmentInstruction.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\Conv.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\IfInstruction.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\ILFunction.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\ILInstruction.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\InstructionCollection.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\LdLen.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\Leave.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\MemoryInstructions.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\PatternMatching.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\SimpleInstruction.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\SwitchInstruction.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\TryInstruction.cs\" />\r\n    <Compile Include=\"IL\\Instructions\\UnaryInstruction.cs\" />\r\n    <Compile Include=\"IL\\Patterns\\ListMatch.cs\" />\r\n    <Compile Include=\"IL\\Patterns\\Match.cs\" />\r\n    <Compile Include=\"IL\\SlotInfo.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\BlockTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\CachedDelegateInitialization.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\CopyPropagation.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\IILTransform.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\ILInlining.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\ExpressionTransforms.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\DelegateConstruction.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\RemoveDeadVariableInit.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\SplitVariables.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\Stepper.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\TransformArrayInitializers.cs\" />\r\n    <Compile Include=\"Disassembler\\DisassemblerHelpers.cs\" />\r\n    <Compile Include=\"Disassembler\\ILStructure.cs\" />\r\n    <Compile Include=\"Disassembler\\MethodBodyDisassembler.cs\" />\r\n    <Compile Include=\"Disassembler\\ReflectionDisassembler.cs\" />\r\n    <Compile Include=\"IL\\SemanticHelper.cs\" />\r\n    <Compile Include=\"IL\\BlockBuilder.cs\" />\r\n    <Compile Include=\"Metadata\\ILOpCodes.cs\">\r\n      <AutoGen>True</AutoGen>\r\n      <DesignTime>True</DesignTime>\r\n      <DependentUpon>ILOpCodes.tt</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"IL\\ILReader.cs\" />\r\n    <Compile Include=\"IL\\ILTypeExtensions.cs\" />\r\n    <Compile Include=\"IL\\ILVariable.cs\" />\r\n    <Compile Include=\"IL\\InstructionFlags.cs\" />\r\n    <Compile Include=\"IL\\InstructionOutputExtensions.cs\" />\r\n    <Compile Include=\"IL\\PrimitiveType.cs\" />\r\n    <Compile Include=\"IL\\StackType.cs\" />\r\n    <Compile Include=\"IL\\Transforms\\TransformAssignment.cs\" />\r\n    <Compile Include=\"NRExtensions.cs\" />\r\n    <Compile Include=\"Output\\ITextOutput.cs\" />\r\n    <Compile Include=\"Output\\PlainTextOutput.cs\" />\r\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\r\n    <Compile Include=\"Output\\TextOutputWriter.cs\" />\r\n    <Compile Include=\"Semantics\\AmbiguousResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\ArrayAccessResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\ArrayCreateResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\ByReferenceResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\ConstantResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\Conversion.cs\" />\r\n    <Compile Include=\"Semantics\\ConversionResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\ErrorResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\ForEachResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\InitializedObjectResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\InvocationResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\LocalResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\MemberResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\NamedArgumentResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\NamespaceResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\OperatorResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\ResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\SizeOfResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\ThisResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\TypeIsResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\TypeOfResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\TypeResolveResult.cs\" />\r\n    <Compile Include=\"Semantics\\UnknownMemberResolveResult.cs\" />\r\n    <Compile Include=\"TypeSystem\\Accessibility.cs\" />\r\n    <Compile Include=\"TypeSystem\\ArrayType.cs\" />\r\n    <Compile Include=\"TypeSystem\\AssemblyQualifiedTypeName.cs\" />\r\n    <Compile Include=\"TypeSystem\\ByReferenceType.cs\" />\r\n    <Compile Include=\"TypeSystem\\ComHelper.cs\" />\r\n    <Compile Include=\"TypeSystem\\DecompilerTypeSystem.cs\" />\r\n    <Compile Include=\"TypeSystem\\FullTypeName.cs\" />\r\n    <Compile Include=\"Output\\IAmbience.cs\" />\r\n    <Compile Include=\"TypeSystem\\IAssembly.cs\" />\r\n    <Compile Include=\"TypeSystem\\IAttribute.cs\" />\r\n    <Compile Include=\"TypeSystem\\ICodeContext.cs\" />\r\n    <Compile Include=\"TypeSystem\\ICompilation.cs\" />\r\n    <Compile Include=\"TypeSystem\\IEntity.cs\" />\r\n    <Compile Include=\"TypeSystem\\IEvent.cs\" />\r\n    <Compile Include=\"TypeSystem\\IField.cs\" />\r\n    <Compile Include=\"TypeSystem\\IFreezable.cs\" />\r\n    <Compile Include=\"TypeSystem\\IInterningProvider.cs\" />\r\n    <Compile Include=\"TypeSystem\\IMember.cs\" />\r\n    <Compile Include=\"TypeSystem\\IMethod.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\AbstractFreezable.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\AbstractTypeParameter.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\AbstractType.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\BaseTypeCollector.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\DefaultAssemblyReference.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\DefaultAttribute.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\DefaultParameter.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\DefaultVariable.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\DummyTypeParameter.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\GetMembersHelper.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\KnownTypeCache.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\MergedNamespace.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\MinimalCorlib.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\NestedTypeReference.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\SimpleCompilation.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\SpecializedEvent.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\SpecializedField.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\SpecializedMember.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\SpecializedMethod.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\SpecializedProperty.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\TypeParameterReference.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\TypeWithElementType.cs\" />\r\n    <Compile Include=\"TypeSystem\\Implementation\\UnknownType.cs\" />\r\n    <Compile Include=\"TypeSystem\\INamedElement.cs\" />\r\n    <Compile Include=\"TypeSystem\\INamespace.cs\" />\r\n    <Compile Include=\"TypeSystem\\InheritanceHelper.cs\" />\r\n    <Compile Include=\"TypeSystem\\IntersectionType.cs\" />\r\n    <Compile Include=\"TypeSystem\\IParameter.cs\" />\r\n    <Compile Include=\"TypeSystem\\IParameterizedMember.cs\" />\r\n    <Compile Include=\"TypeSystem\\IProperty.cs\" />\r\n    <Compile Include=\"TypeSystem\\ISupportsInterning.cs\" />\r\n    <Compile Include=\"TypeSystem\\ISymbol.cs\" />\r\n    <Compile Include=\"TypeSystem\\IType.cs\" />\r\n    <Compile Include=\"TypeSystem\\ITypeDefinition.cs\" />\r\n    <Compile Include=\"TypeSystem\\ITypeParameter.cs\" />\r\n    <Compile Include=\"TypeSystem\\ITypeReference.cs\" />\r\n    <Compile Include=\"TypeSystem\\IVariable.cs\" />\r\n    <Compile Include=\"TypeSystem\\KnownTypeReference.cs\" />\r\n    <Compile Include=\"TypeSystem\\NullableType.cs\" />\r\n    <Compile Include=\"TypeSystem\\ParameterizedType.cs\" />\r\n    <Compile Include=\"TypeSystem\\ParameterListComparer.cs\" />\r\n    <Compile Include=\"TypeSystem\\PointerType.cs\" />\r\n    <Compile Include=\"TypeSystem\\ReflectionHelper.cs\" />\r\n    <Compile Include=\"TypeSystem\\ReflectionNameParseException.cs\" />\r\n    <Compile Include=\"TypeSystem\\SimpleTypeResolveContext.cs\" />\r\n    <Compile Include=\"TypeSystem\\SpecialType.cs\" />\r\n    <Compile Include=\"TypeSystem\\TaskType.cs\" />\r\n    <Compile Include=\"TypeSystem\\TopLevelTypeName.cs\" />\r\n    <Compile Include=\"TypeSystem\\TypeKind.cs\" />\r\n    <Compile Include=\"TypeSystem\\TypeParameterSubstitution.cs\" />\r\n    <Compile Include=\"TypeSystem\\TypeSystemExtensions.cs\" />\r\n    <Compile Include=\"TypeSystem\\TypeUtils.cs\" />\r\n    <Compile Include=\"TypeSystem\\IDecompilerTypeSystem.cs\" />\r\n    <Compile Include=\"TypeSystem\\ReferenceResolvingException.cs\" />\r\n    <Compile Include=\"TypeSystem\\TypeVisitor.cs\" />\r\n    <Compile Include=\"TypeSystem\\VarArgInstanceMethod.cs\" />\r\n    <Compile Include=\"Util\\BusyManager.cs\" />\r\n    <Compile Include=\"Util\\CacheManager.cs\" />\r\n    <Compile Include=\"Util\\CallbackOnDispose.cs\" />\r\n    <Compile Include=\"Util\\CollectionExtensions.cs\" />\r\n    <Compile Include=\"Util\\BitSet.cs\" />\r\n    <Compile Include=\"Util\\CSharpPrimitiveCast.cs\" />\r\n    <Compile Include=\"Util\\EmptyList.cs\" />\r\n    <Compile Include=\"Util\\ExtensionMethods.cs\" />\r\n    <Compile Include=\"Util\\GraphTraversal.cs\" />\r\n    <Compile Include=\"Util\\Interval.cs\" />\r\n    <Compile Include=\"Util\\LazyInit.cs\" />\r\n    <Compile Include=\"Util\\LongSet.cs\" />\r\n    <Compile Include=\"Util\\MultiDictionary.cs\" />\r\n    <Compile Include=\"Util\\Platform.cs\" />\r\n    <Compile Include=\"Util\\ProjectedList.cs\" />\r\n    <Compile Include=\"Util\\ReferenceComparer.cs\" />\r\n    <Compile Include=\"Util\\TreeTraversal.cs\" />\r\n    <Compile Include=\"Util\\UnionFind.cs\" />\r\n    <Compile Include=\"Util\\Win32Resources.cs\" />\r\n    <None Include=\"ICSharpCode.Decompiler.snk\" />\r\n    <None Include=\"Metadata\\ILOpCodes.tt\">\r\n      <Generator>TextTemplatingFileGenerator</Generator>\r\n      <LastGenOutput>ILOpCodes.cs</LastGenOutput>\r\n    </None>\r\n    <None Include=\"IL\\Instructions.tt\">\r\n      <Generator>TextTemplatingFileGenerator</Generator>\r\n      <LastGenOutput>Instructions.cs</LastGenOutput>\r\n    </None>\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <None Include=\"..\\doc\\Pattern Matching.html\">\r\n      <Link>CSharp\\Syntax\\PatternMatching\\Pattern Matching.html</Link>\r\n    </None>\r\n    <None Include=\"Humanizer\\LICENSE\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <Service Include=\"{508349b6-6b84-4df5-91f0-309beebad82d}\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <UpdateAssemblyInfoStamp Include=\"obj\\update-assemblyinfo-last-commit-hash.txt\" />\r\n  </ItemGroup>\r\n\r\n  <Target Name=\"ILSpyUpdateAssemblyInfo\" BeforeTargets=\"BeforeBuild\">\r\n    <PropertyGroup Condition=\" '$(OS)' == 'Windows_NT' \">\r\n      <UpdateAssemblyInfo>powershell -NoProfile -ExecutionPolicy Bypass -File BuildTools/update-assemblyinfo.ps1 $(Configuration)</UpdateAssemblyInfo>\r\n      <GitRevParse>git rev-parse HEAD^^{commit}</GitRevParse>\r\n    </PropertyGroup>\r\n    <PropertyGroup Condition=\" '$(OS)' != 'Windows_NT' \">\r\n      <UpdateAssemblyInfo>pwsh -NoProfile -ExecutionPolicy Bypass -File BuildTools/update-assemblyinfo.ps1 $(Configuration)</UpdateAssemblyInfo>\r\n      <GitRevParse>git rev-parse HEAD^{commit}</GitRevParse>\r\n    </PropertyGroup>\r\n    <ReadLinesFromFile ContinueOnError=\"true\" File=\"@(UpdateAssemblyInfoStamp)\">\r\n      <Output TaskParameter=\"Lines\" PropertyName=\"LastCommitHash\" />\r\n    </ReadLinesFromFile>\r\n    <Exec ContinueOnError=\"true\" WorkingDirectory=\"..\" Command=\"$(GitRevParse)\" ConsoleToMSBuild=\"true\">\r\n      <Output TaskParameter=\"ConsoleOutput\" PropertyName=\"CommitHash\" />\r\n    </Exec>\r\n    <Exec WorkingDirectory=\"..\" Command=\"$(UpdateAssemblyInfo)\" Timeout=\"60000\" Condition=\"'$(CommitHash)'!='$(LastCommitHash)'\" LogStandardErrorAsError=\"true\" ContinueOnError=\"false\" />\r\n    <WriteLinesToFile Lines=\"$(CommitHash)\" File=\"@(UpdateAssemblyInfoStamp)\" Overwrite=\"true\" Condition=\"'$(CommitHash)'!='$(LastCommitHash)'\" />\r\n    <ReadLinesFromFile ContinueOnError=\"true\" File=\"..\\VERSION\">\r\n      <Output TaskParameter=\"Lines\" PropertyName=\"PackageVersion\" />\r\n      <Output TaskParameter=\"Lines\" PropertyName=\"SbomGenerationPackageVersion\" />\r\n    </ReadLinesFromFile>\r\n  </Target>\r\n\r\n  <Target Name=\"CleanUpdateAssemblyInfo\" BeforeTargets=\"BeforeClean\">\r\n    <Delete Files=\"@(UpdateAssemblyInfoStamp);..\\VERSION\" />\r\n  </Target>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/BlockBuilder.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// Converts the list of basic blocks from ILReader into a BlockContainer structure. \n\t/// This involves creating nested block containers for exception handlers, and creating\n\t/// branches between the blocks.\n\t/// </summary>\n\tclass BlockBuilder\n\t{\n\t\treadonly MethodBodyBlock body;\n\t\treadonly Dictionary<ExceptionRegion, ILVariable> variableByExceptionHandler;\n\t\treadonly ICompilation compilation;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether to create extended basic blocks instead of basic blocks.\n\t\t/// The default is <c>false</c>.\n\t\t/// </summary>\n\t\tpublic bool CreateExtendedBlocks;\n\n\t\tinternal BlockBuilder(MethodBodyBlock body,\n\t\t\t\t\t\t\t  Dictionary<ExceptionRegion, ILVariable> variableByExceptionHandler,\n\t\t\t\t\t\t\t  ICompilation compilation)\n\t\t{\n\t\t\tDebug.Assert(body != null);\n\t\t\tDebug.Assert(variableByExceptionHandler != null);\n\t\t\tDebug.Assert(compilation != null);\n\t\t\tthis.body = body;\n\t\t\tthis.variableByExceptionHandler = variableByExceptionHandler;\n\t\t\tthis.compilation = compilation;\n\t\t}\n\n\t\tList<TryInstruction> tryInstructionList = new List<TryInstruction>();\n\t\treadonly Dictionary<int, BlockContainer> handlerContainers = new Dictionary<int, BlockContainer>();\n\n\t\tvoid CreateContainerStructure()\n\t\t{\n\t\t\tList<TryCatch> tryCatchList = new List<TryCatch>();\n\t\t\tforeach (var eh in body.ExceptionRegions)\n\t\t\t{\n\t\t\t\tvar tryRange = new Interval(eh.TryOffset, eh.TryOffset + eh.TryLength);\n\t\t\t\tvar handlerBlock = new BlockContainer();\n\t\t\t\thandlerBlock.AddILRange(new Interval(eh.HandlerOffset, eh.HandlerOffset + eh.HandlerLength));\n\t\t\t\thandlerContainers.Add(handlerBlock.StartILOffset, handlerBlock);\n\n\t\t\t\tif (eh.Kind == ExceptionRegionKind.Fault || eh.Kind == ExceptionRegionKind.Finally)\n\t\t\t\t{\n\t\t\t\t\tvar tryBlock = new BlockContainer();\n\t\t\t\t\ttryBlock.AddILRange(tryRange);\n\t\t\t\t\tif (eh.Kind == ExceptionRegionKind.Finally)\n\t\t\t\t\t\ttryInstructionList.Add(new TryFinally(tryBlock, handlerBlock).WithILRange(tryRange));\n\t\t\t\t\telse\n\t\t\t\t\t\ttryInstructionList.Add(new TryFault(tryBlock, handlerBlock).WithILRange(tryRange));\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// \n\t\t\t\tvar tryCatch = tryCatchList.FirstOrDefault(tc => tc.TryBlock.ILRanges.SingleOrDefault() == tryRange);\n\t\t\t\tif (tryCatch == null)\n\t\t\t\t{\n\t\t\t\t\tvar tryBlock = new BlockContainer();\n\t\t\t\t\ttryBlock.AddILRange(tryRange);\n\t\t\t\t\ttryCatch = new TryCatch(tryBlock);\n\t\t\t\t\ttryCatch.AddILRange(tryRange);\n\t\t\t\t\ttryCatchList.Add(tryCatch);\n\t\t\t\t\ttryInstructionList.Add(tryCatch);\n\t\t\t\t}\n\n\t\t\t\tILInstruction filter;\n\t\t\t\tif (eh.Kind == System.Reflection.Metadata.ExceptionRegionKind.Filter)\n\t\t\t\t{\n\t\t\t\t\tvar filterBlock = new BlockContainer(expectedResultType: StackType.I4);\n\t\t\t\t\tfilterBlock.AddILRange(new Interval(eh.FilterOffset, eh.HandlerOffset));\n\t\t\t\t\thandlerContainers.Add(filterBlock.StartILOffset, filterBlock);\n\t\t\t\t\tfilter = filterBlock;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfilter = new LdcI4(1);\n\t\t\t\t}\n\n\t\t\t\tvar handler = new TryCatchHandler(filter, handlerBlock, variableByExceptionHandler[eh]);\n\t\t\t\thandler.AddILRange(filter);\n\t\t\t\thandler.AddILRange(handlerBlock);\n\t\t\t\ttryCatch.Handlers.Add(handler);\n\t\t\t\ttryCatch.AddILRange(handler);\n\t\t\t}\n\t\t\tif (tryInstructionList.Count > 0)\n\t\t\t{\n\t\t\t\ttryInstructionList = tryInstructionList.OrderBy(tc => tc.TryBlock.StartILOffset).ThenByDescending(tc => tc.TryBlock.EndILOffset).ToList();\n\t\t\t\tnextTry = tryInstructionList[0];\n\t\t\t}\n\t\t}\n\n\t\tint currentTryIndex;\n\t\tTryInstruction? nextTry;\n\n\t\tBlockContainer? currentContainer;\n\t\treadonly Stack<BlockContainer> containerStack = new Stack<BlockContainer>();\n\n\t\tpublic void CreateBlocks(BlockContainer mainContainer, IEnumerable<Block> basicBlocks, CancellationToken cancellationToken)\n\t\t{\n\t\t\tCreateContainerStructure();\n\t\t\tmainContainer.SetILRange(new Interval(0, body.GetCodeSize()));\n\n\t\t\tcurrentContainer = mainContainer;\n\t\t\tforeach (var block in basicBlocks.OrderBy(b => b.StartILOffset))\n\t\t\t{\n\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tint start = block.StartILOffset;\n\t\t\t\t// Leave nested containers if necessary\n\t\t\t\twhile (start >= currentContainer.EndILOffset && containerStack.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tcurrentContainer = containerStack.Pop();\n\t\t\t\t}\n\t\t\t\t// Enter a handler if necessary\n\t\t\t\tif (handlerContainers.TryGetValue(start, out BlockContainer? handlerContainer))\n\t\t\t\t{\n\t\t\t\t\tcontainerStack.Push(currentContainer);\n\t\t\t\t\tcurrentContainer = handlerContainer;\n\t\t\t\t}\n\t\t\t\t// Enter a try block if necessary\n\t\t\t\twhile (nextTry != null && start == nextTry.TryBlock.StartILOffset)\n\t\t\t\t{\n\t\t\t\t\tvar blockForTry = new Block();\n\t\t\t\t\tblockForTry.SetILRange(nextTry);\n\t\t\t\t\tblockForTry.Instructions.Add(nextTry);\n\t\t\t\t\tcurrentContainer.Blocks.Add(blockForTry);\n\n\t\t\t\t\tcontainerStack.Push(currentContainer);\n\t\t\t\t\tcurrentContainer = (BlockContainer)nextTry.TryBlock;\n\n\t\t\t\t\tnextTry = tryInstructionList.ElementAtOrDefault(++currentTryIndex);\n\t\t\t\t}\n\t\t\t\tcurrentContainer.Blocks.Add(block);\n\t\t\t}\n\t\t\tDebug.Assert(currentTryIndex == tryInstructionList.Count && nextTry == null);\n\t\t\tConnectBranches(mainContainer, cancellationToken);\n\t\t\tCreateOnErrorDispatchers();\n\t\t}\n\n\t\tvoid ConnectBranches(ILInstruction inst, CancellationToken cancellationToken)\n\t\t{\n\t\t\tswitch (inst)\n\t\t\t{\n\t\t\t\tcase Branch branch:\n\t\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tDebug.Assert(branch.TargetBlock == null);\n\t\t\t\t\tvar targetBlock = FindBranchTarget(branch.TargetILOffset);\n\t\t\t\t\tif (targetBlock == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tbranch.ReplaceWith(new InvalidBranch(\"Could not find block for branch target \"\n\t\t\t\t\t\t\t+ Disassembler.DisassemblerHelpers.OffsetToString(branch.TargetILOffset)).WithILRange(branch));\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tbranch.TargetBlock = targetBlock;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase Leave leave:\n\t\t\t\t\t// ret (in void method) = leave(mainContainer)\n\t\t\t\t\t// endfinally = leave(null)\n\t\t\t\t\tif (leave.TargetContainer == null)\n\t\t\t\t\t{\n\t\t\t\t\t\t// assign the finally/filter container\n\t\t\t\t\t\tleave.TargetContainer = containerStack.Peek();\n\t\t\t\t\t\tleave.Value = ILReader.Cast(leave.Value, leave.TargetContainer.ExpectedResultType, null, leave.StartILOffset);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase BlockContainer container:\n\t\t\t\t\tcontainerStack.Push(container);\n\t\t\t\t\t// Note: FindBranchTarget()/CreateBranchTargetForOnErrorJump() may append to container.Blocks while we are iterating.\n\t\t\t\t\t// Don't process those artificial blocks here.\n\t\t\t\t\tint blockCount = container.Blocks.Count;\n\t\t\t\t\tfor (int i = 0; i < blockCount; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\t\tvar block = container.Blocks[i];\n\t\t\t\t\t\tConnectBranches(block, cancellationToken);\n\t\t\t\t\t\tif (block.Instructions.Count == 0 || !block.Instructions.Last().HasFlag(InstructionFlags.EndPointUnreachable))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tblock.Instructions.Add(new InvalidBranch(\"Unexpected end of block\"));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcontainerStack.Pop();\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tforeach (var child in inst.Children)\n\t\t\t\t\t\tConnectBranches(child, cancellationToken);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tBlock? FindBranchTarget(int targetILOffset)\n\t\t{\n\t\t\tforeach (var container in containerStack)\n\t\t\t{\n\t\t\t\tforeach (var block in container.Blocks)\n\t\t\t\t{\n\t\t\t\t\tif (block.StartILOffset == targetILOffset && !block.ILRangeIsEmpty)\n\t\t\t\t\t\treturn block;\n\t\t\t\t}\n\t\t\t\tif (container.SlotInfo == TryCatchHandler.BodySlot)\n\t\t\t\t{\n\t\t\t\t\t// catch handler is allowed to branch back into try block (VB On Error)\n\t\t\t\t\tTryCatch tryCatch = (TryCatch)container.Parent!.Parent!;\n\t\t\t\t\tif (tryCatch.TryBlock.StartILOffset < targetILOffset && targetILOffset < tryCatch.TryBlock.EndILOffset)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn CreateBranchTargetForOnErrorJump(tryCatch, targetILOffset);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\treadonly Dictionary<TryCatch, OnErrorDispatch> onErrorDispatchers = new Dictionary<TryCatch, OnErrorDispatch>();\n\n\t\tclass OnErrorDispatch\n\t\t{\n\t\t\tpublic readonly ILVariable Variable;\n\t\t\tpublic readonly HashSet<int> TargetILOffsets = new HashSet<int>();\n\t\t\tpublic readonly List<Branch> Branches = new List<Branch>();\n\n\t\t\tpublic OnErrorDispatch(ILVariable variable)\n\t\t\t{\n\t\t\t\tDebug.Assert(variable != null);\n\t\t\t\tthis.Variable = variable;\n\t\t\t}\n\t\t}\n\n\t\t/// Create a new block that sets a helper variable and then branches to the start of the try-catch\n\t\tBlock CreateBranchTargetForOnErrorJump(TryCatch tryCatch, int targetILOffset)\n\t\t{\n\t\t\tif (!onErrorDispatchers.TryGetValue(tryCatch, out var dispatch))\n\t\t\t{\n\t\t\t\tvar int32 = compilation.FindType(KnownTypeCode.Int32);\n\t\t\t\tvar newDispatchVar = new ILVariable(VariableKind.Local, int32, StackType.I4);\n\t\t\t\tnewDispatchVar.Name = $\"try{tryCatch.StartILOffset:x4}_dispatch\";\n\t\t\t\tdispatch = new OnErrorDispatch(newDispatchVar);\n\t\t\t\tonErrorDispatchers.Add(tryCatch, dispatch);\n\t\t\t}\n\t\t\tdispatch.TargetILOffsets.Add(targetILOffset);\n\n\t\t\tBlock block = new Block();\n\t\t\tblock.Instructions.Add(new StLoc(dispatch.Variable, new LdcI4(targetILOffset)));\n\t\t\tvar branch = new Branch(tryCatch.TryBlock.StartILOffset);\n\t\t\tblock.Instructions.Add(branch);\n\t\t\tdispatch.Branches.Add(branch);\n\t\t\tcontainerStack.Peek().Blocks.Add(block);\n\t\t\treturn block;\n\t\t}\n\n\t\t/// New variables introduced for the \"on error\" dispatchers\n\t\tpublic IEnumerable<ILVariable> OnErrorDispatcherVariables => onErrorDispatchers.Values.Select(d => d.Variable);\n\n\t\tvoid CreateOnErrorDispatchers()\n\t\t{\n\t\t\tforeach (var (tryCatch, dispatch) in onErrorDispatchers)\n\t\t\t{\n\t\t\t\tBlock block = (Block)tryCatch.Parent!;\n\t\t\t\t// Before the regular entry point of the try-catch, insert an. instruction that resets the dispatcher variable\n\t\t\t\tblock.Instructions.Insert(tryCatch.ChildIndex, new StLoc(dispatch.Variable, new LdcI4(-1)));\n\t\t\t\t// Split the block, so that we can introduce branches that jump directly into the try block\n\t\t\t\tint splitAt = tryCatch.ChildIndex;\n\t\t\t\tBlock newBlock = new Block();\n\t\t\t\tnewBlock.AddILRange(tryCatch);\n\t\t\t\tnewBlock.Instructions.AddRange(block.Instructions.Skip(splitAt));\n\t\t\t\tblock.Instructions.RemoveRange(splitAt, block.Instructions.Count - splitAt);\n\t\t\t\tblock.Instructions.Add(new Branch(newBlock));\n\t\t\t\t((BlockContainer)block.Parent!).Blocks.Add(newBlock);\n\t\t\t\t// Update the branches that jump directly into the try block\n\t\t\t\tforeach (var b in dispatch.Branches)\n\t\t\t\t{\n\t\t\t\t\tb.TargetBlock = newBlock;\n\t\t\t\t}\n\n\t\t\t\t// Inside the try-catch, create the dispatch switch\n\t\t\t\tBlockContainer tryBody = (BlockContainer)tryCatch.TryBlock;\n\t\t\t\tBlock dispatchBlock = new Block();\n\t\t\t\tdispatchBlock.AddILRange(new Interval(tryCatch.StartILOffset, tryCatch.StartILOffset + 1));\n\t\t\t\tvar switchInst = new SwitchInstruction(new LdLoc(dispatch.Variable));\n\t\t\t\tswitchInst.AddILRange(new Interval(tryCatch.StartILOffset, tryCatch.StartILOffset + 1));\n\t\t\t\tforeach (int offset in dispatch.TargetILOffsets)\n\t\t\t\t{\n\t\t\t\t\tvar targetBlock = tryBody.Blocks.FirstOrDefault(b => b.StartILOffset == offset && !b.ILRangeIsEmpty);\n\t\t\t\t\tILInstruction branchInst;\n\t\t\t\t\tif (targetBlock == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tbranchInst = new InvalidBranch(\"Could not find block for branch target \"\n\t\t\t\t\t\t\t\t\t\t\t\t\t+ Disassembler.DisassemblerHelpers.OffsetToString(offset));\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tbranchInst = new Branch(targetBlock);\n\t\t\t\t\t}\n\t\t\t\t\tswitchInst.Sections.Add(new SwitchSection { Labels = new LongSet(offset), Body = branchInst });\n\t\t\t\t}\n\t\t\t\tvar usedLabels = new LongSet(dispatch.TargetILOffsets.Select(offset => LongInterval.Inclusive(offset, offset)));\n\t\t\t\tswitchInst.Sections.Add(new SwitchSection { Labels = usedLabels.Invert(), Body = new Branch(tryBody.EntryPoint) });\n\t\t\t\tdispatchBlock.Instructions.Add(new InvalidExpression(\"ILSpy has introduced the following switch to emulate a goto from catch-block to try-block\") { Severity = \"Note\" });\n\t\t\t\tdispatchBlock.Instructions.Add(switchInst);\n\n\t\t\t\ttryBody.Blocks.Insert(0, dispatchBlock);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs",
    "content": "// Copyright (c) 2017 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.DebugInfo;\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.ControlFlow\n{\n\t/// <summary>\n\t/// Decompiler step for C# 5 async/await.\n\t/// </summary>\n\tpublic class AsyncAwaitDecompiler : IILTransform\n\t{\n\t\tinternal static bool IsCompilerGeneratedStateMachine(TypeDefinitionHandle type, MetadataReader metadata)\n\t\t{\n\t\t\tTypeDefinition td;\n\t\t\tif (type.IsNil || (td = metadata.GetTypeDefinition(type)).GetDeclaringType().IsNil)\n\t\t\t\treturn false;\n\t\t\tif (!(type.IsCompilerGenerated(metadata) || td.GetDeclaringType().IsCompilerGenerated(metadata)))\n\t\t\t\treturn false;\n\t\t\tforeach (var i in td.GetInterfaceImplementations())\n\t\t\t{\n\t\t\t\tvar tr = metadata.GetInterfaceImplementation(i).Interface.GetFullTypeName(metadata);\n\t\t\t\tif (!tr.IsNested && tr.TopLevelTypeName.Namespace == \"System.Runtime.CompilerServices\" && tr.TopLevelTypeName.Name == \"IAsyncStateMachine\")\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tinternal static bool IsCompilerGeneratedMainMethod(MetadataFile module, MethodDefinitionHandle method)\n\t\t{\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar definition = metadata.GetMethodDefinition(method);\n\t\t\tvar entrypoint = System.Reflection.Metadata.Ecma335.MetadataTokens.MethodDefinitionHandle(module.CorHeader?.EntryPointTokenOrRelativeVirtualAddress ?? 0);\n\t\t\treturn method == entrypoint && metadata.GetString(definition.Name).Equals(\"<Main>\", StringComparison.Ordinal);\n\t\t}\n\n\t\tenum AsyncMethodType\n\t\t{\n\t\t\tVoid,\n\t\t\tTask,\n\t\t\tTaskOfT,\n\t\t\tAsyncEnumerator,\n\t\t\tAsyncEnumerable\n\t\t}\n\n\t\tILTransformContext context;\n\n\t\t// These fields are set by MatchTaskCreationPattern() or MatchEnumeratorCreationNewObj()\n\t\tIType taskType; // return type of the async method; or IAsyncEnumerable{T}/IAsyncEnumerator{T}\n\t\tIType underlyingReturnType; // return type of the method (only the \"T\" for Task{T}), for async enumerators this is the type being yielded\n\t\tAsyncMethodType methodType;\n\t\tITypeDefinition stateMachineType;\n\t\tIType builderType;\n\t\tIField builderField;\n\t\tIField stateField;\n\t\tint initialState;\n\t\tDictionary<IField, ILVariable> fieldToParameterMap = new Dictionary<IField, ILVariable>();\n\t\tDictionary<ILVariable, ILVariable> cachedFieldToParameterMap = new Dictionary<ILVariable, ILVariable>();\n\t\tIField disposeModeField; // 'disposeMode' field (IAsyncEnumerable/IAsyncEnumerator only)\n\n\t\t// These fields are set by AnalyzeMoveNext():\n\t\tILFunction moveNextFunction;\n\t\tILVariable cachedStateVar; // variable in MoveNext that caches the stateField.\n\t\tTryCatch mainTryCatch;\n\t\tBlock setResultReturnBlock; // block that is jumped to for return statements\n\t\t\t\t\t\t\t\t\t// Note: for async enumerators, a jump to setResultReturnBlock is a 'yield break;'\n\t\tint finalState;       // final state after the setResultAndExitBlock\n\t\tbool finalStateKnown;\n\t\tILVariable resultVar; // the variable that gets returned by the setResultAndExitBlock\n\t\tBlock setResultYieldBlock; // block that is jumped to for 'yield return' statements\n\t\tILVariable doFinallyBodies;\n\n\t\t// These fields are set by AnalyzeStateMachine():\n\t\tint smallestAwaiterVarIndex;\n\t\tHashSet<Leave> moveNextLeaves = new HashSet<Leave>();\n\n\t\t// For each block containing an 'await', stores the awaiter variable, and the field storing the awaiter\n\t\t// across the yield point.\n\t\tDictionary<Block, (ILVariable awaiterVar, IField awaiterField)> awaitBlocks = new Dictionary<Block, (ILVariable awaiterVar, IField awaiterField)>();\n\n\t\tbool isVisualBasicStateMachine;\n\n\t\tint catchHandlerOffset;\n\t\tList<AsyncDebugInfo.Await> awaitDebugInfos = new List<AsyncDebugInfo.Await>();\n\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.AsyncAwait)\n\t\t\t\treturn; // abort if async/await decompilation is disabled\n\t\t\tthis.context = context;\n\t\t\tfieldToParameterMap.Clear();\n\t\t\tcachedFieldToParameterMap.Clear();\n\t\t\tawaitBlocks.Clear();\n\t\t\tawaitDebugInfos.Clear();\n\t\t\tmoveNextLeaves.Clear();\n\t\t\tif (!MatchTaskCreationPattern(function) && !MatchAsyncEnumeratorCreationPattern(function))\n\t\t\t\treturn;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tAnalyzeMoveNext();\n\t\t\t\tValidateCatchBlock();\n\t\t\t\tAnalyzeDisposeAsync();\n\t\t\t}\n\t\t\tcatch (SymbolicAnalysisFailedException)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tInlineBodyOfMoveNext(function);\n\t\t\tfunction.CheckInvariant(ILPhase.InAsyncAwait);\n\t\t\tCleanUpBodyOfMoveNext(function);\n\t\t\tfunction.CheckInvariant(ILPhase.InAsyncAwait);\n\n\t\t\tAnalyzeStateMachine(function);\n\t\t\tDetectAwaitPattern(function);\n\t\t\tCleanDoFinallyBodies(function);\n\n\t\t\tcontext.Step(\"Translate fields to local accesses\", function);\n\t\t\tYieldReturnDecompiler.TranslateFieldsToLocalAccess(function, function, fieldToParameterMap);\n\t\t\tTranslateCachedFieldsToLocals();\n\n\t\t\tFinalizeInlineMoveNext(function);\n\t\t\tif (methodType == AsyncMethodType.AsyncEnumerable || methodType == AsyncMethodType.AsyncEnumerator)\n\t\t\t{\n\t\t\t\t((BlockContainer)function.Body).ExpectedResultType = StackType.Void;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t((BlockContainer)function.Body).ExpectedResultType = underlyingReturnType.GetStackType();\n\t\t\t}\n\n\t\t\t// Re-run control flow simplification over the newly constructed set of gotos,\n\t\t\t// and inlining because TranslateFieldsToLocalAccess() might have opened up new inlining opportunities.\n\t\t\tfunction.RunTransforms(CSharpDecompiler.EarlyILTransforms(), context);\n\n\t\t\tif (!isVisualBasicStateMachine)\n\t\t\t{\n\t\t\t\tcontext.StepStartGroup(\"AwaitInCatchTransform\");\n\t\t\t\tAwaitInCatchTransform.Run(function, context);\n\t\t\t\tcontext.StepEndGroup();\n\t\t\t\tcontext.StepStartGroup(\"AwaitInFinallyTransform\");\n\t\t\t\tAwaitInFinallyTransform.Run(function, context);\n\t\t\t\tcontext.StepEndGroup();\n\t\t\t}\n\n\t\t\tawaitDebugInfos.SortBy(row => row.YieldOffset);\n\t\t\tfunction.AsyncDebugInfo = new AsyncDebugInfo(catchHandlerOffset, awaitDebugInfos.ToImmutableArray());\n\t\t}\n\n\t\tprivate void CleanUpBodyOfMoveNext(ILFunction function)\n\t\t{\n\t\t\tcontext.StepStartGroup(\"CleanUpBodyOfMoveNext\", function);\n\t\t\t// Copy-propagate stack slots holding an 'ldloca':\n\t\t\tforeach (var stloc in function.Descendants.OfType<StLoc>().Where(s => s.Variable.Kind == VariableKind.StackSlot && s.Variable.IsSingleDefinition && s.Value is LdLoca).ToList())\n\t\t\t{\n\t\t\t\tCopyPropagation.Propagate(stloc, context);\n\t\t\t}\n\n\t\t\t// Simplify stobj(ldloca) -> stloc\n\t\t\tforeach (var stobj in function.Descendants.OfType<StObj>())\n\t\t\t{\n\t\t\t\tEarlyExpressionTransforms.StObjToStLoc(stobj, context);\n\t\t\t}\n\n\t\t\tif (isVisualBasicStateMachine)\n\t\t\t{\n\t\t\t\t// Visual Basic state machines often contain stack slots for ldflda instruction for the builder field.\n\t\t\t\t// This messes up the matching code in AnalyzeAwaitBlock() and causes it to fail.\n\t\t\t\t// Propagating these stack stores makes the matching code work without the need for a lot of\n\t\t\t\t// additional matching code to handle these stack slots.\n\t\t\t\tforeach (var stloc in function.Descendants.OfType<StLoc>().Where(s => s.Variable.Kind == VariableKind.StackSlot && s.Variable.IsSingleDefinition\n\t\t\t\t\t\t\t&& s.Value.MatchLdFlda(out var target, out var field) && field.Equals(builderField) && target.MatchLdThis()).ToList())\n\t\t\t\t{\n\t\t\t\t\tCopyPropagation.Propagate(stloc, context);\n\t\t\t\t}\n\n\t\t\t\t// Remove lone 'ldc.i4', present in older Roslyn VB compiler output\n\t\t\t\tforeach (var block in function.Descendants.OfType<Block>())\n\t\t\t\t\tblock.Instructions.RemoveAll(inst => inst.OpCode == OpCode.LdcI4);\n\t\t\t}\n\n\t\t\t// Copy-propagate temporaries holding a copy of 'this'.\n\t\t\tforeach (var stloc in function.Descendants.OfType<StLoc>().Where(s => s.Variable.IsSingleDefinition && s.Value.MatchLdThis()).ToList())\n\t\t\t{\n\t\t\t\tCopyPropagation.Propagate(stloc, context);\n\t\t\t}\n\t\t\tnew RemoveDeadVariableInit().Run(function, context);\n\t\t\tforeach (var block in function.Descendants.OfType<Block>())\n\t\t\t{\n\t\t\t\t// Run inlining, but don't remove dead variables (they might get revived by TranslateFieldsToLocalAccess)\n\t\t\t\tILInlining.InlineAllInBlock(function, block, InliningOptions.None, context);\n\t\t\t\tif (IsAsyncEnumerator)\n\t\t\t\t{\n\t\t\t\t\t// Remove lone 'ldc.i4', those are sometimes left over after C# compiler\n\t\t\t\t\t// optimizes out stores to the state variable.\n\t\t\t\t\tblock.Instructions.RemoveAll(inst => inst.OpCode == OpCode.LdcI4);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontext.StepEndGroup();\n\t\t}\n\n\t\t#region MatchTaskCreationPattern\n\t\tbool MatchTaskCreationPattern(ILFunction function)\n\t\t{\n\t\t\tif (!(function.Body is BlockContainer blockContainer))\n\t\t\t\treturn false;\n\t\t\tif (blockContainer.Blocks.Count != 1)\n\t\t\t\treturn false;\n\t\t\tvar body = blockContainer.EntryPoint.Instructions;\n\t\t\tif (body.Count < 4)\n\t\t\t\treturn false;\n\t\t\t/* Example:\n\t\t\t\tV_0 is an instance of the compiler-generated struct/class,\n\t\t\t\tV_1 is an instance of the builder struct/class\n\t\t\t\tBlock IL_0000 (incoming: 1)  {\n\t\t\t\t\t...\n\t\t\t\t\tstobj AsyncVoidMethodBuilder(ldflda [Field Async+<AwaitYield>d__3.<>t__builder](ldloca V_0), call Create())\n\t\t\t\t\tstobj System.Int32(ldflda [Field Async+<AwaitYield>d__3.<>1__state](ldloca V_0), ldc.i4 -1)\n\t\t\t\t\tstloc V_1(ldobj System.Runtime.CompilerServices.AsyncVoidMethodBuilder(ldflda [Field Async+<AwaitYield>d__3.<>t__builder](ldloc V_0)))\n\t\t\t\t\tcall Start(ldloca V_1, ldloca V_0)\n\t\t\t\t\tleave IL_0000 (or ret for non-void async methods)\n\t\t\t\t}\n\t\t\t\tWith custom task types, it's possible that the builder is a reference type.\n\t\t\t\tIn that case, the variable V_1 may be inlined.\n\t\t\t*/\n\n\t\t\t// Check the second-to-last instruction (the start call) first, as we can get the most information from that\n\t\t\tint pos = body.Count - 2;\n\t\t\tif (!(body[pos] is CallInstruction startCall))\n\t\t\t\treturn false;\n\t\t\tif (startCall.Method.Name != \"Start\")\n\t\t\t\treturn false;\n\t\t\ttaskType = function.Method.ReturnType;\n\t\t\tbuilderType = startCall.Method.DeclaringType;\n\t\t\tFullTypeName builderTypeName;\n\t\t\tif (builderType?.GetDefinitionOrUnknown() is { } builderTypeDef)\n\t\t\t{\n\t\t\t\tbuilderTypeName = builderTypeDef.FullTypeName;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (taskType.IsKnownType(KnownTypeCode.Void))\n\t\t\t{\n\t\t\t\tmethodType = AsyncMethodType.Void;\n\t\t\t\tunderlyingReturnType = taskType;\n\t\t\t\tif (builderTypeName != new TopLevelTypeName(\"System.Runtime.CompilerServices\", \"AsyncVoidMethodBuilder\"))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (TaskType.IsNonGenericTaskType(taskType, out var builderTypeNameFromTask))\n\t\t\t{\n\t\t\t\tmethodType = AsyncMethodType.Task;\n\t\t\t\tunderlyingReturnType = context.TypeSystem.FindType(KnownTypeCode.Void);\n\t\t\t\tif (builderTypeNameFromTask != builderTypeName)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (TaskType.IsGenericTaskType(taskType, out builderTypeNameFromTask))\n\t\t\t{\n\t\t\t\tmethodType = AsyncMethodType.TaskOfT;\n\t\t\t\tif (taskType.IsKnownType(KnownTypeCode.TaskOfT))\n\t\t\t\t\tunderlyingReturnType = TaskType.UnpackTask(context.TypeSystem, taskType);\n\t\t\t\telse\n\t\t\t\t\tunderlyingReturnType = startCall.Method.DeclaringType.TypeArguments[0];\n\t\t\t\tif (builderTypeNameFromTask != builderTypeName)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (startCall.Arguments.Count != 2)\n\t\t\t\treturn false;\n\t\t\tILInstruction loadBuilderExpr = startCall.Arguments[0];\n\t\t\tif (!startCall.Arguments[1].MatchLdLoca(out ILVariable stateMachineVar))\n\t\t\t\treturn false;\n\t\t\tstateMachineType = stateMachineVar.Type.GetDefinition();\n\t\t\tif (stateMachineType == null)\n\t\t\t\treturn false;\n\t\t\tpos--;\n\n\t\t\tif (loadBuilderExpr.MatchLdLocRef(out ILVariable builderVar))\n\t\t\t{\n\t\t\t\t// Check third-to-last instruction (copy of builder)\n\t\t\t\t// stloc builder(ldfld StateMachine::<>t__builder(ldloc stateMachine))\n\t\t\t\tif (!body[pos].MatchStLoc(builderVar, out loadBuilderExpr))\n\t\t\t\t\treturn false;\n\t\t\t\tpos--;\n\t\t\t}\n\t\t\tif (loadBuilderExpr.MatchLdFld(out var loadStateMachineForBuilderExpr, out builderField))\n\t\t\t{\n\t\t\t\t// OK, calling Start on copy of stateMachine.<>t__builder\n\t\t\t}\n\t\t\telse if (loadBuilderExpr.MatchLdFlda(out loadStateMachineForBuilderExpr, out builderField))\n\t\t\t{\n\t\t\t\t// OK, Roslyn 3.6 started directly calling Start without making a copy\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tbuilderField = (IField)builderField.MemberDefinition;\n\t\t\tif (!(loadStateMachineForBuilderExpr.MatchLdLocRef(stateMachineVar) || loadStateMachineForBuilderExpr.MatchLdLoc(stateMachineVar)))\n\t\t\t\treturn false;\n\n\t\t\t// Check the last instruction (ret)\n\t\t\tif (methodType == AsyncMethodType.Void)\n\t\t\t{\n\t\t\t\tif (!body.Last().MatchLeave(blockContainer))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// ret(call(AsyncTaskMethodBuilder::get_Task, ldflda(StateMachine::<>t__builder, ldloca(stateMachine))))\n\t\t\t\tif (!body.Last().MatchReturn(out var returnValue))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!MatchCall(returnValue, \"get_Task\", out var getTaskArgs) || getTaskArgs.Count != 1)\n\t\t\t\t\treturn false;\n\t\t\t\tILInstruction target;\n\t\t\t\tIField builderField2;\n\t\t\t\tif (builderType.IsReferenceType == true)\n\t\t\t\t{\n\t\t\t\t\tif (!getTaskArgs[0].MatchLdFld(out target, out builderField2))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (!getTaskArgs[0].MatchLdFlda(out target, out builderField2))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (builderField2.MemberDefinition != builderField)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(target.MatchLdLoc(stateMachineVar) || target.MatchLdLoca(stateMachineVar)))\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (IsPotentialVisualBasicStateMachineInitialiation(body[0], stateMachineVar))\n\t\t\t{\n\t\t\t\t// Visual Basic compiler uses a different order of field assignements\n\t\t\t\tif (MatchVisualBasicStateMachineFieldAssignements(body, stateMachineVar))\n\t\t\t\t{\n\t\t\t\t\tisVisualBasicStateMachine = true;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\t// If the Visual Basic matching code failed, reset the map in case it\n\t\t\t\t// was partially populated and try matching the C# state machine initialization.\n\t\t\t\tfieldToParameterMap.Clear();\n\t\t\t}\n\n\t\t\t// Check the last field assignment - this should be the state field\n\t\t\t// stfld <>1__state(ldloca stateField, ldc.i4 -1)\n\t\t\tif (!MatchStFld(body[pos], stateMachineVar, out stateField, out var initialStateExpr))\n\t\t\t\treturn false;\n\t\t\tif (!initialStateExpr.MatchLdcI4(out initialState))\n\t\t\t\treturn false;\n\t\t\tif (initialState != -1)\n\t\t\t\treturn false;\n\n\t\t\tint stopPos = pos;\n\t\t\tpos = 0;\n\t\t\tif (stateMachineType.Kind == TypeKind.Class)\n\t\t\t{\n\t\t\t\t// If state machine is a class, the first instruction creates an instance:\n\t\t\t\t// stloc stateMachine(newobj StateMachine.ctor())\n\t\t\t\tif (!body[pos].MatchStLoc(stateMachineVar, out var init))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(init is NewObj newobj && newobj.Arguments.Count == 0 && newobj.Method.DeclaringTypeDefinition == stateMachineType))\n\t\t\t\t\treturn false;\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\tbool builderFieldIsInitialized = false;\n\t\t\tfor (; pos < stopPos; pos++)\n\t\t\t{\n\t\t\t\t// stfld StateMachine.field(ldloca stateMachine, ldvar(param))\n\t\t\t\tif (!MatchStFld(body[pos], stateMachineVar, out var field, out var fieldInit))\n\t\t\t\t\treturn false;\n\t\t\t\tif (field == builderField)\n\t\t\t\t{\n\t\t\t\t\t// stfld StateMachine.builder(ldloca stateMachine, call Create())\n\t\t\t\t\tif (!(fieldInit is Call { Method: { Name: \"Create\" }, Arguments: { Count: 0 } }))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tbuilderFieldIsInitialized = true;\n\t\t\t\t}\n\t\t\t\telse if (fieldInit.MatchLdLoc(out var v) && v.Kind == VariableKind.Parameter)\n\t\t\t\t{\n\t\t\t\t\t// OK, copies parameter into state machine\n\t\t\t\t\tfieldToParameterMap[field] = v;\n\t\t\t\t}\n\t\t\t\telse if (fieldInit is LdObj ldobj && ldobj.Target.MatchLdThis())\n\t\t\t\t{\n\t\t\t\t\t// stfld <>4__this(ldloc stateMachine, ldobj AsyncInStruct(ldloc this))\n\t\t\t\t\tfieldToParameterMap[field] = ((LdLoc)ldobj.Target).Variable;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn builderFieldIsInitialized;\n\t\t}\n\n\t\tbool IsPotentialVisualBasicStateMachineInitialiation(ILInstruction inst, ILVariable stateMachineVar)\n\t\t{\n\t\t\t// stobj VB$StateMachine(ldloca stateMachine, default.value VB$StateMachine)\n\t\t\t// Used by VBC (Debug and Release) and Roslyn VB (Release) builds\n\t\t\tif (inst.MatchStObj(out var target, out var val, out var type1) && target.MatchLdLoca(stateMachineVar) &&\n\t\t\t\tval.MatchDefaultValue(out var type2) && type1.Equals(type2))\n\t\t\t\treturn true;\n\t\t\t// stloc stateMachine(newobj VB$StateMachine..ctor())\n\t\t\t// Used by Roslyn VB (Debug) builds\n\t\t\tif (inst.MatchStLoc(stateMachineVar, out var init) && init is NewObj newObj && newObj.Arguments.Count == 0 &&\n\t\t\t\tstateMachineType.Equals(newObj.Method.DeclaringTypeDefinition))\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\n\t\tbool MatchVisualBasicStateMachineFieldAssignements(IList<ILInstruction> body, ILVariable stateMachineVar)\n\t\t{\n\t\t\t// stfld $State(ldloca stateField, ldc.i4 -1)\n\t\t\tif (!MatchStFld(body[body.Count - 4], stateMachineVar, out stateField, out var initialStateExpr))\n\t\t\t\treturn false;\n\t\t\tif (!initialStateExpr.MatchLdcI4(out initialState))\n\t\t\t\treturn false;\n\t\t\tif (initialState != -1)\n\t\t\t\treturn false;\n\n\t\t\t// stfld $Builder(ldloca stateMachine, call Create())\n\t\t\tif (!MatchStFld(body[body.Count - 3], stateMachineVar, out var builderField2, out var fieldInit))\n\t\t\t\treturn false;\n\t\t\tif (!builderField.Equals(builderField2))\n\t\t\t\treturn false;\n\t\t\tif (fieldInit is not Call { Method: { Name: \"Create\" }, Arguments: { Count: 0 } })\n\t\t\t\treturn false;\n\n\t\t\tfor (int i = 1; i < body.Count - 4; i++)\n\t\t\t{\n\t\t\t\tif (!MatchStFld(body[i], stateMachineVar, out var field, out fieldInit))\n\t\t\t\t\treturn false;\n\t\t\t\t// Legacy Visual Basic compiler can emit a call to RuntimeHelpers.GetObjectValue here\n\t\t\t\tif (fieldInit is Call call && call.Arguments.Count == 1 && call.Method.IsStatic && call.Method.Name == \"GetObjectValue\")\n\t\t\t\t\tfieldInit = call.Arguments[0];\n\t\t\t\tif (fieldInit.MatchLdLoc(out var v) && v.Kind == VariableKind.Parameter)\n\t\t\t\t{\n\t\t\t\t\t// OK, copies parameter into state machine\n\t\t\t\t\tfieldToParameterMap[field] = v;\n\t\t\t\t}\n\t\t\t\telse if (fieldInit is LdObj ldobj && ldobj.Target.MatchLdThis())\n\t\t\t\t{\n\t\t\t\t\t// stfld <>4__this(ldloc stateMachine, ldobj AsyncInStruct(ldloc this))\n\t\t\t\t\tfieldToParameterMap[field] = ((LdLoc)ldobj.Target).Variable;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches a (potentially virtual) instance method call.\n\t\t/// </summary>\n\t\tstatic bool MatchCall(ILInstruction inst, string name, out InstructionCollection<ILInstruction> args)\n\t\t{\n\t\t\tif (inst is CallInstruction call && (call.OpCode == OpCode.Call || call.OpCode == OpCode.CallVirt)\n\t\t\t\t&& call.Method.Name == name && !call.Method.IsStatic)\n\t\t\t{\n\t\t\t\targs = call.Arguments;\n\t\t\t\treturn args.Count > 0;\n\t\t\t}\n\t\t\targs = null;\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches a store to the state machine.\n\t\t/// </summary>\n\t\tstatic bool MatchStFld(ILInstruction stfld, ILVariable stateMachineVar, out IField field, out ILInstruction value)\n\t\t{\n\t\t\tif (!stfld.MatchStFld(out var target, out field, out value))\n\t\t\t\treturn false;\n\t\t\tfield = field.MemberDefinition as IField;\n\t\t\treturn field != null && target.MatchLdLocRef(stateMachineVar);\n\t\t}\n\t\t#endregion\n\n\t\t#region MatchAsyncEnumeratorCreationPattern\n\t\tprivate bool MatchAsyncEnumeratorCreationPattern(ILFunction function)\n\t\t{\n\t\t\tif (!context.Settings.AsyncEnumerator)\n\t\t\t\treturn false;\n\t\t\ttaskType = function.ReturnType;\n\t\t\tif (taskType.IsKnownType(KnownTypeCode.IAsyncEnumeratorOfT))\n\t\t\t{\n\t\t\t\tmethodType = AsyncMethodType.AsyncEnumerator;\n\t\t\t}\n\t\t\telse if (taskType.IsKnownType(KnownTypeCode.IAsyncEnumerableOfT))\n\t\t\t{\n\t\t\t\tmethodType = AsyncMethodType.AsyncEnumerable;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tunderlyingReturnType = taskType.TypeArguments.Single();\n\t\t\tif (!(function.Body is BlockContainer blockContainer))\n\t\t\t\treturn false;\n\t\t\tif (blockContainer.Blocks.Count != 1)\n\t\t\t\treturn false;\n\t\t\tvar body = blockContainer.EntryPoint;\n\t\t\tif (body.Instructions.Count == 1)\n\t\t\t{\n\t\t\t\t// No parameters passed to enumerator (not even 'this'):\n\t\t\t\t// ret(newobj(...))\n\t\t\t\tif (!body.Instructions[0].MatchReturn(out var newObj))\n\t\t\t\t\treturn false;\n\t\t\t\tif (MatchEnumeratorCreationNewObj(newObj, context, out initialState, out stateMachineType))\n\t\t\t\t{\n\t\t\t\t\t// HACK: the normal async/await logic expects 'initialState' to be the 'in progress' state\n\t\t\t\t\tinitialState = -1;\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tAnalyzeEnumeratorCtor(((NewObj)newObj).Method, context, out builderField, out builderType, out stateField);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (SymbolicAnalysisFailedException)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\n\t\t\t\t// stloc v(newobj<CountUpSlowly> d__0..ctor(ldc.i4 - 2))\n\t\t\t\t// stfld <>4__this(ldloc v, ldloc this)\n\t\t\t\t// stfld <>3__otherParam(ldloc v, ldloc otherParam)\n\t\t\t\t// leave IL_0000(ldloc v)\n\t\t\t\tint pos = 0;\n\t\t\t\tif (!body.Instructions[pos].MatchStLoc(out var v, out var newObj))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!MatchEnumeratorCreationNewObj(newObj, context, out initialState, out stateMachineType))\n\t\t\t\t\treturn false;\n\t\t\t\tpos++;\n\n\t\t\t\twhile (MatchStFld(body.Instructions[pos], v, out var field, out var value))\n\t\t\t\t{\n\t\t\t\t\tif (value.MatchLdLoc(out var p) && p.Kind == VariableKind.Parameter)\n\t\t\t\t\t{\n\t\t\t\t\t\tfieldToParameterMap[field] = p;\n\t\t\t\t\t}\n\t\t\t\t\telse if (value is LdObj ldobj && ldobj.Target.MatchLdThis())\n\t\t\t\t\t{\n\t\t\t\t\t\tfieldToParameterMap[field] = ((LdLoc)ldobj.Target).Variable;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t\tif (!body.Instructions[pos].MatchReturn(out var returnValue))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!returnValue.MatchLdLoc(v))\n\t\t\t\t\treturn false;\n\n\t\t\t\t// HACK: the normal async/await logic expects 'initialState' to be the 'in progress' state\n\t\t\t\tinitialState = -1;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tAnalyzeEnumeratorCtor(((NewObj)newObj).Method, context, out builderField, out builderType, out stateField);\n\t\t\t\t\tif (methodType == AsyncMethodType.AsyncEnumerable)\n\t\t\t\t\t{\n\t\t\t\t\t\tResolveIEnumerableIEnumeratorFieldMapping();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (SymbolicAnalysisFailedException)\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tstatic bool MatchEnumeratorCreationNewObj(ILInstruction inst, ILTransformContext context,\n\t\t\tout int initialState, out ITypeDefinition stateMachineType)\n\t\t{\n\t\t\tinitialState = default;\n\t\t\tstateMachineType = default;\n\t\t\t// newobj(CurrentType/...::.ctor, ldc.i4(-2))\n\t\t\tif (!(inst is NewObj newObj))\n\t\t\t\treturn false;\n\t\t\tif (newObj.Arguments.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (!newObj.Arguments[0].MatchLdcI4(out initialState))\n\t\t\t\treturn false;\n\t\t\tstateMachineType = newObj.Method.DeclaringTypeDefinition;\n\t\t\tif (stateMachineType == null)\n\t\t\t\treturn false;\n\t\t\tif (stateMachineType.DeclaringTypeDefinition != context.Function.Method.DeclaringTypeDefinition)\n\t\t\t\treturn false;\n\t\t\treturn IsCompilerGeneratorAsyncEnumerator(\n\t\t\t\t(TypeDefinitionHandle)stateMachineType.MetadataToken,\n\t\t\t\tcontext.TypeSystem.MainModule.metadata);\n\t\t}\n\n\t\tpublic static bool IsCompilerGeneratorAsyncEnumerator(TypeDefinitionHandle type, MetadataReader metadata)\n\t\t{\n\t\t\tTypeDefinition td;\n\t\t\tif (type.IsNil || !type.IsCompilerGeneratedOrIsInCompilerGeneratedClass(metadata) || (td = metadata.GetTypeDefinition(type)).GetDeclaringType().IsNil)\n\t\t\t\treturn false;\n\t\t\tforeach (var i in td.GetInterfaceImplementations())\n\t\t\t{\n\t\t\t\tvar tr = metadata.GetInterfaceImplementation(i).Interface.GetFullTypeName(metadata);\n\t\t\t\tif (!tr.IsNested && tr.TopLevelTypeName.Namespace == \"System.Collections.Generic\" && tr.TopLevelTypeName.Name == \"IAsyncEnumerator\" && tr.TopLevelTypeName.TypeParameterCount == 1)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tstatic void AnalyzeEnumeratorCtor(IMethod ctor, ILTransformContext context, out IField builderField, out IType builderType, out IField stateField)\n\t\t{\n\t\t\tbuilderField = null;\n\t\t\tstateField = null;\n\n\t\t\tvar ctorHandle = (MethodDefinitionHandle)ctor.MetadataToken;\n\t\t\tBlock body = YieldReturnDecompiler.SingleBlock(YieldReturnDecompiler.CreateILAst(ctorHandle, context).Body);\n\t\t\tif (body == null)\n\t\t\t\tthrow new SymbolicAnalysisFailedException(\"Missing enumeratorCtor.Body\");\n\t\t\t// Block IL_0000 (incoming: 1) {\n\t\t\t//   call Object..ctor(ldloc this)\n\t\t\t// \t stfld <>1__state(ldloc this, ldloc <>1__state)\n\t\t\t// \t stfld <>t__builder(ldloc this, call Create())\n\t\t\t// \t leave IL_0000 (nop)\n\t\t\t// }\n\t\t\tforeach (var inst in body.Instructions)\n\t\t\t{\n\t\t\t\tif (inst.MatchStFld(out var target, out var field, out var value)\n\t\t\t\t&& target.MatchLdThis()\n\t\t\t\t&& value.MatchLdLoc(out var arg)\n\t\t\t\t&& arg.Kind == VariableKind.Parameter && arg.Index == 0)\n\t\t\t\t{\n\t\t\t\t\tstateField = (IField)field.MemberDefinition;\n\t\t\t\t}\n\t\t\t\tif (inst.MatchStFld(out target, out field, out value)\n\t\t\t\t\t&& target.MatchLdThis()\n\t\t\t\t\t&& value is Call call && call.Method.Name == \"Create\")\n\t\t\t\t{\n\t\t\t\t\tbuilderField = (IField)field.MemberDefinition;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (stateField == null || builderField == null)\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\n\t\t\tbuilderType = builderField.Type;\n\t\t\tif (builderType == null)\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t}\n\n\t\tprivate void ResolveIEnumerableIEnumeratorFieldMapping()\n\t\t{\n\t\t\tvar getAsyncEnumerator = stateMachineType.Methods.FirstOrDefault(m => m.Name.EndsWith(\".GetAsyncEnumerator\", StringComparison.Ordinal));\n\t\t\tif (getAsyncEnumerator == null)\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\tYieldReturnDecompiler.ResolveIEnumerableIEnumeratorFieldMapping((MethodDefinitionHandle)getAsyncEnumerator.MetadataToken, context, fieldToParameterMap);\n\t\t}\n\t\t#endregion\n\n\t\t#region AnalyzeMoveNext\n\t\t/// <summary>\n\t\t/// First peek into MoveNext(); analyzes everything outside the big try-catch.\n\t\t/// </summary>\n\t\tvoid AnalyzeMoveNext()\n\t\t{\n\t\t\tif (stateMachineType.MetadataToken.IsNil)\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\tvar metadata = context.PEFile.Metadata;\n\t\t\tvar moveNextMethod = metadata.GetTypeDefinition((TypeDefinitionHandle)stateMachineType.MetadataToken)\n\t\t\t\t.GetMethods().FirstOrDefault(f => metadata.GetString(metadata.GetMethodDefinition(f).Name) == \"MoveNext\");\n\t\t\tif (moveNextMethod == null)\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\tmoveNextFunction = YieldReturnDecompiler.CreateILAst(moveNextMethod, context);\n\t\t\tif (!(moveNextFunction.Body is BlockContainer blockContainer))\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\tif (blockContainer.EntryPoint.IncomingEdgeCount != 1)\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\tbool[] blocksAnalyzed = new bool[blockContainer.Blocks.Count];\n\t\t\tcachedStateVar = null;\n\t\t\tint pos = 0;\n\t\t\t// Visual Basic state machines initialize doFinallyBodies at the start of MoveNext()\n\t\t\t// stloc doFinallyBodies(ldc.i4 1)\n\t\t\tif (isVisualBasicStateMachine && blockContainer.EntryPoint.Instructions[pos].MatchStLoc(out var v, out var ldci4) &&\n\t\t\t\tldci4.MatchLdcI4(1))\n\t\t\t{\n\t\t\t\tdoFinallyBodies = v;\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\twhile (blockContainer.EntryPoint.Instructions[pos] is StLoc stloc)\n\t\t\t{\n\t\t\t\t// stloc V_1(ldfld <>4__this(ldloc this))\n\t\t\t\tif (!stloc.Value.MatchLdFld(out var target, out var field))\n\t\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\t\tif (!target.MatchLdThis())\n\t\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\t\tif (field.MemberDefinition == stateField && cachedStateVar == null)\n\t\t\t\t{\n\t\t\t\t\t// stloc(cachedState, ldfld(valuetype StateMachineStruct::<>1__state, ldloc(this)))\n\t\t\t\t\tcachedStateVar = stloc.Variable;\n\t\t\t\t}\n\t\t\t\telse if (fieldToParameterMap.TryGetValue((IField)field.MemberDefinition, out var param))\n\t\t\t\t{\n\t\t\t\t\tif (!stloc.Variable.IsSingleDefinition)\n\t\t\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\t\t\tcachedFieldToParameterMap[stloc.Variable] = param;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\t\t}\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\tmainTryCatch = blockContainer.EntryPoint.Instructions[pos] as TryCatch;\n\t\t\tif (mainTryCatch == null)\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\t// CatchHandler will be validated in ValidateCatchBlock()\n\n\t\t\t// stloc doFinallyBodies(ldc.i4 1)\n\t\t\tif (((BlockContainer)mainTryCatch.TryBlock).EntryPoint.Instructions[0] is StLoc initDoFinallyBodies\n\t\t\t\t&& initDoFinallyBodies.Variable.Kind == VariableKind.Local\n\t\t\t\t&& initDoFinallyBodies.Variable.Type.IsKnownType(KnownTypeCode.Boolean)\n\t\t\t\t&& initDoFinallyBodies.Value.MatchLdcI4(1))\n\t\t\t{\n\t\t\t\tdoFinallyBodies = initDoFinallyBodies.Variable;\n\t\t\t}\n\n\t\t\tDebug.Assert(blockContainer.Blocks[0] == blockContainer.EntryPoint); // already checked this block\n\t\t\tblocksAnalyzed[0] = true;\n\t\t\tpos = 1;\n\t\t\tif (MatchYieldBlock(blockContainer, pos))\n\t\t\t{\n\t\t\t\tsetResultYieldBlock = blockContainer.Blocks[pos];\n\t\t\t\tblocksAnalyzed[pos] = true;\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsetResultYieldBlock = null;\n\t\t\t}\n\n\t\t\tsetResultReturnBlock = CheckSetResultReturnBlock(blockContainer, pos, blocksAnalyzed);\n\n\t\t\tif (!blocksAnalyzed.All(b => b))\n\t\t\t\tthrow new SymbolicAnalysisFailedException(\"too many blocks\");\n\t\t}\n\n\t\tprivate bool IsAsyncEnumerator => methodType == AsyncMethodType.AsyncEnumerable || methodType == AsyncMethodType.AsyncEnumerator;\n\n\t\tbool MatchYieldBlock(BlockContainer blockContainer, int pos)\n\t\t{\n\t\t\tif (!IsAsyncEnumerator)\n\t\t\t\treturn false;\n\t\t\tvar block = blockContainer.Blocks.ElementAtOrDefault(pos);\n\t\t\tif (block == null)\n\t\t\t\treturn false;\n\t\t\t// call SetResult(ldflda <>v__promiseOfValueOrEnd(ldloc this), ldc.i4 1)\n\t\t\t// leave IL_0000(nop)\n\t\t\tif (block.Instructions.Count != 2)\n\t\t\t\treturn false;\n\t\t\tif (!MatchCall(block.Instructions[0], \"SetResult\", out var args))\n\t\t\t\treturn false;\n\t\t\tif (args.Count != 2)\n\t\t\t\treturn false;\n\t\t\tif (!IsBuilderOrPromiseFieldOnThis(args[0]))\n\t\t\t\treturn false;\n\t\t\tif (!args[1].MatchLdcI4(1))\n\t\t\t\treturn false;\n\t\t\treturn block.Instructions[1].MatchLeave(blockContainer);\n\t\t}\n\n\t\tprivate Block CheckSetResultReturnBlock(BlockContainer blockContainer, int setResultReturnBlockIndex, bool[] blocksAnalyzed)\n\t\t{\n\t\t\tif (setResultReturnBlockIndex >= blockContainer.Blocks.Count)\n\t\t\t{\n\t\t\t\t// This block can be absent if the function never exits normally,\n\t\t\t\t// but always throws an exception/loops infinitely.\n\t\t\t\tresultVar = null;\n\t\t\t\tfinalStateKnown = false; // final state will be detected in ValidateCatchBlock() instead\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tvar block = blockContainer.Blocks[setResultReturnBlockIndex];\n\n\t\t\tint pos = 0;\n\t\t\t// [vb-only] stloc S_10(ldloc this)\n\t\t\tif (block.Instructions[pos] is StLoc stlocThisCache && stlocThisCache.Value.MatchLdThis() &&\n\t\t\t\tstlocThisCache.Variable.Kind == VariableKind.StackSlot)\n\t\t\t{\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\t// [vb-only] stloc S_11(ldc.i4 -2)\n\t\t\tILVariable finalStateSlot = null;\n\t\t\tint? finalStateSlotValue = null;\n\t\t\tif (block.Instructions[pos] is StLoc stlocFinalState && stlocFinalState.Value is LdcI4 ldcI4 &&\n\t\t\t\tstlocFinalState.Variable.Kind == VariableKind.StackSlot)\n\t\t\t{\n\t\t\t\tfinalStateSlot = stlocFinalState.Variable;\n\t\t\t\tfinalStateSlotValue = ldcI4.Value;\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\t// [vb-only] stloc cachedStateVar(ldloc S_11)\n\t\t\tif (block.Instructions[pos] is StLoc stlocCachedState && stlocCachedState.Variable.Kind == VariableKind.Local &&\n\t\t\t\tstlocCachedState.Variable.Index == cachedStateVar?.Index && stlocCachedState.Value.MatchLdLoc(finalStateSlot))\n\t\t\t{\n\t\t\t\tpos++;\n\t\t\t}\n\n\t\t\t// stfld <>1__state(ldloc this, ldc.i4 -2)\n\t\t\tif (!MatchStateAssignment(block.Instructions[pos], out finalState))\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\tif (finalStateSlotValue is not null && finalState != finalStateSlotValue.Value)\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\tfinalStateKnown = true;\n\t\t\tpos++;\n\n\t\t\tif (pos + 2 == block.Instructions.Count && block.MatchIfAtEndOfBlock(out var condition, out var trueInst, out var falseInst))\n\t\t\t{\n\t\t\t\tif (MatchDisposeCombinedTokens(blockContainer, condition, trueInst, falseInst, blocksAnalyzed, out var setResultAndExitBlock))\n\t\t\t\t{\n\t\t\t\t\tblocksAnalyzed[block.ChildIndex] = true;\n\t\t\t\t\tblock = setResultAndExitBlock;\n\t\t\t\t\tpos = 0;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// [optional] stfld <>u__N(ldloc this, ldnull)\n\t\t\tMatchHoistedLocalCleanup(block, ref pos);\n\t\t\tCheckSetResultAndExit(blockContainer, block, ref pos);\n\t\t\tblocksAnalyzed[block.ChildIndex] = true;\n\t\t\treturn blockContainer.Blocks[setResultReturnBlockIndex];\n\t\t}\n\n\t\tprivate bool MatchDisposeCombinedTokens(BlockContainer blockContainer, ILInstruction condition, ILInstruction trueInst, ILInstruction falseInst, bool[] blocksAnalyzed, out Block setResultAndExitBlock)\n\t\t{\n\t\t\tsetResultAndExitBlock = null;\n\t\t\t// \t...\n\t\t\t// \tif (comp.o(ldfld <>x__combinedTokens(ldloc this) == ldnull)) br setResultAndExit\n\t\t\t// \tbr disposeCombinedTokens\n\t\t\t// }\n\t\t\t// \n\t\t\t// Block disposeCombinedTokens (incoming: 1) {\n\t\t\t// \tcallvirt Dispose(ldfld <>x__combinedTokens(ldloc this))\n\t\t\t// \tstfld <>x__combinedTokens(ldloc this, ldnull)\n\t\t\t// \tbr setResultAndExit\n\t\t\t// }\n\t\t\tif (!condition.MatchCompEqualsNull(out var testedInst))\n\t\t\t\treturn false;\n\t\t\tif (!testedInst.MatchLdFld(out var target, out var ctsField))\n\t\t\t\treturn false;\n\t\t\tif (!target.MatchLdThis())\n\t\t\t\treturn false;\n\t\t\tif (!(ctsField.Type is ITypeDefinition { FullTypeName: { IsNested: false, TopLevelTypeName: { Name: \"CancellationTokenSource\", Namespace: \"System.Threading\" } } }))\n\t\t\t\treturn false;\n\t\t\tif (!(trueInst.MatchBranch(out setResultAndExitBlock) && falseInst.MatchBranch(out var disposedCombinedTokensBlock)))\n\t\t\t\treturn false;\n\t\t\tif (!(setResultAndExitBlock.Parent == blockContainer && disposedCombinedTokensBlock.Parent == blockContainer))\n\t\t\t\treturn false;\n\n\t\t\tvar block = disposedCombinedTokensBlock;\n\t\t\tint pos = 0;\n\t\t\t// callvirt Dispose(ldfld <>x__combinedTokens(ldloc this))\n\t\t\tif (!(block.Instructions[pos] is CallVirt { Method: { Name: \"Dispose\" } } disposeCall))\n\t\t\t\treturn false;\n\t\t\tif (disposeCall.Arguments.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (!disposeCall.Arguments[0].MatchLdFld(out var target2, out var ctsField2))\n\t\t\t\treturn false;\n\t\t\tif (!(target2.MatchLdThis() && ctsField2.Equals(ctsField)))\n\t\t\t\treturn false;\n\t\t\tpos++;\n\t\t\t// stfld <>x__combinedTokens(ldloc this, ldnull)\n\t\t\tif (!block.Instructions[pos].MatchStFld(out var target3, out var ctsField3, out var storedValue))\n\t\t\t\treturn false;\n\t\t\tif (!(target3.MatchLdThis() && ctsField3.Equals(ctsField)))\n\t\t\t\treturn false;\n\t\t\tif (!storedValue.MatchLdNull())\n\t\t\t\treturn false;\n\t\t\tpos++;\n\t\t\t// br setResultAndExit\n\t\t\tif (!block.Instructions[pos].MatchBranch(setResultAndExitBlock))\n\t\t\t\treturn false;\n\t\t\tblocksAnalyzed[block.ChildIndex] = true;\n\n\t\t\treturn true;\n\t\t}\n\n\t\tprivate void MatchHoistedLocalCleanup(Block block, ref int pos)\n\t\t{\n\t\t\twhile (block.Instructions[pos].MatchStFld(out var target, out _, out var value))\n\t\t\t{\n\t\t\t\t// https://github.com/dotnet/roslyn/pull/39735 hoisted local cleanup\n\t\t\t\tif (!target.MatchLdThis())\n\t\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\t\tif (!value.MatchDefaultOrNullOrZero())\n\t\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\t\tpos++;\n\t\t\t}\n\t\t}\n\n\t\tvoid CheckSetResultAndExit(BlockContainer blockContainer, Block block, ref int pos)\n\t\t{\n\t\t\t// [optional] call Complete(ldflda <>t__builder(ldloc this)) (Roslyn >=3.9)\n\t\t\t// call SetResult(ldflda <>t__builder(ldloc this), ldloc result)\n\t\t\t// [optional] call Complete(ldflda <>t__builder(ldloc this))\n\t\t\t// leave IL_0000\n\t\t\tMatchCompleteCall(block, ref pos);\n\t\t\tif (!MatchCall(block.Instructions[pos], \"SetResult\", out var args))\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\tif (!IsBuilderOrPromiseFieldOnThis(args[0]))\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\tswitch (methodType)\n\t\t\t{\n\t\t\t\tcase AsyncMethodType.TaskOfT:\n\t\t\t\t\tif (args.Count != 2)\n\t\t\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\t\t\tif (!args[1].MatchLdLoc(out resultVar))\n\t\t\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\t\t\tbreak;\n\t\t\t\tcase AsyncMethodType.Task:\n\t\t\t\tcase AsyncMethodType.Void:\n\t\t\t\t\tresultVar = null;\n\t\t\t\t\tif (args.Count != 1)\n\t\t\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\t\t\tbreak;\n\t\t\t\tcase AsyncMethodType.AsyncEnumerable:\n\t\t\t\tcase AsyncMethodType.AsyncEnumerator:\n\t\t\t\t\tresultVar = null;\n\t\t\t\t\tif (args.Count != 2)\n\t\t\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\t\t\tif (!args[1].MatchLdcI4(0))\n\t\t\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tpos++;\n\t\t\tMatchCompleteCall(block, ref pos);\n\t\t\tif (!block.Instructions[pos].MatchLeave(blockContainer))\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t}\n\n\t\tvoid ValidateCatchBlock()\n\t\t{\n\t\t\t// catch E_143 : System.Exception if (ldc.i4 1) BlockContainer {\n\t\t\t// \tBlock IL_008f (incoming: 1)  {\n\t\t\t// \t\tstloc exception(ldloc E_143)\n\t\t\t// \t\tstfld <>1__state(ldloc this, ldc.i4 -2)\n\t\t\t//      [optional] stfld <>u__N(ldloc this, ldnull)\n\t\t\t// \t\tcall SetException(ldfld <>t__builder(ldloc this), ldloc exception)\n\t\t\t//      [optional] call Complete(ldfld <>t__builder(ldloc this))\n\t\t\t// \t\tleave IL_0000\n\t\t\t// \t}\n\t\t\t// }\n\t\t\tif (mainTryCatch?.Handlers.Count != 1)\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\tvar handler = mainTryCatch.Handlers[0];\n\t\t\tif (!handler.Variable.Type.IsKnownType(KnownTypeCode.Exception))\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\tif (!handler.Filter.MatchLdcI4(1))\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\tif (!(handler.Body is BlockContainer handlerContainer))\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\tbool[] blocksAnalyzed = new bool[handlerContainer.Blocks.Count];\n\t\t\tvar catchBlock = handlerContainer.EntryPoint;\n\t\t\tcatchHandlerOffset = catchBlock.StartILOffset;\n\t\t\tint pos = 0;\n\t\t\t// [vb-only] call SetProjectError(ldloc E_143)\n\t\t\tif (isVisualBasicStateMachine && catchBlock.Instructions[pos] is Call call && call.Method.Name == \"SetProjectError\" &&\n\t\t\t\tcall.Arguments.Count == 1 && call.Arguments[0].MatchLdLoc(handler.Variable))\n\t\t\t{\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\t// stloc exception(ldloc E_143)\n\t\t\tif (!(catchBlock.Instructions[pos++] is StLoc stloc))\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\tif (!stloc.Value.MatchLdLoc(handler.Variable))\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\t// stfld <>1__state(ldloc this, ldc.i4 -2)\n\t\t\tif (!MatchStateAssignment(catchBlock.Instructions[pos++], out int newState))\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\tif (finalStateKnown)\n\t\t\t{\n\t\t\t\tif (newState != finalState)\n\t\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfinalState = newState;\n\t\t\t\tfinalStateKnown = true;\n\t\t\t}\n\t\t\tif (pos + 2 == catchBlock.Instructions.Count && catchBlock.MatchIfAtEndOfBlock(out var condition, out var trueInst, out var falseInst))\n\t\t\t{\n\t\t\t\tif (MatchDisposeCombinedTokens(handlerContainer, condition, trueInst, falseInst, blocksAnalyzed, out var setResultAndExitBlock))\n\t\t\t\t{\n\t\t\t\t\tblocksAnalyzed[catchBlock.ChildIndex] = true;\n\t\t\t\t\tcatchBlock = setResultAndExitBlock;\n\t\t\t\t\tpos = 0;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\t\t}\n\t\t\t}\n\t\t\tMatchHoistedLocalCleanup(catchBlock, ref pos);\n\t\t\t// [optional] call Complete(ldfld <>t__builder(ldloc this))\n\t\t\tMatchCompleteCall(catchBlock, ref pos);\n\n\t\t\t// call SetException(ldfld <>t__builder(ldloc this), ldloc exception)\n\t\t\tif (!MatchCall(catchBlock.Instructions[pos], \"SetException\", out var args))\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\tif (args.Count != 2)\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\tif (!IsBuilderOrPromiseFieldOnThis(args[0]))\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\tif (!args[1].MatchLdLoc(stloc.Variable))\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\n\t\t\tpos++;\n\t\t\t// [optional] call Complete(ldfld <>t__builder(ldloc this))\n\t\t\tMatchCompleteCall(catchBlock, ref pos);\n\n\t\t\t// [vb-only] call ClearProjectError()\n\t\t\tif (isVisualBasicStateMachine && catchBlock.Instructions[pos] is Call call2 &&\n\t\t\t\tcall2.Method.Name == \"ClearProjectError\" && call2.Arguments.Count == 0)\n\t\t\t{\n\t\t\t\tpos++;\n\t\t\t}\n\n\t\t\t// leave IL_0000\n\t\t\tif (!catchBlock.Instructions[pos].MatchLeave((BlockContainer)moveNextFunction.Body))\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\tblocksAnalyzed[catchBlock.ChildIndex] = true;\n\t\t\tif (!blocksAnalyzed.All(b => b))\n\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t}\n\n\t\tprivate void MatchCompleteCall(Block block, ref int pos)\n\t\t{\n\t\t\tif (MatchCall(block.Instructions[pos], \"Complete\", out var args))\n\t\t\t{\n\t\t\t\tif (!(args.Count == 1 && IsBuilderFieldOnThis(args[0])))\n\t\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\t\tpos++;\n\t\t\t}\n\t\t}\n\n\t\tbool IsBuilderFieldOnThis(ILInstruction inst)\n\t\t{\n\t\t\tIField field;\n\t\t\tILInstruction target;\n\t\t\tif (builderType.IsReferenceType == true)\n\t\t\t{\n\t\t\t\t// ldfld(StateMachine::<>t__builder, ldloc(this))\n\t\t\t\tif (!inst.MatchLdFld(out target, out field))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// ldflda(StateMachine::<>t__builder, ldloc(this))\n\t\t\t\tif (!inst.MatchLdFlda(out target, out field))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn target.MatchLdThis() && field.MemberDefinition == builderField;\n\t\t}\n\n\t\tbool IsBuilderOrPromiseFieldOnThis(ILInstruction inst)\n\t\t{\n\t\t\tif (methodType == AsyncMethodType.AsyncEnumerable || methodType == AsyncMethodType.AsyncEnumerator)\n\t\t\t{\n\t\t\t\treturn true; // TODO: check against uses of promise fields in other methods?\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn IsBuilderFieldOnThis(inst);\n\t\t\t}\n\t\t}\n\n\t\tbool MatchStateAssignment(ILInstruction inst, out int newState)\n\t\t{\n\t\t\t// stfld(StateMachine::<>1__state, ldloc(this), ldc.i4(stateId))\n\t\t\tif (inst.MatchStFld(out var target, out var field, out var value)\n\t\t\t\t&& StackSlotValue(target).MatchLdThis()\n\t\t\t\t&& field.MemberDefinition == stateField\n\t\t\t\t&& StackSlotValue(value).MatchLdcI4(out newState))\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tnewState = 0;\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Analyse the DisposeAsync() method in order to find the disposeModeField.\n\t\t/// </summary>\n\t\tprivate void AnalyzeDisposeAsync()\n\t\t{\n\t\t\tdisposeModeField = null;\n\t\t\tif (!IsAsyncEnumerator)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar disposeAsync = stateMachineType.Methods.FirstOrDefault(m => m.Name.EndsWith(\".DisposeAsync\", StringComparison.Ordinal));\n\t\t\tif (disposeAsync == null)\n\t\t\t\tthrow new SymbolicAnalysisFailedException(\"Could not find DisposeAsync()\");\n\t\t\tvar disposeAsyncHandle = (MethodDefinitionHandle)disposeAsync.MetadataToken;\n\t\t\tvar function = YieldReturnDecompiler.CreateILAst(disposeAsyncHandle, context);\n\t\t\tforeach (var store in function.Descendants)\n\t\t\t{\n\t\t\t\tif (!store.MatchStFld(out var target, out var field, out var value))\n\t\t\t\t\tcontinue;\n\t\t\t\tif (!target.MatchLdThis())\n\t\t\t\t\tcontinue;\n\t\t\t\tif (!value.MatchLdcI4(1))\n\t\t\t\t\tthrow new SymbolicAnalysisFailedException();\n\t\t\t\tif (disposeModeField != null)\n\t\t\t\t\tthrow new SymbolicAnalysisFailedException(\"Multiple stores to disposeMode in DisposeAsync()\");\n\t\t\t\tdisposeModeField = (IField)field.MemberDefinition;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region InlineBodyOfMoveNext\n\t\tvoid InlineBodyOfMoveNext(ILFunction function)\n\t\t{\n\t\t\tcontext.Step(\"Inline body of MoveNext()\", function);\n\t\t\tfunction.Body = mainTryCatch.TryBlock;\n\t\t\tfunction.AsyncReturnType = underlyingReturnType;\n\t\t\tfunction.MoveNextMethod = moveNextFunction.Method;\n\t\t\tfunction.SequencePointCandidates = moveNextFunction.SequencePointCandidates;\n\t\t\tfunction.CodeSize = moveNextFunction.CodeSize;\n\t\t\tfunction.LocalVariableSignatureLength = moveNextFunction.LocalVariableSignatureLength;\n\t\t\tfunction.IsIterator = IsAsyncEnumerator;\n\t\t\tmoveNextFunction.Variables.Clear();\n\t\t\tmoveNextFunction.ReleaseRef();\n\t\t\tforeach (var branch in function.Descendants.OfType<Branch>())\n\t\t\t{\n\t\t\t\tif (branch.TargetBlock == setResultReturnBlock)\n\t\t\t\t{\n\t\t\t\t\tbranch.ReplaceWith(new Leave((BlockContainer)function.Body, resultVar == null ? null : new LdLoc(resultVar)).WithILRange(branch));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (setResultYieldBlock != null)\n\t\t\t{\n\t\t\t\t// We still might have branches to this block; and we can't quite yet get rid of it.\n\t\t\t\t((BlockContainer)function.Body).Blocks.Add(setResultYieldBlock);\n\t\t\t}\n\t\t\tforeach (var leave in function.Descendants.OfType<Leave>())\n\t\t\t{\n\t\t\t\tif (leave.TargetContainer == moveNextFunction.Body)\n\t\t\t\t{\n\t\t\t\t\tleave.TargetContainer = (BlockContainer)function.Body;\n\t\t\t\t\tmoveNextLeaves.Add(leave);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfunction.Variables.AddRange(function.Descendants.OfType<IInstructionWithVariableOperand>().Select(inst => inst.Variable).Distinct());\n\t\t\tfunction.Variables.RemoveDead();\n\t\t\tfunction.Variables.AddRange(fieldToParameterMap.Values);\n\t\t}\n\n\t\tvoid FinalizeInlineMoveNext(ILFunction function)\n\t\t{\n\t\t\tcontext.Step(\"FinalizeInlineMoveNext()\", function);\n\t\t\tforeach (var leave in function.Descendants.OfType<Leave>())\n\t\t\t{\n\t\t\t\tif (moveNextLeaves.Contains(leave))\n\t\t\t\t{\n\t\t\t\t\tleave.ReplaceWith(new InvalidBranch {\n\t\t\t\t\t\tMessage = \"leave MoveNext - await not detected correctly\"\n\t\t\t\t\t}.WithILRange(leave));\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Delete dead loads of the state cache variable:\n\t\t\tforeach (var block in function.Descendants.OfType<Block>())\n\t\t\t{\n\t\t\t\tfor (int i = block.Instructions.Count - 1; i >= 0; i--)\n\t\t\t\t{\n\t\t\t\t\tif (block.Instructions[i].MatchStLoc(out var v, out var value)\n\t\t\t\t\t\t&& v.IsSingleDefinition && v.LoadCount == 0\n\t\t\t\t\t\t&& value.MatchLdLoc(cachedStateVar))\n\t\t\t\t\t{\n\t\t\t\t\t\tblock.Instructions.RemoveAt(i);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region AnalyzeStateMachine\n\n\t\t/// <summary>\n\t\t/// Analyze the the state machine; and replace 'leave IL_0000' with await+jump to block that gets\n\t\t/// entered on the next MoveNext() call.\n\t\t/// </summary>\n\t\tvoid AnalyzeStateMachine(ILFunction function)\n\t\t{\n\t\t\tcontext.StepStartGroup(\"AnalyzeStateMachine()\", function);\n\t\t\tsmallestAwaiterVarIndex = int.MaxValue;\n\t\t\tforeach (var container in function.Descendants.OfType<BlockContainer>())\n\t\t\t{\n\t\t\t\t// Use a separate state range analysis per container.\n\t\t\t\tvar sra = new StateRangeAnalysis(StateRangeAnalysisMode.AsyncMoveNext, stateField, cachedStateVar);\n\t\t\t\tsra.CancellationToken = context.CancellationToken;\n\t\t\t\tsra.doFinallyBodies = doFinallyBodies;\n\t\t\t\tsra.AssignStateRanges(container, LongSet.Universe);\n\t\t\t\tvar stateToBlockMap = sra.GetBlockStateSetMapping(container);\n\n\t\t\t\tforeach (var block in container.Blocks)\n\t\t\t\t{\n\t\t\t\t\tcontext.CancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tif (block.Instructions.Last() is Leave leave && moveNextLeaves.Contains(leave))\n\t\t\t\t\t{\n\t\t\t\t\t\t// This is likely an 'await' block\n\t\t\t\t\t\tcontext.Step($\"AnalyzeAwaitBlock({block.StartILOffset:x4})\", block);\n\t\t\t\t\t\tif (AnalyzeAwaitBlock(block, out var awaiterVar, out var awaiterField, out int state, out int yieldOffset))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tblock.Instructions.Add(new Await(new LdLoca(awaiterVar)));\n\t\t\t\t\t\t\tBlock targetBlock = stateToBlockMap.GetOrDefault(state);\n\t\t\t\t\t\t\tif (targetBlock != null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tawaitDebugInfos.Add(new AsyncDebugInfo.Await(yieldOffset, targetBlock.StartILOffset));\n\t\t\t\t\t\t\t\tblock.Instructions.Add(new Branch(targetBlock));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tblock.Instructions.Add(new InvalidBranch(\"Could not find block for state \" + state));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tawaitBlocks.Add(block, (awaiterVar, awaiterField));\n\t\t\t\t\t\t\tif (awaiterVar.Index < smallestAwaiterVarIndex)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tsmallestAwaiterVarIndex = awaiterVar.Index.Value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (block.Instructions.Last().MatchBranch(setResultYieldBlock))\n\t\t\t\t\t{\n\t\t\t\t\t\t// This is a 'yield return' in an async enumerator.\n\t\t\t\t\t\tcontext.Step($\"AnalyzeYieldReturn({block.StartILOffset:x4})\", block);\n\t\t\t\t\t\tif (AnalyzeYieldReturn(block, out var yieldValue, out int state))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tblock.Instructions.Add(new YieldReturn(yieldValue));\n\t\t\t\t\t\t\tBlock targetBlock = stateToBlockMap.GetOrDefault(state);\n\t\t\t\t\t\t\tif (targetBlock != null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tblock.Instructions.Add(new Branch(targetBlock));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tblock.Instructions.Add(new InvalidBranch(\"Could not find block for state \" + state));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tblock.Instructions.Add(new InvalidBranch(\"Could not detect 'yield return'\"));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tTransformYieldBreak(block);\n\t\t\t\t}\n\t\t\t\tforeach (var block in container.Blocks)\n\t\t\t\t{\n\t\t\t\t\tSimplifyIfDisposeMode(block);\n\t\t\t\t}\n\t\t\t\t// Skip the state dispatcher and directly jump to the initial state\n\t\t\t\tvar entryPoint = stateToBlockMap.GetOrDefault(initialState);\n\t\t\t\tif (entryPoint != null)\n\t\t\t\t{\n\t\t\t\t\tcontainer.Blocks.Insert(0, new Block {\n\t\t\t\t\t\tInstructions = {\n\t\t\t\t\t\t\tnew Branch(entryPoint)\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tcontainer.SortBlocks(deleteUnreachableBlocks: true);\n\t\t\t}\n\t\t\tcontext.StepEndGroup();\n\t\t}\n\n\t\tprivate bool TransformYieldBreak(Block block)\n\t\t{\n\t\t\t// stfld disposeMode(ldloc this, ldc.i4 1)\n\t\t\t// br nextBlock\n\t\t\tif (block.Instructions.Count < 2)\n\t\t\t\treturn false;\n\t\t\tif (!(block.Instructions.Last() is Branch branch))\n\t\t\t\treturn false;\n\t\t\tif (!block.Instructions[block.Instructions.Count - 2].MatchStFld(out var target, out var field, out var value))\n\t\t\t\treturn false;\n\t\t\tif (!target.MatchLdThis())\n\t\t\t\treturn false;\n\t\t\tif (field.MemberDefinition != disposeModeField)\n\t\t\t\treturn false;\n\t\t\tif (!value.MatchLdcI4(1))\n\t\t\t\treturn false;\n\n\t\t\t// Detected a 'yield break;'\n\t\t\tcontext.Step($\"TransformYieldBreak({block.StartILOffset:x4})\", block);\n\t\t\tvar breakTarget = FindYieldBreakTarget(branch.TargetBlock);\n\t\t\tif (breakTarget is Block targetBlock)\n\t\t\t{\n\t\t\t\tbranch.TargetBlock = targetBlock;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDebug.Assert(breakTarget is BlockContainer);\n\t\t\t\tbranch.ReplaceWith(new Leave((BlockContainer)breakTarget).WithILRange(branch));\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tILInstruction FindYieldBreakTarget(Block block)\n\t\t{\n\t\t\t// We'll follow the branch and evaluate the following instructions\n\t\t\t// under the assumption that disposeModeField==1, which lets us follow a series of jumps\n\t\t\t// to determine the final target.\n\t\t\tvar visited = new HashSet<Block>();\n\t\t\tvar evalContext = new SymbolicEvaluationContext(disposeModeField);\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < block.Instructions.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tILInstruction inst = block.Instructions[i];\n\t\t\t\t\twhile (inst.MatchIfInstruction(out var condition, out var trueInst, out var falseInst))\n\t\t\t\t\t{\n\t\t\t\t\t\tvar condVal = evalContext.Eval(condition).AsBool();\n\t\t\t\t\t\tif (condVal.Type == SymbolicValueType.IntegerConstant)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tinst = condVal.Constant != 0 ? trueInst : falseInst;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (condVal.Type == SymbolicValueType.StateInSet)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tinst = condVal.ValueSet.Contains(1) ? trueInst : falseInst;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn block;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (inst.MatchBranch(out var targetBlock))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (visited.Add(block))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tblock = targetBlock;\n\t\t\t\t\t\t\tbreak; // continue with next block\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn block; // infinite loop detected\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (inst is Leave leave && leave.Value.OpCode == OpCode.Nop)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn leave.TargetContainer;\n\t\t\t\t\t}\n\t\t\t\t\telse if (inst.OpCode == OpCode.Nop)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue; // continue with next instruction in this block\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn block;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate bool SimplifyIfDisposeMode(Block block)\n\t\t{\n\t\t\t// Occasionally Roslyn optimizes out an \"if (disposeMode)\", but keeps the\n\t\t\t// disposeMode field access. Get rid of those field accesses:\n\t\t\tblock.Instructions.RemoveAll(MatchLdDisposeMode);\n\n\t\t\t// if (logic.not(ldfld disposeMode(ldloc this))) br falseInst\n\t\t\t// br trueInst\n\t\t\tif (!block.MatchIfAtEndOfBlock(out var condition, out _, out var falseInst))\n\t\t\t\treturn false;\n\t\t\tif (!MatchLdDisposeMode(condition))\n\t\t\t\treturn false;\n\t\t\tcontext.Step($\"SimplifyIfDisposeMode({block.StartILOffset:x4})\", block);\n\t\t\tblock.Instructions[block.Instructions.Count - 2] = falseInst;\n\t\t\tblock.Instructions.RemoveAt(block.Instructions.Count - 1);\n\t\t\treturn true;\n\n\t\t\tbool MatchLdDisposeMode(ILInstruction inst)\n\t\t\t{\n\t\t\t\tif (!inst.MatchLdFld(out var target, out var field))\n\t\t\t\t\treturn false;\n\t\t\t\treturn target.MatchLdThis() && field.MemberDefinition == disposeModeField;\n\t\t\t}\n\t\t}\n\n\t\tbool AnalyzeAwaitBlock(Block block, out ILVariable awaiter, out IField awaiterField, out int state, out int yieldOffset)\n\t\t{\n\t\t\tawaiter = null;\n\t\t\tawaiterField = null;\n\t\t\tstate = 0;\n\t\t\tyieldOffset = -1;\n\t\t\tint pos = block.Instructions.Count - 2;\n\t\t\tif (pos >= 0 && doFinallyBodies != null && block.Instructions[pos] is StLoc storeDoFinallyBodies)\n\t\t\t{\n\t\t\t\tif (!(storeDoFinallyBodies.Variable.Kind == VariableKind.Local\n\t\t\t\t\t  && storeDoFinallyBodies.Variable.Type.IsKnownType(KnownTypeCode.Boolean)\n\t\t\t\t\t  && storeDoFinallyBodies.Variable.Index == doFinallyBodies.Index))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (!storeDoFinallyBodies.Value.MatchLdcI4(0))\n\t\t\t\t\treturn false;\n\t\t\t\tpos--;\n\t\t\t}\n\n\t\t\tif (pos >= 0 && MatchCall(block.Instructions[pos], \"AwaitUnsafeOnCompleted\", out var callArgs))\n\t\t\t{\n\t\t\t\t// call AwaitUnsafeOnCompleted(ldflda <>t__builder(ldloc this), ldloca awaiter, ldloc this)\n\t\t\t}\n\t\t\telse if (pos >= 0 && MatchCall(block.Instructions[pos], \"AwaitOnCompleted\", out callArgs))\n\t\t\t{\n\t\t\t\t// call AwaitOnCompleted(ldflda <>t__builder(ldloc this), ldloca awaiter, ldloc this)\n\t\t\t\t// The C# compiler emits the non-unsafe call when the awaiter does not implement\n\t\t\t\t// ICriticalNotifyCompletion.\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (callArgs.Count != 3)\n\t\t\t\treturn false;\n\t\t\tif (!IsBuilderFieldOnThis(callArgs[0]))\n\t\t\t\treturn false;\n\t\t\tif (!callArgs[1].MatchLdLoca(out awaiter))\n\t\t\t\treturn false;\n\t\t\tif (callArgs[2].MatchLdThis())\n\t\t\t{\n\t\t\t\t// OK (if state machine is a struct)\n\t\t\t\tpos--;\n\t\t\t}\n\t\t\telse if (callArgs[2].MatchLdLoca(out var tempVar))\n\t\t\t{\n\t\t\t\t// Roslyn, non-optimized uses a class for the state machine.\n\t\t\t\t// stloc tempVar(ldloc this)\n\t\t\t\t// call AwaitUnsafeOnCompleted(ldflda <>t__builder](ldloc this), ldloca awaiter, ldloca tempVar)\n\t\t\t\tif (!(pos > 0 && block.Instructions[pos - 1].MatchStLoc(tempVar, out var tempVal)))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!tempVal.MatchLdThis())\n\t\t\t\t\treturn false;\n\t\t\t\tpos -= 2;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// stfld StateMachine.<>awaiter(ldloc this, ldloc awaiter)\n\t\t\tif (!block.Instructions[pos].MatchStFld(out var target, out awaiterField, out var value))\n\t\t\t\treturn false;\n\t\t\tif (!target.MatchLdThis())\n\t\t\t\treturn false;\n\t\t\tif (!value.MatchLdLoc(awaiter))\n\t\t\t\treturn false;\n\t\t\tpos--;\n\t\t\t// Store IL offset for debug info:\n\t\t\tyieldOffset = block.Instructions[pos].EndILOffset;\n\n\t\t\t// stloc S_10(ldloc this)\n\t\t\t// stloc S_11(ldc.i4 0)\n\t\t\t// stloc cachedStateVar(ldloc S_11)\n\t\t\t// stfld <>1__state(ldloc S_10, ldloc S_11)\n\t\t\tif (!block.Instructions[pos].MatchStFld(out target, out var field, out value))\n\t\t\t\treturn false;\n\t\t\tif (!StackSlotValue(target).MatchLdThis())\n\t\t\t\treturn false;\n\t\t\tif (field.MemberDefinition != stateField)\n\t\t\t\treturn false;\n\t\t\tif (!StackSlotValue(value).MatchLdcI4(out state))\n\t\t\t\treturn false;\n\t\t\tif (pos > 0 && block.Instructions[pos - 1] is StLoc stloc\n\t\t\t\t&& stloc.Variable.Kind == VariableKind.Local && stloc.Variable.Index == cachedStateVar.Index\n\t\t\t\t&& StackSlotValue(stloc.Value).MatchLdcI4(state))\n\t\t\t{\n\t\t\t\t// also delete the assignment to cachedStateVar\n\t\t\t\tpos--;\n\t\t\t}\n\t\t\tblock.Instructions.RemoveRange(pos, block.Instructions.Count - pos);\n\t\t\t// delete preceding dead stores:\n\t\t\twhile (pos > 0 && block.Instructions[pos - 1] is StLoc stloc2\n\t\t\t\t&& stloc2.Variable.IsSingleDefinition && stloc2.Variable.LoadCount == 0\n\t\t\t\t&& stloc2.Variable.Kind == VariableKind.StackSlot\n\t\t\t\t&& SemanticHelper.IsPure(stloc2.Value.Flags))\n\t\t\t{\n\t\t\t\tpos--;\n\t\t\t}\n\t\t\tblock.Instructions.RemoveRange(pos, block.Instructions.Count - pos);\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic ILInstruction StackSlotValue(ILInstruction inst)\n\t\t{\n\t\t\tif (inst.MatchLdLoc(out var v) && v.Kind == VariableKind.StackSlot && v.IsSingleDefinition)\n\t\t\t{\n\t\t\t\tif (v.StoreInstructions[0] is StLoc stloc)\n\t\t\t\t{\n\t\t\t\t\treturn stloc.Value;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn inst;\n\t\t}\n\n\t\tprivate bool AnalyzeYieldReturn(Block block, out ILInstruction yieldValue, out int newState)\n\t\t{\n\t\t\tyieldValue = default;\n\t\t\tnewState = default;\n\t\t\tDebug.Assert(block.Instructions.Last().MatchBranch(setResultYieldBlock));\n\t\t\t// stfld current(ldloc this, ldstr \"yieldValue\")\n\t\t\t// stloc S_45(ldloc this)\n\t\t\t// stloc S_46(ldc.i4 -5)\n\t\t\t// stloc V_0(ldloc S_46)\n\t\t\t// stfld stateField(ldloc S_45, ldloc S_46)\n\t\t\t// br setResultYieldBlock\n\n\t\t\tint pos = block.Instructions.Count - 2;\n\t\t\t// Immediately before the 'yield return', there should be a state assignment:\n\t\t\tif (pos < 0 || !MatchStateAssignment(block.Instructions[pos], out newState))\n\t\t\t\treturn false;\n\t\t\tpos--;\n\n\t\t\tif (pos >= 0 && block.Instructions[pos].MatchStLoc(cachedStateVar, out var cachedStateNewValue))\n\t\t\t{\n\t\t\t\tif (StackSlotValue(cachedStateNewValue).MatchLdcI4(newState))\n\t\t\t\t{\n\t\t\t\t\tpos--; // OK, ignore V_0 store\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\twhile (pos >= 0 && block.Instructions[pos] is StLoc stloc)\n\t\t\t{\n\t\t\t\tif (stloc.Variable.Kind != VariableKind.StackSlot)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!SemanticHelper.IsPure(stloc.Value.Flags))\n\t\t\t\t\treturn false;\n\t\t\t\tpos--;\n\t\t\t}\n\n\t\t\tif (pos < 0 || !MatchCurrentAssignment(block.Instructions[pos], out yieldValue))\n\t\t\t\treturn false;\n\n\t\t\tblock.Instructions.RemoveRange(pos, block.Instructions.Count - pos);\n\t\t\treturn true;\n\t\t}\n\n\t\tbool MatchCurrentAssignment(ILInstruction inst, out ILInstruction value)\n\t\t{\n\t\t\tif (!inst.MatchStFld(out var target, out var field, out value))\n\t\t\t\treturn false;\n\t\t\tif (!StackSlotValue(target).MatchLdThis())\n\t\t\t\treturn false;\n\t\t\t// TODO: check that we are accessing the current field (compare with get_Current)\n\t\t\treturn true;\n\t\t}\n\t\t#endregion\n\n\t\t#region DetectAwaitPattern\n\t\tvoid DetectAwaitPattern(ILFunction function)\n\t\t{\n\t\t\tcontext.StepStartGroup(\"DetectAwaitPattern\", function);\n\t\t\tforeach (var container in function.Descendants.OfType<BlockContainer>())\n\t\t\t{\n\t\t\t\tforeach (var block in container.Blocks)\n\t\t\t\t{\n\t\t\t\t\tcontext.CancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tDetectAwaitPattern(block);\n\t\t\t\t}\n\t\t\t\tcontainer.SortBlocks(deleteUnreachableBlocks: true);\n\t\t\t}\n\t\t\tcontext.StepEndGroup(keepIfEmpty: true);\n\t\t}\n\n\t\tvoid DetectAwaitPattern(Block block)\n\t\t{\n\t\t\t// block:\n\t\t\t//   stloc awaiterVar(callvirt GetAwaiter(...))\n\t\t\t//   if (call get_IsCompleted(ldloca awaiterVar)) br completedBlock\n\t\t\t//   br awaitBlock\n\t\t\t// awaitBlock:\n\t\t\t//   ..\n\t\t\t//   br resumeBlock\n\t\t\t// resumeBlock:\n\t\t\t//   ..\n\t\t\t//   br completedBlock\n\t\t\tif (block.Instructions.Count < 3)\n\t\t\t\treturn;\n\t\t\t// stloc awaiterVar(callvirt GetAwaiter(...))\n\t\t\tif (!(block.Instructions[block.Instructions.Count - 3] is StLoc stLocAwaiter))\n\t\t\t\treturn;\n\t\t\tILVariable awaiterVar = stLocAwaiter.Variable;\n\t\t\tif (!(stLocAwaiter.Value is CallInstruction getAwaiterCall))\n\t\t\t\treturn;\n\t\t\tif (!(getAwaiterCall.Method.Name == \"GetAwaiter\" && (!getAwaiterCall.Method.IsStatic || getAwaiterCall.Method.IsExtensionMethod)))\n\t\t\t\treturn;\n\t\t\tif (getAwaiterCall.Arguments.Count != 1)\n\t\t\t\treturn;\n\t\t\t// if (call get_IsCompleted(ldloca awaiterVar)) br completedBlock\n\t\t\tif (!block.Instructions[block.Instructions.Count - 2].MatchIfInstruction(out var condition, out var trueInst))\n\t\t\t\treturn;\n\t\t\tif (!trueInst.MatchBranch(out var completedBlock))\n\t\t\t\treturn;\n\t\t\t// br awaitBlock\n\t\t\tif (!block.Instructions.Last().MatchBranch(out var awaitBlock))\n\t\t\t\treturn;\n\t\t\t// condition might be inverted, swap branches:\n\t\t\tif (condition.MatchLogicNot(out var negatedCondition))\n\t\t\t{\n\t\t\t\tcondition = negatedCondition;\n\t\t\t\tExtensionMethods.Swap(ref completedBlock, ref awaitBlock);\n\t\t\t}\n\t\t\t// continue matching call get_IsCompleted(ldloca awaiterVar)\n\t\t\tif (!MatchCall(condition, \"get_IsCompleted\", out var isCompletedArgs) || isCompletedArgs.Count != 1)\n\t\t\t\treturn;\n\t\t\tif (!UnwrapConvUnknown(isCompletedArgs[0]).MatchLdLocRef(awaiterVar))\n\t\t\t\treturn;\n\t\t\t// Check awaitBlock and resumeBlock:\n\t\t\tif (!awaitBlocks.TryGetValue(awaitBlock, out var awaitBlockData))\n\t\t\t\treturn;\n\t\t\tif (awaitBlockData.awaiterVar != awaiterVar)\n\t\t\t\treturn;\n\t\t\tif (!CheckAwaitBlock(awaitBlock, out var resumeBlock, out var stackField))\n\t\t\t\treturn;\n\t\t\tif (!CheckResumeBlock(resumeBlock, awaiterVar, awaitBlockData.awaiterField, completedBlock, stackField))\n\t\t\t\treturn;\n\t\t\t// Check completedBlock. The first instruction involves the GetResult call, but it might have\n\t\t\t// been inlined into another instruction.\n\t\t\tvar getResultCall = ILInlining.FindFirstInlinedCall(completedBlock.Instructions[0]);\n\t\t\tif (getResultCall == null)\n\t\t\t\treturn;\n\t\t\tif (!MatchCall(getResultCall, \"GetResult\", out var getResultArgs) || getResultArgs.Count != 1)\n\t\t\t\treturn;\n\t\t\tif (!UnwrapConvUnknown(getResultArgs[0]).MatchLdLocRef(awaiterVar))\n\t\t\t\treturn;\n\t\t\t// All checks successful, let's transform.\n\t\t\tcontext.Step(\"Transform await pattern\", block);\n\t\t\tblock.Instructions.RemoveAt(block.Instructions.Count - 3); // remove getAwaiter call\n\t\t\tblock.Instructions.RemoveAt(block.Instructions.Count - 2); // remove if (isCompleted)\n\t\t\t((Branch)block.Instructions.Last()).TargetBlock = completedBlock; // instead, directly jump to completed block\n\t\t\tAwait awaitInst = new Await(UnwrapConvUnknown(getAwaiterCall.Arguments.Single()));\n\t\t\tawaitInst.GetResultMethod = getResultCall.Method;\n\t\t\tawaitInst.GetAwaiterMethod = getAwaiterCall.Method;\n\t\t\tgetResultCall.ReplaceWith(awaitInst);\n\n\t\t\t// Remove useless reset of awaiterVar.\n\t\t\tif (completedBlock.Instructions.ElementAtOrDefault(1) is StObj stobj)\n\t\t\t{\n\t\t\t\tif (stobj.Target.MatchLdLoca(awaiterVar) && stobj.Value.OpCode == OpCode.DefaultValue)\n\t\t\t\t{\n\t\t\t\t\tcompletedBlock.Instructions.RemoveAt(1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic ILInstruction UnwrapConvUnknown(ILInstruction inst)\n\t\t{\n\t\t\tif (inst is Conv conv && conv.TargetType == PrimitiveType.Unknown)\n\t\t\t{\n\t\t\t\treturn conv.Argument;\n\t\t\t}\n\t\t\treturn inst;\n\t\t}\n\n\t\tbool CheckAwaitBlock(Block block, out Block resumeBlock, out IField stackField)\n\t\t{\n\t\t\t// awaitBlock:\n\t\t\t//   (pre-roslyn: save stack)\n\t\t\t//   await(ldloca V_2)\n\t\t\t//   br resumeBlock\n\t\t\tresumeBlock = null;\n\t\t\tstackField = null;\n\t\t\tif (block.Instructions.Count < 2)\n\t\t\t\treturn false;\n\t\t\tint pos = 0;\n\t\t\tif (block.Instructions[pos] is StLoc stloc && stloc.Variable.IsSingleDefinition)\n\t\t\t{\n\t\t\t\tif (!block.Instructions[pos + 1].MatchStFld(out var target, out stackField, out var value))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!target.MatchLdThis())\n\t\t\t\t\treturn false;\n\t\t\t\tpos += 2;\n\t\t\t}\n\t\t\t// await(ldloca awaiterVar)\n\t\t\tif (block.Instructions[pos].OpCode != OpCode.Await)\n\t\t\t\treturn false;\n\t\t\t// br resumeBlock\n\t\t\treturn block.Instructions[pos + 1].MatchBranch(out resumeBlock);\n\t\t}\n\n\t\tbool CheckResumeBlock(Block block, ILVariable awaiterVar, IField awaiterField, Block completedBlock, IField stackField)\n\t\t{\n\t\t\tint pos = 0;\n\t\t\tif (!RestoreStack(block, ref pos, stackField))\n\t\t\t\treturn false;\n\n\t\t\t// Visual Basic state machines use a different order of field assignements.\n\t\t\tif (isVisualBasicStateMachine)\n\t\t\t{\n\t\t\t\t// stloc S_28(ldc.i4 -1)\n\t\t\t\t// stloc cachedStateVar(ldloc S_28)\n\t\t\t\t// stfld <>1__state(ldloc this, ldloc S_28)\n\t\t\t\tif (!MatchStateFieldAssignement(block, ref pos))\n\t\t\t\t\treturn false;\n\t\t\t\tpos++;\n\n\t\t\t\t// stloc awaiterVar(ldfld awaiterField(ldloc this))\n\t\t\t\tif (!MatchStoreToAwaiterVariable(block.Instructions[pos]))\n\t\t\t\t\treturn false;\n\t\t\t\tpos++;\n\n\t\t\t\t// [optional] stfld awaiterField(ldloc this, default.value)\n\t\t\t\tMatchResetAwaiterField(block, ref pos);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// stloc awaiterVar(ldfld awaiterField(ldloc this))\n\t\t\t\tif (!MatchStoreToAwaiterVariable(block.Instructions[pos]))\n\t\t\t\t\treturn false;\n\t\t\t\tpos++;\n\n\t\t\t\t// [optional] stfld awaiterField(ldloc this, default.value)\n\t\t\t\tMatchResetAwaiterField(block, ref pos);\n\n\t\t\t\t// stloc S_28(ldc.i4 -1)\n\t\t\t\t// stloc cachedStateVar(ldloc S_28)\n\t\t\t\t// stfld <>1__state(ldloc this, ldloc S_28)\n\t\t\t\tif (!MatchStateFieldAssignement(block, ref pos))\n\t\t\t\t\treturn false;\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\treturn block.Instructions[pos].MatchBranch(completedBlock);\n\n\t\t\tbool MatchStoreToAwaiterVariable(ILInstruction instr)\n\t\t\t{\n\t\t\t\t// stloc awaiterVar(ldfld awaiterField(ldloc this))\n\t\t\t\tif (!instr.MatchStLoc(awaiterVar, out var value))\n\t\t\t\t\treturn false;\n\t\t\t\tif (value is CastClass cast && cast.Type.Equals(awaiterVar.Type))\n\t\t\t\t{\n\t\t\t\t\t// If the awaiter is a reference type, it might get stored in a field of type `object`\n\t\t\t\t\t// and cast back to the awaiter type in the resume block\n\t\t\t\t\tvalue = cast.Argument;\n\t\t\t\t}\n\t\t\t\tif (!value.MatchLdFld(out var target, out var field))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!target.MatchLdThis())\n\t\t\t\t\treturn false;\n\t\t\t\tif (!field.Equals(awaiterField))\n\t\t\t\t\treturn false;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tvoid MatchResetAwaiterField(Block block, ref int pos)\n\t\t\t{\n\t\t\t\t// stfld awaiterField(ldloc this, default.value)\n\t\t\t\tif (block.Instructions[pos].MatchStFld(out var target, out var field, out var value)\n\t\t\t\t\t&& target.MatchLdThis()\n\t\t\t\t\t&& field.Equals(awaiterField)\n\t\t\t\t\t&& (value.OpCode == OpCode.DefaultValue || value.OpCode == OpCode.LdNull))\n\t\t\t\t{\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// {stloc V_6(default.value System.Runtime.CompilerServices.TaskAwaiter)}\n\t\t\t\t\t// {stobj System.Runtime.CompilerServices.TaskAwaiter`1[[System.Int32]](ldflda <>u__$awaiter4(ldloc this), ldloc V_6) at IL_0163}\n\t\t\t\t\tif (block.Instructions[pos].MatchStLoc(out var variable, out value) && value.OpCode == OpCode.DefaultValue\n\t\t\t\t\t\t&& block.Instructions[pos + 1].MatchStFld(out target, out field, out value)\n\t\t\t\t\t\t&& field.Equals(awaiterField)\n\t\t\t\t\t\t&& value.MatchLdLoc(variable))\n\t\t\t\t\t{\n\t\t\t\t\t\tpos += 2;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool MatchStateFieldAssignement(Block block, ref int pos)\n\t\t\t{\n\t\t\t\t// stloc S_28(ldc.i4 -1)\n\t\t\t\t// stloc cachedStateVar(ldloc S_28)\n\t\t\t\t// stfld <>1__state(ldloc this, ldloc S_28)\n\t\t\t\tILVariable m1Var = null;\n\t\t\t\tif (block.Instructions[pos] is StLoc stlocM1 && stlocM1.Value.MatchLdcI4(initialState) && stlocM1.Variable.Kind == VariableKind.StackSlot)\n\t\t\t\t{\n\t\t\t\t\tm1Var = stlocM1.Variable;\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t\tif (block.Instructions[pos] is StLoc stlocCachedState)\n\t\t\t\t{\n\t\t\t\t\tif (stlocCachedState.Variable.Kind == VariableKind.Local && stlocCachedState.Variable.Index == cachedStateVar?.Index)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (stlocCachedState.Value.MatchLdLoc(m1Var) || stlocCachedState.Value.MatchLdcI4(initialState))\n\t\t\t\t\t\t\tpos++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!block.Instructions[pos].MatchStFld(out var target, out var field, out var value))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!target.MatchLdThis())\n\t\t\t\t\treturn false;\n\t\t\t\tif (!field.MemberDefinition.Equals(stateField.MemberDefinition))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(value.MatchLdcI4(initialState) || value.MatchLdLoc(m1Var)))\n\t\t\t\t\treturn false;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tprivate bool RestoreStack(Block block, ref int pos, IField stackField)\n\t\t{\n\t\t\tif (stackField == null)\n\t\t\t{\n\t\t\t\treturn true; // nothing to restore\n\t\t\t}\n\t\t\t// stloc temp(unbox.any T(ldfld <>t__stack(ldloc this)))\n\t\t\tif (!(block.Instructions[pos] is StLoc stloc))\n\t\t\t\treturn false;\n\t\t\tif (!stloc.Variable.IsSingleDefinition)\n\t\t\t\treturn false;\n\t\t\tif (!(stloc.Value is UnboxAny unbox))\n\t\t\t\treturn false;\n\t\t\tif (!unbox.Argument.MatchLdFld(out var target, out var field))\n\t\t\t\treturn false;\n\t\t\tif (!target.MatchLdThis())\n\t\t\t\treturn false;\n\t\t\tif (!field.Equals(stackField))\n\t\t\t\treturn false;\n\t\t\tpos++;\n\t\t\t// restoring stack slots\n\t\t\twhile (block.Instructions[pos].MatchStLoc(out var v) && v.Kind == VariableKind.StackSlot)\n\t\t\t{\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\t// stfld <>t__stack(ldloc this, ldnull)\n\t\t\tif (block.Instructions[pos].MatchStFld(out target, out field, out var value))\n\t\t\t{\n\t\t\t\tif (target.MatchLdThis() && field.Equals(stackField) && value.MatchLdNull())\n\t\t\t\t{\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\t#endregion\n\n\t\t/// <summary>\n\t\t/// Eliminates usage of doFinallyBodies\n\t\t/// </summary>\n\t\tprivate void CleanDoFinallyBodies(ILFunction function)\n\t\t{\n\t\t\tif (doFinallyBodies == null)\n\t\t\t{\n\t\t\t\treturn; // roslyn-compiled code doesn't use doFinallyBodies\n\t\t\t}\n\t\t\tcontext.StepStartGroup(\"CleanDoFinallyBodies\", function);\n\t\t\tBlock entryPoint = GetBodyEntryPoint(function.Body as BlockContainer);\n\t\t\tif (entryPoint != null && entryPoint.Instructions[0].MatchStLoc(doFinallyBodies, out var value) && value.MatchLdcI4(1))\n\t\t\t{\n\t\t\t\t// Remove initial doFinallyBodies assignment, if it wasn't already removed when\n\t\t\t\t// we rearranged the control flow.\n\t\t\t\tentryPoint.Instructions.RemoveAt(0);\n\t\t\t}\n\t\t\tif (doFinallyBodies.StoreInstructions.Count != 0 || doFinallyBodies.AddressCount != 0)\n\t\t\t{\n\t\t\t\t// misdetected another variable as doFinallyBodies?\n\t\t\t\t// reintroduce the initial store of ldc.i4(1)\n\t\t\t\tcontext.Step(\"Re-introduce misdetected doFinallyBodies\", function);\n\t\t\t\t((BlockContainer)function.Body).EntryPoint.Instructions.Insert(0,\n\t\t\t\t\tnew StLoc(doFinallyBodies, new LdcI4(1)));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tforeach (var tryFinally in function.Descendants.OfType<TryFinally>())\n\t\t\t{\n\t\t\t\tentryPoint = GetBodyEntryPoint(tryFinally.FinallyBlock as BlockContainer);\n\t\t\t\tif (entryPoint?.Instructions[0] is IfInstruction ifInst)\n\t\t\t\t{\n\t\t\t\t\tif (ifInst.Condition.MatchLogicNot(out var logicNotArg) && logicNotArg.MatchLdLoc(doFinallyBodies))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontext.Step(\"Remove if(doFinallyBodies) from try-finally\", tryFinally);\n\t\t\t\t\t\t// condition will always be false now that we're using 'await' instructions\n\t\t\t\t\t\tentryPoint.Instructions.RemoveAt(0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// if there's any remaining loads (there shouldn't be), replace them with the constant 1\n\t\t\tforeach (LdLoc load in doFinallyBodies.LoadInstructions.ToArray())\n\t\t\t{\n\t\t\t\tload.ReplaceWith(new LdcI4(1).WithILRange(load));\n\t\t\t}\n\t\t\tcontext.StepEndGroup(keepIfEmpty: true);\n\t\t}\n\n\t\tinternal static Block GetBodyEntryPoint(BlockContainer body)\n\t\t{\n\t\t\tif (body == null)\n\t\t\t\treturn null;\n\t\t\tBlock entryPoint = body.EntryPoint;\n\t\t\twhile (entryPoint.Instructions[0].MatchBranch(out var targetBlock) && targetBlock.IncomingEdgeCount == 1 && targetBlock.Parent == body)\n\t\t\t{\n\t\t\t\tentryPoint = targetBlock;\n\t\t\t}\n\t\t\treturn entryPoint;\n\t\t}\n\n\t\tvoid TranslateCachedFieldsToLocals()\n\t\t{\n\t\t\tforeach (var (cachedVar, param) in cachedFieldToParameterMap)\n\t\t\t{\n\t\t\t\tDebug.Assert(cachedVar.StoreCount <= 1);\n\t\t\t\tforeach (var inst in cachedVar.LoadInstructions.ToArray())\n\t\t\t\t{\n\t\t\t\t\tinst.Variable = param;\n\t\t\t\t}\n\t\t\t\tforeach (var inst in cachedVar.AddressInstructions.ToArray())\n\t\t\t\t{\n\t\t\t\t\tinst.Variable = param;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ControlFlow/AwaitInCatchTransform.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.ControlFlow\n{\n\tclass AwaitInCatchTransform\n\t{\n\t\treadonly struct CatchBlockInfo\n\t\t{\n\t\t\tpublic readonly int Id;\n\t\t\tpublic readonly TryCatchHandler Handler;\n\t\t\tpublic readonly Block RealCatchBlockEntryPoint;\n\t\t\tpublic readonly ILInstruction NextBlockOrExitContainer;\n\t\t\tpublic readonly ILInstruction JumpTableEntry;\n\t\t\tpublic readonly ILVariable ObjectVariable;\n\n\t\t\tpublic CatchBlockInfo(int id, TryCatchHandler handler, Block realCatchBlockEntryPoint,\n\t\t\t\tILInstruction nextBlockOrExitContainer, ILInstruction jumpTableEntry, ILVariable objectVariable)\n\t\t\t{\n\t\t\t\tId = id;\n\t\t\t\tHandler = handler;\n\t\t\t\tRealCatchBlockEntryPoint = realCatchBlockEntryPoint;\n\t\t\t\tNextBlockOrExitContainer = nextBlockOrExitContainer;\n\t\t\t\tJumpTableEntry = jumpTableEntry;\n\t\t\t\tObjectVariable = objectVariable;\n\t\t\t}\n\t\t}\n\n\t\tpublic static void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.AwaitInCatchFinally)\n\t\t\t\treturn;\n\t\t\tHashSet<BlockContainer> changedContainers = new HashSet<BlockContainer>();\n\t\t\tHashSet<Block> removedBlocks = new HashSet<Block>();\n\n\t\t\t// analyze all try-catch statements in the function\n\t\t\tforeach (var tryCatch in function.Descendants.OfType<TryCatch>().ToArray())\n\t\t\t{\n\t\t\t\tif (!(tryCatch.Parent?.Parent is BlockContainer container))\n\t\t\t\t\tcontinue;\n\t\t\t\t// Detect all handlers that contain an await expression\n\t\t\t\tAnalyzeHandlers(tryCatch.Handlers, out var catchHandlerIdentifier, out var transformableCatchBlocks);\n\t\t\t\tvar cfg = new ControlFlowGraph(container, context.CancellationToken);\n\t\t\t\tif (transformableCatchBlocks.Count > 0)\n\t\t\t\t\tchangedContainers.Add(container);\n\t\t\t\tSwitchInstruction switchInstructionOpt = null;\n\t\t\t\tforeach (var result in transformableCatchBlocks)\n\t\t\t\t{\n\t\t\t\t\tremovedBlocks.Clear();\n\t\t\t\t\tvar node = cfg.GetNode(result.RealCatchBlockEntryPoint);\n\n\t\t\t\t\tcontext.StepStartGroup($\"Inline catch block with await (at {result.Handler.Variable.Name})\", result.Handler);\n\n\t\t\t\t\t// Remove the IfInstruction from the jump table and eliminate all branches to the block.\n\t\t\t\t\tswitch (result.JumpTableEntry)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase IfInstruction jumpTableEntry:\n\t\t\t\t\t\t\tvar jumpTableBlock = (Block)jumpTableEntry.Parent;\n\t\t\t\t\t\t\tcontext.Step(\"Remove jump-table entry\", result.JumpTableEntry);\n\t\t\t\t\t\t\tjumpTableBlock.Instructions.RemoveAt(result.JumpTableEntry.ChildIndex);\n\n\t\t\t\t\t\t\tforeach (var branch in tryCatch.Descendants.OfType<Branch>())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (branch.TargetBlock == jumpTableBlock)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif (result.NextBlockOrExitContainer is BlockContainer exitContainer)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tcontext.Step(\"branch jumpTableBlock => leave exitContainer\", branch);\n\t\t\t\t\t\t\t\t\t\tbranch.ReplaceWith(new Leave(exitContainer));\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tcontext.Step(\"branch jumpTableBlock => branch nextBlock\", branch);\n\t\t\t\t\t\t\t\t\t\tbranch.ReplaceWith(new Branch((Block)result.NextBlockOrExitContainer));\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase SwitchSection jumpTableEntry:\n\t\t\t\t\t\t\tDebug.Assert(switchInstructionOpt == null || jumpTableEntry.Parent == switchInstructionOpt);\n\t\t\t\t\t\t\tswitchInstructionOpt = (SwitchInstruction)jumpTableEntry.Parent;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Add the real catch block entry-point to the block container\n\t\t\t\t\tvar catchBlockHead = ((BlockContainer)result.Handler.Body).Blocks.Last();\n\n\t\t\t\t\tresult.RealCatchBlockEntryPoint.Remove();\n\t\t\t\t\t((BlockContainer)result.Handler.Body).Blocks.Insert(0, result.RealCatchBlockEntryPoint);\n\n\t\t\t\t\t// Remove the generated catch block\n\t\t\t\t\tcatchBlockHead.Remove();\n\n\t\t\t\t\tTransformAsyncThrowToThrow(context, removedBlocks, result.RealCatchBlockEntryPoint);\n\n\t\t\t\t\t// Inline all blocks that are dominated by the entrypoint of the real catch block\n\t\t\t\t\tforeach (var n in cfg.cfg)\n\t\t\t\t\t{\n\t\t\t\t\t\tBlock block = (Block)n.UserData;\n\n\t\t\t\t\t\tif (node.Dominates(n))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tTransformAsyncThrowToThrow(context, removedBlocks, block);\n\n\t\t\t\t\t\t\tif (block.Parent == result.Handler.Body)\n\t\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\t\tif (!removedBlocks.Contains(block))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcontext.Step(\"Move block\", result.Handler.Body);\n\t\t\t\t\t\t\t\tMoveBlock(block, (BlockContainer)result.Handler.Body);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove unreachable pattern blocks\n\t\t\t\t\t// TODO : sanity check\n\t\t\t\t\tif (result.NextBlockOrExitContainer is Block nextBlock && nextBlock.IncomingEdgeCount == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tList<Block> dependentBlocks = new List<Block>();\n\t\t\t\t\t\tBlock current = nextBlock;\n\n\t\t\t\t\t\tdo\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tforeach (var branch in current.Descendants.OfType<Branch>())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdependentBlocks.Add(branch.TargetBlock);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tcurrent.Remove();\n\t\t\t\t\t\t\tdependentBlocks.Remove(current);\n\t\t\t\t\t\t\tcurrent = dependentBlocks.FirstOrDefault(b => b.IncomingEdgeCount == 0);\n\t\t\t\t\t\t} while (current != null);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove all assignments to the common object variable that stores the exception object.\n\t\t\t\t\tif (result.ObjectVariable != result.Handler.Variable)\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var load in result.ObjectVariable.LoadInstructions.ToArray())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!load.IsDescendantOf(result.Handler))\n\t\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\t\tif (load.Parent is CastClass cc && cc.Type.Equals(result.Handler.Variable.Type))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcc.ReplaceWith(new LdLoc(result.Handler.Variable).WithILRange(cc).WithILRange(load));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tload.ReplaceWith(new LdLoc(result.Handler.Variable).WithILRange(load));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcontext.StepEndGroup(keepIfEmpty: true);\n\t\t\t\t}\n\n\t\t\t\tif (switchInstructionOpt != null && switchInstructionOpt.Parent is Block b && b.IncomingEdgeCount > 0)\n\t\t\t\t{\n\t\t\t\t\tvar defaultSection = switchInstructionOpt.GetDefaultSection();\n\n\t\t\t\t\tforeach (var branch in container.Descendants.OfType<Branch>())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (branch.TargetBlock != b)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tbranch.ReplaceWith(defaultSection.Body.Clone());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// clean up all modified containers\n\t\t\tforeach (var container in changedContainers)\n\t\t\t\tcontainer.SortBlocks(deleteUnreachableBlocks: true);\n\t\t}\n\n\t\tprivate static void TransformAsyncThrowToThrow(ILTransformContext context, HashSet<Block> removedBlocks, Block block)\n\t\t{\n\t\t\tILVariable v = null;\n\t\t\tif (MatchExceptionCaptureBlock(context, block,\n\t\t\t\tref v, out StLoc typedExceptionVariableStore,\n\t\t\t\tout Block captureBlock, out Block throwBlock))\n\t\t\t{\n\t\t\t\tcontext.Step($\"ExceptionDispatchInfo.Capture({v.Name}).Throw() => throw;\", typedExceptionVariableStore);\n\t\t\t\tblock.Instructions.RemoveRange(typedExceptionVariableStore.ChildIndex + 1, 2);\n\t\t\t\tcaptureBlock.Remove();\n\t\t\t\tthrowBlock.Remove();\n\t\t\t\tremovedBlocks.Add(captureBlock);\n\t\t\t\tremovedBlocks.Add(throwBlock);\n\t\t\t\ttypedExceptionVariableStore.ReplaceWith(new Rethrow());\n\t\t\t}\n\t\t}\n\n\t\tstatic void MoveBlock(Block block, BlockContainer target)\n\t\t{\n\t\t\tblock.Remove();\n\t\t\ttarget.Blocks.Add(block);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Analyzes all catch handlers and returns every handler that follows the await catch handler pattern.\n\t\t/// </summary>\n\t\tstatic bool AnalyzeHandlers(InstructionCollection<TryCatchHandler> handlers, out ILVariable catchHandlerIdentifier,\n\t\t\tout List<CatchBlockInfo> transformableCatchBlocks)\n\t\t{\n\t\t\ttransformableCatchBlocks = new List<CatchBlockInfo>();\n\t\t\tcatchHandlerIdentifier = null;\n\t\t\tforeach (var handler in handlers)\n\t\t\t{\n\t\t\t\tif (!MatchAwaitCatchHandler(handler, out int id, out var identifierVariable,\n\t\t\t\t\tout var realEntryPoint, out var nextBlockOrExitContainer, out var jumpTableEntry,\n\t\t\t\t\tout var objectVariable))\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (id < 1 || (catchHandlerIdentifier != null && identifierVariable != catchHandlerIdentifier))\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tcatchHandlerIdentifier = identifierVariable;\n\t\t\t\ttransformableCatchBlocks.Add(new(id, handler, realEntryPoint, nextBlockOrExitContainer, jumpTableEntry, objectVariable ?? handler.Variable));\n\t\t\t}\n\t\t\treturn transformableCatchBlocks.Count > 0;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches the await catch handler pattern:\n\t\t/// [stloc V_3(ldloc E_100)\t- copy exception variable to a temporary]\n\t\t/// stloc V_6(ldloc V_3)\t- store exception in 'global' object variable\n\t\t/// stloc V_5(ldc.i4 2)\t\t- store id of catch block in 'identifierVariable'\n\t\t/// br IL_0075\t\t\t\t- jump out of catch block to the head of the catch-handler jump table\n\t\t/// </summary>\n\t\tstatic bool MatchAwaitCatchHandler(TryCatchHandler handler, out int id, out ILVariable identifierVariable,\n\t\t\tout Block realEntryPoint, out ILInstruction nextBlockOrExitContainer,\n\t\t\tout ILInstruction jumpTableEntry, out ILVariable objectVariable)\n\t\t{\n\t\t\tid = 0;\n\t\t\tidentifierVariable = null;\n\t\t\trealEntryPoint = null;\n\t\t\tjumpTableEntry = null;\n\t\t\tobjectVariable = null;\n\t\t\tnextBlockOrExitContainer = null;\n\t\t\tvar exceptionVariable = handler.Variable;\n\t\t\tvar catchBlock = ((BlockContainer)handler.Body).EntryPoint;\n\t\t\tILInstruction value;\n\t\t\tswitch (catchBlock.Instructions.Count)\n\t\t\t{\n\t\t\t\tcase 3:\n\t\t\t\t\tif (!catchBlock.Instructions[0].MatchStLoc(out objectVariable, out value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!value.MatchLdLoc(exceptionVariable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 4:\n\t\t\t\t\tif (!catchBlock.Instructions[0].MatchStLoc(out var temporaryVariable, out value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!value.MatchLdLoc(exceptionVariable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!catchBlock.Instructions[1].MatchStLoc(out objectVariable, out value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!value.MatchLdLoc(temporaryVariable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t// if the exception variable is not used at all (e.g., catch (Exception))\n\t\t\t\t\t// the \"exception-variable-assignment\" is omitted completely.\n\t\t\t\t\t// This can happen in optimized code.\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!catchBlock.Instructions.Last().MatchBranch(out var jumpTableStartBlock))\n\t\t\t\treturn false;\n\t\t\tvar identifierVariableAssignment = catchBlock.Instructions.SecondToLastOrDefault();\n\t\t\tif (identifierVariableAssignment == null)\n\t\t\t\treturn false;\n\t\t\tif (!identifierVariableAssignment.MatchStLoc(out identifierVariable, out value) || !value.MatchLdcI4(out id))\n\t\t\t\treturn false;\n\t\t\t// analyze jump table:\n\t\t\tswitch (jumpTableStartBlock.Instructions.Count)\n\t\t\t{\n\t\t\t\tcase 3:\n\t\t\t\t\t// stloc identifierVariableCopy(identifierVariable)\n\t\t\t\t\t// if (comp(identifierVariable == id)) br realEntryPoint\n\t\t\t\t\t// br jumpTableEntryBlock\n\t\t\t\t\tif (!jumpTableStartBlock.Instructions[0].MatchStLoc(out var identifierVariableCopy, out var identifierVariableLoad)\n\t\t\t\t\t\t|| !identifierVariableLoad.MatchLdLoc(identifierVariable))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn ParseIfJumpTable(id, jumpTableStartBlock, identifierVariableCopy, out realEntryPoint, out nextBlockOrExitContainer, out jumpTableEntry);\n\t\t\t\tcase 2:\n\t\t\t\t\t// if (comp(identifierVariable == id)) br realEntryPoint\n\t\t\t\t\t// br jumpTableEntryBlock\n\t\t\t\t\treturn ParseIfJumpTable(id, jumpTableStartBlock, identifierVariable, out realEntryPoint, out nextBlockOrExitContainer, out jumpTableEntry);\n\t\t\t\tcase 1:\n\t\t\t\t\tif (jumpTableStartBlock.Instructions[0] is not SwitchInstruction switchInst)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn ParseSwitchJumpTable(id, switchInst, identifierVariable, out realEntryPoint, out nextBlockOrExitContainer, out jumpTableEntry);\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tbool ParseSwitchJumpTable(int id, SwitchInstruction jumpTable, ILVariable identifierVariable, out Block realEntryPoint, out ILInstruction nextBlockOrExitContainer, out ILInstruction jumpTableEntry)\n\t\t\t{\n\t\t\t\trealEntryPoint = null;\n\t\t\t\tnextBlockOrExitContainer = null;\n\t\t\t\tjumpTableEntry = null;\n\n\t\t\t\tif (!jumpTable.Value.MatchLdLoc(identifierVariable))\n\t\t\t\t\treturn false;\n\n\t\t\t\tvar defaultSection = jumpTable.GetDefaultSection();\n\n\t\t\t\tforeach (var section in jumpTable.Sections)\n\t\t\t\t{\n\t\t\t\t\tif (!section.Labels.Contains(id))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tif (!section.Body.MatchBranch(out realEntryPoint))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (defaultSection.Body.MatchBranch(out var t))\n\t\t\t\t\t\tnextBlockOrExitContainer = t;\n\t\t\t\t\telse if (defaultSection.Body.MatchLeave(out var t2))\n\t\t\t\t\t\tnextBlockOrExitContainer = t2;\n\t\t\t\t\tjumpTableEntry = section;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tbool ParseIfJumpTable(int id, Block jumpTableEntryBlock, ILVariable identifierVariable, out Block realEntryPoint, out ILInstruction nextBlockOrExitContainer, out ILInstruction jumpTableEntry)\n\t\t\t{\n\t\t\t\trealEntryPoint = null;\n\t\t\t\tnextBlockOrExitContainer = null;\n\t\t\t\tjumpTableEntry = null;\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tif (!(jumpTableEntryBlock.Instructions.SecondToLastOrDefault() is IfInstruction ifInst))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tILInstruction lastInst = jumpTableEntryBlock.Instructions.Last();\n\t\t\t\t\tif (ifInst.Condition.MatchCompEquals(out var left, out var right))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!ifInst.TrueInst.MatchBranch(out realEntryPoint))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!lastInst.MatchBranch(out jumpTableEntryBlock))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!lastInst.MatchLeave((BlockContainer)lastInst.Parent.Parent))\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (ifInst.Condition.MatchCompNotEquals(out left, out right))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!lastInst.MatchBranch(out realEntryPoint))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!ifInst.TrueInst.MatchBranch(out jumpTableEntryBlock))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!ifInst.TrueInst.MatchLeave((BlockContainer)lastInst.Parent.Parent))\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif (!left.MatchLdLoc(identifierVariable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (right.MatchLdcI4(id))\n\t\t\t\t\t{\n\t\t\t\t\t\tnextBlockOrExitContainer = jumpTableEntryBlock ?? lastInst.Parent.Parent;\n\t\t\t\t\t\tjumpTableEntry = ifInst;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t} while (jumpTableEntryBlock?.Instructions.Count == 2);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Block beforeThrowBlock {\n\t\t// \t[before throw]\n\t\t// \tstloc typedExceptionVariable(isinst System.Exception(ldloc objectVariable))\n\t\t// \tif (comp.o(ldloc typedExceptionVariable != ldnull)) br captureBlock\n\t\t// \tbr throwBlock\n\t\t// }\n\t\t// \n\t\t// Block throwBlock {\n\t\t// \tthrow(ldloc objectVariable)\n\t\t// }\n\t\t// \n\t\t// Block captureBlock {\n\t\t// \tcallvirt Throw(call Capture(ldloc typedExceptionVariable))\n\t\t// \tbr nextBlock\n\t\t// }\n\t\t// =>\n\t\t// throw(ldloc result.Handler.Variable)\n\t\tinternal static bool MatchExceptionCaptureBlock(ILTransformContext context, Block block,\n\t\t\tref ILVariable objectVariable, out StLoc typedExceptionVariableStore, out Block captureBlock, out Block throwBlock)\n\t\t{\n\t\t\tbool DerivesFromException(IType t) => t.GetAllBaseTypes().Any(ty => ty.IsKnownType(KnownTypeCode.Exception));\n\n\t\t\tcaptureBlock = null;\n\t\t\tthrowBlock = null;\n\t\t\ttypedExceptionVariableStore = null;\n\n\t\t\tvar typedExceptionVariableStLoc = block.Instructions.ElementAtOrDefault(block.Instructions.Count - 3) as StLoc;\n\n\t\t\tif (typedExceptionVariableStLoc == null\n\t\t\t\t|| !typedExceptionVariableStLoc.Value.MatchIsInst(out var arg, out var type)\n\t\t\t\t|| !DerivesFromException(type)\n\t\t\t\t|| !arg.MatchLdLoc(out var v))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (objectVariable == null)\n\t\t\t{\n\t\t\t\tobjectVariable = v;\n\t\t\t}\n\t\t\telse if (!objectVariable.Equals(v))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\ttypedExceptionVariableStore = typedExceptionVariableStLoc;\n\n\t\t\tif (!block.Instructions[block.Instructions.Count - 2].MatchIfInstruction(out var condition, out var trueInst))\n\t\t\t\treturn false;\n\n\t\t\tILInstruction lastInstr = block.Instructions.Last();\n\t\t\tif (!lastInstr.MatchBranch(out throwBlock))\n\t\t\t\treturn false;\n\n\t\t\tif (condition.MatchCompNotEqualsNull(out arg)\n\t\t\t\t&& trueInst is Branch branchToCapture)\n\t\t\t{\n\t\t\t\tif (!arg.MatchLdLoc(typedExceptionVariableStore.Variable))\n\t\t\t\t\treturn false;\n\t\t\t\tcaptureBlock = branchToCapture.TargetBlock;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (throwBlock.IncomingEdgeCount != 1\n\t\t\t\t|| throwBlock.Instructions.Count != 1\n\t\t\t\t|| !(throwBlock.Instructions[0].MatchThrow(out var ov) && ov.MatchLdLoc(objectVariable)))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (captureBlock.IncomingEdgeCount != 1\n\t\t\t\t|| captureBlock.Instructions.Count != 2\n\t\t\t\t|| !MatchCaptureThrowCalls(captureBlock.Instructions[0]))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t\tbool MatchCaptureThrowCalls(ILInstruction inst)\n\t\t\t{\n\t\t\t\tvar exceptionDispatchInfoType = context.TypeSystem.FindType(typeof(System.Runtime.ExceptionServices.ExceptionDispatchInfo));\n\t\t\t\tif (inst is not CallVirt callVirt || callVirt.Arguments.Count != 1)\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (callVirt.Arguments[0] is not Call call || call.Arguments.Count != 1\n\t\t\t\t\t|| !call.Arguments[0].MatchLdLoc(typedExceptionVariableStLoc.Variable))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn callVirt.Method.Name == \"Throw\"\n\t\t\t\t\t&& callVirt.Method.DeclaringType.Equals(exceptionDispatchInfoType)\n\t\t\t\t\t&& call.Method.Name == \"Capture\"\n\t\t\t\t\t&& call.Method.DeclaringType.Equals(exceptionDispatchInfoType);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ControlFlow/AwaitInFinallyTransform.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.ControlFlow\n{\n\tclass AwaitInFinallyTransform\n\t{\n\t\tpublic static void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.AwaitInCatchFinally)\n\t\t\t\treturn;\n\t\t\tbool needsUnreachableCodeCleanup = false;\n\n\t\t\t// analyze all try-catch statements in the function\n\t\t\tforeach (var tryCatch in function.Descendants.OfType<TryCatch>().ToArray())\n\t\t\t{\n\t\t\t\tif (!(tryCatch.Parent?.Parent is BlockContainer container))\n\t\t\t\t\tcontinue;\n\t\t\t\t// \t} catch exceptionVariable : 02000078 System.Object when (ldc.i4 1) BlockContainer {\n\t\t\t\t// \t\tBlock IL_004a (incoming: 1) {\n\t\t\t\t// \t\t\tstloc objectVariable(ldloc exceptionVariable)\n\t\t\t\t// \t\t\tbr finallyBlock\n\t\t\t\t// \t\t}\n\t\t\t\t// \n\t\t\t\t// \t}\n\t\t\t\t// }\n\t\t\t\t// \n\t\t\t\t// Block finallyBlock (incoming: 2) {\n\t\t\t\t// \tif (comp.o(ldloc b == ldnull)) br afterFinallyBlock\n\t\t\t\t// \tbr finallyBlockContinuation\n\t\t\t\t// }\n\t\t\t\t// \n\t\t\t\t// Block finallyBlockContinuation (incoming: 1) {\n\t\t\t\t// \tawait(addressof System.Threading.Tasks.ValueTask(callvirt DisposeAsync(ldloc b)))\n\t\t\t\t// \tbr afterFinallyBlock\n\t\t\t\t// }\n\t\t\t\t// \n\t\t\t\t// Block afterFinallyBlock (incoming: 2) {\n\t\t\t\t// \tstloc V_1(ldloc objectVariable)\n\t\t\t\t// \tif (comp.o(ldloc V_1 == ldnull)) br IL_00ea\n\t\t\t\t// \tbr IL_00cf\n\t\t\t\t// }\n\n\t\t\t\t// await in finally uses a single catch block with catch-type object\n\t\t\t\tif (tryCatch.Handlers.Count != 1)\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tvar handler = tryCatch.Handlers[0];\n\t\t\t\tvar exceptionVariable = handler.Variable;\n\t\t\t\tif (handler.Body is not BlockContainer catchBlockContainer)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (!exceptionVariable.Type.IsKnownType(KnownTypeCode.Object))\n\t\t\t\t\tcontinue;\n\t\t\t\t// Matches the await finally pattern:\n\t\t\t\t// [stloc V_3(ldloc E_100)\t- copy exception variable to a temporary]\n\t\t\t\t// stloc V_6(ldloc V_3)\t- store exception in 'global' object variable\n\t\t\t\t// br IL_0075\t\t\t\t- jump out of catch block to the head of the finallyBlock\n\t\t\t\tvar catchBlockEntry = catchBlockContainer.EntryPoint;\n\t\t\t\tILVariable objectVariable;\n\t\t\t\tswitch (catchBlockEntry.Instructions.Count)\n\t\t\t\t{\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tif (!catchBlockEntry.Instructions[0].MatchStLoc(out objectVariable, out var value))\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tif (!value.MatchLdLoc(exceptionVariable))\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\tif (!catchBlockEntry.Instructions[0].MatchStLoc(out var temporaryVariable, out value))\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tif (!value.MatchLdLoc(exceptionVariable))\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tif (!catchBlockEntry.Instructions[1].MatchStLoc(out objectVariable, out value))\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tif (!value.MatchLdLoc(temporaryVariable))\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!catchBlockEntry.Instructions[catchBlockEntry.Instructions.Count - 1].MatchBranch(out var entryPointOfFinally))\n\t\t\t\t\tcontinue;\n\t\t\t\t// globalCopyVar should only be used once, at the end of the finally-block\n\t\t\t\tif (objectVariable.LoadCount != 1 || objectVariable.StoreCount > 2)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tvar beforeExceptionCaptureBlock = Block.FindClosestBlock(objectVariable.LoadInstructions[0]);\n\t\t\t\tif (beforeExceptionCaptureBlock == null)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tvar (noThrowBlock, exceptionCaptureBlock, objectVariableCopy) = FindBlockAfterFinally(context, beforeExceptionCaptureBlock, objectVariable);\n\t\t\t\tif (noThrowBlock == null || exceptionCaptureBlock == null)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tvar initOfStateVariable = tryCatch.Parent.Children.ElementAtOrDefault(tryCatch.ChildIndex - 1) as StLoc;\n\t\t\t\tif (initOfStateVariable == null || !initOfStateVariable.Value.MatchLdcI4(0))\n\t\t\t\t\tcontinue;\n\n\t\t\t\tvar stateVariable = initOfStateVariable.Variable;\n\t\t\t\tif (!ValidateStateVariable(stateVariable, initOfStateVariable, tryCatch, entryPointOfFinally))\n\t\t\t\t\tcontinue;\n\n\t\t\t\tStateRangeAnalysis sra = new StateRangeAnalysis(StateRangeAnalysisMode.AwaitInFinally, null, stateVariable);\n\t\t\t\tsra.AssignStateRanges(noThrowBlock, Util.LongSet.Universe);\n\t\t\t\tvar mapping = sra.GetBlockStateSetMapping((BlockContainer)noThrowBlock.Parent);\n\t\t\t\tvar mappingForLeave = sra.GetBlockStateSetMappingForLeave();\n\n\t\t\t\tcontext.StepStartGroup(\"Inline finally block with await\", tryCatch.Handlers[0]);\n\t\t\t\tvar cfg = new ControlFlowGraph(container, context.CancellationToken);\n\t\t\t\tneedsUnreachableCodeCleanup = true;\n\n\t\t\t\tvar finallyContainer = new BlockContainer().WithILRange(catchBlockContainer);\n\t\t\t\ttryCatch.ReplaceWith(new TryFinally(tryCatch.TryBlock, finallyContainer).WithILRange(tryCatch.TryBlock));\n\n\t\t\t\tcontext.Step(\"Move blocks into finally\", finallyContainer);\n\t\t\t\tMoveDominatedBlocksToContainer(entryPointOfFinally, beforeExceptionCaptureBlock, cfg, finallyContainer);\n\n\t\t\t\tSimplifyEndOfFinally(context, objectVariable, beforeExceptionCaptureBlock, objectVariableCopy, finallyContainer);\n\n\t\t\t\tif (noThrowBlock.Instructions[0].MatchLdLoc(stateVariable))\n\t\t\t\t{\n\t\t\t\t\tnoThrowBlock.Instructions.RemoveAt(0);\n\t\t\t\t}\n\n\t\t\t\tforeach (var branch in tryCatch.TryBlock.Descendants.OfType<Branch>())\n\t\t\t\t{\n\t\t\t\t\tif (branch.TargetBlock == entryPointOfFinally)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!(branch.Parent is Block block && branch.ChildIndex > 0\n\t\t\t\t\t\t\t&& block.Instructions[branch.ChildIndex - 1].MatchStLoc(stateVariable, out var v)\n\t\t\t\t\t\t\t&& v.MatchLdcI4(out int value)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (mapping.TryGetValue(value, out Block targetBlock))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontext.Step($\"branch to finally with state {value} => branch to state target \" + targetBlock.Label, branch);\n\t\t\t\t\t\t\tbranch.TargetBlock = targetBlock;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (mappingForLeave.TryGetValue(value, out BlockContainer targetContainer))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontext.Step($\"branch to finally with state {value} => leave to state target \" + targetContainer, branch);\n\t\t\t\t\t\t\tbranch.ReplaceWith(new Leave(targetContainer).WithILRange(branch));\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontext.Step(\"branch to finally => branch after finally\", branch);\n\t\t\t\t\t\t\tbranch.TargetBlock = noThrowBlock;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(branch.TargetBlock.IsDescendantOf(tryCatch.TryBlock));\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcontext.StepEndGroup(keepIfEmpty: true);\n\t\t\t}\n\n\t\t\tcontext.Step(\"Clean up\", function);\n\n\t\t\tif (needsUnreachableCodeCleanup)\n\t\t\t{\n\t\t\t\t// Cleaning up only the modified containers is insufficient, deleting blocks in\n\t\t\t\t// any container can also cause other blocks in parent containers to become unreachable.\n\t\t\t\t// So we just clean up everything.\n\t\t\t\tforeach (var container in function.Body.Descendants.OfType<BlockContainer>())\n\t\t\t\t{\n\t\t\t\t\tcontainer.SortBlocks(deleteUnreachableBlocks: true);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid MoveDominatedBlocksToContainer(Block newEntryPoint, Block endBlock, ControlFlowGraph graph,\n\t\t\t\tBlockContainer targetContainer)\n\t\t\t{\n\t\t\t\tvar node = graph.GetNode(newEntryPoint);\n\t\t\t\tvar endNode = endBlock == null ? null : graph.GetNode(endBlock);\n\n\t\t\t\tMoveBlock(newEntryPoint, targetContainer);\n\n\t\t\t\tforeach (var n in graph.cfg)\n\t\t\t\t{\n\t\t\t\t\tBlock block = (Block)n.UserData;\n\n\t\t\t\t\tif (node.Dominates(n))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (endNode != null && endNode != n && endNode.Dominates(n))\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\tif (block.Parent == targetContainer)\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\tMoveBlock(block, targetContainer);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid MoveBlock(Block block, BlockContainer target)\n\t\t\t{\n\t\t\t\tcontext.Step($\"Move {block.Label} to container at IL_{target.StartILOffset:x4}\", target);\n\t\t\t\tblock.Remove();\n\t\t\t\ttarget.Blocks.Add(block);\n\t\t\t}\n\n\t\t\tstatic void SimplifyEndOfFinally(ILTransformContext context, ILVariable objectVariable, Block beforeExceptionCaptureBlock, ILVariable objectVariableCopy, BlockContainer finallyContainer)\n\t\t\t{\n\t\t\t\tif (beforeExceptionCaptureBlock.Instructions.Count >= 3\n\t\t\t\t\t&& beforeExceptionCaptureBlock.Instructions.SecondToLastOrDefault().MatchIfInstruction(out var cond, out var brInst)\n\t\t\t\t\t&& beforeExceptionCaptureBlock.Instructions.LastOrDefault() is Branch branch\n\t\t\t\t\t&& beforeExceptionCaptureBlock.Instructions[beforeExceptionCaptureBlock.Instructions.Count - 3].MatchStLoc(objectVariableCopy, out var value)\n\t\t\t\t\t&& value.MatchLdLoc(objectVariable))\n\t\t\t\t{\n\t\t\t\t\tif (cond.MatchCompEqualsNull(out var arg) && arg.MatchLdLoc(objectVariableCopy))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontext.Step(\"Simplify end of finally\", beforeExceptionCaptureBlock);\n\t\t\t\t\t\tbeforeExceptionCaptureBlock.Instructions.RemoveRange(beforeExceptionCaptureBlock.Instructions.Count - 3, 2);\n\t\t\t\t\t\tbranch.ReplaceWith(new Leave(finallyContainer).WithILRange(branch));\n\t\t\t\t\t}\n\t\t\t\t\telse if (cond.MatchCompNotEqualsNull(out arg) && arg.MatchLdLoc(objectVariableCopy))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontext.Step(\"Simplify end of finally\", beforeExceptionCaptureBlock);\n\t\t\t\t\t\tbeforeExceptionCaptureBlock.Instructions.RemoveRange(beforeExceptionCaptureBlock.Instructions.Count - 3, 2);\n\t\t\t\t\t\tbranch.ReplaceWith(new Leave(finallyContainer).WithILRange(branch));\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Fail(\"Broken beforeExceptionCaptureBlock\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tDebug.Fail(\"Broken beforeExceptionCaptureBlock\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate static bool ValidateStateVariable(ILVariable stateVariable, StLoc initializer, TryCatch tryCatch, Block entryPointOfFinally)\n\t\t{\n\t\t\tif (stateVariable.AddressCount > 0)\n\t\t\t\treturn false;\n\n\t\t\tforeach (var store in stateVariable.StoreInstructions)\n\t\t\t{\n\t\t\t\tif (store == initializer)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (store is not StLoc stloc)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!stloc.Value.MatchLdcI4(out _))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!stloc.IsDescendantOf(tryCatch))\n\t\t\t\t\treturn false;\n\t\t\t\tif (stloc.Parent is not Block block)\n\t\t\t\t\treturn false;\n\t\t\t\tif (block.Instructions.ElementAtOrDefault(stloc.ChildIndex + 1)?.MatchBranch(entryPointOfFinally) != true)\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic (Block, Block, ILVariable) FindBlockAfterFinally(ILTransformContext context, Block block, ILVariable objectVariable)\n\t\t{\n\t\t\t// Block IL_0327 (incoming: 2) {\n\t\t\t// \tstloc V_7(ldloc I_0)\n\t\t\t// \tif (comp.o(ldloc V_7 == ldnull)) br IL_034a\n\t\t\t// \tbr IL_0333\n\t\t\t// }\n\t\t\tint count = block.Instructions.Count;\n\t\t\tif (count < 3)\n\t\t\t\treturn default;\n\n\t\t\tif (!block.Instructions[count - 3].MatchStLoc(out var objectVariableCopy, out var value))\n\t\t\t\treturn default;\n\n\t\t\tif (!value.MatchLdLoc(objectVariable))\n\t\t\t\treturn default;\n\n\t\t\tif (!block.Instructions[count - 2].MatchIfInstruction(out var cond, out var noThrowBlockBranch))\n\t\t\t\treturn default;\n\n\t\t\tif (!noThrowBlockBranch.MatchBranch(out var noThrowBlock))\n\t\t\t\treturn default;\n\n\t\t\tif (!block.Instructions[count - 1].MatchBranch(out var exceptionCaptureBlock))\n\t\t\t\treturn default;\n\n\t\t\tif (cond.MatchCompEqualsNull(out var arg))\n\t\t\t{\n\t\t\t\tif (!arg.MatchLdLoc(objectVariableCopy))\n\t\t\t\t\treturn default;\n\t\t\t}\n\t\t\telse if (cond.MatchCompNotEqualsNull(out arg))\n\t\t\t{\n\t\t\t\tif (!arg.MatchLdLoc(objectVariableCopy))\n\t\t\t\t\treturn default;\n\t\t\t\t(noThrowBlock, exceptionCaptureBlock) = (exceptionCaptureBlock, noThrowBlock);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn default;\n\t\t\t}\n\n\t\t\tif (!AwaitInCatchTransform.MatchExceptionCaptureBlock(context, exceptionCaptureBlock,\n\t\t\t\tref objectVariableCopy, out _, out _, out _))\n\t\t\t{\n\t\t\t\treturn default;\n\t\t\t}\n\n\t\t\treturn (noThrowBlock, exceptionCaptureBlock, objectVariableCopy);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ControlFlow/ConditionDetection.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.FlowAnalysis;\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.ControlFlow\n{\n\t/// <summary>\n\t/// Detects 'if' structure and other non-loop aspects of control flow.\n\t/// </summary>\n\t/// <remarks>\n\t/// Order dependency: should run after loop detection.\n\t/// Blocks should be basic blocks prior to this transform.\n\t/// After this transform, they will be extended basic blocks.\n\t/// </remarks>\n\tpublic class ConditionDetection : IBlockTransform\n\t{\n\t\tprivate enum Keyword\n\t\t{\n\t\t\tBreak,\n\t\t\tReturn,\n\t\t\tContinue,\n\t\t\tOther\n\t\t}\n\n\t\tprivate BlockTransformContext context;\n\t\tprivate ControlFlowNode cfgNode;\n\t\tprivate BlockContainer currentContainer;\n\n\t\t/// <summary>\n\t\t/// Builds structured control flow for the block associated with the control flow node.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// After a block was processed, it should use structured control flow\n\t\t/// and have just a single 'regular' exit point (last branch instruction in the block)\n\t\t/// </remarks>\n\t\tpublic void Run(Block block, BlockTransformContext context)\n\t\t{\n\t\t\tthis.context = context;\n\t\t\tcurrentContainer = (BlockContainer)block.Parent;\n\n\t\t\t// We only embed blocks into this block if they aren't referenced anywhere else,\n\t\t\t// so those blocks are dominated by this block.\n\t\t\t// BlockILTransform thus guarantees that the blocks being embedded are already\n\t\t\t// fully processed.\n\n\t\t\tcfgNode = context.ControlFlowNode;\n\t\t\tDebug.Assert(cfgNode.UserData == block);\n\n\t\t\t// Because this transform runs at the beginning of the block transforms,\n\t\t\t// we know that `block` is still a (non-extended) basic block.\n\n\t\t\t// Previous-to-last instruction might have conditional control flow,\n\t\t\t// usually an IfInstruction with a branch:\n\t\t\tif (block.Instructions.SecondToLastOrDefault() is IfInstruction ifInst)\n\t\t\t\tHandleIfInstruction(block, ifInst);\n\t\t\telse\n\t\t\t\tInlineExitBranch(block);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Repeatedly inlines and simplifies, maintaining a good block exit and then attempting to match IL order\n\t\t/// </summary>\n\t\tprivate void HandleIfInstruction(Block block, IfInstruction ifInst)\n\t\t{\n\t\t\twhile (InlineTrueBranch(block, ifInst) || InlineExitBranch(block))\n\t\t\t{\n\t\t\t\tPickBetterBlockExit(block, ifInst);\n\t\t\t\tMergeCommonBranches(block, ifInst);\n\t\t\t\tSwapEmptyThen(ifInst);\n\t\t\t\tIntroduceShortCircuit(ifInst);\n\t\t\t}\n\t\t\tPickBetterBlockExit(block, ifInst);\n\t\t\tOrderIfBlocks(ifInst);\n\t\t\tcontext.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count;\n\t\t}\n\n\t\t/// <summary>\n\t\t///   if (...) br trueBlock;\n\t\t/// ->\n\t\t///   if (...) { trueBlock... }\n\t\t/// \n\t\t/// Only inlines branches that are strictly dominated by this block (incoming edge count == 1)\n\t\t/// </summary>\n\t\tprivate bool InlineTrueBranch(Block block, IfInstruction ifInst)\n\t\t{\n\t\t\tif (!CanInline(ifInst.TrueInst))\n\t\t\t{\n\t\t\t\tif (block.Instructions.SecondToLastOrDefault() == ifInst && ifInst.FalseInst.MatchNop())\n\t\t\t\t{\n\t\t\t\t\tvar exitInst = block.Instructions.Last();\n\t\t\t\t\tif (DetectExitPoints.CompatibleExitInstruction(ifInst.TrueInst, exitInst))\n\t\t\t\t\t{\n\t\t\t\t\t\t// if (...) exitInst; exitInst;\n\t\t\t\t\t\tcontext.Step(\"Use empty block as then-branch\", ifInst.TrueInst);\n\t\t\t\t\t\tifInst.TrueInst = new Nop().WithILRange(ifInst.TrueInst);\n\t\t\t\t\t\t// false, because we didn't inline a real block\n\t\t\t\t\t\t// this will cause HandleIfInstruction() to attempt to inline the exitInst.\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tcontext.Step(\"Inline block as then-branch\", ifInst.TrueInst);\n\t\t\t// The targetBlock was already processed, and is ready to embed\n\t\t\tvar targetBlock = ((Branch)ifInst.TrueInst).TargetBlock;\n\t\t\ttargetBlock.AddRef();  // Peformance: avoid temporarily disconnecting targetBlock\n\t\t\ttargetBlock.Remove();\n\t\t\tifInst.TrueInst = targetBlock;\n\t\t\ttargetBlock.ReleaseRef();\n\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t///   ...; br nextBlock;\n\t\t/// ->\n\t\t///   ...; { nextBlock... }\n\t\t/// \n\t\t/// Only inlines branches that are strictly dominated by this block (incoming edge count == 1)\n\t\t/// </summary>\n\t\tprivate bool InlineExitBranch(Block block)\n\t\t{\n\t\t\tvar exitInst = GetExit(block);\n\t\t\tif (!CanInline(exitInst))\n\t\t\t\treturn false;\n\n\t\t\tcontext.Step(\"Inline target block of unconditional branch\", exitInst);\n\t\t\t// The targetBlock was already processed, and is ready to embed\n\t\t\tvar targetBlock = ((Branch)exitInst).TargetBlock;\n\t\t\tblock.Instructions.RemoveAt(block.Instructions.Count - 1);\n\t\t\tcontext.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count;\n\t\t\tblock.Instructions.AddRange(targetBlock.Instructions);\n\t\t\ttargetBlock.Remove();\n\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether <c>potentialBranchInstruction</c> is a branch to a block that is dominated by <c>cfgNode</c>.\n\t\t/// If this function returns true, we replace the branch instruction with the block itself.\n\t\t/// </summary>\n\t\tprivate bool CanInline(ILInstruction exitInst)\n\t\t{\n\t\t\tif (exitInst is Branch branch\n\t\t\t\t&& branch.TargetBlock.Parent == currentContainer\n\t\t\t\t&& branch.TargetBlock.IncomingEdgeCount == 1)\n\t\t\t{\n\t\t\t\t// if the incoming edge count is 1, then this must be the sole branch, and dominance is already ensured\n\t\t\t\tDebug.Assert(cfgNode.Dominates(context.ControlFlowGraph.GetNode(branch.TargetBlock)));\n\t\t\t\t// can't have \"final instructions\" in control flow blocks\n\t\t\t\tDebug.Assert(branch.TargetBlock.FinalInstruction is Nop);\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Looks for common exits in the inlined then and else branches of an if instruction\n\t\t/// and performs inversions and simplifications to merge them provided they don't \n\t\t/// isolate a higher priority block exit\n\t\t/// </summary>\n\t\tprivate void MergeCommonBranches(Block block, IfInstruction ifInst)\n\t\t{\n\t\t\tvar thenExits = new List<ILInstruction>();\n\t\t\tAddExits(ifInst.TrueInst, 0, thenExits);\n\t\t\tif (thenExits.Count == 0)\n\t\t\t\treturn;\n\n\t\t\t// if there are any exits from the then branch, then the else is redundant and shouldn't exist\n\t\t\tDebug.Assert(IsEmpty(ifInst.FalseInst));\n\t\t\tDebug.Assert(ifInst.Parent == block);\n\t\t\tvar elseExits = new List<ILInstruction>();\n\t\t\tint falseInstIndex = block.Instructions.IndexOf(ifInst) + 1;\n\t\t\tAddExits(block, falseInstIndex, elseExits);\n\n\t\t\tvar commonExits = elseExits.Where(e1 => thenExits.Any(e2 => DetectExitPoints.CompatibleExitInstruction(e1, e2)));\n\n\t\t\t// find the common exit with the highest block exit priority\n\t\t\tILInstruction commonExit = null;\n\t\t\tforeach (var exit in commonExits)\n\t\t\t{\n\t\t\t\tif (commonExit == null || CompareBlockExitPriority(exit, commonExit) > 0)\n\t\t\t\t\tcommonExit = exit;\n\t\t\t}\n\n\t\t\tif (commonExit == null)\n\t\t\t\treturn;\n\n\t\t\t// if the current block exit has higher priority than the exits to merge,\n\t\t\t// determine if this merge will isolate the current block exit\n\t\t\t// that is, no sequence of inversions can restore it to the block exit position\n\t\t\tvar blockExit = block.Instructions.Last();\n\t\t\tif (CompareBlockExitPriority(blockExit, commonExit, true) > 0 && !WillShortCircuit(block, ifInst, commonExit))\n\t\t\t\treturn;\n\n\t\t\t// could improve performance by directly implementing the || short-circuit when WillShortCircuit\n\t\t\t// currently the same general sequence of transformations introduces both operators\n\n\t\t\tcontext.StepStartGroup(\"Merge common branches \" + commonExit, ifInst);\n\t\t\tProduceExit(ifInst.TrueInst, 0, commonExit);\n\t\t\tProduceExit(block, falseInstIndex, commonExit);\n\n\t\t\t// if (...) { ...; blockExit; } ...; blockExit;\n\t\t\t// -> if (...) { ...; blockExit; } else { ... } blockExit;\n\t\t\tif (ifInst != block.Instructions.SecondToLastOrDefault())\n\t\t\t{\n\t\t\t\tcontext.Step(\"Embed else-block for goto removal\", ifInst);\n\t\t\t\tDebug.Assert(IsEmpty(ifInst.FalseInst));\n\t\t\t\tBlock newBlock = new Block();\n\t\t\t\tifInst.FalseInst = newBlock;\n\t\t\t\tExtractBlock(block, block.Instructions.IndexOf(ifInst) + 1, block.Instructions.Count - 1, newBlock);\n\t\t\t}\n\n\t\t\t// if (...) { ...; goto blockExit; } blockExit;\n\t\t\t// -> if (...) { ... } blockExit;\n\t\t\t// OR\n\t\t\t// if (...) { ...; goto blockExit; } else { ... } blockExit;\n\t\t\t// -> if (...) { ... } else { ... } blockExit;\n\t\t\tcontext.Step(\"Remove redundant 'goto blockExit;' in then-branch\", ifInst);\n\t\t\tif (!(ifInst.TrueInst is Block trueBlock) || trueBlock.Instructions.Count == 1)\n\t\t\t\tifInst.TrueInst = new Nop().WithILRange(ifInst.TrueInst);\n\t\t\telse\n\t\t\t\ttrueBlock.Instructions.RemoveAt(trueBlock.Instructions.Count - 1);\n\n\t\t\tcontext.StepEndGroup();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Finds all exits which could be brought to the block root via inversion\n\t\t/// </summary>\n\t\tprivate void AddExits(ILInstruction searchInst, int startIndex, IList<ILInstruction> exits)\n\t\t{\n\t\t\tif (!TryGetExit(searchInst, out var exitInst))\n\t\t\t\treturn;\n\n\t\t\texits.Add(exitInst);\n\t\t\tif (searchInst is Block block)\n\t\t\t{\n\t\t\t\tfor (int i = startIndex; i < block.Instructions.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (block.Instructions[i] is IfInstruction ifInst)\n\t\t\t\t\t\tAddExits(ifInst.TrueInst, 0, exits);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Recursively performs inversions to bring a desired exit to the root of the block\n\t\t/// for example:\n\t\t///   if (a) {\n\t\t///     ...;\n\t\t///     if (b) {\n\t\t///       ...;\n\t\t///       targetExit;\n\t\t///     }\n\t\t///     ...;\n\t\t///     exit1;\n\t\t///   }\n\t\t///   ...;\n\t\t///   exit2;\n\t\t/// ->\n\t\t///   if (!a) {\n\t\t///     ...;\n\t\t///     exit2;\n\t\t///   }\n\t\t///   ...;\n\t\t///   if (!b) {\n\t\t///     ...;\n\t\t///     exit1;\n\t\t///   }\n\t\t///   ...;\n\t\t///   targetExit;\n\t\t/// </summary>\n\t\tprivate bool ProduceExit(ILInstruction searchInst, int startIndex, ILInstruction targetExit)\n\t\t{\n\t\t\tif (!TryGetExit(searchInst, out var exitInst))\n\t\t\t\treturn false;\n\n\t\t\tif (DetectExitPoints.CompatibleExitInstruction(exitInst, targetExit))\n\t\t\t\treturn true;\n\n\t\t\tif (searchInst is Block block)\n\t\t\t{\n\t\t\t\tfor (int i = startIndex; i < block.Instructions.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (block.Instructions[i] is IfInstruction ifInst && ProduceExit(ifInst.TrueInst, 0, targetExit))\n\t\t\t\t\t{\n\t\t\t\t\t\tInvertIf(block, ifInst);\n\t\t\t\t\t\tDebug.Assert(DetectExitPoints.CompatibleExitInstruction(GetExit(block), targetExit));\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Anticipates the introduction of an || operator when merging ifInst and elseExit\n\t\t/// \n\t\t///   if (cond) commonExit;\n\t\t///   if (cond2) commonExit;\n\t\t///   ...;\n\t\t///   blockExit;\n\t\t/// will become:\n\t\t///   if (cond || cond2) commonExit;\n\t\t///   ...;\n\t\t///   blockExit;\n\t\t/// </summary>\n\t\tprivate bool WillShortCircuit(Block block, IfInstruction ifInst, ILInstruction elseExit)\n\t\t{\n\t\t\tbool ThenInstIsSingleExit(ILInstruction inst) =>\n\t\t\t\tinst.MatchIfInstruction(out var _, out var trueInst)\n\t\t\t\t&& (!(trueInst is Block trueBlock) || trueBlock.Instructions.Count == 1)\n\t\t\t\t&& TryGetExit(trueInst, out var _);\n\n\t\t\tif (!ThenInstIsSingleExit(ifInst))\n\t\t\t\treturn false;\n\n\t\t\t// find the host if statement\n\t\t\tvar elseIfInst = elseExit;\n\t\t\twhile (elseIfInst.Parent != block)\n\t\t\t{\n\t\t\t\telseIfInst = elseIfInst.Parent;\n\t\t\t}\n\n\t\t\treturn block.Instructions.IndexOf(elseIfInst) == block.Instructions.IndexOf(ifInst) + 1\n\t\t\t\t   && ThenInstIsSingleExit(elseIfInst);\n\t\t}\n\n\t\tprivate void InvertIf(Block block, IfInstruction ifInst) => InvertIf(block, ifInst, context);\n\n\t\t/// <summary>\n\t\t///   if (cond) { then... }\n\t\t///   else...;\n\t\t///   exit;\n\t\t/// ->\n\t\t///   if (!cond) { else...; exit }\n\t\t///   then...;\n\t\t/// \n\t\t/// Assumes ifInst does not have an else block\n\t\t/// </summary>\n\t\tinternal static void InvertIf(Block block, IfInstruction ifInst, ILTransformContext context)\n\t\t{\n\t\t\tDebug.Assert(ifInst.Parent == block);\n\n\t\t\t//assert then block terminates\n\t\t\tvar exitInst = GetExit(block);\n\t\t\tcontext.Step($\"InvertIf at IL_{ifInst.StartILOffset:x4}\", ifInst);\n\n\t\t\t//if the then block terminates, else blocks are redundant, and should not exist\n\t\t\tDebug.Assert(IsEmpty(ifInst.FalseInst));\n\n\t\t\t//save a copy\n\t\t\tvar thenInst = ifInst.TrueInst;\n\t\t\tthenInst.AddRef();\n\n\t\t\tif (ifInst != block.Instructions.SecondToLastOrDefault())\n\t\t\t{\n\t\t\t\t// extract \"else...; exit\".\n\t\t\t\t// Note that this will only extract instructions that were previously inlined from another block\n\t\t\t\t// (via InlineExitBranch), so the instructions are already fully-transformed.\n\t\t\t\t// So it's OK to move them into a nested block again (which hides them from the following block transforms).\n\t\t\t\tvar newBlock = new Block();\n\t\t\t\tifInst.TrueInst = newBlock;\n\t\t\t\tExtractBlock(block, block.Instructions.IndexOf(ifInst) + 1, block.Instructions.Count, newBlock);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tifInst.TrueInst = exitInst;\n\t\t\t\tblock.Instructions.RemoveAt(block.Instructions.Count - 1);\n\t\t\t}\n\n\t\t\tif (thenInst is Block thenBlock)\n\t\t\t{\n\t\t\t\tblock.Instructions.AddRange(thenBlock.Instructions);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tblock.Instructions.Add(thenInst);\n\t\t\t}\n\t\t\tthenInst.ReleaseRef();\n\n\t\t\tifInst.Condition = Comp.LogicNot(ifInst.Condition);\n\t\t\tExpressionTransforms.RunOnSingleStatement(ifInst, context);\n\t\t}\n\n\t\t/// <summary>\n\t\t///   if (cond) { } else { ... }\n\t\t/// ->\n\t\t///   if (!cond) { ... }\n\t\t/// </summary>\n\t\tprivate void SwapEmptyThen(IfInstruction ifInst)\n\t\t{\n\t\t\tif (!IsEmpty(ifInst.TrueInst))\n\t\t\t\treturn;\n\n\t\t\tcontext.Step(\"Swap empty then-branch with else-branch\", ifInst);\n\t\t\tvar oldTrue = ifInst.TrueInst;\n\t\t\tifInst.TrueInst = ifInst.FalseInst;\n\t\t\tifInst.FalseInst = new Nop().WithILRange(oldTrue);\n\t\t\tifInst.Condition = Comp.LogicNot(ifInst.Condition);\n\t\t}\n\n\t\t/// <summary>\n\t\t///   if (cond) { if (nestedCond) { nestedThen... } }\n\t\t/// ->\n\t\t///   if (cond &amp;&amp; nestedCond) { nestedThen... }\n\t\t/// </summary>\n\t\tprivate void IntroduceShortCircuit(IfInstruction ifInst)\n\t\t{\n\t\t\tif (IsEmpty(ifInst.FalseInst)\n\t\t\t\t\t&& ifInst.TrueInst is Block trueBlock\n\t\t\t\t\t&& trueBlock.Instructions.Count == 1\n\t\t\t\t\t&& trueBlock.FinalInstruction is Nop\n\t\t\t\t\t&& trueBlock.Instructions[0].MatchIfInstruction(out var nestedCondition, out var nestedTrueInst))\n\t\t\t{\n\t\t\t\tcontext.Step(\"Combine 'if (cond1 && cond2)' in then-branch\", ifInst);\n\t\t\t\tifInst.Condition = IfInstruction.LogicAnd(ifInst.Condition, nestedCondition);\n\t\t\t\tifInst.TrueInst = nestedTrueInst;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t///   if (cond) { lateBlock... } else { earlyBlock... }\n\t\t/// ->\n\t\t///   if (!cond) { earlyBlock... } else { lateBlock... }\n\t\t/// </summary>\n\t\tprivate void OrderIfBlocks(IfInstruction ifInst)\n\t\t{\n\t\t\tif (IsEmpty(ifInst.FalseInst) || GetStartILOffset(ifInst.TrueInst, out _) <= GetStartILOffset(ifInst.FalseInst, out _))\n\t\t\t\treturn;\n\n\t\t\tcontext.Step(\"Swap then-branch with else-branch to match IL order\", ifInst);\n\t\t\tvar oldTrue = ifInst.TrueInst;\n\t\t\toldTrue.AddRef(); // Peformance: avoid temporarily disconnecting oldTrue\n\t\t\tifInst.TrueInst = ifInst.FalseInst;\n\t\t\tifInst.FalseInst = oldTrue;\n\t\t\toldTrue.ReleaseRef();\n\t\t\tifInst.Condition = Comp.LogicNot(ifInst.Condition);\n\t\t}\n\n\t\tpublic static int GetStartILOffset(ILInstruction inst, out bool isEmpty)\n\t\t{\n\t\t\t// some compilers merge the leave instructions for different arguments using stack variables\n\t\t\t// these get split and inlined, but the ILRange of the value remains a better indicator of the actual location\n\t\t\tif (inst is Leave leave && !leave.Value.MatchNop())\n\t\t\t{\n\t\t\t\tisEmpty = leave.Value.ILRangeIsEmpty;\n\t\t\t\treturn leave.Value.StartILOffset;\n\t\t\t}\n\n\t\t\tisEmpty = inst.ILRangeIsEmpty;\n\t\t\treturn inst.StartILOffset;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Compares the current block exit, and the exit of ifInst.ThenInst \n\t\t/// and inverts if necessary to pick the better exit\n\t\t/// \n\t\t/// Does nothing when ifInst has an else block (because inverting wouldn't affect the block exit)\n\t\t/// </summary>\n\t\tprivate void PickBetterBlockExit(Block block, IfInstruction ifInst)\n\t\t{\n\t\t\tvar exitInst = GetExit(block);\n\t\t\tif (IsEmpty(ifInst.FalseInst)\n\t\t\t\t  && TryGetExit(ifInst.TrueInst, out var trueExitInst)\n\t\t\t\t  && CompareBlockExitPriority(trueExitInst, exitInst) > 0)\n\t\t\t\tInvertIf(block, ifInst);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Compares two exit instructions for block exit priority\n\t\t/// A higher priority exit should be kept as the last instruction in a block\n\t\t/// even if it prevents the merging of a two compatible lower priority exits\n\t\t/// \n\t\t/// leave from try containers must always be the final instruction, or a goto will be inserted\n\t\t/// loops will endeavour to leave at least one continue branch as the last instruction in the block\n\t\t/// \n\t\t/// The priority is:\n\t\t///   leave > branch > other-keyword > continue > return > break\n\t\t/// \n\t\t/// non-keyword leave instructions are ordered with the outer container having higher priority\n\t\t/// \n\t\t/// if the exits have equal priority, and the <c>strongly</c> flag is not provided\n\t\t/// then the exits are sorted by IL order (target block for branches)\n\t\t/// \n\t\t/// break has higher priority than other keywords in a switch block (for aesthetic reasons)\n\t\t/// </summary>\n\t\t/// <returns>{-1, 0, 1} if exit1 has {lower, equal, higher} priority an exit2</returns>\n\t\tprivate int CompareBlockExitPriority(ILInstruction exit1, ILInstruction exit2, bool strongly = false)\n\t\t{\n\t\t\t// keywords have lower priority than non-keywords\n\t\t\tbool isKeyword1 = IsKeywordExit(exit1, out var keyword1);\n\t\t\tbool isKeyword2 = IsKeywordExit(exit2, out var keyword2);\n\t\t\tif (isKeyword1 != isKeyword2)\n\t\t\t\treturn isKeyword1 ? -1 : 1;\n\n\t\t\tif (isKeyword1)\n\t\t\t{\n\t\t\t\t//for keywords\n\t\t\t\tif (currentContainer.Kind == ContainerKind.Switch)\n\t\t\t\t{\n\t\t\t\t\t// breaks have highest priority in a switch\n\t\t\t\t\tif ((keyword1 == Keyword.Break) != (keyword2 == Keyword.Break))\n\t\t\t\t\t\treturn keyword1 == Keyword.Break ? 1 : -1;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// breaks have lowest priority\n\t\t\t\t\tif ((keyword1 == Keyword.Break) != (keyword2 == Keyword.Break))\n\t\t\t\t\t\treturn keyword1 == Keyword.Break ? -1 : 1;\n\n\t\t\t\t\t// continue has highest priority (to prevent having to jump to the end of a loop block)\n\t\t\t\t\tif ((keyword1 == Keyword.Continue) != (keyword2 == Keyword.Continue))\n\t\t\t\t\t\treturn keyword1 == Keyword.Continue ? 1 : -1;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{// for non-keywords (only Branch or Leave)\n\t\t\t // branches have lower priority than non-keyword leaves\n\t\t\t\tbool isBranch1 = exit1 is Branch;\n\t\t\t\tbool isBranch2 = exit2 is Branch;\n\t\t\t\tif (isBranch1 != isBranch2)\n\t\t\t\t\treturn isBranch1 ? -1 : 1;\n\n\t\t\t\t// two leaves that both want end of block priority\n\t\t\t\tif (exit1.MatchLeave(out var container1) && exit2.MatchLeave(out var container2) && container1 != container2)\n\t\t\t\t{\n\t\t\t\t\t// choose the outer one\n\t\t\t\t\treturn container2.IsDescendantOf(container1) ? 1 : -1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (strongly)\n\t\t\t\treturn 0;\n\n\t\t\t// prefer arranging stuff in IL order\n\t\t\tif (exit1.MatchBranch(out var block1) && exit2.MatchBranch(out var block2))\n\t\t\t\treturn block1.StartILOffset.CompareTo(block2.StartILOffset);\n\n\t\t\t// use the IL offsets of the arguments of leave instructions instead of the leaves themselves if possible\n\t\t\tif (exit1.MatchLeave(out var _, out var arg1) && exit2.MatchLeave(out var _, out var arg2))\n\t\t\t\treturn arg1.StartILOffset.CompareTo(arg2.StartILOffset);\n\n\t\t\treturn exit1.StartILOffset.CompareTo(exit2.StartILOffset);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Determines if an exit instruction has a corresponding keyword and thus doesn't strictly need merging\n\t\t/// Branches can be 'continue' or goto (non-keyword)\n\t\t/// Leave can be 'return', 'break' or a pinned container exit (try/using/lock etc)\n\t\t/// All other instructions (throw, using, etc) are returned as Keyword.Other\n\t\t/// </summary>\n\t\tprivate bool IsKeywordExit(ILInstruction exitInst, out Keyword keyword)\n\t\t{\n\t\t\tkeyword = Keyword.Other;\n\t\t\tswitch (exitInst)\n\t\t\t{\n\t\t\t\tcase Branch branch:\n\t\t\t\t\tif (IsContinueBlock(branch.TargetContainer, branch.TargetBlock))\n\t\t\t\t\t{\n\t\t\t\t\t\tkeyword = Keyword.Continue;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\tcase Leave leave:\n\t\t\t\t\tif (leave.IsLeavingFunction)\n\t\t\t\t\t{\n\t\t\t\t\t\tkeyword = Keyword.Return;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tif (leave.TargetContainer.Kind != ContainerKind.Normal)\n\t\t\t\t\t{\n\t\t\t\t\t\tkeyword = Keyword.Break;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\tdefault:\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Determine if the specified instruction necessarily exits (EndPointUnreachable)\n\t\t/// and if so return last (or single) exit instruction\n\t\t/// </summary>\n\t\tprivate static bool TryGetExit(ILInstruction inst, out ILInstruction exitInst)\n\t\t{\n\t\t\tif (inst is Block block && block.Instructions.Count > 0)\n\t\t\t\tinst = block.Instructions.Last();\n\n\t\t\tif (inst.HasFlag(InstructionFlags.EndPointUnreachable))\n\t\t\t{\n\t\t\t\texitInst = inst;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\texitInst = null;\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the final instruction from a block (or a single instruction) assuming that all blocks\n\t\t/// or instructions in this position have unreachable endpoints\n\t\t/// </summary>\n\t\tprivate static ILInstruction GetExit(ILInstruction inst)\n\t\t{\n\t\t\tILInstruction exitInst = inst is Block block ? block.Instructions.Last() : inst;\n\t\t\t// Last instruction is one with unreachable endpoint\n\t\t\t// (guaranteed by combination of BlockContainer and Block invariants)\n\t\t\tDebug.Assert(exitInst.HasFlag(InstructionFlags.EndPointUnreachable));\n\t\t\treturn exitInst;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns true if inst is Nop or a Block with no instructions.\n\t\t/// </summary>\n\t\tprivate static bool IsEmpty(ILInstruction inst) =>\n\t\t\tinst is Nop || inst is Block block && block.Instructions.Count == 0 && block.FinalInstruction is Nop;\n\n\t\t/// <summary>\n\t\t/// Import some pattern matching from HighLevelLoopTransform to guess the continue block of loop containers.\n\t\t/// Used to identify branches targetting this block as continue statements, for ordering priority.\n\t\t/// </summary>\n\t\t/// <returns></returns>\n\t\tprivate static bool IsContinueBlock(BlockContainer container, Block block)\n\t\t{\n\t\t\tif (container.Kind != ContainerKind.Loop)\n\t\t\t\treturn false;\n\n\t\t\t// increment blocks have exactly 2 incoming edges\n\t\t\tif (container.EntryPoint.IncomingEdgeCount == 2)\n\t\t\t{\n\t\t\t\tvar forIncrement = HighLevelLoopTransform.GetIncrementBlock(container, container.EntryPoint);\n\t\t\t\tif (forIncrement != null)\n\t\t\t\t\treturn block == forIncrement;\n\t\t\t}\n\n\t\t\treturn block == container.EntryPoint;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Removes a subrange of instructions from a block and returns them in a new Block\n\t\t/// </summary>\n\t\tinternal static void ExtractBlock(Block block, int startIndex, int endIndex, Block extractedBlock)\n\t\t{\n\t\t\tfor (int i = startIndex; i < endIndex; i++)\n\t\t\t{\n\t\t\t\tvar inst = block.Instructions[i];\n\t\t\t\textractedBlock.Instructions.Add(inst);\n\t\t\t\textractedBlock.AddILRange(inst);\n\t\t\t}\n\t\t\tblock.Instructions.RemoveRange(startIndex, endIndex - startIndex);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ControlFlow/ControlFlowGraph.cs",
    "content": "using System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.FlowAnalysis;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.ControlFlow\n{\n\t/// <summary>\n\t/// Holds the control flow graph.\n\t/// A separate graph is computed for each BlockContainer at the start of the block transforms\n\t/// (before loop detection).\n\t/// </summary>\n\tpublic class ControlFlowGraph\n\t{\n\t\treadonly BlockContainer container;\n\n\t\t/// <summary>\n\t\t/// The container for which the ControlFlowGraph was created.\n\t\t/// \n\t\t/// This may differ from the container currently holding a block,\n\t\t/// because a transform could have moved the block since the CFG was created.\n\t\t/// </summary>\n\t\tpublic BlockContainer Container { get { return container; } }\n\n\t\t/// <summary>\n\t\t/// Nodes array, indexed by original block index.\n\t\t/// \n\t\t/// Originally <c>cfg[i].UserData == container.Blocks[i]</c>,\n\t\t/// but the ILAst blocks may be moved/reordered by transforms.\n\t\t/// </summary>\n\t\tinternal readonly ControlFlowNode[] cfg;\n\n\t\t/// <inheritdoc cref=\"cfg\"/>\n\t\tpublic IReadOnlyList<ControlFlowNode> Nodes => cfg;\n\n\t\t/// <summary>\n\t\t/// Dictionary from Block to ControlFlowNode.\n\t\t/// Unlike the cfg array, this can be used to discover control flow nodes even after\n\t\t/// blocks were moved/reordered by transforms.\n\t\t/// </summary>\n\t\treadonly Dictionary<Block, ControlFlowNode> dict = new Dictionary<Block, ControlFlowNode>();\n\n\t\t/// <summary>\n\t\t/// nodeHasDirectExitOutOfContainer[i] == true iff cfg[i] directly contains a\n\t\t/// branch/leave instruction leaving the <c>container</c>.\n\t\t/// </summary>\n\t\treadonly BitSet nodeHasDirectExitOutOfContainer;\n\n\t\t/// <summary>\n\t\t/// nodeHasReachableExit[i] == true iff there is a path from cfg[i] to a node not dominated by cfg[i],\n\t\t/// or if there is a path from cfg[i] to a branch/leave instruction leaving the <c>container</c>.\n\t\t/// </summary>\n\t\treadonly BitSet nodeHasReachableExit;\n\n\t\t/// <summary>\n\t\t/// Constructs a control flow graph for the blocks in the given block container.\n\t\t/// \n\t\t/// Return statements, exceptions, or branches leaving the block container are not\n\t\t/// modeled by the control flow graph.\n\t\t/// </summary>\n\t\tpublic ControlFlowGraph(BlockContainer container, CancellationToken cancellationToken = default(CancellationToken))\n\t\t{\n\t\t\tthis.container = container;\n\t\t\tthis.cfg = new ControlFlowNode[container.Blocks.Count];\n\t\t\tthis.nodeHasDirectExitOutOfContainer = new BitSet(cfg.Length);\n\t\t\tfor (int i = 0; i < cfg.Length; i++)\n\t\t\t{\n\t\t\t\tBlock block = container.Blocks[i];\n\t\t\t\tcfg[i] = new ControlFlowNode { UserIndex = i, UserData = block };\n\t\t\t\tdict.Add(block, cfg[i]);\n\t\t\t}\n\n\t\t\tCreateEdges(cancellationToken);\n\t\t\tDominance.ComputeDominance(cfg[0], cancellationToken);\n\t\t\tthis.nodeHasReachableExit = Dominance.MarkNodesWithReachableExits(cfg);\n\t\t\tthis.nodeHasReachableExit.UnionWith(FindNodesWithExitsOutOfContainer());\n\t\t}\n\n\t\tvoid CreateEdges(CancellationToken cancellationToken)\n\t\t{\n\t\t\tfor (int i = 0; i < container.Blocks.Count; i++)\n\t\t\t{\n\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tvar block = container.Blocks[i];\n\t\t\t\tvar sourceNode = cfg[i];\n\t\t\t\tforeach (var node in block.Descendants)\n\t\t\t\t{\n\t\t\t\t\tif (node is Branch branch)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (branch.TargetBlock.Parent == container)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsourceNode.AddEdgeTo(cfg[container.Blocks.IndexOf(branch.TargetBlock)]);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (branch.TargetBlock.IsDescendantOf(container))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Internal control flow within a nested container.\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Branch out of this container into a parent container.\n\t\t\t\t\t\t\t// Like return statements and exceptional exits,\n\t\t\t\t\t\t\t// we ignore this for the CFG and the dominance calculation.\n\t\t\t\t\t\t\t// However, it's relevant for HasReachableExit().\n\t\t\t\t\t\t\tnodeHasDirectExitOutOfContainer.Set(i);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (node is Leave leave && !leave.TargetContainer.IsDescendantOf(block))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Leave instructions (like other exits out of the container)\n\t\t\t\t\t\t// are ignored for the CFG and dominance,\n\t\t\t\t\t\t// but is relevant for HasReachableExit().\n\t\t\t\t\t\t// However, a 'leave' that exits the whole function represents a return,\n\t\t\t\t\t\t// and is not considered a reachable exit.\n\t\t\t\t\t\tif (!leave.IsLeavingFunction)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnodeHasDirectExitOutOfContainer.Set(i);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tBitSet FindNodesWithExitsOutOfContainer()\n\t\t{\n\t\t\t// Also mark the nodes that exit the block container altogether.\n\t\t\t// Invariant: leaving[n.UserIndex] == true implies leaving[n.ImmediateDominator.UserIndex] == true\n\t\t\tvar leaving = new BitSet(cfg.Length);\n\t\t\tforeach (var node in cfg)\n\t\t\t{\n\t\t\t\tif (leaving[node.UserIndex])\n\t\t\t\t\tcontinue;\n\t\t\t\tif (nodeHasDirectExitOutOfContainer[node.UserIndex])\n\t\t\t\t{\n\t\t\t\t\tfor (ControlFlowNode p = node; p != null; p = p.ImmediateDominator)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (leaving[p.UserIndex])\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// we can stop marking when we've reached an already-marked node\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tleaving.Set(p.UserIndex);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn leaving;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the ControlFlowNode for the block.\n\t\t/// \n\t\t/// Precondition: the block belonged to the <c>container</c> at the start of the block transforms\n\t\t/// (when the control flow graph was created).\n\t\t/// </summary>\n\t\tpublic ControlFlowNode GetNode(Block block)\n\t\t{\n\t\t\treturn dict[block];\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns true iff there is a control flow path from <c>node</c> to one of the following:\n\t\t///  * branch or leave instruction leaving <c>this.Container</c>\n\t\t///  * branch instruction within this container to another node that is not dominated by <c>node</c>.\n\t\t/// \n\t\t/// If this function returns false, the only way control flow can leave the set of nodes\n\t\t/// dominated by <c>node</c> is by executing a <c>return</c> or <c>throw</c> instruction.\n\t\t/// </summary>\n\t\tpublic bool HasReachableExit(ControlFlowNode node)\n\t\t{\n\t\t\tDebug.Assert(cfg[node.UserIndex] == node);\n\t\t\treturn nodeHasReachableExit[node.UserIndex];\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the control flow node directly contains a branch/leave instruction\n\t\t/// exiting the container.\n\t\t/// </summary>\n\t\tpublic bool HasDirectExitOutOfContainer(ControlFlowNode node)\n\t\t{\n\t\t\tDebug.Assert(cfg[node.UserIndex] == node);\n\t\t\treturn nodeHasDirectExitOutOfContainer[node.UserIndex];\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ControlFlow/ControlFlowSimplification.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.ControlFlow\n{\n\t/// <summary>\n\t/// This transform 'optimizes' the control flow logic in the IL code:\n\t/// it replaces constructs that are generated by the C# compiler in debug mode\n\t/// with shorter constructs that are more straightforward to analyze.\n\t/// </summary>\n\t/// <remarks>\n\t/// The transformations performed are:\n\t/// * 'nop' instructions are removed\n\t/// * branches that lead to other branches are replaced with branches that directly jump to the destination\n\t/// * branches that lead to a 'return block' are replaced with a return instruction\n\t/// * basic blocks are combined where possible\n\t/// </remarks>\n\tpublic class ControlFlowSimplification : IILTransform\n\t{\n\t\tinternal bool aggressivelyDuplicateReturnBlocks;\n\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tforeach (var block in function.Descendants.OfType<Block>())\n\t\t\t{\n\t\t\t\tcontext.CancellationToken.ThrowIfCancellationRequested();\n\n\t\t\t\tRemoveNopInstructions(block);\n\t\t\t\tRemoveDeadStackStores(block, context);\n\n\t\t\t\tInlineVariableInReturnBlock(block, context);\n\t\t\t\t// 1st pass SimplifySwitchInstruction before SimplifyBranchChains()\n\t\t\t\t// starts duplicating return instructions.\n\t\t\t\tSwitchDetection.SimplifySwitchInstruction(block, context);\n\t\t\t}\n\t\t\tSimplifyBranchChains(function, context);\n\t\t\tCleanUpEmptyBlocks(function, context);\n\t\t}\n\n\t\tprivate static void RemoveNopInstructions(Block block)\n\t\t{\n\t\t\t// Move ILRanges of special nop instructions to the previous non-nop instruction.\n\t\t\tfor (int i = block.Instructions.Count - 1; i > 0; i--)\n\t\t\t{\n\t\t\t\tif (block.Instructions[i] is Nop nop && nop.Kind == NopKind.Pop)\n\t\t\t\t{\n\t\t\t\t\tblock.Instructions[i - 1].AddILRange(nop);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove 'nop' instructions\n\t\t\tblock.Instructions.RemoveAll(inst => inst.OpCode == OpCode.Nop);\n\t\t}\n\n\t\tprivate static void RemoveDeadStackStores(Block block, ILTransformContext context)\n\t\t{\n\t\t\tbool aggressive = context.Settings.RemoveDeadStores;\n\t\t\t// Previously copy propagation did this;\n\t\t\t// ideally the ILReader would already do this,\n\t\t\t// for now do this here (even though it's not control-flow related).\n\t\t\tfor (int i = block.Instructions.Count - 1; i >= 0; i--)\n\t\t\t{\n\t\t\t\tif (block.Instructions[i] is StLoc stloc && stloc.Variable.IsSingleDefinition && stloc.Variable.LoadCount == 0 && stloc.Variable.Kind == VariableKind.StackSlot)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step($\"Remove dead stack store {stloc.Variable.Name}\", stloc);\n\t\t\t\t\tif (aggressive ? SemanticHelper.IsPure(stloc.Value.Flags) : IsSimple(stloc.Value))\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(SemanticHelper.IsPure(stloc.Value.Flags));\n\t\t\t\t\t\tblock.Instructions.RemoveAt(i++);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tstloc.Value.AddILRange(stloc);\n\t\t\t\t\t\tstloc.ReplaceWith(stloc.Value);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool IsSimple(ILInstruction inst)\n\t\t\t{\n\t\t\t\tswitch (inst.OpCode)\n\t\t\t\t{\n\t\t\t\t\tcase OpCode.LdLoc:\n\t\t\t\t\tcase OpCode.LdStr: // C# 1.0 compiler sometimes emits redundant ldstr in switch-on-string pattern\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid InlineVariableInReturnBlock(Block block, ILTransformContext context)\n\t\t{\n\t\t\t// In debug mode, the C#-compiler generates 'return blocks' that\n\t\t\t// unnecessarily store the return value to a local and then load it again:\n\t\t\t//   v = <inst>\n\t\t\t//   ret(v)\n\t\t\t// (where 'v' has no other uses)\n\t\t\t// Simplify these to a simple `ret(<inst>)` so that they match the release build version.\n\t\t\t// \n\t\t\tif (block.Instructions.Count == 2 && block.Instructions[1].MatchReturn(out ILInstruction value))\n\t\t\t{\n\t\t\t\tvar ret = (Leave)block.Instructions[1];\n\t\t\t\tif (value.MatchLdLoc(out ILVariable v)\n\t\t\t\t\t&& v.IsSingleDefinition && v.LoadCount == 1 && block.Instructions[0].MatchStLoc(v, out ILInstruction inst))\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"Inline variable in return block\", block);\n\t\t\t\t\tinst.AddILRange(ret.Value);\n\t\t\t\t\tinst.AddILRange(block.Instructions[0]);\n\t\t\t\t\tret.Value = inst;\n\t\t\t\t\tblock.Instructions.RemoveAt(0);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid SimplifyBranchChains(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tList<(Block Block, BlockContainer TargetContainer)> blocksToMove = new List<(Block, BlockContainer)>();\n\t\t\tHashSet<Block> visitedBlocks = new HashSet<Block>();\n\t\t\tforeach (var branch in function.Descendants.OfType<Branch>())\n\t\t\t{\n\t\t\t\t// Resolve chained branches to the final target:\n\t\t\t\tvar targetBlock = branch.TargetBlock;\n\t\t\t\tvisitedBlocks.Clear();\n\t\t\t\twhile (targetBlock.Instructions.Count == 1 && targetBlock.Instructions[0].OpCode == OpCode.Branch)\n\t\t\t\t{\n\t\t\t\t\tif (!visitedBlocks.Add(targetBlock))\n\t\t\t\t\t{\n\t\t\t\t\t\t// prevent infinite loop when branch chain is cyclic\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcontext.Step(\"Simplify branch to branch\", branch);\n\t\t\t\t\tvar nextBranch = (Branch)targetBlock.Instructions[0];\n\t\t\t\t\tbranch.TargetBlock = nextBranch.TargetBlock;\n\t\t\t\t\tbranch.AddILRange(nextBranch);\n\t\t\t\t\tif (targetBlock.IncomingEdgeCount == 0)\n\t\t\t\t\t\ttargetBlock.Instructions.Clear(); // mark the block for deletion\n\t\t\t\t\ttargetBlock = branch.TargetBlock;\n\t\t\t\t}\n\t\t\t\tif (IsBranchToReturnBlock(branch))\n\t\t\t\t{\n\t\t\t\t\tif (aggressivelyDuplicateReturnBlocks)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Replace branches to 'return blocks' with the return instruction\n\t\t\t\t\t\tcontext.Step(\"Replace branch to return with return\", branch);\n\t\t\t\t\t\tbranch.ReplaceWith(targetBlock.Instructions[0].Clone());\n\t\t\t\t\t}\n\t\t\t\t\telse if (branch.TargetContainer != branch.Ancestors.OfType<BlockContainer>().First() && targetBlock.IncomingEdgeCount == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\t// We don't want to always inline the return directly, because this\n\t\t\t\t\t\t// might force us to place the return within a loop, when it's better\n\t\t\t\t\t\t// placed outside.\n\t\t\t\t\t\t// But we do want to move the return block into the correct try-finally scope,\n\t\t\t\t\t\t// so that loop detection at least has the option to put it inside\n\t\t\t\t\t\t// the loop body.\n\t\t\t\t\t\tcontext.Step(\"Move return block into try block\", branch);\n\t\t\t\t\t\tBlockContainer localContainer = branch.Ancestors.OfType<BlockContainer>().First();\n\t\t\t\t\t\tblocksToMove.Add((targetBlock, localContainer));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (targetBlock.Instructions.Count == 1 && targetBlock.Instructions[0] is Leave leave && leave.Value.MatchNop())\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"Replace branch to leave with leave\", branch);\n\t\t\t\t\t// Replace branches to 'leave' instruction with the leave instruction\n\t\t\t\t\tvar leave2 = leave.Clone();\n\t\t\t\t\tif (!branch.ILRangeIsEmpty) // use the ILRange of the branch if possible\n\t\t\t\t\t\tleave2.AddILRange(branch);\n\t\t\t\t\tbranch.ReplaceWith(leave2);\n\t\t\t\t}\n\t\t\t\tif (targetBlock.IncomingEdgeCount == 0)\n\t\t\t\t\ttargetBlock.Instructions.Clear(); // mark the block for deletion\n\t\t\t}\n\t\t\tforeach ((Block block, BlockContainer targetContainer) in blocksToMove)\n\t\t\t{\n\t\t\t\tblock.Remove();\n\t\t\t\ttargetContainer.Blocks.Add(block);\n\t\t\t}\n\t\t}\n\n\t\tvoid CleanUpEmptyBlocks(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tforeach (var container in function.Descendants.OfType<BlockContainer>())\n\t\t\t{\n\t\t\t\tforeach (var block in container.Blocks)\n\t\t\t\t{\n\t\t\t\t\tif (block.Instructions.Count == 0)\n\t\t\t\t\t\tcontinue; // block is already marked for deletion\n\t\t\t\t\twhile (CombineBlockWithNextBlock(container, block, context))\n\t\t\t\t\t{\n\t\t\t\t\t\t// repeat combining blocks until it is no longer possible\n\t\t\t\t\t\t// (this loop terminates because a block is deleted in every iteration)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Remove return blocks that are no longer reachable:\n\t\t\t\tcontainer.Blocks.RemoveAll(b => b.IncomingEdgeCount == 0 && b.Instructions.Count == 0);\n\t\t\t}\n\t\t}\n\n\t\tbool IsBranchToReturnBlock(Branch branch)\n\t\t{\n\t\t\tvar targetBlock = branch.TargetBlock;\n\t\t\tif (targetBlock.Instructions.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (!targetBlock.Instructions[0].MatchReturn(out var value))\n\t\t\t\treturn false;\n\t\t\tif (!value.MatchLdLoc(out var returnVar))\n\t\t\t\treturn false;\n\t\t\tvar container = branch.TargetContainer;\n\t\t\tfor (ILInstruction inst = branch; inst != container; inst = inst.Parent)\n\t\t\t{\n\t\t\t\tif (inst.Parent is TryFinally tryFinally && inst.SlotInfo == TryFinally.TryBlockSlot)\n\t\t\t\t{\n\t\t\t\t\t// The branch will trigger the finally block.\n\t\t\t\t\t// Moving the return block into the try is only possible if the finally block doesn't touch the return variable.\n\t\t\t\t\tif (returnVar.IsUsedWithin(tryFinally.FinallyBlock))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic bool CombineBlockWithNextBlock(BlockContainer container, Block block, ILTransformContext context)\n\t\t{\n\t\t\tDebug.Assert(container == block.Parent);\n\t\t\t// Ensure the block will stay a basic block -- we don't want extended basic blocks prior to LoopDetection.\n\t\t\tif (block.Instructions.Count > 1 && block.Instructions[block.Instructions.Count - 2].HasFlag(InstructionFlags.MayBranch))\n\t\t\t\treturn false;\n\t\t\tBranch br = block.Instructions.Last() as Branch;\n\t\t\t// Check whether we can combine the target block with this block\n\t\t\tif (br == null || br.TargetBlock.Parent != container || br.TargetBlock.IncomingEdgeCount != 1)\n\t\t\t\treturn false;\n\t\t\tif (br.TargetBlock == block)\n\t\t\t\treturn false; // don't inline block into itself\n\t\t\tcontext.Step(\"CombineBlockWithNextBlock\", br);\n\t\t\tvar targetBlock = br.TargetBlock;\n\t\t\tif (targetBlock.StartILOffset < block.StartILOffset && IsDeadTrueStore(block))\n\t\t\t{\n\t\t\t\t// The C# compiler generates a dead store for the condition of while (true) loops.\n\t\t\t\tblock.Instructions.RemoveAt(block.Instructions.Count - 2);\n\t\t\t}\n\n\t\t\tif (block.ILRangeIsEmpty)\n\t\t\t\tblock.AddILRange(targetBlock);\n\n\t\t\tblock.Instructions.Remove(br);\n\t\t\tblock.Instructions.AddRange(targetBlock.Instructions);\n\t\t\ttargetBlock.Instructions.Clear(); // mark targetBlock for deletion\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns true if the last two instructions before the branch are storing the value 'true' into an unused variable.\n\t\t/// </summary>\n\t\tprivate static bool IsDeadTrueStore(Block block)\n\t\t{\n\t\t\tif (block.Instructions.Count < 2)\n\t\t\t\treturn false;\n\t\t\tif (!(block.Instructions.SecondToLastOrDefault() is StLoc deadStore))\n\t\t\t\treturn false;\n\t\t\tif (!(deadStore.Variable.LoadCount == 0 && deadStore.Variable.AddressCount == 0))\n\t\t\t\treturn false;\n\t\t\treturn deadStore.Value.MatchLdcI4(1) && deadStore.Variable.Type.IsKnownType(KnownTypeCode.Boolean);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ControlFlow/DetectPinnedRegions.cs",
    "content": "// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Runtime.InteropServices.ComTypes;\n\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.ControlFlow\n{\n\t/// <summary>\n\t/// IL uses 'pinned locals' to prevent the GC from moving objects.\n\t/// \n\t/// C#:\n\t/// <code>\n\t/// fixed (int* s = &amp;arr[index]) { use(s); use(s); }\n\t/// </code>\n\t/// \n\t/// <para>Gets translated into IL:</para>\n\t/// <code>\n\t/// pinned local P : System.Int32&amp;\n\t/// \n\t/// stloc(P, ldelema(arr, index))\n\t/// call use(conv ref->i(ldloc P))\n\t/// call use(conv ref->i(ldloc P))\n\t/// stloc(P, conv i4->u(ldc.i4 0))\n\t/// </code>\n\t/// \n\t/// In C#, the only way to pin something is to use a fixed block\n\t/// (or to mess around with GCHandles).\n\t/// But fixed blocks are scoped, so we need to detect the region affected by the pin.\n\t/// To ensure we'll be able to collect all blocks in that region, we perform this transform\n\t/// early, before building any other control flow constructs that aren't as critical for correctness.\n\t/// \n\t/// This means this transform must run before LoopDetection.\n\t/// To make our detection job easier, we must run after variable inlining.\n\t/// </summary>\n\tpublic class DetectPinnedRegions : IILTransform\n\t{\n\t\tILTransformContext context;\n\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tthis.context = context;\n\t\t\tforeach (var container in function.Descendants.OfType<BlockContainer>())\n\t\t\t{\n\t\t\t\tcontext.CancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tDetectNullSafeArrayToPointerOrCustomRefPin(container);\n\t\t\t\tSplitBlocksAtWritesToPinnedLocals(container);\n\t\t\t\tforeach (var block in container.Blocks)\n\t\t\t\t\tDetectPinnedRegion(block);\n\t\t\t\tcontainer.Blocks.RemoveAll(b => b.Instructions.Count == 0); // remove dummy blocks\n\t\t\t}\n\t\t\t// Sometimes there's leftover writes to the original pinned locals\n\t\t\tforeach (var block in function.Descendants.OfType<Block>())\n\t\t\t{\n\t\t\t\tcontext.CancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tfor (int i = 0; i < block.Instructions.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tvar stloc = block.Instructions[i] as StLoc;\n\t\t\t\t\tif (stloc != null && stloc.Variable.Kind == VariableKind.PinnedLocal && stloc.Variable.LoadCount == 0 && stloc.Variable.AddressCount == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (SemanticHelper.IsPure(stloc.Value.Flags))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tblock.Instructions.RemoveAt(i--);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstloc.ReplaceWith(stloc.Value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.context = null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Ensures that every write to a pinned local is followed by a branch instruction.\n\t\t/// This ensures the 'pinning region' does not involve any half blocks, which makes it easier to extract.\n\t\t/// </summary>\n\t\tvoid SplitBlocksAtWritesToPinnedLocals(BlockContainer container)\n\t\t{\n\t\t\tfor (int i = 0; i < container.Blocks.Count; i++)\n\t\t\t{\n\t\t\t\tvar block = container.Blocks[i];\n\t\t\t\tfor (int j = 0; j < block.Instructions.Count - 1; j++)\n\t\t\t\t{\n\t\t\t\t\tvar inst = block.Instructions[j];\n\t\t\t\t\tif (inst.MatchStLoc(out ILVariable v, out var value) && v.Kind == VariableKind.PinnedLocal)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (block.Instructions[j + 1].OpCode != OpCode.Branch)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// split block after j:\n\t\t\t\t\t\t\tcontext.Step(\"Split block after pinned local write\", inst);\n\t\t\t\t\t\t\tvar newBlock = new Block();\n\t\t\t\t\t\t\tfor (int k = j + 1; k < block.Instructions.Count; k++)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tnewBlock.Instructions.Add(block.Instructions[k]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnewBlock.AddILRange(newBlock.Instructions[0]);\n\t\t\t\t\t\t\tblock.Instructions.RemoveRange(j + 1, newBlock.Instructions.Count);\n\t\t\t\t\t\t\tblock.Instructions.Add(new Branch(newBlock));\n\t\t\t\t\t\t\tcontainer.Blocks.Insert(i + 1, newBlock);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// in case of re-pinning (e.g. C++/CLI assignment to pin_ptr variable),\n\t\t\t\t\t\t// it's possible for the new value to be dependent on the old.\n\t\t\t\t\t\tif (v.IsUsedWithin(value))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// In this case, we need to un-inline the uses of the pinned local\n\t\t\t\t\t\t\t// so that they are split off into the block prior to the pinned local write\n\t\t\t\t\t\t\tvar temp = context.Function.RegisterVariable(VariableKind.StackSlot, v.Type);\n\t\t\t\t\t\t\tblock.Instructions.Insert(j++, new StLoc(temp, new LdLoc(v)));\n\t\t\t\t\t\t\tforeach (var descendant in value.Descendants)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (descendant.MatchLdLoc(v))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tdescendant.ReplaceWith(new LdLoc(temp).WithILRange(descendant));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (j > 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// split block before j:\n\t\t\t\t\t\t\tcontext.Step(\"Split block before pinned local write\", inst);\n\t\t\t\t\t\t\tvar newBlock = new Block();\n\t\t\t\t\t\t\tnewBlock.Instructions.Add(block.Instructions[j]);\n\t\t\t\t\t\t\tnewBlock.Instructions.Add(block.Instructions[j + 1]);\n\t\t\t\t\t\t\tnewBlock.AddILRange(newBlock.Instructions[0]);\n\t\t\t\t\t\t\tDebug.Assert(block.Instructions.Count == j + 2);\n\t\t\t\t\t\t\tblock.Instructions.RemoveRange(j, 2);\n\t\t\t\t\t\t\tblock.Instructions.Insert(j, new Branch(newBlock));\n\t\t\t\t\t\t\tcontainer.Blocks.Insert(i + 1, newBlock);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t#region null-safe array to pointer\n\t\tvoid DetectNullSafeArrayToPointerOrCustomRefPin(BlockContainer container)\n\t\t{\n\t\t\tbool modified = false;\n\t\t\tfor (int i = 0; i < container.Blocks.Count; i++)\n\t\t\t{\n\t\t\t\tvar block = container.Blocks[i];\n\t\t\t\tif (IsNullSafeArrayToPointerPattern(block, out ILVariable v, out ILVariable p, out Block targetBlock))\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"NullSafeArrayToPointerPattern\", block);\n\t\t\t\t\tILInstruction arrayToPointer = new GetPinnableReference(new LdLoc(v), null);\n\t\t\t\t\tif (p.StackType != StackType.Ref)\n\t\t\t\t\t{\n\t\t\t\t\t\tarrayToPointer = new Conv(arrayToPointer, p.StackType.ToPrimitiveType(), false, Sign.None);\n\t\t\t\t\t}\n\t\t\t\t\tblock.Instructions[block.Instructions.Count - 2] = new StLoc(p, arrayToPointer)\n\t\t\t\t\t\t.WithILRange(block.Instructions[block.Instructions.Count - 2]);\n\t\t\t\t\t((Branch)block.Instructions.Last()).TargetBlock = targetBlock;\n\t\t\t\t\tmodified = true;\n\t\t\t\t}\n\t\t\t\telse if (IsCustomRefPinPattern(block, out ILInstruction ldlocMem, out var callGPR, out v, out var stlocPtr,\n\t\t\t\t\tout targetBlock, out var nullBlock, out var notNullBlock))\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"CustomRefPinPattern\", block);\n\t\t\t\t\tILInstruction gpr;\n\t\t\t\t\tif (context.Settings.PatternBasedFixedStatement)\n\t\t\t\t\t{\n\t\t\t\t\t\tgpr = new GetPinnableReference(ldlocMem, callGPR.Method);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tgpr = new IfInstruction(\n\t\t\t\t\t\t\tcondition: new Comp(ComparisonKind.Inequality, Sign.None, ldlocMem, new LdNull()),\n\t\t\t\t\t\t\ttrueInst: callGPR,\n\t\t\t\t\t\t\tfalseInst: new Conv(new LdcI4(0), PrimitiveType.Ref, checkForOverflow: false, inputSign: Sign.None)\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tblock.Instructions[block.Instructions.Count - 2] = new StLoc(v, gpr)\n\t\t\t\t\t\t.WithILRange(block.Instructions[block.Instructions.Count - 2]);\n\t\t\t\t\tif (stlocPtr != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tblock.Instructions.Insert(block.Instructions.Count - 1, stlocPtr);\n\t\t\t\t\t}\n\t\t\t\t\t((Branch)block.Instructions.Last()).TargetBlock = targetBlock;\n\t\t\t\t\t// clear out internal blocks that are now unreachable, so that\n\t\t\t\t\t// targetBlock.IncomingEdgeCount is accurate at this point.\n\t\t\t\t\tnullBlock?.Instructions.Clear();\n\t\t\t\t\tnotNullBlock.Instructions.Clear();\n\t\t\t\t\tif (targetBlock.IncomingEdgeCount == 1 && targetBlock.Parent == block.Parent)\n\t\t\t\t\t{\n\t\t\t\t\t\tblock.Instructions.RemoveLast();\n\t\t\t\t\t\tblock.Instructions.AddRange(targetBlock.Instructions);\n\t\t\t\t\t\ttargetBlock.Instructions.Clear();\n\t\t\t\t\t\tif (stlocPtr != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tILInlining.InlineOneIfPossible(block, stlocPtr.ChildIndex, InliningOptions.None, context);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tmodified = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (modified)\n\t\t\t{\n\t\t\t\tcontainer.Blocks.RemoveAll(b => b.IncomingEdgeCount == 0); // remove blocks made unreachable\n\t\t\t}\n\t\t}\n\n\t\t// Detect the following pattern:\n\t\t//      if (comp.o(ldloc mem != ldnull)) br notNullBlock\n\t\t//      br nullBlock\n\t\t//  }\n\t\t//\n\t\t//  Block nullBlock (incoming: 1) {\n\t\t//      stloc ptr(conv i4->u <zero extend>(ldc.i4 0))\n\t\t//      br targetBlock\n\t\t//  }\n\t\t//\n\t\t//  Block notNullBlock (incoming: 1) {\n\t\t//      stloc V_1(call GetPinnableReference(ldloc mem))\n\t\t//      stloc ptr(conv ref->u (ldloc V_1))\n\t\t//      br targetBlock\n\t\t//  }\n\t\t// It will be replaced with:\n\t\t//      stloc V_1(get.pinnable.reference(ldloc mem))\n\t\t//      stloc ptr(conv ref->u (ldloc V_1))\n\t\t//      br targetBlock\n\t\tprivate bool IsCustomRefPinPattern(Block block, out ILInstruction ldlocMem, out CallInstruction callGPR,\n\t\t\tout ILVariable v, out StLoc ptrAssign, out Block targetBlock, out Block nullBlock, out Block notNullBlock)\n\t\t{\n\t\t\tldlocMem = null;\n\t\t\tcallGPR = null;\n\t\t\tv = null;\n\t\t\tptrAssign = null;\n\t\t\ttargetBlock = null;\n\t\t\tnullBlock = null;\n\t\t\tnotNullBlock = null;\n\t\t\t//      if (comp.o(ldloc mem != ldnull)) br on_not_null\n\t\t\t//      br on_null\n\t\t\tif (!block.MatchIfAtEndOfBlock(out var ifCondition, out var trueInst, out var falseInst))\n\t\t\t\treturn false;\n\t\t\tif (!ifCondition.MatchCompNotEqualsNull(out ldlocMem))\n\t\t\t{\n\t\t\t\tif (ifCondition.MatchCompEqualsNull(out ldlocMem))\n\t\t\t\t{\n\t\t\t\t\t(trueInst, falseInst) = (falseInst, trueInst);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!SemanticHelper.IsPure(ldlocMem.Flags))\n\t\t\t\treturn false;\n\t\t\tif (!trueInst.MatchBranch(out notNullBlock) || notNullBlock.Parent != block.Parent)\n\t\t\t\treturn false;\n\t\t\tif (!falseInst.MatchBranch(out nullBlock) || nullBlock.Parent != block.Parent)\n\t\t\t\treturn false;\n\n\t\t\t//  Block notNullBlock (incoming: 1) {\n\t\t\t//      stloc V_1(call GetPinnableReference(ldloc mem))\n\t\t\t//      stloc ptr(conv ref->u (ldloc V_1))\n\t\t\t//      br targetBlock\n\t\t\t//  }\n\t\t\tif (notNullBlock.IncomingEdgeCount != 1)\n\t\t\t\treturn false;\n\t\t\tif (notNullBlock.Instructions.Count < 2)\n\t\t\t\treturn false;\n\t\t\t// stloc V_1(call GetPinnableReference(ldloc mem))\n\t\t\tif (!notNullBlock.Instructions[0].MatchStLoc(out v, out var value))\n\t\t\t\treturn false;\n\t\t\tif (v.Kind != VariableKind.PinnedLocal)\n\t\t\t\treturn false;\n\t\t\tcallGPR = value as CallInstruction;\n\t\t\tif (callGPR == null || callGPR.Arguments.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (callGPR.Method.Name != \"GetPinnableReference\")\n\t\t\t\treturn false;\n\t\t\tif (!ldlocMem.Match(callGPR.Arguments[0]).Success)\n\t\t\t\treturn false;\n\t\t\t// stloc ptr(conv ref->u (ldloc V_1))\n\t\t\tptrAssign = notNullBlock.Instructions[1] as StLoc;\n\t\t\tif (ptrAssign != null)\n\t\t\t{\n\t\t\t\tif (!ptrAssign.Value.UnwrapConv(ConversionKind.StopGCTracking).MatchLdLoc(v))\n\t\t\t\t\treturn false;\n\t\t\t\t// br targetBlock\n\t\t\t\tif (!notNullBlock.Instructions[2].MatchBranch(out targetBlock))\n\t\t\t\t\treturn false;\n\n\t\t\t\t//  Block nullBlock (incoming: 1) {\n\t\t\t\t//      stloc ptr(conv i4->u <zero extend>(ldc.i4 0))\n\t\t\t\t//      br targetBlock\n\t\t\t\t//  }\n\t\t\t\tif (nullBlock.IncomingEdgeCount != 1)\n\t\t\t\t\treturn false;\n\t\t\t\tif (nullBlock.Instructions.Count != 2)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!nullBlock.Instructions[0].MatchStLoc(ptrAssign.Variable, out var nullPointerInst))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!nullPointerInst.MatchLdcI(0))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!nullBlock.Instructions[1].MatchBranch(targetBlock))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// br targetBlock\n\t\t\t\tif (!notNullBlock.Instructions[1].MatchBranch(out targetBlock))\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (targetBlock != nullBlock)\n\t\t\t\t\treturn false;\n\t\t\t\t// nullBlock must be set to null, so that\n\t\t\t\t// we do not clear out targetBlock in the caller.\n\t\t\t\tnullBlock = null;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t// Detect the following pattern:\n\t\t//   ...\n\t\t//   stloc V(ldloc S)\n\t\t//   if (comp(ldloc S == ldnull)) br B_null_or_empty\n\t\t//   br B_not_null\n\t\t// }\n\t\t// Block B_not_null {\n\t\t//   if (conv i->i4 (ldlen(ldloc V))) br B_not_null_and_not_empty\n\t\t//   br B_null_or_empty\n\t\t// }\n\t\t// Block B_not_null_and_not_empty {\n\t\t//   stloc P(ldelema(ldloc V, ldc.i4 0, ...))\n\t\t//   br B_target\n\t\t// }\n\t\t// Block B_null_or_empty {\n\t\t//   stloc P(conv i4->u(ldc.i4 0))\n\t\t//   br B_target\n\t\t// }\n\t\t// And convert the whole thing into:\n\t\t//   ...\n\t\t//   stloc P(array.to.pointer(V))\n\t\t//   br B_target\n\t\tbool IsNullSafeArrayToPointerPattern(Block block, out ILVariable v, out ILVariable p, out Block targetBlock)\n\t\t{\n\t\t\tv = null;\n\t\t\tp = null;\n\t\t\ttargetBlock = null;\n\t\t\t// ...\n\t\t\t// if (comp(ldloc V == ldnull)) br B_null_or_empty\n\t\t\t// br B_not_null\n\t\t\tvar ifInst = block.Instructions.SecondToLastOrDefault() as IfInstruction;\n\t\t\tif (ifInst == null)\n\t\t\t\treturn false;\n\t\t\tvar condition = ifInst.Condition as Comp;\n\t\t\tif (!(condition != null && condition.Kind == ComparisonKind.Equality && condition.Left.MatchLdLoc(out v) && condition.Right.MatchLdNull()))\n\t\t\t\treturn false;\n\t\t\tbool usingPreviousVar = false;\n\t\t\tif (v.Kind == VariableKind.StackSlot)\n\t\t\t{\n\t\t\t\t// If the variable is a stack slot, that might be due to an inline assignment,\n\t\t\t\t// so check the previous instruction:\n\t\t\t\tvar previous = block.Instructions.ElementAtOrDefault(block.Instructions.Count - 3) as StLoc;\n\t\t\t\tif (previous != null && previous.Value.MatchLdLoc(v))\n\t\t\t\t{\n\t\t\t\t\t// stloc V(ldloc S)\n\t\t\t\t\t// if (comp(ldloc S == ldnull)) ...\n\t\t\t\t\tv = previous.Variable;\n\t\t\t\t\tusingPreviousVar = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!ifInst.TrueInst.MatchBranch(out Block nullOrEmptyBlock))\n\t\t\t\treturn false;\n\t\t\tif (!ifInst.FalseInst.MatchNop())\n\t\t\t\treturn false;\n\t\t\tif (nullOrEmptyBlock.Parent != block.Parent)\n\t\t\t\treturn false;\n\t\t\tif (!IsNullSafeArrayToPointerNullOrEmptyBlock(nullOrEmptyBlock, out p, out targetBlock))\n\t\t\t\treturn false;\n\t\t\tif (!(p.Kind == VariableKind.PinnedLocal || (usingPreviousVar && v.Kind == VariableKind.PinnedLocal)))\n\t\t\t\treturn false;\n\t\t\tif (!block.Instructions.Last().MatchBranch(out Block notNullBlock))\n\t\t\t\treturn false;\n\t\t\tif (notNullBlock.Parent != block.Parent)\n\t\t\t\treturn false;\n\t\t\treturn IsNullSafeArrayToPointerNotNullBlock(notNullBlock, v, p, nullOrEmptyBlock, targetBlock);\n\t\t}\n\n\t\tbool IsNullSafeArrayToPointerNotNullBlock(Block block, ILVariable v, ILVariable p, Block nullOrEmptyBlock, Block targetBlock)\n\t\t{\n\t\t\t// Block B_not_null {\n\t\t\t//   if (conv i->i4 (ldlen(ldloc V))) br B_not_null_and_not_empty\n\t\t\t//   br B_null_or_empty\n\t\t\t// }\n\t\t\tif (block.Instructions.Count != 2)\n\t\t\t\treturn false;\n\t\t\tif (!block.Instructions[0].MatchIfInstruction(out ILInstruction condition, out ILInstruction trueInst))\n\t\t\t\treturn false;\n\t\t\tvar falseInst = block.Instructions[1];\n\t\t\tif (condition is Comp comp && comp.Right.MatchLdcI(0))\n\t\t\t{\n\t\t\t\tif (comp.Kind == ComparisonKind.Equality)\n\t\t\t\t{\n\t\t\t\t\t// if (len == 0): effectively negates the condition\n\t\t\t\t\tcondition = comp.Left;\n\t\t\t\t\tExtensionMethods.Swap(ref trueInst, ref falseInst);\n\t\t\t\t}\n\t\t\t\telse if (comp.Kind == ComparisonKind.Inequality)\n\t\t\t\t{\n\t\t\t\t\t// if (len != 0): comparison is redundant (equivalent to implicit non-zero check)\n\t\t\t\t\tcondition = comp.Left;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcondition = condition.UnwrapConv(ConversionKind.Truncate);\n\t\t\tif (condition.MatchLdLen(StackType.I, out ILInstruction array))\n\t\t\t{\n\t\t\t\t// OK\n\t\t\t}\n\t\t\telse if (condition is CallInstruction call && call.Method.Name == \"get_Length\")\n\t\t\t{\n\t\t\t\t// Used instead of ldlen for multi-dimensional arrays\n\t\t\t\tif (!call.Method.DeclaringType.IsKnownType(KnownTypeCode.Array))\n\t\t\t\t\treturn false;\n\t\t\t\tif (call.Arguments.Count != 1)\n\t\t\t\t\treturn false;\n\t\t\t\tarray = call.Arguments[0];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!array.MatchLdLoc(v))\n\t\t\t\treturn false;\n\t\t\tif (!trueInst.MatchBranch(out Block notNullAndNotEmptyBlock))\n\t\t\t\treturn false;\n\t\t\tif (notNullAndNotEmptyBlock.Parent != block.Parent)\n\t\t\t\treturn false;\n\t\t\tif (!IsNullSafeArrayToPointerNotNullAndNotEmptyBlock(notNullAndNotEmptyBlock, v, p, targetBlock))\n\t\t\t\treturn false;\n\t\t\treturn falseInst.MatchBranch(nullOrEmptyBlock);\n\t\t}\n\n\t\tbool IsNullSafeArrayToPointerNotNullAndNotEmptyBlock(Block block, ILVariable v, ILVariable p, Block targetBlock)\n\t\t{\n\t\t\t// Block B_not_null_and_not_empty {\n\t\t\t//   stloc P(ldelema(ldloc V, ldc.i4 0, ...))\n\t\t\t//   br B_target\n\t\t\t// }\n\t\t\tif (block.Instructions.Count != 2)\n\t\t\t\treturn false;\n\t\t\tif (!block.Instructions[0].MatchStLoc(out var p2, out ILInstruction value))\n\t\t\t\treturn false;\n\t\t\tif (p != p2)\n\t\t\t{\n\t\t\t\t// If the pointer is unused, the variable P might have been split.\n\t\t\t\tif (p.LoadCount == 0 && p.AddressCount == 0 && p2.LoadCount == 0 && p2.AddressCount == 0)\n\t\t\t\t{\n\t\t\t\t\tif (!ILVariableEqualityComparer.Instance.Equals(p, p2))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (v.Kind == VariableKind.PinnedLocal)\n\t\t\t{\n\t\t\t\tvalue = value.UnwrapConv(ConversionKind.StopGCTracking);\n\t\t\t}\n\t\t\tif (!(value is LdElema ldelema))\n\t\t\t\treturn false;\n\t\t\tif (!ldelema.Array.MatchLdLoc(v))\n\t\t\t\treturn false;\n\t\t\tif (!ldelema.Indices.All(i => i.MatchLdcI4(0)))\n\t\t\t\treturn false;\n\t\t\treturn block.Instructions[1].MatchBranch(targetBlock);\n\t\t}\n\n\t\tbool IsNullSafeArrayToPointerNullOrEmptyBlock(Block block, out ILVariable p, out Block targetBlock)\n\t\t{\n\t\t\tp = null;\n\t\t\ttargetBlock = null;\n\t\t\t// Block B_null_or_empty {\n\t\t\t//   stloc P(conv i4->u(ldc.i4 0))\n\t\t\t//   br B_target\n\t\t\t// }\n\t\t\tILInstruction value;\n\t\t\treturn block.Instructions.Count == 2\n\t\t\t\t&& block.Instructions[0].MatchStLoc(out p, out value)\n\t\t\t\t&& (p.Kind == VariableKind.PinnedLocal || p.Kind == VariableKind.Local)\n\t\t\t\t&& IsNullOrZero(value)\n\t\t\t\t&& block.Instructions[1].MatchBranch(out targetBlock);\n\t\t}\n\t\t#endregion\n\n\t\t#region CreatePinnedRegion\n\t\tbool DetectPinnedRegion(Block block)\n\t\t{\n\t\t\t// After SplitBlocksAtWritesToPinnedLocals(), only the second-to-last instruction in each block\n\t\t\t// can be a write to a pinned local.\n\t\t\tvar stLoc = block.Instructions.SecondToLastOrDefault() as StLoc;\n\t\t\tif (stLoc == null || stLoc.Variable.Kind != VariableKind.PinnedLocal)\n\t\t\t\treturn false;\n\t\t\t// stLoc is a store to a pinned local.\n\t\t\tif (IsNullOrZero(stLoc.Value))\n\t\t\t{\n\t\t\t\treturn false; // ignore unpin instructions\n\t\t\t}\n\t\t\tif (stLoc.Variable.Type.IsReferenceType == false)\n\t\t\t{\n\t\t\t\t// `pinned` flag has no effect on value types (#2148)\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// stLoc is a store that starts a new pinned region\n\n\t\t\tcontext.StepStartGroup($\"DetectPinnedRegion {stLoc.Variable.Name}\", block);\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn CreatePinnedRegion(block, stLoc);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tcontext.StepEndGroup(keepIfEmpty: true);\n\t\t\t}\n\t\t}\n\n\t\tbool CreatePinnedRegion(Block block, StLoc stLoc)\n\t\t{\n\t\t\t// Collect the blocks to be moved into the region:\n\t\t\tBlockContainer sourceContainer = (BlockContainer)block.Parent;\n\t\t\tint[] reachedEdgesPerBlock = new int[sourceContainer.Blocks.Count];\n\t\t\tQueue<Block> workList = new Queue<Block>();\n\t\t\tBlock entryBlock = ((Branch)block.Instructions.Last()).TargetBlock;\n\t\t\tif (entryBlock.Parent != sourceContainer)\n\t\t\t{\n\t\t\t\t// we didn't find a single block to be added to the pinned region\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (entryBlock.Instructions[0].MatchStLoc(stLoc.Variable, out _))\n\t\t\t{\n\t\t\t\t// pinned region has empty body\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treachedEdgesPerBlock[entryBlock.ChildIndex]++;\n\t\t\t\tworkList.Enqueue(entryBlock);\n\t\t\t}\n\t\t\twhile (workList.Count > 0)\n\t\t\t{\n\t\t\t\tBlock workItem = workList.Dequeue();\n\t\t\t\tforeach (var branch in workItem.Descendants.OfType<Branch>())\n\t\t\t\t{\n\t\t\t\t\tif (branch.TargetBlock.Parent == sourceContainer)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (branch.TargetBlock.Instructions[0].MatchStLoc(stLoc.Variable, out _))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Found unpin instruction\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tDebug.Assert(branch.TargetBlock != block);\n\t\t\t\t\t\tif (reachedEdgesPerBlock[branch.TargetBlock.ChildIndex]++ == 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// detected first edge to that block: add block as work item\n\t\t\t\t\t\t\tworkList.Enqueue(branch.TargetBlock);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Validate that all uses of a block consistently are inside or outside the pinned region.\n\t\t\t// (we cannot do this anymore after we start moving blocks around)\n\t\t\tbool cloneBlocks = false;\n\t\t\tfor (int i = 0; i < sourceContainer.Blocks.Count; i++)\n\t\t\t{\n\t\t\t\tif (reachedEdgesPerBlock[i] != 0 && reachedEdgesPerBlock[i] != sourceContainer.Blocks[i].IncomingEdgeCount)\n\t\t\t\t{\n\t\t\t\t\t// Don't abort in this case, we still need to somehow represent the pinned variable with a fixed statement.\n\t\t\t\t\t// We'll duplicate the code so that it can be both inside and outside the pinned region.\n\t\t\t\t\tcloneBlocks = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcontext.Step(\"CreatePinnedRegion\", block);\n\t\t\tBlockContainer body = new BlockContainer();\n\t\t\tBlock[] clonedBlocks = cloneBlocks ? new Block[sourceContainer.Blocks.Count] : null;\n\t\t\tfor (int i = 0; i < sourceContainer.Blocks.Count; i++)\n\t\t\t{\n\t\t\t\tif (reachedEdgesPerBlock[i] > 0)\n\t\t\t\t{\n\t\t\t\t\tvar innerBlock = sourceContainer.Blocks[i];\n\t\t\t\t\tif (cloneBlocks)\n\t\t\t\t\t{\n\t\t\t\t\t\tinnerBlock = (Block)innerBlock.Clone();\n\t\t\t\t\t\tclonedBlocks[i] = innerBlock;\n\t\t\t\t\t}\n\t\t\t\t\tif (innerBlock.MatchIfAtEndOfBlock(out _, out var trueInst, out var falseInst))\n\t\t\t\t\t{\n\t\t\t\t\t\tHandleBranchLeavingPinnedRegion(trueInst, reachedEdgesPerBlock, sourceContainer, stLoc.Variable);\n\t\t\t\t\t\tHandleBranchLeavingPinnedRegion(falseInst, reachedEdgesPerBlock, sourceContainer, stLoc.Variable);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tHandleBranchLeavingPinnedRegion(innerBlock.Instructions.LastOrDefault(), reachedEdgesPerBlock, sourceContainer, stLoc.Variable);\n\t\t\t\t\t}\n\n\t\t\t\t\t// move block into body\n\t\t\t\t\tif (sourceContainer.Blocks[i] == entryBlock)\n\t\t\t\t\t{\n\t\t\t\t\t\t// ensure entry point comes first\n\t\t\t\t\t\tbody.Blocks.Insert(0, innerBlock);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tbody.Blocks.Add(innerBlock);\n\t\t\t\t\t}\n\t\t\t\t\tif (!cloneBlocks)\n\t\t\t\t\t{\n\t\t\t\t\t\tsourceContainer.Blocks[i] = new Block(); // replace with dummy block\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t // we'll delete the dummy block later\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (body.Blocks.Count == 0)\n\t\t\t{\n\t\t\t\t// empty body, the entryBlock itself doesn't belong into the pinned region\n\t\t\t\tDebug.Assert(reachedEdgesPerBlock[entryBlock.ChildIndex] == 0);\n\t\t\t\tvar bodyBlock = new Block();\n\t\t\t\tbodyBlock.SetILRange(stLoc);\n\t\t\t\tbodyBlock.Instructions.Add(new Branch(entryBlock));\n\t\t\t\tbody.Blocks.Add(bodyBlock);\n\t\t\t}\n\n\t\t\tvar pinnedRegion = new PinnedRegion(stLoc.Variable, stLoc.Value, body).WithILRange(stLoc);\n\t\t\tstLoc.ReplaceWith(pinnedRegion);\n\t\t\tblock.Instructions.RemoveAt(block.Instructions.Count - 1); // remove branch into body\n\n\t\t\tif (cloneBlocks)\n\t\t\t{\n\t\t\t\t// Adjust branches between cloned blocks.\n\t\t\t\tforeach (var branch in body.Descendants.OfType<Branch>())\n\t\t\t\t{\n\t\t\t\t\tif (branch.TargetContainer == sourceContainer)\n\t\t\t\t\t{\n\t\t\t\t\t\tint i = branch.TargetBlock.ChildIndex;\n\t\t\t\t\t\tif (clonedBlocks[i] != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbranch.TargetBlock = clonedBlocks[i];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Replace unreachable blocks in sourceContainer with dummy blocks:\n\t\t\t\tbool[] isAlive = new bool[sourceContainer.Blocks.Count];\n\t\t\t\tList<int> duplicatedBlockStartOffsets = new List<int>();\n\t\t\t\tforeach (var remainingBlock in sourceContainer.TopologicalSort(deleteUnreachableBlocks: true))\n\t\t\t\t{\n\t\t\t\t\tisAlive[remainingBlock.ChildIndex] = true;\n\t\t\t\t\tif (clonedBlocks[remainingBlock.ChildIndex] != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tduplicatedBlockStartOffsets.Add(remainingBlock.StartILOffset);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor (int i = 0; i < isAlive.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tif (!isAlive[i])\n\t\t\t\t\t\tsourceContainer.Blocks[i] = new Block();\n\t\t\t\t}\n\t\t\t\t// we'll delete the dummy blocks later\n\t\t\t\tDebug.Assert(duplicatedBlockStartOffsets.Count > 0);\n\t\t\t\tduplicatedBlockStartOffsets.Sort();\n\t\t\t\tcontext.Function.Warnings.Add(\"The blocks \"\n\t\t\t\t\t+ string.Join(\", \", duplicatedBlockStartOffsets.Select(o => $\"IL_{o:x4}\"))\n\t\t\t\t\t+ $\" are reachable both inside and outside the pinned region starting at IL_{stLoc.StartILOffset:x4}.\"\n\t\t\t\t\t+ \" ILSpy has duplicated these blocks in order to place them both within and outside the `fixed` statement.\");\n\t\t\t}\n\n\t\t\tProcessPinnedRegion(pinnedRegion);\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic void HandleBranchLeavingPinnedRegion(ILInstruction potentialBranch, int[] reachedEdgesPerBlock, BlockContainer sourceContainer, ILVariable pinnedRegionVar)\n\t\t{\n\t\t\tif (potentialBranch is Branch branch && branch.TargetBlock.IncomingEdgeCount == 1\n\t\t\t \t&& branch.TargetContainer == sourceContainer && reachedEdgesPerBlock[branch.TargetBlock.ChildIndex] == 0)\n\t\t\t{\n\t\t\t\t// branch that leaves body.\n\t\t\t\t// The target block should have an instruction that resets the pin; delete that instruction:\n\t\t\t\tStLoc unpin = branch.TargetBlock.Instructions.First() as StLoc;\n\t\t\t\tif (unpin != null && unpin.Variable == pinnedRegionVar && IsNullOrZero(unpin.Value))\n\t\t\t\t{\n\t\t\t\t\tbranch.TargetBlock.Instructions.RemoveAt(0);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic bool IsNullOrZero(ILInstruction inst)\n\t\t{\n\t\t\twhile (inst is Conv conv)\n\t\t\t{\n\t\t\t\tinst = conv.Argument;\n\t\t\t}\n\t\t\treturn inst.MatchLdcI4(0) || inst.MatchLdNull();\n\t\t}\n\t\t#endregion\n\n\t\t#region ProcessPinnedRegion\n\t\t/// <summary>\n\t\t/// After a pinned region was detected; process its body; replacing the pin variable\n\t\t/// with a native pointer as far as possible.\n\t\t/// </summary>\n\t\tvoid ProcessPinnedRegion(PinnedRegion pinnedRegion)\n\t\t{\n\t\t\tif (pinnedRegion.Variable.Type.Kind == TypeKind.ByReference)\n\t\t\t{\n\t\t\t\t// C# doesn't support a \"by reference\" variable, so replace it with a native pointer\n\t\t\t\tcontext.Step(\"Replace pinned ref-local with native pointer\", pinnedRegion);\n\t\t\t\tILVariable oldVar = pinnedRegion.Variable;\n\t\t\t\tIType elementType = ((ByReferenceType)oldVar.Type).ElementType;\n\t\t\t\tif (elementType.Kind == TypeKind.Pointer && pinnedRegion.Init.MatchLdFlda(out _, out var field)\n\t\t\t\t\t&& ((PointerType)elementType).ElementType.Equals(field.Type))\n\t\t\t\t{\n\t\t\t\t\t// Roslyn 2.6 (C# 7.2) uses type \"int*&\" for the pinned local referring to a\n\t\t\t\t\t// fixed field of type \"int\".\n\t\t\t\t\t// Remove the extra level of indirection.\n\t\t\t\t\telementType = ((PointerType)elementType).ElementType;\n\t\t\t\t}\n\t\t\t\tILVariable newVar = new ILVariable(\n\t\t\t\t\tVariableKind.PinnedRegionLocal,\n\t\t\t\t\tnew PointerType(elementType),\n\t\t\t\t\toldVar.Index);\n\t\t\t\tnewVar.Name = oldVar.Name;\n\t\t\t\tnewVar.HasGeneratedName = oldVar.HasGeneratedName;\n\t\t\t\toldVar.Function.Variables.Add(newVar);\n\t\t\t\tReplacePinnedVar(oldVar, newVar, pinnedRegion);\n\t\t\t\tUseExistingVariableForPinnedRegion(pinnedRegion);\n\t\t\t}\n\t\t\telse if (pinnedRegion.Variable.Type.Kind == TypeKind.Array)\n\t\t\t{\n\t\t\t\tcontext.Step(\"Replace pinned array with native pointer\", pinnedRegion);\n\t\t\t\tMoveArrayToPointerToPinnedRegionInit(pinnedRegion);\n\t\t\t\tUseExistingVariableForPinnedRegion(pinnedRegion);\n\t\t\t}\n\t\t\telse if (pinnedRegion.Variable.Type.IsKnownType(KnownTypeCode.String))\n\t\t\t{\n\t\t\t\t// fixing a string\n\t\t\t\tHandleStringToPointer(pinnedRegion);\n\t\t\t}\n\t\t\telse if (pinnedRegion.Init is Conv { Kind: ConversionKind.StopGCTracking, Argument: var convArg })\n\t\t\t{\n\t\t\t\t// If pinnedRegion.Variable was already a pointer type, the input IL has a StopGCTracking conversion.\n\t\t\t\t// We can simply remove this conversion, as it is not needed.\n\t\t\t\tcontext.Step(\"Remove StopGCTracking conversion\", pinnedRegion);\n\t\t\t\tpinnedRegion.Init = convArg;\n\t\t\t}\n\t\t\t// Detect nested pinned regions:\n\t\t\tBlockContainer body = (BlockContainer)pinnedRegion.Body;\n\t\t\tforeach (var block in body.Blocks)\n\t\t\t\tDetectPinnedRegion(block);\n\t\t\tbody.Blocks.RemoveAll(b => b.Instructions.Count == 0); // remove dummy blocks\n\t\t\tbody.SetILRange(body.EntryPoint);\n\t\t\tif (pinnedRegion.Variable.Kind != VariableKind.PinnedRegionLocal)\n\t\t\t{\n\t\t\t\tDebug.Assert(pinnedRegion.Variable.Kind == VariableKind.PinnedLocal);\n\t\t\t\tpinnedRegion.Variable.Kind = VariableKind.PinnedRegionLocal;\n\t\t\t}\n\t\t}\n\n\t\tprivate void MoveArrayToPointerToPinnedRegionInit(PinnedRegion pinnedRegion)\n\t\t{\n\t\t\t// Roslyn started marking the array variable as pinned,\n\t\t\t// and then uses array.to.pointer immediately within the region.\n\t\t\tDebug.Assert(pinnedRegion.Variable.Type.Kind == TypeKind.Array);\n\t\t\t// Find the single load of the variable within the pinnedRegion:\n\t\t\tLdLoc ldloc = null;\n\t\t\tforeach (var inst in pinnedRegion.Descendants.OfType<IInstructionWithVariableOperand>())\n\t\t\t{\n\t\t\t\tif (inst.Variable == pinnedRegion.Variable && inst != pinnedRegion)\n\t\t\t\t{\n\t\t\t\t\tif (ldloc != null)\n\t\t\t\t\t\treturn; // more than 1 variable access\n\t\t\t\t\tldloc = inst as LdLoc;\n\t\t\t\t\tif (ldloc == null)\n\t\t\t\t\t\treturn; // variable access that is not LdLoc\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (ldloc == null)\n\t\t\t\treturn;\n\t\t\tif (!(ldloc.Parent is GetPinnableReference arrayToPointer))\n\t\t\t\treturn;\n\t\t\tif (!(arrayToPointer.Parent is Conv conv && conv.Kind == ConversionKind.StopGCTracking))\n\t\t\t\treturn;\n\t\t\tDebug.Assert(arrayToPointer.IsDescendantOf(pinnedRegion));\n\t\t\tILVariable oldVar = pinnedRegion.Variable;\n\t\t\tILVariable newVar = new ILVariable(\n\t\t\t\tVariableKind.PinnedRegionLocal,\n\t\t\t\tnew PointerType(((ArrayType)oldVar.Type).ElementType),\n\t\t\t\toldVar.Index);\n\t\t\tnewVar.Name = oldVar.Name;\n\t\t\tnewVar.HasGeneratedName = oldVar.HasGeneratedName;\n\t\t\toldVar.Function.Variables.Add(newVar);\n\t\t\tpinnedRegion.Variable = newVar;\n\t\t\tpinnedRegion.Init = new GetPinnableReference(pinnedRegion.Init, arrayToPointer.Method).WithILRange(arrayToPointer);\n\t\t\tconv.ReplaceWith(new LdLoc(newVar).WithILRange(conv));\n\t\t}\n\n\t\tvoid ReplacePinnedVar(ILVariable oldVar, ILVariable newVar, ILInstruction inst)\n\t\t{\n\t\t\tDebug.Assert(newVar.StackType == StackType.I);\n\t\t\tif (inst is Conv conv && conv.Kind == ConversionKind.StopGCTracking && conv.Argument.MatchLdLoc(oldVar) && conv.ResultType == newVar.StackType)\n\t\t\t{\n\t\t\t\t// conv ref->i (ldloc oldVar)\n\t\t\t\t//  => ldloc newVar\n\t\t\t\tconv.AddILRange(conv.Argument);\n\t\t\t\tconv.ReplaceWith(new LdLoc(newVar).WithILRange(conv));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (inst is IInstructionWithVariableOperand iwvo && iwvo.Variable == oldVar)\n\t\t\t{\n\t\t\t\tiwvo.Variable = newVar;\n\t\t\t\tif (inst is StLoc stloc && oldVar.Type.Kind == TypeKind.ByReference)\n\t\t\t\t{\n\t\t\t\t\tstloc.Value = new Conv(stloc.Value, PrimitiveType.I, false, Sign.None);\n\t\t\t\t}\n\t\t\t\tif ((inst is LdLoc || inst is StLoc) && !IsSlotAcceptingBothManagedAndUnmanagedPointers(inst.SlotInfo) && oldVar.StackType != StackType.I)\n\t\t\t\t{\n\t\t\t\t\t// wrap inst in Conv, so that the stack types match up\n\t\t\t\t\tvar children = inst.Parent.Children;\n\t\t\t\t\tchildren[inst.ChildIndex] = new Conv(inst, oldVar.StackType.ToPrimitiveType(), false, Sign.None);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (inst.MatchLdStr(out var val) && val == \"Is this ILSpy?\")\n\t\t\t{\n\t\t\t\tinst.ReplaceWith(new LdStr(\"This is ILSpy!\")); // easter egg ;)\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tforeach (var child in inst.Children)\n\t\t\t{\n\t\t\t\tReplacePinnedVar(oldVar, newVar, child);\n\t\t\t}\n\t\t}\n\n\t\tprivate bool IsSlotAcceptingBothManagedAndUnmanagedPointers(SlotInfo slotInfo)\n\t\t{\n\t\t\treturn slotInfo == Block.InstructionSlot || slotInfo == LdObj.TargetSlot || slotInfo == StObj.TargetSlot;\n\t\t}\n\n\t\tbool IsBranchOnNull(ILInstruction condBranch, ILVariable nativeVar, out Block targetBlock)\n\t\t{\n\t\t\ttargetBlock = null;\n\t\t\t// if (comp(ldloc nativeVar == conv i4->i <sign extend>(ldc.i4 0))) br targetBlock\n\t\t\tILInstruction condition, trueInst, left, right;\n\t\t\treturn condBranch.MatchIfInstruction(out condition, out trueInst)\n\t\t\t\t&& condition.MatchCompEquals(out left, out right)\n\t\t\t\t&& left.MatchLdLoc(nativeVar) && IsNullOrZero(right)\n\t\t\t\t&& trueInst.MatchBranch(out targetBlock);\n\t\t}\n\n\t\tvoid HandleStringToPointer(PinnedRegion pinnedRegion)\n\t\t{\n\t\t\tDebug.Assert(pinnedRegion.Variable.Type.IsKnownType(KnownTypeCode.String));\n\t\t\tBlockContainer body = (BlockContainer)pinnedRegion.Body;\n\t\t\tif (body.EntryPoint.IncomingEdgeCount != 1)\n\t\t\t\treturn;\n\t\t\t// stloc nativeVar(conv o->i (ldloc pinnedVar))\n\t\t\t// if (comp(ldloc nativeVar == conv i4->i <sign extend>(ldc.i4 0))) br targetBlock\n\t\t\t// br adjustOffsetToStringData\n\t\t\tILVariable newVar;\n\t\t\tif (!body.EntryPoint.Instructions[0].MatchStLoc(out ILVariable nativeVar, out ILInstruction initInst))\n\t\t\t{\n\t\t\t\t// potentially a special case with legacy csc and an unused pinned variable:\n\t\t\t\tif (pinnedRegion.Variable.AddressCount == 0 && pinnedRegion.Variable.LoadCount == 0)\n\t\t\t\t{\n\t\t\t\t\tvar charPtr = new PointerType(context.TypeSystem.FindType(KnownTypeCode.Char));\n\t\t\t\t\tnewVar = new ILVariable(VariableKind.PinnedRegionLocal, charPtr, pinnedRegion.Variable.Index);\n\t\t\t\t\tnewVar.Name = pinnedRegion.Variable.Name;\n\t\t\t\t\tnewVar.HasGeneratedName = pinnedRegion.Variable.HasGeneratedName;\n\t\t\t\t\tpinnedRegion.Variable.Function.Variables.Add(newVar);\n\t\t\t\t\tpinnedRegion.Variable = newVar;\n\t\t\t\t\tpinnedRegion.Init = new GetPinnableReference(pinnedRegion.Init, null);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (nativeVar.Type.GetStackType() != StackType.I)\n\t\t\t\treturn;\n\n\t\t\tBlock targetBlock;\n\t\t\tBlock adjustOffsetToStringData = null;\n\t\t\tif (body.EntryPoint.Instructions.Count == 2)\n\t\t\t{\n\t\t\t\tif (!initInst.MatchBinaryNumericInstruction(BinaryNumericOperator.Add, out ILInstruction left, out ILInstruction right))\n\t\t\t\t\treturn;\n\t\t\t\tif (!left.UnwrapConv(ConversionKind.StopGCTracking).MatchLdLoc(pinnedRegion.Variable))\n\t\t\t\t\treturn;\n\t\t\t\tif (!IsOffsetToStringDataCall(right))\n\t\t\t\t\treturn;\n\t\t\t\tif (!body.EntryPoint.Instructions[1].MatchBranch(out targetBlock))\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t\telse if (body.EntryPoint.Instructions.Count == 3)\n\t\t\t{\n\t\t\t\tif (!initInst.UnwrapConv(ConversionKind.StopGCTracking).MatchLdLoc(pinnedRegion.Variable))\n\t\t\t\t\treturn;\n\t\t\t\tif (!IsBranchOnNull(body.EntryPoint.Instructions[1], nativeVar, out targetBlock))\n\t\t\t\t\treturn;\n\t\t\t\tif (!body.EntryPoint.Instructions[2].MatchBranch(out adjustOffsetToStringData))\n\t\t\t\t\treturn;\n\t\t\t\tif (!(adjustOffsetToStringData.Parent == body && adjustOffsetToStringData.IncomingEdgeCount == 1\n\t\t\t\t\t\t&& IsOffsetToStringDataBlock(adjustOffsetToStringData, nativeVar, targetBlock)))\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn;\n\n\t\t\tcontext.Step(\"Handle pinned string (with adjustOffsetToStringData)\", pinnedRegion);\n\t\t\tif (targetBlock.Parent == body)\n\t\t\t{\n\t\t\t\t// remove old entry point\n\t\t\t\tbody.Blocks.RemoveAt(0);\n\t\t\t\tif (adjustOffsetToStringData is not null)\n\t\t\t\t\tbody.Blocks.RemoveAt(adjustOffsetToStringData.ChildIndex);\n\t\t\t\t// make targetBlock the new entry point\n\t\t\t\tbody.Blocks.RemoveAt(targetBlock.ChildIndex);\n\t\t\t\tbody.Blocks.Insert(0, targetBlock);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// pinned region has empty body, immediately jumps to targetBlock which is outside\n\t\t\t\tbody.Blocks[0].Instructions.Clear();\n\t\t\t\tbody.Blocks.RemoveRange(1, body.Blocks.Count - 1);\n\t\t\t\tbody.Blocks[0].Instructions.Add(new Branch(targetBlock));\n\t\t\t}\n\t\t\tpinnedRegion.Init = new GetPinnableReference(pinnedRegion.Init, null);\n\n\t\t\tILVariable otherVar;\n\t\t\tILInstruction otherVarInit;\n\t\t\t// In optimized builds, the 'nativeVar' may end up being a stack slot,\n\t\t\t// and only gets assigned to a real variable after the offset adjustment.\n\t\t\tif (nativeVar.Kind == VariableKind.StackSlot && nativeVar.LoadCount == 1\n\t\t\t\t&& body.EntryPoint.Instructions[0].MatchStLoc(out otherVar, out otherVarInit)\n\t\t\t\t&& otherVarInit.MatchLdLoc(nativeVar)\n\t\t\t\t&& otherVar.IsSingleDefinition)\n\t\t\t{\n\t\t\t\tbody.EntryPoint.Instructions.RemoveAt(0);\n\t\t\t\tnativeVar = otherVar;\n\t\t\t}\n\t\t\tif (nativeVar.Kind == VariableKind.Local)\n\t\t\t{\n\t\t\t\tnewVar = new ILVariable(VariableKind.PinnedRegionLocal, nativeVar.Type, nativeVar.Index);\n\t\t\t\tnewVar.Name = nativeVar.Name;\n\t\t\t\tnewVar.HasGeneratedName = nativeVar.HasGeneratedName;\n\t\t\t\tnativeVar.Function.Variables.Add(newVar);\n\t\t\t\tReplacePinnedVar(nativeVar, newVar, pinnedRegion);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tnewVar = nativeVar;\n\t\t\t}\n\t\t\tReplacePinnedVar(pinnedRegion.Variable, newVar, pinnedRegion);\n\t\t}\n\n\t\tbool IsOffsetToStringDataBlock(Block block, ILVariable nativeVar, Block targetBlock)\n\t\t{\n\t\t\t// stloc nativeVar(add(ldloc nativeVar, conv i4->i <sign extend>(call [Accessor System.Runtime.CompilerServices.RuntimeHelpers.get_OffsetToStringData():System.Int32]())))\n\t\t\t// br IL_0011\n\t\t\tif (block.Instructions.Count != 2)\n\t\t\t\treturn false;\n\t\t\tILInstruction value;\n\t\t\tif (nativeVar.IsSingleDefinition && nativeVar.LoadCount == 2)\n\t\t\t{\n\t\t\t\t// If there are no loads (except for the two in the string-to-pointer pattern),\n\t\t\t\t// then we might have split nativeVar:\n\t\t\t\tif (!block.Instructions[0].MatchStLoc(out var otherVar, out value))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(otherVar.IsSingleDefinition && otherVar.LoadCount == 0))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (nativeVar.StoreCount == 2)\n\t\t\t{\n\t\t\t\t// normal case with non-split variable\n\t\t\t\tif (!block.Instructions[0].MatchStLoc(nativeVar, out value))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!value.MatchBinaryNumericInstruction(BinaryNumericOperator.Add, out ILInstruction left, out ILInstruction right))\n\t\t\t\treturn false;\n\t\t\tif (!left.MatchLdLoc(nativeVar))\n\t\t\t\treturn false;\n\t\t\tif (!IsOffsetToStringDataCall(right))\n\t\t\t\treturn false;\n\t\t\treturn block.Instructions[1].MatchBranch(targetBlock);\n\t\t}\n\n\t\tbool IsOffsetToStringDataCall(ILInstruction inst)\n\t\t{\n\t\t\tCall call = inst.UnwrapConv(ConversionKind.SignExtend) as Call;\n\t\t\treturn call != null && call.Method.FullName == \"System.Runtime.CompilerServices.RuntimeHelpers.get_OffsetToStringData\";\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Modifies a pinned region to eliminate an extra local variable that roslyn tends to generate.\n\t\t/// </summary>\n\t\tvoid UseExistingVariableForPinnedRegion(PinnedRegion pinnedRegion)\n\t\t{\n\t\t\t// PinnedRegion V_1(..., BlockContainer {\n\t\t\t// Block IL_0000(incoming: 1) {\n\t\t\t//    stloc V_0(ldloc V_1)\n\t\t\t//    ...\n\t\t\tif (!(pinnedRegion.Body is BlockContainer body))\n\t\t\t\treturn;\n\t\t\tif (pinnedRegion.Variable.LoadCount != 1)\n\t\t\t\treturn;\n\t\t\tif (!body.EntryPoint.Instructions[0].MatchStLoc(out var v, out var init))\n\t\t\t\treturn;\n\t\t\tif (!init.MatchLdLoc(pinnedRegion.Variable))\n\t\t\t\treturn;\n\t\t\tif (!(v.IsSingleDefinition && v.Type.Equals(pinnedRegion.Variable.Type)))\n\t\t\t\treturn;\n\t\t\tif (v.Kind != VariableKind.Local)\n\t\t\t\treturn;\n\t\t\t// replace V_1 with V_0\n\t\t\tv.Kind = VariableKind.PinnedRegionLocal;\n\t\t\tpinnedRegion.Variable = v;\n\t\t\tbody.EntryPoint.Instructions.RemoveAt(0);\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ControlFlow/ExitPoints.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.IL.Transforms;\n\nnamespace ICSharpCode.Decompiler.IL.ControlFlow\n{\n\t/// <summary>\n\t/// Detect suitable exit points for BlockContainers.\n\t/// \n\t/// An \"exit point\" is an instruction that causes control flow\n\t/// to leave the container (a branch or leave instruction).\n\t/// \n\t/// If an \"exit point\" instruction is placed immediately following a\n\t/// block container, each equivalent exit point within the container\n\t/// can be replaced with a \"leave container\" instruction.\n\t/// \n\t/// This transform performs this replacement: any exit points\n\t/// equivalent to the exit point following the container are\n\t/// replaced with a leave instruction.\n\t/// Additionally, if the container is not yet followed by an exit point,\n\t/// but has room to introduce such an exit point (i.e. iff the container's \n\t/// end point is currently unreachable), we pick one of the non-return\n\t/// exit points within the container, move it to the position following the\n\t/// container, and replace all instances within the container with a leave\n\t/// instruction.\n\t/// \n\t/// This makes it easier for the following transforms to construct\n\t/// control flow that falls out of blocks instead of using goto/break statements.\n\t/// </summary>\n\tpublic class DetectExitPoints : ILVisitor, IILTransform\n\t{\n\t\tstatic readonly Nop ExitNotYetDetermined = new Nop { Comment = \"ExitNotYetDetermined\" };\n\t\tstatic readonly Nop NoExit = new Nop { Comment = \"NoExit\" };\n\n\t\t/// <summary>\n\t\t/// Gets the next instruction after <paramref name=\"inst\"/> is executed.\n\t\t/// Returns NoExit when the next instruction cannot be identified;\n\t\t/// returns <c>null</c> when the end of a Block is reached (so that we could insert an arbitrary instruction)\n\t\t/// </summary>\n\t\tinternal static ILInstruction GetExit(ILInstruction inst)\n\t\t{\n\t\t\tSlotInfo? slot = inst.SlotInfo;\n\t\t\tif (slot == Block.InstructionSlot)\n\t\t\t{\n\t\t\t\tBlock block = (Block)inst.Parent!;\n\t\t\t\treturn block.Instructions.ElementAtOrDefault(inst.ChildIndex + 1) ?? ExitNotYetDetermined;\n\t\t\t}\n\t\t\telse if (slot == TryInstruction.TryBlockSlot\n\t\t\t  || slot == TryCatchHandler.BodySlot\n\t\t\t  || slot == TryCatch.HandlerSlot\n\t\t\t  || slot == PinnedRegion.BodySlot\n\t\t\t  || slot == UsingInstruction.BodySlot\n\t\t\t  || slot == LockInstruction.BodySlot)\n\t\t\t{\n\t\t\t\treturn GetExit(inst.Parent!);\n\t\t\t}\n\t\t\treturn NoExit;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns true iff exit1 and exit2 are both exit instructions\n\t\t/// (branch or leave) and both represent the same exit.\n\t\t/// </summary>\n\t\tinternal static bool CompatibleExitInstruction(ILInstruction exit1, ILInstruction exit2)\n\t\t{\n\t\t\tif (exit1 == null || exit2 == null || exit1.OpCode != exit2.OpCode)\n\t\t\t\treturn false;\n\t\t\tswitch (exit1.OpCode)\n\t\t\t{\n\t\t\t\tcase OpCode.Branch:\n\t\t\t\t\tBranch br1 = (Branch)exit1;\n\t\t\t\t\tBranch br2 = (Branch)exit2;\n\t\t\t\t\treturn br1.TargetBlock == br2.TargetBlock;\n\t\t\t\tcase OpCode.Leave:\n\t\t\t\t\tLeave leave1 = (Leave)exit1;\n\t\t\t\t\tLeave leave2 = (Leave)exit2;\n\t\t\t\t\treturn leave1.TargetContainer == leave2.TargetContainer && leave1.Value.MatchNop() && leave2.Value.MatchNop();\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tclass ContainerContext\n\t\t{\n\t\t\tpublic readonly BlockContainer Container;\n\n\t\t\t/// <summary>\n\t\t\t/// The instruction that will be executed next after leaving the Container.\n\t\t\t/// <c>ExitNotYetDetermined</c> means the container is last in its parent block, and thus does not\n\t\t\t/// yet have any leave instructions. This means we can move any exit instruction of\n\t\t\t/// our choice our of the container and replace it with a leave instruction.\n\t\t\t/// </summary>\n\t\t\tpublic readonly ILInstruction CurrentExit;\n\n\t\t\t/// <summary>\n\t\t\t/// If <c>currentExit==ExitNotYetDetermined</c>, holds the list of potential exit instructions.\n\t\t\t/// After the currentContainer was visited completely, one of these will be selected as exit instruction.\n\t\t\t/// </summary>\n\t\t\tpublic readonly List<ILInstruction>? PotentialExits = null;\n\n\t\t\tpublic ContainerContext(BlockContainer container, ILInstruction currentExit)\n\t\t\t{\n\t\t\t\tthis.Container = container;\n\t\t\t\tthis.CurrentExit = currentExit;\n\t\t\t\tthis.PotentialExits = (currentExit == ExitNotYetDetermined ? new List<ILInstruction>() : null);\n\t\t\t}\n\n\t\t\tpublic void HandleExit(ILInstruction inst)\n\t\t\t{\n\t\t\t\tif (this.CurrentExit == ExitNotYetDetermined && this.Container.LeaveCount == 0)\n\t\t\t\t{\n\t\t\t\t\tthis.PotentialExits!.Add(inst);\n\t\t\t\t}\n\t\t\t\telse if (CompatibleExitInstruction(inst, this.CurrentExit))\n\t\t\t\t{\n\t\t\t\t\tinst.ReplaceWith(new Leave(this.Container).WithILRange(inst));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tCancellationToken cancellationToken;\n\t\treadonly List<Block> blocksPotentiallyMadeUnreachable = new List<Block>();\n\t\treadonly Stack<ContainerContext> containerStack = new Stack<ContainerContext>();\n\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tcancellationToken = context.CancellationToken;\n\t\t\tblocksPotentiallyMadeUnreachable.Clear();\n\t\t\tcontainerStack.Clear();\n\t\t\tfunction.AcceptVisitor(this);\n\t\t\t// It's possible that there are unreachable code blocks which we only\n\t\t\t// detect as such during exit point detection.\n\t\t\t// Clean them up.\n\t\t\tforeach (var block in blocksPotentiallyMadeUnreachable)\n\t\t\t{\n\t\t\t\tif (block.IncomingEdgeCount == 0 || block.IncomingEdgeCount == 1 && IsInfiniteLoop(block))\n\t\t\t\t{\n\t\t\t\t\tblock.Remove();\n\t\t\t\t}\n\t\t\t}\n\t\t\tblocksPotentiallyMadeUnreachable.Clear();\n\t\t\tcontainerStack.Clear();\n\t\t}\n\n\t\tstatic bool IsInfiniteLoop(Block block)\n\t\t{\n\t\t\treturn block.Instructions.Count == 1\n\t\t\t\t&& block.Instructions[0] is Branch b\n\t\t\t\t&& b.TargetBlock == block;\n\t\t}\n\n\t\tprotected override void Default(ILInstruction inst)\n\t\t{\n\t\t\tforeach (var child in inst.Children)\n\t\t\t\tchild.AcceptVisitor(this);\n\t\t}\n\n\t\tprotected internal override void VisitBlockContainer(BlockContainer container)\n\t\t{\n\t\t\tvar thisExit = GetExit(container);\n\t\t\tvar stackEntry = new ContainerContext(container, thisExit);\n\t\t\tcontainerStack.Push(stackEntry);\n\t\t\tbase.VisitBlockContainer(container);\n\t\t\tif (stackEntry.PotentialExits?.Any(i => i.IsConnected) ?? false)\n\t\t\t{\n\t\t\t\t// This transform determined an exit point.\n\t\t\t\tvar newExit = ChooseExit(stackEntry.PotentialExits.Where(i => i.IsConnected));\n\t\t\t\tDebug.Assert(!newExit.MatchLeave(container));\n\t\t\t\tforeach (var exit in stackEntry.PotentialExits)\n\t\t\t\t{\n\t\t\t\t\tif (exit.IsConnected && CompatibleExitInstruction(newExit, exit))\n\t\t\t\t\t{\n\t\t\t\t\t\texit.ReplaceWith(new Leave(container).WithILRange(exit));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tILInstruction inst = container;\n\t\t\t\t// traverse up to the block (we'll always find one because GetExit\n\t\t\t\t// only returns ExitNotYetDetermined if there's a block)\n\t\t\t\twhile (inst.Parent!.OpCode != OpCode.Block)\n\t\t\t\t\tinst = inst.Parent;\n\t\t\t\tBlock block = (Block)inst.Parent;\n\t\t\t\tif (block.HasFlag(InstructionFlags.EndPointUnreachable))\n\t\t\t\t{\n\t\t\t\t\t// Special case: despite replacing the exits with leave(currentContainer),\n\t\t\t\t\t// we still have an unreachable endpoint.\n\t\t\t\t\t// The appended currentExit instruction would not be reachable!\n\t\t\t\t\t// This happens in test case ExceptionHandling.ThrowInFinally()\n\t\t\t\t\tif (newExit is Branch b)\n\t\t\t\t\t{\n\t\t\t\t\t\tblocksPotentiallyMadeUnreachable.Add(b.TargetBlock);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tblock.Instructions.Add(newExit);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (containerStack.Pop() != stackEntry)\n\t\t\t{\n\t\t\t\tDebug.Fail(\"containerStack got imbalanced\");\n\t\t\t}\n\t\t}\n\n\t\tstatic ILInstruction ChooseExit(IEnumerable<ILInstruction> potentialExits)\n\t\t{\n\t\t\tusing var enumerator = potentialExits.GetEnumerator();\n\t\t\tenumerator.MoveNext();\n\t\t\tILInstruction first = enumerator.Current;\n\t\t\tif (first is Leave { IsLeavingFunction: true })\n\t\t\t{\n\t\t\t\twhile (enumerator.MoveNext())\n\t\t\t\t{\n\t\t\t\t\tvar exit = enumerator.Current;\n\t\t\t\t\tif (!(exit is Leave { IsLeavingFunction: true }))\n\t\t\t\t\t\treturn exit;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn first;\n\t\t}\n\n\t\tprotected internal override void VisitBlock(Block block)\n\t\t{\n\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t// Don't use foreach loop, because the children might add to the block\n\t\t\tfor (int i = 0; i < block.Instructions.Count; i++)\n\t\t\t{\n\t\t\t\tblock.Instructions[i].AcceptVisitor(this);\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void VisitBranch(Branch inst)\n\t\t{\n\t\t\tforeach (var entry in containerStack)\n\t\t\t{\n\t\t\t\tif (inst.TargetBlock.IsDescendantOf(entry.Container))\n\t\t\t\t\tbreak;\n\t\t\t\tentry.HandleExit(inst);\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void VisitLeave(Leave inst)\n\t\t{\n\t\t\tbase.VisitLeave(inst);\n\t\t\tif (!inst.Value.MatchNop())\n\t\t\t\treturn;\n\t\t\tforeach (var entry in containerStack)\n\t\t\t{\n\t\t\t\tif (inst.TargetContainer == entry.Container)\n\t\t\t\t\tbreak;\n\t\t\t\tif (inst.IsLeavingFunction || inst.TargetContainer.Kind != ContainerKind.Normal)\n\t\t\t\t{\n\t\t\t\t\tif (entry.Container.Kind == ContainerKind.Normal)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Don't transform a `return`/`break` into a leave for try-block containers (or similar).\n\t\t\t\t\t\t// It's possible that those can be turned into fallthrough later, but\n\t\t\t\t\t\t// it might not work out and then we would be left with a `goto`.\n\t\t\t\t\t\t// But continue searching the container stack, it might be possible to\n\t\t\t\t\t\t// turn the `return` into a `break` instead.\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// return; could turn to break;\n\t\t\t\t\t\tentry.HandleExit(inst);\n\t\t\t\t\t\tbreak; // but only for the innermost loop/switch\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tentry.HandleExit(inst);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ControlFlow/LoopDetection.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.FlowAnalysis;\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.ControlFlow\n{\n\t/// <summary>\n\t/// Detect loops in IL AST.\n\t/// </summary>\n\t/// <remarks>\n\t/// Transform ordering:\n\t/// * LoopDetection should run before other control flow structures are detected.\n\t/// * Blocks should be basic blocks (not extended basic blocks) so that the natural loops\n\t/// don't include more instructions than strictly necessary.\n\t/// * Loop detection should run after the 'return block' is duplicated (ControlFlowSimplification).\n\t/// </remarks>\n\tpublic class LoopDetection : IBlockTransform\n\t{\n\t\tBlockTransformContext context;\n\n\t\t/// <summary>Block container corresponding to the current cfg.</summary>\n\t\tBlockContainer currentBlockContainer;\n\n\t\t/// <summary>\n\t\t/// Enabled during DetectSwitchBody, used by ExtendLoop and children\n\t\t/// </summary>\n\t\tprivate bool isSwitch;\n\t\t/// <summary>\n\t\t/// Used when isSwitch == true, to determine appropriate exit points within loops\n\t\t/// </summary>\n\t\tprivate SwitchDetection.LoopContext loopContext;\n\n\t\t/// <summary>\n\t\t/// Check whether 'block' is a loop head; and construct a loop instruction\n\t\t/// (nested BlockContainer) if it is.\n\t\t/// </summary>\n\t\tpublic void Run(Block block, BlockTransformContext context)\n\t\t{\n\t\t\tthis.context = context;\n\t\t\t// LoopDetection runs early enough so that block should still\n\t\t\t// be in the original container at this point.\n\t\t\tDebug.Assert(block.Parent == context.ControlFlowGraph.Container);\n\t\t\tthis.currentBlockContainer = context.ControlFlowGraph.Container;\n\n\t\t\t// Because this is a post-order block transform, we can assume that\n\t\t\t// any nested loops within this loop have already been constructed.\n\n\t\t\tif (block.Instructions.Last() is SwitchInstruction switchInst)\n\t\t\t{\n\t\t\t\t// Switch instructions support \"break;\" just like loops\n\t\t\t\tDetectSwitchBody(block, switchInst);\n\t\t\t}\n\n\t\t\tControlFlowNode h = context.ControlFlowNode; // CFG node for our potential loop head\n\t\t\tDebug.Assert(h.UserData == block);\n\t\t\tDebug.Assert(!TreeTraversal.PreOrder(h, n => n.DominatorTreeChildren).Any(n => n.Visited));\n\n\t\t\tList<ControlFlowNode> loop = null;\n\t\t\tforeach (var t in h.Predecessors)\n\t\t\t{\n\t\t\t\tif (h.Dominates(t))\n\t\t\t\t{\n\t\t\t\t\t// h->t is a back edge, and h is a loop header\n\t\t\t\t\t// Add the natural loop of t->h to the loop.\n\n\t\t\t\t\t// Definitions:\n\t\t\t\t\t// * A back edge is an edge t->h so that h dominates t.\n\t\t\t\t\t// * The natural loop of the back edge is the smallest set of nodes\n\t\t\t\t\t//   that includes the back edge and has no predecessors outside the set\n\t\t\t\t\t//   except for the predecessor of the header.\n\n\t\t\t\t\tif (loop == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tloop = new List<ControlFlowNode>();\n\t\t\t\t\t\tloop.Add(h);\n\t\t\t\t\t\t// Mark loop header as visited so that the pre-order traversal\n\t\t\t\t\t\t// stops at the loop header.\n\t\t\t\t\t\th.Visited = true;\n\t\t\t\t\t}\n\t\t\t\t\tt.TraversePreOrder(n => n.Predecessors, loop.Add);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (loop != null)\n\t\t\t{\n\t\t\t\tvar headBlock = (Block)h.UserData;\n\t\t\t\tcontext.Step($\"Construct loop with head {headBlock.Label}\", headBlock);\n\t\t\t\t// loop now is the union of all natural loops with loop head h.\n\n\t\t\t\t// Ensure any block included into nested loops is also considered part of this loop:\n\t\t\t\tIncludeNestedContainers(loop);\n\t\t\t\t// Try to extend the loop to reduce the number of exit points:\n\t\t\t\tExtendLoop(h, loop, out var exitPoint);\n\n\t\t\t\t// Sort blocks in the loop in reverse post-order to make the output look a bit nicer.\n\t\t\t\t// (if the loop doesn't contain nested loops, this is a topological sort)\n\t\t\t\tloop.Sort((a, b) => b.PostOrderNumber.CompareTo(a.PostOrderNumber));\n\t\t\t\tDebug.Assert(loop[0] == h);\n\t\t\t\tforeach (var node in loop)\n\t\t\t\t{\n\t\t\t\t\tnode.Visited = false; // reset visited flag so that we can find outer loops\n\t\t\t\t\tDebug.Assert(h.Dominates(node), \"The loop body must be dominated by the loop head\");\n\t\t\t\t}\n\t\t\t\tConstructLoop(loop, exitPoint);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// For each block in the input loop that is the head of a nested loop or switch,\n\t\t/// include all blocks from the nested container into the loop.\n\t\t/// \n\t\t/// This ensures that all blocks that were included into inner loops are also\n\t\t/// included into the outer loop, thus keeping our loops well-nested.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// More details for why this is necessary are here:\n\t\t/// https://github.com/icsharpcode/ILSpy/issues/915\n\t\t/// \n\t\t/// Pre+Post-Condition: node.Visited iff loop.Contains(node)\n\t\t/// </remarks>\n\t\tvoid IncludeNestedContainers(List<ControlFlowNode> loop)\n\t\t{\n\t\t\tfor (int i = 0; i < loop.Count; i++)\n\t\t\t{\n\t\t\t\tIncludeBlock((Block)loop[i].UserData);\n\t\t\t}\n\n\t\t\tvoid IncludeBlock(Block block)\n\t\t\t{\n\t\t\t\tforeach (var nestedContainer in block.Instructions.OfType<BlockContainer>())\n\t\t\t\t{\n\t\t\t\t\t// Just in case the block has multiple nested containers (e.g. due to loop and switch),\n\t\t\t\t\t// also check the entry point:\n\t\t\t\t\tIncludeBlock(nestedContainer.EntryPoint);\n\t\t\t\t\t// Use normal processing for all non-entry-point blocks\n\t\t\t\t\t// (the entry-point itself doesn't have a CFG node, because it's newly created by this transform)\n\t\t\t\t\tfor (int i = 1; i < nestedContainer.Blocks.Count; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar node = context.ControlFlowGraph.GetNode(nestedContainer.Blocks[i]);\n\t\t\t\t\t\tDebug.Assert(loop[0].Dominates(node));\n\t\t\t\t\t\tif (!node.Visited)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnode.Visited = true;\n\t\t\t\t\t\t\tloop.Add(node);\n\t\t\t\t\t\t\t// note: this block will be re-visited when the \"i < loop.Count\"\n\t\t\t\t\t\t\t// gets around to the new entry\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t#region ExtendLoop\n\t\t/// <summary>\n\t\t/// Given a natural loop, add additional CFG nodes to the loop in order\n\t\t/// to reduce the number of exit points out of the loop.\n\t\t/// We do this because C# only allows reaching a single exit point (with 'break'\n\t\t/// statements or when the loop condition evaluates to false), so we'd have\n\t\t/// to introduce 'goto' statements for any additional exit points.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Definition:\n\t\t/// A \"reachable exit\" is a branch/leave target that is reachable from the loop,\n\t\t/// but not dominated by the loop head. A reachable exit may or may not have a\n\t\t/// corresponding CFG node (depending on whether it is a block in the current block container).\n\t\t///   -> reachable exits are leaving the code region dominated by the loop\n\t\t/// \n\t\t/// Definition:\n\t\t/// A loop \"exit point\" is a CFG node that is not itself part of the loop,\n\t\t/// but has at least one predecessor which is part of the loop.\n\t\t///   -> exit points are leaving the loop itself\n\t\t/// \n\t\t/// Nodes can only be added to the loop if they are dominated by the loop head.\n\t\t/// When adding a node to the loop, we must also add all of that node's predecessors\n\t\t/// to the loop. (this ensures that the loop keeps its single entry point)\n\t\t/// \n\t\t/// Goal: If possible, find a set of nodes that can be added to the loop so that there\n\t\t/// remains only a single exit point.\n\t\t/// Add as little code as possible to the loop to reach this goal.\n\t\t/// \n\t\t/// This means we need to partition the set of nodes dominated by the loop entry point\n\t\t/// into two sets (in-loop and out-of-loop).\n\t\t/// Constraints:\n\t\t///  * the loop head itself is in-loop\n\t\t///  * there must not be any edge from an out-of-loop node to an in-loop node\n\t\t///    -> all predecessors of in-loop nodes are also in-loop\n\t\t///    -> all nodes in a cycle are part of the same partition\n\t\t/// Optimize:\n\t\t///  * use only a single exit point if at all possible\n\t\t///  * minimize the amount of code in the in-loop partition\n\t\t///    (thus: maximize the amount of code in the out-of-loop partition)\n\t\t/// \n\t\t/// Observations:\n\t\t///  * If a node is in-loop, so are all its ancestors in the dominator tree (up to the loop entry point)\n\t\t///  * If there are no exits reachable from a node (i.e. all paths from that node lead to a return/throw instruction),\n\t\t///    it is valid to put the group of nodes dominated by that node into either partition independently of\n\t\t///    any other nodes except for the ancestors in the dominator tree.\n\t\t///       (exception: the loop head itself must always be in-loop)\n\t\t/// \n\t\t/// There are two different cases we need to consider:\n\t\t/// 1) There are no exits reachable at all from the loop head.\n\t\t///    ->  it is possible to create a loop with zero exit points by adding all nodes\n\t\t///        dominated by the loop to the loop.\n\t\t///    -> the only way to exit the loop is by \"return;\" or \"throw;\"\n\t\t/// 2) There are some exits reachable from the loop head.\n\t\t/// \n\t\t/// In case 1, we can pick a single exit point freely by picking any node that has no reachable exits\n\t\t/// (other than the loop head).\n\t\t/// All nodes dominated by the exit point are out-of-loop, all other nodes are in-loop.\n\t\t/// See PickExitPoint() for the heuristic that picks the exit point in this case.\n\t\t/// \n\t\t/// In case 2, we need to pick our exit point so that all paths from the loop head\n\t\t/// to the reachable exits run through that exit point.\n\t\t/// \n\t\t/// This is a form of postdominance where the reachable exits are considered exit nodes,\n\t\t/// while \"return;\" or \"throw;\" instructions are not considered exit nodes.\n\t\t/// \n\t\t/// Using this form of postdominance, we are looking for an exit point that post-dominates all nodes in the natural loop.\n\t\t/// --> a common ancestor in post-dominator tree.\n\t\t/// To minimize the amount of code in-loop, we pick the lowest common ancestor.\n\t\t/// All nodes dominated by the exit point are out-of-loop, all other nodes are in-loop.\n\t\t/// (using normal dominance as in case 1, not post-dominance!)\n\t\t/// \n\t\t/// If it is impossible to use a single exit point for the loop, the lowest common ancestor will be the fake \"exit node\"\n\t\t/// used by the post-dominance analysis. In this case, we fall back to the old heuristic algorithm.\n\t\t/// \n\t\t/// Requires and maintains the invariant that a node is marked as visited iff it is contained in the loop.\n\t\t/// </remarks>\n\t\tvoid ExtendLoop(ControlFlowNode loopHead, List<ControlFlowNode> loop, out ControlFlowNode exitPoint)\n\t\t{\n\t\t\texitPoint = FindExitPoint(loopHead, loop);\n\t\t\tDebug.Assert(!loop.Contains(exitPoint), \"Cannot pick an exit point that is part of the natural loop\");\n\t\t\tif (exitPoint != null)\n\t\t\t{\n\t\t\t\t// Either we are in case 1 and just picked an exit that maximizes the amount of code\n\t\t\t\t// outside the loop, or we are in case 2 and found an exit point via post-dominance.\n\t\t\t\t// Note that if exitPoint == NoExitPoint, we end up adding all dominated blocks to the loop.\n\t\t\t\tvar ep = exitPoint;\n\t\t\t\tforeach (var node in TreeTraversal.PreOrder(loopHead, n => DominatorTreeChildren(n, ep)))\n\t\t\t\t{\n\t\t\t\t\tif (!node.Visited)\n\t\t\t\t\t{\n\t\t\t\t\t\tnode.Visited = true;\n\t\t\t\t\t\tloop.Add(node);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// The loop/switch can only be entered through the entry point.\n\t\t\t\tif (isSwitch)\n\t\t\t\t{\n\t\t\t\t\t// In the case of a switch, false positives in the \"continue;\" detection logic\n\t\t\t\t\t// can lead to falsely excludes some blocks from the body.\n\t\t\t\t\t// Fix that by including all predecessors of included blocks.\n\t\t\t\t\tDebug.Assert(loop[0] == loopHead);\n\t\t\t\t\tfor (int i = 1; i < loop.Count; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var p in loop[i].Predecessors)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!p.Visited)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tp.Visited = true;\n\t\t\t\t\t\t\t\tloop.Add(p);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tDebug.Assert(loop.All(n => n == loopHead || n.Predecessors.All(p => p.Visited)));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// We are in case 2, but could not find a suitable exit point.\n\t\t\t\t// Heuristically try to minimize the number of exit points\n\t\t\t\t// (but we'll always end up with more than 1 exit and will require goto statements).\n\t\t\t\tExtendLoopHeuristic(loopHead, loop, loopHead);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Special control flow node (not part of any graph) that signifies that we want to construct a loop\n\t\t/// without any exit point.\n\t\t/// </summary>\n\t\tstatic readonly ControlFlowNode NoExitPoint = new ControlFlowNode();\n\n\t\t/// <summary>\n\t\t/// Finds a suitable single exit point for the specified loop.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// 1) If a suitable exit point was found: the control flow block that should be reached when breaking from the loop\n\t\t/// 2) If the loop should not have any exit point (extend by all dominated blocks): NoExitPoint\n\t\t/// 3) otherwise (exit point unknown, heuristically extend loop): null\n\t\t/// </returns>\n\t\t/// <remarks>This method must not write to the Visited flags on the CFG.</remarks>\n\t\tinternal ControlFlowNode FindExitPoint(ControlFlowNode loopHead, IReadOnlyList<ControlFlowNode> naturalLoop)\n\t\t{\n\t\t\tbool hasReachableExit = HasReachableExit(loopHead);\n\t\t\tif (!hasReachableExit)\n\t\t\t{\n\t\t\t\t// Case 1:\n\t\t\t\t// There are no nodes n so that loopHead dominates a predecessor of n but not n itself\n\t\t\t\t// -> we could build a loop with zero exit points.\n\t\t\t\tif (IsPossibleForeachLoop((Block)loopHead.UserData, out var exitBranch))\n\t\t\t\t{\n\t\t\t\t\tif (exitBranch != null)\n\t\t\t\t\t{\n\t\t\t\t\t\t// let's see if the target of the exit branch is a suitable exit point\n\t\t\t\t\t\tvar cfgNode = loopHead.Successors.FirstOrDefault(n => n.UserData == exitBranch.TargetBlock);\n\t\t\t\t\t\tif (cfgNode != null && loopHead.Dominates(cfgNode) && !context.ControlFlowGraph.HasReachableExit(cfgNode))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn cfgNode;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn NoExitPoint;\n\t\t\t\t}\n\t\t\t\tControlFlowNode exitPoint = null;\n\t\t\t\tint exitPointILOffset = -1;\n\t\t\t\tConsiderReturnAsExitPoint((Block)loopHead.UserData, ref exitPoint, ref exitPointILOffset);\n\t\t\t\tforeach (var node in loopHead.DominatorTreeChildren)\n\t\t\t\t{\n\t\t\t\t\tPickExitPoint(node, ref exitPoint, ref exitPointILOffset);\n\t\t\t\t}\n\t\t\t\treturn exitPoint;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Case 2:\n\t\t\t\t// We need to pick our exit point so that all paths from the loop head\n\t\t\t\t// to the reachable exits run through that exit point.\n\t\t\t\tvar cfg = context.ControlFlowGraph.cfg;\n\t\t\t\tvar revCfg = PrepareReverseCFG(loopHead, out int exitNodeArity);\n\t\t\t\t//ControlFlowNode.ExportGraph(cfg).Show(\"cfg\");\n\t\t\t\t//ControlFlowNode.ExportGraph(revCfg).Show(\"rev\");\n\t\t\t\tControlFlowNode commonAncestor = revCfg[loopHead.UserIndex];\n\t\t\t\tDebug.Assert(commonAncestor.IsReachable);\n\t\t\t\tforeach (ControlFlowNode cfgNode in naturalLoop)\n\t\t\t\t{\n\t\t\t\t\tControlFlowNode revNode = revCfg[cfgNode.UserIndex];\n\t\t\t\t\tif (revNode.IsReachable)\n\t\t\t\t\t{\n\t\t\t\t\t\tcommonAncestor = Dominance.FindCommonDominator(commonAncestor, revNode);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// All paths from within the loop to a reachable exit run through 'commonAncestor'.\n\t\t\t\t// However, this doesn't mean that 'commonAncestor' is valid as an exit point.\n\t\t\t\t// We walk up the post-dominator tree until we've got a valid exit point:\n\t\t\t\tControlFlowNode exitPoint;\n\t\t\t\twhile (commonAncestor.UserIndex >= 0)\n\t\t\t\t{\n\t\t\t\t\texitPoint = cfg[commonAncestor.UserIndex];\n\t\t\t\t\tDebug.Assert(exitPoint.Visited == naturalLoop.Contains(exitPoint));\n\t\t\t\t\t// It's possible that 'commonAncestor' is itself part of the natural loop.\n\t\t\t\t\t// If so, it's not a valid exit point.\n\t\t\t\t\tif (!exitPoint.Visited && ValidateExitPoint(loopHead, exitPoint))\n\t\t\t\t\t{\n\t\t\t\t\t\t// we found an exit point\n\t\t\t\t\t\treturn exitPoint;\n\t\t\t\t\t}\n\t\t\t\t\tcommonAncestor = commonAncestor.ImmediateDominator;\n\t\t\t\t}\n\t\t\t\t// least common post-dominator is the artificial exit node\n\t\t\t\t// This means we're in one of two cases:\n\t\t\t\t// * The loop might have multiple exit points.\n\t\t\t\t//     -> we should return null\n\t\t\t\t// * The loop has a single exit point that wasn't considered during post-dominance analysis.\n\t\t\t\t//        (which means the single exit isn't dominated by the loop head)\n\t\t\t\t//     -> we should return NoExitPoint so that all code dominated by the loop head is included into the loop\n\t\t\t\tif (exitNodeArity > 1)\n\t\t\t\t\treturn null;\n\n\t\t\t\t// Exit node is on the very edge of the tree, and isn't important for determining inclusion\n\t\t\t\t// Still necessary for switch detection to insert correct leave statements\n\t\t\t\tif (exitNodeArity == 1 && isSwitch)\n\t\t\t\t\treturn loopContext.GetBreakTargets(loopHead).Distinct().Single();\n\n\t\t\t\t// If exitNodeArity == 0, we should maybe look test if our exits out of the block container are all compatible?\n\t\t\t\t// but I don't think it hurts to have a bit too much code inside the loop in this rare case.\n\t\t\t\treturn NoExitPoint;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Validates an exit point.\n\t\t/// \n\t\t/// An exit point is invalid iff there is a node reachable from the exit point that\n\t\t/// is dominated by the loop head, but not by the exit point.\n\t\t/// (i.e. this method returns false iff the exit point's dominance frontier contains\n\t\t/// a node dominated by the loop head. but we implement this the slow way because\n\t\t/// we don't have dominance frontiers precomputed)\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// We need this because it's possible that there's a return block (thus reverse-unreachable node ignored by post-dominance)\n\t\t/// that is reachable both directly from the loop, and from the exit point.\n\t\t/// </remarks>\n\t\tbool ValidateExitPoint(ControlFlowNode loopHead, ControlFlowNode exitPoint)\n\t\t{\n\t\t\tvar cfg = context.ControlFlowGraph;\n\t\t\treturn IsValid(exitPoint);\n\n\t\t\tbool IsValid(ControlFlowNode node)\n\t\t\t{\n\t\t\t\tif (!cfg.HasReachableExit(node))\n\t\t\t\t{\n\t\t\t\t\t// Optimization: if the dominance frontier is empty, we don't need\n\t\t\t\t\t// to check every node.\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tforeach (var succ in node.Successors)\n\t\t\t\t{\n\t\t\t\t\tif (loopHead != succ && loopHead.Dominates(succ) && !exitPoint.Dominates(succ))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tforeach (var child in node.DominatorTreeChildren)\n\t\t\t\t{\n\t\t\t\t\tif (!IsValid(child))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Extension of ControlFlowGraph.HasReachableExit\n\t\t/// Uses loopContext.GetBreakTargets().Any() when analyzing switches to avoid \n\t\t/// classifying continue blocks as reachable exits.\n\t\t/// </summary>\n\t\tbool HasReachableExit(ControlFlowNode node) => isSwitch\n\t\t\t? loopContext.GetBreakTargets(node).Any()\n\t\t\t: context.ControlFlowGraph.HasReachableExit(node);\n\n\t\t/// <summary>\n\t\t/// Returns the children in a loop dominator tree, with an optional exit point\n\t\t/// Avoids returning continue statements when analysing switches (because increment blocks can be dominated)\n\t\t/// </summary>\n\t\tIEnumerable<ControlFlowNode> DominatorTreeChildren(ControlFlowNode n, ControlFlowNode exitPoint) =>\n\t\t\tn.DominatorTreeChildren.Where(c => c != exitPoint && (!isSwitch || !loopContext.MatchContinue(c)));\n\n\t\t/// <summary>\n\t\t/// Pick exit point by picking any node that has no reachable exits.\n\t\t/// \n\t\t/// In the common case where the code was compiled with a compiler that emits IL code\n\t\t/// in source order (like the C# compiler), we can find the \"real\" exit point\n\t\t/// by simply picking the block with the highest IL offset.\n\t\t/// So let's do that instead of maximizing amount of code.\n\t\t/// </summary>\n\t\t/// <returns>Code amount in <paramref name=\"node\"/> and its dominated nodes.</returns>\n\t\t/// <remarks>This method must not write to the Visited flags on the CFG.</remarks>\n\t\tvoid PickExitPoint(ControlFlowNode node, ref ControlFlowNode exitPoint, ref int exitPointILOffset)\n\t\t{\n\t\t\tif (isSwitch && loopContext.MatchContinue(node))\n\t\t\t\treturn;\n\n\t\t\tBlock block = (Block)node.UserData;\n\t\t\tif (block.StartILOffset > exitPointILOffset\n\t\t\t\t&& !HasReachableExit(node)\n\t\t\t\t&& ((Block)node.UserData).Parent == currentBlockContainer)\n\t\t\t{\n\t\t\t\t// HasReachableExit(node) == false\n\t\t\t\t// -> there are no nodes n so that `node` dominates a predecessor of n but not n itself\n\t\t\t\t// -> there is no control flow out of `node` back into the loop, so it's usable as exit point\n\n\t\t\t\t// Additionally, we require that the block wasn't already moved into a nested loop,\n\t\t\t\t// since there's no way to jump into the middle of that loop when we need to exit.\n\t\t\t\t// NB: this is the only reason why we detect nested loops before outer loops:\n\t\t\t\t// If we detected the outer loop first, the outer loop might pick an exit point\n\t\t\t\t// that prevents us from finding a nice exit for the inner loops, causing\n\t\t\t\t// unnecessary gotos.\n\t\t\t\texitPoint = node;\n\t\t\t\texitPointILOffset = block.StartILOffset;\n\t\t\t\treturn; // don't visit children, they are likely to have even later IL offsets and we'd end up\n\t\t\t\t\t\t// moving almost all of the code into the loop.\n\t\t\t}\n\t\t\tConsiderReturnAsExitPoint(block, ref exitPoint, ref exitPointILOffset);\n\t\t\tforeach (var child in node.DominatorTreeChildren)\n\t\t\t{\n\t\t\t\tPickExitPoint(child, ref exitPoint, ref exitPointILOffset);\n\t\t\t}\n\t\t}\n\n\t\tprivate static void ConsiderReturnAsExitPoint(Block block, ref ControlFlowNode exitPoint, ref int exitPointILOffset)\n\t\t{\n\t\t\t// It's possible that the real exit point of the loop is a \"return;\" that has been combined (by ControlFlowSimplification)\n\t\t\t// with the condition block.\n\t\t\tif (!block.MatchIfAtEndOfBlock(out _, out var trueInst, out var falseInst))\n\t\t\t\treturn;\n\t\t\tif (trueInst.StartILOffset > exitPointILOffset && trueInst is Leave { IsLeavingFunction: true, Value: Nop _ })\n\t\t\t{\n\t\t\t\t// By using NoExitPoint, everything (including the \"return;\") becomes part of the loop body\n\t\t\t\t// Then DetectExitPoint will move the \"return;\" out of the loop body.\n\t\t\t\texitPoint = NoExitPoint;\n\t\t\t\texitPointILOffset = trueInst.StartILOffset;\n\t\t\t}\n\t\t\tif (falseInst.StartILOffset > exitPointILOffset && falseInst is Leave { IsLeavingFunction: true, Value: Nop _ })\n\t\t\t{\n\t\t\t\texitPoint = NoExitPoint;\n\t\t\t\texitPointILOffset = falseInst.StartILOffset;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Constructs a new control flow graph.\n\t\t/// Each node cfg[i] has a corresponding node rev[i].\n\t\t/// Edges are only created for nodes dominated by loopHead, and are in reverse from their direction\n\t\t/// in the primary CFG.\n\t\t/// An artificial exit node is used for edges that leave the set of nodes dominated by loopHead,\n\t\t/// or that leave the block Container.\n\t\t/// </summary>\n\t\t/// <param name=\"loopHead\">Entry point of the loop.</param>\n\t\t/// <param name=\"exitNodeArity\">out: The number of different CFG nodes.\n\t\t/// Possible values:\n\t\t///  0 = no CFG nodes used as exit nodes (although edges leaving the block container might still be exits);\n\t\t///  1 = a single CFG node (not dominated by loopHead) was used as an exit node;\n\t\t///  2 = more than one CFG node (not dominated by loopHead) was used as an exit node.\n\t\t/// </param>\n\t\t/// <returns></returns>\n\t\tControlFlowNode[] PrepareReverseCFG(ControlFlowNode loopHead, out int exitNodeArity)\n\t\t{\n\t\t\tControlFlowNode[] cfg = context.ControlFlowGraph.cfg;\n\t\t\tControlFlowNode[] rev = new ControlFlowNode[cfg.Length + 1];\n\t\t\tfor (int i = 0; i < cfg.Length; i++)\n\t\t\t{\n\t\t\t\trev[i] = new ControlFlowNode { UserIndex = i, UserData = cfg[i].UserData };\n\t\t\t}\n\t\t\tControlFlowNode nodeTreatedAsExitNode = null;\n\t\t\tbool multipleNodesTreatedAsExitNodes = false;\n\t\t\tControlFlowNode exitNode = new ControlFlowNode { UserIndex = -1 };\n\t\t\trev[cfg.Length] = exitNode;\n\t\t\tfor (int i = 0; i < cfg.Length; i++)\n\t\t\t{\n\t\t\t\tif (!loopHead.Dominates(cfg[i]) || isSwitch && cfg[i] != loopHead && loopContext.MatchContinue(cfg[i]))\n\t\t\t\t\tcontinue;\n\n\t\t\t\t// Add reverse edges for all edges in cfg\n\t\t\t\tforeach (var succ in cfg[i].Successors)\n\t\t\t\t{\n\t\t\t\t\t// edges to outer loops still count as exits (labelled continue not implemented)\n\t\t\t\t\tif (isSwitch && loopContext.MatchContinue(succ, 1))\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\tif (loopHead.Dominates(succ))\n\t\t\t\t\t{\n\t\t\t\t\t\trev[succ.UserIndex].AddEdgeTo(rev[i]);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif (nodeTreatedAsExitNode == null)\n\t\t\t\t\t\t\tnodeTreatedAsExitNode = succ;\n\t\t\t\t\t\tif (nodeTreatedAsExitNode != succ)\n\t\t\t\t\t\t\tmultipleNodesTreatedAsExitNodes = true;\n\t\t\t\t\t\texitNode.AddEdgeTo(rev[i]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (context.ControlFlowGraph.HasDirectExitOutOfContainer(cfg[i]))\n\t\t\t\t{\n\t\t\t\t\texitNode.AddEdgeTo(rev[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (multipleNodesTreatedAsExitNodes)\n\t\t\t\texitNodeArity = 2; // more than 1\n\t\t\telse if (nodeTreatedAsExitNode != null)\n\t\t\t\texitNodeArity = 1;\n\t\t\telse\n\t\t\t\texitNodeArity = 0;\n\t\t\tDominance.ComputeDominance(exitNode, context.CancellationToken);\n\t\t\treturn rev;\n\t\t}\n\n\t\tstatic bool IsPossibleForeachLoop(Block loopHead, out Branch exitBranch)\n\t\t{\n\t\t\texitBranch = null;\n\t\t\tvar container = (BlockContainer)loopHead.Parent;\n\t\t\tif (!(container.SlotInfo == TryInstruction.TryBlockSlot && container.Parent is TryFinally))\n\t\t\t\treturn false;\n\t\t\tif (loopHead.Instructions.Count != 2)\n\t\t\t\treturn false;\n\t\t\tif (!loopHead.Instructions[0].MatchIfInstruction(out var condition, out var trueInst))\n\t\t\t\treturn false;\n\t\t\tvar falseInst = loopHead.Instructions[1];\n\t\t\twhile (condition.MatchLogicNot(out var arg))\n\t\t\t{\n\t\t\t\tcondition = arg;\n\t\t\t\tExtensionMethods.Swap(ref trueInst, ref falseInst);\n\t\t\t}\n\t\t\tif (!(condition is CallInstruction call && call.Method.Name == \"MoveNext\"))\n\t\t\t\treturn false;\n\t\t\tif (!(call.Arguments.Count == 1 && call.Arguments[0].MatchLdLocRef(out var enumeratorVar)))\n\t\t\t\treturn false;\n\t\t\texitBranch = falseInst as Branch;\n\n\t\t\t// Check that loopHead is entry-point of try-block:\n\t\t\tBlock entryPoint = container.EntryPoint;\n\t\t\twhile (entryPoint.IncomingEdgeCount == 1 && entryPoint.Instructions.Count == 1 && entryPoint.Instructions[0].MatchBranch(out var targetBlock))\n\t\t\t{\n\t\t\t\t// skip blocks that only branch to another block\n\t\t\t\tentryPoint = targetBlock;\n\t\t\t}\n\t\t\treturn entryPoint == loopHead;\n\t\t}\n\t\t#endregion\n\n\t\t#region ExtendLoop (fall-back heuristic)\n\t\t/// <summary>\n\t\t/// This function implements a heuristic algorithm that tries to reduce the number of exit\n\t\t/// points. It is only used as fall-back when it is impossible to use a single exit point.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This heuristic loop extension algorithm traverses the loop head's dominator tree in pre-order.\n\t\t/// For each candidate node, we detect whether adding it to the loop reduces the number of exit points.\n\t\t/// If it does, the candidate is added to the loop.\n\t\t/// \n\t\t/// Adding a node to the loop has two effects on the the number of exit points:\n\t\t/// * exit points that were added to the loop are no longer exit points, thus reducing the total number of exit points\n\t\t/// * successors of the newly added nodes might be new, additional exit points\n\t\t/// \n\t\t/// Requires and maintains the invariant that a node is marked as visited iff it is contained in the loop.\n\t\t/// </remarks>\n\t\tvoid ExtendLoopHeuristic(ControlFlowNode loopHead, List<ControlFlowNode> loop, ControlFlowNode candidate)\n\t\t{\n\t\t\tDebug.Assert(candidate.Visited == loop.Contains(candidate));\n\t\t\tif (!candidate.Visited)\n\t\t\t{\n\t\t\t\t// This node not yet part of the loop, but might be added\n\t\t\t\tList<ControlFlowNode> additionalNodes = new List<ControlFlowNode>();\n\t\t\t\t// Find additionalNodes nodes and mark them as visited.\n\t\t\t\tcandidate.TraversePreOrder(n => n.Predecessors, additionalNodes.Add);\n\t\t\t\t// This means Visited now represents the candidate extended loop.\n\t\t\t\t// Determine new exit points that are reachable from the additional nodes\n\t\t\t\t// (note: some of these might have previously been exit points, too)\n\t\t\t\tvar newExitPoints = additionalNodes.SelectMany(n => n.Successors).Where(n => !n.Visited).ToHashSet();\n\t\t\t\t// Make visited represent the unextended loop, so that we can measure the exit points\n\t\t\t\t// in the old state.\n\t\t\t\tforeach (var node in additionalNodes)\n\t\t\t\t\tnode.Visited = false;\n\t\t\t\t// Measure number of added and removed exit points\n\t\t\t\tint removedExitPoints = additionalNodes.Count(IsExitPoint);\n\t\t\t\tint addedExitPoints = newExitPoints.Count(n => !IsExitPoint(n));\n\t\t\t\tif (removedExitPoints > addedExitPoints)\n\t\t\t\t{\n\t\t\t\t\t// We can reduce the number of exit points by adding the candidate node to the loop.\n\t\t\t\t\tcandidate.TraversePreOrder(n => n.Predecessors, loop.Add);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Pre-order traversal of dominator tree\n\t\t\tforeach (var node in candidate.DominatorTreeChildren)\n\t\t\t{\n\t\t\t\tExtendLoopHeuristic(loopHead, loop, node);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether 'node' is an exit point for the loop marked by the Visited flag.\n\t\t/// </summary>\n\t\tbool IsExitPoint(ControlFlowNode node)\n\t\t{\n\t\t\tif (node.Visited)\n\t\t\t\treturn false; // nodes in the loop are not exit points\n\t\t\tforeach (var pred in node.Predecessors)\n\t\t\t{\n\t\t\t\tif (pred.Visited)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\t#endregion\n\n\t\t/// <summary>\n\t\t/// Move the blocks associated with the loop into a new block container.\n\t\t/// </summary>\n\t\tvoid ConstructLoop(List<ControlFlowNode> loop, ControlFlowNode exitPoint)\n\t\t{\n\t\t\tBlock oldEntryPoint = (Block)loop[0].UserData;\n\t\t\tBlock exitTargetBlock = (Block)exitPoint?.UserData;\n\n\t\t\tBlockContainer loopContainer = new BlockContainer(ContainerKind.Loop);\n\t\t\tBlock newEntryPoint = new Block();\n\t\t\tloopContainer.Blocks.Add(newEntryPoint);\n\t\t\t// Move contents of oldEntryPoint to newEntryPoint\n\t\t\t// (we can't move the block itself because it might be the target of branch instructions outside the loop)\n\t\t\tnewEntryPoint.Instructions.ReplaceList(oldEntryPoint.Instructions);\n\t\t\tnewEntryPoint.AddILRange(oldEntryPoint);\n\t\t\toldEntryPoint.Instructions.ReplaceList(new[] { loopContainer });\n\t\t\tif (exitTargetBlock != null)\n\t\t\t\toldEntryPoint.Instructions.Add(new Branch(exitTargetBlock));\n\n\t\t\tloopContainer.AddILRange(newEntryPoint);\n\t\t\tMoveBlocksIntoContainer(loop, loopContainer);\n\n\t\t\t// Rewrite branches within the loop from oldEntryPoint to newEntryPoint:\n\t\t\tforeach (var branch in loopContainer.Descendants.OfType<Branch>())\n\t\t\t{\n\t\t\t\tif (branch.TargetBlock == oldEntryPoint)\n\t\t\t\t{\n\t\t\t\t\tbranch.TargetBlock = newEntryPoint;\n\t\t\t\t}\n\t\t\t\telse if (branch.TargetBlock == exitTargetBlock)\n\t\t\t\t{\n\t\t\t\t\tbranch.ReplaceWith(new Leave(loopContainer).WithILRange(branch));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate void MoveBlocksIntoContainer(List<ControlFlowNode> loop, BlockContainer loopContainer)\n\t\t{\n\t\t\t// Move other blocks into the loop body: they're all dominated by the loop header,\n\t\t\t// and thus cannot be the target of branch instructions outside the loop.\n\t\t\tfor (int i = 1; i < loop.Count; i++)\n\t\t\t{\n\t\t\t\tBlock block = (Block)loop[i].UserData;\n\t\t\t\t// some blocks might already be in use by nested loops that were detected earlier;\n\t\t\t\t// don't move those (they'll be implicitly moved when the block containing the\n\t\t\t\t// nested loop container is moved).\n\t\t\t\tif (block.Parent == currentBlockContainer)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(block.ChildIndex != 0);\n\t\t\t\t\tint oldChildIndex = block.ChildIndex;\n\t\t\t\t\tloopContainer.Blocks.Add(block);\n\t\t\t\t\tcurrentBlockContainer.Blocks.SwapRemoveAt(oldChildIndex);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (int i = 1; i < loop.Count; i++)\n\t\t\t{\n\t\t\t\t// Verify that we moved all loop blocks into the loop container.\n\t\t\t\t// If we wanted to move any blocks already in use by a nested loop,\n\t\t\t\t// this means we check that the whole nested loop got moved.\n\t\t\t\tBlock block = (Block)loop[i].UserData;\n\t\t\t\tDebug.Assert(block.IsDescendantOf(loopContainer));\n\t\t\t}\n\t\t}\n\n\t\tprivate void DetectSwitchBody(Block block, SwitchInstruction switchInst)\n\t\t{\n\t\t\tDebug.Assert(block.Instructions.Last() == switchInst);\n\t\t\tControlFlowNode h = context.ControlFlowNode; // CFG node for our switch head\n\t\t\tDebug.Assert(h.UserData == block);\n\t\t\tDebug.Assert(!TreeTraversal.PreOrder(h, n => n.DominatorTreeChildren).Any(n => n.Visited));\n\n\t\t\tisSwitch = true;\n\t\t\tloopContext = new SwitchDetection.LoopContext(context.ControlFlowGraph, h);\n\n\t\t\tvar nodesInSwitch = new List<ControlFlowNode>();\n\t\t\tnodesInSwitch.Add(h);\n\t\t\th.Visited = true;\n\t\t\tExtendLoop(h, nodesInSwitch, out var exitPoint);\n\t\t\tif (exitPoint != null && h.Dominates(exitPoint) && exitPoint.Predecessors.Count == 1 && !HasReachableExit(exitPoint))\n\t\t\t{\n\t\t\t\t// If the exit point is reachable from just one single \"break;\",\n\t\t\t\t// it's better to move the code into the switch.\n\t\t\t\t// (unlike loops which should not be nested unless necessary,\n\t\t\t\t//  nesting switches makes it clearer in which cases a piece of code is reachable)\n\t\t\t\tnodesInSwitch.AddRange(TreeTraversal.PreOrder(exitPoint, p => p.DominatorTreeChildren));\n\t\t\t\tforeach (var node in nodesInSwitch)\n\t\t\t\t{\n\t\t\t\t\tnode.Visited = true;\n\t\t\t\t}\n\t\t\t\texitPoint = null;\n\t\t\t}\n\n\t\t\tcontext.Step(\"Create BlockContainer for switch\", switchInst);\n\t\t\t// Sort blocks in the loop in reverse post-order to make the output look a bit nicer.\n\t\t\t// (if the loop doesn't contain nested loops, this is a topological sort)\n\t\t\tnodesInSwitch.Sort((a, b) => b.PostOrderNumber.CompareTo(a.PostOrderNumber));\n\t\t\tDebug.Assert(nodesInSwitch[0] == h);\n\t\t\tforeach (var node in nodesInSwitch)\n\t\t\t{\n\t\t\t\tnode.Visited = false; // reset visited flag so that we can find outer loops\n\t\t\t\tDebug.Assert(h.Dominates(node), \"The switch body must be dominated by the switch head\");\n\t\t\t}\n\n\t\t\tBlockContainer switchContainer = new BlockContainer(ContainerKind.Switch);\n\t\t\tBlock newEntryPoint = new Block();\n\t\t\tnewEntryPoint.AddILRange(switchInst);\n\t\t\tswitchContainer.Blocks.Add(newEntryPoint);\n\t\t\tnewEntryPoint.Instructions.Add(switchInst);\n\t\t\tblock.Instructions[block.Instructions.Count - 1] = switchContainer;\n\n\t\t\tBlock exitTargetBlock = (Block)exitPoint?.UserData;\n\t\t\tif (exitTargetBlock != null)\n\t\t\t{\n\t\t\t\tblock.Instructions.Add(new Branch(exitTargetBlock));\n\t\t\t}\n\n\t\t\tswitchContainer.AddILRange(newEntryPoint);\n\t\t\tMoveBlocksIntoContainer(nodesInSwitch, switchContainer);\n\n\t\t\t// Rewrite branches within the loop from oldEntryPoint to newEntryPoint:\n\t\t\tforeach (var branch in switchContainer.Descendants.OfType<Branch>())\n\t\t\t{\n\t\t\t\tif (branch.TargetBlock == exitTargetBlock)\n\t\t\t\t{\n\t\t\t\t\tbranch.ReplaceWith(new Leave(switchContainer).WithILRange(branch));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tisSwitch = false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ControlFlow/RemoveRedundantReturn.cs",
    "content": "// Copyright (c) Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.IL.Transforms;\n\nnamespace ICSharpCode.Decompiler.IL.ControlFlow\n{\n\t/// <summary>\n\t/// Similar to <see cref=\"DetectExitPoints\"/>, but acts only on <c>leave</c> instructions\n\t/// leaving the whole function (<c>return</c>/<c>yield break</c>) that can be made implicit\n\t/// without using goto.\n\t/// </summary>\n\tclass RemoveRedundantReturn : IILTransform\n\t{\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tforeach (var lambda in function.Descendants.OfType<ILFunction>())\n\t\t\t{\n\t\t\t\tif (lambda.Body is BlockContainer c && ((lambda.AsyncReturnType ?? lambda.ReturnType).Kind == TypeSystem.TypeKind.Void || lambda.IsIterator))\n\t\t\t\t{\n\t\t\t\t\tBlock lastBlock = c.Blocks.Last();\n\t\t\t\t\tif (lastBlock.Instructions.Last() is Leave { IsLeavingFunction: true })\n\t\t\t\t\t{\n\t\t\t\t\t\tConvertReturnToFallthrough(lastBlock.Instructions.SecondToLastOrDefault());\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif (ConvertReturnToFallthrough(lastBlock.Instructions.Last()))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlastBlock.Instructions.Add(new Leave(c));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate static bool ConvertReturnToFallthrough(ILInstruction? inst)\n\t\t{\n\t\t\tbool result = false;\n\t\t\tswitch (inst)\n\t\t\t{\n\t\t\t\tcase BlockContainer c when c.Kind == ContainerKind.Normal:\n\t\t\t\t\t// body of try block, or similar: recurse into last instruction in container\n\t\t\t\t\t// Note: no need to handle loops/switches here; those already were handled by DetectExitPoints\n\t\t\t\t\tBlock lastBlock = c.Blocks.Last();\n\t\t\t\t\tif (lastBlock.Instructions.Last() is Leave { IsLeavingFunction: true, Value: Nop } leave)\n\t\t\t\t\t{\n\t\t\t\t\t\tleave.TargetContainer = c;\n\t\t\t\t\t\tresult = true;\n\t\t\t\t\t}\n\t\t\t\t\telse if (ConvertReturnToFallthrough(lastBlock.Instructions.Last()))\n\t\t\t\t\t{\n\t\t\t\t\t\tlastBlock.Instructions.Add(new Leave(c));\n\t\t\t\t\t\tresult = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase TryCatch tryCatch:\n\t\t\t\t\tresult |= ConvertReturnToFallthrough(tryCatch.TryBlock);\n\t\t\t\t\tforeach (var h in tryCatch.Handlers)\n\t\t\t\t\t{\n\t\t\t\t\t\tresult |= ConvertReturnToFallthrough(h.Body);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase TryFinally tryFinally:\n\t\t\t\t\tresult |= ConvertReturnToFallthrough(tryFinally.TryBlock);\n\t\t\t\t\tbreak;\n\t\t\t\tcase LockInstruction lockInst:\n\t\t\t\t\tresult |= ConvertReturnToFallthrough(lockInst.Body);\n\t\t\t\t\tbreak;\n\t\t\t\tcase UsingInstruction usingInst:\n\t\t\t\t\tresult |= ConvertReturnToFallthrough(usingInst.Body);\n\t\t\t\t\tbreak;\n\t\t\t\tcase PinnedRegion pinnedRegion:\n\t\t\t\t\tresult |= ConvertReturnToFallthrough(pinnedRegion.Body);\n\t\t\t\t\tbreak;\n\t\t\t\tcase IfInstruction ifInstruction:\n\t\t\t\t\tresult |= ConvertReturnToFallthrough(ifInstruction.TrueInst);\n\t\t\t\t\tresult |= ConvertReturnToFallthrough(ifInstruction.FalseInst);\n\t\t\t\t\tbreak;\n\t\t\t\tcase Block block when block.Kind == BlockKind.ControlFlow:\n\t\t\t\t{\n\t\t\t\t\tvar lastInst = block.Instructions.LastOrDefault();\n\t\t\t\t\tif (lastInst is Leave { IsLeavingFunction: true, Value: Nop })\n\t\t\t\t\t{\n\t\t\t\t\t\tblock.Instructions.RemoveAt(block.Instructions.Count - 1);\n\t\t\t\t\t\tresult = true;\n\t\t\t\t\t\tlastInst = block.Instructions.LastOrDefault();\n\t\t\t\t\t}\n\t\t\t\t\tresult |= ConvertReturnToFallthrough(lastInst);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ControlFlow/StateRangeAnalysis.cs",
    "content": "// Copyright (c) 2012 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.ControlFlow\n{\n\tenum StateRangeAnalysisMode\n\t{\n\t\tIteratorMoveNext,\n\t\tIteratorDispose,\n\t\tAsyncMoveNext,\n\t\tAwaitInFinally\n\t}\n\n\t/// <summary>\n\t/// Symbolically executes code to determine which blocks are reachable for which values\n\t/// of the 'state' field.\n\t/// </summary>\n\t/// <remarks>\n\t/// Assumption: there are no loops/backward jumps\n\t/// We 'run' the code, with \"state\" being a symbolic variable\n\t/// so it can form expressions like \"state + x\" (when there's a sub instruction)\n\t/// \n\t/// For each block, we maintain the set of values for state for which the block is reachable.\n\t/// This is (int.MinValue, int.MaxValue) for the first instruction.\n\t/// These ranges are propagated depending on the conditional jumps performed by the code.\n\t/// </remarks>\n\tclass StateRangeAnalysis\n\t{\n\t\tpublic CancellationToken CancellationToken;\n\t\treadonly StateRangeAnalysisMode mode;\n\t\treadonly IField? stateField;\n\t\treadonly bool legacyVisualBasic;\n\t\treadonly SymbolicEvaluationContext evalContext;\n\n\t\treadonly Dictionary<Block, LongSet> ranges = new Dictionary<Block, LongSet>();\n\t\treadonly Dictionary<BlockContainer, LongSet>? rangesForLeave; // used only for AwaitInFinally\n\t\treadonly internal Dictionary<IMethod, LongSet>? finallyMethodToStateRange; // used only for IteratorDispose\n\n\t\tinternal ILVariable? doFinallyBodies;\n\t\tinternal ILVariable? skipFinallyBodies;\n\n\t\tpublic StateRangeAnalysis(StateRangeAnalysisMode mode, IField? stateField, ILVariable? cachedStateVar = null, bool legacyVisualBasic = false)\n\t\t{\n\t\t\tthis.mode = mode;\n\t\t\tthis.stateField = stateField;\n\t\t\tthis.legacyVisualBasic = legacyVisualBasic;\n\t\t\tif (mode == StateRangeAnalysisMode.IteratorDispose)\n\t\t\t{\n\t\t\t\tfinallyMethodToStateRange = new Dictionary<IMethod, LongSet>();\n\t\t\t}\n\t\t\tif (mode == StateRangeAnalysisMode.AwaitInFinally)\n\t\t\t{\n\t\t\t\trangesForLeave = new Dictionary<BlockContainer, LongSet>();\n\t\t\t}\n\n\t\t\tevalContext = new SymbolicEvaluationContext(stateField, legacyVisualBasic);\n\t\t\tif (cachedStateVar != null)\n\t\t\t\tevalContext.AddStateVariable(cachedStateVar);\n\t\t}\n\n\t\tpublic IEnumerable<ILVariable> CachedStateVars { get => evalContext.StateVariables; }\n\n\t\t/// <summary>\n\t\t/// Creates a new StateRangeAnalysis with the same settings, including any cached state vars\n\t\t/// discovered by this analysis.\n\t\t/// However, the new analysis has a fresh set of result ranges.\n\t\t/// </summary>\n\t\tinternal StateRangeAnalysis CreateNestedAnalysis()\n\t\t{\n\t\t\tvar sra = new StateRangeAnalysis(mode, stateField, legacyVisualBasic: legacyVisualBasic);\n\t\t\tsra.doFinallyBodies = this.doFinallyBodies;\n\t\t\tsra.skipFinallyBodies = this.skipFinallyBodies;\n\t\t\tforeach (var v in this.evalContext.StateVariables)\n\t\t\t{\n\t\t\t\tsra.evalContext.AddStateVariable(v);\n\t\t\t}\n\t\t\treturn sra;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Assign state ranges for all blocks within 'inst'.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// The set of states for which the exit point of the instruction is reached.\n\t\t/// This must be a subset of the input set.\n\t\t/// \n\t\t/// Returns an empty set for unsupported instructions.\n\t\t/// </returns>\n\t\tpublic LongSet AssignStateRanges(ILInstruction inst, LongSet stateRange)\n\t\t{\n\t\t\tCancellationToken.ThrowIfCancellationRequested();\n\t\t\tswitch (inst)\n\t\t\t{\n\t\t\t\tcase BlockContainer blockContainer:\n\t\t\t\t\tAddStateRange(blockContainer.EntryPoint, stateRange);\n\t\t\t\t\tforeach (var block in blockContainer.Blocks)\n\t\t\t\t\t{\n\t\t\t\t\t\t// We assume that there are no jumps to blocks already processed.\n\t\t\t\t\t\t// TODO: is SortBlocks() guaranteeing this, even if the user code has loops?\n\t\t\t\t\t\tif (ranges.TryGetValue(block, out stateRange))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAssignStateRanges(block, stateRange);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// Since we don't track 'leave' edges, we can only conservatively\n\t\t\t\t\t// return LongSet.Empty.\n\t\t\t\t\treturn LongSet.Empty;\n\t\t\t\tcase Block block:\n\t\t\t\t\tforeach (var instInBlock in block.Instructions)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (stateRange.IsEmpty)\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tvar oldStateRange = stateRange;\n\t\t\t\t\t\tstateRange = AssignStateRanges(instInBlock, stateRange);\n\t\t\t\t\t\t// End-point can only be reachable in a subset of the states where the start-point is reachable.\n\t\t\t\t\t\tDebug.Assert(stateRange.IsSubsetOf(oldStateRange));\n\t\t\t\t\t\t// If the end-point is unreachable, it must be reachable in no states.\n\t\t\t\t\t\tDebug.Assert(stateRange.IsEmpty || !instInBlock.HasFlag(InstructionFlags.EndPointUnreachable));\n\t\t\t\t\t}\n\t\t\t\t\treturn stateRange;\n\t\t\t\tcase TryFinally tryFinally when mode == StateRangeAnalysisMode.IteratorDispose:\n\t\t\t\t\tvar afterTry = AssignStateRanges(tryFinally.TryBlock, stateRange);\n\t\t\t\t\t// really finally should start with 'stateRange.UnionWith(afterTry)', but that's\n\t\t\t\t\t// equal to 'stateRange'.\n\t\t\t\t\tDebug.Assert(afterTry.IsSubsetOf(stateRange));\n\t\t\t\t\tvar afterFinally = AssignStateRanges(tryFinally.FinallyBlock, stateRange);\n\t\t\t\t\treturn afterTry.IntersectWith(afterFinally);\n\t\t\t\tcase SwitchInstruction switchInst:\n\t\t\t\t\tSymbolicValue val = evalContext.Eval(switchInst.Value);\n\t\t\t\t\tif (val.Type != SymbolicValueType.State)\n\t\t\t\t\t\tgoto default;\n\t\t\t\t\tList<LongInterval> exitIntervals = new List<LongInterval>();\n\t\t\t\t\tforeach (var section in switchInst.Sections)\n\t\t\t\t\t{\n\t\t\t\t\t\t// switch (state + Constant)\n\t\t\t\t\t\t// matches 'case VALUE:'\n\t\t\t\t\t\t// iff (state + Constant == value)\n\t\t\t\t\t\t// iff (state == value - Constant)\n\t\t\t\t\t\tvar effectiveLabels = section.Labels.AddOffset(unchecked(-val.Constant));\n\t\t\t\t\t\tvar result = AssignStateRanges(section.Body, stateRange.IntersectWith(effectiveLabels));\n\t\t\t\t\t\texitIntervals.AddRange(result.Intervals);\n\t\t\t\t\t}\n\t\t\t\t\t// exitIntervals = union of exits of all sections\n\t\t\t\t\treturn new LongSet(exitIntervals);\n\t\t\t\tcase IfInstruction ifInst:\n\t\t\t\t\tval = evalContext.Eval(ifInst.Condition).AsBool();\n\t\t\t\t\tif (val.Type != SymbolicValueType.StateInSet)\n\t\t\t\t\t{\n\t\t\t\t\t\tgoto default;\n\t\t\t\t\t}\n\t\t\t\t\tLongSet trueRanges = val.ValueSet;\n\t\t\t\t\tvar afterTrue = AssignStateRanges(ifInst.TrueInst, stateRange.IntersectWith(trueRanges));\n\t\t\t\t\tvar afterFalse = AssignStateRanges(ifInst.FalseInst, stateRange.ExceptWith(trueRanges));\n\t\t\t\t\treturn afterTrue.UnionWith(afterFalse);\n\t\t\t\tcase Branch br:\n\t\t\t\t\tAddStateRange(br.TargetBlock, stateRange);\n\t\t\t\t\treturn LongSet.Empty;\n\t\t\t\tcase Leave leave when mode == StateRangeAnalysisMode.AwaitInFinally:\n\t\t\t\t\tAddStateRangeForLeave(leave.TargetContainer, stateRange);\n\t\t\t\t\treturn LongSet.Empty;\n\t\t\t\tcase Nop nop:\n\t\t\t\t\treturn stateRange;\n\t\t\t\tcase StLoc stloc when stloc.Variable == doFinallyBodies || stloc.Variable == skipFinallyBodies:\n\t\t\t\t\t// pre-roslyn async/await uses a generated 'bool doFinallyBodies';\n\t\t\t\t\t// do not treat this as user code.\n\t\t\t\t\t// Mono also does this for yield-return.\n\t\t\t\t\treturn stateRange;\n\t\t\t\tcase StLoc stloc:\n\t\t\t\t\tval = evalContext.Eval(stloc.Value);\n\t\t\t\t\tif (val.Type == SymbolicValueType.State && val.Constant == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tevalContext.AddStateVariable(stloc.Variable);\n\t\t\t\t\t\treturn stateRange;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tgoto default; // user code\n\t\t\t\t\t}\n\t\t\t\tcase Call call when mode == StateRangeAnalysisMode.IteratorDispose:\n\t\t\t\t\t// Call to finally method.\n\t\t\t\t\t// Usually these are in finally blocks, but sometimes (e.g. foreach over array),\n\t\t\t\t\t// the C# compiler puts the call to a finally method outside the try-finally block.\n\t\t\t\t\tfinallyMethodToStateRange!.Add((IMethod)call.Method.MemberDefinition, stateRange);\n\t\t\t\t\treturn LongSet.Empty; // return Empty since we executed user code (the finally method)\n\t\t\t\tcase StObj stobj when mode == StateRangeAnalysisMode.IteratorMoveNext:\n\t\t\t\t{\n\t\t\t\t\tif (stobj.MatchStFld(out var target, out var field, out var value)\n\t\t\t\t\t\t&& target.MatchLdThis() && field.MemberDefinition == stateField && value.MatchLdcI4(-1))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Mono resets the state field during MoveNext();\n\t\t\t\t\t\t// don't consider this user code.\n\t\t\t\t\t\treturn stateRange;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tgoto default;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcase StObj stobj when mode == StateRangeAnalysisMode.IteratorDispose:\n\t\t\t\t{\n\t\t\t\t\tif (stobj.MatchStFld(out var target, out var field, out var value) && target.MatchLdThis())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (field.MemberDefinition == stateField && value.MatchLdcI4(-2))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Roslyn 4.13 sets the state field in Dispose() to mark the iterator as disposed,\n\t\t\t\t\t\t\t// don't consider this user code.\n\t\t\t\t\t\t\treturn stateRange;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (value.MatchDefaultOrNullOrZero())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Roslyn 4.13 clears any local hoisted local variables in Dispose(),\n\t\t\t\t\t\t\t// don't consider this user code.\n\t\t\t\t\t\t\treturn stateRange;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tgoto default;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tgoto default;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\t// User code - abort analysis\n\t\t\t\t\tif (mode == StateRangeAnalysisMode.IteratorDispose && !(inst is Leave l && l.IsLeavingFunction))\n\t\t\t\t\t{\n\t\t\t\t\t\tthrow new SymbolicAnalysisFailedException(\"Unexpected instruction in Iterator.Dispose()\");\n\t\t\t\t\t}\n\t\t\t\t\treturn LongSet.Empty;\n\t\t\t}\n\t\t}\n\n\t\tprivate void AddStateRange(Block block, LongSet stateRange)\n\t\t{\n\t\t\tif (ranges.TryGetValue(block, out var existingRange))\n\t\t\t\tranges[block] = stateRange.UnionWith(existingRange);\n\t\t\telse\n\t\t\t\tranges.Add(block, stateRange);\n\t\t}\n\n\t\tprivate void AddStateRangeForLeave(BlockContainer target, LongSet stateRange)\n\t\t{\n\t\t\tif (rangesForLeave!.TryGetValue(target, out var existingRange))\n\t\t\t\trangesForLeave[target] = stateRange.UnionWith(existingRange);\n\t\t\telse\n\t\t\t\trangesForLeave.Add(target, stateRange);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a mapping from states to blocks.\n\t\t/// \n\t\t/// Within the given container (which should be the container that was analyzed),\n\t\t/// the mapping prefers the last block.\n\t\t/// Blocks outside of the given container are preferred over blocks within the container.\n\t\t/// </summary>\n\t\tpublic LongDict<Block> GetBlockStateSetMapping(BlockContainer container)\n\t\t{\n\t\t\treturn LongDict.Create(GetMapping());\n\n\t\t\tIEnumerable<(LongSet, Block)> GetMapping()\n\t\t\t{\n\t\t\t\t// First, consider container exits:\n\t\t\t\tforeach (var (block, states) in ranges)\n\t\t\t\t{\n\t\t\t\t\tif (block.Parent != container)\n\t\t\t\t\t\tyield return (states, block);\n\t\t\t\t}\n\t\t\t\t// Then blocks within the container:\n\t\t\t\tforeach (var block in container.Blocks.Reverse())\n\t\t\t\t{\n\t\t\t\t\tif (ranges.TryGetValue(block, out var states))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return (states, block);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic LongDict<BlockContainer> GetBlockStateSetMappingForLeave()\n\t\t{\n\t\t\tDebug.Assert(mode == StateRangeAnalysisMode.AwaitInFinally);\n\t\t\treturn LongDict.Create(rangesForLeave!.Select(kv => (kv.Value, kv.Key)));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ControlFlow/SwitchAnalysis.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.ControlFlow\n{\n\t/// <summary>\n\t/// C# switch statements are not necessarily compiled into IL switch instructions.\n\t/// For example, when the label values are not contiguous, the C# compiler\n\t/// will generate if statements similar to a binary search.\n\t/// \n\t/// This class analyses such sequences of if statements to reconstruct the original switch.\n\t/// </summary>\n\t/// <remarks>\n\t/// This analysis expects to be run on basic blocks (not extended basic blocks).\n\t/// </remarks>\n\tclass SwitchAnalysis\n\t{\n\t\t/// <summary>\n\t\t/// The variable that is used to represent the switch expression.\n\t\t/// <c>null</c> while analyzing the first block.\n\t\t/// </summary>\n\t\tILVariable switchVar;\n\n\t\t/// <summary>\n\t\t/// The variable to be used as the argument of the switch instruction.\n\t\t/// </summary>\n\t\tpublic ILVariable SwitchVariable => switchVar;\n\n\t\t/// <summary>\n\t\t/// Whether at least one of the analyzed blocks contained an IL switch constructors.\n\t\t/// </summary>\n\t\tpublic bool ContainsILSwitch { get; private set; }\n\n\t\t/// <summary>\n\t\t/// Gets the sections that were detected by the previous AnalyzeBlock() call.\n\t\t/// </summary>\n\t\tpublic readonly List<KeyValuePair<LongSet, ILInstruction>> Sections = new List<KeyValuePair<LongSet, ILInstruction>>();\n\n\t\t/// <summary>\n\t\t/// Used to de-duplicate sections with a branch instruction.\n\t\t/// Invariant: (Sections[targetBlockToSectionIndex[branch.TargetBlock]].Instruction as Branch).TargetBlock == branch.TargetBlock\n\t\t/// </summary>\n\t\treadonly Dictionary<Block, int> targetBlockToSectionIndex = new Dictionary<Block, int>();\n\n\t\t/// <summary>\n\t\t/// Used to de-duplicate sections with a value-less leave instruction.\n\t\t/// Invariant: (Sections[targetBlockToSectionIndex[leave.TargetContainer]].Instruction as Leave).TargetContainer == leave.TargetContainer\n\t\t/// </summary>\n\t\treadonly Dictionary<BlockContainer, int> targetContainerToSectionIndex = new Dictionary<BlockContainer, int>();\n\n\t\t/// <summary>\n\t\t/// Blocks that can be deleted if the tail of the initial block is replaced with a switch instruction.\n\t\t/// </summary>\n\t\tpublic readonly List<Block> InnerBlocks = new List<Block>();\n\n\t\tpublic Block RootBlock { get; private set; }\n\n\t\t/// <summary>\n\t\t/// Gets/sets whether to allow unreachable cases in switch instructions.\n\t\t/// </summary>\n\t\tpublic bool AllowUnreachableCases { get; set; }\n\n\t\t/// <summary>\n\t\t/// Analyze the last two statements in the block and see if they can be turned into a\n\t\t/// switch instruction.\n\t\t/// </summary>\n\t\t/// <returns>true if the block could be analyzed successfully; false otherwise</returns>\n\t\tpublic bool AnalyzeBlock(Block block)\n\t\t{\n\t\t\tswitchVar = null;\n\t\t\tRootBlock = block;\n\t\t\ttargetBlockToSectionIndex.Clear();\n\t\t\ttargetContainerToSectionIndex.Clear();\n\t\t\tSections.Clear();\n\t\t\tInnerBlocks.Clear();\n\t\t\tContainsILSwitch = false;\n\t\t\treturn AnalyzeBlock(block, LongSet.Universe, tailOnly: true);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Analyzes the tail end (last two instructions) of a block.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Sets <c>switchVar</c> and <c>defaultInstruction</c> if they are null,\n\t\t/// and adds found sections to <c>sectionLabels</c> and <c>sectionInstructions</c>.\n\t\t/// \n\t\t/// If the function returns false, <c>sectionLabels</c> and <c>sectionInstructions</c> are unmodified.\n\t\t/// </remarks>\n\t\t/// <param name=\"block\">The block to analyze.</param>\n\t\t/// <param name=\"inputValues\">The possible values of the \"interesting\" variable\n\t\t/// when control flow reaches this block.</param>\n\t\t/// <param name=\"tailOnly\">If true, analyze only the tail (last two instructions).\n\t\t/// If false, analyze the whole block.</param>\n\t\tbool AnalyzeBlock(Block block, LongSet inputValues, bool tailOnly = false)\n\t\t{\n\t\t\tif (block.Instructions.Count == 0)\n\t\t\t{\n\t\t\t\t// might happen if the block was already marked for deletion in SwitchDetection\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (tailOnly)\n\t\t\t{\n\t\t\t\tDebug.Assert(block == RootBlock);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDebug.Assert(switchVar != null); // switchVar should always be determined by the top-level call\n\t\t\t\tif (block.IncomingEdgeCount != 1 || block == RootBlock)\n\t\t\t\t\treturn false; // for now, let's only consider if-structures that form a tree\n\t\t\t\tif (block.Parent != RootBlock.Parent)\n\t\t\t\t\treturn false; // all blocks should belong to the same container\n\t\t\t}\n\t\t\tLongSet trueValues;\n\t\t\tif (block.Instructions.Count >= 2\n\t\t\t\t&& block.Instructions[block.Instructions.Count - 2].MatchIfInstruction(out var condition, out var trueInst)\n\t\t\t\t&& AnalyzeCondition(condition, out trueValues)\n\t\t\t)\n\t\t\t{\n\t\t\t\tif (!(tailOnly || block.Instructions.Count == 2))\n\t\t\t\t\treturn false;\n\t\t\t\ttrueValues = trueValues.IntersectWith(inputValues);\n\t\t\t\tif (trueValues.SetEquals(inputValues) || trueValues.IsEmpty)\n\t\t\t\t\treturn false;\n\t\t\t\tBlock trueBlock;\n\t\t\t\tif (trueInst.MatchBranch(out trueBlock) && AnalyzeBlock(trueBlock, trueValues))\n\t\t\t\t{\n\t\t\t\t\t// OK, true block was further analyzed.\n\t\t\t\t\tInnerBlocks.Add(trueBlock);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Create switch section for trueInst.\n\t\t\t\t\tAddSection(trueValues, trueInst);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (block.Instructions.Last() is SwitchInstruction switchInst)\n\t\t\t{\n\t\t\t\tif (!(tailOnly || block.Instructions.Count == 1))\n\t\t\t\t\treturn false;\n\t\t\t\tif (AnalyzeSwitch(switchInst, inputValues))\n\t\t\t\t{\n\t\t\t\t\tContainsILSwitch = true; // OK\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{ // switch analysis failed (e.g. switchVar mismatch)\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{ // unknown inst\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar remainingValues = inputValues.ExceptWith(trueValues);\n\t\t\tILInstruction falseInst = block.Instructions.Last();\n\t\t\tBlock falseBlock;\n\t\t\tif (falseInst.MatchBranch(out falseBlock) && AnalyzeBlock(falseBlock, remainingValues))\n\t\t\t{\n\t\t\t\t// OK, false block was further analyzed.\n\t\t\t\tInnerBlocks.Add(falseBlock);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Create switch section for falseInst.\n\t\t\t\tAddSection(remainingValues, falseInst);\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tprivate bool AnalyzeSwitch(SwitchInstruction inst, LongSet inputValues)\n\t\t{\n\t\t\tDebug.Assert(!inst.IsLifted);\n\t\t\tlong offset;\n\t\t\tif (MatchSwitchVar(inst.Value))\n\t\t\t{\n\t\t\t\toffset = 0;\n\t\t\t}\n\t\t\telse if (inst.Value is BinaryNumericInstruction bop)\n\t\t\t{\n\t\t\t\tif (bop.CheckForOverflow)\n\t\t\t\t\treturn false;\n\t\t\t\tif (MatchSwitchVar(bop.Left) && bop.Right.MatchLdcI(out long val))\n\t\t\t\t{\n\t\t\t\t\tswitch (bop.Operator)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase BinaryNumericOperator.Add:\n\t\t\t\t\t\t\toffset = unchecked(-val);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase BinaryNumericOperator.Sub:\n\t\t\t\t\t\t\toffset = val;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault: // unknown bop.Operator\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{ // unknown bop.Left\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{ // unknown inst.Value\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tforeach (var section in inst.Sections)\n\t\t\t{\n\t\t\t\tvar matchValues = section.Labels.AddOffset(offset).IntersectWith(inputValues);\n\t\t\t\tif (!AllowUnreachableCases && matchValues.IsEmpty)\n\t\t\t\t\treturn false;\n\t\t\t\tif (matchValues.Count() > 1 && section.Body.MatchBranch(out var targetBlock) && AnalyzeBlock(targetBlock, matchValues))\n\t\t\t\t{\n\t\t\t\t\tInnerBlocks.Add(targetBlock);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tAddSection(matchValues, section.Body);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Adds a new section to the Sections list.\n\t\t/// \n\t\t/// If the instruction is a branch instruction, unify the new section with an existing section\n\t\t/// that also branches to the same target.\n\t\t/// </summary>\n\t\tvoid AddSection(LongSet values, ILInstruction inst)\n\t\t{\n\t\t\tif (values.IsEmpty)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (inst.MatchBranch(out Block targetBlock))\n\t\t\t{\n\t\t\t\tif (targetBlockToSectionIndex.TryGetValue(targetBlock, out int index))\n\t\t\t\t{\n\t\t\t\t\tSections[index] = new KeyValuePair<LongSet, ILInstruction>(\n\t\t\t\t\t\tSections[index].Key.UnionWith(values),\n\t\t\t\t\t\tinst\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ttargetBlockToSectionIndex.Add(targetBlock, Sections.Count);\n\t\t\t\t\tSections.Add(new KeyValuePair<LongSet, ILInstruction>(values, inst));\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (inst.MatchLeave(out BlockContainer targetContainer))\n\t\t\t{\n\t\t\t\tif (targetContainerToSectionIndex.TryGetValue(targetContainer, out int index))\n\t\t\t\t{\n\t\t\t\t\tSections[index] = new KeyValuePair<LongSet, ILInstruction>(\n\t\t\t\t\t\tSections[index].Key.UnionWith(values),\n\t\t\t\t\t\tinst\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ttargetContainerToSectionIndex.Add(targetContainer, Sections.Count);\n\t\t\t\t\tSections.Add(new KeyValuePair<LongSet, ILInstruction>(values, inst));\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tSections.Add(new KeyValuePair<LongSet, ILInstruction>(values, inst));\n\t\t\t}\n\t\t}\n\n\t\tbool MatchSwitchVar(ILInstruction inst)\n\t\t{\n\t\t\tif (switchVar != null)\n\t\t\t\treturn inst.MatchLdLoc(switchVar);\n\t\t\telse\n\t\t\t\treturn inst.MatchLdLoc(out switchVar);\n\t\t}\n\n\t\tbool MatchSwitchVar(ILInstruction inst, out long sub)\n\t\t{\n\t\t\tif (inst is BinaryNumericInstruction bn\n\t\t\t\t&& bn.Operator == BinaryNumericOperator.Sub\n\t\t\t\t&& !bn.CheckForOverflow && !bn.IsLifted\n\t\t\t\t&& bn.Right.MatchLdcI(out sub))\n\t\t\t{\n\t\t\t\treturn MatchSwitchVar(bn.Left);\n\t\t\t}\n\n\t\t\tsub = 0;\n\t\t\treturn MatchSwitchVar(inst);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Analyzes the boolean condition, returning the set of values of the interesting\n\t\t/// variable for which the condition evaluates to true.\n\t\t/// </summary>\n\t\tprivate bool AnalyzeCondition(ILInstruction condition, out LongSet trueValues)\n\t\t{\n\t\t\tif (condition is Comp comp && MatchSwitchVar(comp.Left, out var sub) && comp.Right.MatchLdcI(out long val))\n\t\t\t{\n\t\t\t\t// if (comp((V - sub) OP val))\n\t\t\t\ttrueValues = MakeSetWhereComparisonIsTrue(comp.Kind, val, comp.Sign);\n\t\t\t\ttrueValues = trueValues.AddOffset(sub);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (MatchSwitchVar(condition))\n\t\t\t{\n\t\t\t\t// if (ldloc V) --> branch for all values except 0\n\t\t\t\ttrueValues = new LongSet(0).Invert();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (condition.MatchLogicNot(out ILInstruction arg))\n\t\t\t{\n\t\t\t\t// if (logic.not(X)) --> branch for all values where if (X) does not branch\n\t\t\t\tbool res = AnalyzeCondition(arg, out LongSet falseValues);\n\t\t\t\ttrueValues = falseValues.Invert();\n\t\t\t\treturn res;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttrueValues = LongSet.Empty;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Create the LongSet that contains a value x iff x compared with value is true.\n\t\t/// </summary>\n\t\tinternal static LongSet MakeSetWhereComparisonIsTrue(ComparisonKind kind, long val, Sign sign)\n\t\t{\n\t\t\tswitch (kind)\n\t\t\t{\n\t\t\t\tcase ComparisonKind.Equality:\n\t\t\t\t\treturn new LongSet(val);\n\t\t\t\tcase ComparisonKind.Inequality:\n\t\t\t\t\treturn new LongSet(val).Invert();\n\t\t\t\tcase ComparisonKind.LessThan:\n\t\t\t\t\treturn MakeGreaterThanOrEqualSet(val, sign).Invert();\n\t\t\t\tcase ComparisonKind.LessThanOrEqual:\n\t\t\t\t\treturn MakeLessThanOrEqualSet(val, sign);\n\t\t\t\tcase ComparisonKind.GreaterThan:\n\t\t\t\t\treturn MakeLessThanOrEqualSet(val, sign).Invert();\n\t\t\t\tcase ComparisonKind.GreaterThanOrEqual:\n\t\t\t\t\treturn MakeGreaterThanOrEqualSet(val, sign);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentException(\"Invalid ComparisonKind\");\n\t\t\t}\n\t\t}\n\n\t\tprivate static LongSet MakeGreaterThanOrEqualSet(long val, Sign sign)\n\t\t{\n\t\t\tif (sign == Sign.Signed)\n\t\t\t{\n\t\t\t\treturn new LongSet(LongInterval.Inclusive(val, long.MaxValue));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDebug.Assert(sign == Sign.Unsigned);\n\t\t\t\tif (val >= 0)\n\t\t\t\t{\n\t\t\t\t\t// The range val to ulong.MaxValue expressed with signed longs\n\t\t\t\t\t// is not a single contiguous range, but two ranges:\n\t\t\t\t\treturn new LongSet(LongInterval.Inclusive(val, long.MaxValue))\n\t\t\t\t\t\t.UnionWith(new LongSet(new LongInterval(long.MinValue, 0)));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn new LongSet(new LongInterval(val, 0));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate static LongSet MakeLessThanOrEqualSet(long val, Sign sign)\n\t\t{\n\t\t\tif (sign == Sign.Signed)\n\t\t\t{\n\t\t\t\treturn new LongSet(LongInterval.Inclusive(long.MinValue, val));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDebug.Assert(sign == Sign.Unsigned);\n\t\t\t\tif (val >= 0)\n\t\t\t\t{\n\t\t\t\t\treturn new LongSet(LongInterval.Inclusive(0, val));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// The range 0 to (ulong)val expressed with signed longs\n\t\t\t\t\t// is not a single contiguous range, but two ranges:\n\t\t\t\t\treturn new LongSet(LongInterval.Inclusive(0, long.MaxValue))\n\t\t\t\t\t\t.UnionWith(new LongSet(LongInterval.Inclusive(long.MinValue, val)));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ControlFlow/SwitchDetection.cs",
    "content": "// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.FlowAnalysis;\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.ControlFlow\n{\n\t/// <summary>\n\t/// C# switch statements are not necessarily compiled into\n\t/// IL switch instructions (e.g. when the integer values are non-contiguous).\n\t/// \n\t/// Detect sequences of conditional branches that all test a single integer value,\n\t/// and simplify them into a ILAst switch instruction (which like C# does not require contiguous values).\n\t/// </summary>\n\tpublic class SwitchDetection : IILTransform\n\t{\n\t\tprivate readonly SwitchAnalysis analysis = new SwitchAnalysis();\n\n\t\tprivate ILTransformContext context;\n\t\tprivate BlockContainer currentContainer;\n\t\tprivate ControlFlowGraph controlFlowGraph;\n\t\tprivate LoopContext loopContext;\n\n\t\t/// <summary>\n\t\t/// When detecting a switch, it is important to distinguish Branch instructions which will\n\t\t/// eventually decompile to continue; statements. \n\t\t/// \n\t\t/// A LoopContext is constructed for a node and its dominator tree, as for a Branch to be a continue;\n\t\t/// statement, it must be contained within the target-loop\n\t\t/// \n\t\t/// This class also supplies the depth of the loop targetted by a continue; statement relative to the\n\t\t/// context node, to avoid (or eventually support) labelled continues to outer loops\n\t\t/// </summary>\n\t\tpublic class LoopContext\n\t\t{\n\t\t\tprivate readonly IDictionary<ControlFlowNode, int> continueDepth = new Dictionary<ControlFlowNode, int>();\n\n\t\t\tpublic LoopContext(ControlFlowGraph cfg, ControlFlowNode contextNode)\n\t\t\t{\n\t\t\t\tvar loopHeads = new List<ControlFlowNode>();\n\n\t\t\t\tvoid Analyze(ControlFlowNode n)\n\t\t\t\t{\n\t\t\t\t\tif (n.Visited)\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\tn.Visited = true;\n\t\t\t\t\tif (n.Dominates(contextNode))\n\t\t\t\t\t\tloopHeads.Add(n);\n\t\t\t\t\telse\n\t\t\t\t\t\tn.Successors.ForEach(Analyze);\n\t\t\t\t}\n\t\t\t\tcontextNode.Successors.ForEach(Analyze);\n\t\t\t\tResetVisited(cfg.cfg);\n\n\t\t\t\tint l = 1;\n\t\t\t\tforeach (var loopHead in loopHeads.OrderBy(n => n.PostOrderNumber))\n\t\t\t\t\tcontinueDepth[FindContinue(loopHead)] = l++;\n\t\t\t}\n\n\t\t\tprivate static ControlFlowNode FindContinue(ControlFlowNode loopHead)\n\t\t\t{\n\t\t\t\t// potential continue target\n\t\t\t\tvar pred = loopHead.Predecessors.OnlyOrDefault(p => p != loopHead && loopHead.Dominates(p));\n\t\t\t\tif (pred == null)\n\t\t\t\t\treturn loopHead;\n\n\t\t\t\t// match for loop increment block\n\t\t\t\tif (pred.Successors.Count == 1)\n\t\t\t\t{\n\t\t\t\t\tif (HighLevelLoopTransform.MatchIncrementBlock((Block)pred.UserData, out var target) && target == loopHead.UserData)\n\t\t\t\t\t\treturn pred;\n\t\t\t\t}\n\n\t\t\t\t// match do-while condition\n\t\t\t\tif (pred.Successors.Count <= 2)\n\t\t\t\t{\n\t\t\t\t\tif (HighLevelLoopTransform.MatchDoWhileConditionBlock((Block)pred.UserData, out var t1, out var t2) &&\n\t\t\t\t\t\t(t1 == loopHead.UserData || t2 == loopHead.UserData))\n\t\t\t\t\t\treturn pred;\n\t\t\t\t}\n\n\t\t\t\treturn loopHead;\n\t\t\t}\n\n\t\t\tpublic bool MatchContinue(ControlFlowNode node) => MatchContinue(node, out var _);\n\n\t\t\tpublic bool MatchContinue(ControlFlowNode node, int depth) =>\n\t\t\t\tMatchContinue(node, out int _depth) && depth == _depth;\n\n\t\t\tpublic bool MatchContinue(ControlFlowNode node, out int depth) => continueDepth.TryGetValue(node, out depth);\n\n\t\t\tpublic int GetContinueDepth(ControlFlowNode node) => MatchContinue(node, out var depth) ? depth : 0;\n\n\t\t\t/// <summary>\n\t\t\t/// Lists all potential targets for break; statements from a domination tree,\n\t\t\t/// assuming the domination tree must be exited via either break; or continue;\n\t\t\t/// \n\t\t\t/// First list all nodes in the dominator tree (excluding continue nodes)\n\t\t\t/// Then return the all successors not contained within said tree.\n\t\t\t/// \n\t\t\t/// Note that node will be returned once for each outgoing edge.\n\t\t\t/// Labelled continue statements (depth > 1) are counted as break targets\n\t\t\t/// </summary>\n\t\t\tinternal IEnumerable<ControlFlowNode> GetBreakTargets(ControlFlowNode dominator) =>\n\t\t\t\tTreeTraversal.PreOrder(dominator, n => n.DominatorTreeChildren.Where(c => !MatchContinue(c)))\n\t\t\t\t\t.SelectMany(n => n.Successors)\n\t\t\t\t\t.Where(n => !dominator.Dominates(n) && !MatchContinue(n, 1));\n\t\t}\n\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.SparseIntegerSwitch)\n\t\t\t\treturn;\n\t\t\tthis.context = context;\n\n\t\t\tanalysis.AllowUnreachableCases = context.Settings.RemoveDeadCode;\n\n\t\t\tforeach (var container in function.Descendants.OfType<BlockContainer>())\n\t\t\t{\n\t\t\t\tcurrentContainer = container;\n\t\t\t\tcontrolFlowGraph = null;\n\n\t\t\t\tbool blockContainerNeedsCleanup = false;\n\t\t\t\tforeach (var block in container.Blocks)\n\t\t\t\t{\n\t\t\t\t\tcontext.CancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tProcessBlock(block, ref blockContainerNeedsCleanup);\n\t\t\t\t}\n\t\t\t\tif (blockContainerNeedsCleanup)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(container.Blocks.All(b => b.Instructions.Count != 0 || b.IncomingEdgeCount == 0));\n\n\t\t\t\t\t// if the original code has an unreachable switch-like condition\n\t\t\t\t\t// eg. if (i >= 0) { ... } else if (i == 2) { unreachable }\n\t\t\t\t\t// then the 'i == 2' block head gets consumed and the unreachable code needs deleting\n\t\t\t\t\tif (context.Settings.RemoveDeadCode)\n\t\t\t\t\t\tcontainer.SortBlocks(deleteUnreachableBlocks: true);\n\t\t\t\t\telse\n\t\t\t\t\t\tcontainer.Blocks.RemoveAll(b => b.Instructions.Count == 0);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid ProcessBlock(Block block, ref bool blockContainerNeedsCleanup)\n\t\t{\n\t\t\tbool analysisSuccess = analysis.AnalyzeBlock(block);\n\t\t\tif (analysisSuccess && UseCSharpSwitch(out _))\n\t\t\t{\n\t\t\t\t// complex multi-block switch that can be combined into a single SwitchInstruction\n\t\t\t\tILInstruction switchValue = new LdLoc(analysis.SwitchVariable);\n\t\t\t\tDebug.Assert(switchValue.ResultType.IsIntegerType() || switchValue.ResultType == StackType.Unknown);\n\t\t\t\tif (!(switchValue.ResultType == StackType.I4 || switchValue.ResultType == StackType.I8))\n\t\t\t\t{\n\t\t\t\t\t// switchValue must have a result type of either I4 or I8\n\t\t\t\t\tswitchValue = new Conv(switchValue, PrimitiveType.I8, false, Sign.Signed);\n\t\t\t\t}\n\t\t\t\tvar sw = new SwitchInstruction(switchValue);\n\t\t\t\tforeach (var section in analysis.Sections)\n\t\t\t\t{\n\t\t\t\t\tsw.Sections.Add(new SwitchSection {\n\t\t\t\t\t\tLabels = section.Key,\n\t\t\t\t\t\tBody = section.Value\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (block.Instructions.Last() is SwitchInstruction)\n\t\t\t\t{\n\t\t\t\t\t// we'll replace the switch\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(block.Instructions.SecondToLastOrDefault() is IfInstruction);\n\t\t\t\t\t// Remove branch/leave after if; it's getting moved into a section.\n\t\t\t\t\tblock.Instructions.RemoveAt(block.Instructions.Count - 1);\n\t\t\t\t}\n\t\t\t\tsw.AddILRange(block.Instructions[block.Instructions.Count - 1]);\n\t\t\t\tblock.Instructions[block.Instructions.Count - 1] = sw;\n\n\t\t\t\t// mark all inner blocks that were converted to the switch statement for deletion\n\t\t\t\tforeach (var innerBlock in analysis.InnerBlocks)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(innerBlock.Parent == block.Parent);\n\t\t\t\t\tDebug.Assert(innerBlock != ((BlockContainer)block.Parent).EntryPoint);\n\t\t\t\t\tinnerBlock.Instructions.Clear();\n\t\t\t\t}\n\n\t\t\t\tcontrolFlowGraph = null; // control flow graph is no-longer valid\n\t\t\t\tblockContainerNeedsCleanup = true;\n\t\t\t\tSortSwitchSections(sw);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// 2nd pass of SimplifySwitchInstruction (after duplicating return blocks),\n\t\t\t\t// (1st pass was in ControlFlowSimplification)\n\t\t\t\tSimplifySwitchInstruction(block, context);\n\t\t\t}\n\t\t}\n\n\t\tinternal static void SimplifySwitchInstruction(Block block, ILTransformContext context)\n\t\t{\n\t\t\t// due to our of of basic blocks at this point,\n\t\t\t// switch instructions can only appear as last insturction\n\t\t\tvar sw = block.Instructions.LastOrDefault() as SwitchInstruction;\n\t\t\tif (sw == null)\n\t\t\t\treturn;\n\n\t\t\t// ControlFlowSimplification runs early (before any other control flow transforms).\n\t\t\t// Any switch instructions will only have branch instructions in the sections.\n\n\t\t\t// Combine sections with identical branch target:\n\t\t\tvar dict = new Dictionary<Block, SwitchSection>(); // branch target -> switch section\n\t\t\tsw.Sections.RemoveAll(\n\t\t\t\tsection => {\n\t\t\t\t\tif (section.Body.MatchBranch(out Block target))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (dict.TryGetValue(target, out SwitchSection primarySection))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tprimarySection.Labels = primarySection.Labels.UnionWith(section.Labels);\n\t\t\t\t\t\t\tprimarySection.HasNullLabel |= section.HasNullLabel;\n\t\t\t\t\t\t\treturn true; // remove this section\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdict.Add(target, section);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t});\n\t\t\tAdjustLabels(sw, context);\n\t\t\tSortSwitchSections(sw);\n\t\t}\n\n\t\tstatic void SortSwitchSections(SwitchInstruction sw)\n\t\t{\n\t\t\tsw.Sections.ReplaceList(sw.Sections.OrderBy(s => s.Body switch {\n\t\t\t\tBranch b => b.TargetILOffset,\n\t\t\t\tLeave l => l.StartILOffset,\n\t\t\t\t_ => (int?)null\n\t\t\t}).ThenBy(s => s.Labels.Values.FirstOrDefault()));\n\t\t}\n\n\t\tstatic void AdjustLabels(SwitchInstruction sw, ILTransformContext context)\n\t\t{\n\t\t\tif (sw.Value is BinaryNumericInstruction bop && !bop.CheckForOverflow && bop.Right.MatchLdcI(out long val))\n\t\t\t{\n\t\t\t\t// Move offset into labels:\n\t\t\t\tcontext.Step(\"Move offset into switch labels\", bop);\n\t\t\t\tlong offset;\n\t\t\t\tswitch (bop.Operator)\n\t\t\t\t{\n\t\t\t\t\tcase BinaryNumericOperator.Add:\n\t\t\t\t\t\toffset = unchecked(-val);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BinaryNumericOperator.Sub:\n\t\t\t\t\t\toffset = val;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault: // unknown bop.Operator\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsw.Value = bop.Left;\n\t\t\t\tforeach (var section in sw.Sections)\n\t\t\t\t{\n\t\t\t\t\tsection.Labels = section.Labels.AddOffset(offset);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst ulong MaxValuesPerSection = 100;\n\n\t\t/// <summary>\n\t\t/// Tests whether we should prefer a switch statement over an if statement.\n\t\t/// </summary>\n\t\tprivate bool UseCSharpSwitch(out KeyValuePair<LongSet, ILInstruction> defaultSection)\n\t\t{\n\t\t\tif (!analysis.InnerBlocks.Any())\n\t\t\t{\n\t\t\t\tdefaultSection = default;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tdefaultSection = analysis.Sections.FirstOrDefault(s => s.Key.Count() > MaxValuesPerSection);\n\t\t\tif (defaultSection.Value == null)\n\t\t\t{\n\t\t\t\t// no default section found?\n\t\t\t\t// This should never happen, as we'd need 2^64/MaxValuesPerSection sections to hit this case...\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar defaultSectionKey = defaultSection.Key;\n\t\t\tif (analysis.Sections.Any(s => !s.Key.SetEquals(defaultSectionKey) && s.Key.Count() > MaxValuesPerSection))\n\t\t\t{\n\t\t\t\t// Only the default section is allowed to have tons of keys.\n\t\t\t\t// C# doesn't support \"case 1 to 100000000\", and we don't want to generate\n\t\t\t\t// gigabytes of case labels.\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// good enough indicator that the surrounding code also forms a switch statement\n\t\t\tif (analysis.ContainsILSwitch || MatchRoslynSwitchOnString())\n\t\t\t\treturn true;\n\n\t\t\t// heuristic to determine if a block would be better represented as an if statement rather than switch\n\t\t\tint ifCount = analysis.InnerBlocks.Count + 1;\n\t\t\tint intervalCount = analysis.Sections.Where(s => !s.Key.SetEquals(defaultSectionKey)).Sum(s => s.Key.Intervals.Length);\n\t\t\tif (ifCount < intervalCount)\n\t\t\t\treturn false;\n\n\t\t\t(var flowNodes, var caseNodes) = AnalyzeControlFlow();\n\n\t\t\t// don't create switch statements with only one non-default label when the corresponding condition tree is flat\n\t\t\t// it may be important that the switch-like conditions be inlined\n\t\t\t// for example, a loop condition: while (c == '\\n' || c == '\\r')\n\t\t\tif (analysis.Sections.Count == 2 && IsSingleCondition(flowNodes, caseNodes))\n\t\t\t\treturn false;\n\n\t\t\t// if there is no ILSwitch, there's still many control flow patterns that \n\t\t\t// match a switch statement but were originally just regular if statements,\n\t\t\t// and converting them to switches results in poor quality code with goto statements\n\t\t\t// \n\t\t\t// If a single break target cannot be identified, then the equivalent switch statement would require goto statements.\n\t\t\t// These goto statements may be \"goto case x\" or \"goto default\", but these are a hint that the original code was not a switch,\n\t\t\t// and that the switch statement may be very poor quality. \n\t\t\t// Thus the rule of thumb is no goto statements if the original code didn't include them\n\t\t\tif (SwitchUsesGoto(flowNodes, caseNodes, out var breakBlock))\n\t\t\t\treturn false;\n\n\t\t\t// valid switch construction, all code can be inlined\n\t\t\tif (breakBlock == null)\n\t\t\t\treturn true;\n\n\t\t\t// The switch has a single break target and there is one more hint\n\t\t\t// The break target cannot be inlined, and should have the highest IL offset of everything targetted by the switch\n\t\t\treturn breakBlock.StartILOffset >= analysis.Sections.Select(s => s.Value.MatchBranch(out var b) ? b.StartILOffset : -1).Max();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// stloc switchValueVar(call ComputeStringHash(switchValue))\n\t\t/// </summary>\n\t\tprivate bool MatchRoslynSwitchOnString()\n\t\t{\n\t\t\tvar insns = analysis.RootBlock.Instructions;\n\t\t\treturn insns.Count >= 3 && SwitchOnStringTransform.MatchComputeStringOrReadOnlySpanHashCall(insns[insns.Count - 3], analysis.SwitchVariable, out _);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Builds the control flow graph for the current container (if necessary), establishes loopContext\n\t\t/// and returns the ControlFlowNodes corresponding to the inner flow and case blocks of the potential switch\n\t\t/// </summary>\n\t\tprivate (List<ControlFlowNode> flowNodes, List<ControlFlowNode> caseNodes) AnalyzeControlFlow()\n\t\t{\n\t\t\tif (controlFlowGraph == null)\n\t\t\t\tcontrolFlowGraph = new ControlFlowGraph(currentContainer, context.CancellationToken);\n\n\t\t\tvar switchHead = controlFlowGraph.GetNode(analysis.RootBlock);\n\t\t\tloopContext = new LoopContext(controlFlowGraph, switchHead);\n\n\t\t\tvar flowNodes = new List<ControlFlowNode> { switchHead };\n\t\t\tflowNodes.AddRange(analysis.InnerBlocks.Select(controlFlowGraph.GetNode));\n\n\t\t\t// grab the control flow nodes for blocks targetted by each section\n\t\t\tvar caseNodes = new List<ControlFlowNode>();\n\t\t\tforeach (var s in analysis.Sections)\n\t\t\t{\n\t\t\t\tif (!s.Value.MatchBranch(out var block))\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (block.Parent == currentContainer)\n\t\t\t\t{\n\t\t\t\t\tvar node = controlFlowGraph.GetNode(block);\n\t\t\t\t\tif (!loopContext.MatchContinue(node))\n\t\t\t\t\t\tcaseNodes.Add(node);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tAddNullCase(flowNodes, caseNodes);\n\n\t\t\tDebug.Assert(flowNodes.SelectMany(n => n.Successors)\n\t\t\t\t.All(n => flowNodes.Contains(n) || caseNodes.Contains(n) || loopContext.MatchContinue(n)));\n\n\t\t\treturn (flowNodes, caseNodes);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Determines if the analysed switch can be constructed without any gotos\n\t\t/// </summary>\n\t\tprivate bool SwitchUsesGoto(List<ControlFlowNode> flowNodes, List<ControlFlowNode> caseNodes, out Block breakBlock)\n\t\t{\n\t\t\t// cases with predecessors that aren't part of the switch logic \n\t\t\t// must either require \"goto case\" statements, or consist of a single \"break;\"\n\t\t\tvar externalCases = caseNodes.Where(c => c.Predecessors.Any(n => !flowNodes.Contains(n))).ToList();\n\n\t\t\tbreakBlock = null;\n\t\t\tif (externalCases.Count > 1)\n\t\t\t\treturn true; // cannot have more than one break case without gotos\n\n\t\t\t// check that case nodes flow through a single point\n\t\t\tvar breakTargets = caseNodes.Except(externalCases).SelectMany(n => loopContext.GetBreakTargets(n)).ToHashSet();\n\n\t\t\t// if there are multiple break targets, then gotos are required\n\t\t\t// if there are none, then the external case (if any) can be the break target\n\t\t\tif (breakTargets.Count != 1)\n\t\t\t\treturn breakTargets.Count > 1;\n\n\t\t\tbreakBlock = (Block)breakTargets.Single().UserData;\n\n\t\t\t// external case must consist of a single \"break;\"\n\t\t\treturn externalCases.Count == 1 && breakBlock != externalCases.Single().UserData;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Does some of the analysis of SwitchOnNullableTransform to add the null case control flow\n\t\t/// to the results of SwitchAnalysis\n\t\t/// </summary>\n\t\tprivate void AddNullCase(List<ControlFlowNode> flowNodes, List<ControlFlowNode> caseNodes)\n\t\t{\n\t\t\tif (analysis.RootBlock.IncomingEdgeCount != 1)\n\t\t\t\treturn;\n\n\t\t\t// if (comp(logic.not(call get_HasValue(ldloca nullableVar))) br NullCase\n\t\t\t// br RootBlock\n\t\t\tvar nullableBlock = (Block)controlFlowGraph.GetNode(analysis.RootBlock).Predecessors.SingleOrDefault()?.UserData;\n\t\t\tif (nullableBlock == null ||\n\t\t\t\tnullableBlock.Instructions.Count < 2 ||\n\t\t\t\t!nullableBlock.Instructions.Last().MatchBranch(analysis.RootBlock) ||\n\t\t\t\t!nullableBlock.Instructions.SecondToLastOrDefault().MatchIfInstruction(out var cond, out var trueInst) ||\n\t\t\t\t!cond.MatchLogicNot(out var getHasValue) ||\n\t\t\t\t!NullableLiftingTransform.MatchHasValueCall(getHasValue, out ILInstruction nullableInst))\n\t\t\t\treturn;\n\n\t\t\t// could check that nullableInst is ldloc or ldloca and that the switch variable matches a GetValueOrDefault\n\t\t\t// but the effect of adding an incorrect block to the flowBlock list would only be disasterous if it branched directly\n\t\t\t// to a candidate case block\n\n\t\t\t// must branch to a case label, otherwise we can proceed fine and let SwitchOnNullableTransform do all the work\n\t\t\tif (!trueInst.MatchBranch(out var nullBlock) || !caseNodes.Exists(n => n.UserData == nullBlock))\n\t\t\t\treturn;\n\n\t\t\t//add the null case logic to the incoming flow blocks\n\t\t\tflowNodes.Add(controlFlowGraph.GetNode(nullableBlock));\n\t\t}\n\t\t/// <summary>\n\t\t/// Pattern matching for short circuit expressions\n\t\t///   p\n\t\t///   |\\\n\t\t///   | n\n\t\t///   |/ \\\n\t\t///   s   c\n\t\t/// \n\t\t///  where\n\t\t///   p: if (a) goto n; goto s;\n\t\t///   n: if (b) goto c; goto s;\n\t\t/// \n\t\t///  Can simplify to\n\t\t///    p|n\n\t\t///    / \\\n\t\t///   s   c\n\t\t/// \n\t\t///  where:\n\t\t///   p|n: if (a &amp;&amp; b) goto c; goto s;\n\t\t/// \n\t\t///  Note that if n has only 1 successor, but is still a flow node, then a short circuit expression \n\t\t///  has a target (c) with no corresponding block (leave)\n\t\t/// </summary>\n\t\t/// <param name=\"parent\">A node with 2 successors</param>\n\t\t/// <param name=\"side\">The successor index to consider n (the other successor will be the common sibling)</param>\n\t\tprivate static bool IsShortCircuit(ControlFlowNode parent, int side)\n\t\t{\n\t\t\tvar node = parent.Successors[side];\n\t\t\tvar sibling = parent.Successors[side ^ 1];\n\n\t\t\tif (!IsFlowNode(node) || node.Successors.Count > 2 || node.Predecessors.Count != 1)\n\t\t\t\treturn false;\n\n\t\t\treturn node.Successors.Contains(sibling);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// A flow node contains only two instructions, the first of which is an IfInstruction\n\t\t/// A short circuit expression is comprised of a root block ending in an IfInstruction and one or more flow nodes\n\t\t/// </summary>\n\t\tstatic bool IsFlowNode(ControlFlowNode n) => ((Block)n.UserData).Instructions.FirstOrDefault() is IfInstruction;\n\n\t\t/// <summary>\n\t\t/// Determines whether the flowNodes are can be reduced to a single condition via short circuit operators\n\t\t/// </summary>\n\t\tprivate bool IsSingleCondition(List<ControlFlowNode> flowNodes, List<ControlFlowNode> caseNodes)\n\t\t{\n\t\t\tif (flowNodes.Count == 1)\n\t\t\t\treturn true;\n\n\t\t\tvar rootNode = controlFlowGraph.GetNode(analysis.RootBlock);\n\t\t\trootNode.Visited = true;\n\n\t\t\t// search down the tree, marking nodes as visited while they continue the current condition\n\t\t\tvar n = rootNode;\n\t\t\twhile (n.Successors.Count > 0 && (n == rootNode || IsFlowNode(n)))\n\t\t\t{\n\t\t\t\tif (n.Successors.Count == 1)\n\t\t\t\t{\n\t\t\t\t\t// if there is more than one case node, then a flow node with only one successor is not part of the initial condition\n\t\t\t\t\tif (caseNodes.Count > 1)\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tn = n.Successors[0];\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{ // 2 successors\n\t\t\t\t\tif (IsShortCircuit(n, 0))\n\t\t\t\t\t\tn = n.Successors[0];\n\t\t\t\t\telse if (IsShortCircuit(n, 1))\n\t\t\t\t\t\tn = n.Successors[1];\n\t\t\t\t\telse\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tn.Visited = true;\n\t\t\t\tif (loopContext.MatchContinue(n))\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tvar ret = flowNodes.All(f => f.Visited);\n\t\t\tResetVisited(controlFlowGraph.cfg);\n\t\t\treturn ret;\n\t\t}\n\n\t\tprivate static void ResetVisited(IEnumerable<ControlFlowNode> nodes)\n\t\t{\n\t\t\tforeach (var n in nodes)\n\t\t\t\tn.Visited = false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ControlFlow/SymbolicExecution.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.ControlFlow\n{\n\t/// <summary>\n\t/// This exception is thrown when we find something else than we expect from the C# compiler.\n\t/// This aborts the analysis and makes the whole transform fail.\n\t/// </summary>\n\tclass SymbolicAnalysisFailedException : Exception\n\t{\n\t\tpublic SymbolicAnalysisFailedException() { }\n\t\tpublic SymbolicAnalysisFailedException(string message) : base(message) { }\n\t}\n\n\tenum SymbolicValueType\n\t{\n\t\t/// <summary>\n\t\t/// Unknown value\n\t\t/// </summary>\n\t\tUnknown,\n\t\t/// <summary>\n\t\t/// int: Constant (result of ldc.i4)\n\t\t/// </summary>\n\t\tIntegerConstant,\n\t\t/// <summary>\n\t\t/// int: State + Constant\n\t\t/// </summary>\n\t\tState,\n\t\t/// <summary>\n\t\t/// This pointer (result of ldarg.0)\n\t\t/// </summary>\n\t\tThis,\n\t\t/// <summary>\n\t\t/// bool: ValueSet.Contains(State)\n\t\t/// </summary>\n\t\tStateInSet,\n\t}\n\n\tstruct SymbolicValue\n\t{\n\t\tpublic readonly int Constant;\n\t\tpublic readonly SymbolicValueType Type;\n\t\tpublic readonly LongSet ValueSet;\n\n\t\tpublic SymbolicValue(SymbolicValueType type, int constant = 0)\n\t\t{\n\t\t\tthis.Type = type;\n\t\t\tthis.Constant = constant;\n\t\t}\n\n\t\tpublic SymbolicValue(SymbolicValueType type, LongSet valueSet)\n\t\t{\n\t\t\tthis.Type = type;\n\t\t\tthis.Constant = 0;\n\t\t\tthis.ValueSet = valueSet;\n\t\t}\n\n\t\tpublic SymbolicValue AsBool()\n\t\t{\n\t\t\tif (Type == SymbolicValueType.State)\n\t\t\t{\n\t\t\t\t// convert state integer to bool:\n\t\t\t\t// if (state + c) = if (state + c != 0) = if (state != -c)\n\t\t\t\treturn new SymbolicValue(SymbolicValueType.StateInSet, new LongSet(unchecked(-Constant)).Invert());\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(\"[SymbolicValue {0}: {1}]\", this.Type, this.Constant);\n\t\t}\n\t}\n\n\tclass SymbolicEvaluationContext\n\t{\n\t\treadonly IField stateField;\n\t\treadonly bool legacyVisualBasic;\n\t\treadonly List<ILVariable> stateVariables = new List<ILVariable>();\n\n\t\tpublic SymbolicEvaluationContext(IField stateField, bool legacyVisualBasic = false)\n\t\t{\n\t\t\tthis.legacyVisualBasic = legacyVisualBasic;\n\t\t\tthis.stateField = stateField;\n\t\t}\n\n\t\tpublic void AddStateVariable(ILVariable v)\n\t\t{\n\t\t\tif (!stateVariables.Contains(v))\n\t\t\t\tstateVariables.Add(v);\n\t\t}\n\n\t\tpublic IEnumerable<ILVariable> StateVariables { get => stateVariables; }\n\n\t\tstatic readonly SymbolicValue Failed = new SymbolicValue(SymbolicValueType.Unknown);\n\n\t\tpublic SymbolicValue Eval(ILInstruction inst)\n\t\t{\n\t\t\tif (inst is BinaryNumericInstruction bni && bni.Operator == BinaryNumericOperator.Sub && (legacyVisualBasic || !bni.CheckForOverflow))\n\t\t\t{\n\t\t\t\tvar left = Eval(bni.Left);\n\t\t\t\tvar right = Eval(bni.Right);\n\t\t\t\tif (left.Type != SymbolicValueType.State && left.Type != SymbolicValueType.IntegerConstant)\n\t\t\t\t\treturn Failed;\n\t\t\t\tif (right.Type != SymbolicValueType.IntegerConstant)\n\t\t\t\t\treturn Failed;\n\t\t\t\treturn new SymbolicValue(left.Type, unchecked(left.Constant - right.Constant));\n\t\t\t}\n\t\t\telse if (inst.MatchLdFld(out var target, out var field))\n\t\t\t{\n\t\t\t\tif (Eval(target).Type != SymbolicValueType.This)\n\t\t\t\t\treturn Failed;\n\t\t\t\tif (field.MemberDefinition != stateField)\n\t\t\t\t\treturn Failed;\n\t\t\t\treturn new SymbolicValue(SymbolicValueType.State);\n\t\t\t}\n\t\t\telse if (inst.MatchLdLoc(out var loadedVariable))\n\t\t\t{\n\t\t\t\tif (stateVariables.Contains(loadedVariable))\n\t\t\t\t\treturn new SymbolicValue(SymbolicValueType.State);\n\t\t\t\telse if (loadedVariable.Kind == VariableKind.Parameter && loadedVariable.Index < 0)\n\t\t\t\t\treturn new SymbolicValue(SymbolicValueType.This);\n\t\t\t\telse\n\t\t\t\t\treturn Failed;\n\t\t\t}\n\t\t\telse if (inst.MatchLdcI4(out var value))\n\t\t\t{\n\t\t\t\treturn new SymbolicValue(SymbolicValueType.IntegerConstant, value);\n\t\t\t}\n\t\t\telse if (inst is Comp comp)\n\t\t\t{\n\t\t\t\tvar left = Eval(comp.Left);\n\t\t\t\tvar right = Eval(comp.Right);\n\t\t\t\tif (left.Type == SymbolicValueType.State && right.Type == SymbolicValueType.IntegerConstant)\n\t\t\t\t{\n\t\t\t\t\t// bool: (state + left.Constant == right.Constant)\n\t\t\t\t\tLongSet trueSums = SwitchAnalysis.MakeSetWhereComparisonIsTrue(comp.Kind, right.Constant, comp.Sign);\n\t\t\t\t\t// symbolic value is true iff trueSums.Contains(state + left.Constant)\n\t\t\t\t\tLongSet trueStates = trueSums.AddOffset(unchecked(-left.Constant));\n\t\t\t\t\t// symbolic value is true iff trueStates.Contains(state)\n\t\t\t\t\treturn new SymbolicValue(SymbolicValueType.StateInSet, trueStates);\n\t\t\t\t}\n\t\t\t\telse if (left.Type == SymbolicValueType.StateInSet && right.Type == SymbolicValueType.IntegerConstant)\n\t\t\t\t{\n\t\t\t\t\tif (comp.Kind == ComparisonKind.Equality && right.Constant == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t// comp((x in set) == 0) ==> x not in set\n\t\t\t\t\t\treturn new SymbolicValue(SymbolicValueType.StateInSet, left.ValueSet.Invert());\n\t\t\t\t\t}\n\t\t\t\t\telse if (comp.Kind == ComparisonKind.Inequality && right.Constant != 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t// comp((x in set) != 0) => x in set\n\t\t\t\t\t\treturn new SymbolicValue(SymbolicValueType.StateInSet, left.ValueSet);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn Failed;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn Failed;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn Failed;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.ControlFlow\n{\n\tpublic class YieldReturnDecompiler : IILTransform\n\t{\n\t\t// For a description on the code generated by the C# compiler for yield return:\n\t\t// http://csharpindepth.com/Articles/Chapter6/IteratorBlockImplementation.aspx\n\n\t\t// The idea here is:\n\t\t// - Figure out whether the current method is instanciating an enumerator\n\t\t// - Figure out which of the fields is the state field\n\t\t// - Construct an exception table based on states. This allows us to determine, for each state, what the parent try block is.\n\n\t\t// See http://community.sharpdevelop.net/blogs/danielgrunwald/archive/2011/03/06/ilspy-yield-return.aspx\n\t\t// for a description of this step.\n\n\t\tILTransformContext context;\n\t\tMetadataReader metadata;\n\n\t\t/// <summary>The type that contains the function being decompiled.</summary>\n\t\tTypeDefinitionHandle currentType;\n\n\t\t/// <summary>The compiler-generated enumerator class.</summary>\n\t\t/// <remarks>Set in MatchEnumeratorCreationPattern()</remarks>\n\t\tTypeDefinitionHandle enumeratorType;\n\n\t\t/// <summary>The constructor of the compiler-generated enumerator class.</summary>\n\t\t/// <remarks>Set in MatchEnumeratorCreationPattern()</remarks>\n\t\tMethodDefinitionHandle enumeratorCtor;\n\n\t\t/// <remarks>Set in MatchEnumeratorCreationPattern()</remarks>\n\t\tbool isCompiledWithMono;\n\n\t\t/// <remarks>Set in MatchEnumeratorCreationPattern() or ConstructExceptionTable()</remarks>\n\t\tbool isCompiledWithVisualBasic;\n\n\t\t/// <remarks>Set in MatchEnumeratorCreationPattern()</remarks>\n\t\t/// <remarks>If this is true, then isCompiledWithVisualBasic is also true.</remarks>\n\t\tbool isCompiledWithLegacyVisualBasic;\n\n\t\t/// <summary>The dispose method of the compiler-generated enumerator class.</summary>\n\t\t/// <remarks>Set in ConstructExceptionTable()</remarks>\n\t\tMethodDefinitionHandle disposeMethod;\n\n\t\t/// <summary>The field in the compiler-generated class holding the current state of the state machine</summary>\n\t\t/// <remarks>Set in AnalyzeCtor() for MS, MatchEnumeratorCreationPattern() or AnalyzeMoveNext() for Mono</remarks>\n\t\tIField stateField;\n\n\t\t/// <summary>The backing field of the 'Current' property in the compiler-generated class</summary>\n\t\t/// <remarks>Set in AnalyzeCurrentProperty()</remarks>\n\t\tIField currentField;\n\n\t\t/// <summary>The disposing field of the compiler-generated enumerator class.</summary>\n\t\t/// <remarks>Set in ConstructExceptionTable() for assembly compiled with Mono</remarks>\n\t\tIField disposingField;\n\n\t\t/// <summary>Maps the fields of the compiler-generated class to the original parameters.</summary>\n\t\t/// <remarks>Set in MatchEnumeratorCreationPattern() and ResolveIEnumerableIEnumeratorFieldMapping()</remarks>\n\t\treadonly Dictionary<IField, ILVariable> fieldToParameterMap = new Dictionary<IField, ILVariable>();\n\n\t\t/// <summary>This dictionary stores the information extracted from the Dispose() method:\n\t\t/// for each \"Finally Method\", it stores the set of states for which the method is being called.</summary>\n\t\t/// <remarks>Set in ConstructExceptionTable()</remarks>\n\t\tDictionary<IMethod, LongSet> finallyMethodToStateRange;\n\n\t\t/// <summary>\n\t\t/// For each finally method, stores the target state when entering the finally block,\n\t\t/// and the decompiled code of the finally method body.\n\t\t/// </summary>\n\t\treadonly Dictionary<IMethod, (int? outerState, ILFunction function)> decompiledFinallyMethods = new Dictionary<IMethod, (int? outerState, ILFunction body)>();\n\n\t\t/// <summary>\n\t\t/// Temporary stores for 'yield break'.\n\t\t/// </summary>\n\t\treadonly List<StLoc> returnStores = new List<StLoc>();\n\n\t\t/// <summary>\n\t\t/// Local bool variable in MoveNext() that signifies whether to skip finally bodies.\n\t\t/// </summary>\n\t\tILVariable skipFinallyBodies;\n\n\t\t/// <summary>\n\t\t/// Local bool variable in MoveNext() that signifies whether to execute finally bodies.\n\t\t/// </summary>\n\t\tILVariable doFinallyBodies;\n\n\t\t/// <summary>\n\t\t/// Set of variables might hold copies of the generated state field.\n\t\t/// </summary>\n\t\tHashSet<ILVariable> cachedStateVars;\n\n\t\t#region Run() method\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.YieldReturn)\n\t\t\t\treturn; // abort if enumerator decompilation is disabled\n\t\t\tthis.context = context;\n\t\t\tthis.metadata = context.PEFile.Metadata;\n\t\t\tthis.currentType = metadata.GetMethodDefinition((MethodDefinitionHandle)context.Function.Method.MetadataToken).GetDeclaringType();\n\t\t\tthis.enumeratorType = default;\n\t\t\tthis.enumeratorCtor = default;\n\t\t\tthis.isCompiledWithMono = false;\n\t\t\tthis.isCompiledWithVisualBasic = false;\n\t\t\tthis.isCompiledWithLegacyVisualBasic = false;\n\t\t\tthis.stateField = null;\n\t\t\tthis.currentField = null;\n\t\t\tthis.disposingField = null;\n\t\t\tthis.fieldToParameterMap.Clear();\n\t\t\tthis.finallyMethodToStateRange = null;\n\t\t\tthis.decompiledFinallyMethods.Clear();\n\t\t\tthis.returnStores.Clear();\n\t\t\tthis.skipFinallyBodies = null;\n\t\t\tthis.doFinallyBodies = null;\n\t\t\tthis.cachedStateVars = null;\n\t\t\tif (!MatchEnumeratorCreationPattern(function))\n\t\t\t\treturn;\n\t\t\tBlockContainer newBody;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tAnalyzeCtor();\n\t\t\t\tAnalyzeCurrentProperty();\n\t\t\t\tResolveIEnumerableIEnumeratorFieldMapping();\n\t\t\t\tConstructExceptionTable();\n\t\t\t\tnewBody = AnalyzeMoveNext(function);\n\t\t\t}\n\t\t\tcatch (SymbolicAnalysisFailedException ex)\n\t\t\t{\n\t\t\t\tfunction.Warnings.Add($\"yield-return decompiler failed: {ex.Message}\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcontext.Step(\"Replacing body with MoveNext() body\", function);\n\t\t\tfunction.IsIterator = true;\n\t\t\tfunction.StateMachineCompiledWithMono = isCompiledWithMono;\n\t\t\tfunction.StateMachineCompiledWithLegacyVisualBasic = isCompiledWithLegacyVisualBasic;\n\t\t\tvar oldBody = function.Body;\n\t\t\tfunction.Body = newBody;\n\t\t\t// register any locals used in newBody\n\t\t\tfunction.Variables.AddRange(newBody.Descendants.OfType<IInstructionWithVariableOperand>().Select(inst => inst.Variable).Distinct());\n\n\t\t\tPrintFinallyMethodStateRanges(newBody);\n\n\t\t\t// Add state machine field meta-data to parameter ILVariables.\n\t\t\tforeach (var (f, p) in fieldToParameterMap)\n\t\t\t{\n\t\t\t\tp.StateMachineField = f;\n\t\t\t}\n\n\t\t\tcontext.Step(\"Delete unreachable blocks\", function);\n\n\t\t\tif (isCompiledWithMono || isCompiledWithVisualBasic)\n\t\t\t{\n\t\t\t\t// mono has try-finally inline (like async on MS); we also need to sort nested blocks:\n\t\t\t\tforeach (var nestedContainer in newBody.Blocks.SelectMany(c => c.Descendants).OfType<BlockContainer>())\n\t\t\t\t{\n\t\t\t\t\tnestedContainer.SortBlocks(deleteUnreachableBlocks: true);\n\t\t\t\t}\n\t\t\t\t// We need to clean up nested blocks before the main block, so that edges from unreachable code\n\t\t\t\t// in nested containers into the main container are removed before we clean up the main container.\n\t\t\t}\n\t\t\t// Note: because this only deletes blocks outright, the 'stateChanges' entries remain valid\n\t\t\t// (though some may point to now-deleted blocks)\n\t\t\tnewBody.SortBlocks(deleteUnreachableBlocks: true);\n\t\t\tfunction.CheckInvariant(ILPhase.Normal);\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (isCompiledWithMono)\n\t\t\t\t{\n\t\t\t\t\tCleanSkipFinallyBodies(function);\n\t\t\t\t}\n\t\t\t\telse if (isCompiledWithLegacyVisualBasic)\n\t\t\t\t{\n\t\t\t\t\tCleanDoFinallyBodies(function);\n\t\t\t\t}\n\t\t\t\telse if (isCompiledWithVisualBasic)\n\t\t\t\t{\n\t\t\t\t\tCleanFinallyStateChecks(function);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tDecompileFinallyBlocks();\n\t\t\t\t\tReconstructTryFinallyBlocks(function);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (SymbolicAnalysisFailedException ex)\n\t\t\t{\n\t\t\t\t// Revert the yield-return transformation\n\t\t\t\tcontext.Step(\"Transform failed, roll it back\", function);\n\t\t\t\tfunction.IsIterator = false;\n\t\t\t\tfunction.StateMachineCompiledWithMono = false;\n\t\t\t\tfunction.StateMachineCompiledWithLegacyVisualBasic = false;\n\t\t\t\tfunction.Body = oldBody;\n\t\t\t\tfunction.Variables.RemoveDead();\n\t\t\t\tfunction.Warnings.Add($\"yield-return decompiler failed: {ex.Message}\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcontext.Step(\"Translate fields to local accesses\", function);\n\t\t\tTranslateFieldsToLocalAccess(function, function, fieldToParameterMap, isCompiledWithMono);\n\n\t\t\t// On mono, we still need to remove traces of the state variable(s):\n\t\t\tif (isCompiledWithMono || isCompiledWithVisualBasic)\n\t\t\t{\n\t\t\t\tif (fieldToParameterMap.TryGetValue(stateField, out var stateVar))\n\t\t\t\t{\n\t\t\t\t\treturnStores.AddRange(stateVar.StoreInstructions.OfType<StLoc>());\n\t\t\t\t}\n\t\t\t\tforeach (var cachedStateVar in cachedStateVars)\n\t\t\t\t{\n\t\t\t\t\treturnStores.AddRange(cachedStateVar.StoreInstructions.OfType<StLoc>());\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (returnStores.Count > 0)\n\t\t\t{\n\t\t\t\tcontext.Step(\"Remove temporaries\", function);\n\t\t\t\tforeach (var store in returnStores)\n\t\t\t\t{\n\t\t\t\t\tif (store.Variable.LoadCount == 0 && store.Variable.AddressCount == 0 && store.Parent is Block block)\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(SemanticHelper.IsPure(store.Value.Flags));\n\t\t\t\t\t\tblock.Instructions.Remove(store);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Re-run control flow simplification over the newly constructed set of gotos,\n\t\t\t// and inlining because TranslateFieldsToLocalAccess() might have opened up new inlining opportunities.\n\t\t\tfunction.RunTransforms(CSharpDecompiler.EarlyILTransforms(), context);\n\t\t}\n\t\t#endregion\n\n\t\t#region Match the enumerator creation pattern\n\t\tbool MatchEnumeratorCreationPattern(ILFunction function)\n\t\t{\n\t\t\tBlock body = SingleBlock(function.Body);\n\t\t\tif (body == null || body.Instructions.Count == 0)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tILInstruction newObj;\n\t\t\tif (body.Instructions.Count == 1)\n\t\t\t{\n\t\t\t\t// No parameters passed to enumerator (not even 'this'):\n\t\t\t\t// ret(newobj(...))\n\t\t\t\tif (!body.Instructions[0].MatchReturn(out newObj))\n\t\t\t\t\treturn false;\n\t\t\t\tif (MatchEnumeratorCreationNewObj(newObj))\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse if (MatchMonoEnumeratorCreationNewObj(newObj))\n\t\t\t\t{\n\t\t\t\t\tisCompiledWithMono = true;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If there's parameters passed to the helper class, the class instance is first\n\t\t\t// stored in a variable, then the parameters are copied over, then the instance is returned.\n\n\t\t\tint pos = 0;\n\n\t\t\t// stloc(var_1, newobj(..))\n\t\t\tif (!body.Instructions[pos].MatchStLoc(out var var1, out newObj))\n\t\t\t\treturn false;\n\t\t\tif (MatchEnumeratorCreationNewObj(newObj))\n\t\t\t{\n\t\t\t\tpos++; // OK\n\t\t\t}\n\t\t\telse if (MatchMonoEnumeratorCreationNewObj(newObj))\n\t\t\t{\n\t\t\t\tpos++;\n\t\t\t\tif (TransformDisplayClassUsage.ValidateConstructor(context, ((NewObj)newObj).Method))\n\t\t\t\t{\n\t\t\t\t\tisCompiledWithMono = true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tisCompiledWithVisualBasic = true;\n\t\t\t\t\tisCompiledWithLegacyVisualBasic = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tbool stateFieldInitialized = false;\n\t\t\tfor (; pos < body.Instructions.Count; pos++)\n\t\t\t{\n\t\t\t\t// stfld(..., ldloc(var_1), ldloc(parameter))\n\t\t\t\t// or (in structs): stfld(..., ldloc(var_1), ldobj(ldloc(this)))\n\t\t\t\tif (!body.Instructions[pos].MatchStFld(out var ldloc, out var storedField, out var value))\n\t\t\t\t\tbreak;\n\t\t\t\tif (!ldloc.MatchLdLoc(var1))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (value.MatchLdLoc(out var parameter) && parameter.Kind == VariableKind.Parameter)\n\t\t\t\t{\n\t\t\t\t\tfieldToParameterMap[(IField)storedField.MemberDefinition] = parameter;\n\t\t\t\t}\n\t\t\t\telse if (value is LdObj ldobj && ldobj.Target.MatchLdThis())\n\t\t\t\t{\n\t\t\t\t\t// copy of 'this' in struct\n\t\t\t\t\tfieldToParameterMap[(IField)storedField.MemberDefinition] = ((LdLoc)ldobj.Target).Variable;\n\t\t\t\t}\n\t\t\t\telse if ((isCompiledWithMono || isCompiledWithLegacyVisualBasic) && (value.MatchLdcI4(-2) || value.MatchLdcI4(-1) || value.MatchLdcI4(0)))\n\t\t\t\t{\n\t\t\t\t\tstateField = (IField)storedField.MemberDefinition;\n\t\t\t\t\tstateFieldInitialized = true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// In debug builds, the compiler may copy the var1 into another variable (var2) before returning it.\n\t\t\tif (body.Instructions[pos].MatchStLoc(out var var2, out var ldlocForStloc2)\n\t\t\t\t&& ldlocForStloc2.MatchLdLoc(var1))\n\t\t\t{\n\t\t\t\t// stloc(var_2, ldloc(var_1))\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\tif (isCompiledWithMono && !stateFieldInitialized)\n\t\t\t{\n\t\t\t\t// Mono initializes the state field separately:\n\t\t\t\t// (but not if it's left at the default value 0)\n\t\t\t\tif (body.Instructions[pos].MatchStFld(out var target, out var field, out var value)\n\t\t\t\t\t&& target.MatchLdLoc(var2 ?? var1)\n\t\t\t\t\t&& (value.MatchLdcI4(-2) || value.MatchLdcI4(0)))\n\t\t\t\t{\n\t\t\t\t\tstateField = (IField)field.MemberDefinition;\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (body.Instructions[pos].MatchReturn(out var retVal)\n\t\t\t\t&& retVal.MatchLdLoc(var2 ?? var1))\n\t\t\t{\n\t\t\t\t// ret(ldloc(var_2))\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches the body of a method as a single basic block.\n\t\t/// </summary>\n\t\tinternal static Block SingleBlock(ILInstruction body)\n\t\t{\n\t\t\tvar block = body as Block;\n\t\t\tif (body is BlockContainer blockContainer && blockContainer.Blocks.Count == 1)\n\t\t\t{\n\t\t\t\tblock = blockContainer.Blocks.Single();\n\t\t\t}\n\t\t\treturn block;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches the newobj instruction that creates an instance of the compiler-generated enumerator helper class.\n\t\t/// </summary>\n\t\tbool MatchEnumeratorCreationNewObj(ILInstruction inst)\n\t\t{\n\t\t\treturn MatchEnumeratorCreationNewObj(inst, metadata, currentType,\n\t\t\t\tout enumeratorCtor, out enumeratorType);\n\t\t}\n\n\t\tinternal static bool MatchEnumeratorCreationNewObj(ILInstruction inst,\n\t\t\tMetadataReader metadata, TypeDefinitionHandle currentType,\n\t\t\tout MethodDefinitionHandle enumeratorCtor, out TypeDefinitionHandle enumeratorType)\n\t\t{\n\t\t\tenumeratorCtor = default;\n\t\t\tenumeratorType = default;\n\t\t\t// newobj(CurrentType/...::.ctor, ldc.i4(-2))\n\t\t\tif (!(inst is NewObj newObj))\n\t\t\t\treturn false;\n\t\t\tif (newObj.Arguments.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (!newObj.Arguments[0].MatchLdcI4(out int initialState))\n\t\t\t\treturn false;\n\t\t\tif (!(initialState == -2 || initialState == 0))\n\t\t\t\treturn false;\n\t\t\tvar handle = newObj.Method.MetadataToken;\n\t\t\tenumeratorCtor = handle.IsNil || handle.Kind != HandleKind.MethodDefinition ? default : (MethodDefinitionHandle)handle;\n\t\t\tenumeratorType = enumeratorCtor.IsNil ? default : metadata.GetMethodDefinition(enumeratorCtor).GetDeclaringType();\n\t\t\treturn (enumeratorType.IsNil ? default : metadata.GetTypeDefinition(enumeratorType).GetDeclaringType()) == currentType\n\t\t\t\t&& IsCompilerGeneratorEnumerator(enumeratorType, metadata);\n\t\t}\n\n\t\tbool MatchMonoEnumeratorCreationNewObj(ILInstruction inst)\n\t\t{\n\t\t\t// mcs generates iterators that take no parameters in the ctor\n\t\t\tif (!(inst is NewObj newObj))\n\t\t\t\treturn false;\n\t\t\tif (newObj.Arguments.Count != 0)\n\t\t\t\treturn false;\n\t\t\tvar handle = newObj.Method.MetadataToken;\n\t\t\tenumeratorCtor = handle.IsNil || handle.Kind != HandleKind.MethodDefinition ? default : (MethodDefinitionHandle)handle;\n\t\t\tenumeratorType = enumeratorCtor.IsNil ? default : metadata.GetMethodDefinition(enumeratorCtor).GetDeclaringType();\n\t\t\treturn (enumeratorType.IsNil ? default : metadata.GetTypeDefinition(enumeratorType).GetDeclaringType()) == currentType\n\t\t\t\t&& IsCompilerGeneratorEnumerator(enumeratorType, metadata);\n\t\t}\n\n\t\tpublic static bool IsCompilerGeneratorEnumerator(TypeDefinitionHandle type, MetadataReader metadata)\n\t\t{\n\t\t\tTypeDefinition td;\n\t\t\tif (type.IsNil || !type.IsCompilerGeneratedOrIsInCompilerGeneratedClass(metadata) || (td = metadata.GetTypeDefinition(type)).GetDeclaringType().IsNil)\n\t\t\t\treturn false;\n\t\t\tforeach (var i in td.GetInterfaceImplementations())\n\t\t\t{\n\t\t\t\tvar tr = metadata.GetInterfaceImplementation(i).Interface.GetFullTypeName(metadata);\n\t\t\t\tif (!tr.IsNested && tr.TopLevelTypeName.Namespace == \"System.Collections\" && tr.TopLevelTypeName.Name == \"IEnumerator\")\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\t#endregion\n\n\t\t#region Figure out what the 'state' field is (analysis of .ctor())\n\t\t/// <summary>\n\t\t/// Looks at the enumerator's ctor and figures out which of the fields holds the state.\n\t\t/// </summary>\n\t\tvoid AnalyzeCtor()\n\t\t{\n\t\t\tBlock body = SingleBlock(CreateILAst(enumeratorCtor, context).Body);\n\t\t\tif (body == null)\n\t\t\t\tthrow new SymbolicAnalysisFailedException(\"Missing enumeratorCtor.Body\");\n\t\t\tforeach (var inst in body.Instructions)\n\t\t\t{\n\t\t\t\tif (inst.MatchStFld(out var target, out var field, out var value)\n\t\t\t\t\t&& target.MatchLdThis()\n\t\t\t\t\t&& value.MatchLdLoc(out var arg)\n\t\t\t\t\t&& arg.Kind == VariableKind.Parameter && arg.Index == 0)\n\t\t\t\t{\n\t\t\t\t\tstateField = (IField)field.MemberDefinition;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (stateField == null && !isCompiledWithMono)\n\t\t\t\tthrow new SymbolicAnalysisFailedException(\"Could not find stateField\");\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates ILAst for the specified method, optimized up to before the 'YieldReturn' step.\n\t\t/// </summary>\n\t\tinternal static ILFunction CreateILAst(MethodDefinitionHandle method, ILTransformContext context)\n\t\t{\n\t\t\tvar metadata = context.PEFile.Metadata;\n\t\t\tif (method.IsNil)\n\t\t\t\tthrow new SymbolicAnalysisFailedException(\"Method not found\");\n\n\t\t\tvar methodDef = metadata.GetMethodDefinition(method);\n\t\t\tif (!methodDef.HasBody())\n\t\t\t\tthrow new SymbolicAnalysisFailedException($\"Method {methodDef.Name} has no body\");\n\n\t\t\tGenericContext genericContext = context.Function.GenericContext;\n\t\t\tgenericContext = new GenericContext(\n\t\t\t\tclassTypeParameters: (genericContext.ClassTypeParameters ?? EmptyList<ITypeParameter>.Instance)\n\t\t\t\t\t\t.Concat(genericContext.MethodTypeParameters ?? EmptyList<ITypeParameter>.Instance).ToArray(),\n\t\t\t\tmethodTypeParameters: null);\n\t\t\tvar body = context.TypeSystem.MainModule.MetadataFile.GetMethodBody(methodDef.RelativeVirtualAddress);\n\t\t\tvar il = context.CreateILReader()\n\t\t\t\t.ReadIL(method, body, genericContext, ILFunctionKind.TopLevelFunction, context.CancellationToken);\n\t\t\til.RunTransforms(CSharpDecompiler.EarlyILTransforms(true),\n\t\t\t\tnew ILTransformContext(il, context.TypeSystem, context.DebugInfo, context.Settings) {\n\t\t\t\t\tCancellationToken = context.CancellationToken,\n\t\t\t\t\tDecompileRun = context.DecompileRun\n\t\t\t\t});\n\t\t\treturn il;\n\t\t}\n\t\t#endregion\n\n\t\t#region Figure out what the 'current' field is (analysis of get_Current())\n\t\t/// <summary>\n\t\t/// Looks at the enumerator's get_Current method and figures out which of the fields holds the current value.\n\t\t/// </summary>\n\t\tvoid AnalyzeCurrentProperty()\n\t\t{\n\t\t\tMethodDefinitionHandle getCurrentMethod = metadata.GetTypeDefinition(enumeratorType).GetMethods().FirstOrDefault(\n\t\t\t\tm => IsMethod(m, \"get_Current\"));\n\t\t\tBlock body = SingleBlock(CreateILAst(getCurrentMethod, context).Body);\n\t\t\tif (body == null)\n\t\t\t\tthrow new SymbolicAnalysisFailedException(\"get_Current has no body\");\n\t\t\tif (body.Instructions.Count == 1)\n\t\t\t{\n\t\t\t\t// release builds directly return the current field\n\t\t\t\t// ret(ldfld F(ldloc(this)))\n\t\t\t\tif (body.Instructions[0].MatchReturn(out var retVal)\n\t\t\t\t\t&& retVal.MatchLdFld(out var target, out var field)\n\t\t\t\t\t&& target.MatchLdThis())\n\t\t\t\t{\n\t\t\t\t\tcurrentField = (IField)field.MemberDefinition;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (body.Instructions.Count == 2)\n\t\t\t{\n\t\t\t\t// debug builds store the return value in a temporary\n\t\t\t\t// stloc V = ldfld F(ldloc(this))\n\t\t\t\t// ret(ldloc V)\n\t\t\t\tif (body.Instructions[0].MatchStLoc(out var v, out var ldfld)\n\t\t\t\t\t&& ldfld.MatchLdFld(out var target, out var field)\n\t\t\t\t\t&& target.MatchLdThis()\n\t\t\t\t\t&& body.Instructions[1].MatchReturn(out var retVal)\n\t\t\t\t\t&& retVal.MatchLdLoc(v))\n\t\t\t\t{\n\t\t\t\t\tcurrentField = (IField)field.MemberDefinition;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (currentField == null)\n\t\t\t\tthrow new SymbolicAnalysisFailedException(\"Could not find currentField\");\n\t\t}\n\t\t#endregion\n\n\t\t#region Figure out the mapping of IEnumerable fields to IEnumerator fields  (analysis of GetEnumerator())\n\t\tvoid ResolveIEnumerableIEnumeratorFieldMapping()\n\t\t{\n\t\t\tMethodDefinitionHandle getEnumeratorMethod = metadata.GetTypeDefinition(enumeratorType).GetMethods().FirstOrDefault(\n\t\t\t\tm => IsMethod(m, \"GetEnumerator\"));\n\t\t\tResolveIEnumerableIEnumeratorFieldMapping(getEnumeratorMethod, context, fieldToParameterMap);\n\t\t}\n\n\t\tinternal static void ResolveIEnumerableIEnumeratorFieldMapping(MethodDefinitionHandle getEnumeratorMethod, ILTransformContext context,\n\t\t\tDictionary<IField, ILVariable> fieldToParameterMap)\n\t\t{\n\t\t\tif (getEnumeratorMethod.IsNil)\n\t\t\t\treturn; // no mappings (maybe it's just an IEnumerator implementation?)\n\t\t\tvar function = CreateILAst(getEnumeratorMethod, context);\n\t\t\tforeach (var block in function.Descendants.OfType<Block>())\n\t\t\t{\n\t\t\t\tforeach (var inst in block.Instructions)\n\t\t\t\t{\n\t\t\t\t\t// storeTarget.storeField = this.loadField;\n\t\t\t\t\tif (inst.MatchStFld(out var storeTarget, out var storeField, out var storeValue)\n\t\t\t\t\t\t&& storeValue.MatchLdFld(out var loadTarget, out var loadField)\n\t\t\t\t\t\t&& loadTarget.MatchLdThis())\n\t\t\t\t\t{\n\t\t\t\t\t\tstoreField = (IField)storeField.MemberDefinition;\n\t\t\t\t\t\tloadField = (IField)loadField.MemberDefinition;\n\t\t\t\t\t\tif (fieldToParameterMap.TryGetValue(loadField, out var mappedParameter))\n\t\t\t\t\t\t\tfieldToParameterMap[storeField] = mappedParameter;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Construction of the exception table (analysis of Dispose())\n\t\t// We construct the exception table by analyzing the enumerator's Dispose() method.\n\n\t\tvoid ConstructExceptionTable()\n\t\t{\n\t\t\tdisposeMethod = metadata.GetTypeDefinition(enumeratorType).GetMethods().FirstOrDefault(m => IsMethod(m, \"Dispose\"));\n\t\t\tvar function = CreateILAst(disposeMethod, context);\n\n\t\t\tif (!isCompiledWithVisualBasic && !isCompiledWithMono)\n\t\t\t{\n\t\t\t\tBlockContainer body = (BlockContainer)function.Body;\n\t\t\t\tforeach (var instr in body.Blocks.SelectMany(block => block.Instructions))\n\t\t\t\t{\n\t\t\t\t\tif (instr is CallInstruction call && call.Arguments.Count == 1 && call.Arguments[0].MatchLdThis() &&\n\t\t\t\t\t\tIsMethod((MethodDefinitionHandle)call.Method.MetadataToken, \"MoveNext\"))\n\t\t\t\t\t{\n\t\t\t\t\t\tisCompiledWithVisualBasic = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isCompiledWithMono || isCompiledWithVisualBasic)\n\t\t\t{\n\t\t\t\tBlockContainer body = (BlockContainer)function.Body;\n\t\t\t\tfor (var i = 0; (i < body.EntryPoint.Instructions.Count) && !(body.EntryPoint.Instructions[i] is Branch); i++)\n\t\t\t\t{\n\t\t\t\t\tif (body.EntryPoint.Instructions[i] is StObj stobj\n\t\t\t\t\t\t&& stobj.MatchStFld(out var target, out var field, out var value)\n\t\t\t\t\t\t&& target.MatchLdThis()\n\t\t\t\t\t\t&& field.Type.IsKnownType(KnownTypeCode.Boolean)\n\t\t\t\t\t\t&& value.MatchLdcI4(1))\n\t\t\t\t\t{\n\t\t\t\t\t\tdisposingField = (IField)field.MemberDefinition;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// On mono and VB, we don't need to analyse Dispose() to reconstruct the try-finally structure.\n\t\t\t\tfinallyMethodToStateRange = default;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Non-Mono/Non-VB: analyze try-finally structure in Dispose()\n\t\t\t\tvar rangeAnalysis = new StateRangeAnalysis(StateRangeAnalysisMode.IteratorDispose, stateField);\n\t\t\t\trangeAnalysis.AssignStateRanges(function.Body, LongSet.Universe);\n\t\t\t\tfinallyMethodToStateRange = rangeAnalysis.finallyMethodToStateRange;\n\t\t\t}\n\t\t}\n\n\t\t[Conditional(\"DEBUG\")]\n\t\tvoid PrintFinallyMethodStateRanges(BlockContainer bc)\n\t\t{\n\t\t\tif (finallyMethodToStateRange == null)\n\t\t\t\treturn;\n\t\t\tforeach (var (method, stateRange) in finallyMethodToStateRange)\n\t\t\t{\n\t\t\t\tbc.Blocks[0].Instructions.Insert(0, new Nop {\n\t\t\t\t\tComment = method.Name + \" in \" + stateRange\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Analyze MoveNext() and generate new body\n\t\tBlockContainer AnalyzeMoveNext(ILFunction function)\n\t\t{\n\t\t\tcontext.StepStartGroup(\"AnalyzeMoveNext\");\n\t\t\tMethodDefinitionHandle moveNextMethod = metadata.GetTypeDefinition(enumeratorType).GetMethods().FirstOrDefault(m => metadata.GetString(metadata.GetMethodDefinition(m).Name) == \"MoveNext\");\n\t\t\tILFunction moveNextFunction = CreateILAst(moveNextMethod, context);\n\n\t\t\tfunction.MoveNextMethod = moveNextFunction.Method;\n\t\t\tfunction.SequencePointCandidates = moveNextFunction.SequencePointCandidates;\n\t\t\tfunction.CodeSize = moveNextFunction.CodeSize;\n\t\t\tfunction.LocalVariableSignatureLength = moveNextFunction.LocalVariableSignatureLength;\n\n\t\t\t// Copy-propagate temporaries holding a copy of 'this'.\n\t\t\t// This is necessary because the old (pre-Roslyn) C# compiler likes to store 'this' in temporary variables.\n\t\t\tforeach (var stloc in moveNextFunction.Descendants.OfType<StLoc>().Where(s => s.Variable.IsSingleDefinition && s.Value.MatchLdThis()).ToList())\n\t\t\t{\n\t\t\t\tCopyPropagation.Propagate(stloc, context);\n\t\t\t}\n\n\t\t\t// Copy propagate stack slots holding a 32 bit integer.\n\t\t\tforeach (var stloc in moveNextFunction.Descendants.OfType<StLoc>().Where(s => s.Variable.Kind == VariableKind.StackSlot && s.Variable.IsSingleDefinition && s.Value.OpCode == OpCode.LdcI4).ToList())\n\t\t\t{\n\t\t\t\tCopyPropagation.Propagate(stloc, context);\n\t\t\t}\n\n\t\t\tforeach (var block in moveNextFunction.Descendants.OfType<Block>())\n\t\t\t{\n\t\t\t\tblock.Instructions.RemoveAll(inst => inst.OpCode == OpCode.LdcI4);\n\t\t\t}\n\n\t\t\tvar body = (BlockContainer)moveNextFunction.Body;\n\t\t\tif (body.Blocks.Count == 1 && body.Blocks[0].Instructions.Count == 1 && body.Blocks[0].Instructions[0] is TryFault tryFault)\n\t\t\t{\n\t\t\t\tbody = (BlockContainer)tryFault.TryBlock;\n\t\t\t\tvar faultBlockContainer = tryFault.FaultBlock as BlockContainer;\n\t\t\t\tif (faultBlockContainer?.Blocks.Count != 1)\n\t\t\t\t\tthrow new SymbolicAnalysisFailedException(\"Unexpected number of blocks in MoveNext() fault block\");\n\t\t\t\tvar faultBlock = faultBlockContainer.Blocks.Single();\n\t\t\t\tif (!(faultBlock.Instructions.Count == 2\n\t\t\t\t\t&& faultBlock.Instructions[0] is Call call\n\t\t\t\t\t&& call.Method.MetadataToken == disposeMethod\n\t\t\t\t\t&& call.Arguments.Count == 1\n\t\t\t\t\t&& call.Arguments[0].MatchLdThis()\n\t\t\t\t\t&& faultBlock.Instructions[1].MatchLeave(faultBlockContainer)))\n\t\t\t\t{\n\t\t\t\t\tthrow new SymbolicAnalysisFailedException(\"Unexpected fault block contents in MoveNext()\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isCompiledWithLegacyVisualBasic && (body.Blocks.Count == 2 || body.Blocks.Count == 1) &&\n\t\t\t\tbody.Blocks[0].Instructions.Count == 2 &&\n\t\t\t\tbody.Blocks[0].Instructions[0].MatchStLoc(out var firstVar, out var ldc) && ldc.MatchLdcI4(1))\n\t\t\t{\n\t\t\t\tdoFinallyBodies = firstVar;\n\t\t\t\tif (body.Blocks[0].Instructions[1] is TryCatch tryCatch && tryCatch.Handlers.Count == 1)\n\t\t\t\t{\n\t\t\t\t\tTryCatchHandler catchHandler = tryCatch.Handlers[0];\n\t\t\t\t\tvar catchBlockContainer = catchHandler.Body as BlockContainer;\n\t\t\t\t\tif (catchBlockContainer?.Blocks.Count != 1)\n\t\t\t\t\t\tthrow new SymbolicAnalysisFailedException(\"Unexpected number of blocks in MoveNext() catch block\");\n\t\t\t\t\tvar catchBlock = catchBlockContainer.Blocks.Single();\n\t\t\t\t\tif (!(catchBlock.Instructions.Count == 4 && catchBlock.Instructions[0] is Call call &&\n\t\t\t\t\t\t\tcall.Method.Name == \"SetProjectError\" && call.Arguments.Count == 1 &&\n\t\t\t\t\t\t\tcall.Arguments[0].MatchLdLoc(catchHandler.Variable) &&\n\t\t\t\t\t\t\tcatchBlock.Instructions[1].MatchStLoc(out _, out var ldloc) &&\n\t\t\t\t\t\t\tldloc.MatchLdLoc(catchHandler.Variable) &&\n\t\t\t\t\t\t\tcatchBlock.Instructions[2].MatchStFld(out var ldThis, out var fld, out var value) &&\n\t\t\t\t\t\t\tldThis.MatchLdThis() && fld.MemberDefinition.Equals(stateField) && value is LdcI4 &&\n\t\t\t\t\t\t\tcatchBlock.Instructions[3] is Rethrow))\n\t\t\t\t\t\tthrow new SymbolicAnalysisFailedException(\"Unexpected catch block contents in MoveNext()\");\n\t\t\t\t\tBlockContainer tryCatchBody = (BlockContainer)tryCatch.TryBlock;\n\t\t\t\t\t// Move return block\n\t\t\t\t\tif (body.Blocks.Count == 2)\n\t\t\t\t\t\ttryCatchBody.Blocks.Add(body.Blocks[1]);\n\t\t\t\t\tbody = tryCatchBody;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (stateField == null)\n\t\t\t{\n\t\t\t\t// With mono-compiled state machines, it's possible that we haven't discovered the state field\n\t\t\t\t// yet because the compiler let it be implicitly initialized to 0.\n\t\t\t\t// In this case, we must discover it from the first instruction in MoveNext():\n\t\t\t\tif (body.EntryPoint.Instructions[0] is StLoc stloc\n\t\t\t\t\t&& stloc.Value.MatchLdFld(out var target, out var field)\n\t\t\t\t\t&& target.MatchLdThis() && field.Type.IsKnownType(KnownTypeCode.Int32))\n\t\t\t\t{\n\t\t\t\t\tstateField = (IField)field.MemberDefinition;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthrow new SymbolicAnalysisFailedException(\"Could not find state field.\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tskipFinallyBodies = null;\n\t\t\tif (isCompiledWithMono)\n\t\t\t{\n\t\t\t\t// Mono uses skipFinallyBodies; find out which variable that is:\n\t\t\t\tforeach (var tryFinally in body.Descendants.OfType<TryFinally>())\n\t\t\t\t{\n\t\t\t\t\tif ((tryFinally.FinallyBlock as BlockContainer)?.EntryPoint.Instructions[0] is IfInstruction ifInst)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (ifInst.Condition.MatchLogicNot(out var arg) && arg.MatchLdLoc(out var v) && v.Type.IsKnownType(KnownTypeCode.Boolean))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbool isInitializedInEntryBlock = false;\n\t\t\t\t\t\t\tfor (int i = 0; i < 3; i++)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (body.EntryPoint.Instructions.ElementAtOrDefault(i) is StLoc stloc\n\t\t\t\t\t\t\t\t\t&& stloc.Variable == v && stloc.Value.MatchLdcI4(0))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tisInitializedInEntryBlock = true;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (isInitializedInEntryBlock)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tskipFinallyBodies = v;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tPropagateCopiesOfFields(body);\n\n\t\t\t// Note: body may contain try-catch or try-finally statements that have nested block containers,\n\t\t\t// but those cannot contain any yield statements.\n\t\t\t// So for reconstructing the control flow, we only consider the blocks directly within body.\n\n\t\t\tvar rangeAnalysis = new StateRangeAnalysis(StateRangeAnalysisMode.IteratorMoveNext, stateField, legacyVisualBasic: isCompiledWithLegacyVisualBasic);\n\t\t\trangeAnalysis.skipFinallyBodies = skipFinallyBodies;\n\t\t\trangeAnalysis.doFinallyBodies = doFinallyBodies;\n\t\t\trangeAnalysis.CancellationToken = context.CancellationToken;\n\t\t\trangeAnalysis.AssignStateRanges(body, LongSet.Universe);\n\t\t\tcachedStateVars = rangeAnalysis.CachedStateVars.ToHashSet();\n\n\t\t\tvar newBody = ConvertBody(body, rangeAnalysis);\n\t\t\tmoveNextFunction.Variables.Clear();\n\t\t\t// release references from old moveNextFunction to instructions that were moved over to newBody\n\t\t\tmoveNextFunction.ReleaseRef();\n\t\t\tcontext.StepEndGroup();\n\t\t\treturn newBody;\n\t\t}\n\n\t\tprivate void PropagateCopiesOfFields(BlockContainer body)\n\t\t{\n\t\t\t// Roslyn may optimize MoveNext() by copying fields from the iterator class into local variables\n\t\t\t// at the beginning of MoveNext(). Undo this optimization.\n\t\t\tcontext.StepStartGroup(\"PropagateCopiesOfFields\");\n\t\t\tvar mutableFields = body.Descendants.OfType<LdFlda>().Where(ldflda => ldflda.Parent.OpCode != OpCode.LdObj).Select(ldflda => ldflda.Field).ToHashSet();\n\t\t\tfor (int i = 0; i < body.EntryPoint.Instructions.Count; i++)\n\t\t\t{\n\t\t\t\tif (body.EntryPoint.Instructions[i] is StLoc store\n\t\t\t\t\t&& store.Variable.IsSingleDefinition\n\t\t\t\t\t&& store.Value is LdObj ldobj\n\t\t\t\t\t&& ldobj.Target is LdFlda ldflda\n\t\t\t\t\t&& ldflda.Target.MatchLdThis())\n\t\t\t\t{\n\t\t\t\t\tif (!mutableFields.Contains(ldflda.Field))\n\t\t\t\t\t{\n\t\t\t\t\t\t// perform copy propagation: (unlike CopyPropagation.Propagate(), copy the ldobj arguments as well)\n\t\t\t\t\t\tforeach (var expr in store.Variable.LoadInstructions.ToArray())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\texpr.ReplaceWith(store.Value.Clone());\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbody.EntryPoint.Instructions.RemoveAt(i--);\n\t\t\t\t\t}\n\t\t\t\t\telse if (ldflda.Field.MemberDefinition == stateField.MemberDefinition)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tbreak; // unsupported: load of mutable field (other than state field)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbreak; // unknown instruction\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontext.StepEndGroup();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Convert the old body (of MoveNext function) to the new body (of decompiled iterator method).\n\t\t/// \n\t\t/// * Replace the sequence\n\t\t///       this.currentField = expr;\n\t\t///       this.state = N;\n\t\t///       return true;\n\t\t///     with:\n\t\t///       yield return expr;\n\t\t///       goto blockForState(N);\n\t\t///  * Replace the sequence:\n\t\t///       this._finally2();\n\t\t///       this._finally1();\n\t\t///       return false;\n\t\t///     with:\n\t\t///       yield break;\n\t\t///  * Reconstruct try-finally blocks from\n\t\t///      (on enter) this.state = N;\n\t\t///      (on exit)  this._finallyX();\n\t\t/// </summary>\n\t\tprivate BlockContainer ConvertBody(BlockContainer oldBody, StateRangeAnalysis rangeAnalysis)\n\t\t{\n\t\t\tvar blockStateMap = rangeAnalysis.GetBlockStateSetMapping(oldBody);\n\t\t\tBlockContainer newBody = new BlockContainer().WithILRange(oldBody);\n\t\t\t// create all new blocks so that they can be referenced by gotos\n\t\t\tfor (int blockIndex = 0; blockIndex < oldBody.Blocks.Count; blockIndex++)\n\t\t\t{\n\t\t\t\tnewBody.Blocks.Add(new Block().WithILRange(oldBody.Blocks[blockIndex]));\n\t\t\t}\n\t\t\t// convert contents of blocks\n\n\t\t\tfor (int i = 0; i < oldBody.Blocks.Count; i++)\n\t\t\t{\n\t\t\t\tvar oldBlock = oldBody.Blocks[i];\n\t\t\t\tvar newBlock = newBody.Blocks[i];\n\t\t\t\tforeach (var oldInst in oldBlock.Instructions)\n\t\t\t\t{\n\t\t\t\t\tcontext.CancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tif (oldInst.MatchStFld(out var target, out var field, out var value) && target.MatchLdThis())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (field.MemberDefinition.Equals(stateField))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (value.MatchLdcI4(out int newState))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// On state change, break up the block:\n\t\t\t\t\t\t\t\t// (this allows us to consider each block individually for try-finally reconstruction)\n\t\t\t\t\t\t\t\tnewBlock = SplitBlock(newBlock, oldInst);\n\t\t\t\t\t\t\t\t// We keep the state-changing instruction around (as first instruction of the new block)\n\t\t\t\t\t\t\t\t// for reconstructing the try-finallys. \n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tnewBlock.Instructions.Add(new InvalidExpression(\"Assigned non-constant to iterator.state field\").WithILRange(oldInst));\n\t\t\t\t\t\t\t\tReportError(newBlock.Instructions.Last());\n\t\t\t\t\t\t\t\tcontinue; // don't copy over this instruction, but continue with the basic block\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (field.MemberDefinition.Equals(currentField))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// create yield return\n\t\t\t\t\t\t\tnewBlock.Instructions.Add(new YieldReturn(value).WithILRange(oldInst));\n\t\t\t\t\t\t\tConvertBranchAfterYieldReturn(newBlock, oldBlock, oldInst.ChildIndex + 1);\n\t\t\t\t\t\t\tbreak; // we're done with this basic block\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (oldInst is Call call && call.Arguments.Count == 1 && call.Arguments[0].MatchLdThis()\n\t\t\t\t\t  && finallyMethodToStateRange.ContainsKey((IMethod)call.Method.MemberDefinition))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Break up the basic block on a call to a finally method\n\t\t\t\t\t\t// (this allows us to consider each block individually for try-finally reconstruction)\n\t\t\t\t\t\tnewBlock = SplitBlock(newBlock, oldInst);\n\t\t\t\t\t}\n\t\t\t\t\telse if (oldInst is TryFinally tryFinally && (isCompiledWithMono || isCompiledWithVisualBasic))\n\t\t\t\t\t{\n\t\t\t\t\t\t// with mono, we have to recurse into try-finally blocks\n\t\t\t\t\t\tvar oldTryBlock = (BlockContainer)tryFinally.TryBlock;\n\t\t\t\t\t\tvar sra = rangeAnalysis.CreateNestedAnalysis();\n\t\t\t\t\t\tsra.AssignStateRanges(oldTryBlock, LongSet.Universe);\n\t\t\t\t\t\ttryFinally.TryBlock = ConvertBody(oldTryBlock, sra);\n\t\t\t\t\t}\n\t\t\t\t\telse if (isCompiledWithLegacyVisualBasic && oldInst is IfInstruction ifInstruction &&\n\t\t\t\t\t\t\t\tifInstruction.FalseInst.MatchNop() &&\n\t\t\t\t\t\t\t\tifInstruction.Condition.MatchCompEquals(out var left, out var right) &&\n\t\t\t\t\t\t\t\tleft.MatchLdFld(out var ldThis, out var fld) && ldThis.MatchLdThis() &&\n\t\t\t\t\t\t\t\tfld.MemberDefinition.Equals(disposingField) &&\n\t\t\t\t\t\t\t\tright.MatchLdcI4(0))\n\t\t\t\t\t{\n\t\t\t\t\t\tnewBlock.Instructions.Add(ifInstruction.TrueInst);\n\t\t\t\t\t\tnewBlock.AddILRange(ifInstruction.TrueInst);\n\t\t\t\t\t\tUpdateBranchTargets(ifInstruction.TrueInst);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\t// copy over the instruction to the new block\n\t\t\t\t\tnewBlock.Instructions.Add(oldInst);\n\t\t\t\t\tnewBlock.AddILRange(oldInst);\n\t\t\t\t\tUpdateBranchTargets(oldInst);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Insert new artificial block as entry point, and jump to the initial state.\n\t\t\t// This causes the method to start directly at the first user code,\n\t\t\t// and the whole compiler-generated state-dispatching logic becomes unreachable code\n\t\t\t// and gets deleted.\n\t\t\tint initialState = isCompiledWithLegacyVisualBasic ? -1 : 0;\n\t\t\tnewBody.Blocks.Insert(0, new Block {\n\t\t\t\tInstructions = { MakeGoTo(initialState) }\n\t\t\t});\n\t\t\treturn newBody;\n\n\t\t\tvoid ConvertBranchAfterYieldReturn(Block newBlock, Block oldBlock, int pos)\n\t\t\t{\n\t\t\t\tBlock targetBlock;\n\t\t\t\tif (isCompiledWithMono && disposingField != null)\n\t\t\t\t{\n\t\t\t\t\t// Mono skips over the state assignment if 'this.disposing' is set:\n\t\t\t\t\t//      ...\n\t\t\t\t\t//      stfld $current(ldloc this, yield-expr)\n\t\t\t\t\t//  \tif (ldfld $disposing(ldloc this)) br IL_007c\n\t\t\t\t\t//  \tbr targetBlock\n\t\t\t\t\t//  }\n\t\t\t\t\t//  \n\t\t\t\t\t//  Block targetBlock (incoming: 1) {\n\t\t\t\t\t//  \tstfld $PC(ldloc this, ldc.i4 1)\n\t\t\t\t\t//  \tbr setSkipFinallyBodies\n\t\t\t\t\t//  }\n\t\t\t\t\t//  \n\t\t\t\t\t//  Block setSkipFinallyBodies (incoming: 2) {\n\t\t\t\t\t//  \tstloc skipFinallyBodies(ldc.i4 1)\n\t\t\t\t\t//  \tbr returnBlock\n\t\t\t\t\t//  }\n\t\t\t\t\tif (oldBlock.Instructions[pos].MatchIfInstruction(out var condition, out _)\n\t\t\t\t\t\t&& condition.MatchLdFld(out var condTarget, out var condField)\n\t\t\t\t\t\t&& condTarget.MatchLdThis() && condField.MemberDefinition.Equals(disposingField)\n\t\t\t\t\t\t&& oldBlock.Instructions[pos + 1].MatchBranch(out targetBlock)\n\t\t\t\t\t\t&& targetBlock.Parent == oldBlock.Parent)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Keep looking at the target block:\n\t\t\t\t\t\toldBlock = targetBlock;\n\t\t\t\t\t\tpos = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Visual Basic Compiler emits additional stores to variables.\n\t\t\t\tint? localNewState = null;\n\t\t\t\tif (oldBlock.Instructions[pos].MatchStLoc(out _, out var value) && value is LdcI4 ldci4)\n\t\t\t\t{\n\t\t\t\t\tlocalNewState = ldci4.Value;\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\n\t\t\t\tif (oldBlock.Instructions[pos].MatchStFld(out var target, out var field, out value)\n\t\t\t\t\t&& target.MatchLdThis()\n\t\t\t\t\t&& field.MemberDefinition == stateField\n\t\t\t\t\t&& value.MatchLdcI4(out int newState)\n\t\t\t\t\t&& (localNewState is null || localNewState == newState))\n\t\t\t\t{\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tnewBlock.Instructions.Add(new InvalidBranch(\"Unable to find new state assignment for yield return\"));\n\t\t\t\t\tReportError(newBlock.Instructions.Last());\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// Mono may have 'br setSkipFinallyBodies' here, so follow the branch\n\t\t\t\tif (oldBlock.Instructions[pos].MatchBranch(out targetBlock) && targetBlock.Parent == oldBlock.Parent)\n\t\t\t\t{\n\t\t\t\t\toldBlock = targetBlock;\n\t\t\t\t\tpos = 0;\n\t\t\t\t}\n\t\t\t\tif (oldBlock.Instructions[pos].MatchStLoc(skipFinallyBodies, out value))\n\t\t\t\t{\n\t\t\t\t\tif (!value.MatchLdcI4(1))\n\t\t\t\t\t{\n\t\t\t\t\t\tnewBlock.Instructions.Add(new InvalidExpression {\n\t\t\t\t\t\t\tExpectedResultType = StackType.Void,\n\t\t\t\t\t\t\tMessage = \"Unexpected assignment to skipFinallyBodies\"\n\t\t\t\t\t\t});\n\t\t\t\t\t\tReportError(newBlock.Instructions.Last());\n\t\t\t\t\t}\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t\t// We can't use MatchStLoc like above since the doFinallyBodies variable is split by SplitVariables.\n\t\t\t\t// This occurs for the Legacy VBC compiler.\n\t\t\t\tif (oldBlock.Instructions[pos].MatchStLoc(out var var, out value) && var.Kind == VariableKind.Local && var.Index == doFinallyBodies?.Index)\n\t\t\t\t{\n\t\t\t\t\tif (!value.MatchLdcI4(0))\n\t\t\t\t\t{\n\t\t\t\t\t\tnewBlock.Instructions.Add(new InvalidExpression {\n\t\t\t\t\t\t\tExpectedResultType = StackType.Void,\n\t\t\t\t\t\t\tMessage = \"Unexpected assignment to doFinallyBodies\"\n\t\t\t\t\t\t});\n\t\t\t\t\t\tReportError(newBlock.Instructions.Last());\n\t\t\t\t\t}\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\n\t\t\t\tif (oldBlock.Instructions[pos].MatchReturn(out var retVal) && retVal.MatchLdcI4(1))\n\t\t\t\t{\n\t\t\t\t\t// OK, found return directly after state assignment\n\t\t\t\t}\n\t\t\t\telse if (oldBlock.Instructions[pos].MatchBranch(out targetBlock)\n\t\t\t\t  && targetBlock.Instructions[0].MatchReturn(out retVal) && retVal.MatchLdcI4(1))\n\t\t\t\t{\n\t\t\t\t\t// OK, jump to common return block (e.g. on Mono)\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tnewBlock.Instructions.Add(new InvalidBranch(\"Unable to find 'return true' for yield return\"));\n\t\t\t\t\tReportError(newBlock.Instructions.Last());\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tnewBlock.Instructions.Add(MakeGoTo(newState));\n\t\t\t}\n\n\t\t\tBlock SplitBlock(Block newBlock, ILInstruction oldInst)\n\t\t\t{\n\t\t\t\tif (newBlock.Instructions.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tvar newBlock2 = new Block();\n\t\t\t\t\tnewBlock2.AddILRange(new Interval(oldInst.StartILOffset, oldInst.StartILOffset));\n\t\t\t\t\tnewBody.Blocks.Add(newBlock2);\n\t\t\t\t\tnewBlock.Instructions.Add(new Branch(newBlock2));\n\t\t\t\t\tnewBlock = newBlock2;\n\t\t\t\t}\n\t\t\t\treturn newBlock;\n\t\t\t}\n\n\t\t\tILInstruction MakeGoTo(int v)\n\t\t\t{\n\t\t\t\tBlock targetBlock = blockStateMap.GetOrDefault(v);\n\t\t\t\tif (targetBlock != null)\n\t\t\t\t{\n\t\t\t\t\tif (targetBlock.Parent == oldBody)\n\t\t\t\t\t\treturn new Branch(newBody.Blocks[targetBlock.ChildIndex]);\n\t\t\t\t\telse\n\t\t\t\t\t\treturn new Branch(targetBlock);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar err = new InvalidBranch(\"Could not find block for state \" + v);\n\t\t\t\t\tReportError(err);\n\t\t\t\t\treturn err;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid UpdateBranchTargets(ILInstruction inst)\n\t\t\t{\n\t\t\t\tswitch (inst)\n\t\t\t\t{\n\t\t\t\t\tcase Branch branch:\n\t\t\t\t\t\tif (branch.TargetContainer == oldBody)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbranch.TargetBlock = newBody.Blocks[branch.TargetBlock.ChildIndex];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase Leave leave:\n\t\t\t\t\t\tif (leave.MatchReturn(out var value))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbool validYieldBreak = value.MatchLdcI4(0);\n\t\t\t\t\t\t\tif (value.MatchLdLoc(out var v)\n\t\t\t\t\t\t\t\t&& (v.Kind == VariableKind.Local || v.Kind == VariableKind.StackSlot)\n\t\t\t\t\t\t\t\t&& v.StoreInstructions.All(store => store is StLoc stloc && stloc.Value.MatchLdcI4(0)))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvalidYieldBreak = true;\n\t\t\t\t\t\t\t\treturnStores.AddRange(v.StoreInstructions.Cast<StLoc>());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (validYieldBreak)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// yield break\n\t\t\t\t\t\t\t\tleave.ReplaceWith(new Leave(newBody).WithILRange(leave));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// don't treat this as an error, it might just be unreachable code that will be removed soon\n\t\t\t\t\t\t\t\t// (occurs with mcs yield return)\n\t\t\t\t\t\t\t\tleave.ReplaceWith(new InvalidBranch(\"Unexpected return in MoveNext()\").WithILRange(leave));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (leave.TargetContainer == oldBody)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tleave.TargetContainer = newBody;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tforeach (var child in inst.Children)\n\t\t\t\t{\n\t\t\t\t\tUpdateBranchTargets(child);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid ReportError(ILInstruction inst)\n\t\t\t{\n\t\t\t\t// ConvertBody is still called within the try-catch, so we can throw SymbolicAnalysisFailedException\n\t\t\t\t// to suppress conversion of the state machine altogether.\n\t\t\t\t// We still initially create an instruction before converting a to an exception,\n\t\t\t\t// so that the body of this function can be commented out for testing purposes.\n\t\t\t\t// (this allows seeing where exactly the error occurs in the converted body output)\n\t\t\t\tstring message = \"ConvertBody error\";\n\t\t\t\tif (inst is InvalidBranch invalidBranch)\n\t\t\t\t\tmessage = invalidBranch.Message;\n\t\t\t\telse if (inst is InvalidExpression invalidExpr)\n\t\t\t\t\tmessage = invalidExpr.Message;\n\t\t\t\tthrow new SymbolicAnalysisFailedException(message);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region TranslateFieldsToLocalAccess\n\t\t/// <summary>\n\t\t/// Translates all field accesses in `function` to local variable accesses.\n\t\t/// </summary>\n\t\tinternal static void TranslateFieldsToLocalAccess(ILFunction function, ILInstruction inst, Dictionary<IField, ILVariable> fieldToVariableMap, bool isCompiledWithMono = false)\n\t\t{\n\t\t\tif (inst is LdFlda ldflda && ldflda.Target.MatchLdThis())\n\t\t\t{\n\t\t\t\tvar fieldDef = (IField)ldflda.Field.MemberDefinition;\n\t\t\t\tif (!fieldToVariableMap.TryGetValue(fieldDef, out var v))\n\t\t\t\t{\n\t\t\t\t\tstring name = null;\n\t\t\t\t\tif (!string.IsNullOrEmpty(fieldDef.Name) && fieldDef.Name[0] == '<')\n\t\t\t\t\t{\n\t\t\t\t\t\tint pos = fieldDef.Name.IndexOf('>');\n\t\t\t\t\t\tif (pos > 1)\n\t\t\t\t\t\t\tname = fieldDef.Name.Substring(1, pos - 1);\n\t\t\t\t\t}\n\t\t\t\t\tv = function.RegisterVariable(VariableKind.Local, ldflda.Field.ReturnType, name);\n\t\t\t\t\tv.InitialValueIsInitialized = true; // the field was default-initialized, so keep those semantics for the variable\n\t\t\t\t\tv.UsesInitialValue = true;\n\t\t\t\t\tv.StateMachineField = ldflda.Field;\n\t\t\t\t\tfieldToVariableMap.Add(fieldDef, v);\n\t\t\t\t}\n\t\t\t\tif (v.StackType == StackType.Ref)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(v.Kind == VariableKind.Parameter && v.Index < 0); // this pointer\n\t\t\t\t\tinst.ReplaceWith(new LdLoc(v).WithILRange(inst));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tinst.ReplaceWith(new LdLoca(v).WithILRange(inst));\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (!isCompiledWithMono && inst.MatchLdThis())\n\t\t\t{\n\t\t\t\tinst.ReplaceWith(new InvalidExpression(\"stateMachine\") { ExpectedResultType = inst.ResultType }.WithILRange(inst));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tforeach (var child in inst.Children)\n\t\t\t\t{\n\t\t\t\t\tTranslateFieldsToLocalAccess(function, child, fieldToVariableMap, isCompiledWithMono);\n\t\t\t\t}\n\t\t\t\tif (inst is LdObj ldobj && ldobj.Target is LdLoca ldloca && ldloca.Variable.StateMachineField != null)\n\t\t\t\t{\n\t\t\t\t\tLdLoc ldloc = new LdLoc(ldloca.Variable);\n\t\t\t\t\tldloc.AddILRange(ldobj);\n\t\t\t\t\tldloc.AddILRange(ldloca);\n\t\t\t\t\tinst.ReplaceWith(ldloc);\n\t\t\t\t}\n\t\t\t\telse if (inst is StObj stobj && stobj.Target is LdLoca ldloca2 && ldloca2.Variable.StateMachineField != null)\n\t\t\t\t{\n\t\t\t\t\tStLoc stloc = new StLoc(ldloca2.Variable, stobj.Value);\n\t\t\t\t\tstloc.AddILRange(stobj);\n\t\t\t\t\tstloc.AddILRange(ldloca2);\n\t\t\t\t\tinst.ReplaceWith(stloc);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region DecompileFinallyBlocks\n\t\tvoid DecompileFinallyBlocks()\n\t\t{\n\t\t\tforeach (var method in finallyMethodToStateRange.Keys)\n\t\t\t{\n\t\t\t\tvar function = CreateILAst((MethodDefinitionHandle)method.MetadataToken, context);\n\t\t\t\tvar body = (BlockContainer)function.Body;\n\t\t\t\tvar newState = GetNewState(body.EntryPoint);\n\t\t\t\tif (newState != null)\n\t\t\t\t{\n\t\t\t\t\tbody.EntryPoint.Instructions.RemoveAt(0);\n\t\t\t\t}\n\t\t\t\t// Avoid yield-return decompilation if there are unrecognized state assignments in a finally method.\n\t\t\t\tforeach (var inst in body.Descendants)\n\t\t\t\t{\n\t\t\t\t\tif (IsStateAssignment(inst))\n\t\t\t\t\t\tthrow new SymbolicAnalysisFailedException($\"Unknown state transition in {function.Name ?? \"finally\"} at IL_{inst.StartILOffset:x4}\");\n\t\t\t\t}\n\t\t\t\tfunction.ReleaseRef(); // make body reusable outside of function\n\t\t\t\tdecompiledFinallyMethods.Add(method, (newState, function));\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Reconstruct try-finally blocks\n\n\t\t/// <summary>\n\t\t/// Reconstruct try-finally blocks.\n\t\t/// * The stateChanges (iterator._state = N;) tell us when to open a try-finally block\n\t\t/// * The calls to the finally method tell us when to leave the try block.\n\t\t/// \n\t\t/// There might be multiple stateChanges for a given try-finally block, e.g.\n\t\t/// both the original entry point, and the target when leaving a nested block.\n\t\t/// In proper C# code, the entry point of the try-finally will dominate all other code\n\t\t/// in the try-block, so we can use dominance to find the proper entry point.\n\t\t/// \n\t\t/// Precondition: the blocks in newBody are topologically sorted.\n\t\t/// </summary>\n\t\tvoid ReconstructTryFinallyBlocks(ILFunction iteratorFunction)\n\t\t{\n\t\t\tBlockContainer newBody = (BlockContainer)iteratorFunction.Body;\n\t\t\tcontext.Step(\"Reconstuct try-finally blocks\", newBody);\n\t\t\tvar blockState = new int[newBody.Blocks.Count];\n\t\t\tblockState[0] = -1;\n\t\t\tvar stateToContainer = new Dictionary<int, BlockContainer>();\n\t\t\tstateToContainer.Add(-1, newBody);\n\t\t\t// First, analyse the newBody: for each block, determine the active state number.\n\t\t\tforeach (var block in newBody.Blocks)\n\t\t\t{\n\t\t\t\tcontext.CancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tint oldState = blockState[block.ChildIndex];\n\t\t\t\tBlockContainer container; // new container for the block\n\t\t\t\tif (GetNewState(block) is int newState)\n\t\t\t\t{\n\t\t\t\t\t// OK, state change\n\t\t\t\t\t// Remove the state-changing instruction\n\t\t\t\t\tblock.Instructions.RemoveAt(0);\n\n\t\t\t\t\tif (!stateToContainer.TryGetValue(newState, out container))\n\t\t\t\t\t{\n\t\t\t\t\t\t// First time we see this state.\n\t\t\t\t\t\t// This means we just found the entry point of a try block.\n\t\t\t\t\t\tCreateTryBlock(block, newState);\n\t\t\t\t\t\t// CreateTryBlock() wraps the contents of 'block' with a TryFinally.\n\t\t\t\t\t\t// We thus need to put the block (which now contains the whole TryFinally)\n\t\t\t\t\t\t// into the parent container.\n\t\t\t\t\t\t// Assuming a state transition never enters more than one state at once,\n\t\t\t\t\t\t// we can use stateToContainer[oldState] as parent.\n\t\t\t\t\t\tcontainer = stateToContainer[oldState];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Because newBody is topologically sorted we because we just removed unreachable code,\n\t\t\t\t\t// we can assume that blockState[] was already set for this block.\n\t\t\t\t\tnewState = oldState;\n\t\t\t\t\tcontainer = stateToContainer[oldState];\n\t\t\t\t}\n\t\t\t\tif (container != newBody)\n\t\t\t\t{\n\t\t\t\t\t// Move the block into the container.\n\t\t\t\t\tcontainer.Blocks.Add(block);\n\t\t\t\t\t// Keep the stale reference in newBody.Blocks for now, to avoid\n\t\t\t\t\t// changing the ChildIndex of the other blocks while we use it\n\t\t\t\t\t// to index the blockState array.\n\t\t\t\t}\n#if DEBUG\n\t\t\t\tblock.Instructions.Insert(0, new Nop { Comment = \"state == \" + newState });\n#endif\n\t\t\t\t// Propagate newState to successor blocks\n\t\t\t\tforeach (var branch in block.Descendants.OfType<Branch>())\n\t\t\t\t{\n\t\t\t\t\tif (branch.TargetBlock.Parent == newBody)\n\t\t\t\t\t{\n\t\t\t\t\t\tint stateAfterBranch = newState;\n\t\t\t\t\t\tif (Block.GetPredecessor(branch) is Call call\n\t\t\t\t\t\t\t&& call.Arguments.Count == 1 && call.Arguments[0].MatchLdThis()\n\t\t\t\t\t\t\t&& call.Method.Name == \"System.IDisposable.Dispose\")\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// pre-roslyn compiles \"yield break;\" into \"Dispose(); goto return_false;\",\n\t\t\t\t\t\t\t// so convert the dispose call into a state transition to the final state\n\t\t\t\t\t\t\tstateAfterBranch = -1;\n\t\t\t\t\t\t\tcall.ReplaceWith(new Nop() { Comment = \"Dispose call\" });\n\t\t\t\t\t\t}\n\t\t\t\t\t\tDebug.Assert(blockState[branch.TargetBlock.ChildIndex] == stateAfterBranch || blockState[branch.TargetBlock.ChildIndex] == 0);\n\t\t\t\t\t\tblockState[branch.TargetBlock.ChildIndex] = stateAfterBranch;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tnewBody.Blocks.RemoveAll(b => b.Parent != newBody);\n\n\t\t\tvoid CreateTryBlock(Block block, int state)\n\t\t\t{\n\t\t\t\tvar finallyMethod = FindFinallyMethod(state);\n\t\t\t\tif (finallyMethod != null)\n\t\t\t\t{\n\t\t\t\t\t// remove the method so that it doesn't cause ambiguity when processing nested try-finally blocks\n\t\t\t\t\tfinallyMethodToStateRange.Remove(finallyMethod);\n\t\t\t\t}\n\n\t\t\t\tvar tryBlock = new Block();\n\t\t\t\ttryBlock.AddILRange(block);\n\t\t\t\ttryBlock.Instructions.AddRange(block.Instructions);\n\t\t\t\tvar tryBlockContainer = new BlockContainer();\n\t\t\t\ttryBlockContainer.Blocks.Add(tryBlock);\n\t\t\t\ttryBlockContainer.AddILRange(tryBlock);\n\t\t\t\tstateToContainer.Add(state, tryBlockContainer);\n\n\t\t\t\tILInstruction finallyBlock;\n\t\t\t\tif (finallyMethod == null)\n\t\t\t\t{\n\t\t\t\t\tfinallyBlock = new InvalidBranch($\"Could not find finallyMethod for state={state}.\\n\" +\n\t\t\t\t\t\t$\"Possibly this method is affected by a C# compiler bug that causes the finally body\\n\" +\n\t\t\t\t\t\t$\"not to run in case of an exception or early 'break;' out of a loop consuming this iterable.\");\n\t\t\t\t}\n\t\t\t\telse if (decompiledFinallyMethods.TryGetValue(finallyMethod, out var decompiledMethod))\n\t\t\t\t{\n\t\t\t\t\tfinallyBlock = decompiledMethod.function.Body;\n\t\t\t\t\tvar vars = decompiledMethod.function.Variables.ToArray();\n\t\t\t\t\tdecompiledMethod.function.Variables.Clear();\n\t\t\t\t\titeratorFunction.Variables.AddRange(vars);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfinallyBlock = new InvalidBranch(\"Missing decompiledFinallyMethod\");\n\t\t\t\t}\n\n\t\t\t\tblock.Instructions.Clear();\n\t\t\t\tblock.Instructions.Add(new TryFinally(tryBlockContainer, finallyBlock).WithILRange(tryBlockContainer));\n\t\t\t}\n\n\t\t\tIMethod FindFinallyMethod(int state)\n\t\t\t{\n\t\t\t\tIMethod foundMethod = null;\n\t\t\t\tforeach (var (method, stateRange) in finallyMethodToStateRange)\n\t\t\t\t{\n\t\t\t\t\tif (stateRange.Contains(state))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (foundMethod == null)\n\t\t\t\t\t\t\tfoundMethod = method;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tDebug.Fail(\"Ambiguous finally method for state \" + state);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn foundMethod;\n\t\t\t}\n\t\t}\n\n\t\tbool IsStateAssignment(ILInstruction inst)\n\t\t{\n\t\t\treturn inst.MatchStFld(out var target, out var field, out _)\n\t\t\t\t&& target.MatchLdThis()\n\t\t\t\t&& field.MemberDefinition.Equals(stateField);\n\t\t}\n\n\t\t// Gets the state that is transitioned to at the start of the block\n\t\tint? GetNewState(Block block)\n\t\t{\n\t\t\tif (block.Instructions[0].MatchStFld(out var target, out var field, out var value)\n\t\t\t\t&& target.MatchLdThis()\n\t\t\t\t&& field.MemberDefinition.Equals(stateField)\n\t\t\t\t&& value.MatchLdcI4(out int newState))\n\t\t\t{\n\t\t\t\treturn newState;\n\t\t\t}\n\t\t\telse if (block.Instructions[0] is Call call\n\t\t\t  && call.Arguments.Count == 1 && call.Arguments[0].MatchLdThis()\n\t\t\t  && decompiledFinallyMethods.TryGetValue((IMethod)call.Method.MemberDefinition, out var finallyMethod))\n\t\t\t{\n\t\t\t\treturn finallyMethod.outerState;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\t#endregion\n\n\t\t#region Cleanup finally blocks\n\n\t\t/// <summary>\n\t\t/// Eliminates usage of doFinallyBodies\n\t\t/// </summary>\n\t\tprivate void CleanSkipFinallyBodies(ILFunction function)\n\t\t{\n\t\t\tif (skipFinallyBodies == null)\n\t\t\t{\n\t\t\t\treturn; // only mono-compiled code uses skipFinallyBodies\n\t\t\t}\n\t\t\tcontext.StepStartGroup(\"CleanFinallyBlocks\", function);\n\t\t\tif (skipFinallyBodies.StoreInstructions.Count != 0 || skipFinallyBodies.AddressCount != 0)\n\t\t\t{\n\t\t\t\t// misdetected another variable as skipFinallyBodies?\n\t\t\t\t// Fortunately removing the initial store of 0 is harmless, as we\n\t\t\t\t// default-initialize the variable on uninit uses\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tforeach (var tryFinally in function.Descendants.OfType<TryFinally>())\n\t\t\t{\n\t\t\t\tif (!(tryFinally.FinallyBlock is BlockContainer container))\n\t\t\t\t\tcontinue;\n\t\t\t\tBlock entryPoint = AsyncAwaitDecompiler.GetBodyEntryPoint(container);\n\t\t\t\tif (entryPoint?.Instructions[0] is IfInstruction ifInst)\n\t\t\t\t{\n\t\t\t\t\tif (ifInst.Condition.MatchLogicNot(out var logicNotArg) && logicNotArg.MatchLdLoc(skipFinallyBodies))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontext.Step(\"Remove if (skipFinallyBodies) from try-finally\", tryFinally);\n\t\t\t\t\t\t// condition will always be true now that we're using 'yield' instructions\n\t\t\t\t\t\tentryPoint.Instructions[0] = ifInst.TrueInst;\n\t\t\t\t\t\tentryPoint.Instructions.RemoveRange(1, entryPoint.Instructions.Count - 1);\n\t\t\t\t\t\t// find new entryPoint after the old one was modified\n\t\t\t\t\t\tentryPoint = AsyncAwaitDecompiler.GetBodyEntryPoint(container);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (entryPoint?.Instructions.Count == 2\n\t\t\t\t\t&& IsCallToMonoFinallyMethod(entryPoint.Instructions[0] as Call, out var finallyMethod)\n\t\t\t\t\t&& entryPoint.Instructions[1].MatchLeave((BlockContainer)tryFinally.FinallyBlock))\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"Inline \" + finallyMethod.FullName + \" into finally\", tryFinally);\n\t\t\t\t\tvar finallyFunction = CreateILAst((MethodDefinitionHandle)finallyMethod.MetadataToken, context);\n\t\t\t\t\ttryFinally.FinallyBlock = finallyFunction.Body;\n\t\t\t\t\tvar variables = finallyFunction.Variables.ToArray();\n\t\t\t\t\tfinallyFunction.Variables.Clear();\n\t\t\t\t\tfunction.Variables.AddRange(variables);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontext.StepEndGroup(keepIfEmpty: true);\n\n\t\t\tbool IsCallToMonoFinallyMethod(Call call, out IMethod finallyMethod)\n\t\t\t{\n\t\t\t\tfinallyMethod = default;\n\t\t\t\tif (call == null)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(call.Arguments.Count == 1 && call.Arguments[0].MatchLdThis()))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!call.Method.Name.StartsWith(\"<>__Finally\"))\n\t\t\t\t\treturn false;\n\t\t\t\tITypeDefinition declaringTypeDefinition = call.Method.DeclaringTypeDefinition;\n\t\t\t\tif (declaringTypeDefinition.MetadataToken != this.enumeratorType)\n\t\t\t\t\treturn false;\n\t\t\t\tif (declaringTypeDefinition.ParentModule.MetadataFile.Metadata != metadata)\n\t\t\t\t\treturn false;\n\t\t\t\tfinallyMethod = call.Method;\n\t\t\t\treturn !call.Method.MetadataToken.IsNil;\n\t\t\t}\n\t\t}\n\n\t\tprivate void CleanDoFinallyBodies(ILFunction function)\n\t\t{\n\t\t\tif (doFinallyBodies == null)\n\t\t\t{\n\t\t\t\treturn; // only VB code uses doFinallyBodies\n\t\t\t}\n\t\t\tcontext.StepStartGroup(\"CleanDoFinallyBodies\", function);\n\t\t\tif (doFinallyBodies.StoreInstructions.Count != 0 || doFinallyBodies.AddressCount != 0)\n\t\t\t{\n\t\t\t\t// misdetected another variable as skipFinallyBodies?\n\t\t\t\t// Fortunately removing the initial store of 0 is harmless, as we\n\t\t\t\t// default-initialize the variable on uninit uses\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tforeach (var tryFinally in function.Descendants.OfType<TryFinally>())\n\t\t\t{\n\t\t\t\tif (!(tryFinally.FinallyBlock is BlockContainer container))\n\t\t\t\t\tcontinue;\n\t\t\t\tBlock entryPoint = AsyncAwaitDecompiler.GetBodyEntryPoint(container);\n\t\t\t\tif (entryPoint?.Instructions[0] is IfInstruction ifInst)\n\t\t\t\t{\n\t\t\t\t\tif (ifInst.Condition.MatchCompEquals(out var left, out var right) && left.MatchLdLoc(doFinallyBodies) && right.MatchLdcI4(0))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontext.Step(\"Remove if (doFinallyBodies) from try-finally\", tryFinally);\n\t\t\t\t\t\t// condition will always be false now that we're using 'yield' instructions\n\t\t\t\t\t\tentryPoint.Instructions.RemoveAt(0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tforeach (LdLoc load in doFinallyBodies.LoadInstructions.ToArray())\n\t\t\t{\n\t\t\t\tload.ReplaceWith(new LdcI4(1).WithILRange(load));\n\t\t\t}\n\t\t\tcontext.StepEndGroup(keepIfEmpty: true);\n\t\t}\n\n\t\tprivate void CleanFinallyStateChecks(ILFunction function)\n\t\t{\n\t\t\tcontext.StepStartGroup(\"CleanFinallyStateChecks\", function);\n\t\t\tforeach (var tryFinally in function.Descendants.OfType<TryFinally>())\n\t\t\t{\n\t\t\t\tif (!(tryFinally.FinallyBlock is BlockContainer container))\n\t\t\t\t\tcontinue;\n\t\t\t\tBlock entryPoint = AsyncAwaitDecompiler.GetBodyEntryPoint(container);\n\t\t\t\tif (entryPoint?.Instructions[0] is IfInstruction ifInst)\n\t\t\t\t{\n\t\t\t\t\tif (ifInst.Condition is Comp comp && comp.Kind == ComparisonKind.GreaterThanOrEqual &&\n\t\t\t\t\t\tcomp.InputType == StackType.I4 && comp.Sign == Sign.Signed && comp.Left.MatchLdLoc(out var variable) &&\n\t\t\t\t\t\tcachedStateVars.Contains(variable) &&\n\t\t\t\t\t\tcomp.Right.MatchLdcI4(0))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontext.Step(\"Remove if (stateVar >= 0) from try-finally\", tryFinally);\n\t\t\t\t\t\t// condition will always be false now that we're using 'yield' instructions\n\t\t\t\t\t\tentryPoint.Instructions.RemoveAt(0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontext.StepEndGroup(keepIfEmpty: true);\n\t\t}\n\n\t\t#endregion\n\n\t\tbool IsMethod(MethodDefinitionHandle method, string name)\n\t\t{\n\t\t\tvar methodDefinition = metadata.GetMethodDefinition(method);\n\t\t\tif (metadata.GetString(methodDefinition.Name) == name)\n\t\t\t\treturn true;\n\t\t\tforeach (var implHandle in method.GetMethodImplementations(metadata))\n\t\t\t{\n\t\t\t\tvar impl = metadata.GetMethodImplementation(implHandle);\n\t\t\t\tswitch (impl.MethodDeclaration.Kind)\n\t\t\t\t{\n\t\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\t\tvar md = metadata.GetMethodDefinition((MethodDefinitionHandle)impl.MethodDeclaration);\n\t\t\t\t\t\tif (metadata.GetString(md.Name) != name)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tcase HandleKind.MemberReference:\n\t\t\t\t\t\tvar mr = metadata.GetMemberReference((MemberReferenceHandle)impl.MethodDeclaration);\n\t\t\t\t\t\tif (mr.GetKind() != MemberReferenceKind.Method)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tif (metadata.GetString(mr.Name) != name)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ILAmbience.cs",
    "content": "// Copyright (c) Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Output;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\n#nullable enable\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpublic class ILAmbience : IAmbience\n\t{\n\t\tpublic ConversionFlags ConversionFlags { get; set; }\n\n\t\tpublic string ConvertConstantValue(object constantValue)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tpublic string ConvertSymbol(ISymbol symbol)\n\t\t{\n\t\t\tStringWriter sw = new StringWriter();\n\n\t\t\tConvertSymbol(sw, symbol);\n\n\t\t\treturn sw.ToString();\n\t\t}\n\n\t\tvoid ConvertSymbol(StringWriter writer, ISymbol symbol)\n\t\t{\n\t\t\tvar metadata = (symbol as IEntity)?.ParentModule!.MetadataFile?.Metadata;\n\t\t\tvar token = (symbol as IEntity)?.MetadataToken ?? default;\n\n\t\t\tvar output = new PlainTextOutput(writer);\n\n\t\t\tswitch (symbol)\n\t\t\t{\n\t\t\t\tcase IField f:\n\t\t\t\t\tDebug.Assert(metadata != null);\n\t\t\t\t\tif (ConversionFlags.HasFlag(ConversionFlags.ShowDefinitionKeyword))\n\t\t\t\t\t\twriter.Write(\".field \");\n\t\t\t\t\tvar fd = metadata.GetFieldDefinition((FieldDefinitionHandle)token);\n\t\t\t\t\tif (ConversionFlags.HasFlag(ConversionFlags.ShowAccessibility))\n\t\t\t\t\t\tReflectionDisassembler.WriteEnum(fd.Attributes & FieldAttributes.FieldAccessMask, ReflectionDisassembler.fieldVisibility, output);\n\t\t\t\t\tif (ConversionFlags.HasFlag(ConversionFlags.ShowModifiers))\n\t\t\t\t\t{\n\t\t\t\t\t\tconst FieldAttributes hasXAttributes = FieldAttributes.HasDefault | FieldAttributes.HasFieldMarshal | FieldAttributes.HasFieldRVA;\n\t\t\t\t\t\tReflectionDisassembler.WriteFlags(fd.Attributes & ~(FieldAttributes.FieldAccessMask | hasXAttributes), ReflectionDisassembler.fieldAttributes, output);\n\t\t\t\t\t\tif (!f.IsStatic)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\twriter.Write(\"instance \");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase IMethod m:\n\t\t\t\t\tDebug.Assert(metadata != null);\n\t\t\t\t\tif (ConversionFlags.HasFlag(ConversionFlags.ShowDefinitionKeyword))\n\t\t\t\t\t\twriter.Write(\".method \");\n\t\t\t\t\tvar md = metadata.GetMethodDefinition((MethodDefinitionHandle)token);\n\t\t\t\t\tif (ConversionFlags.HasFlag(ConversionFlags.ShowAccessibility))\n\t\t\t\t\t\tReflectionDisassembler.WriteEnum(md.Attributes & MethodAttributes.MemberAccessMask, ReflectionDisassembler.methodVisibility, output);\n\t\t\t\t\tif (ConversionFlags.HasFlag(ConversionFlags.ShowModifiers))\n\t\t\t\t\t{\n\t\t\t\t\t\tReflectionDisassembler.WriteFlags(md.Attributes & ~MethodAttributes.MemberAccessMask, ReflectionDisassembler.methodAttributeFlags, output);\n\t\t\t\t\t\tif (!m.IsStatic)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\twriter.Write(\"instance \");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase IProperty p:\n\t\t\t\t\tDebug.Assert(metadata != null);\n\t\t\t\t\tif (ConversionFlags.HasFlag(ConversionFlags.ShowDefinitionKeyword))\n\t\t\t\t\t\twriter.Write(\".property \");\n\t\t\t\t\tvar pd = metadata.GetPropertyDefinition((PropertyDefinitionHandle)token);\n\t\t\t\t\tif (ConversionFlags.HasFlag(ConversionFlags.ShowModifiers))\n\t\t\t\t\t{\n\t\t\t\t\t\tReflectionDisassembler.WriteFlags(pd.Attributes, ReflectionDisassembler.propertyAttributes, output);\n\t\t\t\t\t\tif (!p.IsStatic)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\twriter.Write(\"instance \");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase IEvent e:\n\t\t\t\t\tDebug.Assert(metadata != null);\n\t\t\t\t\tif (ConversionFlags.HasFlag(ConversionFlags.ShowDefinitionKeyword))\n\t\t\t\t\t\twriter.Write(\".event \");\n\t\t\t\t\tvar ed = metadata.GetEventDefinition((EventDefinitionHandle)token);\n\t\t\t\t\tif (ConversionFlags.HasFlag(ConversionFlags.ShowModifiers))\n\t\t\t\t\t{\n\t\t\t\t\t\tReflectionDisassembler.WriteFlags(ed.Attributes, ReflectionDisassembler.eventAttributes, output);\n\t\t\t\t\t\tif (!e.IsStatic)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\twriter.Write(\"instance \");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase ITypeDefinition:\n\t\t\t\t\tDebug.Assert(metadata != null);\n\t\t\t\t\tvar td = metadata.GetTypeDefinition((TypeDefinitionHandle)token);\n\t\t\t\t\tif (ConversionFlags.HasFlag(ConversionFlags.ShowDefinitionKeyword))\n\t\t\t\t\t{\n\t\t\t\t\t\twriter.Write(\".class \");\n\t\t\t\t\t\tif (td.Attributes.HasFlag(TypeAttributes.Interface))\n\t\t\t\t\t\t\twriter.Write(\"interface \");\n\t\t\t\t\t}\n\t\t\t\t\tif (ConversionFlags.HasFlag(ConversionFlags.ShowAccessibility))\n\t\t\t\t\t\tReflectionDisassembler.WriteEnum(td.Attributes & TypeAttributes.VisibilityMask, ReflectionDisassembler.typeVisibility, output);\n\t\t\t\t\tconst TypeAttributes masks = TypeAttributes.ClassSemanticsMask | TypeAttributes.VisibilityMask | TypeAttributes.LayoutMask | TypeAttributes.StringFormatMask;\n\t\t\t\t\tif (ConversionFlags.HasFlag(ConversionFlags.ShowModifiers))\n\t\t\t\t\t\tReflectionDisassembler.WriteFlags(td.Attributes & ~masks, ReflectionDisassembler.typeAttributes, output);\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tbool showReturnTypeBefore = ConversionFlags.HasFlag(ConversionFlags.ShowReturnType)\n\t\t\t\t&& !ConversionFlags.HasFlag(ConversionFlags.PlaceReturnTypeAfterParameterList);\n\t\t\tbool showReturnTypeAfter = ConversionFlags.HasFlag(ConversionFlags.ShowReturnType)\n\t\t\t\t&& ConversionFlags.HasFlag(ConversionFlags.PlaceReturnTypeAfterParameterList);\n\n\t\t\tif (showReturnTypeBefore && symbol is IMember { SymbolKind: not SymbolKind.Constructor })\n\t\t\t{\n\t\t\t\tswitch (symbol)\n\t\t\t\t{\n\t\t\t\t\tcase IField f:\n\t\t\t\t\t\twriter.Write(ConvertType(f.ReturnType));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase IMethod m:\n\t\t\t\t\t\twriter.Write(ConvertType(m.ReturnType));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase IProperty p:\n\t\t\t\t\t\twriter.Write(ConvertType(p.ReturnType));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase IEvent e:\n\t\t\t\t\t\twriter.Write(ConvertType(e.ReturnType));\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\twriter.Write(' ');\n\t\t\t}\n\n\t\t\tvoid WriteTypeDefinition(ITypeDefinition typeDef)\n\t\t\t{\n\t\t\t\tif ((ConversionFlags.HasFlag(ConversionFlags.UseFullyQualifiedEntityNames)\n\t\t\t\t\t|| ConversionFlags.HasFlag(ConversionFlags.ShowDeclaringType))\n\t\t\t\t\t&& typeDef.DeclaringTypeDefinition != null)\n\t\t\t\t{\n\t\t\t\t\tWriteTypeDefinition(typeDef.DeclaringTypeDefinition);\n\t\t\t\t\twriter.Write('.');\n\t\t\t\t}\n\t\t\t\telse if (ConversionFlags.HasFlag(ConversionFlags.UseFullyQualifiedEntityNames)\n\t\t\t\t\t&& !string.IsNullOrEmpty(typeDef.Namespace))\n\t\t\t\t{\n\t\t\t\t\twriter.Write(typeDef.Namespace);\n\t\t\t\t\twriter.Write('.');\n\t\t\t\t}\n\t\t\t\twriter.Write(typeDef.Name);\n\t\t\t\tWriteTypeParameters(typeDef.TypeParameters, typeDef);\n\t\t\t}\n\n\t\t\tvoid WriteTypeParameters(IReadOnlyList<ITypeParameter> typeParameters, IEntity owner)\n\t\t\t{\n\t\t\t\tif (typeParameters.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tint typeParameterCount = typeParameters.Count - (owner.DeclaringTypeDefinition?.TypeParameterCount ?? 0);\n\t\t\t\t\tif (typeParameterCount > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tswitch (owner)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase IType:\n\t\t\t\t\t\t\t\twriter.Write(\"`\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase IMethod _:\n\t\t\t\t\t\t\t\twriter.Write(\"``\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\twriter.Write(typeParameterCount);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (ConversionFlags.HasFlag(ConversionFlags.ShowTypeParameterList))\n\t\t\t\t\t{\n\t\t\t\t\t\tint i = 0;\n\t\t\t\t\t\twriter.Write('<');\n\t\t\t\t\t\tforeach (var tp in typeParameters)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\t\t\twriter.Write(\",\");\n\t\t\t\t\t\t\tif (ConversionFlags.HasFlag(ConversionFlags.ShowTypeParameterVarianceModifier))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tswitch (tp.Variance)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tcase VarianceModifier.Covariant:\n\t\t\t\t\t\t\t\t\t\twriter.Write('+');\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase VarianceModifier.Contravariant:\n\t\t\t\t\t\t\t\t\t\twriter.Write('-');\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\twriter.Write(tp.Name);\n\t\t\t\t\t\t\ti++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\twriter.Write('>');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tswitch (symbol)\n\t\t\t{\n\t\t\t\tcase ITypeDefinition definition:\n\t\t\t\t\tWriteTypeDefinition(definition);\n\t\t\t\t\tbreak;\n\t\t\t\tcase IMember member:\n\t\t\t\t\tif ((ConversionFlags.HasFlag(ConversionFlags.UseFullyQualifiedTypeNames)\n\t\t\t\t\t|| ConversionFlags.HasFlag(ConversionFlags.ShowDeclaringType)) && member.DeclaringTypeDefinition != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tWriteTypeDefinition(member.DeclaringTypeDefinition);\n\t\t\t\t\t\twriter.Write(\"::\");\n\t\t\t\t\t}\n\t\t\t\t\twriter.Write(member.Name);\n\t\t\t\t\tif (member is IMethod method)\n\t\t\t\t\t{\n\t\t\t\t\t\tWriteTypeParameters(method.TypeParameters, member);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (ConversionFlags.HasFlag(ConversionFlags.ShowParameterList) && symbol is IParameterizedMember { SymbolKind: not SymbolKind.Property } pm)\n\t\t\t{\n\t\t\t\twriter.Write('(');\n\t\t\t\tint i = 0;\n\t\t\t\tforeach (var parameter in pm.Parameters)\n\t\t\t\t{\n\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\twriter.Write(\", \");\n\t\t\t\t\twriter.Write(ConvertType(parameter.Type));\n\t\t\t\t\tif (ConversionFlags.HasFlag(ConversionFlags.ShowParameterNames))\n\t\t\t\t\t\twriter.Write(\" \" + parameter.Name);\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t\twriter.Write(')');\n\t\t\t}\n\n\t\t\tif (showReturnTypeAfter && symbol is IMember { SymbolKind: not SymbolKind.Constructor })\n\t\t\t{\n\t\t\t\twriter.Write(\" : \");\n\n\t\t\t\tswitch (symbol)\n\t\t\t\t{\n\t\t\t\t\tcase IField f:\n\t\t\t\t\t\twriter.Write(ConvertType(f.ReturnType));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase IMethod m:\n\t\t\t\t\t\twriter.Write(ConvertType(m.ReturnType));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase IProperty p:\n\t\t\t\t\t\twriter.Write(ConvertType(p.ReturnType));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase IEvent e:\n\t\t\t\t\t\twriter.Write(ConvertType(e.ReturnType));\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic string ConvertType(IType type)\n\t\t{\n\t\t\tvar visitor = new TypeToStringVisitor(ConversionFlags);\n\t\t\ttype.AcceptVisitor(visitor);\n\t\t\treturn visitor.ToString();\n\t\t}\n\n\t\tclass TypeToStringVisitor : TypeVisitor\n\t\t{\n\t\t\treadonly ConversionFlags flags;\n\t\t\treadonly StringBuilder builder;\n\n\t\t\tpublic override string ToString()\n\t\t\t{\n\t\t\t\treturn builder.ToString();\n\t\t\t}\n\n\t\t\tpublic TypeToStringVisitor(ConversionFlags flags)\n\t\t\t{\n\t\t\t\tthis.flags = flags;\n\t\t\t\tthis.builder = new StringBuilder();\n\t\t\t}\n\n\t\t\tpublic override IType VisitArrayType(ArrayType type)\n\t\t\t{\n\t\t\t\tbase.VisitArrayType(type);\n\t\t\t\tbuilder.Append('[');\n\t\t\t\tbuilder.Append(',', type.Dimensions - 1);\n\t\t\t\tbuilder.Append(']');\n\t\t\t\treturn type;\n\t\t\t}\n\n\t\t\tpublic override IType VisitByReferenceType(ByReferenceType type)\n\t\t\t{\n\t\t\t\tbase.VisitByReferenceType(type);\n\t\t\t\tbuilder.Append('&');\n\t\t\t\treturn type;\n\t\t\t}\n\n\t\t\tpublic override IType VisitModOpt(ModifiedType type)\n\t\t\t{\n\t\t\t\ttype.ElementType.AcceptVisitor(this);\n\t\t\t\tbuilder.Append(\" modopt(\");\n\t\t\t\ttype.Modifier.AcceptVisitor(this);\n\t\t\t\tbuilder.Append(\")\");\n\t\t\t\treturn type;\n\t\t\t}\n\n\t\t\tpublic override IType VisitModReq(ModifiedType type)\n\t\t\t{\n\t\t\t\ttype.ElementType.AcceptVisitor(this);\n\t\t\t\tbuilder.Append(\" modreq(\");\n\t\t\t\ttype.Modifier.AcceptVisitor(this);\n\t\t\t\tbuilder.Append(\")\");\n\t\t\t\treturn type;\n\t\t\t}\n\n\t\t\tpublic override IType VisitPointerType(PointerType type)\n\t\t\t{\n\t\t\t\tbase.VisitPointerType(type);\n\t\t\t\tbuilder.Append('*');\n\t\t\t\treturn type;\n\t\t\t}\n\n\t\t\tpublic override IType VisitTypeParameter(ITypeParameter type)\n\t\t\t{\n\t\t\t\tbase.VisitTypeParameter(type);\n\t\t\t\tEscapeName(builder, type.Name);\n\t\t\t\treturn type;\n\t\t\t}\n\n\t\t\tpublic override IType VisitParameterizedType(ParameterizedType type)\n\t\t\t{\n\t\t\t\ttype.GenericType.AcceptVisitor(this);\n\t\t\t\tbuilder.Append('<');\n\t\t\t\tfor (int i = 0; i < type.TypeArguments.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\tbuilder.Append(',');\n\t\t\t\t\ttype.TypeArguments[i].AcceptVisitor(this);\n\t\t\t\t}\n\t\t\t\tbuilder.Append('>');\n\t\t\t\treturn type;\n\t\t\t}\n\n\t\t\tpublic override IType VisitTupleType(TupleType type)\n\t\t\t{\n\t\t\t\ttype.UnderlyingType.AcceptVisitor(this);\n\t\t\t\treturn type;\n\t\t\t}\n\n\t\t\tpublic override IType VisitFunctionPointerType(FunctionPointerType type)\n\t\t\t{\n\t\t\t\tbuilder.Append(\"method \");\n\t\t\t\tif (type.CallingConvention != SignatureCallingConvention.Default)\n\t\t\t\t{\n\t\t\t\t\tbuilder.Append(type.CallingConvention.ToILSyntax());\n\t\t\t\t\tbuilder.Append(' ');\n\t\t\t\t}\n\t\t\t\ttype.ReturnType.AcceptVisitor(this);\n\t\t\t\tbuilder.Append(\" *(\");\n\t\t\t\tbool first = true;\n\t\t\t\tforeach (var p in type.ParameterTypes)\n\t\t\t\t{\n\t\t\t\t\tif (first)\n\t\t\t\t\t\tfirst = false;\n\t\t\t\t\telse\n\t\t\t\t\t\tbuilder.Append(\", \");\n\n\t\t\t\t\tp.AcceptVisitor(this);\n\t\t\t\t}\n\t\t\t\tbuilder.Append(')');\n\t\t\t\treturn type;\n\t\t\t}\n\n\t\t\tpublic override IType VisitOtherType(IType type)\n\t\t\t{\n\t\t\t\tWriteType(type);\n\t\t\t\treturn type;\n\t\t\t}\n\n\t\t\tprivate void WriteType(IType type)\n\t\t\t{\n\t\t\t\tif (flags.HasFlag(ConversionFlags.UseFullyQualifiedTypeNames))\n\t\t\t\t\tEscapeName(builder, type.FullName);\n\t\t\t\telse\n\t\t\t\t\tEscapeName(builder, type.Name);\n\t\t\t\tif (type.TypeParameterCount > 0)\n\t\t\t\t{\n\t\t\t\t\tbuilder.Append('`');\n\t\t\t\t\tbuilder.Append(type.TypeParameterCount);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override IType VisitTypeDefinition(ITypeDefinition type)\n\t\t\t{\n\t\t\t\tswitch (type.KnownTypeCode)\n\t\t\t\t{\n\t\t\t\t\tcase KnownTypeCode.Object:\n\t\t\t\t\t\tbuilder.Append(\"object\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownTypeCode.Boolean:\n\t\t\t\t\t\tbuilder.Append(\"bool\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownTypeCode.Char:\n\t\t\t\t\t\tbuilder.Append(\"char\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownTypeCode.SByte:\n\t\t\t\t\t\tbuilder.Append(\"int8\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownTypeCode.Byte:\n\t\t\t\t\t\tbuilder.Append(\"uint8\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownTypeCode.Int16:\n\t\t\t\t\t\tbuilder.Append(\"int16\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownTypeCode.UInt16:\n\t\t\t\t\t\tbuilder.Append(\"uint16\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownTypeCode.Int32:\n\t\t\t\t\t\tbuilder.Append(\"int32\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownTypeCode.UInt32:\n\t\t\t\t\t\tbuilder.Append(\"uint32\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownTypeCode.Int64:\n\t\t\t\t\t\tbuilder.Append(\"int64\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownTypeCode.UInt64:\n\t\t\t\t\t\tbuilder.Append(\"uint64\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownTypeCode.Single:\n\t\t\t\t\t\tbuilder.Append(\"float32\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownTypeCode.Double:\n\t\t\t\t\t\tbuilder.Append(\"float64\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownTypeCode.String:\n\t\t\t\t\t\tbuilder.Append(\"string\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownTypeCode.Void:\n\t\t\t\t\t\tbuilder.Append(\"void\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownTypeCode.IntPtr:\n\t\t\t\t\t\tbuilder.Append(\"native int\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownTypeCode.UIntPtr:\n\t\t\t\t\t\tbuilder.Append(\"native uint\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownTypeCode.TypedReference:\n\t\t\t\t\t\tbuilder.Append(\"typedref\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tWriteType(type);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treturn type;\n\t\t\t}\n\t\t}\n\n\t\tpublic string WrapComment(string comment)\n\t\t{\n\t\t\treturn \"// \" + comment;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Escape characters that cannot be displayed in the UI.\n\t\t/// </summary>\n\t\tpublic static StringBuilder EscapeName(StringBuilder sb, string name)\n\t\t{\n\t\t\tforeach (char ch in name)\n\t\t\t{\n\t\t\t\tif (char.IsWhiteSpace(ch) || char.IsControl(ch) || char.IsSurrogate(ch))\n\t\t\t\t\tsb.AppendFormat(\"\\\\u{0:x4}\", (int)ch);\n\t\t\t\telse\n\t\t\t\t\tsb.Append(ch);\n\t\t\t}\n\t\t\treturn sb;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Escape characters that cannot be displayed in the UI.\n\t\t/// </summary>\n\t\tpublic static string EscapeName(string name)\n\t\t{\n\t\t\treturn EscapeName(new StringBuilder(name.Length), name).ToString();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ILAstWritingOptions.cs",
    "content": "#nullable enable\n// Copyright (c) 2017 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.ComponentModel;\nusing System.Runtime.CompilerServices;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpublic class ILAstWritingOptions : INotifyPropertyChanged\n\t{\n\t\tprivate bool useLogicOperationSugar;\n\t\tprivate bool useFieldSugar;\n\t\tprivate bool showILRanges;\n\t\tprivate bool showChildIndexInBlock;\n\n\t\t/// <summary>\n\t\t/// Sugar for logic.not/and/or.\n\t\t/// </summary>\n\t\tpublic bool UseLogicOperationSugar {\n\t\t\tget { return useLogicOperationSugar; }\n\t\t\tset {\n\t\t\t\tif (useLogicOperationSugar != value)\n\t\t\t\t{\n\t\t\t\t\tuseLogicOperationSugar = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Sugar for ldfld/stfld.\n\t\t/// </summary>\n\t\tpublic bool UseFieldSugar {\n\t\t\tget { return useFieldSugar; }\n\t\t\tset {\n\t\t\t\tif (useFieldSugar != value)\n\t\t\t\t{\n\t\t\t\t\tuseFieldSugar = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Show IL ranges in ILAst output.\n\t\t/// </summary>\n\t\tpublic bool ShowILRanges {\n\t\t\tget { return showILRanges; }\n\t\t\tset {\n\t\t\t\tif (showILRanges != value)\n\t\t\t\t{\n\t\t\t\t\tshowILRanges = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Show the child index of the instruction in ILAst output.\n\t\t/// </summary>\n\t\tpublic bool ShowChildIndexInBlock {\n\t\t\tget { return showChildIndexInBlock; }\n\t\t\tset {\n\t\t\t\tif (showChildIndexInBlock != value)\n\t\t\t\t{\n\t\t\t\t\tshowChildIndexInBlock = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)\n\t\t{\n\t\t\tOnPropertyChanged(new PropertyChangedEventArgs(propertyName));\n\t\t}\n\n\t\tprotected virtual void OnPropertyChanged(PropertyChangedEventArgs e)\n\t\t{\n\t\t\tPropertyChanged?.Invoke(this, e);\n\t\t}\n\n\t\tpublic event PropertyChangedEventHandler? PropertyChanged;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ILInstructionExtensions.cs",
    "content": "#nullable enable\nusing System;\nusing System.Collections.Generic;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tinternal static class ILInstructionExtensions\n\t{\n\t\tpublic static T WithILRange<T>(this T target, ILInstruction sourceInstruction) where T : ILInstruction\n\t\t{\n\t\t\ttarget.AddILRange(sourceInstruction);\n\t\t\treturn target;\n\t\t}\n\n\t\tpublic static T WithILRange<T>(this T target, Interval range) where T : ILInstruction\n\t\t{\n\t\t\ttarget.AddILRange(range);\n\t\t\treturn target;\n\t\t}\n\n\t\tpublic static ILInstruction? GetNextSibling(this ILInstruction? instruction)\n\t\t{\n\t\t\tif (instruction?.Parent == null)\n\t\t\t\treturn null;\n\t\t\tif (instruction.ChildIndex + 1 >= instruction.Parent.Children.Count)\n\t\t\t\treturn null;\n\t\t\treturn instruction.Parent.Children[instruction.ChildIndex + 1];\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ILReader.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nusing ArrayType = ICSharpCode.Decompiler.TypeSystem.ArrayType;\nusing ByReferenceType = ICSharpCode.Decompiler.TypeSystem.ByReferenceType;\nusing PinnedType = ICSharpCode.Decompiler.TypeSystem.Implementation.PinnedType;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// Reads IL bytecodes and converts them into ILAst instructions.\n\t/// </summary>\n\t/// <remarks>\n\t/// Instances of this class are not thread-safe. Use separate instances to decompile multiple members in parallel.\n\t/// </remarks>\n\tpublic class ILReader\n\t{\n\t\t/// <summary>\n\t\t/// Represents a block of IL instructions.\n\t\t/// </summary>\n\t\tprivate sealed class ImportedBlock\n\t\t{\n\t\t\t// These members are immediately available after construction:\n\t\t\tpublic readonly Block Block = new Block(BlockKind.ControlFlow);\n\t\t\tpublic ImmutableStack<ILVariable> InputStack;\n\n\t\t\tpublic int StartILOffset => Block.StartILOffset;\n\t\t\t/// True if the import is in progress or completed.\n\t\t\tpublic bool ImportStarted = false;\n\n\t\t\t// When the block is imported, Block.Instructions is filled with the imported instructions\n\t\t\t// and the following members are initialized:\n\t\t\tpublic List<(ImportedBlock, ImmutableStack<ILVariable>)> OutgoingEdges = new();\n\n\t\t\tpublic ImportedBlock(int offset, ImmutableStack<ILVariable> inputStack)\n\t\t\t{\n\t\t\t\tthis.InputStack = inputStack;\n\t\t\t\tthis.Block.AddILRange(new Interval(offset, offset));\n\t\t\t}\n\n\t\t\t/// <summary>\n\t\t\t/// Compares stack types and update InputStack if necessary.\n\t\t\t/// Returns true if InputStack was updated, making a reimport necessary.\n\t\t\t/// </summary>\n\t\t\tpublic bool MergeStackTypes(ImmutableStack<ILVariable> newEdge)\n\t\t\t{\n\t\t\t\tvar a = this.InputStack;\n\t\t\t\tvar b = newEdge;\n\t\t\t\tbool changed = false;\n\t\t\t\twhile (!a.IsEmpty && !b.IsEmpty)\n\t\t\t\t{\n\t\t\t\t\tif (a.Peek().StackType < b.Peek().StackType)\n\t\t\t\t\t{\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t}\n\t\t\t\t\ta = a.Pop();\n\t\t\t\t\tb = b.Pop();\n\t\t\t\t}\n\t\t\t\tif (!changed || !(a.IsEmpty && b.IsEmpty))\n\t\t\t\t\treturn false;\n\t\t\t\ta = this.InputStack;\n\t\t\t\tb = newEdge;\n\t\t\t\tvar output = new List<ILVariable>();\n\t\t\t\twhile (!a.IsEmpty && !b.IsEmpty)\n\t\t\t\t{\n\t\t\t\t\tif (a.Peek().StackType < b.Peek().StackType)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Add(b.Peek());\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Add(a.Peek());\n\t\t\t\t\t}\n\t\t\t\t\ta = a.Pop();\n\t\t\t\t\tb = b.Pop();\n\t\t\t\t}\n\t\t\t\toutput.Reverse(); // restore correct stack order\n\t\t\t\tthis.InputStack = ImmutableStack.CreateRange(output);\n\t\t\t\tthis.ImportStarted = false;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tinternal void ResetForReimport()\n\t\t\t{\n\t\t\t\tthis.Block.Instructions.Clear();\n\t\t\t\tthis.OutgoingEdges.Clear();\n\t\t\t}\n\t\t}\n\n\t\treadonly ICompilation compilation;\n\t\treadonly MetadataModule module;\n\t\treadonly MetadataReader metadata;\n\n\t\tpublic bool UseDebugSymbols { get; set; }\n\t\tpublic bool UseRefLocalsForAccurateOrderOfEvaluation { get; set; }\n\t\tpublic DebugInfo.IDebugInfoProvider? DebugInfo { get; set; }\n\t\tpublic List<string> Warnings { get; } = new List<string>();\n\n\t\t// List of candidate locations for sequence points. Includes empty il stack locations, any nop instructions, and the instruction following\n\t\t// a call instruction. \n\t\tpublic List<int> SequencePointCandidates { get; } = new List<int>();\n\n\t\t/// <summary>\n\t\t/// Creates a new ILReader instance.\n\t\t/// </summary>\n\t\t/// <param name=\"module\">\n\t\t/// The module used to resolve metadata tokens in the type system.\n\t\t/// </param>\n\t\tpublic ILReader(MetadataModule module)\n\t\t{\n\t\t\tif (module == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(module));\n\t\t\tthis.module = module;\n\t\t\tthis.compilation = module.Compilation;\n\t\t\tthis.metadata = module.metadata;\n\t\t}\n\n\t\t// The members initialized with `null!` are initialized in the Init method.\n\t\tGenericContext genericContext;\n\t\tIMethod method = null!;\n\t\tMethodBodyBlock body = null!;\n\t\tStackType methodReturnStackType;\n\t\tBlobReader reader;\n\t\tImmutableStack<ILVariable> currentStack = ImmutableStack<ILVariable>.Empty;\n\t\tImportedBlock? currentBlock;\n\t\tList<ILInstruction> expressionStack = new List<ILInstruction>();\n\t\tILVariable[] parameterVariables = null!;\n\t\tILVariable[] localVariables = null!;\n\t\tBitSet isBranchTarget = null!;\n\t\tBlockContainer mainContainer = null!;\n\t\tint currentInstructionStart;\n\n\t\tDictionary<int, ImportedBlock> blocksByOffset = new Dictionary<int, ImportedBlock>();\n\t\tQueue<ImportedBlock> importQueue = new Queue<ImportedBlock>();\n\t\tDictionary<ExceptionRegion, ILVariable> variableByExceptionHandler = new Dictionary<ExceptionRegion, ILVariable>();\n\t\tIEnumerable<ILVariable>? stackVariables;\n\n\t\tvoid Init(MethodDefinitionHandle methodDefinitionHandle, MethodBodyBlock body, GenericContext genericContext)\n\t\t{\n\t\t\tif (body == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(body));\n\t\t\tif (methodDefinitionHandle.IsNil)\n\t\t\t\tthrow new ArgumentException(\"methodDefinitionHandle.IsNil\");\n\t\t\tthis.method = module.GetDefinition(methodDefinitionHandle);\n\t\t\tif (genericContext.ClassTypeParameters == null && genericContext.MethodTypeParameters == null)\n\t\t\t{\n\t\t\t\t// no generic context specified: use the method's own type parameters\n\t\t\t\tgenericContext = new GenericContext(method);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// generic context specified, so specialize the method for it:\n\t\t\t\tthis.method = this.method.Specialize(genericContext.ToSubstitution());\n\t\t\t}\n\t\t\tthis.genericContext = genericContext;\n\t\t\tthis.body = body;\n\t\t\tthis.reader = body.GetILReader();\n\t\t\tthis.currentStack = ImmutableStack<ILVariable>.Empty;\n\t\t\tthis.expressionStack.Clear();\n\t\t\tthis.methodReturnStackType = method.ReturnType.GetStackType();\n\t\t\tInitParameterVariables();\n\t\t\tlocalVariables = InitLocalVariables();\n\t\t\tforeach (var v in localVariables)\n\t\t\t{\n\t\t\t\tv.InitialValueIsInitialized = body.LocalVariablesInitialized;\n\t\t\t\tv.UsesInitialValue = true;\n\t\t\t}\n\t\t\tthis.mainContainer = new BlockContainer(expectedResultType: methodReturnStackType);\n\t\t\tthis.blocksByOffset.Clear();\n\t\t\tthis.importQueue.Clear();\n\t\t\tthis.isBranchTarget = new BitSet(reader.Length);\n\t\t\tthis.variableByExceptionHandler.Clear();\n\t\t}\n\n\t\tEntityHandle ReadAndDecodeMetadataToken()\n\t\t{\n\t\t\tint token = reader.ReadInt32();\n\t\t\tif (token <= 0)\n\t\t\t{\n\t\t\t\t// SRM uses negative tokens as \"virtual tokens\" and can get confused\n\t\t\t\t// if we manually create them.\n\t\t\t\t// Row-IDs < 1 are always invalid.\n\t\t\t\tthrow new BadImageFormatException(\"Invalid metadata token\");\n\t\t\t}\n\t\t\tvar handle = MetadataTokens.EntityHandle(token);\n\t\t\tif (handle.IsNil)\n\t\t\t{\n\t\t\t\t// The runtime will crash with a BadImageFormatException when it encounters a row-ID of 0.\n\t\t\t\t// We assume the code following this instruction to be unreachable.\n\t\t\t\tthrow new BadImageFormatException(\"Invalid metadata token\");\n\t\t\t}\n\t\t\treturn handle;\n\t\t}\n\n\t\tIType ReadAndDecodeTypeReference()\n\t\t{\n\t\t\tvar typeReference = ReadAndDecodeMetadataToken();\n\t\t\treturn module.ResolveType(typeReference, genericContext);\n\t\t}\n\n\t\tIMethod ReadAndDecodeMethodReference()\n\t\t{\n\t\t\tvar methodReference = ReadAndDecodeMetadataToken();\n\t\t\treturn module.ResolveMethod(methodReference, genericContext);\n\t\t}\n\n\t\tIField ReadAndDecodeFieldReference()\n\t\t{\n\t\t\tvar fieldReference = ReadAndDecodeMetadataToken();\n\t\t\tvar f = module.ResolveEntity(fieldReference, genericContext) as IField;\n\t\t\tif (f == null)\n\t\t\t\tthrow new BadImageFormatException(\"Invalid field token\");\n\t\t\treturn f;\n\t\t}\n\n\t\tILVariable[] InitLocalVariables()\n\t\t{\n\t\t\tif (body.LocalSignature.IsNil)\n\t\t\t\treturn Empty<ILVariable>.Array;\n\t\t\tImmutableArray<IType> variableTypes;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvariableTypes = module.DecodeLocalSignature(body.LocalSignature, genericContext);\n\t\t\t}\n\t\t\tcatch (BadImageFormatException ex)\n\t\t\t{\n\t\t\t\tWarnings.Add(\"Error decoding local variables: \" + ex.Message);\n\t\t\t\tvariableTypes = ImmutableArray<IType>.Empty;\n\t\t\t}\n\t\t\tvar localVariables = new ILVariable[variableTypes.Length];\n\t\t\tforeach (var (index, type) in variableTypes.WithIndex())\n\t\t\t{\n\t\t\t\tlocalVariables[index] = CreateILVariable(index, type);\n\t\t\t}\n\t\t\treturn localVariables;\n\t\t}\n\n\t\tvoid InitParameterVariables()\n\t\t{\n\t\t\tint popCount = method.Parameters.Count;\n\t\t\tif (!method.IsStatic)\n\t\t\t\tpopCount++;\n\t\t\tif (method.Parameters.LastOrDefault()?.Type == SpecialType.ArgList)\n\t\t\t\tpopCount--;\n\t\t\tparameterVariables = new ILVariable[popCount];\n\t\t\tint paramIndex = 0;\n\t\t\tint offset = 0;\n\t\t\tif (!method.IsStatic)\n\t\t\t{\n\t\t\t\toffset = 1;\n\t\t\t\tIType declaringType = method.DeclaringType;\n\t\t\t\tif (declaringType.IsUnbound())\n\t\t\t\t{\n\t\t\t\t\t// If method is a definition (and not specialized), the declaring type is also just a definition,\n\t\t\t\t\t// and needs to be converted into a normally usable type.\n\t\t\t\t\tdeclaringType = new ParameterizedType(declaringType, declaringType.TypeParameters);\n\t\t\t\t}\n\t\t\t\tILVariable ilVar = CreateILVariable(-1, declaringType, \"this\");\n\t\t\t\tilVar.IsRefReadOnly = method.ThisIsRefReadOnly;\n\t\t\t\tparameterVariables[paramIndex++] = ilVar;\n\t\t\t}\n\t\t\twhile (paramIndex < parameterVariables.Length)\n\t\t\t{\n\t\t\t\tIParameter parameter = method.Parameters[paramIndex - offset];\n\t\t\t\tILVariable ilVar = CreateILVariable(paramIndex - offset, parameter.Type, parameter.Name);\n\t\t\t\tilVar.IsRefReadOnly = parameter.ReferenceKind is ReferenceKind.In or ReferenceKind.RefReadOnly;\n\t\t\t\tparameterVariables[paramIndex] = ilVar;\n\t\t\t\tparamIndex++;\n\t\t\t}\n\t\t\tDebug.Assert(paramIndex == parameterVariables.Length);\n\t\t}\n\n\t\tILVariable CreateILVariable(int index, IType type)\n\t\t{\n\t\t\tVariableKind kind;\n\t\t\tif (type.SkipModifiers() is PinnedType pinned)\n\t\t\t{\n\t\t\t\tkind = VariableKind.PinnedLocal;\n\t\t\t\ttype = pinned.ElementType;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tkind = VariableKind.Local;\n\t\t\t}\n\n\t\t\tif (UseDebugSymbols && DebugInfo is not null &&\n\t\t\t\tDebugInfo.TryGetExtraTypeInfo((MethodDefinitionHandle)method.MetadataToken, index, out var pdbExtraTypeInfo))\n\t\t\t{\n\t\t\t\ttype = ApplyAttributeTypeVisitor.ApplyAttributesToType(type, compilation, module.TypeSystemOptions, pdbExtraTypeInfo);\n\t\t\t}\n\n\t\t\tILVariable ilVar = new ILVariable(kind, type, index);\n\t\t\tif (!UseDebugSymbols || DebugInfo == null || !DebugInfo.TryGetName((MethodDefinitionHandle)method.MetadataToken, index, out string name))\n\t\t\t{\n\t\t\t\tilVar.Name = \"V_\" + index;\n\t\t\t\tilVar.HasGeneratedName = true;\n\t\t\t}\n\t\t\telse if (string.IsNullOrWhiteSpace(name))\n\t\t\t{\n\t\t\t\tilVar.Name = \"V_\" + index;\n\t\t\t\tilVar.HasGeneratedName = true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tilVar.Name = name;\n\t\t\t}\n\t\t\treturn ilVar;\n\t\t}\n\n\t\tILVariable CreateILVariable(int index, IType parameterType, string name)\n\t\t{\n\t\t\tDebug.Assert(!parameterType.IsUnbound());\n\t\t\tITypeDefinition? def = parameterType.GetDefinition();\n\t\t\tif (def != null && index < 0 && def.IsReferenceType == false)\n\t\t\t{\n\t\t\t\tparameterType = new ByReferenceType(parameterType);\n\t\t\t}\n\t\t\tvar ilVar = new ILVariable(VariableKind.Parameter, parameterType, index);\n\t\t\tDebug.Assert(ilVar.StoreCount == 1); // count the initial store when the method is called with an argument\n\t\t\tif (index < 0)\n\t\t\t\tilVar.Name = \"this\";\n\t\t\telse if (string.IsNullOrWhiteSpace(name))\n\t\t\t{\n\t\t\t\tilVar.Name = \"P_\" + index;\n\t\t\t\tilVar.HasGeneratedName = true;\n\t\t\t}\n\t\t\telse\n\t\t\t\tilVar.Name = name;\n\t\t\treturn ilVar;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Warn when invalid IL is detected.\n\t\t/// ILSpy should be able to handle invalid IL; but this method can be helpful for debugging the ILReader,\n\t\t/// as this method should not get called when processing valid IL.\n\t\t/// </summary>\n\t\tvoid Warn(string message)\n\t\t{\n\t\t\tWarnings.Add(string.Format(\"IL_{0:x4}: {1}\", currentInstructionStart, message));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Check control flow edges for compatible stacks.\n\t\t/// Returns union find data structure for unifying the different variables for the same stack slot.\n\t\t/// Also inserts stack adjustments where necessary.\n\t\t/// </summary>\n\t\tUnionFind<ILVariable> CheckOutgoingEdges()\n\t\t{\n\t\t\tvar unionFind = new UnionFind<ILVariable>();\n\t\t\tforeach (var block in blocksByOffset.Values)\n\t\t\t{\n\t\t\t\tforeach (var (outgoing, stack) in block.OutgoingEdges)\n\t\t\t\t{\n\t\t\t\t\tvar a = stack;\n\t\t\t\t\tvar b = outgoing.InputStack;\n\t\t\t\t\tif (a.Count() != b.Count())\n\t\t\t\t\t{\n\t\t\t\t\t\t// Let's not try to merge mismatched stacks.\n\t\t\t\t\t\tWarnings.Add($\"IL_{block.Block.EndILOffset:x4}->IL{outgoing.StartILOffset:x4}: Incompatible stack heights: {a.Count()} vs {b.Count()}\");\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\twhile (!a.IsEmpty && !b.IsEmpty)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar varA = a.Peek();\n\t\t\t\t\t\tvar varB = b.Peek();\n\t\t\t\t\t\tif (varA.StackType == varB.StackType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// The stack types match, so we can merge the variables.\n\t\t\t\t\t\t\tunionFind.Merge(varA, varB);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tDebug.Assert(varA.StackType < varB.StackType);\n\t\t\t\t\t\t\tif (!IsValidTypeStackTypeMerge(varA.StackType, varB.StackType))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tWarnings.Add($\"IL_{block.Block.EndILOffset:x4}->IL{outgoing.StartILOffset:x4}: Incompatible stack types: {varA.StackType} vs {varB.StackType}\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tInsertStackAdjustment(block.Block, varA, varB);\n\t\t\t\t\t\t}\n\t\t\t\t\t\ta = a.Pop();\n\t\t\t\t\t\tb = b.Pop();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn unionFind;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Inserts a copy from varA to varB (with conversion) at the end of <paramref name=\"block\"/>.\n\t\t/// If the block ends with a branching instruction, the copy is inserted before the branching instruction.\n\t\t/// </summary>\n\t\tprivate void InsertStackAdjustment(Block block, ILVariable varA, ILVariable varB)\n\t\t{\n\t\t\tint insertionPosition = block.Instructions.Count;\n\t\t\twhile (insertionPosition > 0 && block.Instructions[insertionPosition - 1].HasFlag(InstructionFlags.MayBranch))\n\t\t\t{\n\t\t\t\t// Branch instruction mustn't be initializing varA.\n\t\t\t\tDebug.Assert(!block.Instructions[insertionPosition - 1].HasFlag(InstructionFlags.MayWriteLocals));\n\t\t\t\tinsertionPosition--;\n\t\t\t}\n\t\t\tILInstruction value = new LdLoc(varA);\n\t\t\tvalue = new Conv(value, varB.StackType.ToPrimitiveType(), false, Sign.Signed);\n\t\t\tblock.Instructions.Insert(insertionPosition, new StLoc(varB, value) { IsStackAdjustment = true });\n\t\t}\n\n\t\tprivate static bool IsValidTypeStackTypeMerge(StackType stackType1, StackType stackType2)\n\t\t{\n\t\t\tif (stackType1 == StackType.I && stackType2 == StackType.I4)\n\t\t\t\treturn true;\n\t\t\tif (stackType1 == StackType.I4 && stackType2 == StackType.I)\n\t\t\t\treturn true;\n\t\t\tif (stackType1 == StackType.F4 && stackType2 == StackType.F8)\n\t\t\t\treturn true;\n\t\t\tif (stackType1 == StackType.F8 && stackType2 == StackType.F4)\n\t\t\t\treturn true;\n\t\t\t// allow merging unknown type with any other type\n\t\t\treturn stackType1 == StackType.Unknown || stackType2 == StackType.Unknown;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Stores the given stack for a branch to `offset`.\n\t\t/// </summary>\n\t\tImportedBlock StoreStackForOffset(int offset, ImmutableStack<ILVariable> stack)\n\t\t{\n\t\t\tif (blocksByOffset.TryGetValue(offset, out var existing))\n\t\t\t{\n\t\t\t\tbool wasImported = existing.ImportStarted;\n\t\t\t\tif (existing.MergeStackTypes(stack) && wasImported)\n\t\t\t\t{\n\t\t\t\t\t// If the stack changed, we need to re-import the block.\n\t\t\t\t\timportQueue.Enqueue(existing);\n\t\t\t\t}\n\t\t\t\treturn existing;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tImportedBlock newBlock = new ImportedBlock(offset, stack);\n\t\t\t\tblocksByOffset.Add(offset, newBlock);\n\t\t\t\timportQueue.Enqueue(newBlock);\n\t\t\t\treturn newBlock;\n\t\t\t}\n\t\t}\n\n\t\tvoid ReadInstructions(CancellationToken cancellationToken)\n\t\t{\n\t\t\treader.Reset();\n\t\t\tStoreStackForOffset(0, ImmutableStack<ILVariable>.Empty);\n\t\t\tif (reader.Length == 0)\n\t\t\t{\n\t\t\t\tblocksByOffset[0].Block.Instructions.Add(\n\t\t\t\t\tnew InvalidBranch(\"Empty body found. Decompiled assembly might be a reference assembly.\")\n\t\t\t\t);\n\t\t\t\tstackVariables = Enumerable.Empty<ILVariable>();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tILParser.SetBranchTargets(ref reader, isBranchTarget);\n\t\t\tPrepareBranchTargetsAndStacksForExceptionHandlers();\n\n\t\t\t// Import of IL byte codes:\n\t\t\twhile (importQueue.Count > 0)\n\t\t\t{\n\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tImportedBlock block = importQueue.Dequeue();\n\t\t\t\tReadBlock(block, cancellationToken);\n\t\t\t}\n\t\t\tEnsureExceptionHandlersHaveBlocks();\n\n\t\t\t// Merge different variables for same stack slot:\n\t\t\tvar unionFind = CheckOutgoingEdges();\n\t\t\tvar visitor = new CollectStackVariablesVisitor(unionFind);\n\t\t\tforeach (var block in blocksByOffset.Values)\n\t\t\t{\n\t\t\t\tblock.Block.AcceptVisitor(visitor);\n\t\t\t}\n\t\t\tstackVariables = visitor.variables;\n\t\t}\n\n\t\tvoid ReadBlock(ImportedBlock block, CancellationToken cancellationToken)\n\t\t{\n\t\t\tDebug.Assert(!block.ImportStarted);\n\t\t\tblock.ResetForReimport();\n\t\t\tblock.ImportStarted = true;\n\t\t\treader.Offset = block.StartILOffset;\n\t\t\t//Debug.WriteLine($\"Import block at IL_{block.StartILOffset:x4} with inputs {string.Join(\", \", block.InputStack.Select(v => v.StackType.ToString()))}\");\n\t\t\tcurrentBlock = block;\n\t\t\tcurrentStack = block.InputStack;\n\t\t\t// Read instructions until we reach the end of the block.\n\t\t\twhile (reader.RemainingBytes > 0)\n\t\t\t{\n\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tint start = reader.Offset;\n\t\t\t\tcurrentInstructionStart = start;\n\t\t\t\tbool startedWithEmptyStack = CurrentStackIsEmpty();\n\t\t\t\tDecodedInstruction decodedInstruction;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tdecodedInstruction = DecodeInstruction();\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException ex)\n\t\t\t\t{\n\t\t\t\t\tdecodedInstruction = new InvalidBranch(ex.Message);\n\t\t\t\t}\n\t\t\t\tvar inst = decodedInstruction.Instruction;\n\t\t\t\tif (inst.ResultType == StackType.Unknown && inst.OpCode != OpCode.InvalidBranch && inst.OpCode != OpCode.InvalidExpression)\n\t\t\t\t\tWarn(\"Unknown result type (might be due to invalid IL or missing references)\");\n\t\t\t\tinst.CheckInvariant(ILPhase.InILReader);\n\t\t\t\tint end = reader.Offset;\n\t\t\t\tinst.AddILRange(new Interval(start, end));\n\t\t\t\tif (!decodedInstruction.PushedOnExpressionStack)\n\t\t\t\t{\n\t\t\t\t\t// Flush to avoid re-ordering of side-effects\n\t\t\t\t\tFlushExpressionStack();\n\t\t\t\t\tblock.Block.Instructions.Add(inst);\n\t\t\t\t}\n\n\t\t\t\tif ((!decodedInstruction.PushedOnExpressionStack && IsSequencePointInstruction(inst)) || startedWithEmptyStack)\n\t\t\t\t{\n\t\t\t\t\tthis.SequencePointCandidates.Add(inst.StartILOffset);\n\t\t\t\t}\n\n\t\t\t\tif (inst.HasDirectFlag(InstructionFlags.EndPointUnreachable))\n\t\t\t\t{\n\t\t\t\t\tbreak; // end of block, don't parse following instructions if they are unreachable\n\t\t\t\t}\n\t\t\t\telse if (isBranchTarget[end] || inst.HasFlag(InstructionFlags.MayBranch))\n\t\t\t\t{\n\t\t\t\t\tbreak; // end of block (we'll create fall through)\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Finalize block\n\t\t\tFlushExpressionStack();\n\t\t\tblock.Block.AddILRange(new Interval(block.StartILOffset, reader.Offset));\n\t\t\tif (!block.Block.HasFlag(InstructionFlags.EndPointUnreachable))\n\t\t\t{\n\t\t\t\t// create fall through branch\n\t\t\t\tILInstruction branch;\n\t\t\t\tif (reader.RemainingBytes > 0)\n\t\t\t\t{\n\t\t\t\t\tMarkBranchTarget(reader.Offset, isFallThrough: true);\n\t\t\t\t\tbranch = new Branch(reader.Offset);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbranch = new InvalidBranch(\"End of method reached without returning.\");\n\t\t\t\t}\n\t\t\t\tif (block.Block.Instructions.LastOrDefault() is SwitchInstruction switchInst && switchInst.Sections.Last().Body.MatchNop())\n\t\t\t\t{\n\t\t\t\t\t// Instead of putting the default branch after the switch instruction\n\t\t\t\t\tswitchInst.Sections.Last().Body = branch;\n\t\t\t\t\tDebug.Assert(switchInst.HasFlag(InstructionFlags.EndPointUnreachable));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tblock.Block.Instructions.Add(branch);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate bool CurrentStackIsEmpty()\n\t\t{\n\t\t\treturn currentStack.IsEmpty && expressionStack.Count == 0;\n\t\t}\n\n\t\tprivate void PrepareBranchTargetsAndStacksForExceptionHandlers()\n\t\t{\n\t\t\t// Fill isBranchTarget and branchStackDict based on exception handlers\n\t\t\tforeach (var eh in body.ExceptionRegions)\n\t\t\t{\n\t\t\t\t// Always mark the start of the try block as a \"branch target\".\n\t\t\t\t// We need to ensure that we put a block boundary there.\n\t\t\t\tisBranchTarget[eh.TryOffset] = true;\n\n\t\t\t\tImmutableStack<ILVariable> ehStack;\n\t\t\t\tif (eh.Kind == ExceptionRegionKind.Catch)\n\t\t\t\t{\n\t\t\t\t\tvar catchType = module.ResolveType(eh.CatchType, genericContext);\n\t\t\t\t\tvar v = new ILVariable(VariableKind.ExceptionStackSlot, catchType, eh.HandlerOffset) {\n\t\t\t\t\t\tName = \"E_\" + eh.HandlerOffset,\n\t\t\t\t\t\tHasGeneratedName = true\n\t\t\t\t\t};\n\t\t\t\t\tvariableByExceptionHandler.Add(eh, v);\n\t\t\t\t\tehStack = ImmutableStack.Create(v);\n\t\t\t\t}\n\t\t\t\telse if (eh.Kind == ExceptionRegionKind.Filter)\n\t\t\t\t{\n\t\t\t\t\tvar v = new ILVariable(VariableKind.ExceptionStackSlot, compilation.FindType(KnownTypeCode.Object), eh.HandlerOffset) {\n\t\t\t\t\t\tName = \"E_\" + eh.HandlerOffset,\n\t\t\t\t\t\tHasGeneratedName = true\n\t\t\t\t\t};\n\t\t\t\t\tvariableByExceptionHandler.Add(eh, v);\n\t\t\t\t\tehStack = ImmutableStack.Create(v);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tehStack = ImmutableStack<ILVariable>.Empty;\n\t\t\t\t}\n\t\t\t\tif (eh.FilterOffset != -1)\n\t\t\t\t{\n\t\t\t\t\tisBranchTarget[eh.FilterOffset] = true;\n\t\t\t\t\tStoreStackForOffset(eh.FilterOffset, ehStack);\n\t\t\t\t}\n\t\t\t\tif (eh.HandlerOffset != -1)\n\t\t\t\t{\n\t\t\t\t\tisBranchTarget[eh.HandlerOffset] = true;\n\t\t\t\t\tStoreStackForOffset(eh.HandlerOffset, ehStack);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate void EnsureExceptionHandlersHaveBlocks()\n\t\t{\n\t\t\t// PrepareBranchTargetsAndStacksForExceptionHandlers enqueued filter/handler offsets\n\t\t\t// so we have blocks for those; but it's possible that the TryOffset was never enqueued\n\t\t\t// because it is unreachable.\n\t\t\t// We need to ensure that we have blocks for all exception handler offsets,\n\t\t\t// as otherwise the BlockBuilder will fail.\n\t\t\tforeach (var eh in body.ExceptionRegions)\n\t\t\t{\n\t\t\t\tif (blocksByOffset.ContainsKey(eh.TryOffset))\n\t\t\t\t\tcontinue;\n\t\t\t\t// Create a dummy block for the try offset\n\t\t\t\tvar block = new ImportedBlock(eh.TryOffset, ImmutableStack<ILVariable>.Empty);\n\t\t\t\tblock.Block.Instructions.Add(new InvalidBranch(\"Unreachable try block\"));\n\t\t\t\tblocksByOffset.Add(eh.TryOffset, block);\n\t\t\t}\n\t\t\t// Note that after the BlockBuilder is done, it may delete the whole block containing\n\t\t\t// the unreachable try-except construct, if it is completely unreachable.\n\t\t}\n\n\t\tprivate static bool IsSequencePointInstruction(ILInstruction instruction)\n\t\t{\n\t\t\tif (instruction.OpCode is OpCode.Nop\n\t\t\t\t\t\t\t\t\tor OpCode.Call\n\t\t\t\t\t\t\t\t\tor OpCode.CallIndirect\n\t\t\t\t\t\t\t\t\tor OpCode.CallVirt)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Debugging helper: writes the decoded instruction stream interleaved with the inferred evaluation stack layout.\n\t\t/// </summary>\n\t\tpublic void WriteTypedIL(MethodDefinitionHandle method, MethodBodyBlock body,\n\t\t\tITextOutput output, GenericContext genericContext = default, CancellationToken cancellationToken = default)\n\t\t{\n\t\t\tInit(method, body, genericContext);\n\t\t\tReadInstructions(cancellationToken);\n\t\t\tforeach (var importBlock in blocksByOffset.Values.OrderBy(b => b.StartILOffset))\n\t\t\t{\n\t\t\t\toutput.Write(\"   [\");\n\t\t\t\tbool isFirstElement = true;\n\t\t\t\tforeach (var element in importBlock.InputStack)\n\t\t\t\t{\n\t\t\t\t\tif (isFirstElement)\n\t\t\t\t\t\tisFirstElement = false;\n\t\t\t\t\telse\n\t\t\t\t\t\toutput.Write(\", \");\n\t\t\t\t\toutput.WriteLocalReference(element.Name, element);\n\t\t\t\t\toutput.Write(\":\");\n\t\t\t\t\toutput.Write(element.StackType);\n\t\t\t\t}\n\t\t\t\toutput.Write(']');\n\t\t\t\toutput.WriteLine();\n\n\t\t\t\timportBlock.Block.WriteTo(output, new ILAstWritingOptions());\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t\tnew Disassembler.MethodBodyDisassembler(output, cancellationToken) { DetectControlStructure = false }\n\t\t\t\t.WriteExceptionHandlers(module.MetadataFile, method, body);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Decodes the specified method body and returns an ILFunction.\n\t\t/// </summary>\n\t\tpublic ILFunction ReadIL(MethodDefinitionHandle method, MethodBodyBlock body, GenericContext genericContext = default, ILFunctionKind kind = ILFunctionKind.TopLevelFunction, CancellationToken cancellationToken = default)\n\t\t{\n\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\tInit(method, body, genericContext);\n\t\t\tReadInstructions(cancellationToken);\n\t\t\tvar blockBuilder = new BlockBuilder(body, variableByExceptionHandler, compilation);\n\t\t\tblockBuilder.CreateBlocks(mainContainer, blocksByOffset.Values.Select(ib => ib.Block), cancellationToken);\n\t\t\tvar function = new ILFunction(this.method, body.GetCodeSize(), this.genericContext, mainContainer, kind);\n\t\t\tfunction.Variables.AddRange(parameterVariables);\n\t\t\tfunction.Variables.AddRange(localVariables);\n\t\t\tfunction.LocalVariableSignatureLength = localVariables.Length;\n\t\t\tDebug.Assert(stackVariables != null);\n\t\t\tfunction.Variables.AddRange(stackVariables);\n\t\t\tfunction.Variables.AddRange(variableByExceptionHandler.Values);\n\t\t\tfunction.Variables.AddRange(blockBuilder.OnErrorDispatcherVariables);\n\t\t\tfunction.AddRef(); // mark the root node\n\t\t\tvar removedBlocks = new List<Block>();\n\t\t\tforeach (var c in function.Descendants.OfType<BlockContainer>())\n\t\t\t{\n\t\t\t\tvar newOrder = c.TopologicalSort(deleteUnreachableBlocks: true);\n\t\t\t\tif (newOrder.Count < c.Blocks.Count)\n\t\t\t\t{\n\t\t\t\t\tremovedBlocks.AddRange(c.Blocks.Except(newOrder));\n\t\t\t\t}\n\t\t\t\tc.Blocks.ReplaceList(newOrder);\n\t\t\t}\n\t\t\tif (removedBlocks.Count > 0)\n\t\t\t{\n\t\t\t\tremovedBlocks.SortBy(b => b.StartILOffset);\n\t\t\t\tfunction.Warnings.Add(\"Discarded unreachable code: \"\n\t\t\t\t\t\t\t+ string.Join(\", \", removedBlocks.Select(b => $\"IL_{b.StartILOffset:x4}\")));\n\t\t\t}\n\n\t\t\tthis.SequencePointCandidates.Sort();\n\t\t\tfunction.SequencePointCandidates = this.SequencePointCandidates;\n\n\t\t\tfunction.Warnings.AddRange(Warnings);\n\t\t\treturn function;\n\t\t}\n\n\t\tDecodedInstruction Neg()\n\t\t{\n\t\t\tswitch (PeekStackType())\n\t\t\t{\n\t\t\t\tcase StackType.I4:\n\t\t\t\t\treturn Push(new BinaryNumericInstruction(BinaryNumericOperator.Sub, new LdcI4(0), Pop(), checkForOverflow: false, sign: Sign.None));\n\t\t\t\tcase StackType.I:\n\t\t\t\t\treturn Push(new BinaryNumericInstruction(BinaryNumericOperator.Sub, new Conv(new LdcI4(0), PrimitiveType.I, false, Sign.None), Pop(), checkForOverflow: false, sign: Sign.None));\n\t\t\t\tcase StackType.I8:\n\t\t\t\t\treturn Push(new BinaryNumericInstruction(BinaryNumericOperator.Sub, new LdcI8(0), Pop(), checkForOverflow: false, sign: Sign.None));\n\t\t\t\tcase StackType.F4:\n\t\t\t\t\treturn Push(new BinaryNumericInstruction(BinaryNumericOperator.Sub, new LdcF4(0), Pop(), checkForOverflow: false, sign: Sign.None));\n\t\t\t\tcase StackType.F8:\n\t\t\t\t\treturn Push(new BinaryNumericInstruction(BinaryNumericOperator.Sub, new LdcF8(0), Pop(), checkForOverflow: false, sign: Sign.None));\n\t\t\t\tdefault:\n\t\t\t\t\tWarn(\"Unsupported input type for neg.\");\n\t\t\t\t\tgoto case StackType.I4;\n\t\t\t}\n\t\t}\n\n\t\tstruct DecodedInstruction\n\t\t{\n\t\t\tpublic ILInstruction Instruction;\n\t\t\tpublic bool PushedOnExpressionStack;\n\n\t\t\tpublic static implicit operator DecodedInstruction(ILInstruction instruction)\n\t\t\t{\n\t\t\t\treturn new DecodedInstruction { Instruction = instruction };\n\t\t\t}\n\t\t}\n\n\t\tDecodedInstruction DecodeInstruction()\n\t\t{\n\t\t\tif (reader.RemainingBytes == 0)\n\t\t\t\treturn new InvalidBranch(\"Unexpected end of body\");\n\t\t\tvar opCode = ILParser.DecodeOpCode(ref reader);\n\t\t\tswitch (opCode)\n\t\t\t{\n\t\t\t\tcase ILOpCode.Constrained:\n\t\t\t\t\treturn DecodeConstrainedCall();\n\t\t\t\tcase ILOpCode.Readonly:\n\t\t\t\t\treturn DecodeReadonly();\n\t\t\t\tcase ILOpCode.Tail:\n\t\t\t\t\treturn DecodeTailCall();\n\t\t\t\tcase ILOpCode.Unaligned:\n\t\t\t\t\treturn DecodeUnaligned();\n\t\t\t\tcase ILOpCode.Volatile:\n\t\t\t\t\treturn DecodeVolatile();\n\t\t\t\tcase ILOpCode.Add:\n\t\t\t\t\treturn BinaryNumeric(BinaryNumericOperator.Add);\n\t\t\t\tcase ILOpCode.Add_ovf:\n\t\t\t\t\treturn BinaryNumeric(BinaryNumericOperator.Add, true, Sign.Signed);\n\t\t\t\tcase ILOpCode.Add_ovf_un:\n\t\t\t\t\treturn BinaryNumeric(BinaryNumericOperator.Add, true, Sign.Unsigned);\n\t\t\t\tcase ILOpCode.And:\n\t\t\t\t\treturn BinaryNumeric(BinaryNumericOperator.BitAnd);\n\t\t\t\tcase ILOpCode.Arglist:\n\t\t\t\t\treturn Push(new Arglist());\n\t\t\t\tcase ILOpCode.Beq:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.Equality);\n\t\t\t\tcase ILOpCode.Beq_s:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.Equality);\n\t\t\t\tcase ILOpCode.Bge:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.GreaterThanOrEqual);\n\t\t\t\tcase ILOpCode.Bge_s:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.GreaterThanOrEqual);\n\t\t\t\tcase ILOpCode.Bge_un:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.GreaterThanOrEqual, un: true);\n\t\t\t\tcase ILOpCode.Bge_un_s:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.GreaterThanOrEqual, un: true);\n\t\t\t\tcase ILOpCode.Bgt:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.GreaterThan);\n\t\t\t\tcase ILOpCode.Bgt_s:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.GreaterThan);\n\t\t\t\tcase ILOpCode.Bgt_un:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.GreaterThan, un: true);\n\t\t\t\tcase ILOpCode.Bgt_un_s:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.GreaterThan, un: true);\n\t\t\t\tcase ILOpCode.Ble:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.LessThanOrEqual);\n\t\t\t\tcase ILOpCode.Ble_s:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.LessThanOrEqual);\n\t\t\t\tcase ILOpCode.Ble_un:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.LessThanOrEqual, un: true);\n\t\t\t\tcase ILOpCode.Ble_un_s:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.LessThanOrEqual, un: true);\n\t\t\t\tcase ILOpCode.Blt:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.LessThan);\n\t\t\t\tcase ILOpCode.Blt_s:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.LessThan);\n\t\t\t\tcase ILOpCode.Blt_un:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.LessThan, un: true);\n\t\t\t\tcase ILOpCode.Blt_un_s:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.LessThan, un: true);\n\t\t\t\tcase ILOpCode.Bne_un:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.Inequality, un: true);\n\t\t\t\tcase ILOpCode.Bne_un_s:\n\t\t\t\t\treturn DecodeComparisonBranch(opCode, ComparisonKind.Inequality, un: true);\n\t\t\t\tcase ILOpCode.Br:\n\t\t\t\t\treturn DecodeUnconditionalBranch(opCode);\n\t\t\t\tcase ILOpCode.Br_s:\n\t\t\t\t\treturn DecodeUnconditionalBranch(opCode);\n\t\t\t\tcase ILOpCode.Break:\n\t\t\t\t\treturn new DebugBreak();\n\t\t\t\tcase ILOpCode.Brfalse:\n\t\t\t\t\treturn DecodeConditionalBranch(opCode, true);\n\t\t\t\tcase ILOpCode.Brfalse_s:\n\t\t\t\t\treturn DecodeConditionalBranch(opCode, true);\n\t\t\t\tcase ILOpCode.Brtrue:\n\t\t\t\t\treturn DecodeConditionalBranch(opCode, false);\n\t\t\t\tcase ILOpCode.Brtrue_s:\n\t\t\t\t\treturn DecodeConditionalBranch(opCode, false);\n\t\t\t\tcase ILOpCode.Call:\n\t\t\t\t\treturn DecodeCall(OpCode.Call);\n\t\t\t\tcase ILOpCode.Callvirt:\n\t\t\t\t\treturn DecodeCall(OpCode.CallVirt);\n\t\t\t\tcase ILOpCode.Calli:\n\t\t\t\t\treturn DecodeCallIndirect();\n\t\t\t\tcase ILOpCode.Ceq:\n\t\t\t\t\treturn Push(Comparison(ComparisonKind.Equality));\n\t\t\t\tcase ILOpCode.Cgt:\n\t\t\t\t\treturn Push(Comparison(ComparisonKind.GreaterThan));\n\t\t\t\tcase ILOpCode.Cgt_un:\n\t\t\t\t\treturn Push(Comparison(ComparisonKind.GreaterThan, un: true));\n\t\t\t\tcase ILOpCode.Clt:\n\t\t\t\t\treturn Push(Comparison(ComparisonKind.LessThan));\n\t\t\t\tcase ILOpCode.Clt_un:\n\t\t\t\t\treturn Push(Comparison(ComparisonKind.LessThan, un: true));\n\t\t\t\tcase ILOpCode.Ckfinite:\n\t\t\t\t\treturn new Ckfinite(Peek());\n\t\t\t\tcase ILOpCode.Conv_i1:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.I1, false, Sign.None));\n\t\t\t\tcase ILOpCode.Conv_i2:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.I2, false, Sign.None));\n\t\t\t\tcase ILOpCode.Conv_i4:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.I4, false, Sign.None));\n\t\t\t\tcase ILOpCode.Conv_i8:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.I8, false, Sign.None));\n\t\t\t\tcase ILOpCode.Conv_r4:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.R4, false, Sign.Signed));\n\t\t\t\tcase ILOpCode.Conv_r8:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.R8, false, Sign.Signed));\n\t\t\t\tcase ILOpCode.Conv_u1:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.U1, false, Sign.None));\n\t\t\t\tcase ILOpCode.Conv_u2:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.U2, false, Sign.None));\n\t\t\t\tcase ILOpCode.Conv_u4:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.U4, false, Sign.None));\n\t\t\t\tcase ILOpCode.Conv_u8:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.U8, false, Sign.None));\n\t\t\t\tcase ILOpCode.Conv_i:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.I, false, Sign.None));\n\t\t\t\tcase ILOpCode.Conv_u:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.U, false, Sign.None));\n\t\t\t\tcase ILOpCode.Conv_r_un:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.R, false, Sign.Unsigned));\n\t\t\t\tcase ILOpCode.Conv_ovf_i1:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.I1, true, Sign.Signed));\n\t\t\t\tcase ILOpCode.Conv_ovf_i2:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.I2, true, Sign.Signed));\n\t\t\t\tcase ILOpCode.Conv_ovf_i4:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.I4, true, Sign.Signed));\n\t\t\t\tcase ILOpCode.Conv_ovf_i8:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.I8, true, Sign.Signed));\n\t\t\t\tcase ILOpCode.Conv_ovf_u1:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.U1, true, Sign.Signed));\n\t\t\t\tcase ILOpCode.Conv_ovf_u2:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.U2, true, Sign.Signed));\n\t\t\t\tcase ILOpCode.Conv_ovf_u4:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.U4, true, Sign.Signed));\n\t\t\t\tcase ILOpCode.Conv_ovf_u8:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.U8, true, Sign.Signed));\n\t\t\t\tcase ILOpCode.Conv_ovf_i:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.I, true, Sign.Signed));\n\t\t\t\tcase ILOpCode.Conv_ovf_u:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.U, true, Sign.Signed));\n\t\t\t\tcase ILOpCode.Conv_ovf_i1_un:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.I1, true, Sign.Unsigned));\n\t\t\t\tcase ILOpCode.Conv_ovf_i2_un:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.I2, true, Sign.Unsigned));\n\t\t\t\tcase ILOpCode.Conv_ovf_i4_un:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.I4, true, Sign.Unsigned));\n\t\t\t\tcase ILOpCode.Conv_ovf_i8_un:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.I8, true, Sign.Unsigned));\n\t\t\t\tcase ILOpCode.Conv_ovf_u1_un:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.U1, true, Sign.Unsigned));\n\t\t\t\tcase ILOpCode.Conv_ovf_u2_un:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.U2, true, Sign.Unsigned));\n\t\t\t\tcase ILOpCode.Conv_ovf_u4_un:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.U4, true, Sign.Unsigned));\n\t\t\t\tcase ILOpCode.Conv_ovf_u8_un:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.U8, true, Sign.Unsigned));\n\t\t\t\tcase ILOpCode.Conv_ovf_i_un:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.I, true, Sign.Unsigned));\n\t\t\t\tcase ILOpCode.Conv_ovf_u_un:\n\t\t\t\t\treturn Push(new Conv(Pop(), PrimitiveType.U, true, Sign.Unsigned));\n\t\t\t\tcase ILOpCode.Cpblk:\n\t\t\t\t\t// This preserves the evaluation order because the ILAst will run\n\t\t\t\t\t// destAddress; sourceAddress; size.\n\t\t\t\t\treturn new Cpblk(size: Pop(StackType.I4), sourceAddress: PopPointer(), destAddress: PopPointer());\n\t\t\t\tcase ILOpCode.Div:\n\t\t\t\t\treturn BinaryNumeric(BinaryNumericOperator.Div, false, Sign.Signed);\n\t\t\t\tcase ILOpCode.Div_un:\n\t\t\t\t\treturn BinaryNumeric(BinaryNumericOperator.Div, false, Sign.Unsigned);\n\t\t\t\tcase ILOpCode.Dup:\n\t\t\t\t\treturn Push(Peek());\n\t\t\t\tcase ILOpCode.Endfilter:\n\t\t\t\t\treturn new Leave(null, Pop());\n\t\t\t\tcase ILOpCode.Endfinally:\n\t\t\t\t\treturn new Leave(null);\n\t\t\t\tcase ILOpCode.Initblk:\n\t\t\t\t\t// This preserves the evaluation order because the ILAst will run\n\t\t\t\t\t// address; value; size.\n\t\t\t\t\treturn new Initblk(size: Pop(StackType.I4), value: Pop(StackType.I4), address: PopPointer());\n\t\t\t\tcase ILOpCode.Jmp:\n\t\t\t\t\treturn DecodeJmp();\n\t\t\t\tcase ILOpCode.Ldarg:\n\t\t\t\tcase ILOpCode.Ldarg_s:\n\t\t\t\t\treturn Push(Ldarg(ILParser.DecodeIndex(ref reader, opCode)));\n\t\t\t\tcase ILOpCode.Ldarg_0:\n\t\t\t\t\treturn Push(Ldarg(0));\n\t\t\t\tcase ILOpCode.Ldarg_1:\n\t\t\t\t\treturn Push(Ldarg(1));\n\t\t\t\tcase ILOpCode.Ldarg_2:\n\t\t\t\t\treturn Push(Ldarg(2));\n\t\t\t\tcase ILOpCode.Ldarg_3:\n\t\t\t\t\treturn Push(Ldarg(3));\n\t\t\t\tcase ILOpCode.Ldarga:\n\t\t\t\tcase ILOpCode.Ldarga_s:\n\t\t\t\t\treturn Push(Ldarga(ILParser.DecodeIndex(ref reader, opCode)));\n\t\t\t\tcase ILOpCode.Ldc_i4:\n\t\t\t\t\treturn Push(new LdcI4(reader.ReadInt32()));\n\t\t\t\tcase ILOpCode.Ldc_i8:\n\t\t\t\t\treturn Push(new LdcI8(reader.ReadInt64()));\n\t\t\t\tcase ILOpCode.Ldc_r4:\n\t\t\t\t\treturn Push(new LdcF4(reader.ReadSingle()));\n\t\t\t\tcase ILOpCode.Ldc_r8:\n\t\t\t\t\treturn Push(new LdcF8(reader.ReadDouble()));\n\t\t\t\tcase ILOpCode.Ldc_i4_m1:\n\t\t\t\t\treturn Push(new LdcI4(-1));\n\t\t\t\tcase ILOpCode.Ldc_i4_0:\n\t\t\t\t\treturn Push(new LdcI4(0));\n\t\t\t\tcase ILOpCode.Ldc_i4_1:\n\t\t\t\t\treturn Push(new LdcI4(1));\n\t\t\t\tcase ILOpCode.Ldc_i4_2:\n\t\t\t\t\treturn Push(new LdcI4(2));\n\t\t\t\tcase ILOpCode.Ldc_i4_3:\n\t\t\t\t\treturn Push(new LdcI4(3));\n\t\t\t\tcase ILOpCode.Ldc_i4_4:\n\t\t\t\t\treturn Push(new LdcI4(4));\n\t\t\t\tcase ILOpCode.Ldc_i4_5:\n\t\t\t\t\treturn Push(new LdcI4(5));\n\t\t\t\tcase ILOpCode.Ldc_i4_6:\n\t\t\t\t\treturn Push(new LdcI4(6));\n\t\t\t\tcase ILOpCode.Ldc_i4_7:\n\t\t\t\t\treturn Push(new LdcI4(7));\n\t\t\t\tcase ILOpCode.Ldc_i4_8:\n\t\t\t\t\treturn Push(new LdcI4(8));\n\t\t\t\tcase ILOpCode.Ldc_i4_s:\n\t\t\t\t\treturn Push(new LdcI4(reader.ReadSByte()));\n\t\t\t\tcase ILOpCode.Ldnull:\n\t\t\t\t\treturn Push(new LdNull());\n\t\t\t\tcase ILOpCode.Ldstr:\n\t\t\t\t\treturn Push(DecodeLdstr());\n\t\t\t\tcase ILOpCode.Ldftn:\n\t\t\t\t\treturn Push(new LdFtn(ReadAndDecodeMethodReference()));\n\t\t\t\tcase ILOpCode.Ldind_i1:\n\t\t\t\t\treturn Push(new LdObj(PopPointer(), compilation.FindType(KnownTypeCode.SByte)));\n\t\t\t\tcase ILOpCode.Ldind_i2:\n\t\t\t\t\treturn Push(new LdObj(PopPointer(), compilation.FindType(KnownTypeCode.Int16)));\n\t\t\t\tcase ILOpCode.Ldind_i4:\n\t\t\t\t\treturn Push(new LdObj(PopPointer(), compilation.FindType(KnownTypeCode.Int32)));\n\t\t\t\tcase ILOpCode.Ldind_i8:\n\t\t\t\t\treturn Push(new LdObj(PopPointer(), compilation.FindType(KnownTypeCode.Int64)));\n\t\t\t\tcase ILOpCode.Ldind_u1:\n\t\t\t\t\treturn Push(new LdObj(PopPointer(), compilation.FindType(KnownTypeCode.Byte)));\n\t\t\t\tcase ILOpCode.Ldind_u2:\n\t\t\t\t\treturn Push(new LdObj(PopPointer(), compilation.FindType(KnownTypeCode.UInt16)));\n\t\t\t\tcase ILOpCode.Ldind_u4:\n\t\t\t\t\treturn Push(new LdObj(PopPointer(), compilation.FindType(KnownTypeCode.UInt32)));\n\t\t\t\tcase ILOpCode.Ldind_r4:\n\t\t\t\t\treturn Push(new LdObj(PopPointer(), compilation.FindType(KnownTypeCode.Single)));\n\t\t\t\tcase ILOpCode.Ldind_r8:\n\t\t\t\t\treturn Push(new LdObj(PopPointer(), compilation.FindType(KnownTypeCode.Double)));\n\t\t\t\tcase ILOpCode.Ldind_i:\n\t\t\t\t\treturn Push(new LdObj(PopPointer(), compilation.FindType(KnownTypeCode.IntPtr)));\n\t\t\t\tcase ILOpCode.Ldind_ref:\n\t\t\t\t\treturn Push(new LdObj(PopPointer(), compilation.FindType(KnownTypeCode.Object)));\n\t\t\t\tcase ILOpCode.Ldloc:\n\t\t\t\tcase ILOpCode.Ldloc_s:\n\t\t\t\t\treturn Push(Ldloc(ILParser.DecodeIndex(ref reader, opCode)));\n\t\t\t\tcase ILOpCode.Ldloc_0:\n\t\t\t\t\treturn Push(Ldloc(0));\n\t\t\t\tcase ILOpCode.Ldloc_1:\n\t\t\t\t\treturn Push(Ldloc(1));\n\t\t\t\tcase ILOpCode.Ldloc_2:\n\t\t\t\t\treturn Push(Ldloc(2));\n\t\t\t\tcase ILOpCode.Ldloc_3:\n\t\t\t\t\treturn Push(Ldloc(3));\n\t\t\t\tcase ILOpCode.Ldloca:\n\t\t\t\tcase ILOpCode.Ldloca_s:\n\t\t\t\t\treturn Push(Ldloca(ILParser.DecodeIndex(ref reader, opCode)));\n\t\t\t\tcase ILOpCode.Leave:\n\t\t\t\t\treturn DecodeUnconditionalBranch(opCode, isLeave: true);\n\t\t\t\tcase ILOpCode.Leave_s:\n\t\t\t\t\treturn DecodeUnconditionalBranch(opCode, isLeave: true);\n\t\t\t\tcase ILOpCode.Localloc:\n\t\t\t\t\treturn Push(new LocAlloc(Pop()));\n\t\t\t\tcase ILOpCode.Mul:\n\t\t\t\t\treturn BinaryNumeric(BinaryNumericOperator.Mul, false, Sign.None);\n\t\t\t\tcase ILOpCode.Mul_ovf:\n\t\t\t\t\treturn BinaryNumeric(BinaryNumericOperator.Mul, true, Sign.Signed);\n\t\t\t\tcase ILOpCode.Mul_ovf_un:\n\t\t\t\t\treturn BinaryNumeric(BinaryNumericOperator.Mul, true, Sign.Unsigned);\n\t\t\t\tcase ILOpCode.Neg:\n\t\t\t\t\treturn Neg();\n\t\t\t\tcase ILOpCode.Newobj:\n\t\t\t\t\treturn DecodeCall(OpCode.NewObj);\n\t\t\t\tcase ILOpCode.Nop:\n\t\t\t\t\treturn new Nop();\n\t\t\t\tcase ILOpCode.Not:\n\t\t\t\t\treturn Push(new BitNot(Pop()));\n\t\t\t\tcase ILOpCode.Or:\n\t\t\t\t\treturn BinaryNumeric(BinaryNumericOperator.BitOr);\n\t\t\t\tcase ILOpCode.Pop:\n\t\t\t\t\tFlushExpressionStack(); // discard only the value, not the side-effects\n\t\t\t\t\tPop();\n\t\t\t\t\treturn new Nop() { Kind = NopKind.Pop };\n\t\t\t\tcase ILOpCode.Rem:\n\t\t\t\t\treturn BinaryNumeric(BinaryNumericOperator.Rem, false, Sign.Signed);\n\t\t\t\tcase ILOpCode.Rem_un:\n\t\t\t\t\treturn BinaryNumeric(BinaryNumericOperator.Rem, false, Sign.Unsigned);\n\t\t\t\tcase ILOpCode.Ret:\n\t\t\t\t\treturn Return();\n\t\t\t\tcase ILOpCode.Shl:\n\t\t\t\t\treturn BinaryNumeric(BinaryNumericOperator.ShiftLeft, false, Sign.None);\n\t\t\t\tcase ILOpCode.Shr:\n\t\t\t\t\treturn BinaryNumeric(BinaryNumericOperator.ShiftRight, false, Sign.Signed);\n\t\t\t\tcase ILOpCode.Shr_un:\n\t\t\t\t\treturn BinaryNumeric(BinaryNumericOperator.ShiftRight, false, Sign.Unsigned);\n\t\t\t\tcase ILOpCode.Starg:\n\t\t\t\tcase ILOpCode.Starg_s:\n\t\t\t\t\treturn Starg(ILParser.DecodeIndex(ref reader, opCode));\n\t\t\t\tcase ILOpCode.Stind_i1:\n\t\t\t\t\t// target will run before value, thus preserving the evaluation order\n\t\t\t\t\treturn new StObj(value: Pop(StackType.I4), target: PopStObjTarget(), type: compilation.FindType(KnownTypeCode.SByte));\n\t\t\t\tcase ILOpCode.Stind_i2:\n\t\t\t\t\treturn new StObj(value: Pop(StackType.I4), target: PopStObjTarget(), type: compilation.FindType(KnownTypeCode.Int16));\n\t\t\t\tcase ILOpCode.Stind_i4:\n\t\t\t\t\treturn new StObj(value: Pop(StackType.I4), target: PopStObjTarget(), type: compilation.FindType(KnownTypeCode.Int32));\n\t\t\t\tcase ILOpCode.Stind_i8:\n\t\t\t\t\treturn new StObj(value: Pop(StackType.I8), target: PopStObjTarget(), type: compilation.FindType(KnownTypeCode.Int64));\n\t\t\t\tcase ILOpCode.Stind_r4:\n\t\t\t\t\treturn new StObj(value: Pop(StackType.F4), target: PopStObjTarget(), type: compilation.FindType(KnownTypeCode.Single));\n\t\t\t\tcase ILOpCode.Stind_r8:\n\t\t\t\t\treturn new StObj(value: Pop(StackType.F8), target: PopStObjTarget(), type: compilation.FindType(KnownTypeCode.Double));\n\t\t\t\tcase ILOpCode.Stind_i:\n\t\t\t\t\treturn new StObj(value: Pop(StackType.I), target: PopStObjTarget(), type: compilation.FindType(KnownTypeCode.IntPtr));\n\t\t\t\tcase ILOpCode.Stind_ref:\n\t\t\t\t\treturn new StObj(value: Pop(StackType.O), target: PopStObjTarget(), type: compilation.FindType(KnownTypeCode.Object));\n\t\t\t\tcase ILOpCode.Stloc:\n\t\t\t\tcase ILOpCode.Stloc_s:\n\t\t\t\t\treturn Stloc(ILParser.DecodeIndex(ref reader, opCode));\n\t\t\t\tcase ILOpCode.Stloc_0:\n\t\t\t\t\treturn Stloc(0);\n\t\t\t\tcase ILOpCode.Stloc_1:\n\t\t\t\t\treturn Stloc(1);\n\t\t\t\tcase ILOpCode.Stloc_2:\n\t\t\t\t\treturn Stloc(2);\n\t\t\t\tcase ILOpCode.Stloc_3:\n\t\t\t\t\treturn Stloc(3);\n\t\t\t\tcase ILOpCode.Sub:\n\t\t\t\t\treturn BinaryNumeric(BinaryNumericOperator.Sub, false, Sign.None);\n\t\t\t\tcase ILOpCode.Sub_ovf:\n\t\t\t\t\treturn BinaryNumeric(BinaryNumericOperator.Sub, true, Sign.Signed);\n\t\t\t\tcase ILOpCode.Sub_ovf_un:\n\t\t\t\t\treturn BinaryNumeric(BinaryNumericOperator.Sub, true, Sign.Unsigned);\n\t\t\t\tcase ILOpCode.Switch:\n\t\t\t\t\treturn DecodeSwitch();\n\t\t\t\tcase ILOpCode.Xor:\n\t\t\t\t\treturn BinaryNumeric(BinaryNumericOperator.BitXor);\n\t\t\t\tcase ILOpCode.Box:\n\t\t\t\t{\n\t\t\t\t\tvar type = ReadAndDecodeTypeReference();\n\t\t\t\t\treturn Push(new Box(Pop(type.GetStackType()), type));\n\t\t\t\t}\n\t\t\t\tcase ILOpCode.Castclass:\n\t\t\t\t\treturn Push(new CastClass(Pop(StackType.O), ReadAndDecodeTypeReference()));\n\t\t\t\tcase ILOpCode.Cpobj:\n\t\t\t\t{\n\t\t\t\t\tvar type = ReadAndDecodeTypeReference();\n\t\t\t\t\t// OK, 'target' runs before 'value: ld'\n\t\t\t\t\tvar ld = new LdObj(PopPointer(), type);\n\t\t\t\t\treturn new StObj(PopStObjTarget(), ld, type);\n\t\t\t\t}\n\t\t\t\tcase ILOpCode.Initobj:\n\t\t\t\t\treturn InitObj(PopStObjTarget(), ReadAndDecodeTypeReference());\n\t\t\t\tcase ILOpCode.Isinst:\n\t\t\t\t{\n\t\t\t\t\tvar type = ReadAndDecodeTypeReference();\n\t\t\t\t\tif (type.IsReferenceType != true)\n\t\t\t\t\t{\n\t\t\t\t\t\tFlushExpressionStack(); // value-type isinst has inlining restrictions\n\t\t\t\t\t}\n\t\t\t\t\treturn Push(new IsInst(Pop(StackType.O), type));\n\t\t\t\t}\n\t\t\t\tcase ILOpCode.Ldelem:\n\t\t\t\t\treturn LdElem(ReadAndDecodeTypeReference());\n\t\t\t\tcase ILOpCode.Ldelem_i1:\n\t\t\t\t\treturn LdElem(compilation.FindType(KnownTypeCode.SByte));\n\t\t\t\tcase ILOpCode.Ldelem_i2:\n\t\t\t\t\treturn LdElem(compilation.FindType(KnownTypeCode.Int16));\n\t\t\t\tcase ILOpCode.Ldelem_i4:\n\t\t\t\t\treturn LdElem(compilation.FindType(KnownTypeCode.Int32));\n\t\t\t\tcase ILOpCode.Ldelem_i8:\n\t\t\t\t\treturn LdElem(compilation.FindType(KnownTypeCode.Int64));\n\t\t\t\tcase ILOpCode.Ldelem_u1:\n\t\t\t\t\treturn LdElem(compilation.FindType(KnownTypeCode.Byte));\n\t\t\t\tcase ILOpCode.Ldelem_u2:\n\t\t\t\t\treturn LdElem(compilation.FindType(KnownTypeCode.UInt16));\n\t\t\t\tcase ILOpCode.Ldelem_u4:\n\t\t\t\t\treturn LdElem(compilation.FindType(KnownTypeCode.UInt32));\n\t\t\t\tcase ILOpCode.Ldelem_r4:\n\t\t\t\t\treturn LdElem(compilation.FindType(KnownTypeCode.Single));\n\t\t\t\tcase ILOpCode.Ldelem_r8:\n\t\t\t\t\treturn LdElem(compilation.FindType(KnownTypeCode.Double));\n\t\t\t\tcase ILOpCode.Ldelem_i:\n\t\t\t\t\treturn LdElem(compilation.FindType(KnownTypeCode.IntPtr));\n\t\t\t\tcase ILOpCode.Ldelem_ref:\n\t\t\t\t\treturn LdElem(compilation.FindType(KnownTypeCode.Object));\n\t\t\t\tcase ILOpCode.Ldelema:\n\t\t\t\t\t// LdElema will evalute the array before the indices, so we're preserving the evaluation order\n\t\t\t\t\treturn Push(new LdElema(indices: Pop(), array: Pop(), type: ReadAndDecodeTypeReference()));\n\t\t\t\tcase ILOpCode.Ldfld:\n\t\t\t\t{\n\t\t\t\t\tvar field = ReadAndDecodeFieldReference();\n\t\t\t\t\treturn Push(new LdObj(new LdFlda(PopLdFldTarget(field), field) { DelayExceptions = true }, field.Type));\n\t\t\t\t}\n\t\t\t\tcase ILOpCode.Ldflda:\n\t\t\t\t{\n\t\t\t\t\tvar field = ReadAndDecodeFieldReference();\n\t\t\t\t\treturn Push(new LdFlda(PopFieldTarget(field), field));\n\t\t\t\t}\n\t\t\t\tcase ILOpCode.Stfld:\n\t\t\t\t{\n\t\t\t\t\tvar field = ReadAndDecodeFieldReference();\n\t\t\t\t\treturn new StObj(value: Pop(field.Type.GetStackType()), target: new LdFlda(PopFieldTarget(field), field) { DelayExceptions = true }, type: field.Type);\n\t\t\t\t}\n\t\t\t\tcase ILOpCode.Ldlen:\n\t\t\t\t\treturn Push(new LdLen(StackType.I, Pop(StackType.O)));\n\t\t\t\tcase ILOpCode.Ldobj:\n\t\t\t\t\treturn Push(new LdObj(PopPointer(), ReadAndDecodeTypeReference()));\n\t\t\t\tcase ILOpCode.Ldsfld:\n\t\t\t\t{\n\t\t\t\t\tvar field = ReadAndDecodeFieldReference();\n\t\t\t\t\treturn Push(new LdObj(new LdsFlda(field), field.Type));\n\t\t\t\t}\n\t\t\t\tcase ILOpCode.Ldsflda:\n\t\t\t\t\treturn Push(new LdsFlda(ReadAndDecodeFieldReference()));\n\t\t\t\tcase ILOpCode.Stsfld:\n\t\t\t\t{\n\t\t\t\t\tvar field = ReadAndDecodeFieldReference();\n\t\t\t\t\treturn new StObj(value: Pop(field.Type.GetStackType()), target: new LdsFlda(field), type: field.Type);\n\t\t\t\t}\n\t\t\t\tcase ILOpCode.Ldtoken:\n\t\t\t\t\treturn Push(LdToken(ReadAndDecodeMetadataToken()));\n\t\t\t\tcase ILOpCode.Ldvirtftn:\n\t\t\t\t\treturn Push(new LdVirtFtn(Pop(), ReadAndDecodeMethodReference()));\n\t\t\t\tcase ILOpCode.Mkrefany:\n\t\t\t\t\treturn Push(new MakeRefAny(PopPointer(), ReadAndDecodeTypeReference()));\n\t\t\t\tcase ILOpCode.Newarr:\n\t\t\t\t\treturn Push(new NewArr(ReadAndDecodeTypeReference(), Pop()));\n\t\t\t\tcase ILOpCode.Refanytype:\n\t\t\t\t\treturn Push(new RefAnyType(Pop()));\n\t\t\t\tcase ILOpCode.Refanyval:\n\t\t\t\t\treturn Push(new RefAnyValue(Pop(), ReadAndDecodeTypeReference()));\n\t\t\t\tcase ILOpCode.Rethrow:\n\t\t\t\t\treturn new Rethrow();\n\t\t\t\tcase ILOpCode.Sizeof:\n\t\t\t\t\treturn Push(new SizeOf(ReadAndDecodeTypeReference()));\n\t\t\t\tcase ILOpCode.Stelem:\n\t\t\t\t\treturn StElem(ReadAndDecodeTypeReference());\n\t\t\t\tcase ILOpCode.Stelem_i1:\n\t\t\t\t\treturn StElem(compilation.FindType(KnownTypeCode.SByte));\n\t\t\t\tcase ILOpCode.Stelem_i2:\n\t\t\t\t\treturn StElem(compilation.FindType(KnownTypeCode.Int16));\n\t\t\t\tcase ILOpCode.Stelem_i4:\n\t\t\t\t\treturn StElem(compilation.FindType(KnownTypeCode.Int32));\n\t\t\t\tcase ILOpCode.Stelem_i8:\n\t\t\t\t\treturn StElem(compilation.FindType(KnownTypeCode.Int64));\n\t\t\t\tcase ILOpCode.Stelem_r4:\n\t\t\t\t\treturn StElem(compilation.FindType(KnownTypeCode.Single));\n\t\t\t\tcase ILOpCode.Stelem_r8:\n\t\t\t\t\treturn StElem(compilation.FindType(KnownTypeCode.Double));\n\t\t\t\tcase ILOpCode.Stelem_i:\n\t\t\t\t\treturn StElem(compilation.FindType(KnownTypeCode.IntPtr));\n\t\t\t\tcase ILOpCode.Stelem_ref:\n\t\t\t\t\treturn StElem(compilation.FindType(KnownTypeCode.Object));\n\t\t\t\tcase ILOpCode.Stobj:\n\t\t\t\t{\n\t\t\t\t\tvar type = ReadAndDecodeTypeReference();\n\t\t\t\t\t// OK, target runs before value\n\t\t\t\t\treturn new StObj(value: Pop(type.GetStackType()), target: PopStObjTarget(), type: type);\n\t\t\t\t}\n\t\t\t\tcase ILOpCode.Throw:\n\t\t\t\t\treturn new Throw(Pop());\n\t\t\t\tcase ILOpCode.Unbox:\n\t\t\t\t\treturn Push(new Unbox(Pop(), ReadAndDecodeTypeReference()));\n\t\t\t\tcase ILOpCode.Unbox_any:\n\t\t\t\t\treturn Push(new UnboxAny(Pop(), ReadAndDecodeTypeReference()));\n\t\t\t\tdefault:\n\t\t\t\t\treturn new InvalidBranch($\"Unknown opcode: 0x{(int)opCode:X2}\");\n\t\t\t}\n\t\t}\n\n\t\tStackType PeekStackType()\n\t\t{\n\t\t\tif (expressionStack.Count > 0)\n\t\t\t\treturn expressionStack.Last().ResultType;\n\t\t\tif (currentStack.IsEmpty)\n\t\t\t\treturn StackType.Unknown;\n\t\t\telse\n\t\t\t\treturn currentStack.Peek().StackType;\n\t\t}\n\n\t\tsealed class CollectStackVariablesVisitor : ILVisitor<ILInstruction>\n\t\t{\n\t\t\treadonly UnionFind<ILVariable> unionFind;\n\t\t\tinternal readonly HashSet<ILVariable> variables = new HashSet<ILVariable>();\n\n\t\t\tpublic CollectStackVariablesVisitor(UnionFind<ILVariable> unionFind)\n\t\t\t{\n\t\t\t\tDebug.Assert(unionFind != null);\n\t\t\t\tthis.unionFind = unionFind;\n\t\t\t}\n\n\t\t\tprotected override ILInstruction Default(ILInstruction inst)\n\t\t\t{\n\t\t\t\tforeach (var child in inst.Children)\n\t\t\t\t{\n\t\t\t\t\tvar newChild = child.AcceptVisitor(this);\n\t\t\t\t\tif (newChild != child)\n\t\t\t\t\t\tchild.ReplaceWith(newChild);\n\t\t\t\t}\n\t\t\t\treturn inst;\n\t\t\t}\n\n\t\t\tprotected internal override ILInstruction VisitLdLoc(LdLoc inst)\n\t\t\t{\n\t\t\t\tbase.VisitLdLoc(inst);\n\t\t\t\tif (inst.Variable.Kind == VariableKind.StackSlot)\n\t\t\t\t{\n\t\t\t\t\tvar variable = unionFind.Find(inst.Variable);\n\t\t\t\t\tif (variables.Add(variable))\n\t\t\t\t\t\tvariable.Name = $\"S_{variables.Count - 1}\";\n\t\t\t\t\treturn new LdLoc(variable).WithILRange(inst);\n\t\t\t\t}\n\t\t\t\treturn inst;\n\t\t\t}\n\n\t\t\tprotected internal override ILInstruction VisitStLoc(StLoc inst)\n\t\t\t{\n\t\t\t\tbase.VisitStLoc(inst);\n\t\t\t\tif (inst.Variable.Kind == VariableKind.StackSlot)\n\t\t\t\t{\n\t\t\t\t\tvar variable = unionFind.Find(inst.Variable);\n\t\t\t\t\tif (variables.Add(variable))\n\t\t\t\t\t\tvariable.Name = $\"S_{variables.Count - 1}\";\n\t\t\t\t\treturn new StLoc(variable, inst.Value).WithILRange(inst);\n\t\t\t\t}\n\t\t\t\treturn inst;\n\t\t\t}\n\t\t}\n\n\t\tDecodedInstruction Push(ILInstruction inst)\n\t\t{\n\t\t\texpressionStack.Add(inst);\n\t\t\treturn new DecodedInstruction {\n\t\t\t\tInstruction = inst,\n\t\t\t\tPushedOnExpressionStack = true\n\t\t\t};\n\t\t}\n\n\t\tILInstruction Peek()\n\t\t{\n\t\t\tFlushExpressionStack();\n\t\t\tif (currentStack.IsEmpty)\n\t\t\t{\n\t\t\t\treturn new InvalidExpression(\"Stack underflow\").WithILRange(new Interval(reader.Offset, reader.Offset));\n\t\t\t}\n\t\t\treturn new LdLoc(currentStack.Peek());\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Pops a value/instruction from the evaluation stack.\n\t\t/// Note that instructions popped from the stack must be evaluated in the order they\n\t\t/// were pushed (so in reverse order of the pop calls!).\n\t\t/// \n\t\t/// For instructions like 'conv' that pop a single element and then push their result,\n\t\t/// it's fine to pop just one element as the instruction itself will end up on the stack,\n\t\t/// thus maintaining the evaluation order.\n\t\t/// For instructions like 'call' that pop multiple arguments, it's critical that\n\t\t/// the evaluation order of the resulting ILAst will be reverse from the order of the push\n\t\t/// calls.\n\t\t/// For instructions like 'brtrue', it's fine to pop only a part of the stack because\n\t\t/// ReadInstructions() will flush the evaluation stack before outputting the brtrue instruction.\n\t\t/// \n\t\t/// Use FlushExpressionStack() to ensure that following Pop() calls do not return\n\t\t/// instructions that involve side-effects. This way evaluation order is preserved\n\t\t/// no matter which order the ILAst will execute the popped instructions in.\n\t\t/// </summary>\n\t\tILInstruction Pop()\n\t\t{\n\t\t\tif (expressionStack.Count > 0)\n\t\t\t{\n\t\t\t\tvar inst = expressionStack.Last();\n\t\t\t\texpressionStack.RemoveAt(expressionStack.Count - 1);\n\t\t\t\treturn inst;\n\t\t\t}\n\t\t\tif (currentStack.IsEmpty)\n\t\t\t{\n\t\t\t\treturn new InvalidExpression(\"Stack underflow\").WithILRange(new Interval(reader.Offset, reader.Offset));\n\t\t\t}\n\t\t\tILVariable v;\n\t\t\tcurrentStack = currentStack.Pop(out v);\n\t\t\treturn new LdLoc(v);\n\t\t}\n\n\t\tILInstruction Pop(StackType expectedType)\n\t\t{\n\t\t\tILInstruction inst = Pop();\n\t\t\treturn Cast(inst, expectedType, Warnings, reader.Offset);\n\t\t}\n\n\t\tinternal static ILInstruction Cast(ILInstruction inst, StackType expectedType, List<string>? warnings, int ilOffset)\n\t\t{\n\t\t\tif (expectedType != inst.ResultType)\n\t\t\t{\n\t\t\t\tif (inst is InvalidExpression)\n\t\t\t\t{\n\t\t\t\t\t((InvalidExpression)inst).ExpectedResultType = expectedType;\n\t\t\t\t}\n\t\t\t\telse if (expectedType == StackType.I && inst.ResultType == StackType.I4)\n\t\t\t\t{\n\t\t\t\t\t// IL allows implicit I4->I conversions\n\t\t\t\t\tinst = new Conv(inst, PrimitiveType.I, false, Sign.None);\n\t\t\t\t}\n\t\t\t\telse if (expectedType == StackType.I4 && inst.ResultType == StackType.I)\n\t\t\t\t{\n\t\t\t\t\t// C++/CLI also sometimes implicitly converts in the other direction:\n\t\t\t\t\tinst = new Conv(inst, PrimitiveType.I4, false, Sign.None);\n\t\t\t\t}\n\t\t\t\telse if (expectedType == StackType.Unknown)\n\t\t\t\t{\n\t\t\t\t\tinst = new Conv(inst, PrimitiveType.Unknown, false, Sign.None);\n\t\t\t\t}\n\t\t\t\telse if (inst.ResultType == StackType.Ref)\n\t\t\t\t{\n\t\t\t\t\t// Implicitly stop GC tracking; this occurs when passing the result of 'ldloca' or 'ldsflda'\n\t\t\t\t\t// to a method expecting a native pointer.\n\t\t\t\t\tinst = new Conv(inst, PrimitiveType.I, false, Sign.None);\n\t\t\t\t\tswitch (expectedType)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase StackType.I4:\n\t\t\t\t\t\t\tinst = new Conv(inst, PrimitiveType.I4, false, Sign.None);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase StackType.I:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase StackType.I8:\n\t\t\t\t\t\t\tinst = new Conv(inst, PrimitiveType.I8, false, Sign.None);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tWarn($\"Expected {expectedType}, but got {StackType.Ref}\");\n\t\t\t\t\t\t\tinst = new Conv(inst, expectedType.ToPrimitiveType(), false, Sign.None);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (expectedType == StackType.Ref)\n\t\t\t\t{\n\t\t\t\t\t// implicitly start GC tracking / object to interior\n\t\t\t\t\tif (!inst.ResultType.IsIntegerType() && inst.ResultType != StackType.O)\n\t\t\t\t\t{\n\t\t\t\t\t\t// We also handle the invalid to-ref cases here because the else case\n\t\t\t\t\t\t// below uses expectedType.ToKnownTypeCode(), which doesn't work for Ref.\n\t\t\t\t\t\tWarn($\"Expected {expectedType}, but got {inst.ResultType}\");\n\t\t\t\t\t}\n\t\t\t\t\tinst = new Conv(inst, PrimitiveType.Ref, false, Sign.None);\n\t\t\t\t}\n\t\t\t\telse if (expectedType == StackType.F8 && inst.ResultType == StackType.F4)\n\t\t\t\t{\n\t\t\t\t\t// IL allows implicit F4->F8 conversions, because in IL F4 and F8 are the same.\n\t\t\t\t\tinst = new Conv(inst, PrimitiveType.R8, false, Sign.Signed);\n\t\t\t\t}\n\t\t\t\telse if (expectedType == StackType.F4 && inst.ResultType == StackType.F8)\n\t\t\t\t{\n\t\t\t\t\t// IL allows implicit F8->F4 conversions, because in IL F4 and F8 are the same.\n\t\t\t\t\tinst = new Conv(inst, PrimitiveType.R4, false, Sign.Signed);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tWarn($\"Expected {expectedType}, but got {inst.ResultType}\");\n\t\t\t\t\tinst = new Conv(inst, expectedType.ToPrimitiveType(), false, Sign.Signed);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn inst;\n\n\t\t\tvoid Warn(string message)\n\t\t\t{\n\t\t\t\tif (warnings != null)\n\t\t\t\t{\n\t\t\t\t\twarnings.Add(string.Format(\"IL_{0:x4}: {1}\", ilOffset, message));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tILInstruction PopPointer()\n\t\t{\n\t\t\tILInstruction inst = Pop();\n\t\t\tswitch (inst.ResultType)\n\t\t\t{\n\t\t\t\tcase StackType.I4:\n\t\t\t\tcase StackType.I8:\n\t\t\t\tcase StackType.Unknown:\n\t\t\t\t\treturn new Conv(inst, PrimitiveType.I, false, Sign.None);\n\t\t\t\tcase StackType.I:\n\t\t\t\tcase StackType.Ref:\n\t\t\t\t\treturn inst;\n\t\t\t\tdefault:\n\t\t\t\t\tWarn(\"Expected native int or pointer, but got \" + inst.ResultType);\n\t\t\t\t\treturn new Conv(inst, PrimitiveType.I, false, Sign.None);\n\t\t\t}\n\t\t}\n\n\t\tILInstruction PopStObjTarget()\n\t\t{\n\t\t\t// stobj has a special invariant (StObj.CheckTargetSlot)\n\t\t\t// that prohibits inlining LdElema/LdFlda.\n\t\t\tif (expressionStack.LastOrDefault() is LdElema or LdFlda)\n\t\t\t{\n\t\t\t\tFlushExpressionStack();\n\t\t\t}\n\t\t\treturn PopPointer();\n\t\t}\n\n\t\tILInstruction PopFieldTarget(IField field)\n\t\t{\n\t\t\tswitch (field.DeclaringType.IsReferenceType)\n\t\t\t{\n\t\t\t\tcase true:\n\t\t\t\t\treturn Pop(StackType.O);\n\t\t\t\tcase false:\n\t\t\t\t\treturn PopPointer();\n\t\t\t\tdefault:\n\t\t\t\t\t// field in unresolved type\n\t\t\t\t\tvar stackType = PeekStackType();\n\t\t\t\t\tif (stackType == StackType.O || stackType == StackType.Unknown)\n\t\t\t\t\t\treturn Pop();\n\t\t\t\t\telse\n\t\t\t\t\t\treturn PopPointer();\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Like PopFieldTarget, but supports ldfld's special behavior for fields of temporary value types.\n\t\t/// </summary>\n\t\tILInstruction PopLdFldTarget(IField field)\n\t\t{\n\t\t\tswitch (field.DeclaringType.IsReferenceType)\n\t\t\t{\n\t\t\t\tcase true:\n\t\t\t\t\treturn Pop(StackType.O);\n\t\t\t\tcase false:\n\t\t\t\t\t// field of value type: ldfld can handle temporaries\n\t\t\t\t\tif (PeekStackType() == StackType.O || PeekStackType() == StackType.Unknown)\n\t\t\t\t\t\treturn new AddressOf(Pop(), field.DeclaringType);\n\t\t\t\t\telse\n\t\t\t\t\t\treturn PopPointer();\n\t\t\t\tdefault:\n\t\t\t\t\t// field in unresolved type\n\t\t\t\t\tif (PeekStackType() == StackType.O || PeekStackType() == StackType.Unknown)\n\t\t\t\t\t\treturn Pop();\n\t\t\t\t\telse\n\t\t\t\t\t\treturn PopPointer();\n\t\t\t}\n\t\t}\n\n\t\tprivate ILInstruction Return()\n\t\t{\n\t\t\tif (methodReturnStackType == StackType.Void)\n\t\t\t{\n\t\t\t\treturn new IL.Leave(mainContainer);\n\t\t\t}\n\t\t\telse if (currentInstructionStart == 0)\n\t\t\t{\n\t\t\t\tDebug.Assert(expressionStack.Count == 0 && currentStack.IsEmpty);\n\t\t\t\treturn new InvalidBranch(\"Method body consists only of 'ret', but nothing is being returned. Decompiled assembly might be a reference assembly.\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new IL.Leave(mainContainer, Pop(methodReturnStackType));\n\t\t\t}\n\t\t}\n\n\t\tprivate ILInstruction DecodeLdstr()\n\t\t{\n\t\t\treturn new LdStr(ILParser.DecodeUserString(ref reader, metadata));\n\t\t}\n\n\t\tprivate ILInstruction Ldarg(int v)\n\t\t{\n\t\t\tif (v >= 0 && v < parameterVariables.Length)\n\t\t\t{\n\t\t\t\treturn new LdLoc(parameterVariables[v]);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new InvalidExpression($\"ldarg {v} (out-of-bounds)\");\n\t\t\t}\n\t\t}\n\n\t\tprivate ILInstruction Ldarga(int v)\n\t\t{\n\t\t\tif (v >= 0 && v < parameterVariables.Length)\n\t\t\t{\n\t\t\t\treturn new LdLoca(parameterVariables[v]);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new InvalidExpression($\"ldarga {v} (out-of-bounds)\");\n\t\t\t}\n\t\t}\n\n\t\tprivate ILInstruction Starg(int v)\n\t\t{\n\t\t\tif (v >= 0 && v < parameterVariables.Length)\n\t\t\t{\n\t\t\t\treturn new StLoc(parameterVariables[v], Pop(parameterVariables[v].StackType));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tFlushExpressionStack();\n\t\t\t\tPop();\n\t\t\t\treturn new InvalidExpression($\"starg {v} (out-of-bounds)\");\n\t\t\t}\n\t\t}\n\n\t\tprivate ILInstruction Ldloc(int v)\n\t\t{\n\t\t\tif (v >= 0 && v < localVariables.Length)\n\t\t\t{\n\t\t\t\treturn new LdLoc(localVariables[v]);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new InvalidExpression($\"ldloc {v} (out-of-bounds)\");\n\t\t\t}\n\t\t}\n\n\t\tprivate ILInstruction Ldloca(int v)\n\t\t{\n\t\t\tif (v >= 0 && v < localVariables.Length)\n\t\t\t{\n\t\t\t\treturn new LdLoca(localVariables[v]);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new InvalidExpression($\"ldloca {v} (out-of-bounds)\");\n\t\t\t}\n\t\t}\n\n\t\tprivate ILInstruction Stloc(int v)\n\t\t{\n\t\t\tif (v >= 0 && v < localVariables.Length)\n\t\t\t{\n\t\t\t\treturn new StLoc(localVariables[v], Pop(localVariables[v].StackType)) {\n\t\t\t\t\tILStackWasEmpty = CurrentStackIsEmpty()\n\t\t\t\t};\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tFlushExpressionStack();\n\t\t\t\tPop();\n\t\t\t\treturn new InvalidExpression($\"stloc {v} (out-of-bounds)\");\n\t\t\t}\n\t\t}\n\n\t\tprivate DecodedInstruction LdElem(IType type)\n\t\t{\n\t\t\treturn Push(new LdObj(new LdElema(indices: Pop(), array: Pop(), type: type) { DelayExceptions = true }, type));\n\t\t}\n\n\t\tprivate ILInstruction StElem(IType type)\n\t\t{\n\t\t\tvar value = Pop(type.GetStackType());\n\t\t\tvar index = Pop();\n\t\t\tvar array = Pop();\n\t\t\t// OK, evaluation order is array, index, value\n\t\t\treturn new StObj(new LdElema(type, array, index) { DelayExceptions = true }, value, type);\n\t\t}\n\n\t\tILInstruction InitObj(ILInstruction target, IType type)\n\t\t{\n\t\t\tvar value = new DefaultValue(type);\n\t\t\tvalue.ILStackWasEmpty = CurrentStackIsEmpty();\n\t\t\treturn new StObj(target, value, type);\n\t\t}\n\n\t\tIType? constrainedPrefix;\n\n\t\tprivate DecodedInstruction DecodeConstrainedCall()\n\t\t{\n\t\t\tconstrainedPrefix = ReadAndDecodeTypeReference();\n\t\t\tvar inst = DecodeInstruction();\n\t\t\tvar call = inst.Instruction as CallInstruction;\n\t\t\tif (call != null)\n\t\t\t\tDebug.Assert(call.ConstrainedTo == constrainedPrefix);\n\t\t\telse\n\t\t\t\tWarn(\"Ignored invalid 'constrained' prefix\");\n\t\t\tconstrainedPrefix = null;\n\t\t\treturn inst;\n\t\t}\n\n\t\tprivate DecodedInstruction DecodeTailCall()\n\t\t{\n\t\t\tvar inst = DecodeInstruction();\n\t\t\tvar call = inst.Instruction as CallInstruction;\n\t\t\tif (call != null)\n\t\t\t\tcall.IsTail = true;\n\t\t\telse\n\t\t\t\tWarn(\"Ignored invalid 'tail' prefix\");\n\t\t\treturn inst;\n\t\t}\n\n\t\tprivate DecodedInstruction DecodeUnaligned()\n\t\t{\n\t\t\tbyte alignment = reader.ReadByte();\n\t\t\tvar inst = DecodeInstruction();\n\t\t\tvar sup = inst.Instruction as ISupportsUnalignedPrefix;\n\t\t\tif (sup != null)\n\t\t\t\tsup.UnalignedPrefix = alignment;\n\t\t\telse\n\t\t\t\tWarn(\"Ignored invalid 'unaligned' prefix\");\n\t\t\treturn inst;\n\t\t}\n\n\t\tprivate DecodedInstruction DecodeVolatile()\n\t\t{\n\t\t\tvar inst = DecodeInstruction();\n\t\t\tvar svp = inst.Instruction as ISupportsVolatilePrefix;\n\t\t\tif (svp != null)\n\t\t\t\tsvp.IsVolatile = true;\n\t\t\telse\n\t\t\t\tWarn(\"Ignored invalid 'volatile' prefix\");\n\t\t\treturn inst;\n\t\t}\n\n\t\tprivate DecodedInstruction DecodeReadonly()\n\t\t{\n\t\t\tvar inst = DecodeInstruction();\n\t\t\tvar ldelema = inst.Instruction as LdElema;\n\t\t\tif (ldelema != null)\n\t\t\t\tldelema.IsReadOnly = true;\n\t\t\telse\n\t\t\t\tWarn(\"Ignored invalid 'readonly' prefix\");\n\t\t\treturn inst;\n\t\t}\n\n\t\tDecodedInstruction DecodeCall(OpCode opCode)\n\t\t{\n\t\t\tvar method = ReadAndDecodeMethodReference();\n\t\t\tILInstruction[] arguments;\n\t\t\tswitch (method.DeclaringType.Kind)\n\t\t\t{\n\t\t\t\tcase TypeKind.Array:\n\t\t\t\t{\n\t\t\t\t\targuments = PrepareArguments(firstArgumentIsStObjTarget: false);\n\t\t\t\t\tvar elementType = ((ArrayType)method.DeclaringType).ElementType;\n\t\t\t\t\tif (opCode == OpCode.NewObj)\n\t\t\t\t\t\treturn Push(new NewArr(elementType, arguments));\n\t\t\t\t\tif (method.Name == \"Set\")\n\t\t\t\t\t{\n\t\t\t\t\t\tvar target = arguments[0];\n\t\t\t\t\t\tvar indices = arguments.Skip(1).Take(arguments.Length - 2).ToArray();\n\t\t\t\t\t\tvar value = arguments.Last();\n\t\t\t\t\t\t// preserves evaluation order target,indices,value\n\t\t\t\t\t\treturn new StObj(new LdElema(elementType, target, indices) { DelayExceptions = true }, value, elementType);\n\t\t\t\t\t}\n\t\t\t\t\tif (method.Name == \"Get\")\n\t\t\t\t\t{\n\t\t\t\t\t\tvar target = arguments[0];\n\t\t\t\t\t\tvar indices = arguments.Skip(1).ToArray();\n\t\t\t\t\t\t// preserves evaluation order target,indices\n\t\t\t\t\t\treturn Push(new LdObj(new LdElema(elementType, target, indices) { DelayExceptions = true }, elementType));\n\t\t\t\t\t}\n\t\t\t\t\tif (method.Name == \"Address\")\n\t\t\t\t\t{\n\t\t\t\t\t\tvar target = arguments[0];\n\t\t\t\t\t\tvar indices = arguments.Skip(1).ToArray();\n\t\t\t\t\t\t// preserves evaluation order target,indices\n\t\t\t\t\t\treturn Push(new LdElema(elementType, target, indices));\n\t\t\t\t\t}\n\t\t\t\t\tWarn(\"Unknown method called on array type: \" + method.Name);\n\t\t\t\t\tgoto default;\n\t\t\t\t}\n\t\t\t\tcase TypeKind.Struct when method.IsConstructor && !method.IsStatic && opCode == OpCode.Call\n\t\t\t\t\t&& method.ReturnType.Kind == TypeKind.Void:\n\t\t\t\t{\n\t\t\t\t\t// \"call Struct.ctor(target, ...)\" doesn't exist in C#,\n\t\t\t\t\t// the next best equivalent is an assignment `*target = new Struct(...);`.\n\t\t\t\t\t// So we represent this call as \"stobj Struct(target, newobj Struct.ctor(...))\".\n\t\t\t\t\t// This needs to happen early (not as a transform) because the StObj.TargetSlot has\n\t\t\t\t\t// restricted inlining (doesn't accept ldflda when exceptions aren't delayed).\n\t\t\t\t\targuments = PrepareArguments(firstArgumentIsStObjTarget: true);\n\t\t\t\t\tvar newobj = new NewObj(method);\n\t\t\t\t\tnewobj.ILStackWasEmpty = CurrentStackIsEmpty();\n\t\t\t\t\tnewobj.ConstrainedTo = constrainedPrefix;\n\t\t\t\t\tnewobj.Arguments.AddRange(arguments.Skip(1));\n\t\t\t\t\treturn new StObj(arguments[0], newobj, method.DeclaringType);\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\targuments = PrepareArguments(firstArgumentIsStObjTarget: false);\n\t\t\t\t\tvar call = CallInstruction.Create(opCode, method);\n\t\t\t\t\tcall.ILStackWasEmpty = CurrentStackIsEmpty();\n\t\t\t\t\tcall.ConstrainedTo = constrainedPrefix;\n\t\t\t\t\tcall.Arguments.AddRange(arguments);\n\t\t\t\t\tif (call.ResultType != StackType.Void)\n\t\t\t\t\t\treturn Push(call);\n\t\t\t\t\treturn call;\n\t\t\t}\n\n\t\t\tILInstruction[] PrepareArguments(bool firstArgumentIsStObjTarget)\n\t\t\t{\n\t\t\t\tint firstArgument = (opCode != OpCode.NewObj && !method.IsStatic) ? 1 : 0;\n\t\t\t\tvar arguments = new ILInstruction[firstArgument + method.Parameters.Count];\n\t\t\t\tIType typeOfThis = constrainedPrefix ?? method.DeclaringType;\n\t\t\t\tStackType expectedStackType = CallInstruction.ExpectedTypeForThisPointer(method.DeclaringType, constrainedPrefix);\n\t\t\t\tbool requiresLdObjIfRef = firstArgument == 1\n\t\t\t\t\t&& !firstArgumentIsStObjTarget\n\t\t\t\t\t&& UseRefLocalsForAccurateOrderOfEvaluation\n\t\t\t\t\t&& expectedStackType == StackType.Ref && typeOfThis.IsReferenceType != false;\n\t\t\t\tfor (int i = method.Parameters.Count - 1; i >= 0; i--)\n\t\t\t\t{\n\t\t\t\t\tif (requiresLdObjIfRef)\n\t\t\t\t\t{\n\t\t\t\t\t\tFlushExpressionStack();\n\t\t\t\t\t}\n\n\t\t\t\t\targuments[firstArgument + i] = Pop(method.Parameters[i].Type.GetStackType());\n\t\t\t\t}\n\t\t\t\tif (firstArgument == 1)\n\t\t\t\t{\n\t\t\t\t\tILInstruction firstArgumentInstruction;\n\t\t\t\t\tif (firstArgumentIsStObjTarget)\n\t\t\t\t\t{\n\t\t\t\t\t\tfirstArgumentInstruction = PopStObjTarget();\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tfirstArgumentInstruction = Pop(expectedStackType);\n\t\t\t\t\t\tif (requiresLdObjIfRef)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfirstArgumentInstruction = new LdObjIfRef(firstArgumentInstruction, typeOfThis);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\targuments[0] = firstArgumentInstruction;\n\t\t\t\t}\n\t\t\t\t// arguments is in reverse order of the Pop calls, thus\n\t\t\t\t// arguments is now in the correct evaluation order.\n\t\t\t\treturn arguments;\n\t\t\t}\n\t\t}\n\n\t\tDecodedInstruction DecodeCallIndirect()\n\t\t{\n\t\t\tStandaloneSignatureHandle signatureHandle;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tsignatureHandle = (StandaloneSignatureHandle)ReadAndDecodeMetadataToken();\n\t\t\t}\n\t\t\tcatch (InvalidCastException ex)\n\t\t\t{\n\t\t\t\tthrow new BadImageFormatException(\"Invalid calli metadata token\", ex);\n\t\t\t}\n\t\t\tvar (header, fpt) = module.DecodeMethodSignature(signatureHandle, genericContext);\n\t\t\tvar functionPointer = Pop(StackType.I);\n\t\t\tint firstArgument = header.IsInstance ? 1 : 0;\n\t\t\tvar arguments = new ILInstruction[firstArgument + fpt.ParameterTypes.Length];\n\t\t\tfor (int i = fpt.ParameterTypes.Length - 1; i >= 0; i--)\n\t\t\t{\n\t\t\t\targuments[firstArgument + i] = Pop(fpt.ParameterTypes[i].GetStackType());\n\t\t\t}\n\t\t\tif (firstArgument == 1)\n\t\t\t{\n\t\t\t\targuments[0] = Pop();\n\t\t\t}\n\t\t\t// arguments is in reverse order of the Pop calls, thus\n\t\t\t// arguments is now in the correct evaluation order.\n\t\t\tvar call = new CallIndirect(\n\t\t\t\theader.IsInstance,\n\t\t\t\theader.HasExplicitThis,\n\t\t\t\tfpt,\n\t\t\t\tfunctionPointer,\n\t\t\t\targuments\n\t\t\t);\n\t\t\tif (call.ResultType != StackType.Void)\n\t\t\t\treturn Push(call);\n\t\t\telse\n\t\t\t\treturn call;\n\t\t}\n\n\t\tILInstruction Comparison(ComparisonKind kind, bool un = false)\n\t\t{\n\t\t\tif (!kind.IsEqualityOrInequality() && PeekStackType() == StackType.O)\n\t\t\t{\n\t\t\t\tFlushExpressionStack();\n\t\t\t}\n\n\t\t\tvar right = Pop();\n\t\t\tvar left = Pop();\n\t\t\t// left will run before right, thus preserving the evaluation order\n\n\t\t\tif ((left.ResultType == StackType.O || left.ResultType == StackType.Ref) && right.ResultType.IsIntegerType())\n\t\t\t{\n\t\t\t\t// C++/CLI sometimes compares object references with integers.\n\t\t\t\t// Also happens with Ref==I in Unsafe.IsNullRef().\n\t\t\t\tif (right.ResultType == StackType.I4)\n\t\t\t\t{\n\t\t\t\t\t// ensure we compare at least native integer size\n\t\t\t\t\tright = new Conv(right, PrimitiveType.I, false, Sign.None);\n\t\t\t\t}\n\t\t\t\tleft = new Conv(left, right.ResultType.ToPrimitiveType(), false, Sign.None);\n\t\t\t}\n\t\t\telse if ((right.ResultType == StackType.O || right.ResultType == StackType.Ref) && left.ResultType.IsIntegerType())\n\t\t\t{\n\t\t\t\tif (left.ResultType == StackType.I4)\n\t\t\t\t{\n\t\t\t\t\tleft = new Conv(left, PrimitiveType.I, false, Sign.None);\n\t\t\t\t}\n\t\t\t\tright = new Conv(right, left.ResultType.ToPrimitiveType(), false, Sign.None);\n\t\t\t}\n\n\t\t\t// make implicit integer conversions explicit:\n\t\t\tMakeExplicitConversion(sourceType: StackType.I4, targetType: StackType.I, conversionType: PrimitiveType.I);\n\t\t\tMakeExplicitConversion(sourceType: StackType.I4, targetType: StackType.I8, conversionType: PrimitiveType.I8);\n\t\t\tMakeExplicitConversion(sourceType: StackType.I, targetType: StackType.I8, conversionType: PrimitiveType.I8);\n\n\t\t\t// Based on Table 4: Binary Comparison or Branch Operation\n\t\t\tif (left.ResultType.IsFloatType() && right.ResultType.IsFloatType())\n\t\t\t{\n\t\t\t\tif (left.ResultType != right.ResultType)\n\t\t\t\t{\n\t\t\t\t\t// make the implicit F4->F8 conversion explicit:\n\t\t\t\t\tMakeExplicitConversion(StackType.F4, StackType.F8, PrimitiveType.R8);\n\t\t\t\t}\n\t\t\t\tif (un)\n\t\t\t\t{\n\t\t\t\t\t// for floats, 'un' means 'unordered'\n\t\t\t\t\treturn Comp.LogicNot(new Comp(kind.Negate(), Sign.None, left, right));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn new Comp(kind, Sign.None, left, right);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (left.ResultType.IsIntegerType() && right.ResultType.IsIntegerType() && !kind.IsEqualityOrInequality())\n\t\t\t{\n\t\t\t\t// integer comparison where the sign matters\n\t\t\t\tDebug.Assert(right.ResultType.IsIntegerType());\n\t\t\t\treturn new Comp(kind, un ? Sign.Unsigned : Sign.Signed, left, right);\n\t\t\t}\n\t\t\telse if (left.ResultType == right.ResultType)\n\t\t\t{\n\t\t\t\t// integer equality, object reference or managed reference comparison\n\t\t\t\treturn new Comp(kind, Sign.None, left, right);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tWarn($\"Invalid comparison between {left.ResultType} and {right.ResultType}\");\n\t\t\t\tif (left.ResultType < right.ResultType)\n\t\t\t\t{\n\t\t\t\t\tleft = new Conv(left, right.ResultType.ToPrimitiveType(), false, Sign.Signed);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tright = new Conv(right, left.ResultType.ToPrimitiveType(), false, Sign.Signed);\n\t\t\t\t}\n\t\t\t\treturn new Comp(kind, Sign.None, left, right);\n\t\t\t}\n\n\t\t\tvoid MakeExplicitConversion(StackType sourceType, StackType targetType, PrimitiveType conversionType)\n\t\t\t{\n\t\t\t\tif (left.ResultType == sourceType && right.ResultType == targetType)\n\t\t\t\t{\n\t\t\t\t\tleft = new Conv(left, conversionType, false, Sign.None);\n\t\t\t\t}\n\t\t\t\telse if (left.ResultType == targetType && right.ResultType == sourceType)\n\t\t\t\t{\n\t\t\t\t\tright = new Conv(right, conversionType, false, Sign.None);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool IsInvalidBranch(int target) => target < 0 || target >= reader.Length;\n\n\t\tILInstruction DecodeComparisonBranch(ILOpCode opCode, ComparisonKind kind, bool un = false)\n\t\t{\n\t\t\tint start = reader.Offset - 1; // opCode is always one byte in this case\n\t\t\tint target = ILParser.DecodeBranchTarget(ref reader, opCode);\n\t\t\tvar condition = Comparison(kind, un);\n\t\t\tcondition.AddILRange(new Interval(start, reader.Offset));\n\t\t\tif (!IsInvalidBranch(target))\n\t\t\t{\n\t\t\t\tMarkBranchTarget(target);\n\t\t\t\treturn new IfInstruction(condition, new Branch(target));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new IfInstruction(condition, new InvalidBranch(\"Invalid branch target\"));\n\t\t\t}\n\t\t}\n\n\t\tILInstruction DecodeConditionalBranch(ILOpCode opCode, bool negate)\n\t\t{\n\t\t\tint target = ILParser.DecodeBranchTarget(ref reader, opCode);\n\t\t\tILInstruction condition = Pop();\n\t\t\tswitch (condition.ResultType)\n\t\t\t{\n\t\t\t\tcase StackType.O:\n\t\t\t\t\t// introduce explicit comparison with null\n\t\t\t\t\tcondition = new Comp(\n\t\t\t\t\t\tnegate ? ComparisonKind.Equality : ComparisonKind.Inequality,\n\t\t\t\t\t\tSign.None, condition, new LdNull());\n\t\t\t\t\tbreak;\n\t\t\t\tcase StackType.I:\n\t\t\t\t\t// introduce explicit comparison with 0\n\t\t\t\t\tcondition = new Comp(\n\t\t\t\t\t\tnegate ? ComparisonKind.Equality : ComparisonKind.Inequality,\n\t\t\t\t\t\tSign.None, condition, new Conv(new LdcI4(0), PrimitiveType.I, false, Sign.None));\n\t\t\t\t\tbreak;\n\t\t\t\tcase StackType.I8:\n\t\t\t\t\t// introduce explicit comparison with 0\n\t\t\t\t\tcondition = new Comp(\n\t\t\t\t\t\tnegate ? ComparisonKind.Equality : ComparisonKind.Inequality,\n\t\t\t\t\t\tSign.None, condition, new LdcI8(0));\n\t\t\t\t\tbreak;\n\t\t\t\tcase StackType.Ref:\n\t\t\t\t\t// introduce explicit comparison with null ref\n\t\t\t\t\tcondition = new Comp(\n\t\t\t\t\t\tnegate ? ComparisonKind.Equality : ComparisonKind.Inequality,\n\t\t\t\t\t\tSign.None, new Conv(condition, PrimitiveType.I, false, Sign.None), new Conv(new LdcI4(0), PrimitiveType.I, false, Sign.None));\n\t\t\t\t\tbreak;\n\t\t\t\tcase StackType.I4:\n\t\t\t\t\tif (negate)\n\t\t\t\t\t{\n\t\t\t\t\t\tcondition = Comp.LogicNot(condition);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tcondition = new Conv(condition, PrimitiveType.I4, false, Sign.None);\n\t\t\t\t\tif (negate)\n\t\t\t\t\t{\n\t\t\t\t\t\tcondition = Comp.LogicNot(condition);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!IsInvalidBranch(target))\n\t\t\t{\n\t\t\t\tMarkBranchTarget(target);\n\t\t\t\treturn new IfInstruction(condition, new Branch(target));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new IfInstruction(condition, new InvalidBranch(\"Invalid branch target\"));\n\t\t\t}\n\t\t}\n\n\t\tILInstruction DecodeUnconditionalBranch(ILOpCode opCode, bool isLeave = false)\n\t\t{\n\t\t\tint target = ILParser.DecodeBranchTarget(ref reader, opCode);\n\t\t\tif (isLeave)\n\t\t\t{\n\t\t\t\tFlushExpressionStack();\n\t\t\t\tcurrentStack = currentStack.Clear();\n\t\t\t}\n\t\t\tif (!IsInvalidBranch(target))\n\t\t\t{\n\t\t\t\tMarkBranchTarget(target);\n\t\t\t\treturn new Branch(target);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new InvalidBranch(\"Invalid branch target\");\n\t\t\t}\n\t\t}\n\n\t\tvoid MarkBranchTarget(int targetILOffset, bool isFallThrough = false)\n\t\t{\n\t\t\tFlushExpressionStack();\n\t\t\tDebug.Assert(isFallThrough || isBranchTarget[targetILOffset]);\n\t\t\tvar targetBlock = StoreStackForOffset(targetILOffset, currentStack);\n\t\t\tDebug.Assert(currentBlock != null);\n\t\t\tcurrentBlock.OutgoingEdges.Add((targetBlock, currentStack));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// The expression stack holds ILInstructions that might have side-effects\n\t\t/// that should have already happened (in the order of the pushes).\n\t\t/// This method forces these instructions to be added to the instructionBuilder.\n\t\t/// This is used e.g. to avoid moving side-effects past branches.\n\t\t/// </summary>\n\t\tprivate void FlushExpressionStack()\n\t\t{\n\t\t\tDebug.Assert(currentBlock != null);\n\t\t\tforeach (var inst in expressionStack)\n\t\t\t{\n\t\t\t\tDebug.Assert(inst.ResultType != StackType.Void);\n\t\t\t\tIType type = compilation.FindType(inst.ResultType);\n\t\t\t\tvar v = new ILVariable(VariableKind.StackSlot, type, inst.ResultType);\n\t\t\t\tv.HasGeneratedName = true;\n\t\t\t\tcurrentStack = currentStack.Push(v);\n\t\t\t\tcurrentBlock.Block.Instructions.Add(new StLoc(v, inst).WithILRange(inst));\n\t\t\t}\n\t\t\texpressionStack.Clear();\n\t\t}\n\n\t\tILInstruction DecodeSwitch()\n\t\t{\n\t\t\tvar targets = ILParser.DecodeSwitchTargets(ref reader);\n\t\t\tvar instr = new SwitchInstruction(Pop(StackType.I4));\n\n\t\t\tfor (int i = 0; i < targets.Length; i++)\n\t\t\t{\n\t\t\t\tvar section = new SwitchSection();\n\t\t\t\tsection.Labels = new LongSet(i);\n\t\t\t\tint target = targets[i];\n\t\t\t\tif (!IsInvalidBranch(target))\n\t\t\t\t{\n\t\t\t\t\tMarkBranchTarget(target);\n\t\t\t\t\tsection.Body = new Branch(target);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsection.Body = new InvalidBranch(\"Invalid branch target\");\n\t\t\t\t}\n\t\t\t\tinstr.Sections.Add(section);\n\t\t\t}\n\t\t\tvar defaultSection = new SwitchSection();\n\t\t\tdefaultSection.Labels = new LongSet(new LongInterval(0, targets.Length)).Invert();\n\t\t\tdefaultSection.Body = new Nop();\n\t\t\tinstr.Sections.Add(defaultSection);\n\t\t\treturn instr;\n\t\t}\n\n\t\tDecodedInstruction BinaryNumeric(BinaryNumericOperator @operator, bool checkForOverflow = false, Sign sign = Sign.None)\n\t\t{\n\t\t\tvar right = Pop();\n\t\t\tvar left = Pop();\n\t\t\t// left will run before right, thus preserving the evaluation order\n\t\t\tif (@operator != BinaryNumericOperator.Add && @operator != BinaryNumericOperator.Sub)\n\t\t\t{\n\t\t\t\t// we are treating all Refs as I, make the conversion explicit\n\t\t\t\tif (left.ResultType == StackType.Ref)\n\t\t\t\t{\n\t\t\t\t\tleft = new Conv(left, PrimitiveType.I, false, Sign.None);\n\t\t\t\t}\n\t\t\t\tif (right.ResultType == StackType.Ref)\n\t\t\t\t{\n\t\t\t\t\tright = new Conv(right, PrimitiveType.I, false, Sign.None);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (@operator != BinaryNumericOperator.ShiftLeft && @operator != BinaryNumericOperator.ShiftRight)\n\t\t\t{\n\t\t\t\t// make the implicit I4->I conversion explicit:\n\t\t\t\tMakeExplicitConversion(sourceType: StackType.I4, targetType: StackType.I, conversionType: PrimitiveType.I);\n\t\t\t\t// I4->I8 conversion:\n\t\t\t\tMakeExplicitConversion(sourceType: StackType.I4, targetType: StackType.I8, conversionType: PrimitiveType.I8);\n\t\t\t\t// I->I8 conversion:\n\t\t\t\tMakeExplicitConversion(sourceType: StackType.I, targetType: StackType.I8, conversionType: PrimitiveType.I8);\n\t\t\t\t// F4->F8 conversion:\n\t\t\t\tMakeExplicitConversion(sourceType: StackType.F4, targetType: StackType.F8, conversionType: PrimitiveType.R8);\n\t\t\t}\n\t\t\treturn Push(new BinaryNumericInstruction(@operator, left, right, checkForOverflow, sign));\n\n\t\t\tvoid MakeExplicitConversion(StackType sourceType, StackType targetType, PrimitiveType conversionType)\n\t\t\t{\n\t\t\t\tif (left.ResultType == sourceType && right.ResultType == targetType)\n\t\t\t\t{\n\t\t\t\t\tleft = new Conv(left, conversionType, false, Sign.None);\n\t\t\t\t}\n\t\t\t\telse if (left.ResultType == targetType && right.ResultType == sourceType)\n\t\t\t\t{\n\t\t\t\t\tright = new Conv(right, conversionType, false, Sign.None);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tILInstruction DecodeJmp()\n\t\t{\n\t\t\tIMethod method = ReadAndDecodeMethodReference();\n\t\t\t// Translate jmp into tail call:\n\t\t\tCall call = new Call(method);\n\t\t\tcall.IsTail = true;\n\t\t\tcall.ILStackWasEmpty = true;\n\t\t\tif (!method.IsStatic)\n\t\t\t{\n\t\t\t\tcall.Arguments.Add(Ldarg(0));\n\t\t\t}\n\t\t\tforeach (var p in method.Parameters)\n\t\t\t{\n\t\t\t\tcall.Arguments.Add(Ldarg(call.Arguments.Count));\n\t\t\t}\n\t\t\treturn new Leave(mainContainer, call);\n\t\t}\n\n\t\tILInstruction LdToken(EntityHandle token)\n\t\t{\n\t\t\tif (token.Kind.IsTypeKind())\n\t\t\t\treturn new LdTypeToken(module.ResolveType(token, genericContext));\n\t\t\tif (token.Kind.IsMemberKind())\n\t\t\t{\n\t\t\t\tvar entity = module.ResolveEntity(token, genericContext);\n\t\t\t\tif (entity is IMember member)\n\t\t\t\t\treturn new LdMemberToken(member);\n\t\t\t}\n\t\t\tthrow new BadImageFormatException(\"Invalid metadata token for ldtoken instruction.\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ILTypeExtensions.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tstatic class ILTypeExtensions\n\t{\n\t\tpublic static StackType GetStackType(this PrimitiveType primitiveType)\n\t\t{\n\t\t\tswitch (primitiveType)\n\t\t\t{\n\t\t\t\tcase PrimitiveType.I1:\n\t\t\t\tcase PrimitiveType.U1:\n\t\t\t\tcase PrimitiveType.I2:\n\t\t\t\tcase PrimitiveType.U2:\n\t\t\t\tcase PrimitiveType.I4:\n\t\t\t\tcase PrimitiveType.U4:\n\t\t\t\t\treturn StackType.I4;\n\t\t\t\tcase PrimitiveType.I8:\n\t\t\t\tcase PrimitiveType.U8:\n\t\t\t\t\treturn StackType.I8;\n\t\t\t\tcase PrimitiveType.I:\n\t\t\t\tcase PrimitiveType.U:\n\t\t\t\t\treturn StackType.I;\n\t\t\t\tcase PrimitiveType.R4:\n\t\t\t\t\treturn StackType.F4;\n\t\t\t\tcase PrimitiveType.R8:\n\t\t\t\tcase PrimitiveType.R:\n\t\t\t\t\treturn StackType.F8;\n\t\t\t\tcase PrimitiveType.Ref: // ByRef\n\t\t\t\t\treturn StackType.Ref;\n\t\t\t\tcase PrimitiveType.Unknown:\n\t\t\t\t\treturn StackType.Unknown;\n\t\t\t\tdefault:\n\t\t\t\t\treturn StackType.O;\n\t\t\t}\n\t\t}\n\n\t\tpublic static Sign GetSign(this PrimitiveType primitiveType)\n\t\t{\n\t\t\tswitch (primitiveType)\n\t\t\t{\n\t\t\t\tcase PrimitiveType.I1:\n\t\t\t\tcase PrimitiveType.I2:\n\t\t\t\tcase PrimitiveType.I4:\n\t\t\t\tcase PrimitiveType.I8:\n\t\t\t\tcase PrimitiveType.R4:\n\t\t\t\tcase PrimitiveType.R8:\n\t\t\t\tcase PrimitiveType.R:\n\t\t\t\tcase PrimitiveType.I:\n\t\t\t\t\treturn Sign.Signed;\n\t\t\t\tcase PrimitiveType.U1:\n\t\t\t\tcase PrimitiveType.U2:\n\t\t\t\tcase PrimitiveType.U4:\n\t\t\t\tcase PrimitiveType.U8:\n\t\t\t\tcase PrimitiveType.U:\n\t\t\t\t\treturn Sign.Unsigned;\n\t\t\t\tdefault:\n\t\t\t\t\treturn Sign.None;\n\t\t\t}\n\t\t}\n\n\t\tpublic static bool HasOppositeSign(this PrimitiveType primitiveType)\n\t\t{\n\t\t\tswitch (primitiveType)\n\t\t\t{\n\t\t\t\tcase PrimitiveType.I1:\n\t\t\t\tcase PrimitiveType.I2:\n\t\t\t\tcase PrimitiveType.I4:\n\t\t\t\tcase PrimitiveType.I8:\n\t\t\t\tcase PrimitiveType.U1:\n\t\t\t\tcase PrimitiveType.U2:\n\t\t\t\tcase PrimitiveType.U4:\n\t\t\t\tcase PrimitiveType.U8:\n\t\t\t\tcase PrimitiveType.I:\n\t\t\t\tcase PrimitiveType.U:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the size in bytes of the primitive type.\n\t\t/// \n\t\t/// Returns 0 for non-primitive types.\n\t\t/// Returns <c>NativeIntSize</c> for native int/references.\n\t\t/// </summary>\n\t\tpublic static int GetSize(this PrimitiveType type)\n\t\t{\n\t\t\tswitch (type)\n\t\t\t{\n\t\t\t\tcase PrimitiveType.I1:\n\t\t\t\tcase PrimitiveType.U1:\n\t\t\t\t\treturn 1;\n\t\t\t\tcase PrimitiveType.I2:\n\t\t\t\tcase PrimitiveType.U2:\n\t\t\t\t\treturn 2;\n\t\t\t\tcase PrimitiveType.I4:\n\t\t\t\tcase PrimitiveType.U4:\n\t\t\t\tcase PrimitiveType.R4:\n\t\t\t\t\treturn 4;\n\t\t\t\tcase PrimitiveType.I8:\n\t\t\t\tcase PrimitiveType.R8:\n\t\t\t\tcase PrimitiveType.U8:\n\t\t\t\tcase PrimitiveType.R:\n\t\t\t\t\treturn 8;\n\t\t\t\tcase PrimitiveType.I:\n\t\t\t\tcase PrimitiveType.U:\n\t\t\t\tcase PrimitiveType.Ref:\n\t\t\t\t\treturn TypeUtils.NativeIntSize;\n\t\t\t\tdefault:\n\t\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the type is a small integer type.\n\t\t/// Small integer types are:\n\t\t/// * bool, sbyte, byte, char, short, ushort\n\t\t/// * any enums that have a small integer type as underlying type\n\t\t/// </summary>\n\t\tpublic static bool IsSmallIntegerType(this PrimitiveType type)\n\t\t{\n\t\t\treturn GetSize(type) < 4;\n\t\t}\n\n\t\tpublic static bool IsIntegerType(this PrimitiveType primitiveType)\n\t\t{\n\t\t\treturn primitiveType.GetStackType().IsIntegerType();\n\t\t}\n\n\t\tpublic static bool IsFloatType(this PrimitiveType type)\n\t\t{\n\t\t\tswitch (type)\n\t\t\t{\n\t\t\t\tcase PrimitiveType.R4:\n\t\t\t\tcase PrimitiveType.R8:\n\t\t\t\tcase PrimitiveType.R:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Infers the C# type for an IL instruction.\n\t\t/// \n\t\t/// Returns SpecialType.UnknownType for unsupported instructions.\n\t\t/// </summary>\n\t\tpublic static IType InferType(this ILInstruction inst, ICompilation? compilation)\n\t\t{\n\t\t\tswitch (inst)\n\t\t\t{\n\t\t\t\tcase NewObj newObj:\n\t\t\t\t\treturn newObj.Method.DeclaringType ?? SpecialType.UnknownType;\n\t\t\t\tcase NewArr newArr:\n\t\t\t\t\tif (compilation != null)\n\t\t\t\t\t\treturn new ArrayType(compilation, newArr.Type, newArr.Indices.Count);\n\t\t\t\t\telse\n\t\t\t\t\t\treturn SpecialType.UnknownType;\n\t\t\t\tcase Call call:\n\t\t\t\t\treturn call.Method.ReturnType;\n\t\t\t\tcase CallVirt callVirt:\n\t\t\t\t\treturn callVirt.Method.ReturnType;\n\t\t\t\tcase CallIndirect calli:\n\t\t\t\t\treturn calli.FunctionPointerType.ReturnType;\n\t\t\t\tcase UserDefinedLogicOperator logicOp:\n\t\t\t\t\treturn logicOp.Method.ReturnType;\n\t\t\t\tcase LdObj ldobj:\n\t\t\t\t\treturn ldobj.Type;\n\t\t\t\tcase StObj stobj:\n\t\t\t\t\treturn stobj.Type;\n\t\t\t\tcase LdLoc ldloc:\n\t\t\t\t\treturn ldloc.Variable.Type;\n\t\t\t\tcase StLoc stloc:\n\t\t\t\t\treturn stloc.Variable.Type;\n\t\t\t\tcase LdLoca ldloca:\n\t\t\t\t\treturn new ByReferenceType(ldloca.Variable.Type);\n\t\t\t\tcase LdFlda ldflda:\n\t\t\t\t\treturn new ByReferenceType(ldflda.Field.Type);\n\t\t\t\tcase LdsFlda ldsflda:\n\t\t\t\t\treturn new ByReferenceType(ldsflda.Field.Type);\n\t\t\t\tcase LdElema ldelema:\n\t\t\t\t\tif (ldelema.Array.InferType(compilation) is ArrayType arrayType)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (TypeUtils.IsCompatibleTypeForMemoryAccess(arrayType.ElementType, ldelema.Type))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn new ByReferenceType(arrayType.ElementType);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn new ByReferenceType(ldelema.Type);\n\t\t\t\tcase Comp comp:\n\t\t\t\t\tif (compilation == null)\n\t\t\t\t\t\treturn SpecialType.UnknownType;\n\t\t\t\t\tswitch (comp.LiftingKind)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase ComparisonLiftingKind.None:\n\t\t\t\t\t\tcase ComparisonLiftingKind.CSharp:\n\t\t\t\t\t\t\treturn compilation.FindType(KnownTypeCode.Boolean);\n\t\t\t\t\t\tcase ComparisonLiftingKind.ThreeValuedLogic:\n\t\t\t\t\t\t\treturn NullableType.Create(compilation, compilation.FindType(KnownTypeCode.Boolean));\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn SpecialType.UnknownType;\n\t\t\t\t\t}\n\t\t\t\tcase BinaryNumericInstruction bni:\n\t\t\t\t\tif (bni.IsLifted)\n\t\t\t\t\t\treturn SpecialType.UnknownType;\n\t\t\t\t\tswitch (bni.Operator)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase BinaryNumericOperator.BitAnd:\n\t\t\t\t\t\tcase BinaryNumericOperator.BitOr:\n\t\t\t\t\t\tcase BinaryNumericOperator.BitXor:\n\t\t\t\t\t\t\tvar left = bni.Left.InferType(compilation);\n\t\t\t\t\t\t\tvar right = bni.Right.InferType(compilation);\n\t\t\t\t\t\t\tif (left.Equals(right) && (left.IsCSharpPrimitiveIntegerType() || left.IsCSharpNativeIntegerType() || left.IsKnownType(KnownTypeCode.Boolean)))\n\t\t\t\t\t\t\t\treturn left;\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\treturn SpecialType.UnknownType;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn SpecialType.UnknownType;\n\t\t\t\t\t}\n\t\t\t\tcase DefaultValue defaultValue:\n\t\t\t\t\treturn defaultValue.Type;\n\t\t\t\tcase ILFunction func when func.DelegateType != null:\n\t\t\t\t\treturn func.DelegateType;\n\t\t\t\tdefault:\n\t\t\t\t\treturn SpecialType.UnknownType;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/ILVariable.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpublic enum VariableKind\n\t{\n\t\t/// <summary>\n\t\t/// A local variable.\n\t\t/// </summary>\n\t\tLocal,\n\t\t/// <summary>\n\t\t/// A pinned local variable (not associated with a pinned region)\n\t\t/// </summary>\n\t\tPinnedLocal,\n\t\t/// <summary>\n\t\t/// A pinned local variable (associated with a pinned region)\n\t\t/// </summary>\n\t\tPinnedRegionLocal,\n\t\t/// <summary>\n\t\t/// A local variable used as using-resource variable.\n\t\t/// </summary>\n\t\tUsingLocal,\n\t\t/// <summary>\n\t\t/// A local variable used as foreach variable.\n\t\t/// </summary>\n\t\tForeachLocal,\n\t\t/// <summary>\n\t\t/// A local variable used inside an array, collection or\n\t\t/// object initializer block to denote the object being initialized.\n\t\t/// </summary>\n\t\tInitializerTarget,\n\t\t/// <summary>\n\t\t/// A parameter.\n\t\t/// </summary>\n\t\tParameter,\n\t\t/// <summary>\n\t\t/// Variable created for exception handler.\n\t\t/// </summary>\n\t\tExceptionStackSlot,\n\t\t/// <summary>\n\t\t/// Local variable used in a catch block.\n\t\t/// </summary>\n\t\tExceptionLocal,\n\t\t/// <summary>\n\t\t/// Variable created from stack slot.\n\t\t/// </summary>\n\t\tStackSlot,\n\t\t/// <summary>\n\t\t/// Variable in BlockKind.CallWithNamedArgs\n\t\t/// </summary>\n\t\tNamedArgument,\n\t\t/// <summary>\n\t\t/// Local variable that holds the display class used for lambdas within this function.\n\t\t/// </summary>\n\t\tDisplayClassLocal,\n\t\t/// <summary>\n\t\t/// Local variable declared within a pattern match.\n\t\t/// </summary>\n\t\tPatternLocal,\n\t\t/// <summary>\n\t\t/// Temporary variable declared in a deconstruction init section.\n\t\t/// </summary>\n\t\tDeconstructionInitTemporary,\n\t}\n\n\tstatic class VariableKindExtensions\n\t{\n\t\tpublic static bool IsThis(this ILVariable v)\n\t\t{\n\t\t\treturn v.Kind == VariableKind.Parameter && v.Index < 0;\n\t\t}\n\n\t\tpublic static bool IsLocal(this VariableKind kind)\n\t\t{\n\t\t\tswitch (kind)\n\t\t\t{\n\t\t\t\tcase VariableKind.Local:\n\t\t\t\tcase VariableKind.ExceptionLocal:\n\t\t\t\tcase VariableKind.ForeachLocal:\n\t\t\t\tcase VariableKind.UsingLocal:\n\t\t\t\tcase VariableKind.PatternLocal:\n\t\t\t\tcase VariableKind.PinnedLocal:\n\t\t\t\tcase VariableKind.PinnedRegionLocal:\n\t\t\t\tcase VariableKind.DisplayClassLocal:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\n\t[DebuggerDisplay(\"{Name} : {Type}\")]\n\tpublic class ILVariable\n\t{\n\t\tVariableKind kind;\n\n\t\tpublic VariableKind Kind {\n\t\t\tget {\n\t\t\t\treturn kind;\n\t\t\t}\n\t\t\tinternal set {\n\t\t\t\tif (kind == VariableKind.Parameter)\n\t\t\t\t\tthrow new InvalidOperationException(\"Kind=Parameter cannot be changed!\");\n\t\t\t\tif (Index != null && value.IsLocal() && !kind.IsLocal())\n\t\t\t\t{\n\t\t\t\t\t// For variables, Index has different meaning than for stack slots,\n\t\t\t\t\t// so we need to reset it to null.\n\t\t\t\t\t// StackSlot -> ForeachLocal can happen sometimes (e.g. PST.TransformForeachOnArray)\n\t\t\t\t\tIndex = null;\n\t\t\t\t}\n\t\t\t\tkind = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic readonly StackType StackType;\n\n\t\tIType type;\n\t\tpublic IType Type {\n\t\t\tget {\n\t\t\t\treturn type;\n\t\t\t}\n\t\t\tinternal set {\n\t\t\t\tif (value.GetStackType() != StackType)\n\t\t\t\t\tthrow new ArgumentException($\"Expected stack-type: {StackType} may not be changed. Found: {value.GetStackType()}\");\n\t\t\t\ttype = value;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// This variable is either a C# 7 'in' parameter or must be declared as 'ref readonly'.\n\t\t/// </summary>\n\t\tpublic bool IsRefReadOnly { get; internal set; }\n\n\t\t/// <summary>\n\t\t/// The index of the local variable or parameter (depending on Kind)\n\t\t/// \n\t\t/// For VariableKinds with \"Local\" in the name:\n\t\t///  * if non-null, the Index refers to the LocalVariableSignature.\n\t\t///  * index may be null for variables that used to be fields (captured by lambda/async)\n\t\t/// For Parameters, the Index refers to the method's list of parameters.\n\t\t///   The special \"this\" parameter has index -1.\n\t\t/// For ExceptionStackSlot, the index is the IL offset of the exception handler.\n\t\t/// For other kinds, the index has no meaning, and is usually null.\n\t\t/// </summary>\n\t\tpublic int? Index { get; private set; }\n\n\t\t[Conditional(\"DEBUG\")]\n\t\tinternal void CheckInvariant()\n\t\t{\n\t\t\tswitch (kind)\n\t\t\t{\n\t\t\t\tcase VariableKind.Local:\n\t\t\t\tcase VariableKind.ForeachLocal:\n\t\t\t\tcase VariableKind.PatternLocal:\n\t\t\t\tcase VariableKind.PinnedLocal:\n\t\t\t\tcase VariableKind.PinnedRegionLocal:\n\t\t\t\tcase VariableKind.UsingLocal:\n\t\t\t\tcase VariableKind.ExceptionLocal:\n\t\t\t\tcase VariableKind.DisplayClassLocal:\n\t\t\t\t\t// in range of LocalVariableSignature\n\t\t\t\t\tDebug.Assert(Index == null || Index >= 0);\n\t\t\t\t\tbreak;\n\t\t\t\tcase VariableKind.Parameter:\n\t\t\t\t\t// -1 for the \"this\" parameter\n\t\t\t\t\tDebug.Assert(Index >= -1);\n\t\t\t\t\tDebug.Assert(Function == null || Index < Function.Parameters.Count);\n\t\t\t\t\tbreak;\n\t\t\t\tcase VariableKind.ExceptionStackSlot:\n\t\t\t\t\tDebug.Assert(Index >= 0);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic string? Name { get; set; }\n\n\t\tpublic bool HasGeneratedName { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets the function in which this variable is declared.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This property is set automatically when the variable is added to the <c>ILFunction.Variables</c> collection.\n\t\t/// </remarks>\n\t\tpublic ILFunction? Function { get; internal set; }\n\n\t\t/// <summary>\n\t\t/// Gets the block container in which this variable is captured.\n\t\t/// For captured variables declared inside the loop, the capture scope is the BlockContainer of the loop.\n\t\t/// For captured variables declared outside of the loop, the capture scope is the BlockContainer of the parent function.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This property returns null for variables that are not captured.\n\t\t/// </remarks>\n\t\tpublic BlockContainer? CaptureScope { get; internal set; }\n\n\t\t/// <summary>\n\t\t/// Gets the index of this variable within the <c>Function.Variables</c> collection.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This property is set automatically when the variable is added to the <c>VariableScope.Variables</c> collection.\n\t\t/// It may change if an item with a lower index is removed from the collection.\n\t\t/// </remarks>\n\t\tpublic int IndexInFunction { get; internal set; }\n\n\t\t/// <summary>\n\t\t/// Number of ldloc instructions referencing this variable.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This variable is automatically updated when adding/removing ldloc instructions from the ILAst.\n\t\t/// </remarks>\n\t\tpublic int LoadCount => LoadInstructions.Count;\n\n\t\treadonly List<LdLoc> loadInstructions = new List<LdLoc>();\n\n\t\t/// <summary>\n\t\t/// List of ldloc instructions referencing this variable.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This list is automatically updated when adding/removing ldloc instructions from the ILAst.\n\t\t/// </remarks>\n\t\tpublic IReadOnlyList<LdLoc> LoadInstructions => loadInstructions;\n\n\t\t/// <summary>\n\t\t/// Number of store instructions referencing this variable,\n\t\t/// plus 1 if HasInitialValue.\n\t\t/// \n\t\t/// Stores are:\n\t\t/// <list type=\"item\">\n\t\t/// <item>stloc</item>\n\t\t/// <item>TryCatchHandler (assigning the exception variable)</item>\n\t\t/// <item>PinnedRegion (assigning the pointer variable)</item>\n\t\t/// <item>initial values (<see cref=\"UsesInitialValue\"/>)</item>\n\t\t/// </list>\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This variable is automatically updated when adding/removing stores instructions from the ILAst.\n\t\t/// </remarks>\n\t\tpublic int StoreCount => (usesInitialValue ? 1 : 0) + StoreInstructions.Count;\n\n\t\treadonly List<IStoreInstruction> storeInstructions = new List<IStoreInstruction>();\n\n\t\t/// <summary>\n\t\t/// List of store instructions referencing this variable.\n\t\t/// \n\t\t/// Stores are:\n\t\t/// <list type=\"item\">\n\t\t/// <item>stloc</item>\n\t\t/// <item>TryCatchHandler (assigning the exception variable)</item>\n\t\t/// <item>PinnedRegion (assigning the pointer variable)</item>\n\t\t/// <item>initial values (<see cref=\"UsesInitialValue\"/>) -- however, there is no instruction for\n\t\t///       the initial value, so it is not contained in the store list.</item>\n\t\t/// </list>\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This list is automatically updated when adding/removing stores instructions from the ILAst.\n\t\t/// </remarks>\n\t\tpublic IReadOnlyList<IStoreInstruction> StoreInstructions => storeInstructions;\n\n\t\t/// <summary>\n\t\t/// Number of ldloca instructions referencing this variable.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This variable is automatically updated when adding/removing ldloca instructions from the ILAst.\n\t\t/// </remarks>\n\t\tpublic int AddressCount => AddressInstructions.Count;\n\n\t\treadonly List<LdLoca> addressInstructions = new List<LdLoca>();\n\n\t\t/// <summary>\n\t\t/// List of ldloca instructions referencing this variable.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This list is automatically updated when adding/removing ldloca instructions from the ILAst.\n\t\t/// </remarks>\n\t\tpublic IReadOnlyList<LdLoca> AddressInstructions => addressInstructions;\n\n\t\tinternal void AddLoadInstruction(LdLoc inst) => inst.IndexInLoadInstructionList = AddInstruction(loadInstructions, inst);\n\t\tinternal void AddStoreInstruction(IStoreInstruction inst) => inst.IndexInStoreInstructionList = AddInstruction(storeInstructions, inst);\n\t\tinternal void AddAddressInstruction(LdLoca inst) => inst.IndexInAddressInstructionList = AddInstruction(addressInstructions, inst);\n\n\t\tinternal void RemoveLoadInstruction(LdLoc inst) => RemoveInstruction(loadInstructions, inst.IndexInLoadInstructionList, inst);\n\t\tinternal void RemoveStoreInstruction(IStoreInstruction inst) => RemoveInstruction(storeInstructions, inst.IndexInStoreInstructionList, inst);\n\t\tinternal void RemoveAddressInstruction(LdLoca inst) => RemoveInstruction(addressInstructions, inst.IndexInAddressInstructionList, inst);\n\n\t\tint AddInstruction<T>(List<T> list, T inst) where T : class, IInstructionWithVariableOperand\n\t\t{\n\t\t\tlist.Add(inst);\n\t\t\treturn list.Count - 1;\n\t\t}\n\n\t\tvoid RemoveInstruction<T>(List<T> list, int index, T? inst) where T : class, IInstructionWithVariableOperand\n\t\t{\n\t\t\tDebug.Assert(list[index] == inst);\n\t\t\tint indexToMove = list.Count - 1;\n\t\t\tlist[index] = list[indexToMove];\n\t\t\tlist[index].IndexInVariableInstructionMapping = index;\n\t\t\tlist.RemoveAt(indexToMove);\n\t\t}\n\n\t\tbool initialValueIsInitialized;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether the variable's initial value is initialized.\n\t\t/// This is always <c>true</c> for parameters (incl. <c>this</c>).\n\t\t/// \n\t\t/// Normal variables have an initial value if the function uses \".locals init\".\n\t\t/// </summary>\n\t\tpublic bool InitialValueIsInitialized {\n\t\t\tget { return initialValueIsInitialized; }\n\t\t\tset {\n\t\t\t\tif (Kind == VariableKind.Parameter && !value)\n\t\t\t\t\tthrow new InvalidOperationException(\"Cannot remove InitialValueIsInitialized from parameters\");\n\t\t\t\tinitialValueIsInitialized = value;\n\t\t\t}\n\t\t}\n\n\t\tbool usesInitialValue;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether the initial value of the variable is used.\n\t\t/// This is always <c>true</c> for parameters (incl. <c>this</c>).\n\t\t/// \n\t\t/// Normal variables use the initial value, if no explicit initialization is done.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// The following table shows the relationship between <see cref=\"InitialValueIsInitialized\"/>\n\t\t/// and <see cref=\"UsesInitialValue\"/>.\n\t\t/// <list type=\"table\">\n\t\t/// <listheader>\n\t\t/// <term><see cref=\"InitialValueIsInitialized\"/></term>\n\t\t/// <term><see cref=\"UsesInitialValue\"/></term>\n\t\t/// <term>Meaning</term>\n\t\t/// </listheader>\n\t\t/// <item>\n\t\t/// <term><see langword=\"true\" /></term>\n\t\t/// <term><see langword=\"true\" /></term>\n\t\t/// <term>This variable's initial value is zero-initialized (<c>.locals init</c>) and the initial value is used.\n\t\t/// From C#'s point of view a the value <c>default(T)</c> is assigned at the site of declaration.</term>\n\t\t/// </item>\n\t\t/// <item>\n\t\t/// <term><see langword=\"true\" /></term>\n\t\t/// <term><see langword=\"false\" /></term>\n\t\t/// <term>This variable's initial value is zero-initialized (<c>.locals init</c>) and the initial value is not used.\n\t\t/// From C#'s point of view no implicit initialization occurs, because the code assigns a value\n\t\t/// explicitly, before the variable is first read.</term>\n\t\t/// </item>\n\t\t/// <item>\n\t\t/// <term><see langword=\"false\" /></term>\n\t\t/// <term><see langword=\"true\" /></term>\n\t\t/// <term>This variable's initial value is uninitialized (<c>.locals</c> without <c>init</c>) and the\n\t\t/// initial value is used.\n\t\t/// From C#'s point of view a call to <code>System.Runtime.CompilerServices.Unsafe.SkipInit(out T)</code>\n\t\t/// is generated after the declaration.</term>\n\t\t/// </item>\n\t\t/// <item>\n\t\t/// <term><see langword=\"false\" /></term>\n\t\t/// <term><see langword=\"false\" /></term>\n\t\t/// <term>This variable's initial value is uninitialized (<c>.locals</c> without <c>init</c>) and the\n\t\t/// initial value is not used.\n\t\t/// From C#'s point of view no implicit initialization occurs, because the code assigns a value\n\t\t/// explicitly, before the variable is first read.</term>\n\t\t/// </item>\n\t\t/// </list>\n\t\t/// </remarks>\n\t\tpublic bool UsesInitialValue {\n\t\t\tget { return usesInitialValue; }\n\t\t\tset {\n\t\t\t\tif (Kind == VariableKind.Parameter && !value)\n\t\t\t\t\tthrow new InvalidOperationException(\"Cannot remove UsesInitialValue from parameters\");\n\t\t\t\tusesInitialValue = value;\n\t\t\t}\n\t\t}\n\n\t\t[Obsolete(\"Use 'UsesInitialValue' instead.\")]\n\t\tpublic bool HasInitialValue {\n\t\t\tget => UsesInitialValue;\n\t\t\tset => UsesInitialValue = value;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the variable is in SSA form:\n\t\t/// There is exactly 1 store, and every load sees the value from that store.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Note: the single store is not necessary a store instruction, it might also\n\t\t/// be the use of the implicit initial value.\n\t\t/// For example: for parameters, IsSingleDefinition will only return true if\n\t\t/// the parameter is never assigned to within the function.\n\t\t/// </remarks>\n\t\tpublic bool IsSingleDefinition {\n\t\t\tget {\n\t\t\t\treturn StoreCount == 1 && AddressCount == 0;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the variable is dead - unused.\n\t\t/// </summary>\n\t\tpublic bool IsDead {\n\t\t\tget {\n\t\t\t\treturn StoreInstructions.Count == 0\n\t\t\t\t\t&& LoadCount == 0\n\t\t\t\t\t&& AddressCount == 0;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// The field which was converted to a local variable.\n\t\t/// Set when the variable is from a 'yield return' or 'async' state machine.\n\t\t/// </summary>\n\t\tpublic IField? StateMachineField;\n\n\t\t/// <summary>\n\t\t/// If enabled, remove dead stores to this variable as if the \"Remove dead code\" option is enabled.\n\t\t/// </summary>\n\t\tinternal bool RemoveIfRedundant;\n\n\t\tpublic ILVariable(VariableKind kind, IType type, int? index = null)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tthis.Kind = kind;\n\t\t\tthis.type = type;\n\t\t\tthis.StackType = type.GetStackType();\n\t\t\tthis.Index = index;\n\t\t\tif (kind == VariableKind.Parameter)\n\t\t\t{\n\t\t\t\tthis.InitialValueIsInitialized = true;\n\t\t\t\tthis.UsesInitialValue = true;\n\t\t\t}\n\t\t\tCheckInvariant();\n\t\t}\n\n\t\tpublic ILVariable(VariableKind kind, IType type, StackType stackType, int? index = null)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tthis.Kind = kind;\n\t\t\tthis.type = type;\n\t\t\tthis.StackType = stackType;\n\t\t\tthis.Index = index;\n\t\t\tif (kind == VariableKind.Parameter)\n\t\t\t{\n\t\t\t\tthis.InitialValueIsInitialized = true;\n\t\t\t\tthis.UsesInitialValue = true;\n\t\t\t}\n\t\t\tCheckInvariant();\n\t\t}\n\n\t\tpublic override string? ToString()\n\t\t{\n\t\t\treturn Name;\n\t\t}\n\n\t\tinternal void WriteDefinitionTo(ITextOutput output)\n\t\t{\n\t\t\tif (IsRefReadOnly)\n\t\t\t{\n\t\t\t\toutput.Write(\"readonly \");\n\t\t\t}\n\t\t\tswitch (Kind)\n\t\t\t{\n\t\t\t\tcase VariableKind.Local:\n\t\t\t\t\toutput.Write(\"local \");\n\t\t\t\t\tbreak;\n\t\t\t\tcase VariableKind.PinnedLocal:\n\t\t\t\t\toutput.Write(\"pinned local \");\n\t\t\t\t\tbreak;\n\t\t\t\tcase VariableKind.PinnedRegionLocal:\n\t\t\t\t\toutput.Write(\"PinnedRegion local \");\n\t\t\t\t\tbreak;\n\t\t\t\tcase VariableKind.Parameter:\n\t\t\t\t\toutput.Write(\"param \");\n\t\t\t\t\tbreak;\n\t\t\t\tcase VariableKind.ExceptionLocal:\n\t\t\t\t\toutput.Write(\"exception local \");\n\t\t\t\t\tbreak;\n\t\t\t\tcase VariableKind.ExceptionStackSlot:\n\t\t\t\t\toutput.Write(\"exception stack \");\n\t\t\t\t\tbreak;\n\t\t\t\tcase VariableKind.StackSlot:\n\t\t\t\t\toutput.Write(\"stack \");\n\t\t\t\t\tbreak;\n\t\t\t\tcase VariableKind.InitializerTarget:\n\t\t\t\t\toutput.Write(\"initializer \");\n\t\t\t\t\tbreak;\n\t\t\t\tcase VariableKind.ForeachLocal:\n\t\t\t\t\toutput.Write(\"foreach \");\n\t\t\t\t\tbreak;\n\t\t\t\tcase VariableKind.UsingLocal:\n\t\t\t\t\toutput.Write(\"using \");\n\t\t\t\t\tbreak;\n\t\t\t\tcase VariableKind.NamedArgument:\n\t\t\t\t\toutput.Write(\"named_arg \");\n\t\t\t\t\tbreak;\n\t\t\t\tcase VariableKind.DisplayClassLocal:\n\t\t\t\t\toutput.Write(\"display_class local \");\n\t\t\t\t\tbreak;\n\t\t\t\tcase VariableKind.PatternLocal:\n\t\t\t\t\toutput.Write(\"pattern local \");\n\t\t\t\t\tbreak;\n\t\t\t\tcase VariableKind.DeconstructionInitTemporary:\n\t\t\t\t\toutput.Write(\"deconstruction init temporary \");\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t}\n\t\t\toutput.WriteLocalReference(this.Name, this, isDefinition: true);\n\t\t\toutput.Write(\" : \");\n\t\t\tType.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tif (Kind == VariableKind.Parameter || Kind == VariableKind.Local || Kind == VariableKind.PinnedLocal || Kind == VariableKind.PinnedRegionLocal)\n\t\t\t{\n\t\t\t\toutput.Write(\"Index={0}, \", Index);\n\t\t\t}\n\t\t\toutput.Write(\"LoadCount={0}, AddressCount={1}, StoreCount={2})\", LoadCount, AddressCount, StoreCount);\n\t\t\tif (Kind != VariableKind.Parameter)\n\t\t\t{\n\t\t\t\tif (initialValueIsInitialized)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\" init\");\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\" uninit\");\n\t\t\t\t}\n\t\t\t\tif (usesInitialValue)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\" used\");\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\" unused\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (CaptureScope != null)\n\t\t\t{\n\t\t\t\toutput.Write(\" captured in \");\n\t\t\t\toutput.WriteLocalReference(CaptureScope.EntryPoint?.Label, CaptureScope);\n\t\t\t}\n\t\t\tif (StateMachineField != null)\n\t\t\t{\n\t\t\t\toutput.Write(\" from state-machine\");\n\t\t\t}\n\t\t}\n\n\t\tinternal void WriteTo(ITextOutput output)\n\t\t{\n\t\t\toutput.WriteLocalReference(this.Name, this);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this variable occurs within the specified instruction.\n\t\t/// </summary>\n\t\tinternal bool IsUsedWithin(ILInstruction inst)\n\t\t{\n\t\t\tif (inst is IInstructionWithVariableOperand iwvo && iwvo.Variable == this)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tforeach (var child in inst.Children)\n\t\t\t{\n\t\t\t\tif (IsUsedWithin(child))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic interface IInstructionWithVariableOperand\n\t{\n\t\tILVariable Variable { get; set; }\n\t\tint IndexInVariableInstructionMapping { get; set; }\n\t}\n\n\tpublic interface IStoreInstruction : IInstructionWithVariableOperand\n\t{\n\t\tint IndexInStoreInstructionList { get; set; }\n\t}\n\n\tinterface ILoadInstruction : IInstructionWithVariableOperand\n\t{\n\t\tint IndexInLoadInstructionList { get; set; }\n\t}\n\n\tinterface IAddressInstruction : IInstructionWithVariableOperand\n\t{\n\t\tint IndexInAddressInstructionList { get; set; }\n\t}\n\n\tpublic class ILVariableEqualityComparer : IEqualityComparer<ILVariable>\n\t{\n\t\tpublic static readonly ILVariableEqualityComparer Instance = new ILVariableEqualityComparer();\n\n\t\tpublic bool Equals(ILVariable? x, ILVariable? y)\n\t\t{\n\t\t\tif (x == y)\n\t\t\t\treturn true;\n\t\t\tif (x == null || y == null)\n\t\t\t\treturn false;\n\t\t\tif (x.Kind == VariableKind.StackSlot || y.Kind == VariableKind.StackSlot)\n\t\t\t\treturn false;\n\t\t\tif (x.Kind == VariableKind.PatternLocal || y.Kind == VariableKind.PatternLocal)\n\t\t\t\treturn false;\n\t\t\tif (!(x.Function == y.Function && x.Kind == y.Kind))\n\t\t\t\treturn false;\n\t\t\tif (x.Index != null)\n\t\t\t\treturn x.Index == y.Index;\n\t\t\telse if (x.StateMachineField != null)\n\t\t\t\treturn x.StateMachineField.Equals(y.StateMachineField);\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\n\t\tpublic int GetHashCode(ILVariable obj)\n\t\t{\n\t\t\tif (obj.Kind is VariableKind.StackSlot or VariableKind.PatternLocal)\n\t\t\t\treturn obj.GetHashCode();\n\t\t\tif (obj.Index != null)\n\t\t\t\treturn (obj.Function, obj.Kind, obj.Index).GetHashCode();\n\t\t\tif (obj.StateMachineField != null)\n\t\t\t\treturn (obj.Function, obj.Kind, obj.StateMachineField).GetHashCode();\n\t\t\treturn obj.GetHashCode();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/InstructionFlags.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t[Flags]\n\tpublic enum InstructionFlags\n\t{\n\t\tNone = 0,\n\t\t/// <summary>\n\t\t/// The instruction may read from local variables.\n\t\t/// </summary>\n\t\tMayReadLocals = 0x10,\n\t\t/// <summary>\n\t\t/// The instruction may write to local variables.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This flag is not set for indirect writes to local variables through pointers.\n\t\t/// Ensure you also check the SideEffect flag when checking for instructions that might write to locals.\n\t\t/// </remarks>\n\t\tMayWriteLocals = 0x20,\n\t\t/// <summary>\n\t\t/// The instruction may have side effects, such as accessing heap memory,\n\t\t/// performing system calls, writing to local variables through pointers, etc.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Throwing an exception or directly writing to local variables\n\t\t/// is not considered a side effect, and is modeled by separate flags.\n\t\t/// </remarks>\n\t\tSideEffect = 0x40,\n\n\t\t/// <summary>\n\t\t/// The instruction may throw an exception.\n\t\t/// </summary>\n\t\tMayThrow = 0x100,\n\t\t/// <summary>\n\t\t/// The instruction may exit with a branch or leave.\n\t\t/// </summary>\n\t\tMayBranch = 0x200,\n\t\t/// <summary>\n\t\t/// The instruction may jump to the closest containing <c>nullable.rewrap</c> instruction.\n\t\t/// </summary>\n\t\tMayUnwrapNull = 0x400,\n\t\t/// <summary>\n\t\t/// The instruction performs unconditional control flow, so that its endpoint is unreachable.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// If EndPointUnreachable is set, either MayThrow or MayBranch should also be set\n\t\t/// (unless the instruction represents an infinite loop).\n\t\t/// </remarks>\n\t\tEndPointUnreachable = 0x800,\n\t\t/// <summary>\n\t\t/// The instruction contains some kind of internal control flow.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// If this flag is not set, all descendants of the instruction are fully evaluated (modulo MayThrow/MayBranch/MayUnwrapNull)\n\t\t/// in left-to-right pre-order.\n\t\t/// \n\t\t/// Note that branch instructions don't have this flag set, because their control flow is not internal\n\t\t/// (and they don't have any unusual argument evaluation rules).\n\t\t/// </remarks>\n\t\tControlFlow = 0x1000,\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpublic static partial class InstructionOutputExtensions\n\t{\n\t\tpublic static void Write(this ITextOutput output, OpCode opCode)\n\t\t{\n\t\t\toutput.Write(originalOpCodeNames[(int)opCode]);\n\t\t}\n\n\t\tpublic static void Write(this ITextOutput output, StackType stackType)\n\t\t{\n\t\t\toutput.Write(stackType.ToString().ToLowerInvariant());\n\t\t}\n\n\t\tpublic static void Write(this ITextOutput output, PrimitiveType primitiveType)\n\t\t{\n\t\t\toutput.Write(primitiveType.ToString().ToLowerInvariant());\n\t\t}\n\n\t\tpublic static void WriteTo(this IType type, ITextOutput output)\n\t\t{\n\t\t\toutput.WriteReference(type, type.ReflectionName);\n\t\t}\n\n\t\tpublic static void WriteTo(this IMember member, ITextOutput output)\n\t\t{\n\t\t\tif (member is IMethod method && method.IsConstructor)\n\t\t\t\toutput.WriteReference(member, method.DeclaringType?.Name + \".\" + method.Name);\n\t\t\telse\n\t\t\t\toutput.WriteReference(member, member.Name);\n\t\t}\n\n\t\tpublic static void WriteTo(this Interval interval, ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tif (!options.ShowILRanges)\n\t\t\t\treturn;\n\t\t\tif (interval.IsEmpty)\n\t\t\t\toutput.Write(\"[empty] \");\n\t\t\telse\n\t\t\t\toutput.Write($\"[{interval.Start:x4}..{interval.InclusiveEnd:x4}] \");\n\t\t}\n\n\t\tpublic static void WriteTo(this EntityHandle entity, MetadataFile module, ITextOutput output, Metadata.MetadataGenericContext genericContext, ILNameSyntax syntax = ILNameSyntax.Signature)\n\t\t{\n\t\t\tif (entity.IsNil)\n\t\t\t{\n\t\t\t\toutput.Write(\"<nil>\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (module == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(module));\n\t\t\tvar metadata = module.Metadata;\n\t\t\tAction<ILNameSyntax> signature;\n\t\t\tMethodSignature<Action<ILNameSyntax>> methodSignature;\n\t\t\tstring memberName;\n\t\t\tswitch (entity.Kind)\n\t\t\t{\n\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\t{\n\t\t\t\t\tvar td = metadata.GetTypeDefinition((TypeDefinitionHandle)entity);\n\t\t\t\t\toutput.WriteReference(module, entity, td.GetFullTypeName(metadata).ToILNameString());\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase HandleKind.TypeReference:\n\t\t\t\t{\n\t\t\t\t\tvar tr = metadata.GetTypeReference((TypeReferenceHandle)entity);\n\t\t\t\t\tEntityHandle resolutionScope;\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tresolutionScope = tr.ResolutionScope;\n\t\t\t\t\t}\n\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t{\n\t\t\t\t\t\tresolutionScope = default;\n\t\t\t\t\t}\n\t\t\t\t\tif (!resolutionScope.IsNil)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(\"[\");\n\t\t\t\t\t\tvar currentTypeRef = tr;\n\t\t\t\t\t\twhile (currentTypeRef.ResolutionScope.Kind == HandleKind.TypeReference)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcurrentTypeRef = metadata.GetTypeReference((TypeReferenceHandle)currentTypeRef.ResolutionScope);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tswitch (currentTypeRef.ResolutionScope.Kind)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase HandleKind.ModuleDefinition:\n\t\t\t\t\t\t\t\tvar modDef = metadata.GetModuleDefinition();\n\t\t\t\t\t\t\t\toutput.Write(DisassemblerHelpers.Escape(metadata.GetString(modDef.Name)));\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase HandleKind.ModuleReference:\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase HandleKind.AssemblyReference:\n\t\t\t\t\t\t\t\tvar asmRef = metadata.GetAssemblyReference((AssemblyReferenceHandle)currentTypeRef.ResolutionScope);\n\t\t\t\t\t\t\t\toutput.Write(DisassemblerHelpers.Escape(metadata.GetString(asmRef.Name)));\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\toutput.Write(\"]\");\n\t\t\t\t\t}\n\t\t\t\t\toutput.WriteReference(module, entity, entity.GetFullTypeName(metadata).ToILNameString());\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase HandleKind.TypeSpecification:\n\t\t\t\t{\n\t\t\t\t\tvar ts = metadata.GetTypeSpecification((TypeSpecificationHandle)entity);\n\t\t\t\t\tsignature = ts.DecodeSignature(new DisassemblerSignatureTypeProvider(module, output), genericContext);\n\t\t\t\t\tsignature(syntax);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase HandleKind.FieldDefinition:\n\t\t\t\t{\n\t\t\t\t\tvar fd = metadata.GetFieldDefinition((FieldDefinitionHandle)entity);\n\t\t\t\t\tsignature = fd.DecodeSignature(new DisassemblerSignatureTypeProvider(module, output), new Metadata.MetadataGenericContext(fd.GetDeclaringType(), metadata));\n\t\t\t\t\tsignature(ILNameSyntax.SignatureNoNamedTypeParameters);\n\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t((EntityHandle)fd.GetDeclaringType()).WriteTo(module, output, default, ILNameSyntax.TypeName);\n\t\t\t\t\toutput.Write(\"::\");\n\t\t\t\t\toutput.WriteReference(module, entity, DisassemblerHelpers.Escape(metadata.GetString(fd.Name)));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t{\n\t\t\t\t\tvar md = metadata.GetMethodDefinition((MethodDefinitionHandle)entity);\n\t\t\t\t\tmethodSignature = md.DecodeSignature(new DisassemblerSignatureTypeProvider(module, output), new Metadata.MetadataGenericContext((MethodDefinitionHandle)entity, metadata));\n\t\t\t\t\tmethodSignature.Header.WriteTo(output);\n\t\t\t\t\tmethodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);\n\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\tvar declaringType = md.GetDeclaringType();\n\t\t\t\t\tif (!declaringType.IsNil)\n\t\t\t\t\t{\n\t\t\t\t\t\t((EntityHandle)declaringType).WriteTo(module, output, genericContext, ILNameSyntax.TypeName);\n\t\t\t\t\t\toutput.Write(\"::\");\n\t\t\t\t\t}\n\t\t\t\t\tbool isCompilerControlled = (md.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope;\n\t\t\t\t\tif (isCompilerControlled)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.WriteReference(module, entity, DisassemblerHelpers.Escape(metadata.GetString(md.Name) + \"$PST\" + MetadataTokens.GetToken(entity).ToString(\"X8\")));\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.WriteReference(module, entity, DisassemblerHelpers.Escape(metadata.GetString(md.Name)));\n\t\t\t\t\t}\n\t\t\t\t\tvar genericParameters = md.GetGenericParameters();\n\t\t\t\t\tif (genericParameters.Count > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write('<');\n\t\t\t\t\t\tfor (int i = 0; i < genericParameters.Count; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\t\t\toutput.Write(\", \");\n\t\t\t\t\t\t\tvar gp = metadata.GetGenericParameter(genericParameters[i]);\n\t\t\t\t\t\t\tif ((gp.Attributes & GenericParameterAttributes.ReferenceTypeConstraint) == GenericParameterAttributes.ReferenceTypeConstraint)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutput.Write(\"class \");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if ((gp.Attributes & GenericParameterAttributes.NotNullableValueTypeConstraint) == GenericParameterAttributes.NotNullableValueTypeConstraint)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutput.Write(\"valuetype \");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ((gp.Attributes & GenericParameterAttributes.DefaultConstructorConstraint) == GenericParameterAttributes.DefaultConstructorConstraint)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutput.Write(\".ctor \");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tvar constraints = gp.GetConstraints();\n\t\t\t\t\t\t\tif (constraints.Count > 0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutput.Write('(');\n\t\t\t\t\t\t\t\tfor (int j = 0; j < constraints.Count; j++)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif (j > 0)\n\t\t\t\t\t\t\t\t\t\toutput.Write(\", \");\n\t\t\t\t\t\t\t\t\tvar constraint = metadata.GetGenericParameterConstraint(constraints[j]);\n\t\t\t\t\t\t\t\t\tconstraint.Type.WriteTo(module, output, new Metadata.MetadataGenericContext((MethodDefinitionHandle)entity, metadata), ILNameSyntax.TypeName);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\toutput.Write(\") \");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ((gp.Attributes & GenericParameterAttributes.Contravariant) == GenericParameterAttributes.Contravariant)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutput.Write('-');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if ((gp.Attributes & GenericParameterAttributes.Covariant) == GenericParameterAttributes.Covariant)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutput.Write('+');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\toutput.Write(DisassemblerHelpers.Escape(metadata.GetString(gp.Name)));\n\t\t\t\t\t\t}\n\t\t\t\t\t\toutput.Write('>');\n\t\t\t\t\t}\n\t\t\t\t\tWriteParameterList(output, methodSignature);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase HandleKind.MemberReference:\n\t\t\t\t\tvar mr = metadata.GetMemberReference((MemberReferenceHandle)entity);\n\t\t\t\t\tmemberName = metadata.GetString(mr.Name);\n\t\t\t\t\tswitch (mr.GetKind())\n\t\t\t\t\t{\n\t\t\t\t\t\tcase MemberReferenceKind.Method:\n\t\t\t\t\t\t\tmethodSignature = mr.DecodeMethodSignature(new DisassemblerSignatureTypeProvider(module, output), genericContext);\n\t\t\t\t\t\t\tmethodSignature.Header.WriteTo(output);\n\t\t\t\t\t\t\tmethodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);\n\t\t\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t\t\tWriteParent(output, module, mr.Parent, genericContext, syntax);\n\t\t\t\t\t\t\toutput.Write(\"::\");\n\t\t\t\t\t\t\toutput.WriteReference(module, entity, DisassemblerHelpers.Escape(memberName));\n\t\t\t\t\t\t\tWriteParameterList(output, methodSignature);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase MemberReferenceKind.Field:\n\t\t\t\t\t\t\tvar fieldSignature = mr.DecodeFieldSignature(new DisassemblerSignatureTypeProvider(module, output), genericContext);\n\t\t\t\t\t\t\tfieldSignature(ILNameSyntax.SignatureNoNamedTypeParameters);\n\t\t\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t\t\tWriteParent(output, module, mr.Parent, genericContext, syntax);\n\t\t\t\t\t\t\toutput.Write(\"::\");\n\t\t\t\t\t\t\toutput.WriteReference(module, entity, DisassemblerHelpers.Escape(memberName));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase HandleKind.MethodSpecification:\n\t\t\t\t\tvar ms = metadata.GetMethodSpecification((MethodSpecificationHandle)entity);\n\t\t\t\t\tvar substitution = ms.DecodeSignature(new DisassemblerSignatureTypeProvider(module, output), genericContext);\n\t\t\t\t\tswitch (ms.Method.Kind)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\t\t\tvar methodDefinition = metadata.GetMethodDefinition((MethodDefinitionHandle)ms.Method);\n\t\t\t\t\t\t\tvar methodName = metadata.GetString(methodDefinition.Name);\n\t\t\t\t\t\t\tmethodSignature = methodDefinition.DecodeSignature(new DisassemblerSignatureTypeProvider(module, output), genericContext);\n\t\t\t\t\t\t\tmethodSignature.Header.WriteTo(output);\n\t\t\t\t\t\t\tmethodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);\n\t\t\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t\t\tvar declaringType = methodDefinition.GetDeclaringType();\n\t\t\t\t\t\t\tif (!declaringType.IsNil)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t((EntityHandle)declaringType).WriteTo(module, output, genericContext, ILNameSyntax.TypeName);\n\t\t\t\t\t\t\t\toutput.Write(\"::\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbool isCompilerControlled = (methodDefinition.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope;\n\t\t\t\t\t\t\tif (isCompilerControlled)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutput.Write(DisassemblerHelpers.Escape(methodName + \"$PST\" + MetadataTokens.GetToken(ms.Method).ToString(\"X8\")));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutput.Write(DisassemblerHelpers.Escape(methodName));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tWriteTypeParameterList(output, syntax, substitution);\n\t\t\t\t\t\t\tWriteParameterList(output, methodSignature);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase HandleKind.MemberReference:\n\t\t\t\t\t\t\tvar memberReference = metadata.GetMemberReference((MemberReferenceHandle)ms.Method);\n\t\t\t\t\t\t\tmemberName = metadata.GetString(memberReference.Name);\n\t\t\t\t\t\t\tmethodSignature = memberReference.DecodeMethodSignature(new DisassemblerSignatureTypeProvider(module, output), genericContext);\n\t\t\t\t\t\t\tmethodSignature.Header.WriteTo(output);\n\t\t\t\t\t\t\tmethodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);\n\t\t\t\t\t\t\toutput.Write(' ');\n\t\t\t\t\t\t\tWriteParent(output, module, memberReference.Parent, genericContext, syntax);\n\t\t\t\t\t\t\toutput.Write(\"::\");\n\t\t\t\t\t\t\toutput.Write(DisassemblerHelpers.Escape(memberName));\n\t\t\t\t\t\t\tWriteTypeParameterList(output, syntax, substitution);\n\t\t\t\t\t\t\tWriteParameterList(output, methodSignature);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase HandleKind.StandaloneSignature:\n\t\t\t\t\tvar standaloneSig = metadata.GetStandaloneSignature((StandaloneSignatureHandle)entity);\n\t\t\t\t\tvar header = metadata.GetBlobReader(standaloneSig.Signature).ReadSignatureHeader();\n\t\t\t\t\tswitch (header.Kind)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase SignatureKind.Method:\n\t\t\t\t\t\t\tmethodSignature = standaloneSig.DecodeMethodSignature(new DisassemblerSignatureTypeProvider(module, output), genericContext);\n\t\t\t\t\t\t\tmethodSignature.Header.WriteTo(output);\n\t\t\t\t\t\t\tmethodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);\n\t\t\t\t\t\t\tWriteParameterList(output, methodSignature);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\toutput.Write($\"@{MetadataTokens.GetToken(entity):X8} /* signature {header.Kind} */\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\toutput.Write($\"@{MetadataTokens.GetToken(entity):X8}\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tstatic void WriteTypeParameterList(ITextOutput output, ILNameSyntax syntax, System.Collections.Immutable.ImmutableArray<Action<ILNameSyntax>> substitution)\n\t\t{\n\t\t\toutput.Write('<');\n\t\t\tfor (int i = 0; i < substitution.Length; i++)\n\t\t\t{\n\t\t\t\tif (i > 0)\n\t\t\t\t\toutput.Write(\", \");\n\t\t\t\tsubstitution[i](syntax);\n\t\t\t}\n\t\t\toutput.Write('>');\n\t\t}\n\n\t\tinternal static void WriteParameterList(ITextOutput output, MethodSignature<Action<ILNameSyntax>> methodSignature)\n\t\t{\n\t\t\toutput.Write(\"(\");\n\t\t\tfor (int i = 0; i < methodSignature.ParameterTypes.Length; ++i)\n\t\t\t{\n\t\t\t\tif (i > 0)\n\t\t\t\t\toutput.Write(\", \");\n\t\t\t\tif (i == methodSignature.RequiredParameterCount)\n\t\t\t\t\toutput.Write(\"..., \");\n\t\t\t\tmethodSignature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);\n\t\t\t}\n\t\t\toutput.Write(\")\");\n\t\t}\n\n\t\tinternal static void WriteTo(this in SignatureHeader header, ITextOutput output)\n\t\t{\n\t\t\tif (header.HasExplicitThis)\n\t\t\t{\n\t\t\t\toutput.Write(\"instance explicit \");\n\t\t\t}\n\t\t\telse if (header.IsInstance)\n\t\t\t{\n\t\t\t\toutput.Write(\"instance \");\n\t\t\t}\n\t\t\tif (header.CallingConvention != SignatureCallingConvention.Default)\n\t\t\t{\n\t\t\t\toutput.Write(header.CallingConvention.ToILSyntax());\n\t\t\t\toutput.Write(' ');\n\t\t\t}\n\t\t}\n\n\t\tstatic void WriteParent(ITextOutput output, MetadataFile metadataFile, EntityHandle parentHandle, Metadata.MetadataGenericContext genericContext, ILNameSyntax syntax)\n\t\t{\n\t\t\tswitch (parentHandle.Kind)\n\t\t\t{\n\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\tvar methodDef = metadataFile.Metadata.GetMethodDefinition((MethodDefinitionHandle)parentHandle);\n\t\t\t\t\t((EntityHandle)methodDef.GetDeclaringType()).WriteTo(metadataFile, output, genericContext, syntax);\n\t\t\t\t\tbreak;\n\t\t\t\tcase HandleKind.ModuleReference:\n\t\t\t\t\toutput.Write('[');\n\t\t\t\t\tvar moduleRef = metadataFile.Metadata.GetModuleReference((ModuleReferenceHandle)parentHandle);\n\t\t\t\t\toutput.Write(metadataFile.Metadata.GetString(moduleRef.Name));\n\t\t\t\t\toutput.Write(']');\n\t\t\t\t\tbreak;\n\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\tcase HandleKind.TypeReference:\n\t\t\t\tcase HandleKind.TypeSpecification:\n\t\t\t\t\tparentHandle.WriteTo(metadataFile, output, genericContext, syntax);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/Await.cs",
    "content": "#nullable enable\n// Copyright (c) 2017 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpartial class Await\n\t{\n\t\tpublic IMethod? GetAwaiterMethod;\n\t\tpublic IMethod? GetResultMethod;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpublic enum BinaryNumericOperator : byte\n\t{\n\t\tNone,\n\t\tAdd,\n\t\tSub,\n\t\tMul,\n\t\tDiv,\n\t\tRem,\n\t\tBitAnd,\n\t\tBitOr,\n\t\tBitXor,\n\t\tShiftLeft,\n\t\tShiftRight\n\t}\n\n\tpublic partial class BinaryNumericInstruction : BinaryInstruction, ILiftableInstruction\n\t{\n\t\t/// <summary>\n\t\t/// Gets whether the instruction checks for overflow.\n\t\t/// </summary>\n\t\tpublic readonly bool CheckForOverflow;\n\n\t\t/// <summary>\n\t\t/// For integer operations that depend on the sign, specifies whether the operation\n\t\t/// is signed or unsigned.\n\t\t/// For instructions that produce the same result for either sign, returns Sign.None.\n\t\t/// </summary>\n\t\tpublic readonly Sign Sign;\n\n\t\tpublic readonly StackType LeftInputType;\n\t\tpublic readonly StackType RightInputType;\n\n\t\t/// <summary>\n\t\t/// The operator used by this binary operator instruction.\n\t\t/// </summary>\n\t\tpublic readonly BinaryNumericOperator Operator;\n\n\t\t/// <summary>\n\t\t/// Gets whether this is a lifted nullable operation.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// A lifted binary operation allows its arguments to be a value of type Nullable{T}, where\n\t\t/// T.GetStackType() == [Left|Right]InputType.\n\t\t/// If both input values are non-null:\n\t\t///  * they are sign/zero-extended to the corresponding InputType (based on T's sign)\n\t\t///  * the underlying numeric operator is applied\n\t\t///  * the result is wrapped in a Nullable{UnderlyingResultType}.\n\t\t/// If either input is null, the instruction evaluates to default(UnderlyingResultType?).\n\t\t/// (this result type is underspecified, since there may be multiple C# types for the stack type)\n\t\t/// </remarks>\n\t\tpublic bool IsLifted { get; }\n\n\t\treadonly StackType resultType;\n\n\t\tpublic BinaryNumericInstruction(BinaryNumericOperator op, ILInstruction left, ILInstruction right, bool checkForOverflow, Sign sign)\n\t\t\t: this(op, left, right, left.ResultType, right.ResultType, checkForOverflow, sign)\n\t\t{\n\t\t}\n\n\t\tpublic BinaryNumericInstruction(BinaryNumericOperator op, ILInstruction left, ILInstruction right, StackType leftInputType, StackType rightInputType, bool checkForOverflow, Sign sign, bool isLifted = false)\n\t\t\t: base(OpCode.BinaryNumericInstruction, left, right)\n\t\t{\n\t\t\tthis.CheckForOverflow = checkForOverflow;\n\t\t\tthis.Sign = sign;\n\t\t\tthis.Operator = op;\n\t\t\tthis.LeftInputType = leftInputType;\n\t\t\tthis.RightInputType = rightInputType;\n\t\t\tthis.IsLifted = isLifted;\n\t\t\tthis.resultType = ComputeResultType(op, LeftInputType, RightInputType);\n\t\t}\n\n\t\tinternal static StackType ComputeResultType(BinaryNumericOperator op, StackType left, StackType right)\n\t\t{\n\t\t\t// Based on Table 2: Binary Numeric Operations\n\t\t\t// also works for Table 5: Integer Operations\n\t\t\t// and for Table 7: Overflow Arithmetic Operations\n\t\t\tif (left == right || op == BinaryNumericOperator.ShiftLeft || op == BinaryNumericOperator.ShiftRight)\n\t\t\t{\n\t\t\t\t// Shift op codes use Table 6\n\t\t\t\treturn left;\n\t\t\t}\n\t\t\tif (left == StackType.Ref || right == StackType.Ref)\n\t\t\t{\n\t\t\t\tif (left == StackType.Ref && right == StackType.Ref)\n\t\t\t\t{\n\t\t\t\t\t// sub(&, &) = I\n\t\t\t\t\tDebug.Assert(op == BinaryNumericOperator.Sub);\n\t\t\t\t\treturn StackType.I;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// add/sub with I or I4 and &\n\t\t\t\t\tDebug.Assert(op == BinaryNumericOperator.Add || op == BinaryNumericOperator.Sub);\n\t\t\t\t\treturn StackType.Ref;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn StackType.Unknown;\n\t\t}\n\n\t\tpublic StackType UnderlyingResultType { get => resultType; }\n\n\t\tpublic sealed override StackType ResultType {\n\t\t\tget => IsLifted ? StackType.O : resultType;\n\t\t}\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tif (!IsLifted)\n\t\t\t{\n\t\t\t\tDebug.Assert(LeftInputType == Left.ResultType);\n\t\t\t\tDebug.Assert(RightInputType == Right.ResultType);\n\t\t\t}\n\t\t}\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\tvar flags = base.ComputeFlags();\n\t\t\tif (CheckForOverflow || (Operator == BinaryNumericOperator.Div || Operator == BinaryNumericOperator.Rem))\n\t\t\t\tflags |= InstructionFlags.MayThrow;\n\t\t\treturn flags;\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\tif (CheckForOverflow || (Operator == BinaryNumericOperator.Div || Operator == BinaryNumericOperator.Rem))\n\t\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow;\n\t\t\t\treturn base.DirectFlags;\n\t\t\t}\n\t\t}\n\n\t\tinternal static string GetOperatorName(BinaryNumericOperator @operator)\n\t\t{\n\t\t\tswitch (@operator)\n\t\t\t{\n\t\t\t\tcase BinaryNumericOperator.Add:\n\t\t\t\t\treturn \"add\";\n\t\t\t\tcase BinaryNumericOperator.Sub:\n\t\t\t\t\treturn \"sub\";\n\t\t\t\tcase BinaryNumericOperator.Mul:\n\t\t\t\t\treturn \"mul\";\n\t\t\t\tcase BinaryNumericOperator.Div:\n\t\t\t\t\treturn \"div\";\n\t\t\t\tcase BinaryNumericOperator.Rem:\n\t\t\t\t\treturn \"rem\";\n\t\t\t\tcase BinaryNumericOperator.BitAnd:\n\t\t\t\t\treturn \"bit.and\";\n\t\t\t\tcase BinaryNumericOperator.BitOr:\n\t\t\t\t\treturn \"bit.or\";\n\t\t\t\tcase BinaryNumericOperator.BitXor:\n\t\t\t\t\treturn \"bit.xor\";\n\t\t\t\tcase BinaryNumericOperator.ShiftLeft:\n\t\t\t\t\treturn \"bit.shl\";\n\t\t\t\tcase BinaryNumericOperator.ShiftRight:\n\t\t\t\t\treturn \"bit.shr\";\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t}\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(\".\" + GetOperatorName(Operator));\n\t\t\tif (CheckForOverflow)\n\t\t\t{\n\t\t\t\toutput.Write(\".ovf\");\n\t\t\t}\n\t\t\tif (Sign == Sign.Unsigned)\n\t\t\t{\n\t\t\t\toutput.Write(\".unsigned\");\n\t\t\t}\n\t\t\telse if (Sign == Sign.Signed)\n\t\t\t{\n\t\t\t\toutput.Write(\".signed\");\n\t\t\t}\n\t\t\toutput.Write('.');\n\t\t\toutput.Write(resultType.ToString().ToLowerInvariant());\n\t\t\tif (IsLifted)\n\t\t\t{\n\t\t\t\toutput.Write(\".lifted\");\n\t\t\t}\n\t\t\toutput.Write('(');\n\t\t\tLeft.WriteTo(output, options);\n\t\t\toutput.Write(\", \");\n\t\t\tRight.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/Block.cs",
    "content": "#nullable enable\n// Copyright (c) 2014-2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.TypeSystem;\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// A block consists of a list of IL instructions.\n\t/// \n\t/// <para>\n\t/// Note: if execution reaches the end of the instruction list,\n\t/// the FinalInstruction (which is not part of the list) will be executed.\n\t/// The block returns returns the result value of the FinalInstruction.\n\t/// For blocks returning void, the FinalInstruction will usually be 'nop'.\n\t/// </para>\n\t/// \n\t/// There are three different uses for blocks:\n\t/// 1) Blocks in block containers. Used as targets for Branch instructions.\n\t/// 2) Blocks to group a bunch of statements, e.g. the TrueInst of an IfInstruction.\n\t/// 3) Inline blocks that evaluate to a value, e.g. for array initializers.\n\t/// </summary>\n\tpartial class Block : ILInstruction\n\t{\n\t\tpublic static readonly SlotInfo InstructionSlot = new SlotInfo(\"Instruction\", isCollection: true);\n\t\tpublic static readonly SlotInfo FinalInstructionSlot = new SlotInfo(\"FinalInstruction\");\n\n\t\tpublic readonly BlockKind Kind;\n\t\tpublic readonly InstructionCollection<ILInstruction> Instructions;\n\t\tILInstruction finalInstruction = null!;\n\n\t\t/// <summary>\n\t\t/// For blocks in a block container, this field holds\n\t\t/// the number of incoming control flow edges to this block.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This variable is automatically updated when adding/removing branch instructions from the ILAst,\n\t\t/// or when adding the block as an entry point to a BlockContainer.\n\t\t/// </remarks>\n\t\tpublic int IncomingEdgeCount { get; internal set; }\n\n\t\t/// <summary>\n\t\t/// A 'final instruction' that gets executed after the <c>Instructions</c> collection.\n\t\t/// Provides the return value for the block.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Blocks in containers must have 'Nop' as a final instruction.\n\t\t/// \n\t\t/// Note that the FinalInstruction is included in Block.Children,\n\t\t/// but not in Block.Instructions!\n\t\t/// </remarks>\n\t\tpublic ILInstruction FinalInstruction {\n\t\t\tget {\n\t\t\t\treturn finalInstruction;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref finalInstruction, value, Instructions.Count);\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void InstructionCollectionUpdateComplete()\n\t\t{\n\t\t\tbase.InstructionCollectionUpdateComplete();\n\t\t\tif (finalInstruction.Parent == this)\n\t\t\t\tfinalInstruction.ChildIndex = Instructions.Count;\n\t\t}\n\n\t\tpublic Block(BlockKind kind = BlockKind.ControlFlow) : base(OpCode.Block)\n\t\t{\n\t\t\tthis.Kind = kind;\n\t\t\tthis.Instructions = new InstructionCollection<ILInstruction>(this, 0);\n\t\t\tthis.FinalInstruction = new Nop();\n\t\t}\n\n\t\tpublic override ILInstruction Clone()\n\t\t{\n\t\t\tBlock clone = new Block(Kind);\n\t\t\tclone.AddILRange(this);\n\t\t\tclone.Instructions.AddRange(this.Instructions.Select(inst => inst.Clone()));\n\t\t\tclone.FinalInstruction = this.FinalInstruction.Clone();\n\t\t\treturn clone;\n\t\t}\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tfor (int i = 0; i < Instructions.Count - 1; i++)\n\t\t\t{\n\t\t\t\t// only the last instruction may have an unreachable endpoint\n\t\t\t\tDebug.Assert(!Instructions[i].HasFlag(InstructionFlags.EndPointUnreachable));\n\t\t\t}\n\t\t\tswitch (this.Kind)\n\t\t\t{\n\t\t\t\tcase BlockKind.ControlFlow:\n\t\t\t\t\tDebug.Assert(finalInstruction.OpCode == OpCode.Nop);\n\t\t\t\t\tbreak;\n\t\t\t\tcase BlockKind.CallInlineAssign:\n\t\t\t\t\tDebug.Assert(MatchInlineAssignBlock(out _, out _));\n\t\t\t\t\tbreak;\n\t\t\t\tcase BlockKind.CallWithNamedArgs:\n\t\t\t\t\tDebug.Assert(finalInstruction is CallInstruction);\n\t\t\t\t\tforeach (var inst in Instructions)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar stloc = inst as StLoc;\n\t\t\t\t\t\tDebugAssert(stloc != null, \"Instructions in CallWithNamedArgs must be assignments\");\n\t\t\t\t\t\tDebugAssert(stloc.Variable.Kind == VariableKind.NamedArgument);\n\t\t\t\t\t\tDebugAssert(stloc.Variable.IsSingleDefinition && stloc.Variable.LoadCount == 1);\n\t\t\t\t\t\tDebugAssert(stloc.Variable.LoadInstructions.Single().Parent == finalInstruction);\n\t\t\t\t\t}\n\t\t\t\t\tvar call = (CallInstruction)finalInstruction;\n\t\t\t\t\tif (call.IsInstanceCall)\n\t\t\t\t\t{\n\t\t\t\t\t\t// special case: with instance calls, Instructions[0] must be for the this parameter\n\t\t\t\t\t\tILVariable v = ((StLoc)Instructions[0]).Variable;\n\t\t\t\t\t\tDebug.Assert(call.Arguments[0].MatchLdLoc(v));\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase BlockKind.ArrayInitializer:\n\t\t\t\t\tvar final = finalInstruction as LdLoc;\n\t\t\t\t\tDebug.Assert(final != null && final.Variable.IsSingleDefinition && final.Variable.Kind == VariableKind.InitializerTarget);\n\t\t\t\t\tIType? type = null;\n\t\t\t\t\tDebug.Assert(Instructions[0].MatchStLoc(final!.Variable, out var init) && init.MatchNewArr(out type));\n\t\t\t\t\tfor (int i = 1; i < Instructions.Count; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tDebugAssert(Instructions[i].MatchStObj(out ILInstruction? target, out _, out var t) && type != null && type.Equals(t));\n\t\t\t\t\t\tDebugAssert(target.MatchLdElema(out t, out ILInstruction? array) && type.Equals(t));\n\t\t\t\t\t\tDebugAssert(array.MatchLdLoc(out ILVariable? v) && v == final.Variable);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase BlockKind.CollectionInitializer:\n\t\t\t\tcase BlockKind.ObjectInitializer:\n\t\t\t\t\tvar final2 = finalInstruction as LdLoc;\n\t\t\t\t\tDebug.Assert(final2 != null);\n\t\t\t\t\tvar initVar2 = final2!.Variable;\n\t\t\t\t\tDebug.Assert(initVar2.StoreCount == 1 && initVar2.Kind == VariableKind.InitializerTarget);\n\t\t\t\t\tIType? type2 = null;\n\t\t\t\t\tbool condition = Instructions[0].MatchStLoc(final2.Variable, out var init2);\n\t\t\t\t\tDebug.Assert(condition);\n\t\t\t\t\tDebug.Assert(init2 is NewObj\n\t\t\t\t\t\t|| init2 is DefaultValue\n\t\t\t\t\t\t|| (init2 is CallInstruction c && c.Method.FullNameIs(\"System.Activator\", \"CreateInstance\") && c.Method.TypeArguments.Count == 1)\n\t\t\t\t\t\t|| (init2 is Block named && named.Kind == BlockKind.CallWithNamedArgs));\n\t\t\t\t\tswitch (init2)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase NewObj newObj:\n\t\t\t\t\t\t\ttype2 = newObj.Method.DeclaringType;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DefaultValue defaultValue:\n\t\t\t\t\t\t\ttype2 = defaultValue.Type;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase Block callWithNamedArgs when callWithNamedArgs.Kind == BlockKind.CallWithNamedArgs:\n\t\t\t\t\t\t\ttype2 = ((CallInstruction)callWithNamedArgs.FinalInstruction).Method.ReturnType;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase CallInstruction ci2 when TransformCollectionAndObjectInitializers.IsRecordCloneMethodCall(ci2):\n\t\t\t\t\t\t\ttype2 = ci2.Method.DeclaringType;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase Call c2 when c2.Method.FullNameIs(\"System.Activator\", \"CreateInstance\") && c2.Method.TypeArguments.Count == 1:\n\t\t\t\t\t\t\ttype2 = c2.Method.TypeArguments[0];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tDebug.Assert(false);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tfor (int i = 1; i < Instructions.Count; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(Instructions[i] is StLoc || AccessPathElement.GetAccessPath(Instructions[i], type2).Kind != AccessPathKind.Invalid);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase BlockKind.DeconstructionConversions:\n\t\t\t\t\tDebug.Assert(this.SlotInfo == DeconstructInstruction.ConversionsSlot);\n\t\t\t\t\tbreak;\n\t\t\t\tcase BlockKind.DeconstructionAssignments:\n\t\t\t\t\tDebug.Assert(this.SlotInfo == DeconstructInstruction.AssignmentsSlot);\n\t\t\t\t\tbreak;\n\t\t\t\tcase BlockKind.InterpolatedString:\n\t\t\t\t\tDebug.Assert(FinalInstruction is Call { Method: { Name: \"ToStringAndClear\" }, Arguments: { Count: 1 } });\n\t\t\t\t\tvar interpolInit = Instructions[0] as StLoc;\n\t\t\t\t\tDebugAssert(interpolInit != null\n\t\t\t\t\t\t&& interpolInit.Variable.Kind == VariableKind.InitializerTarget\n\t\t\t\t\t\t&& interpolInit.Variable.AddressCount == Instructions.Count\n\t\t\t\t\t\t&& interpolInit.Variable.StoreCount == 1);\n\t\t\t\t\tfor (int i = 1; i < Instructions.Count; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tCall? inst = Instructions[i] as Call;\n\t\t\t\t\t\tDebugAssert(inst != null);\n\t\t\t\t\t\tDebugAssert(inst.Arguments.Count >= 1 && inst.Arguments[0].MatchLdLoca(interpolInit.Variable));\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic override StackType ResultType {\n\t\t\tget {\n\t\t\t\treturn finalInstruction.ResultType;\n\t\t\t}\n\t\t}\n\n\t\tinternal override bool CanInlineIntoSlot(int childIndex, ILInstruction expressionBeingMoved)\n\t\t{\n\t\t\tswitch (Kind)\n\t\t\t{\n\t\t\t\tcase BlockKind.ControlFlow when Parent is BlockContainer:\n\t\t\t\tcase BlockKind.ArrayInitializer:\n\t\t\t\tcase BlockKind.CollectionInitializer:\n\t\t\t\tcase BlockKind.ObjectInitializer:\n\t\t\t\tcase BlockKind.CallInlineAssign:\n\t\t\t\t\t// Allow inlining into the first instruction of the block\n\t\t\t\t\treturn childIndex == 0;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the name of this block.\n\t\t/// </summary>\n\t\tpublic string Label {\n\t\t\tget { return Disassembler.DisassemblerHelpers.OffsetToString(this.StartILOffset); }\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(\"Block \");\n\t\t\toutput.WriteLocalReference(Label, this, isDefinition: true);\n\t\t\tif (Kind != BlockKind.ControlFlow)\n\t\t\t\toutput.Write($\" ({Kind})\");\n\t\t\tif (Parent is BlockContainer)\n\t\t\t\toutput.Write(\" (incoming: {0})\", IncomingEdgeCount);\n\t\t\toutput.Write(' ');\n\t\t\toutput.MarkFoldStart(\"{...}\");\n\t\t\toutput.WriteLine(\"{\");\n\t\t\toutput.Indent();\n\t\t\tint index = 0;\n\t\t\tforeach (var inst in Instructions)\n\t\t\t{\n\t\t\t\tif (options.ShowChildIndexInBlock)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\"[\" + index + \"] \");\n\t\t\t\t\tindex++;\n\t\t\t\t}\n\t\t\t\tinst.WriteTo(output, options);\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t\tif (finalInstruction.OpCode != OpCode.Nop)\n\t\t\t{\n\t\t\t\toutput.Write(\"final: \");\n\t\t\t\tfinalInstruction.WriteTo(output, options);\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t\toutput.Unindent();\n\t\t\toutput.Write(\"}\");\n\t\t\toutput.MarkFoldEnd();\n\t\t}\n\n\t\tprotected override int GetChildCount()\n\t\t{\n\t\t\treturn Instructions.Count + 1;\n\t\t}\n\n\t\tprotected override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tif (index == Instructions.Count)\n\t\t\t\treturn finalInstruction;\n\t\t\treturn Instructions[index];\n\t\t}\n\n\t\tprotected override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tif (index == Instructions.Count)\n\t\t\t\tFinalInstruction = value;\n\t\t\telse\n\t\t\t\tInstructions[index] = value;\n\t\t}\n\n\t\tprotected override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tif (index == Instructions.Count)\n\t\t\t\treturn FinalInstructionSlot;\n\t\t\telse\n\t\t\t\treturn InstructionSlot;\n\t\t}\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\tvar flags = InstructionFlags.None;\n\t\t\tforeach (var inst in Instructions)\n\t\t\t{\n\t\t\t\tflags |= inst.Flags;\n\t\t\t}\n\t\t\tflags |= FinalInstruction.Flags;\n\t\t\treturn flags;\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.None;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Deletes this block from its parent container.\n\t\t/// This may cause the indices of other blocks in that container to change.\n\t\t/// \n\t\t/// It is an error to call this method on blocks that are not directly within a container.\n\t\t/// It is also an error to call this method on the entry-point block.\n\t\t/// </summary>\n\t\tpublic void Remove()\n\t\t{\n\t\t\tDebug.Assert(ChildIndex > 0);\n\t\t\tvar container = (BlockContainer)Parent!;\n\t\t\tDebug.Assert(container.Blocks[ChildIndex] == this);\n\t\t\tcontainer.Blocks.SwapRemoveAt(ChildIndex);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Apply a list of transforms to this function.\n\t\t/// </summary>\n\t\tpublic void RunTransforms(IEnumerable<IBlockTransform> transforms, BlockTransformContext context)\n\t\t{\n\t\t\tthis.CheckInvariant(ILPhase.Normal);\n\t\t\tforeach (var transform in transforms)\n\t\t\t{\n\t\t\t\tcontext.CancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tDebug.Assert(context.IndexOfFirstAlreadyTransformedInstruction <= this.Instructions.Count);\n\t\t\t\tcontext.StepStartGroup(transform.GetType().Name);\n\t\t\t\ttransform.Run(this, context);\n\t\t\t\tthis.CheckInvariant(ILPhase.Normal);\n\t\t\t\tcontext.StepEndGroup();\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the predecessor of the given instruction.\n\t\t/// Returns null if inst.Parent is not a block.\n\t\t/// </summary>\n\t\tpublic static ILInstruction? GetPredecessor(ILInstruction inst)\n\t\t{\n\t\t\tif (inst.Parent is Block block && inst.ChildIndex > 0)\n\t\t\t{\n\t\t\t\treturn block.Instructions[inst.ChildIndex - 1];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// If inst is a block consisting of a single instruction, returns that instruction.\n\t\t/// Otherwise, returns the input instruction.\n\t\t/// </summary>\n\t\t[return: NotNullIfNotNull(\"inst\")]\n\t\tpublic static ILInstruction? Unwrap(ILInstruction? inst)\n\t\t{\n\t\t\tif (inst is Block block)\n\t\t\t{\n\t\t\t\tif (block.Instructions.Count == 1 && block.finalInstruction.MatchNop())\n\t\t\t\t\treturn block.Instructions[0];\n\t\t\t}\n\t\t\treturn inst;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the closest parent Block.\n\t\t/// Returns null, if the instruction is not a descendant of a Block.\n\t\t/// </summary>\n\t\tpublic static Block? FindClosestBlock(ILInstruction? inst)\n\t\t{\n\t\t\tvar curr = inst;\n\t\t\twhile (curr != null)\n\t\t\t{\n\t\t\t\tif (curr is Block b)\n\t\t\t\t\treturn b;\n\t\t\t\tcurr = curr.Parent;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the closest ancestor that is child of a control-flow (top-level) Block.\n\t\t/// Returns null, if the instruction is not a descendant of a Block.\n\t\t/// </summary>\n\t\tpublic static ILInstruction? GetContainingStatement(ILInstruction inst)\n\t\t{\n\t\t\tvar curr = inst;\n\t\t\twhile (curr != null)\n\t\t\t{\n\t\t\t\tif (curr.Parent is Block { Kind: BlockKind.ControlFlow })\n\t\t\t\t\treturn curr;\n\t\t\t\tcurr = curr.Parent;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic bool MatchInlineAssignBlock([NotNullWhen(true)] out CallInstruction? call, [NotNullWhen(true)] out ILInstruction? value)\n\t\t{\n\t\t\tcall = null;\n\t\t\tvalue = null;\n\t\t\tif (this.Kind != BlockKind.CallInlineAssign)\n\t\t\t\treturn false;\n\t\t\tif (this.Instructions.Count != 1)\n\t\t\t\treturn false;\n\t\t\tcall = this.Instructions[0] as CallInstruction;\n\t\t\tif (call == null || call.Arguments.Count == 0)\n\t\t\t\treturn false;\n\t\t\tif (!call.Arguments.Last().MatchStLoc(out var tmp, out value))\n\t\t\t\treturn false;\n\t\t\tif (!(tmp.IsSingleDefinition && tmp.LoadCount == 1))\n\t\t\t\treturn false;\n\t\t\treturn this.FinalInstruction.MatchLdLoc(tmp);\n\t\t}\n\n\t\tpublic bool MatchIfAtEndOfBlock([NotNullWhen(true)] out ILInstruction? condition, [NotNullWhen(true)] out ILInstruction? trueInst, [NotNullWhen(true)] out ILInstruction? falseInst)\n\t\t{\n\t\t\tcondition = null;\n\t\t\ttrueInst = null;\n\t\t\tfalseInst = null;\n\t\t\tif (Instructions.Count < 2)\n\t\t\t\treturn false;\n\t\t\tif (Instructions[Instructions.Count - 2].MatchIfInstruction(out condition, out trueInst))\n\t\t\t{\n\t\t\t\t// Swap trueInst<>falseInst for every logic.not in the condition.\n\t\t\t\tfalseInst = Instructions.Last();\n\t\t\t\twhile (condition.MatchLogicNot(out var arg))\n\t\t\t\t{\n\t\t\t\t\tcondition = arg;\n\t\t\t\t\t(trueInst, falseInst) = (falseInst, trueInst);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic enum BlockKind\n\t{\n\t\t/// <summary>\n\t\t/// Block is used for control flow.\n\t\t/// All blocks in block containers must have this type.\n\t\t/// Control flow blocks cannot evaluate to a value (FinalInstruction must be Nop).\n\t\t/// </summary>\n\t\tControlFlow,\n\t\t/// <summary>\n\t\t/// Block is used for array initializers, e.g. `new int[] { expr1, expr2 }`.\n\t\t/// </summary>\n\t\tArrayInitializer,\n\t\tCollectionInitializer,\n\t\tObjectInitializer,\n\t\tStackAllocInitializer,\n\t\t/// <summary>\n\t\t/// Block is used for using the result of a property setter inline.\n\t\t/// Example: <code>Use(this.Property = value);</code>\n\t\t/// This is only for inline assignments to property or indexers; other inline assignments work\n\t\t/// by using the result value of the stloc/stobj instructions.\n\t\t/// \n\t\t/// Constructed by TransformAssignment.\n\t\t/// Can be deconstructed using Block.MatchInlineAssignBlock().\n\t\t/// </summary>\n\t\t/// <example>\n\t\t/// Block {\n\t\t///   call setter(..., stloc s(...))\n\t\t///   final: ldloc s\n\t\t/// }\n\t\t/// </example>\n\t\tCallInlineAssign,\n\t\t/// <summary>\n\t\t/// Call using named arguments.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Each instruction is assigning to a new local.\n\t\t/// The final instruction is a call.\n\t\t/// The locals for this block have exactly one store and\n\t\t/// exactly one load, which must be an immediate argument to the call.\n\t\t/// </remarks>\n\t\t/// <example>\n\t\t/// Block {\n\t\t///   stloc arg0 = ...\n\t\t///   stloc arg1 = ...\n\t\t///   final: call M(..., arg1, arg0, ...)\n\t\t/// }\n\t\t/// </example>\n\t\tCallWithNamedArgs,\n\t\t/// <summary>\n\t\t/// <see cref=\"DeconstructInstruction\"/>\n\t\t/// </summary>\n\t\tDeconstructionConversions,\n\t\t/// <summary>\n\t\t/// <see cref=\"DeconstructInstruction\"/>\n\t\t/// </summary>\n\t\tDeconstructionAssignments,\n\t\tWithInitializer,\n\t\t/// <summary>\n\t\t/// String interpolation using DefaultInterpolatedStringHandler.\n\t\t/// </summary>\n\t\t/// <example>\n\t\t/// Block {\n\t\t///\t\tstloc I_0 = newobj DefaultInterpolatedStringHandler(...)\n\t\t///\t\tcall AppendXXX(I_0, ...)\n\t\t///\t\t...\n\t\t///\t\tfinal: call ToStringAndClear(ldloc I_0)\n\t\t/// }\n\t\t/// </example>\n\t\tInterpolatedString,\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.Util;\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// A container of IL blocks.\n\t/// Each block is an extended basic block (branches may only jump to the beginning of blocks, not into the middle),\n\t/// and only branches within this container may reference the blocks in this container.\n\t/// That means that viewed from the outside, the block container has a single entry point (but possibly multiple exit points),\n\t/// and the same holds for every block within the container.\n\t/// \n\t/// All blocks in the container must perform unconditional control flow (falling through to the block end is not allowed).\n\t/// To exit the block container, use the 'leave' instruction.\n\t/// </summary>\n\tpartial class BlockContainer : ILInstruction\n\t{\n\t\tpublic static readonly SlotInfo BlockSlot = new SlotInfo(\"Block\", isCollection: true);\n\t\tpublic readonly InstructionCollection<Block> Blocks;\n\n\t\tpublic ContainerKind Kind { get; set; }\n\t\tpublic StackType ExpectedResultType { get; set; }\n\n\t\tint leaveCount;\n\n\t\t/// <summary>\n\t\t/// Gets the number of 'leave' instructions that target this BlockContainer.\n\t\t/// </summary>\n\t\tpublic int LeaveCount {\n\t\t\tget => leaveCount;\n\t\t\tinternal set {\n\t\t\t\tleaveCount = value;\n\t\t\t\tInvalidateFlags();\n\t\t\t}\n\t\t}\n\n\t\tBlock? entryPoint;\n\n\t\t/// <summary>\n\t\t/// Gets the container's entry point. This is the first block in the Blocks collection.\n\t\t/// </summary>\n\t\tpublic Block EntryPoint {\n\t\t\tget {\n\t\t\t\t// HACK: While it's possible to have BlockContainers without entry point,\n\t\t\t\t// normally every container must have an entry point according to its invariant.\n\t\t\t\t// Thus it's easier on the transforms if this property returns a non-nullable EntryPoint.\n\t\t\t\treturn entryPoint!;\n\t\t\t}\n\t\t\tprivate set {\n\t\t\t\tif (entryPoint != null && IsConnected)\n\t\t\t\t\tentryPoint.IncomingEdgeCount--;\n\t\t\t\tentryPoint = value;\n\t\t\t\tif (entryPoint != null && IsConnected)\n\t\t\t\t\tentryPoint.IncomingEdgeCount++;\n\t\t\t}\n\t\t}\n\n\t\tpublic BlockContainer(ContainerKind kind = ContainerKind.Normal, StackType expectedResultType = StackType.Void) : base(OpCode.BlockContainer)\n\t\t{\n\t\t\tthis.Kind = kind;\n\t\t\tthis.Blocks = new InstructionCollection<Block>(this, 0);\n\t\t\tthis.ExpectedResultType = expectedResultType;\n\t\t}\n\n\t\tpublic override ILInstruction Clone()\n\t\t{\n\t\t\tBlockContainer clone = new BlockContainer(this.Kind, this.ExpectedResultType);\n\t\t\tclone.AddILRange(this);\n\t\t\tclone.Blocks.AddRange(this.Blocks.Select(block => (Block)block.Clone()));\n\t\t\t// Adjust branch instructions to point to the new container\n\t\t\tforeach (var branch in clone.Descendants.OfType<Branch>())\n\t\t\t{\n\t\t\t\tif (branch.TargetBlock != null && branch.TargetBlock.Parent == this)\n\t\t\t\t\tbranch.TargetBlock = clone.Blocks[branch.TargetBlock.ChildIndex];\n\t\t\t}\n\t\t\tforeach (var leave in clone.Descendants.OfType<Leave>())\n\t\t\t{\n\t\t\t\tif (leave.TargetContainer == this)\n\t\t\t\t\tleave.TargetContainer = clone;\n\t\t\t}\n\t\t\treturn clone;\n\t\t}\n\n\t\tprotected internal override void InstructionCollectionUpdateComplete()\n\t\t{\n\t\t\tbase.InstructionCollectionUpdateComplete();\n\t\t\tthis.EntryPoint = this.Blocks.FirstOrDefault()!;\n\t\t}\n\n\t\tprotected override void Connected()\n\t\t{\n\t\t\tbase.Connected();\n\t\t\tif (entryPoint != null)\n\t\t\t\tentryPoint.IncomingEdgeCount++;\n\t\t}\n\n\t\tprotected override void Disconnected()\n\t\t{\n\t\t\tbase.Disconnected();\n\t\t\tif (entryPoint != null)\n\t\t\t\tentryPoint.IncomingEdgeCount--;\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.WriteLocalReference(\"BlockContainer\", this, isDefinition: true);\n\t\t\toutput.Write(' ');\n\t\t\tswitch (Kind)\n\t\t\t{\n\t\t\t\tcase ContainerKind.Loop:\n\t\t\t\t\toutput.Write(\"(while-true) \");\n\t\t\t\t\tbreak;\n\t\t\t\tcase ContainerKind.Switch:\n\t\t\t\t\toutput.Write(\"(switch) \");\n\t\t\t\t\tbreak;\n\t\t\t\tcase ContainerKind.While:\n\t\t\t\t\toutput.Write(\"(while) \");\n\t\t\t\t\tbreak;\n\t\t\t\tcase ContainerKind.DoWhile:\n\t\t\t\t\toutput.Write(\"(do-while) \");\n\t\t\t\t\tbreak;\n\t\t\t\tcase ContainerKind.For:\n\t\t\t\t\toutput.Write(\"(for) \");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\toutput.MarkFoldStart(\"{...}\");\n\t\t\toutput.WriteLine(\"{\");\n\t\t\toutput.Indent();\n\t\t\tforeach (var inst in Blocks)\n\t\t\t{\n\t\t\t\tif (inst.Parent == this)\n\t\t\t\t{\n\t\t\t\t\tinst.WriteTo(output, options);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\"stale reference to \");\n\t\t\t\t\toutput.WriteLocalReference(inst.Label, inst);\n\t\t\t\t}\n\t\t\t\toutput.WriteLine();\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t\toutput.Unindent();\n\t\t\toutput.Write(\"}\");\n\t\t\toutput.MarkFoldEnd();\n\t\t}\n\n\t\tprotected override int GetChildCount()\n\t\t{\n\t\t\treturn Blocks.Count;\n\t\t}\n\n\t\tprotected override ILInstruction GetChild(int index)\n\t\t{\n\t\t\treturn Blocks[index];\n\t\t}\n\n\t\tprotected override void SetChild(int index, ILInstruction? value)\n\t\t{\n\t\t\tif (Blocks[index] != value)\n\t\t\t\tthrow new InvalidOperationException(\"Cannot replace blocks in BlockContainer\");\n\t\t}\n\n\t\tprotected override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\treturn BlockSlot;\n\t\t}\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebug.Assert(Blocks.Count > 0 && EntryPoint == Blocks[0]);\n\t\t\tDebug.Assert(!IsConnected || EntryPoint.IncomingEdgeCount >= 1);\n\t\t\tDebug.Assert(Parent is ILFunction || !ILRangeIsEmpty);\n\t\t\tDebug.Assert(Blocks.All(b => b.HasFlag(InstructionFlags.EndPointUnreachable)));\n\t\t\tDebug.Assert(Blocks.All(b => b.Kind == BlockKind.ControlFlow)); // this also implies that the blocks don't use FinalInstruction\n\t\t\tDebug.Assert(TopologicalSort(deleteUnreachableBlocks: true).Count == Blocks.Count, \"Container should not have any unreachable blocks\");\n\t\t\tBlock? bodyStartBlock;\n\t\t\tswitch (Kind)\n\t\t\t{\n\t\t\t\tcase ContainerKind.Normal:\n\t\t\t\t\tbreak;\n\t\t\t\tcase ContainerKind.Loop:\n\t\t\t\t\tDebug.Assert(EntryPoint.IncomingEdgeCount > 1);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ContainerKind.Switch:\n\t\t\t\t\tDebug.Assert(EntryPoint.Instructions.Count == 1);\n\t\t\t\t\tDebug.Assert(EntryPoint.Instructions[0] is SwitchInstruction);\n\t\t\t\t\tDebug.Assert(EntryPoint.IncomingEdgeCount == 1);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ContainerKind.While:\n\t\t\t\t\tDebug.Assert(EntryPoint.IncomingEdgeCount > 1);\n\t\t\t\t\tDebug.Assert(Blocks.Count >= 2);\n\t\t\t\t\tDebug.Assert(MatchConditionBlock(EntryPoint, out _, out bodyStartBlock));\n\t\t\t\t\tDebug.Assert(bodyStartBlock == Blocks[1]);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ContainerKind.DoWhile:\n\t\t\t\t\tDebug.Assert(EntryPoint.IncomingEdgeCount > 1);\n\t\t\t\t\tDebug.Assert(Blocks.Count >= 2);\n\t\t\t\t\tDebug.Assert(MatchConditionBlock(Blocks.Last(), out _, out bodyStartBlock));\n\t\t\t\t\tDebug.Assert(bodyStartBlock == EntryPoint);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ContainerKind.For:\n\t\t\t\t\tDebug.Assert(EntryPoint.IncomingEdgeCount == 2);\n\t\t\t\t\tDebug.Assert(Blocks.Count >= 3);\n\t\t\t\t\tDebug.Assert(MatchConditionBlock(EntryPoint, out _, out bodyStartBlock));\n\t\t\t\t\tDebug.Assert(MatchIncrementBlock(Blocks.Last()));\n\t\t\t\t\tDebug.Assert(bodyStartBlock == Blocks[1]);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\tInstructionFlags flags = InstructionFlags.ControlFlow;\n\t\t\tforeach (var block in Blocks)\n\t\t\t{\n\t\t\t\tflags |= block.Flags;\n\t\t\t}\n\t\t\t// The end point of the BlockContainer is only reachable if there's a leave instruction\n\t\t\tif (LeaveCount == 0)\n\t\t\t\tflags |= InstructionFlags.EndPointUnreachable;\n\t\t\telse\n\t\t\t\tflags &= ~InstructionFlags.EndPointUnreachable;\n\t\t\treturn flags;\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.ControlFlow;\n\t\t\t}\n\t\t}\n\n\t\tinternal override bool CanInlineIntoSlot(int childIndex, ILInstruction expressionBeingMoved)\n\t\t{\n\t\t\t// Inlining into the entry-point is allowed as long as we're not moving code into a loop.\n\t\t\t// This is used to inline into the switch expression.\n\t\t\treturn childIndex == 0 && this.EntryPoint.IncomingEdgeCount == 1;\n\t\t}\n\n\t\tinternal override bool PrepareExtract(int childIndex, ExtractionContext ctx)\n\t\t{\n\t\t\t// Un-inlining from the entry-point is allowed as long as we're not moving code out of a loop\n\t\t\treturn childIndex == 0 && this.EntryPoint.IncomingEdgeCount == 1;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Topologically sort the blocks.\n\t\t/// The new order is returned without modifying the BlockContainer.\n\t\t/// </summary>\n\t\t/// <param name=\"deleteUnreachableBlocks\">If true, unreachable blocks are not included in the new order.</param>\n\t\tpublic List<Block> TopologicalSort(bool deleteUnreachableBlocks = false)\n\t\t{\n\t\t\t// Visit blocks in post-order\n\t\t\tBitSet visited = new BitSet(Blocks.Count);\n\t\t\tList<Block> postOrder = new List<Block>();\n\t\t\tGraphTraversal.DepthFirstSearch(new[] { EntryPoint }, MarkAsVisited, Successors, postOrder.Add, reverseSuccessors: true);\n\t\t\tpostOrder.Reverse();\n\t\t\tif (!deleteUnreachableBlocks)\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < Blocks.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (!visited[i])\n\t\t\t\t\t\tpostOrder.Add(Blocks[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn postOrder;\n\n\t\t\tbool MarkAsVisited(Block block)\n\t\t\t{\n\t\t\t\tDebug.Assert(block.Parent == this);\n\t\t\t\tif (!visited[block.ChildIndex])\n\t\t\t\t{\n\t\t\t\t\tvisited[block.ChildIndex] = true;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tIEnumerable<Block> Successors(Block block)\n\t\t\t{\n\t\t\t\tforeach (var branch in block.Descendants.OfType<Branch>())\n\t\t\t\t{\n\t\t\t\t\tif (branch.TargetBlock.Parent == this)\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return branch.TargetBlock;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Topologically sort the blocks.\n\t\t/// </summary>\n\t\t/// <param name=\"deleteUnreachableBlocks\">If true, delete unreachable blocks.</param>\n\t\tpublic void SortBlocks(bool deleteUnreachableBlocks = false)\n\t\t{\n\t\t\tif (Blocks.Count < 2)\n\t\t\t\treturn;\n\n\t\t\tvar newOrder = TopologicalSort(deleteUnreachableBlocks);\n\t\t\tDebug.Assert(newOrder[0] == Blocks[0]);\n\t\t\tBlocks.ReplaceList(newOrder);\n\t\t}\n\n\t\tpublic static BlockContainer? FindClosestContainer(ILInstruction? inst)\n\t\t{\n\t\t\twhile (inst != null)\n\t\t\t{\n\t\t\t\tif (inst is BlockContainer bc)\n\t\t\t\t\treturn bc;\n\t\t\t\tinst = inst.Parent;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static BlockContainer? FindClosestSwitchContainer(ILInstruction? inst)\n\t\t{\n\t\t\twhile (inst != null)\n\t\t\t{\n\t\t\t\tif (inst is BlockContainer { Kind: ContainerKind.Switch } bc)\n\t\t\t\t\treturn bc;\n\t\t\t\tinst = inst.Parent;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic bool MatchConditionBlock(Block block, [NotNullWhen(true)] out ILInstruction? condition, [NotNullWhen(true)] out Block? bodyStartBlock)\n\t\t{\n\t\t\tcondition = null;\n\t\t\tbodyStartBlock = null;\n\t\t\tif (block.Instructions.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (!block.Instructions[0].MatchIfInstruction(out condition, out var trueInst, out var falseInst))\n\t\t\t\treturn false;\n\t\t\treturn falseInst.MatchLeave(this) && trueInst.MatchBranch(out bodyStartBlock);\n\t\t}\n\n\t\tpublic bool MatchIncrementBlock(Block block)\n\t\t{\n\t\t\tif (block.Instructions.Count == 0)\n\t\t\t\treturn false;\n\t\t\tif (!block.Instructions.Last().MatchBranch(EntryPoint))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// If the container consists of a single block with a single instruction,\n\t\t/// returns that instruction.\n\t\t/// Otherwise returns the block, or the container itself if it has multiple blocks.\n\t\t/// </summary>\n\t\tpublic ILInstruction SingleInstruction()\n\t\t{\n\t\t\tif (Blocks.Count != 1)\n\t\t\t\treturn this;\n\t\t\tif (Blocks[0].Instructions.Count != 1)\n\t\t\t\treturn Blocks[0];\n\t\t\treturn Blocks[0].Instructions[0];\n\t\t}\n\t}\n\n\tpublic enum ContainerKind\n\t{\n\t\t/// <summary>\n\t\t/// Normal container that contains control-flow blocks.\n\t\t/// </summary>\n\t\tNormal,\n\t\t/// <summary>\n\t\t/// A while-true loop.\n\t\t/// Continue is represented as branch to entry-point.\n\t\t/// Return/break is represented as leave.\n\t\t/// </summary>\n\t\tLoop,\n\t\t/// <summary>\n\t\t/// Container that has a switch instruction as entry-point.\n\t\t/// Goto case is represented as branch.\n\t\t/// Break is represented as leave.\n\t\t/// </summary>\n\t\tSwitch,\n\t\t/// <summary>\n\t\t/// while-loop.\n\t\t/// The entry-point is a block consisting of a single if instruction\n\t\t/// that if true: jumps to the head of the loop body,\n\t\t/// if false: leaves the block.\n\t\t/// Continue is a branch to the entry-point.\n\t\t/// Break is a leave.\n\t\t/// </summary>\n\t\tWhile,\n\t\t/// <summary>\n\t\t/// do-while-loop.\n\t\t/// The entry-point is a block that is the head of the loop body.\n\t\t/// The last block consists of a single if instruction\n\t\t/// that if true: jumps to the head of the loop body,\n\t\t/// if false: leaves the block.\n\t\t/// Only the last block is allowed to jump to the entry-point.\n\t\t/// Continue is a branch to the last block.\n\t\t/// Break is a leave.\n\t\t/// </summary>\n\t\tDoWhile,\n\t\t/// <summary>\n\t\t/// for-loop.\n\t\t/// The entry-point is a block consisting of a single if instruction\n\t\t/// that if true: jumps to the head of the loop body,\n\t\t/// if false: leaves the block.\n\t\t/// The last block is the increment block.\n\t\t/// Only the last block is allowed to jump to the entry-point.\n\t\t/// Continue is a branch to the last block.\n\t\t/// Break is a leave.\n\t\t/// </summary>\n\t\tFor\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/Branch.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// Unconditional branch. <c>goto target;</c>\n\t/// </summary>\n\t/// <remarks>\n\t/// When jumping to the entrypoint of the current block container, the branch represents a <c>continue</c> statement.\n\t/// </remarks>\n\tpartial class Branch : SimpleInstruction, IBranchOrLeaveInstruction\n\t{\n\t\treadonly int targetILOffset;\n\t\tBlock? targetBlock;\n\n\t\tpublic Branch(int targetILOffset) : base(OpCode.Branch)\n\t\t{\n\t\t\tthis.targetILOffset = targetILOffset;\n\t\t}\n\n\t\tpublic Branch(Block targetBlock) : base(OpCode.Branch)\n\t\t{\n\t\t\tthis.targetBlock = targetBlock ?? throw new ArgumentNullException(nameof(targetBlock));\n\t\t\tthis.targetILOffset = targetBlock.StartILOffset;\n\t\t}\n\n\t\tpublic int TargetILOffset {\n\t\t\tget { return targetBlock != null ? targetBlock.StartILOffset : targetILOffset; }\n\t\t}\n\n\t\tpublic Block TargetBlock {\n\t\t\tget {\n\t\t\t\t// HACK: We treat TargetBlock as non-nullable publicly, because it's only null inside\n\t\t\t\t// the ILReader, and becomes non-null once the BlockBuilder has run.\n\t\t\t\treturn targetBlock!;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tif (targetBlock != null && IsConnected)\n\t\t\t\t\ttargetBlock.IncomingEdgeCount--;\n\t\t\t\ttargetBlock = value;\n\t\t\t\tif (targetBlock != null && IsConnected)\n\t\t\t\t\ttargetBlock.IncomingEdgeCount++;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the BlockContainer that contains the target block.\n\t\t/// </summary>\n\t\tpublic BlockContainer TargetContainer {\n\t\t\tget { return (BlockContainer)targetBlock?.Parent!; }\n\t\t}\n\n\t\tprotected override void Connected()\n\t\t{\n\t\t\tbase.Connected();\n\t\t\tif (targetBlock != null)\n\t\t\t\ttargetBlock.IncomingEdgeCount++;\n\t\t}\n\n\t\tprotected override void Disconnected()\n\t\t{\n\t\t\tbase.Disconnected();\n\t\t\tif (targetBlock != null)\n\t\t\t\ttargetBlock.IncomingEdgeCount--;\n\t\t}\n\n\t\tpublic string TargetLabel {\n\t\t\tget { return targetBlock != null ? targetBlock.Label : string.Format(\"IL_{0:x4}\", TargetILOffset); }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this branch executes at least one finally block before jumping to the target block.\n\t\t/// </summary>\n\t\tpublic bool TriggersFinallyBlock {\n\t\t\tget {\n\t\t\t\treturn GetExecutesFinallyBlock(this, TargetContainer);\n\t\t\t}\n\t\t}\n\n\t\tinternal static bool GetExecutesFinallyBlock(ILInstruction? inst, BlockContainer? container)\n\t\t{\n\t\t\tfor (; inst != container && inst != null; inst = inst.Parent)\n\t\t\t{\n\t\t\t\tif (inst.Parent is TryFinally && inst.SlotInfo == TryFinally.TryBlockSlot)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tif (phase > ILPhase.InILReader)\n\t\t\t{\n\t\t\t\tDebug.Assert(targetBlock?.Parent is BlockContainer);\n\t\t\t\tDebug.Assert(this.IsDescendantOf(targetBlock!.Parent!));\n\t\t\t\tDebug.Assert(targetBlock!.Parent!.Children[targetBlock.ChildIndex] == targetBlock);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\toutput.WriteLocalReference(TargetLabel, (object?)targetBlock ?? TargetILOffset);\n\t\t}\n\t}\n\n\tinterface IBranchOrLeaveInstruction\n\t{\n\t\tBlockContainer TargetContainer { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs",
    "content": "#nullable enable\n// Copyright (c) 2017 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpartial class CallIndirect\n\t{\n\t\t// Note: while in IL the arguments come first and the function pointer last;\n\t\t// in the ILAst we're handling it as in C#: the function pointer is evaluated first, the arguments later.\n\t\tpublic static readonly SlotInfo FunctionPointerSlot = new SlotInfo(\"FunctionPointer\", canInlineInto: true);\n\t\tpublic static readonly SlotInfo ArgumentSlot = new SlotInfo(\"Argument\", canInlineInto: true, isCollection: true);\n\n\t\tILInstruction functionPointer = null!;\n\t\tpublic readonly InstructionCollection<ILInstruction> Arguments;\n\t\tpublic bool IsInstance { get; }\n\t\tpublic bool HasExplicitThis { get; }\n\t\tpublic FunctionPointerType FunctionPointerType { get; }\n\n\t\tpublic ILInstruction FunctionPointer {\n\t\t\tget {\n\t\t\t\treturn functionPointer;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref functionPointer, value, 0);\n\t\t\t}\n\t\t}\n\n\t\tpublic CallIndirect(bool isInstance, bool hasExplicitThis, FunctionPointerType functionPointerType,\n\t\t\tILInstruction functionPointer, IEnumerable<ILInstruction> arguments) : base(OpCode.CallIndirect)\n\t\t{\n\t\t\tthis.IsInstance = isInstance;\n\t\t\tthis.HasExplicitThis = hasExplicitThis;\n\t\t\tthis.FunctionPointerType = functionPointerType;\n\t\t\tthis.FunctionPointer = functionPointer;\n\t\t\tthis.Arguments = new InstructionCollection<ILInstruction>(this, 1);\n\t\t\tthis.Arguments.AddRange(arguments);\n\t\t}\n\n\t\tpublic override ILInstruction Clone()\n\t\t{\n\t\t\treturn new CallIndirect(IsInstance, HasExplicitThis, FunctionPointerType,\n\t\t\t\tfunctionPointer.Clone(), this.Arguments.Select(inst => inst.Clone())\n\t\t\t).WithILRange(this);\n\t\t}\n\n\t\tpublic override StackType ResultType => FunctionPointerType.ReturnType.GetStackType();\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebug.Assert(Arguments.Count == FunctionPointerType.ParameterTypes.Length + (IsInstance ? 1 : 0));\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(\"call.indirect \");\n\t\t\tFunctionPointerType.ReturnType.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tfunctionPointer.WriteTo(output, options);\n\t\t\tint firstArgument = IsInstance ? 1 : 0;\n\t\t\tif (firstArgument == 1)\n\t\t\t{\n\t\t\t\toutput.Write(\", \");\n\t\t\t\tArguments[0].WriteTo(output, options);\n\t\t\t}\n\t\t\tforeach (var (inst, type) in Arguments.Zip(FunctionPointerType.ParameterTypes, (a, b) => (a, b)))\n\t\t\t{\n\t\t\t\toutput.Write(\", \");\n\t\t\t\tinst.WriteTo(output, options);\n\t\t\t\toutput.Write(\" : \");\n\t\t\t\ttype.WriteTo(output);\n\t\t\t}\n\t\t\tif (Arguments.Count > 0)\n\t\t\t\toutput.Write(')');\n\t\t}\n\n\t\tprotected override int GetChildCount()\n\t\t{\n\t\t\treturn Arguments.Count + 1;\n\t\t}\n\n\t\tprotected override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tif (index == 0)\n\t\t\t\treturn functionPointer;\n\t\t\treturn Arguments[index - 1];\n\t\t}\n\n\t\tprotected override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tif (index == 0)\n\t\t\t\tFunctionPointer = value;\n\t\t\telse\n\t\t\t\tArguments[index - 1] = value;\n\t\t}\n\n\t\tprotected override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tif (index == 0)\n\t\t\t\treturn FunctionPointerSlot;\n\t\t\telse\n\t\t\t\treturn ArgumentSlot;\n\t\t}\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\tvar flags = this.DirectFlags;\n\t\t\tflags |= functionPointer.Flags;\n\t\t\tforeach (var inst in Arguments)\n\t\t\t{\n\t\t\t\tflags |= inst.Flags;\n\t\t\t}\n\t\t\treturn flags;\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\n\t\tbool EqualSignature(CallIndirect other)\n\t\t{\n\t\t\tif (IsInstance != other.IsInstance)\n\t\t\t\treturn false;\n\t\t\tif (HasExplicitThis != other.HasExplicitThis)\n\t\t\t\treturn false;\n\t\t\treturn FunctionPointerType.Equals(other.FunctionPointerType);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/CallInstruction.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpublic abstract partial class CallInstruction : ILInstruction\n\t{\n\t\tpublic static CallInstruction Create(OpCode opCode, IMethod method)\n\t\t{\n\t\t\tswitch (opCode)\n\t\t\t{\n\t\t\t\tcase OpCode.Call:\n\t\t\t\t\treturn new Call(method);\n\t\t\t\tcase OpCode.CallVirt:\n\t\t\t\t\treturn new CallVirt(method);\n\t\t\t\tcase OpCode.NewObj:\n\t\t\t\t\treturn new NewObj(method);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentException(\"Not a valid call opcode\");\n\t\t\t}\n\t\t}\n\n\t\tpublic readonly IMethod Method;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether the call has the 'tail.' prefix.\n\t\t/// </summary>\n\t\tpublic bool IsTail;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the type specified in the 'constrained.' prefix.\n\t\t/// Returns null if no 'constrained.' prefix exists for this call.\n\t\t/// </summary>\n\t\tpublic IType? ConstrainedTo;\n\n\t\t/// <summary>\n\t\t/// Gets whether the IL stack was empty at the point of this call.\n\t\t/// (not counting the arguments/return value of the call itself)\n\t\t/// </summary>\n\t\tpublic bool ILStackWasEmpty;\n\n\t\tprotected CallInstruction(OpCode opCode, IMethod method) : base(opCode)\n\t\t{\n\t\t\tthis.Method = method ?? throw new ArgumentNullException(nameof(method));\n\t\t\tthis.Arguments = new InstructionCollection<ILInstruction>(this, 0);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this is an instance call (i.e. whether the first argument is the 'this' pointer).\n\t\t/// </summary>\n\t\tpublic bool IsInstanceCall {\n\t\t\tget { return !(Method.IsStatic || OpCode == OpCode.NewObj); }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the parameter for the argument with the specified index.\n\t\t/// Returns null for the <c>this</c> parameter.\n\t\t/// </summary>\n\t\tpublic IParameter? GetParameter(int argumentIndex)\n\t\t{\n\t\t\tint firstParamIndex = (Method.IsStatic || OpCode == OpCode.NewObj) ? 0 : 1;\n\t\t\tif (argumentIndex < firstParamIndex)\n\t\t\t{\n\t\t\t\treturn null; // asking for 'this' parameter\n\t\t\t}\n\t\t\treturn Method.Parameters[argumentIndex - firstParamIndex];\n\t\t}\n\n\t\tpublic override StackType ResultType {\n\t\t\tget {\n\t\t\t\tif (OpCode == OpCode.NewObj)\n\t\t\t\t\treturn Method.DeclaringType.GetStackType();\n\t\t\t\telse\n\t\t\t\t\treturn Method.ReturnType.GetStackType();\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the expected stack type for passing the this pointer in a method call.\n\t\t/// Returns StackType.Ref if constrainedTo is not null,\n\t\t/// StackType.O for reference types (this pointer passed as object reference),\n\t\t/// and StackType.Ref for type parameters and value types (this pointer passed as managed reference).\n\t\t/// \n\t\t/// Returns StackType.Unknown if the input type is unknown.\n\t\t/// </summary>\n\t\tinternal static StackType ExpectedTypeForThisPointer(IType declaringType, IType? constrainedTo)\n\t\t{\n\t\t\tif (constrainedTo != null)\n\t\t\t\treturn StackType.Ref;\n\t\t\tif (declaringType.Kind == TypeKind.TypeParameter)\n\t\t\t\treturn StackType.Ref;\n\t\t\tswitch (declaringType.IsReferenceType)\n\t\t\t{\n\t\t\t\tcase true:\n\t\t\t\t\treturn StackType.O;\n\t\t\t\tcase false:\n\t\t\t\t\treturn StackType.Ref;\n\t\t\t\tdefault:\n\t\t\t\t\treturn StackType.Unknown;\n\t\t\t}\n\t\t}\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tint firstArgument = (OpCode != OpCode.NewObj && !Method.IsStatic) ? 1 : 0;\n\t\t\tDebug.Assert(Method.Parameters.Count + firstArgument == Arguments.Count);\n\t\t\tif (firstArgument == 1)\n\t\t\t{\n\t\t\t\tif (!(Arguments[0].ResultType == ExpectedTypeForThisPointer(Method.DeclaringType, ConstrainedTo)))\n\t\t\t\t\tDebug.Fail($\"Stack type mismatch in 'this' argument in call to {Method.Name}()\");\n\t\t\t}\n\t\t\tfor (int i = 0; i < Method.Parameters.Count; ++i)\n\t\t\t{\n\t\t\t\tif (!(Arguments[firstArgument + i].ResultType == Method.Parameters[i].Type.GetStackType()))\n\t\t\t\t\tDebug.Fail($\"Stack type mismatch in parameter {i} in call to {Method.Name}()\");\n\t\t\t}\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\tif (ConstrainedTo != null)\n\t\t\t{\n\t\t\t\toutput.Write(\"constrained[\");\n\t\t\t\tConstrainedTo.WriteTo(output);\n\t\t\t\toutput.Write(\"].\");\n\t\t\t}\n\t\t\tif (IsTail)\n\t\t\t\toutput.Write(\"tail.\");\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\tMethod.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tfor (int i = 0; i < Arguments.Count; i++)\n\t\t\t{\n\t\t\t\tif (i > 0)\n\t\t\t\t\toutput.Write(\", \");\n\t\t\t\tArguments[i].WriteTo(output, options);\n\t\t\t}\n\t\t\toutput.Write(')');\n\t\t}\n\n\t\tprotected internal sealed override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tCallInstruction? o = other as CallInstruction;\n\t\t\treturn o != null && this.OpCode == o.OpCode && this.Method.Equals(o.Method) && this.IsTail == o.IsTail\n\t\t\t\t&& object.Equals(this.ConstrainedTo, o.ConstrainedTo)\n\t\t\t\t&& Patterns.ListMatch.DoMatch(this.Arguments, o.Arguments, ref match);\n\t\t}\n\t}\n\n\tpartial class Call : ILiftableInstruction\n\t{\n\t\t/// <summary>\n\t\t/// Calls can only be lifted when calling a lifted operator.\n\t\t/// Note that the semantics of such a lifted call depend on the type of operator:\n\t\t/// we follow C# semantics here.\n\t\t/// </summary>\n\t\tpublic bool IsLifted => Method is CSharp.Resolver.ILiftedOperator;\n\n\t\tpublic StackType UnderlyingResultType {\n\t\t\tget {\n\t\t\t\tif (Method is CSharp.Resolver.ILiftedOperator liftedOp)\n\t\t\t\t\treturn liftedOp.NonLiftedReturnType.GetStackType();\n\t\t\t\telse\n\t\t\t\t\treturn Method.ReturnType.GetStackType();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/Comp.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpublic enum ComparisonKind : byte\n\t{\n\t\tEquality,\n\t\tInequality,\n\t\tLessThan,\n\t\tLessThanOrEqual,\n\t\tGreaterThan,\n\t\tGreaterThanOrEqual\n\t}\n\n\tstatic class ComparisonKindExtensions\n\t{\n\t\tpublic static bool IsEqualityOrInequality(this ComparisonKind kind)\n\t\t{\n\t\t\treturn kind == ComparisonKind.Equality || kind == ComparisonKind.Inequality;\n\t\t}\n\n\t\tpublic static ComparisonKind Negate(this ComparisonKind kind)\n\t\t{\n\t\t\tswitch (kind)\n\t\t\t{\n\t\t\t\tcase ComparisonKind.Equality:\n\t\t\t\t\treturn ComparisonKind.Inequality;\n\t\t\t\tcase ComparisonKind.Inequality:\n\t\t\t\t\treturn ComparisonKind.Equality;\n\t\t\t\tcase ComparisonKind.LessThan:\n\t\t\t\t\treturn ComparisonKind.GreaterThanOrEqual;\n\t\t\t\tcase ComparisonKind.LessThanOrEqual:\n\t\t\t\t\treturn ComparisonKind.GreaterThan;\n\t\t\t\tcase ComparisonKind.GreaterThan:\n\t\t\t\t\treturn ComparisonKind.LessThanOrEqual;\n\t\t\t\tcase ComparisonKind.GreaterThanOrEqual:\n\t\t\t\t\treturn ComparisonKind.LessThan;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t}\n\t\t}\n\n\t\tpublic static BinaryOperatorType ToBinaryOperatorType(this ComparisonKind kind)\n\t\t{\n\t\t\tswitch (kind)\n\t\t\t{\n\t\t\t\tcase ComparisonKind.Equality:\n\t\t\t\t\treturn BinaryOperatorType.Equality;\n\t\t\t\tcase ComparisonKind.Inequality:\n\t\t\t\t\treturn BinaryOperatorType.InEquality;\n\t\t\t\tcase ComparisonKind.LessThan:\n\t\t\t\t\treturn BinaryOperatorType.LessThan;\n\t\t\t\tcase ComparisonKind.LessThanOrEqual:\n\t\t\t\t\treturn BinaryOperatorType.LessThanOrEqual;\n\t\t\t\tcase ComparisonKind.GreaterThan:\n\t\t\t\t\treturn BinaryOperatorType.GreaterThan;\n\t\t\t\tcase ComparisonKind.GreaterThanOrEqual:\n\t\t\t\t\treturn BinaryOperatorType.GreaterThanOrEqual;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t}\n\t\t}\n\n\t\tpublic static string GetToken(this ComparisonKind kind)\n\t\t{\n\t\t\treturn BinaryOperatorExpression.GetOperatorRole(kind.ToBinaryOperatorType()).Token;\n\t\t}\n\t}\n\n\tpublic enum ComparisonLiftingKind\n\t{\n\t\t/// <summary>\n\t\t/// Not a lifted comparison.\n\t\t/// </summary>\n\t\tNone,\n\t\t/// <summary>\n\t\t/// C#-style lifted comparison:\n\t\t/// * operands that have a ResultType != this.InputType are expected to return a value of\n\t\t///   type Nullable{T}, where T.GetStackType() == this.InputType.\n\t\t/// * if both operands are <c>null</c>, equality comparisons evaluate to 1, all other comparisons to 0.\n\t\t/// * if one operand is <c>null</c>, inequality comparisons evaluate to 1, all other comparisons to 0.\n\t\t/// * if neither operand is <c>null</c>, the underlying comparison is performed.\n\t\t/// \n\t\t/// Note that even though C#-style lifted comparisons set IsLifted=true,\n\t\t/// the ResultType remains I4 as with normal comparisons.\n\t\t/// </summary>\n\t\tCSharp,\n\t\t/// <summary>\n\t\t/// SQL-style lifted comparison: works like a lifted binary numeric instruction,\n\t\t/// that is, if any input operand is <c>null</c>, the comparison evaluates to <c>null</c>.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This lifting kind is currently only used for operator! on bool?.\n\t\t/// </remarks>\n\t\tThreeValuedLogic\n\t}\n\n\tpartial class Comp : ILiftableInstruction\n\t{\n\t\tComparisonKind kind;\n\n\t\tpublic ComparisonKind Kind {\n\t\t\tget { return kind; }\n\t\t\tset {\n\t\t\t\tkind = value;\n\t\t\t\tMakeDirty();\n\t\t\t}\n\t\t}\n\n\t\tpublic ComparisonLiftingKind LiftingKind;\n\n\t\t/// <summary>\n\t\t/// Gets the stack type of the comparison inputs.\n\t\t/// For lifted comparisons, this is the underlying input type.\n\t\t/// </summary>\n\t\tpublic StackType InputType;\n\n\t\t/// <summary>\n\t\t/// If this is an integer comparison, specifies the sign used to interpret the integers.\n\t\t/// </summary>\n\t\tpublic readonly Sign Sign;\n\n\t\tpublic Comp(ComparisonKind kind, Sign sign, ILInstruction left, ILInstruction right) : base(OpCode.Comp, left, right)\n\t\t{\n\t\t\tthis.kind = kind;\n\t\t\tthis.LiftingKind = ComparisonLiftingKind.None;\n\t\t\tthis.InputType = left.ResultType;\n\t\t\tthis.Sign = sign;\n\t\t\tDebug.Assert(left.ResultType == right.ResultType);\n\t\t}\n\n\t\tpublic Comp(ComparisonKind kind, ComparisonLiftingKind lifting, StackType inputType, Sign sign, ILInstruction left, ILInstruction right) : base(OpCode.Comp, left, right)\n\t\t{\n\t\t\tthis.kind = kind;\n\t\t\tthis.LiftingKind = lifting;\n\t\t\tthis.InputType = inputType;\n\t\t\tthis.Sign = sign;\n\t\t}\n\n\t\tpublic override StackType ResultType => LiftingKind == ComparisonLiftingKind.ThreeValuedLogic ? StackType.O : StackType.I4;\n\t\tpublic bool IsLifted => LiftingKind != ComparisonLiftingKind.None;\n\t\tpublic StackType UnderlyingResultType => StackType.I4;\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tif (LiftingKind == ComparisonLiftingKind.None)\n\t\t\t{\n\t\t\t\tDebug.Assert(Left.ResultType == InputType);\n\t\t\t\tDebug.Assert(Right.ResultType == InputType);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDebug.Assert(Left.ResultType == InputType || Left.ResultType == StackType.O);\n\t\t\t\tDebug.Assert(Right.ResultType == InputType || Right.ResultType == StackType.O);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\tif (options.UseLogicOperationSugar && MatchLogicNot(out var arg))\n\t\t\t{\n\t\t\t\toutput.Write(\"logic.not(\");\n\t\t\t\targ.WriteTo(output, options);\n\t\t\t\toutput.Write(')');\n\t\t\t\treturn;\n\t\t\t}\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write('.');\n\t\t\toutput.Write(InputType.ToString().ToLower());\n\t\t\tswitch (Sign)\n\t\t\t{\n\t\t\t\tcase Sign.Signed:\n\t\t\t\t\toutput.Write(\".signed\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase Sign.Unsigned:\n\t\t\t\t\toutput.Write(\".unsigned\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tswitch (LiftingKind)\n\t\t\t{\n\t\t\t\tcase ComparisonLiftingKind.CSharp:\n\t\t\t\t\toutput.Write(\".lifted[C#]\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase ComparisonLiftingKind.ThreeValuedLogic:\n\t\t\t\t\toutput.Write(\".lifted[3VL]\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\toutput.Write('(');\n\t\t\tLeft.WriteTo(output, options);\n\t\t\toutput.Write(' ');\n\t\t\toutput.Write(Kind.GetToken());\n\t\t\toutput.Write(' ');\n\t\t\tRight.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\n\t\tpublic static Comp LogicNot(ILInstruction arg)\n\t\t{\n\t\t\treturn new Comp(ComparisonKind.Equality, Sign.None, arg, new LdcI4(0));\n\t\t}\n\n\t\tpublic static Comp LogicNot(ILInstruction arg, bool isLifted)\n\t\t{\n\t\t\tvar liftingKind = isLifted ? ComparisonLiftingKind.ThreeValuedLogic : ComparisonLiftingKind.None;\n\t\t\treturn new Comp(ComparisonKind.Equality, liftingKind, StackType.I4, Sign.None, arg, new LdcI4(0));\n\t\t}\n\n\t\tinternal override bool CanInlineIntoSlot(int childIndex, ILInstruction expressionBeingMoved)\n\t\t{\n\t\t\t// ExpressionBuilder translates comp.o(a op b) for op not in (==, !=) into\n\t\t\t// Unsafe.As(ref a) op Unsafe.As(ref b), which requires that a and b are variables\n\t\t\t// and not expressions. Returning false in those cases prevents inlining.\n\t\t\t// However if one of the arguments is LdNull, then we don't need the Unsafe.As trickery, and can always inline.\n\t\t\tif (kind.IsEqualityOrInequality() || this.InputType != StackType.O)\n\t\t\t{\n\t\t\t\t// OK, won't need Unsafe.As.\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (expressionBeingMoved is LdLoc || expressionBeingMoved.MatchLdsFld(out _))\n\t\t\t{\n\t\t\t\t// OK, can use variable/field name with Unsafe.As(ref x)\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (Sign != Sign.Signed && (expressionBeingMoved is LdNull || Left is LdNull || Right is LdNull))\n\t\t\t{\n\t\t\t\t// OK, this is the \"compare with null\" special case that doesn't need Unsafe.As()\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs",
    "content": "#nullable enable\n// Copyright (c) 2016 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\nusing System.Linq.Expressions;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpublic enum CompoundEvalMode : byte\n\t{\n\t\t/// <summary>\n\t\t/// The compound.assign instruction will evaluate to the old value.\n\t\t/// This mode is used only for post-increment/decrement.\n\t\t/// </summary>\n\t\tEvaluatesToOldValue,\n\t\t/// <summary>\n\t\t/// The compound.assign instruction will evaluate to the new value.\n\t\t/// This mode is used for compound assignments and pre-increment/decrement.\n\t\t/// </summary>\n\t\tEvaluatesToNewValue\n\t}\n\n\tpublic enum CompoundTargetKind : byte\n\t{\n\t\t/// <summary>\n\t\t/// The target is an instruction computing an address,\n\t\t/// and the compound.assign will implicitly load/store from/to that address.\n\t\t/// </summary>\n\t\tAddress,\n\t\t/// <summary>\n\t\t/// The Target must be a call to a property getter,\n\t\t/// and the compound.assign will implicitly call the corresponding property setter.\n\t\t/// </summary>\n\t\tProperty,\n\t\t/// <summary>\n\t\t/// The target is a dynamic call.\n\t\t/// </summary>\n\t\tDynamic\n\t}\n\n\tpublic abstract partial class CompoundAssignmentInstruction : ILInstruction\n\t{\n\t\tpublic readonly CompoundEvalMode EvalMode;\n\n\t\t/// <summary>\n\t\t/// If TargetIsProperty is true, the Target must be a call to a property getter,\n\t\t/// and the compound.assign will implicitly call the corresponding property setter.\n\t\t/// Otherwise, the Target can be any instruction that evaluates to an address,\n\t\t/// and the compound.assign will implicit load and store from/to that address.\n\t\t/// </summary>\n\t\tpublic readonly CompoundTargetKind TargetKind;\n\n\t\tpublic CompoundAssignmentInstruction(OpCode opCode, CompoundEvalMode evalMode, ILInstruction target, CompoundTargetKind targetKind, ILInstruction value)\n\t\t\t: base(opCode)\n\t\t{\n\t\t\tthis.EvalMode = evalMode;\n\t\t\tthis.Target = target;\n\t\t\tthis.TargetKind = targetKind;\n\t\t\tthis.Value = value;\n\t\t\tCheckValidTarget();\n\t\t}\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tCheckValidTarget();\n\t\t}\n\n\t\t[Conditional(\"DEBUG\")]\n\t\tvoid CheckValidTarget()\n\t\t{\n\t\t\tswitch (TargetKind)\n\t\t\t{\n\t\t\t\tcase CompoundTargetKind.Address:\n\t\t\t\t\tDebug.Assert(target.ResultType == StackType.Ref || target.ResultType == StackType.I);\n\t\t\t\t\tbreak;\n\t\t\t\tcase CompoundTargetKind.Property:\n\t\t\t\t\tDebug.Assert(target.OpCode == OpCode.Call || target.OpCode == OpCode.CallVirt);\n\t\t\t\t\tvar owner = ((CallInstruction)target).Method.AccessorOwner as IProperty;\n\t\t\t\t\tDebug.Assert(owner != null && owner.CanSet);\n\t\t\t\t\tbreak;\n\t\t\t\tcase CompoundTargetKind.Dynamic:\n\t\t\t\t\tDebug.Assert(target.OpCode == OpCode.DynamicGetMemberInstruction || target.OpCode == OpCode.DynamicGetIndexInstruction);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tprotected void WriteSuffix(ITextOutput output)\n\t\t{\n\t\t\tswitch (TargetKind)\n\t\t\t{\n\t\t\t\tcase CompoundTargetKind.Address:\n\t\t\t\t\toutput.Write(\".address\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase CompoundTargetKind.Property:\n\t\t\t\t\toutput.Write(\".property\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tswitch (EvalMode)\n\t\t\t{\n\t\t\t\tcase CompoundEvalMode.EvaluatesToNewValue:\n\t\t\t\t\toutput.Write(\".new\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase CompoundEvalMode.EvaluatesToOldValue:\n\t\t\t\t\toutput.Write(\".old\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic partial class NumericCompoundAssign : CompoundAssignmentInstruction, ILiftableInstruction\n\t{\n\t\t/// <summary>\n\t\t/// Gets whether the instruction checks for overflow.\n\t\t/// </summary>\n\t\tpublic readonly bool CheckForOverflow;\n\n\t\t/// <summary>\n\t\t/// For integer operations that depend on the sign, specifies whether the operation\n\t\t/// is signed or unsigned.\n\t\t/// For instructions that produce the same result for either sign, returns Sign.None.\n\t\t/// </summary>\n\t\tpublic readonly Sign Sign;\n\n\t\tpublic readonly StackType LeftInputType;\n\t\tpublic readonly StackType RightInputType;\n\t\tpublic StackType UnderlyingResultType { get; }\n\n\t\t/// <summary>\n\t\t/// The operator used by this assignment operator instruction.\n\t\t/// </summary>\n\t\tpublic readonly BinaryNumericOperator Operator;\n\n\t\tpublic bool IsLifted { get; }\n\n\t\tpublic NumericCompoundAssign(BinaryNumericInstruction binary, ILInstruction target,\n\t\t\tCompoundTargetKind targetKind, ILInstruction value, IType type, CompoundEvalMode evalMode)\n\t\t\t: base(OpCode.NumericCompoundAssign, evalMode, target, targetKind, value)\n\t\t{\n\t\t\tDebug.Assert(IsBinaryCompatibleWithType(binary, type, null));\n\t\t\tthis.CheckForOverflow = binary.CheckForOverflow;\n\t\t\tthis.Sign = binary.Sign;\n\t\t\tthis.LeftInputType = binary.LeftInputType;\n\t\t\tthis.RightInputType = binary.RightInputType;\n\t\t\tthis.UnderlyingResultType = binary.UnderlyingResultType;\n\t\t\tthis.Operator = binary.Operator;\n\t\t\tthis.IsLifted = binary.IsLifted;\n\t\t\tthis.type = type;\n\t\t\tthis.AddILRange(binary);\n\t\t\tDebug.Assert(evalMode == CompoundEvalMode.EvaluatesToNewValue || (Operator == BinaryNumericOperator.Add || Operator == BinaryNumericOperator.Sub));\n\t\t\tDebug.Assert(this.ResultType == (IsLifted ? StackType.O : UnderlyingResultType));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the specific binary instruction is compatible with a compound operation on the specified type.\n\t\t/// </summary>\n\t\tinternal static bool IsBinaryCompatibleWithType(BinaryNumericInstruction binary, IType type, DecompilerSettings? settings)\n\t\t{\n\t\t\tif (binary.IsLifted)\n\t\t\t{\n\t\t\t\tif (!NullableType.IsNullable(type))\n\t\t\t\t\treturn false;\n\t\t\t\ttype = NullableType.GetUnderlyingType(type);\n\t\t\t}\n\t\t\tif (type.Kind == TypeKind.Unknown)\n\t\t\t{\n\t\t\t\treturn false; // avoid introducing a potentially-incorrect compound assignment\n\t\t\t}\n\t\t\telse if (type.Kind == TypeKind.Enum)\n\t\t\t{\n\t\t\t\tswitch (binary.Operator)\n\t\t\t\t{\n\t\t\t\t\tcase BinaryNumericOperator.Add:\n\t\t\t\t\tcase BinaryNumericOperator.Sub:\n\t\t\t\t\tcase BinaryNumericOperator.BitAnd:\n\t\t\t\t\tcase BinaryNumericOperator.BitOr:\n\t\t\t\t\tcase BinaryNumericOperator.BitXor:\n\t\t\t\t\t\tbreak; // OK\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false; // operator not supported on enum types\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (type.Kind == TypeKind.Pointer)\n\t\t\t{\n\t\t\t\tswitch (binary.Operator)\n\t\t\t\t{\n\t\t\t\t\tcase BinaryNumericOperator.Add:\n\t\t\t\t\tcase BinaryNumericOperator.Sub:\n\t\t\t\t\t\t// ensure that the byte offset is a multiple of the pointer size\n\t\t\t\t\t\treturn PointerArithmeticOffset.Detect(\n\t\t\t\t\t\t\tbinary.Right,\n\t\t\t\t\t\t\t((PointerType)type).ElementType,\n\t\t\t\t\t\t\tcheckForOverflow: binary.CheckForOverflow\n\t\t\t\t\t\t) != null;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false; // operator not supported on pointer types\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ((type.IsKnownType(KnownTypeCode.IntPtr) || type.IsKnownType(KnownTypeCode.UIntPtr)) && type.Kind is not TypeKind.NInt or TypeKind.NUInt)\n\t\t\t{\n\t\t\t\t// If the LHS is C# 9 IntPtr (but not nint or C# 11 IntPtr):\n\t\t\t\t// \"target.intptr *= 2;\" is compiler error, but\n\t\t\t\t// \"target.intptr *= (nint)2;\" works\n\t\t\t\tif (settings != null && !settings.NativeIntegers)\n\t\t\t\t{\n\t\t\t\t\t// But if native integers are not available, we cannot use compound assignment.\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t// The trick with casting the RHS to n(u)int doesn't work for shifts:\n\t\t\t\tswitch (binary.Operator)\n\t\t\t\t{\n\t\t\t\t\tcase BinaryNumericOperator.ShiftLeft:\n\t\t\t\t\tcase BinaryNumericOperator.ShiftRight:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (binary.Sign != Sign.None)\n\t\t\t{\n\t\t\t\tbool signMismatchAllowed = (binary.Sign == Sign.Unsigned && binary.Operator == BinaryNumericOperator.ShiftRight && (settings == null || settings.UnsignedRightShift));\n\t\t\t\tif (type.IsCSharpSmallIntegerType())\n\t\t\t\t{\n\t\t\t\t\t// C# will use numeric promotion to int, binary op must be signed\n\t\t\t\t\tif (binary.Sign != Sign.Signed && !signMismatchAllowed)\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// C# will use sign from type; except for right shift with C# 11 >>> operator.\n\t\t\t\t\tif (type.GetSign() != binary.Sign && !signMismatchAllowed)\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Can't transform if the RHS value would be need to be truncated for the LHS type.\n\t\t\tif (Transforms.TransformAssignment.IsImplicitTruncation(binary.Right, type, null, binary.IsLifted))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\tvar flags = Target.Flags | Value.Flags | InstructionFlags.SideEffect;\n\t\t\tif (CheckForOverflow || (Operator == BinaryNumericOperator.Div || Operator == BinaryNumericOperator.Rem))\n\t\t\t\tflags |= InstructionFlags.MayThrow;\n\t\t\treturn flags;\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\tvar flags = InstructionFlags.SideEffect;\n\t\t\t\tif (CheckForOverflow || (Operator == BinaryNumericOperator.Div || Operator == BinaryNumericOperator.Rem))\n\t\t\t\t\tflags |= InstructionFlags.MayThrow;\n\t\t\t\treturn flags;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(\".\" + BinaryNumericInstruction.GetOperatorName(Operator));\n\t\t\tif (CheckForOverflow)\n\t\t\t{\n\t\t\t\toutput.Write(\".ovf\");\n\t\t\t}\n\t\t\tif (Sign == Sign.Unsigned)\n\t\t\t{\n\t\t\t\toutput.Write(\".unsigned\");\n\t\t\t}\n\t\t\telse if (Sign == Sign.Signed)\n\t\t\t{\n\t\t\t\toutput.Write(\".signed\");\n\t\t\t}\n\t\t\toutput.Write('.');\n\t\t\toutput.Write(UnderlyingResultType.ToString().ToLowerInvariant());\n\t\t\tif (IsLifted)\n\t\t\t{\n\t\t\t\toutput.Write(\".lifted\");\n\t\t\t}\n\t\t\tbase.WriteSuffix(output);\n\t\t\toutput.Write('(');\n\t\t\tTarget.WriteTo(output, options);\n\t\t\toutput.Write(\", \");\n\t\t\tValue.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t}\n\n\tpublic partial class UserDefinedCompoundAssign : CompoundAssignmentInstruction\n\t{\n\t\tpublic readonly IMethod Method;\n\t\tpublic bool IsLifted => false; // TODO: implement lifted user-defined compound assignments\n\n\t\tpublic UserDefinedCompoundAssign(IMethod method, CompoundEvalMode evalMode,\n\t\t\tILInstruction target, CompoundTargetKind targetKind, ILInstruction value)\n\t\t\t: base(OpCode.UserDefinedCompoundAssign, evalMode, target, targetKind, value)\n\t\t{\n\t\t\tthis.Method = method;\n\t\t\tDebug.Assert(Method.IsOperator || IsStringConcat(method));\n\t\t\tDebug.Assert(evalMode == CompoundEvalMode.EvaluatesToNewValue || IsIncrementOrDecrement(method));\n\t\t}\n\n\t\tpublic static bool IsIncrementOrDecrement(IMethod method, DecompilerSettings? settings = null)\n\t\t{\n\t\t\tif (!(method.IsOperator && method.IsStatic))\n\t\t\t\treturn false;\n\t\t\tif (method.Name is \"op_Increment\" or \"op_Decrement\")\n\t\t\t\treturn true;\n\t\t\tif (method.Name is \"op_CheckedIncrement\" or \"op_CheckedDecrement\")\n\t\t\t\treturn settings?.CheckedOperators ?? true;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool IsStringConcat(IMethod method)\n\t\t{\n\t\t\treturn method.Name == \"Concat\" && method.IsStatic && method.DeclaringType.IsKnownType(KnownTypeCode.String);\n\t\t}\n\n\t\tpublic override StackType ResultType => Method.ReturnType.GetStackType();\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tbase.WriteSuffix(output);\n\t\t\toutput.Write(' ');\n\t\t\tMethod.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tthis.Target.WriteTo(output, options);\n\t\t\toutput.Write(\", \");\n\t\t\tthis.Value.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t}\n\n\tpublic partial class DynamicCompoundAssign : CompoundAssignmentInstruction\n\t{\n\t\tpublic ExpressionType Operation { get; }\n\t\tpublic CSharpArgumentInfo TargetArgumentInfo { get; }\n\t\tpublic CSharpArgumentInfo ValueArgumentInfo { get; }\n\t\tpublic CSharpBinderFlags BinderFlags { get; }\n\n\t\tpublic DynamicCompoundAssign(ExpressionType op, CSharpBinderFlags binderFlags,\n\t\t\tILInstruction target, CSharpArgumentInfo targetArgumentInfo,\n\t\t\tILInstruction value, CSharpArgumentInfo valueArgumentInfo,\n\t\t\tCompoundTargetKind targetKind = CompoundTargetKind.Dynamic)\n\t\t\t: base(OpCode.DynamicCompoundAssign, CompoundEvalModeFromOperation(op), target, targetKind, value)\n\t\t{\n\t\t\tif (!IsExpressionTypeSupported(op))\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(op));\n\t\t\tthis.BinderFlags = binderFlags;\n\t\t\tthis.Operation = op;\n\t\t\tthis.TargetArgumentInfo = targetArgumentInfo;\n\t\t\tthis.ValueArgumentInfo = valueArgumentInfo;\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(\".\" + Operation.ToString().ToLower());\n\t\t\tDynamicInstruction.WriteBinderFlags(BinderFlags, output, options);\n\t\t\tbase.WriteSuffix(output);\n\t\t\toutput.Write(' ');\n\t\t\tDynamicInstruction.WriteArgumentList(output, options, (Target, TargetArgumentInfo), (Value, ValueArgumentInfo));\n\t\t}\n\n\t\tinternal static bool IsExpressionTypeSupported(ExpressionType type)\n\t\t{\n\t\t\treturn type == ExpressionType.AddAssign\n\t\t\t\t|| type == ExpressionType.AddAssignChecked\n\t\t\t\t|| type == ExpressionType.AndAssign\n\t\t\t\t|| type == ExpressionType.DivideAssign\n\t\t\t\t|| type == ExpressionType.ExclusiveOrAssign\n\t\t\t\t|| type == ExpressionType.LeftShiftAssign\n\t\t\t\t|| type == ExpressionType.ModuloAssign\n\t\t\t\t|| type == ExpressionType.MultiplyAssign\n\t\t\t\t|| type == ExpressionType.MultiplyAssignChecked\n\t\t\t\t|| type == ExpressionType.OrAssign\n\t\t\t\t|| type == ExpressionType.PostDecrementAssign\n\t\t\t\t|| type == ExpressionType.PostIncrementAssign\n\t\t\t\t|| type == ExpressionType.PreDecrementAssign\n\t\t\t\t|| type == ExpressionType.PreIncrementAssign\n\t\t\t\t|| type == ExpressionType.RightShiftAssign\n\t\t\t\t|| type == ExpressionType.SubtractAssign\n\t\t\t\t|| type == ExpressionType.SubtractAssignChecked;\n\t\t}\n\n\t\tstatic CompoundEvalMode CompoundEvalModeFromOperation(ExpressionType op)\n\t\t{\n\t\t\tswitch (op)\n\t\t\t{\n\t\t\t\tcase ExpressionType.PostIncrementAssign:\n\t\t\t\tcase ExpressionType.PostDecrementAssign:\n\t\t\t\t\treturn CompoundEvalMode.EvaluatesToOldValue;\n\t\t\t\tdefault:\n\t\t\t\t\treturn CompoundEvalMode.EvaluatesToNewValue;\n\t\t\t}\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/Conv.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// Semantic meaning of a <c>Conv</c> instruction.\n\t/// </summary>\n\tpublic enum ConversionKind : byte\n\t{\n\t\t/// <summary>\n\t\t/// Invalid conversion.\n\t\t/// </summary>\n\t\tInvalid,\n\t\t/// <summary>\n\t\t/// Conversion between two types of same size.\n\t\t/// Can be used to change the sign of integer types, which may involve overflow-checking.\n\t\t/// </summary>\n\t\tNop,\n\t\t/// <summary>\n\t\t/// Integer-to-float conversion.\n\t\t/// Uses <c>InputSign</c> to decide whether the integer should be treated as signed or unsigned.\n\t\t/// </summary>\n\t\tIntToFloat,\n\t\t/// <summary>\n\t\t/// Float-to-integer conversion.\n\t\t/// Truncates toward zero; may perform overflow-checking.\n\t\t/// </summary>\n\t\tFloatToInt,\n\t\t/// <summary>\n\t\t/// Converts from the current precision available on the evaluation stack to the precision specified by\n\t\t/// the <c>TargetType</c>.\n\t\t/// Uses \"round-to-nearest\" mode if the precision is reduced.\n\t\t/// </summary>\n\t\tFloatPrecisionChange,\n\t\t/// <summary>\n\t\t/// Conversion of integer type to larger signed integer type.\n\t\t/// May involve overflow checking (when converting from U4 to I on 32-bit).\n\t\t/// </summary>\n\t\tSignExtend,\n\t\t/// <summary>\n\t\t/// Conversion of integer type to larger unsigned integer type.\n\t\t/// May involve overflow checking (when converting from a signed type).\n\t\t/// </summary>\n\t\tZeroExtend,\n\t\t/// <summary>\n\t\t/// Conversion to smaller integer type.\n\t\t/// \n\t\t/// May involve overflow checking.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// If the target type is smaller than the minimum stack width of 4 bytes,\n\t\t/// then the result of the conversion is zero extended (if the target type is unsigned)\n\t\t/// or sign-extended (if the target type is signed).\n\t\t/// </remarks>\n\t\tTruncate,\n\t\t/// <summary>\n\t\t/// Used to convert managed references/objects to unmanaged pointers.\n\t\t/// </summary>\n\t\tStopGCTracking,\n\t\t/// <summary>\n\t\t/// Used to convert unmanaged pointers to managed references.\n\t\t/// </summary>\n\t\tStartGCTracking,\n\t\t/// <summary>\n\t\t/// Converts from an object reference (O) to an interior pointer (Ref) pointing to the start of the object.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// C++/CLI emits \"ldarg.1; stloc.0\" where arg1 is a string and loc0 is \"ref byte\" (e.g. as part of the PtrToStringChars codegen);\n\t\t/// we represent this type conversion explicitly in the ILAst.\n\t\t/// </remarks>\n\t\tObjectInterior\n\t}\n\n\tpartial class Conv : UnaryInstruction, ILiftableInstruction\n\t{\n\t\t/// <summary>\n\t\t/// Gets the conversion kind.\n\t\t/// </summary>\n\t\tpublic readonly ConversionKind Kind;\n\n\t\t/// <summary>\n\t\t/// Gets whether the conversion performs overflow-checking.\n\t\t/// </summary>\n\t\tpublic readonly bool CheckForOverflow;\n\n\t\t/// <summary>\n\t\t/// Gets whether this conversion is a lifted nullable conversion.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// A lifted conversion expects its argument to be a value of type Nullable{T}, where\n\t\t/// T.GetStackType() == conv.InputType.\n\t\t/// If the value is non-null:\n\t\t///  * it is sign/zero-extended to InputType (based on T's sign)\n\t\t///  * the underlying conversion is performed\n\t\t///  * the result is wrapped in a Nullable{TargetType}.\n\t\t/// If the value is null, the conversion evaluates to default(TargetType?).\n\t\t/// (this result type is underspecified, since there may be multiple C# types for the TargetType)\n\t\t/// </remarks>\n\t\tpublic bool IsLifted { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the stack type of the input type.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// For non-lifted conversions, this is equal to <c>Argument.ResultType</c>.\n\t\t/// For lifted conversions, corresponds to the underlying type of the argument.\n\t\t/// </remarks>\n\t\tpublic readonly StackType InputType;\n\n\t\t/// <summary>\n\t\t/// Gets the sign of the input type.\n\t\t/// \n\t\t/// For conversions to integer types, the input Sign is set iff overflow-checking is enabled.\n\t\t/// For conversions to floating-point types, the input sign is always set.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// The input sign does not have any effect on whether the conversion zero-extends or sign-extends;\n\t\t/// that is purely determined by the <c>TargetType</c>.\n\t\t/// </remarks>\n\t\tpublic readonly Sign InputSign;\n\n\t\t/// <summary>\n\t\t/// The target type of the conversion.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// For lifted conversions, corresponds to the underlying target type.\n\t\t/// \n\t\t/// Target type == PrimitiveType.None can happen for implicit conversions to O in invalid IL.\n\t\t/// </remarks>\n\t\tpublic readonly PrimitiveType TargetType;\n\n\t\tpublic Conv(ILInstruction argument, PrimitiveType targetType, bool checkForOverflow, Sign inputSign)\n\t\t\t: this(argument, argument.ResultType, inputSign, targetType, checkForOverflow)\n\t\t{\n\t\t}\n\n\t\tpublic Conv(ILInstruction argument, StackType inputType, Sign inputSign, PrimitiveType targetType, bool checkForOverflow, bool isLifted = false)\n\t\t\t: base(OpCode.Conv, argument)\n\t\t{\n\t\t\tbool needsSign = checkForOverflow || (!inputType.IsFloatType() && targetType.IsFloatType());\n\t\t\tDebug.Assert(!(needsSign && inputSign == Sign.None));\n\t\t\tthis.InputSign = needsSign ? inputSign : Sign.None;\n\t\t\tthis.InputType = inputType;\n\t\t\tthis.TargetType = targetType;\n\t\t\tthis.CheckForOverflow = checkForOverflow;\n\t\t\tthis.Kind = GetConversionKind(targetType, this.InputType, this.InputSign);\n\t\t\t// Debug.Assert(Kind != ConversionKind.Invalid); // invalid conversion can happen with invalid IL/missing references\n\t\t\tthis.IsLifted = isLifted;\n\t\t}\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\t// Debug.Assert(Kind != ConversionKind.Invalid); // invalid conversion can happen with invalid IL/missing references\n\t\t\tDebug.Assert(Argument.ResultType == (IsLifted ? StackType.O : InputType));\n\t\t\tDebug.Assert(!(IsLifted && Kind == ConversionKind.StopGCTracking));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Implements Ecma-335 Table 8: Conversion Operators.\n\t\t/// </summary>\n\t\tstatic ConversionKind GetConversionKind(PrimitiveType targetType, StackType inputType, Sign inputSign)\n\t\t{\n\t\t\tswitch (targetType)\n\t\t\t{\n\t\t\t\tcase PrimitiveType.I1:\n\t\t\t\tcase PrimitiveType.I2:\n\t\t\t\tcase PrimitiveType.U1:\n\t\t\t\tcase PrimitiveType.U2:\n\t\t\t\t\tswitch (inputType)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase StackType.I4:\n\t\t\t\t\t\tcase StackType.I8:\n\t\t\t\t\t\tcase StackType.I:\n\t\t\t\t\t\t\treturn ConversionKind.Truncate;\n\t\t\t\t\t\tcase StackType.F4:\n\t\t\t\t\t\tcase StackType.F8:\n\t\t\t\t\t\t\treturn ConversionKind.FloatToInt;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn ConversionKind.Invalid;\n\t\t\t\t\t}\n\t\t\t\tcase PrimitiveType.I4:\n\t\t\t\tcase PrimitiveType.U4:\n\t\t\t\t\tswitch (inputType)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase StackType.I4:\n\t\t\t\t\t\t\treturn ConversionKind.Nop;\n\t\t\t\t\t\tcase StackType.I:\n\t\t\t\t\t\tcase StackType.I8:\n\t\t\t\t\t\t\treturn ConversionKind.Truncate;\n\t\t\t\t\t\tcase StackType.F4:\n\t\t\t\t\t\tcase StackType.F8:\n\t\t\t\t\t\t\treturn ConversionKind.FloatToInt;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn ConversionKind.Invalid;\n\t\t\t\t\t}\n\t\t\t\tcase PrimitiveType.I8:\n\t\t\t\tcase PrimitiveType.U8:\n\t\t\t\t\tswitch (inputType)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase StackType.I4:\n\t\t\t\t\t\tcase StackType.I:\n\t\t\t\t\t\t\tif (inputSign == Sign.None)\n\t\t\t\t\t\t\t\treturn targetType == PrimitiveType.I8 ? ConversionKind.SignExtend : ConversionKind.ZeroExtend;\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\treturn inputSign == Sign.Signed ? ConversionKind.SignExtend : ConversionKind.ZeroExtend;\n\t\t\t\t\t\tcase StackType.I8:\n\t\t\t\t\t\t\treturn ConversionKind.Nop;\n\t\t\t\t\t\tcase StackType.F4:\n\t\t\t\t\t\tcase StackType.F8:\n\t\t\t\t\t\t\treturn ConversionKind.FloatToInt;\n\t\t\t\t\t\tcase StackType.Ref:\n\t\t\t\t\t\tcase StackType.O:\n\t\t\t\t\t\t\treturn ConversionKind.StopGCTracking;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn ConversionKind.Invalid;\n\t\t\t\t\t}\n\t\t\t\tcase PrimitiveType.I:\n\t\t\t\tcase PrimitiveType.U:\n\t\t\t\t\tswitch (inputType)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase StackType.I4:\n\t\t\t\t\t\t\tif (inputSign == Sign.None)\n\t\t\t\t\t\t\t\treturn targetType == PrimitiveType.I ? ConversionKind.SignExtend : ConversionKind.ZeroExtend;\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\treturn inputSign == Sign.Signed ? ConversionKind.SignExtend : ConversionKind.ZeroExtend;\n\t\t\t\t\t\tcase StackType.I:\n\t\t\t\t\t\t\treturn ConversionKind.Nop;\n\t\t\t\t\t\tcase StackType.I8:\n\t\t\t\t\t\t\treturn ConversionKind.Truncate;\n\t\t\t\t\t\tcase StackType.F4:\n\t\t\t\t\t\tcase StackType.F8:\n\t\t\t\t\t\t\treturn ConversionKind.FloatToInt;\n\t\t\t\t\t\tcase StackType.Ref:\n\t\t\t\t\t\tcase StackType.O:\n\t\t\t\t\t\t\treturn ConversionKind.StopGCTracking;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn ConversionKind.Invalid;\n\t\t\t\t\t}\n\t\t\t\tcase PrimitiveType.R4:\n\t\t\t\t\tswitch (inputType)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase StackType.I4:\n\t\t\t\t\t\tcase StackType.I:\n\t\t\t\t\t\tcase StackType.I8:\n\t\t\t\t\t\t\treturn ConversionKind.IntToFloat;\n\t\t\t\t\t\tcase StackType.F4:\n\t\t\t\t\t\t\treturn ConversionKind.Nop;\n\t\t\t\t\t\tcase StackType.F8:\n\t\t\t\t\t\t\treturn ConversionKind.FloatPrecisionChange;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn ConversionKind.Invalid;\n\t\t\t\t\t}\n\t\t\t\tcase PrimitiveType.R:\n\t\t\t\tcase PrimitiveType.R8:\n\t\t\t\t\tswitch (inputType)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase StackType.I4:\n\t\t\t\t\t\tcase StackType.I:\n\t\t\t\t\t\tcase StackType.I8:\n\t\t\t\t\t\t\treturn ConversionKind.IntToFloat;\n\t\t\t\t\t\tcase StackType.F4:\n\t\t\t\t\t\t\treturn ConversionKind.FloatPrecisionChange;\n\t\t\t\t\t\tcase StackType.F8:\n\t\t\t\t\t\t\treturn ConversionKind.Nop;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn ConversionKind.Invalid;\n\t\t\t\t\t}\n\t\t\t\tcase PrimitiveType.Ref:\n\t\t\t\t\t// There's no \"conv.ref\" in IL, but IL allows these conversions implicitly,\n\t\t\t\t\t// whereas we represent them explicitly in the ILAst.\n\t\t\t\t\tswitch (inputType)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase StackType.I4:\n\t\t\t\t\t\tcase StackType.I:\n\t\t\t\t\t\tcase StackType.I8:\n\t\t\t\t\t\t\treturn ConversionKind.StartGCTracking;\n\t\t\t\t\t\tcase StackType.O:\n\t\t\t\t\t\t\treturn ConversionKind.ObjectInterior;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn ConversionKind.Invalid;\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\treturn ConversionKind.Invalid;\n\t\t\t}\n\t\t}\n\n\t\tpublic override StackType ResultType {\n\t\t\tget => IsLifted ? StackType.O : TargetType.GetStackType();\n\t\t}\n\n\t\tpublic StackType UnderlyingResultType {\n\t\t\tget => TargetType.GetStackType();\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tif (CheckForOverflow)\n\t\t\t{\n\t\t\t\toutput.Write(\".ovf\");\n\t\t\t}\n\t\t\tif (InputSign == Sign.Unsigned)\n\t\t\t{\n\t\t\t\toutput.Write(\".unsigned\");\n\t\t\t}\n\t\t\telse if (InputSign == Sign.Signed)\n\t\t\t{\n\t\t\t\toutput.Write(\".signed\");\n\t\t\t}\n\t\t\tif (IsLifted)\n\t\t\t{\n\t\t\t\toutput.Write(\".lifted\");\n\t\t\t}\n\t\t\toutput.Write(' ');\n\t\t\toutput.Write(InputType);\n\t\t\toutput.Write(\"->\");\n\t\t\toutput.Write(TargetType);\n\t\t\toutput.Write(' ');\n\t\t\tswitch (Kind)\n\t\t\t{\n\t\t\t\tcase ConversionKind.SignExtend:\n\t\t\t\t\toutput.Write(\"<sign extend>\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase ConversionKind.ZeroExtend:\n\t\t\t\t\toutput.Write(\"<zero extend>\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase ConversionKind.Invalid:\n\t\t\t\t\toutput.Write(\"<invalid>\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\toutput.Write('(');\n\t\t\tArgument.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\tvar flags = base.ComputeFlags();\n\t\t\tif (CheckForOverflow)\n\t\t\t\tflags |= InstructionFlags.MayThrow;\n\t\t\treturn flags;\n\t\t}\n\n\t\tpublic override ILInstruction UnwrapConv(ConversionKind kind)\n\t\t{\n\t\t\tif (this.Kind == kind && !IsLifted)\n\t\t\t\treturn Argument.UnwrapConv(kind);\n\t\t\telse\n\t\t\t\treturn this;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/DeconstructInstruction.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpartial class DeconstructInstruction\n\t{\n\t\tpublic static readonly SlotInfo InitSlot = new SlotInfo(\"Init\", canInlineInto: true, isCollection: true);\n\t\tpublic static readonly SlotInfo PatternSlot = new SlotInfo(\"Pattern\", canInlineInto: true);\n\t\tpublic static readonly SlotInfo ConversionsSlot = new SlotInfo(\"Conversions\");\n\t\tpublic static readonly SlotInfo AssignmentsSlot = new SlotInfo(\"Assignments\");\n\n\t\tpublic DeconstructInstruction()\n\t\t\t: base(OpCode.DeconstructInstruction)\n\t\t{\n\t\t\tthis.Init = new InstructionCollection<StLoc>(this, 0);\n\t\t}\n\n\t\tpublic readonly InstructionCollection<StLoc> Init;\n\n\t\tMatchInstruction pattern;\n\t\tpublic MatchInstruction Pattern {\n\t\t\tget { return this.pattern; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.pattern, value, Init.Count);\n\t\t\t}\n\t\t}\n\n\t\tBlock conversions;\n\t\tpublic Block Conversions {\n\t\t\tget { return this.conversions; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.conversions, value, Init.Count + 1);\n\t\t\t}\n\t\t}\n\n\t\tBlock assignments;\n\t\tpublic Block Assignments {\n\t\t\tget { return this.assignments; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.assignments, value, Init.Count + 2);\n\t\t\t}\n\t\t}\n\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn Init.Count + 3;\n\t\t}\n\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index - Init.Count)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.pattern;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn this.conversions;\n\t\t\t\tcase 2:\n\t\t\t\t\treturn this.assignments;\n\t\t\t\tdefault:\n\t\t\t\t\treturn this.Init[index];\n\t\t\t}\n\t\t}\n\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index - Init.Count)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Pattern = (MatchInstruction)value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tthis.Conversions = (Block)value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tthis.Assignments = (Block)value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthis.Init[index] = (StLoc)value;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index - Init.Count)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn PatternSlot;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn ConversionsSlot;\n\t\t\t\tcase 2:\n\t\t\t\t\treturn AssignmentsSlot;\n\t\t\t\tdefault:\n\t\t\t\t\treturn InitSlot;\n\t\t\t}\n\t\t}\n\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = new DeconstructInstruction();\n\t\t\tclone.Init.AddRange(this.Init.Select(inst => (StLoc)inst.Clone()));\n\t\t\tclone.Pattern = (MatchInstruction)this.pattern.Clone();\n\t\t\tclone.Conversions = (Block)this.conversions.Clone();\n\t\t\tclone.Assignments = (Block)this.assignments.Clone();\n\t\t\treturn clone;\n\t\t}\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\tvar flags = InstructionFlags.None;\n\t\t\tforeach (var inst in Init)\n\t\t\t{\n\t\t\t\tflags |= inst.Flags;\n\t\t\t}\n\t\t\tflags |= pattern.Flags | conversions.Flags | assignments.Flags;\n\t\t\treturn flags;\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.None;\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void InstructionCollectionUpdateComplete()\n\t\t{\n\t\t\tbase.InstructionCollectionUpdateComplete();\n\t\t\tif (pattern.Parent == this)\n\t\t\t\tpattern.ChildIndex = Init.Count;\n\t\t\tif (conversions.Parent == this)\n\t\t\t\tconversions.ChildIndex = Init.Count + 1;\n\t\t\tif (assignments.Parent == this)\n\t\t\t\tassignments.ChildIndex = Init.Count + 2;\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(\"deconstruct \");\n\t\t\toutput.MarkFoldStart(\"{...}\");\n\t\t\toutput.WriteLine(\"{\");\n\t\t\toutput.Indent();\n\t\t\toutput.WriteLine(\"init:\");\n\t\t\toutput.Indent();\n\t\t\tforeach (var inst in this.Init)\n\t\t\t{\n\t\t\t\tinst.WriteTo(output, options);\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t\toutput.Unindent();\n\t\t\toutput.WriteLine(\"pattern:\");\n\t\t\toutput.Indent();\n\t\t\tpattern.WriteTo(output, options);\n\t\t\toutput.Unindent();\n\t\t\toutput.WriteLine();\n\t\t\toutput.Write(\"conversions: \");\n\t\t\tconversions.WriteTo(output, options);\n\t\t\toutput.WriteLine();\n\t\t\toutput.Write(\"assignments: \");\n\t\t\tassignments.WriteTo(output, options);\n\t\t\toutput.Unindent();\n\t\t\toutput.WriteLine();\n\t\t\toutput.Write('}');\n\t\t\toutput.MarkFoldEnd();\n\t\t}\n\n\t\tinternal static bool IsConversionStLoc(ILInstruction inst, out ILVariable variable, out ILVariable inputVariable)\n\t\t{\n\t\t\tinputVariable = null;\n\t\t\tif (!inst.MatchStLoc(out variable, out var value))\n\t\t\t\treturn false;\n\t\t\tILInstruction input;\n\t\t\tswitch (value)\n\t\t\t{\n\t\t\t\tcase Conv conv:\n\t\t\t\t\tinput = conv.Argument;\n\t\t\t\t\tbreak;\n\t\t\t\t//case Call { Method: { IsOperator: true, Name: \"op_Implicit\" }, Arguments: { Count: 1 } } call:\n\t\t\t\t//\tinput = call.Arguments[0];\n\t\t\t\t//\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn input.MatchLdLoc(out inputVariable) || input.MatchLdLoca(out inputVariable);\n\t\t}\n\n\t\tinternal static bool IsAssignment(ILInstruction inst, ICompilation typeSystem, out IType expectedType, out ILInstruction value)\n\t\t{\n\t\t\texpectedType = null;\n\t\t\tvalue = null;\n\t\t\tswitch (inst)\n\t\t\t{\n\t\t\t\tcase CallInstruction call:\n\t\t\t\t\tif (call.Method.AccessorKind != System.Reflection.MethodSemanticsAttributes.Setter)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tfor (int i = 0; i < call.Arguments.Count - 1; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tILInstruction arg = call.Arguments[i];\n\t\t\t\t\t\tif (arg.Flags == InstructionFlags.None)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// OK - we accept integer literals, etc.\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (arg.MatchLdLoc(out var v))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\texpectedType = call.Method.Parameters.Last().Type;\n\t\t\t\t\tvalue = call.Arguments.Last();\n\t\t\t\t\treturn true;\n\t\t\t\tcase StLoc stloc:\n\t\t\t\t\texpectedType = stloc.Variable.Type;\n\t\t\t\t\tvalue = stloc.Value;\n\t\t\t\t\treturn true;\n\t\t\t\tcase StObj stobj:\n\t\t\t\t\tvar target = stobj.Target;\n\t\t\t\t\twhile (target.MatchLdFlda(out var nestedTarget, out _))\n\t\t\t\t\t\ttarget = nestedTarget;\n\t\t\t\t\tif (target.Flags == InstructionFlags.None)\n\t\t\t\t\t{\n\t\t\t\t\t\t// OK - we accept integer literals, etc.\n\t\t\t\t\t}\n\t\t\t\t\telse if (target.MatchLdLoc(out var v))\n\t\t\t\t\t{\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif (stobj.Target.InferType(typeSystem) is ByReferenceType brt)\n\t\t\t\t\t\texpectedType = brt.ElementType;\n\t\t\t\t\telse\n\t\t\t\t\t\texpectedType = SpecialType.UnknownType;\n\t\t\t\t\tvalue = stobj.Value;\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tvar patternVariables = new HashSet<ILVariable>();\n\t\t\tvar conversionVariables = new HashSet<ILVariable>();\n\n\t\t\tforeach (StLoc init in this.Init)\n\t\t\t{\n\t\t\t\tDebug.Assert(init.Variable.IsSingleDefinition && init.Variable.LoadCount == 1);\n\t\t\t\tDebug.Assert(init.Variable.LoadInstructions[0].IsDescendantOf(assignments));\n\t\t\t}\n\n\t\t\tValidatePattern(pattern);\n\n\t\t\tforeach (var inst in this.conversions.Instructions)\n\t\t\t{\n\t\t\t\tif (!IsConversionStLoc(inst, out var variable, out var inputVariable))\n\t\t\t\t\tDebug.Fail(\"inst is not a conversion stloc!\");\n\t\t\t\tDebug.Assert(variable.IsSingleDefinition && variable.LoadCount == 1);\n\t\t\t\tDebug.Assert(variable.LoadInstructions[0].IsDescendantOf(assignments));\n\t\t\t\tDebug.Assert(patternVariables.Contains(inputVariable));\n\t\t\t\tconversionVariables.Add(variable);\n\t\t\t}\n\t\t\tDebug.Assert(this.conversions.FinalInstruction is Nop);\n\n\t\t\tforeach (var inst in assignments.Instructions)\n\t\t\t{\n\t\t\t\tif (!(IsAssignment(inst, typeSystem: null, out _, out var value) && value.MatchLdLoc(out var inputVariable)))\n\t\t\t\t\tthrow new InvalidOperationException(\"inst is not an assignment!\");\n\t\t\t\tDebug.Assert(patternVariables.Contains(inputVariable) || conversionVariables.Contains(inputVariable));\n\t\t\t}\n\t\t\tDebug.Assert(this.assignments.FinalInstruction is Nop);\n\n\t\t\tvoid ValidatePattern(MatchInstruction inst)\n\t\t\t{\n\t\t\t\tDebug.Assert(inst.IsDeconstructCall || inst.IsDeconstructTuple);\n\t\t\t\tDebug.Assert(!inst.CheckNotNull && !inst.CheckType);\n\t\t\t\tDebug.Assert(!inst.HasDesignator);\n\t\t\t\tforeach (var subPattern in inst.SubPatterns.Cast<MatchInstruction>())\n\t\t\t\t{\n\t\t\t\t\tif (subPattern.IsVar)\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(subPattern.Variable.IsSingleDefinition && subPattern.Variable.LoadCount <= 1);\n\t\t\t\t\t\tif (subPattern.Variable.LoadCount == 1)\n\t\t\t\t\t\t\tDebug.Assert(subPattern.Variable.LoadInstructions[0].IsDescendantOf(this));\n\t\t\t\t\t\tpatternVariables.Add(subPattern.Variable);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tValidatePattern(subPattern);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/DeconstructResultInstruction.cs",
    "content": "#nullable enable\n// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpartial class DeconstructResultInstruction\n\t{\n\t\tpublic int Index { get; }\n\n\t\tpublic override StackType ResultType { get; }\n\n\t\tpublic DeconstructResultInstruction(int index, StackType resultType, ILInstruction argument)\n\t\t\t: base(OpCode.DeconstructResultInstruction, argument)\n\t\t{\n\t\t\tDebug.Assert(index >= 0);\n\t\t\tIndex = index;\n\t\t\tResultType = resultType;\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\toutput.Write(Index.ToString());\n\t\t\toutput.Write('(');\n\t\t\tthis.Argument.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\n\t\tMatchInstruction? FindMatch()\n\t\t{\n\t\t\tfor (ILInstruction? inst = this; inst != null; inst = inst.Parent)\n\t\t\t{\n\t\t\t\tif (inst.Parent is MatchInstruction match && inst != match.TestedOperand)\n\t\t\t\t\treturn match;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tvoid AdditionalInvariants()\n\t\t{\n\t\t\tvar matchInst = FindMatch();\n\t\t\tDebugAssert(matchInst != null && (matchInst.IsDeconstructCall || matchInst.IsDeconstructTuple));\n\t\t\tDebugAssert(Argument.MatchLdLoc(matchInst.Variable));\n\t\t\tvar outParamType = matchInst.GetDeconstructResultType(this.Index);\n\t\t\tDebugAssert(outParamType.GetStackType() == ResultType);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/DefaultValue.cs",
    "content": "#nullable enable\n// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpartial class DefaultValue\n\t{\n\t\t/// <summary>\n\t\t/// Gets whether the IL stack was empty at the point of this instruction.\n\t\t/// (not counting the argument of the instruction itself)\n\t\t/// </summary>\n\t\tpublic bool ILStackWasEmpty;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/DynamicInstructions.cs",
    "content": "#nullable enable\n// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Linq.Expressions;\n\nusing ICSharpCode.Decompiler.IL.Patterns;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t[Flags]\n\tpublic enum CSharpArgumentInfoFlags\n\t{\n\t\tNone = 0,\n\t\tUseCompileTimeType = 1,\n\t\tConstant = 2,\n\t\tNamedArgument = 4,\n\t\tIsRef = 8,\n\t\tIsOut = 0x10,\n\t\tIsStaticType = 0x20\n\t}\n\n\t[Flags]\n\tpublic enum CSharpBinderFlags\n\t{\n\t\tNone = 0,\n\t\tCheckedContext = 1,\n\t\tInvokeSimpleName = 2,\n\t\tInvokeSpecialName = 4,\n\t\tBinaryOperationLogical = 8,\n\t\tConvertExplicit = 0x10,\n\t\tConvertArrayIndex = 0x20,\n\t\tResultIndexed = 0x40,\n\t\tValueFromCompoundAssignment = 0x80,\n\t\tResultDiscarded = 0x100\n\t}\n\n\tpublic struct CSharpArgumentInfo\n\t{\n\t\tpublic string? Name { get; set; }\n\t\tpublic CSharpArgumentInfoFlags Flags { get; set; }\n\t\tpublic IType CompileTimeType { get; set; }\n\n\t\tpublic bool HasFlag(CSharpArgumentInfoFlags flag) => (Flags & flag) != 0;\n\t}\n\n\tpartial class DynamicInstruction\n\t{\n\t\tpublic CSharpBinderFlags BinderFlags { get; }\n\t\tpublic IType? CallingContext { get; }\n\n\t\tprotected DynamicInstruction(OpCode opCode, CSharpBinderFlags binderFlags, IType? context)\n\t\t\t: base(opCode)\n\t\t{\n\t\t\tBinderFlags = binderFlags;\n\t\t\tCallingContext = context;\n\t\t}\n\n\t\tprotected void WriteBinderFlags(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteBinderFlags(BinderFlags, output, options);\n\t\t}\n\n\t\tinternal static void WriteBinderFlags(CSharpBinderFlags flags, ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tif ((flags & CSharpBinderFlags.BinaryOperationLogical) != 0)\n\t\t\t\toutput.Write(\".logic\");\n\t\t\tif ((flags & CSharpBinderFlags.CheckedContext) != 0)\n\t\t\t\toutput.Write(\".checked\");\n\t\t\tif ((flags & CSharpBinderFlags.ConvertArrayIndex) != 0)\n\t\t\t\toutput.Write(\".arrayindex\");\n\t\t\tif ((flags & CSharpBinderFlags.ConvertExplicit) != 0)\n\t\t\t\toutput.Write(\".explicit\");\n\t\t\tif ((flags & CSharpBinderFlags.InvokeSimpleName) != 0)\n\t\t\t\toutput.Write(\".invokesimple\");\n\t\t\tif ((flags & CSharpBinderFlags.InvokeSpecialName) != 0)\n\t\t\t\toutput.Write(\".invokespecial\");\n\t\t\tif ((flags & CSharpBinderFlags.ResultDiscarded) != 0)\n\t\t\t\toutput.Write(\".discard\");\n\t\t\tif ((flags & CSharpBinderFlags.ResultIndexed) != 0)\n\t\t\t\toutput.Write(\".resultindexed\");\n\t\t\tif ((flags & CSharpBinderFlags.ValueFromCompoundAssignment) != 0)\n\t\t\t\toutput.Write(\".compound\");\n\t\t}\n\n\t\tpublic abstract CSharpArgumentInfo GetArgumentInfoOfChild(int index);\n\n\t\tinternal static void WriteArgumentList(ITextOutput output, ILAstWritingOptions options, params (ILInstruction, CSharpArgumentInfo)[] arguments)\n\t\t{\n\t\t\tWriteArgumentList(output, options, (IEnumerable<(ILInstruction, CSharpArgumentInfo)>)arguments);\n\t\t}\n\n\t\tinternal static void WriteArgumentList(ITextOutput output, ILAstWritingOptions options, IEnumerable<(ILInstruction, CSharpArgumentInfo)> arguments)\n\t\t{\n\t\t\toutput.Write('(');\n\t\t\tint j = 0;\n\t\t\tforeach (var (arg, info) in arguments)\n\t\t\t{\n\t\t\t\tif (j > 0)\n\t\t\t\t\toutput.Write(\", \");\n\t\t\t\toutput.Write(\"[flags: \");\n\t\t\t\toutput.Write(info.Flags.ToString());\n\t\t\t\toutput.Write(\", name: \" + info.Name + \"] \");\n\t\t\t\targ.WriteTo(output, options);\n\t\t\t\tj++;\n\t\t\t}\n\t\t\toutput.Write(')');\n\t\t}\n\t}\n\n\tpartial class DynamicConvertInstruction\n\t{\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tWriteBinderFlags(output, options);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\targument.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\n\t\tpublic DynamicConvertInstruction(CSharpBinderFlags binderFlags, IType type, IType? context, ILInstruction argument)\n\t\t\t: base(OpCode.DynamicConvertInstruction, binderFlags, context)\n\t\t{\n\t\t\tthis.type = type;\n\t\t\tArgument = argument;\n\t\t}\n\n\t\tprotected internal override bool PerformMatch(ref ListMatch listMatch, ref Match match)\n\t\t{\n\t\t\treturn base.PerformMatch(ref listMatch, ref match);\n\t\t}\n\n\t\tpublic override StackType ResultType => type.GetStackType();\n\n\t\tpublic bool IsChecked => (BinderFlags & CSharpBinderFlags.CheckedContext) != 0;\n\n\t\tpublic bool IsExplicit => (BinderFlags & CSharpBinderFlags.ConvertExplicit) != 0;\n\n\t\tpublic override CSharpArgumentInfo GetArgumentInfoOfChild(int index)\n\t\t{\n\t\t\treturn default(CSharpArgumentInfo);\n\t\t}\n\t}\n\n\tpartial class DynamicInvokeMemberInstruction\n\t{\n\t\tpublic string Name { get; }\n\t\tpublic IReadOnlyList<IType> TypeArguments { get; }\n\t\tpublic IReadOnlyList<CSharpArgumentInfo> ArgumentInfo { get; }\n\n\t\tpublic DynamicInvokeMemberInstruction(CSharpBinderFlags binderFlags, string name, IType[]? typeArguments, IType? context, CSharpArgumentInfo[] argumentInfo, ILInstruction[] arguments)\n\t\t\t: base(OpCode.DynamicInvokeMemberInstruction, binderFlags, context)\n\t\t{\n\t\t\tName = name;\n\t\t\tTypeArguments = typeArguments ?? Empty<IType>.Array;\n\t\t\tArgumentInfo = argumentInfo;\n\t\t\tArguments = new InstructionCollection<ILInstruction>(this, 0);\n\t\t\tArguments.AddRange(arguments);\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tWriteBinderFlags(output, options);\n\t\t\toutput.Write(' ');\n\t\t\toutput.Write(Name);\n\t\t\tif (TypeArguments.Count > 0)\n\t\t\t{\n\t\t\t\toutput.Write('<');\n\t\t\t\tint i = 0;\n\t\t\t\tforeach (var typeArg in TypeArguments)\n\t\t\t\t{\n\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\toutput.Write(\", \");\n\t\t\t\t\ttypeArg.WriteTo(output);\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t\toutput.Write('>');\n\t\t\t}\n\t\t\tWriteArgumentList(output, options, Arguments.Zip(ArgumentInfo));\n\t\t}\n\n\t\tpublic override StackType ResultType => StackType.O;\n\n\t\tpublic override CSharpArgumentInfo GetArgumentInfoOfChild(int index)\n\t\t{\n\t\t\tif (index < 0 || index >= ArgumentInfo.Count)\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(index));\n\t\t\treturn ArgumentInfo[index];\n\t\t}\n\t}\n\n\tpartial class DynamicGetMemberInstruction\n\t{\n\t\tpublic string? Name { get; }\n\t\tpublic CSharpArgumentInfo TargetArgumentInfo { get; }\n\n\t\tpublic DynamicGetMemberInstruction(CSharpBinderFlags binderFlags, string? name, IType? context, CSharpArgumentInfo targetArgumentInfo, ILInstruction target)\n\t\t\t: base(OpCode.DynamicGetMemberInstruction, binderFlags, context)\n\t\t{\n\t\t\tName = name;\n\t\t\tTargetArgumentInfo = targetArgumentInfo;\n\t\t\tTarget = target;\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tWriteBinderFlags(output, options);\n\t\t\toutput.Write(' ');\n\t\t\toutput.Write(Name);\n\t\t\tWriteArgumentList(output, options, (Target, TargetArgumentInfo));\n\t\t}\n\n\t\tpublic override StackType ResultType => StackType.O;\n\n\t\tpublic override CSharpArgumentInfo GetArgumentInfoOfChild(int index)\n\t\t{\n\t\t\tif (index != 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(index));\n\t\t\treturn TargetArgumentInfo;\n\t\t}\n\t}\n\n\tpartial class DynamicSetMemberInstruction\n\t{\n\t\tpublic string? Name { get; }\n\t\tpublic CSharpArgumentInfo TargetArgumentInfo { get; }\n\t\tpublic CSharpArgumentInfo ValueArgumentInfo { get; }\n\n\t\tpublic DynamicSetMemberInstruction(CSharpBinderFlags binderFlags, string? name, IType? context, CSharpArgumentInfo targetArgumentInfo, ILInstruction target, CSharpArgumentInfo valueArgumentInfo, ILInstruction value)\n\t\t\t: base(OpCode.DynamicSetMemberInstruction, binderFlags, context)\n\t\t{\n\t\t\tName = name;\n\t\t\tTargetArgumentInfo = targetArgumentInfo;\n\t\t\tTarget = target;\n\t\t\tValueArgumentInfo = valueArgumentInfo;\n\t\t\tValue = value;\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tWriteBinderFlags(output, options);\n\t\t\toutput.Write(' ');\n\t\t\toutput.Write(Name);\n\t\t\tWriteArgumentList(output, options, (Target, TargetArgumentInfo), (Value, ValueArgumentInfo));\n\t\t}\n\n\t\tpublic override StackType ResultType => StackType.O;\n\n\t\tpublic override CSharpArgumentInfo GetArgumentInfoOfChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn TargetArgumentInfo;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn ValueArgumentInfo;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(index));\n\t\t\t}\n\t\t}\n\t}\n\n\tpartial class DynamicGetIndexInstruction\n\t{\n\t\tpublic IReadOnlyList<CSharpArgumentInfo> ArgumentInfo { get; }\n\n\t\tpublic DynamicGetIndexInstruction(CSharpBinderFlags binderFlags, IType? context, CSharpArgumentInfo[] argumentInfo, ILInstruction[] arguments)\n\t\t\t: base(OpCode.DynamicGetIndexInstruction, binderFlags, context)\n\t\t{\n\t\t\tArgumentInfo = argumentInfo;\n\t\t\tArguments = new InstructionCollection<ILInstruction>(this, 0);\n\t\t\tArguments.AddRange(arguments);\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tWriteBinderFlags(output, options);\n\t\t\toutput.Write(' ');\n\t\t\toutput.Write(\"get_Item\");\n\t\t\tWriteArgumentList(output, options, Arguments.Zip(ArgumentInfo));\n\t\t}\n\n\t\tpublic override StackType ResultType => StackType.O;\n\n\t\tpublic override CSharpArgumentInfo GetArgumentInfoOfChild(int index)\n\t\t{\n\t\t\tif (index < 0 || index >= ArgumentInfo.Count)\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(index));\n\t\t\treturn ArgumentInfo[index];\n\t\t}\n\t}\n\n\tpartial class DynamicSetIndexInstruction\n\t{\n\t\tpublic IReadOnlyList<CSharpArgumentInfo> ArgumentInfo { get; }\n\n\t\tpublic DynamicSetIndexInstruction(CSharpBinderFlags binderFlags, IType? context, CSharpArgumentInfo[] argumentInfo, ILInstruction[] arguments)\n\t\t\t: base(OpCode.DynamicSetIndexInstruction, binderFlags, context)\n\t\t{\n\t\t\tArgumentInfo = argumentInfo;\n\t\t\tArguments = new InstructionCollection<ILInstruction>(this, 0);\n\t\t\tArguments.AddRange(arguments);\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tWriteBinderFlags(output, options);\n\t\t\toutput.Write(' ');\n\t\t\toutput.Write(\"set_Item\");\n\t\t\tWriteArgumentList(output, options, Arguments.Zip(ArgumentInfo));\n\t\t}\n\n\t\tpublic override StackType ResultType => StackType.O;\n\n\t\tpublic override CSharpArgumentInfo GetArgumentInfoOfChild(int index)\n\t\t{\n\t\t\tif (index < 0 || index >= ArgumentInfo.Count)\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(index));\n\t\t\treturn ArgumentInfo[index];\n\t\t}\n\t}\n\n\tpartial class DynamicInvokeConstructorInstruction\n\t{\n\t\treadonly IType? resultType;\n\n\t\tpublic IReadOnlyList<CSharpArgumentInfo> ArgumentInfo { get; }\n\n\t\tpublic DynamicInvokeConstructorInstruction(CSharpBinderFlags binderFlags, IType? type, IType? context, CSharpArgumentInfo[] argumentInfo, ILInstruction[] arguments)\n\t\t\t: base(OpCode.DynamicInvokeConstructorInstruction, binderFlags, context)\n\t\t{\n\t\t\tArgumentInfo = argumentInfo;\n\t\t\tArguments = new InstructionCollection<ILInstruction>(this, 0);\n\t\t\tArguments.AddRange(arguments);\n\t\t\tthis.resultType = type;\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tWriteBinderFlags(output, options);\n\t\t\toutput.Write(' ');\n\t\t\tresultType?.WriteTo(output);\n\t\t\toutput.Write(\".ctor\");\n\t\t\tWriteArgumentList(output, options, Arguments.Zip(ArgumentInfo));\n\t\t}\n\n\t\tpublic override StackType ResultType => resultType?.GetStackType() ?? StackType.Unknown;\n\n\t\tpublic override CSharpArgumentInfo GetArgumentInfoOfChild(int index)\n\t\t{\n\t\t\tif (index < 0 || index >= ArgumentInfo.Count)\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(index));\n\t\t\treturn ArgumentInfo[index];\n\t\t}\n\t}\n\n\tpartial class DynamicBinaryOperatorInstruction\n\t{\n\t\tpublic CSharpArgumentInfo LeftArgumentInfo { get; }\n\t\tpublic CSharpArgumentInfo RightArgumentInfo { get; }\n\t\tpublic ExpressionType Operation { get; }\n\n\t\tpublic DynamicBinaryOperatorInstruction(CSharpBinderFlags binderFlags, ExpressionType operation, IType? context, CSharpArgumentInfo leftArgumentInfo, ILInstruction left, CSharpArgumentInfo rightArgumentInfo, ILInstruction right)\n\t\t\t: base(OpCode.DynamicBinaryOperatorInstruction, binderFlags, context)\n\t\t{\n\t\t\tOperation = operation;\n\t\t\tLeftArgumentInfo = leftArgumentInfo;\n\t\t\tLeft = left;\n\t\t\tRightArgumentInfo = rightArgumentInfo;\n\t\t\tRight = right;\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tWriteBinderFlags(output, options);\n\t\t\toutput.Write(' ');\n\t\t\toutput.Write(Operation.ToString());\n\t\t\tWriteArgumentList(output, options, (Left, LeftArgumentInfo), (Right, RightArgumentInfo));\n\t\t}\n\n\t\tpublic override StackType ResultType => StackType.O;\n\n\t\tpublic override CSharpArgumentInfo GetArgumentInfoOfChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn LeftArgumentInfo;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn RightArgumentInfo;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(index));\n\t\t\t}\n\t\t}\n\t}\n\n\tpartial class DynamicLogicOperatorInstruction\n\t{\n\t\tpublic CSharpArgumentInfo LeftArgumentInfo { get; }\n\t\tpublic CSharpArgumentInfo RightArgumentInfo { get; }\n\t\tpublic ExpressionType Operation { get; }\n\n\t\tpublic DynamicLogicOperatorInstruction(CSharpBinderFlags binderFlags, ExpressionType operation, IType? context, CSharpArgumentInfo leftArgumentInfo, ILInstruction left, CSharpArgumentInfo rightArgumentInfo, ILInstruction right)\n\t\t\t: base(OpCode.DynamicLogicOperatorInstruction, binderFlags, context)\n\t\t{\n\t\t\tOperation = operation;\n\t\t\tLeftArgumentInfo = leftArgumentInfo;\n\t\t\tLeft = left;\n\t\t\tRightArgumentInfo = rightArgumentInfo;\n\t\t\tRight = right;\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tWriteBinderFlags(output, options);\n\t\t\toutput.Write(' ');\n\t\t\toutput.Write(Operation.ToString());\n\t\t\tWriteArgumentList(output, options, (Left, LeftArgumentInfo), (Right, RightArgumentInfo));\n\t\t}\n\n\t\tpublic override StackType ResultType => StackType.O;\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn DirectFlags | Left.Flags\n\t\t\t\t| SemanticHelper.CombineBranches(Right.Flags, InstructionFlags.None);\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags => InstructionFlags.MayThrow | InstructionFlags.SideEffect | InstructionFlags.ControlFlow;\n\n\t\tpublic override CSharpArgumentInfo GetArgumentInfoOfChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn LeftArgumentInfo;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn RightArgumentInfo;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(index));\n\t\t\t}\n\t\t}\n\t}\n\n\tpartial class DynamicUnaryOperatorInstruction\n\t{\n\t\tpublic CSharpArgumentInfo OperandArgumentInfo { get; }\n\t\tpublic ExpressionType Operation { get; }\n\n\t\tpublic DynamicUnaryOperatorInstruction(CSharpBinderFlags binderFlags, ExpressionType operation, IType? context, CSharpArgumentInfo operandArgumentInfo, ILInstruction operand)\n\t\t\t: base(OpCode.DynamicUnaryOperatorInstruction, binderFlags, context)\n\t\t{\n\t\t\tOperation = operation;\n\t\t\tOperandArgumentInfo = operandArgumentInfo;\n\t\t\tOperand = operand;\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tWriteBinderFlags(output, options);\n\t\t\toutput.Write(' ');\n\t\t\toutput.Write(Operation.ToString());\n\t\t\tWriteArgumentList(output, options, (Operand, OperandArgumentInfo));\n\t\t}\n\n\t\tpublic override StackType ResultType {\n\t\t\tget {\n\t\t\t\tswitch (Operation)\n\t\t\t\t{\n\t\t\t\t\tcase ExpressionType.IsFalse:\n\t\t\t\t\tcase ExpressionType.IsTrue:\n\t\t\t\t\t\treturn StackType.I4; // bool\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn StackType.O;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic override CSharpArgumentInfo GetArgumentInfoOfChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn OperandArgumentInfo;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(index));\n\t\t\t}\n\t\t}\n\t}\n\n\tpartial class DynamicInvokeInstruction\n\t{\n\t\tpublic IReadOnlyList<CSharpArgumentInfo> ArgumentInfo { get; }\n\n\t\tpublic DynamicInvokeInstruction(CSharpBinderFlags binderFlags, IType? context, CSharpArgumentInfo[] argumentInfo, ILInstruction[] arguments)\n\t\t\t: base(OpCode.DynamicInvokeInstruction, binderFlags, context)\n\t\t{\n\t\t\tArgumentInfo = argumentInfo;\n\t\t\tArguments = new InstructionCollection<ILInstruction>(this, 0);\n\t\t\tArguments.AddRange(arguments);\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tWriteBinderFlags(output, options);\n\t\t\toutput.Write(' ');\n\t\t\tWriteArgumentList(output, options, Arguments.Zip(ArgumentInfo));\n\t\t}\n\n\t\tpublic override StackType ResultType => StackType.O;\n\n\t\tpublic override CSharpArgumentInfo GetArgumentInfoOfChild(int index)\n\t\t{\n\t\t\tif (index < 0 || index >= ArgumentInfo.Count)\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(index));\n\t\t\treturn ArgumentInfo[index];\n\t\t}\n\t}\n\n\tpartial class DynamicIsEventInstruction\n\t{\n\t\tpublic string? Name { get; }\n\n\t\tpublic DynamicIsEventInstruction(CSharpBinderFlags binderFlags, string? name, IType? context, ILInstruction argument)\n\t\t\t: base(OpCode.DynamicIsEventInstruction, binderFlags, context)\n\t\t{\n\t\t\tName = name;\n\t\t\tArgument = argument;\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tWriteBinderFlags(output, options);\n\t\t\toutput.Write(' ');\n\t\t\toutput.Write('(');\n\t\t\tArgument.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\n\t\tpublic override StackType ResultType => StackType.I4;\n\n\t\tpublic override CSharpArgumentInfo GetArgumentInfoOfChild(int index)\n\t\t{\n\t\t\treturn default(CSharpArgumentInfo);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/ExpressionTreeCast.cs",
    "content": "#nullable enable\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpartial class ExpressionTreeCast\n\t{\n\t\tpublic bool IsChecked { get; set; }\n\n\t\tpublic ExpressionTreeCast(IType type, ILInstruction argument, bool isChecked)\n\t\t\t: base(OpCode.ExpressionTreeCast, argument)\n\t\t{\n\t\t\tthis.type = type;\n\t\t\tthis.IsChecked = isChecked;\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tif (IsChecked)\n\t\t\t\toutput.Write(\".checked\");\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tArgument.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpartial class ILFunction\n\t{\n\t\t/// <summary>\n\t\t/// Gets the method definition from metadata.\n\t\t/// May be null for functions that were not constructed from metadata,\n\t\t/// e.g., expression trees.\n\t\t/// </summary>\n\t\tpublic readonly IMethod? Method;\n\n\t\t/// <summary>\n\t\t/// Gets the generic context of this function.\n\t\t/// </summary>\n\t\tpublic readonly GenericContext GenericContext;\n\n\t\t/// <summary>\n\t\t/// Gets the name of this function, usually this returns the name from metadata.\n\t\t/// <para>\n\t\t/// For local functions:\n\t\t/// This is the name that is used to declare and use the function.\n\t\t/// It may not conflict with the names of local variables of ancestor functions\n\t\t/// and may be overwritten by the AssignVariableNames step.\n\t\t/// \n\t\t/// For top-level functions, delegates and expressions trees modifying this usually\n\t\t/// has no effect, as the name should not be used in the final AST construction.\n\t\t/// </para>\n\t\t/// </summary>\n\t\tpublic string? Name;\n\n\t\t/// <summary>\n\t\t/// Size of the IL code in this function.\n\t\t/// Note: after async/await transform, this is the code size of the MoveNext function.\n\t\t/// </summary>\n\t\tpublic int CodeSize;\n\n\t\t/// <summary>\n\t\t/// List of ILVariables used in this function.\n\t\t/// </summary>\n\t\tpublic readonly ILVariableCollection Variables;\n\n\t\t/// <summary>\n\t\t/// Gets \n\t\t/// </summary>\n\t\tpublic int LocalVariableSignatureLength;\n\n\t\t/// <summary>\n\t\t/// Gets the scope in which the local function is declared.\n\t\t/// Returns null, if this is not a local function.\n\t\t/// </summary>\n\t\tpublic BlockContainer? DeclarationScope { get; internal set; }\n\n\t\t/// <summary>\n\t\t/// Gets the set of captured variables by this ILFunction.\n\t\t/// </summary>\n\t\t/// <remarks>This is populated by the <see cref=\"TransformDisplayClassUsage\" /> step.</remarks>\n\t\tpublic HashSet<ILVariable> CapturedVariables { get; } = new HashSet<ILVariable>();\n\n\t\t/// <summary>\n\t\t/// List of warnings of ILReader.\n\t\t/// </summary>\n\t\tpublic List<string> Warnings { get; } = new List<string>();\n\n\t\t/// <summary>\n\t\t/// Gets whether this function is a decompiled iterator (is using yield).\n\t\t/// This flag gets set by the YieldReturnDecompiler.\n\t\t/// \n\t\t/// If set, the 'return' instruction has the semantics of 'yield break;'\n\t\t/// instead of a normal return.\n\t\t/// </summary>\n\t\tpublic bool IsIterator;\n\n\t\t/// <summary>\n\t\t/// Gets whether the YieldReturnDecompiler determined that the Mono C# compiler was used to compile this function.\n\t\t/// </summary>\n\t\tpublic bool StateMachineCompiledWithMono;\n\n\t\t/// <summary>\n\t\t/// Gets whether the YieldReturnDecompiler determined that the Legacy VB compiler was used to compile this function.\n\t\t/// </summary>\n\t\tpublic bool StateMachineCompiledWithLegacyVisualBasic;\n\n\t\t/// <summary>\n\t\t/// Gets whether this function is async.\n\t\t/// This flag gets set by the AsyncAwaitDecompiler.\n\t\t/// </summary>\n\t\tpublic bool IsAsync => AsyncReturnType != null;\n\n\t\t/// <summary>\n\t\t/// Return element type -- if the async method returns Task{T}, this field stores T.\n\t\t/// If the async method returns Task or void, this field stores void.\n\t\t/// </summary>\n\t\tpublic IType? AsyncReturnType;\n\n\t\t/// <summary>\n\t\t/// If this function is an iterator/async, this field stores the compiler-generated MoveNext() method.\n\t\t/// </summary>\n\t\tpublic IMethod? MoveNextMethod;\n\n\t\t/// <summary>\n\t\t/// If this function is a local function, this field stores the reduced version of the function.\n\t\t/// </summary>\n\t\tinternal TypeSystem.Implementation.LocalFunctionMethod? ReducedMethod;\n\n\t\tpublic DebugInfo.AsyncDebugInfo AsyncDebugInfo;\n\n\t\tint ctorCallStart = int.MinValue;\n\n\t\t/// <summary>\n\t\t/// Returns the IL offset of the constructor call, -1 if this is not a constructor or no chained constructor call was found.\n\t\t/// </summary>\n\t\tinternal int ChainedConstructorCallILOffset {\n\t\t\tget {\n\t\t\t\tif (ctorCallStart == int.MinValue)\n\t\t\t\t{\n\t\t\t\t\tif (this.Method == null || !this.Method.IsConstructor || this.Method.IsStatic)\n\t\t\t\t\t{\n\t\t\t\t\t\tctorCallStart = -1;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tctorCallStart = this.Descendants.FirstOrDefault(d => d is CallInstruction call && !(call is NewObj)\n\t\t\t\t\t\t\t&& call.Method.IsConstructor\n\t\t\t\t\t\t\t&& call.Method.DeclaringType.IsReferenceType == true\n\t\t\t\t\t\t\t&& call.Parent is Block)?.StartILOffset ?? -1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn ctorCallStart;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// If this is an expression tree or delegate, returns the expression tree type Expression{T} or T.\n\t\t/// T is the delegate type that matches the signature of this method.\n\t\t/// Otherwise this must be null.\n\t\t/// </summary>\n\t\tpublic IType? DelegateType;\n\n\t\tILFunctionKind kind;\n\n\t\t/// <summary>\n\t\t/// Gets which kind of function this is.\n\t\t/// </summary>\n\t\tpublic ILFunctionKind Kind {\n\t\t\tget => kind;\n\t\t\tinternal set {\n\t\t\t\tif (kind == ILFunctionKind.TopLevelFunction || kind == ILFunctionKind.LocalFunction)\n\t\t\t\t\tthrow new InvalidOperationException(\"ILFunction.Kind of a top-level or local function may not be changed.\");\n\t\t\t\tkind = value;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Return type of this function.\n\t\t/// </summary>\n\t\tpublic readonly IType ReturnType;\n\n\t\t/// <summary>\n\t\t/// List of parameters of this function.\n\t\t/// </summary>\n\t\tpublic readonly IReadOnlyList<IParameter> Parameters;\n\n\t\t/// <summary>\n\t\t/// List of candidate locations for sequence points. Includes any offset\n\t\t/// where the stack is empty, nop instructions, and the instruction following\n\t\t/// a call instruction\n\t\t/// </summary>\n\t\tpublic List<int>? SequencePointCandidates { get; set; }\n\n\t\t/// <summary>\n\t\t/// Constructs a new ILFunction from the given metadata and with the given ILAst body.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Use <see cref=\"ILReader\"/> to create ILAst.\n\t\t/// </remarks>\n\t\tpublic ILFunction(IMethod method, int codeSize, GenericContext genericContext, ILInstruction body, ILFunctionKind kind = ILFunctionKind.TopLevelFunction) : base(OpCode.ILFunction)\n\t\t{\n\t\t\tthis.Method = method;\n\t\t\tthis.Name = method.Name;\n\t\t\tthis.CodeSize = codeSize;\n\t\t\tthis.GenericContext = genericContext;\n\t\t\tthis.Body = body;\n\t\t\tthis.ReturnType = method.ReturnType;\n\t\t\tthis.Parameters = method.Parameters;\n\t\t\tthis.Variables = new ILVariableCollection(this);\n\t\t\tthis.LocalFunctions = new InstructionCollection<ILFunction>(this, 1);\n\t\t\tthis.kind = kind;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// This constructor is only to be used by the TransformExpressionTrees step.\n\t\t/// </summary>\n\t\tinternal ILFunction(IType returnType, IReadOnlyList<IParameter> parameters, GenericContext genericContext, ILInstruction body, ILFunctionKind kind = ILFunctionKind.TopLevelFunction) : base(OpCode.ILFunction)\n\t\t{\n\t\t\tthis.GenericContext = genericContext;\n\t\t\tthis.Body = body;\n\t\t\tthis.ReturnType = returnType ?? throw new ArgumentNullException(nameof(returnType));\n\t\t\tthis.Parameters = parameters ?? throw new ArgumentNullException(nameof(parameters));\n\t\t\tthis.Variables = new ILVariableCollection(this);\n\t\t\tthis.LocalFunctions = new InstructionCollection<ILFunction>(this, 1);\n\t\t\tthis.kind = kind;\n\t\t}\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tswitch (kind)\n\t\t\t{\n\t\t\t\tcase ILFunctionKind.TopLevelFunction:\n\t\t\t\t\tDebug.Assert(Parent == null);\n\t\t\t\t\tDebug.Assert(DelegateType == null);\n\t\t\t\t\tDebug.Assert(DeclarationScope == null);\n\t\t\t\t\tDebug.Assert(Method != null);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ILFunctionKind.Delegate:\n\t\t\t\t\tDebug.Assert(DelegateType != null);\n\t\t\t\t\tDebug.Assert(DeclarationScope == null);\n\t\t\t\t\tDebug.Assert(!(DelegateType?.FullName == \"System.Linq.Expressions.Expression\" && DelegateType.TypeParameterCount == 1));\n\t\t\t\t\tbreak;\n\t\t\t\tcase ILFunctionKind.ExpressionTree:\n\t\t\t\t\tDebug.Assert(DelegateType != null);\n\t\t\t\t\tDebug.Assert(DeclarationScope == null);\n\t\t\t\t\tDebug.Assert(DelegateType?.FullName == \"System.Linq.Expressions.Expression\" && DelegateType.TypeParameterCount == 1);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ILFunctionKind.LocalFunction:\n\t\t\t\t\tDebug.Assert(Parent is ILFunction && SlotInfo == ILFunction.LocalFunctionsSlot);\n\t\t\t\t\tDebug.Assert(DeclarationScope != null);\n\t\t\t\t\tDebug.Assert(DelegateType == null);\n\t\t\t\t\tDebug.Assert(Method != null);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tfor (int i = 0; i < Variables.Count; i++)\n\t\t\t{\n\t\t\t\tDebug.Assert(Variables[i].Function == this);\n\t\t\t\tDebug.Assert(Variables[i].IndexInFunction == i);\n\t\t\t\tVariables[i].CheckInvariant();\n\t\t\t}\n\t\t\tbase.CheckInvariant(phase);\n\t\t}\n\n\t\tvoid CloneVariables()\n\t\t{\n\t\t\tthrow new NotSupportedException(\"ILFunction.CloneVariables is currently not supported!\");\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tif (Method != null)\n\t\t\t{\n\t\t\t\toutput.Write(' ');\n\t\t\t\tMethod.WriteTo(output);\n\t\t\t}\n\t\t\tswitch (kind)\n\t\t\t{\n\t\t\t\tcase ILFunctionKind.ExpressionTree:\n\t\t\t\t\toutput.Write(\".ET\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase ILFunctionKind.LocalFunction:\n\t\t\t\t\toutput.Write(\".local\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (DelegateType != null)\n\t\t\t{\n\t\t\t\toutput.Write(\"[\");\n\t\t\t\tDelegateType.WriteTo(output);\n\t\t\t\toutput.Write(\"]\");\n\t\t\t}\n\t\t\toutput.WriteLine(\" {\");\n\t\t\toutput.Indent();\n\n\t\t\tif (IsAsync)\n\t\t\t{\n\t\t\t\toutput.WriteLine(\".async\");\n\t\t\t}\n\t\t\tif (IsIterator)\n\t\t\t{\n\t\t\t\toutput.WriteLine(\".iterator\");\n\t\t\t}\n\t\t\tif (DeclarationScope != null)\n\t\t\t{\n\t\t\t\toutput.Write(\"declared as \" + Name + \" in \");\n\t\t\t\toutput.WriteLocalReference(DeclarationScope.EntryPoint.Label, DeclarationScope);\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\n\t\t\toutput.MarkFoldStart(Variables.Count + \" variable(s)\", true);\n\t\t\tforeach (var variable in Variables)\n\t\t\t{\n\t\t\t\tvariable.WriteDefinitionTo(output);\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t\toutput.MarkFoldEnd();\n\t\t\toutput.WriteLine();\n\n\t\t\tforeach (string warning in Warnings)\n\t\t\t{\n\t\t\t\toutput.WriteLine(\"//\" + warning);\n\t\t\t}\n\n\t\t\tbody.WriteTo(output, options);\n\t\t\toutput.WriteLine();\n\n\t\t\tforeach (var localFunction in LocalFunctions)\n\t\t\t{\n\t\t\t\toutput.WriteLine();\n\t\t\t\tlocalFunction.WriteTo(output, options);\n\t\t\t}\n\n\t\t\tif (options.ShowILRanges)\n\t\t\t{\n\t\t\t\tvar unusedILRanges = FindUnusedILRanges();\n\t\t\t\tif (!unusedILRanges.IsEmpty)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\"// Unused IL Ranges: \");\n\t\t\t\t\toutput.Write(string.Join(\", \", unusedILRanges.Intervals.Select(\n\t\t\t\t\t\trange => $\"[{range.Start:x4}..{range.InclusiveEnd:x4}]\")));\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\toutput.Unindent();\n\t\t\toutput.WriteLine(\"}\");\n\t\t}\n\n\t\tLongSet FindUnusedILRanges()\n\t\t{\n\t\t\tvar usedILRanges = new List<LongInterval>();\n\t\t\tMarkUsedILRanges(body);\n\t\t\treturn new LongSet(new LongInterval(0, CodeSize)).ExceptWith(new LongSet(usedILRanges));\n\n\t\t\tvoid MarkUsedILRanges(ILInstruction inst)\n\t\t\t{\n\t\t\t\tif (CSharp.SequencePointBuilder.HasUsableILRange(inst))\n\t\t\t\t{\n\t\t\t\t\tusedILRanges.Add(new LongInterval(inst.StartILOffset, inst.EndILOffset));\n\t\t\t\t}\n\t\t\t\tif (!(inst is ILFunction))\n\t\t\t\t{\n\t\t\t\t\tforeach (var child in inst.Children)\n\t\t\t\t\t{\n\t\t\t\t\t\tMarkUsedILRanges(child);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\t// Creating a lambda may throw OutOfMemoryException\n\t\t\t// We intentionally don't propagate any flags from the lambda body!\n\t\t\treturn InstructionFlags.MayThrow | InstructionFlags.ControlFlow;\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayThrow | InstructionFlags.ControlFlow;\n\t\t\t}\n\t\t}\n\n\t\tinternal override bool CanInlineIntoSlot(int childIndex, ILInstruction expressionBeingMoved)\n\t\t{\n\t\t\t// With expression trees, we occasionally need to inline constants into an existing expression tree.\n\t\t\t// Only allow this for completely pure constants; a MayReadLocals effect would already be problematic\n\t\t\t// because we're essentially delaying evaluation of the expression until the ILFunction is called.\n\t\t\tDebug.Assert(childIndex == 0);\n\t\t\treturn kind == ILFunctionKind.ExpressionTree && expressionBeingMoved.Flags == InstructionFlags.None;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Apply a list of transforms to this function.\n\t\t/// </summary>\n\t\tpublic void RunTransforms(IEnumerable<IILTransform> transforms, ILTransformContext context)\n\t\t{\n\t\t\tthis.CheckInvariant(ILPhase.Normal);\n\t\t\tforeach (var transform in transforms)\n\t\t\t{\n\t\t\t\tcontext.CancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tif (transform is BlockILTransform blockTransform)\n\t\t\t\t{\n\t\t\t\t\tcontext.StepStartGroup(blockTransform.ToString());\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcontext.StepStartGroup(transform.GetType().Name);\n\t\t\t\t}\n\t\t\t\ttransform.Run(this, context);\n\t\t\t\tthis.CheckInvariant(ILPhase.Normal);\n\t\t\t\tcontext.StepEndGroup(keepIfEmpty: true);\n\t\t\t}\n\t\t}\n\n\t\tint helperVariableCount;\n\n\t\tpublic ILVariable RegisterVariable(VariableKind kind, IType type, string? name = null)\n\t\t{\n\t\t\tvar variable = new ILVariable(kind, type);\n\t\t\tif (string.IsNullOrWhiteSpace(name))\n\t\t\t{\n\t\t\t\tname = \"I_\" + (helperVariableCount++);\n\t\t\t\tvariable.HasGeneratedName = true;\n\t\t\t}\n\t\t\tvariable.Name = name;\n\t\t\tVariables.Add(variable);\n\t\t\treturn variable;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Recombine split variables by replacing all occurrences of variable2 with variable1.\n\t\t/// </summary>\n\t\tinternal void RecombineVariables(ILVariable variable1, ILVariable variable2)\n\t\t{\n\t\t\tif (variable1 == variable2)\n\t\t\t\treturn;\n\t\t\tDebug.Assert(ILVariableEqualityComparer.Instance.Equals(variable1, variable2));\n\t\t\tforeach (var ldloc in variable2.LoadInstructions.ToArray())\n\t\t\t{\n\t\t\t\tldloc.Variable = variable1;\n\t\t\t}\n\t\t\tforeach (var store in variable2.StoreInstructions.ToArray())\n\t\t\t{\n\t\t\t\tstore.Variable = variable1;\n\t\t\t}\n\t\t\tforeach (var ldloca in variable2.AddressInstructions.ToArray())\n\t\t\t{\n\t\t\t\tldloca.Variable = variable1;\n\t\t\t}\n\t\t\tbool ok = Variables.Remove(variable2);\n\t\t\tDebug.Assert(ok);\n\t\t}\n\t}\n\n\tpublic enum ILFunctionKind\n\t{\n\t\t/// <summary>\n\t\t/// ILFunction is a \"top-level\" function, i.e., method, accessor, constructor, destructor or operator.\n\t\t/// </summary>\n\t\tTopLevelFunction,\n\t\t/// <summary>\n\t\t/// ILFunction is a delegate or lambda expression.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This kind is introduced by the DelegateConstruction and TransformExpressionTrees steps in the decompiler pipeline.\n\t\t/// </remarks>\n\t\tDelegate,\n\t\t/// <summary>\n\t\t/// ILFunction is an expression tree lambda.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This kind is introduced by the TransformExpressionTrees step in the decompiler pipeline.\n\t\t/// </remarks>\n\t\tExpressionTree,\n\t\t/// <summary>\n\t\t/// ILFunction is a C# 7.0 local function.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This kind is introduced by the LocalFunctionDecompiler step in the decompiler pipeline.\n\t\t/// </remarks>\n\t\tLocalFunction\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.IL.Patterns;\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tinternal enum ILPhase\n\t{\n\t\t/// <summary>\n\t\t/// Reading the individual instructions.\n\t\t/// * Variables don't have scopes yet as the ILFunction is not created yet.\n\t\t/// * Branches point to IL offsets, not blocks.\n\t\t/// </summary>\n\t\tInILReader,\n\t\t/// <summary>\n\t\t/// The usual invariants are established.\n\t\t/// </summary>\n\t\tNormal,\n\t\t/// <summary>\n\t\t/// Special phase within the async-await decompiler, where a few selected invariants\n\t\t/// are temporarily suspended. (see Leave.CheckInvariant)\n\t\t/// </summary>\n\t\tInAsyncAwait\n\t}\n\n\t/// <summary>\n\t/// Represents a decoded IL instruction\n\t/// </summary>\n\tpublic abstract partial class ILInstruction\n\t{\n\t\tpublic readonly OpCode OpCode;\n\n\t\tprotected ILInstruction(OpCode opCode)\n\t\t{\n\t\t\tthis.OpCode = opCode;\n\t\t}\n\n\t\tprotected void ValidateChild(ILInstruction? inst)\n\t\t{\n\t\t\tif (inst == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(inst));\n\t\t\tDebug.Assert(!this.IsDescendantOf(inst), \"ILAst must form a tree\");\n\t\t\t// If a call to ReplaceWith() triggers the \"ILAst must form a tree\" assertion,\n\t\t\t// make sure to read the remarks on the ReplaceWith() method.\n\t\t}\n\n\t\tinternal static void DebugAssert([DoesNotReturnIf(false)] bool b)\n\t\t{\n\t\t\tDebug.Assert(b);\n\t\t}\n\n\t\tinternal static void DebugAssert([DoesNotReturnIf(false)] bool b, string msg)\n\t\t{\n\t\t\tDebug.Assert(b, msg);\n\t\t}\n\n\t\t[Conditional(\"DEBUG\")]\n\t\tinternal virtual void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tforeach (var child in Children)\n\t\t\t{\n\t\t\t\tDebug.Assert(child.Parent == this);\n\t\t\t\tDebug.Assert(this.GetChild(child.ChildIndex) == child);\n\t\t\t\t// if child flags are invalid, parent flags must be too\n\t\t\t\t// exception: nested ILFunctions (lambdas)\n\t\t\t\tDebug.Assert(this is ILFunction || child.flags != invalidFlags || this.flags == invalidFlags);\n\t\t\t\tDebug.Assert(child.IsConnected == this.IsConnected);\n\t\t\t\tchild.CheckInvariant(phase);\n\t\t\t}\n\t\t\tDebug.Assert((this.DirectFlags & ~this.Flags) == 0, \"All DirectFlags must also appear in this.Flags\");\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this node is a descendant of <paramref name=\"possibleAncestor\"/>.\n\t\t/// Also returns true if <c>this</c>==<paramref name=\"possibleAncestor\"/>.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This method uses the <c>Parent</c> property, so it may produce surprising results\n\t\t/// when called on orphaned nodes or with a possibleAncestor that contains stale positions\n\t\t/// (see remarks on Parent property).\n\t\t/// </remarks>\n\t\tpublic bool IsDescendantOf(ILInstruction possibleAncestor)\n\t\t{\n\t\t\tfor (ILInstruction? ancestor = this; ancestor != null; ancestor = ancestor.Parent)\n\t\t\t{\n\t\t\t\tif (ancestor == possibleAncestor)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic ILInstruction? GetCommonParent(ILInstruction other)\n\t\t{\n\t\t\tif (other == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(other));\n\n\t\t\tILInstruction? a = this;\n\t\t\tILInstruction? b = other;\n\n\t\t\tint levelA = a.CountAncestors();\n\t\t\tint levelB = b.CountAncestors();\n\n\t\t\twhile (levelA > levelB)\n\t\t\t{\n\t\t\t\ta = a!.Parent;\n\t\t\t\tlevelA--;\n\t\t\t}\n\n\t\t\twhile (levelB > levelA)\n\t\t\t{\n\t\t\t\tb = b!.Parent;\n\t\t\t\tlevelB--;\n\t\t\t}\n\n\t\t\twhile (a != b)\n\t\t\t{\n\t\t\t\ta = a!.Parent;\n\t\t\t\tb = b!.Parent;\n\t\t\t}\n\n\t\t\treturn a;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns whether this appears before other in a post-order walk of the whole tree.\n\t\t/// </summary>\n\t\tpublic bool IsBefore(ILInstruction other)\n\t\t{\n\t\t\tif (other == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(other));\n\n\t\t\tILInstruction a = this;\n\t\t\tILInstruction b = other;\n\n\t\t\tint levelA = a.CountAncestors();\n\t\t\tint levelB = b.CountAncestors();\n\n\t\t\tint originalLevelA = levelA;\n\t\t\tint originalLevelB = levelB;\n\n\t\t\twhile (levelA > levelB)\n\t\t\t{\n\t\t\t\ta = a.Parent!;\n\t\t\t\tlevelA--;\n\t\t\t}\n\n\t\t\twhile (levelB > levelA)\n\t\t\t{\n\t\t\t\tb = b.Parent!;\n\t\t\t\tlevelB--;\n\t\t\t}\n\n\t\t\tif (a == b)\n\t\t\t{\n\t\t\t\t// a or b is a descendant of the other,\n\t\t\t\t// whichever node has the higher level comes first in post-order walk.\n\t\t\t\treturn originalLevelA > originalLevelB;\n\t\t\t}\n\n\t\t\twhile (a.Parent != b.Parent)\n\t\t\t{\n\t\t\t\ta = a.Parent!;\n\t\t\t\tb = b.Parent!;\n\t\t\t}\n\n\t\t\t// now a and b have the same parent or are both root nodes\n\t\t\treturn a.ChildIndex < b.ChildIndex;\n\t\t}\n\n\t\tprivate int CountAncestors()\n\t\t{\n\t\t\tint level = 0;\n\t\t\tfor (ILInstruction? ancestor = this; ancestor != null; ancestor = ancestor.Parent)\n\t\t\t{\n\t\t\t\tlevel++;\n\t\t\t}\n\t\t\treturn level;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the stack type of the value produced by this instruction.\n\t\t/// </summary>\n\t\tpublic abstract StackType ResultType { get; }\n\n\t\t/* Not sure if it's a good idea to offer this on all instructions --\n\t\t *   e.g. ldloc for a local of type `int?` would return StackType.O (because it's not a lifted operation),\n\t\t *   even though the underlying type is int = StackType.I4.\n\t\t/// <summary>\n\t\t/// Gets the underlying result type of the value produced by this instruction.\n\t\t/// \n\t\t/// If this is a lifted operation, the ResultType will be `StackType.O` (because Nullable{T} is a struct),\n\t\t/// and UnderlyingResultType will be result type of the corresponding non-lifted operation.\n\t\t/// \n\t\t/// If this is not a lifted operation, the underlying result type is equal to the result type.\n\t\t/// </summary>\n\t\tpublic virtual StackType UnderlyingResultType { get => ResultType; }\n\t\t*/\n\n\t\tinternal static StackType CommonResultType(StackType a, StackType b)\n\t\t{\n\t\t\tif (a == StackType.I || b == StackType.I)\n\t\t\t\treturn StackType.I;\n\t\t\tDebug.Assert(a == b);\n\t\t\treturn a;\n\t\t}\n\n#if DEBUG\n\t\t/// <summary>\n\t\t/// Gets whether this node (or any subnode) was modified since the last <c>ResetDirty()</c> call.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// IsDirty is used by the StatementTransform, and must not be used by individual transforms within the loop.\n\t\t/// </remarks>\n\t\tinternal bool IsDirty { get; private set; }\n\n\t\t/// <summary>\n\t\t/// Marks this node (and all subnodes) as <c>IsDirty=false</c>.\n\t\t/// </summary>\n\t\tinternal void ResetDirty()\n\t\t{\n\t\t\tforeach (ILInstruction inst in Descendants)\n\t\t\t\tinst.IsDirty = false;\n\t\t}\n#endif\n\n\t\t[Conditional(\"DEBUG\")]\n\t\tprotected private void MakeDirty()\n\t\t{\n#if DEBUG\n\t\t\tfor (ILInstruction? inst = this; inst != null && !inst.IsDirty; inst = inst.parent)\n\t\t\t{\n\t\t\t\tinst.IsDirty = true;\n\t\t\t}\n#endif\n\t\t}\n\n\t\tconst InstructionFlags invalidFlags = (InstructionFlags)(-1);\n\n\t\tInstructionFlags flags = invalidFlags;\n\n\t\t/// <summary>\n\t\t/// Gets the flags describing the behavior of this instruction.\n\t\t/// This property computes the flags on-demand and caches them\n\t\t/// until some change to the ILAst invalidates the cache.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Flag cache invalidation makes use of the <c>Parent</c> property,\n\t\t/// so it is possible for this property to return a stale value\n\t\t/// if the instruction contains \"stale positions\" (see remarks on Parent property).\n\t\t/// </remarks>\n\t\tpublic InstructionFlags Flags {\n\t\t\tget {\n\t\t\t\tif (flags == invalidFlags)\n\t\t\t\t{\n\t\t\t\t\tflags = ComputeFlags();\n\t\t\t\t}\n\t\t\t\treturn flags;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns whether the instruction (or one of its child instructions) has at least one of the specified flags.\n\t\t/// </summary>\n\t\tpublic bool HasFlag(InstructionFlags flags)\n\t\t{\n\t\t\treturn (this.Flags & flags) != 0;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns whether the instruction (without considering child instructions) has at least one of the specified flags.\n\t\t/// </summary>\n\t\tpublic bool HasDirectFlag(InstructionFlags flags)\n\t\t{\n\t\t\treturn (this.DirectFlags & flags) != 0;\n\t\t}\n\n\t\tprotected void InvalidateFlags()\n\t\t{\n\t\t\tfor (ILInstruction? inst = this; inst != null && inst.flags != invalidFlags; inst = inst.parent)\n\t\t\t\tinst.flags = invalidFlags;\n\t\t}\n\n\t\tprotected abstract InstructionFlags ComputeFlags();\n\n\t\t/// <summary>\n\t\t/// Gets the flags for this instruction only, without considering the child instructions.\n\t\t/// </summary>\n\t\tpublic abstract InstructionFlags DirectFlags { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the ILRange for this instruction alone, ignoring the operands.\n\t\t/// </summary>\n\t\tprivate Interval ILRange;\n\n\t\tpublic void AddILRange(Interval newRange)\n\t\t{\n\t\t\tthis.ILRange = CombineILRange(this.ILRange, newRange);\n\t\t}\n\n\t\tprotected static Interval CombineILRange(Interval oldRange, Interval newRange)\n\t\t{\n\t\t\tif (oldRange.IsEmpty)\n\t\t\t{\n\t\t\t\treturn newRange;\n\t\t\t}\n\t\t\tif (newRange.IsEmpty)\n\t\t\t{\n\t\t\t\treturn oldRange;\n\t\t\t}\n\t\t\tif (newRange.Start <= oldRange.Start)\n\t\t\t{\n\t\t\t\tif (newRange.End < oldRange.Start)\n\t\t\t\t{\n\t\t\t\t\treturn newRange; // use the earlier range\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// join overlapping ranges\n\t\t\t\t\treturn new Interval(newRange.Start, Math.Max(newRange.End, oldRange.End));\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (newRange.Start <= oldRange.End)\n\t\t\t{\n\t\t\t\t// join overlapping ranges\n\t\t\t\treturn new Interval(oldRange.Start, Math.Max(newRange.End, oldRange.End));\n\t\t\t}\n\t\t\treturn oldRange;\n\t\t}\n\n\t\tpublic void AddILRange(ILInstruction sourceInstruction)\n\t\t{\n\t\t\tAddILRange(sourceInstruction.ILRange);\n\t\t}\n\n\t\tpublic void SetILRange(ILInstruction sourceInstruction)\n\t\t{\n\t\t\tILRange = sourceInstruction.ILRange;\n\t\t}\n\n\t\tpublic void SetILRange(Interval range)\n\t\t{\n\t\t\tILRange = range;\n\t\t}\n\n\t\tpublic int StartILOffset => ILRange.Start;\n\n\t\tpublic int EndILOffset => ILRange.End;\n\n\t\tpublic bool ILRangeIsEmpty => ILRange.IsEmpty;\n\n\t\tpublic IEnumerable<Interval> ILRanges => new[] { ILRange };\n\n\t\tpublic void WriteILRange(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tILRange.WriteTo(output, options);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Writes the ILAst to the text output.\n\t\t/// </summary>\n\t\tpublic abstract void WriteTo(ITextOutput output, ILAstWritingOptions options);\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tvar output = new PlainTextOutput();\n\t\t\tWriteTo(output, new ILAstWritingOptions());\n\t\t\tif (!ILRange.IsEmpty)\n\t\t\t{\n\t\t\t\toutput.Write(\" at IL_\" + ILRange.Start.ToString(\"x4\"));\n\t\t\t}\n\t\t\treturn output.ToString();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Calls the Visit*-method on the visitor corresponding to the concrete type of this instruction.\n\t\t/// </summary>\n\t\tpublic abstract void AcceptVisitor(ILVisitor visitor);\n\n\t\t/// <summary>\n\t\t/// Calls the Visit*-method on the visitor corresponding to the concrete type of this instruction.\n\t\t/// </summary>\n\t\tpublic abstract T AcceptVisitor<T>(ILVisitor<T> visitor);\n\n\t\t/// <summary>\n\t\t/// Calls the Visit*-method on the visitor corresponding to the concrete type of this instruction.\n\t\t/// </summary>\n\t\tpublic abstract T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context);\n\n\t\t/// <summary>\n\t\t/// Gets the child nodes of this instruction.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// The ChildrenCollection does not actually store the list of children,\n\t\t/// it merely allows accessing the children stored in the various slots.\n\t\t/// </remarks>\n\t\tpublic ChildrenCollection Children {\n\t\t\tget {\n\t\t\t\treturn new ChildrenCollection(this);\n\t\t\t}\n\t\t}\n\n\t\tprotected abstract int GetChildCount();\n\t\tprotected abstract ILInstruction GetChild(int index);\n\t\tprotected abstract void SetChild(int index, ILInstruction value);\n\t\tprotected abstract SlotInfo GetChildSlot(int index);\n\n\t\t#region ChildrenCollection + ChildrenEnumerator\n\t\tpublic readonly struct ChildrenCollection : IReadOnlyList<ILInstruction>\n\t\t{\n\t\t\treadonly ILInstruction inst;\n\n\t\t\tinternal ChildrenCollection(ILInstruction inst)\n\t\t\t{\n\t\t\t\tDebug.Assert(inst != null);\n\t\t\t\tthis.inst = inst!;\n\t\t\t}\n\n\t\t\tpublic int Count {\n\t\t\t\tget { return inst.GetChildCount(); }\n\t\t\t}\n\n\t\t\tpublic ILInstruction this[int index] {\n\t\t\t\tget { return inst.GetChild(index); }\n\t\t\t\tset { inst.SetChild(index, value); }\n\t\t\t}\n\n\t\t\tpublic ChildrenEnumerator GetEnumerator()\n\t\t\t{\n\t\t\t\treturn new ChildrenEnumerator(inst);\n\t\t\t}\n\n\t\t\tIEnumerator<ILInstruction> IEnumerable<ILInstruction>.GetEnumerator()\n\t\t\t{\n\t\t\t\treturn GetEnumerator();\n\t\t\t}\n\n\t\t\tSystem.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\n\t\t\t{\n\t\t\t\treturn GetEnumerator();\n\t\t\t}\n\t\t}\n\n#if DEBUG\n\t\tint activeEnumerators;\n\n\t\t[Conditional(\"DEBUG\")]\n\t\tinternal void StartEnumerator()\n\t\t{\n\t\t\tactiveEnumerators++;\n\t\t}\n\n\t\t[Conditional(\"DEBUG\")]\n\t\tinternal void StopEnumerator()\n\t\t{\n\t\t\tDebug.Assert(activeEnumerators > 0);\n\t\t\tactiveEnumerators--;\n\t\t}\n#endif\n\n\t\t[Conditional(\"DEBUG\")]\n\t\tinternal void AssertNoEnumerators()\n\t\t{\n#if DEBUG\n\t\t\tDebug.Assert(activeEnumerators == 0);\n#endif\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Enumerator over the children of an ILInstruction.\n\t\t/// Warning: even though this is a struct, it is invalid to copy:\n\t\t/// the number of constructor calls must match the number of dispose calls.\n\t\t/// </summary>\n\t\tpublic struct ChildrenEnumerator : IEnumerator<ILInstruction>\n\t\t{\n\t\t\tILInstruction? inst;\n\t\t\treadonly int end;\n\t\t\tint pos;\n\n\t\t\tinternal ChildrenEnumerator(ILInstruction inst)\n\t\t\t{\n\t\t\t\tDebugAssert(inst != null);\n\t\t\t\tthis.inst = inst;\n\t\t\t\tthis.pos = -1;\n\t\t\t\tthis.end = inst!.GetChildCount();\n#if DEBUG\n\t\t\t\tinst.StartEnumerator();\n#endif\n\t\t\t}\n\n\t\t\tpublic ILInstruction Current {\n\t\t\t\tget {\n\t\t\t\t\treturn inst!.GetChild(pos);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic bool MoveNext()\n\t\t\t{\n\t\t\t\treturn ++pos < end;\n\t\t\t}\n\n\t\t\tpublic void Dispose()\n\t\t\t{\n#if DEBUG\n\t\t\t\tif (inst != null)\n\t\t\t\t{\n\t\t\t\t\tinst.StopEnumerator();\n\t\t\t\t\tinst = null;\n\t\t\t\t}\n#endif\n\t\t\t}\n\n\t\t\tobject System.Collections.IEnumerator.Current {\n\t\t\t\tget { return this.Current; }\n\t\t\t}\n\n\t\t\tvoid System.Collections.IEnumerator.Reset()\n\t\t\t{\n\t\t\t\tpos = -1;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t/// <summary>\n\t\t/// Replaces this ILInstruction with the given replacement instruction.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// It is temporarily possible for a node to be used in multiple places in the ILAst,\n\t\t/// this method only replaces this node at its primary position (see remarks on <see cref=\"Parent\"/>).\n\t\t/// \n\t\t/// This means you cannot use ReplaceWith() to wrap an instruction in another node.\n\t\t/// For example, <c>node.ReplaceWith(new BitNot(node))</c> will first call the BitNot constructor,\n\t\t/// which sets <c>node.Parent</c> to the BitNot instance.\n\t\t/// The ReplaceWith() call then attempts to set <c>BitNot.Argument</c> to the BitNot instance,\n\t\t/// which creates a cyclic ILAst. Meanwhile, node's original parent remains unmodified.\n\t\t/// \n\t\t/// The solution in this case is to avoid using <c>ReplaceWith</c>.\n\t\t/// If the parent node is unknown, the following trick can be used:\n\t\t/// <code>\n\t\t/// node.Parent.Children[node.ChildIndex] = new BitNot(node);\n\t\t/// </code>\n\t\t/// Unlike the <c>ReplaceWith()</c> call, this will evaluate <c>node.Parent</c> and <c>node.ChildIndex</c>\n\t\t/// before the <c>BitNot</c> constructor is called, thus modifying the expected position in the ILAst.\n\t\t/// </remarks>\n\t\tpublic void ReplaceWith(ILInstruction replacement)\n\t\t{\n\t\t\tDebug.Assert(parent!.GetChild(ChildIndex) == this);\n\t\t\tif (replacement == this)\n\t\t\t\treturn;\n\t\t\tparent.SetChild(ChildIndex, replacement);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns all descendants of the ILInstruction in post-order.\n\t\t/// (including the ILInstruction itself)\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Within a loop 'foreach (var node in inst.Descendants)', it is illegal to\n\t\t/// add or remove from the child collections of node's ancestors, as those are\n\t\t/// currently being enumerated.\n\t\t/// Note that it is valid to modify node's children as those were already previously visited.\n\t\t/// As a special case, it is also allowed to replace node itself with another node.\n\t\t/// </remarks>\n\t\tpublic IEnumerable<ILInstruction> Descendants {\n\t\t\tget {\n\t\t\t\t// Copy of TreeTraversal.PostOrder() specialized for ChildrenEnumerator\n\t\t\t\t// We could potentially eliminate the stack by using Parent/ChildIndex,\n\t\t\t\t// but that makes it difficult to reason about the behavior in the cases\n\t\t\t\t// where Parent/ChildIndex is not accurate (stale positions), especially\n\t\t\t\t// if the ILAst is modified during enumeration.\n\t\t\t\tStack<ChildrenEnumerator> stack = new Stack<ChildrenEnumerator>();\n\t\t\t\tChildrenEnumerator enumerator = new ChildrenEnumerator(this);\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\twhile (true)\n\t\t\t\t\t{\n\t\t\t\t\t\twhile (enumerator.MoveNext())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar element = enumerator.Current;\n\t\t\t\t\t\t\tstack.Push(enumerator);\n\t\t\t\t\t\t\tenumerator = new ChildrenEnumerator(element);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tenumerator.Dispose();\n\t\t\t\t\t\tif (stack.Count > 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tenumerator = stack.Pop();\n\t\t\t\t\t\t\tyield return enumerator.Current;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tenumerator.Dispose();\n\t\t\t\t\twhile (stack.Count > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tstack.Pop().Dispose();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tyield return this;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the ancestors of this node (including the node itself as first element).\n\t\t/// </summary>\n\t\tpublic IEnumerable<ILInstruction> Ancestors {\n\t\t\tget {\n\t\t\t\tfor (ILInstruction? node = this; node != null; node = node.Parent)\n\t\t\t\t{\n\t\t\t\t\tyield return node;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Number of parents that refer to this instruction and are connected to the root.\n\t\t/// Usually is 0 for unconnected nodes and 1 for connected nodes, but may temporarily increase to 2\n\t\t/// when the ILAst is re-arranged (e.g. within SetChildInstruction),\n\t\t/// or possibly even more (re-arrangement with stale positions).\n\t\t/// </summary>\n\t\tbyte refCount;\n\n\t\tinternal void AddRef()\n\t\t{\n\t\t\tif (refCount++ == 0)\n\t\t\t{\n\t\t\t\tConnected();\n\t\t\t}\n\t\t}\n\n\t\tinternal void ReleaseRef()\n\t\t{\n\t\t\tDebug.Assert(refCount > 0);\n\t\t\tif (--refCount == 0)\n\t\t\t{\n\t\t\t\tDisconnected();\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this ILInstruction is connected to the root node of the ILAst.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This property returns true if the ILInstruction is reachable from the root node\n\t\t/// of the ILAst; it does not make use of the <c>Parent</c> field so the considerations\n\t\t/// about orphaned nodes and stale positions don't apply.\n\t\t/// </remarks>\n\t\tprotected internal bool IsConnected {\n\t\t\tget { return refCount > 0; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Called after the ILInstruction was connected to the root node of the ILAst.\n\t\t/// </summary>\n\t\tprotected virtual void Connected()\n\t\t{\n\t\t\tforeach (var child in Children)\n\t\t\t\tchild.AddRef();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Called after the ILInstruction was disconnected from the root node of the ILAst.\n\t\t/// </summary>\n\t\tprotected virtual void Disconnected()\n\t\t{\n\t\t\tforeach (var child in Children)\n\t\t\t\tchild.ReleaseRef();\n\t\t}\n\n\t\tILInstruction? parent;\n\n\t\t/// <summary>\n\t\t/// Gets the parent of this ILInstruction.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// It is temporarily possible for a node to be used in multiple places in the ILAst\n\t\t/// (making the ILAst a DAG instead of a tree).\n\t\t/// The <c>Parent</c> and <c>ChildIndex</c> properties are written whenever\n\t\t/// a node is stored in a slot.\n\t\t/// The node's occurrence in that slot is termed the \"primary position\" of the node,\n\t\t/// and all other (older) uses of the nodes are termed \"stale positions\".\n\t\t/// \n\t\t/// A consistent ILAst must not contain any stale positions.\n\t\t/// Debug builds of ILSpy check the ILAst for consistency after every IL transform.\n\t\t/// \n\t\t/// If a slot containing a node is overwritten with another node, the <c>Parent</c>\n\t\t/// and <c>ChildIndex</c> of the old node are not modified.\n\t\t/// This allows overwriting stale positions to restore consistency of the ILAst.\n\t\t/// \n\t\t/// If a \"primary position\" is overwritten, the <c>Parent</c> of the old node also remains unmodified.\n\t\t/// This makes the old node an \"orphaned node\".\n\t\t/// Orphaned nodes may later be added back to the ILAst (or can just be garbage-collected).\n\t\t/// \n\t\t/// Note that is it is possible (though unusual) for a stale position to reference an orphaned node.\n\t\t/// </remarks>\n\t\tpublic ILInstruction? Parent {\n\t\t\tget { return parent; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the index of this node in the <c>Parent.Children</c> collection.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// It is temporarily possible for a node to be used in multiple places in the ILAst,\n\t\t/// this property returns the index of the primary position of this node (see remarks on <see cref=\"Parent\"/>).\n\t\t/// </remarks>\n\t\tpublic int ChildIndex { get; internal set; } = -1;\n\n\t\t/// <summary>\n\t\t/// Gets information about the slot in which this instruction is stored.\n\t\t/// (i.e., the relation of this instruction to its parent instruction)\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// It is temporarily possible for a node to be used in multiple places in the ILAst,\n\t\t/// this property returns the slot of the primary position of this node (see remarks on <see cref=\"Parent\"/>).\n\t\t/// \n\t\t/// Precondition: this node must not be orphaned.\n\t\t/// </remarks>\n\t\tpublic SlotInfo? SlotInfo {\n\t\t\tget {\n\t\t\t\tif (parent == null)\n\t\t\t\t\treturn null;\n\t\t\t\tDebug.Assert(parent.GetChild(this.ChildIndex) == this);\n\t\t\t\treturn parent.GetChildSlot(this.ChildIndex);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Replaces a child of this ILInstruction.\n\t\t/// </summary>\n\t\t/// <param name=\"childPointer\">Reference to the field holding the child</param>\n\t\t/// <param name=\"newValue\">New child</param>\n\t\t/// <param name=\"index\">Index of the field in the Children collection</param>\n\t\tprotected internal void SetChildInstruction<T>(ref T childPointer, T newValue, int index)\n\t\t\twhere T : ILInstruction?\n\t\t{\n\t\t\tT oldValue = childPointer;\n\t\t\tDebug.Assert(oldValue == GetChild(index));\n\t\t\tif (oldValue == newValue && newValue?.parent == this && newValue.ChildIndex == index)\n\t\t\t\treturn;\n\t\t\tchildPointer = newValue;\n\t\t\tif (newValue != null)\n\t\t\t{\n\t\t\t\tnewValue.parent = this;\n\t\t\t\tnewValue.ChildIndex = index;\n\t\t\t}\n\t\t\tInvalidateFlags();\n\t\t\tMakeDirty();\n\t\t\tif (refCount > 0)\n\t\t\t{\n\t\t\t\t// The new value may be a subtree of the old value.\n\t\t\t\t// We first call AddRef(), then ReleaseRef() to prevent the subtree\n\t\t\t\t// that stays connected from receiving a Disconnected() notification followed by a Connected() notification.\n\t\t\t\tif (newValue != null)\n\t\t\t\t\tnewValue.AddRef();\n\t\t\t\tif (oldValue != null)\n\t\t\t\t\toldValue.ReleaseRef();\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Called when a new child is added to a InstructionCollection.\n\t\t/// </summary>\n\t\tprotected internal void InstructionCollectionAdded(ILInstruction newChild)\n\t\t{\n\t\t\tDebug.Assert(GetChild(newChild.ChildIndex) == newChild);\n\t\t\tDebug.Assert(!this.IsDescendantOf(newChild), \"ILAst must form a tree\");\n\t\t\t// If a call to ReplaceWith() triggers the \"ILAst must form a tree\" assertion,\n\t\t\t// make sure to read the remarks on the ReplaceWith() method.\n\t\t\tnewChild.parent = this;\n\t\t\tif (refCount > 0)\n\t\t\t\tnewChild.AddRef();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Called when a child is removed from a InstructionCollection.\n\t\t/// </summary>\n\t\tprotected internal void InstructionCollectionRemoved(ILInstruction oldChild)\n\t\t{\n\t\t\tif (refCount > 0)\n\t\t\t\toldChild.ReleaseRef();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Called when a series of add/remove operations on the InstructionCollection is complete.\n\t\t/// </summary>\n\t\tprotected internal virtual void InstructionCollectionUpdateComplete()\n\t\t{\n\t\t\tInvalidateFlags();\n\t\t\tMakeDirty();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a deep clone of the ILInstruction.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// It is valid to clone nodes with stale positions (see remarks on <c>Parent</c>);\n\t\t/// the result of such a clone will not contain any stale positions (nodes at\n\t\t/// multiple positions will be cloned once per position).\n\t\t/// </remarks>\n\t\tpublic abstract ILInstruction Clone();\n\n\t\t/// <summary>\n\t\t/// Creates a shallow clone of the ILInstruction.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Like MemberwiseClone(), except that the new instruction starts as disconnected.\n\t\t/// </remarks>\n\t\tprotected ILInstruction ShallowClone()\n\t\t{\n\t\t\tILInstruction inst = (ILInstruction)MemberwiseClone();\n\t\t\t// reset refCount and parent so that the cloned instruction starts as disconnected\n\t\t\tinst.refCount = 0;\n\t\t\tinst.parent = null;\n\t\t\tinst.flags = invalidFlags;\n#if DEBUG\n\t\t\tinst.activeEnumerators = 0;\n#endif\n\t\t\treturn inst;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Attempts to match the specified node against the pattern.\n\t\t/// </summary>\n\t\t/// <c>this</c>: The syntactic pattern.\n\t\t/// <param name=\"node\">The syntax node to test against the pattern.</param>\n\t\t/// <returns>\n\t\t/// Returns a match object describing the result of the matching operation.\n\t\t/// Check the <see cref=\"Match.Success\"/> property to see whether the match was successful.\n\t\t/// For successful matches, the match object allows retrieving the nodes that were matched with the captured groups.\n\t\t/// </returns>\n\t\tpublic Match Match(ILInstruction node)\n\t\t{\n\t\t\tMatch match = new Match();\n\t\t\tmatch.Success = PerformMatch(node, ref match);\n\t\t\treturn match;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Attempts matching this instruction against the other instruction.\n\t\t/// </summary>\n\t\t/// <param name=\"other\">The instruction to compare with.</param>\n\t\t/// <param name=\"match\">The match object, used to store global state during the match (such as the results of capture groups).</param>\n\t\t/// <returns>Returns whether the (partial) match was successful.\n\t\t/// If the method returns true, it adds the capture groups (if any) to the match.\n\t\t/// If the method returns false, the match object may remain in a partially-updated state and\n\t\t/// needs to be restored before it can be reused.</returns>\n\t\tprotected internal abstract bool PerformMatch(ILInstruction? other, ref Match match);\n\n\t\t/// <summary>\n\t\t/// Attempts matching this instruction against a list of other instructions (or a part of said list).\n\t\t/// </summary>\n\t\t/// <param name=\"listMatch\">Stores state about the current list match.</param>\n\t\t/// <param name=\"match\">The match object, used to store global state during the match (such as the results of capture groups).</param>\n\t\t/// <returns>Returns whether the (partial) match was successful.\n\t\t/// If the method returns true, it updates listMatch.SyntaxIndex to point to the next node that was not part of the match,\n\t\t/// and adds the capture groups (if any) to the match.\n\t\t/// If the method returns false, the listMatch and match objects remain in a partially-updated state and need to be restored\n\t\t/// before they can be reused.</returns>\n\t\tprotected internal virtual bool PerformMatch(ref ListMatch listMatch, ref Match match)\n\t\t{\n\t\t\t// Base implementation expects the node to match a single element.\n\t\t\t// Any patterns matching 0 or more than 1 element must override this method.\n\t\t\tif (listMatch.SyntaxIndex < listMatch.SyntaxList.Count)\n\t\t\t{\n\t\t\t\tif (PerformMatch(listMatch.SyntaxList[listMatch.SyntaxIndex], ref match))\n\t\t\t\t{\n\t\t\t\t\tlistMatch.SyntaxIndex++;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Extracts the this instruction.\n\t\t///   The instruction is replaced with a load of a new temporary variable;\n\t\t///   and the instruction is moved to a store to said variable at block-level.\n\t\t///   Returns the new variable.\n\t\t/// \n\t\t/// If extraction is not possible, the ILAst is left unmodified and the function returns null.\n\t\t/// May return null if extraction is not possible.\n\t\t/// </summary>\n\t\tpublic ILVariable? Extract(ILTransformContext context)\n\t\t{\n\t\t\treturn Transforms.ExtractionContext.Extract(this, context);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Prepares \"extracting\" a descendant instruction out of this instruction.\n\t\t/// This is the opposite of ILInlining. It may involve re-compiling high-level constructs into lower-level constructs.\n\t\t/// </summary>\n\t\t/// <returns>True if extraction is possible; false otherwise.</returns>\n\t\tinternal virtual bool PrepareExtract(int childIndex, Transforms.ExtractionContext ctx)\n\t\t{\n\t\t\tif (!GetChildSlot(childIndex).CanInlineInto)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Check whether re-ordering with predecessors is valid:\n\t\t\tfor (int i = childIndex - 1; i >= 0; --i)\n\t\t\t{\n\t\t\t\tILInstruction predecessor = GetChild(i);\n\t\t\t\tif (!GetChildSlot(i).CanInlineInto)\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tctx.RegisterMoveIfNecessary(predecessor);\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the expressionBeingMoved, which previously executes prior to `this`,\n\t\t/// may be moved into a descendant of the specified slot.\n\t\t/// (i.e. this controls whether FindLoadInNext may descent into the specified slot)\n\t\t/// \n\t\t/// Note: this does not check whether reordering with the previous slots is valid; only whether the target slot supports inlining at all!\n\t\t/// </summary>\n\t\tinternal virtual bool CanInlineIntoSlot(int childIndex, ILInstruction expressionBeingMoved)\n\t\t{\n\t\t\treturn GetChildSlot(childIndex).CanInlineInto;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Some slots in the ILAst have restrictions on which instructions can appear in them.\n\t\t/// Used to suppress inlining if the new child does not satisfy the restrictions.\n\t\t/// Unlike `CanInlineIntoSlot`, this is not about descendants of the slot, only about\n\t\t/// whether SetChild(childIndex, newChild) is valid.\n\t\t/// (i.e. this controls whether FindLoadInNext may return the specified slot as a final result)\n\t\t/// \n\t\t/// Warning: after newChild is inlined, other nodes may be inlined into newChild's sub-instructions\n\t\t/// without asking this function again. This means this function is not suitable for protecting\n\t\t/// a slot from having side effects, use `CanInlineIntoSlot` for that.\n\t\t/// </summary>\n\t\tinternal virtual bool SatisfiesSlotRestrictionForInlining(int childIndex, ILInstruction newChild)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic interface IInstructionWithTypeOperand\n\t{\n\t\tIType Type { get; }\n\t}\n\n\tpublic interface IInstructionWithFieldOperand\n\t{\n\t\tIField Field { get; }\n\t}\n\n\tpublic interface IInstructionWithMethodOperand\n\t{\n\t\tIMethod? Method { get; }\n\t}\n\n\tpublic interface ILiftableInstruction\n\t{\n\t\t/// <summary>\n\t\t/// Gets whether the instruction was lifted; that is, whether is accepts\n\t\t/// potentially nullable arguments.\n\t\t/// </summary>\n\t\tbool IsLifted { get; }\n\n\t\t/// <summary>\n\t\t/// If the instruction is lifted and returns a nullable result,\n\t\t/// gets the underlying result type.\n\t\t/// \n\t\t/// Note that not all lifted instructions return a nullable result:\n\t\t/// C# comparisons always return a bool!\n\t\t/// </summary>\n\t\tStackType UnderlyingResultType { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/ILVariableCollection.cs",
    "content": "#nullable enable\n// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// The collection of variables in a <c>ILFunction</c>.\n\t/// </summary>\n\tpublic class ILVariableCollection : ICollection<ILVariable>, IReadOnlyList<ILVariable>\n\t{\n\t\treadonly ILFunction scope;\n\t\treadonly List<ILVariable> list = new List<ILVariable>();\n\n\t\tinternal ILVariableCollection(ILFunction scope)\n\t\t{\n\t\t\tthis.scope = scope;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a variable given its <c>IndexInFunction</c>.\n\t\t/// </summary>\n\t\tpublic ILVariable this[int index] {\n\t\t\tget {\n\t\t\t\treturn list[index];\n\t\t\t}\n\t\t}\n\n\t\tpublic bool Add(ILVariable item)\n\t\t{\n\t\t\tif (item.Function != null)\n\t\t\t{\n\t\t\t\tif (item.Function == scope)\n\t\t\t\t\treturn false;\n\t\t\t\telse\n\t\t\t\t\tthrow new ArgumentException(\"Variable already belongs to another scope\");\n\t\t\t}\n\t\t\titem.Function = scope;\n\t\t\titem.IndexInFunction = list.Count;\n\t\t\tlist.Add(item);\n\t\t\treturn true;\n\t\t}\n\n\t\tvoid ICollection<ILVariable>.Add(ILVariable item)\n\t\t{\n\t\t\tAdd(item);\n\t\t}\n\n\t\tpublic void Clear()\n\t\t{\n\t\t\tforeach (var v in list)\n\t\t\t{\n\t\t\t\tv.Function = null;\n\t\t\t}\n\t\t\tlist.Clear();\n\t\t}\n\n\t\tpublic bool Contains(ILVariable item)\n\t\t{\n\t\t\tDebug.Assert(item.Function != scope || list[item.IndexInFunction] == item);\n\t\t\treturn item.Function == scope;\n\t\t}\n\n\t\tpublic bool Remove(ILVariable item)\n\t\t{\n\t\t\tif (item.Function != scope)\n\t\t\t\treturn false;\n\t\t\tDebug.Assert(list[item.IndexInFunction] == item);\n\t\t\tRemoveAt(item.IndexInFunction);\n\t\t\treturn true;\n\t\t}\n\n\t\tvoid RemoveAt(int index)\n\t\t{\n\t\t\tlist[index].Function = null;\n\t\t\t// swap-remove index\n\t\t\tlist[index] = list[list.Count - 1];\n\t\t\tlist[index].IndexInFunction = index;\n\t\t\tlist.RemoveAt(list.Count - 1);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Remove variables that have StoreCount == LoadCount == AddressCount == 0.\n\t\t/// </summary>\n\t\tpublic void RemoveDead()\n\t\t{\n\t\t\tfor (int i = 0; i < list.Count;)\n\t\t\t{\n\t\t\t\tif (ShouldRemoveVariable(list[i]))\n\t\t\t\t{\n\t\t\t\t\tRemoveAt(i);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tstatic bool ShouldRemoveVariable(ILVariable v)\n\t\t\t{\n\t\t\t\tif (!v.IsDead)\n\t\t\t\t\treturn false;\n\t\t\t\t// Note: we cannot remove display-class locals from the collection,\n\t\t\t\t// even if they are unused - which is always the case, if TDCU succeeds,\n\t\t\t\t// because they are necessary for PDB generation to produce correct results.\n\t\t\t\tif (v.Kind == VariableKind.DisplayClassLocal)\n\t\t\t\t\treturn false;\n\t\t\t\t// Do not remove parameter variables, as these are defined even if unused.\n\t\t\t\tif (v.Kind == VariableKind.Parameter)\n\t\t\t\t{\n\t\t\t\t\t// However, remove unused this-parameters of delegates, expression trees, etc.\n\t\t\t\t\t// These will be replaced with the top-level function's this-parameter.\n\t\t\t\t\tif (v.Index == -1 && v.Function!.Kind != ILFunctionKind.TopLevelFunction)\n\t\t\t\t\t\treturn true;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tpublic int Count {\n\t\t\tget { return list.Count; }\n\t\t}\n\n\t\tpublic void CopyTo(ILVariable[] array, int arrayIndex)\n\t\t{\n\t\t\tlist.CopyTo(array, arrayIndex);\n\t\t}\n\n\t\tbool ICollection<ILVariable>.IsReadOnly {\n\t\t\tget { return false; }\n\t\t}\n\n\t\tpublic List<ILVariable>.Enumerator GetEnumerator()\n\t\t{\n\t\t\treturn list.GetEnumerator();\n\t\t}\n\n\t\tIEnumerator<ILVariable> IEnumerable<ILVariable>.GetEnumerator()\n\t\t{\n\t\t\treturn GetEnumerator();\n\t\t}\n\n\t\tSystem.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\n\t\t{\n\t\t\treturn GetEnumerator();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>If statement / conditional expression. <c>if (condition) trueExpr else falseExpr</c></summary>\n\t/// <remarks>\n\t/// The condition must return StackType.I4, use comparison instructions like Ceq to check if other types are non-zero.\n\t///\n\t/// If the condition evaluates to non-zero, the TrueInst is executed.\n\t/// If the condition evaluates to zero, the FalseInst is executed.\n\t/// The return value of the IfInstruction is the return value of the TrueInst or FalseInst.\n\t/// \n\t/// IfInstruction is also used to represent logical operators:\n\t///   \"a || b\" ==> if (a) (ldc.i4 1) else (b)\n\t///   \"a &amp;&amp; b\" ==> if (a) (b) else (ldc.i4 0)\n\t///   \"a ? b : c\" ==> if (a) (b) else (c)\n\t/// </remarks>\n\tpartial class IfInstruction : ILInstruction\n\t{\n\t\tpublic IfInstruction(ILInstruction condition, ILInstruction trueInst, ILInstruction? falseInst = null) : base(OpCode.IfInstruction)\n\t\t{\n\t\t\tthis.Condition = condition;\n\t\t\tthis.TrueInst = trueInst;\n\t\t\tthis.FalseInst = falseInst ?? new Nop();\n\t\t}\n\n\t\tpublic static IfInstruction LogicAnd(ILInstruction lhs, ILInstruction rhs)\n\t\t{\n\t\t\treturn new IfInstruction(lhs, rhs, new LdcI4(0));\n\t\t}\n\n\t\tpublic static IfInstruction LogicOr(ILInstruction lhs, ILInstruction? rhs)\n\t\t{\n\t\t\treturn new IfInstruction(lhs, new LdcI4(1), rhs);\n\t\t}\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebug.Assert(condition.ResultType == StackType.I4);\n\t\t\tDebug.Assert(trueInst.ResultType == falseInst.ResultType\n\t\t\t\t|| trueInst.HasDirectFlag(InstructionFlags.EndPointUnreachable)\n\t\t\t\t|| falseInst.HasDirectFlag(InstructionFlags.EndPointUnreachable));\n\t\t}\n\n\t\tpublic override StackType ResultType {\n\t\t\tget {\n\t\t\t\tif (trueInst.HasDirectFlag(InstructionFlags.EndPointUnreachable))\n\t\t\t\t\treturn falseInst.ResultType;\n\t\t\t\telse\n\t\t\t\t\treturn trueInst.ResultType;\n\t\t\t}\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.ControlFlow;\n\t\t\t}\n\t\t}\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn InstructionFlags.ControlFlow | condition.Flags | SemanticHelper.CombineBranches(trueInst.Flags, falseInst.Flags);\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\tif (options.UseLogicOperationSugar)\n\t\t\t{\n\t\t\t\tif (MatchLogicAnd(out var lhs, out var rhs))\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\"logic.and(\");\n\t\t\t\t\tlhs.WriteTo(output, options);\n\t\t\t\t\toutput.Write(\", \");\n\t\t\t\t\trhs.WriteTo(output, options);\n\t\t\t\t\toutput.Write(')');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (MatchLogicOr(out lhs, out rhs))\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\"logic.or(\");\n\t\t\t\t\tlhs.WriteTo(output, options);\n\t\t\t\t\toutput.Write(\", \");\n\t\t\t\t\trhs.WriteTo(output, options);\n\t\t\t\t\toutput.Write(')');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(\" (\");\n\t\t\tcondition.WriteTo(output, options);\n\t\t\toutput.Write(\") \");\n\t\t\ttrueInst.WriteTo(output, options);\n\t\t\tif (falseInst.OpCode != OpCode.Nop)\n\t\t\t{\n\t\t\t\toutput.Write(\" else \");\n\t\t\t\tfalseInst.WriteTo(output, options);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the input instruction occurs in a context where it is being compared with 0.\n\t\t/// </summary>\n\t\tinternal static bool IsInConditionSlot(ILInstruction inst)\n\t\t{\n\t\t\tvar slot = inst.SlotInfo;\n\t\t\tif (slot == IfInstruction.ConditionSlot)\n\t\t\t\treturn true;\n\t\t\tif (slot == IfInstruction.TrueInstSlot || slot == IfInstruction.FalseInstSlot || slot == NullCoalescingInstruction.FallbackInstSlot)\n\t\t\t\treturn IsInConditionSlot(inst.Parent!);\n\t\t\tif (inst.Parent is Comp comp)\n\t\t\t{\n\t\t\t\tif (comp.Left == inst && comp.Right.MatchLdcI4(0))\n\t\t\t\t\treturn true;\n\t\t\t\tif (comp.Right == inst && comp.Left.MatchLdcI4(0))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/InstructionCollection.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpublic sealed class InstructionCollection<T> : IList<T>, IReadOnlyList<T> where T : ILInstruction\n\t{\n\t\treadonly ILInstruction parentInstruction;\n\t\treadonly int firstChildIndex;\n\t\treadonly List<T> list = new List<T>();\n\n\t\tpublic InstructionCollection(ILInstruction parentInstruction, int firstChildIndex)\n\t\t{\n\t\t\tif (parentInstruction == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(parentInstruction));\n\t\t\tthis.parentInstruction = parentInstruction;\n\t\t\tthis.firstChildIndex = firstChildIndex;\n\t\t}\n\n\t\tpublic int Count {\n\t\t\tget { return list.Count; }\n\t\t}\n\n\t\tpublic T this[int index] {\n\t\t\tget { return list[index]; }\n\t\t\tset {\n\t\t\t\tT oldValue = list[index];\n\t\t\t\tif (!(oldValue == value && value.Parent == parentInstruction && value.ChildIndex == index))\n\t\t\t\t{\n\t\t\t\t\tlist[index] = value;\n\t\t\t\t\tvalue.ChildIndex = index + firstChildIndex;\n\t\t\t\t\tparentInstruction.InstructionCollectionAdded(value);\n\t\t\t\t\tparentInstruction.InstructionCollectionRemoved(oldValue);\n\t\t\t\t\tparentInstruction.InstructionCollectionUpdateComplete();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t#region GetEnumerator\n\t\tpublic Enumerator GetEnumerator()\n\t\t{\n\t\t\treturn new Enumerator(this);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Custom enumerator for InstructionCollection.\n\t\t/// Unlike List{T}.Enumerator, this enumerator allows replacing an item during the enumeration.\n\t\t/// Adding/removing items from the collection still is invalid (however, such\n\t\t/// invalid actions are only detected in debug builds).\n\t\t/// \n\t\t/// Warning: even though this is a struct, it is invalid to copy:\n\t\t/// the number of constructor calls must match the number of dispose calls.\n\t\t/// </summary>\n\t\tpublic struct Enumerator : IEnumerator<T>\n\t\t{\n#if DEBUG\n\t\t\tILInstruction? parentInstruction;\n#endif\n\t\t\treadonly List<T> list;\n\t\t\tint pos;\n\n\t\t\tpublic Enumerator(InstructionCollection<T> col)\n\t\t\t{\n\t\t\t\tthis.list = col.list;\n\t\t\t\tthis.pos = -1;\n#if DEBUG\n\t\t\t\tthis.parentInstruction = col.parentInstruction;\n\t\t\t\tcol.parentInstruction.StartEnumerator();\n#endif\n\t\t\t}\n\n\t\t\t[DebuggerStepThrough]\n\t\t\tpublic bool MoveNext()\n\t\t\t{\n\t\t\t\treturn ++pos < list.Count;\n\t\t\t}\n\n\t\t\tpublic T Current {\n\t\t\t\t[DebuggerStepThrough]\n\t\t\t\tget { return list[pos]; }\n\t\t\t}\n\n\t\t\t[DebuggerStepThrough]\n\t\t\tpublic void Dispose()\n\t\t\t{\n#if DEBUG\n\t\t\t\tif (parentInstruction != null)\n\t\t\t\t{\n\t\t\t\t\tparentInstruction.StopEnumerator();\n\t\t\t\t\tparentInstruction = null;\n\t\t\t\t}\n#endif\n\t\t\t}\n\n\t\t\tvoid System.Collections.IEnumerator.Reset()\n\t\t\t{\n\t\t\t\tpos = -1;\n\t\t\t}\n\n\t\t\tobject System.Collections.IEnumerator.Current {\n\t\t\t\tget { return this.Current; }\n\t\t\t}\n\t\t}\n\n\t\tIEnumerator<T> IEnumerable<T>.GetEnumerator()\n\t\t{\n\t\t\treturn GetEnumerator();\n\t\t}\n\n\t\tSystem.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\n\t\t{\n\t\t\treturn GetEnumerator();\n\t\t}\n\t\t#endregion\n\n\t\t/// <summary>\n\t\t/// Gets the index of the instruction in this collection.\n\t\t/// Returns -1 if the instruction does not exist in the collection.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Runs in O(1) if the item can be found using the Parent/ChildIndex properties.\n\t\t/// Otherwise, runs in O(N).\n\t\t/// </remarks>\n\t\tpublic int IndexOf(T? item)\n\t\t{\n\t\t\tif (item == null)\n\t\t\t{\n\t\t\t\t// InstructionCollection can't contain nulls\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\t// If this collection is the item's primary position, we can use ChildIndex:\n\t\t\tint index = item.ChildIndex - firstChildIndex;\n\t\t\tif (index >= 0 && index < list.Count && list[index] == item)\n\t\t\t\treturn index;\n\t\t\t// But we still need to fall back on a full search, because the ILAst might be\n\t\t\t// in a state where item is in multiple locations.\n\t\t\treturn list.IndexOf(item);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the item is in this collection.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This method searches the list.\n\t\t/// Usually it's more efficient to test item.Parent instead!\n\t\t/// </remarks>\n\t\tpublic bool Contains(T? item)\n\t\t{\n\t\t\treturn IndexOf(item) >= 0;\n\t\t}\n\n\t\tvoid ICollection<T>.CopyTo(T[] array, int arrayIndex)\n\t\t{\n\t\t\tlist.CopyTo(array, arrayIndex);\n\t\t}\n\n\t\tbool ICollection<T>.IsReadOnly {\n\t\t\tget { return false; }\n\t\t}\n\n\t\tpublic void Add(T value)\n\t\t{\n\t\t\tparentInstruction.AssertNoEnumerators();\n\t\t\tvalue.ChildIndex = list.Count + firstChildIndex;\n\t\t\tlist.Add(value);\n\t\t\tparentInstruction.InstructionCollectionAdded(value);\n\t\t\tparentInstruction.InstructionCollectionUpdateComplete();\n\t\t}\n\n\t\tpublic void AddRange(IEnumerable<T> values)\n\t\t{\n\t\t\tparentInstruction.AssertNoEnumerators();\n\t\t\tforeach (T value in values)\n\t\t\t{\n\t\t\t\tvalue.ChildIndex = list.Count + firstChildIndex;\n\t\t\t\tlist.Add(value);\n\t\t\t\tparentInstruction.InstructionCollectionAdded(value);\n\t\t\t}\n\t\t\tparentInstruction.InstructionCollectionUpdateComplete();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Replaces all entries in the InstructionCollection with the newList.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Equivalent to Clear() followed by AddRange(newList), but slightly more efficient.\n\t\t/// </remarks>\n\t\tpublic void ReplaceList(IEnumerable<T> newList)\n\t\t{\n\t\t\tparentInstruction.AssertNoEnumerators();\n\t\t\tint index = 0;\n\t\t\tforeach (T value in newList)\n\t\t\t{\n\t\t\t\tvalue.ChildIndex = index + firstChildIndex;\n\t\t\t\tif (index < list.Count)\n\t\t\t\t{\n\t\t\t\t\tT oldValue = list[index];\n\t\t\t\t\tlist[index] = value;\n\t\t\t\t\tparentInstruction.InstructionCollectionAdded(value);\n\t\t\t\t\tparentInstruction.InstructionCollectionRemoved(oldValue);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tlist.Add(value);\n\t\t\t\t\tparentInstruction.InstructionCollectionAdded(value);\n\t\t\t\t}\n\t\t\t\tindex++;\n\t\t\t}\n\t\t\tfor (int i = index; i < list.Count; i++)\n\t\t\t{\n\t\t\t\tparentInstruction.InstructionCollectionRemoved(list[i]);\n\t\t\t}\n\t\t\tlist.RemoveRange(index, list.Count - index);\n\t\t\tparentInstruction.InstructionCollectionUpdateComplete();\n\t\t}\n\n\t\tpublic void Insert(int index, T item)\n\t\t{\n\t\t\tparentInstruction.AssertNoEnumerators();\n\t\t\tlist.Insert(index, item);\n\t\t\titem.ChildIndex = index;\n\t\t\tparentInstruction.InstructionCollectionAdded(item);\n\t\t\tfor (int i = index + 1; i < list.Count; i++)\n\t\t\t{\n\t\t\t\tT other_item = list[i];\n\t\t\t\t// Update ChildIndex of items after the inserted one, but only if\n\t\t\t\t// that's their 'primary position' (in case of multiple parents)\n\t\t\t\tif (other_item.Parent == parentInstruction && other_item.ChildIndex == i + firstChildIndex - 1)\n\t\t\t\t\tother_item.ChildIndex = i + firstChildIndex;\n\t\t\t}\n\t\t\tparentInstruction.InstructionCollectionUpdateComplete();\n\t\t}\n\n\t\tpublic void RemoveAt(int index)\n\t\t{\n\t\t\tparentInstruction.AssertNoEnumerators();\n\t\t\tparentInstruction.InstructionCollectionRemoved(list[index]);\n\t\t\tlist.RemoveAt(index);\n\t\t\tfor (int i = index; i < list.Count; i++)\n\t\t\t{\n\t\t\t\tvar other_item = list[i];\n\t\t\t\tif (other_item.Parent == parentInstruction && other_item.ChildIndex == i + firstChildIndex + 1)\n\t\t\t\t\tother_item.ChildIndex = i + firstChildIndex;\n\t\t\t}\n\t\t\tparentInstruction.InstructionCollectionUpdateComplete();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Remove item at index <c>index</c> in O(1) by swapping it with the last element in the collection.\n\t\t/// </summary>\n\t\tpublic void SwapRemoveAt(int index)\n\t\t{\n\t\t\tparentInstruction.AssertNoEnumerators();\n\t\t\tparentInstruction.InstructionCollectionRemoved(list[index]);\n\t\t\tint removeIndex = list.Count - 1;\n\t\t\tT movedItem = list[index] = list[removeIndex];\n\t\t\tlist.RemoveAt(removeIndex);\n\t\t\tif (movedItem.Parent == parentInstruction && movedItem.ChildIndex == removeIndex + firstChildIndex)\n\t\t\t\tmovedItem.ChildIndex = index + firstChildIndex;\n\t\t\tparentInstruction.InstructionCollectionUpdateComplete();\n\t\t}\n\n\t\tpublic void Clear()\n\t\t{\n\t\t\tparentInstruction.AssertNoEnumerators();\n\t\t\tforeach (var entry in list)\n\t\t\t{\n\t\t\t\tparentInstruction.InstructionCollectionRemoved(entry);\n\t\t\t}\n\t\t\tlist.Clear();\n\t\t\tparentInstruction.InstructionCollectionUpdateComplete();\n\t\t}\n\n\t\tpublic bool Remove(T item)\n\t\t{\n\t\t\tint index = IndexOf(item);\n\t\t\tif (index >= 0)\n\t\t\t{\n\t\t\t\tRemoveAt(index);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic void RemoveRange(int index, int count)\n\t\t{\n\t\t\tparentInstruction.AssertNoEnumerators();\n\t\t\tfor (int i = 0; i < count; i++)\n\t\t\t{\n\t\t\t\tparentInstruction.InstructionCollectionRemoved(list[index + i]);\n\t\t\t}\n\t\t\tlist.RemoveRange(index, count);\n\t\t\tfor (int i = index; i < list.Count; i++)\n\t\t\t{\n\t\t\t\tvar other_item = list[i];\n\t\t\t\tif (other_item.Parent == parentInstruction && other_item.ChildIndex == i + firstChildIndex + count)\n\t\t\t\t\tother_item.ChildIndex = i + firstChildIndex;\n\t\t\t}\n\t\t\tparentInstruction.InstructionCollectionUpdateComplete();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Removes all elements for which the predicate returns true.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This method runs in O(N), which is more efficient than calling RemoveAt() in a loop.\n\t\t/// The collection may be in an invalid state during the invocation of the predicate.\n\t\t/// </remarks>\n\t\tpublic int RemoveAll(Predicate<T> predicate)\n\t\t{\n\t\t\tparentInstruction.AssertNoEnumerators();\n\t\t\tint j = 0;\n\t\t\tfor (int i = 0; i < list.Count; i++)\n\t\t\t{\n\t\t\t\tT item = list[i];\n\t\t\t\tif (predicate(item))\n\t\t\t\t{\n\t\t\t\t\tparentInstruction.InstructionCollectionRemoved(item);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// keep the item\n\t\t\t\t\tif (item.Parent == parentInstruction && item.ChildIndex == i + firstChildIndex)\n\t\t\t\t\t\titem.ChildIndex = j + firstChildIndex;\n\t\t\t\t\tlist[j] = item;\n\t\t\t\t\tj++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tint removed = list.Count - j;\n\t\t\tif (removed > 0)\n\t\t\t{\n\t\t\t\tlist.RemoveRange(j, removed);\n\t\t\t\tparentInstruction.InstructionCollectionUpdateComplete();\n\t\t\t}\n\t\t\treturn removed;\n\t\t}\n\n\t\tpublic void MoveElementToIndex(int oldIndex, int newIndex)\n\t\t{\n\t\t\tparentInstruction.AssertNoEnumerators();\n\t\t\tvar item = list[oldIndex];\n\t\t\tInsert(newIndex, item);\n\t\t\tif (oldIndex < newIndex)\n\t\t\t\tRemoveAt(oldIndex);\n\t\t\telse\n\t\t\t\tRemoveAt(oldIndex + 1);\n\t\t}\n\n\t\tpublic void MoveElementToIndex(T item, int newIndex)\n\t\t{\n\t\t\tparentInstruction.AssertNoEnumerators();\n\t\t\tint oldIndex = IndexOf(item);\n\t\t\tif (oldIndex >= 0)\n\t\t\t{\n\t\t\t\tInsert(newIndex, item);\n\t\t\t\tif (oldIndex < newIndex)\n\t\t\t\t\tRemoveAt(oldIndex);\n\t\t\t\telse\n\t\t\t\t\tRemoveAt(oldIndex + 1);\n\t\t\t}\n\t\t}\n\n\t\tpublic void MoveElementToEnd(int index)\n\t\t{\n\t\t\tMoveElementToIndex(index, list.Count);\n\t\t}\n\n\t\tpublic void MoveElementToEnd(T item)\n\t\t{\n\t\t\tMoveElementToIndex(item, list.Count);\n\t\t}\n\n\t\t// more efficient versions of some LINQ methods:\n\t\tpublic T First()\n\t\t{\n\t\t\treturn list[0];\n\t\t}\n\n\t\tpublic T? FirstOrDefault()\n\t\t{\n\t\t\treturn list.Count > 0 ? list[0] : null;\n\t\t}\n\n\t\tpublic T Last()\n\t\t{\n\t\t\treturn list[list.Count - 1];\n\t\t}\n\n\t\tpublic T? LastOrDefault()\n\t\t{\n\t\t\treturn list.Count > 0 ? list[list.Count - 1] : null;\n\t\t}\n\n\t\tpublic T? SecondToLastOrDefault()\n\t\t{\n\t\t\treturn list.Count > 1 ? list[list.Count - 2] : null;\n\t\t}\n\n\t\tpublic T? ElementAtOrDefault(int index)\n\t\t{\n\t\t\tif (index >= 0 && index < list.Count)\n\t\t\t\treturn list[index];\n\t\t\treturn null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/IsInst.cs",
    "content": "#nullable enable\n// Copyright (c) 2025 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics;\n\nusing ICSharpCode.Decompiler.CSharp;\n\nnamespace ICSharpCode.Decompiler.IL;\n\npartial class IsInst\n{\n\tinternal override bool CanInlineIntoSlot(int childIndex, ILInstruction newChild)\n\t{\n\t\tDebug.Assert(childIndex == 0);\n\t\tDebug.Assert(base.CanInlineIntoSlot(childIndex, newChild));\n\t\tif (this.Type.IsReferenceType == true)\n\t\t{\n\t\t\treturn true;  // reference-type isinst is always supported\n\t\t}\n\t\tif (SemanticHelper.IsPure(newChild.Flags))\n\t\t{\n\t\t\treturn true; // emulated via \"expr is T ? (T)expr : null\"\n\t\t}\n\t\telse if (newChild is Box box && SemanticHelper.IsPure(box.Argument.Flags) && this.Argument.Children.Count == 0)\n\t\t{\n\t\t\t// Also emulated via \"expr is T ? (T)expr : null\".\n\t\t\t// This duplicates the boxing side-effect, but that's harmless as one of the boxes is only\n\t\t\t// used in the `expr is T` type test where the object identity can never be observed.\n\t\t\t// This appears as part of C# pattern matching, inlining early makes those code patterns easier to detect.\n\n\t\t\t// We can only do this if the Box appears directly top-level in the IsInst, we cannot inline Box instructions\n\t\t\t// deeper into our Argument subtree. So restricts to the case were the previous argument has no children\n\t\t\t// (which means inlining can only replace the argument, not insert within it).\n\t\t\treturn true;\n\t\t}\n\t\tif (this.Parent is UnboxAny unboxAny && ExpressionBuilder.IsUnboxAnyWithIsInst(unboxAny, this.Type))\n\t\t{\n\t\t\treturn true; // supported pattern \"expr as T?\"\n\t\t}\n\t\tif (this.Parent != null && (this.Parent.MatchCompEqualsNull(out _) || this.Parent.MatchCompNotEqualsNull(out _)))\n\t\t{\n\t\t\treturn true; // supported pattern \"expr is T\"\n\t\t}\n\t\tif (this.Parent is Block { Kind: BlockKind.ControlFlow })\n\t\t{\n\t\t\treturn true; // supported via StatementBuilder.VisitIsInst\n\t\t}\n\t\treturn false;\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/LdFlda.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpublic sealed partial class LdFlda\n\t{\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tswitch (field.DeclaringType.IsReferenceType)\n\t\t\t{\n\t\t\t\tcase true:\n\t\t\t\t\tDebug.Assert(target.ResultType == StackType.O,\n\t\t\t\t\t\t\"Class fields can only be accessed with an object on the stack\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase false:\n\t\t\t\t\tDebug.Assert(target.ResultType == StackType.I || target.ResultType == StackType.Ref,\n\t\t\t\t\t\t\"Struct fields can only be accessed with a pointer on the stack\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase null:\n\t\t\t\t\t// field of unresolved type\n\t\t\t\t\tDebug.Assert(target.ResultType == StackType.O || target.ResultType == StackType.I\n\t\t\t\t\t\t|| target.ResultType == StackType.Ref || target.ResultType == StackType.Unknown,\n\t\t\t\t\t\t\"Field of unresolved type with invalid target\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic sealed partial class StObj\n\t{\n\t\tinternal override bool SatisfiesSlotRestrictionForInlining(int childIndex, ILInstruction newChild)\n\t\t{\n\t\t\tif (childIndex == 0) // target slot\n\t\t\t{\n\t\t\t\tDebug.Assert(GetChildSlot(childIndex) == TargetSlot);\n\t\t\t\t// For a store to a field or array element, C# will only throw NullReferenceException/IndexOfBoundsException\n\t\t\t\t// after the value-to-be-stored has been computed.\n\t\t\t\t// This means a LdFlda/LdElema used as target for StObj must have DelayExceptions==true to allow a translation to C#\n\t\t\t\t// without changing the program semantics. See https://github.com/icsharpcode/ILSpy/issues/2050\n\t\t\t\tswitch (newChild.OpCode)\n\t\t\t\t{\n\t\t\t\t\tcase OpCode.LdElema:\n\t\t\t\t\tcase OpCode.LdFlda:\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(newChild.HasDirectFlag(InstructionFlags.MayThrow));\n\t\t\t\t\t\t// If the ldelema/ldflda may throw a non-delayed exception, inlining will cause it\n\t\t\t\t\t\t// to turn into a delayed exception after the translation to C#.\n\t\t\t\t\t\t// This is only valid if the value computation doesn't involve any side effects.\n\t\t\t\t\t\tif (!SemanticHelper.IsPure(this.Value.Flags))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Note that after inlining such a ldelema/ldflda, the normal inlining rules will\n\t\t\t\t\t\t// prevent us from inlining an effectful instruction into the value slot.\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn base.SatisfiesSlotRestrictionForInlining(childIndex, newChild);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// called as part of CheckInvariant()\n\t\t/// </summary>\n\t\tvoid CheckTargetSlot()\n\t\t{\n\t\t\tswitch (this.Target.OpCode)\n\t\t\t{\n\t\t\t\tcase OpCode.LdElema:\n\t\t\t\tcase OpCode.LdFlda:\n\t\t\t\t\tif (this.Target.HasDirectFlag(InstructionFlags.MayThrow))\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(SemanticHelper.IsPure(this.Value.Flags));\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/LdLen.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// Description of LdLen.\n\t/// </summary>\n\tpublic sealed partial class LdLen\n\t{\n\t\treadonly StackType resultType;\n\n\t\tpublic LdLen(StackType type, ILInstruction array) : base(OpCode.LdLen)\n\t\t{\n\t\t\tDebug.Assert(type == StackType.I || type == StackType.I4 || type == StackType.I8);\n\t\t\tthis.resultType = type;\n\t\t\tthis.Array = array;\n\t\t}\n\n\t\tpublic override StackType ResultType {\n\t\t\tget { return resultType; }\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write('.');\n\t\t\toutput.Write(resultType);\n\t\t\toutput.Write('(');\n\t\t\tthis.array.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/Leave.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// Unconditional branch. <c>goto target;</c>\n\t/// </summary>\n\t/// <remarks>\n\t/// When jumping to the entrypoint of the current block container, the branch represents a <c>continue</c> statement.\n\t/// \n\t/// Phase-1 execution of a branch is a no-op.\n\t/// Phase-2 execution removes PopCount elements from the evaluation stack\n\t/// and jumps to the target block.\n\t/// </remarks>\n\tpartial class Leave : ILInstruction, IBranchOrLeaveInstruction\n\t{\n\t\tBlockContainer? targetContainer;\n\n\t\tpublic Leave(BlockContainer? targetContainer, ILInstruction? value = null) : base(OpCode.Leave)\n\t\t{\n\t\t\t// Note: ILReader will create Leave instructions with targetContainer==null to represent 'endfinally',\n\t\t\t// the targetContainer will then be filled in by BlockBuilder\n\t\t\tthis.targetContainer = targetContainer;\n\t\t\tthis.Value = value ?? new Nop();\n\t\t}\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn value.Flags | InstructionFlags.MayBranch | InstructionFlags.EndPointUnreachable;\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayBranch | InstructionFlags.EndPointUnreachable;\n\t\t\t}\n\t\t}\n\n\t\tpublic BlockContainer TargetContainer {\n\t\t\tget { return targetContainer!; }\n\t\t\tset {\n\t\t\t\tif (targetContainer != null && IsConnected)\n\t\t\t\t\ttargetContainer.LeaveCount--;\n\t\t\t\ttargetContainer = value;\n\t\t\t\tif (targetContainer != null && IsConnected)\n\t\t\t\t\ttargetContainer.LeaveCount++;\n\t\t\t}\n\t\t}\n\n\t\tprotected override void Connected()\n\t\t{\n\t\t\tbase.Connected();\n\t\t\tif (targetContainer != null)\n\t\t\t\ttargetContainer.LeaveCount++;\n\t\t}\n\n\t\tprotected override void Disconnected()\n\t\t{\n\t\t\tbase.Disconnected();\n\t\t\tif (targetContainer != null)\n\t\t\t\ttargetContainer.LeaveCount--;\n\t\t}\n\n\t\tpublic string TargetLabel {\n\t\t\tget { return targetContainer?.EntryPoint != null ? targetContainer.EntryPoint.Label : string.Empty; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the leave instruction is directly leaving the whole ILFunction.\n\t\t/// (TargetContainer == main container of the function).\n\t\t/// \n\t\t/// This is only valid for functions returning void (representing value-less \"return;\"),\n\t\t/// and for iterators (representing \"yield break;\").\n\t\t/// \n\t\t/// Note: returns false for leave instructions that indirectly leave the function\n\t\t/// (e.g. leaving a try block, and the try-finally construct is immediately followed\n\t\t/// by another leave instruction)\n\t\t/// </summary>\n\t\tpublic bool IsLeavingFunction {\n\t\t\tget { return targetContainer?.Parent is ILFunction; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this branch executes at least one finally block before jumping to the end of the target block container.\n\t\t/// </summary>\n\t\tpublic bool TriggersFinallyBlock {\n\t\t\tget {\n\t\t\t\treturn Branch.GetExecutesFinallyBlock(this, TargetContainer);\n\t\t\t}\n\t\t}\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebug.Assert(phase <= ILPhase.InILReader || this.IsDescendantOf(targetContainer!));\n\t\t\tDebug.Assert(phase <= ILPhase.InILReader || phase == ILPhase.InAsyncAwait || value.ResultType == targetContainer!.ResultType);\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tif (targetContainer != null)\n\t\t\t{\n\t\t\t\toutput.Write(' ');\n\t\t\t\toutput.WriteLocalReference(TargetLabel, targetContainer);\n\t\t\t\toutput.Write(\" (\");\n\t\t\t\tvalue.WriteTo(output, options);\n\t\t\t\toutput.Write(')');\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/LockInstruction.cs",
    "content": "#nullable enable\n// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpartial class LockInstruction\n\t{\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(\"lock (\");\n\t\t\tOnExpression.WriteTo(output, options);\n\t\t\toutput.WriteLine(\") {\");\n\t\t\toutput.Indent();\n\t\t\tBody.WriteTo(output, options);\n\t\t\toutput.Unindent();\n\t\t\toutput.WriteLine();\n\t\t\toutput.Write(\"}\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/LogicInstructions.cs",
    "content": "#nullable enable\n// Copyright (c) 2017 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t// Note: The comp instruction also supports three-valued logic via ComparisonLiftingKind.ThreeValuedLogic.\n\t// comp.i4.lifted[3VL](x == ldc.i4 0) is used to represent a lifted logic.not.\n\n\tpartial class ThreeValuedBoolAnd : ILiftableInstruction\n\t{\n\t\tbool ILiftableInstruction.IsLifted => true;\n\t\tStackType ILiftableInstruction.UnderlyingResultType => StackType.I4;\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebug.Assert(Left.ResultType == StackType.I4 || Left.ResultType == StackType.O);\n\t\t}\n\t}\n\n\tpartial class ThreeValuedBoolOr : ILiftableInstruction\n\t{\n\t\tbool ILiftableInstruction.IsLifted => true;\n\t\tStackType ILiftableInstruction.UnderlyingResultType => StackType.I4;\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebug.Assert(Left.ResultType == StackType.I4 || Left.ResultType == StackType.O);\n\t\t}\n\t}\n\n\tpartial class UserDefinedLogicOperator\n\t{\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\t// left is always executed; right only sometimes\n\t\t\treturn DirectFlags | left.Flags\n\t\t\t\t| SemanticHelper.CombineBranches(InstructionFlags.None, right.Flags);\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayThrow | InstructionFlags.SideEffect | InstructionFlags.ControlFlow;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/MatchInstruction.cs",
    "content": "#nullable enable\n// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpartial class MatchInstruction : ILInstruction\n\t{\n\t\t/* Pseudo-Code for interpreting a MatchInstruction:\n\t\t\tbool Eval()\n\t\t\t{\n\t\t\t\tvar value = this.TestedOperand.Eval();\n\t\t\t\tif (this.CheckNotNull && value == null)\n\t\t\t\t\treturn false;\n\t\t\t\tif (this.CheckType && !(value is this.Variable.Type))\n\t\t\t\t\treturn false;\n\t\t\t\tif (this.IsDeconstructCall) {\n\t\t\t\t\tdeconstructResult = new[numArgs];\n\t\t\t\t\tEvalCall(this.Method, value, out deconstructResult[0], .., out deconstructResult[numArgs-1]);\n\t\t\t\t\t// any occurrences of 'deconstruct.result' in the subPatterns will refer\n\t\t\t\t\t// to the values provided by evaluating the call.\n\t\t\t\t}\n\t\t\t\tVariable.Value = value;\n\t\t\t\tforeach (var subPattern in this.SubPatterns) {\n\t\t\t\t\tif (!subPattern.Eval())\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t*/\n\t\t/* Examples of MatchInstructions:\n\t\t\texpr is var x:\n\t\t\t\tmatch(x = expr)\n\n\t\t\texpr is {} x:\n\t\t\t\tmatch.notnull(x = expr)\n\n\t\t\texpr is T x:\n\t\t\t\tmatch.type[T](x = expr)\n\n\t\t\texpr is C { A: var x } z:\n\t\t\t\tmatch.type[C](z = expr) {\n\t\t\t\t   match(x = z.A)\n\t\t\t\t}\n\n\t\t\texpr is C { A: var x, B: 42, C: { A: 4 } } z:\n\t\t\t\tmatch.type[C](z = expr) {\n\t\t\t\t\tmatch(x = z.A),\n\t\t\t\t\tcomp (z.B == 42),\n\t\t\t\t\tmatch.notnull(temp2 = z.C) {\n\t\t\t\t\t\tcomp (temp2.A == 4)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\texpr is C(var x, var y, <4):\n\t\t\t\tmatch.type[C].deconstruct[C.Deconstruct](tmp1 = expr) {\n\t\t\t\t\tmatch(x = deconstruct.result1(tmp1)),\n\t\t\t\t\tmatch(y = deconstruct.result2(tmp1)),\n\t\t\t\t\tcomp(deconstruct.result3(tmp1) < 4),\n\t\t\t\t}\n\t\t\t\n\t\t\texpr is C(1, D(2, 3)):\n\t\t\t\tmatch.type[C].deconstruct(c = expr) {\n\t\t\t\t\tcomp(deconstruct.result1(c) == 1),\n\t\t\t\t\tmatch.type[D].deconstruct(d = deconstruct.result2(c)) {\n\t\t\t\t\t\tcomp(deconstruct.result1(d) == 2),\n\t\t\t\t\t\tcomp(deconstruct.result2(d) == 3),\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t */\n\n\t\tpublic bool IsVar => !CheckType && !CheckNotNull && !IsDeconstructCall && !IsDeconstructTuple && SubPatterns.Count == 0;\n\n\t\tpublic bool HasDesignator => Variable.LoadCount + Variable.AddressCount > SubPatterns.Count;\n\n\t\tpublic int NumPositionalPatterns {\n\t\t\tget {\n\t\t\t\tif (IsDeconstructCall)\n\t\t\t\t\treturn method!.Parameters.Count - (method.IsStatic ? 1 : 0);\n\t\t\t\telse if (IsDeconstructTuple)\n\t\t\t\t\treturn TupleType.GetTupleElementTypes(variable.Type).Length;\n\t\t\t\telse\n\t\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\n\t\tpublic MatchInstruction(ILVariable variable, ILInstruction testedOperand)\n\t\t\t: this(variable, method: null, testedOperand)\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Checks whether the input instruction can represent a pattern matching operation.\n\t\t/// \n\t\t/// Any pattern matching instruction will first evaluate the `testedOperand` (a descendant of `inst`),\n\t\t/// and then match the value of that operand against the pattern encoded in the instruction.\n\t\t/// The matching may have side-effects on the newly-initialized pattern variables\n\t\t/// (even if the pattern fails to match!).\n\t\t/// The pattern matching instruction evaluates to 1 (as I4) if the pattern matches, or 0 otherwise.\n\t\t/// </summary>\n\t\tpublic static bool IsPatternMatch(ILInstruction? inst, [NotNullWhen(true)] out ILInstruction? testedOperand, DecompilerSettings? settings)\n\t\t{\n\t\t\tswitch (inst)\n\t\t\t{\n\t\t\t\tcase MatchInstruction m:\n\t\t\t\t\ttestedOperand = m.testedOperand;\n\t\t\t\t\treturn true;\n\t\t\t\tcase Comp comp:\n\t\t\t\t\tif (comp.MatchLogicNot(out var operand) && IsPatternMatch(operand, out testedOperand, settings))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn settings?.PatternCombinators ?? true;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\ttestedOperand = comp.Left;\n\t\t\t\t\t\tif (!(settings?.RelationalPatterns ?? true))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (comp.Kind is not (ComparisonKind.Equality or ComparisonKind.Inequality))\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!(settings?.PatternCombinators ?? true))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (comp.Kind is ComparisonKind.Inequality)\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn IsConstant(comp.Right);\n\t\t\t\t\t}\n\t\t\t\tcase Call call when IsCallToOpEquality(call, KnownTypeCode.String):\n\t\t\t\t\ttestedOperand = call.Arguments[0];\n\t\t\t\t\treturn call.Arguments[1].OpCode == OpCode.LdStr;\n\t\t\t\tcase Call call when IsCallToOpEquality(call, KnownTypeCode.Decimal):\n\t\t\t\t\ttestedOperand = call.Arguments[0];\n\t\t\t\t\treturn call.Arguments[1].OpCode == OpCode.LdcDecimal;\n\t\t\t\tdefault:\n\t\t\t\t\ttestedOperand = null;\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tinternal static bool IsCallToOpEquality(Call call, KnownTypeCode knownType)\n\t\t{\n\t\t\treturn call.Method.IsOperator && call.Method.Name == \"op_Equality\"\n\t\t\t\t&& call.Method.DeclaringType.IsKnownType(knownType)\n\t\t\t\t&& call.Arguments.Count == 2;\n\t\t}\n\n\t\tinternal static bool IsConstant(ILInstruction inst)\n\t\t{\n\t\t\treturn inst.OpCode switch {\n\t\t\t\tOpCode.LdcDecimal => true,\n\t\t\t\tOpCode.LdcF4 => true,\n\t\t\t\tOpCode.LdcF8 => true,\n\t\t\t\tOpCode.LdcI4 => true,\n\t\t\t\tOpCode.LdcI8 => true,\n\t\t\t\tOpCode.LdNull => true,\n\t\t\t\t_ => false\n\t\t\t};\n\t\t}\n\n\t\tinternal IType GetDeconstructResultType(int index)\n\t\t{\n\t\t\tif (this.IsDeconstructCall)\n\t\t\t{\n\t\t\t\tint firstOutParam = (method!.IsStatic ? 1 : 0);\n\t\t\t\tvar outParamType = method.Parameters[firstOutParam + index].Type;\n\t\t\t\tif (outParamType is not ByReferenceType brt)\n\t\t\t\t\tthrow new InvalidOperationException(\"deconstruct out param must be by reference\");\n\t\t\t\treturn brt.ElementType;\n\t\t\t}\n\t\t\tif (this.IsDeconstructTuple)\n\t\t\t{\n\t\t\t\tvar elementTypes = TupleType.GetTupleElementTypes(this.variable.Type);\n\t\t\t\treturn elementTypes[index];\n\t\t\t}\n\t\t\tthrow new InvalidOperationException(\"GetDeconstructResultType requires a deconstruct pattern\");\n\t\t}\n\n\t\tvoid AdditionalInvariants()\n\t\t{\n\t\t\tDebug.Assert(variable.Kind == VariableKind.PatternLocal);\n\t\t\tif (this.IsDeconstructCall)\n\t\t\t{\n\t\t\t\tDebug.Assert(IsDeconstructMethod(method));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDebug.Assert(method == null);\n\t\t\t}\n\t\t\tif (this.IsDeconstructTuple)\n\t\t\t{\n\t\t\t\tDebug.Assert(variable.Type.Kind == TypeKind.Tuple);\n\t\t\t}\n\t\t\tDebug.Assert(SubPatterns.Count >= NumPositionalPatterns);\n\t\t\tforeach (var subPattern in SubPatterns)\n\t\t\t{\n\t\t\t\tif (!IsPatternMatch(subPattern, out ILInstruction? operand, null))\n\t\t\t\t\tthrow new InvalidOperationException(\"Sub-Pattern must be a valid pattern\");\n\t\t\t\t// the first child is TestedOperand\n\t\t\t\tint subPatternIndex = subPattern.ChildIndex - 1;\n\t\t\t\tif (subPatternIndex < NumPositionalPatterns)\n\t\t\t\t{\n\t\t\t\t\t// positional pattern\n\t\t\t\t\tDebug.Assert(operand is DeconstructResultInstruction result && result.Index == subPatternIndex);\n\t\t\t\t}\n\t\t\t\telse if (operand.MatchLdFld(out var target, out _))\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(target.MatchLdLocRef(variable));\n\t\t\t\t}\n\t\t\t\telse if (operand is CallInstruction call)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(call.Method.AccessorKind == System.Reflection.MethodSemanticsAttributes.Getter);\n\t\t\t\t\tDebug.Assert(call.Arguments[0].MatchLdLocRef(variable));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tDebug.Fail(\"Tested operand of sub-pattern is invalid.\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tinternal static bool IsDeconstructMethod(IMethod? method)\n\t\t{\n\t\t\tif (method == null)\n\t\t\t\treturn false;\n\t\t\tif (method.Name != \"Deconstruct\")\n\t\t\t\treturn false;\n\t\t\tif (method.ReturnType.Kind != TypeKind.Void)\n\t\t\t\treturn false;\n\t\t\tint firstOutParam = (method.IsStatic ? 1 : 0);\n\t\t\tif (method.IsStatic)\n\t\t\t{\n\t\t\t\tif (!method.IsExtensionMethod)\n\t\t\t\t\treturn false;\n\t\t\t\t// TODO : check whether all type arguments can be inferred from the first argument\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (method.TypeParameters.Count != 0)\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// TODO : check whether the method is ambigious\n\n\t\t\tif (method.Parameters.Count < firstOutParam)\n\t\t\t\treturn false;\n\n\t\t\tfor (int i = firstOutParam; i < method.Parameters.Count; i++)\n\t\t\t{\n\t\t\t\tif (method.Parameters[i].ReferenceKind != ReferenceKind.Out)\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tif (CheckNotNull)\n\t\t\t{\n\t\t\t\toutput.Write(\".notnull\");\n\t\t\t}\n\t\t\tif (CheckType)\n\t\t\t{\n\t\t\t\toutput.Write(\".type[\");\n\t\t\t\tvariable.Type.WriteTo(output);\n\t\t\t\toutput.Write(']');\n\t\t\t}\n\t\t\tif (IsDeconstructCall)\n\t\t\t{\n\t\t\t\toutput.Write(\".deconstruct[\");\n\t\t\t\tif (method == null)\n\t\t\t\t\toutput.Write(\"<null>\");\n\t\t\t\telse\n\t\t\t\t\tmethod.WriteTo(output);\n\t\t\t\toutput.Write(']');\n\t\t\t}\n\t\t\tif (IsDeconstructTuple)\n\t\t\t{\n\t\t\t\toutput.Write(\".tuple\");\n\t\t\t}\n\t\t\toutput.Write(' ');\n\t\t\toutput.Write('(');\n\t\t\tVariable.WriteTo(output);\n\t\t\toutput.Write(\" = \");\n\t\t\tTestedOperand.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t\tif (SubPatterns.Count > 0)\n\t\t\t{\n\t\t\t\toutput.MarkFoldStart(\"{...}\");\n\t\t\t\toutput.WriteLine(\"{\");\n\t\t\t\toutput.Indent();\n\t\t\t\tforeach (var pattern in SubPatterns)\n\t\t\t\t{\n\t\t\t\t\tpattern.WriteTo(output, options);\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t}\n\t\t\t\toutput.Unindent();\n\t\t\t\toutput.Write('}');\n\t\t\t\toutput.MarkFoldEnd();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/MemoryInstructions.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tinterface ISupportsUnalignedPrefix\n\t{\n\t\t/// <summary>\n\t\t/// Returns the alignment specified by the 'unaligned' prefix; or 0 if there was no 'unaligned' prefix.\n\t\t/// </summary>\n\t\tbyte UnalignedPrefix { get; set; }\n\t}\n\n\tinterface ISupportsVolatilePrefix\n\t{\n\t\t/// <summary>\n\t\t/// Gets/Sets whether the memory access is volatile.\n\t\t/// </summary>\n\t\tbool IsVolatile { get; set; }\n\t}\n\n\tpartial class LdObj\n\t{\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tif (options.UseFieldSugar)\n\t\t\t{\n\t\t\t\tif (this.MatchLdFld(out var target, out var field))\n\t\t\t\t{\n\t\t\t\t\tWriteILRange(output, options);\n\t\t\t\t\toutput.Write(\"ldfld \");\n\t\t\t\t\tfield.WriteTo(output);\n\t\t\t\t\toutput.Write('(');\n\t\t\t\t\ttarget.WriteTo(output, options);\n\t\t\t\t\toutput.Write(')');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\telse if (this.MatchLdsFld(out field))\n\t\t\t\t{\n\t\t\t\t\tWriteILRange(output, options);\n\t\t\t\t\toutput.Write(\"ldsfld \");\n\t\t\t\t\tfield.WriteTo(output);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tOriginalWriteTo(output, options);\n\t\t}\n\t}\n\n\tpartial class StObj\n\t{\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tif (options.UseFieldSugar)\n\t\t\t{\n\t\t\t\tif (this.MatchStFld(out var target, out var field, out var value))\n\t\t\t\t{\n\t\t\t\t\tWriteILRange(output, options);\n\t\t\t\t\toutput.Write(\"stfld \");\n\t\t\t\t\tfield.WriteTo(output);\n\t\t\t\t\toutput.Write('(');\n\t\t\t\t\ttarget.WriteTo(output, options);\n\t\t\t\t\toutput.Write(\", \");\n\t\t\t\t\tvalue.WriteTo(output, options);\n\t\t\t\t\toutput.Write(')');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\telse if (this.MatchStsFld(out field, out value))\n\t\t\t\t{\n\t\t\t\t\tWriteILRange(output, options);\n\t\t\t\t\toutput.Write(\"stsfld \");\n\t\t\t\t\tfield.WriteTo(output);\n\t\t\t\t\toutput.Write('(');\n\t\t\t\t\tvalue.WriteTo(output, options);\n\t\t\t\t\toutput.Write(')');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tOriginalWriteTo(output, options);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/NullCoalescingInstruction.cs",
    "content": "#nullable enable\n// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// Kind of null-coalescing operator.\n\t/// ILAst: <c>if.notnull(valueInst, fallbackInst)</c>\n\t/// C#: <c>value ?? fallback</c>\n\t/// </summary>\n\tpublic enum NullCoalescingKind\n\t{\n\t\t/// <summary>\n\t\t/// Both ValueInst and FallbackInst are of reference type.\n\t\t/// \n\t\t/// Semantics: equivalent to \"valueInst != null ? valueInst : fallbackInst\",\n\t\t///            except that valueInst is evaluated only once.\n\t\t/// </summary>\n\t\tRef,\n\t\t/// <summary>\n\t\t/// Both ValueInst and FallbackInst are of type Nullable{T}.\n\t\t/// \n\t\t/// Semantics: equivalent to \"valueInst.HasValue ? valueInst : fallbackInst\",\n\t\t///            except that valueInst is evaluated only once.\n\t\t/// </summary>\n\t\tNullable,\n\t\t/// <summary>\n\t\t/// ValueInst is Nullable{T}, but FallbackInst is non-nullable value type.\n\t\t/// \n\t\t/// Semantics: equivalent to \"valueInst.HasValue ? valueInst.Value : fallbackInst\",\n\t\t///            except that valueInst is evaluated only once.\n\t\t/// </summary>\n\t\tNullableWithValueFallback\n\t}\n\n\tpartial class NullCoalescingInstruction\n\t{\n\t\tpublic readonly NullCoalescingKind Kind;\n\t\tpublic StackType UnderlyingResultType = StackType.O;\n\n\t\tpublic NullCoalescingInstruction(NullCoalescingKind kind, ILInstruction valueInst, ILInstruction fallbackInst) : base(OpCode.NullCoalescingInstruction)\n\t\t{\n\t\t\tthis.Kind = kind;\n\t\t\tthis.ValueInst = valueInst;\n\t\t\tthis.FallbackInst = fallbackInst;\n\t\t}\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebug.Assert(valueInst.ResultType == StackType.O); // lhs is reference type or nullable type\n\t\t\tDebug.Assert(fallbackInst.ResultType == StackType.O || Kind == NullCoalescingKind.NullableWithValueFallback);\n\t\t\tDebug.Assert(ResultType == UnderlyingResultType || Kind == NullCoalescingKind.Nullable);\n\t\t}\n\n\t\tpublic override StackType ResultType {\n\t\t\tget {\n\t\t\t\treturn fallbackInst.ResultType;\n\t\t\t}\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.ControlFlow;\n\t\t\t}\n\t\t}\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\t// valueInst is always executed; fallbackInst only sometimes\n\t\t\treturn InstructionFlags.ControlFlow | valueInst.Flags\n\t\t\t\t| SemanticHelper.CombineBranches(InstructionFlags.None, fallbackInst.Flags);\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(\"(\");\n\t\t\tvalueInst.WriteTo(output, options);\n\t\t\toutput.Write(\", \");\n\t\t\tfallbackInst.WriteTo(output, options);\n\t\t\toutput.Write(\")\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/NullableInstructions.cs",
    "content": "#nullable enable\n// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.IL.Transforms;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// For a nullable input, gets the underlying value.\n\t/// \n\t/// There are three possible input types:\n\t///  * reference type: if input!=null, evaluates to the input\n\t///  * nullable value type: if input.Has_Value, evaluates to input.GetValueOrDefault()\n\t///  * generic type: behavior depends on the type at runtime.\n\t///    If non-nullable value type, unconditionally evaluates to the input.\n\t///\n\t/// If the input is null, control-flow is tranferred to the nearest surrounding nullable.rewrap\n\t/// instruction.\n\t/// </summary>\n\tpartial class NullableUnwrap\n\t{\n\t\t/// <summary>\n\t\t/// Whether the argument is dereferenced before checking for a null input.\n\t\t/// If true, the argument must be a managed reference to a valid input type.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This mode exists because the C# compiler sometimes avoids copying the whole Nullable{T} struct\n\t\t/// before the null-check.\n\t\t/// The underlying struct T is still copied by the GetValueOrDefault() call, but only in the non-null case.\n\t\t/// </remarks>\n\t\tpublic readonly bool RefInput;\n\n\t\t/// <summary>\n\t\t/// Consider the following code generated for <code>t?.Method()</code> on a generic t:\n\t\t/// <code>if (comp(box ``0(ldloc t) != ldnull)) newobj Nullable..ctor(constrained[``0].callvirt Method(ldloca t)) else default.value Nullable</code>\n\t\t/// Here, the method is called on the original reference, and any mutations performed by the method will be visible in the original variable.\n\t\t/// \n\t\t/// To represent this, we use a nullable.unwrap with ResultType==Ref: instead of returning the input value,\n\t\t/// the input reference is returned in the non-null case.\n\t\t/// Note that in case the generic type ends up being <c>Nullable{T}</c>, this means methods will end up being called on\n\t\t/// the nullable type, not on the underlying type. However, this ends up making no difference, because the only methods\n\t\t/// that can be called that way are those on System.Object. All the virtual methods are overridden in <c>Nullable{T}</c>\n\t\t/// and end up forwarding to <c>T</c>; and the non-virtual methods cause boxing which strips the <c>Nullable{T}</c> wrapper.\n\t\t/// \n\t\t/// RefOutput can only be used if RefInput is also used.\n\t\t/// </summary>\n\t\tpublic bool RefOutput { get => ResultType == StackType.Ref; }\n\n\t\tpublic NullableUnwrap(StackType unwrappedType, ILInstruction argument, bool refInput = false)\n\t\t\t: base(OpCode.NullableUnwrap, argument)\n\t\t{\n\t\t\tthis.ResultType = unwrappedType;\n\t\t\tthis.RefInput = refInput;\n\t\t\tif (unwrappedType == StackType.Ref)\n\t\t\t{\n\t\t\t\tDebug.Assert(refInput);\n\t\t\t}\n\t\t}\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tif (this.RefInput)\n\t\t\t{\n\t\t\t\tDebug.Assert(Argument.ResultType == StackType.Ref, \"nullable.unwrap expects reference to nullable type as input\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDebug.Assert(Argument.ResultType == StackType.O, \"nullable.unwrap expects nullable type as input\");\n\t\t\t}\n\t\t\tDebug.Assert(Ancestors.Any(a => a is NullableRewrap));\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\toutput.Write(\"nullable.unwrap.\");\n\t\t\tif (RefInput)\n\t\t\t{\n\t\t\t\toutput.Write(\"refinput.\");\n\t\t\t}\n\t\t\toutput.Write(ResultType);\n\t\t\toutput.Write('(');\n\t\t\tArgument.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\n\t\tpublic override StackType ResultType { get; }\n\t}\n\n\tpartial class NullableRewrap\n\t{\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebug.Assert(Argument.HasFlag(InstructionFlags.MayUnwrapNull));\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags => InstructionFlags.ControlFlow;\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\t// Convert MayUnwrapNull flag to ControlFlow flag.\n\t\t\t// Also, remove EndpointUnreachable flag, because the end-point is reachable through\n\t\t\t// the implicit nullable.unwrap branch.\n\t\t\tconst InstructionFlags flagsToRemove = InstructionFlags.MayUnwrapNull | InstructionFlags.EndPointUnreachable;\n\t\t\treturn (Argument.Flags & ~flagsToRemove) | InstructionFlags.ControlFlow;\n\t\t}\n\n\t\tpublic override StackType ResultType {\n\t\t\tget {\n\t\t\t\tif (Argument.ResultType == StackType.Void)\n\t\t\t\t\treturn StackType.Void;\n\t\t\t\telse\n\t\t\t\t\treturn StackType.O;\n\t\t\t}\n\t\t}\n\n\t\tinternal override bool PrepareExtract(int childIndex, ExtractionContext ctx)\n\t\t{\n\t\t\treturn base.PrepareExtract(childIndex, ctx)\n\t\t\t\t&& (ctx.FlagsBeingMoved & InstructionFlags.MayUnwrapNull) == 0;\n\t\t}\n\n\t\tinternal override bool CanInlineIntoSlot(int childIndex, ILInstruction expressionBeingMoved)\n\t\t{\n\t\t\t// Inlining into nullable.rewrap is OK unless the expression being inlined\n\t\t\t// contains a nullable.wrap that isn't being re-wrapped within the expression being inlined.\n\t\t\treturn base.CanInlineIntoSlot(childIndex, expressionBeingMoved)\n\t\t\t\t&& !expressionBeingMoved.HasFlag(InstructionFlags.MayUnwrapNull);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/PatternMatching.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics.CodeAnalysis;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpartial class ILInstruction\n\t{\n\t\tpublic bool MatchLdcI4(int val)\n\t\t{\n\t\t\treturn OpCode == OpCode.LdcI4 && ((LdcI4)this).Value == val;\n\t\t}\n\n\t\tpublic bool MatchLdcF4(float value)\n\t\t{\n\t\t\treturn MatchLdcF4(out var v) && v == value;\n\t\t}\n\n\t\tpublic bool MatchLdcF8(double value)\n\t\t{\n\t\t\treturn MatchLdcF8(out var v) && v == value;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches ldc.i4, ldc.i8, and extending conversions.\n\t\t/// </summary>\n\t\tpublic bool MatchLdcI(out long val)\n\t\t{\n\t\t\tif (MatchLdcI8(out val))\n\t\t\t\treturn true;\n\t\t\tif (MatchLdcI4(out int intVal))\n\t\t\t{\n\t\t\t\tval = intVal;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (this is Conv conv)\n\t\t\t{\n\t\t\t\tif (conv.Kind == ConversionKind.SignExtend)\n\t\t\t\t{\n\t\t\t\t\treturn conv.Argument.MatchLdcI(out val);\n\t\t\t\t}\n\t\t\t\telse if (conv.Kind == ConversionKind.ZeroExtend && conv.InputType == StackType.I4)\n\t\t\t\t{\n\t\t\t\t\tif (conv.Argument.MatchLdcI(out val))\n\t\t\t\t\t{\n\t\t\t\t\t\t// clear top 32 bits\n\t\t\t\t\t\tval &= uint.MaxValue;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool MatchLdcI(long val)\n\t\t{\n\t\t\treturn MatchLdcI(out long v) && v == val;\n\t\t}\n\n\t\tpublic bool MatchLdLoc(ILVariable? variable)\n\t\t{\n\t\t\tvar inst = this as LdLoc;\n\t\t\treturn inst != null && inst.Variable == variable;\n\t\t}\n\n\t\tpublic bool MatchLdLoca(ILVariable? variable)\n\t\t{\n\t\t\tvar inst = this as LdLoca;\n\t\t\treturn inst != null && inst.Variable == variable;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches either ldloc (if the variable is a reference type), or ldloca (otherwise).\n\t\t/// </summary>\n\t\tpublic bool MatchLdLocRef(ILVariable? variable)\n\t\t{\n\t\t\treturn MatchLdLocRef(out var v) && v == variable;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches either ldloc (if the variable is a reference type), or ldloca (otherwise).\n\t\t/// </summary>\n\t\tpublic bool MatchLdLocRef([NotNullWhen(true)] out ILVariable? variable)\n\t\t{\n\t\t\tswitch (this)\n\t\t\t{\n\t\t\t\tcase LdLoc ldloc:\n\t\t\t\t\tvariable = ldloc.Variable;\n\t\t\t\t\treturn variable.Type.IsReferenceType == true;\n\t\t\t\tcase LdLoca ldloca:\n\t\t\t\t\tvariable = ldloca.Variable;\n\t\t\t\t\treturn variable.Type.IsReferenceType != true || variable.Type.Kind == TypeKind.TypeParameter;\n\t\t\t\tdefault:\n\t\t\t\t\tvariable = null;\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool MatchLdThis()\n\t\t{\n\t\t\tvar inst = this as LdLoc;\n\t\t\treturn inst != null && inst.Variable.Kind == VariableKind.Parameter && inst.Variable.Index < 0;\n\t\t}\n\n\t\tpublic bool MatchStLoc([NotNullWhen(true)] out ILVariable? variable)\n\t\t{\n\t\t\tvar inst = this as StLoc;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tvariable = inst.Variable;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvariable = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool MatchStLoc(ILVariable? variable, [NotNullWhen(true)] out ILInstruction? value)\n\t\t{\n\t\t\tvar inst = this as StLoc;\n\t\t\tif (inst != null && inst.Variable == variable)\n\t\t\t{\n\t\t\t\tvalue = inst.Value;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvalue = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool MatchLdLen(StackType type, [NotNullWhen(true)] out ILInstruction? array)\n\t\t{\n\t\t\tvar inst = this as LdLen;\n\t\t\tif (inst != null && inst.ResultType == type)\n\t\t\t{\n\t\t\t\tarray = inst.Array;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tarray = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool MatchReturn([NotNullWhen(true)] out ILInstruction? value)\n\t\t{\n\t\t\tvar inst = this as Leave;\n\t\t\tif (inst != null && inst.IsLeavingFunction)\n\t\t\t{\n\t\t\t\tvalue = inst.Value;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvalue = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool MatchBranch([NotNullWhen(true)] out Block? targetBlock)\n\t\t{\n\t\t\tvar inst = this as Branch;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\ttargetBlock = inst.TargetBlock;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ttargetBlock = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool MatchBranch(Block? targetBlock)\n\t\t{\n\t\t\tvar inst = this as Branch;\n\t\t\treturn inst != null && inst.TargetBlock == targetBlock;\n\t\t}\n\n\t\tpublic bool MatchLeave([NotNullWhen(true)] out BlockContainer? targetContainer, [NotNullWhen(true)] out ILInstruction? value)\n\t\t{\n\t\t\tvar inst = this as Leave;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\ttargetContainer = inst.TargetContainer;\n\t\t\t\tvalue = inst.Value;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ttargetContainer = null;\n\t\t\tvalue = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool MatchLeave(BlockContainer? targetContainer, [NotNullWhen(true)] out ILInstruction? value)\n\t\t{\n\t\t\tvar inst = this as Leave;\n\t\t\tif (inst != null && targetContainer == inst.TargetContainer)\n\t\t\t{\n\t\t\t\tvalue = inst.Value;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvalue = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool MatchLeave([NotNullWhen(true)] out BlockContainer? targetContainer)\n\t\t{\n\t\t\tvar inst = this as Leave;\n\t\t\tif (inst != null && inst.Value.MatchNop())\n\t\t\t{\n\t\t\t\ttargetContainer = inst.TargetContainer;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ttargetContainer = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool MatchLeave(BlockContainer? targetContainer)\n\t\t{\n\t\t\tvar inst = this as Leave;\n\t\t\treturn inst != null && inst.TargetContainer == targetContainer && inst.Value.MatchNop();\n\t\t}\n\n\t\tpublic bool MatchIfInstruction([NotNullWhen(true)] out ILInstruction? condition, [NotNullWhen(true)] out ILInstruction? trueInst, [NotNullWhen(true)] out ILInstruction? falseInst)\n\t\t{\n\t\t\tif (this is IfInstruction inst)\n\t\t\t{\n\t\t\t\tcondition = inst.Condition;\n\t\t\t\ttrueInst = inst.TrueInst;\n\t\t\t\tfalseInst = inst.FalseInst;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tcondition = null;\n\t\t\ttrueInst = null;\n\t\t\tfalseInst = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool MatchIfInstructionPositiveCondition([NotNullWhen(true)] out ILInstruction? condition, [NotNullWhen(true)] out ILInstruction? trueInst, [NotNullWhen(true)] out ILInstruction? falseInst)\n\t\t{\n\t\t\tif (MatchIfInstruction(out condition, out trueInst, out falseInst))\n\t\t\t{\n\t\t\t\t// Swap trueInst<>falseInst for every logic.not in the condition.\n\t\t\t\twhile (condition.MatchLogicNot(out var arg))\n\t\t\t\t{\n\t\t\t\t\tcondition = arg;\n\t\t\t\t\tILInstruction? tmp = trueInst;\n\t\t\t\t\ttrueInst = falseInst;\n\t\t\t\t\tfalseInst = tmp;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches an if instruction where the false instruction is a nop.\n\t\t/// </summary>\n\t\tpublic bool MatchIfInstruction([NotNullWhen(true)] out ILInstruction? condition, [NotNullWhen(true)] out ILInstruction? trueInst)\n\t\t{\n\t\t\tvar inst = this as IfInstruction;\n\t\t\tif (inst != null && inst.FalseInst.MatchNop())\n\t\t\t{\n\t\t\t\tcondition = inst.Condition;\n\t\t\t\ttrueInst = inst.TrueInst;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tcondition = null;\n\t\t\ttrueInst = null;\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches a 'logic and' instruction (\"if (a) b else ldc.i4 0\").\n\t\t/// Note: unlike C# '&amp;&amp;', this instruction is not limited to booleans,\n\t\t/// but allows passing through arbitrary I4 values on the rhs (but not on the lhs).\n\t\t/// </summary>\n\t\tpublic bool MatchLogicAnd([NotNullWhen(true)] out ILInstruction? lhs, [NotNullWhen(true)] out ILInstruction? rhs)\n\t\t{\n\t\t\tvar inst = this as IfInstruction;\n\t\t\tif (inst != null && inst.FalseInst.MatchLdcI4(0))\n\t\t\t{\n\t\t\t\tlhs = inst.Condition;\n\t\t\t\trhs = inst.TrueInst;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tlhs = null;\n\t\t\trhs = null;\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches a 'logic or' instruction (\"if (a) ldc.i4 1 else b\").\n\t\t/// Note: unlike C# '||', this instruction is not limited to booleans,\n\t\t/// but allows passing through arbitrary I4 values on the rhs (but not on the lhs).\n\t\t/// </summary>\n\t\tpublic bool MatchLogicOr([NotNullWhen(true)] out ILInstruction? lhs, [NotNullWhen(true)] out ILInstruction? rhs)\n\t\t{\n\t\t\tvar inst = this as IfInstruction;\n\t\t\tif (inst != null && inst.TrueInst.MatchLdcI4(1))\n\t\t\t{\n\t\t\t\tlhs = inst.Condition;\n\t\t\t\trhs = inst.FalseInst;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tlhs = null;\n\t\t\trhs = null;\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches an logical negation.\n\t\t/// </summary>\n\t\tpublic bool MatchLogicNot([NotNullWhen(true)] out ILInstruction? arg)\n\t\t{\n\t\t\tif (this is Comp comp && comp.Kind == ComparisonKind.Equality\n\t\t\t\t&& comp.LiftingKind == ComparisonLiftingKind.None\n\t\t\t\t&& comp.Right.MatchLdcI4(0))\n\t\t\t{\n\t\t\t\targ = comp.Left;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\targ = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool MatchTryCatchHandler([NotNullWhen(true)] out ILVariable? variable)\n\t\t{\n\t\t\tvar inst = this as TryCatchHandler;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tvariable = inst.Variable;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvariable = null;\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches comp(left == right) or logic.not(comp(left != right)).\n\t\t/// </summary>\n\t\tpublic bool MatchCompEquals([NotNullWhen(true)] out ILInstruction? left, [NotNullWhen(true)] out ILInstruction? right)\n\t\t{\n\t\t\tILInstruction thisInst = this;\n\t\t\tvar compKind = ComparisonKind.Equality;\n\t\t\twhile (thisInst.MatchLogicNot(out var arg) && arg is Comp)\n\t\t\t{\n\t\t\t\tthisInst = arg;\n\t\t\t\tif (compKind == ComparisonKind.Equality)\n\t\t\t\t\tcompKind = ComparisonKind.Inequality;\n\t\t\t\telse\n\t\t\t\t\tcompKind = ComparisonKind.Equality;\n\t\t\t}\n\t\t\tif (thisInst is Comp comp && comp.Kind == compKind && !comp.IsLifted)\n\t\t\t{\n\t\t\t\tleft = comp.Left;\n\t\t\t\tright = comp.Right;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tleft = null;\n\t\t\t\tright = null;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches 'comp(arg == ldnull)'\n\t\t/// </summary>\n\t\tpublic bool MatchCompEqualsNull([NotNullWhen(true)] out ILInstruction? arg)\n\t\t{\n\t\t\tif (!MatchCompEquals(out var left, out var right))\n\t\t\t{\n\t\t\t\targ = null;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (right.MatchLdNull())\n\t\t\t{\n\t\t\t\targ = left;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (left.MatchLdNull())\n\t\t\t{\n\t\t\t\targ = right;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\targ = null;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches 'comp(arg != ldnull)'\n\t\t/// </summary>\n\t\tpublic bool MatchCompNotEqualsNull([NotNullWhen(true)] out ILInstruction? arg)\n\t\t{\n\t\t\tif (!MatchCompNotEquals(out var left, out var right))\n\t\t\t{\n\t\t\t\targ = null;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (right.MatchLdNull())\n\t\t\t{\n\t\t\t\targ = left;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (left.MatchLdNull())\n\t\t\t{\n\t\t\t\targ = right;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\targ = null;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches comp(left != right) or logic.not(comp(left == right)).\n\t\t/// </summary>\n\t\tpublic bool MatchCompNotEquals([NotNullWhen(true)] out ILInstruction? left, [NotNullWhen(true)] out ILInstruction? right)\n\t\t{\n\t\t\tILInstruction thisInst = this;\n\t\t\tvar compKind = ComparisonKind.Inequality;\n\t\t\twhile (thisInst.MatchLogicNot(out var arg) && arg is Comp)\n\t\t\t{\n\t\t\t\tthisInst = arg;\n\t\t\t\tif (compKind == ComparisonKind.Equality)\n\t\t\t\t\tcompKind = ComparisonKind.Inequality;\n\t\t\t\telse\n\t\t\t\t\tcompKind = ComparisonKind.Equality;\n\t\t\t}\n\t\t\tif (thisInst is Comp comp && comp.Kind == compKind && !comp.IsLifted)\n\t\t\t{\n\t\t\t\tleft = comp.Left;\n\t\t\t\tright = comp.Right;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tleft = null;\n\t\t\t\tright = null;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool MatchLdFld([NotNullWhen(true)] out ILInstruction? target, [NotNullWhen(true)] out IField? field)\n\t\t{\n\t\t\tif (this is LdObj ldobj && ldobj.Target is LdFlda ldflda && ldobj.UnalignedPrefix == 0 && !ldobj.IsVolatile)\n\t\t\t{\n\t\t\t\tfield = ldflda.Field;\n\t\t\t\tif (field.DeclaringType.IsReferenceType == true || !ldflda.Target.MatchAddressOf(out target, out _))\n\t\t\t\t{\n\t\t\t\t\ttarget = ldflda.Target;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ttarget = null;\n\t\t\tfield = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool MatchLdsFld([NotNullWhen(true)] out IField? field)\n\t\t{\n\t\t\tif (this is LdObj ldobj && ldobj.Target is LdsFlda ldsflda && ldobj.UnalignedPrefix == 0 && !ldobj.IsVolatile)\n\t\t\t{\n\t\t\t\tfield = ldsflda.Field;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tfield = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool MatchLdsFld(IField? field)\n\t\t{\n\t\t\treturn MatchLdsFld(out var f) && f.Equals(field);\n\t\t}\n\n\t\tpublic bool MatchStsFld([NotNullWhen(true)] out IField? field, [NotNullWhen(true)] out ILInstruction? value)\n\t\t{\n\t\t\tif (this is StObj stobj && stobj.Target is LdsFlda ldsflda && stobj.UnalignedPrefix == 0 && !stobj.IsVolatile)\n\t\t\t{\n\t\t\t\tfield = ldsflda.Field;\n\t\t\t\tvalue = stobj.Value;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tfield = null;\n\t\t\tvalue = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool MatchStFld([NotNullWhen(true)] out ILInstruction? target, [NotNullWhen(true)] out IField? field, [NotNullWhen(true)] out ILInstruction? value)\n\t\t{\n\t\t\tif (this is StObj stobj && stobj.Target is LdFlda ldflda && stobj.UnalignedPrefix == 0 && !stobj.IsVolatile)\n\t\t\t{\n\t\t\t\ttarget = ldflda.Target;\n\t\t\t\tfield = ldflda.Field;\n\t\t\t\tvalue = stobj.Value;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ttarget = null;\n\t\t\tfield = null;\n\t\t\tvalue = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool MatchBinaryNumericInstruction(BinaryNumericOperator @operator)\n\t\t{\n\t\t\tvar op = this as BinaryNumericInstruction;\n\t\t\treturn op != null && op.Operator == @operator;\n\t\t}\n\n\t\tpublic bool MatchBinaryNumericInstruction(BinaryNumericOperator @operator, [NotNullWhen(true)] out ILInstruction? left, [NotNullWhen(true)] out ILInstruction? right)\n\t\t{\n\t\t\tvar op = this as BinaryNumericInstruction;\n\t\t\tif (op != null && op.Operator == @operator)\n\t\t\t{\n\t\t\t\tleft = op.Left;\n\t\t\t\tright = op.Right;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tleft = null;\n\t\t\tright = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool MatchBinaryNumericInstruction(out BinaryNumericOperator @operator, [NotNullWhen(true)] out ILInstruction? left, [NotNullWhen(true)] out ILInstruction? right)\n\t\t{\n\t\t\tvar op = this as BinaryNumericInstruction;\n\t\t\tif (op != null)\n\t\t\t{\n\t\t\t\t@operator = op.Operator;\n\t\t\t\tleft = op.Left;\n\t\t\t\tright = op.Right;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\t@operator = BinaryNumericOperator.None;\n\t\t\tleft = null;\n\t\t\tright = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool MatchDefaultOrNullOrZero()\n\t\t{\n\t\t\tswitch (this)\n\t\t\t{\n\t\t\t\tcase LdNull _:\n\t\t\t\tcase LdcF4 { Value: 0 }:\n\t\t\t\tcase LdcF8 { Value: 0 }:\n\t\t\t\tcase LdcI4 { Value: 0 }:\n\t\t\t\tcase LdcI8 { Value: 0 }:\n\t\t\t\tcase DefaultValue _:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// If this instruction is a conversion of the specified kind, return its argument.\n\t\t/// Otherwise, return the instruction itself.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Does not unwrap lifted conversions.\n\t\t/// </remarks>\n\t\tpublic virtual ILInstruction UnwrapConv(ConversionKind kind)\n\t\t{\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic bool MatchLdObj([NotNullWhen(true)] out ILInstruction? target, IType type)\n\t\t{\n\t\t\tvar inst = this as LdObj;\n\t\t\tif (inst != null && inst.Type.Equals(type))\n\t\t\t{\n\t\t\t\ttarget = inst.Target;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ttarget = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// A simple instruction that does not have any arguments.\n\t/// </summary>\n\tpublic abstract partial class SimpleInstruction : ILInstruction\n\t{\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\t// the non-custom WriteTo would add useless parentheses\n\t\t}\n\t}\n\n\tpublic enum NopKind\n\t{\n\t\tNormal,\n\t\tPop\n\t}\n\n\tpartial class Nop\n\t{\n\t\tpublic string? Comment;\n\n\t\tpublic NopKind Kind;\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tif (Kind != NopKind.Normal)\n\t\t\t{\n\t\t\t\toutput.Write(\".\" + Kind.ToString().ToLowerInvariant());\n\t\t\t}\n\t\t\tif (!string.IsNullOrEmpty(Comment))\n\t\t\t{\n\t\t\t\toutput.Write(\" // \" + Comment);\n\t\t\t}\n\t\t}\n\t}\n\n\tpartial class InvalidBranch : SimpleInstruction\n\t{\n\t\tpublic string? Message;\n\t\tpublic StackType ExpectedResultType = StackType.Void;\n\n\t\tpublic InvalidBranch(string? message) : this()\n\t\t{\n\t\t\tthis.Message = message;\n\t\t}\n\n\t\tpublic override StackType ResultType {\n\t\t\tget { return ExpectedResultType; }\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tif (!string.IsNullOrEmpty(Message))\n\t\t\t{\n\t\t\t\toutput.Write(\"(\\\"\");\n\t\t\t\toutput.Write(Message);\n\t\t\t\toutput.Write(\"\\\")\");\n\t\t\t}\n\t\t}\n\t}\n\n\tpartial class InvalidExpression : SimpleInstruction\n\t{\n\t\tpublic string Severity = \"Error\";\n\t\tpublic string? Message;\n\t\tpublic StackType ExpectedResultType = StackType.Unknown;\n\n\t\tpublic InvalidExpression(string? message) : this()\n\t\t{\n\t\t\tthis.Message = message;\n\t\t}\n\n\t\tpublic override StackType ResultType {\n\t\t\tget { return ExpectedResultType; }\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tif (!string.IsNullOrEmpty(Message))\n\t\t\t{\n\t\t\t\toutput.Write(\"(\\\"\");\n\t\t\t\toutput.Write(Message);\n\t\t\t\toutput.Write(\"\\\")\");\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/StLoc.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpartial class StLoc\n\t{\n\t\t/// <summary>\n\t\t/// If true, this stloc represents a stack type adjustment.\n\t\t/// This field is only used in ILReader and BlockBuilder, and should be ignored by ILAst transforms.\n\t\t/// </summary>\n\t\tinternal bool IsStackAdjustment;\n\n\t\t/// <summary>\n\t\t/// Gets whether the IL stack was empty after this store.\n\t\t/// Only set for store instructions from the IL; not for stores to the stack\n\t\t/// or other stores generated by transforms.\n\t\t/// </summary>\n\t\tinternal bool ILStackWasEmpty;\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebug.Assert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function!));\n\t\t\tDebug.Assert(phase <= ILPhase.InILReader || variable.Function!.Variables[variable.IndexInFunction] == variable);\n\t\t\tDebug.Assert(value.ResultType == variable.StackType);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs",
    "content": "#nullable enable\n// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpartial class StringToInt\n\t{\n\t\tpublic List<(string? Key, int Value)> Map { get; }\n\n\t\tpublic IType ExpectedType { get; }\n\n\t\tpublic StringToInt(ILInstruction argument, List<(string? Key, int Value)> map, IType expectedType)\n\t\t\t: base(OpCode.StringToInt)\n\t\t{\n\t\t\tthis.Argument = argument;\n\t\t\tthis.Map = map;\n\t\t\tthis.ExpectedType = expectedType;\n\t\t}\n\n\t\tpublic StringToInt(ILInstruction argument, string?[] map, IType expectedType)\n\t\t\t: this(argument, ArrayToDictionary(map), expectedType)\n\t\t{\n\t\t}\n\n\t\tstatic List<(string? Key, int Value)> ArrayToDictionary(string?[] map)\n\t\t{\n\t\t\tvar dict = new List<(string? Key, int Value)>();\n\t\t\tfor (int i = 0; i < map.Length; i++)\n\t\t\t{\n\t\t\t\tdict.Add((map[i], i));\n\t\t\t}\n\t\t\treturn dict;\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(\"string.to.int \");\n\t\t\tExpectedType.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tArgument.WriteTo(output, options);\n\t\t\toutput.Write(\", { \");\n\t\t\tint i = 0;\n\t\t\tforeach (var entry in Map)\n\t\t\t{\n\t\t\t\tif (i > 0)\n\t\t\t\t\toutput.Write(\", \");\n\t\t\t\tif (entry.Key is null)\n\t\t\t\t\toutput.Write($\"[null] = {entry.Value}\");\n\t\t\t\telse\n\t\t\t\t\toutput.Write($\"[\\\"{entry.Key}\\\"] = {entry.Value}\");\n\t\t\t\ti++;\n\t\t\t}\n\t\t\toutput.Write(\" })\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/SwitchInstruction.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// Generalization of IL switch-case: like a VB switch over integers, this instruction\n\t/// supports integer value ranges as labels.\n\t/// \n\t/// The section labels are using 'long' as integer type.\n\t/// If the Value instruction produces StackType.I4 or I, the value is implicitly sign-extended to I8.\n\t/// </summary>\n\tpartial class SwitchInstruction\n\t{\n\t\tpublic static readonly SlotInfo ValueSlot = new SlotInfo(\"Value\", canInlineInto: true);\n\t\tpublic static readonly SlotInfo SectionSlot = new SlotInfo(\"Section\", isCollection: true);\n\n\t\t/// <summary>\n\t\t/// If the switch instruction is lifted, the value instruction produces a value of type <c>Nullable{T}</c> for some\n\t\t/// integral type T. The section with <c>SwitchSection.HasNullLabel</c> is called if the value is null.\n\t\t/// </summary>\n\t\tpublic bool IsLifted;\n\n\t\t/// <summary>\n\t\t/// Additional type information used to interpret the value instruction.\n\t\t/// Set by ILInlining to preserve stack information that would otherwise be lost.\n\t\t/// </summary>\n\t\tpublic IType? Type;\n\n\t\tpublic SwitchInstruction(ILInstruction value)\n\t\t\t: base(OpCode.SwitchInstruction)\n\t\t{\n\t\t\tthis.Value = value;\n\t\t\tthis.Sections = new InstructionCollection<SwitchSection>(this, 1);\n\t\t}\n\n\t\tILInstruction value = null!;\n\t\tpublic ILInstruction Value {\n\t\t\tget { return this.value; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.value, value, 0);\n\t\t\t}\n\t\t}\n\n\t\tpublic readonly InstructionCollection<SwitchSection> Sections;\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\tvar sectionFlags = InstructionFlags.EndPointUnreachable; // neutral element for CombineBranches()\n\t\t\tforeach (var section in Sections)\n\t\t\t{\n\t\t\t\tsectionFlags = SemanticHelper.CombineBranches(sectionFlags, section.Flags);\n\t\t\t}\n\t\t\treturn value.Flags | InstructionFlags.ControlFlow | sectionFlags;\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.ControlFlow;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(\"switch\");\n\t\t\tif (IsLifted)\n\t\t\t\toutput.Write(\".lifted\");\n\t\t\toutput.Write(' ');\n\t\t\tType?.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tvalue.WriteTo(output, options);\n\t\t\toutput.Write(\") \");\n\t\t\toutput.MarkFoldStart(\"{...}\");\n\t\t\toutput.WriteLine(\"{\");\n\t\t\toutput.Indent();\n\t\t\tforeach (var section in this.Sections)\n\t\t\t{\n\t\t\t\tsection.WriteTo(output, options);\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t\toutput.Unindent();\n\t\t\toutput.Write('}');\n\t\t\toutput.MarkFoldEnd();\n\t\t}\n\n\t\tprotected override int GetChildCount()\n\t\t{\n\t\t\treturn 1 + Sections.Count;\n\t\t}\n\n\t\tprotected override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tif (index == 0)\n\t\t\t\treturn value;\n\t\t\treturn Sections[index - 1];\n\t\t}\n\n\t\tprotected override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tif (index == 0)\n\t\t\t\tValue = value;\n\t\t\telse\n\t\t\t\tSections[index - 1] = (SwitchSection)value;\n\t\t}\n\n\t\tprotected override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tif (index == 0)\n\t\t\t\treturn ValueSlot;\n\t\t\treturn SectionSlot;\n\t\t}\n\n\t\tpublic override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = new SwitchInstruction(value.Clone());\n\t\t\tclone.AddILRange(this);\n\t\t\tclone.Value = value.Clone();\n\t\t\tclone.Sections.AddRange(this.Sections.Select(h => (SwitchSection)h.Clone()));\n\t\t\treturn clone;\n\t\t}\n\n\t\tStackType resultType = StackType.Void;\n\n\t\tpublic override StackType ResultType => resultType;\n\n\t\tpublic void SetResultType(StackType resultType)\n\t\t{\n\t\t\tthis.resultType = resultType;\n\t\t}\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tbool expectNullSection = this.IsLifted;\n\t\t\tLongSet sets = LongSet.Empty;\n\t\t\tforeach (var section in Sections)\n\t\t\t{\n\t\t\t\tif (section.HasNullLabel)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(expectNullSection, \"Duplicate 'case null' or 'case null' in non-lifted switch.\");\n\t\t\t\t\texpectNullSection = false;\n\t\t\t\t}\n\t\t\t\tDebug.Assert(!section.Labels.IsEmpty || section.HasNullLabel);\n\t\t\t\tDebug.Assert(!section.Labels.Overlaps(sets));\n\t\t\t\tDebug.Assert(section.Body.ResultType == this.ResultType);\n\t\t\t\tsets = sets.UnionWith(section.Labels);\n\t\t\t}\n\t\t\tDebug.Assert(sets.SetEquals(LongSet.Universe), \"switch does not handle all possible cases\");\n\t\t\tDebug.Assert(!expectNullSection, \"Lifted switch is missing 'case null'\");\n\t\t\tDebug.Assert(this.IsLifted ? (value.ResultType == StackType.O) : (value.ResultType == StackType.I4 || value.ResultType == StackType.I8));\n\t\t}\n\n\t\tpublic SwitchSection GetDefaultSection()\n\t\t{\n\t\t\t// Pick the section with the most labels as default section.\n\t\t\tIL.SwitchSection defaultSection = Sections.First();\n\t\t\tforeach (var section in Sections)\n\t\t\t{\n\t\t\t\tif (section.Labels.Count() > defaultSection.Labels.Count())\n\t\t\t\t{\n\t\t\t\t\tdefaultSection = section;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn defaultSection;\n\t\t}\n\t}\n\n\tpartial class SwitchSection\n\t{\n\t\tpublic SwitchSection()\n\t\t\t: base(OpCode.SwitchSection)\n\t\t{\n\t\t\tthis.Labels = LongSet.Empty;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// If true, serves as 'case null' in a lifted switch.\n\t\t/// </summary>\n\t\tpublic bool HasNullLabel { get; set; }\n\n\t\t/// <summary>\n\t\t/// The set of labels that cause execution to jump to this switch section.\n\t\t/// </summary>\n\t\tpublic LongSet Labels { get; set; }\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn body.Flags;\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.None;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.WriteLocalReference(\"case\", this, isDefinition: true);\n\t\t\toutput.Write(' ');\n\t\t\tif (HasNullLabel)\n\t\t\t{\n\t\t\t\toutput.Write(\"null\");\n\t\t\t\tif (!Labels.IsEmpty)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\", \");\n\t\t\t\t\toutput.Write(Labels.ToString());\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\toutput.Write(Labels.ToString());\n\t\t\t}\n\t\t\toutput.Write(\": \");\n\n\t\t\tbody.WriteTo(output, options);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/TryInstruction.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpublic abstract class TryInstruction : ILInstruction\n\t{\n\t\tpublic static readonly SlotInfo TryBlockSlot = new SlotInfo(\"TryBlock\");\n\n\t\tprotected TryInstruction(OpCode opCode, ILInstruction tryBlock) : base(opCode)\n\t\t{\n\t\t\tthis.TryBlock = tryBlock;\n\t\t}\n\n\t\tILInstruction tryBlock = null!;\n\t\tpublic ILInstruction TryBlock {\n\t\t\tget { return this.tryBlock; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.tryBlock, value, 0);\n\t\t\t}\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Try-catch statement.\n\t/// </summary>\n\t/// <remarks>\n\t/// The return value of the try or catch blocks is ignored, the TryCatch always returns void.\n\t/// </remarks>\n\tpartial class TryCatch : TryInstruction\n\t{\n\t\tpublic static readonly SlotInfo HandlerSlot = new SlotInfo(\"Handler\", isCollection: true);\n\t\tpublic readonly InstructionCollection<TryCatchHandler> Handlers;\n\n\t\tpublic TryCatch(ILInstruction tryBlock) : base(OpCode.TryCatch, tryBlock)\n\t\t{\n\t\t\tthis.Handlers = new InstructionCollection<TryCatchHandler>(this, 1);\n\t\t}\n\n\t\tpublic override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = new TryCatch(TryBlock.Clone());\n\t\t\tclone.AddILRange(this);\n\t\t\tclone.Handlers.AddRange(this.Handlers.Select(h => (TryCatchHandler)h.Clone()));\n\t\t\treturn clone;\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(\".try \");\n\t\t\tTryBlock.WriteTo(output, options);\n\t\t\tforeach (var handler in Handlers)\n\t\t\t{\n\t\t\t\toutput.Write(' ');\n\t\t\t\thandler.WriteTo(output, options);\n\t\t\t}\n\t\t}\n\n\t\tpublic override StackType ResultType {\n\t\t\tget { return StackType.Void; }\n\t\t}\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\tvar flags = TryBlock.Flags;\n\t\t\tforeach (var handler in Handlers)\n\t\t\t\tflags = SemanticHelper.CombineBranches(flags, handler.Flags);\n\t\t\treturn flags | InstructionFlags.ControlFlow;\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.ControlFlow;\n\t\t\t}\n\t\t}\n\n\t\tprotected override int GetChildCount()\n\t\t{\n\t\t\treturn 1 + Handlers.Count;\n\t\t}\n\n\t\tprotected override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tif (index == 0)\n\t\t\t\treturn TryBlock;\n\t\t\telse\n\t\t\t\treturn Handlers[index - 1];\n\t\t}\n\n\t\tprotected override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tif (index == 0)\n\t\t\t\tTryBlock = value;\n\t\t\telse\n\t\t\t\tHandlers[index - 1] = (TryCatchHandler)value;\n\t\t}\n\n\t\tprotected override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tif (index == 0)\n\t\t\t\treturn TryBlockSlot;\n\t\t\telse\n\t\t\t\treturn HandlerSlot;\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Catch handler within a try-catch statement.\n\t/// \n\t/// When an exception occurs in the try block of the parent try.catch statement, the runtime searches\n\t/// the nearest enclosing TryCatchHandler with a matching variable type and\n\t/// assigns the exception object to the <see cref=\"Variable\"/>, and executes the <see cref=\"Filter\"/>.\n\t/// If the filter evaluates to 0, the exception is not caught and the runtime looks for the next catch handler.\n\t/// If the filter evaluates to 1, the stack is unwound, the exception caught and assigned to the <see cref=\"Variable\"/>,\n\t/// and the <see cref=\"Body\"/> is executed.\n\t/// </summary>\n\tpartial class TryCatchHandler\n\t{\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebug.Assert(Parent is TryCatch);\n\t\t\tDebug.Assert(filter.ResultType == StackType.I4);\n\t\t\tDebug.Assert(this.IsDescendantOf(variable.Function!));\n\t\t}\n\n\t\tpublic override StackType ResultType {\n\t\t\tget { return StackType.Void; }\n\t\t}\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn filter.Flags | body.Flags | InstructionFlags.ControlFlow | InstructionFlags.MayWriteLocals;\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\t// the body is not evaluated if the filter returns 0\n\t\t\t\treturn InstructionFlags.ControlFlow | InstructionFlags.MayWriteLocals;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(\"catch \");\n\t\t\tif (variable != null)\n\t\t\t{\n\t\t\t\toutput.WriteLocalReference(variable.Name, variable, isDefinition: true);\n\t\t\t\toutput.Write(\" : \");\n\t\t\t\tDisassembler.DisassemblerHelpers.WriteOperand(output, variable.Type);\n\t\t\t}\n\t\t\toutput.Write(\" when (\");\n\t\t\tfilter.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t\toutput.Write(' ');\n\t\t\tbody.WriteTo(output, options);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the ILRange of the instructions at the start of the catch-block,\n\t\t/// that take the exception object and store it in the exception variable slot.\n\t\t/// Note: This range is empty, if Filter is not empty, i.e., ldloc 1.\n\t\t/// </summary>\n\t\tpublic Interval ExceptionSpecifierILRange { get; private set; }\n\n\t\tpublic void AddExceptionSpecifierILRange(Interval newRange)\n\t\t{\n\t\t\tExceptionSpecifierILRange = CombineILRange(ExceptionSpecifierILRange, newRange);\n\t\t}\n\t}\n\n\tpartial class TryFinally\n\t{\n\t\tpublic static readonly SlotInfo FinallyBlockSlot = new SlotInfo(\"FinallyBlock\");\n\n\t\tpublic TryFinally(ILInstruction tryBlock, ILInstruction finallyBlock) : base(OpCode.TryFinally, tryBlock)\n\t\t{\n\t\t\tthis.FinallyBlock = finallyBlock;\n\t\t}\n\n\t\tILInstruction finallyBlock = null!;\n\t\tpublic ILInstruction FinallyBlock {\n\t\t\tget { return this.finallyBlock; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.finallyBlock, value, 1);\n\t\t\t}\n\t\t}\n\n\t\tpublic override ILInstruction Clone()\n\t\t{\n\t\t\treturn new TryFinally(TryBlock.Clone(), finallyBlock.Clone()).WithILRange(this);\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(\".try \");\n\t\t\tTryBlock.WriteTo(output, options);\n\t\t\toutput.Write(\" finally \");\n\t\t\tfinallyBlock.WriteTo(output, options);\n\t\t}\n\n\t\tpublic override StackType ResultType {\n\t\t\tget {\n\t\t\t\treturn TryBlock.ResultType;\n\t\t\t}\n\t\t}\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\t// if the endpoint of either the try or the finally is unreachable, the endpoint of the try-finally will be unreachable\n\t\t\treturn TryBlock.Flags | finallyBlock.Flags | InstructionFlags.ControlFlow;\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.ControlFlow;\n\t\t\t}\n\t\t}\n\n\t\tprotected override int GetChildCount()\n\t\t{\n\t\t\treturn 2;\n\t\t}\n\n\t\tprotected override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn TryBlock;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn finallyBlock;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\n\t\tprotected override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tTryBlock = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tFinallyBlock = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\n\t\tprotected override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn TryBlockSlot;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn FinallyBlockSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t}\n\n\tpartial class TryFault\n\t{\n\t\tpublic static readonly SlotInfo FaultBlockSlot = new SlotInfo(\"FaultBlock\");\n\n\t\tpublic TryFault(ILInstruction tryBlock, ILInstruction faultBlock) : base(OpCode.TryFinally, tryBlock)\n\t\t{\n\t\t\tthis.FaultBlock = faultBlock;\n\t\t}\n\n\t\tILInstruction faultBlock = null!;\n\t\tpublic ILInstruction FaultBlock {\n\t\t\tget { return this.faultBlock; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.faultBlock, value, 1);\n\t\t\t}\n\t\t}\n\n\t\tpublic override ILInstruction Clone()\n\t\t{\n\t\t\treturn new TryFault(TryBlock.Clone(), faultBlock.Clone()).WithILRange(this);\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(\".try \");\n\t\t\tTryBlock.WriteTo(output, options);\n\t\t\toutput.Write(\" fault \");\n\t\t\tfaultBlock.WriteTo(output, options);\n\t\t}\n\n\t\tpublic override StackType ResultType {\n\t\t\tget { return TryBlock.ResultType; }\n\t\t}\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\t// The endpoint of the try-fault is unreachable iff the try endpoint is unreachable\n\t\t\treturn TryBlock.Flags | (faultBlock.Flags & ~InstructionFlags.EndPointUnreachable) | InstructionFlags.ControlFlow;\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.ControlFlow;\n\t\t\t}\n\t\t}\n\n\t\tprotected override int GetChildCount()\n\t\t{\n\t\t\treturn 2;\n\t\t}\n\n\t\tprotected override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn TryBlock;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn faultBlock;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\n\t\tprotected override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tTryBlock = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tFaultBlock = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\n\t\tprotected override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn TryBlockSlot;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn FaultBlockSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic partial class Throw\n\t{\n\t\tinternal StackType resultType = StackType.Void;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/UnaryInstruction.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpartial class BitNot : ILiftableInstruction\n\t{\n\t\tpublic BitNot(ILInstruction arg) : base(OpCode.BitNot, arg)\n\t\t{\n\t\t\tthis.UnderlyingResultType = arg.ResultType;\n\t\t}\n\n\t\tpublic BitNot(ILInstruction arg, bool isLifted, StackType stackType) : base(OpCode.BitNot, arg)\n\t\t{\n\t\t\tthis.IsLifted = isLifted;\n\t\t\tthis.UnderlyingResultType = stackType;\n\t\t}\n\n\t\tpublic bool IsLifted { get; }\n\t\tpublic StackType UnderlyingResultType { get; }\n\n\t\tpublic override StackType ResultType {\n\t\t\tget {\n\t\t\t\treturn Argument.ResultType;\n\t\t\t}\n\t\t}\n\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebug.Assert(IsLifted == (ResultType == StackType.O));\n\t\t\tDebug.Assert(IsLifted || ResultType == UnderlyingResultType);\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tif (IsLifted)\n\t\t\t{\n\t\t\t\toutput.Write(\".lifted\");\n\t\t\t}\n\t\t\toutput.Write('(');\n\t\t\tthis.Argument.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions/UsingInstruction.cs",
    "content": "#nullable enable\n// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// IL using instruction.\n\t/// Equivalent to:\n\t/// <code>\n\t/// stloc v(resourceExpression)\n\t/// try {\n\t///    body\n\t/// } finally {\n\t///    v?.Dispose();\n\t/// }\n\t/// </code>\n\t/// </summary>\n\t/// <remarks>\n\t/// The value of v is undefined after the end of the body block.\n\t/// </remarks>\n\tpartial class UsingInstruction\n\t{\n\t\tpublic bool IsAsync { get; set; }\n\n\t\tpublic bool IsRefStruct { get; set; }\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(\"using\");\n\t\t\tif (IsAsync)\n\t\t\t{\n\t\t\t\toutput.Write(\".async\");\n\t\t\t}\n\t\t\tif (IsRefStruct)\n\t\t\t{\n\t\t\t\toutput.Write(\".ref\");\n\t\t\t}\n\t\t\toutput.Write(\" (\");\n\t\t\tVariable.WriteTo(output);\n\t\t\toutput.Write(\" = \");\n\t\t\tResourceExpression.WriteTo(output, options);\n\t\t\toutput.WriteLine(\") {\");\n\t\t\toutput.Indent();\n\t\t\tBody.WriteTo(output, options);\n\t\t\toutput.Unindent();\n\t\t\toutput.WriteLine();\n\t\t\toutput.Write(\"}\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions.cs",
    "content": "// Copyright (c) 2014-2020 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// Enum representing the type of an <see cref=\"ILInstruction\"/>.\n\t/// </summary>\n\tpublic enum OpCode : byte\n\t{\n\t\t/// <summary>Represents invalid IL. Semantically, this instruction is considered to throw some kind of exception.</summary>\n\t\tInvalidBranch,\n\t\t/// <summary>Represents invalid IL. Semantically, this instruction is considered to produce some kind of value.</summary>\n\t\tInvalidExpression,\n\t\t/// <summary>No operation. Takes 0 arguments and returns void.</summary>\n\t\tNop,\n\t\t/// <summary>A container of IL blocks.</summary>\n\t\tILFunction,\n\t\t/// <summary>A container of IL blocks.</summary>\n\t\tBlockContainer,\n\t\t/// <summary>A block of IL instructions.</summary>\n\t\tBlock,\n\t\t/// <summary>A region where a pinned variable is used (initial representation of future fixed statement).</summary>\n\t\tPinnedRegion,\n\t\t/// <summary>Common instruction for add, sub, mul, div, rem, bit.and, bit.or, bit.xor, shl and shr.</summary>\n\t\tBinaryNumericInstruction,\n\t\t/// <summary>Common instruction for numeric compound assignments.</summary>\n\t\tNumericCompoundAssign,\n\t\t/// <summary>Common instruction for user-defined compound assignments.</summary>\n\t\tUserDefinedCompoundAssign,\n\t\t/// <summary>Common instruction for dynamic compound assignments.</summary>\n\t\tDynamicCompoundAssign,\n\t\t/// <summary>Bitwise NOT</summary>\n\t\tBitNot,\n\t\t/// <summary>Retrieves the RuntimeArgumentHandle.</summary>\n\t\tArglist,\n\t\t/// <summary>Unconditional branch. <c>goto target;</c></summary>\n\t\tBranch,\n\t\t/// <summary>Unconditional branch to end of block container. Return is represented using IsLeavingFunction and an (optional) return value. The block container evaluates to the value produced by the argument of the leave instruction.</summary>\n\t\tLeave,\n\t\t/// <summary>If statement / conditional expression. <c>if (condition) trueExpr else falseExpr</c></summary>\n\t\tIfInstruction,\n\t\t/// <summary>Null coalescing operator expression. <c>if.notnull(valueInst, fallbackInst)</c></summary>\n\t\tNullCoalescingInstruction,\n\t\t/// <summary>Switch statement</summary>\n\t\tSwitchInstruction,\n\t\t/// <summary>Switch section within a switch statement</summary>\n\t\tSwitchSection,\n\t\t/// <summary>Try-catch statement.</summary>\n\t\tTryCatch,\n\t\t/// <summary>Catch handler within a try-catch statement.</summary>\n\t\tTryCatchHandler,\n\t\t/// <summary>Try-finally statement</summary>\n\t\tTryFinally,\n\t\t/// <summary>Try-fault statement</summary>\n\t\tTryFault,\n\t\t/// <summary>Lock statement</summary>\n\t\tLockInstruction,\n\t\t/// <summary>Using statement</summary>\n\t\tUsingInstruction,\n\t\t/// <summary>Breakpoint instruction</summary>\n\t\tDebugBreak,\n\t\t/// <summary>Comparison. The inputs must be both integers; or both floats; or both object references. Object references can only be compared for equality or inequality. Floating-point comparisons evaluate to 0 (false) when an input is NaN, except for 'NaN != NaN' which evaluates to 1 (true).</summary>\n\t\tComp,\n\t\t/// <summary>Non-virtual method call.</summary>\n\t\tCall,\n\t\t/// <summary>Virtual method call.</summary>\n\t\tCallVirt,\n\t\t/// <summary>Unsafe function pointer call.</summary>\n\t\tCallIndirect,\n\t\t/// <summary>Checks that the input float is not NaN or infinite.</summary>\n\t\tCkfinite,\n\t\t/// <summary>Numeric cast.</summary>\n\t\tConv,\n\t\t/// <summary>Loads the value of a local variable. (ldarg/ldloc)</summary>\n\t\tLdLoc,\n\t\t/// <summary>Loads the address of a local variable. (ldarga/ldloca)</summary>\n\t\tLdLoca,\n\t\t/// <summary>Stores a value into a local variable. (IL: starg/stloc)\n\t\t/// Evaluates to the value that was stored (for byte/short variables: evaluates to the truncated value, sign/zero extended back to I4 based on variable.Type.GetSign())</summary>\n\t\tStLoc,\n\t\t/// <summary>Stores the value into an anonymous temporary variable, and returns the address of that variable.</summary>\n\t\tAddressOf,\n\t\t/// <summary>Three valued logic and. Inputs are of type bool? or I4, output is of type bool?. Unlike logic.and(), does not have short-circuiting behavior.</summary>\n\t\tThreeValuedBoolAnd,\n\t\t/// <summary>Three valued logic or. Inputs are of type bool? or I4, output is of type bool?. Unlike logic.or(), does not have short-circuiting behavior.</summary>\n\t\tThreeValuedBoolOr,\n\t\t/// <summary>The input operand must be one of:\n\t\t///   1. a nullable value type\n\t\t///   2. a reference type\n\t\t///   3. a managed reference to a type parameter.\n\t\t/// If the input is non-null, evaluates to the (unwrapped) input.\n\t\t/// If the input is null, jumps to the innermost nullable.rewrap instruction that contains this instruction.\n\t\t/// In case 3 (managed reference), the dereferenced value is the input being tested, and the nullable.unwrap instruction returns the managed reference unmodified (if the value is non-null).</summary>\n\t\tNullableUnwrap,\n\t\t/// <summary>Serves as jump target for the nullable.unwrap instruction.\n\t\t/// If the input evaluates normally, evaluates to the input value (wrapped in Nullable&lt;T&gt; if the input is a non-nullable value type).If a nullable.unwrap instruction encounters a null input and jumps to the (endpoint of the) nullable.rewrap instruction,the nullable.rewrap instruction evaluates to null.</summary>\n\t\tNullableRewrap,\n\t\t/// <summary>Loads a constant string.</summary>\n\t\tLdStr,\n\t\t/// <summary>Loads a constant byte string (as ReadOnlySpan&lt;byte&gt;).</summary>\n\t\tLdStrUtf8,\n\t\t/// <summary>Loads a constant 32-bit integer.</summary>\n\t\tLdcI4,\n\t\t/// <summary>Loads a constant 64-bit integer.</summary>\n\t\tLdcI8,\n\t\t/// <summary>Loads a constant 32-bit floating-point number.</summary>\n\t\tLdcF4,\n\t\t/// <summary>Loads a constant 64-bit floating-point number.</summary>\n\t\tLdcF8,\n\t\t/// <summary>Loads a constant decimal.</summary>\n\t\tLdcDecimal,\n\t\t/// <summary>Loads the null reference.</summary>\n\t\tLdNull,\n\t\t/// <summary>Load method pointer</summary>\n\t\tLdFtn,\n\t\t/// <summary>Load method pointer</summary>\n\t\tLdVirtFtn,\n\t\t/// <summary>Virtual delegate construction</summary>\n\t\tLdVirtDelegate,\n\t\t/// <summary>Loads runtime representation of metadata token</summary>\n\t\tLdTypeToken,\n\t\t/// <summary>Loads runtime representation of metadata token</summary>\n\t\tLdMemberToken,\n\t\t/// <summary>Allocates space in the stack frame</summary>\n\t\tLocAlloc,\n\t\t/// <summary>Allocates space in the stack frame and wraps it in a Span</summary>\n\t\tLocAllocSpan,\n\t\t/// <summary>memcpy(destAddress, sourceAddress, size);</summary>\n\t\tCpblk,\n\t\t/// <summary>memset(address, value, size)</summary>\n\t\tInitblk,\n\t\t/// <summary>Load address of instance field</summary>\n\t\tLdFlda,\n\t\t/// <summary>Load static field address</summary>\n\t\tLdsFlda,\n\t\t/// <summary>Casts an object to a class.</summary>\n\t\tCastClass,\n\t\t/// <summary>Test if object is instance of class or interface.</summary>\n\t\tIsInst,\n\t\t/// <summary>Indirect load (ref/pointer dereference).</summary>\n\t\tLdObj,\n\t\t/// <summary>If argument is a ref to a reference type, loads the object reference, stores it in a temporary, and evaluates to the address of that temporary (address.of(ldobj(arg))). Otherwise, returns the argument ref as-is.<para>This instruction represents the memory-load semantics of callvirt with a generic type as receiver (where the IL always takes a ref, but only methods on value types expect one, for method on reference types there's an implicit ldobj, which this instruction makes explicit in order to preserve the order-of-evaluation).</para></summary>\n\t\tLdObjIfRef,\n\t\t/// <summary>Indirect store (store to ref/pointer).\n\t\t/// Evaluates to the value that was stored (when using type byte/short: evaluates to the truncated value, sign/zero extended back to I4 based on type.GetSign())</summary>\n\t\tStObj,\n\t\t/// <summary>Boxes a value.</summary>\n\t\tBox,\n\t\t/// <summary>Compute address inside box.</summary>\n\t\tUnbox,\n\t\t/// <summary>Unbox a value.</summary>\n\t\tUnboxAny,\n\t\t/// <summary>Creates an object instance and calls the constructor.</summary>\n\t\tNewObj,\n\t\t/// <summary>Creates an array instance.</summary>\n\t\tNewArr,\n\t\t/// <summary>Returns the default value for a type.</summary>\n\t\tDefaultValue,\n\t\t/// <summary>Throws an exception.</summary>\n\t\tThrow,\n\t\t/// <summary>Rethrows the current exception.</summary>\n\t\tRethrow,\n\t\t/// <summary>Gets the size of a type in bytes.</summary>\n\t\tSizeOf,\n\t\t/// <summary>Returns the length of an array as 'native unsigned int'.</summary>\n\t\tLdLen,\n\t\t/// <summary>Load address of array element.</summary>\n\t\tLdElema,\n\t\t/// <summary>Load address of inline array element.</summary>\n\t\tLdElemaInlineArray,\n\t\t/// <summary>Retrieves a pinnable reference for the input object.\n\t\t/// The input must be an object reference (O).\n\t\t/// If the input is an array/string, evaluates to a reference to the first element/character, or to a null reference if the array is null or empty.\n\t\t/// Otherwise, uses the GetPinnableReference method to get the reference, or evaluates to a null reference if the input is null.\n\t\t/// </summary>\n\t\tGetPinnableReference,\n\t\t/// <summary>Maps a string value to an integer. This is used in switch(string).</summary>\n\t\tStringToInt,\n\t\t/// <summary>ILAst representation of Expression.Convert.</summary>\n\t\tExpressionTreeCast,\n\t\t/// <summary>Use of user-defined &amp;&amp; or || operator.</summary>\n\t\tUserDefinedLogicOperator,\n\t\t/// <summary>ILAst representation of a short-circuiting binary operator inside a dynamic expression.</summary>\n\t\tDynamicLogicOperatorInstruction,\n\t\t/// <summary>ILAst representation of a binary operator inside a dynamic expression (maps to Binder.BinaryOperation).</summary>\n\t\tDynamicBinaryOperatorInstruction,\n\t\t/// <summary>ILAst representation of a unary operator inside a dynamic expression (maps to Binder.UnaryOperation).</summary>\n\t\tDynamicUnaryOperatorInstruction,\n\t\t/// <summary>ILAst representation of a cast inside a dynamic expression (maps to Binder.Convert).</summary>\n\t\tDynamicConvertInstruction,\n\t\t/// <summary>ILAst representation of a property get method call inside a dynamic expression (maps to Binder.GetMember).</summary>\n\t\tDynamicGetMemberInstruction,\n\t\t/// <summary>ILAst representation of a property set method call inside a dynamic expression (maps to Binder.SetMember).</summary>\n\t\tDynamicSetMemberInstruction,\n\t\t/// <summary>ILAst representation of an indexer get method call inside a dynamic expression (maps to Binder.GetIndex).</summary>\n\t\tDynamicGetIndexInstruction,\n\t\t/// <summary>ILAst representation of an indexer set method call inside a dynamic expression (maps to Binder.SetIndex).</summary>\n\t\tDynamicSetIndexInstruction,\n\t\t/// <summary>ILAst representation of a method call inside a dynamic expression (maps to Binder.InvokeMember).</summary>\n\t\tDynamicInvokeMemberInstruction,\n\t\t/// <summary>ILAst representation of a constuctor invocation inside a dynamic expression (maps to Binder.InvokeConstructor).</summary>\n\t\tDynamicInvokeConstructorInstruction,\n\t\t/// <summary>ILAst representation of a delegate invocation inside a dynamic expression (maps to Binder.Invoke).</summary>\n\t\tDynamicInvokeInstruction,\n\t\t/// <summary>ILAst representation of a call to the Binder.IsEvent method inside a dynamic expression.</summary>\n\t\tDynamicIsEventInstruction,\n\t\t/// <summary>ILAst representation of C# patterns</summary>\n\t\tMatchInstruction,\n\t\t/// <summary>Push a typed reference of type class onto the stack.</summary>\n\t\tMakeRefAny,\n\t\t/// <summary>Push the type token stored in a typed reference.</summary>\n\t\tRefAnyType,\n\t\t/// <summary>Push the address stored in a typed reference.</summary>\n\t\tRefAnyValue,\n\t\t/// <summary>Yield an element from an iterator.</summary>\n\t\tYieldReturn,\n\t\t/// <summary>C# await operator.</summary>\n\t\tAwait,\n\t\t/// <summary>Deconstruction statement</summary>\n\t\tDeconstructInstruction,\n\t\t/// <summary>Represents a deconstructed value</summary>\n\t\tDeconstructResultInstruction,\n\t\t/// <summary>Matches any node</summary>\n\t\tAnyNode,\n\t}\n}\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Instruction without any arguments</summary>\n\tpublic abstract partial class SimpleInstruction : ILInstruction\n\t{\n\t\tprotected SimpleInstruction(OpCode opCode) : base(opCode)\n\t\t{\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 0;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (SimpleInstruction)ShallowClone();\n\t\t\treturn clone;\n\t\t}\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn InstructionFlags.None;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.None;\n\t\t\t}\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Instruction with a single argument</summary>\n\tpublic abstract partial class UnaryInstruction : ILInstruction\n\t{\n\t\tprotected UnaryInstruction(OpCode opCode, ILInstruction argument) : base(opCode)\n\t\t{\n\t\t\tthis.Argument = argument;\n\t\t}\n\t\tpublic static readonly SlotInfo ArgumentSlot = new SlotInfo(\"Argument\", canInlineInto: true);\n\t\tILInstruction argument = null!;\n\t\tpublic ILInstruction Argument {\n\t\t\tget { return this.argument; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.argument, value, 0);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.argument;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Argument = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn ArgumentSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (UnaryInstruction)ShallowClone();\n\t\t\tclone.Argument = this.argument.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn argument.Flags | InstructionFlags.None;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.None;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write('(');\n\t\t\tthis.argument.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Instruction with two arguments: Left and Right</summary>\n\tpublic abstract partial class BinaryInstruction : ILInstruction\n\t{\n\t\tprotected BinaryInstruction(OpCode opCode, ILInstruction left, ILInstruction right) : base(opCode)\n\t\t{\n\t\t\tthis.Left = left;\n\t\t\tthis.Right = right;\n\t\t}\n\t\tpublic static readonly SlotInfo LeftSlot = new SlotInfo(\"Left\", canInlineInto: true);\n\t\tILInstruction left = null!;\n\t\tpublic ILInstruction Left {\n\t\t\tget { return this.left; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.left, value, 0);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo RightSlot = new SlotInfo(\"Right\", canInlineInto: true);\n\t\tILInstruction right = null!;\n\t\tpublic ILInstruction Right {\n\t\t\tget { return this.right; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.right, value, 1);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 2;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.left;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn this.right;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Left = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tthis.Right = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn LeftSlot;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn RightSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (BinaryInstruction)ShallowClone();\n\t\t\tclone.Left = this.left.Clone();\n\t\t\tclone.Right = this.right.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn left.Flags | right.Flags | InstructionFlags.None;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.None;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write('(');\n\t\t\tthis.left.WriteTo(output, options);\n\t\t\toutput.Write(\", \");\n\t\t\tthis.right.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Instruction with a list of arguments.</summary>\n\tpublic abstract partial class CallInstruction : ILInstruction\n\t{\n\t\tpublic static readonly SlotInfo ArgumentsSlot = new SlotInfo(\"Arguments\", canInlineInto: true);\n\t\tpublic InstructionCollection<ILInstruction> Arguments { get; private set; }\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn Arguments.Count;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\treturn this.Arguments[index - 0];\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\tthis.Arguments[index - 0] = (ILInstruction)value;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\treturn ArgumentsSlot;\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (CallInstruction)ShallowClone();\n\t\t\tclone.Arguments = new InstructionCollection<ILInstruction>(clone, 0);\n\t\t\tclone.Arguments.AddRange(this.Arguments.Select(arg => (ILInstruction)arg.Clone()));\n\t\t\treturn clone;\n\t\t}\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn Arguments.Aggregate(InstructionFlags.None, (f, arg) => f | arg.Flags) | InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL.Patterns\n{\n\t/// <summary>Base class for pattern matching in ILAst.</summary>\n\tpublic abstract partial class PatternInstruction : ILInstruction\n\t{\n\t\tprotected PatternInstruction(OpCode opCode) : base(opCode)\n\t\t{\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.Unknown; } }\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Common instruction for compound assignments.</summary>\n\tpublic abstract partial class CompoundAssignmentInstruction : ILInstruction\n\t{\n\t\tpublic static readonly SlotInfo TargetSlot = new SlotInfo(\"Target\", canInlineInto: true);\n\t\tILInstruction target = null!;\n\t\tpublic ILInstruction Target {\n\t\t\tget { return this.target; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.target, value, 0);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo ValueSlot = new SlotInfo(\"Value\", canInlineInto: true);\n\t\tILInstruction value = null!;\n\t\tpublic ILInstruction Value {\n\t\t\tget { return this.value; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.value, value, 1);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 2;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.target;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn this.value;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Target = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tthis.Value = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn TargetSlot;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn ValueSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (CompoundAssignmentInstruction)ShallowClone();\n\t\t\tclone.Target = this.target.Clone();\n\t\t\tclone.Value = this.value.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn target.Flags | value.Flags;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.None;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write('(');\n\t\t\tthis.target.WriteTo(output, options);\n\t\t\toutput.Write(\", \");\n\t\t\tthis.value.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Instruction representing a dynamic call site.</summary>\n\tpublic abstract partial class DynamicInstruction : ILInstruction\n\t{\n\t\tprotected DynamicInstruction(OpCode opCode) : base(opCode)\n\t\t{\n\t\t}\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Represents invalid IL. Semantically, this instruction is considered to throw some kind of exception.</summary>\n\tpublic sealed partial class InvalidBranch : SimpleInstruction\n\t{\n\t\tpublic InvalidBranch() : base(OpCode.InvalidBranch)\n\t\t{\n\t\t}\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn InstructionFlags.MayThrow | InstructionFlags.SideEffect | InstructionFlags.EndPointUnreachable;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayThrow | InstructionFlags.SideEffect | InstructionFlags.EndPointUnreachable;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitInvalidBranch(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitInvalidBranch(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitInvalidBranch(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as InvalidBranch;\n\t\t\treturn o != null;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Represents invalid IL. Semantically, this instruction is considered to produce some kind of value.</summary>\n\tpublic sealed partial class InvalidExpression : SimpleInstruction\n\t{\n\t\tpublic InvalidExpression() : base(OpCode.InvalidExpression)\n\t\t{\n\t\t}\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitInvalidExpression(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitInvalidExpression(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitInvalidExpression(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as InvalidExpression;\n\t\t\treturn o != null;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>No operation. Takes 0 arguments and returns void.</summary>\n\tpublic sealed partial class Nop : SimpleInstruction\n\t{\n\t\tpublic Nop() : base(OpCode.Nop)\n\t\t{\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.Void; } }\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitNop(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitNop(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitNop(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as Nop;\n\t\t\treturn o != null;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>A container of IL blocks.</summary>\n\tpublic sealed partial class ILFunction : ILInstruction\n\t{\n\t\tpublic static readonly SlotInfo BodySlot = new SlotInfo(\"Body\");\n\t\tILInstruction body = null!;\n\t\tpublic ILInstruction Body {\n\t\t\tget { return this.body; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.body, value, 0);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo LocalFunctionsSlot = new SlotInfo(\"LocalFunctions\");\n\t\tpublic InstructionCollection<ILFunction> LocalFunctions { get; private set; }\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1 + LocalFunctions.Count;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.body;\n\t\t\t\tdefault:\n\t\t\t\t\treturn this.LocalFunctions[index - 1];\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Body = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthis.LocalFunctions[index - 1] = (ILFunction)value;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn BodySlot;\n\t\t\t\tdefault:\n\t\t\t\t\treturn LocalFunctionsSlot;\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (ILFunction)ShallowClone();\n\t\t\tclone.Body = this.body.Clone();\n\t\t\tclone.LocalFunctions = new InstructionCollection<ILFunction>(clone, 1);\n\t\t\tclone.LocalFunctions.AddRange(this.LocalFunctions.Select(arg => (ILFunction)arg.Clone()));\n\t\t\tclone.CloneVariables();\n\t\t\treturn clone;\n\t\t}\n\t\tpublic override StackType ResultType { get { return DelegateType?.GetStackType() ?? StackType.O; } }\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitILFunction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitILFunction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitILFunction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as ILFunction;\n\t\t\treturn o != null && this.body.PerformMatch(o.body, ref match) && Patterns.ListMatch.DoMatch(this.LocalFunctions, o.LocalFunctions, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>A container of IL blocks.</summary>\n\tpublic sealed partial class BlockContainer : ILInstruction\n\t{\n\t\tpublic override StackType ResultType { get { return this.ExpectedResultType; } }\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitBlockContainer(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitBlockContainer(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitBlockContainer(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as BlockContainer;\n\t\t\treturn o != null && Patterns.ListMatch.DoMatch(this.Blocks, o.Blocks, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>A block of IL instructions.</summary>\n\tpublic sealed partial class Block : ILInstruction\n\t{\n\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitBlock(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitBlock(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitBlock(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as Block;\n\t\t\treturn o != null && this.Kind == o.Kind && Patterns.ListMatch.DoMatch(this.Instructions, o.Instructions, ref match) && this.FinalInstruction.PerformMatch(o.FinalInstruction, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>A region where a pinned variable is used (initial representation of future fixed statement).</summary>\n\tpublic sealed partial class PinnedRegion : ILInstruction, IStoreInstruction\n\t{\n\t\tpublic PinnedRegion(ILVariable variable, ILInstruction init, ILInstruction body) : base(OpCode.PinnedRegion)\n\t\t{\n\t\t\tthis.variable = variable ?? throw new ArgumentNullException(nameof(variable));\n\t\t\tthis.Init = init;\n\t\t\tthis.Body = body;\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.Void; } }\n\t\tILVariable variable;\n\t\tpublic ILVariable Variable {\n\t\t\tget { return variable; }\n\t\t\tset {\n\t\t\t\tDebugAssert(value != null);\n\t\t\t\tif (IsConnected)\n\t\t\t\t\tvariable.RemoveStoreInstruction(this);\n\t\t\t\tvariable = value;\n\t\t\t\tif (IsConnected)\n\t\t\t\t\tvariable.AddStoreInstruction(this);\n\t\t\t}\n\t\t}\n\n\t\tpublic int IndexInStoreInstructionList { get; set; } = -1;\n\n\t\tint IInstructionWithVariableOperand.IndexInVariableInstructionMapping {\n\t\t\tget { return ((IStoreInstruction)this).IndexInStoreInstructionList; }\n\t\t\tset { ((IStoreInstruction)this).IndexInStoreInstructionList = value; }\n\t\t}\n\n\t\tprotected override void Connected()\n\t\t{\n\t\t\tbase.Connected();\n\t\t\tvariable.AddStoreInstruction(this);\n\t\t}\n\n\t\tprotected override void Disconnected()\n\t\t{\n\t\t\tvariable.RemoveStoreInstruction(this);\n\t\t\tbase.Disconnected();\n\t\t}\n\n\t\tpublic static readonly SlotInfo InitSlot = new SlotInfo(\"Init\", canInlineInto: true);\n\t\tILInstruction init = null!;\n\t\tpublic ILInstruction Init {\n\t\t\tget { return this.init; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.init, value, 0);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo BodySlot = new SlotInfo(\"Body\");\n\t\tILInstruction body = null!;\n\t\tpublic ILInstruction Body {\n\t\t\tget { return this.body; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.body, value, 1);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 2;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.init;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn this.body;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Init = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tthis.Body = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn InitSlot;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn BodySlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (PinnedRegion)ShallowClone();\n\t\t\tclone.Init = this.init.Clone();\n\t\t\tclone.Body = this.body.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn InstructionFlags.MayWriteLocals | init.Flags | body.Flags;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayWriteLocals;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\tvariable.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tthis.init.WriteTo(output, options);\n\t\t\toutput.Write(\", \");\n\t\t\tthis.body.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitPinnedRegion(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitPinnedRegion(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitPinnedRegion(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as PinnedRegion;\n\t\t\treturn o != null && variable == o.variable && this.init.PerformMatch(o.init, ref match) && this.body.PerformMatch(o.body, ref match);\n\t\t}\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebugAssert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function!));\n\t\t\tDebugAssert(phase <= ILPhase.InILReader || variable.Function!.Variables[variable.IndexInFunction] == variable);\n\t\t\tDebugAssert(Variable.Kind == VariableKind.PinnedRegionLocal);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Common instruction for add, sub, mul, div, rem, bit.and, bit.or, bit.xor, shl and shr.</summary>\n\tpublic sealed partial class BinaryNumericInstruction : BinaryInstruction\n\t{\n\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitBinaryNumericInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitBinaryNumericInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitBinaryNumericInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as BinaryNumericInstruction;\n\t\t\treturn o != null && this.Left.PerformMatch(o.Left, ref match) && this.Right.PerformMatch(o.Right, ref match) && CheckForOverflow == o.CheckForOverflow && Sign == o.Sign && Operator == o.Operator && IsLifted == o.IsLifted;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Common instruction for numeric compound assignments.</summary>\n\tpublic sealed partial class NumericCompoundAssign : CompoundAssignmentInstruction\n\t{\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\tpublic override StackType ResultType { get { return type.GetStackType(); } }\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitNumericCompoundAssign(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitNumericCompoundAssign(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitNumericCompoundAssign(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as NumericCompoundAssign;\n\t\t\treturn o != null && type.Equals(o.type) && CheckForOverflow == o.CheckForOverflow && Sign == o.Sign && Operator == o.Operator && this.EvalMode == o.EvalMode && this.TargetKind == o.TargetKind && Target.PerformMatch(o.Target, ref match) && Value.PerformMatch(o.Value, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Common instruction for user-defined compound assignments.</summary>\n\tpublic sealed partial class UserDefinedCompoundAssign : CompoundAssignmentInstruction\n\t{\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitUserDefinedCompoundAssign(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitUserDefinedCompoundAssign(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitUserDefinedCompoundAssign(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as UserDefinedCompoundAssign;\n\t\t\treturn o != null && this.Method.Equals(o.Method) && this.EvalMode == o.EvalMode && this.TargetKind == o.TargetKind && Target.PerformMatch(o.Target, ref match) && Value.PerformMatch(o.Value, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Common instruction for dynamic compound assignments.</summary>\n\tpublic sealed partial class DynamicCompoundAssign : CompoundAssignmentInstruction\n\t{\n\t\tpublic override StackType ResultType { get { return StackType.O; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDynamicCompoundAssign(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDynamicCompoundAssign(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitDynamicCompoundAssign(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as DynamicCompoundAssign;\n\t\t\treturn o != null && this.EvalMode == o.EvalMode && this.TargetKind == o.TargetKind && Target.PerformMatch(o.Target, ref match) && Value.PerformMatch(o.Value, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Bitwise NOT</summary>\n\tpublic sealed partial class BitNot : UnaryInstruction\n\t{\n\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitBitNot(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitBitNot(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitBitNot(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as BitNot;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match) && IsLifted == o.IsLifted && UnderlyingResultType == o.UnderlyingResultType;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Retrieves the RuntimeArgumentHandle.</summary>\n\tpublic sealed partial class Arglist : SimpleInstruction\n\t{\n\t\tpublic Arglist() : base(OpCode.Arglist)\n\t\t{\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.O; } }\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitArglist(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitArglist(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitArglist(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as Arglist;\n\t\t\treturn o != null;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Unconditional branch. <c>goto target;</c></summary>\n\tpublic sealed partial class Branch : SimpleInstruction\n\t{\n\t\tpublic override StackType ResultType { get { return StackType.Void; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn InstructionFlags.EndPointUnreachable | InstructionFlags.MayBranch;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.EndPointUnreachable | InstructionFlags.MayBranch;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitBranch(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitBranch(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitBranch(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as Branch;\n\t\t\treturn o != null && this.TargetBlock == o.TargetBlock;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Unconditional branch to end of block container. Return is represented using IsLeavingFunction and an (optional) return value. The block container evaluates to the value produced by the argument of the leave instruction.</summary>\n\tpublic sealed partial class Leave : ILInstruction\n\t{\n\t\tpublic static readonly SlotInfo ValueSlot = new SlotInfo(\"Value\", canInlineInto: true);\n\t\tILInstruction value = null!;\n\t\tpublic ILInstruction Value {\n\t\t\tget { return this.value; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.value, value, 0);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.value;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Value = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn ValueSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (Leave)ShallowClone();\n\t\t\tclone.Value = this.value.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.Void; } }\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLeave(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLeave(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLeave(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as Leave;\n\t\t\treturn o != null && this.value.PerformMatch(o.value, ref match) && this.TargetContainer == o.TargetContainer;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>If statement / conditional expression. <c>if (condition) trueExpr else falseExpr</c></summary>\n\tpublic sealed partial class IfInstruction : ILInstruction\n\t{\n\t\tpublic static readonly SlotInfo ConditionSlot = new SlotInfo(\"Condition\", canInlineInto: true);\n\t\tILInstruction condition = null!;\n\t\tpublic ILInstruction Condition {\n\t\t\tget { return this.condition; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.condition, value, 0);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo TrueInstSlot = new SlotInfo(\"TrueInst\");\n\t\tILInstruction trueInst = null!;\n\t\tpublic ILInstruction TrueInst {\n\t\t\tget { return this.trueInst; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.trueInst, value, 1);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo FalseInstSlot = new SlotInfo(\"FalseInst\");\n\t\tILInstruction falseInst = null!;\n\t\tpublic ILInstruction FalseInst {\n\t\t\tget { return this.falseInst; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.falseInst, value, 2);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 3;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.condition;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn this.trueInst;\n\t\t\t\tcase 2:\n\t\t\t\t\treturn this.falseInst;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Condition = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tthis.TrueInst = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tthis.FalseInst = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn ConditionSlot;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn TrueInstSlot;\n\t\t\t\tcase 2:\n\t\t\t\t\treturn FalseInstSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (IfInstruction)ShallowClone();\n\t\t\tclone.Condition = this.condition.Clone();\n\t\t\tclone.TrueInst = this.trueInst.Clone();\n\t\t\tclone.FalseInst = this.falseInst.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitIfInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitIfInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitIfInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as IfInstruction;\n\t\t\treturn o != null && this.condition.PerformMatch(o.condition, ref match) && this.trueInst.PerformMatch(o.trueInst, ref match) && this.falseInst.PerformMatch(o.falseInst, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Null coalescing operator expression. <c>if.notnull(valueInst, fallbackInst)</c></summary>\n\tpublic sealed partial class NullCoalescingInstruction : ILInstruction\n\t{\n\t\tpublic static readonly SlotInfo ValueInstSlot = new SlotInfo(\"ValueInst\", canInlineInto: true);\n\t\tILInstruction valueInst = null!;\n\t\tpublic ILInstruction ValueInst {\n\t\t\tget { return this.valueInst; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.valueInst, value, 0);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo FallbackInstSlot = new SlotInfo(\"FallbackInst\");\n\t\tILInstruction fallbackInst = null!;\n\t\tpublic ILInstruction FallbackInst {\n\t\t\tget { return this.fallbackInst; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.fallbackInst, value, 1);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 2;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.valueInst;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn this.fallbackInst;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.ValueInst = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tthis.FallbackInst = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn ValueInstSlot;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn FallbackInstSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (NullCoalescingInstruction)ShallowClone();\n\t\t\tclone.ValueInst = this.valueInst.Clone();\n\t\t\tclone.FallbackInst = this.fallbackInst.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitNullCoalescingInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitNullCoalescingInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitNullCoalescingInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as NullCoalescingInstruction;\n\t\t\treturn o != null && this.valueInst.PerformMatch(o.valueInst, ref match) && this.fallbackInst.PerformMatch(o.fallbackInst, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Switch statement</summary>\n\tpublic sealed partial class SwitchInstruction : ILInstruction\n\t{\n\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitSwitchInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitSwitchInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitSwitchInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as SwitchInstruction;\n\t\t\treturn o != null && IsLifted == o.IsLifted && Value.PerformMatch(o.Value, ref match) && Patterns.ListMatch.DoMatch(this.Sections, o.Sections, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Switch section within a switch statement</summary>\n\tpublic sealed partial class SwitchSection : ILInstruction\n\t{\n\t\tpublic static readonly SlotInfo BodySlot = new SlotInfo(\"Body\");\n\t\tILInstruction body = null!;\n\t\tpublic ILInstruction Body {\n\t\t\tget { return this.body; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.body, value, 0);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.body;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Body = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn BodySlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (SwitchSection)ShallowClone();\n\t\t\tclone.Body = this.body.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.Void; } }\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitSwitchSection(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitSwitchSection(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitSwitchSection(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as SwitchSection;\n\t\t\treturn o != null && this.body.PerformMatch(o.body, ref match) && this.Labels.SetEquals(o.Labels) && this.HasNullLabel == o.HasNullLabel;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Try-catch statement.</summary>\n\tpublic sealed partial class TryCatch : TryInstruction\n\t{\n\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitTryCatch(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitTryCatch(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitTryCatch(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as TryCatch;\n\t\t\treturn o != null && TryBlock.PerformMatch(o.TryBlock, ref match) && Patterns.ListMatch.DoMatch(Handlers, o.Handlers, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Catch handler within a try-catch statement.</summary>\n\tpublic sealed partial class TryCatchHandler : ILInstruction, IStoreInstruction\n\t{\n\t\tpublic TryCatchHandler(ILInstruction filter, ILInstruction body, ILVariable variable) : base(OpCode.TryCatchHandler)\n\t\t{\n\t\t\tthis.Filter = filter;\n\t\t\tthis.Body = body;\n\t\t\tthis.variable = variable ?? throw new ArgumentNullException(nameof(variable));\n\t\t}\n\t\tpublic static readonly SlotInfo FilterSlot = new SlotInfo(\"Filter\");\n\t\tILInstruction filter = null!;\n\t\tpublic ILInstruction Filter {\n\t\t\tget { return this.filter; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.filter, value, 0);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo BodySlot = new SlotInfo(\"Body\");\n\t\tILInstruction body = null!;\n\t\tpublic ILInstruction Body {\n\t\t\tget { return this.body; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.body, value, 1);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 2;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.filter;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn this.body;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Filter = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tthis.Body = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn FilterSlot;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn BodySlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (TryCatchHandler)ShallowClone();\n\t\t\tclone.Filter = this.filter.Clone();\n\t\t\tclone.Body = this.body.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tILVariable variable;\n\t\tpublic ILVariable Variable {\n\t\t\tget { return variable; }\n\t\t\tset {\n\t\t\t\tDebugAssert(value != null);\n\t\t\t\tif (IsConnected)\n\t\t\t\t\tvariable.RemoveStoreInstruction(this);\n\t\t\t\tvariable = value;\n\t\t\t\tif (IsConnected)\n\t\t\t\t\tvariable.AddStoreInstruction(this);\n\t\t\t}\n\t\t}\n\n\t\tpublic int IndexInStoreInstructionList { get; set; } = -1;\n\n\t\tint IInstructionWithVariableOperand.IndexInVariableInstructionMapping {\n\t\t\tget { return ((IStoreInstruction)this).IndexInStoreInstructionList; }\n\t\t\tset { ((IStoreInstruction)this).IndexInStoreInstructionList = value; }\n\t\t}\n\n\t\tprotected override void Connected()\n\t\t{\n\t\t\tbase.Connected();\n\t\t\tvariable.AddStoreInstruction(this);\n\t\t}\n\n\t\tprotected override void Disconnected()\n\t\t{\n\t\t\tvariable.RemoveStoreInstruction(this);\n\t\t\tbase.Disconnected();\n\t\t}\n\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitTryCatchHandler(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitTryCatchHandler(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitTryCatchHandler(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as TryCatchHandler;\n\t\t\treturn o != null && this.filter.PerformMatch(o.filter, ref match) && this.body.PerformMatch(o.body, ref match) && variable == o.variable;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Try-finally statement</summary>\n\tpublic sealed partial class TryFinally : TryInstruction\n\t{\n\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitTryFinally(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitTryFinally(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitTryFinally(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as TryFinally;\n\t\t\treturn o != null && TryBlock.PerformMatch(o.TryBlock, ref match) && finallyBlock.PerformMatch(o.finallyBlock, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Try-fault statement</summary>\n\tpublic sealed partial class TryFault : TryInstruction\n\t{\n\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitTryFault(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitTryFault(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitTryFault(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as TryFault;\n\t\t\treturn o != null && TryBlock.PerformMatch(o.TryBlock, ref match) && faultBlock.PerformMatch(o.faultBlock, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Lock statement</summary>\n\tpublic sealed partial class LockInstruction : ILInstruction\n\t{\n\t\tpublic LockInstruction(ILInstruction onExpression, ILInstruction body) : base(OpCode.LockInstruction)\n\t\t{\n\t\t\tthis.OnExpression = onExpression;\n\t\t\tthis.Body = body;\n\t\t}\n\t\tpublic static readonly SlotInfo OnExpressionSlot = new SlotInfo(\"OnExpression\", canInlineInto: true);\n\t\tILInstruction onExpression = null!;\n\t\tpublic ILInstruction OnExpression {\n\t\t\tget { return this.onExpression; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.onExpression, value, 0);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo BodySlot = new SlotInfo(\"Body\");\n\t\tILInstruction body = null!;\n\t\tpublic ILInstruction Body {\n\t\t\tget { return this.body; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.body, value, 1);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 2;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.onExpression;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn this.body;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.OnExpression = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tthis.Body = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn OnExpressionSlot;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn BodySlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (LockInstruction)ShallowClone();\n\t\t\tclone.OnExpression = this.onExpression.Clone();\n\t\t\tclone.Body = this.body.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.Void; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn onExpression.Flags | body.Flags | InstructionFlags.ControlFlow | InstructionFlags.SideEffect;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.ControlFlow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLockInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLockInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLockInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LockInstruction;\n\t\t\treturn o != null && this.onExpression.PerformMatch(o.onExpression, ref match) && this.body.PerformMatch(o.body, ref match);\n\t\t}\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebugAssert(onExpression.ResultType == StackType.O);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Using statement</summary>\n\tpublic sealed partial class UsingInstruction : ILInstruction, IStoreInstruction\n\t{\n\t\tpublic UsingInstruction(ILVariable variable, ILInstruction resourceExpression, ILInstruction body) : base(OpCode.UsingInstruction)\n\t\t{\n\t\t\tthis.variable = variable ?? throw new ArgumentNullException(nameof(variable));\n\t\t\tthis.ResourceExpression = resourceExpression;\n\t\t\tthis.Body = body;\n\t\t}\n\t\tILVariable variable;\n\t\tpublic ILVariable Variable {\n\t\t\tget { return variable; }\n\t\t\tset {\n\t\t\t\tDebugAssert(value != null);\n\t\t\t\tif (IsConnected)\n\t\t\t\t\tvariable.RemoveStoreInstruction(this);\n\t\t\t\tvariable = value;\n\t\t\t\tif (IsConnected)\n\t\t\t\t\tvariable.AddStoreInstruction(this);\n\t\t\t}\n\t\t}\n\n\t\tpublic int IndexInStoreInstructionList { get; set; } = -1;\n\n\t\tint IInstructionWithVariableOperand.IndexInVariableInstructionMapping {\n\t\t\tget { return ((IStoreInstruction)this).IndexInStoreInstructionList; }\n\t\t\tset { ((IStoreInstruction)this).IndexInStoreInstructionList = value; }\n\t\t}\n\n\t\tprotected override void Connected()\n\t\t{\n\t\t\tbase.Connected();\n\t\t\tvariable.AddStoreInstruction(this);\n\t\t}\n\n\t\tprotected override void Disconnected()\n\t\t{\n\t\t\tvariable.RemoveStoreInstruction(this);\n\t\t\tbase.Disconnected();\n\t\t}\n\n\t\tpublic static readonly SlotInfo ResourceExpressionSlot = new SlotInfo(\"ResourceExpression\", canInlineInto: true);\n\t\tILInstruction resourceExpression = null!;\n\t\tpublic ILInstruction ResourceExpression {\n\t\t\tget { return this.resourceExpression; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.resourceExpression, value, 0);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo BodySlot = new SlotInfo(\"Body\");\n\t\tILInstruction body = null!;\n\t\tpublic ILInstruction Body {\n\t\t\tget { return this.body; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.body, value, 1);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 2;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.resourceExpression;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn this.body;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.ResourceExpression = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tthis.Body = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn ResourceExpressionSlot;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn BodySlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (UsingInstruction)ShallowClone();\n\t\t\tclone.ResourceExpression = this.resourceExpression.Clone();\n\t\t\tclone.Body = this.body.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.Void; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn InstructionFlags.MayWriteLocals | resourceExpression.Flags | body.Flags | InstructionFlags.ControlFlow | InstructionFlags.SideEffect;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayWriteLocals | InstructionFlags.ControlFlow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitUsingInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitUsingInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitUsingInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as UsingInstruction;\n\t\t\treturn o != null && variable == o.variable && this.resourceExpression.PerformMatch(o.resourceExpression, ref match) && this.body.PerformMatch(o.body, ref match);\n\t\t}\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebugAssert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function!));\n\t\t\tDebugAssert(phase <= ILPhase.InILReader || variable.Function!.Variables[variable.IndexInFunction] == variable);\n\t\t\tDebugAssert(resourceExpression.ResultType == StackType.O);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Breakpoint instruction</summary>\n\tpublic sealed partial class DebugBreak : SimpleInstruction\n\t{\n\t\tpublic DebugBreak() : base(OpCode.DebugBreak)\n\t\t{\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.Void; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn InstructionFlags.SideEffect;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDebugBreak(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDebugBreak(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitDebugBreak(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as DebugBreak;\n\t\t\treturn o != null;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Comparison. The inputs must be both integers; or both floats; or both object references. Object references can only be compared for equality or inequality. Floating-point comparisons evaluate to 0 (false) when an input is NaN, except for 'NaN != NaN' which evaluates to 1 (true).</summary>\n\tpublic sealed partial class Comp : BinaryInstruction\n\t{\n\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitComp(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitComp(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitComp(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as Comp;\n\t\t\treturn o != null && this.Left.PerformMatch(o.Left, ref match) && this.Right.PerformMatch(o.Right, ref match) && this.Kind == o.Kind && this.Sign == o.Sign && this.LiftingKind == o.LiftingKind;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Non-virtual method call.</summary>\n\tpublic sealed partial class Call : CallInstruction\n\t{\n\t\tpublic Call(IMethod method) : base(OpCode.Call, method)\n\t\t{\n\t\t}\n\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitCall(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitCall(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitCall(this, context);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Virtual method call.</summary>\n\tpublic sealed partial class CallVirt : CallInstruction\n\t{\n\t\tpublic CallVirt(IMethod method) : base(OpCode.CallVirt, method)\n\t\t{\n\t\t}\n\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitCallVirt(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitCallVirt(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitCallVirt(this, context);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Unsafe function pointer call.</summary>\n\tpublic sealed partial class CallIndirect : ILInstruction\n\t{\n\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitCallIndirect(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitCallIndirect(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitCallIndirect(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as CallIndirect;\n\t\t\treturn o != null && EqualSignature(o) && Patterns.ListMatch.DoMatch(this.Arguments, o.Arguments, ref match) && this.FunctionPointer.PerformMatch(o.FunctionPointer, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Checks that the input float is not NaN or infinite.</summary>\n\tpublic sealed partial class Ckfinite : UnaryInstruction\n\t{\n\t\tpublic Ckfinite(ILInstruction argument) : base(OpCode.Ckfinite, argument)\n\t\t{\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.Void; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitCkfinite(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitCkfinite(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitCkfinite(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as Ckfinite;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Numeric cast.</summary>\n\tpublic sealed partial class Conv : UnaryInstruction\n\t{\n\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitConv(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitConv(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitConv(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as Conv;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match) && CheckForOverflow == o.CheckForOverflow && Kind == o.Kind && InputSign == o.InputSign && TargetType == o.TargetType && IsLifted == o.IsLifted;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Loads the value of a local variable. (ldarg/ldloc)</summary>\n\tpublic sealed partial class LdLoc : SimpleInstruction, ILoadInstruction\n\t{\n\t\tpublic LdLoc(ILVariable variable) : base(OpCode.LdLoc)\n\t\t{\n\t\t\tthis.variable = variable ?? throw new ArgumentNullException(nameof(variable));\n\t\t}\n\t\tILVariable variable;\n\t\tpublic ILVariable Variable {\n\t\t\tget { return variable; }\n\t\t\tset {\n\t\t\t\tDebugAssert(value != null);\n\t\t\t\tif (IsConnected)\n\t\t\t\t\tvariable.RemoveLoadInstruction(this);\n\t\t\t\tvariable = value;\n\t\t\t\tif (IsConnected)\n\t\t\t\t\tvariable.AddLoadInstruction(this);\n\t\t\t}\n\t\t}\n\n\t\tpublic int IndexInLoadInstructionList { get; set; } = -1;\n\n\t\tint IInstructionWithVariableOperand.IndexInVariableInstructionMapping {\n\t\t\tget { return ((ILoadInstruction)this).IndexInLoadInstructionList; }\n\t\t\tset { ((ILoadInstruction)this).IndexInLoadInstructionList = value; }\n\t\t}\n\n\t\tprotected override void Connected()\n\t\t{\n\t\t\tbase.Connected();\n\t\t\tvariable.AddLoadInstruction(this);\n\t\t}\n\n\t\tprotected override void Disconnected()\n\t\t{\n\t\t\tvariable.RemoveLoadInstruction(this);\n\t\t\tbase.Disconnected();\n\t\t}\n\n\t\tpublic override StackType ResultType { get { return variable.StackType; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn InstructionFlags.MayReadLocals;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayReadLocals;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\tvariable.WriteTo(output);\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdLoc(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdLoc(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdLoc(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdLoc;\n\t\t\treturn o != null && variable == o.variable;\n\t\t}\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebugAssert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function!));\n\t\t\tDebugAssert(phase <= ILPhase.InILReader || variable.Function!.Variables[variable.IndexInFunction] == variable);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Loads the address of a local variable. (ldarga/ldloca)</summary>\n\tpublic sealed partial class LdLoca : SimpleInstruction, IAddressInstruction\n\t{\n\t\tpublic LdLoca(ILVariable variable) : base(OpCode.LdLoca)\n\t\t{\n\t\t\tthis.variable = variable ?? throw new ArgumentNullException(nameof(variable));\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.Ref; } }\n\t\tILVariable variable;\n\t\tpublic ILVariable Variable {\n\t\t\tget { return variable; }\n\t\t\tset {\n\t\t\t\tDebugAssert(value != null);\n\t\t\t\tif (IsConnected)\n\t\t\t\t\tvariable.RemoveAddressInstruction(this);\n\t\t\t\tvariable = value;\n\t\t\t\tif (IsConnected)\n\t\t\t\t\tvariable.AddAddressInstruction(this);\n\t\t\t}\n\t\t}\n\n\t\tpublic int IndexInAddressInstructionList { get; set; } = -1;\n\n\t\tint IInstructionWithVariableOperand.IndexInVariableInstructionMapping {\n\t\t\tget { return ((IAddressInstruction)this).IndexInAddressInstructionList; }\n\t\t\tset { ((IAddressInstruction)this).IndexInAddressInstructionList = value; }\n\t\t}\n\n\t\tprotected override void Connected()\n\t\t{\n\t\t\tbase.Connected();\n\t\t\tvariable.AddAddressInstruction(this);\n\t\t}\n\n\t\tprotected override void Disconnected()\n\t\t{\n\t\t\tvariable.RemoveAddressInstruction(this);\n\t\t\tbase.Disconnected();\n\t\t}\n\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\tvariable.WriteTo(output);\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdLoca(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdLoca(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdLoca(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdLoca;\n\t\t\treturn o != null && variable == o.variable;\n\t\t}\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebugAssert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function!));\n\t\t\tDebugAssert(phase <= ILPhase.InILReader || variable.Function!.Variables[variable.IndexInFunction] == variable);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Stores a value into a local variable. (IL: starg/stloc)\n\t/// Evaluates to the value that was stored (for byte/short variables: evaluates to the truncated value, sign/zero extended back to I4 based on variable.Type.GetSign())</summary>\n\tpublic sealed partial class StLoc : ILInstruction, IStoreInstruction\n\t{\n\t\tpublic StLoc(ILVariable variable, ILInstruction value) : base(OpCode.StLoc)\n\t\t{\n\t\t\tthis.variable = variable ?? throw new ArgumentNullException(nameof(variable));\n\t\t\tthis.Value = value;\n\t\t}\n\t\tILVariable variable;\n\t\tpublic ILVariable Variable {\n\t\t\tget { return variable; }\n\t\t\tset {\n\t\t\t\tDebugAssert(value != null);\n\t\t\t\tif (IsConnected)\n\t\t\t\t\tvariable.RemoveStoreInstruction(this);\n\t\t\t\tvariable = value;\n\t\t\t\tif (IsConnected)\n\t\t\t\t\tvariable.AddStoreInstruction(this);\n\t\t\t}\n\t\t}\n\n\t\tpublic int IndexInStoreInstructionList { get; set; } = -1;\n\n\t\tint IInstructionWithVariableOperand.IndexInVariableInstructionMapping {\n\t\t\tget { return ((IStoreInstruction)this).IndexInStoreInstructionList; }\n\t\t\tset { ((IStoreInstruction)this).IndexInStoreInstructionList = value; }\n\t\t}\n\n\t\tprotected override void Connected()\n\t\t{\n\t\t\tbase.Connected();\n\t\t\tvariable.AddStoreInstruction(this);\n\t\t}\n\n\t\tprotected override void Disconnected()\n\t\t{\n\t\t\tvariable.RemoveStoreInstruction(this);\n\t\t\tbase.Disconnected();\n\t\t}\n\n\t\tpublic static readonly SlotInfo ValueSlot = new SlotInfo(\"Value\", canInlineInto: true);\n\t\tILInstruction value = null!;\n\t\tpublic ILInstruction Value {\n\t\t\tget { return this.value; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.value, value, 0);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.value;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Value = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn ValueSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (StLoc)ShallowClone();\n\t\t\tclone.Value = this.value.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tpublic override StackType ResultType { get { return variable.StackType; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn InstructionFlags.MayWriteLocals | value.Flags;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayWriteLocals;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\tvariable.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tthis.value.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitStLoc(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitStLoc(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitStLoc(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as StLoc;\n\t\t\treturn o != null && variable == o.variable && this.value.PerformMatch(o.value, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Stores the value into an anonymous temporary variable, and returns the address of that variable.</summary>\n\tpublic sealed partial class AddressOf : ILInstruction\n\t{\n\t\tpublic AddressOf(ILInstruction value, IType type) : base(OpCode.AddressOf)\n\t\t{\n\t\t\tthis.Value = value;\n\t\t\tthis.type = type;\n\t\t}\n\t\tpublic static readonly SlotInfo ValueSlot = new SlotInfo(\"Value\", canInlineInto: true);\n\t\tILInstruction value = null!;\n\t\tpublic ILInstruction Value {\n\t\t\tget { return this.value; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.value, value, 0);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.value;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Value = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn ValueSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (AddressOf)ShallowClone();\n\t\t\tclone.Value = this.value.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.Ref; } }\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn value.Flags;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.None;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tthis.value.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitAddressOf(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitAddressOf(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitAddressOf(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as AddressOf;\n\t\t\treturn o != null && this.value.PerformMatch(o.value, ref match) && type.Equals(o.type);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Three valued logic and. Inputs are of type bool? or I4, output is of type bool?. Unlike logic.and(), does not have short-circuiting behavior.</summary>\n\tpublic sealed partial class ThreeValuedBoolAnd : BinaryInstruction\n\t{\n\t\tpublic ThreeValuedBoolAnd(ILInstruction left, ILInstruction right) : base(OpCode.ThreeValuedBoolAnd, left, right)\n\t\t{\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.O; } }\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitThreeValuedBoolAnd(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitThreeValuedBoolAnd(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitThreeValuedBoolAnd(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as ThreeValuedBoolAnd;\n\t\t\treturn o != null && this.Left.PerformMatch(o.Left, ref match) && this.Right.PerformMatch(o.Right, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Three valued logic or. Inputs are of type bool? or I4, output is of type bool?. Unlike logic.or(), does not have short-circuiting behavior.</summary>\n\tpublic sealed partial class ThreeValuedBoolOr : BinaryInstruction\n\t{\n\t\tpublic ThreeValuedBoolOr(ILInstruction left, ILInstruction right) : base(OpCode.ThreeValuedBoolOr, left, right)\n\t\t{\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.O; } }\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitThreeValuedBoolOr(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitThreeValuedBoolOr(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitThreeValuedBoolOr(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as ThreeValuedBoolOr;\n\t\t\treturn o != null && this.Left.PerformMatch(o.Left, ref match) && this.Right.PerformMatch(o.Right, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>The input operand must be one of:\n\t///   1. a nullable value type\n\t///   2. a reference type\n\t///   3. a managed reference to a type parameter.\n\t/// If the input is non-null, evaluates to the (unwrapped) input.\n\t/// If the input is null, jumps to the innermost nullable.rewrap instruction that contains this instruction.\n\t/// In case 3 (managed reference), the dereferenced value is the input being tested, and the nullable.unwrap instruction returns the managed reference unmodified (if the value is non-null).</summary>\n\tpublic sealed partial class NullableUnwrap : UnaryInstruction\n\t{\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayUnwrapNull;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayUnwrapNull;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitNullableUnwrap(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitNullableUnwrap(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitNullableUnwrap(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as NullableUnwrap;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Serves as jump target for the nullable.unwrap instruction.\n\t/// If the input evaluates normally, evaluates to the input value (wrapped in Nullable&lt;T&gt; if the input is a non-nullable value type).If a nullable.unwrap instruction encounters a null input and jumps to the (endpoint of the) nullable.rewrap instruction,the nullable.rewrap instruction evaluates to null.</summary>\n\tpublic sealed partial class NullableRewrap : UnaryInstruction\n\t{\n\t\tpublic NullableRewrap(ILInstruction argument) : base(OpCode.NullableRewrap, argument)\n\t\t{\n\t\t}\n\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitNullableRewrap(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitNullableRewrap(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitNullableRewrap(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as NullableRewrap;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Loads a constant string.</summary>\n\tpublic sealed partial class LdStr : SimpleInstruction\n\t{\n\t\tpublic LdStr(string value) : base(OpCode.LdStr)\n\t\t{\n\t\t\tthis.Value = value;\n\t\t}\n\t\tpublic readonly string Value;\n\t\tpublic override StackType ResultType { get { return StackType.O; } }\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\tDisassembler.DisassemblerHelpers.WriteOperand(output, Value);\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdStr(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdStr(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdStr(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdStr;\n\t\t\treturn o != null && this.Value == o.Value;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Loads a constant byte string (as ReadOnlySpan&lt;byte&gt;).</summary>\n\tpublic sealed partial class LdStrUtf8 : SimpleInstruction\n\t{\n\t\tpublic LdStrUtf8(string value) : base(OpCode.LdStrUtf8)\n\t\t{\n\t\t\tthis.Value = value;\n\t\t}\n\t\tpublic readonly string Value;\n\t\tpublic override StackType ResultType { get { return StackType.O; } }\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\tDisassembler.DisassemblerHelpers.WriteOperand(output, Value);\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdStrUtf8(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdStrUtf8(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdStrUtf8(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdStrUtf8;\n\t\t\treturn o != null && this.Value == o.Value;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Loads a constant 32-bit integer.</summary>\n\tpublic sealed partial class LdcI4 : SimpleInstruction\n\t{\n\t\tpublic LdcI4(int value) : base(OpCode.LdcI4)\n\t\t{\n\t\t\tthis.Value = value;\n\t\t}\n\t\tpublic readonly int Value;\n\t\tpublic override StackType ResultType { get { return StackType.I4; } }\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\tDisassembler.DisassemblerHelpers.WriteOperand(output, Value);\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdcI4(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdcI4(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdcI4(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdcI4;\n\t\t\treturn o != null && this.Value == o.Value;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Loads a constant 64-bit integer.</summary>\n\tpublic sealed partial class LdcI8 : SimpleInstruction\n\t{\n\t\tpublic LdcI8(long value) : base(OpCode.LdcI8)\n\t\t{\n\t\t\tthis.Value = value;\n\t\t}\n\t\tpublic readonly long Value;\n\t\tpublic override StackType ResultType { get { return StackType.I8; } }\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\tDisassembler.DisassemblerHelpers.WriteOperand(output, Value);\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdcI8(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdcI8(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdcI8(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdcI8;\n\t\t\treturn o != null && this.Value == o.Value;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Loads a constant 32-bit floating-point number.</summary>\n\tpublic sealed partial class LdcF4 : SimpleInstruction\n\t{\n\t\tpublic LdcF4(float value) : base(OpCode.LdcF4)\n\t\t{\n\t\t\tthis.Value = value;\n\t\t}\n\t\tpublic readonly float Value;\n\t\tpublic override StackType ResultType { get { return StackType.F4; } }\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\tDisassembler.DisassemblerHelpers.WriteOperand(output, Value);\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdcF4(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdcF4(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdcF4(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdcF4;\n\t\t\treturn o != null && this.Value == o.Value;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Loads a constant 64-bit floating-point number.</summary>\n\tpublic sealed partial class LdcF8 : SimpleInstruction\n\t{\n\t\tpublic LdcF8(double value) : base(OpCode.LdcF8)\n\t\t{\n\t\t\tthis.Value = value;\n\t\t}\n\t\tpublic readonly double Value;\n\t\tpublic override StackType ResultType { get { return StackType.F8; } }\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\tDisassembler.DisassemblerHelpers.WriteOperand(output, Value);\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdcF8(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdcF8(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdcF8(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdcF8;\n\t\t\treturn o != null && this.Value == o.Value;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Loads a constant decimal.</summary>\n\tpublic sealed partial class LdcDecimal : SimpleInstruction\n\t{\n\t\tpublic LdcDecimal(decimal value) : base(OpCode.LdcDecimal)\n\t\t{\n\t\t\tthis.Value = value;\n\t\t}\n\t\tpublic readonly decimal Value;\n\t\tpublic override StackType ResultType { get { return StackType.O; } }\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\tDisassembler.DisassemblerHelpers.WriteOperand(output, Value);\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdcDecimal(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdcDecimal(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdcDecimal(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdcDecimal;\n\t\t\treturn o != null && this.Value == o.Value;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Loads the null reference.</summary>\n\tpublic sealed partial class LdNull : SimpleInstruction\n\t{\n\t\tpublic LdNull() : base(OpCode.LdNull)\n\t\t{\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.O; } }\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdNull(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdNull(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdNull(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdNull;\n\t\t\treturn o != null;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Load method pointer</summary>\n\tpublic sealed partial class LdFtn : SimpleInstruction, IInstructionWithMethodOperand\n\t{\n\t\tpublic LdFtn(IMethod method) : base(OpCode.LdFtn)\n\t\t{\n\t\t\tthis.method = method;\n\t\t}\n\t\treadonly IMethod method;\n\t\t/// <summary>Returns the method operand.</summary>\n\t\tpublic IMethod Method => method;\n\t\tpublic override StackType ResultType { get { return StackType.I; } }\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tif (method != null)\n\t\t\t{\n\t\t\t\toutput.Write(' ');\n\t\t\t\tmethod.WriteTo(output);\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdFtn(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdFtn(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdFtn(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdFtn;\n\t\t\treturn o != null && object.Equals(method, o.method);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Load method pointer</summary>\n\tpublic sealed partial class LdVirtFtn : UnaryInstruction, IInstructionWithMethodOperand\n\t{\n\t\tpublic LdVirtFtn(ILInstruction argument, IMethod method) : base(OpCode.LdVirtFtn, argument)\n\t\t{\n\t\t\tthis.method = method;\n\t\t}\n\t\treadonly IMethod method;\n\t\t/// <summary>Returns the method operand.</summary>\n\t\tpublic IMethod Method => method;\n\t\tpublic override StackType ResultType { get { return StackType.I; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tif (method != null)\n\t\t\t{\n\t\t\t\toutput.Write(' ');\n\t\t\t\tmethod.WriteTo(output);\n\t\t\t}\n\t\t\toutput.Write('(');\n\t\t\tArgument.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdVirtFtn(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdVirtFtn(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdVirtFtn(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdVirtFtn;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match) && object.Equals(method, o.method);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Virtual delegate construction</summary>\n\tpublic sealed partial class LdVirtDelegate : UnaryInstruction, IInstructionWithMethodOperand\n\t{\n\t\tpublic LdVirtDelegate(ILInstruction argument, IType type, IMethod method) : base(OpCode.LdVirtDelegate, argument)\n\t\t{\n\t\t\tthis.type = type;\n\t\t\tthis.method = method;\n\t\t}\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\treadonly IMethod method;\n\t\t/// <summary>Returns the method operand.</summary>\n\t\tpublic IMethod Method => method;\n\t\tpublic override StackType ResultType { get { return StackType.O; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t\tif (method != null)\n\t\t\t{\n\t\t\t\toutput.Write(' ');\n\t\t\t\tmethod.WriteTo(output);\n\t\t\t}\n\t\t\toutput.Write('(');\n\t\t\tArgument.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdVirtDelegate(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdVirtDelegate(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdVirtDelegate(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdVirtDelegate;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type) && object.Equals(method, o.method);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Loads runtime representation of metadata token</summary>\n\tpublic sealed partial class LdTypeToken : SimpleInstruction\n\t{\n\t\tpublic LdTypeToken(IType type) : base(OpCode.LdTypeToken)\n\t\t{\n\t\t\tthis.type = type;\n\t\t}\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.O; } }\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdTypeToken(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdTypeToken(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdTypeToken(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdTypeToken;\n\t\t\treturn o != null && type.Equals(o.type);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Loads runtime representation of metadata token</summary>\n\tpublic sealed partial class LdMemberToken : SimpleInstruction\n\t{\n\t\tpublic LdMemberToken(IMember member) : base(OpCode.LdMemberToken)\n\t\t{\n\t\t\tthis.member = member;\n\t\t}\n\t\treadonly IMember member;\n\t\t/// <summary>Returns the token operand.</summary>\n\t\tpublic IMember Member { get { return member; } }\n\t\tpublic override StackType ResultType { get { return StackType.O; } }\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\tmember.WriteTo(output);\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdMemberToken(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdMemberToken(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdMemberToken(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdMemberToken;\n\t\t\treturn o != null && member.Equals(o.member);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Allocates space in the stack frame</summary>\n\tpublic sealed partial class LocAlloc : UnaryInstruction\n\t{\n\t\tpublic LocAlloc(ILInstruction argument) : base(OpCode.LocAlloc, argument)\n\t\t{\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.I; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLocAlloc(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLocAlloc(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLocAlloc(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LocAlloc;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Allocates space in the stack frame and wraps it in a Span</summary>\n\tpublic sealed partial class LocAllocSpan : UnaryInstruction\n\t{\n\t\tpublic LocAllocSpan(ILInstruction argument, IType type) : base(OpCode.LocAllocSpan, argument)\n\t\t{\n\t\t\tthis.type = type;\n\t\t}\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.O; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tArgument.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLocAllocSpan(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLocAllocSpan(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLocAllocSpan(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LocAllocSpan;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>memcpy(destAddress, sourceAddress, size);</summary>\n\tpublic sealed partial class Cpblk : ILInstruction, ISupportsVolatilePrefix, ISupportsUnalignedPrefix\n\t{\n\t\tpublic Cpblk(ILInstruction destAddress, ILInstruction sourceAddress, ILInstruction size) : base(OpCode.Cpblk)\n\t\t{\n\t\t\tthis.DestAddress = destAddress;\n\t\t\tthis.SourceAddress = sourceAddress;\n\t\t\tthis.Size = size;\n\t\t}\n\t\tpublic static readonly SlotInfo DestAddressSlot = new SlotInfo(\"DestAddress\", canInlineInto: true);\n\t\tILInstruction destAddress = null!;\n\t\tpublic ILInstruction DestAddress {\n\t\t\tget { return this.destAddress; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.destAddress, value, 0);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo SourceAddressSlot = new SlotInfo(\"SourceAddress\", canInlineInto: true);\n\t\tILInstruction sourceAddress = null!;\n\t\tpublic ILInstruction SourceAddress {\n\t\t\tget { return this.sourceAddress; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.sourceAddress, value, 1);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo SizeSlot = new SlotInfo(\"Size\", canInlineInto: true);\n\t\tILInstruction size = null!;\n\t\tpublic ILInstruction Size {\n\t\t\tget { return this.size; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.size, value, 2);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 3;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.destAddress;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn this.sourceAddress;\n\t\t\t\tcase 2:\n\t\t\t\t\treturn this.size;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.DestAddress = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tthis.SourceAddress = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tthis.Size = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn DestAddressSlot;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn SourceAddressSlot;\n\t\t\t\tcase 2:\n\t\t\t\t\treturn SizeSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (Cpblk)ShallowClone();\n\t\t\tclone.DestAddress = this.destAddress.Clone();\n\t\t\tclone.SourceAddress = this.sourceAddress.Clone();\n\t\t\tclone.Size = this.size.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\t/// <summary>Gets/Sets whether the memory access is volatile.</summary>\n\t\tpublic bool IsVolatile { get; set; }\n\t\t/// <summary>Returns the alignment specified by the 'unaligned' prefix; or 0 if there was no 'unaligned' prefix.</summary>\n\t\tpublic byte UnalignedPrefix { get; set; }\n\t\tpublic override StackType ResultType { get { return StackType.Void; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn destAddress.Flags | sourceAddress.Flags | size.Flags | InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\tif (IsVolatile)\n\t\t\t\toutput.Write(\"volatile.\");\n\t\t\tif (UnalignedPrefix > 0)\n\t\t\t\toutput.Write(\"unaligned(\" + UnalignedPrefix + \").\");\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write('(');\n\t\t\tthis.destAddress.WriteTo(output, options);\n\t\t\toutput.Write(\", \");\n\t\t\tthis.sourceAddress.WriteTo(output, options);\n\t\t\toutput.Write(\", \");\n\t\t\tthis.size.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitCpblk(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitCpblk(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitCpblk(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as Cpblk;\n\t\t\treturn o != null && this.destAddress.PerformMatch(o.destAddress, ref match) && this.sourceAddress.PerformMatch(o.sourceAddress, ref match) && this.size.PerformMatch(o.size, ref match) && IsVolatile == o.IsVolatile && UnalignedPrefix == o.UnalignedPrefix;\n\t\t}\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebugAssert(destAddress.ResultType == StackType.I || destAddress.ResultType == StackType.Ref);\n\t\t\tDebugAssert(sourceAddress.ResultType == StackType.I || sourceAddress.ResultType == StackType.Ref);\n\t\t\tDebugAssert(size.ResultType == StackType.I4);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>memset(address, value, size)</summary>\n\tpublic sealed partial class Initblk : ILInstruction, ISupportsVolatilePrefix, ISupportsUnalignedPrefix\n\t{\n\t\tpublic Initblk(ILInstruction address, ILInstruction value, ILInstruction size) : base(OpCode.Initblk)\n\t\t{\n\t\t\tthis.Address = address;\n\t\t\tthis.Value = value;\n\t\t\tthis.Size = size;\n\t\t}\n\t\tpublic static readonly SlotInfo AddressSlot = new SlotInfo(\"Address\", canInlineInto: true);\n\t\tILInstruction address = null!;\n\t\tpublic ILInstruction Address {\n\t\t\tget { return this.address; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.address, value, 0);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo ValueSlot = new SlotInfo(\"Value\", canInlineInto: true);\n\t\tILInstruction value = null!;\n\t\tpublic ILInstruction Value {\n\t\t\tget { return this.value; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.value, value, 1);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo SizeSlot = new SlotInfo(\"Size\", canInlineInto: true);\n\t\tILInstruction size = null!;\n\t\tpublic ILInstruction Size {\n\t\t\tget { return this.size; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.size, value, 2);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 3;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.address;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn this.value;\n\t\t\t\tcase 2:\n\t\t\t\t\treturn this.size;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Address = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tthis.Value = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tthis.Size = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn AddressSlot;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn ValueSlot;\n\t\t\t\tcase 2:\n\t\t\t\t\treturn SizeSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (Initblk)ShallowClone();\n\t\t\tclone.Address = this.address.Clone();\n\t\t\tclone.Value = this.value.Clone();\n\t\t\tclone.Size = this.size.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\t/// <summary>Gets/Sets whether the memory access is volatile.</summary>\n\t\tpublic bool IsVolatile { get; set; }\n\t\t/// <summary>Returns the alignment specified by the 'unaligned' prefix; or 0 if there was no 'unaligned' prefix.</summary>\n\t\tpublic byte UnalignedPrefix { get; set; }\n\t\tpublic override StackType ResultType { get { return StackType.Void; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn address.Flags | value.Flags | size.Flags | InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\tif (IsVolatile)\n\t\t\t\toutput.Write(\"volatile.\");\n\t\t\tif (UnalignedPrefix > 0)\n\t\t\t\toutput.Write(\"unaligned(\" + UnalignedPrefix + \").\");\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write('(');\n\t\t\tthis.address.WriteTo(output, options);\n\t\t\toutput.Write(\", \");\n\t\t\tthis.value.WriteTo(output, options);\n\t\t\toutput.Write(\", \");\n\t\t\tthis.size.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitInitblk(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitInitblk(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitInitblk(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as Initblk;\n\t\t\treturn o != null && this.address.PerformMatch(o.address, ref match) && this.value.PerformMatch(o.value, ref match) && this.size.PerformMatch(o.size, ref match) && IsVolatile == o.IsVolatile && UnalignedPrefix == o.UnalignedPrefix;\n\t\t}\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebugAssert(address.ResultType == StackType.I || address.ResultType == StackType.Ref);\n\t\t\tDebugAssert(value.ResultType == StackType.I4);\n\t\t\tDebugAssert(size.ResultType == StackType.I4);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Load address of instance field</summary>\n\tpublic sealed partial class LdFlda : ILInstruction, IInstructionWithFieldOperand\n\t{\n\t\tpublic LdFlda(ILInstruction target, IField @field) : base(OpCode.LdFlda)\n\t\t{\n\t\t\tthis.Target = target;\n\t\t\tthis.@field = @field;\n\t\t}\n\t\tpublic static readonly SlotInfo TargetSlot = new SlotInfo(\"Target\", canInlineInto: true);\n\t\tILInstruction target = null!;\n\t\tpublic ILInstruction Target {\n\t\t\tget { return this.target; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.target, value, 0);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.target;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Target = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn TargetSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (LdFlda)ShallowClone();\n\t\t\tclone.Target = this.target.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tpublic bool DelayExceptions; // NullReferenceException/IndexOutOfBoundsException only occurs when the reference is dereferenced\n\t\treadonly IField @field;\n\t\t/// <summary>Returns the field operand.</summary>\n\t\tpublic IField Field { get { return @field; } }\n\t\tpublic override StackType ResultType { get { return target.ResultType.IsIntegerType() ? StackType.I : StackType.Ref; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn target.Flags | (DelayExceptions ? InstructionFlags.None : InstructionFlags.MayThrow);\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn (DelayExceptions ? InstructionFlags.None : InstructionFlags.MayThrow);\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\tif (DelayExceptions)\n\t\t\t\toutput.Write(\"delayex.\");\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\t@field.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tthis.target.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdFlda(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdFlda(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdFlda(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdFlda;\n\t\t\treturn o != null && this.target.PerformMatch(o.target, ref match) && DelayExceptions == o.DelayExceptions && @field.Equals(o.@field);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Load static field address</summary>\n\tpublic sealed partial class LdsFlda : SimpleInstruction, IInstructionWithFieldOperand\n\t{\n\t\tpublic LdsFlda(IField @field) : base(OpCode.LdsFlda)\n\t\t{\n\t\t\tthis.@field = @field;\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.Ref; } }\n\t\treadonly IField @field;\n\t\t/// <summary>Returns the field operand.</summary>\n\t\tpublic IField Field { get { return @field; } }\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\t@field.WriteTo(output);\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdsFlda(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdsFlda(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdsFlda(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdsFlda;\n\t\t\treturn o != null && @field.Equals(o.@field);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Casts an object to a class.</summary>\n\tpublic sealed partial class CastClass : UnaryInstruction\n\t{\n\t\tpublic CastClass(ILInstruction argument, IType type) : base(OpCode.CastClass, argument)\n\t\t{\n\t\t\tthis.type = type;\n\t\t}\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\tpublic override StackType ResultType { get { return type.GetStackType(); } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tArgument.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitCastClass(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitCastClass(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitCastClass(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as CastClass;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Test if object is instance of class or interface.</summary>\n\tpublic sealed partial class IsInst : UnaryInstruction\n\t{\n\t\tpublic IsInst(ILInstruction argument, IType type) : base(OpCode.IsInst, argument)\n\t\t{\n\t\t\tthis.type = type;\n\t\t}\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.O; } }\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tArgument.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitIsInst(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitIsInst(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitIsInst(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as IsInst;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Indirect load (ref/pointer dereference).</summary>\n\tpublic sealed partial class LdObj : ILInstruction, ISupportsVolatilePrefix, ISupportsUnalignedPrefix\n\t{\n\t\tpublic LdObj(ILInstruction target, IType type) : base(OpCode.LdObj)\n\t\t{\n\t\t\tthis.Target = target;\n\t\t\tthis.type = type;\n\t\t}\n\t\tpublic static readonly SlotInfo TargetSlot = new SlotInfo(\"Target\", canInlineInto: true);\n\t\tILInstruction target = null!;\n\t\tpublic ILInstruction Target {\n\t\t\tget { return this.target; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.target, value, 0);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.target;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Target = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn TargetSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (LdObj)ShallowClone();\n\t\t\tclone.Target = this.target.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\t/// <summary>Gets/Sets whether the memory access is volatile.</summary>\n\t\tpublic bool IsVolatile { get; set; }\n\t\t/// <summary>Returns the alignment specified by the 'unaligned' prefix; or 0 if there was no 'unaligned' prefix.</summary>\n\t\tpublic byte UnalignedPrefix { get; set; }\n\t\tpublic override StackType ResultType { get { return type.GetStackType(); } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn target.Flags | InstructionFlags.SideEffect | InstructionFlags.MayThrow;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.SideEffect | InstructionFlags.MayThrow;\n\t\t\t}\n\t\t}\n\t\tvoid OriginalWriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\tif (IsVolatile)\n\t\t\t\toutput.Write(\"volatile.\");\n\t\t\tif (UnalignedPrefix > 0)\n\t\t\t\toutput.Write(\"unaligned(\" + UnalignedPrefix + \").\");\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tthis.target.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdObj(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdObj(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdObj(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdObj;\n\t\t\treturn o != null && this.target.PerformMatch(o.target, ref match) && type.Equals(o.type) && IsVolatile == o.IsVolatile && UnalignedPrefix == o.UnalignedPrefix;\n\t\t}\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebugAssert(target.ResultType == StackType.Ref || target.ResultType == StackType.I);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>If argument is a ref to a reference type, loads the object reference, stores it in a temporary, and evaluates to the address of that temporary (address.of(ldobj(arg))). Otherwise, returns the argument ref as-is.<para>This instruction represents the memory-load semantics of callvirt with a generic type as receiver (where the IL always takes a ref, but only methods on value types expect one, for method on reference types there's an implicit ldobj, which this instruction makes explicit in order to preserve the order-of-evaluation).</para></summary>\n\tpublic sealed partial class LdObjIfRef : ILInstruction\n\t{\n\t\tpublic LdObjIfRef(ILInstruction target, IType type) : base(OpCode.LdObjIfRef)\n\t\t{\n\t\t\tthis.Target = target;\n\t\t\tthis.type = type;\n\t\t}\n\t\tpublic static readonly SlotInfo TargetSlot = new SlotInfo(\"Target\", canInlineInto: true);\n\t\tILInstruction target = null!;\n\t\tpublic ILInstruction Target {\n\t\t\tget { return this.target; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.target, value, 0);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.target;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Target = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn TargetSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (LdObjIfRef)ShallowClone();\n\t\t\tclone.Target = this.target.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.Ref; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn target.Flags | InstructionFlags.SideEffect | InstructionFlags.MayThrow;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.SideEffect | InstructionFlags.MayThrow;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tthis.target.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdObjIfRef(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdObjIfRef(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdObjIfRef(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdObjIfRef;\n\t\t\treturn o != null && this.target.PerformMatch(o.target, ref match) && type.Equals(o.type);\n\t\t}\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebugAssert(target.ResultType == StackType.Ref || target.ResultType == StackType.I);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Indirect store (store to ref/pointer).\n\t/// Evaluates to the value that was stored (when using type byte/short: evaluates to the truncated value, sign/zero extended back to I4 based on type.GetSign())</summary>\n\tpublic sealed partial class StObj : ILInstruction, ISupportsVolatilePrefix, ISupportsUnalignedPrefix\n\t{\n\t\tpublic StObj(ILInstruction target, ILInstruction value, IType type) : base(OpCode.StObj)\n\t\t{\n\t\t\tthis.Target = target;\n\t\t\tthis.Value = value;\n\t\t\tthis.type = type;\n\t\t}\n\t\tpublic static readonly SlotInfo TargetSlot = new SlotInfo(\"Target\", canInlineInto: true);\n\t\tILInstruction target = null!;\n\t\tpublic ILInstruction Target {\n\t\t\tget { return this.target; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.target, value, 0);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo ValueSlot = new SlotInfo(\"Value\", canInlineInto: true);\n\t\tILInstruction value = null!;\n\t\tpublic ILInstruction Value {\n\t\t\tget { return this.value; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.value, value, 1);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 2;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.target;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn this.value;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Target = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tthis.Value = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn TargetSlot;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn ValueSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (StObj)ShallowClone();\n\t\t\tclone.Target = this.target.Clone();\n\t\t\tclone.Value = this.value.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\t/// <summary>Gets/Sets whether the memory access is volatile.</summary>\n\t\tpublic bool IsVolatile { get; set; }\n\t\t/// <summary>Returns the alignment specified by the 'unaligned' prefix; or 0 if there was no 'unaligned' prefix.</summary>\n\t\tpublic byte UnalignedPrefix { get; set; }\n\t\tpublic override StackType ResultType { get { return UnalignedPrefix == 0 ? type.GetStackType() : StackType.Void; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn target.Flags | value.Flags | InstructionFlags.SideEffect | InstructionFlags.MayThrow;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.SideEffect | InstructionFlags.MayThrow;\n\t\t\t}\n\t\t}\n\t\tvoid OriginalWriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\tif (IsVolatile)\n\t\t\t\toutput.Write(\"volatile.\");\n\t\t\tif (UnalignedPrefix > 0)\n\t\t\t\toutput.Write(\"unaligned(\" + UnalignedPrefix + \").\");\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tthis.target.WriteTo(output, options);\n\t\t\toutput.Write(\", \");\n\t\t\tthis.value.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitStObj(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitStObj(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitStObj(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as StObj;\n\t\t\treturn o != null && this.target.PerformMatch(o.target, ref match) && this.value.PerformMatch(o.value, ref match) && type.Equals(o.type) && IsVolatile == o.IsVolatile && UnalignedPrefix == o.UnalignedPrefix;\n\t\t}\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebugAssert(target.ResultType == StackType.Ref || target.ResultType == StackType.I);\n\t\t\tDebugAssert(value.ResultType == type.GetStackType());\n\t\t\tCheckTargetSlot();\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Boxes a value.</summary>\n\tpublic sealed partial class Box : UnaryInstruction\n\t{\n\t\tpublic Box(ILInstruction argument, IType type) : base(OpCode.Box, argument)\n\t\t{\n\t\t\tthis.type = type;\n\t\t}\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.O; } }\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tArgument.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitBox(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitBox(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitBox(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as Box;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Compute address inside box.</summary>\n\tpublic sealed partial class Unbox : UnaryInstruction\n\t{\n\t\tpublic Unbox(ILInstruction argument, IType type) : base(OpCode.Unbox, argument)\n\t\t{\n\t\t\tthis.type = type;\n\t\t}\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.Ref; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tArgument.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitUnbox(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitUnbox(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitUnbox(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as Unbox;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Unbox a value.</summary>\n\tpublic sealed partial class UnboxAny : UnaryInstruction\n\t{\n\t\tpublic UnboxAny(ILInstruction argument, IType type) : base(OpCode.UnboxAny, argument)\n\t\t{\n\t\t\tthis.type = type;\n\t\t}\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\tpublic override StackType ResultType { get { return type.GetStackType(); } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.SideEffect | InstructionFlags.MayThrow;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.SideEffect | InstructionFlags.MayThrow;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tArgument.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitUnboxAny(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitUnboxAny(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitUnboxAny(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as UnboxAny;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Creates an object instance and calls the constructor.</summary>\n\tpublic sealed partial class NewObj : CallInstruction\n\t{\n\t\tpublic NewObj(IMethod method) : base(OpCode.NewObj, method)\n\t\t{\n\t\t}\n\t\tpublic override StackType ResultType { get { return Method.DeclaringType.GetStackType(); } }\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitNewObj(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitNewObj(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitNewObj(this, context);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Creates an array instance.</summary>\n\tpublic sealed partial class NewArr : ILInstruction\n\t{\n\t\tpublic NewArr(IType type, params ILInstruction[] indices) : base(OpCode.NewArr)\n\t\t{\n\t\t\tthis.type = type;\n\t\t\tthis.Indices = new InstructionCollection<ILInstruction>(this, 0);\n\t\t\tthis.Indices.AddRange(indices);\n\t\t}\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\tpublic static readonly SlotInfo IndicesSlot = new SlotInfo(\"Indices\", canInlineInto: true);\n\t\tpublic InstructionCollection<ILInstruction> Indices { get; private set; }\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn Indices.Count;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\treturn this.Indices[index - 0];\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\tthis.Indices[index - 0] = (ILInstruction)value;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\treturn IndicesSlot;\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (NewArr)ShallowClone();\n\t\t\tclone.Indices = new InstructionCollection<ILInstruction>(clone, 0);\n\t\t\tclone.Indices.AddRange(this.Indices.Select(arg => (ILInstruction)arg.Clone()));\n\t\t\treturn clone;\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.O; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn Indices.Aggregate(InstructionFlags.None, (f, arg) => f | arg.Flags) | InstructionFlags.MayThrow;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayThrow;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tbool first = true;\n\t\t\tforeach (var indices in Indices)\n\t\t\t{\n\t\t\t\tif (!first)\n\t\t\t\t\toutput.Write(\", \");\n\t\t\t\telse\n\t\t\t\t\tfirst = false;\n\t\t\t\tindices.WriteTo(output, options);\n\t\t\t}\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitNewArr(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitNewArr(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitNewArr(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as NewArr;\n\t\t\treturn o != null && type.Equals(o.type) && Patterns.ListMatch.DoMatch(this.Indices, o.Indices, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Returns the default value for a type.</summary>\n\tpublic sealed partial class DefaultValue : SimpleInstruction\n\t{\n\t\tpublic DefaultValue(IType type) : base(OpCode.DefaultValue)\n\t\t{\n\t\t\tthis.type = type;\n\t\t}\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\tpublic override StackType ResultType { get { return type.GetStackType(); } }\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDefaultValue(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDefaultValue(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitDefaultValue(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as DefaultValue;\n\t\t\treturn o != null && type.Equals(o.type);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Throws an exception.</summary>\n\tpublic sealed partial class Throw : UnaryInstruction\n\t{\n\t\tpublic Throw(ILInstruction argument) : base(OpCode.Throw, argument)\n\t\t{\n\t\t}\n\t\tpublic override StackType ResultType { get { return this.resultType; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow | InstructionFlags.EndPointUnreachable;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow | InstructionFlags.EndPointUnreachable;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitThrow(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitThrow(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitThrow(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as Throw;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Rethrows the current exception.</summary>\n\tpublic sealed partial class Rethrow : SimpleInstruction\n\t{\n\t\tpublic Rethrow() : base(OpCode.Rethrow)\n\t\t{\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.Void; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn InstructionFlags.MayThrow | InstructionFlags.EndPointUnreachable;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayThrow | InstructionFlags.EndPointUnreachable;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitRethrow(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitRethrow(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitRethrow(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as Rethrow;\n\t\t\treturn o != null;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Gets the size of a type in bytes.</summary>\n\tpublic sealed partial class SizeOf : SimpleInstruction\n\t{\n\t\tpublic SizeOf(IType type) : base(OpCode.SizeOf)\n\t\t{\n\t\t\tthis.type = type;\n\t\t}\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.I4; } }\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitSizeOf(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitSizeOf(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitSizeOf(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as SizeOf;\n\t\t\treturn o != null && type.Equals(o.type);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Returns the length of an array as 'native unsigned int'.</summary>\n\tpublic sealed partial class LdLen : ILInstruction\n\t{\n\t\tpublic static readonly SlotInfo ArraySlot = new SlotInfo(\"Array\", canInlineInto: true);\n\t\tILInstruction array = null!;\n\t\tpublic ILInstruction Array {\n\t\t\tget { return this.array; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.array, value, 0);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.array;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Array = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn ArraySlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (LdLen)ShallowClone();\n\t\t\tclone.Array = this.array.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn array.Flags | InstructionFlags.MayThrow;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayThrow;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdLen(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdLen(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdLen(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdLen;\n\t\t\treturn o != null && this.array.PerformMatch(o.array, ref match);\n\t\t}\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebugAssert(array.ResultType == StackType.O);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Load address of array element.</summary>\n\tpublic sealed partial class LdElema : ILInstruction\n\t{\n\t\tpublic LdElema(IType type, ILInstruction array, params ILInstruction[] indices) : base(OpCode.LdElema)\n\t\t{\n\t\t\tthis.type = type;\n\t\t\tthis.Array = array;\n\t\t\tthis.Indices = new InstructionCollection<ILInstruction>(this, 1);\n\t\t\tthis.Indices.AddRange(indices);\n\t\t}\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\tpublic static readonly SlotInfo ArraySlot = new SlotInfo(\"Array\", canInlineInto: true);\n\t\tILInstruction array = null!;\n\t\tpublic ILInstruction Array {\n\t\t\tget { return this.array; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.array, value, 0);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo IndicesSlot = new SlotInfo(\"Indices\", canInlineInto: true);\n\t\tpublic InstructionCollection<ILInstruction> Indices { get; private set; }\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1 + Indices.Count;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.array;\n\t\t\t\tdefault:\n\t\t\t\t\treturn this.Indices[index - 1];\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Array = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthis.Indices[index - 1] = (ILInstruction)value;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn ArraySlot;\n\t\t\t\tdefault:\n\t\t\t\t\treturn IndicesSlot;\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (LdElema)ShallowClone();\n\t\t\tclone.Array = this.array.Clone();\n\t\t\tclone.Indices = new InstructionCollection<ILInstruction>(clone, 1);\n\t\t\tclone.Indices.AddRange(this.Indices.Select(arg => (ILInstruction)arg.Clone()));\n\t\t\treturn clone;\n\t\t}\n\t\tpublic bool WithSystemIndex;\n\t\tpublic bool DelayExceptions; // NullReferenceException/IndexOutOfBoundsException only occurs when the reference is dereferenced\n\t\tpublic override StackType ResultType { get { return StackType.Ref; } }\n\t\t/// <summary>Gets whether the 'readonly' prefix was applied to this instruction.</summary>\n\t\tpublic bool IsReadOnly { get; set; }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn array.Flags | Indices.Aggregate(InstructionFlags.None, (f, arg) => f | arg.Flags) | (DelayExceptions ? InstructionFlags.None : InstructionFlags.MayThrow);\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn (DelayExceptions ? InstructionFlags.None : InstructionFlags.MayThrow);\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\tif (WithSystemIndex)\n\t\t\t\toutput.Write(\"withsystemindex.\");\n\t\t\tif (DelayExceptions)\n\t\t\t\toutput.Write(\"delayex.\");\n\t\t\tif (IsReadOnly)\n\t\t\t\toutput.Write(\"readonly.\");\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tthis.array.WriteTo(output, options);\n\t\t\tforeach (var indices in Indices)\n\t\t\t{\n\t\t\t\toutput.Write(\", \");\n\t\t\t\tindices.WriteTo(output, options);\n\t\t\t}\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdElema(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdElema(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdElema(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdElema;\n\t\t\treturn o != null && type.Equals(o.type) && this.array.PerformMatch(o.array, ref match) && Patterns.ListMatch.DoMatch(this.Indices, o.Indices, ref match) && this.WithSystemIndex == o.WithSystemIndex && DelayExceptions == o.DelayExceptions && IsReadOnly == o.IsReadOnly;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Load address of inline array element.</summary>\n\tpublic sealed partial class LdElemaInlineArray : ILInstruction\n\t{\n\t\tpublic LdElemaInlineArray(IType type, ILInstruction array, params ILInstruction[] indices) : base(OpCode.LdElemaInlineArray)\n\t\t{\n\t\t\tthis.type = type;\n\t\t\tthis.Array = array;\n\t\t\tthis.Indices = new InstructionCollection<ILInstruction>(this, 1);\n\t\t\tthis.Indices.AddRange(indices);\n\t\t}\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\tpublic static readonly SlotInfo ArraySlot = new SlotInfo(\"Array\", canInlineInto: true);\n\t\tILInstruction array = null!;\n\t\tpublic ILInstruction Array {\n\t\t\tget { return this.array; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.array, value, 0);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo IndicesSlot = new SlotInfo(\"Indices\", canInlineInto: true);\n\t\tpublic InstructionCollection<ILInstruction> Indices { get; private set; }\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1 + Indices.Count;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.array;\n\t\t\t\tdefault:\n\t\t\t\t\treturn this.Indices[index - 1];\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Array = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthis.Indices[index - 1] = (ILInstruction)value;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn ArraySlot;\n\t\t\t\tdefault:\n\t\t\t\t\treturn IndicesSlot;\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (LdElemaInlineArray)ShallowClone();\n\t\t\tclone.Array = this.array.Clone();\n\t\t\tclone.Indices = new InstructionCollection<ILInstruction>(clone, 1);\n\t\t\tclone.Indices.AddRange(this.Indices.Select(arg => (ILInstruction)arg.Clone()));\n\t\t\treturn clone;\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.Ref; } }\n\t\t/// <summary>Gets whether the 'readonly' prefix was applied to this instruction.</summary>\n\t\tpublic bool IsReadOnly { get; set; }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn array.Flags | Indices.Aggregate(InstructionFlags.None, (f, arg) => f | arg.Flags) | InstructionFlags.MayThrow;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayThrow;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\tif (IsReadOnly)\n\t\t\t\toutput.Write(\"readonly.\");\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tthis.array.WriteTo(output, options);\n\t\t\tforeach (var indices in Indices)\n\t\t\t{\n\t\t\t\toutput.Write(\", \");\n\t\t\t\tindices.WriteTo(output, options);\n\t\t\t}\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitLdElemaInlineArray(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitLdElemaInlineArray(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitLdElemaInlineArray(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as LdElemaInlineArray;\n\t\t\treturn o != null && type.Equals(o.type) && this.array.PerformMatch(o.array, ref match) && Patterns.ListMatch.DoMatch(this.Indices, o.Indices, ref match) && IsReadOnly == o.IsReadOnly;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Retrieves a pinnable reference for the input object.\n\t/// The input must be an object reference (O).\n\t/// If the input is an array/string, evaluates to a reference to the first element/character, or to a null reference if the array is null or empty.\n\t/// Otherwise, uses the GetPinnableReference method to get the reference, or evaluates to a null reference if the input is null.\n\t/// </summary>\n\tpublic sealed partial class GetPinnableReference : ILInstruction, IInstructionWithMethodOperand\n\t{\n\t\tpublic GetPinnableReference(ILInstruction argument, IMethod? method) : base(OpCode.GetPinnableReference)\n\t\t{\n\t\t\tthis.Argument = argument;\n\t\t\tthis.method = method;\n\t\t}\n\t\tpublic static readonly SlotInfo ArgumentSlot = new SlotInfo(\"Argument\", canInlineInto: true);\n\t\tILInstruction argument = null!;\n\t\tpublic ILInstruction Argument {\n\t\t\tget { return this.argument; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.argument, value, 0);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.argument;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Argument = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn ArgumentSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (GetPinnableReference)ShallowClone();\n\t\t\tclone.Argument = this.argument.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.Ref; } }\n\t\treadonly IMethod? method;\n\t\t/// <summary>Returns the method operand.</summary>\n\t\tpublic IMethod? Method => method;\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn argument.Flags;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.None;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tif (method != null)\n\t\t\t{\n\t\t\t\toutput.Write(' ');\n\t\t\t\tmethod.WriteTo(output);\n\t\t\t}\n\t\t\toutput.Write('(');\n\t\t\tthis.argument.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitGetPinnableReference(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitGetPinnableReference(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitGetPinnableReference(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as GetPinnableReference;\n\t\t\treturn o != null && this.argument.PerformMatch(o.argument, ref match) && object.Equals(method, o.method);\n\t\t}\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebugAssert(argument.ResultType == StackType.O);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Maps a string value to an integer. This is used in switch(string).</summary>\n\tpublic sealed partial class StringToInt : ILInstruction\n\t{\n\t\tpublic static readonly SlotInfo ArgumentSlot = new SlotInfo(\"Argument\", canInlineInto: true);\n\t\tILInstruction argument = null!;\n\t\tpublic ILInstruction Argument {\n\t\t\tget { return this.argument; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.argument, value, 0);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.argument;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Argument = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn ArgumentSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (StringToInt)ShallowClone();\n\t\t\tclone.Argument = this.argument.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.I4; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn argument.Flags;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.None;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitStringToInt(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitStringToInt(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitStringToInt(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as StringToInt;\n\t\t\treturn o != null && this.argument.PerformMatch(o.argument, ref match);\n\t\t}\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebugAssert(argument.ResultType == StackType.O);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>ILAst representation of Expression.Convert.</summary>\n\tpublic sealed partial class ExpressionTreeCast : UnaryInstruction\n\t{\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\tpublic override StackType ResultType { get { return type.GetStackType(); } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitExpressionTreeCast(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitExpressionTreeCast(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitExpressionTreeCast(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as ExpressionTreeCast;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type) && this.IsChecked == o.IsChecked;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Use of user-defined &amp;&amp; or || operator.</summary>\n\tpublic sealed partial class UserDefinedLogicOperator : ILInstruction, IInstructionWithMethodOperand\n\t{\n\t\tpublic UserDefinedLogicOperator(IMethod method, ILInstruction left, ILInstruction right) : base(OpCode.UserDefinedLogicOperator)\n\t\t{\n\t\t\tthis.method = method;\n\t\t\tthis.Left = left;\n\t\t\tthis.Right = right;\n\t\t}\n\t\treadonly IMethod method;\n\t\t/// <summary>Returns the method operand.</summary>\n\t\tpublic IMethod Method => method;\n\t\tpublic override StackType ResultType { get { return StackType.O; } }\n\t\tpublic static readonly SlotInfo LeftSlot = new SlotInfo(\"Left\", canInlineInto: true);\n\t\tILInstruction left = null!;\n\t\tpublic ILInstruction Left {\n\t\t\tget { return this.left; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.left, value, 0);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo RightSlot = new SlotInfo(\"Right\");\n\t\tILInstruction right = null!;\n\t\tpublic ILInstruction Right {\n\t\t\tget { return this.right; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.right, value, 1);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 2;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.left;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn this.right;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Left = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tthis.Right = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn LeftSlot;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn RightSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (UserDefinedLogicOperator)ShallowClone();\n\t\t\tclone.Left = this.left.Clone();\n\t\t\tclone.Right = this.right.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\tif (method != null)\n\t\t\t{\n\t\t\t\toutput.Write(' ');\n\t\t\t\tmethod.WriteTo(output);\n\t\t\t}\n\t\t\toutput.Write('(');\n\t\t\tthis.left.WriteTo(output, options);\n\t\t\toutput.Write(\", \");\n\t\t\tthis.right.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitUserDefinedLogicOperator(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitUserDefinedLogicOperator(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitUserDefinedLogicOperator(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as UserDefinedLogicOperator;\n\t\t\treturn o != null && object.Equals(method, o.method) && this.left.PerformMatch(o.left, ref match) && this.right.PerformMatch(o.right, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>ILAst representation of a short-circuiting binary operator inside a dynamic expression.</summary>\n\tpublic sealed partial class DynamicLogicOperatorInstruction : DynamicInstruction\n\t{\n\t\tpublic static readonly SlotInfo LeftSlot = new SlotInfo(\"Left\", canInlineInto: true);\n\t\tILInstruction left = null!;\n\t\tpublic ILInstruction Left {\n\t\t\tget { return this.left; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.left, value, 0);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo RightSlot = new SlotInfo(\"Right\");\n\t\tILInstruction right = null!;\n\t\tpublic ILInstruction Right {\n\t\t\tget { return this.right; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.right, value, 1);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 2;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.left;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn this.right;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Left = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tthis.Right = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn LeftSlot;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn RightSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (DynamicLogicOperatorInstruction)ShallowClone();\n\t\t\tclone.Left = this.left.Clone();\n\t\t\tclone.Right = this.right.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDynamicLogicOperatorInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDynamicLogicOperatorInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitDynamicLogicOperatorInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as DynamicLogicOperatorInstruction;\n\t\t\treturn o != null && this.left.PerformMatch(o.left, ref match) && this.right.PerformMatch(o.right, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>ILAst representation of a binary operator inside a dynamic expression (maps to Binder.BinaryOperation).</summary>\n\tpublic sealed partial class DynamicBinaryOperatorInstruction : DynamicInstruction\n\t{\n\t\tpublic static readonly SlotInfo LeftSlot = new SlotInfo(\"Left\", canInlineInto: true);\n\t\tILInstruction left = null!;\n\t\tpublic ILInstruction Left {\n\t\t\tget { return this.left; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.left, value, 0);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo RightSlot = new SlotInfo(\"Right\", canInlineInto: true);\n\t\tILInstruction right = null!;\n\t\tpublic ILInstruction Right {\n\t\t\tget { return this.right; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.right, value, 1);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 2;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.left;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn this.right;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Left = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tthis.Right = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn LeftSlot;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn RightSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (DynamicBinaryOperatorInstruction)ShallowClone();\n\t\t\tclone.Left = this.left.Clone();\n\t\t\tclone.Right = this.right.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow | InstructionFlags.SideEffect | left.Flags | right.Flags;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDynamicBinaryOperatorInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDynamicBinaryOperatorInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitDynamicBinaryOperatorInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as DynamicBinaryOperatorInstruction;\n\t\t\treturn o != null && this.left.PerformMatch(o.left, ref match) && this.right.PerformMatch(o.right, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>ILAst representation of a unary operator inside a dynamic expression (maps to Binder.UnaryOperation).</summary>\n\tpublic sealed partial class DynamicUnaryOperatorInstruction : DynamicInstruction\n\t{\n\t\tpublic static readonly SlotInfo OperandSlot = new SlotInfo(\"Operand\", canInlineInto: true);\n\t\tILInstruction operand = null!;\n\t\tpublic ILInstruction Operand {\n\t\t\tget { return this.operand; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.operand, value, 0);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.operand;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Operand = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn OperandSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (DynamicUnaryOperatorInstruction)ShallowClone();\n\t\t\tclone.Operand = this.operand.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow | InstructionFlags.SideEffect | operand.Flags;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDynamicUnaryOperatorInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDynamicUnaryOperatorInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitDynamicUnaryOperatorInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as DynamicUnaryOperatorInstruction;\n\t\t\treturn o != null && this.operand.PerformMatch(o.operand, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>ILAst representation of a cast inside a dynamic expression (maps to Binder.Convert).</summary>\n\tpublic sealed partial class DynamicConvertInstruction : DynamicInstruction\n\t{\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\tpublic static readonly SlotInfo ArgumentSlot = new SlotInfo(\"Argument\", canInlineInto: true);\n\t\tILInstruction argument = null!;\n\t\tpublic ILInstruction Argument {\n\t\t\tget { return this.argument; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.argument, value, 0);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.argument;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Argument = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn ArgumentSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (DynamicConvertInstruction)ShallowClone();\n\t\t\tclone.Argument = this.argument.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow | InstructionFlags.SideEffect | argument.Flags;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDynamicConvertInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDynamicConvertInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitDynamicConvertInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as DynamicConvertInstruction;\n\t\t\treturn o != null && type.Equals(o.type) && this.argument.PerformMatch(o.argument, ref match);\n\t\t}\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebugAssert(argument.ResultType == StackType.O);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>ILAst representation of a property get method call inside a dynamic expression (maps to Binder.GetMember).</summary>\n\tpublic sealed partial class DynamicGetMemberInstruction : DynamicInstruction\n\t{\n\t\tpublic static readonly SlotInfo TargetSlot = new SlotInfo(\"Target\", canInlineInto: true);\n\t\tILInstruction target = null!;\n\t\tpublic ILInstruction Target {\n\t\t\tget { return this.target; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.target, value, 0);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.target;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Target = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn TargetSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (DynamicGetMemberInstruction)ShallowClone();\n\t\t\tclone.Target = this.target.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow | InstructionFlags.SideEffect | target.Flags;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDynamicGetMemberInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDynamicGetMemberInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitDynamicGetMemberInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as DynamicGetMemberInstruction;\n\t\t\treturn o != null && this.target.PerformMatch(o.target, ref match);\n\t\t}\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebugAssert(target.ResultType == StackType.O);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>ILAst representation of a property set method call inside a dynamic expression (maps to Binder.SetMember).</summary>\n\tpublic sealed partial class DynamicSetMemberInstruction : DynamicInstruction\n\t{\n\t\tpublic static readonly SlotInfo TargetSlot = new SlotInfo(\"Target\", canInlineInto: true);\n\t\tILInstruction target = null!;\n\t\tpublic ILInstruction Target {\n\t\t\tget { return this.target; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.target, value, 0);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo ValueSlot = new SlotInfo(\"Value\", canInlineInto: true);\n\t\tILInstruction value = null!;\n\t\tpublic ILInstruction Value {\n\t\t\tget { return this.value; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.value, value, 1);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 2;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.target;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn this.value;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Target = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tthis.Value = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn TargetSlot;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn ValueSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (DynamicSetMemberInstruction)ShallowClone();\n\t\t\tclone.Target = this.target.Clone();\n\t\t\tclone.Value = this.value.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow | InstructionFlags.SideEffect | target.Flags | value.Flags;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDynamicSetMemberInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDynamicSetMemberInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitDynamicSetMemberInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as DynamicSetMemberInstruction;\n\t\t\treturn o != null && this.target.PerformMatch(o.target, ref match) && this.value.PerformMatch(o.value, ref match);\n\t\t}\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebugAssert(target.ResultType == StackType.O);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>ILAst representation of an indexer get method call inside a dynamic expression (maps to Binder.GetIndex).</summary>\n\tpublic sealed partial class DynamicGetIndexInstruction : DynamicInstruction\n\t{\n\t\tpublic static readonly SlotInfo ArgumentsSlot = new SlotInfo(\"Arguments\", canInlineInto: true);\n\t\tpublic InstructionCollection<ILInstruction> Arguments { get; private set; }\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn Arguments.Count;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\treturn this.Arguments[index - 0];\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\tthis.Arguments[index - 0] = (ILInstruction)value;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\treturn ArgumentsSlot;\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (DynamicGetIndexInstruction)ShallowClone();\n\t\t\tclone.Arguments = new InstructionCollection<ILInstruction>(clone, 0);\n\t\t\tclone.Arguments.AddRange(this.Arguments.Select(arg => (ILInstruction)arg.Clone()));\n\t\t\treturn clone;\n\t\t}\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow | InstructionFlags.SideEffect | Arguments.Aggregate(InstructionFlags.None, (f, arg) => f | arg.Flags);\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDynamicGetIndexInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDynamicGetIndexInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitDynamicGetIndexInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as DynamicGetIndexInstruction;\n\t\t\treturn o != null && Patterns.ListMatch.DoMatch(this.Arguments, o.Arguments, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>ILAst representation of an indexer set method call inside a dynamic expression (maps to Binder.SetIndex).</summary>\n\tpublic sealed partial class DynamicSetIndexInstruction : DynamicInstruction\n\t{\n\t\tpublic static readonly SlotInfo ArgumentsSlot = new SlotInfo(\"Arguments\", canInlineInto: true);\n\t\tpublic InstructionCollection<ILInstruction> Arguments { get; private set; }\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn Arguments.Count;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\treturn this.Arguments[index - 0];\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\tthis.Arguments[index - 0] = (ILInstruction)value;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\treturn ArgumentsSlot;\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (DynamicSetIndexInstruction)ShallowClone();\n\t\t\tclone.Arguments = new InstructionCollection<ILInstruction>(clone, 0);\n\t\t\tclone.Arguments.AddRange(this.Arguments.Select(arg => (ILInstruction)arg.Clone()));\n\t\t\treturn clone;\n\t\t}\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow | InstructionFlags.SideEffect | Arguments.Aggregate(InstructionFlags.None, (f, arg) => f | arg.Flags);\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDynamicSetIndexInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDynamicSetIndexInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitDynamicSetIndexInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as DynamicSetIndexInstruction;\n\t\t\treturn o != null && Patterns.ListMatch.DoMatch(this.Arguments, o.Arguments, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>ILAst representation of a method call inside a dynamic expression (maps to Binder.InvokeMember).</summary>\n\tpublic sealed partial class DynamicInvokeMemberInstruction : DynamicInstruction\n\t{\n\t\tpublic static readonly SlotInfo ArgumentsSlot = new SlotInfo(\"Arguments\", canInlineInto: true);\n\t\tpublic InstructionCollection<ILInstruction> Arguments { get; private set; }\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn Arguments.Count;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\treturn this.Arguments[index - 0];\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\tthis.Arguments[index - 0] = (ILInstruction)value;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\treturn ArgumentsSlot;\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (DynamicInvokeMemberInstruction)ShallowClone();\n\t\t\tclone.Arguments = new InstructionCollection<ILInstruction>(clone, 0);\n\t\t\tclone.Arguments.AddRange(this.Arguments.Select(arg => (ILInstruction)arg.Clone()));\n\t\t\treturn clone;\n\t\t}\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow | InstructionFlags.SideEffect | Arguments.Aggregate(InstructionFlags.None, (f, arg) => f | arg.Flags);\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDynamicInvokeMemberInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDynamicInvokeMemberInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitDynamicInvokeMemberInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as DynamicInvokeMemberInstruction;\n\t\t\treturn o != null && Patterns.ListMatch.DoMatch(this.Arguments, o.Arguments, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>ILAst representation of a constuctor invocation inside a dynamic expression (maps to Binder.InvokeConstructor).</summary>\n\tpublic sealed partial class DynamicInvokeConstructorInstruction : DynamicInstruction\n\t{\n\t\tpublic static readonly SlotInfo ArgumentsSlot = new SlotInfo(\"Arguments\", canInlineInto: true);\n\t\tpublic InstructionCollection<ILInstruction> Arguments { get; private set; }\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn Arguments.Count;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\treturn this.Arguments[index - 0];\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\tthis.Arguments[index - 0] = (ILInstruction)value;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\treturn ArgumentsSlot;\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (DynamicInvokeConstructorInstruction)ShallowClone();\n\t\t\tclone.Arguments = new InstructionCollection<ILInstruction>(clone, 0);\n\t\t\tclone.Arguments.AddRange(this.Arguments.Select(arg => (ILInstruction)arg.Clone()));\n\t\t\treturn clone;\n\t\t}\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow | InstructionFlags.SideEffect | Arguments.Aggregate(InstructionFlags.None, (f, arg) => f | arg.Flags);\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDynamicInvokeConstructorInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDynamicInvokeConstructorInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitDynamicInvokeConstructorInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as DynamicInvokeConstructorInstruction;\n\t\t\treturn o != null && Patterns.ListMatch.DoMatch(this.Arguments, o.Arguments, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>ILAst representation of a delegate invocation inside a dynamic expression (maps to Binder.Invoke).</summary>\n\tpublic sealed partial class DynamicInvokeInstruction : DynamicInstruction\n\t{\n\t\tpublic static readonly SlotInfo ArgumentsSlot = new SlotInfo(\"Arguments\", canInlineInto: true);\n\t\tpublic InstructionCollection<ILInstruction> Arguments { get; private set; }\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn Arguments.Count;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\treturn this.Arguments[index - 0];\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\tthis.Arguments[index - 0] = (ILInstruction)value;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\treturn ArgumentsSlot;\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (DynamicInvokeInstruction)ShallowClone();\n\t\t\tclone.Arguments = new InstructionCollection<ILInstruction>(clone, 0);\n\t\t\tclone.Arguments.AddRange(this.Arguments.Select(arg => (ILInstruction)arg.Clone()));\n\t\t\treturn clone;\n\t\t}\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow | InstructionFlags.SideEffect | Arguments.Aggregate(InstructionFlags.None, (f, arg) => f | arg.Flags);\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDynamicInvokeInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDynamicInvokeInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitDynamicInvokeInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as DynamicInvokeInstruction;\n\t\t\treturn o != null && Patterns.ListMatch.DoMatch(this.Arguments, o.Arguments, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>ILAst representation of a call to the Binder.IsEvent method inside a dynamic expression.</summary>\n\tpublic sealed partial class DynamicIsEventInstruction : DynamicInstruction\n\t{\n\t\tpublic static readonly SlotInfo ArgumentSlot = new SlotInfo(\"Argument\", canInlineInto: true);\n\t\tILInstruction argument = null!;\n\t\tpublic ILInstruction Argument {\n\t\t\tget { return this.argument; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.argument, value, 0);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.argument;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Argument = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn ArgumentSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (DynamicIsEventInstruction)ShallowClone();\n\t\t\tclone.Argument = this.argument.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow | InstructionFlags.SideEffect | argument.Flags;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDynamicIsEventInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDynamicIsEventInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitDynamicIsEventInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as DynamicIsEventInstruction;\n\t\t\treturn o != null && this.argument.PerformMatch(o.argument, ref match);\n\t\t}\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebugAssert(argument.ResultType == StackType.O);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>ILAst representation of C# patterns</summary>\n\tpublic sealed partial class MatchInstruction : ILInstruction, IStoreInstruction, IInstructionWithMethodOperand\n\t{\n\t\tpublic MatchInstruction(ILVariable variable, IMethod? method, ILInstruction testedOperand, params ILInstruction[] subPatterns) : base(OpCode.MatchInstruction)\n\t\t{\n\t\t\tthis.variable = variable ?? throw new ArgumentNullException(nameof(variable));\n\t\t\tthis.method = method;\n\t\t\tthis.TestedOperand = testedOperand;\n\t\t\tthis.SubPatterns = new InstructionCollection<ILInstruction>(this, 1);\n\t\t\tthis.SubPatterns.AddRange(subPatterns);\n\t\t}\n\t\tILVariable variable;\n\t\tpublic ILVariable Variable {\n\t\t\tget { return variable; }\n\t\t\tset {\n\t\t\t\tDebugAssert(value != null);\n\t\t\t\tif (IsConnected)\n\t\t\t\t\tvariable.RemoveStoreInstruction(this);\n\t\t\t\tvariable = value;\n\t\t\t\tif (IsConnected)\n\t\t\t\t\tvariable.AddStoreInstruction(this);\n\t\t\t}\n\t\t}\n\n\t\tpublic int IndexInStoreInstructionList { get; set; } = -1;\n\n\t\tint IInstructionWithVariableOperand.IndexInVariableInstructionMapping {\n\t\t\tget { return ((IStoreInstruction)this).IndexInStoreInstructionList; }\n\t\t\tset { ((IStoreInstruction)this).IndexInStoreInstructionList = value; }\n\t\t}\n\n\t\tprotected override void Connected()\n\t\t{\n\t\t\tbase.Connected();\n\t\t\tvariable.AddStoreInstruction(this);\n\t\t}\n\n\t\tprotected override void Disconnected()\n\t\t{\n\t\t\tvariable.RemoveStoreInstruction(this);\n\t\t\tbase.Disconnected();\n\t\t}\n\n\t\treadonly IMethod? method;\n\t\t/// <summary>Returns the method operand.</summary>\n\t\tpublic IMethod? Method => method;\n\t\tpublic bool IsDeconstructCall;\n\t\tpublic bool IsDeconstructTuple;\n\t\tpublic bool CheckType;\n\t\tpublic bool CheckNotNull;\n\t\tpublic static readonly SlotInfo TestedOperandSlot = new SlotInfo(\"TestedOperand\", canInlineInto: true);\n\t\tILInstruction testedOperand = null!;\n\t\tpublic ILInstruction TestedOperand {\n\t\t\tget { return this.testedOperand; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.testedOperand, value, 0);\n\t\t\t}\n\t\t}\n\t\tpublic static readonly SlotInfo SubPatternsSlot = new SlotInfo(\"SubPatterns\");\n\t\tpublic InstructionCollection<ILInstruction> SubPatterns { get; private set; }\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1 + SubPatterns.Count;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.testedOperand;\n\t\t\t\tdefault:\n\t\t\t\t\treturn this.SubPatterns[index - 1];\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.TestedOperand = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthis.SubPatterns[index - 1] = (ILInstruction)value;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn TestedOperandSlot;\n\t\t\t\tdefault:\n\t\t\t\t\treturn SubPatternsSlot;\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (MatchInstruction)ShallowClone();\n\t\t\tclone.TestedOperand = this.testedOperand.Clone();\n\t\t\tclone.SubPatterns = new InstructionCollection<ILInstruction>(clone, 1);\n\t\t\tclone.SubPatterns.AddRange(this.SubPatterns.Select(arg => (ILInstruction)arg.Clone()));\n\t\t\treturn clone;\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.I4; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn InstructionFlags.MayWriteLocals | testedOperand.Flags | SubPatterns.Aggregate(InstructionFlags.None, (f, arg) => f | arg.Flags) | InstructionFlags.SideEffect | InstructionFlags.MayThrow | InstructionFlags.ControlFlow;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayWriteLocals | InstructionFlags.SideEffect | InstructionFlags.MayThrow | InstructionFlags.ControlFlow;\n\t\t\t}\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitMatchInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitMatchInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitMatchInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as MatchInstruction;\n\t\t\treturn o != null && variable == o.variable && object.Equals(method, o.method) && this.IsDeconstructCall == o.IsDeconstructCall && this.IsDeconstructTuple == o.IsDeconstructTuple && this.CheckType == o.CheckType && this.CheckNotNull == o.CheckNotNull && this.testedOperand.PerformMatch(o.testedOperand, ref match) && Patterns.ListMatch.DoMatch(this.SubPatterns, o.SubPatterns, ref match);\n\t\t}\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tDebugAssert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function!));\n\t\t\tDebugAssert(phase <= ILPhase.InILReader || variable.Function!.Variables[variable.IndexInFunction] == variable);\n\t\t\tAdditionalInvariants();\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Push a typed reference of type class onto the stack.</summary>\n\tpublic sealed partial class MakeRefAny : UnaryInstruction\n\t{\n\t\tpublic MakeRefAny(ILInstruction argument, IType type) : base(OpCode.MakeRefAny, argument)\n\t\t{\n\t\t\tthis.type = type;\n\t\t}\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.O; } }\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tArgument.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitMakeRefAny(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitMakeRefAny(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitMakeRefAny(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as MakeRefAny;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Push the type token stored in a typed reference.</summary>\n\tpublic sealed partial class RefAnyType : UnaryInstruction\n\t{\n\t\tpublic RefAnyType(ILInstruction argument) : base(OpCode.RefAnyType, argument)\n\t\t{\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.O; } }\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitRefAnyType(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitRefAnyType(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitRefAnyType(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as RefAnyType;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Push the address stored in a typed reference.</summary>\n\tpublic sealed partial class RefAnyValue : UnaryInstruction\n\t{\n\t\tpublic RefAnyValue(ILInstruction argument, IType type) : base(OpCode.RefAnyValue, argument)\n\t\t{\n\t\t\tthis.type = type;\n\t\t}\n\t\tIType type;\n\t\t/// <summary>Returns the type operand.</summary>\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t\tset { type = value; InvalidateFlags(); }\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.Ref; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn base.ComputeFlags() | InstructionFlags.MayThrow;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn base.DirectFlags | InstructionFlags.MayThrow;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write(' ');\n\t\t\ttype.WriteTo(output);\n\t\t\toutput.Write('(');\n\t\t\tArgument.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitRefAnyValue(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitRefAnyValue(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitRefAnyValue(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as RefAnyValue;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match) && type.Equals(o.type);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Yield an element from an iterator.</summary>\n\tpublic sealed partial class YieldReturn : ILInstruction\n\t{\n\t\tpublic YieldReturn(ILInstruction value) : base(OpCode.YieldReturn)\n\t\t{\n\t\t\tthis.Value = value;\n\t\t}\n\t\tpublic static readonly SlotInfo ValueSlot = new SlotInfo(\"Value\", canInlineInto: true);\n\t\tILInstruction value = null!;\n\t\tpublic ILInstruction Value {\n\t\t\tget { return this.value; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.value, value, 0);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.value;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Value = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn ValueSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (YieldReturn)ShallowClone();\n\t\t\tclone.Value = this.value.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tpublic override StackType ResultType { get { return StackType.Void; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn InstructionFlags.MayBranch | InstructionFlags.SideEffect | value.Flags;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.MayBranch | InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write('(');\n\t\t\tthis.value.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitYieldReturn(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitYieldReturn(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitYieldReturn(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as YieldReturn;\n\t\t\treturn o != null && this.value.PerformMatch(o.value, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>C# await operator.</summary>\n\tpublic sealed partial class Await : ILInstruction\n\t{\n\t\tpublic Await(ILInstruction value) : base(OpCode.Await)\n\t\t{\n\t\t\tthis.Value = value;\n\t\t}\n\t\tpublic static readonly SlotInfo ValueSlot = new SlotInfo(\"Value\", canInlineInto: true);\n\t\tILInstruction value = null!;\n\t\tpublic ILInstruction Value {\n\t\t\tget { return this.value; }\n\t\t\tset {\n\t\t\t\tValidateChild(value);\n\t\t\t\tSetChildInstruction(ref this.value, value, 0);\n\t\t\t}\n\t\t}\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn this.value;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tthis.Value = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn ValueSlot;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (Await)ShallowClone();\n\t\t\tclone.Value = this.value.Clone();\n\t\t\treturn clone;\n\t\t}\n\t\tpublic override StackType ResultType { get { return GetResultMethod?.ReturnType.GetStackType() ?? StackType.Unknown; } }\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn InstructionFlags.SideEffect | value.Flags;\n\t\t}\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn InstructionFlags.SideEffect;\n\t\t\t}\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write('(');\n\t\t\tthis.value.WriteTo(output, options);\n\t\t\toutput.Write(')');\n\t\t}\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitAwait(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitAwait(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitAwait(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as Await;\n\t\t\treturn o != null && this.value.PerformMatch(o.value, ref match);\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Deconstruction statement</summary>\n\tpublic sealed partial class DeconstructInstruction : ILInstruction\n\t{\n\t\tpublic override StackType ResultType { get { return StackType.Void; } }\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDeconstructInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDeconstructInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitDeconstructInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as DeconstructInstruction;\n\t\t\treturn o != null;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>Represents a deconstructed value</summary>\n\tpublic sealed partial class DeconstructResultInstruction : UnaryInstruction\n\t{\n\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.VisitDeconstructResultInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.VisitDeconstructResultInstruction(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.VisitDeconstructResultInstruction(this, context);\n\t\t}\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as DeconstructResultInstruction;\n\t\t\treturn o != null && this.Argument.PerformMatch(o.Argument, ref match);\n\t\t}\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n\t\t\tAdditionalInvariants();\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.IL.Patterns\n{\n\t/// <summary>Matches any node</summary>\n\tpublic sealed partial class AnyNode : PatternInstruction\n\t{\n\t\tprotected sealed override int GetChildCount()\n\t\t{\n\t\t\treturn 0;\n\t\t}\n\t\tprotected sealed override ILInstruction GetChild(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override void SetChild(int index, ILInstruction value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tprotected sealed override SlotInfo GetChildSlot(int index)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t}\n\t\tpublic sealed override ILInstruction Clone()\n\t\t{\n\t\t\tvar clone = (AnyNode)ShallowClone();\n\t\t\treturn clone;\n\t\t}\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n\t\t{\n\t\t\tWriteILRange(output, options);\n\t\t\toutput.Write(OpCode);\n\t\t\toutput.Write('(');\n\t\t\toutput.Write(')');\n\t\t}\n\t}\n}\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// Base class for visitor pattern.\n\t/// </summary>\n\tpublic abstract class ILVisitor\n\t{\n\t\t/// <summary>Called by Visit*() methods that were not overridden</summary>\n\t\tprotected abstract void Default(ILInstruction inst);\n\n\t\tprotected internal virtual void VisitInvalidBranch(InvalidBranch inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitInvalidExpression(InvalidExpression inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitNop(Nop inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitILFunction(ILFunction function)\n\t\t{\n\t\t\tDefault(function);\n\t\t}\n\t\tprotected internal virtual void VisitBlockContainer(BlockContainer container)\n\t\t{\n\t\t\tDefault(container);\n\t\t}\n\t\tprotected internal virtual void VisitBlock(Block block)\n\t\t{\n\t\t\tDefault(block);\n\t\t}\n\t\tprotected internal virtual void VisitPinnedRegion(PinnedRegion inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitBinaryNumericInstruction(BinaryNumericInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitNumericCompoundAssign(NumericCompoundAssign inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitUserDefinedCompoundAssign(UserDefinedCompoundAssign inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitDynamicCompoundAssign(DynamicCompoundAssign inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitBitNot(BitNot inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitArglist(Arglist inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitBranch(Branch inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLeave(Leave inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitIfInstruction(IfInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitNullCoalescingInstruction(NullCoalescingInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitSwitchInstruction(SwitchInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitSwitchSection(SwitchSection inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitTryCatch(TryCatch inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitTryCatchHandler(TryCatchHandler inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitTryFinally(TryFinally inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitTryFault(TryFault inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLockInstruction(LockInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitUsingInstruction(UsingInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitDebugBreak(DebugBreak inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitComp(Comp inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitCall(Call inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitCallVirt(CallVirt inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitCallIndirect(CallIndirect inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitCkfinite(Ckfinite inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitConv(Conv inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdLoc(LdLoc inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdLoca(LdLoca inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitStLoc(StLoc inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitAddressOf(AddressOf inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitThreeValuedBoolAnd(ThreeValuedBoolAnd inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitThreeValuedBoolOr(ThreeValuedBoolOr inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitNullableUnwrap(NullableUnwrap inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitNullableRewrap(NullableRewrap inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdStr(LdStr inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdStrUtf8(LdStrUtf8 inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdcI4(LdcI4 inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdcI8(LdcI8 inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdcF4(LdcF4 inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdcF8(LdcF8 inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdcDecimal(LdcDecimal inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdNull(LdNull inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdFtn(LdFtn inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdVirtFtn(LdVirtFtn inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdVirtDelegate(LdVirtDelegate inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdTypeToken(LdTypeToken inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdMemberToken(LdMemberToken inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLocAlloc(LocAlloc inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLocAllocSpan(LocAllocSpan inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitCpblk(Cpblk inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitInitblk(Initblk inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdFlda(LdFlda inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdsFlda(LdsFlda inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitCastClass(CastClass inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitIsInst(IsInst inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdObj(LdObj inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdObjIfRef(LdObjIfRef inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitStObj(StObj inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitBox(Box inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitUnbox(Unbox inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitUnboxAny(UnboxAny inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitNewObj(NewObj inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitNewArr(NewArr inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitDefaultValue(DefaultValue inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitThrow(Throw inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitRethrow(Rethrow inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitSizeOf(SizeOf inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdLen(LdLen inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdElema(LdElema inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitLdElemaInlineArray(LdElemaInlineArray inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitGetPinnableReference(GetPinnableReference inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitStringToInt(StringToInt inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitExpressionTreeCast(ExpressionTreeCast inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitUserDefinedLogicOperator(UserDefinedLogicOperator inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitDynamicLogicOperatorInstruction(DynamicLogicOperatorInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitDynamicBinaryOperatorInstruction(DynamicBinaryOperatorInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitDynamicUnaryOperatorInstruction(DynamicUnaryOperatorInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitDynamicConvertInstruction(DynamicConvertInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitDynamicGetMemberInstruction(DynamicGetMemberInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitDynamicSetMemberInstruction(DynamicSetMemberInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitDynamicGetIndexInstruction(DynamicGetIndexInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitDynamicSetIndexInstruction(DynamicSetIndexInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitDynamicInvokeMemberInstruction(DynamicInvokeMemberInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitDynamicInvokeConstructorInstruction(DynamicInvokeConstructorInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitDynamicInvokeInstruction(DynamicInvokeInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitDynamicIsEventInstruction(DynamicIsEventInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitMatchInstruction(MatchInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitMakeRefAny(MakeRefAny inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitRefAnyType(RefAnyType inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitRefAnyValue(RefAnyValue inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitYieldReturn(YieldReturn inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitAwait(Await inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitDeconstructInstruction(DeconstructInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t\tprotected internal virtual void VisitDeconstructResultInstruction(DeconstructResultInstruction inst)\n\t\t{\n\t\t\tDefault(inst);\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Base class for visitor pattern.\n\t/// </summary>\n\tpublic abstract class ILVisitor<T>\n\t{\n\t\t/// <summary>Called by Visit*() methods that were not overridden</summary>\n\t\tprotected abstract T Default(ILInstruction inst);\n\n\t\tprotected internal virtual T VisitInvalidBranch(InvalidBranch inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitInvalidExpression(InvalidExpression inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitNop(Nop inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitILFunction(ILFunction function)\n\t\t{\n\t\t\treturn Default(function);\n\t\t}\n\t\tprotected internal virtual T VisitBlockContainer(BlockContainer container)\n\t\t{\n\t\t\treturn Default(container);\n\t\t}\n\t\tprotected internal virtual T VisitBlock(Block block)\n\t\t{\n\t\t\treturn Default(block);\n\t\t}\n\t\tprotected internal virtual T VisitPinnedRegion(PinnedRegion inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitBinaryNumericInstruction(BinaryNumericInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitNumericCompoundAssign(NumericCompoundAssign inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitUserDefinedCompoundAssign(UserDefinedCompoundAssign inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicCompoundAssign(DynamicCompoundAssign inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitBitNot(BitNot inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitArglist(Arglist inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitBranch(Branch inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLeave(Leave inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitIfInstruction(IfInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitNullCoalescingInstruction(NullCoalescingInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitSwitchInstruction(SwitchInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitSwitchSection(SwitchSection inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitTryCatch(TryCatch inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitTryCatchHandler(TryCatchHandler inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitTryFinally(TryFinally inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitTryFault(TryFault inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLockInstruction(LockInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitUsingInstruction(UsingInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitDebugBreak(DebugBreak inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitComp(Comp inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitCall(Call inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitCallVirt(CallVirt inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitCallIndirect(CallIndirect inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitCkfinite(Ckfinite inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitConv(Conv inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdLoc(LdLoc inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdLoca(LdLoca inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitStLoc(StLoc inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitAddressOf(AddressOf inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitThreeValuedBoolAnd(ThreeValuedBoolAnd inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitThreeValuedBoolOr(ThreeValuedBoolOr inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitNullableUnwrap(NullableUnwrap inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitNullableRewrap(NullableRewrap inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdStr(LdStr inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdStrUtf8(LdStrUtf8 inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdcI4(LdcI4 inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdcI8(LdcI8 inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdcF4(LdcF4 inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdcF8(LdcF8 inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdcDecimal(LdcDecimal inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdNull(LdNull inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdFtn(LdFtn inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdVirtFtn(LdVirtFtn inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdVirtDelegate(LdVirtDelegate inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdTypeToken(LdTypeToken inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdMemberToken(LdMemberToken inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLocAlloc(LocAlloc inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLocAllocSpan(LocAllocSpan inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitCpblk(Cpblk inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitInitblk(Initblk inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdFlda(LdFlda inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdsFlda(LdsFlda inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitCastClass(CastClass inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitIsInst(IsInst inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdObj(LdObj inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdObjIfRef(LdObjIfRef inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitStObj(StObj inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitBox(Box inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitUnbox(Unbox inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitUnboxAny(UnboxAny inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitNewObj(NewObj inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitNewArr(NewArr inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitDefaultValue(DefaultValue inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitThrow(Throw inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitRethrow(Rethrow inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitSizeOf(SizeOf inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdLen(LdLen inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdElema(LdElema inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitLdElemaInlineArray(LdElemaInlineArray inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitGetPinnableReference(GetPinnableReference inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitStringToInt(StringToInt inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitExpressionTreeCast(ExpressionTreeCast inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitUserDefinedLogicOperator(UserDefinedLogicOperator inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicLogicOperatorInstruction(DynamicLogicOperatorInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicBinaryOperatorInstruction(DynamicBinaryOperatorInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicUnaryOperatorInstruction(DynamicUnaryOperatorInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicConvertInstruction(DynamicConvertInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicGetMemberInstruction(DynamicGetMemberInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicSetMemberInstruction(DynamicSetMemberInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicGetIndexInstruction(DynamicGetIndexInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicSetIndexInstruction(DynamicSetIndexInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicInvokeMemberInstruction(DynamicInvokeMemberInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicInvokeConstructorInstruction(DynamicInvokeConstructorInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicInvokeInstruction(DynamicInvokeInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicIsEventInstruction(DynamicIsEventInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitMatchInstruction(MatchInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitMakeRefAny(MakeRefAny inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitRefAnyType(RefAnyType inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitRefAnyValue(RefAnyValue inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitYieldReturn(YieldReturn inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitAwait(Await inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitDeconstructInstruction(DeconstructInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t\tprotected internal virtual T VisitDeconstructResultInstruction(DeconstructResultInstruction inst)\n\t\t{\n\t\t\treturn Default(inst);\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Base class for visitor pattern.\n\t/// </summary>\n\tpublic abstract class ILVisitor<C, T>\n\t{\n\t\t/// <summary>Called by Visit*() methods that were not overridden</summary>\n\t\tprotected abstract T Default(ILInstruction inst, C context);\n\n\t\tprotected internal virtual T VisitInvalidBranch(InvalidBranch inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitInvalidExpression(InvalidExpression inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitNop(Nop inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitILFunction(ILFunction function, C context)\n\t\t{\n\t\t\treturn Default(function, context);\n\t\t}\n\t\tprotected internal virtual T VisitBlockContainer(BlockContainer container, C context)\n\t\t{\n\t\t\treturn Default(container, context);\n\t\t}\n\t\tprotected internal virtual T VisitBlock(Block block, C context)\n\t\t{\n\t\t\treturn Default(block, context);\n\t\t}\n\t\tprotected internal virtual T VisitPinnedRegion(PinnedRegion inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitBinaryNumericInstruction(BinaryNumericInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitNumericCompoundAssign(NumericCompoundAssign inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitUserDefinedCompoundAssign(UserDefinedCompoundAssign inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicCompoundAssign(DynamicCompoundAssign inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitBitNot(BitNot inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitArglist(Arglist inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitBranch(Branch inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLeave(Leave inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitIfInstruction(IfInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitNullCoalescingInstruction(NullCoalescingInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitSwitchInstruction(SwitchInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitSwitchSection(SwitchSection inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitTryCatch(TryCatch inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitTryCatchHandler(TryCatchHandler inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitTryFinally(TryFinally inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitTryFault(TryFault inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLockInstruction(LockInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitUsingInstruction(UsingInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitDebugBreak(DebugBreak inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitComp(Comp inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitCall(Call inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitCallVirt(CallVirt inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitCallIndirect(CallIndirect inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitCkfinite(Ckfinite inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitConv(Conv inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdLoc(LdLoc inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdLoca(LdLoca inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitStLoc(StLoc inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitAddressOf(AddressOf inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitThreeValuedBoolAnd(ThreeValuedBoolAnd inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitThreeValuedBoolOr(ThreeValuedBoolOr inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitNullableUnwrap(NullableUnwrap inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitNullableRewrap(NullableRewrap inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdStr(LdStr inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdStrUtf8(LdStrUtf8 inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdcI4(LdcI4 inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdcI8(LdcI8 inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdcF4(LdcF4 inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdcF8(LdcF8 inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdcDecimal(LdcDecimal inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdNull(LdNull inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdFtn(LdFtn inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdVirtFtn(LdVirtFtn inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdVirtDelegate(LdVirtDelegate inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdTypeToken(LdTypeToken inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdMemberToken(LdMemberToken inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLocAlloc(LocAlloc inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLocAllocSpan(LocAllocSpan inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitCpblk(Cpblk inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitInitblk(Initblk inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdFlda(LdFlda inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdsFlda(LdsFlda inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitCastClass(CastClass inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitIsInst(IsInst inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdObj(LdObj inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdObjIfRef(LdObjIfRef inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitStObj(StObj inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitBox(Box inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitUnbox(Unbox inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitUnboxAny(UnboxAny inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitNewObj(NewObj inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitNewArr(NewArr inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitDefaultValue(DefaultValue inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitThrow(Throw inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitRethrow(Rethrow inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitSizeOf(SizeOf inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdLen(LdLen inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdElema(LdElema inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitLdElemaInlineArray(LdElemaInlineArray inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitGetPinnableReference(GetPinnableReference inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitStringToInt(StringToInt inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitExpressionTreeCast(ExpressionTreeCast inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitUserDefinedLogicOperator(UserDefinedLogicOperator inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicLogicOperatorInstruction(DynamicLogicOperatorInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicBinaryOperatorInstruction(DynamicBinaryOperatorInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicUnaryOperatorInstruction(DynamicUnaryOperatorInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicConvertInstruction(DynamicConvertInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicGetMemberInstruction(DynamicGetMemberInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicSetMemberInstruction(DynamicSetMemberInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicGetIndexInstruction(DynamicGetIndexInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicSetIndexInstruction(DynamicSetIndexInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicInvokeMemberInstruction(DynamicInvokeMemberInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicInvokeConstructorInstruction(DynamicInvokeConstructorInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicInvokeInstruction(DynamicInvokeInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitDynamicIsEventInstruction(DynamicIsEventInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitMatchInstruction(MatchInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitMakeRefAny(MakeRefAny inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitRefAnyType(RefAnyType inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitRefAnyValue(RefAnyValue inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitYieldReturn(YieldReturn inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitAwait(Await inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitDeconstructInstruction(DeconstructInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t\tprotected internal virtual T VisitDeconstructResultInstruction(DeconstructResultInstruction inst, C context)\n\t\t{\n\t\t\treturn Default(inst, context);\n\t\t}\n\t}\n\n\tpartial class InstructionOutputExtensions\n\t{\n\t\tstatic readonly string[] originalOpCodeNames = {\n\t\t\t\"invalid.branch\",\n\t\t\t\"invalid.expr\",\n\t\t\t\"nop\",\n\t\t\t\"ILFunction\",\n\t\t\t\"BlockContainer\",\n\t\t\t\"Block\",\n\t\t\t\"PinnedRegion\",\n\t\t\t\"binary\",\n\t\t\t\"numeric.compound\",\n\t\t\t\"user.compound\",\n\t\t\t\"dynamic.compound\",\n\t\t\t\"bit.not\",\n\t\t\t\"arglist\",\n\t\t\t\"br\",\n\t\t\t\"leave\",\n\t\t\t\"if\",\n\t\t\t\"if.notnull\",\n\t\t\t\"switch\",\n\t\t\t\"switch.section\",\n\t\t\t\"try.catch\",\n\t\t\t\"try.catch.handler\",\n\t\t\t\"try.finally\",\n\t\t\t\"try.fault\",\n\t\t\t\"lock\",\n\t\t\t\"using\",\n\t\t\t\"debug.break\",\n\t\t\t\"comp\",\n\t\t\t\"call\",\n\t\t\t\"callvirt\",\n\t\t\t\"calli\",\n\t\t\t\"ckfinite\",\n\t\t\t\"conv\",\n\t\t\t\"ldloc\",\n\t\t\t\"ldloca\",\n\t\t\t\"stloc\",\n\t\t\t\"addressof\",\n\t\t\t\"3vl.bool.and\",\n\t\t\t\"3vl.bool.or\",\n\t\t\t\"nullable.unwrap\",\n\t\t\t\"nullable.rewrap\",\n\t\t\t\"ldstr\",\n\t\t\t\"ldstr.utf8\",\n\t\t\t\"ldc.i4\",\n\t\t\t\"ldc.i8\",\n\t\t\t\"ldc.f4\",\n\t\t\t\"ldc.f8\",\n\t\t\t\"ldc.decimal\",\n\t\t\t\"ldnull\",\n\t\t\t\"ldftn\",\n\t\t\t\"ldvirtftn\",\n\t\t\t\"ldvirtdelegate\",\n\t\t\t\"ldtypetoken\",\n\t\t\t\"ldmembertoken\",\n\t\t\t\"localloc\",\n\t\t\t\"localloc.span\",\n\t\t\t\"cpblk\",\n\t\t\t\"initblk\",\n\t\t\t\"ldflda\",\n\t\t\t\"ldsflda\",\n\t\t\t\"castclass\",\n\t\t\t\"isinst\",\n\t\t\t\"ldobj\",\n\t\t\t\"ldobj.if.ref\",\n\t\t\t\"stobj\",\n\t\t\t\"box\",\n\t\t\t\"unbox\",\n\t\t\t\"unbox.any\",\n\t\t\t\"newobj\",\n\t\t\t\"newarr\",\n\t\t\t\"default.value\",\n\t\t\t\"throw\",\n\t\t\t\"rethrow\",\n\t\t\t\"sizeof\",\n\t\t\t\"ldlen\",\n\t\t\t\"ldelema\",\n\t\t\t\"ldelema.inlinearray\",\n\t\t\t\"get.pinnable.reference\",\n\t\t\t\"string.to.int\",\n\t\t\t\"expression.tree.cast\",\n\t\t\t\"user.logic.operator\",\n\t\t\t\"dynamic.logic.operator\",\n\t\t\t\"dynamic.binary.operator\",\n\t\t\t\"dynamic.unary.operator\",\n\t\t\t\"dynamic.convert\",\n\t\t\t\"dynamic.getmember\",\n\t\t\t\"dynamic.setmember\",\n\t\t\t\"dynamic.getindex\",\n\t\t\t\"dynamic.setindex\",\n\t\t\t\"dynamic.invokemember\",\n\t\t\t\"dynamic.invokeconstructor\",\n\t\t\t\"dynamic.invoke\",\n\t\t\t\"dynamic.isevent\",\n\t\t\t\"match\",\n\t\t\t\"mkrefany\",\n\t\t\t\"refanytype\",\n\t\t\t\"refanyval\",\n\t\t\t\"yield.return\",\n\t\t\t\"await\",\n\t\t\t\"deconstruct\",\n\t\t\t\"deconstruct.result\",\n\t\t\t\"AnyNode\",\n\t\t};\n\t}\n\n\tpartial class ILInstruction\n\t{\n\t\tpublic bool MatchInvalidBranch()\n\t\t{\n\t\t\tvar inst = this as InvalidBranch;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchInvalidExpression()\n\t\t{\n\t\t\tvar inst = this as InvalidExpression;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchNop()\n\t\t{\n\t\t\tvar inst = this as Nop;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchPinnedRegion([NotNullWhen(true)] out ILVariable? variable, [NotNullWhen(true)] out ILInstruction? init, [NotNullWhen(true)] out ILInstruction? body)\n\t\t{\n\t\t\tvar inst = this as PinnedRegion;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tvariable = inst.Variable;\n\t\t\t\tinit = inst.Init;\n\t\t\t\tbody = inst.Body;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvariable = default(ILVariable);\n\t\t\tinit = default(ILInstruction);\n\t\t\tbody = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchArglist()\n\t\t{\n\t\t\tvar inst = this as Arglist;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchTryCatchHandler([NotNullWhen(true)] out ILInstruction? filter, [NotNullWhen(true)] out ILInstruction? body, [NotNullWhen(true)] out ILVariable? variable)\n\t\t{\n\t\t\tvar inst = this as TryCatchHandler;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tfilter = inst.Filter;\n\t\t\t\tbody = inst.Body;\n\t\t\t\tvariable = inst.Variable;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tfilter = default(ILInstruction);\n\t\t\tbody = default(ILInstruction);\n\t\t\tvariable = default(ILVariable);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLockInstruction([NotNullWhen(true)] out ILInstruction? onExpression, [NotNullWhen(true)] out ILInstruction? body)\n\t\t{\n\t\t\tvar inst = this as LockInstruction;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tonExpression = inst.OnExpression;\n\t\t\t\tbody = inst.Body;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tonExpression = default(ILInstruction);\n\t\t\tbody = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchUsingInstruction([NotNullWhen(true)] out ILVariable? variable, [NotNullWhen(true)] out ILInstruction? resourceExpression, [NotNullWhen(true)] out ILInstruction? body)\n\t\t{\n\t\t\tvar inst = this as UsingInstruction;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tvariable = inst.Variable;\n\t\t\t\tresourceExpression = inst.ResourceExpression;\n\t\t\t\tbody = inst.Body;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvariable = default(ILVariable);\n\t\t\tresourceExpression = default(ILInstruction);\n\t\t\tbody = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchDebugBreak()\n\t\t{\n\t\t\tvar inst = this as DebugBreak;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchCkfinite([NotNullWhen(true)] out ILInstruction? argument)\n\t\t{\n\t\t\tvar inst = this as Ckfinite;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\targument = inst.Argument;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\targument = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdLoc([NotNullWhen(true)] out ILVariable? variable)\n\t\t{\n\t\t\tvar inst = this as LdLoc;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tvariable = inst.Variable;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvariable = default(ILVariable);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdLoca([NotNullWhen(true)] out ILVariable? variable)\n\t\t{\n\t\t\tvar inst = this as LdLoca;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tvariable = inst.Variable;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvariable = default(ILVariable);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchStLoc([NotNullWhen(true)] out ILVariable? variable, [NotNullWhen(true)] out ILInstruction? value)\n\t\t{\n\t\t\tvar inst = this as StLoc;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tvariable = inst.Variable;\n\t\t\t\tvalue = inst.Value;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvariable = default(ILVariable);\n\t\t\tvalue = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchAddressOf([NotNullWhen(true)] out ILInstruction? value, [NotNullWhen(true)] out IType? type)\n\t\t{\n\t\t\tvar inst = this as AddressOf;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tvalue = inst.Value;\n\t\t\t\ttype = inst.Type;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvalue = default(ILInstruction);\n\t\t\ttype = default(IType);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchThreeValuedBoolAnd([NotNullWhen(true)] out ILInstruction? left, [NotNullWhen(true)] out ILInstruction? right)\n\t\t{\n\t\t\tvar inst = this as ThreeValuedBoolAnd;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tleft = inst.Left;\n\t\t\t\tright = inst.Right;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tleft = default(ILInstruction);\n\t\t\tright = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchThreeValuedBoolOr([NotNullWhen(true)] out ILInstruction? left, [NotNullWhen(true)] out ILInstruction? right)\n\t\t{\n\t\t\tvar inst = this as ThreeValuedBoolOr;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tleft = inst.Left;\n\t\t\t\tright = inst.Right;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tleft = default(ILInstruction);\n\t\t\tright = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchNullableRewrap([NotNullWhen(true)] out ILInstruction? argument)\n\t\t{\n\t\t\tvar inst = this as NullableRewrap;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\targument = inst.Argument;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\targument = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdStr([NotNullWhen(true)] out string? value)\n\t\t{\n\t\t\tvar inst = this as LdStr;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tvalue = inst.Value;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvalue = default(string);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdStrUtf8([NotNullWhen(true)] out string? value)\n\t\t{\n\t\t\tvar inst = this as LdStrUtf8;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tvalue = inst.Value;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvalue = default(string);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdcI4(out int value)\n\t\t{\n\t\t\tvar inst = this as LdcI4;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tvalue = inst.Value;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvalue = default(int);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdcI8(out long value)\n\t\t{\n\t\t\tvar inst = this as LdcI8;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tvalue = inst.Value;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvalue = default(long);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdcF4(out float value)\n\t\t{\n\t\t\tvar inst = this as LdcF4;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tvalue = inst.Value;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvalue = default(float);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdcF8(out double value)\n\t\t{\n\t\t\tvar inst = this as LdcF8;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tvalue = inst.Value;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvalue = default(double);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdcDecimal(out decimal value)\n\t\t{\n\t\t\tvar inst = this as LdcDecimal;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tvalue = inst.Value;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvalue = default(decimal);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdNull()\n\t\t{\n\t\t\tvar inst = this as LdNull;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdFtn([NotNullWhen(true)] out IMethod? method)\n\t\t{\n\t\t\tvar inst = this as LdFtn;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tmethod = inst.Method;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tmethod = default(IMethod);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdVirtFtn([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IMethod? method)\n\t\t{\n\t\t\tvar inst = this as LdVirtFtn;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\targument = inst.Argument;\n\t\t\t\tmethod = inst.Method;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\targument = default(ILInstruction);\n\t\t\tmethod = default(IMethod);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdVirtDelegate([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IType? type, [NotNullWhen(true)] out IMethod? method)\n\t\t{\n\t\t\tvar inst = this as LdVirtDelegate;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\targument = inst.Argument;\n\t\t\t\ttype = inst.Type;\n\t\t\t\tmethod = inst.Method;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\targument = default(ILInstruction);\n\t\t\ttype = default(IType);\n\t\t\tmethod = default(IMethod);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdTypeToken([NotNullWhen(true)] out IType? type)\n\t\t{\n\t\t\tvar inst = this as LdTypeToken;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\ttype = inst.Type;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ttype = default(IType);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdMemberToken([NotNullWhen(true)] out IMember? member)\n\t\t{\n\t\t\tvar inst = this as LdMemberToken;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tmember = inst.Member;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tmember = default(IMember);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLocAlloc([NotNullWhen(true)] out ILInstruction? argument)\n\t\t{\n\t\t\tvar inst = this as LocAlloc;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\targument = inst.Argument;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\targument = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLocAllocSpan([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IType? type)\n\t\t{\n\t\t\tvar inst = this as LocAllocSpan;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\targument = inst.Argument;\n\t\t\t\ttype = inst.Type;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\targument = default(ILInstruction);\n\t\t\ttype = default(IType);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchCpblk([NotNullWhen(true)] out ILInstruction? destAddress, [NotNullWhen(true)] out ILInstruction? sourceAddress, [NotNullWhen(true)] out ILInstruction? size)\n\t\t{\n\t\t\tvar inst = this as Cpblk;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tdestAddress = inst.DestAddress;\n\t\t\t\tsourceAddress = inst.SourceAddress;\n\t\t\t\tsize = inst.Size;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tdestAddress = default(ILInstruction);\n\t\t\tsourceAddress = default(ILInstruction);\n\t\t\tsize = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchInitblk([NotNullWhen(true)] out ILInstruction? address, [NotNullWhen(true)] out ILInstruction? value, [NotNullWhen(true)] out ILInstruction? size)\n\t\t{\n\t\t\tvar inst = this as Initblk;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\taddress = inst.Address;\n\t\t\t\tvalue = inst.Value;\n\t\t\t\tsize = inst.Size;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\taddress = default(ILInstruction);\n\t\t\tvalue = default(ILInstruction);\n\t\t\tsize = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdFlda([NotNullWhen(true)] out ILInstruction? target, [NotNullWhen(true)] out IField? @field)\n\t\t{\n\t\t\tvar inst = this as LdFlda;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\ttarget = inst.Target;\n\t\t\t\t@field = inst.Field;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ttarget = default(ILInstruction);\n\t\t\t@field = default(IField);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdsFlda([NotNullWhen(true)] out IField? @field)\n\t\t{\n\t\t\tvar inst = this as LdsFlda;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\t@field = inst.Field;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\t@field = default(IField);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchCastClass([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IType? type)\n\t\t{\n\t\t\tvar inst = this as CastClass;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\targument = inst.Argument;\n\t\t\t\ttype = inst.Type;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\targument = default(ILInstruction);\n\t\t\ttype = default(IType);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchIsInst([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IType? type)\n\t\t{\n\t\t\tvar inst = this as IsInst;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\targument = inst.Argument;\n\t\t\t\ttype = inst.Type;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\targument = default(ILInstruction);\n\t\t\ttype = default(IType);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdObj([NotNullWhen(true)] out ILInstruction? target, [NotNullWhen(true)] out IType? type)\n\t\t{\n\t\t\tvar inst = this as LdObj;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\ttarget = inst.Target;\n\t\t\t\ttype = inst.Type;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ttarget = default(ILInstruction);\n\t\t\ttype = default(IType);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdObjIfRef([NotNullWhen(true)] out ILInstruction? target, [NotNullWhen(true)] out IType? type)\n\t\t{\n\t\t\tvar inst = this as LdObjIfRef;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\ttarget = inst.Target;\n\t\t\t\ttype = inst.Type;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ttarget = default(ILInstruction);\n\t\t\ttype = default(IType);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchStObj([NotNullWhen(true)] out ILInstruction? target, [NotNullWhen(true)] out ILInstruction? value, [NotNullWhen(true)] out IType? type)\n\t\t{\n\t\t\tvar inst = this as StObj;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\ttarget = inst.Target;\n\t\t\t\tvalue = inst.Value;\n\t\t\t\ttype = inst.Type;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ttarget = default(ILInstruction);\n\t\t\tvalue = default(ILInstruction);\n\t\t\ttype = default(IType);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchBox([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IType? type)\n\t\t{\n\t\t\tvar inst = this as Box;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\targument = inst.Argument;\n\t\t\t\ttype = inst.Type;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\targument = default(ILInstruction);\n\t\t\ttype = default(IType);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchUnbox([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IType? type)\n\t\t{\n\t\t\tvar inst = this as Unbox;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\targument = inst.Argument;\n\t\t\t\ttype = inst.Type;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\targument = default(ILInstruction);\n\t\t\ttype = default(IType);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchUnboxAny([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IType? type)\n\t\t{\n\t\t\tvar inst = this as UnboxAny;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\targument = inst.Argument;\n\t\t\t\ttype = inst.Type;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\targument = default(ILInstruction);\n\t\t\ttype = default(IType);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchNewArr([NotNullWhen(true)] out IType? type)\n\t\t{\n\t\t\tvar inst = this as NewArr;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\ttype = inst.Type;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ttype = default(IType);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchDefaultValue([NotNullWhen(true)] out IType? type)\n\t\t{\n\t\t\tvar inst = this as DefaultValue;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\ttype = inst.Type;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ttype = default(IType);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchThrow([NotNullWhen(true)] out ILInstruction? argument)\n\t\t{\n\t\t\tvar inst = this as Throw;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\targument = inst.Argument;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\targument = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchRethrow()\n\t\t{\n\t\t\tvar inst = this as Rethrow;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchSizeOf([NotNullWhen(true)] out IType? type)\n\t\t{\n\t\t\tvar inst = this as SizeOf;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\ttype = inst.Type;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ttype = default(IType);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdElema([NotNullWhen(true)] out IType? type, [NotNullWhen(true)] out ILInstruction? array)\n\t\t{\n\t\t\tvar inst = this as LdElema;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\ttype = inst.Type;\n\t\t\t\tarray = inst.Array;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ttype = default(IType);\n\t\t\tarray = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchLdElemaInlineArray([NotNullWhen(true)] out IType? type, [NotNullWhen(true)] out ILInstruction? array)\n\t\t{\n\t\t\tvar inst = this as LdElemaInlineArray;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\ttype = inst.Type;\n\t\t\t\tarray = inst.Array;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ttype = default(IType);\n\t\t\tarray = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchGetPinnableReference([NotNullWhen(true)] out ILInstruction? argument, out IMethod? method)\n\t\t{\n\t\t\tvar inst = this as GetPinnableReference;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\targument = inst.Argument;\n\t\t\t\tmethod = inst.Method;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\targument = default(ILInstruction);\n\t\t\tmethod = default(IMethod?);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchUserDefinedLogicOperator([NotNullWhen(true)] out IMethod? method, [NotNullWhen(true)] out ILInstruction? left, [NotNullWhen(true)] out ILInstruction? right)\n\t\t{\n\t\t\tvar inst = this as UserDefinedLogicOperator;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tmethod = inst.Method;\n\t\t\t\tleft = inst.Left;\n\t\t\t\tright = inst.Right;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tmethod = default(IMethod);\n\t\t\tleft = default(ILInstruction);\n\t\t\tright = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchMatchInstruction([NotNullWhen(true)] out ILVariable? variable, out IMethod? method, [NotNullWhen(true)] out ILInstruction? testedOperand)\n\t\t{\n\t\t\tvar inst = this as MatchInstruction;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tvariable = inst.Variable;\n\t\t\t\tmethod = inst.Method;\n\t\t\t\ttestedOperand = inst.TestedOperand;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvariable = default(ILVariable);\n\t\t\tmethod = default(IMethod?);\n\t\t\ttestedOperand = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchMakeRefAny([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IType? type)\n\t\t{\n\t\t\tvar inst = this as MakeRefAny;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\targument = inst.Argument;\n\t\t\t\ttype = inst.Type;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\targument = default(ILInstruction);\n\t\t\ttype = default(IType);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchRefAnyType([NotNullWhen(true)] out ILInstruction? argument)\n\t\t{\n\t\t\tvar inst = this as RefAnyType;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\targument = inst.Argument;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\targument = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchRefAnyValue([NotNullWhen(true)] out ILInstruction? argument, [NotNullWhen(true)] out IType? type)\n\t\t{\n\t\t\tvar inst = this as RefAnyValue;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\targument = inst.Argument;\n\t\t\t\ttype = inst.Type;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\targument = default(ILInstruction);\n\t\t\ttype = default(IType);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchYieldReturn([NotNullWhen(true)] out ILInstruction? value)\n\t\t{\n\t\t\tvar inst = this as YieldReturn;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tvalue = inst.Value;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvalue = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t\tpublic bool MatchAwait([NotNullWhen(true)] out ILInstruction? value)\n\t\t{\n\t\t\tvar inst = this as Await;\n\t\t\tif (inst != null)\n\t\t\t{\n\t\t\t\tvalue = inst.Value;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvalue = default(ILInstruction);\n\t\t\treturn false;\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Instructions.tt",
    "content": "// Copyright (c) 2014-2020 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\n<#@ template debug=\"false\" hostspecific=\"false\" language=\"C#\" #>\n<#@ assembly name=\"System.Core\" #>\n<#@ import namespace=\"System.Linq\" #>\n<#@ import namespace=\"System.Text\" #>\n<#@ import namespace=\"System.Collections.Generic\" #>\n<#@ output extension=\".cs\" #>\n<#\n\tOpCode[] baseClasses = {\n\t\tnew OpCode(\"SimpleInstruction\", \"Instruction without any arguments\",\n\t\t\tAbstractBaseClass, CustomArguments(), CustomWriteTo, HasFlag(\"InstructionFlags.None\")),\n\t\tnew OpCode(\"UnaryInstruction\", \"Instruction with a single argument\",\n\t\t\tAbstractBaseClass, CustomArguments((\"argument\", null)), HasFlag(\"InstructionFlags.None\")),\n\t\tnew OpCode(\"BinaryInstruction\", \"Instruction with two arguments: Left and Right\",\n\t\t\tAbstractBaseClass, CustomArguments((\"left\", null), (\"right\", null)), HasFlag(\"InstructionFlags.None\")),\n\t\tnew OpCode(\"CallInstruction\", \"Instruction with a list of arguments.\",\n\t\t\tAbstractBaseClass, CustomChildren(new []{ new ArgumentInfo(\"arguments\") { IsCollection = true }}),\n\t\t\tCustomConstructor, CustomWriteTo, MayThrow, SideEffect),\n\t\tnew OpCode(\"PatternInstruction\", \"Base class for pattern matching in ILAst.\", AbstractBaseClass, ResultType(\"Unknown\")) { Namespace = \"ICSharpCode.Decompiler.IL.Patterns\" },\n\t\tnew OpCode(\"CompoundAssignmentInstruction\", \"Common instruction for compound assignments.\",\n\t\t\tAbstractBaseClass, CustomConstructor, CustomArguments((\"target\", null), (\"value\", null))),\n\t\tnew OpCode(\"DynamicInstruction\", \"Instruction representing a dynamic call site.\",\n\t\t\tAbstractBaseClass, CustomWriteTo, MayThrow, SideEffect)\n\t};\n\t\n\tOpCode[] opCodes = {\n\t\tnew OpCode(\"invalid.branch\", \"Represents invalid IL. Semantically, this instruction is considered to throw some kind of exception.\",\n\t\t\tCustomClassName(\"InvalidBranch\"), NoArguments, MayThrow, SideEffect, HasFlag(\"InstructionFlags.EndPointUnreachable\")),\n\t\tnew OpCode(\"invalid.expr\", \"Represents invalid IL. Semantically, this instruction is considered to produce some kind of value.\",\n\t\t\tCustomClassName(\"InvalidExpression\"), NoArguments, MayThrow, SideEffect),\n\t\tnew OpCode(\"nop\", \"No operation. Takes 0 arguments and returns void.\",\n\t\t\tVoidResult, NoArguments, CustomWriteTo),\n\t\tnew OpCode(\"ILFunction\", \"A container of IL blocks.\",\n\t\t\tCustomChildren(new [] {\n\t\t\t\tnew ChildInfo(\"body\"),\n\t\t\t\tnew ChildInfo(\"localFunctions\") { IsCollection = true, Type = \"ILFunction\" }\n\t\t\t}), CustomConstructor, CustomWriteTo, CustomComputeFlags, CustomVariableName(\"function\"), ResultType(\"DelegateType?.GetStackType() ?? StackType.O\")\n\t\t),\n\t\tnew OpCode(\"BlockContainer\", \"A container of IL blocks.\",\n\t\t\tResultType(\"this.ExpectedResultType\"), CustomConstructor, CustomVariableName(\"container\"),\n\t\t\tMatchCondition(\"Patterns.ListMatch.DoMatch(this.Blocks, o.Blocks, ref match)\")),\n\t\tnew OpCode(\"Block\", \"A block of IL instructions.\",\n\t\t\tCustomConstructor, CustomVariableName(\"block\"),\n\t\t\tMatchCondition(\"this.Kind == o.Kind\"),\n\t\t\tMatchCondition(\"Patterns.ListMatch.DoMatch(this.Instructions, o.Instructions, ref match)\"),\n\t\t\tMatchCondition(\"this.FinalInstruction.PerformMatch(o.FinalInstruction, ref match)\")),\n\t\tnew OpCode(\"PinnedRegion\", \"A region where a pinned variable is used (initial representation of future fixed statement).\",\n\t\t\tResultType(\"Void\"),\n\t\t\tHasVariableOperand(\"Store\"),\n\t\t\tCustomChildren(new []{\n\t\t\t\tnew ChildInfo(\"init\") { CanInlineInto = true },\n\t\t\t\tnew ChildInfo(\"body\")\n\t\t\t}),\n\t\t\tCustomInvariant(\"DebugAssert(Variable.Kind == VariableKind.PinnedRegionLocal);\")),\n\t\tnew OpCode(\"binary\", \"Common instruction for add, sub, mul, div, rem, bit.and, bit.or, bit.xor, shl and shr.\",\n\t\t\tCustomClassName(\"BinaryNumericInstruction\"), Binary, CustomWriteTo, CustomConstructor, CustomComputeFlags,\n\t\t\tMatchCondition(\"CheckForOverflow == o.CheckForOverflow && Sign == o.Sign && Operator == o.Operator && IsLifted == o.IsLifted\")),\n\t\tnew OpCode(\"numeric.compound\", \"Common instruction for numeric compound assignments.\",\n\t\t\tCustomClassName(\"NumericCompoundAssign\"), BaseClass(\"CompoundAssignmentInstruction\"), CustomConstructor, CustomComputeFlags,\n\t\t\tMayThrow, HasTypeOperand, ResultType(\"type.GetStackType()\"), CustomWriteTo,\n\t\t\tMatchCondition(\"CheckForOverflow == o.CheckForOverflow && Sign == o.Sign && Operator == o.Operator\"),\n\t\t\tMatchCondition(\"this.EvalMode == o.EvalMode\"),\n\t\t\tMatchCondition(\"this.TargetKind == o.TargetKind\"),\n\t\t\tMatchCondition(\"Target.PerformMatch(o.Target, ref match)\"),\n\t\t\tMatchCondition(\"Value.PerformMatch(o.Value, ref match)\")),\n\t\tnew OpCode(\"user.compound\", \"Common instruction for user-defined compound assignments.\",\n\t\t\tCustomClassName(\"UserDefinedCompoundAssign\"), BaseClass(\"CompoundAssignmentInstruction\"), CustomConstructor,\n\t\t\tMayThrow, SideEffect, CustomWriteTo,\n\t\t\tMatchCondition(\"this.Method.Equals(o.Method)\"),\n\t\t\tMatchCondition(\"this.EvalMode == o.EvalMode\"),\n\t\t\tMatchCondition(\"this.TargetKind == o.TargetKind\"),\n\t\t\tMatchCondition(\"Target.PerformMatch(o.Target, ref match)\"),\n\t\t\tMatchCondition(\"Value.PerformMatch(o.Value, ref match)\")),\n\t\tnew OpCode(\"dynamic.compound\", \"Common instruction for dynamic compound assignments.\",\n\t\t\tCustomClassName(\"DynamicCompoundAssign\"), BaseClass(\"CompoundAssignmentInstruction\"),\n\t\t\tMayThrow, SideEffect, CustomWriteTo, CustomConstructor, ResultType(\"O\"),\n\t\t\tMatchCondition(\"this.EvalMode == o.EvalMode\"),\n\t\t\tMatchCondition(\"this.TargetKind == o.TargetKind\"),\n\t\t\tMatchCondition(\"Target.PerformMatch(o.Target, ref match)\"),\n\t\t\tMatchCondition(\"Value.PerformMatch(o.Value, ref match)\")),\n\t\tnew OpCode(\"bit.not\", \"Bitwise NOT\", Unary, CustomConstructor, MatchCondition(\"IsLifted == o.IsLifted && UnderlyingResultType == o.UnderlyingResultType\")),\n\t\tnew OpCode(\"arglist\", \"Retrieves the RuntimeArgumentHandle.\", NoArguments, ResultType(\"O\")),\n\t\tnew OpCode(\"br\", \"Unconditional branch. <c>goto target;</c>\",\n\t\t\tCustomClassName(\"Branch\"), NoArguments, CustomConstructor, UnconditionalBranch, MayBranch,\n\t\t\tMatchCondition(\"this.TargetBlock == o.TargetBlock\")),\n\t\tnew OpCode(\"leave\", \"Unconditional branch to end of block container. Return is represented using IsLeavingFunction and an (optional) return value. The block container evaluates to the value produced by the argument of the leave instruction.\",\n\t\t\tCustomConstructor, CustomArguments((\"value\", null)), UnconditionalBranch, MayBranch, CustomWriteTo, CustomComputeFlags,\n\t\t\tMatchCondition(\"this.TargetContainer == o.TargetContainer\")),\n\t\tnew OpCode(\"if\", \"If statement / conditional expression. <c>if (condition) trueExpr else falseExpr</c>\",\n\t\t\tCustomClassName(\"IfInstruction\"),\n\t\t\tCustomChildren(new []{\n\t\t\t\tnew ArgumentInfo(\"condition\"),\n\t\t\t\tnew ChildInfo(\"trueInst\"),\n\t\t\t\tnew ChildInfo(\"falseInst\"),\n\t\t\t}), CustomConstructor, CustomComputeFlags, CustomWriteTo),\n\t\tnew OpCode(\"if.notnull\", \"Null coalescing operator expression. <c>if.notnull(valueInst, fallbackInst)</c>\",\n\t\t\tCustomClassName(\"NullCoalescingInstruction\"),\n\t\t\tCustomChildren(new []{\n\t\t\t\tnew ChildInfo(\"valueInst\") { CanInlineInto = true },\n\t\t\t\tnew ChildInfo(\"fallbackInst\"),\n\t\t\t}), CustomConstructor, CustomComputeFlags, CustomWriteTo),\n\t\tnew OpCode(\"switch\", \"Switch statement\",\n\t\t\tCustomClassName(\"SwitchInstruction\"), CustomConstructor, CustomComputeFlags, CustomWriteTo,\n\t\t\tMatchCondition(\"IsLifted == o.IsLifted && Value.PerformMatch(o.Value, ref match) && Patterns.ListMatch.DoMatch(this.Sections, o.Sections, ref match)\")),\n\t\tnew OpCode(\"switch.section\", \"Switch section within a switch statement\",\n\t\t\tCustomClassName(\"SwitchSection\"), CustomChildren(new [] { new ChildInfo(\"body\") }),\n\t\t\tCustomConstructor, CustomComputeFlags, CustomWriteTo, ResultType(\"Void\"),\n\t\t\tMatchCondition(\"this.Labels.SetEquals(o.Labels) && this.HasNullLabel == o.HasNullLabel\")),\n\t\tnew OpCode(\"try.catch\", \"Try-catch statement.\",\n\t\t\tBaseClass(\"TryInstruction\"), CustomConstructor, CustomComputeFlags, CustomWriteTo,\n\t\t\tMatchCondition(\"TryBlock.PerformMatch(o.TryBlock, ref match)\"),\n\t\t\tMatchCondition(\"Patterns.ListMatch.DoMatch(Handlers, o.Handlers, ref match)\")),\n\t\tnew OpCode(\"try.catch.handler\", \"Catch handler within a try-catch statement.\",\n\t\t\tCustomChildren(new [] {\n\t\t\t\tnew ChildInfo(\"filter\"),\n\t\t\t\tnew ChildInfo(\"body\"),\n\t\t\t}), HasVariableOperand(\"Store\", generateCheckInvariant: false), CustomWriteTo, CustomComputeFlags),\n\t\tnew OpCode(\"try.finally\", \"Try-finally statement\",\n\t\t\tBaseClass(\"TryInstruction\"), CustomConstructor, CustomWriteTo, CustomComputeFlags,\n\t\t\tMatchCondition(\"TryBlock.PerformMatch(o.TryBlock, ref match) && finallyBlock.PerformMatch(o.finallyBlock, ref match)\")),\n\t\tnew OpCode(\"try.fault\", \"Try-fault statement\",\n\t\t\tBaseClass(\"TryInstruction\"), CustomConstructor, CustomWriteTo, CustomComputeFlags,\n\t\t\tMatchCondition(\"TryBlock.PerformMatch(o.TryBlock, ref match)\"),\n\t\t\tMatchCondition(\"faultBlock.PerformMatch(o.faultBlock, ref match)\")),\n\t\tnew OpCode(\"lock\", \"Lock statement\", CustomClassName(\"LockInstruction\"),\n\t\t\tCustomChildren(new [] {\n\t\t\t\tnew ArgumentInfo(\"onExpression\") { ExpectedTypes = new[] { \"O\" }},\n\t\t\t\tnew ChildInfo(\"body\")\n\t\t\t}), CustomWriteTo, ControlFlow, SideEffect, ResultType(\"Void\")),\n\t\tnew OpCode(\"using\", \"Using statement\", CustomClassName(\"UsingInstruction\"), HasVariableOperand(\"Store\"),\n\t\t\tCustomChildren(new [] {\n\t\t\t\tnew ArgumentInfo(\"resourceExpression\") { ExpectedTypes = new[] { \"O\" }},\n\t\t\t\tnew ChildInfo(\"body\")\n\t\t\t}), CustomWriteTo, ControlFlow, SideEffect, ResultType(\"Void\")),\n\t\tnew OpCode(\"debug.break\", \"Breakpoint instruction\",\n\t\t\tNoArguments, VoidResult, SideEffect),\n\t\tnew OpCode(\"comp\", \"Comparison. The inputs must be both integers; or both floats; or both object references. \"\n\t\t\t+ \"Object references can only be compared for equality or inequality. \"\n\t\t\t+ \"Floating-point comparisons evaluate to 0 (false) when an input is NaN, except for 'NaN != NaN' which \"\n\t\t\t+ \"evaluates to 1 (true).\",\n\t\t\tBinary, CustomConstructor, CustomWriteTo,\n\t\t\tMatchCondition(\"this.Kind == o.Kind && this.Sign == o.Sign && this.LiftingKind == o.LiftingKind\")),\n\t\tnew OpCode(\"call\", \"Non-virtual method call.\", Call),\n\t\tnew OpCode(\"callvirt\", \"Virtual method call.\", \n\t\t\tCustomClassName(\"CallVirt\"), Call),\n\t\tnew OpCode(\"calli\", \"Unsafe function pointer call.\",\n\t\t\tCustomClassName(\"CallIndirect\"),\n\t\t\tCustomConstructor, CustomWriteTo,\n\t\t\tMatchCondition(\"EqualSignature(o)\"),\n\t\t\tMatchCondition(\"Patterns.ListMatch.DoMatch(this.Arguments, o.Arguments, ref match)\"),\n\t\t\tMatchCondition(\"this.FunctionPointer.PerformMatch(o.FunctionPointer, ref match)\")),\n\t\tnew OpCode(\"ckfinite\", \"Checks that the input float is not NaN or infinite.\",\n\t\t\tUnary, MayThrow, VoidResult),\n\t\tnew OpCode(\"conv\", \"Numeric cast.\",\n\t\t\tUnary, CustomConstructor,\n\t\t\tMatchCondition(\"CheckForOverflow == o.CheckForOverflow && Kind == o.Kind && InputSign == o.InputSign && TargetType == o.TargetType && IsLifted == o.IsLifted\")),\n\t\tnew OpCode(\"ldloc\", \"Loads the value of a local variable. (ldarg/ldloc)\",\n\t\t\tCustomClassName(\"LdLoc\"), NoArguments, HasVariableOperand(\"Load\"), ResultType(\"variable.StackType\")),\n\t\tnew OpCode(\"ldloca\", \"Loads the address of a local variable. (ldarga/ldloca)\",\n\t\t\tCustomClassName(\"LdLoca\"), NoArguments, ResultType(\"Ref\"), HasVariableOperand(\"Address\")),\n\t\tnew OpCode(\"stloc\", \"Stores a value into a local variable. (IL: starg/stloc)\" + Environment.NewLine\n\t\t\t\t+ \"Evaluates to the value that was stored (for byte/short variables: evaluates to the truncated value, sign/zero extended back to I4 based on variable.Type.GetSign())\",\n\t\t\tCustomClassName(\"StLoc\"), HasVariableOperand(\"Store\", generateCheckInvariant: false), CustomArguments((\"value\", null)),\n\t\t\tResultType(\"variable.StackType\")),\n\t\tnew OpCode(\"addressof\", \"Stores the value into an anonymous temporary variable, and returns the address of that variable.\",\n\t\t\tCustomClassName(\"AddressOf\"), CustomArguments((\"value\", null)), ResultType(\"Ref\"), HasTypeOperand),\n\t\tnew OpCode(\"3vl.bool.and\", \"Three valued logic and. Inputs are of type bool? or I4, output is of type bool?. Unlike logic.and(), does not have short-circuiting behavior.\",\n\t\t\tCustomClassName(\"ThreeValuedBoolAnd\"), Binary, ResultType(\"O\")),\n\t\tnew OpCode(\"3vl.bool.or\", \"Three valued logic or. Inputs are of type bool? or I4, output is of type bool?. Unlike logic.or(), does not have short-circuiting behavior.\",\n\t\t\tCustomClassName(\"ThreeValuedBoolOr\"), Binary, ResultType(\"O\")),\n\t\tnew OpCode(\"nullable.unwrap\", \"The input operand must be one of:\" + Environment.NewLine\n\t\t\t\t+ \"  1. a nullable value type\" + Environment.NewLine\n\t\t\t\t+ \"  2. a reference type\" + Environment.NewLine\n\t\t\t\t+ \"  3. a managed reference to a type parameter.\" + Environment.NewLine\n\t\t\t\t+ \"If the input is non-null, evaluates to the (unwrapped) input.\" + Environment.NewLine\n\t\t\t\t+ \"If the input is null, jumps to the innermost nullable.rewrap instruction that contains this instruction.\" + Environment.NewLine\n\t\t\t\t+ \"In case 3 (managed reference), the dereferenced value is the input being tested, and the nullable.unwrap instruction \"\n\t\t\t\t+ \"returns the managed reference unmodified (if the value is non-null).\",\n\t\t\tUnary, CustomConstructor, CustomWriteTo, HasFlag(\"InstructionFlags.MayUnwrapNull\")),\n\t\tnew OpCode(\"nullable.rewrap\", \"Serves as jump target for the nullable.unwrap instruction.\" + Environment.NewLine\n\t\t\t\t+ \"If the input evaluates normally, evaluates to the input value (wrapped in Nullable&lt;T&gt; if the input is a non-nullable value type).\"\n\t\t\t\t+ \"If a nullable.unwrap instruction encounters a null input and jumps to the (endpoint of the) nullable.rewrap instruction,\"\n\t\t\t\t+ \"the nullable.rewrap instruction evaluates to null.\",\n\t\t\tUnary, CustomComputeFlags),\n\n\t\tnew OpCode(\"ldstr\", \"Loads a constant string.\",\n\t\t\tCustomClassName(\"LdStr\"), LoadConstant(\"string\"), ResultType(\"O\")),\n\t\tnew OpCode(\"ldstr.utf8\", \"Loads a constant byte string (as ReadOnlySpan&lt;byte&gt;).\",\n\t\t\tCustomClassName(\"LdStrUtf8\"), LoadConstant(\"string\"), ResultType(\"O\")),\n\t\tnew OpCode(\"ldc.i4\", \"Loads a constant 32-bit integer.\",\n\t\t\tLoadConstant(\"int\"), ResultType(\"I4\")),\n\t\tnew OpCode(\"ldc.i8\", \"Loads a constant 64-bit integer.\",\n\t\t\tLoadConstant(\"long\"), ResultType(\"I8\")),\n\t\tnew OpCode(\"ldc.f4\", \"Loads a constant 32-bit floating-point number.\",\n\t\t\tLoadConstant(\"float\"), ResultType(\"F4\")),\n\t\tnew OpCode(\"ldc.f8\", \"Loads a constant 64-bit floating-point number.\",\n\t\t\tLoadConstant(\"double\"), ResultType(\"F8\")),\n\t\tnew OpCode(\"ldc.decimal\", \"Loads a constant decimal.\",\n\t\t\tLoadConstant(\"decimal\"), ResultType(\"O\")),\n\t\tnew OpCode(\"ldnull\", \"Loads the null reference.\",\n\t\t\tCustomClassName(\"LdNull\"), NoArguments, ResultType(\"O\")),\n\t\tnew OpCode(\"ldftn\", \"Load method pointer\",\n\t\t\tCustomClassName(\"LdFtn\"), NoArguments, HasMethodOperand(), ResultType(\"I\")),\n\t\tnew OpCode(\"ldvirtftn\", \"Load method pointer\",\n\t\t\tCustomClassName(\"LdVirtFtn\"), Unary, HasMethodOperand(), MayThrow, ResultType(\"I\")),\n\t\tnew OpCode(\"ldvirtdelegate\", \"Virtual delegate construction\",\n\t\t\tCustomClassName(\"LdVirtDelegate\"), Unary, HasTypeOperand, HasMethodOperand(),\n\t\t\tMayThrow, ResultType(\"O\")),\n\t\tnew OpCode(\"ldtypetoken\", \"Loads runtime representation of metadata token\",\n\t\t\tCustomClassName(\"LdTypeToken\"), NoArguments, HasTypeOperand, ResultType(\"O\")),\n\t\tnew OpCode(\"ldmembertoken\", \"Loads runtime representation of metadata token\",\n\t\t\tCustomClassName(\"LdMemberToken\"), NoArguments, HasMemberOperand, ResultType(\"O\")),\n\t\tnew OpCode(\"localloc\", \"Allocates space in the stack frame\",\n\t\t\tCustomClassName(\"LocAlloc\"), Unary, ResultType(\"I\"), MayThrow),\n\t\tnew OpCode(\"localloc.span\", \"Allocates space in the stack frame and wraps it in a Span\",\n\t\t\tCustomClassName(\"LocAllocSpan\"), Unary, HasTypeOperand, ResultType(\"O\"), MayThrow),\n\t\tnew OpCode(\"cpblk\", \"memcpy(destAddress, sourceAddress, size);\",\n\t\t\tCustomArguments((\"destAddress\", new[] { \"I\", \"Ref\" }), (\"sourceAddress\", new[] { \"I\", \"Ref\" }), (\"size\", new[] { \"I4\" })),\n\t\t\tMayThrow, MemoryAccess,\n\t\t\tSupportsVolatilePrefix, SupportsUnalignedPrefix, ResultType(\"Void\")),\n\t\tnew OpCode(\"initblk\", \"memset(address, value, size)\",\n\t\t\tCustomArguments((\"address\", new[] { \"I\", \"Ref\" }), (\"value\", new[] { \"I4\" }), (\"size\", new[] { \"I4\" })),\n\t\t\tMayThrow, MemoryAccess,\n\t\t\tSupportsVolatilePrefix, SupportsUnalignedPrefix, ResultType(\"Void\")),\n\n\t\tnew OpCode(\"ldflda\", \"Load address of instance field\",\n\t\t\tCustomClassName(\"LdFlda\"), CustomArguments((\"target\", null)), MayThrowIfNotDelayed, HasFieldOperand,\n\t\t\tResultType(\"target.ResultType.IsIntegerType() ? StackType.I : StackType.Ref\")),\n\t\tnew OpCode(\"ldsflda\", \"Load static field address\",\n\t\t\tCustomClassName(\"LdsFlda\"), NoArguments, ResultType(\"Ref\"), HasFieldOperand),\n\t\t\t\n\t\tnew OpCode(\"castclass\", \"Casts an object to a class.\",\n\t\t\tCustomClassName(\"CastClass\"), Unary, HasTypeOperand, MayThrow, ResultType(\"type.GetStackType()\")),\n\t\tnew OpCode(\"isinst\", \"Test if object is instance of class or interface.\",\n\t\t\tCustomClassName(\"IsInst\"), Unary, HasTypeOperand, ResultType(\"O\")),\n\t\tnew OpCode(\"ldobj\", \"Indirect load (ref/pointer dereference).\",\n\t\t\tCustomClassName(\"LdObj\"), CustomArguments((\"target\", new[] { \"Ref\", \"I\" })), HasTypeOperand, MemoryAccess, CustomWriteToButKeepOriginal,\n\t\t\tSupportsVolatilePrefix, SupportsUnalignedPrefix, MayThrow, ResultType(\"type.GetStackType()\")),\n\t\tnew OpCode(\"ldobj.if.ref\", \"If argument is a ref to a reference type, loads the object reference, stores it in a temporary, and evaluates to the address of that temporary (address.of(ldobj(arg))). Otherwise, returns the argument ref as-is.<para>This instruction represents the memory-load semantics of callvirt with a generic type as receiver (where the IL always takes a ref, but only methods on value types expect one, for method on reference types there's an implicit ldobj, which this instruction makes explicit in order to preserve the order-of-evaluation).</para>\",\n\t\t\tCustomClassName(\"LdObjIfRef\"), CustomArguments((\"target\", new[] { \"Ref\", \"I\" })), HasTypeOperand, MemoryAccess,\n\t\t\tMayThrow, ResultType(\"Ref\")),\n\t\tnew OpCode(\"stobj\", \"Indirect store (store to ref/pointer).\" + Environment.NewLine\n\t\t\t\t+ \"Evaluates to the value that was stored (when using type byte/short: evaluates to the truncated value, sign/zero extended back to I4 based on type.GetSign())\",\n\t\t\tCustomClassName(\"StObj\"), CustomArguments((\"target\", new[] { \"Ref\", \"I\" }), (\"value\", new[] { \"type.GetStackType()\" })), HasTypeOperand, MemoryAccess, CustomWriteToButKeepOriginal,\n\t\t\tSupportsVolatilePrefix, SupportsUnalignedPrefix, MayThrow,\n\t\t\tResultType(\"UnalignedPrefix == 0 ? type.GetStackType() : StackType.Void\"),\n\t\t\tCustomInvariant(\"CheckTargetSlot();\")),\n\n\t\tnew OpCode(\"box\", \"Boxes a value.\",\n\t\t\tUnary, HasTypeOperand, ResultType(\"O\")),\n\t\tnew OpCode(\"unbox\", \"Compute address inside box.\",\n\t\t\tUnary, HasTypeOperand, MayThrow, ResultType(\"Ref\")),\n\t\tnew OpCode(\"unbox.any\", \"Unbox a value.\",\n\t\t\tUnary, HasTypeOperand, MemoryAccess, MayThrow, ResultType(\"type.GetStackType()\")),\n\t\tnew OpCode(\"newobj\", \"Creates an object instance and calls the constructor.\",\n\t\t\tCustomClassName(\"NewObj\"), Call, ResultType(\"Method.DeclaringType.GetStackType()\")),\n\t\tnew OpCode(\"newarr\", \"Creates an array instance.\",\n\t\t\tCustomClassName(\"NewArr\"), HasTypeOperand, CustomChildren(new [] { new ArgumentInfo(\"indices\") { IsCollection = true } }, true), MayThrow, ResultType(\"O\")),\n\t\tnew OpCode(\"default.value\", \"Returns the default value for a type.\",\n\t\t\tNoArguments, HasTypeOperand, ResultType(\"type.GetStackType()\")),\n\t\tnew OpCode(\"throw\", \"Throws an exception.\",\n\t\t\tUnary, MayThrow, HasFlag(\"InstructionFlags.EndPointUnreachable\"), ResultType(\"this.resultType\")),\n\t\tnew OpCode(\"rethrow\", \"Rethrows the current exception.\",\n\t\t\tNoArguments, MayThrow, UnconditionalBranch),\n\t\tnew OpCode(\"sizeof\", \"Gets the size of a type in bytes.\",\n\t\t\tCustomClassName(\"SizeOf\"), NoArguments, HasTypeOperand, ResultType(\"I4\")),\n\t\t\n\t\tnew OpCode(\"ldlen\", \"Returns the length of an array as 'native unsigned int'.\",\n\t\t\tCustomClassName(\"LdLen\"), CustomArguments((\"array\", new[] { \"O\" })), CustomConstructor, CustomWriteTo, MayThrow),\n\t\tnew OpCode(\"ldelema\", \"Load address of array element.\",\n\t\t\tCustomClassName(\"LdElema\"), HasTypeOperand, CustomChildren(new [] { new ArgumentInfo(\"array\"), new ArgumentInfo(\"indices\") { IsCollection = true } }, true),\n\t\t\tBoolFlag(\"WithSystemIndex\"),\n\t\t\tMayThrowIfNotDelayed, ResultType(\"Ref\"), SupportsReadonlyPrefix),\n\t\tnew OpCode(\"ldelema.inlinearray\", \"Load address of inline array element.\",\n\t\t\tCustomClassName(\"LdElemaInlineArray\"), HasTypeOperand, CustomChildren(new [] { new ArgumentInfo(\"array\"), new ArgumentInfo(\"indices\") { IsCollection = true } }, true),\n\t\t\tMayThrow, ResultType(\"Ref\"), SupportsReadonlyPrefix),\n\t\tnew OpCode(\"get.pinnable.reference\", \"Retrieves a pinnable reference for the input object.\" + Environment.NewLine\n\t\t\t\t+ \"The input must be an object reference (O).\" + Environment.NewLine\n\t\t\t\t+ \"If the input is an array/string, evaluates to a reference to the first element/character, or to a null reference if the array is null or empty.\" + Environment.NewLine\n\t\t\t\t+ \"Otherwise, uses the GetPinnableReference method to get the reference, or evaluates to a null reference if the input is null.\" + Environment.NewLine,\n\t\t\tCustomArguments((\"argument\", new[] { \"O\" })), ResultType(\"Ref\"), HasMethodOperand(nullable: true)),\n\t\tnew OpCode(\"string.to.int\", \"Maps a string value to an integer. This is used in switch(string).\",\n\t\t\tCustomArguments((\"argument\", new[] { \"O\" })), CustomConstructor, CustomWriteTo, ResultType(\"I4\")),\n\n\t\tnew OpCode(\"expression.tree.cast\", \"ILAst representation of Expression.Convert.\",\n\t\t\tCustomClassName(\"ExpressionTreeCast\"), Unary, HasTypeOperand, MayThrow, CustomConstructor, CustomWriteTo, ResultType(\"type.GetStackType()\"),\n\t\t\tMatchCondition(\"this.IsChecked == o.IsChecked\")),\n\n\t\tnew OpCode(\"user.logic.operator\", \"Use of user-defined &amp;&amp; or || operator.\",\n\t\t\tCustomClassName(\"UserDefinedLogicOperator\"),\n\t\t\tHasMethodOperand(), ResultType(\"O\"),\n\t\t\tCustomChildren(new []{\n\t\t\t\tnew ChildInfo(\"left\") { CanInlineInto = true },\n\t\t\t\tnew ChildInfo(\"right\") { CanInlineInto = false } // only executed depending on value of left\n\t\t\t}),\n\t\t\tCustomComputeFlags // MayThrow, SideEffect, ControlFlow\n\t\t),\n\n\t\tnew OpCode(\"dynamic.logic.operator\", \"ILAst representation of a short-circuiting binary operator inside a dynamic expression.\",\n\t\t\tCustomClassName(\"DynamicLogicOperatorInstruction\"), Dynamic, CustomComputeFlags,\n\t\t\tCustomChildren(new []{\n\t\t\t\tnew ChildInfo(\"left\") { CanInlineInto = true },\n\t\t\t\tnew ChildInfo(\"right\") { CanInlineInto = false } // only executed depending on value of left\n\t\t\t}), CustomWriteTo\n\t\t),\n\t\t\n\t\tnew OpCode(\"dynamic.binary.operator\", \"ILAst representation of a binary operator inside a dynamic expression (maps to Binder.BinaryOperation).\",\n\t\t\tCustomClassName(\"DynamicBinaryOperatorInstruction\"), Dynamic, CustomArguments((\"left\", null), (\"right\", null)), CustomWriteTo),\n\t\tnew OpCode(\"dynamic.unary.operator\", \"ILAst representation of a unary operator inside a dynamic expression (maps to Binder.UnaryOperation).\",\n\t\t\tCustomClassName(\"DynamicUnaryOperatorInstruction\"), Dynamic, CustomArguments((\"operand\", null)), CustomWriteTo),\n\t\tnew OpCode(\"dynamic.convert\", \"ILAst representation of a cast inside a dynamic expression (maps to Binder.Convert).\",\n\t\t\tCustomClassName(\"DynamicConvertInstruction\"), Dynamic, HasTypeOperand, CustomArguments((\"argument\", new[] { \"O\" })), CustomWriteTo),\n\t\tnew OpCode(\"dynamic.getmember\", \"ILAst representation of a property get method call inside a dynamic expression (maps to Binder.GetMember).\",\n\t\t\tCustomClassName(\"DynamicGetMemberInstruction\"), Dynamic, CustomArguments((\"target\", new[] { \"O\" })), CustomConstructor, CustomWriteTo),\n\t\tnew OpCode(\"dynamic.setmember\", \"ILAst representation of a property set method call inside a dynamic expression (maps to Binder.SetMember).\",\n\t\t\tCustomClassName(\"DynamicSetMemberInstruction\"), Dynamic, CustomArguments((\"target\", new[] { \"O\" }), (\"value\", null)), CustomWriteTo),\n\t\tnew OpCode(\"dynamic.getindex\", \"ILAst representation of an indexer get method call inside a dynamic expression (maps to Binder.GetIndex).\",\n\t\t\tCustomClassName(\"DynamicGetIndexInstruction\"), Dynamic, CustomChildren(new []{ new ArgumentInfo(\"arguments\") { IsCollection = true }}), CustomWriteTo),\n\t\tnew OpCode(\"dynamic.setindex\", \"ILAst representation of an indexer set method call inside a dynamic expression (maps to Binder.SetIndex).\",\n\t\t\tCustomClassName(\"DynamicSetIndexInstruction\"), Dynamic, CustomChildren(new []{ new ArgumentInfo(\"arguments\") { IsCollection = true }}), CustomWriteTo),\n\t\tnew OpCode(\"dynamic.invokemember\", \"ILAst representation of a method call inside a dynamic expression (maps to Binder.InvokeMember).\",\n\t\t\tCustomClassName(\"DynamicInvokeMemberInstruction\"), Dynamic, CustomChildren(new []{ new ArgumentInfo(\"arguments\") { IsCollection = true }}), CustomWriteTo),\n\t\tnew OpCode(\"dynamic.invokeconstructor\", \"ILAst representation of a constuctor invocation inside a dynamic expression (maps to Binder.InvokeConstructor).\",\n\t\t\tCustomClassName(\"DynamicInvokeConstructorInstruction\"), Dynamic, CustomChildren(new []{ new ArgumentInfo(\"arguments\") { IsCollection = true }}), CustomWriteTo),\n\t\tnew OpCode(\"dynamic.invoke\", \"ILAst representation of a delegate invocation inside a dynamic expression (maps to Binder.Invoke).\",\n\t\t\tCustomClassName(\"DynamicInvokeInstruction\"), Dynamic, CustomChildren(new []{ new ArgumentInfo(\"arguments\") { IsCollection = true }}), CustomWriteTo),\n\t\tnew OpCode(\"dynamic.isevent\", \"ILAst representation of a call to the Binder.IsEvent method inside a dynamic expression.\",\n\t\t\tCustomClassName(\"DynamicIsEventInstruction\"), Dynamic, CustomArguments((\"argument\", new[] { \"O\" })), CustomWriteTo),\n\n\t\tnew OpCode(\"match\", \"ILAst representation of C# patterns\",\n\t\t\tCustomClassName(\"MatchInstruction\"), HasVariableOperand(\"Store\"), HasMethodOperand(nullable: true),\n\t\t\tBoolFlag(\"IsDeconstructCall\"), BoolFlag(\"IsDeconstructTuple\"), BoolFlag(\"CheckType\"), BoolFlag(\"CheckNotNull\"),\n\t\t\tCustomChildren(new []{\n\t\t\t\tnew ChildInfo(\"testedOperand\") { CanInlineInto = true },\n\t\t\t\tnew ChildInfo(\"subPatterns\") { IsCollection = true }\n\t\t\t}), ResultType(\"I4\"), CustomWriteTo, SideEffect, MayThrow, ControlFlow, CustomInvariant(\"AdditionalInvariants();\")),\n\n\t\tnew OpCode(\"mkrefany\", \"Push a typed reference of type class onto the stack.\",\n\t\t\tCustomClassName(\"MakeRefAny\"), Unary, HasTypeOperand, ResultType(\"O\")),\n\t\tnew OpCode(\"refanytype\", \"Push the type token stored in a typed reference.\",\n\t\t\tCustomClassName(\"RefAnyType\"), Unary, ResultType(\"O\")),\n\t\tnew OpCode(\"refanyval\", \"Push the address stored in a typed reference.\",\n\t\t\tCustomClassName(\"RefAnyValue\"), Unary, HasTypeOperand, MayThrow, ResultType(\"Ref\")),\n\n\t\tnew OpCode(\"yield.return\", \"Yield an element from an iterator.\",\n\t\t\tMayBranch, // yield return may end up returning if the consumer disposes the iterator\n\t\t\tSideEffect, // consumer can have arbitrary side effects while we're yielding\n\t\t\tCustomArguments((\"value\", null)), VoidResult),\n\t\t// note: \"yield break\" is always represented using a \"leave\" instruction\n\t\tnew OpCode(\"await\", \"C# await operator.\",\n\t\t\tSideEffect, // other code can run with arbitrary side effects while we're waiting\n\t\t\tCustomArguments((\"value\", null)), ResultType(\"GetResultMethod?.ReturnType.GetStackType() ?? StackType.Unknown\")),\n\n\t\tnew OpCode(\"deconstruct\", \"Deconstruction statement\",\n\t\t\tCustomClassName(\"DeconstructInstruction\"), CustomConstructor, ResultType(\"Void\"), CustomWriteTo),\n\t\tnew OpCode(\"deconstruct.result\", \"Represents a deconstructed value\",\n\t\t\tCustomClassName(\"DeconstructResultInstruction\"), CustomConstructor, CustomInvariant(\"AdditionalInvariants();\"),\n\t\t\tUnary, CustomWriteTo),\n\n\t\t// patterns\n\t\tnew OpCode(\"AnyNode\", \"Matches any node\", Pattern, CustomArguments(), CustomConstructor),\n\t};\n#>\nusing System;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// Enum representing the type of an <see cref=\"ILInstruction\"/>.\n\t/// </summary>\n\tpublic enum OpCode : byte\n\t{\n<#\tforeach (OpCode opCode in opCodes) { #>\n\t\t/// <summary><#=opCode.Description.Replace(\"\\n\", \"\\n\\t\\t/// \")#></summary>\n\t\t<#=opCode.Name#>,\n<#  } #>\n\t}\n}\n\n<#\tforeach (OpCode opCode in baseClasses.Concat(opCodes)) { #>\nnamespace <#=opCode.Namespace#>\n{\n\t/// <summary><#=opCode.Description.Replace(\"\\n\", \"\\n\\t/// \")#></summary>\n\t<#=opCode.ClassModifiers#> partial class <#=opCode.Name#> : <#=string.Join(\", \", new[]{opCode.BaseClass}.Concat(opCode.Interfaces))#>\n\t{\n<#\tif (opCode.GenerateConstructor) { #>\n\t\t<#=opCode.ConstructorModifier#> <#=opCode.Name#>(<#=string.Join(\", \", opCode.ConstructorParameters)#>) : base(<#=string.Join(\", \", opCode.BaseConstructorArguments)#>)\n\t\t{<#=Body(opCode.ConstructorBody)#>}\n<#\t} #>\n<#=string.Join(Environment.NewLine, opCode.Members.Select(m => \"\\t\\t\" + m.Replace(\"\\n\", \"\\n\\t\\t\")))#>\n<#\tif (opCode.GenerateComputeFlags && opCode.Flags.Any(f => f != \"base.ComputeFlags()\")) { #>\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\treturn <#=string.Join(\" | \", opCode.Flags)#>;\n\t\t}\n<#\t} #>\n<#\tif (opCode.GenerateComputeFlags && opCode.Flags.Any(f => f != \"base.ComputeFlags()\")) { #>\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\treturn <#=opCode.DirectFlags.Count > 0 ? string.Join(\" | \", opCode.DirectFlags) : \"InstructionFlags.None\"#>;\n\t\t\t}\n\t\t}\n<#\t} #>\n<#\tif (opCode.GenerateWriteTo) { #>\n<#      if (opCode.CustomWriteToButKeepOriginal) { #>\n\t\tvoid OriginalWriteTo(ITextOutput output, ILAstWritingOptions options)\n<#      } else { #>\n\t\tpublic override void WriteTo(ITextOutput output, ILAstWritingOptions options)\n<#      } #>\n\t\t{<#=Body(opCode.WriteToBody)#>}\n<#\t} #>\n<#\tif (opCode.GenerateAcceptVisitor) { #>\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tvisitor.Visit<#=opCode.Name#>(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\treturn visitor.Visit<#=opCode.Name#>(this);\n\t\t}\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\treturn visitor.Visit<#=opCode.Name#>(this, context);\n\t\t}\n<#\t} #>\n<#\t\tif (opCode.GeneratePerformMatch) { #>\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)\n\t\t{\n\t\t\tvar o = other as <#=opCode.Name#>;\n\t\t\treturn <#=string.Join(\" && \", opCode.PerformMatchConditions)#>;\n\t\t}\n<#\t\t} #>\n<#\t\tif (opCode.Invariants.Count > 0) { #>\n\t\tinternal override void CheckInvariant(ILPhase phase)\n\t\t{\n\t\t\tbase.CheckInvariant(phase);\n<#\t\t\tforeach (var invariant in opCode.Invariants) {#>\n\t\t\t<#=invariant#>\n<#\t\t\t} #>\n\t\t}\n<#\t\t} #>\n\t}\n}\n<#\t} #>\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// Base class for visitor pattern.\n\t/// </summary>\n\tpublic abstract class ILVisitor\n\t{\n\t\t/// <summary>Called by Visit*() methods that were not overridden</summary>\n\t\tprotected abstract void Default(ILInstruction inst);\n\t\t\n<#\tforeach (OpCode opCode in opCodes.Where(o => o.GenerateAcceptVisitor)) { #>\n\t\tprotected internal virtual void Visit<#=opCode.Name#>(<#=opCode.Name#> <#=opCode.VariableName#>)\n\t\t{\n\t\t\tDefault(<#=opCode.VariableName#>);\n\t\t}\n<#\t} #>\n\t}\n\t\n\t/// <summary>\n\t/// Base class for visitor pattern.\n\t/// </summary>\n\tpublic abstract class ILVisitor<T>\n\t{\n\t\t/// <summary>Called by Visit*() methods that were not overridden</summary>\n\t\tprotected abstract T Default(ILInstruction inst);\n\t\t\n<#\tforeach (OpCode opCode in opCodes.Where(o => o.GenerateAcceptVisitor)) { #>\n\t\tprotected internal virtual T Visit<#=opCode.Name#>(<#=opCode.Name#> <#=opCode.VariableName#>)\n\t\t{\n\t\t\treturn Default(<#=opCode.VariableName#>);\n\t\t}\n<#\t} #>\n\t}\n\n\t/// <summary>\n\t/// Base class for visitor pattern.\n\t/// </summary>\n\tpublic abstract class ILVisitor<C, T>\n\t{\n\t\t/// <summary>Called by Visit*() methods that were not overridden</summary>\n\t\tprotected abstract T Default(ILInstruction inst, C context);\n\t\t\n<#\tforeach (OpCode opCode in opCodes.Where(o => o.GenerateAcceptVisitor)) { #>\n\t\tprotected internal virtual T Visit<#=opCode.Name#>(<#=opCode.Name#> <#=opCode.VariableName#>, C context)\n\t\t{\n\t\t\treturn Default(<#=opCode.VariableName#>, context);\n\t\t}\n<#\t} #>\n\t}\n\t\n\tpartial class InstructionOutputExtensions\n\t{\n\t\tstatic readonly string[] originalOpCodeNames = {\n<#\tforeach (OpCode opCode in opCodes) { #>\n\t\t\t\"<#=opCode.OriginalName#>\",\n<#\t} #>\n\t\t};\n\t}\n\t\n\tpartial class ILInstruction\n\t{\n<#\tforeach (OpCode opCode in opCodes) { #>\n<#\t\tif (opCode.GenerateMatch) { #>\n\t\tpublic bool Match<#=opCode.Name#>(<#=string.Join(\", \", opCode.MatchParameters)#>)\n\t\t{\n\t\t\tvar inst = this as <#=opCode.Name#>;\n\t\t\tif (inst != null) {\n<#\t\t\tforeach (var parameter in opCode.MatchParameters) {#>\n\t\t\t\t<#=parameter.Name#> = inst.<#=parameter.FieldName#>;\n<#\t\t\t}#>\n\t\t\t\treturn true;\n\t\t\t}\n<#\t\t\tforeach (var parameter in opCode.MatchParameters) {#>\n\t\t\t<#=parameter.Name#> = default(<#=parameter.TypeName#>);\n<#\t\t\t}#>\n\t\t\treturn false;\n\t\t}\n<#\t\t}\n\t} #>\n\t}\n}\n\n<#+\n\tstatic string Body(IEnumerable<string> statements)\n\t{\n\t\tStringBuilder b = new StringBuilder();\n\t\tforeach (var st in statements) {\n\t\t\tb.AppendLine();\n\t\t\tb.Append(\"\\t\\t\\t\");\n\t\t\tb.Append(st.Replace(\"\\n\", \"\\n\\t\\t\\t\"));\n\t\t}\n\t\tb.AppendLine();\n\t\tb.Append(\"\\t\\t\");\n\t\treturn b.ToString();\n\t}\n\t\n\tstatic string MakeName(string originalName)\n\t{\n\t\tStringBuilder name = new StringBuilder();\n\t\tbool nextUpper = true;\n\t\tforeach (char c in originalName) {\n\t\t\tif (c == '.')\n\t\t\t\tnextUpper = true;\n\t\t\telse if (nextUpper) {\n\t\t\t\tname.Append(char.ToUpper(c));\n\t\t\t\tnextUpper = false;\n\t\t\t} else\n\t\t\t\tname.Append(c);\n\t\t}\n\t\treturn name.ToString();\n\t}\n\n\tclass OpCode\n\t{\n\t\tpublic readonly string OriginalName;\n\t\tpublic string Name;\n\t\tpublic string Namespace = \"ICSharpCode.Decompiler.IL\";\n\t\tpublic readonly string Description;\n\t\tpublic string VariableName = \"inst\";\n\n\t\tpublic OpCode(string originalName, string description, params Action<OpCode>[] traits)\n\t\t{\n\t\t\tthis.OriginalName = originalName;\n\t\t\tthis.Name = MakeName(originalName);\n\t\t\tthis.Description = description;\n\t\t\tforeach (var trait in traits)\n\t\t\t\ttrait(this);\n\t\t\tif (this.BaseConstructorArguments.FirstOrDefault() != \"opCode\")\n\t\t\t\tthis.BaseConstructorArguments.Insert(0, \"OpCode.\" + this.Name);\n\t\t}\n\n\t\tpublic string ClassModifiers = \"public sealed\";\n\t\t\n\t\tpublic bool GenerateConstructor = true;\n\t\tpublic string ConstructorModifier = \"public\";\n\t\tpublic List<string> ConstructorParameters = new List<string>();\n\t\tpublic List<string> ConstructorBody = new List<string>();\n\t\t\n\t\tpublic bool GenerateMatch = true;\n\t\tpublic bool GeneratePerformMatch = true;\n\t\tpublic List<MatchParamInfo> MatchParameters = new List<MatchParamInfo>();\n\t\tpublic List<string> PerformMatchConditions = new List<string>() { \"o != null\" };\n\t\tpublic List<string> Invariants = new List<string>();\n\n\t\tpublic string BaseClass = \"ILInstruction\";\n\t\tpublic List<string> Interfaces = new List<string>();\n\t\tpublic List<string> BaseConstructorArguments = new List<string>();\n\t\tpublic List<string> Members = new List<string>();\n\t\t\n\t\tpublic List<string> Flags = new List<string>();\n\t\tpublic List<string> DirectFlags = new List<string>();\n\t\tpublic bool GenerateComputeFlags = true;\n\n\n\t\tpublic bool GenerateAcceptVisitor = true;\n\t\t\n\t\t\n\t\tpublic bool GenerateWriteTo = false;\n\t\tpublic bool CustomWriteToButKeepOriginal = false;\n\t\tpublic List<string> WriteOpCodePrefix = new List<string>();\n\t\tpublic List<string> WriteOpCodeSuffix = new List<string>();\n\t\tpublic List<string> WriteOperand = new List<string>();\n\t\tpublic List<string> WriteArguments = new List<string>();\n\t\t\n\t\tpublic IEnumerable<string> WriteToBody {\n\t\t\tget {\n\t\t\t\tyield return \"WriteILRange(output, options);\";\n\t\t\t\tforeach (string line in WriteOpCodePrefix)\n\t\t\t\t\tyield return line;\n\t\t\t\tyield return \"output.Write(OpCode);\";\n\t\t\t\tforeach (string line in WriteOpCodeSuffix.Concat(WriteOperand).Concat(WriteArguments))\n\t\t\t\t\tyield return line;\n\t\t\t}\n\t\t}\n\t}\n\t\n\tclass MatchParamInfo\n\t{\n\t\tpublic string TypeName;\n\t\tpublic string Name;\n\t\tpublic string FieldName;\n\t\tpublic bool IsReferenceType = true;\n\t\t\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tif (IsReferenceType) {\n\t\t\t\treturn \"[NotNullWhen(true)] out \" + TypeName + \"? \" + Name;\n\t\t\t} else {\n\t\t\t\treturn \"out \" + TypeName + \" \" + Name;\n\t\t\t}\n\t\t}\n\t}\n\t\n\tstatic Action<OpCode> CustomClassName(string name)\n\t{\n\t\treturn opCode => {\n\t\t\topCode.Name = name;\n\t\t};\n\t}\n\t\n\tstatic Action<OpCode> CustomVariableName(string name)\n\t{\n\t\treturn opCode => {\n\t\t\topCode.VariableName = name;\n\t\t};\n\t}\n\t\n\tstatic Action<OpCode> CustomConstructor = opCode => {\n\t\topCode.GenerateConstructor = false;\n\t\topCode.GenerateMatch = false;\n\t};\n\t\n\tstatic Action<OpCode> CustomWriteTo = opCode => {\n\t\topCode.GenerateWriteTo = false;\n\t};\n\n\tstatic Action<OpCode> CustomWriteToButKeepOriginal = opCode => {\n\t\topCode.CustomWriteToButKeepOriginal = true;\n\t};\n\t\n\tstatic Action<OpCode> CustomComputeFlags = opCode => {\n\t\topCode.GenerateComputeFlags = false;\n\t};\n\t\n\t// Call trait: the instruction performs a method call\n\tstatic Action<OpCode> MatchCondition(string name)\n\t{\n\t\treturn opCode => {\n\t\t\topCode.PerformMatchConditions.Add(name);\n\t\t};\n\t}\n\t\n\tstatic Action<OpCode> HasFlag(string name)\n\t{\n\t\treturn opCode => {\n\t\t\topCode.Flags.Add(name);\n\t\t\topCode.DirectFlags.Add(name);\n\t\t};\n\t}\n\n\tstatic Action<OpCode> AdditionalMember(string declaration)\n\t{\n\t\treturn opCode => {\n\t\t\topCode.Members.Add(declaration);\n\t\t};\n\t}\n\n\t// ResultType trait: the instruction has the specified result type.\n\tstatic Action<OpCode> ResultType(string type)\n\t{\n\t\tif (!type.Contains(\".\"))\n\t\t\ttype = \"StackType.\" + type;\n\t\treturn opCode => {\n\t\t\topCode.Members.Add(\"public override StackType ResultType { get { return \" + type + \"; } }\");\n\t\t};\n\t}\n\t\n\t// VoidResult trait: the instruction has no result and is not usable as an argument\n\tstatic Action<OpCode> VoidResult = ResultType(\"Void\");\n\n\t// ResultTypeParam trait: the instruction takes its result type as ctor parameter\n\tstatic Action<OpCode> ResultTypeParam = opCode => {\n\t\topCode.ConstructorParameters.Add(\"StackType resultType\");\n\t\topCode.ConstructorBody.Add(\"this.resultType = resultType;\");\n\t\topCode.Members.Add(\"StackType resultType;\");\n\t\topCode.Members.Add(\"public override StackType ResultType { get { return resultType; } }\");\n\t};\n\n\t// MayThrow trait: the instruction may throw exceptions\n\tstatic Action<OpCode> MayThrow = HasFlag(\"InstructionFlags.MayThrow\");\n\t\n\t// MayBranch trait: the instruction may cause control flow to branch (e.g. branch, conditionalbranch, return)\n\tstatic Action<OpCode> MayBranch = HasFlag(\"InstructionFlags.MayBranch\");\n\t\n\t// UnconditionalBranch trait: the instruction does not produce a result normally; it always branches or throws an exception. Implies VoidResult.\n\t// UnconditionalBranch should be paired with either MayBranch or MayThrow (or both).\n\tstatic Action<OpCode> UnconditionalBranch = VoidResult + HasFlag(\"InstructionFlags.EndPointUnreachable\");\n\t\n\t// ControlFlow trait: the instruction involves some form of internal control flow\n\t// Instructions without this trait must evaluate all arguments left-to-right before having any effect of their own.\n\tstatic Action<OpCode> ControlFlow = HasFlag(\"InstructionFlags.ControlFlow\");\n\t\n\tstatic Action<OpCode> MayThrowIfNotDelayed = HasFlag(\"(DelayExceptions ? InstructionFlags.None : InstructionFlags.MayThrow)\") + (opCode => {\n\t\topCode.Members.Add(\"public bool DelayExceptions; // NullReferenceException/IndexOutOfBoundsException only occurs when the reference is dereferenced\");\n\t\topCode.GenerateWriteTo = true;\n\t\topCode.WriteOpCodePrefix.Add(\"if (DelayExceptions)\" + Environment.NewLine + \"\\toutput.Write(\\\"delayex.\\\");\");\n\t\topCode.PerformMatchConditions.Add(\"DelayExceptions == o.DelayExceptions\");\n\t});\n\t\n\tstatic Action<OpCode> BaseClass(string name)\n\t{\n\t\treturn opCode => {\n\t\t\topCode.BaseClass = name;\n\t\t\topCode.Flags.Add(\"base.ComputeFlags()\");\n\t\t\topCode.DirectFlags.Add(\"base.DirectFlags\");\n\t\t};\n\t}\n\t\n\t// NoArguments trait: the instruction no arguments\n\tstatic Action<OpCode> NoArguments = opCode => {\n\t\topCode.BaseClass = \"SimpleInstruction\";\n\t};\n\t\n\t// Unary trait: the instruction has a single argument\n\tstatic Action<OpCode> Unary = opCode => {\n\t\tBaseClass(\"UnaryInstruction\")(opCode);\n\t\topCode.ConstructorParameters.Add(\"ILInstruction argument\");\n\t\topCode.MatchParameters.Add(new MatchParamInfo { TypeName = \"ILInstruction\", Name = \"argument\", FieldName = \"Argument\" });\n\t\topCode.PerformMatchConditions.Add(\"this.Argument.PerformMatch(o.Argument, ref match)\");\n\t\topCode.BaseConstructorArguments.Add(\"argument\");\n\t\topCode.WriteArguments.Add(\"output.Write('(');\");\n\t\topCode.WriteArguments.Add(\"Argument.WriteTo(output, options);\");\n\t\topCode.WriteArguments.Add(\"output.Write(')');\");\n\t};\n\t\n\t// Binary trait: the instruction has two arguments named 'Left' and 'Right'\n\tstatic Action<OpCode> Binary = opCode => {\n\t\tBaseClass(\"BinaryInstruction\")(opCode);\n\t\topCode.ConstructorParameters.Add(\"ILInstruction left\");\n\t\topCode.ConstructorParameters.Add(\"ILInstruction right\");\n\t\topCode.BaseConstructorArguments.Add(\"left\");\n\t\topCode.BaseConstructorArguments.Add(\"right\");\n\t\topCode.MatchParameters.Add(new MatchParamInfo { TypeName = \"ILInstruction\", Name = \"left\", FieldName = \"Left\" });\n\t\topCode.MatchParameters.Add(new MatchParamInfo { TypeName = \"ILInstruction\", Name = \"right\", FieldName = \"Right\" });\n\t\topCode.PerformMatchConditions.Add(\"this.Left.PerformMatch(o.Left, ref match)\");\n\t\topCode.PerformMatchConditions.Add(\"this.Right.PerformMatch(o.Right, ref match)\");\n\t\topCode.WriteArguments.Add(\"output.Write('(');\");\n\t\topCode.WriteArguments.Add(\"Left.WriteTo(output, options);\");\n\t\topCode.WriteArguments.Add(\"output.Write(\\\", \\\");\");\n\t\topCode.WriteArguments.Add(\"Right.WriteTo(output, options);\");\n\t\topCode.WriteArguments.Add(\"output.Write(')');\");\n\t};\n\t\n\tstatic Action<OpCode> CustomArguments(params (string name, string[] expectedTypes)[] arguments)\n\t{\n\t\treturn CustomChildren(arguments.Select(arg => new ArgumentInfo(arg.name) { ExpectedTypes = arg.expectedTypes }).ToArray(), generateInline: true);\n\t}\n\t\n\tclass ChildInfo\n\t{\n\t\tpublic readonly string PropertyName;\n\t\tpublic readonly string Name;\n\t\tpublic readonly string SlotName;\n\t\t\n\t\tpublic bool IsCollection;\n\t\tpublic string Type = \"ILInstruction\";\n\t\tpublic bool CanInlineInto;\n\t\tpublic string[] ExpectedTypes;\n\t\t\n\t\tpublic ChildInfo(string name)\n\t\t{\n\t\t\tthis.Name = name;\n\t\t\tthis.PropertyName = MakeName(name);\n\t\t\tthis.SlotName = this.PropertyName + \"Slot\";\n\t\t}\n\t\t\n\t\tpublic string GetSlotInit()\n\t\t{\n\t\t\tStringBuilder b = new StringBuilder();\n\t\t\tb.Append(\"new SlotInfo(\\\"\" + PropertyName + \"\\\"\");\n\t\t\tif (CanInlineInto)\n\t\t\t\tb.Append(\", canInlineInto: true\");\n\t\t\tb.Append(\")\");\n\t\t\treturn b.ToString();\n\t\t}\n\t}\n\t\n\tclass ArgumentInfo : ChildInfo\n\t{\n\t\tpublic ArgumentInfo(string name) : base(name)\n\t\t{\n\t\t\tthis.CanInlineInto = true;\n\t\t}\n\t}\n\t\n\tstatic Action<OpCode> CustomChildren(ChildInfo[] children, bool generateInline = false)\n\t{\n\t\treturn opCode => {\n\t\t\topCode.GenerateWriteTo = true;\n\t\t\topCode.WriteArguments.Add(\"output.Write('(');\");\n\t\t\tStringBuilder transformChildren = new StringBuilder();\n\t\t\tChildInfo collection = null;\n\t\t\tint childCount = children.Length;\n\t\t\tfor (int i = 0; i < children.Length; i++) {\n\t\t\t\tstring arg = children[i].Name;\n\t\t\t\tstring argProp = children[i].PropertyName;\n\t\t\t\tif (children[i].IsCollection && i + 1 == children.Length) {\n\t\t\t\t\tcollection = children[i];\n\t\t\t\t\tchildCount = children.Length - 1;\n\t\t\t\t\topCode.Flags.Add(argProp + \".Aggregate(InstructionFlags.None, (f, arg) => f | arg.Flags)\");\n\t\t\t\t\topCode.ConstructorParameters.Add(\"params ILInstruction[] \" + arg);\n\t\t\t\t\topCode.ConstructorBody.Add(\"this.\" + argProp + \" = new InstructionCollection<\" + children[i].Type + \">(this, \" + i + \");\");\n\t\t\t\t\topCode.ConstructorBody.Add(\"this.\" + argProp + \".AddRange(\" + arg + \");\");\n\t\t\t\t\topCode.PerformMatchConditions.Add(\"Patterns.ListMatch.DoMatch(this.\" + argProp + \", o.\" + argProp + \", ref match)\");\n\t\t\t\t\tif (i == 0)\n\t\t\t\t\t\topCode.WriteArguments.Add(\"bool first = true;\");\n\t\t\t\t\topCode.WriteArguments.Add(\"foreach (var \" + arg + \" in \" + argProp + \") {\");\n\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\topCode.WriteArguments.Add(\"\\toutput.Write(\\\", \\\");\");\n\t\t\t\t\telse\n\t\t\t\t\t\topCode.WriteArguments.Add(\"\\tif (!first) output.Write(\\\", \\\"); else first = false;\");\n\t\t\t\t\topCode.WriteArguments.Add(\"\\t\" + arg + \".WriteTo(output, options);\");\n\t\t\t\t\topCode.WriteArguments.Add(\"}\");\n\t\t\t\t\topCode.Members.Add(\"public static readonly SlotInfo \" + children[i].SlotName + \" = \" + children[i].GetSlotInit() + \";\");\n\t\t\t\t\topCode.Members.Add(\"public InstructionCollection<\" + children[i].Type + \"> \" + argProp + \" { get; private set; }\");\n\t\t\t\t} else {\n\t\t\t\t\topCode.Flags.Add(arg + \".Flags\");\n\t\t\t\t\topCode.ConstructorParameters.Add(\"ILInstruction \" + arg);\n\t\t\t\t\topCode.ConstructorBody.Add(\"this.\" + argProp + \" = \" + arg + \";\");\n\t\t\t\t\topCode.MatchParameters.Add(new MatchParamInfo { TypeName = \"ILInstruction\", Name = arg, FieldName = argProp });\n\t\t\t\t\topCode.PerformMatchConditions.Add(\"this.\" + arg + \".PerformMatch(o.\" + arg + \", ref match)\");\n\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\topCode.WriteArguments.Add(\"output.Write(\\\", \\\");\");\n\t\t\t\t\topCode.WriteArguments.Add(\"this.\" + arg + \".WriteTo(output, options);\");\n\t\t\t\t\topCode.Members.Add(\"public static readonly SlotInfo \" + children[i].SlotName + \" = \" + children[i].GetSlotInit() + \";\");\n\t\t\t\t\topCode.Members.Add(\"ILInstruction \" + arg + \" = null!;\");\n\t\t\t\t\topCode.Members.Add(\"public ILInstruction \" + argProp + \" {\" + Environment.NewLine\n\t\t\t\t\t\t+ \"\\tget { return this.\" + arg + \"; }\" + Environment.NewLine\n\t\t\t\t\t\t+ \"\\tset {\" + Environment.NewLine\n\t\t\t\t\t\t+ \"\\t\\tValidateChild(value);\" + Environment.NewLine\n\t\t\t\t\t\t+ \"\\t\\tSetChildInstruction(ref this.\" + arg + \", value, \" + i + \");\" + Environment.NewLine\n\t\t\t\t\t\t+ \"\\t}\" + Environment.NewLine\n\t\t\t\t\t\t+ \"}\");\n\t\t\t\t}\n\t\t\t\tif (children[i].ExpectedTypes?.Length > 0) {\n\t\t\t\t\tstring checkString = null;\n\t\t\t\t\tforeach (var expectedType in children[i].ExpectedTypes) {\n\t\t\t\t\t\tvar expectedTypeCode = expectedType;\n\t\t\t\t\t\tif (!expectedType.Contains(\".\"))\n\t\t\t\t\t\t\texpectedTypeCode = \"StackType.\" + expectedTypeCode;\n\t\t\t\t\t\tif (checkString != null)\n\t\t\t\t\t\t\tcheckString += \" || \";\n\t\t\t\t\t\tcheckString += arg + \".ResultType == \" + expectedTypeCode;\n\t\t\t\t\t}\n\t\t\t\t\topCode.Invariants.Add(\"DebugAssert(\" + checkString + \");\");\n\t\t\t\t}\n\t\t\t}\n\t\t\topCode.WriteArguments.Add(\"output.Write(')');\");\n\t\t\tStringBuilder b;\n\t\t\tb = new StringBuilder();\n\t\t\tb.AppendLine(\"protected sealed override int GetChildCount()\");\n\t\t\tb.AppendLine(\"{\");\n\t\t\tb.Append(\"\\treturn \");\n\t\t\tif (childCount > 0 || collection == null)\n\t\t\t\tb.Append(childCount);\n\t\t\tif (collection != null) {\n\t\t\t\tif (childCount > 0) b.Append(\" + \");\n\t\t\t\tb.Append(collection.PropertyName + \".Count\");\n\t\t\t}\n\t\t\tb.AppendLine(\";\");\n\t\t\tb.Append(\"}\");\n\t\t\topCode.Members.Add(b.ToString());\n\t\t\t\n\t\t\tb = new StringBuilder();\n\t\t\tb.AppendLine(\"protected sealed override ILInstruction GetChild(int index)\");\n\t\t\tb.AppendLine(\"{\");\n\t\t\tb.AppendLine(\"\\tswitch (index)\");\n\t\t\tb.AppendLine(\"\\t{\");\n\t\t\tfor (int i = 0; i < childCount; i++) {\n\t\t\t\tb.AppendLine(\"\\t\\tcase \" + i + \":\");\n\t\t\t\tb.AppendLine(\"\\t\\t\\treturn this.\" + children[i].Name + \";\");\n\t\t\t}\n\t\t\tb.AppendLine(\"\\t\\tdefault:\");\n\t\t\tif (collection == null)\n\t\t\t\tb.AppendLine(\"\\t\\t\\tthrow new IndexOutOfRangeException();\");\n\t\t\telse\n\t\t\t\tb.AppendLine(\"\\t\\t\\treturn this.\" + collection.PropertyName + \"[index - \" + childCount + \"];\");\n\t\t\tb.AppendLine(\"\\t}\");\n\t\t\tb.Append(\"}\");\n\t\t\topCode.Members.Add(b.ToString());\n\t\t\t\n\t\t\tb = new StringBuilder();\n\t\t\tb.AppendLine(\"protected sealed override void SetChild(int index, ILInstruction value)\");\n\t\t\tb.AppendLine(\"{\");\n\t\t\tb.AppendLine(\"\\tswitch (index)\");\n\t\t\tb.AppendLine(\"\\t{\");\n\t\t\tfor (int i = 0; i < childCount; i++) {\n\t\t\t\tb.AppendLine(\"\\t\\tcase \" + i + \":\");\n\t\t\t\tb.AppendLine(\"\\t\\t\\tthis.\" + children[i].PropertyName + \" = value;\");\n\t\t\t\tb.AppendLine(\"\\t\\t\\tbreak;\");\n\t\t\t}\n\t\t\tb.AppendLine(\"\\t\\tdefault:\");\n\t\t\tif (collection == null)\n\t\t\t\tb.AppendLine(\"\\t\\t\\tthrow new IndexOutOfRangeException();\");\n\t\t\telse {\n\t\t\t\tb.AppendLine(\"\\t\\t\\tthis.\" + collection.PropertyName + \"[index - \" + childCount + \"] = (\" + collection.Type + \")value;\");\n\t\t\t\tb.AppendLine(\"\\t\\t\\tbreak;\");\n\t\t\t}\n\t\t\tb.AppendLine(\"\\t}\");\n\t\t\tb.Append(\"}\");\n\t\t\topCode.Members.Add(b.ToString());\n\t\t\t\n\t\t\tb = new StringBuilder();\n\t\t\tb.AppendLine(\"protected sealed override SlotInfo GetChildSlot(int index)\");\n\t\t\tb.AppendLine(\"{\");\n\t\t\tb.AppendLine(\"\\tswitch (index)\");\n\t\t\tb.AppendLine(\"\\t{\");\n\t\t\tfor (int i = 0; i < childCount; i++) {\n\t\t\t\tb.AppendLine(\"\\t\\tcase \" + i + \":\");\n\t\t\t\tb.AppendLine(\"\\t\\t\\treturn \" + children[i].SlotName + \";\");\n\t\t\t}\n\t\t\tb.AppendLine(\"\\t\\tdefault:\");\n\t\t\tif (collection == null)\n\t\t\t\tb.AppendLine(\"\\t\\t\\tthrow new IndexOutOfRangeException();\");\n\t\t\telse\n\t\t\t\tb.AppendLine(\"\\t\\t\\treturn \" + collection.SlotName + \";\");\n\t\t\tb.AppendLine(\"\\t}\");\n\t\t\tb.Append(\"}\");\n\t\t\topCode.Members.Add(b.ToString());\n\t\t\t\n\t\t\tb = new StringBuilder();\n\t\t\tb.AppendLine(\"public sealed override ILInstruction Clone()\");\n\t\t\tb.AppendLine(\"{\");\n\t\t\tb.AppendLine(\"\\tvar clone = (\" + opCode.Name + \")ShallowClone();\");\n\t\t\tfor (int i = 0; i < children.Length; i++) {\n\t\t\t\tif (children[i].IsCollection) {\n\t\t\t\t\tb.AppendLine(\"\\tclone.\" + children[i].PropertyName + \" = new InstructionCollection<\" + children[i].Type + \">(clone, \" + i + \");\");\n\t\t\t\t\tb.AppendLine(\"\\tclone.\" + children[i].PropertyName + \".AddRange(this.\" + children[i].PropertyName + \".Select(arg => (\" + children[i].Type + \")arg.Clone()));\");\n\t\t\t\t} else {\n\t\t\t\t\tb.AppendLine(\"\\tclone.\" + children[i].PropertyName + \" = this.\" + children[i].Name + \".Clone();\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (opCode.Name == \"ILFunction\") {\n\t\t\t\tb.AppendLine(\"\\tclone.CloneVariables();\");\n\t\t\t}\n\t\t\tb.AppendLine(\"\\treturn clone;\");\n\t\t\tb.Append(\"}\");\n\t\t\topCode.Members.Add(b.ToString());\n\t\t};\n\t}\n\n\tstatic Action<OpCode> AbstractBaseClass = opCode => {\n\t\topCode.GenerateAcceptVisitor = false;\n\t\topCode.ClassModifiers = \"public abstract\";\n\t\topCode.ConstructorModifier = \"protected\";\n\t\topCode.ConstructorParameters.Add(\"OpCode opCode\");\n\t\topCode.BaseConstructorArguments.Add(\"opCode\");\n\t\topCode.GenerateMatch = false;\n\t\topCode.GeneratePerformMatch = false;\n\t};\n\n\t// SideEffect trait: the instruction has a non-local side effect\n\tstatic Action<OpCode> SideEffect = HasFlag(\"InstructionFlags.SideEffect\");\n\tstatic Action<OpCode> MemoryAccess = SideEffect;\n\t\n\t// Call trait: the instruction performs a method call\n\tstatic Action<OpCode> Call = opCode => {\n\t\topCode.BaseClass = \"CallInstruction\";\n\t\topCode.ConstructorParameters.Add(\"IMethod method\");\n\t\topCode.BaseConstructorArguments.Add(\"method\");\n\t\topCode.GenerateMatch = false;\n\t\topCode.GeneratePerformMatch = false;\n\t};\n\n\t// HasVariableOperand trait: the instruction refers to a local variable\n\tstatic Action<OpCode> HasVariableOperand(string accessType, bool generateCheckInvariant = true)\n\t{\n\t\tAction<OpCode> action = opCode => {\n\t\t\topCode.ConstructorParameters.Add(\"ILVariable variable\");\n\t\t\topCode.Members.Add(\"ILVariable variable;\");\n\t\t\topCode.ConstructorBody.Add(\"this.variable = variable ?? throw new ArgumentNullException(nameof(variable));\");\n\t\t\topCode.MatchParameters.Add(new MatchParamInfo { TypeName = \"ILVariable\", Name = \"variable\", FieldName = \"Variable\" });\n\t\t\topCode.PerformMatchConditions.Add(\"variable == o.variable\");\n\t\t\topCode.GenerateWriteTo = true;\n\t\t\topCode.WriteOperand.Add(\"output.Write(' ');\");\n\t\t\topCode.WriteOperand.Add(\"variable.WriteTo(output);\");\n\t\t\topCode.Interfaces.Add(\"I\" + accessType + \"Instruction\");\n\t\t\topCode.Members.Add(@\"public ILVariable Variable {\n\tget { return variable; }\n\tset {\n\t\tDebugAssert(value != null);\n\t\tif (IsConnected)\n\t\t\tvariable.RemoveAccessInstruction(this);\n\t\tvariable = value;\n\t\tif (IsConnected)\n\t\t\tvariable.AddAccessInstruction(this);\n\t}\n}\n\npublic int IndexInAccessInstructionList { get; set; } = -1;\n\nint IInstructionWithVariableOperand.IndexInVariableInstructionMapping {\n\tget { return ((IAccessInstruction)this).IndexInAccessInstructionList; }\n\tset { ((IAccessInstruction)this).IndexInAccessInstructionList = value; }\n}\n\nprotected override void Connected()\n{\n\tbase.Connected();\n\tvariable.AddAccessInstruction(this);\n}\n\nprotected override void Disconnected()\n{\n\tvariable.RemoveAccessInstruction(this);\n\tbase.Disconnected();\n}\n\".Replace(\"Access\", accessType));\n\t\t\tif (generateCheckInvariant) {\n\t\t\t\topCode.Invariants.Add(\"DebugAssert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function!));\");\n\t\t\t\topCode.Invariants.Add(\"DebugAssert(phase <= ILPhase.InILReader || variable.Function!.Variables[variable.IndexInFunction] == variable);\");\n\t\t\t}\n\t\t};\n\t\tif (accessType == \"Load\") {\n\t\t\taction += HasFlag(\"InstructionFlags.MayReadLocals\");\n\t\t} else if (accessType == \"Store\") {\n\t\t\taction += HasFlag(\"InstructionFlags.MayWriteLocals\");\n\t\t} else {\n\t\t\tif (accessType != \"Address\")\n\t\t\t\tthrow new ArgumentException();\n\t\t} \n\t\treturn action;\n\t}\n\t\n\tstatic Action<OpCode> HasFieldOperand = opCode => {\n\t\topCode.ConstructorParameters.Add(\"IField @field\");\n\t\topCode.Members.Add(\"readonly IField @field;\");\n\t\topCode.ConstructorBody.Add(\"this.@field = @field;\");\n\t\topCode.MatchParameters.Add(new MatchParamInfo { TypeName = \"IField\", Name = \"@field\", FieldName = \"Field\" });\n\t\topCode.PerformMatchConditions.Add(\"@field.Equals(o.@field)\");\n\t\topCode.Members.Add(\"/// <summary>Returns the field operand.</summary>\" + Environment.NewLine\n\t\t\t\t\t\t+ \"public IField Field { get { return @field; } }\");\n\t\topCode.GenerateWriteTo = true;\n\t\topCode.WriteOperand.Add(\"output.Write(' ');\");\n\t\topCode.WriteOperand.Add(\"@field.WriteTo(output);\");\n\t\topCode.Interfaces.Add(\"IInstructionWithFieldOperand\");\n\t};\n\n\tstatic Action<OpCode> HasTypeOperand = opCode => {\n\t\topCode.ConstructorParameters.Add(\"IType type\");\n\t\topCode.Members.Add(\"IType type;\");\n\t\topCode.ConstructorBody.Add(\"this.type = type;\");\n\t\topCode.MatchParameters.Add(new MatchParamInfo { TypeName = \"IType\", Name = \"type\", FieldName = \"Type\" });\n\t\topCode.PerformMatchConditions.Add(\"type.Equals(o.type)\");\n\t\topCode.Members.Add(\"/// <summary>Returns the type operand.</summary>\" + Environment.NewLine\n\t\t\t\t\t\t+ \"public IType Type {\" + Environment.NewLine\n\t\t\t\t\t\t+ \"\\tget { return type; }\" + Environment.NewLine\n\t\t\t\t\t\t+ \"\\tset { type = value; InvalidateFlags(); }\" + Environment.NewLine\n\t\t\t\t\t\t+ \"}\");\n\t\topCode.GenerateWriteTo = true;\n\t\topCode.WriteOperand.Add(\"output.Write(' ');\");\n\t\topCode.WriteOperand.Add(\"type.WriteTo(output);\");\n\t};\n\n\tstatic Action<OpCode> HasMethodOperand(bool nullable = false)\n\t{\n\t\treturn opCode => {\n\t\t\tstring n = nullable ? \"?\" : \"\";\n\t\t\topCode.ConstructorParameters.Add($\"IMethod{n} method\");\n\t\t\topCode.Members.Add($\"readonly IMethod{n} method;\");\n\t\t\topCode.ConstructorBody.Add(\"this.method = method;\");\n\t\t\topCode.MatchParameters.Add(new MatchParamInfo { TypeName = $\"IMethod{n}\", Name = \"method\", FieldName = \"Method\", IsReferenceType = !nullable });\n\t\t\topCode.PerformMatchConditions.Add(\"object.Equals(method, o.method)\");\n\t\t\topCode.Members.Add(\"/// <summary>Returns the method operand.</summary>\" + Environment.NewLine\n\t\t\t\t\t\t\t+ $\"public IMethod{n} Method => method;\");\n\t\t\topCode.GenerateWriteTo = true;\n\t\t\topCode.WriteOperand.Add(\"if (method != null)\");\n\t\t\topCode.WriteOperand.Add(\"{\");\n\t\t\topCode.WriteOperand.Add(\"\\toutput.Write(' ');\");\n\t\t\topCode.WriteOperand.Add(\"\\tmethod.WriteTo(output);\");\n\t\t\topCode.WriteOperand.Add(\"}\");\n\t\t\topCode.Interfaces.Add(\"IInstructionWithMethodOperand\");\n\t\t};\n\t}\n\n\tstatic Action<OpCode> HasMemberOperand = opCode => {\n\t\topCode.ConstructorParameters.Add(\"IMember member\");\n\t\topCode.Members.Add(\"readonly IMember member;\");\n\t\topCode.ConstructorBody.Add(\"this.member = member;\");\n\t\topCode.MatchParameters.Add(new MatchParamInfo { TypeName = \"IMember\", Name = \"member\", FieldName = \"Member\" });\n\t\topCode.PerformMatchConditions.Add(\"member.Equals(o.member)\");\n\t\topCode.Members.Add(\"/// <summary>Returns the token operand.</summary>\" + Environment.NewLine\n\t\t\t\t\t\t+ \"public IMember Member { get { return member; } }\");\n\t\topCode.GenerateWriteTo = true;\n\t\topCode.WriteOperand.Add(\"output.Write(' ');\");\n\t\topCode.WriteOperand.Add(\"member.WriteTo(output);\");\n\t};\n\t\n\t// Adds a member of type bool to the instruction.\n\tstatic Action<OpCode> BoolFlag(string flagName)\n\t{\n\t\treturn opCode => {\n\t\t\topCode.PerformMatchConditions.Add($\"this.{flagName} == o.{flagName}\");\n\t\t\topCode.Members.Add($\"public bool {flagName};\");\n\t\t\topCode.GenerateWriteTo = true;\n\t\t\topCode.WriteOpCodePrefix.Add($\"if ({flagName}){Environment.NewLine}\\toutput.Write(\\\"{flagName.ToLowerInvariant()}.\\\");\");\n\t\t};\n\t}\n\t\n\t// LoadConstant trait: the instruction loads a compile-time constant. Implies NoArguments.\n\tstatic Action<OpCode> LoadConstant(string operandType)\n\t{\n\t\treturn opCode => {\n\t\t\tNoArguments(opCode);\n\t\t\topCode.ConstructorParameters.Add(operandType + \" value\");\n\t\t\topCode.MatchParameters.Add(new MatchParamInfo {\n\t\t\t\tTypeName = operandType,\n\t\t\t\tName = \"value\",\n\t\t\t\tFieldName = \"Value\",\n\t\t\t\tIsReferenceType = operandType == \"string\"\n\t\t\t});\n\t\t\topCode.PerformMatchConditions.Add(\"this.Value == o.Value\");\n\t\t\topCode.Members.Add(\"public readonly \" + operandType + \" Value;\");\n\t\t\topCode.ConstructorBody.Add(\"this.Value = value;\");\n\t\t\topCode.GenerateWriteTo = true;\n\t\t\topCode.WriteOperand.Add(\"output.Write(' ');\");\n\t\t\topCode.WriteOperand.Add(\"Disassembler.DisassemblerHelpers.WriteOperand(output, Value);\");\n\t\t};\n\t}\n\t\n\tstatic Action<OpCode> SupportsVolatilePrefix = opCode => {\n\t\topCode.Interfaces.Add(\"ISupportsVolatilePrefix\");\n\t\topCode.Members.Add(\"/// <summary>Gets/Sets whether the memory access is volatile.</summary>\" + Environment.NewLine\n\t\t\t\t\t\t+ \"public bool IsVolatile { get; set; }\");\n\t\topCode.GenerateWriteTo = true;\n\t\topCode.WriteOpCodePrefix.Add(\"if (IsVolatile)\" + Environment.NewLine + \"\\toutput.Write(\\\"volatile.\\\");\");\n\t\topCode.PerformMatchConditions.Add(\"IsVolatile == o.IsVolatile\");\n\t};\n\t\n\tstatic Action<OpCode> SupportsUnalignedPrefix = opCode => {\n\t\topCode.Interfaces.Add(\"ISupportsUnalignedPrefix\");\n\t\topCode.Members.Add(\"/// <summary>Returns the alignment specified by the 'unaligned' prefix; or 0 if there was no 'unaligned' prefix.</summary>\" + Environment.NewLine\n\t\t\t\t\t\t+ \"public byte UnalignedPrefix { get; set; }\");\n\t\topCode.GenerateWriteTo = true;\n\t\topCode.WriteOpCodePrefix.Add(\"if (UnalignedPrefix > 0)\" + Environment.NewLine + \"\\toutput.Write(\\\"unaligned(\\\" + UnalignedPrefix + \\\").\\\");\");\n\t\topCode.PerformMatchConditions.Add(\"UnalignedPrefix == o.UnalignedPrefix\");\n\t};\n\t\n\tstatic Action<OpCode> SupportsReadonlyPrefix = opCode => {\n\t\topCode.Members.Add(\"/// <summary>Gets whether the 'readonly' prefix was applied to this instruction.</summary>\" + Environment.NewLine\n\t\t\t\t\t\t+ \"public bool IsReadOnly { get; set; }\");\n\t\topCode.GenerateWriteTo = true;\n\t\topCode.WriteOpCodePrefix.Add(\"if (IsReadOnly)\" + Environment.NewLine + \"\\toutput.Write(\\\"readonly.\\\");\");\n\t\topCode.PerformMatchConditions.Add(\"IsReadOnly == o.IsReadOnly\");\n\t};\n\t\n\tstatic Action<OpCode> CustomInvariant(string code)\n\t{\n\t\treturn opCode => {\n\t\t\topCode.Invariants.Add(code);\n\t\t};\n\t}\n\n\tstatic Action<OpCode> Pattern = opCode => {\n\t\tBaseClass(\"PatternInstruction\")(opCode);\n\t\topCode.Namespace = \"ICSharpCode.Decompiler.IL.Patterns\";\n\t\topCode.GenerateAcceptVisitor = false;\n\t\topCode.GenerateMatch = false;\n\t\topCode.GeneratePerformMatch = false;\n\t};\n\n\tstatic Action<OpCode> Dynamic = BaseClass(\"DynamicInstruction\") + MayThrow + SideEffect + CustomConstructor;\n#>"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Patterns/AnyNode.cs",
    "content": "#nullable enable\nusing System;\n\nnamespace ICSharpCode.Decompiler.IL.Patterns\n{\n\tpartial class PatternInstruction : ILInstruction\n\t{\n\t\tpublic override void AcceptVisitor(ILVisitor visitor)\n\t\t{\n\t\t\tthrow new NotSupportedException();\n\t\t}\n\n\t\tpublic override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)\n\t\t{\n\t\t\tthrow new NotSupportedException();\n\t\t}\n\n\t\tpublic override T AcceptVisitor<T>(ILVisitor<T> visitor)\n\t\t{\n\t\t\tthrow new NotSupportedException();\n\t\t}\n\n\t\tprotected override InstructionFlags ComputeFlags()\n\t\t{\n\t\t\tthrow new NotSupportedException();\n\t\t}\n\n\t\tpublic override InstructionFlags DirectFlags {\n\t\t\tget {\n\t\t\t\tthrow new NotSupportedException();\n\t\t\t}\n\t\t}\n\t}\n\n\tpartial class AnyNode : PatternInstruction\n\t{\n\t\tCaptureGroup? group;\n\n\t\tpublic AnyNode(CaptureGroup? group = null)\n\t\t\t: base(OpCode.AnyNode)\n\t\t{\n\t\t\tthis.group = group;\n\t\t}\n\n\t\tprotected internal override bool PerformMatch(ILInstruction? other, ref Match match)\n\t\t{\n\t\t\tif (other == null)\n\t\t\t\treturn false;\n\t\t\tif (group != null)\n\t\t\t\tmatch.Add(group, other);\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Patterns/ListMatch.cs",
    "content": "#nullable enable\n// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.IL.Patterns\n{\n\t/// <summary>\n\t/// Data holder for a single list matching operation.\n\t/// </summary>\n\t/// <remarks>\n\t/// Notes on backtracking:\n\t/// PerformMatch() may save backtracking-savepoints to the ListMatch instance.\n\t/// Each backtracking-savepoints is a Stack{int} with instructions of how to restore the saved state.\n\t/// When a savepoint is created by a PerformMatch() call, that call may be nested in several other PerformMatch() calls that operate on\n\t/// the same list.\n\t/// When leaving those calls (whether with a successful match or not), the outer PerformMatch() calls may push additional state onto\n\t/// all of the added backtracking-savepoints.\n\t/// When the overall list match fails but savepoints exists, the most recently added savepoint is restored by calling PerformMatch()\n\t/// with listMatch.restoreStack set to that savepoint. Each PerformMatch() call must pop its state from that stack before\n\t/// recursively calling its child patterns.\n\t/// </remarks>\n\tpublic struct ListMatch\n\t{\n\t\t/// <summary>\n\t\t/// The main list matching logic.\n\t\t/// </summary>\n\t\t/// <returns>Returns whether the list match was successful.\n\t\t/// If the method returns true, it adds the capture groups (if any) to the match.\n\t\t/// If the method returns false, the match object remains in a partially-updated state and needs to be restored\n\t\t/// before it can be reused.</returns>\n\t\tinternal static bool DoMatch(IReadOnlyList<ILInstruction> patterns, IReadOnlyList<ILInstruction?> syntaxList, ref Match match)\n\t\t{\n\t\t\tListMatch listMatch = new ListMatch(syntaxList);\n\t\t\tdo\n\t\t\t{\n\t\t\t\tif (PerformMatchSequence(patterns, ref listMatch, ref match))\n\t\t\t\t{\n\t\t\t\t\t// If we have a successful match and it matches the whole list,\n\t\t\t\t\t// we are done.\n\t\t\t\t\tif (listMatch.SyntaxIndex == syntaxList.Count)\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\t// Otherwise, restore a savepoint created by PerformMatch() and resume the matching logic at that savepoint.\n\t\t\t} while (listMatch.RestoreSavePoint(ref match));\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// PerformMatch() for a sequence of patterns.\n\t\t/// </summary>\n\t\t/// <param name=\"patterns\">List of patterns to match.</param>\n\t\t/// <param name=\"listMatch\">Stores state about the current list match.</param>\n\t\t/// <param name=\"match\">The match object, used to store global state during the match (such as the results of capture groups).</param>\n\t\t/// <returns>Returns whether all patterns were matched successfully against a part of the list.\n\t\t/// If the method returns true, it updates listMatch.SyntaxIndex to point to the next node that was not part of the match,\n\t\t/// and adds the capture groups (if any) to the match.\n\t\t/// If the method returns false, the listMatch and match objects remain in a partially-updated state and need to be restored\n\t\t/// before they can be reused.</returns>\n\t\tinternal static bool PerformMatchSequence(IReadOnlyList<ILInstruction> patterns, ref ListMatch listMatch, ref Match match)\n\t\t{\n\t\t\t// The patterns may create savepoints, so we need to save the 'i' variable\n\t\t\t// as part of those checkpoints.\n\t\t\tfor (int i = listMatch.PopFromSavePoint() ?? 0; i < patterns.Count; i++)\n\t\t\t{\n\t\t\t\tint startMarker = listMatch.GetSavePointStartMarker();\n\t\t\t\tbool success = patterns[i].PerformMatch(ref listMatch, ref match);\n\t\t\t\tlistMatch.PushToSavePoints(startMarker, i);\n\t\t\t\tif (!success)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// A savepoint that the list matching operation can be restored from.\n\t\t/// </summary>\n\t\tstruct SavePoint\n\t\t{\n\t\t\tinternal readonly int CheckPoint;\n\t\t\tinternal readonly int SyntaxIndex;\n\t\t\tinternal readonly Stack<int> stack;\n\n\t\t\tpublic SavePoint(int checkpoint, int syntaxIndex)\n\t\t\t{\n\t\t\t\tthis.CheckPoint = checkpoint;\n\t\t\t\tthis.SyntaxIndex = syntaxIndex;\n\t\t\t\tthis.stack = new Stack<int>();\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// The syntax list we are matching against.\n\t\t/// </summary>\n\t\tinternal readonly IReadOnlyList<ILInstruction?> SyntaxList;\n\n\t\t/// <summary>\n\t\t/// The current index in the syntax list.\n\t\t/// </summary>\n\t\tinternal int SyntaxIndex;\n\n\t\tListMatch(IReadOnlyList<ILInstruction?> syntaxList)\n\t\t{\n\t\t\tthis.SyntaxList = syntaxList;\n\t\t\tthis.SyntaxIndex = 0;\n\t\t\tthis.backtrackingStack = null;\n\t\t\tthis.restoreStack = null;\n\t\t}\n\n\t\tList<SavePoint>? backtrackingStack;\n\t\tStack<int>? restoreStack;\n\n\t\tvoid AddSavePoint(SavePoint savepoint)\n\t\t{\n\t\t\tif (backtrackingStack == null)\n\t\t\t\tbacktrackingStack = new List<SavePoint>();\n\t\t\tbacktrackingStack.Add(savepoint);\n\t\t}\n\n\t\tinternal void AddSavePoint(ref Match match, int data)\n\t\t{\n\t\t\tvar savepoint = new SavePoint(match.CheckPoint(), this.SyntaxIndex);\n\t\t\tsavepoint.stack.Push(data);\n\t\t\tAddSavePoint(savepoint);\n\t\t}\n\n\t\tinternal int GetSavePointStartMarker()\n\t\t{\n\t\t\treturn backtrackingStack != null ? backtrackingStack.Count : 0;\n\t\t}\n\n\t\tinternal void PushToSavePoints(int startMarker, int data)\n\t\t{\n\t\t\tif (backtrackingStack == null)\n\t\t\t\treturn;\n\t\t\tfor (int i = startMarker; i < backtrackingStack.Count; i++)\n\t\t\t{\n\t\t\t\tbacktrackingStack[i].stack.Push(data);\n\t\t\t}\n\t\t}\n\n\t\tinternal int? PopFromSavePoint()\n\t\t{\n\t\t\tif (restoreStack == null || restoreStack.Count == 0)\n\t\t\t\treturn null;\n\t\t\treturn restoreStack.Pop();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Restores the listmatch state from a savepoint.\n\t\t/// </summary>\n\t\t/// <returns>Returns whether a savepoint exists</returns>\n\t\tinternal bool RestoreSavePoint(ref Match match)\n\t\t{\n\t\t\tif (backtrackingStack == null || backtrackingStack.Count == 0)\n\t\t\t\treturn false;\n\t\t\tvar savepoint = backtrackingStack[backtrackingStack.Count - 1];\n\t\t\tbacktrackingStack.RemoveAt(backtrackingStack.Count - 1);\n\t\t\tmatch.RestoreCheckPoint(savepoint.CheckPoint);\n\t\t\tthis.SyntaxIndex = savepoint.SyntaxIndex;\n\t\t\trestoreStack = savepoint.stack;\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Patterns/Match.cs",
    "content": "#nullable enable\n// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.IL.Patterns\n{\n\tpublic class CaptureGroup { }\n\n\t/// <summary>\n\t/// Data holder for the overall pattern matching operation.\n\t/// </summary>\n\t/// <remarks>\n\t/// This type is a struct in order to prevent unnecessary memory allocations during pattern matching.\n\t/// The default value <c>default(Match)</c> represents an unsuccessful match.\n\t/// </remarks>\n\tpublic struct Match\n\t{\n\t\tstatic readonly List<KeyValuePair<CaptureGroup, ILInstruction>> emptyResults = new List<KeyValuePair<CaptureGroup, ILInstruction>>();\n\n\t\tList<KeyValuePair<CaptureGroup, ILInstruction>>? results;\n\n\t\t/// <summary>\n\t\t/// Gets whether the match was successful.\n\t\t/// </summary>\n\t\tpublic bool Success {\n\t\t\tget {\n\t\t\t\treturn results != null;\n\t\t\t}\n\t\t\tinternal set {\n\t\t\t\tif (value)\n\t\t\t\t{\n\t\t\t\t\tif (results == null)\n\t\t\t\t\t\tresults = emptyResults;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tresults = null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the match was successful.\n\t\t/// </summary>\n\t\tpublic static bool operator true(Match m)\n\t\t{\n\t\t\treturn m.Success;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the match failed.\n\t\t/// </summary>\n\t\tpublic static bool operator false(Match m)\n\t\t{\n\t\t\treturn !m.Success;\n\t\t}\n\n\t\tinternal void Add(CaptureGroup g, ILInstruction n)\n\t\t{\n\t\t\tif (results == null)\n\t\t\t\tresults = new List<KeyValuePair<CaptureGroup, ILInstruction>>();\n\t\t\tresults.Add(new KeyValuePair<CaptureGroup, ILInstruction>(g, n));\n\t\t}\n\n\t\tinternal int CheckPoint()\n\t\t{\n\t\t\treturn results != null ? results.Count : 0;\n\t\t}\n\n\t\tinternal void RestoreCheckPoint(int checkPoint)\n\t\t{\n\t\t\tif (results != null)\n\t\t\t\tresults.RemoveRange(checkPoint, results.Count - checkPoint);\n\t\t}\n\n\t\tpublic IEnumerable<ILInstruction> Get(CaptureGroup captureGroup)\n\t\t{\n\t\t\tif (results != null)\n\t\t\t{\n\t\t\t\tforeach (var pair in results)\n\t\t\t\t{\n\t\t\t\t\tif (pair.Key == captureGroup)\n\t\t\t\t\t\tyield return pair.Value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/PointerArithmeticOffset.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// Analyses the RHS of a 'ptr + int' or 'ptr - int' operation.\n\t/// </summary>\n\tstruct PointerArithmeticOffset\n\t{\n\t\t/// <summary>\n\t\t/// Given an instruction that computes a pointer arithmetic offset in bytes,\n\t\t/// returns an instruction that computes the same offset in number of elements.\n\t\t/// \n\t\t/// Returns null if no such instruction can be found.\n\t\t/// </summary>\n\t\t/// <param name=\"byteOffsetInst\">Input instruction.</param>\n\t\t/// <param name=\"pointerElementType\">The target type of the pointer type.</param>\n\t\t/// <param name=\"checkForOverflow\">Whether the pointer arithmetic operation checks for overflow.</param>\n\t\t/// <param name=\"unwrapZeroExtension\">Whether to allow zero extensions in the mul argument.</param>\n\t\tpublic static ILInstruction Detect(ILInstruction byteOffsetInst, IType pointerElementType,\n\t\t\tbool checkForOverflow,\n\t\t\tbool unwrapZeroExtension = false)\n\t\t{\n\t\t\tif (pointerElementType == null)\n\t\t\t\treturn null;\n\t\t\tif (byteOffsetInst is Conv conv && conv.InputType == StackType.I8 && conv.ResultType == StackType.I)\n\t\t\t{\n\t\t\t\tbyteOffsetInst = conv.Argument;\n\t\t\t}\n\t\t\tint? elementSize = ComputeSizeOf(pointerElementType);\n\t\t\tif (elementSize == 1)\n\t\t\t{\n\t\t\t\treturn byteOffsetInst;\n\t\t\t}\n\t\t\telse if (byteOffsetInst is BinaryNumericInstruction mul && mul.Operator == BinaryNumericOperator.Mul)\n\t\t\t{\n\t\t\t\tif (mul.IsLifted)\n\t\t\t\t\treturn null;\n\t\t\t\tif (mul.CheckForOverflow != checkForOverflow)\n\t\t\t\t\treturn null;\n\t\t\t\tif (elementSize > 0 && mul.Right.MatchLdcI(elementSize.Value)\n\t\t\t\t\t|| mul.Right.UnwrapConv(ConversionKind.SignExtend) is SizeOf sizeOf && NormalizeTypeVisitor.TypeErasure.EquivalentTypes(sizeOf.Type, pointerElementType))\n\t\t\t\t{\n\t\t\t\t\tvar countOffsetInst = mul.Left;\n\t\t\t\t\tif (unwrapZeroExtension)\n\t\t\t\t\t{\n\t\t\t\t\t\tcountOffsetInst = countOffsetInst.UnwrapConv(ConversionKind.ZeroExtend);\n\t\t\t\t\t}\n\t\t\t\t\treturn countOffsetInst;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (byteOffsetInst.UnwrapConv(ConversionKind.SignExtend) is SizeOf sizeOf && sizeOf.Type.Equals(pointerElementType))\n\t\t\t{\n\t\t\t\treturn new LdcI4(1).WithILRange(byteOffsetInst);\n\t\t\t}\n\t\t\telse if (byteOffsetInst.MatchLdcI(out long val))\n\t\t\t{\n\t\t\t\t// If the offset is a constant, it's possible that the compiler\n\t\t\t\t// constant-folded the multiplication.\n\t\t\t\tif (elementSize > 0 && (val % elementSize == 0) && val > 0)\n\t\t\t\t{\n\t\t\t\t\tval /= elementSize.Value;\n\t\t\t\t\tif (val <= int.MaxValue)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new LdcI4((int)val).WithILRange(byteOffsetInst);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static int? ComputeSizeOf(IType type)\n\t\t{\n\t\t\tswitch (type.GetEnumUnderlyingType().GetDefinition()?.KnownTypeCode)\n\t\t\t{\n\t\t\t\tcase KnownTypeCode.Boolean:\n\t\t\t\tcase KnownTypeCode.SByte:\n\t\t\t\tcase KnownTypeCode.Byte:\n\t\t\t\t\treturn 1;\n\t\t\t\tcase KnownTypeCode.Char:\n\t\t\t\tcase KnownTypeCode.Int16:\n\t\t\t\tcase KnownTypeCode.UInt16:\n\t\t\t\t\treturn 2;\n\t\t\t\tcase KnownTypeCode.Int32:\n\t\t\t\tcase KnownTypeCode.UInt32:\n\t\t\t\tcase KnownTypeCode.Single:\n\t\t\t\t\treturn 4;\n\t\t\t\tcase KnownTypeCode.Int64:\n\t\t\t\tcase KnownTypeCode.UInt64:\n\t\t\t\tcase KnownTypeCode.Double:\n\t\t\t\t\treturn 8;\n\t\t\t\tcase KnownTypeCode.Decimal:\n\t\t\t\t\treturn 16;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns true if <c>inst</c> computes the address of a fixed variable; false if it computes the address of a moveable variable.\n\t\t/// (see \"Fixed and moveable variables\" in the C# specification)\n\t\t/// </summary>\n\t\tinternal static bool IsFixedVariable(ILInstruction inst)\n\t\t{\n\t\t\tswitch (inst)\n\t\t\t{\n\t\t\t\tcase LdLoca ldloca:\n\t\t\t\t\treturn ldloca.Variable.CaptureScope == null; // locals are fixed if uncaptured\n\t\t\t\tcase LdFlda ldflda:\n\t\t\t\t\treturn IsFixedVariable(ldflda.Target);\n\t\t\t\tdefault:\n\t\t\t\t\treturn inst.ResultType == StackType.I;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/PrimitiveType.cs",
    "content": "#nullable enable\n// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpublic enum PrimitiveType : byte\n\t{\n\t\tNone,\n\t\tI1 = PrimitiveTypeCode.SByte,\n\t\tI2 = PrimitiveTypeCode.Int16,\n\t\tI4 = PrimitiveTypeCode.Int32,\n\t\tI8 = PrimitiveTypeCode.Int64,\n\t\tR4 = PrimitiveTypeCode.Single,\n\t\tR8 = PrimitiveTypeCode.Double,\n\t\tU1 = PrimitiveTypeCode.Byte,\n\t\tU2 = PrimitiveTypeCode.UInt16,\n\t\tU4 = PrimitiveTypeCode.UInt32,\n\t\tU8 = PrimitiveTypeCode.UInt64,\n\t\tI = PrimitiveTypeCode.IntPtr,\n\t\tU = PrimitiveTypeCode.UIntPtr,\n\t\t/// <summary>Managed reference</summary>\n\t\tRef = 16,\n\t\t/// <summary>Floating point type of unspecified size:\n\t\t/// usually 80 bits on x86 (when the runtime uses x87 instructions);\n\t\t/// but only 64-bit on x64.\n\t\t/// This only occurs for \"conv.r.un\" instructions. The C# compiler usually follows those\n\t\t/// with a \"conv.r4\" or \"conv.r8\" instruction to indicate the desired float type, so\n\t\t/// we only use this as conversion target type and don't bother tracking it as its own stack type:\n\t\t/// basically everything treats R identical to R8, except for the (conv.r.un + conv.r[48] => conv.r[48].un)\n\t\t/// combining logic which should not combine (conv.r.un + conv.r8 + conv.r4) into a single conv.r4.un.\n\t\t/// </summary>\n\t\tR = 254,\n\t\tUnknown = 255\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/SemanticHelper.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tstatic class SemanticHelper\n\t{\n\t\tinternal static InstructionFlags CombineBranches(InstructionFlags trueFlags, InstructionFlags falseFlags)\n\t\t{\n\t\t\t// the endpoint of the 'if' is only unreachable if both branches have an unreachable endpoint\n\t\t\tconst InstructionFlags combineWithAnd = InstructionFlags.EndPointUnreachable;\n\t\t\treturn (trueFlags & falseFlags) | ((trueFlags | falseFlags) & ~combineWithAnd);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether instruction is pure:\n\t\t/// * must not have side effects\n\t\t/// * must not throw exceptions\n\t\t/// * must not branch\n\t\t/// </summary>\n\t\tinternal static bool IsPure(InstructionFlags inst)\n\t\t{\n\t\t\t// ControlFlow is fine: internal control flow is pure as long as it's not an infinite loop,\n\t\t\t// and infinite loops are impossible without MayBranch.\n\t\t\tconst InstructionFlags pureFlags = InstructionFlags.MayReadLocals | InstructionFlags.ControlFlow;\n\t\t\treturn (inst & ~pureFlags) == 0;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the instruction sequence 'inst1; inst2;' may be ordered to 'inst2; inst1;'\n\t\t/// </summary>\n\t\tinternal static bool MayReorder(ILInstruction inst1, ILInstruction inst2)\n\t\t{\n\t\t\t// If both instructions perform an impure action, we cannot reorder them\n\t\t\tif (!IsPure(inst1.Flags) && !IsPure(inst2.Flags))\n\t\t\t\treturn false;\n\t\t\t// We cannot reorder if inst2 might write what inst1 looks at\n\t\t\tif (Inst2MightWriteToVariableReadByInst1(inst1, inst2))\n\t\t\t\treturn false;\n\t\t\t// and the same in reverse:\n\t\t\tif (Inst2MightWriteToVariableReadByInst1(inst2, inst1))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic bool Inst2MightWriteToVariableReadByInst1(ILInstruction inst1, ILInstruction inst2)\n\t\t{\n\t\t\tif (!inst1.HasFlag(InstructionFlags.MayReadLocals))\n\t\t\t{\n\t\t\t\t// quick exit if inst1 doesn't read any variables\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar variables = inst1.Descendants.OfType<LdLoc>().Select(load => load.Variable).ToHashSet();\n\t\t\tif (inst2.HasFlag(InstructionFlags.SideEffect) && variables.Any(v => v.AddressCount > 0))\n\t\t\t{\n\t\t\t\t// If inst2 might have indirect writes, we cannot reorder with any loads of variables that have their address taken.\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tforeach (var inst in inst2.Descendants)\n\t\t\t{\n\t\t\t\tif (inst.HasDirectFlag(InstructionFlags.MayWriteLocals))\n\t\t\t\t{\n\t\t\t\t\tILVariable v = ((IInstructionWithVariableOperand)inst).Variable;\n\t\t\t\t\tif (variables.Contains(v))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/SlotInfo.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// Holds information about the role of an instruction within its parent instruction.\n\t/// </summary>\n\tpublic class SlotInfo\n\t{\n\t\tpublic static SlotInfo None = new SlotInfo(\"<no slot>\");\n\n\t\t/// <summary>\n\t\t/// Gets the name of the slot.\n\t\t/// </summary>\n\t\tpublic readonly string Name;\n\n\t\t/// <summary>\n\t\t/// Gets whether it is possible to inline into this slot.\n\t\t/// </summary>\n\t\tpublic readonly bool CanInlineInto;\n\n\t\t/// <summary>\n\t\t/// Gets whether this slot belongs to a collection.\n\t\t/// </summary>\n\t\tpublic readonly bool IsCollection;\n\n\t\tpublic SlotInfo(string name, bool canInlineInto = false, bool isCollection = false)\n\t\t{\n\t\t\tthis.IsCollection = isCollection;\n\t\t\tthis.Name = name;\n\t\t\tthis.CanInlineInto = canInlineInto;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn Name;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/StackType.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// A type for the purpose of stack analysis.\n\t/// </summary>\n\tpublic enum StackType : byte\n\t{\n\t\t// Note: the numeric of these enum members is relevant for ILReader.MergeStacks:\n\t\t// when two branches meet where a stack slot has different types, the type after\n\t\t// the branch is the one with the higher numeric value.\n\n\t\t/// <summary>\n\t\t/// The stack type is unknown; for example a call returning an unknown type\n\t\t/// because an assembly reference isn't loaded.\n\t\t/// Can also occur with invalid IL.\n\t\t/// </summary>\n\t\tUnknown,\n\t\t/// <summary>32-bit integer</summary>\n\t\t/// <remarks>\n\t\t/// Used for C# <c>int</c>, <c>uint</c>,\n\t\t/// C# small integer types <c>byte</c>, <c>sbyte</c>, <c>short</c>, <c>ushort</c>,\n\t\t/// <c>bool</c> and <c>char</c>,\n\t\t/// and any enums with one of the above as underlying type.\n\t\t/// </remarks>\n\t\tI4,\n\t\t/// <summary>native-size integer, or unmanaged pointer</summary>\n\t\t/// <remarks>\n\t\t/// Used for C# <c>IntPtr</c>, <c>UIntPtr</c> and any native pointer types (<c>void*</c> etc.)\n\t\t/// Also used for IL function pointer types.\n\t\t/// </remarks>\n\t\tI,\n\t\t/// <summary>64-bit integer</summary>\n\t\t/// <remarks>\n\t\t/// Used for C# <c>long</c>, <c>ulong</c>,\n\t\t/// and any enums with one of the above as underlying type.\n\t\t/// </remarks>\n\t\tI8,\n\t\t/// <summary>32-bit floating point number</summary>\n\t\t/// <remarks>\n\t\t/// Used for C# <c>float</c>.\n\t\t/// </remarks>\n\t\tF4,\n\t\t/// <summary>64-bit floating point number</summary>\n\t\t/// <remarks>\n\t\t/// Used for C# <c>double</c>.\n\t\t/// </remarks>\n\t\tF8,\n\t\t/// <summary>Another stack type. Includes objects, value types, ...</summary>\n\t\tO,\n\t\t/// <summary>A managed pointer</summary>\n\t\tRef,\n\t\t/// <summary>Represents the lack of a stack slot</summary>\n\t\tVoid\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs",
    "content": "// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\n\nusing Humanizer.Inflections;\n\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\nusing ICSharpCode.Decompiler.CSharp.Transforms;\nusing ICSharpCode.Decompiler.CSharp.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\tpublic class AssignVariableNames : ILVisitor<AssignVariableNames.VariableScope, Unit>, IILTransform\n\t{\n\t\tstatic readonly Dictionary<string, string> typeNameToVariableNameDict = new Dictionary<string, string> {\n\t\t\t{ \"System.Boolean\", \"flag\" },\n\t\t\t{ \"System.Byte\", \"b\" },\n\t\t\t{ \"System.SByte\", \"b\" },\n\t\t\t{ \"System.Int16\", \"num\" },\n\t\t\t{ \"System.Int32\", \"num\" },\n\t\t\t{ \"System.Int64\", \"num\" },\n\t\t\t{ \"System.UInt16\", \"num\" },\n\t\t\t{ \"System.UInt32\", \"num\" },\n\t\t\t{ \"System.UInt64\", \"num\" },\n\t\t\t{ \"System.Single\", \"num\" },\n\t\t\t{ \"System.Double\", \"num\" },\n\t\t\t{ \"System.Decimal\", \"num\" },\n\t\t\t{ \"System.String\", \"text\" },\n\t\t\t{ \"System.Object\", \"obj\" },\n\t\t\t{ \"System.Char\", \"c\" }\n\t\t};\n\n\t\tILTransformContext context;\n\t\tQueue<(ILFunction function, VariableScope parentScope)> workList;\n\t\tconst char maxLoopVariableName = 'n';\n\n\t\tpublic class VariableScope\n\t\t{\n\t\t\treadonly ILTransformContext context;\n\t\t\treadonly VariableScope parentScope;\n\t\t\treadonly ILFunction function;\n\t\t\treadonly Dictionary<MethodDefinitionHandle, string> localFunctions = new();\n\t\t\treadonly Dictionary<ILVariable, string> variableMapping = new(ILVariableEqualityComparer.Instance);\n\t\t\treadonly string[] assignedLocalSignatureIndices;\n\n\t\t\tIImmutableSet<string> currentLowerCaseTypeOrMemberNames;\n\t\t\tDictionary<string, int> reservedVariableNames;\n\t\t\tHashSet<ILVariable> loopCounters;\n\t\t\tint numDisplayClassLocals;\n\n\t\t\tpublic VariableScope(ILFunction function, ILTransformContext context, VariableScope parentScope = null)\n\t\t\t{\n\t\t\t\tthis.function = function;\n\t\t\t\tthis.context = context;\n\t\t\t\tthis.parentScope = parentScope;\n\n\t\t\t\tnumDisplayClassLocals = 0;\n\t\t\t\tassignedLocalSignatureIndices = new string[function.LocalVariableSignatureLength];\n\t\t\t\treservedVariableNames = new Dictionary<string, int>();\n\n\t\t\t\t// find all loop counters in the current function\n\t\t\t\tloopCounters = new HashSet<ILVariable>();\n\t\t\t\tforeach (var inst in TreeTraversal.PreOrder((ILInstruction)function, i => i.Children))\n\t\t\t\t{\n\t\t\t\t\tif (inst is ILFunction && inst != function)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tif (inst is BlockContainer { Kind: ContainerKind.For, Blocks: [.., var incrementBlock] })\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var i in incrementBlock.Instructions)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (HighLevelLoopTransform.MatchIncrement(i, out var variable))\n\t\t\t\t\t\t\t\tloopCounters.Add(variable);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if this is the root scope, we also collect all lower-case type and member names\n\t\t\t\t// and fixed parameter names to avoid conflicts when naming local variables.\n\t\t\t\tif (parentScope == null)\n\t\t\t\t{\n\t\t\t\t\tvar currentLowerCaseTypeOrMemberNames = new HashSet<string>(StringComparer.Ordinal);\n\t\t\t\t\tforeach (var name in CollectAllLowerCaseMemberNames(function.Method.DeclaringTypeDefinition))\n\t\t\t\t\t\tcurrentLowerCaseTypeOrMemberNames.Add(name);\n\t\t\t\t\tforeach (IField item in function.Method.DeclaringTypeDefinition.Fields)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (TransformFieldAndConstructorInitializers.IsGeneratedPrimaryConstructorBackingField(item))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstring name = item.Name.Substring(1, item.Name.Length - 3);\n\t\t\t\t\t\t\tcurrentLowerCaseTypeOrMemberNames.Add(name);\n\t\t\t\t\t\t\tAddExistingName(reservedVariableNames, name);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tforeach (var name in CollectAllLowerCaseTypeNames(function.Method.DeclaringTypeDefinition))\n\t\t\t\t\t{\n\t\t\t\t\t\tcurrentLowerCaseTypeOrMemberNames.Add(name);\n\t\t\t\t\t\tAddExistingName(reservedVariableNames, name);\n\t\t\t\t\t}\n\t\t\t\t\tforeach (var name in CollectAllLowerCaseTypeNames(context.UsingScope))\n\t\t\t\t\t{\n\t\t\t\t\t\tcurrentLowerCaseTypeOrMemberNames.Add(name);\n\t\t\t\t\t\tAddExistingName(reservedVariableNames, name);\n\t\t\t\t\t}\n\t\t\t\t\tthis.currentLowerCaseTypeOrMemberNames = currentLowerCaseTypeOrMemberNames.ToImmutableHashSet();\n\n\t\t\t\t\t// handle implicit parameters of set or event accessors\n\t\t\t\t\tif (function.Method != null && IsSetOrEventAccessor(function.Method) && function.Parameters.Count > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tfor (int i = 0; i < function.Method.Parameters.Count - 1; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddExistingName(reservedVariableNames, function.Method.Parameters[i].Name);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvar lastParameter = function.Method.Parameters.Last();\n\t\t\t\t\t\tswitch (function.Method.AccessorOwner)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase IProperty prop:\n\t\t\t\t\t\t\t\tif (function.Method.AccessorKind == MethodSemanticsAttributes.Setter)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif (prop.Parameters.Any(p => p.Name == \"value\"))\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfunction.Warnings.Add(\"Parameter named \\\"value\\\" already present in property signature!\");\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tvar variableForLastParameter = function.Variables.FirstOrDefault(v => v.Function == function\n\t\t\t\t\t\t\t\t\t\t&& v.Kind == VariableKind.Parameter\n\t\t\t\t\t\t\t\t\t\t&& v.Index == function.Method.Parameters.Count - 1);\n\t\t\t\t\t\t\t\t\tif (variableForLastParameter == null)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tAddExistingName(reservedVariableNames, lastParameter.Name);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif (variableForLastParameter.Name != \"value\")\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tvariableForLastParameter.Name = \"value\";\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tAddExistingName(reservedVariableNames, variableForLastParameter.Name);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase IEvent ev:\n\t\t\t\t\t\t\t\tif (function.Method.AccessorKind != MethodSemanticsAttributes.Raiser)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tvar variableForLastParameter = function.Variables.FirstOrDefault(v => v.Function == function\n\t\t\t\t\t\t\t\t\t\t&& v.Kind == VariableKind.Parameter\n\t\t\t\t\t\t\t\t\t\t&& v.Index == function.Method.Parameters.Count - 1);\n\t\t\t\t\t\t\t\t\tif (variableForLastParameter == null)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tAddExistingName(reservedVariableNames, lastParameter.Name);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif (variableForLastParameter.Name != \"value\")\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tvariableForLastParameter.Name = \"value\";\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tAddExistingName(reservedVariableNames, variableForLastParameter.Name);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tAddExistingName(reservedVariableNames, lastParameter.Name);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tvar variables = function.Variables.Where(v => v.Kind == VariableKind.Parameter && v.Index >= 0).ToDictionary(v => v.Index);\n\t\t\t\t\t\tforeach (var (i, p) in function.Parameters.WithIndex())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstring name = p.Name;\n\t\t\t\t\t\t\tif (string.IsNullOrWhiteSpace(name) && p.Type != SpecialType.ArgList)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// needs to be consistent with logic in ILReader.CreateILVariable\n\t\t\t\t\t\t\t\tname = \"P_\" + i;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (variables.TryGetValue(i, out var v))\n\t\t\t\t\t\t\t\tvariableMapping[v] = name;\n\t\t\t\t\t\t\tAddExistingName(reservedVariableNames, name);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tstatic bool IsSetOrEventAccessor(IMethod method)\n\t\t\t\t\t{\n\t\t\t\t\t\tswitch (method.AccessorKind)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase MethodSemanticsAttributes.Setter:\n\t\t\t\t\t\t\tcase MethodSemanticsAttributes.Adder:\n\t\t\t\t\t\t\tcase MethodSemanticsAttributes.Remover:\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthis.currentLowerCaseTypeOrMemberNames = parentScope.currentLowerCaseTypeOrMemberNames;\n\t\t\t\t\tvar variables = function.Variables.Where(v => v.Kind == VariableKind.Parameter).ToDictionary(v => v.Index);\n\n\t\t\t\t\tforeach (var (i, p) in function.Parameters.WithIndex())\n\t\t\t\t\t{\n\t\t\t\t\t\tstring name = string.IsNullOrWhiteSpace(p.Name) ? variables[i].Name : p.Name;\n\n\t\t\t\t\t\tif (function.Kind is ILFunctionKind.Delegate or ILFunctionKind.ExpressionTree\n\t\t\t\t\t\t\t&& CSharpDecompiler.IsTransparentIdentifier(name))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddExistingName(reservedVariableNames, name);\n\t\t\t\t\t\t\tif (variables.TryGetValue(i, out var v))\n\t\t\t\t\t\t\t\tvariableMapping[v] = name;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstring nameWithoutNumber = SplitName(name, out int newIndex);\n\t\t\t\t\t\tif (!parentScope.IsReservedVariableName(nameWithoutNumber, out _))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddExistingName(reservedVariableNames, name);\n\t\t\t\t\t\t\tif (variables.TryGetValue(i, out var v))\n\t\t\t\t\t\t\t\tvariableMapping[v] = name;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (variables.TryGetValue(i, out var v))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tv.HasGeneratedName = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic void Add(MethodDefinitionHandle localFunction, string name)\n\t\t\t{\n\t\t\t\tthis.localFunctions[localFunction] = name;\n\t\t\t}\n\n\t\t\tpublic string TryGetExistingName(MethodDefinitionHandle localFunction)\n\t\t\t{\n\t\t\t\tif (localFunctions.TryGetValue(localFunction, out var name))\n\t\t\t\t\treturn name;\n\t\t\t\treturn parentScope?.TryGetExistingName(localFunction);\n\t\t\t}\n\n\t\t\tpublic string TryGetExistingName(ILVariable v)\n\t\t\t{\n\t\t\t\tif (variableMapping.TryGetValue(v, out var name))\n\t\t\t\t\treturn name;\n\t\t\t\treturn parentScope?.TryGetExistingName(v);\n\t\t\t}\n\n\t\t\tpublic string TryGetExistingName(ILFunction function, int index)\n\t\t\t{\n\t\t\t\tif (this.function == function)\n\t\t\t\t{\n\t\t\t\t\treturn this.assignedLocalSignatureIndices[index];\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn parentScope?.TryGetExistingName(function, index);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic void AssignNameToLocalSignatureIndex(ILFunction function, int index, string name)\n\t\t\t{\n\t\t\t\tvar scope = this;\n\t\t\t\twhile (scope != null && scope.function != function)\n\t\t\t\t\tscope = scope.parentScope;\n\t\t\t\tDebug.Assert(scope != null);\n\t\t\t\tscope.assignedLocalSignatureIndices[index] = name;\n\t\t\t}\n\n\t\t\tpublic bool IsReservedVariableName(string name, out int index)\n\t\t\t{\n\t\t\t\tif (reservedVariableNames.TryGetValue(name, out index))\n\t\t\t\t\treturn true;\n\t\t\t\treturn parentScope?.IsReservedVariableName(name, out index) ?? false;\n\t\t\t}\n\n\t\t\tpublic void ReserveVariableName(string name, int index = 1)\n\t\t\t{\n\t\t\t\treservedVariableNames[name] = index;\n\t\t\t}\n\n\t\t\tpublic string NextDisplayClassLocal()\n\t\t\t{\n\t\t\t\treturn parentScope?.NextDisplayClassLocal() ?? \"CS$<>8__locals\" + (numDisplayClassLocals++);\n\t\t\t}\n\n\t\t\tpublic bool IsLoopCounter(ILVariable v)\n\t\t\t{\n\t\t\t\treturn loopCounters.Contains(v) || (parentScope?.IsLoopCounter(v) == true);\n\t\t\t}\n\n\t\t\tpublic string AssignNameIfUnassigned(ILVariable v)\n\t\t\t{\n\t\t\t\tif (variableMapping.TryGetValue(v, out var name))\n\t\t\t\t\treturn name;\n\t\t\t\treturn AssignName(v);\n\t\t\t}\n\n\t\t\tpublic string AssignName(ILVariable v)\n\t\t\t{\n\t\t\t\t// variable has no valid name\n\t\t\t\tstring newName = v.Name;\n\t\t\t\tif (v.HasGeneratedName || !IsValidName(newName))\n\t\t\t\t{\n\t\t\t\t\t// don't use the name from the debug symbols if it looks like a generated name\n\t\t\t\t\t// generate a new one based on how the variable is used\n\t\t\t\t\tnewName = GenerateNameForVariable(v);\n\t\t\t\t}\n\t\t\t\t// use the existing name and update index appended to future conflicts\n\t\t\t\tstring nameWithoutNumber = SplitName(newName, out int newIndex);\n\t\t\t\tif (IsReservedVariableName(nameWithoutNumber, out int lastUsedIndex))\n\t\t\t\t{\n\t\t\t\t\tif (v.Type.IsKnownType(KnownTypeCode.Int32) && IsLoopCounter(v))\n\t\t\t\t\t{\n\t\t\t\t\t\t// special case for loop counters,\n\t\t\t\t\t\t// we don't want them to be named i, i2, ..., but i, j, ...\n\t\t\t\t\t\tnewName = GenerateNameForVariable(v);\n\t\t\t\t\t\tnameWithoutNumber = newName;\n\t\t\t\t\t\tnewIndex = 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (IsReservedVariableName(nameWithoutNumber, out lastUsedIndex))\n\t\t\t\t{\n\t\t\t\t\t// name without number was already used\n\t\t\t\t\tif (newIndex > lastUsedIndex)\n\t\t\t\t\t{\n\t\t\t\t\t\t// new index is larger than last, so we can use it\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// new index is smaller or equal, so we use the next value\n\t\t\t\t\t\tnewIndex = lastUsedIndex + 1;\n\t\t\t\t\t}\n\t\t\t\t\t// resolve conflicts by appending the index to the new name:\n\t\t\t\t\tnewName = nameWithoutNumber + newIndex.ToString();\n\t\t\t\t}\n\t\t\t\t// update the last used index\n\t\t\t\tReserveVariableName(nameWithoutNumber, newIndex);\n\t\t\t\tvariableMapping[v] = newName;\n\t\t\t\treturn newName;\n\t\t\t}\n\n\t\t\tstring GenerateNameForVariable(ILVariable variable)\n\t\t\t{\n\t\t\t\tstring proposedName = null;\n\t\t\t\tif (variable.Type.IsKnownType(KnownTypeCode.Int32))\n\t\t\t\t{\n\t\t\t\t\t// test whether the variable might be a loop counter\n\t\t\t\t\tif (loopCounters.Contains(variable))\n\t\t\t\t\t{\n\t\t\t\t\t\t// For loop variables, use i,j,k,l,m,n\n\t\t\t\t\t\tfor (char c = 'i'; c <= maxLoopVariableName; c++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!IsReservedVariableName(c.ToString(), out _))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tproposedName = c.ToString();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// The ComponentResourceManager inside InitializeComponent must be named \"resources\",\n\t\t\t\t// otherwise the WinForms designer won't load the Form.\n\t\t\t\tif (CSharp.CSharpDecompiler.IsWindowsFormsInitializeComponentMethod(context.Function.Method) && variable.Type.FullName == \"System.ComponentModel.ComponentResourceManager\")\n\t\t\t\t{\n\t\t\t\t\tproposedName = \"resources\";\n\t\t\t\t}\n\t\t\t\tif (string.IsNullOrEmpty(proposedName))\n\t\t\t\t{\n\t\t\t\t\tvar proposedNameForAddress = variable.AddressInstructions.OfType<LdLoca>()\n\t\t\t\t\t\t.Select(arg => arg.Parent is CallInstruction c ? c.GetParameter(arg.ChildIndex)?.Name : null)\n\t\t\t\t\t\t.Where(arg => !string.IsNullOrWhiteSpace(arg))\n\t\t\t\t\t\t.Except(currentLowerCaseTypeOrMemberNames).ToList();\n\t\t\t\t\tif (proposedNameForAddress.Count > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tproposedName = proposedNameForAddress[0];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (string.IsNullOrEmpty(proposedName))\n\t\t\t\t{\n\t\t\t\t\tvar proposedNameForStores = new HashSet<string>();\n\t\t\t\t\tforeach (var store in variable.StoreInstructions)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (store is StLoc stloc)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar name = GetNameFromInstruction(stloc.Value);\n\t\t\t\t\t\t\tif (!currentLowerCaseTypeOrMemberNames.Contains(name))\n\t\t\t\t\t\t\t\tproposedNameForStores.Add(name);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (store is MatchInstruction match && match.SlotInfo == MatchInstruction.SubPatternsSlot)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar name = GetNameFromInstruction(match.TestedOperand);\n\t\t\t\t\t\t\tif (!currentLowerCaseTypeOrMemberNames.Contains(name))\n\t\t\t\t\t\t\t\tproposedNameForStores.Add(name);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (store is PinnedRegion pinnedRegion)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar name = GetNameFromInstruction(pinnedRegion.Init);\n\t\t\t\t\t\t\tif (!currentLowerCaseTypeOrMemberNames.Contains(name))\n\t\t\t\t\t\t\t\tproposedNameForStores.Add(name);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (proposedNameForStores.Count == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tproposedName = proposedNameForStores.Single();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (string.IsNullOrEmpty(proposedName))\n\t\t\t\t{\n\t\t\t\t\tvar proposedNameForLoads = variable.LoadInstructions\n\t\t\t\t\t\t.Select(arg => GetNameForArgument(arg.Parent, arg.ChildIndex))\n\t\t\t\t\t\t.Except(currentLowerCaseTypeOrMemberNames).ToList();\n\t\t\t\t\tif (proposedNameForLoads.Count == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tproposedName = proposedNameForLoads[0];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (string.IsNullOrEmpty(proposedName) && variable.Kind == VariableKind.StackSlot)\n\t\t\t\t{\n\t\t\t\t\tvar proposedNameForStoresFromNewObj = variable.StoreInstructions.OfType<StLoc>()\n\t\t\t\t\t\t.Select(expr => GetNameByType(GuessType(variable.Type, expr.Value, context)))\n\t\t\t\t\t\t.Except(currentLowerCaseTypeOrMemberNames).ToList();\n\t\t\t\t\tif (proposedNameForStoresFromNewObj.Count == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tproposedName = proposedNameForStoresFromNewObj[0];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (string.IsNullOrEmpty(proposedName))\n\t\t\t\t{\n\t\t\t\t\tproposedName = GetNameByType(variable.Type);\n\t\t\t\t}\n\n\t\t\t\t// for generated names remove number-suffixes\n\t\t\t\treturn SplitName(proposedName, out _);\n\t\t\t}\n\t\t}\n\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tthis.context = context;\n\t\t\tthis.workList ??= new Queue<(ILFunction function, VariableScope parentScope)>();\n\t\t\tthis.workList.Clear();\n\t\t\tthis.workList.Enqueue((function, null));\n\n\t\t\twhile (this.workList.Count > 0)\n\t\t\t{\n\t\t\t\tvar (currentFunction, parentContext) = this.workList.Dequeue();\n\n\t\t\t\tvar nestedContext = new VariableScope(currentFunction, this.context, parentContext);\n\n\t\t\t\tforeach (var localFunction in currentFunction.LocalFunctions)\n\t\t\t\t{\n\t\t\t\t\tAssignNameToLocalFunction(localFunction, nestedContext);\n\t\t\t\t\tworkList.Enqueue((localFunction, nestedContext));\n\t\t\t\t}\n\n\t\t\t\tcurrentFunction.Body.AcceptVisitor(this, nestedContext);\n\n\t\t\t\tif (currentFunction.Kind != ILFunctionKind.TopLevelFunction)\n\t\t\t\t{\n\t\t\t\t\tforeach (var p in currentFunction.Variables.Where(v => v.Kind == VariableKind.Parameter && v.Index >= 0))\n\t\t\t\t\t{\n\t\t\t\t\t\tp.Name = nestedContext.AssignNameIfUnassigned(p);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate static void AssignNameToLocalFunction(ILFunction function, VariableScope parentContext)\n\t\t{\n\t\t\tif (!LocalFunctionDecompiler.ParseLocalFunctionName(function.Name, out _, out var newName) || !IsValidName(newName))\n\t\t\t\tnewName = null;\n\t\t\tstring nameWithoutNumber;\n\t\t\tint number;\n\t\t\tif (!string.IsNullOrEmpty(newName))\n\t\t\t{\n\t\t\t\tnameWithoutNumber = SplitName(newName, out number);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tnameWithoutNumber = \"f\";\n\t\t\t\tnumber = 1;\n\t\t\t}\n\t\t\tint count;\n\t\t\tif (!parentContext.IsReservedVariableName(nameWithoutNumber, out int currentIndex))\n\t\t\t{\n\t\t\t\tcount = 1;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (currentIndex < number)\n\t\t\t\t\tcount = number;\n\t\t\t\telse\n\t\t\t\t\tcount = Math.Max(number, currentIndex) + 1;\n\t\t\t}\n\t\t\tparentContext.ReserveVariableName(nameWithoutNumber, count);\n\t\t\tif (count > 1)\n\t\t\t{\n\t\t\t\tnewName = nameWithoutNumber + count.ToString();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tnewName = nameWithoutNumber;\n\t\t\t}\n\t\t\tfunction.Name = newName;\n\t\t\tfunction.ReducedMethod.Name = newName;\n\t\t\tparentContext.Add((MethodDefinitionHandle)function.ReducedMethod.MetadataToken, newName);\n\t\t}\n\n\t\tUnit VisitChildren(ILInstruction inst, VariableScope context)\n\t\t{\n\t\t\tforeach (var child in inst.Children)\n\t\t\t{\n\t\t\t\tchild.AcceptVisitor(this, context);\n\t\t\t}\n\n\t\t\treturn default;\n\t\t}\n\n\t\tprotected override Unit Default(ILInstruction inst, VariableScope context)\n\t\t{\n\t\t\tif (inst is IInstructionWithVariableOperand { Variable: var v })\n\t\t\t{\n\t\t\t\t// if there is already a valid name for the variable slot, just use it\n\t\t\t\tstring name = context.TryGetExistingName(v);\n\t\t\t\tif (!string.IsNullOrEmpty(name))\n\t\t\t\t{\n\t\t\t\t\tv.Name = name;\n\t\t\t\t\treturn VisitChildren(inst, context);\n\t\t\t\t}\n\n\t\t\t\tswitch (v.Kind)\n\t\t\t\t{\n\t\t\t\t\tcase VariableKind.Parameter when !v.HasGeneratedName && v.Function.Kind == ILFunctionKind.TopLevelFunction:\n\t\t\t\t\t\t// Parameter names of top-level functions are handled in ILReader.CreateILVariable\n\t\t\t\t\t\t// and CSharpDecompiler.FixParameterNames\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase VariableKind.InitializerTarget: // keep generated names\n\t\t\t\t\tcase VariableKind.NamedArgument:\n\t\t\t\t\t\tcontext.ReserveVariableName(v.Name);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase VariableKind.UsingLocal when v.AddressCount == 0 && v.LoadCount == 0:\n\t\t\t\t\t\t// using variables that are not read, will not be declared in source source\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase VariableKind.DisplayClassLocal:\n\t\t\t\t\t\tv.Name = context.NextDisplayClassLocal();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase VariableKind.Local when v.Index != null:\n\t\t\t\t\t\tname = context.TryGetExistingName(v.Function, v.Index.Value);\n\t\t\t\t\t\tif (name != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// make sure all local ILVariables that refer to the same slot in the locals signature\n\t\t\t\t\t\t\t// are assigned the same name.\n\t\t\t\t\t\t\tv.Name = name;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tv.Name = context.AssignName(v);\n\t\t\t\t\t\t\tcontext.AssignNameToLocalSignatureIndex(v.Function, v.Index.Value, v.Name);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tv.Name = context.AssignName(v);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn VisitChildren(inst, context);\n\t\t}\n\n\t\tprotected internal override Unit VisitILFunction(ILFunction function, VariableScope context)\n\t\t{\n\t\t\tworkList.Enqueue((function, context));\n\t\t\treturn default;\n\t\t}\n\n\t\tprotected internal override Unit VisitCall(Call inst, VariableScope context)\n\t\t{\n\t\t\tif (inst.Method is LocalFunctionMethod m)\n\t\t\t{\n\t\t\t\tstring name = context.TryGetExistingName((MethodDefinitionHandle)m.MetadataToken);\n\t\t\t\tif (!string.IsNullOrEmpty(name))\n\t\t\t\t\tm.Name = name;\n\t\t\t}\n\n\t\t\treturn base.VisitCall(inst, context);\n\t\t}\n\n\t\tprotected internal override Unit VisitLdFtn(LdFtn inst, VariableScope context)\n\t\t{\n\t\t\tif (inst.Method is LocalFunctionMethod m)\n\t\t\t{\n\t\t\t\tstring name = context.TryGetExistingName((MethodDefinitionHandle)m.MetadataToken);\n\t\t\t\tif (!string.IsNullOrEmpty(name))\n\t\t\t\t\tm.Name = name;\n\t\t\t}\n\n\t\t\treturn base.VisitLdFtn(inst, context);\n\t\t}\n\n\t\tstatic IEnumerable<string> CollectAllLowerCaseMemberNames(ITypeDefinition type)\n\t\t{\n\t\t\tforeach (var item in type.GetMembers(m => IsLowerCase(m.Name)))\n\t\t\t\tyield return item.Name;\n\t\t}\n\n\t\tstatic IEnumerable<string> CollectAllLowerCaseTypeNames(ITypeDefinition type)\n\t\t{\n\t\t\tvar ns = type.ParentModule.Compilation.GetNamespaceByFullName(type.Namespace);\n\t\t\tforeach (var item in ns.Types)\n\t\t\t{\n\t\t\t\tif (IsLowerCase(item.Name))\n\t\t\t\t\tyield return item.Name;\n\t\t\t}\n\t\t\tvar current = type;\n\t\t\twhile (current != null)\n\t\t\t{\n\t\t\t\tforeach (var nested in current.NestedTypes)\n\t\t\t\t{\n\t\t\t\t\tif (IsLowerCase(nested.Name))\n\t\t\t\t\t\tyield return nested.Name;\n\t\t\t\t}\n\t\t\t\tcurrent = current.DeclaringTypeDefinition;\n\t\t\t}\n\t\t}\n\n\t\tstatic IEnumerable<string> CollectAllLowerCaseTypeNames(UsingScope usingScope)\n\t\t{\n\t\t\treturn usingScope?.Usings.SelectMany(n => n.Types).Select(t => t.Name).Where(IsLowerCase) ?? [];\n\t\t}\n\n\t\tstatic bool IsLowerCase(string name)\n\t\t{\n\t\t\treturn name.Length > 0 && char.ToLower(name[0]) == name[0];\n\t\t}\n\n\t\t/// <remarks>\n\t\t/// Must be in sync with <see cref=\"GetNameFromInstruction\" />.\n\t\t/// </remarks>\n\t\tinternal static bool IsSupportedInstruction(object arg)\n\t\t{\n\t\t\tswitch (arg)\n\t\t\t{\n\t\t\t\tcase GetPinnableReference _:\n\t\t\t\tcase LdObj _:\n\t\t\t\tcase LdFlda _:\n\t\t\t\tcase LdsFlda _:\n\t\t\t\tcase CallInstruction _:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tinternal static bool IsValidName(string varName)\n\t\t{\n\t\t\tif (string.IsNullOrWhiteSpace(varName))\n\t\t\t\treturn false;\n\t\t\tif (!(char.IsLetter(varName[0]) || varName[0] == '_'))\n\t\t\t\treturn false;\n\t\t\tfor (int i = 1; i < varName.Length; i++)\n\t\t\t{\n\t\t\t\tif (!(char.IsLetterOrDigit(varName[i]) || varName[i] == '_'))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic string GetNameFromInstruction(ILInstruction inst)\n\t\t{\n\t\t\tswitch (inst)\n\t\t\t{\n\t\t\t\tcase GetPinnableReference getPinnableReference:\n\t\t\t\t\treturn GetNameFromInstruction(getPinnableReference.Argument);\n\t\t\t\tcase LdObj ldobj:\n\t\t\t\t\treturn GetNameFromInstruction(ldobj.Target);\n\t\t\t\tcase LdFlda ldflda:\n\t\t\t\t\tif (ldflda.Field.IsCompilerGeneratedOrIsInCompilerGeneratedClass())\n\t\t\t\t\t\treturn GetNameFromInstruction(ldflda.Target);\n\t\t\t\t\treturn CleanUpVariableName(ldflda.Field.Name);\n\t\t\t\tcase LdsFlda ldsflda:\n\t\t\t\t\treturn CleanUpVariableName(ldsflda.Field.Name);\n\t\t\t\tcase CallInstruction call:\n\t\t\t\t\tif (call is NewObj)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tIMethod m = call.Method;\n\t\t\t\t\tif (ExcludeMethodFromCandidates(m))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tif (m.Name.StartsWith(\"get_\", StringComparison.OrdinalIgnoreCase) && m.Parameters.Count == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t// use name from properties, but not from indexers\n\t\t\t\t\t\treturn CleanUpVariableName(m.Name.Substring(4));\n\t\t\t\t\t}\n\t\t\t\t\telse if (m.Name.StartsWith(\"Get\", StringComparison.OrdinalIgnoreCase) && m.Name.Length >= 4 && char.IsUpper(m.Name[3]))\n\t\t\t\t\t{\n\t\t\t\t\t\t// use name from Get-methods\n\t\t\t\t\t\treturn CleanUpVariableName(m.Name.Substring(3));\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase DynamicInvokeMemberInstruction dynInvokeMember:\n\t\t\t\t\tif (dynInvokeMember.Name.StartsWith(\"Get\", StringComparison.OrdinalIgnoreCase)\n\t\t\t\t\t\t&& dynInvokeMember.Name.Length >= 4 && char.IsUpper(dynInvokeMember.Name[3]))\n\t\t\t\t\t{\n\t\t\t\t\t\t// use name from Get-methods\n\t\t\t\t\t\treturn CleanUpVariableName(dynInvokeMember.Name.Substring(3));\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tstatic string GetNameForArgument(ILInstruction parent, int i)\n\t\t{\n\t\t\tswitch (parent)\n\t\t\t{\n\t\t\t\tcase StObj stobj:\n\t\t\t\t\tIField field;\n\t\t\t\t\tif (stobj.Target is LdFlda ldflda)\n\t\t\t\t\t\tfield = ldflda.Field;\n\t\t\t\t\telse if (stobj.Target is LdsFlda ldsflda)\n\t\t\t\t\t\tfield = ldsflda.Field;\n\t\t\t\t\telse\n\t\t\t\t\t\tbreak;\n\t\t\t\t\treturn CleanUpVariableName(field.Name);\n\t\t\t\tcase CallInstruction call:\n\t\t\t\t\tIMethod m = call.Method;\n\t\t\t\t\tif (ExcludeMethodFromCandidates(m))\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tif (m.Parameters.Count == 1 && i == call.Arguments.Count - 1)\n\t\t\t\t\t{\n\t\t\t\t\t\t// argument might be value of a setter\n\t\t\t\t\t\tif (m.Name.StartsWith(\"set_\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn CleanUpVariableName(m.Name.Substring(4));\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (m.Name.StartsWith(\"Set\", StringComparison.OrdinalIgnoreCase) && m.Name.Length >= 4 && char.IsUpper(m.Name[3]))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn CleanUpVariableName(m.Name.Substring(3));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tvar p = call.GetParameter(i);\n\t\t\t\t\tif (p != null && !string.IsNullOrEmpty(p.Name))\n\t\t\t\t\t\treturn CleanUpVariableName(p.Name);\n\t\t\t\t\tbreak;\n\t\t\t\tcase Leave _:\n\t\t\t\t\treturn \"result\";\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tstatic bool ExcludeMethodFromCandidates(IMethod m)\n\t\t{\n\t\t\tif (m.SymbolKind == SymbolKind.Operator)\n\t\t\t\treturn true;\n\t\t\tif (m.Name == \"ToString\")\n\t\t\t\treturn true;\n\t\t\tif (m.Name == \"Concat\" && m.DeclaringType.IsKnownType(KnownTypeCode.String))\n\t\t\t\treturn true;\n\t\t\tif (m.Name == \"GetPinnableReference\")\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\n\t\tstatic string GetNameByType(IType type)\n\t\t{\n\t\t\ttype = NullableType.GetUnderlyingType(type);\n\t\t\twhile (type is ModifiedType || type is PinnedType)\n\t\t\t{\n\t\t\t\ttype = NullableType.GetUnderlyingType(((TypeWithElementType)type).ElementType);\n\t\t\t}\n\n\t\t\tstring name;\n\t\t\tif (type.IsAnonymousType())\n\t\t\t{\n\t\t\t\tname = \"anon\";\n\t\t\t}\n\t\t\telse if (type.Name.EndsWith(\"Exception\", StringComparison.Ordinal))\n\t\t\t{\n\t\t\t\tname = \"ex\";\n\t\t\t}\n\t\t\telse if (type.Name.EndsWith(\"EventArgs\", StringComparison.Ordinal))\n\t\t\t{\n\t\t\t\tname = \"e\";\n\t\t\t}\n\t\t\telse if (type.IsCSharpNativeIntegerType())\n\t\t\t{\n\t\t\t\tname = \"num\";\n\t\t\t}\n\t\t\telse if (!typeNameToVariableNameDict.TryGetValue(type.FullName, out name))\n\t\t\t{\n\t\t\t\tname = type.Kind switch {\n\t\t\t\t\tTypeKind.Array => \"array\",\n\t\t\t\t\tTypeKind.Pointer => \"ptr\",\n\t\t\t\t\tTypeKind.TypeParameter => \"val\",\n\t\t\t\t\tTypeKind.Unknown => \"val\",\n\t\t\t\t\tTypeKind.Dynamic => \"val\",\n\t\t\t\t\tTypeKind.ByReference => \"reference\",\n\t\t\t\t\tTypeKind.Tuple => \"tuple\",\n\t\t\t\t\tTypeKind.NInt => \"num\",\n\t\t\t\t\tTypeKind.NUInt => \"num\",\n\t\t\t\t\t_ => type.Name\n\t\t\t\t};\n\t\t\t\t// remove the 'I' for interfaces\n\t\t\t\tif (name.Length >= 3 && name[0] == 'I' && char.IsUpper(name[1]) && char.IsLower(name[2]))\n\t\t\t\t\tname = name.Substring(1);\n\t\t\t\tname = CleanUpVariableName(name) ?? \"obj\";\n\t\t\t}\n\t\t\treturn name;\n\t\t}\n\n\t\tstatic void AddExistingName(Dictionary<string, int> reservedVariableNames, string name)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(name))\n\t\t\t\treturn;\n\t\t\tstring nameWithoutDigits = SplitName(name, out int number);\n\t\t\tif (reservedVariableNames.TryGetValue(nameWithoutDigits, out int existingNumber))\n\t\t\t{\n\t\t\t\treservedVariableNames[nameWithoutDigits] = Math.Max(number, existingNumber);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treservedVariableNames.Add(nameWithoutDigits, number);\n\t\t\t}\n\t\t}\n\n\t\tstatic string SplitName(string name, out int number)\n\t\t{\n\t\t\t// First, identify whether the name already ends with a number:\n\t\t\tint pos = name.Length;\n\t\t\twhile (pos > 0 && name[pos - 1] >= '0' && name[pos - 1] <= '9')\n\t\t\t\tpos--;\n\t\t\tif (pos < name.Length)\n\t\t\t{\n\t\t\t\tif (int.TryParse(name.Substring(pos), out number))\n\t\t\t\t{\n\t\t\t\t\treturn name.Substring(0, pos);\n\t\t\t\t}\n\t\t\t}\n\t\t\tnumber = 1;\n\t\t\treturn name;\n\t\t}\n\n\t\tstatic string CleanUpVariableName(string name)\n\t\t{\n\t\t\t// remove the backtick (generics)\n\t\t\tint pos = name.IndexOf('`');\n\t\t\tif (pos >= 0)\n\t\t\t\tname = name.Substring(0, pos);\n\n\t\t\t// remove field prefix:\n\t\t\tif (name.Length > 2 && name.StartsWith(\"m_\", StringComparison.Ordinal))\n\t\t\t\tname = name.Substring(2);\n\t\t\telse if (name.Length > 1 && name[0] == '_' && (char.IsLetter(name[1]) || name[1] == '_'))\n\t\t\t\tname = name.Substring(1);\n\n\t\t\tif (TextWriterTokenWriter.ContainsNonPrintableIdentifierChar(name))\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif (name.Length == 0)\n\t\t\t\treturn \"obj\";\n\t\t\tstring lowerCaseName = char.ToLower(name[0]) + name.Substring(1);\n\t\t\tif (CSharp.OutputVisitor.CSharpOutputVisitor.IsKeyword(lowerCaseName))\n\t\t\t\treturn null;\n\t\t\treturn lowerCaseName;\n\t\t}\n\n\t\tstatic IType GuessType(IType variableType, ILInstruction inst, ILTransformContext context)\n\t\t{\n\t\t\tif (!variableType.IsKnownType(KnownTypeCode.Object))\n\t\t\t\treturn variableType;\n\n\t\t\tIType inferredType = inst.InferType(context.TypeSystem);\n\t\t\tif (inferredType.Kind != TypeKind.Unknown)\n\t\t\t\treturn inferredType;\n\t\t\telse\n\t\t\t\treturn variableType;\n\t\t}\n\n\t\tstatic Dictionary<string, int> CollectReservedVariableNames(ILFunction function,\n\t\t\tILVariable existingVariable, bool mustResolveConflicts, UsingScope usingScope)\n\t\t{\n\t\t\tvar reservedVariableNames = new Dictionary<string, int>();\n\t\t\tvar rootFunction = function.Ancestors.OfType<ILFunction>().Single(f => f.Parent == null);\n\t\t\tforeach (var f in rootFunction.Descendants.OfType<ILFunction>())\n\t\t\t{\n\t\t\t\tforeach (var p in rootFunction.Parameters)\n\t\t\t\t{\n\t\t\t\t\tAddExistingName(reservedVariableNames, p.Name);\n\t\t\t\t}\n\t\t\t\tforeach (var v in f.Variables.Where(v => v.Kind != VariableKind.Parameter))\n\t\t\t\t{\n\t\t\t\t\tif (v != existingVariable)\n\t\t\t\t\t\tAddExistingName(reservedVariableNames, v.Name);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (mustResolveConflicts)\n\t\t\t{\n\t\t\t\tvar memberNames = CollectAllLowerCaseMemberNames(function.Method.DeclaringTypeDefinition)\n\t\t\t\t\t.Concat(CollectAllLowerCaseTypeNames(function.Method.DeclaringTypeDefinition))\n\t\t\t\t\t.Concat(CollectAllLowerCaseTypeNames(usingScope));\n\t\t\t\tforeach (var name in memberNames)\n\t\t\t\t\tAddExistingName(reservedVariableNames, name);\n\t\t\t}\n\t\t\treturn reservedVariableNames;\n\t\t}\n\n\t\tinternal static string GenerateForeachVariableName(ILFunction function, ILInstruction valueContext, UsingScope usingScope,\n\t\t\tILVariable existingVariable = null, bool mustResolveConflicts = false)\n\t\t{\n\t\t\tif (function == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(function));\n\t\t\tif (existingVariable != null && !existingVariable.HasGeneratedName)\n\t\t\t{\n\t\t\t\treturn existingVariable.Name;\n\t\t\t}\n\t\t\tvar reservedVariableNames = CollectReservedVariableNames(function, existingVariable, mustResolveConflicts, usingScope);\n\n\t\t\tstring baseName = GetNameFromInstruction(valueContext);\n\t\t\tif (string.IsNullOrEmpty(baseName))\n\t\t\t{\n\t\t\t\tif (valueContext is LdLoc ldloc && ldloc.Variable.Kind == VariableKind.Parameter)\n\t\t\t\t{\n\t\t\t\t\tbaseName = ldloc.Variable.Name;\n\t\t\t\t}\n\t\t\t}\n\t\t\tstring proposedName = \"item\";\n\n\t\t\tif (!string.IsNullOrEmpty(baseName))\n\t\t\t{\n\t\t\t\tif (!IsPlural(baseName, ref proposedName))\n\t\t\t\t{\n\t\t\t\t\tif (baseName.Length > 4 && baseName.EndsWith(\"List\", StringComparison.Ordinal))\n\t\t\t\t\t{\n\t\t\t\t\t\tproposedName = baseName.Substring(0, baseName.Length - 4);\n\t\t\t\t\t}\n\t\t\t\t\telse if (baseName.Equals(\"list\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\t{\n\t\t\t\t\t\tproposedName = \"item\";\n\t\t\t\t\t}\n\t\t\t\t\telse if (baseName.EndsWith(\"children\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\t{\n\t\t\t\t\t\tproposedName = baseName.Remove(baseName.Length - 3);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// remove any numbers from the proposed name\n\t\t\tproposedName = SplitName(proposedName, out int number);\n\n\t\t\tif (!reservedVariableNames.ContainsKey(proposedName))\n\t\t\t{\n\t\t\t\treservedVariableNames.Add(proposedName, 0);\n\t\t\t}\n\t\t\tint count = ++reservedVariableNames[proposedName];\n\t\t\tDebug.Assert(!string.IsNullOrWhiteSpace(proposedName));\n\t\t\tif (count > 1)\n\t\t\t{\n\t\t\t\treturn proposedName + count.ToString();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn proposedName;\n\t\t\t}\n\t\t}\n\n\t\tinternal static string GenerateVariableName(ILFunction function, IType type, UsingScope usingScope,\n\t\t\tILInstruction valueContext = null, ILVariable existingVariable = null,\n\t\t\tbool mustResolveConflicts = false)\n\t\t{\n\t\t\tif (function == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(function));\n\t\t\tvar reservedVariableNames = CollectReservedVariableNames(function, existingVariable, mustResolveConflicts, usingScope);\n\n\t\t\tstring baseName = valueContext != null ? GetNameFromInstruction(valueContext) ?? GetNameByType(type) : GetNameByType(type);\n\t\t\tstring proposedName = \"obj\";\n\n\t\t\tif (!string.IsNullOrEmpty(baseName))\n\t\t\t{\n\t\t\t\tif (!IsPlural(baseName, ref proposedName))\n\t\t\t\t{\n\t\t\t\t\tif (baseName.Length > 4 && baseName.EndsWith(\"List\", StringComparison.Ordinal))\n\t\t\t\t\t{\n\t\t\t\t\t\tproposedName = baseName.Substring(0, baseName.Length - 4);\n\t\t\t\t\t}\n\t\t\t\t\telse if (baseName.Equals(\"list\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\t{\n\t\t\t\t\t\tproposedName = \"item\";\n\t\t\t\t\t}\n\t\t\t\t\telse if (baseName.EndsWith(\"children\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\t{\n\t\t\t\t\t\tproposedName = baseName.Remove(baseName.Length - 3);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tproposedName = baseName;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// remove any numbers from the proposed name\n\t\t\tproposedName = SplitName(proposedName, out int number);\n\n\t\t\tif (!reservedVariableNames.ContainsKey(proposedName))\n\t\t\t{\n\t\t\t\treservedVariableNames.Add(proposedName, 0);\n\t\t\t}\n\t\t\tint count = ++reservedVariableNames[proposedName];\n\t\t\tDebug.Assert(!string.IsNullOrWhiteSpace(proposedName));\n\t\t\tif (count > 1)\n\t\t\t{\n\t\t\t\treturn proposedName + count.ToString();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn proposedName;\n\t\t\t}\n\t\t}\n\n\t\tprivate static bool IsPlural(string baseName, ref string proposedName)\n\t\t{\n\t\t\tvar newName = Vocabularies.Default.Singularize(baseName, inputIsKnownToBePlural: false);\n\t\t\tif (string.IsNullOrWhiteSpace(newName) || newName == baseName)\n\t\t\t\treturn false;\n\t\t\tproposedName = newName;\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/BlockTransform.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.FlowAnalysis;\nusing ICSharpCode.Decompiler.IL.ControlFlow;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Per-block IL transform.\n\t/// </summary>\n\tpublic interface IBlockTransform\n\t{\n\t\t/// <summary>\n\t\t/// Runs the transform on the specified block.\n\t\t/// \n\t\t/// Note: the transform may only modify the specified block and its descendants,\n\t\t/// as well as any sibling blocks that are dominated by the specified block.\n\t\t/// </summary>\n\t\tvoid Run(Block block, BlockTransformContext context);\n\t}\n\n\t/// <summary>\n\t/// Parameter class holding various arguments for <see cref=\"IBlockTransform.Run\"/>.\n\t/// </summary>\n\tpublic class BlockTransformContext : ILTransformContext\n\t{\n\t\t/// <summary>\n\t\t/// The block to process.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Should be identical to the <c>block</c> parameter to <c>IBlockTransform.Run</c>.\n\t\t/// </remarks>\n\t\tpublic Block Block { get; set; }\n\n\t\t/// <summary>\n\t\t/// The control flow node corresponding to the block being processed.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Identical to <c>ControlFlowGraph.GetNode(Block)</c>.\n\t\t/// Note: the control flow graph is not up-to-date, but was created at the start of the\n\t\t/// block transforms (before loop detection).\n\t\t/// </remarks>\n\t\tpublic ControlFlowNode ControlFlowNode { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets the control flow graph.\n\t\t/// \n\t\t/// Note: the control flow graph is not up-to-date, but was created at the start of the\n\t\t/// block transforms (before loop detection).\n\t\t/// </summary>\n\t\tpublic ControlFlowGraph ControlFlowGraph { get; set; }\n\n\t\t/// <summary>\n\t\t/// Initially equal to Block.Instructions.Count indicating that nothing has been transformed yet.\n\t\t/// Set by <see cref=\"ConditionDetection\"/> when another already transformed block is merged into\n\t\t/// the current block. Subsequent <see cref=\"IBlockTransform\"/>s must update this value, for example,\n\t\t/// by resetting it to Block.Instructions.Count. <see cref=\"StatementTransform\"/> will use this value to\n\t\t/// skip already transformed instructions.\n\t\t/// </summary>\n\t\tpublic int IndexOfFirstAlreadyTransformedInstruction { get; set; }\n\n\t\tpublic BlockTransformContext(ILTransformContext context) : base(context)\n\t\t{\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// IL transform that runs a list of per-block transforms.\n\t/// </summary>\n\tpublic class BlockILTransform : IILTransform\n\t{\n\t\tpublic IList<IBlockTransform> PreOrderTransforms { get; } = new List<IBlockTransform>();\n\t\tpublic IList<IBlockTransform> PostOrderTransforms { get; } = new List<IBlockTransform>();\n\n\t\tbool running;\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn $\"{nameof(BlockILTransform)} ({string.Join(\", \", PreOrderTransforms.Concat(PostOrderTransforms).Select(t => t.GetType().Name))})\";\n\t\t}\n\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tif (running)\n\t\t\t\tthrow new InvalidOperationException(\"Reentrancy detected. Transforms (and the CSharpDecompiler) are neither thread-safe nor re-entrant.\");\n\t\t\ttry\n\t\t\t{\n\t\t\t\trunning = true;\n\t\t\t\tvar blockContext = new BlockTransformContext(context);\n\t\t\t\tDebug.Assert(blockContext.Function == function);\n\t\t\t\tforeach (var container in function.Descendants.OfType<BlockContainer>().ToList())\n\t\t\t\t{\n\t\t\t\t\tcontext.CancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tblockContext.ControlFlowGraph = new ControlFlowGraph(container, context.CancellationToken);\n\t\t\t\t\tVisitBlock(blockContext.ControlFlowGraph.GetNode(container.EntryPoint), blockContext);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\trunning = false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Walks the dominator tree rooted at entryNode, calling the transforms on each block.\n\t\t/// </summary>\n\t\tvoid VisitBlock(ControlFlowNode entryNode, BlockTransformContext context)\n\t\t{\n\t\t\tIEnumerable<ControlFlowNode> Preorder(ControlFlowNode cfgNode)\n\t\t\t{\n\t\t\t\t// preorder processing:\n\t\t\t\tBlock block = (Block)cfgNode.UserData;\n\t\t\t\tcontext.StepStartGroup(block.Label, block);\n\n\t\t\t\tcontext.ControlFlowNode = cfgNode;\n\t\t\t\tcontext.Block = block;\n\t\t\t\tcontext.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count;\n\t\t\t\tblock.RunTransforms(PreOrderTransforms, context);\n\n\t\t\t\t// process the children\n\t\t\t\treturn cfgNode.DominatorTreeChildren;\n\t\t\t}\n\n\t\t\tforeach (var cfgNode in TreeTraversal.PostOrder(entryNode, Preorder))\n\t\t\t{\n\t\t\t\t// in post-order:\n\t\t\t\tBlock block = (Block)cfgNode.UserData;\n\t\t\t\tcontext.ControlFlowNode = cfgNode;\n\t\t\t\tcontext.Block = block;\n\t\t\t\tcontext.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count;\n\t\t\t\tblock.RunTransforms(PostOrderTransforms, context);\n\t\t\t\tcontext.StepEndGroup();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/CachedDelegateInitialization.cs",
    "content": "// Copyright (c) 2011-2016 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\tpublic class CachedDelegateInitialization : IBlockTransform\n\t{\n\t\tBlockTransformContext context;\n\n\t\tpublic void Run(Block block, BlockTransformContext context)\n\t\t{\n\t\t\tthis.context = context;\n\t\t\tif (!context.Settings.AnonymousMethods)\n\t\t\t\treturn;\n\t\t\tfor (int i = context.IndexOfFirstAlreadyTransformedInstruction - 1; i >= 0; i--)\n\t\t\t{\n\t\t\t\tif (block.Instructions[i] is IfInstruction inst)\n\t\t\t\t{\n\t\t\t\t\tif (CachedDelegateInitializationWithField(inst))\n\t\t\t\t\t{\n\t\t\t\t\t\tblock.Instructions.RemoveAt(i);\n\t\t\t\t\t\tcontext.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (CachedDelegateInitializationWithLocal(inst))\n\t\t\t\t\t{\n\t\t\t\t\t\tILInlining.InlineOneIfPossible(block, i, InliningOptions.Aggressive, context);\n\t\t\t\t\t\tcontext.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (CachedDelegateInitializationRoslynInStaticWithLocal(inst) || CachedDelegateInitializationRoslynWithLocal(inst))\n\t\t\t\t\t{\n\t\t\t\t\t\tblock.Instructions.RemoveAt(i);\n\t\t\t\t\t\tcontext.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (CachedDelegateInitializationVB(inst))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontext.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (CachedDelegateInitializationVBWithReturn(inst))\n\t\t\t\t\t{\n\t\t\t\t\t\tblock.Instructions.RemoveAt(i);\n\t\t\t\t\t\tcontext.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (CachedDelegateInitializationVBWithClosure(inst))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontext.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// if (comp(ldsfld CachedAnonMethodDelegate == ldnull)) {\n\t\t///     stsfld CachedAnonMethodDelegate(DelegateConstruction)\n\t\t/// }\n\t\t/// ... one usage of CachedAnonMethodDelegate ...\n\t\t/// =>\n\t\t/// ... one usage of DelegateConstruction ...\n\t\t/// </summary>\n\t\tbool CachedDelegateInitializationWithField(IfInstruction inst)\n\t\t{\n\n\t\t\tBlock trueInst = inst.TrueInst as Block;\n\t\t\tif (trueInst == null || trueInst.Instructions.Count != 1 || !inst.FalseInst.MatchNop())\n\t\t\t\treturn false;\n\t\t\tvar storeInst = trueInst.Instructions[0];\n\t\t\tif (!inst.Condition.MatchCompEquals(out ILInstruction left, out ILInstruction right) || !left.MatchLdsFld(out IField field) || !right.MatchLdNull())\n\t\t\t\treturn false;\n\t\t\tif (!storeInst.MatchStsFld(out IField field2, out ILInstruction value) || !field.Equals(field2) || !field.IsCompilerGeneratedOrIsInCompilerGeneratedClass())\n\t\t\t\treturn false;\n\t\t\tif (!DelegateConstruction.MatchDelegateConstruction(value.UnwrapConv(ConversionKind.Invalid) as NewObj, out _, out _, out _, true))\n\t\t\t\treturn false;\n\t\t\tvar nextInstruction = inst.Parent.Children.ElementAtOrDefault(inst.ChildIndex + 1);\n\t\t\tif (nextInstruction == null)\n\t\t\t\treturn false;\n\t\t\tvar usages = nextInstruction.Descendants.Where(i => i.MatchLdsFld(field)).ToArray();\n\t\t\tif (usages.Length != 1)\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"CachedDelegateInitializationWithField\", inst);\n\t\t\tusages[0].ReplaceWith(value);\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// if (comp(ldloc v == ldnull)) {\n\t\t///     stloc v(DelegateConstruction)\n\t\t/// }\n\t\t/// =>\n\t\t/// stloc v(DelegateConstruction)\n\t\t/// </summary>\n\t\tbool CachedDelegateInitializationWithLocal(IfInstruction inst)\n\t\t{\n\t\t\tBlock trueInst = inst.TrueInst as Block;\n\t\t\tif (trueInst == null || (trueInst.Instructions.Count != 1) || !inst.FalseInst.MatchNop())\n\t\t\t\treturn false;\n\t\t\tif (!inst.Condition.MatchCompEquals(out ILInstruction left, out ILInstruction right) || !left.MatchLdLoc(out ILVariable v) || !right.MatchLdNull())\n\t\t\t\treturn false;\n\t\t\tvar storeInst = trueInst.Instructions.Last();\n\t\t\tif (!storeInst.MatchStLoc(v, out ILInstruction value))\n\t\t\t\treturn false;\n\t\t\tif (!DelegateConstruction.MatchDelegateConstruction(value as NewObj, out _, out _, out _, true))\n\t\t\t\treturn false;\n\t\t\t// do not transform if there are other stores/loads of this variable\n\t\t\tif (v.StoreCount != 2 || v.StoreInstructions.Count != 2 || v.LoadCount != 2 || v.AddressCount != 0)\n\t\t\t\treturn false;\n\t\t\t// do not transform if the first assignment is not assigning null:\n\t\t\tvar otherStore = v.StoreInstructions.OfType<StLoc>().SingleOrDefault(store => store != storeInst);\n\t\t\tif (otherStore == null || !otherStore.Value.MatchLdNull() || !(otherStore.Parent is Block))\n\t\t\t\treturn false;\n\t\t\t// do not transform if there is no usage directly afterwards\n\t\t\tvar nextInstruction = inst.Parent.Children.ElementAtOrDefault(inst.ChildIndex + 1);\n\t\t\tif (nextInstruction == null)\n\t\t\t\treturn false;\n\t\t\tvar usages = nextInstruction.Descendants.Where(i => i.MatchLdLoc(v)).ToArray();\n\t\t\tif (usages.Length != 1)\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"CachedDelegateInitializationWithLocal\", inst);\n\t\t\t((Block)otherStore.Parent).Instructions.Remove(otherStore);\n\t\t\tinst.ReplaceWith(storeInst);\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// stloc s(ldobj(ldsflda(CachedAnonMethodDelegate))\n\t\t/// if (comp(ldloc s == null)) {\n\t\t///\t\tstloc s(stobj(ldsflda(CachedAnonMethodDelegate), DelegateConstruction))\n\t\t///\t}\n\t\t///\t=>\n\t\t///\tstloc s(DelegateConstruction)\n\t\t/// </summary>\n\t\tbool CachedDelegateInitializationRoslynInStaticWithLocal(IfInstruction inst)\n\t\t{\n\t\t\tBlock trueInst = inst.TrueInst as Block;\n\t\t\tif (trueInst == null || (trueInst.Instructions.Count != 1) || !inst.FalseInst.MatchNop())\n\t\t\t\treturn false;\n\t\t\tif (!inst.Condition.MatchCompEquals(out ILInstruction left, out ILInstruction right) || !left.MatchLdLoc(out ILVariable s) || !right.MatchLdNull())\n\t\t\t\treturn false;\n\t\t\tvar storeInst = trueInst.Instructions.Last() as StLoc;\n\t\t\tvar storeBeforeIf = inst.Parent.Children.ElementAtOrDefault(inst.ChildIndex - 1) as StLoc;\n\t\t\tif (storeBeforeIf == null || storeInst == null || storeBeforeIf.Variable != s || storeInst.Variable != s)\n\t\t\t\treturn false;\n\t\t\tif (!(storeInst.Value is StObj stobj) || !(storeBeforeIf.Value is LdObj ldobj))\n\t\t\t\treturn false;\n\t\t\tif (!(stobj.Value is NewObj))\n\t\t\t\treturn false;\n\t\t\tif (!stobj.Target.MatchLdsFlda(out var field1) || !ldobj.Target.MatchLdsFlda(out var field2) || !field1.Equals(field2))\n\t\t\t\treturn false;\n\t\t\tif (!DelegateConstruction.MatchDelegateConstruction((NewObj)stobj.Value, out _, out _, out _, true))\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"CachedDelegateInitializationRoslynInStaticWithLocal\", inst);\n\t\t\tstoreBeforeIf.Value = stobj.Value;\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// stloc s(ldobj(ldflda(CachedAnonMethodDelegate))\n\t\t/// if (comp(ldloc s == null)) {\n\t\t///\t\tstloc s(stobj(ldflda(CachedAnonMethodDelegate), DelegateConstruction))\n\t\t///\t}\n\t\t///\t=>\n\t\t///\tstloc s(DelegateConstruction)\n\t\t/// </summary>\n\t\tbool CachedDelegateInitializationRoslynWithLocal(IfInstruction inst)\n\t\t{\n\t\t\tBlock trueInst = inst.TrueInst as Block;\n\t\t\tif (trueInst == null || (trueInst.Instructions.Count != 1) || !inst.FalseInst.MatchNop())\n\t\t\t\treturn false;\n\t\t\tif (!inst.Condition.MatchCompEquals(out ILInstruction left, out ILInstruction right) || !left.MatchLdLoc(out ILVariable s) || !right.MatchLdNull())\n\t\t\t\treturn false;\n\t\t\tvar storeInst = trueInst.Instructions.Last() as StLoc;\n\t\t\tvar storeBeforeIf = inst.Parent.Children.ElementAtOrDefault(inst.ChildIndex - 1) as StLoc;\n\t\t\tif (storeBeforeIf == null || storeInst == null || storeBeforeIf.Variable != s || storeInst.Variable != s)\n\t\t\t\treturn false;\n\t\t\tif (!(storeInst.Value is StObj stobj) || !(storeBeforeIf.Value is LdObj ldobj))\n\t\t\t\treturn false;\n\t\t\tif (!(stobj.Value is NewObj))\n\t\t\t\treturn false;\n\t\t\tif (!stobj.Target.MatchLdFlda(out var _, out var field1) || !ldobj.Target.MatchLdFlda(out var __, out var field2) || !field1.Equals(field2))\n\t\t\t\treturn false;\n\t\t\tif (!DelegateConstruction.MatchDelegateConstruction((NewObj)stobj.Value, out _, out _, out _, true))\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"CachedDelegateInitializationRoslynWithLocal\", inst);\n\t\t\tstoreBeforeIf.Value = stobj.Value;\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// if (comp.i4(comp.o(ldobj delegateType(ldsflda CachedAnonMethodDelegate) != ldnull) == ldc.i4 0)) Block {\n\t\t/// \tstloc s(stobj(ldflda(CachedAnonMethodDelegate), DelegateConstruction))\n\t\t/// } else Block {\n\t\t/// \tstloc s(ldobj System.Action(ldsflda $I4-1))\n\t\t/// }\n\t\t/// =>\n\t\t///\tstloc s(DelegateConstruction)\n\t\t/// </summary>\n\t\tbool CachedDelegateInitializationVB(IfInstruction inst)\n\t\t{\n\t\t\tif (!(inst.TrueInst is Block trueInst && inst.FalseInst is Block falseInst))\n\t\t\t\treturn false;\n\t\t\tif (trueInst.Instructions.Count != 1 || falseInst.Instructions.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (!(trueInst.Instructions[0].MatchStLoc(out var s, out var trueInitValue)\n\t\t\t\t&& falseInst.Instructions[0].MatchStLoc(s, out var falseInitValue)))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (s.Kind != VariableKind.StackSlot || s.StoreCount != 2)\n\t\t\t\treturn false;\n\t\t\tif (!(trueInitValue is StObj stobj) || !(falseInitValue is LdObj ldobj))\n\t\t\t\treturn false;\n\t\t\tif (!(stobj.Value is NewObj delegateConstruction))\n\t\t\t\treturn false;\n\t\t\tif (!stobj.Target.MatchLdsFlda(out var field1)\n\t\t\t\t|| !ldobj.Target.MatchLdsFlda(out var field2)\n\t\t\t\t|| !field1.Equals(field2))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!inst.Condition.MatchCompEquals(out ILInstruction left, out ILInstruction right) || !right.MatchLdNull())\n\t\t\t\treturn false;\n\t\t\tif (!ldobj.Match(left).Success)\n\t\t\t\treturn false;\n\t\t\tif (!DelegateConstruction.MatchDelegateConstruction(delegateConstruction, out _, out _, out _, true))\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"CachedDelegateInitializationVB\", inst);\n\t\t\tinst.ReplaceWith(new StLoc(s, delegateConstruction));\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// if (comp.o(ldsfld CachedAnonMethodDelegate != ldnull)) {\n\t\t///\t\tleave IL_0005 (ldsfld CachedAnonMethodDelegate)\n\t\t/// }\n\t\t///\tleave IL_0005 (stsfld CachedAnonMethodDelegate(DelegateConstruction))\n\t\t/// =>\n\t\t/// leave IL_0005 (DelegateConstruction)\n\t\t/// </summary>\n\t\tbool CachedDelegateInitializationVBWithReturn(IfInstruction inst)\n\t\t{\n\t\t\tif (!inst.Condition.MatchCompNotEqualsNull(out var arg) || !arg.MatchLdsFld(out var field))\n\t\t\t\treturn false;\n\t\t\tif (!inst.FalseInst.MatchNop())\n\t\t\t\treturn false;\n\t\t\tif (!inst.TrueInst.MatchReturn(out arg) || !arg.MatchLdsFld(field))\n\t\t\t\treturn false;\n\t\t\tvar leaveAfterIf = inst.Parent.Children.ElementAtOrDefault(inst.ChildIndex + 1) as Leave;\n\t\t\tif (leaveAfterIf is null || !leaveAfterIf.IsLeavingFunction)\n\t\t\t\treturn false;\n\t\t\tif (!leaveAfterIf.Value.MatchStsFld(out var field2, out var delegateConstruction) || !field.Equals(field2))\n\t\t\t\treturn false;\n\t\t\tif (!DelegateConstruction.MatchDelegateConstruction(delegateConstruction, out _, out _, out _, true))\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"CachedDelegateInitializationVBWithReturn\", inst);\n\t\t\tleaveAfterIf.Value = delegateConstruction;\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// if (comp.o(ldobj delegateType(ldflda CachedAnonMethodDelegate(ldloc closure)) != ldnull)) Block {\n\t\t/// \tstloc s(ldobj delegateType(ldflda CachedAnonMethodDelegate(ldloc closure)))\n\t\t/// } else Block {\n\t\t/// \tstloc s(stobj delegateType(ldflda CachedAnonMethodDelegate(ldloc closure), DelegateConstruction))\n\t\t/// }\n\t\t/// =>\n\t\t///\tstloc s(DelegateConstruction)\n\t\t/// </summary>\n\t\tbool CachedDelegateInitializationVBWithClosure(IfInstruction inst)\n\t\t{\n\t\t\tif (!(inst.TrueInst is Block trueInst && inst.FalseInst is Block falseInst))\n\t\t\t\treturn false;\n\t\t\tif (trueInst.Instructions.Count != 1 || falseInst.Instructions.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (!(trueInst.Instructions[0].MatchStLoc(out var s, out var trueInitValue)\n\t\t\t\t  && falseInst.Instructions[0].MatchStLoc(s, out var falseInitValue)))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (s.Kind != VariableKind.StackSlot || s.StoreCount != 2)\n\t\t\t\treturn false;\n\t\t\tif (!(falseInitValue is StObj stobj) || !(trueInitValue is LdObj ldobj))\n\t\t\t\treturn false;\n\t\t\tif (!(stobj.Value is NewObj delegateConstruction))\n\t\t\t\treturn false;\n\t\t\tif (!stobj.Target.MatchLdFlda(out var target1, out var field1)\n\t\t\t\t|| !ldobj.Target.MatchLdFlda(out var target2, out var field2)\n\t\t\t\t|| !field1.Equals(field2) || !target1.Match(target2).Success)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!inst.Condition.MatchCompNotEqualsNull(out ILInstruction left))\n\t\t\t\treturn false;\n\t\t\tif (!ldobj.Match(left).Success)\n\t\t\t\treturn false;\n\t\t\tif (!DelegateConstruction.MatchDelegateConstruction(delegateConstruction, out _, out _, out _, true))\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"CachedDelegateInitializationVBWithClosure\", inst);\n\t\t\tinst.ReplaceWith(new StLoc(s, delegateConstruction));\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/CombineExitsTransform.cs",
    "content": "// Copyright (c) 2019 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\tclass CombineExitsTransform : IILTransform\n\t{\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tif (!(function.Body is BlockContainer container && container.Blocks.Count == 1))\n\t\t\t\treturn;\n\t\t\tvar combinedExit = CombineExits(container.EntryPoint);\n\t\t\tif (combinedExit == null)\n\t\t\t\treturn;\n\t\t\tExpressionTransforms.RunOnSingleStatement(combinedExit, context);\n\t\t}\n\n\t\tstatic Leave CombineExits(Block block)\n\t\t{\n\t\t\tif (!(block.Instructions.SecondToLastOrDefault() is IfInstruction ifInst && block.Instructions.LastOrDefault() is Leave leaveElse))\n\t\t\t\treturn null;\n\t\t\tif (!ifInst.FalseInst.MatchNop())\n\t\t\t\treturn null;\n\t\t\t// try to unwrap true branch to single instruction:\n\t\t\tvar trueInstruction = Block.Unwrap(ifInst.TrueInst);\n\t\t\t// if the true branch is a block with multiple instructions:\n\t\t\t// try to apply the combine exits transform to the nested block\n\t\t\t// and then continue on that transformed block.\n\t\t\t// Example:\n\t\t\t// if (cond) {\n\t\t\t//   if (cond2) {\n\t\t\t//     leave (value)\n\t\t\t//   }\n\t\t\t//   leave (value2)\n\t\t\t// }\n\t\t\t// leave (value3)\n\t\t\t// =>\n\t\t\t// leave (if (cond) value else if (cond2) value2 else value3)\n\t\t\tif (trueInstruction is Block nestedBlock && nestedBlock.Instructions.Count == 2)\n\t\t\t\ttrueInstruction = CombineExits(nestedBlock);\n\t\t\tif (!(trueInstruction is Leave leave))\n\t\t\t\treturn null;\n\t\t\tif (!(leave.IsLeavingFunction && leaveElse.IsLeavingFunction))\n\t\t\t\treturn null;\n\t\t\tif (leave.Value.MatchNop() || leaveElse.Value.MatchNop())\n\t\t\t\treturn null;\n\t\t\t// if (cond) {\n\t\t\t//   leave (value)\n\t\t\t// }\n\t\t\t// leave (elseValue)\n\t\t\t// =>\n\t\t\t// leave (if (cond) value else elseValue)\n\t\t\tIfInstruction value = new IfInstruction(ifInst.Condition, leave.Value, leaveElse.Value);\n\t\t\tvalue.AddILRange(ifInst);\n\t\t\tLeave combinedLeave = new Leave(leave.TargetContainer, value);\n\t\t\tcombinedLeave.AddILRange(leaveElse);\n\t\t\tcombinedLeave.AddILRange(leave);\n\t\t\tifInst.ReplaceWith(combinedLeave);\n\t\t\tblock.Instructions.RemoveAt(combinedLeave.ChildIndex + 1);\n\t\t\treturn combinedLeave;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/CopyPropagation.cs",
    "content": "// Copyright (c) 2011-2015 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Runs a very simple form of copy propagation.\n\t/// Copy propagation is used in two cases:\n\t/// 1) assignments from arguments to local variables\n\t///    If the target variable is assigned to only once (so always is that argument) and the argument is never changed (no ldarga/starg),\n\t///    then we can replace the variable with the argument.\n\t/// 2) assignments of address-loading instructions to local variables\n\t/// </summary>\n\tpublic class CopyPropagation : IILTransform\n\t{\n\t\tpublic static void Propagate(StLoc store, ILTransformContext context)\n\t\t{\n\t\t\tDebug.Assert(store.Variable.IsSingleDefinition);\n\t\t\tBlock block = (Block)store.Parent;\n\t\t\tint i = store.ChildIndex;\n\t\t\tDoPropagate(store.Variable, store.Value, block, ref i, context);\n\t\t}\n\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tvar splitVariables = new HashSet<ILVariable>(ILVariableEqualityComparer.Instance);\n\t\t\tforeach (var g in function.Variables.GroupBy(v => v, ILVariableEqualityComparer.Instance))\n\t\t\t{\n\t\t\t\tif (g.Count() > 1)\n\t\t\t\t{\n\t\t\t\t\tsplitVariables.Add(g.Key);\n\t\t\t\t}\n\t\t\t}\n\t\t\tforeach (var block in function.Descendants.OfType<Block>())\n\t\t\t{\n\t\t\t\tif (block.Kind != BlockKind.ControlFlow)\n\t\t\t\t\tcontinue;\n\t\t\t\tRunOnBlock(block, context, splitVariables);\n\t\t\t}\n\t\t}\n\n\t\tstatic void RunOnBlock(Block block, ILTransformContext context, HashSet<ILVariable> splitVariables = null)\n\t\t{\n\t\t\tfor (int i = 0; i < block.Instructions.Count; i++)\n\t\t\t{\n\t\t\t\tif (block.Instructions[i].MatchStLoc(out ILVariable v, out ILInstruction copiedExpr))\n\t\t\t\t{\n\t\t\t\t\tif (v.IsSingleDefinition && v.LoadCount == 0 && v.Kind == VariableKind.StackSlot)\n\t\t\t\t\t{\n\t\t\t\t\t\t// dead store to stack\n\t\t\t\t\t\tif (SemanticHelper.IsPure(copiedExpr.Flags))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// no-op -> delete\n\t\t\t\t\t\t\tcontext.Step(\"remove dead store to stack: no-op -> delete\", block.Instructions[i]);\n\t\t\t\t\t\t\tblock.Instructions.RemoveAt(i);\n\t\t\t\t\t\t\t// This can open up new inlining opportunities:\n\t\t\t\t\t\t\tint c = ILInlining.InlineInto(block, i, InliningOptions.None, context: context);\n\t\t\t\t\t\t\ti -= c + 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// evaluate the value for its side-effects\n\t\t\t\t\t\t\tcontext.Step(\"remove dead store to stack: evaluate the value for its side-effects\", block.Instructions[i]);\n\t\t\t\t\t\t\tcopiedExpr.AddILRange(block.Instructions[i]);\n\t\t\t\t\t\t\tblock.Instructions[i] = copiedExpr;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (v.IsSingleDefinition && CanPerformCopyPropagation(v, copiedExpr, splitVariables, context.Settings))\n\t\t\t\t\t{\n\t\t\t\t\t\tDoPropagate(v, copiedExpr, block, ref i, context);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic bool CanPerformCopyPropagation(ILVariable target, ILInstruction value, HashSet<ILVariable> splitVariables, DecompilerSettings settings)\n\t\t{\n\t\t\tDebug.Assert(target.StackType == value.ResultType);\n\t\t\tif (target.Type.IsSmallIntegerType())\n\t\t\t\treturn false;\n\t\t\tif (splitVariables != null && splitVariables.Contains(target))\n\t\t\t{\n\t\t\t\treturn false; // non-local code move might change semantics when there's split variables\n\t\t\t}\n\t\t\tswitch (value.OpCode)\n\t\t\t{\n\t\t\t\tcase OpCode.LdLoca:\n\t\t\t\tcase OpCode.LdsFlda:\n\t\t\t\t\t// All address-loading instructions always return the same value for a given operand/argument combination,\n\t\t\t\t\t// so they can be safely copied.\n\t\t\t\t\t// ... except for LdElema and LdFlda, because those might throw an exception, and we don't want to\n\t\t\t\t\t// change the place where the exception is thrown.\n\t\t\t\t\treturn true;\n\t\t\t\tcase OpCode.LdElema:\n\t\t\t\tcase OpCode.LdFlda:\n\t\t\t\t\treturn !settings.UseRefLocalsForAccurateOrderOfEvaluation;\n\t\t\t\tcase OpCode.LdLoc:\n\t\t\t\t\tvar v = ((LdLoc)value).Variable;\n\t\t\t\t\tif (splitVariables != null && splitVariables.Contains(v))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false; // non-local code move might change semantics when there's split variables\n\t\t\t\t\t}\n\t\t\t\t\tswitch (v.Kind)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase VariableKind.Parameter:\n\t\t\t\t\t\t\t// Parameters can be copied only if they aren't assigned to (directly or indirectly via ldarga)\n\t\t\t\t\t\t\t// note: the initialization by the caller is the first store -> StoreCount must be 1\n\t\t\t\t\t\t\treturn v.IsSingleDefinition;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t// Variables can be copied if both are single-definition.\n\t\t\t\t\t\t\t// To avoid removing too many variables, we do this only if the target\n\t\t\t\t\t\t\t// is either a stackslot or a ref local.\n\t\t\t\t\t\t\tDebug.Assert(target.IsSingleDefinition);\n\t\t\t\t\t\t\treturn v.IsSingleDefinition && (target.Kind == VariableKind.StackSlot || target.StackType == StackType.Ref);\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\t// All instructions without special behavior that target a stack-variable can be copied.\n\t\t\t\t\treturn value.Flags == InstructionFlags.None && value.Children.Count == 0 && target.Kind == VariableKind.StackSlot;\n\t\t\t}\n\t\t}\n\n\t\tstatic void DoPropagate(ILVariable v, ILInstruction copiedExpr, Block block, ref int i, ILTransformContext context)\n\t\t{\n\t\t\tcontext.Step($\"Copy propagate {v.Name}\", copiedExpr);\n\t\t\t// un-inline the arguments of the ldArg instruction\n\t\t\tILVariable[] uninlinedArgs = new ILVariable[copiedExpr.Children.Count];\n\t\t\tfor (int j = 0; j < uninlinedArgs.Length; j++)\n\t\t\t{\n\t\t\t\tvar arg = copiedExpr.Children[j];\n\t\t\t\tvar type = context.TypeSystem.FindType(arg.ResultType);\n\t\t\t\tuninlinedArgs[j] = new ILVariable(VariableKind.StackSlot, type, arg.ResultType) {\n\t\t\t\t\tName = \"C_\" + arg.StartILOffset,\n\t\t\t\t\tHasGeneratedName = true,\n\t\t\t\t};\n\t\t\t\tblock.Instructions.Insert(i++, new StLoc(uninlinedArgs[j], arg));\n\t\t\t}\n\t\t\tv.Function.Variables.AddRange(uninlinedArgs);\n\t\t\t// perform copy propagation:\n\t\t\tforeach (var expr in v.LoadInstructions.ToArray())\n\t\t\t{\n\t\t\t\tvar clone = copiedExpr.Clone();\n\t\t\t\tfor (int j = 0; j < uninlinedArgs.Length; j++)\n\t\t\t\t{\n\t\t\t\t\tclone.Children[j].ReplaceWith(new LdLoc(uninlinedArgs[j]));\n\t\t\t\t}\n\t\t\t\t// We are copying an expression from far away, reusing the ILRange would result in incorrect sequence points.\n\t\t\t\tclone.SetILRange(new Interval());\n\t\t\t\texpr.ReplaceWith(clone);\n\t\t\t}\n\t\t\tblock.Instructions.RemoveAt(i);\n\t\t\tint c = ILInlining.InlineInto(block, i, InliningOptions.None, context: context);\n\t\t\ti -= c + 1;\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/DeconstructionTransform.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing System.Resources;\n\nusing ICSharpCode.Decompiler.CSharp.Resolver;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// \n\t/// </summary>\n\tclass DeconstructionTransform : IStatementTransform\n\t{\n\t\tStatementTransformContext context;\n\t\treadonly Dictionary<ILVariable, int> deconstructionResultsLookup = new Dictionary<ILVariable, int>();\n\t\tILVariable[] deconstructionResults;\n\t\tILVariable tupleVariable;\n\t\tTupleType tupleType;\n\n\t\t/*\n\t\t\tstloc tuple(call MakeIntIntTuple(ldloc this))\n\t\t----\n\t\t\tstloc myInt(call op_Implicit(ldfld Item2(ldloca tuple)))\n\t\t\tstloc a(ldfld Item1(ldloca tuple))\n\t\t\tstloc b(ldloc myInt)\n\t\t==>\n\t\t\tdeconstruct {\n\t\t\t\tinit:\n\t\t\t\t\t<empty>\n\t\t\t\tdeconstruct:\n\t\t\t\t\tmatch.deconstruct(temp = ldloca tuple) {\n\t\t\t\t\t\tmatch(result0 = deconstruct.result 0(temp)),\n\t\t\t\t\t\tmatch(result1 = deconstruct.result 1(temp))\n\t\t\t\t\t}\n\t\t\t\tconversions: {\n\t\t\t\t\tstloc conv2(call op_Implicit(ldloc result1))\n\t\t\t\t}\n\t\t\t\tassignments: {\n\t\t\t\t\tstloc a(ldloc result0)\n\t\t\t\t\tstloc b(ldloc conv2)\n\t\t\t\t}\n\t\t\t}\n\t\t * */\n\t\tvoid IStatementTransform.Run(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.Deconstruction)\n\t\t\t\treturn;\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tthis.context = context;\n\t\t\t\tReset();\n\n\t\t\t\tif (TransformDeconstruction(block, pos))\n\t\t\t\t\treturn;\n\t\t\t\tif (InlineDeconstructionInitializer(block, pos))\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tthis.context = null;\n\t\t\t\tReset();\n\t\t\t}\n\t\t}\n\n\t\tprivate void Reset()\n\t\t{\n\t\t\tthis.deconstructionResultsLookup.Clear();\n\t\t\tthis.tupleVariable = null;\n\t\t\tthis.tupleType = null;\n\t\t\tthis.deconstructionResults = null;\n\t\t}\n\n\t\tstruct ConversionInfo\n\t\t{\n\t\t\tpublic IType inputType;\n\t\t\tpublic Conv conv;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Get index of deconstruction result or tuple element\n\t\t/// Returns -1 on failure.\n\t\t/// </summary>\n\t\tint FindIndex(ILInstruction inst, out Action<DeconstructInstruction> delayedActions)\n\t\t{\n\t\t\tdelayedActions = null;\n\t\t\tif (inst.MatchLdLoc(out var v))\n\t\t\t{\n\t\t\t\tif (!deconstructionResultsLookup.TryGetValue(v, out int index))\n\t\t\t\t\treturn -1;\n\t\t\t\treturn index;\n\t\t\t}\n\t\t\tif (inst.MatchLdFld(out _, out _))\n\t\t\t{\n\t\t\t\tif (!TupleTransform.MatchTupleFieldAccess((LdFlda)((LdObj)inst).Target, out var tupleType, out var target, out int index))\n\t\t\t\t\treturn -1;\n\t\t\t\t// Item fields are one-based, we use zero-based indexing.\n\t\t\t\tindex--;\n\t\t\t\t// normalize tuple type\n\t\t\t\ttupleType = TupleType.FromUnderlyingType(context.TypeSystem, tupleType);\n\t\t\t\tif (!target.MatchLdLoca(out v))\n\t\t\t\t\treturn -1;\n\t\t\t\tif (this.tupleVariable == null)\n\t\t\t\t{\n\t\t\t\t\tthis.tupleVariable = v;\n\t\t\t\t\tthis.tupleType = (TupleType)tupleType;\n\t\t\t\t\tthis.deconstructionResults = new ILVariable[this.tupleType.Cardinality];\n\t\t\t\t}\n\t\t\t\tif (this.tupleType.Cardinality < 2)\n\t\t\t\t\treturn -1;\n\t\t\t\tif (v != tupleVariable || !this.tupleType.Equals(tupleType))\n\t\t\t\t\treturn -1;\n\t\t\t\tif (this.deconstructionResults[index] == null)\n\t\t\t\t{\n\t\t\t\t\tvar freshVar = new ILVariable(VariableKind.StackSlot, this.tupleType.ElementTypes[index]) { Name = \"E_\" + index };\n\t\t\t\t\tdelayedActions += _ => context.Function.Variables.Add(freshVar);\n\t\t\t\t\tthis.deconstructionResults[index] = freshVar;\n\t\t\t\t}\n\t\t\t\tdelayedActions += _ => {\n\t\t\t\t\tinst.ReplaceWith(new LdLoc(this.deconstructionResults[index]));\n\t\t\t\t};\n\t\t\t\treturn index;\n\t\t\t}\n\t\t\treturn -1;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// stloc v(value)\n\t\t/// expr(..., deconstruct { ... }, ...)\n\t\t/// =>\n\t\t/// expr(..., deconstruct { init: stloc v(value) ... }, ...)\n\t\t/// </summary>\n\t\tbool InlineDeconstructionInitializer(Block block, int pos)\n\t\t{\n\t\t\tif (!block.Instructions[pos].MatchStLoc(out var v, out var value))\n\t\t\t\treturn false;\n\t\t\tif (!(v.IsSingleDefinition && v.LoadCount == 1))\n\t\t\t\treturn false;\n\t\t\tif (pos + 1 >= block.Instructions.Count)\n\t\t\t\treturn false;\n\t\t\tvar result = ILInlining.FindLoadInNext(block.Instructions[pos + 1], v, value, InliningOptions.FindDeconstruction);\n\t\t\tif (result.Type != ILInlining.FindResultType.Deconstruction)\n\t\t\t\treturn false;\n\t\t\tvar deconstruction = (DeconstructInstruction)result.LoadInst;\n\t\t\tLdLoc loadInst = v.LoadInstructions[0];\n\t\t\tif (!loadInst.IsDescendantOf(deconstruction.Assignments))\n\t\t\t\treturn false;\n\t\t\tif (loadInst.SlotInfo == StObj.TargetSlot)\n\t\t\t{\n\t\t\t\tif (value.OpCode == OpCode.LdFlda || value.OpCode == OpCode.LdElema)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (deconstruction.Init.Count > 0)\n\t\t\t{\n\t\t\t\tvar a = deconstruction.Init[0].Variable.LoadInstructions.Single();\n\t\t\t\tvar b = v.LoadInstructions.Single();\n\t\t\t\tif (!b.IsBefore(a))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tcontext.Step(\"InlineDeconstructionInitializer\", block.Instructions[pos]);\n\t\t\tdeconstruction.Init.Insert(0, (StLoc)block.Instructions[pos]);\n\t\t\tblock.Instructions.RemoveAt(pos);\n\t\t\tv.Kind = VariableKind.DeconstructionInitTemporary;\n\t\t\treturn true;\n\t\t}\n\n\t\tbool TransformDeconstruction(Block block, int pos)\n\t\t{\n\t\t\tint startPos = pos;\n\t\t\tAction<DeconstructInstruction> delayedActions = null;\n\t\t\tif (MatchDeconstruction(block.Instructions[pos], out IMethod deconstructMethod,\n\t\t\t\tout ILInstruction rootTestedOperand))\n\t\t\t{\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\tif (!MatchConversions(block, ref pos, out var conversions, out var conversionStLocs, ref delayedActions))\n\t\t\t\treturn false;\n\n\t\t\tif (!MatchAssignments(block, ref pos, conversions, conversionStLocs, ref delayedActions))\n\t\t\t\treturn false;\n\t\t\t// first tuple element may not be discarded,\n\t\t\t// otherwise we would run this transform on a suffix of the actual pattern.\n\t\t\tif (deconstructionResults[0] == null)\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"Deconstruction\", block.Instructions[startPos]);\n\t\t\tDeconstructInstruction replacement = new DeconstructInstruction();\n\t\t\tIType deconstructedType;\n\t\t\tif (deconstructMethod == null)\n\t\t\t{\n\t\t\t\tdeconstructedType = this.tupleType;\n\t\t\t\trootTestedOperand = new LdLoc(this.tupleVariable);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (deconstructMethod.IsStatic)\n\t\t\t\t{\n\t\t\t\t\tdeconstructedType = deconstructMethod.Parameters[0].Type;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tdeconstructedType = deconstructMethod.DeclaringType;\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar rootTempVariable = context.Function.RegisterVariable(VariableKind.PatternLocal, deconstructedType);\n\t\t\treplacement.Pattern = new MatchInstruction(rootTempVariable, deconstructMethod, rootTestedOperand) {\n\t\t\t\tIsDeconstructCall = deconstructMethod != null,\n\t\t\t\tIsDeconstructTuple = this.tupleType != null\n\t\t\t};\n\t\t\tint index = 0;\n\t\t\tforeach (ILVariable v in deconstructionResults)\n\t\t\t{\n\t\t\t\tvar result = v;\n\t\t\t\tif (result == null)\n\t\t\t\t{\n\t\t\t\t\tvar freshVar = new ILVariable(VariableKind.PatternLocal, this.tupleType.ElementTypes[index]) { Name = \"E_\" + index };\n\t\t\t\t\tcontext.Function.Variables.Add(freshVar);\n\t\t\t\t\tresult = freshVar;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tresult.Kind = VariableKind.PatternLocal;\n\t\t\t\t}\n\t\t\t\treplacement.Pattern.SubPatterns.Add(\n\t\t\t\t\tnew MatchInstruction(\n\t\t\t\t\t\tresult,\n\t\t\t\t\t\tnew DeconstructResultInstruction(index, result.StackType, new LdLoc(rootTempVariable))\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t\tindex++;\n\t\t\t}\n\t\t\treplacement.Conversions = new Block(BlockKind.DeconstructionConversions);\n\t\t\tforeach (var convInst in conversionStLocs)\n\t\t\t{\n\t\t\t\treplacement.Conversions.Instructions.Add(convInst);\n\t\t\t}\n\t\t\treplacement.Assignments = new Block(BlockKind.DeconstructionAssignments);\n\t\t\tdelayedActions?.Invoke(replacement);\n\t\t\tblock.Instructions[startPos] = replacement;\n\t\t\tblock.Instructions.RemoveRange(startPos + 1, pos - startPos - 1);\n\t\t\treturn true;\n\t\t}\n\n\t\tbool MatchDeconstruction(ILInstruction inst, out IMethod deconstructMethod,\n\t\t\tout ILInstruction testedOperand)\n\t\t{\n\t\t\ttestedOperand = null;\n\t\t\tdeconstructMethod = null;\n\t\t\tdeconstructionResults = null;\n\t\t\tif (!(inst is CallInstruction call))\n\t\t\t\treturn false;\n\t\t\tif (!MatchInstruction.IsDeconstructMethod(call.Method))\n\t\t\t\treturn false;\n\t\t\tif (call.Method.IsStatic || call.Method.DeclaringType.IsReferenceType == false)\n\t\t\t{\n\t\t\t\tif (!(call is Call))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (!(call is CallVirt))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (call.Arguments.Count < 3)\n\t\t\t\treturn false;\n\t\t\tdeconstructionResults = new ILVariable[call.Arguments.Count - 1];\n\t\t\tfor (int i = 0; i < deconstructionResults.Length; i++)\n\t\t\t{\n\t\t\t\tif (!call.Arguments[i + 1].MatchLdLoca(out var v))\n\t\t\t\t\treturn false;\n\t\t\t\t// TODO v.LoadCount may be 2 if the deconstruction is assigned to a tuple variable\n\t\t\t\t// or 0? because of discards\n\t\t\t\tif (!(v.StoreCount == 0 && v.AddressCount == 1 && v.LoadCount <= 1))\n\t\t\t\t\treturn false;\n\t\t\t\tdeconstructionResultsLookup.Add(v, i);\n\t\t\t\tdeconstructionResults[i] = v;\n\t\t\t}\n\t\t\ttestedOperand = call.Arguments[0];\n\t\t\tdeconstructMethod = call.Method;\n\t\t\treturn true;\n\t\t}\n\n\t\tbool MatchConversions(Block block, ref int pos,\n\t\t\tout Dictionary<ILVariable, ConversionInfo> conversions,\n\t\t\tout List<StLoc> conversionStLocs,\n\t\t\tref Action<DeconstructInstruction> delayedActions)\n\t\t{\n\t\t\tconversions = new Dictionary<ILVariable, ConversionInfo>();\n\t\t\tconversionStLocs = new List<StLoc>();\n\t\t\tint previousIndex = -1;\n\t\t\twhile (MatchConversion(\n\t\t\t\tblock.Instructions.ElementAtOrDefault(pos), out var inputInstruction,\n\t\t\t\tout var outputVariable, out var info))\n\t\t\t{\n\t\t\t\tint index = FindIndex(inputInstruction, out var tupleAccessAdjustment);\n\t\t\t\tif (index <= previousIndex)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(outputVariable.IsSingleDefinition && outputVariable.LoadCount == 1))\n\t\t\t\t\treturn false;\n\t\t\t\tdelayedActions += tupleAccessAdjustment;\n\t\t\t\tdeconstructionResultsLookup.Add(outputVariable, index);\n\t\t\t\tconversions.Add(outputVariable, info);\n\t\t\t\tconversionStLocs.Add((StLoc)block.Instructions[pos]);\n\t\t\t\tpos++;\n\t\t\t\tpreviousIndex = index;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tbool MatchConversion(ILInstruction inst, out ILInstruction inputInstruction,\n\t\t\tout ILVariable outputVariable, out ConversionInfo info)\n\t\t{\n\t\t\tinfo = default;\n\t\t\tinputInstruction = null;\n\t\t\tif (!inst.MatchStLoc(out outputVariable, out var value))\n\t\t\t\treturn false;\n\t\t\tif (!(value is Conv conv))\n\t\t\t\treturn false;\n\t\t\tinfo = new ConversionInfo {\n\t\t\t\tinputType = conv.Argument.InferType(context.TypeSystem),\n\t\t\t\tconv = conv\n\t\t\t};\n\t\t\tinputInstruction = conv.Argument;\n\t\t\treturn true;\n\t\t}\n\n\t\tbool MatchAssignments(Block block, ref int pos,\n\t\t\tDictionary<ILVariable, ConversionInfo> conversions,\n\t\t\tList<StLoc> conversionStLocs,\n\t\t\tref Action<DeconstructInstruction> delayedActions)\n\t\t{\n\t\t\tint previousIndex = -1;\n\t\t\tint conversionStLocIndex = 0;\n\t\t\tint startPos = pos;\n\t\t\twhile (MatchAssignment(block.Instructions.ElementAtOrDefault(pos), out var targetType, out var valueInst, out var addAssignment))\n\t\t\t{\n\t\t\t\tint index = FindIndex(valueInst, out var tupleAccessAdjustment);\n\t\t\t\tif (index <= previousIndex)\n\t\t\t\t\treturn false;\n\t\t\t\tAddMissingAssignmentsForConversions(index, ref delayedActions);\n\t\t\t\tif (!(valueInst.MatchLdLoc(out var resultVariable)\n\t\t\t\t\t&& conversions.TryGetValue(resultVariable, out var conversionInfo)))\n\t\t\t\t{\n\t\t\t\t\tconversionInfo = new ConversionInfo {\n\t\t\t\t\t\tinputType = valueInst.InferType(context.TypeSystem)\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif (block.Instructions[pos].MatchStLoc(out var assignmentTarget, out _)\n\t\t\t\t\t&& assignmentTarget.Kind == VariableKind.StackSlot\n\t\t\t\t\t&& assignmentTarget.IsSingleDefinition\n\t\t\t\t\t&& conversionInfo.conv == null)\n\t\t\t\t{\n\t\t\t\t\tdelayedActions += _ => {\n\t\t\t\t\t\tassignmentTarget.Type = conversionInfo.inputType;\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (!IsCompatibleImplicitConversion(targetType, conversionInfo))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tdelayedActions += addAssignment;\n\t\t\t\tdelayedActions += tupleAccessAdjustment;\n\t\t\t\tpos++;\n\t\t\t\tpreviousIndex = index;\n\t\t\t}\n\t\t\tAddMissingAssignmentsForConversions(int.MaxValue, ref delayedActions);\n\n\t\t\tif (deconstructionResults != null)\n\t\t\t{\n\t\t\t\tint i = previousIndex + 1;\n\t\t\t\twhile (i < deconstructionResults.Length)\n\t\t\t\t{\n\t\t\t\t\tvar v = deconstructionResults[i];\n\t\t\t\t\t// this should only happen in release mode, where usually the last deconstruction element\n\t\t\t\t\t// is not stored to a temporary, if it is used directly (and only once!)\n\t\t\t\t\t// after the deconstruction.\n\t\t\t\t\tif (v?.LoadCount == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tdelayedActions += (DeconstructInstruction deconstructInst) => {\n\t\t\t\t\t\t\tvar freshVar = context.Function.RegisterVariable(VariableKind.StackSlot, v.Type);\n\t\t\t\t\t\t\tdeconstructInst.Assignments.Instructions.Add(new StLoc(freshVar, new LdLoc(v)));\n\t\t\t\t\t\t\tv.LoadInstructions[0].Variable = freshVar;\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn startPos != pos;\n\n\t\t\tvoid AddMissingAssignmentsForConversions(int index, ref Action<DeconstructInstruction> delayedActions)\n\t\t\t{\n\t\t\t\twhile (conversionStLocIndex < conversionStLocs.Count)\n\t\t\t\t{\n\t\t\t\t\tvar stLoc = conversionStLocs[conversionStLocIndex];\n\t\t\t\t\tint conversionResultIndex = deconstructionResultsLookup[stLoc.Variable];\n\n\t\t\t\t\tif (conversionResultIndex >= index)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tif (conversionResultIndex > previousIndex)\n\t\t\t\t\t{\n\t\t\t\t\t\tdelayedActions += (DeconstructInstruction deconstructInst) => {\n\t\t\t\t\t\t\tvar freshVar = context.Function.RegisterVariable(VariableKind.StackSlot, stLoc.Variable.Type);\n\t\t\t\t\t\t\tdeconstructInst.Assignments.Instructions.Add(new StLoc(stLoc.Variable, new LdLoc(freshVar)));\n\t\t\t\t\t\t\tstLoc.Variable = freshVar;\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tpreviousIndex = conversionResultIndex;\n\t\t\t\t\tconversionStLocIndex++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool MatchAssignment(ILInstruction inst, out IType targetType, out ILInstruction valueInst, out Action<DeconstructInstruction> addAssignment)\n\t\t{\n\t\t\ttargetType = null;\n\t\t\tvalueInst = null;\n\t\t\taddAssignment = null;\n\t\t\tif (inst == null)\n\t\t\t\treturn false;\n\t\t\tif (inst.MatchStLoc(out var v, out var value)\n\t\t\t\t&& value is Block block && block.MatchInlineAssignBlock(out var call, out valueInst))\n\t\t\t{\n\t\t\t\tif (!DeconstructInstruction.IsAssignment(call, context.TypeSystem, out targetType, out _))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(v.IsSingleDefinition && v.LoadCount == 0))\n\t\t\t\t\treturn false;\n\t\t\t\tvar valueInstCopy = valueInst;\n\t\t\t\taddAssignment = (DeconstructInstruction deconstructInst) => {\n\t\t\t\t\tcall.Arguments[call.Arguments.Count - 1] = valueInstCopy;\n\t\t\t\t\tdeconstructInst.Assignments.Instructions.Add(call);\n\t\t\t\t};\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (DeconstructInstruction.IsAssignment(inst, context.TypeSystem, out targetType, out valueInst))\n\t\t\t{\n\t\t\t\t// OK - use the assignment as is\n\t\t\t\taddAssignment = (DeconstructInstruction deconstructInst) => {\n\t\t\t\t\tdeconstructInst.Assignments.Instructions.Add(inst);\n\t\t\t\t};\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tbool IsCompatibleImplicitConversion(IType targetType, ConversionInfo conversionInfo)\n\t\t{\n\t\t\tvar c = CSharpConversions.Get(context.TypeSystem)\n\t\t\t\t.ImplicitConversion(conversionInfo.inputType, targetType);\n\t\t\tif (!c.IsValid)\n\t\t\t\treturn false;\n\t\t\tvar inputType = conversionInfo.inputType;\n\t\t\tvar conv = conversionInfo.conv;\n\t\t\tif (c.IsIdentityConversion || c.IsReferenceConversion)\n\t\t\t{\n\t\t\t\treturn conv == null || conv.Kind == ConversionKind.Nop;\n\t\t\t}\n\t\t\tif (c.IsNumericConversion && conv != null)\n\t\t\t{\n\t\t\t\tswitch (conv.Kind)\n\t\t\t\t{\n\t\t\t\t\tcase ConversionKind.IntToFloat:\n\t\t\t\t\t\treturn inputType.GetSign() == conv.InputSign;\n\t\t\t\t\tcase ConversionKind.FloatPrecisionChange:\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tcase ConversionKind.SignExtend:\n\t\t\t\t\t\treturn inputType.GetSign() == Sign.Signed;\n\t\t\t\t\tcase ConversionKind.ZeroExtend:\n\t\t\t\t\t\treturn inputType.GetSign() == Sign.Unsigned;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs",
    "content": "// Copyright (c) 2011-2016 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Transforms anonymous methods and lambdas by creating nested ILFunctions.\n\t/// </summary>\n\tpublic class DelegateConstruction : IILTransform\n\t{\n\t\tILTransformContext context;\n\t\tITypeResolveContext decompilationContext;\n\t\treadonly Stack<MethodDefinitionHandle> activeMethods = new Stack<MethodDefinitionHandle>();\n\n\t\tvoid IILTransform.Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.AnonymousMethods)\n\t\t\t\treturn;\n\t\t\tvar prevContext = this.context;\n\t\t\tvar prevDecompilationContext = this.decompilationContext;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tactiveMethods.Push((MethodDefinitionHandle)function.Method.MetadataToken);\n\t\t\t\tthis.context = context;\n\t\t\t\tthis.decompilationContext = new SimpleTypeResolveContext(function.Method);\n\t\t\t\tvar cancellationToken = context.CancellationToken;\n\t\t\t\tforeach (var inst in function.Descendants)\n\t\t\t\t{\n\t\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tif (!MatchDelegateConstruction(inst, out var targetMethod, out var target,\n\t\t\t\t\t\tout var delegateType, allowTransformed: false))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tcontext.StepStartGroup($\"TransformDelegateConstruction {inst.StartILOffset}\", inst);\n\t\t\t\t\tILFunction f = TransformDelegateConstruction(inst, targetMethod, target, delegateType);\n\t\t\t\t\tif (f != null && target is IInstructionWithVariableOperand instWithVar)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar v = instWithVar.Variable;\n\t\t\t\t\t\tif (v.Kind == VariableKind.Local)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tv.Kind = VariableKind.DisplayClassLocal;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (v.IsSingleDefinition\n\t\t\t\t\t\t\t&& v.StoreInstructions.SingleOrDefault() is StLoc store\n\t\t\t\t\t\t\t&& store.Value is NewObj)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tv.CaptureScope = BlockContainer.FindClosestContainer(store);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcontext.StepEndGroup();\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tthis.context = prevContext;\n\t\t\t\tthis.decompilationContext = prevDecompilationContext;\n\t\t\t\tactiveMethods.Pop();\n\t\t\t}\n\t\t}\n\n\t\tinternal static bool MatchDelegateConstruction(ILInstruction inst, out IMethod targetMethod,\n\t\t\tout ILInstruction target, out IType delegateType, bool allowTransformed = false)\n\t\t{\n\t\t\ttargetMethod = null;\n\t\t\ttarget = null;\n\t\t\tdelegateType = null;\n\t\t\tswitch (inst)\n\t\t\t{\n\t\t\t\tcase NewObj call:\n\t\t\t\t\tif (call.Arguments.Count != 2)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\ttarget = call.Arguments[0];\n\t\t\t\t\tvar opCode = call.Arguments[1].OpCode;\n\t\t\t\t\tdelegateType = call.Method.DeclaringType;\n\t\t\t\t\tif (!(opCode == OpCode.LdFtn || opCode == OpCode.LdVirtFtn\n\t\t\t\t\t\t|| (allowTransformed && opCode == OpCode.ILFunction)))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\ttargetMethod = ((IInstructionWithMethodOperand)call.Arguments[1]).Method;\n\t\t\t\t\tbreak;\n\t\t\t\tcase LdVirtDelegate ldVirtDelegate:\n\t\t\t\t\ttarget = ldVirtDelegate.Argument;\n\t\t\t\t\ttargetMethod = ldVirtDelegate.Method;\n\t\t\t\t\tdelegateType = ldVirtDelegate.Type;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn delegateType.Kind == TypeKind.Delegate || delegateType.Kind == TypeKind.Unknown;\n\t\t}\n\n\t\tstatic bool IsAnonymousMethod(ITypeDefinition decompiledTypeDefinition, IMethod method)\n\t\t{\n\t\t\tif (method == null)\n\t\t\t\treturn false;\n\t\t\tif (!(method.HasGeneratedName()\n\t\t\t\t|| method.Name.Contains(\"$\")\n\t\t\t\t|| method.IsCompilerGenerated()\n\t\t\t\t|| TransformDisplayClassUsage.IsPotentialClosure(\n\t\t\t\t\tdecompiledTypeDefinition, method.DeclaringTypeDefinition)\n\t\t\t\t|| ContainsAnonymousType(method)))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic bool ContainsAnonymousType(IMethod method)\n\t\t{\n\t\t\tif (method.ReturnType.ContainsAnonymousType())\n\t\t\t\treturn true;\n\t\t\tforeach (var p in method.Parameters)\n\t\t\t{\n\t\t\t\tif (p.Type.ContainsAnonymousType())\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tstatic GenericContext? GenericContextFromTypeArguments(TypeParameterSubstitution subst)\n\t\t{\n\t\t\tvar classTypeParameters = new List<ITypeParameter>();\n\t\t\tvar methodTypeParameters = new List<ITypeParameter>();\n\t\t\tif (subst.ClassTypeArguments != null)\n\t\t\t{\n\t\t\t\tforeach (var t in subst.ClassTypeArguments)\n\t\t\t\t{\n\t\t\t\t\tif (t is ITypeParameter tp)\n\t\t\t\t\t\tclassTypeParameters.Add(tp);\n\t\t\t\t\telse\n\t\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (subst.MethodTypeArguments != null)\n\t\t\t{\n\t\t\t\tforeach (var t in subst.MethodTypeArguments)\n\t\t\t\t{\n\t\t\t\t\tif (t is ITypeParameter tp)\n\t\t\t\t\t\tmethodTypeParameters.Add(tp);\n\t\t\t\t\telse\n\t\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn new GenericContext(classTypeParameters, methodTypeParameters);\n\t\t}\n\n\t\tILFunction TransformDelegateConstruction(\n\t\t\tILInstruction value, IMethod targetMethod,\n\t\t\tILInstruction target, IType delegateType)\n\t\t{\n\t\t\tif (!IsAnonymousMethod(decompilationContext.CurrentTypeDefinition, targetMethod))\n\t\t\t\treturn null;\n\t\t\tif (targetMethod.MetadataToken.IsNil)\n\t\t\t\treturn null;\n\t\t\tif (LocalFunctionDecompiler.IsLocalFunctionMethod(targetMethod, context))\n\t\t\t\treturn null;\n\t\t\tif (!ValidateDelegateTarget(target))\n\t\t\t\treturn null;\n\t\t\tvar handle = (MethodDefinitionHandle)targetMethod.MetadataToken;\n\t\t\tif (activeMethods.Contains(handle))\n\t\t\t{\n\t\t\t\tthis.context.Function.Warnings.Add(\" Found self-referencing delegate construction. Abort transformation to avoid stack overflow.\");\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tvar methodDefinition = context.PEFile.Metadata.GetMethodDefinition((MethodDefinitionHandle)targetMethod.MetadataToken);\n\t\t\tif (!methodDefinition.HasBody())\n\t\t\t\treturn null;\n\t\t\tvar genericContext = GenericContextFromTypeArguments(targetMethod.Substitution);\n\t\t\tif (genericContext == null)\n\t\t\t\treturn null;\n\t\t\tvar ilReader = context.CreateILReader();\n\t\t\tvar body = context.PEFile.GetMethodBody(methodDefinition.RelativeVirtualAddress);\n\t\t\tvar function = ilReader.ReadIL((MethodDefinitionHandle)targetMethod.MetadataToken, body, genericContext.Value, ILFunctionKind.Delegate, context.CancellationToken);\n\t\t\tfunction.DelegateType = delegateType;\n\t\t\t// Embed the lambda into the parent function's ILAst, so that \"Show steps\" can show\n\t\t\t// how the lambda body is being transformed.\n\t\t\tvalue.ReplaceWith(function);\n\t\t\tfunction.CheckInvariant(ILPhase.Normal);\n\n\t\t\tvar contextPrefix = targetMethod.Name;\n\t\t\tforeach (ILVariable v in function.Variables.Where(v => v.Kind != VariableKind.Parameter))\n\t\t\t{\n\t\t\t\tv.Name = contextPrefix + v.Name;\n\t\t\t}\n\n\t\t\tvar nestedContext = new ILTransformContext(context, function);\n\t\t\tfunction.RunTransforms(CSharpDecompiler.GetILTransforms().TakeWhile(t => !(t is DelegateConstruction)).Concat(GetTransforms()), nestedContext);\n\t\t\tnestedContext.Step(\"DelegateConstruction (ReplaceDelegateTargetVisitor)\", function);\n\t\t\tfunction.AcceptVisitor(new ReplaceDelegateTargetVisitor(target, function.Variables.SingleOrDefault(VariableKindExtensions.IsThis)));\n\t\t\t// handle nested lambdas\n\t\t\tnestedContext.StepStartGroup(\"DelegateConstruction (nested lambdas)\", function);\n\t\t\t((IILTransform)this).Run(function, nestedContext);\n\t\t\tnestedContext.StepEndGroup();\n\t\t\tfunction.AddILRange(target);\n\t\t\tfunction.AddILRange(value);\n\t\t\tif (value is Call call)\n\t\t\t\tfunction.AddILRange(call.Arguments[1]);\n\t\t\treturn function;\n\t\t}\n\n\t\tprivate static bool ValidateDelegateTarget(ILInstruction inst)\n\t\t{\n\t\t\tswitch (inst)\n\t\t\t{\n\t\t\t\tcase LdNull _:\n\t\t\t\t\treturn true;\n\t\t\t\tcase LdLoc ldloc:\n\t\t\t\t\treturn ldloc.Variable.IsSingleDefinition;\n\t\t\t\tcase LdObj ldobj:\n\t\t\t\t\t// TODO : should make sure that the display-class 'this' is unused,\n\t\t\t\t\t// if the delegate target is ldobj(ldsflda field).\n\t\t\t\t\tif (ldobj.Target is LdsFlda)\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t// TODO : ldfld chains must be validated more thoroughly, i.e., we should make sure\n\t\t\t\t\t// that the value of the field is never changed.\n\t\t\t\t\tILInstruction target = ldobj;\n\t\t\t\t\twhile (target is LdObj || target is LdFlda)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (target is LdObj o)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttarget = o.Target;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (target is LdFlda f)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttarget = f.Target;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn target is LdLoc;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tprivate IEnumerable<IILTransform> GetTransforms()\n\t\t{\n\t\t\tyield return new CombineExitsTransform();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Replaces loads of 'this' with the target expression.\n\t\t/// Async delegates use: ldobj(ldloca this).\n\t\t/// </summary>\n\t\tinternal class ReplaceDelegateTargetVisitor : ILVisitor\n\t\t{\n\t\t\treadonly ILVariable thisVariable;\n\t\t\treadonly ILInstruction target;\n\n\t\t\tpublic ReplaceDelegateTargetVisitor(ILInstruction target, ILVariable thisVariable)\n\t\t\t{\n\t\t\t\tthis.target = target;\n\t\t\t\tthis.thisVariable = thisVariable;\n\t\t\t}\n\n\t\t\tprotected override void Default(ILInstruction inst)\n\t\t\t{\n\t\t\t\tforeach (var child in inst.Children)\n\t\t\t\t{\n\t\t\t\t\tchild.AcceptVisitor(this);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tprotected internal override void VisitILFunction(ILFunction function)\n\t\t\t{\n\t\t\t\tif (function == thisVariable?.Function)\n\t\t\t\t{\n\t\t\t\t\tILVariable v = null;\n\t\t\t\t\tswitch (target)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase LdLoc l:\n\t\t\t\t\t\t\tv = l.Variable;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase LdObj lo:\n\t\t\t\t\t\t\tILInstruction inner = lo.Target;\n\t\t\t\t\t\t\twhile (inner is LdFlda ldf)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tinner = ldf.Target;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (inner is LdLoc l2)\n\t\t\t\t\t\t\t\tv = l2.Variable;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (v != null)\n\t\t\t\t\t\tfunction.CapturedVariables.Add(v);\n\t\t\t\t}\n\t\t\t\tbase.VisitILFunction(function);\n\t\t\t}\n\n\t\t\tprotected internal override void VisitLdLoc(LdLoc inst)\n\t\t\t{\n\t\t\t\tif (inst.Variable == thisVariable)\n\t\t\t\t{\n\t\t\t\t\tinst.ReplaceWith(target.Clone());\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tbase.VisitLdLoc(inst);\n\t\t\t}\n\n\t\t\tprotected internal override void VisitLdObj(LdObj inst)\n\t\t\t{\n\t\t\t\tif (inst.Target.MatchLdLoca(thisVariable))\n\t\t\t\t{\n\t\t\t\t\tinst.ReplaceWith(target.Clone());\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tbase.VisitLdObj(inst);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/DetectCatchWhenConditionBlocks.cs",
    "content": "// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\tpublic class DetectCatchWhenConditionBlocks : IILTransform\n\t{\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tforeach (var catchBlock in function.Descendants.OfType<TryCatchHandler>())\n\t\t\t{\n\t\t\t\tif (catchBlock.Filter is BlockContainer container\n\t\t\t\t\t&& MatchCatchWhenEntryPoint(catchBlock.Variable, container, container.EntryPoint,\n\t\t\t\t\t\tout var exceptionType, out var exceptionSlot, out var whenConditionBlock)\n\t\t\t\t\t&& exceptionType.GetStackType() == catchBlock.Variable.StackType)\n\t\t\t\t{\n\t\t\t\t\t// set exceptionType\n\t\t\t\t\tcatchBlock.Variable.Type = exceptionType;\n\t\t\t\t\t// Block entryPoint (incoming: 1)  {\n\t\t\t\t\t//   stloc temp(isinst exceptionType(ldloc exceptionVar))\n\t\t\t\t\t//   if (comp(ldloc temp != ldnull)) br whenConditionBlock\n\t\t\t\t\t//   br falseBlock\n\t\t\t\t\t// }\n\t\t\t\t\t// =>\n\t\t\t\t\t// Block entryPoint (incoming: 1)  {\n\t\t\t\t\t//   stloc temp(ldloc exceptionSlot)  \n\t\t\t\t\t//   br whenConditionBlock\n\t\t\t\t\t// }\n\t\t\t\t\tvar instructions = container.EntryPoint.Instructions;\n\t\t\t\t\tif (instructions.Count == 3)\n\t\t\t\t\t{\n\t\t\t\t\t\t// stloc temp(isinst exceptionType(ldloc exceptionVar))\n\t\t\t\t\t\t// if (comp(ldloc temp != ldnull)) br whenConditionBlock\n\t\t\t\t\t\t// br falseBlock\n\t\t\t\t\t\tcontext.Step($\"Detected catch-when for {catchBlock.Variable.Name} (extra store)\", instructions[0]);\n\t\t\t\t\t\t((StLoc)instructions[0]).Value = exceptionSlot;\n\t\t\t\t\t\tinstructions[1].ReplaceWith(new Branch(whenConditionBlock));\n\t\t\t\t\t\tinstructions.RemoveAt(2);\n\t\t\t\t\t\tcontainer.SortBlocks(deleteUnreachableBlocks: true);\n\t\t\t\t\t}\n\t\t\t\t\telse if (instructions.Count == 2)\n\t\t\t\t\t{\n\t\t\t\t\t\t// if (comp(isinst exceptionType(ldloc exceptionVar) != ldnull)) br whenConditionBlock\n\t\t\t\t\t\t// br falseBlock\n\t\t\t\t\t\tcontext.Step($\"Detected catch-when for {catchBlock.Variable.Name}\", instructions[0]);\n\t\t\t\t\t\tinstructions[0].ReplaceWith(new Branch(whenConditionBlock));\n\t\t\t\t\t\tinstructions.RemoveAt(1);\n\t\t\t\t\t\tcontainer.SortBlocks(deleteUnreachableBlocks: true);\n\t\t\t\t\t}\n\n\t\t\t\t\tPropagateExceptionVariable(context, catchBlock);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// catch E_189 : 0200007C System.Exception when (BlockContainer {\n\t\t/// \tBlock IL_0079 (incoming: 1) {\n\t\t/// \t\tstloc S_30(ldloc E_189)\n\t\t/// \t\tbr IL_0085\n\t\t/// \t}\n\t\t/// \n\t\t/// \tBlock IL_0085 (incoming: 1) {\n\t\t/// \t\tstloc I_1(ldloc S_30)\n\t\t/// where S_30 and I_1 are single definition\n\t\t/// =>\n\t\t/// copy-propagate E_189 to replace all uses of S_30 and I_1\n\t\t/// </summary>\n\t\tstatic void PropagateExceptionVariable(ILTransformContext context, TryCatchHandler handler)\n\t\t{\n\t\t\tvar exceptionVariable = handler.Variable;\n\t\t\tif (!exceptionVariable.IsSingleDefinition)\n\t\t\t\treturn;\n\t\t\tcontext.StepStartGroup(nameof(PropagateExceptionVariable));\n\t\t\tint i = 0;\n\t\t\twhile (i < exceptionVariable.LoadInstructions.Count)\n\t\t\t{\n\t\t\t\tvar load = exceptionVariable.LoadInstructions[i];\n\n\t\t\t\tif (!load.IsDescendantOf(handler))\n\t\t\t\t{\n\t\t\t\t\ti++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// We are only interested in store \"statements\" copying the exception variable\n\t\t\t\t// without modifying it.\n\t\t\t\tvar statement = Block.GetContainingStatement(load);\n\t\t\t\tif (!(statement is StLoc stloc))\n\t\t\t\t{\n\t\t\t\t\ti++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// simple copy case:\n\t\t\t\t// stloc b(ldloc a)\n\t\t\t\tif (stloc.Value == load)\n\t\t\t\t{\n\t\t\t\t\tPropagateExceptionInstance(stloc);\n\t\t\t\t}\n\t\t\t\t// if the type of the cast-class instruction matches the exceptionType,\n\t\t\t\t// this cast can be removed without losing any side-effects.\n\t\t\t\t// Note: this would also hold true iff exceptionType were an exception derived\n\t\t\t\t// from cc.Type, however, we are more restrictive to match the pattern exactly.\n\t\t\t\t// stloc b(castclass exceptionType(ldloc a))\n\t\t\t\telse if (stloc.Value is CastClass cc && cc.Type.Equals(exceptionVariable.Type) && cc.Argument == load)\n\t\t\t\t{\n\t\t\t\t\tstloc.Value = load;\n\t\t\t\t\tPropagateExceptionInstance(stloc);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ti++;\n\t\t\t\t}\n\n\t\t\t\tvoid PropagateExceptionInstance(StLoc store)\n\t\t\t\t{\n\t\t\t\t\tforeach (var load in store.Variable.LoadInstructions.ToArray())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!load.IsDescendantOf(handler))\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tload.ReplaceWith(new LdLoc(exceptionVariable).WithILRange(load));\n\t\t\t\t\t}\n\t\t\t\t\tif (store.Variable.LoadCount == 0 && store.Parent is Block block)\n\t\t\t\t\t{\n\t\t\t\t\t\tblock.Instructions.RemoveAt(store.ChildIndex);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\ti++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontext.StepEndGroup(keepIfEmpty: false);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Block entryPoint (incoming: 1)  {\n\t\t///   stloc temp(isinst exceptionType(ldloc exceptionVar))\n\t\t///   if (comp(ldloc temp != ldnull)) br whenConditionBlock\n\t\t///   br falseBlock\n\t\t/// }\n\t\t/// </summary>\n\t\tbool MatchCatchWhenEntryPoint(ILVariable exceptionVar, BlockContainer container, Block entryPoint, out IType exceptionType, out ILInstruction exceptionSlot, out Block whenConditionBlock)\n\t\t{\n\t\t\texceptionType = null;\n\t\t\texceptionSlot = null;\n\t\t\twhenConditionBlock = null;\n\t\t\tif (entryPoint == null || entryPoint.IncomingEdgeCount != 1)\n\t\t\t\treturn false;\n\t\t\tif (entryPoint.Instructions.Count == 3)\n\t\t\t{\n\t\t\t\t// stloc temp(isinst exceptionType(ldloc exceptionVar))\n\t\t\t\t// if (comp(ldloc temp != ldnull)) br whenConditionBlock\n\t\t\t\t// br falseBlock\n\t\t\t\tif (!entryPoint.Instructions[0].MatchStLoc(out var temp, out var isinst) ||\n\t\t\t\t\ttemp.Kind != VariableKind.StackSlot || !isinst.MatchIsInst(out exceptionSlot, out exceptionType))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!exceptionSlot.MatchLdLoc(exceptionVar))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!entryPoint.Instructions[1].MatchIfInstruction(out var condition, out var branch))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!condition.MatchCompNotEquals(out var left, out var right))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!entryPoint.Instructions[2].MatchBranch(out var falseBlock) || !MatchFalseBlock(container, falseBlock, out var returnVar, out var exitBlock))\n\t\t\t\t\treturn false;\n\t\t\t\tif ((left.MatchLdNull() && right.MatchLdLoc(temp)) || (right.MatchLdNull() && left.MatchLdLoc(temp)))\n\t\t\t\t{\n\t\t\t\t\treturn branch.MatchBranch(out whenConditionBlock);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (entryPoint.Instructions.Count == 2)\n\t\t\t{\n\t\t\t\t// if (comp(isinst exceptionType(ldloc exceptionVar) != ldnull)) br whenConditionBlock\n\t\t\t\t// br falseBlock\n\t\t\t\tif (!entryPoint.Instructions[0].MatchIfInstruction(out var condition, out var branch))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!condition.MatchCompNotEquals(out var left, out var right))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!entryPoint.Instructions[1].MatchBranch(out var falseBlock) || !MatchFalseBlock(container, falseBlock, out var returnVar, out var exitBlock))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!left.MatchIsInst(out exceptionSlot, out exceptionType))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!exceptionSlot.MatchLdLoc(exceptionVar))\n\t\t\t\t\treturn false;\n\t\t\t\tif (right.MatchLdNull())\n\t\t\t\t{\n\t\t\t\t\treturn branch.MatchBranch(out whenConditionBlock);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Block falseBlock (incoming: 1)  {\n\t\t///   stloc returnVar(ldc.i4 0)\n\t\t///   br exitBlock\n\t\t/// }\n\t\t/// </summary>\n\t\tbool MatchFalseBlock(BlockContainer container, Block falseBlock, out ILVariable returnVar, out Block exitBlock)\n\t\t{\n\t\t\treturnVar = null;\n\t\t\texitBlock = null;\n\t\t\tif (falseBlock.IncomingEdgeCount != 1 || falseBlock.Instructions.Count != 2)\n\t\t\t\treturn false;\n\t\t\treturn falseBlock.Instructions[0].MatchStLoc(out returnVar, out var zero) &&\n\t\t\t\tzero.MatchLdcI4(0) && falseBlock.Instructions[1].MatchBranch(out exitBlock) &&\n\t\t\t\tMatchExitBlock(container, exitBlock, returnVar);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Block exitBlock(incoming: 2) {\n\t\t///   leave container(ldloc returnVar)\n\t\t/// }\n\t\t/// </summary>\n\t\tbool MatchExitBlock(BlockContainer container, Block exitBlock, ILVariable returnVar)\n\t\t{\n\t\t\tif (exitBlock.IncomingEdgeCount != 2 || exitBlock.Instructions.Count != 1)\n\t\t\t\treturn false;\n\t\t\treturn exitBlock.Instructions[0].MatchLeave(container, out var value) &&\n\t\t\t\tvalue.MatchLdLoc(returnVar);\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/DynamicCallSiteTransform.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Linq.Expressions;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Transforms the \"callsite initialization pattern\" into DynamicInstructions.\n\t/// </summary>\n\tpublic class DynamicCallSiteTransform : IILTransform\n\t{\n\t\tILTransformContext context;\n\n\t\tconst string CallSiteTypeName = \"System.Runtime.CompilerServices.CallSite\";\n\t\tconst string CSharpBinderTypeName = \"Microsoft.CSharp.RuntimeBinder.Binder\";\n\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.Dynamic)\n\t\t\t\treturn;\n\n\t\t\tthis.context = context;\n\n\t\t\tDictionary<IField, CallSiteInfo> callsites = new Dictionary<IField, CallSiteInfo>();\n\t\t\tHashSet<BlockContainer> modifiedContainers = new HashSet<BlockContainer>();\n\n\t\t\tforeach (var block in function.Descendants.OfType<Block>())\n\t\t\t{\n\t\t\t\tif (block.Instructions.Count < 2)\n\t\t\t\t\tcontinue;\n\t\t\t\t// Check if, we deal with a callsite cache field null check:\n\t\t\t\t// if (comp(ldsfld <>p__3 == ldnull)) br IL_000c\n\t\t\t\t// br IL_002b\n\t\t\t\tif (!(block.Instructions.SecondToLastOrDefault() is IfInstruction ifInst))\n\t\t\t\t\tcontinue;\n\t\t\t\tif (!(block.Instructions.LastOrDefault() is Branch branchAfterInit))\n\t\t\t\t\tcontinue;\n\t\t\t\tif (!MatchCallSiteCacheNullCheck(ifInst.Condition, out var callSiteCacheField, out var callSiteDelegate, out bool invertBranches))\n\t\t\t\t\tcontinue;\n\t\t\t\tif (!ifInst.TrueInst.MatchBranch(out var trueBlock))\n\t\t\t\t\tcontinue;\n\t\t\t\tBlock callSiteInitBlock, targetBlockAfterInit;\n\t\t\t\tif (invertBranches)\n\t\t\t\t{\n\t\t\t\t\tcallSiteInitBlock = branchAfterInit.TargetBlock;\n\t\t\t\t\ttargetBlockAfterInit = trueBlock;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcallSiteInitBlock = trueBlock;\n\t\t\t\t\ttargetBlockAfterInit = branchAfterInit.TargetBlock;\n\t\t\t\t}\n\t\t\t\tif (!ScanCallSiteInitBlock(callSiteInitBlock, callSiteCacheField, callSiteDelegate, out var callSiteInfo, out var blockAfterInit))\n\t\t\t\t\tcontinue;\n\t\t\t\tif (targetBlockAfterInit != blockAfterInit)\n\t\t\t\t\tcontinue;\n\t\t\t\tcallSiteInfo.DelegateType = callSiteDelegate;\n\t\t\t\tcallSiteInfo.ConditionalJumpToInit = ifInst;\n\t\t\t\tcallSiteInfo.Inverted = invertBranches;\n\t\t\t\tcallSiteInfo.BranchAfterInit = branchAfterInit;\n\t\t\t\tcallsites.Add(callSiteCacheField, callSiteInfo);\n\t\t\t}\n\n\t\t\tvar storesToRemove = new List<StLoc>();\n\n\t\t\tforeach (var invokeCall in function.Descendants.OfType<CallVirt>())\n\t\t\t{\n\t\t\t\tif (invokeCall.Method.DeclaringType.Kind != TypeKind.Delegate || invokeCall.Method.Name != \"Invoke\" || invokeCall.Arguments.Count == 0)\n\t\t\t\t\tcontinue;\n\t\t\t\tvar firstArgument = invokeCall.Arguments[0];\n\t\t\t\tif (firstArgument.MatchLdLoc(out var stackSlot) && stackSlot.Kind == VariableKind.StackSlot && stackSlot.IsSingleDefinition)\n\t\t\t\t{\n\t\t\t\t\tfirstArgument = ((StLoc)stackSlot.StoreInstructions[0]).Value;\n\t\t\t\t}\n\t\t\t\tif (!firstArgument.MatchLdFld(out var cacheFieldLoad, out var targetField))\n\t\t\t\t\tcontinue;\n\t\t\t\tif (!cacheFieldLoad.MatchLdsFld(out var cacheField))\n\t\t\t\t\tcontinue;\n\t\t\t\tif (!callsites.TryGetValue(cacheField, out var callsite))\n\t\t\t\t\tcontinue;\n\t\t\t\tcontext.Stepper.Step(\"Transform callsite for \" + callsite.MemberName);\n\t\t\t\tvar deadArguments = new List<ILInstruction>();\n\t\t\t\tILInstruction replacement = MakeDynamicInstruction(callsite, invokeCall, deadArguments);\n\t\t\t\tif (replacement == null)\n\t\t\t\t\tcontinue;\n\t\t\t\tinvokeCall.ReplaceWith(replacement);\n\t\t\t\tDebug.Assert(callsite.ConditionalJumpToInit?.Parent is Block);\n\t\t\t\tvar block = ((Block)callsite.ConditionalJumpToInit.Parent);\n\t\t\t\tif (callsite.Inverted)\n\t\t\t\t{\n\t\t\t\t\tblock.Instructions.Remove(callsite.ConditionalJumpToInit);\n\t\t\t\t\tcallsite.BranchAfterInit.ReplaceWith(callsite.ConditionalJumpToInit.TrueInst);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tblock.Instructions.Remove(callsite.ConditionalJumpToInit);\n\t\t\t\t}\n\t\t\t\tforeach (var arg in deadArguments)\n\t\t\t\t{\n\t\t\t\t\tif (arg.MatchLdLoc(out var temporary) && temporary.Kind == VariableKind.StackSlot && temporary.IsSingleDefinition && temporary.LoadCount == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tStLoc stLoc = (StLoc)temporary.StoreInstructions[0];\n\t\t\t\t\t\tif (stLoc.Parent is Block storeParentBlock)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar value = stLoc.Value;\n\t\t\t\t\t\t\tif (value.MatchLdsFld(out var cacheFieldCopy) && cacheFieldCopy.Equals(cacheField))\n\t\t\t\t\t\t\t\tstoresToRemove.Add(stLoc);\n\t\t\t\t\t\t\tif (value.MatchLdFld(out cacheFieldLoad, out var targetFieldCopy) && cacheFieldLoad.MatchLdsFld(out cacheFieldCopy) && cacheField.Equals(cacheFieldCopy) && targetField.Equals(targetFieldCopy))\n\t\t\t\t\t\t\t\tstoresToRemove.Add(stLoc);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tmodifiedContainers.Add((BlockContainer)block.Parent);\n\t\t\t}\n\n\t\t\tforeach (var inst in storesToRemove)\n\t\t\t{\n\t\t\t\tBlock parentBlock = (Block)inst.Parent;\n\t\t\t\tparentBlock.Instructions.RemoveAt(inst.ChildIndex);\n\t\t\t}\n\n\t\t\tforeach (var container in modifiedContainers)\n\t\t\t\tcontainer.SortBlocks(deleteUnreachableBlocks: true);\n\t\t}\n\n\t\tILInstruction MakeDynamicInstruction(CallSiteInfo callsite, CallVirt targetInvokeCall, List<ILInstruction> deadArguments)\n\t\t{\n\t\t\tswitch (callsite.Kind)\n\t\t\t{\n\t\t\t\tcase BinderMethodKind.BinaryOperation:\n\t\t\t\t\tdeadArguments.AddRange(targetInvokeCall.Arguments.Take(2));\n\t\t\t\t\treturn new DynamicBinaryOperatorInstruction(\n\t\t\t\t\t\tbinderFlags: callsite.Flags,\n\t\t\t\t\t\toperation: callsite.Operation,\n\t\t\t\t\t\tcontext: callsite.Context,\n\t\t\t\t\t\tleftArgumentInfo: callsite.ArgumentInfos[0],\n\t\t\t\t\t\tleft: targetInvokeCall.Arguments[2],\n\t\t\t\t\t\trightArgumentInfo: callsite.ArgumentInfos[1],\n\t\t\t\t\t\tright: targetInvokeCall.Arguments[3]\n\t\t\t\t\t);\n\t\t\t\tcase BinderMethodKind.Convert:\n\t\t\t\t\tdeadArguments.AddRange(targetInvokeCall.Arguments.Take(2));\n\t\t\t\t\tILInstruction result = new DynamicConvertInstruction(\n\t\t\t\t\t\tbinderFlags: callsite.Flags,\n\t\t\t\t\t\tcontext: callsite.Context,\n\t\t\t\t\t\ttype: callsite.ConvertTargetType,\n\t\t\t\t\t\targument: targetInvokeCall.Arguments[2]\n\t\t\t\t\t);\n\t\t\t\t\tif (result.ResultType == StackType.Unknown)\n\t\t\t\t\t{\n\t\t\t\t\t\t// if references are missing, we need to coerce the primitive type to None.\n\t\t\t\t\t\t// Otherwise we will get loads of assertions.\n\t\t\t\t\t\tresult = new Conv(result, PrimitiveType.None, ((DynamicConvertInstruction)result).IsChecked, Sign.None);\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\tcase BinderMethodKind.GetIndex:\n\t\t\t\t\tdeadArguments.AddRange(targetInvokeCall.Arguments.Take(2));\n\t\t\t\t\treturn new DynamicGetIndexInstruction(\n\t\t\t\t\t\tbinderFlags: callsite.Flags,\n\t\t\t\t\t\tcontext: callsite.Context,\n\t\t\t\t\t\targumentInfo: callsite.ArgumentInfos,\n\t\t\t\t\t\targuments: targetInvokeCall.Arguments.Skip(2).ToArray()\n\t\t\t\t\t);\n\t\t\t\tcase BinderMethodKind.GetMember:\n\t\t\t\t\tdeadArguments.AddRange(targetInvokeCall.Arguments.Take(2));\n\t\t\t\t\treturn new DynamicGetMemberInstruction(\n\t\t\t\t\t\tbinderFlags: callsite.Flags,\n\t\t\t\t\t\tname: callsite.MemberName,\n\t\t\t\t\t\tcontext: callsite.Context,\n\t\t\t\t\t\ttargetArgumentInfo: callsite.ArgumentInfos[0],\n\t\t\t\t\t\ttarget: targetInvokeCall.Arguments[2]\n\t\t\t\t\t);\n\t\t\t\tcase BinderMethodKind.Invoke:\n\t\t\t\t\tdeadArguments.AddRange(targetInvokeCall.Arguments.Take(2));\n\t\t\t\t\treturn new DynamicInvokeInstruction(\n\t\t\t\t\t\tbinderFlags: callsite.Flags,\n\t\t\t\t\t\tcontext: callsite.Context,\n\t\t\t\t\t\targumentInfo: callsite.ArgumentInfos,\n\t\t\t\t\t\targuments: targetInvokeCall.Arguments.Skip(2).ToArray()\n\t\t\t\t\t);\n\t\t\t\tcase BinderMethodKind.InvokeConstructor:\n\t\t\t\t\tvar arguments = targetInvokeCall.Arguments.Skip(2).ToArray();\n\t\t\t\t\t// Extract type information from targetInvokeCall:\n\t\t\t\t\t// Must either be an inlined type or\n\t\t\t\t\t// a reference to a variable that is initialized with a type.\n\t\t\t\t\tif (!TransformExpressionTrees.MatchGetTypeFromHandle(arguments[0], out var type))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!(arguments[0].MatchLdLoc(out var temp) && temp.IsSingleDefinition && temp.StoreInstructions.FirstOrDefault() is StLoc initStore))\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\tif (!TransformExpressionTrees.MatchGetTypeFromHandle(initStore.Value, out type))\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tdeadArguments.AddRange(targetInvokeCall.Arguments.Take(2));\n\t\t\t\t\treturn new DynamicInvokeConstructorInstruction(\n\t\t\t\t\t\tbinderFlags: callsite.Flags,\n\t\t\t\t\t\ttype: type ?? SpecialType.UnknownType,\n\t\t\t\t\t\tcontext: callsite.Context,\n\t\t\t\t\t\targumentInfo: callsite.ArgumentInfos,\n\t\t\t\t\t\targuments: arguments\n\t\t\t\t\t);\n\t\t\t\tcase BinderMethodKind.InvokeMember:\n\t\t\t\t\tdeadArguments.AddRange(targetInvokeCall.Arguments.Take(2));\n\t\t\t\t\treturn new DynamicInvokeMemberInstruction(\n\t\t\t\t\t\tbinderFlags: callsite.Flags,\n\t\t\t\t\t\tname: callsite.MemberName,\n\t\t\t\t\t\ttypeArguments: callsite.TypeArguments,\n\t\t\t\t\t\tcontext: callsite.Context,\n\t\t\t\t\t\targumentInfo: callsite.ArgumentInfos,\n\t\t\t\t\t\targuments: targetInvokeCall.Arguments.Skip(2).ToArray()\n\t\t\t\t\t);\n\t\t\t\tcase BinderMethodKind.IsEvent:\n\t\t\t\t\tdeadArguments.AddRange(targetInvokeCall.Arguments.Take(2));\n\t\t\t\t\treturn new DynamicIsEventInstruction(\n\t\t\t\t\t\tbinderFlags: callsite.Flags,\n\t\t\t\t\t\tname: callsite.MemberName,\n\t\t\t\t\t\tcontext: callsite.Context,\n\t\t\t\t\t\targument: targetInvokeCall.Arguments[2]\n\t\t\t\t\t);\n\t\t\t\tcase BinderMethodKind.SetIndex:\n\t\t\t\t\tdeadArguments.AddRange(targetInvokeCall.Arguments.Take(2));\n\t\t\t\t\treturn new DynamicSetIndexInstruction(\n\t\t\t\t\t\tbinderFlags: callsite.Flags,\n\t\t\t\t\t\tcontext: callsite.Context,\n\t\t\t\t\t\targumentInfo: callsite.ArgumentInfos,\n\t\t\t\t\t\targuments: targetInvokeCall.Arguments.Skip(2).ToArray()\n\t\t\t\t\t);\n\t\t\t\tcase BinderMethodKind.SetMember:\n\t\t\t\t\tdeadArguments.AddRange(targetInvokeCall.Arguments.Take(2));\n\t\t\t\t\treturn new DynamicSetMemberInstruction(\n\t\t\t\t\t\tbinderFlags: callsite.Flags,\n\t\t\t\t\t\tname: callsite.MemberName,\n\t\t\t\t\t\tcontext: callsite.Context,\n\t\t\t\t\t\ttargetArgumentInfo: callsite.ArgumentInfos[0],\n\t\t\t\t\t\ttarget: targetInvokeCall.Arguments[2],\n\t\t\t\t\t\tvalueArgumentInfo: callsite.ArgumentInfos[1],\n\t\t\t\t\t\tvalue: targetInvokeCall.Arguments[3]\n\t\t\t\t\t);\n\t\t\t\tcase BinderMethodKind.UnaryOperation:\n\t\t\t\t\tdeadArguments.AddRange(targetInvokeCall.Arguments.Take(2));\n\t\t\t\t\treturn new DynamicUnaryOperatorInstruction(\n\t\t\t\t\t\tbinderFlags: callsite.Flags,\n\t\t\t\t\t\toperation: callsite.Operation,\n\t\t\t\t\t\tcontext: callsite.Context,\n\t\t\t\t\t\toperandArgumentInfo: callsite.ArgumentInfos[0],\n\t\t\t\t\t\toperand: targetInvokeCall.Arguments[2]\n\t\t\t\t\t);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException($\"Value {callsite.Kind} is not supported!\");\n\t\t\t}\n\t\t}\n\n\t\tbool ScanCallSiteInitBlock(Block callSiteInitBlock, IField callSiteCacheField, IType callSiteDelegateType, out CallSiteInfo callSiteInfo, out Block blockAfterInit)\n\t\t{\n\t\t\tcallSiteInfo = default(CallSiteInfo);\n\t\t\tblockAfterInit = null;\n\t\t\tint instCount = callSiteInitBlock.Instructions.Count;\n\t\t\tif (callSiteInitBlock.IncomingEdgeCount != 1 || instCount < 2)\n\t\t\t\treturn false;\n\t\t\tif (!callSiteInitBlock.Instructions[instCount - 1].MatchBranch(out blockAfterInit))\n\t\t\t\treturn false;\n\t\t\tif (!callSiteInitBlock.Instructions[instCount - 2].MatchStsFld(out var field, out var value) || !field.Equals(callSiteCacheField))\n\t\t\t\treturn false;\n\t\t\tif (!(value is Call createBinderCall) || createBinderCall.Method.TypeArguments.Count != 0 || createBinderCall.Arguments.Count != 1 || createBinderCall.Method.Name != \"Create\" || createBinderCall.Method.DeclaringType.FullName != CallSiteTypeName || createBinderCall.Method.DeclaringType.TypeArguments.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (!(createBinderCall.Arguments[0] is Call binderCall) || binderCall.Method.DeclaringType.FullName != CSharpBinderTypeName || binderCall.Method.DeclaringType.TypeParameterCount != 0)\n\t\t\t\treturn false;\n\t\t\tcallSiteInfo.DelegateType = callSiteDelegateType;\n\t\t\tcallSiteInfo.InitBlock = callSiteInitBlock;\n\t\t\tswitch (binderCall.Method.Name)\n\t\t\t{\n\t\t\t\tcase \"IsEvent\":\n\t\t\t\t\tcallSiteInfo.Kind = BinderMethodKind.IsEvent;\n\t\t\t\t\t// In the case of Binder.IsEvent all arguments should already be properly inlined, as there is no array initializer:\n\t\t\t\t\t// Scan arguments: binder flags, member name, context type\n\t\t\t\t\tif (binderCall.Arguments.Count != 3)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!binderCall.Arguments[0].MatchLdcI4(out int binderFlagsInteger))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcallSiteInfo.Flags = (CSharpBinderFlags)binderFlagsInteger;\n\t\t\t\t\tif (!binderCall.Arguments[1].MatchLdStr(out string name))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcallSiteInfo.MemberName = name;\n\t\t\t\t\tif (!TransformExpressionTrees.MatchGetTypeFromHandle(binderCall.Arguments[2], out var contextType))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcallSiteInfo.Context = contextType;\n\t\t\t\t\treturn true;\n\t\t\t\tcase \"Convert\":\n\t\t\t\t\tcallSiteInfo.Kind = BinderMethodKind.Convert;\n\t\t\t\t\t// In the case of Binder.Convert all arguments should already be properly inlined, as there is no array initializer:\n\t\t\t\t\t// Scan arguments: binder flags, target type, context type\n\t\t\t\t\tif (binderCall.Arguments.Count != 3)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!binderCall.Arguments[0].MatchLdcI4(out binderFlagsInteger))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcallSiteInfo.Flags = (CSharpBinderFlags)binderFlagsInteger;\n\t\t\t\t\tif (!TransformExpressionTrees.MatchGetTypeFromHandle(binderCall.Arguments[1], out var targetType))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcallSiteInfo.ConvertTargetType = targetType;\n\t\t\t\t\tif (!TransformExpressionTrees.MatchGetTypeFromHandle(binderCall.Arguments[2], out contextType))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcallSiteInfo.Context = contextType;\n\t\t\t\t\treturn true;\n\t\t\t\tcase \"InvokeMember\":\n\t\t\t\t\tcallSiteInfo.Kind = BinderMethodKind.InvokeMember;\n\t\t\t\t\tif (binderCall.Arguments.Count != 5)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t// First argument: binder flags\n\t\t\t\t\t// The value must be a single ldc.i4 instruction.\n\t\t\t\t\tif (!binderCall.Arguments[0].MatchLdLoc(out var variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!callSiteInitBlock.Instructions[0].MatchStLoc(variable, out value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!value.MatchLdcI4(out binderFlagsInteger))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcallSiteInfo.Flags = (CSharpBinderFlags)binderFlagsInteger;\n\t\t\t\t\t// Second argument: method name\n\t\t\t\t\t// The value must be a single ldstr instruction.\n\t\t\t\t\tif (!binderCall.Arguments[1].MatchLdLoc(out variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!callSiteInitBlock.Instructions[1].MatchStLoc(variable, out value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!value.MatchLdStr(out name))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcallSiteInfo.MemberName = name;\n\t\t\t\t\t// Third argument: type arguments\n\t\t\t\t\t// The value must be either ldnull (no type arguments) or an array initializer pattern.\n\t\t\t\t\tif (!binderCall.Arguments[2].MatchLdLoc(out variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!callSiteInitBlock.Instructions[2].MatchStLoc(out var variableOrTemporary, out value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tint numberOfTypeArguments = 0;\n\t\t\t\t\tif (!value.MatchLdNull())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (value is NewArr typeArgsNewArr && typeArgsNewArr.Type.IsKnownType(KnownTypeCode.Type) && typeArgsNewArr.Indices.Count == 1 && typeArgsNewArr.Indices[0].MatchLdcI4(out numberOfTypeArguments))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!TransformArrayInitializers.HandleSimpleArrayInitializer(context.Function, callSiteInitBlock, 3, variableOrTemporary, new[] { numberOfTypeArguments }, out var typeArguments, out _))\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\tint i = 0;\n\t\t\t\t\t\t\tcallSiteInfo.TypeArguments = new IType[numberOfTypeArguments];\n\t\t\t\t\t\t\tforeach (var (_, typeArg) in typeArguments)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (!TransformExpressionTrees.MatchGetTypeFromHandle(typeArg, out var type))\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\tcallSiteInfo.TypeArguments[i] = type;\n\t\t\t\t\t\t\t\ti++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tint typeArgumentsOffset = numberOfTypeArguments;\n\t\t\t\t\t// Special case for csc array initializers:\n\t\t\t\t\tif (variableOrTemporary != variable)\n\t\t\t\t\t{\n\t\t\t\t\t\t// store temporary from array initializer in variable\n\t\t\t\t\t\tif (!callSiteInitBlock.Instructions[3 + typeArgumentsOffset].MatchStLoc(variable, out value))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!value.MatchLdLoc(variableOrTemporary))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\ttypeArgumentsOffset++;\n\t\t\t\t\t}\n\t\t\t\t\t// Fourth argument: context type\n\t\t\t\t\tif (!binderCall.Arguments[3].MatchLdLoc(out variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!callSiteInitBlock.Instructions[3 + typeArgumentsOffset].MatchStLoc(variable, out value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!TransformExpressionTrees.MatchGetTypeFromHandle(value, out contextType))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcallSiteInfo.Context = contextType;\n\t\t\t\t\t// Fifth argument: call parameter info\n\t\t\t\t\tif (!binderCall.Arguments[4].MatchLdLoc(out variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!callSiteInitBlock.Instructions[4 + typeArgumentsOffset].MatchStLoc(variable, out value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!ExtractArgumentInfo(value, ref callSiteInfo, 5 + typeArgumentsOffset, variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn true;\n\t\t\t\tcase \"GetMember\":\n\t\t\t\tcase \"SetMember\":\n\t\t\t\t\tcallSiteInfo.Kind = binderCall.Method.Name == \"GetMember\" ? BinderMethodKind.GetMember : BinderMethodKind.SetMember;\n\t\t\t\t\tif (binderCall.Arguments.Count != 4)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t// First argument: binder flags\n\t\t\t\t\t// The value must be a single ldc.i4 instruction.\n\t\t\t\t\tif (!binderCall.Arguments[0].MatchLdLoc(out variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!callSiteInitBlock.Instructions[0].MatchStLoc(variable, out value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!value.MatchLdcI4(out binderFlagsInteger))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcallSiteInfo.Flags = (CSharpBinderFlags)binderFlagsInteger;\n\t\t\t\t\t// Second argument: method name\n\t\t\t\t\t// The value must be a single ldstr instruction.\n\t\t\t\t\tif (!binderCall.Arguments[1].MatchLdLoc(out variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!callSiteInitBlock.Instructions[1].MatchStLoc(variable, out value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!value.MatchLdStr(out name))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcallSiteInfo.MemberName = name;\n\t\t\t\t\t// Third argument: context type\n\t\t\t\t\tif (!binderCall.Arguments[2].MatchLdLoc(out variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!callSiteInitBlock.Instructions[2].MatchStLoc(variable, out value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!TransformExpressionTrees.MatchGetTypeFromHandle(value, out contextType))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcallSiteInfo.Context = contextType;\n\t\t\t\t\t// Fourth argument: call parameter info\n\t\t\t\t\tif (!binderCall.Arguments[3].MatchLdLoc(out variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!callSiteInitBlock.Instructions[3].MatchStLoc(variable, out value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!ExtractArgumentInfo(value, ref callSiteInfo, 4, variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn true;\n\t\t\t\tcase \"GetIndex\":\n\t\t\t\tcase \"SetIndex\":\n\t\t\t\tcase \"InvokeConstructor\":\n\t\t\t\tcase \"Invoke\":\n\t\t\t\t\tswitch (binderCall.Method.Name)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase \"GetIndex\":\n\t\t\t\t\t\t\tcallSiteInfo.Kind = BinderMethodKind.GetIndex;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"SetIndex\":\n\t\t\t\t\t\t\tcallSiteInfo.Kind = BinderMethodKind.SetIndex;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"InvokeConstructor\":\n\t\t\t\t\t\t\tcallSiteInfo.Kind = BinderMethodKind.InvokeConstructor;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"Invoke\":\n\t\t\t\t\t\t\tcallSiteInfo.Kind = BinderMethodKind.Invoke;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t\t\t}\n\t\t\t\t\tif (binderCall.Arguments.Count != 3)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t// First argument: binder flags\n\t\t\t\t\t// The value must be a single ldc.i4 instruction.\n\t\t\t\t\tif (!binderCall.Arguments[0].MatchLdLoc(out variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!callSiteInitBlock.Instructions[0].MatchStLoc(variable, out value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!value.MatchLdcI4(out binderFlagsInteger))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcallSiteInfo.Flags = (CSharpBinderFlags)binderFlagsInteger;\n\t\t\t\t\t// Second argument: context type\n\t\t\t\t\tif (!binderCall.Arguments[1].MatchLdLoc(out variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!callSiteInitBlock.Instructions[1].MatchStLoc(variable, out value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!TransformExpressionTrees.MatchGetTypeFromHandle(value, out contextType))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcallSiteInfo.Context = contextType;\n\t\t\t\t\t// Third argument: call parameter info\n\t\t\t\t\tif (!binderCall.Arguments[2].MatchLdLoc(out variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!callSiteInitBlock.Instructions[2].MatchStLoc(variable, out value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!ExtractArgumentInfo(value, ref callSiteInfo, 3, variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn true;\n\t\t\t\tcase \"UnaryOperation\":\n\t\t\t\tcase \"BinaryOperation\":\n\t\t\t\t\tcallSiteInfo.Kind = binderCall.Method.Name == \"BinaryOperation\" ? BinderMethodKind.BinaryOperation : BinderMethodKind.UnaryOperation;\n\t\t\t\t\tif (binderCall.Arguments.Count != 4)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t// First argument: binder flags\n\t\t\t\t\t// The value must be a single ldc.i4 instruction.\n\t\t\t\t\tif (!binderCall.Arguments[0].MatchLdLoc(out variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!callSiteInitBlock.Instructions[0].MatchStLoc(variable, out value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!value.MatchLdcI4(out binderFlagsInteger))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcallSiteInfo.Flags = (CSharpBinderFlags)binderFlagsInteger;\n\t\t\t\t\t// Second argument: operation\n\t\t\t\t\t// The value must be a single ldc.i4 instruction.\n\t\t\t\t\tif (!binderCall.Arguments[1].MatchLdLoc(out variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!callSiteInitBlock.Instructions[1].MatchStLoc(variable, out value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!value.MatchLdcI4(out int operation))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcallSiteInfo.Operation = (ExpressionType)operation;\n\t\t\t\t\t// Third argument: context type\n\t\t\t\t\tif (!binderCall.Arguments[2].MatchLdLoc(out variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!callSiteInitBlock.Instructions[2].MatchStLoc(variable, out value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!TransformExpressionTrees.MatchGetTypeFromHandle(value, out contextType))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcallSiteInfo.Context = contextType;\n\t\t\t\t\t// Fourth argument: call parameter info\n\t\t\t\t\tif (!binderCall.Arguments[3].MatchLdLoc(out variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!callSiteInitBlock.Instructions[3].MatchStLoc(variable, out value))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!ExtractArgumentInfo(value, ref callSiteInfo, 4, variable))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tbool ExtractArgumentInfo(ILInstruction value, ref CallSiteInfo callSiteInfo, int instructionOffset, ILVariable variable)\n\t\t{\n\t\t\tif (!(value is NewArr newArr2 && newArr2.Type.FullName == \"Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo\" && newArr2.Indices.Count == 1 && newArr2.Indices[0].MatchLdcI4(out var numberOfArguments)))\n\t\t\t\treturn false;\n\t\t\tif (!TransformArrayInitializers.HandleSimpleArrayInitializer(context.Function, callSiteInfo.InitBlock, instructionOffset, variable, new[] { numberOfArguments }, out var arguments, out _))\n\t\t\t\treturn false;\n\t\t\tint i = 0;\n\t\t\tcallSiteInfo.ArgumentInfos = new CSharpArgumentInfo[numberOfArguments];\n\t\t\tIMethod invokeMethod = callSiteInfo.DelegateType.GetDelegateInvokeMethod();\n\t\t\tif (invokeMethod == null)\n\t\t\t\treturn false;\n\t\t\tvar compileTimeTypes = invokeMethod.Parameters.SelectReadOnlyArray(p => p.Type);\n\t\t\tforeach (var (_, arg) in arguments)\n\t\t\t{\n\t\t\t\tif (!(arg is Call createCall))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(createCall.Method.Name == \"Create\" && createCall.Method.DeclaringType.FullName == \"Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo\" && createCall.Arguments.Count == 2))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!createCall.Arguments[0].MatchLdcI4(out var argumentInfoFlags))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!createCall.Arguments[1].MatchLdStr(out string argumentName))\n\t\t\t\t\tif (!createCall.Arguments[1].MatchLdNull())\n\t\t\t\t\t\treturn false;\n\t\t\t\tcallSiteInfo.ArgumentInfos[i] = new CSharpArgumentInfo { Flags = (CSharpArgumentInfoFlags)argumentInfoFlags, Name = argumentName, CompileTimeType = compileTimeTypes[i + 1] };\n\t\t\t\ti++;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tbool MatchCallSiteCacheNullCheck(ILInstruction condition, out IField callSiteCacheField, out IType callSiteDelegate, out bool invertBranches)\n\t\t{\n\t\t\tcallSiteCacheField = null;\n\t\t\tcallSiteDelegate = null;\n\t\t\tinvertBranches = false;\n\t\t\tif (!condition.MatchCompEqualsNull(out var argument))\n\t\t\t{\n\t\t\t\tif (!condition.MatchCompNotEqualsNull(out argument))\n\t\t\t\t\treturn false;\n\t\t\t\tinvertBranches = true;\n\t\t\t}\n\t\t\tif (!argument.MatchLdsFld(out callSiteCacheField) || callSiteCacheField.ReturnType.TypeArguments.Count != 1 || callSiteCacheField.ReturnType.FullName != CallSiteTypeName)\n\t\t\t\treturn false;\n\t\t\tcallSiteDelegate = callSiteCacheField.ReturnType.TypeArguments[0];\n\t\t\tif (callSiteDelegate.Kind != TypeKind.Delegate)\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tstruct CallSiteInfo\n\t\t{\n\t\t\tpublic bool Inverted;\n\t\t\tpublic ILInstruction BranchAfterInit;\n\t\t\tpublic IfInstruction ConditionalJumpToInit;\n\t\t\tpublic Block InitBlock;\n\t\t\tpublic IType DelegateType;\n\t\t\tpublic BinderMethodKind Kind;\n\t\t\tpublic CSharpBinderFlags Flags;\n\t\t\tpublic ExpressionType Operation;\n\t\t\tpublic IType Context;\n\t\t\tpublic IType ConvertTargetType;\n\t\t\tpublic IType[] TypeArguments;\n\t\t\tpublic CSharpArgumentInfo[] ArgumentInfos;\n\t\t\tpublic string MemberName;\n\t\t}\n\n\t\tenum BinderMethodKind\n\t\t{\n\t\t\tBinaryOperation,\n\t\t\tConvert,\n\t\t\tGetIndex,\n\t\t\tGetMember,\n\t\t\tInvoke,\n\t\t\tInvokeConstructor,\n\t\t\tInvokeMember,\n\t\t\tIsEvent,\n\t\t\tSetIndex,\n\t\t\tSetMember,\n\t\t\tUnaryOperation\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/DynamicIsEventAssignmentTransform.cs",
    "content": "// Copyright (c) 2019 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Linq;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\tpublic class DynamicIsEventAssignmentTransform : IStatementTransform\n\t{\n\t\t/// stloc V_1(dynamic.isevent (target))\n\t\t/// if (logic.not(ldloc V_1)) Block IL_004a {\n\t\t/// \tstloc V_2(dynamic.getmember B(target))\n\t\t/// }\n\t\t/// [stloc copyOfValue(value)]\n\t\t/// if (logic.not(ldloc V_1)) Block IL_0149 {\n\t\t/// \tdynamic.setmember.compound B(target, dynamic.binary.operator AddAssign(ldloc V_2,  value))\n\t\t/// } else Block IL_0151 {\n\t\t/// \tdynamic.invokemember.invokespecial.discard add_B(target, value)\n\t\t/// }\n\t\t/// =>\n\t\t/// if (logic.not(dynamic.isevent (target))) Block IL_0149 {\n\t\t/// \tdynamic.setmember.compound B(target, dynamic.binary.operator AddAssign(dynamic.getmember B(target),  value))\n\t\t/// } else Block IL_0151 {\n\t\t/// \tdynamic.invokemember.invokespecial.discard add_B(target, value)\n\t\t/// }\n\t\tpublic void Run(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\tif (!(pos + 3 < block.Instructions.Count && block.Instructions[pos].MatchStLoc(out var flagVar, out var inst) && inst is DynamicIsEventInstruction isEvent))\n\t\t\t\treturn;\n\t\t\tif (!(flagVar.IsSingleDefinition && flagVar.LoadCount == 2))\n\t\t\t\treturn;\n\t\t\tif (!MatchLhsCacheIfInstruction(block.Instructions[pos + 1], flagVar, out var dynamicGetMemberStore))\n\t\t\t\treturn;\n\t\t\tif (!(dynamicGetMemberStore.MatchStLoc(out var getMemberVar, out inst) && inst is DynamicGetMemberInstruction getMemberInst))\n\t\t\t\treturn;\n\t\t\tint offset = 2;\n\t\t\tif (block.Instructions[pos + offset].MatchStLoc(out var valueVariable)\n\t\t\t\t&& pos + 4 < block.Instructions.Count && valueVariable.IsSingleDefinition && valueVariable.LoadCount == 2\n\t\t\t\t&& valueVariable.LoadInstructions.All(ld => ld.Parent is DynamicInstruction))\n\t\t\t{\n\t\t\t\toffset++;\n\t\t\t}\n\t\t\tforeach (var descendant in block.Instructions[pos + offset].Descendants)\n\t\t\t{\n\t\t\t\tif (!MatchIsEventAssignmentIfInstruction(descendant, isEvent, flagVar, getMemberVar, out var setMemberInst, out var getMemberVarUse, out var isEventConditionUse))\n\t\t\t\t\tcontinue;\n\t\t\t\tcontext.Step(\"DynamicIsEventAssignmentTransform\", block.Instructions[pos]);\n\t\t\t\t// Collapse duplicate condition\n\t\t\t\tgetMemberVarUse.ReplaceWith(getMemberInst);\n\t\t\t\tisEventConditionUse.ReplaceWith(isEvent);\n\t\t\t\tblock.Instructions.RemoveRange(pos, 2);\n\t\t\t\t// Reuse ExpressionTransforms\n\t\t\t\tExpressionTransforms.TransformDynamicSetMemberInstruction(setMemberInst, context);\n\t\t\t\tcontext.RequestRerun();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// if (logic.not(ldloc V_1)) Block IL_0149 {\n\t\t/// \tdynamic.setmember.compound B(target, dynamic.binary.operator AddAssign(ldloc V_2,  value))\n\t\t/// } else Block IL_0151 {\n\t\t/// \tdynamic.invokemember.invokespecial.discard add_B(target, value)\n\t\t/// }\n\t\t/// </summary>\n\t\tstatic bool MatchIsEventAssignmentIfInstruction(ILInstruction ifInst, DynamicIsEventInstruction isEvent, ILVariable flagVar, ILVariable getMemberVar,\n\t\t\tout DynamicSetMemberInstruction setMemberInst, out ILInstruction getMemberVarUse, out ILInstruction isEventConditionUse)\n\t\t{\n\t\t\tsetMemberInst = null;\n\t\t\tgetMemberVarUse = null;\n\t\t\tisEventConditionUse = null;\n\t\t\tif (!ifInst.MatchIfInstruction(out var condition, out var trueInst, out var falseInst))\n\t\t\t\treturn false;\n\t\t\tif (MatchFlagEqualsZero(condition, flagVar))\n\t\t\t{\n\t\t\t\tif (!condition.MatchCompEquals(out var left, out _))\n\t\t\t\t\treturn false;\n\t\t\t\tisEventConditionUse = left;\n\t\t\t}\n\t\t\telse if (condition.MatchLdLoc(flagVar))\n\t\t\t{\n\t\t\t\tvar tmp = trueInst;\n\t\t\t\ttrueInst = falseInst;\n\t\t\t\tfalseInst = tmp;\n\t\t\t\tisEventConditionUse = condition;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn false;\n\t\t\tsetMemberInst = Block.Unwrap(trueInst) as DynamicSetMemberInstruction;\n\t\t\tif (setMemberInst == null)\n\t\t\t\treturn false;\n\t\t\tif (!isEvent.Argument.Match(setMemberInst.Target).Success)\n\t\t\t\treturn false;\n\t\t\tif (!(Block.Unwrap(falseInst) is DynamicInvokeMemberInstruction invokeMemberInst && invokeMemberInst.Arguments.Count == 2))\n\t\t\t\treturn false;\n\t\t\tif (!isEvent.Argument.Match(invokeMemberInst.Arguments[0]).Success)\n\t\t\t\treturn false;\n\t\t\tif (!(setMemberInst.Value is DynamicBinaryOperatorInstruction binOp && binOp.Left.MatchLdLoc(getMemberVar)))\n\t\t\t\treturn false;\n\t\t\tgetMemberVarUse = binOp.Left;\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// if (logic.not(ldloc V_1)) Block IL_004a {\n\t\t/// \tstloc V_2(dynamic.getmember B(target))\n\t\t/// }\n\t\t/// </summary>\n\t\tstatic bool MatchLhsCacheIfInstruction(ILInstruction ifInst, ILVariable flagVar, out StLoc cacheStore)\n\t\t{\n\t\t\tcacheStore = null;\n\t\t\tif (!ifInst.MatchIfInstruction(out var condition, out var trueInst))\n\t\t\t\treturn false;\n\t\t\tif (!MatchFlagEqualsZero(condition, flagVar))\n\t\t\t\treturn false;\n\t\t\tcacheStore = Block.Unwrap(trueInst) as StLoc;\n\t\t\treturn cacheStore != null;\n\t\t}\n\n\t\tstatic bool MatchFlagEqualsZero(ILInstruction condition, ILVariable flagVar)\n\t\t{\n\t\t\treturn condition.MatchCompEquals(out var left, out var right)\n\t\t\t\t&& left.MatchLdLoc(flagVar)\n\t\t\t\t&& right.MatchLdcI4(0);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/EarlyExpressionTransforms.cs",
    "content": "// Copyright (c) 2017 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\tpublic class EarlyExpressionTransforms : ILVisitor, IILTransform\n\t{\n\t\tILTransformContext context;\n\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tthis.context = context;\n\t\t\tDefault(function);\n\t\t}\n\n\t\tprotected override void Default(ILInstruction inst)\n\t\t{\n\t\t\tforeach (var child in inst.Children)\n\t\t\t{\n\t\t\t\tchild.AcceptVisitor(this);\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void VisitComp(Comp inst)\n\t\t{\n\t\t\tbase.VisitComp(inst);\n\t\t\tFixComparisonKindLdNull(inst, context);\n\t\t}\n\n\t\tinternal static void FixComparisonKindLdNull(Comp inst, ILTransformContext context)\n\t\t{\n\t\t\tif (inst.IsLifted)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (inst.Right.MatchLdNull())\n\t\t\t{\n\t\t\t\tif (inst.Kind == ComparisonKind.GreaterThan)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"comp(left > ldnull)  => comp(left != ldnull)\", inst);\n\t\t\t\t\tinst.Kind = ComparisonKind.Inequality;\n\t\t\t\t}\n\t\t\t\telse if (inst.Kind == ComparisonKind.LessThanOrEqual)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"comp(left <= ldnull) => comp(left == ldnull)\", inst);\n\t\t\t\t\tinst.Kind = ComparisonKind.Equality;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (inst.Left.MatchLdNull())\n\t\t\t{\n\t\t\t\tif (inst.Kind == ComparisonKind.LessThan)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"comp(ldnull < right)  => comp(ldnull != right)\", inst);\n\t\t\t\t\tinst.Kind = ComparisonKind.Inequality;\n\t\t\t\t}\n\t\t\t\telse if (inst.Kind == ComparisonKind.GreaterThanOrEqual)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"comp(ldnull >= right) => comp(ldnull == right)\", inst);\n\t\t\t\t\tinst.Kind = ComparisonKind.Equality;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (inst.Right.MatchLdNull() && inst.Left.MatchBox(out var arg, out var type) && type.Kind == TypeKind.TypeParameter)\n\t\t\t{\n\t\t\t\tif (inst.Kind == ComparisonKind.Equality)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"comp(box T(..) == ldnull) -> comp(.. == ldnull)\", inst);\n\t\t\t\t\tinst.Left = arg;\n\t\t\t\t}\n\t\t\t\tif (inst.Kind == ComparisonKind.Inequality)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"comp(box T(..) != ldnull) -> comp(.. != ldnull)\", inst);\n\t\t\t\t\tinst.Left = arg;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void VisitStObj(StObj inst)\n\t\t{\n\t\t\tbase.VisitStObj(inst);\n\t\t\tStObjToStLoc(inst, context);\n\t\t}\n\n\t\t// This transform is required because ILInlining only works with stloc/ldloc\n\t\tinternal static bool StObjToStLoc(StObj inst, ILTransformContext context)\n\t\t{\n\t\t\tif (inst.Target.MatchLdLoca(out ILVariable v)\n\t\t\t\t&& TypeUtils.IsCompatibleTypeForMemoryAccess(v.Type, inst.Type)\n\t\t\t\t&& inst.UnalignedPrefix == 0\n\t\t\t\t&& !inst.IsVolatile)\n\t\t\t{\n\t\t\t\tcontext.Step($\"stobj(ldloca {v.Name}, ...) => stloc {v.Name}(...)\", inst);\n\t\t\t\tILInstruction replacement = new StLoc(v, inst.Value).WithILRange(inst);\n\t\t\t\tif (v.StackType == StackType.Unknown && inst.Type.Kind != TypeKind.Unknown\n\t\t\t\t\t&& inst.SlotInfo != Block.InstructionSlot)\n\t\t\t\t{\n\t\t\t\t\treplacement = new Conv(replacement, inst.Type.ToPrimitiveType(),\n\t\t\t\t\t\tcheckForOverflow: false, Sign.None);\n\t\t\t\t}\n\t\t\t\tinst.ReplaceWith(replacement);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tprotected internal override void VisitLdObj(LdObj inst)\n\t\t{\n\t\t\tbase.VisitLdObj(inst);\n\t\t\tAddressOfLdLocToLdLoca(inst, context);\n\t\t\tLdObjToLdLoc(inst, context);\n\t\t}\n\n\t\tinternal static bool LdObjToLdLoc(LdObj inst, ILTransformContext context)\n\t\t{\n\t\t\tif (inst.Target.MatchLdLoca(out ILVariable v)\n\t\t\t\t&& TypeUtils.IsCompatibleTypeForMemoryAccess(v.Type, inst.Type)\n\t\t\t\t&& inst.UnalignedPrefix == 0\n\t\t\t\t&& !inst.IsVolatile)\n\t\t\t{\n\t\t\t\tcontext.Step($\"ldobj(ldloca {v.Name}) => ldloc {v.Name}\", inst);\n\t\t\t\tILInstruction replacement = new LdLoc(v).WithILRange(inst);\n\t\t\t\tif (v.StackType == StackType.Unknown && inst.Type.Kind != TypeKind.Unknown)\n\t\t\t\t{\n\t\t\t\t\treplacement = new Conv(replacement, inst.Type.ToPrimitiveType(),\n\t\t\t\t\t\tcheckForOverflow: false, Sign.None);\n\t\t\t\t}\n\t\t\t\tinst.ReplaceWith(replacement);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tinternal static void AddressOfLdLocToLdLoca(LdObj inst, ILTransformContext context)\n\t\t{\n\t\t\t// ldobj(...(addressof(ldloc V))) where ... can be zero or more ldflda instructions\n\t\t\t// =>\n\t\t\t// ldobj(...(ldloca V))\n\t\t\tvar temp = inst.Target;\n\t\t\tvar range = temp.ILRanges;\n\t\t\twhile (temp.MatchLdFlda(out var ldfldaTarget, out _))\n\t\t\t{\n\t\t\t\ttemp = ldfldaTarget;\n\t\t\t\trange = range.Concat(temp.ILRanges);\n\t\t\t}\n\t\t\tif (temp.MatchAddressOf(out var addressOfTarget, out _) && addressOfTarget.MatchLdLoc(out var v))\n\t\t\t{\n\t\t\t\tcontext.Step($\"ldobj(...(addressof(ldloca {v.Name}))) => ldobj(...(ldloca {v.Name}))\", inst);\n\t\t\t\tvar replacement = new LdLoca(v).WithILRange(addressOfTarget);\n\t\t\t\tforeach (var r in range)\n\t\t\t\t{\n\t\t\t\t\treplacement = replacement.WithILRange(r);\n\t\t\t\t}\n\t\t\t\ttemp.ReplaceWith(replacement);\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void VisitNewObj(NewObj inst)\n\t\t{\n\t\t\tif (TransformDecimalCtorToConstant(inst, out LdcDecimal decimalConstant))\n\t\t\t{\n\t\t\t\tcontext.Step(\"TransformDecimalCtorToConstant\", inst);\n\t\t\t\tinst.ReplaceWith(decimalConstant);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tbase.VisitNewObj(inst);\n\t\t}\n\n\t\tbool TransformDecimalCtorToConstant(NewObj inst, out LdcDecimal result)\n\t\t{\n\t\t\tIType t = inst.Method.DeclaringType;\n\t\t\tresult = null;\n\t\t\tif (!t.IsKnownType(KnownTypeCode.Decimal))\n\t\t\t\treturn false;\n\t\t\tvar args = inst.Arguments;\n\t\t\tif (args.Count == 1)\n\t\t\t{\n\t\t\t\tlong val;\n\t\t\t\tif (args[0].MatchLdcI(out val))\n\t\t\t\t{\n\t\t\t\t\tvar paramType = inst.Method.Parameters[0].Type.GetDefinition()?.KnownTypeCode;\n\t\t\t\t\tresult = paramType switch {\n\t\t\t\t\t\tKnownTypeCode.Int32 => new LdcDecimal(new decimal(unchecked((int)val))),\n\t\t\t\t\t\tKnownTypeCode.UInt32 => new LdcDecimal(new decimal(unchecked((uint)val))),\n\t\t\t\t\t\tKnownTypeCode.Int64 => new LdcDecimal(new decimal(val)),\n\t\t\t\t\t\tKnownTypeCode.UInt64 => new LdcDecimal(new decimal(unchecked((ulong)val))),\n\t\t\t\t\t\t_ => null\n\t\t\t\t\t};\n\t\t\t\t\treturn result is not null;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (args.Count == 5)\n\t\t\t{\n\t\t\t\tint lo, mid, hi, isNegative, scale;\n\t\t\t\tif (args[0].MatchLdcI4(out lo) && args[1].MatchLdcI4(out mid) &&\n\t\t\t\t\targs[2].MatchLdcI4(out hi) && args[3].MatchLdcI4(out isNegative) &&\n\t\t\t\t\targs[4].MatchLdcI4(out scale) && unchecked((byte)scale) <= 28)\n\t\t\t\t{\n\t\t\t\t\tresult = new LdcDecimal(new decimal(lo, mid, hi, isNegative != 0, unchecked((byte)scale)));\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs",
    "content": "// Copyright (c) 2014-2017 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Linq.Expressions;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Collection of transforms that detect simple expression patterns\n\t/// (e.g. 'cgt.un(..., ld.null)') and replace them with different instructions.\n\t/// </summary>\n\t/// <remarks>\n\t/// Should run after inlining so that the expression patterns can be detected.\n\t/// </remarks>\n\tpublic class ExpressionTransforms : ILVisitor, IStatementTransform\n\t{\n\t\tinternal StatementTransformContext context;\n\n\t\tpublic static void RunOnSingleStatement(ILInstruction statement, ILTransformContext context)\n\t\t{\n\t\t\tif (statement == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(statement));\n\t\t\tif (!(statement.Parent is Block parent))\n\t\t\t\tthrow new ArgumentException(\"ILInstruction must be a statement, i.e., direct child of a block.\");\n\t\t\tnew ExpressionTransforms().Run(parent, statement.ChildIndex, new StatementTransformContext(new BlockTransformContext(context)));\n\t\t}\n\n\t\tpublic void Run(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\tthis.context = context;\n\t\t\tcontext.StepStartGroup($\"ExpressionTransforms ({block.Label}:{pos})\", block.Instructions[pos]);\n\t\t\tblock.Instructions[pos].AcceptVisitor(this);\n\t\t\tcontext.StepEndGroup(keepIfEmpty: true);\n\t\t}\n\n\t\tprotected override void Default(ILInstruction inst)\n\t\t{\n\t\t\tforeach (var child in inst.Children)\n\t\t\t{\n\t\t\t\tchild.AcceptVisitor(this);\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void VisitBlockContainer(BlockContainer container)\n\t\t{\n\t\t\tif (container.Kind == ContainerKind.Switch)\n\t\t\t{\n\t\t\t\t// Special case for switch: Only visit the switch condition block.\n\t\t\t\tvar switchInst = (SwitchInstruction)container.EntryPoint.Instructions[0];\n\t\t\t\tswitchInst.Value.AcceptVisitor(this);\n\n\t\t\t\tHandleSwitchExpression(container, switchInst);\n\t\t\t}\n\t\t\t// No need to call base.VisitBlockContainer, see comment in VisitBlock.\n\t\t}\n\n\t\tprotected internal override void VisitBlock(Block block)\n\t\t{\n\t\t\tif (block.Kind == BlockKind.ControlFlow)\n\t\t\t{\n\t\t\t\t// Don't visit child control flow blocks;\n\t\t\t\t// since this is a block transform\n\t\t\t\t// we know those were already handled previously.\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tbase.VisitBlock(block);\n\t\t}\n\n\t\tprotected internal override void VisitComp(Comp inst)\n\t\t{\n\t\t\t// \"logic.not(arg)\" is sugar for \"comp(arg != ldc.i4 0)\"\n\t\t\tif (inst.MatchLogicNot(out var arg))\n\t\t\t{\n\t\t\t\tVisitLogicNot(inst, arg);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\telse if (inst.Kind == ComparisonKind.Inequality && inst.LiftingKind == ComparisonLiftingKind.None\n\t\t\t\t&& inst.Right.MatchLdcI4(0) && (IfInstruction.IsInConditionSlot(inst) || inst.Left is Comp))\n\t\t\t{\n\t\t\t\t// if (comp(x != 0)) ==> if (x)\n\t\t\t\t// comp(comp(...) != 0) => comp(...)\n\t\t\t\tcontext.Step(\"Remove redundant comp(... != 0)\", inst);\n\t\t\t\tinst.Left.AddILRange(inst);\n\t\t\t\tinst.ReplaceWith(inst.Left);\n\t\t\t\tinst.Left.AcceptVisitor(this);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (context.Settings.LiftNullables)\n\t\t\t{\n\t\t\t\tnew NullableLiftingTransform(context).Run(inst);\n\t\t\t}\n\n\t\t\tbase.VisitComp(inst);\n\t\t\tif (inst.IsLifted)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tEarlyExpressionTransforms.FixComparisonKindLdNull(inst, context);\n\n\t\t\tvar rightWithoutConv = inst.Right.UnwrapConv(ConversionKind.SignExtend).UnwrapConv(ConversionKind.ZeroExtend);\n\t\t\tif (rightWithoutConv.MatchLdcI4(0)\n\t\t\t\t&& inst.Sign == Sign.Unsigned\n\t\t\t\t&& (inst.Kind == ComparisonKind.GreaterThan || inst.Kind == ComparisonKind.LessThanOrEqual))\n\t\t\t{\n\t\t\t\tif (inst.Kind == ComparisonKind.GreaterThan)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"comp.unsigned(left > ldc.i4 0) => comp(left != ldc.i4 0)\", inst);\n\t\t\t\t\tinst.Kind = ComparisonKind.Inequality;\n\t\t\t\t\tVisitComp(inst);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\telse if (inst.Kind == ComparisonKind.LessThanOrEqual)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"comp.unsigned(left <= ldc.i4 0) => comp(left == ldc.i4 0)\", inst);\n\t\t\t\t\tinst.Kind = ComparisonKind.Equality;\n\t\t\t\t\tVisitComp(inst);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (rightWithoutConv.MatchLdcI4(0) && inst.Kind.IsEqualityOrInequality())\n\t\t\t{\n\t\t\t\tif (inst.Left.MatchLdLen(StackType.I, out ILInstruction array))\n\t\t\t\t{\n\t\t\t\t\t// comp.unsigned(ldlen array == conv i4->i(ldc.i4 0))\n\t\t\t\t\t// => comp(ldlen.i4 array == ldc.i4 0)\n\t\t\t\t\t// This is a special case where the C# compiler doesn't generate conv.i4 after ldlen.\n\t\t\t\t\tcontext.Step(\"comp(ldlen.i4 array == ldc.i4 0)\", inst);\n\t\t\t\t\tinst.InputType = StackType.I4;\n\t\t\t\t\tinst.Left.ReplaceWith(new LdLen(StackType.I4, array).WithILRange(inst.Left));\n\t\t\t\t\tinst.Right = rightWithoutConv;\n\t\t\t\t}\n\t\t\t\telse if (inst.Left is Conv conv && conv.TargetType == PrimitiveType.I && conv.Argument.ResultType == StackType.O)\n\t\t\t\t{\n\t\t\t\t\t// C++/CLI sometimes uses this weird comparison with null:\n\t\t\t\t\tcontext.Step(\"comp(conv o->i (ldloc obj) == conv i4->i <sign extend>(ldc.i4 0))\", inst);\n\t\t\t\t\t// -> comp(ldloc obj == ldnull)\n\t\t\t\t\tinst.InputType = StackType.O;\n\t\t\t\t\tinst.Left = conv.Argument;\n\t\t\t\t\tinst.Right = new LdNull().WithILRange(inst.Right);\n\t\t\t\t\tinst.Right.AddILRange(rightWithoutConv);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void VisitConv(Conv inst)\n\t\t{\n\t\t\tinst.Argument.AcceptVisitor(this);\n\t\t\tif (inst.Argument.MatchLdLen(StackType.I, out ILInstruction array) && inst.TargetType.IsIntegerType()\n\t\t\t\t&& (!inst.CheckForOverflow || context.Settings.AssumeArrayLengthFitsIntoInt32))\n\t\t\t{\n\t\t\t\tcontext.Step(\"conv.i4(ldlen array) => ldlen.i4(array)\", inst);\n\t\t\t\tinst.AddILRange(inst.Argument);\n\t\t\t\tinst.ReplaceWith(new LdLen(inst.TargetType.GetStackType(), array).WithILRange(inst));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (inst.TargetType.IsFloatType() && inst.Argument is Conv conv\n\t\t\t\t&& conv.Kind == ConversionKind.IntToFloat && conv.TargetType == PrimitiveType.R)\n\t\t\t{\n\t\t\t\t// IL conv.r.un does not indicate whether to convert the target type to R4 or R8,\n\t\t\t\t// so the C# compiler usually follows it with an explicit conv.r4 or conv.r8.\n\t\t\t\t// To avoid emitting '(float)(double)val', we combine these two conversions:\n\t\t\t\tcontext.Step(\"conv.rN(conv.r.un(...)) => conv.rN.un(...)\", inst);\n\t\t\t\tinst.ReplaceWith(new Conv(conv.Argument, conv.InputType, conv.InputSign, inst.TargetType, inst.CheckForOverflow, inst.IsLifted | conv.IsLifted));\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void VisitBox(Box inst)\n\t\t{\n\t\t\tinst.Argument.AcceptVisitor(this);\n\t\t\tif (inst.Type.IsReferenceType == true && inst.Argument.ResultType == inst.ResultType)\n\t\t\t{\n\t\t\t\t// For reference types, box is a no-op.\n\t\t\t\tcontext.Step(\"box ref-type(arg) => arg\", inst);\n\t\t\t\tinst.Argument.AddILRange(inst);\n\t\t\t\tinst.ReplaceWith(inst.Argument);\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void VisitLdElema(LdElema inst)\n\t\t{\n\t\t\tbase.VisitLdElema(inst);\n\t\t\tCleanUpArrayIndices(inst.Indices);\n\t\t\tif (IndexRangeTransform.HandleLdElema(inst, context))\n\t\t\t\treturn;\n\t\t}\n\n\t\tprotected internal override void VisitNewArr(NewArr inst)\n\t\t{\n\t\t\tbase.VisitNewArr(inst);\n\t\t\tCleanUpArrayIndices(inst.Indices);\n\t\t}\n\n\t\tvoid CleanUpArrayIndices(InstructionCollection<ILInstruction> indices)\n\t\t{\n\t\t\tforeach (ILInstruction index in indices)\n\t\t\t{\n\t\t\t\tif (index is Conv conv && conv.ResultType == StackType.I\n\t\t\t\t\t&& (conv.Kind == ConversionKind.Truncate && conv.CheckForOverflow\n\t\t\t\t\t\t|| conv.Kind == ConversionKind.ZeroExtend || conv.Kind == ConversionKind.SignExtend)\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"Remove conv.i from array index\", index);\n\t\t\t\t\tindex.ReplaceWith(conv.Argument);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid VisitLogicNot(Comp inst, ILInstruction arg)\n\t\t{\n\t\t\tILInstruction lhs, rhs;\n\t\t\tif (arg is Comp comp)\n\t\t\t{\n\t\t\t\tif ((!comp.InputType.IsFloatType() && !comp.IsLifted) || comp.Kind.IsEqualityOrInequality())\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"push negation into comparison\", inst);\n\t\t\t\t\tcomp.Kind = comp.Kind.Negate();\n\t\t\t\t\tcomp.AddILRange(inst);\n\t\t\t\t\tinst.ReplaceWith(comp);\n\t\t\t\t}\n\t\t\t\tcomp.AcceptVisitor(this);\n\t\t\t}\n\t\t\telse if (arg.MatchLogicAnd(out lhs, out rhs))\n\t\t\t{\n\t\t\t\t// logic.not(if (lhs) rhs else ldc.i4 0)\n\t\t\t\t// ==> if (logic.not(lhs)) ldc.i4 1 else logic.not(rhs)\n\t\t\t\tcontext.Step(\"push negation into logic.and\", inst);\n\t\t\t\tIfInstruction ifInst = (IfInstruction)arg;\n\t\t\t\tvar ldc0 = ifInst.FalseInst;\n\t\t\t\tDebug.Assert(ldc0.MatchLdcI4(0));\n\t\t\t\tifInst.Condition = Comp.LogicNot(lhs).WithILRange(inst);\n\t\t\t\tifInst.TrueInst = new LdcI4(1).WithILRange(ldc0);\n\t\t\t\tifInst.FalseInst = Comp.LogicNot(rhs).WithILRange(inst);\n\t\t\t\tinst.ReplaceWith(ifInst);\n\t\t\t\tifInst.AcceptVisitor(this);\n\t\t\t}\n\t\t\telse if (arg.MatchLogicOr(out lhs, out rhs))\n\t\t\t{\n\t\t\t\t// logic.not(if (lhs) ldc.i4 1 else rhs)\n\t\t\t\t// ==> if (logic.not(lhs)) logic.not(rhs) else ldc.i4 0)\n\t\t\t\tcontext.Step(\"push negation into logic.or\", inst);\n\t\t\t\tIfInstruction ifInst = (IfInstruction)arg;\n\t\t\t\tvar ldc1 = ifInst.TrueInst;\n\t\t\t\tDebug.Assert(ldc1.MatchLdcI4(1));\n\t\t\t\tifInst.Condition = Comp.LogicNot(lhs).WithILRange(inst);\n\t\t\t\tifInst.TrueInst = Comp.LogicNot(rhs).WithILRange(inst);\n\t\t\t\tifInst.FalseInst = new LdcI4(0).WithILRange(ldc1);\n\t\t\t\tinst.ReplaceWith(ifInst);\n\t\t\t\tifInst.AcceptVisitor(this);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\targ.AcceptVisitor(this);\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void VisitCall(Call inst)\n\t\t{\n\t\t\tif (NullableLiftingTransform.MatchGetValueOrDefault(inst, out var nullableValue, out var fallback)\n\t\t\t\t&& SemanticHelper.IsPure(fallback.Flags))\n\t\t\t{\n\t\t\t\tcontext.Step(\"call Nullable{T}.GetValueOrDefault(a, b) -> a ?? b\", inst);\n\t\t\t\tvar ldObj = new LdObj(nullableValue, inst.Method.DeclaringType);\n\t\t\t\tvar replacement = new NullCoalescingInstruction(NullCoalescingKind.NullableWithValueFallback, ldObj, fallback) {\n\t\t\t\t\tUnderlyingResultType = fallback.ResultType\n\t\t\t\t};\n\t\t\t\tinst.ReplaceWith(replacement.WithILRange(inst));\n\t\t\t\treplacement.AcceptVisitor(this);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (TransformArrayInitializers.TransformRuntimeHelpersCreateSpanInitialization(inst, context, out var replacement2))\n\t\t\t{\n\t\t\t\tcontext.Step(\"TransformRuntimeHelpersCreateSpanInitialization: single-dim\", inst);\n\t\t\t\tinst.ReplaceWith(replacement2);\n\t\t\t\treplacement2.AcceptVisitor(this);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tbase.VisitCall(inst);\n\t\t\tif (context.Settings.InlineArrays && InlineArrayTransform.RunOnExpression(inst, context))\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tTransformAssignment.HandleCompoundAssign(inst, context);\n\t\t}\n\n\t\tprotected internal override void VisitCallVirt(CallVirt inst)\n\t\t{\n\t\t\tbase.VisitCallVirt(inst);\n\t\t\tTransformAssignment.HandleCompoundAssign(inst, context);\n\t\t}\n\n\t\tprotected internal override void VisitNewObj(NewObj inst)\n\t\t{\n\t\t\tif (TransformSpanTCtorContainingStackAlloc(inst, out ILInstruction locallocSpan))\n\t\t\t{\n\t\t\t\tcontext.Step(\"new Span<T>(stackalloc) -> stackalloc Span<T>\", inst);\n\t\t\t\tinst.ReplaceWith(locallocSpan);\n\t\t\t\tILInstruction stmt = Block.GetContainingStatement(locallocSpan);\n\t\t\t\t// Special case to eliminate extra store\n\t\t\t\tif (stmt.GetNextSibling() is StLoc storeStmt && storeStmt.Value is LdLoc)\n\t\t\t\t\tILInlining.InlineIfPossible((Block)stmt.Parent, stmt.ChildIndex, context);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (TransformArrayInitializers.TransformSpanTArrayInitialization(inst, context, out var replacement))\n\t\t\t{\n\t\t\t\tcontext.Step(\"TransformSpanTArrayInitialization: single-dim\", inst);\n\t\t\t\tinst.ReplaceWith(replacement);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (TransformDelegateCtorLdVirtFtnToLdVirtDelegate(inst, out LdVirtDelegate ldVirtDelegate))\n\t\t\t{\n\t\t\t\tcontext.Step(\"new Delegate(target, ldvirtftn Method) -> ldvirtdelegate Delegate Method(target)\", inst);\n\t\t\t\tinst.ReplaceWith(ldVirtDelegate);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tbase.VisitNewObj(inst);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// newobj Delegate..ctor(target, ldvirtftn TargetMethod(target))\n\t\t/// =>\n\t\t/// ldvirtdelegate System.Delegate TargetMethod(target)\n\t\t/// </summary>\n\t\tbool TransformDelegateCtorLdVirtFtnToLdVirtDelegate(NewObj inst, out LdVirtDelegate ldVirtDelegate)\n\t\t{\n\t\t\tldVirtDelegate = null;\n\t\t\tif (inst.Method.DeclaringType.Kind != TypeKind.Delegate)\n\t\t\t\treturn false;\n\t\t\tif (inst.Arguments.Count != 2)\n\t\t\t\treturn false;\n\t\t\tif (!(inst.Arguments[1] is LdVirtFtn ldVirtFtn))\n\t\t\t\treturn false;\n\t\t\tif (!SemanticHelper.IsPure(inst.Arguments[0].Flags))\n\t\t\t\treturn false;\n\t\t\tif (!inst.Arguments[0].Match(ldVirtFtn.Argument).Success)\n\t\t\t\treturn false;\n\t\t\tldVirtDelegate = new LdVirtDelegate(inst.Arguments[0], inst.Method.DeclaringType, ldVirtFtn.Method)\n\t\t\t\t.WithILRange(inst).WithILRange(ldVirtFtn).WithILRange(ldVirtFtn.Argument);\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// newobj Span..ctor(localloc(conv i4->u &lt;zero extend&gt;(ldc.i4 sizeInBytes)), numberOfElementsExpr)\n\t\t/// =>\n\t\t/// localloc.span T(numberOfElementsExpr)\n\t\t/// \n\t\t/// -or-\n\t\t/// \n\t\t/// newobj Span..ctor(Block IL_0000 (StackAllocInitializer) {\n\t\t///\t\tstloc I_0(localloc(conv i4->u&lt;zero extend>(ldc.i4 sizeInBytes)))\n\t\t///\t\t...\n\t\t///\t\tfinal: ldloc I_0\n\t\t///\t}, numberOfElementsExpr)\n\t\t/// =>\n\t\t/// Block IL_0000 (StackAllocInitializer) {\n\t\t///\t\tstloc I_0(localloc.span T(numberOfElementsExpr))\n\t\t///\t\t...\n\t\t///\t\tfinal: ldloc I_0\n\t\t/// }\n\t\t/// </summary>\n\t\tbool TransformSpanTCtorContainingStackAlloc(NewObj newObj, out ILInstruction locallocSpan)\n\t\t{\n\t\t\tlocallocSpan = null;\n\t\t\tIType type = newObj.Method.DeclaringType;\n\t\t\tif (!type.IsKnownType(KnownTypeCode.SpanOfT) && !type.IsKnownType(KnownTypeCode.ReadOnlySpanOfT))\n\t\t\t\treturn false;\n\t\t\tif (newObj.Arguments.Count != 2 || type.TypeArguments.Count != 1)\n\t\t\t\treturn false;\n\t\t\tIType elementType = type.TypeArguments[0];\n\t\t\tif (newObj.Arguments[0].MatchLocAlloc(out var sizeInBytes) && MatchesElementCount(sizeInBytes, elementType, newObj.Arguments[1]))\n\t\t\t{\n\t\t\t\tlocallocSpan = new LocAllocSpan(newObj.Arguments[1], type);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (newObj.Arguments[0] is Block initializer && initializer.Kind == BlockKind.StackAllocInitializer)\n\t\t\t{\n\t\t\t\tif (!initializer.Instructions[0].MatchStLoc(out var initializerVariable, out var value))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(value.MatchLocAlloc(out sizeInBytes) && MatchesElementCount(sizeInBytes, elementType, newObj.Arguments[1])))\n\t\t\t\t\treturn false;\n\t\t\t\tvar newVariable = initializerVariable.Function.RegisterVariable(VariableKind.InitializerTarget, type);\n\t\t\t\tforeach (var load in initializerVariable.LoadInstructions.ToArray())\n\t\t\t\t{\n\t\t\t\t\tILInstruction newInst = new LdLoc(newVariable);\n\t\t\t\t\tnewInst.AddILRange(load);\n\t\t\t\t\tif (load.Parent != initializer)\n\t\t\t\t\t\tnewInst = new Conv(newInst, PrimitiveType.I, false, Sign.None);\n\t\t\t\t\tload.ReplaceWith(newInst);\n\t\t\t\t}\n\t\t\t\tforeach (var store in initializerVariable.StoreInstructions.ToArray())\n\t\t\t\t{\n\t\t\t\t\tstore.Variable = newVariable;\n\t\t\t\t}\n\t\t\t\tvalue.ReplaceWith(new LocAllocSpan(newObj.Arguments[1], type));\n\t\t\t\tlocallocSpan = initializer;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tbool MatchesElementCount(ILInstruction sizeInBytesInstr, IType elementType, ILInstruction elementCountInstr2)\n\t\t{\n\t\t\tvar pointerType = new PointerType(elementType);\n\t\t\tvar elementCountInstr = PointerArithmeticOffset.Detect(sizeInBytesInstr, pointerType.ElementType, checkForOverflow: true, unwrapZeroExtension: true);\n\t\t\tif (elementCountInstr == null || !elementCountInstr.UnwrapConv(ConversionKind.ZeroExtend).Match(elementCountInstr2).Success)\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tbool TransformDecimalFieldToConstant(LdObj inst, out LdcDecimal result)\n\t\t{\n\t\t\tif (inst.MatchLdsFld(out var field) && field.DeclaringType.IsKnownType(KnownTypeCode.Decimal))\n\t\t\t{\n\t\t\t\tdecimal? value = null;\n\t\t\t\tif (field.Name == \"One\")\n\t\t\t\t{\n\t\t\t\t\tvalue = decimal.One;\n\t\t\t\t}\n\t\t\t\telse if (field.Name == \"MinusOne\")\n\t\t\t\t{\n\t\t\t\t\tvalue = decimal.MinusOne;\n\t\t\t\t}\n\t\t\t\telse if (field.Name == \"Zero\")\n\t\t\t\t{\n\t\t\t\t\tvalue = decimal.Zero;\n\t\t\t\t}\n\t\t\t\tif (value != null)\n\t\t\t\t{\n\t\t\t\t\tresult = new LdcDecimal(value.Value).WithILRange(inst).WithILRange(inst.Target);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tresult = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tprotected internal override void VisitLdObj(LdObj inst)\n\t\t{\n\t\t\tbase.VisitLdObj(inst);\n\t\t\tEarlyExpressionTransforms.AddressOfLdLocToLdLoca(inst, context);\n\t\t\tif (EarlyExpressionTransforms.LdObjToLdLoc(inst, context))\n\t\t\t\treturn;\n\t\t\tif (TransformDecimalFieldToConstant(inst, out LdcDecimal decimalConstant))\n\t\t\t{\n\t\t\t\tcontext.Step(\"TransformDecimalFieldToConstant\", inst);\n\t\t\t\tinst.ReplaceWith(decimalConstant);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void VisitLdObjIfRef(LdObjIfRef inst)\n\t\t{\n\t\t\tbase.VisitLdObjIfRef(inst);\n\t\t\tif (inst.Target is AddressOf)\n\t\t\t{\n\t\t\t\tcontext.Step(\"ldobj.if.ref(addressof(...)) -> addressof(...)\", inst);\n\t\t\t\t// there already is a temporary, so the ldobj.if.ref is a no-op in both cases\n\t\t\t\tinst.ReplaceWith(inst.Target);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (inst.Target.MatchLdLoc(out var s) && s.IsSingleDefinition && s.LoadCount == 1\n\t\t\t\t&& s.StoreInstructions.SingleOrDefault() is StLoc {\n\t\t\t\t\tValue: LdLoca { Variable: { AddressCount: 1, StoreCount: 1 } }\n\t\t\t\t})\n\t\t\t{\n\t\t\t\tcontext.Step(\"Single use of ldobj.if.ref(ldloc v) -> ldloc v\", inst);\n\t\t\t\t// there already is a temporary, so the ldobj.if.ref is a no-op in both cases\n\t\t\t\tinst.ReplaceWith(inst.Target);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void VisitStObj(StObj inst)\n\t\t{\n\t\t\tbase.VisitStObj(inst);\n\t\t\tif (EarlyExpressionTransforms.StObjToStLoc(inst, context))\n\t\t\t{\n\t\t\t\tcontext.RequestRerun();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tTransformAssignment.HandleCompoundAssign(inst, context);\n\t\t}\n\n\t\tprotected internal override void VisitStLoc(StLoc inst)\n\t\t{\n\t\t\tbase.VisitStLoc(inst);\n\t\t\tTransformAssignment.HandleCompoundAssign(inst, context);\n\t\t}\n\n\t\tprotected internal override void VisitIfInstruction(IfInstruction inst)\n\t\t{\n\t\t\tinst.TrueInst.AcceptVisitor(this);\n\t\t\tinst.FalseInst.AcceptVisitor(this);\n\t\t\tinst = HandleConditionalOperator(inst);\n\n\t\t\t// Bring LogicAnd/LogicOr into their canonical forms:\n\t\t\t// if (cond) ldc.i4 0 else RHS --> if (!cond) RHS else ldc.i4 0\n\t\t\t// if (cond) RHS else ldc.i4 1 --> if (!cond) ldc.i4 1 else RHS\n\t\t\t// Be careful: when both LHS and RHS are the constant 1, we must not\n\t\t\t// swap the arguments as it would lead to an infinite transform loop.\n\t\t\tif (inst.TrueInst.MatchLdcI4(0) && !inst.FalseInst.MatchLdcI4(0)\n\t\t\t\t|| inst.FalseInst.MatchLdcI4(1) && !inst.TrueInst.MatchLdcI4(1))\n\t\t\t{\n\t\t\t\tcontext.Step(\"canonicalize logic and/or\", inst);\n\t\t\t\tvar t = inst.TrueInst;\n\t\t\t\tinst.TrueInst = inst.FalseInst;\n\t\t\t\tinst.FalseInst = t;\n\t\t\t\tinst.Condition = Comp.LogicNot(inst.Condition);\n\t\t\t}\n\t\t\t// Process condition after our potential modifications.\n\t\t\tinst.Condition.AcceptVisitor(this);\n\n\t\t\tif (new NullableLiftingTransform(context).Run(inst))\n\t\t\t{\n\t\t\t\tcontext.Step(\"NullableLiftingTransform\", inst);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (TransformDynamicAddAssignOrRemoveAssign(inst))\n\t\t\t\treturn;\n\t\t\tif (inst.MatchIfInstructionPositiveCondition(out var condition, out var trueInst, out var falseInst))\n\t\t\t{\n\t\t\t\tILInstruction transformed = UserDefinedLogicTransform.Transform(condition, trueInst, falseInst);\n\t\t\t\tif (transformed == null)\n\t\t\t\t{\n\t\t\t\t\ttransformed = UserDefinedLogicTransform.TransformDynamic(condition, trueInst, falseInst);\n\t\t\t\t}\n\t\t\t\tif (transformed != null)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"User-defined short-circuiting logic operator (roslyn pattern)\", condition);\n\t\t\t\t\ttransformed.AddILRange(inst);\n\t\t\t\t\tinst.ReplaceWith(transformed);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (MatchInstruction.IsPatternMatch(inst.Condition, out _, context.Settings)\n\t\t\t\t&& inst.TrueInst.MatchLdcI4(1) && inst.FalseInst.MatchLdcI4(0))\n\t\t\t{\n\t\t\t\tcontext.Step(\"match(x) ? true : false -> match(x)\", inst);\n\t\t\t\tinst.Condition.AddILRange(inst);\n\t\t\t\tinst.ReplaceWith(inst.Condition);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tIfInstruction HandleConditionalOperator(IfInstruction inst)\n\t\t{\n\t\t\t// if (cond) stloc A(V1) else stloc A(V2) --> stloc A(if (cond) V1 else V2)\n\t\t\tBlock trueInst = inst.TrueInst as Block;\n\t\t\tif (trueInst == null || trueInst.Instructions.Count != 1)\n\t\t\t\treturn inst;\n\t\t\tBlock falseInst = inst.FalseInst as Block;\n\t\t\tif (falseInst == null || falseInst.Instructions.Count != 1)\n\t\t\t\treturn inst;\n\t\t\tILVariable v;\n\t\t\tILInstruction value1, value2;\n\t\t\tif (trueInst.Instructions[0].MatchStLoc(out v, out value1) && falseInst.Instructions[0].MatchStLoc(v, out value2))\n\t\t\t{\n\t\t\t\tcontext.Step(\"conditional operator\", inst);\n\t\t\t\tvar newIf = new IfInstruction(Comp.LogicNot(inst.Condition), value2, value1);\n\t\t\t\tnewIf.AddILRange(inst);\n\t\t\t\tinst.ReplaceWith(new StLoc(v, newIf));\n\t\t\t\tcontext.RequestRerun();  // trigger potential inlining of the newly created StLoc\n\t\t\t\treturn newIf;\n\t\t\t}\n\t\t\treturn inst;\n\t\t}\n\n\t\tprivate void HandleSwitchExpression(BlockContainer container, SwitchInstruction switchInst)\n\t\t{\n\t\t\tif (!context.Settings.SwitchExpressions)\n\t\t\t\treturn;\n\t\t\tDebug.Assert(container.Kind == ContainerKind.Switch);\n\t\t\tDebug.Assert(container.ResultType == StackType.Void);\n\t\t\tvar defaultSection = switchInst.GetDefaultSection();\n\t\t\tStackType resultType = StackType.Void;\n\t\t\tBlockContainer leaveTarget = null;\n\t\t\tILVariable resultVariable = null;\n\t\t\tforeach (var section in switchInst.Sections)\n\t\t\t{\n\t\t\t\tif (section != defaultSection)\n\t\t\t\t{\n\t\t\t\t\t// every section except for the default must have exactly 1 label\n\t\t\t\t\tif (section.Labels.Count() != (section.HasNullLabel ? 0u : 1u))\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!section.Body.MatchBranch(out var sectionBlock))\n\t\t\t\t\treturn;\n\t\t\t\tif (sectionBlock.IncomingEdgeCount != 1)\n\t\t\t\t\treturn;\n\t\t\t\tif (sectionBlock.Parent != container)\n\t\t\t\t\treturn;\n\t\t\t\tif (sectionBlock.Instructions.Count == 1)\n\t\t\t\t{\n\t\t\t\t\tif (sectionBlock.Instructions[0] is Throw)\n\t\t\t\t\t{\n\t\t\t\t\t\t// OK\n\t\t\t\t\t}\n\t\t\t\t\telse if (sectionBlock.Instructions[0] is Leave leave)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!leave.IsLeavingFunction)\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\tleaveTarget ??= leave.TargetContainer;\n\t\t\t\t\t\tDebug.Assert(leaveTarget == leave.TargetContainer);\n\t\t\t\t\t\tresultType = leave.Value.ResultType;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (sectionBlock.Instructions.Count == 2)\n\t\t\t\t{\n\t\t\t\t\tif (!sectionBlock.Instructions[0].MatchStLoc(out var v, out _))\n\t\t\t\t\t\treturn;\n\t\t\t\t\tif (!sectionBlock.Instructions[1].MatchLeave(container))\n\t\t\t\t\t\treturn;\n\t\t\t\t\tresultVariable ??= v;\n\t\t\t\t\tif (resultVariable != v)\n\t\t\t\t\t\treturn;\n\t\t\t\t\tresultType = resultVariable.StackType;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Exactly one of resultVariable/leaveTarget must be null\n\t\t\tif ((resultVariable == null) == (leaveTarget == null))\n\t\t\t\treturn;\n\t\t\tif (switchInst.Value is StringToInt str2int)\n\t\t\t{\n\t\t\t\t// validate that each integer is used for exactly one value\n\t\t\t\tvar integersUsed = new HashSet<int>();\n\t\t\t\tforeach ((string key, int val) in str2int.Map)\n\t\t\t\t{\n\t\t\t\t\tif (!integersUsed.Add(val))\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcontext.Step(\"Switch Expression\", switchInst);\n\t\t\tswitchInst.SetResultType(resultType);\n\t\t\tforeach (var section in switchInst.Sections)\n\t\t\t{\n\t\t\t\tvar block = ((Branch)section.Body).TargetBlock;\n\t\t\t\tif (block.Instructions.Count == 1)\n\t\t\t\t{\n\t\t\t\t\tif (block.Instructions[0] is Throw t)\n\t\t\t\t\t{\n\t\t\t\t\t\tt.resultType = resultType;\n\t\t\t\t\t\tsection.Body = t;\n\t\t\t\t\t}\n\t\t\t\t\telse if (block.Instructions[0] is Leave leave)\n\t\t\t\t\t{\n\t\t\t\t\t\tsection.Body = leave.Value;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tthrow new InvalidOperationException();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsection.Body = ((StLoc)block.Instructions[0]).Value;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (resultVariable != null)\n\t\t\t{\n\t\t\t\tcontainer.ReplaceWith(new StLoc(resultVariable, switchInst));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tcontainer.ReplaceWith(new Leave(leaveTarget, switchInst));\n\t\t\t}\n\t\t\tcontext.RequestRerun(); // new StLoc might trigger inlining\n\t\t}\n\n\t\t/// <summary>\n\t\t/// op is either add or remove/subtract:\n\t\t/// if (dynamic.isevent (target)) {\n\t\t///     dynamic.invokemember.invokespecial.discard op_Name(target, value)\n\t\t/// } else {\n\t\t///     dynamic.compound.op (dynamic.getmember Name(target), value)\n\t\t/// }\n\t\t/// =>\n\t\t/// dynamic.compound.op (dynamic.getmember Name(target), value)\n\t\t/// </summary>\n\t\tbool TransformDynamicAddAssignOrRemoveAssign(IfInstruction inst)\n\t\t{\n\t\t\tif (!inst.MatchIfInstructionPositiveCondition(out var condition, out var trueInst, out var falseInst))\n\t\t\t\treturn false;\n\t\t\tif (!(condition is DynamicIsEventInstruction isEvent))\n\t\t\t\treturn false;\n\t\t\ttrueInst = Block.Unwrap(trueInst);\n\t\t\tfalseInst = Block.Unwrap(falseInst);\n\t\t\tif (!(falseInst is DynamicCompoundAssign dynamicCompoundAssign))\n\t\t\t\treturn false;\n\t\t\tif (!(dynamicCompoundAssign.Target is DynamicGetMemberInstruction getMember))\n\t\t\t\treturn false;\n\t\t\tif (!SemanticHelper.IsPure(isEvent.Argument.Flags))\n\t\t\t\treturn false;\n\t\t\tif (!isEvent.Argument.Match(getMember.Target).Success)\n\t\t\t\treturn false;\n\t\t\tif (!(trueInst is DynamicInvokeMemberInstruction invokeMember))\n\t\t\t\treturn false;\n\t\t\tif (!(invokeMember.BinderFlags.HasFlag(CSharpBinderFlags.InvokeSpecialName) && invokeMember.BinderFlags.HasFlag(CSharpBinderFlags.ResultDiscarded)))\n\t\t\t\treturn false;\n\t\t\tswitch (dynamicCompoundAssign.Operation)\n\t\t\t{\n\t\t\t\tcase ExpressionType.AddAssign:\n\t\t\t\t\tif (invokeMember.Name != \"add_\" + getMember.Name)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tbreak;\n\t\t\t\tcase ExpressionType.SubtractAssign:\n\t\t\t\t\tif (invokeMember.Name != \"remove_\" + getMember.Name)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!dynamicCompoundAssign.Value.Match(invokeMember.Arguments[1]).Success)\n\t\t\t\treturn false;\n\t\t\tif (!invokeMember.Arguments[0].Match(getMember.Target).Success)\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"+= / -= dynamic.isevent pattern -> dynamic.compound.op\", inst);\n\t\t\tinst.ReplaceWith(dynamicCompoundAssign);\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// dynamic.setmember.compound Name(target, dynamic.binary.operator op(dynamic.getmember Name(target), value))\n\t\t/// =>\n\t\t/// dynamic.compound.op (dynamic.getmember Name(target), value)\n\t\t/// </summary>\n\t\tprotected internal override void VisitDynamicSetMemberInstruction(DynamicSetMemberInstruction inst)\n\t\t{\n\t\t\tbase.VisitDynamicSetMemberInstruction(inst);\n\t\t\tTransformDynamicSetMemberInstruction(inst, context);\n\t\t}\n\n\t\tinternal static void TransformDynamicSetMemberInstruction(DynamicSetMemberInstruction inst, StatementTransformContext context)\n\t\t{\n\t\t\tif (!inst.BinderFlags.HasFlag(CSharpBinderFlags.ValueFromCompoundAssignment))\n\t\t\t\treturn;\n\t\t\tif (!(inst.Value is DynamicBinaryOperatorInstruction binaryOp))\n\t\t\t\treturn;\n\t\t\tif (!(binaryOp.Left is DynamicGetMemberInstruction dynamicGetMember))\n\t\t\t\treturn;\n\t\t\tif (!dynamicGetMember.Target.Match(inst.Target).Success)\n\t\t\t\treturn;\n\t\t\tif (!SemanticHelper.IsPure(dynamicGetMember.Target.Flags))\n\t\t\t\treturn;\n\t\t\tif (inst.Name != dynamicGetMember.Name || !DynamicCompoundAssign.IsExpressionTypeSupported(binaryOp.Operation))\n\t\t\t\treturn;\n\t\t\tcontext.Step(\"dynamic.setmember.compound -> dynamic.compound.op\", inst);\n\t\t\tinst.ReplaceWith(new DynamicCompoundAssign(binaryOp.Operation, binaryOp.BinderFlags, binaryOp.Left, binaryOp.LeftArgumentInfo, binaryOp.Right, binaryOp.RightArgumentInfo));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// dynamic.setindex.compound(target, index, dynamic.binary.operator op(dynamic.getindex(target, index), value))\n\t\t/// =>\n\t\t/// dynamic.compound.op (dynamic.getindex(target, index), value)\n\t\t/// </summary>\n\t\tprotected internal override void VisitDynamicSetIndexInstruction(DynamicSetIndexInstruction inst)\n\t\t{\n\t\t\tbase.VisitDynamicSetIndexInstruction(inst);\n\n\t\t\tif (!inst.BinderFlags.HasFlag(CSharpBinderFlags.ValueFromCompoundAssignment))\n\t\t\t\treturn;\n\t\t\tif (!(inst.Arguments.LastOrDefault() is DynamicBinaryOperatorInstruction binaryOp))\n\t\t\t\treturn;\n\t\t\tif (!(binaryOp.Left is DynamicGetIndexInstruction dynamicGetIndex))\n\t\t\t\treturn;\n\t\t\tif (inst.Arguments.Count != dynamicGetIndex.Arguments.Count + 1)\n\t\t\t\treturn;\n\t\t\t// Ensure that same arguments are passed to dynamicGetIndex and inst:\n\t\t\tfor (int j = 0; j < dynamicGetIndex.Arguments.Count; j++)\n\t\t\t{\n\t\t\t\tif (!SemanticHelper.IsPure(dynamicGetIndex.Arguments[j].Flags))\n\t\t\t\t\treturn;\n\t\t\t\tif (!dynamicGetIndex.Arguments[j].Match(inst.Arguments[j]).Success)\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!DynamicCompoundAssign.IsExpressionTypeSupported(binaryOp.Operation))\n\t\t\t\treturn;\n\t\t\tcontext.Step(\"dynamic.setindex.compound -> dynamic.compound.op\", inst);\n\t\t\tinst.ReplaceWith(new DynamicCompoundAssign(binaryOp.Operation, binaryOp.BinderFlags, binaryOp.Left, binaryOp.LeftArgumentInfo, binaryOp.Right, binaryOp.RightArgumentInfo));\n\t\t}\n\n\t\tprotected internal override void VisitBinaryNumericInstruction(BinaryNumericInstruction inst)\n\t\t{\n\t\t\tbase.VisitBinaryNumericInstruction(inst);\n\t\t\tswitch (inst.Operator)\n\t\t\t{\n\t\t\t\tcase BinaryNumericOperator.ShiftLeft:\n\t\t\t\tcase BinaryNumericOperator.ShiftRight:\n\t\t\t\t\tif (inst.Right.MatchBinaryNumericInstruction(BinaryNumericOperator.BitAnd, out var lhs, out var rhs)\n\t\t\t\t\t\t&& MatchExpectedShiftSize(rhs))\n\t\t\t\t\t{\n\t\t\t\t\t\t// a << (b & 31) => a << b\n\t\t\t\t\t\tcontext.Step(\"Combine bit.and into shift\", inst);\n\t\t\t\t\t\tinst.Right = lhs;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase BinaryNumericOperator.BitAnd:\n\t\t\t\t\tif (inst.Left.InferType(context.TypeSystem).IsKnownType(KnownTypeCode.Boolean)\n\t\t\t\t\t\t&& inst.Right.InferType(context.TypeSystem).IsKnownType(KnownTypeCode.Boolean))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (new NullableLiftingTransform(context).Run(inst))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// e.g. \"(a.GetValueOrDefault() == b.GetValueOrDefault()) & (a.HasValue & b.HasValue)\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tbool MatchExpectedShiftSize(ILInstruction rhs)\n\t\t\t{\n\t\t\t\tswitch (inst.ResultType)\n\t\t\t\t{\n\t\t\t\t\tcase StackType.I4:\n\t\t\t\t\t\treturn rhs.MatchLdcI4(31);\n\t\t\t\t\tcase StackType.I8:\n\t\t\t\t\t\treturn rhs.MatchLdcI4(63);\n\t\t\t\t\tcase StackType.I:\n\t\t\t\t\t\t// sizeof(IntPtr) * 8 - 1\n\t\t\t\t\t\treturn rhs.MatchBinaryNumericInstruction(BinaryNumericOperator.Sub, out var mult, out var one)\n\t\t\t\t\t\t\t&& mult.MatchBinaryNumericInstruction(BinaryNumericOperator.Mul, out var size, out var eight)\n\t\t\t\t\t\t\t&& size.MatchSizeOf(out var sizeofType) && sizeofType.GetStackType() == StackType.I\n\t\t\t\t\t\t\t&& eight.MatchLdcI4(8) && one.MatchLdcI4(1);\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void VisitTryCatchHandler(TryCatchHandler inst)\n\t\t{\n\t\t\tbase.VisitTryCatchHandler(inst);\n\t\t\tif (inst.Filter is BlockContainer filterContainer && filterContainer.Blocks.Count == 1)\n\t\t\t{\n\t\t\t\tTransformCatchWhen(inst, filterContainer.EntryPoint);\n\t\t\t}\n\t\t\tif (inst.Body is BlockContainer catchContainer)\n\t\t\t\tTransformCatchVariable(inst, catchContainer.EntryPoint, isCatchBlock: true);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// catch ex : TException when (...) BlockContainer {\n\t\t/// \tBlock entryPoint (incoming: 1) {\n\t\t/// \t\tstloc v(ldloc ex)\n\t\t/// \t\t...\n\t\t/// \t}\n\t\t/// }\n\t\t/// =>\n\t\t/// catch v : TException when (...) BlockContainer {\n\t\t/// \tBlock entryPoint (incoming: 1) {\n\t\t/// \t\t...\n\t\t/// \t}\n\t\t/// }\n\t\t/// </summary>\n\t\tvoid TransformCatchVariable(TryCatchHandler handler, Block entryPoint, bool isCatchBlock)\n\t\t{\n\t\t\tif (!handler.Variable.IsSingleDefinition || handler.Variable.LoadCount != 1)\n\t\t\t\treturn; // handler.Variable already has non-trivial uses\n\t\t\tif (!entryPoint.Instructions[0].MatchStLoc(out var exceptionVar, out var exceptionSlotLoad))\n\t\t\t{\n\t\t\t\t// Not the pattern with a second exceptionVar.\n\t\t\t\t// However, it is still possible that we need to remove a pointless UnboxAny:\n\t\t\t\tif (handler.Variable.LoadInstructions.Single().Parent is UnboxAny inlinedUnboxAny)\n\t\t\t\t{\n\t\t\t\t\tif (inlinedUnboxAny.Type.Equals(handler.Variable.Type))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontext.Step(\"TransformCatchVariable - remove inlined UnboxAny\", inlinedUnboxAny);\n\t\t\t\t\t\tinlinedUnboxAny.ReplaceWith(inlinedUnboxAny.Argument);\n\t\t\t\t\t\tforeach (var range in inlinedUnboxAny.ILRanges)\n\t\t\t\t\t\t\thandler.AddExceptionSpecifierILRange(range);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (exceptionVar.Kind != VariableKind.Local && exceptionVar.Kind != VariableKind.StackSlot)\n\t\t\t\treturn;\n\t\t\tif (exceptionSlotLoad is UnboxAny unboxAny)\n\t\t\t{\n\t\t\t\t// When catching a type parameter, csc emits an unbox.any instruction\n\t\t\t\tif (!unboxAny.Type.Equals(handler.Variable.Type))\n\t\t\t\t\treturn;\n\t\t\t\texceptionSlotLoad = unboxAny.Argument;\n\t\t\t}\n\t\t\tif (!exceptionSlotLoad.MatchLdLoc(handler.Variable))\n\t\t\t\treturn;\n\t\t\t// Check that exceptionVar is only used within the catch block:\n\t\t\tvar allUses = exceptionVar.LoadInstructions\n\t\t\t\t.Concat(exceptionVar.StoreInstructions.Cast<ILInstruction>())\n\t\t\t\t.Concat(exceptionVar.AddressInstructions);\n\t\t\tforeach (var inst in allUses)\n\t\t\t{\n\t\t\t\tif (!inst.IsDescendantOf(handler))\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t\tcontext.Step(\"TransformCatchVariable\", entryPoint.Instructions[0]);\n\t\t\texceptionVar.Kind = VariableKind.ExceptionLocal;\n\t\t\texceptionVar.Name = handler.Variable.Name;\n\t\t\texceptionVar.Type = handler.Variable.Type;\n\t\t\texceptionVar.HasGeneratedName = handler.Variable.HasGeneratedName;\n\t\t\thandler.Variable = exceptionVar;\n\t\t\tif (isCatchBlock)\n\t\t\t{\n\t\t\t\tforeach (var offset in entryPoint.Instructions[0].Descendants.SelectMany(o => o.ILRanges))\n\t\t\t\t\thandler.AddExceptionSpecifierILRange(offset);\n\t\t\t}\n\t\t\tentryPoint.Instructions.RemoveAt(0);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Inline condition from catch-when condition BlockContainer, if possible.\n\t\t/// </summary>\n\t\tvoid TransformCatchWhen(TryCatchHandler handler, Block entryPoint)\n\t\t{\n\t\t\tTransformCatchVariable(handler, entryPoint, isCatchBlock: false);\n\t\t\tif (entryPoint.Instructions.Count == 1 && entryPoint.Instructions[0].MatchLeave(out _, out var condition))\n\t\t\t{\n\t\t\t\tcontext.Step(\"TransformCatchWhen\", entryPoint.Instructions[0]);\n\t\t\t\thandler.Filter = condition;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/FixRemainingIncrements.cs",
    "content": "// Copyright (c) 2019 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\tpublic class FixRemainingIncrements : IILTransform\n\t{\n\t\tvoid IILTransform.Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tvar callsToFix = new List<Call>();\n\t\t\tforeach (var call in function.Descendants.OfType<Call>())\n\t\t\t{\n\t\t\t\tif (!UserDefinedCompoundAssign.IsIncrementOrDecrement(call.Method, context.Settings))\n\t\t\t\t\tcontinue;\n\t\t\t\tif (call.Arguments.Count != 1)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (call.Method.DeclaringType.IsKnownType(KnownTypeCode.Decimal))\n\t\t\t\t{\n\t\t\t\t\t// For decimal, legacy csc can optimize \"d + 1m\" to \"op_Increment(d)\".\n\t\t\t\t\t// We can handle these calls in ReplaceMethodCallsWithOperators.\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcallsToFix.Add(call);\n\t\t\t}\n\t\t\tforeach (var call in callsToFix)\n\t\t\t{\n\t\t\t\t// A user-defined increment/decrement that was not handled by TransformAssignment.\n\t\t\t\t// This can happen because the variable-being-incremented was optimized out by Roslyn,\n\t\t\t\t// e.g.\n\t\t\t\t//   public void Issue1552Pre(UserType a, UserType b)\n\t\t\t\t//   {\n\t\t\t\t//      UserType num = a + b;\n\t\t\t\t//      Console.WriteLine(++num);\n\t\t\t\t//   }\n\t\t\t\t// can end up being compiled to:\n\t\t\t\t//      Console.WriteLine(UserType.op_Increment(a + b));\n\t\t\t\tif (call.SlotInfo == StLoc.ValueSlot && call.Parent.SlotInfo == Block.InstructionSlot)\n\t\t\t\t{\n\t\t\t\t\tvar store = (StLoc)call.Parent;\n\t\t\t\t\tvar block = (Block)store.Parent;\n\t\t\t\t\tcontext.Step($\"Fix {call.Method.Name} call at 0x{call.StartILOffset:x4} using {store.Variable.Name}\", call);\n\t\t\t\t\t// stloc V(call op_Increment(...))\n\t\t\t\t\t// ->\n\t\t\t\t\t// stloc V(...)\n\t\t\t\t\t// compound.assign op_Increment(V)\n\t\t\t\t\tcall.ReplaceWith(call.Arguments[0]);\n\t\t\t\t\tblock.Instructions.Insert(store.ChildIndex + 1,\n\t\t\t\t\t\tnew UserDefinedCompoundAssign(call.Method, CompoundEvalMode.EvaluatesToNewValue,\n\t\t\t\t\t\tnew LdLoca(store.Variable), CompoundTargetKind.Address, new LdcI4(1)).WithILRange(call));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcontext.Step($\"Fix {call.Method.Name} call at 0x{call.StartILOffset:x4} using new local\", call);\n\t\t\t\t\tvar newVariable = call.Arguments[0].Extract(context);\n\t\t\t\t\tif (newVariable == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Fail(\"Failed to extract argument of remaining increment/decrement\");\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tnewVariable.Type = call.GetParameter(0).Type;\n\t\t\t\t\tDebug.Assert(call.Arguments[0].MatchLdLoc(newVariable));\n\t\t\t\t\tcall.ReplaceWith(new UserDefinedCompoundAssign(call.Method, CompoundEvalMode.EvaluatesToNewValue,\n\t\t\t\t\t\tnew LdLoca(newVariable), CompoundTargetKind.Address, new LdcI4(1)).WithILRange(call));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/HighLevelLoopTransform.cs",
    "content": "// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.IL.ControlFlow;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// If possible, transforms plain ILAst loops into while (condition), do-while and for-loops.\n\t/// For the invariants of the transforms <see cref=\"BlockContainer.CheckInvariant(ILPhase)\"/>.\n\t/// </summary>\n\tpublic class HighLevelLoopTransform : IILTransform\n\t{\n\t\tILTransformContext context;\n\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tthis.context = context;\n\n\t\t\tforeach (BlockContainer loop in function.Descendants.OfType<BlockContainer>())\n\t\t\t{\n\t\t\t\tif (loop.Kind != ContainerKind.Loop)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (MatchWhileLoop(loop, out var condition, out var loopBody))\n\t\t\t\t{\n\t\t\t\t\tif (context.Settings.ForStatement)\n\t\t\t\t\t\tMatchForLoop(loop, condition, loopBody);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (context.Settings.DoWhileStatement && MatchDoWhileLoop(loop))\n\t\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tbool MatchWhileLoop(BlockContainer loop, out IfInstruction condition, out Block loopBody)\n\t\t{\n\t\t\t// ConditionDetection favours leave inside if and branch at end of block\n\t\t\t// while-loop:\n\t\t\t// if (!loop-condition) leave loop-container\n\t\t\t// ...\n\t\t\tcondition = null;\n\t\t\tloopBody = loop.EntryPoint;\n\t\t\tif (!(loopBody.Instructions[0] is IfInstruction ifInstruction))\n\t\t\t\treturn false;\n\n\t\t\tif (!ifInstruction.FalseInst.MatchNop())\n\t\t\t\treturn false;\n\n\t\t\tif (UsesVariableCapturedInLoop(loop, ifInstruction.Condition))\n\t\t\t\treturn false;\n\n\t\t\tcondition = ifInstruction;\n\t\t\tif (!ifInstruction.TrueInst.MatchLeave(loop))\n\t\t\t{\n\t\t\t\t// sometimes the loop-body is nested within the if\n\t\t\t\t// if (loop-condition) { loop-body }\n\t\t\t\t// leave loop-container\n\n\t\t\t\tif (loopBody.Instructions.Count != 2 || !loop.EntryPoint.Instructions.Last().MatchLeave(loop))\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (!ifInstruction.TrueInst.HasFlag(InstructionFlags.EndPointUnreachable))\n\t\t\t\t\t((Block)ifInstruction.TrueInst).Instructions.Add(new Leave(loop));\n\n\t\t\t\tConditionDetection.InvertIf(loopBody, ifInstruction, context);\n\t\t\t}\n\n\t\t\tcontext.Step(\"Transform to while (condition) loop: \" + loop.EntryPoint.Label, loop);\n\t\t\tloop.Kind = ContainerKind.While;\n\t\t\t//invert comparison\n\t\t\tifInstruction.Condition = Comp.LogicNot(ifInstruction.Condition);\n\t\t\tifInstruction.FalseInst = ifInstruction.TrueInst;\n\t\t\t//move the rest of the body into a new block\n\t\t\tloopBody = new Block();\n\t\t\tloopBody.AddRef();\n\t\t\tConditionDetection.ExtractBlock(loop.EntryPoint, 1, loop.EntryPoint.Instructions.Count, loopBody);\n\t\t\tloop.Blocks.Insert(1, loopBody);\n\t\t\tloopBody.ReleaseRef();\n\t\t\tif (!loopBody.HasFlag(InstructionFlags.EndPointUnreachable))\n\t\t\t\tloopBody.Instructions.Add(new Leave(loop));\n\n\t\t\tifInstruction.TrueInst = new Branch(loopBody);\n\t\t\tExpressionTransforms.RunOnSingleStatement(ifInstruction, context);\n\n\t\t\t// Analyze conditions and decide whether to move some of them out of the condition block:\n\t\t\t/*var conditions = new List<ILInstruction>();\n\t\t\tSplitConditions(condition.Condition, conditions);\n\t\t\t// Break apart conditions that could be a MoveNext call followed by a Current accessor call:\n\t\t\tif (MightBeHeaderOfForEach(loop, conditions)) {\n\t\t\t\tifInstruction.Condition = conditions[0];\n\t\t\t\tforeach (var cond in conditions.Skip(1).Reverse()) {\n\t\t\t\t\tIfInstruction inst;\n\t\t\t\t\tloopBody.Instructions.Insert(0, inst = new IfInstruction(Comp.LogicNot(cond), new Leave(loop)));\n\t\t\t\t\tExpressionTransforms.RunOnSingleStatment(inst, context);\n\t\t\t\t}\n\t\t\t}*/\n\n\t\t\treturn true;\n\t\t}\n\n\t\tbool MightBeHeaderOfForEach(BlockContainer loop, List<ILInstruction> conditions)\n\t\t{\n\t\t\tif (conditions.Count <= 1)\n\t\t\t\treturn false;\n\t\t\tif (!(conditions[0] is CallInstruction moveNextCall && moveNextCall.Method.Name == \"MoveNext\"\n\t\t\t\t&& conditions[1].Descendants.Any(IsGetCurrentCall)))\n\t\t\t\treturn false;\n\t\t\treturn loop.Parent?.Parent?.Parent is UsingInstruction;\n\n\t\t\tbool IsGetCurrentCall(ILInstruction inst)\n\t\t\t{\n\t\t\t\treturn inst is CallInstruction getterCall\n\t\t\t\t\t&& getterCall.Method.IsAccessor\n\t\t\t\t\t&& getterCall.Method.Name == \"get_Current\";\n\t\t\t}\n\t\t}\n\n\t\tvoid SplitConditions(ILInstruction expression, List<ILInstruction> conditions)\n\t\t{\n\t\t\tif (expression.MatchLogicAnd(out var l, out var r))\n\t\t\t{\n\t\t\t\tSplitConditions(l, conditions);\n\t\t\t\tSplitConditions(r, conditions);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tconditions.Add(expression);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches a do-while loop and performs the following transformations:\n\t\t/// - combine all compatible conditions into one IfInstruction.\n\t\t/// - extract conditions into a condition block, or move the existing condition block to the end.\n\t\t/// </summary>\n\t\tbool MatchDoWhileLoop(BlockContainer loop)\n\t\t{\n\t\t\t(List<IfInstruction> conditions, ILInstruction exit, bool swap, bool split, bool unwrap) = AnalyzeDoWhileConditions(loop);\n\t\t\t// not a do-while loop, exit.\n\t\t\tif (conditions == null || conditions.Count == 0)\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"Transform to do-while loop: \" + loop.EntryPoint.Label, loop);\n\t\t\tBlock conditionBlock;\n\t\t\t// first we remove all extracted instructions from the original block.\n\t\t\tvar originalBlock = (Block)exit.Parent;\n\t\t\tif (unwrap)\n\t\t\t{\n\t\t\t\t// we found a condition block nested in a condition that is followed by a return statement:\n\t\t\t\t// we flip the condition and swap the blocks\n\t\t\t\tDebug.Assert(originalBlock.Parent is IfInstruction);\n\t\t\t\tvar returnCondition = (IfInstruction)originalBlock.Parent;\n\t\t\t\tvar topLevelBlock = (Block)returnCondition.Parent;\n\t\t\t\tDebug.Assert(topLevelBlock.Parent == loop);\n\t\t\t\tvar leaveFunction = topLevelBlock.Instructions[returnCondition.ChildIndex + 1];\n\t\t\t\tDebug.Assert(leaveFunction.MatchReturn(out _));\n\t\t\t\treturnCondition.Condition = Comp.LogicNot(returnCondition.Condition);\n\t\t\t\treturnCondition.TrueInst = leaveFunction;\n\t\t\t\t// simplify the condition:\n\t\t\t\tExpressionTransforms.RunOnSingleStatement(returnCondition, context);\n\t\t\t\ttopLevelBlock.Instructions.RemoveAt(returnCondition.ChildIndex + 1);\n\t\t\t\ttopLevelBlock.Instructions.AddRange(originalBlock.Instructions);\n\t\t\t\toriginalBlock = topLevelBlock;\n\t\t\t\tsplit = true;\n\t\t\t}\n\t\t\toriginalBlock.Instructions.RemoveRange(originalBlock.Instructions.Count - conditions.Count - 1, conditions.Count + 1);\n\t\t\t// we need to split the block:\n\t\t\tif (split)\n\t\t\t{\n\t\t\t\t// add a new block at the end and add a branch to the new block.\n\t\t\t\tconditionBlock = new Block();\n\t\t\t\tloop.Blocks.Add(conditionBlock);\n\t\t\t\toriginalBlock.Instructions.Add(new Branch(conditionBlock));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// move the condition block to the end.\n\t\t\t\tconditionBlock = originalBlock;\n\t\t\t\tloop.Blocks.MoveElementToEnd(originalBlock);\n\t\t\t}\n\t\t\t// combine all conditions and the exit instruction into one IfInstruction:\n\t\t\tIfInstruction condition = null;\n\t\t\tconditionBlock.AddILRange(exit);\n\t\t\tforeach (var inst in conditions)\n\t\t\t{\n\t\t\t\tconditionBlock.AddILRange(inst);\n\t\t\t\tif (condition == null)\n\t\t\t\t{\n\t\t\t\t\tcondition = inst;\n\t\t\t\t\tif (swap)\n\t\t\t\t\t{\n\t\t\t\t\t\t// branches must be swapped and condition negated:\n\t\t\t\t\t\tcondition.Condition = Comp.LogicNot(condition.Condition);\n\t\t\t\t\t\tcondition.FalseInst = condition.TrueInst;\n\t\t\t\t\t\tcondition.TrueInst = exit;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tcondition.FalseInst = exit;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (swap)\n\t\t\t\t\t{\n\t\t\t\t\t\tcondition.Condition = IfInstruction.LogicAnd(Comp.LogicNot(inst.Condition), condition.Condition);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tcondition.Condition = IfInstruction.LogicAnd(inst.Condition, condition.Condition);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// insert the combined conditions into the condition block:\n\t\t\tconditionBlock.Instructions.Add(condition);\n\t\t\t// simplify the condition:\n\t\t\tExpressionTransforms.RunOnSingleStatement(condition, context);\n\t\t\t// transform complete\n\t\t\tloop.Kind = ContainerKind.DoWhile;\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic (List<IfInstruction> conditions, ILInstruction exit, bool swap, bool split, bool unwrap) AnalyzeDoWhileConditions(BlockContainer loop)\n\t\t{\n\t\t\t// we iterate over all blocks from the bottom, because the entry-point\n\t\t\t// should only be considered as condition block, if there are no other blocks.\n\t\t\tforeach (var block in loop.Blocks.Reverse())\n\t\t\t{\n\t\t\t\t// first we match the end of the block:\n\t\t\t\tif (MatchDoWhileConditionBlock(loop, block, out bool swap, out bool unwrapCondtionBlock, out Block conditionBlock))\n\t\t\t\t{\n\t\t\t\t\t// now collect all instructions that are usable as loop conditions\n\t\t\t\t\tvar conditions = CollectConditions(loop, conditionBlock, swap);\n\t\t\t\t\t// split only if the block is either the entry-point or contains other instructions as well.\n\t\t\t\t\tvar split = conditionBlock == loop.EntryPoint || conditionBlock.Instructions.Count > conditions.Count + 1; // + 1 is the final leave/branch.\n\t\t\t\t\treturn (conditions, conditionBlock.Instructions.Last(), swap, split, unwrapCondtionBlock);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn (null, null, false, false, false);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns a list of all IfInstructions that can be used as loop conditon, i.e.,\n\t\t/// that have no false-instruction and have leave loop (if swapped) or branch entry-point as true-instruction.\n\t\t/// </summary>\n\t\tstatic List<IfInstruction> CollectConditions(BlockContainer loop, Block block, bool swap)\n\t\t{\n\t\t\tvar list = new List<IfInstruction>();\n\t\t\tint i = block.Instructions.Count - 2;\n\t\t\twhile (i >= 0 && block.Instructions[i] is IfInstruction ifInst)\n\t\t\t{\n\t\t\t\tif (!ifInst.FalseInst.MatchNop())\n\t\t\t\t\tbreak;\n\t\t\t\tif (UsesVariableCapturedInLoop(loop, ifInst.Condition))\n\t\t\t\t\tbreak;\n\t\t\t\tif (swap)\n\t\t\t\t{\n\t\t\t\t\tif (!ifInst.TrueInst.MatchLeave(loop))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tlist.Add(ifInst);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (!ifInst.TrueInst.MatchBranch(loop.EntryPoint))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tlist.Add(ifInst);\n\t\t\t\t}\n\t\t\t\ti--;\n\t\t\t}\n\n\t\t\treturn list;\n\t\t}\n\n\t\tstatic bool UsesVariableCapturedInLoop(BlockContainer loop, ILInstruction condition)\n\t\t{\n\t\t\tforeach (var inst in condition.Descendants.OfType<IInstructionWithVariableOperand>())\n\t\t\t{\n\t\t\t\tif (inst.Variable.CaptureScope == loop)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tstatic bool MatchDoWhileConditionBlock(BlockContainer loop, Block block, out bool swapBranches, out bool unwrapCondtionBlock, out Block conditionBlock)\n\t\t{\n\t\t\t// match the end of the block:\n\t\t\t// if (condition) branch entry-point else nop\n\t\t\t// leave loop\n\t\t\t// -or-\n\t\t\t// if (condition) leave loop else nop\n\t\t\t// branch entry-point\n\t\t\tswapBranches = false;\n\t\t\tunwrapCondtionBlock = false;\n\t\t\tconditionBlock = block;\n\t\t\t// empty block?\n\t\t\tif (block.Instructions.Count < 2)\n\t\t\t\treturn false;\n\t\t\tvar last = block.Instructions.Last();\n\t\t\tvar ifInstruction = block.Instructions.SecondToLastOrDefault() as IfInstruction;\n\t\t\t// no IfInstruction or already transformed?\n\t\t\tif (ifInstruction == null || !ifInstruction.FalseInst.MatchNop())\n\t\t\t\treturn false;\n\t\t\t// the block ends in a return statement preceeded by an IfInstruction\n\t\t\t// take a look at the nested block and check if that might be a condition block\n\t\t\tif (last.MatchReturn(out _) && ifInstruction.TrueInst is Block nestedConditionBlock)\n\t\t\t{\n\t\t\t\tif (nestedConditionBlock.Instructions.Count < 2)\n\t\t\t\t\treturn false;\n\t\t\t\tlast = nestedConditionBlock.Instructions.Last();\n\t\t\t\tifInstruction = nestedConditionBlock.Instructions.SecondToLastOrDefault() as IfInstruction;\n\t\t\t\tif (ifInstruction == null || !ifInstruction.FalseInst.MatchNop())\n\t\t\t\t\treturn false;\n\t\t\t\tunwrapCondtionBlock = true;\n\t\t\t\tconditionBlock = nestedConditionBlock;\n\t\t\t}\n\t\t\t// if the last instruction is a branch\n\t\t\t// we assume the branch instructions need to be swapped.\n\t\t\tif (last.MatchBranch(loop.EntryPoint))\n\t\t\t\tswapBranches = true;\n\t\t\telse if (last.MatchLeave(loop))\n\t\t\t\tswapBranches = false;\n\t\t\telse\n\t\t\t\treturn false;\n\t\t\t// match the IfInstruction\n\t\t\tif (swapBranches)\n\t\t\t{\n\t\t\t\tif (!ifInstruction.TrueInst.MatchLeave(loop))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (!ifInstruction.TrueInst.MatchBranch(loop.EntryPoint))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t// early match before block containers have been constructed\n\t\tinternal static bool MatchDoWhileConditionBlock(Block block, out Block target1, out Block target2)\n\t\t{\n\t\t\ttarget1 = target2 = null;\n\t\t\tif (block.Instructions.Count < 2)\n\t\t\t\treturn false;\n\n\t\t\tvar last = block.Instructions.Last();\n\t\t\tif (!(block.Instructions.SecondToLastOrDefault() is IfInstruction ifInstruction) || !ifInstruction.FalseInst.MatchNop())\n\t\t\t\treturn false;\n\n\t\t\treturn (ifInstruction.TrueInst.MatchBranch(out target1) || ifInstruction.TrueInst.MatchReturn(out var _)) &&\n\t\t\t\t   (last.MatchBranch(out target2) || last.MatchReturn(out var _));\n\t\t}\n\n\t\tinternal static Block GetIncrementBlock(BlockContainer loop, Block whileLoopBody) =>\n\t\t\tloop.Blocks.SingleOrDefault(b => b != whileLoopBody\n\t\t\t\t\t\t\t\t\t\t  && b.Instructions.Last().MatchBranch(loop.EntryPoint)\n\t\t\t\t\t\t\t\t\t\t  && b.Instructions.SkipLast(1).All(IsSimpleStatement));\n\n\t\tinternal static bool MatchIncrementBlock(Block block, out Block loopHead) =>\n\t\t\tblock.Instructions.Last().MatchBranch(out loopHead)\n\t\t\t&& block.Instructions.SkipLast(1).All(IsSimpleStatement);\n\n\t\tbool MatchForLoop(BlockContainer loop, IfInstruction whileCondition, Block whileLoopBody)\n\t\t{\n\t\t\t// for loops have exactly two incoming edges at the entry point.\n\t\t\tif (loop.EntryPoint.IncomingEdgeCount != 2)\n\t\t\t\treturn false;\n\t\t\t// try to find an increment block:\n\t\t\t// consists of simple statements only.\n\t\t\tvar incrementBlock = GetIncrementBlock(loop, whileLoopBody);\n\t\t\tif (incrementBlock != null)\n\t\t\t{\n\t\t\t\t// we found a possible increment block, just make sure, that there are at least three blocks:\n\t\t\t\t// - condition block\n\t\t\t\t// - loop body\n\t\t\t\t// - increment block\n\t\t\t\tif (incrementBlock.Instructions.Count <= 1 || loop.Blocks.Count < 3)\n\t\t\t\t\treturn false;\n\t\t\t\tcontext.Step(\"Transform to for loop: \" + loop.EntryPoint.Label, loop);\n\t\t\t\t// move the block to the end of the loop:\n\t\t\t\tloop.Blocks.MoveElementToEnd(incrementBlock);\n\t\t\t\tloop.Kind = ContainerKind.For;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// we need to move the increment statements into its own block:\n\t\t\t\t// last must be a branch entry-point\n\t\t\t\tvar last = whileLoopBody.Instructions.LastOrDefault();\n\t\t\t\tvar secondToLast = whileLoopBody.Instructions.SecondToLastOrDefault();\n\t\t\t\tif (last == null || secondToLast == null)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!last.MatchBranch(loop.EntryPoint))\n\t\t\t\t\treturn false;\n\t\t\t\t// we only deal with 'numeric' increments\n\t\t\t\tif (!MatchIncrement(secondToLast, out var incrementVariable))\n\t\t\t\t\treturn false;\n\t\t\t\t// the increment variable must be local/stack variable\n\t\t\t\tif (incrementVariable.Kind == VariableKind.Parameter)\n\t\t\t\t\treturn false;\n\t\t\t\t// split conditions:\n\t\t\t\tvar conditions = new List<ILInstruction>();\n\t\t\t\tSplitConditions(whileCondition.Condition, conditions);\n\t\t\t\tIfInstruction forCondition = null;\n\t\t\t\tint numberOfConditions = 0;\n\t\t\t\tforeach (var condition in conditions)\n\t\t\t\t{\n\t\t\t\t\t// the increment variable must be used in the condition\n\t\t\t\t\tif (!condition.Descendants.Any(inst => inst.MatchLdLoc(incrementVariable)))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t// condition should not contain an assignment\n\t\t\t\t\tif (condition.Descendants.Any(IsAssignment))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tif (forCondition == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tforCondition = new IfInstruction(condition, whileCondition.TrueInst, whileCondition.FalseInst);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tforCondition.Condition = IfInstruction.LogicAnd(forCondition.Condition, condition);\n\t\t\t\t\t}\n\t\t\t\t\tnumberOfConditions++;\n\t\t\t\t}\n\t\t\t\tif (numberOfConditions == 0)\n\t\t\t\t\treturn false;\n\t\t\t\tcontext.Step(\"Transform to for loop: \" + loop.EntryPoint.Label, loop);\n\t\t\t\t// split condition block:\n\t\t\t\twhileCondition.ReplaceWith(forCondition);\n\t\t\t\tExpressionTransforms.RunOnSingleStatement(forCondition, context);\n\t\t\t\tfor (int i = conditions.Count - 1; i >= numberOfConditions; i--)\n\t\t\t\t{\n\t\t\t\t\tIfInstruction inst;\n\t\t\t\t\twhileLoopBody.Instructions.Insert(0, inst = new IfInstruction(Comp.LogicNot(conditions[i]), new Leave(loop)));\n\t\t\t\t\tExpressionTransforms.RunOnSingleStatement(inst, context);\n\t\t\t\t}\n\t\t\t\t// create a new increment block and add it at the end:\n\t\t\t\tint secondToLastIndex = secondToLast.ChildIndex;\n\t\t\t\tvar newIncremenBlock = new Block();\n\t\t\t\tloop.Blocks.Add(newIncremenBlock);\n\t\t\t\t// move the increment instruction:\n\t\t\t\tnewIncremenBlock.Instructions.Add(secondToLast);\n\t\t\t\tnewIncremenBlock.Instructions.Add(last);\n\t\t\t\tnewIncremenBlock.AddILRange(secondToLast);\n\t\t\t\twhileLoopBody.Instructions.RemoveRange(secondToLastIndex, 2);\n\t\t\t\twhileLoopBody.Instructions.Add(new Branch(newIncremenBlock));\n\t\t\t\t// complete transform.\n\t\t\t\tloop.Kind = ContainerKind.For;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tbool IsAssignment(ILInstruction inst)\n\t\t{\n\t\t\tif (inst is StLoc)\n\t\t\t\treturn true;\n\t\t\tif (inst is CompoundAssignmentInstruction)\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns true if the instruction is stloc v(add(ldloc v, arg))\n\t\t/// or compound.assign(ldloca v, arg)\n\t\t/// </summary>\n\t\tpublic static bool MatchIncrement(ILInstruction inst, out ILVariable variable)\n\t\t{\n\t\t\tif (inst.MatchStLoc(out variable, out var value))\n\t\t\t{\n\t\t\t\tif (value.MatchBinaryNumericInstruction(BinaryNumericOperator.Add, out var left, out var right))\n\t\t\t\t{\n\t\t\t\t\treturn left.MatchLdLoc(variable);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (inst is CompoundAssignmentInstruction cai)\n\t\t\t{\n\t\t\t\treturn cai.TargetKind == CompoundTargetKind.Address && cai.Target.MatchLdLoca(out variable);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the statement is 'simple' (usable as for loop iterator):\n\t\t/// Currently we only accept calls and assignments.\n\t\t/// </summary>\n\t\tstatic bool IsSimpleStatement(ILInstruction inst)\n\t\t{\n\t\t\tswitch (inst.OpCode)\n\t\t\t{\n\t\t\t\tcase OpCode.Call:\n\t\t\t\tcase OpCode.CallVirt:\n\t\t\t\tcase OpCode.NewObj:\n\t\t\t\tcase OpCode.StLoc:\n\t\t\t\tcase OpCode.StObj:\n\t\t\t\tcase OpCode.NumericCompoundAssign:\n\t\t\t\tcase OpCode.UserDefinedCompoundAssign:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/IILTransform.cs",
    "content": "// Copyright (c) 2015 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Diagnostics;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.CSharp.Resolver;\nusing ICSharpCode.Decompiler.CSharp.TypeSystem;\nusing ICSharpCode.Decompiler.DebugInfo;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Per-function IL transform.\n\t/// </summary>\n\tpublic interface IILTransform\n\t{\n\t\tvoid Run(ILFunction function, ILTransformContext context);\n\t}\n\n\t/// <summary>\n\t/// Parameter class holding various arguments for <see cref=\"IILTransform.Run(ILFunction, ILTransformContext)\"/>.\n\t/// </summary>\n\tpublic class ILTransformContext\n\t{\n\t\tpublic ILFunction Function { get; }\n\t\tpublic IDecompilerTypeSystem TypeSystem { get; }\n\t\tpublic IDebugInfoProvider? DebugInfo { get; }\n\t\tpublic DecompilerSettings Settings { get; }\n\t\tpublic CancellationToken CancellationToken { get; set; }\n\t\tpublic Stepper Stepper { get; set; }\n\t\tpublic Metadata.MetadataFile PEFile => TypeSystem.MainModule.MetadataFile;\n\n\t\tinternal DecompileRun? DecompileRun { get; set; }\n\t\tinternal UsingScope? UsingScope => DecompileRun?.UsingScope;\n\n\t\tCSharpResolver? csharpResolver;\n\n\t\tinternal CSharpResolver CSharpResolver {\n\t\t\tget {\n\t\t\t\tvar resolver = LazyInit.VolatileRead(ref csharpResolver);\n\t\t\t\tif (resolver != null)\n\t\t\t\t\treturn resolver;\n\t\t\t\treturn LazyInit.GetOrSet(ref csharpResolver, new CSharpResolver(new CSharpTypeResolveContext(TypeSystem.MainModule, UsingScope)));\n\t\t\t}\n\t\t}\n\n\t\tpublic ILTransformContext(ILFunction function, IDecompilerTypeSystem typeSystem, IDebugInfoProvider? debugInfo, DecompilerSettings? settings = null)\n\t\t{\n\t\t\tthis.Function = function ?? throw new ArgumentNullException(nameof(function));\n\t\t\tthis.TypeSystem = typeSystem ?? throw new ArgumentNullException(nameof(typeSystem));\n\t\t\tthis.Settings = settings ?? new DecompilerSettings();\n\t\t\tthis.DebugInfo = debugInfo;\n\t\t\tStepper = new Stepper();\n\t\t}\n\n\t\tpublic ILTransformContext(ILTransformContext context, ILFunction? function = null)\n\t\t{\n\t\t\tthis.Function = function ?? context.Function;\n\t\t\tthis.TypeSystem = context.TypeSystem;\n\t\t\tthis.DebugInfo = context.DebugInfo;\n\t\t\tthis.Settings = context.Settings;\n\t\t\tthis.DecompileRun = context.DecompileRun;\n\t\t\tthis.CancellationToken = context.CancellationToken;\n\t\t\tthis.Stepper = context.Stepper;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a new ILReader instance for decompiling another method in the same assembly.\n\t\t/// </summary>\n\t\tinternal ILReader CreateILReader()\n\t\t{\n\t\t\treturn new ILReader(TypeSystem.MainModule) {\n\t\t\t\tUseDebugSymbols = Settings.UseDebugSymbols,\n\t\t\t\tUseRefLocalsForAccurateOrderOfEvaluation = Settings.UseRefLocalsForAccurateOrderOfEvaluation,\n\t\t\t\tDebugInfo = DebugInfo\n\t\t\t};\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Call this method immediately before performing a transform step.\n\t\t/// Unlike <c>context.Stepper.Step()</c>, calls to this method are only compiled in debug builds.\n\t\t/// </summary>\n\t\t[Conditional(\"STEP\")]\n\t\t[DebuggerStepThrough]\n\t\tinternal void Step(string description, ILInstruction? near)\n\t\t{\n\t\t\tStepper.Step(description, near);\n\t\t}\n\n\t\t[Conditional(\"STEP\")]\n\t\t[DebuggerStepThrough]\n\t\tinternal void StepStartGroup(string description, ILInstruction? near = null)\n\t\t{\n\t\t\tStepper.StartGroup(description, near);\n\t\t}\n\n\t\t[Conditional(\"STEP\")]\n\t\tinternal void StepEndGroup(bool keepIfEmpty = false)\n\t\t{\n\t\t\tStepper.EndGroup(keepIfEmpty);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/ILExtraction.cs",
    "content": "// Copyright (c) 2019 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Context object for the ILInstruction.Extract() operation.\n\t/// </summary>\n\tclass ExtractionContext\n\t{\n\t\t/// <summary>\n\t\t/// Nearest function, used for registering the new locals that are created by extraction.\n\t\t/// </summary>\n\t\treadonly ILFunction Function;\n\n\t\treadonly ILTransformContext context;\n\n\t\t/// <summary>\n\t\t/// Combined flags of all instructions being moved.\n\t\t/// </summary>\n\t\tinternal InstructionFlags FlagsBeingMoved;\n\n\t\t/// <summary>\n\t\t/// List of actions to be executed when performing the extraction.\n\t\t/// \n\t\t/// Each function in this list has the side-effect of replacing the instruction-to-be-moved\n\t\t/// with a load of a fresh temporary variable; and returns the the store to the temporary variable,\n\t\t/// which will be inserted at block-level.\n\t\t/// </summary>\n\t\treadonly List<Func<ILInstruction>> MoveActions = new List<Func<ILInstruction>>();\n\n\t\tExtractionContext(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tDebug.Assert(function != null);\n\t\t\tthis.Function = function;\n\t\t\tthis.context = context;\n\t\t}\n\n\t\tinternal void RegisterMove(ILInstruction predecessor)\n\t\t{\n\t\t\tFlagsBeingMoved |= predecessor.Flags;\n\t\t\tMoveActions.Add(delegate {\n\t\t\t\tvar type = context.TypeSystem.FindType(predecessor.ResultType);\n\t\t\t\tvar v = Function.RegisterVariable(VariableKind.StackSlot, type);\n\t\t\t\tpredecessor.ReplaceWith(new LdLoc(v));\n\t\t\t\treturn new StLoc(v, predecessor);\n\t\t\t});\n\t\t}\n\n\t\tinternal void RegisterMoveIfNecessary(ILInstruction predecessor)\n\t\t{\n\t\t\tif (!CanReorderWithInstructionsBeingMoved(predecessor))\n\t\t\t{\n\t\t\t\tRegisterMove(predecessor);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Currently, <c>predecessor</c> is evaluated before the instructions being moved.\n\t\t/// If this function returns true, <c>predecessor</c> can stay as-is, despite the move changing the evaluation order.\n\t\t/// If this function returns false, <c>predecessor</c> will need to also move, to ensure the evaluation order stays unchanged.\n\t\t/// </summary>\n\t\tpublic bool CanReorderWithInstructionsBeingMoved(ILInstruction predecessor)\n\t\t{\n\t\t\t// We could track the instructions being moved and be smarter about unnecessary moves,\n\t\t\t// but given the limited scenarios where extraction is used so far,\n\t\t\t// this seems unnecessary.\n\t\t\treturn predecessor.Flags == InstructionFlags.None;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Extracts the specified instruction:\n\t\t///   The instruction is replaced with a load of a new temporary variable;\n\t\t///   and the instruction is moved to a store to said variable at block-level.\n\t\t/// \n\t\t/// May return null if extraction is not possible.\n\t\t/// </summary>\n\t\tpublic static ILVariable? Extract(ILInstruction instToExtract, ILTransformContext context)\n\t\t{\n\t\t\tvar function = instToExtract.Ancestors.OfType<ILFunction>().First();\n\t\t\tExtractionContext ctx = new ExtractionContext(function, context);\n\t\t\tctx.FlagsBeingMoved = instToExtract.Flags;\n\t\t\tILInstruction? inst = instToExtract;\n\t\t\twhile (inst != null)\n\t\t\t{\n\t\t\t\tif (inst.Parent is IfInstruction ifInst && inst.SlotInfo != IfInstruction.ConditionSlot)\n\t\t\t\t{\n\t\t\t\t\t// this context doesn't support extraction, but maybe we can create a block here?\n\t\t\t\t\tif (ifInst.ResultType == StackType.Void)\n\t\t\t\t\t{\n\t\t\t\t\t\tBlock newBlock = new Block();\n\t\t\t\t\t\tinst.ReplaceWith(newBlock);\n\t\t\t\t\t\tnewBlock.Instructions.Add(inst);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (inst.Parent is Block { Kind: BlockKind.ControlFlow } block)\n\t\t\t\t{\n\t\t\t\t\t// We've reached a target block, and extraction is possible all the way.\n\t\t\t\t\t// Check if the parent BlockContainer allows extraction:\n\t\t\t\t\tif (block.Parent is BlockContainer container)\n\t\t\t\t\t{\n\t\t\t\t\t\tswitch (container.Kind)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase ContainerKind.Normal:\n\t\t\t\t\t\t\tcase ContainerKind.Loop:\n\t\t\t\t\t\t\t\t// extraction is always possible\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase ContainerKind.Switch:\n\t\t\t\t\t\t\t\t// extraction is possible, unless in the entry-point (i.e., the switch head)\n\t\t\t\t\t\t\t\tif (block == container.EntryPoint && inst.ChildIndex == 0)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t// try to extract to the container's parent block, if it's a valid location\n\t\t\t\t\t\t\t\t\tinst = container;\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase ContainerKind.While:\n\t\t\t\t\t\t\t\t// extraction is possible, unless in the entry-point (i.e., the condition block)\n\t\t\t\t\t\t\t\tif (block == container.EntryPoint)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase ContainerKind.DoWhile:\n\t\t\t\t\t\t\t\t// extraction is possible, unless in the last block (i.e., the condition block)\n\t\t\t\t\t\t\t\tif (block == container.Blocks.Last())\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase ContainerKind.For:\n\t\t\t\t\t\t\t\t// extraction is possible, unless in the first or last block\n\t\t\t\t\t\t\t\t// (i.e., the condition block or increment block)\n\t\t\t\t\t\t\t\tif (block == container.EntryPoint\n\t\t\t\t\t\t\t\t\t|| block == container.Blocks.Last())\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tint insertIndex = inst.ChildIndex;\n\t\t\t\t\tvar type = context.TypeSystem.FindType(instToExtract.ResultType);\n\t\t\t\t\t// Move instToExtract itself:\n\t\t\t\t\tvar v = function.RegisterVariable(VariableKind.StackSlot, type);\n\t\t\t\t\tinstToExtract.ReplaceWith(new LdLoc(v));\n\t\t\t\t\tblock.Instructions.Insert(insertIndex, new StLoc(v, instToExtract));\n\t\t\t\t\t// Apply the other move actions:\n\t\t\t\t\tforeach (var moveAction in ctx.MoveActions)\n\t\t\t\t\t{\n\t\t\t\t\t\tblock.Instructions.Insert(insertIndex, moveAction());\n\t\t\t\t\t}\n\t\t\t\t\treturn v;\n\t\t\t\t}\n\t\t\t\tif (inst.Parent != null && !inst.Parent.PrepareExtract(inst.ChildIndex, ctx))\n\t\t\t\t\treturn null;\n\t\t\t\tinst = inst.Parent;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs",
    "content": "// Copyright (c) 2011-2017 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t[Flags]\n\tpublic enum InliningOptions\n\t{\n\t\tNone = 0,\n\t\tAggressive = 1,\n\t\tIntroduceNamedArguments = 2,\n\t\tFindDeconstruction = 4,\n\t\tAllowChangingOrderOfEvaluationForExceptions = 8,\n\t\tAllowInliningOfLdloca = 0x10\n\t}\n\n\t/// <summary>\n\t/// Performs inlining transformations.\n\t/// </summary>\n\tpublic class ILInlining : IILTransform, IBlockTransform, IStatementTransform\n\t{\n\t\tinternal InliningOptions options;\n\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tforeach (var block in function.Descendants.OfType<Block>())\n\t\t\t{\n\t\t\t\tInlineAllInBlock(function, block, this.options, context);\n\t\t\t}\n\t\t\tfunction.Variables.RemoveDead();\n\t\t}\n\n\t\tpublic void Run(Block block, BlockTransformContext context)\n\t\t{\n\t\t\tInlineAllInBlock(context.Function, block, this.options, context);\n\t\t}\n\n\t\tpublic void Run(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\tvar options = this.options | OptionsForBlock(block, pos, context);\n\t\t\twhile (InlineOneIfPossible(block, pos, options, context: context))\n\t\t\t{\n\t\t\t\t// repeat inlining until nothing changes.\n\t\t\t}\n\t\t}\n\n\t\tinternal static InliningOptions OptionsForBlock(Block block, int pos, ILTransformContext context)\n\t\t{\n\t\t\tInliningOptions options = InliningOptions.None;\n\t\t\tif (context.Settings.AggressiveInlining || IsCatchWhenBlock(block))\n\t\t\t{\n\t\t\t\toptions |= InliningOptions.Aggressive;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar function = block.Ancestors.OfType<ILFunction>().FirstOrDefault();\n\t\t\t\tvar inst = block.Instructions[pos];\n\t\t\t\tif (IsInConstructorInitializer(function, inst) || PreferExpressionsOverStatements(function))\n\t\t\t\t\toptions |= InliningOptions.Aggressive;\n\t\t\t}\n\t\t\tif (!context.Settings.UseRefLocalsForAccurateOrderOfEvaluation)\n\t\t\t{\n\t\t\t\toptions |= InliningOptions.AllowChangingOrderOfEvaluationForExceptions;\n\t\t\t}\n\t\t\treturn options;\n\t\t}\n\n\t\tstatic bool PreferExpressionsOverStatements(ILFunction function)\n\t\t{\n\t\t\tswitch (function.Kind)\n\t\t\t{\n\t\t\t\tcase ILFunctionKind.Delegate:\n\t\t\t\t\treturn function.Parameters.Any(p => CSharp.CSharpDecompiler.IsTransparentIdentifier(p.Name));\n\t\t\t\tcase ILFunctionKind.ExpressionTree:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic static bool InlineAllInBlock(ILFunction function, Block block, InliningOptions options, ILTransformContext context)\n\t\t{\n\t\t\tbool modified = false;\n\t\t\tvar instructions = block.Instructions;\n\t\t\tfor (int i = instructions.Count - 1; i >= 0; i--)\n\t\t\t{\n\t\t\t\tif (instructions[i] is StLoc inst)\n\t\t\t\t{\n\t\t\t\t\tif (InlineOneIfPossible(block, i, options, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tmodified = true;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn modified;\n\t\t}\n\n\t\tinternal static bool IsInConstructorInitializer(ILFunction function, ILInstruction inst)\n\t\t{\n\t\t\tint ctorCallStart = function.ChainedConstructorCallILOffset;\n\t\t\tif (inst.EndILOffset > ctorCallStart)\n\t\t\t\treturn false;\n\t\t\tvar topLevelInst = inst.Ancestors.LastOrDefault(instr => instr.Parent is Block);\n\t\t\tif (topLevelInst == null)\n\t\t\t\treturn false;\n\t\t\treturn topLevelInst.EndILOffset <= ctorCallStart;\n\t\t}\n\n\t\tinternal static bool IsCatchWhenBlock(Block block)\n\t\t{\n\t\t\tvar container = BlockContainer.FindClosestContainer(block);\n\t\t\treturn container?.Parent is TryCatchHandler handler\n\t\t\t\t&& handler.Filter == container;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Inlines instructions before pos into block.Instructions[pos].\n\t\t/// </summary>\n\t\t/// <returns>The number of instructions that were inlined.</returns>\n\t\tpublic static int InlineInto(Block block, int pos, InliningOptions options, ILTransformContext context)\n\t\t{\n\t\t\tif (pos >= block.Instructions.Count)\n\t\t\t\treturn 0;\n\t\t\tint count = 0;\n\t\t\twhile (--pos >= 0)\n\t\t\t{\n\t\t\t\tif (InlineOneIfPossible(block, pos, options, context))\n\t\t\t\t\tcount++;\n\t\t\t\telse\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn count;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Aggressively inlines the stloc instruction at block.Body[pos] into the next instruction, if possible.\n\t\t/// </summary>\n\t\tpublic static bool InlineIfPossible(Block block, int pos, ILTransformContext context)\n\t\t{\n\t\t\treturn InlineOneIfPossible(block, pos, InliningOptions.Aggressive, context);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Inlines the stloc instruction at block.Instructions[pos] into the next instruction, if possible.\n\t\t/// </summary>\n\t\tpublic static bool InlineOneIfPossible(Block block, int pos, InliningOptions options, ILTransformContext context)\n\t\t{\n\t\t\tcontext.CancellationToken.ThrowIfCancellationRequested();\n\t\t\tif (block.Instructions[pos] is not StLoc stloc)\n\t\t\t\treturn false;\n\t\t\tif (!VariableCanBeUsedForInlining(stloc.Variable))\n\t\t\t\treturn false;\n\t\t\t// TODO: inlining of small integer types might be semantically incorrect,\n\t\t\t// but we can't avoid it this easily without breaking lots of tests.\n\t\t\t//if (v.Type.IsSmallIntegerType())\n\t\t\t//\treturn false; // stloc might perform implicit truncation\n\t\t\treturn InlineOne(stloc, options, context);\n\t\t}\n\n\t\tpublic static bool VariableCanBeUsedForInlining(ILVariable v)\n\t\t{\n\t\t\tif (v.Kind == VariableKind.PinnedLocal)\n\t\t\t\treturn false;\n\t\t\t// ensure the variable is accessed only a single time\n\t\t\tif (v.StoreCount != 1)\n\t\t\t\treturn false;\n\t\t\tif (v.LoadCount + v.AddressCount != 1)\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Inlines the stloc instruction at block.Instructions[pos] into the next instruction.\n\t\t/// \n\t\t/// Note that this method does not check whether 'v' has only one use;\n\t\t/// the caller is expected to validate whether inlining 'v' has any effects on other uses of 'v'.\n\t\t/// </summary>\n\t\tpublic static bool InlineOne(StLoc stloc, InliningOptions options, ILTransformContext context)\n\t\t{\n\t\t\tILVariable v = stloc.Variable;\n\t\t\tBlock block = (Block)stloc.Parent;\n\t\t\tint pos = stloc.ChildIndex;\n\t\t\tif (DoInline(v, stloc.Value, block.Instructions.ElementAtOrDefault(pos + 1), options, context))\n\t\t\t{\n\t\t\t\t// Assign the ranges of the stloc instruction:\n\t\t\t\tstloc.Value.AddILRange(stloc);\n\t\t\t\t// Remove the stloc instruction:\n\t\t\t\tDebug.Assert(block.Instructions[pos] == stloc);\n\t\t\t\tblock.Instructions.RemoveAt(pos);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (v.LoadCount == 0 && v.AddressCount == 0)\n\t\t\t{\n\t\t\t\t// The variable is never loaded\n\t\t\t\tif (SemanticHelper.IsPure(stloc.Value.Flags))\n\t\t\t\t{\n\t\t\t\t\t// Remove completely if the instruction has no effects\n\t\t\t\t\t// (except for reading locals)\n\t\t\t\t\tcontext.Step(\"Remove dead store without side effects\", stloc);\n\t\t\t\t\tblock.Instructions.RemoveAt(pos);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse if (v.Kind == VariableKind.StackSlot)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"Remove dead store, but keep expression\", stloc);\n\t\t\t\t\t// Assign the ranges of the stloc instruction:\n\t\t\t\t\tstloc.Value.AddILRange(stloc);\n\t\t\t\t\t// Remove the stloc, but keep the inner expression\n\t\t\t\t\tstloc.ReplaceWith(stloc.Value);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Inlines 'expr' into 'next', if possible.\n\t\t/// \n\t\t/// Note that this method does not check whether 'v' has only one use;\n\t\t/// the caller is expected to validate whether inlining 'v' has any effects on other uses of 'v'.\n\t\t/// </summary>\n\t\tstatic bool DoInline(ILVariable v, ILInstruction inlinedExpression, ILInstruction next, InliningOptions options, ILTransformContext context)\n\t\t{\n\t\t\tvar r = FindLoadInNext(next, v, inlinedExpression, options);\n\t\t\tif (r.Type == FindResultType.Found || r.Type == FindResultType.NamedArgument)\n\t\t\t{\n\t\t\t\tvar loadInst = r.LoadInst;\n\t\t\t\tif (loadInst.OpCode == OpCode.LdLoca)\n\t\t\t\t{\n\t\t\t\t\tif (!IsGeneratedTemporaryForAddressOf((LdLoca)loadInst, v, inlinedExpression, options))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(loadInst.OpCode == OpCode.LdLoc);\n\t\t\t\t\tbool aggressive = (options & InliningOptions.Aggressive) != 0;\n\t\t\t\t\tif (!aggressive && v.Kind != VariableKind.StackSlot\n\t\t\t\t\t\t&& !NonAggressiveInlineInto(next, r, inlinedExpression, v))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (r.Type == FindResultType.NamedArgument)\n\t\t\t\t{\n\t\t\t\t\tNamedArgumentTransform.IntroduceNamedArgument(r.CallArgument, context);\n\t\t\t\t\t// Now that the argument is evaluated early, we can inline as usual\n\t\t\t\t}\n\n\t\t\t\tcontext.Step($\"Inline variable '{v.Name}'\", inlinedExpression);\n\t\t\t\t// Assign the ranges of the ldloc instruction:\n\t\t\t\tinlinedExpression.AddILRange(loadInst);\n\n\t\t\t\tif (loadInst.OpCode == OpCode.LdLoca)\n\t\t\t\t{\n\t\t\t\t\t// it was an ldloca instruction, so we need to use the pseudo-opcode 'addressof'\n\t\t\t\t\t// to preserve the semantics of the compiler-generated temporary\n\t\t\t\t\tDebug.Assert(((LdLoca)loadInst).Variable == v);\n\t\t\t\t\tloadInst.ReplaceWith(new AddressOf(inlinedExpression, v.Type));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tloadInst.ReplaceWith(inlinedExpression);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Is this a temporary variable generated by the C# compiler for instance method calls on value type values\n\t\t/// </summary>\n\t\t/// <param name=\"loadInst\">The load instruction (a descendant within 'next')</param>\n\t\t/// <param name=\"v\">The variable being inlined.</param>\n\t\tstatic bool IsGeneratedTemporaryForAddressOf(LdLoca loadInst, ILVariable v, ILInstruction inlinedExpression, InliningOptions options)\n\t\t{\n\t\t\tDebug.Assert(loadInst.Variable == v);\n\t\t\tif (!options.HasFlag(InliningOptions.AllowInliningOfLdloca))\n\t\t\t{\n\t\t\t\treturn false; // inlining of ldloca is not allowed in the early inlining stage\n\t\t\t}\n\t\t\t// Inlining a value type variable is allowed only if the resulting code will maintain the semantics\n\t\t\t// that the method is operating on a copy.\n\t\t\t// Thus, we have to ensure we're operating on an r-value.\n\t\t\t// Additionally, we cannot inline in cases where the C# compiler prohibits the direct use\n\t\t\t// of the rvalue (e.g. M(ref (MyStruct)obj); is invalid).\n\t\t\tif (IsUsedAsThisPointerInCall(loadInst, out var method, out var constrainedTo))\n\t\t\t{\n\t\t\t\tif (options.HasFlag(InliningOptions.Aggressive))\n\t\t\t\t{\n\t\t\t\t\t// Inlining might be required in ctor initializers (see #2714).\n\t\t\t\t\t// expressionBuilder.VisitAddressOf will handle creating the copy for us.\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tswitch (ClassifyExpression(inlinedExpression))\n\t\t\t\t{\n\t\t\t\t\tcase ExpressionClassification.RValue:\n\t\t\t\t\t\t// For struct method calls on rvalues, the C# compiler always generates temporaries.\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tcase ExpressionClassification.MutableLValue:\n\t\t\t\t\t\t// For struct method calls on mutable lvalues, the C# compiler never generates temporaries.\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcase ExpressionClassification.ReadonlyLValue:\n\t\t\t\t\t\t// For struct method calls on readonly lvalues, the C# compiler\n\t\t\t\t\t\t// only generates a temporary if it isn't a \"readonly struct\"\n\t\t\t\t\t\treturn MethodRequiresCopyForReadonlyLValue(method, constrainedTo);\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new InvalidOperationException(\"invalid expression classification\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (loadInst.Parent is LdElemaInlineArray)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (IsPassedToReadOnlySpanCtor(loadInst))\n\t\t\t{\n\t\t\t\t// Always inlining is possible here, because it's an 'in' or 'ref readonly' parameter\n\t\t\t\t// and the C# compiler allows calling it with an rvalue, even though that might produce\n\t\t\t\t// a warning. Note that we don't need to check the expression classification, because\n\t\t\t\t// expressionBuilder.VisitAddressOf will handle creating the copy for us.\n\t\t\t\t// This is necessary, because there are compiler-generated uses of this ctor when\n\t\t\t\t// passing a single-element array to a params ROS<T> parameter and our following transforms\n\t\t\t\t// assume the value is already inlined.\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (IsPassedToInlineArrayAsSpan(loadInst))\n\t\t\t{\n\t\t\t\t// Inlining is not allowed:\n\t\t\t\t// <PrivateImplementationDetails>.InlineArrayAsReadOnlySpan(GetInlineArray()) is invalid C# code\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (IsPassedToInParameter(loadInst))\n\t\t\t{\n\t\t\t\tif (options.HasFlag(InliningOptions.Aggressive))\n\t\t\t\t{\n\t\t\t\t\t// Inlining might be required in ctor initializers (see #2714).\n\t\t\t\t\t// expressionBuilder.VisitAddressOf will handle creating the copy for us.\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tswitch (ClassifyExpression(inlinedExpression))\n\t\t\t\t{\n\t\t\t\t\tcase ExpressionClassification.RValue:\n\t\t\t\t\t\t// For rvalues passed to in parameters, the C# compiler generates a temporary.\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tcase ExpressionClassification.MutableLValue:\n\t\t\t\t\tcase ExpressionClassification.ReadonlyLValue:\n\t\t\t\t\t\t// For lvalues passed to in parameters, the C# compiler never generates temporaries.\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new InvalidOperationException(\"invalid expression classification\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (IsUsedAsThisPointerInFieldRead(loadInst))\n\t\t\t{\n\t\t\t\t// mcs generated temporaries for field reads on rvalues (#1555)\n\t\t\t\treturn ClassifyExpression(inlinedExpression) == ExpressionClassification.RValue;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tprivate static bool IsPassedToInlineArrayAsSpan(LdLoca loadInst)\n\t\t{\n\t\t\tif (loadInst.Parent is not Call call)\n\t\t\t\treturn false;\n\t\t\tvar method = call.Method;\n\t\t\tvar declaringType = method.DeclaringType;\n\t\t\treturn declaringType.ReflectionName == \"<PrivateImplementationDetails>\"\n\t\t\t\t&& method.Name is \"InlineArrayAsReadOnlySpan\" or \"InlineArrayAsSpan\"\n\t\t\t\t&& method.Parameters is [var arg, var length]\n\t\t\t\t&& (method.ReturnType.IsKnownType(KnownTypeCode.SpanOfT) || method.ReturnType.IsKnownType(KnownTypeCode.ReadOnlySpanOfT))\n\t\t\t\t&& arg.Type is ByReferenceType\n\t\t\t\t&& length.Type.IsKnownType(KnownTypeCode.Int32);\n\t\t}\n\n\t\tinternal static bool MethodRequiresCopyForReadonlyLValue(IMethod method, IType constrainedTo = null)\n\t\t{\n\t\t\tif (method == null)\n\t\t\t\treturn true;\n\t\t\tvar type = constrainedTo ?? method.DeclaringType;\n\t\t\tif (type.IsReferenceType == true)\n\t\t\t\treturn false; // reference types are never implicitly copied\n\t\t\tif (method.ThisIsRefReadOnly)\n\t\t\t\treturn false; // no copies for calls on readonly structs\n\t\t\treturn true;\n\t\t}\n\n\t\tinternal static bool IsUsedAsThisPointerInCall(LdLoca ldloca)\n\t\t{\n\t\t\treturn IsUsedAsThisPointerInCall(ldloca, out _, out _);\n\t\t}\n\n\t\tstatic bool IsUsedAsThisPointerInCall(LdLoca ldloca, out IMethod method, out IType constrainedType)\n\t\t{\n\t\t\tmethod = null;\n\t\t\tconstrainedType = null;\n\t\t\tif (ldloca.Variable.Type.IsReferenceType ?? false)\n\t\t\t\treturn false;\n\t\t\tILInstruction inst = ldloca;\n\t\t\tif (inst.Parent is LdObjIfRef)\n\t\t\t{\n\t\t\t\tinst = inst.Parent;\n\t\t\t}\n\t\t\twhile (inst.Parent is LdFlda ldflda)\n\t\t\t{\n\t\t\t\tinst = ldflda;\n\t\t\t}\n\t\t\tif (inst.ChildIndex != 0)\n\t\t\t\treturn false;\n\t\t\tswitch (inst.Parent.OpCode)\n\t\t\t{\n\t\t\t\tcase OpCode.Call:\n\t\t\t\tcase OpCode.CallVirt:\n\t\t\t\t\tvar callInst = (CallInstruction)inst.Parent;\n\t\t\t\t\tmethod = callInst.Method;\n\t\t\t\t\tconstrainedType = callInst.ConstrainedTo;\n\t\t\t\t\tif (method.IsAccessor)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (method.AccessorKind == MethodSemanticsAttributes.Getter)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// C# doesn't allow property compound assignments on temporary structs\n\t\t\t\t\t\t\treturn !(inst.Parent.Parent is CompoundAssignmentInstruction cai\n\t\t\t\t\t\t\t\t&& cai.TargetKind == CompoundTargetKind.Property\n\t\t\t\t\t\t\t\t&& cai.Target == inst.Parent);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// C# doesn't allow calling setters on temporary structs\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn !method.IsStatic;\n\t\t\t\tcase OpCode.Await:\n\t\t\t\t\tmethod = ((Await)inst.Parent).GetAwaiterMethod;\n\t\t\t\t\treturn true;\n\t\t\t\tcase OpCode.NullableUnwrap:\n\t\t\t\t\treturn ((NullableUnwrap)inst.Parent).RefInput;\n\t\t\t\tcase OpCode.MatchInstruction:\n\t\t\t\t\tmethod = ((MatchInstruction)inst.Parent).Method;\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tstatic bool IsUsedAsThisPointerInFieldRead(LdLoca ldloca)\n\t\t{\n\t\t\tif (ldloca.Variable.Type.IsReferenceType ?? false)\n\t\t\t\treturn false;\n\t\t\tILInstruction inst = ldloca;\n\t\t\twhile (inst.Parent is LdFlda ldflda)\n\t\t\t{\n\t\t\t\tinst = ldflda;\n\t\t\t}\n\t\t\treturn inst != ldloca && inst.Parent is LdObj;\n\t\t}\n\n\t\tinternal static bool IsPassedToInParameter(LdLoca ldloca)\n\t\t{\n\t\t\tif (ldloca.Parent is not CallInstruction call)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn call.GetParameter(ldloca.ChildIndex)?.ReferenceKind is ReferenceKind.In;\n\t\t}\n\n\t\tstatic bool IsPassedToReadOnlySpanCtor(LdLoca ldloca)\n\t\t{\n\t\t\tif (ldloca.Parent is not NewObj call)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar method = call.Method;\n\t\t\treturn method.IsConstructor\n\t\t\t\t&& method.Parameters.Count == 1\n\t\t\t\t&& method.DeclaringType.IsKnownType(KnownTypeCode.ReadOnlySpanOfT);\n\t\t}\n\n\t\tinternal static bool IsReadOnlySpanCharCtor(IMethod method)\n\t\t{\n\t\t\treturn method.IsConstructor\n\t\t\t\t&& method.Parameters.Count == 1\n\t\t\t\t&& method.DeclaringType.IsKnownType(KnownTypeCode.ReadOnlySpanOfT)\n\t\t\t\t&& method.DeclaringType.TypeArguments[0].IsKnownType(KnownTypeCode.Char)\n\t\t\t\t&& method.Parameters[0].Type is ByReferenceType brt\n\t\t\t\t&& brt.ElementType.IsKnownType(KnownTypeCode.Char);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the instruction, when converted into C#, turns into an l-value that can\n\t\t/// be used to mutate a value-type.\n\t\t/// If this function returns false, the C# compiler would introduce a temporary copy\n\t\t/// when calling a method on a value-type (and any mutations performed by the method will be lost)\n\t\t/// </summary>\n\t\tinternal static ExpressionClassification ClassifyExpression(ILInstruction inst)\n\t\t{\n\t\t\tswitch (inst.OpCode)\n\t\t\t{\n\t\t\t\tcase OpCode.LdLoc:\n\t\t\t\tcase OpCode.StLoc:\n\t\t\t\t\tILVariable v = ((IInstructionWithVariableOperand)inst).Variable;\n\t\t\t\t\tif (v.IsRefReadOnly\n\t\t\t\t\t\t|| v.Kind == VariableKind.ForeachLocal\n\t\t\t\t\t\t|| v.Kind == VariableKind.UsingLocal)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn ExpressionClassification.ReadonlyLValue;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn ExpressionClassification.MutableLValue;\n\t\t\t\t\t}\n\t\t\t\tcase OpCode.LdObj:\n\t\t\t\t\t// ldobj typically refers to a storage location,\n\t\t\t\t\t// but readonly fields are an exception.\n\t\t\t\t\tif (IsReadonlyReference(((LdObj)inst).Target))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn ExpressionClassification.ReadonlyLValue;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn ExpressionClassification.MutableLValue;\n\t\t\t\t\t}\n\t\t\t\tcase OpCode.StObj:\n\t\t\t\t\t// stobj is the same as ldobj.\n\t\t\t\t\tif (IsReadonlyReference(((StObj)inst).Target))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn ExpressionClassification.ReadonlyLValue;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn ExpressionClassification.MutableLValue;\n\t\t\t\t\t}\n\t\t\t\tcase OpCode.Call:\n\t\t\t\t\tvar m = ((CallInstruction)inst).Method;\n\t\t\t\t\t// multi-dimensional array getters are lvalues,\n\t\t\t\t\t// everything else is an rvalue.\n\t\t\t\t\tif (m.DeclaringType.Kind == TypeKind.Array)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn ExpressionClassification.MutableLValue;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn ExpressionClassification.RValue;\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\treturn ExpressionClassification.RValue; // most instructions result in an rvalue\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the ILInstruction will turn into a C# expresion that is considered readonly by the C# compiler.\n\t\t/// </summary>\n\t\tinternal static bool IsReadonlyReference(ILInstruction addr)\n\t\t{\n\t\t\tswitch (addr)\n\t\t\t{\n\t\t\t\tcase LdFlda ldflda:\n\t\t\t\t\treturn ldflda.Field.IsReadOnly\n\t\t\t\t\t\t|| (ldflda.Field.DeclaringType.Kind == TypeKind.Struct && IsReadonlyReference(ldflda.Target));\n\t\t\t\tcase LdsFlda ldsflda:\n\t\t\t\t\treturn ldsflda.Field.IsReadOnly;\n\t\t\t\tcase LdLoc ldloc:\n\t\t\t\t\treturn ldloc.Variable.IsRefReadOnly;\n\t\t\t\tcase Call call:\n\t\t\t\t\treturn call.Method.ReturnTypeIsRefReadOnly;\n\t\t\t\tcase CallVirt call:\n\t\t\t\t\treturn call.Method.ReturnTypeIsRefReadOnly;\n\t\t\t\tcase CallIndirect calli:\n\t\t\t\t\treturn calli.FunctionPointerType.ReturnIsRefReadOnly;\n\t\t\t\tcase AddressOf _:\n\t\t\t\t\t// C# doesn't allow mutation of value-type temporaries\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\tif (addr.MatchLdFld(out _, out var field))\n\t\t\t\t\t\treturn field.ReturnTypeIsRefReadOnly;\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Determines whether a variable should be inlined in non-aggressive mode, even though it is not a generated variable.\n\t\t/// </summary>\n\t\t/// <param name=\"next\">The next top-level expression</param>\n\t\t/// <param name=\"v\">The variable being eliminated by inlining.</param>\n\t\t/// <param name=\"inlinedExpression\">The expression being inlined</param>\n\t\tstatic bool NonAggressiveInlineInto(ILInstruction next, FindResult findResult, ILInstruction inlinedExpression, ILVariable v)\n\t\t{\n\t\t\tif (findResult.Type == FindResultType.NamedArgument)\n\t\t\t{\n\t\t\t\tvar originalStore = (StLoc)inlinedExpression.Parent;\n\t\t\t\treturn !originalStore.ILStackWasEmpty;\n\t\t\t}\n\t\t\tDebug.Assert(findResult.Type == FindResultType.Found);\n\n\t\t\tvar loadInst = findResult.LoadInst;\n\t\t\tDebug.Assert(loadInst.IsDescendantOf(next));\n\n\t\t\t// decide based on the source expression being inlined\n\t\t\tswitch (inlinedExpression.OpCode)\n\t\t\t{\n\t\t\t\tcase OpCode.DefaultValue:\n\t\t\t\tcase OpCode.StObj:\n\t\t\t\tcase OpCode.NumericCompoundAssign:\n\t\t\t\tcase OpCode.UserDefinedCompoundAssign:\n\t\t\t\tcase OpCode.Await:\n\t\t\t\tcase OpCode.SwitchInstruction:\n\t\t\t\t\treturn true;\n\t\t\t\tcase OpCode.LdLoc:\n\t\t\t\t\tif (v.StateMachineField == null && ((LdLoc)inlinedExpression).Variable.StateMachineField != null)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Roslyn likes to put the result of fetching a state machine field into a temporary variable,\n\t\t\t\t\t\t// so inline more aggressively in such cases.\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (inlinedExpression.ResultType == StackType.Ref)\n\t\t\t{\n\t\t\t\t// VB likes to use ref locals for compound assignment\n\t\t\t\t// (the C# compiler uses ref stack slots instead).\n\t\t\t\t// We want to avoid unnecessary ref locals, so we'll always inline them if possible.\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tvar parent = loadInst.Parent;\n\t\t\tif (NullableLiftingTransform.MatchNullableCtor(parent, out _, out _))\n\t\t\t{\n\t\t\t\t// inline into nullable ctor call in lifted operator\n\t\t\t\tparent = parent.Parent;\n\t\t\t}\n\t\t\tif (parent is ILiftableInstruction liftable && liftable.IsLifted)\n\t\t\t{\n\t\t\t\treturn true; // inline into lifted operators\n\t\t\t}\n\t\t\t// decide based on the new parent into which we are inlining:\n\t\t\tswitch (parent.OpCode)\n\t\t\t{\n\t\t\t\tcase OpCode.NullCoalescingInstruction:\n\t\t\t\t\tif (NullableType.IsNullable(v.Type))\n\t\t\t\t\t\treturn true; // inline nullables into ?? operator\n\t\t\t\t\tbreak;\n\t\t\t\tcase OpCode.NullableUnwrap:\n\t\t\t\t\treturn true; // inline into ?. operator\n\t\t\t\tcase OpCode.UserDefinedLogicOperator:\n\t\t\t\tcase OpCode.DynamicLogicOperatorInstruction:\n\t\t\t\t\treturn true; // inline into (left slot of) user-defined && or || operator\n\t\t\t\tcase OpCode.DynamicGetMemberInstruction:\n\t\t\t\tcase OpCode.DynamicGetIndexInstruction:\n\t\t\t\t\tif (parent.Parent.OpCode == OpCode.DynamicCompoundAssign)\n\t\t\t\t\t\treturn true; // inline into dynamic compound assignments\n\t\t\t\t\tbreak;\n\t\t\t\tcase OpCode.DynamicCompoundAssign:\n\t\t\t\t\treturn true;\n\t\t\t\tcase OpCode.GetPinnableReference:\n\t\t\t\tcase OpCode.LocAllocSpan:\n\t\t\t\t\treturn true; // inline size-expressions into localloc.span\n\t\t\t\tcase OpCode.Call:\n\t\t\t\tcase OpCode.CallVirt:\n\t\t\t\t\t// Aggressive inline into property/indexer getter calls for compound assignment calls\n\t\t\t\t\t// (The compiler generates locals for these because it doesn't want to evalute the args twice for getter+setter)\n\t\t\t\t\tif (parent.SlotInfo == CompoundAssignmentInstruction.TargetSlot)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tif (((CallInstruction)parent).Method is SyntheticRangeIndexAccessor)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase OpCode.CallIndirect when loadInst.SlotInfo == CallIndirect.FunctionPointerSlot:\n\t\t\t\t\treturn true;\n\t\t\t\tcase OpCode.LdElema:\n\t\t\t\t\tif (((LdElema)parent).WithSystemIndex)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase OpCode.Leave:\n\t\t\t\tcase OpCode.YieldReturn:\n\t\t\t\t\treturn true;\n\t\t\t\tcase OpCode.SwitchInstruction:\n\t\t\t\t\t// Preserve type info on switch instruction, if we're inlining a local variable into the switch-value slot.\n\t\t\t\t\tif (v.Kind != VariableKind.StackSlot && loadInst.SlotInfo == SwitchInstruction.ValueSlot)\n\t\t\t\t\t{\n\t\t\t\t\t\t((SwitchInstruction)parent).Type ??= v.Type;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t//case OpCode.BinaryNumericInstruction when parent.SlotInfo == SwitchInstruction.ValueSlot:\n\t\t\t\tcase OpCode.StringToInt when parent.SlotInfo == SwitchInstruction.ValueSlot:\n\t\t\t\t\treturn true;\n\t\t\t\tcase OpCode.MatchInstruction:\n\t\t\t\t\tvar match = (MatchInstruction)parent;\n\t\t\t\t\tif (match.IsDeconstructTuple\n\t\t\t\t\t\t|| (match.CheckType && match.Variable.Type.IsReferenceType != true))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// decide based on the top-level target instruction into which we are inlining:\n\t\t\tswitch (next.OpCode)\n\t\t\t{\n\t\t\t\tcase OpCode.IfInstruction:\n\t\t\t\t\twhile (parent.MatchLogicNot(out _))\n\t\t\t\t\t{\n\t\t\t\t\t\tparent = parent.Parent;\n\t\t\t\t\t}\n\t\t\t\t\treturn parent == next;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether 'expressionBeingMoved' can be inlined into 'expr'.\n\t\t/// </summary>\n\t\tpublic static bool CanInlineInto(ILInstruction expr, ILVariable v, ILInstruction expressionBeingMoved)\n\t\t{\n\t\t\treturn FindLoadInNext(expr, v, expressionBeingMoved, InliningOptions.None).Type == FindResultType.Found;\n\t\t}\n\n\t\tinternal enum FindResultType\n\t\t{\n\t\t\t/// <summary>\n\t\t\t/// Found a load; inlining is possible.\n\t\t\t/// </summary>\n\t\t\tFound,\n\t\t\t/// <summary>\n\t\t\t/// Load not found and re-ordering not possible. Stop the search.\n\t\t\t/// </summary>\n\t\t\tStop,\n\t\t\t/// <summary>\n\t\t\t/// Load not found, but the expressionBeingMoved can be re-ordered with regards to the\n\t\t\t/// tested expression, so we may continue searching for the matching load.\n\t\t\t/// </summary>\n\t\t\tContinue,\n\t\t\t/// <summary>\n\t\t\t/// Found a load in call, but re-ordering not possible with regards to the\n\t\t\t/// other call arguments.\n\t\t\t/// Inlining is not possible, but we might convert the call to named arguments.\n\t\t\t/// Only used with <see cref=\"InliningOptions.IntroduceNamedArguments\"/>.\n\t\t\t/// </summary>\n\t\t\tNamedArgument,\n\t\t\t/// <summary>\n\t\t\t/// Found a deconstruction.\n\t\t\t/// Only used with <see cref=\"InliningOptions.FindDeconstruction\"/>.\n\t\t\t/// </summary>\n\t\t\tDeconstruction,\n\t\t}\n\n\t\tinternal readonly struct FindResult\n\t\t{\n\t\t\tpublic readonly FindResultType Type;\n\t\t\tpublic readonly ILInstruction LoadInst; // ldloc or ldloca instruction that loads the variable to be inlined\n\t\t\tpublic readonly ILInstruction CallArgument; // argument of call that needs to be promoted to a named argument\n\n\t\t\tprivate FindResult(FindResultType type, ILInstruction loadInst, ILInstruction callArg)\n\t\t\t{\n\t\t\t\tthis.Type = type;\n\t\t\t\tthis.LoadInst = loadInst;\n\t\t\t\tthis.CallArgument = callArg;\n\t\t\t}\n\n\t\t\tpublic static readonly FindResult Stop = new FindResult(FindResultType.Stop, null, null);\n\t\t\tpublic static readonly FindResult Continue = new FindResult(FindResultType.Continue, null, null);\n\n\t\t\tpublic static FindResult Found(ILInstruction loadInst)\n\t\t\t{\n\t\t\t\tDebug.Assert(loadInst.OpCode == OpCode.LdLoc || loadInst.OpCode == OpCode.LdLoca);\n\t\t\t\treturn new FindResult(FindResultType.Found, loadInst, null);\n\t\t\t}\n\n\t\t\tpublic static FindResult NamedArgument(ILInstruction loadInst, ILInstruction callArg)\n\t\t\t{\n\t\t\t\tDebug.Assert(loadInst.OpCode == OpCode.LdLoc || loadInst.OpCode == OpCode.LdLoca);\n\t\t\t\tDebug.Assert(callArg.Parent is CallInstruction);\n\t\t\t\treturn new FindResult(FindResultType.NamedArgument, loadInst, callArg);\n\t\t\t}\n\n\t\t\tpublic static FindResult Deconstruction(DeconstructInstruction deconstruction)\n\t\t\t{\n\t\t\t\treturn new FindResult(FindResultType.Deconstruction, deconstruction, null);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Finds the position to inline to.\n\t\t/// </summary>\n\t\t/// <returns>true = found; false = cannot continue search; null = not found</returns>\n\t\tinternal static FindResult FindLoadInNext(ILInstruction expr, ILVariable v, ILInstruction expressionBeingMoved, InliningOptions options)\n\t\t{\n\t\t\tif (expr == null)\n\t\t\t\treturn FindResult.Stop;\n\t\t\tif (expr.MatchLdLoc(v) || expr.MatchLdLoca(v))\n\t\t\t{\n\t\t\t\t// Match found, we can inline unless there are slot restrictions.\n\t\t\t\tif (expr.Parent.SatisfiesSlotRestrictionForInlining(expr.ChildIndex, expressionBeingMoved))\n\t\t\t\t{\n\t\t\t\t\treturn FindResult.Found(expr);\n\t\t\t\t}\n\t\t\t\t// We cannot inline because the targets slot restrictions are not satisfied\n\t\t\t\tif ((options & InliningOptions.AllowChangingOrderOfEvaluationForExceptions) != 0 && expr.SlotInfo == StObj.TargetSlot)\n\t\t\t\t{\n\t\t\t\t\t// Special case: inlining will change code semantics,\n\t\t\t\t\t// but we accept that so that we can avoid a ref local.\n\t\t\t\t\tif (expressionBeingMoved is LdFlda ldflda)\n\t\t\t\t\t\tldflda.DelayExceptions = true;\n\t\t\t\t\telse if (expressionBeingMoved is LdElema ldelema)\n\t\t\t\t\t\tldelema.DelayExceptions = true;\n\t\t\t\t\treturn FindResult.Found(expr);\n\t\t\t\t}\n\t\t\t\treturn FindResult.Stop;\n\t\t\t}\n\t\t\telse if (expr is Block { Kind: BlockKind.CallWithNamedArgs } block)\n\t\t\t{\n\t\t\t\treturn NamedArgumentTransform.CanExtendNamedArgument(block, v, expressionBeingMoved);\n\t\t\t}\n\t\t\telse if (options.HasFlag(InliningOptions.FindDeconstruction) && expr is DeconstructInstruction di)\n\t\t\t{\n\t\t\t\treturn FindResult.Deconstruction(di);\n\t\t\t}\n\t\t\tforeach (var child in expr.Children)\n\t\t\t{\n\t\t\t\tif (!expr.CanInlineIntoSlot(child.ChildIndex, expressionBeingMoved))\n\t\t\t\t\treturn FindResult.Stop;\n\n\t\t\t\t// Recursively try to find the load instruction\n\t\t\t\tFindResult r = FindLoadInNext(child, v, expressionBeingMoved, options);\n\t\t\t\tif (r.Type != FindResultType.Continue)\n\t\t\t\t{\n\t\t\t\t\tif (r.Type == FindResultType.Stop && (options & InliningOptions.IntroduceNamedArguments) != 0 && expr is CallInstruction call)\n\t\t\t\t\t\treturn NamedArgumentTransform.CanIntroduceNamedArgument(call, child, v, expressionBeingMoved);\n\t\t\t\t\treturn r;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (IsSafeForInlineOver(expr, expressionBeingMoved))\n\t\t\t\treturn FindResult.Continue; // continue searching\n\t\t\telse\n\t\t\t\treturn FindResult.Stop; // abort, inlining not possible\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Determines whether it is safe to move 'expressionBeingMoved' past 'expr'\n\t\t/// </summary>\n\t\tstatic bool IsSafeForInlineOver(ILInstruction expr, ILInstruction expressionBeingMoved)\n\t\t{\n\t\t\treturn SemanticHelper.MayReorder(expressionBeingMoved, expr);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Finds the first call instruction within the instructions that were inlined into inst.\n\t\t/// </summary>\n\t\tinternal static CallInstruction FindFirstInlinedCall(ILInstruction inst)\n\t\t{\n\t\t\tforeach (var child in inst.Children)\n\t\t\t{\n\t\t\t\tif (!child.SlotInfo.CanInlineInto)\n\t\t\t\t\tbreak;\n\t\t\t\tvar call = FindFirstInlinedCall(child);\n\t\t\t\tif (call != null)\n\t\t\t\t{\n\t\t\t\t\treturn call;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn inst as CallInstruction;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether 'expressionBeingMoved' can be moved from somewhere before 'stmt' to become the replacement of 'targetLoad'.\n\t\t/// </summary>\n\t\tpublic static bool CanMoveInto(ILInstruction expressionBeingMoved, ILInstruction stmt, ILInstruction targetLoad)\n\t\t{\n\t\t\tDebug.Assert(targetLoad.IsDescendantOf(stmt));\n\t\t\tfor (ILInstruction inst = targetLoad; inst != stmt; inst = inst.Parent)\n\t\t\t{\n\t\t\t\tif (!inst.Parent.CanInlineIntoSlot(inst.ChildIndex, expressionBeingMoved))\n\t\t\t\t\treturn false;\n\t\t\t\t// Check whether re-ordering with predecessors is valid:\n\t\t\t\tint childIndex = inst.ChildIndex;\n\t\t\t\tfor (int i = 0; i < childIndex; ++i)\n\t\t\t\t{\n\t\t\t\t\tILInstruction predecessor = inst.Parent.Children[i];\n\t\t\t\t\tif (!IsSafeForInlineOver(predecessor, expressionBeingMoved))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether 'expressionBeingMoved' can be moved from somewhere before 'stmt' to become the replacement of 'targetLoad'.\n\t\t/// </summary>\n\t\tpublic static bool CanMoveIntoCallVirt(ILInstruction expressionBeingMoved, ILInstruction stmt, CallVirt nestedCallVirt, ILInstruction targetLoad)\n\t\t{\n\t\t\tDebug.Assert(targetLoad.IsDescendantOf(stmt) && nestedCallVirt.IsDescendantOf(stmt));\n\t\t\tILInstruction thisArg = nestedCallVirt.Arguments[0];\n\t\t\tDebug.Assert(thisArg is LdObjIfRef);\n\t\t\tfor (ILInstruction inst = targetLoad; inst != stmt; inst = inst.Parent)\n\t\t\t{\n\t\t\t\tif (!inst.Parent.CanInlineIntoSlot(inst.ChildIndex, expressionBeingMoved))\n\t\t\t\t\treturn false;\n\t\t\t\t// Check whether re-ordering with predecessors is valid:\n\t\t\t\tint childIndex = inst.ChildIndex;\n\t\t\t\tfor (int i = 0; i < childIndex; ++i)\n\t\t\t\t{\n\t\t\t\t\tILInstruction predecessor = inst.Parent.Children[i];\n\t\t\t\t\tif (predecessor != thisArg && !IsSafeForInlineOver(predecessor, expressionBeingMoved))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether arg can be un-inlined out of stmt.\n\t\t/// </summary>\n\t\t/// <seealso cref=\"ILInstruction.Extract\"/>\n\t\tinternal static bool CanUninline(ILInstruction arg, ILInstruction stmt)\n\t\t{\n\t\t\t// moving into and moving out-of are equivalent\n\t\t\treturn CanMoveInto(arg, stmt, arg);\n\t\t}\n\t}\n\n\tinternal enum ExpressionClassification\n\t{\n\t\tRValue,\n\t\tMutableLValue,\n\t\tReadonlyLValue,\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/IndexRangeTransform.cs",
    "content": "// Copyright (c) 2020 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Transform for the C# 8 System.Index / System.Range feature\n\t/// </summary>\n\tclass IndexRangeTransform : IStatementTransform\n\t{\n\t\t/// <summary>\n\t\t/// Called by expression transforms.\n\t\t/// Handles the `array[System.Index]` cases.\n\t\t/// </summary>\n\t\tpublic static bool HandleLdElema(LdElema ldelema, ILTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.Ranges)\n\t\t\t\treturn false;\n\t\t\tif (!ldelema.Array.MatchLdLoc(out ILVariable array))\n\t\t\t\treturn false;\n\t\t\tif (ldelema.Indices.Count != 1)\n\t\t\t\treturn false; // the index/range feature doesn't support multi-dimensional arrays\n\t\t\tvar index = ldelema.Indices[0];\n\t\t\tif (index is CallInstruction call && call.Method.Name == \"GetOffset\" && call.Method.DeclaringType.IsKnownType(KnownTypeCode.Index))\n\t\t\t{\n\t\t\t\t// ldelema T(ldloc array, call GetOffset(..., ldlen.i4(ldloc array)))\n\t\t\t\t// -> withsystemindex.ldelema T(ldloc array, ...)\n\t\t\t\tif (call.Arguments.Count != 2)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(call.Arguments[1].MatchLdLen(StackType.I4, out var arrayLoad) && arrayLoad.MatchLdLoc(array)))\n\t\t\t\t\treturn false;\n\t\t\t\tcontext.Step(\"ldelema with System.Index\", ldelema);\n\t\t\t\tforeach (var node in call.Arguments[1].Descendants)\n\t\t\t\t\tldelema.AddILRange(node);\n\t\t\t\tldelema.AddILRange(call);\n\t\t\t\tldelema.WithSystemIndex = true;\n\t\t\t\t// The method call had a `ref System.Index` argument for the this pointer, but we want a `System.Index` by-value.\n\t\t\t\tldelema.Indices[0] = new LdObj(call.Arguments[0], call.Method.DeclaringType);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (index is BinaryNumericInstruction bni && bni.Operator == BinaryNumericOperator.Sub && !bni.IsLifted && !bni.CheckForOverflow)\n\t\t\t{\n\t\t\t\t// ldelema T(ldloc array, binary.sub.i4(ldlen.i4(ldloc array), ...))\n\t\t\t\t// -> withsystemindex.ldelema T(ldloc array, newobj System.Index(..., fromEnd: true))\n\t\t\t\tif (!(bni.Left.MatchLdLen(StackType.I4, out var arrayLoad) && arrayLoad.MatchLdLoc(array)))\n\t\t\t\t\treturn false;\n\t\t\t\tvar indexMethods = new IndexMethods(context.TypeSystem);\n\t\t\t\tif (!indexMethods.IsValid)\n\t\t\t\t\treturn false; // don't use System.Index if not supported by the target framework\n\t\t\t\tcontext.Step(\"ldelema indexed from end\", ldelema);\n\t\t\t\tforeach (var node in bni.Left.Descendants)\n\t\t\t\t\tldelema.AddILRange(node);\n\t\t\t\tldelema.AddILRange(bni);\n\t\t\t\tldelema.WithSystemIndex = true;\n\t\t\t\tldelema.Indices[0] = MakeIndex(IndexKind.FromEnd, bni.Right, indexMethods);\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tclass IndexMethods\n\t\t{\n\t\t\tpublic readonly IMethod IndexCtor;\n\t\t\tpublic readonly IMethod IndexImplicitConv;\n\t\t\tpublic readonly IMethod RangeCtor;\n\t\t\tpublic IType IndexType => IndexCtor?.DeclaringType;\n\t\t\tpublic IType RangeType => RangeCtor?.DeclaringType;\n\t\t\tpublic bool IsValid => IndexCtor != null && IndexImplicitConv != null && RangeCtor != null;\n\n\t\t\tpublic readonly IMethod RangeStartAt;\n\t\t\tpublic readonly IMethod RangeEndAt;\n\t\t\tpublic readonly IMethod RangeGetAll;\n\n\t\t\tpublic IndexMethods(ICompilation compilation)\n\t\t\t{\n\t\t\t\tvar indexType = compilation.FindType(KnownTypeCode.Index);\n\t\t\t\tforeach (var ctor in indexType.GetConstructors(m => m.Parameters.Count == 2))\n\t\t\t\t{\n\t\t\t\t\tif (ctor.Parameters[0].Type.IsKnownType(KnownTypeCode.Int32)\n\t\t\t\t\t\t&& ctor.Parameters[1].Type.IsKnownType(KnownTypeCode.Boolean))\n\t\t\t\t\t{\n\t\t\t\t\t\tthis.IndexCtor = ctor;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tforeach (var op in indexType.GetMethods(m => m.IsOperator && m.Name == \"op_Implicit\"))\n\t\t\t\t{\n\t\t\t\t\tif (op.Parameters.Count == 1 && op.Parameters[0].Type.IsKnownType(KnownTypeCode.Int32))\n\t\t\t\t\t{\n\t\t\t\t\t\tthis.IndexImplicitConv = op;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvar rangeType = compilation.FindType(KnownTypeCode.Range);\n\t\t\t\tforeach (var ctor in rangeType.GetConstructors(m => m.Parameters.Count == 2))\n\t\t\t\t{\n\t\t\t\t\tif (ctor.Parameters[0].Type.IsKnownType(KnownTypeCode.Index)\n\t\t\t\t\t\t&& ctor.Parameters[1].Type.IsKnownType(KnownTypeCode.Index))\n\t\t\t\t\t{\n\t\t\t\t\t\tthis.RangeCtor = ctor;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tforeach (var m in rangeType.GetMethods(m => m.Parameters.Count == 1))\n\t\t\t\t{\n\t\t\t\t\tif (m.Parameters.Count == 1 && m.Parameters[0].Type.IsKnownType(KnownTypeCode.Index))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (m.Name == \"StartAt\")\n\t\t\t\t\t\t\tthis.RangeStartAt = m;\n\t\t\t\t\t\telse if (m.Name == \"EndAt\")\n\t\t\t\t\t\t\tthis.RangeEndAt = m;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tforeach (var p in rangeType.GetProperties(p => p.IsStatic && p.Name == \"All\"))\n\t\t\t\t{\n\t\t\t\t\tthis.RangeGetAll = p.Getter;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic static bool IsRangeCtor(IMethod method)\n\t\t\t{\n\t\t\t\treturn method.SymbolKind == SymbolKind.Constructor\n\t\t\t\t\t&& method.Parameters.Count == 2\n\t\t\t\t\t&& method.DeclaringType.IsKnownType(KnownTypeCode.Range)\n\t\t\t\t\t&& method.Parameters.All(p => p.Type.IsKnownType(KnownTypeCode.Index));\n\t\t\t}\n\t\t}\n\n\t\tvoid IStatementTransform.Run(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.Ranges)\n\t\t\t\treturn;\n\t\t\tint startPos = pos;\n\t\t\tILVariable containerVar = null;\n\t\t\t// The container length access may be a separate instruction, or it may be inline with the variable's use\n\t\t\tif (MatchContainerLengthStore(block.Instructions[pos], out ILVariable containerLengthVar, ref containerVar))\n\t\t\t{\n\t\t\t\t//  stloc containerLengthVar(call get_Length/get_Count(ldloc container))\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Reset if MatchContainerLengthStore only had a partial match. MatchGetOffset() will then set `containerVar`.\n\t\t\t\tcontainerLengthVar = null;\n\t\t\t\tcontainerVar = null;\n\t\t\t}\n\t\t\tif (block.Instructions[pos].MatchStLoc(out var rangeVar, out var rangeVarInit) && rangeVar.Type.IsKnownType(KnownTypeCode.Range))\n\t\t\t{\n\t\t\t\t// stloc rangeVar(rangeVarInit)\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\trangeVar = null;\n\t\t\t\trangeVarInit = null;\n\t\t\t}\n\n\t\t\t// stloc startOffsetVar(call GetOffset(startIndexLoad, ldloc length))\n\t\t\tif (!(block.Instructions[pos].MatchStLoc(out ILVariable startOffsetVar, out ILInstruction startOffsetVarInit)\n\t\t\t\t&& startOffsetVar.IsSingleDefinition && startOffsetVar.StackType == StackType.I4))\n\t\t\t{\n\t\t\t\t// Not our primary indexing/slicing pattern.\n\t\t\t\t// However, we might be dealing with a partially-transformed pattern that needs to be extended.\n\t\t\t\tExtendSlicing();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar startIndexKind = MatchGetOffset(startOffsetVarInit, out ILInstruction startIndexLoad, containerLengthVar, ref containerVar);\n\t\t\tpos++;\n\t\t\tif (startOffsetVar.LoadCount == 1)\n\t\t\t{\n\t\t\t\tTransformIndexing();\n\t\t\t}\n\t\t\telse if (startOffsetVar.LoadCount == 2)\n\t\t\t{\n\t\t\t\t// might be slicing: startOffset is used once for the slice length calculation, and once for the Slice() method call\n\t\t\t\tTransformSlicing();\n\t\t\t}\n\n\t\t\tvoid TransformIndexing()\n\t\t\t{\n\t\t\t\t// complex_expr(call get_Item(ldloc container, ldloc startOffsetVar))\n\n\t\t\t\tif (rangeVar != null)\n\t\t\t\t\treturn;\n\t\t\t\tif (!(startOffsetVar.LoadInstructions.Single().Parent is CallInstruction call))\n\t\t\t\t\treturn;\n\t\t\t\tif (call.Method.AccessorKind == System.Reflection.MethodSemanticsAttributes.Getter && call.Arguments.Count == 2)\n\t\t\t\t{\n\t\t\t\t\tif (call.Method.AccessorOwner?.SymbolKind != SymbolKind.Indexer)\n\t\t\t\t\t\treturn;\n\t\t\t\t\tif (call.Method.Parameters.Count != 1)\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\telse if (call.Method.AccessorKind == System.Reflection.MethodSemanticsAttributes.Setter && call.Arguments.Count == 3)\n\t\t\t\t{\n\t\t\t\t\tif (call.Method.AccessorOwner?.SymbolKind != SymbolKind.Indexer)\n\t\t\t\t\t\treturn;\n\t\t\t\t\tif (call.Method.Parameters.Count != 2)\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\telse if (IsSlicingMethod(call.Method))\n\t\t\t\t{\n\t\t\t\t\tTransformSlicing(sliceLengthWasMisdetectedAsStartOffset: true);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (startIndexKind == IndexKind.FromStart)\n\t\t\t\t{\n\t\t\t\t\t// FromStart is only relevant for slicing; indexing from the start does not involve System.Index at all.\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!CheckContainerLengthVariableUseCount(containerLengthVar, startIndexKind))\n\t\t\t\t{\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!call.IsDescendantOf(block.Instructions[pos]))\n\t\t\t\t\treturn;\n\t\t\t\t// startOffsetVar might be used deep inside a complex statement, ensure we can inline up to that point:\n\t\t\t\tfor (int i = startPos; i < pos; i++)\n\t\t\t\t{\n\t\t\t\t\tif (!ILInlining.CanInlineInto(block.Instructions[pos], startOffsetVar, block.Instructions[i]))\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!call.Method.Parameters[0].Type.IsKnownType(KnownTypeCode.Int32))\n\t\t\t\t\treturn;\n\t\t\t\tif (!MatchContainerVar(call.Arguments[0], ref containerVar))\n\t\t\t\t\treturn;\n\t\t\t\tif (!call.Arguments[1].MatchLdLoc(startOffsetVar))\n\t\t\t\t\treturn;\n\t\t\t\tvar specialMethods = new IndexMethods(context.TypeSystem);\n\t\t\t\tif (!specialMethods.IsValid)\n\t\t\t\t\treturn;\n\t\t\t\tif (!CSharpWillGenerateIndexer(call.Method.DeclaringType, slicing: false))\n\t\t\t\t\treturn;\n\n\t\t\t\tcontext.Step($\"{call.Method.Name} indexed with {startIndexKind}\", call);\n\t\t\t\tvar newMethod = new SyntheticRangeIndexAccessor(call.Method, specialMethods.IndexType, slicing: false);\n\t\t\t\tvar newCall = CallInstruction.Create(call.OpCode, newMethod);\n\t\t\t\tnewCall.ConstrainedTo = call.ConstrainedTo;\n\t\t\t\tnewCall.ILStackWasEmpty = call.ILStackWasEmpty;\n\t\t\t\tnewCall.Arguments.Add(call.Arguments[0]);\n\t\t\t\tnewCall.Arguments.Add(MakeIndex(startIndexKind, startIndexLoad, specialMethods));\n\t\t\t\tnewCall.Arguments.AddRange(call.Arguments.Skip(2));\n\t\t\t\tnewCall.AddILRange(call);\n\t\t\t\tfor (int i = startPos; i < pos; i++)\n\t\t\t\t{\n\t\t\t\t\tnewCall.AddILRange(block.Instructions[i]);\n\t\t\t\t}\n\t\t\t\tcall.ReplaceWith(newCall);\n\t\t\t\tblock.Instructions.RemoveRange(startPos, pos - startPos);\n\t\t\t}\n\n\t\t\tvoid TransformSlicing(bool sliceLengthWasMisdetectedAsStartOffset = false)\n\t\t\t{\n\t\t\t\tILVariable sliceLengthVar;\n\t\t\t\tILInstruction sliceLengthVarInit;\n\t\t\t\tif (sliceLengthWasMisdetectedAsStartOffset)\n\t\t\t\t{\n\t\t\t\t\t// Special case: when slicing without a start point, the slice length calculation is mis-detected as the start offset,\n\t\t\t\t\t// and since it only has a single use, we end in TransformIndexing(), which then calls TransformSlicing\n\t\t\t\t\t// on this code path.\n\t\t\t\t\tsliceLengthVar = startOffsetVar;\n\t\t\t\t\tsliceLengthVarInit = ((StLoc)sliceLengthVar.StoreInstructions.Single()).Value;\n\t\t\t\t\tstartOffsetVar = null;\n\t\t\t\t\tstartIndexLoad = new LdcI4(0);\n\t\t\t\t\tstartIndexKind = IndexKind.TheStart;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// stloc containerLengthVar(call get_Length(ldloc containerVar))\n\t\t\t\t\t// stloc startOffset(call GetOffset(startIndexLoad, ldloc length))\n\t\t\t\t\t// -- we are here --\n\t\t\t\t\t// stloc sliceLengthVar(binary.sub.i4(call GetOffset(endIndexLoad, ldloc length), ldloc startOffset))\n\t\t\t\t\t// complex_expr(call Slice(ldloc containerVar, ldloc startOffset, ldloc sliceLength))\n\n\t\t\t\t\tif (!block.Instructions[pos].MatchStLoc(out sliceLengthVar, out sliceLengthVarInit))\n\t\t\t\t\t\treturn;\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\n\t\t\t\tif (!(sliceLengthVar.IsSingleDefinition && sliceLengthVar.LoadCount == 1))\n\t\t\t\t\treturn;\n\t\t\t\tif (!MatchSliceLength(sliceLengthVarInit, out IndexKind endIndexKind, out ILInstruction endIndexLoad, containerLengthVar, ref containerVar, startOffsetVar))\n\t\t\t\t\treturn;\n\t\t\t\tif (!CheckContainerLengthVariableUseCount(containerLengthVar, startIndexKind, endIndexKind))\n\t\t\t\t{\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (rangeVar != null)\n\t\t\t\t{\n\t\t\t\t\treturn; // this should only ever happen in the second step (ExtendSlicing)\n\t\t\t\t}\n\t\t\t\tif (!(sliceLengthVar.LoadInstructions.Single().Parent is CallInstruction call))\n\t\t\t\t\treturn;\n\t\t\t\tif (!call.IsDescendantOf(block.Instructions[pos]))\n\t\t\t\t\treturn;\n\t\t\t\tif (!IsSlicingMethod(call.Method))\n\t\t\t\t\treturn;\n\t\t\t\tif (call.Arguments.Count != 3)\n\t\t\t\t\treturn;\n\t\t\t\tif (!MatchContainerVar(call.Arguments[0], ref containerVar))\n\t\t\t\t\treturn;\n\t\t\t\tif (startOffsetVar == null)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(startIndexKind == IndexKind.TheStart);\n\t\t\t\t\tif (!call.Arguments[1].MatchLdcI4(0))\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (!call.Arguments[1].MatchLdLoc(startOffsetVar))\n\t\t\t\t\t\treturn;\n\t\t\t\t\tif (!ILInlining.CanMoveInto(startOffsetVarInit, block.Instructions[pos], call.Arguments[1]))\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!call.Arguments[2].MatchLdLoc(sliceLengthVar))\n\t\t\t\t\treturn;\n\t\t\t\tif (!ILInlining.CanMoveInto(sliceLengthVarInit, block.Instructions[pos], call.Arguments[2]))\n\t\t\t\t\treturn;\n\t\t\t\tif (!CSharpWillGenerateIndexer(call.Method.DeclaringType, slicing: true))\n\t\t\t\t\treturn;\n\t\t\t\tvar specialMethods = new IndexMethods(context.TypeSystem);\n\t\t\t\tif (!specialMethods.IsValid)\n\t\t\t\t\treturn;\n\n\t\t\t\tcontext.Step($\"{call.Method.Name} sliced with {startIndexKind}..{endIndexKind}\", call);\n\t\t\t\tvar newMethod = new SyntheticRangeIndexAccessor(call.Method, specialMethods.RangeType, slicing: true);\n\t\t\t\tvar newCall = CallInstruction.Create(call.OpCode, newMethod);\n\t\t\t\tnewCall.ConstrainedTo = call.ConstrainedTo;\n\t\t\t\tnewCall.ILStackWasEmpty = call.ILStackWasEmpty;\n\t\t\t\tnewCall.Arguments.Add(call.Arguments[0]);\n\t\t\t\tnewCall.Arguments.Add(MakeRange(startIndexKind, startIndexLoad, endIndexKind, endIndexLoad, specialMethods));\n\t\t\t\tnewCall.AddILRange(call);\n\t\t\t\tfor (int i = startPos; i < pos; i++)\n\t\t\t\t{\n\t\t\t\t\tnewCall.AddILRange(block.Instructions[i]);\n\t\t\t\t}\n\t\t\t\tcall.ReplaceWith(newCall);\n\t\t\t\tblock.Instructions.RemoveRange(startPos, pos - startPos);\n\t\t\t}\n\n\t\t\tILInstruction MakeRange(IndexKind startIndexKind, ILInstruction startIndexLoad, IndexKind endIndexKind, ILInstruction endIndexLoad, IndexMethods specialMethods)\n\t\t\t{\n\t\t\t\tif (rangeVar != null)\n\t\t\t\t{\n\t\t\t\t\treturn rangeVarInit;\n\t\t\t\t}\n\t\t\t\telse if (startIndexKind == IndexKind.TheStart && endIndexKind == IndexKind.TheEnd && specialMethods.RangeGetAll != null)\n\t\t\t\t{\n\t\t\t\t\treturn new Call(specialMethods.RangeGetAll);\n\t\t\t\t}\n\t\t\t\telse if (startIndexKind == IndexKind.TheStart && specialMethods.RangeEndAt != null)\n\t\t\t\t{\n\t\t\t\t\tvar rangeCtorCall = new Call(specialMethods.RangeEndAt);\n\t\t\t\t\trangeCtorCall.Arguments.Add(MakeIndex(endIndexKind, endIndexLoad, specialMethods));\n\t\t\t\t\treturn rangeCtorCall;\n\t\t\t\t}\n\t\t\t\telse if (endIndexKind == IndexKind.TheEnd && specialMethods.RangeStartAt != null)\n\t\t\t\t{\n\t\t\t\t\tvar rangeCtorCall = new Call(specialMethods.RangeStartAt);\n\t\t\t\t\trangeCtorCall.Arguments.Add(MakeIndex(startIndexKind, startIndexLoad, specialMethods));\n\t\t\t\t\treturn rangeCtorCall;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar rangeCtorCall = new NewObj(specialMethods.RangeCtor);\n\t\t\t\t\trangeCtorCall.Arguments.Add(MakeIndex(startIndexKind, startIndexLoad, specialMethods));\n\t\t\t\t\trangeCtorCall.Arguments.Add(MakeIndex(endIndexKind, endIndexLoad, specialMethods));\n\t\t\t\t\treturn rangeCtorCall;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid ExtendSlicing()\n\t\t\t{\n\t\t\t\t// We might be dealing with a situation where we executed TransformSlicing() in a previous run of this transform\n\t\t\t\t// that only looked at a part of the instructions making up the slicing pattern.\n\t\t\t\t// The first run would have mis-detected slicing from end as slicing from start.\n\t\t\t\t// This results in code like:\n\t\t\t\t//   int length = span.Length;\n\t\t\t\t//   Console.WriteLine(span[GetIndex(1).GetOffset(length)..GetIndex(2).GetOffset(length)].ToString());\n\t\t\t\t// or:\n\t\t\t\t//   int length = span.Length;\n\t\t\t\t//   Range range = GetRange();\n\t\t\t\t//   Console.WriteLine(span[range.Start.GetOffset(length)..range.End.GetOffset(length)].ToString());\n\t\t\t\tif (containerLengthVar == null)\n\t\t\t\t{\n\t\t\t\t\treturn; // need a container length to extend with\n\t\t\t\t}\n\t\t\t\tDebug.Assert(containerLengthVar.IsSingleDefinition);\n\t\t\t\tDebug.Assert(containerLengthVar.LoadCount == 1 || containerLengthVar.LoadCount == 2);\n\t\t\t\tNewObj rangeCtorCall = null;\n\t\t\t\tforeach (var inst in containerLengthVar.LoadInstructions[0].Ancestors)\n\t\t\t\t{\n\t\t\t\t\tif (inst is NewObj newobj && IndexMethods.IsRangeCtor(newobj.Method))\n\t\t\t\t\t{\n\t\t\t\t\t\trangeCtorCall = newobj;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (inst == block)\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (rangeCtorCall == null)\n\t\t\t\t\treturn;\n\t\t\t\t// Now match the pattern that TransformSlicing() generated in the IndexKind.FromStart case\n\t\t\t\tif (!(rangeCtorCall.Parent is CallInstruction { Method: SyntheticRangeIndexAccessor _ } slicingCall))\n\t\t\t\t\treturn;\n\t\t\t\tif (!MatchContainerVar(slicingCall.Arguments[0], ref containerVar))\n\t\t\t\t\treturn;\n\t\t\t\tif (!slicingCall.IsDescendantOf(block.Instructions[pos]))\n\t\t\t\t\treturn;\n\t\t\t\tDebug.Assert(rangeCtorCall.Arguments.Count == 2);\n\t\t\t\tif (!MatchIndexImplicitConv(rangeCtorCall.Arguments[0], out var startOffsetInst))\n\t\t\t\t\treturn;\n\t\t\t\tif (!MatchIndexImplicitConv(rangeCtorCall.Arguments[1], out var endOffsetInst))\n\t\t\t\t\treturn;\n\t\t\t\tvar startIndexKind = MatchGetOffset(startOffsetInst, out var startIndexLoad, containerLengthVar, ref containerVar);\n\t\t\t\tvar endIndexKind = MatchGetOffset(endOffsetInst, out var endIndexLoad, containerLengthVar, ref containerVar);\n\t\t\t\tif (!CheckContainerLengthVariableUseCount(containerLengthVar, startIndexKind, endIndexKind))\n\t\t\t\t{\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// holds because we've used containerLengthVar at least once\n\t\t\t\tDebug.Assert(startIndexKind != IndexKind.FromStart || endIndexKind != IndexKind.FromStart);\n\t\t\t\tif (rangeVar != null)\n\t\t\t\t{\n\t\t\t\t\tif (!ILInlining.CanMoveInto(rangeVarInit, block.Instructions[pos], startIndexLoad))\n\t\t\t\t\t\treturn;\n\t\t\t\t\tif (!MatchIndexFromRange(startIndexKind, startIndexLoad, rangeVar, \"get_Start\"))\n\t\t\t\t\t\treturn;\n\t\t\t\t\tif (!MatchIndexFromRange(endIndexKind, endIndexLoad, rangeVar, \"get_End\"))\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tvar specialMethods = new IndexMethods(context.TypeSystem);\n\t\t\t\tif (!specialMethods.IsValid)\n\t\t\t\t\treturn;\n\t\t\t\tcontext.Step(\"Merge containerLengthVar into slicing\", slicingCall);\n\t\t\t\trangeCtorCall.ReplaceWith(MakeRange(startIndexKind, startIndexLoad, endIndexKind, endIndexLoad, specialMethods));\n\t\t\t\tfor (int i = startPos; i < pos; i++)\n\t\t\t\t{\n\t\t\t\t\tslicingCall.AddILRange(block.Instructions[i]);\n\t\t\t\t}\n\t\t\t\tblock.Instructions.RemoveRange(startPos, pos - startPos);\n\t\t\t}\n\t\t}\n\n\t\tprivate bool MatchIndexImplicitConv(ILInstruction inst, out ILInstruction offsetInst)\n\t\t{\n\t\t\toffsetInst = null;\n\t\t\tif (!(inst is CallInstruction call))\n\t\t\t\treturn false;\n\t\t\tif (!(call.Method.IsOperator && call.Method.Name == \"op_Implicit\"))\n\t\t\t\treturn false;\n\t\t\tvar op = call.Method;\n\t\t\tif (!(op.Parameters.Count == 1 && op.Parameters[0].Type.IsKnownType(KnownTypeCode.Int32)))\n\t\t\t\treturn false;\n\t\t\tif (!op.DeclaringType.IsKnownType(KnownTypeCode.Index))\n\t\t\t\treturn false;\n\t\t\toffsetInst = call.Arguments.Single();\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic bool IsSlicingMethod(IMethod method)\n\t\t{\n\t\t\tif (method.IsExtensionMethod)\n\t\t\t\treturn false;\n\t\t\tif (method.Parameters.Count != 2)\n\t\t\t\treturn false;\n\t\t\tif (!method.Parameters.All(p => p.Type.IsKnownType(KnownTypeCode.Int32)))\n\t\t\t\treturn false;\n\t\t\treturn method.Name == \"Slice\"\n\t\t\t\t|| (method.Name == \"Substring\" && method.DeclaringType.IsKnownType(KnownTypeCode.String));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Check that the number of uses of the containerLengthVar variable matches those expected in the pattern.\n\t\t/// </summary>\n\t\tprivate bool CheckContainerLengthVariableUseCount(ILVariable containerLengthVar, IndexKind startIndexKind, IndexKind endIndexKind = IndexKind.FromStart)\n\t\t{\n\t\t\tint expectedUses = 0;\n\t\t\tif (startIndexKind != IndexKind.FromStart && startIndexKind != IndexKind.TheStart)\n\t\t\t\texpectedUses += 1;\n\t\t\tif (endIndexKind != IndexKind.FromStart && endIndexKind != IndexKind.TheStart)\n\t\t\t\texpectedUses += 1;\n\t\t\tif (containerLengthVar != null)\n\t\t\t{\n\t\t\t\treturn containerLengthVar.LoadCount == expectedUses;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn expectedUses <= 1; // can have one inline use\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches 'addressof System.Index(call get_Start/get_End(ldloca rangeVar))'\n\t\t/// </summary>\n\t\tstatic bool MatchIndexFromRange(IndexKind indexKind, ILInstruction indexLoad, ILVariable rangeVar, string accessorName)\n\t\t{\n\t\t\tif (indexKind != IndexKind.RefSystemIndex)\n\t\t\t\treturn false;\n\t\t\tif (!(indexLoad is AddressOf addressOf))\n\t\t\t\treturn false;\n\t\t\tif (!addressOf.Type.IsKnownType(KnownTypeCode.Index))\n\t\t\t\treturn false;\n\t\t\tif (!(addressOf.Value is Call call))\n\t\t\t\treturn false;\n\t\t\tif (call.Method.Name != accessorName)\n\t\t\t\treturn false;\n\t\t\tif (!call.Method.DeclaringType.IsKnownType(KnownTypeCode.Range))\n\t\t\t\treturn false;\n\t\t\tif (call.Arguments.Count != 1)\n\t\t\t\treturn false;\n\t\t\treturn call.Arguments[0].MatchLdLoca(rangeVar);\n\t\t}\n\n\t\tstatic ILInstruction MakeIndex(IndexKind indexKind, ILInstruction indexLoad, IndexMethods specialMethods)\n\t\t{\n\t\t\tif (indexKind == IndexKind.RefSystemIndex)\n\t\t\t{\n\t\t\t\t//  stloc containerLengthVar(call get_Length/get_Count(ldloc container))\n\t\t\t\t//  stloc startOffsetVar(call GetOffset(startIndexLoad, ldloc length))\n\t\t\t\t//  complex_expr(call get_Item(ldloc container, ldloc startOffsetVar))\n\t\t\t\t// -->\n\t\t\t\t//  complex_expr(call get_Item(ldloc container, ldobj startIndexLoad))\n\t\t\t\treturn new LdObj(indexLoad, specialMethods.IndexType);\n\t\t\t}\n\t\t\telse if (indexKind == IndexKind.FromEnd || indexKind == IndexKind.TheEnd)\n\t\t\t{\n\t\t\t\t//  stloc offsetVar(binary.sub.i4(call get_Length/get_Count(ldloc container), startIndexLoad))\n\t\t\t\t//  complex_expr(call get_Item(ldloc container, ldloc startOffsetVar))\n\t\t\t\t// -->\n\t\t\t\t//  complex_expr(call get_Item(ldloc container, newobj System.Index(startIndexLoad, fromEnd: true)))\n\t\t\t\treturn new NewObj(specialMethods.IndexCtor) { Arguments = { indexLoad, new LdcI4(1) } };\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDebug.Assert(indexKind == IndexKind.FromStart || indexKind == IndexKind.TheStart);\n\t\t\t\treturn new Call(specialMethods.IndexImplicitConv) { Arguments = { indexLoad } };\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the C# compiler will call `container[int]` when using `container[Index]`.\n\t\t/// </summary>\n\t\tprivate bool CSharpWillGenerateIndexer(IType declaringType, bool slicing)\n\t\t{\n\t\t\tbool foundInt32Overload = false;\n\t\t\tbool foundIndexOverload = false;\n\t\t\tbool foundRangeOverload = false;\n\t\t\tbool foundCountProperty = false;\n\t\t\tforeach (var prop in declaringType.GetProperties(p => p.IsIndexer || (p.Name == \"Length\" || p.Name == \"Count\")))\n\t\t\t{\n\t\t\t\tif (prop.IsIndexer && prop.Parameters.Count == 1)\n\t\t\t\t{\n\t\t\t\t\tvar p = prop.Parameters[0];\n\t\t\t\t\tif (p.Type.IsKnownType(KnownTypeCode.Int32))\n\t\t\t\t\t{\n\t\t\t\t\t\tfoundInt32Overload = true;\n\t\t\t\t\t}\n\t\t\t\t\telse if (p.Type.IsKnownType(KnownTypeCode.Index))\n\t\t\t\t\t{\n\t\t\t\t\t\tfoundIndexOverload = true;\n\t\t\t\t\t}\n\t\t\t\t\telse if (p.Type.IsKnownType(KnownTypeCode.Range))\n\t\t\t\t\t{\n\t\t\t\t\t\tfoundRangeOverload = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (prop.Name == \"Length\" || prop.Name == \"Count\")\n\t\t\t\t{\n\t\t\t\t\tfoundCountProperty = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (slicing)\n\t\t\t{\n\t\t\t\treturn /* foundSlicingMethod && */ foundCountProperty && !foundRangeOverload;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn foundInt32Overload && foundCountProperty && !foundIndexOverload;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches the instruction:\n\t\t///    stloc containerLengthVar(call get_Length/get_Count(ldloc containerVar))\n\t\t/// </summary>\n\t\tstatic bool MatchContainerLengthStore(ILInstruction inst, out ILVariable lengthVar, ref ILVariable containerVar)\n\t\t{\n\t\t\tif (!inst.MatchStLoc(out lengthVar, out var init))\n\t\t\t\treturn false;\n\t\t\tif (!(lengthVar.IsSingleDefinition && lengthVar.StackType == StackType.I4))\n\t\t\t\treturn false;\n\t\t\tif (lengthVar.LoadCount == 0 || lengthVar.LoadCount > 2)\n\t\t\t\treturn false;\n\t\t\treturn MatchContainerLength(init, null, ref containerVar);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// If lengthVar is non-null, matches 'ldloc lengthVar'.\n\t\t/// \n\t\t///\tOtherwise, matches the instruction:\n\t\t///\t\tcall get_Length/get_Count(ldloc containerVar)\n\t\t/// </summary>\n\t\tstatic bool MatchContainerLength(ILInstruction init, ILVariable lengthVar, ref ILVariable containerVar)\n\t\t{\n\t\t\tif (lengthVar != null)\n\t\t\t{\n\t\t\t\tDebug.Assert(containerVar != null);\n\t\t\t\treturn init.MatchLdLoc(lengthVar);\n\t\t\t}\n\t\t\tif (!(init is CallInstruction call))\n\t\t\t\treturn false;\n\t\t\tif (call.ResultType != StackType.I4)\n\t\t\t\treturn false;\n\t\t\tif (!(call.Method.IsAccessor && call.Method.AccessorKind == System.Reflection.MethodSemanticsAttributes.Getter))\n\t\t\t\treturn false;\n\t\t\tif (!(call.Method.AccessorOwner is IProperty lengthProp))\n\t\t\t\treturn false;\n\t\t\tif (lengthProp.Name == \"Length\")\n\t\t\t{\n\t\t\t\t// OK, Length is preferred\n\t\t\t}\n\t\t\telse if (lengthProp.Name == \"Count\")\n\t\t\t{\n\t\t\t\t// Also works, but only if the type doesn't have \"Length\"\n\t\t\t\tif (lengthProp.DeclaringType.GetProperties(p => p.Name == \"Length\").Any())\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!lengthProp.ReturnType.IsKnownType(KnownTypeCode.Int32))\n\t\t\t\treturn false;\n\t\t\tif (lengthProp.IsVirtual && call.OpCode != OpCode.CallVirt)\n\t\t\t\treturn false;\n\t\t\tif (call.Arguments.Count != 1)\n\t\t\t\treturn false;\n\t\t\treturn MatchContainerVar(call.Arguments[0], ref containerVar);\n\t\t}\n\n\t\tstatic bool MatchContainerVar(ILInstruction inst, ref ILVariable containerVar)\n\t\t{\n\t\t\tif (containerVar != null)\n\t\t\t{\n\t\t\t\treturn inst.MatchLdLoc(containerVar) || inst.MatchLdLoca(containerVar);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn inst.MatchLdLoc(out containerVar) || inst.MatchLdLoca(out containerVar);\n\t\t\t}\n\t\t}\n\n\t\tenum IndexKind\n\t\t{\n\t\t\t/// <summary>\n\t\t\t/// indexLoad is an integer, from the start of the container\n\t\t\t/// </summary>\n\t\t\tFromStart,\n\t\t\t/// <summary>\n\t\t\t/// indexLoad is loading the address of a System.Index struct\n\t\t\t/// </summary>\n\t\t\tRefSystemIndex,\n\t\t\t/// <summary>\n\t\t\t/// indexLoad is an integer, from the end of the container\n\t\t\t/// </summary>\n\t\t\tFromEnd,\n\t\t\t/// <summary>\n\t\t\t/// Always equivalent to `0`, used for the start-index when slicing without a startpoint `a[..end]`\n\t\t\t/// </summary>\n\t\t\tTheStart,\n\t\t\t/// <summary>\n\t\t\t/// Always equivalent to `^0`, used for the end-index when slicing without an endpoint `a[start..]`\n\t\t\t/// </summary>\n\t\t\tTheEnd,\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches an instruction computing an offset:\n\t\t///    call System.Index.GetOffset(indexLoad, ldloc containerLengthVar)\n\t\t/// or\n\t\t///    binary.sub.i4(ldloc containerLengthVar, indexLoad)\n\t\t/// \n\t\t/// Anything else not matching these patterns is interpreted as an `int` expression from the start of the container.\n\t\t/// </summary>\n\t\tstatic IndexKind MatchGetOffset(ILInstruction inst, out ILInstruction indexLoad,\n\t\t\tILVariable containerLengthVar, ref ILVariable containerVar)\n\t\t{\n\t\t\tindexLoad = inst;\n\t\t\tif (MatchContainerLength(inst, containerLengthVar, ref containerVar))\n\t\t\t{\n\t\t\t\tindexLoad = new LdcI4(0);\n\t\t\t\treturn IndexKind.TheEnd;\n\t\t\t}\n\t\t\telse if (inst is CallInstruction call)\n\t\t\t{\n\t\t\t\t// call System.Index.GetOffset(indexLoad, ldloc containerLengthVar)\n\t\t\t\tif (call.Method.Name != \"GetOffset\")\n\t\t\t\t\treturn IndexKind.FromStart;\n\t\t\t\tif (!call.Method.DeclaringType.IsKnownType(KnownTypeCode.Index))\n\t\t\t\t\treturn IndexKind.FromStart;\n\t\t\t\tif (call.Arguments.Count != 2)\n\t\t\t\t\treturn IndexKind.FromStart;\n\t\t\t\tif (!MatchContainerLength(call.Arguments[1], containerLengthVar, ref containerVar))\n\t\t\t\t\treturn IndexKind.FromStart;\n\t\t\t\tindexLoad = call.Arguments[0];\n\t\t\t\treturn IndexKind.RefSystemIndex;\n\t\t\t}\n\t\t\telse if (inst is BinaryNumericInstruction bni && bni.Operator == BinaryNumericOperator.Sub)\n\t\t\t{\n\t\t\t\tif (bni.CheckForOverflow || bni.ResultType != StackType.I4 || bni.IsLifted)\n\t\t\t\t\treturn IndexKind.FromStart;\n\t\t\t\t// binary.sub.i4(ldloc containerLengthVar, indexLoad)\n\t\t\t\tif (!MatchContainerLength(bni.Left, containerLengthVar, ref containerVar))\n\t\t\t\t\treturn IndexKind.FromStart;\n\t\t\t\tindexLoad = bni.Right;\n\t\t\t\treturn IndexKind.FromEnd;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn IndexKind.FromStart;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches an instruction computing a slice length:\n\t\t///    binary.sub.i4(call GetOffset(endIndexLoad, ldloc length), ldloc startOffset))\n\t\t/// </summary>\n\t\tstatic bool MatchSliceLength(ILInstruction inst, out IndexKind endIndexKind, out ILInstruction endIndexLoad, ILVariable containerLengthVar, ref ILVariable containerVar, ILVariable startOffsetVar)\n\t\t{\n\t\t\tendIndexKind = default;\n\t\t\tendIndexLoad = default;\n\t\t\tif (inst is BinaryNumericInstruction bni && bni.Operator == BinaryNumericOperator.Sub)\n\t\t\t{\n\t\t\t\tif (bni.CheckForOverflow || bni.ResultType != StackType.I4 || bni.IsLifted)\n\t\t\t\t\treturn false;\n\t\t\t\tif (startOffsetVar == null)\n\t\t\t\t{\n\t\t\t\t\t// When slicing without explicit start point: `a[..endIndex]`\n\t\t\t\t\tif (!bni.Right.MatchLdcI4(0))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (!bni.Right.MatchLdLoc(startOffsetVar))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tendIndexKind = MatchGetOffset(bni.Left, out endIndexLoad, containerLengthVar, ref containerVar);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (startOffsetVar == null)\n\t\t\t{\n\t\t\t\t// When slicing without explicit start point: `a[..endIndex]`, the compiler doesn't always emit the \"- 0\".\n\t\t\t\tendIndexKind = MatchGetOffset(inst, out endIndexLoad, containerLengthVar, ref containerVar);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/InlineArrayTransform.cs",
    "content": "// Copyright (c) 2025 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Diagnostics.CodeAnalysis;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\tstatic class InlineArrayTransform\n\t{\n\t\tinternal static bool RunOnExpression(Call inst, StatementTransformContext context)\n\t\t{\n\t\t\tif (MatchSpanIndexerWithInlineArrayAsSpan(inst, out var type, out var addr, out var index, out bool isReadOnly))\n\t\t\t{\n\t\t\t\tif (isReadOnly)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"call get_Item(addressof System.ReadOnlySpan{T}(call InlineArrayAsReadOnlySpan(addr)), index) -> readonly.ldelema.inlinearray(addr, index)\", inst);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"call get_Item(addressof System.Span{T}(call InlineArrayAsSpan(addr)), index) -> ldelema.inlinearray(addr, index)\", inst);\n\t\t\t\t}\n\t\t\t\tinst.ReplaceWith(new LdElemaInlineArray(type, addr, index) { IsReadOnly = isReadOnly }.WithILRange(inst));\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (MatchInlineArrayElementRef(inst, out type, out addr, out index, out isReadOnly))\n\t\t\t{\n\t\t\t\tif (isReadOnly)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"call InlineArrayElementRefReadOnly(addr, index) -> readonly.ldelema.inlinearray(addr, index)\", inst);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"call InlineArrayElementRef(addr, index) -> ldelema.inlinearray(addr, index)\", inst);\n\t\t\t\t}\n\t\t\t\tinst.ReplaceWith(new LdElemaInlineArray(type, addr, index) { IsReadOnly = isReadOnly }.WithILRange(inst));\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (MatchInlineArrayFirstElementRef(inst, out type, out addr, out isReadOnly))\n\t\t\t{\n\t\t\t\tif (isReadOnly)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"call InlineArrayFirstElementRefReadOnly(addr) -> readonly.ldelema.inlinearray(addr, ldc.i4 0)\", inst);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"call InlineArrayFirstElementRef(addr) -> ldelema.inlinearray(addr, ldc.i4 0)\", inst);\n\t\t\t\t}\n\t\t\t\tinst.ReplaceWith(new LdElemaInlineArray(type, addr, new LdcI4(0)) { IsReadOnly = isReadOnly }.WithILRange(inst));\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches call get_Item(addressof System.(ReadOnly)Span[[T]](call InlineArrayAs(ReadOnly)Span(addr, length)), index)\n\t\t/// </summary>\n\t\tstatic bool MatchSpanIndexerWithInlineArrayAsSpan(Call inst, [NotNullWhen(true)] out IType? type, [NotNullWhen(true)] out ILInstruction? addr, [NotNullWhen(true)] out ILInstruction? index, out bool isReadOnly)\n\t\t{\n\t\t\tisReadOnly = false;\n\t\t\ttype = null;\n\t\t\taddr = null;\n\t\t\tindex = null;\n\n\t\t\tif (MatchSpanGetItem(inst.Method, \"ReadOnlySpan\"))\n\t\t\t{\n\t\t\t\tisReadOnly = true;\n\n\t\t\t\tif (inst.Arguments is not [AddressOf { Value: Call targetInst, Type: var typeInfo }, var indexInst])\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (!MatchInlineArrayHelper(targetInst.Method, \"InlineArrayAsReadOnlySpan\", out var inlineArrayType))\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (targetInst.Arguments is not [var addrInst, LdcI4 { Value: var length }])\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (length < 0 || length > inlineArrayType.GetInlineArrayLength())\n\t\t\t\t\treturn false;\n\n\t\t\t\ttype = inlineArrayType;\n\t\t\t\taddr = addrInst;\n\t\t\t\tindex = indexInst;\n\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (MatchSpanGetItem(inst.Method, \"Span\"))\n\t\t\t{\n\t\t\t\tif (inst.Arguments is not [AddressOf { Value: Call targetInst, Type: var typeInfo }, var indexInst])\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (!MatchInlineArrayHelper(targetInst.Method, \"InlineArrayAsSpan\", out var inlineArrayType))\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (targetInst.Arguments is not [var addrInst, LdcI4 { Value: var length }])\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (length < 0 || length > inlineArrayType.GetInlineArrayLength())\n\t\t\t\t\treturn false;\n\n\t\t\t\ttype = inlineArrayType;\n\t\t\t\taddr = addrInst;\n\t\t\t\tindex = indexInst;\n\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches call InlineArrayElementRef(ReadOnly)(addr, index)\n\t\t/// </summary>\n\t\tstatic bool MatchInlineArrayElementRef(Call inst, [NotNullWhen(true)] out IType? type, [NotNullWhen(true)] out ILInstruction? addr, [NotNullWhen(true)] out ILInstruction? index, out bool isReadOnly)\n\t\t{\n\t\t\ttype = null;\n\t\t\taddr = null;\n\t\t\tindex = null;\n\t\t\tisReadOnly = false;\n\n\t\t\tif (inst.Arguments is not [var addrInst, LdcI4 { Value: var indexValue } indexInst])\n\t\t\t\treturn false;\n\n\t\t\taddr = addrInst;\n\t\t\tindex = indexInst;\n\n\t\t\tif (MatchInlineArrayHelper(inst.Method, \"InlineArrayElementRef\", out var inlineArrayType))\n\t\t\t{\n\t\t\t\tisReadOnly = false;\n\t\t\t\ttype = inlineArrayType;\n\t\t\t}\n\t\t\telse if (MatchInlineArrayHelper(inst.Method, \"InlineArrayElementRefReadOnly\", out inlineArrayType))\n\t\t\t{\n\t\t\t\tisReadOnly = true;\n\t\t\t\ttype = inlineArrayType;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (indexValue < 0 || indexValue >= inlineArrayType.GetInlineArrayLength())\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tprivate static bool MatchInlineArrayFirstElementRef(Call inst, [NotNullWhen(true)] out IType? type, [NotNullWhen(true)] out ILInstruction? addr, out bool isReadOnly)\n\t\t{\n\t\t\ttype = null;\n\t\t\taddr = null;\n\t\t\tisReadOnly = false;\n\n\t\t\tif (inst.Arguments is not [var addrInst])\n\t\t\t\treturn false;\n\n\t\t\tif (MatchInlineArrayHelper(inst.Method, \"InlineArrayFirstElementRef\", out var inlineArrayType))\n\t\t\t{\n\t\t\t\tisReadOnly = false;\n\t\t\t\ttype = inlineArrayType;\n\t\t\t\taddr = addrInst;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (MatchInlineArrayHelper(inst.Method, \"InlineArrayFirstElementRefReadOnly\", out inlineArrayType))\n\t\t\t{\n\t\t\t\tisReadOnly = true;\n\t\t\t\ttype = inlineArrayType;\n\t\t\t\taddr = addrInst;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tstatic bool MatchSpanGetItem(IMethod method, string typeName)\n\t\t{\n\t\t\treturn method is {\n\t\t\t\tIsStatic: false,\n\t\t\t\tName: \"get_Item\",\n\t\t\t\tDeclaringType: { Namespace: \"System\", Name: string name, TypeParameterCount: 1, DeclaringType: null }\n\t\t\t} && typeName == name;\n\t\t}\n\n\t\tstatic bool MatchInlineArrayHelper(IMethod method, string methodName, [NotNullWhen(true)] out IType? inlineArrayType)\n\t\t{\n\t\t\tinlineArrayType = null;\n\t\t\tif (method is not {\n\t\t\t\tIsStatic: true, Name: var name,\n\t\t\t\tDeclaringType: { FullName: \"<PrivateImplementationDetails>\", TypeParameterCount: 0 },\n\t\t\t\tTypeArguments: [var bufferType, _],\n\t\t\t\tParameters: var parameters\n\t\t\t})\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (methodName != name)\n\t\t\t\treturn false;\n\n\t\t\tif (methodName.Contains(\"FirstElement\"))\n\t\t\t{\n\t\t\t\tif (parameters is not [{ Type: ByReferenceType { ElementType: var type } }])\n\t\t\t\t\treturn false;\n\t\t\t\tif (!type.Equals(bufferType))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (parameters is not [{ Type: ByReferenceType { ElementType: var type } }, { Type: var lengthOrIndexParameterType }])\n\t\t\t\t\treturn false;\n\t\t\t\tif (!type.Equals(bufferType) || !lengthOrIndexParameterType.IsKnownType(KnownTypeCode.Int32))\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tinlineArrayType = bufferType;\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/InlineReturnTransform.cs",
    "content": "// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// This transform duplicates return blocks if they return a local variable that was assigned right before the return.\n\t/// </summary>\n\tclass InlineReturnTransform : IILTransform\n\t{\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tvar instructionsToModify = new List<(BlockContainer, Block, Branch)>();\n\n\t\t\t// Process all leave instructions in a leave-block, that is a block consisting solely of a leave instruction.\n\t\t\tforeach (var leave in function.Descendants.OfType<Leave>())\n\t\t\t{\n\t\t\t\tif (!(leave.Parent is Block leaveBlock && leaveBlock.Instructions.Count == 1))\n\t\t\t\t\tcontinue;\n\t\t\t\t// Skip, if the leave instruction has no value or the value is not a load of a local variable.\n\t\t\t\tif (!leave.Value.MatchLdLoc(out var returnVar) || returnVar.Kind != VariableKind.Local)\n\t\t\t\t\tcontinue;\n\t\t\t\t// If all instructions can be modified, add item to the global list.\n\t\t\t\tif (CanModifyInstructions(returnVar, leaveBlock, out var list))\n\t\t\t\t\tinstructionsToModify.AddRange(list);\n\t\t\t}\n\n\t\t\tforeach (var (container, b, br) in instructionsToModify)\n\t\t\t{\n\t\t\t\tBlock block = b;\n\t\t\t\t// if there is only one branch to this return block, move it to the matching container.\n\t\t\t\t// otherwise duplicate the return block.\n\t\t\t\tif (block.IncomingEdgeCount == 1)\n\t\t\t\t{\n\t\t\t\t\tblock.Remove();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tblock = (Block)block.Clone();\n\t\t\t\t}\n\t\t\t\tcontainer.Blocks.Add(block);\n\t\t\t\t// adjust the target of the branch to the newly created block.\n\t\t\t\tbr.TargetBlock = block;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Determines a list of all store instructions that write to a given <paramref name=\"returnVar\"/>.\n\t\t/// Returns false if any of these instructions does not meet the following criteria:\n\t\t/// - must be a stloc\n\t\t/// - must be a direct child of a block\n\t\t/// - must be the penultimate instruction\n\t\t/// - must be followed by a branch instruction to <paramref name=\"leaveBlock\"/>\n\t\t/// - must have a BlockContainer as ancestor.\n\t\t/// Returns true, if all instructions meet these criteria, and <paramref name=\"instructionsToModify\"/> contains a list of 3-tuples.\n\t\t/// Each tuple consists of the target block container, the leave block, and the branch instruction that should be modified.\n\t\t/// </summary>\n\t\tstatic bool CanModifyInstructions(ILVariable returnVar, Block leaveBlock, out List<(BlockContainer, Block, Branch)> instructionsToModify)\n\t\t{\n\t\t\tinstructionsToModify = new List<(BlockContainer, Block, Branch)>();\n\t\t\tforeach (var inst in returnVar.StoreInstructions)\n\t\t\t{\n\t\t\t\tif (!(inst is StLoc store))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(store.Parent is Block storeBlock))\n\t\t\t\t\treturn false;\n\t\t\t\tif (store.ChildIndex + 2 != storeBlock.Instructions.Count)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(storeBlock.Instructions[store.ChildIndex + 1] is Branch br))\n\t\t\t\t\treturn false;\n\t\t\t\tif (br.TargetBlock != leaveBlock)\n\t\t\t\t\treturn false;\n\t\t\t\tvar targetBlockContainer = BlockContainer.FindClosestContainer(store);\n\t\t\t\tif (targetBlockContainer == null)\n\t\t\t\t\treturn false;\n\t\t\t\tinstructionsToModify.Add((targetBlockContainer, leaveBlock, br));\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/InterpolatedStringTransform.cs",
    "content": "// Copyright (c) 2021 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\tpublic class InterpolatedStringTransform : IStatementTransform\n\t{\n\t\tvoid IStatementTransform.Run(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.StringInterpolation)\n\t\t\t\treturn;\n\t\t\tint interpolationStart = pos;\n\t\t\tint interpolationEnd;\n\t\t\tILInstruction insertionPoint;\n\t\t\t// stloc v(newobj DefaultInterpolatedStringHandler..ctor(ldc.i4 literalLength, ldc.i4 formattedCount))\n\t\t\tif (block.Instructions[pos] is StLoc {\n\t\t\t\tVariable: ILVariable { Kind: VariableKind.Local } v,\n\t\t\t\tValue: NewObj { Arguments: { Count: 2 } } newObj\n\t\t\t} stloc\n\t\t\t\t&& v.Type.IsKnownType(KnownTypeCode.DefaultInterpolatedStringHandler)\n\t\t\t\t&& newObj.Method.DeclaringType.IsKnownType(KnownTypeCode.DefaultInterpolatedStringHandler)\n\t\t\t\t&& newObj.Arguments[0].MatchLdcI4(out _)\n\t\t\t\t&& newObj.Arguments[1].MatchLdcI4(out _))\n\t\t\t{\n\t\t\t\t// { call MethodName(ldloca v, ...) }\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t\twhile (IsKnownCall(block, pos, v));\n\t\t\t\tinterpolationEnd = pos;\n\t\t\t\t// ... call ToStringAndClear(ldloca v) ...\n\t\t\t\tif (!FindToStringAndClear(block, pos, interpolationStart, interpolationEnd, v, out insertionPoint))\n\t\t\t\t{\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!(v.StoreCount == 1 && v.AddressCount == interpolationEnd - interpolationStart && v.LoadCount == 0))\n\t\t\t\t{\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcontext.Step($\"Transform DefaultInterpolatedStringHandler {v.Name}\", stloc);\n\t\t\tv.Kind = VariableKind.InitializerTarget;\n\t\t\tvar replacement = new Block(BlockKind.InterpolatedString);\n\t\t\tfor (int i = interpolationStart; i < interpolationEnd; i++)\n\t\t\t{\n\t\t\t\treplacement.Instructions.Add(block.Instructions[i]);\n\t\t\t}\n\t\t\tvar callToStringAndClear = insertionPoint;\n\t\t\tinsertionPoint.ReplaceWith(replacement);\n\t\t\treplacement.FinalInstruction = callToStringAndClear;\n\t\t\tblock.Instructions.RemoveRange(interpolationStart, interpolationEnd - interpolationStart);\n\t\t}\n\n\t\tprivate bool IsKnownCall(Block block, int pos, ILVariable v)\n\t\t{\n\t\t\tif (pos >= block.Instructions.Count - 1)\n\t\t\t\treturn false;\n\t\t\tif (!(block.Instructions[pos] is Call call))\n\t\t\t\treturn false;\n\t\t\tif (!(call.Arguments.Count > 1))\n\t\t\t\treturn false;\n\t\t\tif (!call.Arguments[0].MatchLdLoca(v))\n\t\t\t\treturn false;\n\t\t\tif (call.Method.IsStatic)\n\t\t\t\treturn false;\n\t\t\tif (!call.Method.DeclaringType.IsKnownType(KnownTypeCode.DefaultInterpolatedStringHandler))\n\t\t\t\treturn false;\n\t\t\tswitch (call.Method.Name)\n\t\t\t{\n\t\t\t\tcase \"AppendLiteral\" when call.Arguments.Count == 2 && call.Arguments[1] is LdStr:\n\t\t\t\tcase \"AppendFormatted\" when call.Arguments.Count == 2:\n\t\t\t\tcase \"AppendFormatted\" when call.Arguments.Count == 3 && call.Arguments[2] is LdStr:\n\t\t\t\tcase \"AppendFormatted\" when call.Arguments.Count == 3 && call.Arguments[2] is LdcI4:\n\t\t\t\tcase \"AppendFormatted\" when call.Arguments.Count == 4 && call.Arguments[2] is LdcI4 && call.Arguments[3] is LdStr:\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tprivate bool FindToStringAndClear(Block block, int pos, int interpolationStart, int interpolationEnd, ILVariable v, out ILInstruction insertionPoint)\n\t\t{\n\t\t\tinsertionPoint = null;\n\t\t\tif (pos >= block.Instructions.Count)\n\t\t\t\treturn false;\n\t\t\t// find\n\t\t\t// ... call ToStringAndClear(ldloca v) ...\n\t\t\t// in block.Instructions[pos]\n\t\t\tfor (int i = interpolationStart; i < interpolationEnd; i++)\n\t\t\t{\n\t\t\t\tvar result = ILInlining.FindLoadInNext(block.Instructions[pos], v, block.Instructions[i], InliningOptions.None);\n\t\t\t\tif (result.Type != ILInlining.FindResultType.Found)\n\t\t\t\t\treturn false;\n\t\t\t\tinsertionPoint ??= result.LoadInst.Parent;\n\t\t\t\tDebug.Assert(insertionPoint == result.LoadInst.Parent);\n\t\t\t}\n\n\t\t\treturn insertionPoint is Call {\n\t\t\t\tArguments: { Count: 1 },\n\t\t\t\tMethod: { Name: \"ToStringAndClear\", IsStatic: false }\n\t\t\t};\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/IntroduceDynamicTypeOnLocals.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpublic class IntroduceDynamicTypeOnLocals : IILTransform\n\t{\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tforeach (var nestedFunction in function.Descendants.OfType<ILFunction>())\n\t\t\t{\n\t\t\t\tHashSet<int> dynamicVariables = new();\n\t\t\t\tforeach (var variable in nestedFunction.Variables)\n\t\t\t\t{\n\t\t\t\t\tif (variable.Kind != VariableKind.Local &&\n\t\t\t\t\t\tvariable.Kind != VariableKind.StackSlot &&\n\t\t\t\t\t\tvariable.Kind != VariableKind.ForeachLocal &&\n\t\t\t\t\t\tvariable.Kind != VariableKind.UsingLocal)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (!variable.Type.IsKnownType(KnownTypeCode.Object) || variable.LoadCount == 0)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tforeach (var load in variable.LoadInstructions)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (load.Parent is DynamicInstruction dynamicInstruction)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar argumentInfo = dynamicInstruction.GetArgumentInfoOfChild(load.ChildIndex);\n\t\t\t\t\t\t\tif (!argumentInfo.HasFlag(CSharpArgumentInfoFlags.UseCompileTimeType))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvariable.Type = SpecialType.Dynamic;\n\t\t\t\t\t\t\t\tif (variable.Index.HasValue && variable.Kind == VariableKind.Local)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tdynamicVariables.Add(variable.Index.Value);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tforeach (var variable in nestedFunction.Variables)\n\t\t\t\t{\n\t\t\t\t\tif (variable.Index.HasValue && variable.Kind == VariableKind.Local\n\t\t\t\t\t\t&& dynamicVariables.Contains(variable.Index.Value))\n\t\t\t\t\t{\n\t\t\t\t\t\tvariable.Type = SpecialType.Dynamic;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/IntroduceNativeIntTypeOnLocals.cs",
    "content": "// Copyright (c) 2020 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tclass IntroduceNativeIntTypeOnLocals : IILTransform\n\t{\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.NativeIntegers)\n\t\t\t\treturn;\n\t\t\tforeach (var nestedFunction in function.Descendants.OfType<ILFunction>())\n\t\t\t{\n\t\t\t\tDictionary<int, IType> variableTypeMapping = new();\n\t\t\t\tforeach (var variable in nestedFunction.Variables)\n\t\t\t\t{\n\t\t\t\t\tif (variable.Kind != VariableKind.Local &&\n\t\t\t\t\t\tvariable.Kind != VariableKind.StackSlot &&\n\t\t\t\t\t\tvariable.Kind != VariableKind.PatternLocal &&\n\t\t\t\t\t\tvariable.Kind != VariableKind.ForeachLocal &&\n\t\t\t\t\t\tvariable.Kind != VariableKind.UsingLocal)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (!(variable.Type.IsKnownType(KnownTypeCode.IntPtr) || variable.Type.IsKnownType(KnownTypeCode.UIntPtr)))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tbool isUsedAsNativeInt = variable.LoadInstructions.Any(IsUsedAsNativeInt);\n\t\t\t\t\tbool isAssignedNativeInt = variable.StoreInstructions.Any(store => IsNativeIntStore(store, context.TypeSystem));\n\t\t\t\t\tif (isUsedAsNativeInt || isAssignedNativeInt)\n\t\t\t\t\t{\n\t\t\t\t\t\tvariable.Type = variable.Type.GetSign() == Sign.Unsigned ? SpecialType.NUInt : SpecialType.NInt;\n\t\t\t\t\t\tif (variable.Kind == VariableKind.Local && variable.Index.HasValue)\n\t\t\t\t\t\t\tvariableTypeMapping[variable.Index.Value] = variable.Type;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tforeach (var variable in nestedFunction.Variables)\n\t\t\t\t{\n\t\t\t\t\tif (variable.Kind == VariableKind.Local && variable.Index.HasValue\n\t\t\t\t\t\t&& variableTypeMapping.TryGetValue(variable.Index.Value, out var type))\n\t\t\t\t\t{\n\t\t\t\t\t\tvariable.Type = type;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic bool IsUsedAsNativeInt(LdLoc load)\n\t\t{\n\t\t\treturn load.Parent switch {\n\t\t\t\tBinaryNumericInstruction { UnderlyingResultType: StackType.I } => true,\n\t\t\t\tBitNot { UnderlyingResultType: StackType.I } => true,\n\t\t\t\tCallInstruction call => call.GetParameter(load.ChildIndex)?.Type.IsCSharpNativeIntegerType() ?? false,\n\t\t\t\t_ => false,\n\t\t\t};\n\t\t}\n\n\t\tstatic bool IsNativeIntStore(IStoreInstruction store, ICompilation compilation)\n\t\t{\n\t\t\tif (store is StLoc stloc)\n\t\t\t{\n\t\t\t\tswitch (stloc.Value)\n\t\t\t\t{\n\t\t\t\t\tcase BinaryNumericInstruction { UnderlyingResultType: StackType.I }:\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tcase Conv { ResultType: StackType.I }:\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tvar inferredType = stloc.Value.InferType(compilation);\n\t\t\t\t\t\treturn inferredType.IsCSharpNativeIntegerType();\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/IntroduceRefReadOnlyModifierOnLocals.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tpublic class IntroduceRefReadOnlyModifierOnLocals : IILTransform\n\t{\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tforeach (var variable in function.Variables)\n\t\t\t{\n\t\t\t\tif (variable.Type.Kind != TypeKind.ByReference || variable.Kind == VariableKind.Parameter)\n\t\t\t\t\tcontinue;\n\t\t\t\t// ref readonly\n\t\t\t\tif (IsUsedAsRefReadonly(variable))\n\t\t\t\t{\n\t\t\t\t\tvariable.IsRefReadOnly = true;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Infer ref readonly type from usage:\n\t\t/// An ILVariable should be marked as readonly,\n\t\t/// if it's a \"by-ref-like\" type and the initialized value is known to be readonly.\n\t\t/// </summary>\n\t\tbool IsUsedAsRefReadonly(ILVariable variable)\n\t\t{\n\t\t\tforeach (var store in variable.StoreInstructions.OfType<StLoc>())\n\t\t\t{\n\t\t\t\t// Check if C# requires that the local is ref-readonly in order to allow the store:\n\t\t\t\tif (ILInlining.IsReadonlyReference(store.Value))\n\t\t\t\t\treturn true;\n\t\t\t\t// Check whether the local needs to be ref-readonly to avoid changing the semantics of\n\t\t\t\t// a readonly.ldelema:\n\t\t\t\tILInstruction val = store.Value;\n\t\t\t\twhile (val is LdFlda ldflda)\n\t\t\t\t{\n\t\t\t\t\tval = ldflda.Target;\n\t\t\t\t}\n\t\t\t\tif (val is LdElema { IsReadOnly: true })\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/LdLocaDupInitObjTransform.cs",
    "content": "// Copyright (c) 2021 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t// stloc s(ldloca v)\n\t// stobj System.DateTime(ldloc s, default.value T)\n\t// where s.LoadCount > 1\n\t// which is: ldloca; dup; initobj in IL (generated by Roslyn >= 2)\n\t// =>\n\t// stloc v(default.value T)\n\t// stloc s(ldloca v)\n\t// which is: ldloca; ldloca; initobj in IL (generated by legacy csc)\n\t// \n\t// The second pattern allows inlining in the subsequent uses.\n\tclass LdLocaDupInitObjTransform : IILTransform\n\t{\n\t\tvoid IILTransform.Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tforeach (var block in function.Descendants.OfType<Block>())\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < block.Instructions.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tTryTransform(block, i, context);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate bool TryTransform(Block block, int i, ILTransformContext context)\n\t\t{\n\t\t\tif (block.Instructions[i] is not StLoc { Variable: var s, Value: LdLoca { Variable: var v } } inst1)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (block.Instructions.ElementAtOrDefault(i + 1) is not StObj inst2)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!(inst2.Target.MatchLdLoc(s)\n\t\t\t\t&& TypeUtils.IsCompatibleTypeForMemoryAccess(v.Type, inst2.Type)\n\t\t\t\t&& inst2.UnalignedPrefix == 0\n\t\t\t\t&& !inst2.IsVolatile\n\t\t\t\t&& inst2.Value is DefaultValue))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tcontext.Step(\"LdLocaDupInitObjTransform\", inst1);\n\t\t\tblock.Instructions[i] = new StLoc(v, inst2.Value).WithILRange(inst2);\n\t\t\tblock.Instructions[i + 1] = inst1;\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/LocalFunctionDecompiler.cs",
    "content": "// Copyright (c) 2019 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Text.RegularExpressions;\n\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Decompiler step for C# 7.0 local functions\n\t/// </summary>\n\tpublic class LocalFunctionDecompiler : IILTransform\n\t{\n\t\tILTransformContext context;\n\t\tITypeResolveContext resolveContext;\n\n\t\tstruct LocalFunctionInfo\n\t\t{\n\t\t\tpublic List<ILInstruction> UseSites;\n\t\t\tpublic IMethod Method;\n\t\t\tpublic ILFunction Definition;\n\t\t\t/// <summary>\n\t\t\t/// Used to store all synthesized call-site arguments grouped by the parameter index.\n\t\t\t/// We use a dictionary instead of a simple array, because -1 is used for the this parameter\n\t\t\t/// and there might be many non-synthesized arguments in between.\n\t\t\t/// </summary>\n\t\t\tpublic Dictionary<int, List<ILInstruction>> LocalFunctionArguments;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// The transform works like this:\n\t\t/// \n\t\t/// <para>\n\t\t/// local functions can either be used in method calls, i.e., call and callvirt instructions,\n\t\t/// or can be used as part of the \"delegate construction\" pattern, i.e.,\n\t\t/// <c>newobj Delegate(&lt;target-expression&gt;, ldftn &lt;method&gt;)</c>.\n\t\t/// </para>\n\t\t/// As local functions can be declared practically anywhere, we have to take a look at\n\t\t/// all use-sites and infer the declaration location from that. Use-sites can be call,\n\t\t/// callvirt and ldftn instructions.\n\t\t/// After all use-sites are collected we construct the ILAst of the local function\n\t\t/// and add it to the parent function.\n\t\t/// Then all use-sites of the local-function are transformed to a call to the \n\t\t/// <c>LocalFunctionMethod</c> or a ldftn of the <c>LocalFunctionMethod</c>.\n\t\t/// In a next step we handle all nested local functions.\n\t\t/// After all local functions are transformed, we move all local functions that capture\n\t\t/// any variables to their respective declaration scope.\n\t\t/// </summary>\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.LocalFunctions)\n\t\t\t\treturn;\n\t\t\t// Disable the transform if we are decompiling a display-class or local function method:\n\t\t\t// This happens if a local function or display class is selected in the ILSpy tree view.\n\t\t\tif (IsLocalFunctionMethod(function.Method, context) || IsLocalFunctionDisplayClass(\n\t\t\t\t\tfunction.Method.ParentModule.MetadataFile,\n\t\t\t\t\t(TypeDefinitionHandle)function.Method.DeclaringTypeDefinition.MetadataToken,\n\t\t\t\t\tcontext)\n\t\t\t\t)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.context = context;\n\t\t\tthis.resolveContext = new SimpleTypeResolveContext(function.Method);\n\t\t\tvar localFunctions = new Dictionary<MethodDefinitionHandle, LocalFunctionInfo>();\n\t\t\t// Find all local functions declared inside this method, including nested local functions or local functions declared in lambdas.\n\t\t\tFindUseSites(function, context, localFunctions);\n\t\t\tReplaceReferencesToDisplayClassThis(localFunctions.Values);\n\t\t\tDetermineCaptureAndDeclarationScopes(localFunctions.Values);\n\t\t\tPropagateClosureParameterArguments(localFunctions);\n\t\t\tTransformUseSites(localFunctions.Values);\n\t\t}\n\n\t\tprivate void ReplaceReferencesToDisplayClassThis(Dictionary<MethodDefinitionHandle, LocalFunctionInfo>.ValueCollection localFunctions)\n\t\t{\n\t\t\tforeach (var info in localFunctions)\n\t\t\t{\n\t\t\t\tvar localFunction = info.Definition;\n\t\t\t\tif (localFunction.Method.IsStatic)\n\t\t\t\t\tcontinue;\n\t\t\t\tvar thisVar = localFunction.Variables.SingleOrDefault(VariableKindExtensions.IsThis);\n\t\t\t\tif (thisVar == null)\n\t\t\t\t\tcontinue;\n\t\t\t\tvar compatibleArgument = FindCompatibleArgument(\n\t\t\t\t\tinfo,\n\t\t\t\t\tinfo.UseSites.OfType<CallInstruction>().Select(u => u.Arguments[0]).ToArray(),\n\t\t\t\t\tignoreStructure: true\n\t\t\t\t);\n\t\t\t\tif (compatibleArgument == null)\n\t\t\t\t\tcontinue;\n\t\t\t\tcontext.Step($\"Replace 'this' with {compatibleArgument}\", localFunction);\n\t\t\t\tlocalFunction.AcceptVisitor(new DelegateConstruction.ReplaceDelegateTargetVisitor(compatibleArgument, thisVar));\n\t\t\t\tDetermineCaptureAndDeclarationScope(info, -1, compatibleArgument);\n\t\t\t}\n\t\t}\n\n\t\tprivate void DetermineCaptureAndDeclarationScopes(Dictionary<MethodDefinitionHandle, LocalFunctionInfo>.ValueCollection localFunctions)\n\t\t{\n\t\t\tforeach (var info in localFunctions)\n\t\t\t{\n\t\t\t\tcontext.CancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tif (info.Definition == null)\n\t\t\t\t{\n\t\t\t\t\tcontext.Function.Warnings.Add($\"Could not decode local function '{info.Method}'\");\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tcontext.StepStartGroup($\"Determine and move to declaration scope of \" + info.Definition.Name, info.Definition);\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tvar localFunction = info.Definition;\n\n\t\t\t\t\tforeach (var useSite in info.UseSites)\n\t\t\t\t\t{\n\t\t\t\t\t\tDetermineCaptureAndDeclarationScope(info, useSite);\n\n\t\t\t\t\t\tif (context.Function.Method.IsConstructor)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (localFunction.DeclarationScope == null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlocalFunction.DeclarationScope = BlockContainer.FindClosestContainer(useSite);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlocalFunction.DeclarationScope = FindCommonAncestorInstruction<BlockContainer>(useSite, localFunction.DeclarationScope);\n\t\t\t\t\t\t\t\tif (localFunction.DeclarationScope == null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlocalFunction.DeclarationScope = (BlockContainer)context.Function.Body;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (localFunction.DeclarationScope == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tlocalFunction.DeclarationScope = (BlockContainer)context.Function.Body;\n\t\t\t\t\t}\n\n\t\t\t\t\tILFunction declaringFunction = GetDeclaringFunction(localFunction);\n\t\t\t\t\tif (declaringFunction != context.Function)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontext.Step($\"Move {localFunction.Name} from {context.Function.Name} to {declaringFunction.Name}\", localFunction);\n\t\t\t\t\t\tcontext.Function.LocalFunctions.Remove(localFunction);\n\t\t\t\t\t\tdeclaringFunction.LocalFunctions.Add(localFunction);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (TryValidateSkipCount(info, out int skipCount) && skipCount != localFunction.ReducedMethod.NumberOfCompilerGeneratedTypeParameters)\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(false);\n\t\t\t\t\t\tcontext.Function.Warnings.Add($\"Could not decode local function '{info.Method}'\");\n\t\t\t\t\t\tif (declaringFunction != context.Function)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdeclaringFunction.LocalFunctions.Remove(localFunction);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tcontext.StepEndGroup(keepIfEmpty: true);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate void TransformUseSites(Dictionary<MethodDefinitionHandle, LocalFunctionInfo>.ValueCollection localFunctions)\n\t\t{\n\t\t\tforeach (var info in localFunctions)\n\t\t\t{\n\t\t\t\tcontext.CancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tif (info.Definition == null)\n\t\t\t\t\tcontinue;\n\t\t\t\tcontext.StepStartGroup($\"TransformUseSites of \" + info.Definition.Name, info.Definition);\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tforeach (var useSite in info.UseSites)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontext.Step($\"Transform use-site at IL_{useSite.StartILOffset:x4}\", useSite);\n\t\t\t\t\t\tswitch (useSite)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase NewObj newObj:\n\t\t\t\t\t\t\t\tTransformToLocalFunctionReference(info.Definition, newObj);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase CallInstruction call:\n\t\t\t\t\t\t\t\tTransformToLocalFunctionInvocation(info.Definition.ReducedMethod, call);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase LdFtn fnptr:\n\t\t\t\t\t\t\t\tvar specializeMethod = info.Definition.ReducedMethod\n\t\t\t\t\t\t\t\t\t.Specialize(fnptr.Method.Substitution);\n\t\t\t\t\t\t\t\tvar replacement = new LdFtn(specializeMethod).WithILRange(fnptr);\n\t\t\t\t\t\t\t\tfnptr.ReplaceWith(replacement);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tthrow new NotSupportedException();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tcontext.StepEndGroup();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate void PropagateClosureParameterArguments(Dictionary<MethodDefinitionHandle, LocalFunctionInfo> localFunctions)\n\t\t{\n\t\t\tforeach (var localFunction in context.Function.Descendants.OfType<ILFunction>())\n\t\t\t{\n\t\t\t\tif (localFunction.Kind != ILFunctionKind.LocalFunction)\n\t\t\t\t\tcontinue;\n\t\t\t\tcontext.CancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tvar token = (MethodDefinitionHandle)localFunction.Method.MetadataToken;\n\t\t\t\tvar info = localFunctions[token];\n\n\t\t\t\tforeach (var useSite in info.UseSites)\n\t\t\t\t{\n\t\t\t\t\tswitch (useSite)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase NewObj newObj:\n\t\t\t\t\t\t\tAddAsArgument(-1, newObj.Arguments[0]);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase CallInstruction call:\n\t\t\t\t\t\t\tint firstArgumentIndex;\n\t\t\t\t\t\t\tif (info.Method.IsStatic)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfirstArgumentIndex = 0;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfirstArgumentIndex = 1;\n\t\t\t\t\t\t\t\tAddAsArgument(-1, call.Arguments[0]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfor (int i = call.Arguments.Count - 1; i >= firstArgumentIndex; i--)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tAddAsArgument(i - firstArgumentIndex, call.Arguments[i]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase LdFtn _:\n\t\t\t\t\t\t\t// &LocalFunction is only possible, if the local function is declared static,\n\t\t\t\t\t\t\t// this means that the local function can be declared in the top-level scope.\n\t\t\t\t\t\t\t// Thus, there are no closure parameters that need propagation.\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow new NotSupportedException();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcontext.StepStartGroup($\"PropagateClosureParameterArguments of \" + info.Definition.Name, info.Definition);\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tforeach (var (index, arguments) in info.LocalFunctionArguments)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar targetVariable = info.Definition.Variables.SingleOrDefault(p => p.Kind == VariableKind.Parameter && p.Index == index);\n\t\t\t\t\t\tif (targetVariable == null)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tvar compatibleArgument = FindCompatibleArgument(info, arguments);\n\t\t\t\t\t\tif (compatibleArgument == null)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tcontext.Step($\"Replace '{targetVariable}' with '{compatibleArgument}'\", info.Definition);\n\t\t\t\t\t\tinfo.Definition.AcceptVisitor(new DelegateConstruction.ReplaceDelegateTargetVisitor(compatibleArgument, targetVariable));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tcontext.StepEndGroup(keepIfEmpty: true);\n\t\t\t\t}\n\n\t\t\t\tvoid AddAsArgument(int index, ILInstruction argument)\n\t\t\t\t{\n\t\t\t\t\tswitch (argument)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase LdLoc _:\n\t\t\t\t\t\tcase LdLoca _:\n\t\t\t\t\t\tcase LdFlda _:\n\t\t\t\t\t\tcase LdObj _:\n\t\t\t\t\t\t\tif (index >= 0 && !IsClosureParameter(info.Method.Parameters[index], resolveContext))\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tif (index >= 0 && IsClosureParameter(info.Method.Parameters[index], resolveContext))\n\t\t\t\t\t\t\t\tinfo.Definition.Warnings.Add(\"Could not transform parameter \" + index + \": unsupported argument pattern\");\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!info.LocalFunctionArguments.TryGetValue(index, out var arguments))\n\t\t\t\t\t{\n\t\t\t\t\t\targuments = new List<ILInstruction>();\n\t\t\t\t\t\tinfo.LocalFunctionArguments.Add(index, arguments);\n\t\t\t\t\t}\n\t\t\t\t\targuments.Add(argument);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate ILInstruction FindCompatibleArgument(LocalFunctionInfo info, IList<ILInstruction> arguments, bool ignoreStructure = false)\n\t\t{\n\t\t\tforeach (var arg in arguments)\n\t\t\t{\n\t\t\t\tif (arg is IInstructionWithVariableOperand ld2 && (ignoreStructure || info.Definition.IsDescendantOf(ld2.Variable.Function)))\n\t\t\t\t\treturn arg;\n\t\t\t\tvar v = ResolveAncestorScopeReference(arg);\n\t\t\t\tif (v != null)\n\t\t\t\t\treturn new LdLoc(v);\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tprivate ILVariable ResolveAncestorScopeReference(ILInstruction inst)\n\t\t{\n\t\t\tif (!inst.MatchLdFld(out var target, out var field))\n\t\t\t\treturn null;\n\t\t\tif (field.Type.Kind != TypeKind.Class)\n\t\t\t\treturn null;\n\t\t\tif (!(TransformDisplayClassUsage.IsPotentialClosure(context, field.Type.GetDefinition()) || context.Function.Method.DeclaringType.Equals(field.Type)))\n\t\t\t\treturn null;\n\t\t\tforeach (var v in context.Function.Descendants.OfType<ILFunction>().SelectMany(f => f.Variables))\n\t\t\t{\n\t\t\t\tif (!(TransformDisplayClassUsage.IsClosure(context, v, out var varType, out _) && varType.Equals(field.Type)))\n\t\t\t\t\tcontinue;\n\t\t\t\treturn v;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tprivate ILFunction GetDeclaringFunction(ILFunction localFunction)\n\t\t{\n\t\t\tif (localFunction.DeclarationScope == null)\n\t\t\t\treturn null;\n\t\t\tILInstruction inst = localFunction.DeclarationScope;\n\t\t\twhile (inst != null)\n\t\t\t{\n\t\t\t\tif (inst is ILFunction declaringFunction)\n\t\t\t\t\treturn declaringFunction;\n\t\t\t\tinst = inst.Parent;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tbool TryValidateSkipCount(LocalFunctionInfo info, out int skipCount)\n\t\t{\n\t\t\tskipCount = 0;\n\t\t\tvar localFunction = info.Definition;\n\t\t\tif (localFunction.Method.TypeParameters.Count == 0)\n\t\t\t\treturn true;\n\t\t\tvar parentMethod = ((ILFunction)localFunction.Parent).Method;\n\t\t\tvar method = localFunction.Method;\n\t\t\tskipCount = parentMethod.DeclaringType.TypeParameterCount - method.DeclaringType.TypeParameterCount;\n\n\t\t\tif (skipCount > 0)\n\t\t\t\treturn false;\n\t\t\tskipCount += parentMethod.TypeParameters.Count;\n\t\t\tif (skipCount < 0 || skipCount > method.TypeArguments.Count)\n\t\t\t\treturn false;\n\n\t\t\tif (skipCount > 0)\n\t\t\t{\n#if DEBUG\n\t\t\t\tforeach (var useSite in info.UseSites)\n\t\t\t\t{\n\t\t\t\t\tvar callerMethod = useSite.Ancestors.OfType<ILFunction>().First().Method;\n\t\t\t\t\tcallerMethod = callerMethod.ReducedFrom ?? callerMethod;\n\t\t\t\t\tIMethod m;\n\t\t\t\t\tswitch (useSite)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase NewObj newObj:\n\t\t\t\t\t\t\tm = ((LdFtn)newObj.Arguments[1]).Method;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase CallInstruction call:\n\t\t\t\t\t\t\tm = call.Method;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase LdFtn fnptr:\n\t\t\t\t\t\t\tm = fnptr.Method;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow new NotSupportedException();\n\t\t\t\t\t}\n\t\t\t\t\tvar totalSkipCount = skipCount + m.DeclaringType.TypeParameterCount;\n\t\t\t\t\tvar methodSkippedArgs = m.DeclaringType.TypeArguments.Concat(m.TypeArguments).Take(totalSkipCount);\n\t\t\t\t\tDebug.Assert(methodSkippedArgs.SequenceEqual(callerMethod.DeclaringType.TypeArguments.Concat(callerMethod.TypeArguments).Take(totalSkipCount)));\n\t\t\t\t\tDebug.Assert(methodSkippedArgs.All(p => p.Kind == TypeKind.TypeParameter));\n\t\t\t\t\tDebug.Assert(methodSkippedArgs.Select(p => p.Name).SequenceEqual(m.DeclaringType.TypeParameters.Concat(m.TypeParameters).Take(totalSkipCount).Select(p => p.Name)));\n\t\t\t\t}\n#endif\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tvoid FindUseSites(ILFunction function, ILTransformContext context, Dictionary<MethodDefinitionHandle, LocalFunctionInfo> localFunctions)\n\t\t{\n\t\t\tforeach (var inst in function.Body.Descendants)\n\t\t\t{\n\t\t\t\tcontext.CancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tif (inst is CallInstruction call && !call.Method.IsLocalFunction && IsLocalFunctionMethod(call.Method, context))\n\t\t\t\t{\n\t\t\t\t\tHandleUseSite(call.Method, call);\n\t\t\t\t}\n\t\t\t\telse if (inst is LdFtn ldftn && !ldftn.Method.IsLocalFunction && IsLocalFunctionMethod(ldftn.Method, context))\n\t\t\t\t{\n\t\t\t\t\tif (ldftn.Parent is NewObj newObj && DelegateConstruction.MatchDelegateConstruction(newObj, out _, out _, out _))\n\t\t\t\t\t\tHandleUseSite(ldftn.Method, newObj);\n\t\t\t\t\telse\n\t\t\t\t\t\tHandleUseSite(ldftn.Method, ldftn);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid HandleUseSite(IMethod targetMethod, ILInstruction inst)\n\t\t\t{\n\t\t\t\tif (!localFunctions.TryGetValue((MethodDefinitionHandle)targetMethod.MetadataToken, out var info))\n\t\t\t\t{\n\t\t\t\t\tcontext.StepStartGroup($\"Read local function '{targetMethod.Name}'\", inst);\n\t\t\t\t\tinfo = new LocalFunctionInfo() {\n\t\t\t\t\t\tUseSites = new List<ILInstruction>() { inst },\n\t\t\t\t\t\tLocalFunctionArguments = new Dictionary<int, List<ILInstruction>>(),\n\t\t\t\t\t\tMethod = (IMethod)targetMethod.MemberDefinition,\n\t\t\t\t\t};\n\t\t\t\t\tvar rootFunction = context.Function;\n\t\t\t\t\tint skipCount = GetSkipCount(rootFunction, targetMethod);\n\t\t\t\t\tinfo.Definition = ReadLocalFunctionDefinition(rootFunction, targetMethod, skipCount);\n\t\t\t\t\tlocalFunctions.Add((MethodDefinitionHandle)targetMethod.MetadataToken, info);\n\t\t\t\t\tif (info.Definition != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tFindUseSites(info.Definition, context, localFunctions);\n\t\t\t\t\t}\n\t\t\t\t\tcontext.StepEndGroup();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tinfo.UseSites.Add(inst);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tILFunction ReadLocalFunctionDefinition(ILFunction rootFunction, IMethod targetMethod, int skipCount)\n\t\t{\n\t\t\tvar methodDefinition = context.PEFile.Metadata.GetMethodDefinition((MethodDefinitionHandle)targetMethod.MetadataToken);\n\t\t\tvar genericContext = GenericContextFromTypeArguments(targetMethod, skipCount);\n\t\t\tif (genericContext == null)\n\t\t\t\treturn null;\n\t\t\tILFunction function;\n\t\t\tbool hasBody = methodDefinition.HasBody();\n\t\t\tif (!hasBody)\n\t\t\t{\n\t\t\t\tfunction = new ILFunction(targetMethod, 0,\n\t\t\t\t\tnew TypeSystem.GenericContext(genericContext?.ClassTypeParameters, genericContext?.MethodTypeParameters),\n\t\t\t\t\tnew Nop(), ILFunctionKind.LocalFunction);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar ilReader = context.CreateILReader();\n\t\t\t\tvar body = context.PEFile.GetMethodBody(methodDefinition.RelativeVirtualAddress);\n\n\t\t\t\tfunction = ilReader.ReadIL((MethodDefinitionHandle)targetMethod.MetadataToken, body,\n\t\t\t\t\tgenericContext.GetValueOrDefault(), ILFunctionKind.LocalFunction,\n\t\t\t\t\tcontext.CancellationToken);\n\t\t\t}\n\t\t\t// Embed the local function into the parent function's ILAst, so that \"Show steps\" can show\n\t\t\t// how the local function body is being transformed.\n\t\t\trootFunction.LocalFunctions.Add(function);\n\t\t\tif (hasBody)\n\t\t\t{\n\t\t\t\tfunction.DeclarationScope = (BlockContainer)rootFunction.Body;\n\t\t\t\tfunction.CheckInvariant(ILPhase.Normal);\n\t\t\t\tvar nestedContext = new ILTransformContext(context, function);\n\t\t\t\tfunction.RunTransforms(CSharpDecompiler.GetILTransforms().TakeWhile(t => !(t is LocalFunctionDecompiler)), nestedContext);\n\t\t\t\tfunction.DeclarationScope = null;\n\t\t\t}\n\t\t\tfunction.ReducedMethod = ReduceToLocalFunction(function.Method, skipCount);\n\t\t\treturn function;\n\t\t}\n\n\t\tint GetSkipCount(ILFunction rootFunction, IMethod targetMethod)\n\t\t{\n\t\t\ttargetMethod = (IMethod)targetMethod.MemberDefinition;\n\t\t\tvar skipCount = rootFunction.Method.DeclaringType.TypeParameters.Count + rootFunction.Method.TypeParameters.Count - targetMethod.DeclaringType.TypeParameters.Count;\n\t\t\tif (skipCount < 0)\n\t\t\t{\n\t\t\t\tskipCount = 0;\n\t\t\t}\n\t\t\tif (targetMethod.TypeParameters.Count > 0)\n\t\t\t{\n\t\t\t\tvar lastParams = targetMethod.Parameters.Where(p => IsClosureParameter(p, this.resolveContext)).SelectMany(p => p.Type.UnwrapByRef().TypeArguments)\n\t\t\t\t\t.Select(pt => (int?)targetMethod.TypeParameters.IndexOf(pt)).DefaultIfEmpty().Max();\n\t\t\t\tif (lastParams != null && lastParams.GetValueOrDefault() + 1 > skipCount)\n\t\t\t\t\tskipCount = lastParams.GetValueOrDefault() + 1;\n\t\t\t}\n\t\t\treturn skipCount;\n\t\t}\n\n\t\tstatic TypeSystem.GenericContext? GenericContextFromTypeArguments(IMethod targetMethod, int skipCount)\n\t\t{\n\t\t\tif (skipCount < 0 || skipCount > targetMethod.TypeParameters.Count)\n\t\t\t{\n\t\t\t\tDebug.Assert(false);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tint total = targetMethod.DeclaringType.TypeParameters.Count + skipCount;\n\t\t\tif (total == 0)\n\t\t\t\treturn default(TypeSystem.GenericContext);\n\n\t\t\tvar classTypeParameters = new List<ITypeParameter>(targetMethod.DeclaringType.TypeParameters);\n\t\t\tvar methodTypeParameters = new List<ITypeParameter>(targetMethod.TypeParameters);\n\t\t\tvar skippedTypeArguments = targetMethod.DeclaringType.TypeArguments.Concat(targetMethod.TypeArguments).Take(total);\n\t\t\tint idx = 0;\n\t\t\tforeach (var skippedTA in skippedTypeArguments)\n\t\t\t{\n\t\t\t\tint curIdx;\n\t\t\t\tList<ITypeParameter> curParameters;\n\t\t\t\tIReadOnlyList<IType> curArgs;\n\t\t\t\tif (idx < classTypeParameters.Count)\n\t\t\t\t{\n\t\t\t\t\tcurIdx = idx;\n\t\t\t\t\tcurParameters = classTypeParameters;\n\t\t\t\t\tcurArgs = targetMethod.DeclaringType.TypeArguments;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcurIdx = idx - classTypeParameters.Count;\n\t\t\t\t\tcurParameters = methodTypeParameters;\n\t\t\t\t\tcurArgs = targetMethod.TypeArguments;\n\t\t\t\t}\n\t\t\t\tif (curArgs[curIdx].Kind != TypeKind.TypeParameter)\n\t\t\t\t\tbreak;\n\t\t\t\tcurParameters[curIdx] = (ITypeParameter)skippedTA;\n\t\t\t\tidx++;\n\t\t\t}\n\t\t\tif (idx != total)\n\t\t\t{\n\t\t\t\tDebug.Assert(false);\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn new TypeSystem.GenericContext(classTypeParameters, methodTypeParameters);\n\t\t}\n\n\t\tstatic T FindCommonAncestorInstruction<T>(ILInstruction a, ILInstruction b)\n\t\t\twhere T : ILInstruction\n\t\t{\n\t\t\tvar ancestorsOfB = new HashSet<T>(b.Ancestors.OfType<T>());\n\t\t\treturn a.Ancestors.OfType<T>().FirstOrDefault(ancestorsOfB.Contains);\n\t\t}\n\n\t\tinternal static bool IsClosureParameter(IParameter parameter, ITypeResolveContext context)\n\t\t{\n\t\t\treturn IsClosureParameter(parameter, context.CurrentTypeDefinition);\n\t\t}\n\n\t\tinternal static bool IsClosureParameter(IParameter parameter, ITypeDefinition currentTypeDefinition)\n\t\t{\n\t\t\tif (parameter.Type is not ByReferenceType brt)\n\t\t\t\treturn false;\n\t\t\tvar type = brt.ElementType.GetDefinition();\n\t\t\treturn type != null\n\t\t\t\t&& type.Kind == TypeKind.Struct\n\t\t\t\t&& TransformDisplayClassUsage.IsPotentialClosure(currentTypeDefinition, type);\n\t\t}\n\n\t\tLocalFunctionMethod ReduceToLocalFunction(IMethod method, int typeParametersToRemove)\n\t\t{\n\t\t\tint parametersToRemove = 0;\n\t\t\tfor (int i = method.Parameters.Count - 1; i >= 0; i--)\n\t\t\t{\n\t\t\t\tif (!IsClosureParameter(method.Parameters[i], resolveContext))\n\t\t\t\t\tbreak;\n\t\t\t\tparametersToRemove++;\n\t\t\t}\n\t\t\treturn new LocalFunctionMethod(method, method.Name, CanBeStaticLocalFunction(), parametersToRemove, typeParametersToRemove);\n\n\t\t\tbool CanBeStaticLocalFunction()\n\t\t\t{\n\t\t\t\tif (!context.Settings.StaticLocalFunctions)\n\t\t\t\t\treturn false;\n\t\t\t\t// Cannot be static because there are closure parameters that will be removed\n\t\t\t\tif (parametersToRemove > 0)\n\t\t\t\t\treturn false;\n\t\t\t\t// no closure parameters, but static:\n\t\t\t\t// we can safely assume, this local function can be declared static\n\t\t\t\tif (method.IsStatic)\n\t\t\t\t\treturn true;\n\t\t\t\t// the local function is used in conjunction with a lambda, which means,\n\t\t\t\t// it is defined inside the display-class type\n\t\t\t\tvar declaringType = method.DeclaringTypeDefinition;\n\t\t\t\tif (!declaringType.IsCompilerGenerated())\n\t\t\t\t\treturn false;\n\t\t\t\t// if there are no instance fields, we can make it a static local function\n\t\t\t\treturn !declaringType.GetFields(f => !f.IsStatic).Any();\n\t\t\t}\n\t\t}\n\n\t\tstatic void TransformToLocalFunctionReference(ILFunction function, CallInstruction useSite)\n\t\t{\n\t\t\tILInstruction target = useSite.Arguments[0];\n\t\t\ttarget.ReplaceWith(new LdNull().WithILRange(target));\n\t\t\tif (target is IInstructionWithVariableOperand withVar && withVar.Variable.Kind == VariableKind.Local)\n\t\t\t{\n\t\t\t\twithVar.Variable.Kind = VariableKind.DisplayClassLocal;\n\t\t\t}\n\t\t\tvar fnptr = (IInstructionWithMethodOperand)useSite.Arguments[1];\n\t\t\tvar specializeMethod = function.ReducedMethod.Specialize(fnptr.Method.Substitution);\n\t\t\tvar replacement = new LdFtn(specializeMethod).WithILRange((ILInstruction)fnptr);\n\t\t\tuseSite.Arguments[1].ReplaceWith(replacement);\n\t\t}\n\n\t\tvoid TransformToLocalFunctionInvocation(LocalFunctionMethod reducedMethod, CallInstruction useSite)\n\t\t{\n\t\t\tvar specializeMethod = reducedMethod.Specialize(useSite.Method.Substitution);\n\t\t\tbool wasInstanceCall = !useSite.Method.IsStatic;\n\t\t\tvar replacement = new Call(specializeMethod);\n\t\t\tint firstArgumentIndex = wasInstanceCall ? 1 : 0;\n\t\t\tint argumentCount = useSite.Arguments.Count;\n\t\t\tint reducedArgumentCount = argumentCount - (reducedMethod.NumberOfCompilerGeneratedParameters + firstArgumentIndex);\n\t\t\treplacement.Arguments.AddRange(useSite.Arguments.Skip(firstArgumentIndex).Take(reducedArgumentCount));\n\t\t\t// copy flags\n\t\t\treplacement.ConstrainedTo = useSite.ConstrainedTo;\n\t\t\treplacement.ILStackWasEmpty = useSite.ILStackWasEmpty;\n\t\t\treplacement.IsTail = useSite.IsTail;\n\t\t\t// copy IL ranges\n\t\t\treplacement.AddILRange(useSite);\n\t\t\tif (wasInstanceCall)\n\t\t\t{\n\t\t\t\treplacement.AddILRange(useSite.Arguments[0]);\n\t\t\t\tif (useSite.Arguments[0].MatchLdLocRef(out var variable) && variable.Kind == VariableKind.NamedArgument)\n\t\t\t\t{\n\t\t\t\t\t// remove the store instruction of the simple load, if it is a named argument.\n\t\t\t\t\tvar storeInst = (ILInstruction)variable.StoreInstructions[0];\n\t\t\t\t\t((Block)storeInst.Parent).Instructions.RemoveAt(storeInst.ChildIndex);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (int i = 0; i < reducedMethod.NumberOfCompilerGeneratedParameters; i++)\n\t\t\t{\n\t\t\t\treplacement.AddILRange(useSite.Arguments[argumentCount - i - 1]);\n\t\t\t}\n\t\t\tuseSite.ReplaceWith(replacement);\n\t\t}\n\n\t\tvoid DetermineCaptureAndDeclarationScope(LocalFunctionInfo info, ILInstruction useSite)\n\t\t{\n\t\t\tswitch (useSite)\n\t\t\t{\n\t\t\t\tcase CallInstruction call:\n\t\t\t\t\tif (DelegateConstruction.MatchDelegateConstruction(useSite, out _, out _, out _))\n\t\t\t\t\t{\n\t\t\t\t\t\t// if this is a delegate construction, skip the use-site, because the capture scope\n\t\t\t\t\t\t// was already determined when analyzing \"this\".\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tint firstArgumentIndex = info.Definition.Method.IsStatic ? 0 : 1;\n\t\t\t\t\tfor (int i = call.Arguments.Count - 1; i >= firstArgumentIndex; i--)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!DetermineCaptureAndDeclarationScope(info, i - firstArgumentIndex, call.Arguments[i]))\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (firstArgumentIndex > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tDetermineCaptureAndDeclarationScope(info, -1, call.Arguments[0]);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase LdFtn _:\n\t\t\t\t\t// &LocalFunction is only possible, if the local function is declared static,\n\t\t\t\t\t// this means that the local function can be declared in the top-level scope.\n\t\t\t\t\t// leave info.DeclarationScope null/unassigned.\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException();\n\t\t\t}\n\t\t}\n\n\t\tbool DetermineCaptureAndDeclarationScope(LocalFunctionInfo info, int parameterIndex, ILInstruction arg)\n\t\t{\n\t\t\tILFunction function = info.Definition;\n\t\t\tILVariable closureVar;\n\t\t\tif (parameterIndex >= 0)\n\t\t\t{\n\t\t\t\tif (!(parameterIndex < function.Method.Parameters.Count\n\t\t\t\t\t&& IsClosureParameter(function.Method.Parameters[parameterIndex], resolveContext)))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!(arg.MatchLdLoc(out closureVar) || arg.MatchLdLoca(out closureVar)))\n\t\t\t{\n\t\t\t\tclosureVar = ResolveAncestorScopeReference(arg);\n\t\t\t\tif (closureVar == null)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (closureVar.Kind == VariableKind.NamedArgument)\n\t\t\t\treturn false;\n\t\t\tvar initializer = GetClosureInitializer(closureVar);\n\t\t\tif (initializer == null)\n\t\t\t\treturn false;\n\t\t\t// determine the capture scope of closureVar and the declaration scope of the function \n\t\t\tvar additionalScope = BlockContainer.FindClosestContainer(initializer);\n\t\t\tif (closureVar.CaptureScope == null)\n\t\t\t\tclosureVar.CaptureScope = additionalScope;\n\t\t\telse\n\t\t\t{\n\t\t\t\tBlockContainer combinedScope = FindCommonAncestorInstruction<BlockContainer>(closureVar.CaptureScope, additionalScope);\n\t\t\t\tDebug.Assert(combinedScope != null);\n\t\t\t\tclosureVar.CaptureScope = combinedScope;\n\t\t\t}\n\t\t\tif (closureVar.Kind == VariableKind.Local)\n\t\t\t{\n\t\t\t\tclosureVar.Kind = VariableKind.DisplayClassLocal;\n\t\t\t}\n\t\t\tif (function.DeclarationScope == null)\n\t\t\t\tfunction.DeclarationScope = closureVar.CaptureScope;\n\t\t\telse if (!IsInNestedLocalFunction(function.DeclarationScope, closureVar.CaptureScope.Ancestors.OfType<ILFunction>().First()))\n\t\t\t\tfunction.DeclarationScope = FindCommonAncestorInstruction<BlockContainer>(function.DeclarationScope, closureVar.CaptureScope);\n\t\t\treturn true;\n\n\t\t\tILInstruction GetClosureInitializer(ILVariable variable)\n\t\t\t{\n\t\t\t\tvar type = variable.Type.UnwrapByRef().GetDefinition();\n\t\t\t\tif (type == null)\n\t\t\t\t\treturn null;\n\t\t\t\tif (variable.Kind == VariableKind.Parameter)\n\t\t\t\t\treturn null;\n\t\t\t\tif (type.Kind == TypeKind.Struct)\n\t\t\t\t\treturn Block.GetContainingStatement(variable.AddressInstructions.OrderBy(i => i.StartILOffset).First());\n\t\t\t\telse\n\t\t\t\t\treturn (StLoc)variable.StoreInstructions[0];\n\t\t\t}\n\t\t}\n\n\t\tbool IsInNestedLocalFunction(BlockContainer declarationScope, ILFunction function)\n\t\t{\n\t\t\treturn TreeTraversal.PreOrder(function, f => f.LocalFunctions).Any(f => declarationScope.IsDescendantOf(f.Body));\n\t\t}\n\n\t\tinternal static bool IsLocalFunctionReference(NewObj inst, ILTransformContext context)\n\t\t{\n\t\t\tif (inst == null || inst.Arguments.Count != 2 || inst.Method.DeclaringType.Kind != TypeKind.Delegate)\n\t\t\t\treturn false;\n\t\t\tvar opCode = inst.Arguments[1].OpCode;\n\n\t\t\treturn opCode == OpCode.LdFtn\n\t\t\t\t&& IsLocalFunctionMethod(((IInstructionWithMethodOperand)inst.Arguments[1]).Method, context);\n\t\t}\n\n\t\tpublic static bool IsLocalFunctionMethod(IMethod method, ILTransformContext context)\n\t\t{\n\t\t\tif (method.MetadataToken.IsNil)\n\t\t\t\treturn false;\n\t\t\treturn IsLocalFunctionMethod(method.ParentModule.MetadataFile, (MethodDefinitionHandle)method.MetadataToken, context);\n\t\t}\n\n\t\tpublic static bool IsLocalFunctionMethod(MetadataFile module, MethodDefinitionHandle methodHandle, ILTransformContext context = null)\n\t\t{\n\t\t\tif (context != null && context.PEFile != module)\n\t\t\t\treturn false;\n\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar method = metadata.GetMethodDefinition(methodHandle);\n\t\t\tvar declaringType = method.GetDeclaringType();\n\n\t\t\tif ((method.Attributes & MethodAttributes.Assembly) == 0 || !(method.IsCompilerGenerated(metadata) || declaringType.IsCompilerGenerated(metadata)))\n\t\t\t\treturn false;\n\n\t\t\tif (!ParseLocalFunctionName(metadata.GetString(method.Name), out _, out _))\n\t\t\t\treturn false;\n\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic static bool LocalFunctionNeedsAccessibilityChange(MetadataFile module, MethodDefinitionHandle methodHandle)\n\t\t{\n\t\t\tif (!IsLocalFunctionMethod(module, methodHandle))\n\t\t\t\treturn false;\n\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar method = metadata.GetMethodDefinition(methodHandle);\n\n\t\t\tFindRefStructParameters visitor = new FindRefStructParameters();\n\t\t\tmethod.DecodeSignature(visitor, default);\n\n\t\t\tforeach (var h in visitor.RefStructTypes)\n\t\t\t{\n\t\t\t\tvar td = metadata.GetTypeDefinition(h);\n\t\t\t\tif (td.IsCompilerGenerated(metadata) && td.IsValueType(metadata))\n\t\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool IsLocalFunctionDisplayClass(MetadataFile module, TypeDefinitionHandle typeHandle, ILTransformContext context = null)\n\t\t{\n\t\t\tif (context != null && context.PEFile != module)\n\t\t\t\treturn false;\n\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar type = metadata.GetTypeDefinition(typeHandle);\n\n\t\t\tif ((type.Attributes & TypeAttributes.VisibilityMask) != TypeAttributes.NestedPrivate)\n\t\t\t\treturn false;\n\t\t\tif (!type.HasGeneratedName(metadata))\n\t\t\t\treturn false;\n\n\t\t\tvar declaringTypeHandle = type.GetDeclaringType();\n\t\t\tvar declaringType = metadata.GetTypeDefinition(declaringTypeHandle);\n\n\t\t\tforeach (var method in declaringType.GetMethods())\n\t\t\t{\n\t\t\t\tif (!IsLocalFunctionMethod(module, method, context))\n\t\t\t\t\tcontinue;\n\t\t\t\tvar md = metadata.GetMethodDefinition(method);\n\t\t\t\tif (md.DecodeSignature(new FindTypeDecoder(typeHandle, module), default).ParameterTypes.Any())\n\t\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Newer Roslyn versions use the format \"&lt;callerName&gt;g__functionName|x_y\"\n\t\t/// Older versions use \"&lt;callerName&gt;g__functionNamex_y\"\n\t\t/// </summary>\n\t\tstatic readonly Regex functionNameRegex = new Regex(@\"^<(.*)>g__([^\\|]*)\\|{0,1}\\d+(_\\d+)?$\", RegexOptions.Compiled);\n\n\t\tinternal static bool ParseLocalFunctionName(string name, out string callerName, out string functionName)\n\t\t{\n\t\t\tcallerName = null;\n\t\t\tfunctionName = null;\n\t\t\tif (string.IsNullOrWhiteSpace(name))\n\t\t\t\treturn false;\n\t\t\tvar match = functionNameRegex.Match(name);\n\t\t\tcallerName = match.Groups[1].Value;\n\t\t\tfunctionName = match.Groups[2].Value;\n\t\t\treturn match.Success;\n\t\t}\n\n\t\tclass FindRefStructParameters : ISignatureTypeProvider<TypeDefinitionHandle, Unit>\n\t\t{\n\t\t\tpublic readonly List<TypeDefinitionHandle> RefStructTypes = new List<TypeDefinitionHandle>();\n\n\t\t\tpublic TypeDefinitionHandle GetArrayType(TypeDefinitionHandle elementType, ArrayShape shape) => default;\n\t\t\tpublic TypeDefinitionHandle GetFunctionPointerType(MethodSignature<TypeDefinitionHandle> signature) => default;\n\t\t\tpublic TypeDefinitionHandle GetGenericInstantiation(TypeDefinitionHandle genericType, ImmutableArray<TypeDefinitionHandle> typeArguments) => default;\n\t\t\tpublic TypeDefinitionHandle GetGenericMethodParameter(Unit genericContext, int index) => default;\n\t\t\tpublic TypeDefinitionHandle GetGenericTypeParameter(Unit genericContext, int index) => default;\n\t\t\tpublic TypeDefinitionHandle GetModifiedType(TypeDefinitionHandle modifier, TypeDefinitionHandle unmodifiedType, bool isRequired) => default;\n\t\t\tpublic TypeDefinitionHandle GetPinnedType(TypeDefinitionHandle elementType) => default;\n\t\t\tpublic TypeDefinitionHandle GetPointerType(TypeDefinitionHandle elementType) => default;\n\t\t\tpublic TypeDefinitionHandle GetPrimitiveType(PrimitiveTypeCode typeCode) => default;\n\t\t\tpublic TypeDefinitionHandle GetSZArrayType(TypeDefinitionHandle elementType) => default;\n\n\t\t\tpublic TypeDefinitionHandle GetByReferenceType(TypeDefinitionHandle elementType)\n\t\t\t{\n\t\t\t\tif (!elementType.IsNil)\n\t\t\t\t\tRefStructTypes.Add(elementType);\n\t\t\t\treturn elementType;\n\t\t\t}\n\n\t\t\tpublic TypeDefinitionHandle GetTypeFromSpecification(MetadataReader reader, Unit genericContext, TypeSpecificationHandle handle, byte rawTypeKind) => default;\n\t\t\tpublic TypeDefinitionHandle GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind) => handle;\n\t\t\tpublic TypeDefinitionHandle GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind) => default;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/LockTransform.cs",
    "content": "// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\tpublic class LockTransform : IBlockTransform\n\t{\n\t\tBlockTransformContext context;\n\n\t\tvoid IBlockTransform.Run(Block block, BlockTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.LockStatement)\n\t\t\t\treturn;\n\t\t\tthis.context = context;\n\t\t\tfor (int i = context.IndexOfFirstAlreadyTransformedInstruction - 1; i >= 0; i--)\n\t\t\t{\n\t\t\t\tbool changed = DoTransform(block, i);\n\t\t\t\tif (changed)\n\t\t\t\t{\n\t\t\t\t\tcontext.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count;\n\t\t\t\t}\n\t\t\t\t// This happens in some cases:\n\t\t\t\t// Use correct index after transformation.\n\t\t\t\tif (i >= block.Instructions.Count)\n\t\t\t\t\ti = block.Instructions.Count;\n\t\t\t}\n\n\t\t\tbool DoTransform(Block block, int i)\n\t\t\t{\n\t\t\t\tif (TransformLockRoslyn(block, i))\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (TransformLockV4(block, i))\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (TransformLockV4YieldReturn(block, i))\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (TransformLockV2(block, i))\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn TransformLockMCS(block, i);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t///\tstloc lockObj(lockExpression)\n\t\t///\tcall Enter(ldloc lockObj)\n\t\t///\t.try BlockContainer {\n\t\t///\t\tBlock lockBlock (incoming: 1) {\n\t\t///\t\t\tcall WriteLine()\n\t\t///\t\t\tleave lockBlock (nop)\n\t\t///\t\t}\n\t\t///\n\t\t///\t} finally BlockContainer {\n\t\t///\t\tBlock exitBlock (incoming: 1) {\n\t\t///\t\t\tcall Exit(ldloc lockObj)\n\t\t///\t\t\tleave exitBlock (nop)\n\t\t///\t\t}\n\t\t///\n\t\t///\t}\n\t\t/// =>\n\t\t/// .lock (lockExpression) BlockContainer {\n\t\t/// \tBlock lockBlock (incoming: 1) {\n\t\t///\t\t\tcall WriteLine()\n\t\t///\t\t\tleave lockBlock (nop)\n\t\t///\t\t}\n\t\t/// }\n\t\t/// </summary>\n\t\tbool TransformLockMCS(Block block, int i)\n\t\t{\n\t\t\tif (i < 2)\n\t\t\t\treturn false;\n\t\t\tif (!(block.Instructions[i] is TryFinally body) || !(block.Instructions[i - 2] is StLoc objectStore) ||\n\t\t\t\t!MatchCall(block.Instructions[i - 1] as Call, \"Enter\", objectStore.Variable))\n\t\t\t\treturn false;\n\t\t\tif (!objectStore.Variable.IsSingleDefinition)\n\t\t\t\treturn false;\n\t\t\tif (!(body.TryBlock is BlockContainer tryContainer) || tryContainer.EntryPoint.Instructions.Count == 0 || tryContainer.EntryPoint.IncomingEdgeCount != 1)\n\t\t\t\treturn false;\n\t\t\tif (!(body.FinallyBlock is BlockContainer finallyContainer) || !MatchExitBlock(finallyContainer.EntryPoint, null, objectStore.Variable))\n\t\t\t\treturn false;\n\t\t\tif (objectStore.Variable.LoadCount > 2)\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"LockTransformMCS\", block);\n\t\t\tblock.Instructions.RemoveAt(i - 1);\n\t\t\tblock.Instructions.RemoveAt(i - 2);\n\t\t\tbody.ReplaceWith(new LockInstruction(objectStore.Value, body.TryBlock).WithILRange(objectStore));\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t///\tstloc lockObj(ldloc tempVar)\n\t\t///\tcall Enter(ldloc tempVar)\n\t\t///\t.try BlockContainer {\n\t\t///\t\tBlock lockBlock(incoming: 1) {\n\t\t///\t\t\tcall WriteLine()\n\t\t///\t\t\tleave lockBlock (nop)\n\t\t///\t\t}\n\t\t///\t} finally BlockContainer {\n\t\t///\t\tBlock exitBlock(incoming: 1) {\n\t\t///\t\t\tcall Exit(ldloc lockObj)\n\t\t///\t\t\tleave exitBlock (nop)\n\t\t///\t\t}\n\t\t/// }\n\t\t/// =>\n\t\t/// .lock (lockObj) BlockContainer {\n\t\t/// \tBlock lockBlock (incoming: 1) {\n\t\t///\t\t\tcall WriteLine()\n\t\t///\t\t\tleave lockBlock (nop)\n\t\t///\t\t}\n\t\t/// }\n\t\t/// </summary>\n\t\tbool TransformLockV2(Block block, int i)\n\t\t{\n\t\t\tif (i < 2)\n\t\t\t\treturn false;\n\t\t\tif (!(block.Instructions[i] is TryFinally body) || !(block.Instructions[i - 2] is StLoc objectStore) ||\n\t\t\t\t!objectStore.Value.MatchLdLoc(out var tempVar) || !MatchCall(block.Instructions[i - 1] as Call, \"Enter\", tempVar))\n\t\t\t\treturn false;\n\t\t\tif (!objectStore.Variable.IsSingleDefinition)\n\t\t\t\treturn false;\n\t\t\tif (!(body.TryBlock is BlockContainer tryContainer) || tryContainer.EntryPoint.Instructions.Count == 0 || tryContainer.EntryPoint.IncomingEdgeCount != 1)\n\t\t\t\treturn false;\n\t\t\tif (!(body.FinallyBlock is BlockContainer finallyContainer) || !MatchExitBlock(finallyContainer.EntryPoint, null, objectStore.Variable))\n\t\t\t\treturn false;\n\t\t\tif (objectStore.Variable.LoadCount > 1)\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"LockTransformV2\", block);\n\t\t\tblock.Instructions.RemoveAt(i - 1);\n\t\t\tblock.Instructions.RemoveAt(i - 2);\n\t\t\tbody.ReplaceWith(new LockInstruction(objectStore.Value, body.TryBlock).WithILRange(objectStore));\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t///\tstloc flag(ldc.i4 0)\n\t\t///\t.try BlockContainer {\n\t\t///\t\tBlock lockBlock (incoming: 1) {\n\t\t///\t\t\tcall Enter(stloc obj(lockObj), ldloca flag)\n\t\t///\t\t\tcall WriteLine()\n\t\t///\t\t\tleave lockBlock (nop)\n\t\t///\t\t}\n\t\t///\t} finally BlockContainer {\n\t\t///\t\tBlock (incoming: 1) {\n\t\t///\t\t\tif (ldloc flag) Block  {\n\t\t///\t\t\t\tcall Exit(ldloc obj)\n\t\t///\t\t\t}\n\t\t///\t\t\tleave lockBlock (nop)\n\t\t///\t\t}\t\t\n\t\t/// }\n\t\t/// =>\n\t\t/// .lock (lockObj) BlockContainer {\n\t\t/// \tBlock lockBlock (incoming: 1) {\n\t\t///\t\t\tcall WriteLine()\n\t\t///\t\t\tleave lockBlock (nop)\n\t\t///\t\t}\n\t\t/// }\n\t\t/// </summary>\n\t\tbool TransformLockV4(Block block, int i)\n\t\t{\n\t\t\tif (i < 1)\n\t\t\t\treturn false;\n\t\t\tif (!(block.Instructions[i] is TryFinally body) || !(block.Instructions[i - 1] is StLoc flagStore))\n\t\t\t\treturn false;\n\t\t\tif (!flagStore.Variable.Type.IsKnownType(KnownTypeCode.Boolean) || !flagStore.Value.MatchLdcI4(0))\n\t\t\t\treturn false;\n\t\t\tif (!(body.TryBlock is BlockContainer tryContainer) || !MatchLockEntryPoint(tryContainer.EntryPoint, flagStore.Variable, out StLoc objectStore))\n\t\t\t\treturn false;\n\t\t\tif (!(body.FinallyBlock is BlockContainer finallyContainer) || !MatchExitBlock(finallyContainer.EntryPoint, flagStore.Variable, objectStore.Variable))\n\t\t\t\treturn false;\n\t\t\tif (objectStore.Variable.LoadCount > 1)\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"LockTransformV4\", block);\n\t\t\tblock.Instructions.RemoveAt(i - 1);\n\t\t\ttryContainer.EntryPoint.Instructions.RemoveAt(0);\n\t\t\tbody.ReplaceWith(new LockInstruction(objectStore.Value, body.TryBlock).WithILRange(objectStore));\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t///\tstloc flag(ldc.i4 0)\n\t\t///\t.try BlockContainer {\n\t\t///\t\tBlock lockBlock (incoming: 1) {\n\t\t///\t\t\tstloc obj1(stloc obj2(lockObj))\n\t\t///\t\t\tcall Enter(ldloc obj2, ldloca flag)\n\t\t///\t\t\tcall WriteLine()\n\t\t///\t\t\tleave lockBlock (nop)\n\t\t///\t\t}\n\t\t///\t} finally BlockContainer {\n\t\t///\t\tBlock (incoming: 1) {\n\t\t///\t\t\tif (ldloc flag) Block  {\n\t\t///\t\t\t\tcall Exit(ldloc obj1)\n\t\t///\t\t\t}\n\t\t///\t\t\tleave lockBlock (nop)\n\t\t///\t\t}\n\t\t/// }\n\t\t/// =>\n\t\t/// .lock (lockObj) BlockContainer {\n\t\t/// \tBlock lockBlock (incoming: 1) {\n\t\t///\t\t\tcall WriteLine()\n\t\t///\t\t\tleave lockBlock (nop)\n\t\t///\t\t}\n\t\t/// }\n\t\t/// </summary>\n\t\tbool TransformLockV4YieldReturn(Block block, int i)\n\t\t{\n\t\t\tif (i < 1)\n\t\t\t\treturn false;\n\t\t\tif (!(block.Instructions[i] is TryFinally body) || !(block.Instructions[i - 1] is StLoc flagStore))\n\t\t\t\treturn false;\n\t\t\tif (!flagStore.Variable.Type.IsKnownType(KnownTypeCode.Boolean) || !flagStore.Value.MatchLdcI4(0))\n\t\t\t\treturn false;\n\t\t\tif (!(body.TryBlock is BlockContainer tryContainer) || !MatchLockEntryPoint(tryContainer.EntryPoint, flagStore.Variable, out ILVariable exitVariable, out var objectStore))\n\t\t\t\treturn false;\n\t\t\tif (!(body.FinallyBlock is BlockContainer finallyContainer) || !MatchExitBlock(finallyContainer.EntryPoint, flagStore.Variable, exitVariable))\n\t\t\t\treturn false;\n\t\t\tif (objectStore.Variable.LoadCount > 1)\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"LockTransformV4YieldReturn\", block);\n\t\t\tblock.Instructions.RemoveAt(i - 1);\n\t\t\ttryContainer.EntryPoint.Instructions.RemoveRange(0, 2);\n\t\t\tbody.ReplaceWith(new LockInstruction(objectStore.Value, body.TryBlock).WithILRange(objectStore));\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// stloc obj(lockObj)\n\t\t///\tstloc flag(ldc.i4 0)\n\t\t///\t.try BlockContainer {\n\t\t///\t\tBlock lockBlock (incoming: 1) {\n\t\t///\t\t\tcall Enter(ldloc obj, ldloca flag)\n\t\t///\t\t\tcall WriteLine()\n\t\t///\t\t\tleave lockBlock (nop)\n\t\t///\t\t}\n\t\t///\t} finally BlockContainer {\n\t\t///\t\tBlock (incoming: 1) {\n\t\t///\t\t\tif (ldloc flag) Block  {\n\t\t///\t\t\t\tcall Exit(ldloc obj)\n\t\t///\t\t\t}\n\t\t///\t\t\tleave lockBlock (nop)\n\t\t///\t\t}\t\t\n\t\t/// }\n\t\t/// =>\n\t\t/// .lock (lockObj) BlockContainer {\n\t\t/// \tBlock lockBlock (incoming: 1) {\n\t\t///\t\t\tcall WriteLine()\n\t\t///\t\t\tleave lockBlock (nop)\n\t\t///\t\t}\n\t\t/// }\n\t\t/// </summary>\n\t\tbool TransformLockRoslyn(Block block, int i)\n\t\t{\n\t\t\tif (i < 2)\n\t\t\t\treturn false;\n\t\t\tif (!(block.Instructions[i] is TryFinally body) || !(block.Instructions[i - 1] is StLoc flagStore) || !(block.Instructions[i - 2] is StLoc objectStore))\n\t\t\t\treturn false;\n\t\t\tif (!objectStore.Variable.IsSingleDefinition || !flagStore.Variable.Type.IsKnownType(KnownTypeCode.Boolean) || !flagStore.Value.MatchLdcI4(0))\n\t\t\t\treturn false;\n\t\t\tif (!(body.TryBlock is BlockContainer tryContainer) || !MatchLockEntryPoint(tryContainer.EntryPoint, flagStore.Variable, objectStore.Variable))\n\t\t\t\treturn false;\n\t\t\tif (!(body.FinallyBlock is BlockContainer finallyContainer) || !MatchExitBlock(finallyContainer.EntryPoint, flagStore.Variable, objectStore.Variable))\n\t\t\t\treturn false;\n\t\t\tif (objectStore.Variable.LoadCount > 2)\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"LockTransformRoslyn\", block);\n\t\t\tblock.Instructions.RemoveAt(i - 1);\n\t\t\tblock.Instructions.RemoveAt(i - 2);\n\t\t\ttryContainer.EntryPoint.Instructions.RemoveAt(0);\n\t\t\tbody.ReplaceWith(new LockInstruction(objectStore.Value, body.TryBlock).WithILRange(objectStore));\n\t\t\treturn true;\n\t\t}\n\n\t\tbool MatchExitBlock(Block entryPoint, ILVariable flag, ILVariable obj)\n\t\t{\n\t\t\tif (entryPoint.Instructions.Count != 2 || entryPoint.IncomingEdgeCount != 1)\n\t\t\t\treturn false;\n\t\t\tif (flag != null)\n\t\t\t{\n\t\t\t\tif (!entryPoint.Instructions[0].MatchIfInstruction(out var cond, out var trueInst) || !(trueInst is Block trueBlock))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(cond.MatchLdLoc(flag) || (cond.MatchCompNotEquals(out var left, out var right) && left.MatchLdLoc(flag) && right.MatchLdcI4(0))) || !MatchExitBlock(trueBlock, obj))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (!MatchCall(entryPoint.Instructions[0] as Call, \"Exit\", obj))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!entryPoint.Instructions[1].MatchLeave((BlockContainer)entryPoint.Parent, out var retVal) || !retVal.MatchNop())\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tbool MatchExitBlock(Block exitBlock, ILVariable obj)\n\t\t{\n\t\t\tif (exitBlock.Instructions.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (!MatchCall(exitBlock.Instructions[0] as Call, \"Exit\", obj))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tbool MatchLockEntryPoint(Block entryPoint, ILVariable flag, ILVariable obj)\n\t\t{\n\t\t\tif (entryPoint.Instructions.Count == 0 || entryPoint.IncomingEdgeCount != 1)\n\t\t\t\treturn false;\n\t\t\tif (!MatchCall(entryPoint.Instructions[0] as Call, \"Enter\", obj, flag))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tbool MatchLockEntryPoint(Block entryPoint, ILVariable flag, out StLoc obj)\n\t\t{\n\t\t\tobj = null;\n\t\t\tif (entryPoint.Instructions.Count == 0 || entryPoint.IncomingEdgeCount != 1)\n\t\t\t\treturn false;\n\t\t\tif (!MatchCall(entryPoint.Instructions[0] as Call, \"Enter\", flag, out obj))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tbool MatchLockEntryPoint(Block entryPoint, ILVariable flag, out ILVariable exitVairable, out StLoc obj)\n\t\t{\n\t\t\t// This pattern is commonly seen in yield return state machines emitted by the legacy C# compiler.\n\t\t\tobj = null;\n\t\t\texitVairable = null;\n\t\t\tif (entryPoint.Instructions.Count < 1 || entryPoint.IncomingEdgeCount != 1)\n\t\t\t\treturn false;\n\t\t\tif (entryPoint.Instructions[0].MatchStLoc(out exitVairable, out var value) && value is StLoc nestedStloc)\n\t\t\t{\n\t\t\t\tobj = nestedStloc;\n\t\t\t\tif (!MatchCall(entryPoint.Instructions[1] as Call, \"Enter\", nestedStloc.Variable, flag))\n\t\t\t\t\treturn false;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tbool MatchCall(Call call, string methodName, ILVariable flag, out StLoc obj)\n\t\t{\n\t\t\tobj = null;\n\t\t\tconst string ThreadingMonitor = \"System.Threading.Monitor\";\n\t\t\tif (call == null || call.Method.Name != methodName || call.Method.DeclaringType.FullName != ThreadingMonitor ||\n\t\t\t\tcall.Method.TypeArguments.Count != 0 || call.Arguments.Count != 2)\n\t\t\t\treturn false;\n\t\t\tif (!call.Arguments[1].MatchLdLoca(flag) || !(call.Arguments[0] is StLoc val))\n\t\t\t\treturn false;\n\t\t\tobj = val;\n\t\t\treturn true;\n\t\t}\n\n\t\tbool MatchCall(Call call, string methodName, params ILVariable[] variables)\n\t\t{\n\t\t\tconst string ThreadingMonitor = \"System.Threading.Monitor\";\n\t\t\tif (call == null || call.Method.Name != methodName || call.Method.DeclaringType.FullName != ThreadingMonitor ||\n\t\t\t\tcall.Method.TypeArguments.Count != 0 || call.Arguments.Count != variables.Length)\n\t\t\t\treturn false;\n\t\t\tif (!call.Arguments[0].MatchLdLoc(variables[0]))\n\t\t\t\treturn false;\n\t\t\tif (variables.Length == 2)\n\t\t\t{\n\t\t\t\tif (!call.Arguments[1].MatchLdLoca(variables[1]))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/NamedArgumentTransform.cs",
    "content": "using System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\tusing FindResult = ILInlining.FindResult;\n\tusing FindResultType = ILInlining.FindResultType;\n\n\tpublic class NamedArgumentTransform : IStatementTransform\n\t{\n\t\tinternal static FindResult CanIntroduceNamedArgument(CallInstruction call, ILInstruction child, ILVariable v, ILInstruction expressionBeingMoved)\n\t\t{\n\t\t\tDebug.Assert(child.Parent == call);\n\t\t\tif (call.IsInstanceCall && child.ChildIndex == 0)\n\t\t\t\treturn FindResult.Stop; // cannot use named arg to move expressionBeingMoved before this pointer\n\t\t\tif (call.Method.IsOperator || call.Method.IsAccessor)\n\t\t\t\treturn FindResult.Stop; // cannot use named arg for operators or accessors\n\t\t\tif (call.Method is VarArgInstanceMethod)\n\t\t\t\treturn FindResult.Stop; // CallBuilder doesn't support named args when using varargs\n\t\t\tif (call.Method.IsConstructor)\n\t\t\t{\n\t\t\t\tIType type = call.Method.DeclaringType;\n\t\t\t\tif (type.Kind == TypeKind.Delegate || type.IsAnonymousType())\n\t\t\t\t\treturn FindResult.Stop;\n\t\t\t}\n\t\t\tif (call.Method.Parameters.Any(p => string.IsNullOrEmpty(p.Name)))\n\t\t\t\treturn FindResult.Stop; // cannot use named arguments\n\t\t\tfor (int i = child.ChildIndex; i < call.Arguments.Count; i++)\n\t\t\t{\n\t\t\t\tvar r = ILInlining.FindLoadInNext(call.Arguments[i], v, expressionBeingMoved, InliningOptions.None);\n\t\t\t\tif (r.Type == FindResultType.Found)\n\t\t\t\t{\n\t\t\t\t\treturn FindResult.NamedArgument(r.LoadInst, call.Arguments[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn FindResult.Stop;\n\t\t}\n\n\t\tinternal static FindResult CanExtendNamedArgument(Block block, ILVariable v, ILInstruction expressionBeingMoved)\n\t\t{\n\t\t\tDebug.Assert(block.Kind == BlockKind.CallWithNamedArgs);\n\t\t\tvar firstArg = ((StLoc)block.Instructions[0]).Value;\n\t\t\tvar r = ILInlining.FindLoadInNext(firstArg, v, expressionBeingMoved, InliningOptions.IntroduceNamedArguments);\n\t\t\tif (r.Type == FindResultType.Found || r.Type == FindResultType.NamedArgument)\n\t\t\t{\n\t\t\t\treturn r; // OK, inline into first instruction of block\n\t\t\t}\n\t\t\tvar call = (CallInstruction)block.FinalInstruction;\n\t\t\tif (call.IsInstanceCall)\n\t\t\t{\n\t\t\t\t// For instance calls, block.Instructions[0] is the argument\n\t\t\t\t// for the 'this' pointer. We can only insert at position 1.\n\t\t\t\tif (r.Type == FindResultType.Stop)\n\t\t\t\t{\n\t\t\t\t\t// error: can't move expressionBeingMoved after block.Instructions[0]\n\t\t\t\t\treturn FindResult.Stop;\n\t\t\t\t}\n\t\t\t\t// Because we always ensure block.Instructions[0] is the 'this' argument,\n\t\t\t\t// it's possible that the place we actually need to inline into\n\t\t\t\t// is within block.Instructions[1]:\n\t\t\t\tif (block.Instructions.Count > 1)\n\t\t\t\t{\n\t\t\t\t\tr = ILInlining.FindLoadInNext(block.Instructions[1], v, expressionBeingMoved, InliningOptions.IntroduceNamedArguments);\n\t\t\t\t\tif (r.Type == FindResultType.Found || r.Type == FindResultType.NamedArgument)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn r; // OK, inline into block.Instructions[1]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tforeach (var arg in call.Arguments)\n\t\t\t{\n\t\t\t\tif (arg.MatchLdLoc(v))\n\t\t\t\t{\n\t\t\t\t\treturn FindResult.NamedArgument(arg, arg);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn FindResult.Stop;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Introduce a named argument for 'arg' and evaluate it before the other arguments\n\t\t/// (except for the \"this\" pointer)\n\t\t/// </summary>\n\t\tinternal static void IntroduceNamedArgument(ILInstruction arg, ILTransformContext context)\n\t\t{\n\t\t\tvar call = (CallInstruction)arg.Parent;\n\t\t\tDebug.Assert(context.Function == call.Ancestors.OfType<ILFunction>().First());\n\t\t\tvar type = context.TypeSystem.FindType(arg.ResultType);\n\t\t\tvar v = context.Function.RegisterVariable(VariableKind.NamedArgument, type);\n\t\t\tcontext.Step($\"Introduce named argument '{v.Name}'\", arg);\n\t\t\tif (!(call.Parent is Block namedArgBlock) || namedArgBlock.Kind != BlockKind.CallWithNamedArgs)\n\t\t\t{\n\t\t\t\t// create namedArgBlock:\n\t\t\t\tnamedArgBlock = new Block(BlockKind.CallWithNamedArgs);\n\t\t\t\tcall.ReplaceWith(namedArgBlock);\n\t\t\t\tnamedArgBlock.FinalInstruction = call;\n\t\t\t\tif (call.IsInstanceCall)\n\t\t\t\t{\n\t\t\t\t\tIType thisVarType = call.ConstrainedTo ?? call.Method.DeclaringType;\n\t\t\t\t\tif (CallInstruction.ExpectedTypeForThisPointer(call.Method.DeclaringType, call.ConstrainedTo) == StackType.Ref)\n\t\t\t\t\t{\n\t\t\t\t\t\tthisVarType = new ByReferenceType(thisVarType);\n\t\t\t\t\t}\n\t\t\t\t\tvar thisArgVar = context.Function.RegisterVariable(VariableKind.NamedArgument, thisVarType, \"this_arg\");\n\t\t\t\t\tnamedArgBlock.Instructions.Add(new StLoc(thisArgVar, call.Arguments[0]));\n\t\t\t\t\tcall.Arguments[0] = new LdLoc(thisArgVar);\n\t\t\t\t}\n\t\t\t}\n\t\t\tint argIndex = arg.ChildIndex;\n\t\t\tDebug.Assert(call.Arguments[argIndex] == arg);\n\t\t\tnamedArgBlock.Instructions.Insert(call.IsInstanceCall ? 1 : 0, new StLoc(v, arg));\n\t\t\tcall.Arguments[argIndex] = new LdLoc(v);\n\t\t}\n\n\t\tpublic void Run(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.NamedArguments)\n\t\t\t\treturn;\n\t\t\tvar options = ILInlining.OptionsForBlock(block, pos, context);\n\t\t\toptions |= InliningOptions.IntroduceNamedArguments;\n\t\t\tILInlining.InlineOneIfPossible(block, pos, options, context: context);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/NullCoalescingTransform.cs",
    "content": "// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Transform for constructing the NullCoalescingInstruction (if.notnull(a,b), or in C#: ??)\n\t/// Note that this transform only handles the case where a,b are reference types.\n\t/// \n\t/// The ?? operator for nullable value types is handled by NullableLiftingTransform.\n\t/// </summary>\n\tpublic class NullCoalescingTransform : IStatementTransform\n\t{\n\t\tpublic void Run(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\tif (!TransformRefTypes(block, pos, context))\n\t\t\t{\n\t\t\t\tTransformThrowExpressionValueTypes(block, pos, context);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Handles NullCoalescingInstruction case 1: reference types.\n\t\t/// </summary>\n\t\tbool TransformRefTypes(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\tif (!(block.Instructions[pos] is StLoc stloc))\n\t\t\t\treturn false;\n\t\t\tif (stloc.Variable.Kind != VariableKind.StackSlot)\n\t\t\t\treturn false;\n\t\t\tif (!block.Instructions[pos + 1].MatchIfInstruction(out var condition, out var trueInst))\n\t\t\t\treturn false;\n\t\t\tif (!(condition.MatchCompEquals(out var left, out var right) && left.MatchLdLoc(stloc.Variable) && right.MatchLdNull()))\n\t\t\t\treturn false;\n\t\t\ttrueInst = Block.Unwrap(trueInst);\n\t\t\t// stloc s(valueInst)\n\t\t\t// if (comp(ldloc s == ldnull)) {\n\t\t\t//\t\tstloc s(fallbackInst)\n\t\t\t// }\n\t\t\t// =>\n\t\t\t// stloc s(if.notnull(valueInst, fallbackInst))\n\t\t\tif (trueInst.MatchStLoc(stloc.Variable, out var fallbackValue))\n\t\t\t{\n\t\t\t\tcontext.Step(\"NullCoalescingTransform: simple (reference types)\", stloc);\n\t\t\t\tstloc.Value = new NullCoalescingInstruction(NullCoalescingKind.Ref, stloc.Value, fallbackValue);\n\t\t\t\tblock.Instructions.RemoveAt(pos + 1); // remove if instruction\n\t\t\t\tILInlining.InlineOneIfPossible(block, pos, InliningOptions.None, context);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\t// sometimes the compiler generates:\n\t\t\t// stloc s(valueInst)\n\t\t\t// if (comp(ldloc s == ldnull)) {\n\t\t\t//\t\tstloc v(fallbackInst)\n\t\t\t//      stloc s(ldloc v)\n\t\t\t// }\n\t\t\t// v must be single-assign and single-use.\n\t\t\tif (trueInst is Block trueBlock && trueBlock.Instructions.Count == 2\n\t\t\t\t&& trueBlock.Instructions[0].MatchStLoc(out var temporary, out fallbackValue)\n\t\t\t\t&& temporary.IsSingleDefinition && temporary.LoadCount == 1\n\t\t\t\t&& trueBlock.Instructions[1].MatchStLoc(stloc.Variable, out var useOfTemporary)\n\t\t\t\t&& useOfTemporary.MatchLdLoc(temporary))\n\t\t\t{\n\t\t\t\tcontext.Step(\"NullCoalescingTransform: with temporary variable (reference types)\", stloc);\n\t\t\t\tstloc.Value = new NullCoalescingInstruction(NullCoalescingKind.Ref, stloc.Value, fallbackValue);\n\t\t\t\tblock.Instructions.RemoveAt(pos + 1); // remove if instruction\n\t\t\t\tILInlining.InlineOneIfPossible(block, pos, InliningOptions.None, context);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\t// stloc obj(valueInst)\n\t\t\t// if (comp(ldloc obj == ldnull)) {\n\t\t\t//\t\tthrow(...)\n\t\t\t// }\n\t\t\t// =>\n\t\t\t// stloc obj(if.notnull(valueInst, throw(...)))\n\t\t\tif (context.Settings.ThrowExpressions && trueInst is Throw throwInst)\n\t\t\t{\n\t\t\t\tcontext.Step(\"NullCoalescingTransform (reference types + throw expression)\", stloc);\n\t\t\t\tthrowInst.resultType = StackType.O;\n\t\t\t\tstloc.Value = new NullCoalescingInstruction(NullCoalescingKind.Ref, stloc.Value, throwInst);\n\t\t\t\tblock.Instructions.RemoveAt(pos + 1); // remove if instruction\n\t\t\t\tILInlining.InlineOneIfPossible(block, pos, InliningOptions.None, context);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// stloc v(value)\n\t\t/// if (logic.not(call get_HasValue(ldloca v))) throw(...)\n\t\t/// ... Call(arg1, arg2, call GetValueOrDefault(ldloca v), arg4) ...\n\t\t/// =>\n\t\t/// ... Call(arg1, arg2, if.notnull(value, throw(...)), arg4) ...\n\t\t/// </summary>\n\t\tbool TransformThrowExpressionValueTypes(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\tif (pos + 2 >= block.Instructions.Count)\n\t\t\t\treturn false;\n\t\t\tif (!(block.Instructions[pos] is StLoc stloc))\n\t\t\t\treturn false;\n\t\t\tILVariable v = stloc.Variable;\n\t\t\tif (!(v.StoreCount == 1 && v.LoadCount == 0 && v.AddressCount == 2))\n\t\t\t\treturn false;\n\t\t\tif (!block.Instructions[pos + 1].MatchIfInstruction(out var condition, out var trueInst))\n\t\t\t\treturn false;\n\t\t\tif (!(Block.Unwrap(trueInst) is Throw throwInst))\n\t\t\t\treturn false;\n\t\t\tif (!condition.MatchLogicNot(out var arg))\n\t\t\t\treturn false;\n\t\t\tif (!(arg is CallInstruction call && NullableLiftingTransform.MatchHasValueCall(call, v)))\n\t\t\t\treturn false;\n\t\t\tvar throwInstParent = throwInst.Parent;\n\t\t\tvar throwInstChildIndex = throwInst.ChildIndex;\n\t\t\tvar nullCoalescingWithThrow = new NullCoalescingInstruction(\n\t\t\t\tNullCoalescingKind.NullableWithValueFallback,\n\t\t\t\tstloc.Value,\n\t\t\t\tthrowInst);\n\t\t\tvar resultType = NullableType.GetUnderlyingType(call.Method.DeclaringType).GetStackType();\n\t\t\tnullCoalescingWithThrow.UnderlyingResultType = resultType;\n\t\t\tvar result = ILInlining.FindLoadInNext(block.Instructions[pos + 2], v, nullCoalescingWithThrow, InliningOptions.None);\n\t\t\tif (result.Type == ILInlining.FindResultType.Found\n\t\t\t\t&& NullableLiftingTransform.MatchGetValueOrDefault(result.LoadInst.Parent, v))\n\t\t\t{\n\t\t\t\tcontext.Step(\"NullCoalescingTransform (value types + throw expression)\", stloc);\n\t\t\t\tthrowInst.resultType = resultType;\n\t\t\t\tresult.LoadInst.Parent.ReplaceWith(nullCoalescingWithThrow);\n\t\t\t\tblock.Instructions.RemoveRange(pos, 2); // remove store(s) and if instruction\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// reset the primary position (see remarks on ILInstruction.Parent)\n\t\t\t\tstloc.Value = stloc.Value;\n\t\t\t\tvar children = throwInstParent.Children;\n\t\t\t\tchildren[throwInstChildIndex] = throwInst;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/NullPropagationTransform.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Transform that converts code patterns like \"v != null ? v.M() : null\" to \"v?.M()\"\n\t/// </summary>\n\treadonly struct NullPropagationTransform\n\t{\n\t\tinternal static bool IsProtectedIfInst(IfInstruction ifInst)\n\t\t{\n\t\t\t// We exclude logic.and to avoid turning\n\t\t\t// \"logic.and(comp(interfaces != ldnull), call get_Count(interfaces))\"\n\t\t\t// into \"if ((interfaces?.Count ?? 0) != 0)\".\n\t\t\treturn ifInst != null\n\t\t\t\t&& (ifInst.MatchLogicAnd(out _, out _) || ifInst.MatchLogicOr(out _, out _))\n\t\t\t\t&& IfInstruction.IsInConditionSlot(ifInst);\n\t\t}\n\n\t\treadonly ILTransformContext context;\n\n\t\tpublic NullPropagationTransform(ILTransformContext context)\n\t\t{\n\t\t\tthis.context = context;\n\t\t}\n\n\t\tenum Mode\n\t\t{\n\t\t\t/// <summary>\n\t\t\t/// reference type or generic type (comparison is 'comp(ldloc(testedVar) == null)')\n\t\t\t/// </summary>\n\t\t\tReferenceType,\n\t\t\t/// <summary>\n\t\t\t/// nullable type, used by value (comparison is 'call get_HasValue(ldloca(testedVar))')\n\t\t\t/// </summary>\n\t\t\tNullableByValue,\n\t\t\t/// <summary>\n\t\t\t/// nullable type, used by reference (comparison is 'call get_HasValue(ldloc(testedVar))')\n\t\t\t/// </summary>\n\t\t\tNullableByReference,\n\t\t\t/// <summary>\n\t\t\t/// unconstrained generic type (see the pattern described in TransformNullPropagationOnUnconstrainedGenericExpression)\n\t\t\t/// </summary>\n\t\t\tUnconstrainedType,\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Check if \"condition ? trueInst : falseInst\" can be simplified using the null-conditional operator.\n\t\t/// Returns the replacement instruction, or null if no replacement is possible.\n\t\t/// </summary>\n\t\tinternal ILInstruction Run(ILInstruction condition, ILInstruction trueInst, ILInstruction falseInst)\n\t\t{\n\t\t\tDebug.Assert(context.Settings.NullPropagation);\n\t\t\tDebug.Assert(!condition.MatchLogicNot(out _), \"Caller should pass in positive condition\");\n\t\t\tif (condition is Comp comp && comp.Left.MatchLdLoc(out var testedVar) && comp.Right.MatchLdNull())\n\t\t\t{\n\t\t\t\tif (comp.LiftingKind != ComparisonLiftingKind.None)\n\t\t\t\t\treturn null;\n\t\t\t\tif (comp.Kind == ComparisonKind.Equality)\n\t\t\t\t{\n\t\t\t\t\t// testedVar == null ? trueInst : falseInst\n\t\t\t\t\treturn TryNullPropagation(testedVar, falseInst, trueInst, Mode.ReferenceType);\n\t\t\t\t}\n\t\t\t\telse if (comp.Kind == ComparisonKind.Inequality)\n\t\t\t\t{\n\t\t\t\t\treturn TryNullPropagation(testedVar, trueInst, falseInst, Mode.ReferenceType);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (NullableLiftingTransform.MatchHasValueCall(condition, out ILInstruction loadInst))\n\t\t\t{\n\t\t\t\t// loadInst.HasValue ? trueInst : falseInst\n\t\t\t\tif (loadInst.MatchLdLoca(out testedVar))\n\t\t\t\t{\n\t\t\t\t\treturn TryNullPropagation(testedVar, trueInst, falseInst, Mode.NullableByValue);\n\t\t\t\t}\n\t\t\t\telse if (loadInst.MatchLdLoc(out testedVar))\n\t\t\t\t{\n\t\t\t\t\treturn TryNullPropagation(testedVar, trueInst, falseInst, Mode.NullableByReference);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// testedVar != null ? nonNullInst : nullInst\n\t\t/// </summary>\n\t\tILInstruction TryNullPropagation(ILVariable testedVar, ILInstruction nonNullInst, ILInstruction nullInst,\n\t\t\tMode mode)\n\t\t{\n\t\t\tbool removedRewrapOrNullableCtor = false;\n\t\t\tif (NullableLiftingTransform.MatchNullableCtor(nonNullInst, out _, out var arg))\n\t\t\t{\n\t\t\t\tnonNullInst = arg;\n\t\t\t\tremovedRewrapOrNullableCtor = true;\n\t\t\t}\n\t\t\telse if (nonNullInst.MatchNullableRewrap(out arg))\n\t\t\t{\n\t\t\t\tnonNullInst = arg;\n\t\t\t\tremovedRewrapOrNullableCtor = true;\n\t\t\t}\n\t\t\tif (!IsValidAccessChain(testedVar, mode, nonNullInst, out var varLoad))\n\t\t\t\treturn null;\n\t\t\t// note: InferType will be accurate in this case because the access chain consists of calls and field accesses\n\t\t\tIType returnType = nonNullInst.InferType(context.TypeSystem);\n\t\t\tif (nullInst.MatchLdNull())\n\t\t\t{\n\t\t\t\tcontext.Step($\"Null propagation (mode={mode}, output=reference type)\", nonNullInst);\n\t\t\t\t// testedVar != null ? testedVar.AccessChain : null\n\t\t\t\t// => testedVar?.AccessChain\n\t\t\t\tIntroduceUnwrap(testedVar, varLoad, mode);\n\t\t\t\treturn new NullableRewrap(nonNullInst);\n\t\t\t}\n\t\t\telse if (nullInst.MatchDefaultValue(out var type) && type.IsKnownType(KnownTypeCode.NullableOfT))\n\t\t\t{\n\t\t\t\tcontext.Step($\"Null propagation (mode={mode}, output=value type)\", nonNullInst);\n\t\t\t\t// testedVar != null ? testedVar.AccessChain : default(T?)\n\t\t\t\t// => testedVar?.AccessChain\n\t\t\t\tIntroduceUnwrap(testedVar, varLoad, mode);\n\t\t\t\treturn new NullableRewrap(nonNullInst);\n\t\t\t}\n\t\t\telse if (!removedRewrapOrNullableCtor && NullableType.IsNonNullableValueType(returnType))\n\t\t\t{\n\t\t\t\tcontext.Step($\"Null propagation (mode={mode}, output=null coalescing)\", nonNullInst);\n\t\t\t\t// testedVar != null ? testedVar.AccessChain : nullInst\n\t\t\t\t// => testedVar?.AccessChain ?? nullInst\n\t\t\t\t// (only valid if AccessChain returns a non-nullable value)\n\t\t\t\tIntroduceUnwrap(testedVar, varLoad, mode);\n\t\t\t\treturn new NullCoalescingInstruction(\n\t\t\t\t\tNullCoalescingKind.NullableWithValueFallback,\n\t\t\t\t\tnew NullableRewrap(nonNullInst),\n\t\t\t\t\tnullInst\n\t\t\t\t) {\n\t\t\t\t\tUnderlyingResultType = nullInst.ResultType\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// if (x != null) x.AccessChain();\n\t\t/// => x?.AccessChain();\n\t\t/// </summary>\n\t\tinternal void RunStatements(Block block, int pos)\n\t\t{\n\t\t\tif (block.Instructions[pos] is IfInstruction ifInst && ifInst.FalseInst.MatchNop())\n\t\t\t{\n\t\t\t\tif (ifInst.Condition is Comp comp && comp.Kind == ComparisonKind.Inequality\n\t\t\t\t\t&& comp.Left.MatchLdLoc(out var testedVar) && comp.Right.MatchLdNull())\n\t\t\t\t{\n\t\t\t\t\tTryNullPropForVoidCall(testedVar, Mode.ReferenceType, ifInst.TrueInst as Block, ifInst);\n\t\t\t\t}\n\t\t\t\telse if (NullableLiftingTransform.MatchHasValueCall(ifInst.Condition, out ILInstruction arg))\n\t\t\t\t{\n\t\t\t\t\tif (arg.MatchLdLoca(out testedVar))\n\t\t\t\t\t{\n\t\t\t\t\t\tTryNullPropForVoidCall(testedVar, Mode.NullableByValue, ifInst.TrueInst as Block, ifInst);\n\t\t\t\t\t}\n\t\t\t\t\telse if (arg.MatchLdLoc(out testedVar))\n\t\t\t\t\t{\n\t\t\t\t\t\tTryNullPropForVoidCall(testedVar, Mode.NullableByReference, ifInst.TrueInst as Block, ifInst);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (TransformNullPropagationOnUnconstrainedGenericExpression(block, pos, out var testedVariable, out var nonNullInst, out var nullInst, out var endBlock))\n\t\t\t{\n\t\t\t\tvar parentInstruction = nonNullInst.Parent;\n\t\t\t\tvar replacement = TryNullPropagation(testedVariable, nonNullInst, nullInst, Mode.UnconstrainedType);\n\t\t\t\tif (replacement == null)\n\t\t\t\t\treturn;\n\t\t\t\tcontext.Step(\"TransformNullPropagationOnUnconstrainedGenericExpression\", block);\n\t\t\t\tswitch (parentInstruction)\n\t\t\t\t{\n\t\t\t\t\tcase StLoc stloc:\n\t\t\t\t\t\tstloc.Value = replacement;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase Leave leave:\n\t\t\t\t\t\tleave.Value = replacement;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// if this ever happens, the pattern checked by TransformNullPropagationOnUnconstrainedGenericExpression\n\t\t\t\t\t\t// has changed, but this part of the code was not properly adjusted.\n\t\t\t\t\t\tthrow new NotSupportedException();\n\t\t\t\t}\n\t\t\t\t// Remove the fallback conditions and blocks\n\t\t\t\tblock.Instructions.RemoveRange(pos + 1, 2);\n\t\t\t\t// if the endBlock is only reachable through the current block,\n\t\t\t\t// combine both blocks.\n\t\t\t\tif (endBlock?.IncomingEdgeCount == 1)\n\t\t\t\t{\n\t\t\t\t\tblock.Instructions.AddRange(endBlock.Instructions);\n\t\t\t\t\tblock.Instructions.RemoveAt(pos + 2);\n\t\t\t\t\tendBlock.Remove();\n\t\t\t\t}\n\t\t\t\tILInlining.InlineIfPossible(block, pos, context);\n\t\t\t}\n\t\t}\n\n\t\tvoid TryNullPropForVoidCall(ILVariable testedVar, Mode mode, Block body, IfInstruction ifInst)\n\t\t{\n\t\t\tif (body == null || body.Instructions.Count != 1)\n\t\t\t\treturn;\n\t\t\tvar bodyInst = body.Instructions[0];\n\t\t\tif (bodyInst.MatchNullableRewrap(out var arg))\n\t\t\t{\n\t\t\t\tbodyInst = arg;\n\t\t\t}\n\t\t\tif (!IsValidAccessChain(testedVar, mode, bodyInst, out var varLoad))\n\t\t\t\treturn;\n\t\t\tcontext.Step($\"Null-propagation (mode={mode}, output=void call)\", body);\n\t\t\t// if (testedVar != null) { testedVar.AccessChain(); }\n\t\t\t// => testedVar?.AccessChain();\n\t\t\tIntroduceUnwrap(testedVar, varLoad, mode);\n\t\t\tifInst.ReplaceWith(new NullableRewrap(\n\t\t\t\tbodyInst\n\t\t\t).WithILRange(ifInst));\n\t\t}\n\n\t\tbool IsValidAccessChain(ILVariable testedVar, Mode mode, ILInstruction inst, out ILInstruction finalLoad)\n\t\t{\n\t\t\tfinalLoad = null;\n\t\t\tint chainLength = 0;\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tif (IsValidEndOfChain())\n\t\t\t\t{\n\t\t\t\t\t// valid end of chain\n\t\t\t\t\tfinalLoad = inst;\n\t\t\t\t\treturn chainLength >= 1;\n\t\t\t\t}\n\t\t\t\telse if (inst.MatchLdFld(out var target, out _))\n\t\t\t\t{\n\t\t\t\t\tinst = target;\n\t\t\t\t}\n\t\t\t\telse if (inst.MatchLdFlda(out target, out var f))\n\t\t\t\t{\n\t\t\t\t\tif (target is AddressOf addressOf && f.DeclaringType.Kind == TypeKind.Struct)\n\t\t\t\t\t{\n\t\t\t\t\t\tinst = addressOf.Value;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tinst = target;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (inst is CallInstruction call && call.OpCode != OpCode.NewObj)\n\t\t\t\t{\n\t\t\t\t\tif (call.Arguments.Count == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif (call.Method.IsStatic && (!call.Method.IsExtensionMethod || !CanTransformToExtensionMethodCall(call, context)))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false; // only instance or extension methods can be called with ?. syntax\n\t\t\t\t\t}\n\t\t\t\t\tif (call.Method.IsAccessor && !IsGetter(call.Method))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false; // setter/adder/remover cannot be called with ?. syntax\n\t\t\t\t\t}\n\t\t\t\t\tinst = call.Arguments[0];\n\t\t\t\t\tif ((call.ConstrainedTo ?? call.Method.DeclaringType).IsReferenceType == false && inst.MatchAddressOf(out var arg, out _))\n\t\t\t\t\t{\n\t\t\t\t\t\tinst = arg;\n\t\t\t\t\t}\n\t\t\t\t\telse if (inst is LdObjIfRef ldObjIfRef)\n\t\t\t\t\t{\n\t\t\t\t\t\tinst = ldObjIfRef.Target;\n\t\t\t\t\t}\n\t\t\t\t\t// ensure the access chain does not contain any 'nullable.unwrap' that aren't directly part of the chain\n\t\t\t\t\tif (ArgumentsAfterFirstMayUnwrapNull(call.Arguments))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse if (inst is LdLen ldLen)\n\t\t\t\t{\n\t\t\t\t\tinst = ldLen.Array;\n\t\t\t\t}\n\t\t\t\telse if (inst is LdElema ldElema)\n\t\t\t\t{\n\t\t\t\t\tinst = ldElema.Array;\n\t\t\t\t\t// ensure the access chain does not contain any 'nullable.unwrap' that aren't directly part of the chain\n\t\t\t\t\tif (ldElema.Indices.Any(i => i.HasFlag(InstructionFlags.MayUnwrapNull)))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse if (inst is NullableUnwrap unwrap)\n\t\t\t\t{\n\t\t\t\t\tinst = unwrap.Argument;\n\t\t\t\t\tif (unwrap.RefInput && inst is AddressOf addressOf)\n\t\t\t\t\t{\n\t\t\t\t\t\tinst = addressOf.Value;\n\t\t\t\t\t}\n\t\t\t\t\t// The argument of the unwrap instruction cannot be the end of the chain, because this\n\t\t\t\t\t// would result in two null-conditional operators immediately following each other,\n\t\t\t\t\t// which is not valid in C#.\n\t\t\t\t\tif (IsValidEndOfChain())\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse if (inst is DynamicGetMemberInstruction dynGetMember)\n\t\t\t\t{\n\t\t\t\t\tinst = dynGetMember.Target;\n\t\t\t\t}\n\t\t\t\telse if (inst is DynamicInvokeMemberInstruction dynInvokeMember)\n\t\t\t\t{\n\t\t\t\t\tinst = dynInvokeMember.Arguments[0];\n\t\t\t\t\tif (ArgumentsAfterFirstMayUnwrapNull(dynInvokeMember.Arguments))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse if (inst is DynamicGetIndexInstruction dynGetIndex)\n\t\t\t\t{\n\t\t\t\t\tinst = dynGetIndex.Arguments[0];\n\t\t\t\t\tif (ArgumentsAfterFirstMayUnwrapNull(dynGetIndex.Arguments))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// unknown node -> invalid chain\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tchainLength++;\n\t\t\t}\n\n\t\t\tbool ArgumentsAfterFirstMayUnwrapNull(InstructionCollection<ILInstruction> arguments)\n\t\t\t{\n\t\t\t\t// ensure the access chain does not contain any 'nullable.unwrap' that aren't directly part of the chain\n\t\t\t\tfor (int i = 1; i < arguments.Count; ++i)\n\t\t\t\t{\n\t\t\t\t\tif (arguments[i].HasFlag(InstructionFlags.MayUnwrapNull))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tbool IsValidEndOfChain()\n\t\t\t{\n\t\t\t\tswitch (mode)\n\t\t\t\t{\n\t\t\t\t\tcase Mode.ReferenceType:\n\t\t\t\t\t\t// either reference type (expect: ldloc(testedVar)) or unconstrained generic type (expect: ldloca(testedVar)).\n\t\t\t\t\t\treturn inst.MatchLdLocRef(testedVar);\n\t\t\t\t\tcase Mode.NullableByValue:\n\t\t\t\t\t\treturn NullableLiftingTransform.MatchGetValueOrDefault(inst, testedVar);\n\t\t\t\t\tcase Mode.NullableByReference:\n\t\t\t\t\t\treturn NullableLiftingTransform.MatchGetValueOrDefault(inst, out ILInstruction arg)\n\t\t\t\t\t\t\t&& arg.MatchLdLoc(testedVar);\n\t\t\t\t\tcase Mode.UnconstrainedType:\n\t\t\t\t\t\t// unconstrained generic type (expect: ldloc(testedVar))\n\t\t\t\t\t\treturn inst.MatchLdLoc(testedVar) || (inst.MatchLdObjIfRef(out var testedVarLoad, out _) && testedVarLoad.MatchLdLoc(testedVar));\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(mode));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool CanTransformToExtensionMethodCall(CallInstruction call, ILTransformContext context)\n\t\t\t{\n\t\t\t\treturn context.CSharpResolver.CanTransformToExtensionMethodCall(call.Method);\n\t\t\t}\n\t\t}\n\n\t\tstatic bool IsGetter(IMethod method)\n\t\t{\n\t\t\treturn method.AccessorKind == System.Reflection.MethodSemanticsAttributes.Getter;\n\t\t}\n\n\t\tprivate void IntroduceUnwrap(ILVariable testedVar, ILInstruction varLoad, Mode mode)\n\t\t{\n\t\t\tvar oldParentChildren = varLoad.Parent.Children;\n\t\t\tvar oldChildIndex = varLoad.ChildIndex;\n\t\t\tILInstruction replacement;\n\t\t\tswitch (mode)\n\t\t\t{\n\t\t\t\tcase Mode.ReferenceType:\n\t\t\t\tcase Mode.UnconstrainedType:\n\t\t\t\t\t// Wrap varLoad in nullable.unwrap:\n\t\t\t\t\treplacement = new NullableUnwrap(varLoad.ResultType, varLoad, refInput: varLoad.ResultType == StackType.Ref);\n\t\t\t\t\tbreak;\n\t\t\t\tcase Mode.NullableByValue:\n\t\t\t\t\tDebug.Assert(NullableLiftingTransform.MatchGetValueOrDefault(varLoad, testedVar));\n\t\t\t\t\treplacement = new NullableUnwrap(\n\t\t\t\t\t\tvarLoad.ResultType,\n\t\t\t\t\t\tnew LdLoc(testedVar).WithILRange(varLoad.Children[0])\n\t\t\t\t\t).WithILRange(varLoad);\n\t\t\t\t\tbreak;\n\t\t\t\tcase Mode.NullableByReference:\n\t\t\t\t\treplacement = new NullableUnwrap(\n\t\t\t\t\t\tvarLoad.ResultType,\n\t\t\t\t\t\tnew LdLoc(testedVar).WithILRange(varLoad.Children[0]),\n\t\t\t\t\t\trefInput: true\n\t\t\t\t\t).WithILRange(varLoad);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(mode));\n\t\t\t}\n\t\t\toldParentChildren[oldChildIndex] = replacement;\n\t\t}\n\n\t\t// stloc target(targetInst)\n\t\t// stloc defaultTemporary(default.value type)\n\t\t// if (logic.not(comp.o(box `0(ldloc defaultTemporary) != ldnull))) Block fallbackBlock {\n\t\t// \tstloc defaultTemporary(ldobj type(ldloc target))\n\t\t// \tstloc target(ldloca defaultTemporary)\n\t\t// \tif (comp.o(ldloc defaultTemporary == ldnull)) Block fallbackBlock2 {\n\t\t// \t\tstloc resultTemporary(nullInst)\n\t\t// \t\tbr endBlock\n\t\t// \t}\n\t\t// }\n\t\t// stloc resultTemporary(constrained[type].call_instruction(ldloc target, ...))\n\t\t// br endBlock\n\t\t// =>\n\t\t// stloc resultTemporary(nullable.rewrap(constrained[type].call_instruction(nullable.unwrap(targetInst), ...)))\n\t\t//\n\t\t// -or-\n\t\t//\n\t\t// stloc target(targetInst)\n\t\t// stloc defaultTemporary(default.value type)\n\t\t// if (logic.not(comp.o(box `0(ldloc defaultTemporary) != ldnull))) Block fallbackBlock {\n\t\t// \tstloc defaultTemporary(ldobj type(ldloc target))\n\t\t// \tstloc target(ldloca defaultTemporary)\n\t\t// \tif (comp.o(ldloc defaultTemporary == ldnull)) Block fallbackBlock2 {\n\t\t// \t\tleave(nullInst)\n\t\t// \t}\n\t\t// }\n\t\t// leave (constrained[type].call_instruction(ldloc target, ...))\n\t\t// =>\n\t\t// leave (nullable.rewrap(constrained[type].call_instruction(nullable.unwrap(targetInst), ...)))\n\t\tprivate bool TransformNullPropagationOnUnconstrainedGenericExpression(Block block, int pos,\n\t\t\tout ILVariable target, out ILInstruction nonNullInst, out ILInstruction nullInst, out Block endBlock)\n\t\t{\n\t\t\ttarget = null;\n\t\t\tnonNullInst = null;\n\t\t\tnullInst = null;\n\t\t\tendBlock = null;\n\t\t\tif (pos + 3 >= block.Instructions.Count)\n\t\t\t\treturn false;\n\t\t\t// stloc target(...)\n\t\t\tif (!block.Instructions[pos].MatchStLoc(out target, out _))\n\t\t\t\treturn false;\n\t\t\tif (!(target.Kind == VariableKind.StackSlot && target.LoadCount == 2 && target.StoreCount == 2))\n\t\t\t\treturn false;\n\t\t\t// stloc defaultTemporary(default.value type)\n\t\t\tif (!(block.Instructions[pos + 1].MatchStLoc(out var defaultTemporary, out var defaultExpression) && defaultExpression.MatchDefaultValue(out var type)))\n\t\t\t\treturn false;\n\t\t\t// In the above pattern the defaultTemporary variable is used two times in stloc and ldloc instructions and once in a ldloca instruction\n\t\t\tif (!(defaultTemporary.Kind == VariableKind.Local && defaultTemporary.LoadCount == 2 && defaultTemporary.StoreCount == 2 && defaultTemporary.AddressCount == 1))\n\t\t\t\treturn false;\n\t\t\t// if (logic.not(comp.o(box `0(ldloc defaultTemporary) != ldnull))) Block fallbackBlock\n\t\t\tif (!(block.Instructions[pos + 2].MatchIfInstruction(out var condition, out var fallbackBlock1) && condition.MatchCompEqualsNull(out var arg) && arg.MatchLdLoc(defaultTemporary)))\n\t\t\t\treturn false;\n\t\t\tif (!MatchStLocResultTemporary(block, pos, type, target, defaultTemporary, fallbackBlock1, out nonNullInst, out nullInst, out endBlock)\n\t\t\t\t&& !MatchLeaveResult(block, pos, type, target, defaultTemporary, fallbackBlock1, out nonNullInst, out nullInst))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\t// stloc resultTemporary(constrained[type].call_instruction(ldloc target, ...))\n\t\t// br endBlock\n\t\tprivate bool MatchStLocResultTemporary(Block block, int pos, IType type, ILVariable target, ILVariable defaultTemporary, ILInstruction fallbackBlock, out ILInstruction nonNullInst, out ILInstruction nullInst, out Block endBlock)\n\t\t{\n\t\t\tendBlock = null;\n\t\t\tnonNullInst = null;\n\t\t\tnullInst = null;\n\n\t\t\tif (pos + 4 >= block.Instructions.Count)\n\t\t\t\treturn false;\n\t\t\t// stloc resultTemporary(constrained[type].call_instruction(ldloc target, ...))\n\t\t\tif (!(block.Instructions[pos + 3].MatchStLoc(out var resultTemporary, out nonNullInst)))\n\t\t\t\treturn false;\n\t\t\t// br endBlock\n\t\t\tif (!(block.Instructions[pos + 4].MatchBranch(out endBlock)))\n\t\t\t\treturn false;\n\t\t\t// Analyze Block fallbackBlock\n\t\t\tif (!(fallbackBlock is Block b && IsFallbackBlock(b, type, target, defaultTemporary, resultTemporary, endBlock, out nullInst)))\n\t\t\t\treturn false;\n\n\t\t\treturn true;\n\t\t}\n\n\t\tprivate bool MatchLeaveResult(Block block, int pos, IType type, ILVariable target, ILVariable defaultTemporary, ILInstruction fallbackBlock, out ILInstruction nonNullInst, out ILInstruction nullInst)\n\t\t{\n\t\t\tnonNullInst = null;\n\t\t\tnullInst = null;\n\n\t\t\t// leave (constrained[type].call_instruction(ldloc target, ...))\n\t\t\tif (!(block.Instructions[pos + 3] is Leave leave && leave.IsLeavingFunction))\n\t\t\t\treturn false;\n\t\t\tnonNullInst = leave.Value;\n\t\t\t// Analyze Block fallbackBlock\n\t\t\tif (!(fallbackBlock is Block b && IsFallbackBlock(b, type, target, defaultTemporary, null, leave.TargetContainer, out nullInst)))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\t// Block fallbackBlock {\n\t\t// \tstloc defaultTemporary(ldobj type(ldloc target))\n\t\t// \tstloc target(ldloca defaultTemporary)\n\t\t// \tif (comp.o(ldloc defaultTemporary == ldnull)) Block fallbackBlock {\n\t\t// \t\tstloc resultTemporary(ldnull)\n\t\t// \t\tbr endBlock\n\t\t// \t}\n\t\t// }\n\t\tprivate bool IsFallbackBlock(Block block, IType type, ILVariable target, ILVariable defaultTemporary, ILVariable resultTemporary, ILInstruction endBlockOrLeaveContainer, out ILInstruction nullInst)\n\t\t{\n\t\t\tnullInst = null;\n\t\t\tif (!(block.Instructions.Count == 3))\n\t\t\t\treturn false;\n\t\t\t// stloc defaultTemporary(ldobj type(ldloc target))\n\t\t\tif (!(block.Instructions[0].MatchStLoc(defaultTemporary, out var value)))\n\t\t\t\treturn false;\n\t\t\tif (!(value.MatchLdObj(out var inst, out var t) && type.Equals(t) && inst.MatchLdLoc(target)))\n\t\t\t\treturn false;\n\t\t\t// stloc target(ldloca defaultTemporary)\n\t\t\tif (!(block.Instructions[1].MatchStLoc(target, out var defaultAddress) && defaultAddress.MatchLdLoca(defaultTemporary)))\n\t\t\t\treturn false;\n\t\t\t// if (comp.o(ldloc defaultTemporary == ldnull)) Block fallbackBlock\n\t\t\tif (!(block.Instructions[2].MatchIfInstruction(out var condition, out var tmp) && condition.MatchCompEqualsNull(out var arg) && arg.MatchLdLoc(defaultTemporary)))\n\t\t\t\treturn false;\n\t\t\t// Block fallbackBlock {\n\t\t\t//   stloc resultTemporary(nullInst)\n\t\t\t//   br endBlock\n\t\t\t// }\n\t\t\tvar fallbackInst = Block.Unwrap(tmp);\n\t\t\tif (fallbackInst is Block fallbackBlock && endBlockOrLeaveContainer is Block endBlock)\n\t\t\t{\n\t\t\t\tif (!(fallbackBlock.Instructions.Count == 2))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!fallbackBlock.Instructions[0].MatchStLoc(resultTemporary, out nullInst))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!fallbackBlock.Instructions[1].MatchBranch(endBlock))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (!(fallbackInst is Leave fallbackLeave && endBlockOrLeaveContainer is BlockContainer leaveContainer\n\t\t\t\t\t&& fallbackLeave.TargetContainer == leaveContainer && !fallbackLeave.Value.MatchNop()))\n\t\t\t\t\treturn false;\n\t\t\t\tnullInst = fallbackLeave.Value;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic class NullPropagationStatementTransform : IStatementTransform\n\t{\n\t\tpublic void Run(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.NullPropagation)\n\t\t\t\treturn;\n\t\t\tnew NullPropagationTransform(context).RunStatements(block, pos);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs",
    "content": "// Copyright (c) 2017 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Nullable lifting gets run in two places:\n\t///  * the usual form looks at an if-else, and runs within the ExpressionTransforms.\n\t///  * the NullableLiftingBlockTransform handles the cases where Roslyn generates\n\t///    two 'ret' statements for the null/non-null cases of a lifted operator.\n\t/// \n\t/// The transform handles the following languages constructs:\n\t///  * lifted conversions\n\t///  * lifted unary and binary operators\n\t///  * lifted comparisons\n\t///  * the ?? operator with type Nullable{T} on the left-hand-side\n\t///  * the ?. operator (via NullPropagationTransform)\n\t/// </summary>\n\tstruct NullableLiftingTransform\n\t{\n\t\treadonly ILTransformContext context;\n\t\tList<ILVariable> nullableVars;\n\n\t\tpublic NullableLiftingTransform(ILTransformContext context)\n\t\t{\n\t\t\tthis.context = context;\n\t\t\tthis.nullableVars = null;\n\t\t}\n\n\t\t#region Run\n\t\t/// <summary>\n\t\t/// Main entry point into the normal code path of this transform.\n\t\t/// Called by expression transform.\n\t\t/// </summary>\n\t\tpublic bool Run(IfInstruction ifInst)\n\t\t{\n\t\t\tvar lifted = Lift(ifInst, ifInst.Condition, ifInst.TrueInst, ifInst.FalseInst);\n\t\t\tif (lifted != null)\n\t\t\t{\n\t\t\t\tifInst.ReplaceWith(lifted);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// VS2017.8 / Roslyn 2.9 started optimizing some cases of\n\t\t///   \"a.GetValueOrDefault() == b.GetValueOrDefault() &amp;&amp; (a.HasValue &amp; b.HasValue)\"\n\t\t/// to\n\t\t///   \"(a.GetValueOrDefault() == b.GetValueOrDefault()) &amp; (a.HasValue &amp; b.HasValue)\"\n\t\t/// so this secondary entry point analyses logic.and as-if it was a short-circuiting &amp;&amp;.\n\t\t/// </summary>\n\t\tpublic bool Run(BinaryNumericInstruction bni)\n\t\t{\n\t\t\tDebug.Assert(!bni.IsLifted && bni.Operator == BinaryNumericOperator.BitAnd);\n\t\t\t// caller ensures that bni.Left/bni.Right are booleans\n\t\t\tvar lifted = Lift(bni, bni.Left, bni.Right, new LdcI4(0));\n\t\t\tif (lifted != null)\n\t\t\t{\n\t\t\t\tbni.ReplaceWith(lifted);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// VS2022.10 / Roslyn 4.10.0 adds an optimization that turns\n\t\t/// a == 42 into a.GetValueOrDefault() == 42 without any HasValue check.\n\t\t/// </summary>\n\t\tpublic void Run(Comp comp)\n\t\t{\n\t\t\tif (!comp.IsLifted && comp.Kind.IsEqualityOrInequality())\n\t\t\t{\n\t\t\t\tvar left = comp.Left;\n\t\t\t\tvar right = comp.Right;\n\t\t\t\tif (MatchGetValueOrDefault(left, out ILInstruction arg)\n\t\t\t\t\t&& right.MatchLdcI(out var value) && value != 0)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"comp(a.GetValueOrDefault() == const) -> comp.lifted(a == const)\", comp);\n\t\t\t\t\tcomp.LiftingKind = ComparisonLiftingKind.CSharp;\n\t\t\t\t\tcomp.Left = new LdObj(arg, ((Call)left).Method.DeclaringType);\n\t\t\t\t}\n\t\t\t\telse if (MatchGetValueOrDefault(right, out arg)\n\t\t\t\t\t&& left.MatchLdcI(out value) && value != 0)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"comp(const == a.GetValueOrDefault()) -> comp.lifted(const == a)\", comp);\n\t\t\t\t\tcomp.LiftingKind = ComparisonLiftingKind.CSharp;\n\t\t\t\t\tcomp.Right = new LdObj(arg, ((Call)right).Method.DeclaringType);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic bool RunStatements(Block block, int pos)\n\t\t{\n\t\t\t// e.g.:\n\t\t\t//  if (!condition) Block {\n\t\t\t//    leave IL_0000 (default.value System.Nullable`1[[System.Int64]])\n\t\t\t//  }\n\t\t\t//  leave IL_0000 (newobj .ctor(exprToLift))\n\t\t\tif (pos != block.Instructions.Count - 2)\n\t\t\t\treturn false;\n\t\t\tif (!(block.Instructions[pos] is IfInstruction ifInst))\n\t\t\t\treturn false;\n\t\t\tif (!(Block.Unwrap(ifInst.TrueInst) is Leave thenLeave))\n\t\t\t\treturn false;\n\t\t\tif (!ifInst.FalseInst.MatchNop())\n\t\t\t\treturn false;\n\n\t\t\tif (!(block.Instructions[pos + 1] is Leave elseLeave))\n\t\t\t\treturn false;\n\t\t\tif (elseLeave.TargetContainer != thenLeave.TargetContainer)\n\t\t\t\treturn false;\n\n\t\t\tvar lifted = Lift(ifInst, ifInst.Condition, thenLeave.Value, elseLeave.Value);\n\t\t\tif (lifted != null)\n\t\t\t{\n\t\t\t\tthenLeave.Value = lifted;\n\t\t\t\tifInst.ReplaceWith(thenLeave);\n\t\t\t\tblock.Instructions.Remove(elseLeave);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\t#endregion\n\n\t\t#region AnalyzeCondition\n\t\tbool AnalyzeCondition(ILInstruction condition)\n\t\t{\n\t\t\tif (MatchHasValueCall(condition, out ILVariable v))\n\t\t\t{\n\t\t\t\tif (nullableVars == null)\n\t\t\t\t\tnullableVars = new List<ILVariable>();\n\t\t\t\tnullableVars.Add(v);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (condition is BinaryNumericInstruction bitand)\n\t\t\t{\n\t\t\t\tif (!(bitand.Operator == BinaryNumericOperator.BitAnd && bitand.ResultType == StackType.I4))\n\t\t\t\t\treturn false;\n\t\t\t\treturn AnalyzeCondition(bitand.Left) && AnalyzeCondition(bitand.Right);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tbool AnalyzeNegatedCondition(ILInstruction condition)\n\t\t{\n\t\t\treturn condition.MatchLogicNot(out var arg) && AnalyzeCondition(arg);\n\t\t}\n\t\t#endregion\n\n\t\t#region Main lifting logic\n\t\t/// <summary>\n\t\t/// Main entry point for lifting; called by both the expression-transform\n\t\t/// and the block transform.\n\t\t/// </summary>\n\t\tILInstruction Lift(ILInstruction ifInst, ILInstruction condition, ILInstruction trueInst, ILInstruction falseInst)\n\t\t{\n\t\t\t// ifInst is usually the IfInstruction to which condition belongs;\n\t\t\t// but can also be a BinaryNumericInstruction.\n\t\t\twhile (condition.MatchLogicNot(out var arg))\n\t\t\t{\n\t\t\t\tcondition = arg;\n\t\t\t\tExtensionMethods.Swap(ref trueInst, ref falseInst);\n\t\t\t}\n\t\t\tif (context.Settings.NullPropagation && !NullPropagationTransform.IsProtectedIfInst(ifInst as IfInstruction))\n\t\t\t{\n\t\t\t\tvar nullPropagated = new NullPropagationTransform(context)\n\t\t\t\t\t.Run(condition, trueInst, falseInst)?.WithILRange(ifInst);\n\t\t\t\tif (nullPropagated != null)\n\t\t\t\t\treturn nullPropagated;\n\t\t\t}\n\t\t\tif (!context.Settings.LiftNullables)\n\t\t\t\treturn null;\n\t\t\tif (AnalyzeCondition(condition))\n\t\t\t{\n\t\t\t\t// (v1 != null && ... && vn != null) ? trueInst : falseInst\n\t\t\t\t// => normal lifting\n\t\t\t\treturn LiftNormal(trueInst, falseInst)?.WithILRange(ifInst);\n\t\t\t}\n\t\t\tif (MatchCompOrDecimal(condition, out var comp))\n\t\t\t{\n\t\t\t\t// This might be a C#-style lifted comparison\n\t\t\t\t// (C# checks the underlying value before checking the HasValue bits)\n\t\t\t\tif (comp.Kind.IsEqualityOrInequality())\n\t\t\t\t{\n\t\t\t\t\t// for equality/inequality, the HasValue bits must also compare equal/inequal\n\t\t\t\t\tif (comp.Kind == ComparisonKind.Inequality)\n\t\t\t\t\t{\n\t\t\t\t\t\t// handle inequality by swapping one last time\n\t\t\t\t\t\tExtensionMethods.Swap(ref trueInst, ref falseInst);\n\t\t\t\t\t}\n\t\t\t\t\tif (falseInst.MatchLdcI4(0))\n\t\t\t\t\t{\n\t\t\t\t\t\t// (a.GetValueOrDefault() == b.GetValueOrDefault()) ? (a.HasValue == b.HasValue) : false\n\t\t\t\t\t\t// => a == b\n\t\t\t\t\t\treturn LiftCSharpEqualityComparison(comp, ComparisonKind.Equality, trueInst)\n\t\t\t\t\t\t\t?? LiftCSharpUserEqualityComparison(comp, ComparisonKind.Equality, trueInst);\n\t\t\t\t\t}\n\t\t\t\t\telse if (falseInst.MatchLdcI4(1))\n\t\t\t\t\t{\n\t\t\t\t\t\t// (a.GetValueOrDefault() == b.GetValueOrDefault()) ? (a.HasValue != b.HasValue) : true\n\t\t\t\t\t\t// => a != b\n\t\t\t\t\t\treturn LiftCSharpEqualityComparison(comp, ComparisonKind.Inequality, trueInst)\n\t\t\t\t\t\t\t?? LiftCSharpUserEqualityComparison(comp, ComparisonKind.Inequality, trueInst);\n\t\t\t\t\t}\n\t\t\t\t\telse if (!comp.IsLifted && IsGenericNewPattern(comp.Left, comp.Right, trueInst, falseInst))\n\t\t\t\t\t{\n\t\t\t\t\t\t// (default(T) == null) ? Activator.CreateInstance<T>() : default(T)\n\t\t\t\t\t\t// => Activator.CreateInstance<T>()\n\t\t\t\t\t\treturn trueInst;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (!comp.IsLifted)\n\t\t\t\t{\n\t\t\t\t\t// Not (in)equality, but one of < <= > >=.\n\t\t\t\t\t// Returns false unless all HasValue bits are true.\n\t\t\t\t\tif (falseInst.MatchLdcI4(0) && AnalyzeCondition(trueInst))\n\t\t\t\t\t{\n\t\t\t\t\t\t// comp(lhs, rhs) ? (v1 != null && ... && vn != null) : false\n\t\t\t\t\t\t// => comp.lifted[C#](lhs, rhs)\n\t\t\t\t\t\treturn LiftCSharpComparison(comp, comp.Kind);\n\t\t\t\t\t}\n\t\t\t\t\tif (trueInst.MatchLdcI4(0) && AnalyzeCondition(falseInst))\n\t\t\t\t\t{\n\t\t\t\t\t\t// comp(lhs, rhs) ? false : (v1 != null && ... && vn != null)\n\t\t\t\t\t\treturn LiftCSharpComparison(comp, comp.Kind.Negate());\n\t\t\t\t\t}\n\t\t\t\t\tif (falseInst.MatchLdcI4(1) && AnalyzeNegatedCondition(trueInst))\n\t\t\t\t\t{\n\t\t\t\t\t\t// comp(lhs, rhs) ? !(v1 != null && ... && vn != null) : true\n\t\t\t\t\t\t// => !comp.lifted[C#](lhs, rhs)\n\t\t\t\t\t\tILInstruction result = LiftCSharpComparison(comp, comp.Kind);\n\t\t\t\t\t\tif (result == null)\n\t\t\t\t\t\t\treturn result;\n\t\t\t\t\t\treturn Comp.LogicNot(result);\n\t\t\t\t\t}\n\t\t\t\t\tif (trueInst.MatchLdcI4(1) && AnalyzeNegatedCondition(falseInst))\n\t\t\t\t\t{\n\t\t\t\t\t\t// comp(lhs, rhs) ? true : !(v1 != null && ... && vn != null)\n\t\t\t\t\t\tILInstruction result = LiftCSharpComparison(comp, comp.Kind.Negate());\n\t\t\t\t\t\tif (result == null)\n\t\t\t\t\t\t\treturn result;\n\t\t\t\t\t\treturn Comp.LogicNot(result);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tILVariable v;\n\t\t\t// Handle equality comparisons with bool?:\n\t\t\tif (MatchGetValueOrDefault(condition, out v)\n\t\t\t\t&& NullableType.GetUnderlyingType(v.Type).IsKnownType(KnownTypeCode.Boolean))\n\t\t\t{\n\t\t\t\tif (MatchHasValueCall(trueInst, v) && falseInst.MatchLdcI4(0))\n\t\t\t\t{\n\t\t\t\t\t// v.GetValueOrDefault() ? v.HasValue : false\n\t\t\t\t\t// ==> v == true\n\t\t\t\t\tcontext.Step(\"NullableLiftingTransform: v == true\", ifInst);\n\t\t\t\t\treturn new Comp(ComparisonKind.Equality, ComparisonLiftingKind.CSharp,\n\t\t\t\t\t\tStackType.I4, Sign.None,\n\t\t\t\t\t\tnew LdLoc(v).WithILRange(trueInst),\n\t\t\t\t\t\tnew LdcI4(1).WithILRange(falseInst)\n\t\t\t\t\t).WithILRange(ifInst);\n\t\t\t\t}\n\t\t\t\telse if (trueInst.MatchLdcI4(0) && MatchHasValueCall(falseInst, v))\n\t\t\t\t{\n\t\t\t\t\t// v.GetValueOrDefault() ? false : v.HasValue\n\t\t\t\t\t// ==> v == false\n\t\t\t\t\tcontext.Step(\"NullableLiftingTransform: v == false\", ifInst);\n\t\t\t\t\treturn new Comp(ComparisonKind.Equality, ComparisonLiftingKind.CSharp,\n\t\t\t\t\t\tStackType.I4, Sign.None,\n\t\t\t\t\t\tnew LdLoc(v).WithILRange(falseInst),\n\t\t\t\t\t\ttrueInst // LdcI4(0)\n\t\t\t\t\t).WithILRange(ifInst);\n\t\t\t\t}\n\t\t\t\telse if (MatchNegatedHasValueCall(trueInst, v) && falseInst.MatchLdcI4(1))\n\t\t\t\t{\n\t\t\t\t\t// v.GetValueOrDefault() ? !v.HasValue : true\n\t\t\t\t\t// ==> v != true\n\t\t\t\t\tcontext.Step(\"NullableLiftingTransform: v != true\", ifInst);\n\t\t\t\t\treturn new Comp(ComparisonKind.Inequality, ComparisonLiftingKind.CSharp,\n\t\t\t\t\t\tStackType.I4, Sign.None,\n\t\t\t\t\t\tnew LdLoc(v).WithILRange(trueInst),\n\t\t\t\t\t\tfalseInst // LdcI4(1)\n\t\t\t\t\t).WithILRange(ifInst);\n\t\t\t\t}\n\t\t\t\telse if (trueInst.MatchLdcI4(1) && MatchNegatedHasValueCall(falseInst, v))\n\t\t\t\t{\n\t\t\t\t\t// v.GetValueOrDefault() ? true : !v.HasValue\n\t\t\t\t\t// ==> v != false\n\t\t\t\t\tcontext.Step(\"NullableLiftingTransform: v != false\", ifInst);\n\t\t\t\t\treturn new Comp(ComparisonKind.Inequality, ComparisonLiftingKind.CSharp,\n\t\t\t\t\t\tStackType.I4, Sign.None,\n\t\t\t\t\t\tnew LdLoc(v).WithILRange(falseInst),\n\t\t\t\t\t\tnew LdcI4(0).WithILRange(trueInst)\n\t\t\t\t\t).WithILRange(ifInst);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Handle & and | on bool?:\n\t\t\tif (trueInst.MatchLdLoc(out v))\n\t\t\t{\n\t\t\t\tif (MatchNullableCtor(falseInst, out var utype, out var arg)\n\t\t\t\t\t&& utype.IsKnownType(KnownTypeCode.Boolean) && arg.MatchLdcI4(0))\n\t\t\t\t{\n\t\t\t\t\t// condition ? v : (bool?)false\n\t\t\t\t\t// => condition & v\n\t\t\t\t\tcontext.Step(\"NullableLiftingTransform: 3vl.bool.and(bool, bool?)\", ifInst);\n\t\t\t\t\treturn new ThreeValuedBoolAnd(condition, trueInst).WithILRange(ifInst);\n\t\t\t\t}\n\t\t\t\tif (falseInst.MatchLdLoc(out var v2))\n\t\t\t\t{\n\t\t\t\t\t// condition ? v : v2\n\t\t\t\t\tif (MatchThreeValuedLogicConditionPattern(condition, out var nullable1, out var nullable2))\n\t\t\t\t\t{\n\t\t\t\t\t\t// (nullable1.GetValueOrDefault() || (!nullable2.GetValueOrDefault() && !nullable1.HasValue)) ? v : v2\n\t\t\t\t\t\tif (v == nullable1 && v2 == nullable2)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontext.Step(\"NullableLiftingTransform: 3vl.bool.or(bool?, bool?)\", ifInst);\n\t\t\t\t\t\t\treturn new ThreeValuedBoolOr(trueInst, falseInst).WithILRange(ifInst);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (v == nullable2 && v2 == nullable1)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontext.Step(\"NullableLiftingTransform: 3vl.bool.and(bool?, bool?)\", ifInst);\n\t\t\t\t\t\t\treturn new ThreeValuedBoolAnd(falseInst, trueInst).WithILRange(ifInst);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (falseInst.MatchLdLoc(out v))\n\t\t\t{\n\t\t\t\tif (MatchNullableCtor(trueInst, out var utype, out var arg)\n\t\t\t\t\t&& utype.IsKnownType(KnownTypeCode.Boolean) && arg.MatchLdcI4(1))\n\t\t\t\t{\n\t\t\t\t\t// condition ? (bool?)true : v\n\t\t\t\t\t// => condition | v\n\t\t\t\t\tcontext.Step(\"NullableLiftingTransform: 3vl.logic.or(bool, bool?)\", ifInst);\n\t\t\t\t\treturn new ThreeValuedBoolOr(condition, falseInst).WithILRange(ifInst);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tprivate bool IsGenericNewPattern(ILInstruction compLeft, ILInstruction compRight, ILInstruction trueInst, ILInstruction falseInst)\n\t\t{\n\t\t\t// (default(T) == null) ? Activator.CreateInstance<T>() : default(T)\n\t\t\treturn falseInst.MatchDefaultValue(out var type) &&\n\t\t\t\t(trueInst is Call c && c.Method.FullName == \"System.Activator.CreateInstance\" && c.Method.TypeArguments.Count == 1) &&\n\t\t\t\ttype.Kind == TypeKind.TypeParameter &&\n\t\t\t\tcompLeft.MatchDefaultValue(out var type2) &&\n\t\t\t\ttype.Equals(type2) &&\n\t\t\t\tcompRight.MatchLdNull();\n\t\t}\n\n\t\tprivate bool MatchThreeValuedLogicConditionPattern(ILInstruction condition, out ILVariable nullable1, out ILVariable nullable2)\n\t\t{\n\t\t\t// Try to match: nullable1.GetValueOrDefault() || (!nullable2.GetValueOrDefault() && !nullable1.HasValue)\n\t\t\tnullable1 = null;\n\t\t\tnullable2 = null;\n\t\t\tif (!condition.MatchLogicOr(out var lhs, out var rhs))\n\t\t\t\treturn false;\n\t\t\tif (!MatchGetValueOrDefault(lhs, out nullable1))\n\t\t\t\treturn false;\n\t\t\tif (!NullableType.GetUnderlyingType(nullable1.Type).IsKnownType(KnownTypeCode.Boolean))\n\t\t\t\treturn false;\n\t\t\tif (!rhs.MatchLogicAnd(out lhs, out rhs))\n\t\t\t\treturn false;\n\t\t\tif (!lhs.MatchLogicNot(out var arg))\n\t\t\t\treturn false;\n\t\t\tif (!MatchGetValueOrDefault(arg, out nullable2))\n\t\t\t\treturn false;\n\t\t\tif (!NullableType.GetUnderlyingType(nullable2.Type).IsKnownType(KnownTypeCode.Boolean))\n\t\t\t\treturn false;\n\t\t\tif (!rhs.MatchLogicNot(out arg))\n\t\t\t\treturn false;\n\t\t\treturn MatchHasValueCall(arg, nullable1);\n\t\t}\n\t\t#endregion\n\n\t\t#region CSharpComp\n\t\tstatic bool MatchCompOrDecimal(ILInstruction inst, out CompOrDecimal result)\n\t\t{\n\t\t\tresult = default(CompOrDecimal);\n\t\t\tresult.Instruction = inst;\n\t\t\tif (inst is Comp comp)\n\t\t\t{\n\t\t\t\tresult.Kind = comp.Kind;\n\t\t\t\tresult.Left = comp.Left;\n\t\t\t\tresult.Right = comp.Right;\n\t\t\t\tresult.IsLifted = comp.IsLifted;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (inst is Call call && call.Method.IsOperator && call.Arguments.Count == 2 && !call.IsLifted)\n\t\t\t{\n\t\t\t\tswitch (call.Method.Name)\n\t\t\t\t{\n\t\t\t\t\tcase \"op_Equality\":\n\t\t\t\t\t\tresult.Kind = ComparisonKind.Equality;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"op_Inequality\":\n\t\t\t\t\t\tresult.Kind = ComparisonKind.Inequality;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"op_LessThan\":\n\t\t\t\t\t\tresult.Kind = ComparisonKind.LessThan;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"op_LessThanOrEqual\":\n\t\t\t\t\t\tresult.Kind = ComparisonKind.LessThanOrEqual;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"op_GreaterThan\":\n\t\t\t\t\t\tresult.Kind = ComparisonKind.GreaterThan;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"op_GreaterThanOrEqual\":\n\t\t\t\t\t\tresult.Kind = ComparisonKind.GreaterThanOrEqual;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tresult.Left = call.Arguments[0];\n\t\t\t\tresult.Right = call.Arguments[1];\n\t\t\t\treturn call.Method.DeclaringType.IsKnownType(KnownTypeCode.Decimal);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Represents either non-lifted IL `Comp` or a call to one of the (non-lifted) 6 comparison operators on `System.Decimal`.\n\t\t/// </summary>\n\t\tstruct CompOrDecimal\n\t\t{\n\t\t\tpublic ILInstruction Instruction;\n\t\t\tpublic ComparisonKind Kind;\n\t\t\tpublic ILInstruction Left;\n\t\t\tpublic ILInstruction Right;\n\t\t\tpublic bool IsLifted;\n\n\t\t\tpublic IType LeftExpectedType {\n\t\t\t\tget {\n\t\t\t\t\tif (Instruction is Call call)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn call.Method.Parameters[0].Type;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn SpecialType.UnknownType;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic IType RightExpectedType {\n\t\t\t\tget {\n\t\t\t\t\tif (Instruction is Call call)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn call.Method.Parameters[1].Type;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn SpecialType.UnknownType;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tinternal ILInstruction MakeLifted(ComparisonKind newComparisonKind, ILInstruction left, ILInstruction right)\n\t\t\t{\n\t\t\t\tif (Instruction is Comp comp)\n\t\t\t\t{\n\t\t\t\t\treturn new Comp(newComparisonKind, ComparisonLiftingKind.CSharp, comp.InputType, comp.Sign, left, right).WithILRange(Instruction);\n\t\t\t\t}\n\t\t\t\telse if (Instruction is Call call)\n\t\t\t\t{\n\t\t\t\t\tIMethod method;\n\t\t\t\t\tif (newComparisonKind == Kind)\n\t\t\t\t\t{\n\t\t\t\t\t\tmethod = call.Method;\n\t\t\t\t\t}\n\t\t\t\t\telse if (newComparisonKind == ComparisonKind.Inequality && call.Method.Name == \"op_Equality\")\n\t\t\t\t\t{\n\t\t\t\t\t\tmethod = call.Method.DeclaringType.GetMethods(m => m.Name == \"op_Inequality\")\n\t\t\t\t\t\t\t.FirstOrDefault(m => ParameterListComparer.Instance.Equals(m.Parameters, call.Method.Parameters));\n\t\t\t\t\t\tif (method == null)\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\treturn new Call(CSharp.Resolver.CSharpOperators.LiftUserDefinedOperator(method)) {\n\t\t\t\t\t\tArguments = { left, right },\n\t\t\t\t\t\tConstrainedTo = call.ConstrainedTo,\n\t\t\t\t\t\tILStackWasEmpty = call.ILStackWasEmpty,\n\t\t\t\t\t\tIsTail = call.IsTail\n\t\t\t\t\t}.WithILRange(call);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Lift...Comparison\n\t\tILInstruction LiftCSharpEqualityComparison(CompOrDecimal valueComp, ComparisonKind newComparisonKind, ILInstruction hasValueTest)\n\t\t{\n\t\t\tDebug.Assert(newComparisonKind.IsEqualityOrInequality());\n\t\t\tbool hasValueTestNegated = false;\n\t\t\twhile (hasValueTest.MatchLogicNot(out var arg))\n\t\t\t{\n\t\t\t\thasValueTest = arg;\n\t\t\t\thasValueTestNegated = !hasValueTestNegated;\n\t\t\t}\n\t\t\t// The HasValue comparison must be the same operator as the Value comparison.\n\t\t\tif (hasValueTest is Comp hasValueComp)\n\t\t\t{\n\t\t\t\tif (valueComp.IsLifted || hasValueComp.IsLifted)\n\t\t\t\t\treturn null;\n\t\t\t\t// Comparing two nullables: HasValue comparison must be the same operator as the Value comparison\n\t\t\t\tif ((hasValueTestNegated ? hasValueComp.Kind.Negate() : hasValueComp.Kind) != newComparisonKind)\n\t\t\t\t\treturn null;\n\t\t\t\tif (!MatchHasValueCall(hasValueComp.Left, out ILVariable leftVar))\n\t\t\t\t\treturn null;\n\t\t\t\tif (!MatchHasValueCall(hasValueComp.Right, out ILVariable rightVar))\n\t\t\t\t\treturn null;\n\t\t\t\tnullableVars = new List<ILVariable> { leftVar };\n\t\t\t\tvar (left, leftBits) = DoLift(valueComp.Left);\n\t\t\t\tnullableVars[0] = rightVar;\n\t\t\t\tvar (right, rightBits) = DoLift(valueComp.Right);\n\t\t\t\tif (left != null && right != null && leftBits[0] && rightBits[0]\n\t\t\t\t\t&& SemanticHelper.IsPure(left.Flags) && SemanticHelper.IsPure(right.Flags)\n\t\t\t\t)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"NullableLiftingTransform: C# (in)equality comparison\", valueComp.Instruction);\n\t\t\t\t\treturn valueComp.MakeLifted(newComparisonKind, left, right);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (newComparisonKind == ComparisonKind.Equality && !hasValueTestNegated && MatchHasValueCall(hasValueTest, out ILVariable v))\n\t\t\t{\n\t\t\t\t// Comparing nullable with non-nullable -> we can fall back to the normal comparison code.\n\t\t\t\tnullableVars = new List<ILVariable> { v };\n\t\t\t\treturn LiftCSharpComparison(valueComp, newComparisonKind);\n\t\t\t}\n\t\t\telse if (newComparisonKind == ComparisonKind.Inequality && hasValueTestNegated && MatchHasValueCall(hasValueTest, out v))\n\t\t\t{\n\t\t\t\t// Comparing nullable with non-nullable -> we can fall back to the normal comparison code.\n\t\t\t\tnullableVars = new List<ILVariable> { v };\n\t\t\t\treturn LiftCSharpComparison(valueComp, newComparisonKind);\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Lift a C# comparison.\n\t\t/// This method cannot be used for (in)equality comparisons where both sides are nullable\n\t\t/// (these special cases are handled in LiftCSharpEqualityComparison instead).\n\t\t/// \n\t\t/// The output instructions should evaluate to <c>false</c> when any of the <c>nullableVars</c> is <c>null</c>\n\t\t///   (except for newComparisonKind==Inequality, where this case should evaluate to <c>true</c> instead).\n\t\t/// Otherwise, the output instruction should evaluate to the same value as the input instruction.\n\t\t/// The output instruction should have the same side-effects (incl. exceptions being thrown) as the input instruction.\n\t\t/// This means unlike LiftNormal(), we cannot rely on the input instruction not being evaluated if\n\t\t/// a variable is <c>null</c>.\n\t\t/// </summary>\n\t\tILInstruction LiftCSharpComparison(CompOrDecimal comp, ComparisonKind newComparisonKind)\n\t\t{\n\t\t\tif (comp.IsLifted)\n\t\t\t{\n\t\t\t\t// Happens when legacy csc generates 'num.GetValueOrDefault() == const && num.HasValue',\n\t\t\t\t// checking HasValue is redundant here, modern Roslyn versions optimize it and our\n\t\t\t\t// NullableLifting transform on Comp will already lift the lhs of the logic.and.\n\t\t\t\t// Treat this case as if the transform had not undone the optimization yet.\n\t\t\t\tif (nullableVars.Count != 1)\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tif (comp.Left.MatchLdLoc(nullableVars[0]) || comp.Right.MatchLdLoc(nullableVars[0]))\n\t\t\t\t{\n\t\t\t\t\treturn comp.MakeLifted(newComparisonKind, comp.Left.Clone(), comp.Right.Clone());\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tvar (left, right, bits) = DoLiftBinary(comp.Left, comp.Right, comp.LeftExpectedType, comp.RightExpectedType);\n\t\t\t// due to the restrictions on side effects, we only allow instructions that are pure after lifting.\n\t\t\t// (we can't check this before lifting due to the calls to GetValueOrDefault())\n\t\t\tif (left != null && right != null && SemanticHelper.IsPure(left.Flags) && SemanticHelper.IsPure(right.Flags))\n\t\t\t{\n\t\t\t\tif (!bits.All(0, nullableVars.Count))\n\t\t\t\t{\n\t\t\t\t\t// don't lift if a nullableVar doesn't contribute to the result\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tcontext.Step(\"NullableLiftingTransform: C# comparison\", comp.Instruction);\n\t\t\t\treturn comp.MakeLifted(newComparisonKind, left, right);\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tILInstruction LiftCSharpUserEqualityComparison(CompOrDecimal hasValueComp, ComparisonKind newComparisonKind, ILInstruction nestedIfInst)\n\t\t{\n\t\t\t// User-defined equality operator:\n\t\t\t//   if (comp(call get_HasValue(ldloca nullable1) == call get_HasValue(ldloca nullable2)))\n\t\t\t//      if (logic.not(call get_HasValue(ldloca nullable)))\n\t\t\t//          ldc.i4 1\n\t\t\t//      else\n\t\t\t//          call op_Equality(call GetValueOrDefault(ldloca nullable1), call GetValueOrDefault(ldloca nullable2)\n\t\t\t//   else\n\t\t\t//      ldc.i4 0\n\n\t\t\t// User-defined inequality operator:\n\t\t\t//   if (comp(call get_HasValue(ldloca nullable1) != call get_HasValue(ldloca nullable2)))\n\t\t\t//      ldc.i4 1\n\t\t\t//   else\n\t\t\t//      if (call get_HasValue(ldloca nullable))\n\t\t\t//         call op_Inequality(call GetValueOrDefault(ldloca nullable1), call GetValueOrDefault(ldloca nullable2))\n\t\t\t//      else\n\t\t\t//         ldc.i4 0\n\t\t\tif (hasValueComp.IsLifted)\n\t\t\t\treturn null;\n\t\t\tif (!MatchHasValueCall(hasValueComp.Left, out ILVariable nullable1))\n\t\t\t\treturn null;\n\t\t\tif (!MatchHasValueCall(hasValueComp.Right, out ILVariable nullable2))\n\t\t\t\treturn null;\n\t\t\tif (!nestedIfInst.MatchIfInstructionPositiveCondition(out var condition, out var trueInst, out var falseInst))\n\t\t\t\treturn null;\n\t\t\tif (!MatchHasValueCall(condition, out ILVariable nullable))\n\t\t\t\treturn null;\n\t\t\tif (nullable != nullable1 && nullable != nullable2)\n\t\t\t\treturn null;\n\t\t\tif (!falseInst.MatchLdcI4(newComparisonKind == ComparisonKind.Equality ? 1 : 0))\n\t\t\t\treturn null;\n\t\t\tbool trueInstNegated = false;\n\t\t\twhile (trueInst.MatchLogicNot(out var arg))\n\t\t\t{\n\t\t\t\ttrueInstNegated = !trueInstNegated;\n\t\t\t\ttrueInst = arg;\n\t\t\t}\n\t\t\tif (!(trueInst is Call call))\n\t\t\t\treturn null;\n\t\t\tif (!(call.Method.IsOperator && call.Arguments.Count == 2))\n\t\t\t\treturn null;\n\t\t\tbool expectEqualityOperator = (newComparisonKind == ComparisonKind.Equality) ^ trueInstNegated;\n\t\t\tif (call.Method.Name != (expectEqualityOperator ? \"op_Equality\" : \"op_Inequality\"))\n\t\t\t\treturn null;\n\t\t\tvar liftedOperator = CSharp.Resolver.CSharpOperators.LiftUserDefinedOperator(call.Method);\n\t\t\tif (liftedOperator == null)\n\t\t\t\treturn null;\n\t\t\tnullableVars = new List<ILVariable> { nullable1 };\n\t\t\tvar (left, leftBits) = DoLift(call.Arguments[0]);\n\t\t\tnullableVars[0] = nullable2;\n\t\t\tvar (right, rightBits) = DoLift(call.Arguments[1]);\n\t\t\tif (left != null && right != null && leftBits[0] && rightBits[0]\n\t\t\t\t&& SemanticHelper.IsPure(left.Flags) && SemanticHelper.IsPure(right.Flags)\n\t\t\t)\n\t\t\t{\n\t\t\t\tcontext.Step(\"NullableLiftingTransform: C# user-defined (in)equality comparison\", nestedIfInst);\n\t\t\t\tILInstruction replacement = new Call(liftedOperator) {\n\t\t\t\t\tArguments = { left, right },\n\t\t\t\t\tConstrainedTo = call.ConstrainedTo,\n\t\t\t\t\tILStackWasEmpty = call.ILStackWasEmpty,\n\t\t\t\t\tIsTail = call.IsTail,\n\t\t\t\t}.WithILRange(call);\n\t\t\t\tif (trueInstNegated)\n\t\t\t\t{\n\t\t\t\t\treplacement = Comp.LogicNot(replacement);\n\t\t\t\t}\n\t\t\t\treturn replacement;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tILInstruction LiftCSharpUserComparison(ILInstruction trueInst, ILInstruction falseInst)\n\t\t{\n\t\t\t// (v1 != null && ... && vn != null) ? trueInst : falseInst\n\t\t\tbool trueInstNegated = false;\n\t\t\twhile (trueInst.MatchLogicNot(out var arg))\n\t\t\t{\n\t\t\t\ttrueInstNegated = !trueInstNegated;\n\t\t\t\ttrueInst = arg;\n\t\t\t}\n\t\t\tif (trueInst is Call call && !call.IsLifted\n\t\t\t  && CSharp.Resolver.CSharpOperators.IsComparisonOperator(call.Method)\n\t\t\t  && falseInst.MatchLdcI4((call.Method.Name == \"op_Inequality\") ^ trueInstNegated ? 1 : 0))\n\t\t\t{\n\t\t\t\t// (v1 != null && ... && vn != null) ? call op_LessThan(lhs, rhs) : ldc.i4(0)\n\t\t\t\tvar liftedOperator = CSharp.Resolver.CSharpOperators.LiftUserDefinedOperator(call.Method);\n\t\t\t\tif ((call.Method.Name == \"op_Equality\" || call.Method.Name == \"op_Inequality\") && nullableVars.Count != 1)\n\t\t\t\t{\n\t\t\t\t\t// Equality is special (returns true if both sides are null), only handle it\n\t\t\t\t\t// in the normal code path if we're dealing with only a single nullable var\n\t\t\t\t\t// (comparing nullable with non-nullable).\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tif (liftedOperator == null)\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tcontext.Step(\"Lift user-defined comparison operator\", trueInst);\n\t\t\t\tvar (left, right, bits) = DoLiftBinary(call.Arguments[0], call.Arguments[1],\n\t\t\t\t\tcall.Method.Parameters[0].Type, call.Method.Parameters[1].Type);\n\t\t\t\tif (left != null && right != null && bits.All(0, nullableVars.Count))\n\t\t\t\t{\n\t\t\t\t\tILInstruction result = new Call(liftedOperator) {\n\t\t\t\t\t\tArguments = { left, right },\n\t\t\t\t\t\tConstrainedTo = call.ConstrainedTo,\n\t\t\t\t\t\tILStackWasEmpty = call.ILStackWasEmpty,\n\t\t\t\t\t\tIsTail = call.IsTail\n\t\t\t\t\t}.WithILRange(call);\n\t\t\t\t\tif (trueInstNegated)\n\t\t\t\t\t{\n\t\t\t\t\t\tresult = Comp.LogicNot(result);\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\t\t#endregion\n\n\t\t#region LiftNormal / DoLift\n\t\t/// <summary>\n\t\t/// Performs nullable lifting.\n\t\t/// \n\t\t/// Produces a lifted instruction with semantics equivalent to:\n\t\t///   (v1 != null &amp;&amp; ... &amp;&amp; vn != null) ? trueInst : falseInst,\n\t\t/// where the v1,...,vn are the <c>this.nullableVars</c>.\n\t\t/// If lifting fails, returns <c>null</c>.\n\t\t/// </summary>\n\t\tILInstruction LiftNormal(ILInstruction trueInst, ILInstruction falseInst)\n\t\t{\n\t\t\tif (trueInst.MatchIfInstructionPositiveCondition(out var nestedCondition, out var nestedTrue, out var nestedFalse))\n\t\t\t{\n\t\t\t\t// Sometimes Roslyn generates pointless conditions like:\n\t\t\t\t//   if (nullable.HasValue && (!nullable.HasValue || nullable.GetValueOrDefault() == b))\n\t\t\t\tif (MatchHasValueCall(nestedCondition, out ILVariable v) && nullableVars.Contains(v))\n\t\t\t\t{\n\t\t\t\t\ttrueInst = nestedTrue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool isNullCoalescingWithNonNullableFallback = false;\n\t\t\tif (!MatchNullableCtor(trueInst, out var utype, out var exprToLift))\n\t\t\t{\n\t\t\t\tisNullCoalescingWithNonNullableFallback = true;\n\t\t\t\tutype = context.TypeSystem.FindType(trueInst.ResultType);\n\t\t\t\texprToLift = trueInst;\n\t\t\t\tif (nullableVars.Count == 1 && exprToLift.MatchLdLoc(nullableVars[0]))\n\t\t\t\t{\n\t\t\t\t\t// v.HasValue ? ldloc v : fallback\n\t\t\t\t\t// => v ?? fallback\n\t\t\t\t\tcontext.Step(\"v.HasValue ? v : fallback => v ?? fallback\", trueInst);\n\t\t\t\t\treturn new NullCoalescingInstruction(NullCoalescingKind.Nullable, trueInst, falseInst) {\n\t\t\t\t\t\tUnderlyingResultType = NullableType.GetUnderlyingType(nullableVars[0].Type).GetStackType()\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tILInstruction result = LiftCSharpUserComparison(trueInst, falseInst);\n\t\t\t\tif (result != null)\n\t\t\t\t\treturn result;\n\t\t\t}\n\t\t\tILInstruction lifted;\n\t\t\tif (nullableVars.Count == 1 && MatchGetValueOrDefault(exprToLift, nullableVars[0]))\n\t\t\t{\n\t\t\t\t// v.HasValue ? call GetValueOrDefault(ldloca v) : fallback\n\t\t\t\t// => conv.nop.lifted(ldloc v) ?? fallback\n\t\t\t\t// This case is handled separately from DoLift() because\n\t\t\t\t// that doesn't introduce nop-conversions.\n\t\t\t\tcontext.Step(\"v.HasValue ? v.GetValueOrDefault() : fallback => v ?? fallback\", trueInst);\n\t\t\t\tvar inputUType = NullableType.GetUnderlyingType(nullableVars[0].Type);\n\t\t\t\tlifted = new LdLoc(nullableVars[0]);\n\t\t\t\tif (!inputUType.Equals(utype) && utype.ToPrimitiveType() != PrimitiveType.None)\n\t\t\t\t{\n\t\t\t\t\t// While the ILAst allows implicit conversions between short and int\n\t\t\t\t\t// (because both map to I4); it does not allow implicit conversions\n\t\t\t\t\t// between short? and int? (structs of different types).\n\t\t\t\t\t// So use 'conv.nop.lifted' to allow the conversion.\n\t\t\t\t\tlifted = new Conv(\n\t\t\t\t\t\tlifted,\n\t\t\t\t\t\tinputUType.GetStackType(), inputUType.GetSign(), utype.ToPrimitiveType(),\n\t\t\t\t\t\tcheckForOverflow: false,\n\t\t\t\t\t\tisLifted: true\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tcontext.Step(\"NullableLiftingTransform.DoLift\", trueInst);\n\t\t\t\tBitSet bits;\n\t\t\t\t(lifted, bits) = DoLift(exprToLift);\n\t\t\t\tif (lifted == null)\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tif (!bits.All(0, nullableVars.Count))\n\t\t\t\t{\n\t\t\t\t\t// don't lift if a nullableVar doesn't contribute to the result\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tDebug.Assert(lifted is ILiftableInstruction liftable && liftable.IsLifted\n\t\t\t\t\t&& liftable.UnderlyingResultType == exprToLift.ResultType);\n\t\t\t}\n\t\t\tif (isNullCoalescingWithNonNullableFallback)\n\t\t\t{\n\t\t\t\tlifted = new NullCoalescingInstruction(NullCoalescingKind.NullableWithValueFallback, lifted, falseInst) {\n\t\t\t\t\tUnderlyingResultType = exprToLift.ResultType\n\t\t\t\t};\n\t\t\t}\n\t\t\telse if (!MatchNull(falseInst, utype))\n\t\t\t{\n\t\t\t\t// Normal lifting, but the falseInst isn't `default(utype?)`\n\t\t\t\t// => use the `??` operator to provide the fallback value.\n\t\t\t\tlifted = new NullCoalescingInstruction(NullCoalescingKind.Nullable, lifted, falseInst) {\n\t\t\t\t\tUnderlyingResultType = exprToLift.ResultType\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn lifted;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Recursive function that lifts the specified instruction.\n\t\t/// The input instruction is expected to a subexpression of the trueInst\n\t\t/// (so that all nullableVars are guaranteed non-null within this expression).\n\t\t/// \n\t\t/// Creates a new lifted instruction without modifying the input instruction.\n\t\t/// On success, returns (new lifted instruction, bitset).\n\t\t/// If lifting fails, returns (null, null).\n\t\t/// \n\t\t/// The returned bitset specifies which nullableVars were considered \"relevant\" for this instruction.\n\t\t/// bitSet[i] == true means nullableVars[i] was relevant.\n\t\t/// \n\t\t/// The new lifted instruction will have equivalent semantics to the input instruction\n\t\t/// if all relevant variables are non-null [except that the result will be wrapped in a Nullable{T} struct].\n\t\t/// If any relevant variable is null, the new instruction is guaranteed to evaluate to <c>null</c>\n\t\t/// without having any other effect.\n\t\t/// </summary>\n\t\t(ILInstruction, BitSet) DoLift(ILInstruction inst)\n\t\t{\n\t\t\tif (MatchGetValueOrDefault(inst, out ILVariable inputVar))\n\t\t\t{\n\t\t\t\t// n.GetValueOrDefault() lifted => n.\n\t\t\t\tBitSet foundIndices = new BitSet(nullableVars.Count);\n\t\t\t\tfor (int i = 0; i < nullableVars.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (nullableVars[i] == inputVar)\n\t\t\t\t\t{\n\t\t\t\t\t\tfoundIndices[i] = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (foundIndices.Any())\n\t\t\t\t\treturn (new LdLoc(inputVar).WithILRange(inst), foundIndices);\n\t\t\t\telse\n\t\t\t\t\treturn (null, null);\n\t\t\t}\n\t\t\telse if (inst is Conv conv)\n\t\t\t{\n\t\t\t\tvar (arg, bits) = DoLift(conv.Argument);\n\t\t\t\tif (arg != null)\n\t\t\t\t{\n\t\t\t\t\tif (conv.HasDirectFlag(InstructionFlags.MayThrow) && !bits.All(0, nullableVars.Count))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Cannot execute potentially-throwing instruction unless all\n\t\t\t\t\t\t// the nullableVars are arguments to the instruction\n\t\t\t\t\t\t// (thus causing it not to throw when any of them is null).\n\t\t\t\t\t\treturn (null, null);\n\t\t\t\t\t}\n\t\t\t\t\tvar newInst = new Conv(arg, conv.InputType, conv.InputSign, conv.TargetType, conv.CheckForOverflow, isLifted: true).WithILRange(conv);\n\t\t\t\t\treturn (newInst, bits);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (inst is BitNot bitnot)\n\t\t\t{\n\t\t\t\tvar (arg, bits) = DoLift(bitnot.Argument);\n\t\t\t\tif (arg != null)\n\t\t\t\t{\n\t\t\t\t\tvar newInst = new BitNot(arg, isLifted: true, stackType: bitnot.ResultType).WithILRange(bitnot);\n\t\t\t\t\treturn (newInst, bits);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (inst is BinaryNumericInstruction binary)\n\t\t\t{\n\t\t\t\tvar (left, right, bits) = DoLiftBinary(binary.Left, binary.Right, SpecialType.UnknownType, SpecialType.UnknownType);\n\t\t\t\tif (left != null && right != null)\n\t\t\t\t{\n\t\t\t\t\tif (binary.HasDirectFlag(InstructionFlags.MayThrow) && !bits.All(0, nullableVars.Count))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Cannot execute potentially-throwing instruction unless all\n\t\t\t\t\t\t// the nullableVars are arguments to the instruction\n\t\t\t\t\t\t// (thus causing it not to throw when any of them is null).\n\t\t\t\t\t\treturn (null, null);\n\t\t\t\t\t}\n\t\t\t\t\tvar newInst = new BinaryNumericInstruction(\n\t\t\t\t\t\tbinary.Operator, left, right,\n\t\t\t\t\t\tbinary.LeftInputType, binary.RightInputType,\n\t\t\t\t\t\tbinary.CheckForOverflow, binary.Sign,\n\t\t\t\t\t\tisLifted: true\n\t\t\t\t\t).WithILRange(binary);\n\t\t\t\t\treturn (newInst, bits);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (inst is Comp comp && !comp.IsLifted && comp.Kind == ComparisonKind.Equality\n\t\t\t  && MatchGetValueOrDefault(comp.Left, out ILVariable v) && nullableVars.Contains(v)\n\t\t\t  && NullableType.GetUnderlyingType(v.Type).IsKnownType(KnownTypeCode.Boolean)\n\t\t\t  && comp.Right.MatchLdcI4(0)\n\t\t  )\n\t\t\t{\n\t\t\t\t// C# doesn't support ComparisonLiftingKind.ThreeValuedLogic,\n\t\t\t\t// except for operator! on bool?.\n\t\t\t\tvar (arg, bits) = DoLift(comp.Left);\n\t\t\t\tDebug.Assert(arg != null);\n\t\t\t\tvar newInst = new Comp(comp.Kind, ComparisonLiftingKind.ThreeValuedLogic, comp.InputType, comp.Sign, arg, comp.Right.Clone()).WithILRange(comp);\n\t\t\t\treturn (newInst, bits);\n\t\t\t}\n\t\t\telse if (inst is Call call && call.Method.IsOperator)\n\t\t\t{\n\t\t\t\t// Lifted user-defined operators, except for comparison operators (as those return bool, not bool?)\n\t\t\t\tvar liftedOperator = CSharp.Resolver.CSharpOperators.LiftUserDefinedOperator(call.Method);\n\t\t\t\tif (liftedOperator == null || !NullableType.IsNullable(liftedOperator.ReturnType))\n\t\t\t\t\treturn (null, null);\n\t\t\t\tILInstruction[] newArgs;\n\t\t\t\tBitSet newBits;\n\t\t\t\tif (call.Arguments.Count == 1)\n\t\t\t\t{\n\t\t\t\t\tvar (arg, bits) = DoLift(call.Arguments[0]);\n\t\t\t\t\tnewArgs = new[] { arg };\n\t\t\t\t\tnewBits = bits;\n\t\t\t\t}\n\t\t\t\telse if (call.Arguments.Count == 2)\n\t\t\t\t{\n\t\t\t\t\tvar (left, right, bits) = DoLiftBinary(call.Arguments[0], call.Arguments[1],\n\t\t\t\t\t\tcall.Method.Parameters[0].Type, call.Method.Parameters[1].Type);\n\t\t\t\t\tnewArgs = new[] { left, right };\n\t\t\t\t\tnewBits = bits;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn (null, null);\n\t\t\t\t}\n\t\t\t\tif (newBits == null || !newBits.All(0, nullableVars.Count))\n\t\t\t\t{\n\t\t\t\t\t// all nullable vars must be involved when calling a method (side effect)\n\t\t\t\t\treturn (null, null);\n\t\t\t\t}\n\t\t\t\tvar newInst = new Call(liftedOperator) {\n\t\t\t\t\tConstrainedTo = call.ConstrainedTo,\n\t\t\t\t\tIsTail = call.IsTail,\n\t\t\t\t\tILStackWasEmpty = call.ILStackWasEmpty,\n\t\t\t\t}.WithILRange(call);\n\t\t\t\tnewInst.Arguments.AddRange(newArgs);\n\t\t\t\treturn (newInst, newBits);\n\t\t\t}\n\t\t\treturn (null, null);\n\t\t}\n\n\t\t(ILInstruction, ILInstruction, BitSet) DoLiftBinary(ILInstruction lhs, ILInstruction rhs, IType leftExpectedType, IType rightExpectedType)\n\t\t{\n\t\t\tvar (left, leftBits) = DoLift(lhs);\n\t\t\tvar (right, rightBits) = DoLift(rhs);\n\t\t\tif (left != null && right == null && SemanticHelper.IsPure(rhs.Flags))\n\t\t\t{\n\t\t\t\t// Embed non-nullable pure expression in lifted expression.\n\t\t\t\tright = NewNullable(rhs.Clone(), rightExpectedType);\n\t\t\t}\n\t\t\tif (left == null && right != null && SemanticHelper.IsPure(lhs.Flags))\n\t\t\t{\n\t\t\t\t// Embed non-nullable pure expression in lifted expression.\n\t\t\t\tleft = NewNullable(lhs.Clone(), leftExpectedType);\n\t\t\t}\n\t\t\tif (left != null && right != null)\n\t\t\t{\n\t\t\t\tvar bits = leftBits ?? rightBits;\n\t\t\t\tif (rightBits != null)\n\t\t\t\t\tbits.UnionWith(rightBits);\n\t\t\t\treturn (left, right, bits);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn (null, null, null);\n\t\t\t}\n\t\t}\n\n\t\tprivate ILInstruction NewNullable(ILInstruction inst, IType underlyingType)\n\t\t{\n\t\t\tif (underlyingType == SpecialType.UnknownType)\n\t\t\t\treturn inst;\n\t\t\tvar nullable = context.TypeSystem.FindType(KnownTypeCode.NullableOfT).GetDefinition();\n\t\t\tvar ctor = nullable?.Methods.FirstOrDefault(m => m.IsConstructor && m.Parameters.Count == 1);\n\t\t\tif (ctor != null)\n\t\t\t{\n\t\t\t\tctor = ctor.Specialize(new TypeParameterSubstitution(new[] { underlyingType }, null));\n\t\t\t\treturn new NewObj(ctor) { Arguments = { inst } };\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn inst;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Match...Call\n\t\t/// <summary>\n\t\t/// Matches 'call get_HasValue(arg)'\n\t\t/// </summary>\n\t\tinternal static bool MatchHasValueCall(ILInstruction inst, out ILInstruction arg)\n\t\t{\n\t\t\targ = null;\n\t\t\tif (!(inst is Call call))\n\t\t\t\treturn false;\n\t\t\tif (call.Arguments.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (call.Method.Name != \"get_HasValue\")\n\t\t\t\treturn false;\n\t\t\tif (call.Method.DeclaringTypeDefinition?.KnownTypeCode != KnownTypeCode.NullableOfT)\n\t\t\t\treturn false;\n\t\t\targ = call.Arguments[0];\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches 'call get_HasValue(ldloca v)'\n\t\t/// </summary>\n\t\tinternal static bool MatchHasValueCall(ILInstruction inst, out ILVariable v)\n\t\t{\n\t\t\tif (MatchHasValueCall(inst, out ILInstruction arg))\n\t\t\t{\n\t\t\t\treturn arg.MatchLdLoca(out v);\n\t\t\t}\n\t\t\tv = null;\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches 'call get_HasValue(ldloca v)'\n\t\t/// </summary>\n\t\tinternal static bool MatchHasValueCall(ILInstruction inst, ILVariable v)\n\t\t{\n\t\t\treturn MatchHasValueCall(inst, out ILVariable v2) && v == v2;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches 'logic.not(call get_HasValue(ldloca v))'\n\t\t/// </summary>\n\t\tinternal static bool MatchNegatedHasValueCall(ILInstruction inst, ILVariable v)\n\t\t{\n\t\t\treturn inst.MatchLogicNot(out var arg) && MatchHasValueCall(arg, v);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches 'newobj Nullable{underlyingType}.ctor(arg)'\n\t\t/// </summary>\n\t\tinternal static bool MatchNullableCtor(ILInstruction inst, out IType underlyingType, out ILInstruction arg)\n\t\t{\n\t\t\tunderlyingType = null;\n\t\t\targ = null;\n\t\t\tif (!(inst is NewObj newobj))\n\t\t\t\treturn false;\n\t\t\tif (!newobj.Method.IsConstructor || newobj.Arguments.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (newobj.Method.DeclaringTypeDefinition?.KnownTypeCode != KnownTypeCode.NullableOfT)\n\t\t\t\treturn false;\n\t\t\targ = newobj.Arguments[0];\n\t\t\tunderlyingType = NullableType.GetUnderlyingType(newobj.Method.DeclaringType);\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches 'call Nullable{T}.GetValueOrDefault(arg)'\n\t\t/// </summary>\n\t\tinternal static bool MatchGetValueOrDefault(ILInstruction inst, out ILInstruction arg)\n\t\t{\n\t\t\targ = null;\n\t\t\tif (!(inst is Call call))\n\t\t\t\treturn false;\n\t\t\tif (call.Method.Name != \"GetValueOrDefault\" || call.Arguments.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (call.Method.DeclaringTypeDefinition?.KnownTypeCode != KnownTypeCode.NullableOfT)\n\t\t\t\treturn false;\n\t\t\targ = call.Arguments[0];\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches 'call nullableValue.GetValueOrDefault(fallback)'\n\t\t/// </summary>\n\t\tinternal static bool MatchGetValueOrDefault(ILInstruction inst, out ILInstruction nullableValue, out ILInstruction fallback)\n\t\t{\n\t\t\tnullableValue = null;\n\t\t\tfallback = null;\n\t\t\tif (!(inst is Call call))\n\t\t\t\treturn false;\n\t\t\tif (call.Method.Name != \"GetValueOrDefault\" || call.Arguments.Count != 2)\n\t\t\t\treturn false;\n\t\t\tif (call.Method.DeclaringTypeDefinition?.KnownTypeCode != KnownTypeCode.NullableOfT)\n\t\t\t\treturn false;\n\t\t\tnullableValue = call.Arguments[0];\n\t\t\tfallback = call.Arguments[1];\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches 'call Nullable{T}.GetValueOrDefault(ldloca v)'\n\t\t/// </summary>\n\t\tinternal static bool MatchGetValueOrDefault(ILInstruction inst, out ILVariable v)\n\t\t{\n\t\t\tv = null;\n\t\t\treturn MatchGetValueOrDefault(inst, out ILInstruction arg)\n\t\t\t\t&& arg.MatchLdLoca(out v);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches 'call Nullable{T}.GetValueOrDefault(ldloca v)'\n\t\t/// </summary>\n\t\tinternal static bool MatchGetValueOrDefault(ILInstruction inst, ILVariable v)\n\t\t{\n\t\t\treturn MatchGetValueOrDefault(inst, out ILVariable v2) && v == v2;\n\t\t}\n\n\t\tstatic bool MatchNull(ILInstruction inst, out IType underlyingType)\n\t\t{\n\t\t\tunderlyingType = null;\n\t\t\tif (inst.MatchDefaultValue(out IType type))\n\t\t\t{\n\t\t\t\tunderlyingType = NullableType.GetUnderlyingType(type);\n\t\t\t\treturn NullableType.IsNullable(type);\n\t\t\t}\n\t\t\tunderlyingType = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tstatic bool MatchNull(ILInstruction inst, IType underlyingType)\n\t\t{\n\t\t\treturn MatchNull(inst, out var utype) && utype.Equals(underlyingType);\n\t\t}\n\t\t#endregion\n\t}\n\n\tpublic class NullableLiftingStatementTransform : IStatementTransform\n\t{\n\t\tpublic void Run(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\tnew NullableLiftingTransform(context).RunStatements(block, pos);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/PatternMatchingTransform.cs",
    "content": "// Copyright (c) 2021 Daniel Grunwald, Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing System.Reflection;\n\nusing ICSharpCode.Decompiler.IL.ControlFlow;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\tclass PatternMatchingTransform : IILTransform\n\t{\n\n\t\tvoid IILTransform.Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.PatternMatching)\n\t\t\t\treturn;\n\t\t\tforeach (var container in function.Descendants.OfType<BlockContainer>())\n\t\t\t{\n\t\t\t\tControlFlowGraph? cfg = null;\n\t\t\t\tforeach (var block in container.Blocks.Reverse())\n\t\t\t\t{\n\t\t\t\t\tif (PatternMatchValueTypes(block, container, context, ref cfg))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (PatternMatchRefTypes(block, container, context, ref cfg))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontainer.Blocks.RemoveAll(b => b.Instructions.Count == 0);\n\t\t\t}\n\t\t}\n\n\t\t/// Block {\n\t\t///\t\t...\n\t\t///\t\tstloc V(isinst T(testedOperand))\n\t\t///\t\tif (comp.o(ldloc V == ldnull)) br falseBlock\n\t\t///\t\tbr trueBlock\n\t\t/// }\n\t\t/// \n\t\t/// All other uses of V are in blocks dominated by trueBlock.\n\t\t/// =>\n\t\t/// Block {\n\t\t///\t\t...\n\t\t///\t\tif (match.type[T].notnull(V = testedOperand)) br trueBlock\n\t\t///\t\tbr falseBlock\n\t\t/// }\n\t\t///\n\t\t/// - or -\n\t\t/// \n\t\t/// Block {\n\t\t/// \tstloc s(isinst T(testedOperand))\n\t\t/// \tstloc v(ldloc s)\n\t\t/// \tif (logic.not(comp.o(ldloc s != ldnull))) br falseBlock\n\t\t/// \tbr trueBlock\n\t\t/// }\n\t\t/// =>\n\t\t/// Block {\n\t\t///\t\t...\n\t\t///\t\tif (match.type[T].notnull(V = testedOperand)) br trueBlock\n\t\t///\t\tbr falseBlock\n\t\t/// }\n\t\t/// \n\t\t/// All other uses of V are in blocks dominated by trueBlock.\n\t\tprivate bool PatternMatchRefTypes(Block block, BlockContainer container, ILTransformContext context, ref ControlFlowGraph? cfg)\n\t\t{\n\t\t\tif (!block.MatchIfAtEndOfBlock(out var condition, out var trueInst, out var falseInst))\n\t\t\t\treturn false;\n\t\t\tint pos = block.Instructions.Count - 3;\n\t\t\tif (condition.MatchLdLoc(out var conditionVar))\n\t\t\t{\n\t\t\t\t// stloc conditionVar(comp.o(ldloc s == ldnull))\n\t\t\t\t// if (logic.not(ldloc conditionVar)) br trueBlock\n\t\t\t\tif (pos < 0)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(conditionVar.IsSingleDefinition && conditionVar.LoadCount == 1\n\t\t\t\t\t&& conditionVar.Kind == VariableKind.StackSlot))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (!block.Instructions[pos].MatchStLoc(conditionVar, out condition))\n\t\t\t\t\treturn false;\n\t\t\t\tpos--;\n\t\t\t}\n\t\t\tif (condition.MatchCompEqualsNull(out var loadInNullCheck))\n\t\t\t{\n\t\t\t\tExtensionMethods.Swap(ref trueInst, ref falseInst);\n\t\t\t}\n\t\t\telse if (condition.MatchCompNotEqualsNull(out loadInNullCheck))\n\t\t\t{\n\t\t\t\t// do nothing\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!loadInNullCheck.MatchLdLoc(out var s))\n\t\t\t\treturn false;\n\t\t\tif (!s.IsSingleDefinition)\n\t\t\t\treturn false;\n\t\t\tif (s.Kind is not (VariableKind.Local or VariableKind.StackSlot))\n\t\t\t\treturn false;\n\t\t\tif (pos < 0)\n\t\t\t\treturn false;\n\t\t\t// stloc V(isinst T(testedOperand))\n\t\t\tILInstruction storeToV = block.Instructions[pos];\n\t\t\tif (!storeToV.MatchStLoc(out var v, out var value))\n\t\t\t\treturn false;\n\t\t\tif (value.MatchLdLoc(s))\n\t\t\t{\n\t\t\t\t// stloc v(ldloc s)\n\t\t\t\tpos--;\n\t\t\t\tif (pos < 0 || !block.Instructions[pos].MatchStLoc(s, out value))\n\t\t\t\t\treturn false;\n\t\t\t\tif (v.Kind is not (VariableKind.Local or VariableKind.StackSlot))\n\t\t\t\t\treturn false;\n\t\t\t\tif (s.LoadCount != 2)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (v != s)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tIType? unboxType;\n\t\t\tif (value is UnboxAny unboxAny)\n\t\t\t{\n\t\t\t\t// stloc S(unbox.any T(isinst T(testedOperand)))\n\t\t\t\tunboxType = unboxAny.Type;\n\t\t\t\tvalue = unboxAny.Argument;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tunboxType = null;\n\t\t\t}\n\t\t\tif (value is not IsInst { Argument: var testedOperand, Type: var type })\n\t\t\t\treturn false;\n\t\t\tif (type.IsReferenceType != true)\n\t\t\t\treturn false;\n\t\t\tif (!(unboxType == null || type.Equals(unboxType)))\n\t\t\t\treturn false;\n\n\t\t\tif (!v.Type.Equals(type))\n\t\t\t\treturn false;\n\t\t\tif (!CheckAllUsesDominatedBy(v, container, trueInst, storeToV, loadInNullCheck, context, ref cfg))\n\t\t\t\treturn false;\n\t\t\tcontext.Step($\"Type pattern matching {v.Name}\", block);\n\t\t\t//\tif (match.type[T].notnull(V = testedOperand)) br trueBlock\n\n\t\t\tvar ifInst = (IfInstruction)block.Instructions.SecondToLastOrDefault()!;\n\n\t\t\tifInst.Condition = new MatchInstruction(v, testedOperand) {\n\t\t\t\tCheckNotNull = true,\n\t\t\t\tCheckType = true\n\t\t\t}.WithILRange(ifInst.Condition);\n\t\t\tifInst.TrueInst = trueInst;\n\t\t\tblock.Instructions[block.Instructions.Count - 1] = falseInst;\n\t\t\tblock.Instructions.RemoveRange(pos, ifInst.ChildIndex - pos);\n\t\t\tv.Kind = VariableKind.PatternLocal;\n\n\t\t\tDetectPropertySubPatterns((MatchInstruction)ifInst.Condition, trueInst, falseInst, container, context, ref cfg);\n\n\t\t\treturn true;\n\t\t}\n\n\t\tprivate static ILInstruction DetectPropertySubPatterns(MatchInstruction parentPattern, ILInstruction trueInst,\n\t\t\tILInstruction parentFalseInst, BlockContainer container, ILTransformContext context, ref ControlFlowGraph? cfg)\n\t\t{\n\t\t\tif (!context.Settings.RecursivePatternMatching)\n\t\t\t{\n\t\t\t\treturn trueInst;\n\t\t\t}\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tBlock? trueBlock = trueInst as Block;\n\t\t\t\tif (!(trueBlock != null || trueInst.MatchBranch(out trueBlock)))\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (!(trueBlock.IncomingEdgeCount == 1 && trueBlock.Parent == container))\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tvar nextTrueInst = DetectPropertySubPattern(parentPattern, trueBlock, parentFalseInst, context, ref cfg);\n\t\t\t\tif (nextTrueInst != null)\n\t\t\t\t{\n\t\t\t\t\ttrueInst = nextTrueInst;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn trueInst;\n\t\t}\n\n\t\tprivate static ILInstruction? DetectPropertySubPattern(MatchInstruction parentPattern, Block block,\n\t\t\tILInstruction parentFalseInst, ILTransformContext context, ref ControlFlowGraph? cfg)\n\t\t{\n\t\t\t// if (match.notnull.type[System.String] (V_0 = callvirt get_C(ldloc V_2))) br IL_0022\n\t\t\t// br IL_0037\n\t\t\tif (MatchBlockContainingOneCondition(block, out var condition, out var trueInst, out var falseInst))\n\t\t\t{\n\t\t\t\tbool negate = false;\n\t\t\t\tif (!DetectExitPoints.CompatibleExitInstruction(parentFalseInst, falseInst))\n\t\t\t\t{\n\t\t\t\t\tif (!DetectExitPoints.CompatibleExitInstruction(parentFalseInst, trueInst))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tExtensionMethods.Swap(ref trueInst, ref falseInst);\n\t\t\t\t\tnegate = true;\n\t\t\t\t}\n\t\t\t\tif (MatchInstruction.IsPatternMatch(condition, out var operand, context.Settings))\n\t\t\t\t{\n\t\t\t\t\tif (!PropertyOrFieldAccess(operand, out var target, out _))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tif (!target.MatchLdLocRef(parentPattern.Variable))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tif (negate && !context.Settings.PatternCombinators)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tcontext.Step(\"Move property sub pattern\", condition);\n\t\t\t\t\tif (negate)\n\t\t\t\t\t{\n\t\t\t\t\t\tcondition = Comp.LogicNot(condition);\n\t\t\t\t\t}\n\t\t\t\t\tparentPattern.SubPatterns.Add(condition);\n\t\t\t\t}\n\t\t\t\telse if (PropertyOrFieldAccess(condition, out var target, out _))\n\t\t\t\t{\n\t\t\t\t\tif (!target.MatchLdLocRef(parentPattern.Variable))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tif (!negate && !context.Settings.PatternCombinators)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tcontext.Step(\"Sub pattern: implicit != 0\", condition);\n\t\t\t\t\tparentPattern.SubPatterns.Add(new Comp(negate ? ComparisonKind.Equality : ComparisonKind.Inequality,\n\t\t\t\t\t\tSign.None, condition, new LdcI4(0)));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tblock.Instructions.Clear();\n\t\t\t\tblock.Instructions.Add(trueInst);\n\t\t\t\treturn trueInst;\n\t\t\t}\n\t\t\telse if (block.Instructions[0].MatchStLoc(out var targetVariable, out var operand))\n\t\t\t{\n\t\t\t\tif (!PropertyOrFieldAccess(operand, out var target, out var member))\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tif (!target.MatchLdLocRef(parentPattern.Variable))\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tif (!targetVariable.Type.Equals(member.ReturnType))\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tif (!CheckAllUsesDominatedBy(targetVariable, (BlockContainer)block.Parent!, block, block.Instructions[0], null, context, ref cfg))\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tcontext.Step(\"Property var pattern\", block);\n\t\t\t\tvar varPattern = new MatchInstruction(targetVariable, operand)\n\t\t\t\t\t.WithILRange(block.Instructions[0]);\n\t\t\t\tparentPattern.SubPatterns.Add(varPattern);\n\t\t\t\tblock.Instructions.RemoveAt(0);\n\t\t\t\ttargetVariable.Kind = VariableKind.PatternLocal;\n\n\t\t\t\tif (targetVariable.Type.IsKnownType(KnownTypeCode.NullableOfT))\n\t\t\t\t{\n\t\t\t\t\treturn MatchNullableHasValueCheckPattern(block, varPattern, parentFalseInst, context, ref cfg)\n\t\t\t\t\t\t?? block;\n\t\t\t\t}\n\n\t\t\t\tvar instructionAfterNullCheck = MatchNullCheckPattern(block, varPattern, parentFalseInst, context);\n\t\t\t\tif (instructionAfterNullCheck != null)\n\t\t\t\t{\n\t\t\t\t\treturn DetectPropertySubPatterns(varPattern, instructionAfterNullCheck, parentFalseInst, (BlockContainer)block.Parent!, context, ref cfg);\n\t\t\t\t}\n\t\t\t\telse if (targetVariable.Type.IsReferenceType == false)\n\t\t\t\t{\n\t\t\t\t\treturn DetectPropertySubPatterns(varPattern, block, parentFalseInst, (BlockContainer)block.Parent!, context, ref cfg);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn block;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tprivate static ILInstruction? MatchNullCheckPattern(Block block, MatchInstruction varPattern,\n\t\t\tILInstruction parentFalseInst, ILTransformContext context)\n\t\t{\n\t\t\tif (!MatchBlockContainingOneCondition(block, out var condition, out var trueInst, out var falseInst))\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (condition.MatchCompEqualsNull(out var arg) && arg.MatchLdLoc(varPattern.Variable))\n\t\t\t{\n\t\t\t\tExtensionMethods.Swap(ref trueInst, ref falseInst);\n\t\t\t}\n\t\t\telse if (condition.MatchCompNotEqualsNull(out arg) && arg.MatchLdLoc(varPattern.Variable))\n\t\t\t{\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (!DetectExitPoints.CompatibleExitInstruction(falseInst, parentFalseInst))\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tcontext.Step(\"Null check pattern\", block);\n\t\t\tvarPattern.CheckNotNull = true;\n\t\t\tblock.Instructions.Clear();\n\t\t\tblock.Instructions.Add(trueInst);\n\t\t\treturn trueInst;\n\t\t}\n\n\t\tprivate static ILInstruction? MatchNullableHasValueCheckPattern(Block block, MatchInstruction varPattern,\n\t\t\tILInstruction parentFalseInst, ILTransformContext context, ref ControlFlowGraph? cfg)\n\t\t{\n\t\t\tif (!(varPattern.Variable.StoreCount == 1 && varPattern.Variable.LoadCount == 0))\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (!MatchBlockContainingOneCondition(block, out var condition, out var trueInst, out var falseInst))\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (!NullableLiftingTransform.MatchHasValueCall(condition, varPattern.Variable))\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (!DetectExitPoints.CompatibleExitInstruction(falseInst, parentFalseInst))\n\t\t\t{\n\t\t\t\tif (DetectExitPoints.CompatibleExitInstruction(trueInst, parentFalseInst))\n\t\t\t\t{\n\t\t\t\t\tif (!(varPattern.Variable.AddressCount == 1))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\n\t\t\t\t\tcontext.Step(\"Nullable.HasValue check -> null pattern\", block);\n\t\t\t\t\tvarPattern.ReplaceWith(new Comp(ComparisonKind.Equality, ComparisonLiftingKind.CSharp, StackType.O, Sign.None, varPattern.TestedOperand, new LdNull()));\n\t\t\t\t\tblock.Instructions.Clear();\n\t\t\t\t\tblock.Instructions.Add(falseInst);\n\t\t\t\t\treturn falseInst;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (varPattern.Variable.AddressCount == 1 && context.Settings.PatternCombinators)\n\t\t\t{\n\t\t\t\tcontext.Step(\"Nullable.HasValue check -> not null pattern\", block);\n\t\t\t\tvarPattern.ReplaceWith(new Comp(ComparisonKind.Inequality, ComparisonLiftingKind.CSharp, StackType.O, Sign.None, varPattern.TestedOperand, new LdNull()));\n\t\t\t\tblock.Instructions.Clear();\n\t\t\t\tblock.Instructions.Add(trueInst);\n\t\t\t\treturn trueInst;\n\t\t\t}\n\t\t\telse if (varPattern.Variable.AddressCount != 2)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (!(trueInst.MatchBranch(out var trueBlock) && trueBlock.Parent == block.Parent && trueBlock.IncomingEdgeCount == 1))\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (trueBlock.Instructions[0].MatchStLoc(out var newTargetVariable, out var getValueOrDefaultCall)\n\t\t\t\t&& NullableLiftingTransform.MatchGetValueOrDefault(getValueOrDefaultCall, varPattern.Variable))\n\t\t\t{\n\t\t\t\tcontext.Step(\"Nullable.HasValue check + Nullable.GetValueOrDefault pattern\", block);\n\t\t\t\tvarPattern.CheckNotNull = true;\n\t\t\t\tvarPattern.Variable = newTargetVariable;\n\t\t\t\tnewTargetVariable.Kind = VariableKind.PatternLocal;\n\t\t\t\tblock.Instructions.Clear();\n\t\t\t\tblock.Instructions.Add(trueInst);\n\t\t\t\ttrueBlock.Instructions.RemoveAt(0);\n\t\t\t\treturn DetectPropertySubPatterns(varPattern, trueBlock, parentFalseInst, (BlockContainer)block.Parent!, context, ref cfg);\n\t\t\t}\n\t\t\telse if (MatchBlockContainingOneCondition(trueBlock, out condition, out trueInst, out falseInst))\n\t\t\t{\n\t\t\t\tif (!(condition is Comp comp\n\t\t\t\t\t&& MatchInstruction.IsConstant(comp.Right)\n\t\t\t\t\t&& NullableLiftingTransform.MatchGetValueOrDefault(comp.Left, varPattern.Variable)))\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tif (!(context.Settings.RelationalPatterns || comp.Kind is ComparisonKind.Equality or ComparisonKind.Inequality))\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tbool negated = false;\n\t\t\t\tif (!DetectExitPoints.CompatibleExitInstruction(falseInst, parentFalseInst))\n\t\t\t\t{\n\t\t\t\t\tif (!DetectExitPoints.CompatibleExitInstruction(trueInst, parentFalseInst))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tExtensionMethods.Swap(ref trueInst, ref falseInst);\n\t\t\t\t\tnegated = true;\n\t\t\t\t}\n\t\t\t\tif (comp.Kind == (negated ? ComparisonKind.Equality : ComparisonKind.Inequality))\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tif (negated && !context.Settings.PatternCombinators)\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tcontext.Step(\"Nullable.HasValue check + Nullable.GetValueOrDefault pattern\", block);\n\t\t\t\t// varPattern: match (v = testedOperand)\n\t\t\t\t// comp: comp.i4(call GetValueOrDefault(ldloca v) != ldc.i4 42)\n\t\t\t\t// =>\n\t\t\t\t// comp.i4.lifted(testedOperand != ldc.i4 42)\n\t\t\t\tblock.Instructions.Clear();\n\t\t\t\tblock.Instructions.Add(trueInst);\n\t\t\t\ttrueBlock.Instructions.Clear();\n\t\t\t\tcomp.Left = varPattern.TestedOperand;\n\t\t\t\tcomp.LiftingKind = ComparisonLiftingKind.CSharp;\n\t\t\t\tif (negated)\n\t\t\t\t{\n\t\t\t\t\tcomp = Comp.LogicNot(comp);\n\t\t\t\t}\n\t\t\t\tvarPattern.ReplaceWith(comp);\n\t\t\t\treturn trueInst;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tprivate static bool PropertyOrFieldAccess(ILInstruction operand, [NotNullWhen(true)] out ILInstruction? target, [NotNullWhen(true)] out IMember? member)\n\t\t{\n\t\t\tif (operand is CallInstruction {\n\t\t\t\tMethod: {\n\t\t\t\t\tSymbolKind: SymbolKind.Accessor,\n\t\t\t\t\tAccessorKind: MethodSemanticsAttributes.Getter,\n\t\t\t\t\tAccessorOwner: { } _member\n\t\t\t\t},\n\t\t\t\tArguments: [var _target]\n\t\t\t})\n\t\t\t{\n\t\t\t\ttarget = _target;\n\t\t\t\tmember = _member;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (operand.MatchLdFld(out target, out var field))\n\t\t\t{\n\t\t\t\tmember = field;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tmember = null;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tprivate static bool MatchBlockContainingOneCondition(Block block, [NotNullWhen(true)] out ILInstruction? condition, [NotNullWhen(true)] out ILInstruction? trueInst, [NotNullWhen(true)] out ILInstruction? falseInst)\n\t\t{\n\t\t\tswitch (block.Instructions.Count)\n\t\t\t{\n\t\t\t\tcase 2:\n\t\t\t\t\treturn block.MatchIfAtEndOfBlock(out condition, out trueInst, out falseInst);\n\t\t\t\tcase 3:\n\t\t\t\t\tcondition = null;\n\t\t\t\t\tif (!block.MatchIfAtEndOfBlock(out var loadTemp, out trueInst, out falseInst))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!(loadTemp.MatchLdLoc(out var tempVar) && tempVar.IsSingleDefinition && tempVar.LoadCount == 1))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!block.Instructions[0].MatchStLoc(tempVar, out condition))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\twhile (condition.MatchLogicNot(out var arg))\n\t\t\t\t\t{\n\t\t\t\t\t\tcondition = arg;\n\t\t\t\t\t\tExtensionMethods.Swap(ref trueInst, ref falseInst);\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\tcondition = null;\n\t\t\t\t\ttrueInst = null;\n\t\t\t\t\tfalseInst = null;\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tprivate static bool CheckAllUsesDominatedBy(ILVariable v, BlockContainer container, ILInstruction trueInst,\n\t\t\tILInstruction storeToV, ILInstruction? loadInNullCheck, ILTransformContext context, ref ControlFlowGraph? cfg)\n\t\t{\n\t\t\tvar targetBlock = trueInst as Block;\n\t\t\tif (targetBlock == null && !trueInst.MatchBranch(out targetBlock))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (targetBlock.Parent != container)\n\t\t\t\treturn false;\n\t\t\tif (targetBlock.IncomingEdgeCount != 1)\n\t\t\t\treturn false;\n\t\t\tcfg ??= new ControlFlowGraph(container, context.CancellationToken);\n\t\t\tvar targetBlockNode = cfg.GetNode(targetBlock);\n\t\t\tvar uses = v.LoadInstructions.Concat<ILInstruction>(v.AddressInstructions)\n\t\t\t\t.Concat(v.StoreInstructions.Cast<ILInstruction>());\n\t\t\tforeach (var use in uses)\n\t\t\t{\n\t\t\t\tif (use == storeToV || use == loadInNullCheck)\n\t\t\t\t\tcontinue;\n\t\t\t\tBlock? found = null;\n\t\t\t\tfor (ILInstruction? current = use; current != null; current = current.Parent)\n\t\t\t\t{\n\t\t\t\t\tif (current.Parent == container)\n\t\t\t\t\t{\n\t\t\t\t\t\tfound = (Block)current;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (found == null)\n\t\t\t\t\treturn false;\n\t\t\t\tvar node = cfg.GetNode(found);\n\t\t\t\tif (!targetBlockNode.Dominates(node))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t/// Block {\n\t\t///\t\t...\n\t\t///\t\t[stloc temp(ldloc testedOperand)]\n\t\t/// \tif (comp.o(isinst T(ldloc testedOperand) == ldnull)) br falseBlock\n\t\t/// \tbr unboxBlock\n\t\t/// }\n\t\t/// \n\t\t/// Block unboxBlock (incoming: 1) {\n\t\t/// \tstloc V(unbox.any T(ldloc temp))\n\t\t/// \t...\n\t\t/// }\n\t\t/// =>\n\t\t/// Block {\n\t\t///\t\t...\n\t\t///\t\tif (match.type[T].notnull(V = testedOperand)) br unboxBlock\n\t\t///\t\tbr falseBlock\n\t\t///\t}\n\t\tprivate bool PatternMatchValueTypes(Block block, BlockContainer container, ILTransformContext context, ref ControlFlowGraph? cfg)\n\t\t{\n\t\t\tif (!MatchIsInstBlock(block, out var type, out var testedOperand, out var testedVariable,\n\t\t\t\tout var boxType1, out var unboxBlock, out var falseInst))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tStLoc? tempStore = block.Instructions.ElementAtOrDefault(block.Instructions.Count - 3) as StLoc;\n\t\t\tif (tempStore == null || !tempStore.Value.MatchLdLoc(testedVariable))\n\t\t\t{\n\t\t\t\ttempStore = null;\n\t\t\t}\n\t\t\tif (!MatchUnboxBlock(unboxBlock, type, out var unboxOperand, out var boxType2, out var storeToV))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!object.Equals(boxType1, boxType2))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (unboxOperand == testedVariable)\n\t\t\t{\n\t\t\t\t// do nothing\n\t\t\t}\n\t\t\telse if (unboxOperand == tempStore?.Variable)\n\t\t\t{\n\t\t\t\tif (!(tempStore.Variable.IsSingleDefinition && tempStore.Variable.LoadCount == 1))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!CheckAllUsesDominatedBy(storeToV.Variable, container, unboxBlock, storeToV, null, context, ref cfg))\n\t\t\t\treturn false;\n\t\t\tcontext.Step($\"PatternMatching with {storeToV.Variable.Name}\", block);\n\t\t\tvar ifInst = (IfInstruction)block.Instructions.SecondToLastOrDefault()!;\n\t\t\tifInst.Condition = new MatchInstruction(storeToV.Variable, testedOperand) {\n\t\t\t\tCheckNotNull = true,\n\t\t\t\tCheckType = true\n\t\t\t};\n\t\t\tifInst.TrueInst = new Branch(unboxBlock);\n\t\t\tblock.Instructions[^1] = falseInst;\n\t\t\tunboxBlock.Instructions.RemoveAt(0);\n\t\t\tif (unboxOperand == tempStore?.Variable)\n\t\t\t{\n\t\t\t\tblock.Instructions.Remove(tempStore);\n\t\t\t}\n\t\t\t// HACK: condition detection uses StartILOffset of blocks to decide which branch of if-else\n\t\t\t// should become the then-branch. Change the unboxBlock StartILOffset from an offset inside\n\t\t\t// the pattern matching machinery to an offset belonging to an instruction in the then-block.\n\t\t\tunboxBlock.SetILRange(unboxBlock.Instructions[0]);\n\t\t\tstoreToV.Variable.Kind = VariableKind.PatternLocal;\n\t\t\tDetectPropertySubPatterns((MatchInstruction)ifInst.Condition, unboxBlock, falseInst, container, context, ref cfg);\n\t\t\treturn true;\n\t\t}\n\n\t\t///\t...\n\t\t/// if (comp.o(isinst T(ldloc testedOperand) == ldnull)) br falseBlock\n\t\t/// br unboxBlock\n\t\t/// - or -\n\t\t/// ...\n\t\t/// if (comp.o(isinst T(box ``0(ldloc testedOperand)) == ldnull)) br falseBlock\n\t\t/// br unboxBlock\n\t\tprivate bool MatchIsInstBlock(Block block,\n\t\t\t[NotNullWhen(true)] out IType? type,\n\t\t\t[NotNullWhen(true)] out ILInstruction? testedOperand,\n\t\t\t[NotNullWhen(true)] out ILVariable? testedVariable,\n\t\t\tout IType? boxType,\n\t\t\t[NotNullWhen(true)] out Block? unboxBlock,\n\t\t\t[NotNullWhen(true)] out ILInstruction? falseInst)\n\t\t{\n\t\t\ttype = null;\n\t\t\ttestedOperand = null;\n\t\t\ttestedVariable = null;\n\t\t\tboxType = null;\n\t\t\tunboxBlock = null;\n\t\t\tif (!block.MatchIfAtEndOfBlock(out var condition, out var trueInst, out falseInst))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (condition.MatchCompEqualsNull(out var arg))\n\t\t\t{\n\t\t\t\tExtensionMethods.Swap(ref trueInst, ref falseInst);\n\t\t\t}\n\t\t\telse if (condition.MatchCompNotEqualsNull(out arg))\n\t\t\t{\n\t\t\t\t// do nothing\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!arg.MatchIsInst(out testedOperand, out type))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!(testedOperand.MatchBox(out var boxArg, out boxType) && boxType.Kind == TypeKind.TypeParameter))\n\t\t\t{\n\t\t\t\tboxArg = testedOperand;\n\t\t\t}\n\t\t\tif (!boxArg.MatchLdLoc(out testedVariable))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn trueInst.MatchBranch(out unboxBlock) && unboxBlock.Parent == block.Parent;\n\t\t}\n\n\t\t/// Block unboxBlock (incoming: 1) {\n\t\t/// \tstloc V(unbox.any T(ldloc testedOperand))\n\t\t/// \t...\n\t\t/// \t- or -\n\t\t/// \tstloc V(unbox.any T(isinst T(box ``0(ldloc testedOperand))))\n\t\t/// \t...\n\t\t/// }\n\t\tprivate bool MatchUnboxBlock(Block unboxBlock, IType type, [NotNullWhen(true)] out ILVariable? testedVariable,\n\t\t\tout IType? boxType, [NotNullWhen(true)] out StLoc? storeToV)\n\t\t{\n\t\t\tboxType = null;\n\t\t\tstoreToV = null;\n\t\t\ttestedVariable = null;\n\t\t\tif (unboxBlock.IncomingEdgeCount != 1)\n\t\t\t\treturn false;\n\t\t\tstoreToV = unboxBlock.Instructions[0] as StLoc;\n\t\t\tif (storeToV == null)\n\t\t\t\treturn false;\n\t\t\tvar value = storeToV.Value;\n\t\t\tif (!(value.MatchUnboxAny(out var arg, out var t) && t.Equals(type)))\n\t\t\t\treturn false;\n\t\t\tif (arg.MatchIsInst(out var isinstArg, out var isinstType) && isinstType.Equals(type))\n\t\t\t{\n\t\t\t\targ = isinstArg;\n\t\t\t}\n\t\t\tif (arg.MatchBox(out var boxArg, out boxType) && boxType.Kind == TypeKind.TypeParameter)\n\t\t\t{\n\t\t\t\targ = boxArg;\n\t\t\t}\n\t\t\tif (!arg.MatchLdLoc(out testedVariable))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (boxType != null && !boxType.Equals(testedVariable.Type))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs",
    "content": "// Copyright (c) 2017 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\tclass ProxyCallReplacer : IILTransform\n\t{\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.AsyncAwait)\n\t\t\t\treturn;\n\t\t\tforeach (var inst in function.Descendants.OfType<CallInstruction>())\n\t\t\t{\n\t\t\t\tRun(inst, context);\n\t\t\t}\n\t\t}\n\n\t\tvoid Run(CallInstruction inst, ILTransformContext context)\n\t\t{\n\t\t\tif (inst.Method.IsStatic)\n\t\t\t\treturn;\n\t\t\tif (inst.Method.MetadataToken.IsNil || inst.Method.MetadataToken.Kind != HandleKind.MethodDefinition)\n\t\t\t\treturn;\n\t\t\tvar handle = (MethodDefinitionHandle)inst.Method.MetadataToken;\n\t\t\tif (!IsDefinedInCurrentOrOuterClass(inst.Method, context.Function.Method.DeclaringTypeDefinition))\n\t\t\t\treturn;\n\t\t\tif (!inst.Method.IsCompilerGeneratedOrIsInCompilerGeneratedClass())\n\t\t\t\treturn;\n\t\t\tvar metadata = context.PEFile.Metadata;\n\t\t\tMethodDefinition methodDef = metadata.GetMethodDefinition((MethodDefinitionHandle)inst.Method.MetadataToken);\n\t\t\tif (!methodDef.HasBody())\n\t\t\t\treturn;\n\t\t\t// Use the callee's generic context\n\t\t\tvar genericContext = new GenericContext(inst.Method);\n\t\t\t// partially copied from CSharpDecompiler\n\t\t\tvar ilReader = context.CreateILReader();\n\t\t\tvar body = context.PEFile.GetMethodBody(methodDef.RelativeVirtualAddress);\n\t\t\tvar proxyFunction = ilReader.ReadIL(handle, body, genericContext, ILFunctionKind.TopLevelFunction, context.CancellationToken);\n\t\t\tvar transformContext = new ILTransformContext(context, proxyFunction);\n\t\t\tproxyFunction.RunTransforms(CSharp.CSharpDecompiler.EarlyILTransforms(), transformContext);\n\t\t\tif (!(proxyFunction.Body is BlockContainer blockContainer))\n\t\t\t\treturn;\n\t\t\tif (blockContainer.Blocks.Count != 1)\n\t\t\t\treturn;\n\t\t\tvar block = blockContainer.Blocks[0];\n\t\t\tCall call;\n\t\t\tILInstruction returnValue;\n\t\t\tswitch (block.Instructions.Count)\n\t\t\t{\n\t\t\t\tcase 1:\n\t\t\t\t\t// leave IL_0000 (call Test(ldloc this, ldloc A_1))\n\t\t\t\t\tif (!block.Instructions[0].MatchLeave(blockContainer, out returnValue))\n\t\t\t\t\t\treturn;\n\t\t\t\t\tcall = returnValue as Call;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\t// call Test(ldloc this, ldloc A_1)\n\t\t\t\t\t// leave IL_0000(nop)\n\t\t\t\t\tcall = block.Instructions[0] as Call;\n\t\t\t\t\tif (!block.Instructions[1].MatchLeave(blockContainer, out returnValue))\n\t\t\t\t\t\treturn;\n\t\t\t\t\tif (!returnValue.MatchNop())\n\t\t\t\t\t\treturn;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (call == null || call.Method.IsConstructor)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (call.Method.IsStatic || call.Method.Parameters.Count != inst.Method.Parameters.Count)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// check if original arguments are only correct ldloc calls\n\t\t\tfor (int i = 0; i < call.Arguments.Count; i++)\n\t\t\t{\n\t\t\t\tvar originalArg = call.Arguments[i];\n\t\t\t\tif (!originalArg.MatchLdLoc(out ILVariable var) ||\n\t\t\t\t\tvar.Kind != VariableKind.Parameter ||\n\t\t\t\t\tvar.Index != i - 1)\n\t\t\t\t{\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontext.Step(\"Replace proxy: \" + inst.Method.Name + \" with \" + call.Method.Name, inst);\n\t\t\t// Apply the wrapper call's substitution to the actual method call.\n\t\t\tCall newInst = new Call(call.Method.Specialize(inst.Method.Substitution));\n\t\t\t// copy flags\n\t\t\tnewInst.ConstrainedTo = call.ConstrainedTo;\n\t\t\tnewInst.ILStackWasEmpty = inst.ILStackWasEmpty;\n\t\t\tnewInst.IsTail = call.IsTail & inst.IsTail;\n\t\t\t// copy IL ranges\n\t\t\tnewInst.AddILRange(inst);\n\t\t\tnewInst.Arguments.ReplaceList(inst.Arguments);\n\t\t\tinst.ReplaceWith(newInst);\n\t\t}\n\n\t\tstatic bool IsDefinedInCurrentOrOuterClass(IMethod method, ITypeDefinition declaringTypeDefinition)\n\t\t{\n\t\t\twhile (declaringTypeDefinition != null)\n\t\t\t{\n\t\t\t\tif (method.DeclaringTypeDefinition == declaringTypeDefinition)\n\t\t\t\t\treturn true;\n\t\t\t\tdeclaringTypeDefinition = declaringTypeDefinition.DeclaringTypeDefinition;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/ReduceNestingTransform.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.IL.ControlFlow;\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\t/// <summary>\n\t/// Improves code quality by duplicating keyword exits to reduce nesting and restoring IL order.\n\t/// </summary>\n\t/// <remarks>\n\t/// ConditionDetection and DetectSwitchBody both have aggressive inlining policies for else blocks and default cases respectively.\n\t/// This can lead to excessive indentation when the entire rest of the method/loop is included in the else block/default case.\n\t/// When an If/SwitchInstruction is followed immediately by a keyword exit, the exit can be moved into the child blocks\n\t/// allowing the else block or default case to be moved after the if/switch as all prior cases exit.\n\t/// Most importantly, this transformation does not change the IL order of any code.\n\t///\n\t/// ConditionDetection also has a block exit priority system to assist exit point reduction which in some cases ignores IL order.\n\t/// After HighLevelLoopTransform has run, all structures have been detected and preference can be returned to maintaining IL ordering.\n\t/// </remarks>\n\tpublic class ReduceNestingTransform : IILTransform\n\t{\n\t\tprivate ILTransformContext context;\n\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tthis.context = context;\n\t\t\tVisit((BlockContainer)function.Body, null);\n\n\t\t\tforeach (var node in function.Descendants.OfType<TryFinally>())\n\t\t\t{\n\t\t\t\tEliminateRedundantTryFinally(node, context);\n\t\t\t}\n\t\t}\n\n\t\tprivate void Visit(BlockContainer container, Block continueTarget)\n\t\t{\n\t\t\tswitch (container.Kind)\n\t\t\t{\n\t\t\t\tcase ContainerKind.Loop:\n\t\t\t\tcase ContainerKind.While:\n\t\t\t\t\tcontinueTarget = container.EntryPoint;\n\t\t\t\t\tbreak;\n\t\t\t\tcase ContainerKind.DoWhile:\n\t\t\t\tcase ContainerKind.For:\n\t\t\t\t\tcontinueTarget = container.Blocks.Last();\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tfor (int i = 0; i < container.Blocks.Count; i++)\n\t\t\t{\n\t\t\t\tvar block = container.Blocks[i];\n\t\t\t\t// Note: it's possible for additional blocks to be appended to the container\n\t\t\t\t// by the Visit() call; but there should be no other changes to the Blocks collection.\n\t\t\t\tVisit(block, continueTarget);\n\t\t\t\tDebug.Assert(container.Blocks[i] == block);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Visits a block in context\n\t\t/// </summary>\n\t\t/// <param name=\"block\"></param>\n\t\t/// <param name=\"continueTarget\">Marks the target block of continue statements.</param>\n\t\t/// <param name=\"nextInstruction\">The instruction following the end point of the block. Can only be null if the end point is unreachable.</param>\n\t\tprivate void Visit(Block block, Block continueTarget, ILInstruction nextInstruction = null)\n\t\t{\n\t\t\tDebug.Assert(block.HasFlag(InstructionFlags.EndPointUnreachable) || nextInstruction != null);\n\n\t\t\t// process each instruction in the block.\n\t\t\tfor (int i = 0; i < block.Instructions.Count; i++)\n\t\t\t{\n\t\t\t\t//  Transformations may be applied to the current and following instructions but already processed instructions will not be changed\n\t\t\t\tvar inst = block.Instructions[i];\n\n\t\t\t\t// the next instruction to be executed. Transformations will change the next instruction, so this is a method instead of a variable\n\t\t\t\tILInstruction NextInsn() => block.Instructions.ElementAtOrDefault(i + 1) ?? nextInstruction;\n\n\t\t\t\tswitch (inst)\n\t\t\t\t{\n\t\t\t\t\tcase BlockContainer container:\n\t\t\t\t\t\t// visit the contents of the container\n\t\t\t\t\t\tVisit(container, continueTarget);\n\n\t\t\t\t\t\t// reduce nesting in switch blocks\n\t\t\t\t\t\tif (container.Kind == ContainerKind.Switch &&\n\t\t\t\t\t\t\tCanDuplicateExit(NextInsn(), continueTarget, out var keywordExit1) &&\n\t\t\t\t\t\t\tReduceSwitchNesting(block, container, keywordExit1))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tRemoveRedundantExit(block, nextInstruction);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase IfInstruction ifInst:\n\t\t\t\t\t\tImproveILOrdering(block, ifInst, continueTarget);\n\n\t\t\t\t\t\t// reduce nesting in if/else blocks\n\t\t\t\t\t\tif (CanDuplicateExit(NextInsn(), continueTarget, out var keywordExit2) && ReduceNesting(block, ifInst, keywordExit2))\n\t\t\t\t\t\t\tRemoveRedundantExit(block, nextInstruction);\n\n\t\t\t\t\t\t// visit content blocks\n\t\t\t\t\t\tif (ifInst.TrueInst is Block trueBlock)\n\t\t\t\t\t\t\tVisit(trueBlock, continueTarget, NextInsn());\n\n\t\t\t\t\t\tif (ifInst.FalseInst is Block falseBlock)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (ifInst.TrueInst.HasFlag(InstructionFlags.EndPointUnreachable))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tExtractElseBlock(ifInst);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tVisit(falseBlock, continueTarget, NextInsn());\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// blocks can only exit containers via leave instructions, not fallthrough, so the only relevant context is `continueTarget`\n\t\t\t\t\t\tVisitContainers(inst, continueTarget);\n\n\t\t\t\t\t\t// reducing nesting inside Try/Using/Lock etc, may make the endpoint unreachable. \n\t\t\t\t\t\t// This should only happen by replacing a Leave with the exit instruction we're about to delete, but I can't see a good way to assert this\n\t\t\t\t\t\t// This would be better placed in ReduceNesting, but it's more difficult to find the affected instructions/blocks there than here\n\t\t\t\t\t\tif (i == block.Instructions.Count - 2 && inst.HasFlag(InstructionFlags.EndPointUnreachable))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontext.Step(\"Remove unreachable exit\", block.Instructions.Last());\n\t\t\t\t\t\t\tblock.Instructions.RemoveLast();\n\n\t\t\t\t\t\t\t// This would be the right place to check and fix the redundant continue; in TestCases.Pretty.ReduceNesting.BreakLockInLoop\n\t\t\t\t\t\t\t// but doing so would require knowledge of what `inst` is, and how it works. (eg. to target the try block and not catch or finally blocks)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// search for child containers to reduce nesting in\n\t\tprivate void VisitContainers(ILInstruction inst, Block continueTarget)\n\t\t{\n\t\t\tswitch (inst)\n\t\t\t{\n\t\t\t\tcase ILFunction _:\n\t\t\t\t\tbreak; // assume inline ILFunctions are already transformed\n\t\t\t\tcase BlockContainer cont:\n\t\t\t\t\tVisit(cont, continueTarget);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tforeach (var child in inst.Children)\n\t\t\t\t\t\tVisitContainers(child, continueTarget);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// For an if statement with an unreachable end point and no else block,\n\t\t/// inverts to match IL order of the first statement of each branch\n\t\t/// </summary>\n\t\tprivate void ImproveILOrdering(Block block, IfInstruction ifInst, Block continueTarget)\n\t\t{\n\t\t\tif (!block.HasFlag(InstructionFlags.EndPointUnreachable)\n\t\t\t\t|| !ifInst.TrueInst.HasFlag(InstructionFlags.EndPointUnreachable)\n\t\t\t\t|| !ifInst.FalseInst.MatchNop())\n\t\t\t\treturn;\n\n\t\t\tDebug.Assert(ifInst != block.Instructions.Last());\n\n\t\t\tvar trueRangeStart = ConditionDetection.GetStartILOffset(ifInst.TrueInst, out bool trueRangeIsEmpty);\n\t\t\tvar falseRangeStart = ConditionDetection.GetStartILOffset(block.Instructions[block.Instructions.IndexOf(ifInst) + 1], out bool falseRangeIsEmpty);\n\t\t\tif (trueRangeIsEmpty || falseRangeIsEmpty || falseRangeStart >= trueRangeStart)\n\t\t\t\treturn;\n\n\t\t\tif (block.Instructions.Last() is Leave leave && !leave.IsLeavingFunction && leave.TargetContainer.Kind == ContainerKind.Normal)\n\t\t\t{\n\t\t\t\t// non-keyword leave. Can't move out of the last position in the block (fall-through) without introducing goto, unless it can be replaced with a keyword (return/continue)\n\t\t\t\tif (!CanDuplicateExit(block.Instructions.Last(), continueTarget, out var keywordExit))\n\t\t\t\t\treturn;\n\n\t\t\t\tcontext.Step(\"Replace leave with keyword exit\", ifInst.TrueInst);\n\t\t\t\tblock.Instructions.Last().ReplaceWith(keywordExit.Clone());\n\t\t\t}\n\n\t\t\tConditionDetection.InvertIf(block, ifInst, context);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Reduce Nesting in if/else statements by duplicating an exit instruction.\n\t\t/// Does not affect IL order\n\t\t/// </summary>\n\t\tprivate bool ReduceNesting(Block block, IfInstruction ifInst, ILInstruction exitInst)\n\t\t{\n\t\t\t// start tallying stats for heuristics from then and else-if blocks\n\t\t\tint maxStatements = 0, maxDepth = 0;\n\t\t\tUpdateStats(ifInst.TrueInst, ref maxStatements, ref maxDepth);\n\n\t\t\t// if (cond) { ... } exit;\n\t\t\tif (ifInst.FalseInst.MatchNop())\n\t\t\t{\n\t\t\t\t// a separate heuristic to ShouldReduceNesting as there is visual balancing to be performed based on number of statments\n\t\t\t\tif (maxDepth < 2)\n\t\t\t\t\treturn false;\n\n\t\t\t\t//   ->\n\t\t\t\t// if (!cond) exit;\n\t\t\t\t// ...; exit;\n\t\t\t\tEnsureEndPointUnreachable(block, exitInst);\n\t\t\t\tDebug.Assert(ifInst == block.Instructions.SecondToLastOrDefault());\n\n\t\t\t\t// use the same exit the block has. If the block already has one (such as a leave from a try), keep it in place\n\t\t\t\tEnsureEndPointUnreachable(ifInst.TrueInst, block.Instructions.Last());\n\t\t\t\tConditionDetection.InvertIf(block, ifInst, context);\n\n\t\t\t\t// ensure the exit inst of the if instruction is a keyword\n\t\t\t\tDebug.Assert(!(ifInst.TrueInst is Block));\n\t\t\t\tif (!ifInst.TrueInst.Match(exitInst).Success)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(ifInst.TrueInst is Leave);\n\t\t\t\t\tcontext.Step(\"Replace leave with keyword exit\", ifInst.TrueInst);\n\t\t\t\t\tifInst.TrueInst.ReplaceWith(exitInst.Clone());\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// else-if trees are considered as a single group from the root IfInstruction\n\t\t\tif (GetElseIfParent(ifInst) != null)\n\t\t\t\treturn false;\n\n\t\t\t// find the else block and tally stats for each else-if block\n\t\t\twhile (Block.Unwrap(ifInst.FalseInst) is IfInstruction elseIfInst)\n\t\t\t{\n\t\t\t\tUpdateStats(elseIfInst.TrueInst, ref maxStatements, ref maxDepth);\n\t\t\t\tifInst = elseIfInst;\n\t\t\t}\n\n\t\t\tif (!ShouldReduceNesting(ifInst.FalseInst, maxStatements, maxDepth))\n\t\t\t\treturn false;\n\n\t\t\t// extract the else block and insert exit points all the way up the else-if tree\n\t\t\tdo\n\t\t\t{\n\t\t\t\tvar elseIfInst = GetElseIfParent(ifInst);\n\n\t\t\t\t// if (cond) { ... } else { ... } exit;\n\t\t\t\t//   ->\n\t\t\t\t// if (cond) { ...; exit; }\n\t\t\t\t// ...; exit;\n\t\t\t\tEnsureEndPointUnreachable(ifInst.TrueInst, exitInst);\n\t\t\t\tif (ifInst.FalseInst.HasFlag(InstructionFlags.EndPointUnreachable))\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(ifInst.HasFlag(InstructionFlags.EndPointUnreachable));\n\t\t\t\t\tDebug.Assert(ifInst.Parent == block);\n\t\t\t\t\tint removeAfter = ifInst.ChildIndex + 1;\n\t\t\t\t\tif (removeAfter < block.Instructions.Count)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Remove all instructions that ended up dead\n\t\t\t\t\t\t// (this should just be exitInst itself)\n\t\t\t\t\t\tDebug.Assert(block.Instructions.SecondToLastOrDefault() == ifInst);\n\t\t\t\t\t\tDebug.Assert(block.Instructions.Last() == exitInst);\n\t\t\t\t\t\tblock.Instructions.RemoveRange(removeAfter, block.Instructions.Count - removeAfter);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tExtractElseBlock(ifInst);\n\t\t\t\tifInst = elseIfInst;\n\t\t\t} while (ifInst != null);\n\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Reduce Nesting in switch statements by replacing break; in cases with the block exit, and extracting the default case\n\t\t/// Does not affect IL order\n\t\t/// </summary>\n\t\tprivate bool ReduceSwitchNesting(Block parentBlock, BlockContainer switchContainer, ILInstruction exitInst)\n\t\t{\n\t\t\t// break; from outer container cannot be brought inside the switch as the meaning would change\n\t\t\tif (exitInst is Leave leave && !leave.IsLeavingFunction)\n\t\t\t\treturn false;\n\n\t\t\t// find the default section, and ensure it has only one incoming edge\n\t\t\tvar switchInst = (SwitchInstruction)switchContainer.EntryPoint.Instructions.Single();\n\t\t\tvar defaultSection = switchInst.Sections.MaxBy(s => s.Labels.Count());\n\t\t\tif (!defaultSection.Body.MatchBranch(out var defaultBlock) || defaultBlock.IncomingEdgeCount != 1)\n\t\t\t\treturn false;\n\t\t\tif (defaultBlock.Parent != switchContainer)\n\t\t\t\treturn false;\n\n\t\t\t// tally stats for heuristic from each case block\n\t\t\tint maxStatements = 0, maxDepth = 0;\n\t\t\tforeach (var section in switchInst.Sections)\n\t\t\t\tif (section != defaultSection && section.Body.MatchBranch(out var caseBlock) && caseBlock.Parent == switchContainer)\n\t\t\t\t\tUpdateStats(caseBlock, ref maxStatements, ref maxDepth);\n\n\t\t\tif (!ShouldReduceNesting(defaultBlock, maxStatements, maxDepth))\n\t\t\t\treturn false;\n\n\t\t\tDebug.Assert(defaultBlock.HasFlag(InstructionFlags.EndPointUnreachable));\n\n\t\t\t// ensure the default case dominator tree has no exits (branches to other cases)\n\t\t\tvar cfg = new ControlFlowGraph(switchContainer, context.CancellationToken);\n\t\t\tvar defaultNode = cfg.GetNode(defaultBlock);\n\t\t\tvar defaultTree = TreeTraversal.PreOrder(defaultNode, n => n.DominatorTreeChildren).ToList();\n\t\t\tif (defaultTree.SelectMany(n => n.Successors).Any(n => !defaultNode.Dominates(n)))\n\t\t\t\treturn false;\n\n\t\t\tif (defaultTree.Count > 1 && !(parentBlock.Parent is BlockContainer))\n\t\t\t\treturn false;\n\n\t\t\tcontext.Step(\"Extract default case of switch\", switchContainer);\n\n\t\t\t// if the switch container is followed by an instruction, it must be a Leave from a try/pinned/etc or exitInst\n\t\t\t// When it's a leave from a container, it's better to let the extracted default block 'fall through' rather than duplicating whatever\n\t\t\t// instruction eventually follows the container\n\t\t\tif (parentBlock.Instructions.SecondToLastOrDefault() == switchContainer)\n\t\t\t{\n\t\t\t\tif (defaultBlock.Instructions.Last().MatchLeave(switchContainer))\n\t\t\t\t\tdefaultBlock.Instructions.Last().ReplaceWith(parentBlock.Instructions.Last());\n\n\t\t\t\tparentBlock.Instructions.RemoveLast();\n\t\t\t}\n\n\t\t\t// replace all break; statements with the exitInst\n\t\t\tvar leaveInstructions = switchContainer.Descendants.Where(inst => inst.MatchLeave(switchContainer));\n\t\t\tforeach (var leaveInst in leaveInstructions.ToArray())\n\t\t\t\tleaveInst.ReplaceWith(exitInst.Clone());\n\n\t\t\t// replace the default section branch with a break;\n\t\t\tdefaultSection.Body.ReplaceWith(new Leave(switchContainer));\n\n\t\t\t// remove all default blocks from the switch container\n\t\t\tvar defaultBlocks = defaultTree.Select(c => (Block)c.UserData).ToList();\n\t\t\tforeach (var block in defaultBlocks)\n\t\t\t\tswitchContainer.Blocks.Remove(block);\n\n\t\t\tDebug.Assert(parentBlock.Instructions.Last() == switchContainer);\n\t\t\tparentBlock.Instructions.AddRange(defaultBlock.Instructions);\n\n\t\t\t// add any additional blocks from the default case to the parent container\n\t\t\tDebug.Assert(defaultBlocks[0] == defaultBlock);\n\t\t\tif (defaultBlocks.Count > 1)\n\t\t\t{\n\t\t\t\tvar parentContainer = (BlockContainer)parentBlock.Parent;\n\t\t\t\tint insertAt = parentContainer.Blocks.IndexOf(parentBlock) + 1;\n\t\t\t\tforeach (var block in defaultBlocks.Skip(1))\n\t\t\t\t\tparentContainer.Blocks.Insert(insertAt++, block);\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Checks if an exit is a duplicable keyword exit (return; break; continue;)\n\t\t/// </summary>\n\t\tprivate bool CanDuplicateExit(ILInstruction exit, Block continueTarget, out ILInstruction keywordExit)\n\t\t{\n\t\t\tkeywordExit = exit;\n\t\t\tif (exit != null && exit.MatchBranch(continueTarget))\n\t\t\t\treturn true;  // keyword is continue\n\n\t\t\tif (!(exit is Leave leave && leave.Value.MatchNop()))\n\t\t\t\treturn false; // don't duplicate valued returns\n\n\t\t\tif (leave.IsLeavingFunction || leave.TargetContainer.Kind != ContainerKind.Normal)\n\t\t\t\treturn true; // keyword is return || break\n\n\t\t\t// leave from a try/pinned/lock etc, check if the target (the instruction following the target container) is duplicable, if so, set keywordExit to that\n\t\t\tILInstruction leavingInst = leave.TargetContainer;\n\t\t\tDebug.Assert(!leavingInst.HasFlag(InstructionFlags.EndPointUnreachable));\n\t\t\twhile (!(leavingInst.Parent is Block b) || leavingInst == b.Instructions.Last())\n\t\t\t{\n\t\t\t\tif (leavingInst.Parent is TryFinally tryFinally)\n\t\t\t\t{\n\t\t\t\t\tif (leavingInst.SlotInfo == TryFinally.FinallyBlockSlot)\n\t\t\t\t\t{ // cannot duplicate leaves from finally containers\n\t\t\t\t\t\tDebug.Assert(leave.TargetContainer == tryFinally.FinallyBlock); //finally cannot have control flow\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif (tryFinally.HasFlag(InstructionFlags.EndPointUnreachable))\n\t\t\t\t\t{ // finally block changes return value/throws an exception? Yikes. Lets leave it alone\n\t\t\t\t\t\tDebug.Assert(tryFinally.FinallyBlock.HasFlag(InstructionFlags.EndPointUnreachable));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (leavingInst.Parent is TryFault tryFault && leavingInst.SlotInfo == TryFault.FaultBlockSlot)\n\t\t\t\t{ // cannot duplicate leaves from fault containers either\n\t\t\t\t\tDebug.Assert(leave.TargetContainer == tryFault.FaultBlock);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tleavingInst = leavingInst.Parent;\n\t\t\t\tDebug.Assert(!leavingInst.HasFlag(InstructionFlags.EndPointUnreachable));\n\t\t\t\tDebug.Assert(!(leavingInst is ILFunction));\n\t\t\t}\n\n\t\t\tvar block = (Block)leavingInst.Parent;\n\t\t\tvar targetInst = block.Instructions[block.Instructions.IndexOf(leavingInst) + 1];\n\t\t\treturn CanDuplicateExit(targetInst, continueTarget, out keywordExit);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Ensures the end point of a block is unreachable by duplicating and appending the [exit] instruction following the end point\n\t\t/// </summary>\n\t\t/// <param name=\"inst\">The instruction/block of interest</param>\n\t\t/// <param name=\"fallthroughExit\">The next instruction to be executed (provided inst does not exit)</param>\n\t\tprivate void EnsureEndPointUnreachable(ILInstruction inst, ILInstruction fallthroughExit)\n\t\t{\n\t\t\tif (!(inst is Block block))\n\t\t\t{\n\t\t\t\tDebug.Assert(inst.HasFlag(InstructionFlags.EndPointUnreachable));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!block.HasFlag(InstructionFlags.EndPointUnreachable))\n\t\t\t{\n\t\t\t\tcontext.Step(\"Duplicate block exit\", fallthroughExit);\n\t\t\t\tblock.Instructions.Add(fallthroughExit.Clone());\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Removes a redundant block exit instruction.\n\t\t/// </summary>\n\t\tprivate void RemoveRedundantExit(Block block, ILInstruction implicitExit)\n\t\t{\n\t\t\tif (block.Instructions.Last().Match(implicitExit).Success)\n\t\t\t{\n\t\t\t\tcontext.Step(\"Remove redundant exit\", block.Instructions.Last());\n\t\t\t\tblock.Instructions.RemoveLast();\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Determines if an IfInstruction is an else-if and returns the preceeding (parent) IfInstruction\n\t\t///\n\t\t/// [else-]if (parent-cond) else { ifInst }\n\t\t/// </summary>\n\t\tprivate IfInstruction GetElseIfParent(IfInstruction ifInst)\n\t\t{\n\t\t\tDebug.Assert(ifInst.Parent is Block);\n\t\t\tif (Block.Unwrap(ifInst.Parent) == ifInst && // only instruction in block\n\t\t\t\t\tifInst.Parent.Parent is IfInstruction elseIfInst && // parent of block is an IfInstruction\n\t\t\t\t\telseIfInst.FalseInst == ifInst.Parent) // part of the false branch not the true branch\n\t\t\t\treturn elseIfInst;\n\n\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Adds a code path to the current heuristic tally\n\t\t/// </summary>\n\t\tprivate void UpdateStats(ILInstruction inst, ref int maxStatements, ref int maxDepth)\n\t\t{\n\t\t\tint numStatements = 0;\n\t\t\tComputeStats(inst, ref numStatements, ref maxDepth, 0);\n\t\t\tmaxStatements = Math.Max(numStatements, maxStatements);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Recursively computes the number of statements and maximum nested depth of an instruction\n\t\t/// </summary>\n\t\tprivate void ComputeStats(ILInstruction inst, ref int numStatements, ref int maxDepth, int currentDepth, bool isStatement = true)\n\t\t{\n\t\t\tif (isStatement)\n\t\t\t\tnumStatements++;\n\n\t\t\tif (currentDepth > maxDepth)\n\t\t\t{\n\t\t\t\tDebug.Assert(isStatement);\n\t\t\t\tmaxDepth = currentDepth;\n\t\t\t}\n\n\t\t\t// enumerate children statements and containers\n\t\t\tswitch (inst)\n\t\t\t{\n\t\t\t\tcase Block block:\n\t\t\t\t\tif (isStatement)\n\t\t\t\t\t\tnumStatements--; // don't count blocks as statements\n\n\t\t\t\t\t// add each child as a statement (unless we're a named block)\n\t\t\t\t\tforeach (var child in block.Instructions)\n\t\t\t\t\t\tComputeStats(child, ref numStatements, ref maxDepth, currentDepth, block.Kind != BlockKind.CallWithNamedArgs && block.Kind != BlockKind.CallInlineAssign);\n\n\t\t\t\t\t// final instruction as an expression\n\t\t\t\t\tComputeStats(block.FinalInstruction, ref numStatements, ref maxDepth, currentDepth, false);\n\t\t\t\t\tbreak;\n\t\t\t\tcase BlockContainer container:\n\t\t\t\t\tif (!isStatement)\n\t\t\t\t\t\tnumStatements++; //always add a statement for a container in an expression\n\n\t\t\t\t\tvar containerBody = container.EntryPoint;\n\t\t\t\t\tif (container.Kind == ContainerKind.For || container.Kind == ContainerKind.While)\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(isStatement);\n\n\t\t\t\t\t\tif (!container.MatchConditionBlock(container.EntryPoint, out _, out containerBody))\n\t\t\t\t\t\t\tthrow new NotSupportedException(\"Invalid condition block in loop.\");\n\t\t\t\t\t}\n\n\t\t\t\t\t// don't count implicit leave. Can't avoid counting for loop initializers but close enough, for loops can have an extra statement of visual weight\n\t\t\t\t\tvar lastInst = containerBody.Instructions.Last();\n\t\t\t\t\tif ((container.Kind == ContainerKind.For || container.Kind == ContainerKind.DoWhile) && lastInst.MatchBranch(container.Blocks.Last()) ||\n\t\t\t\t\t\t(container.Kind == ContainerKind.Loop || container.Kind == ContainerKind.While) && lastInst.MatchBranch(container.Blocks[0]) ||\n\t\t\t\t\t\t container.Kind == ContainerKind.Normal && lastInst.MatchLeave(container) ||\n\t\t\t\t\t\t container.Kind == ContainerKind.Switch) // SwitchInstructyion always counts as a statement anyway, so no need to count the container as well\n\t\t\t\t\t\tnumStatements--;\n\n\t\t\t\t\t// add the nested body\n\t\t\t\t\tComputeStats(containerBody, ref numStatements, ref maxDepth, currentDepth + 1);\n\t\t\t\t\tbreak;\n\t\t\t\tcase IfInstruction ifInst when ifInst.ResultType == StackType.Void:\n\t\t\t\t\tDebug.Assert(isStatement);\n\t\t\t\t\t// nested then instruction\n\t\t\t\t\tComputeStats(ifInst.TrueInst, ref numStatements, ref maxDepth, currentDepth + 1);\n\n\t\t\t\t\t// include all nested else-if instructions at the same depth\n\t\t\t\t\tvar elseInst = ifInst.FalseInst;\n\t\t\t\t\twhile (Block.Unwrap(elseInst) is IfInstruction elseIfInst)\n\t\t\t\t\t{\n\t\t\t\t\t\tnumStatements++;\n\t\t\t\t\t\tComputeStats(elseIfInst.TrueInst, ref numStatements, ref maxDepth, currentDepth + 1);\n\t\t\t\t\t\telseInst = elseIfInst.FalseInst;\n\t\t\t\t\t}\n\n\t\t\t\t\t// include all nested else instruction\n\t\t\t\t\tComputeStats(elseInst, ref numStatements, ref maxDepth, currentDepth + 1);\n\t\t\t\t\tbreak;\n\t\t\t\tcase SwitchSection section:\n\t\t\t\t\tDebug.Assert(!isStatement); // labels are just children of the SwitchInstruction\n\t\t\t\t\tnumStatements++; // add a statement for each case label\n\n\t\t\t\t\t// add all the case blocks at the current depth\n\t\t\t\t\t// most formatters indent switch blocks twice, but we don't want this heuristic to be based on formatting\n\t\t\t\t\t// so we remain conservative and only include the increase in depth from the container and not the labels\n\t\t\t\t\tif (section.Body.MatchBranch(out var caseBlock) && caseBlock.Parent == section.Parent.Parent.Parent)\n\t\t\t\t\t\tComputeStats(caseBlock, ref numStatements, ref maxDepth, currentDepth);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ILFunction func:\n\t\t\t\t\tint bodyStatements = 0;\n\t\t\t\t\tint bodyMaxDepth = maxDepth;\n\t\t\t\t\tComputeStats(func.Body, ref bodyStatements, ref bodyMaxDepth, currentDepth);\n\t\t\t\t\tif (bodyStatements >= 2)\n\t\t\t\t\t{ // don't count inline functions\n\t\t\t\t\t\tnumStatements += bodyStatements;\n\t\t\t\t\t\tmaxDepth = bodyMaxDepth;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t// search each child instruction. Containers will contain statements and contribute to stats\n\t\t\t\t\tint subStatements = 0;\n\t\t\t\t\tforeach (var child in inst.Children)\n\t\t\t\t\t\tComputeStats(child, ref subStatements, ref maxDepth, currentDepth, false);\n\n\t\t\t\t\tnumStatements += subStatements;\n\t\t\t\t\tif (isStatement && subStatements > 0)\n\t\t\t\t\t\tnumStatements--; // don't count the first container, only its contents, because this statement is already counted\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Heuristic to determine whether it is worth duplicating exits into the preceeding sibling blocks (then/else-if/case)\n\t\t/// in order to reduce the nesting of inst by 1\n\t\t/// </summary>\n\t\t/// <param name=\"inst\">The instruction heading the nested candidate block</param>\n\t\t/// <param name=\"maxStatements\">The number of statements in the largest sibling block</param>\n\t\t/// <param name=\"maxDepth\">The relative depth of the most nested statement in the sibling blocks</param>\n\t\t/// <returns></returns>\n\t\tprivate bool ShouldReduceNesting(ILInstruction inst, int maxStatements, int maxDepth)\n\t\t{\n\t\t\tint maxStatements2 = 0, maxDepth2 = 0;\n\t\t\tUpdateStats(inst, ref maxStatements2, ref maxDepth2);\n\t\t\t// if the max depth is 2, always reduce nesting (total depth 3 or more)\n\t\t\t// if the max depth is 1, reduce nesting if this block is the largest\n\t\t\t// otherwise reduce nesting only if this block is twice as large as any other\n\t\t\treturn maxDepth2 >= 2 || maxDepth2 >= 1 && maxStatements2 > maxStatements || maxStatements2 >= 2 * maxStatements;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// if (cond) { ...; exit; } else { ... }\n\t\t/// ...;\n\t\t///   ->\n\t\t/// if (cond) { ...; exit; }\n\t\t/// ...;\n\t\t/// ...;\n\t\t/// </summary>\n\t\t/// <param name=\"ifInst\"></param>\n\t\tprivate void ExtractElseBlock(IfInstruction ifInst)\n\t\t{\n\t\t\tDebug.Assert(ifInst.TrueInst.HasFlag(InstructionFlags.EndPointUnreachable));\n\t\t\tvar block = (Block)ifInst.Parent;\n\t\t\tvar falseBlock = (Block)ifInst.FalseInst;\n\n\t\t\tcontext.Step(\"Extract else block\", ifInst);\n\t\t\tint insertAt = block.Instructions.IndexOf(ifInst) + 1;\n\t\t\tfor (int i = 0; i < falseBlock.Instructions.Count; i++)\n\t\t\t\tblock.Instructions.Insert(insertAt++, falseBlock.Instructions[i]);\n\n\t\t\tifInst.FalseInst = new Nop();\n\t\t}\n\n\t\tprivate void EliminateRedundantTryFinally(TryFinally tryFinally, ILTransformContext context)\n\t\t{\n\t\t\t/* The C# compiler sometimes generates try-finally structures for fixed statements.\n\t\t\t\tAfter our transforms runs, these are redundant and can be removed.\n\t\t\t\t.try BlockContainer {\n\t\t\t\t\tBlock IL_001a (incoming: 1) {\n\t\t\t\t\t\tPinnedRegion ...\n\t\t\t\t\t}\n\t\t\t\t} finally BlockContainer {\n\t\t\t\t\tBlock IL_003e (incoming: 1) {\n\t\t\t\t\t\tleave IL_003e (nop)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t==> PinnedRegion\n\t\t\t*/\n\t\t\tif (!(tryFinally.FinallyBlock is BlockContainer finallyContainer))\n\t\t\t\treturn;\n\t\t\tif (!finallyContainer.SingleInstruction().MatchLeave(finallyContainer))\n\t\t\t\treturn;\n\t\t\t// Finally is empty and redundant. But we'll delete the block only if there's a PinnedRegion.\n\t\t\tif (!(tryFinally.TryBlock is BlockContainer tryContainer))\n\t\t\t\treturn;\n\t\t\tif (tryContainer.Blocks.Count != 1)\n\t\t\t\treturn;\n\t\t\tvar tryBlock = tryContainer.Blocks[0];\n\t\t\tif (tryBlock.Instructions.Count == 1)\n\t\t\t{\n\t\t\t\tif (tryBlock.Instructions[0] is PinnedRegion pinnedRegion)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"Removing try-finally around PinnedRegion\", pinnedRegion);\n\t\t\t\t\ttryFinally.ReplaceWith(pinnedRegion);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (tryBlock.Instructions.Count == 2)\n\t\t\t{\n\t\t\t\tif (tryBlock.Instructions[0] is PinnedRegion pinnedRegion &&\n\t\t\t\t\ttryBlock.Instructions[1].MatchLeave(tryContainer))\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"Removing try-finally around PinnedRegion\", pinnedRegion);\n\t\t\t\t\ttryFinally.ReplaceWith(pinnedRegion);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/RemoveDeadVariableInit.cs",
    "content": "// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.FlowAnalysis;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Remove <c>HasInitialValue</c> from locals that are definitely assigned before every use\n\t/// (=the initial value is a dead store).\n\t/// \n\t/// In yield return generators, additionally removes dead 'V = null;' assignments.\n\t/// \n\t/// Additionally infers IType of stack slots that have StackType.Ref\n\t/// </summary>\n\tpublic class RemoveDeadVariableInit : IILTransform\n\t{\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tResetUsesInitialValueFlag(function, context);\n\t\t\t// Remove dead stores to variables that are never read from.\n\t\t\t// If the stored value has some side-effect, the value is unwrapped.\n\t\t\t// This is necessary to remove useless stores generated by some compilers, e.g., the F# compiler.\n\t\t\t// In yield return + async, the C# compiler tends to store null/default(T) to variables\n\t\t\t// when the variable goes out of scope.\n\t\t\tbool removeDeadStores = function.IsAsync || function.IsIterator || context.Settings.RemoveDeadStores;\n\n\t\t\tvar variableQueue = new Queue<ILVariable>(function.Variables);\n\t\t\twhile (variableQueue.Count > 0)\n\t\t\t{\n\t\t\t\tvar v = variableQueue.Dequeue();\n\t\t\t\tif (v.Kind != VariableKind.Local && v.Kind != VariableKind.StackSlot)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (!(v.RemoveIfRedundant || removeDeadStores))\n\t\t\t\t\tcontinue;\n\t\t\t\t// Skip variables that are captured in a mcs yield state-machine\n\t\t\t\t// loads of these will only be visible after DelegateConstruction step.\n\t\t\t\tif (function.StateMachineCompiledWithMono && v.StateMachineField != null)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (v.LoadCount != 0 || v.AddressCount != 0)\n\t\t\t\t\tcontinue;\n\t\t\t\tforeach (var stloc in v.StoreInstructions.OfType<StLoc>().ToArray())\n\t\t\t\t{\n\t\t\t\t\tif (stloc.Parent is Block block)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontext.Step($\"Dead store to {v.Name}\", stloc);\n\t\t\t\t\t\tif (SemanticHelper.IsPure(stloc.Value.Flags))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tblock.Instructions.Remove(stloc);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstloc.ReplaceWith(stloc.Value);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (stloc.Value is LdLoc ldloc)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvariableQueue.Enqueue(ldloc.Variable);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Try to infer IType of stack slots that are of StackType.Ref:\n\t\t\tforeach (var v in function.Variables)\n\t\t\t{\n\t\t\t\tif (v.Kind == VariableKind.StackSlot && v.StackType == StackType.Ref && v.AddressCount == 0)\n\t\t\t\t{\n\t\t\t\t\tIType newType = null;\n\t\t\t\t\t// Multiple store are possible in case of (c ? ref a : ref b) += 1, for example.\n\t\t\t\t\tforeach (var stloc in v.StoreInstructions.OfType<StLoc>())\n\t\t\t\t\t{\n\t\t\t\t\t\tvar inferredType = stloc.Value.InferType(context.TypeSystem);\n\t\t\t\t\t\t// cancel, if types of values do not match exactly\n\t\t\t\t\t\tif (newType != null && !newType.Equals(inferredType))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnewType = SpecialType.UnknownType;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnewType = inferredType;\n\t\t\t\t\t}\n\t\t\t\t\t// Only overwrite existing type, if a \"better\" type was found.\n\t\t\t\t\tif (newType != null && newType != SpecialType.UnknownType)\n\t\t\t\t\t\tv.Type = newType;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tinternal static void ResetUsesInitialValueFlag(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tvar visitor = new DefiniteAssignmentVisitor(function, context.CancellationToken);\n\t\t\tfunction.AcceptVisitor(visitor);\n\t\t\tforeach (var v in function.Variables)\n\t\t\t{\n\t\t\t\tif (v.Kind != VariableKind.Parameter && !visitor.IsPotentiallyUsedUninitialized(v))\n\t\t\t\t{\n\t\t\t\t\tv.UsesInitialValue = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/RemoveInfeasiblePathTransform.cs",
    "content": "// Copyright (c) 2021 Daniel Grunwald, Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Block IL_0018 (incoming: *) {\n\t///     stloc s(ldc.i4 1)\n\t///     br IL_0019\n\t/// }\n\t/// \n\t/// Block IL_0019 (incoming: > 1) {\n\t///     if (logic.not(ldloc s)) br IL_0027\n\t///     br IL_001d\n\t/// }\n\t/// \n\t/// replace br IL_0019 with br IL_0027\n\t/// </summary>\n\tclass RemoveInfeasiblePathTransform : IILTransform\n\t{\n\t\tvoid IILTransform.Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tforeach (var container in function.Descendants.OfType<BlockContainer>())\n\t\t\t{\n\t\t\t\tbool changed = false;\n\t\t\t\tforeach (var block in container.Blocks)\n\t\t\t\t{\n\t\t\t\t\tchanged |= DoTransform(block, context);\n\t\t\t\t}\n\n\t\t\t\tif (changed)\n\t\t\t\t{\n\t\t\t\t\tcontainer.SortBlocks(deleteUnreachableBlocks: true);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tprivate bool DoTransform(Block block, ILTransformContext context)\n\t\t{\n\t\t\tif (!MatchBlock1(block, out var s, out int value, out var br))\n\t\t\t\treturn false;\n\t\t\tif (!MatchBlock2(br.TargetBlock, s, value, out var exitInst))\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"RemoveInfeasiblePath\", br);\n\t\t\tbr.ReplaceWith(exitInst.Clone());\n\t\t\ts.RemoveIfRedundant = true;\n\t\t\treturn true;\n\t\t}\n\n\t\t// Block IL_0018 (incoming: *) {\n\t\t//  stloc s(ldc.i4 1)\n\t\t//  br IL_0019\n\t\t// }\n\t\tprivate bool MatchBlock1(Block block, [NotNullWhen(true)] out ILVariable? variable, out int constantValue, [NotNullWhen(true)] out Branch? branch)\n\t\t{\n\t\t\tvariable = null;\n\t\t\tconstantValue = 0;\n\t\t\tbranch = null;\n\t\t\tif (block.Instructions.Count != 2)\n\t\t\t\treturn false;\n\t\t\tif (block.Instructions[0] is not StLoc {\n\t\t\t\tVariable: { Kind: VariableKind.StackSlot } s,\n\t\t\t\tValue: LdcI4 { Value: 0 or 1 } valueInst\n\t\t\t})\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (block.Instructions[1] is not Branch br)\n\t\t\t\treturn false;\n\t\t\tvariable = s;\n\t\t\tconstantValue = valueInst.Value;\n\t\t\tbranch = br;\n\t\t\treturn true;\n\t\t}\n\n\t\t// Block IL_0019 (incoming: > 1) {\n\t\t//     if (logic.not(ldloc s)) br IL_0027\n\t\t//     br IL_001d\n\t\t// }\n\t\tbool MatchBlock2(Block block, ILVariable s, int constantValue, [NotNullWhen(true)] out ILInstruction? exitInst)\n\t\t{\n\t\t\texitInst = null;\n\t\t\tif (block.Instructions.Count != 2)\n\t\t\t\treturn false;\n\t\t\tif (block.IncomingEdgeCount <= 1)\n\t\t\t\treturn false;\n\t\t\tif (!block.MatchIfAtEndOfBlock(out var load, out var trueInst, out var falseInst))\n\t\t\t\treturn false;\n\t\t\tif (!load.MatchLdLoc(s))\n\t\t\t\treturn false;\n\t\t\texitInst = constantValue != 0 ? trueInst : falseInst;\n\t\t\treturn exitInst is Branch or Leave { Value: Nop };\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/RemoveUnconstrainedGenericReferenceTypeCheck.cs",
    "content": "// Copyright (c) 2025 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t///\t[stloc address(...)]\n\t///\tstloc temp(default.value ``0)\n\t///\tif (comp.o(ldloc temp == ldnull)) Block IL_002a {\n\t///\t\tstloc temp(ldobj ``0(ldloc address))\n\t///\t\tstloc address(ldloca temp)\n\t///\t}\n\t///\tstloc V_i(expr_i)\n\t///\t...(constrained[``0].callvirt Method(ldobj.if.ref ``0(ldloc address), ldloc V_i ...))...\n\t///\t\n\t///=>\n\t///\n\t///\t[stloc address(...)]\n\t/// stloc address(ldobj.if.ref(ldloc address))\n\t///\tstloc V_i(expr_i)\n\t///\t...(constrained[``0].callvirt Method(ldobj.if.ref ``0(ldloc address), ldloc V_i ...))...\n\t///\t\n\t/// Then ldobj.if.ref in the call is redundant because any object reference was already loaded into an immutable temporary.\n\t/// So we can removed and inlining of the arguments (V_i) becomes possible.\n\t/// \n\t/// Finally the newly created ldobj.if.ref is inlined into the place where the old ldobj.if.ref was.\n\t/// \n\t/// =>\n\t/// \n\t///\t[stloc address(...)]\n\t///\t...(constrained[``0].callvirt Method(ldobj.if.ref ``0(ldloc address), expr_i ...))...\n\t/// \n\t/// </summary>\n\tclass RemoveUnconstrainedGenericReferenceTypeCheck : IStatementTransform\n\t{\n\t\tvoid IStatementTransform.Run(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\tint startPos = pos;\n\t\t\t// stloc temp(default.value ``0)\n\t\t\tif (!block.Instructions[pos].MatchStLoc(out var temp, out var defaultValue))\n\t\t\t\treturn;\n\t\t\tif (!defaultValue.MatchDefaultValue(out var type))\n\t\t\t\treturn;\n\t\t\tif (temp.StoreCount != 2 || temp.LoadCount != 1 || temp.AddressCount != 1)\n\t\t\t\treturn;\n\t\t\tpos++;\n\t\t\t// if (comp.o(ldloc temp == ldnull)) Block IL_002a {\n\t\t\t// \tstloc temp(ldobj ``0(ldloc address))\n\t\t\t// \tstloc address(ldloca temp)\n\t\t\t// }\n\t\t\tif (block.Instructions.ElementAtOrDefault(pos) is not IfInstruction ifInst)\n\t\t\t\treturn;\n\t\t\tif (!ifInst.Condition.MatchCompEqualsNull(out var tempLoadForNullCheck))\n\t\t\t\treturn;\n\t\t\tif (!tempLoadForNullCheck.MatchLdLoc(temp))\n\t\t\t\treturn;\n\t\t\tif (ifInst.TrueInst is not Block dereferenceBlock)\n\t\t\t\treturn;\n\t\t\tif (ifInst.FalseInst is not Nop)\n\t\t\t\treturn;\n\t\t\tif (dereferenceBlock.Instructions is not [StLoc tempStore, StLoc addressReassign])\n\t\t\t\treturn;\n\t\t\tif (tempStore.Variable != temp)\n\t\t\t\treturn;\n\t\t\tif (!tempStore.Value.MatchLdObj(out var addressLoadForLdObj, type))\n\t\t\t\treturn;\n\t\t\tif (!addressLoadForLdObj.MatchLdLoc(addressReassign.Variable))\n\t\t\t\treturn;\n\t\t\tif (!addressReassign.Value.MatchLdLoca(temp))\n\t\t\t\treturn;\n\t\t\tvar address = addressReassign.Variable;\n\t\t\tif (address.StoreCount != 2 || address.LoadCount != 2 || address.AddressCount != 0)\n\t\t\t\treturn;\n\t\t\tpos++;\n\t\t\t// pos now is the first store to V_i\n\t\t\t// ...(constrained[``0].callvirt Method(ldobj.if.ref ``0(ldloc address), ldloc V_i ...))...\n\t\t\tvar callTarget = address.LoadInstructions.Single(l => addressLoadForLdObj != l);\n\t\t\tif (callTarget.Parent is not LdObjIfRef { Parent: CallVirt call } ldobjIfRef)\n\t\t\t\treturn;\n\t\t\tif (call.Arguments.Count == 0 || call.Arguments[0] != ldobjIfRef || !type.Equals(call.ConstrainedTo))\n\t\t\t\treturn;\n\t\t\tILInstruction containingStmt = call;\n\t\t\twhile (containingStmt.Parent != block)\n\t\t\t{\n\t\t\t\tif (containingStmt.Parent == null)\n\t\t\t\t\treturn;\n\t\t\t\tcontainingStmt = containingStmt.Parent;\n\t\t\t}\n\t\t\tif (containingStmt.ChildIndex < pos)\n\t\t\t\treturn;\n\t\t\t// check if we can inline all temporaries used in the call:\n\t\t\tint temporaryInitIndex = containingStmt.ChildIndex - 1;\n\t\t\tList<(ILInstruction, ILInstruction)> replacements = new();\n\t\t\tfor (int argIndex = call.Arguments.Count - 1; argIndex > 0 && temporaryInitIndex >= pos; argIndex--)\n\t\t\t{\n\t\t\t\tvar argument = call.Arguments[argIndex];\n\t\t\t\tswitch (argument)\n\t\t\t\t{\n\t\t\t\t\tcase LdLoc load:\n\t\t\t\t\t\tif (block.Instructions[temporaryInitIndex].MatchStLoc(load.Variable, out var expr) && ILInlining.VariableCanBeUsedForInlining(load.Variable))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!ILInlining.CanMoveIntoCallVirt(expr, containingStmt, call, argument))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treplacements.Add((argument, expr));\n\t\t\t\t\t\t\ttemporaryInitIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// all stores to V_i processed?\n\t\t\tif (temporaryInitIndex != pos - 1)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcontext.Step(\"RemoveUnconstrainedGenericReferenceTypeCheck\", block.Instructions[startPos]);\n\t\t\tforeach (var (argument, expr) in replacements)\n\t\t\t{\n\t\t\t\targument.ReplaceWith(expr);\n\t\t\t}\n\t\t\tblock.Instructions.RemoveRange(startPos, containingStmt.ChildIndex - startPos);\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/SplitVariables.cs",
    "content": "// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.FlowAnalysis;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Live range splitting for IL variables.\n\t/// </summary>\n\tpublic class SplitVariables : IILTransform\n\t{\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tvar groupStores = new GroupStores(function, context.CancellationToken);\n\t\t\tfunction.Body.AcceptVisitor(groupStores);\n\t\t\t// Replace analyzed variables with their split versions:\n\t\t\tforeach (var inst in function.Descendants.OfType<IInstructionWithVariableOperand>())\n\t\t\t{\n\t\t\t\tif (groupStores.IsAnalyzedVariable(inst.Variable))\n\t\t\t\t{\n\t\t\t\t\tinst.Variable = groupStores.GetNewVariable(inst);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfunction.Variables.RemoveDead();\n\t\t}\n\n\t\tstatic bool IsCandidateVariable(ILVariable v)\n\t\t{\n\t\t\tswitch (v.Kind)\n\t\t\t{\n\t\t\t\tcase VariableKind.Local:\n\t\t\t\t\tforeach (var ldloca in v.AddressInstructions)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (DetermineAddressUse(ldloca, ldloca.Variable) == AddressUse.Unknown)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// If we don't understand how the address is being used,\n\t\t\t\t\t\t\t// we can't split the variable.\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\tcase VariableKind.StackSlot:\n\t\t\t\t\t// stack slots: are already split by construction,\n\t\t\t\t\t// except for the locals-turned-stackslots in async functions\n\t\t\t\t\t// or stack slots handled by the infeasible path transform\n\t\t\t\t\tif (v.Function.IsAsync || v.RemoveIfRedundant)\n\t\t\t\t\t\tgoto case VariableKind.Local;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn false;\n\t\t\t\tdefault:\n\t\t\t\t\t// parameters: avoid splitting parameters\n\t\t\t\t\t// pinned locals: must not split (doing so would extend the life of the pin to the end of the method)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tenum AddressUse\n\t\t{\n\t\t\tUnknown,\n\t\t\t/// <summary>\n\t\t\t/// Address is immediately used for reading and/or writing,\n\t\t\t/// without the possibility of the variable being directly stored to (via 'stloc')\n\t\t\t/// in between the 'ldloca' and the use of the address.\n\t\t\t/// </summary>\n\t\t\tImmediate,\n\t\t\t/// <summary>\n\t\t\t/// We support some limited form of ref locals referring to a target variable,\n\t\t\t/// without giving up splitting of the target variable.\n\t\t\t/// Requirements:\n\t\t\t///  * the ref local is single-assignment\n\t\t\t///  * the ref local is initialized directly with 'ldloca target; stloc ref_local',\n\t\t\t///       not a derived pointer (e.g. 'ldloca target; ldflda F; stloc ref_local').\n\t\t\t///  * all uses of the ref_local are immediate.\n\t\t\t/// There may be stores to the target variable in between the 'stloc ref_local' and its uses,\n\t\t\t/// but we handle that case by treating each use of the ref_local as an address access\n\t\t\t/// of the target variable (as if the ref_local was eliminated via copy propagation).\n\t\t\t/// </summary>\n\t\t\tWithSupportedRefLocals,\n\t\t}\n\n\t\tstatic AddressUse DetermineAddressUse(ILInstruction addressLoadingInstruction, ILVariable targetVar)\n\t\t{\n\t\t\tswitch (addressLoadingInstruction.Parent)\n\t\t\t{\n\t\t\t\tcase LdObj _:\n\t\t\t\tcase StObj stobj when stobj.Target == addressLoadingInstruction:\n\t\t\t\t\treturn AddressUse.Immediate;\n\t\t\t\tcase LdObjIfRef:\n\t\t\t\t\t// This is either an immediate use, or we need to check how the parent uses the address.\n\t\t\t\t\treturn DetermineAddressUse(addressLoadingInstruction.Parent, targetVar);\n\t\t\t\tcase LdFlda ldflda:\n\t\t\t\t\treturn DetermineAddressUse(ldflda, targetVar);\n\t\t\t\tcase Await await:\n\t\t\t\t\t// GetAwaiter() may write to the struct, but shouldn't store the address for later use\n\t\t\t\t\treturn AddressUse.Immediate;\n\t\t\t\tcase CallInstruction call:\n\t\t\t\t\treturn HandleCall(addressLoadingInstruction, targetVar, call);\n\t\t\t\tcase StLoc stloc when stloc.Variable.IsSingleDefinition:\n\t\t\t\t\t// Address stored in local variable: also check all uses of that variable.\n\t\t\t\t\tif (!(stloc.Variable.Kind == VariableKind.StackSlot || stloc.Variable.Kind == VariableKind.Local))\n\t\t\t\t\t\treturn AddressUse.Unknown;\n\t\t\t\t\tvar value = stloc.Value;\n\t\t\t\t\twhile (value is LdFlda ldFlda)\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue = ldFlda.Target;\n\t\t\t\t\t}\n\t\t\t\t\tif (value.OpCode != OpCode.LdLoca)\n\t\t\t\t\t{\n\t\t\t\t\t\t// GroupStores only handles ref-locals correctly when they are supported by GetAddressLoadForRefLocalUse(),\n\t\t\t\t\t\t// which only works for ldflda*(ldloca)\n\t\t\t\t\t\treturn AddressUse.Unknown;\n\t\t\t\t\t}\n\t\t\t\t\tforeach (var load in stloc.Variable.LoadInstructions)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (DetermineAddressUse(load, targetVar) != AddressUse.Immediate)\n\t\t\t\t\t\t\treturn AddressUse.Unknown;\n\t\t\t\t\t}\n\t\t\t\t\treturn AddressUse.WithSupportedRefLocals;\n\t\t\t\tdefault:\n\t\t\t\t\treturn AddressUse.Unknown;\n\t\t\t}\n\t\t}\n\n\t\tstatic AddressUse HandleCall(ILInstruction addressLoadingInstruction, ILVariable targetVar, CallInstruction call)\n\t\t{\n\t\t\t// Address is passed to method.\n\t\t\t// We'll assume the method only uses the address locally,\n\t\t\t// unless we can see an address being returned from the method:\n\t\t\tIType returnType = (call is NewObj) ? call.Method.DeclaringType : call.Method.ReturnType;\n\t\t\tif (returnType.IsByRefLike)\n\t\t\t{\n\t\t\t\t// We exclude Span<T>.Item[int index] and ReadOnlySpan<T>.Item[int index], because it is known that this\n\t\t\t\t// or members of this cannot be returned by the method.\n\t\t\t\tif (!IsSpanOfTIndexerAccessor(call.Method))\n\t\t\t\t{\n\t\t\t\t\t// If the address is returned from the method, it check whether it's consumed immediately.\n\t\t\t\t\t// This can still be fine, as long as we also check the consumer's other arguments for 'stloc targetVar'.\n\t\t\t\t\tif (DetermineAddressUse(call, targetVar) != AddressUse.Immediate)\n\t\t\t\t\t\treturn AddressUse.Unknown;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach (var p in call.Method.Parameters)\n\t\t\t{\n\t\t\t\t// catch \"out Span<int>\" and similar\n\t\t\t\tif (p.Type.SkipModifiers() is ByReferenceType brt && brt.ElementType.IsByRefLike)\n\t\t\t\t\treturn AddressUse.Unknown;\n\t\t\t}\n\t\t\t// ensure there's no 'stloc target' in between the ldloca and the call consuming the address\n\t\t\tfor (int i = addressLoadingInstruction.ChildIndex + 1; i < call.Arguments.Count; i++)\n\t\t\t{\n\t\t\t\tforeach (var inst in call.Arguments[i].Descendants)\n\t\t\t\t{\n\t\t\t\t\tif (inst is StLoc store && store.Variable == targetVar)\n\t\t\t\t\t\treturn AddressUse.Unknown;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn AddressUse.Immediate;\n\t\t}\n\n\t\tstatic bool IsSpanOfTIndexerAccessor(IMethod method)\n\t\t{\n\t\t\tvar declaringType = method.DeclaringType;\n\t\t\tif (!declaringType.IsKnownType(KnownTypeCode.SpanOfT)\n\t\t\t\t&& !declaringType.IsKnownType(KnownTypeCode.ReadOnlySpanOfT))\n\t\t\t\treturn false;\n\t\t\treturn method.AccessorOwner is IProperty { IsIndexer: true, Name: \"Item\", Parameters: [var param], ReturnType: ByReferenceType { ElementType: var rt } }\n\t\t\t\t&& param.Type.IsKnownType(KnownTypeCode.Int32) && rt.Equals(declaringType.TypeArguments[0]);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Given 'ldloc ref_local' and 'ldloca target; stloc ref_local', returns the ldloca.\n\t\t/// This function must return a non-null LdLoca for every use of a SupportedRefLocal.\n\t\t/// </summary>\n\t\tstatic LdLoca GetAddressLoadForRefLocalUse(LdLoc ldloc)\n\t\t{\n\t\t\tif (!ldloc.Variable.IsSingleDefinition)\n\t\t\t\treturn null; // only single-definition variables can be supported ref locals\n\t\t\tvar store = ldloc.Variable.StoreInstructions.SingleOrDefault();\n\t\t\tif (store is StLoc stloc)\n\t\t\t{\n\t\t\t\tvar value = stloc.Value;\n\t\t\t\twhile (value is LdFlda ldFlda)\n\t\t\t\t{\n\t\t\t\t\tvalue = ldFlda.Target;\n\t\t\t\t}\n\t\t\t\treturn value as LdLoca;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Use the union-find structure to merge\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Instructions in a group are stores to the same variable that must stay together (cannot be split).\n\t\t/// </remarks>\n\t\tclass GroupStores : ReachingDefinitionsVisitor\n\t\t{\n\t\t\treadonly UnionFind<IInstructionWithVariableOperand> unionFind = new UnionFind<IInstructionWithVariableOperand>();\n\n\t\t\t/// <summary>\n\t\t\t/// For each uninitialized variable, one representative instruction that\n\t\t\t/// potentially observes the unintialized value of the variable.\n\t\t\t/// Used to merge together all such loads of the same uninitialized value.\n\t\t\t/// </summary>\n\t\t\treadonly Dictionary<ILVariable, IInstructionWithVariableOperand> uninitVariableUsage = new Dictionary<ILVariable, IInstructionWithVariableOperand>();\n\n\t\t\tpublic GroupStores(ILFunction scope, CancellationToken cancellationToken) : base(scope, IsCandidateVariable, cancellationToken)\n\t\t\t{\n\t\t\t}\n\n\t\t\tprotected internal override void VisitLdLoc(LdLoc inst)\n\t\t\t{\n\t\t\t\tbase.VisitLdLoc(inst);\n\t\t\t\tHandleLoad(inst);\n\t\t\t\tvar refLocalAddressLoad = GetAddressLoadForRefLocalUse(inst);\n\t\t\t\tif (refLocalAddressLoad != null)\n\t\t\t\t{\n\t\t\t\t\t// SupportedRefLocal: act as if we copy-propagated the ldloca\n\t\t\t\t\t// to the point of use:\n\t\t\t\t\tHandleLoad(refLocalAddressLoad);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tprotected internal override void VisitLdLoca(LdLoca inst)\n\t\t\t{\n\t\t\t\tbase.VisitLdLoca(inst);\n\t\t\t\tHandleLoad(inst);\n\t\t\t}\n\n\t\t\tvoid HandleLoad(IInstructionWithVariableOperand inst)\n\t\t\t{\n\t\t\t\tif (IsAnalyzedVariable(inst.Variable))\n\t\t\t\t{\n\t\t\t\t\tif (IsPotentiallyUninitialized(state, inst.Variable))\n\t\t\t\t\t{\n\t\t\t\t\t\t// merge all uninit loads together:\n\t\t\t\t\t\tif (uninitVariableUsage.TryGetValue(inst.Variable, out var uninitLoad))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tunionFind.Merge(inst, uninitLoad);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tuninitVariableUsage.Add(inst.Variable, inst);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tforeach (var store in GetStores(state, inst.Variable))\n\t\t\t\t\t{\n\t\t\t\t\t\tunionFind.Merge(inst, (IInstructionWithVariableOperand)store);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treadonly Dictionary<IInstructionWithVariableOperand, ILVariable> newVariables = new Dictionary<IInstructionWithVariableOperand, ILVariable>();\n\n\t\t\t/// <summary>\n\t\t\t/// Gets the new variable for a LdLoc, StLoc or TryCatchHandler instruction.\n\t\t\t/// </summary>\n\t\t\tinternal ILVariable GetNewVariable(IInstructionWithVariableOperand inst)\n\t\t\t{\n\t\t\t\tvar representative = unionFind.Find(inst);\n\t\t\t\tILVariable v;\n\t\t\t\tif (!newVariables.TryGetValue(representative, out v))\n\t\t\t\t{\n\t\t\t\t\tv = new ILVariable(inst.Variable.Kind, inst.Variable.Type, inst.Variable.StackType, inst.Variable.Index);\n\t\t\t\t\tv.Name = inst.Variable.Name;\n\t\t\t\t\tv.HasGeneratedName = inst.Variable.HasGeneratedName;\n\t\t\t\t\tv.StateMachineField = inst.Variable.StateMachineField;\n\t\t\t\t\tv.InitialValueIsInitialized = inst.Variable.InitialValueIsInitialized;\n\t\t\t\t\tv.UsesInitialValue = false; // we'll set UsesInitialValue when we encounter an uninit load\n\t\t\t\t\tv.RemoveIfRedundant = inst.Variable.RemoveIfRedundant;\n\t\t\t\t\tnewVariables.Add(representative, v);\n\t\t\t\t\tinst.Variable.Function.Variables.Add(v);\n\t\t\t\t}\n\t\t\t\tif (inst.Variable.UsesInitialValue && uninitVariableUsage.TryGetValue(inst.Variable, out var uninitLoad) && uninitLoad == inst)\n\t\t\t\t{\n\t\t\t\t\tv.UsesInitialValue = true;\n\t\t\t\t}\n\t\t\t\treturn v;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/StatementTransform.cs",
    "content": "// Copyright (c) 2017 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Diagnostics;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// IL transform that runs on a sequence of statements within a block.\n\t/// </summary>\n\t/// <remarks>\n\t/// Interleaving different statement-combining transforms on a per-statement level\n\t/// improves detection of nested constructs.\n\t/// For example, array initializers can assume that each element assignment was already\n\t/// reduced to a single statement, even if the element contains a high-level construct\n\t/// detected by a different transform (e.g. object initializer).\n\t/// </remarks>\n\tpublic interface IStatementTransform\n\t{\n\t\t/// <summary>\n\t\t/// Runs the transform on the statements within a block.\n\t\t/// \n\t\t/// Note: the transform may only modify block.Instructions[pos..].\n\t\t/// The transform will be called repeatedly for pos=block.Instructions.Count-1, pos=block.Instructions.Count-2, ..., pos=0.\n\t\t/// </summary>\n\t\t/// <param name=\"block\">The current block.</param>\n\t\t/// <param name=\"pos\">The starting position where the transform is allowed to work.</param>\n\t\t/// <param name=\"context\">Additional parameters.</param>\n\t\t/// <remarks>\n\t\t/// Instructions prior to block.Instructions[pos] must not be modified.\n\t\t/// It is valid to read such instructions, but not recommended as those have not been transformed yet.\n\t\t/// \n\t\t/// This function is only called on control-flow blocks with unreachable end-point.\n\t\t/// Thus, the last instruction in the block always must have the EndPointUnreachable flag.\n\t\t/// ==> Instructions with reachable end can't be last. Some transforms use this to save some bounds checks.\n\t\t/// </remarks>\n\t\tvoid Run(Block block, int pos, StatementTransformContext context);\n\t}\n\n\t/// <summary>\n\t/// Parameter class holding various arguments for <see cref=\"IStatementTransform.Run\"/>.\n\t/// </summary>\n\tpublic class StatementTransformContext : ILTransformContext\n\t{\n\t\tpublic BlockTransformContext BlockContext { get; }\n\n\t\tpublic StatementTransformContext(BlockTransformContext blockContext) : base(blockContext)\n\t\t{\n\t\t\tthis.BlockContext = blockContext ?? throw new ArgumentNullException(nameof(blockContext));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the block on which the transform is running.\n\t\t/// </summary>\n\t\tpublic Block Block => BlockContext.Block;\n\n\t\tinternal bool rerunCurrentPosition;\n\t\tinternal int? rerunPosition;\n\n\t\t/// <summary>\n\t\t/// After the current statement transform has completed,\n\t\t/// do not continue with the next statement transform at the same position.\n\t\t/// Instead, re-run all statement transforms (including the current transform) starting at the specified position.\n\t\t/// </summary>\n\t\tpublic void RequestRerun(int pos)\n\t\t{\n\t\t\tif (rerunPosition == null || pos > rerunPosition)\n\t\t\t{\n\t\t\t\trerunPosition = pos;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// After the current statement transform has completed,\n\t\t/// repeat all statement transforms on the current position.\n\t\t/// </summary>\n\t\tpublic void RequestRerun()\n\t\t{\n\t\t\trerunCurrentPosition = true;\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Block transform that runs a list of statement transforms.\n\t/// </summary>\n\tpublic class StatementTransform : IBlockTransform\n\t{\n\t\treadonly IStatementTransform[] children;\n\n\t\tpublic StatementTransform(params IStatementTransform[] children)\n\t\t{\n\t\t\tthis.children = children;\n\t\t}\n\n\t\tpublic void Run(Block block, BlockTransformContext context)\n\t\t{\n\t\t\tvar ctx = new StatementTransformContext(context);\n\t\t\tint pos = 0;\n\t\t\tif (context.IndexOfFirstAlreadyTransformedInstruction == 0)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tctx.rerunPosition = context.IndexOfFirstAlreadyTransformedInstruction - 1;\n\t\t\twhile (pos >= 0)\n\t\t\t{\n\t\t\t\tif (ctx.rerunPosition != null)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(ctx.rerunPosition >= pos);\n#if DEBUG\n\t\t\t\t\tfor (; pos < ctx.rerunPosition; ++pos)\n\t\t\t\t\t{\n\t\t\t\t\t\tblock.Instructions[pos].ResetDirty();\n\t\t\t\t\t}\n#else\n\t\t\t\t\tpos = ctx.rerunPosition.Value;\n#endif\n\t\t\t\t\tDebug.Assert(pos == ctx.rerunPosition);\n\t\t\t\t\tctx.rerunPosition = null;\n\t\t\t\t}\n\t\t\t\tforeach (var transform in children)\n\t\t\t\t{\n\t\t\t\t\ttransform.Run(block, pos, ctx);\n#if DEBUG\n\t\t\t\t\tblock.Instructions[pos].CheckInvariant(ILPhase.Normal);\n\t\t\t\t\tfor (int i = Math.Max(0, pos - 100); i < pos; ++i)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (block.Instructions[i].IsDirty)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tDebug.Fail($\"{transform.GetType().Name} modified an instruction before pos\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n#endif\n\t\t\t\t\tif (ctx.rerunCurrentPosition)\n\t\t\t\t\t{\n\t\t\t\t\t\tctx.rerunCurrentPosition = false;\n\t\t\t\t\t\tctx.RequestRerun(pos);\n\t\t\t\t\t}\n\t\t\t\t\tif (ctx.rerunPosition != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (ctx.rerunPosition == null)\n\t\t\t\t{\n\t\t\t\t\tpos--;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// This invariant can be surprisingly expensive to check if the block has thousands\n\t\t\t// of instructions and is frequently modified by transforms (invalidating the flags each time)\n\t\t\t// so we'll check this only once at the end of the block.\n\t\t\tDebug.Assert(block.HasFlag(InstructionFlags.EndPointUnreachable));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/Stepper.cs",
    "content": "// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Exception thrown when an IL transform runs into the <see cref=\"Stepper.StepLimit\"/>.\n\t/// </summary>\n\tpublic class StepLimitReachedException : Exception\n\t{\n\t}\n\n\t/// <summary>\n\t/// Helper class that manages recording transform steps.\n\t/// </summary>\n\tpublic class Stepper\n\t{\n\t\t/// <summary>\n\t\t/// Gets whether stepping of built-in transforms is supported in this build of ICSharpCode.Decompiler.\n\t\t/// Usually only debug builds support transform stepping.\n\t\t/// </summary>\n\t\tpublic static bool SteppingAvailable {\n\t\t\tget {\n#if STEP\n\t\t\t\treturn true;\n#else\n\t\t\t\treturn false;\n#endif\n\t\t\t}\n\t\t}\n\n\t\tpublic IList<Node> Steps => steps;\n\n\t\tpublic int StepLimit { get; set; } = int.MaxValue;\n\t\tpublic bool IsDebug { get; set; }\n\n\t\tpublic class Node\n\t\t{\n\t\t\tpublic string Description { get; }\n\t\t\tpublic ILInstruction? Position { get; set; }\n\t\t\t/// <summary>\n\t\t\t/// BeginStep is inclusive.\n\t\t\t/// </summary>\n\t\t\tpublic int BeginStep { get; set; }\n\t\t\t/// <summary>\n\t\t\t/// EndStep is exclusive.\n\t\t\t/// </summary>\n\t\t\tpublic int EndStep { get; set; }\n\n\t\t\tpublic IList<Node> Children { get; } = new List<Node>();\n\n\t\t\tpublic Node(string description)\n\t\t\t{\n\t\t\t\tDescription = description;\n\t\t\t}\n\t\t}\n\n\t\treadonly Stack<Node> groups;\n\t\treadonly IList<Node> steps;\n\t\tint step = 0;\n\n\t\tpublic Stepper()\n\t\t{\n\t\t\tsteps = new List<Node>();\n\t\t\tgroups = new Stack<Node>();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Call this method immediately before performing a transform step.\n\t\t/// Used for debugging the IL transforms. Has no effect in release mode.\n\t\t/// \n\t\t/// May throw <see cref=\"StepLimitReachedException\"/> in debug mode.\n\t\t/// </summary>\n\t\t[DebuggerStepThrough]\n\t\tpublic void Step(string description, ILInstruction? near = null)\n\t\t{\n\t\t\tStepInternal(description, near);\n\t\t}\n\n\t\t[DebuggerStepThrough]\n\t\tprivate Node StepInternal(string description, ILInstruction? near)\n\t\t{\n\t\t\tif (step == StepLimit)\n\t\t\t{\n\t\t\t\tif (IsDebug)\n\t\t\t\t\tDebugger.Break();\n\t\t\t\telse\n\t\t\t\t\tthrow new StepLimitReachedException();\n\t\t\t}\n\t\t\tvar stepNode = new Node($\"{step}: {description}\") {\n\t\t\t\tPosition = near,\n\t\t\t\tBeginStep = step,\n\t\t\t\tEndStep = step + 1\n\t\t\t};\n\t\t\tvar p = groups.PeekOrDefault();\n\t\t\tif (p != null)\n\t\t\t\tp.Children.Add(stepNode);\n\t\t\telse\n\t\t\t\tsteps.Add(stepNode);\n\t\t\tstep++;\n\t\t\treturn stepNode;\n\t\t}\n\n\t\t[DebuggerStepThrough]\n\t\tpublic void StartGroup(string description, ILInstruction? near = null)\n\t\t{\n\t\t\tgroups.Push(StepInternal(description, near));\n\t\t}\n\n\t\tpublic void EndGroup(bool keepIfEmpty = false)\n\t\t{\n\t\t\tvar node = groups.Pop();\n\t\t\tif (!keepIfEmpty && node.Children.Count == 0)\n\t\t\t{\n\t\t\t\tvar col = groups.PeekOrDefault()?.Children ?? steps;\n\t\t\t\tDebug.Assert(col.Last() == node);\n\t\t\t\tcol.RemoveAt(col.Count - 1);\n\t\t\t}\n\t\t\tnode.EndStep = step;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/SwitchOnNullableTransform.cs",
    "content": "// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.IL.ControlFlow;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Detects switch-on-nullable patterns employed by the C# compiler and transforms them to an ILAst-switch-instruction.\n\t/// </summary>\n\tpublic class SwitchOnNullableTransform : IILTransform\n\t{\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.LiftNullables)\n\t\t\t\treturn;\n\n\t\t\tHashSet<BlockContainer> changedContainers = new HashSet<BlockContainer>();\n\n\t\t\tforeach (var block in function.Descendants.OfType<Block>())\n\t\t\t{\n\t\t\t\tbool changed = false;\n\t\t\t\tfor (int i = block.Instructions.Count - 1; i >= 0; i--)\n\t\t\t\t{\n\t\t\t\t\tSwitchInstruction newSwitch;\n\t\t\t\t\tif (MatchSwitchOnNullable(block.Instructions, i, out newSwitch))\n\t\t\t\t\t{\n\t\t\t\t\t\tnewSwitch.AddILRange(block.Instructions[i - 2]);\n\t\t\t\t\t\tblock.Instructions[i + 1].ReplaceWith(newSwitch);\n\t\t\t\t\t\tblock.Instructions.RemoveRange(i - 2, 3);\n\t\t\t\t\t\ti -= 2;\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (MatchRoslynSwitchOnNullable(block.Instructions, i, out newSwitch))\n\t\t\t\t\t{\n\t\t\t\t\t\tnewSwitch.AddILRange(block.Instructions[i]);\n\t\t\t\t\t\tnewSwitch.AddILRange(block.Instructions[i + 1]);\n\t\t\t\t\t\tblock.Instructions[i].ReplaceWith(newSwitch);\n\t\t\t\t\t\tblock.Instructions.RemoveAt(i + 1);\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!changed)\n\t\t\t\t\tcontinue;\n\t\t\t\tSwitchDetection.SimplifySwitchInstruction(block, context);\n\t\t\t\tif (block.Parent is BlockContainer container)\n\t\t\t\t\tchangedContainers.Add(container);\n\t\t\t}\n\n\t\t\tforeach (var container in changedContainers)\n\t\t\t\tcontainer.SortBlocks(deleteUnreachableBlocks: true);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches legacy C# switch on nullable.\n\t\t/// </summary>\n\t\tbool MatchSwitchOnNullable(InstructionCollection<ILInstruction> instructions, int i, out SwitchInstruction newSwitch)\n\t\t{\n\t\t\tnewSwitch = null;\n\t\t\t// match first block:\n\t\t\t// stloc tmp(ldloca switchValueVar)\n\t\t\t// stloc switchVariable(call GetValueOrDefault(ldloc tmp))\n\t\t\t// if (logic.not(call get_HasValue(ldloc tmp))) br nullCaseBlock\n\t\t\t// br switchBlock\n\t\t\tif (i < 2)\n\t\t\t\treturn false;\n\t\t\tif (!instructions[i - 2].MatchStLoc(out var tmp, out var ldloca) ||\n\t\t\t\t!instructions[i - 1].MatchStLoc(out var switchVariable, out var getValueOrDefault) ||\n\t\t\t\t!instructions[i].MatchIfInstruction(out var condition, out var trueInst))\n\t\t\t\treturn false;\n\t\t\tif (!tmp.IsSingleDefinition || tmp.LoadCount != 2)\n\t\t\t\treturn false;\n\t\t\tif (!switchVariable.IsSingleDefinition || switchVariable.LoadCount != 1)\n\t\t\t\treturn false;\n\t\t\tif (!instructions[i + 1].MatchBranch(out var switchBlock) || !trueInst.MatchBranch(out var nullCaseBlock))\n\t\t\t\treturn false;\n\t\t\tif (!ldloca.MatchLdLoca(out var switchValueVar))\n\t\t\t\treturn false;\n\t\t\tif (!condition.MatchLogicNot(out var getHasValue))\n\t\t\t\treturn false;\n\t\t\tif (!NullableLiftingTransform.MatchGetValueOrDefault(getValueOrDefault, out ILInstruction getValueOrDefaultArg))\n\t\t\t\treturn false;\n\t\t\tif (!NullableLiftingTransform.MatchHasValueCall(getHasValue, out ILInstruction getHasValueArg))\n\t\t\t\treturn false;\n\t\t\tif (!(getHasValueArg.MatchLdLoc(tmp) && getValueOrDefaultArg.MatchLdLoc(tmp)))\n\t\t\t\treturn false;\n\t\t\t// match second block: switchBlock\n\t\t\t// switch (ldloc switchVariable) {\n\t\t\t// \tcase [0..1): br caseBlock1\n\t\t\t//  ... more cases ...\n\t\t\t// \tcase [long.MinValue..0),[1..5),[6..10),[11..long.MaxValue]: br defaultBlock\n\t\t\t// }\n\t\t\tif (switchBlock.Instructions.Count != 1 || switchBlock.IncomingEdgeCount != 1)\n\t\t\t\treturn false;\n\t\t\tif (!(switchBlock.Instructions[0] is SwitchInstruction switchInst))\n\t\t\t\treturn false;\n\t\t\tvar nullableType = ((Call)getHasValue).Method.DeclaringType;\n\t\t\tnewSwitch = BuildLiftedSwitch(nullCaseBlock, switchInst, new LdLoc(switchValueVar), nullableType);\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic SwitchInstruction BuildLiftedSwitch(Block nullCaseBlock, SwitchInstruction switchInst, ILInstruction switchValue, IType nullableType)\n\t\t{\n\t\t\tSwitchInstruction newSwitch = new SwitchInstruction(switchValue);\n\t\t\tnewSwitch.IsLifted = true;\n\t\t\tnewSwitch.Type = nullableType;\n\t\t\tnewSwitch.Sections.AddRange(switchInst.Sections);\n\t\t\tnewSwitch.Sections.Add(new SwitchSection { Body = new Branch(nullCaseBlock), HasNullLabel = true });\n\t\t\treturn newSwitch;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches Roslyn C# switch on nullable.\n\t\t/// </summary>\n\t\tbool MatchRoslynSwitchOnNullable(InstructionCollection<ILInstruction> instructions, int i, out SwitchInstruction newSwitch)\n\t\t{\n\t\t\tnewSwitch = null;\n\t\t\t// match first block:\n\t\t\t// if (logic.not(call get_HasValue(target))) br nullCaseBlock\n\t\t\t// br switchBlock\n\t\t\tif (!instructions[i].MatchIfInstruction(out var condition, out var trueInst))\n\t\t\t\treturn false;\n\t\t\tif (!instructions[i + 1].MatchBranch(out var switchBlock) || !trueInst.MatchBranch(out var nullCaseBlock))\n\t\t\t\treturn false;\n\t\t\tif (!condition.MatchLogicNot(out var getHasValue) || !NullableLiftingTransform.MatchHasValueCall(getHasValue, out ILInstruction target) || !SemanticHelper.IsPure(target.Flags))\n\t\t\t\treturn false;\n\t\t\t// match second block: switchBlock\n\t\t\t// note: I have seen cases where switchVar is inlined into the switch.\n\t\t\t// stloc switchVar(call GetValueOrDefault(ldloca tmp))\n\t\t\t// switch (ldloc switchVar) {\n\t\t\t// \tcase [0..1): br caseBlock1\n\t\t\t// ... more cases ...\n\t\t\t// \tcase [long.MinValue..0),[1..5),[6..10),[11..long.MaxValue]: br defaultBlock\n\t\t\t// }\n\t\t\tif (switchBlock.IncomingEdgeCount != 1)\n\t\t\t\treturn false;\n\t\t\tSwitchInstruction switchInst;\n\t\t\tswitch (switchBlock.Instructions.Count)\n\t\t\t{\n\t\t\t\tcase 2:\n\t\t\t\t{\n\t\t\t\t\t// this is the normal case described by the pattern above\n\t\t\t\t\tif (!switchBlock.Instructions[0].MatchStLoc(out var switchVar, out var getValueOrDefault))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!switchVar.IsSingleDefinition || switchVar.LoadCount != 1)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!(NullableLiftingTransform.MatchGetValueOrDefault(getValueOrDefault, out ILInstruction target2) && target2.Match(target).Success))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!(switchBlock.Instructions[1] is SwitchInstruction si))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tswitchInst = si;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 1:\n\t\t\t\t{\n\t\t\t\t\t// this is the special case where `call GetValueOrDefault(ldloca tmp)` is inlined into the switch.\n\t\t\t\t\tif (!(switchBlock.Instructions[0] is SwitchInstruction si))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!(NullableLiftingTransform.MatchGetValueOrDefault(si.Value, out ILInstruction target2) && target2.Match(target).Success))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tswitchInst = si;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tILInstruction switchValue;\n\t\t\tif (target.MatchLdLoca(out var v))\n\t\t\t\tswitchValue = new LdLoc(v).WithILRange(target);\n\t\t\telse\n\t\t\t\tswitchValue = new LdObj(target, ((CallInstruction)getHasValue).Method.DeclaringType);\n\t\t\tvar nullableType = ((Call)getHasValue).Method.DeclaringType;\n\t\t\tnewSwitch = BuildLiftedSwitch(nullCaseBlock, switchInst, switchValue, nullableType);\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/SwitchOnStringTransform.cs",
    "content": "// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.IL.ControlFlow;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\tusing HashtableInitializer = Dictionary<IField, (List<(string, int)> Labels, IfInstruction JumpToNext, Block ContainingBlock, Block Previous, Block Next, bool Transformed)>;\n\n\t/// <summary>\n\t/// Detects switch-on-string patterns employed by the C# compiler and transforms them to an ILAst-switch-instruction.\n\t/// </summary>\n\tpublic class SwitchOnStringTransform : IILTransform\n\t{\n\t\tILTransformContext context;\n\t\tprivate readonly SwitchAnalysis analysis = new SwitchAnalysis();\n\n\t\tpublic void Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.SwitchStatementOnString)\n\t\t\t\treturn;\n\n\t\t\tthis.context = context;\n\t\t\tBlockContainer body = (BlockContainer)function.Body;\n\t\t\tvar hashtableInitializers = ScanHashtableInitializerBlocks(body.EntryPoint);\n\n\t\t\tHashSet<BlockContainer> changedContainers = new HashSet<BlockContainer>();\n\n\t\t\tforeach (var block in function.Descendants.OfType<Block>())\n\t\t\t{\n\t\t\t\tbool changed = false;\n\t\t\t\tif (block.IncomingEdgeCount == 0)\n\t\t\t\t\tcontinue;\n\t\t\t\tfor (int i = block.Instructions.Count - 1; i >= 0; i--)\n\t\t\t\t{\n\t\t\t\t\tif (SimplifyCascadingIfStatements(block.Instructions, ref i))\n\t\t\t\t\t{\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (SimplifyCSharp1CascadingIfStatements(block.Instructions, ref i))\n\t\t\t\t\t{\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (MatchLegacySwitchOnStringWithHashtable(block, hashtableInitializers, ref i))\n\t\t\t\t\t{\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (MatchLegacySwitchOnStringWithDict(block.Instructions, ref i))\n\t\t\t\t\t{\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (MatchRoslynSwitchOnString(block.Instructions, ref i))\n\t\t\t\t\t{\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (MatchRoslynSwitchOnStringUsingLengthAndChar(block, i))\n\t\t\t\t\t{\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!changed)\n\t\t\t\t\tcontinue;\n\t\t\t\tSwitchDetection.SimplifySwitchInstruction(block, context);\n\t\t\t\tif (block.Parent is BlockContainer container)\n\t\t\t\t\tchangedContainers.Add(container);\n\t\t\t}\n\n\t\t\tvar omittedBlocks = new Dictionary<Block, Block>();\n\n\t\t\t// Remove all transformed hashtable initializers from the entrypoint.\n\t\t\tforeach (var item in hashtableInitializers)\n\t\t\t{\n\t\t\t\tvar (labels, jumpToNext, containingBlock, previous, next, transformed) = item.Value;\n\t\t\t\tif (!transformed)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (!omittedBlocks.TryGetValue(previous, out var actual))\n\t\t\t\t\tactual = previous;\n\t\t\t\tcontext.Step(\"Remove hashtable initializer\", actual);\n\t\t\t\tif (jumpToNext != null)\n\t\t\t\t{\n\t\t\t\t\tactual.Instructions.SecondToLastOrDefault().ReplaceWith(jumpToNext);\n\t\t\t\t}\n\t\t\t\tactual.Instructions.LastOrDefault().ReplaceWith(new Branch(next));\n\t\t\t\tomittedBlocks.Add(containingBlock, previous);\n\t\t\t\tchangedContainers.Add(body);\n\t\t\t}\n\n\t\t\t// If all initializer where removed, remove the initial null check as well.\n\t\t\tif (hashtableInitializers.Count > 0 && omittedBlocks.Count == hashtableInitializers.Count && body.EntryPoint.Instructions.Count == 2)\n\t\t\t{\n\t\t\t\tif (body.EntryPoint.Instructions[0] is IfInstruction ifInst\n\t\t\t\t\t&& ifInst.TrueInst.MatchBranch(out var beginOfMethod) && body.EntryPoint.Instructions[1].MatchBranch(beginOfMethod))\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"Remove initial null check\", body);\n\t\t\t\t\tbody.EntryPoint.Instructions.RemoveAt(0);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach (var container in changedContainers)\n\t\t\t\tcontainer.SortBlocks(deleteUnreachableBlocks: true);\n\t\t}\n\n\t\tHashtableInitializer ScanHashtableInitializerBlocks(Block entryPoint)\n\t\t{\n\t\t\tvar hashtables = new HashtableInitializer();\n\t\t\tif (entryPoint.Instructions.Count != 2)\n\t\t\t\treturn hashtables;\n\t\t\t// match first block: checking compiler-generated Hashtable for null\n\t\t\t// if (comp(volatile.ldobj System.Collections.Hashtable(ldsflda $$method0x600003f-1) != ldnull)) br switchHeadBlock\n\t\t\t// br tableInitBlock\n\t\t\tif (!(entryPoint.Instructions[0].MatchIfInstruction(out var condition, out var branchToSwitchHead)))\n\t\t\t\treturn hashtables;\n\t\t\tif (!entryPoint.Instructions[1].MatchBranch(out var tableInitBlock))\n\t\t\t\treturn hashtables;\n\t\t\tif (!(condition.MatchCompNotEquals(out var left, out var right) && right.MatchLdNull() &&\n\t\t\t\tMatchDictionaryFieldLoad(left, IsNonGenericHashtable, out var dictField, out var dictionaryType)))\n\t\t\t\treturn hashtables;\n\t\t\tif (!branchToSwitchHead.MatchBranch(out var switchHead))\n\t\t\t\treturn hashtables;\n\t\t\t// match second block: initialization of compiler-generated Hashtable\n\t\t\t// stloc table(newobj Hashtable..ctor(ldc.i4 capacity, ldc.f loadFactor))\n\t\t\t// call Add(ldloc table, ldstr value, box System.Int32(ldc.i4 index))\n\t\t\t// ... more calls to Add ...\n\t\t\t// volatile.stobj System.Collections.Hashtable(ldsflda $$method0x600003f - 1, ldloc table)\n\t\t\t// br switchHeadBlock\n\t\t\tif (tableInitBlock.IncomingEdgeCount != 1 || tableInitBlock.Instructions.Count < 3)\n\t\t\t\treturn hashtables;\n\t\t\tBlock previousBlock = entryPoint;\n\t\t\twhile (tableInitBlock != null)\n\t\t\t{\n\t\t\t\tif (!ExtractStringValuesFromInitBlock(tableInitBlock, out var stringValues, out var blockAfterThisInitBlock, dictionaryType, dictField, true))\n\t\t\t\t\tbreak;\n\t\t\t\tvar nextHashtableInitHead = tableInitBlock.Instructions.SecondToLastOrDefault() as IfInstruction;\n\t\t\t\thashtables.Add(dictField, (stringValues, nextHashtableInitHead, tableInitBlock, previousBlock, blockAfterThisInitBlock, false));\n\t\t\t\tpreviousBlock = tableInitBlock;\n\t\t\t\t// if there is another IfInstruction before the end of the block, it might be a jump to the next hashtable init block.\n\t\t\t\t// if (comp(volatile.ldobj System.Collections.Hashtable(ldsflda $$method0x600003f-2) != ldnull)) br switchHeadBlock\n\t\t\t\tif (nextHashtableInitHead != null)\n\t\t\t\t{\n\t\t\t\t\tif (!(nextHashtableInitHead.Condition.MatchCompNotEquals(out left, out right) && right.MatchLdNull() &&\n\t\t\t\t\t\tMatchDictionaryFieldLoad(left, IsNonGenericHashtable, out var nextDictField, out _)))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tif (!nextHashtableInitHead.TrueInst.MatchBranch(switchHead))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\ttableInitBlock = blockAfterThisInitBlock;\n\t\t\t\t\tdictField = nextDictField;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn hashtables;\n\t\t}\n\n\t\tbool SimplifyCascadingIfStatements(InstructionCollection<ILInstruction> instructions, ref int i)\n\t\t{\n\t\t\t// match first block: checking switch-value for null or first value (Roslyn)\n\t\t\t// if (call op_Equality(ldloc switchValueVar, ldstr value)) br firstBlock\n\t\t\t// -or-\n\t\t\t// if (comp(ldloc switchValueVar == ldnull)) br defaultBlock\n\t\t\tif (!instructions[i].MatchIfInstruction(out var condition, out var firstBlockOrDefaultJump))\n\t\t\t\treturn false;\n\t\t\tvar nextCaseJump = instructions[i + 1];\n\t\t\twhile (condition.MatchLogicNot(out var arg))\n\t\t\t{\n\t\t\t\tcondition = arg;\n\t\t\t\tExtensionMethods.Swap(ref firstBlockOrDefaultJump, ref nextCaseJump);\n\t\t\t}\n\t\t\t// match call to operator ==(string, string)\n\t\t\tif (!MatchStringEqualityComparison(condition, out var switchValueVar, out string firstBlockValue, out bool isVBCompareString))\n\t\t\t\treturn false;\n\t\t\tif (isVBCompareString)\n\t\t\t{\n\t\t\t\tExtensionMethods.Swap(ref firstBlockOrDefaultJump, ref nextCaseJump);\n\t\t\t}\n\n\t\t\tif (firstBlockOrDefaultJump.MatchBranch(out var firstBlock))\n\t\t\t{\n\t\t\t\t// success\n\t\t\t}\n\t\t\telse if (firstBlockOrDefaultJump.MatchLeave(out _))\n\t\t\t{\n\t\t\t\tfirstBlock = null;\n\t\t\t\t// success\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar values = new List<(string, ILInstruction)>();\n\t\t\tvar uniqueValues = new HashSet<string>();\n\t\t\tint numberOfUniqueMatchesWithCurrentVariable = 0;\n\t\t\tHashSet<Block> caseBlocks = new HashSet<Block>();\n\t\t\tcaseBlocks.Add((Block)instructions[i].Parent);\n\n\t\t\tbool AddSwitchSection(string value, ILInstruction inst)\n\t\t\t{\n\t\t\t\tif (!uniqueValues.Add(value))\n\t\t\t\t\treturn false;\n\t\t\t\tnumberOfUniqueMatchesWithCurrentVariable++;\n\t\t\t\tvalues.Add((value, inst));\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tILInstruction switchValue = null;\n\t\t\tif (isVBCompareString && string.IsNullOrEmpty(firstBlockValue))\n\t\t\t{\n\t\t\t\tif (!AddSwitchSection(null, firstBlock ?? firstBlockOrDefaultJump))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!AddSwitchSection(string.Empty, firstBlock ?? firstBlockOrDefaultJump))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (!AddSwitchSection(firstBlockValue, firstBlock ?? firstBlockOrDefaultJump))\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tbool removeExtraLoad = false;\n\t\t\tbool keepAssignmentBefore = false;\n\t\t\tif (i >= 1 && instructions[i - 1].MatchStLoc(switchValueVar, out switchValue))\n\t\t\t{\n\t\t\t\t// stloc switchValueVar(switchValue)\n\t\t\t\t// if (call op_Equality(ldloc switchValueVar, ldstr value)) br firstBlock\n\n\t\t\t\t// Newer versions of Roslyn use extra variables:\n\t\t\t\tif (i >= 2 && switchValue.MatchLdLoc(out var otherSwitchValueVar) && otherSwitchValueVar.IsSingleDefinition && otherSwitchValueVar.LoadCount == 1\n\t\t\t\t\t&& instructions[i - 2].MatchStLoc(otherSwitchValueVar, out var newSwitchValue))\n\t\t\t\t{\n\t\t\t\t\tswitchValue = newSwitchValue;\n\t\t\t\t\tremoveExtraLoad = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (i >= 1 && instructions[i - 1] is StLoc stloc)\n\t\t\t{\n\t\t\t\tif (stloc.Value.MatchLdLoc(switchValueVar))\n\t\t\t\t{\n\t\t\t\t\t// in case of optimized legacy code there are two stlocs:\n\t\t\t\t\t// stloc otherSwitchValueVar(ldloc switchValue)\n\t\t\t\t\t// stloc switchValueVar(ldloc otherSwitchValueVar)\n\t\t\t\t\t// if (call op_Equality(ldloc otherSwitchValueVar, ldstr value)) br firstBlock\n\t\t\t\t\tvar otherSwitchValueVar = switchValueVar;\n\t\t\t\t\tswitchValueVar = stloc.Variable;\n\t\t\t\t\tnumberOfUniqueMatchesWithCurrentVariable = 0;\n\t\t\t\t\tif (i >= 2 && instructions[i - 2].MatchStLoc(otherSwitchValueVar, out switchValue)\n\t\t\t\t\t\t&& otherSwitchValueVar.IsSingleDefinition && otherSwitchValueVar.LoadCount == 2)\n\t\t\t\t\t{\n\t\t\t\t\t\tremoveExtraLoad = true;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tswitchValue = new LdLoc(otherSwitchValueVar);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Variable before the start of the switch is not related to the switch.\n\t\t\t\t\tkeepAssignmentBefore = true;\n\t\t\t\t\tswitchValue = new LdLoc(switchValueVar);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Instruction before the start of the switch is not related to the switch.\n\t\t\t\tkeepAssignmentBefore = true;\n\t\t\t\tswitchValue = new LdLoc(switchValueVar);\n\t\t\t}\n\t\t\tif (!switchValueVar.Type.IsKnownType(KnownTypeCode.String))\n\t\t\t{\n\t\t\t\tif (!context.Settings.SwitchOnReadOnlySpanChar)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!switchValueVar.Type.IsKnownType(KnownTypeCode.ReadOnlySpanOfT)\n\t\t\t\t\t&& !switchValueVar.Type.IsKnownType(KnownTypeCode.SpanOfT))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// if instruction must be followed by a branch to the next case\n\t\t\tif (!nextCaseJump.MatchBranch(out Block currentCaseBlock))\n\t\t\t\treturn false;\n\t\t\t// extract all cases and add them to the values list.\n\t\t\tILInstruction nextCaseBlock;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tnextCaseBlock = MatchCaseBlock(currentCaseBlock, switchValueVar, out string value, out bool emptyStringEqualsNull, out ILInstruction block);\n\t\t\t\tif (nextCaseBlock == null)\n\t\t\t\t\tbreak;\n\t\t\t\tif (emptyStringEqualsNull && string.IsNullOrEmpty(value))\n\t\t\t\t{\n\t\t\t\t\tif (!AddSwitchSection(null, block))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!AddSwitchSection(string.Empty, block))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (!AddSwitchSection(value, block))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tcaseBlocks.Add(currentCaseBlock);\n\t\t\t\tcurrentCaseBlock = nextCaseBlock as Block;\n\t\t\t} while (currentCaseBlock != null);\n\n\t\t\t// We didn't find enough cases, exit\n\t\t\tif (values.Count < 3)\n\t\t\t\treturn false;\n\t\t\tcontext.Step(nameof(SimplifyCascadingIfStatements), instructions[i]);\n\t\t\t// if the switchValueVar is used in other places as well, do not eliminate the store.\n\t\t\tif (switchValueVar.LoadCount > numberOfUniqueMatchesWithCurrentVariable || !ValidateUsesOfSwitchValueVariable(switchValueVar, caseBlocks))\n\t\t\t{\n\t\t\t\tkeepAssignmentBefore = true;\n\t\t\t\tremoveExtraLoad = false; // prevent loads from being deleted after detecting that\n\t\t\t\t\t\t\t\t\t\t // we have to keep the assignment before the switch statement\n\t\t\t\tswitchValue = new LdLoc(switchValueVar);\n\t\t\t}\n\t\t\tint offset = firstBlock == null ? 1 : 0;\n\t\t\tvar sections = new List<SwitchSection>(values.Skip(offset).SelectWithIndex((index, s) => new SwitchSection { Labels = new LongSet(index), Body = s.Item2 is Block b ? new Branch(b) : s.Item2.Clone() }));\n\t\t\tsections.Add(new SwitchSection { Labels = new LongSet(new LongInterval(0, sections.Count)).Invert(), Body = currentCaseBlock != null ? (ILInstruction)new Branch(currentCaseBlock) : new Leave((BlockContainer)nextCaseBlock) });\n\t\t\tvar stringToInt = new StringToInt(switchValue, values.Skip(offset).Select(item => item.Item1).ToArray(), switchValueVar.Type);\n\t\t\tvar inst = new SwitchInstruction(stringToInt);\n\t\t\tinst.Sections.AddRange(sections);\n\t\t\tif (removeExtraLoad)\n\t\t\t{\n\t\t\t\tinst.AddILRange(instructions[i - 2]);\n\t\t\t\tinstructions[i - 2].ReplaceWith(inst);\n\t\t\t\tinstructions.RemoveRange(i - 1, 3);\n\t\t\t\ti -= 2;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (keepAssignmentBefore)\n\t\t\t\t{\n\t\t\t\t\tinst.AddILRange(instructions[i]);\n\t\t\t\t\tinstructions[i].ReplaceWith(inst);\n\t\t\t\t\tinstructions.RemoveAt(i + 1);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tinst.AddILRange(instructions[i - 1]);\n\t\t\t\t\tinstructions[i - 1].ReplaceWith(inst);\n\t\t\t\t\tinstructions.RemoveRange(i, 2);\n\t\t\t\t\ti--;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tprivate bool ValidateUsesOfSwitchValueVariable(ILVariable switchValueVar, HashSet<Block> caseBlocks)\n\t\t{\n\t\t\tforeach (var use in switchValueVar.LoadInstructions)\n\t\t\t{\n\t\t\t\tbool isValid = false;\n\t\t\t\tforeach (var caseBlock in caseBlocks)\n\t\t\t\t{\n\t\t\t\t\tif (use.IsDescendantOf(caseBlock))\n\t\t\t\t\t\tisValid = true;\n\t\t\t\t}\n\t\t\t\tif (!isValid)\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tbool SimplifyCSharp1CascadingIfStatements(InstructionCollection<ILInstruction> instructions, ref int i)\n\t\t{\n\t\t\tif (i < 1)\n\t\t\t\treturn false;\n\t\t\t// match first block:\n\t\t\t// stloc switchValueVar(ldloc temp)\n\t\t\t// if (comp(ldloc temp == ldnull)) br defaultBlock\n\t\t\t// br isInternedBlock\n\t\t\tif (!(instructions[i].MatchIfInstruction(out var condition, out var defaultBlockJump)))\n\t\t\t\treturn false;\n\t\t\tif (!instructions[i + 1].MatchBranch(out var isInternedBlock))\n\t\t\t\treturn false;\n\t\t\tif (!defaultBlockJump.MatchBranch(out var defaultOrNullBlock))\n\t\t\t\treturn false;\n\t\t\tif (!(condition.MatchCompEqualsNull(out var tempLoad) && tempLoad.MatchLdLoc(out var temp)))\n\t\t\t\treturn false;\n\t\t\tif (!(temp.Kind == VariableKind.StackSlot && temp.LoadCount == 2))\n\t\t\t\treturn false;\n\t\t\tif (!(instructions[i - 1].MatchStLoc(out var switchValueVar, out var switchValue) && switchValue.MatchLdLoc(temp)))\n\t\t\t\treturn false;\n\t\t\t// match isInternedBlock:\n\t\t\t// stloc switchValueVarCopy(call IsInterned(ldloc switchValueVar))\n\t\t\t// if (comp(ldloc switchValueVarCopy == ldstr \"case1\")) br caseBlock1\n\t\t\t// br caseHeader2\n\t\t\tif (isInternedBlock.IncomingEdgeCount != 1 || isInternedBlock.Instructions.Count != 3)\n\t\t\t\treturn false;\n\t\t\tif (!(isInternedBlock.Instructions[0].MatchStLoc(out var switchValueVarCopy, out var arg) && IsIsInternedCall(arg as Call, out arg) && arg.MatchLdLoc(switchValueVar)))\n\t\t\t\treturn false;\n\t\t\tswitchValueVar = switchValueVarCopy;\n\t\t\tint conditionOffset = 1;\n\t\t\tBlock currentCaseBlock = isInternedBlock;\n\t\t\tvar values = new List<(string, ILInstruction)>();\n\n\t\t\tif (!switchValueVarCopy.IsSingleDefinition)\n\t\t\t\treturn false;\n\n\t\t\t// each case starts with:\n\t\t\t// if (comp(ldloc switchValueVar == ldstr \"case label\")) br caseBlock\n\t\t\t// br currentCaseBlock\n\n\t\t\twhile (currentCaseBlock.Instructions[conditionOffset].MatchIfInstruction(out condition, out var caseBlockJump))\n\t\t\t{\n\t\t\t\tif (currentCaseBlock.Instructions.Count != conditionOffset + 2)\n\t\t\t\t\tbreak;\n\t\t\t\tif (!condition.MatchCompEquals(out var left, out var right))\n\t\t\t\t\tbreak;\n\t\t\t\tif (!left.MatchLdLoc(switchValueVar))\n\t\t\t\t\tbreak;\n\t\t\t\tif (!right.MatchLdStr(out string value))\n\t\t\t\t\tbreak;\n\t\t\t\tif (!(caseBlockJump.MatchBranch(out var caseBlock) || caseBlockJump.MatchLeave((BlockContainer)currentCaseBlock.Parent)))\n\t\t\t\t\tbreak;\n\t\t\t\tif (!currentCaseBlock.Instructions[conditionOffset + 1].MatchBranch(out currentCaseBlock))\n\t\t\t\t\tbreak;\n\t\t\t\tconditionOffset = 0;\n\t\t\t\tvalues.Add((value, caseBlockJump.Clone()));\n\t\t\t}\n\n\t\t\tif (values.Count != switchValueVarCopy.LoadCount)\n\t\t\t\treturn false;\n\t\t\tcontext.Step(nameof(SimplifyCSharp1CascadingIfStatements), instructions[i]);\n\n\t\t\t// switch contains case null: \n\t\t\tif (currentCaseBlock != defaultOrNullBlock)\n\t\t\t{\n\t\t\t\tvalues.Add((null, new Branch(defaultOrNullBlock)));\n\t\t\t}\n\n\t\t\tvar sections = new List<SwitchSection>(values.SelectWithIndex((index, b) => new SwitchSection { Labels = new LongSet(index), Body = b.Item2 }));\n\t\t\tsections.Add(new SwitchSection { Labels = new LongSet(new LongInterval(0, sections.Count)).Invert(), Body = new Branch(currentCaseBlock) });\n\t\t\tvar stringToInt = new StringToInt(switchValue, values.SelectArray(item => item.Item1), context.TypeSystem.FindType(KnownTypeCode.String));\n\t\t\tvar inst = new SwitchInstruction(stringToInt);\n\t\t\tinst.Sections.AddRange(sections);\n\n\t\t\tinst.AddILRange(instructions[i - 1]);\n\t\t\tinstructions[i].ReplaceWith(inst);\n\t\t\tinstructions.RemoveAt(i + 1);\n\t\t\tinstructions.RemoveAt(i - 1);\n\n\t\t\treturn true;\n\t\t}\n\n\t\tbool IsIsInternedCall(Call call, out ILInstruction argument)\n\t\t{\n\t\t\tif (call != null\n\t\t\t\t&& call.Method.DeclaringType.IsKnownType(KnownTypeCode.String)\n\t\t\t\t&& call.Method.IsStatic\n\t\t\t\t&& call.Method.Name == \"IsInterned\"\n\t\t\t\t&& call.Arguments.Count == 1)\n\t\t\t{\n\t\t\t\targument = call.Arguments[0];\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\targument = null;\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Each case consists of two blocks:\n\t\t/// 1. block:\n\t\t/// if (call op_Equality(ldloc switchVariable, ldstr value)) br caseBlock\n\t\t/// br nextBlock\n\t\t/// -or-\n\t\t/// if (comp(ldloc switchValueVar == ldnull)) br nextBlock\n\t\t/// br caseBlock\n\t\t/// 2. block is caseBlock\n\t\t/// This method matches the above pattern or its inverted form:\n\t\t/// the call to ==(string, string) is wrapped in logic.not and the branch targets are reversed.\n\t\t/// Returns the next block that follows in the block-chain.\n\t\t/// The <paramref name=\"switchVariable\"/> is updated if the value gets copied to a different variable.\n\t\t/// See comments below for more info.\n\t\t/// </summary>\n\t\tILInstruction MatchCaseBlock(Block currentBlock, ILVariable switchVariable, out string value, out bool emptyStringEqualsNull, out ILInstruction caseBlockOrLeave)\n\t\t{\n\t\t\tvalue = null;\n\t\t\tcaseBlockOrLeave = null;\n\t\t\temptyStringEqualsNull = false;\n\n\t\t\tif (currentBlock.IncomingEdgeCount != 1 || currentBlock.Instructions.Count != 2)\n\t\t\t\treturn null;\n\t\t\tif (!currentBlock.MatchIfAtEndOfBlock(out var condition, out var caseBlockBranch, out var nextBlockBranch))\n\t\t\t\treturn null;\n\t\t\tif (!MatchStringEqualityComparison(condition, switchVariable, out value, out bool isVBCompareString))\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (isVBCompareString)\n\t\t\t{\n\t\t\t\tExtensionMethods.Swap(ref caseBlockBranch, ref nextBlockBranch);\n\t\t\t\temptyStringEqualsNull = true;\n\t\t\t}\n\t\t\tif (caseBlockBranch.MatchBranch(out var caseBlock))\n\t\t\t{\n\t\t\t\tcaseBlockOrLeave = caseBlock;\n\t\t\t}\n\t\t\telse if (caseBlockBranch.MatchLeave(out _))\n\t\t\t{\n\t\t\t\tcaseBlockOrLeave = caseBlockBranch;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (nextBlockBranch.MatchBranch(out Block nextBlock))\n\t\t\t{\n\t\t\t\t// success\n\t\t\t\treturn nextBlock;\n\t\t\t}\n\t\t\telse if (nextBlockBranch.MatchLeave(out BlockContainer blockContainer))\n\t\t\t{\n\t\t\t\t// success\n\t\t\t\treturn blockContainer;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches the C# 2.0 switch-on-string pattern, which uses Dictionary&lt;string, int&gt;.\n\t\t/// </summary>\n\t\tbool MatchLegacySwitchOnStringWithDict(InstructionCollection<ILInstruction> instructions, ref int i)\n\t\t{\n\t\t\t// match first block: checking switch-value for null:\n\t\t\t// (In some cases, i.e., if switchValueVar is a parameter, the initial store is optional.)\n\t\t\t// stloc switchValueVar(switchValue)\n\t\t\t// if (comp(ldloc switchValueVar == ldnull)) br nullCase\n\t\t\t// br nextBlock\n\t\t\tif (!instructions[i].MatchIfInstruction(out var condition, out var exitBlockJump))\n\t\t\t\treturn false;\n\t\t\tif (!(condition.MatchCompEquals(out var left, out var right) && right.MatchLdNull()))\n\t\t\t\treturn false;\n\t\t\t// Extract switchValueVar\n\t\t\tif (!left.MatchLdLoc(out var switchValueVar) || !switchValueVar.IsSingleDefinition)\n\t\t\t\treturn false;\n\t\t\t// If the switchValueVar is a stack slot and there is an assignment involving it right before the\n\t\t\t// switch-value null-check, we use the previously assigned variable as switchValueVar.\n\t\t\tILInstruction switchValue;\n\t\t\tif (switchValueVar.Kind == VariableKind.StackSlot\n\t\t\t\t&& instructions.ElementAtOrDefault(i - 1) is StLoc extraStore\n\t\t\t\t&& extraStore.Value.MatchLdLoc(switchValueVar))\n\t\t\t{\n\t\t\t\tswitchValueVar = extraStore.Variable;\n\t\t\t\tswitchValue = extraStore.Value;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tswitchValue = null;\n\t\t\t}\n\t\t\tif (!switchValueVar.Type.IsKnownType(KnownTypeCode.String))\n\t\t\t\treturn false;\n\t\t\t// either br nullCase or leave container\n\t\t\tBlockContainer leaveContainer = null;\n\t\t\tif (!exitBlockJump.MatchBranch(out var nullValueCaseBlock) && !exitBlockJump.MatchLeave(out leaveContainer))\n\t\t\t\treturn false;\n\t\t\tvar nextBlockJump = instructions.ElementAtOrDefault(i + 1) as Branch;\n\t\t\tif (nextBlockJump == null || nextBlockJump.TargetBlock.IncomingEdgeCount != 1)\n\t\t\t\treturn false;\n\t\t\t// match second block: checking compiler-generated Dictionary<string, int> for null\n\t\t\t// if (comp(volatile.ldobj System.Collections.Generic.Dictionary`2[[System.String],[System.Int32]](ldsflda $$method0x600000c-1) != ldnull)) br caseNullBlock\n\t\t\t// br dictInitBlock\n\t\t\tvar nextBlock = nextBlockJump.TargetBlock;\n\t\t\tif (nextBlock.Instructions.Count != 2 || !nextBlock.Instructions[0].MatchIfInstruction(out condition, out var tryGetValueBlockJump))\n\t\t\t\treturn false;\n\t\t\tif (!tryGetValueBlockJump.MatchBranch(out var tryGetValueBlock))\n\t\t\t\treturn false;\n\t\t\tif (!nextBlock.Instructions[1].MatchBranch(out var dictInitBlock) || dictInitBlock.IncomingEdgeCount != 1)\n\t\t\t\treturn false;\n\t\t\tif (!(condition.MatchCompNotEquals(out left, out right) && right.MatchLdNull() &&\n\t\t\t\tMatchDictionaryFieldLoad(left, IsStringToIntDictionary, out var dictField, out var dictionaryType)))\n\t\t\t\treturn false;\n\t\t\t// match third block: initialization of compiler-generated Dictionary<string, int>\n\t\t\t// stloc dict(newobj Dictionary..ctor(ldc.i4 valuesLength))\n\t\t\t// call Add(ldloc dict, ldstr value, ldc.i4 index)\n\t\t\t// ... more calls to Add ...\n\t\t\t// volatile.stobj System.Collections.Generic.Dictionary`2[[System.String],[System.Int32]](ldsflda $$method0x600003f-1, ldloc dict)\n\t\t\t// br switchHeadBlock\n\t\t\tif (dictInitBlock.IncomingEdgeCount != 1 || dictInitBlock.Instructions.Count < 3)\n\t\t\t\treturn false;\n\t\t\tif (!ExtractStringValuesFromInitBlock(dictInitBlock, out var stringValues, out var blockAfterInit, dictionaryType, dictField, false))\n\t\t\t\treturn false;\n\t\t\tif (tryGetValueBlock != blockAfterInit)\n\t\t\t\treturn false;\n\t\t\t// match fourth block: TryGetValue on compiler-generated Dictionary<string, int>\n\t\t\t// if (logic.not(call TryGetValue(volatile.ldobj System.Collections.Generic.Dictionary`2[[System.String],[System.Int32]](ldsflda $$method0x600000c-1), ldloc switchValueVar, ldloca switchIndexVar))) br defaultBlock\n\t\t\t// br switchBlock\n\t\t\tif (tryGetValueBlock.IncomingEdgeCount != 2 || tryGetValueBlock.Instructions.Count != 2)\n\t\t\t\treturn false;\n\t\t\tif (!tryGetValueBlock.Instructions[0].MatchIfInstruction(out condition, out var defaultBlockJump))\n\t\t\t\treturn false;\n\t\t\tif (!defaultBlockJump.MatchBranch(out var defaultBlock) && !((leaveContainer != null && defaultBlockJump.MatchLeave(leaveContainer)) || defaultBlockJump.MatchLeave(out _)))\n\t\t\t\treturn false;\n\t\t\tif (!(condition.MatchLogicNot(out var arg) && arg is CallInstruction c && c.Method.Name == \"TryGetValue\" &&\n\t\t\t\tMatchDictionaryFieldLoad(c.Arguments[0], IsStringToIntDictionary, out var dictField2, out _) && dictField2.Equals(dictField)))\n\t\t\t\treturn false;\n\t\t\tif (!c.Arguments[1].MatchLdLoc(switchValueVar) || !c.Arguments[2].MatchLdLoca(out var switchIndexVar))\n\t\t\t\treturn false;\n\t\t\tif (!tryGetValueBlock.Instructions[1].MatchBranch(out var switchBlock))\n\t\t\t\treturn false;\n\t\t\t// match fifth block: switch-instruction block\n\t\t\t// switch (ldloc switchVariable) {\n\t\t\t// \tcase [0..1): br caseBlock1\n\t\t\t//  ... more cases ...\n\t\t\t// \tcase [long.MinValue..0),[13..long.MaxValue]: br defaultBlock\n\t\t\t// }\n\t\t\t// mcs has a bug: when there is only one case it still generates the full-blown Dictionary<string, int> pattern,\n\t\t\t// but uses only a simple if statement instead of the switch instruction.\n\t\t\tif (switchBlock.IncomingEdgeCount != 1 || switchBlock.Instructions.Count == 0)\n\t\t\t\treturn false;\n\t\t\tvar sections = new List<SwitchSection>();\n\t\t\tswitch (switchBlock.Instructions[0])\n\t\t\t{\n\t\t\t\tcase SwitchInstruction switchInst:\n\t\t\t\t\tif (switchBlock.Instructions.Count != 1)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!switchInst.Value.MatchLdLoc(switchIndexVar))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tsections.AddRange(switchInst.Sections);\n\t\t\t\t\tbreak;\n\t\t\t\tcase IfInstruction ifInst:\n\t\t\t\t\tif (switchBlock.Instructions.Count != 2)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!ifInst.Condition.MatchCompEquals(out left, out right))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!left.MatchLdLoc(switchIndexVar))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!right.MatchLdcI4(0))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tsections.Add(new SwitchSection() { Body = ifInst.TrueInst, Labels = new LongSet(0) }.WithILRange(ifInst));\n\t\t\t\t\tsections.Add(new SwitchSection() { Body = switchBlock.Instructions[1], Labels = new LongSet(0).Invert() }.WithILRange(switchBlock.Instructions[1]));\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// mcs: map sections without a value to the default section, if possible\n\t\t\tif (!FixCasesWithoutValue(sections, stringValues))\n\t\t\t\treturn false;\n\t\t\t// switch contains case null:\n\t\t\tif (nullValueCaseBlock != null && nullValueCaseBlock != defaultBlock)\n\t\t\t{\n\t\t\t\tif (!AddNullSection(sections, stringValues, nullValueCaseBlock))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (leaveContainer != null && !defaultBlockJump.MatchLeave(leaveContainer))\n\t\t\t{\n\t\t\t\tif (!AddNullSection(sections, stringValues, (Leave)exitBlockJump))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontext.Step(nameof(MatchLegacySwitchOnStringWithDict), instructions[i]);\n\t\t\tbool keepAssignmentBefore = false;\n\t\t\tif (switchValueVar.LoadCount > 2 || switchValue == null)\n\t\t\t{\n\t\t\t\tswitchValue = new LdLoc(switchValueVar);\n\t\t\t\tkeepAssignmentBefore = true;\n\t\t\t}\n\t\t\tvar stringToInt = new StringToInt(switchValue, stringValues, switchValueVar.Type);\n\t\t\tvar inst = new SwitchInstruction(stringToInt);\n\t\t\tinst.Sections.AddRange(sections);\n\t\t\tinstructions[i + 1].ReplaceWith(inst);\n\t\t\tif (keepAssignmentBefore)\n\t\t\t{\n\t\t\t\t// delete if (comp(ldloc switchValueVar == ldnull))\n\t\t\t\tinst.AddILRange(instructions[i]);\n\t\t\t\tinstructions.RemoveAt(i);\n\t\t\t\ti--;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// delete both the if and the assignment before\n\t\t\t\tinst.AddILRange(instructions[i - 1]);\n\t\t\t\tinstructions.RemoveRange(i - 1, 2);\n\t\t\t\ti -= 2;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tbool FixCasesWithoutValue(List<SwitchSection> sections, List<(string, int)> stringValues)\n\t\t{\n\t\t\tbool HasLabel(SwitchSection section)\n\t\t\t{\n\t\t\t\treturn section.Labels.Values.Any(i => stringValues.Any(value => i == value.Item2));\n\t\t\t}\n\n\t\t\t// Pick the section with the most labels as default section.\n\t\t\t// And collect all sections that have no value mapped to them.\n\t\t\tSwitchSection defaultSection = sections.First();\n\t\t\tList<SwitchSection> sectionsWithoutLabels = new List<SwitchSection>();\n\t\t\tforeach (var section in sections)\n\t\t\t{\n\t\t\t\tif (section == defaultSection)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (section.Labels.Count() > defaultSection.Labels.Count())\n\t\t\t\t{\n\t\t\t\t\tif (!HasLabel(defaultSection))\n\t\t\t\t\t\tsectionsWithoutLabels.Add(defaultSection);\n\t\t\t\t\tdefaultSection = section;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!HasLabel(section))\n\t\t\t\t\tsectionsWithoutLabels.Add(section);\n\t\t\t}\n\n\t\t\tforeach (var section in sectionsWithoutLabels)\n\t\t\t{\n\t\t\t\tdefaultSection.Labels = defaultSection.Labels.UnionWith(section.Labels);\n\t\t\t\tif (section.HasNullLabel)\n\t\t\t\t\tdefaultSection.HasNullLabel = true;\n\t\t\t\tsections.Remove(section);\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tbool AddNullSection(List<SwitchSection> sections, List<(string Value, int Index)> stringValues, Block nullValueCaseBlock)\n\t\t{\n\t\t\treturn AddNullSection(sections, stringValues, new Branch(nullValueCaseBlock));\n\t\t}\n\n\t\tbool AddNullSection(List<SwitchSection> sections, List<(string Value, int Index)> stringValues, ILInstruction body)\n\t\t{\n\t\t\tvar label = new LongSet(stringValues.Max(item => item.Index) + 1);\n\t\t\tvar possibleConflicts = sections.Where(sec => sec.Labels.Overlaps(label)).ToArray();\n\t\t\tif (possibleConflicts.Length > 1)\n\t\t\t\treturn false;\n\t\t\telse if (possibleConflicts.Length == 1)\n\t\t\t{\n\t\t\t\tif (possibleConflicts[0].Labels.Count() == 1)\n\t\t\t\t\treturn false; // cannot remove only label\n\t\t\t\tpossibleConflicts[0].Labels = possibleConflicts[0].Labels.ExceptWith(label);\n\t\t\t}\n\t\t\tstringValues.Add((null, (int)label.Values.First()));\n\t\t\tsections.Add(new SwitchSection() { Labels = label, Body = body });\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches 'volatile.ldobj dictionaryType(ldsflda dictField)'\n\t\t/// </summary>\n\t\tbool MatchDictionaryFieldLoad(ILInstruction inst, Func<IType, bool> typeMatcher, out IField dictField, out IType dictionaryType)\n\t\t{\n\t\t\tdictField = null;\n\t\t\tdictionaryType = null;\n\t\t\treturn inst.MatchLdObj(out var dictionaryFieldLoad, out dictionaryType) &&\n\t\t\t\ttypeMatcher(dictionaryType) &&\n\t\t\t\tdictionaryFieldLoad.MatchLdsFlda(out dictField) &&\n\t\t\t\t(dictField.IsCompilerGeneratedOrIsInCompilerGeneratedClass() || dictField.Name.StartsWith(\"$$method\", StringComparison.Ordinal));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches and extracts values from Add-call sequences.\n\t\t/// </summary>\n\t\tbool ExtractStringValuesFromInitBlock(Block block, out List<(string, int)> values, out Block blockAfterInit, IType dictionaryType, IField dictionaryField, bool isHashtablePattern)\n\t\t{\n\t\t\tvalues = null;\n\t\t\tblockAfterInit = null;\n\t\t\t// stloc dictVar(newobj Dictionary..ctor(ldc.i4 valuesLength))\n\t\t\t// -or-\n\t\t\t// stloc dictVar(newobj Hashtable..ctor(ldc.i4 capacity, ldc.f4 loadFactor))\n\t\t\tif (!(block.Instructions[0].MatchStLoc(out var dictVar, out var newObjDict) && newObjDict is NewObj newObj))\n\t\t\t\treturn false;\n\t\t\tif (!newObj.Method.DeclaringType.Equals(dictionaryType))\n\t\t\t\treturn false;\n\t\t\tint valuesLength = 0;\n\t\t\tif (newObj.Arguments.Count == 2)\n\t\t\t{\n\t\t\t\tif (!newObj.Arguments[0].MatchLdcI4(out valuesLength))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!newObj.Arguments[1].MatchLdcF4(0.5f))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse if (newObj.Arguments.Count == 1)\n\t\t\t{\n\t\t\t\tif (!newObj.Arguments[0].MatchLdcI4(out valuesLength))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvalues = new List<(string, int)>(valuesLength);\n\t\t\tint i = 0;\n\t\t\twhile (MatchAddCall(dictionaryType, block.Instructions[i + 1], dictVar, out var index, out var value))\n\t\t\t{\n\t\t\t\tvalues.Add((value, index));\n\t\t\t\ti++;\n\t\t\t}\n\t\t\t// final store to compiler-generated variable:\n\t\t\t// volatile.stobj dictionaryType(ldsflda dictionaryField, ldloc dictVar)\n\t\t\tif (!(block.Instructions[i + 1].MatchStObj(out var loadField, out var dictVarLoad, out var dictType) &&\n\t\t\t\tdictType.Equals(dictionaryType) && loadField.MatchLdsFlda(out var dictField) && dictField.Equals(dictionaryField) &&\n\t\t\t\tdictVarLoad.MatchLdLoc(dictVar)))\n\t\t\t\treturn false;\n\t\t\tif (isHashtablePattern && block.Instructions[i + 2] is IfInstruction)\n\t\t\t{\n\t\t\t\treturn block.Instructions[i + 3].MatchBranch(out blockAfterInit);\n\t\t\t}\n\t\t\treturn block.Instructions[i + 2].MatchBranch(out blockAfterInit);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// call Add(ldloc dictVar, ldstr value, ldc.i4 index)\n\t\t/// -or-\n\t\t/// call Add(ldloc dictVar, ldstr value, box System.Int32(ldc.i4 index))\n\t\t/// </summary>\n\t\tbool MatchAddCall(IType dictionaryType, ILInstruction inst, ILVariable dictVar, out int index, out string value)\n\t\t{\n\t\t\tvalue = null;\n\t\t\tindex = -1;\n\t\t\tif (!(inst is CallInstruction c && c.Method.Name == \"Add\" && c.Arguments.Count == 3))\n\t\t\t\treturn false;\n\t\t\tif (!c.Arguments[0].MatchLdLoc(dictVar))\n\t\t\t\treturn false;\n\t\t\tif (!c.Arguments[1].MatchLdStr(out value))\n\t\t\t{\n\t\t\t\tif (c.Arguments[1].MatchLdsFld(out var field) && field.DeclaringType.IsKnownType(KnownTypeCode.String) && field.Name == \"Empty\")\n\t\t\t\t{\n\t\t\t\t\tvalue = \"\";\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!(c.Method.DeclaringType.Equals(dictionaryType) && !c.Method.IsStatic))\n\t\t\t\treturn false;\n\t\t\treturn (c.Arguments[2].MatchLdcI4(out index) || (c.Arguments[2].MatchBox(out var arg, out _) && arg.MatchLdcI4(out index)));\n\t\t}\n\n\t\tbool IsStringToIntDictionary(IType dictionaryType)\n\t\t{\n\t\t\tif (dictionaryType.FullName != \"System.Collections.Generic.Dictionary\")\n\t\t\t\treturn false;\n\t\t\tif (dictionaryType.TypeArguments.Count != 2)\n\t\t\t\treturn false;\n\t\t\treturn dictionaryType.TypeArguments[0].IsKnownType(KnownTypeCode.String) &&\n\t\t\t\tdictionaryType.TypeArguments[1].IsKnownType(KnownTypeCode.Int32);\n\t\t}\n\n\t\tbool IsNonGenericHashtable(IType dictionaryType)\n\t\t{\n\t\t\tif (dictionaryType.FullName != \"System.Collections.Hashtable\")\n\t\t\t\treturn false;\n\t\t\tif (dictionaryType.TypeArguments.Count != 0)\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tbool MatchLegacySwitchOnStringWithHashtable(Block block, HashtableInitializer hashtableInitializers, ref int i)\n\t\t{\n\t\t\t// match first block: checking switch-value for null\n\t\t\t// stloc tmp(ldloc switch-value)\n\t\t\t// stloc switchVariable(ldloc tmp)\n\t\t\t// if (comp(ldloc tmp == ldnull)) br nullCaseBlock\n\t\t\t// br getItemBlock\n\t\t\tif (block.Instructions.Count != i + 4)\n\t\t\t\treturn false;\n\t\t\tif (!block.Instructions[i].MatchStLoc(out var tmp, out var switchValue))\n\t\t\t\treturn false;\n\t\t\tif (!block.Instructions[i + 1].MatchStLoc(out var switchVariable, out var tmpLoad) || !tmpLoad.MatchLdLoc(tmp))\n\t\t\t\treturn false;\n\t\t\tif (!block.Instructions[i + 2].MatchIfInstruction(out var condition, out var nullCaseBlockBranch))\n\t\t\t\treturn false;\n\t\t\tif (!block.Instructions[i + 3].MatchBranch(out var getItemBlock) || !(nullCaseBlockBranch.MatchBranch(out var nullCaseBlock) || nullCaseBlockBranch is Leave))\n\t\t\t\treturn false;\n\t\t\tif (!(condition.MatchCompEquals(out var left, out var right) && right.MatchLdNull() && left.MatchLdLoc(tmp)))\n\t\t\t\treturn false;\n\t\t\t// match second block: get_Item on compiler-generated Hashtable\n\t\t\t// stloc tmp2(call get_Item(volatile.ldobj System.Collections.Hashtable(ldsflda $$method0x600003f - 1), ldloc switchVariable))\n\t\t\t// stloc switchVariable(ldloc tmp2)\n\t\t\t// if (comp(ldloc tmp2 == ldnull)) br defaultCaseBlock\n\t\t\t// br switchBlock\n\t\t\tif (getItemBlock.IncomingEdgeCount != 1 || getItemBlock.Instructions.Count != 4)\n\t\t\t\treturn false;\n\t\t\tif (!(getItemBlock.Instructions[0].MatchStLoc(out var tmp2, out var getItem) && getItem is Call getItemCall && getItemCall.Method.Name == \"get_Item\"))\n\t\t\t\treturn false;\n\t\t\tif (!getItemBlock.Instructions[1].MatchStLoc(out var switchVariable2, out var tmp2Load) || !tmp2Load.MatchLdLoc(tmp2))\n\t\t\t\treturn false;\n\t\t\tif (!ILVariableEqualityComparer.Instance.Equals(switchVariable, switchVariable2))\n\t\t\t\treturn false;\n\t\t\tif (!getItemBlock.Instructions[2].MatchIfInstruction(out condition, out var defaultBlockBranch))\n\t\t\t\treturn false;\n\t\t\tif (!getItemBlock.Instructions[3].MatchBranch(out var switchBlock) || !(defaultBlockBranch.MatchBranch(out var defaultBlock) || defaultBlockBranch is Leave))\n\t\t\t\treturn false;\n\t\t\tif (!(condition.MatchCompEquals(out left, out right) && right.MatchLdNull() && left.MatchLdLoc(tmp2)))\n\t\t\t\treturn false;\n\t\t\tif (!(getItemCall.Arguments.Count == 2 && MatchDictionaryFieldLoad(getItemCall.Arguments[0], IsNonGenericHashtable, out var dictField, out _) && getItemCall.Arguments[1].MatchLdLoc(switchVariable)))\n\t\t\t\treturn false;\n\t\t\t// Check if there is a hashtable init block at the beginning of the method\n\t\t\tif (!hashtableInitializers.TryGetValue(dictField, out var info))\n\t\t\t\treturn false;\n\t\t\tvar stringValues = info.Labels;\n\t\t\t// match third block: switch-instruction block\n\t\t\t// switch (ldobj System.Int32(unbox System.Int32(ldloc switchVariable))) {\n\t\t\t// \tcase [0..1): br caseBlock1\n\t\t\t//  ... more cases ...\n\t\t\t// \tcase [long.MinValue..0),[13..long.MaxValue]: br defaultBlock\n\t\t\t// }\n\t\t\tif (switchBlock.IncomingEdgeCount != 1 || switchBlock.Instructions.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (!(switchBlock.Instructions[0] is SwitchInstruction switchInst && switchInst.Value.MatchLdObj(out var target, out var ldobjType) &&\n\t\t\t\ttarget.MatchUnbox(out var arg, out var unboxType) && arg.MatchLdLoc(switchVariable2) && ldobjType.IsKnownType(KnownTypeCode.Int32) && unboxType.Equals(ldobjType)))\n\t\t\t\treturn false;\n\t\t\tvar sections = new List<SwitchSection>(switchInst.Sections);\n\t\t\t// switch contains case null: \n\t\t\tif (!(nullCaseBlockBranch is Leave) && nullCaseBlock != defaultBlock)\n\t\t\t{\n\t\t\t\tif (!AddNullSection(sections, stringValues, nullCaseBlock))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontext.Step(nameof(MatchLegacySwitchOnStringWithHashtable), block.Instructions[i]);\n\t\t\tvar stringToInt = new StringToInt(switchValue, stringValues, context.TypeSystem.FindType(KnownTypeCode.String));\n\t\t\tvar inst = new SwitchInstruction(stringToInt);\n\t\t\tinst.Sections.AddRange(sections);\n\t\t\tinst.AddILRange(block.Instructions[i]);\n\t\t\tblock.Instructions[i].ReplaceWith(inst);\n\t\t\tblock.Instructions.RemoveRange(i + 1, 3);\n\t\t\tinfo.Transformed = true;\n\t\t\thashtableInitializers[dictField] = info;\n\t\t\treturn true;\n\t\t}\n\n\t\tbool FindHashtableInitBlock(Block entryPoint, out List<(string, int)> stringValues, out IField dictField, out Block blockAfterThisInitBlock, out ILInstruction thisSwitchInitJumpInst, out ILInstruction nextSwitchInitJumpInst)\n\t\t{\n\t\t\tstringValues = null;\n\t\t\tdictField = null;\n\t\t\tblockAfterThisInitBlock = null;\n\t\t\tnextSwitchInitJumpInst = null;\n\t\t\tthisSwitchInitJumpInst = null;\n\t\t\tif (entryPoint.Instructions.Count != 2)\n\t\t\t\treturn false;\n\t\t\t// match first block: checking compiler-generated Hashtable for null\n\t\t\t// if (comp(volatile.ldobj System.Collections.Hashtable(ldsflda $$method0x600003f-1) != ldnull)) br switchHeadBlock\n\t\t\t// br tableInitBlock\n\t\t\tif (!(entryPoint.Instructions[0].MatchIfInstruction(out var condition, out var branchToSwitchHead)))\n\t\t\t\treturn false;\n\t\t\tif (!entryPoint.Instructions[1].MatchBranch(out var tableInitBlock))\n\t\t\t\treturn false;\n\t\t\tif (!(condition.MatchCompNotEquals(out var left, out var right) && right.MatchLdNull() &&\n\t\t\t\tMatchDictionaryFieldLoad(left, IsNonGenericHashtable, out dictField, out var dictionaryType)))\n\t\t\t\treturn false;\n\t\t\tif (!branchToSwitchHead.MatchBranch(out var switchHead))\n\t\t\t\treturn false;\n\t\t\tthisSwitchInitJumpInst = entryPoint.Instructions[0];\n\t\t\t// match second block: initialization of compiler-generated Hashtable\n\t\t\t// stloc table(newobj Hashtable..ctor(ldc.i4 capacity, ldc.f loadFactor))\n\t\t\t// call Add(ldloc table, ldstr value, box System.Int32(ldc.i4 index))\n\t\t\t// ... more calls to Add ...\n\t\t\t// volatile.stobj System.Collections.Hashtable(ldsflda $$method0x600003f - 1, ldloc table)\n\t\t\t// br switchHeadBlock\n\t\t\tif (tableInitBlock.IncomingEdgeCount != 1 || tableInitBlock.Instructions.Count < 3)\n\t\t\t\treturn false;\n\t\t\tif (!ExtractStringValuesFromInitBlock(tableInitBlock, out stringValues, out blockAfterThisInitBlock, dictionaryType, dictField, true))\n\t\t\t\treturn false;\n\t\t\t// if there is another IfInstruction before the end of the block, it might be a jump to the next hashtable init block.\n\t\t\t// if (comp(volatile.ldobj System.Collections.Hashtable(ldsflda $$method0x600003f-2) != ldnull)) br switchHeadBlock\n\t\t\tif (tableInitBlock.Instructions.SecondToLastOrDefault() is IfInstruction nextHashtableInitHead)\n\t\t\t{\n\t\t\t\tif (!(nextHashtableInitHead.Condition.MatchCompNotEquals(out left, out right) && right.MatchLdNull() &&\n\t\t\t\t\tMatchDictionaryFieldLoad(left, IsNonGenericHashtable, out var nextSwitchInitField, out _)))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!nextHashtableInitHead.TrueInst.MatchBranch(switchHead))\n\t\t\t\t\treturn false;\n\t\t\t\tnextSwitchInitJumpInst = nextHashtableInitHead;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tbool MatchRoslynSwitchOnString(InstructionCollection<ILInstruction> instructions, ref int i)\n\t\t{\n\t\t\tif (i >= instructions.Count - 1)\n\t\t\t\treturn false;\n\t\t\t// stloc switchValueVar(switchValue)\n\t\t\t// if (comp(ldloc switchValueVar == ldnull)) br nullCase\n\t\t\t// br nextBlock\n\t\t\tInstructionCollection<ILInstruction> switchBlockInstructions = instructions;\n\t\t\tint switchBlockInstructionsOffset = i;\n\t\t\tBlock nullValueCaseBlock = null;\n\t\t\tILInstruction instForNullCheck = null;\n\t\t\tif (instructions[i].MatchIfInstruction(out var condition, out var exitBlockJump)\n\t\t\t\t&& condition.MatchCompEqualsNull(out instForNullCheck))\n\t\t\t{\n\t\t\t\tvar nextBlockJump = instructions[i + 1] as Branch;\n\t\t\t\tif (nextBlockJump == null || nextBlockJump.TargetBlock.IncomingEdgeCount != 1)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!exitBlockJump.MatchBranch(out nullValueCaseBlock))\n\t\t\t\t\treturn false;\n\t\t\t\tswitchBlockInstructions = nextBlockJump.TargetBlock.Instructions;\n\t\t\t\tswitchBlockInstructionsOffset = 0;\n\t\t\t}\n\t\t\t// stloc switchValueVar(call ComputeStringHash(switchValueLoad))\n\t\t\t// switch (ldloc switchValueVar) {\n\t\t\t// \tcase [211455823..211455824): br caseBlock1\n\t\t\t//  ... more cases ...\n\t\t\t// \tcase [long.MinValue..-365098645),...,[1697255802..long.MaxValue]: br defaultBlock\n\t\t\t// }\n\t\t\tif (!(switchBlockInstructionsOffset + 1 < switchBlockInstructions.Count\n\t\t\t\t&& switchBlockInstructions[switchBlockInstructionsOffset + 1] is SwitchInstruction switchInst\n\t\t\t\t&& switchInst.Value.MatchLdLoc(out var switchValueVar)\n\t\t\t\t&& MatchComputeStringOrReadOnlySpanHashCall(switchBlockInstructions[switchBlockInstructionsOffset],\n\t\t\t\t\t\t\t\t\t\t\t  switchValueVar, out LdLoc switchValueLoad)))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (instForNullCheck != null && !instForNullCheck.MatchLdLoc(switchValueLoad.Variable))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar stringValues = new List<(string Value, ILInstruction TargetBlockOrLeave)>();\n\t\t\tSwitchSection defaultSection = switchInst.GetDefaultSection();\n\t\t\tif (!(defaultSection.Body.MatchBranch(out Block exitOrDefaultBlock) || defaultSection.Body.MatchLeave(out _)))\n\t\t\t\treturn false;\n\t\t\tforeach (var section in switchInst.Sections)\n\t\t\t{\n\t\t\t\tif (section == defaultSection)\n\t\t\t\t\tcontinue;\n\t\t\t\t// extract target block\n\t\t\t\tif (!section.Body.MatchBranch(out Block target))\n\t\t\t\t\treturn false;\n\t\t\t\tstring stringValue;\n\t\t\t\tbool emptyStringEqualsNull;\n\t\t\t\tif (MatchRoslynEmptyStringCaseBlockHead(target, switchValueLoad.Variable, out ILInstruction targetOrLeave, out Block currentExitBlock))\n\t\t\t\t{\n\t\t\t\t\tstringValue = \"\";\n\t\t\t\t\temptyStringEqualsNull = false;\n\t\t\t\t}\n\t\t\t\telse if (!MatchRoslynCaseBlockHead(target, switchValueLoad.Variable, out targetOrLeave, out currentExitBlock, out stringValue, out emptyStringEqualsNull))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (currentExitBlock != exitOrDefaultBlock)\n\t\t\t\t\treturn false;\n\t\t\t\tif (emptyStringEqualsNull && string.IsNullOrEmpty(stringValue))\n\t\t\t\t{\n\t\t\t\t\tstringValues.Add((null, targetOrLeave));\n\t\t\t\t\tstringValues.Add((string.Empty, targetOrLeave));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tstringValues.Add((stringValue, targetOrLeave));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (nullValueCaseBlock != null && exitOrDefaultBlock != nullValueCaseBlock)\n\t\t\t{\n\t\t\t\tstringValues.Add((null, nullValueCaseBlock));\n\t\t\t}\n\t\t\t// In newer Roslyn versions (>=3.7) the null check appears in the default case, not prior to the switch.\n\t\t\tILInstruction exitOrDefault = exitOrDefaultBlock;\n\t\t\tif (!stringValues.Any(pair => pair.Value == null) && IsNullCheckInDefaultBlock(ref exitOrDefault, switchValueLoad.Variable, out nullValueCaseBlock))\n\t\t\t{\n\t\t\t\tstringValues.Add((null, nullValueCaseBlock));\n\t\t\t}\n\t\t\texitOrDefaultBlock = (Block)exitOrDefault;\n\n\t\t\tcontext.Step(nameof(MatchRoslynSwitchOnString), switchValueLoad);\n\t\t\tif (exitOrDefaultBlock != null)\n\t\t\t{\n\t\t\t\t// change TargetBlock in case it was modified by IsNullCheckInDefaultBlock()\n\t\t\t\t((Branch)defaultSection.Body).TargetBlock = exitOrDefaultBlock;\n\t\t\t}\n\t\t\tILInstruction switchValueInst = switchValueLoad;\n\t\t\tif (instructions == switchBlockInstructions)\n\t\t\t{\n\t\t\t\t// stloc switchValueLoadVariable(switchValue)\n\t\t\t\t// stloc switchValueVar(call ComputeStringHash(ldloc switchValueLoadVariable))\n\t\t\t\t// switch (ldloc switchValueVar) {\n\t\t\t\tbool keepAssignmentBefore;\n\t\t\t\t// if the switchValueLoad.Variable is only used in the compiler generated case equality checks, we can remove it.\n\t\t\t\tif (i >= 1 && instructions[i - 1].MatchStLoc(switchValueLoad.Variable, out var switchValueTmp) &&\n\t\t\t\t\tswitchValueLoad.Variable.IsSingleDefinition && switchValueLoad.Variable.LoadCount == switchInst.Sections.Count)\n\t\t\t\t{\n\t\t\t\t\tswitchValueInst = switchValueTmp;\n\t\t\t\t\tkeepAssignmentBefore = false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tkeepAssignmentBefore = true;\n\t\t\t\t}\n\t\t\t\t// replace stloc switchValueVar(call ComputeStringHash(...)) with new switch instruction\n\t\t\t\tvar newSwitch = ReplaceWithSwitchInstruction(i);\n\t\t\t\t// remove old switch instruction\n\t\t\t\tnewSwitch.AddILRange(instructions[i + 1]);\n\t\t\t\tinstructions.RemoveAt(i + 1);\n\t\t\t\t// remove extra assignment\n\t\t\t\tif (!keepAssignmentBefore)\n\t\t\t\t{\n\t\t\t\t\tnewSwitch.AddILRange(instructions[i - 1]);\n\t\t\t\t\tinstructions.RemoveRange(i - 1, 1);\n\t\t\t\t\ti -= 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbool keepAssignmentBefore;\n\t\t\t\t// if the switchValueLoad.Variable is only used in the compiler generated case equality checks, we can remove it.\n\t\t\t\tif (i >= 2 && instructions[i - 2].MatchStLoc(out var temporary, out var temporaryValue) && instructions[i - 1].MatchStLoc(switchValueLoad.Variable, out var tempLoad) && tempLoad.MatchLdLoc(temporary))\n\t\t\t\t{\n\t\t\t\t\tswitchValueInst = temporaryValue;\n\t\t\t\t\tkeepAssignmentBefore = false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tkeepAssignmentBefore = true;\n\t\t\t\t}\n\t\t\t\t// replace null check with new switch instruction\n\t\t\t\tvar newSwitch = ReplaceWithSwitchInstruction(i);\n\t\t\t\tnewSwitch.AddILRange(switchInst);\n\t\t\t\t// remove jump instruction to switch block\n\t\t\t\tnewSwitch.AddILRange(instructions[i + 1]);\n\t\t\t\tinstructions.RemoveAt(i + 1);\n\t\t\t\t// remove extra assignment\n\t\t\t\tif (!keepAssignmentBefore)\n\t\t\t\t{\n\t\t\t\t\tnewSwitch.AddILRange(instructions[i - 2]);\n\t\t\t\t\tinstructions.RemoveRange(i - 2, 2);\n\t\t\t\t\ti -= 2;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\n\t\t\tSwitchInstruction ReplaceWithSwitchInstruction(int offset)\n\t\t\t{\n\t\t\t\tvar defaultLabel = new LongSet(new LongInterval(0, stringValues.Count)).Invert();\n\t\t\t\tvar values = new string[stringValues.Count];\n\t\t\t\tvar sections = new SwitchSection[stringValues.Count];\n\t\t\t\tforeach (var (idx, (value, bodyInstruction)) in stringValues.WithIndex())\n\t\t\t\t{\n\t\t\t\t\tvalues[idx] = value;\n\t\t\t\t\tvar body = bodyInstruction is Block b ? new Branch(b) : bodyInstruction;\n\t\t\t\t\tsections[idx] = new SwitchSection { Labels = new LongSet(idx), Body = body };\n\t\t\t\t}\n\t\t\t\tvar newSwitch = new SwitchInstruction(new StringToInt(switchValueInst, values, switchValueLoad.Variable.Type));\n\t\t\t\tnewSwitch.Sections.AddRange(sections);\n\t\t\t\tnewSwitch.Sections.Add(new SwitchSection { Labels = defaultLabel, Body = defaultSection.Body });\n\t\t\t\tinstructions[offset].ReplaceWith(newSwitch);\n\t\t\t\treturn newSwitch;\n\t\t\t}\n\t\t}\n\n\t\tprivate bool MatchRoslynSwitchOnStringUsingLengthAndChar(Block block, int i)\n\t\t{\n\t\t\tvar instructions = block.Instructions;\n\t\t\t// implements https://github.com/dotnet/roslyn/pull/66081\n\t\t\t// if (comp(ldloc switchValueVar == ldnull)) br nullCase\n\t\t\t// br nextBlock\n\t\t\tBlock switchOnLengthBlock;\n\t\t\tint switchOnLengthBlockStartOffset;\n\t\t\tBlock nullCase = null;\n\t\t\tif (instructions[i].MatchIfInstruction(out var condition, out var exitBlockJump)\n\t\t\t\t&& condition.MatchCompEqualsNull(out var ldloc)\n\t\t\t\t&& ldloc is LdLoc { Variable: var switchValueVar })\n\t\t\t{\n\t\t\t\tif (!instructions[i + 1].MatchBranch(out var nextBlock))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!exitBlockJump.MatchBranch(out nullCase) && !exitBlockJump.MatchLeave(out _))\n\t\t\t\t\treturn false;\n\t\t\t\t// if (comp(ldloc switchValueVar == ldnull)) br ...\n\t\t\t\t// br switchOnLengthBlock\n\t\t\t\tif (nextBlock.IncomingEdgeCount == 1\n\t\t\t\t\t&& nextBlock.Instructions[0].MatchIfInstruction(out condition, out _)\n\t\t\t\t\t&& condition.MatchCompEqualsNull(out ldloc)\n\t\t\t\t\t&& ldloc.MatchLdLoc(switchValueVar))\n\t\t\t\t{\n\t\t\t\t\tif (!nextBlock.Instructions[1].MatchBranch(out switchOnLengthBlock))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tswitchOnLengthBlock = nextBlock;\n\t\t\t\t}\n\t\t\t\tif (switchOnLengthBlock.IncomingEdgeCount != 1)\n\t\t\t\t\treturn false;\n\t\t\t\tswitchOnLengthBlockStartOffset = 0;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tswitchOnLengthBlock = block;\n\t\t\t\tswitchValueVar = null; // will be extracted in MatchSwitchOnLengthBlock\n\t\t\t\tswitchOnLengthBlockStartOffset = i;\n\t\t\t}\n\t\t\tILInstruction defaultCase = null;\n\t\t\tif (!MatchSwitchOnLengthBlock(ref switchValueVar, switchOnLengthBlock, switchOnLengthBlockStartOffset, out var blocksByLength))\n\t\t\t\treturn false;\n\t\t\tList<(string, ILInstruction)> stringValues = new();\n\t\t\tforeach (var b in blocksByLength)\n\t\t\t{\n\t\t\t\tif (b.Length.Count() != 1)\n\t\t\t\t{\n\t\t\t\t\tif (b.TargetBlock != nullCase)\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tint length = (int)b.Length.Intervals[0].Start;\n\t\t\t\t\tswitch (b.TargetBlock)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase Leave leave:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase Block targetBlock:\n\t\t\t\t\t\t\tif (MatchSwitchOnCharBlock(targetBlock, length, switchValueVar, out var mapping))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tforeach (var item in mapping)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif (!stringValues.Any(x => x.Item1 == item.StringValue))\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tstringValues.Add(item);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (MatchRoslynCaseBlockHead(targetBlock, switchValueVar, out var bodyOrLeave, out var exit, out string stringValue, out _))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (exit != defaultCase)\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\tif (!stringValues.Any(x => x.Item1 == stringValue))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tstringValues.Add((stringValue, bodyOrLeave));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (length == 0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstringValues.Add((\"\", b.TargetBlock));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!stringValues.Any(pair => pair.Item1 == null))\n\t\t\t{\n\t\t\t\tif (IsNullCheckInDefaultBlock(ref defaultCase, switchValueVar, out var nullBlock))\n\t\t\t\t{\n\t\t\t\t\tstringValues.Add((null, nullBlock));\n\t\t\t\t}\n\t\t\t\telse if (nullCase != null && nullCase != defaultCase)\n\t\t\t\t{\n\t\t\t\t\tstringValues.Add((null, nullCase));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcontext.Step(nameof(MatchRoslynSwitchOnStringUsingLengthAndChar), instructions[i]);\n\t\t\tvar defaultLabel = new LongSet(new LongInterval(0, stringValues.Count)).Invert();\n\t\t\tvar values = new string[stringValues.Count];\n\t\t\tvar sections = new SwitchSection[stringValues.Count];\n\t\t\tforeach (var (idx, (value, bodyInstruction)) in stringValues.WithIndex())\n\t\t\t{\n\t\t\t\tvalues[idx] = value;\n\t\t\t\tvar body = bodyInstruction is Block b ? new Branch(b) : bodyInstruction;\n\t\t\t\tsections[idx] = new SwitchSection { Labels = new LongSet(idx), Body = body };\n\t\t\t}\n\t\t\tvar newSwitch = new SwitchInstruction(new StringToInt(new LdLoc(switchValueVar), values, switchValueVar.Type));\n\t\t\tnewSwitch.Sections.AddRange(sections);\n\t\t\tnewSwitch.Sections.Add(new SwitchSection { Labels = defaultLabel, Body = defaultCase is Block b2 ? new Branch(b2) : defaultCase });\n\t\t\tnewSwitch.AddILRange(instructions[i]);\n\t\t\tif (nullCase != null)\n\t\t\t{\n\t\t\t\tnewSwitch.AddILRange(instructions[i + 1]);\n\t\t\t}\n\t\t\tinstructions[i] = newSwitch;\n\t\t\tinstructions.RemoveRange(i + 1, instructions.Count - (i + 1));\n\t\t\treturn true;\n\n\t\t\tbool MatchGetChars(ILInstruction instruction, ILVariable switchValueVar, out int index)\n\t\t\t{\n\t\t\t\tindex = -1;\n\t\t\t\tif (context.Settings.SwitchOnReadOnlySpanChar && instruction.MatchLdObj(out var target, out var type) && type.IsKnownType(KnownTypeCode.UInt16))\n\t\t\t\t{\n\t\t\t\t\treturn target is Call call\n\t\t\t\t\t\t&& (call.Method.FullNameIs(\"System.ReadOnlySpan\", \"get_Item\")\n\t\t\t\t\t\t|| call.Method.FullNameIs(\"System.Span\", \"get_Item\"))\n\t\t\t\t\t\t&& call.Arguments.Count == 2\n\t\t\t\t\t\t&& call.Arguments[0].MatchLdLoca(switchValueVar)\n\t\t\t\t\t\t&& call.Arguments[1].MatchLdcI4(out index);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn instruction is Call call\n\t\t\t\t\t\t&& call.Method.FullNameIs(\"System.String\", \"get_Chars\")\n\t\t\t\t\t\t&& call.Arguments.Count == 2\n\t\t\t\t\t\t&& call.Arguments[0].MatchLdLoc(switchValueVar)\n\t\t\t\t\t\t&& call.Arguments[1].MatchLdcI4(out index);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool MatchSwitchOnCharBlock(Block block, int length, ILVariable switchValueVar, out List<(string StringValue, ILInstruction BodyOrLeave)> results)\n\t\t\t{\n\t\t\t\tresults = null;\n\t\t\t\tif (block.IncomingEdgeCount != 1)\n\t\t\t\t\treturn false;\n\t\t\t\tSwitchInstruction @switch;\n\t\t\t\tList<KeyValuePair<LongSet, ILInstruction>> sections;\n\t\t\t\tint index;\n\t\t\t\tswitch (block.Instructions.Count)\n\t\t\t\t{\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\t@switch = block.Instructions[0] as SwitchInstruction;\n\t\t\t\t\t\tif (@switch == null)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!MatchGetChars(@switch.Value, switchValueVar, out index))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tsections = @switch.Sections.SelectList(s => new KeyValuePair<LongSet, ILInstruction>(s.Labels, s.Body));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tif (!block.Instructions[0].MatchStLoc(out var charTempVar, out var getCharsCall))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!MatchGetChars(getCharsCall, switchValueVar, out index))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (index < 0)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t@switch = block.Instructions[1] as SwitchInstruction;\n\t\t\t\t\t\tif (@switch == null)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!@switch.Value.MatchLdLoc(charTempVar))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tsections = @switch.Sections.SelectList(s => new KeyValuePair<LongSet, ILInstruction>(s.Labels, s.Body));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif (!analysis.AnalyzeBlock(block))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!block.Instructions[0].MatchStLoc(out charTempVar, out getCharsCall))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!MatchGetChars(getCharsCall, switchValueVar, out index))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (index < 0)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (analysis.SwitchVariable != charTempVar)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tsections = analysis.Sections;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (index >= length)\n\t\t\t\t\treturn false;\n\t\t\t\tbool hasDefaultSection = false;\n\t\t\t\tforeach (var (labels, body) in sections)\n\t\t\t\t{\n\t\t\t\t\tif (labels.Count() == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tchar ch = unchecked((char)labels.Values.Single());\n\t\t\t\t\t\tif (!body.MatchBranch(out var targetBlock))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (length == 1)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tresults ??= new();\n\t\t\t\t\t\t\tresults.Add((ch.ToString(), targetBlock));\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\twhile (MatchRoslynCaseBlockHead(targetBlock, switchValueVar, out var bodyOrLeave, out var exit, out var stringValue, out _))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (stringValue.Length != length || stringValue[index] != ch)\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\tresults ??= new();\n\t\t\t\t\t\t\t\tresults.Add((stringValue, bodyOrLeave));\n\t\t\t\t\t\t\t\tif (exit == nullCase)\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\ttargetBlock = exit;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (!hasDefaultSection)\n\t\t\t\t\t{\n\t\t\t\t\t\thasDefaultSection = true;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn results?.Count > 0;\n\t\t\t}\n\n\t\t\tbool MatchSwitchOnLengthBlock(ref ILVariable switchValueVar, Block switchOnLengthBlock, int startOffset, out List<(LongSet Length, ILInstruction TargetBlock)> blocks)\n\t\t\t{\n\t\t\t\tblocks = null;\n\t\t\t\tSwitchInstruction @switch;\n\t\t\t\tILInstruction getLengthCall;\n\t\t\t\tILVariable lengthVar;\n\t\t\t\tswitch (switchOnLengthBlock.Instructions.Count - startOffset)\n\t\t\t\t{\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\t@switch = switchOnLengthBlock.Instructions[startOffset] as SwitchInstruction;\n\t\t\t\t\t\tif (@switch == null)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tgetLengthCall = @switch.Value;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tif (!switchOnLengthBlock.Instructions[startOffset].MatchStLoc(out lengthVar, out getLengthCall))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t@switch = switchOnLengthBlock.Instructions[startOffset + 1] as SwitchInstruction;\n\t\t\t\t\t\tif (@switch == null)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!@switch.Value.MatchLdLoc(lengthVar))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\t@switch = null;\n\t\t\t\t\t\tif (!switchOnLengthBlock.Instructions[startOffset].MatchStLoc(out lengthVar, out getLengthCall))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!switchOnLengthBlock.Instructions[startOffset + 1].MatchIfInstruction(out var cond, out var gotoLength))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!gotoLength.MatchBranch(out var target))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!switchOnLengthBlock.Instructions[startOffset + 2].MatchBranch(out var gotoElse))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!cond.MatchCompEquals(out var lhs, out var rhs))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!cond.MatchCompNotEquals(out lhs, out rhs))\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\tvar t = target;\n\t\t\t\t\t\t\ttarget = gotoElse;\n\t\t\t\t\t\t\tgotoElse = t;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefaultCase = gotoElse;\n\t\t\t\t\t\tif (!lhs.MatchLdLoc(lengthVar) || !rhs.MatchLdcI4(out int length))\n\t\t\t\t\t\t\treturn false;\n\n\t\t\t\t\t\tblocks = new() {\n\t\t\t\t\t\t\t(new LongSet(length), target),\n\t\t\t\t\t\t\t(new LongSet(length).Invert(), defaultCase)\n\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (getLengthCall is not Call call\n\t\t\t\t\t|| call.Arguments.Count != 1\n\t\t\t\t\t|| call.Method.Name != \"get_Length\")\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tvar declaringTypeCode = call.Method.DeclaringTypeDefinition?.KnownTypeCode;\n\t\t\t\tswitch (declaringTypeCode)\n\t\t\t\t{\n\t\t\t\t\tcase KnownTypeCode.String:\n\t\t\t\t\t\tif (!call.Arguments[0].MatchLdLoc(switchValueVar))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownTypeCode.ReadOnlySpanOfT:\n\t\t\t\t\tcase KnownTypeCode.SpanOfT:\n\t\t\t\t\t\tif (!context.Settings.SwitchOnReadOnlySpanChar)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!call.Arguments[0].MatchLdLoca(out switchValueVar))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (@switch == null)\n\t\t\t\t\treturn true;\n\t\t\t\tblocks = new(@switch.Sections.Count);\n\t\t\t\tforeach (var section in @switch.Sections)\n\t\t\t\t{\n\t\t\t\t\tif (section.HasNullLabel)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!section.Body.MatchBranch(out var target) && !section.Body.MatchLeave(out _))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tILInstruction targetInst = target ?? section.Body;\n\t\t\t\t\tif (section.Labels.Count() != 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tdefaultCase ??= targetInst;\n\t\t\t\t\t\tif (defaultCase != targetInst)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tblocks.Add((section.Labels, targetInst));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches:\n\t\t/// Block oldDefaultBlock (incoming: 1) {\n\t\t///     if (comp.o(ldloc switchVar == ldnull)) br nullValueCaseBlock\n\t\t///\t    br newDefaultBlock\n\t\t/// }\n\t\t/// </summary>\n\t\tprivate bool IsNullCheckInDefaultBlock(ref ILInstruction exitOrDefault, ILVariable switchVar, out Block nullValueCaseBlock)\n\t\t{\n\t\t\tnullValueCaseBlock = null;\n\t\t\tif (exitOrDefault is not Block exitOrDefaultBlock)\n\t\t\t\treturn false;\n\t\t\tif (!exitOrDefaultBlock.Instructions[0].MatchIfInstruction(out var condition, out var thenBranch))\n\t\t\t\treturn false;\n\t\t\tif (!(condition.MatchCompEqualsNull(out var arg) && arg.MatchLdLoc(switchVar)))\n\t\t\t\treturn false;\n\t\t\tif (!thenBranch.MatchBranch(out nullValueCaseBlock))\n\t\t\t\treturn false;\n\t\t\tif (nullValueCaseBlock.Parent != exitOrDefaultBlock.Parent)\n\t\t\t\treturn false;\n\t\t\tif (!exitOrDefaultBlock.Instructions[1].MatchBranch(out var elseBlock))\n\t\t\t\treturn false;\n\t\t\tif (elseBlock.Parent != exitOrDefaultBlock.Parent)\n\t\t\t\treturn false;\n\t\t\texitOrDefault = elseBlock;\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches (and the negated version):\n\t\t/// if (call op_Equality(ldloc switchValueVar, stringValue)) br body\n\t\t/// br exit\n\t\t/// </summary>\n\t\tbool MatchRoslynCaseBlockHead(Block target, ILVariable switchValueVar, out ILInstruction bodyOrLeave, out Block defaultOrExitBlock, out string stringValue, out bool emptyStringEqualsNull)\n\t\t{\n\t\t\tbodyOrLeave = null;\n\t\t\tdefaultOrExitBlock = null;\n\t\t\tstringValue = null;\n\t\t\temptyStringEqualsNull = false;\n\t\t\tif (target.Instructions.Count != 2)\n\t\t\t\treturn false;\n\t\t\tif (!target.Instructions[0].MatchIfInstruction(out var condition, out var bodyBranch))\n\t\t\t{\n\t\t\t\t// Special case: sometimes we don't have an if, because bodyBranch==exitBranch\n\t\t\t\t// and the C# compiler optimized out the if.\n\t\t\t\t// Example:\n\t\t\t\t//  Block IL_0063 (incoming: 1) {\n\t\t\t\t//   call op_Equality(ldloc V_4, ldstr \"rowno\")\n\t\t\t\t//   leave IL_0000(nop)\n\t\t\t\t// }\n\t\t\t\tcondition = target.Instructions[0];\n\t\t\t\tbodyBranch = target.Instructions[1];\n\t\t\t}\n\t\t\tILInstruction exitBranch = target.Instructions[1];\n\t\t\t// Handle negated conditions first:\n\t\t\twhile (condition.MatchLogicNot(out var expr))\n\t\t\t{\n\t\t\t\tExtensionMethods.Swap(ref exitBranch, ref bodyBranch);\n\t\t\t\tcondition = expr;\n\t\t\t}\n\t\t\tif (!MatchStringEqualityComparison(condition, switchValueVar, out stringValue, out bool isVBCompareString))\n\t\t\t\treturn false;\n\t\t\tif (isVBCompareString)\n\t\t\t{\n\t\t\t\tExtensionMethods.Swap(ref exitBranch, ref bodyBranch);\n\t\t\t\temptyStringEqualsNull = true;\n\t\t\t}\n\t\t\tif (!(exitBranch.MatchBranch(out defaultOrExitBlock) || exitBranch.MatchLeave(out _)))\n\t\t\t\treturn false;\n\t\t\tif (bodyBranch.MatchLeave(out _))\n\t\t\t{\n\t\t\t\tbodyOrLeave = bodyBranch;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (bodyBranch.MatchBranch(out var bodyBlock))\n\t\t\t{\n\t\t\t\tbodyOrLeave = bodyBlock;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Block target(incoming: 1) {\n\t\t/// \tif (comp.o(ldloc switchValueVar == ldnull)) br exit\n\t\t/// \tbr lengthCheckBlock\n\t\t/// }\n\t\t/// \n\t\t/// Block lengthCheckBlock(incoming: 1) {\n\t\t/// \tif (logic.not(call get_Length(ldloc switchValueVar))) br body\n\t\t/// \tbr exit\n\t\t/// }\n\t\t/// </summary>\n\t\tbool MatchRoslynEmptyStringCaseBlockHead(Block target, ILVariable switchValueVar, out ILInstruction bodyOrLeave, out Block defaultOrExitBlock)\n\t\t{\n\t\t\tbodyOrLeave = null;\n\t\t\tdefaultOrExitBlock = null;\n\t\t\tif (target.Instructions.Count != 2 || target.IncomingEdgeCount != 1)\n\t\t\t\treturn false;\n\t\t\tif (!target.Instructions[0].MatchIfInstruction(out var nullComparisonCondition, out var exitBranch))\n\t\t\t\treturn false;\n\t\t\tif (!nullComparisonCondition.MatchCompEqualsNull(out var arg) || !arg.MatchLdLoc(switchValueVar))\n\t\t\t\treturn false;\n\t\t\tif (!target.Instructions[1].MatchBranch(out Block lengthCheckBlock))\n\t\t\t\treturn false;\n\t\t\tif (lengthCheckBlock.Instructions.Count != 2 || lengthCheckBlock.IncomingEdgeCount != 1)\n\t\t\t\treturn false;\n\t\t\tif (!lengthCheckBlock.Instructions[0].MatchIfInstruction(out var lengthCheckCondition, out var exitBranch2))\n\t\t\t\treturn false;\n\t\t\tILInstruction bodyBranch;\n\t\t\tif (lengthCheckCondition.MatchLogicNot(out arg))\n\t\t\t{\n\t\t\t\tbodyBranch = exitBranch2;\n\t\t\t\texitBranch2 = lengthCheckBlock.Instructions[1];\n\t\t\t\tlengthCheckCondition = arg;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbodyBranch = lengthCheckBlock.Instructions[1];\n\t\t\t}\n\t\t\tif (!(exitBranch2.MatchBranch(out defaultOrExitBlock) || exitBranch2.MatchLeave(out _)))\n\t\t\t\treturn false;\n\t\t\tif (!MatchStringLengthCall(lengthCheckCondition, switchValueVar))\n\t\t\t\treturn false;\n\t\t\tif (!exitBranch.Match(exitBranch2).Success)\n\t\t\t\treturn false;\n\t\t\tif (bodyBranch.MatchLeave(out _))\n\t\t\t{\n\t\t\t\tbodyOrLeave = bodyBranch;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (bodyBranch.MatchBranch(out var bodyBlock))\n\t\t\t{\n\t\t\t\tbodyOrLeave = bodyBlock;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// call get_Length(ldloc switchValueVar)\n\t\t/// </summary>\n\t\tbool MatchStringLengthCall(ILInstruction inst, ILVariable switchValueVar)\n\t\t{\n\t\t\treturn inst is Call call\n\t\t\t\t&& call.Method.DeclaringType.IsKnownType(KnownTypeCode.String)\n\t\t\t\t&& call.Method.IsAccessor\n\t\t\t\t&& call.Method.AccessorKind == System.Reflection.MethodSemanticsAttributes.Getter\n\t\t\t\t&& call.Method.AccessorOwner.Name == \"Length\"\n\t\t\t\t&& call.Arguments.Count == 1\n\t\t\t\t&& call.Arguments[0].MatchLdLoc(switchValueVar);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches\n\t\t/// 'stloc(targetVar, call ComputeStringHash(ldloc switchValue))'\n\t\t/// - or -\n\t\t/// 'stloc(targetVar, call ComputeSpanHash(ldloc switchValue))'\n\t\t/// - or -\n\t\t/// 'stloc(targetVar, call ComputeReadOnlySpanHash(ldloc switchValue))'\n\t\t/// </summary>\n\t\tinternal static bool MatchComputeStringOrReadOnlySpanHashCall(ILInstruction inst, ILVariable targetVar, out LdLoc switchValue)\n\t\t{\n\t\t\tswitchValue = null;\n\t\t\tif (!inst.MatchStLoc(targetVar, out var value))\n\t\t\t\treturn false;\n\t\t\tif (value is Call c && c.Arguments.Count == 1\n\t\t\t\t&& c.Method.Name is \"ComputeStringHash\" or \"ComputeSpanHash\" or \"ComputeReadOnlySpanHash\"\n\t\t\t\t&& c.Method.IsCompilerGeneratedOrIsInCompilerGeneratedClass())\n\t\t\t{\n\t\t\t\tif (c.Arguments[0] is not LdLoc ldloc)\n\t\t\t\t\treturn false;\n\t\t\t\tswitchValue = ldloc;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches 'call string.op_Equality(ldloc(variable), ldstr stringValue)'\n\t\t///      or 'comp(ldloc(variable) == ldnull)'\n\t\t///      or 'call SequenceEqual(ldloc variable, call AsSpan(ldstr stringValue))'\n\t\t/// </summary>\n\t\tbool MatchStringEqualityComparison(ILInstruction condition, ILVariable variable, out string stringValue, out bool isVBCompareString)\n\t\t{\n\t\t\treturn MatchStringEqualityComparison(condition, out var v, out stringValue, out isVBCompareString) && v == variable;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches 'call string.op_Equality(ldloc(variable), ldstr stringValue)'\n\t\t///      or 'comp(ldloc(variable) == ldnull)'\n\t\t///      or 'call SequenceEqual(ldloc variable, call AsSpan(ldstr stringValue))'\n\t\t/// </summary>\n\t\tbool MatchStringEqualityComparison(ILInstruction condition, out ILVariable variable, out string stringValue, out bool isVBCompareString)\n\t\t{\n\t\t\tstringValue = null;\n\t\t\tvariable = null;\n\t\t\tisVBCompareString = false;\n\t\t\twhile (condition is Comp comp && comp.Kind == ComparisonKind.Inequality && comp.Right.MatchLdcI4(0))\n\t\t\t{\n\t\t\t\t// if (x != 0) == if (x)\n\t\t\t\tcondition = comp.Left;\n\t\t\t}\n\t\t\tif (condition is Call c)\n\t\t\t{\n\t\t\t\tILInstruction left, right;\n\t\t\t\tif (c.Method.IsOperator && c.Method.Name == \"op_Equality\"\n\t\t\t\t\t&& c.Method.DeclaringType.IsKnownType(KnownTypeCode.String) && c.Arguments.Count == 2)\n\t\t\t\t{\n\t\t\t\t\tleft = c.Arguments[0];\n\t\t\t\t\tright = c.Arguments[1];\n\t\t\t\t}\n\t\t\t\telse if (c.Method.IsStatic && c.Method.Name == \"CompareString\"\n\t\t\t\t\t&& c.Method.DeclaringType.FullName == \"Microsoft.VisualBasic.CompilerServices.Operators\"\n\t\t\t\t\t&& c.Arguments.Count == 3)\n\t\t\t\t{\n\t\t\t\t\tleft = c.Arguments[0];\n\t\t\t\t\tright = c.Arguments[1];\n\t\t\t\t\t// VB CompareString(): return 0 on equality -> condition is effectively negated.\n\t\t\t\t\t// Also, the empty string is considered equal to null.\n\t\t\t\t\tisVBCompareString = true;\n\t\t\t\t\tif (!c.Arguments[2].MatchLdcI4(0))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Option Compare Text: case insensitive comparison is not supported in C#\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (c.Method.IsStatic && c.Method.Name == \"SequenceEqual\"\n\t\t\t\t\t&& c.Method.DeclaringType.FullName == \"System.MemoryExtensions\"\n\t\t\t\t\t&& c.Arguments.Count == 2)\n\t\t\t\t{\n\t\t\t\t\tleft = c.Arguments[0];\n\t\t\t\t\tif (c.Arguments[1] is Call {\n\t\t\t\t\t\tMethod.IsStatic: true,\n\t\t\t\t\t\tMethod.Name: \"AsSpan\",\n\t\t\t\t\t\tMethod.DeclaringType.FullName: \"System.MemoryExtensions\",\n\t\t\t\t\t\tArguments: [var ldStr]\n\t\t\t\t\t} asSpanCall)\n\t\t\t\t\t{\n\t\t\t\t\t\tright = ldStr;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn left.MatchLdLoc(out variable) && right.MatchLdStr(out stringValue);\n\t\t\t}\n\t\t\telse if (condition.MatchCompEqualsNull(out var arg))\n\t\t\t{\n\t\t\t\tstringValue = null;\n\t\t\t\treturn arg.MatchLdLoc(out variable);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/TransformArrayInitializers.cs",
    "content": "// Copyright (c) 2015 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Transforms array initialization pattern of System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray.\n\t/// For collection and object initializers see <see cref=\"TransformCollectionAndObjectInitializers\"/>\n\t/// </summary>\n\tpublic class TransformArrayInitializers : IStatementTransform\n\t{\n\t\tStatementTransformContext context;\n\n\t\tvoid IStatementTransform.Run(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.ArrayInitializers)\n\t\t\t\treturn;\n\t\t\tthis.context = context;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (DoTransform(context.Function, block, pos))\n\t\t\t\t\treturn;\n\t\t\t\tif (DoTransformMultiDim(context.Function, block, pos))\n\t\t\t\t\treturn;\n\t\t\t\tif (context.Settings.StackAllocInitializers && DoTransformStackAllocInitializer(block, pos))\n\t\t\t\t\treturn;\n\t\t\t\tif (DoTransformInlineRuntimeHelpersInitializeArray(block, pos))\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tthis.context = null;\n\t\t\t}\n\t\t}\n\n\t\tbool DoTransform(ILFunction function, Block body, int pos)\n\t\t{\n\t\t\tif (pos >= body.Instructions.Count - 2)\n\t\t\t\treturn false;\n\t\t\tILInstruction inst = body.Instructions[pos];\n\t\t\tif (inst.MatchStLoc(out var v, out var newarrExpr) && MatchNewArr(newarrExpr, out var elementType, out var arrayLength))\n\t\t\t{\n\t\t\t\tif (HandleRuntimeHelpersInitializeArray(body, pos + 1, v, elementType, arrayLength, out var values, out var initArrayPos))\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"HandleRuntimeHelperInitializeArray: single-dim\", inst);\n\t\t\t\t\tvar tempStore = context.Function.RegisterVariable(VariableKind.InitializerTarget, v.Type);\n\t\t\t\t\tvar block = BlockFromInitializer(tempStore, elementType, arrayLength, values);\n\t\t\t\t\tbody.Instructions[pos] = new StLoc(v, block);\n\t\t\t\t\tbody.Instructions.RemoveAt(initArrayPos);\n\t\t\t\t\tILInlining.InlineIfPossible(body, pos, context);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (arrayLength.Length == 1)\n\t\t\t\t{\n\t\t\t\t\tif (HandleSimpleArrayInitializer(function, body, pos + 1, v, arrayLength, out var arrayValues, out var instructionsToRemove))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontext.Step(\"HandleSimpleArrayInitializer: single-dim\", inst);\n\t\t\t\t\t\tvar block = new Block(BlockKind.ArrayInitializer);\n\t\t\t\t\t\tvar tempStore = context.Function.RegisterVariable(VariableKind.InitializerTarget, v.Type);\n\t\t\t\t\t\tblock.Instructions.Add(new StLoc(tempStore, new NewArr(elementType, arrayLength.Select(l => new LdcI4(l)).ToArray())));\n\t\t\t\t\t\tblock.Instructions.AddRange(arrayValues.Select(\n\t\t\t\t\t\t\tt => {\n\t\t\t\t\t\t\t\tvar (indices, value) = t;\n\t\t\t\t\t\t\t\tif (value == null)\n\t\t\t\t\t\t\t\t\tvalue = GetNullExpression(elementType);\n\t\t\t\t\t\t\t\treturn StElem(new LdLoc(tempStore), indices, value, elementType);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t));\n\t\t\t\t\t\tblock.FinalInstruction = new LdLoc(tempStore);\n\t\t\t\t\t\tbody.Instructions[pos] = new StLoc(v, block);\n\t\t\t\t\t\tbody.Instructions.RemoveRange(pos + 1, instructionsToRemove);\n\t\t\t\t\t\tILInlining.InlineIfPossible(body, pos, context);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tif (HandleJaggedArrayInitializer(body, pos + 1, v, elementType, arrayLength[0], out ILVariable finalStore, out values, out instructionsToRemove))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontext.Step(\"HandleJaggedArrayInitializer: single-dim\", inst);\n\t\t\t\t\t\tvar block = new Block(BlockKind.ArrayInitializer);\n\t\t\t\t\t\tvar tempStore = context.Function.RegisterVariable(VariableKind.InitializerTarget, v.Type);\n\t\t\t\t\t\tblock.Instructions.Add(new StLoc(tempStore, new NewArr(elementType, arrayLength.Select(l => new LdcI4(l)).ToArray())));\n\t\t\t\t\t\tblock.Instructions.AddRange(values.SelectWithIndex((i, value) => StElem(new LdLoc(tempStore), new[] { new LdcI4(i) }, value, elementType)));\n\t\t\t\t\t\tblock.FinalInstruction = new LdLoc(tempStore);\n\t\t\t\t\t\tbody.Instructions[pos] = new StLoc(finalStore, block);\n\t\t\t\t\t\tbody.Instructions.RemoveRange(pos + 1, instructionsToRemove);\n\t\t\t\t\t\tILInlining.InlineIfPossible(body, pos, context);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tinternal static bool TransformSpanTArrayInitialization(NewObj inst, StatementTransformContext context, out ILInstruction replacement)\n\t\t{\n\t\t\treplacement = null;\n\t\t\tif (!context.Settings.ArrayInitializers)\n\t\t\t\treturn false;\n\t\t\tif (!MatchSpanTCtorWithPointerAndSize(inst, context, out var elementType, out var field, out var size))\n\t\t\t\treturn false;\n\t\t\tif (!field.HasFlag(System.Reflection.FieldAttributes.HasFieldRVA))\n\t\t\t\treturn false;\n\t\t\tvar initialValue = field.GetInitialValue(context.PEFile, context.TypeSystem);\n\t\t\treplacement = DecodeArrayInitializerOrUTF8StringLiteral(context, elementType, initialValue, size);\n\t\t\treturn replacement != null;\n\t\t}\n\n\t\tinternal static bool TransformRuntimeHelpersCreateSpanInitialization(Call inst, StatementTransformContext context, out ILInstruction replacement)\n\t\t{\n\t\t\treplacement = null;\n\t\t\tif (!context.Settings.ArrayInitializers)\n\t\t\t\treturn false;\n\t\t\tif (!MatchRuntimeHelpersCreateSpan(inst, context, out var elementType, out var field))\n\t\t\t\treturn false;\n\t\t\tif (!field.HasFlag(System.Reflection.FieldAttributes.HasFieldRVA))\n\t\t\t\treturn false;\n\t\t\tif (IsSubPatternOfCpblkInitializer(inst))\n\t\t\t\treturn false;\n\t\t\tvar initialValue = field.GetInitialValue(context.PEFile, context.TypeSystem);\n\t\t\tvar elementTypeSize = elementType.GetSize();\n\t\t\tif (elementTypeSize <= 0 || initialValue.Length % elementTypeSize != 0)\n\t\t\t\treturn false;\n\t\t\tvar size = initialValue.Length / elementTypeSize;\n\t\t\treplacement = DecodeArrayInitializerOrUTF8StringLiteral(context, elementType, initialValue, size);\n\t\t\treturn replacement != null;\n\t\t}\n\n\t\tprivate static bool IsSubPatternOfCpblkInitializer(Call inst)\n\t\t{\n\t\t\tif (inst.Parent is not AddressOf { Parent: Call { Parent: Cpblk cpblk } get_Item })\n\t\t\t\treturn false;\n\t\t\treturn MatchGetStaticFieldAddress(get_Item, out _);\n\t\t}\n\n\t\tprivate static ILInstruction DecodeArrayInitializerOrUTF8StringLiteral(StatementTransformContext context, IType elementType, BlobReader initialValue, int size)\n\t\t{\n\t\t\tif (context.Settings.Utf8StringLiterals && elementType.IsKnownType(KnownTypeCode.Byte)\n\t\t\t\t&& DecodeUTF8String(initialValue, size, out string text))\n\t\t\t{\n\t\t\t\treturn new LdStrUtf8(text);\n\t\t\t}\n\t\t\tvar valuesList = new List<ILInstruction>();\n\t\t\tif (DecodeArrayInitializer(elementType, initialValue, new[] { size }, valuesList))\n\t\t\t{\n\t\t\t\tvar tempStore = context.Function.RegisterVariable(VariableKind.InitializerTarget, new ArrayType(context.TypeSystem, elementType));\n\t\t\t\treturn BlockFromInitializer(tempStore, elementType, new[] { size }, valuesList.ToArray());\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tprivate static unsafe bool DecodeUTF8String(BlobReader blob, int size, out string text)\n\t\t{\n\t\t\tif (size > blob.RemainingBytes)\n\t\t\t{\n\t\t\t\ttext = null;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tfor (int i = 0; i < size; i++)\n\t\t\t{\n\t\t\t\tbyte val = blob.CurrentPointer[i];\n\t\t\t\tif (val == 0 && i == size - 1 && size > 1)\n\t\t\t\t{\n\t\t\t\t\t// Allow explicit null-termination character.\n\t\t\t\t}\n\t\t\t\telse if (val < 0x20 && val is not ((byte)'\\r' or (byte)'\\n' or (byte)'\\t'))\n\t\t\t\t{\n\t\t\t\t\t// If the string has control characters, it's probably binary data and not a string.\n\t\t\t\t\ttext = null;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\ttext = Encoding.UTF8.GetString(blob.CurrentPointer, size);\n\t\t\t// Only use UTF8 string literal if we can perfectly roundtrip the data\n\t\t\tbyte[] bytes = Encoding.UTF8.GetBytes(text);\n\t\t\treturn MemoryExtensions.SequenceEqual(bytes, new ReadOnlySpan<byte>(blob.CurrentPointer, size));\n\t\t}\n\n\t\tstatic bool MatchSpanTCtorWithPointerAndSize(NewObj newObj, StatementTransformContext context, out IType elementType, out FieldDefinition field, out int size)\n\t\t{\n\t\t\tfield = default;\n\t\t\tsize = default;\n\t\t\telementType = null;\n\t\t\tIType type = newObj.Method.DeclaringType;\n\t\t\tif (!type.IsKnownType(KnownTypeCode.ReadOnlySpanOfT))\n\t\t\t\treturn false;\n\t\t\tif (newObj.Arguments.Count != 2 || type.TypeArguments.Count != 1)\n\t\t\t\treturn false;\n\t\t\telementType = type.TypeArguments[0];\n\t\t\tif (!newObj.Arguments[0].UnwrapConv(ConversionKind.StopGCTracking).MatchLdsFlda(out var member))\n\t\t\t\treturn false;\n\t\t\tif (member.MetadataToken.IsNil)\n\t\t\t\treturn false;\n\t\t\tif (!newObj.Arguments[1].MatchLdcI4(out size))\n\t\t\t\treturn false;\n\t\t\tfield = context.PEFile.Metadata.GetFieldDefinition((FieldDefinitionHandle)member.MetadataToken);\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic bool MatchRuntimeHelpersCreateSpan(Call inst, StatementTransformContext context, out IType elementType, out FieldDefinition field)\n\t\t{\n\t\t\tfield = default;\n\t\t\telementType = null;\n\t\t\tif (!IsRuntimeHelpers(inst.Method.DeclaringType))\n\t\t\t\treturn false;\n\t\t\tif (inst.Arguments.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (inst.Method is not { Name: \"CreateSpan\", TypeArguments: [var type] })\n\t\t\t\treturn false;\n\t\t\telementType = type;\n\t\t\tif (!inst.Arguments[0].UnwrapConv(ConversionKind.StopGCTracking).MatchLdMemberToken(out var member))\n\t\t\t\treturn false;\n\t\t\tif (member.MetadataToken.IsNil)\n\t\t\t\treturn false;\n\t\t\tfield = context.PEFile.Metadata.GetFieldDefinition((FieldDefinitionHandle)member.MetadataToken);\n\t\t\treturn true;\n\t\t}\n\n\t\tbool DoTransformMultiDim(ILFunction function, Block body, int pos)\n\t\t{\n\t\t\tif (pos >= body.Instructions.Count - 2)\n\t\t\t\treturn false;\n\t\t\tILInstruction inst = body.Instructions[pos];\n\t\t\tif (inst.MatchStLoc(out var v, out var newarrExpr) && MatchNewArr(newarrExpr, out var elementType, out var length))\n\t\t\t{\n\t\t\t\tif (HandleRuntimeHelpersInitializeArray(body, pos + 1, v, elementType, length, out var values, out var initArrayPos))\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"HandleRuntimeHelpersInitializeArray: multi-dim\", inst);\n\t\t\t\t\tvar block = BlockFromInitializer(v, elementType, length, values);\n\t\t\t\t\tbody.Instructions[pos].ReplaceWith(new StLoc(v, block));\n\t\t\t\t\tbody.Instructions.RemoveAt(initArrayPos);\n\t\t\t\t\tILInlining.InlineIfPossible(body, pos, context);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (HandleSimpleArrayInitializer(function, body, pos + 1, v, length, out var arrayValues, out var instructionsToRemove))\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"HandleSimpleArrayInitializer: multi-dim\", inst);\n\t\t\t\t\tvar block = new Block(BlockKind.ArrayInitializer);\n\t\t\t\t\tvar tempStore = context.Function.RegisterVariable(VariableKind.InitializerTarget, v.Type);\n\t\t\t\t\tblock.Instructions.Add(new StLoc(tempStore, new NewArr(elementType, length.Select(l => new LdcI4(l)).ToArray())));\n\t\t\t\t\tblock.Instructions.AddRange(arrayValues.Select(\n\t\t\t\t\t\tt => {\n\t\t\t\t\t\t\tvar (indices, value) = t;\n\t\t\t\t\t\t\tif (value == null)\n\t\t\t\t\t\t\t\tvalue = GetNullExpression(elementType);\n\t\t\t\t\t\t\treturn StElem(new LdLoc(tempStore), indices, value, elementType);\n\t\t\t\t\t\t}\n\t\t\t\t\t));\n\t\t\t\t\tblock.FinalInstruction = new LdLoc(tempStore);\n\t\t\t\t\tbody.Instructions[pos] = new StLoc(v, block);\n\t\t\t\t\tbody.Instructions.RemoveRange(pos + 1, instructionsToRemove);\n\t\t\t\t\tILInlining.InlineIfPossible(body, pos, context);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tbool DoTransformStackAllocInitializer(Block body, int pos)\n\t\t{\n\t\t\tif (pos >= body.Instructions.Count - 2)\n\t\t\t\treturn false;\n\t\t\tILInstruction inst = body.Instructions[pos];\n\t\t\tif (inst.MatchStLoc(out var v, out var locallocExpr) && locallocExpr.MatchLocAlloc(out var lengthInst))\n\t\t\t{\n\t\t\t\tif (lengthInst.MatchLdcI(out var lengthInBytes) && HandleCpblkInitializer(body, pos + 1, v, lengthInBytes, out var blob, out var elementType))\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"HandleCpblkInitializer\", inst);\n\t\t\t\t\tvar block = new Block(BlockKind.StackAllocInitializer);\n\t\t\t\t\tvar tempStore = context.Function.RegisterVariable(VariableKind.InitializerTarget, new PointerType(elementType));\n\t\t\t\t\tblock.Instructions.Add(new StLoc(tempStore, locallocExpr));\n\n\t\t\t\t\twhile (blob.RemainingBytes > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tblock.Instructions.Add(StElemPtr(tempStore, blob.Offset, ReadElement(ref blob, elementType), elementType));\n\t\t\t\t\t}\n\n\t\t\t\t\tblock.FinalInstruction = new LdLoc(tempStore);\n\t\t\t\t\tbody.Instructions[pos] = new StLoc(v, block);\n\t\t\t\t\tbody.Instructions.RemoveAt(pos + 1);\n\t\t\t\t\tILInlining.InlineIfPossible(body, pos, context);\n\t\t\t\t\tExpressionTransforms.RunOnSingleStatement(body.Instructions[pos], context);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (HandleSequentialLocAllocInitializer(body, pos + 1, v, locallocExpr, out elementType, out StObj[] values, out int instructionsToRemove))\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"HandleSequentialLocAllocInitializer\", inst);\n\t\t\t\t\tvar block = new Block(BlockKind.StackAllocInitializer);\n\t\t\t\t\tvar tempStore = context.Function.RegisterVariable(VariableKind.InitializerTarget, new PointerType(elementType));\n\t\t\t\t\tblock.Instructions.Add(new StLoc(tempStore, locallocExpr));\n\t\t\t\t\tblock.Instructions.AddRange(values.Where(value => value != null).Select(value => RewrapStore(tempStore, value, elementType)));\n\t\t\t\t\tblock.FinalInstruction = new LdLoc(tempStore);\n\t\t\t\t\tbody.Instructions[pos] = new StLoc(v, block);\n\t\t\t\t\tbody.Instructions.RemoveRange(pos + 1, instructionsToRemove);\n\t\t\t\t\tILInlining.InlineIfPossible(body, pos, context);\n\t\t\t\t\tExpressionTransforms.RunOnSingleStatement(body.Instructions[pos], context);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tprivate ILInstruction ReadElement(ref BlobReader blob, IType elementType)\n\t\t{\n\t\t\tswitch (elementType.GetSize())\n\t\t\t{\n\t\t\t\tcase 1:\n\t\t\t\t\treturn new LdcI4(blob.ReadByte());\n\t\t\t\tcase 2:\n\t\t\t\t\treturn new LdcI4(blob.ReadInt16());\n\t\t\t\tcase 4:\n\t\t\t\t\treturn new LdcI4(blob.ReadInt32());\n\t\t\t\tcase 8:\n\t\t\t\t\treturn new LdcI8(blob.ReadInt64());\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException();\n\t\t\t}\n\t\t}\n\n\t\tbool HandleCpblkInitializer(Block block, int pos, ILVariable v, long length, out BlobReader blob, out IType elementType)\n\t\t{\n\t\t\tblob = default;\n\t\t\telementType = null;\n\t\t\tif (!block.Instructions[pos].MatchCpblk(out var dest, out var src, out var size))\n\t\t\t\treturn false;\n\t\t\tif (!dest.MatchLdLoc(v) || !MatchGetStaticFieldAddress(src, out var field) || !size.MatchLdcI4((int)length))\n\t\t\t\treturn false;\n\t\t\tif (!(v.IsSingleDefinition && v.LoadCount == 2))\n\t\t\t\treturn false;\n\t\t\tif (field.MetadataToken.IsNil)\n\t\t\t\treturn false;\n\t\t\tif (!block.Instructions[pos + 1].MatchStLoc(out var finalStore, out var value))\n\t\t\t{\n\t\t\t\tvar otherLoadOfV = v.LoadInstructions.FirstOrDefault(l => !(l.Parent is Cpblk));\n\t\t\t\tif (otherLoadOfV == null)\n\t\t\t\t\treturn false;\n\t\t\t\tfinalStore = otherLoadOfV.Parent.Extract(context);\n\t\t\t\tif (finalStore == null)\n\t\t\t\t\treturn false;\n\t\t\t\tvalue = ((StLoc)finalStore.StoreInstructions[0]).Value;\n\t\t\t}\n\t\t\tvar fd = context.PEFile.Metadata.GetFieldDefinition((FieldDefinitionHandle)field.MetadataToken);\n\t\t\tif (!fd.HasFlag(System.Reflection.FieldAttributes.HasFieldRVA))\n\t\t\t\treturn false;\n\t\t\tif (value.MatchLdLoc(v))\n\t\t\t{\n\t\t\t\telementType = ((PointerType)finalStore.Type).ElementType;\n\t\t\t}\n\t\t\telse if (value is NewObj { Arguments: { Count: 2 } } newObj\n\t\t\t\t  && newObj.Method.DeclaringType.IsKnownType(KnownTypeCode.SpanOfT)\n\t\t\t\t  && newObj.Arguments[0].MatchLdLoc(v)\n\t\t\t\t  && newObj.Arguments[1].MatchLdcI4(out var elementCount))\n\t\t\t{\n\t\t\t\telementType = ((ParameterizedType)newObj.Method.DeclaringType).TypeArguments[0];\n\t\t\t\tif (elementCount != length / elementType.GetSize())\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tblob = fd.GetInitialValue(context.PEFile, context.TypeSystem);\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic bool MatchGetStaticFieldAddress(ILInstruction input, out IField field)\n\t\t{\n\t\t\tif (input.MatchLdsFlda(out field))\n\t\t\t\treturn true;\n\t\t\t// call get_Item(addressof System.ReadOnlySpan`1[[T]](call CreateSpan(ldmembertoken field)), ldc.i4 0)\n\t\t\tif (input is not Call { Method.Name: \"get_Item\", Arguments.Count: 2 } call)\n\t\t\t\treturn false;\n\t\t\tif (!call.Method.DeclaringType.IsKnownType(KnownTypeCode.ReadOnlySpanOfT))\n\t\t\t\treturn false;\n\t\t\tif (!call.Arguments[1].MatchLdcI4(0))\n\t\t\t\treturn false;\n\t\t\tif (call.Arguments[0] is not AddressOf addressOf)\n\t\t\t\treturn false;\n\t\t\tif (addressOf.Value is not Call { Method.Name: \"CreateSpan\", Arguments.Count: 1 } createSpanCall)\n\t\t\t\treturn false;\n\t\t\tif (!IsRuntimeHelpers(createSpanCall.Method.DeclaringType))\n\t\t\t\treturn false;\n\t\t\tif (!createSpanCall.Arguments[0].MatchLdMemberToken(out var member))\n\t\t\t\treturn false;\n\t\t\tfield = member as IField;\n\t\t\treturn field != null;\n\t\t}\n\n\t\tstatic bool IsRuntimeHelpers(IType type) => type is { Name: \"RuntimeHelpers\", Namespace: \"System.Runtime.CompilerServices\", TypeParameterCount: 0 };\n\n\t\tunsafe bool HandleSequentialLocAllocInitializer(Block block, int pos, ILVariable store, ILInstruction locAllocInstruction, out IType elementType, out StObj[] values, out int instructionsToRemove)\n\t\t{\n\t\t\tint elementCount = 0;\n\t\t\tlong minExpectedOffset = 0;\n\t\t\tvalues = null;\n\t\t\telementType = null;\n\t\t\tinstructionsToRemove = 0;\n\n\t\t\tif (!locAllocInstruction.MatchLocAlloc(out var lengthInstruction))\n\t\t\t\treturn false;\n\n\t\t\tBlobReader blob = default;\n\n\t\t\tif (lengthInstruction.MatchLdcI(out long byteCount))\n\t\t\t{\n\t\t\t\tif (block.Instructions[pos].MatchInitblk(out var dest, out var value, out var size))\n\t\t\t\t{\n\t\t\t\t\tif (!dest.MatchLdLoc(store) || !size.MatchLdcI(byteCount))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tinstructionsToRemove++;\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t\telse if (block.Instructions[pos].MatchCpblk(out dest, out var src, out size))\n\t\t\t\t{\n\t\t\t\t\tif (!dest.MatchLdLoc(store) || !size.MatchLdcI(byteCount))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!MatchGetStaticFieldAddress(src, out var field))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tvar fd = context.PEFile.Metadata.GetFieldDefinition((FieldDefinitionHandle)field.MetadataToken);\n\t\t\t\t\tif (!fd.HasFlag(System.Reflection.FieldAttributes.HasFieldRVA))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tblob = fd.GetInitialValue(context.PEFile, context.TypeSystem);\n\t\t\t\t\tinstructionsToRemove++;\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (int i = pos; i < block.Instructions.Count; i++)\n\t\t\t{\n\t\t\t\t// match the basic stobj pattern\n\t\t\t\tif (!block.Instructions[i].MatchStObj(out ILInstruction target, out var value, out var currentType)\n\t\t\t\t\t|| value.Descendants.OfType<IInstructionWithVariableOperand>().Any(inst => inst.Variable == store))\n\t\t\t\t\tbreak;\n\t\t\t\t// first\n\t\t\t\tif (elementType == null)\n\t\t\t\t{\n\t\t\t\t\telementType = currentType;\n\t\t\t\t\tif (blob.StartPointer != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar countInstruction = PointerArithmeticOffset.Detect(lengthInstruction, elementType, checkForOverflow: true);\n\t\t\t\t\t\tif (countInstruction == null || !countInstruction.MatchLdcI(out long valuesLength) || valuesLength < 1)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tvalues = new StObj[(int)valuesLength];\n\t\t\t\t\t\tint valueIndex = 0;\n\t\t\t\t\t\twhile (blob.RemainingBytes > 0 && valueIndex < values.Length)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalues[valueIndex] = StElemPtr(store, blob.Offset, ReadElement(ref blob, elementType), elementType);\n\t\t\t\t\t\t\tvalueIndex++;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (!currentType.Equals(elementType))\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t// match the target\n\t\t\t\t// should be either ldloc store (at offset 0)\n\t\t\t\t// or binary.add(ldloc store, offset) where offset is either 'elementSize' or 'i * elementSize'\n\t\t\t\tif (!target.MatchLdLoc(store))\n\t\t\t\t{\n\t\t\t\t\tif (!target.MatchBinaryNumericInstruction(BinaryNumericOperator.Add, out var left, out var right))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!left.MatchLdLoc(store))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tvar offsetInst = PointerArithmeticOffset.Detect(right, elementType, ((BinaryNumericInstruction)target).CheckForOverflow);\n\t\t\t\t\tif (offsetInst == null)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!offsetInst.MatchLdcI(out long offset) || offset < 0 || offset < minExpectedOffset)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tminExpectedOffset = offset;\n\t\t\t\t}\n\t\t\t\tif (values == null)\n\t\t\t\t{\n\t\t\t\t\tvar countInstruction = PointerArithmeticOffset.Detect(lengthInstruction, elementType, checkForOverflow: true);\n\t\t\t\t\tif (countInstruction == null || !countInstruction.MatchLdcI(out long valuesLength) || valuesLength < 1)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tvalues = new StObj[(int)valuesLength];\n\t\t\t\t}\n\t\t\t\tif (minExpectedOffset >= values.Length)\n\t\t\t\t\tbreak;\n\t\t\t\tvalues[minExpectedOffset] = (StObj)block.Instructions[i];\n\t\t\t\telementCount++;\n\t\t\t}\n\n\t\t\tif (values == null || store.Kind != VariableKind.StackSlot || store.StoreCount != 1\n\t\t\t\t|| store.AddressCount != 0 || store.LoadCount > values.Length + 1)\n\t\t\t\treturn false;\n\n\t\t\tif (store.LoadInstructions.Last().Parent is StLoc finalStore)\n\t\t\t{\n\t\t\t\telementType = ((PointerType)finalStore.Variable.Type).ElementType;\n\t\t\t}\n\t\t\tinstructionsToRemove += elementCount;\n\n\t\t\treturn elementCount <= values.Length;\n\t\t}\n\n\t\tILInstruction RewrapStore(ILVariable target, StObj storeInstruction, IType type)\n\t\t{\n\t\t\tILInstruction targetInst;\n\t\t\tif (storeInstruction.Target.MatchLdLoc(out _))\n\t\t\t\ttargetInst = new LdLoc(target);\n\t\t\telse if (storeInstruction.Target.MatchBinaryNumericInstruction(BinaryNumericOperator.Add, out var left, out var right))\n\t\t\t{\n\t\t\t\tvar old = (BinaryNumericInstruction)storeInstruction.Target;\n\t\t\t\ttargetInst = new BinaryNumericInstruction(BinaryNumericOperator.Add, new LdLoc(target), right,\n\t\t\t\t\told.CheckForOverflow, old.Sign);\n\t\t\t}\n\t\t\telse\n\t\t\t\tthrow new NotSupportedException(\"This should never happen: Bug in HandleSequentialLocAllocInitializer!\");\n\n\t\t\treturn new StObj(targetInst, storeInstruction.Value, storeInstruction.Type);\n\t\t}\n\n\t\tStObj StElemPtr(ILVariable target, int offset, ILInstruction value, IType type)\n\t\t{\n\t\t\tvar targetInst = offset == 0 ? (ILInstruction)new LdLoc(target) : new BinaryNumericInstruction(\n\t\t\t\tBinaryNumericOperator.Add,\n\t\t\t\tnew LdLoc(target),\n\t\t\t\tnew Conv(new LdcI4(offset), PrimitiveType.I, false, Sign.Signed),\n\t\t\t\tfalse,\n\t\t\t\tSign.None\n\t\t\t);\n\t\t\treturn new StObj(targetInst, value, type);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Handle simple case where RuntimeHelpers.InitializeArray is not used.\n\t\t/// </summary>\n\t\tinternal static bool HandleSimpleArrayInitializer(ILFunction function, Block block, int pos, ILVariable store, int[] arrayLength, out (ILInstruction[] Indices, ILInstruction Value)[] values, out int instructionsToRemove)\n\t\t{\n\t\t\tinstructionsToRemove = 0;\n\t\t\tint elementCount = 0;\n\t\t\tint length = arrayLength.Aggregate(1, (t, l) => t * l);\n\t\t\t// Cannot pre-allocate the result array, because we do not know yet,\n\t\t\t// whether there is in fact an array initializer.\n\t\t\t// To prevent excessive allocations, use min(|block|, arraySize) als initial capacity.\n\t\t\t// This should prevent list-resizing as well as out-of-memory errors.\n\t\t\tvalues = null;\n\t\t\tvar valuesList = new List<(ILInstruction[] Indices, ILInstruction Value)>(Math.Min(block.Instructions.Count, length));\n\n\t\t\tint[] nextMinimumIndex = new int[arrayLength.Length];\n\n\t\t\tILInstruction[] CalculateNextIndices(InstructionCollection<ILInstruction> indices, out bool exactMatch)\n\t\t\t{\n\t\t\t\tvar nextIndices = new ILInstruction[arrayLength.Length];\n\t\t\t\texactMatch = true;\n\t\t\t\tif (indices == null)\n\t\t\t\t{\n\t\t\t\t\tfor (int k = 0; k < nextIndices.Length; k++)\n\t\t\t\t\t{\n\t\t\t\t\t\tnextIndices[k] = new LdcI4(nextMinimumIndex[k]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbool previousComponentWasGreater = false;\n\t\t\t\t\tfor (int k = 0; k < indices.Count; k++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!indices[k].MatchLdcI4(out int index))\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t// index must be in range [0..length[ and must be greater than or equal to nextMinimumIndex\n\t\t\t\t\t\t// to avoid running out of bounds or accidentally reordering instructions or overwriting previous instructions.\n\t\t\t\t\t\t// However, leaving array slots empty is allowed, as those are filled with default values when the\n\t\t\t\t\t\t// initializer block is generated.\n\t\t\t\t\t\tif (index < 0 || index >= arrayLength[k] || (!previousComponentWasGreater && index < nextMinimumIndex[k]))\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\tnextIndices[k] = new LdcI4(nextMinimumIndex[k]);\n\t\t\t\t\t\tif (index != nextMinimumIndex[k])\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\texactMatch = false;\n\t\t\t\t\t\t\t// this flag allows us to check whether the whole set of indices is smaller:\n\t\t\t\t\t\t\t// [3, 3] should be smaller than [4, 0] even though 3 > 0.\n\t\t\t\t\t\t\tif (index > nextMinimumIndex[k])\n\t\t\t\t\t\t\t\tpreviousComponentWasGreater = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor (int k = nextMinimumIndex.Length - 1; k >= 0; k--)\n\t\t\t\t{\n\t\t\t\t\tnextMinimumIndex[k]++;\n\t\t\t\t\tif (nextMinimumIndex[k] < arrayLength[k] || k == 0)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tnextMinimumIndex[k] = 0;\n\t\t\t\t}\n\n\t\t\t\treturn nextIndices;\n\t\t\t}\n\n\t\t\tint i = pos;\n\t\t\tint step;\n\t\t\twhile (i < block.Instructions.Count)\n\t\t\t{\n\t\t\t\tInstructionCollection<ILInstruction> indices;\n\t\t\t\t// stobj elementType(ldelema elementType(ldloc store, indices), value)\n\t\t\t\tif (block.Instructions[i].MatchStObj(out ILInstruction target, out ILInstruction value, out IType type))\n\t\t\t\t{\n\t\t\t\t\tif (!(target is LdElema ldelem && ldelem.Array.MatchLdLoc(store)))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tindices = ldelem.Indices;\n\t\t\t\t\tstep = 1;\n\t\t\t\t\t// stloc s(ldelema elementType(ldloc store, indices))\n\t\t\t\t\t// stobj elementType(ldloc s, value)\n\t\t\t\t}\n\t\t\t\telse if (block.Instructions[i].MatchStLoc(out var addressTemporary, out var addressValue))\n\t\t\t\t{\n\t\t\t\t\tif (!(addressTemporary.IsSingleDefinition && addressTemporary.LoadCount == 1))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tif (!(addressValue is LdElema ldelem && ldelem.Array.MatchLdLoc(store)))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tif (!(i + 1 < block.Instructions.Count))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tif (!block.Instructions[i + 1].MatchStObj(out target, out value, out type))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tif (!(target.MatchLdLoc(addressTemporary) && ldelem.Array.MatchLdLoc(store)))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tindices = ldelem.Indices;\n\t\t\t\t\tstep = 2;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (value.Descendants.OfType<IInstructionWithVariableOperand>().Any(inst => inst.Variable == store))\n\t\t\t\t\tbreak;\n\t\t\t\tif (indices.Count != arrayLength.Length)\n\t\t\t\t\tbreak;\n\t\t\t\tbool exact;\n\t\t\t\tif (length <= 0)\n\t\t\t\t\tbreak;\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tvar nextIndices = CalculateNextIndices(indices, out exact);\n\t\t\t\t\tif (nextIndices == null)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (exact)\n\t\t\t\t\t{\n\t\t\t\t\t\tvaluesList.Add((nextIndices, value));\n\t\t\t\t\t\telementCount++;\n\t\t\t\t\t\tinstructionsToRemove += step;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tvaluesList.Add((nextIndices, null));\n\t\t\t\t\t}\n\t\t\t\t} while (valuesList.Count < length && !exact);\n\t\t\t\ti += step;\n\t\t\t}\n\t\t\tif (i < block.Instructions.Count)\n\t\t\t{\n\t\t\t\tif (block.Instructions[i].MatchStObj(out ILInstruction target, out ILInstruction value, out IType type))\n\t\t\t\t{\n\t\t\t\t\t// An element of the array is modified directly after the initializer:\n\t\t\t\t\t// Abort transform, so that partial initializers are not constructed. \n\t\t\t\t\tif (target is LdElema ldelem && ldelem.Array.MatchLdLoc(store))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (pos + instructionsToRemove >= block.Instructions.Count)\n\t\t\t\treturn false;\n\t\t\tif (elementCount == 0)\n\t\t\t\treturn false;\n\n\t\t\tbool mustTransform = ILInlining.IsCatchWhenBlock(block) || ILInlining.IsInConstructorInitializer(function, block.Instructions[pos]);\n\t\t\t// If there are not enough user-defined elements after scanning all instructions, we can abort the transform.\n\t\t\t// This avoids unnecessary allocations and OOM crashes (in case of int.MaxValue).\n\t\t\tif (elementCount < length / 3 - 5)\n\t\t\t{\n\t\t\t\tif (!mustTransform)\n\t\t\t\t\treturn false;\n\t\t\t\t// .NET does not allow allocation of arrays >= 2 GB.\n\t\t\t\tif (length >= int.MaxValue)\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tfor (int j = valuesList.Count; j < length; j++)\n\t\t\t{\n\t\t\t\tvar nextIndices = CalculateNextIndices(null, out _);\n\t\t\t\tif (nextIndices == null)\n\t\t\t\t\treturn false;\n\t\t\t\tvaluesList.Add((nextIndices, null));\n\t\t\t}\n\t\t\tvalues = valuesList.ToArray();\n\t\t\treturn true;\n\t\t}\n\n\t\tbool HandleJaggedArrayInitializer(Block block, int pos, ILVariable store, IType elementType, int length, out ILVariable finalStore, out ILInstruction[] values, out int instructionsToRemove)\n\t\t{\n\t\t\tinstructionsToRemove = 0;\n\t\t\tfinalStore = null;\n\t\t\t// Cannot pre-allocate the result array, because we do not know yet,\n\t\t\t// whether there is in fact an array initializer.\n\t\t\t// To prevent excessive allocations, use min(|block|, arraySize) als initial capacity.\n\t\t\t// This should prevent list-resizing as well as out-of-memory errors.\n\t\t\tvalues = null;\n\t\t\tvar valuesList = new List<ILInstruction>(Math.Min(block.Instructions.Count, length));\n\n\t\t\tfor (int i = 0; i < length; i++)\n\t\t\t{\n\t\t\t\t// 1. Instruction: (optional) temporary copy of store\n\t\t\t\tbool hasTemporaryCopy = block.Instructions[pos].MatchStLoc(out var temp, out var storeLoad) && storeLoad.MatchLdLoc(store);\n\t\t\t\tILInstruction initializer;\n\t\t\t\tif (hasTemporaryCopy)\n\t\t\t\t{\n\t\t\t\t\tif (!MatchJaggedArrayStore(block, pos + 1, temp, i, out initializer, out _))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (!MatchJaggedArrayStore(block, pos, store, i, out initializer, out _))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tvaluesList.Add(initializer);\n\t\t\t\tint inc = hasTemporaryCopy ? 3 : 2;\n\t\t\t\tpos += inc;\n\t\t\t\tinstructionsToRemove += inc;\n\t\t\t}\n\t\t\t// In case there is an extra copy of the store variable\n\t\t\t// Remove it and use its value instead.\n\t\t\tif (block.Instructions[pos].MatchStLoc(out finalStore, out var array))\n\t\t\t{\n\t\t\t\tif (!array.MatchLdLoc(store))\n\t\t\t\t\treturn false;\n\t\t\t\tinstructionsToRemove++;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfinalStore = store;\n\t\t\t}\n\t\t\tvalues = valuesList.ToArray();\n\t\t\treturn true;\n\t\t}\n\n\t\tbool MatchJaggedArrayStore(Block block, int pos, ILVariable store, int index, out ILInstruction initializer, out IType type)\n\t\t{\n\t\t\tinitializer = null;\n\t\t\ttype = null;\n\t\t\t// 3. Instruction: stobj(ldelema(ldloc temp, ldc.i4 0), ldloc tempArrayLoad)\n\t\t\tvar finalInstruction = block.Instructions.ElementAtOrDefault(pos + 1);\n\t\t\tif (finalInstruction == null || !finalInstruction.MatchStObj(out var tempAccess, out var tempArrayLoad, out type)\n\t\t\t\t|| !tempArrayLoad.MatchLdLoc(out var initializerStore))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!(tempAccess is LdElema elemLoad) || !elemLoad.Array.MatchLdLoc(store) || elemLoad.Indices.Count != 1\n\t\t\t\t|| !elemLoad.Indices[0].MatchLdcI4(index))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// 2. Instruction: stloc(temp) with block (array initializer)\n\t\t\tvar nextInstruction = block.Instructions.ElementAtOrDefault(pos);\n\t\t\treturn nextInstruction != null\n\t\t\t\t&& nextInstruction.MatchStLoc(initializerStore, out initializer)\n\t\t\t\t&& initializer.OpCode == OpCode.Block;\n\t\t}\n\n\t\tstatic Block BlockFromInitializer(ILVariable v, IType elementType, int[] arrayLength, ILInstruction[] values)\n\t\t{\n\t\t\tvar block = new Block(BlockKind.ArrayInitializer);\n\t\t\tblock.Instructions.Add(new StLoc(v, new NewArr(elementType, arrayLength.Select(l => new LdcI4(l)).ToArray())));\n\t\t\tint step = arrayLength.Length + 1;\n\n\t\t\tvar indices = new List<ILInstruction>();\n\t\t\tfor (int i = 0; i < values.Length / step; i++)\n\t\t\t{\n\t\t\t\t// values array is filled backwards\n\t\t\t\tvar value = values[step * i];\n\n\t\t\t\tindices.EnsureCapacity(step - 1);\n\t\t\t\tfor (int j = step - 1; j >= 1; j--)\n\t\t\t\t{\n\t\t\t\t\tindices.Add(values[step * i + j]);\n\t\t\t\t}\n\n\t\t\t\tblock.Instructions.Add(StElem(new LdLoc(v), indices.ToArray(), value, elementType));\n\t\t\t\tindices.Clear();\n\t\t\t}\n\t\t\tblock.FinalInstruction = new LdLoc(v);\n\t\t\treturn block;\n\t\t}\n\n\t\tstatic bool MatchNewArr(ILInstruction instruction, out IType arrayType, out int[] length)\n\t\t{\n\t\t\tlength = null;\n\t\t\tarrayType = null;\n\t\t\tif (!(instruction is NewArr newArr))\n\t\t\t\treturn false;\n\t\t\tarrayType = newArr.Type;\n\t\t\tvar args = newArr.Indices;\n\t\t\tlength = new int[args.Count];\n\t\t\tfor (int i = 0; i < args.Count; i++)\n\t\t\t{\n\t\t\t\tif (!args[i].MatchLdcI4(out int value) || value <= 0)\n\t\t\t\t\treturn false;\n\t\t\t\tlength[i] = value;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tbool MatchInitializeArrayCall(ILInstruction instruction, out ILInstruction array, out FieldDefinition field)\n\t\t{\n\t\t\tarray = null;\n\t\t\tfield = default;\n\t\t\tif (!(instruction is Call call) || call.Arguments.Count != 2)\n\t\t\t\treturn false;\n\t\t\tIMethod method = call.Method;\n\t\t\tif (!method.IsStatic || method.Name != \"InitializeArray\" || method.DeclaringTypeDefinition == null)\n\t\t\t\treturn false;\n\t\t\tif (!IsRuntimeHelpers(method.DeclaringType))\n\t\t\t\treturn false;\n\t\t\tarray = call.Arguments[0];\n\t\t\tif (!call.Arguments[1].MatchLdMemberToken(out var member))\n\t\t\t\treturn false;\n\t\t\tif (member.MetadataToken.IsNil)\n\t\t\t\treturn false;\n\t\t\tfield = context.PEFile.Metadata.GetFieldDefinition((FieldDefinitionHandle)member.MetadataToken);\n\t\t\treturn true;\n\t\t}\n\n\t\tbool HandleRuntimeHelpersInitializeArray(Block body, int pos, ILVariable array, IType arrayType, int[] arrayLength, out ILInstruction[] values, out int foundPos)\n\t\t{\n\t\t\tvalues = null;\n\t\t\tfoundPos = -1;\n\t\t\tif (MatchInitializeArrayCall(body.Instructions[pos], out var arrayInst, out var field) && arrayInst.MatchLdLoc(array))\n\t\t\t{\n\t\t\t\tif (field.HasFlag(System.Reflection.FieldAttributes.HasFieldRVA))\n\t\t\t\t{\n\t\t\t\t\tvar valuesList = new List<ILInstruction>();\n\t\t\t\t\tBlobReader initialValue;\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tinitialValue = field.GetInitialValue(context.PEFile, context.TypeSystem);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (BadImageFormatException ex)\n\t\t\t\t\t{\n\t\t\t\t\t\tarray.Function.Warnings.Add($\"IL_{body.Instructions[pos].ILRanges.FirstOrDefault().Start:x4}: {ex.Message}\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif (DecodeArrayInitializer(arrayType, initialValue, arrayLength, valuesList))\n\t\t\t\t\t{\n\t\t\t\t\t\tvalues = valuesList.ToArray();\n\t\t\t\t\t\tfoundPos = pos;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// call InitializeArray(newarr T(size), ldmembertoken fieldToken)\n\t\t/// =>\n\t\t/// Block (ArrayInitializer) {\n\t\t///\t\tstloc i(newarr T(size))\n\t\t///\t\tstobj T(ldelema T(... indices ...), value)\n\t\t///\t\tfinal: ldloc i\n\t\t/// }\n\t\t/// </summary>\n\t\tbool DoTransformInlineRuntimeHelpersInitializeArray(Block body, int pos)\n\t\t{\n\t\t\tvar inst = body.Instructions[pos];\n\t\t\tif (!MatchInitializeArrayCall(inst, out var arrayInst, out var field))\n\t\t\t\treturn false;\n\t\t\tif (!MatchNewArr(arrayInst, out var elementType, out var arrayLength))\n\t\t\t\treturn false;\n\t\t\tif (!field.HasFlag(System.Reflection.FieldAttributes.HasFieldRVA))\n\t\t\t\treturn false;\n\t\t\tvar valuesList = new List<ILInstruction>();\n\t\t\tvar initialValue = field.GetInitialValue(context.PEFile, context.TypeSystem);\n\t\t\tif (!DecodeArrayInitializer(elementType, initialValue, arrayLength, valuesList))\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"InlineRuntimeHelpersInitializeArray: single-dim\", inst);\n\t\t\tvar tempStore = context.Function.RegisterVariable(VariableKind.InitializerTarget, new ArrayType(context.TypeSystem, elementType, arrayLength.Length));\n\t\t\tvar block = BlockFromInitializer(tempStore, elementType, arrayLength, valuesList.ToArray());\n\t\t\tbody.Instructions[pos] = block;\n\t\t\tILInlining.InlineIfPossible(body, pos, context);\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic bool DecodeArrayInitializer(IType type, BlobReader initialValue, int[] arrayLength, List<ILInstruction> output)\n\t\t{\n\t\t\tTypeCode typeCode = ReflectionHelper.GetTypeCode(type);\n\t\t\tswitch (typeCode)\n\t\t\t{\n\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\treturn DecodeArrayInitializer(initialValue, arrayLength, output, typeCode, (ref BlobReader r) => new LdcI4(r.ReadByte()));\n\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\treturn DecodeArrayInitializer(initialValue, arrayLength, output, typeCode, (ref BlobReader r) => new LdcI4(r.ReadSByte()));\n\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\treturn DecodeArrayInitializer(initialValue, arrayLength, output, typeCode, (ref BlobReader r) => new LdcI4(r.ReadInt16()));\n\t\t\t\tcase TypeCode.Char:\n\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\treturn DecodeArrayInitializer(initialValue, arrayLength, output, typeCode, (ref BlobReader r) => new LdcI4(r.ReadUInt16()));\n\t\t\t\tcase TypeCode.Int32:\n\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\treturn DecodeArrayInitializer(initialValue, arrayLength, output, typeCode, (ref BlobReader r) => new LdcI4(r.ReadInt32()));\n\t\t\t\tcase TypeCode.Int64:\n\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\treturn DecodeArrayInitializer(initialValue, arrayLength, output, typeCode, (ref BlobReader r) => new LdcI8(r.ReadInt64()));\n\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\treturn DecodeArrayInitializer(initialValue, arrayLength, output, typeCode, (ref BlobReader r) => new LdcF4(r.ReadSingle()));\n\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\treturn DecodeArrayInitializer(initialValue, arrayLength, output, typeCode, (ref BlobReader r) => new LdcF8(r.ReadDouble()));\n\t\t\t\tcase TypeCode.Object:\n\t\t\t\tcase TypeCode.Empty:\n\t\t\t\t\tvar typeDef = type.GetDefinition();\n\t\t\t\t\tif (typeDef != null && typeDef.Kind == TypeKind.Enum)\n\t\t\t\t\t\treturn DecodeArrayInitializer(typeDef.EnumUnderlyingType, initialValue, arrayLength, output);\n\t\t\t\t\treturn false;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tdelegate ILInstruction ValueDecoder(ref BlobReader reader);\n\n\t\tstatic bool DecodeArrayInitializer(BlobReader initialValue, int[] arrayLength,\n\t\t\tList<ILInstruction> output, TypeCode elementType, ValueDecoder decoder)\n\t\t{\n\t\t\tint elementSize = ElementSizeOf(elementType);\n\t\t\tvar totalLength = arrayLength.Aggregate(1, (t, l) => t * l);\n\t\t\tif (initialValue.RemainingBytes < (totalLength * elementSize))\n\t\t\t\treturn false;\n\n\t\t\toutput.EnsureCapacity(totalLength + totalLength * arrayLength.Length);\n\n\t\t\tfor (int i = 0; i < totalLength; i++)\n\t\t\t{\n\t\t\t\toutput.Add(decoder(ref initialValue));\n\t\t\t\tint next = i;\n\t\t\t\tfor (int j = arrayLength.Length - 1; j >= 0; j--)\n\t\t\t\t{\n\t\t\t\t\toutput.Add(new LdcI4(next % arrayLength[j]));\n\t\t\t\t\tnext /= arrayLength[j];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic ILInstruction StElem(ILInstruction array, ILInstruction[] indices, ILInstruction value, IType type)\n\t\t{\n\t\t\tif (type.GetStackType() != value.ResultType)\n\t\t\t{\n\t\t\t\tvalue = new Conv(value, type.ToPrimitiveType(), false, Sign.None);\n\t\t\t}\n\t\t\treturn new StObj(new LdElema(type, array, indices) { DelayExceptions = true }, value, type);\n\t\t}\n\n\t\tinternal static ILInstruction GetNullExpression(IType elementType)\n\t\t{\n\t\t\tITypeDefinition typeDef = elementType.GetEnumUnderlyingType().GetDefinition();\n\t\t\tif (typeDef == null)\n\t\t\t\treturn new DefaultValue(elementType);\n\t\t\tswitch (typeDef.KnownTypeCode)\n\t\t\t{\n\t\t\t\tcase KnownTypeCode.Boolean:\n\t\t\t\tcase KnownTypeCode.Char:\n\t\t\t\tcase KnownTypeCode.SByte:\n\t\t\t\tcase KnownTypeCode.Byte:\n\t\t\t\tcase KnownTypeCode.Int16:\n\t\t\t\tcase KnownTypeCode.UInt16:\n\t\t\t\tcase KnownTypeCode.Int32:\n\t\t\t\tcase KnownTypeCode.UInt32:\n\t\t\t\t\treturn new LdcI4(0);\n\t\t\t\tcase KnownTypeCode.Int64:\n\t\t\t\tcase KnownTypeCode.UInt64:\n\t\t\t\t\treturn new LdcI8(0);\n\t\t\t\tcase KnownTypeCode.Single:\n\t\t\t\t\treturn new LdcF4(0);\n\t\t\t\tcase KnownTypeCode.Double:\n\t\t\t\t\treturn new LdcF8(0);\n\t\t\t\tcase KnownTypeCode.Decimal:\n\t\t\t\t\treturn new LdcDecimal(0);\n\t\t\t\tcase KnownTypeCode.Void:\n\t\t\t\t\tthrow new ArgumentException(\"void is not a valid element type!\");\n\t\t\t\tcase KnownTypeCode.IntPtr:\n\t\t\t\tcase KnownTypeCode.UIntPtr:\n\t\t\t\tdefault:\n\t\t\t\t\treturn new DefaultValue(elementType);\n\t\t\t}\n\t\t}\n\n\t\tstatic int ElementSizeOf(TypeCode elementType)\n\t\t{\n\t\t\tswitch (elementType)\n\t\t\t{\n\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\tcase TypeCode.Byte:\n\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\treturn 1;\n\t\t\t\tcase TypeCode.Char:\n\t\t\t\tcase TypeCode.Int16:\n\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\treturn 2;\n\t\t\t\tcase TypeCode.Int32:\n\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\treturn 4;\n\t\t\t\tcase TypeCode.Int64:\n\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\treturn 8;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(elementType));\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs",
    "content": "// Copyright (c) 2015 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Linq.Expressions;\n\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Constructs compound assignments and inline assignments.\n\t/// </summary>\n\t/// <remarks>\n\t/// This is a statement transform;\n\t/// but some portions are executed as an expression transform instead\n\t/// (with HandleCompoundAssign() as entry point)\n\t/// </remarks>\n\tpublic class TransformAssignment : IStatementTransform\n\t{\n\t\tStatementTransformContext context;\n\n\t\tvoid IStatementTransform.Run(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\tthis.context = context;\n\t\t\tif (context.Settings.MakeAssignmentExpressions)\n\t\t\t{\n\t\t\t\tif (TransformInlineAssignmentStObjOrCall(block, pos) || TransformInlineAssignmentLocal(block, pos))\n\t\t\t\t{\n\t\t\t\t\t// both inline assignments create a top-level stloc which might affect inlining\n\t\t\t\t\tcontext.RequestRerun();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (context.Settings.IntroduceIncrementAndDecrement)\n\t\t\t{\n\t\t\t\tif (TransformPostIncDecOperatorWithInlineStore(block, pos)\n\t\t\t\t\t|| TransformPostIncDecOperator(block, pos)\n\t\t\t\t\t|| TransformPreIncDecOperatorWithInlineStore(block, pos))\n\t\t\t\t{\n\t\t\t\t\t// again, new top-level stloc might need inlining:\n\t\t\t\t\tcontext.RequestRerun();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <code>\n\t\t/// stloc s(value)\n\t\t/// stloc l(ldloc s)\n\t\t/// stobj(..., ldloc s)\n\t\t///   where ... is pure and does not use s or l,\n\t\t///   and where neither the 'stloc s' nor the 'stobj' truncates\n\t\t/// -->\n\t\t/// stloc l(stobj (..., value))\n\t\t/// </code>\n\t\t/// e.g. used for inline assignment to instance field\n\t\t/// \n\t\t/// -or-\n\t\t/// \n\t\t/// <code>\n\t\t/// stloc s(value)\n\t\t/// stobj (..., ldloc s)\n\t\t///   where ... is pure and does not use s, and where the 'stobj' does not truncate\n\t\t/// -->\n\t\t/// stloc s(stobj (..., value))\n\t\t/// </code>\n\t\t/// e.g. used for inline assignment to static field\n\t\t/// \n\t\t/// -or-\n\t\t/// \n\t\t/// <code>\n\t\t/// stloc s(value)\n\t\t/// call set_Property(..., ldloc s)\n\t\t///   where the '...' arguments are pure and not using 's'\n\t\t/// -->\n\t\t/// stloc s(Block InlineAssign { call set_Property(..., stloc i(value)); final: ldloc i })\n\t\t///   new temporary 'i' has type of the property; transform only valid if 'stloc i' doesn't truncate\n\t\t/// </code>\n\t\tbool TransformInlineAssignmentStObjOrCall(Block block, int pos)\n\t\t{\n\t\t\tvar inst = block.Instructions[pos] as StLoc;\n\t\t\t// in some cases it can be a compiler-generated local\n\t\t\tif (inst == null || (inst.Variable.Kind != VariableKind.StackSlot && inst.Variable.Kind != VariableKind.Local))\n\t\t\t\treturn false;\n\t\t\tif (IsImplicitTruncation(inst.Value, inst.Variable.Type, context.TypeSystem))\n\t\t\t{\n\t\t\t\t// 'stloc s' is implicitly truncating the value\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tILVariable local;\n\t\t\tint nextPos;\n\t\t\tif (block.Instructions[pos + 1] is StLoc localStore)\n\t\t\t{ // with extra local\n\t\t\t\tif (localStore.Variable.Kind != VariableKind.Local || !localStore.Value.MatchLdLoc(inst.Variable))\n\t\t\t\t\treturn false;\n\t\t\t\t// if we're using an extra local, we'll delete \"s\", so check that that doesn't have any additional uses\n\t\t\t\tif (!(inst.Variable.IsSingleDefinition && inst.Variable.LoadCount == 2))\n\t\t\t\t\treturn false;\n\t\t\t\tlocal = localStore.Variable;\n\t\t\t\tnextPos = pos + 2;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tlocal = inst.Variable;\n\t\t\t\tlocalStore = null;\n\t\t\t\tnextPos = pos + 1;\n\n\t\t\t\tif (local.LoadCount == 1 && local.AddressCount == 0)\n\t\t\t\t{\n\t\t\t\t\t// inline assignment would produce a dead store in this case, which is ugly\n\t\t\t\t\t// and causes problems with the deconstruction transform.\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (block.Instructions[nextPos] is StObj stobj)\n\t\t\t{\n\t\t\t\t// unaligned.stobj cannot be inlined in C#\n\t\t\t\tif (stobj.UnalignedPrefix > 0)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!stobj.Value.MatchLdLoc(inst.Variable))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!SemanticHelper.IsPure(stobj.Target.Flags) || inst.Variable.IsUsedWithin(stobj.Target))\n\t\t\t\t\treturn false;\n\t\t\t\tvar pointerType = stobj.Target.InferType(context.TypeSystem);\n\t\t\t\tIType newType = stobj.Type;\n\t\t\t\tif (TypeUtils.IsCompatiblePointerTypeForMemoryAccess(pointerType, stobj.Type))\n\t\t\t\t{\n\t\t\t\t\tif (pointerType is ByReferenceType byref)\n\t\t\t\t\t\tnewType = byref.ElementType;\n\t\t\t\t\telse if (pointerType is PointerType pointer)\n\t\t\t\t\t\tnewType = pointer.ElementType;\n\t\t\t\t}\n\t\t\t\tvar truncation = CheckImplicitTruncation(inst.Value, newType, context.TypeSystem);\n\t\t\t\tif (truncation == ImplicitTruncationResult.ValueChanged)\n\t\t\t\t{\n\t\t\t\t\t// 'stobj' is implicitly truncating the value\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (truncation == ImplicitTruncationResult.ValueChangedDueToSignMismatch)\n\t\t\t\t{\n\t\t\t\t\t// Change the sign of the type to skip implicit truncation\n\t\t\t\t\tnewType = SwapSign(newType, context.TypeSystem);\n\t\t\t\t}\n\t\t\t\tcontext.Step(\"Inline assignment stobj\", stobj);\n\t\t\t\tstobj.Type = newType;\n\t\t\t\tblock.Instructions.Remove(localStore);\n\t\t\t\tblock.Instructions.Remove(stobj);\n\t\t\t\tstobj.Value = inst.Value;\n\t\t\t\tinst.ReplaceWith(new StLoc(local, stobj));\n\t\t\t\t// note: our caller will trigger a re-run, which will call HandleStObjCompoundAssign if applicable\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (block.Instructions[nextPos] is CallInstruction call)\n\t\t\t{\n\t\t\t\t// call must be a setter call:\n\t\t\t\tif (!(call.OpCode == OpCode.Call || call.OpCode == OpCode.CallVirt))\n\t\t\t\t\treturn false;\n\t\t\t\tif (call.ResultType != StackType.Void || call.Arguments.Count == 0)\n\t\t\t\t\treturn false;\n\t\t\t\tIProperty property = call.Method.AccessorOwner as IProperty;\n\t\t\t\tif (property == null)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!call.Method.Equals(property.Setter))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(property.IsIndexer || property.Setter.Parameters.Count == 1))\n\t\t\t\t{\n\t\t\t\t\t// this is a parameterized property, which cannot be expressed as C# code.\n\t\t\t\t\t// setter calls are not valid in expression context, if property syntax cannot be used.\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (!call.Arguments.Last().MatchLdLoc(inst.Variable))\n\t\t\t\t\treturn false;\n\t\t\t\tforeach (var arg in call.Arguments.SkipLast(1))\n\t\t\t\t{\n\t\t\t\t\tif (!SemanticHelper.IsPure(arg.Flags) || inst.Variable.IsUsedWithin(arg))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (IsImplicitTruncation(inst.Value, call.Method.Parameters.Last().Type, context.TypeSystem))\n\t\t\t\t{\n\t\t\t\t\t// setter call is implicitly truncating the value\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t// stloc s(Block InlineAssign { call set_Property(..., stloc i(value)); final: ldloc i })\n\t\t\t\tcontext.Step(\"Inline assignment call\", call);\n\t\t\t\tblock.Instructions.Remove(localStore);\n\t\t\t\tblock.Instructions.Remove(call);\n\t\t\t\tvar newVar = context.Function.RegisterVariable(VariableKind.StackSlot, call.Method.Parameters.Last().Type);\n\t\t\t\tcall.Arguments[call.Arguments.Count - 1] = new StLoc(newVar, inst.Value);\n\t\t\t\tvar inlineBlock = new Block(BlockKind.CallInlineAssign) {\n\t\t\t\t\tInstructions = { call },\n\t\t\t\t\tFinalInstruction = new LdLoc(newVar)\n\t\t\t\t};\n\t\t\t\tinst.ReplaceWith(new StLoc(local, inlineBlock));\n\t\t\t\t// because the ExpressionTransforms don't look into inline blocks, manually trigger HandleCallCompoundAssign\n\t\t\t\tif (HandleCompoundAssign(call, context))\n\t\t\t\t{\n\t\t\t\t\t// if we did construct a compound assignment, it should have made our inline block redundant:\n\t\t\t\t\tDebug.Assert(!inlineBlock.IsConnected);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tprivate static IType SwapSign(IType type, ICompilation compilation)\n\t\t{\n\t\t\treturn type.ToPrimitiveType() switch {\n\t\t\t\tPrimitiveType.I1 => compilation.FindType(KnownTypeCode.Byte),\n\t\t\t\tPrimitiveType.I2 => compilation.FindType(KnownTypeCode.UInt16),\n\t\t\t\tPrimitiveType.I4 => compilation.FindType(KnownTypeCode.UInt32),\n\t\t\t\tPrimitiveType.I8 => compilation.FindType(KnownTypeCode.UInt64),\n\t\t\t\tPrimitiveType.U1 => compilation.FindType(KnownTypeCode.SByte),\n\t\t\t\tPrimitiveType.U2 => compilation.FindType(KnownTypeCode.Int16),\n\t\t\t\tPrimitiveType.U4 => compilation.FindType(KnownTypeCode.Int32),\n\t\t\t\tPrimitiveType.U8 => compilation.FindType(KnownTypeCode.Int64),\n\t\t\t\tPrimitiveType.I => compilation.FindType(KnownTypeCode.UIntPtr),\n\t\t\t\tPrimitiveType.U => compilation.FindType(KnownTypeCode.IntPtr),\n\t\t\t\t_ => throw new ArgumentException(\"Type must have an opposing sign: \" + type, nameof(type))\n\t\t\t};\n\t\t}\n\n\t\tstatic ILInstruction UnwrapSmallIntegerConv(ILInstruction inst, out Conv conv)\n\t\t{\n\t\t\tconv = inst as Conv;\n\t\t\tif (conv != null && conv.Kind == ConversionKind.Truncate && conv.TargetType.IsSmallIntegerType())\n\t\t\t{\n\t\t\t\t// for compound assignments to small integers, the compiler emits a \"conv\" instruction\n\t\t\t\treturn conv.Argument;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn inst;\n\t\t\t}\n\t\t}\n\n\t\tstatic bool ValidateCompoundAssign(BinaryNumericInstruction binary, Conv conv, IType targetType, DecompilerSettings settings)\n\t\t{\n\t\t\tif (!NumericCompoundAssign.IsBinaryCompatibleWithType(binary, targetType, settings))\n\t\t\t\treturn false;\n\t\t\tif (conv != null && !(conv.TargetType == targetType.ToPrimitiveType() && conv.CheckForOverflow == binary.CheckForOverflow))\n\t\t\t\treturn false; // conv does not match binary operation\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic bool MatchingGetterAndSetterCalls(CallInstruction getterCall, CallInstruction setterCall, out Action<ILTransformContext> finalizeMatch)\n\t\t{\n\t\t\tfinalizeMatch = null;\n\t\t\tif (getterCall == null || setterCall == null || !IsSameMember(getterCall.Method.AccessorOwner, setterCall.Method.AccessorOwner))\n\t\t\t\treturn false;\n\t\t\tif (setterCall.OpCode != getterCall.OpCode)\n\t\t\t\treturn false;\n\t\t\tvar owner = getterCall.Method.AccessorOwner as IProperty;\n\t\t\tif (owner == null || !IsSameMember(getterCall.Method, owner.Getter) || !IsSameMember(setterCall.Method, owner.Setter))\n\t\t\t\treturn false;\n\t\t\tif (setterCall.Arguments.Count != getterCall.Arguments.Count + 1)\n\t\t\t\treturn false;\n\t\t\t// Ensure that same arguments are passed to getterCall and setterCall:\n\t\t\tfor (int j = 0; j < getterCall.Arguments.Count; j++)\n\t\t\t{\n\t\t\t\tif (setterCall.Arguments[j].MatchStLoc(out var v) && v.IsSingleDefinition && v.LoadCount == 1)\n\t\t\t\t{\n\t\t\t\t\tif (getterCall.Arguments[j].MatchLdLoc(v))\n\t\t\t\t\t{\n\t\t\t\t\t\t// OK, setter call argument is saved in temporary that is re-used for getter call\n\t\t\t\t\t\tif (finalizeMatch == null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinalizeMatch = AdjustArguments;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!SemanticHelper.IsPure(getterCall.Arguments[j].Flags))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!getterCall.Arguments[j].Match(setterCall.Arguments[j]).Success)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\n\t\t\tvoid AdjustArguments(ILTransformContext context)\n\t\t\t{\n\t\t\t\tDebug.Assert(setterCall.Arguments.Count == getterCall.Arguments.Count + 1);\n\t\t\t\tfor (int j = 0; j < getterCall.Arguments.Count; j++)\n\t\t\t\t{\n\t\t\t\t\tif (setterCall.Arguments[j].MatchStLoc(out var v, out var value))\n\t\t\t\t\t{\n\t\t\t\t\t\tDebug.Assert(v.IsSingleDefinition && v.LoadCount == 1);\n\t\t\t\t\t\tDebug.Assert(getterCall.Arguments[j].MatchLdLoc(v));\n\t\t\t\t\t\tgetterCall.Arguments[j] = value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Transform compound assignments where the return value is not being used,\n\t\t/// or where there's an inlined assignment within the setter call.\n\t\t/// \n\t\t/// Patterns handled:\n\t\t/// 1.\n\t\t///   callvirt set_Property(ldloc S_1, binary.op(callvirt get_Property(ldloc S_1), value))\n\t\t///   ==> compound.op.new(callvirt get_Property(ldloc S_1), value)\n\t\t/// 2.\n\t\t///   callvirt set_Property(ldloc S_1, stloc v(binary.op(callvirt get_Property(ldloc S_1), value)))\n\t\t///   ==> stloc v(compound.op.new(callvirt get_Property(ldloc S_1), value))\n\t\t/// 3.\n\t\t///   stobj(target, binary.op(ldobj(target), ...))\n\t\t///     where target is pure\n\t\t///   => compound.op(target, ...)\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Called by ExpressionTransforms, or after the inline-assignment transform for setters.\n\t\t/// </remarks>\n\t\tinternal static bool HandleCompoundAssign(ILInstruction compoundStore, StatementTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.MakeAssignmentExpressions || !context.Settings.IntroduceIncrementAndDecrement)\n\t\t\t\treturn false;\n\t\t\tif (compoundStore is CallInstruction && compoundStore.SlotInfo != Block.InstructionSlot)\n\t\t\t{\n\t\t\t\t// replacing 'call set_Property' with a compound assignment instruction\n\t\t\t\t// changes the return value of the expression, so this is only valid on block-level.\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!IsCompoundStore(compoundStore, out var targetType, out var setterValue, context.TypeSystem))\n\t\t\t\treturn false;\n\t\t\t// targetType = The type of the property/field/etc. being stored to.\n\t\t\t// setterValue = The value being stored.\n\t\t\tvar storeInSetter = setterValue as StLoc;\n\t\t\tif (storeInSetter != null)\n\t\t\t{\n\t\t\t\t// We'll move the stloc to top-level:\n\t\t\t\t// callvirt set_Property(ldloc S_1, stloc v(binary.op(callvirt get_Property(ldloc S_1), value)))\n\t\t\t\t// ==> stloc v(compound.op.new(callvirt get_Property(ldloc S_1), value))\n\t\t\t\tsetterValue = storeInSetter.Value;\n\t\t\t\tif (storeInSetter.Variable.Type.IsSmallIntegerType())\n\t\t\t\t{\n\t\t\t\t\t// 'stloc v' implicitly truncates the value.\n\t\t\t\t\t// Ensure that type of 'v' matches the type of the property:\n\t\t\t\t\tif (storeInSetter.Variable.Type.GetSize() != targetType.GetSize())\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (storeInSetter.Variable.Type.GetSign() != targetType.GetSign())\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tILInstruction newInst;\n\t\t\tif (UnwrapSmallIntegerConv(setterValue, out var smallIntConv) is BinaryNumericInstruction binary)\n\t\t\t{\n\t\t\t\tif (compoundStore is StLoc)\n\t\t\t\t{\n\t\t\t\t\t// transform local variables only for user-defined operators\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (!IsMatchingCompoundLoad(binary.Left, compoundStore, out var target, out var targetKind, out var finalizeMatch, forbiddenVariable: storeInSetter?.Variable))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!ValidateCompoundAssign(binary, smallIntConv, targetType, context.Settings))\n\t\t\t\t\treturn false;\n\t\t\t\tcontext.Step($\"Compound assignment (binary.numeric)\", compoundStore);\n\t\t\t\tfinalizeMatch?.Invoke(context);\n\t\t\t\tnewInst = new NumericCompoundAssign(\n\t\t\t\t\tbinary, target, targetKind, binary.Right,\n\t\t\t\t\ttargetType, CompoundEvalMode.EvaluatesToNewValue);\n\t\t\t}\n\t\t\telse if (setterValue is Call operatorCall && operatorCall.Method.IsOperator)\n\t\t\t{\n\t\t\t\tif (operatorCall.Arguments.Count == 0)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!IsMatchingCompoundLoad(operatorCall.Arguments[0], compoundStore, out var target, out var targetKind, out var finalizeMatch, forbiddenVariable: storeInSetter?.Variable))\n\t\t\t\t\treturn false;\n\t\t\t\tILInstruction rhs;\n\t\t\t\tif (operatorCall.Arguments.Count == 2)\n\t\t\t\t{\n\t\t\t\t\tif (CSharp.ExpressionBuilder.GetAssignmentOperatorTypeFromMetadataName(operatorCall.Method.Name, context.Settings) == null)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\trhs = operatorCall.Arguments[1];\n\t\t\t\t}\n\t\t\t\telse if (operatorCall.Arguments.Count == 1)\n\t\t\t\t{\n\t\t\t\t\tif (!UserDefinedCompoundAssign.IsIncrementOrDecrement(operatorCall.Method, context.Settings))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t// use a dummy node so that we don't need a dedicated instruction for user-defined unary operator calls\n\t\t\t\t\trhs = new LdcI4(1);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (operatorCall.IsLifted)\n\t\t\t\t\treturn false; // TODO: add tests and think about whether nullables need special considerations\n\t\t\t\tcontext.Step($\"Compound assignment (user-defined binary)\", compoundStore);\n\t\t\t\tfinalizeMatch?.Invoke(context);\n\t\t\t\tnewInst = new UserDefinedCompoundAssign(operatorCall.Method, CompoundEvalMode.EvaluatesToNewValue,\n\t\t\t\t\ttarget, targetKind, rhs);\n\t\t\t}\n\t\t\telse if (setterValue is DynamicBinaryOperatorInstruction dynamicBinaryOp)\n\t\t\t{\n\t\t\t\tif (!IsMatchingCompoundLoad(dynamicBinaryOp.Left, compoundStore, out var target, out var targetKind, out var finalizeMatch, forbiddenVariable: storeInSetter?.Variable))\n\t\t\t\t\treturn false;\n\t\t\t\tcontext.Step($\"Compound assignment (dynamic binary)\", compoundStore);\n\t\t\t\tfinalizeMatch?.Invoke(context);\n\t\t\t\tnewInst = new DynamicCompoundAssign(ToCompound(dynamicBinaryOp.Operation), dynamicBinaryOp.BinderFlags, target, dynamicBinaryOp.LeftArgumentInfo, dynamicBinaryOp.Right, dynamicBinaryOp.RightArgumentInfo, targetKind);\n\n\t\t\t\tstatic ExpressionType ToCompound(ExpressionType from)\n\t\t\t\t{\n\t\t\t\t\treturn from switch {\n\t\t\t\t\t\tExpressionType.Add => ExpressionType.AddAssign,\n\t\t\t\t\t\tExpressionType.AddChecked => ExpressionType.AddAssignChecked,\n\t\t\t\t\t\tExpressionType.And => ExpressionType.AndAssign,\n\t\t\t\t\t\tExpressionType.Divide => ExpressionType.DivideAssign,\n\t\t\t\t\t\tExpressionType.ExclusiveOr => ExpressionType.ExclusiveOrAssign,\n\t\t\t\t\t\tExpressionType.LeftShift => ExpressionType.LeftShiftAssign,\n\t\t\t\t\t\tExpressionType.Modulo => ExpressionType.ModuloAssign,\n\t\t\t\t\t\tExpressionType.Multiply => ExpressionType.MultiplyAssign,\n\t\t\t\t\t\tExpressionType.MultiplyChecked => ExpressionType.MultiplyAssignChecked,\n\t\t\t\t\t\tExpressionType.Or => ExpressionType.OrAssign,\n\t\t\t\t\t\tExpressionType.Power => ExpressionType.PowerAssign,\n\t\t\t\t\t\tExpressionType.RightShift => ExpressionType.RightShiftAssign,\n\t\t\t\t\t\tExpressionType.Subtract => ExpressionType.SubtractAssign,\n\t\t\t\t\t\tExpressionType.SubtractChecked => ExpressionType.SubtractAssignChecked,\n\t\t\t\t\t\t_ => from\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (setterValue is Call concatCall && UserDefinedCompoundAssign.IsStringConcat(concatCall.Method))\n\t\t\t{\n\t\t\t\t// setterValue is a string.Concat() invocation\n\t\t\t\tif (compoundStore is StLoc)\n\t\t\t\t{\n\t\t\t\t\t// transform local variables only for user-defined operators\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (concatCall.Arguments.Count != 2)\n\t\t\t\t\treturn false; // for now we only support binary compound assignments\n\t\t\t\tif (!targetType.IsKnownType(KnownTypeCode.String))\n\t\t\t\t\treturn false;\n\t\t\t\tvar arg = concatCall.Arguments[0];\n\t\t\t\tif (arg is Call call && CallBuilder.IsStringToReadOnlySpanCharImplicitConversion(call.Method))\n\t\t\t\t{\n\t\t\t\t\targ = call.Arguments[0];\n\t\t\t\t\tif (!(concatCall.Arguments[1] is NewObj { Arguments: [AddressOf addressOf] } newObj) || !ILInlining.IsReadOnlySpanCharCtor(newObj.Method))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!IsMatchingCompoundLoad(arg, compoundStore, out var target, out var targetKind, out var finalizeMatch, forbiddenVariable: storeInSetter?.Variable))\n\t\t\t\t\treturn false;\n\t\t\t\tcontext.Step($\"Compound assignment (string concatenation)\", compoundStore);\n\t\t\t\tfinalizeMatch?.Invoke(context);\n\t\t\t\tnewInst = new UserDefinedCompoundAssign(concatCall.Method, CompoundEvalMode.EvaluatesToNewValue,\n\t\t\t\t\ttarget, targetKind, concatCall.Arguments[1]);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tnewInst.AddILRange(setterValue);\n\t\t\tif (storeInSetter != null)\n\t\t\t{\n\t\t\t\tstoreInSetter.Value = newInst;\n\t\t\t\tnewInst = storeInSetter;\n\t\t\t\tcontext.RequestRerun(); // moving stloc to top-level might trigger inlining\n\t\t\t}\n\t\t\tcompoundStore.ReplaceWith(newInst);\n\t\t\tif (newInst.Parent is Block inlineAssignBlock && inlineAssignBlock.Kind == BlockKind.CallInlineAssign)\n\t\t\t{\n\t\t\t\t// It's possible that we first replaced the instruction in an inline-assign helper block.\n\t\t\t\t// In such a situation, we know from the block invariant that we're have a storeInSetter.\n\t\t\t\tDebug.Assert(storeInSetter != null);\n\t\t\t\tDebug.Assert(storeInSetter.Variable.IsSingleDefinition && storeInSetter.Variable.LoadCount == 1);\n\t\t\t\tDebug.Assert(inlineAssignBlock.Instructions.Single() == storeInSetter);\n\t\t\t\tDebug.Assert(inlineAssignBlock.FinalInstruction.MatchLdLoc(storeInSetter.Variable));\n\t\t\t\t// Block CallInlineAssign { stloc I_0(compound.op(...)); final: ldloc I_0 }\n\t\t\t\t// --> compound.op(...)\n\t\t\t\tinlineAssignBlock.ReplaceWith(storeInSetter.Value);\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <code>\n\t\t/// stloc s(value)\n\t\t/// stloc l(ldloc s)\n\t\t///   where neither 'stloc s' nor 'stloc l' truncates the value\n\t\t/// -->\n\t\t/// stloc s(stloc l(value))\n\t\t/// </code>\n\t\tbool TransformInlineAssignmentLocal(Block block, int pos)\n\t\t{\n\t\t\tvar inst = block.Instructions[pos] as StLoc;\n\t\t\tvar nextInst = block.Instructions.ElementAtOrDefault(pos + 1) as StLoc;\n\t\t\tif (inst == null || nextInst == null)\n\t\t\t\treturn false;\n\t\t\tif (inst.Variable.Kind != VariableKind.StackSlot)\n\t\t\t\treturn false;\n\t\t\tif (!(nextInst.Variable.Kind == VariableKind.Local || nextInst.Variable.Kind == VariableKind.Parameter))\n\t\t\t\treturn false;\n\t\t\tif (!nextInst.Value.MatchLdLoc(inst.Variable))\n\t\t\t\treturn false;\n\t\t\tif (IsImplicitTruncation(inst.Value, inst.Variable.Type, context.TypeSystem))\n\t\t\t{\n\t\t\t\t// 'stloc s' is implicitly truncating the stack value\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (IsImplicitTruncation(inst.Value, nextInst.Variable.Type, context.TypeSystem))\n\t\t\t{\n\t\t\t\t// 'stloc l' is implicitly truncating the stack value\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (nextInst.Variable.StackType == StackType.Ref)\n\t\t\t{\n\t\t\t\t// ref locals need to be initialized when they are declared, so\n\t\t\t\t// we can only use inline assignments when we know that the\n\t\t\t\t// ref local is definitely assigned.\n\t\t\t\t// We don't have an easy way to check for that in this transform,\n\t\t\t\t// so avoid inline assignments to ref locals for now.\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tcontext.Step(\"Inline assignment to local variable\", inst);\n\t\t\tvar value = inst.Value;\n\t\t\tvar var = nextInst.Variable;\n\t\t\tvar stackVar = inst.Variable;\n\t\t\tblock.Instructions.RemoveAt(pos);\n\t\t\tnextInst.ReplaceWith(new StLoc(stackVar, new StLoc(var, value)));\n\t\t\treturn true;\n\t\t}\n\n\t\tinternal static bool IsImplicitTruncation(ILInstruction value, IType type, ICompilation compilation, bool allowNullableValue = false)\n\t\t{\n\t\t\treturn CheckImplicitTruncation(value, type, compilation, allowNullableValue) != ImplicitTruncationResult.ValuePreserved;\n\t\t}\n\n\t\tinternal enum ImplicitTruncationResult : byte\n\t\t{\n\t\t\t/// <summary>\n\t\t\t/// The value is not implicitly truncated.\n\t\t\t/// </summary>\n\t\t\tValuePreserved,\n\t\t\t/// <summary>\n\t\t\t/// The value is implicitly truncated.\n\t\t\t/// </summary>\n\t\t\tValueChanged,\n\t\t\t/// <summary>\n\t\t\t/// The value is implicitly truncated, but the sign of the target type can be changed to remove the truncation.\n\t\t\t/// </summary>\n\t\t\tValueChangedDueToSignMismatch\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether 'stobj type(..., value)' would evaluate to a different value than 'value'\n\t\t/// due to implicit truncation.\n\t\t/// </summary>\n\t\tinternal static ImplicitTruncationResult CheckImplicitTruncation(ILInstruction value, IType type, ICompilation compilation, bool allowNullableValue = false)\n\t\t{\n\t\t\tif (!type.IsSmallIntegerType())\n\t\t\t{\n\t\t\t\t// Implicit truncation in ILAst only happens for small integer types;\n\t\t\t\t// other types of implicit truncation in IL cause the ILReader to insert\n\t\t\t\t// conv instructions.\n\t\t\t\treturn ImplicitTruncationResult.ValuePreserved;\n\t\t\t}\n\t\t\t// With small integer types, test whether the value might be changed by\n\t\t\t// truncation (based on type.GetSize()) followed by sign/zero extension (based on type.GetSign()).\n\t\t\t// (it's OK to have false-positives here if we're unsure)\n\t\t\tif (value.MatchLdcI4(out int val))\n\t\t\t{\n\t\t\t\tbool valueFits = (type.GetEnumUnderlyingType().GetDefinition()?.KnownTypeCode) switch {\n\t\t\t\t\tKnownTypeCode.Boolean => val == 0 || val == 1,\n\t\t\t\t\tKnownTypeCode.Byte => val >= byte.MinValue && val <= byte.MaxValue,\n\t\t\t\t\tKnownTypeCode.SByte => val >= sbyte.MinValue && val <= sbyte.MaxValue,\n\t\t\t\t\tKnownTypeCode.Int16 => val >= short.MinValue && val <= short.MaxValue,\n\t\t\t\t\tKnownTypeCode.UInt16 or KnownTypeCode.Char => val >= ushort.MinValue && val <= ushort.MaxValue,\n\t\t\t\t\t_ => false\n\t\t\t\t};\n\t\t\t\treturn valueFits ? ImplicitTruncationResult.ValuePreserved : ImplicitTruncationResult.ValueChanged;\n\t\t\t}\n\t\t\telse if (value is Conv conv)\n\t\t\t{\n\t\t\t\tPrimitiveType primitiveType = type.ToPrimitiveType();\n\t\t\t\tPrimitiveType convTargetType = conv.TargetType;\n\t\t\t\tif (convTargetType == primitiveType)\n\t\t\t\t\treturn ImplicitTruncationResult.ValuePreserved;\n\t\t\t\tif (primitiveType.GetSize() == convTargetType.GetSize() && primitiveType.GetSign() != convTargetType.GetSign() && primitiveType.HasOppositeSign())\n\t\t\t\t\treturn ImplicitTruncationResult.ValueChangedDueToSignMismatch;\n\t\t\t\treturn ImplicitTruncationResult.ValueChanged;\n\t\t\t}\n\t\t\telse if (value is Comp)\n\t\t\t{\n\t\t\t\treturn ImplicitTruncationResult.ValuePreserved; // comp returns 0 or 1, which always fits\n\t\t\t}\n\t\t\telse if (value is BinaryNumericInstruction bni)\n\t\t\t{\n\t\t\t\tswitch (bni.Operator)\n\t\t\t\t{\n\t\t\t\t\tcase BinaryNumericOperator.BitAnd:\n\t\t\t\t\tcase BinaryNumericOperator.BitOr:\n\t\t\t\t\tcase BinaryNumericOperator.BitXor:\n\t\t\t\t\t\t// If both input values fit into the type without truncation,\n\t\t\t\t\t\t// the result of a binary operator will also fit.\n\t\t\t\t\t\tvar leftTruncation = CheckImplicitTruncation(bni.Left, type, compilation, allowNullableValue);\n\t\t\t\t\t\t// If the left side is truncating and a sign change is not possible we do not need to evaluate the right side\n\t\t\t\t\t\tif (leftTruncation == ImplicitTruncationResult.ValueChanged)\n\t\t\t\t\t\t\treturn ImplicitTruncationResult.ValueChanged;\n\t\t\t\t\t\tvar rightTruncation = CheckImplicitTruncation(bni.Right, type, compilation, allowNullableValue);\n\t\t\t\t\t\treturn CommonImplicitTruncation(leftTruncation, rightTruncation);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (value is IfInstruction ifInst)\n\t\t\t{\n\t\t\t\tvar trueTruncation = CheckImplicitTruncation(ifInst.TrueInst, type, compilation, allowNullableValue);\n\t\t\t\t// If the true branch is truncating and a sign change is not possible we do not need to evaluate the false branch\n\t\t\t\tif (trueTruncation == ImplicitTruncationResult.ValueChanged)\n\t\t\t\t\treturn ImplicitTruncationResult.ValueChanged;\n\t\t\t\tvar falseTruncation = CheckImplicitTruncation(ifInst.FalseInst, type, compilation, allowNullableValue);\n\t\t\t\treturn CommonImplicitTruncation(trueTruncation, falseTruncation);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tIType inferredType = value.InferType(compilation);\n\t\t\t\tif (allowNullableValue)\n\t\t\t\t{\n\t\t\t\t\tinferredType = NullableType.GetUnderlyingType(inferredType);\n\t\t\t\t}\n\t\t\t\tif (inferredType.Kind != TypeKind.Unknown)\n\t\t\t\t{\n\t\t\t\t\tvar inferredPrimitive = inferredType.ToPrimitiveType();\n\t\t\t\t\tvar primitiveType = type.ToPrimitiveType();\n\n\t\t\t\t\tbool sameSign = inferredPrimitive.GetSign() == primitiveType.GetSign();\n\t\t\t\t\tif (inferredPrimitive.GetSize() <= primitiveType.GetSize() && sameSign)\n\t\t\t\t\t\treturn ImplicitTruncationResult.ValuePreserved;\n\t\t\t\t\tif (inferredPrimitive.GetSize() == primitiveType.GetSize() && !sameSign && primitiveType.HasOppositeSign())\n\t\t\t\t\t\treturn ImplicitTruncationResult.ValueChangedDueToSignMismatch;\n\t\t\t\t\treturn ImplicitTruncationResult.ValueChanged;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// In unknown cases, assume that the value might be changed by truncation.\n\t\t\treturn ImplicitTruncationResult.ValueChanged;\n\t\t}\n\n\t\tprivate static ImplicitTruncationResult CommonImplicitTruncation(ImplicitTruncationResult left, ImplicitTruncationResult right)\n\t\t{\n\t\t\tif (left == right)\n\t\t\t\treturn left;\n\t\t\t// Note: in all cases where left!=right, we return ValueChanged:\n\t\t\t// if only one side can be fixed by changing the sign, we don't want to change the sign of the other side.\n\t\t\treturn ImplicitTruncationResult.ValueChanged;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether 'inst' is a possible store for use as a compound store.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Output parameters:\n\t\t/// storeType: The type of the value being stored.\n\t\t/// value: The value being stored (will be analyzed further to detect compound assignments)\n\t\t/// \n\t\t/// Every IsCompoundStore() call should be followed by an IsMatchingCompoundLoad() call.\n\t\t/// </remarks>\n\t\tstatic bool IsCompoundStore(ILInstruction inst, out IType storeType,\n\t\t\tout ILInstruction value, ICompilation compilation)\n\t\t{\n\t\t\tvalue = null;\n\t\t\tstoreType = null;\n\t\t\tif (inst is StObj stobj)\n\t\t\t{\n\t\t\t\t// stobj.Type may just be 'int' (due to stind.i4) when we're actually operating on a 'ref MyEnum'.\n\t\t\t\t// Try to determine the real type of the object we're modifying:\n\t\t\t\tstoreType = stobj.Target.InferType(compilation);\n\t\t\t\tif (storeType is ByReferenceType refType)\n\t\t\t\t{\n\t\t\t\t\tif (TypeUtils.IsCompatibleTypeForMemoryAccess(refType.ElementType, stobj.Type))\n\t\t\t\t\t{\n\t\t\t\t\t\tstoreType = refType.ElementType;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tstoreType = stobj.Type;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (storeType is PointerType pointerType)\n\t\t\t\t{\n\t\t\t\t\tif (TypeUtils.IsCompatibleTypeForMemoryAccess(pointerType.ElementType, stobj.Type))\n\t\t\t\t\t{\n\t\t\t\t\t\tstoreType = pointerType.ElementType;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tstoreType = stobj.Type;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tstoreType = stobj.Type;\n\t\t\t\t}\n\t\t\t\tvalue = stobj.Value;\n\t\t\t\treturn SemanticHelper.IsPure(stobj.Target.Flags);\n\t\t\t}\n\t\t\telse if (inst is CallInstruction call && (call.OpCode == OpCode.Call || call.OpCode == OpCode.CallVirt))\n\t\t\t{\n\t\t\t\tif (call.Method.Parameters.Count == 0)\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tforeach (var arg in call.Arguments.SkipLast(1))\n\t\t\t\t{\n\t\t\t\t\tif (arg.MatchStLoc(out var v) && v.IsSingleDefinition && v.LoadCount == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue; // OK, IsMatchingCompoundLoad can perform an adjustment in this special case\n\t\t\t\t\t}\n\t\t\t\t\tif (!SemanticHelper.IsPure(arg.Flags))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstoreType = call.Method.Parameters.Last().Type;\n\t\t\t\tvalue = call.Arguments.Last();\n\t\t\t\treturn IsSameMember(call.Method, (call.Method.AccessorOwner as IProperty)?.Setter);\n\t\t\t}\n\t\t\telse if (inst is StLoc stloc && (stloc.Variable.Kind == VariableKind.Local || stloc.Variable.Kind == VariableKind.Parameter))\n\t\t\t{\n\t\t\t\tstoreType = stloc.Variable.Type;\n\t\t\t\tvalue = stloc.Value;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Checks whether 'load' and 'store' both access the same store, and can be combined to a compound assignment.\n\t\t/// </summary>\n\t\t/// <param name=\"load\">The load instruction to test.</param>\n\t\t/// <param name=\"store\">The compound store to test against. Must have previously been tested via IsCompoundStore()</param>\n\t\t/// <param name=\"target\">The target to use for the compound assignment instruction.</param>\n\t\t/// <param name=\"targetKind\">The target kind to use for the compound assignment instruction.</param>\n\t\t/// <param name=\"finalizeMatch\">If set to a non-null value, call this delegate to fix up minor mismatches between getter and setter.</param>\n\t\t/// <param name=\"forbiddenVariable\">\n\t\t/// If given a non-null value, this function returns false if the forbiddenVariable is used in the load/store instructions.\n\t\t/// Some transforms effectively move a store around,\n\t\t/// which is only valid if the variable stored to does not occur in the compound load/store.\n\t\t/// </param>\n\t\t/// <param name=\"previousInstruction\">\n\t\t/// Instruction preceding the load.\n\t\t/// </param>\n\t\tstatic bool IsMatchingCompoundLoad(ILInstruction load, ILInstruction store,\n\t\t\tout ILInstruction target, out CompoundTargetKind targetKind,\n\t\t\tout Action<ILTransformContext> finalizeMatch,\n\t\t\tILVariable forbiddenVariable = null,\n\t\t\tILInstruction previousInstruction = null)\n\t\t{\n\t\t\ttarget = null;\n\t\t\ttargetKind = 0;\n\t\t\tfinalizeMatch = null;\n\t\t\tif (load is LdObj ldobj && store is StObj stobj)\n\t\t\t{\n\t\t\t\tDebug.Assert(SemanticHelper.IsPure(stobj.Target.Flags));\n\t\t\t\tif (!SemanticHelper.IsPure(ldobj.Target.Flags))\n\t\t\t\t\treturn false;\n\t\t\t\tif (forbiddenVariable != null && forbiddenVariable.IsUsedWithin(ldobj.Target))\n\t\t\t\t\treturn false;\n\t\t\t\ttarget = ldobj.Target;\n\t\t\t\ttargetKind = CompoundTargetKind.Address;\n\t\t\t\tif (ldobj.Target.Match(stobj.Target).Success)\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse if (IsDuplicatedAddressComputation(stobj.Target, ldobj.Target))\n\t\t\t\t{\n\t\t\t\t\t// Use S_0 as target, so that S_0 can later be eliminated by inlining.\n\t\t\t\t\t// (we can't eliminate previousInstruction right now, because it's before the transform's starting instruction)\n\t\t\t\t\ttarget = stobj.Target;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (MatchingGetterAndSetterCalls(load as CallInstruction, store as CallInstruction, out finalizeMatch))\n\t\t\t{\n\t\t\t\tif (forbiddenVariable != null && forbiddenVariable.IsUsedWithin(load))\n\t\t\t\t\treturn false;\n\t\t\t\ttarget = load;\n\t\t\t\ttargetKind = CompoundTargetKind.Property;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (load is LdLoc ldloc && store is StLoc stloc && ILVariableEqualityComparer.Instance.Equals(ldloc.Variable, stloc.Variable))\n\t\t\t{\n\t\t\t\tif (ILVariableEqualityComparer.Instance.Equals(ldloc.Variable, forbiddenVariable))\n\t\t\t\t\treturn false;\n\t\t\t\ttarget = new LdLoca(ldloc.Variable).WithILRange(ldloc);\n\t\t\t\ttargetKind = CompoundTargetKind.Address;\n\t\t\t\tfinalizeMatch = context => context.Function.RecombineVariables(ldloc.Variable, stloc.Variable);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tbool IsDuplicatedAddressComputation(ILInstruction storeTarget, ILInstruction loadTarget)\n\t\t\t{\n\t\t\t\t// Sometimes roslyn duplicates the address calculation:\n\t\t\t\t// stloc S_0(ldloc refParam)\n\t\t\t\t// stloc V_0(ldobj System.Int32(ldloc refParam))\n\t\t\t\t// stobj System.Int32(ldloc S_0, binary.add.i4(ldloc V_0, ldc.i4 1))\n\t\t\t\twhile (storeTarget is LdFlda storeLdFlda && loadTarget is LdFlda loadLdFlda)\n\t\t\t\t{\n\t\t\t\t\tif (!storeLdFlda.Field.Equals(loadLdFlda.Field))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tstoreTarget = storeLdFlda.Target;\n\t\t\t\t\tloadTarget = loadLdFlda.Target;\n\t\t\t\t}\n\t\t\t\tif (!storeTarget.MatchLdLoc(out var s))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!(s.Kind == VariableKind.StackSlot && s.IsSingleDefinition && s != forbiddenVariable))\n\t\t\t\t\treturn false;\n\t\t\t\tif (s.StoreInstructions.SingleOrDefault() != previousInstruction)\n\t\t\t\t\treturn false;\n\t\t\t\treturn previousInstruction is StLoc addressStore && addressStore.Value.Match(loadTarget).Success;\n\t\t\t}\n\t\t}\n\n\t\t/// <code>\n\t\t/// stloc l(stloc target(binary.add(ldloc target, ldc.i4 1)))\n\t\t/// </code>\n\t\tbool TransformPreIncDecOperatorWithInlineStore(Block block, int pos)\n\t\t{\n\t\t\tvar store = block.Instructions[pos];\n\t\t\tif (!IsCompoundStore(store, out var targetType1, out var value1, context.TypeSystem))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!IsCompoundStore(value1, out var targetType2, out var value2, context.TypeSystem))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (targetType1 != targetType2)\n\t\t\t\treturn false;\n\t\t\tvar targetType = targetType1;\n\t\t\tvar stloc_outer = store as StLoc;\n\t\t\tvar stloc_inner = value1 as StLoc;\n\t\t\tLdLoc ldloc;\n\t\t\tvar binary = UnwrapSmallIntegerConv(value2, out var conv) as BinaryNumericInstruction;\n\t\t\tif (binary != null && (binary.Right.MatchLdcI(1) || binary.Right.MatchLdcF4(1) || binary.Right.MatchLdcF8(1)))\n\t\t\t{\n\t\t\t\tif (!(binary.Operator == BinaryNumericOperator.Add || binary.Operator == BinaryNumericOperator.Sub))\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (conv is not null)\n\t\t\t\t{\n\t\t\t\t\tvar primitiveType = targetType.ToPrimitiveType();\n\t\t\t\t\tif (primitiveType.GetSize() == conv.TargetType.GetSize() && primitiveType.GetSign() != conv.TargetType.GetSign())\n\t\t\t\t\t\ttargetType = SwapSign(targetType, context.TypeSystem);\n\t\t\t\t}\n\n\t\t\t\tif (!ValidateCompoundAssign(binary, conv, targetType, context.Settings))\n\t\t\t\t\treturn false;\n\t\t\t\tldloc = binary.Left as LdLoc;\n\t\t\t}\n\t\t\telse if (value2 is Call operatorCall && operatorCall.Method.IsOperator && operatorCall.Arguments.Count == 1)\n\t\t\t{\n\t\t\t\tif (!(operatorCall.Method.Name == \"op_Increment\" || operatorCall.Method.Name == \"op_Decrement\"))\n\t\t\t\t\treturn false;\n\t\t\t\tif (operatorCall.IsLifted)\n\t\t\t\t\treturn false; // TODO: add tests and think about whether nullables need special considerations\n\t\t\t\tldloc = operatorCall.Arguments[0] as LdLoc;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (stloc_outer == null)\n\t\t\t\treturn false;\n\t\t\tif (stloc_inner == null)\n\t\t\t\treturn false;\n\t\t\tif (ldloc == null)\n\t\t\t\treturn false;\n\t\t\tif (!(stloc_outer.Variable.Kind == VariableKind.Local || stloc_outer.Variable.Kind == VariableKind.StackSlot))\n\t\t\t\treturn false;\n\t\t\tif (!IsMatchingCompoundLoad(ldloc, stloc_inner, out var target, out var targetKind, out var finalizeMatch))\n\t\t\t\treturn false;\n\t\t\tif (IsImplicitTruncation(stloc_outer.Value, stloc_outer.Variable.Type, context.TypeSystem))\n\t\t\t\treturn false;\n\t\t\tcontext.Step(nameof(TransformPreIncDecOperatorWithInlineStore), store);\n\t\t\tfinalizeMatch?.Invoke(context);\n\t\t\tif (binary != null)\n\t\t\t{\n\t\t\t\tblock.Instructions[pos] = new StLoc(stloc_outer.Variable, new NumericCompoundAssign(\n\t\t\t\t\tbinary, target, targetKind, binary.Right, targetType, CompoundEvalMode.EvaluatesToNewValue));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tCall operatorCall = (Call)value2;\n\t\t\t\tblock.Instructions[pos] = new StLoc(stloc_outer.Variable, new UserDefinedCompoundAssign(\n\t\t\t\t\toperatorCall.Method, CompoundEvalMode.EvaluatesToNewValue, target, targetKind, new LdcI4(1)));\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <code>\n\t\t/// stobj(target, binary.add(stloc l(ldobj(target)), ldc.i4 1))\n\t\t///   where target is pure and does not use 'l', and the 'stloc l' does not truncate\n\t\t/// -->\n\t\t/// stloc l(compound.op.old(ldobj(target), ldc.i4 1))\n\t\t/// \n\t\t///  -or-\n\t\t/// \n\t\t/// call set_Prop(args..., binary.add(stloc l(call get_Prop(args...)), ldc.i4 1))\n\t\t///   where args.. are pure and do not use 'l', and the 'stloc l' does not truncate\n\t\t/// -->\n\t\t/// stloc l(compound.op.old(call get_Prop(target), ldc.i4 1))\n\t\t/// </code>\n\t\t/// <remarks>\n\t\t/// This pattern is used for post-increment by legacy csc.\n\t\t/// \n\t\t/// Even though this transform operates only on a single expression, it's not an expression transform\n\t\t/// as the result value of the expression changes (this is OK only for statements in a block).\n\t\t/// </remarks>\n\t\tbool TransformPostIncDecOperatorWithInlineStore(Block block, int pos)\n\t\t{\n\t\t\tvar store = block.Instructions[pos];\n\t\t\tif (!IsCompoundStore(store, out var targetType, out var value, context.TypeSystem))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tStLoc stloc;\n\t\t\tvar binary = UnwrapSmallIntegerConv(value, out var conv) as BinaryNumericInstruction;\n\t\t\tif (binary != null && (binary.Right.MatchLdcI(1) || binary.Right.MatchLdcF4(1) || binary.Right.MatchLdcF8(1)))\n\t\t\t{\n\t\t\t\tif (!(binary.Operator == BinaryNumericOperator.Add || binary.Operator == BinaryNumericOperator.Sub))\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (conv is not null)\n\t\t\t\t{\n\t\t\t\t\tvar primitiveType = targetType.ToPrimitiveType();\n\t\t\t\t\tif (primitiveType.GetSize() == conv.TargetType.GetSize() && primitiveType.GetSign() != conv.TargetType.GetSign())\n\t\t\t\t\t\ttargetType = SwapSign(targetType, context.TypeSystem);\n\t\t\t\t}\n\n\t\t\t\tif (!ValidateCompoundAssign(binary, conv, targetType, context.Settings))\n\t\t\t\t\treturn false;\n\t\t\t\tstloc = binary.Left as StLoc;\n\t\t\t}\n\t\t\telse if (value is Call operatorCall && operatorCall.Method.IsOperator && operatorCall.Arguments.Count == 1)\n\t\t\t{\n\t\t\t\tif (!(operatorCall.Method.Name == \"op_Increment\" || operatorCall.Method.Name == \"op_Decrement\"))\n\t\t\t\t\treturn false;\n\t\t\t\tif (operatorCall.IsLifted)\n\t\t\t\t\treturn false; // TODO: add tests and think about whether nullables need special considerations\n\t\t\t\tstloc = operatorCall.Arguments[0] as StLoc;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (stloc == null)\n\t\t\t\treturn false;\n\t\t\tif (!(stloc.Variable.Kind == VariableKind.Local || stloc.Variable.Kind == VariableKind.StackSlot))\n\t\t\t\treturn false;\n\t\t\tif (!IsMatchingCompoundLoad(stloc.Value, store, out var target, out var targetKind, out var finalizeMatch, forbiddenVariable: stloc.Variable))\n\t\t\t\treturn false;\n\t\t\tif (IsImplicitTruncation(stloc.Value, stloc.Variable.Type, context.TypeSystem))\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"TransformPostIncDecOperatorWithInlineStore\", store);\n\t\t\tfinalizeMatch?.Invoke(context);\n\t\t\tif (binary != null)\n\t\t\t{\n\t\t\t\tblock.Instructions[pos] = new StLoc(stloc.Variable, new NumericCompoundAssign(\n\t\t\t\t\tbinary, target, targetKind, binary.Right, targetType, CompoundEvalMode.EvaluatesToOldValue));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tCall operatorCall = (Call)value;\n\t\t\t\tblock.Instructions[pos] = new StLoc(stloc.Variable, new UserDefinedCompoundAssign(\n\t\t\t\t\toperatorCall.Method, CompoundEvalMode.EvaluatesToOldValue, target, targetKind, new LdcI4(1)));\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <code>\n\t\t/// stloc tmp(ldobj(target))\n\t\t/// stobj(target, binary.op(ldloc tmp, ldc.i4 1))\n\t\t///   target is pure and does not use 'tmp', 'stloc does not truncate'\n\t\t/// -->\n\t\t/// stloc tmp(compound.op.old(ldobj(target), ldc.i4 1))\n\t\t/// </code>\n\t\t/// This is usually followed by inlining or eliminating 'tmp'.\n\t\t/// \n\t\t/// Local variables use a similar pattern, also detected by this function:\n\t\t/// <code>\n\t\t/// stloc tmp(ldloc target)\n\t\t/// stloc target(binary.op(ldloc tmp, ldc.i4 1))\n\t\t/// -->\n\t\t/// stloc tmp(compound.op.old(ldloca target, ldc.i4 1))\n\t\t/// </code>\n\t\t/// <remarks>\n\t\t/// This pattern occurs with legacy csc for static fields, and with Roslyn for most post-increments.\n\t\t/// </remarks>\n\t\tbool TransformPostIncDecOperator(Block block, int i)\n\t\t{\n\t\t\tvar inst = block.Instructions[i] as StLoc;\n\t\t\tvar store = block.Instructions.ElementAtOrDefault(i + 1);\n\t\t\tif (inst == null || store == null)\n\t\t\t\treturn false;\n\t\t\tvar tmpVar = inst.Variable;\n\t\t\tif (!IsCompoundStore(store, out var targetType, out var value, context.TypeSystem))\n\t\t\t\treturn false;\n\t\t\tvar truncation = CheckImplicitTruncation(inst.Value, targetType, context.TypeSystem);\n\t\t\tif (truncation == ImplicitTruncationResult.ValueChanged)\n\t\t\t{\n\t\t\t\t// 'stloc tmp' is implicitly truncating the value\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (truncation == ImplicitTruncationResult.ValueChangedDueToSignMismatch)\n\t\t\t{\n\t\t\t\tif (!(store is StObj stObj && stObj.Type.Equals(targetType)))\n\t\t\t\t{\n\t\t\t\t\t// We cannot apply the sign change, so we can't fix the truncation\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!IsMatchingCompoundLoad(inst.Value, store, out var target, out var targetKind, out var finalizeMatch,\n\t\t\t\tforbiddenVariable: inst.Variable,\n\t\t\t\tpreviousInstruction: block.Instructions.ElementAtOrDefault(i - 1)))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (UnwrapSmallIntegerConv(value, out var conv) is BinaryNumericInstruction binary)\n\t\t\t{\n\t\t\t\tif (!(binary.Operator == BinaryNumericOperator.Add || binary.Operator == BinaryNumericOperator.Sub))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!binary.Left.MatchLdLoc(tmpVar))\n\t\t\t\t\treturn false;\n\t\t\t\tif (targetType is PointerType ptrType)\n\t\t\t\t{\n\t\t\t\t\tvar right = PointerArithmeticOffset.Detect(binary.Right, ptrType.ElementType, binary.CheckForOverflow);\n\t\t\t\t\tif (right is null || !right.MatchLdcI(1))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse if (!(binary.Right.MatchLdcI(1) || binary.Right.MatchLdcF4(1) || binary.Right.MatchLdcF8(1)))\n\t\t\t\t\treturn false;\n\t\t\t\tif (truncation == ImplicitTruncationResult.ValueChangedDueToSignMismatch && store is StObj stObj)\n\t\t\t\t{\n\t\t\t\t\t// Change the sign of the type to skip implicit truncation\n\t\t\t\t\tstObj.Type = targetType = SwapSign(targetType, context.TypeSystem);\n\t\t\t\t}\n\t\t\t\tif (!ValidateCompoundAssign(binary, conv, targetType, context.Settings))\n\t\t\t\t\treturn false;\n\t\t\t\tcontext.Step(\"TransformPostIncDecOperator (builtin)\", inst);\n\t\t\t\tfinalizeMatch?.Invoke(context);\n\t\t\t\tinst.Value = new NumericCompoundAssign(binary, target, targetKind, binary.Right,\n\t\t\t\t\ttargetType, CompoundEvalMode.EvaluatesToOldValue);\n\t\t\t}\n\t\t\telse if (value is Call operatorCall && operatorCall.Method.IsOperator && operatorCall.Arguments.Count == 1)\n\t\t\t{\n\t\t\t\tif (!operatorCall.Arguments[0].MatchLdLoc(tmpVar))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!UserDefinedCompoundAssign.IsIncrementOrDecrement(operatorCall.Method, context.Settings))\n\t\t\t\t\treturn false;\n\t\t\t\tif (operatorCall.IsLifted)\n\t\t\t\t\treturn false; // TODO: add tests and think about whether nullables need special considerations\n\t\t\t\tcontext.Step(\"TransformPostIncDecOperator (user-defined)\", inst);\n\t\t\t\tDebug.Assert(truncation == ImplicitTruncationResult.ValuePreserved);\n\t\t\t\tfinalizeMatch?.Invoke(context);\n\t\t\t\tinst.Value = new UserDefinedCompoundAssign(operatorCall.Method,\n\t\t\t\t\tCompoundEvalMode.EvaluatesToOldValue, target, targetKind, new LdcI4(1));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tblock.Instructions.RemoveAt(i + 1);\n\t\t\tif (inst.Variable.IsSingleDefinition && inst.Variable.LoadCount == 0)\n\t\t\t{\n\t\t\t\t// dead store -> it was a statement-level post-increment\n\t\t\t\tinst.ReplaceWith(inst.Value);\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic bool IsSameMember(IMember a, IMember b)\n\t\t{\n\t\t\tif (a == null || b == null)\n\t\t\t\treturn false;\n\t\t\ta = a.MemberDefinition;\n\t\t\tb = b.MemberDefinition;\n\t\t\treturn a.Equals(b);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs",
    "content": "// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Resolver;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Transforms collection and object initialization patterns.\n\t/// </summary>\n\tpublic class TransformCollectionAndObjectInitializers : IStatementTransform\n\t{\n\t\tvoid IStatementTransform.Run(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.ObjectOrCollectionInitializers)\n\t\t\t\treturn;\n\t\t\tILInstruction inst = block.Instructions[pos];\n\t\t\t// Match stloc(v, newobj)\n\t\t\tif (!inst.MatchStLoc(out var v, out var initInst) || v.Kind != VariableKind.Local && v.Kind != VariableKind.StackSlot)\n\t\t\t\treturn;\n\t\t\tIType instType;\n\t\t\tvar blockKind = BlockKind.CollectionInitializer;\n\t\t\tvar insertionPos = initInst.ChildIndex;\n\t\t\tvar siblings = initInst.Parent!.Children;\n\t\t\tIMethod currentMethod = context.Function.Method!;\n\t\t\t// we allow a castclass instruction to wrap the init instruction:\n\t\t\t// this is needed, for example, for inherited record types used on .NET runtimes (e.g., .NET 4.x),\n\t\t\t// where covariant return types are not supported.\n\t\t\tif (initInst.MatchCastClass(out var arg, out var targetType))\n\t\t\t{\n\t\t\t\tinitInst = arg;\n\t\t\t}\n\t\t\tswitch (initInst)\n\t\t\t{\n\t\t\t\tcase NewObj newObjInst:\n\t\t\t\t\tif (newObjInst.ILStackWasEmpty && v.Kind == VariableKind.Local\n\t\t\t\t\t\t&& !TypeContainsInitOnlyProperties(newObjInst.Method.DeclaringTypeDefinition)\n\t\t\t\t\t\t&& !currentMethod.IsConstructor\n\t\t\t\t\t\t&& !currentMethod.IsCompilerGeneratedOrIsInCompilerGeneratedClass())\n\t\t\t\t\t{\n\t\t\t\t\t\t// on statement level (no other expressions on IL stack),\n\t\t\t\t\t\t// prefer to keep local variables (but not stack slots),\n\t\t\t\t\t\t// unless we are in a constructor (where inlining object initializers might be critical\n\t\t\t\t\t\t// for the base ctor call) or a compiler-generated delegate method, which might be used in a query expression.\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// Do not try to transform delegate construction.\n\t\t\t\t\t// DelegateConstruction transform cannot deal with this.\n\t\t\t\t\tif (DelegateConstruction.MatchDelegateConstruction(newObjInst, out _, out _, out _)\n\t\t\t\t\t\t|| TransformDisplayClassUsage.IsPotentialClosure(context, newObjInst))\n\t\t\t\t\t\treturn;\n\t\t\t\t\t// Cannot build a collection/object initializer attached to an AnonymousTypeCreateExpression\n\t\t\t\t\t// anon = new { A = 5 } { 3,4,5 } is invalid syntax.\n\t\t\t\t\tif (newObjInst.Method.DeclaringType.ContainsAnonymousType())\n\t\t\t\t\t\treturn;\n\t\t\t\t\t// Tuples cannot have initializers\n\t\t\t\t\tif (TupleTransform.MatchTupleConstruction(newObjInst, out _))\n\t\t\t\t\t\treturn;\n\t\t\t\t\tinstType = newObjInst.Method.DeclaringType;\n\t\t\t\t\tbreak;\n\t\t\t\tcase DefaultValue defaultVal:\n\t\t\t\t\tinstType = defaultVal.Type;\n\t\t\t\t\tbreak;\n\t\t\t\tcase Call c when c.Method.FullNameIs(\"System.Activator\", \"CreateInstance\") && c.Method.TypeArguments.Count == 1:\n\t\t\t\t\tif (!context.Settings.UseObjectCreationOfGenericTypeParameter)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tinstType = c.Method.TypeArguments[0];\n\t\t\t\t\tblockKind = BlockKind.ObjectInitializer;\n\t\t\t\t\tbreak;\n\t\t\t\tcase CallInstruction ci when context.Settings.WithExpressions && IsRecordCloneMethodCall(ci):\n\t\t\t\t\tinstType = ci.Method.DeclaringType;\n\t\t\t\t\tblockKind = BlockKind.WithInitializer;\n\t\t\t\t\tinitInst = ci.Arguments.Single();\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tvar typeDef = v.Type.GetDefinition();\n\t\t\t\t\tif (context.Settings.WithExpressions && typeDef?.IsReferenceType == false && typeDef.IsRecord)\n\t\t\t\t\t{\n\t\t\t\t\t\tinstType = v.Type;\n\t\t\t\t\t\tblockKind = BlockKind.WithInitializer;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (targetType != null)\n\t\t\t{\n\t\t\t\tinstType = targetType;\n\t\t\t}\n\t\t\t// Copy-propagate stack slot holding an 'ldloca' of the variable\n\t\t\tif (pos < block.Instructions.Count && block.Instructions[pos + 1] is StLoc { Variable: { Kind: VariableKind.StackSlot, IsSingleDefinition: true }, Value: LdLoca ldLoca } stLocStack && ldLoca.Variable == v)\n\t\t\t{\n\t\t\t\tCopyPropagation.Propagate(stLocStack, context);\n\t\t\t}\n\t\t\tint initializerItemsCount = 0;\n\t\t\tbool initializerContainsInitOnlyItems = false;\n\t\t\tpossibleIndexVariables.Clear();\n\t\t\tcurrentPath.Clear();\n\t\t\tisCollection = false;\n\t\t\tpathStack.Clear();\n\t\t\tpathStack.Push(new HashSet<AccessPathElement>());\n\t\t\t// Detect initializer type by scanning the following statements\n\t\t\t// each must be a callvirt with ldloc v as first argument\n\t\t\t// if the method is a setter we're dealing with an object initializer\n\t\t\t// if the method is named Add and has at least 2 arguments we're dealing with a collection/dictionary initializer\n\t\t\twhile (pos + initializerItemsCount + 1 < block.Instructions.Count\n\t\t\t\t&& IsPartOfInitializer(block.Instructions, pos + initializerItemsCount + 1, v, instType, ref blockKind, ref initializerContainsInitOnlyItems, context))\n\t\t\t{\n\t\t\t\tinitializerItemsCount++;\n\t\t\t}\n\t\t\t// Do not convert the statements into an initializer if there's an incompatible usage of the initializer variable\n\t\t\t// directly after the possible initializer.\n\t\t\tif (!initializerContainsInitOnlyItems && IsMethodCallOnVariable(block.Instructions[pos + initializerItemsCount + 1], v))\n\t\t\t\treturn;\n\t\t\t// Calculate the correct number of statements inside the initializer:\n\t\t\t// All index variables that were used in the initializer have Index set to -1.\n\t\t\t// We fetch the first unused variable from the list and remove all instructions after its\n\t\t\t// first usage (i.e. the init store) from the initializer.\n\t\t\tvar index = possibleIndexVariables.Where(info => info.Value.Index > -1).Min(info => (int?)info.Value.Index);\n\t\t\tif (index != null)\n\t\t\t{\n\t\t\t\tinitializerItemsCount = index.Value - pos - 1;\n\t\t\t}\n\t\t\t// The initializer would be empty, there's nothing to do here.\n\t\t\tif (initializerItemsCount <= 0)\n\t\t\t\treturn;\n\t\t\tcontext.Step(\"CollectionOrObjectInitializer\", inst);\n\t\t\t// Create a new block and final slot (initializer target variable)\n\t\t\tvar initializerBlock = new Block(blockKind);\n\t\t\tILVariable finalSlot = context.Function.RegisterVariable(VariableKind.InitializerTarget, instType);\n\t\t\tinitializerBlock.FinalInstruction = new LdLoc(finalSlot);\n\t\t\tinitializerBlock.Instructions.Add(new StLoc(finalSlot, initInst));\n\t\t\t// Move all instructions to the initializer block.\n\t\t\tfor (int i = 1; i <= initializerItemsCount; i++)\n\t\t\t{\n\t\t\t\tswitch (block.Instructions[i + pos])\n\t\t\t\t{\n\t\t\t\t\tcase CallInstruction call:\n\t\t\t\t\t\tif (!(call is CallVirt || call is Call))\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tvar newCall = call;\n\t\t\t\t\t\tvar newTarget = newCall.Arguments[0];\n\t\t\t\t\t\tforeach (var load in newTarget.Descendants.OfType<IInstructionWithVariableOperand>())\n\t\t\t\t\t\t\tif ((load is LdLoc || load is LdLoca) && load.Variable == v)\n\t\t\t\t\t\t\t\tload.Variable = finalSlot;\n\t\t\t\t\t\tinitializerBlock.Instructions.Add(newCall);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase StObj stObj:\n\t\t\t\t\t\tvar newStObj = stObj;\n\t\t\t\t\t\tforeach (var load in newStObj.Target.Descendants.OfType<IInstructionWithVariableOperand>())\n\t\t\t\t\t\t\tif ((load is LdLoc || load is LdLoca) && load.Variable == v)\n\t\t\t\t\t\t\t\tload.Variable = finalSlot;\n\t\t\t\t\t\tinitializerBlock.Instructions.Add(newStObj);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase StLoc stLoc:\n\t\t\t\t\t\tvar newStLoc = stLoc;\n\t\t\t\t\t\tinitializerBlock.Instructions.Add(newStLoc);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tblock.Instructions.RemoveRange(pos + 1, initializerItemsCount);\n\t\t\tsiblings[insertionPos] = initializerBlock;\n\t\t\tILInlining.InlineIfPossible(block, pos, context);\n\t\t}\n\n\t\tprivate static bool TypeContainsInitOnlyProperties(ITypeDefinition? typeDefinition)\n\t\t{\n\t\t\tforeach (var property in typeDefinition?.Properties ?? [])\n\t\t\t{\n\t\t\t\tif (property.Setter?.IsInitOnly ?? false)\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tinternal static bool IsRecordCloneMethodCall(CallInstruction ci)\n\t\t{\n\t\t\tif (ci.Method.DeclaringTypeDefinition?.IsRecord != true)\n\t\t\t\treturn false;\n\t\t\tif (ci.Method.Name != \"<Clone>$\")\n\t\t\t\treturn false;\n\t\t\tif (ci.Arguments.Count != 1)\n\t\t\t\treturn false;\n\n\t\t\treturn true;\n\t\t}\n\n\t\tbool IsMethodCallOnVariable(ILInstruction inst, ILVariable variable)\n\t\t{\n\t\t\tif (inst.MatchLdLocRef(variable))\n\t\t\t\treturn true;\n\t\t\tif (inst is CallInstruction call && call.Arguments.Count > 0 && !call.Method.IsStatic)\n\t\t\t\treturn IsMethodCallOnVariable(call.Arguments[0], variable);\n\t\t\tif (inst.MatchLdFld(out var target, out _) || inst.MatchStFld(out target, out _, out _) || inst.MatchLdFlda(out target, out _))\n\t\t\t\treturn IsMethodCallOnVariable(target, variable);\n\t\t\treturn false;\n\t\t}\n\n\t\treadonly Dictionary<ILVariable, (int Index, ILInstruction Value)> possibleIndexVariables = new Dictionary<ILVariable, (int Index, ILInstruction Value)>();\n\t\treadonly List<AccessPathElement> currentPath = new List<AccessPathElement>();\n\t\tbool isCollection;\n\t\treadonly Stack<HashSet<AccessPathElement>> pathStack = new Stack<HashSet<AccessPathElement>>();\n\n\t\tbool IsPartOfInitializer(InstructionCollection<ILInstruction> instructions, int pos, ILVariable target, IType rootType, ref BlockKind blockKind, ref bool initializerContainsInitOnlyItems, StatementTransformContext context)\n\t\t{\n\t\t\t// Include any stores to local variables that are single-assigned and do not reference the initializer-variable\n\t\t\t// in the list of possible index variables.\n\t\t\t// Index variables are used to implement dictionary initializers.\n\t\t\tif (instructions[pos] is StLoc stloc && stloc.Variable.Kind == VariableKind.Local && stloc.Variable.IsSingleDefinition)\n\t\t\t{\n\t\t\t\tif (!context.Settings.DictionaryInitializers)\n\t\t\t\t\treturn false;\n\t\t\t\tif (stloc.Value.Descendants.OfType<IInstructionWithVariableOperand>().Any(ld => ld.Variable == target && (ld is LdLoc || ld is LdLoca)))\n\t\t\t\t\treturn false;\n\t\t\t\tpossibleIndexVariables.Add(stloc.Variable, (stloc.ChildIndex, stloc.Value));\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\t(var kind, var newPath, var values, var targetVariable) = AccessPathElement.GetAccessPath(instructions[pos], rootType, context.Settings, context.CSharpResolver, possibleIndexVariables);\n\t\t\tif (kind == AccessPathKind.Invalid || target != targetVariable)\n\t\t\t\treturn false;\n\t\t\t// Treat last element separately:\n\t\t\t// Can either be an Add method call or property setter.\n\t\t\tvar lastElement = newPath.Last();\n\t\t\tnewPath.RemoveLast();\n\t\t\t// Compare new path with current path:\n\t\t\tint minLen = Math.Min(currentPath.Count, newPath.Count);\n\t\t\tint firstDifferenceIndex = 0;\n\t\t\twhile (firstDifferenceIndex < minLen && newPath[firstDifferenceIndex] == currentPath[firstDifferenceIndex])\n\t\t\t\tfirstDifferenceIndex++;\n\t\t\twhile (currentPath.Count > firstDifferenceIndex)\n\t\t\t{\n\t\t\t\tisCollection = false;\n\t\t\t\tcurrentPath.RemoveAt(currentPath.Count - 1);\n\t\t\t\tpathStack.Pop();\n\t\t\t}\n\t\t\twhile (currentPath.Count < newPath.Count)\n\t\t\t{\n\t\t\t\tAccessPathElement newElement = newPath[currentPath.Count];\n\t\t\t\tcurrentPath.Add(newElement);\n\t\t\t\tif (isCollection || !pathStack.Peek().Add(newElement))\n\t\t\t\t\treturn false;\n\t\t\t\tpathStack.Push(new HashSet<AccessPathElement>());\n\t\t\t}\n\t\t\tswitch (kind)\n\t\t\t{\n\t\t\t\tcase AccessPathKind.Adder:\n\t\t\t\t\tisCollection = true;\n\t\t\t\t\tif (pathStack.Peek().Count != 0)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn true;\n\t\t\t\tcase AccessPathKind.Setter:\n\t\t\t\t\tif (isCollection || !pathStack.Peek().Add(lastElement))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (values?.Count != 1 || !IsValidObjectInitializerTarget(currentPath))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (blockKind != BlockKind.ObjectInitializer && blockKind != BlockKind.WithInitializer)\n\t\t\t\t\t\tblockKind = BlockKind.ObjectInitializer;\n\t\t\t\t\tinitializerContainsInitOnlyItems |= lastElement.Member is IProperty { Setter.IsInitOnly: true };\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tbool IsValidObjectInitializerTarget(List<AccessPathElement> path)\n\t\t{\n\t\t\tif (path.Count == 0)\n\t\t\t\treturn true;\n\t\t\tvar element = path.Last();\n\t\t\tvar previous = path.SkipLast(1).LastOrDefault();\n\t\t\tif (element.Member is not IProperty p)\n\t\t\t\treturn true;\n\t\t\tif (!p.IsIndexer)\n\t\t\t\treturn true;\n\t\t\tif (previous != default)\n\t\t\t{\n\t\t\t\treturn NormalizeTypeVisitor.IgnoreNullabilityAndTuples\n\t\t\t\t\t.EquivalentTypes(previous.Member.ReturnType, element.Member.DeclaringType);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic enum AccessPathKind\n\t{\n\t\tInvalid,\n\t\tSetter,\n\t\tAdder\n\t}\n\n\tpublic struct AccessPathElement : IEquatable<AccessPathElement>\n\t{\n\t\tpublic AccessPathElement(OpCode opCode, IMember member, ILInstruction[]? indices = null)\n\t\t{\n\t\t\tthis.OpCode = opCode;\n\t\t\tthis.Member = member;\n\t\t\tthis.Indices = indices;\n\t\t}\n\n\t\tpublic readonly OpCode OpCode;\n\t\tpublic readonly IMember Member;\n\t\tpublic readonly ILInstruction[]? Indices;\n\n\t\tpublic override string ToString() => $\"[{Member}, {Indices}]\";\n\n\t\tpublic static (AccessPathKind Kind, List<AccessPathElement> Path, List<ILInstruction>? Values, ILVariable? Target) GetAccessPath(\n\t\t\tILInstruction instruction, IType rootType, DecompilerSettings? settings = null,\n\t\t\tCSharpResolver? resolver = null,\n\t\t\tDictionary<ILVariable, (int Index, ILInstruction Value)>? possibleIndexVariables = null)\n\t\t{\n\t\t\tList<AccessPathElement> path = new List<AccessPathElement>();\n\t\t\tILVariable? target = null;\n\t\t\tAccessPathKind kind = AccessPathKind.Invalid;\n\t\t\tList<ILInstruction>? values = null;\n\t\t\tIMethod method;\n\t\t\tILInstruction? inst = instruction;\n\t\t\twhile (inst != null)\n\t\t\t{\n\t\t\t\tswitch (inst)\n\t\t\t\t{\n\t\t\t\t\tcase CallInstruction call:\n\t\t\t\t\t\tif (!(call is CallVirt || call is Call))\n\t\t\t\t\t\t\tgoto default;\n\t\t\t\t\t\tmethod = call.Method;\n\t\t\t\t\t\tif (resolver != null && !IsMethodApplicable(method, call.Arguments, rootType, resolver, settings))\n\t\t\t\t\t\t\tgoto default;\n\t\t\t\t\t\tinst = call.Arguments[0];\n\t\t\t\t\t\tif (inst is LdObjIfRef ldObjIfRef)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tinst = ldObjIfRef.Target;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (method.IsAccessor)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (method.AccessorOwner is IProperty property &&\n\t\t\t\t\t\t\t\t!CanBeUsedInInitializer(property, resolver, kind))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tgoto default;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar isGetter = method.AccessorKind == System.Reflection.MethodSemanticsAttributes.Getter;\n\t\t\t\t\t\t\tvar indices = call.Arguments.Skip(1).Take(call.Arguments.Count - (isGetter ? 1 : 2)).ToArray();\n\t\t\t\t\t\t\tif (indices.Length > 0 && settings?.DictionaryInitializers == false)\n\t\t\t\t\t\t\t\tgoto default;\n\t\t\t\t\t\t\tif (possibleIndexVariables != null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// Mark all index variables as used\n\t\t\t\t\t\t\t\tforeach (var index in indices.OfType<IInstructionWithVariableOperand>())\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif (possibleIndexVariables.TryGetValue(index.Variable, out var info))\n\t\t\t\t\t\t\t\t\t\tpossibleIndexVariables[index.Variable] = (-1, info.Value);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tpath.Insert(0, new AccessPathElement(call.OpCode, method.AccessorOwner, indices));\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpath.Insert(0, new AccessPathElement(call.OpCode, method));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (values == null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (method.IsAccessor)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tkind = AccessPathKind.Setter;\n\t\t\t\t\t\t\t\tvalues = new List<ILInstruction> { call.Arguments.Last() };\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tkind = AccessPathKind.Adder;\n\t\t\t\t\t\t\t\tvalues = new List<ILInstruction>(call.Arguments.Skip(1));\n\t\t\t\t\t\t\t\tif (values.Count == 0)\n\t\t\t\t\t\t\t\t\tgoto default;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase LdObj ldobj:\n\t\t\t\t\t{\n\t\t\t\t\t\tif (ldobj.Target is LdFlda ldflda && (kind != AccessPathKind.Setter || !ldflda.Field.IsReadOnly))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpath.Insert(0, new AccessPathElement(ldobj.OpCode, ldflda.Field));\n\t\t\t\t\t\t\tinst = ldflda.Target;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tgoto default;\n\t\t\t\t\t}\n\t\t\t\t\tcase LdObjIfRef ldobj:\n\t\t\t\t\t{\n\t\t\t\t\t\tif (ldobj.Target is LdFlda ldflda && (kind != AccessPathKind.Setter || !ldflda.Field.IsReadOnly))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpath.Insert(0, new AccessPathElement(ldobj.OpCode, ldflda.Field));\n\t\t\t\t\t\t\tinst = ldflda.Target;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (ldobj.Target is LdLoca ldloca)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttarget = ldloca.Variable;\n\t\t\t\t\t\t\tinst = null;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tgoto default;\n\t\t\t\t\t}\n\t\t\t\t\tcase StObj stobj:\n\t\t\t\t\t{\n\t\t\t\t\t\tif (stobj.Target is LdFlda ldflda)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpath.Insert(0, new AccessPathElement(stobj.OpCode, ldflda.Field));\n\t\t\t\t\t\t\tinst = ldflda.Target;\n\t\t\t\t\t\t\tif (values == null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvalues = new List<ILInstruction>(new[] { stobj.Value });\n\t\t\t\t\t\t\t\tkind = AccessPathKind.Setter;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tgoto default;\n\t\t\t\t\t}\n\t\t\t\t\tcase LdLoc ldloc:\n\t\t\t\t\t\ttarget = ldloc.Variable;\n\t\t\t\t\t\tinst = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase LdLoca ldloca:\n\t\t\t\t\t\ttarget = ldloca.Variable;\n\t\t\t\t\t\tinst = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase LdFlda ldflda:\n\t\t\t\t\t\tpath.Insert(0, new AccessPathElement(ldflda.OpCode, ldflda.Field));\n\t\t\t\t\t\tinst = ldflda.Target;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tkind = AccessPathKind.Invalid;\n\t\t\t\t\t\tinst = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (kind != AccessPathKind.Invalid && values != null && values.SelectMany(v => v.Descendants).OfType<IInstructionWithVariableOperand>().Any(ld => ld.Variable == target && (ld is LdLoc || ld is LdLoca)))\n\t\t\t\tkind = AccessPathKind.Invalid;\n\t\t\treturn (kind, path, values, target);\n\t\t}\n\n\t\tprivate static bool CanBeUsedInInitializer(IProperty property, ITypeResolveContext? resolveContext, AccessPathKind kind)\n\t\t{\n\t\t\tif (property.CanSet && (property.Accessibility == property.Setter.Accessibility || IsAccessorAccessible(property.Setter, resolveContext)))\n\t\t\t\treturn true;\n\t\t\treturn kind != AccessPathKind.Setter;\n\t\t}\n\n\t\tprivate static bool IsAccessorAccessible(IMethod setter, ITypeResolveContext? resolveContext)\n\t\t{\n\t\t\tif (resolveContext == null)\n\t\t\t\treturn true;\n\t\t\tvar lookup = new MemberLookup(resolveContext.CurrentTypeDefinition, resolveContext.CurrentModule);\n\t\t\treturn lookup.IsAccessible(setter, allowProtectedAccess: setter.DeclaringTypeDefinition == resolveContext.CurrentTypeDefinition);\n\t\t}\n\n\t\tstatic bool IsMethodApplicable(IMethod method, IReadOnlyList<ILInstruction> arguments, IType rootType, CSharpResolver resolver, DecompilerSettings? settings)\n\t\t{\n\t\t\tif (method.IsStatic && !method.IsExtensionMethod)\n\t\t\t\treturn false;\n\t\t\tif (method.AccessorOwner is IProperty)\n\t\t\t\treturn true;\n\t\t\tif (!\"Add\".Equals(method.Name, StringComparison.Ordinal) || arguments.Count == 0)\n\t\t\t\treturn false;\n\t\t\tif (method.IsExtensionMethod)\n\t\t\t{\n\t\t\t\tif (settings?.ExtensionMethodsInCollectionInitializers == false)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!resolver.CanTransformToExtensionMethodCall(method, ignoreTypeArguments: true))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar targetType = GetReturnTypeFromInstruction(arguments[0]) ?? rootType;\n\t\t\tif (targetType == null)\n\t\t\t\treturn false;\n\t\t\tif (!targetType.GetAllBaseTypes().Any(i => i.IsKnownType(KnownTypeCode.IEnumerable) || i.IsKnownType(KnownTypeCode.IEnumerableOfT)))\n\t\t\t\treturn false;\n\t\t\treturn CanInferTypeArgumentsFromParameters(method);\n\n\t\t\tbool CanInferTypeArgumentsFromParameters(IMethod method)\n\t\t\t{\n\t\t\t\tif (method.TypeParameters.Count == 0)\n\t\t\t\t\treturn true;\n\t\t\t\t// always use unspecialized member, otherwise type inference fails\n\t\t\t\tmethod = (IMethod)method.MemberDefinition;\n\t\t\t\tnew TypeInference(resolver.Compilation)\n\t\t\t\t\t.InferTypeArguments(\n\t\t\t\t\t\tmethod.TypeParameters,\n\t\t\t\t\t\t// TODO : this is not entirely correct... we need argument type information to resolve Add methods properly\n\t\t\t\t\t\tmethod.Parameters.SelectReadOnlyArray(p => new ResolveResult(p.Type)),\n\t\t\t\t\t\tmethod.Parameters.SelectReadOnlyArray(p => p.Type),\n\t\t\t\t\t\tout bool success\n\t\t\t\t\t);\n\t\t\t\treturn success;\n\t\t\t}\n\t\t}\n\n\t\tstatic IType? GetReturnTypeFromInstruction(ILInstruction instruction)\n\t\t{\n\t\t\tswitch (instruction)\n\t\t\t{\n\t\t\t\tcase CallInstruction call:\n\t\t\t\t\tif (!(call is CallVirt || call is Call))\n\t\t\t\t\t\tgoto default;\n\t\t\t\t\treturn call.Method.ReturnType;\n\t\t\t\tcase LdObj ldobj:\n\t\t\t\t\tif (ldobj.Target is LdFlda ldflda)\n\t\t\t\t\t\treturn ldflda.Field.ReturnType;\n\t\t\t\t\tgoto default;\n\t\t\t\tcase StObj stobj:\n\t\t\t\t\tif (stobj.Target is LdFlda ldflda2)\n\t\t\t\t\t\treturn ldflda2.Field.ReturnType;\n\t\t\t\t\tgoto default;\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool Equals(object? obj)\n\t\t{\n\t\t\tif (obj is AccessPathElement)\n\t\t\t\treturn Equals((AccessPathElement)obj);\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\tint hashCode = 0;\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\tif (Member != null)\n\t\t\t\t\thashCode += 1000000007 * Member.GetHashCode();\n\t\t\t}\n\t\t\treturn hashCode;\n\t\t}\n\n\t\tpublic bool Equals(AccessPathElement other)\n\t\t{\n\t\t\treturn (other.Member == this.Member\n\t\t\t\t|| this.Member.Equals(other.Member))\n\t\t\t\t&& (other.Indices == this.Indices\n\t\t\t\t|| (other.Indices != null && this.Indices != null && this.Indices.SequenceEqual(other.Indices, ILInstructionMatchComparer.Instance)));\n\t\t}\n\n\t\tpublic static bool operator ==(AccessPathElement lhs, AccessPathElement rhs)\n\t\t{\n\t\t\treturn lhs.Equals(rhs);\n\t\t}\n\n\t\tpublic static bool operator !=(AccessPathElement lhs, AccessPathElement rhs)\n\t\t{\n\t\t\treturn !(lhs == rhs);\n\t\t}\n\t}\n\n\tclass ILInstructionMatchComparer : IEqualityComparer<ILInstruction>\n\t{\n\t\tpublic static readonly ILInstructionMatchComparer Instance = new ILInstructionMatchComparer();\n\n\t\tpublic bool Equals(ILInstruction? x, ILInstruction? y)\n\t\t{\n\t\t\tif (x == y)\n\t\t\t\treturn true;\n\t\t\tif (x == null || y == null)\n\t\t\t\treturn false;\n\t\t\treturn SemanticHelper.IsPure(x.Flags)\n\t\t\t\t&& SemanticHelper.IsPure(y.Flags)\n\t\t\t\t&& x.Match(y).Success;\n\t\t}\n\n\t\tpublic int GetHashCode(ILInstruction obj)\n\t\t{\n\t\t\treturn obj.GetHashCode();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/TransformDisplayClassUsage.cs",
    "content": "// Copyright (c) 2019 Siegfried Pammer\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.IL.ControlFlow;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Transforms closure fields to local variables.\n\t/// \n\t/// This is a post-processing step of <see cref=\"DelegateConstruction\"/>, <see cref=\"LocalFunctionDecompiler\"/>\n\t/// and <see cref=\"TransformExpressionTrees\"/>.\n\t/// \n\t/// In general we can perform SROA (scalar replacement of aggregates) on any variable that\n\t/// satisfies the following conditions:\n\t/// 1) It is initialized by an empty/default constructor call.\n\t/// 2) The variable is never passed to another method.\n\t/// 3) The variable is never the target of an invocation.\n\t/// \n\t/// Note that 2) and 3) apply because declarations and uses of lambdas and local functions\n\t/// are already transformed by the time this transform is applied.\n\t/// </summary>\n\tpublic class TransformDisplayClassUsage : ILVisitor, IILTransform\n\t{\n\t\tclass VariableToDeclare\n\t\t{\n\t\t\tprivate readonly DisplayClass container;\n\t\t\tprivate readonly IField field;\n\t\t\tprivate ILVariable declaredVariable;\n\n\t\t\tpublic string Name => field.Name;\n\n\t\t\tpublic bool CanPropagate { get; private set; }\n\t\t\tpublic bool UsesInitialValue { get; set; }\n\n\t\t\tpublic HashSet<ILInstruction> Initializers { get; } = new HashSet<ILInstruction>();\n\n\t\t\tpublic VariableToDeclare(DisplayClass container, IField field, ILVariable declaredVariable = null)\n\t\t\t{\n\t\t\t\tthis.container = container;\n\t\t\t\tthis.field = field;\n\t\t\t\tthis.declaredVariable = declaredVariable;\n\n\t\t\t\tDebug.Assert(declaredVariable == null || declaredVariable.StateMachineField == field);\n\t\t\t}\n\n\t\t\tpublic void Propagate(ILVariable variable)\n\t\t\t{\n\t\t\t\tthis.declaredVariable = variable;\n\t\t\t\tthis.CanPropagate = variable != null;\n\t\t\t}\n\n\t\t\tpublic ILVariable GetOrDeclare()\n\t\t\t{\n\t\t\t\tif (declaredVariable != null)\n\t\t\t\t\treturn declaredVariable;\n\t\t\t\tdeclaredVariable = container.Variable.Function.RegisterVariable(VariableKind.Local, field.Type, field.Name);\n\t\t\t\tdeclaredVariable.InitialValueIsInitialized = true;\n\t\t\t\tdeclaredVariable.UsesInitialValue = UsesInitialValue;\n\t\t\t\tdeclaredVariable.CaptureScope = container.CaptureScope;\n\t\t\t\treturn declaredVariable;\n\t\t\t}\n\t\t}\n\n\t\t[DebuggerDisplay(\"[DisplayClass {Variable} : {Type}]\")]\n\t\tclass DisplayClass\n\t\t{\n\t\t\tpublic readonly ILVariable Variable;\n\t\t\tpublic readonly ITypeDefinition Type;\n\t\t\tpublic readonly Dictionary<IField, VariableToDeclare> VariablesToDeclare;\n\t\t\tpublic BlockContainer CaptureScope;\n\t\t\tpublic ILInstruction Initializer;\n\n\t\t\tpublic DisplayClass(ILVariable variable, ITypeDefinition type)\n\t\t\t{\n\t\t\t\tVariable = variable;\n\t\t\t\tType = type;\n\t\t\t\tVariablesToDeclare = new Dictionary<IField, VariableToDeclare>();\n\t\t\t}\n\t\t}\n\n\t\tILTransformContext context;\n\t\tITypeResolveContext decompilationContext;\n\t\treadonly Dictionary<ILVariable, DisplayClass> displayClasses = new Dictionary<ILVariable, DisplayClass>();\n\t\treadonly Dictionary<ILVariable, ILVariable> displayClassCopyMap = new Dictionary<ILVariable, ILVariable>();\n\n\t\tvoid IILTransform.Run(ILFunction function, ILTransformContext context)\n\t\t{\n\t\t\tif (this.context != null)\n\t\t\t\tthrow new InvalidOperationException(\"Reentrancy in \" + nameof(TransformDisplayClassUsage));\n\t\t\ttry\n\t\t\t{\n\t\t\t\tthis.context = context;\n\t\t\t\tthis.decompilationContext = new SimpleTypeResolveContext(context.Function.Method);\n\t\t\t\tAnalyzeFunction(function);\n\t\t\t\tTransform(function);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tClearState();\n\t\t\t}\n\t\t}\n\n\t\tvoid ClearState()\n\t\t{\n\t\t\tdisplayClasses.Clear();\n\t\t\tdisplayClassCopyMap.Clear();\n\t\t\tthis.decompilationContext = null;\n\t\t\tthis.context = null;\n\t\t}\n\n\t\tvoid AnalyzeFunction(ILFunction function)\n\t\t{\n\t\t\tvoid VisitFunction(ILFunction f)\n\t\t\t{\n\t\t\t\tforeach (var v in f.Variables.ToArray())\n\t\t\t\t{\n\t\t\t\t\tvar result = AnalyzeVariable(v);\n\t\t\t\t\tif (result == null || displayClasses.ContainsKey(result.Variable))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tcontext.Step($\"Detected display-class {result.Variable}\", result.Initializer ?? f.Body);\n\t\t\t\t\tdisplayClasses.Add(result.Variable, result);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid VisitChildren(ILInstruction inst)\n\t\t\t{\n\t\t\t\tforeach (var child in inst.Children)\n\t\t\t\t{\n\t\t\t\t\tVisit(child);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid Visit(ILInstruction inst)\n\t\t\t{\n\t\t\t\tswitch (inst)\n\t\t\t\t{\n\t\t\t\t\tcase ILFunction f:\n\t\t\t\t\t\tVisitFunction(f);\n\t\t\t\t\t\tVisitChildren(inst);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tVisitChildren(inst);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tVisit(function);\n\n\t\t\tforeach (var (v, displayClass) in displayClasses.ToArray())\n\t\t\t{\n\t\t\t\tif (!ValidateDisplayClassUses(v, displayClass))\n\t\t\t\t\tdisplayClasses.Remove(v);\n\t\t\t}\n\n\t\t\tforeach (var displayClass in displayClasses.Values)\n\t\t\t{\n\t\t\t\t// handle uninitialized fields\n\t\t\t\tforeach (var f in displayClass.Type.Fields)\n\t\t\t\t{\n\t\t\t\t\tif (displayClass.VariablesToDeclare.ContainsKey(f))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tvar variable = AddVariable(displayClass, null, f);\n\t\t\t\t\tvariable.UsesInitialValue = true;\n\t\t\t\t\tdisplayClass.VariablesToDeclare[(IField)f.MemberDefinition] = variable;\n\t\t\t\t}\n\n\t\t\t\tforeach (var v in displayClass.VariablesToDeclare.Values)\n\t\t\t\t{\n\t\t\t\t\tif (v.CanPropagate)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar variableToPropagate = v.GetOrDeclare();\n\t\t\t\t\t\tif (variableToPropagate.Kind != VariableKind.Parameter && !displayClasses.ContainsKey(variableToPropagate))\n\t\t\t\t\t\t\tv.Propagate(null);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool ValidateDisplayClassUses(ILVariable v, DisplayClass displayClass)\n\t\t{\n\t\t\tforeach (var ldloc in v.LoadInstructions)\n\t\t\t{\n\t\t\t\tif (!ValidateUse(displayClass, ldloc))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tforeach (var ldloca in v.AddressInstructions)\n\t\t\t{\n\t\t\t\tif (!ValidateUse(displayClass, ldloca))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\n\t\t\tbool ValidateUse(DisplayClass container, ILInstruction use)\n\t\t\t{\n\t\t\t\tIField field;\n\t\t\t\tswitch (use.Parent)\n\t\t\t\t{\n\t\t\t\t\tcase LdFlda ldflda when ldflda.MatchLdFlda(out var target, out field) && target == use:\n\t\t\t\t\t\tvar keyField = (IField)field.MemberDefinition;\n\t\t\t\t\t\tif (!container.VariablesToDeclare.TryGetValue(keyField, out VariableToDeclare variable) || variable == null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvariable = AddVariable(container, null, field);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontainer.VariablesToDeclare[keyField] = variable;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tcase StObj stobj when stobj.MatchStObj(out var target, out ILInstruction value, out _) && value == use:\n\t\t\t\t\t\tif (target.MatchLdFlda(out var load, out field) && load.MatchLdLocRef(out var otherVariable) && displayClasses.TryGetValue(otherVariable, out var otherDisplayClass))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (otherDisplayClass.VariablesToDeclare.TryGetValue((IField)field.MemberDefinition, out var declaredVar))\n\t\t\t\t\t\t\t\treturn declaredVar.CanPropagate;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcase StLoc stloc when stloc.Variable.IsSingleDefinition && stloc.Value == use:\n\t\t\t\t\t\tdisplayClassCopyMap[stloc.Variable] = v;\n\t\t\t\t\t\treturn ValidateDisplayClassUses(stloc.Variable, displayClass);\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate DisplayClass AnalyzeVariable(ILVariable v)\n\t\t{\n\t\t\tswitch (v.Kind)\n\t\t\t{\n\t\t\t\tcase VariableKind.Parameter:\n\t\t\t\t\tif (context.Settings.YieldReturn && v.Function.StateMachineCompiledWithMono && v.IsThis())\n\t\t\t\t\t\treturn HandleMonoStateMachine(v.Function, v);\n\t\t\t\t\treturn null;\n\t\t\t\tcase VariableKind.StackSlot:\n\t\t\t\tcase VariableKind.Local:\n\t\t\t\tcase VariableKind.DisplayClassLocal:\n\t\t\t\t\treturn DetectDisplayClass(v);\n\t\t\t\tcase VariableKind.InitializerTarget:\n\t\t\t\t\treturn DetectDisplayClassInitializer(v);\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tDisplayClass DetectDisplayClass(ILVariable v)\n\t\t{\n\t\t\tITypeDefinition definition;\n\t\t\tif (v.Kind != VariableKind.StackSlot)\n\t\t\t{\n\t\t\t\tdefinition = v.Type.GetDefinition();\n\t\t\t}\n\t\t\telse if (v.StoreInstructions.Count > 0 && v.StoreInstructions[0] is StLoc stloc)\n\t\t\t{\n\t\t\t\tdefinition = stloc.Value.InferType(context.TypeSystem).GetDefinition();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tdefinition = null;\n\t\t\t}\n\t\t\tif (!ValidateDisplayClassDefinition(definition))\n\t\t\t\treturn null;\n\t\t\tDisplayClass result;\n\t\t\tswitch (definition.Kind)\n\t\t\t{\n\t\t\t\tcase TypeKind.Class:\n\t\t\t\t\tif (!v.IsSingleDefinition)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tif (!(v.StoreInstructions.SingleOrDefault() is StLoc stloc))\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tif (stloc.Value is NewObj newObj && ValidateConstructor(context, newObj.Method))\n\t\t\t\t\t{\n\t\t\t\t\t\tresult = new DisplayClass(v, definition) {\n\t\t\t\t\t\t\tCaptureScope = v.CaptureScope,\n\t\t\t\t\t\t\tInitializer = stloc\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\n\t\t\t\t\tHandleInitBlock(stloc.Parent as Block, stloc.ChildIndex + 1, result, result.Variable);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeKind.Struct:\n\t\t\t\t\tif (v.StoreInstructions.Count != 0)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tDebug.Assert(v.StoreInstructions.Count == 0);\n\t\t\t\t\tresult = new DisplayClass(v, definition) { CaptureScope = v.CaptureScope };\n\t\t\t\t\tHandleInitBlock(FindDisplayStructInitBlock(v), 0, result, result.Variable);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif (IsMonoNestedCaptureScope(definition))\n\t\t\t{\n\t\t\t\tresult.CaptureScope = null;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tvoid HandleInitBlock(Block initBlock, int startIndex, DisplayClass result, ILVariable targetVariable)\n\t\t{\n\t\t\tif (initBlock == null)\n\t\t\t\treturn;\n\t\t\tfor (int i = startIndex; i < initBlock.Instructions.Count; i++)\n\t\t\t{\n\t\t\t\tvar init = initBlock.Instructions[i];\n\t\t\t\tif (!init.MatchStFld(out var target, out var field, out _))\n\t\t\t\t\tbreak;\n\t\t\t\tif (!target.MatchLdLocRef(targetVariable))\n\t\t\t\t\tbreak;\n\t\t\t\tif (result.VariablesToDeclare.ContainsKey((IField)field.MemberDefinition))\n\t\t\t\t\tbreak;\n\t\t\t\tvar variable = AddVariable(result, (StObj)init, field);\n\t\t\t\tresult.VariablesToDeclare[(IField)field.MemberDefinition] = variable;\n\t\t\t}\n\t\t}\n\n\t\tprivate Block FindDisplayStructInitBlock(ILVariable v)\n\t\t{\n\t\t\tvar root = v.Function.Body;\n\t\t\treturn Visit(root)?.Ancestors.OfType<Block>().FirstOrDefault();\n\n\t\t\t// Try to find a common ancestor of all uses of the variable v.\n\t\t\tILInstruction Visit(ILInstruction inst)\n\t\t\t{\n\t\t\t\tswitch (inst)\n\t\t\t\t{\n\t\t\t\t\tcase LdLoc l when l.Variable == v:\n\t\t\t\t\t\treturn l;\n\t\t\t\t\tcase StLoc s when s.Variable == v:\n\t\t\t\t\t\treturn s;\n\t\t\t\t\tcase LdLoca la when la.Variable == v:\n\t\t\t\t\t\treturn la;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn VisitChildren(inst);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tILInstruction VisitChildren(ILInstruction inst)\n\t\t\t{\n\t\t\t\t// Visit all children of the instruction\n\t\t\t\tILInstruction result = null;\n\t\t\t\tforeach (var child in inst.Children)\n\t\t\t\t{\n\t\t\t\t\tvar newResult = Visit(child);\n\t\t\t\t\t// As soon as there is a second use of v in this sub-tree,\n\t\t\t\t\t// we can skip all other children and just return this node.\n\t\t\t\t\tif (result == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tresult = newResult;\n\t\t\t\t\t}\n\t\t\t\t\telse if (newResult != null)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn inst;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// returns null, if v is not used in this sub-tree;\n\t\t\t\t// returns a descendant of inst, if it is the only use of v in this sub-tree.\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\n\t\tDisplayClass DetectDisplayClassInitializer(ILVariable v)\n\t\t{\n\t\t\tif (v.StoreInstructions.Count != 1 || !(v.StoreInstructions[0] is StLoc store && store.Parent is Block initializerBlock && initializerBlock.Kind == BlockKind.ObjectInitializer))\n\t\t\t\treturn null;\n\t\t\tif (!(store.Value is NewObj newObj))\n\t\t\t\treturn null;\n\t\t\tvar definition = newObj.Method.DeclaringType.GetDefinition();\n\t\t\tif (!ValidateDisplayClassDefinition(definition))\n\t\t\t\treturn null;\n\t\t\tif (!ValidateConstructor(context, newObj.Method))\n\t\t\t\treturn null;\n\t\t\tif (!initializerBlock.Parent.MatchStLoc(out var referenceVariable))\n\t\t\t\treturn null;\n\t\t\tif (!referenceVariable.IsSingleDefinition)\n\t\t\t\treturn null;\n\t\t\tif (!(referenceVariable.StoreInstructions.SingleOrDefault() is StLoc))\n\t\t\t\treturn null;\n\t\t\tvar result = new DisplayClass(referenceVariable, definition) {\n\t\t\t\tCaptureScope = referenceVariable.CaptureScope,\n\t\t\t\tInitializer = initializerBlock.Parent\n\t\t\t};\n\t\t\tHandleInitBlock(initializerBlock, 1, result, v);\n\t\t\treturn result;\n\t\t}\n\n\t\tprivate bool ValidateDisplayClassDefinition(ITypeDefinition definition)\n\t\t{\n\t\t\tif (definition == null)\n\t\t\t\treturn false;\n\t\t\tif (definition.ParentModule.MetadataFile != context.PEFile)\n\t\t\t\treturn false;\n\t\t\t// We do not want to accidentially transform state-machines and thus destroy them.\n\t\t\tvar token = (TypeDefinitionHandle)definition.MetadataToken;\n\t\t\tvar metadata = definition.ParentModule.MetadataFile.Metadata;\n\t\t\tif (YieldReturnDecompiler.IsCompilerGeneratorEnumerator(token, metadata))\n\t\t\t\treturn false;\n\t\t\tif (AsyncAwaitDecompiler.IsCompilerGeneratedStateMachine(token, metadata))\n\t\t\t\treturn false;\n\t\t\tif (!context.Settings.AggressiveScalarReplacementOfAggregates)\n\t\t\t{\n\t\t\t\tif (definition.DeclaringTypeDefinition == null)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!IsPotentialClosure(context, definition))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tinternal static bool ValidateConstructor(ILTransformContext context, IMethod method)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (method.Parameters.Count != 0)\n\t\t\t\t\treturn false;\n\t\t\t\tvar handle = (MethodDefinitionHandle)method.MetadataToken;\n\t\t\t\tvar module = (MetadataModule)method.ParentModule;\n\t\t\t\tvar file = module.MetadataFile;\n\t\t\t\tif (handle.IsNil || file != context.PEFile)\n\t\t\t\t\treturn false;\n\t\t\t\tvar def = file.Metadata.GetMethodDefinition(handle);\n\t\t\t\tif (def.RelativeVirtualAddress == 0)\n\t\t\t\t\treturn false;\n\t\t\t\tvar body = file.GetMethodBody(def.RelativeVirtualAddress);\n\t\t\t\t// some compilers produce ctors with unused local variables\n\t\t\t\t// see https://github.com/icsharpcode/ILSpy/issues/2174\n\t\t\t\t//if (!body.LocalSignature.IsNil)\n\t\t\t\t//\treturn false;\n\t\t\t\tif (body.ExceptionRegions.Length != 0)\n\t\t\t\t\treturn false;\n\t\t\t\tvar reader = body.GetILReader();\n\t\t\t\tif (reader.Length < 7)\n\t\t\t\t\treturn false;\n\t\t\t\t// IL_0000: ldarg.0\n\t\t\t\t// IL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\t\t\t// IL_0006: ret\n\t\t\t\tvar opCode = DecodeOpCodeSkipNop(ref reader);\n\t\t\t\tswitch (opCode)\n\t\t\t\t{\n\t\t\t\t\tcase ILOpCode.Ldarg:\n\t\t\t\t\tcase ILOpCode.Ldarg_s:\n\t\t\t\t\t\tif (reader.DecodeIndex(opCode) != 0)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase ILOpCode.Ldarg_0:\n\t\t\t\t\t\t// OK\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (DecodeOpCodeSkipNop(ref reader) != ILOpCode.Call)\n\t\t\t\t\treturn false;\n\t\t\t\tvar baseCtorHandle = MetadataTokenHelpers.EntityHandleOrNil(reader.ReadInt32());\n\t\t\t\tif (baseCtorHandle.IsNil)\n\t\t\t\t\treturn false;\n\t\t\t\tvar objectCtor = module.ResolveMethod(baseCtorHandle, new TypeSystem.GenericContext());\n\t\t\t\tif (!objectCtor.DeclaringType.IsKnownType(KnownTypeCode.Object))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!objectCtor.IsConstructor || objectCtor.Parameters.Count != 0)\n\t\t\t\t\treturn false;\n\t\t\t\treturn DecodeOpCodeSkipNop(ref reader) == ILOpCode.Ret;\n\t\t\t}\n\t\t\tcatch (BadImageFormatException)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tstatic ILOpCode DecodeOpCodeSkipNop(ref BlobReader reader)\n\t\t{\n\t\t\tILOpCode code;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tcode = reader.DecodeOpCode();\n\t\t\t} while (code == ILOpCode.Nop);\n\t\t\treturn code;\n\t\t}\n\n\t\tVariableToDeclare AddVariable(DisplayClass result, StObj statement, IField field)\n\t\t{\n\t\t\tVariableToDeclare variable = new VariableToDeclare(result, field);\n\t\t\tif (statement != null)\n\t\t\t{\n\t\t\t\tvariable.Propagate(ResolveVariableToPropagate(statement.Value, field.Type));\n\t\t\t\tvariable.Initializers.Add(statement);\n\t\t\t}\n\t\t\tvariable.UsesInitialValue =\n\t\t\t\tresult.Type.IsReferenceType != false || result.Variable.UsesInitialValue;\n\t\t\treturn variable;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Resolves references to variables that can be propagated.\n\t\t/// If a value does not match either LdLoc or a LdObj LdLdFlda* LdLoc chain, null is returned.\n\t\t/// The if any of the variables/fields in the chain cannot be propagated, null is returned.\n\t\t/// </summary>\n\t\tILVariable ResolveVariableToPropagate(ILInstruction value, IType expectedType = null)\n\t\t{\n\t\t\tILVariable v;\n\t\t\tswitch (value)\n\t\t\t{\n\t\t\t\tcase LdLoc load:\n\t\t\t\t\tv = load.Variable;\n\t\t\t\t\tif (v.Kind == VariableKind.Parameter)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (v.LoadCount != 1 && !v.IsThis())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// If the variable is a parameter and it is used elsewhere, we cannot propagate it.\n\t\t\t\t\t\t\t// \"dc.field = v; dc.field.mutate(); use(v);\" cannot turn to \"v.mutate(); use(v)\"\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// Non-parameter propagation will later be checked, and will only be allowed for display classes\n\t\t\t\t\t\tif (v.Type.IsReferenceType != true)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// don't allow propagation for display structs (as used with local functions)\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (!v.IsSingleDefinition)\n\t\t\t\t\t{\n\t\t\t\t\t\t// \"dc.field = v; v = 42; use(dc.field)\" cannot turn to \"v = 42; use(v);\"\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tif (!(expectedType == null || v.Kind == VariableKind.StackSlot || NormalizeTypeVisitor.IgnoreNullability.EquivalentTypes(v.Type, expectedType)))\n\t\t\t\t\t\treturn null;\n\t\t\t\t\treturn v;\n\t\t\t\tcase LdObj ldfld:\n\t\t\t\t\tDisplayClass currentDisplayClass = null;\n\t\t\t\t\tforeach (var item in ldfld.Target.Descendants)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (IsDisplayClassLoad(item, out v))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!displayClasses.TryGetValue(v, out currentDisplayClass))\n\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (currentDisplayClass == null)\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\tif (item is LdFlda ldf && currentDisplayClass.VariablesToDeclare.TryGetValue((IField)ldf.Field.MemberDefinition, out var vd))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!vd.CanPropagate)\n\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\tif (!displayClasses.TryGetValue(vd.GetOrDeclare(), out currentDisplayClass))\n\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn currentDisplayClass.Variable;\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tprivate void Transform(ILFunction function)\n\t\t{\n\t\t\tVisitILFunction(function);\n\t\t\tcontext.Step($\"ResetHasInitialValueFlag\", function);\n\t\t\tforeach (var f in function.Descendants.OfType<ILFunction>())\n\t\t\t{\n\t\t\t\tRemoveDeadVariableInit.ResetUsesInitialValueFlag(f, context);\n\t\t\t\tf.CapturedVariables.RemoveWhere(v => v.IsDead);\n\t\t\t}\n\t\t}\n\n\t\tinternal static bool IsClosure(ILTransformContext context, ILVariable variable, out ITypeDefinition closureType, out ILInstruction initializer)\n\t\t{\n\t\t\tclosureType = null;\n\t\t\tinitializer = null;\n\t\t\tif (variable.IsSingleDefinition && variable.StoreInstructions.SingleOrDefault() is StLoc inst)\n\t\t\t{\n\t\t\t\tinitializer = inst;\n\t\t\t\tif (IsClosureInit(context, inst, out closureType))\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tclosureType = variable.Type.GetDefinition();\n\t\t\tif (context.Settings.LocalFunctions && closureType?.Kind == TypeKind.Struct\n\t\t\t\t&& variable.UsesInitialValue && IsPotentialClosure(context, closureType))\n\t\t\t{\n\t\t\t\tinitializer = Block.GetContainingStatement(variable.AddressInstructions.OrderBy(i => i.StartILOffset).First());\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tstatic bool IsClosureInit(ILTransformContext context, StLoc inst, out ITypeDefinition closureType)\n\t\t{\n\t\t\tif (inst.Value is NewObj newObj)\n\t\t\t{\n\t\t\t\tclosureType = newObj.Method.DeclaringTypeDefinition;\n\t\t\t\treturn closureType != null && IsPotentialClosure(context, newObj);\n\t\t\t}\n\t\t\tclosureType = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tbool IsMonoNestedCaptureScope(ITypeDefinition closureType)\n\t\t{\n\t\t\tif (!closureType.Name.Contains(\"AnonStorey\"))\n\t\t\t\treturn false;\n\t\t\tvar decompilationContext = new SimpleTypeResolveContext(context.Function.Method);\n\t\t\treturn closureType.Fields.Any(f => IsPotentialClosure(decompilationContext.CurrentTypeDefinition, f.ReturnType.GetDefinition()));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// mcs likes to optimize closures in yield state machines away by moving the captured variables' fields into the state machine type,\n\t\t/// We construct a <see cref=\"DisplayClass\"/> that spans the whole method body.\n\t\t/// </summary>\n\t\tDisplayClass HandleMonoStateMachine(ILFunction function, ILVariable thisVariable)\n\t\t{\n\t\t\tif (!(function.StateMachineCompiledWithMono && thisVariable.IsThis()))\n\t\t\t\treturn null;\n\t\t\t// Special case for Mono-compiled yield state machines\n\t\t\tITypeDefinition closureType = thisVariable.Type.GetDefinition();\n\t\t\tif (!(closureType != decompilationContext.CurrentTypeDefinition\n\t\t\t\t&& IsPotentialClosure(decompilationContext.CurrentTypeDefinition, closureType, allowTypeImplementingInterfaces: true)))\n\t\t\t\treturn null;\n\n\t\t\tvar displayClass = new DisplayClass(thisVariable, thisVariable.Type.GetDefinition());\n\t\t\tdisplayClass.CaptureScope = (BlockContainer)function.Body;\n\t\t\tforeach (var stateMachineVariable in function.Variables)\n\t\t\t{\n\t\t\t\tif (stateMachineVariable.StateMachineField == null || displayClass.VariablesToDeclare.ContainsKey(stateMachineVariable.StateMachineField))\n\t\t\t\t\tcontinue;\n\t\t\t\tVariableToDeclare variableToDeclare = new VariableToDeclare(displayClass, stateMachineVariable.StateMachineField, stateMachineVariable);\n\t\t\t\tdisplayClass.VariablesToDeclare.Add(stateMachineVariable.StateMachineField, variableToDeclare);\n\t\t\t}\n\t\t\tif (!function.Method.IsStatic && FindThisField(out var thisField))\n\t\t\t{\n\t\t\t\tvar thisVar = function.Variables\n\t\t\t\t\t.FirstOrDefault(t => t.IsThis() && t.Type.GetDefinition() == decompilationContext.CurrentTypeDefinition);\n\t\t\t\tif (thisVar == null)\n\t\t\t\t{\n\t\t\t\t\tthisVar = new ILVariable(VariableKind.Parameter, decompilationContext.CurrentTypeDefinition, -1) {\n\t\t\t\t\t\tName = \"this\", StateMachineField = thisField\n\t\t\t\t\t};\n\t\t\t\t\tfunction.Variables.Add(thisVar);\n\t\t\t\t}\n\t\t\t\telse if (thisVar.StateMachineField != null && displayClass.VariablesToDeclare.ContainsKey(thisVar.StateMachineField))\n\t\t\t\t{\n\t\t\t\t\t// \"this\" was already added previously, no need to add it twice.\n\t\t\t\t\treturn displayClass;\n\t\t\t\t}\n\t\t\t\tVariableToDeclare variableToDeclare = new VariableToDeclare(displayClass, thisField, thisVar);\n\t\t\t\tdisplayClass.VariablesToDeclare.Add(thisField, variableToDeclare);\n\t\t\t}\n\t\t\treturn displayClass;\n\n\t\t\tbool FindThisField(out IField foundField)\n\t\t\t{\n\t\t\t\tfoundField = null;\n\t\t\t\tforeach (var field in closureType.GetFields(f2 => !f2.IsStatic && !displayClass.VariablesToDeclare.ContainsKey(f2) && f2.Type.GetDefinition() == decompilationContext.CurrentTypeDefinition))\n\t\t\t\t{\n\t\t\t\t\tthisField = field;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tinternal static bool IsPotentialClosure(ILTransformContext context, NewObj inst)\n\t\t{\n\t\t\tvar decompilationContext = new SimpleTypeResolveContext(context.Function.Ancestors.OfType<ILFunction>().Last().Method);\n\t\t\treturn IsPotentialClosure(decompilationContext.CurrentTypeDefinition, inst.Method.DeclaringTypeDefinition);\n\t\t}\n\n\t\tinternal static bool IsPotentialClosure(ILTransformContext context, ITypeDefinition potentialDisplayClass)\n\t\t{\n\t\t\tvar decompilationContext = new SimpleTypeResolveContext(context.Function.Ancestors.OfType<ILFunction>().Last().Method);\n\t\t\treturn IsPotentialClosure(decompilationContext.CurrentTypeDefinition, potentialDisplayClass);\n\t\t}\n\n\t\tinternal static bool IsPotentialClosure(ITypeDefinition decompiledTypeDefinition, ITypeDefinition potentialDisplayClass, bool allowTypeImplementingInterfaces = false)\n\t\t{\n\t\t\tif (potentialDisplayClass == null || !potentialDisplayClass.IsCompilerGeneratedOrIsInCompilerGeneratedClass())\n\t\t\t\treturn false;\n\t\t\tswitch (potentialDisplayClass.Kind)\n\t\t\t{\n\t\t\t\tcase TypeKind.Struct:\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeKind.Class:\n\t\t\t\t\tif (!allowTypeImplementingInterfaces)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!potentialDisplayClass.DirectBaseTypes.All(t => t.IsKnownType(KnownTypeCode.Object)))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Make sure that potentialDisplayCLass and decompiledTypeDefinition are part of the same type tree\n\t\t\t// Either decompiledTypeDefinition is an ancestor type of potentialDisplayClass or both have\n\t\t\t// at least one common ancestor.\n\t\t\tvar potentialDisplayClassAncestors = new HashSet<ITypeDefinition>();\n\t\t\tvar potentialDisplayClassParent = potentialDisplayClass.DeclaringTypeDefinition;\n\t\t\twhile (potentialDisplayClassParent != null)\n\t\t\t{\n\t\t\t\tpotentialDisplayClassAncestors.Add(potentialDisplayClassParent);\n\t\t\t\tpotentialDisplayClassParent = potentialDisplayClassParent.DeclaringTypeDefinition;\n\t\t\t}\n\n\t\t\tvar decompiledTypeDefinitionOrAncestor = decompiledTypeDefinition;\n\n\t\t\twhile (decompiledTypeDefinitionOrAncestor != null)\n\t\t\t{\n\t\t\t\tif (potentialDisplayClassAncestors.Contains(decompiledTypeDefinitionOrAncestor))\n\t\t\t\t\treturn true;\n\t\t\t\tdecompiledTypeDefinitionOrAncestor = decompiledTypeDefinitionOrAncestor.DeclaringTypeDefinition;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\treadonly Stack<ILFunction> currentFunctions = new Stack<ILFunction>();\n\n\t\tprotected internal override void VisitILFunction(ILFunction function)\n\t\t{\n\t\t\tcontext.StepStartGroup(\"Visit \" + function.Name);\n\t\t\ttry\n\t\t\t{\n\t\t\t\tthis.currentFunctions.Push(function);\n\t\t\t\tbase.VisitILFunction(function);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tthis.currentFunctions.Pop();\n\t\t\t\tcontext.StepEndGroup(keepIfEmpty: true);\n\t\t\t}\n\t\t}\n\n\t\tprotected override void Default(ILInstruction inst)\n\t\t{\n\t\t\tILInstruction next;\n\t\t\tfor (var child = inst.Children.FirstOrDefault(); child != null; child = next)\n\t\t\t{\n\t\t\t\tnext = child.GetNextSibling();\n\t\t\t\tchild.AcceptVisitor(this);\n\t\t\t}\n\t\t}\n\n\t\tprotected internal override void VisitStLoc(StLoc inst)\n\t\t{\n\t\t\tDisplayClass displayClass;\n\t\t\tif (inst.Parent is Block parentBlock && inst.Variable.IsSingleDefinition)\n\t\t\t{\n\t\t\t\tif ((inst.Variable.Kind == VariableKind.Local || inst.Variable.Kind == VariableKind.StackSlot) && inst.Variable.LoadCount == 0)\n\t\t\t\t{\n\t\t\t\t\t// traverse pre-order, so that we do not have to deal with more special cases afterwards\n\t\t\t\t\tbase.VisitStLoc(inst);\n\t\t\t\t\tif (inst.Value is StLoc || inst.Value is CompoundAssignmentInstruction)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontext.Step($\"Remove unused variable assignment {inst.Variable.Name}\", inst);\n\t\t\t\t\t\tinst.ReplaceWith(inst.Value);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (displayClasses.TryGetValue(inst.Variable, out displayClass) && displayClass.Initializer == inst)\n\t\t\t\t{\n\t\t\t\t\t// inline contents of object initializer block\n\t\t\t\t\tif (inst.Value is Block initBlock && initBlock.Kind == BlockKind.ObjectInitializer)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontext.Step($\"Remove initializer of {inst.Variable.Name}\", inst);\n\t\t\t\t\t\tfor (int i = 1; i < initBlock.Instructions.Count; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar stobj = (StObj)initBlock.Instructions[i];\n\t\t\t\t\t\t\tvar variable = displayClass.VariablesToDeclare[(IField)((LdFlda)stobj.Target).Field.MemberDefinition];\n\t\t\t\t\t\t\tparentBlock.Instructions.Insert(inst.ChildIndex + i, new StLoc(variable.GetOrDeclare(), stobj.Value).WithILRange(stobj));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcontext.Step($\"Remove initializer of {inst.Variable.Name}\", inst);\n\t\t\t\t\tparentBlock.Instructions.Remove(inst);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (inst.Value is LdLoc || inst.Value is LdObj)\n\t\t\t\t{\n\t\t\t\t\t// in some cases (e.g. if inlining fails), there can be a reference to a display class in a stack slot,\n\t\t\t\t\t// in that case it is necessary to resolve the reference and iff it can be propagated, replace all loads\n\t\t\t\t\t// of the single-definition.\n\t\t\t\t\tif (!displayClassCopyMap.TryGetValue(inst.Variable, out var referencedDisplayClass))\n\t\t\t\t\t{\n\t\t\t\t\t\treferencedDisplayClass = ResolveVariableToPropagate(inst.Value);\n\t\t\t\t\t}\n\t\t\t\t\tif (referencedDisplayClass != null && displayClasses.TryGetValue(referencedDisplayClass, out _))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontext.Step($\"Propagate reference to {referencedDisplayClass.Name} in {inst.Variable}\", inst);\n\t\t\t\t\t\tforeach (var ld in inst.Variable.LoadInstructions.ToArray())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tld.ReplaceWith(new LdLoc(referencedDisplayClass).WithILRange(ld));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tparentBlock.Instructions.Remove(inst);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbase.VisitStLoc(inst);\n\t\t}\n\n\t\tprotected internal override void VisitStObj(StObj inst)\n\t\t{\n\t\t\tif (IsDisplayClassFieldAccess(inst.Target, out var v, out var displayClass, out var field))\n\t\t\t{\n\t\t\t\tVariableToDeclare vd = displayClass.VariablesToDeclare[(IField)field.MemberDefinition];\n\t\t\t\tif (vd.CanPropagate && vd.Initializers.Contains(inst))\n\t\t\t\t{\n\t\t\t\t\tif (inst.Parent is Block containingBlock)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontext.Step($\"Remove initializer of {v.Name}.{vd.Name} due to propagation\", inst);\n\t\t\t\t\t\tcontainingBlock.Instructions.Remove(inst);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (inst.Value is LdLoc ldLoc && ldLoc.Variable is { IsSingleDefinition: true, CaptureScope: null }\n\t\t\t\t\t&& ldLoc.Variable.StoreInstructions.FirstOrDefault() is StLoc stloc\n\t\t\t\t\t&& stloc.Parent is Block block)\n\t\t\t\t{\n\t\t\t\t\tILInlining.InlineOneIfPossible(block, stloc.ChildIndex, InliningOptions.None, context);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbase.VisitStObj(inst);\n\t\t\tEarlyExpressionTransforms.StObjToStLoc(inst, context);\n\t\t}\n\n\t\tprotected internal override void VisitLdObj(LdObj inst)\n\t\t{\n\t\t\tbase.VisitLdObj(inst);\n\t\t\tEarlyExpressionTransforms.LdObjToLdLoc(inst, context);\n\t\t}\n\n\t\tprivate bool IsDisplayClassLoad(ILInstruction target, out ILVariable variable)\n\t\t{\n\t\t\t// We cannot use MatchLdLocRef here because local functions use ref parameters\n\t\t\tif (!target.MatchLdLoc(out variable) && !target.MatchLdLoca(out variable))\n\t\t\t\treturn false;\n\t\t\tif (displayClassCopyMap.TryGetValue(variable, out ILVariable other))\n\t\t\t\tvariable = other;\n\t\t\treturn true;\n\t\t}\n\n\t\tprivate bool IsDisplayClassFieldAccess(ILInstruction inst,\n\t\t\tout ILVariable displayClassVar, out DisplayClass displayClass, out IField field)\n\t\t{\n\t\t\tdisplayClass = null;\n\t\t\tdisplayClassVar = null;\n\t\t\tfield = null;\n\t\t\tif (inst is not LdFlda ldflda)\n\t\t\t\treturn false;\n\t\t\tfield = ldflda.Field;\n\t\t\treturn IsDisplayClassLoad(ldflda.Target, out displayClassVar)\n\t\t\t\t&& displayClasses.TryGetValue(displayClassVar, out displayClass);\n\t\t}\n\n\t\tprotected internal override void VisitLdFlda(LdFlda inst)\n\t\t{\n\t\t\tbase.VisitLdFlda(inst);\n\t\t\t// Get display class info\n\t\t\tif (!IsDisplayClassFieldAccess(inst, out _, out DisplayClass displayClass, out IField field))\n\t\t\t\treturn;\n\t\t\tvar keyField = (IField)field.MemberDefinition;\n\t\t\tvar v = displayClass.VariablesToDeclare[keyField];\n\t\t\tcontext.Step($\"Replace {field.Name} with captured variable {v.Name}\", inst);\n\t\t\tILVariable variable = v.GetOrDeclare();\n\t\t\tinst.ReplaceWith(new LdLoca(variable).WithILRange(inst));\n\t\t\t// add captured variable to all descendant functions from the declaring function to this use-site function\n\t\t\tforeach (var f in currentFunctions)\n\t\t\t{\n\t\t\t\tif (f == variable.Function)\n\t\t\t\t\tbreak;\n\t\t\t\tf.CapturedVariables.Add(variable);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs",
    "content": "// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.Resolver;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\t/// <summary>\n\t/// Converts LINQ Expression Trees to ILFunctions/ILAst instructions.\n\t/// \n\t/// We build a tree of Func{ILInstruction}s, which are only executed, if the whole transform succeeds.\n\t/// </summary>\n\tpublic class TransformExpressionTrees : IStatementTransform\n\t{\n\t\t/// <summary>\n\t\t/// Returns true if the instruction matches the pattern for Expression.Lambda calls.\n\t\t/// </summary>\n\t\tstatic bool MightBeExpressionTree(ILInstruction inst, ILInstruction stmt)\n\t\t{\n\t\t\tif (!(inst is CallInstruction call\n\t\t\t\t&& call.Method.FullNameIs(\"System.Linq.Expressions.Expression\", \"Lambda\")\n\t\t\t\t&& call.Arguments.Count == 2))\n\t\t\t\treturn false;\n\t\t\tif (!(IsEmptyParameterList(call.Arguments[1]) || (call.Arguments[1] is Block block && block.Kind == BlockKind.ArrayInitializer)))\n\t\t\t\treturn false;\n\t\t\t//if (!ILInlining.CanUninline(call, stmt))\n\t\t\t//\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic bool IsEmptyParameterList(ILInstruction inst)\n\t\t{\n\t\t\tif (inst is CallInstruction emptyCall && emptyCall.Method.FullNameIs(\"System.Array\", \"Empty\") && emptyCall.Arguments.Count == 0)\n\t\t\t\treturn true;\n\t\t\tif (inst.MatchNewArr(out var type) && type.FullName == \"System.Linq.Expressions.ParameterExpression\")\n\t\t\t\treturn true;\n\t\t\tif (inst.MatchNewArr(out type) && type.FullName == \"System.Linq.Expressions.Expression\")\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\n\t\tbool MatchParameterVariableAssignment(ILInstruction expr, out ILVariable parameterReferenceVar, out IType type, out string name)\n\t\t{\n\t\t\t// stloc(v, call(Expression::Parameter, call(Type::GetTypeFromHandle, ldtoken(...)), ldstr(...)))\n\t\t\ttype = null;\n\t\t\tname = null;\n\t\t\tif (!expr.MatchStLoc(out parameterReferenceVar, out var init))\n\t\t\t\treturn false;\n\t\t\tif (!parameterReferenceVar.IsSingleDefinition)\n\t\t\t\treturn false;\n\t\t\tif (!(parameterReferenceVar.Kind == VariableKind.Local || parameterReferenceVar.Kind == VariableKind.StackSlot))\n\t\t\t\treturn false;\n\t\t\tif (parameterReferenceVar.Type == null || parameterReferenceVar.Type.FullName != \"System.Linq.Expressions.ParameterExpression\")\n\t\t\t\treturn false;\n\t\t\tif (!(init is CallInstruction initCall && initCall.Arguments.Count == 2))\n\t\t\t\treturn false;\n\t\t\tif (!(initCall.Method.FullNameIs(\"System.Linq.Expressions.Expression\", \"Parameter\")))\n\t\t\t\treturn false;\n\t\t\tCallInstruction typeArg = initCall.Arguments[0] as CallInstruction;\n\t\t\tif (typeArg == null || typeArg.Arguments.Count != 1)\n\t\t\t\treturn false;\n\t\t\tif (!typeArg.Method.FullNameIs(\"System.Type\", \"GetTypeFromHandle\"))\n\t\t\t\treturn false;\n\t\t\treturn typeArg.Arguments[0].MatchLdTypeToken(out type) && initCall.Arguments[1].MatchLdStr(out name);\n\t\t}\n\n\t\tStatementTransformContext context;\n\t\tDictionary<ILVariable, (IType, string)> parameters;\n\t\tDictionary<ILVariable, ILVariable> parameterMapping;\n\t\tList<ILInstruction> instructionsToRemove;\n\t\tStack<ILFunction> lambdaStack;\n\t\tCSharpConversions conversions;\n\t\tCSharpResolver resolver;\n\n\t\tpublic void Run(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.ExpressionTrees)\n\t\t\t\treturn;\n\t\t\tthis.context = context;\n\t\t\tthis.conversions = CSharpConversions.Get(context.TypeSystem);\n\t\t\tthis.resolver = new CSharpResolver(context.TypeSystem);\n\t\t\tthis.parameters = new Dictionary<ILVariable, (IType, string)>();\n\t\t\tthis.parameterMapping = new Dictionary<ILVariable, ILVariable>();\n\t\t\tthis.instructionsToRemove = new List<ILInstruction>();\n\t\t\tthis.lambdaStack = new Stack<ILFunction>();\n\t\t\tfor (int i = pos; i < block.Instructions.Count; i++)\n\t\t\t{\n\t\t\t\tif (MatchParameterVariableAssignment(block.Instructions[i], out var v, out var type, out var name))\n\t\t\t\t{\n\t\t\t\t\tparameters.Add(v, (type, name));\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (TryConvertExpressionTree(block.Instructions[i], block.Instructions[i]))\n\t\t\t\t{\n\t\t\t\t\tforeach (var inst in instructionsToRemove)\n\t\t\t\t\t\tblock.Instructions.Remove(inst);\n\t\t\t\t\tinstructionsToRemove.Clear();\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tbool TryConvertExpressionTree(ILInstruction instruction, ILInstruction statement)\n\t\t{\n\t\t\tif (MightBeExpressionTree(instruction, statement))\n\t\t\t{\n\t\t\t\tvar (lambda, type) = ConvertLambda((CallInstruction)instruction);\n\t\t\t\tif (lambda != null)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"Convert Expression Tree\", instruction);\n\t\t\t\t\tvar newLambda = (ILFunction)lambda();\n\t\t\t\t\tSetExpressionTreeFlag(newLambda, (CallInstruction)instruction);\n\t\t\t\t\tinstruction.ReplaceWith(newLambda);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (instruction is Block block && block.Kind == BlockKind.ControlFlow)\n\t\t\t\treturn false;  // don't look into nested blocks\n\t\t\tforeach (var child in instruction.Children)\n\t\t\t{\n\t\t\t\tif (TryConvertExpressionTree(child, statement))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts a Expression.Lambda call into an ILFunction.\n\t\t/// If the conversion fails, null is returned.\n\t\t/// </summary>\n\t\t(Func<ILInstruction>, IType) ConvertLambda(CallInstruction instruction)\n\t\t{\n\t\t\tif (instruction.Method.Name != \"Lambda\" || instruction.Arguments.Count != 2 || instruction.Method.ReturnType.FullName != \"System.Linq.Expressions.Expression\" || instruction.Method.ReturnType.TypeArguments.Count != 1)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar parameterList = new List<IParameter>();\n\t\t\tvar parameterVariablesList = new List<ILVariable>();\n\t\t\tif (!ReadParameters(instruction.Arguments[1], parameterList, parameterVariablesList, new SimpleTypeResolveContext(context.Function.Method)))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar container = new BlockContainer();\n\t\t\tcontainer.AddILRange(instruction);\n\t\t\tvar functionType = instruction.Method.ReturnType.TypeArguments[0];\n\t\t\tvar returnType = functionType.GetDelegateInvokeMethod()?.ReturnType ?? SpecialType.UnknownType;\n\t\t\tvar function = new ILFunction(returnType, parameterList, context.Function.GenericContext, container, ILFunctionKind.ExpressionTree);\n\t\t\tfunction.DelegateType = functionType;\n\t\t\tfunction.Kind = IsExpressionTree(functionType) ? ILFunctionKind.ExpressionTree : ILFunctionKind.Delegate;\n\t\t\tfunction.Variables.AddRange(parameterVariablesList);\n\t\t\tfunction.AddILRange(instruction);\n\t\t\tlambdaStack.Push(function);\n\t\t\tvar (bodyInstruction, type) = ConvertInstruction(instruction.Arguments[0]);\n\t\t\tlambdaStack.Pop();\n\t\t\tif (bodyInstruction == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\treturn (BuildFunction, function.DelegateType);\n\n\t\t\tILFunction BuildFunction()\n\t\t\t{\n\t\t\t\tlambdaStack.Push(function);\n\t\t\t\tvar convertedBody = bodyInstruction();\n\t\t\t\tlambdaStack.Pop();\n\t\t\t\tcontainer.ExpectedResultType = convertedBody.ResultType;\n\t\t\t\tcontainer.Blocks.Add(new Block() { Instructions = { new Leave(container, convertedBody) } });\n\t\t\t\t// Replace all other usages of the parameter variable\n\t\t\t\tforeach (var mapping in parameterMapping)\n\t\t\t\t{\n\t\t\t\t\tforeach (var load in mapping.Key.LoadInstructions.ToArray())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (load.IsDescendantOf(instruction))\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tload.ReplaceWith(new LdLoc(mapping.Value));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn function;\n\t\t\t}\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertQuote(CallInstruction invocation)\n\t\t{\n\t\t\tif (invocation.Arguments.Count != 1)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar argument = invocation.Arguments.Single();\n\t\t\tif (argument is ILFunction function)\n\t\t\t{\n\t\t\t\treturn (() => function, function.DelegateType);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar (converted, type) = ConvertInstruction(argument);\n\t\t\t\tif (converted == null)\n\t\t\t\t\treturn (converted, type);\n\t\t\t\treturn (BuildQuote, type);\n\n\t\t\t\tILInstruction BuildQuote()\n\t\t\t\t{\n\t\t\t\t\tvar f = converted();\n\t\t\t\t\tif (f is ILFunction lambda && argument is CallInstruction call)\n\t\t\t\t\t{\n\t\t\t\t\t\tSetExpressionTreeFlag(lambda, call);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn f;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid SetExpressionTreeFlag(ILFunction lambda, CallInstruction call)\n\t\t{\n\t\t\tlambda.Kind = IsExpressionTree(call.Method.ReturnType) ? ILFunctionKind.ExpressionTree : ILFunctionKind.Delegate;\n\t\t\tlambda.DelegateType = call.Method.ReturnType;\n\t\t}\n\n\t\tbool ReadParameters(ILInstruction initializer, IList<IParameter> parameters, IList<ILVariable> parameterVariables, ITypeResolveContext resolveContext)\n\t\t{\n\t\t\tswitch (initializer)\n\t\t\t{\n\t\t\t\tcase Block initializerBlock:\n\t\t\t\t\tif (initializerBlock.Kind != BlockKind.ArrayInitializer)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tint i = 0;\n\t\t\t\t\tforeach (var inst in initializerBlock.Instructions.OfType<StObj>())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (i >= this.parameters.Count)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!inst.Value.MatchLdLoc(out var v))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!this.parameters.TryGetValue(v, out var value))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t// Add parameter variable only once to mapping.\n\t\t\t\t\t\tif (!this.parameterMapping.ContainsKey(v))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar param = new ILVariable(VariableKind.Parameter, value.Item1, i) { Name = value.Item2 };\n\t\t\t\t\t\t\tparameterMapping.Add(v, param);\n\t\t\t\t\t\t\tparameterVariables.Add(param);\n\t\t\t\t\t\t\tparameters.Add(new DefaultParameter(value.Item1, value.Item2));\n\t\t\t\t\t\t\tinstructionsToRemove.Add((ILInstruction)v.StoreInstructions[0]);\n\t\t\t\t\t\t}\n\t\t\t\t\t\ti++;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn IsEmptyParameterList(initializer);\n\t\t\t}\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertInstruction(ILInstruction instruction, IType typeHint = null)\n\t\t{\n\t\t\tvar (inst, type) = Convert();\n\n\t\t\tif (inst == null)\n\t\t\t\treturn (null, type);\n\n\t\t\tILInstruction DoConvert()\n\t\t\t{\n\t\t\t\tvar result = inst();\n\t\t\t\tDebug.Assert(type != null, \"IType must be non-null!\");\n\t\t\t\tDebug.Assert(result.ResultType == type.GetStackType(), \"StackTypes must match!\");\n\t\t\t\tif (typeHint != null)\n\t\t\t\t{\n\t\t\t\t\tif (result.ResultType != typeHint.GetStackType())\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new Conv(result, typeHint.GetStackType().ToPrimitiveType(), false, typeHint.GetSign());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\treturn (DoConvert, typeHint ?? type);\n\n\t\t\t(Func<ILInstruction>, IType) Convert()\n\t\t\t{\n\t\t\t\tswitch (instruction)\n\t\t\t\t{\n\t\t\t\t\tcase CallInstruction invocation:\n\t\t\t\t\t\tif (invocation.Method.DeclaringType.FullName != \"System.Linq.Expressions.Expression\")\n\t\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\n\t\t\t\t\t\tswitch (invocation.Method.Name)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase \"Add\":\n\t\t\t\t\t\t\t\treturn ConvertBinaryNumericOperator(invocation, BinaryNumericOperator.Add, false);\n\t\t\t\t\t\t\tcase \"AddChecked\":\n\t\t\t\t\t\t\t\treturn ConvertBinaryNumericOperator(invocation, BinaryNumericOperator.Add, true);\n\t\t\t\t\t\t\tcase \"And\":\n\t\t\t\t\t\t\t\treturn ConvertBinaryNumericOperator(invocation, BinaryNumericOperator.BitAnd);\n\t\t\t\t\t\t\tcase \"AndAlso\":\n\t\t\t\t\t\t\t\treturn ConvertLogicOperator(invocation, true);\n\t\t\t\t\t\t\tcase \"ArrayAccess\":\n\t\t\t\t\t\t\tcase \"ArrayIndex\":\n\t\t\t\t\t\t\t\treturn ConvertArrayIndex(invocation);\n\t\t\t\t\t\t\tcase \"ArrayLength\":\n\t\t\t\t\t\t\t\treturn ConvertArrayLength(invocation);\n\t\t\t\t\t\t\tcase \"Call\":\n\t\t\t\t\t\t\t\treturn ConvertCall(invocation);\n\t\t\t\t\t\t\tcase \"Coalesce\":\n\t\t\t\t\t\t\t\treturn ConvertCoalesce(invocation);\n\t\t\t\t\t\t\tcase \"Condition\":\n\t\t\t\t\t\t\t\treturn ConvertCondition(invocation);\n\t\t\t\t\t\t\tcase \"Constant\":\n\t\t\t\t\t\t\t\treturn ConvertConstant(invocation);\n\t\t\t\t\t\t\tcase \"Convert\":\n\t\t\t\t\t\t\t\treturn ConvertCast(invocation, false);\n\t\t\t\t\t\t\tcase \"ConvertChecked\":\n\t\t\t\t\t\t\t\treturn ConvertCast(invocation, true);\n\t\t\t\t\t\t\tcase \"Divide\":\n\t\t\t\t\t\t\t\treturn ConvertBinaryNumericOperator(invocation, BinaryNumericOperator.Div);\n\t\t\t\t\t\t\tcase \"Equal\":\n\t\t\t\t\t\t\t\treturn ConvertComparison(invocation, ComparisonKind.Equality);\n\t\t\t\t\t\t\tcase \"ExclusiveOr\":\n\t\t\t\t\t\t\t\treturn ConvertBinaryNumericOperator(invocation, BinaryNumericOperator.BitXor);\n\t\t\t\t\t\t\tcase \"Field\":\n\t\t\t\t\t\t\t\treturn ConvertField(invocation, typeHint);\n\t\t\t\t\t\t\tcase \"GreaterThan\":\n\t\t\t\t\t\t\t\treturn ConvertComparison(invocation, ComparisonKind.GreaterThan);\n\t\t\t\t\t\t\tcase \"GreaterThanOrEqual\":\n\t\t\t\t\t\t\t\treturn ConvertComparison(invocation, ComparisonKind.GreaterThanOrEqual);\n\t\t\t\t\t\t\tcase \"Invoke\":\n\t\t\t\t\t\t\t\treturn ConvertInvoke(invocation);\n\t\t\t\t\t\t\tcase \"Lambda\":\n\t\t\t\t\t\t\t\treturn ConvertLambda(invocation);\n\t\t\t\t\t\t\tcase \"LeftShift\":\n\t\t\t\t\t\t\t\treturn ConvertBinaryNumericOperator(invocation, BinaryNumericOperator.ShiftLeft);\n\t\t\t\t\t\t\tcase \"LessThan\":\n\t\t\t\t\t\t\t\treturn ConvertComparison(invocation, ComparisonKind.LessThan);\n\t\t\t\t\t\t\tcase \"LessThanOrEqual\":\n\t\t\t\t\t\t\t\treturn ConvertComparison(invocation, ComparisonKind.LessThanOrEqual);\n\t\t\t\t\t\t\tcase \"ListInit\":\n\t\t\t\t\t\t\t\treturn ConvertListInit(invocation);\n\t\t\t\t\t\t\tcase \"MemberInit\":\n\t\t\t\t\t\t\t\treturn ConvertMemberInit(invocation);\n\t\t\t\t\t\t\tcase \"Modulo\":\n\t\t\t\t\t\t\t\treturn ConvertBinaryNumericOperator(invocation, BinaryNumericOperator.Rem);\n\t\t\t\t\t\t\tcase \"Multiply\":\n\t\t\t\t\t\t\t\treturn ConvertBinaryNumericOperator(invocation, BinaryNumericOperator.Mul, false);\n\t\t\t\t\t\t\tcase \"MultiplyChecked\":\n\t\t\t\t\t\t\t\treturn ConvertBinaryNumericOperator(invocation, BinaryNumericOperator.Mul, true);\n\t\t\t\t\t\t\tcase \"Negate\":\n\t\t\t\t\t\t\t\treturn ConvertUnaryNumericOperator(invocation, BinaryNumericOperator.Sub, false);\n\t\t\t\t\t\t\tcase \"NegateChecked\":\n\t\t\t\t\t\t\t\treturn ConvertUnaryNumericOperator(invocation, BinaryNumericOperator.Sub, true);\n\t\t\t\t\t\t\tcase \"New\":\n\t\t\t\t\t\t\t\treturn ConvertNewObject(invocation);\n\t\t\t\t\t\t\tcase \"NewArrayBounds\":\n\t\t\t\t\t\t\t\treturn ConvertNewArrayBounds(invocation);\n\t\t\t\t\t\t\tcase \"NewArrayInit\":\n\t\t\t\t\t\t\t\treturn ConvertNewArrayInit(invocation);\n\t\t\t\t\t\t\tcase \"Not\":\n\t\t\t\t\t\t\t\treturn ConvertNotOperator(invocation);\n\t\t\t\t\t\t\tcase \"NotEqual\":\n\t\t\t\t\t\t\t\treturn ConvertComparison(invocation, ComparisonKind.Inequality);\n\t\t\t\t\t\t\tcase \"OnesComplement\":\n\t\t\t\t\t\t\t\treturn ConvertNotOperator(invocation);\n\t\t\t\t\t\t\tcase \"Or\":\n\t\t\t\t\t\t\t\treturn ConvertBinaryNumericOperator(invocation, BinaryNumericOperator.BitOr);\n\t\t\t\t\t\t\tcase \"OrElse\":\n\t\t\t\t\t\t\t\treturn ConvertLogicOperator(invocation, false);\n\t\t\t\t\t\t\tcase \"Property\":\n\t\t\t\t\t\t\t\treturn ConvertProperty(invocation);\n\t\t\t\t\t\t\tcase \"Quote\":\n\t\t\t\t\t\t\t\treturn ConvertQuote(invocation);\n\t\t\t\t\t\t\tcase \"RightShift\":\n\t\t\t\t\t\t\t\treturn ConvertBinaryNumericOperator(invocation, BinaryNumericOperator.ShiftRight);\n\t\t\t\t\t\t\tcase \"Subtract\":\n\t\t\t\t\t\t\t\treturn ConvertBinaryNumericOperator(invocation, BinaryNumericOperator.Sub, false);\n\t\t\t\t\t\t\tcase \"SubtractChecked\":\n\t\t\t\t\t\t\t\treturn ConvertBinaryNumericOperator(invocation, BinaryNumericOperator.Sub, true);\n\t\t\t\t\t\t\tcase \"TypeAs\":\n\t\t\t\t\t\t\t\treturn ConvertTypeAs(invocation);\n\t\t\t\t\t\t\tcase \"TypeIs\":\n\t\t\t\t\t\t\t\treturn ConvertTypeIs(invocation);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\tcase ILFunction function:\n\t\t\t\t\t\tILFunction ApplyChangesToILFunction()\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (function.Kind == ILFunctionKind.ExpressionTree)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfunction.DelegateType = UnwrapExpressionTree(function.DelegateType);\n\t\t\t\t\t\t\t\tfunction.Kind = ILFunctionKind.Delegate;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn function;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn (ApplyChangesToILFunction, function.DelegateType);\n\t\t\t\t\tcase LdLoc ldloc:\n\t\t\t\t\t\tif (IsExpressionTreeParameter(ldloc.Variable))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Replace an already mapped parameter with the actual ILVariable,\n\t\t\t\t\t\t\t// we generated earlier.\n\t\t\t\t\t\t\tif (parameterMapping.TryGetValue(ldloc.Variable, out var v))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (typeHint.SkipModifiers() is ByReferenceType && !v.Type.IsByRefLike)\n\t\t\t\t\t\t\t\t\treturn (() => new LdLoca(v), typeHint);\n\t\t\t\t\t\t\t\treturn (() => new LdLoc(v), v.Type);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// This is a parameter variable from an outer scope.\n\t\t\t\t\t\t\t// We can't replace these variables just yet, because the transform works backwards.\n\t\t\t\t\t\t\t// We simply return the same instruction again, but return the actual expected type,\n\t\t\t\t\t\t\t// so our transform can continue normally.\n\t\t\t\t\t\t\t// Later, we will replace all references to unmapped variables,\n\t\t\t\t\t\t\t// with references to mapped parameters.\n\t\t\t\t\t\t\tif (ldloc.Variable.IsSingleDefinition && ldloc.Variable.StoreInstructions[0] is ILInstruction instr)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (MatchParameterVariableAssignment(instr, out _, out var t, out _))\n\t\t\t\t\t\t\t\t\treturn (() => new ExpressionTreeCast(t, ldloc, false), t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool IsExpressionTree(IType delegateType) => delegateType is ParameterizedType pt\n\t\t\t&& pt.FullName == \"System.Linq.Expressions.Expression\"\n\t\t\t&& pt.TypeArguments.Count == 1;\n\n\t\tIType UnwrapExpressionTree(IType delegateType)\n\t\t{\n\t\t\tif (delegateType is ParameterizedType pt && pt.FullName == \"System.Linq.Expressions.Expression\" && pt.TypeArguments.Count == 1)\n\t\t\t{\n\t\t\t\treturn pt.TypeArguments[0];\n\t\t\t}\n\t\t\treturn delegateType;\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertArrayIndex(CallInstruction invocation)\n\t\t{\n\t\t\tif (invocation.Arguments.Count != 2)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar (array, arrayType) = ConvertInstruction(invocation.Arguments[0]);\n\t\t\tif (array == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (!(arrayType is ArrayType type))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (!MatchArgumentList(invocation.Arguments[1], out var arguments))\n\t\t\t\targuments = new[] { invocation.Arguments[1] };\n\n\t\t\tILInstruction Convert()\n\t\t\t{\n\t\t\t\tFunc<ILInstruction>[] toBeConverted = new Func<ILInstruction>[arguments.Count];\n\t\t\t\tfor (int i = 0; i < arguments.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tvar (converted, indexType) = ConvertInstruction(arguments[i]);\n\t\t\t\t\tif (converted == null)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\ttoBeConverted[i] = converted;\n\t\t\t\t}\n\t\t\t\treturn new LdObj(new LdElema(type.ElementType, array(), toBeConverted.SelectArray(f => f())) { DelayExceptions = true }, type.ElementType);\n\t\t\t}\n\t\t\treturn (Convert, type.ElementType);\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertArrayLength(CallInstruction invocation)\n\t\t{\n\t\t\tif (invocation.Arguments.Count != 1)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar (converted, _) = ConvertInstruction(invocation.Arguments[0]);\n\t\t\tif (converted == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\treturn (() => new LdLen(StackType.I4, converted()), context.TypeSystem.FindType(KnownTypeCode.Int32));\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertBinaryNumericOperator(CallInstruction invocation, BinaryNumericOperator op, bool? isChecked = null)\n\t\t{\n\t\t\tif (invocation.Arguments.Count < 2)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar (left, leftType) = ConvertInstruction(invocation.Arguments[0]);\n\t\t\tif (left == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar (right, rightType) = ConvertInstruction(invocation.Arguments[1]);\n\t\t\tif (right == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tIMember method;\n\t\t\tswitch (invocation.Arguments.Count)\n\t\t\t{\n\t\t\t\tcase 2:\n\t\t\t\t\tif (op == BinaryNumericOperator.ShiftLeft || op == BinaryNumericOperator.ShiftRight)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!NullableType.GetUnderlyingType(rightType).IsKnownType(KnownTypeCode.Int32))\n\t\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!rightType.Equals(leftType))\n\t\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\t}\n\t\t\t\t\treturn (() => new BinaryNumericInstruction(op, left(), right(),\n\t\t\t\t\t\tNullableType.GetUnderlyingType(leftType).GetStackType(),\n\t\t\t\t\t\tNullableType.GetUnderlyingType(rightType).GetStackType(),\n\t\t\t\t\t\tisChecked == true,\n\t\t\t\t\t\tleftType.GetSign(),\n\t\t\t\t\t\tisLifted: NullableType.IsNullable(leftType) || NullableType.IsNullable(rightType)), leftType);\n\t\t\t\tcase 3:\n\t\t\t\t\tif (!MatchGetMethodFromHandle(invocation.Arguments[2], out method))\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\treturn (() => new Call((IMethod)method) {\n\t\t\t\t\t\tArguments = { left(), right() }\n\t\t\t\t\t}, method.ReturnType);\n\t\t\t\tcase 4:\n\t\t\t\t\tif (!invocation.Arguments[2].MatchLdcI4(out var isLiftedToNull))\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\tif (!MatchGetMethodFromHandle(invocation.Arguments[3], out method))\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\tbool isLifted = NullableType.IsNullable(leftType);\n\t\t\t\t\tif (isLifted)\n\t\t\t\t\t\tmethod = CSharpOperators.LiftUserDefinedOperator((IMethod)method);\n\t\t\t\t\treturn (() => new Call((IMethod)method) {\n\t\t\t\t\t\tArguments = { left(), right() }\n\t\t\t\t\t}, isLiftedToNull != 0 ? NullableType.Create(method.Compilation, method.ReturnType) : method.ReturnType);\n\t\t\t\tdefault:\n\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t}\n\t\t}\n\n\t\t(Func<ILVariable, ILInstruction>, IType) ConvertBind(CallInstruction invocation)\n\t\t{\n\t\t\tif (invocation.Arguments.Count != 2)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar (value, typeValue) = ConvertInstruction(invocation.Arguments[1]);\n\t\t\tif (value == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (MatchGetMethodFromHandle(invocation.Arguments[0], out var member))\n\t\t\t{\n\t\t\t\tvar method = (IMethod)member;\n\t\t\t\t// It is possible to use Expression.Bind with a get-accessor,\n\t\t\t\t// however, it would be an invalid expression tree if the property is readonly.\n\t\t\t\t// As this is an assignment, the ILAst expects a set-accessor. To avoid any problems\n\t\t\t\t// constructing property assignments, we explicitly use the set-accessor instead.\n\t\t\t\tif (method.AccessorOwner is IProperty { CanSet: true } property && method != property.Setter)\n\t\t\t\t{\n\t\t\t\t\tmember = property.Setter;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (MatchGetFieldFromHandle(invocation.Arguments[0], out member))\n\t\t\t{\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t}\n\t\t\tswitch (member)\n\t\t\t{\n\t\t\t\tcase IMethod method:\n\t\t\t\t\tif (method.IsStatic)\n\t\t\t\t\t\treturn (targetVariable => new Call(method) { Arguments = { new LdLoc(targetVariable), value() } }, method.ReturnType);\n\t\t\t\t\telse\n\t\t\t\t\t\treturn (targetVariable => new CallVirt(method) { Arguments = { new LdLoc(targetVariable), value() } }, method.ReturnType);\n\t\t\t\tcase IField field:\n\t\t\t\t\treturn (targetVariable => new StObj(new LdFlda(new LdLoc(targetVariable), (IField)member) { DelayExceptions = true }, value(), member.ReturnType), field.ReturnType);\n\t\t\t}\n\t\t\treturn (null, SpecialType.UnknownType);\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertCall(CallInstruction invocation)\n\t\t{\n\t\t\tif (invocation.Arguments.Count < 2)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tIList<ILInstruction> arguments = null;\n\t\t\tFunc<ILInstruction> targetConverter = null;\n\t\t\tIType targetType = null;\n\t\t\tif (MatchGetMethodFromHandle(invocation.Arguments[0], out var member))\n\t\t\t{\n\t\t\t\t// static method\n\t\t\t\tif (invocation.Arguments.Count != 2 || !MatchArgumentList(invocation.Arguments[1], out arguments))\n\t\t\t\t{\n\t\t\t\t\targuments = new List<ILInstruction>(invocation.Arguments.Skip(1));\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (MatchGetMethodFromHandle(invocation.Arguments[1], out member))\n\t\t\t{\n\t\t\t\tif (invocation.Arguments.Count != 3 || !MatchArgumentList(invocation.Arguments[2], out arguments))\n\t\t\t\t{\n\t\t\t\t\targuments = new List<ILInstruction>(invocation.Arguments.Skip(2));\n\t\t\t\t}\n\t\t\t\tif (!invocation.Arguments[0].MatchLdNull())\n\t\t\t\t{\n\t\t\t\t\t(targetConverter, targetType) = ConvertInstruction(invocation.Arguments[0]);\n\t\t\t\t\tif (targetConverter == null)\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (arguments == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tIMethod method = (IMethod)member;\n\t\t\tvar convertedArguments = ConvertCallArguments(arguments, method);\n\t\t\tif (convertedArguments == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (method.FullName == \"System.Reflection.MethodInfo.CreateDelegate\" && method.Parameters.Count == 2)\n\t\t\t{\n\t\t\t\tif (!MatchGetMethodFromHandle(UnpackConstant(invocation.Arguments[0]), out var targetMethod))\n\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\tif (!MatchGetTypeFromHandle(UnpackConstant(arguments[0]), out var delegateType))\n\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\treturn (() => new NewObj(delegateType.GetConstructors().Single()) {\n\t\t\t\t\tArguments = { convertedArguments[1](), new LdFtn((IMethod)targetMethod) }\n\t\t\t\t}, delegateType);\n\t\t\t}\n\n\t\t\tCallInstruction BuildCall()\n\t\t\t{\n\t\t\t\tCallInstruction call;\n\t\t\t\tif (method.IsStatic)\n\t\t\t\t{\n\t\t\t\t\tcall = new Call(method);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcall = new CallVirt(method);\n\t\t\t\t}\n\t\t\t\tif (targetConverter != null)\n\t\t\t\t{\n\t\t\t\t\tcall.Arguments.Add(PrepareCallTarget(method.DeclaringType, targetConverter(), targetType));\n\t\t\t\t}\n\t\t\t\tcall.Arguments.AddRange(convertedArguments.Select(f => f()));\n\t\t\t\treturn call;\n\t\t\t}\n\t\t\treturn (BuildCall, method.ReturnType);\n\t\t}\n\n\t\tILInstruction PrepareCallTarget(IType expectedType, ILInstruction target, IType targetType)\n\t\t{\n\t\t\tILInstruction result;\n\t\t\tswitch (CallInstruction.ExpectedTypeForThisPointer(expectedType, null))\n\t\t\t{\n\t\t\t\tcase StackType.Ref:\n\t\t\t\t\tif (target.ResultType == StackType.Ref)\n\t\t\t\t\t{\n\t\t\t\t\t\tresult = target;\n\t\t\t\t\t}\n\t\t\t\t\telse if (target is LdLoc ldloc)\n\t\t\t\t\t{\n\t\t\t\t\t\tresult = new LdLoca(ldloc.Variable).WithILRange(ldloc);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tresult = new AddressOf(target, expectedType);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase StackType.O:\n\t\t\t\t\tif (targetType.IsReferenceType == false)\n\t\t\t\t\t{\n\t\t\t\t\t\tresult = new Box(target, targetType);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tresult = target;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tresult = target;\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (expectedType.Kind == TypeKind.Unknown && result.ResultType != StackType.Unknown)\n\t\t\t{\n\t\t\t\tresult = new Conv(target, PrimitiveType.Unknown, false, Sign.None);\n\t\t\t}\n\t\t\telse if (expectedType.Kind != TypeKind.Unknown && result.ResultType == StackType.Unknown)\n\t\t\t{\n\t\t\t\t// if references are missing, we need to coerce the unknown type to the expected type.\n\t\t\t\t// Otherwise we will get loads of assertions and expression trees\n\t\t\t\t// are usually explicit about any conversions.\n\t\t\t\tresult = new Conv(result, expectedType.ToPrimitiveType(), false, Sign.None);\n\t\t\t}\n\n\t\t\treturn result;\n\t\t}\n\n\t\tILInstruction UnpackConstant(ILInstruction inst)\n\t\t{\n\t\t\tif (!(inst is CallInstruction call && call.Method.FullName == \"System.Linq.Expressions.Expression.Constant\" && call.Arguments.Count == 2))\n\t\t\t\treturn inst;\n\t\t\treturn call.Arguments[0];\n\t\t}\n\n\t\tFunc<ILInstruction>[] ConvertCallArguments(IList<ILInstruction> arguments, IMethod method)\n\t\t{\n\t\t\tvar converted = new Func<ILInstruction>[arguments.Count];\n\t\t\tDebug.Assert(arguments.Count == method.Parameters.Count);\n\t\t\tfor (int i = 0; i < arguments.Count; i++)\n\t\t\t{\n\t\t\t\tvar expectedType = method.Parameters[i].Type;\n\t\t\t\tvar argument = ConvertInstruction(arguments[i], expectedType).Item1;\n\t\t\t\tif (argument == null)\n\t\t\t\t\treturn null;\n\t\t\t\tconverted[i] = argument;\n\t\t\t}\n\t\t\treturn converted;\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertCast(CallInstruction invocation, bool isChecked)\n\t\t{\n\t\t\tif (invocation.Arguments.Count < 2)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (!MatchGetTypeFromHandle(invocation.Arguments[1], out var targetType))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar (expr, exprType) = ConvertInstruction(invocation.Arguments[0]);\n\t\t\tif (expr == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (exprType.IsSmallIntegerType() && targetType.IsKnownType(KnownTypeCode.Int32))\n\t\t\t\treturn (expr, targetType);\n\t\t\treturn (() => new ExpressionTreeCast(targetType, expr(), isChecked), targetType);\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertCoalesce(CallInstruction invocation)\n\t\t{\n\t\t\tif (invocation.Arguments.Count != 2)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar (trueInst, trueInstType) = ConvertInstruction(invocation.Arguments[0]);\n\t\t\tif (trueInst == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar (fallbackInst, fallbackInstType) = ConvertInstruction(invocation.Arguments[1]);\n\t\t\tif (fallbackInst == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar kind = NullCoalescingKind.Ref;\n\t\t\tvar trueInstTypeNonNullable = NullableType.GetUnderlyingType(trueInstType);\n\t\t\tIType targetType;\n\t\t\tif (NullableType.IsNullable(trueInstType) && conversions.ImplicitConversion(fallbackInstType, trueInstTypeNonNullable).IsValid)\n\t\t\t{\n\t\t\t\ttargetType = trueInstTypeNonNullable;\n\t\t\t\tkind = NullableType.IsNullable(fallbackInstType) ? NullCoalescingKind.Nullable : NullCoalescingKind.NullableWithValueFallback;\n\t\t\t}\n\t\t\telse if (conversions.ImplicitConversion(fallbackInstType, trueInstType).IsValid)\n\t\t\t{\n\t\t\t\ttargetType = trueInstType;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttargetType = fallbackInstType;\n\t\t\t}\n\t\t\treturn (() => new NullCoalescingInstruction(kind, trueInst(), fallbackInst()) {\n\t\t\t\tUnderlyingResultType = trueInstTypeNonNullable.GetStackType()\n\t\t\t}, targetType);\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertComparison(CallInstruction invocation, ComparisonKind kind)\n\t\t{\n\t\t\tif (invocation.Arguments.Count < 2)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar (left, leftType) = ConvertInstruction(invocation.Arguments[0]);\n\t\t\tif (left == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar (right, rightType) = ConvertInstruction(invocation.Arguments[1]);\n\t\t\tif (right == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (invocation.Arguments.Count == 4 && invocation.Arguments[2].MatchLdcI4(out var isLiftedToNull) && MatchGetMethodFromHandle(invocation.Arguments[3], out var method))\n\t\t\t{\n\t\t\t\tbool isLifted = NullableType.IsNullable(leftType);\n\t\t\t\tif (isLifted)\n\t\t\t\t\tmethod = CSharpOperators.LiftUserDefinedOperator((IMethod)method);\n\t\t\t\treturn (() => new Call((IMethod)method) { Arguments = { left(), right() } }, isLiftedToNull != 0 ? NullableType.Create(method.Compilation, method.ReturnType) : method.ReturnType);\n\t\t\t}\n\t\t\tvar rr = resolver.ResolveBinaryOperator(kind.ToBinaryOperatorType(), new ResolveResult(leftType), new ResolveResult(rightType)) as OperatorResolveResult;\n\t\t\tif (rr != null && !rr.IsError && rr.UserDefinedOperatorMethod != null)\n\t\t\t{\n\t\t\t\treturn (() => new Call(rr.UserDefinedOperatorMethod) { Arguments = { left(), right() } }, rr.UserDefinedOperatorMethod.ReturnType);\n\t\t\t}\n\t\t\tif (leftType.IsKnownType(KnownTypeCode.String) && rightType.IsKnownType(KnownTypeCode.String))\n\t\t\t{\n\t\t\t\tIMethod operatorMethod;\n\t\t\t\tswitch (kind)\n\t\t\t\t{\n\t\t\t\t\tcase ComparisonKind.Equality:\n\t\t\t\t\t\toperatorMethod = leftType.GetMethods(m => m.IsOperator && m.Name == \"op_Equality\" && m.Parameters.Count == 2).FirstOrDefault(m => m.Parameters[0].Type.IsKnownType(KnownTypeCode.String) && m.Parameters[1].Type.IsKnownType(KnownTypeCode.String));\n\t\t\t\t\t\tif (operatorMethod == null)\n\t\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase ComparisonKind.Inequality:\n\t\t\t\t\t\toperatorMethod = leftType.GetMethods(m => m.IsOperator && m.Name == \"op_Inequality\" && m.Parameters.Count == 2).FirstOrDefault(m => m.Parameters[0].Type.IsKnownType(KnownTypeCode.String) && m.Parameters[1].Type.IsKnownType(KnownTypeCode.String));\n\t\t\t\t\t\tif (operatorMethod == null)\n\t\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t}\n\t\t\t\treturn (() => new Call(operatorMethod) { Arguments = { left(), right() } }, operatorMethod.ReturnType);\n\t\t\t}\n\t\t\tvar resultType = context.TypeSystem.FindType(KnownTypeCode.Boolean);\n\t\t\tvar lifting = NullableType.IsNullable(leftType) ? ComparisonLiftingKind.CSharp : ComparisonLiftingKind.None;\n\t\t\tvar utype = NullableType.GetUnderlyingType(leftType);\n\t\t\treturn (() => new Comp(kind, lifting, utype.GetStackType(), utype.GetSign(), left(), right()), resultType);\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertCondition(CallInstruction invocation)\n\t\t{\n\t\t\tif (invocation.Arguments.Count != 3)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar (condition, conditionType) = ConvertInstruction(invocation.Arguments[0]);\n\t\t\tif (condition == null || !conditionType.IsKnownType(KnownTypeCode.Boolean))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar (trueInst, trueInstType) = ConvertInstruction(invocation.Arguments[1]);\n\t\t\tif (trueInst == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar (falseInst, falseInstType) = ConvertInstruction(invocation.Arguments[2]);\n\t\t\tif (falseInst == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (!NormalizeTypeVisitor.TypeErasure.EquivalentTypes(trueInstType, falseInstType))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\treturn (() => new IfInstruction(condition(), trueInst(), falseInst()), trueInstType);\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertConstant(CallInstruction invocation)\n\t\t{\n\t\t\tif (!MatchConstantCall(invocation, out var value, out var type))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (value.MatchBox(out var arg, out var boxType))\n\t\t\t{\n\t\t\t\tif (boxType.Kind == TypeKind.Enum || boxType.IsKnownType(KnownTypeCode.Boolean))\n\t\t\t\t\treturn (() => new ExpressionTreeCast(boxType, ConvertValue(arg, invocation), false), boxType);\n\t\t\t\treturn (() => ConvertValue(arg, invocation), type);\n\t\t\t}\n\t\t\treturn (() => ConvertValue(value, invocation), type);\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertElementInit(CallInstruction invocation)\n\t\t{\n\t\t\tif (invocation.Arguments.Count != 2)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (!MatchGetMethodFromHandle(invocation.Arguments[0], out var member))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (!MatchArgumentList(invocation.Arguments[1], out var arguments))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar args = new Func<ILInstruction>[arguments.Count];\n\t\t\tfor (int i = 0; i < arguments.Count; i++)\n\t\t\t{\n\t\t\t\tvar arg = ConvertInstruction(arguments[i]).Item1;\n\t\t\t\tif (arg == null)\n\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\targs[i] = arg;\n\t\t\t}\n\n\t\t\tILInstruction BuildCall()\n\t\t\t{\n\t\t\t\tCallInstruction call = member.IsStatic\n\t\t\t\t\t? (CallInstruction)new Call((IMethod)member)\n\t\t\t\t\t: new CallVirt((IMethod)member);\n\t\t\t\tcall.Arguments.AddRange(args.Select(f => f()));\n\t\t\t\treturn call;\n\t\t\t}\n\t\t\treturn (BuildCall, member.ReturnType);\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertField(CallInstruction invocation, IType typeHint)\n\t\t{\n\t\t\tif (invocation.Arguments.Count != 2)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tFunc<ILInstruction> targetConverter = null;\n\t\t\tif (!invocation.Arguments[0].MatchLdNull())\n\t\t\t{\n\t\t\t\ttargetConverter = ConvertInstruction(invocation.Arguments[0]).Item1;\n\t\t\t\tif (targetConverter == null)\n\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t}\n\t\t\tif (!MatchGetFieldFromHandle(invocation.Arguments[1], out var member))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tIType type = member.ReturnType;\n\t\t\tif (typeHint.SkipModifiers() is ByReferenceType && !member.ReturnType.IsByRefLike)\n\t\t\t{\n\t\t\t\ttype = typeHint;\n\t\t\t}\n\t\t\treturn (BuildField, type);\n\n\t\t\tILInstruction BuildField()\n\t\t\t{\n\t\t\t\tILInstruction inst;\n\t\t\t\tif (targetConverter == null)\n\t\t\t\t{\n\t\t\t\t\tinst = new LdsFlda((IField)member);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar target = targetConverter();\n\t\t\t\t\tif (member.DeclaringType.IsReferenceType == true)\n\t\t\t\t\t{\n\t\t\t\t\t\tinst = new LdFlda(target, (IField)member) { DelayExceptions = true };\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tinst = new LdFlda(new AddressOf(target, member.DeclaringType), (IField)member) { DelayExceptions = true };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!(typeHint.SkipModifiers() is ByReferenceType && !member.ReturnType.IsByRefLike))\n\t\t\t\t{\n\t\t\t\t\tinst = new LdObj(inst, member.ReturnType);\n\t\t\t\t}\n\t\t\t\treturn inst;\n\t\t\t}\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertInvoke(CallInstruction invocation)\n\t\t{\n\t\t\tif (invocation.Arguments.Count != 2)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar (targetConverter, targetType) = ConvertInstruction(invocation.Arguments[0]);\n\t\t\tif (targetConverter == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar invokeMethod = targetType.GetDelegateInvokeMethod();\n\t\t\tif (invokeMethod == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (!MatchArgumentList(invocation.Arguments[1], out var arguments))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar convertedArguments = ConvertCallArguments(arguments, invokeMethod);\n\t\t\tif (convertedArguments == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\n\t\t\tILInstruction BuildCall()\n\t\t\t{\n\t\t\t\tvar call = new CallVirt(invokeMethod);\n\t\t\t\tcall.Arguments.Add(targetConverter());\n\t\t\t\tcall.Arguments.AddRange(convertedArguments.Select(f => f()));\n\t\t\t\treturn call;\n\t\t\t}\n\t\t\treturn (BuildCall, invokeMethod.ReturnType);\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertListInit(CallInstruction invocation)\n\t\t{\n\t\t\tif (invocation.Arguments.Count < 2)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar newObj = ConvertInstruction(invocation.Arguments[0]).Item1;\n\t\t\tif (newObj == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (!MatchNew((CallInstruction)invocation.Arguments[0], out var ctor))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tIList<ILInstruction> arguments;\n\t\t\tif (!MatchGetMethodFromHandle(invocation.Arguments[1], out var member))\n\t\t\t{\n\t\t\t\tif (!MatchArgumentList(invocation.Arguments[1], out arguments))\n\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (invocation.Arguments.Count != 3 || !MatchArgumentList(invocation.Arguments[2], out arguments))\n\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t}\n\t\t\tif (arguments == null || arguments.Count == 0)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tFunc<ILVariable, ILInstruction>[] convertedArguments = new Func<ILVariable, ILInstruction>[arguments.Count];\n\t\t\tfor (int i = 0; i < arguments.Count; i++)\n\t\t\t{\n\t\t\t\tif (arguments[i] is CallInstruction elementInit && elementInit.Method.FullName == \"System.Linq.Expressions.Expression.ElementInit\")\n\t\t\t\t{\n\t\t\t\t\tvar arg = ConvertElementInit(elementInit).Item1;\n\t\t\t\t\tif (arg == null)\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\n\t\t\t\t\tconvertedArguments[i] = v => { var a = arg(); ((CallInstruction)a).Arguments.Insert(0, new LdLoc(v)); return a; };\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar arg = ConvertInstruction(arguments[i]).Item1;\n\t\t\t\t\tif (arg == null)\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\tconvertedArguments[i] = v => arg();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tBlock BuildBlock()\n\t\t\t{\n\t\t\t\tvar initializerBlock = new Block(BlockKind.CollectionInitializer);\n\n\t\t\t\tILFunction function = lambdaStack.Peek();\n\t\t\t\tvar initializer = function.RegisterVariable(VariableKind.InitializerTarget, ctor.DeclaringType);\n\t\t\t\tinitializerBlock.FinalInstruction = new LdLoc(initializer);\n\t\t\t\tinitializerBlock.Instructions.Add(new StLoc(initializer, newObj()));\n\t\t\t\tinitializerBlock.Instructions.AddRange(convertedArguments.Select(f => f(initializer)));\n\t\t\t\treturn initializerBlock;\n\t\t\t}\n\t\t\treturn (BuildBlock, ctor.DeclaringType);\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertLogicOperator(CallInstruction invocation, bool and)\n\t\t{\n\t\t\tif (invocation.Arguments.Count < 2)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar (left, leftType) = ConvertInstruction(invocation.Arguments[0]);\n\t\t\tif (left == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar (right, rightType) = ConvertInstruction(invocation.Arguments[1]);\n\t\t\tif (right == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tIMember method;\n\t\t\tswitch (invocation.Arguments.Count)\n\t\t\t{\n\t\t\t\tcase 2:\n\t\t\t\t\tvar resultType = context.TypeSystem.FindType(KnownTypeCode.Boolean);\n\t\t\t\t\treturn (() => and ? IfInstruction.LogicAnd(left(), right()) : IfInstruction.LogicOr(left(), right()), resultType);\n\t\t\t\tcase 3:\n\t\t\t\t\tif (!MatchGetMethodFromHandle(invocation.Arguments[2], out method))\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\treturn (() => new Call((IMethod)method) {\n\t\t\t\t\t\tArguments = { left(), right() }\n\t\t\t\t\t}, method.ReturnType);\n\t\t\t\tcase 4:\n\t\t\t\t\tif (!invocation.Arguments[2].MatchLdcI4(out var isLiftedToNull))\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\tif (!MatchGetMethodFromHandle(invocation.Arguments[3], out method))\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\tbool isLifted = NullableType.IsNullable(leftType);\n\t\t\t\t\tif (isLifted)\n\t\t\t\t\t\tmethod = CSharpOperators.LiftUserDefinedOperator((IMethod)method);\n\t\t\t\t\treturn (() => new Call((IMethod)method) {\n\t\t\t\t\t\tArguments = { left(), right() }\n\t\t\t\t\t}, isLiftedToNull != 0 ? NullableType.Create(method.Compilation, method.ReturnType) : method.ReturnType);\n\t\t\t\tdefault:\n\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t}\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertMemberInit(CallInstruction invocation)\n\t\t{\n\t\t\tif (invocation.Arguments.Count != 2)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar newObj = ConvertInstruction(invocation.Arguments[0]).Item1;\n\t\t\tif (newObj == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (!MatchNew((CallInstruction)invocation.Arguments[0], out var ctor))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (!MatchArgumentList(invocation.Arguments[1], out var arguments))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (arguments == null || arguments.Count == 0)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\n\t\t\tFunc<ILVariable, ILInstruction>[] convertedArguments = new Func<ILVariable, ILInstruction>[arguments.Count];\n\t\t\tfor (int i = 0; i < arguments.Count; i++)\n\t\t\t{\n\t\t\t\tFunc<ILVariable, ILInstruction> arg;\n\t\t\t\tif (arguments[i] is CallInstruction bind && bind.Method.FullName == \"System.Linq.Expressions.Expression.Bind\")\n\t\t\t\t{\n\t\t\t\t\targ = ConvertBind(bind).Item1;\n\t\t\t\t\tif (arg == null)\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t}\n\t\t\t\tconvertedArguments[i] = arg;\n\t\t\t}\n\n\t\t\tILInstruction BuildBlock()\n\t\t\t{\n\t\t\t\tvar function = lambdaStack.Peek();\n\t\t\t\tvar initializer = function.RegisterVariable(VariableKind.InitializerTarget, ctor.DeclaringType);\n\n\t\t\t\tvar initializerBlock = new Block(BlockKind.CollectionInitializer);\n\t\t\t\tinitializerBlock.FinalInstruction = new LdLoc(initializer);\n\t\t\t\tinitializerBlock.Instructions.Add(new StLoc(initializer, newObj()));\n\t\t\t\tinitializerBlock.Instructions.AddRange(convertedArguments.Select(f => f(initializer)));\n\n\t\t\t\treturn initializerBlock;\n\t\t\t}\n\n\t\t\treturn (BuildBlock, ctor.DeclaringType);\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertNewArrayBounds(CallInstruction invocation)\n\t\t{\n\t\t\tif (invocation.Arguments.Count != 2)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (!MatchGetTypeFromHandle(invocation.Arguments[0], out var type))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (!MatchArgumentList(invocation.Arguments[1], out var arguments))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (arguments.Count == 0)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar indices = new Func<ILInstruction>[arguments.Count];\n\t\t\tfor (int i = 0; i < arguments.Count; i++)\n\t\t\t{\n\t\t\t\tvar index = ConvertInstruction(arguments[i]).Item1;\n\t\t\t\tif (index == null)\n\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\tindices[i] = index;\n\t\t\t}\n\t\t\treturn (() => new NewArr(type, indices.SelectArray(f => f())), new ArrayType(context.TypeSystem, type, arguments.Count));\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertNewArrayInit(CallInstruction invocation)\n\t\t{\n\t\t\tif (invocation.Arguments.Count != 2)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (!MatchGetTypeFromHandle(invocation.Arguments[0], out var type))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (!MatchArgumentList(invocation.Arguments[1], out var arguments))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tArrayType arrayType = new ArrayType(context.BlockContext.TypeSystem, type);\n\t\t\tif (arguments.Count == 0)\n\t\t\t\treturn (() => new NewArr(type, new LdcI4(0)), arrayType);\n\t\t\tvar convertedArguments = new Func<ILInstruction>[arguments.Count];\n\t\t\tfor (int i = 0; i < arguments.Count; i++)\n\t\t\t{\n\t\t\t\tILInstruction item = arguments[i];\n\t\t\t\tvar value = ConvertInstruction(item).Item1;\n\t\t\t\tif (value == null)\n\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\tconvertedArguments[i] = value;\n\t\t\t}\n\n\t\t\tILInstruction BuildInitializer()\n\t\t\t{\n\t\t\t\tvar block = (Block)invocation.Arguments[1];\n\t\t\t\tvar function = lambdaStack.Peek();\n\t\t\t\tvar variable = function.RegisterVariable(VariableKind.InitializerTarget, arrayType);\n\t\t\t\tBlock initializer = new Block(BlockKind.ArrayInitializer);\n\t\t\t\tinitializer.Instructions.Add(new StLoc(variable, new NewArr(type, new LdcI4(convertedArguments.Length))));\n\t\t\t\tfor (int i = 0; i < convertedArguments.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tinitializer.Instructions.Add(new StObj(new LdElema(type, new LdLoc(variable), new LdcI4(i)) { DelayExceptions = true }, convertedArguments[i](), type));\n\t\t\t\t}\n\t\t\t\tinitializer.FinalInstruction = new LdLoc(variable);\n\t\t\t\treturn initializer;\n\t\t\t}\n\n\t\t\treturn (BuildInitializer, arrayType);\n\t\t}\n\n\t\tbool MatchNew(CallInstruction invocation, out IMethod ctor)\n\t\t{\n\t\t\tctor = null;\n\t\t\tif (invocation.Method.Name != \"New\")\n\t\t\t\treturn false;\n\t\t\tswitch (invocation.Arguments.Count)\n\t\t\t{\n\t\t\t\tcase 1:\n\t\t\t\t\tif (MatchGetTypeFromHandle(invocation.Arguments[0], out var type))\n\t\t\t\t\t{\n\t\t\t\t\t\tctor = type.GetConstructors(c => c.Parameters.Count == 0).FirstOrDefault();\n\t\t\t\t\t\treturn ctor != null;\n\t\t\t\t\t}\n\t\t\t\t\tif (MatchGetConstructorFromHandle(invocation.Arguments[0], out var member))\n\t\t\t\t\t{\n\t\t\t\t\t\tctor = (IMethod)member;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\tcase 2:\n\t\t\t\tcase 3:\n\t\t\t\t\tif (!MatchGetConstructorFromHandle(invocation.Arguments[0], out member))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tctor = (IMethod)member;\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertNewObject(CallInstruction invocation)\n\t\t{\n\t\t\tswitch (invocation.Arguments.Count)\n\t\t\t{\n\t\t\t\tcase 1:\n\t\t\t\t\tif (MatchGetTypeFromHandle(invocation.Arguments[0], out var type))\n\t\t\t\t\t{\n\t\t\t\t\t\tvar ctor = type.GetConstructors(c => c.Parameters.Count == 0).FirstOrDefault();\n\t\t\t\t\t\tif (ctor == null)\n\t\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\t\treturn (() => new NewObj(ctor), type);\n\t\t\t\t\t}\n\t\t\t\t\tif (MatchGetConstructorFromHandle(invocation.Arguments[0], out var member))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn (() => new NewObj((IMethod)member), member.DeclaringType);\n\t\t\t\t\t}\n\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\tcase 2:\n\t\t\t\t\tif (!MatchGetConstructorFromHandle(invocation.Arguments[0], out member))\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\tif (!MatchArgumentList(invocation.Arguments[1], out var arguments))\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\tIMethod method = (IMethod)member;\n\t\t\t\t\tFunc<ILInstruction>[] convertedArguments = ConvertCallArguments(arguments, method);\n\t\t\t\t\tif (convertedArguments == null)\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\treturn (() => BuildNewObj(method, convertedArguments), member.DeclaringType);\n\t\t\t\tcase 3:\n\t\t\t\t\tif (!MatchGetConstructorFromHandle(invocation.Arguments[0], out member))\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\tif (!MatchArgumentList(invocation.Arguments[1], out arguments))\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\tmethod = (IMethod)member;\n\t\t\t\t\tconvertedArguments = ConvertCallArguments(arguments, method);\n\t\t\t\t\tif (convertedArguments == null)\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\treturn (() => BuildNewObj(method, convertedArguments), member.DeclaringType);\n\t\t\t}\n\n\t\t\tILInstruction BuildNewObj(IMethod method, Func<ILInstruction>[] args)\n\t\t\t{\n\t\t\t\tvar newObj = new NewObj(method);\n\t\t\t\tnewObj.Arguments.AddRange(args.Select(f => f()));\n\t\t\t\treturn newObj;\n\t\t\t}\n\n\t\t\treturn (null, SpecialType.UnknownType);\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertNotOperator(CallInstruction invocation)\n\t\t{\n\t\t\tif (invocation.Arguments.Count < 1)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar (argument, argumentType) = ConvertInstruction(invocation.Arguments[0]);\n\t\t\tif (argument == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar underlyingType = NullableType.GetUnderlyingType(argumentType);\n\t\t\tswitch (invocation.Arguments.Count)\n\t\t\t{\n\t\t\t\tcase 1:\n\t\t\t\t\tbool isLifted = NullableType.IsNullable(argumentType);\n\t\t\t\t\treturn (() => underlyingType.IsKnownType(KnownTypeCode.Boolean)\n\t\t\t\t\t\t? Comp.LogicNot(argument(), isLifted)\n\t\t\t\t\t\t: (ILInstruction)new BitNot(argument(), isLifted, underlyingType.GetStackType()), argumentType);\n\t\t\t\tcase 2:\n\t\t\t\t\tif (!MatchGetMethodFromHandle(invocation.Arguments[1], out var method))\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\treturn (() => new Call((IMethod)method) {\n\t\t\t\t\t\tArguments = { argument() }\n\t\t\t\t\t}, method.ReturnType);\n\t\t\t\tdefault:\n\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t}\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertProperty(CallInstruction invocation)\n\t\t{\n\t\t\tif (invocation.Arguments.Count < 2)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tFunc<ILInstruction> targetConverter = null;\n\t\t\tIType targetType = null;\n\t\t\tif (!invocation.Arguments[0].MatchLdNull())\n\t\t\t{\n\t\t\t\t(targetConverter, targetType) = ConvertInstruction(invocation.Arguments[0]);\n\t\t\t\tif (targetConverter == null)\n\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t}\n\t\t\tif (!MatchGetMethodFromHandle(invocation.Arguments[1], out var member))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tIList<ILInstruction> arguments;\n\t\t\tif (invocation.Arguments.Count != 3 || !MatchArgumentList(invocation.Arguments[2], out arguments))\n\t\t\t{\n\t\t\t\targuments = new List<ILInstruction>();\n\t\t\t}\n\t\t\tvar convertedArguments = ConvertCallArguments(arguments, (IMethod)member);\n\t\t\tif (convertedArguments == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tILInstruction BuildProperty()\n\t\t\t{\n\t\t\t\tCallInstruction call;\n\t\t\t\tif (member.IsStatic)\n\t\t\t\t{\n\t\t\t\t\tcall = new Call((IMethod)member);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcall = new CallVirt((IMethod)member);\n\t\t\t\t}\n\t\t\t\tif (targetConverter != null)\n\t\t\t\t{\n\t\t\t\t\tcall.Arguments.Add(PrepareCallTarget(member.DeclaringType, targetConverter(), targetType));\n\t\t\t\t}\n\t\t\t\tcall.Arguments.AddRange(convertedArguments.Select(f => f()));\n\t\t\t\treturn call;\n\t\t\t}\n\t\t\treturn (BuildProperty, member.ReturnType);\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertTypeAs(CallInstruction invocation)\n\t\t{\n\t\t\tif (invocation.Arguments.Count != 2)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar converted = ConvertInstruction(invocation.Arguments[0]).Item1;\n\t\t\tif (!MatchGetTypeFromHandle(invocation.Arguments[1], out var type))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tif (converted == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tILInstruction BuildTypeAs()\n\t\t\t{\n\t\t\t\tILInstruction inst = new IsInst(converted(), type);\n\t\t\t\t// We must follow ECMA-335, III.4.6:\n\t\t\t\t// If typeTok is a nullable type, Nullable<T>, it is interpreted as \"boxed\" T.\n\t\t\t\tif (type.IsKnownType(KnownTypeCode.NullableOfT))\n\t\t\t\t\tinst = new UnboxAny(inst, type);\n\t\t\t\treturn inst;\n\t\t\t}\n\t\t\treturn (BuildTypeAs, type);\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertTypeIs(CallInstruction invocation)\n\t\t{\n\t\t\tif (invocation.Arguments.Count != 2)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar converted = ConvertInstruction(invocation.Arguments[0]).Item1;\n\t\t\tif (!MatchGetTypeFromHandle(invocation.Arguments[1], out var type))\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar resultType = context.TypeSystem.FindType(KnownTypeCode.Boolean);\n\t\t\tif (converted != null)\n\t\t\t\treturn (() => new Comp(ComparisonKind.Inequality, Sign.None, new IsInst(converted(), type), new LdNull()), resultType);\n\t\t\treturn (null, SpecialType.UnknownType);\n\t\t}\n\n\t\t(Func<ILInstruction>, IType) ConvertUnaryNumericOperator(CallInstruction invocation, BinaryNumericOperator op, bool? isChecked = null)\n\t\t{\n\t\t\tif (invocation.Arguments.Count < 1)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tvar (argument, argumentType) = ConvertInstruction(invocation.Arguments[0]);\n\t\t\tif (argument == null)\n\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\tswitch (invocation.Arguments.Count)\n\t\t\t{\n\t\t\t\tcase 1:\n\t\t\t\t\tILInstruction left;\n\t\t\t\t\tvar underlyingType = NullableType.GetUnderlyingType(argumentType);\n\n\t\t\t\t\tswitch (underlyingType.GetStackType())\n\t\t\t\t\t{\n\t\t\t\t\t\tcase StackType.I4:\n\t\t\t\t\t\t\tleft = new LdcI4(0);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase StackType.I8:\n\t\t\t\t\t\t\tleft = new LdcI8(0);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase StackType.I:\n\t\t\t\t\t\t\tleft = new Conv(new LdcI4(0), PrimitiveType.I, false, Sign.None);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase StackType.F4:\n\t\t\t\t\t\t\tleft = new LdcF4(0);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase StackType.F8:\n\t\t\t\t\t\t\tleft = new LdcF8(0);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase StackType.O when underlyingType.IsKnownType(KnownTypeCode.Decimal):\n\t\t\t\t\t\t\tleft = new LdcDecimal(0);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\t}\n\t\t\t\t\treturn (() => new BinaryNumericInstruction(op, left, argument(),\n\t\t\t\t\t\tunderlyingType.GetStackType(),\n\t\t\t\t\t\tunderlyingType.GetStackType(),\n\t\t\t\t\t\tisChecked == true,\n\t\t\t\t\t\targumentType.GetSign(),\n\t\t\t\t\t\tisLifted: NullableType.IsNullable(argumentType)), argumentType);\n\t\t\t\tcase 2:\n\t\t\t\t\tif (!MatchGetMethodFromHandle(invocation.Arguments[1], out var method))\n\t\t\t\t\t\treturn (null, SpecialType.UnknownType);\n\t\t\t\t\treturn (() => new Call((IMethod)method) {\n\t\t\t\t\t\tArguments = { argument() }\n\t\t\t\t\t}, method.ReturnType);\n\t\t\t}\n\t\t\treturn (null, SpecialType.UnknownType);\n\t\t}\n\n\t\tILInstruction ConvertValue(ILInstruction value, ILInstruction context)\n\t\t{\n\t\t\tswitch (value)\n\t\t\t{\n\t\t\t\tcase LdLoc ldloc:\n\t\t\t\t\tif (IsExpressionTreeParameter(ldloc.Variable))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!parameterMapping.TryGetValue(ldloc.Variable, out var v))\n\t\t\t\t\t\t\treturn ldloc.Clone();\n\t\t\t\t\t\tif (context is CallInstruction parentCall\n\t\t\t\t\t\t\t&& parentCall.Method.FullName == \"System.Linq.Expressions.Expression.Call\"\n\t\t\t\t\t\t\t&& v.StackType.IsIntegerType())\n\t\t\t\t\t\t\treturn new LdLoca(v).WithILRange(ldloc);\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\telse if (IsClosureReference(ldloc.Variable))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (ldloc.Variable.Kind == VariableKind.Local)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tldloc.Variable.Kind = VariableKind.DisplayClassLocal;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (ldloc.Variable.CaptureScope == null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tldloc.Variable.CaptureScope = BlockContainer.FindClosestContainer(context);\n\t\t\t\t\t\t\tvar f = ldloc.Variable.CaptureScope.Ancestors.OfType<ILFunction>().FirstOrDefault();\n\t\t\t\t\t\t\tif (f != null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tf.CapturedVariables.Add(ldloc.Variable);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn ldloc;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn ldloc;\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\treturn value.Clone();\n\t\t\t}\n\t\t}\n\n\t\tbool IsClosureReference(ILVariable variable)\n\t\t{\n\t\t\tif (!variable.IsSingleDefinition || !(variable.StoreInstructions.SingleOrDefault() is StLoc store))\n\t\t\t\treturn false;\n\t\t\tif (!(store.Value is NewObj newObj))\n\t\t\t\treturn false;\n\t\t\treturn TransformDisplayClassUsage.IsPotentialClosure(this.context, newObj);\n\t\t}\n\n\t\tbool IsExpressionTreeParameter(ILVariable variable)\n\t\t{\n\t\t\treturn variable.Type.FullName == \"System.Linq.Expressions.ParameterExpression\";\n\t\t}\n\n\t\tbool MatchConstantCall(ILInstruction inst, out ILInstruction value, out IType type)\n\t\t{\n\t\t\tvalue = null;\n\t\t\ttype = null;\n\t\t\tif (inst is CallInstruction call && call.Method.FullName == \"System.Linq.Expressions.Expression.Constant\")\n\t\t\t{\n\t\t\t\tvalue = call.Arguments[0];\n\t\t\t\tif (call.Arguments.Count == 2)\n\t\t\t\t\treturn MatchGetTypeFromHandle(call.Arguments[1], out type);\n\t\t\t\ttype = value switch {\n\t\t\t\t\tLdNull => SpecialType.NullType,\n\t\t\t\t\tLdStr => context.TypeSystem.FindType(KnownTypeCode.String),\n\t\t\t\t\tLdcF4 => context.TypeSystem.FindType(KnownTypeCode.Single),\n\t\t\t\t\tLdcF8 => context.TypeSystem.FindType(KnownTypeCode.Double),\n\t\t\t\t\tLdcI4 => context.TypeSystem.FindType(KnownTypeCode.Int32),\n\t\t\t\t\tLdcI8 => context.TypeSystem.FindType(KnownTypeCode.Int64),\n\t\t\t\t\t_ => value.InferType(context.TypeSystem),\n\t\t\t\t};\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tinternal static bool MatchGetTypeFromHandle(ILInstruction inst, out IType type)\n\t\t{\n\t\t\ttype = null;\n\t\t\treturn inst is CallInstruction getTypeCall\n\t\t\t\t&& getTypeCall.Method.FullName == \"System.Type.GetTypeFromHandle\"\n\t\t\t\t&& getTypeCall.Arguments.Count == 1\n\t\t\t\t&& getTypeCall.Arguments[0].MatchLdTypeToken(out type);\n\t\t}\n\n\t\tbool MatchGetMethodFromHandle(ILInstruction inst, out IMember member)\n\t\t{\n\t\t\tmember = null;\n\t\t\t//castclass System.Reflection.MethodInfo(call GetMethodFromHandle(ldmembertoken op_Addition))\n\t\t\tif (!inst.MatchCastClass(out var arg, out var type))\n\t\t\t\treturn false;\n\t\t\tif (type.FullName != \"System.Reflection.MethodInfo\")\n\t\t\t\treturn false;\n\t\t\tif (!(arg is CallInstruction call && call.Method.FullName == \"System.Reflection.MethodBase.GetMethodFromHandle\"))\n\t\t\t\treturn false;\n\t\t\treturn MatchFromHandleParameterList(call, out member);\n\t\t}\n\n\t\tbool MatchGetConstructorFromHandle(ILInstruction inst, out IMember member)\n\t\t{\n\t\t\tmember = null;\n\t\t\t//castclass System.Reflection.ConstructorInfo(call GetMethodFromHandle(ldmembertoken op_Addition))\n\t\t\tif (!inst.MatchCastClass(out var arg, out var type))\n\t\t\t\treturn false;\n\t\t\tif (type.FullName != \"System.Reflection.ConstructorInfo\")\n\t\t\t\treturn false;\n\t\t\tif (!(arg is CallInstruction call && call.Method.FullName == \"System.Reflection.MethodBase.GetMethodFromHandle\"))\n\t\t\t\treturn false;\n\t\t\treturn MatchFromHandleParameterList(call, out member);\n\t\t}\n\n\t\tbool MatchGetFieldFromHandle(ILInstruction inst, out IMember member)\n\t\t{\n\t\t\tmember = null;\n\t\t\tif (!(inst is CallInstruction call && call.Method.FullName == \"System.Reflection.FieldInfo.GetFieldFromHandle\"))\n\t\t\t\treturn false;\n\t\t\treturn MatchFromHandleParameterList(call, out member);\n\t\t}\n\n\t\tstatic bool MatchFromHandleParameterList(CallInstruction call, out IMember member)\n\t\t{\n\t\t\tmember = null;\n\t\t\tswitch (call.Arguments.Count)\n\t\t\t{\n\t\t\t\tcase 1:\n\t\t\t\t\tif (!call.Arguments[0].MatchLdMemberToken(out member))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tif (!call.Arguments[0].MatchLdMemberToken(out member))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!call.Arguments[1].MatchLdTypeToken(out _))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tbool MatchArgumentList(ILInstruction inst, out IList<ILInstruction> arguments)\n\t\t{\n\t\t\targuments = null;\n\t\t\tif (!(inst is Block block && block.Kind == BlockKind.ArrayInitializer))\n\t\t\t{\n\t\t\t\tif (IsEmptyParameterList(inst))\n\t\t\t\t{\n\t\t\t\t\targuments = new List<ILInstruction>();\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tint i = 0;\n\t\t\targuments = new List<ILInstruction>();\n\t\t\tforeach (var item in block.Instructions.OfType<StObj>())\n\t\t\t{\n\t\t\t\tif (!(item.Target is LdElema ldelem && ldelem.Indices.Single().MatchLdcI4(i)))\n\t\t\t\t\treturn false;\n\t\t\t\targuments.Add(item.Value);\n\t\t\t\ti++;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/TupleTransform.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL\n{\n\tclass TupleTransform\n\t{\n\t\t/// <summary>\n\t\t/// Matches an 'ldflda' instruction accessing a tuple element.\n\t\t/// \n\t\t/// E.g. matches:\n\t\t/// <c>ldflda Item1(ldflda Rest(target))</c>\n\t\t/// </summary>\n\t\tpublic static bool MatchTupleFieldAccess(LdFlda inst, out IType tupleType, out ILInstruction target, out int position)\n\t\t{\n\t\t\ttupleType = inst.Field.DeclaringType;\n\t\t\ttarget = inst.Target;\n\t\t\tif (!inst.Field.Name.StartsWith(\"Item\", StringComparison.Ordinal))\n\t\t\t{\n\t\t\t\tposition = 0;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!int.TryParse(inst.Field.Name.Substring(4), out position))\n\t\t\t\treturn false;\n\t\t\tif (!TupleType.IsTupleCompatible(tupleType, out _))\n\t\t\t\treturn false;\n\t\t\twhile (target is LdFlda ldflda && ldflda.Field.Name == \"Rest\" && TupleType.IsTupleCompatible(ldflda.Field.DeclaringType, out _))\n\t\t\t{\n\t\t\t\ttupleType = ldflda.Field.DeclaringType;\n\t\t\t\ttarget = ldflda.Target;\n\t\t\t\tposition += TupleType.RestPosition - 1;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matches 'newobj TupleType(...)'.\n\t\t/// Takes care of flattening long tuples.\n\t\t/// </summary>\n\t\tpublic static bool MatchTupleConstruction(NewObj newobj, out ILInstruction[] arguments)\n\t\t{\n\t\t\targuments = null;\n\t\t\tif (newobj == null)\n\t\t\t\treturn false;\n\t\t\tif (!TupleType.IsTupleCompatible(newobj.Method.DeclaringType, out int elementCount))\n\t\t\t\treturn false;\n\t\t\targuments = new ILInstruction[elementCount];\n\t\t\tint outIndex = 0;\n\t\t\twhile (elementCount >= TupleType.RestPosition)\n\t\t\t{\n\t\t\t\tif (newobj.Arguments.Count != TupleType.RestPosition)\n\t\t\t\t\treturn false;\n\t\t\t\tfor (int pos = 1; pos < TupleType.RestPosition; pos++)\n\t\t\t\t{\n\t\t\t\t\targuments[outIndex++] = newobj.Arguments[pos - 1];\n\t\t\t\t}\n\t\t\t\telementCount -= TupleType.RestPosition - 1;\n\t\t\t\tDebug.Assert(outIndex + elementCount == arguments.Length);\n\t\t\t\tnewobj = newobj.Arguments.Last() as NewObj;\n\t\t\t\tif (newobj == null)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!TupleType.IsTupleCompatible(newobj.Method.DeclaringType, out int restElementCount))\n\t\t\t\t\treturn false;\n\t\t\t\tif (restElementCount != elementCount)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tDebug.Assert(outIndex + elementCount == arguments.Length);\n\t\t\tif (newobj.Arguments.Count != elementCount)\n\t\t\t\treturn false;\n\t\t\tfor (int i = 0; i < elementCount; i++)\n\t\t\t{\n\t\t\t\targuments[outIndex++] = newobj.Arguments[i];\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/UserDefinedLogicTransform.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\tpublic class UserDefinedLogicTransform : IStatementTransform\n\t{\n\t\tvoid IStatementTransform.Run(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\tif (LegacyPattern(block, pos, context))\n\t\t\t\treturn;\n\t\t\tif (RoslynOptimized(block, pos, context))\n\t\t\t\treturn;\n\t\t}\n\n\t\tbool RoslynOptimized(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\t// Roslyn, optimized pattern in combination with return statement:\n\t\t\t//   if (logic.not(call op_False(ldloc lhsVar))) leave IL_0000 (call op_BitwiseAnd(ldloc lhsVar, rhsInst))\n\t\t\t//   leave IL_0000(ldloc lhsVar)\n\t\t\t// ->\n\t\t\t//   user.logic op_BitwiseAnd(ldloc lhsVar, rhsInst)\n\t\t\tif (!block.Instructions[pos].MatchIfInstructionPositiveCondition(out var condition, out var trueInst, out var falseInst))\n\t\t\t\treturn false;\n\t\t\tif (trueInst.OpCode == OpCode.Nop)\n\t\t\t{\n\t\t\t\ttrueInst = block.Instructions[pos + 1];\n\t\t\t}\n\t\t\telse if (falseInst.OpCode == OpCode.Nop)\n\t\t\t{\n\t\t\t\tfalseInst = block.Instructions[pos + 1];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (trueInst.MatchReturn(out var trueValue) && falseInst.MatchReturn(out var falseValue))\n\t\t\t{\n\t\t\t\tvar transformed = Transform(condition, trueValue, falseValue);\n\t\t\t\tif (transformed == null)\n\t\t\t\t{\n\t\t\t\t\ttransformed = TransformDynamic(condition, trueValue, falseValue);\n\t\t\t\t}\n\t\t\t\tif (transformed != null)\n\t\t\t\t{\n\t\t\t\t\tcontext.Step(\"User-defined short-circuiting logic operator (optimized return)\", condition);\n\t\t\t\t\t((Leave)block.Instructions[pos + 1]).Value = transformed;\n\t\t\t\t\tblock.Instructions.RemoveAt(pos);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tbool LegacyPattern(Block block, int pos, StatementTransformContext context)\n\t\t{\n\t\t\t// Legacy csc pattern:\n\t\t\t//   stloc s(lhsInst)\n\t\t\t//   if (logic.not(call op_False(ldloc s))) Block {\n\t\t\t//     stloc s(call op_BitwiseAnd(ldloc s, rhsInst))\n\t\t\t//   }\n\t\t\t// ->\n\t\t\t//   stloc s(user.logic op_BitwiseAnd(lhsInst, rhsInst))\n\t\t\tif (!block.Instructions[pos].MatchStLoc(out var s, out var lhsInst))\n\t\t\t\treturn false;\n\t\t\tif (!(s.Kind == VariableKind.StackSlot))\n\t\t\t\treturn false;\n\t\t\tif (!(block.Instructions[pos + 1] is IfInstruction ifInst))\n\t\t\t\treturn false;\n\t\t\tif (!ifInst.Condition.MatchLogicNot(out var condition))\n\t\t\t\treturn false;\n\t\t\tif (!(MatchCondition(condition, out var s2, out string conditionMethodName) && s2 == s))\n\t\t\t\treturn false;\n\t\t\tif (ifInst.FalseInst.OpCode != OpCode.Nop)\n\t\t\t\treturn false;\n\t\t\tvar trueInst = Block.Unwrap(ifInst.TrueInst);\n\t\t\tif (!trueInst.MatchStLoc(s, out var storeValue))\n\t\t\t\treturn false;\n\t\t\tif (storeValue is Call call)\n\t\t\t{\n\t\t\t\tif (!MatchBitwiseCall(call, s, conditionMethodName))\n\t\t\t\t\treturn false;\n\t\t\t\tif (s.IsUsedWithin(call.Arguments[1]))\n\t\t\t\t\treturn false;\n\t\t\t\tcontext.Step(\"User-defined short-circuiting logic operator (legacy pattern)\", condition);\n\t\t\t\t((StLoc)block.Instructions[pos]).Value = new UserDefinedLogicOperator(call.Method, lhsInst, call.Arguments[1])\n\t\t\t\t\t.WithILRange(call);\n\t\t\t\tblock.Instructions.RemoveAt(pos + 1);\n\t\t\t\tcontext.RequestRerun(); // the 'stloc s' may now be eligible for inlining\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tstatic bool MatchCondition(ILInstruction condition, out ILVariable v, out string name)\n\t\t{\n\t\t\tv = null;\n\t\t\tname = null;\n\t\t\tif (!(condition is Call call && call.Method.IsOperator && call.Arguments.Count == 1 && !call.IsLifted))\n\t\t\t\treturn false;\n\t\t\tname = call.Method.Name;\n\t\t\tif (!(name == \"op_True\" || name == \"op_False\"))\n\t\t\t\treturn false;\n\t\t\treturn call.Arguments[0].MatchLdLoc(out v);\n\t\t}\n\n\t\tstatic bool MatchBitwiseCall(Call call, ILVariable v, string conditionMethodName)\n\t\t{\n\t\t\tif (!(call != null && call.Method.IsOperator && call.Arguments.Count == 2 && !call.IsLifted))\n\t\t\t\treturn false;\n\t\t\tif (!call.Arguments[0].MatchLdLoc(v))\n\t\t\t\treturn false;\n\n\t\t\treturn conditionMethodName == \"op_False\" && call.Method.Name == \"op_BitwiseAnd\"\n\t\t\t\t|| conditionMethodName == \"op_True\" && call.Method.Name == \"op_BitwiseOr\";\n\t\t}\n\n\t\t/// <summary>\n\t\t///       if (call op_False(ldloc lhsVar)) ldloc lhsVar else call op_BitwiseAnd(ldloc lhsVar, rhsInst)\n\t\t///    -> user.logic op_BitwiseAnd(ldloc lhsVar, rhsInst)\n\t\t/// or\n\t\t///       if (call op_True(ldloc lhsVar)) ldloc lhsVar else call op_BitwiseOr(ldloc lhsVar, rhsInst)\n\t\t///    -> user.logic op_BitwiseOr(ldloc lhsVar, rhsInst)\n\t\t/// </summary>\n\t\tpublic static ILInstruction Transform(ILInstruction condition, ILInstruction trueInst, ILInstruction falseInst)\n\t\t{\n\t\t\tif (!MatchCondition(condition, out var lhsVar, out var conditionMethodName))\n\t\t\t\treturn null;\n\t\t\tif (!trueInst.MatchLdLoc(lhsVar))\n\t\t\t\treturn null;\n\t\t\tvar call = falseInst as Call;\n\t\t\tif (!MatchBitwiseCall(call, lhsVar, conditionMethodName))\n\t\t\t\treturn null;\n\n\t\t\tvar result = new UserDefinedLogicOperator(call.Method, call.Arguments[0], call.Arguments[1]);\n\t\t\tresult.AddILRange(condition);\n\t\t\tresult.AddILRange(trueInst);\n\t\t\tresult.AddILRange(call);\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic static ILInstruction TransformDynamic(ILInstruction condition, ILInstruction trueInst, ILInstruction falseInst)\n\t\t{\n\t\t\t// Check condition:\n\t\t\tSystem.Linq.Expressions.ExpressionType unaryOp;\n\t\t\tif (condition.MatchLdLoc(out var lhsVar))\n\t\t\t{\n\t\t\t\t// if (ldloc lhsVar) box bool(ldloc lhsVar) else dynamic.binary.operator.logic Or(ldloc lhsVar, rhsInst)\n\t\t\t\t//    -> dynamic.logic.operator OrElse(ldloc lhsVar, rhsInst)\n\t\t\t\tif (trueInst is Box box && box.Type.IsKnownType(KnownTypeCode.Boolean))\n\t\t\t\t{\n\t\t\t\t\tunaryOp = System.Linq.Expressions.ExpressionType.IsTrue;\n\t\t\t\t\ttrueInst = box.Argument;\n\t\t\t\t}\n\t\t\t\telse if (falseInst is Box box2 && box2.Type.IsKnownType(KnownTypeCode.Boolean))\n\t\t\t\t{\n\t\t\t\t\t// negate condition and swap true/false\n\t\t\t\t\tunaryOp = System.Linq.Expressions.ExpressionType.IsFalse;\n\t\t\t\t\tfalseInst = trueInst;\n\t\t\t\t\ttrueInst = box2.Argument;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (condition is DynamicUnaryOperatorInstruction unary)\n\t\t\t{\n\t\t\t\t// if (dynamic.unary.operator IsFalse(ldloc lhsVar)) ldloc lhsVar else dynamic.binary.operator.logic And(ldloc lhsVar, rhsInst)\n\t\t\t\t//    -> dynamic.logic.operator AndAlso(ldloc lhsVar, rhsInst)\n\t\t\t\tunaryOp = unary.Operation;\n\t\t\t\tif (!unary.Operand.MatchLdLoc(out lhsVar))\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t\telse if (MatchCondition(condition, out lhsVar, out string operatorMethodName))\n\t\t\t{\n\t\t\t\t// if (call op_False(ldloc s)) box S(ldloc s) else dynamic.binary.operator.logic And(ldloc s, rhsInst))\n\t\t\t\tif (operatorMethodName == \"op_True\")\n\t\t\t\t{\n\t\t\t\t\tunaryOp = System.Linq.Expressions.ExpressionType.IsTrue;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(operatorMethodName == \"op_False\");\n\t\t\t\t\tunaryOp = System.Linq.Expressions.ExpressionType.IsFalse;\n\t\t\t\t}\n\t\t\t\tvar callParamType = ((Call)condition).Method.Parameters.Single().Type.SkipModifiers();\n\t\t\t\tif (callParamType.IsReferenceType == false)\n\t\t\t\t{\n\t\t\t\t\t// If lhs is a value type, eliminate the boxing instruction.\n\t\t\t\t\tif (trueInst is Box box && NormalizeTypeVisitor.TypeErasure.EquivalentTypes(box.Type, callParamType))\n\t\t\t\t\t{\n\t\t\t\t\t\ttrueInst = box.Argument;\n\t\t\t\t\t}\n\t\t\t\t\telse if (trueInst.OpCode == OpCode.LdcI4)\n\t\t\t\t\t{\n\t\t\t\t\t\t// special case, handled below in 'check trueInst'\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Check trueInst:\n\t\t\tDynamicUnaryOperatorInstruction rhsUnary;\n\t\t\tif (trueInst.MatchLdLoc(lhsVar))\n\t\t\t{\n\t\t\t\t// OK, typical pattern where the expression evaluates to 'dynamic'\n\t\t\t\trhsUnary = null;\n\t\t\t}\n\t\t\telse if (trueInst.MatchLdcI4(1) && unaryOp == System.Linq.Expressions.ExpressionType.IsTrue)\n\t\t\t{\n\t\t\t\t// logic.or(IsTrue(lhsVar), IsTrue(lhsVar | rhsInst))\n\t\t\t\t// => IsTrue(lhsVar || rhsInst)\n\t\t\t\trhsUnary = falseInst as DynamicUnaryOperatorInstruction;\n\t\t\t\tif (rhsUnary != null)\n\t\t\t\t{\n\t\t\t\t\tif (rhsUnary.Operation != System.Linq.Expressions.ExpressionType.IsTrue)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tfalseInst = rhsUnary.Operand;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tSystem.Linq.Expressions.ExpressionType expectedBitop;\n\t\t\tSystem.Linq.Expressions.ExpressionType logicOp;\n\t\t\tif (unaryOp == System.Linq.Expressions.ExpressionType.IsFalse)\n\t\t\t{\n\t\t\t\texpectedBitop = System.Linq.Expressions.ExpressionType.And;\n\t\t\t\tlogicOp = System.Linq.Expressions.ExpressionType.AndAlso;\n\t\t\t}\n\t\t\telse if (unaryOp == System.Linq.Expressions.ExpressionType.IsTrue)\n\t\t\t{\n\t\t\t\texpectedBitop = System.Linq.Expressions.ExpressionType.Or;\n\t\t\t\tlogicOp = System.Linq.Expressions.ExpressionType.OrElse;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Check falseInst:\n\t\t\tif (!(falseInst is DynamicBinaryOperatorInstruction binary))\n\t\t\t\treturn null;\n\t\t\tif (binary.Operation != expectedBitop)\n\t\t\t\treturn null;\n\t\t\tif (!binary.Left.MatchLdLoc(lhsVar))\n\t\t\t\treturn null;\n\t\t\tvar logicInst = new DynamicLogicOperatorInstruction(binary.BinderFlags, logicOp, binary.CallingContext,\n\t\t\t\tbinary.LeftArgumentInfo, binary.Left, binary.RightArgumentInfo, binary.Right)\n\t\t\t\t.WithILRange(binary);\n\t\t\tif (rhsUnary != null)\n\t\t\t{\n\t\t\t\trhsUnary.Operand = logicInst;\n\t\t\t\treturn rhsUnary;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn logicInst;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/IL/Transforms/UsingTransform.cs",
    "content": "// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.IL.Transforms\n{\n\tpublic class UsingTransform : IBlockTransform\n\t{\n\t\tBlockTransformContext context;\n\n\t\tvoid IBlockTransform.Run(Block block, BlockTransformContext context)\n\t\t{\n\t\t\tif (!context.Settings.UsingStatement)\n\t\t\t\treturn;\n\t\t\tthis.context = context;\n\t\t\tfor (int i = context.IndexOfFirstAlreadyTransformedInstruction - 1; i >= 0; i--)\n\t\t\t{\n\t\t\t\tif (TransformUsing(block, i))\n\t\t\t\t{\n\t\t\t\t\tcontext.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (TransformUsingVB(block, i))\n\t\t\t\t{\n\t\t\t\t\tcontext.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (TransformAsyncUsing(block, i))\n\t\t\t\t{\n\t\t\t\t\tcontext.IndexOfFirstAlreadyTransformedInstruction = block.Instructions.Count;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// stloc obj(resourceExpression)\n\t\t/// .try BlockContainer {\n\t\t///\t\tBlock IL_0003(incoming: 1) {\n\t\t///\t\t\tcall WriteLine(ldstr \"using (null)\")\n\t\t///\t\t\tleave IL_0003(nop)\n\t\t///\t\t}\n\t\t///\t} finally BlockContainer {\n\t\t///\t\tBlock IL_0012(incoming: 1) {\n\t\t///\t\t\tif (comp(ldloc obj != ldnull)) Block IL_001a  {\n\t\t///\t\t\t\tcallvirt Dispose(ldnull)\n\t\t///\t\t\t}\n\t\t///\t\t\tleave IL_0012(nop)\n\t\t///\t\t}\n\t\t/// }\n\t\t/// leave IL_0000(nop)\n\t\t/// =>\n\t\t/// using (resourceExpression) {\n\t\t///\t\tBlockContainer {\n\t\t///\t\t\tBlock IL_0003(incoming: 1) {\n\t\t///\t\t\t\tcall WriteLine(ldstr \"using (null)\")\n\t\t///\t\t\t\tleave IL_0003(nop)\n\t\t///\t\t\t}\n\t\t///\t\t}\n\t\t/// }\n\t\t/// </summary>\n\t\tbool TransformUsing(Block block, int i)\n\t\t{\n\t\t\tif (i + 1 >= block.Instructions.Count)\n\t\t\t\treturn false;\n\t\t\tif (!(block.Instructions[i + 1] is TryFinally tryFinally) || !(block.Instructions[i] is StLoc storeInst))\n\t\t\t\treturn false;\n\t\t\tif (!(storeInst.Value.MatchLdNull() || CheckResourceType(storeInst.Variable.Type)))\n\t\t\t\treturn false;\n\t\t\tif (storeInst.Variable.Kind != VariableKind.Local)\n\t\t\t\treturn false;\n\t\t\tif (storeInst.Variable.LoadInstructions.Any(ld => !ld.IsDescendantOf(tryFinally)))\n\t\t\t\treturn false;\n\t\t\tif (!storeInst.Variable.AddressInstructions.All(ValidateAddressUse))\n\t\t\t\treturn false;\n\t\t\tif (storeInst.Variable.StoreInstructions.Count > 1)\n\t\t\t\treturn false;\n\t\t\tif (!(tryFinally.FinallyBlock is BlockContainer container))\n\t\t\t\treturn false;\n\t\t\tif (!MatchDisposeBlock(container, storeInst.Variable, storeInst.Value.MatchLdNull()))\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"UsingTransform\", tryFinally);\n\t\t\tstoreInst.Variable.Kind = VariableKind.UsingLocal;\n\t\t\tblock.Instructions.RemoveAt(i + 1);\n\t\t\tblock.Instructions[i] = new UsingInstruction(storeInst.Variable, storeInst.Value, tryFinally.TryBlock) {\n\t\t\t\tIsRefStruct = context.Settings.IntroduceRefModifiersOnStructs && storeInst.Variable.Type.Kind == TypeKind.Struct && storeInst.Variable.Type.IsByRefLike\n\t\t\t}.WithILRange(storeInst);\n\t\t\treturn true;\n\n\t\t\tbool ValidateAddressUse(LdLoca la)\n\t\t\t{\n\t\t\t\tif (!la.IsDescendantOf(tryFinally))\n\t\t\t\t\treturn false;\n\t\t\t\tif (la.IsDescendantOf(tryFinally.TryBlock))\n\t\t\t\t{\n\t\t\t\t\tif (!(ILInlining.IsUsedAsThisPointerInCall(la) || ILInlining.IsPassedToInParameter(la)))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// .try BlockContainer {\n\t\t///\t\tBlock IL_0003(incoming: 1) {\n\t\t///\t\t\tstloc obj(resourceExpression)\n\t\t///\t\t\tcall WriteLine(ldstr \"using (null)\")\n\t\t///\t\t\tleave IL_0003(nop)\n\t\t///\t\t}\n\t\t///\t} finally BlockContainer {\n\t\t///\t\tBlock IL_0012(incoming: 1) {\n\t\t///\t\t\tif (comp(ldloc obj != ldnull)) Block IL_001a  {\n\t\t///\t\t\t\tcallvirt Dispose(ldnull)\n\t\t///\t\t\t}\n\t\t///\t\t\tleave IL_0012(nop)\n\t\t///\t\t}\n\t\t/// }\n\t\t/// leave IL_0000(nop)\n\t\t/// =>\n\t\t/// using (resourceExpression) {\n\t\t///\t\tBlockContainer {\n\t\t///\t\t\tBlock IL_0003(incoming: 1) {\n\t\t///\t\t\t\tcall WriteLine(ldstr \"using (null)\")\n\t\t///\t\t\t\tleave IL_0003(nop)\n\t\t///\t\t\t}\n\t\t///\t\t}\n\t\t/// }\n\t\t/// </summary>\n\t\tbool TransformUsingVB(Block block, int i)\n\t\t{\n\t\t\tif (i >= block.Instructions.Count)\n\t\t\t\treturn false;\n\t\t\tif (!(block.Instructions[i] is TryFinally tryFinally))\n\t\t\t\treturn false;\n\t\t\tif (!(tryFinally.TryBlock is BlockContainer tryContainer && tryContainer.EntryPoint.Instructions.FirstOrDefault() is StLoc storeInst))\n\t\t\t\treturn false;\n\t\t\tif (!(storeInst.Value.MatchLdNull() || CheckResourceType(storeInst.Variable.Type)))\n\t\t\t\treturn false;\n\t\t\tif (storeInst.Variable.Kind != VariableKind.Local)\n\t\t\t\treturn false;\n\t\t\tif (storeInst.Variable.LoadInstructions.Any(ld => !ld.IsDescendantOf(tryFinally)))\n\t\t\t\treturn false;\n\t\t\tif (storeInst.Variable.AddressInstructions.Any(la => !la.IsDescendantOf(tryFinally) || (la.IsDescendantOf(tryFinally.TryBlock) && !ILInlining.IsUsedAsThisPointerInCall(la))))\n\t\t\t\treturn false;\n\t\t\tif (storeInst.Variable.StoreInstructions.Count > 1)\n\t\t\t\treturn false;\n\t\t\tif (!(tryFinally.FinallyBlock is BlockContainer container) || !MatchDisposeBlock(container, storeInst.Variable, storeInst.Value.MatchLdNull()))\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"UsingTransformVB\", tryFinally);\n\t\t\tstoreInst.Variable.Kind = VariableKind.UsingLocal;\n\t\t\ttryContainer.EntryPoint.Instructions.RemoveAt(0);\n\t\t\tblock.Instructions[i] = new UsingInstruction(storeInst.Variable, storeInst.Value, tryFinally.TryBlock);\n\t\t\treturn true;\n\t\t}\n\n\t\tbool CheckResourceType(IType type)\n\t\t{\n\t\t\t// non-generic IEnumerator does not implement IDisposable.\n\t\t\t// This is a workaround for non-generic foreach.\n\t\t\tif (type.IsKnownType(KnownTypeCode.IEnumerator) || type.GetAllBaseTypes().Any(b => b.IsKnownType(KnownTypeCode.IEnumerator)))\n\t\t\t\treturn true;\n\t\t\tif (NullableType.GetUnderlyingType(type).GetAllBaseTypes().Any(b => b.IsKnownType(KnownTypeCode.IDisposable)))\n\t\t\t\treturn true;\n\t\t\tif (context.Settings.IntroduceRefModifiersOnStructs && type.Kind == TypeKind.Struct && type.IsByRefLike)\n\t\t\t\treturn true;\n\t\t\t// General GetEnumerator-pattern?\n\t\t\tif (!type.GetMethods(m => m.Name == \"GetEnumerator\" && m.TypeParameters.Count == 0 && m.Parameters.Count == 0).Any(m => ImplementsForeachPattern(m.ReturnType)))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\tbool ImplementsForeachPattern(IType type)\n\t\t{\n\t\t\tif (!type.GetMethods(m => m.Name == \"MoveNext\" && m.TypeParameters.Count == 0 && m.Parameters.Count == 0).Any(m => m.ReturnType.IsKnownType(KnownTypeCode.Boolean)))\n\t\t\t\treturn false;\n\t\t\tif (!type.GetProperties(p => p.Name == \"Current\" && p.CanGet && !p.IsIndexer).Any())\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\n\t\t///\tfinally BlockContainer {\n\t\t///\t\tBlock IL_0012(incoming: 1) {\n\t\t///\t\t\tif (comp(ldloc obj != ldnull)) Block IL_001a  {\n\t\t///\t\t\t\tcallvirt Dispose(obj)\n\t\t///\t\t\t}\n\t\t///\t\t\tleave IL_0012(nop)\n\t\t///\t\t}\n\t\t/// }\n\t\tbool MatchDisposeBlock(BlockContainer container, ILVariable objVar, bool usingNull,\n\t\t\tin string disposeMethodFullName = \"System.IDisposable.Dispose\",\n\t\t\tKnownTypeCode disposeTypeCode = KnownTypeCode.IDisposable)\n\t\t{\n\t\t\tvar entryPoint = container.EntryPoint;\n\t\t\tif (entryPoint.IncomingEdgeCount != 1)\n\t\t\t\treturn false;\n\t\t\tint pos = 0;\n\t\t\tbool isReference = objVar.Type.IsReferenceType != false;\n\t\t\t// optional:\n\t\t\t// stloc temp(isinst TDisposable(ldloc obj))\n\t\t\tif (entryPoint.Instructions.ElementAtOrDefault(pos).MatchStLoc(out var tempVar, out var isinst))\n\t\t\t{\n\t\t\t\tif (!isinst.MatchIsInst(out var load, out var disposableType) || !load.MatchLdLoc(objVar)\n\t\t\t\t\t|| !disposableType.IsKnownType(disposeTypeCode))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (!tempVar.IsSingleDefinition)\n\t\t\t\t\treturn false;\n\t\t\t\tisReference = true;\n\t\t\t\tpos++;\n\t\t\t\tobjVar = tempVar;\n\t\t\t}\n\t\t\t// if (comp(ldloc obj != ldnull)) Block IL_001a  {\n\t\t\t//\tcallvirt Dispose(obj)\n\t\t\t// }\n\t\t\tvar checkInst = entryPoint.Instructions.ElementAtOrDefault(pos);\n\t\t\tif (checkInst == null)\n\t\t\t\treturn false;\n\t\t\tif (!MatchDisposeCheck(objVar, checkInst, isReference, usingNull,\n\t\t\t\tout int numObjVarLoadsInCheck, disposeMethodFullName, disposeTypeCode))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// make sure the (optional) temporary is used only in the dispose check\n\t\t\tif (pos > 0 && objVar.LoadCount != numObjVarLoadsInCheck)\n\t\t\t\treturn false;\n\t\t\tpos++;\n\t\t\t// make sure, the finally ends in a leave(nop) instruction.\n\t\t\tif (!entryPoint.Instructions.ElementAtOrDefault(pos).MatchLeave(container, out var returnValue))\n\t\t\t\treturn false;\n\t\t\tif (!returnValue.MatchNop())\n\t\t\t\treturn false;\n\t\t\t// leave is the last instruction\n\t\t\treturn (pos + 1) == entryPoint.Instructions.Count;\n\t\t}\n\n\t\tbool MatchDisposeCheck(ILVariable objVar, ILInstruction checkInst, bool isReference, bool usingNull,\n\t\t\tout int numObjVarLoadsInCheck, string disposeMethodFullName, KnownTypeCode disposeTypeCode)\n\t\t{\n\t\t\tnumObjVarLoadsInCheck = 2;\n\t\t\tILInstruction disposeInvocation;\n\t\t\tCallInstruction disposeCall;\n\t\t\tif (objVar.Type.IsKnownType(KnownTypeCode.NullableOfT))\n\t\t\t{\n\t\t\t\tif (checkInst.MatchIfInstruction(out var condition, out var disposeInst))\n\t\t\t\t{\n\t\t\t\t\tif (!NullableLiftingTransform.MatchHasValueCall(condition, objVar))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!(disposeInst is Block disposeBlock) || disposeBlock.Instructions.Count != 1)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tdisposeInvocation = disposeBlock.Instructions[0];\n\t\t\t\t}\n\t\t\t\telse if (checkInst.MatchNullableRewrap(out disposeInst))\n\t\t\t\t{\n\t\t\t\t\tdisposeInvocation = disposeInst;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (disposeTypeCode == KnownTypeCode.IAsyncDisposable)\n\t\t\t\t{\n\t\t\t\t\tif (!UnwrapAwait(ref disposeInvocation))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tdisposeCall = disposeInvocation as CallVirt;\n\t\t\t\tif (disposeCall == null)\n\t\t\t\t\treturn false;\n\t\t\t\tif (disposeCall.Method.FullName != disposeMethodFullName)\n\t\t\t\t\treturn false;\n\t\t\t\tif (disposeCall.Method.Parameters.Count > 0)\n\t\t\t\t\treturn false;\n\t\t\t\tif (disposeCall.Arguments.Count != 1)\n\t\t\t\t\treturn false;\n\t\t\t\tvar firstArg = disposeCall.Arguments.FirstOrDefault();\n\t\t\t\tif (!(firstArg.MatchUnboxAny(out var innerArg1, out var unboxType) && unboxType.IsKnownType(disposeTypeCode)))\n\t\t\t\t{\n\t\t\t\t\tif (!firstArg.MatchAddressOf(out var innerArg2, out _))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn NullableLiftingTransform.MatchGetValueOrDefault(innerArg2, objVar)\n\t\t\t\t\t\t|| (innerArg2 is NullableUnwrap unwrap\n\t\t\t\t\t\t\t&& unwrap.Argument.MatchLdLoc(objVar));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (!(innerArg1.MatchBox(out firstArg, out var boxType) && boxType.IsKnownType(KnownTypeCode.NullableOfT) &&\n\t\t\t\t\tNullableType.GetUnderlyingType(boxType).Equals(NullableType.GetUnderlyingType(objVar.Type))))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn firstArg.MatchLdLoc(objVar);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tILInstruction target;\n\t\t\t\tbool boxedValue = false;\n\t\t\t\tif (isReference && checkInst is NullableRewrap rewrap)\n\t\t\t\t{\n\t\t\t\t\t// the null check of reference types might have been transformed into \"objVar?.Dispose();\"\n\t\t\t\t\tif (!(rewrap.Argument is CallVirt cv))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\ttarget = cv.Arguments.FirstOrDefault();\n\t\t\t\t\tif (target is LdObjIfRef ldObjIfRef)\n\t\t\t\t\t\ttarget = ldObjIfRef.Target;\n\t\t\t\t\tif (!(target is NullableUnwrap unwrap))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tnumObjVarLoadsInCheck = 1;\n\t\t\t\t\tdisposeCall = cv;\n\t\t\t\t\ttarget = unwrap.Argument;\n\t\t\t\t}\n\t\t\t\telse if (isReference)\n\t\t\t\t{\n\t\t\t\t\t// reference types have a null check.\n\t\t\t\t\tif (!checkInst.MatchIfInstruction(out var condition, out var disposeInst))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!MatchNullCheckOrTypeCheck(condition, ref objVar, disposeTypeCode, out var isInlinedIsInst))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!(disposeInst is Block disposeBlock) || disposeBlock.Instructions.Count != 1)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tdisposeInvocation = disposeBlock.Instructions[0];\n\t\t\t\t\tif (disposeTypeCode == KnownTypeCode.IAsyncDisposable)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!UnwrapAwait(ref disposeInvocation))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif (!(disposeInvocation is CallVirt cv))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\ttarget = cv.Arguments.FirstOrDefault();\n\t\t\t\t\tif (target == null)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (target is LdObjIfRef ldObjIfRef)\n\t\t\t\t\t\ttarget = ldObjIfRef.Target;\n\t\t\t\t\tif (target.MatchBox(out var newTarget, out var type) && type.Equals(objVar.Type))\n\t\t\t\t\t\ttarget = newTarget;\n\t\t\t\t\telse if (isInlinedIsInst && target.MatchIsInst(out newTarget, out type) && type.IsKnownType(disposeTypeCode))\n\t\t\t\t\t\ttarget = newTarget;\n\t\t\t\t\tdisposeCall = cv;\n\t\t\t\t}\n\t\t\t\telse if (objVar.Type.Kind == TypeKind.Struct && objVar.Type.IsByRefLike)\n\t\t\t\t{\n\t\t\t\t\tif (!(checkInst is Call call && call.Method.DeclaringType == objVar.Type))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\ttarget = call.Arguments.FirstOrDefault();\n\t\t\t\t\tif (target == null)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (call.Method.Name != \"Dispose\")\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tdisposeMethodFullName = call.Method.FullName;\n\t\t\t\t\tdisposeCall = call;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (disposeTypeCode == KnownTypeCode.IAsyncDisposable)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!UnwrapAwait(ref checkInst))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif (!(checkInst is CallInstruction cv))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\ttarget = cv.Arguments.FirstOrDefault();\n\t\t\t\t\tif (target == null)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (target.MatchBox(out var newTarget, out var type) && type.Equals(objVar.Type))\n\t\t\t\t\t{\n\t\t\t\t\t\tboxedValue = type.IsReferenceType != true;\n\t\t\t\t\t\ttarget = newTarget;\n\t\t\t\t\t}\n\t\t\t\t\tdisposeCall = cv;\n\t\t\t\t}\n\t\t\t\tif (disposeCall.Method.IsStatic)\n\t\t\t\t\treturn false;\n\t\t\t\tif (disposeTypeCode == KnownTypeCode.IAsyncDisposable)\n\t\t\t\t{\n\t\t\t\t\tif (disposeCall.Method.Name != \"DisposeAsync\")\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (disposeCall.Method.FullName != disposeMethodFullName)\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (disposeCall.Method.Parameters.Count > 0)\n\t\t\t\t\treturn false;\n\t\t\t\tif (disposeCall.Arguments.Count != 1)\n\t\t\t\t\treturn false;\n\t\t\t\treturn target.MatchLdLocRef(objVar)\n\t\t\t\t\t|| (boxedValue && target.MatchLdLoc(objVar))\n\t\t\t\t\t|| (usingNull && disposeCall.Arguments[0].MatchLdNull())\n\t\t\t\t\t|| (isReference && checkInst is NullableRewrap\n\t\t\t\t\t\t&& target.MatchIsInst(out var arg, out var type2)\n\t\t\t\t\t\t&& arg.MatchLdLoc(objVar) && type2.IsKnownType(disposeTypeCode));\n\t\t\t}\n\t\t}\n\n\t\tbool MatchNullCheckOrTypeCheck(ILInstruction condition, ref ILVariable objVar, KnownTypeCode disposeType, out bool isInlinedIsInst)\n\t\t{\n\t\t\tisInlinedIsInst = false;\n\t\t\tif (condition.MatchCompNotEquals(out var left, out var right))\n\t\t\t{\n\t\t\t\tif (left.MatchStLoc(out var inlineAssignVar, out var inlineAssignVal))\n\t\t\t\t{\n\t\t\t\t\tif (!inlineAssignVal.MatchIsInst(out var arg, out var type) || !type.IsKnownType(disposeType))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!inlineAssignVar.IsSingleDefinition || inlineAssignVar.LoadCount != 1)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!inlineAssignVar.Type.IsKnownType(disposeType))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tisInlinedIsInst = true;\n\t\t\t\t\tleft = arg;\n\t\t\t\t\tif (!left.MatchLdLoc(objVar) || !right.MatchLdNull())\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tobjVar = inlineAssignVar;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse if (left.MatchIsInst(out var arg, out var type) && type.IsKnownType(disposeType))\n\t\t\t\t{\n\t\t\t\t\tisInlinedIsInst = true;\n\t\t\t\t\tleft = arg;\n\t\t\t\t}\n\t\t\t\tif (!left.MatchLdLoc(objVar) || !right.MatchLdNull())\n\t\t\t\t\treturn false;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (condition is MatchInstruction {\n\t\t\t\tCheckNotNull: true,\n\t\t\t\tCheckType: true,\n\t\t\t\tTestedOperand: LdLoc { Variable: var v },\n\t\t\t\tVariable: var newObjVar\n\t\t\t})\n\t\t\t{\n\t\t\t\tif (v != objVar)\n\t\t\t\t\treturn false;\n\t\t\t\tif (!newObjVar.Type.IsKnownType(disposeType))\n\t\t\t\t\treturn false;\n\t\t\t\tobjVar = newObjVar;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// stloc test(resourceExpression)\n\t\t/// .try BlockContainer {\n\t\t/// \tBlock IL_002b (incoming: 1) {\n\t\t/// \t\tcall Use(ldloc test)\n\t\t/// \t\tleave IL_002b (nop)\n\t\t/// \t}\n\t\t/// \n\t\t/// } finally BlockContainer {\n\t\t/// \tBlock IL_0045 (incoming: 1) {\n\t\t/// \t\tif (comp.o(ldloc test == ldnull)) leave IL_0045 (nop)\n\t\t/// \t\tbr IL_00ae\n\t\t/// \t}\n\t\t/// \n\t\t/// \tBlock IL_00ae (incoming: 1) {\n\t\t/// \t\tawait(addressof System.Threading.Tasks.ValueTask(callvirt DisposeAsync(ldloc test)))\n\t\t/// \t\tleave IL_0045 (nop)\n\t\t/// \t}\n\t\t/// \n\t\t/// }\n\t\t/// </summary>\n\t\tprivate bool TransformAsyncUsing(Block block, int i)\n\t\t{\n\t\t\tif (!context.Settings.AsyncUsingAndForEachStatement)\n\t\t\t\treturn false;\n\t\t\tif (i < 1 || i >= block.Instructions.Count)\n\t\t\t\treturn false;\n\t\t\tif (!(block.Instructions[i] is TryFinally tryFinally) || !(block.Instructions[i - 1] is StLoc storeInst))\n\t\t\t\treturn false;\n\t\t\tif (!CheckAsyncResourceType(storeInst.Variable.Type, out string disposeMethodFullName))\n\t\t\t\treturn false;\n\t\t\tif (storeInst.Variable.Kind != VariableKind.Local)\n\t\t\t\treturn false;\n\t\t\tif (storeInst.Variable.LoadInstructions.Any(ld => !ld.IsDescendantOf(tryFinally)))\n\t\t\t\treturn false;\n\t\t\tif (storeInst.Variable.AddressInstructions.Any(la => !la.IsDescendantOf(tryFinally) || (la.IsDescendantOf(tryFinally.TryBlock) && !ILInlining.IsUsedAsThisPointerInCall(la))))\n\t\t\t\treturn false;\n\t\t\tif (storeInst.Variable.StoreInstructions.Count > 1)\n\t\t\t\treturn false;\n\t\t\tif (!(tryFinally.FinallyBlock is BlockContainer container) || !MatchDisposeBlock(container, storeInst.Variable, usingNull: false, disposeMethodFullName, KnownTypeCode.IAsyncDisposable))\n\t\t\t\treturn false;\n\t\t\tcontext.Step(\"AsyncUsingTransform\", tryFinally);\n\t\t\tstoreInst.Variable.Kind = VariableKind.UsingLocal;\n\t\t\tblock.Instructions.RemoveAt(i);\n\t\t\tblock.Instructions[i - 1] = new UsingInstruction(storeInst.Variable, storeInst.Value, tryFinally.TryBlock) { IsAsync = true }\n\t\t\t\t.WithILRange(storeInst);\n\t\t\treturn true;\n\t\t}\n\n\t\tbool CheckAsyncResourceType(IType type, out string disposeMethodFullName)\n\t\t{\n\t\t\tdisposeMethodFullName = null;\n\t\t\tIType t = NullableType.GetUnderlyingType(type);\n\t\t\tif (t.GetAllBaseTypes().Any(b => b.IsKnownType(KnownTypeCode.IAsyncDisposable)))\n\t\t\t{\n\t\t\t\tdisposeMethodFullName = \"System.IAsyncDisposable.DisposeAsync\";\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tIMethod disposeMethod = t\n\t\t\t\t.GetMethods(m => m.Parameters.Count == 0 && m.TypeParameters.Count == 0 && m.Name == \"DisposeAsync\")\n\t\t\t\t.SingleOrDefault();\n\t\t\tif (disposeMethod != null)\n\t\t\t{\n\t\t\t\tdisposeMethodFullName = disposeMethod.FullName;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tbool UnwrapAwait(ref ILInstruction awaitInstruction)\n\t\t{\n\t\t\tif (awaitInstruction == null)\n\t\t\t\treturn false;\n\t\t\tif (!awaitInstruction.MatchAwait(out var arg))\n\t\t\t\treturn false;\n\t\t\tif (arg.MatchAddressOf(out var awaitInstructionInAddressOf, out var type))\n\t\t\t{\n\t\t\t\tawaitInstruction = awaitInstructionInAddressOf;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tawaitInstruction = arg;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Instrumentation/DecompilerEventSource.cs",
    "content": "// Copyright (c) 2021 Christoph Wille\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics.Tracing;\n\nnamespace ICSharpCode.Decompiler.Instrumentation\n{\n\t[EventSource(Name = \"ICSharpCode.Decompiler\")]\n\tpublic sealed class DecompilerEventSource : EventSource\n\t{\n\t\t[Event(1, Level = EventLevel.Informational)]\n\t\tpublic void DoDecompileEvent(string eventName, long elapsedMilliseconds)\n\t\t{\n\t\t\tWriteEvent(1, eventName, elapsedMilliseconds);\n\t\t}\n\n\t\t[Event(2, Level = EventLevel.Informational)]\n\t\tpublic void DoDecompileProperty(string propertyName, long elapsedMilliseconds)\n\t\t{\n\t\t\tWriteEvent(2, propertyName, elapsedMilliseconds);\n\t\t}\n\n\t\t[Event(3, Level = EventLevel.Informational)]\n\t\tpublic void DoDecompileField(string fieldName, long elapsedMilliseconds)\n\t\t{\n\t\t\tWriteEvent(3, fieldName, elapsedMilliseconds);\n\t\t}\n\n\t\t[Event(4, Level = EventLevel.Informational)]\n\t\tpublic void DoDecompileTypeDefinition(string typeDefName, long elapsedMilliseconds)\n\t\t{\n\t\t\tWriteEvent(4, typeDefName, elapsedMilliseconds);\n\t\t}\n\n\t\t[Event(5, Level = EventLevel.Informational)]\n\t\tpublic void DoDecompileMethod(string methodName, long elapsedMilliseconds)\n\t\t{\n\t\t\tWriteEvent(5, methodName, elapsedMilliseconds);\n\t\t}\n\n\t\tpublic static DecompilerEventSource Log = new DecompilerEventSource();\n\t}\n\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/AssemblyReferences.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Immutable;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Security.Cryptography;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\tpublic sealed class ResolutionException : Exception\n\t{\n\t\tpublic IAssemblyReference? Reference { get; }\n\n\t\tpublic string? ModuleName { get; }\n\n\t\tpublic string? MainModuleFullPath { get; }\n\n\t\tpublic string? ResolvedFullPath { get; }\n\n\t\tpublic ResolutionException(IAssemblyReference reference, string? resolvedPath, Exception? innerException)\n\t\t\t: base($\"Failed to resolve assembly: '{reference}'{Environment.NewLine}\" +\n\t\t\t\t  $\"Resolve result: {resolvedPath ?? \"<not found>\"}\", innerException)\n\t\t{\n\t\t\tthis.Reference = reference ?? throw new ArgumentNullException(nameof(reference));\n\t\t\tthis.ResolvedFullPath = resolvedPath;\n\t\t}\n\n\t\tpublic ResolutionException(string mainModule, string moduleName, string? resolvedPath, Exception? innerException)\n\t\t\t: base($\"Failed to resolve module: '{moduleName} of {mainModule}'{Environment.NewLine}\" +\n\t\t\t\t  $\"Resolve result: {resolvedPath ?? \"<not found>\"}\", innerException)\n\t\t{\n\t\t\tthis.MainModuleFullPath = mainModule ?? throw new ArgumentNullException(nameof(mainModule));\n\t\t\tthis.ModuleName = moduleName ?? throw new ArgumentNullException(nameof(moduleName));\n\t\t\tthis.ResolvedFullPath = resolvedPath;\n\t\t}\n\t}\n\n\tpublic interface IAssemblyResolver\n\t{\n#if !VSADDIN\n\t\tMetadataFile? Resolve(IAssemblyReference reference);\n\t\tMetadataFile? ResolveModule(MetadataFile mainModule, string moduleName);\n\t\tTask<MetadataFile?> ResolveAsync(IAssemblyReference reference);\n\t\tTask<MetadataFile?> ResolveModuleAsync(MetadataFile mainModule, string moduleName);\n#endif\n\t}\n\n\tpublic class AssemblyReferenceClassifier\n\t{\n\t\t/// <summary>\n\t\t/// For GAC assembly references, the WholeProjectDecompiler will omit the HintPath in the\n\t\t/// generated .csproj file.\n\t\t/// </summary>\n\t\tpublic virtual bool IsGacAssembly(IAssemblyReference reference)\n\t\t{\n\t\t\treturn UniversalAssemblyResolver.GetAssemblyInGac(reference) != null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// For .NET Core framework references, the WholeProjectDecompiler will omit the\n\t\t/// assembly reference if the runtimePack is already included as an SDK.\n\t\t/// </summary>\n\t\tpublic virtual bool IsSharedAssembly(IAssemblyReference reference, [NotNullWhen(true)] out string? runtimePack)\n\t\t{\n\t\t\truntimePack = null;\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic interface IAssemblyReference\n\t{\n\t\tstring Name { get; }\n\t\tstring FullName { get; }\n\t\tVersion? Version { get; }\n\t\tstring? Culture { get; }\n\t\tbyte[]? PublicKeyToken { get; }\n\n\t\tbool IsWindowsRuntime { get; }\n\t\tbool IsRetargetable { get; }\n\t}\n\n\tpublic class AssemblyNameReference : IAssemblyReference\n\t{\n\t\tstring? fullName;\n\n\t\tpublic string Name { get; private set; } = string.Empty;\n\n\t\tpublic string FullName {\n\t\t\tget {\n\t\t\t\tif (fullName != null)\n\t\t\t\t\treturn fullName;\n\n\t\t\t\tconst string sep = \", \";\n\n\t\t\t\tvar builder = new StringBuilder();\n\t\t\t\tbuilder.Append(Name);\n\t\t\t\tbuilder.Append(sep);\n\t\t\t\tbuilder.Append(\"Version=\");\n\t\t\t\tbuilder.Append((Version ?? UniversalAssemblyResolver.ZeroVersion).ToString(fieldCount: 4));\n\t\t\t\tbuilder.Append(sep);\n\t\t\t\tbuilder.Append(\"Culture=\");\n\t\t\t\tbuilder.Append(string.IsNullOrEmpty(Culture) ? \"neutral\" : Culture);\n\t\t\t\tbuilder.Append(sep);\n\t\t\t\tbuilder.Append(\"PublicKeyToken=\");\n\n\t\t\t\tvar pk_token = PublicKeyToken;\n\t\t\t\tif (pk_token != null && pk_token.Length > 0)\n\t\t\t\t{\n\t\t\t\t\tfor (int i = 0; i < pk_token.Length; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tbuilder.Append(pk_token[i].ToString(\"x2\"));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tbuilder.Append(\"null\");\n\n\t\t\t\tif (IsRetargetable)\n\t\t\t\t{\n\t\t\t\t\tbuilder.Append(sep);\n\t\t\t\t\tbuilder.Append(\"Retargetable=Yes\");\n\t\t\t\t}\n\n\t\t\t\treturn fullName = builder.ToString();\n\t\t\t}\n\t\t}\n\n\t\tpublic Version? Version { get; private set; }\n\n\t\tpublic string? Culture { get; private set; }\n\n\t\tpublic byte[]? PublicKeyToken { get; private set; }\n\n\t\tpublic bool IsWindowsRuntime { get; private set; }\n\n\t\tpublic bool IsRetargetable { get; private set; }\n\n\t\tpublic static AssemblyNameReference Parse(string fullName)\n\t\t{\n\t\t\tif (fullName == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(fullName));\n\t\t\tif (fullName.Length == 0)\n\t\t\t\tthrow new ArgumentException(\"Name can not be empty\");\n\n\t\t\tvar name = new AssemblyNameReference();\n\t\t\tvar tokens = fullName.Split(',');\n\t\t\tfor (int i = 0; i < tokens.Length; i++)\n\t\t\t{\n\t\t\t\tvar token = tokens[i].Trim();\n\n\t\t\t\tif (i == 0)\n\t\t\t\t{\n\t\t\t\t\tname.Name = token;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tvar parts = token.Split('=');\n\t\t\t\tif (parts.Length != 2)\n\t\t\t\t\tthrow new ArgumentException(\"Malformed name\");\n\n\t\t\t\tswitch (parts[0].ToLowerInvariant())\n\t\t\t\t{\n\t\t\t\t\tcase \"version\":\n\t\t\t\t\t\tname.Version = new Version(parts[1]);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"culture\":\n\t\t\t\t\t\tname.Culture = parts[1] == \"neutral\" ? \"\" : parts[1];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"publickeytoken\":\n\t\t\t\t\t\tvar pk_token = parts[1];\n\t\t\t\t\t\tif (pk_token == \"null\")\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tname.PublicKeyToken = new byte[pk_token.Length / 2];\n\t\t\t\t\t\tfor (int j = 0; j < name.PublicKeyToken.Length; j++)\n\t\t\t\t\t\t\tname.PublicKeyToken[j] = Byte.Parse(pk_token.Substring(j * 2, 2), System.Globalization.NumberStyles.HexNumber);\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn name;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn FullName;\n\t\t}\n\t}\n\n#if !VSADDIN\n\tpublic class AssemblyReference : IAssemblyReference\n\t{\n\t\treadonly System.Reflection.Metadata.AssemblyReference entry;\n\n\t\tpublic MetadataReader Metadata { get; }\n\t\tpublic AssemblyReferenceHandle Handle { get; }\n\n\t\tpublic bool IsWindowsRuntime => (entry.Flags & AssemblyFlags.WindowsRuntime) != 0;\n\t\tpublic bool IsRetargetable => (entry.Flags & AssemblyFlags.Retargetable) != 0;\n\n\t\tstring? name;\n\t\tstring? fullName;\n\n\t\tpublic string Name {\n\t\t\tget {\n\t\t\t\tif (name == null)\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tname = Metadata.GetString(entry.Name);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t{\n\t\t\t\t\t\tname = $\"AR:{Handle}\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn name;\n\t\t\t}\n\t\t}\n\n\t\tpublic string FullName {\n\t\t\tget {\n\t\t\t\tif (fullName == null)\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tfullName = entry.GetFullAssemblyName(Metadata);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t{\n\t\t\t\t\t\tfullName = $\"fullname(AR:{Handle})\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn fullName;\n\t\t\t}\n\t\t}\n\n\t\tpublic Version? Version => entry.Version;\n\t\tpublic string Culture => Metadata.GetString(entry.Culture);\n\t\tbyte[]? IAssemblyReference.PublicKeyToken => GetPublicKeyToken();\n\t\tbyte[]? publicKeyToken;\n\n\t\tpublic byte[]? GetPublicKeyToken()\n\t\t{\n\t\t\tif (entry.PublicKeyOrToken.IsNil)\n\t\t\t\treturn null;\n\n\t\t\tif (publicKeyToken == null)\n\t\t\t{\n\t\t\t\tvar bytes = Metadata.GetBlobBytes(entry.PublicKeyOrToken);\n\t\t\t\tif ((entry.Flags & AssemblyFlags.PublicKey) != 0)\n\t\t\t\t{\n\t\t\t\t\tusing (var hasher = SHA1.Create())\n\t\t\t\t\t{\n\t\t\t\t\t\tbytes = hasher.ComputeHash(bytes).Skip(12).ToArray();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tpublicKeyToken = bytes;\n\t\t\t}\n\n\t\t\treturn publicKeyToken;\n\t\t}\n\n\t\tImmutableArray<TypeReferenceMetadata> typeReferences;\n\t\tpublic ImmutableArray<TypeReferenceMetadata> TypeReferences {\n\t\t\tget {\n\t\t\t\tvar value = typeReferences;\n\t\t\t\tif (value.IsDefault)\n\t\t\t\t{\n\t\t\t\t\tvalue = Metadata.TypeReferences\n\t\t\t\t\t\t.Select(r => new TypeReferenceMetadata(Metadata, r))\n\t\t\t\t\t\t.Where(r => r.ResolutionScope == Handle)\n\t\t\t\t\t\t.OrderBy(r => r.Namespace)\n\t\t\t\t\t\t.ThenBy(r => r.Name)\n\t\t\t\t\t\t.ToImmutableArray();\n\t\t\t\t\ttypeReferences = value;\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\n\t\tImmutableArray<ExportedTypeMetadata> exportedTypes;\n\t\tpublic ImmutableArray<ExportedTypeMetadata> ExportedTypes {\n\t\t\tget {\n\t\t\t\tvar value = exportedTypes;\n\t\t\t\tif (value.IsDefault)\n\t\t\t\t{\n\t\t\t\t\tvalue = Metadata.ExportedTypes\n\t\t\t\t\t\t.Select(r => new ExportedTypeMetadata(Metadata, r))\n\t\t\t\t\t\t.Where(r => r.Implementation == Handle)\n\t\t\t\t\t\t.OrderBy(r => r.Namespace)\n\t\t\t\t\t\t.ThenBy(r => r.Name)\n\t\t\t\t\t\t.ToImmutableArray();\n\t\t\t\t\texportedTypes = value;\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\n\t\tpublic AssemblyReference(MetadataReader metadata, AssemblyReferenceHandle handle)\n\t\t{\n\t\t\tif (metadata == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(metadata));\n\t\t\tif (handle.IsNil)\n\t\t\t\tthrow new ArgumentNullException(nameof(handle));\n\t\t\tMetadata = metadata;\n\t\t\tHandle = handle;\n\t\t\tentry = metadata.GetAssemblyReference(handle);\n\t\t}\n\n\t\tpublic AssemblyReference(MetadataFile module, AssemblyReferenceHandle handle)\n\t\t{\n\t\t\tif (module == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(module));\n\t\t\tif (handle.IsNil)\n\t\t\t\tthrow new ArgumentNullException(nameof(handle));\n\t\t\tMetadata = module.Metadata;\n\t\t\tHandle = handle;\n\t\t\tentry = Metadata.GetAssemblyReference(handle);\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn FullName;\n\t\t}\n\t}\n#endif\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/CodeMappingInfo.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\t/// <summary>\n\t/// Describes which parts of the (compiler-generated) code belong to which user code.\n\t/// A part could be:\n\t/// - the body (method) of a lambda.\n\t/// - the MoveNext method of async/yield state machines.\n\t/// </summary>\n\tpublic class CodeMappingInfo\n\t{\n\t\t/// <summary>\n\t\t/// The module containing the code.\n\t\t/// </summary>\n\t\tpublic MetadataFile Module { get; }\n\n\t\t/// <summary>\n\t\t/// The (parent) TypeDef containing the code.\n\t\t/// </summary>\n\t\tpublic TypeDefinitionHandle TypeDefinition { get; }\n\n\t\treadonly Dictionary<MethodDefinitionHandle, List<MethodDefinitionHandle>> parts;\n\t\treadonly Dictionary<MethodDefinitionHandle, MethodDefinitionHandle> parents;\n\n\t\t/// <summary>\n\t\t/// Creates a <see cref=\"CodeMappingInfo\"/> instance using the given <paramref name=\"module\"/> and <paramref name=\"type\"/>.\n\t\t/// </summary>\n\t\tpublic CodeMappingInfo(MetadataFile module, TypeDefinitionHandle type)\n\t\t{\n\t\t\tthis.Module = module;\n\t\t\tthis.TypeDefinition = type;\n\t\t\tthis.parts = new Dictionary<MethodDefinitionHandle, List<MethodDefinitionHandle>>();\n\t\t\tthis.parents = new Dictionary<MethodDefinitionHandle, MethodDefinitionHandle>();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns all parts of a method.\n\t\t/// A method has at least one part, that is, the method itself.\n\t\t/// If no parts are found, only the method itself is returned.\n\t\t/// </summary>\n\t\tpublic IEnumerable<MethodDefinitionHandle> GetMethodParts(MethodDefinitionHandle method)\n\t\t{\n\t\t\tif (parts.TryGetValue(method, out var p))\n\t\t\t\treturn p;\n\t\t\treturn new[] { method };\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the parent of a part.\n\t\t/// The parent is usually the \"calling method\" of lambdas, async and yield state machines.\n\t\t/// The \"calling method\" has itself as parent.\n\t\t/// If no parent is found, the method itself is returned.\n\t\t/// </summary>\n\t\tpublic MethodDefinitionHandle GetParentMethod(MethodDefinitionHandle method)\n\t\t{\n\t\t\tif (parents.TryGetValue(method, out var p))\n\t\t\t\treturn p;\n\t\t\treturn method;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Adds a bidirectional mapping between <paramref name=\"parent\"/> and <paramref name=\"part\"/>.\n\t\t/// </summary>\n\t\tpublic void AddMapping(MethodDefinitionHandle parent, MethodDefinitionHandle part)\n\t\t{\n\t\t\t//Debug.Print(\"Parent: \" + MetadataTokens.GetRowNumber(parent) + \" Part: \" + MetadataTokens.GetRowNumber(part));\n\t\t\tif (parents.ContainsKey(part))\n\t\t\t\treturn;\n\t\t\tparents.Add(part, parent);\n\t\t\tif (!parts.TryGetValue(parent, out var list))\n\t\t\t{\n\t\t\t\tlist = new List<MethodDefinitionHandle>();\n\t\t\t\tparts.Add(parent, list);\n\t\t\t}\n\t\t\tlist.Add(part);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/CustomAttributeDecoder.cs",
    "content": "// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Immutable;\nusing System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\t/// <summary>\n\t/// Decodes custom attribute blobs.\n\t/// </summary>\n\tinternal readonly struct CustomAttributeDecoder<TType>\n\t{\n\t\t// This is a stripped-down copy of SRM's internal CustomAttributeDecoder.\n\t\t// We need it to decode security declarations.\n\n\t\tprivate readonly ICustomAttributeTypeProvider<TType> _provider;\n\t\tprivate readonly MetadataReader _reader;\n\t\tprivate readonly bool _provideBoxingTypeInfo;\n\n\t\tpublic CustomAttributeDecoder(ICustomAttributeTypeProvider<TType> provider, MetadataReader reader, bool provideBoxingTypeInfo = false)\n\t\t{\n\t\t\t_reader = reader;\n\t\t\t_provider = provider;\n\t\t\t_provideBoxingTypeInfo = provideBoxingTypeInfo;\n\t\t}\n\n\t\tpublic ImmutableArray<CustomAttributeNamedArgument<TType>> DecodeNamedArguments(ref BlobReader valueReader, int count)\n\t\t{\n\t\t\tvar arguments = ImmutableArray.CreateBuilder<CustomAttributeNamedArgument<TType>>(count);\n\t\t\tfor (int i = 0; i < count; i++)\n\t\t\t{\n\t\t\t\tCustomAttributeNamedArgumentKind kind = (CustomAttributeNamedArgumentKind)valueReader.ReadSerializationTypeCode();\n\t\t\t\tif (kind != CustomAttributeNamedArgumentKind.Field && kind != CustomAttributeNamedArgumentKind.Property)\n\t\t\t\t{\n\t\t\t\t\tthrow new BadImageFormatException();\n\t\t\t\t}\n\n\t\t\t\tArgumentTypeInfo info = DecodeNamedArgumentType(ref valueReader);\n\t\t\t\tstring name = valueReader.ReadSerializedString();\n\t\t\t\tCustomAttributeTypedArgument<TType> argument = DecodeArgument(ref valueReader, info);\n\t\t\t\targuments.Add(new CustomAttributeNamedArgument<TType>(name, kind, argument.Type, argument.Value));\n\t\t\t}\n\n\t\t\treturn arguments.MoveToImmutable();\n\t\t}\n\n\t\tprivate struct ArgumentTypeInfo\n\t\t{\n\t\t\tpublic TType Type;\n\t\t\tpublic TType ElementType;\n\t\t\tpublic SerializationTypeCode TypeCode;\n\t\t\tpublic SerializationTypeCode ElementTypeCode;\n\t\t}\n\n\t\tprivate ArgumentTypeInfo DecodeNamedArgumentType(ref BlobReader valueReader, bool isElementType = false)\n\t\t{\n\t\t\tvar info = new ArgumentTypeInfo {\n\t\t\t\tTypeCode = valueReader.ReadSerializationTypeCode(),\n\t\t\t};\n\n\t\t\tswitch (info.TypeCode)\n\t\t\t{\n\t\t\t\tcase SerializationTypeCode.Boolean:\n\t\t\t\tcase SerializationTypeCode.Byte:\n\t\t\t\tcase SerializationTypeCode.Char:\n\t\t\t\tcase SerializationTypeCode.Double:\n\t\t\t\tcase SerializationTypeCode.Int16:\n\t\t\t\tcase SerializationTypeCode.Int32:\n\t\t\t\tcase SerializationTypeCode.Int64:\n\t\t\t\tcase SerializationTypeCode.SByte:\n\t\t\t\tcase SerializationTypeCode.Single:\n\t\t\t\tcase SerializationTypeCode.String:\n\t\t\t\tcase SerializationTypeCode.UInt16:\n\t\t\t\tcase SerializationTypeCode.UInt32:\n\t\t\t\tcase SerializationTypeCode.UInt64:\n\t\t\t\t\tinfo.Type = _provider.GetPrimitiveType((PrimitiveTypeCode)info.TypeCode);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SerializationTypeCode.Type:\n\t\t\t\t\tinfo.Type = _provider.GetSystemType();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SerializationTypeCode.TaggedObject:\n\t\t\t\t\tinfo.Type = _provider.GetPrimitiveType(PrimitiveTypeCode.Object);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SerializationTypeCode.SZArray:\n\t\t\t\t\tif (isElementType)\n\t\t\t\t\t{\n\t\t\t\t\t\t// jagged arrays are not allowed.\n\t\t\t\t\t\tthrow new BadImageFormatException();\n\t\t\t\t\t}\n\n\t\t\t\t\tvar elementInfo = DecodeNamedArgumentType(ref valueReader, isElementType: true);\n\t\t\t\t\tinfo.ElementType = elementInfo.Type;\n\t\t\t\t\tinfo.ElementTypeCode = elementInfo.TypeCode;\n\t\t\t\t\tinfo.Type = _provider.GetSZArrayType(info.ElementType);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SerializationTypeCode.Enum:\n\t\t\t\t\tstring typeName = valueReader.ReadSerializedString();\n\t\t\t\t\tinfo.Type = _provider.GetTypeFromSerializedName(typeName);\n\t\t\t\t\tinfo.TypeCode = (SerializationTypeCode)_provider.GetUnderlyingEnumType(info.Type);\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new BadImageFormatException();\n\t\t\t}\n\n\t\t\treturn info;\n\t\t}\n\n\t\tprivate CustomAttributeTypedArgument<TType> DecodeArgument(ref BlobReader valueReader, ArgumentTypeInfo info)\n\t\t{\n\t\t\tvar outer = info;\n\t\t\tif (info.TypeCode == SerializationTypeCode.TaggedObject)\n\t\t\t{\n\t\t\t\tinfo = DecodeNamedArgumentType(ref valueReader);\n\t\t\t}\n\n\t\t\t// PERF_TODO: https://github.com/dotnet/corefx/issues/6533\n\t\t\t//   Cache /reuse common arguments to avoid boxing (small integers, true, false).\n\t\t\tobject value;\n\t\t\tswitch (info.TypeCode)\n\t\t\t{\n\t\t\t\tcase SerializationTypeCode.Boolean:\n\t\t\t\t\tvalue = valueReader.ReadBoolean();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SerializationTypeCode.Byte:\n\t\t\t\t\tvalue = valueReader.ReadByte();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SerializationTypeCode.Char:\n\t\t\t\t\tvalue = valueReader.ReadChar();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SerializationTypeCode.Double:\n\t\t\t\t\tvalue = valueReader.ReadDouble();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SerializationTypeCode.Int16:\n\t\t\t\t\tvalue = valueReader.ReadInt16();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SerializationTypeCode.Int32:\n\t\t\t\t\tvalue = valueReader.ReadInt32();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SerializationTypeCode.Int64:\n\t\t\t\t\tvalue = valueReader.ReadInt64();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SerializationTypeCode.SByte:\n\t\t\t\t\tvalue = valueReader.ReadSByte();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SerializationTypeCode.Single:\n\t\t\t\t\tvalue = valueReader.ReadSingle();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SerializationTypeCode.UInt16:\n\t\t\t\t\tvalue = valueReader.ReadUInt16();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SerializationTypeCode.UInt32:\n\t\t\t\t\tvalue = valueReader.ReadUInt32();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SerializationTypeCode.UInt64:\n\t\t\t\t\tvalue = valueReader.ReadUInt64();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SerializationTypeCode.String:\n\t\t\t\t\tvalue = valueReader.ReadSerializedString();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SerializationTypeCode.Type:\n\t\t\t\t\tstring typeName = valueReader.ReadSerializedString();\n\t\t\t\t\tvalue = _provider.GetTypeFromSerializedName(typeName);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase SerializationTypeCode.SZArray:\n\t\t\t\t\tvalue = DecodeArrayArgument(ref valueReader, info);\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new BadImageFormatException();\n\t\t\t}\n\n\t\t\tif (_provideBoxingTypeInfo && outer.TypeCode == SerializationTypeCode.TaggedObject)\n\t\t\t{\n\t\t\t\treturn new CustomAttributeTypedArgument<TType>(outer.Type, new CustomAttributeTypedArgument<TType>(info.Type, value));\n\t\t\t}\n\n\t\t\treturn new CustomAttributeTypedArgument<TType>(info.Type, value);\n\t\t}\n\n\t\tprivate ImmutableArray<CustomAttributeTypedArgument<TType>>? DecodeArrayArgument(ref BlobReader blobReader, ArgumentTypeInfo info)\n\t\t{\n\t\t\tint count = blobReader.ReadInt32();\n\t\t\tif (count == -1)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif (count == 0)\n\t\t\t{\n\t\t\t\treturn ImmutableArray<CustomAttributeTypedArgument<TType>>.Empty;\n\t\t\t}\n\n\t\t\tif (count < 0)\n\t\t\t{\n\t\t\t\tthrow new BadImageFormatException();\n\t\t\t}\n\n\t\t\tvar elementInfo = new ArgumentTypeInfo {\n\t\t\t\tType = info.ElementType,\n\t\t\t\tTypeCode = info.ElementTypeCode,\n\t\t\t};\n\n\t\t\tvar array = ImmutableArray.CreateBuilder<CustomAttributeTypedArgument<TType>>(count);\n\n\t\t\tfor (int i = 0; i < count; i++)\n\t\t\t{\n\t\t\t\tarray.Add(DecodeArgument(ref blobReader, elementInfo));\n\t\t\t}\n\n\t\t\treturn array.MoveToImmutable();\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/DotNetCorePathFinder.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.Util;\n\nusing LightJson.Serialization;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\tpublic class DotNetCorePathFinder\n\t{\n\t\tclass DotNetCorePackageInfo\n\t\t{\n\t\t\tpublic readonly string Name;\n\t\t\tpublic readonly string Version;\n\t\t\tpublic readonly string Type;\n\t\t\tpublic readonly string Path;\n\t\t\tpublic readonly string[] RuntimeComponents;\n\n\t\t\tpublic DotNetCorePackageInfo(string fullName, string type, string path, string[] runtimeComponents)\n\t\t\t{\n\t\t\t\tvar parts = fullName.Split('/');\n\t\t\t\tthis.Name = parts[0];\n\t\t\t\tif (parts.Length > 1)\n\t\t\t\t{\n\t\t\t\t\tthis.Version = parts[1];\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthis.Version = \"<UNKNOWN>\";\n\t\t\t\t}\n\n\t\t\t\tthis.Type = type;\n\t\t\t\tthis.Path = path;\n\t\t\t\tthis.RuntimeComponents = runtimeComponents ?? Empty<string>.Array;\n\t\t\t}\n\t\t}\n\n\t\tstatic readonly string[] LookupPaths = new string[] {\n\t\t\tEnvironment.GetEnvironmentVariable(\"NUGET_PACKAGES\"),\n\t\t\tPath.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), \".nuget\", \"packages\")\n\t\t};\n\n\t\tstatic readonly string[] RuntimePacks = new[] {\n\t\t\t\"Microsoft.NETCore.App\",\n\t\t\t\"Microsoft.WindowsDesktop.App\",\n\t\t\t\"Microsoft.AspNetCore.App\",\n\t\t\t\"Microsoft.AspNetCore.All\"\n\t\t};\n\n\t\treadonly DotNetCorePackageInfo[] packages;\n\t\treadonly List<string> searchPaths = new List<string>();\n\t\treadonly List<string> packageBasePaths = new List<string>();\n\t\treadonly Version targetFrameworkVersion;\n\t\treadonly string dotnetBasePath = FindDotNetExeDirectory();\n\t\treadonly string preferredRuntimePack;\n\n\t\tpublic DotNetCorePathFinder(TargetFrameworkIdentifier targetFramework, Version targetFrameworkVersion,\n\t\t\tstring preferredRuntimePack)\n\t\t{\n\t\t\tthis.targetFrameworkVersion = targetFrameworkVersion;\n\t\t\tthis.preferredRuntimePack = preferredRuntimePack;\n\n\t\t\tif (targetFramework == TargetFrameworkIdentifier.NETStandard)\n\t\t\t{\n\t\t\t\t// .NET Standard 2.1 is implemented by .NET Core 3.0 or higher\n\t\t\t\tif (targetFrameworkVersion.Major == 2 && targetFrameworkVersion.Minor == 1)\n\t\t\t\t{\n\t\t\t\t\tthis.targetFrameworkVersion = new Version(3, 0, 0);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic DotNetCorePathFinder(string parentAssemblyFileName, string targetFrameworkIdString, string preferredRuntimePack,\n\t\t\tTargetFrameworkIdentifier targetFramework, Version targetFrameworkVersion, ReferenceLoadInfo loadInfo = null)\n\t\t\t: this(targetFramework, targetFrameworkVersion, preferredRuntimePack)\n\t\t{\n\t\t\tstring assemblyName = Path.GetFileNameWithoutExtension(parentAssemblyFileName);\n\t\t\tstring basePath = Path.GetDirectoryName(parentAssemblyFileName);\n\n\t\t\tsearchPaths.Add(basePath);\n\n\t\t\tvar depsJsonFileName = Path.Combine(basePath, $\"{assemblyName}.deps.json\");\n\t\t\tif (File.Exists(depsJsonFileName))\n\t\t\t{\n\t\t\t\tpackages = LoadPackageInfos(depsJsonFileName, targetFrameworkIdString).ToArray();\n\n\t\t\t\tforeach (var path in LookupPaths)\n\t\t\t\t{\n\t\t\t\t\tif (string.IsNullOrWhiteSpace(path))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tforeach (var p in packages)\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var item in p.RuntimeComponents)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar itemPath = Path.GetDirectoryName(item);\n\t\t\t\t\t\t\tvar fullPath = Path.Combine(path, p.Name, p.Version, itemPath).ToLowerInvariant();\n\t\t\t\t\t\t\tif (Directory.Exists(fullPath))\n\t\t\t\t\t\t\t\tpackageBasePaths.Add(fullPath);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tloadInfo?.AddMessage(assemblyName, MessageKind.Warning, $\"{assemblyName}.deps.json could not be found!\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void AddSearchDirectory(string path)\n\t\t{\n\t\t\tthis.searchPaths.Add(path);\n\t\t}\n\n\t\tpublic void RemoveSearchDirectory(string path)\n\t\t{\n\t\t\tthis.searchPaths.Remove(path);\n\t\t}\n\n\t\tpublic string TryResolveDotNetCore(IAssemblyReference name)\n\t\t{\n\t\t\tforeach (var basePath in searchPaths.Concat(packageBasePaths))\n\t\t\t{\n\t\t\t\tif (File.Exists(Path.Combine(basePath, name.Name + \".dll\")))\n\t\t\t\t{\n\t\t\t\t\treturn Path.Combine(basePath, name.Name + \".dll\");\n\t\t\t\t}\n\t\t\t\telse if (File.Exists(Path.Combine(basePath, name.Name + \".exe\")))\n\t\t\t\t{\n\t\t\t\t\treturn Path.Combine(basePath, name.Name + \".exe\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn TryResolveDotNetCoreShared(name, out _);\n\t\t}\n\n\t\tinternal string GetReferenceAssemblyPath(string targetFramework)\n\t\t{\n\t\t\tvar (tfi, version) = UniversalAssemblyResolver.ParseTargetFramework(targetFramework);\n\t\t\tstring identifier, identifierExt;\n\t\t\tswitch (tfi)\n\t\t\t{\n\t\t\t\tcase TargetFrameworkIdentifier.NETCoreApp:\n\t\t\t\t\tidentifier = \"Microsoft.NETCore.App\";\n\t\t\t\t\tidentifierExt = \"netcoreapp\" + version.Major + \".\" + version.Minor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TargetFrameworkIdentifier.NETStandard:\n\t\t\t\t\tidentifier = \"NETStandard.Library\";\n\t\t\t\t\tidentifierExt = \"netstandard\" + version.Major + \".\" + version.Minor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TargetFrameworkIdentifier.NET:\n\t\t\t\t\tidentifier = \"Microsoft.NETCore.App\";\n\t\t\t\t\tidentifierExt = \"net\" + version.Major + \".\" + version.Minor;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException();\n\t\t\t}\n\t\t\tstring basePath = Path.Combine(dotnetBasePath, \"packs\", identifier + \".Ref\");\n\t\t\tstring versionFolder = GetClosestVersionFolder(basePath, version);\n\t\t\treturn Path.Combine(basePath, versionFolder, \"ref\", identifierExt);\n\t\t}\n\n\t\tstatic IEnumerable<DotNetCorePackageInfo> LoadPackageInfos(string depsJsonFileName, string targetFramework)\n\t\t{\n\t\t\tvar dependencies = JsonReader.Parse(File.ReadAllText(depsJsonFileName));\n\t\t\tvar runtimeInfos = dependencies[\"targets\"][targetFramework].AsJsonObject;\n\t\t\tvar libraries = dependencies[\"libraries\"].AsJsonObject;\n\t\t\tif (runtimeInfos == null || libraries == null)\n\t\t\t\tyield break;\n\t\t\tforeach (var library in libraries)\n\t\t\t{\n\t\t\t\tvar type = library.Value[\"type\"].AsString;\n\t\t\t\tvar path = library.Value[\"path\"].AsString;\n\t\t\t\tvar runtimeInfo = runtimeInfos[library.Key].AsJsonObject?[\"runtime\"].AsJsonObject;\n\t\t\t\tstring[] components = new string[runtimeInfo?.Count ?? 0];\n\t\t\t\tif (runtimeInfo != null)\n\t\t\t\t{\n\t\t\t\t\tint i = 0;\n\t\t\t\t\tforeach (var component in runtimeInfo)\n\t\t\t\t\t{\n\t\t\t\t\t\tcomponents[i] = component.Key;\n\t\t\t\t\t\ti++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tyield return new DotNetCorePackageInfo(library.Key, type, path, components);\n\t\t\t}\n\t\t}\n\n\t\tpublic string TryResolveDotNetCoreShared(IAssemblyReference name, out string runtimePack)\n\t\t{\n\t\t\tif (dotnetBasePath == null)\n\t\t\t{\n\t\t\t\truntimePack = null;\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tIEnumerable<string> runtimePacks = RuntimePacks;\n\n\t\t\tif (preferredRuntimePack != null)\n\t\t\t{\n\t\t\t\truntimePacks = new[] { preferredRuntimePack }.Concat(runtimePacks);\n\t\t\t}\n\n\t\t\tforeach (string pack in runtimePacks)\n\t\t\t{\n\t\t\t\truntimePack = pack;\n\t\t\t\tstring basePath = Path.Combine(dotnetBasePath, \"shared\", pack);\n\t\t\t\tif (!Directory.Exists(basePath))\n\t\t\t\t\tcontinue;\n\t\t\t\tvar closestVersion = GetClosestVersionFolder(basePath, targetFrameworkVersion);\n\t\t\t\tif (File.Exists(Path.Combine(basePath, closestVersion, name.Name + \".dll\")))\n\t\t\t\t{\n\t\t\t\t\treturn Path.Combine(basePath, closestVersion, name.Name + \".dll\");\n\t\t\t\t}\n\t\t\t\telse if (File.Exists(Path.Combine(basePath, closestVersion, name.Name + \".exe\")))\n\t\t\t\t{\n\t\t\t\t\treturn Path.Combine(basePath, closestVersion, name.Name + \".exe\");\n\t\t\t\t}\n\t\t\t}\n\t\t\truntimePack = null;\n\t\t\treturn null;\n\t\t}\n\n\t\tstatic string GetClosestVersionFolder(string basePath, Version version)\n\t\t{\n\t\t\tvar foundVersions = new DirectoryInfo(basePath).GetDirectories()\n\t\t\t\t.Select(ConvertToVersion)\n\t\t\t\t.Where(v => v.version != null);\n\t\t\tforeach (var folder in foundVersions.OrderBy(v => v.version))\n\t\t\t{\n\t\t\t\tif (folder.version >= version\n\t\t\t\t\t&& folder.directory.EnumerateFiles(\"*.dll\", SearchOption.AllDirectories).Any())\n\t\t\t\t{\n\t\t\t\t\treturn folder.directory.Name;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn version.ToString();\n\t\t}\n\n\t\tinternal static (Version version, DirectoryInfo directory) ConvertToVersion(DirectoryInfo directory)\n\t\t{\n\t\t\tstring RemoveTrailingVersionInfo()\n\t\t\t{\n\t\t\t\tstring shortName = directory.Name;\n\t\t\t\tint dashIndex = shortName.IndexOf('-');\n\t\t\t\tif (dashIndex > 0)\n\t\t\t\t{\n\t\t\t\t\tshortName = shortName.Remove(dashIndex);\n\t\t\t\t}\n\t\t\t\treturn shortName;\n\t\t\t}\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn (new Version(RemoveTrailingVersionInfo()), directory);\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tTrace.TraceWarning(ex.ToString());\n\t\t\t\treturn (null, null);\n\t\t\t}\n\t\t}\n\n\t\tpublic static string FindDotNetExeDirectory()\n\t\t{\n\t\t\tstring dotnetExeName = (Environment.OSVersion.Platform == PlatformID.Unix) ? \"dotnet\" : \"dotnet.exe\";\n\t\t\tforeach (var item in Environment.GetEnvironmentVariable(\"PATH\").Split(Path.PathSeparator))\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tstring fileName = Path.Combine(item, dotnetExeName);\n\t\t\t\t\tif (!File.Exists(fileName))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tif (Environment.OSVersion.Platform == PlatformID.Unix)\n\t\t\t\t\t{\n\t\t\t\t\t\tif ((new FileInfo(fileName).Attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfileName = GetRealPath(fileName, Encoding.Default);\n\t\t\t\t\t\t\tif (!File.Exists(fileName))\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn Path.GetDirectoryName(fileName);\n\t\t\t\t}\n\t\t\t\tcatch (ArgumentException) { }\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tstatic unsafe string GetRealPath(string path, Encoding encoding)\n\t\t{\n\t\t\tvar bytes = encoding.GetBytes(path);\n\t\t\tfixed (byte* input = bytes)\n\t\t\t{\n\n\t\t\t\tbyte* output = GetRealPath(input, null);\n\t\t\t\tif (output == null)\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tint len = 0;\n\t\t\t\tfor (byte* c = output; *c != 0; c++)\n\t\t\t\t{\n\t\t\t\t\tlen++;\n\t\t\t\t}\n\t\t\t\tbyte[] result = new byte[len];\n\t\t\t\tMarshal.Copy((IntPtr)output, result, 0, result.Length);\n\t\t\t\tFree(output);\n\t\t\t\treturn encoding.GetString(result);\n\t\t\t}\n\t\t}\n\n\t\t[DllImport(\"libc\", EntryPoint = \"realpath\")]\n\t\tstatic extern unsafe byte* GetRealPath(byte* path, byte* resolvedPath);\n\n\t\t[DllImport(\"libc\", EntryPoint = \"free\")]\n\t\tstatic extern unsafe void Free(void* ptr);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/DotNetCorePathFinderExtensions.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Reflection.Metadata;\nusing System.Text.RegularExpressions;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\tpublic static class DotNetCorePathFinderExtensions\n\t{\n\t\tstatic readonly string PathPattern =\n\t\t\t@\"(Reference Assemblies[/\\\\]Microsoft[/\\\\]Framework[/\\\\](?<type>.NETFramework)[/\\\\]v(?<version>[^/\\\\]+)[/\\\\])\" +\n\t\t\t@\"|((?<type>Microsoft\\.NET)[/\\\\]assembly[/\\\\]GAC_(MSIL|32|64)[/\\\\])\" +\n\t\t\t@\"|((?<type>Microsoft\\.NET)[/\\\\]Framework(64)?[/\\\\](?<version>[^/\\\\]+)[/\\\\])\" +\n\t\t\t@\"|(NuGetFallbackFolder[/\\\\](?<type>[^/\\\\]+)\\\\(?<version>[^/\\\\]+)([/\\\\].*)?[/\\\\]ref[/\\\\])\" +\n\t\t\t@\"|(shared[/\\\\](?<type>[^/\\\\]+)\\\\(?<version>[^/\\\\]+)([/\\\\].*)?[/\\\\])\" +\n\t\t\t@\"|(packs[/\\\\](?<type>[^/\\\\]+)\\\\(?<version>[^/\\\\]+)\\\\ref([/\\\\].*)?[/\\\\])\";\n\n\t\tstatic readonly string RefPathPattern =\n\t\t\t@\"(Reference Assemblies[/\\\\]Microsoft[/\\\\]Framework[/\\\\](?<type>.NETFramework)[/\\\\]v(?<version>[^/\\\\]+)[/\\\\])\" +\n\t\t\t@\"|(NuGetFallbackFolder[/\\\\](?<type>[^/\\\\]+)\\\\(?<version>[^/\\\\]+)([/\\\\].*)?[/\\\\]ref[/\\\\])\" +\n\t\t\t@\"|(packs[/\\\\](?<type>[^/\\\\]+)\\\\(?<version>[^/\\\\]+)\\\\ref([/\\\\].*)?[/\\\\])\";\n\n\t\tpublic static string DetectTargetFrameworkId(this MetadataFile assembly)\n\t\t{\n\t\t\treturn DetectTargetFrameworkId(assembly.Metadata, assembly.FileName);\n\t\t}\n\n\t\tpublic static string DetectTargetFrameworkId(this MetadataReader metadata, string assemblyPath = null)\n\t\t{\n\t\t\tif (metadata == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(metadata));\n\n\t\t\tconst string TargetFrameworkAttributeName = \"System.Runtime.Versioning.TargetFrameworkAttribute\";\n\n\t\t\tforeach (var h in metadata.GetCustomAttributes(Handle.AssemblyDefinition))\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tvar attribute = metadata.GetCustomAttribute(h);\n\t\t\t\t\tif (attribute.GetAttributeType(metadata).GetFullTypeName(metadata).ToString() != TargetFrameworkAttributeName)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tvar blobReader = metadata.GetBlobReader(attribute.Value);\n\t\t\t\t\tif (blobReader.ReadUInt16() == 0x0001)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn blobReader.ReadSerializedString()?.Replace(\" \", \"\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\t// ignore malformed attributes\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (metadata.IsAssembly)\n\t\t\t{\n\t\t\t\tAssemblyDefinition assemblyDefinition = metadata.GetAssemblyDefinition();\n\t\t\t\tswitch (metadata.GetString(assemblyDefinition.Name))\n\t\t\t\t{\n\t\t\t\t\tcase \"mscorlib\":\n\t\t\t\t\t\treturn $\".NETFramework,Version=v{assemblyDefinition.Version.ToString(2)}\";\n\t\t\t\t\tcase \"netstandard\":\n\t\t\t\t\t\treturn $\".NETStandard,Version=v{assemblyDefinition.Version.ToString(2)}\";\n\t\t\t\t\tcase \"System.Runtime\":\n\t\t\t\t\tcase \"System.Private.CoreLib\":\n\t\t\t\t\t{\n\t\t\t\t\t\tstring version = GetDotNetCoreVersion(assemblyDefinition.Version);\n\t\t\t\t\t\tif (version != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn $\".NETCoreApp,Version=v{version}\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach (var h in metadata.AssemblyReferences)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tvar r = metadata.GetAssemblyReference(h);\n\t\t\t\t\tif (r.PublicKeyOrToken.IsNil)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tstring version;\n\t\t\t\t\tswitch (metadata.GetString(r.Name))\n\t\t\t\t\t{\n\t\t\t\t\t\tcase \"mscorlib\":\n\t\t\t\t\t\t\tversion = r.Version.ToString(2);\n\t\t\t\t\t\t\treturn $\".NETFramework,Version=v{version}\";\n\t\t\t\t\t\tcase \"System.Runtime\":\n\t\t\t\t\t\tcase \"System.Private.CoreLib\":\n\t\t\t\t\t\t\tversion = GetDotNetCoreVersion(r.Version);\n\t\t\t\t\t\t\tif (version != null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn $\".NETCoreApp,Version=v{version}\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\t// ignore malformed references\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// We check for netstandard separately because .NET Core/Framework assemblies can reference it.\n\t\t\tforeach (var h in metadata.AssemblyReferences)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tvar r = metadata.GetAssemblyReference(h);\n\t\t\t\t\tif (r.PublicKeyOrToken.IsNil || metadata.GetString(r.Name) is not \"netstandard\")\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\tstring version = r.Version.ToString(2);\n\t\t\t\t\treturn $\".NETStandard,Version=v{version}\";\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\t// ignore malformed references\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Optionally try to detect target version through assembly path as a fallback (use case: reference assemblies)\n\t\t\tif (assemblyPath != null)\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t * Detected path patterns (examples):\n\t\t\t\t * \n\t\t\t\t * - .NETFramework -> C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.6.1\\mscorlib.dll\n\t\t\t\t * - .NETCore      -> C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder\\microsoft.netcore.app\\2.1.0\\ref\\netcoreapp2.1\\System.Console.dll\n\t\t\t\t * - .NETStandard  -> C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder\\netstandard.library\\2.0.3\\build\\netstandard2.0\\ref\\netstandard.dll\n\t\t\t\t */\n\t\t\t\tvar pathMatch = Regex.Match(assemblyPath, PathPattern,\n\t\t\t\t\tRegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.ExplicitCapture);\n\t\t\t\tstring version;\n\t\t\t\tif (pathMatch.Success)\n\t\t\t\t{\n\t\t\t\t\tvar type = pathMatch.Groups[\"type\"].Value;\n\t\t\t\t\tversion = pathMatch.Groups[\"version\"].Value;\n\t\t\t\t\tif (string.IsNullOrEmpty(version))\n\t\t\t\t\t\tversion = metadata.MetadataVersion;\n\t\t\t\t\tif (string.IsNullOrEmpty(version))\n\t\t\t\t\t\tversion = \"4.0\";\n\t\t\t\t\tversion = version.TrimStart('v');\n\n\t\t\t\t\tif (type == \"Microsoft.NET\" || type == \".NETFramework\")\n\t\t\t\t\t{\n\t\t\t\t\t\treturn $\".NETFramework,Version=v{version.Substring(0, Math.Min(3, version.Length))}\";\n\t\t\t\t\t}\n\t\t\t\t\telse if (type.IndexOf(\"netcore\", StringComparison.OrdinalIgnoreCase) >= 0)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn $\".NETCoreApp,Version=v{version}\";\n\t\t\t\t\t}\n\t\t\t\t\telse if (type.IndexOf(\"netstandard\", StringComparison.OrdinalIgnoreCase) >= 0)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn $\".NETStandard,Version=v{version}\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tversion = metadata.MetadataVersion;\n\t\t\t\t\tif (string.IsNullOrEmpty(version))\n\t\t\t\t\t\tversion = \"4.0\";\n\t\t\t\t\tversion = version.TrimStart('v');\n\t\t\t\t\treturn $\".NETFramework,Version=v{version.Substring(0, Math.Min(3, version.Length))}\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn string.Empty;\n\t\t}\n\n\t\tstatic string GetDotNetCoreVersion(Version assemblyVersion)\n\t\t{\n\t\t\t// System.Runtime.dll and System.Private.CoreLib.dll use the following scheme:\n\t\t\t// 4.1.0 => .NET Core 1.0 / 1.1\n\t\t\t// 4.2.0 => .NET Core 2.0\n\t\t\t// 4.2.1 => .NET Core 2.1 / 3.0\n\t\t\t// 4.2.2 => .NET Core 3.1\n\t\t\t// 5.0.0+ => .NET 5+\n\t\t\treturn (assemblyVersion.Major, assemblyVersion.Minor, assemblyVersion.Build) switch {\n\t\t\t\t(4, 1, 0) => \"1.1\",\n\t\t\t\t(4, 2, 0) => \"2.0\",\n\t\t\t\t(4, 2, 1) => \"3.0\",\n\t\t\t\t(4, 2, 2) => \"3.1\",\n\t\t\t\t( >= 5, _, _) => assemblyVersion.ToString(2),\n\t\t\t\t_ => null\n\t\t\t};\n\t\t}\n\n\t\tpublic static bool IsReferenceAssembly(this MetadataFile assembly)\n\t\t{\n\t\t\treturn IsReferenceAssembly(assembly.Metadata, assembly.FileName);\n\t\t}\n\n\t\tpublic static bool IsReferenceAssembly(this MetadataReader metadata, string assemblyPath)\n\t\t{\n\t\t\tif (metadata == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(metadata));\n\n\t\t\tif (metadata.GetCustomAttributes(Handle.AssemblyDefinition).HasKnownAttribute(metadata, KnownAttribute.ReferenceAssembly))\n\t\t\t\treturn true;\n\n\t\t\t// Try to detect reference assembly through specific path pattern\n\t\t\tvar refPathMatch = Regex.Match(assemblyPath, RefPathPattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);\n\t\t\treturn refPathMatch.Success;\n\t\t}\n\n\t\tpublic static string DetectRuntimePack(this MetadataFile assembly)\n\t\t{\n\t\t\tif (assembly is null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(assembly));\n\t\t\t}\n\n\t\t\tvar metadata = assembly.Metadata;\n\n\t\t\tforeach (var r in metadata.AssemblyReferences)\n\t\t\t{\n\t\t\t\tvar reference = metadata.GetAssemblyReference(r);\n\n\t\t\t\tif (reference.PublicKeyOrToken.IsNil)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (metadata.StringComparer.Equals(reference.Name, \"WindowsBase\"))\n\t\t\t\t{\n\t\t\t\t\treturn \"Microsoft.WindowsDesktop.App\";\n\t\t\t\t}\n\n\t\t\t\tif (metadata.StringComparer.Equals(reference.Name, \"PresentationFramework\"))\n\t\t\t\t{\n\t\t\t\t\treturn \"Microsoft.WindowsDesktop.App\";\n\t\t\t\t}\n\n\t\t\t\tif (metadata.StringComparer.Equals(reference.Name, \"PresentationCore\"))\n\t\t\t\t{\n\t\t\t\t\treturn \"Microsoft.WindowsDesktop.App\";\n\t\t\t\t}\n\n\t\t\t\t// TODO add support for ASP.NET Core\n\t\t\t}\n\n\t\t\treturn \"Microsoft.NETCore.App\";\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/EnumUnderlyingTypeResolveException.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Runtime.Serialization;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\t[Serializable]\n\tpublic class EnumUnderlyingTypeResolveException : Exception\n\t{\n\t\tpublic EnumUnderlyingTypeResolveException() { }\n\t\tpublic EnumUnderlyingTypeResolveException(string message) : base(message) { }\n\t\tpublic EnumUnderlyingTypeResolveException(string message, Exception inner) : base(message, inner) { }\n\t\tprotected EnumUnderlyingTypeResolveException(\n\t\t  SerializationInfo info,\n\t\t  StreamingContext context) : base(info, context) { }\n\t}\n\n\t[Serializable]\n\tpublic class MetadataFileNotSupportedException : Exception\n\t{\n\t\tpublic MetadataFileNotSupportedException() { }\n\t\tpublic MetadataFileNotSupportedException(string message) : base(message) { }\n\t\tpublic MetadataFileNotSupportedException(string message, Exception inner) : base(message, inner) { }\n\t\tprotected MetadataFileNotSupportedException(\n\t\t  SerializationInfo info,\n\t\t  StreamingContext context) : base(info, context) { }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/ExportedTypeMetadata.cs",
    "content": "// Copyright (c) 2023 James May\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n#if !VSADDIN\n\t/// <summary>\n\t/// Convenience wrapper for <see cref=\"ExportedType\"/> and <see cref=\"ExportedTypeHandle\"/>.\n\t/// </summary>\n\tpublic sealed class ExportedTypeMetadata\n\t{\n\t\treadonly ExportedType entry;\n\n\t\tpublic MetadataReader Metadata { get; }\n\t\tpublic ExportedTypeHandle Handle { get; }\n\n\t\tstring? name;\n\t\tpublic string Name {\n\t\t\tget {\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\treturn name ??= Metadata.GetString(entry.Name);\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\treturn name = $\"ET:{Handle}\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstring? @namespace;\n\t\tpublic string Namespace {\n\t\t\tget {\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\treturn @namespace ??= Metadata.GetString(entry.Namespace);\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\treturn @namespace = $\"namespace(ET:{Handle})\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic EntityHandle Implementation => entry.Implementation;\n\t\tpublic TypeAttributes Attributes => entry.Attributes;\n\t\tpublic bool IsForwarder => entry.IsForwarder;\n\t\tpublic NamespaceDefinition NamespaceDefinition => Metadata.GetNamespaceDefinition(entry.NamespaceDefinition);\n\n\t\tImmutableArray<ExportedTypeMetadata> exportedTypes;\n\t\tpublic ImmutableArray<ExportedTypeMetadata> ExportedTypes {\n\t\t\tget {\n\t\t\t\tvar value = exportedTypes;\n\t\t\t\tif (value.IsDefault)\n\t\t\t\t{\n\t\t\t\t\tvalue = Metadata.ExportedTypes\n\t\t\t\t\t\t.Select(r => new ExportedTypeMetadata(Metadata, r))\n\t\t\t\t\t\t.Where(r => r.Implementation == Handle)\n\t\t\t\t\t\t.OrderBy(r => r.Namespace)\n\t\t\t\t\t\t.ThenBy(r => r.Name)\n\t\t\t\t\t\t.ToImmutableArray();\n\t\t\t\t\texportedTypes = value;\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\n\t\tpublic ExportedTypeMetadata(MetadataReader metadata, ExportedTypeHandle handle)\n\t\t{\n\t\t\tMetadata = metadata ?? throw new ArgumentNullException(nameof(metadata));\n\t\t\tif (handle.IsNil)\n\t\t\t\tthrow new ArgumentNullException(nameof(handle));\n\t\t\tHandle = handle;\n\t\t\tentry = metadata.GetExportedType(handle);\n\t\t}\n\n\t\tpublic override string ToString() => $\"{Namespace}::{Name}\";\n\t}\n#endif\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/FindTypeDecoder.cs",
    "content": "// Copyright (c) 2022 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Immutable;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\tpublic class FindTypeDecoder : ISignatureTypeProvider<bool, Unit>\n\t{\n\t\treadonly MetadataFile declaringModule;\n\t\treadonly MetadataModule? currentModule;\n\t\treadonly TypeDefinitionHandle handle;\n\t\treadonly string? typeName;\n\t\treadonly string? namespaceName;\n\t\treadonly PrimitiveTypeCode primitiveType;\n\n\t\t/// <summary>\n\t\t/// Constructs a FindTypeDecoder that finds uses of a specific type-definition handle.\n\t\t/// This assumes that the module we are search in is the same as the module containing the type-definiton.\n\t\t/// </summary>\n\t\tinternal FindTypeDecoder(TypeDefinitionHandle handle, MetadataFile declaringModule)\n\t\t{\n\t\t\tthis.handle = handle;\n\t\t\tthis.declaringModule = declaringModule;\n\t\t\tthis.primitiveType = 0;\n\t\t\tthis.currentModule = null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Constructs a FindTypeDecoder that can be used to find <paramref name=\"type\"/> in signatures from <paramref name=\"currentModule\"/>.\n\t\t/// </summary>\n\t\tpublic FindTypeDecoder(MetadataModule currentModule, ITypeDefinition type)\n\t\t{\n\t\t\tthis.currentModule = currentModule;\n\t\t\tthis.declaringModule = type.ParentModule?.MetadataFile ?? throw new InvalidOperationException(\"Cannot use MetadataModule without PEFile as context.\");\n\t\t\tthis.handle = (TypeDefinitionHandle)type.MetadataToken;\n\t\t\tthis.primitiveType = type.KnownTypeCode == KnownTypeCode.None ? 0 : type.KnownTypeCode.ToPrimitiveTypeCode();\n\t\t\tthis.typeName = type.MetadataName;\n\t\t\tthis.namespaceName = type.Namespace;\n\t\t}\n\n\t\tpublic bool GetArrayType(bool elementType, ArrayShape shape) => elementType;\n\t\tpublic bool GetByReferenceType(bool elementType) => elementType;\n\t\tpublic bool GetFunctionPointerType(MethodSignature<bool> signature)\n\t\t{\n\t\t\treturn AnyInMethodSignature(signature);\n\t\t}\n\n\t\tpublic static bool AnyInMethodSignature(MethodSignature<bool> signature)\n\t\t{\n\t\t\tif (signature.ReturnType)\n\t\t\t\treturn true;\n\t\t\tforeach (bool type in signature.ParameterTypes)\n\t\t\t{\n\t\t\t\tif (type)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool GetGenericInstantiation(bool genericType, ImmutableArray<bool> typeArguments)\n\t\t{\n\t\t\tif (genericType)\n\t\t\t\treturn true;\n\t\t\tforeach (bool ta in typeArguments)\n\t\t\t{\n\t\t\t\tif (ta)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool GetGenericMethodParameter(Unit genericContext, int index) => false;\n\t\tpublic bool GetGenericTypeParameter(Unit genericContext, int index) => false;\n\t\tpublic bool GetModifiedType(bool modifier, bool unmodifiedType, bool isRequired) => unmodifiedType || modifier;\n\t\tpublic bool GetPinnedType(bool elementType) => elementType;\n\t\tpublic bool GetPointerType(bool elementType) => elementType;\n\n\t\tpublic bool GetPrimitiveType(PrimitiveTypeCode typeCode)\n\t\t{\n\t\t\treturn typeCode == primitiveType;\n\t\t}\n\n\t\tpublic bool GetSZArrayType(bool elementType) => elementType;\n\n\t\tpublic bool GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)\n\t\t{\n\t\t\treturn this.handle == handle && reader == declaringModule.Metadata;\n\t\t}\n\n\t\tpublic bool GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)\n\t\t{\n\t\t\tif (currentModule == null || typeName == null || namespaceName == null)\n\t\t\t\treturn false;\n\n\t\t\tvar tr = reader.GetTypeReference(handle);\n\t\t\tif (!reader.StringComparer.Equals(tr.Name, typeName))\n\t\t\t\treturn false;\n\t\t\tif (!((tr.Namespace.IsNil && namespaceName.Length == 0) || reader.StringComparer.Equals(tr.Namespace, namespaceName)))\n\t\t\t\treturn false;\n\n\t\t\tvar t = currentModule.ResolveType(handle, default);\n\t\t\tvar td = t.GetDefinition();\n\t\t\tif (td == null)\n\t\t\t\treturn false;\n\n\t\t\treturn td.MetadataToken == this.handle && td.ParentModule?.MetadataFile == declaringModule;\n\t\t}\n\n\t\tpublic bool GetTypeFromSpecification(MetadataReader reader, Unit genericContext, TypeSpecificationHandle handle, byte rawTypeKind)\n\t\t{\n\t\t\treturn reader.GetTypeSpecification(handle).DecodeSignature(this, genericContext);\n\t\t}\n\n\t\tpublic bool GetTypeFromEntity(MetadataReader reader, EntityHandle handle, Unit genericContext = default, byte rawTypeKind = 0)\n\t\t{\n\t\t\tswitch (handle.Kind)\n\t\t\t{\n\t\t\t\tcase HandleKind.TypeReference:\n\t\t\t\t\treturn GetTypeFromReference(reader, (TypeReferenceHandle)handle, rawTypeKind);\n\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\t\treturn GetTypeFromDefinition(reader, (TypeDefinitionHandle)handle, rawTypeKind);\n\t\t\t\tcase HandleKind.TypeSpecification:\n\t\t\t\t\treturn GetTypeFromSpecification(reader, genericContext, (TypeSpecificationHandle)handle, rawTypeKind);\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/FullTypeNameSignatureDecoder.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Immutable;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\tpublic sealed class FullTypeNameSignatureDecoder : ISignatureTypeProvider<FullTypeName, Unit>, ICustomAttributeTypeProvider<FullTypeName>\n\t{\n\t\treadonly MetadataReader metadata;\n\n\t\tpublic FullTypeNameSignatureDecoder(MetadataReader metadata)\n\t\t{\n\t\t\tthis.metadata = metadata;\n\t\t}\n\n\t\tpublic FullTypeName GetArrayType(FullTypeName elementType, ArrayShape shape)\n\t\t{\n\t\t\treturn elementType;\n\t\t}\n\n\t\tpublic FullTypeName GetByReferenceType(FullTypeName elementType)\n\t\t{\n\t\t\treturn elementType;\n\t\t}\n\n\t\tpublic FullTypeName GetFunctionPointerType(MethodSignature<FullTypeName> signature)\n\t\t{\n\t\t\treturn default;\n\t\t}\n\n\t\tpublic FullTypeName GetGenericInstantiation(FullTypeName genericType, ImmutableArray<FullTypeName> typeArguments)\n\t\t{\n\t\t\treturn genericType;\n\t\t}\n\n\t\tpublic FullTypeName GetGenericMethodParameter(Unit genericContext, int index)\n\t\t{\n\t\t\treturn default;\n\t\t}\n\n\t\tpublic FullTypeName GetGenericTypeParameter(Unit genericContext, int index)\n\t\t{\n\t\t\treturn default;\n\t\t}\n\n\t\tpublic FullTypeName GetModifiedType(FullTypeName modifier, FullTypeName unmodifiedType, bool isRequired)\n\t\t{\n\t\t\treturn unmodifiedType;\n\t\t}\n\n\t\tpublic FullTypeName GetPinnedType(FullTypeName elementType)\n\t\t{\n\t\t\treturn elementType;\n\t\t}\n\n\t\tpublic FullTypeName GetPointerType(FullTypeName elementType)\n\t\t{\n\t\t\treturn elementType;\n\t\t}\n\n\t\tpublic FullTypeName GetPrimitiveType(PrimitiveTypeCode typeCode)\n\t\t{\n\t\t\tvar ktr = KnownTypeReference.Get(typeCode.ToKnownTypeCode());\n\t\t\tif (ktr == null)\n\t\t\t\treturn default;\n\t\t\treturn new TopLevelTypeName(ktr.Namespace, ktr.Name, ktr.TypeParameterCount);\n\t\t}\n\n\t\tpublic FullTypeName GetSystemType()\n\t\t{\n\t\t\treturn new TopLevelTypeName(\"System\", \"Type\");\n\t\t}\n\n\t\tpublic FullTypeName GetSZArrayType(FullTypeName elementType)\n\t\t{\n\t\t\treturn elementType;\n\t\t}\n\n\t\tpublic FullTypeName GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)\n\t\t{\n\t\t\treturn handle.GetFullTypeName(reader);\n\t\t}\n\n\t\tpublic FullTypeName GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)\n\t\t{\n\t\t\treturn handle.GetFullTypeName(reader);\n\t\t}\n\n\t\tpublic FullTypeName GetTypeFromSerializedName(string name)\n\t\t{\n\t\t\treturn new FullTypeName(name);\n\t\t}\n\n\t\tpublic FullTypeName GetTypeFromSpecification(MetadataReader reader, Unit genericContext, TypeSpecificationHandle handle, byte rawTypeKind)\n\t\t{\n\t\t\treturn reader.GetTypeSpecification(handle).DecodeSignature(new FullTypeNameSignatureDecoder(metadata), default);\n\t\t}\n\n\t\tpublic PrimitiveTypeCode GetUnderlyingEnumType(FullTypeName type)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tpublic bool IsSystemType(FullTypeName type)\n\t\t{\n\t\t\treturn type.IsKnownType(KnownTypeCode.Type);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/ILOpCodes.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\n\tstatic partial class ILOpCodeExtensions\n\t{\n\t\t// We use a byte array instead of an enum array because it can be initialized more efficiently\n\t\tstatic readonly byte[] operandTypes = { (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.ShortVariable, (byte)OperandType.ShortVariable, (byte)OperandType.ShortVariable, (byte)OperandType.ShortVariable, (byte)OperandType.ShortVariable, (byte)OperandType.ShortVariable, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.ShortI, (byte)OperandType.I, (byte)OperandType.I8, (byte)OperandType.ShortR, (byte)OperandType.R, 255, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.Method, (byte)OperandType.Method, (byte)OperandType.Sig, (byte)OperandType.None, (byte)OperandType.ShortBrTarget, (byte)OperandType.ShortBrTarget, (byte)OperandType.ShortBrTarget, (byte)OperandType.ShortBrTarget, (byte)OperandType.ShortBrTarget, (byte)OperandType.ShortBrTarget, (byte)OperandType.ShortBrTarget, (byte)OperandType.ShortBrTarget, (byte)OperandType.ShortBrTarget, (byte)OperandType.ShortBrTarget, (byte)OperandType.ShortBrTarget, (byte)OperandType.ShortBrTarget, (byte)OperandType.ShortBrTarget, (byte)OperandType.BrTarget, (byte)OperandType.BrTarget, (byte)OperandType.BrTarget, (byte)OperandType.BrTarget, (byte)OperandType.BrTarget, (byte)OperandType.BrTarget, (byte)OperandType.BrTarget, (byte)OperandType.BrTarget, (byte)OperandType.BrTarget, (byte)OperandType.BrTarget, (byte)OperandType.BrTarget, (byte)OperandType.BrTarget, (byte)OperandType.BrTarget, (byte)OperandType.Switch, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.Method, (byte)OperandType.Type, (byte)OperandType.Type, (byte)OperandType.String, (byte)OperandType.Method, (byte)OperandType.Type, (byte)OperandType.Type, (byte)OperandType.None, 255, 255, (byte)OperandType.Type, (byte)OperandType.None, (byte)OperandType.Field, (byte)OperandType.Field, (byte)OperandType.Field, (byte)OperandType.Field, (byte)OperandType.Field, (byte)OperandType.Field, (byte)OperandType.Type, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.Type, (byte)OperandType.Type, (byte)OperandType.None, (byte)OperandType.Type, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.Type, (byte)OperandType.Type, (byte)OperandType.Type, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, 255, 255, 255, 255, 255, 255, 255, (byte)OperandType.Type, (byte)OperandType.None, 255, 255, (byte)OperandType.Type, 255, 255, 255, 255, 255, 255, 255, 255, 255, (byte)OperandType.Tok, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.BrTarget, (byte)OperandType.ShortBrTarget, (byte)OperandType.None, (byte)OperandType.None, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.Method, (byte)OperandType.Method, 255, (byte)OperandType.Variable, (byte)OperandType.Variable, (byte)OperandType.Variable, (byte)OperandType.Variable, (byte)OperandType.Variable, (byte)OperandType.Variable, (byte)OperandType.None, 255, (byte)OperandType.None, (byte)OperandType.ShortI, (byte)OperandType.None, (byte)OperandType.None, (byte)OperandType.Type, (byte)OperandType.Type, (byte)OperandType.None, (byte)OperandType.None, 255, (byte)OperandType.None, 255, (byte)OperandType.Type, (byte)OperandType.None, (byte)OperandType.None, };\n\n\t\tstatic readonly string[] operandNames = { \"nop\", \"break\", \"ldarg.0\", \"ldarg.1\", \"ldarg.2\", \"ldarg.3\", \"ldloc.0\", \"ldloc.1\", \"ldloc.2\", \"ldloc.3\", \"stloc.0\", \"stloc.1\", \"stloc.2\", \"stloc.3\", \"ldarg.s\", \"ldarga.s\", \"starg.s\", \"ldloc.s\", \"ldloca.s\", \"stloc.s\", \"ldnull\", \"ldc.i4.m1\", \"ldc.i4.0\", \"ldc.i4.1\", \"ldc.i4.2\", \"ldc.i4.3\", \"ldc.i4.4\", \"ldc.i4.5\", \"ldc.i4.6\", \"ldc.i4.7\", \"ldc.i4.8\", \"ldc.i4.s\", \"ldc.i4\", \"ldc.i8\", \"ldc.r4\", \"ldc.r8\", \"\", \"dup\", \"pop\", \"jmp\", \"call\", \"calli\", \"ret\", \"br.s\", \"brfalse.s\", \"brtrue.s\", \"beq.s\", \"bge.s\", \"bgt.s\", \"ble.s\", \"blt.s\", \"bne.un.s\", \"bge.un.s\", \"bgt.un.s\", \"ble.un.s\", \"blt.un.s\", \"br\", \"brfalse\", \"brtrue\", \"beq\", \"bge\", \"bgt\", \"ble\", \"blt\", \"bne.un\", \"bge.un\", \"bgt.un\", \"ble.un\", \"blt.un\", \"switch\", \"ldind.i1\", \"ldind.u1\", \"ldind.i2\", \"ldind.u2\", \"ldind.i4\", \"ldind.u4\", \"ldind.i8\", \"ldind.i\", \"ldind.r4\", \"ldind.r8\", \"ldind.ref\", \"stind.ref\", \"stind.i1\", \"stind.i2\", \"stind.i4\", \"stind.i8\", \"stind.r4\", \"stind.r8\", \"add\", \"sub\", \"mul\", \"div\", \"div.un\", \"rem\", \"rem.un\", \"and\", \"or\", \"xor\", \"shl\", \"shr\", \"shr.un\", \"neg\", \"not\", \"conv.i1\", \"conv.i2\", \"conv.i4\", \"conv.i8\", \"conv.r4\", \"conv.r8\", \"conv.u4\", \"conv.u8\", \"callvirt\", \"cpobj\", \"ldobj\", \"ldstr\", \"newobj\", \"castclass\", \"isinst\", \"conv.r.un\", \"\", \"\", \"unbox\", \"throw\", \"ldfld\", \"ldflda\", \"stfld\", \"ldsfld\", \"ldsflda\", \"stsfld\", \"stobj\", \"conv.ovf.i1.un\", \"conv.ovf.i2.un\", \"conv.ovf.i4.un\", \"conv.ovf.i8.un\", \"conv.ovf.u1.un\", \"conv.ovf.u2.un\", \"conv.ovf.u4.un\", \"conv.ovf.u8.un\", \"conv.ovf.i.un\", \"conv.ovf.u.un\", \"box\", \"newarr\", \"ldlen\", \"ldelema\", \"ldelem.i1\", \"ldelem.u1\", \"ldelem.i2\", \"ldelem.u2\", \"ldelem.i4\", \"ldelem.u4\", \"ldelem.i8\", \"ldelem.i\", \"ldelem.r4\", \"ldelem.r8\", \"ldelem.ref\", \"stelem.i\", \"stelem.i1\", \"stelem.i2\", \"stelem.i4\", \"stelem.i8\", \"stelem.r4\", \"stelem.r8\", \"stelem.ref\", \"ldelem\", \"stelem\", \"unbox.any\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"conv.ovf.i1\", \"conv.ovf.u1\", \"conv.ovf.i2\", \"conv.ovf.u2\", \"conv.ovf.i4\", \"conv.ovf.u4\", \"conv.ovf.i8\", \"conv.ovf.u8\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"refanyval\", \"ckfinite\", \"\", \"\", \"mkrefany\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"ldtoken\", \"conv.u2\", \"conv.u1\", \"conv.i\", \"conv.ovf.i\", \"conv.ovf.u\", \"add.ovf\", \"add.ovf.un\", \"mul.ovf\", \"mul.ovf.un\", \"sub.ovf\", \"sub.ovf.un\", \"endfinally\", \"leave\", \"leave.s\", \"stind.i\", \"conv.u\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"prefix7\", \"prefix6\", \"prefix5\", \"prefix4\", \"prefix3\", \"prefix2\", \"prefix1\", \"prefixref\", \"arglist\", \"ceq\", \"cgt\", \"cgt.un\", \"clt\", \"clt.un\", \"ldftn\", \"ldvirtftn\", \"\", \"ldarg\", \"ldarga\", \"starg\", \"ldloc\", \"ldloca\", \"stloc\", \"localloc\", \"\", \"endfilter\", \"unaligned.\", \"volatile.\", \"tail.\", \"initobj\", \"constrained.\", \"cpblk\", \"initblk\", \"\", \"rethrow\", \"\", \"sizeof\", \"refanytype\", \"readonly.\", };\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/ILOpCodes.tt",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n<#@ template debug=\"false\" hostspecific=\"false\" language=\"C#\" #>\n<#@ assembly name=\"System.Core\" #>\n<#@ import namespace=\"System.Linq\" #>\n<#@ import namespace=\"System.Text\" #>\n<#@ import namespace=\"System.Collections.Generic\" #>\n<#@ import namespace=\"System.Reflection.Metadata\" #>\n<#@ import namespace=\"System.Reflection.Emit\" #>\n<#@ output extension=\".cs\" #>\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\n<#\n\tvar operandTypes = Enumerable.Repeat((OperandType)0xff, 0x11f).ToArray();\n\tvar operandNames = new string[0x11f];\n#>\nnamespace ICSharpCode.Decompiler.Metadata\n{\n<#\n\tforeach (var field in typeof(OpCodes).GetFields()) {\n\t\tvar opCode = (OpCode)field.GetValue(null);\n\t\tushort index = (ushort)(((opCode.Value & 0x200) >> 1) | (opCode.Value & 0xff));\n\t\toperandTypes[index] = opCode.OperandType;\n\t\toperandNames[index] = opCode.Name;\n\t} #>\n\n\tstatic partial class ILOpCodeExtensions\n\t{\n\t\t// We use a byte array instead of an enum array because it can be initialized more efficiently\n\t\tstatic readonly byte[] operandTypes = { <#\n\t\t\tforeach (var operandType in operandTypes) {\n\t\t\t\tif ((byte)operandType == 255) {\n\t\t\t\t\tWrite(\"255, \");\n\t\t\t\t} else {\n\t\t\t\t\tstring operandTypeName = operandType.ToString().Replace(\"Inline\", \"\").Replace(\"Var\", \"Variable\");\n\t\t\t\t\tWrite(\"(byte)OperandType.\" + operandTypeName + \", \");\n\t\t\t\t}\n\t\t\t}\n\t\t#> };\n\n\t\tstatic readonly string[] operandNames = { <#\n\t\t\tforeach (var operandName in operandNames) {\n\t\t\t\tWrite(\"\\\"\" + operandName + \"\\\", \");\n\t\t\t}\n\t\t#> };\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/LightJson/JsonArray.cs",
    "content": "// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nnamespace LightJson\n{\n\tusing System;\n\tusing System.Collections.Generic;\n\tusing System.Diagnostics;\n\tusing System.Diagnostics.CodeAnalysis;\n\n\t/// <summary>\n\t/// Represents an ordered collection of JsonValues.\n\t/// </summary>\n\t[DebuggerDisplay(\"Count = {Count}\")]\n\t[DebuggerTypeProxy(typeof(JsonArrayDebugView))]\n\tinternal sealed class JsonArray : IEnumerable<JsonValue>\n\t{\n\t\tprivate IList<JsonValue> items;\n\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"JsonArray\"/> class.\n\t\t/// </summary>\n\t\tpublic JsonArray()\n\t\t{\n\t\t\tthis.items = new List<JsonValue>();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"JsonArray\"/> class, adding the given values to the collection.\n\t\t/// </summary>\n\t\t/// <param name=\"values\">The values to be added to this collection.</param>\n\t\tpublic JsonArray(params JsonValue[] values)\n\t\t\t: this()\n\t\t{\n\t\t\tif (values == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(values));\n\t\t\t}\n\n\t\t\tforeach (var value in values)\n\t\t\t{\n\t\t\t\tthis.items.Add(value);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the number of values in this collection.\n\t\t/// </summary>\n\t\t/// <value>The number of values in this collection.</value>\n\t\tpublic int Count {\n\t\t\tget {\n\t\t\t\treturn this.items.Count;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets or sets the value at the given index.\n\t\t/// </summary>\n\t\t/// <param name=\"index\">The zero-based index of the value to get or set.</param>\n\t\t/// <remarks>\n\t\t/// The getter will return JsonValue.Null if the given index is out of range.\n\t\t/// </remarks>\n\t\tpublic JsonValue this[int index] {\n\t\t\tget {\n\t\t\t\tif (index >= 0 && index < this.items.Count)\n\t\t\t\t{\n\t\t\t\t\treturn this.items[index];\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn JsonValue.Null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tset {\n\t\t\t\tthis.items[index] = value;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Adds the given value to this collection.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to be added.</param>\n\t\t/// <returns>Returns this collection.</returns>\n\t\tpublic JsonArray Add(JsonValue value)\n\t\t{\n\t\t\tthis.items.Add(value);\n\t\t\treturn this;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Inserts the given value at the given index in this collection.\n\t\t/// </summary>\n\t\t/// <param name=\"index\">The index where the given value will be inserted.</param>\n\t\t/// <param name=\"value\">The value to be inserted into this collection.</param>\n\t\t/// <returns>Returns this collection.</returns>\n\t\tpublic JsonArray Insert(int index, JsonValue value)\n\t\t{\n\t\t\tthis.items.Insert(index, value);\n\t\t\treturn this;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Removes the value at the given index.\n\t\t/// </summary>\n\t\t/// <param name=\"index\">The index of the value to be removed.</param>\n\t\t/// <returns>Return this collection.</returns>\n\t\tpublic JsonArray Remove(int index)\n\t\t{\n\t\t\tthis.items.RemoveAt(index);\n\t\t\treturn this;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Clears the contents of this collection.\n\t\t/// </summary>\n\t\t/// <returns>Returns this collection.</returns>\n\t\tpublic JsonArray Clear()\n\t\t{\n\t\t\tthis.items.Clear();\n\t\t\treturn this;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Determines whether the given item is in the JsonArray.\n\t\t/// </summary>\n\t\t/// <param name=\"item\">The item to locate in the JsonArray.</param>\n\t\t/// <returns>Returns true if the item is found; otherwise, false.</returns>\n\t\tpublic bool Contains(JsonValue item)\n\t\t{\n\t\t\treturn this.items.Contains(item);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Determines the index of the given item in this JsonArray.\n\t\t/// </summary>\n\t\t/// <param name=\"item\">The item to locate in this JsonArray.</param>\n\t\t/// <returns>The index of the item, if found. Otherwise, returns -1.</returns>\n\t\tpublic int IndexOf(JsonValue item)\n\t\t{\n\t\t\treturn this.items.IndexOf(item);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns an enumerator that iterates through the collection.\n\t\t/// </summary>\n\t\t/// <returns>The enumerator that iterates through the collection.</returns>\n\t\tpublic IEnumerator<JsonValue> GetEnumerator()\n\t\t{\n\t\t\treturn this.items.GetEnumerator();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns an enumerator that iterates through the collection.\n\t\t/// </summary>\n\t\t/// <returns>The enumerator that iterates through the collection.</returns>\n\t\tSystem.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\n\t\t{\n\t\t\treturn this.GetEnumerator();\n\t\t}\n\n\t\t[ExcludeFromCodeCoverage]\n\t\tprivate class JsonArrayDebugView\n\t\t{\n\t\t\tprivate JsonArray jsonArray;\n\n\t\t\tpublic JsonArrayDebugView(JsonArray jsonArray)\n\t\t\t{\n\t\t\t\tthis.jsonArray = jsonArray;\n\t\t\t}\n\n\t\t\t[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]\n\t\t\tpublic JsonValue[] Items {\n\t\t\t\tget {\n\t\t\t\t\tvar items = new JsonValue[this.jsonArray.Count];\n\n\t\t\t\t\tfor (int i = 0; i < this.jsonArray.Count; i += 1)\n\t\t\t\t\t{\n\t\t\t\t\t\titems[i] = this.jsonArray[i];\n\t\t\t\t\t}\n\n\t\t\t\t\treturn items;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/LightJson/JsonObject.cs",
    "content": "// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nnamespace LightJson\n{\n\tusing System.Collections.Generic;\n\tusing System.Diagnostics;\n\tusing System.Diagnostics.CodeAnalysis;\n\n\t/// <summary>\n\t/// Represents a key-value pair collection of JsonValue objects.\n\t/// </summary>\n\t[DebuggerDisplay(\"Count = {Count}\")]\n\t[DebuggerTypeProxy(typeof(JsonObjectDebugView))]\n\tinternal sealed class JsonObject : IEnumerable<KeyValuePair<string, JsonValue>>, IEnumerable<JsonValue>\n\t{\n\t\tprivate IDictionary<string, JsonValue> properties;\n\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"JsonObject\"/> class.\n\t\t/// </summary>\n\t\tpublic JsonObject()\n\t\t{\n\t\t\tthis.properties = new Dictionary<string, JsonValue>();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the number of properties in this JsonObject.\n\t\t/// </summary>\n\t\t/// <value>The number of properties in this JsonObject.</value>\n\t\tpublic int Count {\n\t\t\tget {\n\t\t\t\treturn this.properties.Count;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets or sets the property with the given key.\n\t\t/// </summary>\n\t\t/// <param name=\"key\">The key of the property to get or set.</param>\n\t\t/// <remarks>\n\t\t/// The getter will return JsonValue.Null if the given key is not associated with any value.\n\t\t/// </remarks>\n\t\tpublic JsonValue this[string key] {\n\t\t\tget {\n\t\t\t\tJsonValue value;\n\n\t\t\t\tif (this.properties.TryGetValue(key, out value))\n\t\t\t\t{\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn JsonValue.Null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tset {\n\t\t\t\tthis.properties[key] = value;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Adds a key with a null value to this collection.\n\t\t/// </summary>\n\t\t/// <param name=\"key\">The key of the property to be added.</param>\n\t\t/// <remarks>Returns this JsonObject.</remarks>\n\t\t/// <returns>The <see cref=\"JsonObject\"/> that was added.</returns>\n\t\tpublic JsonObject Add(string key)\n\t\t{\n\t\t\treturn this.Add(key, JsonValue.Null);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Adds a value associated with a key to this collection.\n\t\t/// </summary>\n\t\t/// <param name=\"key\">The key of the property to be added.</param>\n\t\t/// <param name=\"value\">The value of the property to be added.</param>\n\t\t/// <returns>Returns this JsonObject.</returns>\n\t\tpublic JsonObject Add(string key, JsonValue value)\n\t\t{\n\t\t\tthis.properties.Add(key, value);\n\t\t\treturn this;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Removes a property with the given key.\n\t\t/// </summary>\n\t\t/// <param name=\"key\">The key of the property to be removed.</param>\n\t\t/// <returns>\n\t\t/// Returns true if the given key is found and removed; otherwise, false.\n\t\t/// </returns>\n\t\tpublic bool Remove(string key)\n\t\t{\n\t\t\treturn this.properties.Remove(key);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Clears the contents of this collection.\n\t\t/// </summary>\n\t\t/// <returns>Returns this JsonObject.</returns>\n\t\tpublic JsonObject Clear()\n\t\t{\n\t\t\tthis.properties.Clear();\n\t\t\treturn this;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Changes the key of one of the items in the collection.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This method has no effects if the <i>oldKey</i> does not exists.\n\t\t/// If the <i>newKey</i> already exists, the value will be overwritten.\n\t\t/// </remarks>\n\t\t/// <param name=\"oldKey\">The name of the key to be changed.</param>\n\t\t/// <param name=\"newKey\">The new name of the key.</param>\n\t\t/// <returns>Returns this JsonObject.</returns>\n\t\tpublic JsonObject Rename(string oldKey, string newKey)\n\t\t{\n\t\t\tif (oldKey == newKey)\n\t\t\t{\n\t\t\t\t// Renaming to the same name just does nothing\n\t\t\t\treturn this;\n\t\t\t}\n\n\t\t\tJsonValue value;\n\n\t\t\tif (this.properties.TryGetValue(oldKey, out value))\n\t\t\t{\n\t\t\t\tthis[newKey] = value;\n\t\t\t\tthis.Remove(oldKey);\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Determines whether this collection contains an item assosiated with the given key.\n\t\t/// </summary>\n\t\t/// <param name=\"key\">The key to locate in this collection.</param>\n\t\t/// <returns>Returns true if the key is found; otherwise, false.</returns>\n\t\tpublic bool ContainsKey(string key)\n\t\t{\n\t\t\treturn this.properties.ContainsKey(key);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Determines whether this collection contains the given JsonValue.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to locate in this collection.</param>\n\t\t/// <returns>Returns true if the value is found; otherwise, false.</returns>\n\t\tpublic bool Contains(JsonValue value)\n\t\t{\n\t\t\treturn this.properties.Values.Contains(value);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns an enumerator that iterates through this collection.\n\t\t/// </summary>\n\t\t/// <returns>The enumerator that iterates through this collection.</returns>\n\t\tpublic IEnumerator<KeyValuePair<string, JsonValue>> GetEnumerator()\n\t\t{\n\t\t\treturn this.properties.GetEnumerator();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns an enumerator that iterates through this collection.\n\t\t/// </summary>\n\t\t/// <returns>The enumerator that iterates through this collection.</returns>\n\t\tIEnumerator<JsonValue> IEnumerable<JsonValue>.GetEnumerator()\n\t\t{\n\t\t\treturn this.properties.Values.GetEnumerator();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns an enumerator that iterates through this collection.\n\t\t/// </summary>\n\t\t/// <returns>The enumerator that iterates through this collection.</returns>\n\t\tSystem.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\n\t\t{\n\t\t\treturn this.GetEnumerator();\n\t\t}\n\n\t\t[ExcludeFromCodeCoverage]\n\t\tprivate class JsonObjectDebugView\n\t\t{\n\t\t\tprivate JsonObject jsonObject;\n\n\t\t\tpublic JsonObjectDebugView(JsonObject jsonObject)\n\t\t\t{\n\t\t\t\tthis.jsonObject = jsonObject;\n\t\t\t}\n\n\t\t\t[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]\n\t\t\tpublic KeyValuePair[] Keys {\n\t\t\t\tget {\n\t\t\t\t\tvar keys = new KeyValuePair[this.jsonObject.Count];\n\n\t\t\t\t\tvar i = 0;\n\t\t\t\t\tforeach (var property in this.jsonObject)\n\t\t\t\t\t{\n\t\t\t\t\t\tkeys[i] = new KeyValuePair(property.Key, property.Value);\n\t\t\t\t\t\ti += 1;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn keys;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t[DebuggerDisplay(\"{value.ToString(),nq}\", Name = \"{key}\", Type = \"JsonValue({Type})\")]\n\t\t\tpublic class KeyValuePair\n\t\t\t{\n\t\t\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\t\t\tprivate string key;\n\n\t\t\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\t\t\tprivate JsonValue value;\n\n\t\t\t\tpublic KeyValuePair(string key, JsonValue value)\n\t\t\t\t{\n\t\t\t\t\tthis.key = key;\n\t\t\t\t\tthis.value = value;\n\t\t\t\t}\n\n\t\t\t\t[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]\n\t\t\t\tpublic object View {\n\t\t\t\t\tget {\n\t\t\t\t\t\tif (this.value.IsJsonObject)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn (JsonObject)this.value;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (this.value.IsJsonArray)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn (JsonArray)this.value;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn this.value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\t\t\tprivate JsonValueType Type {\n\t\t\t\t\tget {\n\t\t\t\t\t\treturn this.value.Type;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/LightJson/JsonValue.cs",
    "content": "// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nnamespace LightJson\n{\n\tusing System;\n\tusing System.Collections.Generic;\n\tusing System.Diagnostics;\n\tusing System.Diagnostics.CodeAnalysis;\n\tusing System.Globalization;\n\n\tusing LightJson.Serialization;\n\n\t/// <summary>\n\t/// A wrapper object that contains a valid JSON value.\n\t/// </summary>\n\t[DebuggerDisplay(\"{ToString(),nq}\", Type = \"JsonValue({Type})\")]\n\t[DebuggerTypeProxy(typeof(JsonValueDebugView))]\n\tinternal struct JsonValue\n\t{\n\t\t/// <summary>\n\t\t/// Represents a null JsonValue.\n\t\t/// </summary>\n\t\tpublic static readonly JsonValue Null = new JsonValue(JsonValueType.Null, default(double), null);\n\n\t\tprivate readonly JsonValueType type;\n\t\tprivate readonly object reference;\n\t\tprivate readonly double value;\n\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"JsonValue\"/> struct, representing a Boolean value.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to be wrapped.</param>\n\t\tpublic JsonValue(bool? value)\n\t\t{\n\t\t\tif (value.HasValue)\n\t\t\t{\n\t\t\t\tthis.reference = null;\n\n\t\t\t\tthis.type = JsonValueType.Boolean;\n\n\t\t\t\tthis.value = value.Value ? 1 : 0;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis = JsonValue.Null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"JsonValue\"/> struct, representing a Number value.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to be wrapped.</param>\n\t\tpublic JsonValue(double? value)\n\t\t{\n\t\t\tif (value.HasValue)\n\t\t\t{\n\t\t\t\tthis.reference = null;\n\n\t\t\t\tthis.type = JsonValueType.Number;\n\n\t\t\t\tthis.value = value.Value;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis = JsonValue.Null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"JsonValue\"/> struct, representing a String value.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to be wrapped.</param>\n\t\tpublic JsonValue(string value)\n\t\t{\n\t\t\tif (value != null)\n\t\t\t{\n\t\t\t\tthis.value = default(double);\n\n\t\t\t\tthis.type = JsonValueType.String;\n\n\t\t\t\tthis.reference = value;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis = JsonValue.Null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"JsonValue\"/> struct, representing a JsonObject.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to be wrapped.</param>\n\t\tpublic JsonValue(JsonObject value)\n\t\t{\n\t\t\tif (value != null)\n\t\t\t{\n\t\t\t\tthis.value = default(double);\n\n\t\t\t\tthis.type = JsonValueType.Object;\n\n\t\t\t\tthis.reference = value;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis = JsonValue.Null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"JsonValue\"/> struct, representing a Array reference value.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to be wrapped.</param>\n\t\tpublic JsonValue(JsonArray value)\n\t\t{\n\t\t\tif (value != null)\n\t\t\t{\n\t\t\t\tthis.value = default(double);\n\n\t\t\t\tthis.type = JsonValueType.Array;\n\n\t\t\t\tthis.reference = value;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis = JsonValue.Null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"JsonValue\"/> struct.\n\t\t/// </summary>\n\t\t/// <param name=\"type\">The Json type of the JsonValue.</param>\n\t\t/// <param name=\"value\">\n\t\t/// The internal value of the JsonValue.\n\t\t/// This is used when the Json type is Number or Boolean.\n\t\t/// </param>\n\t\t/// <param name=\"reference\">\n\t\t/// The internal value reference of the JsonValue.\n\t\t/// This value is used when the Json type is String, JsonObject, or JsonArray.\n\t\t/// </param>\n\t\tprivate JsonValue(JsonValueType type, double value, object reference)\n\t\t{\n\t\t\tthis.type = type;\n\t\t\tthis.value = value;\n\t\t\tthis.reference = reference;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the type of this JsonValue.\n\t\t/// </summary>\n\t\t/// <value>The type of this JsonValue.</value>\n\t\tpublic JsonValueType Type {\n\t\t\tget {\n\t\t\t\treturn this.type;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a value indicating whether this JsonValue is Null.\n\t\t/// </summary>\n\t\t/// <value>A value indicating whether this JsonValue is Null.</value>\n\t\tpublic bool IsNull {\n\t\t\tget {\n\t\t\t\treturn this.Type == JsonValueType.Null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a value indicating whether this JsonValue is a Boolean.\n\t\t/// </summary>\n\t\t/// <value>A value indicating whether this JsonValue is a Boolean.</value>\n\t\tpublic bool IsBoolean {\n\t\t\tget {\n\t\t\t\treturn this.Type == JsonValueType.Boolean;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a value indicating whether this JsonValue is an Integer.\n\t\t/// </summary>\n\t\t/// <value>A value indicating whether this JsonValue is an Integer.</value>\n\t\tpublic bool IsInteger {\n\t\t\tget {\n\t\t\t\tif (!this.IsNumber)\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tvar value = this.value;\n\t\t\t\treturn unchecked((int)value) == value;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a value indicating whether this JsonValue is a Number.\n\t\t/// </summary>\n\t\t/// <value>A value indicating whether this JsonValue is a Number.</value>\n\t\tpublic bool IsNumber {\n\t\t\tget {\n\t\t\t\treturn this.Type == JsonValueType.Number;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a value indicating whether this JsonValue is a String.\n\t\t/// </summary>\n\t\t/// <value>A value indicating whether this JsonValue is a String.</value>\n\t\tpublic bool IsString {\n\t\t\tget {\n\t\t\t\treturn this.Type == JsonValueType.String;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a value indicating whether this JsonValue is a JsonObject.\n\t\t/// </summary>\n\t\t/// <value>A value indicating whether this JsonValue is a JsonObject.</value>\n\t\tpublic bool IsJsonObject {\n\t\t\tget {\n\t\t\t\treturn this.Type == JsonValueType.Object;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a value indicating whether this JsonValue is a JsonArray.\n\t\t/// </summary>\n\t\t/// <value>A value indicating whether this JsonValue is a JsonArray.</value>\n\t\tpublic bool IsJsonArray {\n\t\t\tget {\n\t\t\t\treturn this.Type == JsonValueType.Array;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a value indicating whether this JsonValue represents a DateTime.\n\t\t/// </summary>\n\t\t/// <value>A value indicating whether this JsonValue represents a DateTime.</value>\n\t\tpublic bool IsDateTime {\n\t\t\tget {\n\t\t\t\treturn this.AsDateTime != null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a value indicating whether this value is true or false.\n\t\t/// </summary>\n\t\t/// <value>This value as a Boolean type.</value>\n\t\tpublic bool AsBoolean {\n\t\t\tget {\n\t\t\t\tswitch (this.Type)\n\t\t\t\t{\n\t\t\t\t\tcase JsonValueType.Boolean:\n\t\t\t\t\t\treturn this.value == 1;\n\n\t\t\t\t\tcase JsonValueType.Number:\n\t\t\t\t\t\treturn this.value != 0;\n\n\t\t\t\t\tcase JsonValueType.String:\n\t\t\t\t\t\treturn (string)this.reference != string.Empty;\n\n\t\t\t\t\tcase JsonValueType.Object:\n\t\t\t\t\tcase JsonValueType.Array:\n\t\t\t\t\t\treturn true;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets this value as an Integer type.\n\t\t/// </summary>\n\t\t/// <value>This value as an Integer type.</value>\n\t\tpublic int AsInteger {\n\t\t\tget {\n\t\t\t\tvar value = this.AsNumber;\n\n\t\t\t\t// Prevent overflow if the value doesn't fit.\n\t\t\t\tif (value >= int.MaxValue)\n\t\t\t\t{\n\t\t\t\t\treturn int.MaxValue;\n\t\t\t\t}\n\n\t\t\t\tif (value <= int.MinValue)\n\t\t\t\t{\n\t\t\t\t\treturn int.MinValue;\n\t\t\t\t}\n\n\t\t\t\treturn (int)value;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets this value as a Number type.\n\t\t/// </summary>\n\t\t/// <value>This value as a Number type.</value>\n\t\tpublic double AsNumber {\n\t\t\tget {\n\t\t\t\tswitch (this.Type)\n\t\t\t\t{\n\t\t\t\t\tcase JsonValueType.Boolean:\n\t\t\t\t\t\treturn (this.value == 1)\n\t\t\t\t\t\t\t? 1\n\t\t\t\t\t\t\t: 0;\n\n\t\t\t\t\tcase JsonValueType.Number:\n\t\t\t\t\t\treturn this.value;\n\n\t\t\t\t\tcase JsonValueType.String:\n\t\t\t\t\t\tdouble number;\n\t\t\t\t\t\tif (double.TryParse((string)this.reference, NumberStyles.Float, CultureInfo.InvariantCulture, out number))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn number;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tgoto default;\n\t\t\t\t\t\t}\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets this value as a String type.\n\t\t/// </summary>\n\t\t/// <value>This value as a String type.</value>\n\t\tpublic string AsString {\n\t\t\tget {\n\t\t\t\tswitch (this.Type)\n\t\t\t\t{\n\t\t\t\t\tcase JsonValueType.Boolean:\n\t\t\t\t\t\treturn (this.value == 1)\n\t\t\t\t\t\t\t? \"true\"\n\t\t\t\t\t\t\t: \"false\";\n\n\t\t\t\t\tcase JsonValueType.Number:\n\t\t\t\t\t\treturn this.value.ToString(CultureInfo.InvariantCulture);\n\n\t\t\t\t\tcase JsonValueType.String:\n\t\t\t\t\t\treturn (string)this.reference;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets this value as an JsonObject.\n\t\t/// </summary>\n\t\t/// <value>This value as an JsonObject.</value>\n\t\tpublic JsonObject AsJsonObject {\n\t\t\tget {\n\t\t\t\treturn this.IsJsonObject\n\t\t\t\t\t? (JsonObject)this.reference\n\t\t\t\t\t: null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets this value as an JsonArray.\n\t\t/// </summary>\n\t\t/// <value>This value as an JsonArray.</value>\n\t\tpublic JsonArray AsJsonArray {\n\t\t\tget {\n\t\t\t\treturn this.IsJsonArray\n\t\t\t\t\t? (JsonArray)this.reference\n\t\t\t\t\t: null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets this value as a system.DateTime.\n\t\t/// </summary>\n\t\t/// <value>This value as a system.DateTime.</value>\n\t\tpublic DateTime? AsDateTime {\n\t\t\tget {\n\t\t\t\tDateTime value;\n\n\t\t\t\tif (this.IsString && DateTime.TryParse((string)this.reference, out value))\n\t\t\t\t{\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets this (inner) value as a System.object.\n\t\t/// </summary>\n\t\t/// <value>This (inner) value as a System.object.</value>\n\t\tpublic object AsObject {\n\t\t\tget {\n\t\t\t\tswitch (this.Type)\n\t\t\t\t{\n\t\t\t\t\tcase JsonValueType.Boolean:\n\t\t\t\t\tcase JsonValueType.Number:\n\t\t\t\t\t\treturn this.value;\n\n\t\t\t\t\tcase JsonValueType.String:\n\t\t\t\t\tcase JsonValueType.Object:\n\t\t\t\t\tcase JsonValueType.Array:\n\t\t\t\t\t\treturn this.reference;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets or sets the value associated with the specified key.\n\t\t/// </summary>\n\t\t/// <param name=\"key\">The key of the value to get or set.</param>\n\t\t/// <exception cref=\"System.InvalidOperationException\">\n\t\t/// Thrown when this JsonValue is not a JsonObject.\n\t\t/// </exception>\n\t\tpublic JsonValue this[string key] {\n\t\t\tget {\n\t\t\t\tif (this.IsJsonObject)\n\t\t\t\t{\n\t\t\t\t\treturn ((JsonObject)this.reference)[key];\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthrow new InvalidOperationException(\"This value does not represent a JsonObject.\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tset {\n\t\t\t\tif (this.IsJsonObject)\n\t\t\t\t{\n\t\t\t\t\t((JsonObject)this.reference)[key] = value;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthrow new InvalidOperationException(\"This value does not represent a JsonObject.\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets or sets the value at the specified index.\n\t\t/// </summary>\n\t\t/// <param name=\"index\">The zero-based index of the value to get or set.</param>\n\t\t/// <exception cref=\"System.InvalidOperationException\">\n\t\t/// Thrown when this JsonValue is not a JsonArray\n\t\t/// </exception>\n\t\tpublic JsonValue this[int index] {\n\t\t\tget {\n\t\t\t\tif (this.IsJsonArray)\n\t\t\t\t{\n\t\t\t\t\treturn ((JsonArray)this.reference)[index];\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthrow new InvalidOperationException(\"This value does not represent a JsonArray.\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tset {\n\t\t\t\tif (this.IsJsonArray)\n\t\t\t\t{\n\t\t\t\t\t((JsonArray)this.reference)[index] = value;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthrow new InvalidOperationException(\"This value does not represent a JsonArray.\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the given nullable boolean into a JsonValue.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to be converted.</param>\n\t\tpublic static implicit operator JsonValue(bool? value)\n\t\t{\n\t\t\treturn new JsonValue(value);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the given nullable double into a JsonValue.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to be converted.</param>\n\t\tpublic static implicit operator JsonValue(double? value)\n\t\t{\n\t\t\treturn new JsonValue(value);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the given string into a JsonValue.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to be converted.</param>\n\t\tpublic static implicit operator JsonValue(string value)\n\t\t{\n\t\t\treturn new JsonValue(value);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the given JsonObject into a JsonValue.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to be converted.</param>\n\t\tpublic static implicit operator JsonValue(JsonObject value)\n\t\t{\n\t\t\treturn new JsonValue(value);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the given JsonArray into a JsonValue.\n\t\t/// </summary>\n\t\t/// <param name=\"value\">The value to be converted.</param>\n\t\tpublic static implicit operator JsonValue(JsonArray value)\n\t\t{\n\t\t\treturn new JsonValue(value);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the given DateTime? into a JsonValue.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// The DateTime value will be stored as a string using ISO 8601 format,\n\t\t/// since JSON does not define a DateTime type.\n\t\t/// </remarks>\n\t\t/// <param name=\"value\">The value to be converted.</param>\n\t\tpublic static implicit operator JsonValue(DateTime? value)\n\t\t{\n\t\t\tif (value == null)\n\t\t\t{\n\t\t\t\treturn JsonValue.Null;\n\t\t\t}\n\n\t\t\treturn new JsonValue(value.Value.ToString(\"o\"));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the given JsonValue into an Int.\n\t\t/// </summary>\n\t\t/// <param name=\"jsonValue\">The JsonValue to be converted.</param>\n\t\tpublic static explicit operator int(JsonValue jsonValue)\n\t\t{\n\t\t\tif (jsonValue.IsInteger)\n\t\t\t{\n\t\t\t\treturn jsonValue.AsInteger;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the given JsonValue into a nullable Int.\n\t\t/// </summary>\n\t\t/// <param name=\"jsonValue\">The JsonValue to be converted.</param>\n\t\t/// <exception cref=\"System.InvalidCastException\">\n\t\t/// Throws System.InvalidCastException when the inner value type of the\n\t\t/// JsonValue is not the desired type of the conversion.\n\t\t/// </exception>\n\t\tpublic static explicit operator int?(JsonValue jsonValue)\n\t\t{\n\t\t\tif (jsonValue.IsNull)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn (int)jsonValue;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the given JsonValue into a Bool.\n\t\t/// </summary>\n\t\t/// <param name=\"jsonValue\">The JsonValue to be converted.</param>\n\t\tpublic static explicit operator bool(JsonValue jsonValue)\n\t\t{\n\t\t\tif (jsonValue.IsBoolean)\n\t\t\t{\n\t\t\t\treturn jsonValue.value == 1;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the given JsonValue into a nullable Bool.\n\t\t/// </summary>\n\t\t/// <param name=\"jsonValue\">The JsonValue to be converted.</param>\n\t\t/// <exception cref=\"System.InvalidCastException\">\n\t\t/// Throws System.InvalidCastException when the inner value type of the\n\t\t/// JsonValue is not the desired type of the conversion.\n\t\t/// </exception>\n\t\tpublic static explicit operator bool?(JsonValue jsonValue)\n\t\t{\n\t\t\tif (jsonValue.IsNull)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn (bool)jsonValue;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the given JsonValue into a Double.\n\t\t/// </summary>\n\t\t/// <param name=\"jsonValue\">The JsonValue to be converted.</param>\n\t\tpublic static explicit operator double(JsonValue jsonValue)\n\t\t{\n\t\t\tif (jsonValue.IsNumber)\n\t\t\t{\n\t\t\t\treturn jsonValue.value;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn double.NaN;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the given JsonValue into a nullable Double.\n\t\t/// </summary>\n\t\t/// <param name=\"jsonValue\">The JsonValue to be converted.</param>\n\t\t/// <exception cref=\"System.InvalidCastException\">\n\t\t/// Throws System.InvalidCastException when the inner value type of the\n\t\t/// JsonValue is not the desired type of the conversion.\n\t\t/// </exception>\n\t\tpublic static explicit operator double?(JsonValue jsonValue)\n\t\t{\n\t\t\tif (jsonValue.IsNull)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn (double)jsonValue;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the given JsonValue into a String.\n\t\t/// </summary>\n\t\t/// <param name=\"jsonValue\">The JsonValue to be converted.</param>\n\t\tpublic static explicit operator string(JsonValue jsonValue)\n\t\t{\n\t\t\tif (jsonValue.IsString || jsonValue.IsNull)\n\t\t\t{\n\t\t\t\treturn jsonValue.reference as string;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the given JsonValue into a JsonObject.\n\t\t/// </summary>\n\t\t/// <param name=\"jsonValue\">The JsonValue to be converted.</param>\n\t\tpublic static explicit operator JsonObject(JsonValue jsonValue)\n\t\t{\n\t\t\tif (jsonValue.IsJsonObject || jsonValue.IsNull)\n\t\t\t{\n\t\t\t\treturn jsonValue.reference as JsonObject;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the given JsonValue into a JsonArray.\n\t\t/// </summary>\n\t\t/// <param name=\"jsonValue\">The JsonValue to be converted.</param>\n\t\tpublic static explicit operator JsonArray(JsonValue jsonValue)\n\t\t{\n\t\t\tif (jsonValue.IsJsonArray || jsonValue.IsNull)\n\t\t\t{\n\t\t\t\treturn jsonValue.reference as JsonArray;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the given JsonValue into a DateTime.\n\t\t/// </summary>\n\t\t/// <param name=\"jsonValue\">The JsonValue to be converted.</param>\n\t\tpublic static explicit operator DateTime(JsonValue jsonValue)\n\t\t{\n\t\t\tvar dateTime = jsonValue.AsDateTime;\n\n\t\t\tif (dateTime.HasValue)\n\t\t\t{\n\t\t\t\treturn dateTime.Value;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn DateTime.MinValue;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts the given JsonValue into a nullable DateTime.\n\t\t/// </summary>\n\t\t/// <param name=\"jsonValue\">The JsonValue to be converted.</param>\n\t\tpublic static explicit operator DateTime?(JsonValue jsonValue)\n\t\t{\n\t\t\tif (jsonValue.IsDateTime || jsonValue.IsNull)\n\t\t\t{\n\t\t\t\treturn jsonValue.AsDateTime;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns a value indicating whether the two given JsonValues are equal.\n\t\t/// </summary>\n\t\t/// <param name=\"a\">First JsonValue to compare.</param>\n\t\t/// <param name=\"b\">Second JsonValue to compare.</param>\n\t\tpublic static bool operator ==(JsonValue a, JsonValue b)\n\t\t{\n\t\t\treturn (a.Type == b.Type)\n\t\t\t\t&& (a.value == b.value)\n\t\t\t\t&& Equals(a.reference, b.reference);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns a value indicating whether the two given JsonValues are unequal.\n\t\t/// </summary>\n\t\t/// <param name=\"a\">First JsonValue to compare.</param>\n\t\t/// <param name=\"b\">Second JsonValue to compare.</param>\n\t\tpublic static bool operator !=(JsonValue a, JsonValue b)\n\t\t{\n\t\t\treturn !(a == b);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns a JsonValue by parsing the given string.\n\t\t/// </summary>\n\t\t/// <param name=\"text\">The JSON-formatted string to be parsed.</param>\n\t\t/// <returns>The <see cref=\"JsonValue\"/> representing the parsed text.</returns>\n\t\tpublic static JsonValue Parse(string text)\n\t\t{\n\t\t\treturn JsonReader.Parse(text);\n\t\t}\n\n\t\t/// <inheritdoc/>\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\tif (obj == null)\n\t\t\t{\n\t\t\t\treturn this.IsNull;\n\t\t\t}\n\n\t\t\tvar jsonValue = obj as JsonValue?;\n\t\t\tif (jsonValue == null)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn this == jsonValue.Value;\n\t\t\t}\n\t\t}\n\n\t\t/// <inheritdoc/>\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\tif (this.IsNull)\n\t\t\t{\n\t\t\t\treturn this.Type.GetHashCode();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn this.Type.GetHashCode()\n\t\t\t\t\t^ this.value.GetHashCode()\n\t\t\t\t\t^ EqualityComparer<object>.Default.GetHashCode(this.reference);\n\t\t\t}\n\t\t}\n\n\t\t[ExcludeFromCodeCoverage]\n\t\tprivate class JsonValueDebugView\n\t\t{\n\t\t\tprivate JsonValue jsonValue;\n\n\t\t\tpublic JsonValueDebugView(JsonValue jsonValue)\n\t\t\t{\n\t\t\t\tthis.jsonValue = jsonValue;\n\t\t\t}\n\n\t\t\t[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]\n\t\t\tpublic JsonObject ObjectView {\n\t\t\t\tget {\n\t\t\t\t\tif (this.jsonValue.IsJsonObject)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn (JsonObject)this.jsonValue.reference;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]\n\t\t\tpublic JsonArray ArrayView {\n\t\t\t\tget {\n\t\t\t\t\tif (this.jsonValue.IsJsonArray)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn (JsonArray)this.jsonValue.reference;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic JsonValueType Type {\n\t\t\t\tget {\n\t\t\t\t\treturn this.jsonValue.Type;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic object Value {\n\t\t\t\tget {\n\t\t\t\t\tif (this.jsonValue.IsJsonObject)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn (JsonObject)this.jsonValue.reference;\n\t\t\t\t\t}\n\t\t\t\t\telse if (this.jsonValue.IsJsonArray)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn (JsonArray)this.jsonValue.reference;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn this.jsonValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/LightJson/JsonValueType.cs",
    "content": "// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nnamespace LightJson\n{\n\t/// <summary>\n\t/// Enumerates the types of Json values.\n\t/// </summary>\n\tinternal enum JsonValueType : byte\n\t{\n\t\t/// <summary>\n\t\t/// A null value.\n\t\t/// </summary>\n\t\tNull = 0,\n\n\t\t/// <summary>\n\t\t/// A boolean value.\n\t\t/// </summary>\n\t\tBoolean,\n\n\t\t/// <summary>\n\t\t/// A number value.\n\t\t/// </summary>\n\t\tNumber,\n\n\t\t/// <summary>\n\t\t/// A string value.\n\t\t/// </summary>\n\t\tString,\n\n\t\t/// <summary>\n\t\t/// An object value.\n\t\t/// </summary>\n\t\tObject,\n\n\t\t/// <summary>\n\t\t/// An array value.\n\t\t/// </summary>\n\t\tArray,\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/LightJson/Serialization/JsonParseException.cs",
    "content": "// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nnamespace LightJson.Serialization\n{\n\tusing System;\n\n\t/// <summary>\n\t/// The exception that is thrown when a JSON message cannot be parsed.\n\t/// </summary>\n\t/// <remarks>\n\t/// This exception is only intended to be thrown by LightJson.\n\t/// </remarks>\n\tinternal sealed class JsonParseException : Exception\n\t{\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"JsonParseException\"/> class.\n\t\t/// </summary>\n\t\tpublic JsonParseException()\n\t\t\t: base(GetDefaultMessage(ErrorType.Unknown))\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"JsonParseException\"/> class with the given error type and position.\n\t\t/// </summary>\n\t\t/// <param name=\"type\">The error type that describes the cause of the error.</param>\n\t\t/// <param name=\"position\">The position in the text where the error occurred.</param>\n\t\tpublic JsonParseException(ErrorType type, TextPosition position)\n\t\t\t: this(GetDefaultMessage(type), type, position)\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"JsonParseException\"/> class with the given message, error type, and position.\n\t\t/// </summary>\n\t\t/// <param name=\"message\">The message that describes the error.</param>\n\t\t/// <param name=\"type\">The error type that describes the cause of the error.</param>\n\t\t/// <param name=\"position\">The position in the text where the error occurred.</param>\n\t\tpublic JsonParseException(string message, ErrorType type, TextPosition position)\n\t\t\t: base(message)\n\t\t{\n\t\t\tthis.Type = type;\n\t\t\tthis.Position = position;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Enumerates the types of errors that can occur when parsing a JSON message.\n\t\t/// </summary>\n\t\tpublic enum ErrorType : int\n\t\t{\n\t\t\t/// <summary>\n\t\t\t/// Indicates that the cause of the error is unknown.\n\t\t\t/// </summary>\n\t\t\tUnknown = 0,\n\n\t\t\t/// <summary>\n\t\t\t/// Indicates that the text ended before the message could be parsed.\n\t\t\t/// </summary>\n\t\t\tIncompleteMessage,\n\n\t\t\t/// <summary>\n\t\t\t/// Indicates that a JsonObject contains more than one key with the same name.\n\t\t\t/// </summary>\n\t\t\tDuplicateObjectKeys,\n\n\t\t\t/// <summary>\n\t\t\t/// Indicates that the parser encountered and invalid or unexpected character.\n\t\t\t/// </summary>\n\t\t\tInvalidOrUnexpectedCharacter,\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the text position where the error occurred.\n\t\t/// </summary>\n\t\t/// <value>The text position where the error occurred.</value>\n\t\tpublic TextPosition Position { get; private set; }\n\n\t\t/// <summary>\n\t\t/// Gets the type of error that caused the exception to be thrown.\n\t\t/// </summary>\n\t\t/// <value>The type of error that caused the exception to be thrown.</value>\n\t\tpublic ErrorType Type { get; private set; }\n\n\t\tprivate static string GetDefaultMessage(ErrorType type)\n\t\t{\n\t\t\tswitch (type)\n\t\t\t{\n\t\t\t\tcase ErrorType.IncompleteMessage:\n\t\t\t\t\treturn \"The string ended before a value could be parsed.\";\n\n\t\t\t\tcase ErrorType.InvalidOrUnexpectedCharacter:\n\t\t\t\t\treturn \"The parser encountered an invalid or unexpected character.\";\n\n\t\t\t\tcase ErrorType.DuplicateObjectKeys:\n\t\t\t\t\treturn \"The parser encountered a JsonObject with duplicate keys.\";\n\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"An error occurred while parsing the JSON message.\";\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/LightJson/Serialization/JsonReader.cs",
    "content": "// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nnamespace LightJson.Serialization\n{\n\tusing System;\n\tusing System.Globalization;\n\tusing System.IO;\n\tusing System.Text;\n\n\tusing ErrorType = JsonParseException.ErrorType;\n\n\t/// <summary>\n\t/// Represents a reader that can read JsonValues.\n\t/// </summary>\n\tinternal sealed class JsonReader\n\t{\n\t\tprivate TextScanner scanner;\n\n\t\tprivate JsonReader(TextReader reader)\n\t\t{\n\t\t\tthis.scanner = new TextScanner(reader);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a JsonValue by using the given TextReader.\n\t\t/// </summary>\n\t\t/// <param name=\"reader\">The TextReader used to read a JSON message.</param>\n\t\t/// <returns>The parsed <see cref=\"JsonValue\"/>.</returns>\n\t\tpublic static JsonValue Parse(TextReader reader)\n\t\t{\n\t\t\tif (reader == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(reader));\n\t\t\t}\n\n\t\t\treturn new JsonReader(reader).Parse();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a JsonValue by reader the JSON message in the given string.\n\t\t/// </summary>\n\t\t/// <param name=\"source\">The string containing the JSON message.</param>\n\t\t/// <returns>The parsed <see cref=\"JsonValue\"/>.</returns>\n\t\tpublic static JsonValue Parse(string source)\n\t\t{\n\t\t\tif (source == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(source));\n\t\t\t}\n\n\t\t\tusing (var reader = new StringReader(source))\n\t\t\t{\n\t\t\t\treturn Parse(reader);\n\t\t\t}\n\t\t}\n\n\t\tprivate string ReadJsonKey()\n\t\t{\n\t\t\treturn this.ReadString();\n\t\t}\n\n\t\tprivate JsonValue ReadJsonValue()\n\t\t{\n\t\t\tthis.scanner.SkipWhitespace();\n\n\t\t\tvar next = this.scanner.Peek();\n\n\t\t\tif (char.IsNumber(next))\n\t\t\t{\n\t\t\t\treturn this.ReadNumber();\n\t\t\t}\n\n\t\t\tswitch (next)\n\t\t\t{\n\t\t\t\tcase '{':\n\t\t\t\t\treturn this.ReadObject();\n\n\t\t\t\tcase '[':\n\t\t\t\t\treturn this.ReadArray();\n\n\t\t\t\tcase '\"':\n\t\t\t\t\treturn this.ReadString();\n\n\t\t\t\tcase '-':\n\t\t\t\t\treturn this.ReadNumber();\n\n\t\t\t\tcase 't':\n\t\t\t\tcase 'f':\n\t\t\t\t\treturn this.ReadBoolean();\n\n\t\t\t\tcase 'n':\n\t\t\t\t\treturn this.ReadNull();\n\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new JsonParseException(\n\t\t\t\t\t\tErrorType.InvalidOrUnexpectedCharacter,\n\t\t\t\t\t\tthis.scanner.Position);\n\t\t\t}\n\t\t}\n\n\t\tprivate JsonValue ReadNull()\n\t\t{\n\t\t\tthis.scanner.Assert(\"null\");\n\t\t\treturn JsonValue.Null;\n\t\t}\n\n\t\tprivate JsonValue ReadBoolean()\n\t\t{\n\t\t\tswitch (this.scanner.Peek())\n\t\t\t{\n\t\t\t\tcase 't':\n\t\t\t\t\tthis.scanner.Assert(\"true\");\n\t\t\t\t\treturn true;\n\n\t\t\t\tdefault:\n\t\t\t\t\tthis.scanner.Assert(\"false\");\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tprivate void ReadDigits(StringBuilder builder)\n\t\t{\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tint next = this.scanner.Peek(throwAtEndOfFile: false);\n\t\t\t\tif (next == -1 || !char.IsNumber((char)next))\n\t\t\t\t{\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tbuilder.Append(this.scanner.Read());\n\t\t\t}\n\t\t}\n\n\t\tprivate JsonValue ReadNumber()\n\t\t{\n\t\t\tvar builder = new StringBuilder();\n\n\t\t\tif (this.scanner.Peek() == '-')\n\t\t\t{\n\t\t\t\tbuilder.Append(this.scanner.Read());\n\t\t\t}\n\n\t\t\tif (this.scanner.Peek() == '0')\n\t\t\t{\n\t\t\t\tbuilder.Append(this.scanner.Read());\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.ReadDigits(builder);\n\t\t\t}\n\n\t\t\tif (this.scanner.Peek(throwAtEndOfFile: false) == '.')\n\t\t\t{\n\t\t\t\tbuilder.Append(this.scanner.Read());\n\t\t\t\tthis.ReadDigits(builder);\n\t\t\t}\n\n\t\t\tif (this.scanner.Peek(throwAtEndOfFile: false) == 'e' || this.scanner.Peek(throwAtEndOfFile: false) == 'E')\n\t\t\t{\n\t\t\t\tbuilder.Append(this.scanner.Read());\n\n\t\t\t\tvar next = this.scanner.Peek();\n\n\t\t\t\tswitch (next)\n\t\t\t\t{\n\t\t\t\t\tcase '+':\n\t\t\t\t\tcase '-':\n\t\t\t\t\t\tbuilder.Append(this.scanner.Read());\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tthis.ReadDigits(builder);\n\t\t\t}\n\n\t\t\treturn double.Parse(\n\t\t\t\tbuilder.ToString(),\n\t\t\t\tCultureInfo.InvariantCulture);\n\t\t}\n\n\t\tprivate string ReadString()\n\t\t{\n\t\t\tvar builder = new StringBuilder();\n\n\t\t\tthis.scanner.Assert('\"');\n\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tvar errorPosition = this.scanner.Position;\n\t\t\t\tvar c = this.scanner.Read();\n\n\t\t\t\tif (c == '\\\\')\n\t\t\t\t{\n\t\t\t\t\terrorPosition = this.scanner.Position;\n\t\t\t\t\tc = this.scanner.Read();\n\n\t\t\t\t\tswitch (char.ToLower(c))\n\t\t\t\t\t{\n\t\t\t\t\t\tcase '\"':\n\t\t\t\t\t\tcase '\\\\':\n\t\t\t\t\t\tcase '/':\n\t\t\t\t\t\t\tbuilder.Append(c);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'b':\n\t\t\t\t\t\t\tbuilder.Append('\\b');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'f':\n\t\t\t\t\t\t\tbuilder.Append('\\f');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'n':\n\t\t\t\t\t\t\tbuilder.Append('\\n');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'r':\n\t\t\t\t\t\t\tbuilder.Append('\\r');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 't':\n\t\t\t\t\t\t\tbuilder.Append('\\t');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'u':\n\t\t\t\t\t\t\tbuilder.Append(this.ReadUnicodeLiteral());\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow new JsonParseException(\n\t\t\t\t\t\t\t\tErrorType.InvalidOrUnexpectedCharacter,\n\t\t\t\t\t\t\t\terrorPosition);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (c == '\"')\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (char.IsControl(c))\n\t\t\t\t\t{\n\t\t\t\t\t\tthrow new JsonParseException(\n\t\t\t\t\t\t\tErrorType.InvalidOrUnexpectedCharacter,\n\t\t\t\t\t\t\terrorPosition);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tbuilder.Append(c);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn builder.ToString();\n\t\t}\n\n\t\tprivate int ReadHexDigit()\n\t\t{\n\t\t\tvar errorPosition = this.scanner.Position;\n\t\t\tswitch (char.ToUpper(this.scanner.Read()))\n\t\t\t{\n\t\t\t\tcase '0':\n\t\t\t\t\treturn 0;\n\n\t\t\t\tcase '1':\n\t\t\t\t\treturn 1;\n\n\t\t\t\tcase '2':\n\t\t\t\t\treturn 2;\n\n\t\t\t\tcase '3':\n\t\t\t\t\treturn 3;\n\n\t\t\t\tcase '4':\n\t\t\t\t\treturn 4;\n\n\t\t\t\tcase '5':\n\t\t\t\t\treturn 5;\n\n\t\t\t\tcase '6':\n\t\t\t\t\treturn 6;\n\n\t\t\t\tcase '7':\n\t\t\t\t\treturn 7;\n\n\t\t\t\tcase '8':\n\t\t\t\t\treturn 8;\n\n\t\t\t\tcase '9':\n\t\t\t\t\treturn 9;\n\n\t\t\t\tcase 'A':\n\t\t\t\t\treturn 10;\n\n\t\t\t\tcase 'B':\n\t\t\t\t\treturn 11;\n\n\t\t\t\tcase 'C':\n\t\t\t\t\treturn 12;\n\n\t\t\t\tcase 'D':\n\t\t\t\t\treturn 13;\n\n\t\t\t\tcase 'E':\n\t\t\t\t\treturn 14;\n\n\t\t\t\tcase 'F':\n\t\t\t\t\treturn 15;\n\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new JsonParseException(\n\t\t\t\t\t\tErrorType.InvalidOrUnexpectedCharacter,\n\t\t\t\t\t\terrorPosition);\n\t\t\t}\n\t\t}\n\n\t\tprivate char ReadUnicodeLiteral()\n\t\t{\n\t\t\tint value = 0;\n\n\t\t\tvalue += this.ReadHexDigit() * 4096; // 16^3\n\t\t\tvalue += this.ReadHexDigit() * 256;  // 16^2\n\t\t\tvalue += this.ReadHexDigit() * 16;   // 16^1\n\t\t\tvalue += this.ReadHexDigit();        // 16^0\n\n\t\t\treturn (char)value;\n\t\t}\n\n\t\tprivate JsonObject ReadObject()\n\t\t{\n\t\t\treturn this.ReadObject(new JsonObject());\n\t\t}\n\n\t\tprivate JsonObject ReadObject(JsonObject jsonObject)\n\t\t{\n\t\t\tthis.scanner.Assert('{');\n\n\t\t\tthis.scanner.SkipWhitespace();\n\n\t\t\tif (this.scanner.Peek() == '}')\n\t\t\t{\n\t\t\t\tthis.scanner.Read();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\twhile (true)\n\t\t\t\t{\n\t\t\t\t\tthis.scanner.SkipWhitespace();\n\n\t\t\t\t\tvar errorPosition = this.scanner.Position;\n\t\t\t\t\tvar key = this.ReadJsonKey();\n\n\t\t\t\t\tif (jsonObject.ContainsKey(key))\n\t\t\t\t\t{\n\t\t\t\t\t\tthrow new JsonParseException(\n\t\t\t\t\t\t\tErrorType.DuplicateObjectKeys,\n\t\t\t\t\t\t\terrorPosition);\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.scanner.SkipWhitespace();\n\n\t\t\t\t\tthis.scanner.Assert(':');\n\n\t\t\t\t\tthis.scanner.SkipWhitespace();\n\n\t\t\t\t\tvar value = this.ReadJsonValue();\n\n\t\t\t\t\tjsonObject.Add(key, value);\n\n\t\t\t\t\tthis.scanner.SkipWhitespace();\n\n\t\t\t\t\terrorPosition = this.scanner.Position;\n\t\t\t\t\tvar next = this.scanner.Read();\n\t\t\t\t\tif (next == ',')\n\t\t\t\t\t{\n\t\t\t\t\t\t// Allow trailing commas in objects\n\t\t\t\t\t\tthis.scanner.SkipWhitespace();\n\t\t\t\t\t\tif (this.scanner.Peek() == '}')\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnext = this.scanner.Read();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (next == '}')\n\t\t\t\t\t{\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\telse if (next == ',')\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tthrow new JsonParseException(\n\t\t\t\t\t\t\tErrorType.InvalidOrUnexpectedCharacter,\n\t\t\t\t\t\t\terrorPosition);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn jsonObject;\n\t\t}\n\n\t\tprivate JsonArray ReadArray()\n\t\t{\n\t\t\treturn this.ReadArray(new JsonArray());\n\t\t}\n\n\t\tprivate JsonArray ReadArray(JsonArray jsonArray)\n\t\t{\n\t\t\tthis.scanner.Assert('[');\n\n\t\t\tthis.scanner.SkipWhitespace();\n\n\t\t\tif (this.scanner.Peek() == ']')\n\t\t\t{\n\t\t\t\tthis.scanner.Read();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\twhile (true)\n\t\t\t\t{\n\t\t\t\t\tthis.scanner.SkipWhitespace();\n\n\t\t\t\t\tvar value = this.ReadJsonValue();\n\n\t\t\t\t\tjsonArray.Add(value);\n\n\t\t\t\t\tthis.scanner.SkipWhitespace();\n\n\t\t\t\t\tvar errorPosition = this.scanner.Position;\n\t\t\t\t\tvar next = this.scanner.Read();\n\t\t\t\t\tif (next == ',')\n\t\t\t\t\t{\n\t\t\t\t\t\t// Allow trailing commas in arrays\n\t\t\t\t\t\tthis.scanner.SkipWhitespace();\n\t\t\t\t\t\tif (this.scanner.Peek() == ']')\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnext = this.scanner.Read();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (next == ']')\n\t\t\t\t\t{\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\telse if (next == ',')\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tthrow new JsonParseException(\n\t\t\t\t\t\t\tErrorType.InvalidOrUnexpectedCharacter,\n\t\t\t\t\t\t\terrorPosition);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn jsonArray;\n\t\t}\n\n\t\tprivate JsonValue Parse()\n\t\t{\n\t\t\tthis.scanner.SkipWhitespace();\n\t\t\treturn this.ReadJsonValue();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/LightJson/Serialization/TextPosition.cs",
    "content": "// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nnamespace LightJson.Serialization\n{\n\t/// <summary>\n\t/// Represents a position within a plain text resource.\n\t/// </summary>\n\tinternal struct TextPosition\n\t{\n\t\t/// <summary>\n\t\t/// The column position, 0-based.\n\t\t/// </summary>\n\t\tpublic long Column;\n\n\t\t/// <summary>\n\t\t/// The line position, 0-based.\n\t\t/// </summary>\n\t\tpublic long Line;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/LightJson/Serialization/TextScanner.cs",
    "content": "// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nnamespace LightJson.Serialization\n{\n\tusing System.IO;\n\n\tusing ErrorType = JsonParseException.ErrorType;\n\n\t/// <summary>\n\t/// Represents a text scanner that reads one character at a time.\n\t/// </summary>\n\tinternal sealed class TextScanner\n\t{\n\t\tprivate TextReader reader;\n\t\tprivate TextPosition position;\n\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"TextScanner\"/> class.\n\t\t/// </summary>\n\t\t/// <param name=\"reader\">The TextReader to read the text.</param>\n\t\tpublic TextScanner(TextReader reader)\n\t\t{\n\t\t\tthis.reader = reader;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the position of the scanner within the text.\n\t\t/// </summary>\n\t\t/// <value>The position of the scanner within the text.</value>\n\t\tpublic TextPosition Position {\n\t\t\tget {\n\t\t\t\treturn this.position;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Reads the next character in the stream without changing the current position.\n\t\t/// </summary>\n\t\t/// <returns>The next character in the stream.</returns>\n\t\tpublic char Peek()\n\t\t\t=> (char)this.Peek(throwAtEndOfFile: true);\n\n\t\t/// <summary>\n\t\t/// Reads the next character in the stream without changing the current position.\n\t\t/// </summary>\n\t\t/// <param name=\"throwAtEndOfFile\"><see langword=\"true\"/> to throw an exception if the end of the file is\n\t\t/// reached; otherwise, <see langword=\"false\"/>.</param>\n\t\t/// <returns>The next character in the stream, or -1 if the end of the file is reached with\n\t\t/// <paramref name=\"throwAtEndOfFile\"/> set to <see langword=\"false\"/>.</returns>\n\t\tpublic int Peek(bool throwAtEndOfFile)\n\t\t{\n\t\t\tvar next = this.reader.Peek();\n\n\t\t\tif (next == -1 && throwAtEndOfFile)\n\t\t\t{\n\t\t\t\tthrow new JsonParseException(\n\t\t\t\t\tErrorType.IncompleteMessage,\n\t\t\t\t\tthis.position);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn next;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Reads the next character in the stream, advancing the text position.\n\t\t/// </summary>\n\t\t/// <returns>The next character in the stream.</returns>\n\t\tpublic char Read()\n\t\t{\n\t\t\tvar next = this.reader.Read();\n\n\t\t\tif (next == -1)\n\t\t\t{\n\t\t\t\tthrow new JsonParseException(\n\t\t\t\t\tErrorType.IncompleteMessage,\n\t\t\t\t\tthis.position);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (next == '\\n')\n\t\t\t\t{\n\t\t\t\t\tthis.position.Line += 1;\n\t\t\t\t\tthis.position.Column = 0;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthis.position.Column += 1;\n\t\t\t\t}\n\n\t\t\t\treturn (char)next;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Advances the scanner to next non-whitespace character.\n\t\t/// </summary>\n\t\tpublic void SkipWhitespace()\n\t\t{\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tchar next = this.Peek();\n\t\t\t\tif (char.IsWhiteSpace(next))\n\t\t\t\t{\n\t\t\t\t\tthis.Read();\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\telse if (next == '/')\n\t\t\t\t{\n\t\t\t\t\tthis.SkipComment();\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Verifies that the given character matches the next character in the stream.\n\t\t/// If the characters do not match, an exception will be thrown.\n\t\t/// </summary>\n\t\t/// <param name=\"next\">The expected character.</param>\n\t\tpublic void Assert(char next)\n\t\t{\n\t\t\tvar errorPosition = this.position;\n\t\t\tif (this.Read() != next)\n\t\t\t{\n\t\t\t\tthrow new JsonParseException(\n\t\t\t\t\tstring.Format(\"Parser expected '{0}'\", next),\n\t\t\t\t\tErrorType.InvalidOrUnexpectedCharacter,\n\t\t\t\t\terrorPosition);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Verifies that the given string matches the next characters in the stream.\n\t\t/// If the strings do not match, an exception will be thrown.\n\t\t/// </summary>\n\t\t/// <param name=\"next\">The expected string.</param>\n\t\tpublic void Assert(string next)\n\t\t{\n\t\t\tfor (var i = 0; i < next.Length; i += 1)\n\t\t\t{\n\t\t\t\tthis.Assert(next[i]);\n\t\t\t}\n\t\t}\n\n\t\tprivate void SkipComment()\n\t\t{\n\t\t\t// First character is the first slash\n\t\t\tthis.Read();\n\t\t\tswitch (this.Peek())\n\t\t\t{\n\t\t\t\tcase '/':\n\t\t\t\t\tthis.SkipLineComment();\n\t\t\t\t\treturn;\n\n\t\t\t\tcase '*':\n\t\t\t\t\tthis.SkipBlockComment();\n\t\t\t\t\treturn;\n\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new JsonParseException(\n\t\t\t\t\t\tstring.Format(\"Parser expected '{0}'\", this.Peek()),\n\t\t\t\t\t\tErrorType.InvalidOrUnexpectedCharacter,\n\t\t\t\t\t\tthis.position);\n\t\t\t}\n\t\t}\n\n\t\tprivate void SkipLineComment()\n\t\t{\n\t\t\t// First character is the second '/' of the opening '//'\n\t\t\tthis.Read();\n\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tswitch (this.reader.Peek())\n\t\t\t\t{\n\t\t\t\t\tcase '\\n':\n\t\t\t\t\t\t// Reached the end of the line\n\t\t\t\t\t\tthis.Read();\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\tcase -1:\n\t\t\t\t\t\t// Reached the end of the file\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthis.Read();\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate void SkipBlockComment()\n\t\t{\n\t\t\t// First character is the '*' of the opening '/*'\n\t\t\tthis.Read();\n\n\t\t\tbool foundStar = false;\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tswitch (this.reader.Peek())\n\t\t\t\t{\n\t\t\t\t\tcase '*':\n\t\t\t\t\t\tthis.Read();\n\t\t\t\t\t\tfoundStar = true;\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\tcase '/':\n\t\t\t\t\t\tthis.Read();\n\t\t\t\t\t\tif (foundStar)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfoundStar = false;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase -1:\n\t\t\t\t\t\t// Reached the end of the file\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthis.Read();\n\t\t\t\t\t\tfoundStar = false;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/MemberReferenceMetadata.cs",
    "content": "// Copyright (c) 2023 James May\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n#if !VSADDIN\n\t/// <summary>\n\t/// Convenience wrapper for <see cref=\"MemberReference\"/> and <see cref=\"MemberReferenceHandle\"/>.\n\t/// </summary>\n\tpublic sealed class MemberReferenceMetadata\n\t{\n\t\treadonly MemberReference entry;\n\n\t\tpublic MetadataReader Metadata { get; }\n\t\tpublic MemberReferenceHandle Handle { get; }\n\n\t\tstring? name;\n\n\t\tpublic string Name {\n\t\t\tget {\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\treturn name ??= Metadata.GetString(entry.Name);\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\treturn name = $\"MR:{Handle}\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic EntityHandle Parent => entry.Parent;\n\n\t\tpublic MemberReferenceKind MemberReferenceKind => entry.GetKind();\n\n\t\tpublic MemberReferenceMetadata(MetadataReader metadata, MemberReferenceHandle handle)\n\t\t{\n\t\t\tMetadata = metadata ?? throw new ArgumentNullException(nameof(metadata));\n\t\t\tif (handle.IsNil)\n\t\t\t\tthrow new ArgumentNullException(nameof(handle));\n\t\t\tHandle = handle;\n\t\t\tentry = metadata.GetMemberReference(handle);\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t\t=> Name;\n\t}\n#endif\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Buffers.Binary;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Security.Cryptography;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nusing SRM = System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\tpublic static class MetadataExtensions\n\t{\n\t\tstatic string CalculatePublicKeyToken(BlobHandle blob, MetadataReader reader)\n\t\t{\n\t\t\t// Calculate public key token:\n\t\t\t// 1. hash the public key (always use SHA1).\n\t\t\tbyte[] publicKeyTokenBytes;\n\t\t\tusing (var hasher = SHA1.Create())\n\t\t\t{\n\t\t\t\tpublicKeyTokenBytes = hasher.ComputeHash(reader.GetBlobBytes(blob));\n\t\t\t}\n\n\t\t\t// 2. take the last 8 bytes\n\t\t\t// 3. according to Cecil we need to reverse them, other sources did not mention this.\n\t\t\treturn publicKeyTokenBytes.TakeLast(8).Reverse().ToHexString(8);\n\t\t}\n\n\t\tpublic static string GetPublicKeyToken(this MetadataReader reader)\n\t\t{\n\t\t\tif (!reader.IsAssembly)\n\t\t\t\treturn string.Empty;\n\t\t\tvar asm = reader.GetAssemblyDefinition();\n\t\t\tstring publicKey = \"null\";\n\t\t\tif (!asm.PublicKey.IsNil)\n\t\t\t{\n\t\t\t\t// AssemblyFlags.PublicKey does not apply to assembly definitions\n\t\t\t\tpublicKey = CalculatePublicKeyToken(asm.PublicKey, reader);\n\t\t\t}\n\t\t\treturn publicKey;\n\t\t}\n\n\t\tpublic static string GetFullAssemblyName(this MetadataReader reader)\n\t\t{\n\t\t\tif (!reader.IsAssembly)\n\t\t\t\treturn string.Empty;\n\t\t\tvar asm = reader.GetAssemblyDefinition();\n\t\t\tstring publicKey = reader.GetPublicKeyToken();\n\t\t\treturn $\"{reader.GetString(asm.Name)}, \" +\n\t\t\t\t$\"Version={asm.Version}, \" +\n\t\t\t\t$\"Culture={(asm.Culture.IsNil ? \"neutral\" : reader.GetString(asm.Culture))}, \" +\n\t\t\t\t$\"PublicKeyToken={publicKey}\";\n\t\t}\n\n\t\tpublic static bool TryGetFullAssemblyName(this MetadataReader reader, out string assemblyName)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tassemblyName = GetFullAssemblyName(reader);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tcatch (BadImageFormatException)\n\t\t\t{\n\t\t\t\tassemblyName = null;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic static string GetFullAssemblyName(this SRM.AssemblyReference reference, MetadataReader reader)\n\t\t{\n\t\t\tStringBuilder builder = new StringBuilder();\n\t\t\tbuilder.Append(reader.GetString(reference.Name));\n\t\t\tbuilder.Append(\", Version=\");\n\t\t\tbuilder.Append(reference.Version);\n\t\t\tbuilder.Append(\", Culture=\");\n\t\t\tif (reference.Culture.IsNil)\n\t\t\t{\n\t\t\t\tbuilder.Append(\"neutral\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbuilder.Append(reader.GetString(reference.Culture));\n\t\t\t}\n\n\t\t\tif (reference.PublicKeyOrToken.IsNil)\n\t\t\t{\n\t\t\t\tbuilder.Append(\", PublicKeyToken=null\");\n\t\t\t}\n\t\t\telse if ((reference.Flags & AssemblyFlags.PublicKey) != 0)\n\t\t\t{\n\t\t\t\tbuilder.Append(\", PublicKeyToken=\");\n\t\t\t\tbuilder.Append(CalculatePublicKeyToken(reference.PublicKeyOrToken, reader));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbuilder.Append(\", PublicKeyToken=\");\n\t\t\t\tbuilder.AppendHexString(reader.GetBlobReader(reference.PublicKeyOrToken));\n\t\t\t}\n\t\t\tif ((reference.Flags & AssemblyFlags.Retargetable) != 0)\n\t\t\t{\n\t\t\t\tbuilder.Append(\", Retargetable=true\");\n\t\t\t}\n\t\t\treturn builder.ToString();\n\t\t}\n\n\t\tpublic static bool TryGetFullAssemblyName(this SRM.AssemblyReference reference, MetadataReader reader, out string assemblyName)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tassemblyName = GetFullAssemblyName(reference, reader);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tcatch (BadImageFormatException)\n\t\t\t{\n\t\t\t\tassemblyName = null;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic static string ToHexString(this IEnumerable<byte> bytes, int estimatedLength)\n\t\t{\n\t\t\tif (bytes == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(bytes));\n\n\t\t\tStringBuilder sb = new StringBuilder(estimatedLength * 2);\n\t\t\tforeach (var b in bytes)\n\t\t\t\tsb.AppendFormat(\"{0:x2}\", b);\n\t\t\treturn sb.ToString();\n\t\t}\n\n\t\tpublic static void AppendHexString(this StringBuilder builder, BlobReader reader)\n\t\t{\n\t\t\tfor (int i = 0; i < reader.Length; i++)\n\t\t\t{\n\t\t\t\tbuilder.AppendFormat(\"{0:x2}\", reader.ReadByte());\n\t\t\t}\n\t\t}\n\n\t\tpublic static string ToHexString(this BlobReader reader)\n\t\t{\n\t\t\tStringBuilder sb = new StringBuilder(reader.Length * 3);\n\t\t\tfor (int i = 0; i < reader.Length; i++)\n\t\t\t{\n\t\t\t\tif (i == 0)\n\t\t\t\t\tsb.AppendFormat(\"{0:X2}\", reader.ReadByte());\n\t\t\t\telse\n\t\t\t\t\tsb.AppendFormat(\"-{0:X2}\", reader.ReadByte());\n\t\t\t}\n\t\t\treturn sb.ToString();\n\t\t}\n\n\t\tpublic static IEnumerable<TypeDefinitionHandle> GetTopLevelTypeDefinitions(this MetadataReader reader)\n\t\t{\n\t\t\tforeach (var handle in reader.TypeDefinitions)\n\t\t\t{\n\t\t\t\tvar td = reader.GetTypeDefinition(handle);\n\t\t\t\tif (td.GetDeclaringType().IsNil)\n\t\t\t\t\tyield return handle;\n\t\t\t}\n\t\t}\n\n\t\tpublic static string ToILNameString(this FullTypeName typeName, bool omitGenerics = false)\n\t\t{\n\t\t\tstring name;\n\t\t\tif (typeName.IsNested)\n\t\t\t{\n\t\t\t\tname = typeName.Name;\n\t\t\t\tif (!omitGenerics)\n\t\t\t\t{\n\t\t\t\t\tint localTypeParameterCount = typeName.GetNestedTypeAdditionalTypeParameterCount(typeName.NestingLevel - 1);\n\t\t\t\t\tif (localTypeParameterCount > 0)\n\t\t\t\t\t\tname += \"`\" + localTypeParameterCount;\n\t\t\t\t}\n\t\t\t\tname = Disassembler.DisassemblerHelpers.Escape(name);\n\t\t\t\treturn $\"{typeName.GetDeclaringType().ToILNameString(omitGenerics)}/{name}\";\n\t\t\t}\n\t\t\tif (!string.IsNullOrEmpty(typeName.TopLevelTypeName.Namespace))\n\t\t\t{\n\t\t\t\tname = $\"{typeName.TopLevelTypeName.Namespace}.{typeName.Name}\";\n\t\t\t\tif (!omitGenerics && typeName.TypeParameterCount > 0)\n\t\t\t\t\tname += \"`\" + typeName.TypeParameterCount;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tname = typeName.Name;\n\t\t\t\tif (!omitGenerics && typeName.TypeParameterCount > 0)\n\t\t\t\t\tname += \"`\" + typeName.TypeParameterCount;\n\t\t\t}\n\t\t\treturn Disassembler.DisassemblerHelpers.Escape(name);\n\t\t}\n\n\t\tinternal static readonly TypeProvider minimalCorlibTypeProvider =\n\t\t\tnew TypeProvider(new SimpleCompilation(MinimalCorlib.Instance));\n\n\t\t/// <summary>\n\t\t/// An attribute type provider that can be used to decode attribute signatures\n\t\t/// that only mention built-in types.\n\t\t/// </summary>\n\t\tpublic static ICustomAttributeTypeProvider<IType> MinimalAttributeTypeProvider {\n\t\t\tget => minimalCorlibTypeProvider;\n\t\t}\n\n\t\tpublic static ISignatureTypeProvider<IType, TypeSystem.GenericContext> MinimalSignatureTypeProvider {\n\t\t\tget => minimalCorlibTypeProvider;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts <see cref=\"KnownTypeCode\"/> to <see cref=\"PrimitiveTypeCode\"/>.\n\t\t/// Returns 0 for known types that are not primitive types (such as <see cref=\"Span{T}\"/>).\n\t\t/// </summary>\n\t\tpublic static PrimitiveTypeCode ToPrimitiveTypeCode(this KnownTypeCode typeCode)\n\t\t{\n\t\t\tswitch (typeCode)\n\t\t\t{\n\t\t\t\tcase KnownTypeCode.Object:\n\t\t\t\t\treturn PrimitiveTypeCode.Object;\n\t\t\t\tcase KnownTypeCode.Boolean:\n\t\t\t\t\treturn PrimitiveTypeCode.Boolean;\n\t\t\t\tcase KnownTypeCode.Char:\n\t\t\t\t\treturn PrimitiveTypeCode.Char;\n\t\t\t\tcase KnownTypeCode.SByte:\n\t\t\t\t\treturn PrimitiveTypeCode.SByte;\n\t\t\t\tcase KnownTypeCode.Byte:\n\t\t\t\t\treturn PrimitiveTypeCode.Byte;\n\t\t\t\tcase KnownTypeCode.Int16:\n\t\t\t\t\treturn PrimitiveTypeCode.Int16;\n\t\t\t\tcase KnownTypeCode.UInt16:\n\t\t\t\t\treturn PrimitiveTypeCode.UInt16;\n\t\t\t\tcase KnownTypeCode.Int32:\n\t\t\t\t\treturn PrimitiveTypeCode.Int32;\n\t\t\t\tcase KnownTypeCode.UInt32:\n\t\t\t\t\treturn PrimitiveTypeCode.UInt32;\n\t\t\t\tcase KnownTypeCode.Int64:\n\t\t\t\t\treturn PrimitiveTypeCode.Int64;\n\t\t\t\tcase KnownTypeCode.UInt64:\n\t\t\t\t\treturn PrimitiveTypeCode.UInt64;\n\t\t\t\tcase KnownTypeCode.Single:\n\t\t\t\t\treturn PrimitiveTypeCode.Single;\n\t\t\t\tcase KnownTypeCode.Double:\n\t\t\t\t\treturn PrimitiveTypeCode.Double;\n\t\t\t\tcase KnownTypeCode.String:\n\t\t\t\t\treturn PrimitiveTypeCode.String;\n\t\t\t\tcase KnownTypeCode.Void:\n\t\t\t\t\treturn PrimitiveTypeCode.Void;\n\t\t\t\tcase KnownTypeCode.TypedReference:\n\t\t\t\t\treturn PrimitiveTypeCode.TypedReference;\n\t\t\t\tcase KnownTypeCode.IntPtr:\n\t\t\t\t\treturn PrimitiveTypeCode.IntPtr;\n\t\t\t\tcase KnownTypeCode.UIntPtr:\n\t\t\t\t\treturn PrimitiveTypeCode.UIntPtr;\n\t\t\t\tdefault:\n\t\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\n\t\tpublic static KnownTypeCode ToKnownTypeCode(this PrimitiveTypeCode typeCode)\n\t\t{\n\t\t\tswitch (typeCode)\n\t\t\t{\n\t\t\t\tcase PrimitiveTypeCode.Boolean:\n\t\t\t\t\treturn KnownTypeCode.Boolean;\n\t\t\t\tcase PrimitiveTypeCode.Byte:\n\t\t\t\t\treturn KnownTypeCode.Byte;\n\t\t\t\tcase PrimitiveTypeCode.SByte:\n\t\t\t\t\treturn KnownTypeCode.SByte;\n\t\t\t\tcase PrimitiveTypeCode.Char:\n\t\t\t\t\treturn KnownTypeCode.Char;\n\t\t\t\tcase PrimitiveTypeCode.Int16:\n\t\t\t\t\treturn KnownTypeCode.Int16;\n\t\t\t\tcase PrimitiveTypeCode.UInt16:\n\t\t\t\t\treturn KnownTypeCode.UInt16;\n\t\t\t\tcase PrimitiveTypeCode.Int32:\n\t\t\t\t\treturn KnownTypeCode.Int32;\n\t\t\t\tcase PrimitiveTypeCode.UInt32:\n\t\t\t\t\treturn KnownTypeCode.UInt32;\n\t\t\t\tcase PrimitiveTypeCode.Int64:\n\t\t\t\t\treturn KnownTypeCode.Int64;\n\t\t\t\tcase PrimitiveTypeCode.UInt64:\n\t\t\t\t\treturn KnownTypeCode.UInt64;\n\t\t\t\tcase PrimitiveTypeCode.Single:\n\t\t\t\t\treturn KnownTypeCode.Single;\n\t\t\t\tcase PrimitiveTypeCode.Double:\n\t\t\t\t\treturn KnownTypeCode.Double;\n\t\t\t\tcase PrimitiveTypeCode.IntPtr:\n\t\t\t\t\treturn KnownTypeCode.IntPtr;\n\t\t\t\tcase PrimitiveTypeCode.UIntPtr:\n\t\t\t\t\treturn KnownTypeCode.UIntPtr;\n\t\t\t\tcase PrimitiveTypeCode.Object:\n\t\t\t\t\treturn KnownTypeCode.Object;\n\t\t\t\tcase PrimitiveTypeCode.String:\n\t\t\t\t\treturn KnownTypeCode.String;\n\t\t\t\tcase PrimitiveTypeCode.TypedReference:\n\t\t\t\t\treturn KnownTypeCode.TypedReference;\n\t\t\t\tcase PrimitiveTypeCode.Void:\n\t\t\t\t\treturn KnownTypeCode.Void;\n\t\t\t\tdefault:\n\t\t\t\t\treturn KnownTypeCode.None;\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<ModuleReferenceHandle> GetModuleReferences(this MetadataReader metadata)\n\t\t{\n\t\t\tvar rowCount = metadata.GetTableRowCount(TableIndex.ModuleRef);\n\t\t\tfor (int row = 1; row <= rowCount; row++)\n\t\t\t{\n\t\t\t\tyield return MetadataTokens.ModuleReferenceHandle(row);\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<TypeSpecificationHandle> GetTypeSpecifications(this MetadataReader metadata)\n\t\t{\n\t\t\tvar rowCount = metadata.GetTableRowCount(TableIndex.TypeSpec);\n\t\t\tfor (int row = 1; row <= rowCount; row++)\n\t\t\t{\n\t\t\t\tyield return MetadataTokens.TypeSpecificationHandle(row);\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<MethodSpecificationHandle> GetMethodSpecifications(this MetadataReader metadata)\n\t\t{\n\t\t\tvar rowCount = metadata.GetTableRowCount(TableIndex.MethodSpec);\n\t\t\tfor (int row = 1; row <= rowCount; row++)\n\t\t\t{\n\t\t\t\tyield return MetadataTokens.MethodSpecificationHandle(row);\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<(Handle Handle, MethodSemanticsAttributes Semantics, MethodDefinitionHandle Method, EntityHandle Association)> GetMethodSemantics(this MetadataReader metadata)\n\t\t{\n\t\t\tint offset = metadata.GetTableMetadataOffset(TableIndex.MethodSemantics);\n\t\t\tint rowSize = metadata.GetTableRowSize(TableIndex.MethodSemantics);\n\t\t\tint rowCount = metadata.GetTableRowCount(TableIndex.MethodSemantics);\n\n\t\t\tbool methodSmall = metadata.GetTableRowCount(TableIndex.MethodDef) <= ushort.MaxValue;\n\t\t\tbool assocSmall = metadata.GetTableRowCount(TableIndex.Property) <= ushort.MaxValue && metadata.GetTableRowCount(TableIndex.Event) <= ushort.MaxValue;\n\t\t\tint assocOffset = (methodSmall ? 2 : 4) + 2;\n\t\t\tfor (int row = 0; row < rowCount; row++)\n\t\t\t{\n\t\t\t\tyield return Read(row);\n\t\t\t}\n\n\t\t\t(Handle Handle, MethodSemanticsAttributes Semantics, MethodDefinitionHandle Method, EntityHandle Association) Read(int row)\n\t\t\t{\n\t\t\t\tvar span = metadata.AsReadOnlySpan();\n\t\t\t\tvar methodDefSpan = span.Slice(offset + rowSize * row + 2);\n\t\t\t\tint methodDef = methodSmall ? BinaryPrimitives.ReadUInt16LittleEndian(methodDefSpan) : (int)BinaryPrimitives.ReadUInt32LittleEndian(methodDefSpan);\n\t\t\t\tvar assocSpan = span.Slice(assocOffset);\n\t\t\t\tint assocDef = assocSmall ? BinaryPrimitives.ReadUInt16LittleEndian(assocSpan) : (int)BinaryPrimitives.ReadUInt32LittleEndian(assocSpan);\n\t\t\t\tEntityHandle propOrEvent;\n\t\t\t\tif ((assocDef & 0x1) == 1)\n\t\t\t\t{\n\t\t\t\t\tpropOrEvent = MetadataTokens.PropertyDefinitionHandle(assocDef >> 1);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tpropOrEvent = MetadataTokens.EventDefinitionHandle(assocDef >> 1);\n\t\t\t\t}\n\t\t\t\treturn (MetadataTokens.Handle(0x18000000 | (row + 1)), (MethodSemanticsAttributes)(BinaryPrimitives.ReadUInt16LittleEndian(span)), MetadataTokens.MethodDefinitionHandle(methodDef), propOrEvent);\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<EntityHandle> GetFieldLayouts(this MetadataReader metadata)\n\t\t{\n\t\t\tvar rowCount = metadata.GetTableRowCount(TableIndex.FieldLayout);\n\t\t\tfor (int row = 1; row <= rowCount; row++)\n\t\t\t{\n\t\t\t\tyield return MetadataTokens.EntityHandle(TableIndex.FieldLayout, row);\n\t\t\t}\n\t\t}\n\n\t\tpublic static (int Offset, FieldDefinitionHandle FieldDef) GetFieldLayout(this MetadataReader metadata, EntityHandle fieldLayoutHandle)\n\t\t{\n\t\t\tvar startPointer = metadata.AsReadOnlySpan();\n\t\t\tint offset = metadata.GetTableMetadataOffset(TableIndex.FieldLayout);\n\t\t\tint rowSize = metadata.GetTableRowSize(TableIndex.FieldLayout);\n\t\t\tint rowCount = metadata.GetTableRowCount(TableIndex.FieldLayout);\n\n\t\t\tint fieldRowNo = metadata.GetRowNumber(fieldLayoutHandle);\n\t\t\tbool small = metadata.GetTableRowCount(TableIndex.Field) <= ushort.MaxValue;\n\t\t\tfor (int row = rowCount - 1; row >= 0; row--)\n\t\t\t{\n\t\t\t\tReadOnlySpan<byte> ptr = startPointer.Slice(offset + rowSize * row);\n\t\t\t\tvar rowNoSpan = ptr.Slice(4);\n\t\t\t\tuint rowNo = small ? BinaryPrimitives.ReadUInt16LittleEndian(rowNoSpan) : BinaryPrimitives.ReadUInt32LittleEndian(rowNoSpan);\n\t\t\t\tif (fieldRowNo == rowNo)\n\t\t\t\t{\n\t\t\t\t\treturn (BinaryPrimitives.ReadInt32LittleEndian(ptr), MetadataTokens.FieldDefinitionHandle(fieldRowNo));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn (0, default);\n\t\t}\n\n\t\tpublic static ReadOnlySpan<byte> AsReadOnlySpan(this MetadataReader metadataReader)\n\t\t{\n\t\t\tunsafe\n\t\t\t{\n\t\t\t\treturn new(metadataReader.MetadataPointer, metadataReader.MetadataLength);\n\t\t\t}\n\t\t}\n\n\t\tpublic static BlobReader AsBlobReader(this MetadataReader metadataReader)\n\t\t{\n\t\t\tunsafe\n\t\t\t{\n\t\t\t\treturn new(metadataReader.MetadataPointer, metadataReader.MetadataLength);\n\t\t\t}\n\t\t}\n\n\t\tpublic static uint ReadULEB128(this BinaryReader reader)\n\t\t{\n\t\t\tuint val = 0;\n\t\t\tint shift = 0;\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tbyte b = reader.ReadByte();\n\t\t\t\tval |= (b & 0b0111_1111u) << shift;\n\t\t\t\tif ((b & 0b1000_0000) == 0)\n\t\t\t\t\tbreak;\n\t\t\t\tshift += 7;\n\t\t\t\tif (shift >= 35)\n\t\t\t\t\tthrow new OverflowException();\n\t\t\t}\n\t\t\treturn val;\n\t\t}\n\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/MetadataFile.cs",
    "content": "// Copyright (c) 2024 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.PortableExecutable;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\t/// <summary>\n\t/// MetadataFile is the main class the decompiler uses to represent a metadata assembly/module.\n\t/// Every file on disk can be loaded into a standalone MetadataFile instance.\n\t/// \n\t/// A MetadataFile can be combined with its referenced assemblies/modules to form a type system,\n\t/// in that case the <see cref=\"MetadataModule\"/> class is used instead.\n\t/// </summary>\n\t/// <remarks>\n\t/// In addition to wrapping a <c>System.Reflection.Metadata.MetadataReader</c>, this class\n\t/// contains a few decompiler-specific caches to allow efficiently constructing a type\n\t/// system from multiple MetadataFiles. This allows the caches to be shared across multiple\n\t/// decompiled type systems.\n\t/// </remarks>\n\t[DebuggerDisplay(\"{Kind}: {FileName}\")]\n\tpublic class MetadataFile\n\t{\n\t\tpublic enum MetadataFileKind\n\t\t{\n\t\t\tPortableExecutable,\n\t\t\tProgramDebugDatabase,\n\t\t\tWebCIL,\n\t\t\tMetadata\n\t\t}\n\n\t\tpublic string FileName { get; }\n\t\tpublic MetadataFileKind Kind { get; }\n\t\tpublic MetadataReader Metadata { get; }\n\n\t\tpublic virtual int MetadataOffset { get; }\n\t\tpublic virtual bool IsEmbedded { get; }\n\t\tpublic virtual bool IsMetadataOnly { get; } = true;\n\n\t\tpublic bool IsAssembly => Metadata.IsAssembly;\n\n\t\tstring? name;\n\n\t\tpublic string Name {\n\t\t\tget {\n\t\t\t\tvar value = LazyInit.VolatileRead(ref name);\n\t\t\t\tif (value == null)\n\t\t\t\t{\n\t\t\t\t\tvar metadata = Metadata;\n\t\t\t\t\tif (metadata.IsAssembly)\n\t\t\t\t\t\tvalue = metadata.GetString(metadata.GetAssemblyDefinition().Name);\n\t\t\t\t\telse if (metadata.DebugMetadataHeader == null) // standalone debug metadata does not contain module table\n\t\t\t\t\t\tvalue = metadata.GetString(metadata.GetModuleDefinition().Name);\n\t\t\t\t\telse\n\t\t\t\t\t\tvalue = \"debug metadata\";\n\t\t\t\t\tvalue = LazyInit.GetOrSet(ref name, value);\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\n\t\tstring? fullName;\n\n\t\tpublic string FullName {\n\t\t\tget {\n\t\t\t\tvar value = LazyInit.VolatileRead(ref fullName);\n\t\t\t\tif (value == null)\n\t\t\t\t{\n\t\t\t\t\tvar metadata = Metadata;\n\t\t\t\t\tvalue = metadata.IsAssembly ? metadata.GetFullAssemblyName() : Name;\n\t\t\t\t\tvalue = LazyInit.GetOrSet(ref fullName, value);\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\n\t\tpublic TargetRuntime GetRuntime()\n\t\t{\n\t\t\tstring version = Metadata.MetadataVersion;\n\t\t\tif (version == null || version.Length <= 1)\n\t\t\t\treturn TargetRuntime.Unknown;\n\t\t\tswitch (version[1])\n\t\t\t{\n\t\t\t\tcase '1':\n\t\t\t\t\tif (version.Length <= 3)\n\t\t\t\t\t\treturn TargetRuntime.Unknown;\n\t\t\t\t\tif (version[3] == 1)\n\t\t\t\t\t\treturn TargetRuntime.Net_1_0;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn TargetRuntime.Net_1_1;\n\t\t\t\tcase '2':\n\t\t\t\t\treturn TargetRuntime.Net_2_0;\n\t\t\t\tcase '4':\n\t\t\t\t\treturn TargetRuntime.Net_4_0;\n\t\t\t\tdefault:\n\t\t\t\t\treturn TargetRuntime.Unknown;\n\t\t\t}\n\t\t}\n\n\t\tImmutableArray<AssemblyReference> assemblyReferences;\n\t\tpublic ImmutableArray<AssemblyReference> AssemblyReferences {\n\t\t\tget {\n\t\t\t\tvar value = assemblyReferences;\n\t\t\t\tif (value.IsDefault)\n\t\t\t\t{\n\t\t\t\t\tvalue = Metadata.AssemblyReferences.Select(r => new AssemblyReference(this.Metadata, r)).ToImmutableArray();\n\t\t\t\t\tassemblyReferences = value;\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\n\t\tImmutableArray<ModuleReferenceMetadata> moduleReferences;\n\t\tpublic ImmutableArray<ModuleReferenceMetadata> ModuleReferences {\n\t\t\tget {\n\t\t\t\tvar value = moduleReferences;\n\t\t\t\tif (value.IsDefault)\n\t\t\t\t{\n\t\t\t\t\tvalue = Metadata.GetModuleReferences()\n\t\t\t\t\t\t\t.Select(m => new ModuleReferenceMetadata(this.Metadata, m))\n\t\t\t\t\t\t\t.ToImmutableArray();\n\n\t\t\t\t\tmoduleReferences = value;\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\n\t\tpublic ImmutableArray<Resource> Resources => GetResources().ToImmutableArray();\n\n\t\tIEnumerable<Resource> GetResources()\n\t\t{\n\t\t\tvar metadata = Metadata;\n\t\t\tforeach (var h in metadata.ManifestResources)\n\t\t\t{\n\t\t\t\tyield return new MetadataResource(this, h);\n\t\t\t}\n\t\t}\n\n\t\tDictionary<TopLevelTypeName, TypeDefinitionHandle>? typeLookup;\n\n\t\t/// <summary>\n\t\t/// Finds the top-level-type with the specified name.\n\t\t/// </summary>\n\t\tpublic TypeDefinitionHandle GetTypeDefinition(TopLevelTypeName typeName)\n\t\t{\n\t\t\tvar lookup = LazyInit.VolatileRead(ref typeLookup);\n\t\t\tif (lookup == null)\n\t\t\t{\n\t\t\t\tlookup = new Dictionary<TopLevelTypeName, TypeDefinitionHandle>();\n\t\t\t\tforeach (var handle in Metadata.TypeDefinitions)\n\t\t\t\t{\n\t\t\t\t\tvar td = Metadata.GetTypeDefinition(handle);\n\t\t\t\t\tif (!td.GetDeclaringType().IsNil)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue; // nested type\n\t\t\t\t\t}\n\t\t\t\t\tvar nsHandle = td.Namespace;\n\t\t\t\t\tstring ns = nsHandle.IsNil ? string.Empty : Metadata.GetString(nsHandle);\n\t\t\t\t\tstring name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(Metadata.GetString(td.Name), out int typeParameterCount);\n\t\t\t\t\tlookup[new TopLevelTypeName(ns, name, typeParameterCount)] = handle;\n\t\t\t\t}\n\t\t\t\tlookup = LazyInit.GetOrSet(ref typeLookup, lookup);\n\t\t\t}\n\t\t\tif (lookup.TryGetValue(typeName, out var resultHandle))\n\t\t\t\treturn resultHandle;\n\t\t\telse\n\t\t\t\treturn default;\n\t\t}\n\n\t\tDictionary<FullTypeName, ExportedTypeHandle>? typeForwarderLookup;\n\n\t\t/// <summary>\n\t\t/// Finds the type forwarder with the specified name.\n\t\t/// </summary>\n\t\tpublic ExportedTypeHandle GetTypeForwarder(FullTypeName typeName)\n\t\t{\n\t\t\tvar lookup = LazyInit.VolatileRead(ref typeForwarderLookup);\n\t\t\tif (lookup == null)\n\t\t\t{\n\t\t\t\tlookup = new Dictionary<FullTypeName, ExportedTypeHandle>();\n\t\t\t\tforeach (var handle in Metadata.ExportedTypes)\n\t\t\t\t{\n\t\t\t\t\tvar td = Metadata.GetExportedType(handle);\n\t\t\t\t\tlookup[td.GetFullTypeName(Metadata)] = handle;\n\t\t\t\t}\n\t\t\t\tlookup = LazyInit.GetOrSet(ref typeForwarderLookup, lookup);\n\t\t\t}\n\t\t\tif (lookup.TryGetValue(typeName, out var resultHandle))\n\t\t\t\treturn resultHandle;\n\t\t\telse\n\t\t\t\treturn default;\n\t\t}\n\n\t\tMethodSemanticsLookup? methodSemanticsLookup;\n\n\t\tinternal MethodSemanticsLookup MethodSemanticsLookup {\n\t\t\tget {\n\t\t\t\tvar r = LazyInit.VolatileRead(ref methodSemanticsLookup);\n\t\t\t\tif (r != null)\n\t\t\t\t\treturn r;\n\t\t\t\telse\n\t\t\t\t\treturn LazyInit.GetOrSet(ref methodSemanticsLookup, new MethodSemanticsLookup(Metadata));\n\t\t\t}\n\t\t}\n\n\t\tPropertyAndEventBackingFieldLookup? propertyAndEventBackingFieldLookup;\n\n\t\tinternal PropertyAndEventBackingFieldLookup PropertyAndEventBackingFieldLookup {\n\t\t\tget {\n\t\t\t\tvar r = LazyInit.VolatileRead(ref propertyAndEventBackingFieldLookup);\n\t\t\t\tif (r != null)\n\t\t\t\t\treturn r;\n\t\t\t\telse\n\t\t\t\t\treturn LazyInit.GetOrSet(ref propertyAndEventBackingFieldLookup, new PropertyAndEventBackingFieldLookup(Metadata));\n\t\t\t}\n\t\t}\n\n\t\tpublic MetadataFile(MetadataFileKind kind, string fileName, MetadataReaderProvider metadata, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default, int metadataOffset = 0, bool isEmbedded = false, MetadataStringDecoder? utf8Decoder = null)\n\t\t{\n\t\t\tthis.Kind = kind;\n\t\t\tthis.FileName = fileName;\n\t\t\tthis.Metadata = metadata.GetMetadataReader(metadataOptions, utf8Decoder);\n\t\t\tthis.MetadataOffset = metadataOffset;\n\t\t\tthis.IsEmbedded = isEmbedded;\n\t\t}\n\n\t\tpublic MetadataFile(MetadataFileKind kind, string fileName, MetadataReader metadataReader, int metadataOffset = 0, bool isEmbedded = false)\n\t\t{\n\t\t\tthis.Kind = kind;\n\t\t\tthis.FileName = fileName;\n\t\t\tthis.Metadata = metadataReader;\n\t\t\tthis.MetadataOffset = metadataOffset;\n\t\t\tthis.IsEmbedded = isEmbedded;\n\t\t}\n\n\t\tprivate protected MetadataFile(MetadataFileKind kind, string fileName, PEReader reader, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default, MetadataStringDecoder? utf8Decoder = null)\n\t\t{\n\t\t\tthis.Kind = kind;\n\t\t\tthis.FileName = fileName ?? throw new ArgumentNullException(nameof(fileName));\n\t\t\t_ = reader ?? throw new ArgumentNullException(nameof(reader));\n\t\t\tif (!reader.HasMetadata)\n\t\t\t\tthrow new MetadataFileNotSupportedException(\"PE file does not contain any managed metadata.\");\n\t\t\tthis.Metadata = reader.GetMetadataReader(metadataOptions, utf8Decoder);\n\t\t}\n\n\t\tpublic virtual MethodBodyBlock GetMethodBody(int rva)\n\t\t{\n\t\t\tthrow new BadImageFormatException(\"This metadata file does not contain method bodies.\");\n\t\t}\n\n\t\tpublic virtual SectionData GetSectionData(int rva)\n\t\t{\n\t\t\tthrow new BadImageFormatException(\"This metadata file does not support sections.\");\n\t\t}\n\n\t\tpublic virtual int GetContainingSectionIndex(int rva)\n\t\t{\n\t\t\tthrow new BadImageFormatException(\"This metadata file does not support sections.\");\n\t\t}\n\n\t\tpublic virtual ImmutableArray<SectionHeader> SectionHeaders => throw new BadImageFormatException(\"This metadata file does not support sections.\");\n\n\t\t/// <summary>\n\t\t/// Gets the CLI header or null if the image does not have one.\n\t\t/// </summary>\n\t\tpublic virtual CorHeader? CorHeader => null;\n\n\t\tpublic IModuleReference WithOptions(TypeSystemOptions options)\n\t\t{\n\t\t\treturn new MetadataFileWithOptions(this, options);\n\t\t}\n\n\t\tprivate class MetadataFileWithOptions : IModuleReference\n\t\t{\n\t\t\treadonly MetadataFile peFile;\n\t\t\treadonly TypeSystemOptions options;\n\n\t\t\tpublic MetadataFileWithOptions(MetadataFile peFile, TypeSystemOptions options)\n\t\t\t{\n\t\t\t\tthis.peFile = peFile;\n\t\t\t\tthis.options = options;\n\t\t\t}\n\n\t\t\tIModule IModuleReference.Resolve(ITypeResolveContext context)\n\t\t\t{\n\t\t\t\treturn new MetadataModule(context.Compilation, peFile, options);\n\t\t\t}\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Abstraction over PEMemoryBlock\n\t/// </summary>\n\tpublic readonly unsafe struct SectionData\n\t{\n\t\tpublic byte* Pointer { get; }\n\t\tpublic int Length { get; }\n\n\t\tpublic SectionData(PEMemoryBlock block)\n\t\t{\n\t\t\tPointer = block.Pointer;\n\t\t\tLength = block.Length;\n\t\t}\n\n\t\tpublic SectionData(byte* startPointer, int length)\n\t\t{\n\t\t\tPointer = startPointer;\n\t\t\tLength = length;\n\t\t}\n\n\t\tpublic BlobReader GetReader()\n\t\t{\n\t\t\treturn new BlobReader(Pointer, Length);\n\t\t}\n\n\t\tinternal BlobReader GetReader(int offset, int size)\n\t\t{\n\t\t\treturn new BlobReader(Pointer + offset, size);\n\t\t}\n\t}\n\n\tpublic struct SectionHeader\n\t{\n\t\tpublic string Name;\n\t\tpublic uint VirtualSize;\n\t\tpublic uint VirtualAddress;\n\t\tpublic uint RawDataSize;\n\t\tpublic uint RawDataPtr;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/MetadataGenericContext.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\tpublic readonly struct MetadataGenericContext\n\t{\n\t\treadonly MetadataReader? metadata;\n\t\treadonly TypeDefinitionHandle declaringType;\n\t\treadonly MethodDefinitionHandle method;\n\n\t\tpublic MetadataGenericContext(MethodDefinitionHandle method, MetadataFile module)\n\t\t{\n\t\t\tthis.metadata = module.Metadata;\n\t\t\tthis.method = method;\n\t\t\tthis.declaringType = module.Metadata.GetMethodDefinition(method).GetDeclaringType();\n\t\t}\n\n\t\tpublic MetadataGenericContext(MethodDefinitionHandle method, MetadataReader metadata)\n\t\t{\n\t\t\tthis.metadata = metadata;\n\t\t\tthis.method = method;\n\t\t\tthis.declaringType = metadata.GetMethodDefinition(method).GetDeclaringType();\n\t\t}\n\n\t\tpublic MetadataGenericContext(TypeDefinitionHandle declaringType, MetadataFile module)\n\t\t{\n\t\t\tthis.metadata = module.Metadata;\n\t\t\tthis.method = default;\n\t\t\tthis.declaringType = declaringType;\n\t\t}\n\n\t\tpublic MetadataGenericContext(TypeDefinitionHandle declaringType, MetadataReader metadata)\n\t\t{\n\t\t\tthis.metadata = metadata;\n\t\t\tthis.method = default;\n\t\t\tthis.declaringType = declaringType;\n\t\t}\n\n\t\tpublic string GetGenericTypeParameterName(int index)\n\t\t{\n\t\t\tGenericParameterHandle genericParameter = GetGenericTypeParameterHandleOrNull(index);\n\t\t\tif (genericParameter.IsNil || metadata == null)\n\t\t\t\treturn index.ToString();\n\t\t\treturn metadata.GetString(metadata.GetGenericParameter(genericParameter).Name);\n\t\t}\n\n\t\tpublic string GetGenericMethodTypeParameterName(int index)\n\t\t{\n\t\t\tGenericParameterHandle genericParameter = GetGenericMethodTypeParameterHandleOrNull(index);\n\t\t\tif (genericParameter.IsNil || metadata == null)\n\t\t\t\treturn index.ToString();\n\t\t\treturn metadata.GetString(metadata.GetGenericParameter(genericParameter).Name);\n\t\t}\n\n\t\tpublic GenericParameterHandle GetGenericTypeParameterHandleOrNull(int index)\n\t\t{\n\t\t\tif (declaringType.IsNil || index < 0 || metadata == null)\n\t\t\t\treturn MetadataTokens.GenericParameterHandle(0);\n\t\t\tvar genericParameters = metadata.GetTypeDefinition(declaringType).GetGenericParameters();\n\t\t\tif (index >= genericParameters.Count)\n\t\t\t\treturn MetadataTokens.GenericParameterHandle(0);\n\t\t\treturn genericParameters[index];\n\t\t}\n\n\t\tpublic GenericParameterHandle GetGenericMethodTypeParameterHandleOrNull(int index)\n\t\t{\n\t\t\tif (method.IsNil || index < 0 || metadata == null)\n\t\t\t\treturn MetadataTokens.GenericParameterHandle(0);\n\t\t\tvar genericParameters = metadata.GetMethodDefinition(method).GetGenericParameters();\n\t\t\tif (index >= genericParameters.Count)\n\t\t\t\treturn MetadataTokens.GenericParameterHandle(0);\n\t\t\treturn genericParameters[index];\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/MetadataTokenHelpers.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\tpublic static class MetadataTokenHelpers\n\t{\n\t\tpublic static EntityHandle? TryAsEntityHandle(int metadataToken)\n\t\t{\n\t\t\t// SRM would interpret negative token values as virtual tokens,\n\t\t\t// but that causes problems later on.\n\t\t\tif (metadataToken < 0)\n\t\t\t\treturn null;\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn MetadataTokens.EntityHandle(metadataToken);\n\t\t\t}\n\t\t\tcatch (ArgumentException)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tpublic static EntityHandle EntityHandleOrNil(int metadataToken)\n\t\t{\n\t\t\t// SRM would interpret negative token values as virtual tokens,\n\t\t\t// but that causes problems later on.\n\t\t\tif (metadataToken < 0)\n\t\t\t\treturn MetadataTokens.EntityHandle(0);\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn MetadataTokens.EntityHandle(metadataToken);\n\t\t\t}\n\t\t\tcatch (ArgumentException)\n\t\t\t{\n\t\t\t\treturn MetadataTokens.EntityHandle(0);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/MethodSemanticsLookup.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\t/// <summary>\n\t/// Lookup structure that, for an accessor, can find the associated property/event.\n\t/// </summary>\n\tclass MethodSemanticsLookup\n\t{\n\t\tconst MethodSemanticsAttributes csharpAccessors =\n\t\t\tMethodSemanticsAttributes.Getter | MethodSemanticsAttributes.Setter\n\t\t\t| MethodSemanticsAttributes.Adder | MethodSemanticsAttributes.Remover;\n\n\t\treadonly struct Entry : IComparable<Entry>\n\t\t{\n\t\t\tpublic readonly MethodSemanticsAttributes Semantics;\n\t\t\tpublic readonly int MethodRowNumber;\n\t\t\tpublic MethodDefinitionHandle Method => MetadataTokens.MethodDefinitionHandle(MethodRowNumber);\n\t\t\tpublic readonly EntityHandle Association;\n\n\t\t\tpublic Entry(MethodSemanticsAttributes semantics, MethodDefinitionHandle method, EntityHandle association)\n\t\t\t{\n\t\t\t\tSemantics = semantics;\n\t\t\t\tMethodRowNumber = MetadataTokens.GetRowNumber(method);\n\t\t\t\tAssociation = association;\n\t\t\t}\n\n\t\t\tpublic int CompareTo(Entry other)\n\t\t\t{\n\t\t\t\treturn MethodRowNumber.CompareTo(other.MethodRowNumber);\n\t\t\t}\n\t\t}\n\n\t\t// entries, sorted by MethodRowNumber\n\t\treadonly List<Entry> entries;\n\n\t\tpublic MethodSemanticsLookup(MetadataReader metadata, MethodSemanticsAttributes filter = csharpAccessors)\n\t\t{\n\t\t\tif ((filter & MethodSemanticsAttributes.Other) != 0)\n\t\t\t{\n\t\t\t\tthrow new NotSupportedException(\"SRM doesn't provide access to 'other' accessors\");\n\t\t\t}\n\t\t\tentries = new List<Entry>(metadata.GetTableRowCount(TableIndex.MethodSemantics));\n\t\t\tforeach (var propHandle in metadata.PropertyDefinitions)\n\t\t\t{\n\t\t\t\tvar prop = metadata.GetPropertyDefinition(propHandle);\n\t\t\t\tvar accessors = prop.GetAccessors();\n\t\t\t\tAddEntry(MethodSemanticsAttributes.Getter, accessors.Getter, propHandle);\n\t\t\t\tAddEntry(MethodSemanticsAttributes.Setter, accessors.Setter, propHandle);\n\t\t\t}\n\t\t\tforeach (var eventHandle in metadata.EventDefinitions)\n\t\t\t{\n\t\t\t\tvar ev = metadata.GetEventDefinition(eventHandle);\n\t\t\t\tvar accessors = ev.GetAccessors();\n\t\t\t\tAddEntry(MethodSemanticsAttributes.Adder, accessors.Adder, eventHandle);\n\t\t\t\tAddEntry(MethodSemanticsAttributes.Remover, accessors.Remover, eventHandle);\n\t\t\t\tAddEntry(MethodSemanticsAttributes.Raiser, accessors.Raiser, eventHandle);\n\t\t\t}\n\t\t\tentries.Sort();\n\n\t\t\tvoid AddEntry(MethodSemanticsAttributes semantics, MethodDefinitionHandle method, EntityHandle association)\n\t\t\t{\n\t\t\t\tif ((semantics & filter) == 0 || method.IsNil)\n\t\t\t\t\treturn;\n\t\t\t\tentries.Add(new Entry(semantics, method, association));\n\t\t\t}\n\t\t}\n\n\t\tpublic (EntityHandle, MethodSemanticsAttributes) GetSemantics(MethodDefinitionHandle method)\n\t\t{\n\t\t\tint pos = entries.BinarySearch(new Entry(0, method, default(EntityHandle)));\n\t\t\tif (pos >= 0)\n\t\t\t{\n\t\t\t\treturn (entries[pos].Association, entries[pos].Semantics);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn (default(EntityHandle), 0);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/ModuleReferenceMetadata.cs",
    "content": "// Copyright (c) 2023 James May\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n#if !VSADDIN\n\tpublic class ModuleReferenceMetadata /* : IModuleReference*/\n\t{\n\t\treadonly ModuleReference entry;\n\n\t\tpublic MetadataReader Metadata { get; }\n\t\tpublic ModuleReferenceHandle Handle { get; }\n\n\t\tstring? name;\n\t\tpublic string Name {\n\t\t\tget {\n\t\t\t\tif (name == null)\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tname = Metadata.GetString(entry.Name);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t{\n\t\t\t\t\t\tname = $\"AR:{Handle}\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn name;\n\t\t\t}\n\t\t}\n\n\t\tImmutableArray<CustomAttribute> attributes;\n\t\tpublic ImmutableArray<CustomAttribute> Attributes {\n\t\t\tget {\n\t\t\t\tvar value = attributes;\n\t\t\t\tif (value.IsDefault)\n\t\t\t\t{\n\t\t\t\t\tvalue = entry.GetCustomAttributes().Select(Metadata.GetCustomAttribute).ToImmutableArray();\n\t\t\t\t\tattributes = value;\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\n\t\tImmutableArray<TypeReferenceMetadata> typeReferences;\n\t\tpublic ImmutableArray<TypeReferenceMetadata> TypeReferences {\n\t\t\tget {\n\t\t\t\tvar value = typeReferences;\n\t\t\t\tif (value.IsDefault)\n\t\t\t\t{\n\t\t\t\t\tvalue = Metadata.TypeReferences\n\t\t\t\t\t\t.Select(r => new TypeReferenceMetadata(Metadata, r))\n\t\t\t\t\t\t.Where(r => r.ResolutionScope == Handle)\n\t\t\t\t\t\t.OrderBy(r => r.Namespace)\n\t\t\t\t\t\t.ThenBy(r => r.Name)\n\t\t\t\t\t\t.ToImmutableArray();\n\t\t\t\t\ttypeReferences = value;\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\n\t\tImmutableArray<ExportedTypeMetadata> exportedTypes;\n\t\tpublic ImmutableArray<ExportedTypeMetadata> ExportedTypes {\n\t\t\tget {\n\t\t\t\tvar value = exportedTypes;\n\t\t\t\tif (value.IsDefault)\n\t\t\t\t{\n\t\t\t\t\tvalue = Metadata.ExportedTypes\n\t\t\t\t\t\t.Select(r => new ExportedTypeMetadata(Metadata, r))\n\t\t\t\t\t\t.Where(r => r.Implementation == Handle)\n\t\t\t\t\t\t.OrderBy(r => r.Namespace)\n\t\t\t\t\t\t.ThenBy(r => r.Name)\n\t\t\t\t\t\t.ToImmutableArray();\n\t\t\t\t\texportedTypes = value;\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\n\t\tpublic ModuleReferenceMetadata(MetadataReader metadata, ModuleReferenceHandle handle)\n\t\t{\n\t\t\tif (metadata == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(metadata));\n\t\t\tif (handle.IsNil)\n\t\t\t\tthrow new ArgumentNullException(nameof(handle));\n\t\t\tMetadata = metadata;\n\t\t\tHandle = handle;\n\t\t\tentry = metadata.GetModuleReference(handle);\n\t\t}\n\n\t\tpublic ModuleReferenceMetadata(PEFile module, ModuleReferenceHandle handle)\n\t\t{\n\t\t\tif (module == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(module));\n\t\t\tif (handle.IsNil)\n\t\t\t\tthrow new ArgumentNullException(nameof(handle));\n\t\t\tMetadata = module.Metadata;\n\t\t\tHandle = handle;\n\t\t\tentry = Metadata.GetModuleReference(handle);\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn Name;\n\t\t}\n\t}\n#endif\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/OperandType.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\tpublic enum OperandType\n\t{\n\t\tBrTarget,\n\t\tField,\n\t\tI,\n\t\tI8,\n\t\tMethod,\n\t\tNone,\n\t\tR = 7,\n\t\tSig = 9,\n\t\tString,\n\t\tSwitch,\n\t\tTok,\n\t\tType,\n\t\tVariable,\n\t\tShortBrTarget,\n\t\tShortI,\n\t\tShortR,\n\t\tShortVariable\n\t}\n\n\tpublic static partial class ILOpCodeExtensions\n\t{\n\t\tpublic static OperandType GetOperandType(this ILOpCode opCode)\n\t\t{\n\t\t\tushort index = (ushort)((((int)opCode & 0x200) >> 1) | ((int)opCode & 0xff));\n\t\t\tif (index >= operandTypes.Length)\n\t\t\t\treturn (OperandType)255;\n\t\t\treturn (OperandType)operandTypes[index];\n\t\t}\n\n\t\tpublic static string GetDisplayName(this ILOpCode opCode)\n\t\t{\n\t\t\tushort index = (ushort)((((int)opCode & 0x200) >> 1) | ((int)opCode & 0xff));\n\t\t\tif (index >= operandNames.Length)\n\t\t\t\treturn \"\";\n\t\t\treturn operandNames[index];\n\t\t}\n\n\t\tpublic static bool IsDefined(this ILOpCode opCode)\n\t\t{\n\t\t\treturn !string.IsNullOrEmpty(GetDisplayName(opCode));\n\t\t}\n\n\t\tstatic ILOpCodeExtensions()\n\t\t{\n\t\t\tILKeywords = BuildKeywordList(\n\t\t\t\t\"abstract\", \"algorithm\", \"alignment\", \"ansi\", \"any\", \"arglist\",\n\t\t\t\t\"array\", \"as\", \"assembly\", \"assert\", \"at\", \"auto\", \"autochar\", \"beforefieldinit\",\n\t\t\t\t\"blob\", \"blob_object\", \"bool\", \"brnull\", \"brnull.s\", \"brzero\", \"brzero.s\", \"bstr\",\n\t\t\t\t\"bytearray\", \"byvalstr\", \"callmostderived\", \"carray\", \"catch\", \"cdecl\", \"cf\",\n\t\t\t\t\"char\", \"cil\", \"class\", \"clsid\", \"const\", \"currency\", \"custom\", \"date\", \"decimal\",\n\t\t\t\t\"default\", \"demand\", \"deny\", \"endmac\", \"enum\", \"error\", \"explicit\", \"extends\", \"extern\",\n\t\t\t\t\"false\", \"famandassem\", \"family\", \"famorassem\", \"fastcall\", \"fault\", \"field\", \"filetime\",\n\t\t\t\t\"filter\", \"final\", \"finally\", \"fixed\", \"float\", \"float32\", \"float64\", \"forwardref\",\n\t\t\t\t\"fromunmanaged\", \"handler\", \"hidebysig\", \"hresult\", \"idispatch\", \"il\", \"illegal\",\n\t\t\t\t\"implements\", \"implicitcom\", \"implicitres\", \"import\", \"in\", \"inheritcheck\", \"init\",\n\t\t\t\t\"initonly\", \"instance\", \"int\", \"int16\", \"int32\", \"int64\", \"int8\", \"interface\", \"internalcall\",\n\t\t\t\t\"iunknown\", \"lasterr\", \"lcid\", \"linkcheck\", \"literal\", \"localloc\", \"lpstr\", \"lpstruct\", \"lptstr\",\n\t\t\t\t\"lpvoid\", \"lpwstr\", \"managed\", \"marshal\", \"method\", \"modopt\", \"modreq\", \"native\", \"nested\",\n\t\t\t\t\"newslot\", \"noappdomain\", \"noinlining\", \"nomachine\", \"nomangle\", \"nometadata\", \"noncasdemand\",\n\t\t\t\t\"noncasinheritance\", \"noncaslinkdemand\", \"noprocess\", \"not\", \"not_in_gc_heap\", \"notremotable\",\n\t\t\t\t\"notserialized\", \"null\", \"nullref\", \"object\", \"objectref\", \"opt\", \"optil\", \"out\",\n\t\t\t\t\"permitonly\", \"pinned\", \"pinvokeimpl\", \"prefix1\", \"prefix2\", \"prefix3\", \"prefix4\", \"prefix5\", \"prefix6\",\n\t\t\t\t\"prefix7\", \"prefixref\", \"prejitdeny\", \"prejitgrant\", \"preservesig\", \"private\", \"privatescope\", \"protected\",\n\t\t\t\t\"public\", \"record\", \"refany\", \"reqmin\", \"reqopt\", \"reqrefuse\", \"reqsecobj\", \"request\", \"retval\",\n\t\t\t\t\"rtspecialname\", \"runtime\", \"safearray\", \"sealed\", \"sequential\", \"serializable\", \"special\", \"specialname\",\n\t\t\t\t\"static\", \"stdcall\", \"storage\", \"stored_object\", \"stream\", \"streamed_object\", \"string\", \"struct\",\n\t\t\t\t\"synchronized\", \"syschar\", \"sysstring\", \"tbstr\", \"thiscall\", \"tls\", \"to\", \"true\", \"typedref\",\n\t\t\t\t\"unicode\", \"unmanaged\", \"unmanagedexp\", \"unsigned\", \"unused\", \"userdefined\", \"value\", \"valuetype\",\n\t\t\t\t\"vararg\", \"variant\", \"vector\", \"virtual\", \"void\", \"wchar\", \"winapi\", \"with\", \"wrapper\",\n\n\t\t\t\t// These are not listed as keywords in spec, but ILAsm treats them as such\n\t\t\t\t\"property\", \"type\", \"flags\", \"codelabel\", \"callconv\", \"strict\",\n\t\t\t\t// ILDasm uses these keywords for unsigned integers\n\t\t\t\t\"uint8\", \"uint16\", \"uint32\", \"uint64\"\n\t\t\t);\n\t\t}\n\n\t\tpublic static readonly HashSet<string> ILKeywords;\n\n\t\tstatic HashSet<string> BuildKeywordList(params string[] keywords)\n\t\t{\n\t\t\tHashSet<string> s = new HashSet<string>(keywords);\n\t\t\tforeach (var inst in operandNames)\n\t\t\t{\n\t\t\t\tif (string.IsNullOrEmpty(inst))\n\t\t\t\t\tcontinue;\n\t\t\t\ts.Add(inst);\n\t\t\t}\n\t\t\treturn s;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/PEFile.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.PortableExecutable;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\t[DebuggerDisplay(\"{FileName}\")]\n\tpublic class PEFile : MetadataFile, IDisposable, IModuleReference\n\t{\n\t\tpublic PEReader Reader { get; }\n\n\t\tpublic PEFile(string fileName, PEStreamOptions streamOptions = PEStreamOptions.Default, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default, MetadataStringDecoder? utf8Decoder = null)\n\t\t\t: this(fileName, new PEReader(new FileStream(fileName, FileMode.Open, FileAccess.Read), streamOptions), metadataOptions, utf8Decoder)\n\t\t{\n\t\t}\n\n\t\tpublic PEFile(string fileName, Stream stream, PEStreamOptions streamOptions = PEStreamOptions.Default, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default, MetadataStringDecoder? utf8Decoder = null)\n\t\t\t: this(fileName, new PEReader(stream, streamOptions), metadataOptions, utf8Decoder)\n\t\t{\n\t\t}\n\n\t\tpublic PEFile(string fileName, PEReader reader, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default, MetadataStringDecoder? utf8Decoder = null)\n\t\t\t: base(MetadataFileKind.PortableExecutable, fileName, reader, metadataOptions, utf8Decoder)\n\t\t{\n\t\t\tthis.Reader = reader;\n\t\t}\n\n\t\tpublic override bool IsEmbedded => false;\n\t\tpublic override int MetadataOffset => Reader.PEHeaders.MetadataStartOffset;\n\t\tpublic override bool IsMetadataOnly => false;\n\n\t\tpublic void Dispose()\n\t\t{\n\t\t\tReader.Dispose();\n\t\t}\n\n\t\tIModule TypeSystem.IModuleReference.Resolve(ITypeResolveContext context)\n\t\t{\n\t\t\treturn new MetadataModule(context.Compilation, this, TypeSystemOptions.Default);\n\t\t}\n\n\t\tpublic override MethodBodyBlock GetMethodBody(int rva)\n\t\t{\n\t\t\treturn Reader.GetMethodBody(rva);\n\t\t}\n\n\t\tpublic override SectionData GetSectionData(int rva)\n\t\t{\n\t\t\treturn new SectionData(Reader.GetSectionData(rva));\n\t\t}\n\n\t\tpublic override int GetContainingSectionIndex(int rva)\n\t\t{\n\t\t\treturn Reader.PEHeaders.GetContainingSectionIndex(rva);\n\t\t}\n\n\t\tImmutableArray<SectionHeader> sectionHeaders;\n\t\tpublic override ImmutableArray<SectionHeader> SectionHeaders {\n\t\t\tget {\n\t\t\t\tvar value = sectionHeaders;\n\t\t\t\tif (value.IsDefault)\n\t\t\t\t{\n\t\t\t\t\tvalue = Reader.PEHeaders.SectionHeaders\n\t\t\t\t\t\t.Select(h => new SectionHeader {\n\t\t\t\t\t\t\tName = h.Name,\n\t\t\t\t\t\t\tRawDataPtr = unchecked((uint)h.PointerToRawData),\n\t\t\t\t\t\t\tRawDataSize = unchecked((uint)h.SizeOfRawData),\n\t\t\t\t\t\t\tVirtualAddress = unchecked((uint)h.VirtualAddress),\n\t\t\t\t\t\t\tVirtualSize = unchecked((uint)h.VirtualSize)\n\t\t\t\t\t\t}).ToImmutableArray();\n\t\t\t\t\tsectionHeaders = value;\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\n\t\tpublic override CorHeader? CorHeader => Reader.PEHeaders.CorHeader;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/PropertyAndEventBackingFieldLookup.cs",
    "content": "// Copyright (c) 2025 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\tclass PropertyAndEventBackingFieldLookup\n\t{\n\t\tprivate readonly MetadataReader metadata;\n\t\tprivate readonly Dictionary<FieldDefinitionHandle, PropertyDefinitionHandle> propertyLookup\n\t\t\t= new();\n\t\tprivate readonly Dictionary<FieldDefinitionHandle, EventDefinitionHandle> eventLookup\n\t\t\t= new();\n\n\t\tpublic PropertyAndEventBackingFieldLookup(MetadataReader metadata)\n\t\t{\n\t\t\tthis.metadata = metadata;\n\n\t\t\tvar nameToFieldMap = new MultiDictionary<string, FieldDefinitionHandle>();\n\n\t\t\tHashSet<string> eventNames = new();\n\n\t\t\tforeach (var tdh in metadata.TypeDefinitions)\n\t\t\t{\n\t\t\t\tvar type = metadata.GetTypeDefinition(tdh);\n\n\t\t\t\tforeach (var fdh in type.GetFields())\n\t\t\t\t{\n\t\t\t\t\tvar field = metadata.GetFieldDefinition(fdh);\n\t\t\t\t\tvar name = metadata.GetString(field.Name);\n\t\t\t\t\tnameToFieldMap.Add(name, fdh);\n\t\t\t\t}\n\n\t\t\t\tforeach (var pdh in type.GetProperties())\n\t\t\t\t{\n\t\t\t\t\tvar property = metadata.GetPropertyDefinition(pdh);\n\t\t\t\t\tvar name = metadata.GetString(property.Name);\n\t\t\t\t\t// default C# property backing field name is \"<PropertyName>k__BackingField\"\n\t\t\t\t\tif (nameToFieldMap.TryGetValues($\"<{name}>k__BackingField\", out var fieldHandles))\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var fieldHandle in fieldHandles)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpropertyLookup[fieldHandle] = pdh;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (nameToFieldMap.TryGetValues($\"_{name}\", out fieldHandles))\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var fieldHandle in fieldHandles)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (fieldHandle.IsCompilerGenerated(metadata))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tpropertyLookup[fieldHandle] = pdh;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// first get all names of events defined, so that we can make sure we don't accidentally\n\t\t\t\t// associate the wrong backing field with the event, in case there is an event called \"Something\"\n\t\t\t\t// without a backing field (i.e., custom event) as well as an auto/field event called \"SomethingEvent\"\n\t\t\t\t// declared in the same type.\n\t\t\t\tforeach (var edh in type.GetEvents())\n\t\t\t\t{\n\t\t\t\t\tvar ev = metadata.GetEventDefinition(edh);\n\t\t\t\t\teventNames.Add(metadata.GetString(ev.Name));\n\t\t\t\t}\n\n\t\t\t\tforeach (var edh in type.GetEvents())\n\t\t\t\t{\n\t\t\t\t\tvar ev = metadata.GetEventDefinition(edh);\n\t\t\t\t\tvar name = metadata.GetString(ev.Name);\n\t\t\t\t\tif (nameToFieldMap.TryGetValues(name, out var fieldHandles))\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var fieldHandle in fieldHandles)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventLookup[fieldHandle] = edh;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tvar nameWithSuffix = $\"{name}Event\";\n\t\t\t\t\t\tif (!eventNames.Contains(nameWithSuffix) && nameToFieldMap.TryGetValues(nameWithSuffix, out fieldHandles))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tforeach (var fieldHandle in fieldHandles)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\teventLookup[fieldHandle] = edh;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\teventNames.Clear();\n\t\t\t\tnameToFieldMap.Clear();\n\t\t\t}\n\t\t}\n\n\t\tpublic bool IsPropertyBackingField(FieldDefinitionHandle field, out PropertyDefinitionHandle handle)\n\t\t{\n\t\t\treturn propertyLookup.TryGetValue(field, out handle);\n\t\t}\n\n\t\tpublic bool IsEventBackingField(FieldDefinitionHandle field, out EventDefinitionHandle handle)\n\t\t{\n\t\t\treturn eventLookup.TryGetValue(field, out handle);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/ReferenceLoadInfo.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\tpublic class ReferenceLoadInfo\n\t{\n\t\treadonly Dictionary<string, UnresolvedAssemblyNameReference> loadedAssemblyReferences = new Dictionary<string, UnresolvedAssemblyNameReference>();\n\n\t\tpublic void AddMessage(string fullName, MessageKind kind, string message)\n\t\t{\n\t\t\tlock (loadedAssemblyReferences)\n\t\t\t{\n\t\t\t\tif (!loadedAssemblyReferences.TryGetValue(fullName, out var referenceInfo))\n\t\t\t\t{\n\t\t\t\t\treferenceInfo = new UnresolvedAssemblyNameReference(fullName);\n\t\t\t\t\tloadedAssemblyReferences.Add(fullName, referenceInfo);\n\t\t\t\t}\n\t\t\t\treferenceInfo.Messages.Add((kind, message));\n\t\t\t}\n\t\t}\n\n\t\tpublic void AddMessageOnce(string fullName, MessageKind kind, string message)\n\t\t{\n\t\t\tlock (loadedAssemblyReferences)\n\t\t\t{\n\t\t\t\tif (!loadedAssemblyReferences.TryGetValue(fullName, out var referenceInfo))\n\t\t\t\t{\n\t\t\t\t\treferenceInfo = new UnresolvedAssemblyNameReference(fullName);\n\t\t\t\t\tloadedAssemblyReferences.Add(fullName, referenceInfo);\n\t\t\t\t\treferenceInfo.Messages.Add((kind, message));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar lastMsg = referenceInfo.Messages.LastOrDefault();\n\t\t\t\t\tif (kind != lastMsg.Item1 && message != lastMsg.Item2)\n\t\t\t\t\t\treferenceInfo.Messages.Add((kind, message));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic bool TryGetInfo(string fullName, out UnresolvedAssemblyNameReference info)\n\t\t{\n\t\t\tlock (loadedAssemblyReferences)\n\t\t\t{\n\t\t\t\treturn loadedAssemblyReferences.TryGetValue(fullName, out info);\n\t\t\t}\n\t\t}\n\n\t\tpublic IReadOnlyList<UnresolvedAssemblyNameReference> Entries {\n\t\t\tget {\n\t\t\t\tlock (loadedAssemblyReferences)\n\t\t\t\t{\n\t\t\t\t\treturn loadedAssemblyReferences.Values.ToList();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic bool HasErrors {\n\t\t\tget {\n\t\t\t\tlock (loadedAssemblyReferences)\n\t\t\t\t{\n\t\t\t\t\treturn loadedAssemblyReferences.Any(i => i.Value.HasErrors);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/Resource.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.IO;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\tpublic enum ResourceType\n\t{\n\t\tLinked,\n\t\tEmbedded,\n\t\tAssemblyLinked,\n\t}\n\n\tpublic abstract class Resource\n\t{\n\t\tpublic virtual ResourceType ResourceType => ResourceType.Embedded;\n\t\tpublic virtual ManifestResourceAttributes Attributes => ManifestResourceAttributes.Public;\n\t\tpublic abstract string Name { get; }\n\t\tpublic abstract Stream? TryOpenStream();\n\t\tpublic abstract long? TryGetLength();\n\t}\n\n\tpublic class ByteArrayResource : Resource\n\t{\n\t\tpublic override string Name { get; }\n\t\tbyte[] data;\n\n\t\tpublic ByteArrayResource(string name, byte[] data)\n\t\t{\n\t\t\tthis.Name = name ?? throw new ArgumentNullException(nameof(name));\n\t\t\tthis.data = data ?? throw new ArgumentNullException(nameof(data));\n\t\t}\n\n\t\tpublic override Stream TryOpenStream()\n\t\t{\n\t\t\treturn new MemoryStream(data);\n\t\t}\n\n\t\tpublic override long? TryGetLength()\n\t\t{\n\t\t\treturn data.Length;\n\t\t}\n\t}\n\n\tsealed class MetadataResource : Resource\n\t{\n\t\tpublic MetadataFile Module { get; }\n\t\tpublic ManifestResourceHandle Handle { get; }\n\t\tpublic bool IsNil => Handle.IsNil;\n\n\t\tpublic MetadataResource(MetadataFile module, ManifestResourceHandle handle)\n\t\t{\n\t\t\tthis.Module = module ?? throw new ArgumentNullException(nameof(module));\n\t\t\tthis.Handle = handle;\n\t\t}\n\n\t\tpublic bool Equals(MetadataResource other)\n\t\t{\n\t\t\treturn Module == other.Module && Handle == other.Handle;\n\t\t}\n\n\t\tpublic override bool Equals(object? obj)\n\t\t{\n\t\t\tif (obj is MetadataResource res)\n\t\t\t\treturn Equals(res);\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn unchecked(982451629 * Module.GetHashCode() + 982451653 * MetadataTokens.GetToken(Handle));\n\t\t}\n\n\t\tpublic override string Name => Module.Metadata.GetString(Module.Metadata.GetManifestResource(Handle).Name);\n\n\t\tpublic override ManifestResourceAttributes Attributes => Module.Metadata.GetManifestResource(Handle).Attributes;\n\t\tpublic bool HasFlag(ManifestResourceAttributes flag) => (Attributes & flag) == flag;\n\t\tpublic override ResourceType ResourceType => GetResourceType();\n\n\t\tResourceType GetResourceType()\n\t\t{\n\t\t\tvar resource = Module.Metadata.GetManifestResource(Handle);\n\t\t\tif (resource.Implementation.IsNil)\n\t\t\t\treturn ResourceType.Embedded;\n\t\t\tif (resource.Implementation.Kind == HandleKind.AssemblyReference)\n\t\t\t\treturn ResourceType.AssemblyLinked;\n\t\t\treturn ResourceType.Linked;\n\t\t}\n\n\t\tunsafe bool TryReadResource(out byte* ptr, out long length)\n\t\t{\n\t\t\tptr = null;\n\t\t\tlength = 0;\n\t\t\t// embedded resources cannot be read from this binary.\n\t\t\tif (ResourceType != ResourceType.Embedded)\n\t\t\t\treturn false;\n\t\t\tif (Module.CorHeader == null)\n\t\t\t\treturn false;\n\t\t\tvar resources = Module.CorHeader.ResourcesDirectory;\n\t\t\t// validate resources directory, GetSectionData throws on negative RVAs\n\t\t\tif (resources.RelativeVirtualAddress <= 0)\n\t\t\t\treturn false;\n\t\t\tvar sectionData = Module.GetSectionData(resources.RelativeVirtualAddress);\n\t\t\t// validate section length: we need at least 4 bytes to extract\n\t\t\t// the actual length of the resource blob.\n\t\t\tif (sectionData.Length < 4)\n\t\t\t\treturn false;\n\t\t\tvar offset = Module.Metadata.GetManifestResource(Handle).Offset;\n\t\t\t// validate resource offset\n\t\t\tif (offset < 0 || offset > sectionData.Length - 4)\n\t\t\t\treturn false;\n\t\t\tptr = sectionData.Pointer + offset;\n\t\t\t// get actual length of resource blob.\n\t\t\tlength = ptr[0] + (ptr[1] << 8) + (ptr[2] << 16) + (ptr[3] << 24);\n\t\t\treturn length >= 0 && length <= sectionData.Length;\n\t\t}\n\n\t\tpublic override unsafe Stream? TryOpenStream()\n\t\t{\n\t\t\tif (!TryReadResource(out var ptr, out var length))\n\t\t\t\treturn null;\n\t\t\treturn new ResourceMemoryStream(Module, ptr + sizeof(int), length);\n\t\t}\n\n\t\tpublic unsafe override long? TryGetLength()\n\t\t{\n\t\t\tif (!TryReadResource(out _, out var length))\n\t\t\t\treturn null;\n\t\t\treturn length;\n\t\t}\n\t}\n\n\tsealed unsafe class ResourceMemoryStream : UnmanagedMemoryStream\n\t{\n#pragma warning disable IDE0052 // Remove unread private members\n\t\treadonly MetadataFile peReader;\n#pragma warning restore IDE0052 // Remove unread private members\n\n\t\tpublic ResourceMemoryStream(MetadataFile peReader, byte* data, long length)\n\t\t\t: base(data, length, length, FileAccess.Read)\n\t\t{\n\t\t\t// Keep the PEReader alive while the stream in in use.\n\t\t\tthis.peReader = peReader;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/SignatureBlobComparer.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\tpublic static class SignatureBlobComparer\n\t{\n\t\tpublic static bool EqualsMethodSignature(BlobReader a, BlobReader b, MetadataReader contextForA, MetadataReader contextForB)\n\t\t{\n\t\t\treturn EqualsMethodSignature(ref a, ref b, contextForA, contextForB);\n\t\t}\n\n\t\tstatic bool EqualsMethodSignature(ref BlobReader a, ref BlobReader b, MetadataReader contextForA, MetadataReader contextForB)\n\t\t{\n\t\t\tSignatureHeader header;\n\t\t\t// compare signature headers\n\t\t\tif (a.RemainingBytes == 0 || b.RemainingBytes == 0 || (header = a.ReadSignatureHeader()) != b.ReadSignatureHeader())\n\t\t\t\treturn false;\n\t\t\tif (header.IsGeneric)\n\t\t\t{\n\t\t\t\t// read & compare generic parameter count\n\t\t\t\tif (!IsSameCompressedInteger(ref a, ref b, out _))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// read & compare parameter count\n\t\t\tif (!IsSameCompressedInteger(ref a, ref b, out int totalParameterCount))\n\t\t\t\treturn false;\n\t\t\tif (!IsSameCompressedInteger(ref a, ref b, out int typeCode))\n\t\t\t\treturn false;\n\t\t\tif (!TypesAreEqual(ref a, ref b, contextForA, contextForB, typeCode))\n\t\t\t\treturn false;\n\t\t\tint i = 0;\n\t\t\tfor (; i < totalParameterCount; i++)\n\t\t\t{\n\t\t\t\tif (!IsSameCompressedInteger(ref a, ref b, out typeCode))\n\t\t\t\t\treturn false;\n\t\t\t\t// varargs sentinel\n\t\t\t\tif (typeCode == 65)\n\t\t\t\t\tbreak;\n\t\t\t\tif (!TypesAreEqual(ref a, ref b, contextForA, contextForB, typeCode))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tfor (; i < totalParameterCount; i++)\n\t\t\t{\n\t\t\t\tif (!IsSameCompressedInteger(ref a, ref b, out typeCode))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!TypesAreEqual(ref a, ref b, contextForA, contextForB, typeCode))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic static bool EqualsTypeSignature(BlobReader a, BlobReader b, MetadataReader contextForA, MetadataReader contextForB)\n\t\t{\n\t\t\treturn EqualsTypeSignature(ref a, ref b, contextForA, contextForB);\n\t\t}\n\n\t\tstatic bool EqualsTypeSignature(ref BlobReader a, ref BlobReader b, MetadataReader contextForA, MetadataReader contextForB)\n\t\t{\n\t\t\tif (!IsSameCompressedInteger(ref a, ref b, out int typeCode))\n\t\t\t\treturn false;\n\t\t\treturn TypesAreEqual(ref a, ref b, contextForA, contextForB, typeCode);\n\t\t}\n\n\t\tstatic bool IsSameCompressedInteger(ref BlobReader a, ref BlobReader b, out int value)\n\t\t{\n\t\t\treturn a.TryReadCompressedInteger(out value) && b.TryReadCompressedInteger(out int otherValue) && value == otherValue;\n\t\t}\n\n\t\tstatic bool IsSameCompressedSignedInteger(ref BlobReader a, ref BlobReader b, out int value)\n\t\t{\n\t\t\treturn a.TryReadCompressedSignedInteger(out value) && b.TryReadCompressedSignedInteger(out int otherValue) && value == otherValue;\n\t\t}\n\n\t\tstatic bool TypesAreEqual(ref BlobReader a, ref BlobReader b, MetadataReader contextForA, MetadataReader contextForB, int typeCode)\n\t\t{\n\t\t\tswitch (typeCode)\n\t\t\t{\n\t\t\t\tcase 0x1: // ELEMENT_TYPE_VOID\n\t\t\t\tcase 0x2: // ELEMENT_TYPE_BOOLEAN \n\t\t\t\tcase 0x3: // ELEMENT_TYPE_CHAR \n\t\t\t\tcase 0x4: // ELEMENT_TYPE_I1 \n\t\t\t\tcase 0x5: // ELEMENT_TYPE_U1\n\t\t\t\tcase 0x6: // ELEMENT_TYPE_I2\n\t\t\t\tcase 0x7: // ELEMENT_TYPE_U2\n\t\t\t\tcase 0x8: // ELEMENT_TYPE_I4\n\t\t\t\tcase 0x9: // ELEMENT_TYPE_U4\n\t\t\t\tcase 0xA: // ELEMENT_TYPE_I8\n\t\t\t\tcase 0xB: // ELEMENT_TYPE_U8\n\t\t\t\tcase 0xC: // ELEMENT_TYPE_R4\n\t\t\t\tcase 0xD: // ELEMENT_TYPE_R8\n\t\t\t\tcase 0xE: // ELEMENT_TYPE_STRING\n\t\t\t\tcase 0x16: // ELEMENT_TYPE_TYPEDBYREF\n\t\t\t\tcase 0x18: // ELEMENT_TYPE_I\n\t\t\t\tcase 0x19: // ELEMENT_TYPE_U\n\t\t\t\tcase 0x1C: // ELEMENT_TYPE_OBJECT\n\t\t\t\t\treturn true;\n\t\t\t\tcase 0xF: // ELEMENT_TYPE_PTR \n\t\t\t\tcase 0x10: // ELEMENT_TYPE_BYREF \n\t\t\t\tcase 0x45: // ELEMENT_TYPE_PINNED\n\t\t\t\tcase 0x1D: // ELEMENT_TYPE_SZARRAY\n\t\t\t\t\tif (!IsSameCompressedInteger(ref a, ref b, out typeCode))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!TypesAreEqual(ref a, ref b, contextForA, contextForB, typeCode))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn true;\n\t\t\t\tcase 0x1B: // ELEMENT_TYPE_FNPTR \n\t\t\t\t\tif (!EqualsMethodSignature(ref a, ref b, contextForA, contextForB))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn true;\n\t\t\t\tcase 0x14: // ELEMENT_TYPE_ARRAY \n\t\t\t\t\t\t   // element type\n\t\t\t\t\tif (!IsSameCompressedInteger(ref a, ref b, out typeCode))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!TypesAreEqual(ref a, ref b, contextForA, contextForB, typeCode))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t// rank\n\t\t\t\t\tif (!IsSameCompressedInteger(ref a, ref b, out _))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t// sizes\n\t\t\t\t\tif (!IsSameCompressedInteger(ref a, ref b, out int numOfSizes))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tfor (int i = 0; i < numOfSizes; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!IsSameCompressedInteger(ref a, ref b, out _))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\t// lower bounds\n\t\t\t\t\tif (!IsSameCompressedInteger(ref a, ref b, out int numOfLowerBounds))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tfor (int i = 0; i < numOfLowerBounds; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!IsSameCompressedSignedInteger(ref a, ref b, out _))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\tcase 0x1F: // ELEMENT_TYPE_CMOD_REQD \n\t\t\t\tcase 0x20: // ELEMENT_TYPE_CMOD_OPT \n\t\t\t\t\t\t   // modifier\n\t\t\t\t\tif (!TypeHandleEquals(ref a, ref b, contextForA, contextForB))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t// unmodified type\n\t\t\t\t\tif (!IsSameCompressedInteger(ref a, ref b, out typeCode))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!TypesAreEqual(ref a, ref b, contextForA, contextForB, typeCode))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn true;\n\t\t\t\tcase 0x15: // ELEMENT_TYPE_GENERICINST \n\t\t\t\t\t\t   // generic type\n\t\t\t\t\tif (!IsSameCompressedInteger(ref a, ref b, out typeCode))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!TypesAreEqual(ref a, ref b, contextForA, contextForB, typeCode))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!IsSameCompressedInteger(ref a, ref b, out int numOfArguments))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tfor (int i = 0; i < numOfArguments; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!IsSameCompressedInteger(ref a, ref b, out typeCode))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (!TypesAreEqual(ref a, ref b, contextForA, contextForB, typeCode))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\tcase 0x13: // ELEMENT_TYPE_VAR\n\t\t\t\tcase 0x1E: // ELEMENT_TYPE_MVAR \n\t\t\t\t\t\t   // index\n\t\t\t\t\tif (!IsSameCompressedInteger(ref a, ref b, out _))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn true;\n\t\t\t\tcase 0x11: // ELEMENT_TYPE_VALUETYPE\n\t\t\t\tcase 0x12: // ELEMENT_TYPE_CLASS\n\t\t\t\t\tif (!TypeHandleEquals(ref a, ref b, contextForA, contextForB))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tstatic bool TypeHandleEquals(ref BlobReader a, ref BlobReader b, MetadataReader contextForA, MetadataReader contextForB)\n\t\t{\n\t\t\tvar typeA = a.ReadTypeHandle();\n\t\t\tvar typeB = b.ReadTypeHandle();\n\t\t\tif (typeA.IsNil || typeB.IsNil)\n\t\t\t\treturn false;\n\t\t\treturn typeA.GetFullTypeName(contextForA) == typeB.GetFullTypeName(contextForB);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/TypeReferenceMetadata.cs",
    "content": "// Copyright (c) 2023 James May\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n#if !VSADDIN\n\tpublic sealed class TypeReferenceMetadata\n\t{\n\t\treadonly TypeReference entry;\n\n\t\tpublic MetadataReader Metadata { get; }\n\t\tpublic TypeReferenceHandle Handle { get; }\n\n\t\tstring? name;\n\t\tpublic string Name {\n\t\t\tget {\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\treturn name ??= Metadata.GetString(entry.Name);\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\treturn name = $\"TR:{Handle}\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstring? @namespace;\n\t\tpublic string Namespace {\n\t\t\tget {\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\treturn @namespace ??= Metadata.GetString(entry.Namespace);\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\treturn @namespace = $\"namespace(TR:{Handle})\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic EntityHandle ResolutionScope => entry.ResolutionScope;\n\n\t\tImmutableArray<MemberReferenceMetadata> memberReferences;\n\t\tpublic ImmutableArray<MemberReferenceMetadata> MemberReferences {\n\t\t\tget {\n\t\t\t\tvar value = memberReferences;\n\t\t\t\tif (value.IsDefault)\n\t\t\t\t{\n\t\t\t\t\tvalue = Metadata.MemberReferences\n\t\t\t\t\t\t.Select(r => new MemberReferenceMetadata(Metadata, r))\n\t\t\t\t\t\t.Where(r => r.Parent == Handle)\n\t\t\t\t\t\t.OrderBy(r => r.Name)\n\t\t\t\t\t\t.ToImmutableArray();\n\t\t\t\t\tmemberReferences = value;\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\n\t\tImmutableArray<TypeReferenceMetadata> typeReferences;\n\t\tpublic ImmutableArray<TypeReferenceMetadata> TypeReferences {\n\t\t\tget {\n\t\t\t\tvar value = typeReferences;\n\t\t\t\tif (value.IsDefault)\n\t\t\t\t{\n\t\t\t\t\tvalue = Metadata.TypeReferences\n\t\t\t\t\t\t.Select(r => new TypeReferenceMetadata(Metadata, r))\n\t\t\t\t\t\t.Where(r => r.ResolutionScope == Handle)\n\t\t\t\t\t\t.OrderBy(r => r.Name)\n\t\t\t\t\t\t.ToImmutableArray();\n\t\t\t\t\ttypeReferences = value;\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\n\t\tpublic TypeReferenceMetadata(MetadataReader metadata, TypeReferenceHandle handle)\n\t\t{\n\t\t\tMetadata = metadata ?? throw new ArgumentNullException(nameof(metadata));\n\t\t\tif (handle.IsNil)\n\t\t\t\tthrow new ArgumentNullException(nameof(handle));\n\t\t\tHandle = handle;\n\t\t\tentry = metadata.GetTypeReference(handle);\n\t\t}\n\n\t\tpublic override string ToString() => $\"{Namespace}::{Name}\";\n\t}\n#endif\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.PortableExecutable;\nusing System.Text;\nusing System.Text.RegularExpressions;\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\tpublic enum TargetRuntime\n\t{\n\t\tUnknown,\n\t\tNet_1_0,\n\t\tNet_1_1,\n\t\tNet_2_0,\n\t\tNet_4_0\n\t}\n\n\tpublic enum TargetFrameworkIdentifier\n\t{\n\t\tNETFramework,\n\t\tNETCoreApp,\n\t\tNETStandard,\n\t\tSilverlight,\n\t\tNET\n\t}\n\n\tenum DecompilerRuntime\n\t{\n\t\tNETFramework,\n\t\tNETCoreApp,\n\t\tMono\n\t}\n\n\t/// <summary>\n\t/// Used to resolve assemblies referenced by an assembly.\n\t/// </summary>\n\tpublic class UniversalAssemblyResolver : AssemblyReferenceClassifier, IAssemblyResolver\n\t{\n\t\tstatic UniversalAssemblyResolver()\n\t\t{\n\t\t\t// TODO : test whether this works with Mono on *Windows*, not sure if we'll\n\t\t\t// ever need this...\n\t\t\tif (Type.GetType(\"Mono.Runtime\") != null)\n\t\t\t\tdecompilerRuntime = DecompilerRuntime.Mono;\n\t\t\telse if (typeof(object).Assembly.GetName().Name == \"System.Private.CoreLib\")\n\t\t\t\tdecompilerRuntime = DecompilerRuntime.NETCoreApp;\n\t\t\telse if (Environment.OSVersion.Platform == PlatformID.Unix)\n\t\t\t\tdecompilerRuntime = DecompilerRuntime.Mono;\n\t\t}\n\n\t\treadonly Lazy<DotNetCorePathFinder> dotNetCorePathFinder;\n\t\treadonly bool throwOnError;\n\t\treadonly PEStreamOptions streamOptions;\n\t\treadonly MetadataReaderOptions metadataOptions;\n\t\treadonly string? mainAssemblyFileName;\n\t\treadonly string? baseDirectory;\n\t\treadonly List<string?> directories = new List<string?>();\n\t\tstatic readonly List<string> gac_paths = GetGacPaths();\n\t\tstatic readonly DecompilerRuntime decompilerRuntime;\n\n\t\tpublic void AddSearchDirectory(string? directory)\n\t\t{\n\t\t\tdirectories.Add(directory);\n\t\t\tif (dotNetCorePathFinder.IsValueCreated)\n\t\t\t{\n\t\t\t\tdotNetCorePathFinder.Value.AddSearchDirectory(directory);\n\t\t\t}\n\t\t}\n\n\t\tpublic void RemoveSearchDirectory(string? directory)\n\t\t{\n\t\t\tdirectories.Remove(directory);\n\t\t\tif (dotNetCorePathFinder.IsValueCreated)\n\t\t\t{\n\t\t\t\tdotNetCorePathFinder.Value.RemoveSearchDirectory(directory);\n\t\t\t}\n\t\t}\n\n\t\tpublic string?[] GetSearchDirectories()\n\t\t{\n\t\t\treturn directories.ToArray();\n\t\t}\n\n\t\treadonly string targetFramework;\n\t\treadonly string runtimePack;\n\t\treadonly TargetFrameworkIdentifier targetFrameworkIdentifier;\n\t\treadonly Version targetFrameworkVersion;\n\n\t\t/// <summary>\n\t\t/// Creates a new instance of the <see cref=\"UniversalAssemblyResolver\"/>.\n\t\t/// </summary>\n\t\t/// <param name=\"mainAssemblyFileName\">\n\t\t/// The full path to the \"main assembly\" (i.e., the assembly being decompiled). This is used to\n\t\t/// resolve assemblies that are located next the main assembly. If no full path is used, the resolver\n\t\t/// falls back to using <see cref=\"Environment.CurrentDirectory\"/>.\n\t\t/// </param>\n\t\t/// <param name=\"throwOnError\">\n\t\t/// If <see langword=\"true\"/> an <see cref=\"ResolutionException\"/> is thrown, in case the\n\t\t/// assembly reference cannot be resolved.\n\t\t/// </param>\n\t\t/// <param name=\"targetFramework\">\n\t\t/// The target framework name as used by <see cref=\"System.Runtime.Versioning.TargetFrameworkAttribute\"/>.\n\t\t/// That is, \"{framework},Version={version}\": currently it supports \".NETCoreApp\", \".NETStandard\" and\n\t\t/// \"Silverlight\", if the string doesn't match any of these, the resolver falls back to \".NET Framework\",\n\t\t/// which is \"classic\" .NET &lt;= 4.8.\n\t\t/// </param>\n\t\t/// <param name=\"runtimePack\">\n\t\t/// Identifier of the runtime pack this assembly was compiled for.\n\t\t/// If omitted, falling back to \"Microsoft.NETCore.App\" and this is ignored in case of classic .NET</param>\n\t\t/// <param name=\"streamOptions\">Options used for the <see cref=\"PEReader\"/>.</param>\n\t\t/// <param name=\"metadataOptions\">Options used for the <see cref=\"MetadataReader\"/>.</param>\n\t\tpublic UniversalAssemblyResolver(string? mainAssemblyFileName, bool throwOnError, string? targetFramework,\n\t\t\tstring? runtimePack = null, PEStreamOptions streamOptions = PEStreamOptions.Default, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default)\n\t\t{\n\t\t\tthis.mainAssemblyFileName = mainAssemblyFileName;\n\t\t\tthis.throwOnError = throwOnError;\n\t\t\tthis.streamOptions = streamOptions;\n\t\t\tthis.metadataOptions = metadataOptions;\n\t\t\tthis.targetFramework = targetFramework ?? string.Empty;\n\t\t\tthis.runtimePack = runtimePack ?? \"Microsoft.NETCore.App\";\n\t\t\t(targetFrameworkIdentifier, targetFrameworkVersion) = ParseTargetFramework(this.targetFramework);\n\t\t\tthis.dotNetCorePathFinder = new Lazy<DotNetCorePathFinder>(InitDotNetCorePathFinder);\n\t\t\tif (mainAssemblyFileName != null)\n\t\t\t{\n\t\t\t\tthis.baseDirectory = Path.GetDirectoryName(mainAssemblyFileName);\n\t\t\t\tif (string.IsNullOrWhiteSpace(this.baseDirectory))\n\t\t\t\t\tthis.baseDirectory = Environment.CurrentDirectory;\n\t\t\t\tAddSearchDirectory(baseDirectory);\n\t\t\t}\n\t\t}\n\n\t\tinternal static (TargetFrameworkIdentifier, Version) ParseTargetFramework(string targetFramework)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(targetFramework))\n\t\t\t\treturn (TargetFrameworkIdentifier.NETFramework, ZeroVersion);\n\t\t\tstring[] tokens = targetFramework.Split(',');\n\t\t\tTargetFrameworkIdentifier identifier;\n\n\t\t\tswitch (tokens[0].Trim().ToUpperInvariant())\n\t\t\t{\n\t\t\t\tcase \".NETCOREAPP\":\n\t\t\t\t\tidentifier = TargetFrameworkIdentifier.NETCoreApp;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \".NETSTANDARD\":\n\t\t\t\t\tidentifier = TargetFrameworkIdentifier.NETStandard;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"SILVERLIGHT\":\n\t\t\t\t\tidentifier = TargetFrameworkIdentifier.Silverlight;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tidentifier = TargetFrameworkIdentifier.NETFramework;\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tVersion? version = null;\n\n\t\t\tfor (int i = 1; i < tokens.Length; i++)\n\t\t\t{\n\t\t\t\tvar pair = tokens[i].Trim().Split('=');\n\n\t\t\t\tif (pair.Length != 2)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tswitch (pair[0].Trim().ToUpperInvariant())\n\t\t\t\t{\n\t\t\t\t\tcase \"VERSION\":\n\t\t\t\t\t\tvar versionString = pair[1].TrimStart('v', 'V', ' ', '\\t');\n\n\t\t\t\t\t\tif (!Version.TryParse(versionString, out version))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tversion = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tversion = new Version(version.Major, version.Minor, version.Build < 0 ? 0 : version.Build);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// .NET 5 or greater still use \".NETCOREAPP\" as TargetFrameworkAttribute value...\n\t\t\t\t\t\tif (version?.Major >= 5 && identifier == TargetFrameworkIdentifier.NETCoreApp)\n\t\t\t\t\t\t\tidentifier = TargetFrameworkIdentifier.NET;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn (identifier, version ?? ZeroVersion);\n\t\t}\n\n#if !VSADDIN\n\t\tpublic MetadataFile? Resolve(IAssemblyReference name)\n\t\t{\n\t\t\tvar file = FindAssemblyFile(name);\n\t\t\treturn CreatePEFileFromFileName(file, ex => new ResolutionException(name, file, ex));\n\t\t}\n\n\t\tpublic MetadataFile? ResolveModule(MetadataFile mainModule, string moduleName)\n\t\t{\n\t\t\tstring? baseDirectory = Path.GetDirectoryName(mainModule.FileName);\n\t\t\tif (baseDirectory == null)\n\t\t\t\treturn null;\n\t\t\tstring moduleFileName = Path.Combine(baseDirectory, moduleName);\n\t\t\treturn CreatePEFileFromFileName(moduleFileName, ex => new ResolutionException(mainModule.FileName, moduleName, moduleFileName, ex));\n\t\t}\n\n\t\tprivate MetadataFile? CreatePEFileFromFileName(string? fileName, Func<Exception?, Exception> makeException)\n\t\t{\n\t\t\tif (fileName == null)\n\t\t\t{\n\t\t\t\tif (throwOnError)\n\t\t\t\t\tthrow makeException(null);\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tFileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read);\n\t\t\t\treturn new PEFile(fileName, stream, streamOptions, metadataOptions);\n\t\t\t}\n\t\t\tcatch (BadImageFormatException ex)\n\t\t\t{\n\t\t\t\tif (throwOnError)\n\t\t\t\t\tthrow makeException(ex);\n\t\t\t}\n\t\t\tcatch (IOException ex)\n\t\t\t{\n\t\t\t\tif (throwOnError)\n\t\t\t\t\tthrow makeException(ex);\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic Task<MetadataFile?> ResolveAsync(IAssemblyReference name)\n\t\t{\n\t\t\treturn Task.Run(() => Resolve(name));\n\t\t}\n\n\t\tpublic Task<MetadataFile?> ResolveModuleAsync(MetadataFile mainModule, string moduleName)\n\t\t{\n\t\t\treturn Task.Run(() => ResolveModule(mainModule, moduleName));\n\t\t}\n#endif\n\n\t\tpublic override bool IsSharedAssembly(IAssemblyReference reference, [NotNullWhen(true)] out string? runtimePack)\n\t\t{\n\t\t\treturn dotNetCorePathFinder.Value.TryResolveDotNetCoreShared(reference, out runtimePack) != null;\n\t\t}\n\n\t\tpublic string? FindAssemblyFile(IAssemblyReference name)\n\t\t{\n\t\t\tif (name.IsWindowsRuntime)\n\t\t\t{\n\t\t\t\treturn FindWindowsMetadataFile(name);\n\t\t\t}\n\n\t\t\tstring? file;\n\t\t\tswitch (targetFrameworkIdentifier)\n\t\t\t{\n\t\t\t\tcase TargetFrameworkIdentifier.NET:\n\t\t\t\tcase TargetFrameworkIdentifier.NETCoreApp:\n\t\t\t\tcase TargetFrameworkIdentifier.NETStandard:\n\t\t\t\t\tif (IsZeroOrAllOnes(targetFrameworkVersion))\n\t\t\t\t\t\tgoto default;\n\t\t\t\t\tfile = dotNetCorePathFinder.Value.TryResolveDotNetCore(name);\n\t\t\t\t\tif (file != null)\n\t\t\t\t\t\treturn file;\n\t\t\t\t\tgoto default;\n\t\t\t\tcase TargetFrameworkIdentifier.Silverlight:\n\t\t\t\t\tif (IsZeroOrAllOnes(targetFrameworkVersion))\n\t\t\t\t\t\tgoto default;\n\t\t\t\t\tfile = ResolveSilverlight(name, targetFrameworkVersion);\n\t\t\t\t\tif (file != null)\n\t\t\t\t\t\treturn file;\n\t\t\t\t\tgoto default;\n\t\t\t\tdefault:\n\t\t\t\t\treturn ResolveInternal(name);\n\t\t\t}\n\t\t}\n\n\t\tDotNetCorePathFinder InitDotNetCorePathFinder()\n\t\t{\n\t\t\tDotNetCorePathFinder dotNetCorePathFinder;\n\t\t\tif (mainAssemblyFileName == null)\n\t\t\t\tdotNetCorePathFinder = new DotNetCorePathFinder(targetFrameworkIdentifier, targetFrameworkVersion, runtimePack);\n\t\t\telse\n\t\t\t\tdotNetCorePathFinder = new DotNetCorePathFinder(mainAssemblyFileName, targetFramework, runtimePack, targetFrameworkIdentifier, targetFrameworkVersion);\n\t\t\tforeach (var directory in directories)\n\t\t\t{\n\t\t\t\tdotNetCorePathFinder.AddSearchDirectory(directory);\n\t\t\t}\n\t\t\treturn dotNetCorePathFinder;\n\t\t}\n\n\t\tstring? FindWindowsMetadataFile(IAssemblyReference name)\n\t\t{\n\t\t\t// Finding Windows Metadata (winmd) is currently only supported on Windows.\n\t\t\tif (Environment.OSVersion.Platform != PlatformID.Win32NT)\n\t\t\t\treturn null;\n\n\t\t\t// TODO : Find a way to detect the base directory for the required Windows SDK.\n\t\t\tstring? basePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), \"Windows Kits\", \"10\", \"References\");\n\n\t\t\tif (!Directory.Exists(basePath))\n\t\t\t\treturn FindWindowsMetadataInSystemDirectory(name);\n\n\t\t\t// TODO : Find a way to detect the required Windows SDK version.\n\t\t\tvar di = new DirectoryInfo(basePath);\n\t\t\tbasePath = null;\n\t\t\tforeach (var versionFolder in di.EnumerateDirectories())\n\t\t\t{\n\t\t\t\tbasePath = versionFolder.FullName;\n\t\t\t}\n\n\t\t\tif (basePath == null)\n\t\t\t\treturn FindWindowsMetadataInSystemDirectory(name);\n\n\t\t\tbasePath = Path.Combine(basePath, name.Name);\n\n\t\t\tif (!Directory.Exists(basePath))\n\t\t\t\treturn FindWindowsMetadataInSystemDirectory(name);\n\n\t\t\tbasePath = Path.Combine(basePath, FindClosestVersionDirectory(basePath, name.Version));\n\n\t\t\tif (!Directory.Exists(basePath))\n\t\t\t\treturn FindWindowsMetadataInSystemDirectory(name);\n\n\t\t\tstring file = Path.Combine(basePath, name.Name + \".winmd\");\n\n\t\t\tif (!File.Exists(file))\n\t\t\t\treturn FindWindowsMetadataInSystemDirectory(name);\n\n\t\t\treturn file;\n\t\t}\n\n\t\tstring? FindWindowsMetadataInSystemDirectory(IAssemblyReference name)\n\t\t{\n\t\t\tstring file = Path.Combine(Environment.SystemDirectory, \"WinMetadata\", name.Name + \".winmd\");\n\t\t\tif (File.Exists(file))\n\t\t\t\treturn file;\n\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// This only works on Windows\n\t\t/// </summary>\n\t\tstring? ResolveSilverlight(IAssemblyReference name, Version? version)\n\t\t{\n\t\t\tstring[] targetFrameworkSearchPaths = {\n\t\t\t\tPath.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), \"Microsoft Silverlight\"),\n\t\t\t\tPath.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), \"Microsoft Silverlight\")\n\t\t\t};\n\n\t\t\tforeach (var baseDirectory in targetFrameworkSearchPaths)\n\t\t\t{\n\t\t\t\tif (!Directory.Exists(baseDirectory))\n\t\t\t\t\tcontinue;\n\t\t\t\tvar versionDirectory = Path.Combine(baseDirectory, FindClosestVersionDirectory(baseDirectory, version));\n\t\t\t\tvar file = SearchDirectory(name, versionDirectory);\n\t\t\t\tif (file != null)\n\t\t\t\t\treturn file;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tstring FindClosestVersionDirectory(string basePath, Version? version)\n\t\t{\n\t\t\tstring? path = null;\n\t\t\tforeach (var folder in new DirectoryInfo(basePath).GetDirectories().Select(DotNetCorePathFinder.ConvertToVersion)\n\t\t\t\t.Where(v => v.Item1 != null).OrderByDescending(v => v.Item1))\n\t\t\t{\n\t\t\t\tif (path == null || version == null || folder.Item1 >= version)\n\t\t\t\t\tpath = folder.Item2.Name;\n\t\t\t}\n\t\t\treturn path ?? version?.ToString() ?? \".\";\n\t\t}\n\n\t\tstring? ResolveInternal(IAssemblyReference name)\n\t\t{\n\t\t\tif (name == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(name));\n\n\t\t\tvar assembly = SearchDirectory(name, directories);\n\t\t\tif (assembly != null)\n\t\t\t\treturn assembly;\n\n\t\t\tstring[] framework_dirs;\n\t\t\tstring framework_dir;\n\n\t\t\tswitch (decompilerRuntime)\n\t\t\t{\n\t\t\t\tcase DecompilerRuntime.Mono:\n\t\t\t\t\tframework_dir = Path.GetDirectoryName(typeof(object).Module.FullyQualifiedName)!;\n\t\t\t\t\tframework_dirs = new[] { framework_dir, Path.Combine(framework_dir, \"Facades\") };\n\t\t\t\t\tbreak;\n\t\t\t\tcase DecompilerRuntime.NETCoreApp:\n\t\t\t\t\tstring windir;\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\twindir = Environment.GetFolderPath(Environment.SpecialFolder.Windows);\n\t\t\t\t\t\tif (string.IsNullOrEmpty(windir))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tgoto default;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcatch (PlatformNotSupportedException)\n\t\t\t\t\t{\n\t\t\t\t\t\tgoto default;\n\t\t\t\t\t}\n\t\t\t\t\tframework_dir = Path.Combine(windir, \"Microsoft.NET\", \"Framework64\", \"v4.0.30319\");\n\t\t\t\t\tframework_dirs = new[] { framework_dir };\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tframework_dir = Path.GetDirectoryName(typeof(object).Module.FullyQualifiedName)!;\n\t\t\t\t\tframework_dirs = new[] { framework_dir };\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (IsSpecialVersionOrRetargetable(name))\n\t\t\t{\n\t\t\t\tassembly = SearchDirectory(name, framework_dirs);\n\t\t\t\tif (assembly != null)\n\t\t\t\t\treturn assembly;\n\t\t\t}\n\n\t\t\tif (name.Name == \"mscorlib\")\n\t\t\t{\n\t\t\t\tassembly = GetCorlib(name);\n\t\t\t\tif (assembly != null)\n\t\t\t\t\treturn assembly;\n\t\t\t}\n\n\t\t\tassembly = GetAssemblyInGac(name);\n\t\t\tif (assembly != null)\n\t\t\t\treturn assembly;\n\n\t\t\t// when decompiling assemblies that target frameworks prior to 4.0, we can fall back to the 4.0 assemblies in case the target framework is not installed.\n\t\t\t// but when looking for Microsoft.Build.Framework, Version=15.0.0.0 we should not use the version 4.0 assembly here so that the LoadedAssembly logic can instead fall back to version 15.1.0.0\n\t\t\tif (name.Version <= new Version(4, 0, 0, 0))\n\t\t\t{\n\t\t\t\tassembly = SearchDirectory(name, framework_dirs);\n\t\t\t\tif (assembly != null)\n\t\t\t\t\treturn assembly;\n\t\t\t}\n\n\t\t\tif (throwOnError)\n\t\t\t\tthrow new ResolutionException(name, null, null);\n\t\t\treturn null;\n\t\t}\n\n\t\t#region .NET / mono GAC handling\n\t\tstring? SearchDirectory(IAssemblyReference name, IEnumerable<string?> directories)\n\t\t{\n\t\t\tforeach (var directory in directories)\n\t\t\t{\n\t\t\t\tif (directory == null)\n\t\t\t\t\tcontinue;\n\t\t\t\tstring? file = SearchDirectory(name, directory);\n\t\t\t\tif (file != null)\n\t\t\t\t\treturn file;\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tstatic bool IsSpecialVersionOrRetargetable(IAssemblyReference reference)\n\t\t{\n\t\t\treturn IsZeroOrAllOnes(reference.Version) || reference.IsRetargetable;\n\t\t}\n\n\t\tstring? SearchDirectory(IAssemblyReference name, string directory)\n\t\t{\n\t\t\tvar extensions = name.IsWindowsRuntime ? new[] { \".winmd\", \".dll\" } : new[] { \".dll\", \".exe\" };\n\t\t\tforeach (var extension in extensions)\n\t\t\t{\n\t\t\t\tstring file = Path.Combine(directory, name.Name + extension);\n\t\t\t\tif (!File.Exists(file))\n\t\t\t\t\tcontinue;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\treturn file;\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tstatic bool IsZeroOrAllOnes(Version? version)\n\t\t{\n\t\t\treturn version == null\n\t\t\t\t|| (version.Major == 0 && version.Minor == 0 && version.Build == 0 && version.Revision == 0)\n\t\t\t\t|| (version.Major == 65535 && version.Minor == 65535 && version.Build == 65535 && version.Revision == 65535);\n\t\t}\n\n\t\tinternal static Version ZeroVersion = new Version(0, 0, 0, 0);\n\n\t\tstring? GetCorlib(IAssemblyReference reference)\n\t\t{\n\t\t\tvar version = reference.Version;\n\t\t\tvar corlib = typeof(object).Assembly.GetName();\n\n\t\t\tif (decompilerRuntime != DecompilerRuntime.NETCoreApp)\n\t\t\t{\n\t\t\t\tif (corlib.Version == version || IsSpecialVersionOrRetargetable(reference))\n\t\t\t\t\treturn typeof(object).Module.FullyQualifiedName;\n\t\t\t}\n\n\t\t\tif (reference.PublicKeyToken == null)\n\t\t\t\treturn null;\n\t\t\tif (version == null)\n\t\t\t\treturn null;\n\n\t\t\tstring? path;\n\t\t\tif (decompilerRuntime == DecompilerRuntime.Mono)\n\t\t\t{\n\t\t\t\tpath = GetMonoMscorlibBasePath(version);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tpath = GetMscorlibBasePath(version, reference.PublicKeyToken.ToHexString(8));\n\t\t\t}\n\n\t\t\tif (path == null)\n\t\t\t\treturn null;\n\n\t\t\tvar file = Path.Combine(path, \"mscorlib.dll\");\n\t\t\tif (File.Exists(file))\n\t\t\t\treturn file;\n\n\t\t\treturn null;\n\t\t}\n\n\t\tstring? GetMscorlibBasePath(Version version, string? publicKeyToken)\n\t\t{\n\t\t\tstring? GetSubFolderForVersion()\n\t\t\t{\n\t\t\t\tswitch (version.Major)\n\t\t\t\t{\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tif (version.MajorRevision == 3300)\n\t\t\t\t\t\t\treturn \"v1.0.3705\";\n\t\t\t\t\t\treturn \"v1.1.4322\";\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\treturn \"v2.0.50727\";\n\t\t\t\t\tcase 4:\n\t\t\t\t\t\treturn \"v4.0.30319\";\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif (throwOnError)\n\t\t\t\t\t\t\tthrow new NotSupportedException(\"Version not supported: \" + version);\n\t\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (publicKeyToken == \"969db8053d3322ac\")\n\t\t\t{\n\t\t\t\tstring programFiles = Environment.Is64BitOperatingSystem ?\n\t\t\t\t\tEnvironment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) :\n\t\t\t\t\tEnvironment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);\n\t\t\t\tstring cfPath = $@\"Microsoft.NET\\SDK\\CompactFramework\\v{version.Major}.{version.Minor}\\WindowsCE\\\";\n\t\t\t\tstring cfBasePath = Path.Combine(programFiles, cfPath);\n\t\t\t\tif (Directory.Exists(cfBasePath))\n\t\t\t\t\treturn cfBasePath;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tstring rootPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), \"Microsoft.NET\");\n\t\t\t\tstring[] frameworkPaths = new[] {\n\t\t\t\t\tPath.Combine(rootPath, \"Framework\"),\n\t\t\t\t\tPath.Combine(rootPath, \"Framework64\")\n\t\t\t\t};\n\n\t\t\t\tstring? folder = GetSubFolderForVersion();\n\n\t\t\t\tif (folder != null)\n\t\t\t\t{\n\t\t\t\t\tforeach (var path in frameworkPaths)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar basePath = Path.Combine(path, folder);\n\t\t\t\t\t\tif (Directory.Exists(basePath))\n\t\t\t\t\t\t\treturn basePath;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (throwOnError)\n\t\t\t\tthrow new NotSupportedException(\"Version not supported: \" + version);\n\t\t\treturn null;\n\t\t}\n\n\t\tstring? GetMonoMscorlibBasePath(Version version)\n\t\t{\n\t\t\tvar path = Directory.GetParent(typeof(object).Module.FullyQualifiedName)!.Parent!.FullName;\n\t\t\tif (version.Major == 1)\n\t\t\t\tpath = Path.Combine(path, \"1.0\");\n\t\t\telse if (version.Major == 2)\n\t\t\t{\n\t\t\t\tif (version.MajorRevision == 5)\n\t\t\t\t\tpath = Path.Combine(path, \"2.1\");\n\t\t\t\telse\n\t\t\t\t\tpath = Path.Combine(path, \"2.0\");\n\t\t\t}\n\t\t\telse if (version.Major == 4)\n\t\t\t\tpath = Path.Combine(path, \"4.0\");\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (throwOnError)\n\t\t\t\t\tthrow new NotSupportedException(\"Version not supported: \" + version);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn path;\n\t\t}\n\n\t\tpublic static List<string> GetGacPaths()\n\t\t{\n\t\t\tif (decompilerRuntime == DecompilerRuntime.Mono)\n\t\t\t\treturn GetDefaultMonoGacPaths();\n\n\t\t\tvar paths = new List<string>(2);\n\t\t\tvar windir = Environment.GetFolderPath(Environment.SpecialFolder.Windows);\n\t\t\tif (windir == null)\n\t\t\t\treturn paths;\n\n\t\t\tpaths.Add(Path.Combine(windir, \"assembly\"));\n\t\t\tpaths.Add(Path.Combine(windir, \"Microsoft.NET\", \"assembly\"));\n\t\t\treturn paths;\n\t\t}\n\n\t\tstatic List<string> GetDefaultMonoGacPaths()\n\t\t{\n\t\t\tvar paths = new List<string>(1);\n\t\t\tvar gac = GetCurrentMonoGac();\n\t\t\tif (gac != null)\n\t\t\t\tpaths.Add(gac);\n\n\t\t\tvar gac_paths_env = Environment.GetEnvironmentVariable(\"MONO_GAC_PREFIX\");\n\t\t\tif (string.IsNullOrEmpty(gac_paths_env))\n\t\t\t\treturn paths;\n\n\t\t\tvar prefixes = gac_paths_env.Split(Path.PathSeparator);\n\t\t\tforeach (var prefix in prefixes)\n\t\t\t{\n\t\t\t\tif (string.IsNullOrEmpty(prefix))\n\t\t\t\t\tcontinue;\n\n\t\t\t\tvar gac_path = Path.Combine(Path.Combine(Path.Combine(prefix, \"lib\"), \"mono\"), \"gac\");\n\t\t\t\tif (Directory.Exists(gac_path) && !paths.Contains(gac_path))\n\t\t\t\t\tpaths.Add(gac_path);\n\t\t\t}\n\n\t\t\treturn paths;\n\t\t}\n\n\t\tstatic string GetCurrentMonoGac()\n\t\t{\n\t\t\treturn Path.Combine(\n\t\t\t\tDirectory.GetParent(\n\t\t\t\t\tPath.GetDirectoryName(typeof(object).Module.FullyQualifiedName)!)!.FullName,\n\t\t\t\t\"gac\");\n\t\t}\n\n\t\tpublic static string? GetAssemblyInGac(IAssemblyReference reference)\n\t\t{\n\t\t\tif (reference.PublicKeyToken == null || reference.PublicKeyToken.Length == 0)\n\t\t\t\treturn null;\n\n\t\t\tif (decompilerRuntime == DecompilerRuntime.Mono)\n\t\t\t\treturn GetAssemblyInMonoGac(reference);\n\n\t\t\treturn GetAssemblyInNetGac(reference);\n\t\t}\n\n\t\tstatic string? GetAssemblyInMonoGac(IAssemblyReference reference)\n\t\t{\n\t\t\tfor (int i = 0; i < gac_paths.Count; i++)\n\t\t\t{\n\t\t\t\tvar gac_path = gac_paths[i];\n\t\t\t\tvar file = GetAssemblyFile(reference, string.Empty, gac_path);\n\t\t\t\tif (File.Exists(file))\n\t\t\t\t\treturn file;\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tstatic string? GetAssemblyInNetGac(IAssemblyReference reference)\n\t\t{\n\t\t\tvar gacs = new[] { \"GAC_MSIL\", \"GAC_32\", \"GAC_64\", \"GAC\" };\n\t\t\tvar prefixes = new[] { string.Empty, \"v4.0_\" };\n\n\t\t\tfor (int i = 0; i < gac_paths.Count; i++)\n\t\t\t{\n\t\t\t\tfor (int j = 0; j < gacs.Length; j++)\n\t\t\t\t{\n\t\t\t\t\tvar gac = Path.Combine(gac_paths[i], gacs[j]);\n\t\t\t\t\tvar file = GetAssemblyFile(reference, prefixes[i], gac);\n\t\t\t\t\tif (File.Exists(file))\n\t\t\t\t\t\treturn file;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tstatic string GetAssemblyFile(IAssemblyReference reference, string prefix, string gac)\n\t\t{\n\t\t\tvar gac_folder = new StringBuilder()\n\t\t\t\t.Append(prefix)\n\t\t\t\t.Append(reference.Version);\n\t\t\tgac_folder.Append(\"__\");\n\t\t\tfor (int i = 0; i < reference.PublicKeyToken!.Length; i++)\n\t\t\t\tgac_folder.Append(reference.PublicKeyToken[i].ToString(\"x2\"));\n\t\t\treturn Path.Combine(gac, reference.Name, gac_folder.ToString(), reference.Name + \".dll\");\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the names of all assemblies in the GAC.\n\t\t/// </summary>\n\t\tpublic static IEnumerable<AssemblyNameReference> EnumerateGac()\n\t\t{\n\t\t\tvar gacs = new[] { \"GAC_MSIL\", \"GAC_32\", \"GAC_64\", \"GAC\" };\n\t\t\tforeach (var path in GetGacPaths())\n\t\t\t{\n\t\t\t\tforeach (var gac in gacs)\n\t\t\t\t{\n\t\t\t\t\tstring rootPath = Path.Combine(path, gac);\n\t\t\t\t\tif (!Directory.Exists(rootPath))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tforeach (var item in new DirectoryInfo(rootPath).EnumerateFiles(\"*.dll\", SearchOption.AllDirectories))\n\t\t\t\t\t{\n\t\t\t\t\t\t// The root of the GAC should only contain folders, but make sure we handle the case where it does NOT in case\n\t\t\t\t\t\t// someone has a non-standard layout (e.g. due to a broken installer).\n\t\t\t\t\t\tstring? assemblyParentPath = Path.GetDirectoryName(item.FullName);\n\t\t\t\t\t\tif (assemblyParentPath?.Length > rootPath.Length)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstring[]? name = assemblyParentPath.Substring(rootPath.Length + 1).Split(new[] { \"\\\\\" }, StringSplitOptions.RemoveEmptyEntries);\n\t\t\t\t\t\t\tif (name?.Length != 2)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\tvar match = Regex.Match(name[1], $\"(v4.0_)?(?<version>[^_]+)_(?<culture>[^_]+)?_(?<publicKey>[^_]+)\");\n\t\t\t\t\t\t\tif (!match.Success)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\tstring culture = match.Groups[\"culture\"].Value;\n\t\t\t\t\t\t\tif (string.IsNullOrEmpty(culture))\n\t\t\t\t\t\t\t\tculture = \"neutral\";\n\t\t\t\t\t\t\tyield return AssemblyNameReference.Parse(name[0] + \", Version=\" + match.Groups[\"version\"].Value + \", Culture=\" + culture + \", PublicKeyToken=\" + match.Groups[\"publicKey\"].Value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/UnresolvedAssemblyNameReference.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\tpublic sealed class UnresolvedAssemblyNameReference\n\t{\n\t\tpublic string FullName { get; }\n\n\t\tpublic bool HasErrors => Messages.Any(m => m.Item1 == MessageKind.Error);\n\n\t\tpublic List<(MessageKind, string)> Messages { get; } = new List<(MessageKind, string)>();\n\n\t\tpublic UnresolvedAssemblyNameReference(string fullName)\n\t\t{\n\t\t\tthis.FullName = fullName;\n\t\t}\n\t}\n\n\tpublic enum MessageKind { Error, Warning, Info }\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Metadata/WebCilFile.cs",
    "content": "// Copyright (c) 2024 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing System.IO.MemoryMappedFiles;\nusing System.Reflection.Metadata;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\n#nullable enable\n\nnamespace ICSharpCode.Decompiler.Metadata\n{\n\tpublic class WebCilFile : MetadataFile, IDisposable, IModuleReference\n\t{\n\t\treadonly MemoryMappedViewAccessor view;\n\t\treadonly long webcilOffset;\n\n\t\tprivate WebCilFile(string fileName, long webcilOffset, long metadataOffset, MemoryMappedViewAccessor view, ImmutableArray<SectionHeader> sectionHeaders, ImmutableArray<WasmSection> wasmSections, MetadataReaderProvider provider, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default)\n\t\t\t: base(MetadataFileKind.WebCIL, fileName, provider, metadataOptions, 0)\n\t\t{\n\t\t\tthis.webcilOffset = webcilOffset;\n\t\t\tthis.MetadataOffset = (int)metadataOffset;\n\t\t\tthis.view = view;\n\t\t\tthis.SectionHeaders = sectionHeaders;\n\t\t\tthis.WasmSections = wasmSections;\n\t\t}\n\n\t\tpublic static WebCilFile? FromFile(string fileName, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default)\n\t\t{\n\t\t\tusing var memoryMappedFile = TryCreateFromFile(fileName);\n\t\t\tif (memoryMappedFile == null)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tvar view = memoryMappedFile.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read);\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// read magic \"\\0asm\"\n\t\t\t\tif (view.ReadUInt32(0) != WASM_MAGIC)\n\t\t\t\t\treturn null;\n\n\t\t\t\t// read version\n\t\t\t\tif (view.ReadUInt32(4) != 1)\n\t\t\t\t\treturn null;\n\n\t\t\t\tusing var stream = view.AsStream();\n\t\t\t\tusing var reader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true);\n\n\t\t\t\tstream.Position += 8;\n\n\t\t\t\tlong metadataOffset = -1;\n\t\t\t\tList<WasmSection> sections = new List<WasmSection>();\n\n\t\t\t\twhile (stream.Position < stream.Length)\n\t\t\t\t{\n\t\t\t\t\tWasmSectionId id = (WasmSectionId)reader.ReadByte();\n\t\t\t\t\tuint size = reader.ReadULEB128();\n\t\t\t\t\tsections.Add(new WasmSection(id, stream.Position, size, view));\n\n\t\t\t\t\tif (id == WasmSectionId.Custom && size == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tstream.Seek(size, SeekOrigin.Current);\n\t\t\t\t}\n\n\t\t\t\tforeach (var section in sections)\n\t\t\t\t{\n\t\t\t\t\tif (section.Id != WasmSectionId.Data || metadataOffset > -1)\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\tstream.Seek(section.Offset, SeekOrigin.Begin);\n\n\t\t\t\t\tuint numSegments = reader.ReadULEB128();\n\t\t\t\t\tif (numSegments != 2)\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t// skip the first segment\n\t\t\t\t\tif (reader.ReadByte() != 1)\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\tlong segmentLength = reader.ReadULEB128();\n\t\t\t\t\tlong segmentStart = reader.BaseStream.Position;\n\n\t\t\t\t\treader.BaseStream.Seek(segmentLength, SeekOrigin.Current);\n\n\t\t\t\t\tif (reader.ReadByte() != 1)\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\tsegmentLength = reader.ReadULEB128();\n\t\t\t\t\tif (TryReadWebCilSegment(reader, out var header, out metadataOffset, out var webcilOffset, out var sectionHeaders))\n\t\t\t\t\t{\n\t\t\t\t\t\tstream.Seek(metadataOffset, SeekOrigin.Begin);\n\t\t\t\t\t\tvar metadata = MetadataReaderProvider.FromMetadataStream(stream, MetadataStreamOptions.LeaveOpen | MetadataStreamOptions.PrefetchMetadata);\n\n\t\t\t\t\t\tvar result = new WebCilFile(fileName, webcilOffset, metadataOffset, view, ImmutableArray.Create(sectionHeaders), sections.ToImmutableArray(), metadata, metadataOptions);\n\n\t\t\t\t\t\tview = null; // don't dispose the view, we're still using it in the sections\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tview?.Dispose();\n\t\t\t}\n\n\t\t\tstatic MemoryMappedFile? TryCreateFromFile(string fileName)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\treturn MemoryMappedFile.CreateFromFile(fileName, FileMode.Open, null, 0, MemoryMappedFileAccess.Read);\n\t\t\t\t}\n\t\t\t\tcatch (IOException)\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic unsafe bool TryReadWebCilSegment(BinaryReader reader, out WebcilHeader webcilHeader, out long metadataOffset, out long webcilOffset, [NotNullWhen(true)] out SectionHeader[]? sectionHeaders)\n\t\t{\n\t\t\twebcilHeader = default;\n\t\t\tmetadataOffset = -1;\n\t\t\tsectionHeaders = null;\n\n\t\t\twebcilOffset = reader.BaseStream.Position;\n\n\t\t\tif (reader.ReadUInt32() != WEBCIL_MAGIC)\n\t\t\t\treturn false;\n\n\t\t\twebcilHeader.VersionMajor = reader.ReadUInt16();\n\t\t\twebcilHeader.VersionMinor = reader.ReadUInt16();\n\t\t\twebcilHeader.CoffSections = reader.ReadUInt16();\n\t\t\t_ = reader.ReadUInt16(); // reserved0\n\t\t\twebcilHeader.PECliHeaderRVA = reader.ReadUInt32();\n\t\t\twebcilHeader.PECliHeaderSize = reader.ReadUInt32();\n\t\t\twebcilHeader.PEDebugRVA = reader.ReadUInt32();\n\t\t\twebcilHeader.PEDebugSize = reader.ReadUInt32();\n\n\t\t\tsectionHeaders = new SectionHeader[webcilHeader.CoffSections];\n\t\t\tfor (int i = 0; i < webcilHeader.CoffSections; i++)\n\t\t\t{\n\t\t\t\tsectionHeaders[i].VirtualSize = reader.ReadUInt32();\n\t\t\t\tsectionHeaders[i].VirtualAddress = reader.ReadUInt32();\n\t\t\t\tsectionHeaders[i].RawDataSize = reader.ReadUInt32();\n\t\t\t\tsectionHeaders[i].RawDataPtr = reader.ReadUInt32();\n\t\t\t}\n\n\t\t\tlong corHeaderStart = TranslateRVA(sectionHeaders, webcilOffset, webcilHeader.PECliHeaderRVA);\n\t\t\tif (reader.BaseStream.Seek(corHeaderStart, SeekOrigin.Begin) != corHeaderStart)\n\t\t\t\treturn false;\n\t\t\tint byteCount = reader.ReadInt32();\n\t\t\tint majorVersion = reader.ReadUInt16();\n\t\t\tint minorVersion = reader.ReadUInt16();\n\t\t\tmetadataOffset = TranslateRVA(sectionHeaders, webcilOffset, (uint)reader.ReadInt32());\n\t\t\treturn reader.BaseStream.Seek(metadataOffset, SeekOrigin.Begin) == metadataOffset;\n\t\t}\n\n\t\tpublic override int MetadataOffset { get; }\n\t\tpublic override bool IsMetadataOnly => false;\n\n\t\tprivate static int GetContainingSectionIndex(IEnumerable<SectionHeader> sections, int rva)\n\t\t{\n\t\t\tint i = 0;\n\t\t\tforeach (var section in sections)\n\t\t\t{\n\t\t\t\tif (rva >= section.VirtualAddress && rva < section.VirtualAddress + section.VirtualSize)\n\t\t\t\t{\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t\ti++;\n\t\t\t}\n\t\t\treturn -1;\n\t\t}\n\n\t\tprivate static long TranslateRVA(IEnumerable<SectionHeader> sections, long webcilOffset, uint rva)\n\t\t{\n\t\t\tforeach (var section in sections)\n\t\t\t{\n\t\t\t\tif (rva >= section.VirtualAddress && rva < section.VirtualAddress + section.VirtualSize)\n\t\t\t\t{\n\t\t\t\t\treturn section.RawDataPtr + (rva - section.VirtualAddress) + webcilOffset;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new BadImageFormatException(\"RVA not found in any section\");\n\t\t}\n\n\t\tpublic override MethodBodyBlock GetMethodBody(int rva)\n\t\t{\n\t\t\tvar reader = GetSectionData(rva).GetReader();\n\t\t\treturn MethodBodyBlock.Create(reader);\n\t\t}\n\n\t\tpublic override int GetContainingSectionIndex(int rva)\n\t\t{\n\t\t\treturn GetContainingSectionIndex(SectionHeaders, rva);\n\t\t}\n\n\t\tpublic override unsafe SectionData GetSectionData(int rva)\n\t\t{\n\t\t\tforeach (var section in SectionHeaders)\n\t\t\t{\n\t\t\t\tif (rva >= section.VirtualAddress && rva < section.VirtualAddress + section.VirtualSize)\n\t\t\t\t{\n\t\t\t\t\tbyte* ptr = (byte*)0;\n\t\t\t\t\tview.SafeMemoryMappedViewHandle.AcquirePointer(ref ptr);\n\t\t\t\t\treturn new SectionData(ptr + section.RawDataPtr + webcilOffset + (rva - section.VirtualAddress), (int)section.RawDataSize);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new BadImageFormatException(\"RVA not found in any section\");\n\t\t}\n\n\t\tpublic override ImmutableArray<SectionHeader> SectionHeaders { get; }\n\n\t\tpublic ImmutableArray<WasmSection> WasmSections { get; }\n\n\t\tIModule? IModuleReference.Resolve(ITypeResolveContext context)\n\t\t{\n\t\t\treturn new MetadataModule(context.Compilation, this, TypeSystemOptions.Default);\n\t\t}\n\n\t\tpublic void Dispose()\n\t\t{\n\t\t\tview.Dispose();\n\t\t}\n\n\t\tpublic struct WebcilHeader\n\t\t{\n\t\t\tpublic ushort VersionMajor;\n\t\t\tpublic ushort VersionMinor;\n\t\t\tpublic ushort CoffSections;\n\t\t\tpublic uint PECliHeaderRVA;\n\t\t\tpublic uint PECliHeaderSize;\n\t\t\tpublic uint PEDebugRVA;\n\t\t\tpublic uint PEDebugSize;\n\t\t}\n\n\t\tconst uint WASM_MAGIC = 0x6d736100u; // \"\\0asm\"\n\t\tconst uint WEBCIL_MAGIC = 0x4c496257u; // \"WbIL\"\n\n\t\t[DebuggerDisplay(\"WasmSection {Id}: {Offset} {Size}\")]\n\t\tpublic class WasmSection\n\t\t{\n\t\t\tpublic WasmSectionId Id;\n\t\t\tpublic long Offset;\n\t\t\tpublic uint Size;\n\t\t\tprivate MemoryMappedViewAccessor view;\n\n\t\t\tpublic WasmSection(WasmSectionId id, long offset, uint size, MemoryMappedViewAccessor view)\n\t\t\t{\n\t\t\t\tthis.Id = id;\n\t\t\t\tthis.Size = size;\n\t\t\t\tthis.Offset = offset;\n\t\t\t\tthis.view = view;\n\t\t\t}\n\t\t}\n\n\t\tpublic enum WasmSectionId : byte\n\t\t{\n\t\t\t// order matters: enum values must match the WebAssembly spec\n\t\t\tCustom = 0,\n\t\t\tType = 1,\n\t\t\tImport = 2,\n\t\t\tFunction = 3,\n\t\t\tTable = 4,\n\t\t\tMemory = 5,\n\t\t\tGlobal = 6,\n\t\t\tExport = 7,\n\t\t\tStart = 8,\n\t\t\tElement = 9,\n\t\t\tCode = 10,\n\t\t\tData = 11,\n\t\t\tDataCount = 12,\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/NRExtensions.cs",
    "content": "// Copyright (c) 2015 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\nusing System;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Documentation;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler\n{\n\tpublic static class NRExtensions\n\t{\n\t\tpublic static bool IsCompilerGenerated(this IEntity entity)\n\t\t{\n\t\t\tif (entity != null)\n\t\t\t{\n\t\t\t\treturn entity.HasAttribute(KnownAttribute.CompilerGenerated);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool IsCompilerGeneratedOrIsInCompilerGeneratedClass(this IEntity entity)\n\t\t{\n\t\t\tif (entity == null)\n\t\t\t\treturn false;\n\t\t\tif (entity.IsCompilerGenerated())\n\t\t\t\treturn true;\n\t\t\treturn IsCompilerGeneratedOrIsInCompilerGeneratedClass(entity.DeclaringTypeDefinition);\n\t\t}\n\n\t\tpublic static bool HasGeneratedName(this IMember member)\n\t\t{\n\t\t\treturn member.Name.StartsWith(\"<\", StringComparison.Ordinal);\n\t\t}\n\n\t\tpublic static bool HasGeneratedName(this IType type)\n\t\t{\n\t\t\treturn type.Name.StartsWith(\"<\", StringComparison.Ordinal) || type.Name.Contains(\"<\");\n\t\t}\n\n\t\tpublic static bool IsAnonymousType(this IType type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\treturn false;\n\t\t\tif (string.IsNullOrEmpty(type.Namespace) && type.HasGeneratedName()\n\t\t\t\t&& (type.Name.Contains(\"AnonType\") || type.Name.Contains(\"AnonymousType\")))\n\t\t\t{\n\t\t\t\tITypeDefinition td = type.GetDefinition();\n\t\t\t\treturn td != null && td.IsCompilerGenerated();\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool ContainsAnonymousType(this IType type)\n\t\t{\n\t\t\tvar visitor = new ContainsAnonTypeVisitor();\n\t\t\ttype.AcceptVisitor(visitor);\n\t\t\treturn visitor.ContainsAnonType;\n\t\t}\n\n\t\tclass ContainsAnonTypeVisitor : TypeVisitor\n\t\t{\n\t\t\tpublic bool ContainsAnonType;\n\n\t\t\tpublic override IType VisitOtherType(IType type)\n\t\t\t{\n\t\t\t\tif (IsAnonymousType(type))\n\t\t\t\t\tContainsAnonType = true;\n\t\t\t\treturn base.VisitOtherType(type);\n\t\t\t}\n\n\t\t\tpublic override IType VisitTypeDefinition(ITypeDefinition type)\n\t\t\t{\n\t\t\t\tif (IsAnonymousType(type))\n\t\t\t\t\tContainsAnonType = true;\n\t\t\t\treturn base.VisitTypeDefinition(type);\n\t\t\t}\n\t\t}\n\n\t\tinternal static string GetDocumentation(this IEntity entity)\n\t\t{\n\t\t\tvar docProvider = XmlDocLoader.LoadDocumentation(entity.ParentModule.MetadataFile);\n\t\t\tif (docProvider == null)\n\t\t\t\treturn null;\n\t\t\treturn docProvider.GetDocumentation(entity);\n\t\t}\n\n\t\tinternal static System.Reflection.TypeAttributes GetMetadataAttributes(this ITypeDefinition type)\n\t\t{\n\t\t\tvar metadata = type.ParentModule.MetadataFile?.Metadata;\n\t\t\tif (metadata == null || type.MetadataToken.IsNil)\n\t\t\t\treturn 0;\n\t\t\treturn metadata.GetTypeDefinition((TypeDefinitionHandle)type.MetadataToken).Attributes;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/NRTAttributes.cs",
    "content": "// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n\nnamespace System.Diagnostics.CodeAnalysis\n{\n\t[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]\n\tinternal sealed class MemberNotNullWhenAttribute : Attribute\n\t{\n\t\tpublic bool ReturnValue { get; }\n\n\t\tpublic string[] Members { get; }\n\n\t\tpublic MemberNotNullWhenAttribute(bool returnValue, string member)\n\t\t{\n\t\t\tReturnValue = returnValue;\n\t\t\tMembers = new string[1] { member };\n\t\t}\n\n\t\tpublic MemberNotNullWhenAttribute(bool returnValue, params string[] members)\n\t\t{\n\t\t\tReturnValue = returnValue;\n\t\t\tMembers = members;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Output/IAmbience.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Output\n{\n\t[Flags]\n\tpublic enum ConversionFlags\n\t{\n\t\t/// <summary>\n\t\t/// Convert only the name.\n\t\t/// </summary>\n\t\tNone = 0,\n\t\t/// <summary>\n\t\t/// Show the parameter list\n\t\t/// </summary>\n\t\tShowParameterList = 1,\n\t\t/// <summary>\n\t\t/// Show names for parameters\n\t\t/// </summary>\n\t\tShowParameterNames = 2,\n\t\t/// <summary>\n\t\t/// Show the accessibility (private, public, etc.)\n\t\t/// </summary>\n\t\tShowAccessibility = 4,\n\t\t/// <summary>\n\t\t/// Show the definition key word (class, struct, Sub, Function, etc.)\n\t\t/// </summary>\n\t\tShowDefinitionKeyword = 8,\n\t\t/// <summary>\n\t\t/// Show the declaring type for the type or member\n\t\t/// </summary>\n\t\tShowDeclaringType = 0x10,\n\t\t/// <summary>\n\t\t/// Show modifiers (virtual, override, etc.)\n\t\t/// </summary>\n\t\tShowModifiers = 0x20,\n\t\t/// <summary>\n\t\t/// Show the return type\n\t\t/// </summary>\n\t\tShowReturnType = 0x40,\n\t\t/// <summary>\n\t\t/// Use fully qualified names for types.\n\t\t/// </summary>\n\t\tUseFullyQualifiedTypeNames = 0x80,\n\t\t/// <summary>\n\t\t/// Show the list of type parameters on method and class declarations.\n\t\t/// Type arguments for parameter/return types are always shown.\n\t\t/// </summary>\n\t\tShowTypeParameterList = 0x100,\n\t\t/// <summary>\n\t\t/// For fields, events and methods: adds a semicolon at the end.\n\t\t/// For properties: shows \"{ get; }\" or similar.\n\t\t/// </summary>\n\t\tShowBody = 0x200,\n\t\t/// <summary>\n\t\t/// Use fully qualified names for members.\n\t\t/// </summary>\n\t\tUseFullyQualifiedEntityNames = 0x400,\n\t\t/// <summary>\n\t\t/// Instead of placing the return type before the entity name,\n\t\t/// append it after the parameter list, preceeded by a colon.\n\t\t/// </summary>\n\t\tPlaceReturnTypeAfterParameterList = 0x800,\n\t\t/// <summary>\n\t\t/// Show the variance modifier of the type parameter.\n\t\t/// If active, shows 'Func&lt;in T, out TResult&gt;' instead of 'Func&lt;T, TResult&gt;'.\n\t\t/// </summary>\n\t\tShowTypeParameterVarianceModifier = 0x1000,\n\t\t/// <summary>\n\t\t/// Show modifiers of parameters, e.g. 'this', 'params', 'ref', 'out' and 'in'.\n\t\t/// </summary>\n\t\tShowParameterModifiers = 0x2000,\n\t\t/// <summary>\n\t\t/// Show default values of parameters.\n\t\t/// </summary>\n\t\tShowParameterDefaultValues = 0x4000,\n\t\t/// <summary>\n\t\t/// Use <c>T?</c> instead of <c>Nullable&lt;T&gt;</c>.\n\t\t/// </summary>\n\t\tUseNullableSpecifierForValueTypes = 0x8000,\n\t\t/// <summary>\n\t\t/// Support <c>init</c> accessors.\n\t\t/// </summary>\n\t\tSupportInitAccessors = 0x10000,\n\t\t/// <summary>\n\t\t/// Support <c>record</c> classes.\n\t\t/// </summary>\n\t\tSupportRecordClasses = 0x20000,\n\t\t/// <summary>\n\t\t/// Support <c>record</c> structs.\n\t\t/// </summary>\n\t\tSupportRecordStructs = 0x40000,\n\t\t/// <summary>\n\t\t/// Support <c>&gt;&gt;&gt;</c> as unsigned right shift operator.\n\t\t/// </summary>\n\t\tSupportUnsignedRightShift = 0x80000,\n\t\t/// <summary>\n\t\t/// Support C# 11 <c>operator checked</c>.\n\t\t/// </summary>\n\t\tSupportOperatorChecked = 0x100000,\n\t\t/// <summary>\n\t\t/// Support C# 7.2 <c>private protected</c>.\n\t\t/// </summary>\n\t\tUsePrivateProtectedAccessibility = 0x200000,\n\n\t\tStandardConversionFlags = ShowParameterNames |\n\t\t\tShowAccessibility |\n\t\t\tUsePrivateProtectedAccessibility |\n\t\t\tShowParameterList |\n\t\t\tShowParameterModifiers |\n\t\t\tShowParameterDefaultValues |\n\t\t\tUseNullableSpecifierForValueTypes |\n\t\t\tShowReturnType |\n\t\t\tShowModifiers |\n\t\t\tShowTypeParameterList |\n\t\t\tShowTypeParameterVarianceModifier |\n\t\t\tShowDefinitionKeyword |\n\t\t\tShowBody,\n\n\t\tAll = 0x1fffff,\n\t}\n\n\t/// <summary>\n\t/// Ambiences are used to convert type system symbols to text (usually for displaying the symbol to the user; e.g. in editor tooltips).\n\t/// </summary>\n\tpublic interface IAmbience\n\t{\n\t\tConversionFlags ConversionFlags { get; set; }\n\n\t\tstring ConvertSymbol(ISymbol symbol);\n\t\tstring ConvertType(IType type);\n\t\tstring ConvertConstantValue(object constantValue);\n\n\t\tstring WrapComment(string comment);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Output/ITextOutput.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler\n{\n\tpublic interface ITextOutput\n\t{\n\t\tstring IndentationString { get; set; }\n\t\tvoid Indent();\n\t\tvoid Unindent();\n\t\tvoid Write(char ch);\n\t\tvoid Write(string text);\n\t\tvoid WriteLine();\n\t\tvoid WriteReference(OpCodeInfo opCode, bool omitSuffix = false);\n\t\tvoid WriteReference(MetadataFile metadata, Handle handle, string text, string protocol = \"decompile\", bool isDefinition = false);\n\t\tvoid WriteReference(IType type, string text, bool isDefinition = false);\n\t\tvoid WriteReference(IMember member, string text, bool isDefinition = false);\n\t\tvoid WriteLocalReference(string text, object reference, bool isDefinition = false);\n\n\t\tvoid MarkFoldStart(string collapsedText = \"...\", bool defaultCollapsed = false, bool isDefinition = false);\n\t\tvoid MarkFoldEnd();\n\t}\n\n\tpublic static class TextOutputExtensions\n\t{\n\t\tpublic static void Write(this ITextOutput output, string format, params object[] args)\n\t\t{\n\t\t\toutput.Write(string.Format(format, args));\n\t\t}\n\n\t\tpublic static void WriteLine(this ITextOutput output, string text)\n\t\t{\n\t\t\toutput.Write(text);\n\t\t\toutput.WriteLine();\n\t\t}\n\n\t\tpublic static void WriteLine(this ITextOutput output, string format, params object[] args)\n\t\t{\n\t\t\toutput.WriteLine(string.Format(format, args));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Output/PlainTextOutput.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler\n{\n\tpublic sealed class PlainTextOutput : ITextOutput\n\t{\n\t\treadonly TextWriter writer;\n\t\tint indent;\n\t\tbool needsIndent;\n\n\t\tint line = 1;\n\t\tint column = 1;\n\n\t\tpublic string IndentationString { get; set; } = \"\\t\";\n\n\t\tpublic PlainTextOutput(TextWriter writer)\n\t\t{\n\t\t\tif (writer == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(writer));\n\t\t\tthis.writer = writer;\n\t\t}\n\n\t\tpublic PlainTextOutput()\n\t\t{\n\t\t\tthis.writer = new StringWriter();\n\t\t}\n\n\t\tpublic TextLocation Location {\n\t\t\tget {\n\t\t\t\treturn new TextLocation(line, column + (needsIndent ? indent : 0));\n\t\t\t}\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn writer.ToString();\n\t\t}\n\n\t\tpublic void Indent()\n\t\t{\n\t\t\tindent++;\n\t\t}\n\n\t\tpublic void Unindent()\n\t\t{\n\t\t\tindent--;\n\t\t}\n\n\t\tvoid WriteIndent()\n\t\t{\n\t\t\tif (needsIndent)\n\t\t\t{\n\t\t\t\tneedsIndent = false;\n\t\t\t\tfor (int i = 0; i < indent; i++)\n\t\t\t\t{\n\t\t\t\t\twriter.Write(IndentationString);\n\t\t\t\t}\n\t\t\t\tcolumn += indent;\n\t\t\t}\n\t\t}\n\n\t\tpublic void Write(char ch)\n\t\t{\n\t\t\tWriteIndent();\n\t\t\twriter.Write(ch);\n\t\t\tcolumn++;\n\t\t}\n\n\t\tpublic void Write(string text)\n\t\t{\n\t\t\tWriteIndent();\n\t\t\twriter.Write(text);\n\t\t\tcolumn += text.Length;\n\t\t}\n\n\t\tpublic void WriteLine()\n\t\t{\n\t\t\twriter.WriteLine();\n\t\t\tneedsIndent = true;\n\t\t\tline++;\n\t\t\tcolumn = 1;\n\t\t}\n\n\t\tpublic void WriteReference(Disassembler.OpCodeInfo opCode, bool omitSuffix = false)\n\t\t{\n\t\t\tif (omitSuffix)\n\t\t\t{\n\t\t\t\tint lastDot = opCode.Name.LastIndexOf('.');\n\t\t\t\tif (lastDot > 0)\n\t\t\t\t{\n\t\t\t\t\tWrite(opCode.Name.Remove(lastDot + 1));\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tWrite(opCode.Name);\n\t\t\t}\n\t\t}\n\n\t\tpublic void WriteReference(MetadataFile module, Handle handle, string text, string protocol = \"decompile\", bool isDefinition = false)\n\t\t{\n\t\t\tWrite(text);\n\t\t}\n\n\t\tpublic void WriteReference(IType type, string text, bool isDefinition = false)\n\t\t{\n\t\t\tWrite(text);\n\t\t}\n\n\t\tpublic void WriteReference(IMember member, string text, bool isDefinition = false)\n\t\t{\n\t\t\tWrite(text);\n\t\t}\n\n\t\tpublic void WriteLocalReference(string text, object reference, bool isDefinition = false)\n\t\t{\n\t\t\tWrite(text);\n\t\t}\n\n\t\tvoid ITextOutput.MarkFoldStart(string collapsedText, bool defaultCollapsed, bool isDefinition)\n\t\t{\n\t\t}\n\n\t\tvoid ITextOutput.MarkFoldEnd()\n\t\t{\n\t\t}\n\t}\n\n\tinternal class TextOutputWithRollback : ITextOutput\n\t{\n\t\tList<Action<ITextOutput>> actions;\n\t\tITextOutput target;\n\n\t\tpublic TextOutputWithRollback(ITextOutput target)\n\t\t{\n\t\t\tthis.target = target;\n\t\t\tthis.actions = new List<Action<ITextOutput>>();\n\t\t}\n\n\t\tstring ITextOutput.IndentationString {\n\t\t\tget {\n\t\t\t\treturn target.IndentationString;\n\t\t\t}\n\t\t\tset {\n\t\t\t\ttarget.IndentationString = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic void Commit()\n\t\t{\n\t\t\tforeach (var action in actions)\n\t\t\t{\n\t\t\t\taction(target);\n\t\t\t}\n\t\t}\n\n\t\tpublic void Indent()\n\t\t{\n\t\t\tactions.Add(target => target.Indent());\n\t\t}\n\n\t\tpublic void MarkFoldEnd()\n\t\t{\n\t\t\tactions.Add(target => target.MarkFoldEnd());\n\t\t}\n\n\t\tpublic void MarkFoldStart(string collapsedText = \"...\", bool defaultCollapsed = false, bool isDefinition = false)\n\t\t{\n\t\t\tactions.Add(target => target.MarkFoldStart(collapsedText, defaultCollapsed));\n\t\t}\n\n\t\tpublic void Unindent()\n\t\t{\n\t\t\tactions.Add(target => target.Unindent());\n\t\t}\n\n\t\tpublic void Write(char ch)\n\t\t{\n\t\t\tactions.Add(target => target.Write(ch));\n\t\t}\n\n\t\tpublic void Write(string text)\n\t\t{\n\t\t\tactions.Add(target => target.Write(text));\n\t\t}\n\n\t\tpublic void WriteLine()\n\t\t{\n\t\t\tactions.Add(target => target.WriteLine());\n\t\t}\n\n\t\tpublic void WriteLocalReference(string text, object reference, bool isDefinition = false)\n\t\t{\n\t\t\tactions.Add(target => target.WriteLocalReference(text, reference, isDefinition));\n\t\t}\n\n\t\tpublic void WriteReference(OpCodeInfo opCode, bool omitSuffix = false)\n\t\t{\n\t\t\tactions.Add(target => target.WriteReference(opCode));\n\t\t}\n\n\t\tpublic void WriteReference(MetadataFile module, Handle handle, string text, string protocol = \"decompile\", bool isDefinition = false)\n\t\t{\n\t\t\tactions.Add(target => target.WriteReference(module, handle, text, protocol, isDefinition));\n\t\t}\n\n\t\tpublic void WriteReference(IType type, string text, bool isDefinition = false)\n\t\t{\n\t\t\tactions.Add(target => target.WriteReference(type, text, isDefinition));\n\t\t}\n\n\t\tpublic void WriteReference(IMember member, string text, bool isDefinition = false)\n\t\t{\n\t\t\tactions.Add(target => target.WriteReference(member, text, isDefinition));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Output/TextOutputWriter.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler\n{\n\tpublic class TextOutputWriter : TextWriter\n\t{\n\t\treadonly ITextOutput output;\n\n\t\tpublic TextOutputWriter(ITextOutput output)\n\t\t{\n\t\t\tif (output == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(output));\n\t\t\tthis.output = output;\n\t\t}\n\n\t\tpublic override Encoding Encoding {\n\t\t\tget { return Encoding.UTF8; }\n\t\t}\n\n\t\tpublic override void Write(char value)\n\t\t{\n\t\t\toutput.Write(value);\n\t\t}\n\n\t\tpublic override void Write(string value)\n\t\t{\n\t\t\toutput.Write(value);\n\t\t}\n\n\t\tpublic override void WriteLine()\n\t\t{\n\t\t\toutput.WriteLine();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Output/TextTokenWriter.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler\n{\n\tpublic class TextTokenWriter : TokenWriter\n\t{\n\t\treadonly ITextOutput output;\n\t\treadonly DecompilerSettings settings;\n\t\treadonly IDecompilerTypeSystem typeSystem;\n\t\treadonly Stack<AstNode> nodeStack = new Stack<AstNode>();\n\t\tint braceLevelWithinType = -1;\n\t\tbool inDocumentationComment = false;\n\t\tbool firstUsingDeclaration;\n\t\tbool lastUsingDeclaration;\n\n\t\tpublic TextTokenWriter(ITextOutput output, DecompilerSettings settings, IDecompilerTypeSystem typeSystem)\n\t\t{\n\t\t\tif (output == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(output));\n\t\t\tif (settings == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(settings));\n\t\t\tif (typeSystem == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(typeSystem));\n\t\t\tthis.output = output;\n\t\t\tthis.settings = settings;\n\t\t\tthis.typeSystem = typeSystem;\n\t\t}\n\n\t\tpublic override void WriteIdentifier(Identifier identifier)\n\t\t{\n\t\t\tif (identifier.IsVerbatim || CSharpOutputVisitor.IsKeyword(identifier.Name, identifier))\n\t\t\t{\n\t\t\t\toutput.Write('@');\n\t\t\t}\n\n\t\t\tvar definition = GetCurrentDefinition();\n\t\t\tstring name = TextWriterTokenWriter.EscapeIdentifier(identifier.Name);\n\t\t\tswitch (definition)\n\t\t\t{\n\t\t\t\tcase IType t:\n\t\t\t\t\toutput.WriteReference(t, name, true);\n\t\t\t\t\treturn;\n\t\t\t\tcase IMember m:\n\t\t\t\t\toutput.WriteReference(m, name, true);\n\t\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar member = GetCurrentMemberReference();\n\t\t\tswitch (member)\n\t\t\t{\n\t\t\t\tcase IType t:\n\t\t\t\t\toutput.WriteReference(t, name, false);\n\t\t\t\t\treturn;\n\t\t\t\tcase IMember m:\n\t\t\t\t\toutput.WriteReference(m, name, false);\n\t\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar localDefinition = GetCurrentLocalDefinition(identifier);\n\t\t\tif (localDefinition != null)\n\t\t\t{\n\t\t\t\toutput.WriteLocalReference(name, localDefinition, isDefinition: true);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar localRef = GetCurrentLocalReference();\n\t\t\tif (localRef != null)\n\t\t\t{\n\t\t\t\toutput.WriteLocalReference(name, localRef);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (firstUsingDeclaration && !lastUsingDeclaration)\n\t\t\t{\n\t\t\t\toutput.MarkFoldStart(defaultCollapsed: !settings.ExpandUsingDeclarations);\n\t\t\t\tfirstUsingDeclaration = false;\n\t\t\t}\n\n\t\t\toutput.Write(name);\n\t\t}\n\n\t\tISymbol GetCurrentMemberReference()\n\t\t{\n\t\t\tAstNode node = nodeStack.Peek();\n\t\t\tvar symbol = node.GetSymbol();\n\t\t\tif (symbol == null && node.Role == Roles.TargetExpression && node.Parent is InvocationExpression)\n\t\t\t{\n\t\t\t\tsymbol = node.Parent.GetSymbol();\n\t\t\t}\n\t\t\tif (symbol != null && node.Role == Roles.Type && node.Parent is ObjectCreateExpression)\n\t\t\t{\n\t\t\t\tvar ctorSymbol = node.Parent.GetSymbol();\n\t\t\t\tif (ctorSymbol != null)\n\t\t\t\t\tsymbol = ctorSymbol;\n\t\t\t}\n\n\t\t\tif (node is IdentifierExpression && node.Role == Roles.TargetExpression && node.Parent is InvocationExpression && symbol is IMember member)\n\t\t\t{\n\t\t\t\tvar declaringType = member.DeclaringType;\n\t\t\t\tif (declaringType != null && declaringType.Kind == TypeKind.Delegate)\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn FilterMember(symbol);\n\t\t}\n\n\t\tISymbol FilterMember(ISymbol symbol)\n\t\t{\n\t\t\tif (symbol == null)\n\t\t\t\treturn null;\n\n\t\t\tif (symbol is LocalFunctionMethod)\n\t\t\t\treturn null;\n\n\t\t\treturn symbol;\n\t\t}\n\n\t\tobject GetCurrentLocalReference()\n\t\t{\n\t\t\tAstNode node = nodeStack.Peek();\n\t\t\tILVariable variable = node.Annotation<ILVariableResolveResult>()?.Variable;\n\t\t\tif (variable != null)\n\t\t\t\treturn variable;\n\n\t\t\tvar letClauseVariable = node.Annotation<CSharp.Transforms.LetIdentifierAnnotation>();\n\t\t\tif (letClauseVariable != null)\n\t\t\t\treturn letClauseVariable;\n\n\t\t\tif (node is GotoStatement gotoStatement)\n\t\t\t{\n\t\t\t\tvar method = nodeStack.Select(nd => nd.GetSymbol() as IMethod).FirstOrDefault(mr => mr != null);\n\t\t\t\tif (method != null)\n\t\t\t\t\treturn method + gotoStatement.Label;\n\t\t\t}\n\n\t\t\tif (node.Role == Roles.TargetExpression && node.Parent is InvocationExpression)\n\t\t\t{\n\t\t\t\tvar symbol = node.Parent.GetSymbol();\n\t\t\t\tif (symbol is LocalFunctionMethod)\n\t\t\t\t\treturn symbol;\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tobject GetCurrentLocalDefinition(Identifier id)\n\t\t{\n\t\t\tAstNode node = nodeStack.Peek();\n\t\t\tif (node is Identifier && node.Parent != null)\n\t\t\t\tnode = node.Parent;\n\n\t\t\tif (node is ParameterDeclaration || node is VariableInitializer || node is CatchClause || node is VariableDesignation)\n\t\t\t{\n\t\t\t\tvar variable = node.Annotation<ILVariableResolveResult>()?.Variable;\n\t\t\t\tif (variable != null)\n\t\t\t\t\treturn variable;\n\t\t\t}\n\n\t\t\tif (id.Role == QueryJoinClause.IntoIdentifierRole || id.Role == QueryJoinClause.JoinIdentifierRole)\n\t\t\t{\n\t\t\t\tvar variable = id.Annotation<ILVariableResolveResult>()?.Variable;\n\t\t\t\tif (variable != null)\n\t\t\t\t\treturn variable;\n\t\t\t}\n\n\t\t\tif (node is QueryLetClause)\n\t\t\t{\n\t\t\t\tvar variable = node.Annotation<CSharp.Transforms.LetIdentifierAnnotation>();\n\t\t\t\tif (variable != null)\n\t\t\t\t\treturn variable;\n\t\t\t}\n\n\t\t\tif (node is LabelStatement label)\n\t\t\t{\n\t\t\t\tvar method = nodeStack.Select(nd => nd.GetSymbol() as IMethod).FirstOrDefault(mr => mr != null);\n\t\t\t\tif (method != null)\n\t\t\t\t\treturn method + label.Label;\n\t\t\t}\n\n\t\t\tif (node is MethodDeclaration && node.Parent is LocalFunctionDeclarationStatement)\n\t\t\t{\n\t\t\t\tvar localFunction = node.Parent.GetResolveResult() as MemberResolveResult;\n\t\t\t\tif (localFunction != null)\n\t\t\t\t\treturn localFunction.Member;\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tISymbol GetCurrentDefinition()\n\t\t{\n\t\t\tif (nodeStack == null || nodeStack.Count == 0)\n\t\t\t\treturn null;\n\n\t\t\tvar node = nodeStack.Peek();\n\t\t\tif (node is Identifier)\n\t\t\t\tnode = node.Parent;\n\t\t\tif (IsDefinition(ref node))\n\t\t\t\treturn node.GetSymbol();\n\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic override void WriteKeyword(Role role, string keyword)\n\t\t{\n\t\t\t//To make reference for 'this' and 'base' keywords in the ClassName():this() expression\n\t\t\tif (role == ConstructorInitializer.ThisKeywordRole || role == ConstructorInitializer.BaseKeywordRole)\n\t\t\t{\n\t\t\t\tif (nodeStack.Peek() is ConstructorInitializer initializer && initializer.GetSymbol() is IMember member)\n\t\t\t\t{\n\t\t\t\t\toutput.WriteReference(member, keyword);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\toutput.Write(keyword);\n\t\t}\n\n\t\tpublic override void WriteToken(Role role, string token)\n\t\t{\n\t\t\tswitch (token)\n\t\t\t{\n\t\t\t\tcase \"{\":\n\t\t\t\t\tif (role != Roles.LBrace)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(\"{\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (braceLevelWithinType >= 0 || nodeStack.Peek() is TypeDeclaration)\n\t\t\t\t\t\tbraceLevelWithinType++;\n\t\t\t\t\tif (nodeStack.PeekOrDefault() is TypeDeclaration or ExtensionDeclaration or BlockStatement { Parent: EntityDeclaration or LocalFunctionDeclarationStatement or AnonymousMethodExpression or LambdaExpression } || settings.FoldBraces)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.MarkFoldStart(defaultCollapsed: !settings.ExpandMemberDefinitions && braceLevelWithinType == 1, isDefinition: braceLevelWithinType == 1);\n\t\t\t\t\t}\n\t\t\t\t\toutput.Write(\"{\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"}\":\n\t\t\t\t\toutput.Write('}');\n\t\t\t\t\tif (role != Roles.RBrace)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tif (nodeStack.PeekOrDefault() is TypeDeclaration or ExtensionDeclaration or BlockStatement { Parent: EntityDeclaration or LocalFunctionDeclarationStatement or AnonymousMethodExpression or LambdaExpression } || settings.FoldBraces)\n\t\t\t\t\t\toutput.MarkFoldEnd();\n\t\t\t\t\tif (braceLevelWithinType >= 0)\n\t\t\t\t\t\tbraceLevelWithinType--;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t// Attach member reference to token only if there's no identifier in the current node.\n\t\t\t\t\tvar member = GetCurrentMemberReference();\n\t\t\t\t\tvar node = nodeStack.Peek();\n\t\t\t\t\tif (member != null && node.GetChildByRole(Roles.Identifier).IsNull)\n\t\t\t\t\t{\n\t\t\t\t\t\tswitch (member)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase IType t:\n\t\t\t\t\t\t\t\toutput.WriteReference(t, token, false);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\tcase IMember m:\n\t\t\t\t\t\t\t\toutput.WriteReference(m, token, false);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\toutput.Write(token);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void Space()\n\t\t{\n\t\t\toutput.Write(' ');\n\t\t}\n\n\t\tpublic override void Indent()\n\t\t{\n\t\t\toutput.Indent();\n\t\t}\n\n\t\tpublic override void Unindent()\n\t\t{\n\t\t\toutput.Unindent();\n\t\t}\n\n\t\tpublic override void NewLine()\n\t\t{\n\t\t\tif (!firstUsingDeclaration && lastUsingDeclaration)\n\t\t\t{\n\t\t\t\toutput.MarkFoldEnd();\n\t\t\t\tlastUsingDeclaration = false;\n\t\t\t}\n\t\t\toutput.WriteLine();\n\t\t}\n\n\t\tpublic override void WriteComment(CommentType commentType, string content)\n\t\t{\n\t\t\tswitch (commentType)\n\t\t\t{\n\t\t\t\tcase CommentType.SingleLine:\n\t\t\t\t\toutput.Write(\"//\");\n\t\t\t\t\toutput.WriteLine(content);\n\t\t\t\t\tbreak;\n\t\t\t\tcase CommentType.MultiLine:\n\t\t\t\t\toutput.Write(\"/*\");\n\t\t\t\t\toutput.Write(content);\n\t\t\t\t\toutput.Write(\"*/\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase CommentType.Documentation:\n\t\t\t\t\tbool isLastLine = !(nodeStack.Peek().NextSibling is Comment);\n\t\t\t\t\tif (!inDocumentationComment && !isLastLine)\n\t\t\t\t\t{\n\t\t\t\t\t\tinDocumentationComment = true;\n\t\t\t\t\t\toutput.MarkFoldStart(\"///\" + content, true);\n\t\t\t\t\t}\n\t\t\t\t\toutput.Write(\"///\");\n\t\t\t\t\toutput.Write(content);\n\t\t\t\t\tif (inDocumentationComment && isLastLine)\n\t\t\t\t\t{\n\t\t\t\t\t\tinDocumentationComment = false;\n\t\t\t\t\t\toutput.MarkFoldEnd();\n\t\t\t\t\t}\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\toutput.Write(content);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void WritePreProcessorDirective(PreProcessorDirectiveType type, string argument)\n\t\t{\n\t\t\t// pre-processor directive must start on its own line\n\t\t\toutput.Write('#');\n\t\t\toutput.Write(type.ToString().ToLowerInvariant());\n\t\t\tif (!string.IsNullOrEmpty(argument))\n\t\t\t{\n\t\t\t\toutput.Write(' ');\n\t\t\t\toutput.Write(argument);\n\t\t\t}\n\t\t\toutput.WriteLine();\n\t\t}\n\n\t\tpublic override void WritePrimitiveValue(object value, LiteralFormat format = LiteralFormat.None)\n\t\t{\n\t\t\tnew TextWriterTokenWriter(new TextOutputWriter(output)).WritePrimitiveValue(value, format);\n\t\t}\n\n\t\tpublic override void WriteInterpolatedText(string text)\n\t\t{\n\t\t\toutput.Write(TextWriterTokenWriter.ConvertString(text));\n\t\t}\n\n\t\tpublic override void WritePrimitiveType(string type)\n\t\t{\n\t\t\tswitch (type)\n\t\t\t{\n\t\t\t\tcase \"new\":\n\t\t\t\t\toutput.Write(type);\n\t\t\t\t\toutput.Write(\"()\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"bool\":\n\t\t\t\tcase \"byte\":\n\t\t\t\tcase \"sbyte\":\n\t\t\t\tcase \"short\":\n\t\t\t\tcase \"ushort\":\n\t\t\t\tcase \"int\":\n\t\t\t\tcase \"uint\":\n\t\t\t\tcase \"long\":\n\t\t\t\tcase \"ulong\":\n\t\t\t\tcase \"float\":\n\t\t\t\tcase \"double\":\n\t\t\t\tcase \"decimal\":\n\t\t\t\tcase \"char\":\n\t\t\t\tcase \"string\":\n\t\t\t\tcase \"object\":\n\t\t\t\t\tvar node = nodeStack.Peek();\n\t\t\t\t\tISymbol symbol;\n\t\t\t\t\tif (node.Role == Roles.Type && node.Parent is ObjectCreateExpression)\n\t\t\t\t\t{\n\t\t\t\t\t\tsymbol = node.Parent.GetSymbol();\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tsymbol = nodeStack.Peek().GetSymbol();\n\t\t\t\t\t}\n\t\t\t\t\tif (symbol == null)\n\t\t\t\t\t\tgoto default;\n\t\t\t\t\tswitch (symbol)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase IType t:\n\t\t\t\t\t\t\toutput.WriteReference(t, type, false);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\tcase IMember m:\n\t\t\t\t\t\t\toutput.WriteReference(m, type, false);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\toutput.Write(type);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void StartNode(AstNode node)\n\t\t{\n\t\t\tif (nodeStack.Count == 0)\n\t\t\t{\n\t\t\t\tif (IsUsingDeclaration(node))\n\t\t\t\t{\n\t\t\t\t\tfirstUsingDeclaration = !IsUsingDeclaration(node.PrevSibling);\n\t\t\t\t\tlastUsingDeclaration = !IsUsingDeclaration(node.NextSibling);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfirstUsingDeclaration = false;\n\t\t\t\t\tlastUsingDeclaration = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tnodeStack.Push(node);\n\t\t}\n\n\t\tprivate bool IsUsingDeclaration(AstNode node)\n\t\t{\n\t\t\treturn node is UsingDeclaration || node is UsingAliasDeclaration;\n\t\t}\n\n\t\tpublic override void EndNode(AstNode node)\n\t\t{\n\t\t\tif (nodeStack.Pop() != node)\n\t\t\t\tthrow new InvalidOperationException();\n\t\t}\n\n\t\tpublic static bool IsDefinition(ref AstNode node)\n\t\t{\n\t\t\tif (node is EntityDeclaration && !(node.Parent is LocalFunctionDeclarationStatement))\n\t\t\t\treturn true;\n\t\t\tif (node is VariableInitializer && node.Parent is FieldDeclaration or EventDeclaration)\n\t\t\t{\n\t\t\t\tnode = node.Parent;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (node is FixedVariableInitializer && node.Parent is FixedFieldDeclaration)\n\t\t\t{\n\t\t\t\tnode = node.Parent;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/PackageReadme.md",
    "content": "## About\n\nICSharpCode.Decompiler is the decompiler engine used in [ILSpy](https://github.com/icsharpcode/ILSpy/).\n\nYou can learn how to use it from the following samples/real-world applications:\n\n* **decompiler-nuget-demos.ipynb** in the [ILSpy repository](https://github.com/icsharpcode/ILSpy/). This shows the basics of using the NuGet.\n* **ILSpyCmd** project in the [ILSpy repository](https://github.com/icsharpcode/ILSpy/tree/master/ICSharpCode.ILSpyCmd). This dotnet tool shows automation of whole assembly decompilation.\n* **ILSpy.Backend** in the [ILSpy Visual Studio Code Extension repository](https://github.com/icsharpcode/ilspy-vscode/tree/master/backend). This LSP shows listing / decompiling members.\n* **ILSpy** itself. Complex, recommended only for advanced users and definitely **not** the place to get started.\n"
  },
  {
    "path": "ICSharpCode.Decompiler/PartialTypeInfo.cs",
    "content": "// Copyright (c) 2022 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler\n{\n\tpublic class PartialTypeInfo\n\t{\n\t\treadonly HashSet<EntityHandle> declaredMembers = new();\n\n\t\tpublic PartialTypeInfo(ITypeDefinition declaringTypeDefinition)\n\t\t{\n\t\t\tDeclaringTypeDefinitionHandle = (TypeDefinitionHandle)declaringTypeDefinition.MetadataToken;\n\t\t}\n\n\t\tpublic PartialTypeInfo(TypeDefinitionHandle declaringTypeDefinitionHandle)\n\t\t{\n\t\t\tDeclaringTypeDefinitionHandle = declaringTypeDefinitionHandle;\n\t\t}\n\n\t\tpublic TypeDefinitionHandle DeclaringTypeDefinitionHandle { get; }\n\n\t\tpublic void AddDeclaredMember(IMember member)\n\t\t{\n\t\t\tdeclaredMembers.Add(member.MetadataToken);\n\t\t}\n\n\t\tpublic void AddDeclaredMember(EntityHandle handle)\n\t\t{\n\t\t\tdeclaredMembers.Add(handle);\n\t\t}\n\n\t\tpublic bool IsDeclaredMember(IMember member)\n\t\t{\n\t\t\treturn declaredMembers.Contains(member.MetadataToken);\n\t\t}\n\n\t\tpublic bool IsDeclaredMember(EntityHandle handle)\n\t\t{\n\t\t\treturn declaredMembers.Contains(handle);\n\t\t}\n\n\t\tpublic void AddDeclaredMembers(PartialTypeInfo info)\n\t\t{\n\t\t\tforeach (var member in info.declaredMembers)\n\t\t\t{\n\t\t\t\tdeclaredMembers.Add(member);\n\t\t\t}\n\t\t}\n\n\t\tpublic string DebugOutput => string.Join(\", \", declaredMembers.Select(m => MetadataTokens.GetToken(m).ToString(\"X\")));\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler/Properties/AssemblyInfo.cs",
    "content": "#region Using directives\n\nusing System.Diagnostics.CodeAnalysis;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n#endregion\n\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// This sets the default COM visibility of types in the assembly to invisible.\n// If you need to expose a type to COM, use [ComVisible(true)] on that type.\n[assembly: ComVisible(false)]\n\n[assembly: AssemblyVersion(DecompilerVersionInfo.Version)]\n[assembly: AssemblyInformationalVersion(DecompilerVersionInfo.FullVersionWithCommitHash)]\n\n[assembly: InternalsVisibleTo(\"ICSharpCode.Decompiler.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001004dcf3979c4e902efa4dd2163a039701ed5822e6f1134d77737296abbb97bf0803083cfb2117b4f5446a217782f5c7c634f9fe1fc60b4c11d62c5b3d33545036706296d31903ddcf750875db38a8ac379512f51620bb948c94d0831125fbc5fe63707cbb93f48c1459c4d1749eb7ac5e681a2f0d6d7c60fa527a3c0b8f92b02bf\")]\n\n[assembly: SuppressMessage(\"Microsoft.Usage\", \"CA2243:AttributeStringLiteralsShouldParseCorrectly\",\n\tJustification = \"AssemblyInformationalVersion does not need to be a parsable version\")]\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Properties/DecompilerVersionInfo.template.cs",
    "content": "public static class DecompilerVersionInfo\n{\n\tpublic const string Major = \"10\";\n\tpublic const string Minor = \"0\";\n\tpublic const string Build = \"0\";\n\tpublic const string Revision = \"$INSERTREVISION$\";\n\tpublic const string VersionName = \"preview3\";\n\n\tpublic const string Version = Major + \".\" + Minor + \".\" + Build + \".\" + Revision;\n\tpublic const string FullVersion = Major + \".\" + Minor + \".\" + Build + \".$INSERTREVISION$$INSERTBRANCHPOSTFIX$$INSERTVERSIONNAMEPOSTFIX$\";\n\tpublic const string FullVersionWithShortCommitHash = FullVersion + \"+$INSERTSHORTCOMMITHASH$\";\n\tpublic const string FullVersionWithCommitHash = FullVersion + \"+$INSERTCOMMITHASH$\";\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/SRMExtensions.cs",
    "content": "using System;\nusing System.Collections.Immutable;\nusing System.IO;\nusing System.IO.MemoryMappedFiles;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Reflection.PortableExecutable;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nusing SRM = System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler\n{\n\tpublic static partial class SRMExtensions\n\t{\n\t\tpublic static bool HasFlag(this TypeDefinition typeDefinition, TypeAttributes attribute)\n\t\t\t=> (typeDefinition.Attributes & attribute) == attribute;\n\t\tpublic static bool HasFlag(this MethodDefinition methodDefinition, MethodAttributes attribute)\n\t\t\t=> (methodDefinition.Attributes & attribute) == attribute;\n\t\tpublic static bool HasFlag(this FieldDefinition fieldDefinition, FieldAttributes attribute)\n\t\t\t=> (fieldDefinition.Attributes & attribute) == attribute;\n\t\tpublic static bool HasFlag(this PropertyDefinition propertyDefinition, PropertyAttributes attribute)\n\t\t\t=> (propertyDefinition.Attributes & attribute) == attribute;\n\t\tpublic static bool HasFlag(this EventDefinition eventDefinition, EventAttributes attribute)\n\t\t\t=> (eventDefinition.Attributes & attribute) == attribute;\n\n\t\tpublic static bool IsTypeKind(this HandleKind kind) =>\n\t\t\tkind == HandleKind.TypeDefinition || kind == HandleKind.TypeReference\n\t\t\t|| kind == HandleKind.TypeSpecification;\n\t\tpublic static bool IsMemberKind(this HandleKind kind) =>\n\t\t\tkind == HandleKind.MethodDefinition || kind == HandleKind.PropertyDefinition\n\t\t\t|| kind == HandleKind.FieldDefinition || kind == HandleKind.EventDefinition\n\t\t\t|| kind == HandleKind.MemberReference || kind == HandleKind.MethodSpecification;\n\t\tpublic static bool IsEntityHandle(this Handle handle) =>\n\t\t\thandle.IsNil || (byte)handle.Kind < 112;\n\n\t\tpublic static bool IsValueType(this TypeDefinitionHandle handle, MetadataReader reader)\n\t\t{\n\t\t\treturn reader.GetTypeDefinition(handle).IsValueType(reader);\n\t\t}\n\n\t\tpublic static bool IsValueType(this TypeDefinition typeDefinition, MetadataReader reader)\n\t\t{\n\t\t\tEntityHandle baseType = typeDefinition.GetBaseTypeOrNil();\n\t\t\tif (baseType.IsNil)\n\t\t\t\treturn false;\n\t\t\tif (baseType.IsKnownType(reader, KnownTypeCode.Enum))\n\t\t\t\treturn true;\n\t\t\tif (!baseType.IsKnownType(reader, KnownTypeCode.ValueType))\n\t\t\t\treturn false;\n\t\t\tvar thisType = typeDefinition.GetFullTypeName(reader);\n\t\t\treturn !thisType.IsKnownType(KnownTypeCode.Enum);\n\t\t}\n\n\t\tpublic static bool IsEnum(this TypeDefinitionHandle handle, MetadataReader reader)\n\t\t{\n\t\t\treturn reader.GetTypeDefinition(handle).IsEnum(reader);\n\t\t}\n\n\t\tpublic static bool IsEnum(this TypeDefinition typeDefinition, MetadataReader reader)\n\t\t{\n\t\t\tEntityHandle baseType = typeDefinition.GetBaseTypeOrNil();\n\t\t\tif (baseType.IsNil)\n\t\t\t\treturn false;\n\t\t\treturn baseType.IsKnownType(reader, KnownTypeCode.Enum);\n\t\t}\n\n\t\tpublic static bool IsEnum(this TypeDefinitionHandle handle, MetadataReader reader,\n\t\t\tout PrimitiveTypeCode underlyingType)\n\t\t{\n\t\t\treturn reader.GetTypeDefinition(handle).IsEnum(reader, out underlyingType);\n\t\t}\n\n\t\tpublic static bool IsEnum(this TypeDefinition typeDefinition, MetadataReader reader,\n\t\t\tout PrimitiveTypeCode underlyingType)\n\t\t{\n\t\t\tunderlyingType = 0;\n\t\t\tEntityHandle baseType = typeDefinition.GetBaseTypeOrNil();\n\t\t\tif (baseType.IsNil)\n\t\t\t\treturn false;\n\t\t\tif (!baseType.IsKnownType(reader, KnownTypeCode.Enum))\n\t\t\t\treturn false;\n\t\t\tforeach (var handle in typeDefinition.GetFields())\n\t\t\t{\n\t\t\t\tvar field = reader.GetFieldDefinition(handle);\n\t\t\t\tif ((field.Attributes & FieldAttributes.Static) != 0)\n\t\t\t\t\tcontinue;\n\t\t\t\tvar blob = reader.GetBlobReader(field.Signature);\n\t\t\t\tif (blob.ReadSignatureHeader().Kind != SignatureKind.Field)\n\t\t\t\t\treturn false;\n\t\t\t\tunderlyingType = (PrimitiveTypeCode)blob.ReadByte();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool IsDelegate(this TypeDefinitionHandle handle, MetadataReader reader)\n\t\t{\n\t\t\treturn reader.GetTypeDefinition(handle).IsDelegate(reader);\n\t\t}\n\n\t\tpublic static bool IsDelegate(this TypeDefinition typeDefinition, MetadataReader reader)\n\t\t{\n\t\t\tvar baseType = typeDefinition.GetBaseTypeOrNil();\n\t\t\treturn !baseType.IsNil && baseType.IsKnownType(reader, KnownTypeCode.MulticastDelegate);\n\t\t}\n\n\t\tpublic static bool HasBody(this MethodDefinition methodDefinition)\n\t\t{\n\t\t\tconst MethodAttributes noBodyAttrs = MethodAttributes.Abstract | MethodAttributes.PinvokeImpl;\n\t\t\tconst MethodImplAttributes noBodyImplAttrs = MethodImplAttributes.InternalCall\n\t\t\t\t| MethodImplAttributes.Native | MethodImplAttributes.Unmanaged | MethodImplAttributes.Runtime;\n\t\t\treturn (methodDefinition.Attributes & noBodyAttrs) == 0 &&\n\t\t\t\t(methodDefinition.ImplAttributes & noBodyImplAttrs) == 0 &&\n\t\t\t\tmethodDefinition.RelativeVirtualAddress > 0;\n\t\t}\n\n\t\tpublic static int GetCodeSize(this MethodBodyBlock body)\n\t\t{\n\t\t\tif (body == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(body));\n\n\t\t\treturn body.GetILReader().Length;\n\t\t}\n\n\t\tpublic static MethodDefinitionHandle GetAny(this PropertyAccessors accessors)\n\t\t{\n\t\t\tif (!accessors.Getter.IsNil)\n\t\t\t\treturn accessors.Getter;\n\t\t\treturn accessors.Setter;\n\t\t}\n\n\t\tpublic static MethodDefinitionHandle GetAny(this EventAccessors accessors)\n\t\t{\n\t\t\tif (!accessors.Adder.IsNil)\n\t\t\t\treturn accessors.Adder;\n\t\t\tif (!accessors.Remover.IsNil)\n\t\t\t\treturn accessors.Remover;\n\t\t\treturn accessors.Raiser;\n\t\t}\n\n\t\tpublic static EntityHandle GetGenericType(this in TypeSpecification ts, MetadataReader metadata)\n\t\t{\n\t\t\tif (ts.Signature.IsNil)\n\t\t\t\treturn default;\n\t\t\t// Do a quick scan using BlobReader\n\t\t\tvar signature = metadata.GetBlobReader(ts.Signature);\n\t\t\t// When dealing with FSM implementations, we can safely assume that if it's a type spec,\n\t\t\t// it must be a generic type instance.\n\t\t\tif (signature.ReadByte() != (byte)SignatureTypeCode.GenericTypeInstance)\n\t\t\t\treturn default;\n\t\t\t// Skip over the rawTypeKind: value type or class\n\t\t\tvar rawTypeKind = signature.ReadCompressedInteger();\n\t\t\tif (rawTypeKind < 17 || rawTypeKind > 18)\n\t\t\t\treturn default;\n\t\t\t// Only read the generic type, ignore the type arguments\n\t\t\treturn signature.ReadTypeHandle();\n\t\t}\n\n\t\tpublic static EntityHandle GetDeclaringType(this EntityHandle entity, MetadataReader metadata)\n\t\t{\n\t\t\tswitch (entity.Kind)\n\t\t\t{\n\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\t\tvar td = metadata.GetTypeDefinition((TypeDefinitionHandle)entity);\n\t\t\t\t\treturn td.GetDeclaringType();\n\t\t\t\tcase HandleKind.TypeReference:\n\t\t\t\t\tvar tr = metadata.GetTypeReference((TypeReferenceHandle)entity);\n\t\t\t\t\treturn tr.GetDeclaringType();\n\t\t\t\tcase HandleKind.TypeSpecification:\n\t\t\t\t\tvar ts = metadata.GetTypeSpecification((TypeSpecificationHandle)entity);\n\t\t\t\t\treturn ts.GetGenericType(metadata).GetDeclaringType(metadata);\n\t\t\t\tcase HandleKind.FieldDefinition:\n\t\t\t\t\tvar fd = metadata.GetFieldDefinition((FieldDefinitionHandle)entity);\n\t\t\t\t\treturn fd.GetDeclaringType();\n\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\tvar md = metadata.GetMethodDefinition((MethodDefinitionHandle)entity);\n\t\t\t\t\treturn md.GetDeclaringType();\n\t\t\t\tcase HandleKind.MemberReference:\n\t\t\t\t\tvar mr = metadata.GetMemberReference((MemberReferenceHandle)entity);\n\t\t\t\t\treturn mr.Parent;\n\t\t\t\tcase HandleKind.EventDefinition:\n\t\t\t\t\tvar ed = metadata.GetEventDefinition((EventDefinitionHandle)entity);\n\t\t\t\t\treturn metadata.GetMethodDefinition(ed.GetAccessors().GetAny()).GetDeclaringType();\n\t\t\t\tcase HandleKind.PropertyDefinition:\n\t\t\t\t\tvar pd = metadata.GetPropertyDefinition((PropertyDefinitionHandle)entity);\n\t\t\t\t\treturn metadata.GetMethodDefinition(pd.GetAccessors().GetAny()).GetDeclaringType();\n\t\t\t\tcase HandleKind.MethodSpecification:\n\t\t\t\t\tvar ms = metadata.GetMethodSpecification((MethodSpecificationHandle)entity);\n\t\t\t\t\treturn ms.Method.GetDeclaringType(metadata);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t}\n\t\t}\n\n\t\tpublic static TypeReferenceHandle GetDeclaringType(this in TypeReference tr)\n\t\t{\n\t\t\tswitch (tr.ResolutionScope.Kind)\n\t\t\t{\n\t\t\t\tcase HandleKind.TypeReference:\n\t\t\t\t\treturn (TypeReferenceHandle)tr.ResolutionScope;\n\t\t\t\tdefault:\n\t\t\t\t\treturn default(TypeReferenceHandle);\n\t\t\t}\n\t\t}\n\n\t\tpublic static FullTypeName GetFullTypeName(this EntityHandle handle, MetadataReader reader)\n\t\t{\n\t\t\tif (handle.IsNil)\n\t\t\t\tthrow new ArgumentNullException(nameof(handle));\n\t\t\tswitch (handle.Kind)\n\t\t\t{\n\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\t\treturn ((TypeDefinitionHandle)handle).GetFullTypeName(reader);\n\t\t\t\tcase HandleKind.TypeReference:\n\t\t\t\t\treturn ((TypeReferenceHandle)handle).GetFullTypeName(reader);\n\t\t\t\tcase HandleKind.TypeSpecification:\n\t\t\t\t\treturn ((TypeSpecificationHandle)handle).GetFullTypeName(reader);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t}\n\t\t}\n\n\t\tpublic static bool IsKnownType(this EntityHandle handle, MetadataReader reader,\n\t\t\tKnownTypeCode knownType)\n\t\t{\n\t\t\treturn IsKnownType(handle, reader, KnownTypeReference.Get(knownType).TypeName);\n\t\t}\n\n\t\tinternal static bool IsKnownType(this EntityHandle handle, MetadataReader reader,\n\t\t\tKnownAttribute knownType)\n\t\t{\n\t\t\treturn IsKnownType(handle, reader, knownType.GetTypeName());\n\t\t}\n\n\t\tprivate static bool IsKnownType(EntityHandle handle, MetadataReader reader, TopLevelTypeName knownType)\n\t\t{\n\t\t\tif (handle.IsNil)\n\t\t\t\treturn false;\n\t\t\tStringHandle nameHandle, namespaceHandle;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tswitch (handle.Kind)\n\t\t\t\t{\n\t\t\t\t\tcase HandleKind.TypeReference:\n\t\t\t\t\t\tvar tr = reader.GetTypeReference((TypeReferenceHandle)handle);\n\t\t\t\t\t\t// ignore exported and nested types\n\t\t\t\t\t\tif (tr.ResolutionScope.IsNil || tr.ResolutionScope.Kind == HandleKind.TypeReference)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tnameHandle = tr.Name;\n\t\t\t\t\t\tnamespaceHandle = tr.Namespace;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\t\t\tvar td = reader.GetTypeDefinition((TypeDefinitionHandle)handle);\n\t\t\t\t\t\tif (td.IsNested)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tnameHandle = td.Name;\n\t\t\t\t\t\tnamespaceHandle = td.Namespace;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HandleKind.TypeSpecification:\n\t\t\t\t\t\tvar ts = reader.GetTypeSpecification((TypeSpecificationHandle)handle);\n\t\t\t\t\t\tvar blob = reader.GetBlobReader(ts.Signature);\n\t\t\t\t\t\treturn SignatureIsKnownType(reader, knownType, ref blob);\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (BadImageFormatException)\n\t\t\t{\n\t\t\t\t// ignore bad metadata when trying to resolve ResolutionScope et al.\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (knownType.TypeParameterCount == 0)\n\t\t\t{\n\t\t\t\tif (!reader.StringComparer.Equals(nameHandle, knownType.Name))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tstring name = reader.GetString(nameHandle);\n\t\t\t\tname = ReflectionHelper.SplitTypeParameterCountFromReflectionName(name, out int typeParameterCount);\n\t\t\t\tif (typeParameterCount != knownType.TypeParameterCount || name != knownType.Name)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (namespaceHandle.IsNil)\n\t\t\t{\n\t\t\t\treturn knownType.Namespace.Length == 0;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn reader.StringComparer.Equals(namespaceHandle, knownType.Namespace);\n\t\t\t}\n\t\t}\n\n\t\tprivate static bool SignatureIsKnownType(MetadataReader reader, TopLevelTypeName knownType, ref BlobReader blob)\n\t\t{\n\t\t\tif (!blob.TryReadCompressedInteger(out int typeCode))\n\t\t\t\treturn false;\n\t\t\tswitch (typeCode)\n\t\t\t{\n\t\t\t\tcase 0x1: // ELEMENT_TYPE_VOID\n\t\t\t\t\treturn knownType.IsKnownType(KnownTypeCode.Void);\n\t\t\t\tcase 0x2: // ELEMENT_TYPE_BOOLEAN \n\t\t\t\t\treturn knownType.IsKnownType(KnownTypeCode.Boolean);\n\t\t\t\tcase 0x3: // ELEMENT_TYPE_CHAR \n\t\t\t\t\treturn knownType.IsKnownType(KnownTypeCode.Char);\n\t\t\t\tcase 0x4: // ELEMENT_TYPE_I1 \n\t\t\t\t\treturn knownType.IsKnownType(KnownTypeCode.SByte);\n\t\t\t\tcase 0x5: // ELEMENT_TYPE_U1\n\t\t\t\t\treturn knownType.IsKnownType(KnownTypeCode.Byte);\n\t\t\t\tcase 0x6: // ELEMENT_TYPE_I2\n\t\t\t\t\treturn knownType.IsKnownType(KnownTypeCode.Int16);\n\t\t\t\tcase 0x7: // ELEMENT_TYPE_U2\n\t\t\t\t\treturn knownType.IsKnownType(KnownTypeCode.UInt16);\n\t\t\t\tcase 0x8: // ELEMENT_TYPE_I4\n\t\t\t\t\treturn knownType.IsKnownType(KnownTypeCode.Int32);\n\t\t\t\tcase 0x9: // ELEMENT_TYPE_U4\n\t\t\t\t\treturn knownType.IsKnownType(KnownTypeCode.UInt32);\n\t\t\t\tcase 0xA: // ELEMENT_TYPE_I8\n\t\t\t\t\treturn knownType.IsKnownType(KnownTypeCode.Int64);\n\t\t\t\tcase 0xB: // ELEMENT_TYPE_U8\n\t\t\t\t\treturn knownType.IsKnownType(KnownTypeCode.UInt64);\n\t\t\t\tcase 0xC: // ELEMENT_TYPE_R4\n\t\t\t\t\treturn knownType.IsKnownType(KnownTypeCode.Single);\n\t\t\t\tcase 0xD: // ELEMENT_TYPE_R8\n\t\t\t\t\treturn knownType.IsKnownType(KnownTypeCode.Double);\n\t\t\t\tcase 0xE: // ELEMENT_TYPE_STRING\n\t\t\t\t\treturn knownType.IsKnownType(KnownTypeCode.String);\n\t\t\t\tcase 0x16: // ELEMENT_TYPE_TYPEDBYREF\n\t\t\t\t\treturn knownType.IsKnownType(KnownTypeCode.TypedReference);\n\t\t\t\tcase 0x18: // ELEMENT_TYPE_I\n\t\t\t\t\treturn knownType.IsKnownType(KnownTypeCode.IntPtr);\n\t\t\t\tcase 0x19: // ELEMENT_TYPE_U\n\t\t\t\t\treturn knownType.IsKnownType(KnownTypeCode.UIntPtr);\n\t\t\t\tcase 0x1C: // ELEMENT_TYPE_OBJECT\n\t\t\t\t\treturn knownType.IsKnownType(KnownTypeCode.Object);\n\t\t\t\tcase 0xF: // ELEMENT_TYPE_PTR \n\t\t\t\tcase 0x10: // ELEMENT_TYPE_BYREF \n\t\t\t\tcase 0x45: // ELEMENT_TYPE_PINNED\n\t\t\t\tcase 0x1D: // ELEMENT_TYPE_SZARRAY\n\t\t\t\tcase 0x1B: // ELEMENT_TYPE_FNPTR \n\t\t\t\tcase 0x14: // ELEMENT_TYPE_ARRAY \n\t\t\t\t\treturn false;\n\t\t\t\tcase 0x1F: // ELEMENT_TYPE_CMOD_REQD \n\t\t\t\tcase 0x20: // ELEMENT_TYPE_CMOD_OPT \n\t\t\t\t\t\t   // modifier\n\t\t\t\t\tblob.ReadTypeHandle(); // skip modifier\n\t\t\t\t\treturn SignatureIsKnownType(reader, knownType, ref blob);\n\t\t\t\tcase 0x15: // ELEMENT_TYPE_GENERICINST \n\t\t\t\t\t\t   // generic type\n\t\t\t\t\treturn SignatureIsKnownType(reader, knownType, ref blob);\n\t\t\t\tcase 0x13: // ELEMENT_TYPE_VAR\n\t\t\t\tcase 0x1E: // ELEMENT_TYPE_MVAR \n\t\t\t\t\t\t   // index\n\t\t\t\t\treturn false;\n\t\t\t\tcase 0x11: // ELEMENT_TYPE_VALUETYPE\n\t\t\t\tcase 0x12: // ELEMENT_TYPE_CLASS\n\t\t\t\t\treturn IsKnownType(blob.ReadTypeHandle(), reader, knownType);\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic static FullTypeName GetFullTypeName(this TypeSpecificationHandle handle, MetadataReader reader)\n\t\t{\n\t\t\tif (handle.IsNil)\n\t\t\t\tthrow new ArgumentNullException(nameof(handle));\n\t\t\tvar ts = reader.GetTypeSpecification(handle);\n\t\t\treturn ts.DecodeSignature(new Metadata.FullTypeNameSignatureDecoder(reader), default(Unit));\n\t\t}\n\n\t\tpublic static FullTypeName GetFullTypeName(this TypeReferenceHandle handle, MetadataReader reader)\n\t\t{\n\t\t\tif (handle.IsNil)\n\t\t\t\tthrow new ArgumentNullException(nameof(handle));\n\t\t\tvar tr = reader.GetTypeReference(handle);\n\t\t\tstring name;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tname = reader.GetString(tr.Name);\n\t\t\t}\n\t\t\tcatch (BadImageFormatException)\n\t\t\t{\n\t\t\t\tname = $\"TR{reader.GetToken(handle):x8}\";\n\t\t\t}\n\t\t\tname = ReflectionHelper.SplitTypeParameterCountFromReflectionName(\n\t\t\t\tname, out var typeParameterCount);\n\t\t\tTypeReferenceHandle declaringTypeHandle;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tdeclaringTypeHandle = tr.GetDeclaringType();\n\t\t\t}\n\t\t\tcatch (BadImageFormatException)\n\t\t\t{\n\t\t\t\tdeclaringTypeHandle = default;\n\t\t\t}\n\t\t\tif (declaringTypeHandle.IsNil)\n\t\t\t{\n\t\t\t\tstring ns;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tns = tr.Namespace.IsNil ? \"\" : reader.GetString(tr.Namespace);\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\tns = \"\";\n\t\t\t\t}\n\t\t\t\treturn new FullTypeName(new TopLevelTypeName(ns, name, typeParameterCount));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn declaringTypeHandle.GetFullTypeName(reader).NestedType(name, typeParameterCount);\n\t\t\t}\n\t\t}\n\n\t\tpublic static FullTypeName GetFullTypeName(this TypeDefinitionHandle handle, MetadataReader reader)\n\t\t{\n\t\t\tif (handle.IsNil)\n\t\t\t\tthrow new ArgumentNullException(nameof(handle));\n\t\t\treturn reader.GetTypeDefinition(handle).GetFullTypeName(reader);\n\t\t}\n\n\t\tpublic static FullTypeName GetFullTypeName(this TypeDefinition td, MetadataReader reader)\n\t\t{\n\t\t\tTypeDefinitionHandle declaringTypeHandle;\n\t\t\tstring name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(\n\t\t\t\treader.GetString(td.Name), out var typeParameterCount);\n\t\t\tif ((declaringTypeHandle = td.GetDeclaringType()).IsNil)\n\t\t\t{\n\t\t\t\tstring @namespace = td.Namespace.IsNil ? \"\" : reader.GetString(td.Namespace);\n\t\t\t\treturn new FullTypeName(new TopLevelTypeName(@namespace, name, typeParameterCount));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn declaringTypeHandle.GetFullTypeName(reader).NestedType(name, typeParameterCount);\n\t\t\t}\n\t\t}\n\n\t\tpublic static FullTypeName GetFullTypeName(this ExportedType type, MetadataReader metadata)\n\t\t{\n\t\t\tstring name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(\n\t\t\t\tmetadata.GetString(type.Name), out int typeParameterCount);\n\t\t\tif (type.Implementation.Kind == HandleKind.ExportedType)\n\t\t\t{\n\t\t\t\tvar outerType = metadata.GetExportedType((ExportedTypeHandle)type.Implementation);\n\t\t\t\treturn outerType.GetFullTypeName(metadata).NestedType(name, typeParameterCount);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tstring ns = type.Namespace.IsNil ? \"\" : metadata.GetString(type.Namespace);\n\t\t\t\treturn new TopLevelTypeName(ns, name, typeParameterCount);\n\t\t\t}\n\t\t}\n\n\t\tpublic static bool IsAnonymousType(this TypeDefinition type, MetadataReader metadata)\n\t\t{\n\t\t\tstring name = metadata.GetString(type.Name);\n\t\t\tif (type.Namespace.IsNil && type.HasGeneratedName(metadata)\n\t\t\t\t&& (name.Contains(\"AnonType\") || name.Contains(\"AnonymousType\")))\n\t\t\t{\n\t\t\t\treturn type.IsCompilerGenerated(metadata);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t#region HasGeneratedName\n\n\t\tpublic static bool IsGeneratedName(this StringHandle handle, MetadataReader metadata)\n\t\t{\n\t\t\treturn !handle.IsNil\n\t\t\t\t&& (metadata.GetString(handle).StartsWith(\"<\", StringComparison.Ordinal)\n\t\t\t\t|| metadata.GetString(handle).Contains(\"$\"));\n\t\t}\n\n\t\tpublic static bool HasGeneratedName(this MethodDefinitionHandle handle, MetadataReader metadata)\n\t\t{\n\t\t\treturn metadata.GetMethodDefinition(handle).Name.IsGeneratedName(metadata);\n\t\t}\n\n\t\tpublic static bool HasGeneratedName(this TypeDefinitionHandle handle, MetadataReader metadata)\n\t\t{\n\t\t\treturn metadata.GetTypeDefinition(handle).Name.IsGeneratedName(metadata);\n\t\t}\n\n\t\tpublic static bool HasGeneratedName(this TypeDefinition type, MetadataReader metadata)\n\t\t{\n\t\t\treturn type.Name.IsGeneratedName(metadata);\n\t\t}\n\n\t\tpublic static bool HasGeneratedName(this FieldDefinitionHandle handle, MetadataReader metadata)\n\t\t{\n\t\t\treturn metadata.GetFieldDefinition(handle).Name.IsGeneratedName(metadata);\n\t\t}\n\n\t\t#endregion\n\n\t\t#region IsCompilerGenerated\n\n\t\tpublic static bool IsCompilerGenerated(this MethodDefinitionHandle handle, MetadataReader metadata)\n\t\t{\n\t\t\treturn metadata.GetMethodDefinition(handle).IsCompilerGenerated(metadata);\n\t\t}\n\n\t\tpublic static bool IsCompilerGeneratedOrIsInCompilerGeneratedClass(this MethodDefinitionHandle handle,\n\t\t\tMetadataReader metadata)\n\t\t{\n\t\t\tMethodDefinition method = metadata.GetMethodDefinition(handle);\n\t\t\tif (method.IsCompilerGenerated(metadata))\n\t\t\t\treturn true;\n\t\t\tTypeDefinitionHandle declaringTypeHandle = method.GetDeclaringType();\n\t\t\tif (!declaringTypeHandle.IsNil && declaringTypeHandle.IsCompilerGenerated(metadata))\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool IsCompilerGeneratedOrIsInCompilerGeneratedClass(this TypeDefinitionHandle handle,\n\t\t\tMetadataReader metadata)\n\t\t{\n\t\t\tTypeDefinition type = metadata.GetTypeDefinition(handle);\n\t\t\tif (type.IsCompilerGenerated(metadata))\n\t\t\t\treturn true;\n\t\t\tTypeDefinitionHandle declaringTypeHandle = type.GetDeclaringType();\n\t\t\tif (!declaringTypeHandle.IsNil && declaringTypeHandle.IsCompilerGenerated(metadata))\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool IsCompilerGenerated(this MethodDefinition method, MetadataReader metadata)\n\t\t{\n\t\t\treturn method.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.CompilerGenerated);\n\t\t}\n\n\t\tpublic static bool IsCompilerGenerated(this FieldDefinitionHandle handle, MetadataReader metadata)\n\t\t{\n\t\t\treturn metadata.GetFieldDefinition(handle).IsCompilerGenerated(metadata);\n\t\t}\n\n\t\tpublic static bool IsCompilerGenerated(this FieldDefinition field, MetadataReader metadata)\n\t\t{\n\t\t\treturn field.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.CompilerGenerated);\n\t\t}\n\n\t\tpublic static bool IsCompilerGenerated(this TypeDefinitionHandle handle, MetadataReader metadata)\n\t\t{\n\t\t\treturn metadata.GetTypeDefinition(handle).IsCompilerGenerated(metadata);\n\t\t}\n\n\t\tpublic static bool IsCompilerGenerated(this TypeDefinition type, MetadataReader metadata)\n\t\t{\n\t\t\treturn type.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.CompilerGenerated);\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Attribute extensions\n\t\t/// <summary>\n\t\t/// Gets the type of the attribute.\n\t\t/// </summary>\n\t\tpublic static EntityHandle GetAttributeType(this SRM.CustomAttribute attribute, MetadataReader reader)\n\t\t{\n\t\t\tswitch (attribute.Constructor.Kind)\n\t\t\t{\n\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\tvar md = reader.GetMethodDefinition((MethodDefinitionHandle)attribute.Constructor);\n\t\t\t\t\treturn md.GetDeclaringType();\n\t\t\t\tcase HandleKind.MemberReference:\n\t\t\t\t\tvar mr = reader.GetMemberReference((MemberReferenceHandle)attribute.Constructor);\n\t\t\t\t\treturn mr.Parent;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new BadImageFormatException(\"Unexpected token kind for attribute constructor: \"\n\t\t\t\t\t\t+ attribute.Constructor.Kind);\n\t\t\t}\n\t\t}\n\n\t\tpublic static bool HasKnownAttribute(this CustomAttributeHandleCollection customAttributes,\n\t\t\tMetadataReader metadata, KnownAttribute type)\n\t\t{\n\t\t\tforeach (var handle in customAttributes)\n\t\t\t{\n\t\t\t\tvar customAttribute = metadata.GetCustomAttribute(handle);\n\t\t\t\tif (customAttribute.IsKnownAttribute(metadata, type))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tinternal static bool IsKnownAttribute(this SRM.CustomAttribute attr, MetadataReader metadata,\n\t\t\tKnownAttribute attrType)\n\t\t{\n\t\t\treturn attr.GetAttributeType(metadata).IsKnownType(metadata, attrType);\n\t\t}\n\n\t\tpublic static Nullability? GetNullableContext(this CustomAttributeHandleCollection customAttributes,\n\t\t\tMetadataReader metadata)\n\t\t{\n\t\t\tforeach (var handle in customAttributes)\n\t\t\t{\n\t\t\t\tvar customAttribute = metadata.GetCustomAttribute(handle);\n\t\t\t\tif (customAttribute.IsKnownAttribute(metadata, KnownAttribute.NullableContext))\n\t\t\t\t{\n\t\t\t\t\t// Decode \n\t\t\t\t\tCustomAttributeValue<IType> value;\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue = customAttribute.DecodeValue(\n\t\t\t\t\t\t\tMetadata.MetadataExtensions.MinimalAttributeTypeProvider);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tcatch (Metadata.EnumUnderlyingTypeResolveException)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (value.FixedArguments.Length == 1 && value.FixedArguments[0].Value is byte b && b <= 2)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn (Nullability)b;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\t#endregion\n\n\t\tpublic static unsafe BlobReader GetInitialValue(this FieldDefinition field, MetadataFile pefile,\n\t\t\tICompilation typeSystem)\n\t\t{\n\t\t\tif (!field.HasFlag(FieldAttributes.HasFieldRVA))\n\t\t\t\treturn default;\n\t\t\tint rva = field.GetRelativeVirtualAddress();\n\t\t\tif (rva == 0)\n\t\t\t\treturn default;\n\t\t\tint size = field.DecodeSignature(new FieldValueSizeDecoder(typeSystem), default);\n\t\t\tvar sectionData = pefile.GetSectionData(rva);\n\t\t\tif (sectionData.Length == 0 && size != 0)\n\t\t\t\tthrow new BadImageFormatException($\"Field data (rva=0x{rva:x}) could not be found\"\n\t\t\t\t\t+ \" in any section!\");\n\t\t\tif (size < 0 || size > sectionData.Length)\n\t\t\t\tthrow new BadImageFormatException($\"Invalid size {size} for field data!\");\n\t\t\treturn sectionData.GetReader(0, size);\n\t\t}\n\n\t\tsealed class FieldValueSizeDecoder : ISignatureTypeProvider<int, GenericContext>\n\t\t{\n\t\t\treadonly MetadataModule module;\n\t\t\treadonly int pointerSize;\n\n\t\t\tpublic FieldValueSizeDecoder(ICompilation typeSystem = null)\n\t\t\t{\n\t\t\t\tthis.module = (MetadataModule)typeSystem?.MainModule;\n\t\t\t\tif (module?.MetadataFile is not PEFile pefile)\n\t\t\t\t\tthis.pointerSize = IntPtr.Size;\n\t\t\t\telse\n\t\t\t\t\tthis.pointerSize = pefile.Reader.PEHeaders.PEHeader.Magic == PEMagic.PE32 ? 4 : 8;\n\t\t\t}\n\n\t\t\tpublic int GetArrayType(int elementType, ArrayShape shape) =>\n\t\t\t\tGetPrimitiveType(PrimitiveTypeCode.Object);\n\t\t\tpublic int GetSZArrayType(int elementType) => GetPrimitiveType(PrimitiveTypeCode.Object);\n\t\t\tpublic int GetByReferenceType(int elementType) => pointerSize;\n\t\t\tpublic int GetFunctionPointerType(MethodSignature<int> signature) => pointerSize;\n\t\t\tpublic int GetGenericInstantiation(int genericType, ImmutableArray<int> typeArguments)\n\t\t\t\t=> genericType;\n\t\t\tpublic int GetGenericMethodParameter(GenericContext genericContext, int index) => 0;\n\t\t\tpublic int GetGenericTypeParameter(GenericContext genericContext, int index) => 0;\n\t\t\tpublic int GetModifiedType(int modifier, int unmodifiedType, bool isRequired) => unmodifiedType;\n\t\t\tpublic int GetPinnedType(int elementType) => elementType;\n\t\t\tpublic int GetPointerType(int elementType) => pointerSize;\n\n\t\t\tpublic int GetPrimitiveType(PrimitiveTypeCode typeCode)\n\t\t\t{\n\t\t\t\tswitch (typeCode)\n\t\t\t\t{\n\t\t\t\t\tcase PrimitiveTypeCode.Boolean:\n\t\t\t\t\tcase PrimitiveTypeCode.Byte:\n\t\t\t\t\tcase PrimitiveTypeCode.SByte:\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\tcase PrimitiveTypeCode.Char:\n\t\t\t\t\tcase PrimitiveTypeCode.Int16:\n\t\t\t\t\tcase PrimitiveTypeCode.UInt16:\n\t\t\t\t\t\treturn 2;\n\t\t\t\t\tcase PrimitiveTypeCode.Int32:\n\t\t\t\t\tcase PrimitiveTypeCode.UInt32:\n\t\t\t\t\tcase PrimitiveTypeCode.Single:\n\t\t\t\t\t\treturn 4;\n\t\t\t\t\tcase PrimitiveTypeCode.Int64:\n\t\t\t\t\tcase PrimitiveTypeCode.UInt64:\n\t\t\t\t\tcase PrimitiveTypeCode.Double:\n\t\t\t\t\t\treturn 8;\n\t\t\t\t\tcase PrimitiveTypeCode.IntPtr:\n\t\t\t\t\tcase PrimitiveTypeCode.UIntPtr:\n\t\t\t\t\t\treturn pointerSize;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic int GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle,\n\t\t\t\tbyte rawTypeKind)\n\t\t\t{\n\t\t\t\tvar td = reader.GetTypeDefinition(handle);\n\t\t\t\treturn td.GetLayout().Size;\n\t\t\t}\n\n\t\t\tpublic int GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle,\n\t\t\t\tbyte rawTypeKind)\n\t\t\t{\n\t\t\t\tvar typeDef = module?.ResolveType(handle, new GenericContext()).GetDefinition();\n\t\t\t\tif (typeDef == null || typeDef.MetadataToken.IsNil)\n\t\t\t\t\treturn 0;\n\t\t\t\treader = typeDef.ParentModule.MetadataFile.Metadata;\n\t\t\t\tvar td = reader.GetTypeDefinition((TypeDefinitionHandle)typeDef.MetadataToken);\n\t\t\t\treturn td.GetLayout().Size;\n\t\t\t}\n\n\t\t\tpublic int GetTypeFromSpecification(MetadataReader reader, GenericContext genericContext,\n\t\t\t\tTypeSpecificationHandle handle, byte rawTypeKind)\n\t\t\t{\n\t\t\t\treturn reader.GetTypeSpecification(handle).DecodeSignature(this, genericContext);\n\t\t\t}\n\t\t}\n\n\t\tpublic static EntityHandle GetBaseTypeOrNil(this TypeDefinition definition)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn definition.BaseType;\n\t\t\t}\n\t\t\tcatch (BadImageFormatException)\n\t\t\t{\n\t\t\t\treturn default;\n\t\t\t}\n\t\t}\n\n\t\tpublic static string ToILSyntax(this SignatureCallingConvention callConv)\n\t\t{\n\t\t\treturn callConv switch {\n\t\t\t\tSignatureCallingConvention.Default => \"default\",\n\t\t\t\tSignatureCallingConvention.CDecl => \"unmanaged cdecl\",\n\t\t\t\tSignatureCallingConvention.StdCall => \"unmanaged stdcall\",\n\t\t\t\tSignatureCallingConvention.ThisCall => \"unmanaged thiscall\",\n\t\t\t\tSignatureCallingConvention.FastCall => \"unmanaged fastcall\",\n\t\t\t\tSignatureCallingConvention.VarArgs => \"vararg\",\n\t\t\t\tSignatureCallingConvention.Unmanaged => \"unmanaged\",\n\t\t\t\t_ => callConv.ToString().ToLowerInvariant()\n\t\t\t};\n\t\t}\n\n\t\tpublic static UnmanagedMemoryStream AsStream(this MemoryMappedViewAccessor view)\n\t\t{\n\t\t\tlong size = checked((long)view.SafeMemoryMappedViewHandle.ByteLength);\n\t\t\treturn new UnmanagedMemoryStream(view.SafeMemoryMappedViewHandle, 0, size);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/SRMHacks.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Text;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.Decompiler\n{\n\tpublic static partial class SRMExtensions\n\t{\n\t\tinternal const GenericParameterAttributes AllowByRefLike = (GenericParameterAttributes)0x0020;\n\n\t\tpublic static ImmutableArray<MethodImplementationHandle> GetMethodImplementations(\n\t\t\tthis MethodDefinitionHandle handle, MetadataReader reader)\n\t\t{\n\t\t\tvar resultBuilder = ImmutableArray.CreateBuilder<MethodImplementationHandle>();\n\t\t\tvar typeDefinition = reader.GetTypeDefinition(reader.GetMethodDefinition(handle)\n\t\t\t\t.GetDeclaringType());\n\n\t\t\tforeach (var methodImplementationHandle in typeDefinition.GetMethodImplementations())\n\t\t\t{\n\t\t\t\tvar methodImplementation = reader.GetMethodImplementation(methodImplementationHandle);\n\t\t\t\tif (methodImplementation.MethodBody == handle)\n\t\t\t\t{\n\t\t\t\t\tresultBuilder.Add(methodImplementationHandle);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn resultBuilder.ToImmutable();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/AmbiguousResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Represents an ambiguous type resolve result.\n\t/// </summary>\n\tpublic class AmbiguousTypeResolveResult : TypeResolveResult\n\t{\n\t\tpublic AmbiguousTypeResolveResult(IType type) : base(type)\n\t\t{\n\t\t}\n\n\t\tpublic override bool IsError {\n\t\t\tget { return true; }\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Represents an ambiguous field/property/event access.\n\t/// </summary>\n\tpublic class AmbiguousMemberResolveResult : MemberResolveResult\n\t{\n\t\tpublic AmbiguousMemberResolveResult(ResolveResult targetResult, IMember member) : base(targetResult, member)\n\t\t{\n\t\t}\n\n\t\tpublic override bool IsError {\n\t\t\tget { return true; }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/ArrayAccessResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Resolve result representing an array access.\n\t/// </summary>\n\tpublic class ArrayAccessResolveResult : ResolveResult\n\t{\n\t\tpublic readonly ResolveResult Array;\n\t\tpublic readonly IList<ResolveResult> Indexes;\n\n\t\tpublic ArrayAccessResolveResult(IType elementType, ResolveResult array, IList<ResolveResult> indexes) : base(elementType)\n\t\t{\n\t\t\tif (array == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(array));\n\t\t\tif (indexes == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(indexes));\n\t\t\tthis.Array = array;\n\t\t\tthis.Indexes = indexes;\n\t\t}\n\n\t\tpublic override IEnumerable<ResolveResult> GetChildResults()\n\t\t{\n\t\t\treturn new[] { Array }.Concat(Indexes);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/ArrayCreateResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Resolve result representing an array creation.\n\t/// </summary>\n\tpublic class ArrayCreateResolveResult : ResolveResult\n\t{\n\t\t/// <summary>\n\t\t/// Gets the size arguments.\n\t\t/// </summary>\n\t\tpublic readonly IReadOnlyList<ResolveResult> SizeArguments;\n\n\t\t/// <summary>\n\t\t/// Gets the initializer elements.\n\t\t/// This field may be null if no initializer was specified.\n\t\t/// </summary>\n\t\tpublic readonly IReadOnlyList<ResolveResult> InitializerElements;\n\n\t\tpublic ArrayCreateResolveResult(IType arrayType, IReadOnlyList<ResolveResult> sizeArguments, IReadOnlyList<ResolveResult> initializerElements)\n\t\t\t: base(arrayType)\n\t\t{\n\t\t\tif (sizeArguments == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(sizeArguments));\n\t\t\tthis.SizeArguments = sizeArguments;\n\t\t\tthis.InitializerElements = initializerElements;\n\t\t}\n\n\t\tpublic override IEnumerable<ResolveResult> GetChildResults()\n\t\t{\n\t\t\tif (InitializerElements != null)\n\t\t\t\treturn SizeArguments.Concat(InitializerElements);\n\t\t\telse\n\t\t\t\treturn SizeArguments;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/ByReferenceResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Represents the resolve result of an 'ref x', 'in x' or 'out x' expression.\n\t/// </summary>\n\tpublic class ByReferenceResolveResult : ResolveResult\n\t{\n\t\tpublic ReferenceKind ReferenceKind { get; }\n\n\t\tpublic readonly ResolveResult ElementResult;\n\n\t\tpublic ByReferenceResolveResult(ResolveResult elementResult, ReferenceKind kind)\n\t\t\t: this(elementResult.Type, kind)\n\t\t{\n\t\t\tthis.ElementResult = elementResult;\n\t\t}\n\n\t\t/// <remarks>\n\t\t/// Should only be used for temporary ResolveResults in TypeInference and CSharpConversions, etc.\n\t\t/// </remarks>\n\t\tinternal ByReferenceResolveResult(IType elementType, ReferenceKind kind)\n\t\t\t: base(new ByReferenceType(elementType))\n\t\t{\n\t\t\tthis.ReferenceKind = kind;\n\t\t}\n\n\t\tpublic IType ElementType {\n\t\t\tget { return ((ByReferenceType)this.Type).ElementType; }\n\t\t}\n\n\t\tpublic override IEnumerable<ResolveResult> GetChildResults()\n\t\t{\n\t\t\tif (ElementResult != null)\n\t\t\t\treturn new[] { ElementResult };\n\t\t\telse\n\t\t\t\treturn Enumerable.Empty<ResolveResult>();\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(CultureInfo.InvariantCulture, \"[{0} {1} {2}]\", GetType().Name, ReferenceKind.ToString().ToLowerInvariant(), ElementType);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/ConstantResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Globalization;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// ResolveResult representing a compile-time constant.\n\t/// Note: this class is mainly used for literals; there may be other ResolveResult classes\n\t/// which are compile-time constants as well.\n\t/// For example, a reference to a <c>const</c> field results in a <see cref=\"MemberResolveResult\"/>.\n\t/// \n\t/// Check <see cref=\"ResolveResult.IsCompileTimeConstant\"/> to determine is a resolve result is a constant.\n\t/// </summary>\n\tpublic class ConstantResolveResult : ResolveResult\n\t{\n\t\tobject constantValue;\n\n\t\tpublic ConstantResolveResult(IType type, object constantValue) : base(type)\n\t\t{\n\t\t\tthis.constantValue = constantValue;\n\t\t}\n\n\t\tpublic override bool IsCompileTimeConstant {\n\t\t\tget { return true; }\n\t\t}\n\n\t\tpublic override object ConstantValue {\n\t\t\tget { return constantValue; }\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(CultureInfo.InvariantCulture, \"[{0} {1} = {2}]\", GetType().Name, this.Type, constantValue);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/Conversion.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Immutable;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Holds information about a conversion between two types.\n\t/// </summary>\n\tpublic abstract class Conversion : IEquatable<Conversion>\n\t{\n\t\t#region Conversion factory methods\n\t\t/// <summary>\n\t\t/// Not a valid conversion.\n\t\t/// </summary>\n\t\tpublic static readonly Conversion None = new InvalidConversion();\n\n\t\t/// <summary>\n\t\t/// Identity conversion.\n\t\t/// </summary>\n\t\tpublic static readonly Conversion IdentityConversion = new BuiltinConversion(true, 0);\n\n\t\tpublic static readonly Conversion ImplicitNumericConversion = new NumericOrEnumerationConversion(true, false);\n\t\tpublic static readonly Conversion ExplicitNumericConversion = new NumericOrEnumerationConversion(false, false);\n\t\tpublic static readonly Conversion ImplicitLiftedNumericConversion = new NumericOrEnumerationConversion(true, true);\n\t\tpublic static readonly Conversion ExplicitLiftedNumericConversion = new NumericOrEnumerationConversion(false, true);\n\n\t\tpublic static Conversion EnumerationConversion(bool isImplicit, bool isLifted)\n\t\t{\n\t\t\treturn new NumericOrEnumerationConversion(isImplicit, isLifted, true);\n\t\t}\n\n\t\tpublic static readonly Conversion NullLiteralConversion = new BuiltinConversion(true, 1);\n\n\t\t/// <summary>\n\t\t/// The numeric conversion of a constant expression.\n\t\t/// </summary>\n\t\tpublic static readonly Conversion ImplicitConstantExpressionConversion = new BuiltinConversion(true, 2);\n\n\t\tpublic static readonly Conversion ImplicitReferenceConversion = new BuiltinConversion(true, 3);\n\t\tpublic static readonly Conversion ExplicitReferenceConversion = new BuiltinConversion(false, 3);\n\n\t\tpublic static readonly Conversion ImplicitDynamicConversion = new BuiltinConversion(true, 4);\n\t\tpublic static readonly Conversion ExplicitDynamicConversion = new BuiltinConversion(false, 4);\n\n\t\tpublic static readonly Conversion ImplicitNullableConversion = new BuiltinConversion(true, 5);\n\t\tpublic static readonly Conversion ExplicitNullableConversion = new BuiltinConversion(false, 5);\n\n\t\tpublic static readonly Conversion ImplicitPointerConversion = new BuiltinConversion(true, 6);\n\t\tpublic static readonly Conversion ExplicitPointerConversion = new BuiltinConversion(false, 6);\n\n\t\tpublic static readonly Conversion BoxingConversion = new BuiltinConversion(true, 7);\n\t\tpublic static readonly Conversion UnboxingConversion = new BuiltinConversion(false, 8);\n\n\t\t/// <summary>\n\t\t/// C# 'as' cast.\n\t\t/// </summary>\n\t\tpublic static readonly Conversion TryCast = new BuiltinConversion(false, 9);\n\n\t\t/// <summary>\n\t\t/// C# 6 string interpolation expression implicitly being converted to <see cref=\"System.IFormattable\"/> or <see cref=\"System.FormattableString\"/>.\n\t\t/// </summary>\n\t\tpublic static readonly Conversion ImplicitInterpolatedStringConversion = new BuiltinConversion(true, 10);\n\n\t\t/// <summary>\n\t\t/// C# 7 throw expression being converted to an arbitrary type.\n\t\t/// </summary>\n\t\tpublic static readonly Conversion ThrowExpressionConversion = new BuiltinConversion(true, 11);\n\n\t\t/// <summary>\n\t\t/// C# 12 inline array implicitly being converted to <see cref=\"System.Span{T}\"/> or <see cref=\"System.ReadOnlySpan{T}\"/>.\n\t\t/// </summary>\n\t\tpublic static readonly Conversion InlineArrayConversion = new BuiltinConversion(true, 12);\n\n\t\t/// <summary>\n\t\t/// C# 14 implicit span conversion from an array type to <see cref=\"System.Span{T}\"/> or <see cref=\"System.ReadOnlySpan{T}\"/>.\n\t\t/// </summary>\n\t\tpublic static readonly Conversion ImplicitSpanConversion = new BuiltinConversion(true, 13);\n\n\t\tpublic static Conversion UserDefinedConversion(IMethod operatorMethod, bool isImplicit, Conversion conversionBeforeUserDefinedOperator, Conversion conversionAfterUserDefinedOperator, bool isLifted = false, bool isAmbiguous = false)\n\t\t{\n\t\t\tif (operatorMethod == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(operatorMethod));\n\t\t\treturn new UserDefinedConv(isImplicit, operatorMethod, conversionBeforeUserDefinedOperator, conversionAfterUserDefinedOperator, isLifted, isAmbiguous);\n\t\t}\n\n\t\tpublic static Conversion MethodGroupConversion(IMethod chosenMethod, bool isVirtualMethodLookup, bool delegateCapturesFirstArgument)\n\t\t{\n\t\t\tif (chosenMethod == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(chosenMethod));\n\t\t\treturn new MethodGroupConv(chosenMethod, isVirtualMethodLookup, delegateCapturesFirstArgument, isValid: true);\n\t\t}\n\n\t\tpublic static Conversion InvalidMethodGroupConversion(IMethod chosenMethod, bool isVirtualMethodLookup, bool delegateCapturesFirstArgument)\n\t\t{\n\t\t\tif (chosenMethod == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(chosenMethod));\n\t\t\treturn new MethodGroupConv(chosenMethod, isVirtualMethodLookup, delegateCapturesFirstArgument, isValid: false);\n\t\t}\n\n\t\tpublic static Conversion TupleConversion(ImmutableArray<Conversion> conversions)\n\t\t{\n\t\t\treturn new TupleConv(conversions);\n\t\t}\n\t\t#endregion\n\n\t\t#region Inner classes\n\t\tsealed class InvalidConversion : Conversion\n\t\t{\n\t\t\tpublic override bool IsValid {\n\t\t\t\tget { return false; }\n\t\t\t}\n\n\t\t\tpublic override string ToString()\n\t\t\t{\n\t\t\t\treturn \"None\";\n\t\t\t}\n\t\t}\n\n\t\tsealed class NumericOrEnumerationConversion : Conversion\n\t\t{\n\t\t\treadonly bool isImplicit;\n\t\t\treadonly bool isLifted;\n\t\t\treadonly bool isEnumeration;\n\n\t\t\tpublic NumericOrEnumerationConversion(bool isImplicit, bool isLifted, bool isEnumeration = false)\n\t\t\t{\n\t\t\t\tthis.isImplicit = isImplicit;\n\t\t\t\tthis.isLifted = isLifted;\n\t\t\t\tthis.isEnumeration = isEnumeration;\n\t\t\t}\n\n\t\t\tpublic override bool IsImplicit {\n\t\t\t\tget { return isImplicit; }\n\t\t\t}\n\n\t\t\tpublic override bool IsExplicit {\n\t\t\t\tget { return !isImplicit; }\n\t\t\t}\n\n\t\t\tpublic override bool IsNumericConversion {\n\t\t\t\tget { return !isEnumeration; }\n\t\t\t}\n\n\t\t\tpublic override bool IsEnumerationConversion {\n\t\t\t\tget { return isEnumeration; }\n\t\t\t}\n\n\t\t\tpublic override bool IsLifted {\n\t\t\t\tget { return isLifted; }\n\t\t\t}\n\n\t\t\tpublic override string ToString()\n\t\t\t{\n\t\t\t\treturn (isImplicit ? \"implicit\" : \"explicit\")\n\t\t\t\t\t+ (isLifted ? \" lifted\" : \"\")\n\t\t\t\t\t+ (isEnumeration ? \" enumeration\" : \" numeric\")\n\t\t\t\t\t+ \" conversion\";\n\t\t\t}\n\n\t\t\tpublic override bool Equals(Conversion other)\n\t\t\t{\n\t\t\t\tNumericOrEnumerationConversion o = other as NumericOrEnumerationConversion;\n\t\t\t\treturn o != null && isImplicit == o.isImplicit && isLifted == o.isLifted && isEnumeration == o.isEnumeration;\n\t\t\t}\n\n\t\t\tpublic override int GetHashCode()\n\t\t\t{\n\t\t\t\treturn (isImplicit ? 1 : 0) + (isLifted ? 2 : 0) + (isEnumeration ? 4 : 0);\n\t\t\t}\n\t\t}\n\n\t\tsealed class BuiltinConversion : Conversion\n\t\t{\n\t\t\treadonly bool isImplicit;\n\t\t\treadonly byte type;\n\n\t\t\tpublic BuiltinConversion(bool isImplicit, byte type)\n\t\t\t{\n\t\t\t\tthis.isImplicit = isImplicit;\n\t\t\t\tthis.type = type;\n\t\t\t}\n\n\t\t\tpublic override bool IsImplicit {\n\t\t\t\tget { return isImplicit; }\n\t\t\t}\n\n\t\t\tpublic override bool IsExplicit {\n\t\t\t\tget { return !isImplicit; }\n\t\t\t}\n\n\t\t\tpublic override bool IsIdentityConversion {\n\t\t\t\tget { return type == 0; }\n\t\t\t}\n\n\t\t\tpublic override bool IsNullLiteralConversion {\n\t\t\t\tget { return type == 1; }\n\t\t\t}\n\n\t\t\tpublic override bool IsConstantExpressionConversion {\n\t\t\t\tget { return type == 2; }\n\t\t\t}\n\n\t\t\tpublic override bool IsReferenceConversion {\n\t\t\t\tget { return type == 3; }\n\t\t\t}\n\n\t\t\tpublic override bool IsDynamicConversion {\n\t\t\t\tget { return type == 4; }\n\t\t\t}\n\n\t\t\tpublic override bool IsNullableConversion {\n\t\t\t\tget { return type == 5; }\n\t\t\t}\n\n\t\t\tpublic override bool IsPointerConversion {\n\t\t\t\tget { return type == 6; }\n\t\t\t}\n\n\t\t\tpublic override bool IsBoxingConversion {\n\t\t\t\tget { return type == 7; }\n\t\t\t}\n\n\t\t\tpublic override bool IsUnboxingConversion {\n\t\t\t\tget { return type == 8; }\n\t\t\t}\n\n\t\t\tpublic override bool IsTryCast {\n\t\t\t\tget { return type == 9; }\n\t\t\t}\n\n\t\t\tpublic override bool IsInterpolatedStringConversion => type == 10;\n\n\t\t\tpublic override bool IsThrowExpressionConversion {\n\t\t\t\tget { return type == 11; }\n\t\t\t}\n\n\t\t\tpublic override bool IsInlineArrayConversion => type == 12;\n\t\t\tpublic override bool IsImplicitSpanConversion => type == 13;\n\n\t\t\tpublic override string ToString()\n\t\t\t{\n\t\t\t\tstring name = null;\n\t\t\t\tswitch (type)\n\t\t\t\t{\n\t\t\t\t\tcase 0:\n\t\t\t\t\t\treturn \"identity conversion\";\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\treturn \"null-literal conversion\";\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tname = \"constant-expression\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\tname = \"reference\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 4:\n\t\t\t\t\t\tname = \"dynamic\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 5:\n\t\t\t\t\t\tname = \"nullable\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 6:\n\t\t\t\t\t\tname = \"pointer\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 7:\n\t\t\t\t\t\treturn \"boxing conversion\";\n\t\t\t\t\tcase 8:\n\t\t\t\t\t\treturn \"unboxing conversion\";\n\t\t\t\t\tcase 9:\n\t\t\t\t\t\treturn \"try cast\";\n\t\t\t\t\tcase 10:\n\t\t\t\t\t\treturn \"interpolated string\";\n\t\t\t\t\tcase 11:\n\t\t\t\t\t\treturn \"throw-expression conversion\";\n\t\t\t\t\tcase 12:\n\t\t\t\t\t\treturn \"inline array conversion\";\n\t\t\t\t\tcase 13:\n\t\t\t\t\t\treturn \"implicit span conversion\";\n\t\t\t\t}\n\t\t\t\treturn (isImplicit ? \"implicit \" : \"explicit \") + name + \" conversion\";\n\t\t\t}\n\t\t}\n\n\t\tsealed class UserDefinedConv : Conversion\n\t\t{\n\t\t\treadonly IMethod method;\n\t\t\treadonly bool isLifted;\n\t\t\treadonly Conversion conversionBeforeUserDefinedOperator;\n\t\t\treadonly Conversion conversionAfterUserDefinedOperator;\n\t\t\treadonly bool isImplicit;\n\t\t\treadonly bool isValid;\n\n\t\t\tpublic UserDefinedConv(bool isImplicit, IMethod method, Conversion conversionBeforeUserDefinedOperator, Conversion conversionAfterUserDefinedOperator, bool isLifted, bool isAmbiguous)\n\t\t\t{\n\t\t\t\tthis.method = method;\n\t\t\t\tthis.isLifted = isLifted;\n\t\t\t\tthis.conversionBeforeUserDefinedOperator = conversionBeforeUserDefinedOperator;\n\t\t\t\tthis.conversionAfterUserDefinedOperator = conversionAfterUserDefinedOperator;\n\t\t\t\tthis.isImplicit = isImplicit;\n\t\t\t\tthis.isValid = !isAmbiguous;\n\t\t\t}\n\n\t\t\tpublic override bool IsValid {\n\t\t\t\tget { return isValid; }\n\t\t\t}\n\n\t\t\tpublic override bool IsImplicit {\n\t\t\t\tget { return isImplicit; }\n\t\t\t}\n\n\t\t\tpublic override bool IsExplicit {\n\t\t\t\tget { return !isImplicit; }\n\t\t\t}\n\n\t\t\tpublic override bool IsLifted {\n\t\t\t\tget { return isLifted; }\n\t\t\t}\n\n\t\t\tpublic override bool IsUserDefined {\n\t\t\t\tget { return true; }\n\t\t\t}\n\n\t\t\tpublic override Conversion ConversionBeforeUserDefinedOperator {\n\t\t\t\tget { return conversionBeforeUserDefinedOperator; }\n\t\t\t}\n\n\t\t\tpublic override Conversion ConversionAfterUserDefinedOperator {\n\t\t\t\tget { return conversionAfterUserDefinedOperator; }\n\t\t\t}\n\n\t\t\tpublic override IMethod Method {\n\t\t\t\tget { return method; }\n\t\t\t}\n\n\t\t\tpublic override bool Equals(Conversion other)\n\t\t\t{\n\t\t\t\tUserDefinedConv o = other as UserDefinedConv;\n\t\t\t\treturn o != null && isLifted == o.isLifted && isImplicit == o.isImplicit && isValid == o.isValid && method.Equals(o.method);\n\t\t\t}\n\n\t\t\tpublic override int GetHashCode()\n\t\t\t{\n\t\t\t\treturn unchecked(method.GetHashCode() + (isLifted ? 31 : 27) + (isImplicit ? 71 : 61) + (isValid ? 107 : 109));\n\t\t\t}\n\n\t\t\tpublic override string ToString()\n\t\t\t{\n\t\t\t\treturn (isImplicit ? \"implicit\" : \"explicit\")\n\t\t\t\t\t+ (isLifted ? \" lifted\" : \"\")\n\t\t\t\t\t+ (isValid ? \"\" : \" ambiguous\")\n\t\t\t\t\t+ \"user-defined conversion (\" + method + \")\";\n\t\t\t}\n\t\t}\n\n\t\tsealed class MethodGroupConv : Conversion\n\t\t{\n\t\t\treadonly IMethod method;\n\t\t\treadonly bool isVirtualMethodLookup;\n\t\t\treadonly bool delegateCapturesFirstArgument;\n\t\t\treadonly bool isValid;\n\n\t\t\tpublic MethodGroupConv(IMethod method, bool isVirtualMethodLookup, bool delegateCapturesFirstArgument, bool isValid)\n\t\t\t{\n\t\t\t\tthis.method = method;\n\t\t\t\tthis.isVirtualMethodLookup = isVirtualMethodLookup;\n\t\t\t\tthis.delegateCapturesFirstArgument = delegateCapturesFirstArgument;\n\t\t\t\tthis.isValid = isValid;\n\t\t\t}\n\n\t\t\tpublic override bool IsValid {\n\t\t\t\tget { return isValid; }\n\t\t\t}\n\n\t\t\tpublic override bool IsImplicit {\n\t\t\t\tget { return true; }\n\t\t\t}\n\n\t\t\tpublic override bool IsMethodGroupConversion {\n\t\t\t\tget { return true; }\n\t\t\t}\n\n\t\t\tpublic override bool IsVirtualMethodLookup {\n\t\t\t\tget { return isVirtualMethodLookup; }\n\t\t\t}\n\n\t\t\tpublic override bool DelegateCapturesFirstArgument {\n\t\t\t\tget { return delegateCapturesFirstArgument; }\n\t\t\t}\n\n\t\t\tpublic override IMethod Method {\n\t\t\t\tget { return method; }\n\t\t\t}\n\n\t\t\tpublic override bool Equals(Conversion other)\n\t\t\t{\n\t\t\t\tMethodGroupConv o = other as MethodGroupConv;\n\t\t\t\treturn o != null && method.Equals(o.method);\n\t\t\t}\n\n\t\t\tpublic override int GetHashCode()\n\t\t\t{\n\t\t\t\treturn method.GetHashCode();\n\t\t\t}\n\t\t}\n\n\t\tsealed class TupleConv : Conversion\n\t\t{\n\t\t\tpublic override bool IsImplicit { get; }\n\t\t\tpublic override bool IsExplicit => !IsImplicit;\n\t\t\tpublic override ImmutableArray<Conversion> ElementConversions { get; }\n\t\t\tpublic override bool IsTupleConversion => true;\n\n\t\t\tpublic TupleConv(ImmutableArray<Conversion> elementConversions)\n\t\t\t{\n\t\t\t\tthis.ElementConversions = elementConversions;\n\t\t\t\tthis.IsImplicit = elementConversions.All(c => c.IsImplicit);\n\t\t\t}\n\n\t\t\tpublic override bool Equals(Conversion other)\n\t\t\t{\n\t\t\t\treturn other is TupleConv o\n\t\t\t\t\t&& ElementConversions.SequenceEqual(o.ElementConversions);\n\t\t\t}\n\n\t\t\tpublic override int GetHashCode()\n\t\t\t{\n\t\t\t\tunchecked\n\t\t\t\t{\n\t\t\t\t\tint hash = 0;\n\t\t\t\t\tforeach (var conv in ElementConversions)\n\t\t\t\t\t{\n\t\t\t\t\t\thash *= 31;\n\t\t\t\t\t\thash += conv.GetHashCode();\n\t\t\t\t\t}\n\t\t\t\t\treturn hash;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override string ToString()\n\t\t\t{\n\t\t\t\treturn (IsImplicit ? \"implicit \" : \"explicit \") + \" tuple conversion\";\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t/// <summary>\n\t\t/// Gets whether the conversion is valid.\n\t\t/// </summary>\n\t\tpublic virtual bool IsValid {\n\t\t\tget { return true; }\n\t\t}\n\n\t\tpublic virtual bool IsImplicit {\n\t\t\tget { return false; }\n\t\t}\n\n\t\tpublic virtual bool IsExplicit {\n\t\t\tget { return false; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the conversion is an '<c>as</c>' cast.\n\t\t/// </summary>\n\t\tpublic virtual bool IsTryCast {\n\t\t\tget { return false; }\n\t\t}\n\n\t\tpublic virtual bool IsThrowExpressionConversion {\n\t\t\tget { return false; }\n\t\t}\n\n\t\tpublic virtual bool IsIdentityConversion {\n\t\t\tget { return false; }\n\t\t}\n\n\t\tpublic virtual bool IsNullLiteralConversion {\n\t\t\tget { return false; }\n\t\t}\n\n\t\tpublic virtual bool IsConstantExpressionConversion {\n\t\t\tget { return false; }\n\t\t}\n\n\t\tpublic virtual bool IsNumericConversion {\n\t\t\tget { return false; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this conversion is a lifted version of another conversion.\n\t\t/// </summary>\n\t\tpublic virtual bool IsLifted {\n\t\t\tget { return false; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the conversion is dynamic.\n\t\t/// </summary>\n\t\tpublic virtual bool IsDynamicConversion {\n\t\t\tget { return false; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the conversion is a reference conversion.\n\t\t/// </summary>\n\t\tpublic virtual bool IsReferenceConversion {\n\t\t\tget { return false; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the conversion is an enumeration conversion.\n\t\t/// </summary>\n\t\tpublic virtual bool IsEnumerationConversion {\n\t\t\tget { return false; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the conversion is a nullable conversion\n\t\t/// (conversion between a nullable type and the regular type).\n\t\t/// </summary>\n\t\tpublic virtual bool IsNullableConversion {\n\t\t\tget { return false; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this conversion is user-defined (op_Implicit or op_Explicit).\n\t\t/// </summary>\n\t\tpublic virtual bool IsUserDefined {\n\t\t\tget { return false; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// The conversion that is applied to the input before the user-defined conversion operator is invoked.\n\t\t/// </summary>\n\t\tpublic virtual Conversion ConversionBeforeUserDefinedOperator {\n\t\t\tget { return null; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// The conversion that is applied to the result of the user-defined conversion operator.\n\t\t/// </summary>\n\t\tpublic virtual Conversion ConversionAfterUserDefinedOperator {\n\t\t\tget { return null; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this conversion is a boxing conversion.\n\t\t/// </summary>\n\t\tpublic virtual bool IsBoxingConversion {\n\t\t\tget { return false; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this conversion is an unboxing conversion.\n\t\t/// </summary>\n\t\tpublic virtual bool IsUnboxingConversion {\n\t\t\tget { return false; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this conversion is a pointer conversion.\n\t\t/// </summary>\n\t\tpublic virtual bool IsPointerConversion {\n\t\t\tget { return false; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this conversion is a method group conversion.\n\t\t/// </summary>\n\t\tpublic virtual bool IsMethodGroupConversion {\n\t\t\tget { return false; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// For method-group conversions, gets whether to perform a virtual method lookup at runtime.\n\t\t/// </summary>\n\t\tpublic virtual bool IsVirtualMethodLookup {\n\t\t\tget { return false; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// For method-group conversions, gets whether the conversion captures the first argument.\n\t\t/// \n\t\t/// For instance methods, this property always returns true for C# method-group conversions.\n\t\t/// For static methods, this property returns true for method-group conversions of an extension method performed on an instance (eg. <c>Func&lt;int&gt; f = myEnumerable.Single</c>).\n\t\t/// </summary>\n\t\tpublic virtual bool DelegateCapturesFirstArgument {\n\t\t\tget { return false; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this conversion is an anonymous function conversion.\n\t\t/// </summary>\n\t\tpublic virtual bool IsAnonymousFunctionConversion {\n\t\t\tget { return false; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the method associated with this conversion.\n\t\t/// For user-defined conversions, this is the method being called.\n\t\t/// For method-group conversions, this is the method that was chosen from the group.\n\t\t/// </summary>\n\t\tpublic virtual IMethod Method {\n\t\t\tget { return null; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this conversion is a tuple conversion.\n\t\t/// </summary>\n\t\tpublic virtual bool IsTupleConversion => false;\n\n\t\t/// <summary>\n\t\t/// Gets whether this is an interpolated string conversion to <see cref=\"IFormattable\" /> or <see cref=\"FormattableString\"/>.\n\t\t/// </summary>\n\t\tpublic virtual bool IsInterpolatedStringConversion => false;\n\n\t\t/// <summary>\n\t\t/// Gets whether this is an inline array conversion to <see cref=\"System.Span{T}\"/> or <see cref=\"System.ReadOnlySpan{T}\"/>.\n\t\t/// </summary>\n\t\tpublic virtual bool IsInlineArrayConversion => false;\n\n\t\t/// <summary>\n\t\t/// Gets whether this is an implicit span conversion from an array type to <see cref=\"System.Span{T}\"/> or <see cref=\"System.ReadOnlySpan{T}\"/>.\n\t\t/// </summary>\n\t\tpublic virtual bool IsImplicitSpanConversion => false;\n\n\t\t/// <summary>\n\t\t/// For a tuple conversion, gets the individual tuple element conversions.\n\t\t/// </summary>\n\t\tpublic virtual ImmutableArray<Conversion> ElementConversions => default(ImmutableArray<Conversion>);\n\n\t\tpublic override sealed bool Equals(object obj)\n\t\t{\n\t\t\treturn Equals(obj as Conversion);\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn base.GetHashCode();\n\t\t}\n\n\t\tpublic virtual bool Equals(Conversion other)\n\t\t{\n\t\t\treturn this == other;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/ConversionResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Represents an implicit or explicit type conversion.\n\t/// <c>conversionResolveResult.Input.Type</c> is the source type;\n\t/// <c>conversionResolveResult.Type</c> is the target type.\n\t/// The <see cref=\"Conversion\"/> property provides details about the kind of conversion.\n\t/// </summary>\n\tpublic class ConversionResolveResult : ResolveResult\n\t{\n\t\tpublic readonly ResolveResult Input;\n\t\tpublic readonly Conversion Conversion;\n\n\t\t/// <summary>\n\t\t/// For numeric conversions, specifies whether overflow checking is enabled.\n\t\t/// </summary>\n\t\tpublic readonly bool CheckForOverflow;\n\n\t\tpublic ConversionResolveResult(IType targetType, ResolveResult input, Conversion conversion)\n\t\t\t: base(targetType)\n\t\t{\n\t\t\tif (input == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(input));\n\t\t\tif (conversion == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(conversion));\n\t\t\tthis.Input = input;\n\t\t\tthis.Conversion = conversion;\n\t\t}\n\n\t\tpublic ConversionResolveResult(IType targetType, ResolveResult input, Conversion conversion, bool checkForOverflow)\n\t\t\t: this(targetType, input, conversion)\n\t\t{\n\t\t\tthis.CheckForOverflow = checkForOverflow;\n\t\t}\n\n\t\tpublic override bool IsError {\n\t\t\tget { return !Conversion.IsValid; }\n\t\t}\n\n\t\tpublic override IEnumerable<ResolveResult> GetChildResults()\n\t\t{\n\t\t\treturn new[] { Input };\n\t\t}\n\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/ErrorResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Represents a resolve error.\n\t/// \n\t/// Note: some errors are represented by other classes; for example a <see cref=\"ConversionResolveResult\"/> may\n\t/// be erroneous if the conversion is invalid.\n\t/// </summary>\n\t/// <seealso cref=\"ResolveResult.IsError\"/>.\n\tpublic class ErrorResolveResult : ResolveResult\n\t{\n\t\t/// <summary>\n\t\t/// Gets an ErrorResolveResult instance with <c>Type</c> = <c>SpecialType.UnknownType</c>.\n\t\t/// </summary>\n\t\tpublic static readonly ErrorResolveResult UnknownError = new ErrorResolveResult(SpecialType.UnknownType);\n\n\t\tpublic ErrorResolveResult(IType type) : base(type)\n\t\t{\n\t\t}\n\n\t\tpublic ErrorResolveResult(IType type, string message, TextLocation location) : base(type)\n\t\t{\n\t\t\tthis.Message = message;\n\t\t\tthis.Location = location;\n\t\t}\n\n\t\tpublic override bool IsError {\n\t\t\tget { return true; }\n\t\t}\n\n\t\tpublic string Message { get; private set; }\n\n\t\tpublic TextLocation Location { get; private set; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/ForEachResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Resolve result representing a 'foreach' loop.\n\t/// </summary>\n\tpublic class ForEachResolveResult : ResolveResult\n\t{\n\t\t/// <summary>\n\t\t/// Gets the semantic tree for the call to GetEnumerator.\n\t\t/// </summary>\n\t\tpublic readonly ResolveResult GetEnumeratorCall;\n\n\t\t/// <summary>\n\t\t/// Gets the collection type.\n\t\t/// </summary>\n\t\tpublic readonly IType CollectionType;\n\n\t\t/// <summary>\n\t\t/// Gets the enumerator type.\n\t\t/// </summary>\n\t\tpublic readonly IType EnumeratorType;\n\n\t\t/// <summary>\n\t\t/// Gets the element type.\n\t\t/// This is the type that would be inferred for an implicitly-typed element variable.\n\t\t/// For explicitly-typed element variables, this type may differ from <c>ElementVariable.Type</c>.\n\t\t/// </summary>\n\t\tpublic readonly IType ElementType;\n\n\t\t/// <summary>\n\t\t/// Gets the Current property on the IEnumerator.\n\t\t/// Returns null if the property is not found.\n\t\t/// </summary>\n\t\tpublic readonly IProperty CurrentProperty;\n\n\t\t/// <summary>\n\t\t/// Gets the MoveNext() method on the IEnumerator.\n\t\t/// Returns null if the method is not found.\n\t\t/// </summary>\n\t\tpublic readonly IMethod MoveNextMethod;\n\n\t\tpublic ForEachResolveResult(ResolveResult getEnumeratorCall, IType collectionType, IType enumeratorType, IType elementType, IProperty currentProperty, IMethod moveNextMethod, IType voidType)\n\t\t\t: base(voidType)\n\t\t{\n\t\t\tif (getEnumeratorCall == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(getEnumeratorCall));\n\t\t\tif (collectionType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(collectionType));\n\t\t\tif (enumeratorType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(enumeratorType));\n\t\t\tif (elementType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(elementType));\n\t\t\tthis.GetEnumeratorCall = getEnumeratorCall;\n\t\t\tthis.CollectionType = collectionType;\n\t\t\tthis.EnumeratorType = enumeratorType;\n\t\t\tthis.ElementType = elementType;\n\t\t\tthis.CurrentProperty = currentProperty;\n\t\t\tthis.MoveNextMethod = moveNextMethod;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/InitializedObjectResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Refers to the object that is currently being initialized.\n\t/// Used within <see cref=\"InvocationResolveResult.InitializerStatements\"/>.\n\t/// </summary>\n\tpublic class InitializedObjectResolveResult : ResolveResult\n\t{\n\t\tpublic InitializedObjectResolveResult(IType type) : base(type)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/InterpolatedStringResolveResult.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\tpublic class InterpolatedStringResolveResult : ResolveResult\n\t{\n\t\tpublic readonly string FormatString;\n\t\tpublic readonly ResolveResult[] Arguments;\n\n\t\tpublic InterpolatedStringResolveResult(IType stringType, string formatString, params ResolveResult[] arguments)\n\t\t\t: base(stringType)\n\t\t{\n\t\t\tFormatString = formatString;\n\t\t\tArguments = arguments;\n\t\t}\n\n\t\tpublic override IEnumerable<ResolveResult> GetChildResults()\n\t\t{\n\t\t\treturn Arguments;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/InvocationResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Represents the result of a method, constructor or indexer invocation.\n\t/// </summary>\n\tpublic class InvocationResolveResult : MemberResolveResult\n\t{\n\t\t/// <summary>\n\t\t/// Gets the arguments that are being passed to the method, in the order the arguments are being evaluated.\n\t\t/// </summary>\n\t\tpublic readonly IList<ResolveResult> Arguments;\n\n\t\t/// <summary>\n\t\t/// Gets the list of initializer statements that are appplied to the result of this invocation.\n\t\t/// This is used to represent object and collection initializers.\n\t\t/// With the initializer statements, the <see cref=\"InitializedObjectResolveResult\"/> is used\n\t\t/// to refer to the result of this invocation.\n\t\t/// </summary>\n\t\tpublic readonly IList<ResolveResult> InitializerStatements;\n\n\t\tpublic InvocationResolveResult(ResolveResult targetResult, IParameterizedMember member,\n\t\t\t\t\t\t\t\t\t   IList<ResolveResult> arguments = null,\n\t\t\t\t\t\t\t\t\t   IList<ResolveResult> initializerStatements = null,\n\t\t\t\t\t\t\t\t\t   IType returnTypeOverride = null)\n\t\t\t: base(targetResult, member, returnTypeOverride)\n\t\t{\n\t\t\tthis.Arguments = arguments ?? EmptyList<ResolveResult>.Instance;\n\t\t\tthis.InitializerStatements = initializerStatements ?? EmptyList<ResolveResult>.Instance;\n\t\t}\n\n\t\tpublic new IParameterizedMember Member {\n\t\t\tget { return (IParameterizedMember)base.Member; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the arguments in the order they are being passed to the method.\n\t\t/// For parameter arrays (params), this will return an ArrayCreateResolveResult.\n\t\t/// </summary>\n\t\t[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1024:UsePropertiesWhereAppropriate\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t Justification = \"Derived methods may be expensive and create new lists\")]\n\t\tpublic virtual IList<ResolveResult> GetArgumentsForCall()\n\t\t{\n\t\t\treturn Arguments;\n\t\t}\n\n\t\tpublic override IEnumerable<ResolveResult> GetChildResults()\n\t\t{\n\t\t\treturn base.GetChildResults().Concat(this.Arguments).Concat(this.InitializerStatements);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/LocalResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Globalization;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Represents a local variable or parameter.\n\t/// </summary>\n\tpublic class LocalResolveResult : ResolveResult\n\t{\n\t\treadonly IVariable variable;\n\n\t\tpublic LocalResolveResult(IVariable variable)\n\t\t\t: base(UnpackTypeIfByRefParameter(variable))\n\t\t{\n\t\t\tthis.variable = variable;\n\t\t}\n\n\t\tstatic IType UnpackTypeIfByRefParameter(IVariable variable)\n\t\t{\n\t\t\tif (variable == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(variable));\n\t\t\tIType type = variable.Type;\n\t\t\tif (type.Kind == TypeKind.ByReference)\n\t\t\t{\n\t\t\t\tIParameter p = variable as IParameter;\n\t\t\t\tif (p != null && p.ReferenceKind != ReferenceKind.None)\n\t\t\t\t\treturn ((ByReferenceType)type).ElementType;\n\t\t\t}\n\t\t\treturn type;\n\t\t}\n\n\t\tpublic IVariable Variable {\n\t\t\tget { return variable; }\n\t\t}\n\n\t\tpublic bool IsParameter {\n\t\t\tget { return variable is IParameter; }\n\t\t}\n\n\t\tpublic override bool IsCompileTimeConstant {\n\t\t\tget { return variable.IsConst; }\n\t\t}\n\n\t\tpublic override object ConstantValue {\n\t\t\tget { return IsParameter ? null : variable.GetConstantValue(); }\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(CultureInfo.InvariantCulture, \"[LocalResolveResult {0}]\", variable);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/MemberResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Represents the result of a member invocation.\n\t/// Used for field/property/event access.\n\t/// Also, <see cref=\"InvocationResolveResult\"/> derives from MemberResolveResult.\n\t/// </summary>\n\tpublic class MemberResolveResult : ResolveResult\n\t{\n\t\treadonly IMember member;\n\t\treadonly bool isConstant;\n\t\treadonly object constantValue;\n\t\treadonly ResolveResult targetResult;\n\t\treadonly bool isVirtualCall;\n\n\t\tpublic MemberResolveResult(ResolveResult targetResult, IMember member, IType returnTypeOverride = null)\n\t\t\t: base(returnTypeOverride ?? ComputeType(member))\n\t\t{\n\t\t\tthis.targetResult = targetResult;\n\t\t\tthis.member = member;\n\t\t\tvar thisRR = targetResult as ThisResolveResult;\n\t\t\tthis.isVirtualCall = member.IsOverridable && !(thisRR != null && thisRR.CausesNonVirtualInvocation);\n\n\t\t\tIField field = member as IField;\n\t\t\tif (field != null)\n\t\t\t{\n\t\t\t\tisConstant = field.IsConst;\n\t\t\t\tif (isConstant)\n\t\t\t\t\tconstantValue = field.GetConstantValue();\n\t\t\t}\n\t\t}\n\n\t\tpublic MemberResolveResult(ResolveResult targetResult, IMember member, bool isVirtualCall, IType returnTypeOverride = null)\n\t\t\t: base(returnTypeOverride ?? ComputeType(member))\n\t\t{\n\t\t\tthis.targetResult = targetResult;\n\t\t\tthis.member = member;\n\t\t\tthis.isVirtualCall = isVirtualCall;\n\t\t\tIField field = member as IField;\n\t\t\tif (field != null)\n\t\t\t{\n\t\t\t\tisConstant = field.IsConst;\n\t\t\t\tif (isConstant)\n\t\t\t\t\tconstantValue = field.GetConstantValue();\n\t\t\t}\n\t\t}\n\n\t\tstatic IType ComputeType(IMember member)\n\t\t{\n\t\t\tswitch (member.SymbolKind)\n\t\t\t{\n\t\t\t\tcase SymbolKind.Constructor:\n\t\t\t\t\treturn member.DeclaringType ?? SpecialType.UnknownType;\n\t\t\t\tcase SymbolKind.Field:\n\t\t\t\t\t//if (((IField)member).IsFixed)\n\t\t\t\t\t//\treturn new PointerType(member.ReturnType);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (member.ReturnType.Kind == TypeKind.ByReference)\n\t\t\t\treturn ((ByReferenceType)member.ReturnType).ElementType;\n\t\t\treturn member.ReturnType;\n\t\t}\n\n\t\tpublic MemberResolveResult(ResolveResult targetResult, IMember member, IType returnType, bool isConstant, object constantValue)\n\t\t\t: base(returnType)\n\t\t{\n\t\t\tthis.targetResult = targetResult;\n\t\t\tthis.member = member;\n\t\t\tthis.isConstant = isConstant;\n\t\t\tthis.constantValue = constantValue;\n\t\t}\n\n\t\tpublic MemberResolveResult(ResolveResult targetResult, IMember member, IType returnType, bool isConstant, object constantValue, bool isVirtualCall)\n\t\t\t: base(returnType)\n\t\t{\n\t\t\tthis.targetResult = targetResult;\n\t\t\tthis.member = member;\n\t\t\tthis.isConstant = isConstant;\n\t\t\tthis.constantValue = constantValue;\n\t\t\tthis.isVirtualCall = isVirtualCall;\n\t\t}\n\n\t\tpublic ResolveResult TargetResult {\n\t\t\tget { return targetResult; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the member.\n\t\t/// This property never returns null.\n\t\t/// </summary>\n\t\tpublic IMember Member {\n\t\t\tget { return member; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this MemberResolveResult is a virtual call.\n\t\t/// </summary>\n\t\tpublic bool IsVirtualCall {\n\t\t\tget { return isVirtualCall; }\n\t\t}\n\n\t\tpublic override bool IsCompileTimeConstant {\n\t\t\tget { return isConstant; }\n\t\t}\n\n\t\tpublic override object ConstantValue {\n\t\t\tget { return constantValue; }\n\t\t}\n\n\t\tpublic override IEnumerable<ResolveResult> GetChildResults()\n\t\t{\n\t\t\tif (targetResult != null)\n\t\t\t\treturn new[] { targetResult };\n\t\t\telse\n\t\t\t\treturn Enumerable.Empty<ResolveResult>();\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(CultureInfo.InvariantCulture, \"[{0} {1}]\", GetType().Name, member);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/NamedArgumentResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Represents a named argument.\n\t/// </summary>\n\tpublic class NamedArgumentResolveResult : ResolveResult\n\t{\n\t\t/// <summary>\n\t\t/// Gets the member to which the parameter belongs.\n\t\t/// This field can be null.\n\t\t/// </summary>\n\t\tpublic readonly IParameterizedMember Member;\n\n\t\t/// <summary>\n\t\t/// Gets the parameter.\n\t\t/// This field can be null.\n\t\t/// </summary>\n\t\tpublic readonly IParameter Parameter;\n\n\t\t/// <summary>\n\t\t/// Gets the parameter name.\n\t\t/// </summary>\n\t\tpublic readonly string ParameterName;\n\n\t\t/// <summary>\n\t\t/// Gets the argument passed to the parameter.\n\t\t/// </summary>\n\t\tpublic readonly ResolveResult Argument;\n\n\t\tpublic NamedArgumentResolveResult(IParameter parameter, ResolveResult argument, IParameterizedMember member = null)\n\t\t\t: base(argument.Type)\n\t\t{\n\t\t\tif (parameter == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(parameter));\n\t\t\tif (argument == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(argument));\n\t\t\tthis.Member = member;\n\t\t\tthis.Parameter = parameter;\n\t\t\tthis.ParameterName = parameter.Name;\n\t\t\tthis.Argument = argument;\n\t\t}\n\n\t\tpublic NamedArgumentResolveResult(string parameterName, ResolveResult argument)\n\t\t\t: base(argument.Type)\n\t\t{\n\t\t\tif (parameterName == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(parameterName));\n\t\t\tif (argument == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(argument));\n\t\t\tthis.ParameterName = parameterName;\n\t\t\tthis.Argument = argument;\n\t\t}\n\n\t\tpublic override IEnumerable<ResolveResult> GetChildResults()\n\t\t{\n\t\t\treturn new[] { Argument };\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/NamespaceResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Globalization;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Represents that an expression resolved to a namespace.\n\t/// </summary>\n\tpublic class NamespaceResolveResult : ResolveResult\n\t{\n\t\treadonly INamespace ns;\n\n\t\tpublic NamespaceResolveResult(INamespace ns) : base(SpecialType.NoType)\n\t\t{\n\t\t\tthis.ns = ns;\n\t\t}\n\n\t\tpublic INamespace Namespace {\n\t\t\tget { return ns; }\n\t\t}\n\n\t\tpublic string NamespaceName {\n\t\t\tget { return ns.FullName; }\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(CultureInfo.InvariantCulture, \"[{0} {1}]\", GetType().Name, ns);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/OperatorResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq.Expressions;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Represents a unary/binary/ternary operator invocation.\n\t/// </summary>\n\tpublic class OperatorResolveResult : ResolveResult\n\t{\n\t\treadonly ExpressionType operatorType;\n\t\treadonly IMethod userDefinedOperatorMethod;\n\t\treadonly IList<ResolveResult> operands;\n\t\treadonly bool isLiftedOperator;\n\n\t\tpublic OperatorResolveResult(IType resultType, ExpressionType operatorType, params ResolveResult[] operands)\n\t\t\t: base(resultType)\n\t\t{\n\t\t\tif (operands == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(operands));\n\t\t\tthis.operatorType = operatorType;\n\t\t\tthis.operands = operands;\n\t\t}\n\n\t\tpublic OperatorResolveResult(IType resultType, ExpressionType operatorType, IMethod userDefinedOperatorMethod, bool isLiftedOperator, IList<ResolveResult> operands)\n\t\t\t: base(resultType)\n\t\t{\n\t\t\tif (operands == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(operands));\n\t\t\tthis.operatorType = operatorType;\n\t\t\tthis.userDefinedOperatorMethod = userDefinedOperatorMethod;\n\t\t\tthis.isLiftedOperator = isLiftedOperator;\n\t\t\tthis.operands = operands;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the operator type.\n\t\t/// </summary>\n\t\tpublic ExpressionType OperatorType {\n\t\t\tget { return operatorType; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the operands.\n\t\t/// </summary>\n\t\tpublic IList<ResolveResult> Operands {\n\t\t\tget { return operands; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the user defined operator method.\n\t\t/// Returns null if this is a predefined operator.\n\t\t/// </summary>\n\t\tpublic IMethod UserDefinedOperatorMethod {\n\t\t\tget { return userDefinedOperatorMethod; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this is a lifted operator.\n\t\t/// </summary>\n\t\tpublic bool IsLiftedOperator {\n\t\t\tget { return isLiftedOperator; }\n\t\t}\n\n\t\tpublic override IEnumerable<ResolveResult> GetChildResults()\n\t\t{\n\t\t\treturn operands;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/OutVarResolveResult.cs",
    "content": "// Copyright (c) 2020 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Represents the implicitly-typed \"out var\".\n\t/// Special-cased in overload resolution to be compatible with any out-parameter.\n\t/// </summary>\n\tclass OutVarResolveResult : ResolveResult\n\t{\n\t\t/// <summary>\n\t\t/// Type of the variable originally used in IL. It will be used, if \"out var\" cannot be used.\n\t\t/// </summary>\n\t\tpublic readonly IType OriginalVariableType;\n\n\t\tpublic OutVarResolveResult(IType originalVariableType) : base(SpecialType.NoType) { OriginalVariableType = originalVariableType; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/ResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Represents the result of resolving an expression.\n\t/// </summary>\n\tpublic class ResolveResult\n\t{\n\t\treadonly IType type;\n\n\t\tpublic ResolveResult(IType type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tthis.type = type;\n\t\t}\n\n\t\t[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1721:PropertyNamesShouldNotMatchGetMethods\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t Justification = \"Unrelated to object.GetType()\")]\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t}\n\n\t\tpublic virtual bool IsCompileTimeConstant {\n\t\t\tget { return false; }\n\t\t}\n\n\t\tpublic virtual object ConstantValue {\n\t\t\tget { return null; }\n\t\t}\n\n\t\tpublic virtual bool IsError {\n\t\t\tget { return false; }\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn \"[\" + GetType().Name + \" \" + type + \"]\";\n\t\t}\n\n\t\tpublic virtual IEnumerable<ResolveResult> GetChildResults()\n\t\t{\n\t\t\treturn Enumerable.Empty<ResolveResult>();\n\t\t}\n\n\t\tpublic virtual ResolveResult ShallowClone()\n\t\t{\n\t\t\treturn (ResolveResult)MemberwiseClone();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/SizeOfResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Represents the 'sizeof'.\n\t/// </summary>\n\tpublic class SizeOfResolveResult : ResolveResult\n\t{\n\t\treadonly IType referencedType;\n\t\treadonly int? constantValue;\n\n\t\tpublic SizeOfResolveResult(IType int32, IType referencedType, int? constantValue)\n\t\t\t: base(int32)\n\t\t{\n\t\t\tif (referencedType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(referencedType));\n\t\t\tthis.referencedType = referencedType;\n\t\t\tthis.constantValue = constantValue;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// The type referenced by the 'sizeof'.\n\t\t/// </summary>\n\t\tpublic IType ReferencedType {\n\t\t\tget { return referencedType; }\n\t\t}\n\n\t\tpublic override bool IsCompileTimeConstant {\n\t\t\tget {\n\t\t\t\treturn constantValue != null;\n\t\t\t}\n\t\t}\n\n\t\tpublic override object ConstantValue {\n\t\t\tget {\n\t\t\t\treturn constantValue;\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool IsError {\n\t\t\tget {\n\t\t\t\treturn referencedType.IsReferenceType != false;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/ThisResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Represents the 'this' reference.\n\t/// Also used for the 'base' reference.\n\t/// </summary>\n\tpublic class ThisResolveResult : ResolveResult\n\t{\n\t\tbool causesNonVirtualInvocation;\n\n\t\tpublic ThisResolveResult(IType type, bool causesNonVirtualInvocation = false) : base(type)\n\t\t{\n\t\t\tthis.causesNonVirtualInvocation = causesNonVirtualInvocation;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this resolve result causes member invocations to be non-virtual.\n\t\t/// </summary>\n\t\tpublic bool CausesNonVirtualInvocation {\n\t\t\tget { return causesNonVirtualInvocation; }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/ThrowResolveResult.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\tclass ThrowResolveResult : ResolveResult\n\t{\n\t\tpublic ThrowResolveResult() : base(SpecialType.NoType)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/TupleResolveResult.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Resolve result for a C# 7 tuple literal.\n\t/// </summary>\n\tpublic class TupleResolveResult : ResolveResult\n\t{\n\t\tpublic ImmutableArray<ResolveResult> Elements { get; }\n\n\t\tpublic TupleResolveResult(ICompilation compilation,\n\t\t\tImmutableArray<ResolveResult> elements,\n\t\t\tImmutableArray<string> elementNames = default(ImmutableArray<string>),\n\t\t\tIModule valueTupleAssembly = null)\n\t\t: base(GetTupleType(compilation, elements, elementNames, valueTupleAssembly))\n\t\t{\n\t\t\tthis.Elements = elements;\n\t\t}\n\n\t\tpublic override IEnumerable<ResolveResult> GetChildResults()\n\t\t{\n\t\t\treturn Elements;\n\t\t}\n\n\t\tstatic IType GetTupleType(ICompilation compilation, ImmutableArray<ResolveResult> elements, ImmutableArray<string> elementNames, IModule valueTupleAssembly)\n\t\t{\n\t\t\tif (elements.Any(e => e.Type.Kind == TypeKind.None || e.Type.Kind == TypeKind.Null))\n\t\t\t\treturn SpecialType.NoType;\n\t\t\telse\n\t\t\t\treturn new TupleType(compilation, elements.Select(e => e.Type).ToImmutableArray(), elementNames, valueTupleAssembly);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/TypeIsResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Resolve result for a C# 'is' expression.\n\t/// \"Input is TargetType\".\n\t/// </summary>\n\tpublic class TypeIsResolveResult : ResolveResult\n\t{\n\t\tpublic readonly ResolveResult Input;\n\t\t/// <summary>\n\t\t/// Type that is being compared with.\n\t\t/// </summary>\n\t\tpublic readonly IType TargetType;\n\n\t\tpublic TypeIsResolveResult(ResolveResult input, IType targetType, IType booleanType)\n\t\t\t: base(booleanType)\n\t\t{\n\t\t\tif (input == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(input));\n\t\t\tif (targetType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(targetType));\n\t\t\tthis.Input = input;\n\t\t\tthis.TargetType = targetType;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/TypeOfResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Represents the 'typeof'.\n\t/// </summary>\n\tpublic class TypeOfResolveResult : ResolveResult\n\t{\n\t\treadonly IType referencedType;\n\n\t\tpublic TypeOfResolveResult(IType systemType, IType referencedType)\n\t\t\t: base(systemType)\n\t\t{\n\t\t\tif (referencedType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(referencedType));\n\t\t\tthis.referencedType = referencedType;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// The type referenced by the 'typeof'.\n\t\t/// </summary>\n\t\tpublic IType ReferencedType {\n\t\t\tget { return referencedType; }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/TypeResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// The resolved expression refers to a type name.\n\t/// </summary>\n\tpublic class TypeResolveResult : ResolveResult\n\t{\n\t\tpublic TypeResolveResult(IType type)\n\t\t\t: base(type)\n\t\t{\n\t\t}\n\n\t\tpublic override bool IsError {\n\t\t\tget { return this.Type.Kind == TypeKind.Unknown; }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Semantics/UnknownMemberResolveResult.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Globalization;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Semantics\n{\n\t/// <summary>\n\t/// Represents an unknown member.\n\t/// </summary>\n\tpublic class UnknownMemberResolveResult : ResolveResult\n\t{\n\t\treadonly IType targetType;\n\t\treadonly string memberName;\n\t\treadonly ReadOnlyCollection<IType> typeArguments;\n\n\t\tpublic UnknownMemberResolveResult(IType targetType, string memberName, IEnumerable<IType> typeArguments)\n\t\t\t: base(SpecialType.UnknownType)\n\t\t{\n\t\t\tif (targetType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(targetType));\n\t\t\tthis.targetType = targetType;\n\t\t\tthis.memberName = memberName;\n\t\t\tthis.typeArguments = new ReadOnlyCollection<IType>(typeArguments.ToArray());\n\t\t}\n\n\t\t/// <summary>\n\t\t/// The type on which the method is being called.\n\t\t/// </summary>\n\t\tpublic IType TargetType {\n\t\t\tget { return targetType; }\n\t\t}\n\n\t\tpublic string MemberName {\n\t\t\tget { return memberName; }\n\t\t}\n\n\t\tpublic ReadOnlyCollection<IType> TypeArguments {\n\t\t\tget { return typeArguments; }\n\t\t}\n\n\t\tpublic override bool IsError {\n\t\t\tget { return true; }\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(CultureInfo.InvariantCulture, \"[{0} {1}.{2}]\", GetType().Name, targetType, memberName);\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Represents an unknown method.\n\t/// </summary>\n\tpublic class UnknownMethodResolveResult : UnknownMemberResolveResult\n\t{\n\t\treadonly ReadOnlyCollection<IParameter> parameters;\n\n\t\tpublic UnknownMethodResolveResult(IType targetType, string methodName, IEnumerable<IType> typeArguments, IEnumerable<IParameter> parameters)\n\t\t\t: base(targetType, methodName, typeArguments)\n\t\t{\n\t\t\tthis.parameters = new ReadOnlyCollection<IParameter>(parameters.ToArray());\n\t\t}\n\n\t\tpublic ReadOnlyCollection<IParameter> Parameters {\n\t\t\tget { return parameters; }\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Represents an unknown identifier.\n\t/// </summary>\n\tpublic class UnknownIdentifierResolveResult : ResolveResult\n\t{\n\t\treadonly string identifier;\n\t\treadonly int typeArgumentCount;\n\n\t\tpublic UnknownIdentifierResolveResult(string identifier, int typeArgumentCount = 0)\n\t\t\t: base(SpecialType.UnknownType)\n\t\t{\n\t\t\tthis.identifier = identifier;\n\t\t\tthis.typeArgumentCount = typeArgumentCount;\n\t\t}\n\n\t\tpublic string Identifier {\n\t\t\tget { return identifier; }\n\t\t}\n\n\t\tpublic int TypeArgumentCount {\n\t\t\tget { return typeArgumentCount; }\n\t\t}\n\n\t\tpublic override bool IsError {\n\t\t\tget { return true; }\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(CultureInfo.InvariantCulture, \"[{0} {1}]\", GetType().Name, identifier);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/SingleFileBundle.cs",
    "content": "// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n\nusing System;\nusing System.Collections.Immutable;\nusing System.IO;\nusing System.IO.MemoryMappedFiles;\nusing System.Runtime.CompilerServices;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler\n{\n\t/// <summary>\n\t/// Class for dealing with .NET 5 single-file bundles.\n\t/// \n\t/// Based on code from Microsoft.NET.HostModel.\n\t/// </summary>\n\tpublic static class SingleFileBundle\n\t{\n\t\t/// <summary>\n\t\t/// Check if the memory-mapped data is a single-file bundle\n\t\t/// </summary>\n\t\tpublic static unsafe bool IsBundle(MemoryMappedViewAccessor view, out long bundleHeaderOffset)\n\t\t{\n\t\t\tvar buffer = view.SafeMemoryMappedViewHandle;\n\t\t\tbyte* ptr = null;\n\t\t\tbuffer.AcquirePointer(ref ptr);\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn IsBundle(ptr, checked((long)buffer.ByteLength), out bundleHeaderOffset);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tbuffer.ReleasePointer();\n\t\t\t}\n\t\t}\n\n\t\tpublic static unsafe bool IsBundle(byte* data, long size, out long bundleHeaderOffset)\n\t\t{\n\t\t\tReadOnlySpan<byte> bundleSignature = new byte[] {\n\t\t\t\t// 32 bytes represent the bundle signature: SHA-256 for \".net core bundle\"\n\t\t\t\t0x8b, 0x12, 0x02, 0xb9, 0x6a, 0x61, 0x20, 0x38,\n\t\t\t\t0x72, 0x7b, 0x93, 0x02, 0x14, 0xd7, 0xa0, 0x32,\n\t\t\t\t0x13, 0xf5, 0xb9, 0xe6, 0xef, 0xae, 0x33, 0x18,\n\t\t\t\t0xee, 0x3b, 0x2d, 0xce, 0x24, 0xb3, 0x6a, 0xae\n\t\t\t};\n\n\t\t\tbyte* end = data + (size - bundleSignature.Length);\n\t\t\tfor (byte* ptr = data; ptr < end; ptr++)\n\t\t\t{\n\t\t\t\tif (*ptr == 0x8b && bundleSignature.SequenceEqual(new ReadOnlySpan<byte>(ptr, bundleSignature.Length)))\n\t\t\t\t{\n\t\t\t\t\tbundleHeaderOffset = Unsafe.ReadUnaligned<long>(ptr - sizeof(long));\n\t\t\t\t\tif (bundleHeaderOffset > 0 && bundleHeaderOffset < size)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbundleHeaderOffset = 0;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic struct Header\n\t\t{\n\t\t\tpublic uint MajorVersion;\n\t\t\tpublic uint MinorVersion;\n\t\t\tpublic int FileCount;\n\t\t\tpublic string BundleID;\n\n\t\t\t// Fields introduced with v2:\n\t\t\tpublic long DepsJsonOffset;\n\t\t\tpublic long DepsJsonSize;\n\t\t\tpublic long RuntimeConfigJsonOffset;\n\t\t\tpublic long RuntimeConfigJsonSize;\n\t\t\tpublic ulong Flags;\n\n\t\t\tpublic ImmutableArray<Entry> Entries;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// FileType: Identifies the type of file embedded into the bundle.\n\t\t///\n\t\t/// The bundler differentiates a few kinds of files via the manifest,\n\t\t/// with respect to the way in which they'll be used by the runtime.\n\t\t/// </summary>\n\t\tpublic enum FileType : byte\n\t\t{\n\t\t\tUnknown,           // Type not determined.\n\t\t\tAssembly,          // IL and R2R Assemblies\n\t\t\tNativeBinary,      // NativeBinaries\n\t\t\tDepsJson,          // .deps.json configuration file\n\t\t\tRuntimeConfigJson, // .runtimeconfig.json configuration file\n\t\t\tSymbols            // PDB Files\n\t\t};\n\n\t\tpublic struct Entry\n\t\t{\n\t\t\tpublic long Offset;\n\t\t\tpublic long Size;\n\t\t\tpublic long CompressedSize; // 0 if not compressed, otherwise the compressed size in the bundle\n\t\t\tpublic FileType Type;\n\t\t\tpublic string RelativePath; // Path of an embedded file, relative to the Bundle source-directory.\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Reads the manifest header from the memory mapping.\n\t\t/// </summary>\n\t\tpublic static Header ReadManifest(MemoryMappedViewAccessor view, long bundleHeaderOffset)\n\t\t{\n\t\t\tusing var stream = view.AsStream();\n\t\t\tstream.Seek(bundleHeaderOffset, SeekOrigin.Begin);\n\t\t\treturn ReadManifest(stream);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Reads the manifest header from the stream.\n\t\t/// </summary>\n\t\tpublic static Header ReadManifest(Stream stream)\n\t\t{\n\t\t\tvar header = new Header();\n\t\t\tusing var reader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true);\n\t\t\theader.MajorVersion = reader.ReadUInt32();\n\t\t\theader.MinorVersion = reader.ReadUInt32();\n\n\t\t\t// Major versions 3, 4 and 5 were skipped to align bundle versioning with .NET versioning scheme\n\t\t\tif (header.MajorVersion < 1 || header.MajorVersion > 6)\n\t\t\t{\n\t\t\t\tthrow new InvalidDataException($\"Unsupported manifest version: {header.MajorVersion}.{header.MinorVersion}\");\n\t\t\t}\n\t\t\theader.FileCount = reader.ReadInt32();\n\t\t\theader.BundleID = reader.ReadString();\n\t\t\tif (header.MajorVersion >= 2)\n\t\t\t{\n\t\t\t\theader.DepsJsonOffset = reader.ReadInt64();\n\t\t\t\theader.DepsJsonSize = reader.ReadInt64();\n\t\t\t\theader.RuntimeConfigJsonOffset = reader.ReadInt64();\n\t\t\t\theader.RuntimeConfigJsonSize = reader.ReadInt64();\n\t\t\t\theader.Flags = reader.ReadUInt64();\n\t\t\t}\n\t\t\tvar entries = ImmutableArray.CreateBuilder<Entry>(header.FileCount);\n\t\t\tfor (int i = 0; i < header.FileCount; i++)\n\t\t\t{\n\t\t\t\tentries.Add(ReadEntry(reader, header.MajorVersion));\n\t\t\t}\n\t\t\theader.Entries = entries.MoveToImmutable();\n\t\t\treturn header;\n\t\t}\n\n\t\tprivate static Entry ReadEntry(BinaryReader reader, uint bundleMajorVersion)\n\t\t{\n\t\t\tEntry entry;\n\t\t\tentry.Offset = reader.ReadInt64();\n\t\t\tentry.Size = reader.ReadInt64();\n\t\t\tentry.CompressedSize = bundleMajorVersion >= 6 ? reader.ReadInt64() : 0;\n\t\t\tentry.Type = (FileType)reader.ReadByte();\n\t\t\tentry.RelativePath = reader.ReadString();\n\t\t\treturn entry;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Solution/ProjectId.cs",
    "content": "// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Solution\n{\n\t/// <summary>\n\t/// A container class that holds platform and GUID information about a Visual Studio project.\n\t/// </summary>\n\tpublic class ProjectId\n\t{\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"ProjectId\"/> class.\n\t\t/// </summary>\n\t\t/// <param name=\"projectPlatform\">The project platform.</param>\n\t\t/// <param name=\"projectGuid\">The project GUID.</param>\n\t\t/// \n\t\t/// <exception cref=\"ArgumentException\">Thrown when <paramref name=\"projectPlatform\"/> is null or empty.</exception>\n\t\tpublic ProjectId(string projectPlatform, Guid projectGuid, Guid typeGuid)\n\t\t{\n\t\t\tif (string.IsNullOrWhiteSpace(projectPlatform))\n\t\t\t{\n\t\t\t\tthrow new ArgumentException(\"The platform cannot be null or empty.\", nameof(projectPlatform));\n\t\t\t}\n\n\t\t\tGuid = projectGuid;\n\t\t\tTypeGuid = typeGuid;\n\t\t\tPlatformName = projectPlatform;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the GUID of this project.\n\t\t/// This is usually a newly generated GUID for each decompiled project.\n\t\t/// </summary>\n\t\tpublic Guid Guid { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the primary type GUID of this project.\n\t\t/// This is one of the GUIDs from <see cref=\"ProjectTypeGuids\"/>.\n\t\t/// </summary>\n\t\tpublic Guid TypeGuid { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the platform name of this project. Only single platform per project is supported.\n\t\t/// </summary>\n\t\tpublic string PlatformName { get; }\n\t}\n\n\tpublic static class ProjectTypeGuids\n\t{\n\t\tpublic static readonly Guid SolutionFolder = Guid.Parse(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\");\n\n\t\tpublic static readonly Guid CSharpWindows = Guid.Parse(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\");\n\t\tpublic static readonly Guid CSharpCore = Guid.Parse(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\");\n\n\t\tpublic static readonly Guid Silverlight = Guid.Parse(\"{A1591282-1198-4647-A2B1-27E5FF5F6F3B}\");\n\t\tpublic static readonly Guid PortableLibrary = Guid.Parse(\"{786C830F-07A1-408B-BD7F-6EE04809D6DB}\");\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Solution/ProjectItem.cs",
    "content": "// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\n\nnamespace ICSharpCode.Decompiler.Solution\n{\n\t/// <summary>\n\t/// A container class that holds information about a Visual Studio project.\n\t/// </summary>\n\tpublic sealed class ProjectItem : ProjectId\n\t{\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"ProjectItem\"/> class.\n\t\t/// </summary>\n\t\t/// <param name=\"projectFile\">The full path of the project file.</param>\n\t\t/// <param name=\"projectPlatform\">The project platform.</param>\n\t\t/// <param name=\"projectGuid\">The project GUID.</param>\n\t\t/// \n\t\t/// <exception cref=\"ArgumentException\">Thrown when <paramref name=\"projectFile\"/> \n\t\t/// or <paramref name=\"projectPlatform\"/> is null or empty.</exception>\n\t\tpublic ProjectItem(string projectFile, string projectPlatform, Guid projectGuid, Guid typeGuid)\n\t\t\t: base(projectPlatform, projectGuid, typeGuid)\n\t\t{\n\t\t\tProjectName = Path.GetFileNameWithoutExtension(projectFile);\n\t\t\tFilePath = projectFile;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the name of the project.\n\t\t/// </summary>\n\t\tpublic string ProjectName { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the full path to the project file.\n\t\t/// </summary>\n\t\tpublic string FilePath { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Solution/SolutionCreator.cs",
    "content": "// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Xml.Linq;\n\nnamespace ICSharpCode.Decompiler.Solution\n{\n\t/// <summary>\n\t/// A helper class that can write a Visual Studio Solution file for the provided projects.\n\t/// </summary>\n\tpublic static class SolutionCreator\n\t{\n\t\tstatic readonly XNamespace NonSDKProjectFileNamespace = XNamespace.Get(\"http://schemas.microsoft.com/developer/msbuild/2003\");\n\n\t\t/// <summary>\n\t\t/// Writes a solution file to the specified <paramref name=\"targetFile\"/>.\n\t\t/// Also fixes intra-solution project references in the project files.\n\t\t/// </summary>\n\t\t/// <param name=\"targetFile\">The full path of the file to write.</param>\n\t\t/// <param name=\"projects\">The projects contained in this solution.</param>\n\t\t/// \n\t\t/// <exception cref=\"ArgumentException\">Thrown when <paramref name=\"targetFile\"/> is null or empty.</exception>\n\t\t/// <exception cref=\"ArgumentNullException\">Thrown when <paramref name=\"projects\"/> is null.</exception>\n\t\t/// <exception cref=\"InvalidOperationException\">Thrown when <paramref name=\"projects\"/> contains no items.</exception>\n\t\tpublic static void WriteSolutionFile(string targetFile, List<ProjectItem> projects)\n\t\t{\n\t\t\tif (string.IsNullOrWhiteSpace(targetFile))\n\t\t\t{\n\t\t\t\tthrow new ArgumentException(\"The target file cannot be null or empty.\", nameof(targetFile));\n\t\t\t}\n\n\t\t\tif (projects == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(projects));\n\t\t\t}\n\n\t\t\tif (!projects.Any())\n\t\t\t{\n\t\t\t\tthrow new InvalidOperationException(\"At least one project is expected.\");\n\t\t\t}\n\n\t\t\tusing (var writer = new StreamWriter(targetFile))\n\t\t\t{\n\t\t\t\tWriteSolutionFile(writer, projects, targetFile);\n\t\t\t}\n\n\t\t\tFixAllProjectReferences(projects);\n\t\t}\n\n\t\tstatic void WriteSolutionFile(TextWriter writer, List<ProjectItem> projects, string solutionFilePath)\n\t\t{\n\t\t\tWriteHeader(writer);\n\t\t\tWriteProjects(writer, projects, solutionFilePath);\n\n\t\t\twriter.WriteLine(\"Global\");\n\n\t\t\tvar platforms = WriteSolutionConfigurations(writer, projects);\n\t\t\tWriteProjectConfigurations(writer, projects, platforms);\n\n\t\t\twriter.WriteLine(\"\\tGlobalSection(SolutionProperties) = preSolution\");\n\t\t\twriter.WriteLine(\"\\t\\tHideSolutionNode = FALSE\");\n\t\t\twriter.WriteLine(\"\\tEndGlobalSection\");\n\n\t\t\twriter.WriteLine(\"EndGlobal\");\n\t\t}\n\n\t\tprivate static void WriteHeader(TextWriter writer)\n\t\t{\n\t\t\twriter.WriteLine(\"Microsoft Visual Studio Solution File, Format Version 12.00\");\n\t\t\twriter.WriteLine(\"# Visual Studio 14\");\n\t\t\twriter.WriteLine(\"VisualStudioVersion = 14.0.24720.0\");\n\t\t\twriter.WriteLine(\"MinimumVisualStudioVersion = 10.0.40219.1\");\n\t\t}\n\n\t\tstatic void WriteProjects(TextWriter writer, List<ProjectItem> projects, string solutionFilePath)\n\t\t{\n\t\t\tforeach (var project in projects)\n\t\t\t{\n\t\t\t\tvar projectRelativePath = GetRelativePath(solutionFilePath, project.FilePath);\n\t\t\t\tvar typeGuid = project.TypeGuid.ToString(\"B\").ToUpperInvariant();\n\t\t\t\tvar projectGuid = project.Guid.ToString(\"B\").ToUpperInvariant();\n\n\t\t\t\twriter.WriteLine($\"Project(\\\"{typeGuid}\\\") = \\\"{project.ProjectName}\\\", \\\"{projectRelativePath}\\\", \\\"{projectGuid}\\\"\");\n\t\t\t\twriter.WriteLine(\"EndProject\");\n\t\t\t}\n\t\t}\n\n\t\tstatic List<string> WriteSolutionConfigurations(TextWriter writer, List<ProjectItem> projects)\n\t\t{\n\t\t\tvar platforms = projects.GroupBy(p => p.PlatformName).Select(g => g.Key).ToList();\n\n\t\t\tplatforms.Sort();\n\n\t\t\twriter.WriteLine(\"\\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\");\n\t\t\tforeach (var platform in platforms)\n\t\t\t{\n\t\t\t\twriter.WriteLine($\"\\t\\tDebug|{platform} = Debug|{platform}\");\n\t\t\t}\n\n\t\t\tforeach (var platform in platforms)\n\t\t\t{\n\t\t\t\twriter.WriteLine($\"\\t\\tRelease|{platform} = Release|{platform}\");\n\t\t\t}\n\n\t\t\twriter.WriteLine(\"\\tEndGlobalSection\");\n\n\t\t\treturn platforms;\n\t\t}\n\n\t\tstatic void WriteProjectConfigurations(\n\t\t\tTextWriter writer,\n\t\t\tList<ProjectItem> projects,\n\t\t\tList<string> solutionPlatforms)\n\t\t{\n\t\t\twriter.WriteLine(\"\\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\");\n\n\t\t\tforeach (var project in projects)\n\t\t\t{\n\t\t\t\tvar projectGuid = project.Guid.ToString(\"B\").ToUpperInvariant();\n\n\t\t\t\tforeach (var platform in solutionPlatforms)\n\t\t\t\t{\n\t\t\t\t\twriter.WriteLine($\"\\t\\t{projectGuid}.Debug|{platform}.ActiveCfg = Debug|{project.PlatformName}\");\n\t\t\t\t\twriter.WriteLine($\"\\t\\t{projectGuid}.Debug|{platform}.Build.0 = Debug|{project.PlatformName}\");\n\t\t\t\t}\n\n\t\t\t\tforeach (var platform in solutionPlatforms)\n\t\t\t\t{\n\t\t\t\t\twriter.WriteLine($\"\\t\\t{projectGuid}.Release|{platform}.ActiveCfg = Release|{project.PlatformName}\");\n\t\t\t\t\twriter.WriteLine($\"\\t\\t{projectGuid}.Release|{platform}.Build.0 = Release|{project.PlatformName}\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\twriter.WriteLine(\"\\tEndGlobalSection\");\n\t\t}\n\n\t\tstatic void FixAllProjectReferences(List<ProjectItem> projects)\n\t\t{\n\t\t\tvar projectsMap = projects.ToDictionary(\n\t\t\t\tp => p.ProjectName,\n\t\t\t\tp => p);\n\n\t\t\tforeach (var project in projects)\n\t\t\t{\n\t\t\t\tXDocument projectDoc = XDocument.Load(project.FilePath);\n\n\t\t\t\tif (projectDoc.Root?.Name.LocalName != \"Project\")\n\t\t\t\t{\n\t\t\t\t\tthrow new InvalidOperationException(\n\t\t\t\t\t\t$\"The file {project.FilePath} is not a valid project file, \" +\n\t\t\t\t\t\t$\"no <Project> at the root; could not fix project references.\");\n\t\t\t\t}\n\n\t\t\t\t// sdk style projects don't use a namespace for the elements,\n\t\t\t\t// but we still need to use the namespace for non-sdk style projects.\n\t\t\t\tvar sdkStyle = projectDoc.Root.Attribute(\"Sdk\") != null;\n\t\t\t\tvar itemGroupTagName = sdkStyle ? \"ItemGroup\" : NonSDKProjectFileNamespace + \"ItemGroup\";\n\t\t\t\tvar referenceTagName = sdkStyle ? \"Reference\" : NonSDKProjectFileNamespace + \"Reference\";\n\n\t\t\t\tvar referencesItemGroups = projectDoc.Root\n\t\t\t\t\t.Elements(itemGroupTagName)\n\t\t\t\t\t.Where(e => e.Elements(referenceTagName).Any())\n\t\t\t\t\t.ToList();\n\n\t\t\t\tforeach (var itemGroup in referencesItemGroups)\n\t\t\t\t{\n\t\t\t\t\tFixProjectReferences(project.FilePath, itemGroup, projectsMap, sdkStyle);\n\t\t\t\t}\n\n\t\t\t\tprojectDoc.Save(project.FilePath);\n\t\t\t}\n\t\t}\n\n\t\tstatic void FixProjectReferences(string projectFilePath, XElement itemGroup,\n\t\t\tDictionary<string, ProjectItem> projects, bool sdkStyle)\n\t\t{\n\n\t\t\tXName GetElementName(string name) => sdkStyle ? name : NonSDKProjectFileNamespace + name;\n\n\t\t\tvar referenceTagName = GetElementName(\"Reference\");\n\t\t\tvar projectReferenceTagName = GetElementName(\"ProjectReference\");\n\n\t\t\tforeach (var item in itemGroup.Elements(referenceTagName).ToList())\n\t\t\t{\n\t\t\t\tvar assemblyName = item.Attribute(\"Include\")?.Value;\n\t\t\t\tif (assemblyName != null && projects.TryGetValue(assemblyName, out var referencedProject))\n\t\t\t\t{\n\t\t\t\t\titem.Remove();\n\n\t\t\t\t\tvar projectReference = new XElement(\n\t\t\t\t\t\tprojectReferenceTagName,\n\t\t\t\t\t\tnew XAttribute(\"Include\", GetRelativePath(projectFilePath, referencedProject.FilePath)));\n\n\t\t\t\t\t// SDK-style projects do not use the <Project> and <Name> elements for project references.\n\t\t\t\t\t// (Instead, those get read from the .csproj file in \"Include\".)\n\t\t\t\t\tif (!sdkStyle)\n\t\t\t\t\t{\n\t\t\t\t\t\tprojectReference.Add(\n\t\t\t\t\t\t\t// no ToUpper() for uuids, most Microsoft tools seem to emit them in lowercase\n\t\t\t\t\t\t\t// (no .ToLower() as .ToString(\"B\") already outputs lowercase)\n\t\t\t\t\t\t\tnew XElement(NonSDKProjectFileNamespace + \"Project\", referencedProject.Guid.ToString(\"B\")),\n\t\t\t\t\t\t\tnew XElement(NonSDKProjectFileNamespace + \"Name\", referencedProject.ProjectName));\n\t\t\t\t\t}\n\n\t\t\t\t\titemGroup.Add(projectReference);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic string GetRelativePath(string fromFilePath, string toFilePath)\n\t\t{\n\t\t\tUri fromUri = new Uri(fromFilePath);\n\t\t\tUri toUri = new Uri(toFilePath);\n\n\t\t\tif (fromUri.Scheme != toUri.Scheme)\n\t\t\t{\n\t\t\t\treturn toFilePath;\n\t\t\t}\n\n\t\t\tUri relativeUri = fromUri.MakeRelativeUri(toUri);\n\t\t\tstring relativePath = Uri.UnescapeDataString(relativeUri.ToString());\n\n\t\t\tif (string.Equals(toUri.Scheme, Uri.UriSchemeFile, StringComparison.OrdinalIgnoreCase))\n\t\t\t{\n\t\t\t\trelativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);\n\t\t\t}\n\n\t\t\treturn relativePath;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Accessibility.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Enum that describes the accessibility of an entity.\n\t/// </summary>\n\tpublic enum Accessibility : byte\n\t{\n\t\t// Note: some code depends on the fact that these values are within the range 0-7\n\n\t\t/// <summary>\n\t\t/// The entity is completely inaccessible. This is used for C# explicit interface implementations.\n\t\t/// </summary>\n\t\tNone,\n\t\t/// <summary>\n\t\t/// The entity is only accessible within the same class.\n\t\t/// </summary>\n\t\tPrivate,\n\t\t/// <summary>\n\t\t/// The entity is accessible in derived classes within the same assembly.\n\t\t/// This corresponds to C# <c>private protected</c>.\n\t\t/// </summary>\n\t\tProtectedAndInternal,\n\t\t/// <summary>\n\t\t/// The entity is only accessible within the same class and in derived classes.\n\t\t/// </summary>\n\t\tProtected,\n\t\t/// <summary>\n\t\t/// The entity is accessible within the same assembly.\n\t\t/// </summary>\n\t\tInternal,\n\t\t/// <summary>\n\t\t/// The entity is accessible both everywhere in the assembly, and in all derived classes.\n\t\t/// This corresponds to C# <c>protected internal</c>.\n\t\t/// </summary>\n\t\tProtectedOrInternal,\n\t\t/// <summary>\n\t\t/// The entity is accessible everywhere.\n\t\t/// </summary>\n\t\tPublic,\n\t}\n\n\tpublic static class AccessibilityExtensions\n\t{\n\t\t// This code depends on the fact that the enum values are sorted similar to the partial order\n\t\t// where an accessibility is smaller than another if it makes an entity visibible to a subset of the code:\n\t\t// digraph Accessibilities {\n\t\t//   none -> private -> protected_and_internal -> protected -> protected_or_internal -> public;\n\t\t//   none -> private -> protected_and_internal -> internal  -> protected_or_internal -> public;\n\t\t// }\n\n\t\t/// <summary>\n\t\t/// Gets whether a &lt;= b in the partial order of accessibilities:\n\t\t/// return true if b is accessible everywhere where a is accessible.\n\t\t/// </summary>\n\t\tpublic static bool LessThanOrEqual(this Accessibility a, Accessibility b)\n\t\t{\n\t\t\t// Exploit the enum order being similar to the partial order to dramatically simplify the logic here:\n\t\t\t// protected vs. internal is the only pair for which the enum value order doesn't match the partial order\n\t\t\treturn a <= b && !(a == Accessibility.Protected && b == Accessibility.Internal);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Computes the intersection of the two accessibilities:\n\t\t/// The result is accessible from any given point in the code\n\t\t/// iff both a and b are accessible from that point.\n\t\t/// </summary>\n\t\tpublic static Accessibility Intersect(this Accessibility a, Accessibility b)\n\t\t{\n\t\t\tif (a > b)\n\t\t\t{\n\t\t\t\tExtensionMethods.Swap(ref a, ref b);\n\t\t\t}\n\t\t\tif (a == Accessibility.Protected && b == Accessibility.Internal)\n\t\t\t{\n\t\t\t\treturn Accessibility.ProtectedAndInternal;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDebug.Assert(!(a == Accessibility.Internal && b == Accessibility.Protected));\n\t\t\t\treturn a;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Computes the union of the two accessibilities:\n\t\t/// The result is accessible from any given point in the code\n\t\t/// iff at least one of a or b is accessible from that point.\n\t\t/// </summary>\n\t\tpublic static Accessibility Union(this Accessibility a, Accessibility b)\n\t\t{\n\t\t\tif (a > b)\n\t\t\t{\n\t\t\t\tExtensionMethods.Swap(ref a, ref b);\n\t\t\t}\n\t\t\tif (a == Accessibility.Protected && b == Accessibility.Internal)\n\t\t\t{\n\t\t\t\treturn Accessibility.ProtectedOrInternal;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDebug.Assert(!(a == Accessibility.Internal && b == Accessibility.Protected));\n\t\t\t\treturn b;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the effective accessibility of the entity.\n\t\t/// For example, a public method in an internal class returns \"internal\".\n\t\t/// </summary>\n\t\tpublic static Accessibility EffectiveAccessibility(this IEntity entity)\n\t\t{\n\t\t\tAccessibility accessibility = entity.Accessibility;\n\t\t\tfor (ITypeDefinition typeDef = entity.DeclaringTypeDefinition; typeDef != null; typeDef = typeDef.DeclaringTypeDefinition)\n\t\t\t{\n\t\t\t\taccessibility = Intersect(accessibility, typeDef.Accessibility);\n\t\t\t}\n\t\t\treturn accessibility;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/ApplyAttributeTypeVisitor.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.DebugInfo;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nusing SRM = System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Introduces 'dynamic' and tuple types based on attribute values.\n\t/// </summary>\n\tsealed class ApplyAttributeTypeVisitor : TypeVisitor\n\t{\n\t\tpublic static IType ApplyAttributesToType(\n\t\t\tIType inputType,\n\t\t\tICompilation compilation,\n\t\t\tSRM.CustomAttributeHandleCollection? attributes,\n\t\t\tSRM.MetadataReader metadata,\n\t\t\tTypeSystemOptions options,\n\t\t\tNullability nullableContext,\n\t\t\tbool typeChildrenOnly = false,\n\t\t\tSRM.CustomAttributeHandleCollection? additionalAttributes = null)\n\t\t{\n\t\t\tbool hasDynamicAttribute = false;\n\t\t\tbool[] dynamicAttributeData = null;\n\t\t\tbool hasNativeIntegersAttribute = (options & TypeSystemOptions.NativeIntegersWithoutAttribute) != 0;\n\t\t\tbool[] nativeIntegersAttributeData = null;\n\t\t\tstring[] tupleElementNames = null;\n\t\t\tNullability nullability;\n\t\t\tNullability[] nullableAttributeData = null;\n\t\t\tif ((options & TypeSystemOptions.NullabilityAnnotations) != 0)\n\t\t\t{\n\t\t\t\tnullability = nullableContext;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tnullability = Nullability.Oblivious;\n\t\t\t}\n\n\t\t\tvoid ProcessAttribute(SRM.CustomAttributeHandle attrHandle)\n\t\t\t{\n\t\t\t\tvar attr = metadata.GetCustomAttribute(attrHandle);\n\t\t\t\tvar attrType = attr.GetAttributeType(metadata);\n\t\t\t\tif ((options & TypeSystemOptions.Dynamic) != 0 && attrType.IsKnownType(metadata, KnownAttribute.Dynamic))\n\t\t\t\t{\n\t\t\t\t\thasDynamicAttribute = true;\n\t\t\t\t\tvar ctor = attr.DecodeValue(Metadata.MetadataExtensions.minimalCorlibTypeProvider);\n\t\t\t\t\tif (ctor.FixedArguments.Length == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar arg = ctor.FixedArguments[0];\n\t\t\t\t\t\tif (arg.Value is ImmutableArray<SRM.CustomAttributeTypedArgument<IType>> values\n\t\t\t\t\t\t\t&& values.All(v => v.Value is bool))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdynamicAttributeData = values.SelectArray(v => (bool)v.Value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if ((options & TypeSystemOptions.NativeIntegers) != 0 && attrType.IsKnownType(metadata, KnownAttribute.NativeInteger))\n\t\t\t\t{\n\t\t\t\t\thasNativeIntegersAttribute = true;\n\t\t\t\t\tvar ctor = attr.DecodeValue(Metadata.MetadataExtensions.minimalCorlibTypeProvider);\n\t\t\t\t\tif (ctor.FixedArguments.Length == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar arg = ctor.FixedArguments[0];\n\t\t\t\t\t\tif (arg.Value is ImmutableArray<SRM.CustomAttributeTypedArgument<IType>> values\n\t\t\t\t\t\t\t&& values.All(v => v.Value is bool))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnativeIntegersAttributeData = values.SelectArray(v => (bool)v.Value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if ((options & TypeSystemOptions.Tuple) != 0 && attrType.IsKnownType(metadata, KnownAttribute.TupleElementNames))\n\t\t\t\t{\n\t\t\t\t\tvar ctor = attr.DecodeValue(Metadata.MetadataExtensions.minimalCorlibTypeProvider);\n\t\t\t\t\tif (ctor.FixedArguments.Length == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar arg = ctor.FixedArguments[0];\n\t\t\t\t\t\tif (arg.Value is ImmutableArray<SRM.CustomAttributeTypedArgument<IType>> values\n\t\t\t\t\t\t\t&& values.All(v => v.Value is string || v.Value == null))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttupleElementNames = values.SelectArray(v => (string)v.Value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if ((options & TypeSystemOptions.NullabilityAnnotations) != 0 && attrType.IsKnownType(metadata, KnownAttribute.Nullable))\n\t\t\t\t{\n\t\t\t\t\tvar ctor = attr.DecodeValue(Metadata.MetadataExtensions.minimalCorlibTypeProvider);\n\t\t\t\t\tif (ctor.FixedArguments.Length == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar arg = ctor.FixedArguments[0];\n\t\t\t\t\t\tif (arg.Value is ImmutableArray<SRM.CustomAttributeTypedArgument<IType>> values\n\t\t\t\t\t\t\t&& values.All(v => v.Value is byte b && b <= 2))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnullableAttributeData = values.SelectArray(v => (Nullability)(byte)v.Value);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (arg.Value is byte b && b <= 2)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnullability = (Nullability)b;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst TypeSystemOptions relevantOptions = TypeSystemOptions.Dynamic | TypeSystemOptions.Tuple | TypeSystemOptions.NullabilityAnnotations | TypeSystemOptions.NativeIntegers;\n\t\t\tif (attributes != null && (options & relevantOptions) != 0)\n\t\t\t{\n\t\t\t\tforeach (var attrHandle in attributes.Value)\n\t\t\t\t{\n\t\t\t\t\tProcessAttribute(attrHandle);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (additionalAttributes != null && (options & relevantOptions) != 0)\n\t\t\t{\n\t\t\t\t// Note: additional attributes will override the values from the normal attributes.\n\t\t\t\tforeach (var attrHandle in additionalAttributes.Value)\n\t\t\t\t{\n\t\t\t\t\tProcessAttribute(attrHandle);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (hasDynamicAttribute || hasNativeIntegersAttribute || nullability != Nullability.Oblivious || nullableAttributeData != null\n\t\t\t\t|| (options & (TypeSystemOptions.Tuple | TypeSystemOptions.KeepModifiers)) != TypeSystemOptions.KeepModifiers)\n\t\t\t{\n\t\t\t\tvar visitor = new ApplyAttributeTypeVisitor(\n\t\t\t\t\tcompilation, hasDynamicAttribute, dynamicAttributeData,\n\t\t\t\t\thasNativeIntegersAttribute, nativeIntegersAttributeData,\n\t\t\t\t\toptions, tupleElementNames,\n\t\t\t\t\tnullability, nullableAttributeData\n\t\t\t\t);\n\t\t\t\tif (typeChildrenOnly)\n\t\t\t\t{\n\t\t\t\t\treturn inputType.VisitChildren(visitor);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn inputType.AcceptVisitor(visitor);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn inputType;\n\t\t\t}\n\t\t}\n\n\t\tpublic static IType ApplyAttributesToType(IType inputType, ICompilation compilation, TypeSystemOptions options, PdbExtraTypeInfo pdbExtraTypeInfo)\n\t\t{\n\t\t\tif (pdbExtraTypeInfo.DynamicFlags is null && pdbExtraTypeInfo.TupleElementNames is null)\n\t\t\t\treturn inputType;\n\t\t\treturn inputType.AcceptVisitor(new ApplyAttributeTypeVisitor(compilation, pdbExtraTypeInfo.DynamicFlags != null, pdbExtraTypeInfo.DynamicFlags, false, null, options, pdbExtraTypeInfo.TupleElementNames, Nullability.Oblivious, null));\n\t\t}\n\n\t\treadonly ICompilation compilation;\n\t\treadonly bool hasDynamicAttribute;\n\t\treadonly bool[] dynamicAttributeData;\n\t\treadonly bool hasNativeIntegersAttribute;\n\t\treadonly bool[] nativeIntegersAttributeData;\n\t\treadonly TypeSystemOptions options;\n\t\treadonly string[] tupleElementNames;\n\t\treadonly Nullability defaultNullability;\n\t\treadonly Nullability[] nullableAttributeData;\n\t\tint dynamicTypeIndex = 0;\n\t\tint tupleTypeIndex = 0;\n\t\tint nullabilityTypeIndex = 0;\n\t\tint nativeIntTypeIndex = 0;\n\n\t\tprivate ApplyAttributeTypeVisitor(ICompilation compilation,\n\t\t\tbool hasDynamicAttribute, bool[] dynamicAttributeData,\n\t\t\tbool hasNativeIntegersAttribute, bool[] nativeIntegersAttributeData,\n\t\t\tTypeSystemOptions options, string[] tupleElementNames,\n\t\t\tNullability defaultNullability, Nullability[] nullableAttributeData)\n\t\t{\n\t\t\tthis.compilation = compilation ?? throw new ArgumentNullException(nameof(compilation));\n\t\t\tthis.hasDynamicAttribute = hasDynamicAttribute;\n\t\t\tthis.dynamicAttributeData = dynamicAttributeData;\n\t\t\tthis.hasNativeIntegersAttribute = hasNativeIntegersAttribute;\n\t\t\tthis.nativeIntegersAttributeData = nativeIntegersAttributeData;\n\t\t\tthis.options = options;\n\t\t\tthis.tupleElementNames = tupleElementNames;\n\t\t\tthis.defaultNullability = defaultNullability;\n\t\t\tthis.nullableAttributeData = nullableAttributeData;\n\t\t}\n\n\t\tpublic override IType VisitModOpt(ModifiedType type)\n\t\t{\n\t\t\tdynamicTypeIndex++;\n\t\t\tif ((options & TypeSystemOptions.KeepModifiers) != 0)\n\t\t\t\treturn base.VisitModOpt(type);\n\t\t\telse\n\t\t\t\treturn type.ElementType.AcceptVisitor(this);\n\t\t}\n\n\t\tpublic override IType VisitModReq(ModifiedType type)\n\t\t{\n\t\t\tdynamicTypeIndex++;\n\t\t\tif ((options & TypeSystemOptions.KeepModifiers) != 0)\n\t\t\t\treturn base.VisitModReq(type);\n\t\t\telse\n\t\t\t\treturn type.ElementType.AcceptVisitor(this);\n\t\t}\n\n\t\tpublic override IType VisitPointerType(PointerType type)\n\t\t{\n\t\t\tdynamicTypeIndex++;\n\t\t\treturn base.VisitPointerType(type);\n\t\t}\n\n\t\tNullability GetNullability()\n\t\t{\n\t\t\tif (nullabilityTypeIndex < nullableAttributeData?.Length)\n\t\t\t\treturn nullableAttributeData[nullabilityTypeIndex++];\n\t\t\telse\n\t\t\t\treturn defaultNullability;\n\t\t}\n\n\t\tvoid ExpectDummyNullabilityForGenericValueType()\n\t\t{\n\t\t\tvar n = GetNullability();\n\t\t\tDebug.Assert(n == Nullability.Oblivious);\n\t\t}\n\n\t\tpublic override IType VisitArrayType(ArrayType type)\n\t\t{\n\t\t\tvar nullability = GetNullability();\n\t\t\tdynamicTypeIndex++;\n\t\t\treturn base.VisitArrayType(type).ChangeNullability(nullability);\n\t\t}\n\n\t\tpublic override IType VisitByReferenceType(ByReferenceType type)\n\t\t{\n\t\t\tdynamicTypeIndex++;\n\t\t\treturn base.VisitByReferenceType(type);\n\t\t}\n\n\t\tpublic override IType VisitParameterizedType(ParameterizedType type)\n\t\t{\n\t\t\tbool useTupleTypes = (options & TypeSystemOptions.Tuple) != 0;\n\t\t\tif (useTupleTypes && TupleType.IsTupleCompatible(type, out int tupleCardinality))\n\t\t\t{\n\t\t\t\tif (tupleCardinality > 1)\n\t\t\t\t{\n\t\t\t\t\tvar valueTupleAssembly = type.GetDefinition()?.ParentModule;\n\t\t\t\t\tImmutableArray<string> elementNames = default;\n\t\t\t\t\tif (tupleElementNames != null && tupleTypeIndex < tupleElementNames.Length)\n\t\t\t\t\t{\n\t\t\t\t\t\tstring[] extractedValues = new string[tupleCardinality];\n\t\t\t\t\t\tArray.Copy(tupleElementNames, tupleTypeIndex, extractedValues, 0,\n\t\t\t\t\t\t\tMath.Min(tupleCardinality, tupleElementNames.Length - tupleTypeIndex));\n\t\t\t\t\t\telementNames = ImmutableArray.CreateRange(extractedValues);\n\t\t\t\t\t}\n\t\t\t\t\ttupleTypeIndex += tupleCardinality;\n\t\t\t\t\tExpectDummyNullabilityForGenericValueType();\n\t\t\t\t\tvar elementTypes = ImmutableArray.CreateBuilder<IType>(tupleCardinality);\n\t\t\t\t\tdo\n\t\t\t\t\t{\n\t\t\t\t\t\tint normalArgCount = Math.Min(type.TypeArguments.Count, TupleType.RestPosition - 1);\n\t\t\t\t\t\tfor (int i = 0; i < normalArgCount; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdynamicTypeIndex++;\n\t\t\t\t\t\t\telementTypes.Add(type.TypeArguments[i].AcceptVisitor(this));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (type.TypeArguments.Count == TupleType.RestPosition)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype = type.TypeArguments.Last() as ParameterizedType;\n\t\t\t\t\t\t\tExpectDummyNullabilityForGenericValueType();\n\t\t\t\t\t\t\tdynamicTypeIndex++;\n\t\t\t\t\t\t\tif (type != null && TupleType.IsTupleCompatible(type, out int nestedCardinality))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttupleTypeIndex += nestedCardinality;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tDebug.Fail(\"TRest should be another value tuple\");\n\t\t\t\t\t\t\t\ttype = null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t} while (type != null);\n\t\t\t\t\tDebug.Assert(elementTypes.Count == tupleCardinality);\n\t\t\t\t\treturn new TupleType(\n\t\t\t\t\t\tcompilation,\n\t\t\t\t\t\telementTypes.MoveToImmutable(),\n\t\t\t\t\t\telementNames,\n\t\t\t\t\t\tvalueTupleAssembly\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// C# doesn't have syntax for tuples of cardinality <= 1\n\t\t\t\t\ttupleTypeIndex += tupleCardinality;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Visit generic type and type arguments.\n\t\t\t// Like base implementation, except that it increments dynamicTypeIndex.\n\t\t\tvar genericType = type.GenericType.AcceptVisitor(this);\n\t\t\tif (genericType.IsReferenceType != true && !genericType.IsKnownType(KnownTypeCode.NullableOfT))\n\t\t\t{\n\t\t\t\tExpectDummyNullabilityForGenericValueType();\n\t\t\t}\n\t\t\tbool changed = type.GenericType != genericType;\n\t\t\tvar arguments = new IType[type.TypeArguments.Count];\n\t\t\tfor (int i = 0; i < type.TypeArguments.Count; i++)\n\t\t\t{\n\t\t\t\tdynamicTypeIndex++;\n\t\t\t\targuments[i] = type.TypeArguments[i].AcceptVisitor(this);\n\t\t\t\tchanged = changed || arguments[i] != type.TypeArguments[i];\n\t\t\t}\n\t\t\tif (!changed)\n\t\t\t\treturn type;\n\t\t\treturn new ParameterizedType(genericType, arguments);\n\t\t}\n\n\t\tpublic override IType VisitFunctionPointerType(FunctionPointerType type)\n\t\t{\n\t\t\tdynamicTypeIndex++;\n\t\t\tif (type.ReturnIsRefReadOnly)\n\t\t\t{\n\t\t\t\tdynamicTypeIndex++;\n\t\t\t}\n\t\t\tvar returnType = type.ReturnType.AcceptVisitor(this);\n\t\t\tbool changed = type.ReturnType != returnType;\n\t\t\tvar parameters = new IType[type.ParameterTypes.Length];\n\t\t\tfor (int i = 0; i < parameters.Length; i++)\n\t\t\t{\n\t\t\t\tdynamicTypeIndex += type.ParameterReferenceKinds[i] switch {\n\t\t\t\t\tReferenceKind.None => 1,\n\t\t\t\t\tReferenceKind.Ref => 1,\n\t\t\t\t\tReferenceKind.Out => 2, // in/out also count the modreq\n\t\t\t\t\tReferenceKind.In => 2,\n\t\t\t\t\tReferenceKind.RefReadOnly => 2, // counts the modopt\n\t\t\t\t\t_ => throw new NotSupportedException()\n\t\t\t\t};\n\t\t\t\tparameters[i] = type.ParameterTypes[i].AcceptVisitor(this);\n\t\t\t\tchanged = changed || parameters[i] != type.ParameterTypes[i];\n\t\t\t}\n\t\t\tif (!changed)\n\t\t\t\treturn type;\n\t\t\treturn type.WithSignature(returnType, parameters.ToImmutableArray());\n\t\t}\n\n\t\tpublic override IType VisitTypeDefinition(ITypeDefinition type)\n\t\t{\n\t\t\tIType newType = type;\n\t\t\tvar ktc = type.KnownTypeCode;\n\t\t\tif (ktc == KnownTypeCode.Object && hasDynamicAttribute)\n\t\t\t{\n\t\t\t\tif (dynamicAttributeData == null || dynamicTypeIndex >= dynamicAttributeData.Length)\n\t\t\t\t\tnewType = SpecialType.Dynamic;\n\t\t\t\telse if (dynamicAttributeData[dynamicTypeIndex])\n\t\t\t\t\tnewType = SpecialType.Dynamic;\n\t\t\t}\n\t\t\telse if ((ktc == KnownTypeCode.IntPtr || ktc == KnownTypeCode.UIntPtr) && hasNativeIntegersAttribute)\n\t\t\t{\n\t\t\t\t// native integers use the same indexing logic as 'dynamic'\n\t\t\t\tif (nativeIntegersAttributeData == null || nativeIntTypeIndex >= nativeIntegersAttributeData.Length)\n\t\t\t\t\tnewType = (ktc == KnownTypeCode.IntPtr ? SpecialType.NInt : SpecialType.NUInt);\n\t\t\t\telse if (nativeIntegersAttributeData[nativeIntTypeIndex])\n\t\t\t\t\tnewType = (ktc == KnownTypeCode.IntPtr ? SpecialType.NInt : SpecialType.NUInt);\n\t\t\t\tnativeIntTypeIndex++;\n\t\t\t}\n\t\t\tif (type.IsReferenceType == true)\n\t\t\t{\n\t\t\t\tNullability nullability = GetNullability();\n\t\t\t\treturn newType.ChangeNullability(nullability);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn newType;\n\t\t\t}\n\t\t}\n\n\t\tpublic override IType VisitOtherType(IType type)\n\t\t{\n\t\t\ttype = base.VisitOtherType(type);\n\t\t\tif (type.Kind == TypeKind.Unknown && type.IsReferenceType == true)\n\t\t\t{\n\t\t\t\tNullability nullability = GetNullability();\n\t\t\t\ttype = type.ChangeNullability(nullability);\n\t\t\t}\n\t\t\treturn type;\n\t\t}\n\n\t\tpublic override IType VisitTypeParameter(ITypeParameter type)\n\t\t{\n\t\t\tNullability nullability = GetNullability();\n\t\t\treturn type.ChangeNullability(nullability);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/ArrayType.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Represents an array type.\n\t/// </summary>\n\tpublic sealed class ArrayType : TypeWithElementType, ICompilationProvider\n\t{\n\t\treadonly int dimensions;\n\t\treadonly ICompilation compilation;\n\t\treadonly Nullability nullability;\n\n\t\tpublic ArrayType(ICompilation compilation, IType elementType, int dimensions = 1, Nullability nullability = Nullability.Oblivious) : base(elementType)\n\t\t{\n\t\t\tif (compilation == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(compilation));\n\t\t\tif (dimensions <= 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(dimensions), dimensions, \"dimensions must be positive\");\n\t\t\tthis.compilation = compilation;\n\t\t\tthis.dimensions = dimensions;\n\t\t\tthis.nullability = nullability;\n\n\t\t\tICompilationProvider p = elementType as ICompilationProvider;\n\t\t\tif (p != null && p.Compilation != compilation)\n\t\t\t\tthrow new InvalidOperationException(\"Cannot create an array type using a different compilation from the element type.\");\n\t\t}\n\n\t\tpublic override TypeKind Kind {\n\t\t\tget { return TypeKind.Array; }\n\t\t}\n\n\t\tpublic ICompilation Compilation {\n\t\t\tget { return compilation; }\n\t\t}\n\n\t\tpublic int Dimensions {\n\t\t\tget { return dimensions; }\n\t\t}\n\n\t\tpublic override Nullability Nullability => nullability;\n\n\t\tpublic override IType ChangeNullability(Nullability nullability)\n\t\t{\n\t\t\tif (nullability == this.nullability)\n\t\t\t\treturn this;\n\t\t\telse\n\t\t\t\treturn new ArrayType(compilation, elementType, dimensions, nullability);\n\t\t}\n\n\t\tpublic override string NameSuffix {\n\t\t\tget {\n\t\t\t\treturn \"[\" + new string(',', dimensions - 1) + \"]\";\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool? IsReferenceType {\n\t\t\tget { return true; }\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn unchecked(elementType.GetHashCode() * 71681 + dimensions);\n\t\t}\n\n\t\tpublic override bool Equals(IType other)\n\t\t{\n\t\t\tArrayType a = other as ArrayType;\n\t\t\treturn a != null && elementType.Equals(a.elementType) && a.dimensions == dimensions && a.nullability == nullability;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tswitch (nullability)\n\t\t\t{\n\t\t\t\tcase Nullability.Nullable:\n\t\t\t\t\treturn elementType.ToString() + NameSuffix + \"?\";\n\t\t\t\tcase Nullability.NotNullable:\n\t\t\t\t\treturn elementType.ToString() + NameSuffix + \"!\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn elementType.ToString() + NameSuffix;\n\t\t\t}\n\t\t}\n\n\t\tpublic override IEnumerable<IType> DirectBaseTypes {\n\t\t\tget {\n\t\t\t\tList<IType> baseTypes = new List<IType>();\n\t\t\t\tIType t = compilation.FindType(KnownTypeCode.Array);\n\t\t\t\tif (t.Kind != TypeKind.Unknown)\n\t\t\t\t\tbaseTypes.Add(t);\n\t\t\t\tif (dimensions == 1 && elementType.Kind != TypeKind.Pointer)\n\t\t\t\t{\n\t\t\t\t\t// single-dimensional arrays implement IList<T>\n\t\t\t\t\tITypeDefinition def = compilation.FindType(KnownTypeCode.IListOfT) as ITypeDefinition;\n\t\t\t\t\tif (def != null)\n\t\t\t\t\t\tbaseTypes.Add(new ParameterizedType(def, new[] { elementType }));\n\t\t\t\t\t// And in .NET 4.5 they also implement IReadOnlyList<T>\n\t\t\t\t\tdef = compilation.FindType(KnownTypeCode.IReadOnlyListOfT) as ITypeDefinition;\n\t\t\t\t\tif (def != null)\n\t\t\t\t\t\tbaseTypes.Add(new ParameterizedType(def, new[] { elementType }));\n\t\t\t\t}\n\t\t\t\treturn baseTypes;\n\t\t\t}\n\t\t}\n\n\t\tpublic override IEnumerable<IMethod> GetMethods(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t\telse\n\t\t\t\treturn compilation.FindType(KnownTypeCode.Array).GetMethods(filter, options);\n\t\t}\n\n\t\tpublic override IEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t\telse\n\t\t\t\treturn compilation.FindType(KnownTypeCode.Array).GetMethods(typeArguments, filter, options);\n\t\t}\n\n\t\tpublic override IEnumerable<IMethod> GetAccessors(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t\telse\n\t\t\t\treturn compilation.FindType(KnownTypeCode.Array).GetAccessors(filter, options);\n\t\t}\n\n\t\tpublic override IEnumerable<IProperty> GetProperties(Predicate<IProperty> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t\treturn EmptyList<IProperty>.Instance;\n\t\t\telse\n\t\t\t\treturn compilation.FindType(KnownTypeCode.Array).GetProperties(filter, options);\n\t\t}\n\n\t\t// NestedTypes, Events, Fields: System.Array doesn't have any; so we can use the AbstractType default implementation\n\t\t// that simply returns an empty list\n\n\t\tpublic override IType AcceptVisitor(TypeVisitor visitor)\n\t\t{\n\t\t\treturn visitor.VisitArrayType(this);\n\t\t}\n\n\t\tpublic override IType VisitChildren(TypeVisitor visitor)\n\t\t{\n\t\t\tIType e = elementType.AcceptVisitor(visitor);\n\t\t\tif (e == elementType)\n\t\t\t\treturn this;\n\t\t\telse\n\t\t\t\treturn new ArrayType(compilation, e, dimensions, nullability);\n\t\t}\n\t}\n\n\t[Serializable]\n\tpublic sealed class ArrayTypeReference : ITypeReference, ISupportsInterning\n\t{\n\t\treadonly ITypeReference elementType;\n\t\treadonly int dimensions;\n\n\t\tpublic ArrayTypeReference(ITypeReference elementType, int dimensions = 1)\n\t\t{\n\t\t\tif (elementType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(elementType));\n\t\t\tif (dimensions <= 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(dimensions), dimensions, \"dimensions must be positive\");\n\t\t\tthis.elementType = elementType;\n\t\t\tthis.dimensions = dimensions;\n\t\t}\n\n\t\tpublic ITypeReference ElementType {\n\t\t\tget { return elementType; }\n\t\t}\n\n\t\tpublic int Dimensions {\n\t\t\tget { return dimensions; }\n\t\t}\n\n\t\tpublic IType Resolve(ITypeResolveContext context)\n\t\t{\n\t\t\treturn new ArrayType(context.Compilation, elementType.Resolve(context), dimensions);\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn elementType.ToString() + \"[\" + new string(',', dimensions - 1) + \"]\";\n\t\t}\n\n\t\tint ISupportsInterning.GetHashCodeForInterning()\n\t\t{\n\t\t\treturn elementType.GetHashCode() ^ dimensions;\n\t\t}\n\n\t\tbool ISupportsInterning.EqualsForInterning(ISupportsInterning other)\n\t\t{\n\t\t\tArrayTypeReference o = other as ArrayTypeReference;\n\t\t\treturn o != null && elementType == o.elementType && dimensions == o.dimensions;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/AssemblyQualifiedTypeName.cs",
    "content": "// Copyright (c) 2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\tpublic struct AssemblyQualifiedTypeName : IEquatable<AssemblyQualifiedTypeName>\n\t{\n\t\tpublic readonly string AssemblyName;\n\t\tpublic readonly FullTypeName TypeName;\n\n\t\tpublic AssemblyQualifiedTypeName(FullTypeName typeName, string assemblyName)\n\t\t{\n\t\t\tthis.AssemblyName = assemblyName;\n\t\t\tthis.TypeName = typeName;\n\t\t}\n\n\t\tpublic AssemblyQualifiedTypeName(ITypeDefinition typeDefinition)\n\t\t{\n\t\t\tthis.AssemblyName = typeDefinition.ParentModule.AssemblyName;\n\t\t\tthis.TypeName = typeDefinition.FullTypeName;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(AssemblyName))\n\t\t\t\treturn TypeName.ToString();\n\t\t\telse\n\t\t\t\treturn TypeName.ToString() + \", \" + AssemblyName;\n\t\t}\n\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\treturn (obj is AssemblyQualifiedTypeName) && Equals((AssemblyQualifiedTypeName)obj);\n\t\t}\n\n\t\tpublic bool Equals(AssemblyQualifiedTypeName other)\n\t\t{\n\t\t\treturn this.AssemblyName == other.AssemblyName && this.TypeName == other.TypeName;\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\tint hashCode = 0;\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\tif (AssemblyName != null)\n\t\t\t\t\thashCode += 1000000007 * AssemblyName.GetHashCode();\n\t\t\t\thashCode += TypeName.GetHashCode();\n\t\t\t}\n\t\t\treturn hashCode;\n\t\t}\n\n\t\tpublic static bool operator ==(AssemblyQualifiedTypeName lhs, AssemblyQualifiedTypeName rhs)\n\t\t{\n\t\t\treturn lhs.Equals(rhs);\n\t\t}\n\n\t\tpublic static bool operator !=(AssemblyQualifiedTypeName lhs, AssemblyQualifiedTypeName rhs)\n\t\t{\n\t\t\treturn !lhs.Equals(rhs);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/ByReferenceType.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\tpublic sealed class ByReferenceType : TypeWithElementType\n\t{\n\t\tpublic ByReferenceType(IType elementType) : base(elementType)\n\t\t{\n\t\t}\n\n\t\tpublic override TypeKind Kind {\n\t\t\tget { return TypeKind.ByReference; }\n\t\t}\n\n\t\tpublic override string NameSuffix {\n\t\t\tget {\n\t\t\t\treturn \"&\";\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool? IsReferenceType {\n\t\t\tget { return null; }\n\t\t}\n\n\t\tpublic override bool IsByRefLike => true;\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn elementType.GetHashCode() ^ 91725813;\n\t\t}\n\n\t\tpublic override bool Equals(IType other)\n\t\t{\n\t\t\tByReferenceType a = other as ByReferenceType;\n\t\t\treturn a != null && elementType.Equals(a.elementType);\n\t\t}\n\n\t\tpublic override IType AcceptVisitor(TypeVisitor visitor)\n\t\t{\n\t\t\treturn visitor.VisitByReferenceType(this);\n\t\t}\n\n\t\tpublic override IType VisitChildren(TypeVisitor visitor)\n\t\t{\n\t\t\tIType e = elementType.AcceptVisitor(visitor);\n\t\t\tif (e == elementType)\n\t\t\t\treturn this;\n\t\t\telse\n\t\t\t\treturn new ByReferenceType(e);\n\t\t}\n\t}\n\n\t[Serializable]\n\tpublic sealed class ByReferenceTypeReference : ITypeReference, ISupportsInterning\n\t{\n\t\treadonly ITypeReference elementType;\n\n\t\tpublic ByReferenceTypeReference(ITypeReference elementType)\n\t\t{\n\t\t\tif (elementType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(elementType));\n\t\t\tthis.elementType = elementType;\n\t\t}\n\n\t\tpublic ITypeReference ElementType {\n\t\t\tget { return elementType; }\n\t\t}\n\n\t\tpublic IType Resolve(ITypeResolveContext context)\n\t\t{\n\t\t\treturn new ByReferenceType(elementType.Resolve(context));\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn elementType.ToString() + \"&\";\n\t\t}\n\n\t\tint ISupportsInterning.GetHashCodeForInterning()\n\t\t{\n\t\t\treturn elementType.GetHashCode() ^ 91725814;\n\t\t}\n\n\t\tbool ISupportsInterning.EqualsForInterning(ISupportsInterning other)\n\t\t{\n\t\t\tByReferenceTypeReference brt = other as ByReferenceTypeReference;\n\t\t\treturn brt != null && this.elementType == brt.elementType;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/ComHelper.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.Semantics;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Helper methods for COM.\n\t/// </summary>\n\tpublic static class ComHelper\n\t{\n\t\t/// <summary>\n\t\t/// Gets whether the specified type is imported from COM.\n\t\t/// </summary>\n\t\tpublic static bool IsComImport(ITypeDefinition typeDefinition)\n\t\t{\n\t\t\treturn typeDefinition != null\n\t\t\t\t&& typeDefinition.Kind == TypeKind.Interface\n\t\t\t\t&& typeDefinition.HasAttribute(KnownAttribute.ComImport);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the CoClass of the specified COM interface.\n\t\t/// </summary>\n\t\t[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1709:IdentifiersShouldBeCasedCorrectly\", MessageId = \"Co\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t Justification = \"Consistent with CoClassAttribute\")]\n\t\tpublic static IType GetCoClass(ITypeDefinition typeDefinition)\n\t\t{\n\t\t\tif (typeDefinition == null)\n\t\t\t\treturn SpecialType.UnknownType;\n\t\t\tvar coClassAttribute = typeDefinition.GetAttribute(KnownAttribute.CoClass);\n\t\t\tif (coClassAttribute != null && coClassAttribute.FixedArguments.Length == 1)\n\t\t\t{\n\t\t\t\tif (coClassAttribute.FixedArguments[0].Value is IType ty)\n\t\t\t\t\treturn ty;\n\t\t\t}\n\t\t\treturn SpecialType.UnknownType;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nusing static ICSharpCode.Decompiler.Metadata.MetadataExtensions;\n\nusing SRM = System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Options that control how metadata is represented in the type system.\n\t/// </summary>\n\t[Flags]\n\tpublic enum TypeSystemOptions\n\t{\n\t\t/// <summary>\n\t\t/// No options enabled; stay as close to the metadata as possible.\n\t\t/// </summary>\n\t\tNone = 0,\n\t\t/// <summary>\n\t\t/// [DynamicAttribute] is used to replace 'object' types with the 'dynamic' type.\n\t\t/// \n\t\t/// If this option is not active, the 'dynamic' type is not used, and the attribute is preserved.\n\t\t/// </summary>\n\t\tDynamic = 1,\n\t\t/// <summary>\n\t\t/// Tuple types are represented using the TupleType class.\n\t\t/// [TupleElementNames] is used to name the tuple elements.\n\t\t/// \n\t\t/// If this option is not active, the tuples are represented using their underlying type, and the attribute is preserved.\n\t\t/// </summary>\n\t\tTuple = 2,\n\t\t/// <summary>\n\t\t/// If this option is active, [ExtensionAttribute] is removed and methods are marked as IsExtensionMethod.\n\t\t/// Otherwise, the attribute is preserved but the methods are not marked.\n\t\t/// </summary>\n\t\tExtensionMethods = 4,\n\t\t/// <summary>\n\t\t/// Only load the public API into the type system.\n\t\t/// </summary>\n\t\tOnlyPublicAPI = 8,\n\t\t/// <summary>\n\t\t/// Do not cache accessed entities.\n\t\t/// In a normal type system (without this option), every type or member definition has exactly one ITypeDefinition/IMember\n\t\t/// instance. This instance is kept alive until the whole type system can be garbage-collected.\n\t\t/// When this option is specified, the type system avoids these caches.\n\t\t/// This reduces the memory usage in many cases, but increases the number of allocations.\n\t\t/// Also, some code in the decompiler expects to be able to compare type/member definitions by reference equality,\n\t\t/// and thus will fail with uncached type systems.\n\t\t/// </summary>\n\t\tUncached = 0x10,\n\t\t/// <summary>\n\t\t/// If this option is active, [DecimalConstantAttribute] is removed and constant values are transformed into simple decimal literals.\n\t\t/// </summary>\n\t\tDecimalConstants = 0x20,\n\t\t/// <summary>\n\t\t/// If this option is active, modopt and modreq types are preserved in the type system.\n\t\t/// \n\t\t/// Note: the decompiler currently does not support handling modified types;\n\t\t/// activating this option may lead to incorrect decompilation or internal errors.\n\t\t/// </summary>\n\t\tKeepModifiers = 0x40,\n\t\t/// <summary>\n\t\t/// If this option is active, [IsReadOnlyAttribute] on parameters+structs is removed\n\t\t/// and parameters are marked as in, structs as readonly.\n\t\t/// Otherwise, the attribute is preserved but the parameters and structs are not marked.\n\t\t/// </summary>\n\t\tReadOnlyStructsAndParameters = 0x80,\n\t\t/// <summary>\n\t\t/// If this option is active, [IsByRefLikeAttribute] is removed and structs are marked as ref.\n\t\t/// Otherwise, the attribute is preserved but the structs are not marked.\n\t\t/// </summary>\n\t\tRefStructs = 0x100,\n\t\t/// <summary>\n\t\t/// If this option is active, [IsUnmanagedAttribute] is removed from type parameters,\n\t\t/// and HasUnmanagedConstraint is set instead.\n\t\t/// </summary>\n\t\tUnmanagedConstraints = 0x200,\n\t\t/// <summary>\n\t\t/// If this option is active, [NullableAttribute] is removed and reference types with\n\t\t/// nullability annotations are used instead.\n\t\t/// </summary>\n\t\tNullabilityAnnotations = 0x400,\n\t\t/// <summary>\n\t\t/// If this option is active, [IsReadOnlyAttribute] on methods is removed\n\t\t/// and the method marked as ThisIsRefReadOnly.\n\t\t/// </summary>\n\t\tReadOnlyMethods = 0x800,\n\t\t/// <summary>\n\t\t/// [NativeIntegerAttribute] is used to replace 'IntPtr' types with the 'nint' type.\n\t\t/// </summary>\n\t\tNativeIntegers = 0x1000,\n\t\t/// <summary>\n\t\t/// Allow function pointer types. If this option is not enabled, function pointers are\n\t\t/// replaced with the 'IntPtr' type.\n\t\t/// </summary>\n\t\tFunctionPointers = 0x2000,\n\t\t/// <summary>\n\t\t/// Allow C# 11 scoped annotation. If this option is not enabled, ScopedRefAttribute\n\t\t/// will be reported as custom attribute.\n\t\t/// </summary>\n\t\tScopedRef = 0x4000,\n\t\t/// <summary>\n\t\t/// Replace 'IntPtr' types with the 'nint' type even in absence of [NativeIntegerAttribute].\n\t\t/// Note: DecompilerTypeSystem constructor removes this setting from the options if\n\t\t/// not targeting .NET 7 or later.\n\t\t/// </summary>\n\t\tNativeIntegersWithoutAttribute = 0x8000,\n\t\t/// <summary>\n\t\t/// If this option is active, [RequiresLocationAttribute] on parameters is removed\n\t\t/// and parameters are marked as ref readonly.\n\t\t/// Otherwise, the attribute is preserved but the parameters are not marked\n\t\t/// as if it was a ref parameter without any attributes.\n\t\t/// </summary>\n\t\tRefReadOnlyParameters = 0x10000,\n\t\t/// <summary>\n\t\t/// If this option is active, [ParamCollectionAttribute] on parameters is removed\n\t\t/// and parameters are marked as params.\n\t\t/// Otherwise, the attribute is preserved but the parameters are not marked\n\t\t/// as if it was a normal parameter without any attributes.\n\t\t/// </summary>\n\t\tParamsCollections = 0x20000,\n\t\t/// <summary>\n\t\t/// If this option is active, span types (Span&lt;T&gt; and ReadOnlySpan&lt;T&gt;) are treated like\n\t\t/// built-in types and language rules of C# 14 and later are applied.\n\t\t/// </summary>\n\t\tFirstClassSpanTypes = 0x40000,\n\t\t/// <summary>\n\t\t/// Default settings: typical options for the decompiler, with all C# language features enabled.\n\t\t/// </summary>\n\t\tDefault = Dynamic | Tuple | ExtensionMethods | DecimalConstants | ReadOnlyStructsAndParameters\n\t\t\t| RefStructs | UnmanagedConstraints | NullabilityAnnotations | ReadOnlyMethods\n\t\t\t| NativeIntegers | FunctionPointers | ScopedRef | NativeIntegersWithoutAttribute\n\t\t\t| RefReadOnlyParameters | ParamsCollections | FirstClassSpanTypes\n\t}\n\n\t/// <summary>\n\t/// Manages the NRefactory type system for the decompiler.\n\t/// </summary>\n\t/// <remarks>\n\t/// This class is thread-safe.\n\t/// </remarks>\n\tpublic class DecompilerTypeSystem : SimpleCompilation, IDecompilerTypeSystem\n\t{\n\t\tpublic static TypeSystemOptions GetOptions(DecompilerSettings settings)\n\t\t{\n\t\t\tvar typeSystemOptions = TypeSystemOptions.None;\n\t\t\tif (settings.Dynamic)\n\t\t\t\ttypeSystemOptions |= TypeSystemOptions.Dynamic;\n\t\t\tif (settings.TupleTypes)\n\t\t\t\ttypeSystemOptions |= TypeSystemOptions.Tuple;\n\t\t\tif (settings.ExtensionMethods)\n\t\t\t\ttypeSystemOptions |= TypeSystemOptions.ExtensionMethods;\n\t\t\tif (settings.DecimalConstants)\n\t\t\t\ttypeSystemOptions |= TypeSystemOptions.DecimalConstants;\n\t\t\tif (settings.IntroduceRefModifiersOnStructs)\n\t\t\t\ttypeSystemOptions |= TypeSystemOptions.RefStructs;\n\t\t\tif (settings.IntroduceReadonlyAndInModifiers)\n\t\t\t\ttypeSystemOptions |= TypeSystemOptions.ReadOnlyStructsAndParameters;\n\t\t\tif (settings.IntroduceUnmanagedConstraint)\n\t\t\t\ttypeSystemOptions |= TypeSystemOptions.UnmanagedConstraints;\n\t\t\tif (settings.NullableReferenceTypes)\n\t\t\t\ttypeSystemOptions |= TypeSystemOptions.NullabilityAnnotations;\n\t\t\tif (settings.ReadOnlyMethods)\n\t\t\t\ttypeSystemOptions |= TypeSystemOptions.ReadOnlyMethods;\n\t\t\tif (settings.NativeIntegers)\n\t\t\t\ttypeSystemOptions |= TypeSystemOptions.NativeIntegers;\n\t\t\tif (settings.FunctionPointers)\n\t\t\t\ttypeSystemOptions |= TypeSystemOptions.FunctionPointers;\n\t\t\tif (settings.ScopedRef)\n\t\t\t\ttypeSystemOptions |= TypeSystemOptions.ScopedRef;\n\t\t\tif (settings.NumericIntPtr)\n\t\t\t\ttypeSystemOptions |= TypeSystemOptions.NativeIntegersWithoutAttribute;\n\t\t\tif (settings.RefReadOnlyParameters)\n\t\t\t\ttypeSystemOptions |= TypeSystemOptions.RefReadOnlyParameters;\n\t\t\tif (settings.ParamsCollections)\n\t\t\t\ttypeSystemOptions |= TypeSystemOptions.ParamsCollections;\n\t\t\tif (settings.FirstClassSpanTypes)\n\t\t\t\ttypeSystemOptions |= TypeSystemOptions.FirstClassSpanTypes;\n\t\t\treturn typeSystemOptions;\n\t\t}\n\n\t\tpublic static Task<DecompilerTypeSystem> CreateAsync(PEFile mainModule, IAssemblyResolver assemblyResolver)\n\t\t{\n\t\t\treturn CreateAsync(mainModule, assemblyResolver, TypeSystemOptions.Default);\n\t\t}\n\n\t\tpublic static Task<DecompilerTypeSystem> CreateAsync(PEFile mainModule, IAssemblyResolver assemblyResolver, DecompilerSettings settings)\n\t\t{\n\t\t\treturn CreateAsync(mainModule, assemblyResolver, GetOptions(settings ?? throw new ArgumentNullException(nameof(settings))));\n\t\t}\n\n\t\tpublic static async Task<DecompilerTypeSystem> CreateAsync(PEFile mainModule, IAssemblyResolver assemblyResolver, TypeSystemOptions typeSystemOptions)\n\t\t{\n\t\t\tif (mainModule == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(mainModule));\n\t\t\tif (assemblyResolver == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(assemblyResolver));\n\t\t\tvar ts = new DecompilerTypeSystem(typeSystemOptions);\n\t\t\tawait ts.InitializeAsync(mainModule, assemblyResolver)\n\t\t\t\t.ConfigureAwait(false);\n\t\t\treturn ts;\n\t\t}\n\n\t\tprivate MetadataModule mainModule;\n\t\tprivate TypeSystemOptions typeSystemOptions;\n\n\t\tprivate DecompilerTypeSystem(TypeSystemOptions typeSystemOptions)\n\t\t{\n\t\t\tthis.typeSystemOptions = typeSystemOptions;\n\t\t}\n\n\t\tpublic DecompilerTypeSystem(MetadataFile mainModule, IAssemblyResolver assemblyResolver)\n\t\t\t: this(mainModule, assemblyResolver, TypeSystemOptions.Default)\n\t\t{\n\t\t}\n\n\t\tpublic DecompilerTypeSystem(MetadataFile mainModule, IAssemblyResolver assemblyResolver, DecompilerSettings settings)\n\t\t\t: this(mainModule, assemblyResolver, GetOptions(settings ?? throw new ArgumentNullException(nameof(settings))))\n\t\t{\n\t\t}\n\n\t\tpublic DecompilerTypeSystem(MetadataFile mainModule, IAssemblyResolver assemblyResolver, TypeSystemOptions typeSystemOptions)\n\t\t\t: this(typeSystemOptions)\n\t\t{\n\t\t\tif (mainModule == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(mainModule));\n\t\t\tif (assemblyResolver == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(assemblyResolver));\n\t\t\tInitializeAsync(mainModule, assemblyResolver).GetAwaiter().GetResult();\n\t\t}\n\n\t\tstatic readonly string[] implicitReferences = new[] {\n\t\t\t\"System.Runtime.InteropServices\",\n\t\t\t\"System.Runtime.CompilerServices.Unsafe\"\n\t\t};\n\n\t\tprivate async Task InitializeAsync(MetadataFile mainModule, IAssemblyResolver assemblyResolver)\n\t\t{\n\t\t\t// Load referenced assemblies and type-forwarder references.\n\t\t\t// This is necessary to make .NET Core/PCL binaries work better.\n\t\t\tvar referencedAssemblies = new List<MetadataFile>();\n\t\t\tvar assemblyReferenceQueue = new Queue<(bool IsAssembly, MetadataFile MainModule, object Reference, Task<MetadataFile> ResolveTask)>();\n\t\t\tvar comparer = KeyComparer.Create(((bool IsAssembly, MetadataFile MainModule, object Reference) reference) =>\n\t\t\t\treference.IsAssembly ? \"A:\" + ((IAssemblyReference)reference.Reference).FullName :\n\t\t\t\t\t\t\t\t\t   \"M:\" + reference.Reference);\n\t\t\tvar assemblyReferencesInQueue = new HashSet<(bool IsAssembly, MetadataFile Parent, object Reference)>(comparer);\n\t\t\tvar mainMetadata = mainModule.Metadata;\n\t\t\tvar tfm = mainModule.DetectTargetFrameworkId();\n\t\t\tvar (identifier, version) = UniversalAssemblyResolver.ParseTargetFramework(tfm);\n\t\t\tforeach (var h in mainMetadata.GetModuleReferences())\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tvar moduleRef = mainMetadata.GetModuleReference(h);\n\t\t\t\t\tvar moduleName = mainMetadata.GetString(moduleRef.Name);\n\t\t\t\t\tforeach (var fileHandle in mainMetadata.AssemblyFiles)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar file = mainMetadata.GetAssemblyFile(fileHandle);\n\t\t\t\t\t\tif (mainMetadata.StringComparer.Equals(file.Name, moduleName) && file.ContainsMetadata)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddToQueue(false, mainModule, moduleName);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t}\n\t\t\t}\n\t\t\tforeach (var refs in mainModule.AssemblyReferences)\n\t\t\t{\n\t\t\t\tAddToQueue(true, mainModule, refs);\n\t\t\t}\n\t\t\twhile (assemblyReferenceQueue.Count > 0)\n\t\t\t{\n\t\t\t\tvar asmRef = assemblyReferenceQueue.Dequeue();\n\t\t\t\tvar asm = await asmRef.ResolveTask.ConfigureAwait(false);\n\t\t\t\tif (asm != null)\n\t\t\t\t{\n\t\t\t\t\treferencedAssemblies.Add(asm);\n\t\t\t\t\tvar metadata = asm.Metadata;\n\t\t\t\t\tforeach (var h in metadata.ExportedTypes)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar exportedType = metadata.GetExportedType(h);\n\t\t\t\t\t\tswitch (exportedType.Implementation.Kind)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase SRM.HandleKind.AssemblyReference:\n\t\t\t\t\t\t\t\tAddToQueue(true, asm, new AssemblyReference(asm, (SRM.AssemblyReferenceHandle)exportedType.Implementation));\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase SRM.HandleKind.AssemblyFile:\n\t\t\t\t\t\t\t\tvar file = metadata.GetAssemblyFile((SRM.AssemblyFileHandle)exportedType.Implementation);\n\t\t\t\t\t\t\t\tAddToQueue(false, asm, metadata.GetString(file.Name));\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (assemblyReferenceQueue.Count == 0)\n\t\t\t\t{\n\t\t\t\t\t// For .NET Core and .NET 5 and newer, we need to pull in implicit references which are not included in the metadata,\n\t\t\t\t\t// as they contain compile-time-only types, such as System.Runtime.InteropServices.dll (for DllImport, MarshalAs, etc.)\n\t\t\t\t\tswitch (identifier)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase TargetFrameworkIdentifier.NETCoreApp:\n\t\t\t\t\t\tcase TargetFrameworkIdentifier.NETStandard:\n\t\t\t\t\t\tcase TargetFrameworkIdentifier.NET:\n\t\t\t\t\t\t\tforeach (var item in implicitReferences)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvar existing = referencedAssemblies.FirstOrDefault(asm => asm.Name == item);\n\t\t\t\t\t\t\t\tif (existing == null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAddToQueue(true, mainModule, AssemblyNameReference.Parse(item + \", Version=\" + version.ToString(3) + \".0, Culture=neutral\"));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!(identifier == TargetFrameworkIdentifier.NET && version >= new Version(7, 0)))\n\t\t\t{\n\t\t\t\ttypeSystemOptions &= ~TypeSystemOptions.NativeIntegersWithoutAttribute;\n\t\t\t}\n\t\t\tvar mainModuleWithOptions = mainModule.WithOptions(typeSystemOptions);\n\t\t\t// create IModuleReferences for all references\n\t\t\tvar referencedAssembliesWithOptions = new List<IModuleReference>(referencedAssemblies.Count);\n\t\t\tDictionary<string, (Version version, int insertionIndex)> referenceAssemblyVersionMap = new();\n\t\t\tforeach (var file in referencedAssemblies)\n\t\t\t{\n\t\t\t\t// if the file is an assembly, we need to make sure to deduplicate all assemblies,\n\t\t\t\t// with the same name, but different version. We keep the highest version number.\n\t\t\t\tif (file.IsAssembly)\n\t\t\t\t{\n\t\t\t\t\tvar newFileVersion = file.Metadata.GetAssemblyDefinition().Version;\n\t\t\t\t\tif (referenceAssemblyVersionMap.TryGetValue(file.Name, out var info))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (newFileVersion >= info.version)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treferencedAssembliesWithOptions[info.insertionIndex] = file.WithOptions(typeSystemOptions);\n\t\t\t\t\t\t\treferenceAssemblyVersionMap[file.Name] = (newFileVersion, info.insertionIndex);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treferenceAssemblyVersionMap[file.Name] = (file.Metadata.GetAssemblyDefinition().Version, referencedAssembliesWithOptions.Count);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treferencedAssembliesWithOptions.Add(file.WithOptions(typeSystemOptions));\n\t\t\t}\n\t\t\t// Primitive types are necessary to avoid assertions in ILReader.\n\t\t\t// Other known types are necessary in order for transforms to work (e.g. Task<T> for async transform).\n\t\t\t// Figure out which known types are missing from our type system so far:\n\t\t\tvar missingKnownTypes = KnownTypeReference.AllKnownTypes.Where(IsMissing).ToList();\n\t\t\tif (missingKnownTypes.Count > 0)\n\t\t\t{\n\t\t\t\tInit(mainModuleWithOptions, referencedAssembliesWithOptions.Concat(new[] { MinimalCorlib.CreateWithTypes(missingKnownTypes) }));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tInit(mainModuleWithOptions, referencedAssembliesWithOptions);\n\t\t\t}\n\t\t\tthis.mainModule = (MetadataModule)base.MainModule;\n\n\t\t\tvoid AddToQueue(bool isAssembly, MetadataFile mainModule, object reference)\n\t\t\t{\n\t\t\t\tif (assemblyReferencesInQueue.Add((isAssembly, mainModule, reference)))\n\t\t\t\t{\n\t\t\t\t\t// Immediately start loading the referenced module as we add the entry to the queue.\n\t\t\t\t\t// This allows loading multiple modules in parallel.\n\t\t\t\t\tTask<MetadataFile> asm;\n\t\t\t\t\tif (isAssembly)\n\t\t\t\t\t{\n\t\t\t\t\t\tasm = assemblyResolver.ResolveAsync((IAssemblyReference)reference);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tasm = assemblyResolver.ResolveModuleAsync(mainModule, (string)reference);\n\t\t\t\t\t}\n\t\t\t\t\tassemblyReferenceQueue.Enqueue((isAssembly, mainModule, reference, asm));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool IsMissing(KnownTypeReference knownType)\n\t\t\t{\n\t\t\t\tvar name = knownType.TypeName;\n\t\t\t\tif (!mainModule.GetTypeDefinition(name).IsNil)\n\t\t\t\t\treturn false;\n\t\t\t\tforeach (var file in referencedAssemblies)\n\t\t\t\t{\n\t\t\t\t\tif (!file.GetTypeDefinition(name).IsNil)\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tpublic new MetadataModule MainModule => mainModule;\n\n\t\tpublic override TypeSystemOptions TypeSystemOptions => typeSystemOptions;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/ExtensionInfo.cs",
    "content": "// Copyright (c) 2025 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\tpublic class ExtensionInfo\n\t{\n\t\treadonly Dictionary<IMember, ExtensionMemberInfo> extensionMemberMap;\n\t\treadonly Dictionary<IMember, ExtensionMemberInfo> implementationMemberMap;\n\n\t\tpublic ExtensionInfo(MetadataModule module, ITypeDefinition extensionContainer)\n\t\t{\n\t\t\tthis.extensionMemberMap = new();\n\t\t\tthis.implementationMemberMap = new();\n\n\t\t\tvar metadata = module.MetadataFile.Metadata;\n\n\t\t\tforeach (var nestedType in extensionContainer.NestedTypes)\n\t\t\t{\n\t\t\t\tif (TryEncodingV1(nestedType))\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tTryEncodingV2(nestedType);\n\t\t\t}\n\n\t\t\tbool TryEncodingV1(ITypeDefinition extGroup)\n\t\t\t{\n\t\t\t\tif (!(extGroup is { Kind: TypeKind.Class, IsSealed: true }\n\t\t\t\t\t&& extGroup.Name.StartsWith(\"<>E__\", System.StringComparison.Ordinal)))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tTypeDefinition td = metadata.GetTypeDefinition((TypeDefinitionHandle)extGroup.MetadataToken);\n\t\t\t\tIMethod? marker = null;\n\t\t\t\tbool hasMultipleMarkers = false;\n\t\t\t\tList<IMethod> extensionMethods = [];\n\t\t\t\tITypeParameter[] extensionGroupTypeParameters = extGroup.TypeParameters.ToArray();\n\n\t\t\t\t// For easier access to accessors we use SRM\n\t\t\t\tforeach (var h in td.GetMethods())\n\t\t\t\t{\n\t\t\t\t\tvar method = module.GetDefinition(h);\n\n\t\t\t\t\tif (method.SymbolKind is SymbolKind.Constructor)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tif (method is { Name: \"<Extension>$\", IsStatic: true, Parameters.Count: 1 })\n\t\t\t\t\t{\n\t\t\t\t\t\tif (marker == null)\n\t\t\t\t\t\t\tmarker = method;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\thasMultipleMarkers = true;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\textensionMethods.Add(method);\n\t\t\t\t}\n\n\t\t\t\tif (marker == null || hasMultipleMarkers)\n\t\t\t\t\treturn false;\n\n\t\t\t\tCollectImplementationMethods(extGroup, marker, extensionMethods, extensionGroupTypeParameters);\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tbool TryEncodingV2(ITypeDefinition extensionGroupsContainer)\n\t\t\t{\n\t\t\t\t// there exists one nested type per extension target type\n\t\t\t\tif (!(extensionGroupsContainer is { Kind: TypeKind.Class, IsSealed: true }\n\t\t\t\t\t&& extensionGroupsContainer.Name.StartsWith(\"<G>$\", StringComparison.Ordinal)))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// if there are multiple extension-blocks with the same target type,\n\t\t\t\t// but different names for the extension parameter,\n\t\t\t\t// there is a separate markerType, so there are multiple marker types per\n\t\t\t\t// target type\n\t\t\t\tforeach (var markerType in extensionGroupsContainer.NestedTypes)\n\t\t\t\t{\n\t\t\t\t\tif (!(markerType.Name.StartsWith(\"<M>$\", StringComparison.Ordinal) && markerType.IsStatic))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tvar marker = markerType.Methods.SingleOrDefault(m => m.Name == \"<Extension>$\" && m.IsStatic && m.Parameters.Count == 1);\n\t\t\t\t\tif (marker == null)\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\tTypeDefinition td = metadata.GetTypeDefinition((TypeDefinitionHandle)extensionGroupsContainer.MetadataToken);\n\t\t\t\t\tList<IMethod> extensionMethods = [];\n\t\t\t\t\tITypeParameter[] extensionGroupTypeParameters = new ITypeParameter[extensionGroupsContainer.TypeParameterCount];\n\n\t\t\t\t\t// For easier access to accessors we use SRM\n\t\t\t\t\tforeach (var h in td.GetMethods())\n\t\t\t\t\t{\n\t\t\t\t\t\tvar method = module.GetDefinition(h);\n\n\t\t\t\t\t\tif (method.SymbolKind is SymbolKind.Constructor)\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\tvar attribute = method.GetAttribute(KnownAttribute.ExtensionMarker);\n\t\t\t\t\t\tif (attribute == null)\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\tif (attribute.FixedArguments[0].Value?.ToString() != markerType.Name)\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\textensionMethods.Add(method);\n\t\t\t\t\t}\n\n\t\t\t\t\tCollectImplementationMethods(extensionGroupsContainer, marker, extensionMethods, extensionGroupTypeParameters);\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tvoid CollectImplementationMethods(ITypeDefinition extGroup, IMethod marker, List<IMethod> extensionMethods, ITypeParameter[] extensionGroupTypeParameters)\n\t\t\t{\n\t\t\t\tList<(IMethod extension, IMethod implementation)> implementations = [];\n\n\t\t\t\tstring[] typeParameterNames = new string[extGroup.TypeParameterCount];\n\n\t\t\t\tforeach (var extension in extensionMethods)\n\t\t\t\t{\n\t\t\t\t\tint expectedTypeParameterCount = extension.TypeParameters.Count + extGroup.TypeParameterCount;\n\t\t\t\t\tbool hasInstance = !extension.IsStatic;\n\t\t\t\t\tint parameterOffset = hasInstance ? 1 : 0;\n\t\t\t\t\tint expectedParameterCount = extension.Parameters.Count + parameterOffset;\n\t\t\t\t\tTypeParameterSubstitution subst = new TypeParameterSubstitution([], [.. extGroup.TypeArguments, .. extension.TypeArguments]);\n\n\t\t\t\t\tbool IsMatchingImplementation(IMethod impl)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!impl.IsStatic)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (extension.Name != impl.Name)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (expectedTypeParameterCount != impl.TypeParameters.Count)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (expectedParameterCount != impl.Parameters.Count)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tif (hasInstance)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tIType ti = impl.Parameters[0].Type.AcceptVisitor(subst);\n\t\t\t\t\t\t\tIType tm = marker.Parameters.Single().Type;\n\t\t\t\t\t\t\tif (!NormalizeTypeVisitor.TypeErasure.EquivalentTypes(ti, tm))\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (int i = 0; i < extension.Parameters.Count; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tIType ti = impl.Parameters[i + parameterOffset].Type.AcceptVisitor(subst);\n\t\t\t\t\t\t\tIType tm = extension.Parameters[i].Type;\n\t\t\t\t\t\t\tif (!NormalizeTypeVisitor.TypeErasure.EquivalentTypes(ti, tm))\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn NormalizeTypeVisitor.TypeErasure.EquivalentTypes(\n\t\t\t\t\t\t\timpl.ReturnType.AcceptVisitor(subst),\n\t\t\t\t\t\t\textension.ReturnType\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tIMethod? foundImpl = null;\n\n\t\t\t\t\tforeach (var impl in extensionContainer.Methods)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!IsMatchingImplementation(impl))\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tDebug.Assert(foundImpl == null, \"Multiple matching implementations found\");\n\t\t\t\t\t\tfoundImpl = impl;\n\t\t\t\t\t}\n\n\t\t\t\t\tDebug.Assert(foundImpl != null, \"No matching implementation found\");\n\n\t\t\t\t\timplementations.Add((extension, foundImpl));\n\t\t\t\t}\n\n\t\t\t\tforeach (var (extension, implementation) in implementations)\n\t\t\t\t{\n\t\t\t\t\tfor (int i = 0; i < extensionGroupTypeParameters.Length; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (typeParameterNames[i] == null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttypeParameterNames[i] = implementation.TypeParameters[i].Name;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (typeParameterNames[i] != implementation.TypeParameters[i].Name)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// TODO: Handle name conflicts properly\n\t\t\t\t\t\t\ttypeParameterNames[i] = $\"T{i + 1}\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor (int i = 0; i < extensionGroupTypeParameters.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tvar originalTypeParameter = extGroup.TypeParameters[i];\n\t\t\t\t\tif (extensionGroupTypeParameters[i] == null)\n\t\t\t\t\t{\n\t\t\t\t\t\textensionGroupTypeParameters[i] = new DefaultTypeParameter(\n\t\t\t\t\t\t\textGroup, i, typeParameterNames[i],\n\t\t\t\t\t\t\tVarianceModifier.Invariant,\n\t\t\t\t\t\t\tattributes: originalTypeParameter.GetAttributes().ToArray(),\n\t\t\t\t\t\t\toriginalTypeParameter.HasValueTypeConstraint,\n\t\t\t\t\t\t\toriginalTypeParameter.HasReferenceTypeConstraint,\n\t\t\t\t\t\t\toriginalTypeParameter.HasDefaultConstructorConstraint,\n\t\t\t\t\t\t\toriginalTypeParameter.TypeConstraints.Select(c => c.Type).ToArray(),\n\t\t\t\t\t\t\toriginalTypeParameter.NullabilityConstraint\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tforeach (var (extension, implementation) in implementations)\n\t\t\t\t{\n\t\t\t\t\tvar info = new ExtensionMemberInfo(marker, extension, implementation, extensionGroupTypeParameters);\n\t\t\t\t\tthis.extensionMemberMap[extension] = info;\n\t\t\t\t\tthis.implementationMemberMap[implementation] = info;\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\n\t\tpublic ExtensionMemberInfo? InfoOfExtensionMember(IMethod method)\n\t\t{\n\t\t\treturn this.extensionMemberMap.TryGetValue(method, out var value) ? value : null;\n\t\t}\n\n\t\tpublic ExtensionMemberInfo? InfoOfImplementationMember(IMethod method)\n\t\t{\n\t\t\treturn this.implementationMemberMap.TryGetValue(method, out var value) ? value : null;\n\t\t}\n\n\t\tpublic IEnumerable<IGrouping<(IMethod Marker, ITypeParameter[] TypeParameters), ExtensionMemberInfo>> GetGroups()\n\t\t{\n\t\t\treturn this.extensionMemberMap.Values.GroupBy(x => (x.ExtensionMarkerMethod, x.ExtensionGroupingTypeParameters));\n\t\t}\n\n\t\tpublic bool IsExtensionGroupingType(ITypeDefinition type)\n\t\t{\n\t\t\treturn this.extensionMemberMap.Values.Any(x => x.ExtensionGroupingType.Equals(type));\n\t\t}\n\t}\n\n\tpublic readonly struct ExtensionMemberInfo(IMethod marker, IMethod extension, IMethod implementation, ITypeParameter[] extensionGroupingTypeParameters)\n\t{\n\t\t/// <summary>\n\t\t/// Metadata-only method called '&lt;Extension&gt;$'. Has the C# signature for the extension declaration.\n\t\t/// \n\t\t/// <code>extension(ReceiverType name) {} -> void &lt;Extension&gt;$(ReceiverType name) {}</code>\n\t\t/// </summary>\n\t\tpublic readonly IMethod ExtensionMarkerMethod = marker;\n\t\t/// <summary>\n\t\t/// Metadata-only method with a signature as declared in C# within the extension declaration.\n\t\t/// This could also be an accessor of an extension property.\n\t\t/// </summary>\n\t\tpublic readonly IMethod ExtensionMember = extension;\n\t\t/// <summary>\n\t\t/// The actual implementation method in the outer class. The signature is a concatenation\n\t\t/// of the extension marker and the extension member's signatures.\n\t\t/// </summary>\n\t\tpublic readonly IMethod ImplementationMethod = implementation;\n\n\t\t/// <summary>\n\t\t/// This is the enclosing static class.\n\t\t/// </summary>\n\t\tpublic ITypeDefinition ExtensionContainer => ImplementationMethod.DeclaringTypeDefinition!;\n\n\t\t/// <summary>\n\t\t/// This is the compiler-generated class containing the extension members. Has type parameters\n\t\t/// from the extension declaration with minimal constraints.\n\t\t/// </summary>\n\t\tpublic ITypeDefinition ExtensionGroupingType => ExtensionMember.DeclaringTypeDefinition!;\n\n\t\t/// <summary>\n\t\t/// This is the array of type parameters for the extension declaration.\n\t\t/// </summary>\n\t\tpublic ITypeParameter[] ExtensionGroupingTypeParameters => extensionGroupingTypeParameters;\n\n\t\t/// <summary>\n\t\t/// This class holds the type parameters for the extension declaration with full fidelity of C# constraints.\n\t\t/// </summary>\n\t\tpublic ITypeDefinition ExtensionMarkerType => ExtensionMarkerMethod.DeclaringTypeDefinition!;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/FullTypeName.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Holds the full name of a type definition.\n\t/// A full type name uniquely identifies a type definition within a single assembly.\n\t/// </summary>\n\t/// <remarks>\n\t/// A full type name can only represent type definitions, not arbitrary types.\n\t/// It does not include any type arguments, and can not refer to array or pointer types.\n\t/// \n\t/// A full type name represented as reflection name has the syntax:\n\t/// <c>NamespaceName '.' TopLevelTypeName ['`'#] { '+' NestedTypeName ['`'#] }</c>\n\t/// </remarks>\n\t[Serializable]\n\tpublic readonly struct FullTypeName : IEquatable<FullTypeName>\n\t{\n\t\t[Serializable]\n\t\treadonly struct NestedTypeName\n\t\t{\n\t\t\tpublic readonly string Name;\n\t\t\tpublic readonly int AdditionalTypeParameterCount;\n\n\t\t\tpublic NestedTypeName(string name, int additionalTypeParameterCount)\n\t\t\t{\n\t\t\t\tif (name == null)\n\t\t\t\t\tthrow new ArgumentNullException(nameof(name));\n\t\t\t\tthis.Name = name;\n\t\t\t\tthis.AdditionalTypeParameterCount = additionalTypeParameterCount;\n\t\t\t}\n\t\t}\n\n\t\treadonly TopLevelTypeName topLevelType;\n\t\treadonly NestedTypeName[] nestedTypes;\n\n\t\tFullTypeName(TopLevelTypeName topLevelTypeName, NestedTypeName[] nestedTypes)\n\t\t{\n\t\t\tthis.topLevelType = topLevelTypeName;\n\t\t\tthis.nestedTypes = nestedTypes;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Constructs a FullTypeName representing the given top-level type.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// FullTypeName has an implicit conversion operator from TopLevelTypeName,\n\t\t/// so you can simply write:\n\t\t/// <c>FullTypeName f = new TopLevelTypeName(...);</c>\n\t\t/// </remarks>\n\t\tpublic FullTypeName(TopLevelTypeName topLevelTypeName)\n\t\t{\n\t\t\tthis.topLevelType = topLevelTypeName;\n\t\t\tthis.nestedTypes = null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Constructs a FullTypeName by parsing the given reflection name.\n\t\t/// Note that FullTypeName can only represent type definition names. If the reflection name\n\t\t/// might refer to a parameterized type or array etc., use\n\t\t/// <see cref=\"ReflectionHelper.ParseReflectionName(string, ITypeResolveContext)\"/> instead.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Expected syntax: <c>NamespaceName '.' TopLevelTypeName ['`'#] { '+' NestedTypeName ['`'#] }</c>\n\t\t/// where # are type parameter counts\n\t\t/// </remarks>\n\t\tpublic FullTypeName(string reflectionName)\n\t\t{\n\t\t\tint pos = reflectionName.IndexOf('+');\n\t\t\tif (pos < 0)\n\t\t\t{\n\t\t\t\t// top-level type\n\t\t\t\tthis.topLevelType = new TopLevelTypeName(reflectionName);\n\t\t\t\tthis.nestedTypes = null;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// nested type\n\t\t\t\tstring[] parts = reflectionName.Split('+');\n\t\t\t\tthis.topLevelType = new TopLevelTypeName(parts[0]);\n\t\t\t\tthis.nestedTypes = new NestedTypeName[parts.Length - 1];\n\t\t\t\tfor (int i = 0; i < nestedTypes.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tint tpc;\n\t\t\t\t\tstring name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(parts[i + 1], out tpc);\n\t\t\t\t\tnestedTypes[i] = new NestedTypeName(name, tpc);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the top-level type name.\n\t\t/// </summary>\n\t\tpublic TopLevelTypeName TopLevelTypeName {\n\t\t\tget { return topLevelType; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this is a nested type.\n\t\t/// </summary>\n\t\tpublic bool IsNested {\n\t\t\tget {\n\t\t\t\treturn nestedTypes != null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the nesting level.\n\t\t/// </summary>\n\t\tpublic int NestingLevel {\n\t\t\tget {\n\t\t\t\treturn nestedTypes != null ? nestedTypes.Length : 0;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the name of the type.\n\t\t/// For nested types, this is the name of the innermost type.\n\t\t/// </summary>\n\t\tpublic string Name {\n\t\t\tget {\n\t\t\t\tif (nestedTypes != null)\n\t\t\t\t\treturn nestedTypes[nestedTypes.Length - 1].Name;\n\t\t\t\telse\n\t\t\t\t\treturn topLevelType.Name;\n\t\t\t}\n\t\t}\n\n\t\tpublic string ReflectionName {\n\t\t\tget {\n\t\t\t\tif (nestedTypes == null)\n\t\t\t\t\treturn topLevelType.ReflectionName;\n\t\t\t\tStringBuilder b = new StringBuilder(topLevelType.ReflectionName);\n\t\t\t\tforeach (NestedTypeName nt in nestedTypes)\n\t\t\t\t{\n\t\t\t\t\tb.Append('+');\n\t\t\t\t\tb.Append(nt.Name);\n\t\t\t\t\tif (nt.AdditionalTypeParameterCount > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tb.Append('`');\n\t\t\t\t\t\tb.Append(nt.AdditionalTypeParameterCount);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn b.ToString();\n\t\t\t}\n\t\t}\n\n\t\tpublic string FullName {\n\t\t\tget {\n\t\t\t\tif (nestedTypes == null)\n\t\t\t\t\treturn topLevelType.Namespace + \".\" + topLevelType.Name;\n\t\t\t\tStringBuilder b = new StringBuilder(topLevelType.Namespace);\n\t\t\t\tb.Append('.');\n\t\t\t\tb.Append(topLevelType.Name);\n\t\t\t\tforeach (NestedTypeName nt in nestedTypes)\n\t\t\t\t{\n\t\t\t\t\tb.Append('.');\n\t\t\t\t\tb.Append(nt.Name);\n\t\t\t\t}\n\t\t\t\treturn b.ToString();\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the total type parameter count.\n\t\t/// </summary>\n\t\tpublic int TypeParameterCount {\n\t\t\tget {\n\t\t\t\tint tpc = topLevelType.TypeParameterCount;\n\t\t\t\tif (nestedTypes != null)\n\t\t\t\t{\n\t\t\t\t\tforeach (var nt in nestedTypes)\n\t\t\t\t\t{\n\t\t\t\t\t\ttpc += nt.AdditionalTypeParameterCount;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn tpc;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the name of the nested type at the given level.\n\t\t/// </summary>\n\t\tpublic string GetNestedTypeName(int nestingLevel)\n\t\t{\n\t\t\tif (nestedTypes == null)\n\t\t\t\tthrow new InvalidOperationException();\n\t\t\treturn nestedTypes[nestingLevel].Name;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the number of additional type parameters of the nested type at the given level.\n\t\t/// </summary>\n\t\tpublic int GetNestedTypeAdditionalTypeParameterCount(int nestingLevel)\n\t\t{\n\t\t\tif (nestedTypes == null)\n\t\t\t\tthrow new InvalidOperationException();\n\t\t\treturn nestedTypes[nestingLevel].AdditionalTypeParameterCount;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the declaring type name.\n\t\t/// </summary>\n\t\t/// <exception cref=\"InvalidOperationException\">This is a top-level type name.</exception>\n\t\t/// <example><c>new FullTypeName(\"NS.A+B+C\").GetDeclaringType()</c> will return <c>new FullTypeName(\"NS.A+B\")</c></example>\n\t\tpublic FullTypeName GetDeclaringType()\n\t\t{\n\t\t\tif (nestedTypes == null)\n\t\t\t\tthrow new InvalidOperationException();\n\t\t\tif (nestedTypes.Length == 1)\n\t\t\t\treturn topLevelType;\n\t\t\tNestedTypeName[] outerNestedTypeNames = new NestedTypeName[nestedTypes.Length - 1];\n\t\t\tArray.Copy(nestedTypes, 0, outerNestedTypeNames, 0, outerNestedTypeNames.Length);\n\t\t\treturn new FullTypeName(topLevelType, outerNestedTypeNames);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a nested type name.\n\t\t/// </summary>\n\t\t/// <example><c>new FullTypeName(\"NS.A+B\").NestedType(\"C\", 1)</c> will return <c>new FullTypeName(\"NS.A+B+C`1\")</c></example>\n\t\tpublic FullTypeName NestedType(string name, int additionalTypeParameterCount)\n\t\t{\n\t\t\tif (name == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(name));\n\t\t\tvar newNestedType = new NestedTypeName(name, additionalTypeParameterCount);\n\t\t\tif (nestedTypes == null)\n\t\t\t\treturn new FullTypeName(topLevelType, new[] { newNestedType });\n\t\t\tNestedTypeName[] newNestedTypeNames = new NestedTypeName[nestedTypes.Length + 1];\n\t\t\tnestedTypes.CopyTo(newNestedTypeNames, 0);\n\t\t\tnewNestedTypeNames[newNestedTypeNames.Length - 1] = newNestedType;\n\t\t\treturn new FullTypeName(topLevelType, newNestedTypeNames);\n\t\t}\n\n\t\tpublic static implicit operator FullTypeName(TopLevelTypeName topLevelTypeName)\n\t\t{\n\t\t\treturn new FullTypeName(topLevelTypeName);\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn this.ReflectionName;\n\t\t}\n\n\t\t#region Equals and GetHashCode implementation\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\treturn obj is FullTypeName && Equals((FullTypeName)obj);\n\t\t}\n\n\t\tpublic bool Equals(FullTypeName other)\n\t\t{\n\t\t\treturn FullTypeNameComparer.Ordinal.Equals(this, other);\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn FullTypeNameComparer.Ordinal.GetHashCode(this);\n\t\t}\n\n\t\tpublic static bool operator ==(FullTypeName left, FullTypeName right)\n\t\t{\n\t\t\treturn left.Equals(right);\n\t\t}\n\n\t\tpublic static bool operator !=(FullTypeName left, FullTypeName right)\n\t\t{\n\t\t\treturn !left.Equals(right);\n\t\t}\n\t\t#endregion\n\t}\n\n\t[Serializable]\n\tpublic sealed class FullTypeNameComparer : IEqualityComparer<FullTypeName>\n\t{\n\t\tpublic static readonly FullTypeNameComparer Ordinal = new FullTypeNameComparer(StringComparer.Ordinal);\n\t\tpublic static readonly FullTypeNameComparer OrdinalIgnoreCase = new FullTypeNameComparer(StringComparer.OrdinalIgnoreCase);\n\n\t\tpublic readonly StringComparer NameComparer;\n\n\t\tpublic FullTypeNameComparer(StringComparer nameComparer)\n\t\t{\n\t\t\tthis.NameComparer = nameComparer;\n\t\t}\n\n\t\tpublic bool Equals(FullTypeName x, FullTypeName y)\n\t\t{\n\t\t\tif (x.NestingLevel != y.NestingLevel)\n\t\t\t\treturn false;\n\t\t\tTopLevelTypeName topX = x.TopLevelTypeName;\n\t\t\tTopLevelTypeName topY = y.TopLevelTypeName;\n\t\t\tif (topX.TypeParameterCount == topY.TypeParameterCount\n\t\t\t\t&& NameComparer.Equals(topX.Name, topY.Name)\n\t\t\t\t&& NameComparer.Equals(topX.Namespace, topY.Namespace))\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < x.NestingLevel; i++)\n\t\t\t\t{\n\t\t\t\t\tif (x.GetNestedTypeAdditionalTypeParameterCount(i) != y.GetNestedTypeAdditionalTypeParameterCount(i))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (!NameComparer.Equals(x.GetNestedTypeName(i), y.GetNestedTypeName(i)))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic int GetHashCode(FullTypeName obj)\n\t\t{\n\t\t\tTopLevelTypeName top = obj.TopLevelTypeName;\n\t\t\tint hash = NameComparer.GetHashCode(top.Name) ^ NameComparer.GetHashCode(top.Namespace) ^ top.TypeParameterCount;\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < obj.NestingLevel; i++)\n\t\t\t\t{\n\t\t\t\t\thash *= 31;\n\t\t\t\t\thash += NameComparer.GetHashCode(obj.Name) ^ obj.TypeParameterCount;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn hash;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/FunctionPointerType.cs",
    "content": "// Copyright (c) 2020 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\tpublic class FunctionPointerType : AbstractType\n\t{\n\t\tpublic static FunctionPointerType FromSignature(MethodSignature<IType> signature, MetadataModule module)\n\t\t{\n\t\t\tIType returnType = signature.ReturnType;\n\t\t\tbool returnIsRefReadOnly = false;\n\t\t\tSignatureCallingConvention callingConvention = signature.Header.CallingConvention;\n\t\t\tvar customCallConvs = ImmutableArray.CreateBuilder<IType>();\n\t\t\twhile (returnType is ModifiedType modReturn)\n\t\t\t{\n\t\t\t\tif (modReturn.Modifier.IsKnownType(KnownAttribute.In))\n\t\t\t\t{\n\t\t\t\t\treturnType = modReturn.ElementType;\n\t\t\t\t\treturnIsRefReadOnly = true;\n\t\t\t\t}\n\t\t\t\telse if (modReturn.Modifier.Name.StartsWith(\"CallConv\", StringComparison.Ordinal)\n\t\t\t\t\t&& modReturn.Modifier.Namespace == \"System.Runtime.CompilerServices\")\n\t\t\t\t{\n\t\t\t\t\treturnType = modReturn.ElementType;\n\t\t\t\t\tif (callingConvention == SignatureCallingConvention.Unmanaged)\n\t\t\t\t\t{\n\t\t\t\t\t\tswitch (modReturn.Modifier.Name)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase \"CallConvCdecl\":\n\t\t\t\t\t\t\t\tcallingConvention = SignatureCallingConvention.CDecl;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase \"CallConvFastcall\":\n\t\t\t\t\t\t\t\tcallingConvention = SignatureCallingConvention.FastCall;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase \"CallConvStdcall\":\n\t\t\t\t\t\t\t\tcallingConvention = SignatureCallingConvention.StdCall;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase \"CallConvThiscall\":\n\t\t\t\t\t\t\t\tcallingConvention = SignatureCallingConvention.ThisCall;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tcustomCallConvs.Add(modReturn.Modifier);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tcustomCallConvs.Add(modReturn.Modifier);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar parameterTypes = ImmutableArray.CreateBuilder<IType>(signature.ParameterTypes.Length);\n\t\t\tvar parameterReferenceKinds = ImmutableArray.CreateBuilder<ReferenceKind>(signature.ParameterTypes.Length);\n\t\t\tforeach (var p in signature.ParameterTypes)\n\t\t\t{\n\t\t\t\tIType paramType = p;\n\t\t\t\tReferenceKind kind = ReferenceKind.None;\n\t\t\t\tif (p is ModifiedType mod)\n\t\t\t\t{\n\t\t\t\t\tif (mod.Modifier.IsKnownType(KnownAttribute.In))\n\t\t\t\t\t{\n\t\t\t\t\t\tkind = ReferenceKind.In;\n\t\t\t\t\t\tparamType = mod.ElementType;\n\t\t\t\t\t}\n\t\t\t\t\telse if (mod.Modifier.IsKnownType(KnownAttribute.Out))\n\t\t\t\t\t{\n\t\t\t\t\t\tkind = ReferenceKind.Out;\n\t\t\t\t\t\tparamType = mod.ElementType;\n\t\t\t\t\t}\n\t\t\t\t\telse if (mod.Modifier.IsKnownType(KnownAttribute.RequiresLocation))\n\t\t\t\t\t{\n\t\t\t\t\t\tkind = ReferenceKind.RefReadOnly;\n\t\t\t\t\t\tparamType = mod.ElementType;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (paramType.Kind == TypeKind.ByReference)\n\t\t\t\t{\n\t\t\t\t\tif (kind == ReferenceKind.None)\n\t\t\t\t\t\tkind = ReferenceKind.Ref;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tkind = ReferenceKind.None;\n\t\t\t\t}\n\t\t\t\tparameterTypes.Add(paramType);\n\t\t\t\tparameterReferenceKinds.Add(kind);\n\t\t\t}\n\t\t\treturn new FunctionPointerType(\n\t\t\t\tmodule, callingConvention, customCallConvs.ToImmutable(),\n\t\t\t\treturnType, returnIsRefReadOnly,\n\t\t\t\tparameterTypes.MoveToImmutable(), parameterReferenceKinds.MoveToImmutable());\n\t\t}\n\n\t\tprivate readonly MetadataModule module;\n\t\tpublic readonly SignatureCallingConvention CallingConvention;\n\t\tpublic readonly ImmutableArray<IType> CustomCallingConventions;\n\t\tpublic readonly IType ReturnType;\n\t\tpublic readonly bool ReturnIsRefReadOnly;\n\t\tpublic readonly ImmutableArray<IType> ParameterTypes;\n\t\tpublic readonly ImmutableArray<ReferenceKind> ParameterReferenceKinds;\n\n\t\tpublic FunctionPointerType(MetadataModule module,\n\t\t\tSignatureCallingConvention callingConvention, ImmutableArray<IType> customCallingConventions,\n\t\t\tIType returnType, bool returnIsRefReadOnly,\n\t\t\tImmutableArray<IType> parameterTypes, ImmutableArray<ReferenceKind> parameterReferenceKinds)\n\t\t{\n\t\t\tthis.module = module;\n\t\t\tthis.CallingConvention = callingConvention;\n\t\t\tthis.CustomCallingConventions = customCallingConventions;\n\t\t\tthis.ReturnType = returnType;\n\t\t\tthis.ReturnIsRefReadOnly = returnIsRefReadOnly;\n\t\t\tthis.ParameterTypes = parameterTypes;\n\t\t\tthis.ParameterReferenceKinds = parameterReferenceKinds;\n\t\t\tDebug.Assert(parameterTypes.Length == parameterReferenceKinds.Length);\n\t\t}\n\n\t\tpublic override string Name => \"delegate*\";\n\n\t\tpublic override bool? IsReferenceType => false;\n\n\t\tpublic override TypeKind Kind => ((module.TypeSystemOptions & TypeSystemOptions.FunctionPointers) != 0) ? TypeKind.FunctionPointer : TypeKind.Struct;\n\n\t\tpublic override ITypeDefinition GetDefinition()\n\t\t{\n\t\t\tif ((module.TypeSystemOptions & TypeSystemOptions.FunctionPointers) != 0)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// If FunctionPointers are not enabled in the TS, we still use FunctionPointerType instances;\n\t\t\t\t// but have them act as if they were aliases for UIntPtr.\n\t\t\t\treturn module.Compilation.FindType(KnownTypeCode.UIntPtr).GetDefinition();\n\t\t\t}\n\t\t}\n\n\t\tpublic override ITypeDefinitionOrUnknown GetDefinitionOrUnknown()\n\t\t{\n\t\t\treturn GetDefinition();\n\t\t}\n\n\t\tpublic override IType AcceptVisitor(TypeVisitor visitor)\n\t\t{\n\t\t\treturn visitor.VisitFunctionPointerType(this);\n\t\t}\n\n\t\tpublic override IType VisitChildren(TypeVisitor visitor)\n\t\t{\n\t\t\tIType r = ReturnType.AcceptVisitor(visitor);\n\t\t\t// Keep ta == null as long as no elements changed, allocate the array only if necessary.\n\t\t\tIType[] pt = (r != ReturnType) ? new IType[ParameterTypes.Length] : null;\n\t\t\tfor (int i = 0; i < ParameterTypes.Length; i++)\n\t\t\t{\n\t\t\t\tIType p = ParameterTypes[i].AcceptVisitor(visitor);\n\t\t\t\tif (p == null)\n\t\t\t\t\tthrow new NullReferenceException(\"TypeVisitor.Visit-method returned null\");\n\t\t\t\tif (pt == null && p != ParameterTypes[i])\n\t\t\t\t{\n\t\t\t\t\t// we found a difference, so we need to allocate the array\n\t\t\t\t\tpt = new IType[ParameterTypes.Length];\n\t\t\t\t\tfor (int j = 0; j < i; j++)\n\t\t\t\t\t{\n\t\t\t\t\t\tpt[j] = ParameterTypes[j];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (pt != null)\n\t\t\t\t\tpt[i] = p;\n\t\t\t}\n\t\t\tif (pt == null)\n\t\t\t\treturn this;\n\t\t\telse\n\t\t\t\treturn new FunctionPointerType(\n\t\t\t\t\tmodule, CallingConvention, CustomCallingConventions,\n\t\t\t\t\tr, ReturnIsRefReadOnly,\n\t\t\t\t\tpt.ToImmutableArray(),\n\t\t\t\t\tParameterReferenceKinds);\n\t\t}\n\n\t\tpublic override bool Equals(IType other)\n\t\t{\n\t\t\treturn other is FunctionPointerType fpt\n\t\t\t\t&& CallingConvention == fpt.CallingConvention\n\t\t\t\t&& CustomCallingConventions.SequenceEqual(fpt.CustomCallingConventions)\n\t\t\t\t&& ReturnType.Equals(fpt.ReturnType)\n\t\t\t\t&& ReturnIsRefReadOnly == fpt.ReturnIsRefReadOnly\n\t\t\t\t&& ParameterTypes.SequenceEqual(fpt.ParameterTypes)\n\t\t\t\t&& ParameterReferenceKinds.SequenceEqual(fpt.ParameterReferenceKinds);\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\tint hash = ReturnType.GetHashCode() ^ CallingConvention.GetHashCode();\n\t\t\t\tforeach (var (p, k) in ParameterTypes.Zip(ParameterReferenceKinds))\n\t\t\t\t{\n\t\t\t\t\thash ^= p.GetHashCode() ^ k.GetHashCode();\n\t\t\t\t\thash *= 8310859;\n\t\t\t\t}\n\t\t\t\treturn hash;\n\t\t\t}\n\t\t}\n\n\t\tinternal IType WithSignature(IType returnType, ImmutableArray<IType> parameterTypes)\n\t\t{\n\t\t\treturn new FunctionPointerType(this.module,\n\t\t\t\tthis.CallingConvention, this.CustomCallingConventions,\n\t\t\t\treturnType, this.ReturnIsRefReadOnly,\n\t\t\t\tparameterTypes, this.ParameterReferenceKinds);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/GenericContext.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\tpublic readonly struct GenericContext\n\t{\n\t\tpublic readonly IReadOnlyList<ITypeParameter> ClassTypeParameters;\n\t\tpublic readonly IReadOnlyList<ITypeParameter> MethodTypeParameters;\n\n\t\tpublic GenericContext(IReadOnlyList<ITypeParameter> classTypeParameters)\n\t\t{\n\t\t\tthis.ClassTypeParameters = classTypeParameters;\n\t\t\tthis.MethodTypeParameters = null;\n\t\t}\n\n\t\tpublic GenericContext(IReadOnlyList<ITypeParameter> classTypeParameters, IReadOnlyList<ITypeParameter> methodTypeParameters)\n\t\t{\n\t\t\tthis.ClassTypeParameters = classTypeParameters;\n\t\t\tthis.MethodTypeParameters = methodTypeParameters;\n\t\t}\n\n\t\tinternal GenericContext(ITypeResolveContext context)\n\t\t{\n\t\t\tthis.ClassTypeParameters = context.CurrentTypeDefinition?.TypeParameters;\n\t\t\tthis.MethodTypeParameters = (context.CurrentMember as IMethod)?.TypeParameters;\n\t\t}\n\n\t\tinternal GenericContext(IEntity context)\n\t\t{\n\t\t\tif (context is ITypeDefinition td)\n\t\t\t{\n\t\t\t\tthis.ClassTypeParameters = td.TypeParameters;\n\t\t\t\tthis.MethodTypeParameters = null;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.ClassTypeParameters = context.DeclaringTypeDefinition?.TypeParameters;\n\t\t\t\tthis.MethodTypeParameters = (context as IMethod)?.TypeParameters;\n\t\t\t}\n\t\t}\n\n\t\tpublic ITypeParameter GetClassTypeParameter(int index)\n\t\t{\n\t\t\tif (index < ClassTypeParameters?.Count)\n\t\t\t\treturn ClassTypeParameters[index];\n\t\t\telse\n\t\t\t\treturn DummyTypeParameter.GetClassTypeParameter(index);\n\t\t}\n\n\t\tpublic ITypeParameter GetMethodTypeParameter(int index)\n\t\t{\n\t\t\tif (index < MethodTypeParameters?.Count)\n\t\t\t\treturn MethodTypeParameters[index];\n\t\t\telse\n\t\t\t\treturn DummyTypeParameter.GetMethodTypeParameter(index);\n\t\t}\n\n\t\tinternal TypeParameterSubstitution ToSubstitution()\n\t\t{\n\t\t\t// The TS prefers 'null' over empty lists in substitutions, and we need our substitution\n\t\t\t// to compare equal to the ones created by the TS.\n\t\t\treturn new TypeParameterSubstitution(\n\t\t\t\tclassTypeArguments: ClassTypeParameters?.Count > 0 ? ClassTypeParameters : null,\n\t\t\t\tmethodTypeArguments: MethodTypeParameters?.Count > 0 ? MethodTypeParameters : null\n\t\t\t);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/IAssembly.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Interface used to help with construction of the type system.\n\t/// </summary>\n\t/// <remarks>\n\t/// The type system is an immutable cyclic data structure:\n\t/// the compilation (ICompilation) has references to all modules,\n\t/// and each module has a reference back to the compilation.\n\t/// \n\t/// Module references are used to solve this cyclic dependency:\n\t/// The compilation constructor accepts module references,\n\t/// and only the IModuleReference.Resolve() function can observe a\n\t/// partially-constructed compilation; but not any user code.\n\t/// </remarks>\n\tpublic interface IModuleReference\n\t{\n\t\t/// <summary>\n\t\t/// Resolves this metadata module.\n\t\t/// </summary>\n\t\tIModule? Resolve(ITypeResolveContext context);\n\t}\n\n\t/// <summary>\n\t/// Represents a metadata module.\n\t/// </summary>\n\tpublic interface IModule : ISymbol, ICompilationProvider\n\t{\n\t\t/// <summary>\n\t\t/// Gets the underlying metadata file. May return null, if the module was not created from a file.\n\t\t/// </summary>\n\t\tMetadataFile? MetadataFile { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether this assembly is the main assembly of the compilation.\n\t\t/// </summary>\n\t\tbool IsMainModule { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the assembly name (short name).\n\t\t/// </summary>\n\t\tstring AssemblyName { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the assembly version.\n\t\t/// </summary>\n\t\tVersion AssemblyVersion { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the full assembly name (including public key token etc.)\n\t\t/// </summary>\n\t\tstring FullAssemblyName { get; }\n\n\t\t/// <summary>\n\t\t/// Gets all assembly attributes.\n\t\t/// </summary>\n\t\tIEnumerable<IAttribute> GetAssemblyAttributes();\n\n\t\t/// <summary>\n\t\t/// Gets all module attributes.\n\t\t/// </summary>\n\t\tIEnumerable<IAttribute> GetModuleAttributes();\n\n\t\t/// <summary>\n\t\t/// Gets whether the internals of this assembly are visible in the specified assembly.\n\t\t/// </summary>\n\t\tbool InternalsVisibleTo(IModule module);\n\n\t\t/// <summary>\n\t\t/// Gets the root namespace for this module.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This always is the namespace without a name - it's unrelated to the 'root namespace' project setting.\n\t\t/// It contains only subnamespaces and types defined in this module -- use ICompilation.RootNamespace\n\t\t/// to get the combined view of all referenced assemblies.\n\t\t/// </remarks>\n\t\tINamespace RootNamespace { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the type definition for a top-level type.\n\t\t/// </summary>\n\t\t/// <remarks>This method uses ordinal name comparison, not the compilation's name comparer.</remarks>\n\t\tITypeDefinition? GetTypeDefinition(TopLevelTypeName topLevelTypeName);\n\n\t\t/// <summary>\n\t\t/// Gets all non-nested types in the assembly.\n\t\t/// </summary>\n\t\tIEnumerable<ITypeDefinition> TopLevelTypeDefinitions { get; }\n\n\t\t/// <summary>\n\t\t/// Gets all types in the assembly, including nested types.\n\t\t/// </summary>\n\t\tIEnumerable<ITypeDefinition> TypeDefinitions { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/IAttribute.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Collections.Immutable;\nusing System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Represents an attribute.\n\t/// </summary>\n\t[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1711:IdentifiersShouldNotHaveIncorrectSuffix\")]\n\tpublic interface IAttribute\n\t{\n\t\t/// <summary>\n\t\t/// Gets the type of the attribute.\n\t\t/// </summary>\n\t\tIType AttributeType { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the constructor being used.\n\t\t/// This property may return null if no matching constructor was found.\n\t\t/// </summary>\n\t\tIMethod? Constructor { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether there were errors decoding the attribute.\n\t\t/// </summary>\n\t\tbool HasDecodeErrors { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the positional arguments.\n\t\t/// </summary>\n\t\tImmutableArray<CustomAttributeTypedArgument<IType>> FixedArguments { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the named arguments passed to the attribute.\n\t\t/// </summary>\n\t\tImmutableArray<CustomAttributeNamedArgument<IType>> NamedArguments { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/ICodeContext.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\tpublic interface ICodeContext : ITypeResolveContext\n\t{\n\t\t/// <summary>\n\t\t/// Gets all currently visible local variables and lambda parameters.\n\t\t/// Does not include method parameters.\n\t\t/// </summary>\n\t\tIEnumerable<IVariable> LocalVariables { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether the context is within a lambda expression or anonymous method.\n\t\t/// </summary>\n\t\tbool IsWithinLambdaExpression { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/ICompilation.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\tpublic interface ICompilation\n\t{\n\t\t/// <summary>\n\t\t/// Gets the primary module.\n\t\t/// This is the module being (de)compiled; all other modules in the compilation are the other assemblies/modules\n\t\t/// referenced by the main module.\n\t\t/// </summary>\n\t\tIModule MainModule { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the list of all modules in the compilation.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This main module is the first entry in the list.\n\t\t/// </remarks>\n\t\tIReadOnlyList<IModule> Modules { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the referenced modules.\n\t\t/// This list does not include the main module.\n\t\t/// </summary>\n\t\tIReadOnlyList<IModule> ReferencedModules { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the root namespace of this compilation.\n\t\t/// This is a merged version of the root namespaces of all assemblies.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This always is the namespace without a name - it's unrelated to the 'root namespace' project setting.\n\t\t/// </remarks>\n\t\tINamespace RootNamespace { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the root namespace for a given extern alias.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// If <paramref name=\"alias\"/> is <c>null</c> or an empty string, this method\n\t\t/// returns the global root namespace.\n\t\t/// If no alias with the specified name exists, this method returns null.\n\t\t/// </remarks>\n\t\tINamespace? GetNamespaceForExternAlias(string? alias);\n\n\t\tIType FindType(KnownTypeCode typeCode);\n\n\t\t/// <summary>\n\t\t/// Gets the name comparer for the language being compiled.\n\t\t/// This is the string comparer used for the INamespace.GetTypeDefinition method.\n\t\t/// </summary>\n\t\tStringComparer NameComparer { get; }\n\n\t\tCacheManager CacheManager { get; }\n\n\t\tTypeSystemOptions TypeSystemOptions { get; }\n\t}\n\n\tpublic interface ICompilationProvider\n\t{\n\t\t/// <summary>\n\t\t/// Gets the parent compilation.\n\t\t/// This property never returns null.\n\t\t/// </summary>\n\t\tICompilation Compilation { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/IDecompilerTypeSystem.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Main interface for the decompiler type system.\n\t/// \n\t/// The MetadataModule class allows decoding/resolving metadata tokens into type system entities.\n\t/// </summary>\n\tpublic interface IDecompilerTypeSystem : ICompilation\n\t{\n\t\tnew MetadataModule MainModule { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/IEntity.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Represents a resolved entity.\n\t/// </summary>\n\tpublic interface IEntity : ISymbol, ICompilationProvider, INamedElement\n\t{\n\t\t/// <summary>\n\t\t/// Gets the metadata token for this entity.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// The token is only valid within the context of the assembly defining this entity.\n\t\t/// Token may be 0 if this is a generated member.\n\t\t/// Note: specialized members will return the token of the member definition.\n\t\t/// </remarks>\n\t\tSystem.Reflection.Metadata.EntityHandle MetadataToken { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the short name of the entity.\n\t\t/// </summary>\n\t\tnew string Name { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the declaring class.\n\t\t/// For members, this is the class that contains the member.\n\t\t/// For nested classes, this is the outer class. For top-level entities, this property returns null.\n\t\t/// </summary>\n\t\tITypeDefinition? DeclaringTypeDefinition { get; }\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the declaring type (incl. type arguments, if any).\n\t\t/// This property will return null for top-level entities.\n\t\t/// If this is not a specialized member, the value returned is equal to <see cref=\"DeclaringTypeDefinition\"/>.\n\t\t/// </summary>\n\t\tIType? DeclaringType { get; }\n\n\t\t/// <summary>\n\t\t/// The module in which this entity is defined.\n\t\t/// May return null, if the IEntity was not created from a module.\n\t\t/// </summary>\n\t\tIModule? ParentModule { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the attributes on this entity.\n\t\t/// Does not include inherited attributes.\n\t\t/// </summary>\n\t\tIEnumerable<IAttribute> GetAttributes();\n\n\t\tbool HasAttribute(KnownAttribute attribute);\n\n\t\tIAttribute? GetAttribute(KnownAttribute attribute);\n\n\t\t/// <summary>\n\t\t/// Gets the accessibility of this entity.\n\t\t/// </summary>\n\t\tAccessibility Accessibility { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether this entity is static.\n\t\t/// Returns true if either the 'static' or the 'const' modifier is set.\n\t\t/// </summary>\n\t\tbool IsStatic { get; }\n\n\t\t/// <summary>\n\t\t/// Returns whether this entity is abstract.\n\t\t/// </summary>\n\t\t/// <remarks>Static classes also count as abstract classes.</remarks>\n\t\tbool IsAbstract { get; }\n\n\t\t/// <summary>\n\t\t/// Returns whether this entity is sealed.\n\t\t/// </summary>\n\t\t/// <remarks>Static classes also count as sealed classes.</remarks>\n\t\tbool IsSealed { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/IEvent.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Diagnostics.CodeAnalysis;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\tpublic interface IEvent : IMember\n\t{\n\t\t[MemberNotNullWhen(true, nameof(AddAccessor))]\n\t\tbool CanAdd { get; }\n\t\t[MemberNotNullWhen(true, nameof(RemoveAccessor))]\n\t\tbool CanRemove { get; }\n\t\t[MemberNotNullWhen(true, nameof(InvokeAccessor))]\n\t\tbool CanInvoke { get; }\n\n\t\tIMethod? AddAccessor { get; }\n\t\tIMethod? RemoveAccessor { get; }\n\t\tIMethod? InvokeAccessor { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/IField.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Represents a field or constant.\n\t/// </summary>\n\tpublic interface IField : IMember, IVariable\n\t{\n\t\t/// <summary>\n\t\t/// Gets the name of the field.\n\t\t/// </summary>\n\t\tnew string Name { get; } // solve ambiguity between IMember.Name and IVariable.Name\n\n\t\t/// <summary>\n\t\t/// Gets whether this field is readonly.\n\t\t/// </summary>\n\t\tbool IsReadOnly { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether the field type is 'ref readonly'.\n\t\t/// </summary>\n\t\tbool ReturnTypeIsRefReadOnly { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether this field is volatile.\n\t\t/// </summary>\n\t\tbool IsVolatile { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/IFreezable.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\tpublic interface IFreezable\n\t{\n\t\t/// <summary>\n\t\t/// Gets if this instance is frozen. Frozen instances are immutable and thus thread-safe.\n\t\t/// </summary>\n\t\tbool IsFrozen { get; }\n\n\t\t/// <summary>\n\t\t/// Freezes this instance.\n\t\t/// </summary>\n\t\tvoid Freeze();\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/IInterningProvider.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Provider used for interning.\n\t/// </summary>\n\t/// <remarks>\n\t/// A simple IInterningProvider implementation could use 3 dictionaries:\n\t///  1. using value equality comparer (for certain types known to implement value equality, e.g. string and IType)\n\t///  2. using comparer that calls into ISupportsInterning (for types implementing ISupportsInterning)\n\t///  3. list comparer (for InternList method)\n\t/// \n\t/// On the first Intern()-call, the provider tells the object to prepare for interning (ISupportsInterning.PrepareForInterning)\n\t/// and stores it into a dictionary. On further Intern() calls, the original object is returned for all equal objects.\n\t/// This allows reducing the memory usage by using a single object instance where possible.\n\t/// \n\t/// Interning provider implementations could also use the interning logic for different purposes:\n\t/// for example, it could be used to determine which objects are used jointly between multiple type definitions\n\t/// and which are used only within a single type definition. Then a persistent file format could be organized so\n\t/// that shared objects are loaded only once, yet non-shared objects get loaded lazily together with the class.\n\t/// </remarks>\n\tpublic abstract class InterningProvider\n\t{\n\t\tpublic static readonly InterningProvider Dummy = new DummyInterningProvider();\n\n\t\t/// <summary>\n\t\t/// Interns the specified object.\n\t\t/// \n\t\t/// If the object is freezable, it will be frozen.\n\t\t/// </summary>\n\t\t[return: NotNullIfNotNull(\"obj\")]\n\t\tpublic abstract ISupportsInterning? Intern(ISupportsInterning? obj);\n\n\t\t/// <summary>\n\t\t/// Interns the specified object.\n\t\t/// \n\t\t/// If the object is freezable, it will be frozen.\n\t\t/// </summary>\n\t\t[return: NotNullIfNotNull(\"obj\")]\n\t\tpublic T? Intern<T>(T? obj) where T : class, ISupportsInterning\n\t\t{\n\t\t\tISupportsInterning? input = obj;\n\t\t\treturn (T?)Intern(input);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Interns the specified string.\n\t\t/// </summary>\n\t\t[return: NotNullIfNotNull(\"text\")]\n\t\tpublic abstract string? Intern(string? text);\n\n\t\t/// <summary>\n\t\t/// Inters a boxed value type.\n\t\t/// </summary>\n\t\t[return: NotNullIfNotNull(\"obj\")]\n\t\tpublic abstract object? InternValue(object? obj);\n\n\t\t/// <summary>\n\t\t/// Interns the given list. Uses reference equality to compare the list elements.\n\t\t/// </summary>\n\t\t[return: NotNullIfNotNull(\"list\")]\n\t\tpublic abstract IList<T>? InternList<T>(IList<T>? list) where T : class;\n\n\t\tsealed class DummyInterningProvider : InterningProvider\n\t\t{\n\t\t\tpublic override ISupportsInterning? Intern(ISupportsInterning? obj)\n\t\t\t{\n\t\t\t\treturn obj;\n\t\t\t}\n\n\t\t\tpublic override string? Intern(string? text)\n\t\t\t{\n\t\t\t\treturn text;\n\t\t\t}\n\n\t\t\tpublic override object? InternValue(object? obj)\n\t\t\t{\n\t\t\t\treturn obj;\n\t\t\t}\n\n\t\t\tpublic override IList<T>? InternList<T>(IList<T>? list)\n\t\t\t{\n\t\t\t\treturn list;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/IMember.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\tpublic interface IMemberReference\n\t{\n\t\t/// <summary>\n\t\t/// Gets the declaring type reference for the member.\n\t\t/// </summary>\n\t\tITypeReference DeclaringTypeReference { get; }\n\n\t\t/// <summary>\n\t\t/// Resolves the member.\n\t\t/// </summary>\n\t\t/// <param name=\"context\">\n\t\t/// Context to use for resolving this member reference.\n\t\t/// Which kind of context is required depends on the which kind of member reference this is;\n\t\t/// please consult the documentation of the method that was used to create this member reference,\n\t\t/// or that of the class implementing this method.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// Returns the resolved member, or <c>null</c> if the member could not be found.\n\t\t/// </returns>\n\t\tIMember? Resolve(ITypeResolveContext context);\n\t}\n\n\t/// <summary>\n\t/// Method/field/property/event.\n\t/// </summary>\n\tpublic interface IMember : IEntity\n\t{\n\t\t/// <summary>\n\t\t/// Gets the original member definition for this member.\n\t\t/// Returns <c>this</c> if this is not a specialized member.\n\t\t/// Specialized members are the result of overload resolution with type substitution.\n\t\t/// </summary>\n\t\tIMember MemberDefinition { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the return type of this member.\n\t\t/// This property never returns <c>null</c>.\n\t\t/// </summary>\n\t\tIType ReturnType { get; }\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the declaring type (incl. type arguments, if any).\n\t\t/// If this is not a specialized member, the value returned is equal to <see cref=\"IEntity.DeclaringTypeDefinition\"/>.\n\t\t/// </summary>\n\t\tnew IType DeclaringType { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the interface members explicitly implemented by this member.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// For methods, equivalent to (\n\t\t///\t\tfrom impl in DeclaringTypeDefinition.GetExplicitInterfaceImplementations()\n\t\t///\t\twhere impl.Implementation == this\n\t\t///\t\tselect impl.InterfaceMethod\n\t\t/// ),\n\t\t/// but may be more efficient than searching the whole list.\n\t\t/// \n\t\t/// Note that it is possible for a class to implement an interface using members in a\n\t\t/// base class unrelated to that interface:\n\t\t///   class BaseClass { public void Dispose() {} }\n\t\t///   class C : BaseClass, IDisposable { }\n\t\t/// In this case, the interface member will not show up in (BaseClass.Dispose).ImplementedInterfaceMembers,\n\t\t/// so use (C).GetInterfaceImplementations() instead to handle this case.\n\t\t/// </remarks>\n\t\tIEnumerable<IMember> ExplicitlyImplementedInterfaceMembers { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether this member is explicitly implementing an interface.\n\t\t/// </summary>\n\t\tbool IsExplicitInterfaceImplementation { get; }\n\n\t\t/// <summary>\n\t\t/// Gets if the member is virtual. Is true only if the \"virtual\" modifier was used, but non-virtual\n\t\t/// members can be overridden, too; if they are abstract or overriding a method.\n\t\t/// </summary>\n\t\tbool IsVirtual { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether this member is overriding another member.\n\t\t/// </summary>\n\t\tbool IsOverride { get; }\n\n\t\t/// <summary>\n\t\t/// Gets if the member can be overridden. Returns true when the member is \"abstract\", \"virtual\" or \"override\" but not \"sealed\".\n\t\t/// </summary>\n\t\tbool IsOverridable { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the substitution belonging to this specialized member.\n\t\t/// Returns TypeParameterSubstitution.Identity for not specialized members.\n\t\t/// </summary>\n\t\tTypeParameterSubstitution Substitution {\n\t\t\tget;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Specializes this member with the given substitution.\n\t\t/// If this member is already specialized, the new substitution is composed with the existing substition.\n\t\t/// </summary>\n\t\tIMember Specialize(TypeParameterSubstitution substitution);\n\n\t\t/// <summary>\n\t\t/// Gets whether the members are considered equal when applying the specified type normalization.\n\t\t/// </summary>\n\t\tbool Equals(IMember? obj, TypeVisitor typeNormalization);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/IMethod.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Reflection;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Represents a method, constructor, destructor or operator.\n\t/// </summary>\n\tpublic interface IMethod : IParameterizedMember\n\t{\n\t\t/// <summary>\n\t\t/// Gets the attributes associated with the return type. (e.g. [return: MarshalAs(...)])\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Does not include inherited attributes.\n\t\t/// </remarks>\n\t\tIEnumerable<IAttribute> GetReturnTypeAttributes();\n\n\t\t/// <summary>\n\t\t/// Gets whether the return type is 'ref readonly'.\n\t\t/// </summary>\n\t\tbool ReturnTypeIsRefReadOnly { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether this method may only be called on fresh instances.\n\t\t/// Used with C# 9 `init;` property setters.\n\t\t/// </summary>\n\t\tbool IsInitOnly { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether the method accepts the 'this' reference as ref readonly.\n\t\t/// This can be either because the method is C# 8.0 'readonly', or because it is within a C# 7.2 'readonly struct'\n\t\t/// </summary>\n\t\tbool ThisIsRefReadOnly { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the type parameters of this method; or an empty list if the method is not generic.\n\t\t/// </summary>\n\t\tIReadOnlyList<ITypeParameter> TypeParameters { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the type arguments passed to this method.\n\t\t/// If the method is generic but not parameterized yet, this property returns the type parameters,\n\t\t/// as if the method was parameterized with its own type arguments (<c>void M&lt;T&gt;() { M&lt;T&gt;(); }</c>).\n\t\t/// </summary>\n\t\tIReadOnlyList<IType> TypeArguments { get; }\n\n\t\tbool IsExtensionMethod { get; }\n\t\tbool IsLocalFunction { get; }\n\t\tbool IsConstructor { get; }\n\t\tbool IsDestructor { get; }\n\t\tbool IsOperator { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether the method has a body.\n\t\t/// This property returns <c>false</c> for <c>abstract</c> or <c>extern</c> methods,\n\t\t/// or for <c>partial</c> methods without implementation.\n\t\t/// </summary>\n\t\tbool HasBody { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether the method is a property/event accessor.\n\t\t/// </summary>\n\t\t[MemberNotNullWhen(true, nameof(AccessorOwner))]\n\t\tbool IsAccessor { get; }\n\n\t\t/// <summary>\n\t\t/// If this method is an accessor, returns the corresponding property/event.\n\t\t/// Otherwise, returns null.\n\t\t/// </summary>\n\t\tIMember? AccessorOwner { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the kind of accessor this is.\n\t\t/// </summary>\n\t\tMethodSemanticsAttributes AccessorKind { get; }\n\n\t\t/// <summary>\n\t\t/// If this method is reduced from an extension method or a local function returns the original method, <c>null</c> otherwise.\n\t\t/// A reduced method doesn't contain the extension method parameter. That means that it has one parameter less than its definition.\n\t\t/// A local function doesn't contain compiler-generated method parameters at the end.\n\t\t/// </summary>\n\t\tIMethod? ReducedFrom { get; }\n\n\t\t/// <summary>\n\t\t/// Specializes this method with the given substitution.\n\t\t/// If this method is already specialized, the new substitution is composed with the existing substition.\n\t\t/// </summary>\n\t\tnew IMethod Specialize(TypeParameterSubstitution substitution);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/INamedElement.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\tpublic interface INamedElement\n\t{\n\t\t/// <summary>\n\t\t/// Gets the fully qualified name of the class the return type is pointing to.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// \"System.Int32[]\" for int[]<br/>\n\t\t/// \"System.Collections.Generic.List\" for List&lt;string&gt;\n\t\t/// \"System.Environment.SpecialFolder\" for Environment.SpecialFolder\n\t\t/// </returns>\n\t\tstring FullName { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the short name of the class the return type is pointing to.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// \"Int32[]\" for int[]<br/>\n\t\t/// \"List\" for List&lt;string&gt;\n\t\t/// \"SpecialFolder\" for Environment.SpecialFolder\n\t\t/// </returns>\n\t\tstring Name { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the full reflection name of the element.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// For types, the reflection name can be parsed back into a IType by using\n\t\t/// <see cref=\"ReflectionHelper.ParseReflectionName(string, ITypeResolveContext)\"/>.\n\t\t/// </remarks>\n\t\t/// <returns>\n\t\t/// \"System.Int32[]\" for int[]<br/>\n\t\t/// \"System.Int32[][,]\" for C# int[,][]<br/>\n\t\t/// \"System.Collections.Generic.List`1[[System.String]]\" for List&lt;string&gt;\n\t\t/// \"System.Environment+SpecialFolder\" for Environment.SpecialFolder\n\t\t/// </returns>\n\t\tstring ReflectionName { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the full name of the namespace containing this entity.\n\t\t/// </summary>\n\t\tstring Namespace { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/INamespace.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Represents a resolved namespace.\n\t/// </summary>\n\tpublic interface INamespace : ISymbol, ICompilationProvider\n\t{\n\t\t// No pointer back to unresolved namespace:\n\t\t// multiple unresolved namespaces (from different assemblies) get\n\t\t// merged into one INamespace.\n\n\t\t/// <summary>\n\t\t/// Gets the extern alias for this namespace.\n\t\t/// Returns an empty string for normal namespaces.\n\t\t/// </summary>\n\t\tstring ExternAlias { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the full name of this namespace. (e.g. \"System.Collections\")\n\t\t/// </summary>\n\t\tstring FullName { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the short name of this namespace (e.g. \"Collections\").\n\t\t/// </summary>\n\t\tnew string Name { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the parent namespace.\n\t\t/// Returns null if this is the root namespace.\n\t\t/// </summary>\n\t\tINamespace? ParentNamespace { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the child namespaces in this namespace.\n\t\t/// </summary>\n\t\tIEnumerable<INamespace> ChildNamespaces { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the types in this namespace.\n\t\t/// </summary>\n\t\tIEnumerable<ITypeDefinition> Types { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the modules that contribute types to this namespace (or to child namespaces).\n\t\t/// </summary>\n\t\tIEnumerable<IModule> ContributingModules { get; }\n\n\t\t/// <summary>\n\t\t/// Gets a direct child namespace by its short name.\n\t\t/// Returns null when the namespace cannot be found.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This method uses the compilation's current string comparer.\n\t\t/// </remarks>\n\t\tINamespace? GetChildNamespace(string name);\n\n\t\t/// <summary>\n\t\t/// Gets the type with the specified short name and type parameter count.\n\t\t/// Returns null if the type cannot be found.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This method uses the compilation's current string comparer.\n\t\t/// </remarks>\n\t\tITypeDefinition? GetTypeDefinition(string name, int typeParameterCount);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/IParameter.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <remarks>\n\t/// Should match order in <see cref=\"CSharp.Syntax.FieldDirection\"/>.\n\t/// </remarks>\n\tpublic enum ReferenceKind : byte\n\t{\n\t\tNone,\n\t\tOut,\n\t\tRef,\n\t\tIn,\n\t\tRefReadOnly,\n\t}\n\n\tpublic struct LifetimeAnnotation\n\t{\n\t\t/// <summary>\n\t\t/// C# 11 scoped annotation: \"scoped ref\" (ScopedRefAttribute)\n\t\t/// </summary>\n\t\tpublic bool ScopedRef {\n#pragma warning disable 618\n\t\t\tget { return RefScoped; }\n\t\t\tset { RefScoped = value; }\n#pragma warning restore 618\n\t\t}\n\n\t\t[Obsolete(\"Use ScopedRef property instead of directly accessing this field\")]\n\t\tpublic bool RefScoped;\n\n\t\t[Obsolete(\"C# 11 preview: \\\"ref scoped\\\" no longer supported\")]\n\t\tpublic bool ValueScoped;\n\t}\n\n\tpublic interface IParameter : IVariable\n\t{\n\t\t/// <summary>\n\t\t/// Gets the attributes on this parameter.\n\t\t/// </summary>\n\t\tIEnumerable<IAttribute> GetAttributes();\n\n\t\t/// <summary>\n\t\t/// Gets the reference kind of this parameter.\n\t\t/// </summary>\n\t\tReferenceKind ReferenceKind { get; }\n\n\t\t/// <summary>\n\t\t/// C# 11 scoped annotation.\n\t\t/// </summary>\n\t\tLifetimeAnnotation Lifetime { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether this parameter is a C# 'params' parameter.\n\t\t/// </summary>\n\t\tbool IsParams { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether this parameter is optional.\n\t\t/// The default value is given by the <see cref=\"IVariable.GetConstantValue\"/> function.\n\t\t/// </summary>\n\t\tbool IsOptional { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether this parameter has a constant value when presented in method signature.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This can only be <c>true</c> if the parameter is optional, and it's true for most \n\t\t/// optional parameters. However it is possible to compile a parameter without a default value,\n\t\t/// and some parameters handle their default values in an special way.\n\t\t/// \n\t\t/// For example, <see cref=\"DecimalConstantAttribute\"/> does not use normal constants,\n\t\t/// so when <see cref=\"DecompilerSettings.DecimalConstants\" /> is <c>false</c>\n\t\t/// we expose <c>DecimalConstantAttribute</c> directly instead of a constant value.\n\t\t/// \n\t\t/// On the call sites, though, we can still use the value inferred from the attribute.\n\t\t/// </remarks>\n\t\tbool HasConstantValueInSignature { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the owner of this parameter.\n\t\t/// May return null; for example when parameters belong to lambdas or anonymous methods.\n\t\t/// </summary>\n\t\tIParameterizedMember? Owner { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/IParameterizedMember.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n#nullable enable\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Represents a method or property.\n\t/// </summary>\n\tpublic interface IParameterizedMember : IMember\n\t{\n\t\tIReadOnlyList<IParameter> Parameters { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/IProperty.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Diagnostics.CodeAnalysis;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Represents a property or indexer.\n\t/// </summary>\n\tpublic interface IProperty : IParameterizedMember\n\t{\n\t\t[MemberNotNullWhen(true, nameof(Getter))]\n\t\tbool CanGet { get; }\n\t\t[MemberNotNullWhen(true, nameof(Setter))]\n\t\tbool CanSet { get; }\n\n\t\tIMethod? Getter { get; }\n\t\tIMethod? Setter { get; }\n\n\t\tbool IsIndexer { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether the return type is 'ref readonly'.\n\t\t/// </summary>\n\t\tbool ReturnTypeIsRefReadOnly { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/ISupportsInterning.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Interface for TypeSystem objects that support interning.\n\t/// See <see cref=\"InterningProvider\"/> for more information.\n\t/// </summary>\n\tpublic interface ISupportsInterning\n\t{\n\t\t/// <summary>\n\t\t/// Gets a hash code for interning.\n\t\t/// </summary>\n\t\tint GetHashCodeForInterning();\n\n\t\t/// <summary>\n\t\t/// Equality test for interning.\n\t\t/// </summary>\n\t\tbool EqualsForInterning(ISupportsInterning other);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/ISymbol.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\tpublic enum SymbolKind : byte\n\t{\n\t\tNone,\n\t\t/// <seealso cref=\"IModule\"/>\n\t\tModule,\n\t\t/// <seealso cref=\"ITypeDefinition\"/>\n\t\tTypeDefinition,\n\t\t/// <seealso cref=\"IField\"/>\n\t\tField,\n\t\t/// <summary>\n\t\t/// The symbol is a property, but not an indexer.\n\t\t/// </summary>\n\t\t/// <seealso cref=\"IProperty\"/>\n\t\tProperty,\n\t\t/// <summary>\n\t\t/// The symbol is an indexer, not a regular property.\n\t\t/// </summary>\n\t\t/// <seealso cref=\"IProperty\"/>\n\t\tIndexer,\n\t\t/// <seealso cref=\"IEvent\"/>\n\t\tEvent,\n\t\t/// <summary>\n\t\t/// The symbol is a method which is not an operator/constructor/destructor or accessor.\n\t\t/// </summary>\n\t\t/// <seealso cref=\"IMethod\"/>\n\t\tMethod,\n\t\t/// <summary>\n\t\t/// The symbol is a user-defined operator.\n\t\t/// </summary>\n\t\t/// <seealso cref=\"IMethod\"/>\n\t\tOperator,\n\t\t/// <seealso cref=\"IMethod\"/>\n\t\tConstructor,\n\t\t/// <seealso cref=\"IMethod\"/>\n\t\tDestructor,\n\t\t/// <summary>\n\t\t/// The accessor method for a property getter/setter or event add/remove.\n\t\t/// </summary>\n\t\t/// <seealso cref=\"IMethod\"/>\n\t\tAccessor,\n\t\t/// <seealso cref=\"INamespace\"/>\n\t\tNamespace,\n\t\t/// <summary>\n\t\t/// The symbol is a variable, but not a parameter.\n\t\t/// </summary>\n\t\t/// <seealso cref=\"IVariable\"/>\n\t\tVariable,\n\t\t/// <seealso cref=\"IParameter\"/>\n\t\tParameter,\n\t\t/// <seealso cref=\"ITypeParameter\"/>\n\t\tTypeParameter,\n\t\t/// <summary>\n\t\t/// Constraint on a type parameter.\n\t\t/// </summary>\n\t\tConstraint,\n\t\t/// <summary>\n\t\t/// Return type. Not actually an ISymbol implementation; but can appear as attribut target.\n\t\t/// </summary>\n\t\tReturnType,\n\t}\n\n\t/// <summary>\n\t/// Interface for type system symbols.\n\t/// </summary>\n\tpublic interface ISymbol\n\t{\n\t\t/// <summary>\n\t\t/// This property returns an enum specifying which kind of symbol this is\n\t\t/// (which derived interfaces of ISymbol are implemented)\n\t\t/// </summary>\n\t\tSymbolKind SymbolKind { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the short name of the symbol.\n\t\t/// </summary>\n\t\tstring Name { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/IType.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// This interface represents a resolved type in the type system.\n\t/// </summary>\n\t/// <remarks>\n\t/// <para>\n\t/// A type is potentially\n\t/// - a type definition (<see cref=\"ITypeDefinition\"/>, i.e. a class, struct, interface, delegate, or built-in primitive type)\n\t/// - a parameterized type (<see cref=\"ParameterizedType\"/>, e.g. List&lt;int>)\n\t/// - a type parameter (<see cref=\"ITypeParameter\"/>, e.g. T)\n\t/// - an array (<see cref=\"ArrayType\"/>)\n\t/// - a pointer (<see cref=\"PointerType\"/>)\n\t/// - a managed reference (<see cref=\"ByReferenceType\"/>)\n\t/// - one of the special types (<see cref=\"SpecialType.UnknownType\"/>, <see cref=\"SpecialType.NullType\"/>,\n\t///      <see cref=\"SpecialType.Dynamic\"/>, <see cref=\"SpecialType.UnboundTypeArgument\"/>)\n\t/// \n\t/// The <see cref=\"IType.Kind\"/> property can be used to switch on the kind of a type.\n\t/// </para>\n\t/// <para>\n\t/// IType uses the null object pattern: <see cref=\"SpecialType.UnknownType\"/> serves as the null object.\n\t/// Methods or properties returning IType never return null unless documented otherwise.\n\t/// </para>\n\t/// <para>\n\t/// Types should be compared for equality using the <see cref=\"IEquatable{IType}.Equals(IType)\"/> method.\n\t/// Identical types do not necessarily use the same object reference.\n\t/// </para>\n\t/// </remarks>\n\tpublic interface IType : INamedElement, IEquatable<IType>\n\t{\n\t\t/// <summary>\n\t\t/// Gets the type kind.\n\t\t/// </summary>\n\t\tTypeKind Kind { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether the type is a reference type or value type.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// true, if the type is a reference type.\n\t\t/// false, if the type is a value type.\n\t\t/// null, if the type is not known (e.g. unconstrained generic type parameter or type not found)\n\t\t/// </returns>\n\t\tbool? IsReferenceType { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether this type is \"ref-like\": a ByReferenceType or \"ref struct\".\n\t\t/// </summary>\n\t\tbool IsByRefLike { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the nullability annotation on this type.\n\t\t/// </summary>\n\t\tNullability Nullability { get; }\n\n\t\t/// <summary>\n\t\t/// Creates a new type that is a copy of this type, with the changed nullability annotation.\n\t\t/// </summary>\n\t\tIType ChangeNullability(Nullability newNullability);\n\n\t\t/// <summary>\n\t\t/// Gets the underlying type definition.\n\t\t/// Can return null for types which do not have a type definition (for example arrays, pointers, type parameters).\n\t\t/// </summary>\n\t\tITypeDefinition? GetDefinition();\n\n\t\t/// <summary>\n\t\t/// Gets the underlying type definition or UnkownType, if unknown.\n\t\t/// Can return null for types which do not have a type definition (for example arrays, pointers, type parameters).\n\t\t/// </summary>\n\t\tITypeDefinitionOrUnknown? GetDefinitionOrUnknown();\n\n\t\t/// <summary>\n\t\t/// Gets the parent type, if this is a nested type.\n\t\t/// Returns null for top-level types.\n\t\t/// </summary>\n\t\tIType? DeclaringType { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the number of type parameters.\n\t\t/// </summary>\n\t\tint TypeParameterCount { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the type parameters.\n\t\t/// Returns an empty list if this type is not generic.\n\t\t/// </summary>\n\t\tIReadOnlyList<ITypeParameter> TypeParameters { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the type arguments passed to this type.\n\t\t/// If this type is a generic type definition that is not parameterized, this property returns the type parameters,\n\t\t/// as if the type was parameterized with its own type arguments (<c>class C&lt;T&gt; { C&lt;T&gt; field; }</c>).\n\t\t/// </summary>\n\t\tIReadOnlyList<IType> TypeArguments { get; }\n\n\t\t/// <summary>\n\t\t/// Calls ITypeVisitor.Visit for this type.\n\t\t/// </summary>\n\t\t/// <returns>The return value of the ITypeVisitor.Visit call</returns>\n\t\tIType AcceptVisitor(TypeVisitor visitor);\n\n\t\t/// <summary>\n\t\t/// Calls ITypeVisitor.Visit for all children of this type, and reconstructs this type with the children based\n\t\t/// on the return values of the visit calls.\n\t\t/// </summary>\n\t\t/// <returns>A copy of this type, with all children replaced by the return value of the corresponding visitor call.\n\t\t/// If the visitor returned the original types for all children (or if there are no children), returns <c>this</c>.\n\t\t/// </returns>\n\t\tIType VisitChildren(TypeVisitor visitor);\n\n\t\t/// <summary>\n\t\t/// Gets the direct base types.\n\t\t/// </summary>\n\t\t/// <returns>Returns the direct base types including interfaces</returns>\n\t\tIEnumerable<IType> DirectBaseTypes { get; }\n\n\t\t/// <summary>\n\t\t/// Gets a type visitor that performs the substitution of class type parameters with the type arguments\n\t\t/// of this parameterized type.\n\t\t/// Returns TypeParameterSubstitution.Identity if the type is not parametrized.\n\t\t/// </summary>\n\t\tTypeParameterSubstitution GetSubstitution();\n\n\t\t/// <summary>\n\t\t/// Gets inner classes (including inherited inner classes).\n\t\t/// </summary>\n\t\t/// <param name=\"filter\">The filter used to select which types to return.\n\t\t/// The filter is tested on the original type definitions (before parameterization).</param>\n\t\t/// <param name=\"options\">Specified additional options for the GetMembers() operation.</param>\n\t\t/// <remarks>\n\t\t/// <para>\n\t\t/// If the nested type is generic, this method will return a parameterized type,\n\t\t/// where the additional type parameters are set to <see cref=\"SpecialType.UnboundTypeArgument\"/>.\n\t\t/// </para>\n\t\t/// <para>\n\t\t/// Type parameters belonging to the outer class will have the value copied from the outer type\n\t\t/// if it is a parameterized type. Otherwise, those existing type parameters will be self-parameterized,\n\t\t/// and thus 'leaked' to the caller in the same way the GetMembers() method does not specialize members\n\t\t/// from an <see cref=\"ITypeDefinition\"/> and 'leaks' type parameters in member signatures.\n\t\t/// </para>\n\t\t/// </remarks>\n\t\t/// <example>\n\t\t/// <code>\n\t\t/// class Base&lt;T> {\n\t\t/// \tclass Nested&lt;X> {}\n\t\t/// }\n\t\t/// class Derived&lt;A, B> : Base&lt;B> {}\n\t\t/// \n\t\t/// Derived[string,int].GetNestedTypes() = { Base`1+Nested`1[int, unbound] }\n\t\t/// Derived.GetNestedTypes() = { Base`1+Nested`1[`1, unbound] }\n\t\t/// Base[`1].GetNestedTypes() = { Base`1+Nested`1[`1, unbound] }\n\t\t/// Base.GetNestedTypes() = { Base`1+Nested`1[`0, unbound] }\n\t\t/// </code>\n\t\t/// </example>\n\t\tIEnumerable<IType> GetNestedTypes(Predicate<ITypeDefinition>? filter = null, GetMemberOptions options = GetMemberOptions.None);\n\n\t\t// Note that we cannot 'leak' the additional type parameter as we leak the normal type parameters, because\n\t\t// the index might collide. For example,\n\t\t//   class Base<T> { class Nested<X> {} }\n\t\t//   class Derived<A, B> : Base<B> { }\n\t\t// \n\t\t// Derived<string, int>.GetNestedTypes() = Base+Nested<int, UnboundTypeArgument>\n\t\t// Derived.GetNestedTypes() = Base+Nested<`1, >\n\t\t//  Here `1 refers to B, and there's no way to return X as it would collide with B.\n\n\t\t/// <summary>\n\t\t/// Gets inner classes (including inherited inner classes)\n\t\t/// that have <c>typeArguments.Count</c> additional type parameters.\n\t\t/// </summary>\n\t\t/// <param name=\"typeArguments\">The type arguments passed to the inner class</param>\n\t\t/// <param name=\"filter\">The filter used to select which types to return.\n\t\t/// The filter is tested on the original type definitions (before parameterization).</param>\n\t\t/// <param name=\"options\">Specified additional options for the GetMembers() operation.</param>\n\t\t/// <remarks>\n\t\t/// Type parameters belonging to the outer class will have the value copied from the outer type\n\t\t/// if it is a parameterized type. Otherwise, those existing type parameters will be self-parameterized,\n\t\t/// and thus 'leaked' to the caller in the same way the GetMembers() method does not specialize members\n\t\t/// from an <see cref=\"ITypeDefinition\"/> and 'leaks' type parameters in member signatures.\n\t\t/// </remarks>\n\t\tIEnumerable<IType> GetNestedTypes(IReadOnlyList<IType> typeArguments, Predicate<ITypeDefinition>? filter = null, GetMemberOptions options = GetMemberOptions.None);\n\n\t\t/// <summary>\n\t\t/// Gets all instance constructors for this type.\n\t\t/// </summary>\n\t\t/// <param name=\"filter\">The filter used to select which constructors to return.\n\t\t/// The filter is tested on the original method definitions (before specialization).</param>\n\t\t/// <param name=\"options\">Specified additional options for the GetMembers() operation.</param>\n\t\t/// <remarks>\n\t\t/// <para>The result does not include static constructors.\n\t\t/// Constructors in base classes are not returned by default, as GetMemberOptions.IgnoreInheritedMembers is the default value.</para>\n\t\t/// <para>\n\t\t/// For methods on parameterized types, type substitution will be performed on the method signature,\n\t\t/// and the appropriate <see cref=\"Implementation.SpecializedMethod\"/> will be returned.\n\t\t/// </para>\n\t\t/// </remarks>\n\t\tIEnumerable<IMethod> GetConstructors(Predicate<IMethod>? filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers);\n\n\t\t/// <summary>\n\t\t/// Gets all methods that can be called on this type.\n\t\t/// </summary>\n\t\t/// <param name=\"filter\">The filter used to select which methods to return.\n\t\t/// The filter is tested on the original method definitions (before specialization).</param>\n\t\t/// <param name=\"options\">Specified additional options for the GetMembers() operation.</param>\n\t\t/// <remarks>\n\t\t/// <para>\n\t\t/// The result does not include constructors or accessors.\n\t\t/// </para>\n\t\t/// <para>\n\t\t/// For methods on parameterized types, type substitution will be performed on the method signature,\n\t\t/// and the appropriate <see cref=\"Implementation.SpecializedMethod\"/> will be returned.\n\t\t/// </para>\n\t\t/// <para>\n\t\t/// If the method being returned is generic, and this type is a parameterized type where the type\n\t\t/// arguments involve another method's type parameters, the resulting specialized signature\n\t\t/// will be ambiguous as to which method a type parameter belongs to.\n\t\t/// For example, \"List[[``0]].GetMethods()\" will return \"ConvertAll(Converter`2[[``0, ``0]])\".\n\t\t/// \n\t\t/// If possible, use the other GetMethods() overload to supply type arguments to the method,\n\t\t/// so that both class and method type parameter can be substituted at the same time, so that\n\t\t/// the ambiguity can be avoided.\n\t\t/// </para>\n\t\t/// </remarks>\n\t\tIEnumerable<IMethod> GetMethods(Predicate<IMethod>? filter = null, GetMemberOptions options = GetMemberOptions.None);\n\n\t\t/// <summary>\n\t\t/// Gets all generic methods that can be called on this type with the specified type arguments.\n\t\t/// </summary>\n\t\t/// <param name=\"typeArguments\">The type arguments used for the method call.</param>\n\t\t/// <param name=\"filter\">The filter used to select which methods to return.\n\t\t/// The filter is tested on the original method definitions (before specialization).</param>\n\t\t/// <param name=\"options\">Specified additional options for the GetMembers() operation.</param>\n\t\t/// <remarks>\n\t\t/// <para>The result does not include constructors or accessors.</para>\n\t\t/// <para>\n\t\t/// Type substitution will be performed on the method signature, creating a <see cref=\"Implementation.SpecializedMethod\"/>\n\t\t/// with the specified type arguments.\n\t\t/// </para>\n\t\t/// <para>\n\t\t/// When the list of type arguments is empty, this method acts like the GetMethods() overload without\n\t\t/// the type arguments parameter - that is, it also returns generic methods,\n\t\t/// and the other overload's remarks about ambiguous signatures apply here as well.\n\t\t/// </para>\n\t\t/// </remarks>\n\t\tIEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IMethod>? filter = null, GetMemberOptions options = GetMemberOptions.None);\n\n\t\t/// <summary>\n\t\t/// Gets all properties that can be called on this type.\n\t\t/// </summary>\n\t\t/// <param name=\"filter\">The filter used to select which properties to return.\n\t\t/// The filter is tested on the original property definitions (before specialization).</param>\n\t\t/// <param name=\"options\">Specified additional options for the GetMembers() operation.</param>\n\t\t/// <remarks>\n\t\t/// For properties on parameterized types, type substitution will be performed on the property signature,\n\t\t/// and the appropriate <see cref=\"Implementation.SpecializedProperty\"/> will be returned.\n\t\t/// </remarks>\n\t\tIEnumerable<IProperty> GetProperties(Predicate<IProperty>? filter = null, GetMemberOptions options = GetMemberOptions.None);\n\n\t\t/// <summary>\n\t\t/// Gets all fields that can be accessed on this type.\n\t\t/// </summary>\n\t\t/// <param name=\"filter\">The filter used to select which constructors to return.\n\t\t/// The filter is tested on the original field definitions (before specialization).</param>\n\t\t/// <param name=\"options\">Specified additional options for the GetMembers() operation.</param>\n\t\t/// <remarks>\n\t\t/// For fields on parameterized types, type substitution will be performed on the field's return type,\n\t\t/// and the appropriate <see cref=\"Implementation.SpecializedField\"/> will be returned.\n\t\t/// </remarks>\n\t\tIEnumerable<IField> GetFields(Predicate<IField>? filter = null, GetMemberOptions options = GetMemberOptions.None);\n\n\t\t/// <summary>\n\t\t/// Gets all events that can be accessed on this type.\n\t\t/// </summary>\n\t\t/// <param name=\"filter\">The filter used to select which events to return.\n\t\t/// The filter is tested on the original event definitions (before specialization).</param>\n\t\t/// <param name=\"options\">Specified additional options for the GetMembers() operation.</param>\n\t\t/// <remarks>\n\t\t/// For fields on parameterized types, type substitution will be performed on the event's return type,\n\t\t/// and the appropriate <see cref=\"Implementation.SpecializedEvent\"/> will be returned.\n\t\t/// </remarks>\n\t\tIEnumerable<IEvent> GetEvents(Predicate<IEvent>? filter = null, GetMemberOptions options = GetMemberOptions.None);\n\n\t\t/// <summary>\n\t\t/// Gets all members that can be called on this type.\n\t\t/// </summary>\n\t\t/// <param name=\"filter\">The filter used to select which members to return.\n\t\t/// The filter is tested on the original member definitions (before specialization).</param>\n\t\t/// <param name=\"options\">Specified additional options for the GetMembers() operation.</param>\n\t\t/// <remarks>\n\t\t/// <para>\n\t\t/// The resulting list is the union of GetFields(), GetProperties(), GetMethods() and GetEvents().\n\t\t/// It does not include constructors.\n\t\t/// For parameterized types, type substitution will be performed.\n\t\t/// </para>\n\t\t/// <para>\n\t\t/// For generic methods, the remarks about ambiguous signatures from the\n\t\t/// <see cref=\"GetMethods(Predicate{IMethod}, GetMemberOptions)\"/> method apply here as well.\n\t\t/// </para>\n\t\t/// </remarks>\n\t\tIEnumerable<IMember> GetMembers(Predicate<IMember>? filter = null, GetMemberOptions options = GetMemberOptions.None);\n\n\t\t/// <summary>\n\t\t/// Gets all accessors belonging to properties or events on this type.\n\t\t/// </summary>\n\t\t/// <param name=\"filter\">The filter used to select which members to return.\n\t\t/// The filter is tested on the original member definitions (before specialization).</param>\n\t\t/// <param name=\"options\">Specified additional options for the GetMembers() operation.</param>\n\t\t/// <remarks>\n\t\t/// Accessors are not returned by GetMembers() or GetMethods().\n\t\t/// </remarks>\n\t\tIEnumerable<IMethod> GetAccessors(Predicate<IMethod>? filter = null, GetMemberOptions options = GetMemberOptions.None);\n\t}\n\n\t[Flags]\n\tpublic enum GetMemberOptions\n\t{\n\t\t/// <summary>\n\t\t/// No options specified - this is the default.\n\t\t/// Members will be specialized, and inherited members will be included.\n\t\t/// </summary>\n\t\tNone = 0x00,\n\t\t/// <summary>\n\t\t/// Do not specialize the returned members - directly return the definitions.\n\t\t/// </summary>\n\t\tReturnMemberDefinitions = 0x01,\n\t\t/// <summary>\n\t\t/// Do not list inherited members - only list members defined directly on this type.\n\t\t/// </summary>\n\t\tIgnoreInheritedMembers = 0x02\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/ITypeDefinition.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Represents a class, enum, interface, struct, delegate, record or VB module.\n\t/// For partial classes, this represents the whole class.\n\t/// </summary>\n\tpublic interface ITypeDefinition : ITypeDefinitionOrUnknown, IType, IEntity\n\t{\n\t\tExtensionInfo? ExtensionInfo { get; }\n\t\tIReadOnlyList<ITypeDefinition> NestedTypes { get; }\n\t\tIReadOnlyList<IMember> Members { get; }\n\n\t\tIEnumerable<IField> Fields { get; }\n\t\tIEnumerable<IMethod> Methods { get; }\n\t\tIEnumerable<IProperty> Properties { get; }\n\t\tIEnumerable<IEvent> Events { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the known type code for this type definition.\n\t\t/// </summary>\n\t\tKnownTypeCode KnownTypeCode { get; }\n\n\t\t/// <summary>\n\t\t/// For enums: returns the underlying primitive type.\n\t\t/// For all other types: returns <see langword=\"null\"/>.\n\t\t/// </summary>\n\t\tIType? EnumUnderlyingType { get; }\n\n\t\t/// <summary>\n\t\t/// For structs: returns whether this is a readonly struct.\n\t\t/// For all other types: returns false.\n\t\t/// </summary>\n\t\tbool IsReadOnly { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the short type name as stored in metadata.\n\t\t/// That is, the short type name including the generic arity (`N) appended.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// \"Int32\" for int\n\t\t/// \"List`1\" for List&lt;T&gt;\n\t\t/// \"List`1\" for List&lt;string&gt;\n\t\t/// </remarks>\n\t\tstring MetadataName { get; }\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the declaring type (incl. type arguments, if any).\n\t\t/// This property will return null for top-level types.\n\t\t/// </summary>\n\t\tnew IType? DeclaringType { get; } // solves ambiguity between IType.DeclaringType and IEntity.DeclaringType\n\n\t\t/// <summary>\n\t\t/// Gets whether this type contains extension methods or C# 14 extensions.\n\t\t/// </summary>\n\t\t/// <remarks>This property is used to speed up the search for extension members.</remarks>\n\t\tbool HasExtensions { get; }\n\n\t\t/// <summary>\n\t\t/// The nullability specified in the [NullableContext] attribute on the type.\n\t\t/// This serves as default nullability for members of the type that do not have a [Nullable] attribute.\n\t\t/// </summary>\n\t\tNullability NullableContext { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether the type has the necessary members to be considered a C# 9 record or C# 10 record struct type.\n\t\t/// </summary>\n\t\tbool IsRecord { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/ITypeDefinitionOrUnknown.cs",
    "content": "// Copyright (c) 2022 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Represents a class, enum, interface, struct, delegate, record or unknown type.\n\t/// For partial classes, this represents the whole class.\n\t/// </summary>\n\tpublic interface ITypeDefinitionOrUnknown : IType\n\t{\n\t\t/// <summary>\n\t\t/// Gets the full name of this type.\n\t\t/// </summary>\n\t\tFullTypeName FullTypeName { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/ITypeParameter.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Type parameter of a generic class/method.\n\t/// </summary>\n\tpublic interface ITypeParameter : IType, ISymbol\n\t{\n\t\t/// <summary>\n\t\t/// Get the type of this type parameter's owner.\n\t\t/// </summary>\n\t\t/// <returns>SymbolKind.TypeDefinition or SymbolKind.Method</returns>\n\t\tSymbolKind OwnerType { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the owning method/class.\n\t\t/// This property may return null (for example for the dummy type parameters used by <see cref=\"NormalizeTypeVisitor.ReplaceMethodTypeParametersWithDummy\"/>).\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// For \"class Outer&lt;T&gt; { class Inner {} }\",\n\t\t/// inner.TypeParameters[0].Owner will be the outer class, because the same\n\t\t/// ITypeParameter instance is used both on Outer`1 and Outer`1+Inner.\n\t\t/// </remarks>\n\t\tIEntity? Owner { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the index of the type parameter in the type parameter list of the owning method/class.\n\t\t/// </summary>\n\t\tint Index { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the name of the type parameter.\n\t\t/// </summary>\n\t\tnew string Name { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the attributes declared on this type parameter.\n\t\t/// </summary>\n\t\tIEnumerable<IAttribute> GetAttributes();\n\n\t\t/// <summary>\n\t\t/// Gets the variance of this type parameter.\n\t\t/// </summary>\n\t\tVarianceModifier Variance { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the effective base class of this type parameter.\n\t\t/// </summary>\n\t\tIType EffectiveBaseClass { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the effective interface set of this type parameter.\n\t\t/// </summary>\n\t\tIReadOnlyCollection<IType> EffectiveInterfaceSet { get; }\n\n\t\t/// <summary>\n\t\t/// Gets if the type parameter has the 'new()' constraint.\n\t\t/// </summary>\n\t\tbool HasDefaultConstructorConstraint { get; }\n\n\t\t/// <summary>\n\t\t/// Gets if the type parameter has the 'class' constraint.\n\t\t/// </summary>\n\t\tbool HasReferenceTypeConstraint { get; }\n\n\t\t/// <summary>\n\t\t/// Gets if the type parameter has the 'struct' or 'unmanaged' constraint.\n\t\t/// </summary>\n\t\tbool HasValueTypeConstraint { get; }\n\n\t\t/// <summary>\n\t\t/// Gets if the type parameter has the 'unmanaged' constraint.\n\t\t/// </summary>\n\t\tbool HasUnmanagedConstraint { get; }\n\n\t\t/// <summary>\n\t\t/// <see langword=\"true\"/> if the <c>allows ref struct</c> constraint is specified for the type parameter.\n\t\t/// </summary>\n\t\tbool AllowsRefLikeType { get; }\n\n\t\t/// <summary>\n\t\t/// Nullability of the reference type constraint. (e.g. \"where T : class?\").\n\t\t/// \n\t\t/// Note that the nullability of a use of the type parameter may differ from this.\n\t\t/// E.g. \"T? GetNull&lt;T&gt;() where T : class => null;\"\n\t\t/// </summary>\n\t\tNullability NullabilityConstraint { get; }\n\n\t\tIReadOnlyList<TypeConstraint> TypeConstraints { get; }\n\t}\n\n\tpublic readonly struct TypeConstraint\n\t{\n\t\tpublic SymbolKind SymbolKind => SymbolKind.Constraint;\n\t\tpublic IType Type { get; }\n\t\tpublic IReadOnlyList<IAttribute> Attributes { get; }\n\n\t\tpublic TypeConstraint(IType type, IReadOnlyList<IAttribute>? attributes = null)\n\t\t{\n\t\t\tthis.Type = type ?? throw new ArgumentNullException(nameof(type));\n\t\t\tthis.Attributes = attributes ?? EmptyList<IAttribute>.Instance;\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Represents the variance of a type parameter.\n\t/// </summary>\n\tpublic enum VarianceModifier : byte\n\t{\n\t\t/// <summary>\n\t\t/// The type parameter is not variant.\n\t\t/// </summary>\n\t\tInvariant,\n\t\t/// <summary>\n\t\t/// The type parameter is covariant (used in output position).\n\t\t/// </summary>\n\t\tCovariant,\n\t\t/// <summary>\n\t\t/// The type parameter is contravariant (used in input position).\n\t\t/// </summary>\n\t\tContravariant\n\t};\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/ITypeReference.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Represents a reference to a type.\n\t/// Must be resolved before it can be used as type.\n\t/// </summary>\n\tpublic interface ITypeReference\n\t{\n\t\t// Keep this interface simple: I decided against having GetMethods/GetEvents etc. here,\n\t\t// so that the Resolve step is never hidden from the consumer.\n\n\t\t// I decided against implementing IFreezable here: IUnresolvedTypeDefinition can be used as ITypeReference,\n\t\t// but when freezing the reference, one wouldn't expect the definition to freeze.\n\n\t\t/// <summary>\n\t\t/// Resolves this type reference.\n\t\t/// </summary>\n\t\t/// <param name=\"context\">\n\t\t/// Context to use for resolving this type reference.\n\t\t/// Which kind of context is required depends on the which kind of type reference this is;\n\t\t/// please consult the documentation of the method that was used to create this type reference,\n\t\t/// or that of the class implementing this method.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// Returns the resolved type.\n\t\t/// In case of an error, returns an unknown type (<see cref=\"TypeKind.Unknown\"/>).\n\t\t/// Never returns null.\n\t\t/// </returns>\n\t\tIType Resolve(ITypeResolveContext context);\n\t}\n\n\tpublic interface ITypeResolveContext : ICompilationProvider\n\t{\n\t\t/// <summary>\n\t\t/// Gets the current module.\n\t\t/// This property may return null if this context does not specify any module.\n\t\t/// </summary>\n\t\tIModule? CurrentModule { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the current type definition.\n\t\t/// </summary>\n\t\tITypeDefinition? CurrentTypeDefinition { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the current member.\n\t\t/// </summary>\n\t\tIMember? CurrentMember { get; }\n\n\t\tITypeResolveContext WithCurrentTypeDefinition(ITypeDefinition? typeDefinition);\n\t\tITypeResolveContext WithCurrentMember(IMember? member);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/IVariable.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n#nullable enable\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Represents a variable (name/type pair).\n\t/// </summary>\n\tpublic interface IVariable : ISymbol\n\t{\n\t\t/// <summary>\n\t\t/// Gets the name of the variable.\n\t\t/// </summary>\n\t\tnew string Name { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the type of the variable.\n\t\t/// </summary>\n\t\tIType Type { get; }\n\n\t\t/// <summary>\n\t\t/// Gets whether this variable is a constant (C#-like const).\n\t\t/// </summary>\n\t\tbool IsConst { get; }\n\n\t\t/// <summary>\n\t\t/// If this field is a constant, retrieves the value.\n\t\t/// For parameters, this is the default value.\n\t\t/// </summary>\n\t\tobject? GetConstantValue(bool throwOnInvalidMetadata = false);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractFreezable.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\tpublic static class FreezableHelper\n\t{\n\t\tpublic static void ThrowIfFrozen(IFreezable freezable)\n\t\t{\n\t\t\tif (freezable.IsFrozen)\n\t\t\t\tthrow new InvalidOperationException(\"Cannot mutate frozen \" + freezable.GetType().Name);\n\t\t}\n\n\t\tpublic static IList<T> FreezeListAndElements<T>(IList<T> list)\n\t\t{\n\t\t\tif (list != null)\n\t\t\t{\n\t\t\t\tforeach (T item in list)\n\t\t\t\t\tFreeze(item);\n\t\t\t}\n\t\t\treturn FreezeList(list);\n\t\t}\n\n\t\tpublic static IList<T> FreezeList<T>(IList<T> list)\n\t\t{\n\t\t\tif (list == null || list.Count == 0)\n\t\t\t\treturn EmptyList<T>.Instance;\n\t\t\tif (list.IsReadOnly)\n\t\t\t{\n\t\t\t\t// If the list is already read-only, return it directly.\n\t\t\t\t// This is important, otherwise we might undo the effects of interning.\n\t\t\t\treturn list;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new ReadOnlyCollection<T>(list.ToArray());\n\t\t\t}\n\t\t}\n\n\t\tpublic static void Freeze(object item)\n\t\t{\n\t\t\tIFreezable f = item as IFreezable;\n\t\t\tif (f != null)\n\t\t\t\tf.Freeze();\n\t\t}\n\n\t\tpublic static T FreezeAndReturn<T>(T item) where T : IFreezable\n\t\t{\n\t\t\titem.Freeze();\n\t\t\treturn item;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// If the item is not frozen, this method creates and returns a frozen clone.\n\t\t/// If the item is already frozen, it is returned without creating a clone.\n\t\t/// </summary>\n\t\tpublic static T GetFrozenClone<T>(T item) where T : IFreezable, ICloneable\n\t\t{\n\t\t\tif (!item.IsFrozen)\n\t\t\t{\n\t\t\t\titem = (T)item.Clone();\n\t\t\t\titem.Freeze();\n\t\t\t}\n\t\t\treturn item;\n\t\t}\n\t}\n\n\t[Serializable]\n\tpublic abstract class AbstractFreezable : IFreezable\n\t{\n\t\tbool isFrozen;\n\n\t\t/// <summary>\n\t\t/// Gets if this instance is frozen. Frozen instances are immutable and thus thread-safe.\n\t\t/// </summary>\n\t\tpublic bool IsFrozen {\n\t\t\tget { return isFrozen; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Freezes this instance.\n\t\t/// </summary>\n\t\tpublic void Freeze()\n\t\t{\n\t\t\tif (!isFrozen)\n\t\t\t{\n\t\t\t\tFreezeInternal();\n\t\t\t\tisFrozen = true;\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual void FreezeInternal()\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractType.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Default implementation for IType interface.\n\t/// </summary>\n\t[Serializable]\n\tpublic abstract class AbstractType : IType\n\t{\n\t\tpublic virtual string FullName {\n\t\t\tget {\n\t\t\t\tstring ns = this.Namespace;\n\t\t\t\tstring name = this.Name;\n\t\t\t\tif (string.IsNullOrEmpty(ns))\n\t\t\t\t{\n\t\t\t\t\treturn name;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn ns + \".\" + name;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic abstract string Name { get; }\n\n\t\tpublic virtual string Namespace {\n\t\t\tget { return string.Empty; }\n\t\t}\n\n\t\tpublic virtual string ReflectionName {\n\t\t\tget { return this.FullName; }\n\t\t}\n\n\t\tpublic abstract bool? IsReferenceType { get; }\n\n\t\tpublic virtual bool IsByRefLike => false;\n\n\t\tpublic virtual Nullability Nullability => Nullability.Oblivious;\n\n\t\tpublic virtual IType ChangeNullability(Nullability nullability)\n\t\t{\n\t\t\t// Only some types support nullability, in the default implementation\n\t\t\t// we just ignore the nullability change.\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic abstract TypeKind Kind { get; }\n\n\t\tpublic virtual int TypeParameterCount {\n\t\t\tget { return 0; }\n\t\t}\n\n\t\tpublic virtual IReadOnlyList<ITypeParameter> TypeParameters {\n\t\t\tget { return EmptyList<ITypeParameter>.Instance; }\n\t\t}\n\n\t\tpublic virtual IReadOnlyList<IType> TypeArguments {\n\t\t\tget { return EmptyList<IType>.Instance; }\n\t\t}\n\n\t\tpublic virtual IType DeclaringType {\n\t\t\tget { return null; }\n\t\t}\n\n\t\tpublic virtual ITypeDefinition GetDefinition()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic virtual ITypeDefinitionOrUnknown GetDefinitionOrUnknown()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic virtual IEnumerable<IType> DirectBaseTypes {\n\t\t\tget { return EmptyList<IType>.Instance; }\n\t\t}\n\n\t\tpublic virtual IEnumerable<IType> GetNestedTypes(Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn EmptyList<IType>.Instance;\n\t\t}\n\n\t\tpublic virtual IEnumerable<IType> GetNestedTypes(IReadOnlyList<IType> typeArguments, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn EmptyList<IType>.Instance;\n\t\t}\n\n\t\tpublic virtual IEnumerable<IMethod> GetMethods(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t}\n\n\t\tpublic virtual IEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t}\n\n\t\tpublic virtual IEnumerable<IMethod> GetConstructors(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers)\n\t\t{\n\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t}\n\n\t\tpublic virtual IEnumerable<IProperty> GetProperties(Predicate<IProperty> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn EmptyList<IProperty>.Instance;\n\t\t}\n\n\t\tpublic virtual IEnumerable<IField> GetFields(Predicate<IField> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn EmptyList<IField>.Instance;\n\t\t}\n\n\t\tpublic virtual IEnumerable<IEvent> GetEvents(Predicate<IEvent> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn EmptyList<IEvent>.Instance;\n\t\t}\n\n\t\tpublic virtual IEnumerable<IMember> GetMembers(Predicate<IMember> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tIEnumerable<IMember> members = GetMethods(filter, options);\n\t\t\treturn members\n\t\t\t\t.Concat(GetProperties(filter, options))\n\t\t\t\t.Concat(GetFields(filter, options))\n\t\t\t\t.Concat(GetEvents(filter, options));\n\t\t}\n\n\t\tpublic virtual IEnumerable<IMethod> GetAccessors(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t}\n\n\t\tpublic TypeParameterSubstitution GetSubstitution()\n\t\t{\n\t\t\treturn TypeParameterSubstitution.Identity;\n\t\t}\n\n\t\tpublic TypeParameterSubstitution GetSubstitution(IReadOnlyList<IType> methodTypeArguments)\n\t\t{\n\t\t\treturn TypeParameterSubstitution.Identity;\n\t\t}\n\n\t\tpublic override sealed bool Equals(object obj)\n\t\t{\n\t\t\treturn Equals(obj as IType);\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn base.GetHashCode();\n\t\t}\n\n\t\tpublic virtual bool Equals(IType other)\n\t\t{\n\t\t\treturn this == other; // use reference equality by default\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn this.ReflectionName;\n\t\t}\n\n\t\tpublic virtual IType AcceptVisitor(TypeVisitor visitor)\n\t\t{\n\t\t\treturn visitor.VisitOtherType(this);\n\t\t}\n\n\t\tpublic virtual IType VisitChildren(TypeVisitor visitor)\n\t\t{\n\t\t\treturn this;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractTypeParameter.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\tpublic abstract class AbstractTypeParameter : ITypeParameter, ICompilationProvider\n\t{\n\t\treadonly ICompilation compilation;\n\t\treadonly SymbolKind ownerType;\n\t\treadonly IEntity owner;\n\t\treadonly int index;\n\t\treadonly string name;\n\t\treadonly VarianceModifier variance;\n\n\t\tprotected AbstractTypeParameter(IEntity owner, int index, string name, VarianceModifier variance)\n\t\t{\n\t\t\tif (owner == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(owner));\n\t\t\tthis.owner = owner;\n\t\t\tthis.compilation = owner.Compilation;\n\t\t\tthis.ownerType = owner.SymbolKind;\n\t\t\tthis.index = index;\n\t\t\tthis.name = name ?? ((this.OwnerType == SymbolKind.Method ? \"!!\" : \"!\") + index.ToString(CultureInfo.InvariantCulture));\n\t\t\tthis.variance = variance;\n\t\t}\n\n\t\tprotected AbstractTypeParameter(ICompilation compilation, SymbolKind ownerType, int index, string name, VarianceModifier variance)\n\t\t{\n\t\t\tif (compilation == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(compilation));\n\t\t\tthis.compilation = compilation;\n\t\t\tthis.ownerType = ownerType;\n\t\t\tthis.index = index;\n\t\t\tthis.name = name ?? ((this.OwnerType == SymbolKind.Method ? \"!!\" : \"!\") + index.ToString(CultureInfo.InvariantCulture));\n\t\t\tthis.variance = variance;\n\t\t}\n\n\t\tSymbolKind ISymbol.SymbolKind {\n\t\t\tget { return SymbolKind.TypeParameter; }\n\t\t}\n\n\t\tpublic SymbolKind OwnerType {\n\t\t\tget { return ownerType; }\n\t\t}\n\n\t\tpublic IEntity Owner {\n\t\t\tget { return owner; }\n\t\t}\n\n\t\tpublic int Index {\n\t\t\tget { return index; }\n\t\t}\n\n\t\tpublic abstract IEnumerable<IAttribute> GetAttributes();\n\n\t\tpublic VarianceModifier Variance {\n\t\t\tget { return variance; }\n\t\t}\n\n\t\tpublic ICompilation Compilation {\n\t\t\tget { return compilation; }\n\t\t}\n\n\t\tvolatile IType effectiveBaseClass;\n\n\t\tpublic IType EffectiveBaseClass {\n\t\t\tget {\n\t\t\t\tif (effectiveBaseClass == null)\n\t\t\t\t{\n\t\t\t\t\t// protect against cyclic type parameters\n\t\t\t\t\tusing (var busyLock = BusyManager.Enter(this))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!busyLock.Success)\n\t\t\t\t\t\t\treturn SpecialType.UnknownType; // don't cache this error\n\t\t\t\t\t\teffectiveBaseClass = CalculateEffectiveBaseClass();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn effectiveBaseClass;\n\t\t\t}\n\t\t}\n\n\t\tIType CalculateEffectiveBaseClass()\n\t\t{\n\t\t\tif (HasValueTypeConstraint)\n\t\t\t\treturn this.Compilation.FindType(KnownTypeCode.ValueType);\n\n\t\t\tList<IType> classTypeConstraints = new List<IType>();\n\t\t\tforeach (IType constraint in this.DirectBaseTypes)\n\t\t\t{\n\t\t\t\tif (constraint.Kind == TypeKind.Class)\n\t\t\t\t{\n\t\t\t\t\tclassTypeConstraints.Add(constraint);\n\t\t\t\t}\n\t\t\t\telse if (constraint.Kind == TypeKind.TypeParameter)\n\t\t\t\t{\n\t\t\t\t\tIType baseClass = ((ITypeParameter)constraint).EffectiveBaseClass;\n\t\t\t\t\tif (baseClass.Kind == TypeKind.Class)\n\t\t\t\t\t\tclassTypeConstraints.Add(baseClass);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (classTypeConstraints.Count == 0)\n\t\t\t\treturn this.Compilation.FindType(KnownTypeCode.Object);\n\t\t\t// Find the derived-most type in the resulting set:\n\t\t\tIType result = classTypeConstraints[0];\n\t\t\tfor (int i = 1; i < classTypeConstraints.Count; i++)\n\t\t\t{\n\t\t\t\tif (classTypeConstraints[i].GetDefinition().IsDerivedFrom(result.GetDefinition()))\n\t\t\t\t\tresult = classTypeConstraints[i];\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tIReadOnlyCollection<IType> effectiveInterfaceSet;\n\n\t\tpublic IReadOnlyCollection<IType> EffectiveInterfaceSet {\n\t\t\tget {\n\t\t\t\tvar result = LazyInit.VolatileRead(ref effectiveInterfaceSet);\n\t\t\t\tif (result != null)\n\t\t\t\t{\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// protect against cyclic type parameters\n\t\t\t\t\tusing (var busyLock = BusyManager.Enter(this))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!busyLock.Success)\n\t\t\t\t\t\t\treturn EmptyList<IType>.Instance; // don't cache this error\n\t\t\t\t\t\treturn LazyInit.GetOrSet(ref effectiveInterfaceSet, CalculateEffectiveInterfaceSet());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tIReadOnlyCollection<IType> CalculateEffectiveInterfaceSet()\n\t\t{\n\t\t\tHashSet<IType> result = new HashSet<IType>();\n\t\t\tforeach (IType constraint in this.DirectBaseTypes)\n\t\t\t{\n\t\t\t\tif (constraint.Kind == TypeKind.Interface)\n\t\t\t\t{\n\t\t\t\t\tresult.Add(constraint);\n\t\t\t\t}\n\t\t\t\telse if (constraint.Kind == TypeKind.TypeParameter)\n\t\t\t\t{\n\t\t\t\t\tresult.UnionWith(((ITypeParameter)constraint).EffectiveInterfaceSet);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result.ToArray();\n\t\t}\n\n\t\tpublic abstract bool HasDefaultConstructorConstraint { get; }\n\t\tpublic abstract bool HasReferenceTypeConstraint { get; }\n\t\tpublic abstract bool HasValueTypeConstraint { get; }\n\t\tpublic abstract bool HasUnmanagedConstraint { get; }\n\t\tpublic abstract bool AllowsRefLikeType { get; }\n\t\tpublic abstract Nullability NullabilityConstraint { get; }\n\n\t\tpublic TypeKind Kind {\n\t\t\tget { return TypeKind.TypeParameter; }\n\t\t}\n\n\t\tpublic bool? IsReferenceType {\n\t\t\tget {\n\t\t\t\tif (this.HasValueTypeConstraint)\n\t\t\t\t\treturn false;\n\t\t\t\tif (this.HasReferenceTypeConstraint)\n\t\t\t\t\treturn true;\n\n\t\t\t\t// A type parameter is known to be a reference type if it has the reference type constraint\n\t\t\t\t// or its effective base class is not object or System.ValueType.\n\t\t\t\tIType effectiveBaseClass = this.EffectiveBaseClass;\n\t\t\t\tif (effectiveBaseClass.Kind == TypeKind.Class || effectiveBaseClass.Kind == TypeKind.Delegate)\n\t\t\t\t{\n\t\t\t\t\tITypeDefinition effectiveBaseClassDef = effectiveBaseClass.GetDefinition();\n\t\t\t\t\tif (effectiveBaseClassDef != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tswitch (effectiveBaseClassDef.KnownTypeCode)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase KnownTypeCode.Object:\n\t\t\t\t\t\t\tcase KnownTypeCode.ValueType:\n\t\t\t\t\t\t\tcase KnownTypeCode.Enum:\n\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse if (effectiveBaseClass.Kind == TypeKind.Struct || effectiveBaseClass.Kind == TypeKind.Enum)\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tbool IType.IsByRefLike => false;\n\t\tNullability IType.Nullability => Nullability.Oblivious;\n\n\t\tpublic IType ChangeNullability(Nullability nullability)\n\t\t{\n\t\t\tif (nullability == Nullability.Oblivious)\n\t\t\t\treturn this;\n\t\t\telse\n\t\t\t\treturn new NullabilityAnnotatedTypeParameter(this, nullability);\n\t\t}\n\n\t\tIType IType.DeclaringType {\n\t\t\tget { return null; }\n\t\t}\n\n\t\tint IType.TypeParameterCount {\n\t\t\tget { return 0; }\n\t\t}\n\n\t\tIReadOnlyList<ITypeParameter> IType.TypeParameters {\n\t\t\tget { return EmptyList<ITypeParameter>.Instance; }\n\t\t}\n\n\t\tIReadOnlyList<IType> IType.TypeArguments {\n\t\t\tget { return EmptyList<IType>.Instance; }\n\t\t}\n\n\t\tpublic IEnumerable<IType> DirectBaseTypes {\n\t\t\tget { return TypeConstraints.Select(t => t.Type); }\n\t\t}\n\n\t\tpublic abstract IReadOnlyList<TypeConstraint> TypeConstraints { get; }\n\n\t\tpublic string Name {\n\t\t\tget { return name; }\n\t\t}\n\n\t\tstring INamedElement.Namespace {\n\t\t\tget { return string.Empty; }\n\t\t}\n\n\t\tstring INamedElement.FullName {\n\t\t\tget { return name; }\n\t\t}\n\n\t\tpublic string ReflectionName {\n\t\t\tget {\n\t\t\t\treturn (this.OwnerType == SymbolKind.Method ? \"``\" : \"`\") + index.ToString(CultureInfo.InvariantCulture);\n\t\t\t}\n\t\t}\n\n\t\tITypeDefinition IType.GetDefinition()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tITypeDefinitionOrUnknown IType.GetDefinitionOrUnknown()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic IType AcceptVisitor(TypeVisitor visitor)\n\t\t{\n\t\t\treturn visitor.VisitTypeParameter(this);\n\t\t}\n\n\t\tpublic IType VisitChildren(TypeVisitor visitor)\n\t\t{\n\t\t\treturn this;\n\t\t}\n\n\t\tIEnumerable<IType> IType.GetNestedTypes(Predicate<ITypeDefinition> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn EmptyList<IType>.Instance;\n\t\t}\n\n\t\tIEnumerable<IType> IType.GetNestedTypes(IReadOnlyList<IType> typeArguments, Predicate<ITypeDefinition> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn EmptyList<IType>.Instance;\n\t\t}\n\n\t\tpublic IEnumerable<IMethod> GetConstructors(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t{\n\t\t\t\tif (this.HasDefaultConstructorConstraint || this.HasValueTypeConstraint)\n\t\t\t\t{\n\t\t\t\t\tvar dummyCtor = FakeMethod.CreateDummyConstructor(compilation, this);\n\t\t\t\t\tif (filter == null || filter(dummyCtor))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new[] { dummyCtor };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn GetMembersHelper.GetConstructors(this, filter, options);\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable<IMethod> GetMethods(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t\telse\n\t\t\t\treturn GetMembersHelper.GetMethods(this, FilterNonStatic(filter), options);\n\t\t}\n\n\t\tpublic IEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t\telse\n\t\t\t\treturn GetMembersHelper.GetMethods(this, typeArguments, FilterNonStatic(filter), options);\n\t\t}\n\n\t\tpublic IEnumerable<IProperty> GetProperties(Predicate<IProperty> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t\treturn EmptyList<IProperty>.Instance;\n\t\t\telse\n\t\t\t\treturn GetMembersHelper.GetProperties(this, FilterNonStatic(filter), options);\n\t\t}\n\n\t\tpublic IEnumerable<IField> GetFields(Predicate<IField> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t\treturn EmptyList<IField>.Instance;\n\t\t\telse\n\t\t\t\treturn GetMembersHelper.GetFields(this, FilterNonStatic(filter), options);\n\t\t}\n\n\t\tpublic IEnumerable<IEvent> GetEvents(Predicate<IEvent> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t\treturn EmptyList<IEvent>.Instance;\n\t\t\telse\n\t\t\t\treturn GetMembersHelper.GetEvents(this, FilterNonStatic(filter), options);\n\t\t}\n\n\t\tpublic IEnumerable<IMember> GetMembers(Predicate<IMember> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t\treturn EmptyList<IMember>.Instance;\n\t\t\telse\n\t\t\t\treturn GetMembersHelper.GetMembers(this, FilterNonStatic(filter), options);\n\t\t}\n\n\t\tpublic IEnumerable<IMethod> GetAccessors(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t\telse\n\t\t\t\treturn GetMembersHelper.GetAccessors(this, FilterNonStatic(filter), options);\n\t\t}\n\n\t\tTypeParameterSubstitution IType.GetSubstitution()\n\t\t{\n\t\t\treturn TypeParameterSubstitution.Identity;\n\t\t}\n\n\t\tstatic Predicate<T> FilterNonStatic<T>(Predicate<T> filter) where T : class, IMember\n\t\t{\n\t\t\treturn member => (!member.IsStatic || member.SymbolKind == SymbolKind.Operator || member.IsVirtual)\n\t\t\t\t&& (filter == null || filter(member));\n\t\t}\n\n\t\tpublic sealed override bool Equals(object obj)\n\t\t{\n\t\t\treturn Equals(obj as IType);\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn base.GetHashCode();\n\t\t}\n\n\t\tpublic virtual bool Equals(IType other)\n\t\t{\n\t\t\treturn this == other; // use reference equality for type parameters\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn this.ReflectionName;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/AttributeListBuilder.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.Util;\n\nusing SRM = System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\treadonly struct AttributeListBuilder\n\t{\n\t\treadonly MetadataModule module;\n\t\treadonly List<IAttribute> attributes;\n\n\t\tpublic AttributeListBuilder(MetadataModule module)\n\t\t{\n\t\t\tDebug.Assert(module != null);\n\t\t\tthis.module = module;\n\t\t\tthis.attributes = new List<IAttribute>();\n\t\t}\n\n\t\tpublic AttributeListBuilder(MetadataModule module, int capacity)\n\t\t{\n\t\t\tDebug.Assert(module != null);\n\t\t\tthis.module = module;\n\t\t\tthis.attributes = new List<IAttribute>(capacity);\n\t\t}\n\n\t\tpublic void Add(IAttribute attr)\n\t\t{\n\t\t\tattributes.Add(attr);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Add a builtin attribute without any arguments.\n\t\t/// </summary>\n\t\tpublic void Add(KnownAttribute type)\n\t\t{\n\t\t\t// use the assemblies' cache for simple attributes\n\t\t\tAdd(module.MakeAttribute(type));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Construct a builtin attribute with a single positional argument of known type.\n\t\t/// </summary>\n\t\tpublic void Add(KnownAttribute type, KnownTypeCode argType, object argValue)\n\t\t{\n\t\t\tAdd(type, ImmutableArray.Create(new CustomAttributeTypedArgument<IType>(module.Compilation.FindType(argType), argValue)));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Construct a builtin attribute with a single positional argument of known type.\n\t\t/// </summary>\n\t\tpublic void Add(KnownAttribute type, TopLevelTypeName argType, object argValue)\n\t\t{\n\t\t\tAdd(type, ImmutableArray.Create(new CustomAttributeTypedArgument<IType>(module.Compilation.FindType(argType), argValue)));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Construct a builtin attribute.\n\t\t/// </summary>\n\t\tpublic void Add(KnownAttribute type, ImmutableArray<CustomAttributeTypedArgument<IType>> fixedArguments)\n\t\t{\n\t\t\tAdd(new DefaultAttribute(module.GetAttributeType(type), fixedArguments,\n\t\t\t\tImmutableArray.Create<CustomAttributeNamedArgument<IType>>()));\n\t\t}\n\n\t\t#region MarshalAsAttribute (ConvertMarshalInfo)\n\t\tinternal void AddMarshalInfo(BlobHandle marshalInfo)\n\t\t{\n\t\t\tif (marshalInfo.IsNil)\n\t\t\t\treturn;\n\t\t\tvar metadata = module.metadata;\n\t\t\tAdd(ConvertMarshalInfo(metadata.GetBlobReader(marshalInfo)));\n\t\t}\n\n\t\tconst string InteropServices = \"System.Runtime.InteropServices\";\n\n\t\tIAttribute ConvertMarshalInfo(SRM.BlobReader marshalInfo)\n\t\t{\n\t\t\tvar b = new AttributeBuilder(module, KnownAttribute.MarshalAs);\n\t\t\tIType unmanagedTypeType = module.Compilation.FindType(new TopLevelTypeName(InteropServices, nameof(UnmanagedType)));\n\n\t\t\tint type = marshalInfo.ReadByte();\n\t\t\tb.AddFixedArg(unmanagedTypeType, type);\n\n\t\t\tint size;\n\t\t\tswitch (type)\n\t\t\t{\n\t\t\t\tcase 0x1e: // FixedArray\n\t\t\t\t\tif (!marshalInfo.TryReadCompressedInteger(out size))\n\t\t\t\t\t\tsize = 0;\n\t\t\t\t\tb.AddNamedArg(\"SizeConst\", KnownTypeCode.Int32, size);\n\t\t\t\t\tif (marshalInfo.RemainingBytes > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\ttype = marshalInfo.ReadByte();\n\t\t\t\t\t\tif (type != 0x66) // None\n\t\t\t\t\t\t\tb.AddNamedArg(\"ArraySubType\", unmanagedTypeType, type);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x1d: // SafeArray\n\t\t\t\t\tif (marshalInfo.RemainingBytes > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tVarEnum varType = (VarEnum)marshalInfo.ReadByte();\n\t\t\t\t\t\tif (varType != VarEnum.VT_EMPTY)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar varEnumType = new TopLevelTypeName(InteropServices, nameof(VarEnum));\n\t\t\t\t\t\t\tb.AddNamedArg(\"SafeArraySubType\", varEnumType, (int)varType);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x2a: // NATIVE_TYPE_ARRAY\n\t\t\t\t\tif (marshalInfo.RemainingBytes > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\ttype = marshalInfo.ReadByte();\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\ttype = 0x66; // Cecil uses NativeType.None as default.\n\t\t\t\t\t}\n\t\t\t\t\tif (type != 0x50)\n\t\t\t\t\t{ // Max\n\t\t\t\t\t\tb.AddNamedArg(\"ArraySubType\", unmanagedTypeType, type);\n\t\t\t\t\t}\n\t\t\t\t\tint sizeParameterIndex = marshalInfo.TryReadCompressedInteger(out int value) ? value : -1;\n\t\t\t\t\tsize = marshalInfo.TryReadCompressedInteger(out value) ? value : -1;\n\t\t\t\t\tint sizeParameterMultiplier = marshalInfo.TryReadCompressedInteger(out value) ? value : -1;\n\t\t\t\t\tif (size >= 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tb.AddNamedArg(\"SizeConst\", KnownTypeCode.Int32, size);\n\t\t\t\t\t}\n\t\t\t\t\tif (sizeParameterMultiplier != 0 && sizeParameterIndex >= 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tb.AddNamedArg(\"SizeParamIndex\", KnownTypeCode.Int16, (short)sizeParameterIndex);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x2c: // CustomMarshaler\n\t\t\t\t\tstring guidValue = marshalInfo.ReadSerializedString();\n\t\t\t\t\tstring unmanagedType = marshalInfo.ReadSerializedString();\n\t\t\t\t\tstring managedType = marshalInfo.ReadSerializedString();\n\t\t\t\t\tstring cookie = marshalInfo.ReadSerializedString();\n\t\t\t\t\tif (managedType != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tb.AddNamedArg(\"MarshalType\", KnownTypeCode.String, managedType);\n\t\t\t\t\t}\n\t\t\t\t\tif (!string.IsNullOrEmpty(cookie))\n\t\t\t\t\t{\n\t\t\t\t\t\tb.AddNamedArg(\"MarshalCookie\", KnownTypeCode.String, cookie);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x17: // FixedSysString\n\t\t\t\t\tb.AddNamedArg(\"SizeConst\", KnownTypeCode.Int32, marshalInfo.ReadCompressedInteger());\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\treturn b.Build();\n\t\t}\n\t\t#endregion\n\n\t\t#region Custom Attributes (ReadAttribute)\n\t\tpublic void Add(CustomAttributeHandleCollection attributes, SymbolKind target)\n\t\t{\n\t\t\tvar metadata = module.metadata;\n\t\t\tforeach (var handle in attributes)\n\t\t\t{\n\t\t\t\tvar attribute = metadata.GetCustomAttribute(handle);\n\t\t\t\t// Attribute types shouldn't be open generic, so we don't need a generic context.\n\t\t\t\tvar ctor = module.ResolveMethod(attribute.Constructor, new GenericContext());\n\t\t\t\tvar type = ctor.DeclaringType;\n\t\t\t\tif (IgnoreAttribute(type, target))\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tAdd(new CustomAttribute(module, ctor, handle));\n\t\t\t}\n\t\t}\n\n\t\tbool IgnoreAttribute(IType attributeType, SymbolKind target)\n\t\t{\n\t\t\tif (attributeType.DeclaringType != null || attributeType.TypeParameterCount != 0)\n\t\t\t\treturn false;\n\t\t\treturn IgnoreAttribute(new TopLevelTypeName(attributeType.Namespace, attributeType.Name), target);\n\t\t}\n\n\t\tinternal bool IgnoreAttribute(TopLevelTypeName attributeType, SymbolKind target)\n\t\t{\n\t\t\tswitch (attributeType.Namespace)\n\t\t\t{\n\t\t\t\tcase \"System.Runtime.CompilerServices\":\n\t\t\t\t\tvar options = module.TypeSystemOptions;\n\t\t\t\t\tswitch (attributeType.Name)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase \"DynamicAttribute\":\n\t\t\t\t\t\t\treturn (options & TypeSystemOptions.Dynamic) != 0;\n\t\t\t\t\t\tcase \"NativeIntegerAttribute\":\n\t\t\t\t\t\t\treturn (options & TypeSystemOptions.NativeIntegers) != 0;\n\t\t\t\t\t\tcase \"TupleElementNamesAttribute\":\n\t\t\t\t\t\t\treturn (options & TypeSystemOptions.Tuple) != 0;\n\t\t\t\t\t\tcase \"ExtensionAttribute\":\n\t\t\t\t\t\t\treturn (options & TypeSystemOptions.ExtensionMethods) != 0;\n\t\t\t\t\t\tcase \"DecimalConstantAttribute\":\n\t\t\t\t\t\t\treturn (options & TypeSystemOptions.DecimalConstants) != 0 && (target == SymbolKind.Field || target == SymbolKind.Parameter);\n\t\t\t\t\t\tcase \"IsReadOnlyAttribute\":\n\t\t\t\t\t\t\tswitch (target)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcase SymbolKind.TypeDefinition:\n\t\t\t\t\t\t\t\tcase SymbolKind.Parameter:\n\t\t\t\t\t\t\t\t\treturn (options & TypeSystemOptions.ReadOnlyStructsAndParameters) != 0;\n\t\t\t\t\t\t\t\tcase SymbolKind.Method:\n\t\t\t\t\t\t\t\tcase SymbolKind.Accessor:\n\t\t\t\t\t\t\t\t\treturn (options & TypeSystemOptions.ReadOnlyMethods) != 0;\n\t\t\t\t\t\t\t\tcase SymbolKind.ReturnType:\n\t\t\t\t\t\t\t\tcase SymbolKind.Property:\n\t\t\t\t\t\t\t\tcase SymbolKind.Indexer:\n\t\t\t\t\t\t\t\tcase SymbolKind.Field:\n\t\t\t\t\t\t\t\t\treturn true;  // \"ref readonly\" is currently always active\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\tcase \"IsByRefLikeAttribute\":\n\t\t\t\t\t\t\treturn (options & TypeSystemOptions.RefStructs) != 0 && target == SymbolKind.TypeDefinition;\n\t\t\t\t\t\tcase \"IsUnmanagedAttribute\":\n\t\t\t\t\t\t\treturn (options & TypeSystemOptions.UnmanagedConstraints) != 0 && target == SymbolKind.TypeParameter;\n\t\t\t\t\t\tcase \"NullableAttribute\":\n\t\t\t\t\t\t\treturn (options & TypeSystemOptions.NullabilityAnnotations) != 0;\n\t\t\t\t\t\tcase \"NullableContextAttribute\":\n\t\t\t\t\t\t\treturn (options & TypeSystemOptions.NullabilityAnnotations) != 0\n\t\t\t\t\t\t\t\t&& (target == SymbolKind.TypeDefinition || IsMethodLike(target));\n\t\t\t\t\t\tcase \"ScopedRefAttribute\":\n\t\t\t\t\t\t\treturn (options & TypeSystemOptions.ScopedRef) != 0\n\t\t\t\t\t\t\t\t&& (target == SymbolKind.Parameter);\n\t\t\t\t\t\tcase \"RequiresLocationAttribute\":\n\t\t\t\t\t\t\treturn (options & TypeSystemOptions.RefReadOnlyParameters) != 0\n\t\t\t\t\t\t\t\t&& (target == SymbolKind.Parameter);\n\t\t\t\t\t\tcase \"ParamCollectionAttribute\":\n\t\t\t\t\t\t\treturn (options & TypeSystemOptions.ParamsCollections) != 0\n\t\t\t\t\t\t\t\t&& (target == SymbolKind.Parameter);\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\tcase \"System\":\n\t\t\t\t\treturn attributeType.Name == \"ParamArrayAttribute\" && target == SymbolKind.Parameter;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tinternal bool HasAttribute(MetadataReader metadata, CustomAttributeHandleCollection customAttributes, KnownAttribute attribute, SymbolKind symbolKind)\n\t\t{\n\t\t\tDebug.Assert(attribute.IsCustomAttribute());\n\t\t\tforeach (var h in customAttributes)\n\t\t\t{\n\t\t\t\tvar attr = metadata.GetCustomAttribute(h);\n\t\t\t\tif (attr.IsKnownAttribute(metadata, attribute))\n\t\t\t\t{\n\t\t\t\t\treturn !IgnoreAttribute(attribute.GetTypeName(), symbolKind);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tinternal IAttribute GetAttribute(MetadataReader metadata, CustomAttributeHandleCollection customAttributes, KnownAttribute attribute, SymbolKind symbolKind)\n\t\t{\n\t\t\tDebug.Assert(attribute.IsCustomAttribute());\n\t\t\tforeach (var h in customAttributes)\n\t\t\t{\n\t\t\t\tvar attr = metadata.GetCustomAttribute(h);\n\t\t\t\tif (attr.IsKnownAttribute(metadata, attribute)\n\t\t\t\t\t&& !IgnoreAttribute(attribute.GetTypeName(), symbolKind))\n\t\t\t\t{\n\t\t\t\t\t// Attribute types shouldn't be open generic, so we don't need a generic context.\n\t\t\t\t\tvar ctor = module.ResolveMethod(attr.Constructor, new GenericContext());\n\t\t\t\t\treturn new CustomAttribute(module, ctor, h);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tstatic bool IsMethodLike(SymbolKind kind)\n\t\t{\n\t\t\treturn kind switch {\n\t\t\t\tSymbolKind.Method => true,\n\t\t\t\tSymbolKind.Operator => true,\n\t\t\t\tSymbolKind.Constructor => true,\n\t\t\t\tSymbolKind.Destructor => true,\n\t\t\t\tSymbolKind.Accessor => true,\n\t\t\t\t_ => false\n\t\t\t};\n\t\t}\n\t\t#endregion\n\n\t\t#region Security Attributes\n\t\tpublic void AddSecurityAttributes(DeclarativeSecurityAttributeHandleCollection securityDeclarations)\n\t\t{\n\t\t\tvar metadata = module.metadata;\n\t\t\tforeach (var secDecl in securityDeclarations)\n\t\t\t{\n\t\t\t\tif (secDecl.IsNil)\n\t\t\t\t\tcontinue;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tAddSecurityAttributes(metadata.GetDeclarativeSecurityAttribute(secDecl));\n\t\t\t\t}\n\t\t\t\tcatch (EnumUnderlyingTypeResolveException)\n\t\t\t\t{\n\t\t\t\t\t// ignore resolve errors\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\t// ignore invalid security declarations\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic void AddSecurityAttributes(DeclarativeSecurityAttribute secDecl)\n\t\t{\n\t\t\tvar securityActionType = module.Compilation.FindType(new TopLevelTypeName(\"System.Security.Permissions\", \"SecurityAction\"));\n\t\t\tvar securityAction = new CustomAttributeTypedArgument<IType>(securityActionType, (int)secDecl.Action);\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar reader = metadata.GetBlobReader(secDecl.PermissionSet);\n\t\t\tif (reader.ReadByte() == '.')\n\t\t\t{\n\t\t\t\t// binary attribute\n\t\t\t\tint attributeCount = reader.ReadCompressedInteger();\n\t\t\t\tfor (int i = 0; i < attributeCount; i++)\n\t\t\t\t{\n\t\t\t\t\tAdd(ReadBinarySecurityAttribute(ref reader, securityAction));\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// for backward compatibility with .NET 1.0: XML-encoded attribute\n\t\t\t\treader.Reset();\n\t\t\t\tAdd(ReadXmlSecurityAttribute(ref reader, securityAction));\n\t\t\t}\n\t\t}\n\n\t\tprivate IAttribute ReadXmlSecurityAttribute(ref SRM.BlobReader reader, CustomAttributeTypedArgument<IType> securityAction)\n\t\t{\n\t\t\tstring xml = reader.ReadUTF16(reader.RemainingBytes);\n\t\t\tvar b = new AttributeBuilder(module, KnownAttribute.PermissionSet);\n\t\t\tb.AddFixedArg(securityAction);\n\t\t\tb.AddNamedArg(\"XML\", KnownTypeCode.String, xml);\n\t\t\treturn b.Build();\n\t\t}\n\n\t\tprivate IAttribute ReadBinarySecurityAttribute(ref SRM.BlobReader reader, CustomAttributeTypedArgument<IType> securityAction)\n\t\t{\n\t\t\tstring attributeTypeName = reader.ReadSerializedString();\n\t\t\tIType attributeType = module.TypeProvider.GetTypeFromSerializedName(attributeTypeName);\n\n\t\t\treader.ReadCompressedInteger(); // ??\n\t\t\t\t\t\t\t\t\t\t\t// The specification seems to be incorrect here, so I'm using the logic from Cecil instead.\n\t\t\tint numNamed = reader.ReadCompressedInteger();\n\n\t\t\tvar decoder = new Metadata.CustomAttributeDecoder<IType>(module.TypeProvider, module.metadata);\n\t\t\tvar namedArgs = decoder.DecodeNamedArguments(ref reader, numNamed);\n\n\t\t\treturn new DefaultAttribute(\n\t\t\t\tattributeType,\n\t\t\t\tfixedArguments: ImmutableArray.Create(securityAction),\n\t\t\t\tnamedArguments: namedArgs);\n\t\t}\n\t\t#endregion\n\n\t\tpublic IAttribute[] Build()\n\t\t{\n\t\t\tif (attributes.Count == 0)\n\t\t\t\treturn Empty<IAttribute>.Array;\n\t\t\telse\n\t\t\t\treturn attributes.ToArray();\n\t\t}\n\t}\n\n\tstruct AttributeBuilder\n\t{\n\t\treadonly ICompilation compilation;\n\t\treadonly IType attributeType;\n\t\tImmutableArray<CustomAttributeTypedArgument<IType>>.Builder fixedArgs;\n\t\tImmutableArray<CustomAttributeNamedArgument<IType>>.Builder namedArgs;\n\n\t\tpublic AttributeBuilder(MetadataModule module, KnownAttribute attributeType)\n\t\t\t: this(module, module.GetAttributeType(attributeType))\n\t\t{\n\t\t}\n\n\t\tpublic AttributeBuilder(MetadataModule module, IType attributeType)\n\t\t{\n\t\t\tthis.compilation = module.Compilation;\n\t\t\tthis.attributeType = attributeType;\n\t\t\tthis.fixedArgs = ImmutableArray.CreateBuilder<CustomAttributeTypedArgument<IType>>();\n\t\t\tthis.namedArgs = ImmutableArray.CreateBuilder<CustomAttributeNamedArgument<IType>>();\n\t\t}\n\n\t\tpublic void AddFixedArg(CustomAttributeTypedArgument<IType> arg)\n\t\t{\n\t\t\tfixedArgs.Add(arg);\n\t\t}\n\n\t\tpublic void AddFixedArg(KnownTypeCode type, object value)\n\t\t{\n\t\t\tAddFixedArg(compilation.FindType(type), value);\n\t\t}\n\n\t\tpublic void AddFixedArg(TopLevelTypeName type, object value)\n\t\t{\n\t\t\tAddFixedArg(compilation.FindType(type), value);\n\t\t}\n\n\t\tpublic void AddFixedArg(IType type, object value)\n\t\t{\n\t\t\tfixedArgs.Add(new CustomAttributeTypedArgument<IType>(type, value));\n\t\t}\n\n\t\tpublic void AddNamedArg(string name, KnownTypeCode type, object value)\n\t\t{\n\t\t\tAddNamedArg(name, compilation.FindType(type), value);\n\t\t}\n\n\t\tpublic void AddNamedArg(string name, TopLevelTypeName type, object value)\n\t\t{\n\t\t\tAddNamedArg(name, compilation.FindType(type), value);\n\t\t}\n\n\t\tpublic void AddNamedArg(string name, IType type, object value)\n\t\t{\n\t\t\tCustomAttributeNamedArgumentKind kind;\n\t\t\tif (attributeType.GetFields(f => f.Name == name, GetMemberOptions.ReturnMemberDefinitions).Any())\n\t\t\t\tkind = CustomAttributeNamedArgumentKind.Field;\n\t\t\telse\n\t\t\t\tkind = CustomAttributeNamedArgumentKind.Property;\n\t\t\tnamedArgs.Add(new CustomAttributeNamedArgument<IType>(name, kind, type, value));\n\t\t}\n\n\t\tpublic IAttribute Build()\n\t\t{\n\t\t\treturn new DefaultAttribute(attributeType, fixedArgs.ToImmutable(), namedArgs.ToImmutable());\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/BaseTypeCollector.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Helper class for the GetAllBaseTypes() implementation.\n\t/// </summary>\n\tsealed class BaseTypeCollector : List<IType>\n\t{\n\t\treadonly Stack<IType> activeTypes = new Stack<IType>();\n\n\t\t/// <summary>\n\t\t/// If this option is enabled, the list will not contain interfaces when retrieving the base types\n\t\t/// of a class.\n\t\t/// </summary>\n\t\tinternal bool SkipImplementedInterfaces;\n\n\t\tpublic void CollectBaseTypes(IType type)\n\t\t{\n\t\t\tIType def = type.GetDefinition() ?? type;\n\n\t\t\t// Maintain a stack of currently active type definitions, and avoid having one definition\n\t\t\t// multiple times on that stack.\n\t\t\t// This is necessary to ensure the output is finite in the presence of cyclic inheritance:\n\t\t\t// class C<X> : C<C<X>> {} would not be caught by the 'no duplicate output' check, yet would\n\t\t\t// produce infinite output.\n\t\t\tif (activeTypes.Contains(def))\n\t\t\t\treturn;\n\t\t\tactiveTypes.Push(def);\n\t\t\t// Note that we also need to push non-type definitions, e.g. for protecting against\n\t\t\t// cyclic inheritance in type parameters (where T : S where S : T).\n\t\t\t// The output check doesn't help there because we call Add(type) only at the end.\n\t\t\t// We can't simply call this.Add(type); at the start because that would return in an incorrect order.\n\n\t\t\t// Avoid outputting a type more than once - necessary for \"diamond\" multiple inheritance\n\t\t\t// (e.g. C implements I1 and I2, and both interfaces derive from Object)\n\t\t\tif (!this.Contains(type))\n\t\t\t{\n\t\t\t\tforeach (IType baseType in type.DirectBaseTypes)\n\t\t\t\t{\n\t\t\t\t\tif (SkipImplementedInterfaces && def != null && def.Kind != TypeKind.Interface && def.Kind != TypeKind.TypeParameter)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (baseType.Kind == TypeKind.Interface)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// skip the interface\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tCollectBaseTypes(baseType);\n\t\t\t\t}\n\t\t\t\t// Add(type) at the end - we want a type to be output only after all its base types were added.\n\t\t\t\tthis.Add(type);\n\t\t\t\t// Note that this is not the same as putting the this.Add() call in front and then reversing the list.\n\t\t\t\t// For the diamond inheritance, Add() at the start produces \"C, I1, Object, I2\",\n\t\t\t\t// while Add() at the end produces \"Object, I1, I2, C\".\n\t\t\t}\n\t\t\tactiveTypes.Pop();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/CustomAttribute.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Custom attribute loaded from metadata.\n\t/// </summary>\n\tsealed class CustomAttribute : IAttribute\n\t{\n\t\treadonly MetadataModule module;\n\t\treadonly CustomAttributeHandle handle;\n\t\tpublic IMethod Constructor { get; }\n\n\t\t// lazy-loaded:\n\t\tCustomAttributeValue<IType> value;\n\t\tbool valueDecoded;\n\t\tbool hasDecodeErrors;\n\n\t\tinternal CustomAttribute(MetadataModule module, IMethod attrCtor, CustomAttributeHandle handle)\n\t\t{\n\t\t\tDebug.Assert(module != null);\n\t\t\tDebug.Assert(attrCtor != null);\n\t\t\tDebug.Assert(!handle.IsNil);\n\t\t\tthis.module = module;\n\t\t\tthis.Constructor = attrCtor;\n\t\t\tthis.handle = handle;\n\t\t}\n\n\t\tpublic IType AttributeType => Constructor.DeclaringType;\n\n\t\tpublic ImmutableArray<CustomAttributeTypedArgument<IType>> FixedArguments {\n\t\t\tget {\n\t\t\t\tDecodeValue();\n\t\t\t\treturn value.FixedArguments;\n\t\t\t}\n\t\t}\n\n\t\tpublic ImmutableArray<CustomAttributeNamedArgument<IType>> NamedArguments {\n\t\t\tget {\n\t\t\t\tDecodeValue();\n\t\t\t\treturn value.NamedArguments;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool HasDecodeErrors {\n\t\t\tget {\n\t\t\t\tDecodeValue();\n\t\t\t\treturn hasDecodeErrors;\n\t\t\t}\n\t\t}\n\n\t\tvoid DecodeValue()\n\t\t{\n\t\t\tlock (this)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tif (!valueDecoded)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar metadata = module.metadata;\n\t\t\t\t\t\tvar attr = metadata.GetCustomAttribute(handle);\n\t\t\t\t\t\tvalue = attr.DecodeValue(module.TypeProvider);\n\t\t\t\t\t\tvalueDecoded = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (EnumUnderlyingTypeResolveException)\n\t\t\t\t{\n\t\t\t\t\tvalue = new CustomAttributeValue<IType>(\n\t\t\t\t\t\tImmutableArray<CustomAttributeTypedArgument<IType>>.Empty,\n\t\t\t\t\t\tImmutableArray<CustomAttributeNamedArgument<IType>>.Empty\n\t\t\t\t\t);\n\t\t\t\t\thasDecodeErrors = true;\n\t\t\t\t\tvalueDecoded = true; // in case of errors, never try again.\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\tvalue = new CustomAttributeValue<IType>(\n\t\t\t\t\t\tImmutableArray<CustomAttributeTypedArgument<IType>>.Empty,\n\t\t\t\t\t\tImmutableArray<CustomAttributeNamedArgument<IType>>.Empty\n\t\t\t\t\t);\n\t\t\t\t\thasDecodeErrors = true;\n\t\t\t\t\tvalueDecoded = true; // in case of errors, never try again.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tinternal static IMember MemberForNamedArgument(IType attributeType, CustomAttributeNamedArgument<IType> namedArgument)\n\t\t{\n\t\t\tswitch (namedArgument.Kind)\n\t\t\t{\n\t\t\t\tcase CustomAttributeNamedArgumentKind.Field:\n\t\t\t\t\treturn attributeType.GetFields(f => f.Name == namedArgument.Name).LastOrDefault();\n\t\t\t\tcase CustomAttributeNamedArgumentKind.Property:\n\t\t\t\t\treturn attributeType.GetProperties(p => p.Name == namedArgument.Name).LastOrDefault();\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/DecimalConstantHelper.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\tstatic class DecimalConstantHelper\n\t{\n\t\tpublic static bool AllowsDecimalConstants(MetadataModule module)\n\t\t{\n\t\t\treturn ((module.TypeSystemOptions & TypeSystemOptions.DecimalConstants) == TypeSystemOptions.DecimalConstants);\n\t\t}\n\n\t\tpublic static bool IsDecimalConstant(MetadataModule module, CustomAttributeHandleCollection attributeHandles)\n\t\t{\n\t\t\treturn attributeHandles.HasKnownAttribute(module.metadata, KnownAttribute.DecimalConstant);\n\t\t}\n\n\t\tpublic static object GetDecimalConstantValue(MetadataModule module, CustomAttributeHandleCollection attributeHandles)\n\t\t{\n\t\t\tvar metadata = module.metadata;\n\t\t\tforeach (var attributeHandle in attributeHandles)\n\t\t\t{\n\t\t\t\tvar attribute = metadata.GetCustomAttribute(attributeHandle);\n\t\t\t\tif (attribute.IsKnownAttribute(metadata, KnownAttribute.DecimalConstant))\n\t\t\t\t\treturn TryDecodeDecimalConstantAttribute(module, attribute);\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tstatic decimal? TryDecodeDecimalConstantAttribute(MetadataModule module, System.Reflection.Metadata.CustomAttribute attribute)\n\t\t{\n\t\t\tvar attrValue = attribute.DecodeValue(module.TypeProvider);\n\t\t\tif (attrValue.FixedArguments.Length != 5)\n\t\t\t\treturn null;\n\t\t\t// DecimalConstantAttribute has the arguments (byte scale, byte sign, uint hi, uint mid, uint low) or (byte scale, byte sign, int hi, int mid, int low)\n\t\t\t// Both of these invoke the Decimal constructor (int lo, int mid, int hi, bool isNegative, byte scale) with explicit argument conversions if required.\n\t\t\tif (!(attrValue.FixedArguments[0].Value is byte scale && attrValue.FixedArguments[1].Value is byte sign))\n\t\t\t\treturn null;\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\tif (attrValue.FixedArguments[2].Value is uint hi\n\t\t\t\t\t&& attrValue.FixedArguments[3].Value is uint mid\n\t\t\t\t\t&& attrValue.FixedArguments[4].Value is uint lo)\n\t\t\t\t{\n\t\t\t\t\treturn new decimal((int)lo, (int)mid, (int)hi, sign != 0, scale);\n\t\t\t\t}\n\t\t\t}\n\t\t\t{\n\t\t\t\tif (attrValue.FixedArguments[2].Value is int hi\n\t\t\t\t\t&& attrValue.FixedArguments[3].Value is int mid\n\t\t\t\t\t&& attrValue.FixedArguments[4].Value is int lo)\n\t\t\t\t{\n\t\t\t\t\treturn new decimal(lo, mid, hi, sign != 0, scale);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/DecoratedType.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\tpublic abstract class DecoratedType : IType\n\t{\n\t\tprotected readonly IType baseType;\n\n\t\tprotected DecoratedType(IType baseType)\n\t\t{\n\t\t\tthis.baseType = baseType;\n\t\t}\n\n\t\tTypeKind IType.Kind => baseType.Kind;\n\n\t\tbool? IType.IsReferenceType => baseType.IsReferenceType;\n\n\t\tbool IType.IsByRefLike => baseType.IsByRefLike;\n\n\t\tNullability IType.Nullability => baseType.Nullability;\n\t\tpublic abstract IType ChangeNullability(Nullability nullability);\n\n\t\tIType IType.DeclaringType => baseType.DeclaringType;\n\n\t\tint IType.TypeParameterCount => baseType.TypeParameterCount;\n\n\t\tIReadOnlyList<ITypeParameter> IType.TypeParameters => baseType.TypeParameters;\n\n\t\tIReadOnlyList<IType> IType.TypeArguments => baseType.TypeArguments;\n\n\t\tIEnumerable<IType> IType.DirectBaseTypes => baseType.DirectBaseTypes;\n\n\t\tstring INamedElement.FullName => baseType.FullName;\n\n\t\tstring INamedElement.Name => baseType.Name;\n\n\t\tstring INamedElement.ReflectionName => baseType.ReflectionName;\n\n\t\tstring INamedElement.Namespace => baseType.Namespace;\n\n\t\tpublic abstract IType AcceptVisitor(TypeVisitor visitor);\n\n\t\tpublic abstract bool Equals(IType other);\n\n\t\tIEnumerable<IMethod> IType.GetAccessors(Predicate<IMethod> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn baseType.GetAccessors(filter, options);\n\t\t}\n\n\t\tIEnumerable<IMethod> IType.GetConstructors(Predicate<IMethod> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn baseType.GetConstructors(filter, options);\n\t\t}\n\n\t\tITypeDefinition IType.GetDefinition()\n\t\t{\n\t\t\treturn baseType.GetDefinition();\n\t\t}\n\n\t\tITypeDefinitionOrUnknown IType.GetDefinitionOrUnknown()\n\t\t{\n\t\t\treturn baseType.GetDefinitionOrUnknown();\n\t\t}\n\n\t\tIEnumerable<IEvent> IType.GetEvents(Predicate<IEvent> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn baseType.GetEvents(filter, options);\n\t\t}\n\n\t\tIEnumerable<IField> IType.GetFields(Predicate<IField> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn baseType.GetFields(filter, options);\n\t\t}\n\n\t\tIEnumerable<IMember> IType.GetMembers(Predicate<IMember> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn baseType.GetMembers(filter, options);\n\t\t}\n\n\t\tIEnumerable<IMethod> IType.GetMethods(Predicate<IMethod> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn baseType.GetMethods(filter, options);\n\t\t}\n\n\t\tIEnumerable<IMethod> IType.GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IMethod> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn baseType.GetMethods(typeArguments, filter, options);\n\t\t}\n\n\t\tIEnumerable<IType> IType.GetNestedTypes(Predicate<ITypeDefinition> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn baseType.GetNestedTypes(filter, options);\n\t\t}\n\n\t\tIEnumerable<IType> IType.GetNestedTypes(IReadOnlyList<IType> typeArguments, Predicate<ITypeDefinition> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn baseType.GetNestedTypes(typeArguments, filter, options);\n\t\t}\n\n\t\tIEnumerable<IProperty> IType.GetProperties(Predicate<IProperty> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn baseType.GetProperties(filter, options);\n\t\t}\n\n\t\tTypeParameterSubstitution IType.GetSubstitution()\n\t\t{\n\t\t\treturn baseType.GetSubstitution();\n\t\t}\n\n\t\tpublic abstract IType VisitChildren(TypeVisitor visitor);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultAssemblyReference.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// References an existing assembly by name.\n\t/// </summary>\n\t[Serializable]\n\tpublic sealed class DefaultAssemblyReference : IModuleReference, ISupportsInterning\n\t{\n\t\tpublic static readonly IModuleReference CurrentAssembly = new CurrentModuleReference();\n\n\t\treadonly string shortName;\n\n\t\tpublic DefaultAssemblyReference(string assemblyName)\n\t\t{\n\t\t\tint pos = assemblyName != null ? assemblyName.IndexOf(',') : -1;\n\t\t\tif (pos >= 0)\n\t\t\t\tshortName = assemblyName.Substring(0, pos);\n\t\t\telse\n\t\t\t\tshortName = assemblyName;\n\t\t}\n\n\t\tpublic IModule Resolve(ITypeResolveContext context)\n\t\t{\n\t\t\tIModule current = context.CurrentModule;\n\t\t\tif (current != null && string.Equals(shortName, current.AssemblyName, StringComparison.OrdinalIgnoreCase))\n\t\t\t\treturn current;\n\t\t\tforeach (IModule asm in context.Compilation.Modules)\n\t\t\t{\n\t\t\t\tif (string.Equals(shortName, asm.AssemblyName, StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\treturn asm;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn shortName;\n\t\t}\n\n\t\tint ISupportsInterning.GetHashCodeForInterning()\n\t\t{\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\treturn shortName.GetHashCode();\n\t\t\t}\n\t\t}\n\n\t\tbool ISupportsInterning.EqualsForInterning(ISupportsInterning other)\n\t\t{\n\t\t\tDefaultAssemblyReference o = other as DefaultAssemblyReference;\n\t\t\treturn o != null && shortName == o.shortName;\n\t\t}\n\n\t\t[Serializable]\n\t\tsealed class CurrentModuleReference : IModuleReference\n\t\t{\n\t\t\tpublic IModule Resolve(ITypeResolveContext context)\n\t\t\t{\n\t\t\t\tIModule asm = context.CurrentModule;\n\t\t\t\tif (asm == null)\n\t\t\t\t\tthrow new ArgumentException(\"A reference to the current assembly cannot be resolved in the compilation's global type resolve context.\");\n\t\t\t\treturn asm;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultAttribute.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// IAttribute implementation for already-resolved attributes.\n\t/// </summary>\n\tpublic class DefaultAttribute : IAttribute\n\t{\n\t\treadonly IType attributeType;\n\t\tvolatile IMethod constructor;\n\n\t\tpublic ImmutableArray<CustomAttributeTypedArgument<IType>> FixedArguments { get; }\n\t\tpublic ImmutableArray<CustomAttributeNamedArgument<IType>> NamedArguments { get; }\n\n\t\tpublic DefaultAttribute(IType attributeType,\n\t\t\tImmutableArray<CustomAttributeTypedArgument<IType>> fixedArguments,\n\t\t\tImmutableArray<CustomAttributeNamedArgument<IType>> namedArguments)\n\t\t{\n\t\t\tif (attributeType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(attributeType));\n\t\t\tthis.attributeType = attributeType;\n\t\t\tthis.FixedArguments = fixedArguments;\n\t\t\tthis.NamedArguments = namedArguments;\n\t\t}\n\n\t\tpublic DefaultAttribute(IMethod constructor,\n\t\t\tImmutableArray<CustomAttributeTypedArgument<IType>> fixedArguments,\n\t\t\tImmutableArray<CustomAttributeNamedArgument<IType>> namedArguments)\n\t\t{\n\t\t\tif (constructor == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(constructor));\n\t\t\tthis.constructor = constructor;\n\t\t\tthis.attributeType = constructor.DeclaringType ?? SpecialType.UnknownType;\n\t\t\tthis.FixedArguments = fixedArguments;\n\t\t\tthis.NamedArguments = namedArguments;\n\t\t\tif (fixedArguments.Length != constructor.Parameters.Count)\n\t\t\t{\n\t\t\t\tthrow new ArgumentException(\"Positional argument count must match the constructor's parameter count\");\n\t\t\t}\n\t\t}\n\n\t\tpublic IType AttributeType {\n\t\t\tget { return attributeType; }\n\t\t}\n\n\t\tbool IAttribute.HasDecodeErrors => false;\n\n\t\tpublic IMethod Constructor {\n\t\t\tget {\n\t\t\t\tIMethod ctor = this.constructor;\n\t\t\t\tif (ctor == null)\n\t\t\t\t{\n\t\t\t\t\tforeach (IMethod candidate in this.AttributeType.GetConstructors(m => m.Parameters.Count == FixedArguments.Length))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (candidate.Parameters.Select(p => p.Type).SequenceEqual(this.FixedArguments.Select(a => a.Type)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tctor = candidate;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis.constructor = ctor;\n\t\t\t\t}\n\t\t\t\treturn ctor;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultParameter.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Default implementation of <see cref=\"IParameter\"/>.\n\t/// </summary>\n\tpublic sealed class DefaultParameter : IParameter\n\t{\n\t\treadonly IType type;\n\t\treadonly string name;\n\t\treadonly IReadOnlyList<IAttribute> attributes;\n\t\treadonly ReferenceKind referenceKind;\n\t\treadonly bool isParams, isOptional;\n\t\treadonly object defaultValue;\n\t\treadonly IParameterizedMember owner;\n\n\t\tpublic DefaultParameter(IType type, string name)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tif (name == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(name));\n\t\t\tthis.type = type;\n\t\t\tthis.name = name;\n\t\t\tthis.attributes = EmptyList<IAttribute>.Instance;\n\t\t}\n\n\t\tpublic DefaultParameter(IType type, string name, IParameterizedMember owner = null, IReadOnlyList<IAttribute> attributes = null,\n\t\t\t\t\t\t\t\tReferenceKind referenceKind = ReferenceKind.None, bool isParams = false, bool isOptional = false, object defaultValue = null)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tif (name == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(name));\n\t\t\tthis.type = type;\n\t\t\tthis.name = name;\n\t\t\tthis.owner = owner;\n\t\t\tthis.attributes = attributes ?? EmptyList<IAttribute>.Instance;\n\t\t\tthis.referenceKind = referenceKind;\n\t\t\tthis.isParams = isParams;\n\t\t\tthis.isOptional = isOptional;\n\t\t\tthis.defaultValue = defaultValue;\n\t\t}\n\n\t\tSymbolKind ISymbol.SymbolKind {\n\t\t\tget { return SymbolKind.Parameter; }\n\t\t}\n\n\t\tpublic IParameterizedMember Owner {\n\t\t\tget { return owner; }\n\t\t}\n\n\t\tpublic IEnumerable<IAttribute> GetAttributes() => attributes;\n\n\t\tpublic ReferenceKind ReferenceKind => referenceKind;\n\n\t\tpublic bool IsParams => isParams;\n\n\t\tpublic bool IsOptional => isOptional;\n\n\t\tpublic string Name {\n\t\t\tget { return name; }\n\t\t}\n\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t}\n\n\t\tbool IVariable.IsConst {\n\t\t\tget { return false; }\n\t\t}\n\n\t\tpublic bool HasConstantValueInSignature {\n\t\t\tget { return IsOptional; }\n\t\t}\n\n\t\tpublic LifetimeAnnotation Lifetime => default;\n\n\t\tpublic object GetConstantValue(bool throwOnInvalidMetadata)\n\t\t{\n\t\t\treturn defaultValue;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn ToString(this);\n\t\t}\n\n\t\tpublic static string ToString(IParameter parameter)\n\t\t{\n\t\t\tStringBuilder b = new StringBuilder();\n\t\t\tb.Append(parameter.ReferenceKind switch {\n\t\t\t\tReferenceKind.None => \"\",\n\t\t\t\tReferenceKind.Ref => \"ref \",\n\t\t\t\tReferenceKind.Out => \"out \",\n\t\t\t\tReferenceKind.In => \"in \",\n\t\t\t\tReferenceKind.RefReadOnly => \"ref readonly \",\n\t\t\t\t_ => throw new NotSupportedException()\n\t\t\t});\n\t\t\tif (parameter.IsParams)\n\t\t\t\tb.Append(\"params \");\n\t\t\tb.Append(parameter.Name);\n\t\t\tb.Append(':');\n\t\t\tb.Append(parameter.Type.ReflectionName);\n\t\t\tif (parameter.IsOptional && parameter.HasConstantValueInSignature)\n\t\t\t{\n\t\t\t\tb.Append(\" = \");\n\t\t\t\tobject val = parameter.GetConstantValue(throwOnInvalidMetadata: false);\n\t\t\t\tif (val != null)\n\t\t\t\t\tb.Append(val.ToString());\n\t\t\t\telse\n\t\t\t\t\tb.Append(\"null\");\n\t\t\t}\n\t\t\treturn b.ToString();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultTypeParameter.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\tpublic class DefaultTypeParameter : AbstractTypeParameter\n\t{\n\t\treadonly bool hasValueTypeConstraint;\n\t\treadonly bool hasReferenceTypeConstraint;\n\t\treadonly bool hasDefaultConstructorConstraint;\n\t\treadonly Nullability nullabilityConstraint;\n\t\treadonly IReadOnlyList<IAttribute> attributes;\n\n\t\tpublic DefaultTypeParameter(\n\t\t\tIEntity owner,\n\t\t\tint index, string name = null,\n\t\t\tVarianceModifier variance = VarianceModifier.Invariant,\n\t\t\tIReadOnlyList<IAttribute> attributes = null,\n\t\t\tbool hasValueTypeConstraint = false, bool hasReferenceTypeConstraint = false, bool hasDefaultConstructorConstraint = false,\n\t\t\tIReadOnlyList<IType> constraints = null, Nullability nullabilityConstraint = Nullability.Oblivious)\n\t\t\t: base(owner, index, name, variance)\n\t\t{\n\t\t\tthis.hasValueTypeConstraint = hasValueTypeConstraint;\n\t\t\tthis.hasReferenceTypeConstraint = hasReferenceTypeConstraint;\n\t\t\tthis.hasDefaultConstructorConstraint = hasDefaultConstructorConstraint;\n\t\t\tthis.nullabilityConstraint = nullabilityConstraint;\n\t\t\tthis.TypeConstraints = MakeConstraints(constraints);\n\t\t\tthis.attributes = attributes ?? EmptyList<IAttribute>.Instance;\n\t\t}\n\n\t\tpublic DefaultTypeParameter(\n\t\t\tICompilation compilation, SymbolKind ownerType,\n\t\t\tint index, string name = null,\n\t\t\tVarianceModifier variance = VarianceModifier.Invariant,\n\t\t\tIReadOnlyList<IAttribute> attributes = null,\n\t\t\tbool hasValueTypeConstraint = false, bool hasReferenceTypeConstraint = false, bool hasDefaultConstructorConstraint = false,\n\t\t\tIReadOnlyList<IType> constraints = null, Nullability nullabilityConstraint = Nullability.Oblivious)\n\t\t\t: base(compilation, ownerType, index, name, variance)\n\t\t{\n\t\t\tthis.hasValueTypeConstraint = hasValueTypeConstraint;\n\t\t\tthis.hasReferenceTypeConstraint = hasReferenceTypeConstraint;\n\t\t\tthis.hasDefaultConstructorConstraint = hasDefaultConstructorConstraint;\n\t\t\tthis.nullabilityConstraint = nullabilityConstraint;\n\t\t\tthis.TypeConstraints = MakeConstraints(constraints);\n\t\t\tthis.attributes = attributes ?? EmptyList<IAttribute>.Instance;\n\t\t}\n\n\t\tpublic override IEnumerable<IAttribute> GetAttributes() => attributes;\n\n\t\tpublic override bool HasValueTypeConstraint => hasValueTypeConstraint;\n\t\tpublic override bool HasReferenceTypeConstraint => hasReferenceTypeConstraint;\n\t\tpublic override bool HasDefaultConstructorConstraint => hasDefaultConstructorConstraint;\n\t\tpublic override bool HasUnmanagedConstraint => false;\n\t\tpublic override bool AllowsRefLikeType => false;\n\t\tpublic override Nullability NullabilityConstraint => nullabilityConstraint;\n\n\t\tpublic override IReadOnlyList<TypeConstraint> TypeConstraints { get; }\n\n\t\tIReadOnlyList<TypeConstraint> MakeConstraints(IReadOnlyList<IType> constraints)\n\t\t{\n\t\t\tvar result = new List<TypeConstraint>();\n\t\t\tbool hasNonInterfaceConstraint = false;\n\t\t\tif (constraints != null)\n\t\t\t{\n\t\t\t\tforeach (IType c in constraints)\n\t\t\t\t{\n\t\t\t\t\tresult.Add(new TypeConstraint(c));\n\t\t\t\t\tif (c.Kind != TypeKind.Interface)\n\t\t\t\t\t\thasNonInterfaceConstraint = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Do not add the 'System.Object' constraint if there is another constraint with a base class.\n\t\t\tif (this.HasValueTypeConstraint || !hasNonInterfaceConstraint)\n\t\t\t{\n\t\t\t\tresult.Add(new TypeConstraint(this.Compilation.FindType(this.HasValueTypeConstraint ? KnownTypeCode.ValueType : KnownTypeCode.Object)));\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultVariable.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Default implementation of <see cref=\"IVariable\"/>.\n\t/// </summary>\n\tpublic sealed class DefaultVariable : IVariable\n\t{\n\t\treadonly string name;\n\t\treadonly IType type;\n\t\treadonly object constantValue;\n\t\treadonly bool isConst;\n\n\t\tpublic DefaultVariable(IType type, string name)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tif (name == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(name));\n\t\t\tthis.type = type;\n\t\t\tthis.name = name;\n\t\t}\n\n\t\tpublic DefaultVariable(IType type, string name,\n\t\t\t\t\t\t\t   bool isConst = false, object constantValue = null)\n\t\t\t: this(type, name)\n\t\t{\n\t\t\tthis.isConst = isConst;\n\t\t\tthis.constantValue = constantValue;\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget { return name; }\n\t\t}\n\n\t\tpublic IType Type {\n\t\t\tget { return type; }\n\t\t}\n\n\t\tpublic bool IsConst {\n\t\t\tget { return isConst; }\n\t\t}\n\n\t\tpublic object GetConstantValue(bool throwOnInvalidMetadata)\n\t\t{\n\t\t\treturn constantValue;\n\t\t}\n\n\t\tpublic SymbolKind SymbolKind {\n\t\t\tget { return SymbolKind.Variable; }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/DummyTypeParameter.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\tpublic sealed class DummyTypeParameter : AbstractType, ITypeParameter\n\t{\n\t\tstatic ITypeParameter[] methodTypeParameters = { new DummyTypeParameter(SymbolKind.Method, 0) };\n\t\tstatic ITypeParameter[] classTypeParameters = { new DummyTypeParameter(SymbolKind.TypeDefinition, 0) };\n\t\tstatic IReadOnlyList<ITypeParameter>[] classTypeParameterLists = { EmptyList<ITypeParameter>.Instance };\n\n\t\tpublic static ITypeParameter GetMethodTypeParameter(int index)\n\t\t{\n\t\t\treturn GetTypeParameter(ref methodTypeParameters, SymbolKind.Method, index);\n\t\t}\n\n\t\tpublic static ITypeParameter GetClassTypeParameter(int index)\n\t\t{\n\t\t\treturn GetTypeParameter(ref classTypeParameters, SymbolKind.TypeDefinition, index);\n\t\t}\n\n\t\tstatic ITypeParameter GetTypeParameter(ref ITypeParameter[] typeParameters, SymbolKind symbolKind, int index)\n\t\t{\n\t\t\tITypeParameter[] tps = typeParameters;\n\t\t\twhile (index >= tps.Length)\n\t\t\t{\n\t\t\t\t// We don't have a normal type parameter for this index, so we need to extend our array.\n\t\t\t\t// Because the array can be used concurrently from multiple threads, we have to use\n\t\t\t\t// Interlocked.CompareExchange.\n\t\t\t\tITypeParameter[] newTps = new ITypeParameter[index + 1];\n\t\t\t\ttps.CopyTo(newTps, 0);\n\t\t\t\tfor (int i = tps.Length; i < newTps.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tnewTps[i] = new DummyTypeParameter(symbolKind, i);\n\t\t\t\t}\n\t\t\t\tITypeParameter[] oldTps = Interlocked.CompareExchange(ref typeParameters, newTps, tps);\n\t\t\t\tif (oldTps == tps)\n\t\t\t\t{\n\t\t\t\t\t// exchange successful\n\t\t\t\t\ttps = newTps;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// exchange not successful\n\t\t\t\t\ttps = oldTps;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn tps[index];\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a list filled with dummy type parameters.\n\t\t/// </summary>\n\t\tinternal static IReadOnlyList<ITypeParameter> GetClassTypeParameterList(int length)\n\t\t{\n\t\t\tIReadOnlyList<ITypeParameter>[] tps = classTypeParameterLists;\n\t\t\twhile (length >= tps.Length)\n\t\t\t{\n\t\t\t\t// We don't have a normal type parameter for this index, so we need to extend our array.\n\t\t\t\t// Because the array can be used concurrently from multiple threads, we have to use\n\t\t\t\t// Interlocked.CompareExchange.\n\t\t\t\tIReadOnlyList<ITypeParameter>[] newTps = new IReadOnlyList<ITypeParameter>[length + 1];\n\t\t\t\ttps.CopyTo(newTps, 0);\n\t\t\t\tfor (int i = tps.Length; i < newTps.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tvar newList = new ITypeParameter[i];\n\t\t\t\t\tfor (int j = 0; j < newList.Length; j++)\n\t\t\t\t\t{\n\t\t\t\t\t\tnewList[j] = GetClassTypeParameter(j);\n\t\t\t\t\t}\n\t\t\t\t\tnewTps[i] = newList;\n\t\t\t\t}\n\t\t\t\tvar oldTps = Interlocked.CompareExchange(ref classTypeParameterLists, newTps, tps);\n\t\t\t\tif (oldTps == tps)\n\t\t\t\t{\n\t\t\t\t\t// exchange successful\n\t\t\t\t\ttps = newTps;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// exchange not successful\n\t\t\t\t\ttps = oldTps;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn tps[length];\n\t\t}\n\n\t\treadonly SymbolKind ownerType;\n\t\treadonly int index;\n\n\t\tprivate DummyTypeParameter(SymbolKind ownerType, int index)\n\t\t{\n\t\t\tthis.ownerType = ownerType;\n\t\t\tthis.index = index;\n\t\t}\n\n\t\tSymbolKind ISymbol.SymbolKind {\n\t\t\tget { return SymbolKind.TypeParameter; }\n\t\t}\n\n\t\tpublic override string Name {\n\t\t\tget {\n\t\t\t\treturn (ownerType == SymbolKind.Method ? \"!!\" : \"!\") + index;\n\t\t\t}\n\t\t}\n\n\t\tpublic override string ReflectionName {\n\t\t\tget {\n\t\t\t\treturn (ownerType == SymbolKind.Method ? \"``\" : \"`\") + index;\n\t\t\t}\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn ReflectionName + \" (dummy)\";\n\t\t}\n\n\t\tpublic override bool? IsReferenceType {\n\t\t\tget { return null; }\n\t\t}\n\n\t\tpublic override TypeKind Kind {\n\t\t\tget { return TypeKind.TypeParameter; }\n\t\t}\n\n\t\tpublic override IType AcceptVisitor(TypeVisitor visitor)\n\t\t{\n\t\t\treturn visitor.VisitTypeParameter(this);\n\t\t}\n\n\t\tpublic int Index {\n\t\t\tget { return index; }\n\t\t}\n\n\t\tIEnumerable<IAttribute> ITypeParameter.GetAttributes() => EmptyList<IAttribute>.Instance;\n\n\t\tSymbolKind ITypeParameter.OwnerType {\n\t\t\tget { return ownerType; }\n\t\t}\n\n\t\tVarianceModifier ITypeParameter.Variance {\n\t\t\tget { return VarianceModifier.Invariant; }\n\t\t}\n\n\t\tIEntity ITypeParameter.Owner {\n\t\t\tget { return null; }\n\t\t}\n\n\t\tIType ITypeParameter.EffectiveBaseClass {\n\t\t\tget { return SpecialType.UnknownType; }\n\t\t}\n\n\t\tIReadOnlyCollection<IType> ITypeParameter.EffectiveInterfaceSet {\n\t\t\tget { return EmptyList<IType>.Instance; }\n\t\t}\n\n\t\tbool ITypeParameter.HasDefaultConstructorConstraint => false;\n\t\tbool ITypeParameter.HasReferenceTypeConstraint => false;\n\t\tbool ITypeParameter.HasValueTypeConstraint => false;\n\t\tbool ITypeParameter.HasUnmanagedConstraint => false;\n\t\tbool ITypeParameter.AllowsRefLikeType => false;\n\t\tNullability ITypeParameter.NullabilityConstraint => Nullability.Oblivious;\n\n\t\tIReadOnlyList<TypeConstraint> ITypeParameter.TypeConstraints => EmptyList<TypeConstraint>.Instance;\n\n\t\tpublic override IType ChangeNullability(Nullability nullability)\n\t\t{\n\t\t\tif (nullability == Nullability.Oblivious)\n\t\t\t{\n\t\t\t\treturn this;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new NullabilityAnnotatedTypeParameter(this, nullability);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/FakeMember.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Base class for fake members.\n\t/// </summary>\n\tabstract class FakeMember : IMember\n\t{\n\t\treadonly ICompilation compilation;\n\n\t\tprotected FakeMember(ICompilation compilation)\n\t\t{\n\t\t\tthis.compilation = compilation ?? throw new ArgumentNullException(nameof(compilation));\n\t\t}\n\n\t\tIMember IMember.MemberDefinition => this;\n\n\t\tpublic IType ReturnType { get; set; } = SpecialType.UnknownType;\n\n\t\tIEnumerable<IMember> IMember.ExplicitlyImplementedInterfaceMembers => EmptyList<IMember>.Instance;\n\n\t\tbool IMember.IsExplicitInterfaceImplementation => false;\n\n\t\tbool IMember.IsVirtual => false;\n\t\tbool IMember.IsOverride => false;\n\t\tbool IMember.IsOverridable => false;\n\n\t\tTypeParameterSubstitution IMember.Substitution => TypeParameterSubstitution.Identity;\n\t\tEntityHandle IEntity.MetadataToken => default;\n\n\t\tpublic string Name { get; set; }\n\n\t\tITypeDefinition IEntity.DeclaringTypeDefinition => DeclaringType?.GetDefinition();\n\n\t\tpublic IType DeclaringType { get; set; }\n\n\t\tIModule IEntity.ParentModule => DeclaringType?.GetDefinition()?.ParentModule;\n\n\t\tIEnumerable<IAttribute> IEntity.GetAttributes() => EmptyList<IAttribute>.Instance;\n\t\tbool IEntity.HasAttribute(KnownAttribute attribute) => false;\n\t\tIAttribute IEntity.GetAttribute(KnownAttribute attribute) => null;\n\n\t\tpublic Accessibility Accessibility { get; set; } = Accessibility.Public;\n\n\t\tpublic bool IsStatic { get; set; }\n\t\tbool IEntity.IsAbstract => false;\n\t\tbool IEntity.IsSealed => false;\n\n\t\tpublic abstract SymbolKind SymbolKind { get; }\n\n\t\tICompilation ICompilationProvider.Compilation => compilation;\n\n\t\tstring INamedElement.FullName {\n\t\t\tget {\n\t\t\t\tif (DeclaringType != null)\n\t\t\t\t\treturn DeclaringType.FullName + \".\" + Name;\n\t\t\t\telse\n\t\t\t\t\treturn Name;\n\t\t\t}\n\t\t}\n\n\t\tstring INamedElement.ReflectionName {\n\t\t\tget {\n\t\t\t\tif (DeclaringType != null)\n\t\t\t\t\treturn DeclaringType.ReflectionName + \".\" + Name;\n\t\t\t\telse\n\t\t\t\t\treturn Name;\n\t\t\t}\n\t\t}\n\n\t\tstring INamedElement.Namespace => DeclaringType?.Namespace;\n\n\t\tbool IMember.Equals(IMember obj, TypeVisitor typeNormalization)\n\t\t{\n\t\t\treturn Equals(obj);\n\t\t}\n\n\t\tpublic abstract IMember Specialize(TypeParameterSubstitution substitution);\n\t}\n\n\tclass FakeField : FakeMember, IField\n\t{\n\t\tpublic FakeField(ICompilation compilation) : base(compilation)\n\t\t{\n\t\t}\n\n\t\tbool IField.IsReadOnly => false;\n\t\tbool IField.ReturnTypeIsRefReadOnly => false;\n\t\tbool IField.IsVolatile => false;\n\n\t\tbool IVariable.IsConst => false;\n\t\tobject IVariable.GetConstantValue(bool throwOnInvalidMetadata) => null;\n\t\tIType IVariable.Type => ReturnType;\n\n\t\tpublic override SymbolKind SymbolKind => SymbolKind.Field;\n\n\t\tpublic override IMember Specialize(TypeParameterSubstitution substitution)\n\t\t{\n\t\t\treturn SpecializedField.Create(this, substitution);\n\t\t}\n\t}\n\n\tclass FakeMethod : FakeMember, IMethod\n\t{\n\t\treadonly SymbolKind symbolKind;\n\n\t\tpublic FakeMethod(ICompilation compilation, SymbolKind symbolKind) : base(compilation)\n\t\t{\n\t\t\tthis.symbolKind = symbolKind;\n\t\t}\n\n\t\tpublic override SymbolKind SymbolKind => symbolKind;\n\n\t\tIEnumerable<IAttribute> IMethod.GetReturnTypeAttributes() => EmptyList<IAttribute>.Instance;\n\t\tbool IMethod.ReturnTypeIsRefReadOnly => false;\n\t\tbool IMethod.ThisIsRefReadOnly => false;\n\t\tbool IMethod.IsInitOnly => false;\n\n\t\tpublic IReadOnlyList<ITypeParameter> TypeParameters { get; set; } = EmptyList<ITypeParameter>.Instance;\n\n\t\tIReadOnlyList<IType> IMethod.TypeArguments => TypeParameters;\n\n\t\tbool IMethod.IsExtensionMethod => false;\n\t\tbool IMethod.IsLocalFunction => false;\n\t\tbool IMethod.IsConstructor => symbolKind == SymbolKind.Constructor;\n\t\tbool IMethod.IsDestructor => symbolKind == SymbolKind.Destructor;\n\t\tbool IMethod.IsOperator => symbolKind == SymbolKind.Operator;\n\n\t\tbool IMethod.HasBody => false;\n\t\tpublic bool IsAccessor => AccessorOwner is not null;\n\t\tpublic IMember AccessorOwner { get; set; }\n\t\tpublic MethodSemanticsAttributes AccessorKind { get; set; }\n\n\t\tIMethod IMethod.ReducedFrom => null;\n\n\t\tpublic IReadOnlyList<IParameter> Parameters { get; set; } = EmptyList<IParameter>.Instance;\n\n\t\tpublic override IMember Specialize(TypeParameterSubstitution substitution)\n\t\t{\n\t\t\treturn SpecializedMethod.Create(this, substitution);\n\t\t}\n\n\t\tIMethod IMethod.Specialize(TypeParameterSubstitution substitution)\n\t\t{\n\t\t\treturn SpecializedMethod.Create(this, substitution);\n\t\t}\n\n\t\tinternal static IMethod CreateDummyConstructor(ICompilation compilation, IType declaringType, Accessibility accessibility = Accessibility.Public)\n\t\t{\n\t\t\treturn new FakeMethod(compilation, SymbolKind.Constructor) {\n\t\t\t\tDeclaringType = declaringType,\n\t\t\t\tName = \".ctor\",\n\t\t\t\tReturnType = compilation.FindType(KnownTypeCode.Void),\n\t\t\t\tAccessibility = accessibility,\n\t\t\t};\n\t\t}\n\t}\n\n\tsealed class FakeProperty : FakeMember, IProperty\n\t{\n\t\tpublic FakeProperty(ICompilation compilation)\n\t\t\t: base(compilation)\n\t\t{\n\t\t}\n\n\t\tpublic override SymbolKind SymbolKind\n\t\t\t=> IsIndexer ? SymbolKind.Indexer : SymbolKind.Property;\n\n\t\tpublic override IMember Specialize(TypeParameterSubstitution substitution)\n\t\t\t=> SpecializedProperty.Create(this, substitution);\n\n\t\tpublic bool CanGet => Getter is not null;\n\t\tpublic bool CanSet => Setter is not null;\n\t\tpublic IMethod Getter { get; set; }\n\t\tpublic IMethod Setter { get; set; }\n\t\tpublic bool IsIndexer { get; set; }\n\t\tpublic bool ReturnTypeIsRefReadOnly => false;\n\t\tpublic IReadOnlyList<IParameter> Parameters { get; set; }\n\n\t\tpublic override string ToString() =>\n\t\t\t\"FakeProperty \" + ReturnType + \" \" + DeclaringType.Name + \".\" + Name +\n\t\t\t\t(Parameters.Count == 0\n\t\t\t\t\t? \"\"\n\t\t\t\t\t: \"[\" + string.Join(\", \", Parameters) + \"]\") +\n\t\t\t\t\" { \" +\n\t\t\t\t\t(CanGet ? \"get; \" : \"\") +\n\t\t\t\t\t(CanSet ? \"set; \" : \"\") +\n\t\t\t\t\"}\";\n\t}\n\n\tsealed class FakeEvent : FakeMember, IEvent\n\t{\n\t\tpublic FakeEvent(ICompilation compilation)\n\t\t\t: base(compilation)\n\t\t{ }\n\n\t\tpublic override SymbolKind SymbolKind => SymbolKind.Event;\n\n\t\tpublic override IMember Specialize(TypeParameterSubstitution substitution)\n\t\t\t=> SpecializedEvent.Create(this, substitution);\n\n\t\tpublic bool CanAdd => AddAccessor is not null;\n\t\tpublic bool CanRemove => RemoveAccessor is not null;\n\t\tpublic bool CanInvoke => InvokeAccessor is not null;\n\t\tpublic IMethod AddAccessor { get; set; }\n\t\tpublic IMethod RemoveAccessor { get; set; }\n\t\tpublic IMethod InvokeAccessor { get; set; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/GetMembersHelper.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Provides helper methods for implementing GetMembers() on IType-implementations.\n\t/// Note: GetMembersHelper will recursively call back into IType.GetMembers(), but only with\n\t/// both GetMemberOptions.IgnoreInheritedMembers and GetMemberOptions.ReturnMemberDefinitions set,\n\t/// and only the 'simple' overloads (not taking type arguments).\n\t/// \n\t/// Ensure that your IType implementation does not use the GetMembersHelper if both flags are set,\n\t/// otherwise you'll get a StackOverflowException!\n\t/// </summary>\n\tstatic class GetMembersHelper\n\t{\n\t\t#region GetNestedTypes\n\t\tpublic static IEnumerable<IType> GetNestedTypes(IType type, Predicate<ITypeDefinition> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn GetNestedTypes(type, null, filter, options);\n\t\t}\n\n\t\tpublic static IEnumerable<IType> GetNestedTypes(IType type, IReadOnlyList<IType> nestedTypeArguments, Predicate<ITypeDefinition> filter, GetMemberOptions options)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t{\n\t\t\t\treturn GetNestedTypesImpl(type, nestedTypeArguments, filter, options);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn type.GetNonInterfaceBaseTypes().SelectMany(t => GetNestedTypesImpl(t, nestedTypeArguments, filter, options));\n\t\t\t}\n\t\t}\n\n\t\tstatic IEnumerable<IType> GetNestedTypesImpl(IType outerType, IReadOnlyList<IType> nestedTypeArguments, Predicate<ITypeDefinition> filter, GetMemberOptions options)\n\t\t{\n\t\t\tITypeDefinition outerTypeDef = outerType.GetDefinition();\n\t\t\tif (outerTypeDef == null)\n\t\t\t\tyield break;\n\n\t\t\tint outerTypeParameterCount = outerTypeDef.TypeParameterCount;\n\t\t\tParameterizedType pt = outerType as ParameterizedType;\n\t\t\tforeach (ITypeDefinition nestedType in outerTypeDef.NestedTypes)\n\t\t\t{\n\t\t\t\tint totalTypeParameterCount = nestedType.TypeParameterCount;\n\t\t\t\tif (nestedTypeArguments != null)\n\t\t\t\t{\n\t\t\t\t\tif (totalTypeParameterCount - outerTypeParameterCount != nestedTypeArguments.Count)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!(filter == null || filter(nestedType)))\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (totalTypeParameterCount == 0 || (options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)\n\t\t\t\t{\n\t\t\t\t\tyield return nestedType;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// We need to parameterize the nested type\n\t\t\t\t\tIType[] newTypeArguments = new IType[totalTypeParameterCount];\n\t\t\t\t\tfor (int i = 0; i < outerTypeParameterCount; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tnewTypeArguments[i] = pt != null ? pt.GetTypeArgument(i) : outerTypeDef.TypeParameters[i];\n\t\t\t\t\t}\n\t\t\t\t\tfor (int i = outerTypeParameterCount; i < totalTypeParameterCount; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (nestedTypeArguments != null)\n\t\t\t\t\t\t\tnewTypeArguments[i] = nestedTypeArguments[i - outerTypeParameterCount];\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tnewTypeArguments[i] = SpecialType.UnboundTypeArgument;\n\t\t\t\t\t}\n\t\t\t\t\tyield return new ParameterizedType(nestedType, newTypeArguments);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region GetMethods\n\t\tpublic static IEnumerable<IMethod> GetMethods(IType type, Predicate<IMethod> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn GetMethods(type, null, filter, options);\n\t\t}\n\n\t\tpublic static IEnumerable<IMethod> GetMethods(IType type, IReadOnlyList<IType> typeArguments, Predicate<IMethod> filter, GetMemberOptions options)\n\t\t{\n\t\t\tif (typeArguments != null && typeArguments.Count > 0)\n\t\t\t{\n\t\t\t\tfilter = FilterTypeParameterCount(typeArguments.Count).And(filter);\n\t\t\t}\n\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t{\n\t\t\t\treturn GetMethodsImpl(type, typeArguments, filter, options);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn type.GetNonInterfaceBaseTypes().SelectMany(t => GetMethodsImpl(t, typeArguments, filter, options));\n\t\t\t}\n\t\t}\n\n\t\tstatic Predicate<IMethod> FilterTypeParameterCount(int expectedTypeParameterCount)\n\t\t{\n\t\t\treturn m => m.TypeParameters.Count == expectedTypeParameterCount;\n\t\t}\n\n\t\tconst GetMemberOptions declaredMembers = GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions;\n\n\t\tstatic IEnumerable<IMethod> GetMethodsImpl(IType baseType, IReadOnlyList<IType> methodTypeArguments, Predicate<IMethod> filter, GetMemberOptions options)\n\t\t{\n\t\t\tIEnumerable<IMethod> declaredMethods = baseType.GetMethods(filter, options | declaredMembers);\n\n\t\t\tParameterizedType pt = baseType as ParameterizedType;\n\t\t\tif ((options & GetMemberOptions.ReturnMemberDefinitions) == 0\n\t\t\t\t&& (pt != null || (methodTypeArguments != null && methodTypeArguments.Count > 0)))\n\t\t\t{\n\t\t\t\tTypeParameterSubstitution substitution = null;\n\t\t\t\tforeach (IMethod m in declaredMethods)\n\t\t\t\t{\n\t\t\t\t\tif (methodTypeArguments != null && methodTypeArguments.Count > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (m.TypeParameters.Count != methodTypeArguments.Count)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (substitution == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (pt != null)\n\t\t\t\t\t\t\tsubstitution = pt.GetSubstitution(methodTypeArguments);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tsubstitution = new TypeParameterSubstitution(null, methodTypeArguments);\n\t\t\t\t\t}\n\t\t\t\t\tyield return new SpecializedMethod(m, substitution);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tforeach (IMethod m in declaredMethods)\n\t\t\t\t{\n\t\t\t\t\tyield return m;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region GetAccessors\n\t\tpublic static IEnumerable<IMethod> GetAccessors(IType type, Predicate<IMethod> filter, GetMemberOptions options)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t{\n\t\t\t\treturn GetAccessorsImpl(type, filter, options);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn type.GetNonInterfaceBaseTypes().SelectMany(t => GetAccessorsImpl(t, filter, options));\n\t\t\t}\n\t\t}\n\n\t\tstatic IEnumerable<IMethod> GetAccessorsImpl(IType baseType, Predicate<IMethod> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn GetConstructorsOrAccessorsImpl(baseType, baseType.GetAccessors(filter, options | declaredMembers), options);\n\t\t}\n\t\t#endregion\n\n\t\t#region GetConstructors\n\t\tpublic static IEnumerable<IMethod> GetConstructors(IType type, Predicate<IMethod> filter, GetMemberOptions options)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t{\n\t\t\t\treturn GetConstructorsImpl(type, filter, options);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn type.GetNonInterfaceBaseTypes().SelectMany(t => GetConstructorsImpl(t, filter, options));\n\t\t\t}\n\t\t}\n\n\t\tstatic IEnumerable<IMethod> GetConstructorsImpl(IType baseType, Predicate<IMethod> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn GetConstructorsOrAccessorsImpl(baseType, baseType.GetConstructors(filter, options | declaredMembers), options);\n\t\t}\n\n\t\tstatic IEnumerable<IMethod> GetConstructorsOrAccessorsImpl(IType baseType, IEnumerable<IMethod> declaredMembers, GetMemberOptions options)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)\n\t\t\t{\n\t\t\t\treturn declaredMembers;\n\t\t\t}\n\n\t\t\tParameterizedType pt = baseType as ParameterizedType;\n\t\t\tif (pt != null)\n\t\t\t{\n\t\t\t\tvar substitution = pt.GetSubstitution();\n\t\t\t\treturn declaredMembers.Select(m => new SpecializedMethod(m, substitution) { DeclaringType = pt });\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn declaredMembers;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region GetProperties\n\t\tpublic static IEnumerable<IProperty> GetProperties(IType type, Predicate<IProperty> filter, GetMemberOptions options)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t{\n\t\t\t\treturn GetPropertiesImpl(type, filter, options);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn type.GetNonInterfaceBaseTypes().SelectMany(t => GetPropertiesImpl(t, filter, options));\n\t\t\t}\n\t\t}\n\n\t\tstatic IEnumerable<IProperty> GetPropertiesImpl(IType baseType, Predicate<IProperty> filter, GetMemberOptions options)\n\t\t{\n\t\t\tIEnumerable<IProperty> declaredProperties = baseType.GetProperties(filter, options | declaredMembers);\n\t\t\tif ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)\n\t\t\t{\n\t\t\t\treturn declaredProperties;\n\t\t\t}\n\n\t\t\tParameterizedType pt = baseType as ParameterizedType;\n\t\t\tif (pt != null)\n\t\t\t{\n\t\t\t\tvar substitution = pt.GetSubstitution();\n\t\t\t\treturn declaredProperties.Select(m => new SpecializedProperty(m, substitution) { DeclaringType = pt });\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn declaredProperties;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region GetFields\n\t\tpublic static IEnumerable<IField> GetFields(IType type, Predicate<IField> filter, GetMemberOptions options)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t{\n\t\t\t\treturn GetFieldsImpl(type, filter, options);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn type.GetNonInterfaceBaseTypes().SelectMany(t => GetFieldsImpl(t, filter, options));\n\t\t\t}\n\t\t}\n\n\t\tstatic IEnumerable<IField> GetFieldsImpl(IType baseType, Predicate<IField> filter, GetMemberOptions options)\n\t\t{\n\t\t\tIEnumerable<IField> declaredFields = baseType.GetFields(filter, options | declaredMembers);\n\t\t\tif ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)\n\t\t\t{\n\t\t\t\treturn declaredFields;\n\t\t\t}\n\n\t\t\tParameterizedType pt = baseType as ParameterizedType;\n\t\t\tif (pt != null)\n\t\t\t{\n\t\t\t\tvar substitution = pt.GetSubstitution();\n\t\t\t\treturn declaredFields.Select(m => new SpecializedField(m, substitution) { DeclaringType = pt });\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn declaredFields;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region GetEvents\n\t\tpublic static IEnumerable<IEvent> GetEvents(IType type, Predicate<IEvent> filter, GetMemberOptions options)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t{\n\t\t\t\treturn GetEventsImpl(type, filter, options);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn type.GetNonInterfaceBaseTypes().SelectMany(t => GetEventsImpl(t, filter, options));\n\t\t\t}\n\t\t}\n\n\t\tstatic IEnumerable<IEvent> GetEventsImpl(IType baseType, Predicate<IEvent> filter, GetMemberOptions options)\n\t\t{\n\t\t\tIEnumerable<IEvent> declaredEvents = baseType.GetEvents(filter, options | declaredMembers);\n\t\t\tif ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)\n\t\t\t{\n\t\t\t\treturn declaredEvents;\n\t\t\t}\n\n\t\t\tParameterizedType pt = baseType as ParameterizedType;\n\t\t\tif (pt != null)\n\t\t\t{\n\t\t\t\tvar substitution = pt.GetSubstitution();\n\t\t\t\treturn declaredEvents.Select(m => new SpecializedEvent(m, substitution) { DeclaringType = pt });\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn declaredEvents;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region GetMembers\n\t\tpublic static IEnumerable<IMember> GetMembers(IType type, Predicate<IMember> filter, GetMemberOptions options)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t{\n\t\t\t\treturn GetMembersImpl(type, filter, options);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn type.GetNonInterfaceBaseTypes().SelectMany(t => GetMembersImpl(t, filter, options));\n\t\t\t}\n\t\t}\n\n\t\tstatic IEnumerable<IMember> GetMembersImpl(IType baseType, Predicate<IMember> filter, GetMemberOptions options)\n\t\t{\n\t\t\tforeach (var m in GetMethodsImpl(baseType, null, filter, options))\n\t\t\t\tyield return m;\n\t\t\tforeach (var m in GetPropertiesImpl(baseType, filter, options))\n\t\t\t\tyield return m;\n\t\t\tforeach (var m in GetFieldsImpl(baseType, filter, options))\n\t\t\t\tyield return m;\n\t\t\tforeach (var m in GetEventsImpl(baseType, filter, options))\n\t\t\t\tyield return m;\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/KnownAttributes.cs",
    "content": "// Copyright (c) 2010-2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\tpublic enum KnownAttribute\n\t{\n\t\t/// <summary>\n\t\t/// Not a known attribute\n\t\t/// </summary>\n\t\tNone,\n\n\t\tCompilerGenerated,\n\t\tCompilerFeatureRequired,\n\t\t/// <summary>\n\t\t/// Marks a method as extension method; or a class as containing extension methods.\n\t\t/// </summary>\n\t\tExtension,\n\t\tDynamic,\n\t\tTupleElementNames,\n\t\tNullable,\n\t\tNullableContext,\n\t\tNullablePublicOnly,\n\t\tConditional,\n\t\tObsolete,\n\t\tEmbedded,\n\t\tIsReadOnly,\n\t\tSpecialName,\n\t\tDebuggerHidden,\n\t\tDebuggerStepThrough,\n\t\tDebuggerBrowsable,\n\n\t\t// Assembly attributes:\n\t\tAssemblyVersion,\n\t\tInternalsVisibleTo,\n\t\tTypeForwardedTo,\n\t\tReferenceAssembly,\n\n\t\t// Type attributes:\n\t\tSerializable,\n\t\tFlags,\n\t\tComImport,\n\t\tCoClass,\n\t\tStructLayout,\n\t\tDefaultMember,\n\t\tIsByRefLike,\n\t\tIteratorStateMachine,\n\t\tAsyncStateMachine,\n\t\tAsyncMethodBuilder,\n\t\tAsyncIteratorStateMachine,\n\n\t\t// Field attributes:\n\t\tFieldOffset,\n\t\tNonSerialized,\n\t\tDecimalConstant,\n\t\tFixedBuffer,\n\n\t\t// Method attributes:\n\t\tDllImport,\n\t\tPreserveSig,\n\t\tMethodImpl,\n\n\t\t// Property attributes:\n\t\tIndexerName,\n\n\t\t// Parameter attributes:\n\t\tParamArray,\n\t\tParamCollection,\n\t\tIn,\n\t\tOut,\n\t\tOptional,\n\t\tDefaultParameterValue,\n\t\tCallerMemberName,\n\t\tCallerFilePath,\n\t\tCallerLineNumber,\n\t\tScopedRef,\n\t\tRequiresLocation,\n\n\t\t// Type parameter attributes:\n\t\tIsUnmanaged,\n\n\t\t// Marshalling attributes:\n\t\tMarshalAs,\n\n\t\t// Security attributes:\n\t\tPermissionSet,\n\n\t\t// C# 9 attributes:\n\t\tNativeInteger,\n\t\tPreserveBaseOverrides,\n\t\tUnmanagedCallersOnly,\n\n\t\t// C# 11 attributes:\n\t\tRequired,\n\n\t\t// C# 12 attributes:\n\t\tInlineArray,\n\n\t\t// C# 14 attributes:\n\t\tExtensionMarker,\n\t}\n\n\tpublic static class KnownAttributes\n\t{\n\t\tinternal const int Count = (int)KnownAttribute.ExtensionMarker + 1;\n\n\t\tstatic readonly TopLevelTypeName[] typeNames = new TopLevelTypeName[Count]{\n\t\t\tdefault,\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", nameof(CompilerGeneratedAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", \"CompilerFeatureRequiredAttribute\"),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", nameof(ExtensionAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", nameof(DynamicAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", nameof(TupleElementNamesAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", \"NullableAttribute\"),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", \"NullableContextAttribute\"),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", \"NullablePublicOnlyAttribute\"),\n\t\t\tnew TopLevelTypeName(\"System.Diagnostics\", nameof(ConditionalAttribute)),\n\t\t\tnew TopLevelTypeName(\"System\", nameof(ObsoleteAttribute)),\n\t\t\tnew TopLevelTypeName(\"Microsoft.CodeAnalysis\", \"EmbeddedAttribute\"),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", \"IsReadOnlyAttribute\"),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", nameof(SpecialNameAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Diagnostics\", nameof(DebuggerHiddenAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Diagnostics\", nameof(DebuggerStepThroughAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Diagnostics\", nameof(DebuggerBrowsableAttribute)),\n\t\t\t// Assembly attributes:\n\t\t\tnew TopLevelTypeName(\"System.Reflection\", nameof(AssemblyVersionAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", nameof(InternalsVisibleToAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", nameof(TypeForwardedToAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", nameof(ReferenceAssemblyAttribute)),\n\t\t\t// Type attributes:\n\t\t\tnew TopLevelTypeName(\"System\", nameof(SerializableAttribute)),\n\t\t\tnew TopLevelTypeName(\"System\", nameof(FlagsAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.InteropServices\", nameof(ComImportAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.InteropServices\", nameof(CoClassAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.InteropServices\", nameof(StructLayoutAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Reflection\", nameof(DefaultMemberAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", \"IsByRefLikeAttribute\"),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", nameof(IteratorStateMachineAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", nameof(AsyncStateMachineAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", \"AsyncMethodBuilderAttribute\"),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", \"AsyncIteratorStateMachineAttribute\"),\n\t\t\t// Field attributes:\n\t\t\tnew TopLevelTypeName(\"System.Runtime.InteropServices\", nameof(FieldOffsetAttribute)),\n\t\t\tnew TopLevelTypeName(\"System\", nameof(NonSerializedAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", nameof(DecimalConstantAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", nameof(FixedBufferAttribute)),\n\t\t\t// Method attributes:\n\t\t\tnew TopLevelTypeName(\"System.Runtime.InteropServices\", nameof(DllImportAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.InteropServices\", nameof(PreserveSigAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", nameof(MethodImplAttribute)),\n\t\t\t// Property attributes:\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", nameof(IndexerNameAttribute)),\n\t\t\t// Parameter attributes:\n\t\t\tnew TopLevelTypeName(\"System\", nameof(ParamArrayAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", \"ParamCollectionAttribute\"),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.InteropServices\", nameof(InAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.InteropServices\", nameof(OutAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.InteropServices\", nameof(OptionalAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.InteropServices\", nameof(DefaultParameterValueAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", nameof(CallerMemberNameAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", nameof(CallerFilePathAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", nameof(CallerLineNumberAttribute)),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", \"ScopedRefAttribute\"),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", \"RequiresLocationAttribute\"),\n\t\t\t// Type parameter attributes:\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", \"IsUnmanagedAttribute\"),\n\t\t\t// Marshalling attributes:\n\t\t\tnew TopLevelTypeName(\"System.Runtime.InteropServices\", nameof(MarshalAsAttribute)),\n\t\t\t// Security attributes:\n\t\t\tnew TopLevelTypeName(\"System.Security.Permissions\", \"PermissionSetAttribute\"),\n\t\t\t// C# 9 attributes:\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", \"NativeIntegerAttribute\"),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", \"PreserveBaseOverridesAttribute\"),\n\t\t\tnew TopLevelTypeName(\"System.Runtime.InteropServices\", \"UnmanagedCallersOnlyAttribute\"),\n\t\t\t// C# 11 attributes:\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", \"RequiredMemberAttribute\"),\n\t\t\t// C# 12 attributes:\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", \"InlineArrayAttribute\"),\n\t\t\t// C# 14 attributes:\n\t\t\tnew TopLevelTypeName(\"System.Runtime.CompilerServices\", \"ExtensionMarkerAttribute\"),\n\t\t};\n\n\t\tpublic static ref readonly TopLevelTypeName GetTypeName(this KnownAttribute attr)\n\t\t{\n\t\t\tDebug.Assert(attr != KnownAttribute.None);\n\t\t\treturn ref typeNames[(int)attr];\n\t\t}\n\n\t\tpublic static IType FindType(this ICompilation compilation, KnownAttribute attrType)\n\t\t{\n\t\t\treturn compilation.FindType(attrType.GetTypeName());\n\t\t}\n\n\t\tpublic static KnownAttribute IsKnownAttributeType(this ITypeDefinition attributeType)\n\t\t{\n\t\t\tif (!attributeType.GetNonInterfaceBaseTypes().Any(t => t.IsKnownType(KnownTypeCode.Attribute)))\n\t\t\t\treturn KnownAttribute.None;\n\t\t\tfor (int i = 1; i < typeNames.Length; i++)\n\t\t\t{\n\t\t\t\tif (typeNames[i] == attributeType.FullTypeName)\n\t\t\t\t\treturn (KnownAttribute)i;\n\t\t\t}\n\t\t\treturn KnownAttribute.None;\n\t\t}\n\n\t\tpublic static bool IsCustomAttribute(this KnownAttribute knownAttribute)\n\t\t{\n\t\t\tswitch (knownAttribute)\n\t\t\t{\n\t\t\t\tcase KnownAttribute.Serializable:\n\t\t\t\tcase KnownAttribute.ComImport:\n\t\t\t\tcase KnownAttribute.StructLayout:\n\t\t\t\tcase KnownAttribute.DllImport:\n\t\t\t\tcase KnownAttribute.PreserveSig:\n\t\t\t\tcase KnownAttribute.MethodImpl:\n\t\t\t\tcase KnownAttribute.FieldOffset:\n\t\t\t\tcase KnownAttribute.NonSerialized:\n\t\t\t\tcase KnownAttribute.MarshalAs:\n\t\t\t\tcase KnownAttribute.PermissionSet:\n\t\t\t\tcase KnownAttribute.Optional:\n\t\t\t\tcase KnownAttribute.DefaultParameterValue:\n\t\t\t\tcase KnownAttribute.In:\n\t\t\t\tcase KnownAttribute.Out:\n\t\t\t\tcase KnownAttribute.IndexerName:\n\t\t\t\tcase KnownAttribute.SpecialName:\n\t\t\t\t\treturn false;\n\t\t\t\tdefault:\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/KnownTypeCache.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Cache for KnownTypeReferences.\n\t/// </summary>\n\tsealed class KnownTypeCache\n\t{\n\t\treadonly ICompilation compilation;\n\t\treadonly IType[] knownTypes = new IType[KnownTypeReference.KnownTypeCodeCount];\n\n\t\tpublic KnownTypeCache(ICompilation compilation)\n\t\t{\n\t\t\tthis.compilation = compilation;\n\t\t}\n\n\t\tpublic IType FindType(KnownTypeCode typeCode)\n\t\t{\n\t\t\tIType type = LazyInit.VolatileRead(ref knownTypes[(int)typeCode]);\n\t\t\tif (type != null)\n\t\t\t{\n\t\t\t\treturn type;\n\t\t\t}\n\t\t\treturn LazyInit.GetOrSet(ref knownTypes[(int)typeCode], SearchType(typeCode));\n\t\t}\n\n\t\tIType SearchType(KnownTypeCode typeCode)\n\t\t{\n\t\t\tKnownTypeReference typeRef = KnownTypeReference.Get(typeCode);\n\t\t\tif (typeRef == null)\n\t\t\t\treturn SpecialType.UnknownType;\n\t\t\tvar typeName = new TopLevelTypeName(typeRef.Namespace, typeRef.Name, typeRef.TypeParameterCount);\n\t\t\tforeach (IModule asm in compilation.Modules)\n\t\t\t{\n\t\t\t\tvar typeDef = asm.GetTypeDefinition(typeName);\n\t\t\t\tif (typeDef != null)\n\t\t\t\t\treturn typeDef;\n\t\t\t}\n\t\t\treturn new UnknownType(typeName);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/LocalFunctionMethod.cs",
    "content": "// Copyright (c) 2019 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// A local function has zero or more compiler-generated parameters added at the end.\n\t/// </summary>\n\tclass LocalFunctionMethod : IMethod\n\t{\n\t\treadonly IMethod baseMethod;\n\n\t\tpublic LocalFunctionMethod(IMethod baseMethod, string name, bool isStaticLocalFunction, int numberOfCompilerGeneratedParameters, int numberOfCompilerGeneratedTypeParameters)\n\t\t{\n\t\t\tif (baseMethod == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(baseMethod));\n\t\t\tthis.baseMethod = baseMethod;\n\t\t\tthis.Name = name;\n\t\t\tthis.IsStaticLocalFunction = isStaticLocalFunction;\n\t\t\tthis.NumberOfCompilerGeneratedParameters = numberOfCompilerGeneratedParameters;\n\t\t\tthis.NumberOfCompilerGeneratedTypeParameters = numberOfCompilerGeneratedTypeParameters;\n\t\t}\n\n\t\tpublic bool Equals(IMember obj, TypeVisitor typeNormalization)\n\t\t{\n\t\t\tif (!(obj is LocalFunctionMethod other))\n\t\t\t\treturn false;\n\t\t\treturn baseMethod.Equals(other.baseMethod, typeNormalization)\n\t\t\t\t&& NumberOfCompilerGeneratedParameters == other.NumberOfCompilerGeneratedParameters\n\t\t\t\t&& NumberOfCompilerGeneratedTypeParameters == other.NumberOfCompilerGeneratedTypeParameters\n\t\t\t\t&& IsStaticLocalFunction == other.IsStaticLocalFunction;\n\t\t}\n\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\tif (!(obj is LocalFunctionMethod other))\n\t\t\t\treturn false;\n\t\t\treturn baseMethod.Equals(other.baseMethod)\n\t\t\t\t&& NumberOfCompilerGeneratedParameters == other.NumberOfCompilerGeneratedParameters\n\t\t\t\t&& NumberOfCompilerGeneratedTypeParameters == other.NumberOfCompilerGeneratedTypeParameters\n\t\t\t\t&& IsStaticLocalFunction == other.IsStaticLocalFunction;\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn baseMethod.GetHashCode();\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(\"[LocalFunctionMethod: ReducedFrom={0}, Name={1}, NumberOfGeneratedParameters={2}, NumberOfCompilerGeneratedTypeParameters={3}, IsStaticLocalFunction={4}]\", ReducedFrom, Name, NumberOfCompilerGeneratedParameters, NumberOfCompilerGeneratedTypeParameters, IsStaticLocalFunction);\n\t\t}\n\n\t\tinternal int NumberOfCompilerGeneratedParameters { get; }\n\n\t\tinternal int NumberOfCompilerGeneratedTypeParameters { get; }\n\n\t\tinternal bool IsStaticLocalFunction { get; }\n\n\t\tpublic IMember MemberDefinition => this;\n\n\t\tpublic IType ReturnType => baseMethod.ReturnType;\n\t\tIEnumerable<IMember> IMember.ExplicitlyImplementedInterfaceMembers => baseMethod.ExplicitlyImplementedInterfaceMembers;\n\t\tbool IMember.IsExplicitInterfaceImplementation => baseMethod.IsExplicitInterfaceImplementation;\n\t\tpublic bool IsVirtual => baseMethod.IsVirtual;\n\t\tpublic bool IsOverride => baseMethod.IsOverride;\n\t\tpublic bool IsOverridable => baseMethod.IsOverridable;\n\t\tpublic TypeParameterSubstitution Substitution => baseMethod.Substitution;\n\n\t\tpublic IMethod Specialize(TypeParameterSubstitution substitution)\n\t\t{\n\t\t\treturn new LocalFunctionMethod(\n\t\t\t\tbaseMethod.Specialize(substitution),\n\t\t\t\tName, IsStaticLocalFunction, NumberOfCompilerGeneratedParameters, NumberOfCompilerGeneratedTypeParameters);\n\t\t}\n\n\t\tIMember IMember.Specialize(TypeParameterSubstitution substitution)\n\t\t{\n\t\t\treturn Specialize(substitution);\n\t\t}\n\n\t\tpublic bool IsExtensionMethod => baseMethod.IsExtensionMethod;\n\t\tpublic bool IsLocalFunction => true;\n\t\tpublic bool IsConstructor => baseMethod.IsConstructor;\n\t\tpublic bool IsDestructor => baseMethod.IsDestructor;\n\t\tpublic bool IsOperator => baseMethod.IsOperator;\n\t\tpublic bool HasBody => baseMethod.HasBody;\n\t\tpublic bool IsAccessor => baseMethod.IsAccessor;\n\t\tpublic IMember AccessorOwner => baseMethod.AccessorOwner;\n\t\tpublic MethodSemanticsAttributes AccessorKind => baseMethod.AccessorKind;\n\t\tpublic IMethod ReducedFrom => baseMethod;\n\n\t\tList<ITypeParameter> typeParameters;\n\t\tpublic IReadOnlyList<ITypeParameter> TypeParameters {\n\t\t\tget {\n\t\t\t\tif (typeParameters == null)\n\t\t\t\t\ttypeParameters = new List<ITypeParameter>(baseMethod.TypeParameters.Skip(NumberOfCompilerGeneratedTypeParameters));\n\t\t\t\treturn typeParameters;\n\t\t\t}\n\t\t}\n\n\t\tList<IType> typeArguments;\n\t\tpublic IReadOnlyList<IType> TypeArguments {\n\t\t\tget {\n\t\t\t\tif (typeArguments == null)\n\t\t\t\t\ttypeArguments = new List<IType>(baseMethod.TypeArguments.Skip(NumberOfCompilerGeneratedTypeParameters));\n\t\t\t\treturn typeArguments;\n\t\t\t}\n\t\t}\n\n\t\tList<IParameter> parameters;\n\t\tpublic IReadOnlyList<IParameter> Parameters {\n\t\t\tget {\n\t\t\t\tif (parameters == null)\n\t\t\t\t\tparameters = new List<IParameter>(baseMethod.Parameters.SkipLast(NumberOfCompilerGeneratedParameters));\n\t\t\t\treturn parameters;\n\t\t\t}\n\t\t}\n\n\t\tpublic System.Reflection.Metadata.EntityHandle MetadataToken => baseMethod.MetadataToken;\n\t\tpublic SymbolKind SymbolKind => baseMethod.SymbolKind;\n\t\tpublic ITypeDefinition DeclaringTypeDefinition => baseMethod.DeclaringTypeDefinition;\n\t\tpublic IType DeclaringType => baseMethod.DeclaringType;\n\t\tpublic IModule ParentModule => baseMethod.ParentModule;\n\t\tIEnumerable<IAttribute> IEntity.GetAttributes() => baseMethod.GetAttributes();\n\t\tbool IEntity.HasAttribute(KnownAttribute attribute) => baseMethod.HasAttribute(attribute);\n\t\tIAttribute IEntity.GetAttribute(KnownAttribute attribute) => baseMethod.GetAttribute(attribute);\n\t\tIEnumerable<IAttribute> IMethod.GetReturnTypeAttributes() => baseMethod.GetReturnTypeAttributes();\n\t\tbool IMethod.ReturnTypeIsRefReadOnly => baseMethod.ReturnTypeIsRefReadOnly;\n\t\tbool IMethod.ThisIsRefReadOnly => baseMethod.ThisIsRefReadOnly;\n\t\tbool IMethod.IsInitOnly => baseMethod.IsInitOnly;\n\t\t/// <summary>\n\t\t/// We consider local functions as always static, because they do not have a \"this parameter\".\n\t\t/// Even local functions in instance methods capture this.\n\t\t/// </summary>\n\t\tpublic bool IsStatic => true;\n\t\tpublic bool IsAbstract => baseMethod.IsAbstract;\n\t\tpublic bool IsSealed => baseMethod.IsSealed;\n\n\t\tpublic Accessibility Accessibility => baseMethod.Accessibility;\n\n\t\tpublic string FullName => Name;\n\t\tpublic string Name { get; set; }\n\t\tpublic string ReflectionName => baseMethod.ReflectionName;\n\t\tpublic string Namespace => baseMethod.Namespace;\n\n\t\tpublic ICompilation Compilation => baseMethod.Compilation;\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/MergedNamespace.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// A merged namespace.\n\t/// </summary>\n\tpublic sealed class MergedNamespace : INamespace\n\t{\n\t\treadonly string externAlias;\n\t\treadonly ICompilation compilation;\n\t\treadonly INamespace parentNamespace;\n\t\treadonly INamespace[] namespaces;\n\t\tDictionary<string, INamespace> childNamespaces;\n\n\t\t/// <summary>\n\t\t/// Creates a new merged root namespace.\n\t\t/// </summary>\n\t\t/// <param name=\"compilation\">The main compilation.</param>\n\t\t/// <param name=\"namespaces\">The individual namespaces being merged.</param>\n\t\t/// <param name=\"externAlias\">The extern alias for this namespace.</param>\n\t\tpublic MergedNamespace(ICompilation compilation, INamespace[] namespaces, string externAlias = null)\n\t\t{\n\t\t\tif (compilation == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(compilation));\n\t\t\tif (namespaces == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(namespaces));\n\t\t\tthis.compilation = compilation;\n\t\t\tthis.namespaces = namespaces;\n\t\t\tthis.externAlias = externAlias;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a new merged child namespace.\n\t\t/// </summary>\n\t\t/// <param name=\"parentNamespace\">The parent merged namespace.</param>\n\t\t/// <param name=\"namespaces\">The individual namespaces being merged.</param>\n\t\tpublic MergedNamespace(INamespace parentNamespace, INamespace[] namespaces)\n\t\t{\n\t\t\tif (parentNamespace == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(parentNamespace));\n\t\t\tif (namespaces == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(namespaces));\n\t\t\tthis.parentNamespace = parentNamespace;\n\t\t\tthis.namespaces = namespaces;\n\t\t\tthis.compilation = parentNamespace.Compilation;\n\t\t\tthis.externAlias = parentNamespace.ExternAlias;\n\t\t}\n\n\t\tpublic string ExternAlias {\n\t\t\tget { return externAlias; }\n\t\t}\n\n\t\tpublic string FullName {\n\t\t\tget { return namespaces[0].FullName; }\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget { return namespaces[0].Name; }\n\t\t}\n\n\t\tpublic INamespace ParentNamespace {\n\t\t\tget { return parentNamespace; }\n\t\t}\n\n\t\tpublic IEnumerable<ITypeDefinition> Types {\n\t\t\tget {\n\t\t\t\treturn namespaces.SelectMany(ns => ns.Types);\n\t\t\t}\n\t\t}\n\n\t\tpublic SymbolKind SymbolKind {\n\t\t\tget { return SymbolKind.Namespace; }\n\t\t}\n\n\t\tpublic ICompilation Compilation {\n\t\t\tget { return compilation; }\n\t\t}\n\n\t\tpublic IEnumerable<IModule> ContributingModules {\n\t\t\tget { return namespaces.SelectMany(ns => ns.ContributingModules); }\n\t\t}\n\n\t\tpublic IEnumerable<INamespace> ChildNamespaces {\n\t\t\tget { return GetChildNamespaces().Values; }\n\t\t}\n\n\t\tpublic INamespace GetChildNamespace(string name)\n\t\t{\n\t\t\tINamespace ns;\n\t\t\tif (GetChildNamespaces().TryGetValue(name, out ns))\n\t\t\t\treturn ns;\n\t\t\telse\n\t\t\t\treturn null;\n\t\t}\n\n\t\tDictionary<string, INamespace> GetChildNamespaces()\n\t\t{\n\t\t\tvar result = LazyInit.VolatileRead(ref this.childNamespaces);\n\t\t\tif (result != null)\n\t\t\t{\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tresult = new Dictionary<string, INamespace>(compilation.NameComparer);\n\t\t\t\tforeach (var g in namespaces.SelectMany(ns => ns.ChildNamespaces).GroupBy(ns => ns.Name, compilation.NameComparer))\n\t\t\t\t{\n\t\t\t\t\tresult.Add(g.Key, new MergedNamespace(this, g.ToArray()));\n\t\t\t\t}\n\t\t\t\treturn LazyInit.GetOrSet(ref this.childNamespaces, result);\n\t\t\t}\n\t\t}\n\n\t\tpublic ITypeDefinition GetTypeDefinition(string name, int typeParameterCount)\n\t\t{\n\t\t\tITypeDefinition anyTypeDef = null;\n\t\t\tforeach (var ns in namespaces)\n\t\t\t{\n\t\t\t\tITypeDefinition typeDef = ns.GetTypeDefinition(name, typeParameterCount);\n\t\t\t\tif (typeDef != null)\n\t\t\t\t{\n\t\t\t\t\tif (typeDef.Accessibility == Accessibility.Public)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Prefer accessible types over non-accessible types.\n\t\t\t\t\t\treturn typeDef;\n\t\t\t\t\t\t// || (typeDef.IsInternal && typeDef.ParentAssembly.InternalsVisibleTo(...))\n\t\t\t\t\t\t// We can't call InternalsVisibleTo() here as we don't know the correct 'current' assembly,\n\t\t\t\t\t\t// and using the main assembly can cause a stack overflow if there\n\t\t\t\t\t\t// are internal assembly attributes.\n\t\t\t\t\t}\n\t\t\t\t\tanyTypeDef = typeDef;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn anyTypeDef;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(CultureInfo.InvariantCulture, \"[MergedNamespace {0}{1} (from {2} assemblies)]\",\n\t\t\t\t\t\t\t\t externAlias != null ? externAlias + \"::\" : null, this.FullName, this.namespaces.Length);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataEvent.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\tsealed class MetadataEvent : IEvent\n\t{\n\t\treadonly MetadataModule module;\n\t\treadonly EventDefinitionHandle handle;\n\t\treadonly EventAccessors accessors;\n\t\treadonly string name;\n\n\t\t// lazy-loaded:\n\t\tIType returnType;\n\n\t\tinternal MetadataEvent(MetadataModule module, EventDefinitionHandle handle)\n\t\t{\n\t\t\tDebug.Assert(module != null);\n\t\t\tDebug.Assert(!handle.IsNil);\n\t\t\tthis.module = module;\n\t\t\tthis.handle = handle;\n\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar ev = metadata.GetEventDefinition(handle);\n\t\t\taccessors = ev.GetAccessors();\n\t\t\tname = metadata.GetString(ev.Name);\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn $\"{MetadataTokens.GetToken(handle):X8} {DeclaringType?.ReflectionName}.{Name}\";\n\t\t}\n\n\t\tpublic EntityHandle MetadataToken => handle;\n\t\tpublic string Name => name;\n\n\t\tSymbolKind ISymbol.SymbolKind => SymbolKind.Event;\n\n\t\tpublic bool CanAdd => !accessors.Adder.IsNil;\n\t\tpublic bool CanRemove => !accessors.Remover.IsNil;\n\t\tpublic bool CanInvoke => !accessors.Raiser.IsNil;\n\t\tpublic IMethod AddAccessor => module.GetDefinition(accessors.Adder);\n\t\tpublic IMethod RemoveAccessor => module.GetDefinition(accessors.Remover);\n\t\tpublic IMethod InvokeAccessor => module.GetDefinition(accessors.Raiser);\n\t\tIMethod AnyAccessor => module.GetDefinition(accessors.GetAny());\n\n\t\t#region Signature (ReturnType + Parameters)\n\t\tpublic IType ReturnType {\n\t\t\tget {\n\t\t\t\tvar returnType = LazyInit.VolatileRead(ref this.returnType);\n\t\t\t\tif (returnType != null)\n\t\t\t\t\treturn returnType;\n\t\t\t\tvar metadata = module.metadata;\n\t\t\t\tvar ev = metadata.GetEventDefinition(handle);\n\t\t\t\tvar declaringTypeDef = DeclaringTypeDefinition;\n\t\t\t\tvar context = new GenericContext(declaringTypeDef?.TypeParameters);\n\t\t\t\tvar nullableContext = declaringTypeDef?.NullableContext ?? Nullability.Oblivious;\n\t\t\t\t// The event does not have explicit accessibility in metadata, so use its\n\t\t\t\t// containing type to determine whether nullability applies to this type.\n\t\t\t\tvar typeOptions = module.OptionsForEntity(declaringTypeDef);\n\t\t\t\treturnType = module.ResolveType(ev.Type, context, typeOptions, ev.GetCustomAttributes(), nullableContext);\n\t\t\t\treturn LazyInit.GetOrSet(ref this.returnType, returnType);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic bool IsExplicitInterfaceImplementation => AnyAccessor?.IsExplicitInterfaceImplementation ?? false;\n\t\tpublic IEnumerable<IMember> ExplicitlyImplementedInterfaceMembers => GetInterfaceMembersFromAccessor(AnyAccessor);\n\n\t\tinternal static IEnumerable<IMember> GetInterfaceMembersFromAccessor(IMethod method)\n\t\t{\n\t\t\tif (method == null)\n\t\t\t\treturn EmptyList<IMember>.Instance;\n\t\t\treturn method.ExplicitlyImplementedInterfaceMembers.Select(m => ((IMethod)m).AccessorOwner).Where(m => m != null);\n\t\t}\n\n\t\tpublic ITypeDefinition DeclaringTypeDefinition => AnyAccessor?.DeclaringTypeDefinition;\n\t\tpublic IType DeclaringType => AnyAccessor?.DeclaringType;\n\t\tIMember IMember.MemberDefinition => this;\n\t\tTypeParameterSubstitution IMember.Substitution => TypeParameterSubstitution.Identity;\n\n\t\t#region Attributes\n\t\tpublic IEnumerable<IAttribute> GetAttributes()\n\t\t{\n\t\t\tvar b = new AttributeListBuilder(module);\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar eventDef = metadata.GetEventDefinition(handle);\n\n\t\t\t// SpecialName\n\t\t\tif ((eventDef.Attributes & (EventAttributes.SpecialName | EventAttributes.RTSpecialName)) == EventAttributes.SpecialName)\n\t\t\t{\n\t\t\t\tb.Add(KnownAttribute.SpecialName);\n\t\t\t}\n\n\t\t\tb.Add(eventDef.GetCustomAttributes(), SymbolKind.Event);\n\t\t\treturn b.Build();\n\t\t}\n\n\t\tpublic bool HasAttribute(KnownAttribute attribute)\n\t\t{\n\t\t\tif (!attribute.IsCustomAttribute())\n\t\t\t{\n\t\t\t\treturn GetAttributes().Any(attr => attr.AttributeType.IsKnownType(attribute));\n\t\t\t}\n\t\t\tvar b = new AttributeListBuilder(module);\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar def = metadata.GetEventDefinition(handle);\n\t\t\treturn b.HasAttribute(metadata, def.GetCustomAttributes(), attribute, SymbolKind.Event);\n\t\t}\n\n\t\tpublic IAttribute GetAttribute(KnownAttribute attribute)\n\t\t{\n\t\t\tif (!attribute.IsCustomAttribute())\n\t\t\t{\n\t\t\t\treturn GetAttributes().FirstOrDefault(attr => attr.AttributeType.IsKnownType(attribute));\n\t\t\t}\n\t\t\tvar b = new AttributeListBuilder(module);\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar def = metadata.GetEventDefinition(handle);\n\t\t\treturn b.GetAttribute(metadata, def.GetCustomAttributes(), attribute, SymbolKind.Event);\n\t\t}\n\t\t#endregion\n\n\t\tpublic Accessibility Accessibility => AnyAccessor?.Accessibility ?? Accessibility.None;\n\t\tpublic bool IsStatic => AnyAccessor?.IsStatic ?? false;\n\t\tpublic bool IsAbstract => AnyAccessor?.IsAbstract ?? false;\n\t\tpublic bool IsSealed => AnyAccessor?.IsSealed ?? false;\n\t\tpublic bool IsVirtual => AnyAccessor?.IsVirtual ?? false;\n\t\tpublic bool IsOverride => AnyAccessor?.IsOverride ?? false;\n\t\tpublic bool IsOverridable => AnyAccessor?.IsOverridable ?? false;\n\n\t\tpublic IModule ParentModule => module;\n\t\tpublic ICompilation Compilation => module.Compilation;\n\n\t\tpublic string FullName => $\"{DeclaringType?.FullName}.{Name}\";\n\t\tpublic string ReflectionName => $\"{DeclaringType?.ReflectionName}.{Name}\";\n\t\tpublic string Namespace => DeclaringType?.Namespace ?? string.Empty;\n\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\tif (obj is MetadataEvent ev)\n\t\t\t{\n\t\t\t\treturn handle == ev.handle && module.MetadataFile == ev.module.MetadataFile;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn 0x7937039a ^ module.MetadataFile.GetHashCode() ^ handle.GetHashCode();\n\t\t}\n\n\t\tbool IMember.Equals(IMember obj, TypeVisitor typeNormalization)\n\t\t{\n\t\t\treturn Equals(obj);\n\t\t}\n\n\t\tpublic IMember Specialize(TypeParameterSubstitution substitution)\n\t\t{\n\t\t\treturn SpecializedEvent.Create(this, substitution);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataField.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Field definition backed by System.Reflection.Metadata\n\t/// </summary>\n\tsealed class MetadataField : IField\n\t{\n\t\treadonly MetadataModule module;\n\t\treadonly FieldDefinitionHandle handle;\n\t\treadonly FieldAttributes attributes;\n\n\t\t// lazy-loaded fields:\n\t\tITypeDefinition declaringType;\n\t\tstring name;\n\t\tobject constantValue;\n\t\tIType type;\n\t\tbool isVolatile; // initialized together with this.type\n\t\t\t\t\t\t // this can't be bool? as bool? is not thread-safe from torn reads\n\t\tbyte decimalConstantState;\n\n\t\tinternal MetadataField(MetadataModule module, FieldDefinitionHandle handle)\n\t\t{\n\t\t\tDebug.Assert(module != null);\n\t\t\tDebug.Assert(!handle.IsNil);\n\t\t\tthis.module = module;\n\t\t\tthis.handle = handle;\n\t\t\tvar def = module.metadata.GetFieldDefinition(handle);\n\t\t\tthis.attributes = def.Attributes;\n\n\t\t\tif ((attributes & (FieldAttributes.Static | FieldAttributes.InitOnly)) != (FieldAttributes.Static | FieldAttributes.InitOnly))\n\t\t\t\tdecimalConstantState = ThreeState.False;\n\t\t}\n\n\t\tpublic EntityHandle MetadataToken => handle;\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn $\"{MetadataTokens.GetToken(handle):X8} {DeclaringType?.ReflectionName}.{Name}\";\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget {\n\t\t\t\tstring name = LazyInit.VolatileRead(ref this.name);\n\t\t\t\tif (name != null)\n\t\t\t\t\treturn name;\n\t\t\t\tvar metadata = module.metadata;\n\t\t\t\tvar fieldDef = metadata.GetFieldDefinition(handle);\n\t\t\t\treturn LazyInit.GetOrSet(ref this.name, metadata.GetString(fieldDef.Name));\n\t\t\t}\n\t\t}\n\n\t\tpublic Accessibility Accessibility {\n\t\t\tget {\n\t\t\t\tswitch (attributes & FieldAttributes.FieldAccessMask)\n\t\t\t\t{\n\t\t\t\t\tcase FieldAttributes.Public:\n\t\t\t\t\t\treturn Accessibility.Public;\n\t\t\t\t\tcase FieldAttributes.FamANDAssem:\n\t\t\t\t\t\treturn Accessibility.ProtectedAndInternal;\n\t\t\t\t\tcase FieldAttributes.Assembly:\n\t\t\t\t\t\treturn Accessibility.Internal;\n\t\t\t\t\tcase FieldAttributes.Family:\n\t\t\t\t\t\treturn Accessibility.Protected;\n\t\t\t\t\tcase FieldAttributes.FamORAssem:\n\t\t\t\t\t\treturn Accessibility.ProtectedOrInternal;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn Accessibility.Private;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic bool IsReadOnly => (attributes & FieldAttributes.InitOnly) != 0;\n\t\tpublic bool IsStatic => (attributes & FieldAttributes.Static) != 0;\n\n\t\tSymbolKind ISymbol.SymbolKind => SymbolKind.Field;\n\t\tIMember IMember.MemberDefinition => this;\n\t\tTypeParameterSubstitution IMember.Substitution => TypeParameterSubstitution.Identity;\n\n\t\t// Fields can't implement interfaces:\n\t\tIEnumerable<IMember> IMember.ExplicitlyImplementedInterfaceMembers => EmptyList<IMember>.Instance;\n\t\tbool IMember.IsExplicitInterfaceImplementation => false;\n\t\tbool IMember.IsVirtual => false;\n\t\tbool IMember.IsOverride => false;\n\t\tbool IMember.IsOverridable => false;\n\t\tbool IEntity.IsAbstract => false;\n\t\tbool IEntity.IsSealed => false;\n\n\t\tpublic ITypeDefinition DeclaringTypeDefinition {\n\t\t\tget {\n\t\t\t\tvar declType = LazyInit.VolatileRead(ref this.declaringType);\n\t\t\t\tif (declType != null)\n\t\t\t\t{\n\t\t\t\t\treturn declType;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar def = module.metadata.GetFieldDefinition(handle);\n\t\t\t\t\treturn LazyInit.GetOrSet(ref this.declaringType,\n\t\t\t\t\t\tmodule.GetDefinition(def.GetDeclaringType()));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic IType DeclaringType => DeclaringTypeDefinition;\n\t\tpublic IModule ParentModule => module;\n\t\tpublic ICompilation Compilation => module.Compilation;\n\n\t\tpublic IEnumerable<IAttribute> GetAttributes()\n\t\t{\n\t\t\tvar b = new AttributeListBuilder(module);\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar fieldDef = metadata.GetFieldDefinition(handle);\n\n\t\t\t// FieldOffsetAttribute\n\t\t\tint offset = fieldDef.GetOffset();\n\t\t\tif (offset != -1)\n\t\t\t{\n\t\t\t\tb.Add(KnownAttribute.FieldOffset, KnownTypeCode.Int32, offset);\n\t\t\t}\n\n\t\t\t// NonSerializedAttribute\n\t\t\tif ((fieldDef.Attributes & FieldAttributes.NotSerialized) != 0)\n\t\t\t{\n\t\t\t\tb.Add(KnownAttribute.NonSerialized);\n\t\t\t}\n\n\t\t\t// SpecialName\n\t\t\tif ((fieldDef.Attributes & (FieldAttributes.SpecialName | FieldAttributes.RTSpecialName)) == FieldAttributes.SpecialName)\n\t\t\t{\n\t\t\t\tb.Add(KnownAttribute.SpecialName);\n\t\t\t}\n\n\t\t\tb.AddMarshalInfo(fieldDef.GetMarshallingDescriptor());\n\t\t\tb.Add(fieldDef.GetCustomAttributes(), SymbolKind.Field);\n\n\t\t\treturn b.Build();\n\t\t}\n\n\t\tpublic bool HasAttribute(KnownAttribute attribute)\n\t\t{\n\t\t\tif (!attribute.IsCustomAttribute())\n\t\t\t{\n\t\t\t\treturn GetAttributes().Any(attr => attr.AttributeType.IsKnownType(attribute));\n\t\t\t}\n\t\t\tvar b = new AttributeListBuilder(module);\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar def = metadata.GetFieldDefinition(handle);\n\t\t\treturn b.HasAttribute(metadata, def.GetCustomAttributes(), attribute, SymbolKind.Field);\n\t\t}\n\n\t\tpublic IAttribute GetAttribute(KnownAttribute attribute)\n\t\t{\n\t\t\tif (!attribute.IsCustomAttribute())\n\t\t\t{\n\t\t\t\treturn GetAttributes().FirstOrDefault(attr => attr.AttributeType.IsKnownType(attribute));\n\t\t\t}\n\t\t\tvar b = new AttributeListBuilder(module);\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar def = metadata.GetFieldDefinition(handle);\n\t\t\treturn b.GetAttribute(metadata, def.GetCustomAttributes(), attribute, SymbolKind.Field);\n\t\t}\n\n\t\tpublic bool ReturnTypeIsRefReadOnly {\n\t\t\tget {\n\t\t\t\tvar def = module.metadata.GetFieldDefinition(handle);\n\t\t\t\treturn def.GetCustomAttributes().HasKnownAttribute(module.metadata, KnownAttribute.IsReadOnly);\n\t\t\t}\n\t\t}\n\n\t\tpublic string FullName => $\"{DeclaringType?.FullName}.{Name}\";\n\t\tpublic string ReflectionName => $\"{DeclaringType?.ReflectionName}.{Name}\";\n\t\tpublic string Namespace => DeclaringType?.Namespace ?? string.Empty;\n\n\t\tpublic bool IsVolatile {\n\t\t\tget {\n\t\t\t\tif (LazyInit.VolatileRead(ref this.type) == null)\n\t\t\t\t{\n\t\t\t\t\tDecodeTypeAndVolatileFlag();\n\t\t\t\t}\n\t\t\t\treturn this.isVolatile;\n\t\t\t}\n\t\t}\n\t\tIType IMember.ReturnType => Type;\n\t\tpublic IType Type {\n\t\t\tget {\n\t\t\t\tvar ty = LazyInit.VolatileRead(ref this.type);\n\t\t\t\tif (ty != null)\n\t\t\t\t{\n\t\t\t\t\treturn ty;\n\t\t\t\t}\n\t\t\t\treturn DecodeTypeAndVolatileFlag();\n\t\t\t}\n\t\t}\n\n\t\tprivate IType DecodeTypeAndVolatileFlag()\n\t\t{\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar fieldDef = metadata.GetFieldDefinition(handle);\n\t\t\tIType ty;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tty = fieldDef.DecodeSignature(module.TypeProvider, new GenericContext(DeclaringType?.TypeParameters));\n\t\t\t\tif (ty is ModifiedType mod && mod.Modifier.Name == \"IsVolatile\" && mod.Modifier.Namespace == \"System.Runtime.CompilerServices\")\n\t\t\t\t{\n\t\t\t\t\tVolatile.Write(ref this.isVolatile, true);\n\t\t\t\t}\n\t\t\t\tty = ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, Compilation,\n\t\t\t\t\tfieldDef.GetCustomAttributes(), metadata, module.OptionsForEntity(this),\n\t\t\t\t\tDeclaringTypeDefinition?.NullableContext ?? Nullability.Oblivious);\n\t\t\t}\n\t\t\tcatch (BadImageFormatException)\n\t\t\t{\n\t\t\t\tty = SpecialType.UnknownType;\n\t\t\t}\n\t\t\treturn LazyInit.GetOrSet(ref this.type, ty);\n\t\t}\n\n\t\tpublic bool IsConst => (attributes & FieldAttributes.Literal) != 0\n\t\t\t\t\t\t\t|| (IsDecimalConstant && DecimalConstantHelper.AllowsDecimalConstants(module));\n\n\t\tbool IsDecimalConstant {\n\t\t\tget {\n\t\t\t\tif (decimalConstantState == ThreeState.Unknown)\n\t\t\t\t{\n\t\t\t\t\tvar fieldDef = module.metadata.GetFieldDefinition(handle);\n\t\t\t\t\tdecimalConstantState = ThreeState.From(DecimalConstantHelper.IsDecimalConstant(module, fieldDef.GetCustomAttributes()));\n\t\t\t\t}\n\t\t\t\treturn decimalConstantState == ThreeState.True;\n\t\t\t}\n\t\t}\n\n\t\tpublic object GetConstantValue(bool throwOnInvalidMetadata)\n\t\t{\n\t\t\tobject val = LazyInit.VolatileRead(ref this.constantValue);\n\t\t\tif (val != null)\n\t\t\t\treturn val;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar metadata = module.metadata;\n\t\t\t\tvar fieldDef = metadata.GetFieldDefinition(handle);\n\t\t\t\tif (IsDecimalConstant && DecimalConstantHelper.AllowsDecimalConstants(module))\n\t\t\t\t{\n\t\t\t\t\tval = DecimalConstantHelper.GetDecimalConstantValue(module, fieldDef.GetCustomAttributes());\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar constantHandle = fieldDef.GetDefaultValue();\n\t\t\t\t\tif (constantHandle.IsNil)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tvar constant = metadata.GetConstant(constantHandle);\n\t\t\t\t\tvar blobReader = metadata.GetBlobReader(constant.Value);\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tval = blobReader.ReadConstant(constant.TypeCode);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (ArgumentOutOfRangeException)\n\t\t\t\t\t{\n\t\t\t\t\t\tthrow new BadImageFormatException($\"Constant with invalid typecode: {constant.TypeCode}\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn LazyInit.GetOrSet(ref this.constantValue, val);\n\t\t\t}\n\t\t\tcatch (BadImageFormatException) when (!throwOnInvalidMetadata)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\tif (obj is MetadataField f)\n\t\t\t{\n\t\t\t\treturn handle == f.handle && module.MetadataFile == f.module.MetadataFile;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn 0x11dda32b ^ module.MetadataFile.GetHashCode() ^ handle.GetHashCode();\n\t\t}\n\n\t\tbool IMember.Equals(IMember obj, TypeVisitor typeNormalization)\n\t\t{\n\t\t\treturn Equals(obj);\n\t\t}\n\n\t\tpublic IMember Specialize(TypeParameterSubstitution substitution)\n\t\t{\n\t\t\treturn SpecializedField.Create(this, substitution);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\tsealed class MetadataMethod : IMethod\n\t{\n\t\treadonly MetadataModule module;\n\t\treadonly MethodDefinitionHandle handle;\n\n\t\t// eagerly loaded fields:\n\t\treadonly MethodAttributes attributes;\n\t\treadonly SymbolKind symbolKind;\n\t\treadonly ITypeParameter[] typeParameters;\n\t\treadonly EntityHandle accessorOwner;\n\t\tpublic MethodSemanticsAttributes AccessorKind { get; }\n\t\tpublic bool IsExtensionMethod { get; }\n\t\tbool IMethod.IsLocalFunction => false;\n\n\t\t// lazy-loaded fields:\n\t\tITypeDefinition declaringType;\n\t\tstring name;\n\t\tIParameter[] parameters;\n\t\tIType returnType;\n\t\tbyte returnTypeIsRefReadonly = ThreeState.Unknown;\n\t\tbyte thisIsRefReadonly = ThreeState.Unknown;\n\t\tbool isInitOnly;\n\n\t\tinternal MetadataMethod(MetadataModule module, MethodDefinitionHandle handle)\n\t\t{\n\t\t\tDebug.Assert(module != null);\n\t\t\tDebug.Assert(!handle.IsNil);\n\t\t\tthis.module = module;\n\t\t\tthis.handle = handle;\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar def = metadata.GetMethodDefinition(handle);\n\t\t\tthis.attributes = def.Attributes;\n\n\t\t\tthis.symbolKind = SymbolKind.Method;\n\t\t\tvar (accessorOwner, semanticsAttribute) = module.MetadataFile.MethodSemanticsLookup.GetSemantics(handle);\n\t\t\tconst MethodAttributes finalizerAttributes = (MethodAttributes.Virtual | MethodAttributes.Family | MethodAttributes.HideBySig);\n\t\t\tthis.typeParameters = MetadataTypeParameter.Create(module, this, def.GetGenericParameters());\n\t\t\tif (semanticsAttribute != 0 && !accessorOwner.IsNil\n\t\t\t\t&& accessorOwner.Kind is HandleKind.PropertyDefinition or HandleKind.EventDefinition)\n\t\t\t{\n\t\t\t\tthis.symbolKind = SymbolKind.Accessor;\n\t\t\t\tthis.accessorOwner = accessorOwner;\n\t\t\t\tthis.AccessorKind = semanticsAttribute;\n\t\t\t}\n\t\t\telse if ((attributes & (MethodAttributes.SpecialName | MethodAttributes.RTSpecialName)) != 0\n\t\t\t\t&& typeParameters.Length == 0)\n\t\t\t{\n\t\t\t\tstring name = this.Name;\n\t\t\t\tif (name == \".cctor\" || name == \".ctor\")\n\t\t\t\t{\n\t\t\t\t\tthis.symbolKind = SymbolKind.Constructor;\n\t\t\t\t}\n\t\t\t\telse if (name.StartsWith(\"op_\", StringComparison.Ordinal)\n\t\t\t\t\t&& CSharp.Syntax.OperatorDeclaration.GetOperatorType(name) != null)\n\t\t\t\t{\n\t\t\t\t\tthis.symbolKind = SymbolKind.Operator;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ((attributes & finalizerAttributes) == finalizerAttributes && typeParameters.Length == 0)\n\t\t\t{\n\t\t\t\tif (Name == \"Finalize\" && Parameters.Count == 0 && ReturnType.IsKnownType(KnownTypeCode.Void)\n\t\t\t\t\t&& (DeclaringTypeDefinition as MetadataTypeDefinition)?.Kind == TypeKind.Class)\n\t\t\t\t{\n\t\t\t\t\tthis.symbolKind = SymbolKind.Destructor;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ((attributes & MethodAttributes.Static) != 0 && typeParameters.Length == 0)\n\t\t\t{\n\t\t\t\t// Operators that are explicit interface implementations are not marked\n\t\t\t\t// with MethodAttributes.SpecialName or MethodAttributes.RTSpecialName\n\t\t\t\tstring name = this.Name;\n\t\t\t\tint index = name.LastIndexOf('.');\n\t\t\t\tif (index > 0)\n\t\t\t\t{\n\t\t\t\t\tname = name.Substring(index + 1);\n\n\t\t\t\t\tif (name.StartsWith(\"op_\", StringComparison.Ordinal)\n\t\t\t\t\t\t&& CSharp.Syntax.OperatorDeclaration.GetOperatorType(name) != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tthis.symbolKind = SymbolKind.Operator;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.IsExtensionMethod = (attributes & MethodAttributes.Static) == MethodAttributes.Static\n\t\t\t\t&& (module.TypeSystemOptions & TypeSystemOptions.ExtensionMethods) == TypeSystemOptions.ExtensionMethods\n\t\t\t\t&& def.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.Extension);\n\t\t}\n\n\t\tpublic EntityHandle MetadataToken => handle;\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn $\"{MetadataTokens.GetToken(handle):X8} {DeclaringType?.ReflectionName}.{Name}\";\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget {\n\t\t\t\tstring name = LazyInit.VolatileRead(ref this.name);\n\t\t\t\tif (name != null)\n\t\t\t\t\treturn name;\n\t\t\t\tvar metadata = module.metadata;\n\t\t\t\tvar methodDef = metadata.GetMethodDefinition(handle);\n\t\t\t\treturn LazyInit.GetOrSet(ref this.name, metadata.GetString(methodDef.Name));\n\t\t\t}\n\t\t}\n\n\t\tpublic IReadOnlyList<ITypeParameter> TypeParameters => typeParameters;\n\t\tIReadOnlyList<IType> IMethod.TypeArguments => typeParameters;\n\n\t\tpublic SymbolKind SymbolKind => symbolKind;\n\t\tpublic bool IsConstructor => symbolKind == SymbolKind.Constructor;\n\t\tpublic bool IsDestructor => symbolKind == SymbolKind.Destructor;\n\t\tpublic bool IsOperator => symbolKind == SymbolKind.Operator;\n\t\tpublic bool IsAccessor => symbolKind == SymbolKind.Accessor;\n\n\t\tpublic bool HasBody => module.metadata.GetMethodDefinition(handle).HasBody();\n\n\t\tpublic IMember AccessorOwner {\n\t\t\tget {\n\t\t\t\tif (accessorOwner.IsNil)\n\t\t\t\t\treturn null;\n\t\t\t\tif (accessorOwner.Kind == HandleKind.PropertyDefinition)\n\t\t\t\t\treturn module.GetDefinition((PropertyDefinitionHandle)accessorOwner);\n\t\t\t\telse if (accessorOwner.Kind == HandleKind.EventDefinition)\n\t\t\t\t\treturn module.GetDefinition((EventDefinitionHandle)accessorOwner);\n\t\t\t\telse\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\t#region Signature (ReturnType + Parameters)\n\t\tpublic IReadOnlyList<IParameter> Parameters {\n\t\t\tget {\n\t\t\t\tvar parameters = LazyInit.VolatileRead(ref this.parameters);\n\t\t\t\tif (parameters != null)\n\t\t\t\t\treturn parameters;\n\t\t\t\tDecodeSignature();\n\t\t\t\treturn this.parameters;\n\t\t\t}\n\t\t}\n\n\t\tpublic IType ReturnType {\n\t\t\tget {\n\t\t\t\tvar returnType = LazyInit.VolatileRead(ref this.returnType);\n\t\t\t\tif (returnType != null)\n\t\t\t\t\treturn returnType;\n\t\t\t\tDecodeSignature();\n\t\t\t\treturn this.returnType;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool IsInitOnly {\n\t\t\tget {\n\t\t\t\tvar returnType = LazyInit.VolatileRead(ref this.returnType);\n\t\t\t\tif (returnType == null)\n\t\t\t\t\tDecodeSignature();\n\t\t\t\treturn this.isInitOnly;\n\t\t\t}\n\t\t}\n\n\t\tinternal Nullability NullableContext {\n\t\t\tget {\n\t\t\t\tvar methodDef = module.metadata.GetMethodDefinition(handle);\n\t\t\t\treturn methodDef.GetCustomAttributes().GetNullableContext(module.metadata) ?? DeclaringTypeDefinition.NullableContext;\n\t\t\t}\n\t\t}\n\n\t\tprivate void DecodeSignature()\n\t\t{\n\t\t\tvar methodDef = module.metadata.GetMethodDefinition(handle);\n\t\t\tvar genericContext = new GenericContext(DeclaringType.TypeParameters, this.TypeParameters);\n\t\t\tIType returnType;\n\t\t\tIParameter[] parameters;\n\t\t\tModifiedType mod;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar nullableContext = methodDef.GetCustomAttributes().GetNullableContext(module.metadata) ?? DeclaringTypeDefinition.NullableContext;\n\t\t\t\tvar signature = methodDef.DecodeSignature(module.TypeProvider, genericContext);\n\t\t\t\t(returnType, parameters, mod) = DecodeSignature(module, this, signature,\n\t\t\t\t\tmethodDef.GetParameters(), nullableContext, module.OptionsForEntity(this));\n\t\t\t}\n\t\t\tcatch (BadImageFormatException)\n\t\t\t{\n\t\t\t\treturnType = SpecialType.UnknownType;\n\t\t\t\tparameters = Empty<IParameter>.Array;\n\t\t\t\tmod = null;\n\t\t\t}\n\t\t\tthis.isInitOnly = mod is { Modifier: { Name: \"IsExternalInit\", Namespace: \"System.Runtime.CompilerServices\" } };\n\t\t\tLazyInit.GetOrSet(ref this.returnType, returnType);\n\t\t\tLazyInit.GetOrSet(ref this.parameters, parameters);\n\t\t}\n\n\t\tinternal static (IType returnType, IParameter[] parameters, ModifiedType returnTypeModifier) DecodeSignature(\n\t\t\tMetadataModule module, IParameterizedMember owner,\n\t\t\tMethodSignature<IType> signature, ParameterHandleCollection? parameterHandles,\n\t\t\tNullability nullableContext, TypeSystemOptions typeSystemOptions,\n\t\t\tCustomAttributeHandleCollection? additionalReturnTypeAttributes = null)\n\t\t{\n\t\t\tvar metadata = module.metadata;\n\t\t\tint i = 0;\n\t\t\tIParameter[] parameters = new IParameter[signature.RequiredParameterCount\n\t\t\t\t+ (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs ? 1 : 0)];\n\t\t\tIType parameterType;\n\t\t\tCustomAttributeHandleCollection? returnTypeAttributes = null;\n\t\t\tif (parameterHandles != null)\n\t\t\t{\n\t\t\t\tforeach (var parameterHandle in parameterHandles)\n\t\t\t\t{\n\t\t\t\t\tvar par = metadata.GetParameter(parameterHandle);\n\t\t\t\t\tif (par.SequenceNumber == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t// \"parameter\" holds return type attributes.\n\t\t\t\t\t\t// Note: for properties, the attributes normally stored on a method's return type\n\t\t\t\t\t\t// are instead typically stored as normal attributes on the property.\n\t\t\t\t\t\t// So MetadataProperty provides a non-null value for additionalReturnTypeAttributes,\n\t\t\t\t\t\t// which then will be preferred over the attributes on the accessor's parameters.\n\t\t\t\t\t\t// However if an attribute only exists on the accessor's parameters, we still want\n\t\t\t\t\t\t// to process it here.\n\t\t\t\t\t\treturnTypeAttributes = par.GetCustomAttributes();\n\t\t\t\t\t}\n\t\t\t\t\telse if (i < par.SequenceNumber && par.SequenceNumber <= signature.RequiredParameterCount)\n\t\t\t\t\t{\n\t\t\t\t\t\t// \"Successive rows of the Param table that are owned by the same method shall be\n\t\t\t\t\t\t// ordered by increasing Sequence value - although gaps in the sequence are allowed\"\n\t\t\t\t\t\tDebug.Assert(par.SequenceNumber <= signature.ParameterTypes.Length);\n\t\t\t\t\t\tDebug.Assert(par.SequenceNumber <= parameters.Length);\n\t\t\t\t\t\t// Fill gaps in the sequence with non-metadata parameters:\n\t\t\t\t\t\twhile (i < par.SequenceNumber - 1)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tparameterType = ApplyAttributeTypeVisitor.ApplyAttributesToType(\n\t\t\t\t\t\t\t\tsignature.ParameterTypes[i], module.Compilation, null, metadata, typeSystemOptions, nullableContext);\n\t\t\t\t\t\t\tparameters[i] = new DefaultParameter(parameterType, name: string.Empty, owner,\n\t\t\t\t\t\t\t\treferenceKind: parameterType.Kind == TypeKind.ByReference ? ReferenceKind.Ref : ReferenceKind.None);\n\t\t\t\t\t\t\ti++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tparameterType = ApplyAttributeTypeVisitor.ApplyAttributesToType(\n\t\t\t\t\t\t\tsignature.ParameterTypes[i], module.Compilation,\n\t\t\t\t\t\t\tpar.GetCustomAttributes(), metadata, typeSystemOptions, nullableContext);\n\t\t\t\t\t\tparameters[i] = new MetadataParameter(module, owner, parameterType, parameterHandle);\n\t\t\t\t\t\ti++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\twhile (i < signature.RequiredParameterCount)\n\t\t\t{\n\t\t\t\tparameterType = ApplyAttributeTypeVisitor.ApplyAttributesToType(\n\t\t\t\t\tsignature.ParameterTypes[i], module.Compilation, null, metadata, typeSystemOptions, nullableContext);\n\t\t\t\tparameters[i] = new DefaultParameter(parameterType, name: string.Empty, owner,\n\t\t\t\t\treferenceKind: parameterType.Kind == TypeKind.ByReference ? ReferenceKind.Ref : ReferenceKind.None);\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tif (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs)\n\t\t\t{\n\t\t\t\tparameters[i] = new DefaultParameter(SpecialType.ArgList, name: string.Empty, owner);\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tDebug.Assert(i == parameters.Length);\n\t\t\tvar returnType = ApplyAttributeTypeVisitor.ApplyAttributesToType(signature.ReturnType,\n\t\t\t\tmodule.Compilation, returnTypeAttributes, metadata, typeSystemOptions, nullableContext,\n\t\t\t\tadditionalAttributes: additionalReturnTypeAttributes);\n\t\t\treturn (returnType, parameters, signature.ReturnType as ModifiedType);\n\t\t}\n\t\t#endregion\n\n\t\tpublic bool IsExplicitInterfaceImplementation {\n\t\t\tget {\n\t\t\t\tif (Name.IndexOf('.') < 0)\n\t\t\t\t\treturn false;\n\t\t\t\tvar typeDef = ((MetadataTypeDefinition)DeclaringTypeDefinition);\n\t\t\t\treturn typeDef.HasOverrides(handle);\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable<IMember> ExplicitlyImplementedInterfaceMembers {\n\t\t\tget {\n\t\t\t\tvar typeDef = ((MetadataTypeDefinition)DeclaringTypeDefinition);\n\t\t\t\treturn typeDef.GetOverrides(handle);\n\t\t\t}\n\t\t}\n\n\t\tIMember IMember.MemberDefinition => this;\n\t\tIMethod IMethod.ReducedFrom => null;\n\t\tTypeParameterSubstitution IMember.Substitution => TypeParameterSubstitution.Identity;\n\n\t\tpublic ITypeDefinition DeclaringTypeDefinition {\n\t\t\tget {\n\t\t\t\tvar declType = LazyInit.VolatileRead(ref this.declaringType);\n\t\t\t\tif (declType != null)\n\t\t\t\t{\n\t\t\t\t\treturn declType;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar def = module.metadata.GetMethodDefinition(handle);\n\t\t\t\t\treturn LazyInit.GetOrSet(ref this.declaringType,\n\t\t\t\t\t\tmodule.GetDefinition(def.GetDeclaringType()));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic IType DeclaringType => DeclaringTypeDefinition;\n\n\t\tpublic IModule ParentModule => module;\n\t\tpublic ICompilation Compilation => module.Compilation;\n\n\t\t#region Attributes\n\t\tIType FindInteropType(string name)\n\t\t{\n\t\t\treturn module.Compilation.FindType(new TopLevelTypeName(\n\t\t\t\t\"System.Runtime.InteropServices\", name, 0\n\t\t\t));\n\t\t}\n\n\t\tpublic IEnumerable<IAttribute> GetAttributes()\n\t\t{\n\t\t\tvar b = new AttributeListBuilder(module);\n\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar def = metadata.GetMethodDefinition(handle);\n\t\t\tMethodImplAttributes implAttributes = def.ImplAttributes & ~MethodImplAttributes.CodeTypeMask;\n\t\t\tint methodCodeType = (int)(def.ImplAttributes & MethodImplAttributes.CodeTypeMask);\n\n\t\t\t#region DllImportAttribute\n\t\t\tvar info = def.GetImport();\n\t\t\tif ((attributes & MethodAttributes.PinvokeImpl) == MethodAttributes.PinvokeImpl && !info.Module.IsNil)\n\t\t\t{\n\t\t\t\tvar dllImport = new AttributeBuilder(module, KnownAttribute.DllImport);\n\t\t\t\tdllImport.AddFixedArg(KnownTypeCode.String,\n\t\t\t\t\tmetadata.GetString(metadata.GetModuleReference(info.Module).Name));\n\n\t\t\t\tvar importAttrs = info.Attributes;\n\t\t\t\tif ((importAttrs & MethodImportAttributes.BestFitMappingDisable) == MethodImportAttributes.BestFitMappingDisable)\n\t\t\t\t\tdllImport.AddNamedArg(\"BestFitMapping\", KnownTypeCode.Boolean, false);\n\t\t\t\tif ((importAttrs & MethodImportAttributes.BestFitMappingEnable) == MethodImportAttributes.BestFitMappingEnable)\n\t\t\t\t\tdllImport.AddNamedArg(\"BestFitMapping\", KnownTypeCode.Boolean, true);\n\n\t\t\t\tCallingConvention callingConvention;\n\t\t\t\tswitch (info.Attributes & MethodImportAttributes.CallingConventionMask)\n\t\t\t\t{\n\t\t\t\t\tcase 0:\n\t\t\t\t\t\tDebug.WriteLine($\"P/Invoke calling convention not set on: {this}\");\n\t\t\t\t\t\tcallingConvention = 0;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MethodImportAttributes.CallingConventionCDecl:\n\t\t\t\t\t\tcallingConvention = CallingConvention.Cdecl;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MethodImportAttributes.CallingConventionFastCall:\n\t\t\t\t\t\tcallingConvention = CallingConvention.FastCall;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MethodImportAttributes.CallingConventionStdCall:\n\t\t\t\t\t\tcallingConvention = CallingConvention.StdCall;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MethodImportAttributes.CallingConventionThisCall:\n\t\t\t\t\t\tcallingConvention = CallingConvention.ThisCall;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MethodImportAttributes.CallingConventionWinApi:\n\t\t\t\t\t\tcallingConvention = CallingConvention.Winapi;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new NotSupportedException(\"unknown calling convention\");\n\t\t\t\t}\n\t\t\t\tif (callingConvention != CallingConvention.Winapi)\n\t\t\t\t{\n\t\t\t\t\tvar callingConventionType = FindInteropType(nameof(CallingConvention));\n\t\t\t\t\tdllImport.AddNamedArg(\"CallingConvention\", callingConventionType, (int)callingConvention);\n\t\t\t\t}\n\n\t\t\t\tCharSet charSet = CharSet.None;\n\t\t\t\tswitch (info.Attributes & MethodImportAttributes.CharSetMask)\n\t\t\t\t{\n\t\t\t\t\tcase MethodImportAttributes.CharSetAnsi:\n\t\t\t\t\t\tcharSet = CharSet.Ansi;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MethodImportAttributes.CharSetAuto:\n\t\t\t\t\t\tcharSet = CharSet.Auto;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MethodImportAttributes.CharSetUnicode:\n\t\t\t\t\t\tcharSet = CharSet.Unicode;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (charSet != CharSet.None)\n\t\t\t\t{\n\t\t\t\t\tvar charSetType = FindInteropType(nameof(CharSet));\n\t\t\t\t\tdllImport.AddNamedArg(\"CharSet\", charSetType, (int)charSet);\n\t\t\t\t}\n\n\t\t\t\tif (!info.Name.IsNil && info.Name != def.Name)\n\t\t\t\t{\n\t\t\t\t\tdllImport.AddNamedArg(\"EntryPoint\", KnownTypeCode.String, metadata.GetString(info.Name));\n\t\t\t\t}\n\n\t\t\t\tif ((info.Attributes & MethodImportAttributes.ExactSpelling) == MethodImportAttributes.ExactSpelling)\n\t\t\t\t{\n\t\t\t\t\tdllImport.AddNamedArg(\"ExactSpelling\", KnownTypeCode.Boolean, true);\n\t\t\t\t}\n\n\t\t\t\tif ((implAttributes & MethodImplAttributes.PreserveSig) == MethodImplAttributes.PreserveSig)\n\t\t\t\t{\n\t\t\t\t\timplAttributes &= ~MethodImplAttributes.PreserveSig;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tdllImport.AddNamedArg(\"PreserveSig\", KnownTypeCode.Boolean, false);\n\t\t\t\t}\n\n\t\t\t\tif ((info.Attributes & MethodImportAttributes.SetLastError) == MethodImportAttributes.SetLastError)\n\t\t\t\t\tdllImport.AddNamedArg(\"SetLastError\", KnownTypeCode.Boolean, true);\n\n\t\t\t\tif ((info.Attributes & MethodImportAttributes.ThrowOnUnmappableCharDisable) == MethodImportAttributes.ThrowOnUnmappableCharDisable)\n\t\t\t\t\tdllImport.AddNamedArg(\"ThrowOnUnmappableChar\", KnownTypeCode.Boolean, false);\n\t\t\t\tif ((info.Attributes & MethodImportAttributes.ThrowOnUnmappableCharEnable) == MethodImportAttributes.ThrowOnUnmappableCharEnable)\n\t\t\t\t\tdllImport.AddNamedArg(\"ThrowOnUnmappableChar\", KnownTypeCode.Boolean, true);\n\n\t\t\t\tb.Add(dllImport.Build());\n\t\t\t}\n\t\t\t#endregion\n\n\t\t\t#region PreserveSigAttribute\n\t\t\tif (implAttributes == MethodImplAttributes.PreserveSig && methodCodeType == 0)\n\t\t\t{\n\t\t\t\tb.Add(KnownAttribute.PreserveSig);\n\t\t\t\timplAttributes = 0;\n\t\t\t}\n\t\t\t#endregion\n\n\t\t\t#region MethodImplAttribute\n\t\t\tif (implAttributes != 0)\n\t\t\t{\n\t\t\t\tvar methodImpl = new AttributeBuilder(module, KnownAttribute.MethodImpl);\n\t\t\t\tmethodImpl.AddFixedArg(new TopLevelTypeName(\"System.Runtime.CompilerServices\", nameof(MethodImplOptions)), (int)implAttributes);\n\t\t\t\tif (methodCodeType != 0)\n\t\t\t\t{\n\t\t\t\t\tmethodImpl.AddNamedArg(\"MethodCodeType\", new TopLevelTypeName(\"System.Runtime.CompilerServices\", nameof(MethodCodeType)), methodCodeType);\n\t\t\t\t}\n\t\t\t\tb.Add(methodImpl.Build());\n\t\t\t}\n\t\t\t#endregion\n\n\t\t\t// SpecialName\n\t\t\tif ((def.Attributes & (MethodAttributes.SpecialName | MethodAttributes.RTSpecialName)) == MethodAttributes.SpecialName\n\t\t\t\t&& SymbolKind == SymbolKind.Method)\n\t\t\t{\n\t\t\t\tb.Add(KnownAttribute.SpecialName);\n\t\t\t}\n\n\t\t\tb.Add(def.GetCustomAttributes(), symbolKind);\n\t\t\tb.AddSecurityAttributes(def.GetDeclarativeSecurityAttributes());\n\n\t\t\treturn b.Build();\n\t\t}\n\n\t\tpublic bool HasAttribute(KnownAttribute attribute)\n\t\t{\n\t\t\tif (!attribute.IsCustomAttribute())\n\t\t\t{\n\t\t\t\treturn GetAttributes().Any(attr => attr.AttributeType.IsKnownType(attribute));\n\t\t\t}\n\t\t\tvar b = new AttributeListBuilder(module);\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar def = metadata.GetMethodDefinition(handle);\n\t\t\treturn b.HasAttribute(metadata, def.GetCustomAttributes(), attribute, symbolKind);\n\t\t}\n\n\t\tpublic IAttribute GetAttribute(KnownAttribute attribute)\n\t\t{\n\t\t\tif (!attribute.IsCustomAttribute())\n\t\t\t{\n\t\t\t\treturn GetAttributes().FirstOrDefault(attr => attr.AttributeType.IsKnownType(attribute));\n\t\t\t}\n\t\t\tvar b = new AttributeListBuilder(module);\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar def = metadata.GetMethodDefinition(handle);\n\t\t\treturn b.GetAttribute(metadata, def.GetCustomAttributes(), attribute, symbolKind);\n\t\t}\n\t\t#endregion\n\n\t\t#region Return type attributes\n\t\tpublic IEnumerable<IAttribute> GetReturnTypeAttributes()\n\t\t{\n\t\t\tvar b = new AttributeListBuilder(module);\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar methodDefinition = metadata.GetMethodDefinition(handle);\n\t\t\tvar parameters = methodDefinition.GetParameters();\n\t\t\tif (parameters.Count > 0)\n\t\t\t{\n\t\t\t\tvar retParam = metadata.GetParameter(parameters.First());\n\t\t\t\tif (retParam.SequenceNumber == 0)\n\t\t\t\t{\n\t\t\t\t\tb.AddMarshalInfo(retParam.GetMarshallingDescriptor());\n\t\t\t\t\tb.Add(retParam.GetCustomAttributes(), SymbolKind.ReturnType);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn b.Build();\n\t\t}\n\n\t\tpublic bool ReturnTypeIsRefReadOnly {\n\t\t\tget {\n\t\t\t\tif (returnTypeIsRefReadonly != ThreeState.Unknown)\n\t\t\t\t{\n\t\t\t\t\treturn returnTypeIsRefReadonly == ThreeState.True;\n\t\t\t\t}\n\t\t\t\tvar metadata = module.metadata;\n\t\t\t\tvar methodDefinition = metadata.GetMethodDefinition(handle);\n\t\t\t\tvar parameters = methodDefinition.GetParameters();\n\t\t\t\tbool hasReadOnlyAttr = false;\n\t\t\t\tif (parameters.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tvar retParam = metadata.GetParameter(parameters.First());\n\t\t\t\t\tif (retParam.SequenceNumber == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\thasReadOnlyAttr = retParam.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.IsReadOnly);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis.returnTypeIsRefReadonly = ThreeState.From(hasReadOnlyAttr);\n\t\t\t\treturn hasReadOnlyAttr;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool ThisIsRefReadOnly {\n\t\t\tget {\n\t\t\t\tif (thisIsRefReadonly != ThreeState.Unknown)\n\t\t\t\t{\n\t\t\t\t\treturn thisIsRefReadonly == ThreeState.True;\n\t\t\t\t}\n\t\t\t\tvar metadata = module.metadata;\n\t\t\t\tvar methodDefinition = metadata.GetMethodDefinition(handle);\n\t\t\t\tbool hasReadOnlyAttr = DeclaringTypeDefinition?.IsReadOnly ?? false;\n\t\t\t\tif ((module.TypeSystemOptions & TypeSystemOptions.ReadOnlyMethods) != 0)\n\t\t\t\t{\n\t\t\t\t\thasReadOnlyAttr |= methodDefinition.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.IsReadOnly);\n\t\t\t\t}\n\t\t\t\tthis.thisIsRefReadonly = ThreeState.From(hasReadOnlyAttr);\n\t\t\t\treturn hasReadOnlyAttr;\n\t\t\t}\n\t\t}\n\n\t\t#endregion\n\n\t\tpublic Accessibility Accessibility => GetAccessibility(attributes);\n\n\t\tinternal static Accessibility GetAccessibility(MethodAttributes attr)\n\t\t{\n\t\t\tswitch (attr & MethodAttributes.MemberAccessMask)\n\t\t\t{\n\t\t\t\tcase MethodAttributes.Public:\n\t\t\t\t\treturn Accessibility.Public;\n\t\t\t\tcase MethodAttributes.Assembly:\n\t\t\t\t\treturn Accessibility.Internal;\n\t\t\t\tcase MethodAttributes.Private:\n\t\t\t\t\treturn Accessibility.Private;\n\t\t\t\tcase MethodAttributes.Family:\n\t\t\t\t\treturn Accessibility.Protected;\n\t\t\t\tcase MethodAttributes.FamANDAssem:\n\t\t\t\t\treturn Accessibility.ProtectedAndInternal;\n\t\t\t\tcase MethodAttributes.FamORAssem:\n\t\t\t\t\treturn Accessibility.ProtectedOrInternal;\n\t\t\t\tdefault:\n\t\t\t\t\treturn Accessibility.None;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool IsStatic => (attributes & MethodAttributes.Static) != 0;\n\t\tpublic bool IsAbstract => (attributes & MethodAttributes.Abstract) != 0;\n\t\tpublic bool IsSealed => (attributes & (MethodAttributes.Abstract | MethodAttributes.Final | MethodAttributes.NewSlot | MethodAttributes.Static)) == MethodAttributes.Final;\n\n\t\tpublic bool IsVirtual {\n\t\t\tget {\n\t\t\t\tif (IsStatic)\n\t\t\t\t{\n\t\t\t\t\treturn (attributes & (MethodAttributes.Abstract | MethodAttributes.Virtual)) == MethodAttributes.Virtual;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tconst MethodAttributes mask = MethodAttributes.Abstract | MethodAttributes.Virtual\n\t\t\t\t\t\t| MethodAttributes.NewSlot | MethodAttributes.Final;\n\t\t\t\t\treturn (attributes & mask) == (MethodAttributes.Virtual | MethodAttributes.NewSlot);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic bool IsOverride => (attributes & (MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Static)) == MethodAttributes.Virtual;\n\t\tpublic bool IsOverridable\n\t\t\t=> (attributes & (MethodAttributes.Abstract | MethodAttributes.Virtual)) != 0\n\t\t\t&& (attributes & MethodAttributes.Final) == 0;\n\n\t\tpublic string FullName => $\"{DeclaringType?.FullName}.{Name}\";\n\t\tpublic string ReflectionName => $\"{DeclaringType?.ReflectionName}.{Name}\";\n\t\tpublic string Namespace => DeclaringType?.Namespace ?? string.Empty;\n\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\tif (obj is MetadataMethod m)\n\t\t\t{\n\t\t\t\treturn handle == m.handle && module.MetadataFile == m.module.MetadataFile;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn 0x5a00d671 ^ module.MetadataFile.GetHashCode() ^ handle.GetHashCode();\n\t\t}\n\n\t\tbool IMember.Equals(IMember obj, TypeVisitor typeNormalization)\n\t\t{\n\t\t\treturn Equals(obj);\n\t\t}\n\n\t\tpublic IMethod Specialize(TypeParameterSubstitution substitution)\n\t\t{\n\t\t\treturn SpecializedMethod.Create(this, substitution);\n\t\t}\n\n\t\tIMember IMember.Specialize(TypeParameterSubstitution substitution)\n\t\t{\n\t\t\treturn SpecializedMethod.Create(this, substitution);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataNamespace.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\tsealed class MetadataNamespace : INamespace\n\t{\n\t\treadonly MetadataModule module;\n\t\treadonly NamespaceDefinition ns;\n\n\t\tpublic INamespace ParentNamespace { get; }\n\t\tpublic string FullName { get; }\n\t\tpublic string Name { get; }\n\n\t\tpublic MetadataNamespace(MetadataModule module, INamespace parent, string fullName, NamespaceDefinition ns)\n\t\t{\n\t\t\tDebug.Assert(module != null);\n\t\t\tDebug.Assert(fullName != null);\n\t\t\tthis.module = module;\n\t\t\tthis.ParentNamespace = parent;\n\t\t\tthis.ns = ns;\n\t\t\tthis.FullName = fullName;\n\t\t\tthis.Name = module.GetString(ns.Name);\n\t\t}\n\n\t\tstring INamespace.ExternAlias => string.Empty;\n\n\t\tINamespace[] childNamespaces;\n\n\t\tpublic IEnumerable<INamespace> ChildNamespaces {\n\t\t\tget {\n\t\t\t\tvar children = LazyInit.VolatileRead(ref childNamespaces);\n\t\t\t\tif (children != null)\n\t\t\t\t{\n\t\t\t\t\treturn children;\n\t\t\t\t}\n\t\t\t\tvar nsDefs = ns.NamespaceDefinitions;\n\t\t\t\tchildren = new INamespace[nsDefs.Length];\n\t\t\t\tfor (int i = 0; i < children.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tvar nsHandle = nsDefs[i];\n\t\t\t\t\tstring fullName = module.metadata.GetString(nsHandle);\n\t\t\t\t\tchildren[i] = new MetadataNamespace(module, this, fullName,\n\t\t\t\t\t\tmodule.metadata.GetNamespaceDefinition(nsHandle));\n\t\t\t\t}\n\t\t\t\treturn LazyInit.GetOrSet(ref childNamespaces, children);\n\t\t\t}\n\t\t}\n\n\t\tIEnumerable<ITypeDefinition> INamespace.Types {\n\t\t\tget {\n\t\t\t\tforeach (var typeHandle in ns.TypeDefinitions)\n\t\t\t\t{\n\t\t\t\t\tvar def = module.GetDefinition(typeHandle);\n\t\t\t\t\tif (def != null)\n\t\t\t\t\t\tyield return def;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tIEnumerable<IModule> INamespace.ContributingModules => new[] { module };\n\n\t\tSymbolKind ISymbol.SymbolKind => SymbolKind.Namespace;\n\n\t\tICompilation ICompilationProvider.Compilation => module.Compilation;\n\n\t\tINamespace INamespace.GetChildNamespace(string name)\n\t\t{\n\t\t\tforeach (var ns in ChildNamespaces)\n\t\t\t{\n\t\t\t\tif (ns.Name == name)\n\t\t\t\t\treturn ns;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tITypeDefinition INamespace.GetTypeDefinition(string name, int typeParameterCount)\n\t\t{\n\t\t\treturn module.GetTypeDefinition(FullName, name, typeParameterCount);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataParameter.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\tsealed class MetadataParameter : IParameter\n\t{\n\t\treadonly MetadataModule module;\n\t\treadonly ParameterHandle handle;\n\t\treadonly ParameterAttributes attributes;\n\n\t\tpublic IType Type { get; }\n\t\tpublic IParameterizedMember Owner { get; }\n\n\t\t// lazy-loaded:\n\t\tstring name;\n\t\t// these can't be bool? as bool? is not thread-safe from torn reads\n\t\tbyte constantValueInSignatureState;\n\t\tbyte decimalConstantState;\n\n\t\tinternal MetadataParameter(MetadataModule module, IParameterizedMember owner, IType type, ParameterHandle handle)\n\t\t{\n\t\t\tthis.module = module;\n\t\t\tthis.Owner = owner;\n\t\t\tthis.Type = type;\n\t\t\tthis.handle = handle;\n\n\t\t\tvar param = module.metadata.GetParameter(handle);\n\t\t\tthis.attributes = param.Attributes;\n\t\t\tif (!IsOptional)\n\t\t\t\tdecimalConstantState = ThreeState.False; // only optional parameters can be constants\n\t\t}\n\n\t\tpublic EntityHandle MetadataToken => handle;\n\n\t\t#region Attributes\n\t\tpublic IEnumerable<IAttribute> GetAttributes()\n\t\t{\n\t\t\tvar b = new AttributeListBuilder(module);\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar parameter = metadata.GetParameter(handle);\n\n\t\t\tbool defaultValueAssignmentAllowed = this.IsDefaultValueAssignmentAllowed();\n\n\t\t\tif (IsOptional && !defaultValueAssignmentAllowed)\n\t\t\t{\n\t\t\t\tb.Add(KnownAttribute.Optional);\n\t\t\t}\n\n\t\t\tif (!IsDecimalConstant && HasConstantValueInSignature && !defaultValueAssignmentAllowed)\n\t\t\t{\n\t\t\t\tb.Add(KnownAttribute.DefaultParameterValue, KnownTypeCode.Object, GetConstantValue(throwOnInvalidMetadata: false));\n\t\t\t}\n\n\t\t\tif ((attributes & ParameterAttributes.In) == ParameterAttributes.In && ReferenceKind is not (ReferenceKind.In or ReferenceKind.RefReadOnly))\n\t\t\t\tb.Add(KnownAttribute.In);\n\t\t\tif ((attributes & ParameterAttributes.Out) == ParameterAttributes.Out && ReferenceKind != ReferenceKind.Out)\n\t\t\t\tb.Add(KnownAttribute.Out);\n\t\t\tb.Add(parameter.GetCustomAttributes(), SymbolKind.Parameter);\n\t\t\tb.AddMarshalInfo(parameter.GetMarshallingDescriptor());\n\n\t\t\treturn b.Build();\n\t\t}\n\t\t#endregion\n\n\t\tconst ParameterAttributes inOut = ParameterAttributes.In | ParameterAttributes.Out;\n\n\t\tpublic ReferenceKind ReferenceKind => DetectRefKind();\n\n\t\tpublic bool IsOptional => (attributes & ParameterAttributes.Optional) != 0;\n\n\t\tReferenceKind DetectRefKind()\n\t\t{\n\t\t\tif (Type.Kind != TypeKind.ByReference)\n\t\t\t\treturn ReferenceKind.None;\n\t\t\tif ((attributes & inOut) == ParameterAttributes.Out)\n\t\t\t\treturn ReferenceKind.Out;\n\t\t\tif ((module.TypeSystemOptions & TypeSystemOptions.ReadOnlyStructsAndParameters) != 0)\n\t\t\t{\n\t\t\t\tvar metadata = module.metadata;\n\t\t\t\tvar parameterDef = metadata.GetParameter(handle);\n\t\t\t\tif (parameterDef.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.IsReadOnly))\n\t\t\t\t\treturn ReferenceKind.In;\n\t\t\t}\n\t\t\tif ((module.TypeSystemOptions & TypeSystemOptions.RefReadOnlyParameters) != 0\n\t\t\t\t&& (attributes & inOut) == ParameterAttributes.In)\n\t\t\t{\n\t\t\t\tvar metadata = module.metadata;\n\t\t\t\tvar parameterDef = metadata.GetParameter(handle);\n\t\t\t\tif (parameterDef.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.RequiresLocation))\n\t\t\t\t\treturn ReferenceKind.RefReadOnly;\n\t\t\t}\n\t\t\treturn ReferenceKind.Ref;\n\t\t}\n\n\t\tpublic LifetimeAnnotation Lifetime {\n\t\t\tget {\n\t\t\t\tif ((module.TypeSystemOptions & TypeSystemOptions.ScopedRef) == 0)\n\t\t\t\t{\n\t\t\t\t\treturn default;\n\t\t\t\t}\n\n\t\t\t\tvar metadata = module.metadata;\n\t\t\t\tvar parameterDef = metadata.GetParameter(handle);\n\t\t\t\tif ((module.TypeSystemOptions & TypeSystemOptions.ParamsCollections) != 0\n\t\t\t\t\t&& parameterDef.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.ParamCollection))\n\t\t\t\t{\n\t\t\t\t\t// params collections are implicitly scoped\n\t\t\t\t\treturn default;\n\t\t\t\t}\n\t\t\t\tif (parameterDef.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.ScopedRef))\n\t\t\t\t{\n\t\t\t\t\treturn new LifetimeAnnotation { ScopedRef = true };\n\t\t\t\t}\n\t\t\t\treturn default;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool IsParams {\n\t\t\tget {\n\t\t\t\tvar metadata = module.metadata;\n\t\t\t\tvar parameterDef = metadata.GetParameter(handle);\n\t\t\t\tif (Type.Kind == TypeKind.Array)\n\t\t\t\t{\n\t\t\t\t\treturn parameterDef.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.ParamArray);\n\t\t\t\t}\n\t\t\t\tif (module.TypeSystemOptions.HasFlag(TypeSystemOptions.ParamsCollections))\n\t\t\t\t{\n\t\t\t\t\treturn parameterDef.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.ParamCollection);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget {\n\t\t\t\tstring name = LazyInit.VolatileRead(ref this.name);\n\t\t\t\tif (name != null)\n\t\t\t\t\treturn name;\n\t\t\t\tvar metadata = module.metadata;\n\t\t\t\tvar parameterDef = metadata.GetParameter(handle);\n\t\t\t\treturn LazyInit.GetOrSet(ref this.name, metadata.GetString(parameterDef.Name));\n\t\t\t}\n\t\t}\n\n\t\tbool IVariable.IsConst => false;\n\n\t\tpublic object GetConstantValue(bool throwOnInvalidMetadata)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar metadata = module.metadata;\n\t\t\t\tvar parameterDef = metadata.GetParameter(handle);\n\t\t\t\tif (IsDecimalConstant)\n\t\t\t\t\treturn DecimalConstantHelper.GetDecimalConstantValue(module, parameterDef.GetCustomAttributes());\n\n\t\t\t\tvar constantHandle = parameterDef.GetDefaultValue();\n\t\t\t\tif (constantHandle.IsNil)\n\t\t\t\t\treturn null;\n\n\t\t\t\tvar constant = metadata.GetConstant(constantHandle);\n\t\t\t\tvar blobReader = metadata.GetBlobReader(constant.Value);\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\treturn blobReader.ReadConstant(constant.TypeCode);\n\t\t\t\t}\n\t\t\t\tcatch (ArgumentOutOfRangeException)\n\t\t\t\t{\n\t\t\t\t\tthrow new BadImageFormatException($\"Constant with invalid typecode: {constant.TypeCode}\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (BadImageFormatException) when (!throwOnInvalidMetadata)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool HasConstantValueInSignature {\n\t\t\tget {\n\t\t\t\tif (constantValueInSignatureState == ThreeState.Unknown)\n\t\t\t\t{\n\t\t\t\t\tif (IsDecimalConstant)\n\t\t\t\t\t{\n\t\t\t\t\t\tconstantValueInSignatureState = ThreeState.From(DecimalConstantHelper.AllowsDecimalConstants(module));\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tconstantValueInSignatureState = ThreeState.From(!module.metadata.GetParameter(handle).GetDefaultValue().IsNil);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn constantValueInSignatureState == ThreeState.True;\n\t\t\t}\n\t\t}\n\n\t\tbool IsDecimalConstant {\n\t\t\tget {\n\t\t\t\tif (decimalConstantState == ThreeState.Unknown)\n\t\t\t\t{\n\t\t\t\t\tvar parameterDef = module.metadata.GetParameter(handle);\n\t\t\t\t\tdecimalConstantState = ThreeState.From(DecimalConstantHelper.IsDecimalConstant(module, parameterDef.GetCustomAttributes()));\n\t\t\t\t}\n\t\t\t\treturn decimalConstantState == ThreeState.True;\n\t\t\t}\n\t\t}\n\n\t\tSymbolKind ISymbol.SymbolKind => SymbolKind.Parameter;\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn $\"{MetadataTokens.GetToken(handle):X8} {DefaultParameter.ToString(this)}\";\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataProperty.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\tsealed class MetadataProperty : IProperty\n\t{\n\t\tconst Accessibility InvalidAccessibility = (Accessibility)0xff;\n\n\t\treadonly MetadataModule module;\n\t\treadonly PropertyDefinitionHandle handle;\n\t\treadonly IMethod getter;\n\t\treadonly IMethod setter;\n\t\treadonly string name;\n\t\treadonly SymbolKind symbolKind;\n\n\t\t// lazy-loaded:\n\t\tvolatile Accessibility cachedAccessiblity = InvalidAccessibility;\n\t\tIParameter[] parameters;\n\t\tIType returnType;\n\n\t\tinternal MetadataProperty(MetadataModule module, PropertyDefinitionHandle handle)\n\t\t{\n\t\t\tDebug.Assert(module != null);\n\t\t\tDebug.Assert(!handle.IsNil);\n\t\t\tthis.module = module;\n\t\t\tthis.handle = handle;\n\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar prop = metadata.GetPropertyDefinition(handle);\n\t\t\tvar accessors = prop.GetAccessors();\n\t\t\tgetter = module.GetDefinition(accessors.Getter);\n\t\t\tsetter = module.GetDefinition(accessors.Setter);\n\t\t\tname = metadata.GetString(prop.Name);\n\t\t\t// Maybe we should defer the calculation of symbolKind?\n\t\t\tif (DetermineIsIndexer(name))\n\t\t\t{\n\t\t\t\tsymbolKind = SymbolKind.Indexer;\n\t\t\t}\n\t\t\telse if (name.IndexOf('.') >= 0)\n\t\t\t{\n\t\t\t\t// explicit interface implementation\n\t\t\t\tvar interfaceProp = this.ExplicitlyImplementedInterfaceMembers.FirstOrDefault() as IProperty;\n\t\t\t\tsymbolKind = interfaceProp?.SymbolKind ?? SymbolKind.Property;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsymbolKind = SymbolKind.Property;\n\t\t\t}\n\t\t}\n\n\t\tbool DetermineIsIndexer(string name)\n\t\t{\n\t\t\tif (name != (DeclaringTypeDefinition as MetadataTypeDefinition)?.DefaultMemberName)\n\t\t\t\treturn false;\n\t\t\treturn Parameters.Count > 0;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn $\"{MetadataTokens.GetToken(handle):X8} {DeclaringType?.ReflectionName}.{Name}\";\n\t\t}\n\n\t\tpublic EntityHandle MetadataToken => handle;\n\t\tpublic string Name => name;\n\n\t\tpublic bool CanGet => getter != null;\n\t\tpublic bool CanSet => setter != null;\n\n\t\tpublic IMethod Getter => getter;\n\t\tpublic IMethod Setter => setter;\n\t\tIMethod AnyAccessor => getter ?? setter;\n\n\t\tpublic bool IsIndexer => symbolKind == SymbolKind.Indexer;\n\t\tpublic SymbolKind SymbolKind => symbolKind;\n\n\t\t#region Signature (ReturnType + Parameters)\n\t\tpublic IReadOnlyList<IParameter> Parameters {\n\t\t\tget {\n\t\t\t\tvar parameters = LazyInit.VolatileRead(ref this.parameters);\n\t\t\t\tif (parameters != null)\n\t\t\t\t\treturn parameters;\n\t\t\t\tDecodeSignature();\n\t\t\t\treturn this.parameters;\n\t\t\t}\n\t\t}\n\n\t\tpublic IType ReturnType {\n\t\t\tget {\n\t\t\t\tvar returnType = LazyInit.VolatileRead(ref this.returnType);\n\t\t\t\tif (returnType != null)\n\t\t\t\t\treturn returnType;\n\t\t\t\tDecodeSignature();\n\t\t\t\treturn this.returnType;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool ReturnTypeIsRefReadOnly {\n\t\t\tget {\n\t\t\t\tvar propertyDef = module.metadata.GetPropertyDefinition(handle);\n\t\t\t\treturn propertyDef.GetCustomAttributes().HasKnownAttribute(module.metadata, KnownAttribute.IsReadOnly);\n\t\t\t}\n\t\t}\n\n\t\tprivate void DecodeSignature()\n\t\t{\n\t\t\tvar propertyDef = module.metadata.GetPropertyDefinition(handle);\n\t\t\tvar genericContext = new GenericContext(DeclaringType.TypeParameters);\n\t\t\tIType returnType;\n\t\t\tIParameter[] parameters;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar signature = propertyDef.DecodeSignature(module.TypeProvider, genericContext);\n\t\t\t\tvar accessors = propertyDef.GetAccessors();\n\t\t\t\tvar declTypeDef = this.DeclaringTypeDefinition;\n\t\t\t\tParameterHandleCollection? parameterHandles;\n\t\t\t\tNullability nullableContext;\n\t\t\t\tif (!accessors.Getter.IsNil)\n\t\t\t\t{\n\t\t\t\t\tvar getter = module.metadata.GetMethodDefinition(accessors.Getter);\n\t\t\t\t\tparameterHandles = getter.GetParameters();\n\t\t\t\t\tnullableContext = getter.GetCustomAttributes().GetNullableContext(module.metadata)\n\t\t\t\t\t\t?? declTypeDef?.NullableContext ?? Nullability.Oblivious;\n\t\t\t\t}\n\t\t\t\telse if (!accessors.Setter.IsNil)\n\t\t\t\t{\n\t\t\t\t\tvar setter = module.metadata.GetMethodDefinition(accessors.Setter);\n\t\t\t\t\tparameterHandles = setter.GetParameters();\n\t\t\t\t\tnullableContext = setter.GetCustomAttributes().GetNullableContext(module.metadata)\n\t\t\t\t\t\t?? declTypeDef?.NullableContext ?? Nullability.Oblivious;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tparameterHandles = null;\n\t\t\t\t\tnullableContext = declTypeDef?.NullableContext ?? Nullability.Oblivious;\n\t\t\t\t}\n\t\t\t\t// We call OptionsForEntity() for the declaring type, not the property itself,\n\t\t\t\t// because the property's accessibilty isn't stored in metadata but computed.\n\t\t\t\t// Otherwise we'd get infinite recursion, because computing the accessibility\n\t\t\t\t// requires decoding the signature for the GetBaseMembers() call.\n\t\t\t\t// Roslyn uses the same workaround (see the NullableTypeDecoder.TransformType\n\t\t\t\t// call in PEPropertySymbol).\n\t\t\t\tvar typeOptions = module.OptionsForEntity(declTypeDef);\n\t\t\t\t(returnType, parameters, _) = MetadataMethod.DecodeSignature(\n\t\t\t\t\tmodule, this, signature,\n\t\t\t\t\tparameterHandles, nullableContext, typeOptions,\n\t\t\t\t\tadditionalReturnTypeAttributes: propertyDef.GetCustomAttributes());\n\t\t\t}\n\t\t\tcatch (BadImageFormatException)\n\t\t\t{\n\t\t\t\treturnType = SpecialType.UnknownType;\n\t\t\t\tparameters = Empty<IParameter>.Array;\n\t\t\t}\n\t\t\tLazyInit.GetOrSet(ref this.returnType, returnType);\n\t\t\tLazyInit.GetOrSet(ref this.parameters, parameters);\n\t\t}\n\t\t#endregion\n\n\t\tpublic bool IsExplicitInterfaceImplementation => AnyAccessor?.IsExplicitInterfaceImplementation ?? false;\n\t\tpublic IEnumerable<IMember> ExplicitlyImplementedInterfaceMembers => GetInterfaceMembersFromAccessor(AnyAccessor);\n\n\t\tinternal static IEnumerable<IMember> GetInterfaceMembersFromAccessor(IMethod method)\n\t\t{\n\t\t\tif (method == null)\n\t\t\t\treturn EmptyList<IMember>.Instance;\n\t\t\treturn method.ExplicitlyImplementedInterfaceMembers.Select(m => ((IMethod)m).AccessorOwner).Where(m => m != null);\n\t\t}\n\n\t\tpublic ITypeDefinition DeclaringTypeDefinition => AnyAccessor?.DeclaringTypeDefinition;\n\t\tpublic IType DeclaringType => AnyAccessor?.DeclaringType;\n\t\tIMember IMember.MemberDefinition => this;\n\t\tTypeParameterSubstitution IMember.Substitution => TypeParameterSubstitution.Identity;\n\n\t\t#region Attributes\n\t\tpublic IEnumerable<IAttribute> GetAttributes()\n\t\t{\n\t\t\tvar b = new AttributeListBuilder(module);\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar propertyDef = metadata.GetPropertyDefinition(handle);\n\t\t\tif (IsIndexer && Name != \"Item\" && !IsExplicitInterfaceImplementation)\n\t\t\t{\n\t\t\t\tb.Add(KnownAttribute.IndexerName, KnownTypeCode.String, Name);\n\t\t\t}\n\n\t\t\t// SpecialName\n\t\t\tif ((propertyDef.Attributes & (PropertyAttributes.SpecialName | PropertyAttributes.RTSpecialName)) == PropertyAttributes.SpecialName)\n\t\t\t{\n\t\t\t\tb.Add(KnownAttribute.SpecialName);\n\t\t\t}\n\n\t\t\tb.Add(propertyDef.GetCustomAttributes(), symbolKind);\n\t\t\treturn b.Build();\n\t\t}\n\n\t\tpublic bool HasAttribute(KnownAttribute attribute)\n\t\t{\n\t\t\tif (!attribute.IsCustomAttribute())\n\t\t\t{\n\t\t\t\treturn GetAttributes().Any(attr => attr.AttributeType.IsKnownType(attribute));\n\t\t\t}\n\t\t\tvar b = new AttributeListBuilder(module);\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar def = metadata.GetPropertyDefinition(handle);\n\t\t\treturn b.HasAttribute(metadata, def.GetCustomAttributes(), attribute, symbolKind);\n\t\t}\n\n\t\tpublic IAttribute GetAttribute(KnownAttribute attribute)\n\t\t{\n\t\t\tif (!attribute.IsCustomAttribute())\n\t\t\t{\n\t\t\t\treturn GetAttributes().FirstOrDefault(attr => attr.AttributeType.IsKnownType(attribute));\n\t\t\t}\n\t\t\tvar b = new AttributeListBuilder(module);\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar def = metadata.GetPropertyDefinition(handle);\n\t\t\treturn b.GetAttribute(metadata, def.GetCustomAttributes(), attribute, symbolKind);\n\t\t}\n\t\t#endregion\n\n\t\t#region Accessibility\n\t\tpublic Accessibility Accessibility {\n\t\t\tget {\n\t\t\t\tvar acc = cachedAccessiblity;\n\t\t\t\tif (acc == InvalidAccessibility)\n\t\t\t\t\treturn cachedAccessiblity = ComputeAccessibility();\n\t\t\t\telse\n\t\t\t\t\treturn acc;\n\t\t\t}\n\t\t}\n\n\t\tAccessibility ComputeAccessibility()\n\t\t{\n\t\t\tif (IsOverride && (getter == null || setter == null))\n\t\t\t{\n\t\t\t\t// Overrides may override only one of the accessors, hence calculating the accessibility from\n\t\t\t\t// the declared accessors is not sufficient. We need to \"copy\" accessibility from the baseMember.\n\t\t\t\tforeach (var baseMember in InheritanceHelper.GetBaseMembers(this, includeImplementedInterfaces: false))\n\t\t\t\t{\n\t\t\t\t\tif (!baseMember.IsOverride)\n\t\t\t\t\t{\n\t\t\t\t\t\t// See https://github.com/icsharpcode/ILSpy/issues/2653\n\t\t\t\t\t\t// \"protected internal\" (ProtectedOrInternal) accessibility is \"reduced\"\n\t\t\t\t\t\t// to \"protected\" accessibility across assembly boundaries.\n\t\t\t\t\t\tif (baseMember.Accessibility == Accessibility.ProtectedOrInternal\n\t\t\t\t\t\t\t&& this.ParentModule?.MetadataFile != baseMember.ParentModule?.MetadataFile)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn Accessibility.Protected;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn baseMember.Accessibility;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn AccessibilityExtensions.Union(\n\t\t\t\tthis.Getter?.Accessibility ?? Accessibility.None,\n\t\t\t\tthis.Setter?.Accessibility ?? Accessibility.None);\n\t\t}\n\t\t#endregion\n\n\t\tpublic bool IsStatic => AnyAccessor?.IsStatic ?? false;\n\t\tpublic bool IsAbstract => AnyAccessor?.IsAbstract ?? false;\n\t\tpublic bool IsSealed => AnyAccessor?.IsSealed ?? false;\n\t\tpublic bool IsVirtual => AnyAccessor?.IsVirtual ?? false;\n\t\tpublic bool IsOverride => AnyAccessor?.IsOverride ?? false;\n\t\tpublic bool IsOverridable => AnyAccessor?.IsOverridable ?? false;\n\n\t\tpublic IModule ParentModule => module;\n\t\tpublic ICompilation Compilation => module.Compilation;\n\n\t\tpublic string FullName => $\"{DeclaringType?.FullName}.{Name}\";\n\t\tpublic string ReflectionName => $\"{DeclaringType?.ReflectionName}.{Name}\";\n\t\tpublic string Namespace => DeclaringType?.Namespace ?? string.Empty;\n\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\tif (obj is MetadataProperty p)\n\t\t\t{\n\t\t\t\treturn handle == p.handle && module.MetadataFile == p.module.MetadataFile;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn 0x32b6a76c ^ module.MetadataFile.GetHashCode() ^ handle.GetHashCode();\n\t\t}\n\n\t\tbool IMember.Equals(IMember obj, TypeVisitor typeNormalization)\n\t\t{\n\t\t\treturn Equals(obj);\n\t\t}\n\n\t\tpublic IMember Specialize(TypeParameterSubstitution substitution)\n\t\t{\n\t\t\treturn SpecializedProperty.Create(this, substitution);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Runtime.InteropServices;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Type definition backed by System.Reflection.Metadata\n\t/// </summary>\n\tsealed class MetadataTypeDefinition : ITypeDefinition\n\t{\n\t\treadonly MetadataModule module;\n\t\treadonly TypeDefinitionHandle handle;\n\n\t\t// eagerly loaded:\n\t\treadonly FullTypeName fullTypeName;\n\t\treadonly TypeAttributes attributes;\n\n\t\tpublic TypeKind Kind { get; }\n\t\tpublic bool IsByRefLike { get; }\n\t\tpublic bool IsReadOnly { get; }\n\t\tpublic ITypeDefinition DeclaringTypeDefinition { get; }\n\t\tpublic IReadOnlyList<ITypeParameter> TypeParameters { get; }\n\t\tpublic KnownTypeCode KnownTypeCode { get; }\n\t\tpublic IType EnumUnderlyingType { get; }\n\t\tpublic bool HasExtensions { get; }\n\t\tpublic Nullability NullableContext { get; }\n\n\t\t// lazy-loaded:\n\t\tIMember[] members;\n\t\tIField[] fields;\n\t\tIProperty[] properties;\n\t\tIEvent[] events;\n\t\tIMethod[] methods;\n\t\tList<IType> directBaseTypes;\n\t\tbool defaultMemberNameInitialized;\n\t\tstring defaultMemberName;\n\n\t\tinternal MetadataTypeDefinition(MetadataModule module, TypeDefinitionHandle handle)\n\t\t{\n\t\t\tDebug.Assert(module != null);\n\t\t\tDebug.Assert(!handle.IsNil);\n\t\t\tthis.module = module;\n\t\t\tthis.handle = handle;\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar td = metadata.GetTypeDefinition(handle);\n\t\t\tthis.attributes = td.Attributes;\n\t\t\tthis.fullTypeName = td.GetFullTypeName(metadata);\n\t\t\tthis.MetadataName = metadata.GetString(td.Name);\n\t\t\t// Find DeclaringType + KnownTypeCode:\n\t\t\tif (fullTypeName.IsNested)\n\t\t\t{\n\t\t\t\tthis.DeclaringTypeDefinition = module.GetDefinition(td.GetDeclaringType());\n\n\t\t\t\t// Create type parameters:\n\t\t\t\tthis.TypeParameters = MetadataTypeParameter.Create(module, this.DeclaringTypeDefinition, this, td.GetGenericParameters());\n\n\t\t\t\tthis.NullableContext = td.GetCustomAttributes().GetNullableContext(metadata) ?? this.DeclaringTypeDefinition.NullableContext;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Create type parameters:\n\t\t\t\tthis.TypeParameters = MetadataTypeParameter.Create(module, this, td.GetGenericParameters());\n\n\t\t\t\tthis.NullableContext = td.GetCustomAttributes().GetNullableContext(metadata) ?? module.NullableContext;\n\n\t\t\t\tvar topLevelTypeName = fullTypeName.TopLevelTypeName;\n\t\t\t\tfor (int i = 0; i < KnownTypeReference.KnownTypeCodeCount; i++)\n\t\t\t\t{\n\t\t\t\t\tvar ktr = KnownTypeReference.Get((KnownTypeCode)i);\n\t\t\t\t\tif (ktr != null && ktr.TypeName == topLevelTypeName)\n\t\t\t\t\t{\n\t\t\t\t\t\tthis.KnownTypeCode = (KnownTypeCode)i;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Find type kind:\n\t\t\tif ((attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface)\n\t\t\t{\n\t\t\t\tthis.Kind = TypeKind.Interface;\n\t\t\t}\n\t\t\telse if (td.IsEnum(metadata, out var underlyingType))\n\t\t\t{\n\t\t\t\tthis.Kind = TypeKind.Enum;\n\t\t\t\tthis.EnumUnderlyingType = module.Compilation.FindType(underlyingType.ToKnownTypeCode());\n\t\t\t}\n\t\t\telse if (td.IsValueType(metadata))\n\t\t\t{\n\t\t\t\tif (KnownTypeCode == KnownTypeCode.Void)\n\t\t\t\t{\n\t\t\t\t\tthis.Kind = TypeKind.Void;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthis.Kind = TypeKind.Struct;\n\t\t\t\t\tthis.IsByRefLike = (module.TypeSystemOptions & TypeSystemOptions.RefStructs) == TypeSystemOptions.RefStructs\n\t\t\t\t\t\t&& td.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.IsByRefLike);\n\t\t\t\t\tthis.IsReadOnly = (module.TypeSystemOptions & TypeSystemOptions.ReadOnlyStructsAndParameters) == TypeSystemOptions.ReadOnlyStructsAndParameters\n\t\t\t\t\t\t&& td.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.IsReadOnly);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (td.IsDelegate(metadata))\n\t\t\t{\n\t\t\t\tthis.Kind = TypeKind.Delegate;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.Kind = TypeKind.Class;\n\t\t\t\tthis.HasExtensions = this.IsStatic\n\t\t\t\t\t&& (module.TypeSystemOptions & TypeSystemOptions.ExtensionMethods) == TypeSystemOptions.ExtensionMethods\n\t\t\t\t\t&& td.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.Extension);\n\t\t\t}\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn $\"{MetadataTokens.GetToken(handle):X8} {fullTypeName}\";\n\t\t}\n\n\t\tprivate ExtensionInfo extensionInfo;\n\n\t\tpublic ExtensionInfo ExtensionInfo {\n\t\t\tget {\n\t\t\t\tif (!HasExtensions)\n\t\t\t\t\treturn null;\n\t\t\t\tvar extensionInfo = LazyInit.VolatileRead(ref this.extensionInfo);\n\t\t\t\tif (extensionInfo != null)\n\t\t\t\t\treturn extensionInfo;\n\t\t\t\textensionInfo = new ExtensionInfo(module, this);\n\t\t\t\tif ((module.TypeSystemOptions & TypeSystemOptions.Uncached) != 0)\n\t\t\t\t\treturn extensionInfo;\n\t\t\t\treturn LazyInit.GetOrSet(ref this.extensionInfo, extensionInfo);\n\t\t\t}\n\t\t}\n\n\t\tITypeDefinition[] nestedTypes;\n\n\t\tpublic IReadOnlyList<ITypeDefinition> NestedTypes {\n\t\t\tget {\n\t\t\t\tvar nestedTypes = LazyInit.VolatileRead(ref this.nestedTypes);\n\t\t\t\tif (nestedTypes != null)\n\t\t\t\t\treturn nestedTypes;\n\t\t\t\tvar metadata = module.metadata;\n\t\t\t\tvar nestedTypeCollection = metadata.GetTypeDefinition(handle).GetNestedTypes();\n\t\t\t\tvar nestedTypeList = new List<ITypeDefinition>(nestedTypeCollection.Length);\n\t\t\t\tforeach (TypeDefinitionHandle h in nestedTypeCollection)\n\t\t\t\t{\n\t\t\t\t\tnestedTypeList.Add(module.GetDefinition(h));\n\t\t\t\t}\n\t\t\t\tif ((module.TypeSystemOptions & TypeSystemOptions.Uncached) != 0)\n\t\t\t\t\treturn nestedTypeList;\n\t\t\t\treturn LazyInit.GetOrSet(ref this.nestedTypes, nestedTypeList.ToArray());\n\t\t\t}\n\t\t}\n\n\t\t#region Members\n\t\tpublic IReadOnlyList<IMember> Members {\n\t\t\tget {\n\t\t\t\tvar members = LazyInit.VolatileRead(ref this.members);\n\t\t\t\tif (members != null)\n\t\t\t\t\treturn members;\n\t\t\t\tmembers = this.Fields.Concat<IMember>(this.Methods).Concat(this.Properties).Concat(this.Events).ToArray();\n\t\t\t\tif ((module.TypeSystemOptions & TypeSystemOptions.Uncached) != 0)\n\t\t\t\t\treturn members;\n\t\t\t\treturn LazyInit.GetOrSet(ref this.members, members);\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable<IField> Fields {\n\t\t\tget {\n\t\t\t\tvar fields = LazyInit.VolatileRead(ref this.fields);\n\t\t\t\tif (fields != null)\n\t\t\t\t\treturn fields;\n\t\t\t\tvar metadata = module.metadata;\n\t\t\t\tvar fieldCollection = metadata.GetTypeDefinition(handle).GetFields();\n\t\t\t\tvar fieldList = new List<IField>(fieldCollection.Count);\n\t\t\t\tforeach (FieldDefinitionHandle h in fieldCollection)\n\t\t\t\t{\n\t\t\t\t\tvar field = metadata.GetFieldDefinition(h);\n\t\t\t\t\tvar attr = field.Attributes;\n\t\t\t\t\tif (module.IsVisible(attr))\n\t\t\t\t\t{\n\t\t\t\t\t\tfieldList.Add(module.GetDefinition(h));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ((module.TypeSystemOptions & TypeSystemOptions.Uncached) != 0)\n\t\t\t\t\treturn fieldList;\n\t\t\t\treturn LazyInit.GetOrSet(ref this.fields, fieldList.ToArray());\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable<IProperty> Properties {\n\t\t\tget {\n\t\t\t\tvar properties = LazyInit.VolatileRead(ref this.properties);\n\t\t\t\tif (properties != null)\n\t\t\t\t\treturn properties;\n\t\t\t\tvar metadata = module.metadata;\n\t\t\t\tvar propertyCollection = metadata.GetTypeDefinition(handle).GetProperties();\n\t\t\t\tvar propertyList = new List<IProperty>(propertyCollection.Count);\n\t\t\t\tforeach (PropertyDefinitionHandle h in propertyCollection)\n\t\t\t\t{\n\t\t\t\t\tvar property = metadata.GetPropertyDefinition(h);\n\t\t\t\t\tvar accessors = property.GetAccessors();\n\t\t\t\t\tbool getterVisible = !accessors.Getter.IsNil && module.IsVisible(metadata.GetMethodDefinition(accessors.Getter).Attributes);\n\t\t\t\t\tbool setterVisible = !accessors.Setter.IsNil && module.IsVisible(metadata.GetMethodDefinition(accessors.Setter).Attributes);\n\t\t\t\t\tif (getterVisible || setterVisible)\n\t\t\t\t\t{\n\t\t\t\t\t\tpropertyList.Add(module.GetDefinition(h));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ((module.TypeSystemOptions & TypeSystemOptions.Uncached) != 0)\n\t\t\t\t\treturn propertyList;\n\t\t\t\treturn LazyInit.GetOrSet(ref this.properties, propertyList.ToArray());\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable<IEvent> Events {\n\t\t\tget {\n\t\t\t\tvar events = LazyInit.VolatileRead(ref this.events);\n\t\t\t\tif (events != null)\n\t\t\t\t\treturn events;\n\t\t\t\tvar metadata = module.metadata;\n\t\t\t\tvar eventCollection = metadata.GetTypeDefinition(handle).GetEvents();\n\t\t\t\tvar eventList = new List<IEvent>(eventCollection.Count);\n\t\t\t\tforeach (EventDefinitionHandle h in eventCollection)\n\t\t\t\t{\n\t\t\t\t\tvar ev = metadata.GetEventDefinition(h);\n\t\t\t\t\tvar accessors = ev.GetAccessors();\n\t\t\t\t\tif (accessors.Adder.IsNil)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tvar addMethod = metadata.GetMethodDefinition(accessors.Adder);\n\t\t\t\t\tif (module.IsVisible(addMethod.Attributes))\n\t\t\t\t\t{\n\t\t\t\t\t\teventList.Add(module.GetDefinition(h));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ((module.TypeSystemOptions & TypeSystemOptions.Uncached) != 0)\n\t\t\t\t\treturn eventList;\n\t\t\t\treturn LazyInit.GetOrSet(ref this.events, eventList.ToArray());\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable<IMethod> Methods {\n\t\t\tget {\n\t\t\t\tvar methods = LazyInit.VolatileRead(ref this.methods);\n\t\t\t\tif (methods != null)\n\t\t\t\t\treturn methods;\n\t\t\t\tvar metadata = module.metadata;\n\t\t\t\tvar methodsCollection = metadata.GetTypeDefinition(handle).GetMethods();\n\t\t\t\tvar methodsList = new List<IMethod>(methodsCollection.Count);\n\t\t\t\tvar methodSemantics = module.MetadataFile.MethodSemanticsLookup;\n\t\t\t\tbool hasDefaultCtor = false;\n\t\t\t\tforeach (MethodDefinitionHandle h in methodsCollection)\n\t\t\t\t{\n\t\t\t\t\tvar md = metadata.GetMethodDefinition(h);\n\t\t\t\t\tif (methodSemantics.GetSemantics(h).Item2 == 0 && module.IsVisible(md.Attributes))\n\t\t\t\t\t{\n\t\t\t\t\t\tIMethod method = module.GetDefinition(h);\n\t\t\t\t\t\tif (method.SymbolKind == SymbolKind.Constructor && !method.IsStatic && method.Parameters.Count == 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\thasDefaultCtor = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmethodsList.Add(method);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!hasDefaultCtor && (this.Kind == TypeKind.Struct || this.Kind == TypeKind.Enum))\n\t\t\t\t{\n\t\t\t\t\tmethodsList.Add(FakeMethod.CreateDummyConstructor(Compilation, this, Accessibility.Public));\n\t\t\t\t}\n\t\t\t\tif ((module.TypeSystemOptions & TypeSystemOptions.Uncached) != 0)\n\t\t\t\t\treturn methodsList;\n\t\t\t\treturn LazyInit.GetOrSet(ref this.methods, methodsList.ToArray());\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic IType DeclaringType => DeclaringTypeDefinition;\n\n\t\tpublic bool? IsReferenceType {\n\t\t\tget {\n\t\t\t\tswitch (Kind)\n\t\t\t\t{\n\t\t\t\t\tcase TypeKind.Struct:\n\t\t\t\t\tcase TypeKind.Enum:\n\t\t\t\t\tcase TypeKind.Void:\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic int TypeParameterCount => TypeParameters.Count;\n\n\t\tIReadOnlyList<IType> IType.TypeArguments => TypeParameters;\n\n\t\tNullability IType.Nullability => Nullability.Oblivious;\n\n\t\tpublic IType ChangeNullability(Nullability nullability)\n\t\t{\n\t\t\tif (nullability == Nullability.Oblivious || IsReferenceType == false)\n\t\t\t\treturn this;\n\t\t\telse\n\t\t\t\treturn new NullabilityAnnotatedType(this, nullability);\n\t\t}\n\n\t\tpublic IEnumerable<IType> DirectBaseTypes {\n\t\t\tget {\n\t\t\t\tvar baseTypes = LazyInit.VolatileRead(ref this.directBaseTypes);\n\t\t\t\tif (baseTypes != null)\n\t\t\t\t\treturn baseTypes;\n\t\t\t\tvar metadata = module.metadata;\n\t\t\t\tvar td = metadata.GetTypeDefinition(handle);\n\t\t\t\tvar context = new GenericContext(TypeParameters);\n\t\t\t\tvar interfaceImplCollection = td.GetInterfaceImplementations();\n\t\t\t\tbaseTypes = new List<IType>(1 + interfaceImplCollection.Count);\n\t\t\t\tIType baseType = null;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tEntityHandle baseTypeHandle = td.BaseType;\n\t\t\t\t\tif (!baseTypeHandle.IsNil)\n\t\t\t\t\t{\n\t\t\t\t\t\tbaseType = module.ResolveType(baseTypeHandle, context, metadata.GetCustomAttributes(this.handle), Nullability.Oblivious);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\tbaseType = SpecialType.UnknownType;\n\t\t\t\t}\n\t\t\t\tif (baseType != null)\n\t\t\t\t{\n\t\t\t\t\tbaseTypes.Add(baseType);\n\t\t\t\t}\n\t\t\t\telse if (Kind == TypeKind.Interface)\n\t\t\t\t{\n\t\t\t\t\t// td.BaseType.IsNil is always true for interfaces,\n\t\t\t\t\t// but the type system expects every interface to derive from System.Object as well.\n\t\t\t\t\tbaseTypes.Add(Compilation.FindType(KnownTypeCode.Object));\n\t\t\t\t}\n\t\t\t\tforeach (var h in interfaceImplCollection)\n\t\t\t\t{\n\t\t\t\t\tvar iface = metadata.GetInterfaceImplementation(h);\n\t\t\t\t\tbaseTypes.Add(module.ResolveType(iface.Interface, context, iface.GetCustomAttributes(), Nullability.Oblivious));\n\t\t\t\t}\n\t\t\t\treturn LazyInit.GetOrSet(ref this.directBaseTypes, baseTypes);\n\t\t\t}\n\t\t}\n\n\t\tpublic EntityHandle MetadataToken => handle;\n\t\tpublic string MetadataName { get; }\n\t\tpublic FullTypeName FullTypeName => fullTypeName;\n\t\tpublic string Name => fullTypeName.Name;\n\n\t\tpublic IModule ParentModule => module;\n\n\t\t#region Type Attributes\n\t\tpublic IEnumerable<IAttribute> GetAttributes()\n\t\t{\n\t\t\tvar b = new AttributeListBuilder(module);\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar typeDefinition = metadata.GetTypeDefinition(handle);\n\n\t\t\t// SerializableAttribute\n\t\t\tif ((typeDefinition.Attributes & TypeAttributes.Serializable) != 0)\n\t\t\t\tb.Add(KnownAttribute.Serializable);\n\n\t\t\t// ComImportAttribute\n\t\t\tif ((typeDefinition.Attributes & TypeAttributes.Import) != 0)\n\t\t\t\tb.Add(KnownAttribute.ComImport);\n\n\t\t\t// SpecialName\n\t\t\tif ((typeDefinition.Attributes & (TypeAttributes.SpecialName | TypeAttributes.RTSpecialName)) == TypeAttributes.SpecialName)\n\t\t\t{\n\t\t\t\tb.Add(KnownAttribute.SpecialName);\n\t\t\t}\n\n\t\t\t#region StructLayoutAttribute\n\t\t\tLayoutKind layoutKind = LayoutKind.Auto;\n\t\t\tswitch (typeDefinition.Attributes & TypeAttributes.LayoutMask)\n\t\t\t{\n\t\t\t\tcase TypeAttributes.SequentialLayout:\n\t\t\t\t\tlayoutKind = LayoutKind.Sequential;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeAttributes.ExplicitLayout:\n\t\t\t\t\tlayoutKind = LayoutKind.Explicit;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tCharSet charSet = CharSet.None;\n\t\t\tswitch (typeDefinition.Attributes & TypeAttributes.StringFormatMask)\n\t\t\t{\n\t\t\t\tcase TypeAttributes.AnsiClass:\n\t\t\t\t\tcharSet = CharSet.Ansi;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeAttributes.AutoClass:\n\t\t\t\t\tcharSet = CharSet.Auto;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeAttributes.UnicodeClass:\n\t\t\t\t\tcharSet = CharSet.Unicode;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tvar layout = typeDefinition.GetLayout();\n\t\t\tLayoutKind defaultLayoutKind = Kind == TypeKind.Struct ? LayoutKind.Sequential : LayoutKind.Auto;\n\t\t\tif (layoutKind != defaultLayoutKind || charSet != CharSet.Ansi || layout.PackingSize > 0 || layout.Size > 0)\n\t\t\t{\n\t\t\t\tvar structLayout = new AttributeBuilder(module, KnownAttribute.StructLayout);\n\t\t\t\tstructLayout.AddFixedArg(\n\t\t\t\t\tnew TopLevelTypeName(\"System.Runtime.InteropServices\", \"LayoutKind\"),\n\t\t\t\t\t(int)layoutKind);\n\t\t\t\tif (charSet != CharSet.Ansi)\n\t\t\t\t{\n\t\t\t\t\tvar charSetType = Compilation.FindType(new TopLevelTypeName(\"System.Runtime.InteropServices\", \"CharSet\"));\n\t\t\t\t\tstructLayout.AddNamedArg(\"CharSet\", charSetType, (int)charSet);\n\t\t\t\t}\n\t\t\t\tif (layout.PackingSize > 0)\n\t\t\t\t{\n\t\t\t\t\tstructLayout.AddNamedArg(\"Pack\", KnownTypeCode.Int32, (int)layout.PackingSize);\n\t\t\t\t}\n\t\t\t\tif (layout.Size > 0)\n\t\t\t\t{\n\t\t\t\t\tstructLayout.AddNamedArg(\"Size\", KnownTypeCode.Int32, (int)layout.Size);\n\t\t\t\t}\n\t\t\t\tb.Add(structLayout.Build());\n\t\t\t}\n\t\t\t#endregion\n\n\t\t\tb.Add(typeDefinition.GetCustomAttributes(), SymbolKind.TypeDefinition);\n\t\t\tb.AddSecurityAttributes(typeDefinition.GetDeclarativeSecurityAttributes());\n\n\t\t\treturn b.Build();\n\t\t}\n\n\t\tpublic bool HasAttribute(KnownAttribute attribute)\n\t\t{\n\t\t\tif (!attribute.IsCustomAttribute())\n\t\t\t{\n\t\t\t\treturn GetAttributes().Any(attr => attr.AttributeType.IsKnownType(attribute));\n\t\t\t}\n\t\t\tvar b = new AttributeListBuilder(module);\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar def = metadata.GetTypeDefinition(handle);\n\t\t\treturn b.HasAttribute(metadata, def.GetCustomAttributes(), attribute, SymbolKind.TypeDefinition);\n\t\t}\n\n\t\tpublic IAttribute GetAttribute(KnownAttribute attribute)\n\t\t{\n\t\t\tif (!attribute.IsCustomAttribute())\n\t\t\t{\n\t\t\t\treturn GetAttributes().FirstOrDefault(attr => attr.AttributeType.IsKnownType(attribute));\n\t\t\t}\n\t\t\tvar b = new AttributeListBuilder(module);\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar def = metadata.GetTypeDefinition(handle);\n\t\t\treturn b.GetAttribute(metadata, def.GetCustomAttributes(), attribute, SymbolKind.TypeDefinition);\n\t\t}\n\n\t\tpublic string DefaultMemberName {\n\t\t\tget {\n\t\t\t\tstring defaultMemberName = LazyInit.VolatileRead(ref this.defaultMemberName);\n\t\t\t\tif (defaultMemberName != null || defaultMemberNameInitialized)\n\t\t\t\t\treturn defaultMemberName;\n\t\t\t\tvar metadata = module.metadata;\n\t\t\t\tvar typeDefinition = metadata.GetTypeDefinition(handle);\n\t\t\t\tforeach (var h in typeDefinition.GetCustomAttributes())\n\t\t\t\t{\n\t\t\t\t\tvar a = metadata.GetCustomAttribute(h);\n\t\t\t\t\tif (!a.IsKnownAttribute(metadata, KnownAttribute.DefaultMember))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tvar value = a.DecodeValue(module.TypeProvider);\n\t\t\t\t\tif (value.FixedArguments.Length == 1 && value.FixedArguments[0].Value is string name)\n\t\t\t\t\t{\n\t\t\t\t\t\tdefaultMemberName = name;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdefaultMemberName = LazyInit.GetOrSet(ref this.defaultMemberName, defaultMemberName);\n\t\t\t\tdefaultMemberNameInitialized = true;\n\t\t\t\treturn defaultMemberName;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic Accessibility Accessibility {\n\t\t\tget {\n\t\t\t\tswitch (attributes & TypeAttributes.VisibilityMask)\n\t\t\t\t{\n\t\t\t\t\tcase TypeAttributes.NotPublic:\n\t\t\t\t\tcase TypeAttributes.NestedAssembly:\n\t\t\t\t\t\treturn Accessibility.Internal;\n\t\t\t\t\tcase TypeAttributes.Public:\n\t\t\t\t\tcase TypeAttributes.NestedPublic:\n\t\t\t\t\t\treturn Accessibility.Public;\n\t\t\t\t\tcase TypeAttributes.NestedPrivate:\n\t\t\t\t\t\treturn Accessibility.Private;\n\t\t\t\t\tcase TypeAttributes.NestedFamily:\n\t\t\t\t\t\treturn Accessibility.Protected;\n\t\t\t\t\tcase TypeAttributes.NestedFamANDAssem:\n\t\t\t\t\t\treturn Accessibility.ProtectedAndInternal;\n\t\t\t\t\tcase TypeAttributes.NestedFamORAssem:\n\t\t\t\t\t\treturn Accessibility.ProtectedOrInternal;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn Accessibility.None;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic bool IsStatic => (attributes & (TypeAttributes.Abstract | TypeAttributes.Sealed)) == (TypeAttributes.Abstract | TypeAttributes.Sealed);\n\t\tpublic bool IsAbstract => (attributes & TypeAttributes.Abstract) != 0;\n\t\tpublic bool IsSealed => (attributes & TypeAttributes.Sealed) != 0;\n\n\t\tpublic SymbolKind SymbolKind => SymbolKind.TypeDefinition;\n\n\t\tpublic ICompilation Compilation => module.Compilation;\n\n\t\tpublic string FullName {\n\t\t\tget {\n\t\t\t\tif (DeclaringType != null)\n\t\t\t\t\treturn DeclaringType.FullName + \".\" + Name;\n\t\t\t\telse if (!string.IsNullOrEmpty(this.Namespace))\n\t\t\t\t\treturn this.Namespace + \".\" + Name;\n\t\t\t\telse\n\t\t\t\t\treturn Name;\n\t\t\t}\n\t\t}\n\n\t\tpublic string ReflectionName => fullTypeName.ReflectionName;\n\t\tpublic string Namespace => fullTypeName.TopLevelTypeName.Namespace;\n\n\t\tITypeDefinition IType.GetDefinition() => this;\n\t\tITypeDefinitionOrUnknown IType.GetDefinitionOrUnknown() => this;\n\t\tTypeParameterSubstitution IType.GetSubstitution() => TypeParameterSubstitution.Identity;\n\n\t\tpublic IType AcceptVisitor(TypeVisitor visitor)\n\t\t{\n\t\t\treturn visitor.VisitTypeDefinition(this);\n\t\t}\n\n\t\tIType IType.VisitChildren(TypeVisitor visitor)\n\t\t{\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\tif (obj is MetadataTypeDefinition td)\n\t\t\t{\n\t\t\t\treturn handle == td.handle && module.MetadataFile == td.module.MetadataFile;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn 0x2e0520f2 ^ module.MetadataFile.GetHashCode() ^ handle.GetHashCode();\n\t\t}\n\n\t\tbool IEquatable<IType>.Equals(IType other)\n\t\t{\n\t\t\treturn Equals(other);\n\t\t}\n\n\t\t#region GetNestedTypes\n\t\tpublic IEnumerable<IType> GetNestedTypes(Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tconst GetMemberOptions opt = GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions;\n\t\t\tif ((options & opt) == opt)\n\t\t\t{\n\t\t\t\treturn GetFiltered(this.NestedTypes, filter);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn GetMembersHelper.GetNestedTypes(this, filter, options);\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable<IType> GetNestedTypes(IReadOnlyList<IType> typeArguments, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn GetMembersHelper.GetNestedTypes(this, typeArguments, filter, options);\n\t\t}\n\t\t#endregion\n\n\t\t#region GetMembers()\n\t\tIEnumerable<T> GetFiltered<T>(IEnumerable<T> input, Predicate<T> filter) where T : class\n\t\t{\n\t\t\tif (filter == null)\n\t\t\t\treturn input;\n\t\t\telse\n\t\t\t\treturn ApplyFilter(input, filter);\n\t\t}\n\n\t\tIEnumerable<T> ApplyFilter<T>(IEnumerable<T> input, Predicate<T> filter) where T : class\n\t\t{\n\t\t\tforeach (var member in input)\n\t\t\t{\n\t\t\t\tif (filter(member))\n\t\t\t\t\tyield return member;\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable<IMethod> GetMethods(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif (Kind == TypeKind.Void)\n\t\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t{\n\t\t\t\treturn GetFiltered(this.Methods, ExtensionMethods.And(m => !m.IsConstructor, filter));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn GetMembersHelper.GetMethods(this, filter, options);\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif (Kind == TypeKind.Void)\n\t\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t\treturn GetMembersHelper.GetMethods(this, typeArguments, filter, options);\n\t\t}\n\n\t\tpublic IEnumerable<IMethod> GetConstructors(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers)\n\t\t{\n\t\t\tif (Kind == TypeKind.Void)\n\t\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t\tif (ComHelper.IsComImport(this))\n\t\t\t{\n\t\t\t\tIType coClass = ComHelper.GetCoClass(this);\n\t\t\t\tusing (var busyLock = BusyManager.Enter(this))\n\t\t\t\t{\n\t\t\t\t\tif (busyLock.Success)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn coClass.GetConstructors(filter, options)\n\t\t\t\t\t\t\t.Select(m => new SpecializedMethod(m, m.Substitution) { DeclaringType = this });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t\t}\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t{\n\t\t\t\treturn GetFiltered(this.Methods, ExtensionMethods.And(m => m.IsConstructor && !m.IsStatic, filter));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn GetMembersHelper.GetConstructors(this, filter, options);\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable<IProperty> GetProperties(Predicate<IProperty> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif (Kind == TypeKind.Void)\n\t\t\t\treturn EmptyList<IProperty>.Instance;\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t{\n\t\t\t\treturn GetFiltered(this.Properties, filter);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn GetMembersHelper.GetProperties(this, filter, options);\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable<IField> GetFields(Predicate<IField> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif (Kind == TypeKind.Void)\n\t\t\t\treturn EmptyList<IField>.Instance;\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t{\n\t\t\t\treturn GetFiltered(this.Fields, filter);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn GetMembersHelper.GetFields(this, filter, options);\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable<IEvent> GetEvents(Predicate<IEvent> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif (Kind == TypeKind.Void)\n\t\t\t\treturn EmptyList<IEvent>.Instance;\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t{\n\t\t\t\treturn GetFiltered(this.Events, filter);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn GetMembersHelper.GetEvents(this, filter, options);\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable<IMember> GetMembers(Predicate<IMember> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif (Kind == TypeKind.Void)\n\t\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t{\n\t\t\t\treturn GetFiltered(this.Members, filter);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn GetMembersHelper.GetMembers(this, filter, options);\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable<IMethod> GetAccessors(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif (Kind == TypeKind.Void)\n\t\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t\tif ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t{\n\t\t\t\treturn GetFilteredAccessors(filter);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn GetMembersHelper.GetAccessors(this, filter, options);\n\t\t\t}\n\t\t}\n\n\t\tIEnumerable<IMethod> GetFilteredAccessors(Predicate<IMethod> filter)\n\t\t{\n\t\t\tforeach (var prop in this.Properties)\n\t\t\t{\n\t\t\t\tvar getter = prop.Getter;\n\t\t\t\tif (getter != null && (filter == null || filter(getter)))\n\t\t\t\t\tyield return getter;\n\t\t\t\tvar setter = prop.Setter;\n\t\t\t\tif (setter != null && (filter == null || filter(setter)))\n\t\t\t\t\tyield return setter;\n\t\t\t}\n\t\t\tforeach (var ev in this.Events)\n\t\t\t{\n\t\t\t\tvar adder = ev.AddAccessor;\n\t\t\t\tif (adder != null && (filter == null || filter(adder)))\n\t\t\t\t\tyield return adder;\n\t\t\t\tvar remover = ev.RemoveAccessor;\n\t\t\t\tif (remover != null && (filter == null || filter(remover)))\n\t\t\t\t\tyield return remover;\n\t\t\t\tvar invoker = ev.InvokeAccessor;\n\t\t\t\tif (invoker != null && (filter == null || filter(invoker)))\n\t\t\t\t\tyield return remover;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region GetOverrides\n\t\tinternal IEnumerable<IMethod> GetOverrides(MethodDefinitionHandle method)\n\t\t{\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar td = metadata.GetTypeDefinition(handle);\n\t\t\tforeach (var implHandle in td.GetMethodImplementations())\n\t\t\t{\n\t\t\t\tvar impl = metadata.GetMethodImplementation(implHandle);\n\t\t\t\tif (impl.MethodBody == method)\n\t\t\t\t\tyield return module.ResolveMethod(impl.MethodDeclaration, new GenericContext(this.TypeParameters));\n\t\t\t}\n\t\t}\n\n\t\tinternal bool HasOverrides(MethodDefinitionHandle method)\n\t\t{\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar td = metadata.GetTypeDefinition(handle);\n\t\t\tforeach (var implHandle in td.GetMethodImplementations())\n\t\t\t{\n\t\t\t\tvar impl = metadata.GetMethodImplementation(implHandle);\n\t\t\t\tif (impl.MethodBody == method)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\t#endregion\n\n\t\t#region IsRecord\n\t\tbyte isRecord = ThreeState.Unknown;\n\n\t\tpublic bool IsRecord {\n\t\t\tget {\n\t\t\t\tif (isRecord == ThreeState.Unknown)\n\t\t\t\t{\n\t\t\t\t\tisRecord = ThreeState.From(ComputeIsRecord());\n\t\t\t\t}\n\t\t\t\treturn isRecord == ThreeState.True;\n\t\t\t}\n\t\t}\n\n\t\tprivate bool ComputeIsRecord()\n\t\t{\n\t\t\tif (Kind != TypeKind.Class && Kind != TypeKind.Struct)\n\t\t\t\treturn false;\n\t\t\tbool isStruct = Kind == TypeKind.Struct;\n\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar typeDef = metadata.GetTypeDefinition(handle);\n\n\t\t\tbool getEqualityContract = isStruct;\n\t\t\tbool toString = false;\n\t\t\tbool printMembers = false;\n\t\t\tbool getHashCode = false;\n\t\t\tbool equals = false;\n\t\t\tbool opEquality = false;\n\t\t\tbool opInequality = false;\n\t\t\tbool clone = isStruct;\n\t\t\tforeach (var methodHandle in typeDef.GetMethods())\n\t\t\t{\n\t\t\t\tvar method = metadata.GetMethodDefinition(methodHandle);\n\t\t\t\tif (metadata.StringComparer.Equals(method.Name, \"Clone\"))\n\t\t\t\t{\n\t\t\t\t\t// error CS8859: Members named 'Clone' are disallowed in records.\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tgetEqualityContract |= metadata.StringComparer.Equals(method.Name, \"get_EqualityContract\");\n\t\t\t\ttoString |= metadata.StringComparer.Equals(method.Name, \"ToString\");\n\t\t\t\tprintMembers |= metadata.StringComparer.Equals(method.Name, \"PrintMembers\");\n\t\t\t\tgetHashCode |= metadata.StringComparer.Equals(method.Name, \"GetHashCode\");\n\t\t\t\tequals |= metadata.StringComparer.Equals(method.Name, \"Equals\");\n\t\t\t\topEquality |= metadata.StringComparer.Equals(method.Name, \"op_Equality\");\n\t\t\t\topInequality |= metadata.StringComparer.Equals(method.Name, \"op_Inequality\");\n\t\t\t\tclone |= metadata.StringComparer.Equals(method.Name, \"<Clone>$\");\n\t\t\t}\n\t\t\t// relaxed check for toString:\n\t\t\t// record classes may have their ToString implementation only in the base class,\n\t\t\t// so we cannot check for it here, as the type hierarchy is not yet known.\n\t\t\t// usually, the existence of a \"<Clone>$\" and \"get_EqualityContract\" method should\n\t\t\t// be a good enough indicator.\n\t\t\t// in record structs we require a ToString implementation, because the PrintMembers\n\t\t\t// method needs to be called.\n\t\t\tif (isStruct && !toString)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn getEqualityContract & printMembers & getHashCode & equals & opEquality & opInequality & clone;\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeParameter.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\tsealed class MetadataTypeParameter : AbstractTypeParameter\n\t{\n\t\treadonly MetadataModule module;\n\t\treadonly GenericParameterHandle handle;\n\n\t\treadonly GenericParameterAttributes attr;\n\n\t\t// lazy-loaded:\n\t\tIReadOnlyList<TypeConstraint> constraints;\n\t\tbyte unmanagedConstraint = ThreeState.Unknown;\n\t\tconst byte nullabilityNotYetLoaded = 255;\n\t\tbyte nullabilityConstraint = nullabilityNotYetLoaded;\n\n\t\tpublic static ITypeParameter[] Create(MetadataModule module, ITypeDefinition copyFromOuter, IEntity owner, GenericParameterHandleCollection handles)\n\t\t{\n\t\t\tif (handles.Count == 0)\n\t\t\t\treturn Empty<ITypeParameter>.Array;\n\t\t\tvar outerTps = copyFromOuter.TypeParameters;\n\t\t\tvar tps = new ITypeParameter[handles.Count];\n\t\t\tint i = 0;\n\t\t\tforeach (var handle in handles)\n\t\t\t{\n\t\t\t\tif (i < outerTps.Count)\n\t\t\t\t\ttps[i] = outerTps[i];\n\t\t\t\telse\n\t\t\t\t\ttps[i] = Create(module, owner, i, handle);\n\t\t\t\ti++;\n\t\t\t}\n\t\t\treturn tps;\n\t\t}\n\n\t\tpublic static ITypeParameter[] Create(MetadataModule module, IEntity owner, GenericParameterHandleCollection handles)\n\t\t{\n\t\t\tif (handles.Count == 0)\n\t\t\t\treturn Empty<ITypeParameter>.Array;\n\t\t\tvar tps = new ITypeParameter[handles.Count];\n\t\t\tint i = 0;\n\t\t\tforeach (var handle in handles)\n\t\t\t{\n\t\t\t\ttps[i] = Create(module, owner, i, handle);\n\t\t\t\ti++;\n\t\t\t}\n\t\t\treturn tps;\n\t\t}\n\n\t\tpublic static MetadataTypeParameter Create(MetadataModule module, IEntity owner, int index, GenericParameterHandle handle)\n\t\t{\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar gp = metadata.GetGenericParameter(handle);\n\t\t\tDebug.Assert(gp.Index == index);\n\t\t\treturn new MetadataTypeParameter(module, owner, index, module.GetString(gp.Name), handle, gp.Attributes);\n\t\t}\n\n\t\tprivate MetadataTypeParameter(MetadataModule module, IEntity owner, int index, string name,\n\t\t\tGenericParameterHandle handle, GenericParameterAttributes attr)\n\t\t\t: base(owner, index, name, GetVariance(attr))\n\t\t{\n\t\t\tthis.module = module;\n\t\t\tthis.handle = handle;\n\t\t\tthis.attr = attr;\n\t\t}\n\n\t\tprivate static VarianceModifier GetVariance(GenericParameterAttributes attr)\n\t\t{\n\t\t\tswitch (attr & GenericParameterAttributes.VarianceMask)\n\t\t\t{\n\t\t\t\tcase GenericParameterAttributes.Contravariant:\n\t\t\t\t\treturn VarianceModifier.Contravariant;\n\t\t\t\tcase GenericParameterAttributes.Covariant:\n\t\t\t\t\treturn VarianceModifier.Covariant;\n\t\t\t\tdefault:\n\t\t\t\t\treturn VarianceModifier.Invariant;\n\t\t\t}\n\t\t}\n\n\t\tpublic GenericParameterHandle MetadataToken => handle;\n\n\t\tpublic override IEnumerable<IAttribute> GetAttributes()\n\t\t{\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar gp = metadata.GetGenericParameter(handle);\n\n\t\t\tvar attributes = gp.GetCustomAttributes();\n\t\t\tvar b = new AttributeListBuilder(module, attributes.Count);\n\t\t\tb.Add(attributes, SymbolKind.TypeParameter);\n\t\t\treturn b.Build();\n\t\t}\n\n\t\tpublic override bool HasDefaultConstructorConstraint => (attr & GenericParameterAttributes.DefaultConstructorConstraint) != 0;\n\t\tpublic override bool HasReferenceTypeConstraint => (attr & GenericParameterAttributes.ReferenceTypeConstraint) != 0;\n\t\tpublic override bool HasValueTypeConstraint => (attr & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0;\n\t\tpublic override bool AllowsRefLikeType => (attr & SRMExtensions.AllowByRefLike) != 0;\n\n\t\tpublic override bool HasUnmanagedConstraint {\n\t\t\tget {\n\t\t\t\tif (unmanagedConstraint == ThreeState.Unknown)\n\t\t\t\t{\n\t\t\t\t\tunmanagedConstraint = ThreeState.From(LoadUnmanagedConstraint());\n\t\t\t\t}\n\t\t\t\treturn unmanagedConstraint == ThreeState.True;\n\t\t\t}\n\t\t}\n\n\t\tprivate bool LoadUnmanagedConstraint()\n\t\t{\n\t\t\tif ((module.TypeSystemOptions & TypeSystemOptions.UnmanagedConstraints) == 0)\n\t\t\t\treturn false;\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar gp = metadata.GetGenericParameter(handle);\n\t\t\treturn gp.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.IsUnmanaged);\n\t\t}\n\n\t\tpublic override Nullability NullabilityConstraint {\n\t\t\tget {\n\t\t\t\tif (nullabilityConstraint == nullabilityNotYetLoaded)\n\t\t\t\t{\n\t\t\t\t\tnullabilityConstraint = (byte)LoadNullabilityConstraint();\n\t\t\t\t}\n\t\t\t\treturn (Nullability)nullabilityConstraint;\n\t\t\t}\n\t\t}\n\n\t\tNullability LoadNullabilityConstraint()\n\t\t{\n\t\t\tif (!module.ShouldDecodeNullableAttributes(Owner))\n\t\t\t\treturn Nullability.Oblivious;\n\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar gp = metadata.GetGenericParameter(handle);\n\n\t\t\tforeach (var handle in gp.GetCustomAttributes())\n\t\t\t{\n\t\t\t\tvar customAttribute = metadata.GetCustomAttribute(handle);\n\t\t\t\tif (customAttribute.IsKnownAttribute(metadata, KnownAttribute.Nullable))\n\t\t\t\t{\n\t\t\t\t\tvar attrVal = customAttribute.DecodeValue(module.TypeProvider);\n\t\t\t\t\tif (attrVal.FixedArguments.Length == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (attrVal.FixedArguments[0].Value is byte b && b <= 2)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn (Nullability)b;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (Owner is MetadataMethod method)\n\t\t\t{\n\t\t\t\treturn method.NullableContext;\n\t\t\t}\n\t\t\telse if (Owner is ITypeDefinition td)\n\t\t\t{\n\t\t\t\treturn td.NullableContext;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn Nullability.Oblivious;\n\t\t\t}\n\t\t}\n\n\t\tpublic override IReadOnlyList<TypeConstraint> TypeConstraints {\n\t\t\tget {\n\t\t\t\tvar constraints = LazyInit.VolatileRead(ref this.constraints);\n\t\t\t\tif (constraints == null)\n\t\t\t\t{\n\t\t\t\t\tconstraints = LazyInit.GetOrSet(ref this.constraints, DecodeConstraints());\n\t\t\t\t}\n\t\t\t\treturn constraints;\n\t\t\t}\n\t\t}\n\n\t\tprivate IReadOnlyList<TypeConstraint> DecodeConstraints()\n\t\t{\n\t\t\tvar metadata = module.metadata;\n\t\t\tvar gp = metadata.GetGenericParameter(handle);\n\t\t\tNullability nullableContext;\n\t\t\tif (Owner is ITypeDefinition typeDef)\n\t\t\t{\n\t\t\t\tnullableContext = typeDef.NullableContext;\n\t\t\t}\n\t\t\telse if (Owner is MetadataMethod method)\n\t\t\t{\n\t\t\t\tnullableContext = method.NullableContext;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tnullableContext = Nullability.Oblivious;\n\t\t\t}\n\n\t\t\tvar constraintHandleCollection = gp.GetConstraints();\n\t\t\tvar result = new List<TypeConstraint>(constraintHandleCollection.Count + 1);\n\t\t\tbool hasNonInterfaceConstraint = false;\n\t\t\tforeach (var constraintHandle in constraintHandleCollection)\n\t\t\t{\n\t\t\t\tvar constraint = metadata.GetGenericParameterConstraint(constraintHandle);\n\t\t\t\tvar attrs = constraint.GetCustomAttributes();\n\t\t\t\tvar ty = module.ResolveType(constraint.Type, new GenericContext(Owner), attrs, nullableContext);\n\t\t\t\tif (attrs.Count == 0)\n\t\t\t\t{\n\t\t\t\t\tresult.Add(new TypeConstraint(ty));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tAttributeListBuilder b = new AttributeListBuilder(module);\n\t\t\t\t\tb.Add(attrs, SymbolKind.Constraint);\n\t\t\t\t\tresult.Add(new TypeConstraint(ty, b.Build()));\n\t\t\t\t}\n\t\t\t\thasNonInterfaceConstraint |= (ty.Kind != TypeKind.Interface);\n\t\t\t}\n\t\t\tif (this.HasValueTypeConstraint)\n\t\t\t{\n\t\t\t\tresult.Add(new TypeConstraint(Compilation.FindType(KnownTypeCode.ValueType)));\n\t\t\t}\n\t\t\telse if (!hasNonInterfaceConstraint)\n\t\t\t{\n\t\t\t\tresult.Add(new TypeConstraint(Compilation.FindType(KnownTypeCode.Object)));\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn 0x51fc5b83 ^ module.MetadataFile.GetHashCode() ^ handle.GetHashCode();\n\t\t}\n\n\t\tpublic override bool Equals(IType other)\n\t\t{\n\t\t\treturn other is MetadataTypeParameter tp && handle == tp.handle && module.MetadataFile == tp.module.MetadataFile;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn $\"{MetadataTokens.GetToken(handle):X8} {ReflectionName}\";\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/MinimalCorlib.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// An artificial \"assembly\" that contains all known types (<see cref=\"KnownTypeCode\"/>) and no other types.\n\t/// It does not contain any members.\n\t/// </summary>\n\tpublic sealed class MinimalCorlib : IModule\n\t{\n\t\t/// <summary>\n\t\t/// Minimal corlib instance containing all known types.\n\t\t/// </summary>\n\t\tpublic static readonly IModuleReference Instance = new CorlibModuleReference(KnownTypeReference.AllKnownTypes);\n\n\t\tpublic static IModuleReference CreateWithTypes(IEnumerable<KnownTypeReference> types)\n\t\t{\n\t\t\treturn new CorlibModuleReference(types);\n\t\t}\n\n\t\tpublic ICompilation Compilation { get; }\n\t\tCorlibTypeDefinition[] typeDefinitions;\n\t\treadonly CorlibNamespace rootNamespace;\n\t\treadonly Version asmVersion = new Version(0, 0, 0, 0);\n\n\t\tprivate MinimalCorlib(ICompilation compilation, IEnumerable<KnownTypeReference> types)\n\t\t{\n\t\t\tthis.Compilation = compilation;\n\t\t\tthis.typeDefinitions = types.Select(ktr => new CorlibTypeDefinition(this, ktr.KnownTypeCode)).ToArray();\n\t\t\tthis.rootNamespace = new CorlibNamespace(this, null, string.Empty, string.Empty);\n\t\t}\n\n\t\tbool IModule.IsMainModule => Compilation.MainModule == this;\n\n\t\tstring IModule.AssemblyName => \"corlib\";\n\t\tVersion IModule.AssemblyVersion => asmVersion;\n\t\tstring IModule.FullAssemblyName => \"corlib\";\n\t\tstring ISymbol.Name => \"corlib\";\n\t\tSymbolKind ISymbol.SymbolKind => SymbolKind.Module;\n\n\t\tMetadata.MetadataFile IModule.MetadataFile => null;\n\t\tINamespace IModule.RootNamespace => rootNamespace;\n\n\t\tpublic IEnumerable<ITypeDefinition> TopLevelTypeDefinitions => typeDefinitions.Where(td => td != null);\n\t\tpublic IEnumerable<ITypeDefinition> TypeDefinitions => TopLevelTypeDefinitions;\n\n\t\tpublic ITypeDefinition GetTypeDefinition(TopLevelTypeName topLevelTypeName)\n\t\t{\n\t\t\tforeach (var typeDef in typeDefinitions)\n\t\t\t{\n\t\t\t\tif (typeDef.FullTypeName == topLevelTypeName)\n\t\t\t\t\treturn typeDef;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tIEnumerable<IAttribute> IModule.GetAssemblyAttributes() => EmptyList<IAttribute>.Instance;\n\t\tIEnumerable<IAttribute> IModule.GetModuleAttributes() => EmptyList<IAttribute>.Instance;\n\n\t\tbool IModule.InternalsVisibleTo(IModule module)\n\t\t{\n\t\t\treturn module == this;\n\t\t}\n\n\t\tsealed class CorlibModuleReference : IModuleReference\n\t\t{\n\t\t\treadonly IEnumerable<KnownTypeReference> types;\n\n\t\t\tpublic CorlibModuleReference(IEnumerable<KnownTypeReference> types)\n\t\t\t{\n\t\t\t\tthis.types = types;\n\t\t\t}\n\n\t\t\tIModule IModuleReference.Resolve(ITypeResolveContext context)\n\t\t\t{\n\t\t\t\treturn new MinimalCorlib(context.Compilation, types);\n\t\t\t}\n\t\t}\n\n\t\tsealed class CorlibNamespace : INamespace\n\t\t{\n\t\t\treadonly MinimalCorlib corlib;\n\t\t\tinternal List<INamespace> childNamespaces = new List<INamespace>();\n\t\t\tpublic INamespace ParentNamespace { get; }\n\t\t\tpublic string FullName { get; }\n\t\t\tpublic string Name { get; }\n\n\t\t\tpublic CorlibNamespace(MinimalCorlib corlib, INamespace parentNamespace, string fullName, string name)\n\t\t\t{\n\t\t\t\tthis.corlib = corlib;\n\t\t\t\tthis.ParentNamespace = parentNamespace;\n\t\t\t\tthis.FullName = fullName;\n\t\t\t\tthis.Name = name;\n\t\t\t}\n\n\t\t\tstring INamespace.ExternAlias => string.Empty;\n\n\t\t\tIEnumerable<INamespace> INamespace.ChildNamespaces => childNamespaces;\n\t\t\tIEnumerable<ITypeDefinition> INamespace.Types => corlib.TopLevelTypeDefinitions.Where(td => td.Namespace == FullName);\n\n\t\t\tIEnumerable<IModule> INamespace.ContributingModules => new[] { corlib };\n\n\t\t\tSymbolKind ISymbol.SymbolKind => SymbolKind.Namespace;\n\t\t\tICompilation ICompilationProvider.Compilation => corlib.Compilation;\n\n\t\t\tINamespace INamespace.GetChildNamespace(string name)\n\t\t\t{\n\t\t\t\treturn childNamespaces.FirstOrDefault(ns => ns.Name == name);\n\t\t\t}\n\n\t\t\tITypeDefinition INamespace.GetTypeDefinition(string name, int typeParameterCount)\n\t\t\t{\n\t\t\t\treturn corlib.GetTypeDefinition(this.FullName, name, typeParameterCount);\n\t\t\t}\n\t\t}\n\n\t\tsealed class CorlibTypeDefinition : ITypeDefinition\n\t\t{\n\t\t\treadonly MinimalCorlib corlib;\n\t\t\treadonly KnownTypeCode typeCode;\n\t\t\treadonly TypeKind typeKind;\n\n\t\t\tpublic CorlibTypeDefinition(MinimalCorlib corlib, KnownTypeCode typeCode)\n\t\t\t{\n\t\t\t\tthis.corlib = corlib;\n\t\t\t\tthis.typeCode = typeCode;\n\t\t\t\tKnownTypeReference ktr = KnownTypeReference.Get(typeCode);\n\t\t\t\tthis.typeKind = ktr.typeKind;\n\t\t\t\tthis.MetadataName = ktr.Name + (ktr.TypeParameterCount > 0 ? \"`\" + ktr.TypeParameterCount : \"\");\n\t\t\t}\n\n\t\t\tIReadOnlyList<ITypeDefinition> ITypeDefinition.NestedTypes => EmptyList<ITypeDefinition>.Instance;\n\t\t\tIReadOnlyList<IMember> ITypeDefinition.Members => EmptyList<IMember>.Instance;\n\t\t\tIEnumerable<IField> ITypeDefinition.Fields => EmptyList<IField>.Instance;\n\t\t\tIEnumerable<IMethod> ITypeDefinition.Methods => EmptyList<IMethod>.Instance;\n\t\t\tIEnumerable<IProperty> ITypeDefinition.Properties => EmptyList<IProperty>.Instance;\n\t\t\tIEnumerable<IEvent> ITypeDefinition.Events => EmptyList<IEvent>.Instance;\n\n\t\t\tKnownTypeCode ITypeDefinition.KnownTypeCode => typeCode;\n\n\t\t\tIType ITypeDefinition.EnumUnderlyingType => SpecialType.UnknownType;\n\n\t\t\tpublic FullTypeName FullTypeName => KnownTypeReference.Get(typeCode).TypeName;\n\n\t\t\tpublic string MetadataName { get; }\n\n\t\t\tITypeDefinition IEntity.DeclaringTypeDefinition => null;\n\t\t\tIType ITypeDefinition.DeclaringType => null;\n\t\t\tIType IType.DeclaringType => null;\n\t\t\tIType IEntity.DeclaringType => null;\n\n\t\t\tbool ITypeDefinition.HasExtensions => false;\n\t\t\tExtensionInfo ITypeDefinition.ExtensionInfo => null;\n\t\t\tbool ITypeDefinition.IsReadOnly => false;\n\n\t\t\tTypeKind IType.Kind => typeKind;\n\n\t\t\tbool? IType.IsReferenceType {\n\t\t\t\tget {\n\t\t\t\t\tswitch (typeKind)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase TypeKind.Class:\n\t\t\t\t\t\tcase TypeKind.Interface:\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tcase TypeKind.Struct:\n\t\t\t\t\t\tcase TypeKind.Enum:\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool IType.IsByRefLike => false;\n\t\t\tNullability IType.Nullability => Nullability.Oblivious;\n\t\t\tNullability ITypeDefinition.NullableContext => Nullability.Oblivious;\n\n\t\t\tIType IType.ChangeNullability(Nullability nullability)\n\t\t\t{\n\t\t\t\tif (nullability == Nullability.Oblivious)\n\t\t\t\t\treturn this;\n\t\t\t\telse\n\t\t\t\t\treturn new NullabilityAnnotatedType(this, nullability);\n\t\t\t}\n\n\t\t\tint IType.TypeParameterCount => KnownTypeReference.Get(typeCode).TypeParameterCount;\n\n\t\t\tIReadOnlyList<ITypeParameter> IType.TypeParameters => DummyTypeParameter.GetClassTypeParameterList(KnownTypeReference.Get(typeCode).TypeParameterCount);\n\t\t\tIReadOnlyList<IType> IType.TypeArguments => DummyTypeParameter.GetClassTypeParameterList(KnownTypeReference.Get(typeCode).TypeParameterCount);\n\n\t\t\tIEnumerable<IType> IType.DirectBaseTypes {\n\t\t\t\tget {\n\t\t\t\t\tvar baseType = KnownTypeReference.Get(typeCode).baseType;\n\t\t\t\t\tif (baseType != KnownTypeCode.None)\n\t\t\t\t\t\treturn new[] { corlib.Compilation.FindType(baseType) };\n\t\t\t\t\telse\n\t\t\t\t\t\treturn EmptyList<IType>.Instance;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tEntityHandle IEntity.MetadataToken => MetadataTokens.TypeDefinitionHandle(0);\n\n\t\t\tpublic string Name => KnownTypeReference.Get(typeCode).Name;\n\n\t\t\tIModule IEntity.ParentModule => corlib;\n\n\t\t\tAccessibility IEntity.Accessibility => Accessibility.Public;\n\n\t\t\tbool IEntity.IsStatic => false;\n\t\t\tbool IEntity.IsAbstract => typeKind == TypeKind.Interface;\n\t\t\tbool IEntity.IsSealed => typeKind == TypeKind.Struct;\n\n\t\t\tSymbolKind ISymbol.SymbolKind => SymbolKind.TypeDefinition;\n\n\t\t\tICompilation ICompilationProvider.Compilation => corlib.Compilation;\n\n\t\t\tstring INamedElement.FullName {\n\t\t\t\tget {\n\t\t\t\t\tvar ktr = KnownTypeReference.Get(typeCode);\n\t\t\t\t\treturn ktr.Namespace + \".\" + ktr.Name;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tstring INamedElement.ReflectionName => KnownTypeReference.Get(typeCode).TypeName.ReflectionName;\n\n\t\t\tstring INamedElement.Namespace => KnownTypeReference.Get(typeCode).Namespace;\n\n\t\t\tbool IEquatable<IType>.Equals(IType other)\n\t\t\t{\n\t\t\t\treturn this == other;\n\t\t\t}\n\n\t\t\tIEnumerable<IMethod> IType.GetAccessors(Predicate<IMethod> filter, GetMemberOptions options)\n\t\t\t{\n\t\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t\t}\n\n\t\t\tIEnumerable<IAttribute> IEntity.GetAttributes() => EmptyList<IAttribute>.Instance;\n\t\t\tbool IEntity.HasAttribute(KnownAttribute attribute) => false;\n\t\t\tIAttribute IEntity.GetAttribute(KnownAttribute attribute) => null;\n\n\t\t\tIEnumerable<IMethod> IType.GetConstructors(Predicate<IMethod> filter, GetMemberOptions options)\n\t\t\t{\n\t\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t\t}\n\n\t\t\tIEnumerable<IEvent> IType.GetEvents(Predicate<IEvent> filter, GetMemberOptions options)\n\t\t\t{\n\t\t\t\treturn EmptyList<IEvent>.Instance;\n\t\t\t}\n\n\t\t\tIEnumerable<IField> IType.GetFields(Predicate<IField> filter, GetMemberOptions options)\n\t\t\t{\n\t\t\t\treturn EmptyList<IField>.Instance;\n\t\t\t}\n\n\t\t\tIEnumerable<IMember> IType.GetMembers(Predicate<IMember> filter, GetMemberOptions options)\n\t\t\t{\n\t\t\t\treturn EmptyList<IMember>.Instance;\n\t\t\t}\n\n\t\t\tIEnumerable<IMethod> IType.GetMethods(Predicate<IMethod> filter, GetMemberOptions options)\n\t\t\t{\n\t\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t\t}\n\n\t\t\tIEnumerable<IMethod> IType.GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IMethod> filter, GetMemberOptions options)\n\t\t\t{\n\t\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t\t}\n\n\t\t\tIEnumerable<IType> IType.GetNestedTypes(Predicate<ITypeDefinition> filter, GetMemberOptions options)\n\t\t\t{\n\t\t\t\treturn EmptyList<IType>.Instance;\n\t\t\t}\n\n\t\t\tIEnumerable<IType> IType.GetNestedTypes(IReadOnlyList<IType> typeArguments, Predicate<ITypeDefinition> filter, GetMemberOptions options)\n\t\t\t{\n\t\t\t\treturn EmptyList<IType>.Instance;\n\t\t\t}\n\n\t\t\tIEnumerable<IProperty> IType.GetProperties(Predicate<IProperty> filter, GetMemberOptions options)\n\t\t\t{\n\t\t\t\treturn EmptyList<IProperty>.Instance;\n\t\t\t}\n\n\t\t\tbool ITypeDefinition.IsRecord => false;\n\n\t\t\tITypeDefinition IType.GetDefinition() => this;\n\t\t\tITypeDefinitionOrUnknown IType.GetDefinitionOrUnknown() => this;\n\t\t\tTypeParameterSubstitution IType.GetSubstitution() => TypeParameterSubstitution.Identity;\n\n\t\t\tIType IType.AcceptVisitor(TypeVisitor visitor)\n\t\t\t{\n\t\t\t\treturn visitor.VisitTypeDefinition(this);\n\t\t\t}\n\n\t\t\tIType IType.VisitChildren(TypeVisitor visitor)\n\t\t\t{\n\t\t\t\treturn this;\n\t\t\t}\n\n\t\t\tpublic override string ToString()\n\t\t\t{\n\t\t\t\treturn $\"[MinimalCorlibType {typeCode}]\";\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/NestedTypeReference.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Type reference used to reference nested types.\n\t/// </summary>\n\t[Serializable]\n\tpublic sealed class NestedTypeReference : ITypeReference, ISupportsInterning\n\t{\n\t\treadonly ITypeReference declaringTypeRef;\n\t\treadonly string name;\n\t\treadonly int additionalTypeParameterCount;\n\t\treadonly bool? isReferenceType;\n\n\t\t/// <summary>\n\t\t/// Creates a new NestedTypeReference.\n\t\t/// </summary>\n\t\t/// <param name=\"declaringTypeRef\">Reference to the declaring type.</param>\n\t\t/// <param name=\"name\">Name of the nested class</param>\n\t\t/// <param name=\"additionalTypeParameterCount\">Number of type parameters on the inner class (without type parameters on baseTypeRef)</param>\n\t\t/// <remarks>\n\t\t/// <paramref name=\"declaringTypeRef\"/> must be exactly the (unbound) declaring type, not a derived type, not a parameterized type.\n\t\t/// NestedTypeReference thus always resolves to a type definition, never to (partially) parameterized types.\n\t\t/// </remarks>\n\t\tpublic NestedTypeReference(ITypeReference declaringTypeRef, string name, int additionalTypeParameterCount, bool? isReferenceType = null)\n\t\t{\n\t\t\tif (declaringTypeRef == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(declaringTypeRef));\n\t\t\tif (name == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(name));\n\t\t\tthis.declaringTypeRef = declaringTypeRef;\n\t\t\tthis.name = name;\n\t\t\tthis.additionalTypeParameterCount = additionalTypeParameterCount;\n\t\t\tthis.isReferenceType = isReferenceType;\n\t\t}\n\n\t\tpublic ITypeReference DeclaringTypeReference {\n\t\t\tget { return declaringTypeRef; }\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget { return name; }\n\t\t}\n\n\t\tpublic int AdditionalTypeParameterCount {\n\t\t\tget { return additionalTypeParameterCount; }\n\t\t}\n\n\t\tpublic IType Resolve(ITypeResolveContext context)\n\t\t{\n\t\t\tITypeDefinition declaringType = declaringTypeRef.Resolve(context) as ITypeDefinition;\n\t\t\tif (declaringType != null)\n\t\t\t{\n\t\t\t\tint tpc = declaringType.TypeParameterCount;\n\t\t\t\tforeach (IType type in declaringType.NestedTypes)\n\t\t\t\t{\n\t\t\t\t\tif (type.Name == name && type.TypeParameterCount == tpc + additionalTypeParameterCount)\n\t\t\t\t\t\treturn type;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn new UnknownType(null, name, additionalTypeParameterCount);\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tif (additionalTypeParameterCount == 0)\n\t\t\t\treturn declaringTypeRef + \"+\" + name;\n\t\t\telse\n\t\t\t\treturn declaringTypeRef + \"+\" + name + \"`\" + additionalTypeParameterCount;\n\t\t}\n\n\t\tint ISupportsInterning.GetHashCodeForInterning()\n\t\t{\n\t\t\treturn declaringTypeRef.GetHashCode() ^ name.GetHashCode() ^ additionalTypeParameterCount;\n\t\t}\n\n\t\tbool ISupportsInterning.EqualsForInterning(ISupportsInterning other)\n\t\t{\n\t\t\tNestedTypeReference o = other as NestedTypeReference;\n\t\t\treturn o != null && declaringTypeRef == o.declaringTypeRef && name == o.name\n\t\t\t\t&& additionalTypeParameterCount == o.additionalTypeParameterCount\n\t\t\t\t&& isReferenceType == o.isReferenceType;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/NullabilityAnnotatedType.cs",
    "content": "using System.Collections.Generic;\nusing System.Diagnostics;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// A decorator that annotates the nullability status for a type.\n\t/// Note: ArrayType does not use a decorator, but has direct support for nullability.\n\t/// </summary>\n\tpublic class NullabilityAnnotatedType : DecoratedType, IType\n\t{\n\t\treadonly Nullability nullability;\n\n\t\tinternal NullabilityAnnotatedType(IType type, Nullability nullability)\n\t\t\t: base(type)\n\t\t{\n\t\t\tDebug.Assert(type.Nullability == Nullability.Oblivious);\n\t\t\tDebug.Assert(nullability != Nullability.Oblivious);\n\t\t\t// Due to IType -> concrete type casts all over the type system, we can insert\n\t\t\t// the NullabilityAnnotatedType wrapper only in some limited places.\n\t\t\tDebug.Assert(type is ITypeDefinition { IsReferenceType: not false }\n\t\t\t\t|| type.Kind == TypeKind.Dynamic\n\t\t\t\t|| type.Kind == TypeKind.Unknown\n\t\t\t\t|| (type is ITypeParameter && this is ITypeParameter));\n\t\t\tthis.nullability = nullability;\n\t\t}\n\n\t\tpublic Nullability Nullability => nullability;\n\n\t\tpublic IType TypeWithoutAnnotation => baseType;\n\n\t\tpublic override IType AcceptVisitor(TypeVisitor visitor)\n\t\t{\n\t\t\treturn visitor.VisitNullabilityAnnotatedType(this);\n\t\t}\n\n\t\tpublic override bool Equals(IType other)\n\t\t{\n\t\t\treturn other is NullabilityAnnotatedType nat\n\t\t\t\t&& nat.nullability == nullability\n\t\t\t\t&& nat.baseType.Equals(baseType);\n\t\t}\n\n\t\tpublic override IType ChangeNullability(Nullability nullability)\n\t\t{\n\t\t\tif (nullability == this.nullability)\n\t\t\t\treturn this;\n\t\t\telse\n\t\t\t\treturn baseType.ChangeNullability(nullability);\n\t\t}\n\n\t\tpublic override IType VisitChildren(TypeVisitor visitor)\n\t\t{\n\t\t\tIType newBase = baseType.AcceptVisitor(visitor);\n\t\t\tif (newBase != baseType)\n\t\t\t{\n\t\t\t\tif (newBase.Nullability == Nullability.Nullable)\n\t\t\t\t{\n\t\t\t\t\t// `T!` with substitution T=`U?` becomes `U?`\n\t\t\t\t\t// This happens during type substitution for generic methods.\n\t\t\t\t\treturn newBase;\n\t\t\t\t}\n\t\t\t\tif (newBase.Kind == TypeKind.TypeParameter || newBase.IsReferenceType == true)\n\t\t\t\t{\n\t\t\t\t\treturn newBase.ChangeNullability(nullability);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// `T!` with substitution T=`int` becomes `int`, not `int!`\n\t\t\t\t\treturn newBase;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tswitch (nullability)\n\t\t\t{\n\t\t\t\tcase Nullability.Nullable:\n\t\t\t\t\treturn $\"{baseType.ToString()}?\";\n\t\t\t\tcase Nullability.NotNullable:\n\t\t\t\t\treturn $\"{baseType.ToString()}!\";\n\t\t\t\tdefault:\n\t\t\t\t\tDebug.Assert(nullability == Nullability.Oblivious);\n\t\t\t\t\treturn $\"{baseType.ToString()}~\";\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic sealed class NullabilityAnnotatedTypeParameter : NullabilityAnnotatedType, ITypeParameter\n\t{\n\t\treadonly new ITypeParameter baseType;\n\n\t\tinternal NullabilityAnnotatedTypeParameter(ITypeParameter type, Nullability nullability)\n\t\t\t: base(type, nullability)\n\t\t{\n\t\t\tthis.baseType = type;\n\t\t}\n\n\t\tpublic ITypeParameter OriginalTypeParameter => baseType;\n\n\t\tSymbolKind ITypeParameter.OwnerType => baseType.OwnerType;\n\t\tIEntity ITypeParameter.Owner => baseType.Owner;\n\t\tint ITypeParameter.Index => baseType.Index;\n\t\tstring ITypeParameter.Name => baseType.Name;\n\t\tstring ISymbol.Name => baseType.Name;\n\t\tVarianceModifier ITypeParameter.Variance => baseType.Variance;\n\t\tIType ITypeParameter.EffectiveBaseClass => baseType.EffectiveBaseClass;\n\t\tIReadOnlyCollection<IType> ITypeParameter.EffectiveInterfaceSet => baseType.EffectiveInterfaceSet;\n\t\tbool ITypeParameter.HasDefaultConstructorConstraint => baseType.HasDefaultConstructorConstraint;\n\t\tbool ITypeParameter.HasReferenceTypeConstraint => baseType.HasReferenceTypeConstraint;\n\t\tbool ITypeParameter.HasValueTypeConstraint => baseType.HasValueTypeConstraint;\n\t\tbool ITypeParameter.HasUnmanagedConstraint => baseType.HasUnmanagedConstraint;\n\t\tbool ITypeParameter.AllowsRefLikeType => baseType.AllowsRefLikeType;\n\t\tNullability ITypeParameter.NullabilityConstraint => baseType.NullabilityConstraint;\n\t\tIReadOnlyList<TypeConstraint> ITypeParameter.TypeConstraints => baseType.TypeConstraints;\n\t\tSymbolKind ISymbol.SymbolKind => SymbolKind.TypeParameter;\n\t\tIEnumerable<IAttribute> ITypeParameter.GetAttributes() => baseType.GetAttributes();\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/PinnedType.cs",
    "content": "// Copyright (c) 2017 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Util;\n\nusing SRM = System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\tpublic sealed class PinnedType : TypeWithElementType\n\t{\n\t\tpublic PinnedType(IType elementType)\n\t\t\t: base(elementType)\n\t\t{\n\t\t}\n\n\t\tpublic override string NameSuffix => \" pinned\";\n\n\t\tpublic override bool? IsReferenceType => elementType.IsReferenceType;\n\t\tpublic override bool IsByRefLike => elementType.IsByRefLike;\n\n\t\tpublic override TypeKind Kind => TypeKind.Other;\n\n\t\tpublic override IType VisitChildren(TypeVisitor visitor)\n\t\t{\n\t\t\tvar newType = elementType.AcceptVisitor(visitor);\n\t\t\tif (newType == elementType)\n\t\t\t\treturn this;\n\t\t\treturn new PinnedType(newType);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/SimpleCompilation.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Simple compilation implementation.\n\t/// </summary>\n\tpublic class SimpleCompilation : ICompilation\n\t{\n\t\treadonly CacheManager cacheManager = new CacheManager();\n\t\tIModule mainModule;\n\t\tKnownTypeCache knownTypeCache;\n\t\tIReadOnlyList<IModule> assemblies;\n\t\tIReadOnlyList<IModule> referencedAssemblies;\n\t\tbool initialized;\n\t\tINamespace rootNamespace;\n\n\t\tpublic SimpleCompilation(IModuleReference mainAssembly, params IModuleReference[] assemblyReferences)\n\t\t{\n\t\t\tInit(mainAssembly, assemblyReferences);\n\t\t}\n\n\t\tpublic SimpleCompilation(IModuleReference mainAssembly, IEnumerable<IModuleReference> assemblyReferences)\n\t\t{\n\t\t\tInit(mainAssembly, assemblyReferences);\n\t\t}\n\n\t\tprotected SimpleCompilation()\n\t\t{\n\t\t}\n\n\t\tprotected void Init(IModuleReference mainAssembly, IEnumerable<IModuleReference> assemblyReferences)\n\t\t{\n\t\t\tif (mainAssembly == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(mainAssembly));\n\t\t\tif (assemblyReferences == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(assemblyReferences));\n\t\t\tvar context = new SimpleTypeResolveContext(this);\n\t\t\tthis.mainModule = mainAssembly.Resolve(context);\n\t\t\tList<IModule> assemblies = new List<IModule>();\n\t\t\tassemblies.Add(this.mainModule);\n\t\t\tList<IModule> referencedAssemblies = new List<IModule>();\n\t\t\tforeach (var asmRef in assemblyReferences)\n\t\t\t{\n\t\t\t\tIModule asm;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tasm = asmRef.Resolve(context);\n\t\t\t\t}\n\t\t\t\tcatch (InvalidOperationException)\n\t\t\t\t{\n\t\t\t\t\tthrow new InvalidOperationException(\"Tried to initialize compilation with an invalid assembly reference. (Forgot to load the assembly reference ? - see CecilLoader)\");\n\t\t\t\t}\n\t\t\t\tif (asm != null && !assemblies.Contains(asm))\n\t\t\t\t\tassemblies.Add(asm);\n\t\t\t\tif (asm != null && !referencedAssemblies.Contains(asm))\n\t\t\t\t\treferencedAssemblies.Add(asm);\n\t\t\t}\n\t\t\tthis.assemblies = assemblies.AsReadOnly();\n\t\t\tthis.referencedAssemblies = referencedAssemblies.AsReadOnly();\n\t\t\tthis.knownTypeCache = new KnownTypeCache(this);\n\t\t\tthis.initialized = true;\n\t\t}\n\n\t\tpublic IModule MainModule {\n\t\t\tget {\n\t\t\t\tif (!initialized)\n\t\t\t\t\tthrow new InvalidOperationException(\"Compilation isn't initialized yet\");\n\t\t\t\treturn mainModule;\n\t\t\t}\n\t\t}\n\n\t\tpublic IReadOnlyList<IModule> Modules {\n\t\t\tget {\n\t\t\t\tif (!initialized)\n\t\t\t\t\tthrow new InvalidOperationException(\"Compilation isn't initialized yet\");\n\t\t\t\treturn assemblies;\n\t\t\t}\n\t\t}\n\n\t\tpublic IReadOnlyList<IModule> ReferencedModules {\n\t\t\tget {\n\t\t\t\tif (!initialized)\n\t\t\t\t\tthrow new InvalidOperationException(\"Compilation isn't initialized yet\");\n\t\t\t\treturn referencedAssemblies;\n\t\t\t}\n\t\t}\n\n\t\tpublic INamespace RootNamespace {\n\t\t\tget {\n\t\t\t\tINamespace ns = LazyInit.VolatileRead(ref this.rootNamespace);\n\t\t\t\tif (ns != null)\n\t\t\t\t{\n\t\t\t\t\treturn ns;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (!initialized)\n\t\t\t\t\t\tthrow new InvalidOperationException(\"Compilation isn't initialized yet\");\n\t\t\t\t\treturn LazyInit.GetOrSet(ref this.rootNamespace, CreateRootNamespace());\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual INamespace CreateRootNamespace()\n\t\t{\n\t\t\t// SimpleCompilation does not support extern aliases; but derived classes might.\n\t\t\t// CreateRootNamespace() is virtual so that derived classes can change the global namespace.\n\t\t\tINamespace[] namespaces = new INamespace[referencedAssemblies.Count + 1];\n\t\t\tnamespaces[0] = mainModule.RootNamespace;\n\t\t\tfor (int i = 0; i < referencedAssemblies.Count; i++)\n\t\t\t{\n\t\t\t\tnamespaces[i + 1] = referencedAssemblies[i].RootNamespace;\n\t\t\t}\n\t\t\treturn new MergedNamespace(this, namespaces);\n\t\t}\n\n\t\tpublic CacheManager CacheManager {\n\t\t\tget { return cacheManager; }\n\t\t}\n\n\t\tpublic virtual INamespace GetNamespaceForExternAlias(string alias)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(alias))\n\t\t\t\treturn this.RootNamespace;\n\t\t\t// SimpleCompilation does not support extern aliases; but derived classes might.\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic IType FindType(KnownTypeCode typeCode)\n\t\t{\n\t\t\treturn knownTypeCache.FindType(typeCode);\n\t\t}\n\n\t\tpublic StringComparer NameComparer {\n\t\t\tget { return StringComparer.Ordinal; }\n\t\t}\n\n\t\tpublic virtual TypeSystemOptions TypeSystemOptions => TypeSystemOptions.Default;\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn \"[\" + GetType().Name + \" \" + mainModule.AssemblyName + \"]\";\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedEvent.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Represents a specialized IEvent (event after type substitution).\n\t/// </summary>\n\tpublic class SpecializedEvent : SpecializedMember, IEvent\n\t{\n\t\tpublic static IEvent Create(IEvent ev, TypeParameterSubstitution substitution)\n\t\t{\n\t\t\tif (TypeParameterSubstitution.Identity.Equals(substitution)\n\t\t\t\t|| ev.DeclaringType.TypeParameterCount == 0)\n\t\t\t{\n\t\t\t\treturn ev;\n\t\t\t}\n\t\t\tif (substitution.MethodTypeArguments != null && substitution.MethodTypeArguments.Count > 0)\n\t\t\t\tsubstitution = new TypeParameterSubstitution(substitution.ClassTypeArguments, EmptyList<IType>.Instance);\n\t\t\treturn new SpecializedEvent(ev, substitution);\n\t\t}\n\n\t\treadonly IEvent eventDefinition;\n\n\t\tpublic SpecializedEvent(IEvent eventDefinition, TypeParameterSubstitution substitution)\n\t\t\t: base(eventDefinition)\n\t\t{\n\t\t\tthis.eventDefinition = eventDefinition;\n\t\t\tAddSubstitution(substitution);\n\t\t}\n\n\t\tpublic bool CanAdd {\n\t\t\tget { return eventDefinition.CanAdd; }\n\t\t}\n\n\t\tpublic bool CanRemove {\n\t\t\tget { return eventDefinition.CanRemove; }\n\t\t}\n\n\t\tpublic bool CanInvoke {\n\t\t\tget { return eventDefinition.CanInvoke; }\n\t\t}\n\n\t\tIMethod addAccessor, removeAccessor, invokeAccessor;\n\n\t\tpublic IMethod AddAccessor {\n\t\t\tget { return WrapAccessor(ref this.addAccessor, eventDefinition.AddAccessor); }\n\t\t}\n\n\t\tpublic IMethod RemoveAccessor {\n\t\t\tget { return WrapAccessor(ref this.removeAccessor, eventDefinition.RemoveAccessor); }\n\t\t}\n\n\t\tpublic IMethod InvokeAccessor {\n\t\t\tget { return WrapAccessor(ref this.invokeAccessor, eventDefinition.InvokeAccessor); }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedField.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Represents a specialized IField (field after type substitution).\n\t/// </summary>\n\tpublic class SpecializedField : SpecializedMember, IField\n\t{\n\t\tinternal static IField Create(IField fieldDefinition, TypeParameterSubstitution substitution)\n\t\t{\n\t\t\tif (TypeParameterSubstitution.Identity.Equals(substitution) || fieldDefinition.DeclaringType.TypeParameterCount == 0)\n\t\t\t{\n\t\t\t\treturn fieldDefinition;\n\t\t\t}\n\t\t\tif (substitution.MethodTypeArguments != null && substitution.MethodTypeArguments.Count > 0)\n\t\t\t\tsubstitution = new TypeParameterSubstitution(substitution.ClassTypeArguments, EmptyList<IType>.Instance);\n\t\t\treturn new SpecializedField(fieldDefinition, substitution);\n\t\t}\n\n\t\treadonly IField fieldDefinition;\n\n\t\tpublic SpecializedField(IField fieldDefinition, TypeParameterSubstitution substitution)\n\t\t\t: base(fieldDefinition)\n\t\t{\n\t\t\tthis.fieldDefinition = fieldDefinition;\n\t\t\tAddSubstitution(substitution);\n\t\t}\n\n\t\tpublic bool IsReadOnly => fieldDefinition.IsReadOnly;\n\t\tpublic bool ReturnTypeIsRefReadOnly => fieldDefinition.ReturnTypeIsRefReadOnly;\n\t\tpublic bool IsVolatile => fieldDefinition.IsVolatile;\n\n\t\tIType IVariable.Type {\n\t\t\tget { return this.ReturnType; }\n\t\t}\n\n\t\tpublic bool IsConst {\n\t\t\tget { return fieldDefinition.IsConst; }\n\t\t}\n\n\t\tpublic object GetConstantValue(bool throwOnInvalidMetadata)\n\t\t{\n\t\t\treturn fieldDefinition.GetConstantValue(throwOnInvalidMetadata);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMember.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Text;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Represents a SpecializedMember (a member on which type substitution has been performed).\n\t/// </summary>\n\tpublic abstract class SpecializedMember : IMember\n\t{\n\t\tprotected readonly IMember baseMember;\n\t\tTypeParameterSubstitution substitution;\n\n\t\tIType declaringType;\n\t\tIType returnType;\n\n\t\tprotected SpecializedMember(IMember memberDefinition)\n\t\t{\n\t\t\tif (memberDefinition == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(memberDefinition));\n\t\t\tif (memberDefinition is SpecializedMember)\n\t\t\t\tthrow new ArgumentException(\"Member definition cannot be specialized. Please use IMember.Specialize() instead of directly constructing SpecializedMember instances.\");\n\n\t\t\tthis.baseMember = memberDefinition;\n\t\t\tthis.substitution = TypeParameterSubstitution.Identity;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Performs a substitution. This method may only be called by constructors in derived classes.\n\t\t/// </summary>\n\t\tprotected void AddSubstitution(TypeParameterSubstitution newSubstitution)\n\t\t{\n\t\t\tDebug.Assert(declaringType == null);\n\t\t\tDebug.Assert(returnType == null);\n\t\t\tthis.substitution = TypeParameterSubstitution.Compose(newSubstitution, this.substitution);\n\t\t}\n\n\t\tinternal IMethod WrapAccessor(ref IMethod cachingField, IMethod accessorDefinition)\n\t\t{\n\t\t\tif (accessorDefinition == null)\n\t\t\t\treturn null;\n\t\t\tvar result = LazyInit.VolatileRead(ref cachingField);\n\t\t\tif (result != null)\n\t\t\t{\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar sm = accessorDefinition.Specialize(substitution);\n\t\t\t\t//sm.AccessorOwner = this;\n\t\t\t\treturn LazyInit.GetOrSet(ref cachingField, sm);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the substitution belonging to this specialized member.\n\t\t/// </summary>\n\t\tpublic TypeParameterSubstitution Substitution {\n\t\t\tget { return substitution; }\n\t\t}\n\n\t\tpublic IType DeclaringType {\n\t\t\tget {\n\t\t\t\tvar result = LazyInit.VolatileRead(ref this.declaringType);\n\t\t\t\tif (result != null)\n\t\t\t\t\treturn result;\n\t\t\t\tIType definitionDeclaringType = baseMember.DeclaringType;\n\t\t\t\tITypeDefinition definitionDeclaringTypeDef = definitionDeclaringType as ITypeDefinition;\n\t\t\t\tif (definitionDeclaringTypeDef != null && definitionDeclaringType.TypeParameterCount > 0)\n\t\t\t\t{\n\t\t\t\t\tif (substitution.ClassTypeArguments != null && substitution.ClassTypeArguments.Count == definitionDeclaringType.TypeParameterCount)\n\t\t\t\t\t{\n\t\t\t\t\t\tresult = new ParameterizedType(definitionDeclaringTypeDef, substitution.ClassTypeArguments);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tresult = new ParameterizedType(definitionDeclaringTypeDef, definitionDeclaringTypeDef.TypeParameters).AcceptVisitor(substitution);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (definitionDeclaringType != null)\n\t\t\t\t{\n\t\t\t\t\tresult = definitionDeclaringType.AcceptVisitor(substitution);\n\t\t\t\t}\n\t\t\t\treturn LazyInit.GetOrSet(ref this.declaringType, result);\n\t\t\t}\n\t\t\tinternal set {\n\t\t\t\t// This setter is used as an optimization when the code constructing\n\t\t\t\t// the SpecializedMember already knows the declaring type.\n\t\t\t\tDebug.Assert(this.declaringType == null);\n\t\t\t\t// As this setter is used only during construction before the member is published\n\t\t\t\t// to other threads, we don't need a volatile write.\n\t\t\t\tthis.declaringType = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic IMember MemberDefinition {\n\t\t\tget { return baseMember.MemberDefinition; }\n\t\t}\n\n\t\tpublic IType ReturnType {\n\t\t\tget {\n\t\t\t\tvar result = LazyInit.VolatileRead(ref this.returnType);\n\t\t\t\tif (result != null)\n\t\t\t\t\treturn result;\n\t\t\t\telse\n\t\t\t\t\treturn LazyInit.GetOrSet(ref this.returnType, baseMember.ReturnType.AcceptVisitor(substitution));\n\t\t\t}\n\t\t\tprotected set {\n\t\t\t\t// This setter is used for LiftedUserDefinedOperator, a special case of specialized member\n\t\t\t\t// (not a normal type parameter substitution).\n\n\t\t\t\t// As this setter is used only during construction before the member is published\n\t\t\t\t// to other threads, we don't need a volatile write.\n\t\t\t\tthis.returnType = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic System.Reflection.Metadata.EntityHandle MetadataToken => baseMember.MetadataToken;\n\n\t\tpublic bool IsVirtual {\n\t\t\tget { return baseMember.IsVirtual; }\n\t\t}\n\n\t\tpublic bool IsOverride {\n\t\t\tget { return baseMember.IsOverride; }\n\t\t}\n\n\t\tpublic bool IsOverridable {\n\t\t\tget { return baseMember.IsOverridable; }\n\t\t}\n\n\t\tpublic SymbolKind SymbolKind {\n\t\t\tget { return baseMember.SymbolKind; }\n\t\t}\n\n\t\tpublic ITypeDefinition DeclaringTypeDefinition {\n\t\t\tget { return baseMember.DeclaringTypeDefinition; }\n\t\t}\n\n\t\tIEnumerable<IAttribute> IEntity.GetAttributes() => baseMember.GetAttributes();\n\t\tbool IEntity.HasAttribute(KnownAttribute attribute) => baseMember.HasAttribute(attribute);\n\t\tIAttribute IEntity.GetAttribute(KnownAttribute attribute) => baseMember.GetAttribute(attribute);\n\n\t\tpublic IEnumerable<IMember> ExplicitlyImplementedInterfaceMembers {\n\t\t\tget {\n\t\t\t\t// Note: if the interface is generic, then the interface members should already be specialized,\n\t\t\t\t// so we only need to append our substitution.\n\t\t\t\treturn baseMember.ExplicitlyImplementedInterfaceMembers.Select(m => m.Specialize(substitution));\n\t\t\t}\n\t\t}\n\n\t\tpublic bool IsExplicitInterfaceImplementation {\n\t\t\tget { return baseMember.IsExplicitInterfaceImplementation; }\n\t\t}\n\n\t\tpublic Accessibility Accessibility {\n\t\t\tget { return baseMember.Accessibility; }\n\t\t}\n\n\t\tpublic bool IsStatic {\n\t\t\tget { return baseMember.IsStatic; }\n\t\t}\n\n\t\tpublic bool IsAbstract {\n\t\t\tget { return baseMember.IsAbstract; }\n\t\t}\n\n\t\tpublic bool IsSealed {\n\t\t\tget { return baseMember.IsSealed; }\n\t\t}\n\n\t\tpublic string FullName {\n\t\t\tget { return baseMember.FullName; }\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget { return baseMember.Name; }\n\t\t}\n\n\t\tpublic string Namespace {\n\t\t\tget { return baseMember.Namespace; }\n\t\t}\n\n\t\tpublic string ReflectionName {\n\t\t\tget { return baseMember.ReflectionName; }\n\t\t}\n\n\t\tpublic ICompilation Compilation {\n\t\t\tget { return baseMember.Compilation; }\n\t\t}\n\n\t\tpublic IModule ParentModule {\n\t\t\tget { return baseMember.ParentModule; }\n\t\t}\n\n\t\tpublic virtual IMember Specialize(TypeParameterSubstitution newSubstitution)\n\t\t{\n\t\t\treturn baseMember.Specialize(TypeParameterSubstitution.Compose(newSubstitution, this.substitution));\n\t\t}\n\n\t\tpublic virtual bool Equals(IMember obj, TypeVisitor typeNormalization)\n\t\t{\n\t\t\tSpecializedMember other = obj as SpecializedMember;\n\t\t\tif (other == null)\n\t\t\t\treturn false;\n\t\t\treturn this.baseMember.Equals(other.baseMember, typeNormalization)\n\t\t\t\t&& this.substitution.Equals(other.substitution, typeNormalization);\n\t\t}\n\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\tSpecializedMember other = obj as SpecializedMember;\n\t\t\tif (other == null)\n\t\t\t\treturn false;\n\t\t\treturn this.baseMember.Equals(other.baseMember) && this.substitution.Equals(other.substitution);\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\treturn 1000000007 * baseMember.GetHashCode() + 1000000009 * substitution.GetHashCode();\n\t\t\t}\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tStringBuilder b = new StringBuilder(\"[\");\n\t\t\tb.Append(GetType().Name);\n\t\t\tb.Append(' ');\n\t\t\tb.Append(this.DeclaringType.ToString());\n\t\t\tb.Append('.');\n\t\t\tb.Append(this.Name);\n\t\t\tb.Append(':');\n\t\t\tb.Append(this.ReturnType.ToString());\n\t\t\tb.Append(']');\n\t\t\treturn b.ToString();\n\t\t}\n\t}\n\n\tpublic abstract class SpecializedParameterizedMember : SpecializedMember, IParameterizedMember\n\t{\n\t\tIReadOnlyList<IParameter> parameters;\n\n\t\tprotected SpecializedParameterizedMember(IParameterizedMember memberDefinition)\n\t\t\t: base(memberDefinition)\n\t\t{\n\t\t}\n\n\t\tpublic IReadOnlyList<IParameter> Parameters {\n\t\t\tget {\n\t\t\t\tvar result = LazyInit.VolatileRead(ref this.parameters);\n\t\t\t\tif (result != null)\n\t\t\t\t\treturn result;\n\t\t\t\telse\n\t\t\t\t\treturn LazyInit.GetOrSet(ref this.parameters, CreateParameters(t => t.AcceptVisitor(this.Substitution)));\n\t\t\t}\n\t\t\tprotected set {\n\t\t\t\t// This setter is used for LiftedUserDefinedOperator, a special case of specialized member\n\t\t\t\t// (not a normal type parameter substitution).\n\n\t\t\t\t// As this setter is used only during construction before the member is published\n\t\t\t\t// to other threads, we don't need a volatile write.\n\t\t\t\tthis.parameters = value;\n\t\t\t}\n\t\t}\n\n\t\tprotected IParameter[] CreateParameters(Func<IType, IType> substitution)\n\t\t{\n\t\t\tvar paramDefs = ((IParameterizedMember)this.baseMember).Parameters;\n\t\t\tif (paramDefs.Count == 0)\n\t\t\t{\n\t\t\t\treturn Empty<IParameter>.Array;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar parameters = new IParameter[paramDefs.Count];\n\t\t\t\tfor (int i = 0; i < parameters.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tvar p = paramDefs[i];\n\t\t\t\t\tIType newType = substitution(p.Type);\n\t\t\t\t\tparameters[i] = new SpecializedParameter(p, newType, this);\n\t\t\t\t}\n\t\t\t\treturn parameters;\n\t\t\t}\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tStringBuilder b = new StringBuilder(\"[\");\n\t\t\tb.Append(GetType().Name);\n\t\t\tb.Append(' ');\n\t\t\tb.Append(this.DeclaringType.ReflectionName);\n\t\t\tb.Append('.');\n\t\t\tb.Append(this.Name);\n\t\t\tb.Append('(');\n\t\t\tfor (int i = 0; i < this.Parameters.Count; i++)\n\t\t\t{\n\t\t\t\tif (i > 0)\n\t\t\t\t\tb.Append(\", \");\n\t\t\t\tb.Append(this.Parameters[i].ToString());\n\t\t\t}\n\t\t\tb.Append(\"):\");\n\t\t\tb.Append(this.ReturnType.ReflectionName);\n\t\t\tb.Append(']');\n\t\t\treturn b.ToString();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMethod.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Represents a specialized IMethod (e.g. after type substitution).\n\t/// </summary>\n\tpublic class SpecializedMethod : SpecializedParameterizedMember, IMethod\n\t{\n\t\tinternal static IMethod Create(IMethod methodDefinition, TypeParameterSubstitution substitution)\n\t\t{\n\t\t\tif (TypeParameterSubstitution.Identity.Equals(substitution))\n\t\t\t\treturn methodDefinition;\n\t\t\tif (methodDefinition.DeclaringType is ArrayType)\n\t\t\t\treturn new SpecializedMethod(methodDefinition, substitution);\n\t\t\tif (methodDefinition.TypeParameters.Count == 0)\n\t\t\t{\n\t\t\t\tif (methodDefinition.DeclaringType.TypeParameterCount == 0)\n\t\t\t\t\treturn methodDefinition;\n\t\t\t\tif (substitution.MethodTypeArguments != null && substitution.MethodTypeArguments.Count > 0)\n\t\t\t\t\tsubstitution = new TypeParameterSubstitution(substitution.ClassTypeArguments, EmptyList<IType>.Instance);\n\t\t\t}\n\t\t\treturn new SpecializedMethod(methodDefinition, substitution);\n\t\t}\n\n\t\treadonly IMethod methodDefinition;\n\t\treadonly ITypeParameter[] specializedTypeParameters;\n\t\treadonly bool isParameterized;\n\t\treadonly TypeParameterSubstitution substitutionWithoutSpecializedTypeParameters;\n\n\t\tpublic SpecializedMethod(IMethod methodDefinition, TypeParameterSubstitution substitution)\n\t\t\t: base(methodDefinition)\n\t\t{\n\t\t\tif (substitution == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(substitution));\n\t\t\tthis.methodDefinition = methodDefinition;\n\t\t\tthis.isParameterized = substitution.MethodTypeArguments != null;\n\t\t\tif (methodDefinition.TypeParameters.Count > 0)\n\t\t\t{\n\t\t\t\t// The method is generic, so we need to specialize the type parameters\n\t\t\t\t// (for specializing the constraints, and also to set the correct Owner)\n\t\t\t\tspecializedTypeParameters = new ITypeParameter[methodDefinition.TypeParameters.Count];\n\t\t\t\tfor (int i = 0; i < specializedTypeParameters.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tspecializedTypeParameters[i] = new SpecializedTypeParameter(methodDefinition.TypeParameters[i], this);\n\t\t\t\t}\n\t\t\t\tif (!isParameterized)\n\t\t\t\t{\n\t\t\t\t\t// Add substitution that replaces the base method's type parameters with our specialized version\n\t\t\t\t\t// but do this only if the type parameters on the baseMember have not already been substituted\n\t\t\t\t\tsubstitutionWithoutSpecializedTypeParameters = this.Substitution;\n\t\t\t\t\tAddSubstitution(new TypeParameterSubstitution(null, specializedTypeParameters));\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Add the main substitution after the method type parameter specialization.\n\t\t\tAddSubstitution(substitution);\n\t\t\tif (substitutionWithoutSpecializedTypeParameters != null)\n\t\t\t{\n\t\t\t\t// If we already have a substitution without specialized type parameters, update that:\n\t\t\t\tsubstitutionWithoutSpecializedTypeParameters = TypeParameterSubstitution.Compose(substitution, substitutionWithoutSpecializedTypeParameters);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Otherwise just use the whole substitution, as that doesn't contain specialized type parameters\n\t\t\t\t// in this case.\n\t\t\t\tsubstitutionWithoutSpecializedTypeParameters = this.Substitution;\n\t\t\t}\n\t\t\tif (specializedTypeParameters != null)\n\t\t\t{\n\t\t\t\t// Set the substitution on the type parameters to the final composed substitution\n\t\t\t\tforeach (var tp in specializedTypeParameters.OfType<SpecializedTypeParameter>())\n\t\t\t\t{\n\t\t\t\t\tif (tp.Owner == this)\n\t\t\t\t\t\ttp.substitution = base.Substitution;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic IReadOnlyList<IType> TypeArguments {\n\t\t\tget { return this.Substitution.MethodTypeArguments ?? EmptyList<IType>.Instance; }\n\t\t}\n\n\t\tpublic IEnumerable<IAttribute> GetReturnTypeAttributes() => methodDefinition.GetReturnTypeAttributes();\n\t\tpublic bool ReturnTypeIsRefReadOnly => methodDefinition.ReturnTypeIsRefReadOnly;\n\n\t\tbool IMethod.ThisIsRefReadOnly => methodDefinition.ThisIsRefReadOnly;\n\t\tbool IMethod.IsInitOnly => methodDefinition.IsInitOnly;\n\n\t\tpublic IReadOnlyList<ITypeParameter> TypeParameters {\n\t\t\tget {\n\t\t\t\treturn specializedTypeParameters ?? methodDefinition.TypeParameters;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool IsExtensionMethod {\n\t\t\tget { return methodDefinition.IsExtensionMethod; }\n\t\t}\n\n\t\tpublic bool IsLocalFunction {\n\t\t\tget { return methodDefinition.IsLocalFunction; }\n\t\t}\n\n\t\tpublic bool IsConstructor {\n\t\t\tget { return methodDefinition.IsConstructor; }\n\t\t}\n\n\t\tpublic bool IsDestructor {\n\t\t\tget { return methodDefinition.IsDestructor; }\n\t\t}\n\n\t\tpublic bool IsOperator {\n\t\t\tget { return methodDefinition.IsOperator; }\n\t\t}\n\n\t\tpublic bool HasBody {\n\t\t\tget { return methodDefinition.HasBody; }\n\t\t}\n\n\t\tpublic bool IsAccessor {\n\t\t\tget { return methodDefinition.IsAccessor; }\n\t\t}\n\n\t\tpublic MethodSemanticsAttributes AccessorKind => methodDefinition.AccessorKind;\n\n\t\tpublic IMethod ReducedFrom {\n\t\t\tget { return null; }\n\t\t}\n\n\t\tIMember accessorOwner;\n\n\t\tpublic IMember AccessorOwner {\n\t\t\tget {\n\t\t\t\tvar result = LazyInit.VolatileRead(ref accessorOwner);\n\t\t\t\tif (result != null)\n\t\t\t\t{\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar ownerDefinition = methodDefinition.AccessorOwner;\n\t\t\t\t\tif (ownerDefinition == null)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tresult = ownerDefinition.Specialize(this.Substitution);\n\t\t\t\t\treturn LazyInit.GetOrSet(ref accessorOwner, result);\n\t\t\t\t}\n\t\t\t}\n\t\t\tinternal set {\n\t\t\t\taccessorOwner = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool Equals(IMember obj, TypeVisitor typeNormalization)\n\t\t{\n\t\t\tSpecializedMethod other = obj as SpecializedMethod;\n\t\t\tif (other == null)\n\t\t\t\treturn false;\n\t\t\treturn this.baseMember.Equals(other.baseMember, typeNormalization)\n\t\t\t\t&& this.substitutionWithoutSpecializedTypeParameters.Equals(other.substitutionWithoutSpecializedTypeParameters, typeNormalization);\n\t\t}\n\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\tSpecializedMethod other = obj as SpecializedMethod;\n\t\t\tif (other == null)\n\t\t\t\treturn false;\n\t\t\treturn this.baseMember.Equals(other.baseMember) && this.substitutionWithoutSpecializedTypeParameters.Equals(other.substitutionWithoutSpecializedTypeParameters);\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\treturn 1000000013 * baseMember.GetHashCode() + 1000000009 * substitutionWithoutSpecializedTypeParameters.GetHashCode();\n\t\t\t}\n\t\t}\n\n\t\tpublic override IMember Specialize(TypeParameterSubstitution newSubstitution)\n\t\t{\n\t\t\treturn methodDefinition.Specialize(TypeParameterSubstitution.Compose(newSubstitution, substitutionWithoutSpecializedTypeParameters));\n\t\t}\n\n\t\tIMethod IMethod.Specialize(TypeParameterSubstitution newSubstitution)\n\t\t{\n\t\t\treturn methodDefinition.Specialize(TypeParameterSubstitution.Compose(newSubstitution, substitutionWithoutSpecializedTypeParameters));\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tStringBuilder b = new StringBuilder(\"[\");\n\t\t\tb.Append(GetType().Name);\n\t\t\tb.Append(' ');\n\t\t\tb.Append(this.DeclaringType.ReflectionName);\n\t\t\tb.Append('.');\n\t\t\tb.Append(this.Name);\n\t\t\tif (this.TypeArguments.Count > 0)\n\t\t\t{\n\t\t\t\tb.Append('[');\n\t\t\t\tfor (int i = 0; i < this.TypeArguments.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\tb.Append(\", \");\n\t\t\t\t\tb.Append(this.TypeArguments[i].ToString());\n\t\t\t\t}\n\t\t\t\tb.Append(']');\n\t\t\t}\n\t\t\telse if (this.TypeParameters.Count > 0)\n\t\t\t{\n\t\t\t\tb.Append(\"``\");\n\t\t\t\tb.Append(this.TypeParameters.Count);\n\t\t\t}\n\t\t\tb.Append('(');\n\t\t\tfor (int i = 0; i < this.Parameters.Count; i++)\n\t\t\t{\n\t\t\t\tif (i > 0)\n\t\t\t\t\tb.Append(\", \");\n\t\t\t\tb.Append(this.Parameters[i].ToString());\n\t\t\t}\n\t\t\tb.Append(\"):\");\n\t\t\tb.Append(this.ReturnType.ToString());\n\t\t\tb.Append(']');\n\t\t\treturn b.ToString();\n\t\t}\n\n\t\tsealed class SpecializedTypeParameter : AbstractTypeParameter\n\t\t{\n\t\t\treadonly ITypeParameter baseTp;\n\n\t\t\t// The substition is set at the end of SpecializedMethod constructor\n\t\t\tinternal TypeVisitor substitution;\n\n\t\t\tpublic SpecializedTypeParameter(ITypeParameter baseTp, IMethod specializedOwner)\n\t\t\t\t: base(specializedOwner, baseTp.Index, baseTp.Name, baseTp.Variance)\n\t\t\t{\n\t\t\t\t// We don't have to consider already-specialized baseTps because\n\t\t\t\t// we read the baseTp directly from the unpacked memberDefinition.\n\t\t\t\tthis.baseTp = baseTp;\n\t\t\t}\n\n\t\t\tpublic override IEnumerable<IAttribute> GetAttributes() => baseTp.GetAttributes();\n\n\t\t\tpublic override int GetHashCode()\n\t\t\t{\n\t\t\t\treturn baseTp.GetHashCode() ^ this.Owner.GetHashCode();\n\t\t\t}\n\n\t\t\tpublic override bool Equals(IType other)\n\t\t\t{\n\t\t\t\t// Compare the owner, not the substitution, because the substitution may contain this specialized type parameter recursively\n\t\t\t\tSpecializedTypeParameter o = other as SpecializedTypeParameter;\n\t\t\t\treturn o != null && baseTp.Equals(o.baseTp) && this.Owner.Equals(o.Owner);\n\t\t\t}\n\n\t\t\tpublic override bool HasValueTypeConstraint => baseTp.HasValueTypeConstraint;\n\t\t\tpublic override bool HasReferenceTypeConstraint => baseTp.HasReferenceTypeConstraint;\n\t\t\tpublic override bool HasDefaultConstructorConstraint => baseTp.HasDefaultConstructorConstraint;\n\t\t\tpublic override bool HasUnmanagedConstraint => baseTp.HasUnmanagedConstraint;\n\t\t\tpublic override bool AllowsRefLikeType => baseTp.AllowsRefLikeType;\n\n\t\t\tpublic override Nullability NullabilityConstraint => baseTp.NullabilityConstraint;\n\n\t\t\tIReadOnlyList<TypeConstraint> typeConstraints;\n\n\t\t\tpublic override IReadOnlyList<TypeConstraint> TypeConstraints {\n\t\t\t\tget {\n\t\t\t\t\tvar typeConstraints = LazyInit.VolatileRead(ref this.typeConstraints);\n\t\t\t\t\tif (typeConstraints == null)\n\t\t\t\t\t{\n\t\t\t\t\t\ttypeConstraints = baseTp.TypeConstraints.SelectReadOnlyArray(c => new TypeConstraint(c.Type.AcceptVisitor(substitution), c.Attributes));\n\t\t\t\t\t\ttypeConstraints = LazyInit.GetOrSet(ref this.typeConstraints, typeConstraints);\n\t\t\t\t\t}\n\t\t\t\t\treturn typeConstraints;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedParameter.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\tsealed class SpecializedParameter : IParameter\n\t{\n\t\treadonly IParameter baseParameter;\n\t\treadonly IType newType;\n\t\treadonly IParameterizedMember newOwner;\n\n\t\tpublic SpecializedParameter(IParameter baseParameter, IType newType, IParameterizedMember newOwner)\n\t\t{\n\t\t\tDebug.Assert(baseParameter != null && newType != null);\n\t\t\tthis.baseParameter = baseParameter;\n\t\t\tthis.newType = newType;\n\t\t\tthis.newOwner = newOwner;\n\t\t}\n\n\t\tIEnumerable<IAttribute> IParameter.GetAttributes() => baseParameter.GetAttributes();\n\t\tReferenceKind IParameter.ReferenceKind => baseParameter.ReferenceKind;\n\t\tbool IParameter.IsParams => baseParameter.IsParams;\n\t\tbool IParameter.IsOptional => baseParameter.IsOptional;\n\t\tbool IParameter.HasConstantValueInSignature => baseParameter.HasConstantValueInSignature;\n\t\tIParameterizedMember IParameter.Owner => newOwner;\n\t\tstring IVariable.Name => baseParameter.Name;\n\t\tstring ISymbol.Name => baseParameter.Name;\n\t\tIType IVariable.Type => newType;\n\t\tbool IVariable.IsConst => baseParameter.IsConst;\n\t\tobject IVariable.GetConstantValue(bool throwOnInvalidMetadata) => baseParameter.GetConstantValue(throwOnInvalidMetadata);\n\t\tSymbolKind ISymbol.SymbolKind => SymbolKind.Parameter;\n\n\t\tpublic LifetimeAnnotation Lifetime => baseParameter.Lifetime;\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn DefaultParameter.ToString(this);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedProperty.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Represents a specialized IProperty (property after type substitution).\n\t/// </summary>\n\tpublic class SpecializedProperty : SpecializedParameterizedMember, IProperty\n\t{\n\t\tinternal static IProperty Create(IProperty propertyDefinition, TypeParameterSubstitution substitution)\n\t\t{\n\t\t\tif (TypeParameterSubstitution.Identity.Equals(substitution) || propertyDefinition.DeclaringType.TypeParameterCount == 0)\n\t\t\t{\n\t\t\t\treturn propertyDefinition;\n\t\t\t}\n\t\t\tif (substitution.MethodTypeArguments != null && substitution.MethodTypeArguments.Count > 0)\n\t\t\t\tsubstitution = new TypeParameterSubstitution(substitution.ClassTypeArguments, EmptyList<IType>.Instance);\n\t\t\treturn new SpecializedProperty(propertyDefinition, substitution);\n\t\t}\n\n\t\treadonly IProperty propertyDefinition;\n\n\t\tpublic SpecializedProperty(IProperty propertyDefinition, TypeParameterSubstitution substitution)\n\t\t\t: base(propertyDefinition)\n\t\t{\n\t\t\tthis.propertyDefinition = propertyDefinition;\n\t\t\tAddSubstitution(substitution);\n\t\t}\n\n\t\tpublic bool CanGet {\n\t\t\tget { return propertyDefinition.CanGet; }\n\t\t}\n\n\t\tpublic bool CanSet {\n\t\t\tget { return propertyDefinition.CanSet; }\n\t\t}\n\n\t\tIMethod getter, setter;\n\n\t\tpublic IMethod Getter {\n\t\t\tget { return WrapAccessor(ref this.getter, propertyDefinition.Getter); }\n\t\t}\n\n\t\tpublic IMethod Setter {\n\t\t\tget { return WrapAccessor(ref this.setter, propertyDefinition.Setter); }\n\t\t}\n\n\t\tpublic bool IsIndexer {\n\t\t\tget { return propertyDefinition.IsIndexer; }\n\t\t}\n\n\t\tpublic bool ReturnTypeIsRefReadOnly => propertyDefinition.ReturnTypeIsRefReadOnly;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/SyntheticRangeIndexer.cs",
    "content": "// Copyright (c) 2020 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Synthetic method representing a compiler-generated indexer\n\t/// with the signature 'get_Item(System.Index)' or 'get_Item(System.Range)'.\n\t/// Can also be a setter.\n\t/// Used for the \"Implicit Index support\"/\"Implicit Range support\" for the C# 8 ranges feature.\n\t/// </summary>\n\tclass SyntheticRangeIndexAccessor : IMethod\n\t{\n\t\t/// <summary>\n\t\t/// The underlying method: `get_Item(int)`, `set_Item(int, T)` or `Slice(int, int)`.\n\t\t/// </summary>\n\t\treadonly IMethod underlyingMethod;\n\t\treadonly IType indexOrRangeType;\n\t\treadonly IReadOnlyList<IParameter> parameters;\n\t\treadonly bool slicing;\n\n\t\tpublic SyntheticRangeIndexAccessor(IMethod underlyingMethod, IType indexOrRangeType, bool slicing)\n\t\t{\n\t\t\tDebug.Assert(underlyingMethod != null);\n\t\t\tDebug.Assert(indexOrRangeType != null);\n\t\t\tthis.underlyingMethod = underlyingMethod;\n\t\t\tthis.indexOrRangeType = indexOrRangeType;\n\t\t\tthis.slicing = slicing;\n\t\t\tvar parameters = new List<IParameter>();\n\t\t\tparameters.Add(new DefaultParameter(indexOrRangeType, \"\"));\n\t\t\tif (slicing)\n\t\t\t{\n\t\t\t\tDebug.Assert(underlyingMethod.Parameters.Count == 2);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tparameters.AddRange(underlyingMethod.Parameters.Skip(1));\n\t\t\t}\n\t\t\tthis.parameters = parameters;\n\t\t}\n\n\t\tpublic bool IsSlicing => slicing;\n\n\t\tbool IMethod.ReturnTypeIsRefReadOnly => underlyingMethod.ReturnTypeIsRefReadOnly;\n\t\tbool IMethod.ThisIsRefReadOnly => underlyingMethod.ThisIsRefReadOnly;\n\t\tbool IMethod.IsInitOnly => underlyingMethod.IsInitOnly;\n\n\t\tIReadOnlyList<ITypeParameter> IMethod.TypeParameters => EmptyList<ITypeParameter>.Instance;\n\t\tIReadOnlyList<IType> IMethod.TypeArguments => EmptyList<IType>.Instance;\n\n\t\tbool IMethod.IsExtensionMethod => false;\n\t\tbool IMethod.IsLocalFunction => false;\n\t\tbool IMethod.IsConstructor => false;\n\t\tbool IMethod.IsDestructor => false;\n\t\tbool IMethod.IsOperator => false;\n\t\tbool IMethod.HasBody => underlyingMethod.HasBody;\n\t\tbool IMethod.IsAccessor => underlyingMethod.IsAccessor;\n\t\tIMember IMethod.AccessorOwner => underlyingMethod.AccessorOwner;\n\t\tMethodSemanticsAttributes IMethod.AccessorKind => underlyingMethod.AccessorKind;\n\t\tIMethod IMethod.ReducedFrom => underlyingMethod.ReducedFrom;\n\t\tIReadOnlyList<IParameter> IParameterizedMember.Parameters => parameters;\n\t\tIMember IMember.MemberDefinition => underlyingMethod.MemberDefinition;\n\t\tIType IMember.ReturnType => underlyingMethod.ReturnType;\n\t\tIEnumerable<IMember> IMember.ExplicitlyImplementedInterfaceMembers => EmptyList<IMember>.Instance;\n\t\tbool IMember.IsExplicitInterfaceImplementation => false;\n\t\tbool IMember.IsVirtual => underlyingMethod.IsVirtual;\n\t\tbool IMember.IsOverride => underlyingMethod.IsOverride;\n\t\tbool IMember.IsOverridable => underlyingMethod.IsOverridable;\n\t\tTypeParameterSubstitution IMember.Substitution => underlyingMethod.Substitution;\n\t\tEntityHandle IEntity.MetadataToken => underlyingMethod.MetadataToken;\n\t\tpublic string Name => underlyingMethod.Name;\n\t\tpublic IType DeclaringType => underlyingMethod.DeclaringType;\n\t\tITypeDefinition IEntity.DeclaringTypeDefinition => underlyingMethod.DeclaringTypeDefinition;\n\t\tIModule IEntity.ParentModule => underlyingMethod.ParentModule;\n\t\tAccessibility IEntity.Accessibility => underlyingMethod.Accessibility;\n\t\tbool IEntity.IsStatic => underlyingMethod.IsStatic;\n\t\tbool IEntity.IsAbstract => underlyingMethod.IsAbstract;\n\t\tbool IEntity.IsSealed => underlyingMethod.IsSealed;\n\t\tSymbolKind ISymbol.SymbolKind => SymbolKind.Method;\n\t\tICompilation ICompilationProvider.Compilation => underlyingMethod.Compilation;\n\t\tstring INamedElement.FullName => underlyingMethod.FullName;\n\t\tstring INamedElement.ReflectionName => underlyingMethod.ReflectionName;\n\t\tstring INamedElement.Namespace => underlyingMethod.Namespace;\n\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\treturn obj is SyntheticRangeIndexAccessor g\n\t\t\t\t&& this.underlyingMethod.Equals(g.underlyingMethod)\n\t\t\t\t&& this.indexOrRangeType.Equals(g.indexOrRangeType)\n\t\t\t\t&& this.slicing == g.slicing;\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn underlyingMethod.GetHashCode() ^ indexOrRangeType.GetHashCode();\n\t\t}\n\n\t\tbool IMember.Equals(IMember obj, TypeVisitor typeNormalization)\n\t\t{\n\t\t\treturn obj is SyntheticRangeIndexAccessor g\n\t\t\t\t&& this.underlyingMethod.Equals(g.underlyingMethod, typeNormalization)\n\t\t\t\t&& this.indexOrRangeType.AcceptVisitor(typeNormalization).Equals(g.indexOrRangeType.AcceptVisitor(typeNormalization));\n\t\t}\n\n\t\tIEnumerable<IAttribute> IEntity.GetAttributes() => underlyingMethod.GetAttributes();\n\t\tbool IEntity.HasAttribute(KnownAttribute attribute) => underlyingMethod.HasAttribute(attribute);\n\t\tIAttribute IEntity.GetAttribute(KnownAttribute attribute) => underlyingMethod.GetAttribute(attribute);\n\n\t\tIEnumerable<IAttribute> IMethod.GetReturnTypeAttributes() => underlyingMethod.GetReturnTypeAttributes();\n\n\t\tIMethod IMethod.Specialize(TypeParameterSubstitution substitution)\n\t\t{\n\t\t\treturn new SyntheticRangeIndexAccessor(underlyingMethod.Specialize(substitution), indexOrRangeType, slicing);\n\t\t}\n\n\t\tIMember IMember.Specialize(TypeParameterSubstitution substitution)\n\t\t{\n\t\t\treturn new SyntheticRangeIndexAccessor(underlyingMethod.Specialize(substitution), indexOrRangeType, slicing);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/ThreeState.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Constants used instead of <c>bool?</c>\n\t/// in multithreaded code, as <c>bool?</c> might produce torn reads.\n\t/// </summary>\n\tstatic class ThreeState\n\t{\n\t\tpublic const byte Unknown = 0;\n\t\tpublic const byte False = 1;\n\t\tpublic const byte True = 2;\n\n\t\tpublic static byte From(bool value) => value ? True : False;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/TypeParameterReference.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Globalization;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t[Serializable]\n\tpublic sealed class TypeParameterReference : ITypeReference\n\t{\n\t\tstatic readonly TypeParameterReference[] classTypeParameterReferences = new TypeParameterReference[8];\n\t\tstatic readonly TypeParameterReference[] methodTypeParameterReferences = new TypeParameterReference[8];\n\n\t\t/// <summary>\n\t\t/// Creates a type parameter reference.\n\t\t/// For common type parameter references, this method may return a shared instance.\n\t\t/// </summary>\n\t\tpublic static TypeParameterReference Create(SymbolKind ownerType, int index)\n\t\t{\n\t\t\tif (index >= 0 && index < 8 && (ownerType == SymbolKind.TypeDefinition || ownerType == SymbolKind.Method))\n\t\t\t{\n\t\t\t\tTypeParameterReference[] arr = (ownerType == SymbolKind.TypeDefinition) ? classTypeParameterReferences : methodTypeParameterReferences;\n\t\t\t\tTypeParameterReference result = LazyInit.VolatileRead(ref arr[index]);\n\t\t\t\tif (result == null)\n\t\t\t\t{\n\t\t\t\t\tresult = LazyInit.GetOrSet(ref arr[index], new TypeParameterReference(ownerType, index));\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new TypeParameterReference(ownerType, index);\n\t\t\t}\n\t\t}\n\n\t\treadonly SymbolKind ownerType;\n\t\treadonly int index;\n\n\t\tpublic int Index {\n\t\t\tget {\n\t\t\t\treturn index;\n\t\t\t}\n\t\t}\n\n\t\tpublic TypeParameterReference(SymbolKind ownerType, int index)\n\t\t{\n\t\t\tthis.ownerType = ownerType;\n\t\t\tthis.index = index;\n\t\t}\n\n\t\tpublic IType Resolve(ITypeResolveContext context)\n\t\t{\n\t\t\tif (ownerType == SymbolKind.Method)\n\t\t\t{\n\t\t\t\tIMethod method = context.CurrentMember as IMethod;\n\t\t\t\tif (method != null && index < method.TypeParameters.Count)\n\t\t\t\t{\n\t\t\t\t\treturn method.TypeParameters[index];\n\t\t\t\t}\n\t\t\t\treturn DummyTypeParameter.GetMethodTypeParameter(index);\n\t\t\t}\n\t\t\telse if (ownerType == SymbolKind.TypeDefinition)\n\t\t\t{\n\t\t\t\tITypeDefinition typeDef = context.CurrentTypeDefinition;\n\t\t\t\tif (typeDef != null && index < typeDef.TypeParameters.Count)\n\t\t\t\t{\n\t\t\t\t\treturn typeDef.TypeParameters[index];\n\t\t\t\t}\n\t\t\t\treturn DummyTypeParameter.GetClassTypeParameter(index);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn SpecialType.UnknownType;\n\t\t\t}\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tif (ownerType == SymbolKind.Method)\n\t\t\t\treturn \"!!\" + index.ToString(CultureInfo.InvariantCulture);\n\t\t\telse\n\t\t\t\treturn \"!\" + index.ToString(CultureInfo.InvariantCulture);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/TypeWithElementType.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\tpublic abstract class TypeWithElementType : AbstractType\n\t{\n\t\tprotected IType elementType;\n\n\t\tprotected TypeWithElementType(IType elementType)\n\t\t{\n\t\t\tif (elementType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(elementType));\n\t\t\tthis.elementType = elementType;\n\t\t}\n\n\t\tpublic override string Name {\n\t\t\tget { return elementType.Name + NameSuffix; }\n\t\t}\n\n\t\tpublic override string Namespace {\n\t\t\tget { return elementType.Namespace; }\n\t\t}\n\n\t\tpublic override string FullName {\n\t\t\tget { return elementType.FullName + NameSuffix; }\n\t\t}\n\n\t\tpublic override string ReflectionName {\n\t\t\tget { return elementType.ReflectionName + NameSuffix; }\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn elementType.ToString() + NameSuffix;\n\t\t}\n\n\t\tpublic abstract string NameSuffix { get; }\n\n\t\tpublic IType ElementType {\n\t\t\tget { return elementType; }\n\t\t}\n\n\t\t// Force concrete implementations to override VisitChildren - the base implementation\n\t\t// in AbstractType assumes there are no children, but we know there is (at least) 1.\n\t\tpublic abstract override IType VisitChildren(TypeVisitor visitor);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Implementation/UnknownType.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// An unknown type where (part) of the name is known.\n\t/// </summary>\n\t[Serializable]\n\tpublic class UnknownType : AbstractType, ITypeDefinitionOrUnknown, ITypeReference\n\t{\n\t\treadonly bool namespaceKnown;\n\t\treadonly FullTypeName fullTypeName;\n\t\treadonly bool? isReferenceType = null;\n\n\t\t/// <summary>\n\t\t/// Creates a new unknown type.\n\t\t/// </summary>\n\t\t/// <param name=\"namespaceName\">Namespace name, if known. Can be null if unknown.</param>\n\t\t/// <param name=\"name\">Name of the type, must not be null.</param>\n\t\t/// <param name=\"typeParameterCount\">Type parameter count, zero if unknown.</param>\n\t\tpublic UnknownType(string namespaceName, string name, int typeParameterCount = 0, bool? isReferenceType = null)\n\t\t{\n\t\t\tif (name == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(name));\n\t\t\tthis.namespaceKnown = namespaceName != null;\n\t\t\tthis.fullTypeName = new TopLevelTypeName(namespaceName ?? string.Empty, name, typeParameterCount);\n\t\t\tthis.isReferenceType = isReferenceType;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a new unknown type.\n\t\t/// </summary>\n\t\t/// <param name=\"fullTypeName\">Full name of the unknown type.</param>\n\t\tpublic UnknownType(FullTypeName fullTypeName, bool? isReferenceType = null)\n\t\t{\n\t\t\tthis.isReferenceType = isReferenceType;\n\t\t\tif (fullTypeName.Name == null)\n\t\t\t{\n\t\t\t\tDebug.Assert(fullTypeName == default(FullTypeName));\n\t\t\t\tthis.namespaceKnown = false;\n\t\t\t\tthis.fullTypeName = new TopLevelTypeName(string.Empty, \"?\", 0);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.namespaceKnown = true;\n\t\t\t\tthis.fullTypeName = fullTypeName;\n\t\t\t}\n\t\t}\n\n\t\tpublic override TypeKind Kind {\n\t\t\tget { return TypeKind.Unknown; }\n\t\t}\n\n\t\tIType ITypeReference.Resolve(ITypeResolveContext context)\n\t\t{\n\t\t\tif (context == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(context));\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic override ITypeDefinitionOrUnknown GetDefinitionOrUnknown()\n\t\t{\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic override string Name {\n\t\t\tget { return fullTypeName.Name; }\n\t\t}\n\n\t\tpublic override string Namespace {\n\t\t\tget { return fullTypeName.TopLevelTypeName.Namespace; }\n\t\t}\n\n\t\tpublic override string ReflectionName {\n\t\t\tget { return namespaceKnown ? fullTypeName.ReflectionName : \"?\"; }\n\t\t}\n\n\t\tpublic override string FullName {\n\t\t\tget { return namespaceKnown ? fullTypeName.FullName : \"?\"; }\n\t\t}\n\n\t\tpublic FullTypeName FullTypeName => fullTypeName;\n\n\t\tpublic override int TypeParameterCount => fullTypeName.TypeParameterCount;\n\t\tpublic override IReadOnlyList<ITypeParameter> TypeParameters => DummyTypeParameter.GetClassTypeParameterList(TypeParameterCount);\n\t\tpublic override IReadOnlyList<IType> TypeArguments => TypeParameters;\n\n\t\tpublic override bool? IsReferenceType {\n\t\t\tget { return isReferenceType; }\n\t\t}\n\n\t\tpublic override IType ChangeNullability(Nullability nullability)\n\t\t{\n\t\t\tif (nullability == Nullability.Oblivious || isReferenceType == false)\n\t\t\t\treturn this;\n\t\t\telse\n\t\t\t\treturn new NullabilityAnnotatedType(this, nullability);\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn (namespaceKnown ? 812571 : 12651) ^ fullTypeName.GetHashCode();\n\t\t}\n\n\t\tpublic override bool Equals(IType other)\n\t\t{\n\t\t\tUnknownType o = other as UnknownType;\n\t\t\tif (o == null)\n\t\t\t\treturn false;\n\t\t\treturn this.namespaceKnown == o.namespaceKnown && this.fullTypeName == o.fullTypeName && this.isReferenceType == o.isReferenceType;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn \"[UnknownType \" + fullTypeName.ReflectionName + \"]\";\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/InheritanceHelper.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\n#nullable enable\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Provides helper methods for inheritance.\n\t/// </summary>\n\tpublic static class InheritanceHelper\n\t{\n\t\t// TODO: maybe these should be extension methods?\n\t\t// or even part of the interface itself? (would allow for easy caching)\n\n\t\t#region GetBaseMember\n\t\t/// <summary>\n\t\t/// Gets the base member that has the same signature.\n\t\t/// </summary>\n\t\tpublic static IMember? GetBaseMember(IMember member)\n\t\t{\n\t\t\treturn GetBaseMembers(member, false).FirstOrDefault();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets all base members that have the same signature.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// List of base members with the same signature. The member from the derived-most base class is returned first.\n\t\t/// </returns>\n\t\tpublic static IEnumerable<IMember> GetBaseMembers(IMember member, bool includeImplementedInterfaces)\n\t\t{\n\t\t\tif (member == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(member));\n\n\t\t\tif (includeImplementedInterfaces)\n\t\t\t{\n\t\t\t\tif (member.IsExplicitInterfaceImplementation && member.ExplicitlyImplementedInterfaceMembers.Count() == 1)\n\t\t\t\t{\n\t\t\t\t\t// C#-style explicit interface implementation\n\t\t\t\t\tmember = member.ExplicitlyImplementedInterfaceMembers.First();\n\t\t\t\t\tyield return member;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic specialization\n\t\t\tvar substitution = member.Substitution;\n\t\t\tmember = member.MemberDefinition;\n\n\t\t\tif (member.DeclaringTypeDefinition == null)\n\t\t\t{\n\t\t\t\t// For global methods, return empty list. (prevent SharpDevelop UDC crash 4524)\n\t\t\t\tyield break;\n\t\t\t}\n\n\t\t\tIEnumerable<IType> allBaseTypes;\n\t\t\tif (includeImplementedInterfaces)\n\t\t\t{\n\t\t\t\tallBaseTypes = member.DeclaringTypeDefinition.GetAllBaseTypes();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tallBaseTypes = member.DeclaringTypeDefinition.GetNonInterfaceBaseTypes();\n\t\t\t}\n\t\t\tforeach (IType baseType in allBaseTypes.Reverse())\n\t\t\t{\n\t\t\t\tif (baseType == member.DeclaringTypeDefinition)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tIEnumerable<IMember> baseMembers;\n\t\t\t\tif (member.SymbolKind == SymbolKind.Accessor)\n\t\t\t\t{\n\t\t\t\t\tbaseMembers = baseType.GetAccessors(m => m.Name == member.Name && m.Accessibility > Accessibility.Private, GetMemberOptions.IgnoreInheritedMembers);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbaseMembers = baseType.GetMembers(m => m.Name == member.Name && m.Accessibility > Accessibility.Private, GetMemberOptions.IgnoreInheritedMembers);\n\t\t\t\t}\n\t\t\t\tforeach (IMember baseMember in baseMembers)\n\t\t\t\t{\n\t\t\t\t\tSystem.Diagnostics.Debug.Assert(baseMember.Accessibility != Accessibility.Private);\n\t\t\t\t\tif (SignatureComparer.Ordinal.Equals(member, baseMember))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return baseMember.Specialize(substitution);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region GetDerivedMember\n\t\t/// <summary>\n\t\t/// Finds the member declared in 'derivedType' that has the same signature (could override) 'baseMember'.\n\t\t/// </summary>\n\t\tpublic static IMember? GetDerivedMember(IMember baseMember, ITypeDefinition derivedType)\n\t\t{\n\t\t\tif (baseMember == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(baseMember));\n\t\t\tif (derivedType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(derivedType));\n\n\t\t\tif (baseMember.Compilation != derivedType.Compilation)\n\t\t\t\tthrow new ArgumentException(\"baseMember and derivedType must be from the same compilation\");\n\n\t\t\tbaseMember = baseMember.MemberDefinition;\n\t\t\tbool includeInterfaces = baseMember.DeclaringTypeDefinition?.Kind == TypeKind.Interface;\n\t\t\tif (baseMember is IMethod method)\n\t\t\t{\n\t\t\t\tforeach (IMethod derivedMethod in derivedType.Methods)\n\t\t\t\t{\n\t\t\t\t\tif (derivedMethod.Name == method.Name && derivedMethod.Parameters.Count == method.Parameters.Count)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (derivedMethod.TypeParameters.Count == method.TypeParameters.Count)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// The method could override the base method:\n\t\t\t\t\t\t\tif (GetBaseMembers(derivedMethod, includeInterfaces).Any(m => m.MemberDefinition == baseMember))\n\t\t\t\t\t\t\t\treturn derivedMethod;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (baseMember is IProperty property)\n\t\t\t{\n\t\t\t\tforeach (IProperty derivedProperty in derivedType.Properties)\n\t\t\t\t{\n\t\t\t\t\tif (derivedProperty.Name == property.Name && derivedProperty.Parameters.Count == property.Parameters.Count)\n\t\t\t\t\t{\n\t\t\t\t\t\t// The property could override the base property:\n\t\t\t\t\t\tif (GetBaseMembers(derivedProperty, includeInterfaces).Any(m => m.MemberDefinition == baseMember))\n\t\t\t\t\t\t\treturn derivedProperty;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (baseMember is IEvent)\n\t\t\t{\n\t\t\t\tforeach (IEvent derivedEvent in derivedType.Events)\n\t\t\t\t{\n\t\t\t\t\tif (derivedEvent.Name == baseMember.Name)\n\t\t\t\t\t\treturn derivedEvent;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (baseMember is IField)\n\t\t\t{\n\t\t\t\tforeach (IField derivedField in derivedType.Fields)\n\t\t\t\t{\n\t\t\t\t\tif (derivedField.Name == baseMember.Name)\n\t\t\t\t\t\treturn derivedField;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\t#endregion\n\n\t\t#region Attributes\n\t\tinternal static IEnumerable<IAttribute> GetAttributes(ITypeDefinition typeDef)\n\t\t{\n\t\t\tforeach (var baseType in typeDef.GetNonInterfaceBaseTypes().Reverse())\n\t\t\t{\n\t\t\t\tITypeDefinition? baseTypeDef = baseType.GetDefinition();\n\t\t\t\tif (baseTypeDef == null)\n\t\t\t\t\tcontinue;\n\t\t\t\tforeach (var attr in baseTypeDef.GetAttributes())\n\t\t\t\t{\n\t\t\t\t\tyield return attr;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tinternal static IAttribute? GetAttribute(ITypeDefinition typeDef, KnownAttribute attributeType)\n\t\t{\n\t\t\tforeach (var baseType in typeDef.GetNonInterfaceBaseTypes().Reverse())\n\t\t\t{\n\t\t\t\tITypeDefinition? baseTypeDef = baseType.GetDefinition();\n\t\t\t\tif (baseTypeDef == null)\n\t\t\t\t\tcontinue;\n\t\t\t\tvar attr = baseTypeDef.GetAttribute(attributeType);\n\t\t\t\tif (attr != null)\n\t\t\t\t\treturn attr;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tinternal static IEnumerable<IAttribute> GetAttributes(IMember member)\n\t\t{\n\t\t\tHashSet<IMember> visitedMembers = new HashSet<IMember>();\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tmember = member.MemberDefinition; // it's sufficient to look at the definitions\n\t\t\t\tif (!visitedMembers.Add(member))\n\t\t\t\t{\n\t\t\t\t\t// abort if we seem to be in an infinite loop (cyclic inheritance)\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tforeach (var attr in member.GetAttributes())\n\t\t\t\t{\n\t\t\t\t\tyield return attr;\n\t\t\t\t}\n\t\t\t\tif (!member.IsOverride)\n\t\t\t\t\tbreak;\n\t\t\t\tvar baseMember = GetBaseMember(member);\n\t\t\t\tif (baseMember == null)\n\t\t\t\t\tbreak;\n\t\t\t\tmember = baseMember;\n\t\t\t}\n\t\t}\n\n\t\tinternal static IAttribute? GetAttribute(IMember member, KnownAttribute attributeType)\n\t\t{\n\t\t\tHashSet<IMember> visitedMembers = new HashSet<IMember>();\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tmember = member.MemberDefinition; // it's sufficient to look at the definitions\n\t\t\t\tif (!visitedMembers.Add(member))\n\t\t\t\t{\n\t\t\t\t\t// abort if we seem to be in an infinite loop (cyclic inheritance)\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tvar attr = member.GetAttribute(attributeType);\n\t\t\t\tif (attr != null)\n\t\t\t\t\treturn attr;\n\t\t\t\tif (!member.IsOverride)\n\t\t\t\t\tbreak;\n\t\t\t\tvar baseMember = GetBaseMember(member);\n\t\t\t\tif (baseMember == null)\n\t\t\t\t\tbreak;\n\t\t\t\tmember = baseMember;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/IntersectionType.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Represents the intersection of several types.\n\t/// </summary>\n\tpublic class IntersectionType : AbstractType\n\t{\n\t\treadonly ReadOnlyCollection<IType> types;\n\n\t\tpublic ReadOnlyCollection<IType> Types {\n\t\t\tget { return types; }\n\t\t}\n\n\t\tprivate IntersectionType(IType[] types)\n\t\t{\n\t\t\tDebug.Assert(types.Length >= 2);\n\t\t\tthis.types = Array.AsReadOnly(types);\n\t\t}\n\n\t\tpublic static IType Create(IEnumerable<IType> types)\n\t\t{\n\t\t\tIType[] arr = types.Distinct().ToArray();\n\t\t\tforeach (IType type in arr)\n\t\t\t{\n\t\t\t\tif (type == null)\n\t\t\t\t\tthrow new ArgumentNullException();\n\t\t\t}\n\t\t\tif (arr.Length == 0)\n\t\t\t\treturn SpecialType.UnknownType;\n\t\t\telse if (arr.Length == 1)\n\t\t\t\treturn arr[0];\n\t\t\telse\n\t\t\t\treturn new IntersectionType(arr);\n\t\t}\n\n\t\tpublic override TypeKind Kind {\n\t\t\tget { return TypeKind.Intersection; }\n\t\t}\n\n\t\tpublic override string Name {\n\t\t\tget {\n\t\t\t\tStringBuilder b = new StringBuilder();\n\t\t\t\tforeach (var t in types)\n\t\t\t\t{\n\t\t\t\t\tif (b.Length > 0)\n\t\t\t\t\t\tb.Append(\" & \");\n\t\t\t\t\tb.Append(t.Name);\n\t\t\t\t}\n\t\t\t\treturn b.ToString();\n\t\t\t}\n\t\t}\n\n\t\tpublic override string ReflectionName {\n\t\t\tget {\n\t\t\t\tStringBuilder b = new StringBuilder();\n\t\t\t\tforeach (var t in types)\n\t\t\t\t{\n\t\t\t\t\tif (b.Length > 0)\n\t\t\t\t\t\tb.Append(\" & \");\n\t\t\t\t\tb.Append(t.ReflectionName);\n\t\t\t\t}\n\t\t\t\treturn b.ToString();\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool? IsReferenceType {\n\t\t\tget {\n\t\t\t\tforeach (var t in types)\n\t\t\t\t{\n\t\t\t\t\tbool? isReferenceType = t.IsReferenceType;\n\t\t\t\t\tif (isReferenceType.HasValue)\n\t\t\t\t\t\treturn isReferenceType.Value;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\tint hashCode = 0;\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\tforeach (var t in types)\n\t\t\t\t{\n\t\t\t\t\thashCode *= 7137517;\n\t\t\t\t\thashCode += t.GetHashCode();\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn hashCode;\n\t\t}\n\n\t\tpublic override bool Equals(IType other)\n\t\t{\n\t\t\tIntersectionType o = other as IntersectionType;\n\t\t\tif (o != null && types.Count == o.types.Count)\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < types.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (!types[i].Equals(o.types[i]))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic override IEnumerable<IType> DirectBaseTypes {\n\t\t\tget { return types; }\n\t\t}\n\n\t\tpublic override IEnumerable<IMethod> GetMethods(Predicate<IMethod> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn GetMembersHelper.GetMethods(this, FilterNonStatic(filter), options);\n\t\t}\n\n\t\tpublic override IEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IMethod> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn GetMembersHelper.GetMethods(this, typeArguments, filter, options);\n\t\t}\n\n\t\tpublic override IEnumerable<IProperty> GetProperties(Predicate<IProperty> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn GetMembersHelper.GetProperties(this, FilterNonStatic(filter), options);\n\t\t}\n\n\t\tpublic override IEnumerable<IField> GetFields(Predicate<IField> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn GetMembersHelper.GetFields(this, FilterNonStatic(filter), options);\n\t\t}\n\n\t\tpublic override IEnumerable<IEvent> GetEvents(Predicate<IEvent> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn GetMembersHelper.GetEvents(this, FilterNonStatic(filter), options);\n\t\t}\n\n\t\tpublic override IEnumerable<IMember> GetMembers(Predicate<IMember> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn GetMembersHelper.GetMembers(this, FilterNonStatic(filter), options);\n\t\t}\n\n\t\tpublic override IEnumerable<IMethod> GetAccessors(Predicate<IMethod> filter, GetMemberOptions options)\n\t\t{\n\t\t\treturn GetMembersHelper.GetAccessors(this, FilterNonStatic(filter), options);\n\t\t}\n\n\t\tstatic Predicate<T> FilterNonStatic<T>(Predicate<T> filter) where T : class, IMember\n\t\t{\n\t\t\tif (filter == null)\n\t\t\t\treturn member => !member.IsStatic;\n\t\t\telse\n\t\t\t\treturn member => !member.IsStatic && filter(member);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/KnownTypeReference.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Represents some well-known types.\n\t/// </summary>\n\tpublic enum KnownTypeCode\n\t{\n\t\t// Note: DefaultResolvedTypeDefinition uses (KnownTypeCode)-1 as special value for \"not yet calculated\".\n\t\t// The order of type codes at the beginning must correspond to those in System.TypeCode.\n\n\t\t/// <summary>\n\t\t/// Not one of the known types.\n\t\t/// </summary>\n\t\tNone,\n\t\t/// <summary><c>object</c> (System.Object)</summary>\n\t\tObject,\n\t\t/// <summary><c>System.DBNull</c></summary>\n\t\tDBNull,\n\t\t/// <summary><c>bool</c> (System.Boolean)</summary>\n\t\tBoolean,\n\t\t/// <summary><c>char</c> (System.Char)</summary>\n\t\tChar,\n\t\t/// <summary><c>sbyte</c> (System.SByte)</summary>\n\t\tSByte,\n\t\t/// <summary><c>byte</c> (System.Byte)</summary>\n\t\tByte,\n\t\t/// <summary><c>short</c> (System.Int16)</summary>\n\t\tInt16,\n\t\t/// <summary><c>ushort</c> (System.UInt16)</summary>\n\t\tUInt16,\n\t\t/// <summary><c>int</c> (System.Int32)</summary>\n\t\tInt32,\n\t\t/// <summary><c>uint</c> (System.UInt32)</summary>\n\t\tUInt32,\n\t\t/// <summary><c>long</c> (System.Int64)</summary>\n\t\tInt64,\n\t\t/// <summary><c>ulong</c> (System.UInt64)</summary>\n\t\tUInt64,\n\t\t/// <summary><c>float</c> (System.Single)</summary>\n\t\tSingle,\n\t\t/// <summary><c>double</c> (System.Double)</summary>\n\t\tDouble,\n\t\t/// <summary><c>decimal</c> (System.Decimal)</summary>\n\t\tDecimal,\n\t\t/// <summary><c>System.DateTime</c></summary>\n\t\tDateTime,\n\t\t/// <summary><c>string</c> (System.String)</summary>\n\t\tString = 18,\n\n\t\t// String was the last element from System.TypeCode, now our additional known types start\n\n\t\t/// <summary><c>void</c> (System.Void)</summary>\n\t\tVoid,\n\t\t/// <summary><c>System.Type</c></summary>\n\t\tType,\n\t\t/// <summary><c>System.Array</c></summary>\n\t\tArray,\n\t\t/// <summary><c>System.Attribute</c></summary>\n\t\tAttribute,\n\t\t/// <summary><c>System.ValueType</c></summary>\n\t\tValueType,\n\t\t/// <summary><c>System.Enum</c></summary>\n\t\tEnum,\n\t\t/// <summary><c>System.Delegate</c></summary>\n\t\tDelegate,\n\t\t/// <summary><c>System.MulticastDelegate</c></summary>\n\t\tMulticastDelegate,\n\t\t/// <summary><c>System.Exception</c></summary>\n\t\tException,\n\t\t/// <summary><c>System.IntPtr</c></summary>\n\t\tIntPtr,\n\t\t/// <summary><c>System.UIntPtr</c></summary>\n\t\tUIntPtr,\n\t\t/// <summary><c>System.Collections.IEnumerable</c></summary>\n\t\tIEnumerable,\n\t\t/// <summary><c>System.Collections.IEnumerator</c></summary>\n\t\tIEnumerator,\n\t\t/// <summary><c>System.Collections.Generic.IEnumerable{T}</c></summary>\n\t\tIEnumerableOfT,\n\t\t/// <summary><c>System.Collections.Generic.IEnumerator{T}</c></summary>\n\t\tIEnumeratorOfT,\n\t\t/// <summary><c>System.Collections.Generic.ICollection</c></summary>\n\t\tICollection,\n\t\t/// <summary><c>System.Collections.Generic.ICollection{T}</c></summary>\n\t\tICollectionOfT,\n\t\t/// <summary><c>System.Collections.Generic.IList</c></summary>\n\t\tIList,\n\t\t/// <summary><c>System.Collections.Generic.IList{T}</c></summary>\n\t\tIListOfT,\n\t\t/// <summary><c>System.Collections.Generic.IReadOnlyCollection{T}</c></summary>\n\t\tIReadOnlyCollectionOfT,\n\t\t/// <summary><c>System.Collections.Generic.IReadOnlyList{T}</c></summary>\n\t\tIReadOnlyListOfT,\n\t\t/// <summary><c>System.Threading.Tasks.Task</c></summary>\n\t\tTask,\n\t\t/// <summary><c>System.Threading.Tasks.Task{T}</c></summary>\n\t\tTaskOfT,\n\t\t/// <summary><c>System.Threading.Tasks.ValueTask</c></summary>\n\t\tValueTask,\n\t\t/// <summary><c>System.Threading.Tasks.ValueTask{T}</c></summary>\n\t\tValueTaskOfT,\n\t\t/// <summary><c>System.Nullable{T}</c></summary>\n\t\tNullableOfT,\n\t\t/// <summary><c>System.IDisposable</c></summary>\n\t\tIDisposable,\n\t\t/// <summary><c>System.IAsyncDisposable</c></summary>\n\t\tIAsyncDisposable,\n\t\t/// <summary><c>System.Runtime.CompilerServices.INotifyCompletion</c></summary>\n\t\tINotifyCompletion,\n\t\t/// <summary><c>System.Runtime.CompilerServices.ICriticalNotifyCompletion</c></summary>\n\t\tICriticalNotifyCompletion,\n\t\t/// <summary><c>System.TypedReference</c></summary>\n\t\tTypedReference,\n\t\t/// <summary><c>System.IFormattable</c></summary>\n\t\tIFormattable,\n\t\t/// <summary><c>System.FormattableString</c></summary>\n\t\tFormattableString,\n\t\t/// <summary><c>System.Runtime.CompilerServices.DefaultInterpolatedStringHandler</c></summary>\n\t\tDefaultInterpolatedStringHandler,\n\t\t/// <summary><c>System.Span{T}</c></summary>\n\t\tSpanOfT,\n\t\t/// <summary><c>System.ReadOnlySpan{T}</c></summary>\n\t\tReadOnlySpanOfT,\n\t\t/// <summary><c>System.Memory{T}</c></summary>\n\t\tMemoryOfT,\n\t\t/// <summary><c>System.Runtime.CompilerServices.Unsafe</c></summary>\n\t\tUnsafe,\n\t\t/// <summary><c>System.Collections.Generic.IAsyncEnumerable{T}</c></summary>\n\t\tIAsyncEnumerableOfT,\n\t\t/// <summary><c>System.Collections.Generic.IAsyncEnumerator{T}</c></summary>\n\t\tIAsyncEnumeratorOfT,\n\t\t/// <summary><c>System.Index</c></summary>\n\t\tIndex,\n\t\t/// <summary><c>System.Range</c></summary>\n\t\tRange\n\t}\n\n\t/// <summary>\n\t/// Contains well-known type references.\n\t/// </summary>\n\t[Serializable]\n\tpublic sealed class KnownTypeReference : ITypeReference\n\t{\n\t\tinternal const int KnownTypeCodeCount = (int)KnownTypeCode.Range + 1;\n\n\t\tstatic readonly KnownTypeReference?[] knownTypeReferences = new KnownTypeReference?[KnownTypeCodeCount] {\n\t\t\tnull, // None\n\t\t\tnew KnownTypeReference(KnownTypeCode.Object,   TypeKind.Class, \"System\", \"Object\", baseType: KnownTypeCode.None),\n\t\t\tnew KnownTypeReference(KnownTypeCode.DBNull,   TypeKind.Class, \"System\", \"DBNull\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Boolean,  TypeKind.Struct, \"System\", \"Boolean\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Char,     TypeKind.Struct, \"System\", \"Char\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.SByte,    TypeKind.Struct, \"System\", \"SByte\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Byte,     TypeKind.Struct, \"System\", \"Byte\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Int16,    TypeKind.Struct, \"System\", \"Int16\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.UInt16,   TypeKind.Struct, \"System\", \"UInt16\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Int32,    TypeKind.Struct, \"System\", \"Int32\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.UInt32,   TypeKind.Struct, \"System\", \"UInt32\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Int64,    TypeKind.Struct, \"System\", \"Int64\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.UInt64,   TypeKind.Struct, \"System\", \"UInt64\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Single,   TypeKind.Struct, \"System\", \"Single\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Double,   TypeKind.Struct, \"System\", \"Double\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Decimal,  TypeKind.Struct, \"System\", \"Decimal\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.DateTime, TypeKind.Struct, \"System\", \"DateTime\"),\n\t\t\tnull,\n\t\t\tnew KnownTypeReference(KnownTypeCode.String,    TypeKind.Class, \"System\", \"String\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Void,      TypeKind.Void,  \"System\", \"Void\", baseType: KnownTypeCode.ValueType),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Type,      TypeKind.Class, \"System\", \"Type\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Array,     TypeKind.Class, \"System\", \"Array\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Attribute, TypeKind.Class, \"System\", \"Attribute\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.ValueType, TypeKind.Class, \"System\", \"ValueType\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Enum,      TypeKind.Class, \"System\", \"Enum\", baseType: KnownTypeCode.ValueType),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Delegate,  TypeKind.Class, \"System\", \"Delegate\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.MulticastDelegate, TypeKind.Class, \"System\", \"MulticastDelegate\", baseType: KnownTypeCode.Delegate),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Exception, TypeKind.Class, \"System\", \"Exception\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.IntPtr,    TypeKind.Struct, \"System\", \"IntPtr\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.UIntPtr,   TypeKind.Struct, \"System\", \"UIntPtr\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.IEnumerable,    TypeKind.Interface, \"System.Collections\", \"IEnumerable\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.IEnumerator,    TypeKind.Interface, \"System.Collections\", \"IEnumerator\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.IEnumerableOfT, TypeKind.Interface, \"System.Collections.Generic\", \"IEnumerable\", 1),\n\t\t\tnew KnownTypeReference(KnownTypeCode.IEnumeratorOfT, TypeKind.Interface, \"System.Collections.Generic\", \"IEnumerator\", 1),\n\t\t\tnew KnownTypeReference(KnownTypeCode.ICollection,    TypeKind.Interface, \"System.Collections\", \"ICollection\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.ICollectionOfT, TypeKind.Interface, \"System.Collections.Generic\", \"ICollection\", 1),\n\t\t\tnew KnownTypeReference(KnownTypeCode.IList,          TypeKind.Interface, \"System.Collections\", \"IList\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.IListOfT,       TypeKind.Interface, \"System.Collections.Generic\", \"IList\", 1),\n\n\t\t\tnew KnownTypeReference(KnownTypeCode.IReadOnlyCollectionOfT, TypeKind.Interface, \"System.Collections.Generic\", \"IReadOnlyCollection\", 1),\n\t\t\tnew KnownTypeReference(KnownTypeCode.IReadOnlyListOfT, TypeKind.Interface, \"System.Collections.Generic\", \"IReadOnlyList\", 1),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Task,         TypeKind.Class, \"System.Threading.Tasks\", \"Task\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.TaskOfT,      TypeKind.Class, \"System.Threading.Tasks\", \"Task\", 1, baseType: KnownTypeCode.Task),\n\t\t\tnew KnownTypeReference(KnownTypeCode.ValueTask,    TypeKind.Struct, \"System.Threading.Tasks\", \"ValueTask\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.ValueTaskOfT, TypeKind.Struct, \"System.Threading.Tasks\", \"ValueTask\", 1),\n\t\t\tnew KnownTypeReference(KnownTypeCode.NullableOfT, TypeKind.Struct, \"System\", \"Nullable\", 1),\n\t\t\tnew KnownTypeReference(KnownTypeCode.IDisposable, TypeKind.Interface, \"System\", \"IDisposable\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.IAsyncDisposable, TypeKind.Interface, \"System\", \"IAsyncDisposable\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.INotifyCompletion, TypeKind.Interface, \"System.Runtime.CompilerServices\", \"INotifyCompletion\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.ICriticalNotifyCompletion, TypeKind.Interface, \"System.Runtime.CompilerServices\", \"ICriticalNotifyCompletion\"),\n\n\t\t\tnew KnownTypeReference(KnownTypeCode.TypedReference, TypeKind.Struct, \"System\", \"TypedReference\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.IFormattable, TypeKind.Interface, \"System\", \"IFormattable\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.FormattableString, TypeKind.Class, \"System\", \"FormattableString\", baseType: KnownTypeCode.IFormattable),\n\t\t\tnew KnownTypeReference(KnownTypeCode.DefaultInterpolatedStringHandler, TypeKind.Struct, \"System.Runtime.CompilerServices\", \"DefaultInterpolatedStringHandler\"),\n\t\t\tnew KnownTypeReference(KnownTypeCode.SpanOfT, TypeKind.Struct, \"System\", \"Span\", 1),\n\t\t\tnew KnownTypeReference(KnownTypeCode.ReadOnlySpanOfT, TypeKind.Struct, \"System\", \"ReadOnlySpan\", 1),\n\t\t\tnew KnownTypeReference(KnownTypeCode.MemoryOfT, TypeKind.Struct, \"System\", \"Memory\", 1),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Unsafe, TypeKind.Class, \"System.Runtime.CompilerServices\", \"Unsafe\", 0),\n\t\t\tnew KnownTypeReference(KnownTypeCode.IAsyncEnumerableOfT, TypeKind.Interface, \"System.Collections.Generic\", \"IAsyncEnumerable\", 1),\n\t\t\tnew KnownTypeReference(KnownTypeCode.IAsyncEnumeratorOfT, TypeKind.Interface, \"System.Collections.Generic\", \"IAsyncEnumerator\", 1),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Index, TypeKind.Struct, \"System\", \"Index\", 0),\n\t\t\tnew KnownTypeReference(KnownTypeCode.Range, TypeKind.Struct, \"System\", \"Range\", 0),\n\t\t};\n\n\t\t/// <summary>\n\t\t/// Gets the known type reference for the specified type code.\n\t\t/// Returns null for KnownTypeCode.None.\n\t\t/// </summary>\n\t\tpublic static KnownTypeReference? Get(KnownTypeCode typeCode)\n\t\t{\n\t\t\treturn knownTypeReferences[(int)typeCode];\n\t\t}\n\n\t\tpublic static IEnumerable<KnownTypeReference> AllKnownTypes {\n\t\t\tget {\n\t\t\t\tfor (int i = 0; i < KnownTypeCodeCount; i++)\n\t\t\t\t{\n\t\t\t\t\tvar ktr = Get((KnownTypeCode)i);\n\t\t\t\t\tif (ktr == null)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tyield return ktr;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treadonly KnownTypeCode knownTypeCode;\n\t\treadonly string namespaceName;\n\t\treadonly string name;\n\t\treadonly int typeParameterCount;\n\t\tinternal readonly KnownTypeCode baseType;\n\t\tinternal readonly TypeKind typeKind;\n\n\t\tprivate KnownTypeReference(KnownTypeCode knownTypeCode, TypeKind typeKind, string namespaceName, string name, int typeParameterCount = 0, KnownTypeCode baseType = KnownTypeCode.Object)\n\t\t{\n\t\t\tif (typeKind == TypeKind.Struct && baseType == KnownTypeCode.Object)\n\t\t\t\tbaseType = KnownTypeCode.ValueType;\n\t\t\tthis.knownTypeCode = knownTypeCode;\n\t\t\tthis.namespaceName = namespaceName;\n\t\t\tthis.name = name;\n\t\t\tthis.typeParameterCount = typeParameterCount;\n\t\t\tthis.typeKind = typeKind;\n\t\t\tthis.baseType = baseType;\n\t\t}\n\n\t\tpublic KnownTypeCode KnownTypeCode {\n\t\t\tget { return knownTypeCode; }\n\t\t}\n\n\t\tpublic string Namespace {\n\t\t\tget { return namespaceName; }\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget { return name; }\n\t\t}\n\n\t\tpublic int TypeParameterCount {\n\t\t\tget { return typeParameterCount; }\n\t\t}\n\n\t\tpublic TopLevelTypeName TypeName => new TopLevelTypeName(namespaceName, name, typeParameterCount);\n\n\t\tpublic IType Resolve(ITypeResolveContext context)\n\t\t{\n\t\t\treturn context.Compilation.FindType(knownTypeCode);\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn GetCSharpNameByTypeCode(knownTypeCode) ?? (this.Namespace + \".\" + this.Name);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the C# primitive type name from the known type code.\n\t\t/// Returns null if there is no primitive name for the specified type.\n\t\t/// </summary>\n\t\tpublic static string? GetCSharpNameByTypeCode(KnownTypeCode knownTypeCode)\n\t\t{\n\t\t\tswitch (knownTypeCode)\n\t\t\t{\n\t\t\t\tcase KnownTypeCode.Object:\n\t\t\t\t\treturn \"object\";\n\t\t\t\tcase KnownTypeCode.Boolean:\n\t\t\t\t\treturn \"bool\";\n\t\t\t\tcase KnownTypeCode.Char:\n\t\t\t\t\treturn \"char\";\n\t\t\t\tcase KnownTypeCode.SByte:\n\t\t\t\t\treturn \"sbyte\";\n\t\t\t\tcase KnownTypeCode.Byte:\n\t\t\t\t\treturn \"byte\";\n\t\t\t\tcase KnownTypeCode.Int16:\n\t\t\t\t\treturn \"short\";\n\t\t\t\tcase KnownTypeCode.UInt16:\n\t\t\t\t\treturn \"ushort\";\n\t\t\t\tcase KnownTypeCode.Int32:\n\t\t\t\t\treturn \"int\";\n\t\t\t\tcase KnownTypeCode.UInt32:\n\t\t\t\t\treturn \"uint\";\n\t\t\t\tcase KnownTypeCode.Int64:\n\t\t\t\t\treturn \"long\";\n\t\t\t\tcase KnownTypeCode.UInt64:\n\t\t\t\t\treturn \"ulong\";\n\t\t\t\tcase KnownTypeCode.Single:\n\t\t\t\t\treturn \"float\";\n\t\t\t\tcase KnownTypeCode.Double:\n\t\t\t\t\treturn \"double\";\n\t\t\t\tcase KnownTypeCode.Decimal:\n\t\t\t\t\treturn \"decimal\";\n\t\t\t\tcase KnownTypeCode.String:\n\t\t\t\t\treturn \"string\";\n\t\t\t\tcase KnownTypeCode.Void:\n\t\t\t\t\treturn \"void\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/MetadataModule.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Type system implementation for Metadata.PEFile.\n\t/// </summary>\n\t[DebuggerDisplay(\"<MetadataModule: {AssemblyName}>\")]\n\tpublic class MetadataModule : IModule\n\t{\n\t\tpublic ICompilation Compilation { get; }\n\t\tinternal readonly MetadataReader metadata;\n\t\treadonly TypeSystemOptions options;\n\t\tinternal readonly TypeProvider TypeProvider;\n\t\tinternal readonly Nullability NullableContext;\n\n\t\treadonly MetadataNamespace rootNamespace;\n\t\treadonly MetadataTypeDefinition[] typeDefs;\n\t\treadonly MetadataField[] fieldDefs;\n\t\treadonly MetadataMethod[] methodDefs;\n\t\treadonly MetadataProperty[] propertyDefs;\n\t\treadonly MetadataEvent[] eventDefs;\n\t\treadonly IModule[] referencedAssemblies;\n\n\t\tinternal MetadataModule(ICompilation compilation, MetadataFile peFile, TypeSystemOptions options)\n\t\t{\n\t\t\tthis.Compilation = compilation;\n\t\t\tthis.MetadataFile = peFile;\n\t\t\tthis.metadata = peFile.Metadata;\n\t\t\tthis.options = options;\n\t\t\tthis.TypeProvider = new TypeProvider(this);\n\n\t\t\t// assembly metadata\n\t\t\tif (metadata.IsAssembly)\n\t\t\t{\n\t\t\t\tvar asmdef = metadata.GetAssemblyDefinition();\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tthis.AssemblyName = metadata.GetString(asmdef.Name);\n\t\t\t\t\tthis.AssemblyVersion = asmdef.Version;\n\t\t\t\t\tthis.FullAssemblyName = metadata.GetFullAssemblyName();\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\tthis.AssemblyName = \"<ERR: invalid assembly name>\";\n\t\t\t\t\tthis.FullAssemblyName = \"<ERR: invalid assembly name>\";\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tvar moddef = metadata.GetModuleDefinition();\n\t\t\t\t\tthis.AssemblyName = metadata.GetString(moddef.Name);\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\tthis.AssemblyName = \"<ERR: invalid assembly name>\";\n\t\t\t\t}\n\t\t\t\tthis.FullAssemblyName = this.AssemblyName;\n\t\t\t}\n\t\t\tvar customAttrs = metadata.GetModuleDefinition().GetCustomAttributes();\n\t\t\tthis.NullableContext = customAttrs.GetNullableContext(metadata) ?? Nullability.Oblivious;\n\t\t\tthis.minAccessibilityForNRT = FindMinimumAccessibilityForNRT(metadata, customAttrs);\n\t\t\tthis.rootNamespace = new MetadataNamespace(this, null, string.Empty, metadata.GetNamespaceDefinitionRoot());\n\n\t\t\tif (!options.HasFlag(TypeSystemOptions.Uncached))\n\t\t\t{\n\t\t\t\t// create arrays for resolved entities, indexed by row index\n\t\t\t\tthis.typeDefs = new MetadataTypeDefinition[metadata.TypeDefinitions.Count + 1];\n\t\t\t\tthis.fieldDefs = new MetadataField[metadata.FieldDefinitions.Count + 1];\n\t\t\t\tthis.methodDefs = new MetadataMethod[metadata.MethodDefinitions.Count + 1];\n\t\t\t\tthis.propertyDefs = new MetadataProperty[metadata.PropertyDefinitions.Count + 1];\n\t\t\t\tthis.eventDefs = new MetadataEvent[metadata.EventDefinitions.Count + 1];\n\t\t\t\tthis.referencedAssemblies = new IModule[metadata.AssemblyReferences.Count + 1];\n\t\t\t}\n\t\t}\n\n\t\tinternal string GetString(StringHandle name)\n\t\t{\n\t\t\treturn metadata.GetString(name);\n\t\t}\n\n\t\tpublic TypeSystemOptions TypeSystemOptions => options;\n\n\t\t#region IModule interface\n\t\tpublic MetadataFile MetadataFile { get; }\n\n\t\tpublic bool IsMainModule => this == Compilation.MainModule;\n\n\t\tpublic string AssemblyName { get; }\n\t\tpublic Version AssemblyVersion { get; }\n\t\tpublic string FullAssemblyName { get; }\n\t\tstring ISymbol.Name => AssemblyName;\n\t\tSymbolKind ISymbol.SymbolKind => SymbolKind.Module;\n\n\t\tpublic INamespace RootNamespace => rootNamespace;\n\n\t\tpublic IEnumerable<ITypeDefinition> TopLevelTypeDefinitions => TypeDefinitions.Where(td => td.DeclaringTypeDefinition == null);\n\n\t\tpublic ITypeDefinition GetTypeDefinition(TopLevelTypeName topLevelTypeName)\n\t\t{\n\t\t\tvar typeDefHandle = MetadataFile.GetTypeDefinition(topLevelTypeName);\n\t\t\tif (typeDefHandle.IsNil)\n\t\t\t{\n\t\t\t\tvar forwarderHandle = MetadataFile.GetTypeForwarder(topLevelTypeName);\n\t\t\t\tif (!forwarderHandle.IsNil)\n\t\t\t\t{\n\t\t\t\t\tvar forwarder = metadata.GetExportedType(forwarderHandle);\n\t\t\t\t\treturn ResolveForwardedType(forwarder).GetDefinition();\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn GetDefinition(typeDefHandle);\n\t\t}\n\t\t#endregion\n\n\t\t#region InternalsVisibleTo\n\t\tpublic bool InternalsVisibleTo(IModule module)\n\t\t{\n\t\t\tif (this == module)\n\t\t\t\treturn true;\n\t\t\tforeach (string shortName in GetInternalsVisibleTo())\n\t\t\t{\n\t\t\t\tif (string.Equals(module.AssemblyName, shortName, StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tstring[] internalsVisibleTo;\n\n\t\tstring[] GetInternalsVisibleTo()\n\t\t{\n\t\t\tvar result = LazyInit.VolatileRead(ref this.internalsVisibleTo);\n\t\t\tif (result != null)\n\t\t\t{\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\tif (metadata.IsAssembly)\n\t\t\t{\n\t\t\t\tvar list = new List<string>();\n\t\t\t\tforeach (var attrHandle in metadata.GetAssemblyDefinition().GetCustomAttributes())\n\t\t\t\t{\n\t\t\t\t\tvar attr = metadata.GetCustomAttribute(attrHandle);\n\t\t\t\t\tif (attr.IsKnownAttribute(metadata, KnownAttribute.InternalsVisibleTo))\n\t\t\t\t\t{\n\t\t\t\t\t\tvar attrValue = attr.DecodeValue(this.TypeProvider);\n\t\t\t\t\t\tif (attrValue.FixedArguments.Length == 1)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (attrValue.FixedArguments[0].Value is string s)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlist.Add(GetShortName(s));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tresult = list.ToArray();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tresult = Empty<string>.Array;\n\t\t\t}\n\t\t\treturn LazyInit.GetOrSet(ref this.internalsVisibleTo, result);\n\t\t}\n\n\t\tstatic string GetShortName(string fullAssemblyName)\n\t\t{\n\t\t\tif (fullAssemblyName == null)\n\t\t\t\treturn null;\n\t\t\tint pos = fullAssemblyName.IndexOf(',');\n\t\t\tif (pos < 0)\n\t\t\t\treturn fullAssemblyName;\n\t\t\telse\n\t\t\t\treturn fullAssemblyName.Substring(0, pos);\n\t\t}\n\t\t#endregion\n\n\t\t#region GetDefinition\n\t\t/// <summary>\n\t\t/// Gets all types in the assembly, including nested types.\n\t\t/// </summary>\n\t\tpublic IEnumerable<ITypeDefinition> TypeDefinitions {\n\t\t\tget {\n\t\t\t\tforeach (var tdHandle in metadata.TypeDefinitions)\n\t\t\t\t{\n\t\t\t\t\tyield return GetDefinition(tdHandle);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic ITypeDefinition GetDefinition(TypeDefinitionHandle handle)\n\t\t{\n\t\t\tif (handle.IsNil)\n\t\t\t\treturn null;\n\t\t\tif (typeDefs == null)\n\t\t\t\treturn new MetadataTypeDefinition(this, handle);\n\t\t\tint row = MetadataTokens.GetRowNumber(handle);\n\t\t\tif (row >= typeDefs.Length)\n\t\t\t\tHandleOutOfRange(handle);\n\t\t\tvar typeDef = LazyInit.VolatileRead(ref typeDefs[row]);\n\t\t\tif (typeDef != null)\n\t\t\t\treturn typeDef;\n\t\t\ttypeDef = new MetadataTypeDefinition(this, handle);\n\t\t\treturn LazyInit.GetOrSet(ref typeDefs[row], typeDef);\n\t\t}\n\n\t\tpublic IField GetDefinition(FieldDefinitionHandle handle)\n\t\t{\n\t\t\tif (handle.IsNil)\n\t\t\t\treturn null;\n\t\t\tif (fieldDefs == null)\n\t\t\t\treturn new MetadataField(this, handle);\n\t\t\tint row = MetadataTokens.GetRowNumber(handle);\n\t\t\tif (row >= fieldDefs.Length)\n\t\t\t\tHandleOutOfRange(handle);\n\t\t\tvar field = LazyInit.VolatileRead(ref fieldDefs[row]);\n\t\t\tif (field != null)\n\t\t\t\treturn field;\n\t\t\tfield = new MetadataField(this, handle);\n\t\t\treturn LazyInit.GetOrSet(ref fieldDefs[row], field);\n\t\t}\n\n\t\tpublic IMethod GetDefinition(MethodDefinitionHandle handle)\n\t\t{\n\t\t\tif (handle.IsNil)\n\t\t\t\treturn null;\n\t\t\tif (methodDefs == null)\n\t\t\t\treturn new MetadataMethod(this, handle);\n\t\t\tint row = MetadataTokens.GetRowNumber(handle);\n\t\t\tDebug.Assert(row != 0);\n\t\t\tif (row >= methodDefs.Length)\n\t\t\t\tHandleOutOfRange(handle);\n\t\t\tvar method = LazyInit.VolatileRead(ref methodDefs[row]);\n\t\t\tif (method != null)\n\t\t\t\treturn method;\n\t\t\tmethod = new MetadataMethod(this, handle);\n\t\t\treturn LazyInit.GetOrSet(ref methodDefs[row], method);\n\t\t}\n\n\t\tpublic IProperty GetDefinition(PropertyDefinitionHandle handle)\n\t\t{\n\t\t\tif (handle.IsNil)\n\t\t\t\treturn null;\n\t\t\tif (propertyDefs == null)\n\t\t\t\treturn new MetadataProperty(this, handle);\n\t\t\tint row = MetadataTokens.GetRowNumber(handle);\n\t\t\tDebug.Assert(row != 0);\n\t\t\tif (row >= methodDefs.Length)\n\t\t\t\tHandleOutOfRange(handle);\n\t\t\tvar property = LazyInit.VolatileRead(ref propertyDefs[row]);\n\t\t\tif (property != null)\n\t\t\t\treturn property;\n\t\t\tproperty = new MetadataProperty(this, handle);\n\t\t\treturn LazyInit.GetOrSet(ref propertyDefs[row], property);\n\t\t}\n\n\t\tpublic IEvent GetDefinition(EventDefinitionHandle handle)\n\t\t{\n\t\t\tif (handle.IsNil)\n\t\t\t\treturn null;\n\t\t\tif (eventDefs == null)\n\t\t\t\treturn new MetadataEvent(this, handle);\n\t\t\tint row = MetadataTokens.GetRowNumber(handle);\n\t\t\tDebug.Assert(row != 0);\n\t\t\tif (row >= methodDefs.Length)\n\t\t\t\tHandleOutOfRange(handle);\n\t\t\tvar ev = LazyInit.VolatileRead(ref eventDefs[row]);\n\t\t\tif (ev != null)\n\t\t\t\treturn ev;\n\t\t\tev = new MetadataEvent(this, handle);\n\t\t\treturn LazyInit.GetOrSet(ref eventDefs[row], ev);\n\t\t}\n\n\t\tvoid HandleOutOfRange(EntityHandle handle)\n\t\t{\n\t\t\tthrow new BadImageFormatException(\"Handle with invalid row number.\");\n\t\t}\n\t\t#endregion\n\n\t\t#region Resolve Module\n\n\t\tpublic IModule ResolveModule(AssemblyReferenceHandle handle)\n\t\t{\n\t\t\tif (handle.IsNil)\n\t\t\t\treturn null;\n\n\t\t\tif (referencedAssemblies == null)\n\t\t\t\treturn ResolveModuleUncached(handle);\n\t\t\tint row = metadata.GetRowNumber(handle);\n\t\t\tDebug.Assert(row != 0);\n\t\t\tif (row >= referencedAssemblies.Length)\n\t\t\t\tHandleOutOfRange(handle);\n\t\t\tvar module = LazyInit.VolatileRead(ref referencedAssemblies[row]);\n\t\t\tif (module != null)\n\t\t\t\treturn module;\n\t\t\tmodule = ResolveModuleUncached(handle);\n\t\t\treturn LazyInit.GetOrSet(ref referencedAssemblies[row], module);\n\t\t}\n\n\t\tIModule ResolveModuleUncached(AssemblyReferenceHandle handle)\n\t\t{\n\t\t\tvar asmRef = new Metadata.AssemblyReference(metadata, handle);\n\t\t\treturn Compilation.FindModuleByReference(asmRef);\n\t\t}\n\n\t\tpublic IModule ResolveModule(ModuleReferenceHandle handle)\n\t\t{\n\t\t\tif (handle.IsNil)\n\t\t\t\treturn null;\n\t\t\tvar modRef = metadata.GetModuleReference(handle);\n\t\t\tstring name = metadata.GetString(modRef.Name);\n\t\t\tforeach (var mod in Compilation.Modules)\n\t\t\t{\n\t\t\t\tif (mod.Name == name)\n\t\t\t\t{\n\t\t\t\t\treturn mod;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic IModule GetDeclaringModule(TypeReferenceHandle handle)\n\t\t{\n\t\t\tif (handle.IsNil)\n\t\t\t\treturn null;\n\t\t\tvar tr = metadata.GetTypeReference(handle);\n\t\t\tswitch (tr.ResolutionScope.Kind)\n\t\t\t{\n\t\t\t\tcase HandleKind.TypeReference:\n\t\t\t\t\treturn GetDeclaringModule((TypeReferenceHandle)tr.ResolutionScope);\n\t\t\t\tcase HandleKind.AssemblyReference:\n\t\t\t\t\treturn ResolveModule((AssemblyReferenceHandle)tr.ResolutionScope);\n\t\t\t\tcase HandleKind.ModuleReference:\n\t\t\t\t\treturn ResolveModule((ModuleReferenceHandle)tr.ResolutionScope);\n\t\t\t\tdefault:\n\t\t\t\t\treturn this;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Resolve Type\n\t\tpublic IType ResolveType(EntityHandle typeRefDefSpec, GenericContext context, CustomAttributeHandleCollection? typeAttributes = null, Nullability nullableContext = Nullability.Oblivious)\n\t\t{\n\t\t\treturn ResolveType(typeRefDefSpec, context, options, typeAttributes, nullableContext);\n\t\t}\n\n\t\tpublic IType ResolveType(EntityHandle typeRefDefSpec, GenericContext context, TypeSystemOptions customOptions, CustomAttributeHandleCollection? typeAttributes = null, Nullability nullableContext = Nullability.Oblivious)\n\t\t{\n\t\t\tif (typeRefDefSpec.IsNil)\n\t\t\t\treturn SpecialType.UnknownType;\n\t\t\tIType ty;\n\t\t\tswitch (typeRefDefSpec.Kind)\n\t\t\t{\n\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\t\tty = TypeProvider.GetTypeFromDefinition(metadata, (TypeDefinitionHandle)typeRefDefSpec, 0);\n\t\t\t\t\tbreak;\n\t\t\t\tcase HandleKind.TypeReference:\n\t\t\t\t\tty = TypeProvider.GetTypeFromReference(metadata, (TypeReferenceHandle)typeRefDefSpec, 0);\n\t\t\t\t\tbreak;\n\t\t\t\tcase HandleKind.TypeSpecification:\n\t\t\t\t\tvar typeSpec = metadata.GetTypeSpecification((TypeSpecificationHandle)typeRefDefSpec);\n\t\t\t\t\tty = typeSpec.DecodeSignature(TypeProvider, context);\n\t\t\t\t\tbreak;\n\t\t\t\tcase HandleKind.ExportedType:\n\t\t\t\t\treturn ResolveForwardedType(metadata.GetExportedType((ExportedTypeHandle)typeRefDefSpec));\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new BadImageFormatException(\"Not a type handle\");\n\t\t\t}\n\t\t\tty = ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, Compilation, typeAttributes, metadata, customOptions, nullableContext);\n\t\t\treturn ty;\n\t\t}\n\n\t\tIType ResolveDeclaringType(EntityHandle declaringTypeReference, GenericContext context)\n\t\t{\n\t\t\t// resolve without substituting dynamic/tuple types\n\t\t\tconst TypeSystemOptions removedOptions = TypeSystemOptions.Dynamic | TypeSystemOptions.Tuple\n\t\t\t\t| TypeSystemOptions.NullabilityAnnotations | TypeSystemOptions.NativeIntegers | TypeSystemOptions.NativeIntegersWithoutAttribute;\n\t\t\tvar ty = ResolveType(declaringTypeReference, context, options & ~removedOptions);\n\t\t\t// but substitute tuple types in type arguments:\n\t\t\tty = ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, Compilation, null, metadata, options, Nullability.Oblivious, typeChildrenOnly: true);\n\t\t\treturn ty;\n\t\t}\n\n\t\tIType IntroduceTupleTypes(IType ty)\n\t\t{\n\t\t\t// run ApplyAttributeTypeVisitor without attributes, in order to introduce tuple types\n\t\t\treturn ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, Compilation, null, metadata, options, Nullability.Oblivious);\n\t\t}\n\t\t#endregion\n\n\t\t#region Resolve Method\n\t\tpublic IMethod ResolveMethod(EntityHandle methodReference, GenericContext context)\n\t\t{\n\t\t\tif (methodReference.IsNil)\n\t\t\t\tthrow new ArgumentNullException(nameof(methodReference));\n\t\t\tswitch (methodReference.Kind)\n\t\t\t{\n\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\treturn ResolveMethodDefinition((MethodDefinitionHandle)methodReference, expandVarArgs: true);\n\t\t\t\tcase HandleKind.MemberReference:\n\t\t\t\t\treturn ResolveMethodReference((MemberReferenceHandle)methodReference, context, expandVarArgs: true);\n\t\t\t\tcase HandleKind.MethodSpecification:\n\t\t\t\t\treturn ResolveMethodSpecification((MethodSpecificationHandle)methodReference, context, expandVarArgs: true);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new BadImageFormatException(\"Metadata token must be either a methoddef, memberref or methodspec\");\n\t\t\t}\n\t\t}\n\n\t\tIMethod ResolveMethodDefinition(MethodDefinitionHandle methodDefHandle, bool expandVarArgs)\n\t\t{\n\t\t\tvar method = GetDefinition(methodDefHandle);\n\t\t\tif (expandVarArgs && method.Parameters.LastOrDefault()?.Type.Kind == TypeKind.ArgList)\n\t\t\t{\n\t\t\t\tmethod = new VarArgInstanceMethod(method, EmptyList<IType>.Instance);\n\t\t\t}\n\t\t\treturn method;\n\t\t}\n\n\t\tIMethod ResolveMethodSpecification(MethodSpecificationHandle methodSpecHandle, GenericContext context, bool expandVarArgs)\n\t\t{\n\t\t\tvar methodSpec = metadata.GetMethodSpecification(methodSpecHandle);\n\t\t\tvar methodTypeArgs = methodSpec.DecodeSignature(TypeProvider, context)\n\t\t\t\t.SelectReadOnlyArray(IntroduceTupleTypes);\n\t\t\tIMethod method;\n\t\t\tif (methodSpec.Method.Kind == HandleKind.MethodDefinition)\n\t\t\t{\n\t\t\t\t// generic instance of a methoddef (=generic method in non-generic class in current assembly)\n\t\t\t\tmethod = ResolveMethodDefinition((MethodDefinitionHandle)methodSpec.Method, expandVarArgs);\n\t\t\t\tmethod = method.Specialize(new TypeParameterSubstitution(null, methodTypeArgs));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tmethod = ResolveMethodReference((MemberReferenceHandle)methodSpec.Method, context, methodTypeArgs, expandVarArgs);\n\t\t\t}\n\t\t\treturn method;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Resolves a method reference.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Class type arguments are provided by the declaring type stored in the memberRef.\n\t\t/// Method type arguments are provided by the caller.\n\t\t/// </remarks>\n\t\tIMethod ResolveMethodReference(MemberReferenceHandle memberRefHandle, GenericContext context, IReadOnlyList<IType> methodTypeArguments = null, bool expandVarArgs = true)\n\t\t{\n\t\t\tvar memberRef = metadata.GetMemberReference(memberRefHandle);\n\t\t\tif (memberRef.GetKind() != MemberReferenceKind.Method)\n\t\t\t{\n\t\t\t\tthrow new BadImageFormatException($\"Member reference must be method, but was: {memberRef.GetKind()}\");\n\t\t\t}\n\t\t\tMethodSignature<IType> signature;\n\t\t\tIReadOnlyList<IType> classTypeArguments = null;\n\t\t\tIMethod method;\n\t\t\tif (memberRef.Parent.Kind == HandleKind.MethodDefinition)\n\t\t\t{\n\t\t\t\tmethod = ResolveMethodDefinition((MethodDefinitionHandle)memberRef.Parent, expandVarArgs: false);\n\t\t\t\tsignature = memberRef.DecodeMethodSignature(TypeProvider, context);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar declaringType = ResolveDeclaringType(memberRef.Parent, context);\n\t\t\t\tvar declaringTypeDefinition = declaringType.GetDefinition();\n\t\t\t\tif (declaringType.TypeArguments.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tclassTypeArguments = declaringType.TypeArguments;\n\t\t\t\t}\n\t\t\t\t// Note: declaringType might be parameterized, but the signature is for the original method definition.\n\t\t\t\t// We'll have to search the member directly on declaringTypeDefinition.\n\t\t\t\tstring name = metadata.GetString(memberRef.Name);\n\t\t\t\tsignature = memberRef.DecodeMethodSignature(TypeProvider,\n\t\t\t\t\tnew GenericContext(declaringTypeDefinition?.TypeParameters));\n\t\t\t\tif (declaringTypeDefinition != null)\n\t\t\t\t{\n\t\t\t\t\t// Find the set of overloads to search:\n\t\t\t\t\tIEnumerable<IMethod> methods;\n\t\t\t\t\tif (name == \".ctor\")\n\t\t\t\t\t{\n\t\t\t\t\t\tmethods = declaringTypeDefinition.GetConstructors();\n\t\t\t\t\t}\n\t\t\t\t\telse if (name == \".cctor\")\n\t\t\t\t\t{\n\t\t\t\t\t\tmethods = declaringTypeDefinition.Methods.Where(m => m.IsConstructor && m.IsStatic);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tmethods = declaringTypeDefinition.GetMethods(m => m.Name == name, GetMemberOptions.IgnoreInheritedMembers)\n\t\t\t\t\t\t\t.Concat(declaringTypeDefinition.GetAccessors(m => m.Name == name, GetMemberOptions.IgnoreInheritedMembers));\n\t\t\t\t\t}\n\t\t\t\t\t// Determine the expected parameters from the signature:\n\t\t\t\t\tImmutableArray<IType> parameterTypes;\n\t\t\t\t\tif (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs)\n\t\t\t\t\t{\n\t\t\t\t\t\tparameterTypes = signature.ParameterTypes\n\t\t\t\t\t\t\t.Take(signature.RequiredParameterCount)\n\t\t\t\t\t\t\t.Concat(new[] { SpecialType.ArgList })\n\t\t\t\t\t\t\t.ToImmutableArray();\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tparameterTypes = signature.ParameterTypes;\n\t\t\t\t\t}\n\t\t\t\t\t// Search for the matching method:\n\t\t\t\t\tmethod = null;\n\t\t\t\t\tforeach (var m in methods)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (m.TypeParameters.Count != signature.GenericParameterCount)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tif (signature.Header.IsInstance != !m.IsStatic)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tif (CompareSignatures(m.Parameters, parameterTypes) && CompareTypes(m.ReturnType, signature.ReturnType))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmethod = m;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tmethod = null;\n\t\t\t\t}\n\t\t\t\tif (method == null)\n\t\t\t\t{\n\t\t\t\t\tmethod = CreateFakeMethod(declaringType, name, signature);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (classTypeArguments != null || methodTypeArguments != null)\n\t\t\t{\n\t\t\t\tmethod = method.Specialize(new TypeParameterSubstitution(classTypeArguments, methodTypeArguments));\n\t\t\t}\n\t\t\tif (expandVarArgs && signature.Header.CallingConvention == SignatureCallingConvention.VarArgs)\n\t\t\t{\n\t\t\t\tmethod = new VarArgInstanceMethod(method, signature.ParameterTypes.Skip(signature.RequiredParameterCount));\n\t\t\t}\n\t\t\treturn method;\n\t\t}\n\n\t\tstatic readonly NormalizeTypeVisitor normalizeTypeVisitor = new NormalizeTypeVisitor {\n\t\t\tReplaceClassTypeParametersWithDummy = true,\n\t\t\tReplaceMethodTypeParametersWithDummy = true,\n\t\t};\n\n\t\tstatic bool CompareTypes(IType a, IType b)\n\t\t{\n\t\t\tIType type1 = a.AcceptVisitor(normalizeTypeVisitor);\n\t\t\tIType type2 = b.AcceptVisitor(normalizeTypeVisitor);\n\t\t\treturn type1.Equals(type2);\n\t\t}\n\n\t\tstatic bool CompareSignatures(IReadOnlyList<IParameter> parameters, ImmutableArray<IType> parameterTypes)\n\t\t{\n\t\t\tif (parameterTypes.Length != parameters.Count)\n\t\t\t\treturn false;\n\t\t\tfor (int i = 0; i < parameterTypes.Length; i++)\n\t\t\t{\n\t\t\t\tif (!CompareTypes(parameterTypes[i], parameters[i].Type))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Create a dummy IMethod from the specified MethodReference\n\t\t/// </summary>\n\t\tIMethod CreateFakeMethod(IType declaringType, string name, MethodSignature<IType> signature)\n\t\t{\n\t\t\tSymbolKind symbolKind = SymbolKind.Method;\n\t\t\tif (name == \".ctor\" || name == \".cctor\")\n\t\t\t\tsymbolKind = SymbolKind.Constructor;\n\t\t\tvar m = new FakeMethod(Compilation, symbolKind);\n\t\t\tm.DeclaringType = declaringType;\n\t\t\tm.Name = name;\n\t\t\tm.ReturnType = signature.ReturnType;\n\t\t\tm.IsStatic = !signature.Header.IsInstance;\n\n\t\t\tTypeParameterSubstitution substitution = null;\n\t\t\tif (signature.GenericParameterCount > 0)\n\t\t\t{\n\t\t\t\tvar typeParameters = new List<ITypeParameter>();\n\t\t\t\tfor (int i = 0; i < signature.GenericParameterCount; i++)\n\t\t\t\t{\n\t\t\t\t\ttypeParameters.Add(new DefaultTypeParameter(m, i));\n\t\t\t\t}\n\t\t\t\tm.TypeParameters = typeParameters;\n\t\t\t\tsubstitution = new TypeParameterSubstitution(declaringType.TypeArguments, typeParameters);\n\t\t\t}\n\t\t\telse if (declaringType.TypeArguments.Count > 0)\n\t\t\t{\n\t\t\t\tsubstitution = declaringType.GetSubstitution();\n\t\t\t}\n\t\t\tvar parameters = new List<IParameter>();\n\t\t\tfor (int i = 0; i < signature.RequiredParameterCount; i++)\n\t\t\t{\n\t\t\t\tvar type = signature.ParameterTypes[i];\n\t\t\t\tif (substitution != null)\n\t\t\t\t{\n\t\t\t\t\t// replace the dummy method type parameters with the owned instances we just created\n\t\t\t\t\ttype = type.AcceptVisitor(substitution);\n\t\t\t\t}\n\t\t\t\tparameters.Add(new DefaultParameter(type, \"\"));\n\t\t\t}\n\t\t\tm.Parameters = parameters;\n\n\t\t\tGuessFakeMethodAccessor(declaringType, name, signature, m, parameters);\n\n\t\t\treturn m;\n\t\t}\n\n\t\tprivate void GuessFakeMethodAccessor(IType declaringType, string name, MethodSignature<IType> signature, FakeMethod m, List<IParameter> parameters)\n\t\t{\n\t\t\tif (signature.GenericParameterCount > 0)\n\t\t\t\treturn;\n\n\t\t\tvar guessedGetter = name.StartsWith(\"get_\", StringComparison.Ordinal);\n\t\t\tvar guessedSetter = name.StartsWith(\"set_\", StringComparison.Ordinal);\n\t\t\tif (guessedGetter || guessedSetter)\n\t\t\t{\n\t\t\t\tvar propertyName = name.Substring(4);\n\n\t\t\t\tvar fakeProperty = new FakeProperty(Compilation) {\n\t\t\t\t\tName = propertyName,\n\t\t\t\t\tDeclaringType = declaringType,\n\t\t\t\t\tIsStatic = m.IsStatic,\n\t\t\t\t};\n\n\t\t\t\tif (guessedGetter)\n\t\t\t\t{\n\t\t\t\t\tif (signature.ReturnType.Kind == TypeKind.Void)\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\tm.AccessorKind = MethodSemanticsAttributes.Getter;\n\t\t\t\t\tm.AccessorOwner = fakeProperty;\n\t\t\t\t\tfakeProperty.Getter = m;\n\t\t\t\t\tfakeProperty.ReturnType = signature.ReturnType;\n\t\t\t\t\tfakeProperty.IsIndexer = parameters.Count > 0;\n\t\t\t\t\tfakeProperty.Parameters = parameters;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (guessedSetter)\n\t\t\t\t{\n\t\t\t\t\tif (parameters.Count < 1 || signature.ReturnType.Kind != TypeKind.Void)\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\tm.AccessorKind = MethodSemanticsAttributes.Setter;\n\t\t\t\t\tm.AccessorOwner = fakeProperty;\n\t\t\t\t\tfakeProperty.Setter = m;\n\t\t\t\t\tfakeProperty.ReturnType = parameters.Last().Type;\n\t\t\t\t\tfakeProperty.IsIndexer = parameters.Count > 1;\n\t\t\t\t\tfakeProperty.Parameters = parameters.SkipLast(1).ToArray();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst string addPrefix = \"add_\";\n\t\t\tconst string removePrefix = \"remove_\";\n\t\t\tconst string raisePrefix = \"raise_\";\n\t\t\tvar guessedAdd = name.StartsWith(addPrefix, StringComparison.Ordinal);\n\t\t\tvar guessedRemove = name.StartsWith(removePrefix, StringComparison.Ordinal);\n\t\t\tvar guessedRaise = name.StartsWith(raisePrefix, StringComparison.Ordinal);\n\t\t\tif (guessedAdd || guessedRemove || guessedRaise)\n\t\t\t{\n\t\t\t\tvar fakeEvent = new FakeEvent(Compilation) {\n\t\t\t\t\tDeclaringType = declaringType,\n\t\t\t\t\tIsStatic = m.IsStatic,\n\t\t\t\t};\n\n\t\t\t\tif (guessedAdd)\n\t\t\t\t{\n\t\t\t\t\tif (parameters.Count != 1)\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\tm.AccessorKind = MethodSemanticsAttributes.Adder;\n\t\t\t\t\tm.AccessorOwner = fakeEvent;\n\n\t\t\t\t\tfakeEvent.Name = name.Substring(addPrefix.Length);\n\t\t\t\t\tfakeEvent.AddAccessor = m;\n\t\t\t\t\tfakeEvent.ReturnType = parameters.Single().Type;\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (guessedRemove)\n\t\t\t\t{\n\t\t\t\t\tif (parameters.Count != 1)\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\tm.AccessorKind = MethodSemanticsAttributes.Remover;\n\t\t\t\t\tm.AccessorOwner = fakeEvent;\n\n\t\t\t\t\tfakeEvent.Name = name.Substring(removePrefix.Length);\n\t\t\t\t\tfakeEvent.RemoveAccessor = m;\n\t\t\t\t\tfakeEvent.ReturnType = parameters.Single().Type;\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (guessedRaise)\n\t\t\t\t{\n\t\t\t\t\tfakeEvent.Name = name.Substring(raisePrefix.Length);\n\t\t\t\t\tfakeEvent.InvokeAccessor = m;\n\t\t\t\t\tm.AccessorKind = MethodSemanticsAttributes.Raiser;\n\t\t\t\t\tm.AccessorOwner = fakeEvent;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Resolve Entity\n\t\t/// <summary>\n\t\t/// Resolves a symbol.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// * Types are resolved to their definition, as IType does not implement ISymbol.\n\t\t///    * types without definition will resolve to <c>null</c>\n\t\t///    * use ResolveType() to properly resolve types\n\t\t/// * When resolving methods, varargs signatures are not expanded.\n\t\t///    * use ResolveMethod() instead to get an IMethod instance suitable for call-sites\n\t\t/// * May return specialized members, where generics are involved.\n\t\t/// * Other types of handles that don't correspond to TS entities, will return <c>null</c>.\n\t\t/// </remarks>\n\t\tpublic IEntity ResolveEntity(EntityHandle entityHandle, GenericContext context = default)\n\t\t{\n\t\t\tswitch (entityHandle.Kind)\n\t\t\t{\n\t\t\t\tcase HandleKind.TypeReference:\n\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\tcase HandleKind.TypeSpecification:\n\t\t\t\tcase HandleKind.ExportedType:\n\t\t\t\t\t// Using ResolveDeclaringType() here because ResolveType() might return\n\t\t\t\t\t// nint/nuint which are SpecialTypes without a definition.\n\t\t\t\t\treturn ResolveDeclaringType(entityHandle, context).GetDefinition();\n\t\t\t\tcase HandleKind.MemberReference:\n\t\t\t\t\tvar memberReferenceHandle = (MemberReferenceHandle)entityHandle;\n\t\t\t\t\tswitch (metadata.GetMemberReference(memberReferenceHandle).GetKind())\n\t\t\t\t\t{\n\t\t\t\t\t\tcase MemberReferenceKind.Method:\n\t\t\t\t\t\t\t// for consistency with the MethodDefinition case, never expand varargs\n\t\t\t\t\t\t\treturn ResolveMethodReference(memberReferenceHandle, context, expandVarArgs: false);\n\t\t\t\t\t\tcase MemberReferenceKind.Field:\n\t\t\t\t\t\t\treturn ResolveFieldReference(memberReferenceHandle, context);\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow new BadImageFormatException(\"Unknown MemberReferenceKind\");\n\t\t\t\t\t}\n\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\treturn GetDefinition((MethodDefinitionHandle)entityHandle);\n\t\t\t\tcase HandleKind.MethodSpecification:\n\t\t\t\t\treturn ResolveMethodSpecification((MethodSpecificationHandle)entityHandle, context, expandVarArgs: false);\n\t\t\t\tcase HandleKind.FieldDefinition:\n\t\t\t\t\treturn GetDefinition((FieldDefinitionHandle)entityHandle);\n\t\t\t\tcase HandleKind.EventDefinition:\n\t\t\t\t\treturn GetDefinition((EventDefinitionHandle)entityHandle);\n\t\t\t\tcase HandleKind.PropertyDefinition:\n\t\t\t\t\treturn GetDefinition((PropertyDefinitionHandle)entityHandle);\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tIField ResolveFieldReference(MemberReferenceHandle memberReferenceHandle, GenericContext context)\n\t\t{\n\t\t\tvar memberRef = metadata.GetMemberReference(memberReferenceHandle);\n\t\t\tvar declaringType = ResolveDeclaringType(memberRef.Parent, context);\n\t\t\tvar declaringTypeDefinition = declaringType.GetDefinition();\n\t\t\tstring name = metadata.GetString(memberRef.Name);\n\t\t\t// field signature is for the definition, not the generic instance\n\t\t\tvar signature = memberRef.DecodeFieldSignature(TypeProvider,\n\t\t\t\tnew GenericContext(declaringTypeDefinition?.TypeParameters));\n\t\t\t// 'f' in the predicate is also the definition, even if declaringType is a ParameterizedType\n\t\t\tvar field = declaringType.GetFields(f => f.Name == name && CompareTypes(f.ReturnType, signature),\n\t\t\t\tGetMemberOptions.IgnoreInheritedMembers).FirstOrDefault();\n\t\t\tif (field == null)\n\t\t\t{\n\t\t\t\t// If it's a field in a generic type, we need to substitute the type arguments:\n\t\t\t\tif (declaringType.TypeArguments.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tsignature = signature.AcceptVisitor(declaringType.GetSubstitution());\n\t\t\t\t}\n\t\t\t\tfield = new FakeField(Compilation) {\n\t\t\t\t\tReturnType = signature,\n\t\t\t\t\tName = name,\n\t\t\t\t\tDeclaringType = declaringType,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn field;\n\t\t}\n\t\t#endregion\n\n\t\t#region Decode Standalone Signature\n\t\tpublic (SignatureHeader, FunctionPointerType) DecodeMethodSignature(StandaloneSignatureHandle handle, GenericContext genericContext)\n\t\t{\n\t\t\tvar standaloneSignature = metadata.GetStandaloneSignature(handle);\n\t\t\tif (standaloneSignature.GetKind() != StandaloneSignatureKind.Method)\n\t\t\t\tthrow new BadImageFormatException(\"Expected Method signature\");\n\t\t\tvar sig = standaloneSignature.DecodeMethodSignature(TypeProvider, genericContext);\n\t\t\tvar fpt = FunctionPointerType.FromSignature(sig, this);\n\t\t\treturn (sig.Header, (FunctionPointerType)IntroduceTupleTypes(fpt));\n\t\t}\n\n\t\tpublic ImmutableArray<IType> DecodeLocalSignature(StandaloneSignatureHandle handle, GenericContext genericContext)\n\t\t{\n\t\t\tvar standaloneSignature = metadata.GetStandaloneSignature(handle);\n\t\t\tif (standaloneSignature.GetKind() != StandaloneSignatureKind.LocalVariables)\n\t\t\t\tthrow new BadImageFormatException(\"Expected LocalVariables signature\");\n\t\t\tvar types = standaloneSignature.DecodeLocalSignature(TypeProvider, genericContext);\n\t\t\treturn ImmutableArray.CreateRange(types, IntroduceTupleTypes);\n\t\t}\n\t\t#endregion\n\n\t\t#region Module / Assembly attributes\n\t\t/// <summary>\n\t\t/// Gets the list of all assembly attributes in the project.\n\t\t/// </summary>\n\t\tpublic IEnumerable<IAttribute> GetAssemblyAttributes()\n\t\t{\n\t\t\tvar b = new AttributeListBuilder(this);\n\t\t\tif (metadata.IsAssembly)\n\t\t\t{\n\t\t\t\tvar assembly = metadata.GetAssemblyDefinition();\n\t\t\t\tb.Add(metadata.GetCustomAttributes(Handle.AssemblyDefinition), SymbolKind.Module);\n\t\t\t\tb.AddSecurityAttributes(assembly.GetDeclarativeSecurityAttributes());\n\n\t\t\t\t// AssemblyVersionAttribute\n\t\t\t\tif (assembly.Version != null)\n\t\t\t\t{\n\t\t\t\t\tb.Add(KnownAttribute.AssemblyVersion, KnownTypeCode.String, assembly.Version.ToString());\n\t\t\t\t}\n\n\t\t\t\tAddTypeForwarderAttributes(ref b);\n\t\t\t}\n\t\t\treturn b.Build();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the list of all module attributes in the project.\n\t\t/// </summary>\n\t\tpublic IEnumerable<IAttribute> GetModuleAttributes()\n\t\t{\n\t\t\tvar b = new AttributeListBuilder(this);\n\t\t\tb.Add(metadata.GetCustomAttributes(Handle.ModuleDefinition), SymbolKind.Module);\n\t\t\tif (!metadata.IsAssembly)\n\t\t\t{\n\t\t\t\tAddTypeForwarderAttributes(ref b);\n\t\t\t}\n\t\t\treturn b.Build();\n\t\t}\n\n\t\tvoid AddTypeForwarderAttributes(ref AttributeListBuilder b)\n\t\t{\n\t\t\tforeach (ExportedTypeHandle t in metadata.ExportedTypes)\n\t\t\t{\n\t\t\t\tvar type = metadata.GetExportedType(t);\n\t\t\t\tif (type.IsForwarder)\n\t\t\t\t{\n\t\t\t\t\tb.Add(KnownAttribute.TypeForwardedTo, KnownTypeCode.Type, ResolveForwardedType(type));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tIType ResolveForwardedType(ExportedType forwarder)\n\t\t{\n\t\t\tIModule module = ResolveModule(forwarder);\n\t\t\tvar typeName = forwarder.GetFullTypeName(metadata);\n\t\t\tif (module == null)\n\t\t\t\treturn new UnknownType(typeName);\n\t\t\tusing (var busyLock = BusyManager.Enter(this))\n\t\t\t{\n\t\t\t\tif (busyLock.Success)\n\t\t\t\t{\n\t\t\t\t\tvar td = module.GetTypeDefinition(typeName);\n\t\t\t\t\tif (td != null)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn td;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn new UnknownType(typeName);\n\n\t\t\tIModule ResolveModule(ExportedType type)\n\t\t\t{\n\t\t\t\tswitch (type.Implementation.Kind)\n\t\t\t\t{\n\t\t\t\t\tcase HandleKind.AssemblyFile:\n\t\t\t\t\t\t// TODO : Resolve assembly file (module)...\n\t\t\t\t\t\treturn this;\n\t\t\t\t\tcase HandleKind.ExportedType:\n\t\t\t\t\t\tvar outerType = metadata.GetExportedType((ExportedTypeHandle)type.Implementation);\n\t\t\t\t\t\treturn ResolveModule(outerType);\n\t\t\t\t\tcase HandleKind.AssemblyReference:\n\t\t\t\t\t\tvar asmRef = metadata.GetAssemblyReference((AssemblyReferenceHandle)type.Implementation);\n\t\t\t\t\t\tstring shortName = metadata.GetString(asmRef.Name);\n\t\t\t\t\t\tforeach (var asm in Compilation.Modules)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (string.Equals(asm.AssemblyName, shortName, StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn asm;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new BadImageFormatException(\"Expected implementation to be either an AssemblyFile, ExportedType or AssemblyReference.\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Attribute Helpers\n\t\t/// <summary>\n\t\t/// Cache for parameterless known attribute types.\n\t\t/// </summary>\n\t\treadonly IType[] knownAttributeTypes = new IType[KnownAttributes.Count];\n\n\t\tinternal IType GetAttributeType(KnownAttribute attr)\n\t\t{\n\t\t\tvar ty = LazyInit.VolatileRead(ref knownAttributeTypes[(int)attr]);\n\t\t\tif (ty != null)\n\t\t\t\treturn ty;\n\t\t\tty = Compilation.FindType(attr.GetTypeName());\n\t\t\treturn LazyInit.GetOrSet(ref knownAttributeTypes[(int)attr], ty);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Cache for parameterless known attributes.\n\t\t/// </summary>\n\t\treadonly IAttribute[] knownAttributes = new IAttribute[KnownAttributes.Count];\n\n\t\t/// <summary>\n\t\t/// Construct a builtin attribute.\n\t\t/// </summary>\n\t\tinternal IAttribute MakeAttribute(KnownAttribute type)\n\t\t{\n\t\t\tvar attr = LazyInit.VolatileRead(ref knownAttributes[(int)type]);\n\t\t\tif (attr != null)\n\t\t\t\treturn attr;\n\t\t\tattr = new DefaultAttribute(GetAttributeType(type),\n\t\t\t\tImmutableArray.Create<CustomAttributeTypedArgument<IType>>(),\n\t\t\t\tImmutableArray.Create<CustomAttributeNamedArgument<IType>>());\n\t\t\treturn LazyInit.GetOrSet(ref knownAttributes[(int)type], attr);\n\t\t}\n\t\t#endregion\n\n\t\t#region Visibility Filter\n\t\tinternal bool IncludeInternalMembers => (options & TypeSystemOptions.OnlyPublicAPI) == 0;\n\n\t\tinternal bool IsVisible(FieldAttributes att)\n\t\t{\n\t\t\tatt &= FieldAttributes.FieldAccessMask;\n\t\t\treturn IncludeInternalMembers\n\t\t\t\t|| att == FieldAttributes.Public\n\t\t\t\t|| att == FieldAttributes.Family\n\t\t\t\t|| att == FieldAttributes.FamORAssem;\n\t\t}\n\n\t\tinternal bool IsVisible(MethodAttributes att)\n\t\t{\n\t\t\tatt &= MethodAttributes.MemberAccessMask;\n\t\t\treturn IncludeInternalMembers\n\t\t\t\t|| att == MethodAttributes.Public\n\t\t\t\t|| att == MethodAttributes.Family\n\t\t\t\t|| att == MethodAttributes.FamORAssem;\n\t\t}\n\t\t#endregion\n\n\t\t#region Nullability Reference Type Support\n\t\treadonly Accessibility minAccessibilityForNRT;\n\n\t\tstatic Accessibility FindMinimumAccessibilityForNRT(MetadataReader metadata, CustomAttributeHandleCollection customAttributes)\n\t\t{\n\t\t\t// Determine the minimum effective accessibility an entity must have, so that the metadata stores the nullability for its type.\n\t\t\tforeach (var handle in customAttributes)\n\t\t\t{\n\t\t\t\tvar customAttribute = metadata.GetCustomAttribute(handle);\n\t\t\t\tif (customAttribute.IsKnownAttribute(metadata, KnownAttribute.NullablePublicOnly))\n\t\t\t\t{\n\t\t\t\t\tCustomAttributeValue<IType> value;\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue = customAttribute.DecodeValue(Metadata.MetadataExtensions.MinimalAttributeTypeProvider);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tcatch (EnumUnderlyingTypeResolveException)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (value.FixedArguments.Length == 1 && value.FixedArguments[0].Value is bool includesInternals)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn includesInternals ? Accessibility.ProtectedAndInternal : Accessibility.Protected;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn Accessibility.None;\n\t\t}\n\n\t\tinternal bool ShouldDecodeNullableAttributes(IEntity entity)\n\t\t{\n\t\t\tif ((options & TypeSystemOptions.NullabilityAnnotations) == 0)\n\t\t\t\treturn false;\n\t\t\tif (minAccessibilityForNRT == Accessibility.None || entity == null)\n\t\t\t\treturn true;\n\t\t\treturn minAccessibilityForNRT.LessThanOrEqual(entity.EffectiveAccessibility());\n\t\t}\n\n\t\tinternal TypeSystemOptions OptionsForEntity(IEntity entity)\n\t\t{\n\t\t\tvar opt = this.options;\n\t\t\tif ((opt & TypeSystemOptions.NullabilityAnnotations) != 0)\n\t\t\t{\n\t\t\t\tif (!ShouldDecodeNullableAttributes(entity))\n\t\t\t\t{\n\t\t\t\t\topt &= ~TypeSystemOptions.NullabilityAnnotations;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn opt;\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/ModifiedType.cs",
    "content": "// Copyright (c) 2018 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.TypeSystem.Implementation\n{\n\t/// <summary>\n\t/// Represents a modopt or modreq type.\n\t/// </summary>\n\tpublic class ModifiedType : TypeWithElementType, IType\n\t{\n\t\treadonly TypeKind kind;\n\t\treadonly IType modifier;\n\n\t\tpublic ModifiedType(IType modifier, IType unmodifiedType, bool isRequired) : base(unmodifiedType)\n\t\t{\n\t\t\tthis.kind = isRequired ? TypeKind.ModReq : TypeKind.ModOpt;\n\t\t\tthis.modifier = modifier ?? throw new ArgumentNullException(nameof(modifier));\n\t\t}\n\n\t\tpublic IType Modifier => modifier;\n\t\tpublic override TypeKind Kind => kind;\n\n\t\tpublic override string NameSuffix => (kind == TypeKind.ModReq ? \" modreq\" : \" modopt\") + $\"({modifier.FullName})\";\n\n\t\tpublic override bool? IsReferenceType => elementType.IsReferenceType;\n\t\tpublic override bool IsByRefLike => elementType.IsByRefLike;\n\t\tpublic override Nullability Nullability => elementType.Nullability;\n\n\t\tpublic override IType ChangeNullability(Nullability nullability)\n\t\t{\n\t\t\tIType newElementType = elementType.ChangeNullability(nullability);\n\t\t\tif (newElementType == elementType)\n\t\t\t\treturn this;\n\t\t\telse\n\t\t\t\treturn new ModifiedType(modifier, newElementType, kind == TypeKind.ModReq);\n\t\t}\n\n\t\tpublic override ITypeDefinition GetDefinition()\n\t\t{\n\t\t\treturn elementType.GetDefinition();\n\t\t}\n\n\t\tpublic override ITypeDefinitionOrUnknown GetDefinitionOrUnknown()\n\t\t{\n\t\t\treturn elementType.GetDefinitionOrUnknown();\n\t\t}\n\n\t\tpublic override IEnumerable<IMethod> GetAccessors(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn elementType.GetAccessors(filter, options);\n\t\t}\n\n\t\tpublic override IEnumerable<IMethod> GetConstructors(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers)\n\t\t{\n\t\t\treturn elementType.GetConstructors(filter, options);\n\t\t}\n\n\t\tpublic override IEnumerable<IEvent> GetEvents(Predicate<IEvent> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn elementType.GetEvents(filter, options);\n\t\t}\n\n\t\tpublic override IEnumerable<IField> GetFields(Predicate<IField> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn elementType.GetFields(filter, options);\n\t\t}\n\n\t\tpublic override IEnumerable<IMember> GetMembers(Predicate<IMember> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn elementType.GetMembers(filter, options);\n\t\t}\n\n\t\tpublic override IEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn elementType.GetMethods(typeArguments, filter, options);\n\t\t}\n\n\t\tpublic override IEnumerable<IMethod> GetMethods(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn elementType.GetMethods(filter, options);\n\t\t}\n\n\t\tpublic override IEnumerable<IType> GetNestedTypes(IReadOnlyList<IType> typeArguments, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn elementType.GetNestedTypes(typeArguments, filter, options);\n\t\t}\n\n\t\tpublic override IEnumerable<IType> GetNestedTypes(Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn elementType.GetNestedTypes(filter, options);\n\t\t}\n\n\t\tpublic override IEnumerable<IProperty> GetProperties(Predicate<IProperty> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn elementType.GetProperties(filter, options);\n\t\t}\n\n\t\tpublic override IType VisitChildren(TypeVisitor visitor)\n\t\t{\n\t\t\tvar newElementType = elementType.AcceptVisitor(visitor);\n\t\t\tvar newModifier = modifier.AcceptVisitor(visitor);\n\t\t\tif (newModifier != modifier || newElementType != elementType)\n\t\t\t{\n\t\t\t\treturn new ModifiedType(newModifier, newElementType, kind == TypeKind.ModReq);\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic override IType AcceptVisitor(TypeVisitor visitor)\n\t\t{\n\t\t\tif (kind == TypeKind.ModReq)\n\t\t\t\treturn visitor.VisitModReq(this);\n\t\t\telse\n\t\t\t\treturn visitor.VisitModOpt(this);\n\t\t}\n\n\t\tpublic override bool Equals(IType other)\n\t\t{\n\t\t\treturn other is ModifiedType o && kind == o.kind && modifier.Equals(o.modifier) && elementType.Equals(o.elementType);\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\treturn (int)kind ^ (elementType.GetHashCode() * 1344795899) ^ (modifier.GetHashCode() * 901375117);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/NormalizeTypeVisitor.cs",
    "content": "// Copyright (c) 2019 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\tsealed class NormalizeTypeVisitor : TypeVisitor\n\t{\n\t\t/// <summary>\n\t\t/// NormalizeTypeVisitor that does not normalize type parameters,\n\t\t/// but performs type erasure (object->dynamic; tuple->underlying type).\n\t\t/// </summary>\n\t\tinternal static readonly NormalizeTypeVisitor TypeErasure = new NormalizeTypeVisitor {\n\t\t\tReplaceClassTypeParametersWithDummy = false,\n\t\t\tReplaceMethodTypeParametersWithDummy = false,\n\t\t\tDynamicAndObject = true,\n\t\t\tIntPtrToNInt = true,\n\t\t\tTupleToUnderlyingType = true,\n\t\t\tRemoveModOpt = true,\n\t\t\tRemoveModReq = true,\n\t\t\tRemoveNullability = true,\n\t\t};\n\n\t\tinternal static readonly NormalizeTypeVisitor IgnoreNullabilityAndTuples = new NormalizeTypeVisitor {\n\t\t\tReplaceClassTypeParametersWithDummy = false,\n\t\t\tReplaceMethodTypeParametersWithDummy = false,\n\t\t\tDynamicAndObject = false,\n\t\t\tIntPtrToNInt = false,\n\t\t\tTupleToUnderlyingType = true,\n\t\t\tRemoveModOpt = true,\n\t\t\tRemoveModReq = true,\n\t\t\tRemoveNullability = true,\n\t\t};\n\n\t\tinternal static readonly NormalizeTypeVisitor IgnoreNullability = new NormalizeTypeVisitor {\n\t\t\tReplaceClassTypeParametersWithDummy = false,\n\t\t\tReplaceMethodTypeParametersWithDummy = false,\n\t\t\tDynamicAndObject = false,\n\t\t\tIntPtrToNInt = false,\n\t\t\tTupleToUnderlyingType = false,\n\t\t\tRemoveModOpt = true,\n\t\t\tRemoveModReq = true,\n\t\t\tRemoveNullability = true,\n\t\t};\n\n\t\tpublic bool EquivalentTypes(IType a, IType b)\n\t\t{\n\t\t\ta = a.AcceptVisitor(this);\n\t\t\tb = b.AcceptVisitor(this);\n\t\t\treturn a.Equals(b);\n\t\t}\n\n\t\tpublic bool RemoveModOpt = true;\n\t\tpublic bool RemoveModReq = true;\n\t\tpublic bool ReplaceClassTypeParametersWithDummy = true;\n\t\tpublic bool ReplaceMethodTypeParametersWithDummy = true;\n\t\tpublic bool DynamicAndObject = true;\n\t\tpublic bool IntPtrToNInt = true;\n\t\tpublic bool TupleToUnderlyingType = true;\n\t\tpublic bool RemoveNullability = true;\n\n\t\tpublic override IType VisitTypeParameter(ITypeParameter type)\n\t\t{\n\t\t\tif (type.OwnerType == SymbolKind.Method && ReplaceMethodTypeParametersWithDummy)\n\t\t\t{\n\t\t\t\treturn DummyTypeParameter.GetMethodTypeParameter(type.Index);\n\t\t\t}\n\t\t\telse if (type.OwnerType == SymbolKind.TypeDefinition && ReplaceClassTypeParametersWithDummy)\n\t\t\t{\n\t\t\t\treturn DummyTypeParameter.GetClassTypeParameter(type.Index);\n\t\t\t}\n\t\t\telse if (RemoveNullability && type is NullabilityAnnotatedTypeParameter natp)\n\t\t\t{\n\t\t\t\treturn natp.TypeWithoutAnnotation.AcceptVisitor(this);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn base.VisitTypeParameter(type);\n\t\t\t}\n\t\t}\n\n\t\tpublic override IType VisitTypeDefinition(ITypeDefinition type)\n\t\t{\n\t\t\tswitch (type.KnownTypeCode)\n\t\t\t{\n\t\t\t\tcase KnownTypeCode.Object when DynamicAndObject:\n\t\t\t\t\t// Instead of normalizing dynamic->object,\n\t\t\t\t\t// we do this the opposite direction, so that we don't need a compilation to find the object type.\n\t\t\t\t\tif (RemoveNullability)\n\t\t\t\t\t\treturn SpecialType.Dynamic;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn SpecialType.Dynamic.ChangeNullability(type.Nullability);\n\t\t\t\tcase KnownTypeCode.IntPtr when IntPtrToNInt:\n\t\t\t\t\treturn SpecialType.NInt;\n\t\t\t\tcase KnownTypeCode.UIntPtr when IntPtrToNInt:\n\t\t\t\t\treturn SpecialType.NUInt;\n\t\t\t}\n\t\t\treturn base.VisitTypeDefinition(type);\n\t\t}\n\n\t\tpublic override IType VisitTupleType(TupleType type)\n\t\t{\n\t\t\tif (TupleToUnderlyingType)\n\t\t\t{\n\t\t\t\treturn type.UnderlyingType.AcceptVisitor(this);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn base.VisitTupleType(type);\n\t\t\t}\n\t\t}\n\n\t\tpublic override IType VisitNullabilityAnnotatedType(NullabilityAnnotatedType type)\n\t\t{\n\t\t\tif (RemoveNullability)\n\t\t\t\treturn type.TypeWithoutAnnotation.AcceptVisitor(this);\n\t\t\telse\n\t\t\t\treturn base.VisitNullabilityAnnotatedType(type);\n\t\t}\n\n\t\tpublic override IType VisitArrayType(ArrayType type)\n\t\t{\n\t\t\tif (RemoveNullability)\n\t\t\t\treturn base.VisitArrayType(type).ChangeNullability(Nullability.Oblivious);\n\t\t\telse\n\t\t\t\treturn base.VisitArrayType(type);\n\t\t}\n\n\t\tpublic override IType VisitModOpt(ModifiedType type)\n\t\t{\n\t\t\tif (RemoveModOpt)\n\t\t\t{\n\t\t\t\treturn type.ElementType.AcceptVisitor(this);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn base.VisitModOpt(type);\n\t\t\t}\n\t\t}\n\n\t\tpublic override IType VisitModReq(ModifiedType type)\n\t\t{\n\t\t\tif (RemoveModReq)\n\t\t\t{\n\t\t\t\treturn type.ElementType.AcceptVisitor(this);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn base.VisitModReq(type);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/Nullability.cs",
    "content": "// Copyright (c) 2019 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\tpublic enum Nullability : byte\n\t{\n\t\tOblivious = 0,\n\t\tNotNullable = 1,\n\t\tNullable = 2\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/NullableType.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Static helper methods for working with nullable types.\n\t/// </summary>\n\tpublic static class NullableType\n\t{\n\t\t/// <summary>\n\t\t/// Gets whether the specified type is a nullable type.\n\t\t/// </summary>\n\t\tpublic static bool IsNullable(IType type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tParameterizedType pt = type.SkipModifiers() as ParameterizedType;\n\t\t\treturn pt != null && pt.TypeParameterCount == 1 && pt.GenericType.IsKnownType(KnownTypeCode.NullableOfT);\n\t\t}\n\n\t\tpublic static bool IsNonNullableValueType(IType type)\n\t\t{\n\t\t\treturn type.IsReferenceType == false && !IsNullable(type);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the element type, if <paramref name=\"type\"/> is a nullable type.\n\t\t/// Otherwise, returns the type itself.\n\t\t/// </summary>\n\t\tpublic static IType GetUnderlyingType(IType type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tParameterizedType pt = type.SkipModifiers() as ParameterizedType;\n\t\t\tif (pt != null && pt.TypeParameterCount == 1 && pt.GenericType.IsKnownType(KnownTypeCode.NullableOfT))\n\t\t\t\treturn pt.GetTypeArgument(0);\n\t\t\telse\n\t\t\t\treturn type;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a nullable type.\n\t\t/// </summary>\n\t\tpublic static IType Create(ICompilation compilation, IType elementType)\n\t\t{\n\t\t\tif (compilation == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(compilation));\n\t\t\tif (elementType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(elementType));\n\n\t\t\tIType nullableType = compilation.FindType(KnownTypeCode.NullableOfT);\n\t\t\tITypeDefinition nullableTypeDef = nullableType.GetDefinition();\n\t\t\tif (nullableTypeDef != null)\n\t\t\t\treturn new ParameterizedType(nullableTypeDef, new[] { elementType });\n\t\t\telse\n\t\t\t\treturn nullableType;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a nullable type reference.\n\t\t/// </summary>\n\t\tpublic static ParameterizedTypeReference Create(ITypeReference elementType)\n\t\t{\n\t\t\tif (elementType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(elementType));\n\t\t\treturn new ParameterizedTypeReference(KnownTypeReference.Get(KnownTypeCode.NullableOfT), new[] { elementType });\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/ParameterListComparer.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Compares parameter lists by comparing the types of all parameters.\n\t/// </summary>\n\t/// <remarks>\n\t/// 'ref int' and 'out int' are considered to be equal - unless <see cref=\"includeModifiers\" /> is set to true.\n\t/// 'object' and 'dynamic' are also equal.\n\t/// For generic methods, \"Method{T}(T a)\" and \"Method{S}(S b)\" are considered equal.\n\t/// However, \"Method(T a)\" and \"Method(S b)\" are not considered equal when the type parameters T and S belong to classes.\n\t/// </remarks>\n\tpublic sealed class ParameterListComparer : IEqualityComparer<IReadOnlyList<IParameter>>\n\t{\n\t\tpublic static readonly ParameterListComparer Instance = new ParameterListComparer();\n\n\t\tstatic readonly NormalizeTypeVisitor normalizationVisitor = new NormalizeTypeVisitor {\n\t\t\tReplaceClassTypeParametersWithDummy = false,\n\t\t\tReplaceMethodTypeParametersWithDummy = true,\n\t\t\tDynamicAndObject = true,\n\t\t\tTupleToUnderlyingType = true,\n\t\t};\n\n\t\tbool includeModifiers;\n\n\t\tpublic static ParameterListComparer WithOptions(bool includeModifiers = false)\n\t\t{\n\t\t\treturn new ParameterListComparer() {\n\t\t\t\tincludeModifiers = includeModifiers\n\t\t\t};\n\t\t}\n\n\t\tpublic bool Equals(IReadOnlyList<IParameter> x, IReadOnlyList<IParameter> y)\n\t\t{\n\t\t\tif (x == y)\n\t\t\t\treturn true;\n\t\t\tif (x == null || y == null || x.Count != y.Count)\n\t\t\t\treturn false;\n\t\t\tfor (int i = 0; i < x.Count; i++)\n\t\t\t{\n\t\t\t\tvar a = x[i];\n\t\t\t\tvar b = y[i];\n\t\t\t\tif (a == null && b == null)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (a == null || b == null)\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (includeModifiers)\n\t\t\t\t{\n\t\t\t\t\tif (a.ReferenceKind != b.ReferenceKind)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (a.IsParams != b.IsParams)\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// We want to consider the parameter lists \"Method<T>(T a)\" and \"Method<S>(S b)\" as equal.\n\t\t\t\t// However, the parameter types are not considered equal, as T is a different type parameter than S.\n\t\t\t\t// In order to compare the method signatures, we will normalize all method type parameters.\n\t\t\t\tIType aType = a.Type.AcceptVisitor(normalizationVisitor);\n\t\t\t\tIType bType = b.Type.AcceptVisitor(normalizationVisitor);\n\n\t\t\t\tif (!aType.Equals(bType))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic int GetHashCode(IReadOnlyList<IParameter> obj)\n\t\t{\n\t\t\tint hashCode = obj.Count;\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\tforeach (IParameter p in obj)\n\t\t\t\t{\n\t\t\t\t\thashCode *= 27;\n\t\t\t\t\tIType type = p.Type.AcceptVisitor(normalizationVisitor);\n\t\t\t\t\thashCode += type.GetHashCode();\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn hashCode;\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Compares member signatures.\n\t/// </summary>\n\t/// <remarks>\n\t/// This comparer checks for equal short name, equal type parameter count, and equal parameter types (using ParameterListComparer).\n\t/// </remarks>\n\tpublic sealed class SignatureComparer : IEqualityComparer<IMember>\n\t{\n\t\tStringComparer nameComparer;\n\n\t\tpublic SignatureComparer(StringComparer nameComparer)\n\t\t{\n\t\t\tif (nameComparer == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(nameComparer));\n\t\t\tthis.nameComparer = nameComparer;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a signature comparer that uses an ordinal comparison for the member name.\n\t\t/// </summary>\n\t\tpublic static readonly SignatureComparer Ordinal = new SignatureComparer(StringComparer.Ordinal);\n\n\t\tpublic bool Equals(IMember x, IMember y)\n\t\t{\n\t\t\tif (x == y)\n\t\t\t\treturn true;\n\t\t\tif (x == null || y == null || x.SymbolKind != y.SymbolKind || !nameComparer.Equals(x.Name, y.Name))\n\t\t\t\treturn false;\n\t\t\tIParameterizedMember px = x as IParameterizedMember;\n\t\t\tIParameterizedMember py = y as IParameterizedMember;\n\t\t\tif (px != null && py != null)\n\t\t\t{\n\t\t\t\tIMethod mx = x as IMethod;\n\t\t\t\tIMethod my = y as IMethod;\n\t\t\t\tif (mx != null && my != null && mx.TypeParameters.Count != my.TypeParameters.Count)\n\t\t\t\t\treturn false;\n\t\t\t\treturn ParameterListComparer.Instance.Equals(px.Parameters, py.Parameters);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tpublic int GetHashCode(IMember obj)\n\t\t{\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\tint hash = (int)obj.SymbolKind * 33 + nameComparer.GetHashCode(obj.Name);\n\t\t\t\tIParameterizedMember pm = obj as IParameterizedMember;\n\t\t\t\tif (pm != null)\n\t\t\t\t{\n\t\t\t\t\thash *= 27;\n\t\t\t\t\thash += ParameterListComparer.Instance.GetHashCode(pm.Parameters);\n\t\t\t\t\tIMethod m = pm as IMethod;\n\t\t\t\t\tif (m != null)\n\t\t\t\t\t\thash += m.TypeParameters.Count;\n\t\t\t\t}\n\t\t\t\treturn hash;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/ParameterizedType.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// ParameterizedType represents an instance of a generic type.\n\t/// Example: List&lt;string&gt;\n\t/// </summary>\n\t/// <remarks>\n\t/// When getting the members, this type modifies the lists so that\n\t/// type parameters in the signatures of the members are replaced with\n\t/// the type arguments.\n\t/// </remarks>\n\t[Serializable]\n\tpublic sealed class ParameterizedType : IType\n\t{\n\t\treadonly IType genericType;\n\t\treadonly IType[] typeArguments;\n\n\t\tpublic ParameterizedType(IType genericType, IEnumerable<IType> typeArguments)\n\t\t{\n\t\t\tif (genericType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(genericType));\n\t\t\tif (typeArguments == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(typeArguments));\n\t\t\tthis.genericType = genericType;\n\t\t\tthis.typeArguments = typeArguments.ToArray(); // copy input array to ensure it isn't modified\n\t\t\tif (this.typeArguments.Length == 0)\n\t\t\t\tthrow new ArgumentException(\"Cannot use ParameterizedType with 0 type arguments.\");\n\t\t\tif (genericType.TypeParameterCount != this.typeArguments.Length)\n\t\t\t\tthrow new ArgumentException(\"Number of type arguments must match the type definition's number of type parameters\");\n\t\t\tICompilationProvider gp = genericType as ICompilationProvider;\n\t\t\tfor (int i = 0; i < this.typeArguments.Length; i++)\n\t\t\t{\n\t\t\t\tif (this.typeArguments[i] == null)\n\t\t\t\t\tthrow new ArgumentNullException(\"typeArguments[\" + i + \"]\");\n\t\t\t\tICompilationProvider p = this.typeArguments[i] as ICompilationProvider;\n\t\t\t\tif (p != null && gp != null && p.Compilation != gp.Compilation)\n\t\t\t\t\tthrow new InvalidOperationException(\"Cannot parameterize a type with type arguments from a different compilation.\");\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Fast internal version of the constructor. (no safety checks)\n\t\t/// Keeps the array that was passed and assumes it won't be modified.\n\t\t/// </summary>\n\t\tinternal ParameterizedType(IType genericType, params IType[] typeArguments)\n\t\t{\n\t\t\tDebug.Assert(genericType.TypeParameterCount == typeArguments.Length);\n\t\t\tthis.genericType = genericType;\n\t\t\tthis.typeArguments = typeArguments;\n\t\t}\n\n\t\tpublic TypeKind Kind {\n\t\t\tget { return genericType.Kind; }\n\t\t}\n\n\t\tpublic IType GenericType {\n\t\t\tget { return genericType; }\n\t\t}\n\n\t\tpublic bool? IsReferenceType => genericType.IsReferenceType;\n\t\tpublic bool IsByRefLike => genericType.IsByRefLike;\n\t\tpublic Nullability Nullability => genericType.Nullability;\n\n\t\tpublic IType ChangeNullability(Nullability nullability)\n\t\t{\n\t\t\tIType newGenericType = genericType.ChangeNullability(nullability);\n\t\t\tif (newGenericType == genericType)\n\t\t\t\treturn this;\n\t\t\telse\n\t\t\t\treturn new ParameterizedType(newGenericType, typeArguments);\n\t\t}\n\n\t\tpublic IType DeclaringType {\n\t\t\tget {\n\t\t\t\tIType declaringType = genericType.DeclaringType;\n\t\t\t\tif (declaringType != null && declaringType.TypeParameterCount > 0\n\t\t\t\t\t&& declaringType.TypeParameterCount <= genericType.TypeParameterCount)\n\t\t\t\t{\n\t\t\t\t\tIType[] newTypeArgs = new IType[declaringType.TypeParameterCount];\n\t\t\t\t\tArray.Copy(this.typeArguments, 0, newTypeArgs, 0, newTypeArgs.Length);\n\t\t\t\t\treturn new ParameterizedType(declaringType, newTypeArgs);\n\t\t\t\t}\n\t\t\t\treturn declaringType;\n\t\t\t}\n\t\t}\n\n\t\tpublic int TypeParameterCount {\n\t\t\tget { return typeArguments.Length; }\n\t\t}\n\n\t\tpublic string FullName {\n\t\t\tget { return genericType.FullName; }\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget { return genericType.Name; }\n\t\t}\n\n\t\tpublic string Namespace {\n\t\t\tget { return genericType.Namespace; }\n\t\t}\n\n\t\tpublic string ReflectionName {\n\t\t\tget {\n\t\t\t\tStringBuilder b = new StringBuilder(genericType.ReflectionName);\n\t\t\t\tb.Append('[');\n\t\t\t\tfor (int i = 0; i < typeArguments.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\tb.Append(',');\n\t\t\t\t\tb.Append('[');\n\t\t\t\t\tb.Append(typeArguments[i].ReflectionName);\n\t\t\t\t\tb.Append(']');\n\t\t\t\t}\n\t\t\t\tb.Append(']');\n\t\t\t\treturn b.ToString();\n\t\t\t}\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tStringBuilder b = new StringBuilder(genericType.ToString());\n\t\t\tb.Append('[');\n\t\t\tfor (int i = 0; i < typeArguments.Length; i++)\n\t\t\t{\n\t\t\t\tif (i > 0)\n\t\t\t\t\tb.Append(',');\n\t\t\t\tb.Append('[');\n\t\t\t\tb.Append(typeArguments[i].ToString());\n\t\t\t\tb.Append(']');\n\t\t\t}\n\t\t\tb.Append(']');\n\t\t\treturn b.ToString();\n\t\t}\n\n\t\tpublic IReadOnlyList<IType> TypeArguments => typeArguments;\n\n\t\t/// <summary>\n\t\t/// Same as 'parameterizedType.TypeArguments[index]'.\n\t\t/// </summary>\n\t\tpublic IType GetTypeArgument(int index)\n\t\t{\n\t\t\treturn typeArguments[index];\n\t\t}\n\n\t\tpublic IReadOnlyList<ITypeParameter> TypeParameters => genericType.TypeParameters;\n\n\t\t/// <summary>\n\t\t/// Gets the definition of the generic type.\n\t\t/// For <c>ParameterizedType</c>, this method never returns null.\n\t\t/// </summary>\n\t\tpublic ITypeDefinition GetDefinition()\n\t\t{\n\t\t\treturn genericType.GetDefinition();\n\t\t}\n\n\t\tpublic ITypeDefinitionOrUnknown GetDefinitionOrUnknown()\n\t\t{\n\t\t\treturn genericType.GetDefinitionOrUnknown();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a type visitor that performs the substitution of class type parameters with the type arguments\n\t\t/// of this parameterized type.\n\t\t/// </summary>\n\t\tpublic TypeParameterSubstitution GetSubstitution()\n\t\t{\n\t\t\treturn new TypeParameterSubstitution(typeArguments, null);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a type visitor that performs the substitution of class type parameters with the type arguments\n\t\t/// of this parameterized type,\n\t\t/// and also substitutes method type parameters with the specified method type arguments.\n\t\t/// </summary>\n\t\tpublic TypeParameterSubstitution GetSubstitution(IReadOnlyList<IType> methodTypeArguments)\n\t\t{\n\t\t\treturn new TypeParameterSubstitution(typeArguments, methodTypeArguments);\n\t\t}\n\n\t\tpublic IEnumerable<IType> DirectBaseTypes {\n\t\t\tget {\n\t\t\t\tvar substitution = GetSubstitution();\n\t\t\t\treturn genericType.DirectBaseTypes.Select(t => t.AcceptVisitor(substitution));\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable<IType> GetNestedTypes(Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)\n\t\t\t\treturn genericType.GetNestedTypes(filter, options);\n\t\t\telse\n\t\t\t\treturn GetMembersHelper.GetNestedTypes(this, filter, options);\n\t\t}\n\n\t\tpublic IEnumerable<IType> GetNestedTypes(IReadOnlyList<IType> typeArguments, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)\n\t\t\t\treturn genericType.GetNestedTypes(typeArguments, filter, options);\n\t\t\telse\n\t\t\t\treturn GetMembersHelper.GetNestedTypes(this, typeArguments, filter, options);\n\t\t}\n\n\t\tpublic IEnumerable<IMethod> GetConstructors(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)\n\t\t\t\treturn genericType.GetConstructors(filter, options);\n\t\t\telse\n\t\t\t\treturn GetMembersHelper.GetConstructors(this, filter, options);\n\t\t}\n\n\t\tpublic IEnumerable<IMethod> GetMethods(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)\n\t\t\t\treturn genericType.GetMethods(filter, options);\n\t\t\telse\n\t\t\t\treturn GetMembersHelper.GetMethods(this, filter, options);\n\t\t}\n\n\t\tpublic IEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)\n\t\t\t\treturn genericType.GetMethods(typeArguments, filter, options);\n\t\t\telse\n\t\t\t\treturn GetMembersHelper.GetMethods(this, typeArguments, filter, options);\n\t\t}\n\n\t\tpublic IEnumerable<IProperty> GetProperties(Predicate<IProperty> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)\n\t\t\t\treturn genericType.GetProperties(filter, options);\n\t\t\telse\n\t\t\t\treturn GetMembersHelper.GetProperties(this, filter, options);\n\t\t}\n\n\t\tpublic IEnumerable<IField> GetFields(Predicate<IField> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)\n\t\t\t\treturn genericType.GetFields(filter, options);\n\t\t\telse\n\t\t\t\treturn GetMembersHelper.GetFields(this, filter, options);\n\t\t}\n\n\t\tpublic IEnumerable<IEvent> GetEvents(Predicate<IEvent> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)\n\t\t\t\treturn genericType.GetEvents(filter, options);\n\t\t\telse\n\t\t\t\treturn GetMembersHelper.GetEvents(this, filter, options);\n\t\t}\n\n\t\tpublic IEnumerable<IMember> GetMembers(Predicate<IMember> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)\n\t\t\t\treturn genericType.GetMembers(filter, options);\n\t\t\telse\n\t\t\t\treturn GetMembersHelper.GetMembers(this, filter, options);\n\t\t}\n\n\t\tpublic IEnumerable<IMethod> GetAccessors(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\tif ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)\n\t\t\t\treturn genericType.GetAccessors(filter, options);\n\t\t\telse\n\t\t\t\treturn GetMembersHelper.GetAccessors(this, filter, options);\n\t\t}\n\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\treturn Equals(obj as IType);\n\t\t}\n\n\t\tpublic bool Equals(IType other)\n\t\t{\n\t\t\tif (this == other)\n\t\t\t\treturn true;\n\t\t\tParameterizedType c = other as ParameterizedType;\n\t\t\tif (c == null || !genericType.Equals(c.genericType) || typeArguments.Length != c.typeArguments.Length)\n\t\t\t\treturn false;\n\t\t\tfor (int i = 0; i < typeArguments.Length; i++)\n\t\t\t{\n\t\t\t\tif (!typeArguments[i].Equals(c.typeArguments[i]))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\tint hashCode = genericType.GetHashCode();\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\tforeach (var ta in typeArguments)\n\t\t\t\t{\n\t\t\t\t\thashCode *= 1000000007;\n\t\t\t\t\thashCode += 1000000009 * ta.GetHashCode();\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn hashCode;\n\t\t}\n\n\t\tpublic IType AcceptVisitor(TypeVisitor visitor)\n\t\t{\n\t\t\treturn visitor.VisitParameterizedType(this);\n\t\t}\n\n\t\tpublic IType VisitChildren(TypeVisitor visitor)\n\t\t{\n\t\t\tIType g = genericType.AcceptVisitor(visitor);\n\t\t\t// Keep ta == null as long as no elements changed, allocate the array only if necessary.\n\t\t\tIType[] ta = (g != genericType) ? new IType[typeArguments.Length] : null;\n\t\t\tfor (int i = 0; i < typeArguments.Length; i++)\n\t\t\t{\n\t\t\t\tIType r = typeArguments[i].AcceptVisitor(visitor);\n\t\t\t\tif (r == null)\n\t\t\t\t\tthrow new NullReferenceException(\"TypeVisitor.Visit-method returned null\");\n\t\t\t\tif (ta == null && r != typeArguments[i])\n\t\t\t\t{\n\t\t\t\t\t// we found a difference, so we need to allocate the array\n\t\t\t\t\tta = new IType[typeArguments.Length];\n\t\t\t\t\tfor (int j = 0; j < i; j++)\n\t\t\t\t\t{\n\t\t\t\t\t\tta[j] = typeArguments[j];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (ta != null)\n\t\t\t\t\tta[i] = r;\n\t\t\t}\n\t\t\tif (ta == null)\n\t\t\t\treturn this;\n\t\t\telse\n\t\t\t\treturn new ParameterizedType(g, ta);\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// ParameterizedTypeReference is a reference to generic class that specifies the type parameters.\n\t/// Example: List&lt;string&gt;\n\t/// </summary>\n\t[Serializable]\n\tpublic sealed class ParameterizedTypeReference : ITypeReference, ISupportsInterning\n\t{\n\t\treadonly ITypeReference genericType;\n\t\treadonly ITypeReference[] typeArguments;\n\n\t\tpublic ParameterizedTypeReference(ITypeReference genericType, IEnumerable<ITypeReference> typeArguments)\n\t\t{\n\t\t\tif (genericType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(genericType));\n\t\t\tif (typeArguments == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(typeArguments));\n\t\t\tthis.genericType = genericType;\n\t\t\tthis.typeArguments = typeArguments.ToArray();\n\t\t\tfor (int i = 0; i < this.typeArguments.Length; i++)\n\t\t\t{\n\t\t\t\tif (this.typeArguments[i] == null)\n\t\t\t\t\tthrow new ArgumentNullException(\"typeArguments[\" + i + \"]\");\n\t\t\t}\n\t\t}\n\n\t\tpublic ITypeReference GenericType {\n\t\t\tget { return genericType; }\n\t\t}\n\n\t\tpublic IReadOnlyList<ITypeReference> TypeArguments {\n\t\t\tget {\n\t\t\t\treturn typeArguments;\n\t\t\t}\n\t\t}\n\n\t\tpublic IType Resolve(ITypeResolveContext context)\n\t\t{\n\t\t\tIType baseType = genericType.Resolve(context);\n\t\t\tint tpc = baseType.TypeParameterCount;\n\t\t\tif (tpc == 0)\n\t\t\t\treturn baseType;\n\t\t\tIType[] resolvedTypes = new IType[tpc];\n\t\t\tfor (int i = 0; i < resolvedTypes.Length; i++)\n\t\t\t{\n\t\t\t\tif (i < typeArguments.Length)\n\t\t\t\t\tresolvedTypes[i] = typeArguments[i].Resolve(context);\n\t\t\t\telse\n\t\t\t\t\tresolvedTypes[i] = SpecialType.UnknownType;\n\t\t\t}\n\t\t\treturn new ParameterizedType(baseType, resolvedTypes);\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tStringBuilder b = new StringBuilder(genericType.ToString());\n\t\t\tb.Append('[');\n\t\t\tfor (int i = 0; i < typeArguments.Length; i++)\n\t\t\t{\n\t\t\t\tif (i > 0)\n\t\t\t\t\tb.Append(',');\n\t\t\t\tb.Append('[');\n\t\t\t\tb.Append(typeArguments[i].ToString());\n\t\t\t\tb.Append(']');\n\t\t\t}\n\t\t\tb.Append(']');\n\t\t\treturn b.ToString();\n\t\t}\n\n\t\tint ISupportsInterning.GetHashCodeForInterning()\n\t\t{\n\t\t\tint hashCode = genericType.GetHashCode();\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\tforeach (ITypeReference t in typeArguments)\n\t\t\t\t{\n\t\t\t\t\thashCode *= 27;\n\t\t\t\t\thashCode += t.GetHashCode();\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn hashCode;\n\t\t}\n\n\t\tbool ISupportsInterning.EqualsForInterning(ISupportsInterning other)\n\t\t{\n\t\t\tParameterizedTypeReference o = other as ParameterizedTypeReference;\n\t\t\tif (o != null && genericType == o.genericType && typeArguments.Length == o.typeArguments.Length)\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < typeArguments.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tif (typeArguments[i] != o.typeArguments[i])\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/PointerType.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\tpublic sealed class PointerType : TypeWithElementType\n\t{\n\t\tpublic PointerType(IType elementType) : base(elementType)\n\t\t{\n\t\t}\n\n\t\tpublic override TypeKind Kind {\n\t\t\tget { return TypeKind.Pointer; }\n\t\t}\n\n\t\tpublic override string NameSuffix {\n\t\t\tget {\n\t\t\t\treturn \"*\";\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool? IsReferenceType {\n\t\t\tget { return null; }\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn elementType.GetHashCode() ^ 91725811;\n\t\t}\n\n\t\tpublic override bool Equals(IType other)\n\t\t{\n\t\t\tPointerType a = other as PointerType;\n\t\t\treturn a != null && elementType.Equals(a.elementType);\n\t\t}\n\n\t\tpublic override IType AcceptVisitor(TypeVisitor visitor)\n\t\t{\n\t\t\treturn visitor.VisitPointerType(this);\n\t\t}\n\n\t\tpublic override IType VisitChildren(TypeVisitor visitor)\n\t\t{\n\t\t\tIType e = elementType.AcceptVisitor(visitor);\n\t\t\tif (e == elementType)\n\t\t\t\treturn this;\n\t\t\telse\n\t\t\t\treturn new PointerType(e);\n\t\t}\n\t}\n\n\t[Serializable]\n\tpublic sealed class PointerTypeReference : ITypeReference, ISupportsInterning\n\t{\n\t\treadonly ITypeReference elementType;\n\n\t\tpublic PointerTypeReference(ITypeReference elementType)\n\t\t{\n\t\t\tif (elementType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(elementType));\n\t\t\tthis.elementType = elementType;\n\t\t}\n\n\t\tpublic ITypeReference ElementType {\n\t\t\tget { return elementType; }\n\t\t}\n\n\t\tpublic IType Resolve(ITypeResolveContext context)\n\t\t{\n\t\t\treturn new PointerType(elementType.Resolve(context));\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn elementType.ToString() + \"*\";\n\t\t}\n\n\t\tint ISupportsInterning.GetHashCodeForInterning()\n\t\t{\n\t\t\treturn elementType.GetHashCode() ^ 91725812;\n\t\t}\n\n\t\tbool ISupportsInterning.EqualsForInterning(ISupportsInterning other)\n\t\t{\n\t\t\tPointerTypeReference o = other as PointerTypeReference;\n\t\t\treturn o != null && this.elementType == o.elementType;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/ReferenceResolvingException.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Represents an error while resolving a reference to a type or a member.\n\t/// </summary>\n\t[Serializable]\n\tpublic class ReferenceResolvingException : Exception\n\t{\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"ReferenceResolvingException\"/> class\n\t\t/// </summary>\n\t\tpublic ReferenceResolvingException()\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"ReferenceResolvingException\"/> class\n\t\t/// </summary>\n\t\t/// <param name=\"message\">A <see cref=\"T:System.String\"/> that describes the error. The content of message is intended to be understood by humans. The caller of this constructor is required to ensure that this string has been localized for the current system culture.</param>\n\t\tpublic ReferenceResolvingException(string message)\n\t\t\t: base(message)\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"ReferenceResolvingException\"/> class\n\t\t/// </summary>\n\t\t/// <param name=\"message\">A <see cref=\"T:System.String\"/> that describes the error. The content of message is intended to be understood by humans. The caller of this constructor is required to ensure that this string has been localized for the current system culture.</param>\n\t\t/// <param name=\"inner\">The exception that is the cause of the current exception. If the innerException parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception.</param>\n\t\tpublic ReferenceResolvingException(string message, Exception inner)\n\t\t\t: base(message, inner)\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Initializes a new instance of the <see cref=\"ReferenceResolvingException\"/> class\n\t\t/// </summary>\n\t\t/// <param name=\"info\">The object that holds the serialized object data.</param>\n\t\t/// <param name=\"context\">The contextual information about the source or destination.</param>\n\t\tprotected ReferenceResolvingException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)\n\t\t\t: base(info, context)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/ReflectionHelper.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Static helper methods for reflection names.\n\t/// </summary>\n\tpublic static class ReflectionHelper\n\t{\n\t\t#region ICompilation.FindType\n\t\t/// <summary>\n\t\t/// Retrieves the specified type in this compilation.\n\t\t/// Returns <see cref=\"SpecialType.UnknownType\"/> if the type cannot be found in this compilation.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This method cannot be used with open types; all type parameters will be substituted\n\t\t/// with <see cref=\"SpecialType.UnknownType\"/>.\n\t\t/// </remarks>\n\t\tpublic static IType FindType(this ICompilation compilation, Type type)\n\t\t{\n\t\t\treturn ParseReflectionName(type.AssemblyQualifiedName, new SimpleTypeResolveContext(compilation));\n\t\t}\n\n\t\tpublic static IType FindType(this ICompilation compilation, StackType stackType, Sign sign = Sign.None)\n\t\t{\n\t\t\tswitch (stackType)\n\t\t\t{\n\t\t\t\tcase StackType.Unknown:\n\t\t\t\t\treturn SpecialType.UnknownType;\n\t\t\t\tcase StackType.Ref:\n\t\t\t\t\treturn new ByReferenceType(SpecialType.UnknownType);\n\t\t\t\tdefault:\n\t\t\t\t\treturn compilation.FindType(stackType.ToKnownTypeCode(sign));\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region SplitTypeParameterCountFromReflectionName\n\t\t/// <summary>\n\t\t/// Removes the ` with type parameter count from the reflection name.\n\t\t/// </summary>\n\t\t/// <remarks>Do not use this method with the full name of inner classes.</remarks>\n\t\tpublic static string SplitTypeParameterCountFromReflectionName(string reflectionName)\n\t\t{\n\t\t\tint pos = reflectionName.LastIndexOf('`');\n\t\t\tif (pos < 0)\n\t\t\t{\n\t\t\t\treturn reflectionName;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn reflectionName.Substring(0, pos);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Removes the ` with type parameter count from the reflection name.\n\t\t/// </summary>\n\t\t/// <remarks>Do not use this method with the full name of inner classes.</remarks>\n\t\tpublic static string SplitTypeParameterCountFromReflectionName(string reflectionName, out int typeParameterCount)\n\t\t{\n\t\t\tint pos = reflectionName.LastIndexOf('`');\n\t\t\tif (pos < 0)\n\t\t\t{\n\t\t\t\ttypeParameterCount = 0;\n\t\t\t\treturn reflectionName;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tstring typeCount = reflectionName.Substring(pos + 1);\n\t\t\t\tif (int.TryParse(typeCount, out typeParameterCount))\n\t\t\t\t\treturn reflectionName.Substring(0, pos);\n\t\t\t\telse\n\t\t\t\t\treturn reflectionName;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region TypeCode support\n\t\t/// <summary>\n\t\t/// Retrieves a built-in type using the specified type code.\n\t\t/// </summary>\n\t\tpublic static IType FindType(this ICompilation compilation, TypeCode typeCode)\n\t\t{\n\t\t\treturn compilation.FindType((KnownTypeCode)typeCode);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the type code for the specified type, or TypeCode.Empty if none of the other type codes match.\n\t\t/// </summary>\n\t\tpublic static TypeCode GetTypeCode(this IType type)\n\t\t{\n\t\t\tITypeDefinition def = type as ITypeDefinition;\n\t\t\tif (def != null)\n\t\t\t{\n\t\t\t\tKnownTypeCode typeCode = def.KnownTypeCode;\n\t\t\t\tif (typeCode <= KnownTypeCode.String && typeCode != KnownTypeCode.Void)\n\t\t\t\t\treturn (TypeCode)typeCode;\n\t\t\t\telse\n\t\t\t\t\treturn TypeCode.Empty;\n\t\t\t}\n\t\t\treturn TypeCode.Empty;\n\t\t}\n\t\t#endregion\n\n\t\t#region ParseReflectionName\n\t\t/// <summary>\n\t\t/// Parses a reflection name into a type reference.\n\t\t/// </summary>\n\t\t/// <param name=\"reflectionTypeName\">The reflection name of the type.</param>\n\t\t/// <returns>A type reference that represents the reflection name.</returns>\n\t\t/// <exception cref=\"ReflectionNameParseException\">The syntax of the reflection type name is invalid</exception>\n\t\t/// <remarks>\n\t\t/// If the type is open (contains type parameters '`0' or '``0'),\n\t\t/// an <see cref=\"ITypeResolveContext\"/> with the appropriate CurrentTypeDefinition/CurrentMember is required\n\t\t/// to resolve the reference to the ITypeParameter.\n\t\t/// For looking up closed, assembly qualified type names, the root type resolve context for the compilation\n\t\t/// is sufficient.\n\t\t/// When looking up a type name that isn't assembly qualified, the type reference will look in\n\t\t/// <see cref=\"ITypeResolveContext.CurrentModule\"/> first, and if the type is not found there,\n\t\t/// it will look in all other assemblies of the compilation.\n\t\t/// </remarks>\n\t\t/// <seealso cref=\"FullTypeName(string)\"/>\n\t\tpublic static IType ParseReflectionName(string reflectionTypeName, ITypeResolveContext resolveContext)\n\t\t{\n\t\t\tif (reflectionTypeName == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(reflectionTypeName));\n\t\t\tif (!TypeName.TryParse(reflectionTypeName.AsSpan(), out var result))\n\t\t\t{\n\t\t\t\tthrow new ReflectionNameParseException(0, \"Invalid type name: \" + reflectionTypeName);\n\t\t\t}\n\t\t\treturn ResolveTypeName(result, resolveContext);\n\t\t}\n\n\t\tprivate static IType ResolveTypeName(TypeName result, ITypeResolveContext resolveContext)\n\t\t{\n\t\t\tif (result.IsArray)\n\t\t\t{\n\t\t\t\treturn new ArrayType(\n\t\t\t\t\tresolveContext.Compilation,\n\t\t\t\t\tResolveTypeName(result.GetElementType(), resolveContext),\n\t\t\t\t\tresult.GetArrayRank()\n\t\t\t\t);\n\t\t\t}\n\t\t\telse if (result.IsByRef)\n\t\t\t{\n\t\t\t\treturn new ByReferenceType(\n\t\t\t\t\tResolveTypeName(result.GetElementType(), resolveContext)\n\t\t\t\t);\n\t\t\t}\n\t\t\telse if (result.IsConstructedGenericType)\n\t\t\t{\n\t\t\t\tIType genericType = ResolveTypeName(result.GetGenericTypeDefinition(), resolveContext);\n\t\t\t\tvar genericArgs = result.GetGenericArguments();\n\t\t\t\tif (genericType.TypeParameterCount == 0)\n\t\t\t\t{\n\t\t\t\t\treturn genericType;\n\t\t\t\t}\n\n\t\t\t\tIType[] resolvedTypes = new IType[genericType.TypeParameterCount];\n\t\t\t\tfor (int i = 0; i < genericArgs.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tif (i < genericArgs.Length)\n\t\t\t\t\t\tresolvedTypes[i] = ResolveTypeName(genericArgs[i], resolveContext);\n\t\t\t\t\telse\n\t\t\t\t\t\tresolvedTypes[i] = SpecialType.UnknownType;\n\t\t\t\t}\n\t\t\t\treturn new ParameterizedType(genericType, resolvedTypes);\n\t\t\t}\n\t\t\telse if (result.IsNested)\n\t\t\t{\n\t\t\t\tvar declaringType = ResolveTypeName(result.DeclaringType, resolveContext).GetDefinition();\n\t\t\t\tvar plainName = SplitTypeParameterCountFromReflectionName(result.Name, out int tpc);\n\t\t\t\tif (declaringType != null)\n\t\t\t\t{\n\t\t\t\t\tforeach (var type in declaringType.NestedTypes)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (type.Name == plainName && type.TypeParameterCount == tpc + declaringType.TypeParameterCount)\n\t\t\t\t\t\t\treturn type;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn new UnknownType(new FullTypeName(result.FullName));\n\t\t\t}\n\t\t\telse if (result.IsPointer)\n\t\t\t{\n\t\t\t\treturn new PointerType(\n\t\t\t\t\tResolveTypeName(result.GetElementType(), resolveContext)\n\t\t\t\t);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDebug.Assert(result.IsSimple);\n\t\t\t\tif (result.FullName.Length > 1 && result.FullName[0] == '`')\n\t\t\t\t{\n\t\t\t\t\tif (result.FullName.Length > 2 && result.FullName[1] == '`')\n\t\t\t\t\t{\n\t\t\t\t\t\tif (int.TryParse(result.FullName.Substring(2), out int index))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (resolveContext.CurrentMember is IMethod m && index < m.TypeParameters.Count)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn m.TypeParameters[index];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn DummyTypeParameter.GetMethodTypeParameter(index);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (int.TryParse(result.FullName.Substring(1), out int index))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (resolveContext.CurrentTypeDefinition != null && index < resolveContext.CurrentTypeDefinition.TypeParameterCount)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn resolveContext.CurrentTypeDefinition.TypeParameters[index];\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn DummyTypeParameter.GetClassTypeParameter(index);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvar topLevelTypeName = new TopLevelTypeName(result.FullName);\n\t\t\t\tif (result.AssemblyName != null)\n\t\t\t\t{\n\t\t\t\t\tvar module = resolveContext.Compilation.FindModuleByAssemblyNameInfo(result.AssemblyName);\n\t\t\t\t\tif (module != null)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn (IType)module.GetTypeDefinition(topLevelTypeName) ?? new UnknownType(topLevelTypeName);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tforeach (var module in resolveContext.Compilation.Modules)\n\t\t\t\t{\n\t\t\t\t\tvar type = module.GetTypeDefinition(topLevelTypeName);\n\t\t\t\t\tif (type != null)\n\t\t\t\t\t\treturn type;\n\t\t\t\t}\n\n\t\t\t\treturn new UnknownType(topLevelTypeName);\n\t\t\t}\n\t\t}\n\n\t\tinternal static int ReadTypeParameterCount(string reflectionTypeName, ref int pos)\n\t\t{\n\t\t\tint startPos = pos;\n\t\t\twhile (pos < reflectionTypeName.Length)\n\t\t\t{\n\t\t\t\tchar c = reflectionTypeName[pos];\n\t\t\t\tif (c < '0' || c > '9')\n\t\t\t\t\tbreak;\n\t\t\t\tpos++;\n\t\t\t}\n\t\t\tint tpc;\n\t\t\tif (!int.TryParse(reflectionTypeName.Substring(startPos, pos - startPos), out tpc))\n\t\t\t\tthrow new ReflectionNameParseException(pos, \"Expected type parameter count\");\n\t\t\treturn tpc;\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/ReflectionNameParseException.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Runtime.Serialization;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Represents an error while parsing a reflection name.\n\t/// </summary>\n\t[Serializable]\n\tpublic class ReflectionNameParseException : Exception\n\t{\n\t\tint position;\n\n\t\tpublic int Position {\n\t\t\tget { return position; }\n\t\t}\n\n\t\tpublic ReflectionNameParseException(int position)\n\t\t{\n\t\t\tthis.position = position;\n\t\t}\n\n\t\tpublic ReflectionNameParseException(int position, string message) : base(message)\n\t\t{\n\t\t\tthis.position = position;\n\t\t}\n\n\t\tpublic ReflectionNameParseException(int position, string message, Exception innerException) : base(message, innerException)\n\t\t{\n\t\t\tthis.position = position;\n\t\t}\n\n\t\t// This constructor is needed for serialization.\n\t\tprotected ReflectionNameParseException(SerializationInfo info, StreamingContext context) : base(info, context)\n\t\t{\n\t\t\tposition = info.GetInt32(\"position\");\n\t\t}\n\n\t\tpublic override void GetObjectData(SerializationInfo info, StreamingContext context)\n\t\t{\n\t\t\tbase.GetObjectData(info, context);\n\t\t\tinfo.AddValue(\"position\", position);\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/SimpleTypeResolveContext.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Default ITypeResolveContext implementation.\n\t/// </summary>\n\tpublic class SimpleTypeResolveContext : ITypeResolveContext\n\t{\n\t\treadonly ICompilation compilation;\n\t\treadonly IModule currentModule;\n\t\treadonly ITypeDefinition currentTypeDefinition;\n\t\treadonly IMember currentMember;\n\n\t\tpublic SimpleTypeResolveContext(ICompilation compilation)\n\t\t{\n\t\t\tif (compilation == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(compilation));\n\t\t\tthis.compilation = compilation;\n\t\t}\n\n\t\tpublic SimpleTypeResolveContext(IModule module)\n\t\t{\n\t\t\tif (module == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(module));\n\t\t\tthis.compilation = module.Compilation;\n\t\t\tthis.currentModule = module;\n\t\t}\n\n\t\tpublic SimpleTypeResolveContext(IEntity entity)\n\t\t{\n\t\t\tif (entity == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(entity));\n\t\t\tthis.compilation = entity.Compilation;\n\t\t\tthis.currentModule = entity.ParentModule;\n\t\t\tthis.currentTypeDefinition = (entity as ITypeDefinition) ?? entity.DeclaringTypeDefinition;\n\t\t\tthis.currentMember = entity as IMember;\n\t\t}\n\n\t\tprivate SimpleTypeResolveContext(ICompilation compilation, IModule currentModule, ITypeDefinition currentTypeDefinition, IMember currentMember)\n\t\t{\n\t\t\tthis.compilation = compilation;\n\t\t\tthis.currentModule = currentModule;\n\t\t\tthis.currentTypeDefinition = currentTypeDefinition;\n\t\t\tthis.currentMember = currentMember;\n\t\t}\n\n\t\tpublic ICompilation Compilation {\n\t\t\tget { return compilation; }\n\t\t}\n\n\t\tpublic IModule CurrentModule {\n\t\t\tget { return currentModule; }\n\t\t}\n\n\t\tpublic ITypeDefinition CurrentTypeDefinition {\n\t\t\tget { return currentTypeDefinition; }\n\t\t}\n\n\t\tpublic IMember CurrentMember {\n\t\t\tget { return currentMember; }\n\t\t}\n\n\t\tpublic ITypeResolveContext WithCurrentTypeDefinition(ITypeDefinition typeDefinition)\n\t\t{\n\t\t\treturn new SimpleTypeResolveContext(compilation, currentModule, typeDefinition, currentMember);\n\t\t}\n\n\t\tpublic ITypeResolveContext WithCurrentMember(IMember member)\n\t\t{\n\t\t\treturn new SimpleTypeResolveContext(compilation, currentModule, currentTypeDefinition, member);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/SpecialType.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Contains static implementations of special types.\n\t/// </summary>\n\t[Serializable]\n\tpublic sealed class SpecialType : AbstractType, ITypeReference\n\t{\n\t\t/// <summary>\n\t\t/// Gets the type representing resolve errors.\n\t\t/// </summary>\n\t\tpublic readonly static SpecialType UnknownType = new SpecialType(TypeKind.Unknown, \"?\", isReferenceType: null);\n\n\t\t/// <summary>\n\t\t/// The null type is used as type of the null literal. It is a reference type without any members; and it is a subtype of all reference types.\n\t\t/// </summary>\n\t\tpublic readonly static SpecialType NullType = new SpecialType(TypeKind.Null, \"null\", isReferenceType: true);\n\n\t\t/// <summary>\n\t\t/// Used for expressions without type, e.g. method groups or lambdas.\n\t\t/// </summary>\n\t\tpublic readonly static SpecialType NoType = new SpecialType(TypeKind.None, \"?\", isReferenceType: null);\n\n\t\t/// <summary>\n\t\t/// Type representing the C# 'dynamic' type.\n\t\t/// </summary>\n\t\tpublic readonly static SpecialType Dynamic = new SpecialType(TypeKind.Dynamic, \"dynamic\", isReferenceType: true);\n\n\t\t/// <summary>\n\t\t/// Type representing the C# 9 'nint' type.\n\t\t/// </summary>\n\t\tpublic readonly static SpecialType NInt = new SpecialType(TypeKind.NInt, \"nint\", isReferenceType: false);\n\n\t\t/// <summary>\n\t\t/// Type representing the C# 9 'nuint' type.\n\t\t/// </summary>\n\t\tpublic readonly static SpecialType NUInt = new SpecialType(TypeKind.NUInt, \"nuint\", isReferenceType: false);\n\n\t\t/// <summary>\n\t\t/// Type representing the result of the C# '__arglist()' expression.\n\t\t/// </summary>\n\t\tpublic readonly static SpecialType ArgList = new SpecialType(TypeKind.ArgList, \"__arglist\", isReferenceType: null);\n\n\t\t/// <summary>\n\t\t/// A type used for unbound type arguments in partially parameterized types.\n\t\t/// </summary>\n\t\t/// <see cref=\"IType.GetNestedTypes(Predicate{ITypeDefinition}, GetMemberOptions)\"/>\n\t\tpublic readonly static SpecialType UnboundTypeArgument = new SpecialType(TypeKind.UnboundTypeArgument, \"\", isReferenceType: null);\n\n\t\treadonly TypeKind kind;\n\t\treadonly string name;\n\t\treadonly bool? isReferenceType;\n\n\t\tprivate SpecialType(TypeKind kind, string name, bool? isReferenceType)\n\t\t{\n\t\t\tthis.kind = kind;\n\t\t\tthis.name = name;\n\t\t\tthis.isReferenceType = isReferenceType;\n\t\t}\n\n\t\tpublic override string Name {\n\t\t\tget { return name; }\n\t\t}\n\n\t\tpublic override TypeKind Kind {\n\t\t\tget { return kind; }\n\t\t}\n\n\t\tpublic override bool? IsReferenceType {\n\t\t\tget { return isReferenceType; }\n\t\t}\n\n\t\tIType ITypeReference.Resolve(ITypeResolveContext context)\n\t\t{\n\t\t\tif (context == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(context));\n\t\t\treturn this;\n\t\t}\n\n#pragma warning disable 809\n\t\t[Obsolete(\"Please compare special types using the kind property instead.\")]\n\t\tpublic override bool Equals(IType other)\n\t\t{\n\t\t\t// We consider a special types equal when they have equal types.\n\t\t\t// However, an unknown type with additional information is not considered to be equal to the SpecialType with TypeKind.Unknown.\n\t\t\treturn other is SpecialType && other.Kind == kind;\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn 81625621 ^ (int)kind;\n\t\t}\n\n\t\tpublic override IType ChangeNullability(Nullability nullability)\n\t\t{\n\t\t\tif (nullability == base.Nullability || Kind is not TypeKind.Dynamic)\n\t\t\t\treturn this;\n\t\t\telse\n\t\t\t\treturn new NullabilityAnnotatedType(this, nullability);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/TaskType.cs",
    "content": "// Copyright (c) 2010-2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Helper class for dealing with System.Threading.Tasks.Task.\n\t/// </summary>\n\tpublic static class TaskType\n\t{\n\t\t/// <summary>\n\t\t/// Gets the T in Task&lt;T&gt;.\n\t\t/// Returns void for non-generic Task.\n\t\t/// Any other type is returned unmodified.\n\t\t/// </summary>\n\t\tpublic static IType UnpackTask(ICompilation compilation, IType type)\n\t\t{\n\t\t\tif (!IsTask(type))\n\t\t\t\treturn type;\n\t\t\tif (type.TypeParameterCount == 0)\n\t\t\t\treturn compilation.FindType(KnownTypeCode.Void);\n\t\t\telse\n\t\t\t\treturn type.TypeArguments[0];\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the specified type is Task or Task&lt;T&gt;.\n\t\t/// </summary>\n\t\tpublic static bool IsTask(IType type)\n\t\t{\n\t\t\tITypeDefinition def = type.GetDefinition();\n\t\t\tif (def != null)\n\t\t\t{\n\t\t\t\tif (def.KnownTypeCode == KnownTypeCode.Task)\n\t\t\t\t\treturn true;\n\t\t\t\tif (def.KnownTypeCode == KnownTypeCode.TaskOfT)\n\t\t\t\t\treturn type is ParameterizedType;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the specified type is a Task-like type.\n\t\t/// </summary>\n\t\tpublic static bool IsCustomTask(IType type, out IType builderType)\n\t\t{\n\t\t\tbuilderType = null;\n\t\t\tITypeDefinition def = type.GetDefinition();\n\t\t\tif (def != null)\n\t\t\t{\n\t\t\t\tif (def.TypeParameterCount > 1)\n\t\t\t\t\treturn false;\n\t\t\t\tvar attribute = def.GetAttribute(KnownAttribute.AsyncMethodBuilder);\n\t\t\t\tif (attribute == null || attribute.FixedArguments.Length != 1)\n\t\t\t\t\treturn false;\n\t\t\t\tvar arg = attribute.FixedArguments[0];\n\t\t\t\tif (!arg.Type.IsKnownType(KnownTypeCode.Type))\n\t\t\t\t\treturn false;\n\t\t\t\tbuilderType = (IType)arg.Value;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tconst string ns = \"System.Runtime.CompilerServices\";\n\n\t\t/// <summary>\n\t\t/// Gets whether the specified type is a non-generic Task-like type.\n\t\t/// </summary>\n\t\t/// <param name=\"builderTypeName\">Returns the full type-name of the builder type, if successful.</param>\n\t\tpublic static bool IsNonGenericTaskType(IType task, out FullTypeName builderTypeName)\n\t\t{\n\t\t\tif (task.IsKnownType(KnownTypeCode.Task))\n\t\t\t{\n\t\t\t\tbuilderTypeName = new TopLevelTypeName(ns, \"AsyncTaskMethodBuilder\");\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (IsCustomTask(task, out var builderType))\n\t\t\t{\n\t\t\t\tbuilderTypeName = new FullTypeName(builderType.ReflectionName);\n\t\t\t\treturn builderTypeName.TypeParameterCount == 0;\n\t\t\t}\n\t\t\tbuilderTypeName = default;\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the specified type is a generic Task-like type.\n\t\t/// </summary>\n\t\t/// <param name=\"builderTypeName\">Returns the full type-name of the builder type, if successful.</param>\n\t\tpublic static bool IsGenericTaskType(IType task, out FullTypeName builderTypeName)\n\t\t{\n\t\t\tif (task.IsKnownType(KnownTypeCode.TaskOfT))\n\t\t\t{\n\t\t\t\tbuilderTypeName = new TopLevelTypeName(ns, \"AsyncTaskMethodBuilder\", 1);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (IsCustomTask(task, out var builderType))\n\t\t\t{\n\t\t\t\tbuilderTypeName = new FullTypeName(builderType.ReflectionName);\n\t\t\t\treturn builderTypeName.TypeParameterCount == 1;\n\t\t\t}\n\t\t\tbuilderTypeName = default;\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a task type.\n\t\t/// </summary>\n\t\tpublic static IType Create(ICompilation compilation, IType elementType)\n\t\t{\n\t\t\tif (compilation == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(compilation));\n\t\t\tif (elementType == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(elementType));\n\n\t\t\tif (elementType.Kind == TypeKind.Void)\n\t\t\t\treturn compilation.FindType(KnownTypeCode.Task);\n\t\t\tIType taskType = compilation.FindType(KnownTypeCode.TaskOfT);\n\t\t\tITypeDefinition taskTypeDef = taskType.GetDefinition();\n\t\t\tif (taskTypeDef != null)\n\t\t\t\treturn new ParameterizedType(taskTypeDef, new[] { elementType });\n\t\t\telse\n\t\t\t\treturn taskType;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/TopLevelTypeName.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Holds the name of a top-level type.\n\t/// This struct cannot refer to nested classes.\n\t/// </summary>\n\t[Serializable]\n\tpublic readonly struct TopLevelTypeName : IEquatable<TopLevelTypeName>\n\t{\n\t\treadonly string namespaceName;\n\t\treadonly string name;\n\t\treadonly int typeParameterCount;\n\n\t\tpublic TopLevelTypeName(string namespaceName, string name, int typeParameterCount = 0)\n\t\t{\n\t\t\tif (namespaceName == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(namespaceName));\n\t\t\tif (name == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(name));\n\t\t\tthis.namespaceName = namespaceName;\n\t\t\tthis.name = name;\n\t\t\tthis.typeParameterCount = typeParameterCount;\n\t\t}\n\n\t\tpublic TopLevelTypeName(string reflectionName)\n\t\t{\n\t\t\tint pos = reflectionName.LastIndexOf('.');\n\t\t\tif (pos < 0)\n\t\t\t{\n\t\t\t\tnamespaceName = string.Empty;\n\t\t\t\tname = reflectionName;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tnamespaceName = reflectionName.Substring(0, pos);\n\t\t\t\tname = reflectionName.Substring(pos + 1);\n\t\t\t}\n\t\t\tname = ReflectionHelper.SplitTypeParameterCountFromReflectionName(name, out typeParameterCount);\n\t\t}\n\n\t\tpublic string Namespace {\n\t\t\tget { return namespaceName; }\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget { return name; }\n\t\t}\n\n\t\tpublic int TypeParameterCount {\n\t\t\tget { return typeParameterCount; }\n\t\t}\n\n\t\tpublic string ReflectionName {\n\t\t\tget {\n\t\t\t\tStringBuilder b = new StringBuilder();\n\t\t\t\tif (!string.IsNullOrEmpty(namespaceName))\n\t\t\t\t{\n\t\t\t\t\tb.Append(namespaceName);\n\t\t\t\t\tb.Append('.');\n\t\t\t\t}\n\t\t\t\tb.Append(name);\n\t\t\t\tif (typeParameterCount > 0)\n\t\t\t\t{\n\t\t\t\t\tb.Append('`');\n\t\t\t\t\tb.Append(typeParameterCount);\n\t\t\t\t}\n\t\t\t\treturn b.ToString();\n\t\t\t}\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn this.ReflectionName;\n\t\t}\n\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\treturn (obj is TopLevelTypeName) && Equals((TopLevelTypeName)obj);\n\t\t}\n\n\t\tpublic bool Equals(TopLevelTypeName other)\n\t\t{\n\t\t\treturn this.namespaceName == other.namespaceName && this.name == other.name && this.typeParameterCount == other.typeParameterCount;\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn (name != null ? name.GetHashCode() : 0) ^ (namespaceName != null ? namespaceName.GetHashCode() : 0) ^ typeParameterCount;\n\t\t}\n\n\t\tpublic static bool operator ==(TopLevelTypeName lhs, TopLevelTypeName rhs)\n\t\t{\n\t\t\treturn lhs.Equals(rhs);\n\t\t}\n\n\t\tpublic static bool operator !=(TopLevelTypeName lhs, TopLevelTypeName rhs)\n\t\t{\n\t\t\treturn !lhs.Equals(rhs);\n\t\t}\n\t}\n\n\t[Serializable]\n\tpublic sealed class TopLevelTypeNameComparer : IEqualityComparer<TopLevelTypeName>\n\t{\n\t\tpublic static readonly TopLevelTypeNameComparer Ordinal = new TopLevelTypeNameComparer(StringComparer.Ordinal);\n\t\tpublic static readonly TopLevelTypeNameComparer OrdinalIgnoreCase = new TopLevelTypeNameComparer(StringComparer.OrdinalIgnoreCase);\n\n\t\tpublic readonly StringComparer NameComparer;\n\n\t\tpublic TopLevelTypeNameComparer(StringComparer nameComparer)\n\t\t{\n\t\t\tthis.NameComparer = nameComparer;\n\t\t}\n\n\t\tpublic bool Equals(TopLevelTypeName x, TopLevelTypeName y)\n\t\t{\n\t\t\treturn x.TypeParameterCount == y.TypeParameterCount\n\t\t\t\t&& NameComparer.Equals(x.Name, y.Name)\n\t\t\t\t&& NameComparer.Equals(x.Namespace, y.Namespace);\n\t\t}\n\n\t\tpublic int GetHashCode(TopLevelTypeName obj)\n\t\t{\n\t\t\treturn NameComparer.GetHashCode(obj.Name) ^ NameComparer.GetHashCode(obj.Namespace) ^ obj.TypeParameterCount;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/TupleType.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\tpublic sealed class TupleType : AbstractType, ICompilationProvider\n\t{\n\t\tpublic const int RestPosition = 8;\n\t\tconst int RestIndex = RestPosition - 1;\n\n\t\tpublic ICompilation Compilation { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the underlying <c>System.ValueType</c> type.\n\t\t/// </summary>\n\t\tpublic ParameterizedType UnderlyingType { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the tuple elements.\n\t\t/// </summary>\n\t\tpublic ImmutableArray<IType> ElementTypes { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the cardinality of the tuple.\n\t\t/// </summary>\n\t\tpublic int Cardinality => ElementTypes.Length;\n\n\t\t/// <summary>\n\t\t/// Gets the names of the tuple elements.\n\t\t/// </summary>\n\t\tpublic ImmutableArray<string> ElementNames { get; }\n\n\t\tpublic TupleType(ICompilation compilation, ImmutableArray<IType> elementTypes,\n\t\t\tImmutableArray<string> elementNames = default(ImmutableArray<string>),\n\t\t\tIModule valueTupleAssembly = null)\n\t\t{\n\t\t\tthis.Compilation = compilation;\n\t\t\tthis.UnderlyingType = CreateUnderlyingType(compilation, elementTypes, valueTupleAssembly);\n\t\t\tthis.ElementTypes = elementTypes;\n\t\t\tif (elementNames.IsDefault)\n\t\t\t{\n\t\t\t\tthis.ElementNames = Enumerable.Repeat<string>(null, elementTypes.Length).ToImmutableArray();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDebug.Assert(elementNames.Length == elementTypes.Length);\n\t\t\t\tthis.ElementNames = elementNames;\n\t\t\t}\n\t\t}\n\n\t\tstatic ParameterizedType CreateUnderlyingType(ICompilation compilation, ImmutableArray<IType> elementTypes, IModule valueTupleAssembly)\n\t\t{\n\t\t\tint remainder = (elementTypes.Length - 1) % (RestPosition - 1) + 1;\n\t\t\tDebug.Assert(remainder >= 1 && remainder < RestPosition);\n\t\t\tint pos = elementTypes.Length - remainder;\n\t\t\tvar type = new ParameterizedType(\n\t\t\t\tFindValueTupleType(compilation, valueTupleAssembly, remainder),\n\t\t\t\telementTypes.Slice(pos));\n\t\t\twhile (pos > 0)\n\t\t\t{\n\t\t\t\tpos -= (RestPosition - 1);\n\t\t\t\ttype = new ParameterizedType(\n\t\t\t\t\tFindValueTupleType(compilation, valueTupleAssembly, RestPosition),\n\t\t\t\t\telementTypes.Slice(pos, RestPosition - 1).Concat(new[] { type }));\n\t\t\t}\n\t\t\tDebug.Assert(pos == 0);\n\t\t\treturn type;\n\t\t}\n\n\t\tprivate static IType FindValueTupleType(ICompilation compilation, IModule valueTupleAssembly, int tpc)\n\t\t{\n\t\t\tvar typeName = new TopLevelTypeName(\"System\", \"ValueTuple\", tpc);\n\t\t\tif (valueTupleAssembly != null)\n\t\t\t{\n\t\t\t\tvar typeDef = valueTupleAssembly.GetTypeDefinition(typeName);\n\t\t\t\tif (typeDef != null)\n\t\t\t\t\treturn typeDef;\n\t\t\t}\n\t\t\treturn compilation.FindType(typeName);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the specified type is a valid underlying type for a tuple.\n\t\t/// Also returns true for tuple types themselves.\n\t\t/// </summary>\n\t\tpublic static bool IsTupleCompatible(IType type, out int tupleCardinality)\n\t\t{\n\t\t\tswitch (type.Kind)\n\t\t\t{\n\t\t\t\tcase TypeKind.Tuple:\n\t\t\t\t\ttupleCardinality = ((TupleType)type).ElementTypes.Length;\n\t\t\t\t\treturn true;\n\t\t\t\tcase TypeKind.Class:\n\t\t\t\tcase TypeKind.Struct:\n\t\t\t\t\tif (type.Namespace == \"System\" && type.Name == \"ValueTuple\")\n\t\t\t\t\t{\n\t\t\t\t\t\tint tpc = type.TypeParameterCount;\n\t\t\t\t\t\tif (tpc > 0 && tpc < RestPosition)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttupleCardinality = tpc;\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (tpc == RestPosition && type is ParameterizedType pt)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (IsTupleCompatible(pt.TypeArguments[RestIndex], out tupleCardinality))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttupleCardinality += RestPosition - 1;\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\ttupleCardinality = 0;\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Construct a tuple type (without element names) from the given underlying type.\n\t\t/// Returns null if the input is not a valid underlying type.\n\t\t/// </summary>\n\t\tpublic static TupleType FromUnderlyingType(ICompilation compilation, IType type)\n\t\t{\n\t\t\tvar elementTypes = GetTupleElementTypes(type);\n\t\t\tif (elementTypes.Length > 0)\n\t\t\t{\n\t\t\t\treturn new TupleType(\n\t\t\t\t\tcompilation,\n\t\t\t\t\telementTypes,\n\t\t\t\t\tvalueTupleAssembly: type.GetDefinition()?.ParentModule\n\t\t\t\t);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the tuple element types from a tuple type or tuple underlying type.\n\t\t/// </summary>\n\t\tpublic static ImmutableArray<IType> GetTupleElementTypes(IType tupleType)\n\t\t{\n\t\t\tList<IType> output = null;\n\t\t\tif (Collect(tupleType))\n\t\t\t{\n\t\t\t\treturn output.ToImmutableArray();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn default(ImmutableArray<IType>);\n\t\t\t}\n\n\t\t\tbool Collect(IType type)\n\t\t\t{\n\t\t\t\tswitch (type.Kind)\n\t\t\t\t{\n\t\t\t\t\tcase TypeKind.Tuple:\n\t\t\t\t\t\tif (output == null)\n\t\t\t\t\t\t\toutput = new List<IType>();\n\t\t\t\t\t\toutput.AddRange(((TupleType)type).ElementTypes);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tcase TypeKind.Class:\n\t\t\t\t\tcase TypeKind.Struct:\n\t\t\t\t\t\tif (type.Namespace == \"System\" && type.Name == \"ValueTuple\")\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (output == null)\n\t\t\t\t\t\t\t\toutput = new List<IType>();\n\t\t\t\t\t\t\tint tpc = type.TypeParameterCount;\n\t\t\t\t\t\t\tif (tpc > 0 && tpc < RestPosition)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutput.AddRange(type.TypeArguments);\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (tpc == RestPosition)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutput.AddRange(type.TypeArguments.Take(RestPosition - 1));\n\t\t\t\t\t\t\t\treturn Collect(type.TypeArguments[RestIndex]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic override TypeKind Kind => TypeKind.Tuple;\n\t\tpublic override bool? IsReferenceType => UnderlyingType.IsReferenceType;\n\t\tpublic override int TypeParameterCount => 0;\n\t\tpublic override IReadOnlyList<ITypeParameter> TypeParameters => EmptyList<ITypeParameter>.Instance;\n\t\tpublic override IReadOnlyList<IType> TypeArguments => EmptyList<IType>.Instance;\n\t\tpublic override IEnumerable<IType> DirectBaseTypes => UnderlyingType.DirectBaseTypes;\n\t\tpublic override string FullName => UnderlyingType.FullName;\n\t\tpublic override string Name => UnderlyingType.Name;\n\t\tpublic override string ReflectionName => UnderlyingType.ReflectionName;\n\t\tpublic override string Namespace => UnderlyingType.Namespace;\n\n\t\tpublic override bool Equals(IType other)\n\t\t{\n\t\t\tvar o = other as TupleType;\n\t\t\tif (o == null)\n\t\t\t\treturn false;\n\t\t\tif (!UnderlyingType.Equals(o.UnderlyingType))\n\t\t\t\treturn false;\n\t\t\treturn UnderlyingType.Equals(o.UnderlyingType)\n\t\t\t\t&& ElementNames.SequenceEqual(o.ElementNames);\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\tint hash = UnderlyingType.GetHashCode();\n\t\t\t\tforeach (string name in ElementNames)\n\t\t\t\t{\n\t\t\t\t\thash *= 31;\n\t\t\t\t\thash += name != null ? name.GetHashCode() : 0;\n\t\t\t\t}\n\t\t\t\treturn hash;\n\t\t\t}\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tStringBuilder b = new StringBuilder();\n\t\t\tb.Append('(');\n\t\t\tfor (int i = 0; i < ElementTypes.Length; i++)\n\t\t\t{\n\t\t\t\tif (i > 0)\n\t\t\t\t\tb.Append(\", \");\n\t\t\t\tb.Append(ElementTypes[i]);\n\t\t\t\tif (ElementNames[i] != null)\n\t\t\t\t{\n\t\t\t\t\tb.Append(' ');\n\t\t\t\t\tb.Append(ElementNames[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tb.Append(')');\n\t\t\treturn b.ToString();\n\t\t}\n\n\t\tpublic override IType AcceptVisitor(TypeVisitor visitor)\n\t\t{\n\t\t\treturn visitor.VisitTupleType(this);\n\t\t}\n\n\t\tpublic override IType VisitChildren(TypeVisitor visitor)\n\t\t{\n\t\t\tIType[] newElementTypes = null;\n\t\t\tfor (int i = 0; i < ElementTypes.Length; i++)\n\t\t\t{\n\t\t\t\tIType type = ElementTypes[i];\n\t\t\t\tvar newType = type.AcceptVisitor(visitor);\n\t\t\t\tif (newType != type)\n\t\t\t\t{\n\t\t\t\t\tif (newElementTypes == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tnewElementTypes = ElementTypes.ToArray();\n\t\t\t\t\t}\n\t\t\t\t\tnewElementTypes[i] = newType;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (newElementTypes != null)\n\t\t\t{\n\t\t\t\treturn new TupleType(this.Compilation, newElementTypes.ToImmutableArray(), this.ElementNames,\n\t\t\t\t\tthis.GetDefinition()?.ParentModule);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}\n\n\t\tpublic override IEnumerable<IMethod> GetAccessors(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn UnderlyingType.GetAccessors(filter, options);\n\t\t}\n\n\t\tpublic override IEnumerable<IMethod> GetConstructors(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers)\n\t\t{\n\t\t\t// CS8181 'new' cannot be used with tuple type. Use a tuple literal expression instead.\n\t\t\treturn EmptyList<IMethod>.Instance;\n\t\t}\n\n\t\tpublic override ITypeDefinition GetDefinition()\n\t\t{\n\t\t\treturn UnderlyingType.GetDefinition();\n\t\t}\n\n\t\tpublic override ITypeDefinitionOrUnknown GetDefinitionOrUnknown()\n\t\t{\n\t\t\treturn UnderlyingType.GetDefinitionOrUnknown();\n\t\t}\n\n\t\tpublic override IEnumerable<IEvent> GetEvents(Predicate<IEvent> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn UnderlyingType.GetEvents(filter, options);\n\t\t}\n\n\t\tpublic override IEnumerable<IField> GetFields(Predicate<IField> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\t// The fields from the underlying type (Item1..Item7 and Rest)\n\t\t\tforeach (var field in UnderlyingType.GetFields(filter, options))\n\t\t\t{\n\t\t\t\tyield return field;\n\t\t\t}\n\t\t\t/*for (int i = 0; i < ElementTypes.Length; i++) {\n\t\t\t\tvar type = ElementTypes[i];\n\t\t\t\tvar name = ElementNames[i];\n\t\t\t\tint pos = i + 1;\n\t\t\t\tstring itemName = \"Item\" + pos;\n\t\t\t\tif (name != itemName && name != null)\n\t\t\t\t\tyield return MakeField(type, name);\n\t\t\t\tif (pos >= RestPosition)\n\t\t\t\t\tyield return MakeField(type, itemName);\n\t\t\t}*/\n\t\t}\n\n\t\t/*private IField MakeField(IType type, string name)\n\t\t{\n\t\t\tvar f = new DefaultUnresolvedField();\n\t\t\tf.ReturnType = SpecialType.UnknownType;\n\t\t\tf.Name = name;\n\t\t\treturn new TupleElementField(f, Compilation.TypeResolveContext);\n\t\t}*/\n\n\t\tpublic override IEnumerable<IMethod> GetMethods(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn UnderlyingType.GetMethods(filter, options);\n\t\t}\n\n\t\tpublic override IEnumerable<IMethod> GetMethods(IReadOnlyList<IType> typeArguments, Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn UnderlyingType.GetMethods(typeArguments, filter, options);\n\t\t}\n\n\t\tpublic override IEnumerable<IType> GetNestedTypes(Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn UnderlyingType.GetNestedTypes(filter, options);\n\t\t}\n\n\t\tpublic override IEnumerable<IType> GetNestedTypes(IReadOnlyList<IType> typeArguments, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn UnderlyingType.GetNestedTypes(typeArguments, filter, options);\n\t\t}\n\n\t\tpublic override IEnumerable<IProperty> GetProperties(Predicate<IProperty> filter = null, GetMemberOptions options = GetMemberOptions.None)\n\t\t{\n\t\t\treturn UnderlyingType.GetProperties(filter, options);\n\t\t}\n\t}\n\n\tpublic static class TupleTypeExtensions\n\t{\n\t\tpublic static IType TupleUnderlyingTypeOrSelf(this IType type)\n\t\t{\n\t\t\tvar t = (type as TupleType)?.UnderlyingType ?? type;\n\t\t\treturn t.WithoutNullability();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/TypeKind.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// .\n\t/// </summary>\n\tpublic enum TypeKind : byte\n\t{\n\t\t/// <summary>Language-specific type that is not part of NRefactory.TypeSystem itself.</summary>\n\t\tOther,\n\n\t\t/// <summary>A <see cref=\"ITypeDefinition\"/> or <see cref=\"ParameterizedType\"/> that is a class.</summary>\n\t\tClass,\n\t\t/// <summary>A <see cref=\"ITypeDefinition\"/> or <see cref=\"ParameterizedType\"/> that is an interface.</summary>\n\t\tInterface,\n\t\t/// <summary>A <see cref=\"ITypeDefinition\"/> or <see cref=\"ParameterizedType\"/> that is a struct.</summary>\n\t\tStruct,\n\t\t/// <summary>A <see cref=\"ITypeDefinition\"/> or <see cref=\"ParameterizedType\"/> that is a delegate.</summary>\n\t\t/// <remarks><c>System.Delegate</c> itself is TypeKind.Class</remarks>\n\t\tDelegate,\n\t\t/// <summary>A <see cref=\"ITypeDefinition\"/> that is an enum.</summary>\n\t\t/// <remarks><c>System.Enum</c> itself is TypeKind.Class</remarks>\n\t\tEnum,\n\n\t\t/// <summary>The <c>System.Void</c> type.</summary>\n\t\t/// <see cref=\"KnownTypeCode.Void\"/>\n\t\tVoid,\n\n\t\t/// <summary>Type used for invalid expressions and for types whose definition could not be found.</summary>\n\t\t/// <see cref=\"SpecialType.UnknownType\"/>\n\t\tUnknown,\n\t\t/// <summary>The type of the null literal.</summary>\n\t\t/// <see cref=\"SpecialType.NullType\"/>\n\t\tNull,\n\t\t/// <summary>The type of expressions without type (except for null literals, which have <c>TypeKind.Null</c>).</summary>\n\t\t/// <see cref=\"SpecialType.NoType\"/>\n\t\tNone,\n\t\t/// <summary>Type representing the C# 'dynamic' type.</summary>\n\t\t/// <see cref=\"SpecialType.Dynamic\"/>\n\t\tDynamic,\n\t\t/// <summary>Represents missing type arguments in partially parameterized types.</summary>\n\t\t/// <see cref=\"SpecialType.UnboundTypeArgument\"/>\n\t\t/// <see cref=\"IType\">IType.GetNestedTypes(Predicate{ITypeDefinition}, GetMemberOptions)</see>\n\t\tUnboundTypeArgument,\n\n\t\t/// <summary>The type is a type parameter.</summary>\n\t\t/// <see cref=\"ITypeParameter\"/>\n\t\tTypeParameter,\n\n\t\t/// <summary>An array type</summary>\n\t\t/// <see cref=\"ArrayType\"/>\n\t\tArray,\n\t\t/// <summary>A pointer type</summary>\n\t\t/// <see cref=\"PointerType\"/>\n\t\tPointer,\n\t\t/// <summary>A managed reference type</summary>\n\t\t/// <see cref=\"ByReferenceType\"/>\n\t\tByReference,\n\n\t\t/// <summary>Intersection of several types</summary>\n\t\t/// <see cref=\"IntersectionType\"/>\n\t\tIntersection,\n\t\t/// <see cref=\"SpecialType.ArgList\"/>\n\t\tArgList,\n\t\t/// <summary>A C# 7 tuple type.\n\t\t/// E.g. <code>(string, int)</code>\n\t\t/// Note: <code>System.ValueTuple&lt;string, int&gt;</code> is not considered a tuple type.\n\t\t/// </summary>\n\t\t/// <see cref=\"TupleType\"/>\n\t\tTuple,\n\t\t/// <summary>\n\t\t/// Modified type, with optional modifier.\n\t\t/// </summary>\n\t\tModOpt,\n\t\t/// <summary>\n\t\t/// Modified type, with required modifier.\n\t\t/// </summary>\n\t\tModReq,\n\n\t\t/// <summary>\n\t\t/// C# 9 <c>nint</c>\n\t\t/// </summary>\n\t\tNInt,\n\t\t/// <summary>\n\t\t/// C# 9 <c>nuint</c>\n\t\t/// </summary>\n\t\tNUInt,\n\n\t\t/// <summary>\n\t\t/// C# 9 <c>delegate*</c>\n\t\t/// </summary>\n\t\tFunctionPointer,\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/TypeParameterSubstitution.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Substitutes class and method type parameters.\n\t/// </summary>\n\tpublic class TypeParameterSubstitution : TypeVisitor\n\t{\n\t\t/// <summary>\n\t\t/// The identity function.\n\t\t/// </summary>\n\t\tpublic static readonly TypeParameterSubstitution Identity = new TypeParameterSubstitution(null, null);\n\n\t\treadonly IReadOnlyList<IType> classTypeArguments;\n\t\treadonly IReadOnlyList<IType> methodTypeArguments;\n\n\t\t/// <summary>\n\t\t/// Creates a new type parameter substitution.\n\t\t/// </summary>\n\t\t/// <param name=\"classTypeArguments\">\n\t\t/// The type arguments to substitute for class type parameters.\n\t\t/// Pass <c>null</c> to keep class type parameters unmodified.\n\t\t/// </param>\n\t\t/// <param name=\"methodTypeArguments\">\n\t\t/// The type arguments to substitute for method type parameters.\n\t\t/// Pass <c>null</c> to keep method type parameters unmodified.\n\t\t/// </param>\n\t\tpublic TypeParameterSubstitution(IReadOnlyList<IType> classTypeArguments, IReadOnlyList<IType> methodTypeArguments)\n\t\t{\n\t\t\tthis.classTypeArguments = classTypeArguments;\n\t\t\tthis.methodTypeArguments = methodTypeArguments;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the list of class type arguments.\n\t\t/// Returns <c>null</c> if this substitution keeps class type parameters unmodified.\n\t\t/// </summary>\n\t\tpublic IReadOnlyList<IType> ClassTypeArguments {\n\t\t\tget { return classTypeArguments; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the list of method type arguments.\n\t\t/// Returns <c>null</c> if this substitution keeps method type parameters unmodified.\n\t\t/// </summary>\n\t\tpublic IReadOnlyList<IType> MethodTypeArguments {\n\t\t\tget { return methodTypeArguments; }\n\t\t}\n\n\t\t#region Compose\n\t\t/// <summary>\n\t\t/// Computes a single TypeParameterSubstitution so that for all types <c>t</c>:\n\t\t/// <c>t.AcceptVisitor(Compose(g, f)) equals t.AcceptVisitor(f).AcceptVisitor(g)</c>\n\t\t/// </summary>\n\t\t/// <remarks>If you consider type parameter substitution to be a function, this is function composition.</remarks>\n\t\tpublic static TypeParameterSubstitution Compose(TypeParameterSubstitution g, TypeParameterSubstitution f)\n\t\t{\n\t\t\tif (g == null)\n\t\t\t\treturn f;\n\t\t\tif (f == null || (f.classTypeArguments == null && f.methodTypeArguments == null))\n\t\t\t\treturn g;\n\t\t\t// The composition is a copy of 'f', with 'g' applied on the array elements.\n\t\t\t// If 'f' has a null list (keeps type parameters unmodified), we have to treat it as\n\t\t\t// the identity function, and thus use the list from 'g'.\n\t\t\tvar classTypeArguments = f.classTypeArguments != null ? GetComposedTypeArguments(f.classTypeArguments, g) : g.classTypeArguments;\n\t\t\tvar methodTypeArguments = f.methodTypeArguments != null ? GetComposedTypeArguments(f.methodTypeArguments, g) : g.methodTypeArguments;\n\t\t\treturn new TypeParameterSubstitution(classTypeArguments, methodTypeArguments);\n\t\t}\n\n\t\tstatic IReadOnlyList<IType> GetComposedTypeArguments(IReadOnlyList<IType> input, TypeParameterSubstitution substitution)\n\t\t{\n\t\t\tIType[] result = new IType[input.Count];\n\t\t\tfor (int i = 0; i < result.Length; i++)\n\t\t\t{\n\t\t\t\tresult[i] = input[i].AcceptVisitor(substitution);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t\t#endregion\n\n\t\t#region Equals and GetHashCode implementation\n\t\tpublic bool Equals(TypeParameterSubstitution other, TypeVisitor normalization)\n\t\t{\n\t\t\tif (other == null)\n\t\t\t\treturn false;\n\t\t\treturn TypeListEquals(classTypeArguments, other.classTypeArguments, normalization)\n\t\t\t\t&& TypeListEquals(methodTypeArguments, other.methodTypeArguments, normalization);\n\t\t}\n\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\tTypeParameterSubstitution other = obj as TypeParameterSubstitution;\n\t\t\tif (other == null)\n\t\t\t\treturn false;\n\t\t\treturn TypeListEquals(classTypeArguments, other.classTypeArguments)\n\t\t\t\t&& TypeListEquals(methodTypeArguments, other.methodTypeArguments);\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\treturn 1124131 * TypeListHashCode(classTypeArguments) + 1821779 * TypeListHashCode(methodTypeArguments);\n\t\t\t}\n\t\t}\n\n\t\tstatic bool TypeListEquals(IReadOnlyList<IType> a, IReadOnlyList<IType> b)\n\t\t{\n\t\t\tif (a == b)\n\t\t\t\treturn true;\n\t\t\tif (a == null || b == null)\n\t\t\t\treturn false;\n\t\t\tif (a.Count != b.Count)\n\t\t\t\treturn false;\n\t\t\tfor (int i = 0; i < a.Count; i++)\n\t\t\t{\n\t\t\t\tif (!a[i].Equals(b[i]))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic bool TypeListEquals(IReadOnlyList<IType> a, IReadOnlyList<IType> b, TypeVisitor normalization)\n\t\t{\n\t\t\tif (a == b)\n\t\t\t\treturn true;\n\t\t\tif (a == null || b == null)\n\t\t\t\treturn false;\n\t\t\tif (a.Count != b.Count)\n\t\t\t\treturn false;\n\t\t\tfor (int i = 0; i < a.Count; i++)\n\t\t\t{\n\t\t\t\tvar an = a[i].AcceptVisitor(normalization);\n\t\t\t\tvar bn = b[i].AcceptVisitor(normalization);\n\t\t\t\tif (!an.Equals(bn))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic int TypeListHashCode(IReadOnlyList<IType> obj)\n\t\t{\n\t\t\tif (obj == null)\n\t\t\t\treturn 0;\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\tint hashCode = 1;\n\t\t\t\tforeach (var element in obj)\n\t\t\t\t{\n\t\t\t\t\thashCode *= 27;\n\t\t\t\t\thashCode += element.GetHashCode();\n\t\t\t\t}\n\t\t\t\treturn hashCode;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tpublic override IType VisitTypeParameter(ITypeParameter type)\n\t\t{\n\t\t\tint index = type.Index;\n\t\t\tif (classTypeArguments != null && type.OwnerType == SymbolKind.TypeDefinition)\n\t\t\t{\n\t\t\t\tif (index >= 0 && index < classTypeArguments.Count)\n\t\t\t\t\treturn classTypeArguments[index];\n\t\t\t\telse\n\t\t\t\t\treturn SpecialType.UnknownType;\n\t\t\t}\n\t\t\telse if (methodTypeArguments != null && type.OwnerType == SymbolKind.Method)\n\t\t\t{\n\t\t\t\tif (index >= 0 && index < methodTypeArguments.Count)\n\t\t\t\t\treturn methodTypeArguments[index];\n\t\t\t\telse\n\t\t\t\t\treturn SpecialType.UnknownType;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn base.VisitTypeParameter(type);\n\t\t\t}\n\t\t}\n\n\t\tpublic override IType VisitNullabilityAnnotatedType(NullabilityAnnotatedType type)\n\t\t{\n\t\t\tif (type is NullabilityAnnotatedTypeParameter tp)\n\t\t\t{\n\t\t\t\tif (tp.Nullability == Nullability.Nullable)\n\t\t\t\t{\n\t\t\t\t\treturn VisitTypeParameter(tp).ChangeNullability(Nullability.Nullable);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// T! substituted with T=oblivious string should result in oblivious string\n\t\t\t\t\treturn VisitTypeParameter(tp);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn base.VisitNullabilityAnnotatedType(type);\n\t\t\t}\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tStringBuilder b = new StringBuilder();\n\t\t\tb.Append('[');\n\t\t\tbool first = true;\n\t\t\tif (classTypeArguments != null)\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < classTypeArguments.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (first)\n\t\t\t\t\t\tfirst = false;\n\t\t\t\t\telse\n\t\t\t\t\t\tb.Append(\", \");\n\t\t\t\t\tb.Append('`');\n\t\t\t\t\tb.Append(i);\n\t\t\t\t\tb.Append(\" -> \");\n\t\t\t\t\tb.Append(classTypeArguments[i].ReflectionName);\n\t\t\t\t}\n\t\t\t\tif (classTypeArguments.Count == 0)\n\t\t\t\t{\n\t\t\t\t\tif (first)\n\t\t\t\t\t\tfirst = false;\n\t\t\t\t\telse\n\t\t\t\t\t\tb.Append(\", \");\n\t\t\t\t\tb.Append(\"[]\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (methodTypeArguments != null)\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < methodTypeArguments.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (first)\n\t\t\t\t\t\tfirst = false;\n\t\t\t\t\telse\n\t\t\t\t\t\tb.Append(\", \");\n\t\t\t\t\tb.Append(\"``\");\n\t\t\t\t\tb.Append(i);\n\t\t\t\t\tb.Append(\" -> \");\n\t\t\t\t\tb.Append(methodTypeArguments[i].ReflectionName);\n\t\t\t\t}\n\t\t\t\tif (methodTypeArguments.Count == 0)\n\t\t\t\t{\n\t\t\t\t\tif (first)\n\t\t\t\t\t\tfirst = false;\n\t\t\t\t\telse\n\t\t\t\t\t\tb.Append(\", \");\n\t\t\t\t\tb.Append(\"[]\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tb.Append(']');\n\t\t\treturn b.ToString();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/TypeProvider.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Immutable;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nusing SRM = System.Reflection.Metadata;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Allows decoding signatures using decompiler types.\n\t/// </summary>\n\tsealed class TypeProvider : ICompilationProvider,\n\t\tSRM.ISignatureTypeProvider<IType, GenericContext>,\n\t\tSRM.ICustomAttributeTypeProvider<IType>\n\t{\n\t\treadonly MetadataModule module;\n\t\treadonly ICompilation compilation;\n\n\t\tpublic TypeProvider(MetadataModule module)\n\t\t{\n\t\t\tthis.module = module;\n\t\t\tthis.compilation = module.Compilation;\n\t\t}\n\n\t\tpublic TypeProvider(ICompilation compilation)\n\t\t{\n\t\t\tthis.compilation = compilation;\n\t\t}\n\n\t\tpublic ICompilation Compilation => compilation;\n\n\t\tpublic IType GetArrayType(IType elementType, SRM.ArrayShape shape)\n\t\t{\n\t\t\treturn new ArrayType(compilation, elementType, shape.Rank);\n\t\t}\n\n\t\tpublic IType GetByReferenceType(IType elementType)\n\t\t{\n\t\t\treturn new ByReferenceType(elementType);\n\t\t}\n\n\t\tpublic IType GetFunctionPointerType(SRM.MethodSignature<IType> signature)\n\t\t{\n\t\t\tif (signature.Header.IsInstance)\n\t\t\t{\n\t\t\t\t// pointers to member functions are not supported even in C# 9\n\t\t\t\treturn compilation.FindType(KnownTypeCode.IntPtr);\n\t\t\t}\n\t\t\treturn FunctionPointerType.FromSignature(signature, module);\n\t\t}\n\n\t\tpublic IType GetGenericInstantiation(IType genericType, ImmutableArray<IType> typeArguments)\n\t\t{\n\t\t\tint tpc = genericType.TypeParameterCount;\n\t\t\tif (tpc == 0 || tpc != typeArguments.Length)\n\t\t\t{\n\t\t\t\t// This can occur when the genericType is from another assembly,\n\t\t\t\t// doesn't have the typical `1 suffix, and that other assembly is not loaded.\n\t\t\t\treturn genericType;\n\t\t\t}\n\t\t\treturn new ParameterizedType(genericType, typeArguments);\n\t\t}\n\n\t\tpublic IType GetGenericMethodParameter(GenericContext genericContext, int index)\n\t\t{\n\t\t\treturn genericContext.GetMethodTypeParameter(index);\n\t\t}\n\n\t\tpublic IType GetGenericTypeParameter(GenericContext genericContext, int index)\n\t\t{\n\t\t\treturn genericContext.GetClassTypeParameter(index);\n\t\t}\n\n\t\tpublic IType GetModifiedType(IType modifier, IType unmodifiedType, bool isRequired)\n\t\t{\n\t\t\treturn new ModifiedType(modifier, unmodifiedType, isRequired);\n\t\t}\n\n\t\tpublic IType GetPinnedType(IType elementType)\n\t\t{\n\t\t\treturn new PinnedType(elementType);\n\t\t}\n\n\t\tpublic IType GetPointerType(IType elementType)\n\t\t{\n\t\t\treturn new PointerType(elementType);\n\t\t}\n\n\t\tpublic IType GetPrimitiveType(SRM.PrimitiveTypeCode typeCode)\n\t\t{\n\t\t\treturn compilation.FindType(typeCode.ToKnownTypeCode());\n\t\t}\n\n\t\tpublic IType GetSystemType()\n\t\t{\n\t\t\treturn compilation.FindType(KnownTypeCode.Type);\n\t\t}\n\n\t\tpublic IType GetSZArrayType(IType elementType)\n\t\t{\n\t\t\treturn new ArrayType(compilation, elementType);\n\t\t}\n\n\t\tbool? IsReferenceType(SRM.MetadataReader reader, SRM.EntityHandle handle, byte rawTypeKind)\n\t\t{\n\t\t\tswitch (reader.ResolveSignatureTypeKind(handle, rawTypeKind))\n\t\t\t{\n\t\t\t\tcase SRM.SignatureTypeKind.ValueType:\n\t\t\t\t\treturn false;\n\t\t\t\tcase SRM.SignatureTypeKind.Class:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tpublic IType GetTypeFromDefinition(SRM.MetadataReader reader, SRM.TypeDefinitionHandle handle, byte rawTypeKind)\n\t\t{\n\t\t\tITypeDefinition td = module?.GetDefinition(handle);\n\t\t\tif (td != null)\n\t\t\t\treturn td;\n\t\t\tbool? isReferenceType = IsReferenceType(reader, handle, rawTypeKind);\n\t\t\treturn new UnknownType(handle.GetFullTypeName(reader), isReferenceType);\n\t\t}\n\n\t\tpublic IType GetTypeFromReference(SRM.MetadataReader reader, SRM.TypeReferenceHandle handle, byte rawTypeKind)\n\t\t{\n\t\t\tIModule resolvedModule = module?.GetDeclaringModule(handle);\n\t\t\tvar fullTypeName = handle.GetFullTypeName(reader);\n\t\t\tIType type = null;\n\t\t\tif (resolvedModule != null)\n\t\t\t{\n\t\t\t\ttype = resolvedModule.GetTypeDefinition(fullTypeName);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tforeach (var asm in compilation.Modules)\n\t\t\t\t{\n\t\t\t\t\ttype = asm.GetTypeDefinition(fullTypeName);\n\t\t\t\t\tif (type != null)\n\t\t\t\t\t\treturn type;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn type ?? new UnknownType(fullTypeName, IsReferenceType(reader, handle, rawTypeKind));\n\t\t}\n\n\t\tpublic IType GetTypeFromSerializedName(string name)\n\t\t{\n\t\t\tif (name == null)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn ReflectionHelper.ParseReflectionName(name, module != null ? new SimpleTypeResolveContext(module) : new SimpleTypeResolveContext(compilation));\n\t\t\t}\n\t\t\tcatch (ReflectionNameParseException ex)\n\t\t\t{\n\t\t\t\tthrow new BadImageFormatException($\"Invalid type name: \\\"{name}\\\": {ex.Message}\");\n\t\t\t}\n\t\t}\n\n\t\tpublic IType GetTypeFromSpecification(SRM.MetadataReader reader, GenericContext genericContext, SRM.TypeSpecificationHandle handle, byte rawTypeKind)\n\t\t{\n\t\t\treturn reader.GetTypeSpecification(handle).DecodeSignature<IType, GenericContext>(this, genericContext);\n\t\t}\n\n\t\tpublic SRM.PrimitiveTypeCode GetUnderlyingEnumType(IType type)\n\t\t{\n\t\t\tvar def = type.GetEnumUnderlyingType().GetDefinition();\n\t\t\tif (def == null)\n\t\t\t\tthrow new EnumUnderlyingTypeResolveException();\n\t\t\treturn def.KnownTypeCode.ToPrimitiveTypeCode();\n\t\t}\n\n\t\tpublic bool IsSystemType(IType type)\n\t\t{\n\t\t\treturn type.IsKnownType(KnownTypeCode.Type);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Contains extension methods for the type system.\n\t/// </summary>\n\tpublic static class TypeSystemExtensions\n\t{\n\t\t#region GetAllBaseTypes\n\t\t/// <summary>\n\t\t/// Gets all base types.\n\t\t/// </summary>\n\t\t/// <remarks>This is the reflexive and transitive closure of <see cref=\"IType.DirectBaseTypes\"/>.\n\t\t/// Note that this method does not return all supertypes - doing so is impossible due to contravariance\n\t\t/// (and undesirable for covariance as the list could become very large).\n\t\t/// \n\t\t/// The output is ordered so that base types occur before derived types.\n\t\t/// </remarks>\n\t\tpublic static IEnumerable<IType> GetAllBaseTypes(this IType type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tBaseTypeCollector collector = new BaseTypeCollector();\n\t\t\tcollector.CollectBaseTypes(type);\n\t\t\treturn collector;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets all non-interface base types.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// When <paramref name=\"type\"/> is an interface, this method will also return base interfaces (return same output as GetAllBaseTypes()).\n\t\t/// \n\t\t/// The output is ordered so that base types occur before derived types.\n\t\t/// </remarks>\n\t\tpublic static IEnumerable<IType> GetNonInterfaceBaseTypes(this IType type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tBaseTypeCollector collector = new BaseTypeCollector();\n\t\t\tcollector.SkipImplementedInterfaces = true;\n\t\t\tcollector.CollectBaseTypes(type);\n\t\t\treturn collector;\n\t\t}\n\t\t#endregion\n\n\t\t#region GetAllBaseTypeDefinitions\n\t\t/// <summary>\n\t\t/// Gets all base type definitions.\n\t\t/// The output is ordered so that base types occur before derived types.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This is equivalent to type.GetAllBaseTypes().Select(t => t.GetDefinition()).Where(d => d != null).Distinct().\n\t\t/// </remarks>\n\t\tpublic static IEnumerable<ITypeDefinition> GetAllBaseTypeDefinitions(this IType type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\n\t\t\treturn type.GetAllBaseTypes().Select(t => t.GetDefinition()).Where(d => d != null).Distinct();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this type definition is derived from the base type definition.\n\t\t/// </summary>\n\t\tpublic static bool IsDerivedFrom(this ITypeDefinition type, ITypeDefinition baseType)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tif (baseType == null)\n\t\t\t\treturn false;\n\t\t\tif (type.Compilation != baseType.Compilation)\n\t\t\t{\n\t\t\t\tthrow new InvalidOperationException(\"Both arguments to IsDerivedFrom() must be from the same compilation.\");\n\t\t\t}\n\t\t\treturn type.GetAllBaseTypeDefinitions().Contains(baseType);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this type definition is derived from a given known type.\n\t\t/// </summary>\n\t\tpublic static bool IsDerivedFrom(this ITypeDefinition type, KnownTypeCode baseType)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tif (baseType == KnownTypeCode.None)\n\t\t\t\treturn false;\n\t\t\treturn IsDerivedFrom(type, type.Compilation.FindType(baseType).GetDefinition());\n\t\t}\n\t\t#endregion\n\n\t\t#region GetDeclaringTypeDefinitionsOrThis\n\t\t/// <summary>\n\t\t/// Returns all declaring type definitions of this type definition.\n\t\t/// The output is ordered so that inner types occur before outer types.\n\t\t/// </summary>\n\t\tpublic static IEnumerable<ITypeDefinition> GetDeclaringTypeDefinitions(this ITypeDefinition definition)\n\t\t{\n\t\t\tif (definition == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(definition));\n\t\t\t}\n\n\t\t\twhile (definition != null)\n\t\t\t{\n\t\t\t\tyield return definition;\n\t\t\t\tdefinition = definition.DeclaringTypeDefinition;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region IsOpen / IsUnbound / IsUnmanagedType / IsKnownType\n\t\tsealed class TypeClassificationVisitor : TypeVisitor\n\t\t{\n\t\t\tinternal bool isOpen;\n\t\t\tinternal IEntity typeParameterOwner;\n\t\t\tint typeParameterOwnerNestingLevel;\n\n\t\t\tpublic override IType VisitTypeParameter(ITypeParameter type)\n\t\t\t{\n\t\t\t\tisOpen = true;\n\t\t\t\t// If both classes and methods, or different classes (nested types)\n\t\t\t\t// are involved, find the most specific one\n\t\t\t\tint newNestingLevel = GetNestingLevel(type.Owner);\n\t\t\t\tif (newNestingLevel > typeParameterOwnerNestingLevel)\n\t\t\t\t{\n\t\t\t\t\ttypeParameterOwner = type.Owner;\n\t\t\t\t\ttypeParameterOwnerNestingLevel = newNestingLevel;\n\t\t\t\t}\n\t\t\t\treturn base.VisitTypeParameter(type);\n\t\t\t}\n\n\t\t\tstatic int GetNestingLevel(IEntity entity)\n\t\t\t{\n\t\t\t\tint level = 0;\n\t\t\t\twhile (entity != null)\n\t\t\t\t{\n\t\t\t\t\tlevel++;\n\t\t\t\t\tentity = entity.DeclaringTypeDefinition;\n\t\t\t\t}\n\t\t\t\treturn level;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the type is an open type (contains type parameters).\n\t\t/// </summary>\n\t\t/// <example>\n\t\t/// <code>\n\t\t/// class X&lt;T&gt; {\n\t\t///   List&lt;T&gt; open;\n\t\t///   X&lt;X&lt;T[]&gt;&gt; open;\n\t\t///   X&lt;string&gt; closed;\n\t\t///   int closed;\n\t\t/// }\n\t\t/// </code>\n\t\t/// </example>\n\t\tpublic static bool IsOpen(this IType type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tTypeClassificationVisitor v = new TypeClassificationVisitor();\n\t\t\ttype.AcceptVisitor(v);\n\t\t\treturn v.isOpen;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the entity that owns the type parameters occurring in the specified type.\n\t\t/// If both class and method type parameters are present, the method is returned.\n\t\t/// Returns null if the specified type is closed.\n\t\t/// </summary>\n\t\t/// <seealso cref=\"IsOpen\"/>\n\t\tstatic IEntity GetTypeParameterOwner(IType type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tTypeClassificationVisitor v = new TypeClassificationVisitor();\n\t\t\ttype.AcceptVisitor(v);\n\t\t\treturn v.typeParameterOwner;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the type is unbound (is a generic type, but no type arguments were provided).\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// In \"<c>typeof(List&lt;Dictionary&lt;,&gt;&gt;)</c>\", only the Dictionary is unbound, the List is considered\n\t\t/// bound despite containing an unbound type.\n\t\t/// This method returns false for partially parameterized types (<c>Dictionary&lt;string, &gt;</c>).\n\t\t/// </remarks>\n\t\tpublic static bool IsUnbound(this IType type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\treturn (type is ITypeDefinition || type is UnknownType) && type.TypeParameterCount > 0;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the type is considered unmanaged.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// The C# 6.0 spec lists the following criteria: An unmanaged type is one of the following\n\t\t/// * sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, or bool\n\t\t/// * any enum type\n\t\t/// * any pointer type\n\t\t/// * any user-defined struct type that is not a constructed (= generic) type and contains fields of unmanaged types only.\n\t\t/// \n\t\t/// C# 8.0 removes the restriction that constructed (= generic) types are not considered unmanaged types.\n\t\t/// </remarks>\n\t\tpublic static bool IsUnmanagedType(this IType type, bool allowGenerics)\n\t\t{\n\t\t\tHashSet<IType> types = null;\n\t\t\treturn IsUnmanagedTypeInternal(type);\n\n\t\t\tbool IsUnmanagedTypeInternal(IType type)\n\t\t\t{\n\t\t\t\tif (type.Kind is TypeKind.Enum or TypeKind.Pointer or TypeKind.FunctionPointer or TypeKind.NInt or TypeKind.NUInt)\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (type is ITypeParameter tp)\n\t\t\t\t{\n\t\t\t\t\treturn tp.HasUnmanagedConstraint;\n\t\t\t\t}\n\t\t\t\tvar def = type.GetDefinition();\n\t\t\t\tif (def == null)\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tswitch (def.KnownTypeCode)\n\t\t\t\t{\n\t\t\t\t\tcase KnownTypeCode.Void:\n\t\t\t\t\tcase KnownTypeCode.Boolean:\n\t\t\t\t\tcase KnownTypeCode.Char:\n\t\t\t\t\tcase KnownTypeCode.SByte:\n\t\t\t\t\tcase KnownTypeCode.Byte:\n\t\t\t\t\tcase KnownTypeCode.Int16:\n\t\t\t\t\tcase KnownTypeCode.UInt16:\n\t\t\t\t\tcase KnownTypeCode.Int32:\n\t\t\t\t\tcase KnownTypeCode.UInt32:\n\t\t\t\t\tcase KnownTypeCode.Int64:\n\t\t\t\t\tcase KnownTypeCode.UInt64:\n\t\t\t\t\tcase KnownTypeCode.Decimal:\n\t\t\t\t\tcase KnownTypeCode.Single:\n\t\t\t\t\tcase KnownTypeCode.Double:\n\t\t\t\t\tcase KnownTypeCode.IntPtr:\n\t\t\t\t\tcase KnownTypeCode.UIntPtr:\n\t\t\t\t\tcase KnownTypeCode.TypedReference:\n\t\t\t\t\t\t//case KnownTypeCode.ArgIterator:\n\t\t\t\t\t\t//case KnownTypeCode.RuntimeArgumentHandle:\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (type.Kind == TypeKind.Struct)\n\t\t\t\t{\n\t\t\t\t\tif (!allowGenerics && def.TypeParameterCount > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif (types == null)\n\t\t\t\t\t{\n\t\t\t\t\t\ttypes = new HashSet<IType>();\n\t\t\t\t\t}\n\t\t\t\t\ttypes.Add(type);\n\t\t\t\t\tforeach (var f in type.GetFields(f => !f.IsStatic))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (types.Contains(f.Type))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttypes.Remove(type);\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!IsUnmanagedTypeInternal(f.Type))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttypes.Remove(type);\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\ttypes.Remove(type);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic static bool IsArrayInterfaceType(this IType type)\n\t\t{\n\t\t\tif (type == null || type.TypeParameterCount != 1)\n\t\t\t\treturn false;\n\t\t\tswitch (type.GetDefinition()?.KnownTypeCode)\n\t\t\t{\n\t\t\t\tcase KnownTypeCode.IEnumerableOfT:\n\t\t\t\tcase KnownTypeCode.ICollectionOfT:\n\t\t\t\tcase KnownTypeCode.IListOfT:\n\t\t\t\tcase KnownTypeCode.IReadOnlyCollectionOfT:\n\t\t\t\tcase KnownTypeCode.IReadOnlyListOfT:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic static bool IsInlineArrayType(this IType type)\n\t\t{\n\t\t\tif (type.Kind != TypeKind.Struct)\n\t\t\t\treturn false;\n\t\t\tvar td = type.GetDefinition();\n\t\t\tif (td == null)\n\t\t\t\treturn false;\n\t\t\treturn td.HasAttribute(KnownAttribute.InlineArray);\n\t\t}\n\n\t\tpublic static int? GetInlineArrayLength(this IType type)\n\t\t{\n\t\t\tif (type.Kind != TypeKind.Struct)\n\t\t\t\treturn null;\n\t\t\tvar td = type.GetDefinition();\n\t\t\tif (td == null)\n\t\t\t\treturn null;\n\t\t\tvar attr = td.GetAttribute(KnownAttribute.InlineArray);\n\t\t\treturn attr?.FixedArguments.FirstOrDefault().Value as int?;\n\t\t}\n\n\t\tpublic static IType GetInlineArrayElementType(this IType arrayType)\n\t\t{\n\t\t\treturn arrayType?.GetFields(f => !f.IsStatic).SingleOrDefault()?.Type ?? SpecialType.UnknownType;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the type is the specified known type.\n\t\t/// For generic known types, this returns true for any parameterization of the type (and also for the definition itself).\n\t\t/// </summary>\n\t\tpublic static bool IsKnownType(this IType type, KnownTypeCode knownType)\n\t\t{\n\t\t\tvar def = type.GetDefinition();\n\t\t\treturn def != null && def.KnownTypeCode == knownType;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the type is the specified known type.\n\t\t/// For generic known types, this returns true for any parameterization of the type (and also for the definition itself).\n\t\t/// </summary>\n\t\tinternal static bool IsKnownType(this IType type, KnownAttribute knownType)\n\t\t{\n\t\t\tvar def = type.GetDefinition();\n\t\t\treturn def != null && def.FullTypeName.IsKnownType(knownType);\n\t\t}\n\n\t\tpublic static bool IsKnownType(this FullTypeName typeName, KnownTypeCode knownType)\n\t\t{\n\t\t\treturn typeName == KnownTypeReference.Get(knownType).TypeName;\n\t\t}\n\n\t\tpublic static bool IsKnownType(this TopLevelTypeName typeName, KnownTypeCode knownType)\n\t\t{\n\t\t\treturn typeName == KnownTypeReference.Get(knownType).TypeName;\n\t\t}\n\n\t\tinternal static bool IsKnownType(this FullTypeName typeName, KnownAttribute knownType)\n\t\t{\n\t\t\treturn typeName == knownType.GetTypeName();\n\t\t}\n\n\t\tinternal static bool IsKnownType(this TopLevelTypeName typeName, KnownAttribute knownType)\n\t\t{\n\t\t\treturn typeName == knownType.GetTypeName();\n\t\t}\n\t\t#endregion\n\n\t\t#region GetDelegateInvokeMethod\n\t\t/// <summary>\n\t\t/// Gets the invoke method for a delegate type.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Returns null if the type is not a delegate type; or if the invoke method could not be found.\n\t\t/// </remarks>\n\t\tpublic static IMethod GetDelegateInvokeMethod(this IType type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tif (type.Kind == TypeKind.Delegate)\n\t\t\t\treturn type.GetMethods(m => m.Name == \"Invoke\", GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault();\n\t\t\telse\n\t\t\t\treturn null;\n\t\t}\n\t\t#endregion\n\n\t\tpublic static IType SkipModifiers(this IType ty)\n\t\t{\n\t\t\twhile (ty is ModifiedType mt)\n\t\t\t{\n\t\t\t\tty = mt.ElementType;\n\t\t\t}\n\t\t\treturn ty;\n\t\t}\n\n\t\tpublic static IType UnwrapByRef(this IType type)\n\t\t{\n\t\t\tif (type is ByReferenceType byRef)\n\t\t\t{\n\t\t\t\ttype = byRef.ElementType;\n\t\t\t}\n\t\t\treturn type;\n\t\t}\n\n\t\tpublic static bool HasReadonlyModifier(this IMethod accessor)\n\t\t{\n\t\t\treturn accessor.ThisIsRefReadOnly && accessor.DeclaringTypeDefinition?.IsReadOnly == false;\n\t\t}\n\n\t\tpublic static bool IsAnyPointer(this TypeKind typeKind)\n\t\t{\n\t\t\treturn typeKind switch {\n\t\t\t\tTypeKind.Pointer => true,\n\t\t\t\tTypeKind.FunctionPointer => true,\n\t\t\t\t_ => false\n\t\t\t};\n\t\t}\n\n\t\t#region GetType/Member\n\t\t/// <summary>\n\t\t/// Gets all type definitions in the compilation.\n\t\t/// This may include types from referenced assemblies that are not accessible in the main assembly.\n\t\t/// </summary>\n\t\tpublic static IEnumerable<ITypeDefinition> GetAllTypeDefinitions(this ICompilation compilation)\n\t\t{\n\t\t\treturn compilation.Modules.SelectMany(a => a.TypeDefinitions);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets all top level type definitions in the compilation.\n\t\t/// This may include types from referenced assemblies that are not accessible in the main assembly.\n\t\t/// </summary>\n\t\tpublic static IEnumerable<ITypeDefinition> GetTopLevelTypeDefinitions(this ICompilation compilation)\n\t\t{\n\t\t\treturn compilation.Modules.SelectMany(a => a.TopLevelTypeDefinitions);\n\t\t}\n\t\t#endregion\n\n\t\t#region Resolve on collections\n\t\tpublic static IReadOnlyList<IType> Resolve(this IList<ITypeReference> typeReferences, ITypeResolveContext context)\n\t\t{\n\t\t\tif (typeReferences == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(typeReferences));\n\t\t\tif (typeReferences.Count == 0)\n\t\t\t\treturn EmptyList<IType>.Instance;\n\t\t\telse\n\t\t\t\treturn new ProjectedList<ITypeResolveContext, ITypeReference, IType>(context, typeReferences, (c, t) => t.Resolve(c));\n\t\t}\n\n\t\t// There is intentionally no Resolve() overload for IList<IMemberReference>: the resulting IList<Member> would\n\t\t// contains nulls when there are resolve errors.\n\t\t#endregion\n\n\t\t#region IAssembly.GetTypeDefinition()\n\t\t/// <summary>\n\t\t/// Retrieves the specified type in this compilation.\n\t\t/// Returns an <see cref=\"UnknownType\"/> if the type cannot be found in this compilation.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// There can be multiple types with the same full name in a compilation, as a\n\t\t/// full type name is only unique per assembly.\n\t\t/// If there are multiple possible matches, this method will return just one of them.\n\t\t/// When possible, use <see cref=\"IModule.GetTypeDefinition\"/> instead to\n\t\t/// retrieve a type from a specific assembly.\n\t\t/// </remarks>\n\t\tpublic static IType FindType(this ICompilation compilation, FullTypeName fullTypeName)\n\t\t{\n\t\t\tif (compilation == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(compilation));\n\t\t\tforeach (IModule asm in compilation.Modules)\n\t\t\t{\n\t\t\t\tITypeDefinition def = asm.GetTypeDefinition(fullTypeName);\n\t\t\t\tif (def != null)\n\t\t\t\t\treturn def;\n\t\t\t}\n\t\t\treturn new UnknownType(fullTypeName);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the type definition for the specified unresolved type.\n\t\t/// Returns null if the unresolved type does not belong to this assembly.\n\t\t/// </summary>\n\t\tpublic static ITypeDefinition GetTypeDefinition(this IModule module, FullTypeName fullTypeName)\n\t\t{\n\t\t\tif (module == null)\n\t\t\t\tthrow new ArgumentNullException(\"assembly\");\n\t\t\tTopLevelTypeName topLevelTypeName = fullTypeName.TopLevelTypeName;\n\t\t\tITypeDefinition typeDef = module.GetTypeDefinition(topLevelTypeName);\n\t\t\tif (typeDef == null)\n\t\t\t\treturn null;\n\t\t\tint typeParameterCount = topLevelTypeName.TypeParameterCount;\n\t\t\tfor (int i = 0; i < fullTypeName.NestingLevel; i++)\n\t\t\t{\n\t\t\t\tstring name = fullTypeName.GetNestedTypeName(i);\n\t\t\t\ttypeParameterCount += fullTypeName.GetNestedTypeAdditionalTypeParameterCount(i);\n\t\t\t\ttypeDef = FindNestedType(typeDef, name, typeParameterCount);\n\t\t\t\tif (typeDef == null)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn typeDef;\n\t\t}\n\n\t\tstatic ITypeDefinition FindNestedType(ITypeDefinition typeDef, string name, int typeParameterCount)\n\t\t{\n\t\t\tforeach (var nestedType in typeDef.NestedTypes)\n\t\t\t{\n\t\t\t\tif (nestedType.Name == name && nestedType.TypeParameterCount == typeParameterCount)\n\t\t\t\t\treturn nestedType;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\t#endregion\n\n\t\t#region IEntity.GetAttribute\n\t\t/// <summary>\n\t\t/// Gets whether the entity has an attribute of the specified attribute type.\n\t\t/// </summary>\n\t\t/// <param name=\"entity\">The entity on which the attributes are declared.</param>\n\t\t/// <param name=\"attributeType\">The attribute type to look for.</param>\n\t\t/// <param name=\"inherit\">\n\t\t/// Specifies whether attributes inherited from base classes and base members\n\t\t/// (if the given <paramref name=\"entity\"/> in an <c>override</c>)\n\t\t/// should be returned.\n\t\t/// </param>\n\t\tpublic static bool HasAttribute(this IEntity entity, KnownAttribute attributeType, bool inherit)\n\t\t{\n\t\t\tif (!inherit)\n\t\t\t\treturn entity.HasAttribute(attributeType);\n\n\t\t\treturn GetAttribute(entity, attributeType, inherit) != null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the attribute of the specified attribute type.\n\t\t/// </summary>\n\t\t/// <param name=\"entity\">The entity on which the attributes are declared.</param>\n\t\t/// <param name=\"attributeType\">The attribute type to look for.</param>\n\t\t/// <param name=\"inherit\">\n\t\t/// Specifies whether attributes inherited from base classes and base members\n\t\t/// (if the given <paramref name=\"entity\"/> in an <c>override</c>)\n\t\t/// should be returned.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// Returns the attribute that was found; or <c>null</c> if none was found.\n\t\t/// If inherit is true, an from the entity itself will be returned if possible;\n\t\t/// and the base entity will only be searched if none exists.\n\t\t/// </returns>\n\t\tpublic static IAttribute GetAttribute(this IEntity entity, KnownAttribute attributeType, bool inherit)\n\t\t{\n\t\t\tif (inherit)\n\t\t\t{\n\t\t\t\tif (entity is ITypeDefinition td)\n\t\t\t\t{\n\t\t\t\t\treturn InheritanceHelper.GetAttribute(td, attributeType);\n\t\t\t\t}\n\t\t\t\telse if (entity is IMember m)\n\t\t\t\t{\n\t\t\t\t\treturn InheritanceHelper.GetAttribute(m, attributeType);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthrow new NotSupportedException(\"Unknown entity type\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn entity.GetAttribute(attributeType);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the attributes on the entity.\n\t\t/// </summary>\n\t\t/// <param name=\"entity\">The entity on which the attributes are declared.</param>\n\t\t/// <param name=\"inherit\">\n\t\t/// Specifies whether attributes inherited from base classes and base members\n\t\t/// (if the given <paramref name=\"entity\"/> in an <c>override</c>)\n\t\t/// should be returned.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// Returns the list of attributes that were found.\n\t\t/// If inherit is true, attributes from the entity itself are returned first;\n\t\t/// followed by attributes inherited from the base entity.\n\t\t/// </returns>\n\t\tpublic static IEnumerable<IAttribute> GetAttributes(this IEntity entity, bool inherit)\n\t\t{\n\t\t\tif (inherit)\n\t\t\t{\n\t\t\t\tif (entity is ITypeDefinition td)\n\t\t\t\t{\n\t\t\t\t\treturn InheritanceHelper.GetAttributes(td);\n\t\t\t\t}\n\t\t\t\telse if (entity is IMember m)\n\t\t\t\t{\n\t\t\t\t\treturn InheritanceHelper.GetAttributes(m);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthrow new NotSupportedException(\"Unknown entity type\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn entity.GetAttributes();\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region IParameter.GetAttribute\n\t\t/// <summary>\n\t\t/// Gets whether the parameter has an attribute of the specified attribute type.\n\t\t/// </summary>\n\t\t/// <param name=\"parameter\">The parameter on which the attributes are declared.</param>\n\t\t/// <param name=\"attributeType\">The attribute type to look for.</param>\n\t\tpublic static bool HasAttribute(this IParameter parameter, KnownAttribute attributeType)\n\t\t{\n\t\t\treturn GetAttribute(parameter, attributeType) != null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the attribute of the specified attribute type.\n\t\t/// </summary>\n\t\t/// <param name=\"parameter\">The parameter on which the attributes are declared.</param>\n\t\t/// <param name=\"attributeType\">The attribute type to look for.</param>\n\t\t/// <returns>\n\t\t/// Returns the attribute that was found; or <c>null</c> if none was found.\n\t\t/// </returns>\n\t\tpublic static IAttribute GetAttribute(this IParameter parameter, KnownAttribute attributeType)\n\t\t{\n\t\t\treturn parameter.GetAttributes().FirstOrDefault(a => a.AttributeType.IsKnownType(attributeType));\n\t\t}\n\t\t#endregion\n\n\t\t#region IParameter.IsDefaultValueAssignmentAllowed\n\t\t/// <summary>\n\t\t/// Checks if the parameter is allowed to be assigned a default value.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This checks <see cref=\"IParameter.IsOptional\"/>, <see cref=\"IParameter.HasConstantValueInSignature\"/>, <see cref=\"IParameter.ReferenceKind\"/>,\n\t\t/// and <see cref=\"IParameter.IsParams\"/> on this parameter and all subsequent parameters.\n\t\t/// If the parameter has no <see cref=\"IParameter.Owner\"/>, it does not check subsequent parameters.\n\t\t/// </remarks>\n\t\t/// <param name=\"parameter\">The parameter</param>\n\t\t/// <returns>True if the <paramref name=\"parameter\"/> has a default value and is allowed to be assigned a default value.</returns>\n\t\tpublic static bool IsDefaultValueAssignmentAllowed(this IParameter parameter)\n\t\t{\n\t\t\tif (!DefaultValueAssignmentAllowedIndividual(parameter))\n\t\t\t\treturn false;\n\n\t\t\tif (parameter.Owner == null)\n\t\t\t\treturn true; // Shouldn't happen, but we need to check for it.\n\n\t\t\tfor (int i = parameter.Owner.Parameters.Count - 1; i >= 0; i--)\n\t\t\t{\n\t\t\t\tIParameter otherParameter = parameter.Owner.Parameters[i];\n\t\t\t\tif (otherParameter == parameter)\n\t\t\t\t\tbreak;\n\n\t\t\t\tif (LocalFunctionDecompiler.IsClosureParameter(otherParameter, otherParameter.Owner.DeclaringTypeDefinition))\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (DefaultValueAssignmentAllowedIndividual(otherParameter) || otherParameter.IsParams)\n\t\t\t\t\tcontinue;\n\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\n\t\t\tstatic bool DefaultValueAssignmentAllowedIndividual(IParameter parameter)\n\t\t\t{\n\t\t\t\treturn parameter.IsOptional && parameter.HasConstantValueInSignature && parameter.ReferenceKind is ReferenceKind.None or ReferenceKind.In or ReferenceKind.RefReadOnly;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region IAssembly.GetTypeDefinition(string,string,int)\n\t\t/// <summary>\n\t\t/// Gets the type definition for a top-level type.\n\t\t/// </summary>\n\t\t/// <remarks>This method uses ordinal name comparison, not the compilation's name comparer.</remarks>\n\t\tpublic static ITypeDefinition GetTypeDefinition(this IModule module, string namespaceName, string name, int typeParameterCount = 0)\n\t\t{\n\t\t\tif (module == null)\n\t\t\t\tthrow new ArgumentNullException(\"assembly\");\n\t\t\treturn module.GetTypeDefinition(new TopLevelTypeName(namespaceName, name, typeParameterCount));\n\t\t}\n\t\t#endregion\n\n\t\t#region ResolveResult\n\t\tpublic static ISymbol GetSymbol(this ResolveResult rr)\n\t\t{\n\t\t\tif (rr is LocalResolveResult)\n\t\t\t{\n\t\t\t\treturn ((LocalResolveResult)rr).Variable;\n\t\t\t}\n\t\t\telse if (rr is MemberResolveResult)\n\t\t\t{\n\t\t\t\treturn ((MemberResolveResult)rr).Member;\n\t\t\t}\n\t\t\telse if (rr is TypeResolveResult)\n\t\t\t{\n\t\t\t\treturn ((TypeResolveResult)rr).Type.GetDefinition();\n\t\t\t}\n\t\t\telse if (rr is ConversionResolveResult)\n\t\t\t{\n\t\t\t\treturn ((ConversionResolveResult)rr).Input.GetSymbol();\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\t\t#endregion\n\n\t\tpublic static IType GetElementTypeFromIEnumerable(this IType collectionType, ICompilation compilation, bool allowIEnumerator, out bool? isGeneric)\n\t\t{\n\t\t\tbool foundNonGenericIEnumerable = false;\n\t\t\tforeach (IType baseType in collectionType.GetAllBaseTypes())\n\t\t\t{\n\t\t\t\tITypeDefinition baseTypeDef = baseType.GetDefinition();\n\t\t\t\tif (baseTypeDef != null)\n\t\t\t\t{\n\t\t\t\t\tKnownTypeCode typeCode = baseTypeDef.KnownTypeCode;\n\t\t\t\t\tif (typeCode == KnownTypeCode.IEnumerableOfT || (allowIEnumerator && typeCode == KnownTypeCode.IEnumeratorOfT))\n\t\t\t\t\t{\n\t\t\t\t\t\tParameterizedType pt = baseType as ParameterizedType;\n\t\t\t\t\t\tif (pt != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tisGeneric = true;\n\t\t\t\t\t\t\treturn pt.GetTypeArgument(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (typeCode == KnownTypeCode.IEnumerable || (allowIEnumerator && typeCode == KnownTypeCode.IEnumerator))\n\t\t\t\t\t\tfoundNonGenericIEnumerable = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// System.Collections.IEnumerable found in type hierarchy -> Object is element type.\n\t\t\tif (foundNonGenericIEnumerable)\n\t\t\t{\n\t\t\t\tisGeneric = false;\n\t\t\t\treturn compilation.FindType(KnownTypeCode.Object);\n\t\t\t}\n\t\t\tisGeneric = null;\n\t\t\treturn SpecialType.UnknownType;\n\t\t}\n\n\t\tpublic static bool FullNameIs(this IMember member, string type, string name)\n\t\t{\n\t\t\treturn member.Name == name && member.DeclaringType?.FullName == type;\n\t\t}\n\n\t\tpublic static KnownAttribute IsBuiltinAttribute(this ITypeDefinition type)\n\t\t{\n\t\t\treturn KnownAttributes.IsKnownAttributeType(type);\n\t\t}\n\n\t\tpublic static IType WithoutNullability(this IType type)\n\t\t{\n\t\t\treturn type.ChangeNullability(Nullability.Oblivious);\n\t\t}\n\n\t\tpublic static bool IsDirectImportOf(this ITypeDefinition type, IModule module)\n\t\t{\n\t\t\tvar moduleReference = type.ParentModule;\n\t\t\tforeach (var asmRef in module.MetadataFile.AssemblyReferences)\n\t\t\t{\n\t\t\t\tif (asmRef.FullName == moduleReference.FullAssemblyName)\n\t\t\t\t\treturn true;\n\t\t\t\tif (asmRef.Name == \"netstandard\" && asmRef.GetPublicKeyToken() != null)\n\t\t\t\t{\n\t\t\t\t\tvar referencedModule = module.Compilation.FindModuleByReference(asmRef);\n\t\t\t\t\tif (referencedModule != null && !referencedModule.MetadataFile.GetTypeForwarder(type.FullTypeName).IsNil)\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static IModule FindModuleByReference(this ICompilation compilation, IAssemblyReference assemblyName)\n\t\t{\n\t\t\tforeach (var module in compilation.Modules)\n\t\t\t{\n\t\t\t\tif (string.Equals(module.FullAssemblyName, assemblyName.FullName, StringComparison.OrdinalIgnoreCase))\n\t\t\t\t{\n\t\t\t\t\treturn module;\n\t\t\t\t}\n\t\t\t}\n\t\t\tforeach (var module in compilation.Modules)\n\t\t\t{\n\t\t\t\tif (string.Equals(module.Name, assemblyName.Name, StringComparison.OrdinalIgnoreCase))\n\t\t\t\t{\n\t\t\t\t\treturn module;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static IModule FindModuleByAssemblyNameInfo(this ICompilation compilation, AssemblyNameInfo assemblyName)\n\t\t{\n\t\t\tforeach (var module in compilation.Modules)\n\t\t\t{\n\t\t\t\tif (string.Equals(module.FullAssemblyName, assemblyName.FullName, StringComparison.OrdinalIgnoreCase))\n\t\t\t\t{\n\t\t\t\t\treturn module;\n\t\t\t\t}\n\t\t\t}\n\t\t\tforeach (var module in compilation.Modules)\n\t\t\t{\n\t\t\t\tif (string.Equals(module.Name, assemblyName.Name, StringComparison.OrdinalIgnoreCase))\n\t\t\t\t{\n\t\t\t\t\treturn module;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// When given a generic type definition, returns the self-parameterized type\n\t\t/// (i.e. the type of \"this\" within the type definition).\n\t\t/// When given a non-generic type definition, returns that definition unchanged.\n\t\t/// </summary>\n\t\tpublic static IType AsParameterizedType(this ITypeDefinition td)\n\t\t{\n\t\t\tif (td.TypeParameterCount == 0)\n\t\t\t{\n\t\t\t\treturn td;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn new ParameterizedType(td, td.TypeArguments);\n\t\t\t}\n\t\t}\n\n#nullable enable\n\t\tpublic static INamespace? GetNamespaceByFullName(this ICompilation compilation, string? name)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(name))\n\t\t\t\treturn compilation.RootNamespace;\n\t\t\tvar parts = name.Split('.');\n\t\t\tvar ns = compilation.RootNamespace;\n\t\t\tforeach (var part in parts)\n\t\t\t{\n\t\t\t\tvar child = ns.GetChildNamespace(part);\n\t\t\t\tif (child == null)\n\t\t\t\t\treturn null;\n\t\t\t\tns = child;\n\t\t\t}\n\t\t\treturn ns;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/TypeUtils.cs",
    "content": "// Copyright (c) 2015 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Reflection;\n\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\tpublic static class TypeUtils\n\t{\n\t\tpublic const int NativeIntSize = 6; // between 4 (Int32) and 8 (Int64)\n\n\t\t/// <summary>\n\t\t/// Gets the size (in bytes) of the input type.\n\t\t/// Returns <c>NativeIntSize</c> for pointer-sized types.\n\t\t/// Returns 0 for structs and other types of unknown size.\n\t\t/// </summary>\n\t\tpublic static int GetSize(this IType type)\n\t\t{\n\t\t\tswitch (type.Kind)\n\t\t\t{\n\t\t\t\tcase TypeKind.Pointer:\n\t\t\t\tcase TypeKind.ByReference:\n\t\t\t\tcase TypeKind.Class:\n\t\t\t\tcase TypeKind.NInt:\n\t\t\t\tcase TypeKind.NUInt:\n\t\t\t\t\treturn NativeIntSize;\n\t\t\t\tcase TypeKind.Enum:\n\t\t\t\t\ttype = type.GetEnumUnderlyingType();\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeKind.ModOpt:\n\t\t\t\tcase TypeKind.ModReq:\n\t\t\t\t\treturn type.SkipModifiers().GetSize();\n\t\t\t}\n\n\t\t\tvar typeDef = type.GetDefinition();\n\t\t\tif (typeDef == null)\n\t\t\t\treturn 0;\n\t\t\tswitch (typeDef.KnownTypeCode)\n\t\t\t{\n\t\t\t\tcase KnownTypeCode.Boolean:\n\t\t\t\tcase KnownTypeCode.SByte:\n\t\t\t\tcase KnownTypeCode.Byte:\n\t\t\t\t\treturn 1;\n\t\t\t\tcase KnownTypeCode.Char:\n\t\t\t\tcase KnownTypeCode.Int16:\n\t\t\t\tcase KnownTypeCode.UInt16:\n\t\t\t\t\treturn 2;\n\t\t\t\tcase KnownTypeCode.Int32:\n\t\t\t\tcase KnownTypeCode.UInt32:\n\t\t\t\tcase KnownTypeCode.Single:\n\t\t\t\t\treturn 4;\n\t\t\t\tcase KnownTypeCode.IntPtr:\n\t\t\t\tcase KnownTypeCode.UIntPtr:\n\t\t\t\t\treturn NativeIntSize;\n\t\t\t\tcase KnownTypeCode.Int64:\n\t\t\t\tcase KnownTypeCode.UInt64:\n\t\t\t\tcase KnownTypeCode.Double:\n\t\t\t\t\treturn 8;\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the size of the input stack type.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// * 4 for <c>I4</c>,\n\t\t/// * 8 for <c>I8</c>,\n\t\t/// * <c>NativeIntSize</c> for <c>I</c> and <c>Ref</c>,\n\t\t/// * 0 otherwise (O, F, Void, Unknown).\n\t\t/// </returns>\n\t\tpublic static int GetSize(this StackType type)\n\t\t{\n\t\t\tswitch (type)\n\t\t\t{\n\t\t\t\tcase StackType.I4:\n\t\t\t\t\treturn 4;\n\t\t\t\tcase StackType.I8:\n\t\t\t\t\treturn 8;\n\t\t\t\tcase StackType.I:\n\t\t\t\tcase StackType.Ref:\n\t\t\t\t\treturn NativeIntSize;\n\t\t\t\tdefault:\n\t\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\n\t\tpublic static IType GetLargerType(IType type1, IType type2)\n\t\t{\n\t\t\treturn GetSize(type1) >= GetSize(type2) ? type1 : type2;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the type is a small integer type.\n\t\t/// Small integer types are:\n\t\t/// * bool, sbyte, byte, char, short, ushort\n\t\t/// * any enums that have a small integer type as underlying type\n\t\t/// </summary>\n\t\tpublic static bool IsSmallIntegerType(this IType type)\n\t\t{\n\t\t\tint size = GetSize(type);\n\t\t\treturn size > 0 && size < 4;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the type is a C# small integer type: byte, sbyte, short or ushort.\n\t\t/// \n\t\t/// Unlike the ILAst, C# does not consider bool, char or enums to be small integers.\n\t\t/// </summary>\n\t\tpublic static bool IsCSharpSmallIntegerType(this IType type)\n\t\t{\n\t\t\tswitch (type.GetDefinition()?.KnownTypeCode)\n\t\t\t{\n\t\t\t\tcase KnownTypeCode.Byte:\n\t\t\t\tcase KnownTypeCode.SByte:\n\t\t\t\tcase KnownTypeCode.Int16:\n\t\t\t\tcase KnownTypeCode.UInt16:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the type is a C# 9 native integer type: nint or nuint.\n\t\t/// \n\t\t/// Returns false for (U)IntPtr.\n\t\t/// </summary>\n\t\tpublic static bool IsCSharpNativeIntegerType(this IType type)\n\t\t{\n\t\t\tswitch (type.Kind)\n\t\t\t{\n\t\t\t\tcase TypeKind.NInt:\n\t\t\t\tcase TypeKind.NUInt:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the type is a C# primitive integer type: byte, sbyte, short, ushort, int, uint, long and ulong.\n\t\t/// \n\t\t/// Unlike the ILAst, C# does not consider bool, enums, pointers or IntPtr to be integers.\n\t\t/// </summary>\n\t\tpublic static bool IsCSharpPrimitiveIntegerType(this IType type)\n\t\t{\n\t\t\tswitch (type.GetDefinition()?.KnownTypeCode)\n\t\t\t{\n\t\t\t\tcase KnownTypeCode.Byte:\n\t\t\t\tcase KnownTypeCode.SByte:\n\t\t\t\tcase KnownTypeCode.Int16:\n\t\t\t\tcase KnownTypeCode.UInt16:\n\t\t\t\tcase KnownTypeCode.Int32:\n\t\t\t\tcase KnownTypeCode.UInt32:\n\t\t\t\tcase KnownTypeCode.Int64:\n\t\t\t\tcase KnownTypeCode.UInt64:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the type is an IL integer type.\n\t\t/// Returns true for I4, I, or I8.\n\t\t/// </summary>\n\t\tpublic static bool IsIntegerType(this StackType type)\n\t\t{\n\t\t\tswitch (type)\n\t\t\t{\n\t\t\t\tcase StackType.I4:\n\t\t\t\tcase StackType.I:\n\t\t\t\tcase StackType.I8:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether the type is an IL floating point type.\n\t\t/// Returns true for F4 or F8.\n\t\t/// </summary>\n\t\tpublic static bool IsFloatType(this StackType type)\n\t\t{\n\t\t\tswitch (type)\n\t\t\t{\n\t\t\t\tcase StackType.F4:\n\t\t\t\tcase StackType.F8:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether reading/writing an element of accessType from the pointer\n\t\t/// is equivalent to reading/writing an element of the pointer's element type.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// The access semantics may sligthly differ on read accesses of small integer types,\n\t\t/// due to zero extension vs. sign extension when the signs differ.\n\t\t/// </remarks>\n\t\tpublic static bool IsCompatiblePointerTypeForMemoryAccess(IType pointerType, IType accessType)\n\t\t{\n\t\t\tIType memoryType;\n\t\t\tif (pointerType is PointerType || pointerType is ByReferenceType)\n\t\t\t\tmemoryType = ((TypeWithElementType)pointerType).ElementType;\n\t\t\telse\n\t\t\t\treturn false;\n\t\t\treturn IsCompatibleTypeForMemoryAccess(memoryType, accessType);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether reading/writing an element of accessType from the pointer\n\t\t/// is equivalent to reading/writing an element of the memoryType.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// The access semantics may sligthly differ on read accesses of small integer types,\n\t\t/// due to zero extension vs. sign extension when the signs differ.\n\t\t/// </remarks>\n\t\tpublic static bool IsCompatibleTypeForMemoryAccess(IType memoryType, IType accessType)\n\t\t{\n\t\t\tmemoryType = memoryType.AcceptVisitor(NormalizeTypeVisitor.TypeErasure);\n\t\t\taccessType = accessType.AcceptVisitor(NormalizeTypeVisitor.TypeErasure);\n\t\t\tif (memoryType.Equals(accessType))\n\t\t\t\treturn true;\n\t\t\t// If the types are not equal, the access still might produce equal results in some cases:\n\t\t\t// 1) Both types are reference types\n\t\t\tif (memoryType.IsReferenceType == true && accessType.IsReferenceType == true)\n\t\t\t\treturn true;\n\t\t\t// 2) Both types are integer types of equal size\n\t\t\tStackType memoryStackType = memoryType.GetStackType();\n\t\t\tStackType accessStackType = accessType.GetStackType();\n\t\t\tif (memoryStackType == accessStackType && memoryStackType.IsIntegerType() && GetSize(memoryType) == GetSize(accessType))\n\t\t\t\treturn true;\n\t\t\t// 3) Any of the types is unknown: we assume they are compatible.\n\t\t\treturn memoryType.Kind == TypeKind.Unknown || accessType.Kind == TypeKind.Unknown;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the stack type corresponding to this type.\n\t\t/// </summary>\n\t\tpublic static StackType GetStackType(this IType type)\n\t\t{\n\t\t\tswitch (type.Kind)\n\t\t\t{\n\t\t\t\tcase TypeKind.Unknown:\n\t\t\t\t\tif (type.IsReferenceType == true)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn StackType.O;\n\t\t\t\t\t}\n\t\t\t\t\treturn StackType.Unknown;\n\t\t\t\tcase TypeKind.ByReference:\n\t\t\t\t\treturn StackType.Ref;\n\t\t\t\tcase TypeKind.Pointer:\n\t\t\t\tcase TypeKind.NInt:\n\t\t\t\tcase TypeKind.NUInt:\n\t\t\t\tcase TypeKind.FunctionPointer:\n\t\t\t\t\treturn StackType.I;\n\t\t\t\tcase TypeKind.TypeParameter:\n\t\t\t\t\t// Type parameters are always considered StackType.O, even\n\t\t\t\t\t// though they might be instantiated with primitive types.\n\t\t\t\t\treturn StackType.O;\n\t\t\t\tcase TypeKind.ModOpt:\n\t\t\t\tcase TypeKind.ModReq:\n\t\t\t\t\treturn type.SkipModifiers().GetStackType();\n\t\t\t}\n\t\t\tITypeDefinition typeDef = type.GetEnumUnderlyingType().GetDefinition();\n\t\t\tif (typeDef == null)\n\t\t\t\treturn StackType.O;\n\t\t\tswitch (typeDef.KnownTypeCode)\n\t\t\t{\n\t\t\t\tcase KnownTypeCode.Boolean:\n\t\t\t\tcase KnownTypeCode.Char:\n\t\t\t\tcase KnownTypeCode.SByte:\n\t\t\t\tcase KnownTypeCode.Byte:\n\t\t\t\tcase KnownTypeCode.Int16:\n\t\t\t\tcase KnownTypeCode.UInt16:\n\t\t\t\tcase KnownTypeCode.Int32:\n\t\t\t\tcase KnownTypeCode.UInt32:\n\t\t\t\t\treturn StackType.I4;\n\t\t\t\tcase KnownTypeCode.Int64:\n\t\t\t\tcase KnownTypeCode.UInt64:\n\t\t\t\t\treturn StackType.I8;\n\t\t\t\tcase KnownTypeCode.Single:\n\t\t\t\t\treturn StackType.F4;\n\t\t\t\tcase KnownTypeCode.Double:\n\t\t\t\t\treturn StackType.F8;\n\t\t\t\tcase KnownTypeCode.Void:\n\t\t\t\t\treturn StackType.Void;\n\t\t\t\tcase KnownTypeCode.IntPtr:\n\t\t\t\tcase KnownTypeCode.UIntPtr:\n\t\t\t\t\treturn StackType.I;\n\t\t\t\tdefault:\n\t\t\t\t\treturn StackType.O;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// If type is an enumeration type, returns the underlying type.\n\t\t/// Otherwise, returns type unmodified.\n\t\t/// </summary>\n\t\tpublic static IType GetEnumUnderlyingType(this IType type)\n\t\t{\n\t\t\ttype = type.SkipModifiers();\n\t\t\treturn (type.Kind == TypeKind.Enum) ? type.GetDefinition().EnumUnderlyingType : type;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the sign of the input type.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Integer types (including IntPtr/UIntPtr) return the sign as expected.\n\t\t/// Floating point types and <c>decimal</c> are considered to be signed.\n\t\t/// <c>char</c>, <c>bool</c> and pointer types (e.g. <c>void*</c>) are unsigned.\n\t\t/// Enums have a sign based on their underlying type.\n\t\t/// All other types return <c>Sign.None</c>.\n\t\t/// </remarks>\n\t\tpublic static Sign GetSign(this IType type)\n\t\t{\n\t\t\ttype = type.SkipModifiers();\n\t\t\tswitch (type.Kind)\n\t\t\t{\n\t\t\t\tcase TypeKind.Pointer:\n\t\t\t\tcase TypeKind.NUInt:\n\t\t\t\tcase TypeKind.FunctionPointer:\n\t\t\t\t\treturn Sign.Unsigned;\n\t\t\t\tcase TypeKind.NInt:\n\t\t\t\t\treturn Sign.Signed;\n\t\t\t}\n\t\t\tvar typeDef = type.GetEnumUnderlyingType().GetDefinition();\n\t\t\tif (typeDef == null)\n\t\t\t\treturn Sign.None;\n\t\t\tswitch (typeDef.KnownTypeCode)\n\t\t\t{\n\t\t\t\tcase KnownTypeCode.SByte:\n\t\t\t\tcase KnownTypeCode.Int16:\n\t\t\t\tcase KnownTypeCode.Int32:\n\t\t\t\tcase KnownTypeCode.Int64:\n\t\t\t\tcase KnownTypeCode.IntPtr:\n\t\t\t\tcase KnownTypeCode.Single:\n\t\t\t\tcase KnownTypeCode.Double:\n\t\t\t\tcase KnownTypeCode.Decimal:\n\t\t\t\t\treturn Sign.Signed;\n\t\t\t\tcase KnownTypeCode.UIntPtr:\n\t\t\t\tcase KnownTypeCode.Char:\n\t\t\t\tcase KnownTypeCode.Boolean:\n\t\t\t\tcase KnownTypeCode.Byte:\n\t\t\t\tcase KnownTypeCode.UInt16:\n\t\t\t\tcase KnownTypeCode.UInt32:\n\t\t\t\tcase KnownTypeCode.UInt64:\n\t\t\t\t\treturn Sign.Unsigned;\n\t\t\t\tdefault:\n\t\t\t\t\treturn Sign.None;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Maps the KnownTypeCode values to the corresponding PrimitiveTypes.\n\t\t/// </summary>\n\t\tpublic static PrimitiveType ToPrimitiveType(this KnownTypeCode knownTypeCode)\n\t\t{\n\t\t\tswitch (knownTypeCode)\n\t\t\t{\n\t\t\t\tcase KnownTypeCode.SByte:\n\t\t\t\t\treturn PrimitiveType.I1;\n\t\t\t\tcase KnownTypeCode.Int16:\n\t\t\t\t\treturn PrimitiveType.I2;\n\t\t\t\tcase KnownTypeCode.Int32:\n\t\t\t\t\treturn PrimitiveType.I4;\n\t\t\t\tcase KnownTypeCode.Int64:\n\t\t\t\t\treturn PrimitiveType.I8;\n\t\t\t\tcase KnownTypeCode.Single:\n\t\t\t\t\treturn PrimitiveType.R4;\n\t\t\t\tcase KnownTypeCode.Double:\n\t\t\t\t\treturn PrimitiveType.R8;\n\t\t\t\tcase KnownTypeCode.Byte:\n\t\t\t\t\treturn PrimitiveType.U1;\n\t\t\t\tcase KnownTypeCode.UInt16:\n\t\t\t\tcase KnownTypeCode.Char:\n\t\t\t\t\treturn PrimitiveType.U2;\n\t\t\t\tcase KnownTypeCode.UInt32:\n\t\t\t\t\treturn PrimitiveType.U4;\n\t\t\t\tcase KnownTypeCode.UInt64:\n\t\t\t\t\treturn PrimitiveType.U8;\n\t\t\t\tcase KnownTypeCode.IntPtr:\n\t\t\t\t\treturn PrimitiveType.I;\n\t\t\t\tcase KnownTypeCode.UIntPtr:\n\t\t\t\t\treturn PrimitiveType.U;\n\t\t\t\tdefault:\n\t\t\t\t\treturn PrimitiveType.None;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Maps the KnownTypeCode values to the corresponding PrimitiveTypes.\n\t\t/// </summary>\n\t\tpublic static PrimitiveType ToPrimitiveType(this IType type)\n\t\t{\n\t\t\ttype = type.SkipModifiers();\n\t\t\tswitch (type.Kind)\n\t\t\t{\n\t\t\t\tcase TypeKind.Unknown:\n\t\t\t\t\treturn PrimitiveType.Unknown;\n\t\t\t\tcase TypeKind.ByReference:\n\t\t\t\t\treturn PrimitiveType.Ref;\n\t\t\t\tcase TypeKind.NInt:\n\t\t\t\tcase TypeKind.FunctionPointer:\n\t\t\t\t\treturn PrimitiveType.I;\n\t\t\t\tcase TypeKind.NUInt:\n\t\t\t\t\treturn PrimitiveType.U;\n\t\t\t}\n\t\t\tvar def = type.GetEnumUnderlyingType().GetDefinition();\n\t\t\treturn def != null ? def.KnownTypeCode.ToPrimitiveType() : PrimitiveType.None;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Maps the PrimitiveType values to the corresponding KnownTypeCodes.\n\t\t/// </summary>\n\t\tpublic static KnownTypeCode ToKnownTypeCode(this PrimitiveType primitiveType)\n\t\t{\n\t\t\tswitch (primitiveType)\n\t\t\t{\n\t\t\t\tcase PrimitiveType.I1:\n\t\t\t\t\treturn KnownTypeCode.SByte;\n\t\t\t\tcase PrimitiveType.I2:\n\t\t\t\t\treturn KnownTypeCode.Int16;\n\t\t\t\tcase PrimitiveType.I4:\n\t\t\t\t\treturn KnownTypeCode.Int32;\n\t\t\t\tcase PrimitiveType.I8:\n\t\t\t\t\treturn KnownTypeCode.Int64;\n\t\t\t\tcase PrimitiveType.R4:\n\t\t\t\t\treturn KnownTypeCode.Single;\n\t\t\t\tcase PrimitiveType.R8:\n\t\t\t\tcase PrimitiveType.R:\n\t\t\t\t\treturn KnownTypeCode.Double;\n\t\t\t\tcase PrimitiveType.U1:\n\t\t\t\t\treturn KnownTypeCode.Byte;\n\t\t\t\tcase PrimitiveType.U2:\n\t\t\t\t\treturn KnownTypeCode.UInt16;\n\t\t\t\tcase PrimitiveType.U4:\n\t\t\t\t\treturn KnownTypeCode.UInt32;\n\t\t\t\tcase PrimitiveType.U8:\n\t\t\t\t\treturn KnownTypeCode.UInt64;\n\t\t\t\tcase PrimitiveType.I:\n\t\t\t\t\treturn KnownTypeCode.IntPtr;\n\t\t\t\tcase PrimitiveType.U:\n\t\t\t\t\treturn KnownTypeCode.UIntPtr;\n\t\t\t\tdefault:\n\t\t\t\t\treturn KnownTypeCode.None;\n\t\t\t}\n\t\t}\n\n\t\tpublic static KnownTypeCode ToKnownTypeCode(this StackType stackType, Sign sign = Sign.None)\n\t\t{\n\t\t\tswitch (stackType)\n\t\t\t{\n\t\t\t\tcase StackType.I4:\n\t\t\t\t\treturn sign == Sign.Unsigned ? KnownTypeCode.UInt32 : KnownTypeCode.Int32;\n\t\t\t\tcase StackType.I8:\n\t\t\t\t\treturn sign == Sign.Unsigned ? KnownTypeCode.UInt64 : KnownTypeCode.Int64;\n\t\t\t\tcase StackType.I:\n\t\t\t\t\treturn sign == Sign.Unsigned ? KnownTypeCode.UIntPtr : KnownTypeCode.IntPtr;\n\t\t\t\tcase StackType.F4:\n\t\t\t\t\treturn KnownTypeCode.Single;\n\t\t\t\tcase StackType.F8:\n\t\t\t\t\treturn KnownTypeCode.Double;\n\t\t\t\tcase StackType.O:\n\t\t\t\t\treturn KnownTypeCode.Object;\n\t\t\t\tcase StackType.Void:\n\t\t\t\t\treturn KnownTypeCode.Void;\n\t\t\t\tdefault:\n\t\t\t\t\treturn KnownTypeCode.None;\n\t\t\t}\n\t\t}\n\n\t\tpublic static PrimitiveType ToPrimitiveType(this StackType stackType, Sign sign = Sign.None)\n\t\t{\n\t\t\tswitch (stackType)\n\t\t\t{\n\t\t\t\tcase StackType.I4:\n\t\t\t\t\treturn sign == Sign.Unsigned ? PrimitiveType.U4 : PrimitiveType.I4;\n\t\t\t\tcase StackType.I8:\n\t\t\t\t\treturn sign == Sign.Unsigned ? PrimitiveType.U8 : PrimitiveType.I8;\n\t\t\t\tcase StackType.I:\n\t\t\t\t\treturn sign == Sign.Unsigned ? PrimitiveType.U : PrimitiveType.I;\n\t\t\t\tcase StackType.F4:\n\t\t\t\t\treturn PrimitiveType.R4;\n\t\t\t\tcase StackType.F8:\n\t\t\t\t\treturn PrimitiveType.R8;\n\t\t\t\tcase StackType.Ref:\n\t\t\t\t\treturn PrimitiveType.Ref;\n\t\t\t\tcase StackType.Unknown:\n\t\t\t\t\treturn PrimitiveType.Unknown;\n\t\t\t\tdefault:\n\t\t\t\t\treturn PrimitiveType.None;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic enum Sign : byte\n\t{\n\t\tNone,\n\t\tSigned,\n\t\tUnsigned\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/TypeVisitor.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Base class for the visitor pattern on <see cref=\"IType\"/>.\n\t/// </summary>\n\tpublic abstract class TypeVisitor\n\t{\n\t\tpublic virtual IType VisitTypeDefinition(ITypeDefinition type)\n\t\t{\n\t\t\treturn type.VisitChildren(this);\n\t\t}\n\n\t\tpublic virtual IType VisitTypeParameter(ITypeParameter type)\n\t\t{\n\t\t\treturn type.VisitChildren(this);\n\t\t}\n\n\t\tpublic virtual IType VisitParameterizedType(ParameterizedType type)\n\t\t{\n\t\t\treturn type.VisitChildren(this);\n\t\t}\n\n\t\tpublic virtual IType VisitArrayType(ArrayType type)\n\t\t{\n\t\t\treturn type.VisitChildren(this);\n\t\t}\n\n\t\tpublic virtual IType VisitPointerType(PointerType type)\n\t\t{\n\t\t\treturn type.VisitChildren(this);\n\t\t}\n\n\t\tpublic virtual IType VisitByReferenceType(ByReferenceType type)\n\t\t{\n\t\t\treturn type.VisitChildren(this);\n\t\t}\n\n\t\tpublic virtual IType VisitTupleType(TupleType type)\n\t\t{\n\t\t\treturn type.VisitChildren(this);\n\t\t}\n\n\t\tpublic virtual IType VisitOtherType(IType type)\n\t\t{\n\t\t\treturn type.VisitChildren(this);\n\t\t}\n\n\t\tpublic virtual IType VisitModReq(ModifiedType type)\n\t\t{\n\t\t\treturn type.VisitChildren(this);\n\t\t}\n\n\t\tpublic virtual IType VisitModOpt(ModifiedType type)\n\t\t{\n\t\t\treturn type.VisitChildren(this);\n\t\t}\n\n\t\tpublic virtual IType VisitNullabilityAnnotatedType(NullabilityAnnotatedType type)\n\t\t{\n\t\t\treturn type.VisitChildren(this);\n\t\t}\n\n\t\tpublic virtual IType VisitFunctionPointerType(FunctionPointerType type)\n\t\t{\n\t\t\treturn type.VisitChildren(this);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/TypeSystem/VarArgInstanceMethod.cs",
    "content": "// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nnamespace ICSharpCode.Decompiler.TypeSystem\n{\n\t/// <summary>\n\t/// Used when calling a vararg method. Stores the actual parameter types being passed.\n\t/// </summary>\n\tpublic class VarArgInstanceMethod : IMethod\n\t{\n\t\treadonly IMethod baseMethod;\n\t\treadonly IParameter[] parameters;\n\n\t\tpublic VarArgInstanceMethod(IMethod baseMethod, IEnumerable<IType> varArgTypes)\n\t\t{\n\t\t\tthis.baseMethod = baseMethod;\n\t\t\tvar paramList = new List<IParameter>(baseMethod.Parameters);\n\t\t\tDebug.Assert(paramList.Last().Type.Kind == TypeKind.ArgList);\n\t\t\tparamList.RemoveAt(paramList.Count - 1);\n\t\t\tforeach (IType varArg in varArgTypes)\n\t\t\t{\n\t\t\t\tparamList.Add(new DefaultParameter(varArg, name: string.Empty, owner: this));\n\t\t\t}\n\t\t\tthis.parameters = paramList.ToArray();\n\t\t}\n\n\t\tpublic IMethod BaseMethod => baseMethod;\n\n\t\tpublic int RegularParameterCount {\n\t\t\tget { return baseMethod.Parameters.Count - 1; }\n\t\t}\n\n\t\tpublic IReadOnlyList<IParameter> Parameters {\n\t\t\tget { return parameters; }\n\t\t}\n\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\tVarArgInstanceMethod other = obj as VarArgInstanceMethod;\n\t\t\treturn other != null && baseMethod.Equals(other.baseMethod);\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn baseMethod.GetHashCode();\n\t\t}\n\n\t\tpublic bool Equals(IMember obj, TypeVisitor typeNormalization)\n\t\t{\n\t\t\tVarArgInstanceMethod other = obj as VarArgInstanceMethod;\n\t\t\treturn other != null && baseMethod.Equals(other.baseMethod, typeNormalization);\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tStringBuilder b = new StringBuilder(\"[\");\n\t\t\tb.Append(this.SymbolKind);\n\t\t\tif (this.DeclaringType != null)\n\t\t\t{\n\t\t\t\tb.Append(this.DeclaringType.ReflectionName);\n\t\t\t\tb.Append('.');\n\t\t\t}\n\t\t\tb.Append(this.Name);\n\t\t\tif (this.TypeParameters.Count > 0)\n\t\t\t{\n\t\t\t\tb.Append(\"``\");\n\t\t\t\tb.Append(this.TypeParameters.Count);\n\t\t\t}\n\t\t\tb.Append('(');\n\t\t\tfor (int i = 0; i < this.Parameters.Count; i++)\n\t\t\t{\n\t\t\t\tif (i > 0)\n\t\t\t\t\tb.Append(\", \");\n\t\t\t\tif (i == this.RegularParameterCount)\n\t\t\t\t\tb.Append(\"..., \");\n\t\t\t\tb.Append(this.Parameters[i].Type.ReflectionName);\n\t\t\t}\n\t\t\tif (this.Parameters.Count == this.RegularParameterCount)\n\t\t\t{\n\t\t\t\tb.Append(\", ...\");\n\t\t\t}\n\t\t\tb.Append(\"):\");\n\t\t\tb.Append(this.ReturnType.ReflectionName);\n\t\t\tb.Append(']');\n\t\t\treturn b.ToString();\n\t\t}\n\n\t\t#region IMethod implementation\n\t\tpublic IMethod Specialize(TypeParameterSubstitution substitution)\n\t\t{\n\t\t\treturn new VarArgInstanceMethod(\n\t\t\t\tbaseMethod.Specialize(substitution),\n\t\t\t\tparameters.Skip(baseMethod.Parameters.Count - 1).Select(p => p.Type.AcceptVisitor(substitution)).ToList());\n\t\t}\n\n\t\tIEnumerable<IAttribute> IEntity.GetAttributes() => baseMethod.GetAttributes();\n\t\tbool IEntity.HasAttribute(KnownAttribute attribute) => baseMethod.HasAttribute(attribute);\n\t\tIAttribute IEntity.GetAttribute(KnownAttribute attribute) => baseMethod.GetAttribute(attribute);\n\n\t\tIEnumerable<IAttribute> IMethod.GetReturnTypeAttributes() => baseMethod.GetReturnTypeAttributes();\n\t\tbool IMethod.ReturnTypeIsRefReadOnly => baseMethod.ReturnTypeIsRefReadOnly;\n\t\tbool IMethod.ThisIsRefReadOnly => baseMethod.ThisIsRefReadOnly;\n\t\tbool IMethod.IsInitOnly => baseMethod.IsInitOnly;\n\n\t\tpublic IReadOnlyList<ITypeParameter> TypeParameters {\n\t\t\tget { return baseMethod.TypeParameters; }\n\t\t}\n\n\t\tpublic IReadOnlyList<IType> TypeArguments {\n\t\t\tget { return baseMethod.TypeArguments; }\n\t\t}\n\n\t\tpublic System.Reflection.Metadata.EntityHandle MetadataToken => baseMethod.MetadataToken;\n\n\t\tpublic bool IsExtensionMethod {\n\t\t\tget { return baseMethod.IsExtensionMethod; }\n\t\t}\n\n\t\tbool IMethod.IsLocalFunction {\n\t\t\tget { return baseMethod.IsLocalFunction; }\n\t\t}\n\n\t\tpublic bool IsConstructor {\n\t\t\tget { return baseMethod.IsConstructor; }\n\t\t}\n\n\t\tpublic bool IsDestructor {\n\t\t\tget { return baseMethod.IsDestructor; }\n\t\t}\n\n\t\tpublic bool IsOperator {\n\t\t\tget { return baseMethod.IsOperator; }\n\t\t}\n\n\t\tpublic bool HasBody {\n\t\t\tget { return baseMethod.HasBody; }\n\t\t}\n\n\t\tpublic bool IsAccessor => baseMethod.IsAccessor;\n\t\tpublic IMember AccessorOwner => baseMethod.AccessorOwner;\n\t\tpublic MethodSemanticsAttributes AccessorKind => baseMethod.AccessorKind;\n\n\t\tpublic IMethod ReducedFrom {\n\t\t\tget { return baseMethod.ReducedFrom; }\n\t\t}\n\n\t\t#endregion\n\n\t\t#region IMember implementation\n\n\t\tIMember IMember.Specialize(TypeParameterSubstitution substitution)\n\t\t{\n\t\t\treturn Specialize(substitution);\n\t\t}\n\n\t\tpublic IMember MemberDefinition {\n\t\t\tget { return baseMethod.MemberDefinition; }\n\t\t}\n\n\t\tpublic IType ReturnType {\n\t\t\tget { return baseMethod.ReturnType; }\n\t\t}\n\n\t\tpublic IEnumerable<IMember> ExplicitlyImplementedInterfaceMembers {\n\t\t\tget { return baseMethod.ExplicitlyImplementedInterfaceMembers; }\n\t\t}\n\n\t\tpublic bool IsExplicitInterfaceImplementation {\n\t\t\tget { return baseMethod.IsExplicitInterfaceImplementation; }\n\t\t}\n\n\t\tpublic bool IsVirtual {\n\t\t\tget { return baseMethod.IsVirtual; }\n\t\t}\n\n\t\tpublic bool IsOverride {\n\t\t\tget { return baseMethod.IsOverride; }\n\t\t}\n\n\t\tpublic bool IsOverridable {\n\t\t\tget { return baseMethod.IsOverridable; }\n\t\t}\n\n\t\tpublic TypeParameterSubstitution Substitution {\n\t\t\tget { return baseMethod.Substitution; }\n\t\t}\n\n\t\t#endregion\n\n\t\t#region ISymbol implementation\n\n\t\tpublic SymbolKind SymbolKind {\n\t\t\tget { return baseMethod.SymbolKind; }\n\t\t}\n\n\t\tpublic string Name {\n\t\t\tget { return baseMethod.Name; }\n\t\t}\n\n\t\t#endregion\n\n\t\t#region IEntity implementation\n\n\t\tpublic ITypeDefinition DeclaringTypeDefinition {\n\t\t\tget { return baseMethod.DeclaringTypeDefinition; }\n\t\t}\n\n\t\tpublic IType DeclaringType {\n\t\t\tget { return baseMethod.DeclaringType; }\n\t\t}\n\n\t\tpublic IModule ParentModule {\n\t\t\tget { return baseMethod.ParentModule; }\n\t\t}\n\n\t\tpublic bool IsStatic {\n\t\t\tget { return baseMethod.IsStatic; }\n\t\t}\n\n\t\tpublic bool IsAbstract {\n\t\t\tget { return baseMethod.IsAbstract; }\n\t\t}\n\n\t\tpublic bool IsSealed {\n\t\t\tget { return baseMethod.IsSealed; }\n\t\t}\n\n\t\t#endregion\n\n\t\t#region IHasAccessibility implementation\n\n\t\tpublic Accessibility Accessibility {\n\t\t\tget { return baseMethod.Accessibility; }\n\t\t}\n\n\t\t#endregion\n\n\t\t#region INamedElement implementation\n\n\t\tpublic string FullName {\n\t\t\tget { return baseMethod.FullName; }\n\t\t}\n\n\t\tpublic string ReflectionName {\n\t\t\tget { return baseMethod.ReflectionName; }\n\t\t}\n\n\t\tpublic string Namespace {\n\t\t\tget { return baseMethod.Namespace; }\n\t\t}\n\n\t\t#endregion\n\n\t\t#region ICompilationProvider implementation\n\n\t\tpublic ICompilation Compilation {\n\t\t\tget { return baseMethod.Compilation; }\n\t\t}\n\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/BitOperations.cs",
    "content": "using System;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n#if !NET8_0_OR_GREATER\nnamespace System.Numerics\n{\n\tinternal static class BitOperations\n\t{\n\t\tprivate static ReadOnlySpan<byte> TrailingZeroCountDeBruijn => new byte[32]\n{\n\t\t\t00, 01, 28, 02, 29, 14, 24, 03,\n\t\t\t30, 22, 20, 15, 25, 17, 04, 08,\n\t\t\t31, 27, 13, 23, 21, 19, 16, 07,\n\t\t\t26, 12, 18, 06, 11, 05, 10, 09\n};\n\t\tpublic static int TrailingZeroCount(uint value)\n\t\t{\n\t\t\t// Unguarded fallback contract is 0->0, BSF contract is 0->undefined\n\t\t\tif (value == 0)\n\t\t\t{\n\t\t\t\treturn 32;\n\t\t\t}\n\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\t// uint.MaxValue >> 27 is always in range [0 - 31] so we use Unsafe.AddByteOffset to avoid bounds check\n\t\t\t\treturn Unsafe.AddByteOffset(\n\t\t\t\t\t// Using deBruijn sequence, k=2, n=5 (2^5=32) : 0b_0000_0111_0111_1100_1011_0101_0011_0001u\n\t\t\t\t\tref MemoryMarshal.GetReference(TrailingZeroCountDeBruijn),\n\t\t\t\t\t// uint|long -> IntPtr cast on 32-bit platforms does expensive overflow checks not needed here\n\t\t\t\t\t(IntPtr)(int)(((value & (uint)-(int)value) * 0x077CB531u) >> 27)); // Multi-cast mitigates redundant conv.u8\n\t\t\t}\n\t\t}\n\n\t\tpublic static int TrailingZeroCount(ulong value)\n\t\t{\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\tuint lo = (uint)value;\n\n\t\t\t\tif (lo == 0)\n\t\t\t\t{\n\t\t\t\t\treturn 32 + TrailingZeroCount((uint)(value >> 32));\n\t\t\t\t}\n\n\t\t\t\treturn TrailingZeroCount(lo);\n\t\t\t}\n\t\t}\n\t}\n}\n#endif\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/BitSet.cs",
    "content": "// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Numerics;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\t/// <summary>\n\t/// Improved version of BitArray\n\t/// </summary>\n\tpublic class BitSet\n\t{\n\t\tconst int BitsPerWord = 64;\n\t\tconst int Log2BitsPerWord = 6;\n\t\tconst ulong Mask = 0xffffffffffffffffUL;\n\n\t\treadonly ulong[] words;\n\n\t\tstatic int WordIndex(int bitIndex)\n\t\t{\n\t\t\tDebug.Assert(bitIndex >= 0);\n\t\t\treturn bitIndex >> Log2BitsPerWord;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a new bitset, where initially all bits are zero.\n\t\t/// </summary>\n\t\tpublic BitSet(int capacity)\n\t\t{\n\t\t\tthis.words = new ulong[Math.Max(1, WordIndex(capacity + BitsPerWord - 1))];\n\t\t}\n\n\t\tprivate BitSet(ulong[] bits)\n\t\t{\n\t\t\tthis.words = bits;\n\t\t}\n\n\t\tpublic BitSet Clone()\n\t\t{\n\t\t\treturn new BitSet((ulong[])words.Clone());\n\t\t}\n\n\t\tpublic bool this[int index] {\n\t\t\tget {\n\t\t\t\treturn (words[WordIndex(index)] & (1UL << index)) != 0;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tif (value)\n\t\t\t\t\tSet(index);\n\t\t\t\telse\n\t\t\t\t\tClear(index);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether at least one bit is set.\n\t\t/// </summary>\n\t\tpublic bool Any()\n\t\t{\n\t\t\tfor (int i = 0; i < words.Length; i++)\n\t\t\t{\n\t\t\t\tif (words[i] != 0)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether all bits in the specified range are set.\n\t\t/// </summary>\n\t\tpublic bool All(int startIndex, int endIndex)\n\t\t{\n\t\t\tDebug.Assert(startIndex <= endIndex);\n\t\t\tif (startIndex >= endIndex)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tint startWordIndex = WordIndex(startIndex);\n\t\t\tint endWordIndex = WordIndex(endIndex - 1);\n\t\t\tulong startMask = Mask << startIndex;\n\t\t\tulong endMask = Mask >> -endIndex; // same as (Mask >> (64 - (endIndex % 64)))\n\t\t\tif (startWordIndex == endWordIndex)\n\t\t\t{\n\t\t\t\treturn (words[startWordIndex] & (startMask & endMask)) == (startMask & endMask);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif ((words[startWordIndex] & startMask) != startMask)\n\t\t\t\t\treturn false;\n\t\t\t\tfor (int i = startWordIndex + 1; i < endWordIndex; i++)\n\t\t\t\t{\n\t\t\t\t\tif (words[i] != ulong.MaxValue)\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn (words[endWordIndex] & endMask) == endMask;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether both bitsets have the same content.\n\t\t/// </summary>\n\t\tpublic bool SetEquals(BitSet other)\n\t\t{\n\t\t\tDebug.Assert(words.Length == other.words.Length);\n\t\t\tfor (int i = 0; i < words.Length; i++)\n\t\t\t{\n\t\t\t\tif (words[i] != other.words[i])\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this set is a subset of other, or equal.\n\t\t/// </summary>\n\t\tpublic bool IsSubsetOf(BitSet other)\n\t\t{\n\t\t\tfor (int i = 0; i < words.Length; i++)\n\t\t\t{\n\t\t\t\tif ((words[i] & ~other.words[i]) != 0)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this set is a superset of other, or equal.\n\t\t/// </summary>\n\t\tpublic bool IsSupersetOf(BitSet other)\n\t\t{\n\t\t\treturn other.IsSubsetOf(this);\n\t\t}\n\n\t\tpublic bool IsProperSubsetOf(BitSet other)\n\t\t{\n\t\t\treturn IsSubsetOf(other) && !SetEquals(other);\n\t\t}\n\n\t\tpublic bool IsProperSupersetOf(BitSet other)\n\t\t{\n\t\t\treturn IsSupersetOf(other) && !SetEquals(other);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether at least one bit is set in both bitsets.\n\t\t/// </summary>\n\t\tpublic bool Overlaps(BitSet other)\n\t\t{\n\t\t\tfor (int i = 0; i < words.Length; i++)\n\t\t\t{\n\t\t\t\tif ((words[i] & other.words[i]) != 0)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic void UnionWith(BitSet other)\n\t\t{\n\t\t\tDebug.Assert(words.Length == other.words.Length);\n\t\t\tfor (int i = 0; i < words.Length; i++)\n\t\t\t{\n\t\t\t\twords[i] |= other.words[i];\n\t\t\t}\n\t\t}\n\n\t\tpublic void IntersectWith(BitSet other)\n\t\t{\n\t\t\tfor (int i = 0; i < words.Length; i++)\n\t\t\t{\n\t\t\t\twords[i] &= other.words[i];\n\t\t\t}\n\t\t}\n\n\t\tpublic void Set(int index)\n\t\t{\n\t\t\twords[WordIndex(index)] |= (1UL << index);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Sets all bits i; where startIndex &lt;= i &lt; endIndex.\n\t\t/// </summary>\n\t\tpublic void Set(int startIndex, int endIndex)\n\t\t{\n\t\t\tDebug.Assert(startIndex <= endIndex);\n\t\t\tif (startIndex >= endIndex)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tint startWordIndex = WordIndex(startIndex);\n\t\t\tint endWordIndex = WordIndex(endIndex - 1);\n\t\t\tulong startMask = Mask << startIndex;\n\t\t\tulong endMask = Mask >> -endIndex; // same as (Mask >> (64 - (endIndex % 64)))\n\t\t\tif (startWordIndex == endWordIndex)\n\t\t\t{\n\t\t\t\twords[startWordIndex] |= (startMask & endMask);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\twords[startWordIndex] |= startMask;\n\t\t\t\tfor (int i = startWordIndex + 1; i < endWordIndex; i++)\n\t\t\t\t{\n\t\t\t\t\twords[i] = ulong.MaxValue;\n\t\t\t\t}\n\t\t\t\twords[endWordIndex] |= endMask;\n\t\t\t}\n\t\t}\n\n\t\t// Note: intentionally no SetAll(), because it would also set the\n\t\t// extra bits (due to the capacity being rounded up to a full word).\n\n\t\tpublic void Clear(int index)\n\t\t{\n\t\t\twords[WordIndex(index)] &= ~(1UL << index);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Clear all bits i; where startIndex &lt;= i &lt; endIndex.\n\t\t/// </summary>\n\t\tpublic void Clear(int startIndex, int endIndex)\n\t\t{\n\t\t\tDebug.Assert(startIndex <= endIndex);\n\t\t\tif (startIndex >= endIndex)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tint startWordIndex = WordIndex(startIndex);\n\t\t\tint endWordIndex = WordIndex(endIndex - 1);\n\t\t\tulong startMask = Mask << startIndex;\n\t\t\tulong endMask = Mask >> -endIndex; // same as (Mask >> (64 - (endIndex % 64)))\n\t\t\tif (startWordIndex == endWordIndex)\n\t\t\t{\n\t\t\t\twords[startWordIndex] &= ~(startMask & endMask);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\twords[startWordIndex] &= ~startMask;\n\t\t\t\tfor (int i = startWordIndex + 1; i < endWordIndex; i++)\n\t\t\t\t{\n\t\t\t\t\twords[i] = 0;\n\t\t\t\t}\n\t\t\t\twords[endWordIndex] &= ~endMask;\n\t\t\t}\n\t\t}\n\n\t\tpublic void ClearAll()\n\t\t{\n\t\t\tfor (int i = 0; i < words.Length; i++)\n\t\t\t{\n\t\t\t\twords[i] = 0;\n\t\t\t}\n\t\t}\n\n\t\tpublic int NextSetBit(int startIndex, int endIndex)\n\t\t{\n\t\t\tDebug.Assert(startIndex <= endIndex);\n\t\t\tif (startIndex >= endIndex)\n\t\t\t{\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\tint startWordIndex = WordIndex(startIndex);\n\t\t\tint endWordIndex = WordIndex(endIndex - 1);\n\t\t\tulong startMask = Mask << startIndex;\n\t\t\tulong endMask = Mask >> -endIndex; // same as (Mask >> (64 - (endIndex % 64)))\n\t\t\tif (startWordIndex == endWordIndex)\n\t\t\t{\n\t\t\t\tulong maskedWord = words[startWordIndex] & startMask & endMask;\n\t\t\t\tif (maskedWord != 0)\n\t\t\t\t{\n\t\t\t\t\treturn startWordIndex * 64 + BitOperations.TrailingZeroCount(maskedWord);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tulong maskedWord = words[startWordIndex] & startMask;\n\t\t\t\tif (maskedWord != 0)\n\t\t\t\t{\n\t\t\t\t\treturn startWordIndex * 64 + BitOperations.TrailingZeroCount(maskedWord);\n\t\t\t\t}\n\t\t\t\tfor (int i = startWordIndex + 1; i < endWordIndex; i++)\n\t\t\t\t{\n\t\t\t\t\tmaskedWord = words[i];\n\t\t\t\t\tif (maskedWord != 0)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn i * 64 + BitOperations.TrailingZeroCount(maskedWord);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tmaskedWord = words[endWordIndex] & endMask;\n\t\t\t\tif (maskedWord != 0)\n\t\t\t\t{\n\t\t\t\t\treturn endWordIndex * 64 + BitOperations.TrailingZeroCount(maskedWord);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn -1;\n\t\t}\n\n\t\tpublic IEnumerable<int> SetBits(int startIndex, int endIndex)\n\t\t{\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tint next = NextSetBit(startIndex, endIndex);\n\t\t\t\tif (next == -1)\n\t\t\t\t\tbreak;\n\t\t\t\tyield return next;\n\t\t\t\tstartIndex = next + 1;\n\t\t\t}\n\t\t}\n\n\t\tpublic void ReplaceWith(BitSet incoming)\n\t\t{\n\t\t\tDebug.Assert(words.Length == incoming.words.Length);\n\t\t\tArray.Copy(incoming.words, 0, words, 0, words.Length);\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tStringBuilder b = new StringBuilder();\n\t\t\tb.Append('{');\n\t\t\tfor (int i = 0; i < words.Length * BitsPerWord; i++)\n\t\t\t{\n\t\t\t\tif (this[i])\n\t\t\t\t{\n\t\t\t\t\tif (b.Length > 1)\n\t\t\t\t\t\tb.Append(\", \");\n\t\t\t\t\tif (b.Length > 500)\n\t\t\t\t\t{\n\t\t\t\t\t\tb.Append(\"...\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tb.Append(i);\n\t\t\t\t}\n\t\t\t}\n\t\t\tb.Append('}');\n\t\t\treturn b.ToString();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/BusyManager.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\t/// <summary>\n\t/// This class is used to prevent stack overflows by representing a 'busy' flag\n\t/// that prevents reentrance when another call is running.\n\t/// However, using a simple 'bool busy' is not thread-safe, so we use a\n\t/// thread-static BusyManager.\n\t/// </summary>\n\tpublic static class BusyManager\n\t{\n\t\t[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Performance\", \"CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes\")]\n\t\t[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1034:NestedTypesShouldNotBeVisible\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t Justification = \"Should always be used with 'var'\")]\n\t\tpublic struct BusyLock : IDisposable\n\t\t{\n\t\t\tpublic static readonly BusyLock Failed = new BusyLock(null);\n\n\t\t\treadonly List<object?>? objectList;\n\n\t\t\tinternal BusyLock(List<object?>? objectList)\n\t\t\t{\n\t\t\t\tthis.objectList = objectList;\n\t\t\t}\n\n\t\t\tpublic bool Success {\n\t\t\t\tget { return objectList != null; }\n\t\t\t}\n\n\t\t\tpublic void Dispose()\n\t\t\t{\n\t\t\t\tif (objectList != null)\n\t\t\t\t{\n\t\t\t\t\tobjectList.RemoveAt(objectList.Count - 1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t[ThreadStatic] static List<object?>? _activeObjects;\n\n\t\tpublic static BusyLock Enter(object? obj)\n\t\t{\n\t\t\tList<object?>? activeObjects = _activeObjects;\n\t\t\tif (activeObjects == null)\n\t\t\t\tactiveObjects = _activeObjects = new List<object?>();\n\t\t\tfor (int i = 0; i < activeObjects.Count; i++)\n\t\t\t{\n\t\t\t\tif (activeObjects[i] == obj)\n\t\t\t\t\treturn BusyLock.Failed;\n\t\t\t}\n\t\t\tactiveObjects.Add(obj);\n\t\t\treturn new BusyLock(activeObjects);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/CSharpPrimitiveCast.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\t/// <summary>\n\t/// Static helper method for converting between primitive types.\n\t/// </summary>\n\tpublic static class CSharpPrimitiveCast\n\t{\n\t\t/// <summary>\n\t\t/// Performs a conversion between primitive types.\n\t\t/// Unfortunately we cannot use Convert.ChangeType because it has different semantics\n\t\t/// (e.g. rounding behavior for floats, overflow, etc.), so we write down every possible primitive C# cast\n\t\t/// and let the compiler figure out the exact semantics.\n\t\t/// And we have to do everything twice, once in a checked-block, once in an unchecked-block.\n\t\t/// </summary>\n\t\t/// <exception cref=\"OverflowException\">Overflow checking is enabled and an overflow occurred.</exception>\n\t\t/// <exception cref=\"InvalidCastException\">The cast is invalid, e.g. casting a boolean to an integer.</exception>\n\t\tpublic static object Cast(TypeCode targetType, object input, bool checkForOverflow)\n\t\t{\n\t\t\tif (input == null)\n\t\t\t\treturn null;\n\t\t\tif (checkForOverflow)\n\t\t\t\treturn CSharpPrimitiveCastChecked(targetType, input);\n\t\t\telse\n\t\t\t\treturn CSharpPrimitiveCastUnchecked(targetType, input);\n\t\t}\n\n\t\tstatic object CSharpPrimitiveCastChecked(TypeCode targetType, object input)\n\t\t{\n\t\t\tchecked\n\t\t\t{\n\t\t\t\tTypeCode sourceType = Type.GetTypeCode(input.GetType());\n\t\t\t\tif (sourceType == targetType)\n\t\t\t\t\treturn input;\n\t\t\t\tswitch (targetType)\n\t\t\t\t{\n\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (char)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (char)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (char)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (char)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (char)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (char)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (char)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (char)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (char)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (char)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (char)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (char)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (sbyte)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (sbyte)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (sbyte)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (sbyte)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (sbyte)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (sbyte)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (sbyte)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (sbyte)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (sbyte)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (sbyte)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (sbyte)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (sbyte)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (byte)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (byte)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (byte)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (byte)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (byte)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (byte)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (byte)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (byte)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (byte)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (byte)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (byte)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (byte)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (short)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (short)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (short)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (short)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (short)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (short)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (short)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (short)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (short)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (short)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (short)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (short)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (ushort)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (ushort)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (ushort)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (ushort)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (ushort)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (ushort)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (ushort)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (ushort)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (ushort)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (ushort)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (ushort)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (ushort)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (int)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (int)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (int)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (int)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (int)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (int)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (int)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (int)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (int)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (int)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (int)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (int)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (uint)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (uint)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (uint)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (uint)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (uint)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (uint)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (uint)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (uint)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (uint)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (uint)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (uint)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (uint)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (long)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (long)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (long)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (long)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (long)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (long)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (long)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (long)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (long)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (long)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (long)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (long)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (ulong)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (ulong)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (ulong)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (ulong)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (ulong)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (ulong)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (ulong)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (ulong)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (ulong)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (ulong)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (ulong)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (ulong)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (float)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (float)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (float)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (float)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (float)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (float)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (float)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (float)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (float)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (float)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (float)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (float)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (double)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (double)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (double)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (double)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (double)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (double)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (double)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (double)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (double)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (double)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (double)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (double)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (decimal)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (decimal)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (decimal)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (decimal)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (decimal)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (decimal)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (decimal)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (decimal)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (decimal)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (decimal)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (decimal)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (decimal)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tthrow new InvalidCastException(\"Cast from \" + sourceType + \" to \" + targetType + \"not supported.\");\n\t\t\t}\n\t\t}\n\n\t\tstatic object CSharpPrimitiveCastUnchecked(TypeCode targetType, object input)\n\t\t{\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\tTypeCode sourceType = Type.GetTypeCode(input.GetType());\n\t\t\t\tif (sourceType == targetType)\n\t\t\t\t\treturn input;\n\t\t\t\tswitch (targetType)\n\t\t\t\t{\n\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (char)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (char)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (char)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (char)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (char)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (char)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (char)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (char)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (char)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (char)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (char)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (char)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (sbyte)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (sbyte)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (sbyte)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (sbyte)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (sbyte)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (sbyte)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (sbyte)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (sbyte)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (sbyte)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (sbyte)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (sbyte)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (sbyte)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (byte)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (byte)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (byte)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (byte)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (byte)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (byte)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (byte)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (byte)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (byte)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (byte)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (byte)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (byte)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (short)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (short)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (short)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (short)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (short)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (short)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (short)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (short)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (short)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (short)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (short)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (short)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (ushort)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (ushort)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (ushort)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (ushort)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (ushort)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (ushort)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (ushort)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (ushort)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (ushort)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (ushort)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (ushort)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (ushort)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (int)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (int)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (int)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (int)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (int)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (int)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (int)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (int)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (int)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (int)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (int)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (int)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (uint)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (uint)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (uint)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (uint)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (uint)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (uint)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (uint)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (uint)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (uint)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (uint)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (uint)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (uint)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (long)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (long)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (long)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (long)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (long)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (long)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (long)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (long)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (long)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (long)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (long)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (long)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (ulong)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (ulong)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (ulong)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (ulong)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (ulong)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (ulong)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (ulong)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (ulong)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (ulong)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (ulong)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (ulong)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (ulong)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (float)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (float)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (float)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (float)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (float)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (float)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (float)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (float)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (float)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (float)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (float)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (float)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (double)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (double)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (double)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (double)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (double)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (double)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (double)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (double)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (double)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (double)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\t\t\treturn (double)(decimal)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (double)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Decimal:\n\t\t\t\t\t\tswitch (sourceType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TypeCode.Char:\n\t\t\t\t\t\t\t\treturn (decimal)(char)input;\n\t\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\t\t\treturn (decimal)(sbyte)input;\n\t\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\t\t\treturn (decimal)(byte)input;\n\t\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\t\t\treturn (decimal)(short)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\t\t\treturn (decimal)(ushort)input;\n\t\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\t\t\treturn (decimal)(int)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\t\t\treturn (decimal)(uint)input;\n\t\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\t\t\treturn (decimal)(long)input;\n\t\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\t\treturn (decimal)(ulong)input;\n\t\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\t\t\treturn (decimal)(float)input;\n\t\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\t\t\treturn (decimal)(double)input;\n\t\t\t\t\t\t\tcase TypeCode.Boolean:\n\t\t\t\t\t\t\t\treturn (decimal)((bool)input ? 1 : 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tthrow new InvalidCastException(\"Cast from \" + sourceType + \" to \" + targetType + \" not supported.\");\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/CacheManager.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Concurrent;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\t/// <summary>\n\t/// Allows caching values for a specific compilation.\n\t/// A CacheManager consists of a for shared instances (shared among all threads working with that resolve context).\n\t/// </summary>\n\t/// <remarks>This class is thread-safe</remarks>\n\tpublic sealed class CacheManager\n\t{\n\t\treadonly ConcurrentDictionary<object, object> sharedDict = new ConcurrentDictionary<object, object>(ReferenceComparer.Instance);\n\t\t// There used to be a thread-local dictionary here, but I removed it as it was causing memory\n\t\t// leaks in some use cases.\n\n\t\tpublic object? GetShared(object key)\n\t\t{\n\t\t\tobject? value;\n\t\t\tsharedDict.TryGetValue(key, out value);\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic object GetOrAddShared(object key, Func<object, object> valueFactory)\n\t\t{\n\t\t\treturn sharedDict.GetOrAdd(key, valueFactory);\n\t\t}\n\n\t\tpublic object GetOrAddShared(object key, object value)\n\t\t{\n\t\t\treturn sharedDict.GetOrAdd(key, value);\n\t\t}\n\n\t\tpublic void SetShared(object key, object value)\n\t\t{\n\t\t\tsharedDict[key] = value;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/CallbackOnDispose.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Threading;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\t/// <summary>\n\t/// Invokes an action when it is disposed.\n\t/// </summary>\n\t/// <remarks>\n\t/// This class ensures the callback is invoked at most once,\n\t/// even when Dispose is called on multiple threads.\n\t/// </remarks>\n\tpublic sealed class CallbackOnDispose : IDisposable\n\t{\n\t\tAction? action;\n\n\t\tpublic CallbackOnDispose(Action action)\n\t\t{\n\t\t\tif (action == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(action));\n\t\t\tthis.action = action;\n\t\t}\n\n\t\tpublic void Dispose()\n\t\t{\n\t\t\tAction? a = Interlocked.Exchange(ref action, null);\n\t\t\tif (a != null)\n\t\t\t{\n\t\t\t\ta();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/CollectionExtensions.cs",
    "content": "#nullable enable\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\tstatic class CollectionExtensions\n\t{\n\t\tpublic static void Deconstruct<K, V>(this KeyValuePair<K, V> pair, out K key, out V value)\n\t\t{\n\t\t\tkey = pair.Key;\n\t\t\tvalue = pair.Value;\n\t\t}\n\n#if !NET8_0_OR_GREATER\n\t\tpublic static IEnumerable<(A, B)> Zip<A, B>(this IEnumerable<A> input1, IEnumerable<B> input2)\n\t\t{\n\t\t\treturn input1.Zip(input2, (a, b) => (a, b));\n\t\t}\n#endif\n\n\t\tpublic static IEnumerable<(int, A, B)> ZipWithIndex<A, B>(this IEnumerable<A> input1, IEnumerable<B> input2)\n\t\t{\n\t\t\tint index = 0;\n\t\t\treturn input1.Zip(input2, (a, b) => (index++, a, b));\n\t\t}\n\n\t\tpublic static IEnumerable<(A?, B?)> ZipLongest<A, B>(this IEnumerable<A> input1, IEnumerable<B> input2)\n\t\t{\n\t\t\tusing (var it1 = input1.GetEnumerator())\n\t\t\t{\n\t\t\t\tusing (var it2 = input2.GetEnumerator())\n\t\t\t\t{\n\t\t\t\t\tbool hasElements1 = true;\n\t\t\t\t\tbool hasElements2 = true;\n\t\t\t\t\twhile (true)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (hasElements1)\n\t\t\t\t\t\t\thasElements1 = it1.MoveNext();\n\t\t\t\t\t\tif (hasElements2)\n\t\t\t\t\t\t\thasElements2 = it2.MoveNext();\n\t\t\t\t\t\tif (!(hasElements1 || hasElements2))\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tyield return ((hasElements1 ? it1.Current : default), (hasElements2 ? it2.Current : default));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<T> Slice<T>(this IReadOnlyList<T> input, int offset, int length)\n\t\t{\n\t\t\tfor (int i = offset; i < offset + length; i++)\n\t\t\t{\n\t\t\t\tyield return input[i];\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<T> Slice<T>(this IReadOnlyList<T> input, int offset)\n\t\t{\n\t\t\tint length = input.Count;\n\t\t\tfor (int i = offset; i < length; i++)\n\t\t\t{\n\t\t\t\tyield return input[i];\n\t\t\t}\n\t\t}\n\n#if !NET8_0_OR_GREATER\n\t\tpublic static HashSet<T> ToHashSet<T>(this IEnumerable<T> input)\n\t\t{\n\t\t\treturn new HashSet<T>(input);\n\t\t}\n#endif\n\n\t\tpublic static IEnumerable<T> SkipLast<T>(this IReadOnlyCollection<T> input, int count)\n\t\t{\n\t\t\treturn input.Take(input.Count - count);\n\t\t}\n\n\t\tpublic static IEnumerable<T> TakeLast<T>(this IReadOnlyCollection<T> input, int count)\n\t\t{\n\t\t\treturn input.Skip(input.Count - count);\n\t\t}\n\n\t\tpublic static T? PopOrDefault<T>(this Stack<T> stack)\n\t\t{\n\t\t\tif (stack.Count == 0)\n\t\t\t\treturn default(T);\n\t\t\treturn stack.Pop();\n\t\t}\n\n\t\tpublic static T? PeekOrDefault<T>(this Stack<T> stack)\n\t\t{\n\t\t\tif (stack.Count == 0)\n\t\t\t\treturn default(T);\n\t\t\treturn stack.Peek();\n\t\t}\n\n\t\tpublic static int MaxOrDefault<T>(this IEnumerable<T> input, Func<T, int> selector, int defaultValue = 0)\n\t\t{\n\t\t\tint max = defaultValue;\n\t\t\tforeach (var element in input)\n\t\t\t{\n\t\t\t\tint value = selector(element);\n\t\t\t\tif (value > max)\n\t\t\t\t\tmax = value;\n\t\t\t}\n\t\t\treturn max;\n\t\t}\n\n\t\tpublic static int IndexOf<T>(this IReadOnlyList<T> collection, T value)\n\t\t{\n\t\t\tvar comparer = EqualityComparer<T>.Default;\n\t\t\tint index = 0;\n\t\t\tforeach (T item in collection)\n\t\t\t{\n\t\t\t\tif (comparer.Equals(item, value))\n\t\t\t\t{\n\t\t\t\t\treturn index;\n\t\t\t\t}\n\t\t\t\tindex++;\n\t\t\t}\n\t\t\treturn -1;\n\t\t}\n\n\t\tpublic static void AddRange<T>(this ICollection<T> collection, IEnumerable<T> input)\n\t\t{\n\t\t\tforeach (T item in input)\n\t\t\t\tcollection.Add(item);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Equivalent to <code>collection.Select(func).ToArray()</code>, but more efficient as it makes\n\t\t/// use of the input collection's known size.\n\t\t/// </summary>\n\t\tpublic static U[] SelectArray<T, U>(this ICollection<T> collection, Func<T, U> func)\n\t\t{\n\t\t\tU[] result = new U[collection.Count];\n\t\t\tint index = 0;\n\t\t\tforeach (var element in collection)\n\t\t\t{\n\t\t\t\tresult[index++] = func(element);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Equivalent to <code>collection.Select(func).ToImmutableArray()</code>, but more efficient as it makes\n\t\t/// use of the input collection's known size.\n\t\t/// </summary>\n\t\tpublic static ImmutableArray<U> SelectImmutableArray<T, U>(this IReadOnlyCollection<T> collection, Func<T, U> func)\n\t\t{\n\t\t\tvar builder = ImmutableArray.CreateBuilder<U>(collection.Count);\n\t\t\tforeach (var element in collection)\n\t\t\t{\n\t\t\t\tbuilder.Add(func(element));\n\t\t\t}\n\t\t\treturn builder.MoveToImmutable();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Equivalent to <code>collection.Select(func).ToArray()</code>, but more efficient as it makes\n\t\t/// use of the input collection's known size.\n\t\t/// </summary>\n\t\tpublic static U[] SelectReadOnlyArray<T, U>(this IReadOnlyCollection<T> collection, Func<T, U> func)\n\t\t{\n\t\t\tU[] result = new U[collection.Count];\n\t\t\tint index = 0;\n\t\t\tforeach (var element in collection)\n\t\t\t{\n\t\t\t\tresult[index++] = func(element);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Equivalent to <code>collection.Select(func).ToArray()</code>, but more efficient as it makes\n\t\t/// use of the input collection's known size.\n\t\t/// </summary>\n\t\tpublic static U[] SelectArray<T, U>(this List<T> collection, Func<T, U> func)\n\t\t{\n\t\t\tU[] result = new U[collection.Count];\n\t\t\tint index = 0;\n\t\t\tforeach (var element in collection)\n\t\t\t{\n\t\t\t\tresult[index++] = func(element);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Equivalent to <code>collection.Select(func).ToArray()</code>, but more efficient as it makes\n\t\t/// use of the input collection's known size.\n\t\t/// </summary>\n\t\tpublic static U[] SelectArray<T, U>(this T[] collection, Func<T, U> func)\n\t\t{\n\t\t\tU[] result = new U[collection.Length];\n\t\t\tint index = 0;\n\t\t\tforeach (var element in collection)\n\t\t\t{\n\t\t\t\tresult[index++] = func(element);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Equivalent to <code>collection.Select(func).ToList()</code>, but more efficient as it makes\n\t\t/// use of the input collection's known size.\n\t\t/// </summary>\n\t\tpublic static List<U> SelectList<T, U>(this ICollection<T> collection, Func<T, U> func)\n\t\t{\n\t\t\tList<U> result = new List<U>(collection.Count);\n\t\t\tforeach (var element in collection)\n\t\t\t{\n\t\t\t\tresult.Add(func(element));\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic static IEnumerable<U> SelectWithIndex<T, U>(this IEnumerable<T> source, Func<int, T, U> func)\n\t\t{\n\t\t\tint index = 0;\n\t\t\tforeach (var element in source)\n\t\t\t\tyield return func(index++, element);\n\t\t}\n\n\t\tpublic static IEnumerable<(int, T)> WithIndex<T>(this IEnumerable<T> source)\n\t\t{\n\t\t\tint index = 0;\n\t\t\tforeach (var item in source)\n\t\t\t{\n\t\t\t\tyield return (index, item);\n\t\t\t\tindex++;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// The merge step of merge sort.\n\t\t/// </summary>\n\t\tpublic static IEnumerable<T> Merge<T>(this IEnumerable<T> input1, IEnumerable<T> input2, Comparison<T> comparison)\n\t\t{\n\t\t\tusing (var enumA = input1.GetEnumerator())\n\t\t\tusing (var enumB = input2.GetEnumerator())\n\t\t\t{\n\t\t\t\tbool moreA = enumA.MoveNext();\n\t\t\t\tbool moreB = enumB.MoveNext();\n\t\t\t\twhile (moreA && moreB)\n\t\t\t\t{\n\t\t\t\t\tif (comparison(enumA.Current, enumB.Current) <= 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return enumA.Current;\n\t\t\t\t\t\tmoreA = enumA.MoveNext();\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return enumB.Current;\n\t\t\t\t\t\tmoreB = enumB.MoveNext();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\twhile (moreA)\n\t\t\t\t{\n\t\t\t\t\tyield return enumA.Current;\n\t\t\t\t\tmoreA = enumA.MoveNext();\n\t\t\t\t}\n\t\t\t\twhile (moreB)\n\t\t\t\t{\n\t\t\t\t\tyield return enumB.Current;\n\t\t\t\t\tmoreB = enumB.MoveNext();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the minimum element.\n\t\t/// </summary>\n\t\t/// <exception cref=\"InvalidOperationException\">The input sequence is empty</exception>\n\t\tpublic static T MinBy<T, K>(this IEnumerable<T> source, Func<T, K> keySelector) where K : IComparable<K>\n\t\t{\n\t\t\treturn source.MinBy(keySelector, Comparer<K>.Default);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the minimum element.\n\t\t/// </summary>\n\t\t/// <exception cref=\"InvalidOperationException\">The input sequence is empty</exception>\n\t\tpublic static T MinBy<T, K>(this IEnumerable<T> source, Func<T, K> keySelector, IComparer<K>? keyComparer)\n\t\t{\n\t\t\tif (source == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(source));\n\t\t\tif (keySelector == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(keySelector));\n\t\t\tif (keyComparer == null)\n\t\t\t\tkeyComparer = Comparer<K>.Default;\n\t\t\tusing (var enumerator = source.GetEnumerator())\n\t\t\t{\n\t\t\t\tif (!enumerator.MoveNext())\n\t\t\t\t\tthrow new InvalidOperationException(\"Sequence contains no elements\");\n\t\t\t\tT minElement = enumerator.Current;\n\t\t\t\tK minKey = keySelector(minElement);\n\t\t\t\twhile (enumerator.MoveNext())\n\t\t\t\t{\n\t\t\t\t\tT element = enumerator.Current;\n\t\t\t\t\tK key = keySelector(element);\n\t\t\t\t\tif (keyComparer.Compare(key, minKey) < 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tminElement = element;\n\t\t\t\t\t\tminKey = key;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn minElement;\n\t\t\t}\n\t\t}\n\n#if !NET8_0_OR_GREATER\n\t\t/// <summary>\n\t\t/// Returns the maximum element.\n\t\t/// </summary>\n\t\t/// <exception cref=\"InvalidOperationException\">The input sequence is empty</exception>\n\t\tpublic static T MaxBy<T, K>(this IEnumerable<T> source, Func<T, K> keySelector) where K : IComparable<K>\n\t\t{\n\t\t\treturn source.MaxBy(keySelector, Comparer<K>.Default);\n\t\t}\n#endif\n\t\t/// <summary>\n\t\t/// Returns the maximum element.\n\t\t/// </summary>\n\t\t/// <exception cref=\"InvalidOperationException\">The input sequence is empty</exception>\n\t\tpublic static T MaxBy<T, K>(this IEnumerable<T> source, Func<T, K> keySelector, IComparer<K>? keyComparer)\n\t\t{\n\t\t\tif (source == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(source));\n\t\t\tif (keySelector == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(keySelector));\n\t\t\tif (keyComparer == null)\n\t\t\t\tkeyComparer = Comparer<K>.Default;\n\t\t\tusing (var enumerator = source.GetEnumerator())\n\t\t\t{\n\t\t\t\tif (!enumerator.MoveNext())\n\t\t\t\t\tthrow new InvalidOperationException(\"Sequence contains no elements\");\n\t\t\t\tT maxElement = enumerator.Current;\n\t\t\t\tK maxKey = keySelector(maxElement);\n\t\t\t\twhile (enumerator.MoveNext())\n\t\t\t\t{\n\t\t\t\t\tT element = enumerator.Current;\n\t\t\t\t\tK key = keySelector(element);\n\t\t\t\t\tif (keyComparer.Compare(key, maxKey) > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tmaxElement = element;\n\t\t\t\t\t\tmaxKey = key;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn maxElement;\n\t\t\t}\n\t\t}\n\n\t\tpublic static void RemoveLast<T>(this IList<T> list)\n\t\t{\n\t\t\tif (list == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(list));\n\t\t\tlist.RemoveAt(list.Count - 1);\n\t\t}\n\n\t\tpublic static T? OnlyOrDefault<T>(this IEnumerable<T> source, Func<T, bool> predicate) => OnlyOrDefault(source.Where(predicate));\n\n\t\tpublic static T? OnlyOrDefault<T>(this IEnumerable<T> source)\n\t\t{\n\t\t\tbool any = false;\n\t\t\tT? first = default;\n\t\t\tforeach (var t in source)\n\t\t\t{\n\t\t\t\tif (any)\n\t\t\t\t\treturn default(T);\n\t\t\t\tfirst = t;\n\t\t\t\tany = true;\n\t\t\t}\n\n\t\t\treturn first;\n\t\t}\n\n#if !NET8_0_OR_GREATER\n\t\tpublic static int EnsureCapacity<T>(this List<T> list, int capacity)\n\t\t{\n\t\t\tif (capacity < 0)\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(capacity));\n\t\t\tif (list.Capacity < capacity)\n\t\t\t{\n\t\t\t\tconst int DefaultCapacity = 4;\n\t\t\t\tconst int MaxLength = 0X7FFFFFC7;\n\n\t\t\t\tint newcapacity = list.Capacity == 0 ? DefaultCapacity : 2 * list.Capacity;\n\n\t\t\t\tif ((uint)newcapacity > MaxLength)\n\t\t\t\t\tnewcapacity = MaxLength;\n\n\t\t\t\tif (newcapacity < capacity)\n\t\t\t\t\tnewcapacity = capacity;\n\n\t\t\t\tlist.Capacity = newcapacity;\n\t\t\t}\n\n\t\t\treturn list.Capacity;\n\t\t}\n#endif\n\n\t\t#region Aliases/shortcuts for Enumerable extension methods\n\t\tpublic static bool Any<T>(this ICollection<T> list) => list.Count > 0;\n\t\tpublic static bool Any<T>(this T[] array, Predicate<T> match) => Array.Exists(array, match);\n\t\tpublic static bool Any<T>(this List<T> list, Predicate<T> match) => list.Exists(match);\n\n\t\tpublic static bool All<T>(this T[] array, Predicate<T> match) => Array.TrueForAll(array, match);\n\t\tpublic static bool All<T>(this List<T> list, Predicate<T> match) => list.TrueForAll(match);\n\n\t\tpublic static T? FirstOrDefault<T>(this T[] array, Predicate<T> predicate) => Array.Find(array, predicate);\n\t\tpublic static T? FirstOrDefault<T>(this List<T> list, Predicate<T> predicate) => list.Find(predicate);\n\n\t\tpublic static T Last<T>(this IList<T> list) => list[list.Count - 1];\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/DelegateComparer.cs",
    "content": "#nullable enable\n// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\tpublic class DelegateComparer<T> : IComparer<T>\n\t{\n\t\tprivate readonly Func<T?, T?, int> func;\n\n\t\tpublic DelegateComparer(Func<T?, T?, int> func)\n\t\t{\n\t\t\tthis.func = func ?? throw new ArgumentNullException(nameof(func));\n\t\t}\n\n\t\tpublic int Compare(T? x, T? y)\n\t\t{\n\t\t\treturn func(x, y);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/EmptyList.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n#nullable enable\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\t[Serializable]\n\tpublic sealed class EmptyList<T> : IList<T>, IEnumerator<T>, IReadOnlyList<T>\n\t{\n\t\tpublic static readonly EmptyList<T> Instance = new EmptyList<T>();\n\n\t\tprivate EmptyList() { }\n\n\t\tpublic T this[int index] {\n\t\t\tget { throw new ArgumentOutOfRangeException(nameof(index)); }\n\t\t\tset { throw new ArgumentOutOfRangeException(nameof(index)); }\n\t\t}\n\n\t\tpublic int Count {\n\t\t\tget { return 0; }\n\t\t}\n\n\t\tbool ICollection<T>.IsReadOnly {\n\t\t\tget { return true; }\n\t\t}\n\n\t\tint IList<T>.IndexOf(T item)\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\n\t\tvoid IList<T>.Insert(int index, T item)\n\t\t{\n\t\t\tthrow new NotSupportedException();\n\t\t}\n\n\t\tvoid IList<T>.RemoveAt(int index)\n\t\t{\n\t\t\tthrow new NotSupportedException();\n\t\t}\n\n\t\tvoid ICollection<T>.Add(T item)\n\t\t{\n\t\t\tthrow new NotSupportedException();\n\t\t}\n\n\t\tvoid ICollection<T>.Clear()\n\t\t{\n\t\t}\n\n\t\tbool ICollection<T>.Contains(T item)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tvoid ICollection<T>.CopyTo(T[] array, int arrayIndex)\n\t\t{\n\t\t}\n\n\t\tbool ICollection<T>.Remove(T item)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tIEnumerator<T> IEnumerable<T>.GetEnumerator()\n\t\t{\n\t\t\treturn this;\n\t\t}\n\n\t\tSystem.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\n\t\t{\n\t\t\treturn this;\n\t\t}\n\n\t\tT IEnumerator<T>.Current {\n\t\t\tget { throw new NotSupportedException(); }\n\t\t}\n\n\t\tobject IEnumerator.Current {\n\t\t\tget { throw new NotSupportedException(); }\n\t\t}\n\n\t\tvoid IDisposable.Dispose()\n\t\t{\n\t\t}\n\n\t\tbool IEnumerator.MoveNext()\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tvoid IEnumerator.Reset()\n\t\t{\n\t\t}\n\t}\n\n\tpublic static class Empty<T>\n\t{\n\t\tpublic static readonly T[] Array = System.Array.Empty<T>();\n\t}\n\n\tpublic struct Unit { }\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/ExtensionMethods.cs",
    "content": "#nullable enable\n// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\t/// <summary>\n\t/// Contains extension methods for internal use within the decompiler.\n\t/// </summary>\n\tstatic class ExtensionMethods\n\t{\n\t\tpublic static Predicate<T>? And<T>(this Predicate<T>? filter1, Predicate<T>? filter2)\n\t\t{\n\t\t\tif (filter1 == null)\n\t\t\t\treturn filter2;\n\t\t\tif (filter2 == null)\n\t\t\t\treturn filter1;\n\t\t\treturn m => filter1(m) && filter2(m);\n\t\t}\n\n\t\tpublic static void Swap<T>(ref T a, ref T b)\n\t\t{\n\t\t\tT tmp = a;\n\t\t\ta = b;\n\t\t\tb = tmp;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/FileUtility.cs",
    "content": "// Copyright (c) 2020 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\tstatic class FileUtility\n\t{\n\t\t/// <summary>\n\t\t/// Gets the normalized version of fileName.\n\t\t/// Slashes are replaced with backslashes, backreferences \".\" and \"..\" are 'evaluated'.\n\t\t/// </summary>\n\t\t[return: NotNullIfNotNull(\"fileName\")]\n\t\tpublic static string? NormalizePath(string? fileName)\n\t\t{\n\t\t\tif (fileName == null || fileName.Length == 0)\n\t\t\t\treturn fileName;\n\n\t\t\tint i;\n\n\t\t\tbool isWeb = false;\n\t\t\tfor (i = 0; i < fileName.Length; i++)\n\t\t\t{\n\t\t\t\tif (fileName[i] == '/' || fileName[i] == '\\\\')\n\t\t\t\t\tbreak;\n\t\t\t\tif (fileName[i] == ':')\n\t\t\t\t{\n\t\t\t\t\tif (i > 1)\n\t\t\t\t\t\tisWeb = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tchar outputSeparator = '/';\n\t\t\tbool isRelative;\n\t\t\tbool isAbsoluteUnixPath = false;\n\n\t\t\tStringBuilder result = new StringBuilder();\n\t\t\tif (isWeb == false && IsUNCPath(fileName))\n\t\t\t{\n\t\t\t\t// UNC path\n\t\t\t\ti = 2;\n\t\t\t\toutputSeparator = '\\\\';\n\t\t\t\tresult.Append(outputSeparator);\n\t\t\t\tisRelative = false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ti = 0;\n\t\t\t\tisAbsoluteUnixPath = fileName[0] == '/';\n\t\t\t\tisRelative = !isWeb && !isAbsoluteUnixPath && (fileName.Length < 2 || fileName[1] != ':');\n\t\t\t\tif (fileName.Length >= 2 && fileName[1] == ':')\n\t\t\t\t{\n\t\t\t\t\toutputSeparator = '\\\\';\n\t\t\t\t}\n\t\t\t}\n\t\t\tint levelsBack = 0;\n\t\t\tint segmentStartPos = i;\n\t\t\tfor (; i <= fileName.Length; i++)\n\t\t\t{\n\t\t\t\tif (i == fileName.Length || fileName[i] == '/' || fileName[i] == '\\\\')\n\t\t\t\t{\n\t\t\t\t\tint segmentLength = i - segmentStartPos;\n\t\t\t\t\tswitch (segmentLength)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase 0:\n\t\t\t\t\t\t\t// ignore empty segment (if not in web mode)\n\t\t\t\t\t\t\tif (isWeb)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tresult.Append(outputSeparator);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 1:\n\t\t\t\t\t\t\t// ignore /./ segment, but append other one-letter segments\n\t\t\t\t\t\t\tif (fileName[segmentStartPos] != '.')\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (result.Length > 0)\n\t\t\t\t\t\t\t\t\tresult.Append(outputSeparator);\n\t\t\t\t\t\t\t\tresult.Append(fileName[segmentStartPos]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\tif (fileName[segmentStartPos] == '.' && fileName[segmentStartPos + 1] == '.')\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// remove previous segment\n\t\t\t\t\t\t\t\tint j;\n\t\t\t\t\t\t\t\tfor (j = result.Length - 1; j >= 0 && result[j] != outputSeparator; j--)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (j > 0)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tresult.Length = j;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse if (isAbsoluteUnixPath)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tresult.Length = 0;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse if (isRelative)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif (result.Length == 0)\n\t\t\t\t\t\t\t\t\t\tlevelsBack++;\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\tresult.Length = 0;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// append normal segment\n\t\t\t\t\t\t\t\tgoto default;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tif (result.Length > 0)\n\t\t\t\t\t\t\t\tresult.Append(outputSeparator);\n\t\t\t\t\t\t\tresult.Append(fileName, segmentStartPos, segmentLength);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tsegmentStartPos = i + 1; // remember start position for next segment\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (isWeb == false)\n\t\t\t{\n\t\t\t\tif (isRelative)\n\t\t\t\t{\n\t\t\t\t\tfor (int j = 0; j < levelsBack; j++)\n\t\t\t\t\t{\n\t\t\t\t\t\tresult.Insert(0, \"..\" + outputSeparator);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (result.Length > 0 && result[result.Length - 1] == outputSeparator)\n\t\t\t\t{\n\t\t\t\t\tresult.Length -= 1;\n\t\t\t\t}\n\t\t\t\tif (isAbsoluteUnixPath)\n\t\t\t\t{\n\t\t\t\t\tresult.Insert(0, '/');\n\t\t\t\t}\n\t\t\t\tif (result.Length == 2 && result[1] == ':')\n\t\t\t\t{\n\t\t\t\t\tresult.Append(outputSeparator);\n\t\t\t\t}\n\t\t\t\tif (result.Length == 0)\n\t\t\t\t\treturn \".\";\n\t\t\t}\n\t\t\treturn result.ToString();\n\t\t}\n\n\t\tstatic bool IsUNCPath(string fileName)\n\t\t{\n\t\t\treturn fileName.Length > 2\n\t\t\t\t&& (fileName[0] == '\\\\' || fileName[0] == '/')\n\t\t\t\t&& (fileName[1] == '\\\\' || fileName[1] == '/');\n\t\t}\n\n\t\tpublic static bool IsEqualFileName(string? fileName1, string? fileName2)\n\t\t{\n\t\t\treturn string.Equals(NormalizePath(fileName1),\n\t\t\t\t\t\t\t\t NormalizePath(fileName2),\n\t\t\t\t\t\t\t\t StringComparison.OrdinalIgnoreCase);\n\t\t}\n\n\t\tpublic static bool IsBaseDirectory(string? baseDirectory, string? testDirectory)\n\t\t{\n\t\t\tif (baseDirectory == null || testDirectory == null)\n\t\t\t\treturn false;\n\t\t\tbaseDirectory = NormalizePath(baseDirectory);\n\t\t\tif (baseDirectory == \".\" || baseDirectory == \"\")\n\t\t\t\treturn !Path.IsPathRooted(testDirectory);\n\t\t\tbaseDirectory = AddTrailingSeparator(baseDirectory);\n\t\t\ttestDirectory = AddTrailingSeparator(NormalizePath(testDirectory));\n\n\t\t\treturn testDirectory.StartsWith(baseDirectory, StringComparison.OrdinalIgnoreCase);\n\t\t}\n\n\t\t[return: NotNullIfNotNull(\"input\")]\n\t\tstatic string? AddTrailingSeparator(string? input)\n\t\t{\n\t\t\tif (input == null || input.Length == 0)\n\t\t\t\treturn input;\n\t\t\tif (input[input.Length - 1] == Path.DirectorySeparatorChar || input[input.Length - 1] == Path.AltDirectorySeparatorChar)\n\t\t\t\treturn input;\n\t\t\telse\n\t\t\t\treturn input + GetSeparatorForPath(input).ToString();\n\t\t}\n\n\t\tstatic char GetSeparatorForPath(string input)\n\t\t{\n\t\t\tif (input.Length > 2 && input[1] == ':' || IsUNCPath(input))\n\t\t\t\treturn '\\\\';\n\t\t\treturn '/';\n\t\t}\n\n\t\treadonly static char[] separators = { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar };\n\n\t\t/// <summary>\n\t\t/// Converts a given absolute path and a given base path to a path that leads\n\t\t/// from the base path to the absoulte path. (as a relative path)\n\t\t/// </summary>\n\t\tpublic static string GetRelativePath(string? baseDirectoryPath, string absPath)\n\t\t{\n\t\t\tif (baseDirectoryPath == null || baseDirectoryPath.Length == 0)\n\t\t\t{\n\t\t\t\treturn absPath;\n\t\t\t}\n\n\t\t\tbaseDirectoryPath = NormalizePath(baseDirectoryPath);\n\t\t\tabsPath = NormalizePath(absPath);\n\n\t\t\tstring[] bPath = baseDirectoryPath != \".\" ? baseDirectoryPath.TrimEnd(separators).Split(separators) : new string[0];\n\t\t\tstring[] aPath = absPath != \".\" ? absPath.TrimEnd(separators).Split(separators) : new string[0];\n\t\t\tint indx = 0;\n\t\t\tfor (; indx < Math.Min(bPath.Length, aPath.Length); ++indx)\n\t\t\t{\n\t\t\t\tif (!bPath[indx].Equals(aPath[indx], StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (indx == 0 && (Path.IsPathRooted(baseDirectoryPath) || Path.IsPathRooted(absPath)))\n\t\t\t{\n\t\t\t\treturn absPath;\n\t\t\t}\n\n\t\t\tif (indx == bPath.Length && indx == aPath.Length)\n\t\t\t{\n\t\t\t\treturn \".\";\n\t\t\t}\n\t\t\tStringBuilder erg = new StringBuilder();\n\t\t\tfor (int i = indx; i < bPath.Length; ++i)\n\t\t\t{\n\t\t\t\terg.Append(\"..\");\n\t\t\t\terg.Append(Path.DirectorySeparatorChar);\n\t\t\t}\n\t\t\terg.Append(String.Join(Path.DirectorySeparatorChar.ToString(), aPath, indx, aPath.Length - indx));\n\t\t\tif (erg[erg.Length - 1] == Path.DirectorySeparatorChar)\n\t\t\t\terg.Length -= 1;\n\t\t\treturn erg.ToString();\n\t\t}\n\n\t\t[return: NotNullIfNotNull(\"path\")]\n\t\tpublic static string? TrimPath(string? path, int max_chars)\n\t\t{\n\t\t\tconst char ellipsis = '\\u2026'; // HORIZONTAL ELLIPSIS\n\t\t\tconst int ellipsisLength = 2;\n\n\t\t\tif (path == null || path.Length <= max_chars)\n\t\t\t\treturn path;\n\t\t\tchar sep = Path.DirectorySeparatorChar;\n\t\t\tif (path.IndexOf(Path.AltDirectorySeparatorChar) >= 0 && path.IndexOf(Path.DirectorySeparatorChar) < 0)\n\t\t\t{\n\t\t\t\tsep = Path.AltDirectorySeparatorChar;\n\t\t\t}\n\t\t\tstring[] parts = path.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);\n\t\t\tint len = ellipsisLength; // For initial ellipsis\n\t\t\tint index = parts.Length;\n\t\t\t// From the end of the path, fit as many parts as possible:\n\t\t\twhile (index > 1 && len + parts[index - 1].Length < max_chars)\n\t\t\t{\n\t\t\t\tlen += parts[index - 1].Length + 1;\n\t\t\t\tindex--;\n\t\t\t}\n\n\t\t\tStringBuilder result = new StringBuilder();\n\t\t\tresult.Append(ellipsis);\n\t\t\t// If there's 5 chars left, partially fit another part:\n\t\t\tif (index > 1 && len + 5 <= max_chars)\n\t\t\t{\n\t\t\t\tif (index == 2 && parts[0].Length <= ellipsisLength)\n\t\t\t\t{\n\t\t\t\t\t// If the partial part is part #1,\n\t\t\t\t\t// and part #0 is as short as the ellipsis\n\t\t\t\t\t// (e.g. just a drive letter), use part #0\n\t\t\t\t\t// instead of the ellipsis.\n\t\t\t\t\tresult.Clear();\n\t\t\t\t\tresult.Append(parts[0]);\n\t\t\t\t}\n\t\t\t\tresult.Append(sep);\n\t\t\t\tresult.Append(parts[index - 1], 0, max_chars - len - 3);\n\t\t\t\tresult.Append(ellipsis);\n\t\t\t}\n\t\t\twhile (index < parts.Length)\n\t\t\t{\n\t\t\t\tresult.Append(sep);\n\t\t\t\tresult.Append(parts[index]);\n\t\t\t\tindex++;\n\t\t\t}\n\t\t\treturn result.ToString();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/GraphTraversal.cs",
    "content": "// Copyright (c) 2023 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Util;\n\nstatic class GraphTraversal\n{\n\t/// <summary>\n\t/// Depth-first-search of an graph data structure.\n\t/// The two callbacks (successorFunc + postorderAction) will be called exactly once for each node reachable from startNodes.\n\t/// </summary>\n\t/// <param name=\"startNodes\">The start nodes.</param>\n\t/// <param name=\"visitedFunc\">Called multiple times per node. The first call should return true, subsequent calls must return false.\n\t/// The first calls to this function occur in pre-order.\n\t/// If null, normal Equals/GetHashCode will be used to compare nodes.</param>\n\t/// <param name=\"successorFunc\">The function that gets the successors of an element. Called in pre-order.</param>\n\t/// <param name=\"postorderAction\">Called in post-order.</param>\n\t/// <param name=\"reverseSuccessors\">\n\t/// With reverse_successors=True, the start_nodes and each list of successors will be handled in reverse order.\n\t/// This is useful if the post-order will be reversed later (e.g. for a topological sort)\n\t/// so that blocks which could be output in either order (e.g. then-block and else-block of an if)\n\t/// will maintain the order of the edges (then-block before else-block).\n\t/// </param>\n\tpublic static void DepthFirstSearch<T>(IEnumerable<T> startNodes, Func<T, bool>? visitedFunc, Func<T, IEnumerable<T>?> successorFunc, Action<T>? postorderAction = null, bool reverseSuccessors = false)\n\t{\n\t\t/*\n        Pseudocode:\n            def dfs_walk(start_nodes, successor_func, visited, postorder_func, reverse_successors):\n                if reverse_successors:\n                    start_nodes = reversed(start_nodes)\n                for node in start_nodes:\n                    if node in visited: continue\n                    visited.insert(node)\n                    children = successor_func(node)\n                    dfs_walk(children, successor_func, visited, postorder_action, reverse_successors)\n                    postorder_action(node)\n        \n        The actual implementation here is equivalent but does not use recursion,\n        so that we don't blow the stack on large graphs.\n        A single stack holds the \"continuations\" of work that needs to be done.\n        These can be either \"visit continuations\" (=execute the body of the pseudocode\n        loop for the given node) or \"postorder continuations\" (=execute postorder_action)\n        */\n\t\t// Use a List as stack (but allowing for the Reverse() usage)\n\t\tvar worklist = new List<(T node, bool isPostOrderContinuation)>();\n\t\tvisitedFunc ??= new HashSet<T>().Add;\n\t\tforeach (T node in startNodes)\n\t\t{\n\t\t\tworklist.Add((node, false));\n\t\t}\n\t\tif (!reverseSuccessors)\n\t\t{\n\t\t\t// Our use of a stack will reverse the order of the nodes.\n\t\t\t// If that's not desired, restore original order by reversing twice.\n\t\t\tworklist.Reverse();\n\t\t}\n\t\t// Process outstanding continuations:\n\t\twhile (worklist.Count > 0)\n\t\t{\n\t\t\tvar (node, isPostOrderContinuation) = worklist.Last();\n\t\t\tif (isPostOrderContinuation)\n\t\t\t{\n\t\t\t\t// Execute postorder_action\n\t\t\t\tpostorderAction?.Invoke(node);\n\t\t\t\tworklist.RemoveAt(worklist.Count - 1);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// Execute body of loop\n\t\t\tif (!visitedFunc(node))\n\t\t\t{\n\t\t\t\t// Already visited\n\t\t\t\tworklist.RemoveAt(worklist.Count - 1);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// foreach-loop-iteration will end with postorder_func call,\n\t\t\t// so switch the type of continuation for this node\n\t\t\tint oldWorkListSize = worklist.Count;\n\t\t\tworklist[oldWorkListSize - 1] = (node, true);\n\t\t\t// Create \"visit continuations\" for all successor nodes:\n\t\t\tIEnumerable<T>? children = successorFunc(node);\n\t\t\tif (children != null)\n\t\t\t{\n\t\t\t\tforeach (T child in children)\n\t\t\t\t{\n\t\t\t\t\tworklist.Add((child, false));\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Our use of a stack will reverse the order of the nodes.\n\t\t\t// If that's not desired, restore original order by reversing twice.\n\t\t\tif (!reverseSuccessors)\n\t\t\t{\n\t\t\t\tworklist.Reverse(oldWorkListSize, worklist.Count - oldWorkListSize);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/Index.cs",
    "content": "// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n#nullable enable\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Runtime.CompilerServices;\n\nnamespace System\n{\n\t/// <summary>Represent a type can be used to index a collection either from the start or the end.</summary>\n\t/// <remarks>\n\t/// Index is used by the C# compiler to support the new index syntax\n\t/// <code>\n\t/// int[] someArray = new int[5] { 1, 2, 3, 4, 5 } ;\n\t/// int lastElement = someArray[^1]; // lastElement = 5\n\t/// </code>\n\t/// </remarks>\n#if SYSTEM_PRIVATE_CORELIB\n    public\n#else\n\tinternal\n#endif\n\treadonly struct Index : IEquatable<Index>\n\t{\n\t\tprivate readonly int _value;\n\n\t\t/// <summary>Construct an Index using a value and indicating if the index is from the start or from the end.</summary>\n\t\t/// <param name=\"value\">The index value. it has to be zero or positive number.</param>\n\t\t/// <param name=\"fromEnd\">Indicating if the index is from the start or from the end.</param>\n\t\t/// <remarks>\n\t\t/// If the Index constructed from the end, index value 1 means pointing at the last element and index value 0 means pointing at beyond last element.\n\t\t/// </remarks>\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic Index(int value, bool fromEnd = false)\n\t\t{\n\t\t\tif (value < 0)\n\t\t\t{\n\t\t\t\tThrowValueArgumentOutOfRange_NeedNonNegNumException();\n\t\t\t}\n\n\t\t\tif (fromEnd)\n\t\t\t\t_value = ~value;\n\t\t\telse\n\t\t\t\t_value = value;\n\t\t}\n\n\t\t// The following private constructors mainly created for perf reason to avoid the checks\n\t\tprivate Index(int value)\n\t\t{\n\t\t\t_value = value;\n\t\t}\n\n\t\t/// <summary>Create an Index pointing at first element.</summary>\n\t\tpublic static Index Start => new Index(0);\n\n\t\t/// <summary>Create an Index pointing at beyond last element.</summary>\n\t\tpublic static Index End => new Index(~0);\n\n\t\t/// <summary>Create an Index from the start at the position indicated by the value.</summary>\n\t\t/// <param name=\"value\">The index value from the start.</param>\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static Index FromStart(int value)\n\t\t{\n\t\t\tif (value < 0)\n\t\t\t{\n\t\t\t\tThrowValueArgumentOutOfRange_NeedNonNegNumException();\n\t\t\t}\n\n\t\t\treturn new Index(value);\n\t\t}\n\n\t\t/// <summary>Create an Index from the end at the position indicated by the value.</summary>\n\t\t/// <param name=\"value\">The index value from the end.</param>\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static Index FromEnd(int value)\n\t\t{\n\t\t\tif (value < 0)\n\t\t\t{\n\t\t\t\tThrowValueArgumentOutOfRange_NeedNonNegNumException();\n\t\t\t}\n\n\t\t\treturn new Index(~value);\n\t\t}\n\n\t\t/// <summary>Returns the index value.</summary>\n\t\tpublic int Value {\n\t\t\tget {\n\t\t\t\tif (_value < 0)\n\t\t\t\t\treturn ~_value;\n\t\t\t\telse\n\t\t\t\t\treturn _value;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>Indicates whether the index is from the start or the end.</summary>\n\t\tpublic bool IsFromEnd => _value < 0;\n\n\t\t/// <summary>Calculate the offset from the start using the giving collection length.</summary>\n\t\t/// <param name=\"length\">The length of the collection that the Index will be used with. length has to be a positive value</param>\n\t\t/// <remarks>\n\t\t/// For performance reason, we don't validate the input length parameter and the returned offset value against negative values.\n\t\t/// we don't validate either the returned offset is greater than the input length.\n\t\t/// It is expected Index will be used with collections which always have non negative length/count. If the returned offset is negative and\n\t\t/// then used to index a collection will get out of range exception which will be same affect as the validation.\n\t\t/// </remarks>\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic int GetOffset(int length)\n\t\t{\n\t\t\tint offset = _value;\n\t\t\tif (IsFromEnd)\n\t\t\t{\n\t\t\t\t// offset = length - (~value)\n\t\t\t\t// offset = length + (~(~value) + 1)\n\t\t\t\t// offset = length + value + 1\n\n\t\t\t\toffset += length + 1;\n\t\t\t}\n\t\t\treturn offset;\n\t\t}\n\n\t\t/// <summary>Indicates whether the current Index object is equal to another object of the same type.</summary>\n\t\t/// <param name=\"value\">An object to compare with this object</param>\n\t\tpublic override bool Equals([NotNullWhen(true)] object? value) => value is Index && _value == ((Index)value)._value;\n\n\t\t/// <summary>Indicates whether the current Index object is equal to another Index object.</summary>\n\t\t/// <param name=\"other\">An object to compare with this object</param>\n\t\tpublic bool Equals(Index other) => _value == other._value;\n\n\t\t/// <summary>Returns the hash code for this instance.</summary>\n\t\tpublic override int GetHashCode() => _value;\n\n\t\t/// <summary>Converts integer number to an Index.</summary>\n\t\tpublic static implicit operator Index(int value) => FromStart(value);\n\n\t\t/// <summary>Converts the value of the current Index object to its equivalent string representation.</summary>\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tif (IsFromEnd)\n\t\t\t\treturn ToStringFromEnd();\n\n\t\t\treturn ((uint)Value).ToString();\n\t\t}\n\n\t\tprivate static void ThrowValueArgumentOutOfRange_NeedNonNegNumException()\n\t\t{\n#if SYSTEM_PRIVATE_CORELIB\n            throw new ArgumentOutOfRangeException(\"value\", SR.ArgumentOutOfRange_NeedNonNegNum);\n#else\n\t\t\tthrow new ArgumentOutOfRangeException(\"value\", \"value must be non-negative\");\n#endif\n\t\t}\n\n\t\tprivate string ToStringFromEnd()\n\t\t{\n#if (!NETSTANDARD2_0 && !NETFRAMEWORK)\n            Span<char> span = stackalloc char[11]; // 1 for ^ and 10 for longest possible uint value\n            bool formatted = ((uint)Value).TryFormat(span.Slice(1), out int charsWritten);\n            Debug.Assert(formatted);\n            span[0] = '^';\n            return new string(span.Slice(0, charsWritten + 1));\n#else\n\t\t\treturn '^' + Value.ToString();\n#endif\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/Interval.cs",
    "content": "#nullable enable\n// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\t/// <summary>\n\t/// Represents a half-closed interval.\n\t/// The start position is inclusive; but the end position is exclusive.\n\t/// </summary>\n\t/// <remarks>\n\t/// Start &lt;= unchecked(End - 1): normal interval\n\t/// Start == End: empty interval\n\t/// Special case: Start == End == int.MinValue: interval containing all integers, not an empty interval!\n\t/// </remarks>\n\tpublic struct Interval : IEquatable<Interval>\n\t{\n\t\t/// <summary>\n\t\t/// Gets the inclusive start of the interval.\n\t\t/// </summary>\n\t\tpublic readonly int Start;\n\n\t\t/// <summary>\n\t\t/// Gets the exclusive end of the interval.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Note that an End of int.MinValue is a special case, and stands\n\t\t/// for an actual End of int.MaxValue+1.\n\t\t/// If possible, prefer using InclusiveEnd for comparisons, as that does not have an overflow problem.\n\t\t/// </remarks>\n\t\tpublic readonly int End;\n\n\t\t/// <summary>\n\t\t/// Creates a new interval.\n\t\t/// </summary>\n\t\t/// <param name=\"start\">Start position (inclusive)</param>\n\t\t/// <param name=\"end\">End position (exclusive).\n\t\t/// Note that it is possible to create an interval that includes int.MaxValue\n\t\t/// by using end==int.MaxValue+1==int.MinValue.</param>\n\t\tpublic Interval(int start, int end)\n\t\t{\n\t\t\tif (!(start <= unchecked(end - 1) || start == end))\n\t\t\t\tthrow new ArgumentException(\"The end must be after the start\", nameof(end));\n\t\t\tthis.Start = start;\n\t\t\tthis.End = end;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the inclusive end of the interval. (End - 1)\n\t\t/// For empty intervals, this returns Start - 1.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Because there is no empty interval at int.MinValue,\n\t\t/// (Start==End==int.MinValue is a special case referring to [int.MinValue..int.MaxValue]),\n\t\t/// integer overflow is not a problem here.\n\t\t/// </remarks>\n\t\tpublic int InclusiveEnd {\n\t\t\tget {\n\t\t\t\treturn unchecked(End - 1);\n\t\t\t}\n\t\t}\n\n\t\tpublic bool IsEmpty {\n\t\t\tget {\n\t\t\t\treturn Start > InclusiveEnd;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool Contains(int val)\n\t\t{\n\t\t\t// Use 'val <= InclusiveEnd' instead of 'val < End' to allow intervals to include int.MaxValue.\n\t\t\treturn Start <= val && val <= InclusiveEnd;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Calculates the intersection between this interval and the other interval.\n\t\t/// </summary>\n\t\tpublic Interval Intersect(Interval other)\n\t\t{\n\t\t\tint start = Math.Max(this.Start, other.Start);\n\t\t\tint inclusiveEnd = Math.Min(this.InclusiveEnd, other.InclusiveEnd);\n\t\t\tif (start <= inclusiveEnd)\n\t\t\t\treturn new Interval(start, unchecked(inclusiveEnd + 1));\n\t\t\telse\n\t\t\t\treturn default(Interval);\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tif (End == int.MinValue)\n\t\t\t\treturn string.Format(\"[{0}..int.MaxValue]\", Start);\n\t\t\telse\n\t\t\t\treturn string.Format(\"[{0}..{1})\", Start, End);\n\t\t}\n\n\t\t#region Equals and GetHashCode implementation\n\t\tpublic override bool Equals(object? obj)\n\t\t{\n\t\t\treturn (obj is Interval) && Equals((Interval)obj);\n\t\t}\n\n\t\tpublic bool Equals(Interval other)\n\t\t{\n\t\t\treturn this.Start == other.Start && this.End == other.End;\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn Start ^ End ^ (End << 7);\n\t\t}\n\n\t\tpublic static bool operator ==(Interval lhs, Interval rhs)\n\t\t{\n\t\t\treturn lhs.Equals(rhs);\n\t\t}\n\n\t\tpublic static bool operator !=(Interval lhs, Interval rhs)\n\t\t{\n\t\t\treturn !(lhs == rhs);\n\t\t}\n\t\t#endregion\n\t}\n\n\t/// <summary>\n\t/// Represents a half-closed interval.\n\t/// The start position is inclusive; but the end position is exclusive.\n\t/// </summary>\n\t/// <remarks>\n\t/// Start &lt;= unchecked(End - 1): normal interval\n\t/// Start == End: empty interval\n\t/// Special case: Start == End == long.MinValue: interval containing all integers, not an empty interval!\n\t/// </remarks>\n\tpublic struct LongInterval : IEquatable<LongInterval>\n\t{\n\t\t/// <summary>\n\t\t/// Gets the inclusive start of the interval.\n\t\t/// </summary>\n\t\tpublic readonly long Start;\n\n\t\t/// <summary>\n\t\t/// Gets the exclusive end of the interval.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Note that an End of long.MinValue is a special case, and stands\n\t\t/// for an actual End of long.MaxValue+1.\n\t\t/// If possible, prefer using InclusiveEnd for comparisons, as that does not have an overflow problem.\n\t\t/// </remarks>\n\t\tpublic readonly long End;\n\n\t\t/// <summary>\n\t\t/// Creates a new interval.\n\t\t/// </summary>\n\t\t/// <param name=\"start\">Start position (inclusive)</param>\n\t\t/// <param name=\"end\">End position (exclusive).\n\t\t/// Note that it is possible to create an interval that includes long.MaxValue\n\t\t/// by using end==long.MaxValue+1==long.MinValue.</param>\n\t\t/// <remarks>\n\t\t/// This method can be used to create an empty interval by specifying start==end,\n\t\t/// however this is error-prone due to the special case of\n\t\t/// start==end==long.MinValue being interpreted as the full interval [long.MinValue,long.MaxValue].\n\t\t/// </remarks>\n\t\tpublic LongInterval(long start, long end)\n\t\t{\n\t\t\tif (!(start <= unchecked(end - 1) || start == end))\n\t\t\t\tthrow new ArgumentException(\"The end must be after the start\", nameof(end));\n\t\t\tthis.Start = start;\n\t\t\tthis.End = end;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a new interval from start to end.\n\t\t/// Unlike the constructor where the end position is exclusive,\n\t\t/// this method interprets the end position as inclusive.\n\t\t/// \n\t\t/// This method cannot be used to construct an empty interval.\n\t\t/// </summary>\n\t\tpublic static LongInterval Inclusive(long start, long inclusiveEnd)\n\t\t{\n\t\t\tif (!(start <= inclusiveEnd))\n\t\t\t\tthrow new ArgumentException();\n\t\t\treturn new LongInterval(start, unchecked(inclusiveEnd + 1));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the inclusive end of the interval. (End - 1)\n\t\t/// For empty intervals, this returns Start - 1.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Because there is no empty interval at int.MinValue,\n\t\t/// (Start==End==int.MinValue is a special case referring to [int.MinValue..int.MaxValue]),\n\t\t/// integer overflow is not a problem here.\n\t\t/// </remarks>\n\t\tpublic long InclusiveEnd {\n\t\t\tget {\n\t\t\t\treturn unchecked(End - 1);\n\t\t\t}\n\t\t}\n\n\t\tpublic bool IsEmpty {\n\t\t\tget {\n\t\t\t\treturn Start > InclusiveEnd;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool Contains(long val)\n\t\t{\n\t\t\t// Use 'val <= InclusiveEnd' instead of 'val < End' to allow intervals to include long.MaxValue.\n\t\t\treturn Start <= val && val <= InclusiveEnd;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Calculates the intersection between this interval and the other interval.\n\t\t/// </summary>\n\t\tpublic LongInterval Intersect(LongInterval other)\n\t\t{\n\t\t\tlong start = Math.Max(this.Start, other.Start);\n\t\t\tlong inclusiveEnd = Math.Min(this.InclusiveEnd, other.InclusiveEnd);\n\t\t\tif (start <= inclusiveEnd)\n\t\t\t\treturn new LongInterval(start, unchecked(inclusiveEnd + 1));\n\t\t\telse\n\t\t\t\treturn default(LongInterval);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns an enumerator over all values in this interval.\n\t\t/// </summary>\n\t\tpublic IEnumerable<long> Range()\n\t\t{\n\t\t\tif (End == long.MinValue)\n\t\t\t{\n\t\t\t\tlong i = Start;\n\t\t\t\twhile (true)\n\t\t\t\t{\n\t\t\t\t\tyield return i;\n\t\t\t\t\tif (i == long.MaxValue)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfor (long i = Start; i < End; i++)\n\t\t\t\t\tyield return i;\n\t\t\t}\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\tif (End == long.MinValue)\n\t\t\t{\n\t\t\t\tif (Start == long.MinValue)\n\t\t\t\t\treturn \"[long.MinValue..long.MaxValue]\";\n\t\t\t\telse\n\t\t\t\t\treturn $\"[{Start}..long.MaxValue]\";\n\t\t\t}\n\t\t\telse if (Start == long.MinValue)\n\t\t\t{\n\t\t\t\treturn $\"[long.MinValue..{End})\";\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn $\"[{Start}..{End})\";\n\t\t\t}\n\t\t}\n\n\t\t#region Equals and GetHashCode implementation\n\t\tpublic override bool Equals(object? obj)\n\t\t{\n\t\t\treturn (obj is LongInterval) && Equals((LongInterval)obj);\n\t\t}\n\n\t\tpublic bool Equals(LongInterval other)\n\t\t{\n\t\t\treturn this.Start == other.Start && this.End == other.End;\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn (Start ^ End ^ (End << 7)).GetHashCode();\n\t\t}\n\n\t\tpublic static bool operator ==(LongInterval lhs, LongInterval rhs)\n\t\t{\n\t\t\treturn lhs.Equals(rhs);\n\t\t}\n\n\t\tpublic static bool operator !=(LongInterval lhs, LongInterval rhs)\n\t\t{\n\t\t\treturn !(lhs == rhs);\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/KeyComparer.cs",
    "content": "#nullable enable\n// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\tpublic static class KeyComparer\n\t{\n\t\tpublic static KeyComparer<TElement, TKey> Create<TElement, TKey>(Func<TElement, TKey> keySelector)\n\t\t{\n\t\t\treturn new KeyComparer<TElement, TKey>(keySelector, Comparer<TKey>.Default, EqualityComparer<TKey>.Default);\n\t\t}\n\n\t\tpublic static KeyComparer<TElement, TKey> Create<TElement, TKey>(Func<TElement, TKey> keySelector, IComparer<TKey> comparer, IEqualityComparer<TKey> equalityComparer)\n\t\t{\n\t\t\treturn new KeyComparer<TElement, TKey>(keySelector, comparer, equalityComparer);\n\t\t}\n\n\t\tpublic static IComparer<TElement> Create<TElement, TKey>(Func<TElement, TKey> keySelector, IComparer<TKey> comparer)\n\t\t{\n\t\t\treturn new KeyComparer<TElement, TKey>(keySelector, comparer, EqualityComparer<TKey>.Default);\n\t\t}\n\n\t\tpublic static IEqualityComparer<TElement> Create<TElement, TKey>(Func<TElement, TKey> keySelector, IEqualityComparer<TKey> equalityComparer)\n\t\t{\n\t\t\treturn new KeyComparer<TElement, TKey>(keySelector, Comparer<TKey>.Default, equalityComparer);\n\t\t}\n\n\t\tpublic static void SortBy<TElement, TKey>(this List<TElement> list, Func<TElement, TKey> keySelector)\n\t\t{\n\t\t\tlist.Sort(Create(keySelector));\n\t\t}\n\t}\n\n\tpublic class KeyComparer<TElement, TKey> : IComparer<TElement>, IEqualityComparer<TElement>\n\t{\n\t\treadonly Func<TElement, TKey> keySelector;\n\t\treadonly IComparer<TKey> keyComparer;\n\t\treadonly IEqualityComparer<TKey> keyEqualityComparer;\n\n\t\tpublic KeyComparer(Func<TElement, TKey> keySelector, IComparer<TKey> keyComparer, IEqualityComparer<TKey> keyEqualityComparer)\n\t\t{\n\t\t\tif (keySelector == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(keySelector));\n\t\t\tif (keyComparer == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(keyComparer));\n\t\t\tif (keyEqualityComparer == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(keyEqualityComparer));\n\t\t\tthis.keySelector = keySelector;\n\t\t\tthis.keyComparer = keyComparer;\n\t\t\tthis.keyEqualityComparer = keyEqualityComparer;\n\t\t}\n\n\t\tpublic int Compare(TElement? x, TElement? y)\n\t\t{\n\t\t\treturn keyComparer.Compare(keySelector(x!), keySelector(y!));\n\t\t}\n\n\t\tpublic bool Equals(TElement? x, TElement? y)\n\t\t{\n\t\t\treturn keyEqualityComparer.Equals(keySelector(x!), keySelector(y!));\n\t\t}\n\n\t\tpublic int GetHashCode(TElement obj)\n\t\t{\n\t\t\tvar key = keySelector(obj)!;\n\t\t\treturn keyEqualityComparer.GetHashCode(key);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/LazyInit.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\nusing System.Diagnostics.CodeAnalysis;\nusing System.Threading;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\tpublic static class LazyInit\n\t{\n\t\tpublic static T VolatileRead<T>(ref T location) where T : class?\n\t\t{\n\t\t\treturn Volatile.Read(ref location);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Atomically performs the following operation:\n\t\t/// - If target is null: stores newValue in target and returns newValue.\n\t\t/// - If target is not null: returns target.\n\t\t/// </summary>\n\t\t[return: NotNullIfNotNull(\"newValue\")]\n\t\tpublic static T? GetOrSet<T>(ref T? target, T? newValue) where T : class\n\t\t{\n\t\t\tT? oldValue = Interlocked.CompareExchange(ref target, newValue, null);\n\t\t\treturn oldValue ?? newValue;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/LongDict.cs",
    "content": "// Copyright (c) 2017 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\tstatic class LongDict\n\t{\n\t\tpublic static LongDict<T> Create<T>(IEnumerable<(LongSet, T)> entries)\n\t\t{\n\t\t\treturn new LongDict<T>(entries);\n\t\t}\n\n\t\tinternal static readonly KeyComparer<LongInterval, long> StartComparer = KeyComparer.Create((LongInterval i) => i.Start);\n\t}\n\n\t/// <summary>\n\t/// An immutable mapping from keys of type long to values of type T.\n\t/// </summary>\n\tstruct LongDict<T> : IEnumerable<KeyValuePair<LongInterval, T>>\n\t{\n\t\treadonly LongInterval[] keys;\n\t\treadonly T[] values;\n\n\t\t/// <summary>\n\t\t/// Creates a new LongDict from the given entries.\n\t\t/// If there are multiple entries for the same long key,\n\t\t/// the resulting LongDict will store the value from the first entry.\n\t\t/// </summary>\n\t\tpublic LongDict(IEnumerable<(LongSet, T)> entries)\n\t\t{\n\t\t\tLongSet available = LongSet.Universe;\n\t\t\tvar keys = new List<LongInterval>();\n\t\t\tvar values = new List<T>();\n\t\t\tforeach (var (key, val) in entries)\n\t\t\t{\n\t\t\t\tforeach (var interval in key.IntersectWith(available).Intervals)\n\t\t\t\t{\n\t\t\t\t\tkeys.Add(interval);\n\t\t\t\t\tvalues.Add(val);\n\t\t\t\t}\n\t\t\t\tavailable = available.ExceptWith(key);\n\t\t\t}\n\t\t\tthis.keys = keys.ToArray();\n\t\t\tthis.values = values.ToArray();\n\t\t\tArray.Sort(this.keys, this.values, LongDict.StartComparer);\n\t\t}\n\n\t\tpublic bool TryGetValue(long key, out T value)\n\t\t{\n\t\t\tint pos = Array.BinarySearch(this.keys, new LongInterval(key, key), LongDict.StartComparer);\n\t\t\t// If the element isn't found, BinarySearch returns the complement of \"insertion position\".\n\t\t\t// We use this to find the previous element (if there wasn't any exact match).\n\t\t\tif (pos < 0)\n\t\t\t\tpos = ~pos - 1;\n\t\t\tif (pos >= 0 && this.keys[pos].Contains(key))\n\t\t\t{\n\t\t\t\tvalue = this.values[pos];\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvalue = default(T);\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic T GetOrDefault(long key)\n\t\t{\n\t\t\tTryGetValue(key, out T val);\n\t\t\treturn val;\n\t\t}\n\n\t\tpublic IEnumerator<KeyValuePair<LongInterval, T>> GetEnumerator()\n\t\t{\n\t\t\tfor (int i = 0; i < this.keys.Length; ++i)\n\t\t\t{\n\t\t\t\tyield return new KeyValuePair<LongInterval, T>(this.keys[i], this.values[i]);\n\t\t\t}\n\t\t}\n\n\t\tIEnumerator IEnumerable.GetEnumerator()\n\t\t{\n\t\t\treturn GetEnumerator();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/LongSet.cs",
    "content": "#nullable enable\n// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Diagnostics;\nusing System.Linq;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\t/// <summary>\n\t/// An immutable set of longs, that is implemented as a list of intervals.\n\t/// </summary>\n\tpublic struct LongSet : IEquatable<LongSet>\n\t{\n\t\t/// <summary>\n\t\t/// The intervals in this set of longs.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Invariant: the intervals in this array are non-empty, non-overlapping, non-touching, and sorted.\n\t\t/// \n\t\t/// This invariant ensures every LongSet is always in a normalized representation.\n\t\t/// </remarks>\n\t\tpublic readonly ImmutableArray<LongInterval> Intervals;\n\n\t\tprivate LongSet(ImmutableArray<LongInterval> intervals)\n\t\t{\n\t\t\tthis.Intervals = intervals;\n#if DEBUG\n\t\t\t// Check invariant\n\t\t\tlong minValue = long.MinValue;\n\t\t\tfor (int i = 0; i < intervals.Length; i++)\n\t\t\t{\n\t\t\t\tDebug.Assert(!intervals[i].IsEmpty);\n\t\t\t\tDebug.Assert(minValue <= intervals[i].Start);\n\t\t\t\tif (intervals[i].InclusiveEnd == long.MaxValue - 1 || intervals[i].InclusiveEnd == long.MaxValue)\n\t\t\t\t{\n\t\t\t\t\t// An inclusive end of long.MaxValue-1 or long.MaxValue means (after the gap of 1 element),\n\t\t\t\t\t// there isn't any room for more non-empty intervals.\n\t\t\t\t\tDebug.Assert(i == intervals.Length - 1);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tminValue = checked(intervals[i].End + 1); // enforce least 1 gap between intervals\n\t\t\t\t}\n\t\t\t}\n#endif\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Create a new LongSet that contains a single value.\n\t\t/// </summary>\n\t\tpublic LongSet(long value)\n\t\t\t: this(ImmutableArray.Create(LongInterval.Inclusive(value, value)))\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Create a new LongSet that contains the values from the interval.\n\t\t/// </summary>\n\t\tpublic LongSet(LongInterval interval)\n\t\t\t: this(interval.IsEmpty ? Empty.Intervals : ImmutableArray.Create(interval))\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a new LongSet the contains the values from the specified intervals.\n\t\t/// </summary>\n\t\tpublic LongSet(IEnumerable<LongInterval> intervals)\n\t\t\t: this(MergeOverlapping(intervals.Where(i => !i.IsEmpty).OrderBy(i => i.Start)).ToImmutableArray())\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// The empty LongSet.\n\t\t/// </summary>\n\t\tpublic static readonly LongSet Empty = new LongSet(ImmutableArray.Create<LongInterval>());\n\n\t\t/// <summary>\n\t\t/// The LongSet that contains all possible long values.\n\t\t/// </summary>\n\t\tpublic static readonly LongSet Universe = new LongSet(LongInterval.Inclusive(long.MinValue, long.MaxValue));\n\n\t\tpublic bool IsEmpty {\n\t\t\tget { return Intervals.IsEmpty; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the number of values in this LongSet.\n\t\t/// Note: for <c>LongSet.Universe</c>, the number of values does not fit into <c>ulong</c>.\n\t\t/// Instead, this property returns the off-by-one value <c>ulong.MaxValue</c> to avoid overflow.\n\t\t/// </summary>\n\t\tpublic ulong Count()\n\t\t{\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\tulong count = 0;\n\t\t\t\tforeach (var interval in Intervals)\n\t\t\t\t{\n\t\t\t\t\tcount += (ulong)(interval.End - interval.Start);\n\t\t\t\t}\n\t\t\t\tif (count == 0 && !Intervals.IsEmpty)\n\t\t\t\t\treturn ulong.MaxValue;\n\t\t\t\telse\n\t\t\t\t\treturn count;\n\t\t\t}\n\t\t}\n\n\t\tIEnumerable<LongInterval> DoIntersectWith(LongSet other)\n\t\t{\n\t\t\tvar enumA = this.Intervals.GetEnumerator();\n\t\t\tvar enumB = other.Intervals.GetEnumerator();\n\t\t\tbool moreA = enumA.MoveNext();\n\t\t\tbool moreB = enumB.MoveNext();\n\t\t\twhile (moreA && moreB)\n\t\t\t{\n\t\t\t\tLongInterval a = enumA.Current;\n\t\t\t\tLongInterval b = enumB.Current;\n\t\t\t\tLongInterval intersection = a.Intersect(b);\n\t\t\t\tif (!intersection.IsEmpty)\n\t\t\t\t{\n\t\t\t\t\tyield return intersection;\n\t\t\t\t}\n\t\t\t\tif (a.InclusiveEnd < b.InclusiveEnd)\n\t\t\t\t{\n\t\t\t\t\tmoreA = enumA.MoveNext();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tmoreB = enumB.MoveNext();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic bool Overlaps(LongSet other)\n\t\t{\n\t\t\treturn DoIntersectWith(other).Any();\n\t\t}\n\n\t\tpublic LongSet IntersectWith(LongSet other)\n\t\t{\n\t\t\treturn new LongSet(DoIntersectWith(other).ToImmutableArray());\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Given an enumerable of non-empty intervals sorted by the starting position,\n\t\t/// merges overlapping or touching intervals to create a valid interval array for LongSet.\n\t\t/// </summary>\n\t\tstatic IEnumerable<LongInterval> MergeOverlapping(IEnumerable<LongInterval> input)\n\t\t{\n\t\t\tlong start = long.MinValue;\n\t\t\tlong end = long.MinValue;\n\t\t\tbool empty = true;\n\t\t\tforeach (var element in input)\n\t\t\t{\n\t\t\t\tDebug.Assert(start <= element.Start);\n\t\t\t\tDebug.Assert(!element.IsEmpty);\n\n\t\t\t\tif (!empty && element.Start <= end)\n\t\t\t\t{\n\t\t\t\t\t// element overlaps or touches [start, end), so combine the intervals:\n\t\t\t\t\tif (element.End == long.MinValue)\n\t\t\t\t\t{\n\t\t\t\t\t\t// special case: element goes all the way up to long.MaxValue inclusive\n\t\t\t\t\t\tend = long.MinValue;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tend = Math.Max(end, element.End);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// flush existing interval:\n\t\t\t\t\tif (!empty)\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return new LongInterval(start, end);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tempty = false;\n\t\t\t\t\t}\n\t\t\t\t\tstart = element.Start;\n\t\t\t\t\tend = element.End;\n\t\t\t\t}\n\t\t\t\tif (end == long.MinValue)\n\t\t\t\t{\n\t\t\t\t\t// special case: element goes all the way up to long.MaxValue inclusive\n\t\t\t\t\t// all further intervals in the input must be contained in [start, end),\n\t\t\t\t\t// so ignore them (and avoid trouble due to the overflow in `end`).\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!empty)\n\t\t\t{\n\t\t\t\tyield return new LongInterval(start, end);\n\t\t\t}\n\t\t}\n\n\t\tpublic LongSet UnionWith(LongSet other)\n\t\t{\n\t\t\tvar mergedIntervals = this.Intervals.Merge(other.Intervals, (a, b) => a.Start.CompareTo(b.Start));\n\t\t\treturn new LongSet(MergeOverlapping(mergedIntervals).ToImmutableArray());\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a new LongSet where val is added to each element of this LongSet.\n\t\t/// </summary>\n\t\tpublic LongSet AddOffset(long val)\n\t\t{\n\t\t\tif (val == 0)\n\t\t\t{\n\t\t\t\treturn this;\n\t\t\t}\n\t\t\tvar newIntervals = new List<LongInterval>(Intervals.Length + 1);\n\t\t\tforeach (var element in Intervals)\n\t\t\t{\n\t\t\t\tlong newStart = unchecked(element.Start + val);\n\t\t\t\tlong newInclusiveEnd = unchecked(element.InclusiveEnd + val);\n\t\t\t\tif (newStart <= newInclusiveEnd)\n\t\t\t\t{\n\t\t\t\t\tnewIntervals.Add(LongInterval.Inclusive(newStart, newInclusiveEnd));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// interval got split by integer overflow\n\t\t\t\t\tnewIntervals.Add(LongInterval.Inclusive(newStart, long.MaxValue));\n\t\t\t\t\tnewIntervals.Add(LongInterval.Inclusive(long.MinValue, newInclusiveEnd));\n\t\t\t\t}\n\t\t\t}\n\t\t\tnewIntervals.Sort((a, b) => a.Start.CompareTo(b.Start));\n\t\t\treturn new LongSet(MergeOverlapping(newIntervals).ToImmutableArray());\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a new set that contains all values that are in <c>this</c>, but not in <c>other</c>.\n\t\t/// </summary>\n\t\tpublic LongSet ExceptWith(LongSet other)\n\t\t{\n\t\t\treturn IntersectWith(other.Invert());\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a new LongSet that contains all elements not contained in this LongSet.\n\t\t/// </summary>\n\t\tpublic LongSet Invert()\n\t\t{\n\t\t\t// The loop below assumes a non-empty LongSet, so handle the empty case specially.\n\t\t\tif (IsEmpty)\n\t\t\t{\n\t\t\t\treturn Universe;\n\t\t\t}\n\t\t\tList<LongInterval> newIntervals = new List<LongInterval>(Intervals.Length + 1);\n\t\t\tlong prevEnd = long.MinValue; // previous exclusive end\n\t\t\tforeach (var interval in Intervals)\n\t\t\t{\n\t\t\t\tif (interval.Start > prevEnd)\n\t\t\t\t{\n\t\t\t\t\tnewIntervals.Add(new LongInterval(prevEnd, interval.Start));\n\t\t\t\t}\n\t\t\t\tprevEnd = interval.End;\n\t\t\t}\n\t\t\t// create a final interval up to long.MaxValue inclusive\n\t\t\tif (prevEnd != long.MinValue)\n\t\t\t{\n\t\t\t\tnewIntervals.Add(new LongInterval(prevEnd, long.MinValue));\n\t\t\t}\n\t\t\treturn new LongSet(newIntervals.ToImmutableArray());\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this set is a subset of other, or equal.\n\t\t/// </summary>\n\t\tpublic bool IsSubsetOf(LongSet other)\n\t\t{\n\t\t\t// TODO: optimize IsSubsetOf -- there's no need to build a temporary set\n\t\t\treturn this.UnionWith(other).SetEquals(other);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether this set is a superset of other, or equal.\n\t\t/// </summary>\n\t\tpublic bool IsSupersetOf(LongSet other)\n\t\t{\n\t\t\treturn other.IsSubsetOf(this);\n\t\t}\n\n\t\tpublic bool IsProperSubsetOf(LongSet other)\n\t\t{\n\t\t\treturn IsSubsetOf(other) && !SetEquals(other);\n\t\t}\n\n\t\tpublic bool IsProperSupersetOf(LongSet other)\n\t\t{\n\t\t\treturn IsSupersetOf(other) && !SetEquals(other);\n\t\t}\n\n\t\tpublic bool Contains(long val)\n\t\t{\n\t\t\tint index = upper_bound(val);\n\t\t\treturn index > 0 && Intervals[index - 1].Contains(val);\n\t\t}\n\n\t\tinternal int upper_bound(long val)\n\t\t{\n\t\t\tint min = 0, max = Intervals.Length - 1;\n\t\t\twhile (max >= min)\n\t\t\t{\n\t\t\t\tint m = min + (max - min) / 2;\n\t\t\t\tLongInterval i = Intervals[m];\n\t\t\t\tif (val < i.Start)\n\t\t\t\t{\n\t\t\t\t\tmax = m - 1;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (val > i.End)\n\t\t\t\t{\n\t\t\t\t\tmin = m + 1;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\treturn m + 1;\n\t\t\t}\n\t\t\treturn min;\n\t\t}\n\n\t\tpublic IEnumerable<long> Values {\n\t\t\tget { return Intervals.SelectMany(i => i.Range()); }\n\t\t}\n\n\t\tpublic LongInterval ContainingInterval()\n\t\t{\n\t\t\tif (IsEmpty)\n\t\t\t\treturn default;\n\t\t\treturn new LongInterval(Intervals[0].Start, Intervals[Intervals.Length - 1].End);\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Join(\",\", Intervals);\n\t\t}\n\n\t\t#region Equals and GetHashCode implementation\n\t\tpublic override bool Equals(object? obj)\n\t\t{\n\t\t\treturn obj is LongSet && SetEquals((LongSet)obj);\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\t[Obsolete(\"Explicitly call SetEquals() instead.\")]\n\t\tpublic bool Equals(LongSet other)\n\t\t{\n\t\t\treturn SetEquals(other);\n\t\t}\n\n\t\tpublic bool SetEquals(LongSet other)\n\t\t{\n\t\t\tif (Intervals.Length != other.Intervals.Length)\n\t\t\t\treturn false;\n\t\t\tfor (int i = 0; i < Intervals.Length; i++)\n\t\t\t{\n\t\t\t\tif (Intervals[i] != other.Intervals[i])\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/MultiDictionary.cs",
    "content": "#nullable enable\n// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\t/// <summary>\n\t/// A dictionary that allows multiple pairs with the same key.\n\t/// </summary>\n\tpublic class MultiDictionary<TKey, TValue> : ILookup<TKey, TValue> where TKey : notnull\n\t{\n\t\treadonly Dictionary<TKey, List<TValue>> dict;\n\n\t\tpublic MultiDictionary()\n\t\t{\n\t\t\tdict = new Dictionary<TKey, List<TValue>>();\n\t\t}\n\n\t\tpublic MultiDictionary(IEqualityComparer<TKey>? comparer)\n\t\t{\n\t\t\tdict = new Dictionary<TKey, List<TValue>>(comparer);\n\t\t}\n\n\t\tpublic void Add(TKey key, TValue value)\n\t\t{\n\t\t\tif (!dict.TryGetValue(key, out List<TValue>? valueList))\n\t\t\t{\n\t\t\t\tvalueList = new List<TValue>();\n\t\t\t\tdict.Add(key, valueList);\n\t\t\t}\n\t\t\tvalueList.Add(value);\n\t\t}\n\n\t\tpublic bool Remove(TKey key, TValue value)\n\t\t{\n\t\t\tif (dict.TryGetValue(key, out List<TValue>? valueList))\n\t\t\t{\n\t\t\t\tif (valueList.Remove(value))\n\t\t\t\t{\n\t\t\t\t\tif (valueList.Count == 0)\n\t\t\t\t\t\tdict.Remove(key);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Removes all entries with the specified key.\n\t\t/// </summary>\n\t\t/// <returns>Returns true if at least one entry was removed.</returns>\n\t\tpublic bool RemoveAll(TKey key)\n\t\t{\n\t\t\treturn dict.Remove(key);\n\t\t}\n\n\t\tpublic void Clear()\n\t\t{\n\t\t\tdict.Clear();\n\t\t}\n\n\t\tpublic IReadOnlyList<TValue> this[TKey key] {\n\t\t\tget {\n\t\t\t\tif (dict.TryGetValue(key, out var list))\n\t\t\t\t\treturn list;\n\t\t\t\telse\n\t\t\t\t\treturn EmptyList<TValue>.Instance;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool TryGetValues(TKey key, out IReadOnlyList<TValue> values)\n\t\t{\n\t\t\tvalues = EmptyList<TValue>.Instance;\n\t\t\tif (dict.TryGetValue(key, out var list))\n\t\t\t{\n\t\t\t\tvalues = list;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the number of different keys.\n\t\t/// </summary>\n\t\tpublic int Count {\n\t\t\tget { return dict.Count; }\n\t\t}\n\n\t\tpublic ICollection<TKey> Keys {\n\t\t\tget { return dict.Keys; }\n\t\t}\n\n\t\tpublic IEnumerable<TValue> Values {\n\t\t\tget { return dict.Values.SelectMany(list => list); }\n\t\t}\n\n\t\tIEnumerable<TValue> ILookup<TKey, TValue>.this[TKey key] {\n\t\t\tget { return this[key]; }\n\t\t}\n\n\t\tpublic bool Contains(TKey key)\n\t\t{\n\t\t\treturn dict.ContainsKey(key);\n\t\t}\n\n\t\tpublic IEnumerator<IGrouping<TKey, TValue>> GetEnumerator()\n\t\t{\n\t\t\tforeach (var pair in dict)\n\t\t\t\tyield return new Grouping(pair.Key, pair.Value);\n\t\t}\n\n\t\tSystem.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\n\t\t{\n\t\t\treturn GetEnumerator();\n\t\t}\n\n\t\tsealed class Grouping : IGrouping<TKey, TValue>\n\t\t{\n\t\t\treadonly TKey key;\n\t\t\treadonly List<TValue> values;\n\n\t\t\tpublic Grouping(TKey key, List<TValue> values)\n\t\t\t{\n\t\t\t\tthis.key = key;\n\t\t\t\tthis.values = values;\n\t\t\t}\n\n\t\t\tpublic TKey Key {\n\t\t\t\tget { return key; }\n\t\t\t}\n\n\t\t\tpublic IEnumerator<TValue> GetEnumerator()\n\t\t\t{\n\t\t\t\treturn values.GetEnumerator();\n\t\t\t}\n\n\t\t\tSystem.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\n\t\t\t{\n\t\t\t\treturn values.GetEnumerator();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/Platform.cs",
    "content": "#nullable enable\n// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\t/// <summary>\n\t/// Platform-specific code.\n\t/// </summary>\n\tpublic static class Platform\n\t{\n\t\tpublic static StringComparer FileNameComparer {\n\t\t\tget {\n\t\t\t\tswitch (Environment.OSVersion.Platform)\n\t\t\t\t{\n\t\t\t\t\tcase PlatformID.Unix:\n\t\t\t\t\tcase PlatformID.MacOSX:\n\t\t\t\t\t\treturn StringComparer.Ordinal;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn StringComparer.OrdinalIgnoreCase;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/ProjectedList.cs",
    "content": "#nullable enable\n// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\tpublic sealed class ProjectedList<TInput, TOutput> : IReadOnlyList<TOutput> where TOutput : class\n\t{\n\t\treadonly IList<TInput> input;\n\t\treadonly Func<TInput, TOutput> projection;\n\t\treadonly TOutput?[] items;\n\n\t\tpublic ProjectedList(IList<TInput> input, Func<TInput, TOutput> projection)\n\t\t{\n\t\t\tif (input == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(input));\n\t\t\tif (projection == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(projection));\n\t\t\tthis.input = input;\n\t\t\tthis.projection = projection;\n\t\t\tthis.items = new TOutput?[input.Count];\n\t\t}\n\n\t\tpublic TOutput this[int index] {\n\t\t\tget {\n\t\t\t\tTOutput? output = LazyInit.VolatileRead(ref items[index]);\n\t\t\t\tif (output != null)\n\t\t\t\t{\n\t\t\t\t\treturn output;\n\t\t\t\t}\n\t\t\t\treturn LazyInit.GetOrSet(ref items[index], projection(input[index]));\n\t\t\t}\n\t\t}\n\n\t\tpublic int Count {\n\t\t\tget { return items.Length; }\n\t\t}\n\n\t\tpublic IEnumerator<TOutput> GetEnumerator()\n\t\t{\n\t\t\tfor (int i = 0; i < this.Count; i++)\n\t\t\t{\n\t\t\t\tyield return this[i];\n\t\t\t}\n\t\t}\n\n\t\tSystem.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\n\t\t{\n\t\t\treturn GetEnumerator();\n\t\t}\n\t}\n\n\tpublic sealed class ProjectedList<TContext, TInput, TOutput> : IReadOnlyList<TOutput> where TOutput : class\n\t{\n\t\treadonly IList<TInput> input;\n\t\treadonly TContext context;\n\t\treadonly Func<TContext, TInput, TOutput> projection;\n\t\treadonly TOutput?[] items;\n\n\t\tpublic ProjectedList(TContext context, IList<TInput> input, Func<TContext, TInput, TOutput> projection)\n\t\t{\n\t\t\tif (input == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(input));\n\t\t\tif (projection == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(projection));\n\t\t\tthis.input = input;\n\t\t\tthis.context = context;\n\t\t\tthis.projection = projection;\n\t\t\tthis.items = new TOutput?[input.Count];\n\t\t}\n\n\t\tpublic TOutput this[int index] {\n\t\t\tget {\n\t\t\t\tTOutput? output = LazyInit.VolatileRead(ref items[index]);\n\t\t\t\tif (output != null)\n\t\t\t\t{\n\t\t\t\t\treturn output;\n\t\t\t\t}\n\t\t\t\treturn LazyInit.GetOrSet(ref items[index], projection(context, input[index]));\n\t\t\t}\n\t\t}\n\n\t\tpublic int Count {\n\t\t\tget { return items.Length; }\n\t\t}\n\n\t\tpublic IEnumerator<TOutput> GetEnumerator()\n\t\t{\n\t\t\tfor (int i = 0; i < this.Count; i++)\n\t\t\t{\n\t\t\t\tyield return this[i];\n\t\t\t}\n\t\t}\n\n\t\tSystem.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\n\t\t{\n\t\t\treturn GetEnumerator();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/ReferenceComparer.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n#nullable enable\n\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\tpublic sealed class ReferenceComparer : IEqualityComparer<object?>\n\t{\n\t\tpublic readonly static ReferenceComparer Instance = new ReferenceComparer();\n\n\t\tpublic new bool Equals(object? x, object? y)\n\t\t{\n\t\t\treturn x == y;\n\t\t}\n\n\t\tpublic int GetHashCode(object? obj)\n\t\t{\n\t\t\treturn RuntimeHelpers.GetHashCode(obj);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/ResXResourceWriter.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n//   This file is based on the Mono implementation of ResXResourceWriter.\n//   It is modified to add support for \"ResourceSerializedObject\" values.\n//\n// Permission is hereby granted, free of charge, to any person obtaining\n// a copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to\n// permit persons to whom the Software is furnished to do so, subject to\n// the following conditions:\n// \n// The above copyright notice and this permission notice shall be\n// included in all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n//\n// Copyright (c) 2004-2005 Novell, Inc.\n//\n// Authors:\n//\tDuncan Mak\t\tduncan@ximian.com\n//\tGonzalo Paniagua Javier\tgonzalo@ximian.com\n//\tPeter Bartok\t\tpbartok@novell.com\n//\tGary Barnett\t\tgary.barnett.mono@gmail.com\n//\tincludes code by Mike Krüger and Lluis Sanchez\n\nusing System;\nusing System.Globalization;\nusing System.IO;\nusing System.Text;\nusing System.Xml;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n#if INSIDE_SYSTEM_WEB\n\tinternal\n#else\n\tpublic\n#endif\n\tclass ResXResourceWriter : IDisposable\n\t{\n\t\tprivate string filename;\n\t\tprivate Stream stream;\n\t\tprivate TextWriter textwriter;\n\t\tprivate XmlTextWriter writer;\n\t\tprivate bool written;\n\t\tprivate string base_path;\n\n\t\tpublic static readonly string BinSerializedObjectMimeType = \"application/x-microsoft.net.object.binary.base64\";\n\t\tpublic static readonly string ByteArraySerializedObjectMimeType = \"application/x-microsoft.net.object.bytearray.base64\";\n\t\tpublic static readonly string DefaultSerializedObjectMimeType = BinSerializedObjectMimeType;\n\t\tpublic static readonly string ResMimeType = \"text/microsoft-resx\";\n\t\tpublic static readonly string SoapSerializedObjectMimeType = \"application/x-microsoft.net.object.soap.base64\";\n\t\tpublic static readonly string Version = \"2.0\";\n\n\t\tpublic ResXResourceWriter(Stream stream)\n\t\t{\n\t\t\tif (stream == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(stream));\n\n\t\t\tif (!stream.CanWrite)\n\t\t\t\tthrow new ArgumentException(\"stream is not writable.\", nameof(stream));\n\n\t\t\tthis.stream = stream;\n\t\t}\n\n\t\tpublic ResXResourceWriter(TextWriter textWriter)\n\t\t{\n\t\t\tif (textWriter == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(textWriter));\n\n\t\t\tthis.textwriter = textWriter;\n\t\t}\n\n\t\tpublic ResXResourceWriter(string fileName)\n\t\t{\n\t\t\tif (fileName == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(fileName));\n\n\t\t\tthis.filename = fileName;\n\t\t}\n\n\t\t~ResXResourceWriter()\n\t\t{\n\t\t\tDispose(false);\n\t\t}\n\n\t\tconst string WinFormsAssemblyName = \", System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\";\n\t\tconst string MSCorLibAssemblyName = \", mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\";\n\t\tconst string ResXNullRefTypeName = \"System.Resources.ResXNullRef\" + WinFormsAssemblyName;\n\n\t\tvoid InitWriter()\n\t\t{\n\t\t\tif (filename != null)\n\t\t\t\tstream = File.Open(filename, FileMode.Create);\n\t\t\tif (textwriter == null)\n\t\t\t\ttextwriter = new StreamWriter(stream, Encoding.UTF8);\n\n\t\t\twriter = new XmlTextWriter(textwriter);\n\t\t\twriter.Formatting = Formatting.Indented;\n\t\t\twriter.WriteStartDocument();\n\t\t\twriter.WriteStartElement(\"root\");\n\t\t\twriter.WriteRaw(schema);\n\t\t\tWriteHeader(\"resmimetype\", \"text/microsoft-resx\");\n\t\t\tWriteHeader(\"version\", \"1.3\");\n\t\t\tWriteHeader(\"reader\", \"System.Resources.ResXResourceReader\" + WinFormsAssemblyName);\n\t\t\tWriteHeader(\"writer\", \"System.Resources.ResXResourceWriter\" + WinFormsAssemblyName);\n\t\t}\n\n\t\tvoid WriteHeader(string name, string value)\n\t\t{\n\t\t\twriter.WriteStartElement(\"resheader\");\n\t\t\twriter.WriteAttributeString(\"name\", name);\n\t\t\twriter.WriteStartElement(\"value\");\n\t\t\twriter.WriteString(value);\n\t\t\twriter.WriteEndElement();\n\t\t\twriter.WriteEndElement();\n\t\t}\n\n\t\tvoid WriteNiceBase64(byte[] value, int offset, int length)\n\t\t{\n\t\t\tstring base64 = Convert.ToBase64String(\n\t\t\t\tvalue, offset, length,\n\t\t\t\tBase64FormattingOptions.InsertLineBreaks);\n\t\t\twriter.WriteString(base64);\n\t\t}\n\n\t\tvoid WriteBytes(string name, string type, byte[] value, int offset, int length, string comment)\n\t\t{\n\t\t\twriter.WriteStartElement(\"data\");\n\t\t\twriter.WriteAttributeString(\"name\", name);\n\n\t\t\tif (type != null)\n\t\t\t{\n\t\t\t\twriter.WriteAttributeString(\"type\", type);\n\t\t\t\t// byte[] should never get a mimetype, otherwise MS.NET won't be able\n\t\t\t\t// to parse the data.\n\t\t\t\tif (type != \"System.Byte[]\" + MSCorLibAssemblyName)\n\t\t\t\t\twriter.WriteAttributeString(\"mimetype\", ByteArraySerializedObjectMimeType);\n\t\t\t\twriter.WriteStartElement(\"value\");\n\t\t\t\tWriteNiceBase64(value, offset, length);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\twriter.WriteAttributeString(\"mimetype\", BinSerializedObjectMimeType);\n\t\t\t\twriter.WriteStartElement(\"value\");\n\t\t\t\tWriteNiceBase64(value, offset, length);\n\t\t\t}\n\n\t\t\twriter.WriteEndElement();\n\n\t\t\tif (!string.IsNullOrEmpty(comment))\n\t\t\t{\n\t\t\t\twriter.WriteStartElement(\"comment\");\n\t\t\t\twriter.WriteString(comment);\n\t\t\t\twriter.WriteEndElement();\n\t\t\t}\n\n\t\t\twriter.WriteEndElement();\n\t\t}\n\n\t\tvoid WriteString(string name, string value, string type, string comment)\n\t\t{\n\t\t\twriter.WriteStartElement(\"data\");\n\t\t\twriter.WriteAttributeString(\"name\", name);\n\t\t\tif (type != null)\n\t\t\t{\n\t\t\t\twriter.WriteAttributeString(\"type\", type);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\twriter.WriteAttributeString(\"xml:space\", \"preserve\");\n\t\t\t}\n\t\t\twriter.WriteStartElement(\"value\");\n\t\t\twriter.WriteString(value);\n\t\t\twriter.WriteEndElement();\n\t\t\tif (!string.IsNullOrEmpty(comment))\n\t\t\t{\n\t\t\t\twriter.WriteStartElement(\"comment\");\n\t\t\t\twriter.WriteString(comment);\n\t\t\t\twriter.WriteEndElement();\n\t\t\t}\n\t\t\twriter.WriteEndElement();\n\t\t\twriter.WriteWhitespace(\"\\n  \");\n\t\t}\n\n\t\tpublic void AddResource(string name, byte[] value)\n\t\t{\n\t\t\tAddResource(name, value, string.Empty);\n\t\t}\n\n\t\tpublic void AddResource(string name, object value)\n\t\t{\n\t\t\tAddResource(name, value, string.Empty);\n\t\t}\n\n\t\tprivate void AddResource(string name, object value, string comment)\n\t\t{\n\t\t\tif (name == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(name));\n\n\t\t\tif (written)\n\t\t\t\tthrow new InvalidOperationException(\"The resource is already generated.\");\n\n\t\t\tif (writer == null)\n\t\t\t\tInitWriter();\n\n\t\t\tswitch (value)\n\t\t\t{\n\t\t\t\tcase null:\n\t\t\t\t\t// nulls written as ResXNullRef\n\t\t\t\t\tWriteString(name, \"\", ResXNullRefTypeName, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tcase string s:\n\t\t\t\t\tWriteString(name, s, null, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tcase bool bo:\n\t\t\t\t\tWriteString(name, bo.ToString(CultureInfo.InvariantCulture), \"System.Boolean\" + MSCorLibAssemblyName, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tcase char ch:\n\t\t\t\t\tWriteString(name, ch.ToString(CultureInfo.InvariantCulture), \"System.Char\" + MSCorLibAssemblyName, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tcase sbyte sb:\n\t\t\t\t\tWriteString(name, sb.ToString(CultureInfo.InvariantCulture), \"System.SByte\" + MSCorLibAssemblyName, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tcase byte b:\n\t\t\t\t\tWriteString(name, b.ToString(CultureInfo.InvariantCulture), \"System.Byte\" + MSCorLibAssemblyName, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tcase short sh:\n\t\t\t\t\tWriteString(name, sh.ToString(CultureInfo.InvariantCulture), \"System.Int16\" + MSCorLibAssemblyName, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ushort ush:\n\t\t\t\t\tWriteString(name, ush.ToString(CultureInfo.InvariantCulture), \"System.UInt16\" + MSCorLibAssemblyName, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tcase int i:\n\t\t\t\t\tWriteString(name, i.ToString(CultureInfo.InvariantCulture), \"System.Int32\" + MSCorLibAssemblyName, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tcase uint u:\n\t\t\t\t\tWriteString(name, u.ToString(CultureInfo.InvariantCulture), \"System.UInt32\" + MSCorLibAssemblyName, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tcase long l:\n\t\t\t\t\tWriteString(name, l.ToString(CultureInfo.InvariantCulture), \"System.Int64\" + MSCorLibAssemblyName, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ulong ul:\n\t\t\t\t\tWriteString(name, ul.ToString(CultureInfo.InvariantCulture), \"System.UInt64\" + MSCorLibAssemblyName, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tcase float f:\n\t\t\t\t\tWriteString(name, f.ToString(CultureInfo.InvariantCulture), \"System.Single\" + MSCorLibAssemblyName, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tcase double d:\n\t\t\t\t\tWriteString(name, d.ToString(CultureInfo.InvariantCulture), \"System.Double\" + MSCorLibAssemblyName, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tcase decimal m:\n\t\t\t\t\tWriteString(name, m.ToString(CultureInfo.InvariantCulture), \"System.Decimal\" + MSCorLibAssemblyName, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tcase DateTime dt:\n\t\t\t\t\tWriteString(name, dt.ToString(CultureInfo.InvariantCulture), \"System.DateTime\" + MSCorLibAssemblyName, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TimeSpan sp:\n\t\t\t\t\tWriteString(name, sp.ToString(), \"System.TimeSpan\" + MSCorLibAssemblyName, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tcase byte[] array:\n\t\t\t\t\tWriteBytes(name, \"System.Byte[]\" + MSCorLibAssemblyName, array, 0, array.Length, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tcase MemoryStream memoryStream:\n\t\t\t\t\tvar arr = memoryStream.ToArray();\n\t\t\t\t\tWriteBytes(name, null, arr, 0, arr.Length, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ResourceSerializedObject rso:\n\t\t\t\t\tvar bytes = rso.GetBytes();\n\t\t\t\t\tWriteBytes(name, rso.TypeName, bytes, 0, bytes.Length, comment);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException($\"Value '{value}' of type {value.GetType().FullName} is not supported by this version of ResXResourceWriter. Use byte arrays or streams instead.\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void AddResource(string name, string value)\n\t\t{\n\t\t\tAddResource(name, value, string.Empty);\n\t\t}\n\n\t\tpublic void Close()\n\t\t{\n\t\t\tif (writer != null)\n\t\t\t{\n\t\t\t\tif (!written)\n\t\t\t\t{\n\t\t\t\t\tGenerate();\n\t\t\t\t}\n\n\t\t\t\twriter.Close();\n\t\t\t\tstream = null;\n\t\t\t\tfilename = null;\n\t\t\t\ttextwriter = null;\n\t\t\t}\n\t\t}\n\n\t\tpublic virtual void Dispose()\n\t\t{\n\t\t\tDispose(true);\n\t\t\tGC.SuppressFinalize(this);\n\t\t}\n\n\t\tpublic void Generate()\n\t\t{\n\t\t\tif (writer == null)\n\t\t\t\tInitWriter();\n\n\t\t\tif (written)\n\t\t\t\tthrow new InvalidOperationException(\"The resource is already generated.\");\n\n\t\t\twritten = true;\n\t\t\twriter.WriteEndElement();\n\t\t\twriter.Flush();\n\t\t}\n\n\t\tprotected virtual void Dispose(bool disposing)\n\t\t{\n\t\t\tif (disposing)\n\t\t\t\tClose();\n\t\t}\n\n\t\tstatic readonly string schema = @\"\n\t<xsd:schema id='root' xmlns='' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:msdata='urn:schemas-microsoft-com:xml-msdata'>\n\t\t<xsd:element name='root' msdata:IsDataSet='true'>\n\t\t\t<xsd:complexType>\n\t\t\t\t<xsd:choice maxOccurs='unbounded'>\n\t\t\t\t\t<xsd:element name='data'>\n\t\t\t\t\t\t<xsd:complexType>\n\t\t\t\t\t\t\t<xsd:sequence>\n\t\t\t\t\t\t\t\t<xsd:element name='value' type='xsd:string' minOccurs='0' msdata:Ordinal='1' />\n\t\t\t\t\t\t\t\t<xsd:element name='comment' type='xsd:string' minOccurs='0' msdata:Ordinal='2' />\n\t\t\t\t\t\t\t</xsd:sequence>\n\t\t\t\t\t\t\t<xsd:attribute name='name' type='xsd:string' msdata:Ordinal='1' />\n\t\t\t\t\t\t\t<xsd:attribute name='type' type='xsd:string' msdata:Ordinal='3' />\n\t\t\t\t\t\t\t<xsd:attribute name='mimetype' type='xsd:string' msdata:Ordinal='4' />\n\t\t\t\t\t\t</xsd:complexType>\n\t\t\t\t\t</xsd:element>\n\t\t\t\t\t<xsd:element name='resheader'>\n\t\t\t\t\t\t<xsd:complexType>\n\t\t\t\t\t\t\t<xsd:sequence>\n\t\t\t\t\t\t\t\t<xsd:element name='value' type='xsd:string' minOccurs='0' msdata:Ordinal='1' />\n\t\t\t\t\t\t\t</xsd:sequence>\n\t\t\t\t\t\t\t<xsd:attribute name='name' type='xsd:string' use='required' />\n\t\t\t\t\t\t</xsd:complexType>\n\t\t\t\t\t</xsd:element>\n\t\t\t\t</xsd:choice>\n\t\t\t</xsd:complexType>\n\t\t</xsd:element>\n\t</xsd:schema>\n\".Replace(\"'\", \"\\\"\").Replace(\"\\t\", \"  \");\n\n\t\tpublic string BasePath {\n\t\t\tget { return base_path; }\n\t\t\tset { base_path = value; }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/ResourcesFile.cs",
    "content": "#nullable enable\n// Copyright (c) 2018 Daniel Grunwald\n// Based on the .NET Core ResourceReader; make available under the MIT license\n// by the .NET Foundation.\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\t/// <summary>\n\t/// .resources file.\n\t/// </summary>\n\tpublic class ResourcesFile : IEnumerable<KeyValuePair<string, object?>>, IDisposable\n\t{\n\t\tsealed class MyBinaryReader : BinaryReader\n\t\t{\n\t\t\tpublic MyBinaryReader(Stream input, bool leaveOpen) : base(input, Encoding.UTF8, leaveOpen)\n\t\t\t{\n\t\t\t}\n\n\t\t\t// upgrade from protected to public visibility\n\t\t\tpublic new int Read7BitEncodedInt()\n\t\t\t{\n\t\t\t\treturn base.Read7BitEncodedInt();\n\t\t\t}\n\n\t\t\tpublic void Seek(long pos, SeekOrigin origin)\n\t\t\t{\n\t\t\t\tBaseStream.Seek(pos, origin);\n\t\t\t}\n\t\t}\n\n\t\tenum ResourceTypeCode\n\t\t{\n\t\t\tNull = 0,\n\t\t\tString = 1,\n\t\t\tBoolean = 2,\n\t\t\tChar = 3,\n\t\t\tByte = 4,\n\t\t\tSByte = 5,\n\t\t\tInt16 = 6,\n\t\t\tUInt16 = 7,\n\t\t\tInt32 = 8,\n\t\t\tUInt32 = 9,\n\t\t\tInt64 = 10,\n\t\t\tUInt64 = 11,\n\t\t\tSingle = 12,\n\t\t\tDouble = 13,\n\t\t\tDecimal = 14,\n\t\t\tDateTime = 0xF,\n\t\t\tTimeSpan = 0x10,\n\t\t\tLastPrimitive = 0x10,\n\t\t\tByteArray = 0x20,\n\t\t\tStream = 33,\n\t\t\tStartOfUserTypes = 0x40\n\t\t}\n\n\t\tenum SerializationFormat\n\t\t{\n\t\t\tBinaryFormatter = 1,\n\t\t\tTypeConverterByteArray = 2,\n\t\t\tTypeConverterString = 3,\n\t\t\tActivatorStream = 4\n\t\t}\n\n\t\t/// <summary>Holds the number used to identify resource files.</summary>\n\t\tpublic const int MagicNumber = unchecked((int)0xBEEFCACE);\n\t\tconst int ResourceSetVersion = 2;\n\n\t\treadonly MyBinaryReader reader;\n\t\treadonly int version;\n\t\treadonly bool usesSerializationFormat;\n\t\treadonly int numResources;\n\t\treadonly string[] typeTable;\n\t\treadonly int[] namePositions;\n\t\treadonly long fileStartPosition;\n\t\treadonly long nameSectionPosition;\n\t\treadonly long dataSectionPosition;\n\t\tlong[]? startPositions;\n\n\t\t/// <summary>\n\t\t/// Creates a new ResourcesFile.\n\t\t/// </summary>\n\t\t/// <param name=\"stream\">Input stream.</param>\n\t\t/// <param name=\"leaveOpen\">Whether the stream should be held open when the ResourcesFile is disposed.</param>\n\t\t/// <remarks>\n\t\t/// The stream is must be held open while the ResourcesFile is in use.\n\t\t/// The stream must be seekable; any operation using the ResourcesFile will end up seeking the stream.\n\t\t/// </remarks>\n\t\tpublic ResourcesFile(Stream stream, bool leaveOpen = true)\n\t\t{\n\t\t\tfileStartPosition = stream.Position;\n\t\t\treader = new MyBinaryReader(stream, leaveOpen);\n\n\t\t\tconst string ResourcesHeaderCorrupted = \"Resources header corrupted.\";\n\n\t\t\t// Read ResourceManager header\n\t\t\t// Check for magic number\n\t\t\tint magicNum = reader.ReadInt32();\n\t\t\tif (magicNum != MagicNumber)\n\t\t\t\tthrow new BadImageFormatException(\"Not a .resources file - invalid magic number\");\n\t\t\t// Assuming this is ResourceManager header V1 or greater, hopefully\n\t\t\t// after the version number there is a number of bytes to skip\n\t\t\t// to bypass the rest of the ResMgr header. For V2 or greater, we\n\t\t\t// use this to skip to the end of the header\n\t\t\tint resMgrHeaderVersion = reader.ReadInt32();\n\t\t\tint numBytesToSkip = reader.ReadInt32();\n\t\t\tif (numBytesToSkip < 0 || resMgrHeaderVersion < 0)\n\t\t\t{\n\t\t\t\tthrow new BadImageFormatException(ResourcesHeaderCorrupted);\n\t\t\t}\n\t\t\tif (resMgrHeaderVersion > 1)\n\t\t\t{\n\t\t\t\treader.BaseStream.Seek(numBytesToSkip, SeekOrigin.Current);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// We don't care about numBytesToSkip; read the rest of the header\n\n\t\t\t\t// readerType:\n\t\t\t\tstring readerType = reader.ReadString();\n\t\t\t\tusesSerializationFormat = readerType == \"System.Resources.Extensions.DeserializingResourceReader, System.Resources.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51\";\n\t\t\t\t// resourceSetType:\n\t\t\t\treader.ReadString();\n\t\t\t}\n\n\t\t\t// Read RuntimeResourceSet header\n\t\t\t// Do file version check\n\t\t\tversion = reader.ReadInt32();\n\t\t\tif (version != ResourceSetVersion && version != 1)\n\t\t\t\tthrow new BadImageFormatException($\"Unsupported resource set version: {version}\");\n\n\t\t\tnumResources = reader.ReadInt32();\n\t\t\tif (numResources < 0)\n\t\t\t{\n\t\t\t\tthrow new BadImageFormatException(ResourcesHeaderCorrupted);\n\t\t\t}\n\n\t\t\t// Read type positions into type positions array.\n\t\t\t// But delay initialize the type table.\n\t\t\tint numTypes = reader.ReadInt32();\n\t\t\tif (numTypes < 0)\n\t\t\t{\n\t\t\t\tthrow new BadImageFormatException(ResourcesHeaderCorrupted);\n\t\t\t}\n\t\t\ttypeTable = new string[numTypes];\n\t\t\tfor (int i = 0; i < numTypes; i++)\n\t\t\t{\n\t\t\t\ttypeTable[i] = reader.ReadString();\n\t\t\t}\n\n\t\t\t// Prepare to read in the array of name hashes\n\t\t\t//  Note that the name hashes array is aligned to 8 bytes so \n\t\t\t//  we can use pointers into it on 64 bit machines. (4 bytes \n\t\t\t//  may be sufficient, but let's plan for the future)\n\t\t\t//  Skip over alignment stuff.  All public .resources files\n\t\t\t//  should be aligned   No need to verify the byte values.\n\t\t\tlong pos = reader.BaseStream.Position - fileStartPosition;\n\t\t\tint alignBytes = unchecked((int)pos) & 7;\n\t\t\tif (alignBytes != 0)\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < 8 - alignBytes; i++)\n\t\t\t\t{\n\t\t\t\t\treader.ReadByte();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Skip over the array of name hashes\n\t\t\ttry\n\t\t\t{\n\t\t\t\treader.Seek(checked(4 * numResources), SeekOrigin.Current);\n\t\t\t}\n\t\t\tcatch (OverflowException)\n\t\t\t{\n\t\t\t\tthrow new BadImageFormatException(ResourcesHeaderCorrupted);\n\t\t\t}\n\n\t\t\t// Read in the array of relative positions for all the names.\n\t\t\tnamePositions = new int[numResources];\n\t\t\tfor (int i = 0; i < numResources; i++)\n\t\t\t{\n\t\t\t\tint namePosition = reader.ReadInt32();\n\t\t\t\tif (namePosition < 0)\n\t\t\t\t{\n\t\t\t\t\tthrow new BadImageFormatException(ResourcesHeaderCorrupted);\n\t\t\t\t}\n\t\t\t\tnamePositions[i] = namePosition;\n\t\t\t}\n\n\t\t\t// Read location of data section.\n\t\t\tint dataSectionOffset = reader.ReadInt32();\n\t\t\tif (dataSectionOffset < 0)\n\t\t\t{\n\t\t\t\tthrow new BadImageFormatException(ResourcesHeaderCorrupted);\n\t\t\t}\n\n\t\t\t// Store current location as start of name section\n\t\t\tnameSectionPosition = reader.BaseStream.Position;\n\t\t\tdataSectionPosition = fileStartPosition + dataSectionOffset;\n\n\t\t\t// _nameSectionOffset should be <= _dataSectionOffset; if not, it's corrupt\n\t\t\tif (dataSectionPosition < nameSectionPosition)\n\t\t\t{\n\t\t\t\tthrow new BadImageFormatException(ResourcesHeaderCorrupted);\n\t\t\t}\n\t\t}\n\n\t\tpublic void Dispose()\n\t\t{\n\t\t\treader.Dispose();\n\t\t}\n\n\t\tpublic int ResourceCount => numResources;\n\n\t\tpublic string GetResourceName(int index)\n\t\t{\n\t\t\treturn GetResourceName(index, out _);\n\t\t}\n\n\t\tint GetResourceDataOffset(int index)\n\t\t{\n\t\t\tGetResourceName(index, out int dataOffset);\n\t\t\treturn dataOffset;\n\t\t}\n\n\t\tstring GetResourceName(int index, out int dataOffset)\n\t\t{\n\t\t\tlong pos = nameSectionPosition + namePositions[index];\n\t\t\tbyte[] bytes;\n\t\t\tlock (reader)\n\t\t\t{\n\t\t\t\treader.Seek(pos, SeekOrigin.Begin);\n\t\t\t\t// Can't use reader.ReadString, since it's using UTF-8!\n\t\t\t\tint byteLen = reader.Read7BitEncodedInt();\n\t\t\t\tif (byteLen < 0)\n\t\t\t\t{\n\t\t\t\t\tthrow new BadImageFormatException(\"Resource name has negative length\");\n\t\t\t\t}\n\t\t\t\tbytes = new byte[byteLen];\n\t\t\t\t// We must read byteLen bytes, or we have a corrupted file.\n\t\t\t\t// Use a blocking read in case the stream doesn't give us back\n\t\t\t\t// everything immediately.\n\t\t\t\tint count = byteLen;\n\t\t\t\twhile (count > 0)\n\t\t\t\t{\n\t\t\t\t\tint n = reader.Read(bytes, byteLen - count, count);\n\t\t\t\t\tif (n == 0)\n\t\t\t\t\t\tthrow new BadImageFormatException(\"End of stream within a resource name\");\n\t\t\t\t\tcount -= n;\n\t\t\t\t}\n\t\t\t\tdataOffset = reader.ReadInt32();\n\t\t\t\tif (dataOffset < 0)\n\t\t\t\t{\n\t\t\t\t\tthrow new BadImageFormatException(\"Negative data offset\");\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn Encoding.Unicode.GetString(bytes);\n\t\t}\n\n\t\tinternal bool AllEntriesAreStreams()\n\t\t{\n\t\t\tif (version != 2)\n\t\t\t\treturn false;\n\t\t\tlock (reader)\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < numResources; i++)\n\t\t\t\t{\n\t\t\t\t\tint dataOffset = GetResourceDataOffset(i);\n\t\t\t\t\treader.Seek(dataSectionPosition + dataOffset, SeekOrigin.Begin);\n\t\t\t\t\tvar typeCode = (ResourceTypeCode)reader.Read7BitEncodedInt();\n\t\t\t\t\tif (typeCode != ResourceTypeCode.Stream)\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tobject? LoadObject(int dataOffset)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tlock (reader)\n\t\t\t\t{\n\t\t\t\t\tif (version == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn LoadObjectV1(dataOffset);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn LoadObjectV2(dataOffset);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (EndOfStreamException e)\n\t\t\t{\n\t\t\t\tthrow new BadImageFormatException(\"Invalid resource file\", e);\n\t\t\t}\n\t\t}\n\n\t\tstring FindType(int typeIndex)\n\t\t{\n\t\t\tif (typeIndex < 0 || typeIndex >= typeTable.Length)\n\t\t\t\tthrow new BadImageFormatException(\"Type index out of bounds\");\n\t\t\treturn typeTable[typeIndex];\n\t\t}\n\n\t\t// This takes a virtual offset into the data section and reads an Object\n\t\t// from that location.\n\t\t// Anyone who calls LoadObject should make sure they take a lock so \n\t\t// no one can cause us to do a seek in here.\n\t\tprivate object? LoadObjectV1(int dataOffset)\n\t\t{\n\t\t\tDebug.Assert(System.Threading.Monitor.IsEntered(reader));\n\t\t\treader.Seek(dataSectionPosition + dataOffset, SeekOrigin.Begin);\n\t\t\tint typeIndex = reader.Read7BitEncodedInt();\n\t\t\tif (typeIndex == -1)\n\t\t\t\treturn null;\n\t\t\tstring typeName = FindType(typeIndex);\n\t\t\tint comma = typeName.IndexOf(',');\n\t\t\tif (comma > 0)\n\t\t\t{\n\t\t\t\t// strip assembly name\n\t\t\t\ttypeName = typeName.Substring(0, comma);\n\t\t\t}\n\t\t\tswitch (typeName)\n\t\t\t{\n\t\t\t\tcase \"System.String\":\n\t\t\t\t\treturn reader.ReadString();\n\t\t\t\tcase \"System.Byte\":\n\t\t\t\t\treturn reader.ReadByte();\n\t\t\t\tcase \"System.SByte\":\n\t\t\t\t\treturn reader.ReadSByte();\n\t\t\t\tcase \"System.Int16\":\n\t\t\t\t\treturn reader.ReadInt16();\n\t\t\t\tcase \"System.UInt16\":\n\t\t\t\t\treturn reader.ReadUInt16();\n\t\t\t\tcase \"System.Int32\":\n\t\t\t\t\treturn reader.ReadInt32();\n\t\t\t\tcase \"System.UInt32\":\n\t\t\t\t\treturn reader.ReadUInt32();\n\t\t\t\tcase \"System.Int64\":\n\t\t\t\t\treturn reader.ReadInt64();\n\t\t\t\tcase \"System.UInt64\":\n\t\t\t\t\treturn reader.ReadUInt64();\n\t\t\t\tcase \"System.Single\":\n\t\t\t\t\treturn reader.ReadSingle();\n\t\t\t\tcase \"System.Double\":\n\t\t\t\t\treturn reader.ReadDouble();\n\t\t\t\tcase \"System.DateTime\":\n\t\t\t\t\t// Ideally we should use DateTime's ToBinary & FromBinary,\n\t\t\t\t\t// but we can't for compatibility reasons.\n\t\t\t\t\treturn new DateTime(reader.ReadInt64());\n\t\t\t\tcase \"System.TimeSpan\":\n\t\t\t\t\treturn new TimeSpan(reader.ReadInt64());\n\t\t\t\tcase \"System.Decimal\":\n\t\t\t\t\tint[] bits = new int[4];\n\t\t\t\t\tfor (int i = 0; i < bits.Length; i++)\n\t\t\t\t\t\tbits[i] = reader.ReadInt32();\n\t\t\t\t\treturn new decimal(bits);\n\t\t\t\tdefault:\n\t\t\t\t\treturn new ResourceSerializedObject(FindType(typeIndex), this, reader.BaseStream.Position, usesSerializationFormat);\n\t\t\t}\n\t\t}\n\n\t\tprivate object? LoadObjectV2(int dataOffset)\n\t\t{\n\t\t\tDebug.Assert(System.Threading.Monitor.IsEntered(reader));\n\t\t\treader.Seek(dataSectionPosition + dataOffset, SeekOrigin.Begin);\n\t\t\tvar typeCode = (ResourceTypeCode)reader.Read7BitEncodedInt();\n\t\t\tswitch (typeCode)\n\t\t\t{\n\t\t\t\tcase ResourceTypeCode.Null:\n\t\t\t\t\treturn null;\n\n\t\t\t\tcase ResourceTypeCode.String:\n\t\t\t\t\treturn reader.ReadString();\n\n\t\t\t\tcase ResourceTypeCode.Boolean:\n\t\t\t\t\treturn reader.ReadBoolean();\n\n\t\t\t\tcase ResourceTypeCode.Char:\n\t\t\t\t\treturn (char)reader.ReadUInt16();\n\n\t\t\t\tcase ResourceTypeCode.Byte:\n\t\t\t\t\treturn reader.ReadByte();\n\n\t\t\t\tcase ResourceTypeCode.SByte:\n\t\t\t\t\treturn reader.ReadSByte();\n\n\t\t\t\tcase ResourceTypeCode.Int16:\n\t\t\t\t\treturn reader.ReadInt16();\n\n\t\t\t\tcase ResourceTypeCode.UInt16:\n\t\t\t\t\treturn reader.ReadUInt16();\n\n\t\t\t\tcase ResourceTypeCode.Int32:\n\t\t\t\t\treturn reader.ReadInt32();\n\n\t\t\t\tcase ResourceTypeCode.UInt32:\n\t\t\t\t\treturn reader.ReadUInt32();\n\n\t\t\t\tcase ResourceTypeCode.Int64:\n\t\t\t\t\treturn reader.ReadInt64();\n\n\t\t\t\tcase ResourceTypeCode.UInt64:\n\t\t\t\t\treturn reader.ReadUInt64();\n\n\t\t\t\tcase ResourceTypeCode.Single:\n\t\t\t\t\treturn reader.ReadSingle();\n\n\t\t\t\tcase ResourceTypeCode.Double:\n\t\t\t\t\treturn reader.ReadDouble();\n\n\t\t\t\tcase ResourceTypeCode.Decimal:\n\t\t\t\t\treturn reader.ReadDecimal();\n\n\t\t\t\tcase ResourceTypeCode.DateTime:\n\t\t\t\t\t// Use DateTime's ToBinary & FromBinary.\n\t\t\t\t\tlong data = reader.ReadInt64();\n\t\t\t\t\treturn DateTime.FromBinary(data);\n\n\t\t\t\tcase ResourceTypeCode.TimeSpan:\n\t\t\t\t\tlong ticks = reader.ReadInt64();\n\t\t\t\t\treturn new TimeSpan(ticks);\n\n\t\t\t\t// Special types\n\t\t\t\tcase ResourceTypeCode.ByteArray:\n\t\t\t\t{\n\t\t\t\t\tint len = reader.ReadInt32();\n\t\t\t\t\tif (len < 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tthrow new BadImageFormatException(\"Resource with negative length\");\n\t\t\t\t\t}\n\t\t\t\t\treturn reader.ReadBytes(len);\n\t\t\t\t}\n\n\t\t\t\tcase ResourceTypeCode.Stream:\n\t\t\t\t{\n\t\t\t\t\tint len = reader.ReadInt32();\n\t\t\t\t\tif (len < 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tthrow new BadImageFormatException(\"Resource with negative length\");\n\t\t\t\t\t}\n\t\t\t\t\tbyte[] bytes = reader.ReadBytes(len);\n\t\t\t\t\treturn new MemoryStream(bytes, writable: false);\n\t\t\t\t}\n\n\t\t\t\tdefault:\n\t\t\t\t\tif (typeCode < ResourceTypeCode.StartOfUserTypes)\n\t\t\t\t\t{\n\t\t\t\t\t\tthrow new BadImageFormatException(\"Invalid typeCode\");\n\t\t\t\t\t}\n\t\t\t\t\treturn new ResourceSerializedObject(FindType(typeCode - ResourceTypeCode.StartOfUserTypes), this, reader.BaseStream.Position, usesSerializationFormat);\n\t\t\t}\n\t\t}\n\n\t\tpublic object? GetResourceValue(int index)\n\t\t{\n\t\t\tGetResourceName(index, out int dataOffset);\n\t\t\treturn LoadObject(dataOffset);\n\t\t}\n\n\t\tpublic IEnumerator<KeyValuePair<string, object?>> GetEnumerator()\n\t\t{\n\t\t\tfor (int i = 0; i < numResources; i++)\n\t\t\t{\n\t\t\t\tstring name = GetResourceName(i, out int dataOffset);\n\t\t\t\tobject? val = LoadObject(dataOffset);\n\t\t\t\tyield return new KeyValuePair<string, object?>(name, val);\n\t\t\t}\n\t\t}\n\n\t\tIEnumerator IEnumerable.GetEnumerator()\n\t\t{\n\t\t\treturn GetEnumerator();\n\t\t}\n\n\t\tlong[] GetStartPositions()\n\t\t{\n\t\t\tlong[]? positions = LazyInit.VolatileRead(ref startPositions);\n\t\t\tif (positions != null)\n\t\t\t\treturn positions;\n\t\t\tlock (reader)\n\t\t\t{\n\t\t\t\t// double-checked locking\n\t\t\t\tpositions = LazyInit.VolatileRead(ref startPositions);\n\t\t\t\tif (positions != null)\n\t\t\t\t\treturn positions;\n\t\t\t\tpositions = new long[numResources * 2];\n\t\t\t\tint outPos = 0;\n\t\t\t\tfor (int i = 0; i < numResources; i++)\n\t\t\t\t{\n\t\t\t\t\tpositions[outPos++] = nameSectionPosition + namePositions[i];\n\t\t\t\t\tpositions[outPos++] = dataSectionPosition + GetResourceDataOffset(i);\n\t\t\t\t}\n\t\t\t\tArray.Sort(positions);\n\t\t\t\treturn LazyInit.GetOrSet(ref startPositions, positions);\n\t\t\t}\n\t\t}\n\n\t\tinternal byte[] GetBytesForSerializedObject(long pos, bool usesSerializationFormat)\n\t\t{\n\t\t\tlong[] positions = GetStartPositions();\n\t\t\tint i = Array.BinarySearch(positions, pos);\n\t\t\tif (i < 0)\n\t\t\t{\n\t\t\t\t// 'pos' the the start position of the serialized object data\n\t\t\t\t// This is the position after the type code, so it should not appear in the 'positions' array.\n\t\t\t\t// Set i to the index of the next position after 'pos'.\n\t\t\t\ti = ~i;\n\t\t\t\t// Note: if 'pos' does exist in the array, that means the stream has length 0,\n\t\t\t\t// so we keep the i that we found.\n\t\t\t}\n\t\t\tlock (reader)\n\t\t\t{\n\t\t\t\tlong endPos;\n\t\t\t\tif (i == positions.Length)\n\t\t\t\t{\n\t\t\t\t\tendPos = reader.BaseStream.Length;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tendPos = positions[i];\n\t\t\t\t}\n\t\t\t\tint len = (int)(endPos - pos);\n\t\t\t\treader.Seek(pos, SeekOrigin.Begin);\n\t\t\t\tif (usesSerializationFormat)\n\t\t\t\t{\n\t\t\t\t\tint kind = reader.Read7BitEncodedInt();\n\t\t\t\t\tDebug.Assert(Enum.IsDefined(typeof(SerializationFormat), kind));\n\t\t\t\t\tlen = reader.Read7BitEncodedInt();\n\t\t\t\t}\n\t\t\t\treturn reader.ReadBytes(len);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic class ResourceSerializedObject\n\t{\n\t\tpublic string? TypeName { get; }\n\t\treadonly ResourcesFile file;\n\t\treadonly long position;\n\t\treadonly bool usesSerializationFormat;\n\n\t\tinternal ResourceSerializedObject(string? typeName, ResourcesFile file, long position, bool usesSerializationFormat)\n\t\t{\n\t\t\tthis.TypeName = usesSerializationFormat ? typeName : null;\n\t\t\tthis.file = file;\n\t\t\tthis.position = position;\n\t\t\tthis.usesSerializationFormat = usesSerializationFormat;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets a stream that starts with the serialized object data.\n\t\t/// </summary>\n\t\tpublic Stream GetStream()\n\t\t{\n\t\t\treturn new MemoryStream(file.GetBytesForSerializedObject(position, usesSerializationFormat), writable: false);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the serialized object data.\n\t\t/// </summary>\n\t\tpublic byte[] GetBytes()\n\t\t{\n\t\t\treturn file.GetBytesForSerializedObject(position, usesSerializationFormat);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/TreeTraversal.cs",
    "content": "#nullable enable\n// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\t/// <summary>\n\t/// Static helper methods for traversing trees.\n\t/// </summary>\n\tpublic static class TreeTraversal\n\t{\n\t\t/// <summary>\n\t\t/// Converts a tree data structure into a flat list by traversing it in pre-order.\n\t\t/// </summary>\n\t\t/// <param name=\"root\">The root element of the tree.</param>\n\t\t/// <param name=\"recursion\">The function that gets the children of an element.</param>\n\t\t/// <returns>Iterator that enumerates the tree structure in pre-order.</returns>\n\t\tpublic static IEnumerable<T> PreOrder<T>(T root, Func<T, IEnumerable<T>?> recursion)\n\t\t{\n\t\t\treturn PreOrder(new T[] { root }, recursion);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts a tree data structure into a flat list by traversing it in pre-order.\n\t\t/// </summary>\n\t\t/// <param name=\"input\">The root elements of the forest.</param>\n\t\t/// <param name=\"recursion\">The function that gets the children of an element.</param>\n\t\t/// <returns>Iterator that enumerates the tree structure in pre-order.</returns>\n\t\tpublic static IEnumerable<T> PreOrder<T>(IEnumerable<T> input, Func<T, IEnumerable<T>?> recursion)\n\t\t{\n\t\t\tStack<IEnumerator<T>> stack = new Stack<IEnumerator<T>>();\n\t\t\ttry\n\t\t\t{\n\t\t\t\tstack.Push(input.GetEnumerator());\n\t\t\t\twhile (stack.Count > 0)\n\t\t\t\t{\n\t\t\t\t\twhile (stack.Peek().MoveNext())\n\t\t\t\t\t{\n\t\t\t\t\t\tT element = stack.Peek().Current;\n\t\t\t\t\t\tyield return element;\n\t\t\t\t\t\tIEnumerable<T>? children = recursion(element);\n\t\t\t\t\t\tif (children != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstack.Push(children.GetEnumerator());\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tstack.Pop().Dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\twhile (stack.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tstack.Pop().Dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts a tree data structure into a flat list by traversing it in post-order.\n\t\t/// </summary>\n\t\t/// <param name=\"root\">The root element of the tree.</param>\n\t\t/// <param name=\"recursion\">The function that gets the children of an element.</param>\n\t\t/// <returns>Iterator that enumerates the tree structure in post-order.</returns>\n\t\tpublic static IEnumerable<T> PostOrder<T>(T root, Func<T, IEnumerable<T>?> recursion)\n\t\t{\n\t\t\treturn PostOrder(new T[] { root }, recursion);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts a tree data structure into a flat list by traversing it in post-order.\n\t\t/// </summary>\n\t\t/// <param name=\"input\">The root elements of the forest.</param>\n\t\t/// <param name=\"recursion\">The function that gets the children of an element.</param>\n\t\t/// <returns>Iterator that enumerates the tree structure in post-order.</returns>\n\t\tpublic static IEnumerable<T> PostOrder<T>(IEnumerable<T> input, Func<T, IEnumerable<T>?> recursion)\n\t\t{\n\t\t\tStack<IEnumerator<T>> stack = new Stack<IEnumerator<T>>();\n\t\t\ttry\n\t\t\t{\n\t\t\t\tstack.Push(input.GetEnumerator());\n\t\t\t\twhile (stack.Count > 0)\n\t\t\t\t{\n\t\t\t\t\twhile (stack.Peek().MoveNext())\n\t\t\t\t\t{\n\t\t\t\t\t\tT element = stack.Peek().Current;\n\t\t\t\t\t\tIEnumerable<T>? children = recursion(element);\n\t\t\t\t\t\tif (children != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstack.Push(children.GetEnumerator());\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tyield return element;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tstack.Pop().Dispose();\n\t\t\t\t\tif (stack.Count > 0)\n\t\t\t\t\t\tyield return stack.Peek().Current;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\twhile (stack.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tstack.Pop().Dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/UnicodeNewline.cs",
    "content": "#nullable enable\n//\n// UnicodeNewline.cs\n//\n// Author:\n//       Mike Krüger <mkrueger@xamarin.com>\n//\n// Copyright (c) 2013 Xamarin Inc. (http://xamarin.com)\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\nusing System;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\tpublic enum UnicodeNewline\n\t{\n\t\tUnknown,\n\n\t\t/// <summary>\n\t\t/// Line Feed, U+000A\n\t\t/// </summary>\n\t\tLF = 0x0A,\n\n\t\tCRLF = 0x0D0A,\n\n\t\t/// <summary>\n\t\t/// Carriage Return, U+000D\n\t\t/// </summary>\n\t\tCR = 0x0D,\n\n\t\t/// <summary>\n\t\t/// Next Line, U+0085\n\t\t/// </summary>\n\t\tNEL = 0x85,\n\n\t\t/// <summary>\n\t\t/// Vertical Tab, U+000B\n\t\t/// </summary>\n\t\tVT = 0x0B,\n\n\t\t/// <summary>\n\t\t/// Form Feed, U+000C\n\t\t/// </summary>\n\t\tFF = 0x0C,\n\n\t\t/// <summary>\n\t\t/// Line Separator, U+2028\n\t\t/// </summary>\n\t\tLS = 0x2028,\n\n\t\t/// <summary>\n\t\t/// Paragraph Separator, U+2029\n\t\t/// </summary>\n\t\tPS = 0x2029\n\t}\n\n\t/// <summary>\n\t/// Defines unicode new lines according to  Unicode Technical Report #13\n\t/// http://www.unicode.org/standard/reports/tr13/tr13-5.html\n\t/// </summary>\n\tpublic static class NewLine\n\t{\n\t\t/// <summary>\n\t\t/// Carriage Return, U+000D\n\t\t/// </summary>\n\t\tpublic const char CR = (char)0x0D;\n\n\t\t/// <summary>\n\t\t/// Line Feed, U+000A\n\t\t/// </summary>\n\t\tpublic const char LF = (char)0x0A;\n\n\t\t/// <summary>\n\t\t/// Next Line, U+0085\n\t\t/// </summary>\n\t\tpublic const char NEL = (char)0x85;\n\n\t\t/// <summary>\n\t\t/// Vertical Tab, U+000B\n\t\t/// </summary>\n\t\tpublic const char VT = (char)0x0B;\n\n\t\t/// <summary>\n\t\t/// Form Feed, U+000C\n\t\t/// </summary>\n\t\tpublic const char FF = (char)0x0C;\n\n\t\t/// <summary>\n\t\t/// Line Separator, U+2028\n\t\t/// </summary>\n\t\tpublic const char LS = (char)0x2028;\n\n\t\t/// <summary>\n\t\t/// Paragraph Separator, U+2029\n\t\t/// </summary>\n\t\tpublic const char PS = (char)0x2029;\n\n\t\t/// <summary>\n\t\t/// Determines if a char is a new line delimiter.\n\t\t/// </summary>\n\t\t/// <returns>0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter.</returns>\n\t\t/// <param name=\"curChar\">The current character.</param>\n\t\t/// <param name=\"nextChar\">A callback getting the next character (may be null).</param>\n\t\tpublic static int GetDelimiterLength(char curChar, Func<char>? nextChar = null)\n\t\t{\n\t\t\tif (curChar == CR)\n\t\t\t{\n\t\t\t\tif (nextChar != null && nextChar() == LF)\n\t\t\t\t\treturn 2;\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tif (curChar == LF || curChar == NEL || curChar == VT || curChar == FF || curChar == LS || curChar == PS)\n\t\t\t\treturn 1;\n\t\t\treturn 0;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Determines if a char is a new line delimiter.\n\t\t/// </summary>\n\t\t/// <returns>0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter.</returns>\n\t\t/// <param name=\"curChar\">The current character.</param>\n\t\t/// <param name=\"nextChar\">The next character (if != LF then length will always be 0 or 1).</param>\n\t\tpublic static int GetDelimiterLength(char curChar, char nextChar)\n\t\t{\n\t\t\tif (curChar == CR)\n\t\t\t{\n\t\t\t\tif (nextChar == LF)\n\t\t\t\t\treturn 2;\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tif (curChar == LF || curChar == NEL || curChar == VT || curChar == FF || curChar == LS || curChar == PS)\n\t\t\t\treturn 1;\n\t\t\treturn 0;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Determines if a char is a new line delimiter.\n\t\t/// </summary>\n\t\t/// <returns>0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter.</returns>\n\t\t/// <param name=\"curChar\">The current character.</param>\n\t\t/// <param name = \"length\">The length of the delimiter</param>\n\t\t/// <param name = \"type\">The type of the delimiter</param>\n\t\t/// <param name=\"nextChar\">A callback getting the next character (may be null).</param>\n\t\tpublic static bool TryGetDelimiterLengthAndType(char curChar, out int length, out UnicodeNewline type, Func<char>? nextChar = null)\n\t\t{\n\t\t\tif (curChar == CR)\n\t\t\t{\n\t\t\t\tif (nextChar != null && nextChar() == LF)\n\t\t\t\t{\n\t\t\t\t\tlength = 2;\n\t\t\t\t\ttype = UnicodeNewline.CRLF;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tlength = 1;\n\t\t\t\t\ttype = UnicodeNewline.CR;\n\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tswitch (curChar)\n\t\t\t{\n\t\t\t\tcase LF:\n\t\t\t\t\ttype = UnicodeNewline.LF;\n\t\t\t\t\tlength = 1;\n\t\t\t\t\treturn true;\n\t\t\t\tcase NEL:\n\t\t\t\t\ttype = UnicodeNewline.NEL;\n\t\t\t\t\tlength = 1;\n\t\t\t\t\treturn true;\n\t\t\t\tcase VT:\n\t\t\t\t\ttype = UnicodeNewline.VT;\n\t\t\t\t\tlength = 1;\n\t\t\t\t\treturn true;\n\t\t\t\tcase FF:\n\t\t\t\t\ttype = UnicodeNewline.FF;\n\t\t\t\t\tlength = 1;\n\t\t\t\t\treturn true;\n\t\t\t\tcase LS:\n\t\t\t\t\ttype = UnicodeNewline.LS;\n\t\t\t\t\tlength = 1;\n\t\t\t\t\treturn true;\n\t\t\t\tcase PS:\n\t\t\t\t\ttype = UnicodeNewline.PS;\n\t\t\t\t\tlength = 1;\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\tlength = -1;\n\t\t\ttype = UnicodeNewline.Unknown;\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Determines if a char is a new line delimiter.\n\t\t/// </summary>\n\t\t/// <returns>0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter.</returns>\n\t\t/// <param name=\"curChar\">The current character.</param>\n\t\t/// <param name = \"length\">The length of the delimiter</param>\n\t\t/// <param name = \"type\">The type of the delimiter</param>\n\t\t/// <param name=\"nextChar\">The next character (if != LF then length will always be 0 or 1).</param>\n\t\tpublic static bool TryGetDelimiterLengthAndType(char curChar, out int length, out UnicodeNewline type, char nextChar)\n\t\t{\n\t\t\tif (curChar == CR)\n\t\t\t{\n\t\t\t\tif (nextChar == LF)\n\t\t\t\t{\n\t\t\t\t\tlength = 2;\n\t\t\t\t\ttype = UnicodeNewline.CRLF;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tlength = 1;\n\t\t\t\t\ttype = UnicodeNewline.CR;\n\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tswitch (curChar)\n\t\t\t{\n\t\t\t\tcase LF:\n\t\t\t\t\ttype = UnicodeNewline.LF;\n\t\t\t\t\tlength = 1;\n\t\t\t\t\treturn true;\n\t\t\t\tcase NEL:\n\t\t\t\t\ttype = UnicodeNewline.NEL;\n\t\t\t\t\tlength = 1;\n\t\t\t\t\treturn true;\n\t\t\t\tcase VT:\n\t\t\t\t\ttype = UnicodeNewline.VT;\n\t\t\t\t\tlength = 1;\n\t\t\t\t\treturn true;\n\t\t\t\tcase FF:\n\t\t\t\t\ttype = UnicodeNewline.FF;\n\t\t\t\t\tlength = 1;\n\t\t\t\t\treturn true;\n\t\t\t\tcase LS:\n\t\t\t\t\ttype = UnicodeNewline.LS;\n\t\t\t\t\tlength = 1;\n\t\t\t\t\treturn true;\n\t\t\t\tcase PS:\n\t\t\t\t\ttype = UnicodeNewline.PS;\n\t\t\t\t\tlength = 1;\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\tlength = -1;\n\t\t\ttype = UnicodeNewline.Unknown;\n\t\t\treturn false;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the new line type of a given char/next char.\n\t\t/// </summary>\n\t\t/// <returns>0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter.</returns>\n\t\t/// <param name=\"curChar\">The current character.</param>\n\t\t/// <param name=\"nextChar\">A callback getting the next character (may be null).</param>\n\t\tpublic static UnicodeNewline GetDelimiterType(char curChar, Func<char>? nextChar = null)\n\t\t{\n\t\t\tswitch (curChar)\n\t\t\t{\n\t\t\t\tcase CR:\n\t\t\t\t\tif (nextChar != null && nextChar() == LF)\n\t\t\t\t\t\treturn UnicodeNewline.CRLF;\n\t\t\t\t\treturn UnicodeNewline.CR;\n\t\t\t\tcase LF:\n\t\t\t\t\treturn UnicodeNewline.LF;\n\t\t\t\tcase NEL:\n\t\t\t\t\treturn UnicodeNewline.NEL;\n\t\t\t\tcase VT:\n\t\t\t\t\treturn UnicodeNewline.VT;\n\t\t\t\tcase FF:\n\t\t\t\t\treturn UnicodeNewline.FF;\n\t\t\t\tcase LS:\n\t\t\t\t\treturn UnicodeNewline.LS;\n\t\t\t\tcase PS:\n\t\t\t\t\treturn UnicodeNewline.PS;\n\t\t\t}\n\t\t\treturn UnicodeNewline.Unknown;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the new line type of a given char/next char.\n\t\t/// </summary>\n\t\t/// <returns>0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter.</returns>\n\t\t/// <param name=\"curChar\">The current character.</param>\n\t\t/// <param name=\"nextChar\">The next character (if != LF then length will always be 0 or 1).</param>\n\t\tpublic static UnicodeNewline GetDelimiterType(char curChar, char nextChar)\n\t\t{\n\t\t\tswitch (curChar)\n\t\t\t{\n\t\t\t\tcase CR:\n\t\t\t\t\tif (nextChar == LF)\n\t\t\t\t\t\treturn UnicodeNewline.CRLF;\n\t\t\t\t\treturn UnicodeNewline.CR;\n\t\t\t\tcase LF:\n\t\t\t\t\treturn UnicodeNewline.LF;\n\t\t\t\tcase NEL:\n\t\t\t\t\treturn UnicodeNewline.NEL;\n\t\t\t\tcase VT:\n\t\t\t\t\treturn UnicodeNewline.VT;\n\t\t\t\tcase FF:\n\t\t\t\t\treturn UnicodeNewline.FF;\n\t\t\t\tcase LS:\n\t\t\t\t\treturn UnicodeNewline.LS;\n\t\t\t\tcase PS:\n\t\t\t\t\treturn UnicodeNewline.PS;\n\t\t\t}\n\t\t\treturn UnicodeNewline.Unknown;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Determines if a char is a new line delimiter. \n\t\t/// \n\t\t/// Note that the only 2 char wide new line is CR LF and both chars are new line\n\t\t/// chars on their own. For most cases GetDelimiterLength is the better choice.\n\t\t/// </summary>\n\t\tpublic static bool IsNewLine(char ch)\n\t\t{\n\t\t\treturn\n\t\t\t\tch == NewLine.CR ||\n\t\t\t\tch == NewLine.LF ||\n\t\t\t\tch == NewLine.NEL ||\n\t\t\t\tch == NewLine.VT ||\n\t\t\t\tch == NewLine.FF ||\n\t\t\t\tch == NewLine.LS ||\n\t\t\t\tch == NewLine.PS;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the new line as a string.\n\t\t/// </summary>\n\t\tpublic static string GetString(UnicodeNewline newLine)\n\t\t{\n\t\t\tswitch (newLine)\n\t\t\t{\n\t\t\t\tcase UnicodeNewline.Unknown:\n\t\t\t\t\treturn \"\";\n\t\t\t\tcase UnicodeNewline.LF:\n\t\t\t\t\treturn \"\\n\";\n\t\t\t\tcase UnicodeNewline.CRLF:\n\t\t\t\t\treturn \"\\r\\n\";\n\t\t\t\tcase UnicodeNewline.CR:\n\t\t\t\t\treturn \"\\r\";\n\t\t\t\tcase UnicodeNewline.NEL:\n\t\t\t\t\treturn \"\\u0085\";\n\t\t\t\tcase UnicodeNewline.VT:\n\t\t\t\t\treturn \"\\u000B\";\n\t\t\t\tcase UnicodeNewline.FF:\n\t\t\t\t\treturn \"\\u000C\";\n\t\t\t\tcase UnicodeNewline.LS:\n\t\t\t\t\treturn \"\\u2028\";\n\t\t\t\tcase UnicodeNewline.PS:\n\t\t\t\t\treturn \"\\u2029\";\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t}\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/UnionFind.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n#nullable enable\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\t/// <summary>\n\t/// Union-Find data structure.\n\t/// </summary>\n\tpublic class UnionFind<T> where T : notnull\n\t{\n\t\tDictionary<T, Node> mapping;\n\n\t\tclass Node\n\t\t{\n\t\t\tpublic int rank;\n\t\t\tpublic Node parent;\n\t\t\tpublic T value;\n\n\t\t\tinternal Node(T value)\n\t\t\t{\n\t\t\t\tthis.value = value;\n\t\t\t\tthis.parent = this;\n\t\t\t}\n\t\t}\n\n\t\tpublic UnionFind()\n\t\t{\n\t\t\tmapping = new Dictionary<T, Node>();\n\t\t}\n\n\t\tNode GetNode(T element)\n\t\t{\n\t\t\tif (!mapping.TryGetValue(element, out Node? node))\n\t\t\t{\n\t\t\t\tnode = new Node(element);\n\t\t\t\tnode.parent = node;\n\t\t\t\tmapping.Add(element, node);\n\t\t\t}\n\t\t\treturn node;\n\t\t}\n\n\t\tpublic T Find(T element)\n\t\t{\n\t\t\treturn FindRoot(GetNode(element)).value;\n\t\t}\n\n\t\tNode FindRoot(Node node)\n\t\t{\n\t\t\tif (node.parent != node)\n\t\t\t\tnode.parent = FindRoot(node.parent);\n\t\t\treturn node.parent;\n\t\t}\n\n\t\tpublic void Merge(T a, T b)\n\t\t{\n\t\t\tvar rootA = FindRoot(GetNode(a));\n\t\t\tvar rootB = FindRoot(GetNode(b));\n\t\t\tif (rootA == rootB)\n\t\t\t\treturn;\n\t\t\tif (rootA.rank < rootB.rank)\n\t\t\t\trootA.parent = rootB;\n\t\t\telse if (rootA.rank > rootB.rank)\n\t\t\t\trootB.parent = rootA;\n\t\t\telse\n\t\t\t{\n\t\t\t\trootB.parent = rootA;\n\t\t\t\trootA.rank++;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/Util/Win32Resources.cs",
    "content": "#nullable enable\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Reflection.PortableExecutable;\n\nnamespace ICSharpCode.Decompiler.Util\n{\n\t/// <summary>\n\t/// Represents win32 resources\n\t/// </summary>\n\tpublic static class Win32Resources\n\t{\n\t\t/// <summary>\n\t\t/// Reads win32 resource root directory\n\t\t/// </summary>\n\t\t/// <param name=\"pe\"></param>\n\t\t/// <returns></returns>\n\t\tpublic static unsafe Win32ResourceDirectory? ReadWin32Resources(this PEReader pe)\n\t\t{\n\t\t\tif (pe == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(pe));\n\t\t\t}\n\n\t\t\tint rva = pe.PEHeaders.PEHeader?.ResourceTableDirectory.RelativeVirtualAddress ?? 0;\n\t\t\tif (rva == 0)\n\t\t\t\treturn null;\n\t\t\tbyte* pRoot = pe.GetSectionData(rva).Pointer;\n\t\t\treturn new Win32ResourceDirectory(pe, pRoot, 0, new Win32ResourceName(\"Root\"));\n\t\t}\n\n\t\tpublic static Win32ResourceDirectory? Find(this Win32ResourceDirectory root, Win32ResourceName type)\n\t\t{\n\t\t\tif (root is null)\n\t\t\t\tthrow new ArgumentNullException(nameof(root));\n\t\t\tif (!root.Name.HasName || root.Name.Name != \"Root\")\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(root));\n\t\t\tif (type is null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\n\t\t\treturn root.FindDirectory(type);\n\t\t}\n\n\t\tpublic static Win32ResourceDirectory? Find(this Win32ResourceDirectory root, Win32ResourceName type, Win32ResourceName name)\n\t\t{\n\t\t\tif (root is null)\n\t\t\t\tthrow new ArgumentNullException(nameof(root));\n\t\t\tif (!root.Name.HasName || root.Name.Name != \"Root\")\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(root));\n\t\t\tif (type is null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tif (name is null)\n\t\t\t\tthrow new ArgumentNullException(nameof(name));\n\n\t\t\treturn root.FindDirectory(type)?.FindDirectory(name);\n\t\t}\n\n\t\tpublic static Win32ResourceData? Find(this Win32ResourceDirectory root, Win32ResourceName type, Win32ResourceName name, Win32ResourceName langId)\n\t\t{\n\t\t\tif (root is null)\n\t\t\t\tthrow new ArgumentNullException(nameof(root));\n\t\t\tif (!root.Name.HasName || root.Name.Name != \"Root\")\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(root));\n\t\t\tif (type is null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tif (name is null)\n\t\t\t\tthrow new ArgumentNullException(nameof(name));\n\t\t\tif (langId is null)\n\t\t\t\tthrow new ArgumentNullException(nameof(langId));\n\n\t\t\treturn root.FindDirectory(type)?.FindDirectory(name)?.FindData(langId);\n\t\t}\n\t}\n\n\t[DebuggerDisplay(\"Directory: {Name}\")]\n\tpublic sealed class Win32ResourceDirectory\n\t{\n\t\t#region Structure\n\t\tpublic uint Characteristics { get; }\n\t\tpublic uint TimeDateStamp { get; }\n\t\tpublic ushort MajorVersion { get; }\n\t\tpublic ushort MinorVersion { get; }\n\t\tpublic ushort NumberOfNamedEntries { get; }\n\t\tpublic ushort NumberOfIdEntries { get; }\n\t\t#endregion\n\n\t\tpublic Win32ResourceName Name { get; }\n\n\t\tpublic IList<Win32ResourceDirectory> Directories { get; }\n\n\t\tpublic IList<Win32ResourceData> Datas { get; }\n\n\t\tinternal unsafe Win32ResourceDirectory(PEReader pe, byte* pRoot, int offset, Win32ResourceName name)\n\t\t{\n\t\t\tvar p = (IMAGE_RESOURCE_DIRECTORY*)(pRoot + offset);\n\t\t\tCharacteristics = p->Characteristics;\n\t\t\tTimeDateStamp = p->TimeDateStamp;\n\t\t\tMajorVersion = p->MajorVersion;\n\t\t\tMinorVersion = p->MinorVersion;\n\t\t\tNumberOfNamedEntries = p->NumberOfNamedEntries;\n\t\t\tNumberOfIdEntries = p->NumberOfIdEntries;\n\n\t\t\tName = name;\n\t\t\tDirectories = new List<Win32ResourceDirectory>();\n\t\t\tDatas = new List<Win32ResourceData>();\n\t\t\tvar pEntries = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(p + 1);\n\t\t\tint total = NumberOfNamedEntries + NumberOfIdEntries;\n\t\t\tfor (int i = 0; i < total; i++)\n\t\t\t{\n\t\t\t\tvar pEntry = pEntries + i;\n\t\t\t\tname = new Win32ResourceName(pRoot, pEntry);\n\t\t\t\tif ((pEntry->OffsetToData & 0x80000000) == 0)\n\t\t\t\t\tDatas.Add(new Win32ResourceData(pe, pRoot, (int)pEntry->OffsetToData, name));\n\t\t\t\telse\n\t\t\t\t\tDirectories.Add(new Win32ResourceDirectory(pe, pRoot, (int)(pEntry->OffsetToData & 0x7FFFFFFF), name));\n\t\t\t}\n\t\t}\n\n\t\tstatic unsafe string ReadString(byte* pRoot, int offset)\n\t\t{\n\t\t\tvar pString = (IMAGE_RESOURCE_DIRECTORY_STRING*)(pRoot + offset);\n\t\t\treturn new string(pString->NameString, 0, pString->Length);\n\t\t}\n\n\t\tpublic Win32ResourceDirectory? FindDirectory(Win32ResourceName name)\n\t\t{\n\t\t\tforeach (var directory in Directories)\n\t\t\t{\n\t\t\t\tif (directory.Name == name)\n\t\t\t\t\treturn directory;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic Win32ResourceData? FindData(Win32ResourceName name)\n\t\t{\n\t\t\tforeach (var data in Datas)\n\t\t\t{\n\t\t\t\tif (data.Name == name)\n\t\t\t\t\treturn data;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic Win32ResourceDirectory? FirstDirectory()\n\t\t{\n\t\t\treturn Directories.Count != 0 ? Directories[0] : null;\n\t\t}\n\n\t\tpublic Win32ResourceData? FirstData()\n\t\t{\n\t\t\treturn Datas.Count != 0 ? Datas[0] : null;\n\t\t}\n\t}\n\n\t[DebuggerDisplay(\"Data: {Name}\")]\n\tpublic sealed unsafe class Win32ResourceData\n\t{\n\t\t#region Structure\n\t\tpublic uint OffsetToData { get; }\n\t\tpublic uint Size { get; }\n\t\tpublic uint CodePage { get; }\n\t\tpublic uint Reserved { get; }\n\t\t#endregion\n\n\t\tprivate readonly void* _pointer;\n\n\t\tpublic Win32ResourceName Name { get; }\n\n\t\tpublic byte[] Data {\n\t\t\tget {\n\t\t\t\tbyte[] data = new byte[Size];\n\t\t\t\tfixed (void* pData = data)\n\t\t\t\t\tBuffer.MemoryCopy(_pointer, pData, Size, Size);\n\t\t\t\treturn data;\n\t\t\t}\n\t\t}\n\n\t\tinternal Win32ResourceData(PEReader pe, byte* pRoot, int offset, Win32ResourceName name)\n\t\t{\n\t\t\tvar p = (IMAGE_RESOURCE_DATA_ENTRY*)(pRoot + offset);\n\t\t\tOffsetToData = p->OffsetToData;\n\t\t\tSize = p->Size;\n\t\t\tCodePage = p->CodePage;\n\t\t\tReserved = p->Reserved;\n\n\t\t\t_pointer = pe.GetSectionData((int)OffsetToData).Pointer;\n\t\t\tName = name;\n\t\t}\n\t}\n\n\tpublic sealed class Win32ResourceName\n\t{\n\t\tprivate readonly object _name;\n\n\t\tpublic bool HasName => _name is string;\n\n\t\tpublic bool HasId => _name is ushort;\n\n\t\tpublic string Name => (string)_name;\n\n\t\tpublic ushort Id => (ushort)_name;\n\n\t\tpublic Win32ResourceName(string name)\n\t\t{\n\t\t\t_name = name ?? throw new ArgumentNullException(nameof(name));\n\t\t}\n\n\t\tpublic Win32ResourceName(int id) : this(checked((ushort)id))\n\t\t{\n\t\t}\n\n\t\tpublic Win32ResourceName(ushort id)\n\t\t{\n\t\t\t_name = id;\n\t\t}\n\n\t\tinternal unsafe Win32ResourceName(byte* pRoot, IMAGE_RESOURCE_DIRECTORY_ENTRY* pEntry)\n\t\t{\n\t\t\t_name = (pEntry->Name & 0x80000000) == 0 ? (object)(ushort)pEntry->Name : ReadString(pRoot, (int)(pEntry->Name & 0x7FFFFFFF));\n\n\t\t\tstatic string ReadString(byte* pRoot, int offset)\n\t\t\t{\n\t\t\t\tvar pString = (IMAGE_RESOURCE_DIRECTORY_STRING*)(pRoot + offset);\n\t\t\t\treturn new string(pString->NameString, 0, pString->Length);\n\t\t\t}\n\t\t}\n\n\t\tpublic static bool operator ==(Win32ResourceName x, Win32ResourceName y)\n\t\t{\n\t\t\tif (x.HasName)\n\t\t\t{\n\t\t\t\treturn y.HasName ? string.Compare(x.Name, y.Name, StringComparison.OrdinalIgnoreCase) == 0 : false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn y.HasId ? x.Id == y.Id : false;\n\t\t\t}\n\t\t}\n\n\t\tpublic static bool operator !=(Win32ResourceName x, Win32ResourceName y)\n\t\t{\n\t\t\treturn !(x == y);\n\t\t}\n\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\treturn _name.GetHashCode();\n\t\t}\n\n\t\tpublic override bool Equals(object? obj)\n\t\t{\n\t\t\tif (!(obj is Win32ResourceName name))\n\t\t\t\treturn false;\n\t\t\treturn this == name;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn HasName ? $\"Name: {Name}\" : $\"Id: {Id}\";\n\t\t}\n\t}\n\n\tinternal struct IMAGE_RESOURCE_DIRECTORY\n\t{\n\t\tpublic uint Characteristics;\n\t\tpublic uint TimeDateStamp;\n\t\tpublic ushort MajorVersion;\n\t\tpublic ushort MinorVersion;\n\t\tpublic ushort NumberOfNamedEntries;\n\t\tpublic ushort NumberOfIdEntries;\n\t}\n\n\tinternal struct IMAGE_RESOURCE_DIRECTORY_ENTRY\n\t{\n\t\tpublic uint Name;\n\t\tpublic uint OffsetToData;\n\t}\n\n\tinternal unsafe struct IMAGE_RESOURCE_DIRECTORY_STRING\n\t{\n\t\tpublic ushort Length;\n\t\tpublic fixed char NameString[1];\n\t}\n\n\tinternal struct IMAGE_RESOURCE_DATA_ENTRY\n\t{\n\t\tpublic uint OffsetToData;\n\t\tpublic uint Size;\n\t\tpublic uint CodePage;\n\t\tpublic uint Reserved;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler/packages.lock.json",
    "content": "{\n  \"version\": 1,\n  \"dependencies\": {\n    \".NETStandard,Version=v2.0\": {\n      \"Microsoft.CodeAnalysis.NetAnalyzers\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[10.0.201, )\",\n        \"resolved\": \"10.0.201\",\n        \"contentHash\": \"MTE+F0fj0N8dtfkEGIcX3/rEycMbOf54DXq/n6n8cE6ZfDIPEElY8lc4X5BpZ+c7DBoQDGLG0iBY/W0YZ3nhtw==\"\n      },\n      \"Microsoft.Sbom.Targets\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[4.1.5, )\",\n        \"resolved\": \"4.1.5\",\n        \"contentHash\": \"i5z+cNu/cOcdO0AgFB8aXk8w6In2H+haaDfSgd9ImvQIK+rSHavHZIogVoAZLL8jLwYx4bAcs5b7EyuMMG4mQQ==\"\n      },\n      \"Microsoft.SourceLink.GitHub\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[10.0.201, )\",\n        \"resolved\": \"10.0.201\",\n        \"contentHash\": \"qxYAmO4ktzd9L+HMdnqWucxpu7bI9undPyACXOMqPyhaiMtbpbYL/n0ACyWIJlbyEJrXFwxiOaBOSasLtDvsCg==\",\n        \"dependencies\": {\n          \"Microsoft.Build.Tasks.Git\": \"10.0.201\",\n          \"Microsoft.SourceLink.Common\": \"10.0.201\",\n          \"System.IO.Hashing\": \"10.0.5\"\n        }\n      },\n      \"NETStandard.Library\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[2.0.3, )\",\n        \"resolved\": \"2.0.3\",\n        \"contentHash\": \"st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==\",\n        \"dependencies\": {\n          \"Microsoft.NETCore.Platforms\": \"1.1.0\"\n        }\n      },\n      \"System.Collections.Immutable\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[9.0.0, )\",\n        \"resolved\": \"9.0.0\",\n        \"contentHash\": \"QhkXUl2gNrQtvPmtBTQHb0YsUrDiDQ2QS09YbtTTiSjGcf7NBqtYbrG/BE06zcBPCKEwQGzIv13IVdXNOSub2w==\",\n        \"dependencies\": {\n          \"System.Memory\": \"4.5.5\",\n          \"System.Runtime.CompilerServices.Unsafe\": \"6.0.0\"\n        }\n      },\n      \"System.Reflection.Metadata\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[9.0.0, )\",\n        \"resolved\": \"9.0.0\",\n        \"contentHash\": \"ANiqLu3DxW9kol/hMmTWbt3414t9ftdIuiIU7j80okq2YzAueo120M442xk1kDJWtmZTqWQn7wHDvMRipVOEOQ==\",\n        \"dependencies\": {\n          \"System.Collections.Immutable\": \"9.0.0\",\n          \"System.Memory\": \"4.5.5\"\n        }\n      },\n      \"TunnelVisionLabs.ReferenceAssemblyAnnotator\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[1.0.0-alpha.160, )\",\n        \"resolved\": \"1.0.0-alpha.160\",\n        \"contentHash\": \"ktxB8PGoPpIaYKjLk/+P94Fi2Qw2E1Dw7atBQRrKnHA57sk8WwmkI4RJmg6s5ph4k1RIaaAZMus05ah/AikEkA==\"\n      },\n      \"Microsoft.Build.Tasks.Git\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.201\",\n        \"contentHash\": \"DMYBnrFZvLnBKn14VavEuuIr31CY6YY2i2L9P8DorS/Qp6ifRR8ZPLdJCFLFfjikNq8DykbYyLd/RP6lSqHcWw==\",\n        \"dependencies\": {\n          \"System.IO.Hashing\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.NETCore.Platforms\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"1.1.0\",\n        \"contentHash\": \"kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==\"\n      },\n      \"Microsoft.SourceLink.Common\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.201\",\n        \"contentHash\": \"QbBYhkjgL6rCnBfDbzsAJLlsad13TlBHqYCFDIw56OO2g6ix+9RsmY8uxiQGdWwFKbZXaXyAA6jDCzFYVGCZDw==\"\n      },\n      \"System.Buffers\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"4.6.1\",\n        \"contentHash\": \"N8GXpmiLMtljq7gwvyS+1QvKT/W2J8sNAvx+HVg4NGmsG/H+2k/y9QI23auLJRterrzCiDH+IWAw4V/GPwsMlw==\"\n      },\n      \"System.IO.Hashing\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"8IBJWcCT9+e4Bmevm4T7+fQEiAh133KGiz4oiVTgJckd3Q76OFdR1falgn9lpz7+C4HJvogCDJeAa2QmvbeVtg==\",\n        \"dependencies\": {\n          \"System.Buffers\": \"4.6.1\",\n          \"System.Memory\": \"4.6.3\"\n        }\n      },\n      \"System.Memory\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"4.6.3\",\n        \"contentHash\": \"qdcDOgnFZY40+Q9876JUHnlHu7bosOHX8XISRoH94fwk6hgaeQGSgfZd8srWRZNt5bV9ZW2TljcegDNxsf+96A==\",\n        \"dependencies\": {\n          \"System.Buffers\": \"4.6.1\",\n          \"System.Numerics.Vectors\": \"4.6.1\",\n          \"System.Runtime.CompilerServices.Unsafe\": \"6.1.2\"\n        }\n      },\n      \"System.Numerics.Vectors\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"4.6.1\",\n        \"contentHash\": \"sQxefTnhagrhoq2ReR0D/6K0zJcr9Hrd6kikeXsA1I8kOCboTavcUC4r7TSfpKFeE163uMuxZcyfO1mGO3EN8Q==\"\n      },\n      \"System.Runtime.CompilerServices.Unsafe\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"6.1.2\",\n        \"contentHash\": \"2hBr6zdbIBTDE3EhK7NSVNdX58uTK6iHW/P/Axmm9sl1xoGSLqDvMtpecn226TNwHByFokYwJmt/aQQNlO5CRw==\"\n      }\n    }\n  }\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.PowerShell/Demo.ps1",
    "content": "$basePath = $PSScriptRoot\nif ([string]::IsNullOrEmpty($basePath))\n{\n\t$basePath = Split-Path -parent $psISE.CurrentFile.Fullpath\n}\n\n$modulePath = $basePath + '\\bin\\Debug\\netstandard2.0\\ICSharpCode.Decompiler.Powershell.dll'\n\nImport-Module $modulePath\n$version = Get-DecompilerVersion\nWrite-Output $version\n\n# different test assemblies - it makes a difference wrt .deps.json so there are two netstandard tests here\n$asm_netstdWithDepsJson = $basePath + '\\bin\\Debug\\netstandard2.0\\ICSharpCode.Decompiler.Powershell.dll'\n$asm_netstd = $basePath + '\\bin\\Debug\\netstandard2.0\\ICSharpCode.Decompiler.dll'\n\n$decompiler = Get-Decompiler $asm_netstdWithDepsJson\n\n$classes = Get-DecompiledTypes $decompiler -Types class\n$classes.Count\n\nforeach ($c in $classes)\n{\n\tWrite-Output $c.FullName\n}\n\n\nGet-DecompiledSource $decompiler -TypeName ICSharpCode.Decompiler.PowerShell.GetDecompilerCmdlet\n\nGet-DecompiledProject $decompiler -OutputPath .\\decomptest"
  },
  {
    "path": "ICSharpCode.Decompiler.PowerShell/ErrorIds.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler.PowerShell\n{\n\tpublic static class ErrorIds\n\t{\n\t\tpublic static readonly string AssemblyLoadFailed = \"1\";\n\t\tpublic static readonly string DecompilationFailed = \"2\";\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.PowerShell/GetDecompiledProjectCmdlet.cs",
    "content": "using System;\nusing System.IO;\nusing System.Management.Automation;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.CSharp.ProjectDecompiler;\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.Decompiler.PowerShell\n{\n\t[Cmdlet(VerbsCommon.Get, \"DecompiledProject\")]\n\t[OutputType(typeof(string))]\n\tpublic class GetDecompiledProjectCmdlet : PSCmdlet, IProgress<DecompilationProgress>\n\t{\n\t\t[Parameter(Position = 0, Mandatory = true)]\n\t\tpublic CSharpDecompiler Decompiler { get; set; }\n\n\t\t[Parameter(Position = 1, Mandatory = true)]\n\t\t[Alias(\"PSPath\", \"OutputPath\")]\n\t\t[ValidateNotNullOrEmpty]\n\t\tpublic string LiteralPath { get; set; }\n\n\t\treadonly object syncObject = new object();\n\t\tint completed;\n\t\tstring fileName;\n\t\tProgressRecord progress;\n\n\t\tpublic void Report(DecompilationProgress value)\n\t\t{\n\t\t\tlock (syncObject)\n\t\t\t{\n\t\t\t\tcompleted++;\n\t\t\t\tprogress = new ProgressRecord(1, \"Decompiling \" + fileName, $\"Completed {completed} of {value.TotalUnits}: {value.Status}\") {\n\t\t\t\t\tPercentComplete = (int)(completed * 100.0 / value.TotalUnits)\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tprotected override void ProcessRecord()\n\t\t{\n\t\t\tstring path = GetUnresolvedProviderPathFromPSPath(LiteralPath);\n\t\t\tif (!Directory.Exists(path))\n\t\t\t{\n\t\t\t\tWriteObject(\"Destination directory must exist prior to decompilation\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar task = Task.Run(() => DoDecompile(path));\n\t\t\t\tint timeout = 100;\n\n\t\t\t\t// Give the decompiler some time to spin up all threads\n\t\t\t\tThread.Sleep(timeout);\n\n\t\t\t\twhile (!task.IsCompleted)\n\t\t\t\t{\n\t\t\t\t\tProgressRecord progress;\n\t\t\t\t\tlock (syncObject)\n\t\t\t\t\t{\n\t\t\t\t\t\tprogress = this.progress;\n\t\t\t\t\t\tthis.progress = null;\n\t\t\t\t\t}\n\t\t\t\t\tif (progress != null)\n\t\t\t\t\t{\n\t\t\t\t\t\ttimeout = 100;\n\t\t\t\t\t\tWriteProgress(progress);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tThread.Sleep(timeout);\n\t\t\t\t\t\ttimeout = Math.Min(1000, timeout * 2);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\ttask.Wait();\n\n\t\t\t\tWriteProgress(new ProgressRecord(1, \"Decompiling \" + fileName, \"Decompilation finished\") { RecordType = ProgressRecordType.Completed });\n\t\t\t}\n\t\t\tcatch (Exception e)\n\t\t\t{\n\t\t\t\tWriteVerbose(e.ToString());\n\t\t\t\tWriteError(new ErrorRecord(e, ErrorIds.DecompilationFailed, ErrorCategory.OperationStopped, null));\n\t\t\t}\n\t\t}\n\n\t\tprivate void DoDecompile(string path)\n\t\t{\n\t\t\tMetadataFile module = Decompiler.TypeSystem.MainModule.MetadataFile;\n\t\t\tvar assemblyResolver = new UniversalAssemblyResolver(module.FileName, false, module.Metadata.DetectTargetFrameworkId());\n\t\t\tWholeProjectDecompiler decompiler = new WholeProjectDecompiler(assemblyResolver);\n\t\t\tdecompiler.ProgressIndicator = this;\n\t\t\tfileName = module.FileName;\n\t\t\tcompleted = 0;\n\t\t\tdecompiler.DecompileProject(module, path);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.PowerShell/GetDecompiledSourceCmdlet.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Management.Automation;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.PowerShell\n{\n\t[Cmdlet(VerbsCommon.Get, \"DecompiledSource\")]\n\t[OutputType(typeof(string))]\n\tpublic class GetDecompiledSourceCmdlet : PSCmdlet\n\t{\n\t\t[Parameter(Position = 0, Mandatory = true)]\n\t\tpublic CSharpDecompiler Decompiler { get; set; }\n\n\t\t[Parameter]\n\t\tpublic string TypeName { get; set; } = string.Empty;\n\n\t\tprotected override void ProcessRecord()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tStringWriter output = new StringWriter();\n\t\t\t\tif (TypeName == null)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(Decompiler.DecompileWholeModuleAsString());\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar name = new FullTypeName(TypeName);\n\t\t\t\t\toutput.Write(Decompiler.DecompileTypeAsString(name));\n\t\t\t\t}\n\n\t\t\t\tWriteObject(output.ToString());\n\t\t\t}\n\t\t\tcatch (Exception e)\n\t\t\t{\n\t\t\t\tWriteVerbose(e.ToString());\n\t\t\t\tWriteError(new ErrorRecord(e, ErrorIds.DecompilationFailed, ErrorCategory.OperationStopped, null));\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.PowerShell/GetDecompiledTypesCmdlet.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Management.Automation;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.PowerShell\n{\n\t[Cmdlet(VerbsCommon.Get, \"DecompiledTypes\")]\n\t[OutputType(typeof(ITypeDefinition[]))]\n\tpublic class GetDecompiledTypesCmdlet : PSCmdlet\n\t{\n\t\t[Parameter(Position = 0, Mandatory = true)]\n\t\tpublic CSharpDecompiler Decompiler { get; set; }\n\n\t\t[Parameter(Mandatory = true)]\n\t\tpublic string[] Types { get; set; }\n\n\t\tprotected override void ProcessRecord()\n\t\t{\n\t\t\tHashSet<TypeKind> kinds = TypesParser.ParseSelection(Types);\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tList<ITypeDefinition> output = new List<ITypeDefinition>();\n\t\t\t\tforeach (var type in Decompiler.TypeSystem.MainModule.TypeDefinitions)\n\t\t\t\t{\n\t\t\t\t\tif (!kinds.Contains(type.Kind))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\toutput.Add(type);\n\t\t\t\t}\n\n\t\t\t\tWriteObject(output.ToArray());\n\t\t\t}\n\t\t\tcatch (Exception e)\n\t\t\t{\n\t\t\t\tWriteVerbose(e.ToString());\n\t\t\t\tWriteError(new ErrorRecord(e, ErrorIds.DecompilationFailed, ErrorCategory.OperationStopped, null));\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.PowerShell/GetDecompilerCmdlet.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Management.Automation;\nusing System.Reflection.PortableExecutable;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpyX.PdbProvider;\n\nnamespace ICSharpCode.Decompiler.PowerShell\n{\n\t[Cmdlet(VerbsCommon.Get, \"Decompiler\")]\n\t[OutputType(typeof(CSharpDecompiler))]\n\tpublic class GetDecompilerCmdlet : PSCmdlet\n\t{\n\t\t[Parameter(Position = 0, Mandatory = true, HelpMessage = \"Path to the assembly you want to decompile\")]\n\t\t[Alias(\"PSPath\")]\n\t\t[ValidateNotNullOrEmpty]\n\t\tpublic string LiteralPath { get; set; }\n\n\t\t[Parameter(HelpMessage = \"C# Language version to be used by the decompiler\")]\n\t\tpublic LanguageVersion LanguageVersion { get; set; } = LanguageVersion.Latest;\n\n\t\t[Parameter(HelpMessage = \"Remove dead stores\")]\n\t\tpublic bool RemoveDeadStores { get; set; }\n\n\t\t[Parameter(HelpMessage = \"Remove dead code\")]\n\t\tpublic bool RemoveDeadCode { get; set; }\n\n\t\t[Parameter(HelpMessage = \"Use PDB\")]\n\t\tpublic string PDBFilePath { get; set; }\n\n\t\tprotected override void ProcessRecord()\n\t\t{\n\t\t\tstring path = GetUnresolvedProviderPathFromPSPath(LiteralPath);\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar module = new PEFile(LiteralPath, new FileStream(LiteralPath, FileMode.Open, FileAccess.Read), PEStreamOptions.Default);\n\t\t\t\tvar debugInfo = DebugInfoUtils.FromFile(module, PDBFilePath);\n\t\t\t\tvar decompiler = new CSharpDecompiler(path, new DecompilerSettings(LanguageVersion) {\n\t\t\t\t\tThrowOnAssemblyResolveErrors = false,\n\t\t\t\t\tRemoveDeadCode = RemoveDeadCode,\n\t\t\t\t\tRemoveDeadStores = RemoveDeadStores,\n\t\t\t\t\tUseDebugSymbols = debugInfo != null,\n\t\t\t\t\tShowDebugInfo = debugInfo != null,\n\t\t\t\t});\n\t\t\t\tdecompiler.DebugInfoProvider = debugInfo;\n\t\t\t\tWriteObject(decompiler);\n\t\t\t}\n\t\t\tcatch (Exception e)\n\t\t\t{\n\t\t\t\tWriteVerbose(e.ToString());\n\t\t\t\tWriteError(new ErrorRecord(e, ErrorIds.AssemblyLoadFailed, ErrorCategory.OperationStopped, null));\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.PowerShell/GetDecompilerVersion.cs",
    "content": "using System;\nusing System.Management.Automation;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.PowerShell\n{\n\t[Cmdlet(VerbsCommon.Get, \"DecompilerVersion\")]\n\t[OutputType(typeof(string))]\n\tpublic class GetDecompilerVersion : PSCmdlet\n\t{\n\t\tprotected override void ProcessRecord()\n\t\t{\n\t\t\tWriteObject(typeof(FullTypeName).Assembly.GetName().Version.ToString());\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.PowerShell/GetTargetFramework.cs",
    "content": "using System.Management.Automation;\n\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.Decompiler.PowerShell\n{\n\t[Cmdlet(VerbsCommon.Get, \"TargetFramework\")]\n\t[OutputType(typeof(string))]\n\tpublic class GetTargetFramework : PSCmdlet\n\t{\n\t\t[Parameter(Position = 0, Mandatory = true)]\n\t\tpublic CSharpDecompiler Decompiler { get; set; }\n\n\t\tprotected override void ProcessRecord()\n\t\t{\n\t\t\tMetadataFile module = Decompiler.TypeSystem.MainModule.MetadataFile;\n\t\t\tWriteObject(module.Metadata.DetectTargetFrameworkId());\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.PowerShell/ICSharpCode.Decompiler.PowerShell.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <TargetFramework>netstandard2.0</TargetFramework>\r\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\r\n    <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>\r\n    <RootNamespace>ICSharpCode.Decompiler.PowerShell</RootNamespace>\r\n    <LangVersion>8.0</LangVersion>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"PowerShellStandard.Library\" />\r\n    <PackageReference Include=\"Mono.Cecil\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\ICSharpCode.Decompiler\\ICSharpCode.Decompiler.csproj\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <Compile Include=\"..\\ICSharpCode.ILSpyX\\PdbProvider\\MonoCecilDebugInfoProvider.cs\" Link=\"%(Filename)%(Extension)\" />\r\n    <Compile Include=\"..\\ICSharpCode.ILSpyX\\PdbProvider\\PortableDebugInfoProvider.cs\" Link=\"%(Filename)%(Extension)\" />\r\n    <Compile Include=\"..\\ICSharpCode.ILSpyX\\PdbProvider\\DebugInfoUtils.cs\" Link=\"%(Filename)%(Extension)\" />\r\n  </ItemGroup>\r\n\r\n  <Target Name=\"PostBuild\" AfterTargets=\"PostBuildEvent\">\r\n    <Exec Condition=\" '$(OS)' == 'Windows_NT' \" Command=\"powershell -Command &quot;Copy-Item $(ProjectDir)manifest.psd1 $(TargetDir)$(TargetName).psd1&quot;\" />\r\n\t<Exec Condition=\" '$(OS)' != 'Windows_NT' \" Command=\"pwsh -Command &quot;Copy-Item $(ProjectDir)manifest.psd1 $(TargetDir)$(TargetName).psd1&quot;\" />\r\n  </Target>\r\n</Project>\r\n"
  },
  {
    "path": "ICSharpCode.Decompiler.PowerShell/NullAttributes.cs",
    "content": "#if !NETCORE\n\n#nullable enable\n\nnamespace System.Diagnostics.CodeAnalysis\n{\n\t[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true)]\n\tinternal sealed class NotNullIfNotNullAttribute : Attribute\n\t{\n\t\tpublic string ParameterName { get; }\n\n\t\tpublic NotNullIfNotNullAttribute(string parameterName)\n\t\t{\n\t\t\tParameterName = parameterName;\n\t\t}\n\t}\n\n\t[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]\n\tinternal sealed class NotNullWhenAttribute : Attribute\n\t{\n\t\tpublic NotNullWhenAttribute(bool returnValue)\n\t\t{\n\t\t\tReturnValue = returnValue;\n\t\t}\n\n\t\tpublic bool ReturnValue { get; }\n\t}\n\n\t[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]\n\tinternal sealed class DoesNotReturnIfAttribute : Attribute\n\t{\n\t\tpublic DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue;\n\n\t\tpublic bool ParameterValue { get; }\n\t}\n}\n#endif\n"
  },
  {
    "path": "ICSharpCode.Decompiler.PowerShell/README.md",
    "content": "# ILSpy PowerShell Module\n\nBuilt using https://github.com/PowerShell/PowerShell/blob/master/docs/cmdlet-example/command-line-simple-example.md as guideline\n\nSample usage: Demo.ps1\n\nTested with: PowerShell 5.1 on Windows, PowerShell 7+ on Windows and Mac\n\n\n\n## Missing\n\nPublishing to https://www.powershellgallery.com/\n\n* https://learn.microsoft.com/en-us/powershell/gallery/how-to/publishing-packages/publishing-a-package\n* https://learn.microsoft.com/en-us/powershell/gallery/concepts/publishing-guidelines\n\n## Links for developing PS cmdlets\n\n* https://learn.microsoft.com/en-us/powershell/scripting/developer/cmdlet/how-to-write-a-simple-cmdlet\n* https://learn.microsoft.com/en-us/powershell/scripting/developer/cmdlet/approved-verbs-for-windows-powershell-commands\n* https://github.com/mmaitre314/PowerShellGet-Test-Binary-Module\n* https://www.red-gate.com/simple-talk/dotnet/net-development/using-c-to-create-powershell-cmdlets-beyond-the-basics/\n* https://www.google.com/search?q=write+a+module+for+powershell+core"
  },
  {
    "path": "ICSharpCode.Decompiler.PowerShell/TypesParser.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.PowerShell\n{\n\tpublic static class TypesParser\n\t{\n\t\tpublic static HashSet<TypeKind> ParseSelection(string[] values)\n\t\t{\n\t\t\tvar possibleValues = new Dictionary<string, TypeKind>(StringComparer.OrdinalIgnoreCase) { [\"class\"] = TypeKind.Class, [\"struct\"] = TypeKind.Struct, [\"interface\"] = TypeKind.Interface, [\"enum\"] = TypeKind.Enum, [\"delegate\"] = TypeKind.Delegate };\n\t\t\tHashSet<TypeKind> kinds = new HashSet<TypeKind>();\n\t\t\tif (values.Length == 1 && !possibleValues.Keys.Any(v => values[0].StartsWith(v, StringComparison.OrdinalIgnoreCase)))\n\t\t\t{\n\t\t\t\tforeach (char ch in values[0])\n\t\t\t\t{\n\t\t\t\t\tswitch (ch)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase 'c':\n\t\t\t\t\t\t\tkinds.Add(TypeKind.Class);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'i':\n\t\t\t\t\t\t\tkinds.Add(TypeKind.Interface);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 's':\n\t\t\t\t\t\t\tkinds.Add(TypeKind.Struct);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'd':\n\t\t\t\t\t\t\tkinds.Add(TypeKind.Delegate);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'e':\n\t\t\t\t\t\t\tkinds.Add(TypeKind.Enum);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tforeach (var value in values)\n\t\t\t\t{\n\t\t\t\t\tstring v = value;\n\t\t\t\t\twhile (v.Length > 0 && !possibleValues.ContainsKey(v))\n\t\t\t\t\t\tv = v.Remove(v.Length - 1);\n\t\t\t\t\tif (possibleValues.TryGetValue(v, out var kind))\n\t\t\t\t\t\tkinds.Add(kind);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn kinds;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.PowerShell/manifest.psd1",
    "content": "@{\n  # Script module or binary module file associated with this manifest.\n  RootModule        = 'ICSharpCode.Decompiler.PowerShell.dll'\n\n  # Version number of this module.\n  ModuleVersion     = '8.0.0.0'\n\n  # Supported PSEditions\n  # CompatiblePSEditions = @()\n\n  # ID used to uniquely identify this module\n  GUID              = '198b4312-cbe7-417e-81a7-1aaff467ef06'\n\n  # Author of this module\n  Author            = 'ILSpy Contributors'\n\n  # Company or vendor of this module\n  CompanyName       = 'ic#code'\n\n  # Copyright statement for this module\n  Copyright         = 'Copyright 2011-2023 AlphaSierraPapa'\n\n  # Description of the functionality provided by this module\n  Description       = 'PowerShell front-end for ILSpy'\n\n  # Minimum version of the PowerShell engine required by this module\n  # PowerShellVersion = ''\n\n  # Name of the PowerShell host required by this module\n  # PowerShellHostName = ''\n\n  # Minimum version of the PowerShell host required by this module\n  # PowerShellHostVersion = ''\n\n  # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.\n  # DotNetFrameworkVersion = ''\n\n  # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.\n  # ClrVersion = ''\n\n  # Processor architecture (None, X86, Amd64) required by this module\n  # ProcessorArchitecture = ''\n\n  # Modules that must be imported into the global environment prior to importing this module\n  # RequiredModules = @()\n\n  # Assemblies that must be loaded prior to importing this module\n  # RequiredAssemblies = @()\n\n  # Script files (.ps1) that are run in the caller's environment prior to importing this module.\n  # ScriptsToProcess = @()\n\n  # Type files (.ps1xml) to be loaded when importing this module\n  # TypesToProcess = @()\n\n  # Format files (.ps1xml) to be loaded when importing this module\n  # FormatsToProcess = @()\n\n  # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess\n  # NestedModules = @()\n\n  # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.\n  FunctionsToExport = @()\n\n  # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.\n  CmdletsToExport   = @(\n    'Get-DecompiledProject',\n    'Get-DecompiledSource',\n    'Get-DecompiledTypes',\n    'Get-Decompiler',\n    'Get-DecompilerVersion',\n    'Get-TargetFramework'\n  )\n\n  # Variables to export from this module\n  VariablesToExport = '*'\n\n  # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.\n  AliasesToExport   = @()\n\n  # DSC resources to export from this module\n  # DscResourcesToExport = @()\n\n  # List of all modules packaged with this module\n  # ModuleList = @()\n\n  # List of all files packaged with this module\n  # FileList = @()\n\n  # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.\n  PrivateData       = @{\n\n    PSData = @{\n\n      # Tags applied to this module. These help with module discovery in online galleries.\n      # Tags = @()\n\n      # A URL to the license for this module.\n      # LicenseUri = ''\n\n      # A URL to the main website for this project.\n      ProjectUri = 'https://github.com/icsharpcode/ILSpy'\n\n      # A URL to an icon representing this module.\n      # IconUri = ''\n\n      # ReleaseNotes of this module\n      # ReleaseNotes = ''\n\n      # Prerelease string of this module\n      # Prerelease = ''\n\n      # Flag to indicate whether the module requires explicit user acceptance for install/update/save\n      # RequireLicenseAcceptance = $false\n\n      # External dependent modules of this module\n      # ExternalModuleDependencies = @()\n\n    } # End of PSData hashtable\n\n  } # End of PrivateData hashtable\n\n  # HelpInfo URI of this module\n  # HelpInfoURI = ''\n\n  # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.\n  # DefaultCommandPrefix = ''\n\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler.TestRunner/ICSharpCode.Decompiler.TestRunner.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net10.0</TargetFramework>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "ICSharpCode.Decompiler.TestRunner/Program.cs",
    "content": "// Copyright (c) 2022 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Reflection;\nusing System.Runtime.Loader;\n\nnamespace ICSharpCode.Decompiler.TestRunner;\n\npublic static class Program\n{\n\tstatic int Main(string[] args)\n\t{\n\t\tAssemblyLoadContext context = new(\"TestRunner\", isCollectible: true);\n\t\tcontext.Resolving += ContextResolving;\n\n\t\ttry\n\t\t{\n\t\t\tvar mainAssembly = context.LoadFromAssemblyPath(args[0]);\n\t\t\tint paramCount = mainAssembly.EntryPoint!.GetParameters().Length;\n\t\t\tobject? result = mainAssembly.EntryPoint!.Invoke(null, paramCount == 0 ? new object[0] : new object[1] { new string[0] });\n\t\t\treturn result is int i ? i : 0;\n\t\t}\n\t\tcatch (Exception ex)\n\t\t{\n\t\t\tConsole.Error.WriteLine(\"TestRunner crashed:\");\n\t\t\tConsole.Error.WriteLine(ex.ToString());\n\t\t\treturn -1;\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tcontext.Unload();\n\t\t\tcontext.Resolving -= ContextResolving;\n\t\t}\n\t}\n\n\tprivate static Assembly? ContextResolving(AssemblyLoadContext context, AssemblyName name)\n\t{\n\t\treturn null;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/.editorconfig",
    "content": "# We disable some of the rules that don't make sense in our test\n[*.cs]\ndotnet_diagnostic.CA1060.severity = none\ndotnet_diagnostic.CA1063.severity = none\ndotnet_diagnostic.CA1065.severity = none\ndotnet_diagnostic.CA1401.severity = none\ndotnet_diagnostic.CA1821.severity = none\ndotnet_diagnostic.CA2002.severity = none\ndotnet_diagnostic.CA2101.severity = none\ndotnet_diagnostic.CA2241.severity = none\ndotnet_diagnostic.CA2263.severity = none # disable because it's choking on our test code in UndocumentedExpressions.cs\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.IO;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.Tests.Helpers;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests\n{\n\t[TestFixture, Parallelizable(ParallelScope.All)]\n\tpublic class CorrectnessTestRunner\n\t{\n\t\tstatic readonly string TestCasePath = Tester.TestCasePath + \"/Correctness\";\n\n\t\t[Test]\n\t\tpublic void AllFilesHaveTests()\n\t\t{\n\t\t\tvar testNames = typeof(CorrectnessTestRunner).GetMethods()\n\t\t\t\t.Where(m => m.GetCustomAttributes(typeof(TestAttribute), false).Any())\n\t\t\t\t.Select(m => m.Name)\n\t\t\t\t.ToArray();\n\t\t\tforeach (var file in new DirectoryInfo(TestCasePath).EnumerateFiles())\n\t\t\t{\n\t\t\t\tif (file.Extension == \".txt\" || file.Extension == \".exe\" || file.Extension == \".config\")\n\t\t\t\t\tcontinue;\n\t\t\t\tvar testName = Path.GetFileNameWithoutExtension(file.Name);\n\t\t\t\tAssert.That(testNames, Has.Member(testName));\n\t\t\t}\n\t\t}\n\n\t\tstatic readonly CompilerOptions[] noMonoOptions =\n\t\t{\n\t\t\tCompilerOptions.None,\n\t\t\tCompilerOptions.Optimize,\n\t\t\tCompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn1_3_2,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,\n\t\t\tCompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,\n\t\t};\n\n\t\tstatic readonly CompilerOptions[] net40OnlyOptions =\n\t\t{\n\t\t\tCompilerOptions.None,\n\t\t\tCompilerOptions.Optimize,\n\t\t\tCompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40\n\t\t};\n\n\t\tstatic readonly CompilerOptions[] defaultOptions =\n\t\t{\n\t\t\tCompilerOptions.None,\n\t\t\tCompilerOptions.Optimize,\n\t\t\tCompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn1_3_2,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,\n\t\t\tCompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.UseMcs2_6_4,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseMcs2_6_4,\n\t\t\tCompilerOptions.UseMcs5_23,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseMcs5_23\n\t\t};\n\n\t\tstatic readonly CompilerOptions[] roslynOnlyOptions =\n\t\t{\n\t\t\tCompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn1_3_2,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,\n\t\t\tCompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,\n\t\t};\n\n\t\tstatic readonly CompilerOptions[] roslyn2OrNewerOptions =\n\t\t{\n\t\t\tCompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,\n\t\t};\n\n\t\tstatic readonly CompilerOptions[] roslynLatestOnlyOptions =\n\t\t{\n\t\t\tCompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,\n\t\t};\n\n\t\t[Test]\n\t\tpublic async Task Comparisons([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Conversions([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task FloatingPointArithmetic([ValueSource(nameof(noMonoOptions))] CompilerOptions options, [Values(32, 64)] int bits)\n\t\t{\n\t\t\t// The behavior of the #1794 incorrect `(float)(double)val` cast only causes test failures\n\t\t\t// for some runtime+compiler combinations.\n\t\t\tif (bits == 32)\n\t\t\t\toptions |= CompilerOptions.Force32Bit;\n\t\t\t// Mono is excluded because we never use it for the second pass, so the test ends up failing\n\t\t\t// due to some Mono vs. Roslyn compiler differences.\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task HelloWorld([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ControlFlow([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task CompoundAssignment([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task PropertiesAndEvents([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Switch([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Using([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Loops([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task NullableTests([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Generics([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ValueTypeCall([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task InitializerTests([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task DecimalFields([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task UndocumentedExpressions([ValueSource(nameof(noMonoOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Uninit([ValueSource(nameof(noMonoOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunVB(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task MemberLookup([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task OverloadResolution([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ExpressionTrees([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task NullPropagation([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task DeconstructionTests([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task BitNot([Values(false, true)] bool force32Bit)\n\t\t{\n\t\t\tCompilerOptions compiler = CompilerOptions.UseDebug;\n\t\t\tAssemblerOptions asm = AssemblerOptions.None;\n\t\t\tif (force32Bit)\n\t\t\t{\n\t\t\t\tcompiler |= CompilerOptions.Force32Bit;\n\t\t\t\tasm |= AssemblerOptions.Force32Bit;\n\t\t\t}\n\t\t\tawait RunIL(\"BitNot.il\", compiler, asm);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Jmp()\n\t\t{\n\t\t\tawait RunIL(\"Jmp.il\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task NonGenericConstrainedCallVirt()\n\t\t{\n\t\t\tawait RunIL(\"NonGenericConstrainedCallVirt.il\", CompilerOptions.UseRoslynLatest);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task StackTests()\n\t\t{\n\t\t\t// IL contains .corflags = 32BITREQUIRED\n\t\t\tawait RunIL(\"StackTests.il\", CompilerOptions.Force32Bit, AssemblerOptions.Force32Bit);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task StackTypes([Values(false, true)] bool force32Bit)\n\t\t{\n\t\t\tCompilerOptions compiler = CompilerOptions.UseRoslynLatest | CompilerOptions.UseDebug;\n\t\t\tAssemblerOptions asm = AssemblerOptions.None;\n\t\t\tif (force32Bit)\n\t\t\t{\n\t\t\t\tcompiler |= CompilerOptions.Force32Bit;\n\t\t\t\tasm |= AssemblerOptions.Force32Bit;\n\t\t\t}\n\t\t\tawait RunIL(\"StackTypes.il\", compiler, asm);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task UnsafeCode([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ConditionalAttr([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task TrickyTypes([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Capturing([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task YieldReturn([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tif ((options & CompilerOptions.UseMcsMask) != 0)\n\t\t\t{\n\t\t\t\tAssert.Ignore(\"Decompiler bug with mono!\");\n\t\t\t}\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Async([ValueSource(nameof(noMonoOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task LINQRaytracer([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task StringConcat([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task DynamicTests([ValueSource(nameof(noMonoOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task MiniJSON([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ComInterop([ValueSource(nameof(net40OnlyOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait RunCS(options: options);\n\t\t}\n\n\t\tasync Task RunCS([CallerMemberName] string testName = null, CompilerOptions options = CompilerOptions.UseDebug)\n\t\t{\n\t\t\tif ((options & CompilerOptions.UseRoslynMask) != 0 && (options & CompilerOptions.TargetNet40) == 0)\n\t\t\t\toptions |= CompilerOptions.UseTestRunner;\n\t\t\tstring testFileName = testName + \".cs\";\n\t\t\tstring testOutputFileName = TestsAssemblyOutput.GetFilePath(TestCasePath, testName, Tester.GetSuffix(options) + \".exe\");\n\t\t\tHelpers.CompilerResults outputFile = null, decompiledOutputFile = null;\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\toutputFile = await Tester.CompileCSharp(Path.Combine(TestCasePath, testFileName), options,\n\t\t\t\t\toutputFileName: testOutputFileName).ConfigureAwait(false);\n\t\t\t\tstring decompiledCodeFile = await Tester.DecompileCSharp(outputFile.PathToAssembly, Tester.GetSettings(options)).ConfigureAwait(false);\n\t\t\t\tif ((options & CompilerOptions.UseMcsMask) != 0)\n\t\t\t\t{\n\t\t\t\t\t// For second pass, use roslyn instead of mcs.\n\t\t\t\t\t// mcs has some compiler bugs that cause it to not accept ILSpy-generated code,\n\t\t\t\t\t// for example when there's unreachable code due to other compiler bugs in the first mcs run.\n\t\t\t\t\toptions &= ~CompilerOptions.UseMcsMask;\n\t\t\t\t\toptions |= CompilerOptions.UseRoslynLatest;\n\t\t\t\t\t// Also, add an .exe.config so that we consistently use the .NET 4.x runtime.\n\t\t\t\t\tFile.WriteAllText(outputFile.PathToAssembly + \".config\", @\"<?xml version=\"\"1.0\"\" encoding=\"\"utf-8\"\"?>\n<configuration>\n\t<startup>\n\t\t<supportedRuntime version=\"\"v4.0\"\" sku=\"\".NETFramework,Version=v4.0,Profile=Client\"\" />\n\t</startup>\n</configuration>\");\n\t\t\t\t\toptions |= CompilerOptions.TargetNet40;\n\t\t\t\t}\n\t\t\t\tdecompiledOutputFile = await Tester.CompileCSharp(decompiledCodeFile, options).ConfigureAwait(false);\n\n\t\t\t\tawait Tester.RunAndCompareOutput(testFileName, outputFile.PathToAssembly, decompiledOutputFile.PathToAssembly, decompiledCodeFile, (options & CompilerOptions.UseTestRunner) != 0, (options & CompilerOptions.Force32Bit) != 0);\n\t\t\t\tTester.RepeatOnIOError(() => File.Delete(decompiledCodeFile));\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tif (outputFile != null)\n\t\t\t\t\toutputFile.DeleteTempFiles();\n\t\t\t\tif (decompiledOutputFile != null)\n\t\t\t\t\tdecompiledOutputFile.DeleteTempFiles();\n\t\t\t}\n\t\t}\n\n\t\tasync Task RunVB([CallerMemberName] string testName = null, CompilerOptions options = CompilerOptions.UseDebug)\n\t\t{\n\t\t\toptions |= CompilerOptions.ReferenceVisualBasic;\n\t\t\tif ((options & CompilerOptions.UseRoslynMask) != 0)\n\t\t\t\toptions |= CompilerOptions.UseTestRunner;\n\t\t\tstring testFileName = testName + \".vb\";\n\t\t\tstring testOutputFileName = TestsAssemblyOutput.GetFilePath(TestCasePath, testName, Tester.GetSuffix(options) + \".exe\");\n\t\t\tHelpers.CompilerResults outputFile = null, decompiledOutputFile = null;\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\toutputFile = await Tester.CompileVB(Path.Combine(TestCasePath, testFileName), options,\n\t\t\t\t\toutputFileName: testOutputFileName).ConfigureAwait(false);\n\t\t\t\tstring decompiledCodeFile = await Tester.DecompileCSharp(outputFile.PathToAssembly, Tester.GetSettings(options)).ConfigureAwait(false);\n\t\t\t\tdecompiledOutputFile = await Tester.CompileCSharp(decompiledCodeFile, options).ConfigureAwait(false);\n\n\t\t\t\tawait Tester.RunAndCompareOutput(testFileName, outputFile.PathToAssembly, decompiledOutputFile.PathToAssembly, decompiledCodeFile, (options & CompilerOptions.UseTestRunner) != 0, (options & CompilerOptions.Force32Bit) != 0);\n\t\t\t\tTester.RepeatOnIOError(() => File.Delete(decompiledCodeFile));\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tif (outputFile != null)\n\t\t\t\t\toutputFile.DeleteTempFiles();\n\t\t\t\tif (decompiledOutputFile != null)\n\t\t\t\t\tdecompiledOutputFile.DeleteTempFiles();\n\t\t\t}\n\t\t}\n\n\t\tasync Task RunIL(string testFileName, CompilerOptions options = CompilerOptions.UseDebug, AssemblerOptions asmOptions = AssemblerOptions.None)\n\t\t{\n\t\t\tstring outputFile = null;\n\t\t\tHelpers.CompilerResults decompiledOutputFile = null;\n\n\t\t\tbool optionsForce32Bit = options.HasFlag(CompilerOptions.Force32Bit);\n\t\t\tbool asmOptionsForce32Bit = asmOptions.HasFlag(AssemblerOptions.Force32Bit);\n\n\t\t\tAssert.That(asmOptionsForce32Bit, Is.EqualTo(optionsForce32Bit), \"Inconsistent architecture.\");\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\toptions |= CompilerOptions.UseTestRunner;\n\t\t\t\toutputFile = await Tester.AssembleIL(Path.Combine(TestCasePath, testFileName), asmOptions).ConfigureAwait(false);\n\t\t\t\tstring decompiledCodeFile = await Tester.DecompileCSharp(outputFile, Tester.GetSettings(options)).ConfigureAwait(false);\n\t\t\t\tdecompiledOutputFile = await Tester.CompileCSharp(decompiledCodeFile, options).ConfigureAwait(false);\n\n\t\t\t\tawait Tester.RunAndCompareOutput(testFileName, outputFile, decompiledOutputFile.PathToAssembly, decompiledCodeFile, (options & CompilerOptions.UseTestRunner) != 0, (options & CompilerOptions.Force32Bit) != 0).ConfigureAwait(false);\n\t\t\t\tTester.RepeatOnIOError(() => File.Delete(decompiledCodeFile));\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tif (decompiledOutputFile != null)\n\t\t\t\t\tdecompiledOutputFile.DeleteTempFiles();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/DataFlowTest.cs",
    "content": "// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.FlowAnalysis;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests\n{\n\t[TestFixture]\n\tclass DataFlowTest\n\t{\n\t\tclass RDTest : ReachingDefinitionsVisitor\n\t\t{\n\t\t\tILVariable v;\n\n\t\t\tpublic RDTest(ILFunction f, ILVariable v) : base(f, _ => true, CancellationToken.None)\n\t\t\t{\n\t\t\t\tthis.v = v;\n\t\t\t}\n\n\t\t\tprotected internal override void VisitTryFinally(TryFinally inst)\n\t\t\t{\n\t\t\t\tAssert.That(IsPotentiallyUninitialized(state, v));\n\t\t\t\tbase.VisitTryFinally(inst);\n\t\t\t\tAssert.That(state.IsReachable);\n\t\t\t\tAssert.That(GetStores(state, v).Count(), Is.EqualTo(1));\n\t\t\t\tAssert.That(!IsPotentiallyUninitialized(state, v));\n\t\t\t}\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TryFinallyWithAssignmentInFinally()\n\t\t{\n\t\t\tILVariable v = new ILVariable(VariableKind.Local, SpecialType.UnknownType, 0);\n\t\t\tILFunction f = new ILFunction(\n\t\t\t\treturnType: SpecialType.UnknownType,\n\t\t\t\tparameters: new IParameter[0],\n\t\t\t\tgenericContext: new GenericContext(),\n\t\t\t\tbody: new TryFinally(\n\t\t\t\t\tnew Nop(),\n\t\t\t\t\tnew StLoc(v, new LdcI4(0))\n\t\t\t\t));\n\t\t\tf.AddRef();\n\t\t\tf.Variables.Add(v);\n\t\t\tf.Body.AcceptVisitor(new RDTest(f, v));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/DisassemblerPrettyTestRunner.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Text;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.Tests.Helpers;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests\n{\n\t[TestFixture, Parallelizable(ParallelScope.All)]\n\tpublic class DisassemblerPrettyTestRunner\n\t{\n\t\tstatic readonly string TestCasePath = Tester.TestCasePath + \"/Disassembler/Pretty\";\n\n\t\t[Test]\n\t\tpublic void AllFilesHaveTests()\n\t\t{\n\t\t\tvar testNames = typeof(DisassemblerPrettyTestRunner).GetMethods()\n\t\t\t\t.Where(m => m.GetCustomAttributes(typeof(TestAttribute), false).Any())\n\t\t\t\t.Select(m => m.Name)\n\t\t\t\t.ToArray();\n\t\t\tforeach (var file in new DirectoryInfo(TestCasePath).EnumerateFiles())\n\t\t\t{\n\t\t\t\tif (file.Extension.Equals(\".il\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t{\n\t\t\t\t\tvar testName = file.Name.Split('.')[0];\n\t\t\t\t\tAssert.That(testNames, Has.Member(testName));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task GenericConstraints()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task SecurityDeclarations()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task SortMembers()\n\t\t{\n\t\t\tawait Run(ilExpectedFile: Path.Combine(TestCasePath, \"SortMembers.expected.il\"), asmOptions: AssemblerOptions.SortedOutput);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task InterfaceImplAttributes()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\tasync Task Run([CallerMemberName] string testName = null, string ilExpectedFile = null, AssemblerOptions asmOptions = AssemblerOptions.None)\n\t\t{\n\t\t\tvar ilInputFile = Path.Combine(TestCasePath, testName + \".il\");\n\t\t\tilExpectedFile ??= ilInputFile;\n\t\t\tvar ilResultFile = Path.Combine(TestCasePath, testName + \".result.il\");\n\n\t\t\tvar executable = await Tester.AssembleIL(ilInputFile, AssemblerOptions.Library).ConfigureAwait(false);\n\t\t\tvar disassembled = await Tester.Disassemble(executable, ilResultFile, AssemblerOptions.UseOwnDisassembler | asmOptions).ConfigureAwait(false);\n\n\t\t\tCodeAssert.FilesAreEqual(ilExpectedFile, disassembled);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/Helpers/CodeAssert.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\n\nusing DiffLib;\nusing DiffLib.Alignment;\n\nusing Microsoft.CodeAnalysis;\nusing Microsoft.CodeAnalysis.CSharp;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests.Helpers\n{\n\tpublic static class CodeAssert\n\t{\n\t\tpublic static void FilesAreEqual(string fileName1, string fileName2, string[] definedSymbols = null)\n\t\t{\n\t\t\tAreEqual(File.ReadAllText(fileName1), File.ReadAllText(fileName2), definedSymbols);\n\t\t}\n\n\t\tpublic static void AreEqual(string input1, string input2, string[] definedSymbols = null)\n\t\t{\n\t\t\tvar diff = new StringWriter();\n\t\t\tif (!CodeComparer.Compare(input1, input2, diff, CodeComparer.NormalizeLine, definedSymbols))\n\t\t\t{\n\t\t\t\tAssert.Fail(diff.ToString());\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic static class CodeComparer\n\t{\n\t\tpublic static bool Compare(string input1, string input2, StringWriter diff, Func<string, string> normalizeLine, string[] definedSymbols = null)\n\t\t{\n\t\t\tvar collection1 = NormalizeAndSplitCode(input1, definedSymbols ?? new string[0]);\n\t\t\tvar collection2 = NormalizeAndSplitCode(input2, definedSymbols ?? new string[0]);\n\t\t\tvar diffSections = DiffLib.Diff.CalculateSections(\n\t\t\t\tcollection1, collection2, new CodeLineEqualityComparer(normalizeLine)\n\t\t\t);\n\t\t\tvar alignedDiff = Diff.AlignElements(collection1, collection2, diffSections, new StringSimilarityDiffElementAligner());\n\n\t\t\tbool result = true;\n\t\t\tint line1 = 0, line2 = 0;\n\t\t\tconst int contextSize = 10;\n\t\t\tint consecutiveMatches = contextSize;\n\t\t\tvar hiddenMatches = new List<string>();\n\n\t\t\tforeach (var change in alignedDiff)\n\t\t\t{\n\t\t\t\tswitch (change.Operation)\n\t\t\t\t{\n\t\t\t\t\tcase DiffOperation.Match:\n\t\t\t\t\t\tAppendMatch($\"{++line1,4} {++line2,4} \", change.ElementFromCollection1.Value);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase DiffOperation.Insert:\n\t\t\t\t\t\tstring pos = $\"     {++line2,4} \";\n\t\t\t\t\t\tif (ShouldIgnoreChange(change.ElementFromCollection2.Value))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAppendMatch(pos, change.ElementFromCollection2.Value);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAppendDelta(pos, \" + \", change.ElementFromCollection2.Value);\n\t\t\t\t\t\t\tresult = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase DiffOperation.Delete:\n\t\t\t\t\t\tpos = $\"{++line1,4}      \";\n\t\t\t\t\t\tif (ShouldIgnoreChange(change.ElementFromCollection1.Value))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAppendMatch(pos, change.ElementFromCollection1.Value);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAppendDelta(pos, \" - \", change.ElementFromCollection1.Value);\n\t\t\t\t\t\t\tresult = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase DiffOperation.Modify:\n\t\t\t\t\tcase DiffOperation.Replace:\n\t\t\t\t\t\tAppendDelta($\"{++line1,4}      \", \"(-)\", change.ElementFromCollection1.Value);\n\t\t\t\t\t\tAppendDelta($\"     {++line2,4} \", \"(+)\", change.ElementFromCollection2.Value);\n\t\t\t\t\t\tresult = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (hiddenMatches.Count > 0)\n\t\t\t{\n\t\t\t\tdiff.WriteLine(\"  ...\");\n\t\t\t}\n\n\t\t\treturn result;\n\n\t\t\tvoid AppendMatch(string pos, string code)\n\t\t\t{\n\t\t\t\tconsecutiveMatches++;\n\t\t\t\tif (consecutiveMatches > contextSize)\n\t\t\t\t{\n\t\t\t\t\t// hide this match\n\t\t\t\t\thiddenMatches.Add(pos + \"    \" + code);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tdiff.WriteLine(pos + \"    \" + code);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid AppendDelta(string pos, string changeType, string code)\n\t\t\t{\n\t\t\t\tconsecutiveMatches = 0;\n\t\t\t\tif (hiddenMatches.Count > contextSize)\n\t\t\t\t{\n\t\t\t\t\tdiff.WriteLine(\"  ...\");\n\t\t\t\t}\n\t\t\t\tfor (int i = Math.Max(0, hiddenMatches.Count - contextSize); i < hiddenMatches.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tdiff.WriteLine(hiddenMatches[i]);\n\t\t\t\t}\n\t\t\t\thiddenMatches.Clear();\n\t\t\t\tdiff.WriteLine(pos + changeType + \" \" + code);\n\t\t\t}\n\t\t}\n\n\t\tclass CodeLineEqualityComparer : IEqualityComparer<string>\n\t\t{\n\t\t\tprivate IEqualityComparer<string> baseComparer = EqualityComparer<string>.Default;\n\t\t\tprivate Func<string, string> normalizeLine;\n\n\t\t\tpublic CodeLineEqualityComparer(Func<string, string> normalizeLine)\n\t\t\t{\n\t\t\t\tthis.normalizeLine = normalizeLine;\n\t\t\t}\n\n\t\t\tpublic bool Equals(string x, string y)\n\t\t\t{\n\t\t\t\treturn baseComparer.Equals(\n\t\t\t\t\tnormalizeLine(x),\n\t\t\t\t\tnormalizeLine(y)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tpublic int GetHashCode(string obj)\n\t\t\t{\n\t\t\t\treturn baseComparer.GetHashCode(normalizeLine(obj));\n\t\t\t}\n\t\t}\n\n\t\tpublic static string NormalizeLine(string line)\n\t\t{\n\t\t\tline = line.Trim();\n\t\t\tvar index = line.IndexOf(\"//\", StringComparison.Ordinal);\n\t\t\tif (index >= 0)\n\t\t\t{\n\t\t\t\treturn line.Substring(0, index);\n\t\t\t}\n\t\t\telse if (line.StartsWith(\"#\", StringComparison.Ordinal))\n\t\t\t{\n\t\t\t\treturn string.Empty;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn line;\n\t\t\t}\n\t\t}\n\n\t\tprivate static bool ShouldIgnoreChange(string line)\n\t\t{\n\t\t\t// for the result, we should ignore blank lines and added comments\n\t\t\treturn NormalizeLine(line) == string.Empty;\n\t\t}\n\n\t\tclass DeleteDisabledTextRewriter : CSharpSyntaxRewriter\n\t\t{\n\t\t\tpublic override SyntaxTrivia VisitTrivia(SyntaxTrivia trivia)\n\t\t\t{\n\t\t\t\tif (trivia.IsKind(SyntaxKind.DisabledTextTrivia))\n\t\t\t\t{\n\t\t\t\t\treturn default(SyntaxTrivia); // delete\n\t\t\t\t}\n\t\t\t\tif (trivia.IsKind(SyntaxKind.PragmaWarningDirectiveTrivia))\n\t\t\t\t{\n\t\t\t\t\treturn default(SyntaxTrivia); // delete\n\t\t\t\t}\n\t\t\t\treturn base.VisitTrivia(trivia);\n\t\t\t}\n\t\t}\n\n\t\tprivate static IList<string> NormalizeAndSplitCode(string input, IEnumerable<string> definedSymbols)\n\t\t{\n\t\t\tvar syntaxTree = CSharpSyntaxTree.ParseText(input, new CSharpParseOptions(preprocessorSymbols: definedSymbols));\n\t\t\tvar result = new DeleteDisabledTextRewriter().Visit(syntaxTree.GetRoot());\n\t\t\tinput = result.ToFullString();\n\t\t\treturn input.Split(new[] { \"\\r\\n\", \"\\n\", \"\\r\" }, StringSplitOptions.RemoveEmptyEntries);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/Helpers/RemoveCompilerAttribute.cs",
    "content": "using System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.CSharp.Transforms;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.Decompiler.Tests.Helpers\n{\n\tclass RemoveCompilerAttribute : DepthFirstAstVisitor, IAstTransform\n\t{\n\t\tpublic override void VisitAttribute(CSharp.Syntax.Attribute attribute)\n\t\t{\n\t\t\tvar section = (AttributeSection)attribute.Parent;\n\t\t\tSimpleType type = attribute.Type as SimpleType;\n\t\t\tif (section.AttributeTarget == \"assembly\" &&\n\t\t\t\t(type.Identifier == \"CompilationRelaxations\" || type.Identifier == \"RuntimeCompatibility\" || type.Identifier == \"SecurityPermission\" || type.Identifier == \"PermissionSet\" || type.Identifier == \"AssemblyVersion\" || type.Identifier == \"Debuggable\" || type.Identifier == \"TargetFramework\"))\n\t\t\t{\n\t\t\t\tattribute.Remove();\n\t\t\t\tif (section.Attributes.Count == 0)\n\t\t\t\t\tsection.Remove();\n\t\t\t}\n\t\t\tif (section.AttributeTarget == \"module\" && type.Identifier is \"UnverifiableCode\" or \"RefSafetyRules\")\n\t\t\t{\n\t\t\t\tattribute.Remove();\n\t\t\t\tif (section.Attributes.Count == 0)\n\t\t\t\t\tsection.Remove();\n\t\t\t}\n\t\t}\n\n\t\tpublic void Run(AstNode rootNode, TransformContext context)\n\t\t{\n\t\t\trootNode.AcceptVisitor(this);\n\t\t}\n\t}\n\n\tpublic class RemoveNamespaceMy : DepthFirstAstVisitor, IAstTransform\n\t{\n\t\tpublic override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)\n\t\t{\n\t\t\tif (namespaceDeclaration.Name == \"My\")\n\t\t\t{\n\t\t\t\tnamespaceDeclaration.Remove();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbase.VisitNamespaceDeclaration(namespaceDeclaration);\n\t\t\t}\n\t\t}\n\n\t\tpublic void Run(AstNode rootNode, TransformContext context)\n\t\t{\n\t\t\trootNode.AcceptVisitor(this);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/Helpers/RoslynToolset.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nusing NuGet.Common;\nusing NuGet.Packaging;\nusing NuGet.Protocol;\nusing NuGet.Protocol.Core.Types;\nusing NuGet.Versioning;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests.Helpers\n{\n\t[System.Diagnostics.CodeAnalysis.SuppressMessage(\"Design\", \"CA1001:Types that own disposable fields should be disposable\",\n\t\tJustification = \"Derived types are intended to be used as static singletons, each living until the process terminates.\")]\n\tabstract class AbstractToolset\n\t{\n\t\treadonly SourceCacheContext cache;\n\t\treadonly SourceRepository repository;\n\t\treadonly FindPackageByIdResource resource;\n\t\tprotected readonly string baseDir;\n\n\t\tpublic AbstractToolset(string baseDir)\n\t\t{\n\t\t\tthis.cache = new SourceCacheContext();\n\t\t\tthis.repository = Repository.Factory.GetCoreV3(\"https://api.nuget.org/v3/index.json\");\n\t\t\tthis.resource = repository.GetResource<FindPackageByIdResource>();\n\t\t\tthis.baseDir = baseDir;\n\t\t}\n\n\t\tprotected async Task FetchPackage(string packageName, string version, string sourcePath, string outputPath)\n\t\t{\n\t\t\tif (!Directory.Exists(Path.Combine(Roundtrip.RoundtripAssembly.TestDir, \"nuget\")))\n\t\t\t\tAssert.Fail(\"No nuget cache found!\");\n\n\t\t\tILogger logger = NullLogger.Instance;\n\t\t\tCancellationToken cancellationToken = CancellationToken.None;\n\t\t\tstring pathToPackage = Path.Combine(Roundtrip.RoundtripAssembly.TestDir, \"nuget\", $\"{packageName}-{version}.nupkg\");\n\t\t\tStream packageStream;\n\t\t\tif (File.Exists(pathToPackage))\n\t\t\t{\n\t\t\t\tpackageStream = File.OpenRead(pathToPackage);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tpackageStream = new MemoryStream();\n\n\t\t\t\tawait resource.CopyNupkgToStreamAsync(\n\t\t\t\t\tpackageName,\n\t\t\t\t\tNuGetVersion.Parse(version),\n\t\t\t\t\tpackageStream,\n\t\t\t\t\tcache,\n\t\t\t\t\tlogger,\n\t\t\t\t\tcancellationToken).ConfigureAwait(false);\n\n\t\t\t\tpackageStream.Position = 0;\n\t\t\t}\n\t\t\tusing (packageStream)\n\t\t\t{\n\t\t\t\tusing PackageArchiveReader packageReader = new PackageArchiveReader(packageStream);\n\t\t\t\tNuspecReader nuspecReader = await packageReader.GetNuspecReaderAsync(cancellationToken).ConfigureAwait(false);\n\n\t\t\t\tvar files = (await packageReader.GetFilesAsync(cancellationToken).ConfigureAwait(false)).ToArray();\n\t\t\t\tfiles = files.Where(f => f.StartsWith(sourcePath, StringComparison.OrdinalIgnoreCase)).ToArray();\n\t\t\t\tawait packageReader.CopyFilesAsync(outputPath, files,\n\t\t\t\t\t(sourceFile, targetPath, fileStream) => {\n\t\t\t\t\t\tfileStream.CopyToFile(targetPath);\n\t\t\t\t\t\treturn targetPath;\n\t\t\t\t\t},\n\t\t\t\t\tlogger, cancellationToken).ConfigureAwait(false);\n\t\t\t}\n\t\t}\n\t}\n\n\tclass RoslynToolset : AbstractToolset\n\t{\n\t\treadonly Dictionary<string, string> installedCompilers = new Dictionary<string, string> {\n\t\t\t{ \"legacy\", Environment.ExpandEnvironmentVariables(@\"%WINDIR%\\Microsoft.NET\\Framework\\v4.0.30319\") }\n\t\t};\n\n\t\tpublic RoslynToolset()\n\t\t\t: base(Path.Combine(AppContext.BaseDirectory, \"roslyn\"))\n\t\t{\n\t\t}\n\n\t\tpublic async Task Fetch(string version, string packageName = \"Microsoft.Net.Compilers.Toolset\", string sourcePath = \"tasks/net472\")\n\t\t{\n\t\t\tstring path = Path.Combine(baseDir, version, sourcePath);\n\t\t\tif (!Directory.Exists(path))\n\t\t\t{\n\t\t\t\tawait FetchPackage(packageName, version, sourcePath, Path.Combine(baseDir, version)).ConfigureAwait(false);\n\t\t\t}\n\n\t\t\tinstalledCompilers.Add(SanitizeVersion(version), path);\n\t\t}\n\n\t\tpublic string GetCSharpCompiler(string version)\n\t\t{\n\t\t\treturn GetCompiler(\"csc.exe\", version);\n\t\t}\n\n\t\tpublic string GetVBCompiler(string version)\n\t\t{\n\t\t\treturn GetCompiler(\"vbc.exe\", version);\n\t\t}\n\n\t\tstring GetCompiler(string compiler, string version)\n\t\t{\n\t\t\tif (installedCompilers.TryGetValue(SanitizeVersion(version), out var path))\n\t\t\t\treturn Path.Combine(path, compiler);\n\t\t\tthrow new NotSupportedException($\"Cannot find {compiler} {version}, please add it to the initialization.\");\n\t\t}\n\n\t\tinternal static string SanitizeVersion(string version)\n\t\t{\n\t\t\tint index = version.IndexOf(\"-\");\n\t\t\tif (index > 0)\n\t\t\t\treturn version.Remove(index);\n\t\t\treturn version;\n\t\t}\n\t}\n\n\tclass VsWhereToolset : AbstractToolset\n\t{\n\t\tstring vswherePath;\n\n\t\tpublic VsWhereToolset()\n\t\t\t: base(Path.Combine(AppContext.BaseDirectory, \"vswhere\"))\n\t\t{\n\t\t}\n\n\t\tpublic async Task Fetch()\n\t\t{\n\t\t\tstring path = Path.Combine(baseDir, \"tools\");\n\t\t\tif (!Directory.Exists(path))\n\t\t\t{\n\t\t\t\tawait FetchPackage(\"vswhere\", \"2.8.4\", \"tools\", baseDir).ConfigureAwait(false);\n\t\t\t}\n\t\t\tvswherePath = Path.Combine(path, \"vswhere.exe\");\n\t\t}\n\n\t\tpublic string GetVsWhere() => vswherePath;\n\t}\n\n\tclass RefAssembliesToolset : AbstractToolset\n\t{\n\t\treadonly Dictionary<string, string> installedFrameworks = new Dictionary<string, string> {\n\t\t\t{ \"legacy\", Path.Combine(Roundtrip.RoundtripAssembly.TestDir, \"dotnet\", \"legacy\") },\n\t\t\t{ \"2.2.0\", Path.Combine(Roundtrip.RoundtripAssembly.TestDir, \"dotnet\", \"netcore-2.2\") },\n\t\t};\n\n\t\tpublic RefAssembliesToolset()\n\t\t\t: base(Path.Combine(AppContext.BaseDirectory, \"netfx\"))\n\t\t{\n\t\t}\n\n\t\tpublic async Task Fetch(string version, string packageName = \"Microsoft.NETCore.App.Ref\", string sourcePath = \"ref/net5.0\")\n\t\t{\n\t\t\tstring path = Path.Combine(baseDir, version, sourcePath);\n\t\t\tif (!Directory.Exists(path))\n\t\t\t{\n\t\t\t\tawait FetchPackage(packageName, version, sourcePath, Path.Combine(baseDir, version)).ConfigureAwait(false);\n\t\t\t}\n\n\t\t\tinstalledFrameworks.Add(RoslynToolset.SanitizeVersion(version), path);\n\t\t}\n\n\t\tinternal string GetPath(string targetFramework)\n\t\t{\n\t\t\tvar (id, version) = UniversalAssemblyResolver.ParseTargetFramework(targetFramework);\n\t\t\tstring path;\n\t\t\tif (id == TargetFrameworkIdentifier.NETFramework)\n\t\t\t{\n\t\t\t\tpath = installedFrameworks[\"legacy\"];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tpath = installedFrameworks[version.ToString(3)];\n\t\t\t}\n\t\t\tDebug.Assert(Path.Exists(path));\n\t\t\treturn path;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/Helpers/SdkUtility.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.IO;\n\nusing Microsoft.Win32;\n\nnamespace ICSharpCode.Decompiler.Tests.Helpers\n{\n\tpublic static class SdkUtility\n\t{\n\t\tstatic string GetPathFromRegistry(string key, string valueName)\n\t\t{\n\t\t\tusing (RegistryKey installRootKey = Registry.LocalMachine.OpenSubKey(key))\n\t\t\t{\n\t\t\t\tif (installRootKey != null)\n\t\t\t\t{\n\t\t\t\t\tobject o = installRootKey.GetValue(valueName);\n\t\t\t\t\tif (o != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tstring r = o.ToString();\n\t\t\t\t\t\tif (!string.IsNullOrEmpty(r))\n\t\t\t\t\t\t\treturn r;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tstatic string GetPathFromRegistryX86(string key, string valueName)\n\t\t{\n\t\t\tusing (RegistryKey baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))\n\t\t\t{\n\t\t\t\tusing (RegistryKey installRootKey = baseKey.OpenSubKey(key))\n\t\t\t\t{\n\t\t\t\t\tif (installRootKey != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tobject o = installRootKey.GetValue(valueName);\n\t\t\t\t\t\tif (o != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstring r = o.ToString();\n\t\t\t\t\t\t\tif (!string.IsNullOrEmpty(r))\n\t\t\t\t\t\t\t\treturn r;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\t#region InstallRoot Properties\n\n\t\tstatic string netFrameworkInstallRoot = null;\n\t\t/// <summary>\n\t\t/// Gets the installation root of the .NET Framework (@\"C:\\Windows\\Microsoft.NET\\Framework\\\")\n\t\t/// </summary>\n\t\tpublic static string NetFrameworkInstallRoot {\n\t\t\tget {\n\t\t\t\tif (netFrameworkInstallRoot == null)\n\t\t\t\t{\n\t\t\t\t\tnetFrameworkInstallRoot = GetPathFromRegistry(@\"SOFTWARE\\Microsoft\\.NETFramework\", \"InstallRoot\") ?? string.Empty;\n\t\t\t\t}\n\t\t\t\treturn netFrameworkInstallRoot;\n\t\t\t}\n\t\t}\n\n\t\tstatic string netSdk20InstallRoot = null;\n\t\t/// <summary>\n\t\t/// Location of the .NET 2.0 SDK install root.\n\t\t/// </summary>\n\t\tpublic static string NetSdk20InstallRoot {\n\t\t\tget {\n\t\t\t\tif (netSdk20InstallRoot == null)\n\t\t\t\t{\n\t\t\t\t\tnetSdk20InstallRoot = GetPathFromRegistry(@\"SOFTWARE\\Microsoft\\.NETFramework\", \"sdkInstallRootv2.0\") ?? string.Empty;\n\t\t\t\t}\n\t\t\t\treturn netSdk20InstallRoot;\n\t\t\t}\n\t\t}\n\n\t\tstatic string windowsSdk60InstallRoot = null;\n\t\t/// <summary>\n\t\t/// Location of the .NET 3.0 SDK (Windows SDK 6.0) install root.\n\t\t/// </summary>\n\t\tpublic static string WindowsSdk60InstallRoot {\n\t\t\tget {\n\t\t\t\tif (windowsSdk60InstallRoot == null)\n\t\t\t\t{\n\t\t\t\t\twindowsSdk60InstallRoot = GetPathFromRegistry(@\"SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v6.0\", \"InstallationFolder\") ?? string.Empty;\n\t\t\t\t}\n\t\t\t\treturn windowsSdk60InstallRoot;\n\t\t\t}\n\t\t}\n\n\t\tstatic string windowsSdk60aInstallRoot = null;\n\t\t/// <summary>\n\t\t/// Location of the Windows SDK Components in Visual Studio 2008 (.NET 3.5; Windows SDK 6.0a).\n\t\t/// </summary>\n\t\tpublic static string WindowsSdk60aInstallRoot {\n\t\t\tget {\n\t\t\t\tif (windowsSdk60aInstallRoot == null)\n\t\t\t\t{\n\t\t\t\t\twindowsSdk60aInstallRoot = GetPathFromRegistry(@\"SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v6.0a\", \"InstallationFolder\") ?? string.Empty;\n\t\t\t\t}\n\t\t\t\treturn windowsSdk60aInstallRoot;\n\t\t\t}\n\t\t}\n\n\t\tstatic string windowsSdk61InstallRoot = null;\n\t\t/// <summary>\n\t\t/// Location of the .NET 3.5 SDK (Windows SDK 6.1) install root.\n\t\t/// </summary>\n\t\tpublic static string WindowsSdk61InstallRoot {\n\t\t\tget {\n\t\t\t\tif (windowsSdk61InstallRoot == null)\n\t\t\t\t{\n\t\t\t\t\twindowsSdk61InstallRoot = GetPathFromRegistry(@\"SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v6.1\", \"InstallationFolder\") ?? string.Empty;\n\t\t\t\t}\n\t\t\t\treturn windowsSdk61InstallRoot;\n\t\t\t}\n\t\t}\n\n\t\tstatic string windowsSdk70InstallRoot = null;\n\t\t/// <summary>\n\t\t/// Location of the .NET 3.5 SP1 SDK (Windows SDK 7.0) install root.\n\t\t/// </summary>\n\t\tpublic static string WindowsSdk70InstallRoot {\n\t\t\tget {\n\t\t\t\tif (windowsSdk70InstallRoot == null)\n\t\t\t\t{\n\t\t\t\t\twindowsSdk70InstallRoot = GetPathFromRegistry(@\"SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v7.0\", \"InstallationFolder\") ?? string.Empty;\n\t\t\t\t}\n\t\t\t\treturn windowsSdk70InstallRoot;\n\t\t\t}\n\t\t}\n\n\t\tstatic string windowsSdk71InstallRoot = null;\n\t\t/// <summary>\n\t\t/// Location of the .NET 4.0 SDK (Windows SDK 7.1) install root.\n\t\t/// </summary>\n\t\tpublic static string WindowsSdk71InstallRoot {\n\t\t\tget {\n\t\t\t\tif (windowsSdk71InstallRoot == null)\n\t\t\t\t{\n\t\t\t\t\twindowsSdk71InstallRoot = GetPathFromRegistry(@\"SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v7.1\", \"InstallationFolder\") ?? string.Empty;\n\t\t\t\t}\n\t\t\t\treturn windowsSdk71InstallRoot;\n\t\t\t}\n\t\t}\n\n\t\tstatic string windowsSdk80InstallRoot = null;\n\t\t/// <summary>\n\t\t/// Location of the .NET 4.5 SDK (Windows SDK 8.0) install root.\n\t\t/// </summary>\n\t\tpublic static string WindowsSdk80NetFxTools {\n\t\t\tget {\n\t\t\t\tif (windowsSdk80InstallRoot == null)\n\t\t\t\t{\n\t\t\t\t\twindowsSdk80InstallRoot = GetPathFromRegistryX86(@\"SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v8.0A\\WinSDK-NetFx40Tools\", \"InstallationFolder\") ?? string.Empty;\n\t\t\t\t}\n\t\t\t\treturn windowsSdk80InstallRoot;\n\t\t\t}\n\t\t}\n\n\t\tstatic string WindowsSdk461InstallRoot = null;\n\t\t/// <summary>\n\t\t/// Location of the .NET 4.6.1 SDK install root.\n\t\t/// </summary>\n\t\tpublic static string WindowsSdk461NetFxTools {\n\t\t\tget {\n\t\t\t\tif (WindowsSdk461InstallRoot == null)\n\t\t\t\t{\n\t\t\t\t\tWindowsSdk461InstallRoot = GetPathFromRegistryX86(@\"SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\NETFXSDK\\4.6.1\\WinSDK-NetFx40Tools\", \"InstallationFolder\") ?? string.Empty;\n\t\t\t\t}\n\t\t\t\treturn WindowsSdk461InstallRoot;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t/// <summary>\n\t\t/// Searches all the .net sdk bin folders and return the path of the\n\t\t/// exe from the latest sdk.\n\t\t/// </summary>\n\t\t/// <param name=\"exeName\">The EXE to search for.</param>\n\t\t/// <returns>The path of the executable, or null if the exe is not found.</returns>\n\t\tpublic static string GetSdkPath(string exeName)\n\t\t{\n\t\t\tstring execPath;\n\t\t\tif (!string.IsNullOrEmpty(WindowsSdk461NetFxTools))\n\t\t\t{\n\t\t\t\texecPath = Path.Combine(WindowsSdk461NetFxTools, exeName);\n\t\t\t\tif (File.Exists(execPath))\n\t\t\t\t{ return execPath; }\n\t\t\t}\n\t\t\tif (!string.IsNullOrEmpty(WindowsSdk80NetFxTools))\n\t\t\t{\n\t\t\t\texecPath = Path.Combine(WindowsSdk80NetFxTools, exeName);\n\t\t\t\tif (File.Exists(execPath))\n\t\t\t\t{ return execPath; }\n\t\t\t}\n\t\t\tif (!string.IsNullOrEmpty(WindowsSdk71InstallRoot))\n\t\t\t{\n\t\t\t\texecPath = Path.Combine(WindowsSdk71InstallRoot, \"bin\\\\\" + exeName);\n\t\t\t\tif (File.Exists(execPath))\n\t\t\t\t{ return execPath; }\n\t\t\t}\n\t\t\tif (!string.IsNullOrEmpty(WindowsSdk70InstallRoot))\n\t\t\t{\n\t\t\t\texecPath = Path.Combine(WindowsSdk70InstallRoot, \"bin\\\\\" + exeName);\n\t\t\t\tif (File.Exists(execPath))\n\t\t\t\t{ return execPath; }\n\t\t\t}\n\t\t\tif (!string.IsNullOrEmpty(WindowsSdk61InstallRoot))\n\t\t\t{\n\t\t\t\texecPath = Path.Combine(WindowsSdk61InstallRoot, \"bin\\\\\" + exeName);\n\t\t\t\tif (File.Exists(execPath))\n\t\t\t\t{ return execPath; }\n\t\t\t}\n\t\t\tif (!string.IsNullOrEmpty(WindowsSdk60aInstallRoot))\n\t\t\t{\n\t\t\t\texecPath = Path.Combine(WindowsSdk60aInstallRoot, \"bin\\\\\" + exeName);\n\t\t\t\tif (File.Exists(execPath))\n\t\t\t\t{ return execPath; }\n\t\t\t}\n\t\t\tif (!string.IsNullOrEmpty(WindowsSdk60InstallRoot))\n\t\t\t{\n\t\t\t\texecPath = Path.Combine(WindowsSdk60InstallRoot, \"bin\\\\\" + exeName);\n\t\t\t\tif (File.Exists(execPath))\n\t\t\t\t{ return execPath; }\n\t\t\t}\n\t\t\tif (!string.IsNullOrEmpty(NetSdk20InstallRoot))\n\t\t\t{\n\t\t\t\texecPath = Path.Combine(NetSdk20InstallRoot, \"bin\\\\\" + exeName);\n\t\t\t\tif (File.Exists(execPath))\n\t\t\t\t{ return execPath; }\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs",
    "content": "// Copyright (c) 2015 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text.RegularExpressions;\nusing System.Threading.Tasks;\n\nusing CliWrap;\nusing CliWrap.Buffered;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests.Helpers\n{\n\tpartial class Tester\n\t{\n\t\tpublic static async Task<CompilerResults> CompileVB(string sourceFileName, CompilerOptions flags = CompilerOptions.UseDebug, string outputFileName = null)\n\t\t{\n\t\t\tList<string> sourceFileNames = new List<string> { sourceFileName };\n\t\t\tforeach (Match match in Regex.Matches(File.ReadAllText(sourceFileName), @\"#include \"\"([\\w\\d./]+)\"\"\"))\n\t\t\t{\n\t\t\t\tsourceFileNames.Add(Path.GetFullPath(Path.Combine(Path.GetDirectoryName(sourceFileName), match.Groups[1].Value)));\n\t\t\t}\n\n\t\t\tvar preprocessorSymbols = GetPreprocessorSymbols(flags).Select(symbol => new KeyValuePair<string, object>(symbol, 1)).ToList();\n\n\t\t\tif ((flags & CompilerOptions.UseMcsMask) == 0)\n\t\t\t{\n\t\t\t\tCompilerResults results = new CompilerResults();\n\t\t\t\tresults.PathToAssembly = outputFileName;\n\n\t\t\t\tbool targetNet40 = (flags & CompilerOptions.TargetNet40) != 0;\n\n\t\t\t\tvar (roslynVersion, languageVersion, targetFramework) = (flags & CompilerOptions.UseRoslynMask) switch {\n\t\t\t\t\t0 => (\"legacy\", \"11\", null),\n\t\t\t\t\tCompilerOptions.UseRoslyn1_3_2 => (\"1.3.2\", \"14\", null),\n\t\t\t\t\tCompilerOptions.UseRoslyn2_10_0 => (\"2.10.0\", \"latest\", targetNet40 ? null : \".NETCoreApp,Version=v2.2\"),\n\t\t\t\t\tCompilerOptions.UseRoslyn3_11_0 => (\"3.11.0\", \"latest\", targetNet40 ? null : \".NETCoreApp,Version=v5.0\"),\n\t\t\t\t\t_ => (roslynLatestVersion, flags.HasFlag(CompilerOptions.Preview) ? \"preview\" : \"latest\", targetNet40 ? null : \".NETCoreApp,Version=v10.0\")\n\t\t\t\t};\n\n\t\t\t\tvar vbcPath = roslynToolset.GetVBCompiler(roslynVersion);\n\n\t\t\t\tIEnumerable<string> references;\n\t\t\t\tstring libPath;\n\t\t\t\tif ((flags & CompilerOptions.UseRoslynMask) != 0 && targetFramework != null)\n\t\t\t\t{\n\t\t\t\t\tvar coreRefAsmPath = RefAssembliesToolset.GetPath(targetFramework);\n\t\t\t\t\treferences = coreDefaultReferences.Select(r => \"-r:\\\"\" + r + \"\\\"\");\n\t\t\t\t\tlibPath = coreRefAsmPath;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treferences = defaultReferences.Select(r => \"-r:\\\"\" + r + \"\\\"\");\n\t\t\t\t\tlibPath = RefAssembliesToolset.GetPath(\"legacy\");\n\t\t\t\t}\n\t\t\t\tif (flags.HasFlag(CompilerOptions.ReferenceVisualBasic))\n\t\t\t\t{\n\t\t\t\t\treferences = references.Concat(new[] { \"-r:\\\"Microsoft.VisualBasic.dll\\\"\" });\n\t\t\t\t}\n\t\t\t\tstring otherOptions = $\"-nologo -noconfig \" +\n\t\t\t\t\t\"-optioninfer+ -optionexplicit+ \" +\n\t\t\t\t\t$\"-langversion:{languageVersion} \" +\n\t\t\t\t\t$\"/optimize{(flags.HasFlag(CompilerOptions.Optimize) ? \"+ \" : \"- \")}\";\n\n\t\t\t\t// note: the /shared switch is undocumented. It allows us to use the VBCSCompiler.exe compiler\n\t\t\t\t// server to speed up testing\n\t\t\t\tif (roslynVersion != \"legacy\")\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"/shared \";\n\t\t\t\t}\n\n\t\t\t\tif (flags.HasFlag(CompilerOptions.Library))\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"-t:library \";\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"-t:exe \";\n\t\t\t\t}\n\n\t\t\t\tif (flags.HasFlag(CompilerOptions.GeneratePdb))\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"-debug:full \";\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"-debug- \";\n\t\t\t\t}\n\n\t\t\t\tif (flags.HasFlag(CompilerOptions.Force32Bit))\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"-platform:x86 \";\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"-platform:anycpu \";\n\t\t\t\t}\n\t\t\t\tif (preprocessorSymbols.Count > 0)\n\t\t\t\t{\n\t\t\t\t\totherOptions += \" \\\"-d:\" + string.Join(\",\", preprocessorSymbols.Select(kv => kv.Key + \"=\" + kv.Value)) + \"\\\" \";\n\t\t\t\t}\n\n\t\t\t\tvar command = Cli.Wrap(vbcPath)\n\t\t\t\t\t.WithArguments($\"{otherOptions}-libpath:\\\"{libPath}\\\" {string.Join(\" \", references)} -out:\\\"{Path.GetFullPath(results.PathToAssembly)}\\\" {string.Join(\" \", sourceFileNames.Select(fn => '\"' + Path.GetFullPath(fn) + '\"'))}\")\n\t\t\t\t\t.WithValidation(CommandResultValidation.None);\n\t\t\t\t//Console.WriteLine($\"\\\"{command.TargetFilePath}\\\" {command.Arguments}\");\n\n\t\t\t\tvar result = await command.ExecuteBufferedAsync().ConfigureAwait(false);\n\n\t\t\t\tif (!string.IsNullOrWhiteSpace(result.StandardOutput))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"output:\" + Environment.NewLine + result.StandardOutput);\n\t\t\t\t}\n\t\t\t\tif (!string.IsNullOrWhiteSpace(result.StandardError))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"errors:\" + Environment.NewLine + result.StandardError);\n\t\t\t\t}\n\t\t\t\tAssert.That(result.ExitCode, Is.EqualTo(0), \"vbc failed\");\n\n\t\t\t\treturn results;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthrow new NotSupportedException(\"Cannot use mcs for VB\");\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/Helpers/Tester.cs",
    "content": "// Copyright (c) 2015 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection.PortableExecutable;\nusing System.Text;\nusing System.Text.RegularExpressions;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Xml.Linq;\nusing System.Xml.XPath;\n\nusing CliWrap;\nusing CliWrap.Buffered;\n\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\nusing ICSharpCode.Decompiler.CSharp.Transforms;\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Documentation;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX.PdbProvider;\n\nusing Microsoft.CodeAnalysis;\nusing Microsoft.CodeAnalysis.CSharp;\nusing Microsoft.CodeAnalysis.Emit;\nusing Microsoft.CodeAnalysis.Text;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests.Helpers\n{\n\t[Flags]\n\tpublic enum CompilerOptions\n\t{\n\t\tNone,\n\t\tOptimize = 0x1,\n\t\tUseDebug = 0x2,\n\t\tForce32Bit = 0x4,\n\t\tLibrary = 0x8,\n\t\tUseRoslyn1_3_2 = 0x10,\n\t\tUseMcs2_6_4 = 0x20,\n\t\tReferenceVisualBasic = 0x40,\n\t\tTargetNet40 = 0x80,\n\t\tGeneratePdb = 0x100,\n\t\tPreview = 0x200,\n\t\tUseRoslyn2_10_0 = 0x400,\n\t\tUseRoslyn3_11_0 = 0x800,\n\t\tUseRoslynLatest = 0x1000,\n\t\tUseMcs5_23 = 0x2000,\n\t\tUseTestRunner = 0x4000,\n\t\tNullableEnable = 0x8000,\n\t\tReferenceUnsafe = 0x10000,\n\t\tCheckForOverflowUnderflow = 0x20000,\n\t\tProcessXmlDoc = 0x40000,\n\t\tUseMcsMask = UseMcs2_6_4 | UseMcs5_23,\n\t\tUseRoslynMask = UseRoslyn1_3_2 | UseRoslyn2_10_0 | UseRoslyn3_11_0 | UseRoslynLatest\n\t}\n\n\t[Flags]\n\tpublic enum AssemblerOptions\n\t{\n\t\tNone,\n\t\tUseDebug = 0x1,\n\t\tForce32Bit = 0x2,\n\t\tLibrary = 0x4,\n\t\t/// Testing our own disassembler, or working around a bug in ildasm.\n\t\tUseOwnDisassembler = 0x8,\n\t\t/// Work around bug in .NET 5 ilasm (https://github.com/dotnet/runtime/issues/32400)\n\t\tUseLegacyAssembler = 0x10,\n\t\t/// UseSortByNameFilter, implies UseOwnDisassembler\n\t\tSortedOutput = 0x20,\n\t}\n\n\tpublic static partial class Tester\n\t{\n\t\tpublic static readonly string TesterPath;\n\t\tpublic static readonly string TestCasePath;\n\n\t\tstatic readonly string testRunnerBasePath;\n\t\tstatic readonly string packagesPropsFile;\n\t\tstatic readonly string roslynLatestVersion;\n\t\tstatic readonly RoslynToolset roslynToolset;\n\t\tstatic readonly VsWhereToolset vswhereToolset;\n\t\tinternal static readonly RefAssembliesToolset RefAssembliesToolset;\n\n\t\tstatic Tester()\n\t\t{\n\t\t\tTesterPath = Path.GetDirectoryName(typeof(Tester).Assembly.Location);\n\t\t\tTestCasePath = Path.Combine(TesterPath, \"../../../../TestCases\");\n#if DEBUG\n\t\t\ttestRunnerBasePath = Path.Combine(TesterPath, \"../../../../../ICSharpCode.Decompiler.TestRunner/bin/Debug/net10.0\");\n#else\n\t\t\ttestRunnerBasePath = Path.Combine(TesterPath, \"../../../../../ICSharpCode.Decompiler.TestRunner/bin/Release/net10.0\");\n#endif\n\t\t\t// To parse: <Project><ItemGroup><PackageVersion Include=\"Microsoft.CodeAnalysis.CSharp\" Version=\"4.8.0-3.final\" />\n\t\t\tpackagesPropsFile = Path.Combine(TesterPath, \"../../../../../Directory.Packages.props\");\n\t\t\troslynLatestVersion = ((IEnumerable<object>)(XDocument\n\t\t\t\t.Load(packagesPropsFile)\n\t\t\t\t.XPathEvaluate(\"//Project//ItemGroup//PackageVersion[@Include='Microsoft.CodeAnalysis.CSharp']/@Version\")))\n\t\t\t\t.OfType<XAttribute>()\n\t\t\t\t.Single()\n\t\t\t\t.Value;\n\n\t\t\troslynToolset = new RoslynToolset();\n\t\t\tvswhereToolset = new VsWhereToolset();\n\t\t\tRefAssembliesToolset = new RefAssembliesToolset();\n\t\t}\n\n\t\tinternal static async Task Initialize()\n\t\t{\n\t\t\tawait roslynToolset.Fetch(\"1.3.2\", \"Microsoft.Net.Compilers\", \"tools\").ConfigureAwait(false);\n\t\t\tawait roslynToolset.Fetch(\"2.10.0\", \"Microsoft.Net.Compilers\", \"tools\").ConfigureAwait(false);\n\t\t\tawait roslynToolset.Fetch(\"3.11.0\").ConfigureAwait(false);\n\t\t\tawait roslynToolset.Fetch(roslynLatestVersion).ConfigureAwait(false);\n\n\t\t\tawait vswhereToolset.Fetch().ConfigureAwait(false);\n\t\t\tawait RefAssembliesToolset.Fetch(\"5.0.0\", sourcePath: \"ref/net5.0\").ConfigureAwait(false);\n\t\t\tawait RefAssembliesToolset.Fetch(\"10.0.0-rc.2.25502.107\", sourcePath: \"ref/net10.0\").ConfigureAwait(false);\n\n#if DEBUG\n\t\t\tawait BuildTestRunner(\"win-x86\", \"Debug\").ConfigureAwait(false);\n\t\t\tawait BuildTestRunner(\"win-x64\", \"Debug\").ConfigureAwait(false);\n#else\n\t\t\tawait BuildTestRunner(\"win-x86\", \"Release\").ConfigureAwait(false);\n\t\t\tawait BuildTestRunner(\"win-x64\", \"Release\").ConfigureAwait(false);\n#endif\n\t\t}\n\n\t\tstatic async Task BuildTestRunner(string runtime, string config)\n\t\t{\n\t\t\tawait Cli.Wrap(\"dotnet.exe\")\n\t\t\t\t.WithArguments(new[] { \"build\", Path.Combine(TesterPath, \"../../../../../ICSharpCode.Decompiler.TestRunner/ICSharpCode.Decompiler.TestRunner.csproj\"), \"-r\", runtime, \"-c\", config, \"--self-contained\" })\n\t\t\t\t.ExecuteAsync();\n\t\t}\n\n\t\tpublic static async Task<string> AssembleIL(string sourceFileName, AssemblerOptions options = AssemblerOptions.UseDebug)\n\t\t{\n\t\t\tstring ilasmPath;\n\t\t\tif (options.HasFlag(AssemblerOptions.UseLegacyAssembler))\n\t\t\t{\n\t\t\t\tilasmPath = Path.Combine(Environment.GetEnvironmentVariable(\"windir\"), @\"Microsoft.NET\\Framework\\v4.0.30319\\ilasm.exe\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tilasmPath = Path.Combine(\n\t\t\t\t\tPath.GetDirectoryName(typeof(Tester).Assembly.Location),\n\t\t\t\t\t\"ilasm.exe\");\n\t\t\t}\n\t\t\tstring outputFile = Path.Combine(Path.GetDirectoryName(sourceFileName), Path.GetFileNameWithoutExtension(sourceFileName));\n\t\t\tstring otherOptions = \" \";\n\t\t\tif (options.HasFlag(AssemblerOptions.Force32Bit))\n\t\t\t{\n\t\t\t\toutputFile += \".32\";\n\t\t\t\totherOptions += \"/32BitPreferred \";\n\t\t\t}\n\t\t\tif (options.HasFlag(AssemblerOptions.Library))\n\t\t\t{\n\t\t\t\toutputFile += \".dll\";\n\t\t\t\totherOptions += \"/dll \";\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\toutputFile += \".exe\";\n\t\t\t\totherOptions += \"/exe \";\n\t\t\t}\n\n\t\t\tif (options.HasFlag(AssemblerOptions.UseDebug))\n\t\t\t{\n\t\t\t\totherOptions += \"/debug \";\n\t\t\t}\n\n\t\t\tvar command = Cli.Wrap(ilasmPath)\n\t\t\t\t.WithArguments($\"/quiet {otherOptions}/output=\\\"{outputFile}\\\" \\\"{sourceFileName}\\\"\")\n\t\t\t\t.WithValidation(CommandResultValidation.None);\n\n\t\t\tvar result = await command.ExecuteBufferedAsync().ConfigureAwait(false);\n\n\t\t\tif (!string.IsNullOrWhiteSpace(result.StandardOutput))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"output:\" + Environment.NewLine + result.StandardOutput);\n\t\t\t}\n\t\t\tif (!string.IsNullOrWhiteSpace(result.StandardError))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"errors:\" + Environment.NewLine + result.StandardError);\n\t\t\t}\n\t\t\tAssert.That(result.ExitCode, Is.EqualTo(0), \"ilasm failed\");\n\n\t\t\treturn outputFile;\n\t\t}\n\n\t\tpublic static async Task<string> Disassemble(string sourceFileName, string outputFile, AssemblerOptions asmOptions)\n\t\t{\n\t\t\tif (asmOptions.HasFlag(AssemblerOptions.UseOwnDisassembler) || asmOptions.HasFlag(AssemblerOptions.SortedOutput))\n\t\t\t{\n\t\t\t\tusing (var peFileStream = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read))\n\t\t\t\tusing (var peFile = new PEFile(sourceFileName, peFileStream))\n\t\t\t\tusing (var writer = new StringWriter())\n\t\t\t\t{\n\t\t\t\t\tvar metadata = peFile.Metadata;\n\t\t\t\t\tvar output = new PlainTextOutput(writer);\n\t\t\t\t\tReflectionDisassembler rd = new ReflectionDisassembler(output, CancellationToken.None);\n\t\t\t\t\tif (asmOptions.HasFlag(AssemblerOptions.SortedOutput))\n\t\t\t\t\t{\n\t\t\t\t\t\trd.EntityProcessor = new SortByNameProcessor();\n\t\t\t\t\t}\n\t\t\t\t\trd.AssemblyResolver = new UniversalAssemblyResolver(sourceFileName, throwOnError: true, null);\n\t\t\t\t\trd.DetectControlStructure = false;\n\t\t\t\t\trd.WriteAssemblyReferences(metadata);\n\t\t\t\t\tif (metadata.IsAssembly)\n\t\t\t\t\t\trd.WriteAssemblyHeader(peFile);\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\trd.WriteModuleHeader(peFile, skipMVID: true);\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\trd.WriteModuleContents(peFile);\n\n\t\t\t\t\tFile.WriteAllText(outputFile, ReplacePrivImplDetails(writer.ToString()));\n\t\t\t\t}\n\t\t\t\treturn outputFile;\n\t\t\t}\n\n\t\t\tstring ildasmPath = Path.Combine(\n\t\t\t\tPath.GetDirectoryName(typeof(Tester).Assembly.Location),\n\t\t\t\t\"ildasm.exe\");\n\n\t\t\tvar command = Cli.Wrap(ildasmPath)\n\t\t\t\t.WithArguments($\"/utf8 /out=\\\"{outputFile}\\\" \\\"{sourceFileName}\\\"\")\n\t\t\t\t.WithValidation(CommandResultValidation.None);\n\n\t\t\tvar result = await command.ExecuteBufferedAsync().ConfigureAwait(false);\n\n\t\t\tif (!string.IsNullOrWhiteSpace(result.StandardOutput))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"output:\" + Environment.NewLine + result.StandardOutput);\n\t\t\t}\n\t\t\tif (!string.IsNullOrWhiteSpace(result.StandardError))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"errors:\" + Environment.NewLine + result.StandardError);\n\t\t\t}\n\t\t\tAssert.That(result.ExitCode, Is.EqualTo(0), \"ildasm failed\");\n\n\t\t\t// Unlike the .imagebase directive (which is a fixed value when compiling with /deterministic),\n\t\t\t// the image base comment still varies... ildasm putting a random number here?\n\t\t\tstring il = File.ReadAllText(outputFile);\n\t\t\til = Regex.Replace(il, @\"^// Image base: 0x[0-9A-F]+\\r?\\n\", \"\", RegexOptions.Multiline);\n\t\t\t// and while we're at it, also remove the MVID\n\t\t\til = Regex.Replace(il, @\"^// MVID: \\{[0-9A-F-]+\\}\\r?\\n\", \"\", RegexOptions.Multiline);\n\t\t\t// and the ildasm version info (varies from system to system)\n\t\t\til = Regex.Replace(il, @\"^// +Microsoft .* Disassembler\\. +Version.*\\r?\\n\", \"\", RegexOptions.Multiline);\n\t\t\t// copyright header \"All rights reserved\" is dependent on system language\n\t\t\til = Regex.Replace(il, @\"^// +Copyright .* Microsoft.*\\r?\\n\", \"\", RegexOptions.Multiline);\n\t\t\t// filename may contain full path\n\t\t\til = Regex.Replace(il, @\"^// WARNING: Created Win32 resource file.*\\r?\\n\", \"\", RegexOptions.Multiline);\n\t\t\til = ReplacePrivImplDetails(il);\n\t\t\tFile.WriteAllText(outputFile, il);\n\n\t\t\treturn outputFile;\n\t\t}\n\n\t\tprivate static string ReplacePrivImplDetails(string il)\n\t\t{\n\t\t\treturn Regex.Replace(il, @\"'<PrivateImplementationDetails>\\{[0-9A-F-]+\\}'\", \"'<PrivateImplementationDetails>'\");\n\t\t}\n\n\t\tstatic readonly string[] defaultReferences = new[] {\n\t\t\t\"System.dll\",\n\t\t\t\"System.Core.dll\",\n\t\t\t\"System.Runtime.dll\",\n\t\t\t\"System.Xml.dll\",\n\t\t\t\"Microsoft.CSharp.dll\"\n\t\t};\n\n\t\tstatic readonly string[] core220DefaultReferences = new[]\n\t\t\t{\n\t\t\t\t\"netstandard.dll\",\n\t\t\t\t\"mscorlib.dll\",\n\t\t\t\t\"System.dll\",\n\t\t\t\t\"System.Collections.dll\",\n\t\t\t\t\"System.Console.dll\",\n\t\t\t\t\"System.Core.dll\",\n\t\t\t\t\"System.Linq.dll\",\n\t\t\t\t\"System.Linq.Expressions.dll\",\n\t\t\t\t\"System.Linq.Queryable.dll\",\n\t\t\t\t\"System.IO.FileSystem.Watcher.dll\",\n\t\t\t\t\"System.Memory.dll\",\n\t\t\t\t\"System.Private.CoreLib.dll\",\n\t\t\t\t\"System.Private.Xml.dll\",\n\t\t\t\t\"System.Threading.dll\",\n\t\t\t\t\"System.Threading.Thread.dll\",\n\t\t\t\t\"System.Runtime.dll\",\n\t\t\t\t\"System.Runtime.Extensions.dll\",\n\t\t\t\t\"System.Runtime.InteropServices.dll\",\n\t\t\t\t\"System.Xml.dll\",\n\t\t\t\t\"System.Xml.ReaderWriter.dll\",\n\t\t\t\t\"System.ValueTuple.dll\",\n\t\t\t\t\"Microsoft.CSharp.dll\",\n\t\t\t\t\"Microsoft.VisualBasic.dll\",\n\t\t\t};\n\n\t\tstatic readonly string[] coreDefaultReferences = new[]\n\t\t\t{\n\t\t\t\t\"netstandard.dll\",\n\t\t\t\t\"mscorlib.dll\",\n\t\t\t\t\"System.dll\",\n\t\t\t\t\"System.Collections.dll\",\n\t\t\t\t\"System.Console.dll\",\n\t\t\t\t\"System.Core.dll\",\n\t\t\t\t\"System.Linq.dll\",\n\t\t\t\t\"System.Linq.Expressions.dll\",\n\t\t\t\t\"System.Linq.Queryable.dll\",\n\t\t\t\t\"System.IO.FileSystem.Watcher.dll\",\n\t\t\t\t\"System.Memory.dll\",\n\t\t\t\t\"System.Threading.dll\",\n\t\t\t\t\"System.Threading.Thread.dll\",\n\t\t\t\t\"System.Runtime.dll\",\n\t\t\t\t\"System.Runtime.InteropServices.dll\",\n\t\t\t\t\"System.Xml.dll\",\n\t\t\t\t\"System.Xml.ReaderWriter.dll\",\n\t\t\t\t\"System.ValueTuple.dll\",\n\t\t\t\t\"Microsoft.CSharp.dll\",\n\t\t\t\t\"Microsoft.VisualBasic.dll\",\n\t\t\t};\n\n\t\tstatic readonly Dictionary<string, Lazy<string>> targetFrameworkAttributeSnippetFiles = new() {\n\t\t\t{ \".NETCoreApp,Version=v10.0\", new Lazy<string>(() => GetTargetFrameworkAttributeSnippetFile(\".NETCoreApp,Version=v10.0\")) },\n\t\t\t{ \".NETCoreApp,Version=v5.0\", new Lazy<string>(() => GetTargetFrameworkAttributeSnippetFile(\".NETCoreApp,Version=v5.0\")) },\n\t\t\t{ \".NETCoreApp,Version=v2.2\", new Lazy<string>(() => GetTargetFrameworkAttributeSnippetFile(\".NETCoreApp,Version=v2.2\")) },\n\t\t};\n\n\t\tstatic string GetTargetFrameworkAttributeSnippetFile(string targetFrameworkMoniker)\n\t\t{\n\t\t\t// Note: this leaks a temporary file, we're not attempting to delete it, because it is only one.\n\t\t\tvar tempFile = Path.GetTempFileName();\n\t\t\tFile.WriteAllText(tempFile, $@\"\n\n[assembly: System.Runtime.Versioning.TargetFramework(\"\"{targetFrameworkMoniker}\"\")]\n\n\");\n\t\t\treturn tempFile;\n\t\t}\n\n\t\tconst string nonEmbeddedAttributesSnippet = @\"\nusing System;\n\n#if !NET60\nnamespace System.Runtime.CompilerServices\n{\n\t[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]\n\tinternal sealed class CompilerFeatureRequiredAttribute : Attribute\n\t{\n\t\tpublic CompilerFeatureRequiredAttribute(string featureName)\n\t\t{\n\t\t}\n\t}\n\n\tinternal class IsExternalInit\n\t{\n\t}\n#endif\n#if !NET70\n\t[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]\n\tinternal sealed class RequiredMemberAttribute : Attribute\n\t{\n\t}\n#endif\n#if !NET60\n}\n#endif\n\";\n\n\t\tstatic readonly Lazy<string> nonEmbeddedAttributesSnippetFile = new Lazy<string>(GetNonEmbeddedAttributesSnippetFile);\n\n\t\tstatic string GetNonEmbeddedAttributesSnippetFile()\n\t\t{\n\t\t\t// Note: this leaks a temporary file, we're not attempting to delete it, because it is only one.\n\t\t\tvar tempFile = Path.GetTempFileName();\n\t\t\tFile.WriteAllText(tempFile, nonEmbeddedAttributesSnippet);\n\t\t\treturn tempFile;\n\t\t}\n\n\t\tpublic static List<string> GetPreprocessorSymbols(CompilerOptions flags)\n\t\t{\n\t\t\tvar preprocessorSymbols = new List<string>();\n\t\t\tif (flags.HasFlag(CompilerOptions.UseDebug))\n\t\t\t{\n\t\t\t\tpreprocessorSymbols.Add(\"DEBUG\");\n\t\t\t}\n\t\t\tif (flags.HasFlag(CompilerOptions.Optimize))\n\t\t\t{\n\t\t\t\tpreprocessorSymbols.Add(\"OPT\");\n\t\t\t}\n\t\t\tif (flags.HasFlag(CompilerOptions.TargetNet40))\n\t\t\t{\n\t\t\t\tpreprocessorSymbols.Add(\"NET40\");\n\t\t\t}\n\t\t\tif ((flags & CompilerOptions.UseRoslynMask) != 0)\n\t\t\t{\n\t\t\t\tif (!flags.HasFlag(CompilerOptions.TargetNet40))\n\t\t\t\t{\n\t\t\t\t\tpreprocessorSymbols.Add(\"NETCORE\");\n\t\t\t\t}\n\t\t\t\tpreprocessorSymbols.Add(\"ROSLYN\");\n\t\t\t\tpreprocessorSymbols.Add(\"CS60\");\n\t\t\t\tpreprocessorSymbols.Add(\"VB11\");\n\t\t\t\tpreprocessorSymbols.Add(\"VB14\");\n\t\t\t\tif (flags.HasFlag(CompilerOptions.UseRoslyn2_10_0)\n\t\t\t\t\t|| flags.HasFlag(CompilerOptions.UseRoslyn3_11_0)\n\t\t\t\t\t|| flags.HasFlag(CompilerOptions.UseRoslynLatest))\n\t\t\t\t{\n\t\t\t\t\tpreprocessorSymbols.Add(\"ROSLYN2\");\n\t\t\t\t\tpreprocessorSymbols.Add(\"CS70\");\n\t\t\t\t\tpreprocessorSymbols.Add(\"CS71\");\n\t\t\t\t\tpreprocessorSymbols.Add(\"CS72\");\n\t\t\t\t\tpreprocessorSymbols.Add(\"CS73\");\n\t\t\t\t\tpreprocessorSymbols.Add(\"VB15\");\n\t\t\t\t}\n\t\t\t\tif (flags.HasFlag(CompilerOptions.UseRoslyn3_11_0)\n\t\t\t\t\t|| flags.HasFlag(CompilerOptions.UseRoslynLatest))\n\t\t\t\t{\n\t\t\t\t\tif (!flags.HasFlag(CompilerOptions.TargetNet40))\n\t\t\t\t\t{\n\t\t\t\t\t\tpreprocessorSymbols.Add(\"NET50\");\n\t\t\t\t\t}\n\t\t\t\t\tpreprocessorSymbols.Add(\"ROSLYN3\");\n\t\t\t\t\tpreprocessorSymbols.Add(\"CS80\");\n\t\t\t\t\tpreprocessorSymbols.Add(\"CS90\");\n\t\t\t\t\tpreprocessorSymbols.Add(\"VB16\");\n\t\t\t\t}\n\t\t\t\tif (flags.HasFlag(CompilerOptions.UseRoslynLatest))\n\t\t\t\t{\n\t\t\t\t\tif (!flags.HasFlag(CompilerOptions.TargetNet40))\n\t\t\t\t\t{\n\t\t\t\t\t\tpreprocessorSymbols.Add(\"NET60\");\n\t\t\t\t\t\tpreprocessorSymbols.Add(\"NET70\");\n\t\t\t\t\t\tpreprocessorSymbols.Add(\"NET80\");\n\t\t\t\t\t\tpreprocessorSymbols.Add(\"NET90\");\n\t\t\t\t\t\tpreprocessorSymbols.Add(\"NET100\");\n\t\t\t\t\t}\n\t\t\t\t\tpreprocessorSymbols.Add(\"ROSLYN4\");\n\t\t\t\t\tpreprocessorSymbols.Add(\"CS100\");\n\t\t\t\t\tpreprocessorSymbols.Add(\"CS110\");\n\t\t\t\t\tpreprocessorSymbols.Add(\"CS120\");\n\t\t\t\t\tpreprocessorSymbols.Add(\"CS130\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ((flags & CompilerOptions.UseMcsMask) != 0)\n\t\t\t{\n\t\t\t\tpreprocessorSymbols.Add(\"MCS\");\n\t\t\t\tif (flags.HasFlag(CompilerOptions.UseMcs2_6_4))\n\t\t\t\t{\n\t\t\t\t\tpreprocessorSymbols.Add(\"MCS2\");\n\t\t\t\t}\n\t\t\t\tif (flags.HasFlag(CompilerOptions.UseMcs5_23))\n\t\t\t\t{\n\t\t\t\t\tpreprocessorSymbols.Add(\"MCS5\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tpreprocessorSymbols.Add(\"LEGACY_CSC\");\n\t\t\t\tpreprocessorSymbols.Add(\"LEGACY_VBC\");\n\t\t\t}\n\t\t\treturn preprocessorSymbols;\n\t\t}\n\n\t\tpublic static async Task<CompilerResults> CompileCSharp(string sourceFileName, CompilerOptions flags = CompilerOptions.UseDebug, string outputFileName = null)\n\t\t{\n\t\t\tList<string> sourceFileNames = new List<string> { sourceFileName };\n\t\t\tforeach (Match match in Regex.Matches(File.ReadAllText(sourceFileName), @\"#include \"\"([\\w\\d./]+)\"\"\"))\n\t\t\t{\n\t\t\t\tsourceFileNames.Add(Path.GetFullPath(Path.Combine(Path.GetDirectoryName(sourceFileName), match.Groups[1].Value)));\n\t\t\t}\n\t\t\tbool targetNet40 = (flags & CompilerOptions.TargetNet40) != 0;\n\t\t\tbool useRoslyn = (flags & CompilerOptions.UseRoslynMask) != 0;\n\n\t\t\tif (targetNet40)\n\t\t\t{\n\t\t\t\tsourceFileNames.Add(nonEmbeddedAttributesSnippetFile.Value);\n\t\t\t}\n\n\t\t\tvar preprocessorSymbols = GetPreprocessorSymbols(flags);\n\n\t\t\tif ((flags & CompilerOptions.UseMcsMask) == 0)\n\t\t\t{\n\t\t\t\tCompilerResults results = new CompilerResults();\n\t\t\t\tresults.PathToAssembly = outputFileName;\n\n\t\t\t\tvar (roslynVersion, languageVersion, targetFramework) = (flags & CompilerOptions.UseRoslynMask) switch {\n\t\t\t\t\t0 => (\"legacy\", \"5\", null),\n\t\t\t\t\tCompilerOptions.UseRoslyn1_3_2 => (\"1.3.2\", \"6\", null),\n\t\t\t\t\tCompilerOptions.UseRoslyn2_10_0 => (\"2.10.0\", \"latest\", targetNet40 ? null : \".NETCoreApp,Version=v2.2\"),\n\t\t\t\t\tCompilerOptions.UseRoslyn3_11_0 => (\"3.11.0\", \"latest\", targetNet40 ? null : \".NETCoreApp,Version=v5.0\"),\n\t\t\t\t\t_ => (roslynLatestVersion, flags.HasFlag(CompilerOptions.Preview) ? \"preview\" : \"latest\", targetNet40 ? null : \".NETCoreApp,Version=v10.0\")\n\t\t\t\t};\n\n\t\t\t\tvar cscPath = roslynToolset.GetCSharpCompiler(roslynVersion);\n\n\t\t\t\tstring libPath, refAsmPath;\n\t\t\t\tIEnumerable<string> references;\n\t\t\t\tif (useRoslyn && targetFramework != null)\n\t\t\t\t{\n\t\t\t\t\trefAsmPath = RefAssembliesToolset.GetPath(targetFramework);\n\t\t\t\t\tif (targetFramework == \".NETCoreApp,Version=v2.2\")\n\t\t\t\t\t{\n\t\t\t\t\t\treferences = core220DefaultReferences;\n\t\t\t\t\t\tif (flags.HasFlag(CompilerOptions.ReferenceVisualBasic))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treferences = references.Append(\"Microsoft.VisualBasic.dll\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treferences = coreDefaultReferences;\n\t\t\t\t\t\tif (flags.HasFlag(CompilerOptions.ReferenceVisualBasic))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treferences = references.Append(\"Microsoft.VisualBasic.dll\");\n\t\t\t\t\t\t\treferences = references.Append(\"Microsoft.VisualBasic.Core.dll\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tlibPath = \"\\\"\" + refAsmPath + \"\\\"\";\n\t\t\t\t\tsourceFileNames.Add(targetFrameworkAttributeSnippetFiles[targetFramework].Value);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\trefAsmPath = RefAssembliesToolset.GetPath(\"legacy\");\n\t\t\t\t\tlibPath = \"\\\"\" + refAsmPath + \"\\\"\";\n\t\t\t\t\treferences = defaultReferences;\n\t\t\t\t\tif (flags.HasFlag(CompilerOptions.ReferenceVisualBasic))\n\t\t\t\t\t{\n\t\t\t\t\t\treferences = references.Append(\"Microsoft.VisualBasic.dll\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (useRoslyn && !targetNet40 && flags.HasFlag(CompilerOptions.ReferenceUnsafe))\n\t\t\t\t{\n\t\t\t\t\treferences = references.Append(\"System.Runtime.CompilerServices.Unsafe.dll\");\n\t\t\t\t}\n\n\t\t\t\treferences = references.Select(r => \"-r:\\\"\" + Path.Combine(refAsmPath, r) + \"\\\"\");\n\n\t\t\t\tstring otherOptions = $\"-nologo -noconfig \" +\n\t\t\t\t\t$\"-langversion:{languageVersion} \" +\n\t\t\t\t\t$\"-unsafe -o{(flags.HasFlag(CompilerOptions.Optimize) ? \"+ \" : \"- \")}\";\n\n\t\t\t\tHashSet<string> noWarn = new HashSet<string>(StringComparer.OrdinalIgnoreCase);\n\n\t\t\t\t// note: the /shared switch is undocumented. It allows us to use the VBCSCompiler.exe compiler\n\t\t\t\t// server to speed up testing\n\t\t\t\tif (roslynVersion != \"legacy\")\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"/shared \";\n\t\t\t\t\tif (!targetNet40 && Version.Parse(RoslynToolset.SanitizeVersion(roslynVersion)).Major > 2)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (flags.HasFlag(CompilerOptions.NullableEnable))\n\t\t\t\t\t\t\totherOptions += \"/nullable+ \";\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\totherOptions += \"/nullable- \";\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (flags.HasFlag(CompilerOptions.Library))\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"-t:library \";\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"-t:exe \";\n\t\t\t\t}\n\n\t\t\t\tif (flags.HasFlag(CompilerOptions.GeneratePdb))\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"-debug:full \";\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"-debug- \";\n\t\t\t\t}\n\n\t\t\t\tif (flags.HasFlag(CompilerOptions.Force32Bit))\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"-platform:x86 \";\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"-platform:anycpu \";\n\t\t\t\t}\n\n\t\t\t\tif (flags.HasFlag(CompilerOptions.ProcessXmlDoc))\n\t\t\t\t{\n\t\t\t\t\totherOptions += $\"-doc:\\\"{Path.ChangeExtension(results.PathToAssembly, \".xml\")}\\\" \";\n\t\t\t\t\tnoWarn.Add(\"CS1591\"); // Missing XML comment for publicly visible type or member 'Type_or_Member'\n\t\t\t\t}\n\n\t\t\t\tif (flags.HasFlag(CompilerOptions.CheckForOverflowUnderflow))\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"-checked+ \";\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"-checked- \";\n\t\t\t\t}\n\n\t\t\t\tif (preprocessorSymbols.Count > 0)\n\t\t\t\t{\n\t\t\t\t\totherOptions += \" \\\"-d:\" + string.Join(\";\", preprocessorSymbols) + \"\\\" \";\n\t\t\t\t}\n\n\t\t\t\tif (noWarn.Count > 0)\n\t\t\t\t{\n\t\t\t\t\totherOptions += \" -nowarn:\" + string.Join(\",\", noWarn);\n\t\t\t\t}\n\n\t\t\t\tvar command = Cli.Wrap(cscPath)\n\t\t\t\t\t.WithArguments($\"{otherOptions} -lib:{libPath} {string.Join(\" \", references)} -out:\\\"{Path.GetFullPath(results.PathToAssembly)}\\\" {string.Join(\" \", sourceFileNames.Select(fn => '\"' + Path.GetFullPath(fn) + '\"'))}\")\n\t\t\t\t\t.WithValidation(CommandResultValidation.None);\n\t\t\t\t//Console.WriteLine($\"\\\"{command.TargetFilePath}\\\" {command.Arguments}\");\n\n\t\t\t\tvar result = await command.ExecuteBufferedAsync().ConfigureAwait(false);\n\t\t\t\tif (!string.IsNullOrWhiteSpace(result.StandardOutput))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"output:\" + Environment.NewLine + result.StandardOutput);\n\t\t\t\t}\n\t\t\t\tif (!string.IsNullOrWhiteSpace(result.StandardError))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"errors:\" + Environment.NewLine + result.StandardError);\n\t\t\t\t}\n\n\t\t\t\tAssert.That(result.ExitCode, Is.EqualTo(0), \"csc failed\");\n\n\t\t\t\treturn results;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tCompilerResults results = new CompilerResults();\n\t\t\t\tresults.PathToAssembly = outputFileName;\n\t\t\t\tstring testBasePath = Roundtrip.RoundtripAssembly.TestDir;\n\t\t\t\tif (!Directory.Exists(testBasePath))\n\t\t\t\t{\n\t\t\t\t\tAssert.Ignore($\"Compilation with mcs ignored: test directory '{testBasePath}' needs to be checked out separately.\" + Environment.NewLine +\n\t\t\t  $\"git clone https://github.com/icsharpcode/ILSpy-tests \\\"{testBasePath}\\\"\");\n\t\t\t\t}\n\t\t\t\tstring mcsPath = (flags & CompilerOptions.UseMcsMask) switch {\n\t\t\t\t\tCompilerOptions.UseMcs5_23 => Path.Combine(testBasePath, @\"mcs\\5.23\\bin\\mcs.bat\"),\n\t\t\t\t\t_ => Path.Combine(testBasePath, @\"mcs\\2.6.4\\bin\\gmcs.bat\")\n\t\t\t\t};\n\t\t\t\tstring otherOptions = \" -unsafe -o\" + (flags.HasFlag(CompilerOptions.Optimize) ? \"+ \" : \"- \");\n\n\t\t\t\tif (flags.HasFlag(CompilerOptions.Library))\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"-t:library \";\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"-t:exe \";\n\t\t\t\t}\n\n\t\t\t\tif (flags.HasFlag(CompilerOptions.UseDebug))\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"-g \";\n\t\t\t\t}\n\n\t\t\t\tif (flags.HasFlag(CompilerOptions.Force32Bit))\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"-platform:x86 \";\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\totherOptions += \"-platform:anycpu \";\n\t\t\t\t}\n\t\t\t\tif (preprocessorSymbols.Count > 0)\n\t\t\t\t{\n\t\t\t\t\totherOptions += \" \\\"-d:\" + string.Join(\";\", preprocessorSymbols) + \"\\\" \";\n\t\t\t\t}\n\n\t\t\t\tvar command = Cli.Wrap(mcsPath)\n\t\t\t\t\t.WithArguments($\"{otherOptions}-out:\\\"{Path.GetFullPath(results.PathToAssembly)}\\\" {string.Join(\" \", sourceFileNames.Select(fn => '\"' + Path.GetFullPath(fn) + '\"'))}\")\n\t\t\t\t\t.WithValidation(CommandResultValidation.None);\n\t\t\t\t//Console.WriteLine($\"\\\"{command.TargetFilePath}\\\" {command.Arguments}\");\n\n\t\t\t\tvar result = await command.ExecuteBufferedAsync().ConfigureAwait(false);\n\n\t\t\t\tif (!string.IsNullOrWhiteSpace(result.StandardOutput))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"output:\" + Environment.NewLine + result.StandardOutput);\n\t\t\t\t}\n\t\t\t\tif (!string.IsNullOrWhiteSpace(result.StandardError))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"errors:\" + Environment.NewLine + result.StandardError);\n\t\t\t\t}\n\t\t\t\tAssert.That(result.ExitCode, Is.EqualTo(0), \"mcs failed\");\n\n\t\t\t\treturn results;\n\t\t\t}\n\t\t}\n\n\t\tinternal static DecompilerSettings GetSettings(CompilerOptions cscOptions)\n\t\t{\n\t\t\tif ((cscOptions & CompilerOptions.UseRoslynMask) != 0)\n\t\t\t{\n\t\t\t\tvar langVersion = (cscOptions & CompilerOptions.UseRoslynMask) switch {\n\t\t\t\t\tCompilerOptions.UseRoslyn1_3_2 => CSharp.LanguageVersion.CSharp6,\n\t\t\t\t\tCompilerOptions.UseRoslyn2_10_0 => CSharp.LanguageVersion.CSharp7_3,\n\t\t\t\t\tCompilerOptions.UseRoslyn3_11_0 => CSharp.LanguageVersion.CSharp9_0,\n\t\t\t\t\t_ => cscOptions.HasFlag(CompilerOptions.Preview) ? CSharp.LanguageVersion.Latest : CSharp.LanguageVersion.CSharp14_0,\n\t\t\t\t};\n\t\t\t\tDecompilerSettings settings = new(langVersion) {\n\t\t\t\t\t// Never use file-scoped namespaces\n\t\t\t\t\tFileScopedNamespaces = false\n\t\t\t\t};\n\t\t\t\treturn settings;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar settings = new DecompilerSettings(CSharp.LanguageVersion.CSharp5);\n\t\t\t\tif ((cscOptions & CompilerOptions.UseMcsMask) != 0)\n\t\t\t\t{\n\t\t\t\t\t// we don't recompile with mcs but with roslyn, so we can use ref locals\n\t\t\t\t\tsettings.UseRefLocalsForAccurateOrderOfEvaluation = true;\n\t\t\t\t}\n\t\t\t\treturn settings;\n\t\t\t}\n\t\t}\n\n\t\tpublic static void CompileCSharpWithPdb(string assemblyName, Dictionary<string, string> sourceFiles)\n\t\t{\n\t\t\tvar parseOptions = new CSharpParseOptions(languageVersion: Microsoft.CodeAnalysis.CSharp.LanguageVersion.Latest);\n\n\t\t\tList<EmbeddedText> embeddedTexts = new List<EmbeddedText>();\n\t\t\tList<SyntaxTree> syntaxTrees = new List<SyntaxTree>();\n\n\t\t\tforeach (KeyValuePair<string, string> file in sourceFiles)\n\t\t\t{\n\t\t\t\tvar sourceText = SourceText.From(file.Value, new UTF8Encoding(false), SourceHashAlgorithm.Sha256);\n\t\t\t\tsyntaxTrees.Add(SyntaxFactory.ParseSyntaxTree(sourceText, parseOptions, file.Key));\n\t\t\t\tembeddedTexts.Add(EmbeddedText.FromSource(file.Key, sourceText));\n\t\t\t}\n\n\t\t\tvar compilation = CSharpCompilation.Create(Path.GetFileNameWithoutExtension(assemblyName),\n\t\t\t\tsyntaxTrees, coreDefaultReferences.Select(r => MetadataReference.CreateFromFile(Path.Combine(RefAssembliesToolset.GetPath(\".NETCoreApp,Version=v10.0\"), r))),\n\t\t\t\tnew CSharpCompilationOptions(\n\t\t\t\t\tOutputKind.DynamicallyLinkedLibrary,\n\t\t\t\t\tplatform: Platform.AnyCpu,\n\t\t\t\t\toptimizationLevel: OptimizationLevel.Release,\n\t\t\t\t\tallowUnsafe: true,\n\t\t\t\t\tdeterministic: true\n\t\t\t\t));\n\t\t\tusing (FileStream peStream = File.Open(assemblyName + \".dll\", FileMode.OpenOrCreate, FileAccess.ReadWrite))\n\t\t\tusing (FileStream pdbStream = File.Open(assemblyName + \".pdb\", FileMode.OpenOrCreate, FileAccess.ReadWrite))\n\t\t\t{\n\t\t\t\tvar emitResult = compilation.Emit(peStream, pdbStream, options: new EmitOptions(debugInformationFormat: DebugInformationFormat.PortablePdb, pdbFilePath: assemblyName + \".pdb\"), embeddedTexts: embeddedTexts);\n\t\t\t\tif (!emitResult.Success)\n\t\t\t\t{\n\t\t\t\t\tStringBuilder b = new StringBuilder(\"Compiler error:\");\n\t\t\t\t\tforeach (var diag in emitResult.Diagnostics)\n\t\t\t\t\t{\n\t\t\t\t\t\tb.AppendLine(diag.ToString());\n\t\t\t\t\t}\n\t\t\t\t\tthrow new Exception(b.ToString());\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tinternal static string GetSuffix(CompilerOptions cscOptions)\n\t\t{\n\t\t\tstring suffix = \"\";\n\t\t\tif ((cscOptions & CompilerOptions.Optimize) != 0)\n\t\t\t\tsuffix += \".opt\";\n\t\t\tif ((cscOptions & CompilerOptions.Force32Bit) != 0)\n\t\t\t\tsuffix += \".32\";\n\t\t\tif ((cscOptions & CompilerOptions.UseDebug) != 0)\n\t\t\t\tsuffix += \".dbg\";\n\t\t\tif ((cscOptions & CompilerOptions.TargetNet40) != 0)\n\t\t\t\tsuffix += \".net40\";\n\t\t\tif ((cscOptions & CompilerOptions.UseRoslyn1_3_2) != 0)\n\t\t\t\tsuffix += \".roslyn1\";\n\t\t\tif ((cscOptions & CompilerOptions.UseRoslyn2_10_0) != 0)\n\t\t\t\tsuffix += \".roslyn2\";\n\t\t\tif ((cscOptions & CompilerOptions.UseRoslyn3_11_0) != 0)\n\t\t\t\tsuffix += \".roslyn3\";\n\t\t\tif ((cscOptions & CompilerOptions.UseRoslynLatest) != 0)\n\t\t\t\tsuffix += \".roslyn\";\n\t\t\tif ((cscOptions & CompilerOptions.UseMcs2_6_4) != 0)\n\t\t\t\tsuffix += \".mcs2\";\n\t\t\tif ((cscOptions & CompilerOptions.UseMcs5_23) != 0)\n\t\t\t\tsuffix += \".mcs5\";\n\t\t\treturn suffix;\n\t\t}\n\n\t\tpublic static async Task<(int ExitCode, string Output, string Error)> Run(string assemblyFileName)\n\t\t{\n\t\t\tvar command = Cli.Wrap(assemblyFileName)\n\t\t\t\t.WithValidation(CommandResultValidation.None);\n\n\t\t\tvar result = await command.ExecuteBufferedAsync().ConfigureAwait(false);\n\n\t\t\treturn (result.ExitCode, result.StandardOutput, result.StandardError);\n\t\t}\n\n\t\tpublic static async Task<(int ExitCode, string Output, string Error)> RunWithTestRunner(string assemblyFileName, bool force32Bit)\n\t\t{\n\t\t\tstring testRunner = Path.Combine(testRunnerBasePath, force32Bit ? \"win-x86\" : \"win-x64\", \"ICSharpCode.Decompiler.TestRunner.exe\");\n\t\t\tvar command = Cli.Wrap(testRunner)\n\t\t\t\t.WithArguments(assemblyFileName)\n\t\t\t\t.WithValidation(CommandResultValidation.None);\n\n\t\t\tvar result = await command.ExecuteBufferedAsync().ConfigureAwait(false);\n\n\t\t\treturn (result.ExitCode, result.StandardOutput, result.StandardError);\n\t\t}\n\n\t\tpublic static Task<string> DecompileCSharp(string assemblyFileName, DecompilerSettings settings = null)\n\t\t{\n\t\t\tif (settings == null)\n\t\t\t\tsettings = new DecompilerSettings();\n\t\t\tusing (var file = new FileStream(assemblyFileName, FileMode.Open, FileAccess.Read))\n\t\t\t{\n\t\t\t\tvar module = new PEFile(assemblyFileName, file, PEStreamOptions.PrefetchEntireImage);\n\t\t\t\tstring targetFramework = module.Metadata.DetectTargetFrameworkId();\n\t\t\t\tvar resolver = new UniversalAssemblyResolver(assemblyFileName, false,\n\t\t\t\t\ttargetFramework, null, PEStreamOptions.PrefetchMetadata);\n\t\t\t\tresolver.AddSearchDirectory(RefAssembliesToolset.GetPath(targetFramework));\n\t\t\t\tvar typeSystem = new DecompilerTypeSystem(module, resolver, settings);\n\t\t\t\tCSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, settings);\n\t\t\t\tdecompiler.AstTransforms.Insert(0, new RemoveEmbeddedAttributes());\n\t\t\t\tdecompiler.AstTransforms.Insert(0, new RemoveCompilerAttribute());\n\t\t\t\tdecompiler.AstTransforms.Insert(0, new RemoveNamespaceMy());\n\t\t\t\tdecompiler.AstTransforms.Add(new EscapeInvalidIdentifiers());\n\t\t\t\tvar pdbFileName = Path.ChangeExtension(assemblyFileName, \".pdb\");\n\t\t\t\tif (File.Exists(pdbFileName))\n\t\t\t\t\tdecompiler.DebugInfoProvider = DebugInfoUtils.FromFile(module, pdbFileName);\n\t\t\t\tvar xmlDocFileName = Path.ChangeExtension(assemblyFileName, \".xml\");\n\t\t\t\tif (File.Exists(xmlDocFileName))\n\t\t\t\t\tdecompiler.DocumentationProvider = new XmlDocumentationProvider(xmlDocFileName);\n\t\t\t\tvar syntaxTree = decompiler.DecompileWholeModuleAsSingleFile(sortTypes: true);\n\n\t\t\t\tStringWriter output = new StringWriter();\n\t\t\t\tCSharpFormattingOptions formattingPolicy = CreateFormattingPolicyForTests();\n\t\t\t\tvar visitor = new CSharpOutputVisitor(output, formattingPolicy);\n\t\t\t\tsyntaxTree.AcceptVisitor(visitor);\n\n\t\t\t\tstring fileName = Path.GetTempFileName();\n\t\t\t\tFile.WriteAllText(fileName, output.ToString());\n\n\t\t\t\treturn Task.FromResult(fileName);\n\t\t\t}\n\t\t}\n\n\t\tprivate static CSharpFormattingOptions CreateFormattingPolicyForTests()\n\t\t{\n\t\t\tvar formattingPolicy = FormattingOptionsFactory.CreateSharpDevelop();\n\t\t\tformattingPolicy.StatementBraceStyle = BraceStyle.NextLine;\n\t\t\tformattingPolicy.CatchNewLinePlacement = NewLinePlacement.NewLine;\n\t\t\tformattingPolicy.ElseNewLinePlacement = NewLinePlacement.NewLine;\n\t\t\tformattingPolicy.FinallyNewLinePlacement = NewLinePlacement.NewLine;\n\t\t\tformattingPolicy.SpaceBeforeAnonymousMethodParentheses = true;\n\t\t\treturn formattingPolicy;\n\t\t}\n\n\t\tpublic static async Task RunAndCompareOutput(string testFileName, string outputFile, string decompiledOutputFile, string decompiledCodeFile = null, bool useTestRunner = false, bool force32Bit = false)\n\t\t{\n\t\t\tstring output1, output2, error1, error2;\n\t\t\tint result1, result2;\n\n\t\t\tif (useTestRunner)\n\t\t\t{\n\t\t\t\t(result1, output1, error1) = await RunWithTestRunner(outputFile, force32Bit).ConfigureAwait(false);\n\t\t\t\t(result2, output2, error2) = await RunWithTestRunner(decompiledOutputFile, force32Bit).ConfigureAwait(false);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t(result1, output1, error1) = await Run(outputFile).ConfigureAwait(false);\n\t\t\t\t(result2, output2, error2) = await Run(decompiledOutputFile).ConfigureAwait(false);\n\t\t\t}\n\n\t\t\tAssert.That(result1, Is.EqualTo(0), \"Exit code != 0; did the test case crash?\" + Environment.NewLine + error1);\n\t\t\tAssert.That(result2, Is.EqualTo(0), \"Exit code != 0; did the decompiled code crash?\" + Environment.NewLine + error2);\n\n\t\t\tif (output1 != output2 || error1 != error2)\n\t\t\t{\n\t\t\t\tStringBuilder b = new StringBuilder();\n\t\t\t\tb.AppendLine($\"Test {testFileName} failed: output does not match.\");\n\t\t\t\tif (decompiledCodeFile != null)\n\t\t\t\t{\n\t\t\t\t\tb.AppendLine($\"Decompiled code in {decompiledCodeFile}:line 1\");\n\t\t\t\t}\n\t\t\t\tif (error1 != error2)\n\t\t\t\t{\n\t\t\t\t\tb.AppendLine(\"Got different error output.\");\n\t\t\t\t\tb.AppendLine(\"Original error:\");\n\t\t\t\t\tb.AppendLine(error1);\n\t\t\t\t\tb.AppendLine();\n\t\t\t\t\tb.AppendLine(\"Error after de+re-compiling:\");\n\t\t\t\t\tb.AppendLine(error2);\n\t\t\t\t\tb.AppendLine();\n\t\t\t\t}\n\t\t\t\tif (output1 != output2)\n\t\t\t\t{\n\t\t\t\t\tstring outputFileName = Path.Combine(Path.GetTempPath(), Path.GetFileNameWithoutExtension(testFileName));\n\t\t\t\t\tFile.WriteAllText(outputFileName + \".original.out\", output1);\n\t\t\t\t\tFile.WriteAllText(outputFileName + \".decompiled.out\", output2);\n\t\t\t\t\tint diffLine = 0;\n\t\t\t\t\tstring lastHeader = null;\n\t\t\t\t\tTuple<string, string> errorItem = null;\n\t\t\t\t\tforeach (var pair in output1.Replace(\"\\r\", \"\").Split('\\n').Zip(output2.Replace(\"\\r\", \"\").Split('\\n'), Tuple.Create))\n\t\t\t\t\t{\n\t\t\t\t\t\tdiffLine++;\n\t\t\t\t\t\tif (pair.Item1 != pair.Item2)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\terrorItem = pair;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (pair.Item1.EndsWith(\":\", StringComparison.Ordinal))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlastHeader = pair.Item1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tb.AppendLine($\"Output differs; first difference in line {diffLine}\");\n\t\t\t\t\tif (lastHeader != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tb.AppendLine(lastHeader);\n\t\t\t\t\t}\n\t\t\t\t\tb.AppendLine($\"{outputFileName}.original.out:line {diffLine}\");\n\t\t\t\t\tb.AppendLine(errorItem.Item1);\n\t\t\t\t\tb.AppendLine($\"{outputFileName}.decompiled.out:line {diffLine}\");\n\t\t\t\t\tb.AppendLine(errorItem.Item2);\n\t\t\t\t}\n\t\t\t\tAssert.Fail(b.ToString());\n\t\t\t}\n\t\t}\n\n\t\tinternal static void RepeatOnIOError(Action action, int numTries = 5)\n\t\t{\n\t\t\tfor (int i = 0; i < numTries - 1; i++)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\taction();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tcatch (IOException)\n\t\t\t\t{\n\t\t\t\t}\n\t\t\t\tcatch (UnauthorizedAccessException)\n\t\t\t\t{\n\t\t\t\t\t// potential virus scanner problem\n\t\t\t\t}\n\t\t\t\tThread.Sleep(10);\n\t\t\t}\n\t\t\t// If the last try still fails, don't catch the exception\n\t\t\taction();\n\t\t}\n\n\t\tpublic static async Task SignAssembly(string assemblyPath, string keyFilePath)\n\t\t{\n\t\t\tstring snPath = SdkUtility.GetSdkPath(\"sn.exe\");\n\n\t\t\tvar command = Cli.Wrap(snPath)\n\t\t\t\t.WithArguments($\"-R \\\"{assemblyPath}\\\" \\\"{keyFilePath}\\\"\")\n\t\t\t\t.WithValidation(CommandResultValidation.None);\n\n\t\t\tvar result = await command.ExecuteBufferedAsync().ConfigureAwait(false);\n\t\t\tAssert.That(result.ExitCode, Is.EqualTo(0), \"sn failed\");\n\n\t\t\tif (!string.IsNullOrWhiteSpace(result.StandardOutput))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"output:\" + Environment.NewLine + result.StandardOutput);\n\t\t\t}\n\t\t\tif (!string.IsNullOrWhiteSpace(result.StandardError))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"errors:\" + Environment.NewLine + result.StandardError);\n\t\t\t}\n\t\t}\n\n\t\tpublic static async Task<string> FindMSBuild()\n\t\t{\n\t\t\tstring path = vswhereToolset.GetVsWhere();\n\n\t\t\tvar result = await Cli.Wrap(path)\n\t\t\t\t.WithArguments(@\"-latest -requires Microsoft.Component.MSBuild -find MSBuild\\**\\Bin\\MSBuild.exe\")\n\t\t\t\t.WithValidation(CommandResultValidation.None)\n\t\t\t\t.ExecuteBufferedAsync().ConfigureAwait(false);\n\t\t\tif (result.ExitCode != 0)\n\t\t\t\tthrow new InvalidOperationException(\"Could not find MSBuild\");\n\t\t\treturn result.StandardOutput.TrimEnd();\n\t\t}\n\t}\n\n\tpublic class CompilerResults\n\t{\n\t\treadonly HashSet<string> tempFiles = new(Decompiler.Util.Platform.FileNameComparer);\n\t\tstring pathToAssembly;\n\n\t\tpublic string PathToAssembly {\n\t\t\tget {\n\t\t\t\tif (pathToAssembly == null)\n\t\t\t\t{\n\t\t\t\t\tpathToAssembly = TestsAssemblyOutput.GetTempFileName();\n\t\t\t\t\ttempFiles.Add(pathToAssembly);\n\t\t\t\t}\n\t\t\t\treturn pathToAssembly;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tif (pathToAssembly != null)\n\t\t\t\t{\n\t\t\t\t\tthrow new InvalidOperationException(\"PathToAssembly can only be set once\");\n\t\t\t\t}\n\t\t\t\tpathToAssembly = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic void DeleteTempFiles()\n\t\t{\n\t\t\tforeach (var file in tempFiles)\n\t\t\t{\n\t\t\t\tTester.RepeatOnIOError(() => File.Delete(file));\n\t\t\t}\n\t\t}\n\n\t\tpublic void AddTempFile(string file)\n\t\t{\n\t\t\tif (!Path.IsPathFullyQualified(file))\n\t\t\t{\n\t\t\t\tthrow new InvalidOperationException(\"file must be a fully qualified path\");\n\t\t\t}\n\t\t\ttempFiles.Add(file);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/Helpers/TestsAssemblyOutput.cs",
    "content": "// Copyright (c) 2024 Christoph Wille\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\n\nusing Microsoft.Extensions.Configuration;\n\nnamespace ICSharpCode.Decompiler.Tests.Helpers\n{\n\t/// <summary>\n\t/// Centralizes all file-path generation for compilation output (assemblies)\n\t/// \n\t/// DecompilerTests.config.json file format:\n\t/// {\n\t/// \t\"TestsAssemblyTempPath\": \"d:\\\\test\\\\\"\n\t/// }\n\t/// </summary>\n\tinternal static class TestsAssemblyOutput\n\t{\n\t\tstatic string? TestsAssemblyTempPath = null;\n\n\t\tprivate static bool UseCustomPath => !string.IsNullOrWhiteSpace(TestsAssemblyTempPath);\n\n\t\tstatic TestsAssemblyOutput()\n\t\t{\n\t\t\tif (!File.Exists(\"DecompilerTests.config.json\"))\n\t\t\t\treturn;\n\n\t\t\tvar builder = new ConfigurationBuilder()\n\t\t\t\t.AddJsonFile(\"DecompilerTests.config.json\", optional: true, reloadOnChange: false);\n\n\t\t\tIConfigurationRoot configuration = builder.Build();\n\t\t\tvar pathRedirectIfAny = configuration[\"TestsAssemblyTempPath\"];\n\n\t\t\tif (!string.IsNullOrWhiteSpace(pathRedirectIfAny))\n\t\t\t{\n\t\t\t\tTestsAssemblyTempPath = pathRedirectIfAny;\n\t\t\t}\n\t\t}\n\n\t\tpublic static string GetFilePath(string testCasePath, string testName, string computedExtension)\n\t\t{\n\t\t\tif (!UseCustomPath)\n\t\t\t\treturn Path.Combine(testCasePath, testName) + computedExtension;\n\n\t\t\t// As we are using the TestsAssemblyTempPath flat, we need to make sure that duplicated test names don't create file name clashes\n\t\t\treturn Path.Combine(TestsAssemblyTempPath, testName) + Guid.NewGuid().ToString() + computedExtension;\n\t\t}\n\n\t\tpublic static string GetTempFileName()\n\t\t{\n\t\t\tif (!UseCustomPath)\n\t\t\t\treturn Path.GetTempFileName();\n\n\t\t\treturn Path.Combine(TestsAssemblyTempPath, Path.GetRandomFileName());\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <IsWindowsX64 Condition=\"$([MSBuild]::IsOsPlatform('Windows')) And $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) == X64\">true</IsWindowsX64>\r\n    <IsWindowsARM64 Condition=\"$([MSBuild]::IsOsPlatform('Windows')) And $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) == ARM64\">true</IsWindowsARM64>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup>\r\n    <TargetFramework>net10.0-windows</TargetFramework>\r\n    <LangVersion>preview</LangVersion>\r\n    <RuntimeIdentifier Condition=\"$(IsWindowsX64) == true\">win-x64</RuntimeIdentifier>\r\n    <RuntimeIdentifier Condition=\"$(IsWindowsARM64) == true\">win-arm64</RuntimeIdentifier>\r\n\r\n    <IsPackable>false</IsPackable>\r\n\r\n    <GenerateTestingPlatformEntryPoint>true</GenerateTestingPlatformEntryPoint>\r\n    <StartupObject>ICSharpCode.Decompiler.Tests.MicrosoftTestingPlatformEntryPoint</StartupObject>\r\n    <OutputType>Exe</OutputType>\r\n\r\n    <AllowUnsafeBlocks>True</AllowUnsafeBlocks>\r\n\r\n    <!-- NU1902/1903 are \"Package 'X' has a known security vulnerability\". In our tests, we don't care. -->\r\n    <NoWarn>$(NoWarn);1701;1702;1705,67,169,1058,728,1720,649,168,251,660,661,675;1998;162;8632;626;8618;8714;8602;8981;NU1902;NU1903</NoWarn>\r\n    <DefineConstants>ROSLYN;ROSLYN2;ROSLYN3;ROSLYN4;NET60;CS60;CS70;CS71;CS72;CS73;CS80;CS90;CS100;CS110;CS120;CS130</DefineConstants>\r\n\r\n    <GenerateAssemblyVersionAttribute>False</GenerateAssemblyVersionAttribute>\r\n    <GenerateAssemblyFileVersionAttribute>False</GenerateAssemblyFileVersionAttribute>\r\n    <GenerateAssemblyInformationalVersionAttribute>False</GenerateAssemblyInformationalVersionAttribute>\r\n    <EnableDefaultItems>false</EnableDefaultItems>\r\n\r\n    <AutoGenerateBindingRedirects>True</AutoGenerateBindingRedirects>\r\n\r\n    <SignAssembly>True</SignAssembly>\r\n    <AssemblyOriginatorKeyFile>..\\ICSharpCode.Decompiler\\ICSharpCode.Decompiler.snk</AssemblyOriginatorKeyFile>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Debug'\">\r\n    <DebugType>full</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\r\n    <DebugType>pdbonly</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|AnyCPU'\">\r\n    <DefineConstants>TRACE;DEBUG;$(DefineConstants)</DefineConstants>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|AnyCPU'\">\r\n    <DefineConstants>TRACE;$(DefineConstants)</DefineConstants>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"DiffLib\" />\r\n    <PackageReference Include=\"CliWrap\" />\r\n    <PackageReference Include=\"Microsoft.Extensions.Configuration\" />\r\n    <PackageReference Include=\"Microsoft.Extensions.Configuration.Json\" />\r\n    <PackageReference Include=\"NuGet.Protocol\" />\r\n    <PackageReference Include=\"System.Collections.Immutable\" />\r\n    <PackageReference Include=\"System.Reflection.Metadata\" />\r\n    <PackageReference Include=\"Microsoft.CodeAnalysis.CSharp\" />\r\n    <PackageReference Include=\"Microsoft.CodeAnalysis.VisualBasic\" />\r\n    <PackageReference Include=\"Microsoft.DiaSymReader.Converter.Xml\" />\r\n    <PackageReference Include=\"Microsoft.DiaSymReader\" />\r\n    <PackageReference Include=\"Microsoft.DiaSymReader.Native\" />\r\n    <PackageReference Include=\"NUnit3TestAdapter\" />\r\n    <PackageReference Include=\"coverlet.MTP\" />\r\n    <PackageReference Include=\"NUnit\" />\r\n    <PackageReference Include=\"AwesomeAssertions\" />\r\n    <PackageReference Include=\"Microsoft.Testing.Extensions.TrxReport\" />\r\n    <PackageReference Include=\"Microsoft.Testing.Extensions.VSTestBridge\" />\r\n    <PackageReference Include=\"System.Memory\" />\r\n    <PackageReference Include=\"Mono.Cecil\" />\r\n    <PackageReference Include=\"Microsoft.NETCore.ILAsm\" />\r\n    <PackageReference Include=\"Microsoft.NETCore.ILDAsm\" />\r\n    <PackageReference Include=\"System.Resources.Extensions\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\ICSharpCode.ILSpyX\\ICSharpCode.ILSpyX.csproj\" />\r\n    <ProjectReference Include=\"..\\ICSharpCode.Decompiler\\ICSharpCode.Decompiler.csproj\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <None Include=\"TestCases\\Correctness\\Jmp.il\" />\r\n    <None Include=\"TestCases\\Correctness\\StackTests.il\" />\r\n    <None Include=\"TestCases\\Correctness\\StackTypes.il\" />\r\n    <None Include=\"TestCases\\Correctness\\Uninit.vb\" />\r\n    <None Include=\"TestCases\\Disassembler\\Pretty\\GenericConstraints.il\" />\r\n    <None Include=\"TestCases\\Disassembler\\Pretty\\InterfaceImplAttributes.il\" />\r\n    <None Include=\"TestCases\\Disassembler\\Pretty\\SortMembers.expected.il\" />\r\n    <None Include=\"TestCases\\Disassembler\\Pretty\\SortMembers.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\ExtensionEncodingV2.il\" />\r\n    <None Include=\"testcases\\ilpretty\\ExtensionEncodingV1.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\GuessAccessors.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\GuessAccessors.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue2260SwitchString.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue3442.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue3344CkFinite.il\" />\r\n    <None Include=\"testcases\\ilpretty\\Issue3465.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue3466.il\" />\r\n    <None Include=\"testcases\\ilpretty\\Issue3504.il\" />\r\n    <None Include=\"testcases\\ilpretty\\Issue3524.il\" />\r\n    <None Include=\"testcases\\ilpretty\\Issue3552.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\MonoFixed.il\" />\r\n    <None Include=\"TestCases\\Correctness\\NonGenericConstrainedCallVirt.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\UnknownTypes.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\UnknownTypes.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\EvalOrder.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\EvalOrder.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\CallIndirect.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue1454.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue1681.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue1922.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue1918.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue2104.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue3421.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\WeirdEnums.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\ConstantBlobs.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\CS1xSwitch_Debug.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\CS1xSwitch_Release.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue1157.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue684.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue684.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\FSharpLoops.fs\" />\r\n    <None Include=\"TestCases\\ILPretty\\FSharpLoops_Debug.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\FSharpLoops_Release.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\FSharpUsing.fs\" />\r\n    <None Include=\"TestCases\\ILPretty\\FSharpUsing_Debug.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\DirectCallToExplicitInterfaceImpl.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\FSharpUsing_Release.il\" />\r\n    <None Include=\"TestCases\\Correctness\\BitNot.il\" />\r\n    <None Include=\"TestCases\\Correctness\\Readme.txt\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <Compile Include=\"DisassemblerPrettyTestRunner.cs\" />\r\n    <Compile Include=\"Helpers\\RoslynToolset.cs\" />\r\n    <Compile Include=\"Helpers\\TestsAssemblyOutput.cs\" />\r\n    <Compile Include=\"Output\\ILAmbienceTests.cs\" />\r\n    <Compile Include=\"Output\\InsertParenthesesVisitorTests.cs\" />\r\n    <Compile Include=\"ProjectDecompiler\\TargetFrameworkTests.cs\" />\r\n    <Compile Include=\"ProjectDecompiler\\WholeProjectDecompilerTests.cs\" />\r\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\r\n    <Compile Include=\"TestAssemblyResolver.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\ExtensionEncodingV2.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\ExtensionEncodingV1.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\Issue3344CkFinite.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\Issue3421.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\Issue3465.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\Issue3442.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\Issue3466.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\Issue3524.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\Issue3552.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\ExpandParamsArgumentsDisabled.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\ExtensionProperties.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Issue3452.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Issue3541.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Issue3571_C.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Issue3571_B.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Issue3571_A.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Issue3576.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Issue3584.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Issue3610.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Issue3611.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Issue3598.cs\" />\r\n    <None Include=\"TestCases\\Ugly\\NoLocalFunctions.Expected.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue3504.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\MonoFixed.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Comparisons.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\GloballyQualifiedTypeInStringInterpolation.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\InlineArrayTests.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Issue3406.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Issue3439.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Issue3442.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Issue3483.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\PointerArithmetic.cs\" />\r\n    <Compile Include=\"TestCases\\Ugly\\NoNewOfT.cs\" />\r\n    <None Include=\"TestCases\\Ugly\\NoNewOfT.Expected.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\ParamsCollections.cs\" />\r\n    <None Include=\"TestCases\\VBPretty\\VBAutomaticEvents.vb\" />\r\n    <Compile Include=\"TestCases\\VBPretty\\VBAutomaticEvents.cs\" />\r\n    <Compile Include=\"TestCases\\VBPretty\\VBNonGenericForEach.cs\" />\r\n    <None Include=\"TestCases\\VBPretty\\VBNonGenericForEach.vb\" />\r\n    <Compile Include=\"TestCases\\VBPretty\\YieldReturn.cs\" />\r\n    <None Include=\"TestCases\\VBPretty\\YieldReturn.vb\" />\r\n    <Compile Include=\"TypeSystem\\ReflectionHelperTests.cs\" />\r\n    <None Include=\"TestCases\\Pretty\\MetadataAttributes.cs\" />\r\n    <None Include=\"TestCases\\Correctness\\ComInterop.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\DeconstructionTests.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\DynamicTests.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\StringConcat.cs\" />\r\n    <None Include=\"TestCases\\Pretty\\StaticAbstractInterfaceMembers.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Structs.cs\" />\r\n    <None Include=\"TestCases\\Pretty\\FileScopedNamespaces.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\PatternMatching.cs\" />\r\n    <None Include=\"TestCases\\Ugly\\NoPropertiesAndEvents.Expected.cs\" />\r\n    <Compile Include=\"TestCases\\Ugly\\NoPropertiesAndEvents.cs\" />\r\n    <None Include=\"TestCases\\Pretty\\CovariantReturns.cs\" />\r\n    <Compile Include=\"TestCases\\VBPretty\\VBPropertiesTest.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue2260SwitchString.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Records.cs\" />\r\n    <Compile Include=\"TestCases\\VBPretty\\Issue2192.cs\" />\r\n    <Compile Include=\"Util\\FileUtilityTests.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\FunctionPointers.cs\" />\r\n    <None Include=\"TestCases\\Pretty\\CS9_ExtensionGetEnumerator.cs\" />\r\n    <None Include=\"TestCases\\Pretty\\UsingVariables.cs\" />\r\n    <None Include=\"TestCases\\Pretty\\AsyncForeach.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\DeconstructionTests.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\Issue2104.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\SwitchExpressions.cs\" />\r\n    <None Include=\"TestCases\\Pretty\\NativeInts.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\CallIndirect.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\Issue1681.cs\" />\r\n    <Compile Include=\"TestCases\\Ugly\\AggressiveScalarReplacementOfAggregates.cs\" />\r\n    <None Include=\"TestCases\\Ugly\\AggressiveScalarReplacementOfAggregates.Expected.cs\" />\r\n    <None Include=\"TestCases\\Pretty\\IndexRangeTest.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue1918.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\Issue1922.cs\" />\r\n    <Compile Include=\"TestCases\\Ugly\\NoLocalFunctions.cs\" />\r\n    <Compile Include=\"TestCases\\VBPretty\\Issue1906.cs\" />\r\n    <Compile Include=\"TestCases\\VBPretty\\Select.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\WeirdEnums.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\ConstantBlobs.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\AsyncStreams.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\AsyncUsing.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\OutVariables.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\CustomTaskType.cs\" />\r\n    <None Include=\"TestCases\\Ugly\\NoForEachStatement.Expected.cs\" />\r\n    <Compile Include=\"TestCases\\Ugly\\NoForEachStatement.cs\" />\r\n    <None Include=\"TestCases\\Ugly\\NoExtensionMethods.Expected.cs\" />\r\n    <Compile Include=\"TestCases\\Ugly\\NoExtensionMethods.cs\" />\r\n    <None Include=\"TestCases\\VBPretty\\Issue1906.vb\" />\r\n    <None Include=\"TestCases\\VBPretty\\Issue2192.vb\" />\r\n    <None Include=\"TestCases\\VBPretty\\Select.vb\" />\r\n    <None Include=\"TestCases\\VBPretty\\VBCompoundAssign.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\ThrowExpressions.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue1145.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\Issue1157.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\Unsafe.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\CS1xSwitch_Debug.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\CS1xSwitch_Release.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\DirectCallToExplicitInterfaceImpl.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\Issue1389.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\Issue1454.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Discards.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\MultidimensionalArray.cs\" />\r\n    <Compile Include=\"Output\\CSharpAmbienceTests.cs\" />\r\n    <Compile Include=\"Semantics\\ConversionTests.cs\" />\r\n    <Compile Include=\"Semantics\\ExplicitConversionTest.cs\" />\r\n    <Compile Include=\"Semantics\\OverloadResolutionTests.cs\" />\r\n    <Compile Include=\"DataFlowTest.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\LocalFunctions.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\Issue1256.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\Issue1323.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\CustomAttributes2.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\EnumTests.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\UserDefinedConversions.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\Unsafe.il\" />\r\n    <None Include=\"TestCases\\Pretty\\NullableRefTypes.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\TypeMemberTests.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\ValueTypes.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue1389.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\SequenceOfNestedIfs.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\ConstructorInitializers.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\SequenceOfNestedIfs.il\" />\r\n    <None Include=\"TestCases\\Pretty\\AsyncMain.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue1325.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\ConstantsTests.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\CS73_StackAllocInitializers.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\OptionalArguments.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\OptionalArgumentsDisabled.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\CustomShortCircuitOperators.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\ReduceNesting.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\InterfaceTests.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\YieldReturn.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue1256.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue1323.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue1325.il\" />\r\n    <None Include=\"TestCases\\Ugly\\NoDecimalConstants.Expected.cs\" />\r\n    <Compile Include=\"TestCases\\Ugly\\NoDecimalConstants.cs\" />\r\n    <None Include=\"TestCases\\Disassembler\\Pretty\\SecurityDeclarations.il\" />\r\n    <Compile Include=\"TestCases\\Pretty\\CustomAttributeConflicts.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\DynamicTests.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Issue1080.cs\" />\r\n    <None Include=\"TestCases\\Pretty\\MemberTests.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\NamedArguments.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\QualifierTests.cs\" />\r\n    <None Include=\"TestCases\\Pretty\\RefFields.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\RefLocalsAndReturns.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\TupleTests.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\WellKnownConstants.cs\" />\r\n    <Compile Include=\"TypeSystem\\TypeSystemLoaderTests.cs\" />\r\n    <Compile Include=\"TypeSystem\\TypeSystemTestCase.cs\" />\r\n    <Compile Include=\"VBPrettyTestRunner.cs\" />\r\n    <Compile Include=\"TestCases\\VBPretty\\Async.cs\" />\r\n    <Compile Include=\"UglyTestRunner.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\ExpressionTrees.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\LINQRaytracer.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\MiniJSON.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\FloatingPointArithmetic.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\Issue1038.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue1038.il\" />\r\n    <Compile Include=\"TestCases\\Ugly\\NoArrayInitializers.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue1145.il\" />\r\n    <None Include=\"TestCases\\Ugly\\NoArrayInitializers.Expected.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue1047.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\NullPropagation.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\Issue982.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\CS72_PrivateProtected.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\StringInterpolation.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\ExpressionTrees.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\NullPropagation.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\VariableNaming.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\VariableNamingWithoutSymbols.cs\" />\r\n    <Compile Include=\"PdbGenerationTestRunner.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue1047.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue959.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\FSharpLoops_Debug.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\FSharpLoops_Release.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\DelegateConstruction.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\FSharpUsing_Debug.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\FSharpUsing_Release.cs\" />\r\n    <Compile Include=\"Helpers\\CodeAssert.cs\" />\r\n    <Compile Include=\"Helpers\\SdkUtility.cs\" />\r\n    <Compile Include=\"Helpers\\RemoveCompilerAttribute.cs\" />\r\n    <Compile Include=\"Helpers\\Tester.cs\" />\r\n    <Compile Include=\"Helpers\\Tester.VB.cs\" />\r\n    <Compile Include=\"ILPrettyTestRunner.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\Loops.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\NullableTests.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\TrickyTypes.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\Using.cs\" />\r\n    <Compile Include=\"TestCases\\ILPretty\\Issue379.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\FixProxyCalls.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\UnsafeCode.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\InitializerTests.cs\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue959.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue646.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Async.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\CheckedUnchecked.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Generics.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\LiftedOperators.cs\" />\r\n    <Compile Include=\"PrettyTestRunner.cs\" />\r\n    <Compile Include=\"RoundtripAssembly.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\Capturing.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\OverloadResolution.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\AnonymousTypes.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\Async.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\CompoundAssignment.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\ConditionalAttr.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\ControlFlow.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\Conversions.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\DecimalFields.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\Comparisons.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\Generics.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\HelloWorld.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\InitializerTests.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\MemberLookup.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\PropertiesAndEvents.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\Switch.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\UndocumentedExpressions.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\UnsafeCode.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\ValueTypeCall.cs\" />\r\n    <Compile Include=\"CorrectnessTestRunner.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\AutoProperties.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Lock.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Loops.cs\" />\r\n    <Compile Include=\"TestCases\\Correctness\\YieldReturn.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\CompoundAssignmentTest.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\ExceptionHandling.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\HelloWorld.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\InlineAssignmentTest.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\PInvoke.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\PropertiesAndEvents.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\QueryExpressions.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\ShortCircuit.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Switch.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\TypeAnalysisTests.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\Using.cs\" />\r\n    <Compile Include=\"TestTraceListener.cs\" />\r\n    <Compile Include=\"Util\\BitSetTests.cs\" />\r\n    <Compile Include=\"Util\\IntervalTests.cs\" />\r\n    <Compile Include=\"Util\\LongSetTests.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\AssemblyCustomAttributes.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\CustomAttributeSamples.cs\" />\r\n    <Compile Include=\"TestCases\\Pretty\\CustomAttributes.cs\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <Content Include=\"TestCases\\PdbGen\\Members.xml\" />\r\n    <Content Include=\"TestCases\\PdbGen\\ProgressReporting.xml\" />\r\n    <Content Include=\"TestCases\\PdbGen\\ForLoopTests.xml\" />\r\n    <Content Include=\"TestCases\\PdbGen\\CustomPdbId.xml\" />\r\n    <Content Include=\"TestCases\\PdbGen\\HelloWorld.xml\" />\r\n    <Content Include=\"TestCases\\PdbGen\\LambdaCapturing.xml\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <None Include=\"TestCases\\ILPretty\\Issue646.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue379.il\" />\r\n    <None Include=\"TestCases\\ILPretty\\Issue982.il\" />\r\n    <None Include=\"TestCases\\Pretty\\Readme.txt\" />\r\n    <None Include=\"TestCases\\VBPretty\\VBCompoundAssign.vb\" />\r\n    <None Include=\"TestCases\\VBPretty\\Async.vb\" />\r\n    <None Include=\"TestCases\\VBPretty\\VBPropertiesTest.vb\" />\r\n  </ItemGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.Tests.Helpers;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests\n{\n\t[TestFixture, Parallelizable(ParallelScope.All)]\n\tpublic class ILPrettyTestRunner\n\t{\n\t\tstatic readonly string TestCasePath = Tester.TestCasePath + \"/ILPretty\";\n\n\t\t[Test]\n\t\tpublic void AllFilesHaveTests()\n\t\t{\n\t\t\tvar testNames = typeof(ILPrettyTestRunner).GetMethods()\n\t\t\t\t.Where(m => m.GetCustomAttributes(typeof(TestAttribute), false).Any())\n\t\t\t\t.Select(m => m.Name)\n\t\t\t\t.ToArray();\n\t\t\tforeach (var file in new DirectoryInfo(TestCasePath).EnumerateFiles())\n\t\t\t{\n\t\t\t\tif (file.Extension.Equals(\".il\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t{\n\t\t\t\t\tvar testName = file.Name.Split('.')[0];\n\t\t\t\t\tAssert.That(testNames, Has.Member(testName));\n\t\t\t\t\tAssert.That(File.Exists(Path.Combine(TestCasePath, testName + \".cs\")));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t[Test, Ignore(\"Need to decide how to represent virtual methods without 'newslot' flag\")]\n\t\tpublic async Task Issue379()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue646()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue684()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue959()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue982()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue1038()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue1047()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue1389()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue1918()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue1922()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task FSharpUsing_Debug()\n\t\t{\n\t\t\tawait Run(settings: new DecompilerSettings { RemoveDeadStores = true, UseEnhancedUsing = false, FileScopedNamespaces = false });\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task FSharpUsing_Release()\n\t\t{\n\t\t\tawait Run(settings: new DecompilerSettings { RemoveDeadStores = true, UseEnhancedUsing = false, FileScopedNamespaces = false });\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task DirectCallToExplicitInterfaceImpl()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task EvalOrder()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task CS1xSwitch_Debug()\n\t\t{\n\t\t\tawait Run(settings: new DecompilerSettings { SwitchExpressions = false, FileScopedNamespaces = false });\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task CS1xSwitch_Release()\n\t\t{\n\t\t\tawait Run(settings: new DecompilerSettings { SwitchExpressions = false, FileScopedNamespaces = false });\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task UnknownTypes()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue1145()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue1157()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue1256()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue1323()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue1325()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue1681()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue1454()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue2104()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue2443()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3344CkFinite()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3421()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3442()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3465()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3466()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3504()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3524()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3552()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue2260SwitchString()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ConstantBlobs()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task SequenceOfNestedIfs()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Unsafe()\n\t\t{\n\t\t\tawait Run(assemblerOptions: AssemblerOptions.Library | AssemblerOptions.UseLegacyAssembler);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task CallIndirect()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task FSharpLoops_Debug()\n\t\t{\n\t\t\tCopyFSharpCoreDll();\n\t\t\tawait Run(settings: new DecompilerSettings { RemoveDeadStores = true, FileScopedNamespaces = false });\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task FSharpLoops_Release()\n\t\t{\n\t\t\tCopyFSharpCoreDll();\n\t\t\tawait Run(settings: new DecompilerSettings { RemoveDeadStores = true, FileScopedNamespaces = false });\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task WeirdEnums()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task GuessAccessors()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task EmptyBodies()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task MonoFixed()\n\t\t{\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ExtensionEncodingV1()\n\t\t{\n\t\t\t// uses Microsoft.Net.Compilers.Toolset 5.0.0-2.25380.108\n\t\t\t// see ExtensionEncodingV1.il for details\n\t\t\tawait Run();\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ExtensionEncodingV2()\n\t\t{\n\t\t\t// uses Microsoft.Net.Compilers.Toolset 5.0.0-2.25451.107\n\t\t\t// see ExtensionEncodingV2.il for details\n\t\t\tawait Run();\n\t\t}\n\n\t\tasync Task Run([CallerMemberName] string testName = null, DecompilerSettings settings = null,\n\t\t\tAssemblerOptions assemblerOptions = AssemblerOptions.Library)\n\t\t{\n\t\t\tif (settings == null)\n\t\t\t{\n\t\t\t\t// never use file-scoped namespaces, unless explicitly specified\n\t\t\t\tsettings = new DecompilerSettings { FileScopedNamespaces = false };\n\t\t\t}\n\t\t\tvar ilFile = Path.Combine(TestCasePath, testName + \".il\");\n\t\t\tvar csFile = Path.Combine(TestCasePath, testName + \".cs\");\n\n\t\t\tvar executable = await Tester.AssembleIL(ilFile, assemblerOptions).ConfigureAwait(false);\n\t\t\tvar decompiled = await Tester.DecompileCSharp(executable, settings).ConfigureAwait(false);\n\n\t\t\tCodeAssert.FilesAreEqual(csFile, decompiled, [\"EXPECTED_OUTPUT\"]);\n\t\t\tTester.RepeatOnIOError(() => File.Delete(decompiled));\n\t\t}\n\n\t\tstatic readonly object copyLock = new object();\n\n\t\tstatic void CopyFSharpCoreDll()\n\t\t{\n\t\t\tlock (copyLock)\n\t\t\t{\n\t\t\t\tif (File.Exists(Path.Combine(TestCasePath, \"FSharp.Core.dll\")))\n\t\t\t\t\treturn;\n\t\t\t\tstring fsharpCoreDll = Path.Combine(TestCasePath, \"..\\\\..\\\\..\\\\ILSpy-tests\\\\FSharp\\\\FSharp.Core.dll\");\n\t\t\t\tif (!File.Exists(fsharpCoreDll))\n\t\t\t\t\tAssert.Ignore(\"Ignored because of missing ILSpy-tests repo. Must be checked out separately from https://github.com/icsharpcode/ILSpy-tests!\");\n\t\t\t\tFile.Copy(fsharpCoreDll, Path.Combine(TestCasePath, \"FSharp.Core.dll\"));\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/Output/CSharpAmbienceTests.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\nusing ICSharpCode.Decompiler.Output;\nusing ICSharpCode.Decompiler.Tests.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nusing NUnit.Framework;\n\nusing static ICSharpCode.Decompiler.Output.ConversionFlags;\n\nnamespace ICSharpCode.Decompiler.Tests.Output\n{\n\t[TestFixture]\n\tpublic class CSharpAmbienceTests\n\t{\n\t\tICompilation compilation;\n\t\tCSharpAmbience ambience;\n\n\t\t[OneTimeSetUp]\n\t\tpublic void FixtureSetUp()\n\t\t{\n\t\t\tambience = new CSharpAmbience();\n\n\t\t\tcompilation = new SimpleCompilation(TypeSystemLoaderTests.TestAssembly,\n\t\t\t\tTypeSystemLoaderTests.Mscorlib.WithOptions(TypeSystemOptions.Default));\n\t\t}\n\n\t\tITypeDefinition GetDefinition(Type type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\t}\n\n\t\t\tvar foundType = compilation.FindType(type).GetDefinition();\n\t\t\tAssert.That(foundType, Is.Not.Null);\n\t\t\treturn foundType;\n\t\t}\n\n\t\tconst ConversionFlags ILSpyMainTreeViewTypeFlags = ShowTypeParameterList | PlaceReturnTypeAfterParameterList;\n\t\tconst ConversionFlags ILSpyMainTreeViewMemberFlags = ILSpyMainTreeViewTypeFlags | ShowParameterList | ShowReturnType | ShowParameterModifiers;\n\n\t\t#region ITypeDefinition tests\n\t\t[TestCase(None, \"Dictionary\")]\n\t\t[TestCase(ShowDefinitionKeyword, \"class Dictionary\")]\n\t\t[TestCase(ShowAccessibility, \"public Dictionary\")]\n\t\t[TestCase(ShowDefinitionKeyword | ShowAccessibility, \"public class Dictionary\")]\n\t\t[TestCase(ShowTypeParameterList, \"Dictionary<TKey,TValue>\")]\n\t\t[TestCase(ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, \"public class Dictionary<TKey,TValue>\")]\n\t\t[TestCase(UseFullyQualifiedEntityNames | ShowTypeParameterList, \"System.Collections.Generic.Dictionary<TKey,TValue>\")]\n\t\t[TestCase(UseFullyQualifiedEntityNames | ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, \"public class System.Collections.Generic.Dictionary<TKey,TValue>\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"Dictionary<TKey,TValue>\")]\n\t\tpublic void GenericType(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar typeDef = GetDefinition(typeof(Dictionary<,>));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(None, \"Object\")]\n\t\t[TestCase(ShowDefinitionKeyword, \"class Object\")]\n\t\t[TestCase(ShowAccessibility, \"public Object\")]\n\t\t[TestCase(ShowDefinitionKeyword | ShowAccessibility, \"public class Object\")]\n\t\t[TestCase(ShowTypeParameterList, \"Object\")]\n\t\t[TestCase(ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, \"public class Object\")]\n\t\t[TestCase(UseFullyQualifiedEntityNames | ShowTypeParameterList, \"System.Object\")]\n\t\t[TestCase(All, \"public class System.Object\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"Object\")]\n\t\tpublic void SimpleType(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar typeDef = GetDefinition(typeof(object));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(None, \"IEnumerable\")]\n\t\t[TestCase(ShowTypeParameterList, \"IEnumerable<T>\")]\n\t\t[TestCase(ShowTypeParameterList | ShowTypeParameterVarianceModifier, \"IEnumerable<out T>\")]\n\t\t[TestCase(All, \"public interface System.Collections.Generic.IEnumerable<out T>\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"IEnumerable<T>\")]\n\t\tpublic void GenericInterface(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar typeDef = GetDefinition(typeof(IEnumerable<>));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(None, \"Enumerator\")]\n\t\t[TestCase(ShowDefinitionKeyword, \"struct Enumerator\")]\n\t\t[TestCase(ShowAccessibility, \"public Enumerator\")]\n\t\t[TestCase(ShowDefinitionKeyword | ShowAccessibility, \"public struct Enumerator\")]\n\t\t[TestCase(ShowTypeParameterList, \"Enumerator\")]\n\t\t[TestCase(ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, \"public struct Enumerator\")]\n\t\t[TestCase(UseFullyQualifiedEntityNames | ShowTypeParameterList, \"System.Collections.Generic.List<T>.Enumerator\")]\n\t\t[TestCase(ShowDeclaringType | ShowTypeParameterList, \"List<T>.Enumerator\")]\n\t\t[TestCase(All, \"public struct System.Collections.Generic.List<T>.Enumerator\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"Enumerator\")]\n\t\tpublic void GenericTypeWithNested(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar typeDef = GetDefinition(typeof(List<>.Enumerator));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(None, \"StaticClass\")]\n\t\t[TestCase(ShowDefinitionKeyword, \"class StaticClass\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword, \"static class StaticClass\")]\n\t\t[TestCase(ShowModifiers | ShowAccessibility, \"private static StaticClass\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword | ShowAccessibility, \"private static class StaticClass\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList, \"static StaticClass\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, \"private static class StaticClass\")]\n\t\t[TestCase(All, \"private static class ICSharpCode.Decompiler.Tests.Output.CSharpAmbienceTests.StaticClass\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"StaticClass\")]\n\t\tpublic void StaticClassTest(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar typeDef = GetDefinition(typeof(StaticClass));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(None, \"SealedClass\")]\n\t\t[TestCase(ShowDefinitionKeyword, \"class SealedClass\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword, \"sealed class SealedClass\")]\n\t\t[TestCase(ShowModifiers | ShowAccessibility, \"private sealed SealedClass\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword | ShowAccessibility, \"private sealed class SealedClass\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList, \"sealed SealedClass\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, \"private sealed class SealedClass\")]\n\t\t[TestCase(All, \"private sealed class ICSharpCode.Decompiler.Tests.Output.CSharpAmbienceTests.SealedClass\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"SealedClass\")]\n\t\tpublic void SealedClassTest(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar typeDef = GetDefinition(typeof(SealedClass));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(None, \"RefStruct\")]\n\t\t[TestCase(ShowDefinitionKeyword, \"struct RefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword, \"ref struct RefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowAccessibility, \"private ref RefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword | ShowAccessibility, \"private ref struct RefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList, \"ref RefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, \"private ref struct RefStruct\")]\n\t\t[TestCase(All, \"private ref struct ICSharpCode.Decompiler.Tests.Output.CSharpAmbienceTests.RefStruct\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"RefStruct\")]\n\t\tpublic void RefStructTest(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar typeDef = GetDefinition(typeof(RefStruct));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(None, \"ReadonlyStruct\")]\n\t\t[TestCase(ShowDefinitionKeyword, \"struct ReadonlyStruct\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword, \"readonly struct ReadonlyStruct\")]\n\t\t[TestCase(ShowModifiers | ShowAccessibility, \"private readonly ReadonlyStruct\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword | ShowAccessibility, \"private readonly struct ReadonlyStruct\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList, \"readonly ReadonlyStruct\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, \"private readonly struct ReadonlyStruct\")]\n\t\t[TestCase(All, \"private readonly struct ICSharpCode.Decompiler.Tests.Output.CSharpAmbienceTests.ReadonlyStruct\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"ReadonlyStruct\")]\n\t\tpublic void ReadonlyStructTest(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar typeDef = GetDefinition(typeof(ReadonlyStruct));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(None, \"ReadonlyRefStruct\")]\n\t\t[TestCase(ShowDefinitionKeyword, \"struct ReadonlyRefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword, \"readonly ref struct ReadonlyRefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowAccessibility, \"private readonly ref ReadonlyRefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword | ShowAccessibility, \"private readonly ref struct ReadonlyRefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList, \"readonly ref ReadonlyRefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, \"private readonly ref struct ReadonlyRefStruct\")]\n\t\t[TestCase(All, \"private readonly ref struct ICSharpCode.Decompiler.Tests.Output.CSharpAmbienceTests.ReadonlyRefStruct\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"ReadonlyRefStruct\")]\n\t\tpublic void ReadonlyRefStructTest(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar typeDef = GetDefinition(typeof(ReadonlyRefStruct));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput));\n\t\t}\n\t\t#endregion\n\n\t\t#region Delegate tests\n\t\t[TestCase(None, \"Func\")]\n\t\t[TestCase(ShowTypeParameterList, \"Func<T,TResult>\")]\n\t\t[TestCase(ShowTypeParameterList | ShowTypeParameterVarianceModifier, \"Func<in T,out TResult>\")]\n\t\t[TestCase(ShowTypeParameterList | ShowReturnType | ShowTypeParameterVarianceModifier, \"TResult Func<in T,out TResult>\")]\n\t\t[TestCase(ShowTypeParameterList | ShowParameterList | ShowTypeParameterVarianceModifier, \"Func<in T,out TResult>(T)\")]\n\t\t[TestCase(ShowTypeParameterList | ShowParameterList | ShowReturnType | ShowTypeParameterVarianceModifier, \"TResult Func<in T,out TResult>(T)\")]\n\t\t[TestCase(All & ~PlaceReturnTypeAfterParameterList, \"public delegate TResult System.Func<in T,out TResult>(T arg);\")]\n\t\t[TestCase(All, \"public delegate System.Func<in T,out TResult>(T arg) : TResult;\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"Func<T,TResult>\")]\n\t\tpublic void FuncDelegate(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar func = GetDefinition(typeof(Func<,>));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(func), Is.EqualTo(expectedOutput));\n\t\t}\n\t\t#endregion\n\n\t\t#region IField tests\n\t\t[TestCase(All & ~PlaceReturnTypeAfterParameterList, \"private int ICSharpCode.Decompiler.Tests.Output.CSharpAmbienceTests.Program.test;\")]\n\t\t[TestCase(ILSpyMainTreeViewMemberFlags, \"test : int\")]\n\t\t[TestCase(ConversionFlags.All & ~(ConversionFlags.ShowDeclaringType | ConversionFlags.ShowModifiers | ConversionFlags.ShowAccessibility | ConversionFlags.PlaceReturnTypeAfterParameterList), \"int test;\")]\n\t\tpublic void SimpleField(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar field = GetDefinition(typeof(CSharpAmbienceTests.Program)).GetFields(f => f.Name == \"test\").Single();\n\t\t\tambience.ConversionFlags = flags;\n\n\t\t\tAssert.That(ambience.ConvertSymbol(field), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(All & ~PlaceReturnTypeAfterParameterList, \"private const int ICSharpCode.Decompiler.Tests.Output.CSharpAmbienceTests.Program.TEST2;\")]\n\t\t[TestCase(ILSpyMainTreeViewMemberFlags, \"TEST2 : int\")]\n\t\tpublic void SimpleConstField(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar field = compilation.FindType(typeof(CSharpAmbienceTests.Program)).GetFields(f => f.Name == \"TEST2\").Single();\n\t\t\tambience.ConversionFlags = flags;\n\n\t\t\tAssert.That(ambience.ConvertSymbol(field), Is.EqualTo(expectedOutput));\n\t\t}\n\t\t#endregion\n\n\t\t#region IEvent tests\n\t\t[Test]\n\t\tpublic void EventWithDeclaringType()\n\t\t{\n\t\t\tvar ev = compilation.FindType(typeof(CSharpAmbienceTests.Program)).GetEvents(f => f.Name == \"ProgramChanged\").Single();\n\t\t\tambience.ConversionFlags = ConversionFlags.StandardConversionFlags | ConversionFlags.ShowDeclaringType;\n\t\t\tstring result = ambience.ConvertSymbol(ev);\n\n\t\t\tAssert.That(result, Is.EqualTo(\"public event EventHandler Program.ProgramChanged;\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void CustomEvent()\n\t\t{\n\t\t\tvar ev = compilation.FindType(typeof(CSharpAmbienceTests.Program)).GetEvents(f => f.Name == \"SomeEvent\").Single();\n\t\t\tambience.ConversionFlags = ConversionFlags.StandardConversionFlags;\n\t\t\tstring result = ambience.ConvertSymbol(ev);\n\n\t\t\tAssert.That(result, Is.EqualTo(\"public event EventHandler SomeEvent;\"));\n\t\t}\n\t\t#endregion\n\n\t\t#region Property tests\n\t\t[TestCase(StandardConversionFlags, \"public int Test { get; set; }\")]\n\t\t[TestCase(ILSpyMainTreeViewMemberFlags, \"Test : int\")]\n\t\tpublic void AutomaticProperty(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar prop = compilation.FindType(typeof(CSharpAmbienceTests.Program)).GetProperties(p => p.Name == \"Test\").Single();\n\t\t\tambience.ConversionFlags = flags;\n\n\t\t\tAssert.That(ambience.ConvertSymbol(prop), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(StandardConversionFlags, \"public int this[int index] { get; }\")]\n\t\t[TestCase(ILSpyMainTreeViewMemberFlags, \"this[int] : int\")]\n\t\tpublic void Indexer(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar prop = compilation.FindType(typeof(CSharpAmbienceTests.Program)).GetProperties(p => p.IsIndexer && !p.IsExplicitInterfaceImplementation).Single();\n\t\t\tambience.ConversionFlags = flags;\n\n\t\t\tAssert.That(ambience.ConvertSymbol(prop), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(StandardConversionFlags, \"int Interface.this[int index] { get; }\")]\n\t\t[TestCase(ILSpyMainTreeViewMemberFlags, \"Interface.this[int] : int\")]\n\t\tpublic void ExplicitIndexer(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar prop = compilation.FindType(typeof(CSharpAmbienceTests.Program)).GetProperties(p => p.IsIndexer && p.IsExplicitInterfaceImplementation).Single();\n\t\t\tambience.ConversionFlags = flags;\n\n\t\t\tAssert.That(ambience.ConvertSymbol(prop), Is.EqualTo(expectedOutput));\n\t\t}\n\t\t#endregion\n\n\t\t#region IMethod tests\n\t\t[TestCase(StandardConversionFlags, \"public Program(int x);\")]\n\t\t[TestCase(ILSpyMainTreeViewMemberFlags, \"Program(int)\")]\n\t\tpublic void ConstructorTests(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar prop = compilation.FindType(typeof(CSharpAmbienceTests.Program)).GetConstructors().Single();\n\t\t\tambience.ConversionFlags = flags;\n\n\t\t\tAssert.That(ambience.ConvertSymbol(prop), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(StandardConversionFlags, \"~Program();\")]\n\t\t[TestCase(ILSpyMainTreeViewMemberFlags, \"~Program()\")]\n\t\tpublic void DestructorTests(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar dtor = compilation.FindType(typeof(CSharpAmbienceTests.Program))\n\t\t\t\t.GetMembers(m => m.SymbolKind == SymbolKind.Destructor, GetMemberOptions.IgnoreInheritedMembers).Single();\n\t\t\tambience.ConversionFlags = flags;\n\n\t\t\tAssert.That(ambience.ConvertSymbol(dtor), Is.EqualTo(expectedOutput));\n\t\t}\n\t\t#endregion\n\n\t\t#region Test types\n#pragma warning disable 169, 67\n\n\t\tclass Test { }\n\t\tstatic class StaticClass { }\n\t\tsealed class SealedClass { }\n\t\tref struct RefStruct { }\n\t\treadonly struct ReadonlyStruct { }\n\t\treadonly ref struct ReadonlyRefStruct { }\n\n\t\tinterface Interface\n\t\t{\n\t\t\tint this[int x] { get; }\n\t\t}\n\n\t\tclass Program : Interface\n\t\t{\n\t\t\tint test;\n\t\t\tconst int TEST2 = 2;\n\n\t\t\tpublic int Test { get; set; }\n\n\t\t\tpublic int this[int index] {\n\t\t\t\tget {\n\t\t\t\t\treturn index;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tint Interface.this[int index] {\n\t\t\t\tget {\n\t\t\t\t\treturn index;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic event EventHandler ProgramChanged;\n\n\t\t\tpublic event EventHandler SomeEvent {\n\t\t\t\tadd { }\n\t\t\t\tremove { }\n\t\t\t}\n\n\t\t\tpublic static bool operator +(Program lhs, Program rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic static implicit operator Test(Program lhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic static explicit operator int(Program lhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic Program(int x)\n\t\t\t{\n\n\t\t\t}\n\n\t\t\t~Program()\n\t\t\t{\n\n\t\t\t}\n\n\t\t\tpublic static void Main(string[] args)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Hello World!\");\n\n\t\t\t\tConsole.Write(\"Press any key to continue . . . \");\n\t\t\t\tConsole.ReadKey(true);\n\t\t\t}\n\n\t\t\tpublic static void InParameter(in int a)\n\t\t\t{\n\n\t\t\t}\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/Output/ILAmbienceTests.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Output;\nusing ICSharpCode.Decompiler.Tests.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nusing NUnit.Framework;\n\nusing static ICSharpCode.Decompiler.Output.ConversionFlags;\n\nnamespace ICSharpCode.Decompiler.Tests.Output\n{\n\t[TestFixture]\n\tpublic class ILAmbienceTests\n\t{\n\t\tICompilation compilation;\n\t\tILAmbience ambience;\n\n\t\t[OneTimeSetUp]\n\t\tpublic void FixtureSetUp()\n\t\t{\n\t\t\tambience = new ILAmbience();\n\n\t\t\tcompilation = new SimpleCompilation(TypeSystemLoaderTests.TestAssembly,\n\t\t\t\tTypeSystemLoaderTests.Mscorlib.WithOptions(TypeSystemOptions.Default));\n\t\t}\n\n\t\tITypeDefinition GetDefinition(Type type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\t}\n\n\t\t\tvar foundType = compilation.FindType(type).GetDefinition();\n\t\t\tAssert.That(foundType, Is.Not.Null);\n\t\t\treturn foundType;\n\t\t}\n\n\t\tconst ConversionFlags ILSpyMainTreeViewTypeFlags = ShowTypeParameterList | PlaceReturnTypeAfterParameterList;\n\t\tconst ConversionFlags ILSpyMainTreeViewMemberFlags = ILSpyMainTreeViewTypeFlags | ShowParameterList | ShowReturnType | ShowParameterModifiers;\n\n\t\t#region ITypeDefinition tests\n\t\t[TestCase(None, \"Dictionary`2\")]\n\t\t[TestCase(ShowDefinitionKeyword, \".class Dictionary`2\")]\n\t\t[TestCase(ShowAccessibility, \"public Dictionary`2\")]\n\t\t[TestCase(ShowDefinitionKeyword | ShowAccessibility, \".class public Dictionary`2\")]\n\t\t[TestCase(ShowTypeParameterList, \"Dictionary`2<TKey,TValue>\")]\n\t\t[TestCase(ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, \".class public Dictionary`2<TKey,TValue>\")]\n\t\t[TestCase(UseFullyQualifiedEntityNames | ShowTypeParameterList, \"System.Collections.Generic.Dictionary`2<TKey,TValue>\")]\n\t\t[TestCase(UseFullyQualifiedEntityNames | ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, \".class public System.Collections.Generic.Dictionary`2<TKey,TValue>\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"Dictionary`2<TKey,TValue>\")]\n\t\tpublic void GenericType(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar typeDef = GetDefinition(typeof(Dictionary<,>));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(None, \"Object\")]\n\t\t[TestCase(ShowDefinitionKeyword, \".class Object\")]\n\t\t[TestCase(ShowAccessibility, \"public Object\")]\n\t\t[TestCase(ShowDefinitionKeyword | ShowAccessibility, \".class public Object\")]\n\t\t[TestCase(ShowTypeParameterList, \"Object\")]\n\t\t[TestCase(ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, \".class public Object\")]\n\t\t[TestCase(UseFullyQualifiedEntityNames | ShowTypeParameterList, \"System.Object\")]\n\t\t[TestCase(All, \".class public serializable beforefieldinit System.Object\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"Object\")]\n\t\tpublic void SimpleType(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar typeDef = GetDefinition(typeof(object));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(None, \"IEnumerable`1\")]\n\t\t[TestCase(ShowTypeParameterList, \"IEnumerable`1<T>\")]\n\t\t[TestCase(ShowTypeParameterList | ShowTypeParameterVarianceModifier, \"IEnumerable`1<+T>\")]\n\t\t[TestCase(All, \".class interface public abstract System.Collections.Generic.IEnumerable`1<+T>\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"IEnumerable`1<T>\")]\n\t\tpublic void GenericInterface(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar typeDef = GetDefinition(typeof(IEnumerable<>));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(None, \"Enumerator\")]\n\t\t[TestCase(ShowDefinitionKeyword, \".class Enumerator\")]\n\t\t[TestCase(ShowAccessibility, \"nested public Enumerator\")]\n\t\t[TestCase(ShowDefinitionKeyword | ShowAccessibility, \".class nested public Enumerator\")]\n\t\t[TestCase(ShowTypeParameterList, \"Enumerator<T>\")]\n\t\t[TestCase(ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, \".class nested public Enumerator<T>\")]\n\t\t[TestCase(UseFullyQualifiedEntityNames | ShowTypeParameterList, \"System.Collections.Generic.List`1<T>.Enumerator<T>\")]\n\t\t[TestCase(ShowDeclaringType | ShowTypeParameterList, \"List`1<T>.Enumerator<T>\")]\n\t\t[TestCase(All, \".class nested public sealed serializable beforefieldinit System.Collections.Generic.List`1<T>.Enumerator<T>\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"Enumerator<T>\")]\n\t\tpublic void GenericTypeWithNested(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar typeDef = GetDefinition(typeof(List<>.Enumerator));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(None, \"StaticClass\")]\n\t\t[TestCase(ShowDefinitionKeyword, \".class StaticClass\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword, \".class abstract sealed beforefieldinit StaticClass\")]\n\t\t[TestCase(ShowModifiers | ShowAccessibility, \"private abstract sealed beforefieldinit StaticClass\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword | ShowAccessibility, \".class private abstract sealed beforefieldinit StaticClass\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList, \"abstract sealed beforefieldinit StaticClass\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, \".class private abstract sealed beforefieldinit StaticClass\")]\n\t\t[TestCase(All, \".class private abstract sealed beforefieldinit ICSharpCode.Decompiler.Tests.Output.StaticClass\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"StaticClass\")]\n\t\tpublic void StaticClassTest(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar typeDef = GetDefinition(typeof(StaticClass));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(None, \"SealedClass\")]\n\t\t[TestCase(ShowDefinitionKeyword, \".class SealedClass\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword, \".class sealed beforefieldinit SealedClass\")]\n\t\t[TestCase(ShowModifiers | ShowAccessibility, \"private sealed beforefieldinit SealedClass\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword | ShowAccessibility, \".class private sealed beforefieldinit SealedClass\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList, \"sealed beforefieldinit SealedClass\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, \".class private sealed beforefieldinit SealedClass\")]\n\t\t[TestCase(All, \".class private sealed beforefieldinit ICSharpCode.Decompiler.Tests.Output.SealedClass\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"SealedClass\")]\n\t\tpublic void SealedClassTest(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar typeDef = GetDefinition(typeof(SealedClass));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(None, \"RefStruct\")]\n\t\t[TestCase(ShowDefinitionKeyword, \".class RefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword, \".class sealed beforefieldinit RefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowAccessibility, \"private sealed beforefieldinit RefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword | ShowAccessibility, \".class private sealed beforefieldinit RefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList, \"sealed beforefieldinit RefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, \".class private sealed beforefieldinit RefStruct\")]\n\t\t[TestCase(All, \".class private sealed beforefieldinit ICSharpCode.Decompiler.Tests.Output.RefStruct\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"RefStruct\")]\n\t\tpublic void RefStructTest(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar typeDef = GetDefinition(typeof(RefStruct));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(None, \"ReadonlyStruct\")]\n\t\t[TestCase(ShowDefinitionKeyword, \".class ReadonlyStruct\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword, \".class sealed beforefieldinit ReadonlyStruct\")]\n\t\t[TestCase(ShowModifiers | ShowAccessibility, \"private sealed beforefieldinit ReadonlyStruct\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword | ShowAccessibility, \".class private sealed beforefieldinit ReadonlyStruct\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList, \"sealed beforefieldinit ReadonlyStruct\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, \".class private sealed beforefieldinit ReadonlyStruct\")]\n\t\t[TestCase(All, \".class private sealed beforefieldinit ICSharpCode.Decompiler.Tests.Output.ReadonlyStruct\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"ReadonlyStruct\")]\n\t\tpublic void ReadonlyStructTest(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar typeDef = GetDefinition(typeof(ReadonlyStruct));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(None, \"ReadonlyRefStruct\")]\n\t\t[TestCase(ShowDefinitionKeyword, \".class ReadonlyRefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword, \".class sealed beforefieldinit ReadonlyRefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowAccessibility, \"private sealed beforefieldinit ReadonlyRefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowDefinitionKeyword | ShowAccessibility, \".class private sealed beforefieldinit ReadonlyRefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList, \"sealed beforefieldinit ReadonlyRefStruct\")]\n\t\t[TestCase(ShowModifiers | ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, \".class private sealed beforefieldinit ReadonlyRefStruct\")]\n\t\t[TestCase(All, \".class private sealed beforefieldinit ICSharpCode.Decompiler.Tests.Output.ReadonlyRefStruct\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"ReadonlyRefStruct\")]\n\t\tpublic void ReadonlyRefStructTest(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar typeDef = GetDefinition(typeof(ReadonlyRefStruct));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(typeDef), Is.EqualTo(expectedOutput));\n\t\t}\n\t\t#endregion\n\n\t\t#region Delegate tests\n\t\t[TestCase(None, \"Func`2\")]\n\t\t[TestCase(ShowTypeParameterList, \"Func`2<T,TResult>\")]\n\t\t[TestCase(ShowTypeParameterList | ShowTypeParameterVarianceModifier, \"Func`2<-T,+TResult>\")]\n\t\t[TestCase(All, \".class public sealed System.Func`2<-T,+TResult>\")]\n\t\t[TestCase(ILSpyMainTreeViewTypeFlags, \"Func`2<T,TResult>\")]\n\t\tpublic void FuncDelegate(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar func = GetDefinition(typeof(Func<,>));\n\t\t\tambience.ConversionFlags = flags;\n\t\t\tAssert.That(ambience.ConvertSymbol(func), Is.EqualTo(expectedOutput));\n\t\t}\n\t\t#endregion\n\n\t\t#region IField tests\n\t\t[TestCase(All & ~PlaceReturnTypeAfterParameterList, \".field private instance int32 ICSharpCode.Decompiler.Tests.Output.Program::test\")]\n\t\t[TestCase(ILSpyMainTreeViewMemberFlags, \"test : int32\")]\n\t\t[TestCase(All & ~(ShowDeclaringType | ShowModifiers | ShowAccessibility | PlaceReturnTypeAfterParameterList), \".field int32 ICSharpCode.Decompiler.Tests.Output.Program::test\")]\n\t\tpublic void SimpleField(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar field = GetDefinition(typeof(Program)).GetFields(f => f.Name == \"test\").Single();\n\t\t\tambience.ConversionFlags = flags;\n\n\t\t\tAssert.That(ambience.ConvertSymbol(field), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(All & ~PlaceReturnTypeAfterParameterList, \".field private static literal int32 ICSharpCode.Decompiler.Tests.Output.Program::TEST2\")]\n\t\t[TestCase(ILSpyMainTreeViewMemberFlags, \"TEST2 : int32\")]\n\t\tpublic void SimpleConstField(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar field = compilation.FindType(typeof(Program)).GetFields(f => f.Name == \"TEST2\").Single();\n\t\t\tambience.ConversionFlags = flags;\n\n\t\t\tAssert.That(ambience.ConvertSymbol(field), Is.EqualTo(expectedOutput));\n\t\t}\n\t\t#endregion\n\n\t\t#region IEvent tests\n\t\t[Test]\n\t\tpublic void EventWithDeclaringType()\n\t\t{\n\t\t\tvar ev = compilation.FindType(typeof(Program)).GetEvents(f => f.Name == \"ProgramChanged\").Single();\n\t\t\tambience.ConversionFlags = ConversionFlags.StandardConversionFlags | ConversionFlags.ShowDeclaringType;\n\t\t\tstring result = ambience.ConvertSymbol(ev);\n\n\t\t\tAssert.That(result, Is.EqualTo(\".event instance EventHandler Program::ProgramChanged\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void CustomEvent()\n\t\t{\n\t\t\tvar ev = compilation.FindType(typeof(Program)).GetEvents(f => f.Name == \"SomeEvent\").Single();\n\t\t\tambience.ConversionFlags = ConversionFlags.StandardConversionFlags;\n\t\t\tstring result = ambience.ConvertSymbol(ev);\n\n\t\t\tAssert.That(result, Is.EqualTo(\".event instance EventHandler SomeEvent\"));\n\t\t}\n\t\t#endregion\n\n\t\t#region Property tests\n\t\t[TestCase(StandardConversionFlags, \".property instance int32 Test\")]\n\t\t[TestCase(ILSpyMainTreeViewMemberFlags, \"Test : int32\")]\n\t\tpublic void AutomaticProperty(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar prop = compilation.FindType(typeof(Program)).GetProperties(p => p.Name == \"Test\").Single();\n\t\t\tambience.ConversionFlags = flags;\n\n\t\t\tAssert.That(ambience.ConvertSymbol(prop), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(StandardConversionFlags, \".property instance int32 Item(int32 index)\")]\n\t\t[TestCase(ILSpyMainTreeViewMemberFlags, \"Item(int32) : int32\")]\n\t\tpublic void Indexer(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar prop = compilation.FindType(typeof(Program)).GetProperties(p => p.IsIndexer && !p.IsExplicitInterfaceImplementation).Single();\n\t\t\tambience.ConversionFlags = flags;\n\n\t\t\tAssert.That(ambience.ConvertSymbol(prop), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(StandardConversionFlags, \".property instance int32 ICSharpCode.Decompiler.Tests.Output.Interface.Item(int32 index)\")]\n\t\t[TestCase(ILSpyMainTreeViewMemberFlags, \"ICSharpCode.Decompiler.Tests.Output.Interface.Item(int32) : int32\")]\n\t\tpublic void ExplicitIndexer(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar prop = compilation.FindType(typeof(Program)).GetProperties(p => p.IsIndexer && p.IsExplicitInterfaceImplementation).Single();\n\t\t\tambience.ConversionFlags = flags;\n\n\t\t\tAssert.That(ambience.ConvertSymbol(prop), Is.EqualTo(expectedOutput));\n\t\t}\n\t\t#endregion\n\n\t\t#region IMethod tests\n\t\t[TestCase(StandardConversionFlags, \".method public hidebysig specialname rtspecialname instance .ctor(int32 x)\")]\n\t\t[TestCase(ILSpyMainTreeViewMemberFlags, \".ctor(int32)\")]\n\t\tpublic void ConstructorTests(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar prop = compilation.FindType(typeof(Program)).GetConstructors().Single();\n\t\t\tambience.ConversionFlags = flags;\n\n\t\t\tAssert.That(ambience.ConvertSymbol(prop), Is.EqualTo(expectedOutput));\n\t\t}\n\n\t\t[TestCase(StandardConversionFlags, \".method family hidebysig virtual instance void Finalize()\")]\n\t\t[TestCase(ILSpyMainTreeViewMemberFlags, \"Finalize() : void\")]\n\t\tpublic void DestructorTests(ConversionFlags flags, string expectedOutput)\n\t\t{\n\t\t\tvar dtor = compilation.FindType(typeof(Program))\n\t\t\t\t.GetMembers(m => m.SymbolKind == SymbolKind.Destructor, GetMemberOptions.IgnoreInheritedMembers).Single();\n\t\t\tambience.ConversionFlags = flags;\n\n\t\t\tAssert.That(ambience.ConvertSymbol(dtor), Is.EqualTo(expectedOutput));\n\t\t}\n\t\t#endregion\n\t}\n\n\t#region Test types\n#pragma warning disable 169, 67\n\n\tclass Test { }\n\tstatic class StaticClass { }\n\tsealed class SealedClass { }\n\tref struct RefStruct { }\n\treadonly struct ReadonlyStruct { }\n\treadonly ref struct ReadonlyRefStruct { }\n\n\tinterface Interface\n\t{\n\t\tint this[int x] { get; }\n\t}\n\n\tclass Program : Interface\n\t{\n\t\tint test;\n\t\tconst int TEST2 = 2;\n\n\t\tpublic int Test { get; set; }\n\n\t\tpublic int this[int index] {\n\t\t\tget {\n\t\t\t\treturn index;\n\t\t\t}\n\t\t}\n\n\t\tint Interface.this[int index] {\n\t\t\tget {\n\t\t\t\treturn index;\n\t\t\t}\n\t\t}\n\n\t\tpublic event EventHandler ProgramChanged;\n\n\t\tpublic event EventHandler SomeEvent {\n\t\t\tadd { }\n\t\t\tremove { }\n\t\t}\n\n\t\tpublic static bool operator +(Program lhs, Program rhs)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tpublic static implicit operator Test(Program lhs)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tpublic static explicit operator int(Program lhs)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tpublic Program(int x)\n\t\t{\n\n\t\t}\n\n\t\t~Program()\n\t\t{\n\n\t\t}\n\n\t\tpublic static void Main(string[] args)\n\t\t{\n\t\t\tConsole.WriteLine(\"Hello World!\");\n\n\t\t\tConsole.Write(\"Press any key to continue . . . \");\n\t\t\tConsole.ReadKey(true);\n\t\t}\n\n\t\tpublic static void InParameter(in int a)\n\t\t{\n\n\t\t}\n\t}\n\t#endregion\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/Output/InsertParenthesesVisitorTests.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.IO;\n\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\nusing ICSharpCode.Decompiler.CSharp.Syntax;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests.Output\n{\n\t[TestFixture]\n\tpublic class InsertParenthesesVisitorTests\n\t{\n\t\tCSharpFormattingOptions policy;\n\n\t\t[SetUp]\n\t\tpublic void SetUp()\n\t\t{\n\t\t\tpolicy = FormattingOptionsFactory.CreateMono();\n\t\t}\n\n\t\tstring InsertReadable(Expression expr)\n\t\t{\n\t\t\texpr = expr.Clone();\n\t\t\texpr.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true });\n\t\t\tStringWriter w = new StringWriter();\n\t\t\tw.NewLine = \" \";\n\t\t\texpr.AcceptVisitor(new CSharpOutputVisitor(new TextWriterTokenWriter(w) { IndentationString = \"\" }, policy));\n\t\t\treturn w.ToString();\n\t\t}\n\n\t\tstring InsertRequired(Expression expr)\n\t\t{\n\t\t\texpr = expr.Clone();\n\t\t\texpr.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = false });\n\t\t\tStringWriter w = new StringWriter();\n\t\t\tw.NewLine = \" \";\n\t\t\texpr.AcceptVisitor(new CSharpOutputVisitor(new TextWriterTokenWriter(w) { IndentationString = \"\" }, policy));\n\t\t\treturn w.ToString();\n\t\t}\n\n\t\t[Test]\n\t\tpublic void EqualityInAssignment()\n\t\t{\n\t\t\tExpression expr = new AssignmentExpression(\n\t\t\t\tnew IdentifierExpression(\"cond\"),\n\t\t\t\tnew BinaryOperatorExpression(\n\t\t\t\t\tnew IdentifierExpression(\"a\"),\n\t\t\t\t\tBinaryOperatorType.Equality,\n\t\t\t\t\tnew IdentifierExpression(\"b\")\n\t\t\t\t)\n\t\t\t);\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"cond = a == b\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"cond = a == b\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void LambdaInAssignment()\n\t\t{\n\t\t\tExpression expr = new AssignmentExpression(\n\t\t\t\tnew IdentifierExpression(\"p\"),\n\t\t\t\tnew LambdaExpression {\n\t\t\t\t\tBody = new BinaryOperatorExpression(\n\t\t\t\t\t\tnew IdentifierExpression(\"a\"),\n\t\t\t\t\t\tBinaryOperatorType.Add,\n\t\t\t\t\t\tnew IdentifierExpression(\"b\")\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"p = () => a + b\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"p = () => a + b\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void LambdaInDelegateAdditionRHS()\n\t\t{\n\t\t\tExpression expr = new BinaryOperatorExpression {\n\t\t\t\tLeft = new IdentifierExpression(\"p\"),\n\t\t\t\tOperator = BinaryOperatorType.Add,\n\t\t\t\tRight = new LambdaExpression {\n\t\t\t\t\tBody = new BinaryOperatorExpression(\n\t\t\t\t\t\tnew IdentifierExpression(\"a\"),\n\t\t\t\t\t\tBinaryOperatorType.Add,\n\t\t\t\t\t\tnew IdentifierExpression(\"b\")\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"p + () => a + b\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"p + (() => a + b)\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void LambdaInDelegateAdditionLHS()\n\t\t{\n\t\t\tExpression expr = new BinaryOperatorExpression {\n\t\t\t\tLeft = new LambdaExpression {\n\t\t\t\t\tBody = new BinaryOperatorExpression(\n\t\t\t\t\t\tnew IdentifierExpression(\"a\"),\n\t\t\t\t\t\tBinaryOperatorType.Add,\n\t\t\t\t\t\tnew IdentifierExpression(\"b\")\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t\tOperator = BinaryOperatorType.Add,\n\t\t\t\tRight = new IdentifierExpression(\"p\"),\n\t\t\t};\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"(() => a + b) + p\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"(() => a + b) + p\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TrickyCast1()\n\t\t{\n\t\t\tExpression expr = new CastExpression {\n\t\t\t\tType = new PrimitiveType(\"int\"),\n\t\t\t\tExpression = new UnaryOperatorExpression(\n\t\t\t\t\tUnaryOperatorType.Minus, new IdentifierExpression(\"a\")\n\t\t\t\t)\n\t\t\t};\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"(int)-a\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"(int)(-a)\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TrickyCast2()\n\t\t{\n\t\t\tExpression expr = new CastExpression {\n\t\t\t\tType = new SimpleType(\"MyType\"),\n\t\t\t\tExpression = new UnaryOperatorExpression(\n\t\t\t\t\tUnaryOperatorType.Minus, new IdentifierExpression(\"a\")\n\t\t\t\t)\n\t\t\t};\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"(MyType)(-a)\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"(MyType)(-a)\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TrickyCast3()\n\t\t{\n\t\t\tExpression expr = new CastExpression {\n\t\t\t\tType = new SimpleType(\"MyType\"),\n\t\t\t\tExpression = new UnaryOperatorExpression(\n\t\t\t\t\tUnaryOperatorType.Not, new IdentifierExpression(\"a\")\n\t\t\t\t)\n\t\t\t};\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"(MyType)!a\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"(MyType)(!a)\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TrickyCast4()\n\t\t{\n\t\t\tExpression expr = new CastExpression {\n\t\t\t\tType = new SimpleType(\"MyType\"),\n\t\t\t\tExpression = new PrimitiveExpression(int.MinValue),\n\t\t\t};\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"(MyType)(-2147483648)\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"(MyType)(-2147483648)\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TrickyCast5()\n\t\t{\n\t\t\tExpression expr = new CastExpression {\n\t\t\t\tType = new SimpleType(\"MyType\"),\n\t\t\t\tExpression = new PrimitiveExpression(-1.0),\n\t\t\t};\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"(MyType)(-1.0)\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"(MyType)(-1.0)\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TrickyCast6()\n\t\t{\n\t\t\tExpression expr = new CastExpression {\n\t\t\t\tType = new PrimitiveType(\"double\"),\n\t\t\t\tExpression = new PrimitiveExpression(int.MinValue),\n\t\t\t};\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"(double)-2147483648\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"(double)(-2147483648)\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void CastAndInvoke()\n\t\t{\n\t\t\tExpression expr = new MemberReferenceExpression {\n\t\t\t\tTarget = new CastExpression {\n\t\t\t\t\tType = new PrimitiveType(\"string\"),\n\t\t\t\t\tExpression = new IdentifierExpression(\"a\")\n\t\t\t\t},\n\t\t\t\tMemberName = \"Length\"\n\t\t\t};\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"((string)a).Length\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"((string)a).Length\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void DoubleNegation()\n\t\t{\n\t\t\tExpression expr = new UnaryOperatorExpression(\n\t\t\t\tUnaryOperatorType.Minus,\n\t\t\t\tnew UnaryOperatorExpression(UnaryOperatorType.Minus, new IdentifierExpression(\"a\"))\n\t\t\t);\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"- -a\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"-(-a)\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void AdditionWithConditional()\n\t\t{\n\t\t\tExpression expr = new BinaryOperatorExpression {\n\t\t\t\tLeft = new IdentifierExpression(\"a\"),\n\t\t\t\tOperator = BinaryOperatorType.Add,\n\t\t\t\tRight = new ConditionalExpression {\n\t\t\t\t\tCondition = new BinaryOperatorExpression {\n\t\t\t\t\t\tLeft = new IdentifierExpression(\"b\"),\n\t\t\t\t\t\tOperator = BinaryOperatorType.Equality,\n\t\t\t\t\t\tRight = new PrimitiveExpression(null)\n\t\t\t\t\t},\n\t\t\t\t\tTrueExpression = new IdentifierExpression(\"c\"),\n\t\t\t\t\tFalseExpression = new IdentifierExpression(\"d\")\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"a + (b == null ? c : d)\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"a + ((b == null) ? c : d)\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TypeTestInConditional()\n\t\t{\n\t\t\tExpression expr = new ConditionalExpression {\n\t\t\t\tCondition = new IsExpression {\n\t\t\t\t\tExpression = new IdentifierExpression(\"a\"),\n\t\t\t\t\tType = new ComposedType {\n\t\t\t\t\t\tBaseType = new PrimitiveType(\"int\"),\n\t\t\t\t\t\tHasNullableSpecifier = true\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tTrueExpression = new IdentifierExpression(\"b\"),\n\t\t\t\tFalseExpression = new IdentifierExpression(\"c\")\n\t\t\t};\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"a is int? ? b : c\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"(a is int?) ? b : c\"));\n\n\t\t\tpolicy.SpaceBeforeConditionalOperatorCondition = false;\n\t\t\tpolicy.SpaceAfterConditionalOperatorCondition = false;\n\t\t\tpolicy.SpaceBeforeConditionalOperatorSeparator = false;\n\t\t\tpolicy.SpaceAfterConditionalOperatorSeparator = false;\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"a is int? ?b:c\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"(a is int?)?b:c\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodCallOnQueryExpression()\n\t\t{\n\t\t\tExpression expr = new InvocationExpression(new MemberReferenceExpression {\n\t\t\t\tTarget = new QueryExpression {\n\t\t\t\t\tClauses = {\n\t\t\t\t\tnew QueryFromClause {\n\t\t\t\t\t\tIdentifier = \"a\",\n\t\t\t\t\t\tExpression = new IdentifierExpression(\"b\")\n\t\t\t\t\t},\n\t\t\t\t\tnew QuerySelectClause {\n\t\t\t\t\t\tExpression = new InvocationExpression(new MemberReferenceExpression {\n\t\t\t\t\t\t\tTarget = new IdentifierExpression(\"a\"),\n\t\t\t\t\t\t\tMemberName = \"c\"\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tMemberName = \"ToArray\"\n\t\t\t});\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"(from a in b select a.c ()).ToArray ()\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"(from a in b select a.c ()).ToArray ()\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void SumOfQueries()\n\t\t{\n\t\t\tQueryExpression query = new QueryExpression {\n\t\t\t\tClauses = {\n\t\t\t\t\tnew QueryFromClause {\n\t\t\t\t\t\tIdentifier = \"a\",\n\t\t\t\t\t\tExpression = new IdentifierExpression(\"b\")\n\t\t\t\t\t},\n\t\t\t\t\tnew QuerySelectClause {\n\t\t\t\t\t\tExpression = new IdentifierExpression(\"a\")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t\tExpression expr = new BinaryOperatorExpression(\n\t\t\t\tquery,\n\t\t\t\tBinaryOperatorType.Add,\n\t\t\t\tquery.Clone()\n\t\t\t);\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"(from a in b select a) + \" +\n\t\t\t\t\t\t\t\"from a in b select a\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"(from a in b select a) + \" +\n\t\t\t\t\t\t\t\"(from a in b select a)\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void QueryInTypeTest()\n\t\t{\n\t\t\tExpression expr = new IsExpression {\n\t\t\t\tExpression = new QueryExpression {\n\t\t\t\t\tClauses = {\n\t\t\t\t\t\tnew QueryFromClause {\n\t\t\t\t\t\t\tIdentifier = \"a\",\n\t\t\t\t\t\t\tExpression = new IdentifierExpression(\"b\")\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnew QuerySelectClause {\n\t\t\t\t\t\t\tExpression = new IdentifierExpression(\"a\")\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tType = new PrimitiveType(\"int\")\n\t\t\t};\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"(from a in b select a) is int\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"(from a in b select a) is int\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void PrePost()\n\t\t{\n\t\t\tExpression expr = new UnaryOperatorExpression(\n\t\t\t\tUnaryOperatorType.Increment,\n\t\t\t\tnew UnaryOperatorExpression(\n\t\t\t\t\tUnaryOperatorType.PostIncrement,\n\t\t\t\t\tnew IdentifierExpression(\"a\")\n\t\t\t\t)\n\t\t\t);\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"++a++\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"++(a++)\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void PostPre()\n\t\t{\n\t\t\tExpression expr = new UnaryOperatorExpression(\n\t\t\t\tUnaryOperatorType.PostIncrement,\n\t\t\t\tnew UnaryOperatorExpression(\n\t\t\t\t\tUnaryOperatorType.Increment,\n\t\t\t\t\tnew IdentifierExpression(\"a\")\n\t\t\t\t)\n\t\t\t);\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"(++a)++\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"(++a)++\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Logical1()\n\t\t{\n\t\t\tExpression expr = new BinaryOperatorExpression(\n\t\t\t\tnew BinaryOperatorExpression(\n\t\t\t\t\tnew IdentifierExpression(\"a\"),\n\t\t\t\t\tBinaryOperatorType.ConditionalAnd,\n\t\t\t\t\tnew IdentifierExpression(\"b\")\n\t\t\t\t),\n\t\t\t\tBinaryOperatorType.ConditionalAnd,\n\t\t\t\tnew IdentifierExpression(\"c\")\n\t\t\t);\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"a && b && c\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"a && b && c\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Logical2()\n\t\t{\n\t\t\tExpression expr = new BinaryOperatorExpression(\n\t\t\t\tnew IdentifierExpression(\"a\"),\n\t\t\t\tBinaryOperatorType.ConditionalAnd,\n\t\t\t\tnew BinaryOperatorExpression(\n\t\t\t\t\tnew IdentifierExpression(\"b\"),\n\t\t\t\t\tBinaryOperatorType.ConditionalAnd,\n\t\t\t\t\tnew IdentifierExpression(\"c\")\n\t\t\t\t)\n\t\t\t);\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"a && (b && c)\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"a && (b && c)\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Logical3()\n\t\t{\n\t\t\tExpression expr = new BinaryOperatorExpression(\n\t\t\t\tnew IdentifierExpression(\"a\"),\n\t\t\t\tBinaryOperatorType.ConditionalOr,\n\t\t\t\tnew BinaryOperatorExpression(\n\t\t\t\t\tnew IdentifierExpression(\"b\"),\n\t\t\t\t\tBinaryOperatorType.ConditionalAnd,\n\t\t\t\t\tnew IdentifierExpression(\"c\")\n\t\t\t\t)\n\t\t\t);\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"a || b && c\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"a || (b && c)\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Logical4()\n\t\t{\n\t\t\tExpression expr = new BinaryOperatorExpression(\n\t\t\t\tnew IdentifierExpression(\"a\"),\n\t\t\t\tBinaryOperatorType.ConditionalAnd,\n\t\t\t\tnew BinaryOperatorExpression(\n\t\t\t\t\tnew IdentifierExpression(\"b\"),\n\t\t\t\t\tBinaryOperatorType.ConditionalOr,\n\t\t\t\t\tnew IdentifierExpression(\"c\")\n\t\t\t\t)\n\t\t\t);\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"a && (b || c)\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"a && (b || c)\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ArrayCreationInIndexer()\n\t\t{\n\t\t\tExpression expr = new IndexerExpression {\n\t\t\t\tTarget = new ArrayCreateExpression {\n\t\t\t\t\tType = new PrimitiveType(\"int\"),\n\t\t\t\t\tArguments = { new PrimitiveExpression(1) }\n\t\t\t\t},\n\t\t\t\tArguments = { new PrimitiveExpression(0) }\n\t\t\t};\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"(new int[1]) [0]\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"(new int[1]) [0]\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ArrayCreationWithInitializerInIndexer()\n\t\t{\n\t\t\tExpression expr = new IndexerExpression {\n\t\t\t\tTarget = new ArrayCreateExpression {\n\t\t\t\t\tType = new PrimitiveType(\"int\"),\n\t\t\t\t\tArguments = { new PrimitiveExpression(1) },\n\t\t\t\t\tInitializer = new ArrayInitializerExpression {\n\t\t\t\t\t\tElements = { new PrimitiveExpression(42) }\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tArguments = { new PrimitiveExpression(0) }\n\t\t\t};\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"new int[1] { 42 } [0]\"));\n\t\t\tAssert.That(InsertReadable(expr), Is.EqualTo(\"(new int[1] { 42 }) [0]\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void AssignmentInObjectOrCollectionInitializer()\n\t\t{\n\t\t\tExpression expr = new ObjectCreateExpression {\n\t\t\t\tType = AstType.Create(\"List<int>\"),\n\t\t\t\tInitializer = new ArrayInitializerExpression {\n\t\t\t\t\tElements = { new AssignmentExpression(new IdentifierExpression(\"x\"), new PrimitiveExpression(42)) }\n\t\t\t\t}\n\t\t\t};\n\t\t\tExpression expr2 = new ObjectCreateExpression {\n\t\t\t\tType = AstType.Create(\"Data\"),\n\t\t\t\tInitializer = new ArrayInitializerExpression {\n\t\t\t\t\tElements = { new NamedExpression(\"X\", new PrimitiveExpression(42)) }\n\t\t\t\t}\n\t\t\t};\n\t\t\tExpression expr3 = new ObjectCreateExpression {\n\t\t\t\tType = AstType.Create(\"Dictionary<int, string>\"),\n\t\t\t\tInitializer = new ArrayInitializerExpression {\n\t\t\t\t\tElements = { new AssignmentExpression(new IndexerExpression(null, new PrimitiveExpression(0)), new PrimitiveExpression(\"42\")) }\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tAssert.That(InsertRequired(expr), Is.EqualTo(\"new List<int> { (x = 42) }\"));\n\t\t\tAssert.That(InsertRequired(expr2), Is.EqualTo(\"new Data { X = 42 }\"));\n\t\t\tAssert.That(InsertRequired(expr3), Is.EqualTo(\"new Dictionary<int, string> { [0] = \\\"42\\\" }\"));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs",
    "content": "using System;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.PortableExecutable;\nusing System.Runtime.CompilerServices;\nusing System.Text;\nusing System.Xml.Linq;\n\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.DebugInfo;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Tests.Helpers;\n\nusing Microsoft.DiaSymReader.Tools;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests\n{\n\t[TestFixture, Parallelizable(ParallelScope.All)]\n\tpublic class PdbGenerationTestRunner\n\t{\n\t\tstatic readonly string TestCasePath = Tester.TestCasePath + \"/PdbGen\";\n\n\t\t[Test]\n\t\tpublic void HelloWorld()\n\t\t{\n\t\t\tTestGeneratePdb();\n\t\t}\n\n\t\t[Test]\n\t\t[Ignore(\"Missing nested local scopes for loops, differences in IL ranges\")]\n\t\tpublic void ForLoopTests()\n\t\t{\n\t\t\tTestGeneratePdb();\n\t\t}\n\n\t\t[Test]\n\t\t[Ignore(\"Differences in IL ranges\")]\n\t\tpublic void LambdaCapturing()\n\t\t{\n\t\t\tTestGeneratePdb();\n\t\t}\n\n\t\t[Test]\n\t\t[Ignore(\"Duplicate sequence points for local function\")]\n\t\tpublic void Members()\n\t\t{\n\t\t\tTestGeneratePdb();\n\t\t}\n\n\t\t[Test]\n\t\tpublic void CustomPdbId()\n\t\t{\n\t\t\t// Generate a PDB for an assembly using a randomly-generated ID, then validate that the PDB uses the specified ID\n\t\t\t(string peFileName, string pdbFileName) = CompileTestCase(nameof(CustomPdbId));\n\n\t\t\tvar moduleDefinition = new PEFile(peFileName);\n\t\t\tvar resolver = new UniversalAssemblyResolver(peFileName, false, moduleDefinition.Metadata.DetectTargetFrameworkId(), null, PEStreamOptions.PrefetchEntireImage);\n\t\t\tvar decompiler = new CSharpDecompiler(moduleDefinition, resolver, new DecompilerSettings());\n\t\t\tvar expectedPdbId = new BlobContentId(Guid.NewGuid(), (uint)Random.Shared.Next());\n\n\t\t\tusing (FileStream pdbStream = File.Open(Path.Combine(TestCasePath, nameof(CustomPdbId) + \".pdb\"), FileMode.OpenOrCreate, FileAccess.ReadWrite))\n\t\t\t{\n\t\t\t\tpdbStream.SetLength(0);\n\t\t\t\tPortablePdbWriter.WritePdb(moduleDefinition, decompiler, new DecompilerSettings(), pdbStream, noLogo: true, pdbId: expectedPdbId);\n\n\t\t\t\tpdbStream.Position = 0;\n\t\t\t\tvar metadataReader = MetadataReaderProvider.FromPortablePdbStream(pdbStream).GetMetadataReader();\n\t\t\t\tvar generatedPdbId = new BlobContentId(metadataReader.DebugMetadataHeader.Id);\n\n\t\t\t\tAssert.That(generatedPdbId.Guid, Is.EqualTo(expectedPdbId.Guid));\n\t\t\t\tAssert.That(generatedPdbId.Stamp, Is.EqualTo(expectedPdbId.Stamp));\n\t\t\t}\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ProgressReporting()\n\t\t{\n\t\t\t// Generate a PDB for an assembly and validate that the progress reporter is called with reasonable values\n\t\t\t(string peFileName, string pdbFileName) = CompileTestCase(nameof(ProgressReporting));\n\n\t\t\tvar moduleDefinition = new PEFile(peFileName);\n\t\t\tvar resolver = new UniversalAssemblyResolver(peFileName, false, moduleDefinition.Metadata.DetectTargetFrameworkId(), null, PEStreamOptions.PrefetchEntireImage);\n\t\t\tvar decompiler = new CSharpDecompiler(moduleDefinition, resolver, new DecompilerSettings());\n\n\t\t\tvar lastFilesWritten = 0;\n\t\t\tvar totalFiles = -1;\n\n\t\t\tAction<DecompilationProgress> reportFunc = progress => {\n\t\t\t\tif (totalFiles == -1)\n\t\t\t\t{\n\t\t\t\t\t// Initialize value on first call\n\t\t\t\t\ttotalFiles = progress.TotalUnits;\n\t\t\t\t}\n\n\t\t\t\tAssert.That(totalFiles, Is.EqualTo(progress.TotalUnits));\n\t\t\t\tAssert.That(lastFilesWritten + 1, Is.EqualTo(progress.UnitsCompleted));\n\n\t\t\t\tlastFilesWritten = progress.UnitsCompleted;\n\t\t\t};\n\n\t\t\tusing (FileStream pdbStream = File.Open(Path.Combine(TestCasePath, nameof(ProgressReporting) + \".pdb\"), FileMode.OpenOrCreate, FileAccess.ReadWrite))\n\t\t\t{\n\t\t\t\tpdbStream.SetLength(0);\n\t\t\t\tPortablePdbWriter.WritePdb(moduleDefinition, decompiler, new DecompilerSettings(), pdbStream, noLogo: true, progress: new TestProgressReporter(reportFunc));\n\n\t\t\t\tpdbStream.Position = 0;\n\t\t\t\tvar metadataReader = MetadataReaderProvider.FromPortablePdbStream(pdbStream).GetMetadataReader();\n\t\t\t\tvar generatedPdbId = new BlobContentId(metadataReader.DebugMetadataHeader.Id);\n\t\t\t}\n\n\t\t\tAssert.That(lastFilesWritten, Is.EqualTo(totalFiles));\n\t\t}\n\n\t\tprivate class TestProgressReporter : IProgress<DecompilationProgress>\n\t\t{\n\t\t\tprivate Action<DecompilationProgress> reportFunc;\n\n\t\t\tpublic TestProgressReporter(Action<DecompilationProgress> reportFunc)\n\t\t\t{\n\t\t\t\tthis.reportFunc = reportFunc;\n\t\t\t}\n\n\t\t\tpublic void Report(DecompilationProgress value)\n\t\t\t{\n\t\t\t\treportFunc(value);\n\t\t\t}\n\t\t}\n\n\t\tprivate void TestGeneratePdb([CallerMemberName] string testName = null)\n\t\t{\n\t\t\tconst PdbToXmlOptions options = PdbToXmlOptions.IncludeEmbeddedSources | PdbToXmlOptions.ThrowOnError | PdbToXmlOptions.IncludeTokens | PdbToXmlOptions.ResolveTokens | PdbToXmlOptions.IncludeMethodSpans;\n\n\t\t\tstring xmlFile = Path.Combine(TestCasePath, testName + \".xml\");\n\t\t\t(string peFileName, string pdbFileName) = CompileTestCase(testName);\n\n\t\t\tvar moduleDefinition = new PEFile(peFileName);\n\t\t\tvar resolver = new UniversalAssemblyResolver(peFileName, false, moduleDefinition.Metadata.DetectTargetFrameworkId(), null, PEStreamOptions.PrefetchEntireImage);\n\t\t\tvar decompiler = new CSharpDecompiler(moduleDefinition, resolver, new DecompilerSettings());\n\t\t\tusing (FileStream pdbStream = File.Open(Path.Combine(TestCasePath, testName + \".pdb\"), FileMode.OpenOrCreate, FileAccess.ReadWrite))\n\t\t\t{\n\t\t\t\tpdbStream.SetLength(0);\n\t\t\t\tPortablePdbWriter.WritePdb(moduleDefinition, decompiler, new DecompilerSettings(), pdbStream, noLogo: true);\n\t\t\t\tpdbStream.Position = 0;\n\t\t\t\tusing (Stream peStream = File.OpenRead(peFileName))\n\t\t\t\tusing (Stream expectedPdbStream = File.OpenRead(pdbFileName))\n\t\t\t\t{\n\t\t\t\t\tusing (StreamWriter writer = new StreamWriter(Path.ChangeExtension(pdbFileName, \".xml\"), false, Encoding.UTF8))\n\t\t\t\t\t{\n\t\t\t\t\t\tPdbToXmlConverter.ToXml(writer, expectedPdbStream, peStream, options);\n\t\t\t\t\t}\n\t\t\t\t\tpeStream.Position = 0;\n\t\t\t\t\tusing (StreamWriter writer = new StreamWriter(Path.ChangeExtension(xmlFile, \".generated.xml\"), false, Encoding.UTF8))\n\t\t\t\t\t{\n\t\t\t\t\t\tPdbToXmlConverter.ToXml(writer, pdbStream, peStream, options);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tstring expectedFileName = Path.ChangeExtension(xmlFile, \".expected.xml\");\n\t\t\tProcessXmlFile(expectedFileName);\n\t\t\tstring generatedFileName = Path.ChangeExtension(xmlFile, \".generated.xml\");\n\t\t\tProcessXmlFile(generatedFileName);\n\t\t\tCodeAssert.AreEqual(Normalize(expectedFileName), Normalize(generatedFileName));\n\t\t}\n\n\t\tprivate (string peFileName, string pdbFileName) CompileTestCase(string testName)\n\t\t{\n\t\t\tstring xmlFile = Path.Combine(TestCasePath, testName + \".xml\");\n\t\t\tstring xmlContent = File.ReadAllText(xmlFile);\n\t\t\tXDocument document = XDocument.Parse(xmlContent);\n\t\t\tvar files = document.Descendants(\"file\").ToDictionary(f => f.Attribute(\"name\").Value, f => f.Value);\n\t\t\tTester.CompileCSharpWithPdb(Path.Combine(TestCasePath, testName + \".expected\"), files);\n\n\t\t\tstring peFileName = Path.Combine(TestCasePath, testName + \".expected.dll\");\n\t\t\tstring pdbFileName = Path.Combine(TestCasePath, testName + \".expected.pdb\");\n\n\t\t\treturn (peFileName, pdbFileName);\n\t\t}\n\n\t\tprivate void ProcessXmlFile(string fileName)\n\t\t{\n\t\t\tvar document = XDocument.Load(fileName);\n\t\t\tforeach (var file in document.Descendants(\"file\"))\n\t\t\t{\n\t\t\t\tfile.Attribute(\"checksum\").Remove();\n\t\t\t\tfile.Attribute(\"embeddedSourceLength\")?.Remove();\n\t\t\t\tfile.ReplaceNodes(new XCData(file.Value.Replace(\"\\uFEFF\", \"\")));\n\t\t\t}\n\t\t\tdocument.Save(fileName, SaveOptions.None);\n\t\t}\n\n\t\tprivate string Normalize(string inputFileName)\n\t\t{\n\t\t\treturn File.ReadAllText(inputFileName).Replace(\"\\r\\n\", \"\\n\").Replace(\"\\r\", \"\\n\");\n\t\t}\n\t}\n\n\tclass StringWriterWithEncoding : StringWriter\n\t{\n\t\treadonly Encoding encoding;\n\n\t\tpublic StringWriterWithEncoding(Encoding encoding)\n\t\t{\n\t\t\tthis.encoding = encoding ?? throw new ArgumentNullException(\"encoding\");\n\t\t}\n\n\t\tpublic override Encoding Encoding => encoding;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.Tests.Helpers;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests\n{\n\t[TestFixture, Parallelizable(ParallelScope.All)]\n\tpublic class PrettyTestRunner\n\t{\n\t\tstatic readonly string TestCasePath = Tester.TestCasePath + \"/Pretty\";\n\n\t\t[Test]\n\t\tpublic void AllFilesHaveTests()\n\t\t{\n\t\t\tvar testNames = typeof(PrettyTestRunner).GetMethods()\n\t\t\t\t.Where(m => m.GetCustomAttributes(typeof(TestAttribute), false).Any())\n\t\t\t\t.Select(m => m.Name)\n\t\t\t\t.ToArray();\n\t\t\tforeach (var file in new DirectoryInfo(TestCasePath).EnumerateFiles())\n\t\t\t{\n\t\t\t\tif (file.Extension.Equals(\".il\", StringComparison.OrdinalIgnoreCase)\n\t\t\t\t\t|| file.Extension.Equals(\".cs\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t{\n\t\t\t\t\tvar testName = file.Name.Split('.')[0];\n\t\t\t\t\tAssert.That(testNames, Has.Member(testName));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic readonly CompilerOptions[] noRoslynOptions =\n\t\t{\n\t\t\tCompilerOptions.None,\n\t\t\tCompilerOptions.Optimize\n\t\t};\n\n\t\tstatic readonly CompilerOptions[] roslynOnlyWithNet40Options =\n\t\t{\n\t\t\tCompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn1_3_2,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,\n\t\t\tCompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,\n\t\t};\n\n\t\tstatic readonly CompilerOptions[] roslynOnlyOptions =\n\t\t{\n\t\t\tCompilerOptions.UseRoslyn1_3_2,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,\n\t\t\tCompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,\n\t\t};\n\n\t\tstatic readonly CompilerOptions[] roslyn2OrNewerWithNet40Options =\n\t\t{\n\t\t\tCompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,\n\t\t};\n\n\t\tstatic readonly CompilerOptions[] roslyn2OrNewerOptions =\n\t\t{\n\t\t\tCompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,\n\t\t};\n\n\t\tstatic readonly CompilerOptions[] roslyn3OrNewerWithNet40Options =\n\t\t{\n\t\t\tCompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,\n\t\t};\n\n\t\tstatic readonly CompilerOptions[] roslyn3OrNewerOptions =\n\t\t{\n\t\t\tCompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,\n\t\t};\n\n\t\tstatic readonly CompilerOptions[] roslyn4OrNewerWithNet40Options =\n\t\t{\n\t\t\tCompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,\n\t\t};\n\n\t\tstatic readonly CompilerOptions[] roslyn4OrNewerOptions =\n\t\t{\n\t\t\tCompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,\n\t\t};\n\n\t\tstatic readonly CompilerOptions[] defaultOptions =\n\t\t{\n\t\t\tCompilerOptions.None,\n\t\t\tCompilerOptions.Optimize,\n\t\t\tCompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn1_3_2,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,\n\t\t\tCompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,\n\t\t};\n\n\t\tstatic readonly CompilerOptions[] defaultOptionsWithMcs =\n\t\t{\n\t\t\tCompilerOptions.None,\n\t\t\tCompilerOptions.Optimize,\n\t\t\tCompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn1_3_2,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,\n\t\t\tCompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,\n\t\t\tCompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.UseMcs2_6_4,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseMcs2_6_4,\n\t\t\tCompilerOptions.UseMcs5_23,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseMcs5_23\n\t\t};\n\n\t\t[Test]\n\t\tpublic async Task HelloWorld()\n\t\t{\n\t\t\tawait RunForLibrary();\n\t\t\tawait RunForLibrary(asmOptions: AssemblerOptions.UseDebug);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task IndexRangeTest([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tif (cscOptions.HasFlag(CompilerOptions.UseRoslynLatest))\n\t\t\t{\n\t\t\t\tAssert.Ignore(\"See https://github.com/icsharpcode/ILSpy/issues/2540\");\n\t\t\t}\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task InlineAssignmentTest([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task CompoundAssignmentTest([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ShortCircuit([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task CustomShortCircuitOperators([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ExceptionHandling([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => {\n\t\t\t\tsettings.NullPropagation = false;\n\t\t\t\t// legacy csc generates a dead store in debug builds\n\t\t\t\tsettings.RemoveDeadStores = (cscOptions == CompilerOptions.None);\n\t\t\t\tsettings.FileScopedNamespaces = false;\n\t\t\t});\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Switch([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => {\n\t\t\t\t// legacy csc generates a dead store in debug builds\n\t\t\t\tsettings.RemoveDeadStores = (cscOptions == CompilerOptions.None);\n\t\t\t\tsettings.SwitchExpressions = false;\n\t\t\t});\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task SwitchExpressions([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ReduceNesting([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task DelegateConstruction([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => {\n\t\t\t\tsettings.QueryExpressions = false;\n\t\t\t\tsettings.NullableReferenceTypes = false;\n\t\t\t});\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task AnonymousTypes([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Async([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Lock([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Using([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(\n\t\t\t\tcscOptions: cscOptions,\n\t\t\t\tconfigureDecompiler: settings => {\n\t\t\t\t\tsettings.UseEnhancedUsing = false;\n\t\t\t\t\tsettings.FileScopedNamespaces = false;\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task UsingVariables([ValueSource(nameof(roslyn3OrNewerWithNet40Options))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task GloballyQualifiedTypeInStringInterpolation([ValueSource(nameof(roslynOnlyWithNet40Options))] CompilerOptions cscOptions)\n\t\t{\n\t\t\t// https://github.com/icsharpcode/ILSpy/issues/3447\n\t\t\tawait RunForLibrary(\n\t\t\t\tcscOptions: cscOptions,\n\t\t\t\tconfigureDecompiler: settings => {\n\t\t\t\t\tsettings.UsingDeclarations = false;\n\t\t\t\t\tsettings.AlwaysUseGlobal = true;\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task LiftedOperators([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Operators([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Generics([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Loops([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => {\n\t\t\t\t// legacy csc generates a dead store in debug builds\n\t\t\t\tsettings.RemoveDeadStores = (cscOptions == CompilerOptions.None);\n\t\t\t\tsettings.UseExpressionBodyForCalculatedGetterOnlyProperties = false;\n\t\t\t});\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task LocalFunctions([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task PropertiesAndEvents([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions | CompilerOptions.NullableEnable);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task AutoProperties([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task QueryExpressions([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task TypeAnalysisTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task CheckedUnchecked([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task UnsafeCode([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions | CompilerOptions.ReferenceUnsafe);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ConstructorInitializers([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions | CompilerOptions.ProcessXmlDoc);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task PInvoke([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\t// This tests needs our own disassembler; ildasm has a bug with marshalinfo.\n\t\t\tawait RunForLibrary(cscOptions: cscOptions, asmOptions: AssemblerOptions.UseOwnDisassembler);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task OutVariables([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task PatternMatching([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task InitializerTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions | CompilerOptions.NullableEnable);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task DynamicTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ExpressionTrees([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task FixProxyCalls([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ValueTypes([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task VariableNaming([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions | CompilerOptions.GeneratePdb);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task VariableNamingWithoutSymbols([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => settings.UseDebugSymbols = false);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task CS72_PrivateProtected([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task AsyncForeach([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task AsyncMain([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait Run(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task AsyncStreams([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task AsyncUsing([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(\n\t\t\t\tcscOptions: cscOptions,\n\t\t\t\tconfigureDecompiler: settings => { settings.UseEnhancedUsing = false; }\n\t\t\t);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task CustomTaskType([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task NullableRefTypes([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions | CompilerOptions.NullableEnable);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task NativeInts([ValueSource(nameof(roslyn3OrNewerWithNet40Options))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task FileScopedNamespaces([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => settings.FileScopedNamespaces = true);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Structs([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task FunctionPointers([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Records([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3610([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3611([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3452([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions | CompilerOptions.NullableEnable);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3598([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions | CompilerOptions.NullableEnable);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ExtensionProperties([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions | CompilerOptions.Preview | CompilerOptions.NullableEnable);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task NullPropagation([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task StringInterpolation([ValueSource(nameof(roslynOnlyWithNet40Options))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait Run(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task CS73_StackAllocInitializers([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task RefLocalsAndReturns([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task RefFields([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ThrowExpressions([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task WellKnownConstants([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task QualifierTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task TupleTests([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task NamedArguments([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task OptionalArguments([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task OptionalArgumentsDisabled([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(\n\t\t\t\tcscOptions: cscOptions,\n\t\t\t\tconfigureDecompiler: settings => {\n\t\t\t\t\tsettings.OptionalArguments = false;\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Comparisons([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ConstantsTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ParamsCollections([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ExpandParamsArgumentsDisabled([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => settings.ExpandParamsArguments = false);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue1080([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => settings.SetLanguageVersion(CSharp.LanguageVersion.CSharp6));\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3439([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3406([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3442([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3483([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions | CompilerOptions.CheckForOverflowUnderflow, configureDecompiler: settings => settings.CheckForOverflowUnderflow = true);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3541([ValueSource(nameof(roslyn4OrNewerWithNet40Options))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3571_A([ValueSource(nameof(roslyn2OrNewerWithNet40Options))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3571_B([ValueSource(nameof(roslyn2OrNewerWithNet40Options))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3571_C([ValueSource(nameof(roslyn2OrNewerWithNet40Options))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3576([ValueSource(nameof(roslyn2OrNewerWithNet40Options))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue3584([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task AssemblyCustomAttributes([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task CustomAttributes([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task CustomAttributes2([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task CustomAttributeConflicts([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task CustomAttributeSamples([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task MemberTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task MultidimensionalArray([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task EnumTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task InterfaceTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task TypeMemberTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task YieldReturn([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task UserDefinedConversions([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Discards([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task DeconstructionTests([ValueSource(nameof(roslyn2OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task CS9_ExtensionGetEnumerator([ValueSource(nameof(roslyn3OrNewerWithNet40Options))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task CovariantReturns([ValueSource(nameof(roslyn3OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task StaticAbstractInterfaceMembers([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task MetadataAttributes([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task PointerArithmetic([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task InlineArrayTests([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions);\n\t\t}\n\n\t\tasync Task RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, Action<DecompilerSettings> configureDecompiler = null)\n\t\t{\n\t\t\tawait Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CompilerOptions.Library, configureDecompiler);\n\t\t}\n\n\t\tasync Task Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, Action<DecompilerSettings> configureDecompiler = null)\n\t\t{\n\t\t\tvar csFile = Path.Combine(TestCasePath, testName + \".cs\");\n\t\t\tvar exeFile = TestsAssemblyOutput.GetFilePath(TestCasePath, testName, Tester.GetSuffix(cscOptions) + \".exe\");\n\t\t\tif (cscOptions.HasFlag(CompilerOptions.Library))\n\t\t\t{\n\t\t\t\texeFile = Path.ChangeExtension(exeFile, \".dll\");\n\t\t\t}\n\n\t\t\t// 1. Compile\n\t\t\tCompilerResults output = null;\n\t\t\ttry\n\t\t\t{\n\t\t\t\toutput = await Tester.CompileCSharp(csFile, cscOptions, exeFile).ConfigureAwait(false);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tif (output != null)\n\t\t\t\t\toutput.DeleteTempFiles();\n\t\t\t}\n\n\t\t\t// 2. Decompile\n\t\t\tvar settings = Tester.GetSettings(cscOptions);\n\t\t\tconfigureDecompiler?.Invoke(settings);\n\t\t\tvar decompiled = await Tester.DecompileCSharp(exeFile, settings).ConfigureAwait(false);\n\n\t\t\t// 3. Compare\n\t\t\tCodeAssert.FilesAreEqual(csFile, decompiled, Tester.GetPreprocessorSymbols(cscOptions).Append(\"EXPECTED_OUTPUT\").ToArray());\n\t\t\tTester.RepeatOnIOError(() => File.Delete(decompiled));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/ProjectDecompiler/TargetFrameworkTests.cs",
    "content": "// Copyright (c) 2020 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.Decompiler.CSharp.ProjectDecompiler;\nusing ICSharpCode.Decompiler.Metadata;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests.ProjectDecompiler\n{\n\t[TestFixture]\n\tpublic sealed class TargetFrameworkTests\n\t{\n\t\t[TestCase(-1)]\n\t\t[TestCase(0)]\n\t\t[TestCase(1)]\n\t\t[TestCase(99)]\n\t\t[TestCase(int.MinValue)]\n\t\tpublic void VerifyThrowsForInvalidVersion(int invalidVersion)\n\t\t{\n\t\t\t// Arrange - nothing\n\n\t\t\t// Act\n\t\t\tvoid CreateInstance() => new TargetFramework(identifier: null, invalidVersion, profile: null);\n\n\t\t\t// Assert\n\t\t\tAssert.Throws<ArgumentException>(CreateInstance);\n\t\t}\n\n\t\t[TestCase(100, \"v1.0\")]\n\t\t[TestCase(102, \"v1.0.2\")]\n\t\t[TestCase(130, \"v1.3\")]\n\t\t[TestCase(145, \"v1.4.5\")]\n\t\t[TestCase(1670, \"v16.7\")]\n\t\t[TestCase(1800, \"v18.0\")]\n\t\tpublic void VerifyVersion(int version, string expectedVersion)\n\t\t{\n\t\t\t// Arrange - nothing\n\n\t\t\t// Act\n\t\t\tvar targetFramework = new TargetFramework(identifier: null, version, profile: null);\n\n\t\t\t// Assert\n\t\t\tAssert.That(targetFramework.VersionNumber, Is.EqualTo(version));\n\t\t\tAssert.That(targetFramework.VersionString, Is.EqualTo(expectedVersion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void VerifyPortableLibrary()\n\t\t{\n\t\t\t// Arrange\n\t\t\tconst string identifier = \".NETPortable\";\n\n\t\t\t// Act\n\t\t\tvar targetFramework = new TargetFramework(identifier, 100, profile: null);\n\n\t\t\t// Assert\n\t\t\tAssert.That(targetFramework.IsPortableClassLibrary);\n\t\t\tAssert.That(targetFramework.Identifier, Is.EqualTo(identifier));\n\t\t}\n\n\t\t[Test]\n\t\t[Pairwise]\n\t\tpublic void VerifyIdentifierAndProfile(\n\t\t\t[Values(null, \"\", \".NETFramework\")] string identifier,\n\t\t\t[Values(null, \"\", \".Client\")] string profile)\n\t\t{\n\t\t\t// Arrange - nothing\n\n\t\t\t// Act\n\t\t\tvar targetFramework = new TargetFramework(identifier, 100, profile);\n\n\t\t\t// Assert\n\t\t\tAssert.That(targetFramework.Identifier, Is.EqualTo(identifier));\n\t\t\tAssert.That(targetFramework.Profile, Is.EqualTo(profile));\n\t\t}\n\n\t\t[TestCase(null, 350, \"net35\")]\n\t\t[TestCase(\".NETFramework\", 350, \"net35\")]\n\t\t[TestCase(\".NETFramework\", 400, \"net40\")]\n\t\t[TestCase(\".NETFramework\", 451, \"net451\")]\n\t\t[TestCase(\".NETCoreApp\", 200, \"netcoreapp2.0\")]\n\t\t[TestCase(\".NETCoreApp\", 310, \"netcoreapp3.1\")]\n\t\t[TestCase(\".NETStandard\", 130, \"netstandard1.3\")]\n\t\t[TestCase(\".NETStandard\", 200, \"netstandard2.0\")]\n\t\t[TestCase(\"Silverlight\", 400, \"sl4\")]\n\t\t[TestCase(\"Silverlight\", 550, \"sl5\")]\n\t\t[TestCase(\".NETCore\", 450, \"netcore45\")]\n\t\t[TestCase(\".NETCore\", 451, \"netcore451\")]\n\t\t[TestCase(\"WindowsPhone\", 700, \"wp7\")]\n\t\t[TestCase(\"WindowsPhone\", 810, \"wp81\")]\n\t\t[TestCase(\".NETMicroFramework\", 100, \"netmf\")]\n\t\t[TestCase(\".NETMicroFramework\", 210, \"netmf\")]\n\t\t[TestCase(\".NETPortable\", 100, null)]\n\t\t[TestCase(\"Unsupported\", 100, null)]\n\t\tpublic void VerifyMoniker(string identifier, int version, string expectedMoniker)\n\t\t{\n\t\t\t// Arrange - nothing\n\n\t\t\t// Act\n\t\t\tvar targetFramework = new TargetFramework(identifier, version, profile: null);\n\n\t\t\t// Assert\n\t\t\tAssert.That(targetFramework.Moniker, Is.EqualTo(expectedMoniker));\n\t\t}\n\n\t\t[TestCase(\".NETCoreApp, Version=v5.0\", TargetFrameworkIdentifier.NET, \"5.0.0\")]\n\t\t[TestCase(\".NETCoreApp, Version=v10.0\", TargetFrameworkIdentifier.NET, \"10.0.0\")]\n\t\tpublic void VerifyUniversalAssemblyResolverParseTargetFramework(string targetFramework, TargetFrameworkIdentifier identifier, string version)\n\t\t{\n\t\t\tvar (id, v) = UniversalAssemblyResolver.ParseTargetFramework(targetFramework);\n\t\t\tAssert.That(id, Is.EqualTo(identifier));\n\t\t\tAssert.That(v.ToString(3), Is.EqualTo(version));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/ProjectDecompiler/WholeProjectDecompilerTests.cs",
    "content": "// Copyright (c) 2025 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\n\nusing ICSharpCode.Decompiler.CSharp.ProjectDecompiler;\nusing ICSharpCode.Decompiler.Metadata;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests.ProjectDecompiler;\n\n[TestFixture]\npublic sealed class WholeProjectDecompilerTests\n{\n\t[Test]\n\tpublic void UseNestedDirectoriesForNamespacesTrueWorks()\n\t{\n\t\tstring targetDirectory = Path.Combine(Environment.CurrentDirectory, Path.GetRandomFileName());\n\t\tTestFriendlyProjectDecompiler decompiler = new(new UniversalAssemblyResolver(null, false, null));\n\t\tdecompiler.Settings.UseNestedDirectoriesForNamespaces = true;\n\t\tdecompiler.DecompileProject(new PEFile(\"ICSharpCode.Decompiler.dll\"), targetDirectory);\n\t\tAssertDirectoryDoesntExist(targetDirectory);\n\n\t\tstring projectDecompilerDirectory = Path.Combine(targetDirectory, \"ICSharpCode\", \"Decompiler\", \"CSharp\", \"ProjectDecompiler\");\n\t\tstring projectDecompilerFile = Path.Combine(projectDecompilerDirectory, $\"{nameof(WholeProjectDecompiler)}.cs\");\n\n\t\tusing (Assert.EnterMultipleScope())\n\t\t{\n\t\t\tAssert.That(decompiler.Files.ContainsKey(projectDecompilerFile), Is.True);\n\t\t\tAssert.That(decompiler.Directories.Contains(projectDecompilerDirectory), Is.True);\n\t\t}\n\t}\n\n\t[Test]\n\tpublic void UseNestedDirectoriesForNamespacesFalseWorks()\n\t{\n\t\tstring targetDirectory = Path.Combine(Environment.CurrentDirectory, Path.GetRandomFileName());\n\t\tTestFriendlyProjectDecompiler decompiler = new(new UniversalAssemblyResolver(null, false, null));\n\t\tdecompiler.Settings.UseNestedDirectoriesForNamespaces = false;\n\t\tdecompiler.DecompileProject(new PEFile(\"ICSharpCode.Decompiler.dll\"), targetDirectory);\n\t\tAssertDirectoryDoesntExist(targetDirectory);\n\n\t\tstring projectDecompilerDirectory = Path.Combine(targetDirectory, \"ICSharpCode.Decompiler.CSharp.ProjectDecompiler\");\n\t\tstring projectDecompilerFile = Path.Combine(projectDecompilerDirectory, $\"{nameof(WholeProjectDecompiler)}.cs\");\n\n\t\tusing (Assert.EnterMultipleScope())\n\t\t{\n\t\t\tAssert.That(decompiler.Files.ContainsKey(projectDecompilerFile), Is.True);\n\t\t\tAssert.That(decompiler.Directories.Contains(projectDecompilerDirectory), Is.True);\n\t\t}\n\t}\n\n\tstatic void AssertDirectoryDoesntExist(string directory)\n\t{\n\t\tif (Directory.Exists(directory))\n\t\t{\n\t\t\tDirectory.Delete(directory, recursive: true);\n\t\t\tAssert.Fail(\"Directory should not have been created.\");\n\t\t}\n\t}\n\n\tsealed class TestFriendlyProjectDecompiler(IAssemblyResolver assemblyResolver) : WholeProjectDecompiler(assemblyResolver)\n\t{\n\t\tpublic Dictionary<string, StringWriter> Files { get; } = [];\n\t\tpublic HashSet<string> Directories { get; } = [];\n\n\t\tprotected override TextWriter CreateFile(string path)\n\t\t{\n\t\t\tStringWriter writer = new();\n\t\t\tlock (Files)\n\t\t\t{\n\t\t\t\tFiles[path] = writer;\n\t\t\t}\n\t\t\treturn writer;\n\t\t}\n\n\t\tprotected override void CreateDirectory(string path)\n\t\t{\n\t\t\tlock (Directories)\n\t\t\t{\n\t\t\t\tDirectories.Add(path);\n\t\t\t}\n\t\t}\n\n\t\tprotected override IEnumerable<ProjectItemInfo> WriteMiscellaneousFilesInProject(PEFile module) => [];\n\n\t\tprotected override IEnumerable<ProjectItemInfo> WriteResourceFilesInProject(MetadataFile module) => [];\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/Properties/AssemblyInfo.cs",
    "content": "#region Using directives\n\nusing System.Diagnostics.CodeAnalysis;\nusing System.Reflection;\nusing System.Runtime.InteropServices;\n\n#endregion\n\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// This sets the default COM visibility of types in the assembly to invisible.\n// If you need to expose a type to COM, use [ComVisible(true)] on that type.\n[assembly: ComVisible(false)]\n\n[assembly: AssemblyVersion(DecompilerVersionInfo.Major + \".\" + DecompilerVersionInfo.Minor + \".\" + DecompilerVersionInfo.Build + \".\" + DecompilerVersionInfo.Revision)]\n[assembly: AssemblyInformationalVersion(DecompilerVersionInfo.FullVersionWithCommitHash)]\n\n[assembly: SuppressMessage(\"Microsoft.Usage\", \"CA2243:AttributeStringLiteralsShouldParseCorrectly\",\n\tJustification = \"AssemblyInformationalVersion does not need to be a parsable version\")]\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/RoundtripAssembly.cs",
    "content": "// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Reflection.PortableExecutable;\nusing System.Text.RegularExpressions;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nusing CliWrap;\n\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.CSharp.ProjectDecompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Tests;\nusing ICSharpCode.Decompiler.Tests.Helpers;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Roundtrip\n{\n\t[TestFixture, Parallelizable(ParallelScope.All)]\n\tpublic class RoundtripAssembly\n\t{\n\t\tpublic static readonly string TestDir = Path.GetFullPath(Path.Combine(Tester.TestCasePath, \"../../ILSpy-tests\"));\n\t\tstatic readonly string nunit = Path.Combine(TestDir, \"nunit\", \"nunit3-console.exe\");\n\n\t\t[Test]\n\t\tpublic async Task Cecil_net45()\n\t\t{\n\t\t\tawait RunWithTest(\"Mono.Cecil-net45\", \"Mono.Cecil.dll\", \"Mono.Cecil.Tests.dll\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task NewtonsoftJson_net45()\n\t\t{\n\t\t\tawait RunWithTest(\"Newtonsoft.Json-net45\", \"Newtonsoft.Json.dll\", \"Newtonsoft.Json.Tests.dll\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task NewtonsoftJson_pcl_debug()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tawait RunWithTest(\"Newtonsoft.Json-pcl-debug\", \"Newtonsoft.Json.dll\", \"Newtonsoft.Json.Tests.dll\", useOldProjectFormat: true);\n\t\t\t}\n\t\t\tcatch (CompilationFailedException)\n\t\t\t{\n\t\t\t\tAssert.Ignore(\"Cannot yet re-compile PCL projects.\");\n\t\t\t}\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task NRefactory_CSharp()\n\t\t{\n\t\t\tawait RunWithTest(\"NRefactory\", \"ICSharpCode.NRefactory.CSharp.dll\", \"ICSharpCode.NRefactory.Tests.dll\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ICSharpCode_Decompiler()\n\t\t{\n\t\t\tawait RunOnly(\"ICSharpCode.Decompiler\", \"ICSharpCode.Decompiler.dll\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ImplicitConversions()\n\t\t{\n\t\t\tawait RunWithOutput(\"Random Tests\\\\TestCases\", \"ImplicitConversions.exe\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ImplicitConversions_32()\n\t\t{\n\t\t\tawait RunWithOutput(\"Random Tests\\\\TestCases\", \"ImplicitConversions_32.exe\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ExplicitConversions()\n\t\t{\n\t\t\tawait RunWithOutput(\"Random Tests\\\\TestCases\", \"ExplicitConversions.exe\", LanguageVersion.CSharp8_0);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ExplicitConversions_32()\n\t\t{\n\t\t\tawait RunWithOutput(\"Random Tests\\\\TestCases\", \"ExplicitConversions_32.exe\", LanguageVersion.CSharp8_0);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ExplicitConversions_With_NativeInts()\n\t\t{\n\t\t\tawait RunWithOutput(\"Random Tests\\\\TestCases\", \"ExplicitConversions.exe\", LanguageVersion.CSharp9_0);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task ExplicitConversions_32_With_NativeInts()\n\t\t{\n\t\t\tawait RunWithOutput(\"Random Tests\\\\TestCases\", \"ExplicitConversions_32.exe\", LanguageVersion.CSharp9_0);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Random_TestCase_1()\n\t\t{\n\t\t\tawait RunWithOutput(\"Random Tests\\\\TestCases\", \"TestCase-1.exe\", LanguageVersion.CSharp8_0);\n\t\t}\n\n\t\t[Test]\n\t\t[Ignore(\"See https://github.com/icsharpcode/ILSpy/issues/2541 - Waiting for https://github.com/dotnet/roslyn/issues/45929\")]\n\t\tpublic async Task Random_TestCase_1_With_NativeInts()\n\t\t{\n\t\t\tawait RunWithOutput(\"Random Tests\\\\TestCases\", \"TestCase-1.exe\", LanguageVersion.CSharp9_0);\n\t\t}\n\n\t\t// Let's limit the roundtrip tests to C# 8.0 for now; because 9.0 is still in preview\n\t\t// and the generated project doesn't build as-is.\n\t\tconst LanguageVersion defaultLanguageVersion = LanguageVersion.CSharp8_0;\n\n\t\tasync Task RunWithTest(string dir, string fileToRoundtrip, string fileToTest, LanguageVersion languageVersion = defaultLanguageVersion, string keyFile = null, bool useOldProjectFormat = false)\n\t\t{\n\t\t\tawait RunInternal(dir, fileToRoundtrip, outputDir => RunTest(outputDir, fileToTest).GetAwaiter().GetResult(), languageVersion, snkFilePath: keyFile, useOldProjectFormat: useOldProjectFormat);\n\t\t}\n\n\t\tasync Task RunWithOutput(string dir, string fileToRoundtrip, LanguageVersion languageVersion = defaultLanguageVersion)\n\t\t{\n\t\t\tstring inputDir = Path.Combine(TestDir, dir);\n\t\t\tawait RunInternal(dir, fileToRoundtrip,\n\t\t\t\toutputDir => Tester.RunAndCompareOutput(fileToRoundtrip, Path.Combine(inputDir, fileToRoundtrip), Path.Combine(outputDir, fileToRoundtrip)).GetAwaiter().GetResult(),\n\t\t\t\tlanguageVersion);\n\t\t}\n\n\t\tasync Task RunOnly(string dir, string fileToRoundtrip, LanguageVersion languageVersion = defaultLanguageVersion)\n\t\t{\n\t\t\tawait RunInternal(dir, fileToRoundtrip, outputDir => { }, languageVersion);\n\t\t}\n\n\t\tasync Task RunInternal(string dir, string fileToRoundtrip, Action<string> testAction, LanguageVersion languageVersion, string snkFilePath = null, bool useOldProjectFormat = false)\n\t\t{\n\t\t\tif (!Directory.Exists(TestDir))\n\t\t\t{\n\t\t\t\tAssert.Ignore($\"Assembly-roundtrip test ignored: test directory '{TestDir}' needs to be checked out separately.\" + Environment.NewLine +\n\t\t\t\t\t\t\t  $\"git clone https://github.com/icsharpcode/ILSpy-tests \\\"{TestDir}\\\"\");\n\t\t\t}\n\t\t\tstring inputDir = Path.Combine(TestDir, dir);\n\t\t\tstring decompiledDir = inputDir + \"-decompiled\";\n\t\t\tstring outputDir = inputDir + \"-output\";\n\t\t\tif (inputDir.EndsWith(\"TestCases\"))\n\t\t\t{\n\t\t\t\t// make sure output dir names are unique so that we don't get trouble due to parallel test execution\n\t\t\t\tdecompiledDir += Path.GetFileNameWithoutExtension(fileToRoundtrip) + \"_\" + languageVersion.ToString();\n\t\t\t\toutputDir += Path.GetFileNameWithoutExtension(fileToRoundtrip) + \"_\" + languageVersion.ToString();\n\t\t\t}\n\t\t\tClearDirectory(decompiledDir);\n\t\t\tClearDirectory(outputDir);\n\t\t\tstring projectFile = null;\n\t\t\tforeach (string file in Directory.EnumerateFiles(inputDir, \"*\", SearchOption.AllDirectories))\n\t\t\t{\n\t\t\t\tif (!file.StartsWith(inputDir + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase))\n\t\t\t\t{\n\t\t\t\t\tAssert.Fail($\"Unexpected file name: {file}\");\n\t\t\t\t}\n\t\t\t\tstring relFile = file.Substring(inputDir.Length + 1);\n\t\t\t\tDirectory.CreateDirectory(Path.Combine(outputDir, Path.GetDirectoryName(relFile)));\n\t\t\t\tif (relFile.Equals(fileToRoundtrip, StringComparison.OrdinalIgnoreCase))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine($\"Decompiling {fileToRoundtrip}...\");\n\t\t\t\t\tStopwatch w = Stopwatch.StartNew();\n\t\t\t\t\tusing (var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read))\n\t\t\t\t\t{\n\t\t\t\t\t\tPEFile module = new PEFile(file, fileStream, PEStreamOptions.PrefetchEntireImage);\n\t\t\t\t\t\tvar resolver = new TestAssemblyResolver(file, inputDir, module.Metadata.DetectTargetFrameworkId());\n\t\t\t\t\t\tresolver.AddSearchDirectory(inputDir);\n\t\t\t\t\t\tresolver.RemoveSearchDirectory(\".\");\n\n\t\t\t\t\t\t// use a fixed GUID so that we can diff the output between different ILSpy runs without spurious changes\n\t\t\t\t\t\tvar projectGuid = Guid.Parse(\"{127C83E4-4587-4CF9-ADCA-799875F3DFE6}\");\n\n\t\t\t\t\t\tvar settings = new DecompilerSettings(languageVersion);\n\t\t\t\t\t\tif (useOldProjectFormat)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsettings.UseSdkStyleProjectFormat = false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar decompiler = new TestProjectDecompiler(projectGuid, resolver, resolver, settings);\n\n\t\t\t\t\t\tif (snkFilePath != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdecompiler.StrongNameKeyFile = Path.Combine(inputDir, snkFilePath);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdecompiler.DecompileProject(module, decompiledDir);\n\t\t\t\t\t\tConsole.WriteLine($\"Decompiled {fileToRoundtrip} in {w.Elapsed.TotalSeconds:f2}\");\n\t\t\t\t\t\tprojectFile = Path.Combine(decompiledDir, module.Name + \".csproj\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tFile.Copy(file, Path.Combine(outputDir, relFile));\n\t\t\t\t}\n\t\t\t}\n\t\t\tAssert.That(projectFile, Is.Not.Null, $\"Could not find {fileToRoundtrip}\");\n\n\t\t\tawait Compile(projectFile, outputDir);\n\t\t\ttestAction(outputDir);\n\t\t}\n\n\t\tstatic void ClearDirectory(string dir)\n\t\t{\n\t\t\tDirectory.CreateDirectory(dir);\n\t\t\tforeach (string subdir in Directory.EnumerateDirectories(dir))\n\t\t\t{\n\t\t\t\tfor (int attempt = 0; ; attempt++)\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tDirectory.Delete(subdir, true);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcatch (IOException)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (attempt >= 10)\n\t\t\t\t\t\t\tthrow;\n\t\t\t\t\t\tThread.Sleep(100);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tforeach (string file in Directory.EnumerateFiles(dir))\n\t\t\t{\n\t\t\t\tFile.Delete(file);\n\t\t\t}\n\t\t}\n\n\t\tstatic async Task Compile(string projectFile, string outputDir)\n\t\t{\n\t\t\tRegex errorRegex = new Regex(@\"^[\\w\\d.\\\\-]+\\(\\d+,\\d+\\):\");\n\t\t\tstring suffix = $\" [{projectFile}]\";\n\n\t\t\tvar command = Cli.Wrap(await Tester.FindMSBuild())\n\t\t\t\t.WithArguments($\"/nologo /v:minimal /restore /p:OutputPath=\\\"{outputDir}\\\" \\\"{projectFile}\\\"\")\n\t\t\t\t.WithValidation(CommandResultValidation.None)\n\t\t\t\t.WithStandardOutputPipe(PipeTarget.ToDelegate(PrintLine));\n\t\t\tConsole.WriteLine($\"\\\"{command.TargetFilePath}\\\" {command.Arguments}\");\n\t\t\tvar result = await command.ExecuteAsync().ConfigureAwait(false);\n\t\t\tif (result.ExitCode != 0)\n\t\t\t\tthrow new CompilationFailedException($\"Compilation of {Path.GetFileName(projectFile)} failed\");\n\n\t\t\tvoid PrintLine(string line)\n\t\t\t{\n\t\t\t\tif (line.EndsWith(suffix, StringComparison.OrdinalIgnoreCase))\n\t\t\t\t{\n\t\t\t\t\tline = line.Substring(0, line.Length - suffix.Length);\n\t\t\t\t}\n\t\t\t\tMatch m = errorRegex.Match(line);\n\t\t\t\tif (m.Success)\n\t\t\t\t{\n\t\t\t\t\t// Make path absolute so that it gets hyperlinked\n\t\t\t\t\tline = Path.GetDirectoryName(projectFile) + Path.DirectorySeparatorChar + line;\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(line);\n\t\t\t}\n\t\t}\n\n\t\tstatic async Task RunTest(string outputDir, string fileToTest)\n\t\t{\n\t\t\tvar command = Cli.Wrap(nunit)\n\t\t\t\t.WithWorkingDirectory(outputDir)\n\t\t\t\t.WithArguments($\"\\\"{fileToTest}\\\"\")\n\t\t\t\t.WithValidation(CommandResultValidation.None)\n\t\t\t\t.WithStandardOutputPipe(PipeTarget.ToDelegate(Console.WriteLine));\n\t\t\tConsole.WriteLine($\"\\\"{command.TargetFilePath}\\\" {command.Arguments}\");\n\t\t\tvar result = await command.ExecuteAsync().ConfigureAwait(false);\n\t\t\tif (result.ExitCode != 0)\n\t\t\t\tthrow new TestRunFailedException($\"Test execution of {Path.GetFileName(fileToTest)} failed\");\n\t\t}\n\n\t\tclass TestProjectDecompiler : WholeProjectDecompiler\n\t\t{\n\t\t\tpublic TestProjectDecompiler(Guid projectGuid, IAssemblyResolver resolver, AssemblyReferenceClassifier assemblyReferenceClassifier, DecompilerSettings settings)\n\t\t\t\t: base(settings, projectGuid, resolver, null, assemblyReferenceClassifier, debugInfoProvider: null)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tclass CompilationFailedException : Exception\n\t\t{\n\t\t\tpublic CompilationFailedException(string message) : base(message)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tclass TestRunFailedException : Exception\n\t\t{\n\t\t\tpublic TestRunFailedException(string message) : base(message)\n\t\t\t{\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/Semantics/ConversionTests.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\n\nusing ICSharpCode.Decompiler.CSharp.Resolver;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.Tests.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests.Semantics\n{\n\t// assign short names to the fake reflection types\n\tusing C = Conversion;\n\tusing dynamic = ConversionTest.Dynamic;\n\tusing nint = ConversionTest.NInt;\n\tusing nuint = ConversionTest.NUInt;\n\n\t[TestFixture, Parallelizable(ParallelScope.All)]\n\tpublic unsafe class ConversionTest\n\t{\n\t\t/// <summary>\n\t\t/// A reflection class used to represent <c>null</c>.\n\t\t/// </summary>\n\t\tpublic sealed class Null { }\n\n\t\t/// <summary>\n\t\t/// A reflection class used to represent <c>dynamic</c>.\n\t\t/// </summary>\n\t\tpublic sealed class Dynamic { }\n\n\t\t/// <summary>\n\t\t/// A reflection class used to represent <c>nint</c>.\n\t\t/// </summary>\n\t\tpublic sealed class NInt { }\n\n\t\t/// <summary>\n\t\t/// A reflection class used to represent <c>nuint</c>.\n\t\t/// </summary>\n\t\tpublic sealed class NUInt { }\n\n\t\tCSharpConversions conversions;\n\t\tICompilation compilation;\n\n\t\t[OneTimeSetUp]\n\t\tpublic void SetUp()\n\t\t{\n\t\t\tcompilation = new SimpleCompilation(TypeSystemLoaderTests.TestAssembly,\n\t\t\t\tTypeSystemLoaderTests.Mscorlib,\n\t\t\t\tTypeSystemLoaderTests.SystemCore);\n\t\t\tconversions = new CSharpConversions(compilation);\n\t\t}\n\n\t\tpublic class ReplaceSpecialTypesVisitor : TypeVisitor\n\t\t{\n\t\t\tpublic override IType VisitTypeDefinition(ITypeDefinition type)\n\t\t\t{\n\t\t\t\tswitch (type.FullName)\n\t\t\t\t{\n\t\t\t\t\tcase \"ICSharpCode.Decompiler.Tests.Semantics.ConversionTest.Dynamic\":\n\t\t\t\t\t\treturn SpecialType.Dynamic;\n\t\t\t\t\tcase \"ICSharpCode.Decompiler.Tests.Semantics.ConversionTest.Null\":\n\t\t\t\t\t\treturn SpecialType.NullType;\n\t\t\t\t\tcase \"ICSharpCode.Decompiler.Tests.Semantics.ConversionTest.NInt\":\n\t\t\t\t\t\treturn SpecialType.NInt;\n\t\t\t\t\tcase \"ICSharpCode.Decompiler.Tests.Semantics.ConversionTest.NUInt\":\n\t\t\t\t\t\treturn SpecialType.NUInt;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn base.VisitTypeDefinition(type);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tConversion ImplicitConversion(Type from, Type to)\n\t\t{\n\t\t\tIType from2 = compilation.FindType(from).AcceptVisitor(new ReplaceSpecialTypesVisitor());\n\t\t\tIType to2 = compilation.FindType(to).AcceptVisitor(new ReplaceSpecialTypesVisitor());\n\t\t\treturn conversions.ImplicitConversion(from2, to2);\n\t\t}\n\n\t\tConversion ExplicitConversion(Type from, Type to)\n\t\t{\n\t\t\tIType from2 = compilation.FindType(from).AcceptVisitor(new ReplaceSpecialTypesVisitor());\n\t\t\tIType to2 = compilation.FindType(to).AcceptVisitor(new ReplaceSpecialTypesVisitor());\n\t\t\treturn conversions.ExplicitConversion(from2, to2);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void IdentityConversions()\n\t\t{\n\t\t\tAssert.That(ImplicitConversion(typeof(char), typeof(char)), Is.EqualTo(C.IdentityConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(string), typeof(string)), Is.EqualTo(C.IdentityConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(object), typeof(object)), Is.EqualTo(C.IdentityConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(bool), typeof(char)), Is.EqualTo(C.None));\n\n\t\t\tAssert.That(conversions.ImplicitConversion(SpecialType.Dynamic, SpecialType.Dynamic), Is.EqualTo(C.IdentityConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(SpecialType.UnknownType, SpecialType.UnknownType), Is.EqualTo(C.IdentityConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(SpecialType.NullType, SpecialType.NullType), Is.EqualTo(C.IdentityConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void DynamicIdentityConversions()\n\t\t{\n\t\t\tAssert.That(ImplicitConversion(typeof(object), typeof(dynamic)), Is.EqualTo(C.IdentityConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(dynamic), typeof(object)), Is.EqualTo(C.IdentityConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ComplexDynamicIdentityConversions()\n\t\t{\n\t\t\tAssert.That(ImplicitConversion(typeof(List<object>), typeof(List<dynamic>)), Is.EqualTo(C.IdentityConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(List<dynamic>), typeof(List<object>)), Is.EqualTo(C.IdentityConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(List<string>), typeof(List<dynamic>)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(List<dynamic>), typeof(List<string>)), Is.EqualTo(C.None));\n\n\t\t\tAssert.That(ImplicitConversion(typeof(List<List<dynamic>[]>), typeof(List<List<object>[]>)), Is.EqualTo(C.IdentityConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(List<List<object>[]>), typeof(List<List<dynamic>[]>)), Is.EqualTo(C.IdentityConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(List<List<object>[,]>), typeof(List<List<dynamic>[]>)), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TupleIdentityConversions()\n\t\t{\n\t\t\tvar intType = compilation.FindType(typeof(int));\n\t\t\tvar stringType = compilation.FindType(typeof(string));\n\t\t\tAssert.That(conversions.ImplicitConversion(\n\t\t\t\tnew TupleType(compilation, ImmutableArray.Create(intType, stringType), ImmutableArray.Create(\"a\", \"b\")),\n\t\t\t\tnew TupleType(compilation, ImmutableArray.Create(intType, stringType), ImmutableArray.Create(\"a\", \"c\"))), Is.EqualTo(C.IdentityConversion));\n\n\t\t\tAssert.That(conversions.ImplicitConversion(\n\t\t\t\tnew TupleType(compilation, ImmutableArray.Create(intType, stringType), ImmutableArray.Create(\"a\", \"b\")),\n\t\t\t\tnew TupleType(compilation, ImmutableArray.Create(stringType, intType), ImmutableArray.Create(\"a\", \"b\"))), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TupleConversions()\n\t\t{\n\t\t\tAssert.That(\n\t\t\t\tImplicitConversion(typeof((int, string)), typeof((long, object))), Is.EqualTo(C.TupleConversion(ImmutableArray.Create(C.ImplicitNumericConversion, C.ImplicitReferenceConversion))));\n\n\t\t\tAssert.That(\n\t\t\t\tImplicitConversion(typeof(ValueTuple<float>), typeof(ValueTuple<double>)), Is.EqualTo(C.TupleConversion(ImmutableArray.Create(C.ImplicitNumericConversion))));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void PrimitiveConversions()\n\t\t{\n\t\t\tAssert.That(ImplicitConversion(typeof(char), typeof(ushort)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(byte), typeof(char)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(int), typeof(long)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(long), typeof(int)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(int), typeof(float)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(bool), typeof(float)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(float), typeof(double)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(float), typeof(decimal)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(char), typeof(long)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(uint), typeof(long)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void EnumerationConversion()\n\t\t{\n\t\t\tResolveResult zero = new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), 0);\n\t\t\tResolveResult one = new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), 1);\n\t\t\tC implicitEnumerationConversion = C.EnumerationConversion(true, false);\n\t\t\tAssert.That(conversions.ImplicitConversion(zero, compilation.FindType(typeof(StringComparison))), Is.EqualTo(implicitEnumerationConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(one, compilation.FindType(typeof(StringComparison))), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NullableConversions()\n\t\t{\n\t\t\tAssert.That(ImplicitConversion(typeof(char), typeof(ushort?)), Is.EqualTo(C.ImplicitLiftedNumericConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(byte), typeof(char?)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(int), typeof(long?)), Is.EqualTo(C.ImplicitLiftedNumericConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(long), typeof(int?)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(int), typeof(float?)), Is.EqualTo(C.ImplicitLiftedNumericConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(bool), typeof(float?)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(float), typeof(double?)), Is.EqualTo(C.ImplicitLiftedNumericConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(float), typeof(decimal?)), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NullableConversions2()\n\t\t{\n\t\t\tAssert.That(ImplicitConversion(typeof(char?), typeof(ushort?)), Is.EqualTo(C.ImplicitLiftedNumericConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(byte?), typeof(char?)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(int?), typeof(long?)), Is.EqualTo(C.ImplicitLiftedNumericConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(long?), typeof(int?)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(int?), typeof(float?)), Is.EqualTo(C.ImplicitLiftedNumericConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(bool?), typeof(float?)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(float?), typeof(double?)), Is.EqualTo(C.ImplicitLiftedNumericConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(float?), typeof(decimal?)), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NullableEnumerationConversion()\n\t\t{\n\t\t\tResolveResult zero = new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), 0);\n\t\t\tResolveResult one = new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), 1);\n\t\t\tC implicitEnumerationConversion = C.EnumerationConversion(true, true);\n\t\t\tAssert.That(conversions.ImplicitConversion(zero, compilation.FindType(typeof(StringComparison?))), Is.EqualTo(implicitEnumerationConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(one, compilation.FindType(typeof(StringComparison?))), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NullLiteralConversions()\n\t\t{\n\t\t\tAssert.That(ImplicitConversion(typeof(Null), typeof(int?)), Is.EqualTo(C.NullLiteralConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(Null), typeof(char?)), Is.EqualTo(C.NullLiteralConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(Null), typeof(int)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(Null), typeof(object)), Is.EqualTo(C.NullLiteralConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(Null), typeof(dynamic)), Is.EqualTo(C.NullLiteralConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(Null), typeof(string)), Is.EqualTo(C.NullLiteralConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(Null), typeof(int[])), Is.EqualTo(C.NullLiteralConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void SimpleReferenceConversions()\n\t\t{\n\t\t\tAssert.That(ImplicitConversion(typeof(string), typeof(object)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(BitArray), typeof(ICollection)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(IList), typeof(IEnumerable)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(object), typeof(string)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(ICollection), typeof(BitArray)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(IEnumerable), typeof(IList)), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ConversionToDynamic()\n\t\t{\n\t\t\tAssert.That(ImplicitConversion(typeof(string), typeof(dynamic)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(int), typeof(dynamic)), Is.EqualTo(C.BoxingConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ConversionFromDynamic()\n\t\t{\n\t\t\t// There is no conversion from the type 'dynamic' to other types (except the identity conversion to object).\n\t\t\t// Such conversions only exists from dynamic expression.\n\t\t\t// This is an important distinction for type inference (see TypeInferenceTests.IEnumerableCovarianceWithDynamic)\n\t\t\tAssert.That(ImplicitConversion(typeof(dynamic), typeof(string)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(dynamic), typeof(int)), Is.EqualTo(C.None));\n\n\t\t\tvar dynamicRR = new ResolveResult(SpecialType.Dynamic);\n\t\t\tAssert.That(conversions.ImplicitConversion(dynamicRR, compilation.FindType(typeof(string))), Is.EqualTo(C.ImplicitDynamicConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(dynamicRR, compilation.FindType(typeof(int))), Is.EqualTo(C.ImplicitDynamicConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParameterizedTypeConversions()\n\t\t{\n\t\t\tAssert.That(ImplicitConversion(typeof(List<string>), typeof(ICollection<string>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(IList<string>), typeof(ICollection<string>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(List<string>), typeof(ICollection<object>)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(IList<string>), typeof(ICollection<object>)), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ArrayConversions()\n\t\t{\n\t\t\tAssert.That(ImplicitConversion(typeof(string[]), typeof(object[])), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(string[,]), typeof(object[,])), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(string[]), typeof(object[,])), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(object[]), typeof(string[])), Is.EqualTo(C.None));\n\n\t\t\tAssert.That(ImplicitConversion(typeof(string[]), typeof(IList<string>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(string[,]), typeof(IList<string>)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(string[]), typeof(IList<object>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\n\t\t\tAssert.That(ImplicitConversion(typeof(string[]), typeof(Array)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(string[]), typeof(ICloneable)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(Array), typeof(string[])), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(object), typeof(object[])), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void VarianceConversions()\n\t\t{\n\t\t\tAssert.That(ImplicitConversion(typeof(List<string>), typeof(IEnumerable<object>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(List<object>), typeof(IEnumerable<string>)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(IEnumerable<string>), typeof(IEnumerable<object>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(ICollection<string>), typeof(ICollection<object>)), Is.EqualTo(C.None));\n\n\t\t\tAssert.That(ImplicitConversion(typeof(Comparer<object>), typeof(IComparer<string>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(Comparer<object>), typeof(IComparer<Array>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(Comparer<object>), typeof(Comparer<string>)), Is.EqualTo(C.None));\n\n\t\t\tAssert.That(ImplicitConversion(typeof(List<object>), typeof(IEnumerable<string>)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(IEnumerable<string>), typeof(IEnumerable<object>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\n\t\t\tAssert.That(ImplicitConversion(typeof(Func<ICollection, ICollection>), typeof(Func<IList, IEnumerable>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(Func<IEnumerable, IList>), typeof(Func<ICollection, ICollection>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(Func<ICollection, ICollection>), typeof(Func<IEnumerable, IList>)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(Func<IList, IEnumerable>), typeof(Func<ICollection, ICollection>)), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ImplicitPointerConversion()\n\t\t{\n\t\t\tAssert.That(ImplicitConversion(typeof(Null), typeof(int*)), Is.EqualTo(C.ImplicitPointerConversion));\n\t\t\tAssert.That(ImplicitConversion(typeof(int*), typeof(void*)), Is.EqualTo(C.ImplicitPointerConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NoConversionFromPointerTypeToObject()\n\t\t{\n\t\t\tAssert.That(ImplicitConversion(typeof(int*), typeof(object)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ImplicitConversion(typeof(int*), typeof(dynamic)), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ConversionToNInt()\n\t\t{\n\t\t\t// Test based on the table in https://github.com/dotnet/csharplang/blob/master/proposals/native-integers.md\n\t\t\tAssert.That(ExplicitConversion(typeof(object), typeof(nint)), Is.EqualTo(C.UnboxingConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(void*), typeof(nint)), Is.EqualTo(C.ExplicitPointerConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(sbyte), typeof(nint)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(byte), typeof(nint)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(short), typeof(nint)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(ushort), typeof(nint)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(int), typeof(nint)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(uint), typeof(nint)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(long), typeof(nint)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(ulong), typeof(nint)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(char), typeof(nint)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(float), typeof(nint)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(double), typeof(nint)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(decimal), typeof(nint)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IntPtr), typeof(nint)), Is.EqualTo(C.IdentityConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(UIntPtr), typeof(nint)), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ConversionToNUInt()\n\t\t{\n\t\t\t// Test based on the table in https://github.com/dotnet/csharplang/blob/master/proposals/native-integers.md\n\t\t\tAssert.That(ExplicitConversion(typeof(object), typeof(nuint)), Is.EqualTo(C.UnboxingConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(void*), typeof(nuint)), Is.EqualTo(C.ExplicitPointerConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(sbyte), typeof(nuint)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(byte), typeof(nuint)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(short), typeof(nuint)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(ushort), typeof(nuint)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(int), typeof(nuint)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(uint), typeof(nuint)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(long), typeof(nuint)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(ulong), typeof(nuint)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(char), typeof(nuint)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(float), typeof(nuint)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(double), typeof(nuint)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(decimal), typeof(nuint)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IntPtr), typeof(nuint)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ExplicitConversion(typeof(UIntPtr), typeof(nuint)), Is.EqualTo(C.IdentityConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ConversionFromNInt()\n\t\t{\n\t\t\t// Test based on the table in https://github.com/dotnet/csharplang/blob/master/proposals/native-integers.md\n\t\t\tAssert.That(ExplicitConversion(typeof(nint), typeof(object)), Is.EqualTo(C.BoxingConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nint), typeof(void*)), Is.EqualTo(C.ExplicitPointerConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nint), typeof(nuint)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nint), typeof(sbyte)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nint), typeof(byte)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nint), typeof(short)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nint), typeof(ushort)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nint), typeof(int)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nint), typeof(uint)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nint), typeof(long)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nint), typeof(ulong)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nint), typeof(char)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nint), typeof(float)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nint), typeof(double)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nint), typeof(decimal)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nint), typeof(IntPtr)), Is.EqualTo(C.IdentityConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nint), typeof(UIntPtr)), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ConversionFromNUInt()\n\t\t{\n\t\t\t// Test based on the table in https://github.com/dotnet/csharplang/blob/master/proposals/native-integers.md\n\t\t\tAssert.That(ExplicitConversion(typeof(nuint), typeof(object)), Is.EqualTo(C.BoxingConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nuint), typeof(void*)), Is.EqualTo(C.ExplicitPointerConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nuint), typeof(nint)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nuint), typeof(sbyte)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nuint), typeof(byte)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nuint), typeof(short)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nuint), typeof(ushort)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nuint), typeof(int)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nuint), typeof(uint)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nuint), typeof(long)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nuint), typeof(ulong)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nuint), typeof(char)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nuint), typeof(float)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nuint), typeof(double)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nuint), typeof(decimal)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nuint), typeof(IntPtr)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ExplicitConversion(typeof(nuint), typeof(UIntPtr)), Is.EqualTo(C.IdentityConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NIntEnumConversion()\n\t\t{\n\t\t\tvar explicitEnumConversion = C.EnumerationConversion(isImplicit: false, isLifted: false);\n\t\t\tAssert.That(ExplicitConversion(typeof(nint), typeof(StringComparison)), Is.EqualTo(explicitEnumConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(nuint), typeof(StringComparison)), Is.EqualTo(explicitEnumConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(StringComparison), typeof(nint)), Is.EqualTo(explicitEnumConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(StringComparison), typeof(nuint)), Is.EqualTo(explicitEnumConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void IntegerLiteralToNIntConversions()\n\t\t{\n\t\t\tAssert.That(IntegerLiteralConversion(0, typeof(nint)));\n\t\t\tAssert.That(IntegerLiteralConversion(-1, typeof(nint)));\n\t\t\tAssert.That(!IntegerLiteralConversion(uint.MaxValue, typeof(nint)));\n\t\t\tAssert.That(!IntegerLiteralConversion(long.MaxValue, typeof(nint)));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void IntegerLiteralToNUIntConversions()\n\t\t{\n\t\t\tAssert.That(IntegerLiteralConversion(0, typeof(nuint)));\n\t\t\tAssert.That(!IntegerLiteralConversion(-1, typeof(nuint)));\n\t\t\tAssert.That(IntegerLiteralConversion(uint.MaxValue, typeof(nuint)));\n\t\t\tAssert.That(!IntegerLiteralConversion(long.MaxValue, typeof(nuint)));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UnconstrainedTypeParameter()\n\t\t{\n\t\t\tITypeParameter t = new DefaultTypeParameter(compilation, SymbolKind.TypeDefinition, 0, \"T\");\n\t\t\tITypeParameter t2 = new DefaultTypeParameter(compilation, SymbolKind.TypeDefinition, 1, \"T2\");\n\t\t\tITypeParameter tm = new DefaultTypeParameter(compilation, SymbolKind.Method, 0, \"TM\");\n\n\t\t\tAssert.That(conversions.ImplicitConversion(SpecialType.NullType, t), Is.EqualTo(C.None));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, compilation.FindType(KnownTypeCode.Object)), Is.EqualTo(C.BoxingConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, SpecialType.Dynamic), Is.EqualTo(C.BoxingConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(ValueType))), Is.EqualTo(C.None));\n\n\t\t\tAssert.That(conversions.ImplicitConversion(t, t), Is.EqualTo(C.IdentityConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(t2, t), Is.EqualTo(C.None));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, t2), Is.EqualTo(C.None));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, tm), Is.EqualTo(C.None));\n\t\t\tAssert.That(conversions.ImplicitConversion(tm, t), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TypeParameterWithReferenceTypeConstraint()\n\t\t{\n\t\t\tITypeParameter t = new DefaultTypeParameter(compilation, SymbolKind.TypeDefinition, 0, \"T\", hasReferenceTypeConstraint: true);\n\n\t\t\tAssert.That(conversions.ImplicitConversion(SpecialType.NullType, t), Is.EqualTo(C.NullLiteralConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, compilation.FindType(KnownTypeCode.Object)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, SpecialType.Dynamic), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(ValueType))), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TypeParameterWithValueTypeConstraint()\n\t\t{\n\t\t\tITypeParameter t = new DefaultTypeParameter(compilation, SymbolKind.TypeDefinition, 0, \"T\", hasValueTypeConstraint: true);\n\n\t\t\tAssert.That(conversions.ImplicitConversion(SpecialType.NullType, t), Is.EqualTo(C.None));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, compilation.FindType(KnownTypeCode.Object)), Is.EqualTo(C.BoxingConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, SpecialType.Dynamic), Is.EqualTo(C.BoxingConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(ValueType))), Is.EqualTo(C.BoxingConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TypeParameterWithClassConstraint()\n\t\t{\n\t\t\tITypeParameter t = new DefaultTypeParameter(compilation, SymbolKind.TypeDefinition, 0, \"T\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tconstraints: new[] { compilation.FindType(typeof(StringComparer)) });\n\n\t\t\tAssert.That(conversions.ImplicitConversion(SpecialType.NullType, t), Is.EqualTo(C.NullLiteralConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, compilation.FindType(KnownTypeCode.Object)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, SpecialType.Dynamic), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(ValueType))), Is.EqualTo(C.None));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(StringComparer))), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(IComparer))), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(IComparer<int>))), Is.EqualTo(C.None));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(IComparer<string>))), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TypeParameterWithInterfaceConstraint()\n\t\t{\n\t\t\tITypeParameter t = new DefaultTypeParameter(compilation, SymbolKind.TypeDefinition, 0, \"T\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tconstraints: new[] { compilation.FindType(typeof(IList)) });\n\n\t\t\tAssert.That(conversions.ImplicitConversion(SpecialType.NullType, t), Is.EqualTo(C.None));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, compilation.FindType(KnownTypeCode.Object)), Is.EqualTo(C.BoxingConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, SpecialType.Dynamic), Is.EqualTo(C.BoxingConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(ValueType))), Is.EqualTo(C.None));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(IList))), Is.EqualTo(C.BoxingConversion));\n\t\t\tAssert.That(conversions.ImplicitConversion(t, compilation.FindType(typeof(IEnumerable))), Is.EqualTo(C.BoxingConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion()\n\t\t{\n\t\t\tConversion c = ImplicitConversion(typeof(DateTime), typeof(DateTimeOffset));\n\t\t\tAssert.That(c.IsImplicit && c.IsUserDefined);\n\t\t\tAssert.That(c.Method.FullName, Is.EqualTo(\"System.DateTimeOffset.op_Implicit\"));\n\n\t\t\tAssert.That(ImplicitConversion(typeof(DateTimeOffset), typeof(DateTime)), Is.EqualTo(C.None));\n\n\t\t\tITypeDefinition classImplementingIDisposable = compilation.FindType(typeof(ClassImplementingIDisposable)).GetDefinition();\n\t\t\tITypeDefinition genericStructWithIDisposableConstraintAndImplicitConversion = compilation.FindType(typeof(GenericStructWithIDisposableConstraintAndImplicitConversion<>)).GetDefinition();\n\t\t\tIType genericStructIDisposableInstance = new ParameterizedType(genericStructWithIDisposableConstraintAndImplicitConversion, ImmutableArray.Create(compilation.FindType(typeof(IDisposable))));\n\n\t\t\t// C => S<I>\n\t\t\tConversion c2 = conversions.ImplicitConversion(classImplementingIDisposable, genericStructIDisposableInstance);\n\t\t\tAssert.That(c2.IsImplicit && c2.IsUserDefined);\n\t\t\tAssert.That(c2.Method.FullName, Is.EqualTo(\"ICSharpCode.Decompiler.Tests.TypeSystem.GenericStructWithIDisposableConstraintAndImplicitConversion.op_Implicit\"));\n\n\t\t\tAssert.That(conversions.ImplicitConversion(genericStructIDisposableInstance, classImplementingIDisposable), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitNullableConversion()\n\t\t{\n\t\t\t// User-defined conversion followed by nullable conversion\n\t\t\tConversion c = ImplicitConversion(typeof(DateTime), typeof(DateTimeOffset?));\n\t\t\tAssert.That(c.IsValid && c.IsUserDefined);\n\t\t\tAssert.That(!c.IsLifted);\n\t\t\t// Lifted user-defined conversion\n\t\t\tc = ImplicitConversion(typeof(DateTime?), typeof(DateTimeOffset?));\n\t\t\tAssert.That(c.IsValid && c.IsUserDefined && c.IsLifted);\n\t\t\t// User-defined conversion doesn't drop the nullability\n\t\t\tc = ImplicitConversion(typeof(DateTime?), typeof(DateTimeOffset));\n\t\t\tAssert.That(!c.IsValid);\n\t\t}\n\n\t\tbool IntegerLiteralConversion(object value, Type to)\n\t\t{\n\t\t\tIType fromType = compilation.FindType(value.GetType()).AcceptVisitor(new ReplaceSpecialTypesVisitor());\n\t\t\tConstantResolveResult crr = new ConstantResolveResult(fromType, value);\n\t\t\tIType to2 = compilation.FindType(to).AcceptVisitor(new ReplaceSpecialTypesVisitor());\n\t\t\treturn conversions.ImplicitConversion(crr, to2).IsValid;\n\t\t}\n\n\t\t[Test]\n\t\tpublic void IntegerLiteralToEnumConversions()\n\t\t{\n\t\t\tAssert.That(IntegerLiteralConversion(0, typeof(LoaderOptimization)));\n\t\t\tAssert.That(IntegerLiteralConversion(0L, typeof(LoaderOptimization)));\n\t\t\tAssert.That(IntegerLiteralConversion(0, typeof(LoaderOptimization?)));\n\t\t\tAssert.That(!IntegerLiteralConversion(0, typeof(string)));\n\t\t\tAssert.That(!IntegerLiteralConversion(1, typeof(LoaderOptimization)));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ImplicitConstantExpressionConversion()\n\t\t{\n\t\t\tAssert.That(IntegerLiteralConversion(0, typeof(int)));\n\t\t\tAssert.That(IntegerLiteralConversion(0, typeof(ushort)));\n\t\t\tAssert.That(IntegerLiteralConversion(0, typeof(sbyte)));\n\n\t\t\tAssert.That(IntegerLiteralConversion(-1, typeof(int)));\n\t\t\tAssert.That(!IntegerLiteralConversion(-1, typeof(ushort)));\n\t\t\tAssert.That(IntegerLiteralConversion(-1, typeof(sbyte)));\n\n\t\t\tAssert.That(IntegerLiteralConversion(200, typeof(int)));\n\t\t\tAssert.That(IntegerLiteralConversion(200, typeof(ushort)));\n\t\t\tAssert.That(!IntegerLiteralConversion(200, typeof(sbyte)));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ImplicitLongConstantExpressionConversion()\n\t\t{\n\t\t\tAssert.That(!IntegerLiteralConversion(0L, typeof(int)));\n\t\t\tAssert.That(!IntegerLiteralConversion(0L, typeof(short)));\n\t\t\tAssert.That(IntegerLiteralConversion(0L, typeof(long)));\n\t\t\tAssert.That(IntegerLiteralConversion(0L, typeof(ulong)));\n\n\t\t\tAssert.That(IntegerLiteralConversion(-1L, typeof(long)));\n\t\t\tAssert.That(!IntegerLiteralConversion(-1L, typeof(ulong)));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ImplicitConstantExpressionConversionToNullable()\n\t\t{\n\t\t\tAssert.That(IntegerLiteralConversion(0, typeof(uint?)));\n\t\t\tAssert.That(IntegerLiteralConversion(0, typeof(short?)));\n\t\t\tAssert.That(IntegerLiteralConversion(0, typeof(byte?)));\n\n\t\t\tAssert.That(!IntegerLiteralConversion(-1, typeof(uint?)));\n\t\t\tAssert.That(IntegerLiteralConversion(-1, typeof(short?)));\n\t\t\tAssert.That(!IntegerLiteralConversion(-1, typeof(byte?)));\n\n\t\t\tAssert.That(IntegerLiteralConversion(200, typeof(uint?)));\n\t\t\tAssert.That(IntegerLiteralConversion(200, typeof(short?)));\n\t\t\tAssert.That(IntegerLiteralConversion(200, typeof(byte?)));\n\n\t\t\tAssert.That(!IntegerLiteralConversion(0L, typeof(uint?)));\n\t\t\tAssert.That(IntegerLiteralConversion(0L, typeof(long?)));\n\t\t\tAssert.That(IntegerLiteralConversion(0L, typeof(ulong?)));\n\n\t\t\tAssert.That(IntegerLiteralConversion(-1L, typeof(long?)));\n\t\t\tAssert.That(!IntegerLiteralConversion(-1L, typeof(ulong?)));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ImplicitConstantExpressionConversionNumberInterfaces()\n\t\t{\n\t\t\tAssert.That(IntegerLiteralConversion(0, typeof(IFormattable)));\n\t\t\tAssert.That(IntegerLiteralConversion(0, typeof(IComparable<int>)));\n\t\t\tAssert.That(!IntegerLiteralConversion(0, typeof(IComparable<short>)));\n\t\t\tAssert.That(!IntegerLiteralConversion(0, typeof(IComparable<long>)));\n\t\t}\n\n\t\tint BetterConversion(Type s, Type t1, Type t2)\n\t\t{\n\t\t\tIType sType = compilation.FindType(s).AcceptVisitor(new ReplaceSpecialTypesVisitor());\n\t\t\tIType t1Type = compilation.FindType(t1).AcceptVisitor(new ReplaceSpecialTypesVisitor());\n\t\t\tIType t2Type = compilation.FindType(t2).AcceptVisitor(new ReplaceSpecialTypesVisitor());\n\t\t\treturn conversions.BetterConversion(sType, t1Type, t2Type);\n\t\t}\n\n\t\tint BetterConversion(object value, Type t1, Type t2)\n\t\t{\n\t\t\tIType fromType = compilation.FindType(value.GetType()).AcceptVisitor(new ReplaceSpecialTypesVisitor());\n\t\t\tConstantResolveResult crr = new ConstantResolveResult(fromType, value);\n\t\t\tIType t1Type = compilation.FindType(t1).AcceptVisitor(new ReplaceSpecialTypesVisitor());\n\t\t\tIType t2Type = compilation.FindType(t2).AcceptVisitor(new ReplaceSpecialTypesVisitor());\n\t\t\treturn conversions.BetterConversion(crr, t1Type, t2Type);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void BetterConversion()\n\t\t{\n\t\t\tAssert.That(BetterConversion(typeof(string), typeof(string), typeof(object)), Is.EqualTo(1));\n\t\t\tAssert.That(BetterConversion(typeof(string), typeof(object), typeof(IComparable<string>)), Is.EqualTo(2));\n\t\t\tAssert.That(BetterConversion(typeof(string), typeof(IEnumerable<char>), typeof(IComparable<string>)), Is.EqualTo(0));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void BetterPrimitiveConversion()\n\t\t{\n\t\t\tAssert.That(BetterConversion(typeof(short), typeof(int), typeof(long)), Is.EqualTo(1));\n\t\t\tAssert.That(BetterConversion(typeof(short), typeof(int), typeof(uint)), Is.EqualTo(1));\n\t\t\tAssert.That(BetterConversion(typeof(ushort), typeof(uint), typeof(int)), Is.EqualTo(2));\n\t\t\tAssert.That(BetterConversion(typeof(char), typeof(short), typeof(int)), Is.EqualTo(1));\n\t\t\tAssert.That(BetterConversion(typeof(char), typeof(ushort), typeof(int)), Is.EqualTo(1));\n\t\t\tAssert.That(BetterConversion(typeof(sbyte), typeof(long), typeof(ulong)), Is.EqualTo(1));\n\t\t\tAssert.That(BetterConversion(typeof(byte), typeof(ushort), typeof(short)), Is.EqualTo(2));\n\n\t\t\tAssert.That(BetterConversion(1, typeof(sbyte), typeof(byte)), Is.EqualTo(1));\n\t\t\tAssert.That(BetterConversion(1, typeof(ushort), typeof(sbyte)), Is.EqualTo(2));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void BetterNullableConversion()\n\t\t{\n\t\t\tAssert.That(BetterConversion(typeof(byte), typeof(int), typeof(uint?)), Is.EqualTo(0));\n\t\t\tAssert.That(BetterConversion(typeof(byte?), typeof(int?), typeof(uint?)), Is.EqualTo(0));\n\t\t\tAssert.That(BetterConversion(typeof(byte), typeof(ushort?), typeof(uint?)), Is.EqualTo(1));\n\t\t\tAssert.That(BetterConversion(typeof(byte?), typeof(ulong?), typeof(uint?)), Is.EqualTo(2));\n\t\t\tAssert.That(BetterConversion(typeof(byte), typeof(ushort?), typeof(uint)), Is.EqualTo(0));\n\t\t\tAssert.That(BetterConversion(typeof(byte), typeof(ushort?), typeof(int)), Is.EqualTo(0));\n\t\t\tAssert.That(BetterConversion(typeof(byte), typeof(ulong?), typeof(uint)), Is.EqualTo(2));\n\t\t\tAssert.That(BetterConversion(typeof(byte), typeof(ulong?), typeof(int)), Is.EqualTo(0));\n\t\t\tAssert.That(BetterConversion(typeof(ushort?), typeof(long?), typeof(int?)), Is.EqualTo(2));\n\t\t\tAssert.That(BetterConversion(typeof(sbyte), typeof(int?), typeof(uint?)), Is.EqualTo(0));\n\t\t}\n\n\t\t/* TODO: we should probably revive these tests somehow\n\t\t[Test]\n\t\tpublic void ExpansiveInheritance()\n\t\t{\n\t\t\tvar a = new DefaultUnresolvedTypeDefinition(string.Empty, \"A\");\n\t\t\tvar b = new DefaultUnresolvedTypeDefinition(string.Empty, \"B\");\n\t\t\t// interface A<in U>\n\t\t\ta.Kind = TypeKind.Interface;\n\t\t\ta.TypeParameters.Add(new DefaultUnresolvedTypeParameter(SymbolKind.TypeDefinition, 0, \"U\") { Variance = VarianceModifier.Contravariant });\n\t\t\t// interface B<X> : A<A<B<X>>> { }\n\t\t\tb.TypeParameters.Add(new DefaultUnresolvedTypeParameter(SymbolKind.TypeDefinition, 0, \"X\"));\n\t\t\tb.BaseTypes.Add(new ParameterizedTypeReference(\n\t\t\t\ta, new[] { new ParameterizedTypeReference(\n\t\t\t\t\ta, new [] { new ParameterizedTypeReference(\n\t\t\t\t\t\tb, new [] { new TypeParameterReference(SymbolKind.TypeDefinition, 0) }\n\t\t\t\t\t) } ) }));\n\n\t\t\tICompilation compilation = TypeSystemHelper.CreateCompilation(a, b);\n\t\t\tITypeDefinition resolvedA = compilation.MainAssembly.GetTypeDefinition(a.FullTypeName);\n\t\t\tITypeDefinition resolvedB = compilation.MainAssembly.GetTypeDefinition(b.FullTypeName);\n\n\t\t\tIType type1 = new ParameterizedType(resolvedB, new[] { compilation.FindType(KnownTypeCode.Double) });\n\t\t\tIType type2 = new ParameterizedType(resolvedA, new[] { new ParameterizedType(resolvedB, new[] { compilation.FindType(KnownTypeCode.String) }) });\n\t\t\tAssert.That(!conversions.ImplicitConversion(type1, type2).IsValid);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ImplicitTypeParameterConversion()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T, U>(T t) where T : U {\n\t\tU u = $t$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.BoxingConversion, GetConversion(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void InvalidImplicitTypeParameterConversion()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T, U>(T t) where U : T {\n\t\tU u = $t$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.None, GetConversion(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ImplicitTypeParameterArrayConversion()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T, U>(T[] t) where T : U {\n\t\tU[] u = $t$;\n\t}\n}\";\n\t\t\t// invalid, e.g. T=int[], U=object[]\n\t\t\tAssert.AreEqual(C.None, GetConversion(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ImplicitTypeParameterConversionWithClassConstraint()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T, U>(T t) where T : class, U where U : class {\n\t\tU u = $t$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.ImplicitReferenceConversion, GetConversion(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ImplicitTypeParameterArrayConversionWithClassConstraint()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T, U>(T[] t) where T : class, U where U : class {\n\t\tU[] u = $t$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.ImplicitReferenceConversion, GetConversion(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ImplicitTypeParameterConversionWithClassConstraintOnlyOnT()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T, U>(T t) where T : class, U {\n\t\tU u = $t$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.ImplicitReferenceConversion, GetConversion(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ImplicitTypeParameterArrayConversionWithClassConstraintOnlyOnT()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T, U>(T[] t) where T : class, U {\n\t\tU[] u = $t$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.ImplicitReferenceConversion, GetConversion(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_Void()\n\t\t{\n\t\t\tstring program = @\"using System;\ndelegate void D();\nclass Test {\n\tD d = $M$;\n\tpublic static void M() {}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsMethodGroupConversion);\n\t\t\tAssert.That(!c.DelegateCapturesFirstArgument);\n\t\t\tAssert.IsNotNull(c.Method);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_Void_InstanceMethod()\n\t\t{\n\t\t\tstring program = @\"using System;\ndelegate void D();\nclass Test {\n\tD d;\n\tpublic void M() {\n\t\td = $M$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsMethodGroupConversion);\n\t\t\tAssert.That(c.DelegateCapturesFirstArgument);\n\t\t\tAssert.IsNotNull(c.Method);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_MatchingSignature()\n\t\t{\n\t\t\tstring program = @\"using System;\ndelegate object D(int argument);\nclass Test {\n\tD d = $M$;\n\tpublic static object M(int argument) {}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsMethodGroupConversion);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_InvalidReturnType()\n\t\t{\n\t\t\tstring program = @\"using System;\ndelegate object D(int argument);\nclass Test {\n\tD d = $M$;\n\tpublic static int M(int argument) {}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(!c.IsValid);\n\t\t\tAssert.That(c.IsMethodGroupConversion);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_CovariantReturnType()\n\t\t{\n\t\t\tstring program = @\"using System;\ndelegate object D(int argument);\nclass Test {\n\tD d = $M$;\n\tpublic static string M(int argument) {}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsMethodGroupConversion);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_RefArgumentTypesEqual()\n\t\t{\n\t\t\tstring program = @\"using System;\ndelegate void D(ref object o);\nclass Test {\n\tD d = $M$;\n\tpublic static void M(ref object o) {}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsMethodGroupConversion);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_RefArgumentObjectVsDynamic()\n\t\t{\n\t\t\tstring program = @\"using System;\ndelegate void D(ref object o);\nclass Test {\n\tD d = $M$;\n\tpublic static void M(ref dynamic o) {}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(!c.IsValid);\n\t\t\tAssert.That(c.IsMethodGroupConversion);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_RefVsOut()\n\t\t{\n\t\t\tstring program = @\"using System;\ndelegate void D(ref object o);\nclass Test {\n\tD d = $M$;\n\tpublic static void M(out object o) {}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(!c.IsValid);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_RefVsNormal()\n\t\t{\n\t\t\tstring program = @\"using System;\ndelegate void D(ref object o);\nclass Test {\n\tD d = $M$;\n\tpublic static void M(object o) {}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(!c.IsValid);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_NormalVsOut()\n\t\t{\n\t\t\tstring program = @\"using System;\ndelegate void D(object o);\nclass Test {\n\tD d = $M$;\n\tpublic static void M(out object o) {}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(!c.IsValid);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_MatchingNormalParameter()\n\t\t{\n\t\t\tstring program = @\"using System;\ndelegate void D(object o);\nclass Test {\n\tD d = $M$;\n\tpublic static void M(object o) {}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsMethodGroupConversion);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_IdentityConversion()\n\t\t{\n\t\t\tstring program = @\"using System;\ndelegate void D(object o);\nclass Test {\n\tD d = $M$;\n\tpublic static void M(dynamic o) {}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsMethodGroupConversion);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_Contravariance()\n\t\t{\n\t\t\tstring program = @\"using System;\ndelegate void D(string o);\nclass Test {\n\tD d = $M$;\n\tpublic static void M(object o) {}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsMethodGroupConversion);\n\n\t\t}\n\n\t\t[Test, Ignore(\"Not sure if this conversion should be valid or not... NR and mcs both accept it as valid, csc treats it as invalid\")]\n\t\tpublic void MethodGroupConversion_NoContravarianceDynamic()\n\t\t{\n\t\t\tstring program = @\"using System;\ndelegate void D(string o);\nclass Test {\n\tD d = $M$;\n\tpublic static void M(dynamic o) {}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\t//Assert.IsFrue(c.IsValid);\n\t\t\tAssert.That(c.IsMethodGroupConversion);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_ExactMatchIsBetter()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tdelegate void D(string a);\n\tD d = $M$;\n\tstatic void M(object x) {}\n\tstatic void M(string x = null) {}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsMethodGroupConversion);\n\t\t\tAssert.AreEqual(\"System.String\", c.Method.Parameters.Single().Type.FullName);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_CannotLeaveOutOptionalParameters()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tdelegate void D(string a);\n\tD d = $M$;\n\tstatic void M(object x) {}\n\tstatic void M(string x, string y = null) {}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsMethodGroupConversion);\n\t\t\tAssert.AreEqual(\"System.Object\", c.Method.Parameters.Single().Type.FullName);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_CannotUseExpandedParams()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tdelegate void D(string a);\n\tD d = $M$;\n\tstatic void M(object x) {}\n\tstatic void M(params string[] x) {}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsMethodGroupConversion);\n\t\t\tAssert.AreEqual(\"System.Object\", c.Method.Parameters.Single().Type.FullName);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_ExtensionMethod()\n\t\t{\n\t\t\tstring program = @\"using System;\nstatic class Ext {\n\tpublic static void M(this string s, int x) {}\n}\nclass Test {\n\tdelegate void D(int a);\n\tvoid F() {\n\t\tstring s = \"\"\"\";\n\t\tD d = $s.M$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsMethodGroupConversion);\n\t\t\tAssert.That(c.DelegateCapturesFirstArgument);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_ExtensionMethodUsedAsStaticMethod()\n\t\t{\n\t\t\tstring program = @\"using System;\nstatic class Ext {\n\tpublic static void M(this string s, int x) {}\n}\nclass Test {\n\tdelegate void D(string s, int a);\n\tvoid F() {\n\t\tD d = $Ext.M$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsMethodGroupConversion);\n\t\t\tAssert.That(!c.DelegateCapturesFirstArgument);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_ObjectToDynamic()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void F(object o) {}\n\tpublic void M() {\n\t\tAction<dynamic> x = $F$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_ObjectToDynamicGenericArgument()\n\t\t{\n\t\t\tstring program = @\"using System;\nusing System.Collections.Generic;\nclass Test {\n\tpublic void F(List<object> l) {}\n\tpublic void M() {\n\t\tAction<List<dynamic>> x = $F$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_ObjectToDynamicReturnValue()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic object F() {}\n\tpublic void M() {\n\t\tFunc<dynamic> x = $F$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_DynamicToObject()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void F(dynamic o) {}\n\tpublic void M() {\n\t\tAction<object> x = $F$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_DynamicToObjectGenericArgument()\n\t\t{\n\t\t\tstring program = @\"using System;\nusing System.Collections.Generic;\nclass Test {\n\tpublic void F(List<dynamic> l) {}\n\tpublic void M() {\n\t\tAction<List<object>> x = $F$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodGroupConversion_DynamicToObjectReturnValue()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic dynamic F() {}\n\tpublic void M() {\n\t\tFunc<object> x = $F$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefined_IntLiteral_ViaUInt_ToCustomStruct()\n\t\t{\n\t\t\tstring program = @\"using System;\nstruct T {\n\tpublic static implicit operator T(uint a) { return new T(); }\n}\nclass Test {\n\tstatic void M() {\n\t\tT t = $1$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsUserDefined);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefined_NullLiteral_ViaString_ToCustomStruct()\n\t\t{\n\t\t\tstring program = @\"using System;\nstruct T {\n\tpublic static implicit operator T(string a) { return new T(); }\n\n}\nclass Test {\n\tstatic void M() {\n\t\tT t = $null$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsUserDefined);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefined_CanUseLiftedEvenIfReturnTypeAlreadyNullable()\n\t\t{\n\t\t\tstring program = @\"using System;\nstruct S {\n\tpublic static implicit operator short?(S s) { return 0; }\n}\n\nclass Test {\n\tstatic void M(S? s) {\n\t\tint? i = $s$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsUserDefined);\n\t\t\tAssert.That(c.IsLifted);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_PicksExactSourceTypeIfPossible()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static implicit operator Convertible(int i) {return new Convertible(); }\n\tpublic static implicit operator Convertible(short s) {return new Convertible(); }\n}\nclass Test {\n\tpublic void M() {\n\t\tConvertible a = $33$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsUserDefined);\n\t\t\tAssert.AreEqual(\"i\", c.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_PicksMostEncompassedSourceType()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static implicit operator Convertible(long l) {return new Convertible(); }\n\tpublic static implicit operator Convertible(uint ui) {return new Convertible(); }\n}\nclass Test {\n\tpublic void M() {\n\t\tConvertible a = $(ushort)33$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsUserDefined);\n\t\t\tAssert.AreEqual(\"ui\", c.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_NoMostEncompassedSourceTypeIsInvalid()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static implicit operator Convertible(ulong l) {return new Convertible(); }\n\tpublic static implicit operator Convertible(int ui) {return new Convertible(); }\n}\nclass Test {\n\tpublic void M() {\n\t\tConvertible a = $(ushort)33$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(!c.IsValid);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_PicksExactTargetTypeIfPossible()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static implicit operator int(Convertible i) {return 0; }\n\tpublic static implicit operator short(Convertible s) {return 0; }\n}\nclass Test {\n\tpublic void M() {\n\t\tint a = $new Convertible()$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsUserDefined);\n\t\t\tAssert.AreEqual(\"i\", c.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_PicksMostEncompassingTargetType()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static implicit operator int(Convertible i) {return 0; }\n\tpublic static implicit operator ushort(Convertible us) {return 0; }\n}\nclass Test {\n\tpublic void M() {\n\t\tulong a = $new Convertible()$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsUserDefined);\n\t\t\tAssert.AreEqual(\"us\", c.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_NoMostEncompassingTargetTypeIsInvalid()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static implicit operator uint(Convertible i) {return 0; }\n\tpublic static implicit operator short(Convertible us) {return 0; }\n}\nclass Test {\n\tpublic void M() {\n\t\tlong a = $new Convertible()$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(!c.IsValid);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_AmbiguousIsInvalid()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible1 {\n\tpublic static implicit operator Convertible2(Convertible1 c) {return 0; }\n}\nclass Convertible2 {\n\tpublic static implicit operator Convertible2(Convertible1 c) {return 0; }\n}\nclass Test {\n\tpublic void M() {\n\t\tConvertible2 a = $new Convertible1()$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(!c.IsValid);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_DefinedNullableTakesPrecedenceOverLifted()\n\t\t{\n\t\t\tstring program = @\"using System;\nstruct Convertible {\n\tpublic static implicit operator Convertible(int i) {return new Convertible(); }\n\tpublic static implicit operator Convertible?(int? ni) {return new Convertible(); }\n}\nclass Test {\n\tpublic void M() {\n\t\tConvertible? a = $(int?)33$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsUserDefined);\n\t\t\tAssert.That(!c.IsLifted);\n\t\t\tAssert.AreEqual(\"ni\", c.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_UIntConstant()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static implicit operator Convertible(long l) {return new Convertible(); }\n\tpublic static implicit operator Convertible(uint ui) {return new Convertible(); }\n}\nclass Test {\n\tpublic void M() {\n\t\tConvertible a = $33$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsUserDefined);\n\t\t\tAssert.AreEqual(\"ui\", c.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_NullableUIntConstant()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static implicit operator Convertible(long? l) {return new Convertible(); }\n\tpublic static implicit operator Convertible(uint? ui) {return new Convertible(); }\n}\nclass Test {\n\tpublic void M() {\n\t\tConvertible a = $33$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsUserDefined);\n\t\t\tAssert.AreEqual(\"ui\", c.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_UseShortResult_BecauseNullableCannotBeUnpacked()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic static implicit operator int?(Test i) { return 0; }\n\tpublic static implicit operator short(Test s) { return 0; }\n}\nclass Program {\n\tpublic static void Main(string[] args)\n\t{\n\t\tint x = $new Test()$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsUserDefined);\n\t\t\tAssert.AreEqual(\"System.Int16\", c.Method.ReturnType.FullName);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_Short_Or_NullableByte_Target()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic static implicit operator short(Test s) { return 0; }\n\tpublic static implicit operator byte?(Test b) { return 0; }\n}\nclass Program {\n\tpublic static void Main(string[] args)\n\t{\n\t\tint? x = $new Test()$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsUserDefined);\n\t\t\tAssert.AreEqual(\"System.Int16\", c.Method.ReturnType.FullName);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_Byte_Or_NullableShort_Target()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic static implicit operator byte(Test b) { return 0; }\n\tpublic static implicit operator short?(Test s) { return 0; }\n}\nclass Program {\n\tpublic static void Main(string[] args)\n\t{\n\t\tint? x = $new Test()$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsUserDefined);\n\t\t\tAssert.AreEqual(\"s\", c.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_Int_Or_NullableLong_Source()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic static implicit operator Test(int i) { return new Test(); }\n\tpublic static implicit operator Test(long? l) { return new Test(); }\n}\nclass Program {\n\tstatic void Main() {\n\t\tshort s = 0;\n\t\tTest t = $s$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsUserDefined);\n\t\t\tAssert.AreEqual(\"i\", c.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_NullableInt_Or_Long_Source()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic static implicit operator Test(int? i) { return new Test(); }\n\tpublic static implicit operator Test(long l) { return new Test(); }\n}\nclass Program {\n\tstatic void Main() {\n\t\tshort s = 0;\n\t\tTest t = $s$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(!c.IsValid);\n\t\t\tAssert.That(c.IsUserDefined);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_NullableInt_Or_Long_Constant_Source()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic static implicit operator Test(int? i) { return new Test(); }\n\tpublic static implicit operator Test(long l) { return new Test(); }\n}\nclass Program {\n\tstatic void Main() {\n\t\tTest t = $1$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(!c.IsValid);\n\t\t\tAssert.That(c.IsUserDefined);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_NullableInt_Or_NullableLong_Source()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic static implicit operator Test(int? i) { return new Test(); }\n\tpublic static implicit operator Test(long? l) { return new Test(); }\n}\nclass Program {\n\tstatic void Main() {\n\t\tshort s = 0;\n\t\tTest t = $s$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsUserDefined);\n\t\t\tAssert.AreEqual(\"i\", c.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void PreferUserDefinedConversionOverReferenceConversion()\n\t\t{\n\t\t\t// actually this is not because user-defined conversions are better;\n\t\t\t// but because string is a better conversion target\n\t\t\tstring program = @\"\nclass AA {\n\tpublic static implicit operator string(AA a) { return null; }\n}\nclass Test {\n\tstatic void M(object obj) {}\n\tstatic void M(string str) {}\n\t\n\tstatic void Main() {\n\t\t$M(new AA())$;\n\t}\n}\";\n\n\t\t\tvar rr = Resolve<CSharpInvocationResolveResult>(program);\n\t\t\tAssert.That(!rr.IsError);\n\t\t\tAssert.AreEqual(\"str\", rr.Member.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void PreferAmbiguousConversionOverReferenceConversion()\n\t\t{\n\t\t\t// Ambiguous conversions are a compiler error; but they are not\n\t\t\t// preventing the overload from being chosen.\n\n\t\t\t// The user-defined conversion wins because BB is a better conversion target than object.\n\t\t\tstring program = @\"\nclass AA {\n\tpublic static implicit operator BB(AA a) { return null; }\n}\nclass BB {\n\tpublic static implicit operator BB(AA a) { return null; }\n}\n\nclass Test {\n\tstatic void M(BB b) {}\n\tstatic void M(object o) {}\n\t\n\tstatic void Main() {\n\t\tM($new AA()$);\n\t}\n}\";\n\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsUserDefined);\n\t\t\tAssert.That(!c.IsValid);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_ConversionBeforeUserDefinedOperatorIsCorrect()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static implicit operator Convertible(long l) {return new Convertible(); }\n}\nclass Test {\n\tpublic void M() {\n\t\tint i = 33;\n\t\tConvertible a = $i$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.ConversionBeforeUserDefinedOperator.IsImplicit);\n\t\t\tAssert.That(c.ConversionBeforeUserDefinedOperator.IsNumericConversion);\n\t\t\tAssert.That(c.ConversionBeforeUserDefinedOperator.IsValid);\n\t\t\tAssert.That(c.ConversionAfterUserDefinedOperator.IsIdentityConversion);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_ConversionAfterUserDefinedOperatorIsCorrect()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static implicit operator int(Convertible i) {return 0; }\n}\nclass Test {\n\tpublic void M() {\n\t\tlong a = $new Convertible()$;\n\t}\n}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.ConversionBeforeUserDefinedOperator.IsIdentityConversion);\n\t\t\tAssert.That(c.ConversionAfterUserDefinedOperator.IsImplicit);\n\t\t\tAssert.That(c.ConversionAfterUserDefinedOperator.IsNumericConversion);\n\t\t\tAssert.That(c.ConversionAfterUserDefinedOperator.IsValid);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedImplicitConversion_IsImplicit()\n\t\t{\n\t\t\t// Bug icsharpcode/NRefactory#183: conversions from constant expressions were incorrectly marked as explicit\n\t\t\tstring program = @\"using System;\n\tclass Test {\n\t\tvoid Hello(JsNumber3 x) {\n\t\t\tHello($7$);\n\t\t}\n\t}\n\tpublic class JsNumber3 {\n\t\tpublic static implicit operator JsNumber3(int d) {\n\t\t\treturn null;\n\t\t}\n\t}\";\n\t\t\tvar c = GetConversion(program);\n\t\t\tAssert.That(c.IsValid);\n\t\t\tAssert.That(c.IsImplicit);\n\t\t\tAssert.That(!c.IsExplicit);\n\t\t\tAssert.AreEqual(Conversion.IdentityConversion, c.ConversionBeforeUserDefinedOperator);\n\t\t\tAssert.AreEqual(Conversion.IdentityConversion, c.ConversionAfterUserDefinedOperator);\n\t\t}\n\t\t*/\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/Semantics/ExplicitConversionTest.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.CSharp.Resolver;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.Tests.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests.Semantics\n{\n\tusing C = Conversion;\n\tusing dynamic = ConversionTest.Dynamic;\n\n\t[TestFixture, Parallelizable(ParallelScope.All)]\n\tpublic class ExplicitConversionsTest\n\t{\n\t\tCSharpConversions conversions;\n\t\tICompilation compilation;\n\n\t\t[OneTimeSetUp]\n\t\tpublic void SetUp()\n\t\t{\n\t\t\tcompilation = new SimpleCompilation(TypeSystemLoaderTests.TestAssembly,\n\t\t\t\tTypeSystemLoaderTests.Mscorlib,\n\t\t\t\tTypeSystemLoaderTests.SystemCore);\n\t\t\tconversions = new CSharpConversions(compilation);\n\t\t}\n\n\t\tConversion ExplicitConversion(Type from, Type to)\n\t\t{\n\t\t\tIType from2 = compilation.FindType(from).AcceptVisitor(new ConversionTest.ReplaceSpecialTypesVisitor());\n\t\t\tIType to2 = compilation.FindType(to).AcceptVisitor(new ConversionTest.ReplaceSpecialTypesVisitor());\n\t\t\treturn conversions.ExplicitConversion(from2, to2);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void PointerConversion()\n\t\t{\n\t\t\tAssert.That(ExplicitConversion(typeof(int*), typeof(short)), Is.EqualTo(C.ExplicitPointerConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(short), typeof(void*)), Is.EqualTo(C.ExplicitPointerConversion));\n\n\t\t\tAssert.That(ExplicitConversion(typeof(void*), typeof(int*)), Is.EqualTo(C.ExplicitPointerConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(long*), typeof(byte*)), Is.EqualTo(C.ExplicitPointerConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ConversionFromDynamic()\n\t\t{\n\t\t\t// Explicit dynamic conversion is for resolve results only;\n\t\t\t// otherwise it's an explicit reference / unboxing conversion\n\t\t\tAssert.That(ExplicitConversion(typeof(dynamic), typeof(string)), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(dynamic), typeof(int)), Is.EqualTo(C.UnboxingConversion));\n\n\t\t\tvar dynamicRR = new ResolveResult(SpecialType.Dynamic);\n\t\t\tAssert.That(conversions.ExplicitConversion(dynamicRR, compilation.FindType(typeof(string))), Is.EqualTo(C.ExplicitDynamicConversion));\n\t\t\tAssert.That(conversions.ExplicitConversion(dynamicRR, compilation.FindType(typeof(int))), Is.EqualTo(C.ExplicitDynamicConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NumericConversions()\n\t\t{\n\t\t\tAssert.That(ExplicitConversion(typeof(sbyte), typeof(uint)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(sbyte), typeof(char)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(byte), typeof(char)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(byte), typeof(sbyte)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\t// if an implicit conversion exists, ExplicitConversion() should return that\n\t\t\tAssert.That(ExplicitConversion(typeof(byte), typeof(int)), Is.EqualTo(C.ImplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(double), typeof(float)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(double), typeof(decimal)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(decimal), typeof(double)), Is.EqualTo(C.ExplicitNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(int), typeof(decimal)), Is.EqualTo(C.ImplicitNumericConversion));\n\n\t\t\tAssert.That(ExplicitConversion(typeof(bool), typeof(int)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ExplicitConversion(typeof(int), typeof(bool)), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void EnumerationConversions()\n\t\t{\n\t\t\tvar explicitEnumerationConversion = C.EnumerationConversion(false, false);\n\t\t\tAssert.That(ExplicitConversion(typeof(sbyte), typeof(StringComparison)), Is.EqualTo(explicitEnumerationConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(char), typeof(StringComparison)), Is.EqualTo(explicitEnumerationConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(int), typeof(StringComparison)), Is.EqualTo(explicitEnumerationConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(decimal), typeof(StringComparison)), Is.EqualTo(explicitEnumerationConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(StringComparison), typeof(char)), Is.EqualTo(explicitEnumerationConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(StringComparison), typeof(int)), Is.EqualTo(explicitEnumerationConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(StringComparison), typeof(decimal)), Is.EqualTo(explicitEnumerationConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(StringComparison), typeof(StringSplitOptions)), Is.EqualTo(explicitEnumerationConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NullableConversion_BasedOnIdentityConversion()\n\t\t{\n\t\t\tAssert.That(ExplicitConversion(typeof(ArraySegment<dynamic>?), typeof(ArraySegment<object>?)), Is.EqualTo(C.IdentityConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(ArraySegment<dynamic>), typeof(ArraySegment<object>?)), Is.EqualTo(C.ImplicitNullableConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(ArraySegment<dynamic>?), typeof(ArraySegment<object>)), Is.EqualTo(C.ExplicitNullableConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NullableConversion_BasedOnImplicitNumericConversion()\n\t\t{\n\t\t\tAssert.That(ExplicitConversion(typeof(int?), typeof(long?)), Is.EqualTo(C.ImplicitLiftedNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(int), typeof(long?)), Is.EqualTo(C.ImplicitLiftedNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(int?), typeof(long)), Is.EqualTo(C.ExplicitLiftedNumericConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NullableConversion_BasedOnImplicitEnumerationConversion()\n\t\t{\n\t\t\tResolveResult zero = new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), 0);\n\t\t\tResolveResult one = new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), 1);\n\t\t\tAssert.That(conversions.ExplicitConversion(zero, compilation.FindType(typeof(StringComparison?))), Is.EqualTo(C.EnumerationConversion(true, true)));\n\t\t\tAssert.That(conversions.ExplicitConversion(one, compilation.FindType(typeof(StringComparison?))), Is.EqualTo(C.EnumerationConversion(false, true)));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NullableConversion_BasedOnExplicitNumericConversion()\n\t\t{\n\t\t\tAssert.That(ExplicitConversion(typeof(int?), typeof(short?)), Is.EqualTo(C.ExplicitLiftedNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(int), typeof(short?)), Is.EqualTo(C.ExplicitLiftedNumericConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(int?), typeof(short)), Is.EqualTo(C.ExplicitLiftedNumericConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NullableConversion_BasedOnExplicitEnumerationConversion()\n\t\t{\n\t\t\tC c = C.EnumerationConversion(false, true); // c = explicit lifted enumeration conversion\n\t\t\tAssert.That(ExplicitConversion(typeof(int?), typeof(StringComparison?)), Is.EqualTo(c));\n\t\t\tAssert.That(ExplicitConversion(typeof(int), typeof(StringComparison?)), Is.EqualTo(c));\n\t\t\tAssert.That(ExplicitConversion(typeof(int?), typeof(StringComparison)), Is.EqualTo(c));\n\n\t\t\tAssert.That(ExplicitConversion(typeof(StringComparison?), typeof(int?)), Is.EqualTo(c));\n\t\t\tAssert.That(ExplicitConversion(typeof(StringComparison), typeof(int?)), Is.EqualTo(c));\n\t\t\tAssert.That(ExplicitConversion(typeof(StringComparison?), typeof(int)), Is.EqualTo(c));\n\n\t\t\tAssert.That(ExplicitConversion(typeof(StringComparison?), typeof(StringSplitOptions?)), Is.EqualTo(c));\n\t\t\tAssert.That(ExplicitConversion(typeof(StringComparison), typeof(StringSplitOptions?)), Is.EqualTo(c));\n\t\t\tAssert.That(ExplicitConversion(typeof(StringComparison?), typeof(StringSplitOptions)), Is.EqualTo(c));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExplicitReferenceConversion_SealedClass()\n\t\t{\n\t\t\tAssert.That(ExplicitConversion(typeof(object), typeof(string)), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<char>), typeof(string)), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<int>), typeof(string)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<object>), typeof(string)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ExplicitConversion(typeof(string), typeof(IEnumerable<char>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(string), typeof(IEnumerable<int>)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ExplicitConversion(typeof(string), typeof(IEnumerable<object>)), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExplicitReferenceConversion_NonSealedClass()\n\t\t{\n\t\t\tAssert.That(ExplicitConversion(typeof(object), typeof(List<string>)), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<object>), typeof(List<string>)), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<string>), typeof(List<string>)), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<int>), typeof(List<string>)), Is.EqualTo(C.ExplicitReferenceConversion));\n\n\t\t\tAssert.That(ExplicitConversion(typeof(List<string>), typeof(IEnumerable<object>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(List<string>), typeof(IEnumerable<string>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(List<string>), typeof(IEnumerable<int>)), Is.EqualTo(C.ExplicitReferenceConversion));\n\n\t\t\tAssert.That(ExplicitConversion(typeof(List<string>), typeof(List<object>)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ExplicitConversion(typeof(List<string>), typeof(List<int>)), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExplicitReferenceConversion_Interfaces()\n\t\t{\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<string>), typeof(IEnumerable<object>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<int>), typeof(IEnumerable<object>)), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<object>), typeof(IEnumerable<string>)), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<object>), typeof(IEnumerable<int>)), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<object>), typeof(IConvertible)), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExplicitReferenceConversion_Arrays()\n\t\t{\n\t\t\tAssert.That(ExplicitConversion(typeof(object[]), typeof(string[])), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(dynamic[]), typeof(string[])), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(object[]), typeof(object[,])), Is.EqualTo(C.None));\n\t\t\tAssert.That(ExplicitConversion(typeof(object[]), typeof(int[])), Is.EqualTo(C.None));\n\t\t\tAssert.That(ExplicitConversion(typeof(short[]), typeof(int[])), Is.EqualTo(C.None));\n\t\t\tAssert.That(ExplicitConversion(typeof(Array), typeof(int[])), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExplicitReferenceConversion_InterfaceToArray()\n\t\t{\n\t\t\tAssert.That(ExplicitConversion(typeof(ICloneable), typeof(int[])), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<string>), typeof(string[])), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<object>), typeof(string[])), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<string>), typeof(object[])), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<string>), typeof(dynamic[])), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<int>), typeof(int[])), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<string>), typeof(object[,])), Is.EqualTo(C.None));\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<short>), typeof(object[])), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExplicitReferenceConversion_ArrayToInterface()\n\t\t{\n\t\t\tAssert.That(ExplicitConversion(typeof(int[]), typeof(ICloneable)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(string[]), typeof(IEnumerable<string>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(string[]), typeof(IEnumerable<object>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(object[]), typeof(IEnumerable<string>)), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(dynamic[]), typeof(IEnumerable<string>)), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(int[]), typeof(IEnumerable<int>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(object[,]), typeof(IEnumerable<string>)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ExplicitConversion(typeof(object[]), typeof(IEnumerable<short>)), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExplicitReferenceConversion_Delegates()\n\t\t{\n\t\t\tAssert.That(ExplicitConversion(typeof(MulticastDelegate), typeof(Action)), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(Delegate), typeof(Action)), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(ICloneable), typeof(Action)), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(System.Threading.ThreadStart), typeof(Action)), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExplicitReferenceConversion_GenericDelegates()\n\t\t{\n\t\t\tAssert.That(ExplicitConversion(typeof(Action<object>), typeof(Action<string>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(Action<string>), typeof(Action<object>)), Is.EqualTo(C.ExplicitReferenceConversion));\n\n\t\t\tAssert.That(ExplicitConversion(typeof(Func<object>), typeof(Func<string>)), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(Func<string>), typeof(Func<object>)), Is.EqualTo(C.ImplicitReferenceConversion));\n\n\t\t\tAssert.That(ExplicitConversion(typeof(Action<IFormattable>), typeof(Action<IConvertible>)), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(Action<IFormattable>), typeof(Action<int>)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ExplicitConversion(typeof(Action<string>), typeof(Action<IEnumerable<int>>)), Is.EqualTo(C.ExplicitReferenceConversion));\n\n\t\t\tAssert.That(ExplicitConversion(typeof(Func<IFormattable>), typeof(Func<IConvertible>)), Is.EqualTo(C.ExplicitReferenceConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(Func<IFormattable>), typeof(Func<int>)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ExplicitConversion(typeof(Func<string>), typeof(Func<IEnumerable<int>>)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ExplicitConversion(typeof(Func<string>), typeof(Func<IEnumerable<int>>)), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UnboxingConversion()\n\t\t{\n\t\t\tAssert.That(ExplicitConversion(typeof(object), typeof(int)), Is.EqualTo(C.UnboxingConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(object), typeof(decimal)), Is.EqualTo(C.UnboxingConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(ValueType), typeof(int)), Is.EqualTo(C.UnboxingConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IFormattable), typeof(int)), Is.EqualTo(C.UnboxingConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<object>), typeof(int)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ExplicitConversion(typeof(Enum), typeof(StringComparison)), Is.EqualTo(C.UnboxingConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(Enum), typeof(int)), Is.EqualTo(C.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void LiftedUnboxingConversion()\n\t\t{\n\t\t\tAssert.That(ExplicitConversion(typeof(object), typeof(int?)), Is.EqualTo(C.UnboxingConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(object), typeof(decimal?)), Is.EqualTo(C.UnboxingConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(ValueType), typeof(int?)), Is.EqualTo(C.UnboxingConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IFormattable), typeof(int?)), Is.EqualTo(C.UnboxingConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(IEnumerable<object>), typeof(int?)), Is.EqualTo(C.None));\n\t\t\tAssert.That(ExplicitConversion(typeof(Enum), typeof(StringComparison?)), Is.EqualTo(C.UnboxingConversion));\n\t\t\tAssert.That(ExplicitConversion(typeof(Enum), typeof(int?)), Is.EqualTo(C.None));\n\t\t}\n\n\t\t/* TODO: we should probably revive these tests somehow\n\t\tConversion ResolveCast(string program)\n\t\t{\n\t\t\treturn Resolve<ConversionResolveResult>(program).Conversion;\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ObjectToTypeParameter()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T>(object o) {\n\t\tT t = $(T)o$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.UnboxingConversion, ResolveCast(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UnrelatedClassToTypeParameter()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T>(string o) {\n\t\tT t = $(T)o$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.None, ResolveCast(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void IntefaceToTypeParameter()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T>(IDisposable o) {\n\t\tT t = $(T)o$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.UnboxingConversion, ResolveCast(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TypeParameterToInterface()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T>(T t) {\n\t\tIDisposable d = $(IDisposable)t$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.BoxingConversion, ResolveCast(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ValueTypeToTypeParameter()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T>(ValueType o) where T : struct {\n\t\tT t = $(T)o$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.UnboxingConversion, ResolveCast(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void InvalidTypeParameterConversion()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T, U>(T t) {\n\t\tU u = $(U)t$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.None, ResolveCast(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TypeParameterConversion1()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T, U>(T t) where T : U {\n\t\tU u = $(U)t$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.BoxingConversion, ResolveCast(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TypeParameterConversion1Array()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T, U>(T[] t) where T : U {\n\t\tU[] u = $(U[])t$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.None, ResolveCast(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TypeParameterConversion2()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T, U>(T t) where U : T {\n\t\tU u = $(U)t$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.UnboxingConversion, ResolveCast(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TypeParameterConversion2Array()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T, U>(T[] t) where U : T {\n\t\tU[] u = $(U[])t$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.None, ResolveCast(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ImplicitTypeParameterConversionWithClassConstraint()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T, U>(T t) where T : class where U : class, T {\n\t\tU u = $(U)t$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.ExplicitReferenceConversion, ResolveCast(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ImplicitTypeParameterArrayConversionWithClassConstraint()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T, U>(T[] t) where T : class where U : class, T {\n\t\tU[] u = $(U[])t$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.ExplicitReferenceConversion, ResolveCast(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ImplicitTypeParameterConversionWithClassConstraintOnlyOnT()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T, U>(T t) where U : class, T {\n\t\tU u = $(U)t$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.ExplicitReferenceConversion, ResolveCast(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ImplicitTypeParameterArrayConversionWithClassConstraintOnlyOnT()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic void M<T, U>(T[] t) where U : class, T {\n\t\tU[] u = $(U[])t$;\n\t}\n}\";\n\t\t\tAssert.AreEqual(C.ExplicitReferenceConversion, ResolveCast(program));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void SimpleUserDefinedConversion()\n\t\t{\n\t\t\tvar rr = Resolve<ConversionResolveResult>(@\"\nclass C1 {}\nclass C2 {\n\tpublic static explicit operator C1(C2 c2) {\n\t\treturn null;\n\t}\n}\nclass C {\n\tpublic void M() {\n\t\tvar c2 = new C2();\n\t\tC1 c1 = $(C1)c2$;\n\t}\n}\");\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\tAssert.AreEqual(\"op_Explicit\", rr.Conversion.Method.Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExplicitReferenceConversionFollowedByUserDefinedConversion()\n\t\t{\n\t\t\tvar rr = Resolve<ConversionResolveResult>(@\"\n\t\tclass B {}\n\t\tclass S : B {}\n\t\tclass T {\n\t\t\tpublic static explicit operator T(S s) { return null; }\n\t\t}\n\t\tclass Test {\n\t\t\tvoid Run(B b) {\n\t\t\t\tT t = $(T)b$;\n\t\t\t}\n\t\t}\");\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\tAssert.AreEqual(\"B\", rr.Input.Type.Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ImplicitUserDefinedConversionFollowedByExplicitNumericConversion()\n\t\t{\n\t\t\tvar rr = Resolve<ConversionResolveResult>(@\"\n\t\tstruct T {\n\t\t\tpublic static implicit operator float(T t) { return 0; }\n\t\t}\n\t\tclass Test {\n\t\t\tvoid Run(T t) {\n\t\t\t\tint x = $(int)t$;\n\t\t\t}\n\t\t}\");\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\t// even though the user-defined conversion is implicit, the combined conversion is explicit\n\t\t\tAssert.That(rr.Conversion.IsExplicit);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void BothDirectConversionAndBaseClassConversionAvailable()\n\t\t{\n\t\t\tvar rr = Resolve<ConversionResolveResult>(@\"\n\t\tclass B {}\n\t\tclass S : B {}\n\t\tclass T {\n\t\t\tpublic static explicit operator T(S s) { return null; }\n\t\t\tpublic static explicit operator T(B b) { return null; }\n\t\t}\n\t\tclass Test {\n\t\t\tvoid Run(B b) {\n\t\t\t\tT t = $(T)b$;\n\t\t\t}\n\t\t}\");\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\tAssert.AreEqual(\"b\", rr.Conversion.Method.Parameters.Single().Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedExplicitConversion_PicksExactSourceTypeIfPossible()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static explicit operator Convertible(int i) {return new Convertible(); }\n\tpublic static explicit operator Convertible(short s) {return new Convertible(); }\n}\nclass Test {\n\tpublic void M() {\n\t\tvar a = $(Convertible)33$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\tAssert.AreEqual(\"i\", rr.Conversion.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedExplicitConversion_PicksMostEncompassedSourceTypeIfPossible()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static explicit operator Convertible(long l) {return new Convertible(); }\n\tpublic static explicit operator Convertible(uint ui) {return new Convertible(); }\n}\nclass Test {\n\tpublic void M() {\n\t\tvar a = $(Convertible)(ushort)33$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\tAssert.AreEqual(\"ui\", rr.Conversion.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedExplicitConversion_PicksMostEncompassingSourceType()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static explicit operator Convertible(int i) {return new Convertible(); }\n\tpublic static explicit operator Convertible(ushort us) {return new Convertible(); }\n}\nclass Test {\n\tpublic void M() {\n\t\tvar a = $(Convertible)(long)33$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\tAssert.AreEqual(\"i\", rr.Conversion.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedExplicitConversion_NoMostEncompassingSourceTypeIsInvalid()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static explicit operator Convertible(uint i) {return new Convertible(); }\n\tpublic static explicit operator Convertible(short us) {return new Convertible(); }\n}\nclass Test {\n\tpublic void M() {\n\t\tvar a = $(Convertible)(long)33$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(!rr.Conversion.IsValid);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedExplicitConversion_PicksExactTargetTypeIfPossible()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static explicit operator int(Convertible i) {return 0; }\n\tpublic static explicit operator short(Convertible s) {return 0; }\n}\nclass Test {\n\tpublic void M() {\n\t\tvar a = $(int)new Convertible()$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\tAssert.AreEqual(\"i\", rr.Conversion.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedExplicitConversion_PicksMostEncompassingTargetTypeIfPossible()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static explicit operator int(Convertible i) {return 0; }\n\tpublic static explicit operator ushort(Convertible us) {return 0; }\n}\nclass Test {\n\tpublic void M() {\n\t\tvar a = $(ulong)new Convertible()$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\tAssert.AreEqual(\"us\", rr.Conversion.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedExplicitConversion_PicksMostEncompassedTargetType()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static explicit operator long(Convertible l) { return 0; }\n\tpublic static explicit operator uint(Convertible ui) { return 0; }\n}\nclass Test {\n\tpublic void M() {\n\t\tvar a = $(ushort)new Convertible()$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\tAssert.AreEqual(\"ui\", rr.Conversion.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedExplicitConversion_NoMostEncompassedTargetTypeIsInvalid()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static explicit operator ulong(Convertible l) { return 0; }\n\tpublic static explicit operator int(Convertible ui) { return 0; }\n}\nclass Test {\n\tpublic void M() {\n\t\tvar a = $(ushort)new Convertible()$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(!rr.Conversion.IsValid);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedExplicitConversion_AmbiguousIsInvalid()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible1 {\n\tpublic static explicit operator Convertible2(Convertible1 c) {return 0; }\n}\nclass Convertible2 {\n\tpublic static explicit operator Convertible2(Convertible1 c) {return 0; }\n}\nclass Test {\n\tpublic void M() {\n\t\tvar a = $(Convertible2)new Convertible1()$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(!rr.Conversion.IsValid);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedExplicitConversion_Lifted()\n\t\t{\n\t\t\tstring program = @\"using System;\nstruct Convertible {\n\tpublic static explicit operator Convertible(int i) {return new Convertible(); }\n}\nclass Test {\n\tpublic void M(int? i) {\n\t\t a = $(Convertible?)i$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\tAssert.That(rr.Conversion.IsLifted);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedExplicitConversionFollowedByImplicitNullableConversion()\n\t\t{\n\t\t\tstring program = @\"using System;\nstruct Convertible {\n\tpublic static explicit operator Convertible(int i) {return new Convertible(); }\n}\nclass Test {\n\tpublic void M(int i) {\n\t\t a = $(Convertible?)i$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\tAssert.That(!rr.Conversion.IsLifted);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedExplicitConversion_ExplicitNullable_ThenUserDefined()\n\t\t{\n\t\t\tstring program = @\"using System;\nstruct Convertible {\n\tpublic static explicit operator Convertible(int i) {return new Convertible(); }\n\tpublic static explicit operator Convertible?(int? ni) {return new Convertible(); }\n}\nclass Test {\n\tpublic void M(int? i) {\n\t\t a = $(Convertible)i$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\tAssert.That(!rr.Conversion.IsLifted);\n\t\t\tAssert.AreEqual(\"i\", rr.Conversion.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedExplicitConversion_DefinedNullableTakesPrecedenceOverLifted()\n\t\t{\n\t\t\tstring program = @\"using System;\nstruct Convertible {\n\tpublic static explicit operator Convertible(int i) {return new Convertible(); }\n\tpublic static explicit operator Convertible?(int? ni) {return new Convertible(); }\n}\nclass Test {\n\tpublic void M() {\n\t\t a = $(Convertible?)(int?)33$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\tAssert.That(!rr.Conversion.IsLifted);\n\t\t\tAssert.AreEqual(\"ni\", rr.Conversion.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedExplicitConversion_UIntConstant()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static explicit operator Convertible(long l) {return new Convertible(); }\n\tpublic static explicit operator Convertible(uint ui) {return new Convertible(); }\n}\nclass Test {\n\tpublic void M() {\n\t\tvar a = $(Convertible)33$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\tAssert.AreEqual(\"ui\", rr.Conversion.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedExplicitConversion_NullableUIntConstant()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static explicit operator Convertible(long? l) {return new Convertible(); }\n\tpublic static explicit operator Convertible(uint? ui) {return new Convertible(); }\n}\nclass Test {\n\tpublic void M() {\n\t\tConvertible a = $(Convertible)33$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\tAssert.AreEqual(\"ui\", rr.Conversion.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UseDefinedExplicitConversion_Lifted()\n\t\t{\n\t\t\tstring program = @\"\nstruct Convertible {\n\tpublic static explicit operator Convertible(int i) { return new Convertible(); }\n}\nclass Test {\n\tpublic void M(int? i) {\n\t\ta = $(Convertible?)i$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\tAssert.That(rr.Conversion.IsLifted);\n\t\t\tAssert.That(rr.Input is LocalResolveResult);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedExplicitConversion_Short_Or_NullableByte_Target()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic static explicit operator short(Test s) { return 0; }\n\tpublic static explicit operator byte?(Test b) { return 0; }\n}\nclass Program {\n\tpublic static void Main(string[] args)\n\t{\n\t\tint? x = $(int?)new Test()$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\tAssert.AreEqual(\"System.Int16\", rr.Conversion.Method.ReturnType.FullName);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedExplicitConversion_Byte_Or_NullableShort_Target()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Test {\n\tpublic static explicit operator byte(Test b) { return 0; }\n\tpublic static explicit operator short?(Test s) { return 0; }\n}\nclass Program {\n\tpublic static void Main(string[] args)\n\t{\n\t\tint? x = $(int?)new Test()$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\tAssert.AreEqual(\"s\", rr.Conversion.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExplicitConversionOperatorsCanOverrideApplicableImplicitOnes()\n\t\t{\n\t\t\tstring program = @\"\nstruct Convertible {\n\tpublic static explicit operator int(Convertible ci) {return 0; }\n\tpublic static implicit operator short(Convertible cs) {return 0; }\n}\nclass Test {\n\tstatic void Main() {\n\t\tint i = $(int)new Convertible()$; // csc uses the explicit conversion operator\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.IsUserDefined);\n\t\t\tAssert.AreEqual(\"ci\", rr.Conversion.Method.Parameters[0].Name);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedExplicitConversion_ConversionBeforeUserDefinedOperatorIsCorrect()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static implicit operator Convertible(int l) {return new Convertible(); }\n}\nclass Test {\n\tpublic void M() {\n\t\tlong i = 33;\n\t\tConvertible a = $(Convertible)i$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.ConversionBeforeUserDefinedOperator.IsValid);\n\t\t\tAssert.That(rr.Conversion.ConversionBeforeUserDefinedOperator.IsExplicit);\n\t\t\tAssert.That(rr.Conversion.ConversionBeforeUserDefinedOperator.IsNumericConversion);\n\t\t\tAssert.That(rr.Conversion.ConversionAfterUserDefinedOperator.IsIdentityConversion);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UserDefinedExplicitConversion_ConversionAfterUserDefinedOperatorIsCorrect()\n\t\t{\n\t\t\tstring program = @\"using System;\nclass Convertible {\n\tpublic static implicit operator long(Convertible i) {return 0; }\n}\nclass Test {\n\tpublic void M() {\n\t\tint a = $(int)new Convertible()$;\n\t}\n}\";\n\t\t\tvar rr = Resolve<ConversionResolveResult>(program);\n\t\t\tAssert.That(rr.Conversion.IsValid);\n\t\t\tAssert.That(rr.Conversion.ConversionBeforeUserDefinedOperator.IsIdentityConversion);\n\t\t\tAssert.That(rr.Conversion.ConversionAfterUserDefinedOperator.IsValid);\n\t\t\tAssert.That(rr.Conversion.ConversionAfterUserDefinedOperator.IsExplicit);\n\t\t\tAssert.That(rr.Conversion.ConversionAfterUserDefinedOperator.IsNumericConversion);\n\t\t}*/\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/Semantics/OverloadResolutionTests.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Linq.Expressions;\n\nusing ICSharpCode.Decompiler.CSharp.Resolver;\nusing ICSharpCode.Decompiler.Semantics;\nusing ICSharpCode.Decompiler.Tests.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests.Semantics\n{\n\t[TestFixture, Parallelizable(ParallelScope.All)]\n\tpublic class OverloadResolutionTests\n\t{\n\t\tICompilation compilation;\n\n\t\t[OneTimeSetUp]\n\t\tpublic void SetUp()\n\t\t{\n\t\t\tcompilation = new SimpleCompilation(TypeSystemLoaderTests.TestAssembly,\n\t\t\t\tTypeSystemLoaderTests.Mscorlib,\n\t\t\t\tTypeSystemLoaderTests.SystemCore);\n\t\t}\n\n\t\tResolveResult[] MakeArgumentList(params Type[] argumentTypes)\n\t\t{\n\t\t\treturn argumentTypes.Select(t => new ResolveResult(compilation.FindType(t))).ToArray();\n\t\t}\n\n\t\tIMethod MakeMethod(params object[] parameterTypesOrDefaultValues)\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tvar m = new FakeMethod(compilation, SymbolKind.Method);\n\t\t\tm.Name = \"Method\";\n\t\t\tvar parameters = new List<IParameter>();\n\t\t\tforeach (var typeOrDefaultValue in parameterTypesOrDefaultValues)\n\t\t\t{\n\t\t\t\tType type = typeOrDefaultValue as Type;\n\t\t\t\tif (type != null)\n\t\t\t\t\tparameters.Add(new DefaultParameter(compilation.FindType(type), string.Empty, owner: m));\n\t\t\t\telse if (Type.GetTypeCode(typeOrDefaultValue.GetType()) > TypeCode.Object)\n\t\t\t\t\tparameters.Add(new DefaultParameter(compilation.FindType(typeOrDefaultValue.GetType()), string.Empty,\n\t\t\t\t\t\towner: m, isOptional: true, defaultValue: typeOrDefaultValue));\n\t\t\t\telse\n\t\t\t\t\tthrow new ArgumentException(typeOrDefaultValue.ToString());\n\t\t\t}\n\t\t\tm.Parameters = parameters;\n\t\t\treturn m;\n\t\t}\n\n\t\tIMethod MakeParamsMethod(params object[] parameterTypesOrDefaultValues)\n\t\t{\n\t\t\tvar m = (FakeMethod)MakeMethod(parameterTypesOrDefaultValues);\n\t\t\tvar parameters = m.Parameters.ToList();\n\t\t\tparameters[parameters.Count - 1] = new DefaultParameter(\n\t\t\t\tparameters.Last().Type, parameters.Last().Name,\n\t\t\t\tisParams: true);\n\t\t\tm.Parameters = parameters;\n\t\t\treturn m;\n\t\t}\n\n\t\t[Test]\n\t\tpublic void PreferIntOverUInt()\n\t\t{\n\t\t\tOverloadResolution r = new OverloadResolution(compilation, MakeArgumentList(typeof(ushort)));\n\t\t\tvar c1 = MakeMethod(typeof(int));\n\t\t\tAssert.That(r.AddCandidate(c1), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(r.AddCandidate(MakeMethod(typeof(uint))), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(!r.IsAmbiguous);\n\t\t\tAssert.That(r.BestCandidate, Is.SameAs(c1));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void PreferUIntOverLong_FromIntLiteral()\n\t\t{\n\t\t\tResolveResult[] args = { new ConstantResolveResult(compilation.FindType(KnownTypeCode.Int32), 1) };\n\t\t\tOverloadResolution r = new OverloadResolution(compilation, args);\n\t\t\tvar c1 = MakeMethod(typeof(uint));\n\t\t\tAssert.That(r.AddCandidate(c1), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(r.AddCandidate(MakeMethod(typeof(long))), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(!r.IsAmbiguous);\n\t\t\tAssert.That(r.BestCandidate, Is.SameAs(c1));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NullableIntAndNullableUIntIsAmbiguous()\n\t\t{\n\t\t\tOverloadResolution r = new OverloadResolution(compilation, MakeArgumentList(typeof(ushort?)));\n\t\t\tAssert.That(r.AddCandidate(MakeMethod(typeof(int?))), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(r.AddCandidate(MakeMethod(typeof(uint?))), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(r.BestCandidateErrors, Is.EqualTo(OverloadResolutionErrors.AmbiguousMatch));\n\n\t\t\t// then adding a matching overload solves the ambiguity:\n\t\t\tAssert.That(r.AddCandidate(MakeMethod(typeof(ushort?))), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(r.BestCandidateErrors, Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(r.BestCandidateAmbiguousWith, Is.Null);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParamsMethodMatchesEmptyArgumentList()\n\t\t{\n\t\t\tOverloadResolution r = new OverloadResolution(compilation, MakeArgumentList());\n\t\t\tAssert.That(r.AddCandidate(MakeParamsMethod(typeof(int[]))), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(r.BestCandidateIsExpandedForm);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParamsMethodMatchesOneArgumentInExpandedForm()\n\t\t{\n\t\t\tOverloadResolution r = new OverloadResolution(compilation, MakeArgumentList(typeof(int)));\n\t\t\tAssert.That(r.AddCandidate(MakeParamsMethod(typeof(int[]))), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(r.BestCandidateIsExpandedForm);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParamsMethodMatchesInUnexpandedForm()\n\t\t{\n\t\t\tOverloadResolution r = new OverloadResolution(compilation, MakeArgumentList(typeof(int[])));\n\t\t\tAssert.That(r.AddCandidate(MakeParamsMethod(typeof(int[]))), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(!r.BestCandidateIsExpandedForm);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void LessArgumentsPassedToParamsIsBetter()\n\t\t{\n\t\t\tOverloadResolution r = new OverloadResolution(compilation, MakeArgumentList(typeof(int), typeof(int), typeof(int)));\n\t\t\tAssert.That(r.AddCandidate(MakeParamsMethod(typeof(int[]))), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(r.AddCandidate(MakeParamsMethod(typeof(int), typeof(int[]))), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(!r.IsAmbiguous);\n\t\t\tAssert.That(r.BestCandidate.Parameters.Count, Is.EqualTo(2));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void CallInvalidParamsDeclaration()\n\t\t{\n\t\t\tOverloadResolution r = new OverloadResolution(compilation, MakeArgumentList(typeof(int[,])));\n\t\t\tAssert.That(r.AddCandidate(MakeParamsMethod(typeof(int))), Is.EqualTo(OverloadResolutionErrors.ArgumentTypeMismatch));\n\t\t\tAssert.That(!r.BestCandidateIsExpandedForm);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void PreferMethodWithoutOptionalParameters()\n\t\t{\n\t\t\tvar m1 = MakeMethod();\n\t\t\tvar m2 = MakeMethod(1);\n\n\t\t\tOverloadResolution r = new OverloadResolution(compilation, MakeArgumentList());\n\t\t\tAssert.That(r.AddCandidate(m1), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(r.AddCandidate(m2), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(!r.IsAmbiguous);\n\t\t\tAssert.That(r.BestCandidate, Is.SameAs(m1));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void SkeetEvilOverloadResolution()\n\t\t{\n\t\t\t// http://msmvps.com/blogs/jon_skeet/archive/2010/11/02/evil-code-overload-resolution-workaround.aspx\n\n\t\t\tvar container = compilation.FindType(typeof(SkeetEvilOverloadResolutionTestCase)).GetDefinition();\n\t\t\tIMethod resolvedM1 = container.GetMethods(m => m.Name == \"Foo\").First();\n\t\t\tIMethod resolvedM2 = container.GetMethods(m => m.Name == \"Foo\").Skip(1).First();\n\t\t\tIMethod resolvedM3 = container.GetMethods(m => m.Name == \"Foo\").Skip(2).First();\n\n\t\t\t// Call: Foo<int>();\n\t\t\tOverloadResolution o;\n\t\t\to = new OverloadResolution(compilation, new ResolveResult[0], typeArguments: new[] { compilation.FindType(typeof(int)) });\n\t\t\tAssert.That(o.AddCandidate(resolvedM1), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(o.AddCandidate(resolvedM2), Is.EqualTo(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint));\n\t\t\tAssert.That(o.BestCandidate, Is.SameAs(resolvedM1));\n\n\t\t\t// Call: Foo<string>();\n\t\t\to = new OverloadResolution(compilation, new ResolveResult[0], typeArguments: new[] { compilation.FindType(typeof(string)) });\n\t\t\tAssert.That(o.AddCandidate(resolvedM1), Is.EqualTo(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint));\n\t\t\tAssert.That(o.AddCandidate(resolvedM2), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(o.BestCandidate, Is.SameAs(resolvedM2));\n\n\t\t\t// Call: Foo<int?>();\n\t\t\to = new OverloadResolution(compilation, new ResolveResult[0], typeArguments: new[] { compilation.FindType(typeof(int?)) });\n\t\t\tAssert.That(o.AddCandidate(resolvedM1), Is.EqualTo(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint));\n\t\t\tAssert.That(o.AddCandidate(resolvedM2), Is.EqualTo(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint));\n\t\t\tAssert.That(o.AddCandidate(resolvedM3), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(o.BestCandidate, Is.SameAs(resolvedM3));\n\t\t}\n\n\t\tclass SkeetEvilOverloadResolutionTestCase\n\t\t{\n\t\t\tclass ClassConstraint<T> where T : class { }\n\t\t\tstatic void Foo<T>(T? ignored = default(T?)) where T : struct { }\n\t\t\tstatic void Foo<T>(ClassConstraint<T> ignored = default(ClassConstraint<T>)) where T : class { }\n\t\t\tstatic void Foo<T>() { }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// A lambda of the form \"() => default(returnType)\"\n\t\t/// </summary>\n\t\tclass MockLambda : LambdaResolveResult\n\t\t{\n\t\t\treadonly IType inferredReturnType;\n\t\t\tinternal readonly List<IParameter> parameters = new List<IParameter>();\n\n\t\t\tpublic MockLambda(IType returnType)\n\t\t\t{\n\t\t\t\tthis.inferredReturnType = returnType;\n\t\t\t}\n\n\t\t\tpublic override IReadOnlyList<IParameter> Parameters {\n\t\t\t\tget { return parameters; }\n\t\t\t}\n\n\t\t\tpublic override Conversion IsValid(IType[] parameterTypes, IType returnType, CSharpConversions conversions)\n\t\t\t{\n\t\t\t\treturn conversions.ImplicitConversion(inferredReturnType, returnType);\n\t\t\t}\n\n\t\t\tpublic override bool IsImplicitlyTyped {\n\t\t\t\tget { return false; }\n\t\t\t}\n\n\t\t\tpublic override bool IsAnonymousMethod {\n\t\t\t\tget { return false; }\n\t\t\t}\n\n\t\t\tpublic override bool HasParameterList {\n\t\t\t\tget { return true; }\n\t\t\t}\n\n\t\t\tpublic override bool IsAsync {\n\t\t\t\tget { return false; }\n\t\t\t}\n\n\t\t\tpublic override ResolveResult Body {\n\t\t\t\tget { throw new NotImplementedException(); }\n\t\t\t}\n\n\t\t\tpublic override IType ReturnType {\n\t\t\t\tget { throw new NotImplementedException(); }\n\t\t\t}\n\n\t\t\tpublic override IType GetInferredReturnType(IType[] parameterTypes)\n\t\t\t{\n\t\t\t\treturn inferredReturnType;\n\t\t\t}\n\t\t}\n\n\t\t[Test]\n\t\tpublic void BetterConversionByLambdaReturnValue()\n\t\t{\n\t\t\tvar m1 = MakeMethod(typeof(Func<long>));\n\t\t\tvar m2 = MakeMethod(typeof(Func<int>));\n\n\t\t\t// M(() => default(byte));\n\t\t\tResolveResult[] args = {\n\t\t\t\tnew MockLambda(compilation.FindType(KnownTypeCode.Byte))\n\t\t\t};\n\n\t\t\tOverloadResolution r = new OverloadResolution(compilation, args);\n\t\t\tAssert.That(r.AddCandidate(m1), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(r.AddCandidate(m2), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(r.BestCandidate, Is.SameAs(m2));\n\t\t\tAssert.That(r.BestCandidateErrors, Is.EqualTo(OverloadResolutionErrors.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void BetterConversionByLambdaReturnValue_ExpressionTree()\n\t\t{\n\t\t\tvar m1 = MakeMethod(typeof(Func<long>));\n\t\t\tvar m2 = MakeMethod(typeof(Expression<Func<int>>));\n\n\t\t\t// M(() => default(byte));\n\t\t\tResolveResult[] args = {\n\t\t\t\tnew MockLambda(compilation.FindType(KnownTypeCode.Byte))\n\t\t\t};\n\n\t\t\tOverloadResolution r = new OverloadResolution(compilation, args);\n\t\t\tAssert.That(r.AddCandidate(m1), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(r.AddCandidate(m2), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(r.BestCandidate, Is.SameAs(m2));\n\t\t\tAssert.That(r.BestCandidateErrors, Is.EqualTo(OverloadResolutionErrors.None));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Lambda_DelegateAndExpressionTreeOverloadsAreAmbiguous()\n\t\t{\n\t\t\tvar m1 = MakeMethod(typeof(Func<int>));\n\t\t\tvar m2 = MakeMethod(typeof(Expression<Func<int>>));\n\n\t\t\t// M(() => default(int));\n\t\t\tResolveResult[] args = {\n\t\t\t\tnew MockLambda(compilation.FindType(KnownTypeCode.Int32))\n\t\t\t};\n\n\t\t\tOverloadResolution r = new OverloadResolution(compilation, args);\n\t\t\tAssert.That(r.AddCandidate(m1), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(r.AddCandidate(m2), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\tAssert.That(r.BestCandidateErrors, Is.EqualTo(OverloadResolutionErrors.AmbiguousMatch));\n\t\t}\n\n\t\t[Test, Ignore(\"Overload Resolution bug\")]\n\t\tpublic void BetterFunctionMemberIsNotTransitive()\n\t\t{\n\t\t\tvar container = compilation.FindType(typeof(BetterFunctionMemberIsNotTransitiveTestCase)).GetDefinition();\n\n\t\t\tvar args = new ResolveResult[] {\n\t\t\t\tnew MockLambda(compilation.FindType(KnownTypeCode.String)) { parameters = { new DefaultParameter(SpecialType.UnknownType, \"arg\") } }\n\t\t\t};\n\n\t\t\tOverloadResolution r = new OverloadResolution(compilation, args);\n\t\t\tforeach (var method in container.GetMethods(m => m.Name == \"Method\"))\n\t\t\t{\n\t\t\t\tAssert.That(r.AddCandidate(method), Is.EqualTo(OverloadResolutionErrors.None));\n\t\t\t}\n\n\t\t\tAssert.That(r.BestCandidate, Is.EqualTo(container.GetMethods(m => m.Name == \"Method\").Last()));\n\t\t}\n\n\t\tclass BetterFunctionMemberIsNotTransitiveTestCase\n\t\t{\n\t\t\tstatic void Method(Action<string> a) { }\n\t\t\tstatic void Method<T>(Func<string, T> a) { }\n\t\t\tstatic void Method(Action<object> a) { }\n\t\t\tstatic void Method<T>(Func<object, T> a) { }\n\n\t\t\tpublic static void Main(string[] args)\n\t\t\t{\n\t\t\t\tMethod(a => a.ToString());\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestAssemblyResolver.cs",
    "content": "using System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.PortableExecutable;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.Decompiler.Tests\n{\n\tsealed class TestAssemblyResolver : UniversalAssemblyResolver\n\t{\n\t\treadonly HashSet<string> localAssemblies = new HashSet<string>();\n\n\t\tpublic TestAssemblyResolver(string mainAssemblyFileName, string baseDir, string targetFramework)\n\t\t\t: base(mainAssemblyFileName, false, targetFramework, null, PEStreamOptions.PrefetchMetadata, MetadataReaderOptions.ApplyWindowsRuntimeProjections)\n\t\t{\n\t\t\tvar assemblyNames = new DirectoryInfo(baseDir).EnumerateFiles(\"*.dll\").Select(f => Path.GetFileNameWithoutExtension(f.Name));\n\t\t\tforeach (var name in assemblyNames)\n\t\t\t{\n\t\t\t\tlocalAssemblies.Add(name);\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool IsGacAssembly(IAssemblyReference reference)\n\t\t{\n\t\t\treturn reference != null && !localAssemblies.Contains(reference.Name);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/Async.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#pragma warning disable 1998\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tpublic class Async\n\t{\n\t\tpublic static void Main()\n\t\t{\n\t\t\tnew Async().Run().Wait();\n\t\t}\n\n\t\tpublic async Task Run()\n\t\t{\n\t\t\tConsole.WriteLine(\"SimpleBoolTaskMethod:\");\n\t\t\tawait SimpleBoolTaskMethod();\n\t\t\tConsole.WriteLine(\"StreamCopyTo:\");\n\t\t\tStreamCopyTo(new MemoryStream(new byte[1024]), 16);\n\t\t\tConsole.WriteLine(\"StreamCopyToWithConfigureAwait:\");\n\t\t\tStreamCopyToWithConfigureAwait(new MemoryStream(new byte[1024]), 16);\n\t\t\tConsole.WriteLine(\"AwaitInForEach:\");\n\t\t\tawait AwaitInForEach(Enumerable.Range(0, 100).Select(i => Task.FromResult(i)));\n\t\t\tConsole.WriteLine(\"TaskMethodWithoutAwaitButWithExceptionHandling:\");\n\t\t\tawait TaskMethodWithoutAwaitButWithExceptionHandling();\n#if CS60\n\t\t\tConsole.WriteLine($\"{nameof(AwaitCatch)}:\");\n\t\t\tawait AwaitCatch(Task.FromResult(1));\n\t\t\tConsole.WriteLine($\"{nameof(AwaitMultipleCatchBlocks)}:\");\n\t\t\tawait AwaitMultipleCatchBlocks(Task.FromResult(1));\n\t\t\tConsole.WriteLine($\"{nameof(AwaitMultipleCatchBlocks2)}:\");\n\t\t\tawait AwaitMultipleCatchBlocks2(Task.FromResult(1));\n\t\t\tConsole.WriteLine($\"{nameof(AwaitInComplexFinally)}:\");\n\t\t\tConsole.WriteLine(await AwaitInComplexFinally());\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine($\"{nameof(AwaitFinally)}:\");\n\t\t\t\tawait AwaitFinally(Task.FromResult(2));\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex + \" caught!\");\n\t\t\t}\n#endif\n\t\t\tConsole.WriteLine(\"NestedAwait:\");\n\t\t\tawait NestedAwait(Task.FromResult(Task.FromResult(5)));\n\t\t\tConsole.WriteLine(\"AwaitWithStack:\");\n\t\t\tawait AwaitWithStack(Task.FromResult(3));\n\t\t\tConsole.WriteLine(\"AwaitWithStack2:\");\n\t\t\tawait AwaitWithStack2(Task.FromResult(4));\n#if CS60\n\t\t\tConsole.WriteLine($\"{nameof(AwaitInCatch)}:\");\n\t\t\tawait AwaitInCatch(Task.FromResult(1), Task.FromResult(2));\n\t\t\tConsole.WriteLine($\"{nameof(AwaitInFinally)}:\");\n\t\t\tawait AwaitInFinally(Task.FromResult(2), Task.FromResult(4));\n\t\t\tConsole.WriteLine($\"{nameof(AwaitInCatchAndFinally)}:\");\n\t\t\tawait AwaitInCatchAndFinally(Task.FromResult(3), Task.FromResult(6), Task.FromResult(9));\n\t\t\tConsole.WriteLine($\"{nameof(AwaitInFinallyInUsing)}:\");\n\t\t\tConsole.WriteLine(await AwaitInFinallyInUsing(Task.FromResult<IDisposable>(new StringWriter()), Task.FromResult(6), Task.FromResult(9)));\n#endif\n\t\t}\n\n\t\tpublic async Task<bool> SimpleBoolTaskMethod()\n\t\t{\n\t\t\tConsole.WriteLine(\"Before\");\n\t\t\tawait Task.Delay(TimeSpan.FromSeconds(1.0));\n\t\t\tConsole.WriteLine(\"After\");\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic async void StreamCopyTo(Stream destination, int bufferSize)\n\t\t{\n\t\t\tConsole.WriteLine(\"Before\");\n\t\t\tbyte[] array = new byte[bufferSize];\n\t\t\tint count;\n\t\t\tConsole.WriteLine(\"BeforeLoop\");\n\t\t\twhile ((count = await destination.ReadAsync(array, 0, array.Length)) != 0)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"In Loop after condition!\");\n\t\t\t\tawait destination.WriteAsync(array, 0, count);\n\t\t\t\tConsole.WriteLine(\"In Loop after inner await\");\n\t\t\t}\n\t\t\tConsole.WriteLine(\"After\");\n\t\t}\n\n\t\tpublic async void StreamCopyToWithConfigureAwait(Stream destination, int bufferSize)\n\t\t{\n\t\t\tConsole.WriteLine(\"Before\");\n\t\t\tbyte[] array = new byte[bufferSize];\n\t\t\tint count;\n\t\t\tConsole.WriteLine(\"Before Loop\");\n\t\t\twhile ((count = await destination.ReadAsync(array, 0, array.Length).ConfigureAwait(false)) != 0)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Before Inner Await\");\n\t\t\t\tawait destination.WriteAsync(array, 0, count).ConfigureAwait(false);\n\t\t\t\tConsole.WriteLine(\"After Inner Await\");\n\t\t\t}\n\t\t\tConsole.WriteLine(\"After\");\n\t\t}\n\n\t\tpublic async Task<int> AwaitInForEach(IEnumerable<Task<int>> elements)\n\t\t{\n\t\t\tint num = 0;\n\t\t\tConsole.WriteLine(\"Before Loop\");\n\t\t\tforeach (Task<int> current in elements)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Before Inner Await\");\n\t\t\t\tnum += await current;\n\t\t\t\tConsole.WriteLine(\"After Inner Await\");\n\t\t\t}\n\t\t\tConsole.WriteLine(\"After\");\n\t\t\treturn num;\n\t\t}\n\n\t\tpublic async Task TaskMethodWithoutAwaitButWithExceptionHandling()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tusing (new StringWriter())\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"No Await\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Crash\");\n\t\t\t}\n\t\t}\n\n#if CS60\n\t\tpublic async Task AwaitCatch(Task<int> task)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Before throw\");\n\t\t\t\tthrow new Exception();\n\t\t\t}\n\t\t\tcatch\n\t\t\t{\n\t\t\t\tConsole.WriteLine(await task);\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task AwaitMultipleCatchBlocks(Task<int> task)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Before throw\");\n\t\t\t\tthrow new Exception();\n\t\t\t}\n\t\t\tcatch (OutOfMemoryException ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.ToString());\n\t\t\t\tConsole.WriteLine(await task);\n\t\t\t}\n\t\t\tcatch\n\t\t\t{\n\t\t\t\tConsole.WriteLine(await task);\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task AwaitMultipleCatchBlocks2(Task<int> task)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Before throw\");\n\t\t\t\tthrow new Exception();\n\t\t\t}\n\t\t\tcatch (OutOfMemoryException ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.ToString());\n\t\t\t\tConsole.WriteLine(await task);\n\t\t\t}\n\t\t\tcatch (InternalBufferOverflowException ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.ToString());\n\t\t\t}\n\t\t\tcatch\n\t\t\t{\n\t\t\t\tConsole.WriteLine(await task);\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task AwaitFinally(Task<int> task)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Before throw\");\n\t\t\t\tthrow new Exception();\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(await task);\n\t\t\t}\n\t\t}\n#endif\n\n\t\tpublic async Task<int> NestedAwait(Task<Task<int>> task)\n\t\t{\n\t\t\treturn await (await task);\n\t\t}\n\n\t\tpublic async Task AwaitWithStack(Task<int> task)\n\t\t{\n\t\t\tConsole.WriteLine(\"A\", 1, await task);\n\t\t}\n\n\t\tpublic async Task AwaitWithStack2(Task<int> task)\n\t\t{\n\t\t\tif (await this.SimpleBoolTaskMethod())\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"A\", 1, await task);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tint num = 1;\n\t\t\t\tConsole.WriteLine(\"A\", 1, num);\n\t\t\t}\n\t\t}\n\n#if CS60\n\t\tpublic async Task AwaitInCatch(Task<int> task1, Task<int> task2)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Start try\");\n\t\t\t\tawait task1;\n\t\t\t\tConsole.WriteLine(\"End try\");\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Start catch\");\n\t\t\t\tawait task2;\n\t\t\t\tConsole.WriteLine(\"End catch\");\n\t\t\t}\n\t\t\tConsole.WriteLine(\"End Method\");\n\t\t}\n\n\t\tpublic async Task AwaitInFinally(Task<int> task1, Task<int> task2)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Start try\");\n\t\t\t\tawait task1;\n\t\t\t\tConsole.WriteLine(\"End try\");\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Start finally\");\n\t\t\t\tawait task2;\n\t\t\t\tConsole.WriteLine(\"End finally\");\n\t\t\t}\n\t\t\tConsole.WriteLine(\"End Method\");\n\t\t}\n\n\t\tpublic static async Task<int> AwaitInComplexFinally()\n\t\t{\n\t\t\tConsole.WriteLine(\"a\");\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"b\");\n\t\t\t\tawait Task.Delay(1);\n\t\t\t\tConsole.WriteLine(\"c\");\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tawait Task.Delay(ex.HResult);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"d\");\n\t\t\t\tint i = 0;\n\t\t\t\tif (Console.CapsLock)\n\t\t\t\t{\n\t\t\t\t\ti++;\n\t\t\t\t\tawait Task.Delay(i);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\twhile (i < 5)\n\t\t\t\t\t{\n\t\t\t\t\t\tConsole.WriteLine(\"i: \" + i);\n\t\t\t\t\t\ti++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(\"e\");\n\t\t\t}\n\t\t\tConsole.WriteLine(\"f\");\n\t\t\treturn 1;\n\t\t}\n\n\t\tpublic async Task AwaitInCatchAndFinally(Task<int> task1, Task<int> task2, Task<int> task3)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Start try\");\n\t\t\t\tawait task1;\n\t\t\t\tConsole.WriteLine(\"End try\");\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Start catch\");\n\t\t\t\tawait task2;\n\t\t\t\tConsole.WriteLine(\"End catch\");\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Start finally\");\n\t\t\t\tawait task3;\n\t\t\t\tConsole.WriteLine(\"End finally\");\n\t\t\t}\n\t\t\tConsole.WriteLine(\"End Method\");\n\t\t}\n\n\t\tpublic async Task<int> AwaitInFinallyInUsing(Task<IDisposable> task1, Task<int> task2, Task<int> task3)\n\t\t{\n\t\t\tusing (await task1)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Start using\");\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Before return\");\n\t\t\t\t\treturn await task2;\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Start finally\");\n\t\t\t\t\tawait task3;\n\t\t\t\t\tConsole.WriteLine(\"End finally\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n#endif\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/BitNot.il",
    "content": ".assembly extern mscorlib\n{\n\t.publickeytoken = ( b7 7a 5c 56 19 34 e0 89 )\n\t.ver 4:0:0:0\n}\n\n.assembly 'ConvTest'\n{\n\t.ver 0:0:0:0\n}\n\n.module ConvTest.exe\n.corflags 0x00000001 // ILOnly\n\n.class private auto ansi abstract sealed beforefieldinit Program\n\textends [mscorlib]System.Object\n{\n\t.method public hidebysig static void Main (string[] args) cil managed \n\t{\n\t\t.maxstack 8\n\t\t.entrypoint\n\n\t\tldc.i8 0xCCCCCCCCCCCCCCCC\n\t\tcall int64 Program::BitwiseComplementInNativeSize(int64)\n\t\tcall void Program::PrintHex(int64)\n\t\t\n\t\tldc.i4 0x99999999\n\t\tcall int64 Program::BitwiseComplementWithUndersizedValue(int32)\n\t\tcall void Program::PrintHex(int64)\n\t\t\n\t\tldc.i4 0x9999\n\t\tcall int32 Program::BitwiseComplementWithSmallInteger(uint16)\n\t\tcall void Program::PrintHex(int32)\n\t\t\n\t\tldc.i4 0x9999\n\t\tcall int32 Program::BitwiseComplementWithSmallEnum(valuetype Enums.EUInt16)\n\t\tcall void Program::PrintHex(int32)\n\t\t\n\t\tret\n\t} // end of method Main\n\t\n\t.method public static int64 BitwiseComplementInNativeSize(int64 val)\n\t{\n\t\tldarg.0\n\t\tconv.i    // truncate 64-bits to native-size bits\n\t\tnot       // negate those native size bits\n\t\tconv.i8   // sign extend back to 64-bits\n\t\tret\n\t}\n\t\n\t.method public static int64 BitwiseComplementWithUndersizedValue(int32 val)\n\t{\n\t\tldarg.0\n\t\tconv.u8   // zero extend up to 64-bits\n\t\tnot       // negate those 64-bits\n\t\tret\n\t}\n\t\n\t.method public static int32 BitwiseComplementWithSmallInteger(uint16 val)\n\t{\n\t\tldarg.0  // zero extend up to 32-bits\n\t\tnot      // negate those 32-bits\n\t\tret\n\t}\n\t\n\t.method public static int32 BitwiseComplementWithSmallEnum(valuetype Enums.EUInt16 val)\n\t{\n\t\tldarg.0  // zero extend up to 32-bits\n\t\tnot      // negate those 32-bits\n\t\tret\n\t}\n\t\n\t.method public static void PrintHex(int32 val)\n\t{\n\t\tldstr \"{0:x8}\"\n\t\tldarg.0\n\t\tbox valuetype [mscorlib]System.UInt32\n\t\tcall void [mscorlib]System.Console::WriteLine(string, object)\n\t\tret\n\t}\n\t\n\t.method public static void PrintHex(int64 val)\n\t{\n\t\tldstr \"{0:x16}\"\n\t\tldarg.0\n\t\tbox valuetype [mscorlib]System.UInt64\n\t\tcall void [mscorlib]System.Console::WriteLine(string, object)\n\t\tret\n\t}\n}\n\n.class public auto ansi sealed Enums.EUInt16\n\textends [mscorlib]System.Enum\n{\n\t.field public specialname uint16 __value\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/Capturing.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tclass Capturing\n\t{\n\t\tstatic void Main(string[] args)\n\t\t{\n\t\t\tTestCase1();\n\t\t\tTestCase2();\n\t\t\tTestCase3();\n\t\t\tTestCase4(\"TestCase4\");\n\t\t\tOutsideLoop();\n\t\t\tInsideLoop();\n\t\t\tOutsideLoopOverArray();\n\t\t\tOutsideLoopOverArray2();\n\t\t\tInsideLoopOverArray2();\n\t\t\tNotWhileDueToVariableInsideLoop();\n\t\t\tNotDoWhileDueToVariableInsideLoop();\n\t\t\tIssue1936();\n\t\t}\n\n\t\tstatic void TestCase1()\n\t\t{\n\t\t\tConsole.WriteLine(\"TestCase1\");\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t\tConsole.WriteLine(i);\n\t\t\t// i no longer declared\n\t\t\tList<Action> actions = new List<Action>();\n\t\t\tint max = 5;\n\t\t\tstring line;\n\t\t\twhile (ReadLine(out line, ref max))\n\t\t\t{\n\t\t\t\tactions.Add(() => Console.WriteLine(line));\n\t\t\t}\n\t\t\t// line still declared\n\t\t\tline = null;\n\t\t\tConsole.WriteLine(\"----\");\n\t\t\tforeach (var action in actions)\n\t\t\t\taction();\n\t\t}\n\n\t\tstatic void TestCase2()\n\t\t{\n\t\t\tConsole.WriteLine(\"TestCase2\");\n\t\t\tList<Action> actions = new List<Action>();\n\t\t\tint max = 5;\n\t\t\tstring line;\n\t\t\twhile (ReadLine(out line, ref max))\n\t\t\t{\n\t\t\t\tstring capture = line;\n\t\t\t\tactions.Add(() => Console.WriteLine(capture));\n\t\t\t}\n\t\t\t// line still declared\n\t\t\tline = null;\n\t\t\tConsole.WriteLine(\"----\");\n\t\t\tforeach (var action in actions)\n\t\t\t\taction();\n\t\t}\n\n\t\tstatic void TestCase3()\n\t\t{\n\t\t\tConsole.WriteLine(\"TestCase3\");\n\t\t\tList<Action> actions = new List<Action>();\n\t\t\tint max = 5;\n\t\t\tstring line, capture;\n\t\t\twhile (ReadLine(out line, ref max))\n\t\t\t{\n\t\t\t\tcapture = line;\n\t\t\t\tactions.Add(() => Console.WriteLine(capture));\n\t\t\t}\n\t\t\t// line still declared\n\t\t\tline = null;\n\t\t\tConsole.WriteLine(\"----\");\n\t\t\tforeach (var action in actions)\n\t\t\t\taction();\n\t\t}\n\n\t\tstatic void TestCase4(string capture)\n\t\t{\n\t\t\tConsole.WriteLine(\"TestCase4\");\n\t\t\tList<Action> actions = new List<Action>();\n\t\t\tactions.Add(() => Console.WriteLine(capture));\n\t\t\tConsole.WriteLine(\"----\");\n\t\t\tforeach (var action in actions)\n\t\t\t\taction();\n\t\t}\n\n\t\tprivate static bool ReadLine(out string line, ref int v)\n\t\t{\n\t\t\tline = v + \" line\";\n\t\t\treturn --v > 0;\n\t\t}\n\n\t\tstatic void OutsideLoop()\n\t\t{\n\t\t\tConsole.WriteLine(\"OutsideLoop\");\n\t\t\tvar list = new List<int> { 1, 2, 3 };\n\t\t\tvar functions = new List<Func<int>>();\n\t\t\tusing (var e = list.GetEnumerator())\n\t\t\t{\n\t\t\t\tint val; // declared outside loop\n\t\t\t\t\t\t // The decompiler cannot convert this to a foreach-loop without\n\t\t\t\t\t\t // changing the lambda capture semantics.\n\t\t\t\twhile (e.MoveNext())\n\t\t\t\t{\n\t\t\t\t\tval = e.Current;\n\t\t\t\t\tfunctions.Add(() => val);\n\t\t\t\t}\n\t\t\t}\n\t\t\tforeach (var func in functions)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(func());\n\t\t\t}\n\t\t}\n\n\t\tstatic void InsideLoop()\n\t\t{\n\t\t\tConsole.WriteLine(\"InsideLoop\");\n\t\t\tvar list = new List<int> { 1, 2, 3 };\n\t\t\tvar functions = new List<Func<int>>();\n\t\t\tusing (var e = list.GetEnumerator())\n\t\t\t{\n\t\t\t\twhile (e.MoveNext())\n\t\t\t\t{\n\t\t\t\t\tint val = e.Current;\n\t\t\t\t\tfunctions.Add(() => val);\n\t\t\t\t}\n\t\t\t}\n\t\t\tforeach (var func in functions)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(func());\n\t\t\t}\n\t\t}\n\n\t\tstatic void OutsideLoopOverArray()\n\t\t{\n\t\t\tConsole.WriteLine(\"OutsideLoopOverArray:\");\n\t\t\tvar functions = new List<Func<int>>();\n\t\t\tvar array = new int[] { 1, 2, 3 };\n\t\t\tint val; // declared outside loop\n\t\t\t\t\t // The decompiler cannot convert this to a foreach-loop without\n\t\t\t\t\t // changing the lambda capture semantics.\n\t\t\tfor (int i = 0; i < array.Length; ++i)\n\t\t\t{\n\t\t\t\tval = array[i];\n\t\t\t\tfunctions.Add(() => val);\n\t\t\t}\n\t\t\tforeach (var func in functions)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(func());\n\t\t\t}\n\t\t}\n\n\t\tstatic void OutsideLoopOverArray2()\n\t\t{\n\t\t\tConsole.WriteLine(\"OutsideLoopOverArray2:\");\n\t\t\tvar functions = new List<Func<int>>();\n\t\t\tvar array = new int[] { 1, 2, 3 };\n\t\t\tint val; // declared outside loop\n\t\t\t\t\t // The decompiler can convert this to a foreach-loop, but the 'val'\n\t\t\t\t\t // variable must be declared outside.\n\t\t\tfor (int i = 0; i < array.Length; ++i)\n\t\t\t{\n\t\t\t\tint element = array[i];\n\t\t\t\tval = element * 2;\n\t\t\t\tfunctions.Add(() => val);\n\t\t\t}\n\t\t\tforeach (var func in functions)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(func());\n\t\t\t}\n\t\t}\n\n\t\tstatic void InsideLoopOverArray2()\n\t\t{\n\t\t\tConsole.WriteLine(\"InsideLoopOverArray2:\");\n\t\t\tvar functions = new List<Func<int>>();\n\t\t\tvar array = new int[] { 1, 2, 3 };\n\t\t\tfor (int i = 0; i < array.Length; ++i)\n\t\t\t{\n\t\t\t\tint element = array[i];\n\t\t\t\tint val = element * 2;\n\t\t\t\tfunctions.Add(() => val);\n\t\t\t}\n\t\t\tforeach (var func in functions)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(func());\n\t\t\t}\n\t\t}\n\n\t\tstatic int nextVal;\n\n\t\tstatic int GetVal()\n\t\t{\n\t\t\treturn ++nextVal & 7;\n\t\t}\n\n\t\tstatic void NotWhileDueToVariableInsideLoop()\n\t\t{\n\t\t\tConsole.WriteLine(\"NotWhileDueToVariableInsideLoop:\");\n\t\t\tvar functions = new List<Func<int>>();\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tint v;\n\t\t\t\tif ((v = GetVal()) == 0)\n\t\t\t\t\tbreak;\n\t\t\t\tfunctions.Add(() => v);\n\t\t\t}\n\t\t\tforeach (var f in functions)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(f());\n\t\t\t}\n\t\t}\n\n\t\tstatic void NotDoWhileDueToVariableInsideLoop()\n\t\t{\n\t\t\tConsole.WriteLine(\"NotDoWhileDueToVariableInsideLoop:\");\n\t\t\tvar functions = new List<Func<int>>();\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tint v = GetVal();\n\t\t\t\tfunctions.Add(() => v);\n\t\t\t\tif (v == 0)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tforeach (var f in functions)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(f());\n\t\t\t}\n\t\t}\n\n\t\tpublic static void Issue1936()\n\t\t{\n\t\t\tIEnumerable<object> outerCapture = null;\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tint innerCapture = 0;\n\t\t\t\tAction a = (delegate {\n\t\t\t\t\tList<object> list = new List<object>();\n\t\t\t\t\tConsole.WriteLine(\"before inc: \" + innerCapture);\n\t\t\t\t\t++innerCapture;\n\t\t\t\t\tConsole.WriteLine(\"after inc: \" + innerCapture);\n\t\t\t\t\tConsole.WriteLine(\"before assign: \" + outerCapture);\n\t\t\t\t\touterCapture = outerCapture == null ? list : outerCapture.Concat(list);\n\t\t\t\t\tConsole.WriteLine(\"after assign: \" + outerCapture);\n\t\t\t\t});\n\t\t\t\ta.Invoke();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/ComInterop.cs",
    "content": "using System;\nusing System.Runtime.InteropServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tpublic class ComInterop\n\t{\n\t\tpublic static void Main()\n\t\t{\n\t\t\tConsole.WriteLine(Marshal.GetComSlotForMethodInfo(typeof(IMixedPropsAndMethods).GetMethod(\"MyMethod1\")));\n\t\t\tConsole.WriteLine(Marshal.GetComSlotForMethodInfo(typeof(IMixedPropsAndMethods).GetProperty(\"MyProperty1\").GetMethod));\n\t\t\tConsole.WriteLine(Marshal.GetComSlotForMethodInfo(typeof(IMixedPropsAndMethods).GetMethod(\"MyMethod2\")));\n\t\t\tConsole.WriteLine(Marshal.GetComSlotForMethodInfo(typeof(IMixedPropsAndMethods).GetProperty(\"MyProperty2\").GetMethod));\n\t\t\tConsole.WriteLine(Marshal.GetComSlotForMethodInfo(typeof(IMixedPropsAndMethods).GetProperty(\"MyProperty2\").SetMethod));\n\t\t\tConsole.WriteLine(Marshal.GetComSlotForMethodInfo(typeof(IMixedPropsAndMethods).GetEvent(\"MyEvent1\").AddMethod));\n\t\t\tConsole.WriteLine(Marshal.GetComSlotForMethodInfo(typeof(IMixedPropsAndMethods).GetEvent(\"MyEvent1\").RemoveMethod));\n\t\t}\n\n\t\t[Guid(\"761618B8-3994-449A-A96B-F1FF2795EA85\")]\n\t\t[ComImport]\n\t\t[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]\n\t\tinternal interface IMixedPropsAndMethods\n\t\t{\n\t\t\tint MyMethod1();\n\n\t\t\tint MyProperty1 { get; }\n\t\t\tint MyOverload();\n\n\t\t\tint MyMethod2();\n\n\t\t\tint MyProperty2 { get; set; }\n\n\t\t\tint MyOverload(int x);\n\n\t\t\tevent EventHandler MyEvent1;\n\n\t\t\tint MyMethod3();\n\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/Comparisons.cs",
    "content": "// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Globalization;\n\n#pragma warning disable 652\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tpublic class Comparisons\n\t{\n\t\tpublic static int Main()\n\t\t{\n#pragma warning disable RECS0018 // Comparison of floating point numbers with equality operator\n\t\t\tTestFloatOp(\"==\", (a, b) => a == b);\n\t\t\tTestFloatOp(\"!=\", (a, b) => a != b);\n\t\t\tTestFloatOp(\"<\", (a, b) => a < b);\n\t\t\tTestFloatOp(\">\", (a, b) => a > b);\n\t\t\tTestFloatOp(\"<=\", (a, b) => a <= b);\n\t\t\tTestFloatOp(\">=\", (a, b) => a >= b);\n\t\t\tTestFloatOp(\"!<\", (a, b) => !(a < b));\n\t\t\tTestFloatOp(\"!>\", (a, b) => !(a > b));\n\t\t\tTestFloatOp(\"!<=\", (a, b) => !(a <= b));\n\t\t\tTestFloatOp(\"!>=\", (a, b) => !(a >= b));\n\n\t\t\tTestUInt(0);\n\t\t\tTestUInt(uint.MaxValue);\n\t\t\tTestUShort(0);\n\t\t\tTestUShort(ushort.MaxValue);\n\n\t\t\tConsole.WriteLine(\"Issue2398:\");\n\t\t\tIssue2398(0x100000000);\n\n\t\t\tConsole.WriteLine(\"OverloadedOperators:\");\n\t\t\tConsole.WriteLine(IsNotNull(new OverloadedOperators()));\n\t\t\tConsole.WriteLine(IsNull(new OverloadedOperators()));\n\t\t\tConsole.WriteLine(NullIs(new OverloadedOperators()));\n\t\t\tConsole.WriteLine(NullIsNot(new OverloadedOperators()));\n\t\t\treturn 0;\n\t\t}\n\n\t\tstatic void TestFloatOp(string name, Func<float, float, bool> f)\n\t\t{\n\t\t\tfloat[] vals = { -1, 0, 3, float.PositiveInfinity, float.NaN };\n\t\t\tfor (int i = 0; i < vals.Length; i++)\n\t\t\t{\n\t\t\t\tfor (int j = 0; j < vals.Length; j++)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Float: {0} {1} {2:r} = {3}\",\n\t\t\t\t\t\tvals[i].ToString(\"r\", CultureInfo.InvariantCulture),\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tvals[j].ToString(\"r\", CultureInfo.InvariantCulture),\n\t\t\t\t\t\tf(vals[i], vals[j]));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic T Id<T>(T arg)\n\t\t{\n\t\t\treturn arg;\n\t\t}\n\n\t\tstatic void TestUShort(ushort i)\n\t\t{\n\t\t\tConsole.WriteLine(\"ushort: {0} == ushort.MaxValue = {1}\", i, i == ushort.MaxValue);\n\t\t\tConsole.WriteLine(\"ushort: {0} == -1 = {1}\", i, i == -1);\n\t\t\tConsole.WriteLine(\"ushort: {0} == Id<short>(-1) = {1}\", i, i == Id<short>(-1));\n\t\t\tConsole.WriteLine(\"ushort: {0} == 0x1ffff = {1}\", i, i == 0x1ffff);\n\t\t}\n\n\t\tstatic void TestUInt(uint i)\n\t\t{\n\t\t\tConsole.WriteLine(\"uint: {0} == uint.MaxValue = {1}\", i, i == uint.MaxValue);\n\t\t\tConsole.WriteLine(\"uint: {0} == Id(uint.MaxValue) = {1}\", i, i == Id(uint.MaxValue));\n\t\t\tConsole.WriteLine(\"uint: {0} == -1 = {1}\", i, i == -1);\n\t\t\tConsole.WriteLine(\"uint: {0} == Id(-1) = {1}\", i, i == Id(-1));\n\t\t}\n\n\t\tstatic void Issue2398(long value)\n\t\t{\n\t\t\tif ((int)value != 0)\n\t\t\t\tConsole.WriteLine(\"TRUE\");\n\t\t}\n\n\t\tstatic bool IsNull(OverloadedOperators oo)\n\t\t{\n\t\t\treturn (object)oo == null;\n\t\t}\n\n\t\tstatic bool IsNotNull(OverloadedOperators oo)\n\t\t{\n\t\t\treturn (object)oo != null;\n\t\t}\n\n\t\tstatic bool NullIs(OverloadedOperators oo)\n\t\t{\n\t\t\treturn null == (object)oo;\n\t\t}\n\n\t\tstatic bool NullIsNot(OverloadedOperators oo)\n\t\t{\n\t\t\treturn null != (object)oo;\n\t\t}\n\t}\n\n#pragma warning disable CS0660 // Type defines operator == or operator != but does not override Object.Equals(object o)\n#pragma warning disable CS0661 // Type defines operator == or operator != but does not override Object.GetHashCode()\n\tclass OverloadedOperators\n\t{\n\t\tpublic static bool operator ==(OverloadedOperators oo, object b)\n\t\t{\n\t\t\tthrow new NotSupportedException(\"Not supported to call the user-defined operator\");\n\t\t}\n\n\t\tpublic static bool operator !=(OverloadedOperators oo, object b)\n\t\t{\n\t\t\tthrow new NotSupportedException(\"Not supported to call the user-defined operator\");\n\t\t}\n\n\t\tpublic static bool operator ==(object oo, OverloadedOperators b)\n\t\t{\n\t\t\tthrow new NotSupportedException(\"Not supported to call the user-defined operator\");\n\t\t}\n\n\t\tpublic static bool operator !=(object oo, OverloadedOperators b)\n\t\t{\n\t\t\tthrow new NotSupportedException(\"Not supported to call the user-defined operator\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/CompoundAssignment.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tclass CompoundAssignment\n\t{\n\t\tstatic void Main()\n\t\t{\n\t\t\tPreIncrementProperty();\n\t\t\tPreIncrementIndexer();\n\t\t\tCallTwice();\n\t\t\tUnsignedShiftRightInstanceField();\n\t\t\tUnsignedShiftRightStaticProperty();\n\t\t\tDivideByBigValue();\n\t\t\tOverflow();\n\t\t\tIntPtr_CompoundAssign();\n\t\t}\n\n\t\tstatic void Test(int a, int b)\n\t\t{\n\t\t\tConsole.WriteLine(\"{0} {1}\", a, b);\n\t\t}\n\n\t\tstatic int x;\n\n\t\tstatic int X()\n\t\t{\n\t\t\tConsole.Write(\"X \");\n\t\t\treturn ++x;\n\t\t}\n\n\t\tstatic int instanceCount;\n\t\tint instanceNumber = ++instanceCount;\n\n\t\tint instanceField;\n\n\t\tpublic int InstanceProperty {\n\t\t\tget {\n\t\t\t\tConsole.WriteLine(\"In {0}.get_InstanceProperty\", instanceNumber);\n\t\t\t\treturn instanceField;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tConsole.WriteLine(\"In {0}.set_InstanceProperty, value=\" + value, instanceNumber);\n\t\t\t\tinstanceField = value;\n\t\t\t}\n\t\t}\n\n\t\tstatic int staticField;\n\n\t\tpublic static int StaticProperty {\n\t\t\tget {\n\t\t\t\tConsole.WriteLine(\"In get_StaticProperty\");\n\t\t\t\treturn staticField;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tConsole.WriteLine(\"In set_StaticProperty, value=\" + value);\n\t\t\t\tstaticField = value;\n\t\t\t}\n\t\t}\n\n\t\tstatic short shortField;\n\n\t\tpublic static short ShortProperty {\n\t\t\tget {\n\t\t\t\tConsole.WriteLine(\"In get_ShortProperty\");\n\t\t\t\treturn shortField;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tConsole.WriteLine(\"In set_ShortProperty, value={0}\", value);\n\t\t\t\tshortField = value;\n\t\t\t}\n\t\t}\n\n\t\tstatic byte byteField;\n\n\t\tpublic static byte ByteProperty {\n\t\t\tget {\n\t\t\t\tConsole.WriteLine(\"In get_ByteProperty\");\n\t\t\t\treturn byteField;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tConsole.WriteLine(\"In set_ByteProperty, value={0}\", value);\n\t\t\t\tbyteField = value;\n\t\t\t}\n\t\t}\n\n\t\tIntPtr intPtrField = new IntPtr(IntPtr.Size == 8 ? long.MaxValue : int.MaxValue);\n\n\t\tpublic IntPtr IntPtrProperty {\n\t\t\tget {\n\t\t\t\tConsole.WriteLine(\"In {0}.get_IntPtrProperty\", instanceNumber);\n\t\t\t\treturn intPtrField;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tConsole.WriteLine(\"In {0}.set_IntPtrProperty, value={1}\", instanceNumber, value);\n\t\t\t\tintPtrField = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic static Dictionary<string, int> GetDict()\n\t\t{\n\t\t\tConsole.WriteLine(\"In GetDict()\");\n\t\t\treturn new Dictionary<string, int>() { { GetString(), 5 } };\n\t\t}\n\n\t\tstatic CompoundAssignment GetObject()\n\t\t{\n\t\t\tvar obj = new CompoundAssignment();\n\t\t\tConsole.WriteLine(\"In GetObject() (instance #{0})\", obj.instanceNumber);\n\t\t\treturn obj;\n\t\t}\n\n\t\tstatic string GetString()\n\t\t{\n\t\t\tConsole.WriteLine(\"In GetString()\");\n\t\t\treturn \"the string\";\n\t\t}\n\n\t\tstatic void PreIncrementProperty()\n\t\t{\n\t\t\tConsole.WriteLine(\"PreIncrementProperty:\");\n\t\t\tTest(X(), ++new CompoundAssignment().InstanceProperty);\n\t\t\tTest(X(), ++StaticProperty);\n\t\t}\n\n\t\tstatic void PreIncrementIndexer()\n\t\t{\n\t\t\tConsole.WriteLine(\"PreIncrementIndexer:\");\n\t\t\tTest(X(), ++GetDict()[GetString()]);\n\t\t}\n\n\t\tstatic void CallTwice()\n\t\t{\n\t\t\tConsole.WriteLine(\"CallTwice: instanceField:\");\n\t\t\tGetObject().instanceField = GetObject().instanceField + 1;\n\t\t\tTest(X(), GetObject().instanceField = GetObject().instanceField + 1);\n\t\t\tConsole.WriteLine(\"CallTwice: InstanceProperty:\");\n\t\t\tGetObject().InstanceProperty = GetObject().InstanceProperty + 1;\n\t\t\tTest(X(), GetObject().InstanceProperty = GetObject().InstanceProperty + 1);\n\t\t\tConsole.WriteLine(\"CallTwice: dict indexer:\");\n\t\t\tGetDict()[GetString()] = GetDict()[GetString()] + 1;\n\t\t\tTest(X(), GetDict()[GetString()] = GetDict()[GetString()] + 1);\n\t\t}\n\n\t\tstatic void UnsignedShiftRightInstanceField()\n\t\t{\n#if CS70\n\t\t\tref int f = ref new CompoundAssignment().instanceField;\n\t\t\tTest(X(), f = (int)((uint)f >> 2));\n#endif\n\t\t}\n\n\t\tstatic void UnsignedShiftRightStaticProperty()\n\t\t{\n\t\t\tConsole.WriteLine(\"UnsignedShiftRightStaticProperty:\");\n\t\t\tStaticProperty = -15;\n\t\t\tTest(X(), StaticProperty = (int)((uint)StaticProperty >> 2));\n\n\t\t\tShortProperty = -20;\n\t\t\tShortProperty = (short)((uint)StaticProperty >> 2);\n\n\t\t\tShortProperty = -30;\n\t\t\tShortProperty = (short)((ushort)StaticProperty >> 2);\n\t\t}\n\n\t\tstatic void DivideByBigValue()\n\t\t{\n\t\t\tConsole.WriteLine(\"DivideByBigValue:\");\n\t\t\tByteProperty = 5;\n\t\t\t// can't use \"ByteProperty /= (byte)(byte.MaxValue + 3)\" because that would be division by 2.\n\t\t\tByteProperty = (byte)(ByteProperty / (byte.MaxValue + 3));\n\n\t\t\tByteProperty = 200;\n\t\t\tByteProperty = (byte)(ByteProperty / Id(byte.MaxValue + 3));\n\n\t\t\tShortProperty = short.MaxValue;\n\t\t\tShortProperty = (short)(ShortProperty / (short.MaxValue + 3));\n\t\t}\n\n\t\tstatic void Overflow()\n\t\t{\n\t\t\tConsole.WriteLine(\"Overflow:\");\n\t\t\tByteProperty = 0;\n\t\t\tByteProperty = (byte)checked(ByteProperty + 300);\n\t\t\ttry\n\t\t\t{\n\t\t\t\tByteProperty = checked((byte)(ByteProperty + 300));\n\t\t\t}\n\t\t\tcatch (OverflowException)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Overflow OK\");\n\t\t\t}\n\n\t\t\tByteProperty = 200;\n\t\t\tByteProperty = (byte)checked(ByteProperty + 100);\n\t\t\tByteProperty = 201;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tByteProperty = checked((byte)(ByteProperty + 100));\n\t\t\t}\n\t\t\tcatch (OverflowException)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Overflow OK\");\n\t\t\t}\n\t\t}\n\n\t\tstatic T Id<T>(T val)\n\t\t{\n\t\t\treturn val;\n\t\t}\n\n\t\tstatic void IntPtr_CompoundAssign()\n\t\t{\n\t\t\tConsole.WriteLine(\"IntPtr_CompoundAssign:\");\n#if !MCS\n\t\t\tGetObject().IntPtrProperty -= 2;\n\t\t\tGetObject().IntPtrProperty += 2;\n#endif\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/ConditionalAttr.cs",
    "content": "#define PRINT\n\nusing System;\nusing System.Diagnostics;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tclass ConditionalAttr\n\t{\n\t\t[Conditional(\"PRINT\")]\n\t\tstatic void Print()\n\t\t{\n\t\t\tConsole.WriteLine(\"Text!\");\n\t\t}\n\n\t\tstatic void Main()\n\t\t{\n\t\t\tPrint();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/ControlFlow.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tclass ControlFlow\n\t{\n\t\tpublic static int Main()\n\t\t{\n\t\t\tint result = 0;\n\t\t\tEmptyIf(\"Empty\", ref result);\n\t\t\tEmptyIf(\"test\", ref result);\n\t\t\tNormalIf(\"none\", ref result);\n\t\t\tNormalIf(\"test\", ref result);\n\t\t\tNormalIf2(\"none\", ref result);\n\t\t\tNormalIf2(\"test\", ref result);\n\t\t\tNormalIf3(\"none\", ref result);\n\t\t\tNormalIf3(\"test\", ref result);\n\t\t\tTest(\"none\", ref result);\n\t\t\tTest(\"test\", ref result);\n\t\t\tConsole.WriteLine(result);\n\t\t\tForeachWithAssignment(new int[] { 1, 5, 25 });\n\t\t\tBreakUnlessContinue(true);\n\t\t\tBreakUnlessContinue(false);\n\t\t\tTestConditionals();\n\t\t\tConsole.WriteLine(\"Issue1946:\\n\" + Issue1946());\n\t\t\treturn 0;\n\t\t}\n\n\t\tstatic void EmptyIf(string input, ref int result)\n\t\t{\n\t\t\tif (input.Contains(\"test\"))\n\t\t\t{\n\t\t\t}\n\t\t\tresult = result + 1;\n\t\t\tConsole.WriteLine(\"EmptyIf\");\n\t\t}\n\n\t\tstatic void NormalIf(string input, ref int result)\n\t\t{\n\t\t\tif (input.Contains(\"test\"))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"result\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"else\");\n\t\t\t}\n\t\t\tresult = result + 1;\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\n\t\tstatic void NormalIf2(string input, ref int result)\n\t\t{\n\t\t\tif (input.Contains(\"test\"))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"result\");\n\t\t\t}\n\t\t\tresult = result + 1;\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\n\t\tstatic void NormalIf3(string input, ref int result)\n\t\t{\n\t\t\tif (input.Contains(\"test\"))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"result\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"else\");\n\t\t\t}\n\t\t\tresult = result + 1;\n\t\t}\n\n\t\tstatic void Test(string input, ref int result)\n\t\t{\n\t\t\tforeach (char c in input)\n\t\t\t{\n\t\t\t\tConsole.Write(c);\n\t\t\t\tresult = result + 1;\n\t\t\t}\n\t\t\tif (input.Contains(\"test\"))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"result\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"else\");\n\t\t\t}\n\t\t}\n\n\t\tint Dim2Search(int arg)\n\t\t{\n\t\t\tvar tens = new[] { 10, 20, 30 };\n\t\t\tvar ones = new[] { 1, 2, 3 };\n\n\t\t\tfor (int i = 0; i < tens.Length; i++)\n\t\t\t{\n\t\t\t\tfor (int j = 0; j < ones.Length; j++)\n\t\t\t\t{\n\t\t\t\t\tif (tens[i] + ones[j] == arg)\n\t\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn -1;\n\t\t}\n\n\t\tstatic void ForeachWithAssignment(IEnumerable<int> inputs)\n\t\t{\n\t\t\tConsole.WriteLine(\"ForeachWithAssignment\");\n\t\t\tforeach (int input in inputs)\n\t\t\t{\n\t\t\t\tint i = input;\n\t\t\t\tif (i < 10)\n\t\t\t\t\ti *= 2;\n\t\t\t\tConsole.WriteLine(i);\n\t\t\t}\n\t\t}\n\n\t\tstatic void BreakUnlessContinue(bool b)\n\t\t{\n\t\t\tConsole.WriteLine(\"BreakUnlessContinue({0})\", b);\n\t\t\tfor (int i = 0; i < 5; i++)\n\t\t\t{\n\t\t\t\tif ((i % 3) == 0)\n\t\t\t\t\tcontinue;\n\t\t\t\tConsole.WriteLine(i);\n\t\t\t\tif (b)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"continuing\");\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(\"breaking out of loop\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"BreakUnlessContinue (end)\");\n\t\t}\n\n\t\tstatic void TestConditionals()\n\t\t{\n\t\t\tConsole.WriteLine(CastAfterConditional(0));\n\t\t\tConsole.WriteLine(CastAfterConditional(128));\n\t\t}\n\n\t\tstatic byte CastAfterConditional(int value)\n\t\t{\n\t\t\tbyte answer = (byte)(value == 128 ? 255 : 0);\n\t\t\treturn answer;\n\t\t}\n\n\t\tstatic string Issue1946()\n\t\t{\n\t\t\tstring obj = \"1\";\n\t\t\ttry\n\t\t\t{\n\t\t\t\tobj = \"2\";\n\t\t\t}\n\t\t\tcatch\n\t\t\t{\n\t\t\t\tobj = \"3\";\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tobj = \"4\";\n\t\t\t}\n\t\t\treturn obj;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/Conversions.cs",
    "content": "// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n// #include \"../../../ICSharpCode.Decompiler/Util/CSharpPrimitiveCast.cs\"\n\nusing System;\nusing System.Runtime.CompilerServices;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tpublic class Conversions\n\t{\n\t\tstatic readonly TypeCode[] targetTypes = {\n\t\t\tTypeCode.Char,\n\t\t\tTypeCode.SByte,\n\t\t\tTypeCode.Byte,\n\t\t\tTypeCode.Int16,\n\t\t\tTypeCode.UInt16,\n\t\t\tTypeCode.Int32,\n\t\t\tTypeCode.UInt32,\n\t\t\tTypeCode.Int64,\n\t\t\tTypeCode.UInt64,\n\t\t\tTypeCode.Single,\n\t\t\tTypeCode.Double,\n\t\t\tTypeCode.Decimal\n\t\t};\n\n\t\tstatic object[] inputValues = {\n\t\t\t'\\0',\n\t\t\t'a',\n\t\t\t'\\uFFFE',\n\n\t\t\tsbyte.MinValue,\n\t\t\tsbyte.MaxValue,\n\t\t\t(sbyte)-1,\n\t\t\t(sbyte)1,\n\n\t\t\tbyte.MinValue,\n\t\t\tbyte.MaxValue,\n\t\t\t(byte)1,\n\n\t\t\tshort.MinValue,\n\t\t\tshort.MaxValue,\n\t\t\t(short)-1,\n\t\t\t(short)1,\n\n\t\t\tushort.MinValue,\n\t\t\tushort.MaxValue,\n\t\t\t(ushort)1,\n\n\t\t\tint.MinValue,\n\t\t\tint.MaxValue,\n\t\t\t(int)-1,\n\t\t\t(int)1,\n\n\t\t\tuint.MinValue,\n\t\t\tuint.MaxValue,\n\t\t\t(uint)1,\n\n\t\t\tlong.MinValue,\n\t\t\tlong.MaxValue,\n\t\t\t(long)-1,\n\t\t\t(long)1,\n\n\t\t\tulong.MinValue,\n\t\t\tulong.MaxValue,\n\t\t\t(ulong)1,\n\n\t\t\t-1.1f,\n\t\t\t1.1f,\n\t\t\tfloat.MinValue,\n\t\t\tfloat.MaxValue,\n\t\t\tfloat.NegativeInfinity,\n\t\t\tfloat.PositiveInfinity,\n\t\t\tfloat.NaN,\n\n\t\t\t-1.1,\n\t\t\t1.1,\n\t\t\tdouble.MinValue,\n\t\t\tdouble.MaxValue,\n\t\t\tdouble.NegativeInfinity,\n\t\t\tdouble.PositiveInfinity,\n\t\t\tdouble.NaN,\n\n\t\t\tdecimal.MinValue,\n\t\t\tdecimal.MaxValue,\n\t\t\tdecimal.MinusOne,\n\t\t\tdecimal.One\n\t\t};\n\n\t\tstatic void Main(string[] args)\n\t\t{\n\t\t\tRunTest(checkForOverflow: false);\n\t\t\tRunTest(checkForOverflow: true);\n\n\t\t\tConsole.WriteLine(ReadZeroTerminatedString(\"Hello World!\".Length));\n\t\t\tC1.Test();\n#if CS120 && !NET40\n\t\t\tC3.Run();\n#endif\n\t\t}\n\n\t\tstatic void RunTest(bool checkForOverflow)\n\t\t{\n\t\t\tstring mode = checkForOverflow ? \"checked\" : \"unchecked\";\n\t\t\tforeach (object input in inputValues)\n\t\t\t{\n\t\t\t\tstring inputType = input.GetType().Name;\n\t\t\t\tforeach (var targetType in targetTypes)\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tobject result = CSharpPrimitiveCast.Cast(targetType, input, checkForOverflow);\n\t\t\t\t\t\tConsole.WriteLine(\"{0} ({1})({2}){3} = ({4}){5}\", mode, targetType, inputType, input,\n\t\t\t\t\t\t\t\t\t\t  result.GetType().Name, result);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (Exception ex)\n\t\t\t\t\t{\n\t\t\t\t\t\tConsole.WriteLine(\"{0} ({1})({2}){3} = {4}\", mode, targetType, inputType, input,\n\t\t\t\t\t\t\t\t\t\t  ex.GetType().Name);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic object MM(sbyte c)\n\t\t{\n\t\t\tchecked\n\t\t\t{\n\t\t\t\treturn (UInt64)c;\n\t\t\t}\n\t\t}\n\n\t\tstatic string ReadZeroTerminatedString(int length)\n\t\t{\n\t\t\tint read = 0;\n\t\t\tvar buffer = new char[length];\n\t\t\tvar bytes = ReadBytes(length);\n\t\t\twhile (read < length)\n\t\t\t{\n\t\t\t\tvar current = bytes[read];\n\t\t\t\tif (current == 0)\n\t\t\t\t\tbreak;\n\n\t\t\t\tbuffer[read++] = (char)current;\n\t\t\t}\n\n\t\t\treturn new string(buffer, 0, read);\n\t\t}\n\n\t\tstatic byte[] ReadBytes(int length)\n\t\t{\n\t\t\treturn System.Text.Encoding.ASCII.GetBytes(\"Hello World!\");\n\t\t}\n\t}\n\n\tclass C1\n\t{\n\t\tpublic static implicit operator Type(C1 c)\n\t\t{\n\t\t\treturn c.GetType();\n\t\t}\n\n\t\tpublic static void Test()\n\t\t{\n\t\t\tConsole.WriteLine(\"op_Implicit tests\");\n\t\t\tExplicitUseOfImplicitConversion(new C1());\n\t\t\tConsole.WriteLine(ChainedImplicitConversions(new C2()).Name);\n\t\t}\n\n\t\tstatic void ExplicitUseOfImplicitConversion(C1 c)\n\t\t{\n\t\t\tConsole.WriteLine(((Type)c).Name);\n\t\t}\n\n\t\tstatic Type ChainedImplicitConversions(C2 c)\n\t\t{\n\t\t\treturn (C1)c;\n\t\t}\n\t}\n\n\tclass C2\n\t{\n\t\tpublic static implicit operator C1(C2 c)\n\t\t{\n\t\t\treturn new C1();\n\t\t}\n\t}\n\n#if CS120 && !NET40\n\tclass C3\n\t{\n\t\t[InlineArray(4)] struct MyArray { private int elem; }\n\n\t\tstatic void Foo(object o)\n\t\t{\n\t\t\tConsole.WriteLine(\"Foo(object) called\");\n\t\t}\n\n\t\tstatic void Foo(ReadOnlySpan<int> o)\n\t\t{\n\t\t\tConsole.WriteLine(\"Foo(ReadOnlySpan<int>) called\");\n\t\t}\n\n\t\tstatic void Test(MyArray arr)\n\t\t{\n\t\t\tFoo((object)arr);\n\t\t}\n\n\t\tpublic static void Run()\n\t\t{\n\t\t\tConsole.WriteLine(\"C3.Run() called\");\n\t\t\tTest(default);\n\t\t}\n\t}\n#endif\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/DecimalFields.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\t/// <summary>\n\t/// Description of DecimalFields.\n\t/// </summary>\n\tpublic class DecimalFields\n\t{\n\t\tpublic const decimal field1 = 1.5m;\n\t\tpublic const decimal field2 = decimal.One;\n\t\tpublic const decimal field3 = decimal.MaxValue;\n\t\tpublic const decimal field4 = decimal.MinValue;\n\n\t\tpublic static int Main()\n\t\t{\n\t\t\tConsole.WriteLine(field1);\n\t\t\tConsole.WriteLine(field2);\n\t\t\tConsole.WriteLine(field3);\n\t\t\tConsole.WriteLine(field4);\n\t\t\tConsole.WriteLine(IntToDecimal());\n\t\t\tConsole.WriteLine(UIntToDecimal());\n\t\t\tConsole.WriteLine(LongToDecimal());\n\t\t\tConsole.WriteLine(ULongToDecimal());\n\t\t\treturn 0;\n\t\t}\n\n\t\tpublic static decimal IntToDecimal()\n\t\t{\n\t\t\treturn (decimal)int.MaxValue;\n\t\t}\n\n\t\tpublic static decimal UIntToDecimal()\n\t\t{\n\t\t\treturn (decimal)uint.MaxValue;\n\t\t}\n\n\t\tpublic static decimal LongToDecimal()\n\t\t{\n\t\t\treturn (decimal)long.MaxValue;\n\t\t}\n\n\t\tpublic static decimal ULongToDecimal()\n\t\t{\n\t\t\treturn (decimal)ulong.MaxValue;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/DeconstructionTests.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tclass DeconstructionTests\n\t{\n\t\tpublic static void Main()\n\t\t{\n\t\t\tnew DeconstructionTests().Test();\n\t\t}\n\n\t\tpublic struct MyInt\n\t\t{\n\t\t\tpublic static implicit operator int(MyInt x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"int op_Implicit(MyInt)\");\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tpublic static implicit operator MyInt(int x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"MyInt op_Implicit(int)\");\n\t\t\t\treturn default(MyInt);\n\t\t\t}\n\t\t}\n\n\t\tprivate class DeconstructionSource<T, T2>\n\t\t{\n\t\t\tpublic int Dummy {\n\t\t\t\tget;\n\t\t\t\tset;\n\t\t\t}\n\n\t\t\tpublic void Deconstruct(out T a, out T2 b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Deconstruct\");\n\t\t\t\ta = default(T);\n\t\t\t\tb = default(T2);\n\t\t\t}\n\t\t}\n\n\t\tprivate class AssignmentTargets\n\t\t{\n\t\t\tint id;\n\n\t\t\tpublic AssignmentTargets(int id)\n\t\t\t{\n\t\t\t\tthis.id = id;\n\t\t\t}\n\n\t\t\tpublic int IntField;\n\n\t\t\tpublic int? NullableIntField;\n\n\t\t\tpublic MyInt MyIntField;\n\n\t\t\tpublic MyInt? NullableMyIntField;\n\n\t\t\tpublic MyInt My {\n\t\t\t\tget {\n\t\t\t\t\tConsole.WriteLine($\"{id}.get_My()\");\n\t\t\t\t\treturn default(MyInt);\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t\tConsole.WriteLine($\"{id}.set_My({value})\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic MyInt? NMy {\n\t\t\t\tget {\n\t\t\t\t\tConsole.WriteLine($\"{id}.get_NMy()\");\n\t\t\t\t\treturn default(MyInt?);\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t\tConsole.WriteLine($\"{id}.set_NMy({value})\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic int IntProperty {\n\t\t\t\tget {\n\t\t\t\t\tConsole.WriteLine($\"{id}.get_IntProperty()\");\n\t\t\t\t\treturn default(int);\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t\tConsole.WriteLine($\"{id}.set_IntProperty({value})\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic uint UIntProperty {\n\t\t\t\tget {\n\t\t\t\t\tConsole.WriteLine($\"{id}.get_UIntProperty()\");\n\t\t\t\t\treturn default(uint);\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t\tConsole.WriteLine($\"{id}.set_UIntProperty({value})\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate DeconstructionSource<T, T2> GetSource<T, T2>()\n\t\t{\n\t\t\tConsole.WriteLine(\"GetSource()\");\n\t\t\treturn new DeconstructionSource<T, T2>();\n\t\t}\n\n\t\tprivate (T, T2) GetTuple<T, T2>()\n\t\t{\n\t\t\tConsole.WriteLine(\"GetTuple<T, T2>()\");\n\t\t\treturn default(ValueTuple<T, T2>);\n\t\t}\n\n\t\tprivate (T, T2, T3) GetTuple<T, T2, T3>()\n\t\t{\n\t\t\tConsole.WriteLine(\"GetTuple<T, T2, T3>()\");\n\t\t\treturn default(ValueTuple<T, T2, T3>);\n\t\t}\n\n\t\tprivate AssignmentTargets Get(int i)\n\t\t{\n\t\t\tConsole.WriteLine($\"Get({i})\");\n\t\t\treturn new AssignmentTargets(i);\n\t\t}\n\n\t\tpublic void Test()\n\t\t{\n\t\t\tProperty_NoDeconstruction_SwappedAssignments();\n\t\t\tProperty_NoDeconstruction_SwappedInits();\n\t\t\tProperty_IntToUIntConversion();\n\t\t\tNoDeconstruction_NotUsingConver();\n\t\t\tNoDeconstruction_NotUsingConver_Tuple();\n\t\t\tNullReferenceException_Field_Deconstruction(out _);\n\t\t\tNullReferenceException_RefLocalReferencesField_Deconstruction(out _);\n\t\t\tNullReferenceException_RefLocalReferencesArrayElement_Deconstruction(out _, null);\n\t\t\tDeconstructTupleSameVar((\"a\", \"b\"));\n\t\t\tDeconstructTupleListForEachSameVar(new List<(string, string)> { (\"a\", \"b\") });\n\t\t}\n\n\t\tpublic void Property_NoDeconstruction_SwappedAssignments()\n\t\t{\n\t\t\tConsole.WriteLine(\"Property_NoDeconstruction_SwappedAssignments:\");\n\t\t\tAssignmentTargets customDeconstructionAndConversion = Get(0);\n\t\t\tAssignmentTargets customDeconstructionAndConversion2 = Get(1);\n\t\t\tGetSource<MyInt?, MyInt>().Deconstruct(out MyInt? x, out MyInt y);\n\t\t\tMyInt myInt2 = customDeconstructionAndConversion2.My = y;\n\t\t\tMyInt? myInt4 = customDeconstructionAndConversion.NMy = x;\n\t\t}\n\n\t\tpublic void Property_NoDeconstruction_SwappedInits()\n\t\t{\n\t\t\tConsole.WriteLine(\"Property_NoDeconstruction_SwappedInits:\");\n\t\t\tAssignmentTargets customDeconstructionAndConversion = Get(1);\n\t\t\t(Get(0).NMy, customDeconstructionAndConversion.My) = GetSource<MyInt?, MyInt>();\n\t\t}\n\n\t\tpublic void Property_IntToUIntConversion()\n\t\t{\n\t\t\tConsole.WriteLine(\"Property_IntToUIntConversion:\");\n\t\t\tAssignmentTargets t0 = Get(0);\n\t\t\tAssignmentTargets t1 = Get(1);\n\t\t\tint a;\n\t\t\tuint b;\n\t\t\tGetSource<int, uint>().Deconstruct(out a, out b);\n\t\t\tt0.UIntProperty = (uint)a;\n\t\t\tt1.IntProperty = (int)b;\n\t\t}\n\n\t\tpublic void NoDeconstruction_NotUsingConver()\n\t\t{\n\t\t\tConsole.WriteLine(\"NoDeconstruction_NotUsingConver:\");\n\t\t\tAssignmentTargets t0 = Get(0);\n\t\t\tint a;\n\t\t\tuint b;\n\t\t\tGetSource<int, uint>().Deconstruct(out a, out b);\n\t\t\tlong c = a;\n\t\t\tt0.IntProperty = a;\n\t\t\tt0.UIntProperty = b;\n\t\t\tConsole.WriteLine(c);\n\t\t}\n\n\t\tpublic void NoDeconstruction_NotUsingConver_Tuple()\n\t\t{\n\t\t\tConsole.WriteLine(\"NoDeconstruction_NotUsingConver_Tuple:\");\n\t\t\tAssignmentTargets t0 = Get(0);\n\t\t\tvar t = GetTuple<int, uint>();\n\t\t\tlong c = t.Item1;\n\t\t\tt0.IntProperty = t.Item1;\n\t\t\tt0.UIntProperty = t.Item2;\n\t\t\tConsole.WriteLine(c);\n\t\t}\n\n\t\tpublic void NullReferenceException_Field_Deconstruction(out int a)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tAssignmentTargets t0 = null;\n\t\t\t\t(t0.IntField, a) = GetSource<int, int>();\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\ta = 0;\n\t\t\t\tConsole.WriteLine(ex.GetType().FullName);\n\t\t\t}\n\t\t}\n\n\t\tpublic void NullReferenceException_RefLocalReferencesField_Deconstruction(out int a)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tAssignmentTargets t0 = null;\n\t\t\t\tref int i = ref t0.IntField;\n\t\t\t\t(i, a) = GetSource<int, int>();\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\ta = 0;\n\t\t\t\tConsole.WriteLine(ex.GetType().FullName);\n\t\t\t}\n\t\t}\n\n\t\tpublic void NullReferenceException_RefLocalReferencesArrayElement_Deconstruction(out int a, int[] arr)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tref int i = ref arr[0];\n\t\t\t\t(i, a) = GetSource<int, int>();\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\ta = 0;\n\t\t\t\tConsole.WriteLine(ex.GetType().FullName);\n\t\t\t}\n\t\t}\n\n\t\tpublic void DeconstructTupleSameVar((string, string) tuple)\n\t\t{\n\t\t\tConsole.WriteLine(\"DeconstructTupleSameVar:\");\n\t\t\tstring a;\n\t\t\ta = tuple.Item1;\n\t\t\ta = tuple.Item2;\n\t\t\tConsole.WriteLine(a);\n\t\t}\n\n\t\tpublic void DeconstructTupleListForEachSameVar(List<(string, string)> tuples)\n\t\t{\n\t\t\tConsole.WriteLine(\"DeconstructTupleListForEachSameVar:\");\n\t\t\tforeach (var tuple in tuples)\n\t\t\t{\n\t\t\t\tstring a;\n\t\t\t\ta = tuple.Item1;\n\t\t\t\ta = tuple.Item2;\n\t\t\t\tConsole.WriteLine(a);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/DynamicTests.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tclass DynamicTests\n\t{\n\t\tdelegate void RefAction<T>(ref T arg);\n\n\t\tstatic void Main(string[] args)\n\t\t{\n\t\t\tPrintResult((ref dynamic x) => x = x + 2.0, 5.0);\n\t\t\tPrintResult((ref dynamic x) => x = x + 2.0, 5);\n\t\t\tPrintResult((ref dynamic x) => x = x + 2, 5.0);\n\t\t\tPrintResult((ref dynamic x) => x = x + 2, 5);\n\t\t\tPrintResult((ref dynamic x) => x = x - 2.0, 5.0);\n\t\t\tPrintResult((ref dynamic x) => x = x - 2.0, 5);\n\t\t\tPrintResult((ref dynamic x) => x = x - 2, 5.0);\n\t\t\tPrintResult((ref dynamic x) => x = x - 2, 5);\n\t\t\tPrintResult((ref dynamic x) => x = x * 2.0, 5.0);\n\t\t\tPrintResult((ref dynamic x) => x = x * 2.0, 5);\n\t\t\tPrintResult((ref dynamic x) => x = x * 2, 5.0);\n\t\t\tPrintResult((ref dynamic x) => x = x * 2, 5);\n\t\t\tPrintResult((ref dynamic x) => x = x / 2.0, 5.0);\n\t\t\tPrintResult((ref dynamic x) => x = x / 2.0, 5);\n\t\t\tPrintResult((ref dynamic x) => x = x / 2, 5.0);\n\t\t\tPrintResult((ref dynamic x) => x = x / 2, 5);\n\t\t}\n\n\t\tprivate static void PrintResult(RefAction<dynamic> p, dynamic arg)\n\t\t{\n\t\t\tp(ref arg);\n\t\t\tConsole.WriteLine(arg);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/ExpressionTrees.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Linq.Expressions;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tclass ExpressionTrees\n\t{\n\t\tstatic void Main()\n\t\t{\n\t\t\tTest();\n\t\t\tvar twice = GetExpression(Expression.Constant(2)).Compile();\n\t\t\tConsole.WriteLine(twice(21));\n\t\t}\n\n\t\tstatic void Test()\n\t\t{\n\t\t\tint i = 0;\n\t\t\tExpression<Func<int>> expression = () => i;\n\t\t\ti = 1;\n\t\t\tConsole.WriteLine(expression.Compile()());\n\t\t}\n\n\t\tstatic Expression<Func<int, int>> GetExpression(Expression factor)\n\t\t{\n\t\t\tParameterExpression parameterExpression = Expression.Parameter(typeof(int), \"x\");\n\t\t\treturn Expression.Lambda<Func<int, int>>(Expression.Multiply(parameterExpression, factor), parameterExpression);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/FloatingPointArithmetic.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tclass FloatingPointArithmetic\n\t{\n\t\tpublic static int Main(string[] args)\n\t\t{\n\t\t\tIssue999();\n\t\t\tIssue1656();\n\t\t\tIssue1794();\n\t\t\treturn 0;\n\t\t}\n\n\t\tstatic void Issue999()\n\t\t{\n\t\t\tfor (float i = -10f; i <= 10f; i += 0.01f)\n\t\t\t\tConsole.WriteLine(\"{1:R}: {0:R}\", M(i), i);\n\t\t}\n\n\t\tstatic float M(float v)\n\t\t{\n\t\t\treturn 0.99f * v + 0.01f;\n\t\t}\n\n\t\tstatic void Issue1656()\n\t\t{\n\t\t\tdouble primary = 'B';\n\t\t\tCxAssert((++primary) == 'C');\n\t\t\tCxAssert((--primary) == 'B');\n\t\t\tCxAssert((primary++) == 'B');\n\t\t\tCxAssert((primary--) == 'C');\n\t\t}\n\n\t\tstatic void Issue1794()\n\t\t{\n\t\t\tConsole.WriteLine(\"CastUnsignedToFloat:\");\n\t\t\tConsole.WriteLine(CastUnsignedToFloat(9007199791611905).ToString(\"r\"));\n\t\t\tConsole.WriteLine(\"CastUnsignedToDouble:\");\n\t\t\tConsole.WriteLine(CastUnsignedToDouble(9007199791611905).ToString(\"r\"));\n\t\t\tConsole.WriteLine(\"CastUnsignedToFloatViaDouble:\");\n\t\t\tConsole.WriteLine(CastUnsignedToFloatViaDouble(9007199791611905).ToString(\"r\"));\n\n\t\t\tConsole.WriteLine(\"CastSignedToFloat:\");\n\t\t\tConsole.WriteLine(CastSignedToFloat(9007199791611905).ToString(\"r\"));\n\t\t\tConsole.WriteLine(\"ImplicitCastSignedToFloat:\");\n\t\t\tConsole.WriteLine(ImplicitCastSignedToFloat(9007199791611905).ToString(\"r\"));\n\t\t\tConsole.WriteLine(\"CastSignedToDouble:\");\n\t\t\tConsole.WriteLine(CastSignedToDouble(9007199791611905).ToString(\"r\"));\n\t\t\tConsole.WriteLine(\"CastSignedToFloatViaDouble:\");\n\t\t\tConsole.WriteLine(CastSignedToFloatViaDouble(9007199791611905).ToString(\"r\"));\n\t\t}\n\n\t\tstatic float CastUnsignedToFloat(ulong val)\n\t\t{\n\t\t\treturn (float)val;\n\t\t}\n\n\t\tstatic double CastUnsignedToDouble(ulong val)\n\t\t{\n\t\t\treturn (double)val;\n\t\t}\n\n\t\tstatic float CastUnsignedToFloatViaDouble(ulong val)\n\t\t{\n\t\t\t// The double-rounding can increase the rounding error\n\t\t\treturn (float)(double)val;\n\t\t}\n\n\t\tstatic float CastSignedToFloat(long val)\n\t\t{\n\t\t\treturn (float)val;\n\t\t}\n\n\t\tstatic double CastSignedToDouble(long val)\n\t\t{\n\t\t\treturn (double)val;\n\t\t}\n\n\t\tstatic float CastSignedToFloatViaDouble(long val)\n\t\t{\n\t\t\t// The double-rounding can increase the rounding error\n\t\t\treturn (float)(double)val;\n\t\t}\n\n\t\tstatic float ImplicitCastSignedToFloat(long val)\n\t\t{\n\t\t\treturn val;\n\t\t}\n\n\t\tstatic void CxAssert(bool v)\n\t\t{\n\t\t\tif (!v)\n\t\t\t{\n\t\t\t\tthrow new InvalidOperationException();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/Generics.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\t/// <summary>\n\t/// Description of Generics.\n\t/// </summary>\n\tpublic class Generics\n\t{\n\t\tpublic static void Main()\n\t\t{\n\t\t\tConsole.WriteLine(TestGenericReturn<int>());\n\t\t\tConsole.WriteLine(TestGenericReturn<string>());\n\t\t\tTestGenericParam<string>();\n\t\t\tTestGenericParam<int, int>();\n\t\t}\n\n\t\tpublic static T TestGenericReturn<T>()\n\t\t{\n\t\t\treturn default(T);\n\t\t}\n\n\t\tpublic static void TestGenericParam<T>()\n\t\t{\n\t\t\tConsole.WriteLine(typeof(T));\n\t\t}\n\n\t\tpublic static void TestGenericParam<T1, T2>()\n\t\t{\n\t\t\tConsole.WriteLine(typeof(T1) + \" \" + typeof(T2));\n\t\t}\n\t}\n\n\tclass GenericClass<T>\n\t{\n\t\tpublic void M(out GenericClass<T> self)\n\t\t{\n\t\t\tself = this;\n\t\t}\n\t}\n\n\tpublic abstract class BaseClass\n\t{\n\t\tprotected abstract void Method1<T>(T test);\n\t}\n\n\tpublic class DerivedClass : BaseClass\n\t{\n\t\tprotected override void Method1<T>(T test) { }\n\n\t\tprivate void Method2()\n\t\t{\n\t\t\tthis.Method1(0);\n\t\t}\n\t}\n\n\t#region Issue 958 - Invalid cast in generic class for abstract base call\n\tinternal abstract class BaseClass<T>\n\t{\n\t\tprotected abstract void Method1();\n\t}\n\n\tinternal class DerivedClass<T> : BaseClass<T>\n\t{\n\t\tprotected override void Method1() { }\n\n\t\tprivate void Method2()\n\t\t{\n\t\t\tthis.Method1();\n\t\t}\n\t}\n\t#endregion\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/HelloWorld.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tclass HelloWorld\n\t{\n\t\tpublic static int Main(string[] args)\n\t\t{\n\t\t\tConsole.WriteLine(\"Hello World!\");\n\t\t\treturn 0;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/InitializerTests.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\nusing System.Threading;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tpublic class InitializerTests\n\t{\n\t\tpublic static int Main()\n\t\t{\n\t\t\tint[,] test = new int[2, 3];\n\t\t\ttest[0, 0] = 0;\n\t\t\ttest[0, 1] = 1;\n\t\t\ttest[0, 2] = 2;\n\t\t\tint result = test.Length + test[0, 0] + test[0, 2];\n\t\t\tConsole.WriteLine(result);\n\t\t\treturn 0;\n\t\t}\n\n\t\tprivate enum MyEnum\n\t\t{\n\t\t\ta,\n\t\t\tb\n\t\t}\n\n\t\tprivate enum MyEnum2\n\t\t{\n\t\t\tc,\n\t\t\td\n\t\t}\n\n\t\tprivate class Data\n\t\t{\n\t\t\tpublic List<InitializerTests.MyEnum2> FieldList = new List<InitializerTests.MyEnum2>();\n\t\t\tpublic InitializerTests.MyEnum a {\n\t\t\t\tget;\n\t\t\t\tset;\n\t\t\t}\n\t\t\tpublic InitializerTests.MyEnum b {\n\t\t\t\tget;\n\t\t\t\tset;\n\t\t\t}\n\t\t\tpublic List<InitializerTests.MyEnum2> PropertyList {\n\t\t\t\tget;\n\t\t\t\tset;\n\t\t\t}\n\n\t\t\tpublic InitializerTests.Data MoreData {\n\t\t\t\tget;\n\t\t\t\tset;\n\t\t\t}\n\n\t\t\tpublic InitializerTests.StructData NestedStruct {\n\t\t\t\tget;\n\t\t\t\tset;\n\t\t\t}\n\n\t\t\tpublic InitializerTests.Data this[int i] {\n\t\t\t\tget {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tset { }\n\t\t\t}\n\n\t\t\tpublic InitializerTests.Data this[int i, string j] {\n\t\t\t\tget {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tset { }\n\t\t\t}\n\t\t}\n\n\t\tprivate struct StructData\n\t\t{\n\t\t\tpublic int Field;\n\t\t\tpublic int Property {\n\t\t\t\tget;\n\t\t\t\tset;\n\t\t\t}\n\n\t\t\tpublic InitializerTests.Data MoreData {\n\t\t\t\tget;\n\t\t\t\tset;\n\t\t\t}\n\n\t\t\tpublic StructData(int initialValue)\n\t\t\t{\n\t\t\t\tthis = default(InitializerTests.StructData);\n\t\t\t\tthis.Field = initialValue;\n\t\t\t\tthis.Property = initialValue;\n\t\t\t}\n\t\t}\n\n\t\t// Helper methods used to ensure initializers used within expressions work correctly\n\t\tprivate static void X(object a, object b)\n\t\t{\n\t\t}\n\n\t\tprivate static object Y()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static void CollectionInitializerList()\n\t\t{\n\t\t\tInitializerTests.X(InitializerTests.Y(), new List<int>\n\t\t\t\t{\n\t\t\t\t\t1,\n\t\t\t\t\t2,\n\t\t\t\t\t3\n\t\t\t\t});\n\t\t}\n\n\t\tpublic static object RecursiveCollectionInitializer()\n\t\t{\n\t\t\tList<object> list = new List<object>();\n\t\t\tlist.Add(list);\n\t\t\treturn list;\n\t\t}\n\n\t\tpublic static void CollectionInitializerDictionary()\n\t\t{\n\t\t\tInitializerTests.X(InitializerTests.Y(), new Dictionary<string, int>\n\t\t{\n\t\t\t{\n\t\t\t\t\"First\",\n\t\t\t\t1\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"Second\",\n\t\t\t\t2\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"Third\",\n\t\t\t\t3\n\t\t\t}\n\t\t  });\n\t\t}\n\n\t\tpublic static void CollectionInitializerDictionaryWithEnumTypes()\n\t\t{\n\t\t\tInitializerTests.X(InitializerTests.Y(), new Dictionary<InitializerTests.MyEnum, InitializerTests.MyEnum2>\n\t\t{\n\t\t\t{\n\t\t\t\tInitializerTests.MyEnum.a,\n\t\t\t\tInitializerTests.MyEnum2.c\n\t\t\t},\n\t\t\t{\n\t\t\t\tInitializerTests.MyEnum.b,\n\t\t\t\tInitializerTests.MyEnum2.d\n\t\t\t}\n\t\t  });\n\t\t}\n\n\t\tpublic static void NotACollectionInitializer()\n\t\t{\n\t\t\tList<int> list = new List<int>();\n\t\t\tlist.Add(1);\n\t\t\tlist.Add(2);\n\t\t\tlist.Add(3);\n\t\t\tInitializerTests.X(InitializerTests.Y(), list);\n\t\t}\n\n\t\tpublic static void ObjectInitializer()\n\t\t{\n\t\t\tInitializerTests.X(InitializerTests.Y(), new InitializerTests.Data {\n\t\t\t\ta = InitializerTests.MyEnum.a\n\t\t\t});\n\t\t}\n\n\t\tpublic static void NotAnObjectInitializer()\n\t\t{\n\t\t\tInitializerTests.Data data = new InitializerTests.Data();\n\t\t\tdata.a = InitializerTests.MyEnum.a;\n\t\t\tInitializerTests.X(InitializerTests.Y(), data);\n\t\t}\n\n\t\tpublic static void ObjectInitializerAssignCollectionToField()\n\t\t{\n\t\t\tInitializerTests.X(InitializerTests.Y(), new InitializerTests.Data {\n\t\t\t\ta = InitializerTests.MyEnum.a,\n\t\t\t\tFieldList = new List<InitializerTests.MyEnum2>\n\t\t\t\t{\n\t\t\t\t\tInitializerTests.MyEnum2.c,\n\t\t\t\t\tInitializerTests.MyEnum2.d\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic static void ObjectInitializerAddToCollectionInField()\n\t\t{\n\t\t\tInitializerTests.X(InitializerTests.Y(), new InitializerTests.Data {\n\t\t\t\ta = InitializerTests.MyEnum.a,\n\t\t\t\tFieldList =\n\t\t\t\t{\n\t\t\t\t\tInitializerTests.MyEnum2.c,\n\t\t\t\t\tInitializerTests.MyEnum2.d\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic static void ObjectInitializerAssignCollectionToProperty()\n\t\t{\n\t\t\tInitializerTests.X(InitializerTests.Y(), new InitializerTests.Data {\n\t\t\t\ta = InitializerTests.MyEnum.a,\n\t\t\t\tPropertyList = new List<InitializerTests.MyEnum2>\n\t\t\t\t{\n\t\t\t\t\tInitializerTests.MyEnum2.c,\n\t\t\t\t\tInitializerTests.MyEnum2.d\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic static void ObjectInitializerAddToCollectionInProperty()\n\t\t{\n\t\t\tInitializerTests.X(InitializerTests.Y(), new InitializerTests.Data {\n\t\t\t\ta = InitializerTests.MyEnum.a,\n\t\t\t\tPropertyList =\n\t\t\t\t{\n\t\t\t\t\tInitializerTests.MyEnum2.c,\n\t\t\t\t\tInitializerTests.MyEnum2.d\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic static void ObjectInitializerWithInitializationOfNestedObjects()\n\t\t{\n\t\t\tInitializerTests.X(InitializerTests.Y(), new InitializerTests.Data {\n\t\t\t\tMoreData =\n\t\t\t\t{\n\t\t\t\t\ta = InitializerTests.MyEnum.a,\n\t\t\t\t\tMoreData = {\n\t\t\t\t\t\ta = InitializerTests.MyEnum.b\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tstatic int GetInt()\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\n\t\tstatic string GetString()\n\t\t{\n\t\t\treturn \"Test\";\n\t\t}\n\n#if CS60\n\t\tpublic static void SimpleDictInitializer()\n\t\t{\n\t\t\tInitializerTests.X(InitializerTests.Y(), new InitializerTests.Data {\n\t\t\t\tMoreData =\n\t\t\t\t{\n\t\t\t\t\ta = InitializerTests.MyEnum.a,\n\t\t\t\t\t[2] = (Data)null\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic static void MixedObjectAndDictInitializer()\n\t\t{\n\t\t\tInitializerTests.X(InitializerTests.Y(), new InitializerTests.Data {\n\t\t\t\tMoreData =\n\t\t\t\t{\n\t\t\t\t\ta = InitializerTests.MyEnum.a,\n\t\t\t\t\t[GetInt()] = {\n\t\t\t\t\t\ta = InitializerTests.MyEnum.b,\n\t\t\t\t\t\tFieldList = { MyEnum2.c },\n\t\t\t\t\t\t[GetInt(), GetString()] = new Data(),\n\t\t\t\t\t\t[2] = (Data)null\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n#endif\n\n\t\tpublic static void ObjectInitializerWithInitializationOfDeeplyNestedObjects()\n\t\t{\n\t\t\tInitializerTests.X(InitializerTests.Y(), new InitializerTests.Data {\n\t\t\t\ta = InitializerTests.MyEnum.b,\n\t\t\t\tMoreData =\n\t\t\t  {\n\t\t\t\t  a = InitializerTests.MyEnum.a,\n\t\t\t\t  MoreData = { MoreData = { MoreData = { MoreData = { MoreData = { MoreData = { a = MyEnum.b } } } } } }\n\t\t\t  }\n\t\t\t});\n\t\t}\n\n\t\tpublic static void CollectionInitializerInsideObjectInitializers()\n\t\t{\n\t\t\tInitializerTests.Data castPattern = new InitializerTests.Data {\n\t\t\t\tMoreData = new InitializerTests.Data {\n\t\t\t\t\ta = InitializerTests.MyEnum.a,\n\t\t\t\t\tb = InitializerTests.MyEnum.b,\n\t\t\t\t\tPropertyList = { InitializerTests.MyEnum2.c }\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\tpublic static void StructInitializer_DefaultConstructor()\n\t\t{\n\t\t\tInitializerTests.X(InitializerTests.Y(), new InitializerTests.StructData {\n\t\t\t\tField = 1,\n\t\t\t\tProperty = 2\n\t\t\t});\n\t\t}\n\n\t\tpublic static void StructInitializer_ExplicitConstructor()\n\t\t{\n\t\t\tInitializerTests.X(InitializerTests.Y(), new InitializerTests.StructData(0) {\n\t\t\t\tField = 1,\n\t\t\t\tProperty = 2\n\t\t\t});\n\t\t}\n\n\t\tpublic static void StructInitializerWithInitializationOfNestedObjects()\n\t\t{\n\t\t\tInitializerTests.X(InitializerTests.Y(), new InitializerTests.StructData {\n\t\t\t\tMoreData =\n\t\t\t\t{\n\t\t\t\t\ta = InitializerTests.MyEnum.a,\n\t\t\t\t\tFieldList =\n\t\t\t\t\t{\n\t\t\t\t\t\tInitializerTests.MyEnum2.c,\n\t\t\t\t\t\tInitializerTests.MyEnum2.d\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic static void StructInitializerWithinObjectInitializer()\n\t\t{\n\t\t\tInitializerTests.X(InitializerTests.Y(), new InitializerTests.Data {\n\t\t\t\tNestedStruct = new InitializerTests.StructData(2) {\n\t\t\t\t\tField = 1,\n\t\t\t\t\tProperty = 2\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic static void Bug270_NestedInitialisers()\n\t\t{\n\t\t\tNumberFormatInfo[] numberFormats = null;\n\n\t\t\tThread t = new Thread(Bug270_NestedInitialisers) {\n\t\t\t\tPriority = ThreadPriority.BelowNormal,\n\t\t\t\tCurrentCulture = new CultureInfo(0) {\n\t\t\t\t\tDateTimeFormat = new DateTimeFormatInfo {\n\t\t\t\t\t\tShortDatePattern = \"ddmmyy\"\n\t\t\t\t\t},\n\t\t\t\t\tNumberFormat = (from format in numberFormats where format.CurrencySymbol == \"$\" select format).First()\n\t\t\t\t}\n\t\t\t};\n\n\t\t}\n\n#if CS60\n\t\tclass Issue2622a\n\t\t{\n\t\t\tpublic class C\n\t\t\t{\n\t\t\t\tpublic ServiceHost M()\n\t\t\t\t{\n\t\t\t\t\treturn new ServiceHost(typeof(EWSService), null) {\n\t\t\t\t\t\tDescription = { Endpoints = { [0] = { Behaviors = { new EwsWebHttpBehavior() } } } }\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tclass EWSService { }\n\n\t\t\tpublic class ServiceHost\n\t\t\t{\n\t\t\t\tpublic ServiceHost(Type type, object x) { }\n\n\t\t\t\tpublic Descr Description { get; }\n\t\t\t}\n\n\t\t\tpublic class Descr\n\t\t\t{\n\t\t\t\tpublic List<EP> Endpoints { get; }\n\t\t\t}\n\n\t\t\tpublic class EP\n\t\t\t{\n\t\t\t\tpublic List<Beh> Behaviors { get; }\n\t\t\t}\n\n\t\t\tpublic abstract class Beh { }\n\n\t\t\tpublic class EwsWebHttpBehavior : Beh { }\n\t\t}\n#endif\n\n\t\tclass Issue855\n\t\t{\n\t\t\tclass Data\n\t\t\t{\n\t\t\t\tpublic object Obj;\n\t\t\t}\n\n\t\t\tclass Items\n\t\t\t{\n\t\t\t\tpublic void SetItem(int i, object item) { }\n\t\t\t}\n\n\t\t\tobject Item(string s, Data d)\n\t\t\t{\n\t\t\t\treturn new object();\n\t\t\t}\n\n\t\t\tvoid Test()\n\t\t\t{\n\t\t\t\tItems items = null;\n\n\t\t\t\tint num = 0;\n\n\t\t\t\tfor (int i = 0; i < 2; i++)\n\t\t\t\t{\n\t\t\t\t\tif (num < 10)\n\t\t\t\t\t\titems.SetItem(num, Item(string.Empty, new Data { Obj = null }));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/Jmp.il",
    "content": ".assembly extern mscorlib\n{\n\t.publickeytoken = ( b7 7a 5c 56 19 34 e0 89 )\n\t.ver 4:0:0:0\n}\n\n.assembly 'Jmp'\n{\n\t.ver 0:0:0:0\n}\n\n.module Jmp.exe\n.corflags 0x00000001 // ILOnly\n\n.class private auto ansi abstract sealed beforefieldinit Program\n\textends [mscorlib]System.Object\n{\n\t.method public hidebysig static void Main (string[] args) cil managed \n\t{\n\t\t.maxstack 8\n\t\t.entrypoint\n\n\t\tldstr \"Method1(100) = {0}\"\n\t\tldc.i4 100\n\t\tcall int32 Program::Method1(int32)\n\t\tbox int32\n\t\tcall void [mscorlib]System.Console::WriteLine(string, object)\n\t\tret\n\t} // end of method Main\n\t\n  .method public static int32 Method1(int32 val)\n\t{\n    ldarg.0\n    ldc.i4.1\n    add\n    starg.s 0\n    jmp int32 Program::Method2(int32)\n  }\n\t\n\t.method public static int32 Method2(int32 val)\n\t{\n\t\tldarg.0\n\t\tldc.i4.5\n\t\tmul\n\t\tret\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/LINQRaytracer.cs",
    "content": "// This test case is taken from https://blogs.msdn.microsoft.com/lukeh/2007/10/01/taking-linq-to-objects-to-extremes-a-fully-linqified-raytracer/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace RayTracer\n{\n\tpublic class RayTracer\n\t{\n\t\tstatic void Main()\n\t\t{\n\t\t\tconst int width = 50;\n\t\t\tconst int height = 50;\n\n\t\t\tRayTracer rayTracer = new RayTracer(width, height, (int x, int y, Color color) => {\n\t\t\t\tConsole.Write(\"{0},{1}:{2};\", x, y, color);\n\t\t\t});\n\t\t\trayTracer.Render(rayTracer.DefaultScene);\n\t\t}\n\n\t\tprivate int screenWidth;\n\t\tprivate int screenHeight;\n\t\tprivate const int MaxDepth = 5;\n\n\t\tpublic Action<int, int, Color> setPixel;\n\n\t\tpublic RayTracer(int screenWidth, int screenHeight, Action<int, int, Color> setPixel)\n\t\t{\n\t\t\tthis.screenWidth = screenWidth;\n\t\t\tthis.screenHeight = screenHeight;\n\t\t\tthis.setPixel = setPixel;\n\t\t}\n\n\t\tprivate class Wrap<T>\n\t\t{\n\t\t\tpublic readonly Func<Wrap<T>, T> It;\n\t\t\tpublic Wrap(Func<Wrap<T>, T> it) { It = it; }\n\t\t}\n\n\t\tpublic static Func<T, U> Y<T, U>(Func<Func<T, U>, Func<T, U>> f)\n\t\t{\n\t\t\tFunc<Wrap<Func<T, U>>, Func<T, U>> g = wx => f(wx.It(wx));\n\t\t\treturn g(new Wrap<Func<T, U>>(wx => f(y => wx.It(wx)(y))));\n\t\t}\n\n\t\tclass TraceRayArgs\n\t\t{\n\t\t\tpublic readonly Ray Ray;\n\t\t\tpublic readonly Scene Scene;\n\t\t\tpublic readonly int Depth;\n\n\t\t\tpublic TraceRayArgs(Ray ray, Scene scene, int depth) { Ray = ray; Scene = scene; Depth = depth; }\n\t\t}\n\n\t\tinternal void Render(Scene scene)\n\t\t{\n\t\t\tvar pixelsQuery =\n\t\t\t\tfrom y in Enumerable.Range(0, screenHeight)\n\t\t\t\tlet recenterY = -(y - (screenHeight / 2.0)) / (2.0 * screenHeight)\n\t\t\t\tselect from x in Enumerable.Range(0, screenWidth)\n\t\t\t\t\t   let recenterX = (x - (screenWidth / 2.0)) / (2.0 * screenWidth)\n\t\t\t\t\t   let point =\n\t\t\t\t\t\t   Vector.Norm(Vector.Plus(scene.Camera.Forward,\n\t\t\t\t\t\t\t\t\t\t\t\t   Vector.Plus(Vector.Times(recenterX, scene.Camera.Right),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   Vector.Times(recenterY, scene.Camera.Up))))\n\t\t\t\t\t   let ray = new Ray() { Start = scene.Camera.Pos, Dir = point }\n\t\t\t\t\t   let computeTraceRay = (Func<Func<TraceRayArgs, Color>, Func<TraceRayArgs, Color>>)\n\t\t\t\t\t\t(f => traceRayArgs =>\n\t\t\t\t\t\t (from isect in\n\t\t\t\t\t\t\t  from thing in traceRayArgs.Scene.Things\n\t\t\t\t\t\t\t  select thing.Intersect(traceRayArgs.Ray)\n\t\t\t\t\t\t  where isect != null\n\t\t\t\t\t\t  orderby isect.Dist\n\t\t\t\t\t\t  let d = isect.Ray.Dir\n\t\t\t\t\t\t  let pos = Vector.Plus(Vector.Times(isect.Dist, isect.Ray.Dir), isect.Ray.Start)\n\t\t\t\t\t\t  let normal = isect.Thing.Normal(pos)\n\t\t\t\t\t\t  let reflectDir = Vector.Minus(d, Vector.Times(2 * Vector.Dot(normal, d), normal))\n\t\t\t\t\t\t  let naturalColors =\n\t\t\t\t\t\t\t  from light in traceRayArgs.Scene.Lights\n\t\t\t\t\t\t\t  let ldis = Vector.Minus(light.Pos, pos)\n\t\t\t\t\t\t\t  let livec = Vector.Norm(ldis)\n\t\t\t\t\t\t\t  let testRay = new Ray() { Start = pos, Dir = livec }\n\t\t\t\t\t\t\t  let testIsects = from inter in\n\t\t\t\t\t\t\t\t\t\t\t\t   from thing in traceRayArgs.Scene.Things\n\t\t\t\t\t\t\t\t\t\t\t\t   select thing.Intersect(testRay)\n\t\t\t\t\t\t\t\t\t\t\t   where inter != null\n\t\t\t\t\t\t\t\t\t\t\t   orderby inter.Dist\n\t\t\t\t\t\t\t\t\t\t\t   select inter\n\t\t\t\t\t\t\t  let testIsect = testIsects.FirstOrDefault()\n\t\t\t\t\t\t\t  let neatIsect = testIsect == null ? 0 : testIsect.Dist\n\t\t\t\t\t\t\t  let isInShadow = !((neatIsect > Vector.Mag(ldis)) || (neatIsect == 0))\n\t\t\t\t\t\t\t  where !isInShadow\n\t\t\t\t\t\t\t  let illum = Vector.Dot(livec, normal)\n\t\t\t\t\t\t\t  let lcolor = illum > 0 ? Color.Times(illum, light.Color) : Color.Make(0, 0, 0)\n\t\t\t\t\t\t\t  let specular = Vector.Dot(livec, Vector.Norm(reflectDir))\n\t\t\t\t\t\t\t  let scolor = specular > 0\n\t\t\t\t\t\t\t\t\t\t\t ? Color.Times(Math.Pow(specular, isect.Thing.Surface.Roughness),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   light.Color)\n\t\t\t\t\t\t\t\t\t\t\t : Color.Make(0, 0, 0)\n\t\t\t\t\t\t\t  select Color.Plus(Color.Times(isect.Thing.Surface.Diffuse(pos), lcolor),\n\t\t\t\t\t\t\t\t\t\t\t\tColor.Times(isect.Thing.Surface.Specular(pos), scolor))\n\t\t\t\t\t\t  let reflectPos = Vector.Plus(pos, Vector.Times(.001, reflectDir))\n\t\t\t\t\t\t  let reflectColor = traceRayArgs.Depth >= MaxDepth\n\t\t\t\t\t\t\t\t\t\t\t  ? Color.Make(.5, .5, .5)\n\t\t\t\t\t\t\t\t\t\t\t  : Color.Times(isect.Thing.Surface.Reflect(reflectPos),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tf(new TraceRayArgs(new Ray() {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tStart = reflectPos,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tDir = reflectDir\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   traceRayArgs.Scene,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   traceRayArgs.Depth + 1)))\n\t\t\t\t\t\t  select naturalColors.Aggregate(reflectColor,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (color, natColor) => Color.Plus(color, natColor))\n\t\t\t\t\t\t ).DefaultIfEmpty(Color.Background).First())\n\t\t\t\t\t   let traceRay = Y(computeTraceRay)\n\t\t\t\t\t   select new { X = x, Y = y, Color = traceRay(new TraceRayArgs(ray, scene, 0)) };\n\n\t\t\tforeach (var row in pixelsQuery)\n\t\t\t\tforeach (var pixel in row)\n\t\t\t\t\tsetPixel(pixel.X, pixel.Y, pixel.Color);\n\t\t}\n\n\t\tinternal readonly Scene DefaultScene =\n\t\t\tnew Scene() {\n\t\t\t\tThings = new SceneObject[] {\n\t\t\t\t\t\t\t\tnew Plane() {\n\t\t\t\t\t\t\t\t\tNorm = Vector.Make(0,1,0),\n\t\t\t\t\t\t\t\t\tOffset = 0,\n\t\t\t\t\t\t\t\t\tSurface = Surfaces.CheckerBoard\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tnew Sphere() {\n\t\t\t\t\t\t\t\t\tCenter = Vector.Make(0,1,0),\n\t\t\t\t\t\t\t\t\tRadius = 1,\n\t\t\t\t\t\t\t\t\tSurface = Surfaces.Shiny\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tnew Sphere() {\n\t\t\t\t\t\t\t\t\tCenter = Vector.Make(-1,.5,1.5),\n\t\t\t\t\t\t\t\t\tRadius = .5,\n\t\t\t\t\t\t\t\t\tSurface = Surfaces.Shiny\n\t\t\t\t\t\t\t\t}},\n\t\t\t\tLights = new Light[] {\n\t\t\t\t\t\t\t\tnew Light() {\n\t\t\t\t\t\t\t\t\tPos = Vector.Make(-2,2.5,0),\n\t\t\t\t\t\t\t\t\tColor = Color.Make(.49,.07,.07)\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tnew Light() {\n\t\t\t\t\t\t\t\t\tPos = Vector.Make(1.5,2.5,1.5),\n\t\t\t\t\t\t\t\t\tColor = Color.Make(.07,.07,.49)\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tnew Light() {\n\t\t\t\t\t\t\t\t\tPos = Vector.Make(1.5,2.5,-1.5),\n\t\t\t\t\t\t\t\t\tColor = Color.Make(.07,.49,.071)\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tnew Light() {\n\t\t\t\t\t\t\t\t\tPos = Vector.Make(0,3.5,0),\n\t\t\t\t\t\t\t\t\tColor = Color.Make(.21,.21,.35)\n\t\t\t\t\t\t\t\t}},\n\t\t\t\tCamera = Camera.Create(Vector.Make(3, 2, 4), Vector.Make(-1, .5, 0))\n\t\t\t};\n\t}\n\n\tstatic class Surfaces\n\t{\n\t\t// Only works with X-Z plane.\n\t\tpublic static readonly Surface CheckerBoard =\n\t\t\tnew Surface() {\n\t\t\t\tDiffuse = pos => ((Math.Floor(pos.Z) + Math.Floor(pos.X)) % 2 != 0)\n\t\t\t\t\t\t\t\t\t? Color.Make(1, 1, 1)\n\t\t\t\t\t\t\t\t\t: Color.Make(0, 0, 0),\n\t\t\t\tSpecular = pos => Color.Make(1, 1, 1),\n\t\t\t\tReflect = pos => ((Math.Floor(pos.Z) + Math.Floor(pos.X)) % 2 != 0)\n\t\t\t\t\t\t\t\t\t? .1\n\t\t\t\t\t\t\t\t\t: .7,\n\t\t\t\tRoughness = 150\n\t\t\t};\n\n\t\tpublic static readonly Surface Shiny =\n\t\t\tnew Surface() {\n\t\t\t\tDiffuse = pos => Color.Make(1, 1, 1),\n\t\t\t\tSpecular = pos => Color.Make(.5, .5, .5),\n\t\t\t\tReflect = pos => .6,\n\t\t\t\tRoughness = 50\n\t\t\t};\n\t}\n\n\tclass Vector\n\t{\n\t\tpublic readonly double X;\n\t\tpublic readonly double Y;\n\t\tpublic readonly double Z;\n\n\t\tpublic Vector(double x, double y, double z) { X = x; Y = y; Z = z; }\n\n\t\tpublic static Vector Make(double x, double y, double z) { return new Vector(x, y, z); }\n\t\tpublic static Vector Times(double n, Vector v)\n\t\t{\n\t\t\treturn new Vector(v.X * n, v.Y * n, v.Z * n);\n\t\t}\n\t\tpublic static Vector Minus(Vector v1, Vector v2)\n\t\t{\n\t\t\treturn new Vector(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z);\n\t\t}\n\t\tpublic static Vector Plus(Vector v1, Vector v2)\n\t\t{\n\t\t\treturn new Vector(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z);\n\t\t}\n\t\tpublic static double Dot(Vector v1, Vector v2)\n\t\t{\n\t\t\treturn (v1.X * v2.X) + (v1.Y * v2.Y) + (v1.Z * v2.Z);\n\t\t}\n\t\tpublic static double Mag(Vector v) { return Math.Sqrt(Dot(v, v)); }\n\t\tpublic static Vector Norm(Vector v)\n\t\t{\n\t\t\tdouble mag = Mag(v);\n\t\t\tdouble div = mag == 0 ? double.PositiveInfinity : 1 / mag;\n\t\t\treturn Times(div, v);\n\t\t}\n\t\tpublic static Vector Cross(Vector v1, Vector v2)\n\t\t{\n\t\t\treturn new Vector(((v1.Y * v2.Z) - (v1.Z * v2.Y)),\n\t\t\t\t\t\t\t  ((v1.Z * v2.X) - (v1.X * v2.Z)),\n\t\t\t\t\t\t\t  ((v1.X * v2.Y) - (v1.Y * v2.X)));\n\t\t}\n\t\tpublic static bool Equals(Vector v1, Vector v2)\n\t\t{\n\t\t\treturn (v1.X == v2.X) && (v1.Y == v2.Y) && (v1.Z == v2.Z);\n\t\t}\n\t}\n\n\tpublic class Color\n\t{\n\t\tpublic double R;\n\t\tpublic double G;\n\t\tpublic double B;\n\n\t\tpublic Color(double r, double g, double b) { R = r; G = g; B = b; }\n\n\t\tpublic static Color Make(double r, double g, double b) { return new Color(r, g, b); }\n\n\t\tpublic static Color Times(double n, Color v)\n\t\t{\n\t\t\treturn new Color(n * v.R, n * v.G, n * v.B);\n\t\t}\n\t\tpublic static Color Times(Color v1, Color v2)\n\t\t{\n\t\t\treturn new Color(v1.R * v2.R, v1.G * v2.G, v1.B * v2.B);\n\t\t}\n\n\t\tpublic static Color Plus(Color v1, Color v2)\n\t\t{\n\t\t\treturn new Color(v1.R + v2.R, v1.G + v2.G, v1.B + v2.B);\n\t\t}\n\t\tpublic static Color Minus(Color v1, Color v2)\n\t\t{\n\t\t\treturn new Color(v1.R - v2.R, v1.G - v2.G, v1.B - v2.B);\n\t\t}\n\n\t\tpublic static readonly Color Background = Make(0, 0, 0);\n\t\tpublic static readonly Color DefaultColor = Make(0, 0, 0);\n\n\t\tprivate double Legalize(double d)\n\t\t{\n\t\t\treturn d > 1 ? 1 : d;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn string.Format(\"[{0},{1},{2}]\", R, G, B);\n\t\t}\n\t}\n\n\tclass Ray\n\t{\n\t\tpublic Vector Start;\n\t\tpublic Vector Dir;\n\t}\n\n\tclass ISect\n\t{\n\t\tpublic SceneObject Thing;\n\t\tpublic Ray Ray;\n\t\tpublic double Dist;\n\t}\n\n\tclass Surface\n\t{\n\t\tpublic Func<Vector, Color> Diffuse;\n\t\tpublic Func<Vector, Color> Specular;\n\t\tpublic Func<Vector, double> Reflect;\n\t\tpublic double Roughness;\n\t}\n\n\tclass Camera\n\t{\n\t\tpublic Vector Pos;\n\t\tpublic Vector Forward;\n\t\tpublic Vector Up;\n\t\tpublic Vector Right;\n\n\t\tpublic static Camera Create(Vector pos, Vector lookAt)\n\t\t{\n\t\t\tVector forward = Vector.Norm(Vector.Minus(lookAt, pos));\n\t\t\tVector down = new Vector(0, -1, 0);\n\t\t\tVector right = Vector.Times(1.5, Vector.Norm(Vector.Cross(forward, down)));\n\t\t\tVector up = Vector.Times(1.5, Vector.Norm(Vector.Cross(forward, right)));\n\n\t\t\treturn new Camera() { Pos = pos, Forward = forward, Up = up, Right = right };\n\t\t}\n\t}\n\n\tclass Light\n\t{\n\t\tpublic Vector Pos;\n\t\tpublic Color Color;\n\t}\n\n\tabstract class SceneObject\n\t{\n\t\tpublic Surface Surface;\n\t\tpublic abstract ISect Intersect(Ray ray);\n\t\tpublic abstract Vector Normal(Vector pos);\n\t}\n\n\tclass Sphere : SceneObject\n\t{\n\t\tpublic Vector Center;\n\t\tpublic double Radius;\n\n\t\tpublic override ISect Intersect(Ray ray)\n\t\t{\n\t\t\tVector eo = Vector.Minus(Center, ray.Start);\n\t\t\tdouble v = Vector.Dot(eo, ray.Dir);\n\t\t\tdouble dist;\n\t\t\tif (v < 0)\n\t\t\t{\n\t\t\t\tdist = 0;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tdouble disc = Math.Pow(Radius, 2) - (Vector.Dot(eo, eo) - Math.Pow(v, 2));\n\t\t\t\tdist = disc < 0 ? 0 : v - Math.Sqrt(disc);\n\t\t\t}\n\t\t\tif (dist == 0)\n\t\t\t\treturn null;\n\t\t\treturn new ISect() {\n\t\t\t\tThing = this,\n\t\t\t\tRay = ray,\n\t\t\t\tDist = dist\n\t\t\t};\n\t\t}\n\n\t\tpublic override Vector Normal(Vector pos)\n\t\t{\n\t\t\treturn Vector.Norm(Vector.Minus(pos, Center));\n\t\t}\n\t}\n\n\tclass Plane : SceneObject\n\t{\n\t\tpublic Vector Norm;\n\t\tpublic double Offset;\n\n\t\tpublic override ISect Intersect(Ray ray)\n\t\t{\n\t\t\tdouble denom = Vector.Dot(Norm, ray.Dir);\n\t\t\tif (denom > 0)\n\t\t\t\treturn null;\n\t\t\treturn new ISect() {\n\t\t\t\tThing = this,\n\t\t\t\tRay = ray,\n\t\t\t\tDist = (Vector.Dot(Norm, ray.Start) + Offset) / (-denom)\n\t\t\t};\n\t\t}\n\n\t\tpublic override Vector Normal(Vector pos)\n\t\t{\n\t\t\treturn Norm;\n\t\t}\n\t}\n\n\tclass Scene\n\t{\n\t\tpublic SceneObject[] Things;\n\t\tpublic Light[] Lights;\n\t\tpublic Camera Camera;\n\n\t\tpublic IEnumerable<ISect> Intersect(Ray r)\n\t\t{\n\t\t\treturn from thing in Things\n\t\t\t\t   select thing.Intersect(r);\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/Loops.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tclass Loops\n\t{\n\t\tpublic class CustomClassEnumeratorWithIDisposable<T> : IDisposable\n\t\t{\n\t\t\tbool next = true;\n\n\t\t\tpublic T Current {\n\t\t\t\tget {\n\t\t\t\t\treturn default(T);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic void Dispose()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"CustomClassEnumeratorWithIDisposable<T>.Dispose()\");\n\t\t\t}\n\n\t\t\tpublic bool MoveNext()\n\t\t\t{\n\t\t\t\tif (next)\n\t\t\t\t{\n\t\t\t\t\tnext = false;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn next;\n\t\t\t}\n\n\t\t\tpublic CustomClassEnumeratorWithIDisposable<T> GetEnumerator()\n\t\t\t{\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}\n\n\t\tstatic void Operation(ref int item)\n\t\t{\n\t\t\titem++;\n\t\t}\n\n\t\tstatic T CallWithSideEffect<T>()\n\t\t{\n\t\t\tConsole.WriteLine(\"CallWithSideEffect\");\n\t\t\treturn default(T);\n\t\t}\n\n\t\tstatic void Main()\n\t\t{\n\t\t\tForWithMultipleVariables();\n\t\t\tDoubleForEachWithSameVariable(new[] { \"a\", \"b\", \"c\" });\n\t\t\tForeachExceptForNameCollision(new[] { 42, 43, 44, 45 });\n\t\t\tForeachExceptForContinuedUse(new[] { 42, 43, 44, 45 });\n\t\t\tNonGenericForeachWithReturnFallbackTest(new object[] { \"a\", 42, \"b\", 43 });\n\t\t\tNonGenericForeachWithReturn(new object[] { \"a\", 42, \"b\", 43 });\n\t\t\tForeachWithReturn(new[] { 42, 43, 44, 45 });\n\t\t\tForeachWithRefUsage(new List<int> { 1, 2, 3, 4, 5 });\n\t\t\tConsole.WriteLine(FirstOrDefault(new List<int> { 1, 2, 3, 4, 5 }));\n\t\t\tConsole.WriteLine(NoForeachDueToMultipleCurrentAccess(new List<int> { 1, 2, 3, 4, 5 }));\n\t\t\tConsole.WriteLine(NoForeachCallWithSideEffect(new CustomClassEnumeratorWithIDisposable<int>()));\n\t\t\tLoopWithGotoRepeat();\n\t\t\tConsole.WriteLine(\"LoopFollowedByIf: {0}\", LoopFollowedByIf());\n\t\t\tNoForeachDueToVariableAssignment();\n\t\t}\n\n\t\tpublic static void ForWithMultipleVariables()\n\t\t{\n\t\t\tint x, y;\n\t\t\tConsole.WriteLine(\"before for\");\n\t\t\tfor (x = y = 0; x < 10; x++)\n\t\t\t{\n\t\t\t\ty++;\n\t\t\t\tConsole.WriteLine(\"x = \" + x + \", y = \" + y);\n\t\t\t}\n\t\t\tConsole.WriteLine(\"after for\");\n\t\t}\n\n\t\tpublic static void DoubleForEachWithSameVariable(IEnumerable<string> enumerable)\n\t\t{\n\t\t\tConsole.WriteLine(\"DoubleForEachWithSameVariable:\");\n\t\t\tforeach (string current in enumerable)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(current.ToLower());\n\t\t\t}\n\t\t\tConsole.WriteLine(\"after first loop\");\n\t\t\tforeach (string current in enumerable)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(current.ToUpper());\n\t\t\t}\n\t\t\tConsole.WriteLine(\"after second loop\");\n\t\t}\n\n\t\tpublic static void ForeachExceptForNameCollision(IEnumerable<int> inputs)\n\t\t{\n\t\t\tConsole.WriteLine(\"ForeachWithNameCollision:\");\n\t\t\tint current;\n\t\t\tusing (IEnumerator<int> enumerator = inputs.GetEnumerator())\n\t\t\t{\n\t\t\t\twhile (enumerator.MoveNext())\n\t\t\t\t{\n\t\t\t\t\tcurrent = enumerator.Current;\n\t\t\t\t\tConsole.WriteLine(current);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcurrent = 1;\n\t\t\tConsole.WriteLine(current);\n\t\t}\n\n\t\tpublic static void ForeachExceptForContinuedUse(IEnumerable<int> inputs)\n\t\t{\n\t\t\tConsole.WriteLine(\"ForeachExceptForContinuedUse\");\n\t\t\tint num = 0;\n\t\t\tusing (IEnumerator<int> enumerator = inputs.GetEnumerator())\n\t\t\t{\n\t\t\t\twhile (enumerator.MoveNext())\n\t\t\t\t{\n\t\t\t\t\tnum = enumerator.Current;\n\t\t\t\t\tConsole.WriteLine(num);\n\t\t\t\t}\n\t\t\t}\n\t\t\tConsole.WriteLine(\"Last: \" + num);\n\t\t}\n\n\t\tpublic static void NonGenericForeachWithReturnFallbackTest(IEnumerable e)\n\t\t{\n\t\t\tConsole.WriteLine(\"NonGenericForeachWithReturnFallback:\");\n\t\t\tIEnumerator enumerator = e.GetEnumerator();\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"MoveNext\");\n\t\t\t\tif (enumerator.MoveNext())\n\t\t\t\t{\n\t\t\t\t\tobject current = enumerator.Current;\n\t\t\t\t\tConsole.WriteLine(\"current: \" + current);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tIDisposable disposable = enumerator as IDisposable;\n\t\t\t\tif (disposable != null)\n\t\t\t\t{\n\t\t\t\t\tdisposable.Dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t\tConsole.WriteLine(\"After finally!\");\n\t\t}\n\n\t\tpublic static object NonGenericForeachWithReturn(IEnumerable enumerable)\n\t\t{\n\t\t\tConsole.WriteLine(\"NonGenericForeachWithReturn:\");\n\t\t\tforeach (var obj in enumerable)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"return: \" + obj);\n\t\t\t\treturn obj;\n\t\t\t}\n\n\t\t\tConsole.WriteLine(\"return: null\");\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static int? ForeachWithReturn(IEnumerable<int> enumerable)\n\t\t{\n\t\t\tConsole.WriteLine(\"ForeachWithReturn:\");\n\t\t\tforeach (var obj in enumerable)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"return: \" + obj);\n\t\t\t\treturn obj;\n\t\t\t}\n\n\t\t\tConsole.WriteLine(\"return: null\");\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static void ForeachWithRefUsage(List<int> items)\n\t\t{\n\t\t\tConsole.WriteLine(\"ForeachWithRefUsage:\");\n\t\t\tforeach (var item in items)\n\t\t\t{\n\t\t\t\tvar itemToChange = item;\n\t\t\t\tConsole.WriteLine(\"item: \" + item);\n\t\t\t\tOperation(ref itemToChange);\n\t\t\t\tConsole.WriteLine(\"item: \" + itemToChange);\n\t\t\t}\n\t\t}\n\n\t\tpublic static T FirstOrDefault<T>(IEnumerable<T> items)\n\t\t{\n\t\t\tT result = default(T);\n\t\t\tforeach (T item in items)\n\t\t\t{\n\t\t\t\tresult = item;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic static T NoForeachDueToMultipleCurrentAccess<T>(IEnumerable<T> items)\n\t\t{\n\t\t\tConsole.WriteLine(\"NoForeachDueToMultipleCurrentAccess:\");\n\t\t\tT result = default(T);\n\t\t\tusing (IEnumerator<T> enumerator = items.GetEnumerator())\n\t\t\t{\n\t\t\t\twhile (enumerator.MoveNext())\n\t\t\t\t{\n\t\t\t\t\tresult = enumerator.Current;\n\t\t\t\t\tConsole.WriteLine(\"result: \" + result);\n\t\t\t\t}\n\t\t\t\treturn enumerator.Current;\n\t\t\t}\n\t\t}\n\n\t\tpublic static T NoForeachCallWithSideEffect<T>(CustomClassEnumeratorWithIDisposable<T> items)\n\t\t{\n\t\t\tConsole.WriteLine(\"NoForeachCallWithSideEffect:\");\n\t\t\tusing (CustomClassEnumeratorWithIDisposable<T> enumerator = items.GetEnumerator())\n\t\t\t{\n\t\t\t\twhile (enumerator.MoveNext())\n\t\t\t\t{\n\t\t\t\t\tT result = enumerator.Current;\n\t\t\t\t}\n\t\t\t\treturn CallWithSideEffect<T>();\n\t\t\t}\n\t\t}\n\n\t\tstatic bool GetBool(string text)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://github.com/icsharpcode/ILSpy/issues/915\n\t\tstatic void LoopWithGotoRepeat()\n\t\t{\n\t\t\tConsole.WriteLine(\"LoopWithGotoRepeat:\");\n\t\t\ttry\n\t\t\t{\n\t\t\t\tREPEAT:\n\t\t\t\tConsole.WriteLine(\"after repeat label\");\n\t\t\t\twhile (GetBool(\"Loop condition\"))\n\t\t\t\t{\n\t\t\t\t\tif (GetBool(\"if1\"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (GetBool(\"if3\"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tgoto REPEAT;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(\"after loop\");\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"finally\");\n\t\t\t}\n\t\t\tConsole.WriteLine(\"after finally\");\n\t\t}\n\n\t\tprivate static int LoopFollowedByIf()\n\t\t{\n\t\t\tint num = 0;\n\t\t\twhile (num == 0)\n\t\t\t{\n\t\t\t\tnum++;\n\t\t\t}\n\t\t\tif (num == 0)\n\t\t\t{\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\treturn num;\n\t\t}\n\n\t\tstatic void Issue1392ForWithNestedSwitchPlusGoto()\n\t\t{\n\t\t\tfor (int i = 0; i < 100; i++)\n\t\t\t{\n\t\t\t\tagain:\n\t\t\t\tswitch (i)\n\t\t\t\t{\n\t\t\t\t\tcase 10:\n\t\t\t\t\t\tConsole.WriteLine(\"10\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 25:\n\t\t\t\t\t\tConsole.WriteLine(\"25\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 50:\n\t\t\t\t\t\tConsole.WriteLine(\"50\");\n\t\t\t\t\t\tgoto again;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate static void NoForeachDueToVariableAssignment()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tint[] array = new int[] { 1, 2, 3 };\n\t\t\t\tfor (int i = 0; i < array.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(array[i]);\n\t\t\t\t\tarray = null;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.GetType() + \": \" + ex.Message);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/MemberLookup.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tpublic class MemberLookup\n\t{\n\t\tstatic readonly Action delegateConstruction = (new Child1() as Base1).TestAction;\n\n\t\tpublic static int Main()\n\t\t{\n\t\t\tConsole.WriteLine((new Child1() as Base1).Field);\n\t\t\tChild1.Test();\n\t\t\tdelegateConstruction();\n\t\t\tnew Child2b().CallTestMethod();\n\t\t\treturn 0;\n\t\t}\n\n\t\tclass Base1\n\t\t{\n\t\t\tpublic int Field = 1;\n\n\t\t\tprotected virtual void TestMethod()\n\t\t\t{\n\t\t\t\tProperty = 5;\n\t\t\t\tConsole.WriteLine(\"Base1.TestMethod()\");\n\t\t\t\tConsole.WriteLine(Property);\n\t\t\t}\n\n\t\t\tpublic void TestAction()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Base1.TestAction()\");\n\t\t\t}\n\n\t\t\tpublic int Property { get; set; }\n\n\t\t\tpublic virtual int VirtProp {\n\t\t\t\tget {\n\t\t\t\t\treturn 3;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tclass Child1 : Base1\n\t\t{\n\t\t\tChild1 child;\n\t\t\tnew public int Field = 2;\n\n\t\t\tpublic static void Test()\n\t\t\t{\n\t\t\t\tvar o = new Child1();\n\t\t\t\to.child = new Child1();\n\t\t\t\to.TestMethod();\n\n\t\t\t\tConsole.WriteLine(((Base1)o).Property);\n\t\t\t\tConsole.WriteLine(o.Property);\n\t\t\t\tConsole.WriteLine(((Base1)o).VirtProp);\n\t\t\t\tConsole.WriteLine(o.VirtProp);\n\t\t\t}\n\n\t\t\tprotected override void TestMethod()\n\t\t\t{\n\t\t\t\tProperty = 10;\n\t\t\t\tbase.TestMethod();\n\t\t\t\tif (child != null)\n\t\t\t\t\tchild.TestMethod();\n\t\t\t\tConsole.WriteLine(\"Child1.TestMethod()\");\n\t\t\t\tConsole.WriteLine(\"Property = \" + Property + \" \" + base.Property);\n\t\t\t\tConsole.WriteLine(\"Field = \" + Field);\n\t\t\t\tConsole.WriteLine(\"base.Field = \" + base.Field);\n\t\t\t}\n\n\t\t\tnew public void TestAction()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Child1.TestAction()\");\n\t\t\t}\n\n\t\t\tnew public int Property { get; set; }\n\n\t\t\tpublic override int VirtProp {\n\t\t\t\tget {\n\t\t\t\t\treturn base.VirtProp * 2;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tclass Child2 : Base1\n\t\t{\n\t\t\tpublic void CallTestMethod()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Child2 calling this.TestMethod():\");\n\t\t\t\tthis.TestMethod();\n\t\t\t\tConsole.WriteLine(\"Child2 calling base.TestMethod():\");\n\t\t\t\tbase.TestMethod();\n\t\t\t}\n\t\t}\n\n\t\tclass Child2b : Child2\n\t\t{\n\t\t\tprotected override void TestMethod()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Child2b.TestMethod\");\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/MiniJSON.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\t// taken from https://github.com/Jackyjjc/MiniJSON.cs\n\t// Copyright (c) 2013 Calvin Rien.\n\t// Licensed under the MIT LICENSE.\n\tpublic class MiniJSONTest\n\t{\n\t\tpublic static void Main(string[] args)\n\t\t{\n\t\t\tvar jsonString = \"{ \\\"array\\\": [1.44,2,3], \" +\n\t\t\t\t\t\t\t\"\\\"object\\\": {\\\"key1\\\":\\\"value1\\\", \\\"key2\\\":256}, \" +\n\t\t\t\t\t\t\t\"\\\"string\\\": \\\"The quick brown fox \\\\\\\"jumps\\\\\\\" over the lazy dog \\\", \" +\n\t\t\t\t\t\t\t\"\\\"unicode\\\": \\\"\\\\u3041 Men\\u00fa sesi\\u00f3n\\\", \" +\n\t\t\t\t\t\t\t\"\\\"int\\\": 65536, \" +\n\t\t\t\t\t\t\t\"\\\"float\\\": 3.1415926, \" +\n\t\t\t\t\t\t\t\"\\\"bool\\\": true, \" +\n\t\t\t\t\t\t\t\"\\\"null\\\": null }\";\n\n\t\t\tvar dict = Json.Deserialize(jsonString) as Dictionary<string, object>;\n\n\t\t\tConsole.WriteLine(\"deserialized: \" + dict.GetType());\n\t\t\tConsole.WriteLine(\"dict['array'][0]: \" + ((List<object>)dict[\"array\"])[0]);\n\t\t\tConsole.WriteLine(\"dict['string']: \" + (string)dict[\"string\"]);\n\t\t\tConsole.WriteLine(\"dict['float']: \" + (double)dict[\"float\"]); // floats come out as doubles\n\t\t\tConsole.WriteLine(\"dict['int']: \" + (long)dict[\"int\"]); // ints come out as longs\n\t\t\tConsole.WriteLine(\"dict['unicode']: \" + (string)dict[\"unicode\"]);\n\n\t\t\tvar str = Json.Serialize(dict);\n\n\t\t\tConsole.WriteLine(\"serialized: \" + str);\n\t\t}\n\t}\n\n\tpublic static class Json\n\t{\n\t\t/// <summary>\n\t\t/// Parses the string json into a value\n\t\t/// </summary>\n\t\t/// <param name=\"json\">A JSON string.</param>\n\t\t/// <returns>An List&lt;object&gt;, a Dictionary&lt;string, object&gt;, a double, an integer,a string, null, true, or false</returns>\n\t\tpublic static object Deserialize(string json)\n\t\t{\n\t\t\t// save the string for debug information\n\t\t\tif (json == null)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn Parser.Parse(json);\n\t\t}\n\n\t\tsealed class Parser : IDisposable\n\t\t{\n\t\t\tconst string WORD_BREAK = \"{}[],:\\\"\";\n\n\t\t\tpublic static bool IsWordBreak(char c)\n\t\t\t{\n\t\t\t\treturn Char.IsWhiteSpace(c) || WORD_BREAK.IndexOf(c) != -1;\n\t\t\t}\n\n\t\t\tconst string HEX_DIGIT = \"0123456789ABCDEFabcdef\";\n\n\t\t\tpublic static bool IsHexDigit(char c)\n\t\t\t{\n\t\t\t\treturn HEX_DIGIT.IndexOf(c) != -1;\n\t\t\t}\n\n\t\t\tenum TOKEN\n\t\t\t{\n\t\t\t\tNONE,\n\t\t\t\tCURLY_OPEN,\n\t\t\t\tCURLY_CLOSE,\n\t\t\t\tSQUARED_OPEN,\n\t\t\t\tSQUARED_CLOSE,\n\t\t\t\tCOLON,\n\t\t\t\tCOMMA,\n\t\t\t\tSTRING,\n\t\t\t\tNUMBER,\n\t\t\t\tTRUE,\n\t\t\t\tFALSE,\n\t\t\t\tNULL\n\t\t\t};\n\n\t\t\tStringReader json;\n\n\t\t\tParser(string jsonString)\n\t\t\t{\n\t\t\t\tjson = new StringReader(jsonString);\n\t\t\t}\n\n\t\t\tpublic static object Parse(string jsonString)\n\t\t\t{\n\t\t\t\tusing (var instance = new Parser(jsonString))\n\t\t\t\t{\n\t\t\t\t\treturn instance.ParseValue();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic void Dispose()\n\t\t\t{\n\t\t\t\tjson.Dispose();\n\t\t\t\tjson = null;\n\t\t\t}\n\n\t\t\tDictionary<string, object> ParseObject()\n\t\t\t{\n\t\t\t\tDictionary<string, object> table = new Dictionary<string, object>();\n\n\t\t\t\t// ditch opening brace\n\t\t\t\tjson.Read();\n\n\t\t\t\t// {\n\t\t\t\twhile (true)\n\t\t\t\t{\n\t\t\t\t\tswitch (NextToken)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase TOKEN.NONE:\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\tcase TOKEN.COMMA:\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tcase TOKEN.CURLY_CLOSE:\n\t\t\t\t\t\t\treturn table;\n\t\t\t\t\t\tcase TOKEN.STRING:\n\t\t\t\t\t\t\t// name\n\t\t\t\t\t\t\tstring name = ParseString();\n\t\t\t\t\t\t\tif (name == null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// :\n\t\t\t\t\t\t\tif (NextToken != TOKEN.COLON)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// ditch the colon\n\t\t\t\t\t\t\tjson.Read();\n\n\t\t\t\t\t\t\t// value\n\t\t\t\t\t\t\tTOKEN valueToken = NextToken;\n\t\t\t\t\t\t\tobject value = ParseByToken(valueToken);\n\t\t\t\t\t\t\tif (value == null && valueToken != TOKEN.NULL)\n\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\ttable[name] = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tList<object> ParseArray()\n\t\t\t{\n\t\t\t\tList<object> array = new List<object>();\n\n\t\t\t\t// ditch opening bracket\n\t\t\t\tjson.Read();\n\n\t\t\t\t// [\n\t\t\t\tvar parsing = true;\n\t\t\t\twhile (parsing)\n\t\t\t\t{\n\t\t\t\t\tTOKEN nextToken = NextToken;\n\n\t\t\t\t\tswitch (nextToken)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase TOKEN.NONE:\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\tcase TOKEN.COMMA:\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tcase TOKEN.SQUARED_CLOSE:\n\t\t\t\t\t\t\tparsing = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tobject value = ParseByToken(nextToken);\n\t\t\t\t\t\t\tif (value == null && nextToken != TOKEN.NULL)\n\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\tarray.Add(value);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn array;\n\t\t\t}\n\n\t\t\tobject ParseValue()\n\t\t\t{\n\t\t\t\tTOKEN nextToken = NextToken;\n\t\t\t\treturn ParseByToken(nextToken);\n\t\t\t}\n\n\t\t\tobject ParseByToken(TOKEN token)\n\t\t\t{\n\t\t\t\tswitch (token)\n\t\t\t\t{\n\t\t\t\t\tcase TOKEN.STRING:\n\t\t\t\t\t\treturn ParseString();\n\t\t\t\t\tcase TOKEN.NUMBER:\n\t\t\t\t\t\treturn ParseNumber();\n\t\t\t\t\tcase TOKEN.CURLY_OPEN:\n\t\t\t\t\t\treturn ParseObject();\n\t\t\t\t\tcase TOKEN.SQUARED_OPEN:\n\t\t\t\t\t\treturn ParseArray();\n\t\t\t\t\tcase TOKEN.TRUE:\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tcase TOKEN.FALSE:\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcase TOKEN.NULL:\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tstring ParseString()\n\t\t\t{\n\t\t\t\tStringBuilder s = new StringBuilder();\n\t\t\t\tchar c;\n\n\t\t\t\t// ditch opening quote\n\t\t\t\tjson.Read();\n\n\t\t\t\tbool parsing = true;\n\t\t\t\twhile (parsing)\n\t\t\t\t{\n\n\t\t\t\t\tif (json.Peek() == -1)\n\t\t\t\t\t{\n\t\t\t\t\t\tparsing = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tc = NextChar;\n\t\t\t\t\tswitch (c)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase '\"':\n\t\t\t\t\t\t\tparsing = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '\\\\':\n\t\t\t\t\t\t\tif (json.Peek() == -1)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tparsing = false;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tc = NextChar;\n\t\t\t\t\t\t\tswitch (c)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcase '\"':\n\t\t\t\t\t\t\t\tcase '\\\\':\n\t\t\t\t\t\t\t\tcase '/':\n\t\t\t\t\t\t\t\t\ts.Append(c);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase 'b':\n\t\t\t\t\t\t\t\t\ts.Append('\\b');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase 'f':\n\t\t\t\t\t\t\t\t\ts.Append('\\f');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase 'n':\n\t\t\t\t\t\t\t\t\ts.Append('\\n');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase 'r':\n\t\t\t\t\t\t\t\t\ts.Append('\\r');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase 't':\n\t\t\t\t\t\t\t\t\ts.Append('\\t');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase 'u':\n\t\t\t\t\t\t\t\t\tvar hex = new char[4];\n\n\t\t\t\t\t\t\t\t\tfor (int i = 0; i < 4; i++)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\thex[i] = NextChar;\n\t\t\t\t\t\t\t\t\t\tif (!IsHexDigit(hex[i]))\n\t\t\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\ts.Append((char)Convert.ToInt32(new string(hex), 16));\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\ts.Append(c);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn s.ToString();\n\t\t\t}\n\n\t\t\tobject ParseNumber()\n\t\t\t{\n\t\t\t\tstring number = NextWord;\n\n\t\t\t\tif (number.IndexOf('.') == -1 && number.IndexOf('E') == -1 && number.IndexOf('e') == -1)\n\t\t\t\t{\n\t\t\t\t\tlong parsedInt;\n\t\t\t\t\tInt64.TryParse(number, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out parsedInt);\n\t\t\t\t\treturn parsedInt;\n\t\t\t\t}\n\n\t\t\t\tdouble parsedDouble;\n\t\t\t\tDouble.TryParse(number, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out parsedDouble);\n\t\t\t\treturn parsedDouble;\n\t\t\t}\n\n\t\t\tvoid EatWhitespace()\n\t\t\t{\n\t\t\t\twhile (Char.IsWhiteSpace(PeekChar))\n\t\t\t\t{\n\t\t\t\t\tjson.Read();\n\n\t\t\t\t\tif (json.Peek() == -1)\n\t\t\t\t\t{\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tchar PeekChar {\n\t\t\t\tget {\n\t\t\t\t\treturn Convert.ToChar(json.Peek());\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tchar NextChar {\n\t\t\t\tget {\n\t\t\t\t\treturn Convert.ToChar(json.Read());\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tstring NextWord {\n\t\t\t\tget {\n\t\t\t\t\tStringBuilder word = new StringBuilder();\n\n\t\t\t\t\twhile (!IsWordBreak(PeekChar))\n\t\t\t\t\t{\n\t\t\t\t\t\tword.Append(NextChar);\n\n\t\t\t\t\t\tif (json.Peek() == -1)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn word.ToString();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tTOKEN NextToken {\n\t\t\t\tget {\n\t\t\t\t\tEatWhitespace();\n\n\t\t\t\t\tif (json.Peek() == -1)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn TOKEN.NONE;\n\t\t\t\t\t}\n\n\t\t\t\t\tswitch (PeekChar)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase '{':\n\t\t\t\t\t\t\treturn TOKEN.CURLY_OPEN;\n\t\t\t\t\t\tcase '}':\n\t\t\t\t\t\t\tjson.Read();\n\t\t\t\t\t\t\treturn TOKEN.CURLY_CLOSE;\n\t\t\t\t\t\tcase '[':\n\t\t\t\t\t\t\treturn TOKEN.SQUARED_OPEN;\n\t\t\t\t\t\tcase ']':\n\t\t\t\t\t\t\tjson.Read();\n\t\t\t\t\t\t\treturn TOKEN.SQUARED_CLOSE;\n\t\t\t\t\t\tcase ',':\n\t\t\t\t\t\t\tjson.Read();\n\t\t\t\t\t\t\treturn TOKEN.COMMA;\n\t\t\t\t\t\tcase '\"':\n\t\t\t\t\t\t\treturn TOKEN.STRING;\n\t\t\t\t\t\tcase ':':\n\t\t\t\t\t\t\treturn TOKEN.COLON;\n\t\t\t\t\t\tcase '0':\n\t\t\t\t\t\tcase '1':\n\t\t\t\t\t\tcase '2':\n\t\t\t\t\t\tcase '3':\n\t\t\t\t\t\tcase '4':\n\t\t\t\t\t\tcase '5':\n\t\t\t\t\t\tcase '6':\n\t\t\t\t\t\tcase '7':\n\t\t\t\t\t\tcase '8':\n\t\t\t\t\t\tcase '9':\n\t\t\t\t\t\tcase '-':\n\t\t\t\t\t\t\treturn TOKEN.NUMBER;\n\t\t\t\t\t}\n\n\t\t\t\t\tswitch (NextWord)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase \"false\":\n\t\t\t\t\t\t\treturn TOKEN.FALSE;\n\t\t\t\t\t\tcase \"true\":\n\t\t\t\t\t\t\treturn TOKEN.TRUE;\n\t\t\t\t\t\tcase \"null\":\n\t\t\t\t\t\t\treturn TOKEN.NULL;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn TOKEN.NONE;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts a IDictionary / IList object or a simple type (string, int, etc.) into a JSON string\n\t\t/// </summary>\n\t\t/// <param name=\"json\">A Dictionary&lt;string, object&gt; / List&lt;object&gt;</param>\n\t\t/// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns>\n\t\tpublic static string Serialize(object obj)\n\t\t{\n\t\t\treturn Serializer.Serialize(obj);\n\t\t}\n\n\t\tsealed class Serializer\n\t\t{\n\t\t\tStringBuilder builder;\n\n\t\t\tSerializer()\n\t\t\t{\n\t\t\t\tbuilder = new StringBuilder();\n\t\t\t}\n\n\t\t\tpublic static string Serialize(object obj)\n\t\t\t{\n\t\t\t\tvar instance = new Serializer();\n\n\t\t\t\tinstance.SerializeValue(obj);\n\n\t\t\t\treturn instance.builder.ToString();\n\t\t\t}\n\n\t\t\tvoid SerializeValue(object value)\n\t\t\t{\n\t\t\t\tIList asList;\n\t\t\t\tIDictionary asDict;\n\t\t\t\tstring asStr;\n\n\t\t\t\tif (value == null)\n\t\t\t\t{\n\t\t\t\t\tbuilder.Append(\"null\");\n\t\t\t\t}\n\t\t\t\telse if ((asStr = value as string) != null)\n\t\t\t\t{\n\t\t\t\t\tSerializeString(asStr);\n\t\t\t\t}\n\t\t\t\telse if (value is bool)\n\t\t\t\t{\n\t\t\t\t\tbuilder.Append((bool)value ? \"true\" : \"false\");\n\t\t\t\t}\n\t\t\t\telse if ((asList = value as IList) != null)\n\t\t\t\t{\n\t\t\t\t\tSerializeArray(asList);\n\t\t\t\t}\n\t\t\t\telse if ((asDict = value as IDictionary) != null)\n\t\t\t\t{\n\t\t\t\t\tSerializeObject(asDict);\n\t\t\t\t}\n\t\t\t\telse if (value is char)\n\t\t\t\t{\n\t\t\t\t\tSerializeString(new string((char)value, 1));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tSerializeOther(value);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid SerializeObject(IDictionary obj)\n\t\t\t{\n\t\t\t\tbool first = true;\n\n\t\t\t\tbuilder.Append('{');\n\n\t\t\t\tforeach (object e in obj.Keys)\n\t\t\t\t{\n\t\t\t\t\tif (!first)\n\t\t\t\t\t{\n\t\t\t\t\t\tbuilder.Append(',');\n\t\t\t\t\t}\n\n\t\t\t\t\tSerializeString(e.ToString());\n\t\t\t\t\tbuilder.Append(':');\n\n\t\t\t\t\tSerializeValue(obj[e]);\n\n\t\t\t\t\tfirst = false;\n\t\t\t\t}\n\n\t\t\t\tbuilder.Append('}');\n\t\t\t}\n\n\t\t\tvoid SerializeArray(IList anArray)\n\t\t\t{\n\t\t\t\tbuilder.Append('[');\n\n\t\t\t\tbool first = true;\n\n\t\t\t\tfor (int i = 0; i < anArray.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tobject obj = anArray[i];\n\t\t\t\t\tif (!first)\n\t\t\t\t\t{\n\t\t\t\t\t\tbuilder.Append(',');\n\t\t\t\t\t}\n\n\t\t\t\t\tSerializeValue(obj);\n\n\t\t\t\t\tfirst = false;\n\t\t\t\t}\n\n\t\t\t\tbuilder.Append(']');\n\t\t\t}\n\n\t\t\tvoid SerializeString(string str)\n\t\t\t{\n\t\t\t\tbuilder.Append('\\\"');\n\n\t\t\t\tchar[] charArray = str.ToCharArray();\n\t\t\t\tfor (int i = 0; i < charArray.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tchar c = charArray[i];\n\t\t\t\t\tswitch (c)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase '\"':\n\t\t\t\t\t\t\tbuilder.Append(\"\\\\\\\"\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '\\\\':\n\t\t\t\t\t\t\tbuilder.Append(\"\\\\\\\\\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '\\b':\n\t\t\t\t\t\t\tbuilder.Append(\"\\\\b\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '\\f':\n\t\t\t\t\t\t\tbuilder.Append(\"\\\\f\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '\\n':\n\t\t\t\t\t\t\tbuilder.Append(\"\\\\n\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '\\r':\n\t\t\t\t\t\t\tbuilder.Append(\"\\\\r\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '\\t':\n\t\t\t\t\t\t\tbuilder.Append(\"\\\\t\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tint codepoint = Convert.ToInt32(c);\n\t\t\t\t\t\t\tif ((codepoint >= 32) && (codepoint <= 126))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tbuilder.Append(c);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tbuilder.Append(\"\\\\u\");\n\t\t\t\t\t\t\t\tbuilder.Append(codepoint.ToString(\"x4\"));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbuilder.Append('\\\"');\n\t\t\t}\n\n\t\t\tvoid SerializeOther(object value)\n\t\t\t{\n\t\t\t\t// NOTE: decimals lose precision during serialization.\n\t\t\t\t// They always have, I'm just letting you know.\n\t\t\t\t// Previously floats and doubles lost precision too.\n\t\t\t\tif (value is float)\n\t\t\t\t{\n\t\t\t\t\tbuilder.Append(((float)value).ToString(\"R\", System.Globalization.CultureInfo.InvariantCulture));\n\t\t\t\t}\n\t\t\t\telse if (value is int\n\t\t\t\t  || value is uint\n\t\t\t\t  || value is long\n\t\t\t\t  || value is sbyte\n\t\t\t\t  || value is byte\n\t\t\t\t  || value is short\n\t\t\t\t  || value is ushort\n\t\t\t\t  || value is ulong)\n\t\t\t\t{\n\t\t\t\t\tbuilder.Append(value);\n\t\t\t\t}\n\t\t\t\telse if (value is double\n\t\t\t\t  || value is decimal)\n\t\t\t\t{\n\t\t\t\t\tbuilder.Append(Convert.ToDouble(value).ToString(\"R\", System.Globalization.CultureInfo.InvariantCulture));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tSerializeString(value.ToString());\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/NonGenericConstrainedCallVirt.il",
    "content": ".assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n\n.assembly _\n{\n    .hash algorithm 0x00008004 // SHA1\n    .ver 0:0:0:0\n}\n\n.class public auto ansi beforefieldinit NonGenericConstrainedCallVirt\n    extends [mscorlib]System.Object\n{\n    // Methods\n    .method public hidebysig static \n        void Main () cil managed \n    {\n        // Method begins at RVA 0x2050\n        // Code size 16 (0x10)\n        .entrypoint\n        .maxstack 8\n\n        IL_0000: ldstr \"A\"\n        IL_0005: newobj instance void C::.ctor(string)\n        IL_000a: call void NonGenericConstrainedCallVirt::Foo(class C)\n        IL_000f: ret\n    } // end of method NonGenericConstrainedCallVirt::Main\n\n    .method private hidebysig static \n        void Foo (\n            class C arg\n        ) cil managed \n    {\n        // Method begins at RVA 0x2064\n        // Code size 25 (0x19)\n        .maxstack 8\n\n        IL_0000: ldarga arg\n        IL_0004: ldarga arg\n        IL_0008: call int32 NonGenericConstrainedCallVirt::Bar(class C&)\n        IL_000d: constrained. C\n        IL_0013: callvirt instance void C::Baz(int32)\n        IL_0018: ret\n    } // end of method NonGenericConstrainedCallVirt::Foo\n\n    .method private hidebysig static \n        int32 Bar (\n            class C& o\n        ) cil managed \n    {\n        // Method begins at RVA 0x2080\n        // Code size 14 (0xe)\n        .maxstack 8\n\n        IL_0000: ldarg.0\n        IL_0001: ldstr \"B\"\n        IL_0006: newobj instance void C::.ctor(string)\n        IL_000b: stind.ref\n        IL_000c: ldc.i4.0\n        IL_000d: ret\n    } // end of method NonGenericConstrainedCallVirt::Bar\n\n    .method public hidebysig specialname rtspecialname \n        instance void .ctor () cil managed \n    {\n        // Method begins at RVA 0x2090\n        // Code size 7 (0x7)\n        .maxstack 8\n\n        IL_0000: ldarg.0\n        IL_0001: call instance void [mscorlib]System.Object::.ctor()\n        IL_0006: ret\n    } // end of method NonGenericConstrainedCallVirt::.ctor\n\n} // end of class NonGenericConstrainedCallVirt\n\n.class public auto ansi beforefieldinit C\n    extends [mscorlib]System.Object\n{\n    // Fields\n    .field private initonly string '<Name>k__BackingField'\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n        01 00 00 00\n    )\n\n    // Methods\n    .method public hidebysig specialname rtspecialname \n        instance void .ctor (\n            string n\n        ) cil managed \n    {\n        // Method begins at RVA 0x2098\n        // Code size 14 (0xe)\n        .maxstack 8\n\n        IL_0000: ldarg.0\n        IL_0001: call instance void [mscorlib]System.Object::.ctor()\n        IL_0006: ldarg.0\n        IL_0007: ldarg.1\n        IL_0008: stfld string C::'<Name>k__BackingField'\n        IL_000d: ret\n    } // end of method C::.ctor\n\n    .method public hidebysig \n        instance void Baz (\n            int32 arg\n        ) cil managed \n    {\n        // Method begins at RVA 0x20a8\n        // Code size 12 (0xc)\n        .maxstack 8\n\n        IL_0000: ldarg.0\n        IL_0001: call instance string C::get_Name()\n        IL_0006: call void [mscorlib]System.Console::WriteLine(string)\n        IL_000b: ret\n    } // end of method C::Baz\n\n    .method public hidebysig specialname \n        instance string get_Name () cil managed \n    {\n        .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n            01 00 00 00\n        )\n        // Method begins at RVA 0x20b8\n        // Code size 7 (0x7)\n        .maxstack 8\n\n        IL_0000: ldarg.0\n        IL_0001: ldfld string C::'<Name>k__BackingField'\n        IL_0006: ret\n    } // end of method C::get_Name\n\n    // Properties\n    .property instance string Name()\n    {\n        .get instance string C::get_Name()\n    }\n\n} // end of class C\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/NullPropagation.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tclass NullPropagation\n\t{\n\t\tstatic void Main()\n\t\t{\n\t\t\tnew NullPropagation().TestNotCoalescing();\n\t\t}\n\n\t\tclass MyClass\n\t\t{\n\t\t\tpublic string Text;\n\t\t}\n\n\t\tvoid TestNotCoalescing()\n\t\t{\n\t\t\tConsole.WriteLine(\"TestNotCoalescing:\");\n\t\t\tConsole.WriteLine(NotCoalescing(null));\n\t\t\tConsole.WriteLine(NotCoalescing(new MyClass()));\n\t\t}\n\n\t\tstring NotCoalescing(MyClass c)\n\t\t{\n\t\t\treturn c != null ? c.Text : \"Hello\";\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/NullableTests.cs",
    "content": "// Copyright (c) 2017 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tclass NullableTests\n\t{\n\t\tstatic void Main()\n\t\t{\n\t\t\tAvoidLifting();\n\t\t\tBitNot();\n\t\t\tFieldAccessOrderOfEvaluation(null);\n\t\t\tFieldAccessOrderOfEvaluationWithStruct(null);\n\t\t\tArrayAccessOrderOfEvaluation();\n\t\t}\n\n\t\tstruct SomeStruct\n\t\t{\n\t\t\tpublic int IntField;\n\t\t}\n\n\t\tstatic void AvoidLifting()\n\t\t{\n\t\t\tConsole.WriteLine(\"MayThrow:\");\n\t\t\tConsole.WriteLine(MayThrow(10, 2, 3));\n\t\t\tConsole.WriteLine(MayThrow(10, 0, null));\n\n\t\t\tConsole.WriteLine(\"NotUsingAllInputs:\");\n\t\t\tConsole.WriteLine(NotUsingAllInputs(5, 3));\n\t\t\tConsole.WriteLine(NotUsingAllInputs(5, null));\n\n\t\t\tConsole.WriteLine(\"UsingUntestedValue:\");\n\t\t\tConsole.WriteLine(UsingUntestedValue(5, 3));\n\t\t\tConsole.WriteLine(UsingUntestedValue(5, null));\n\t\t}\n\n\t\tstatic int? MayThrow(int? a, int? b, int? c)\n\t\t{\n\t\t\t// cannot be lifted without changing the exception behavior\n\t\t\treturn a.HasValue & b.HasValue & c.HasValue ? a.GetValueOrDefault() / b.GetValueOrDefault() + c.GetValueOrDefault() : default(int?);\n\t\t}\n\n\t\tstatic int? NotUsingAllInputs(int? a, int? b)\n\t\t{\n\t\t\t// cannot be lifted because the value differs if b == null\n\t\t\treturn a.HasValue & b.HasValue ? a.GetValueOrDefault() + a.GetValueOrDefault() : default(int?);\n\t\t}\n\n\t\tstatic int? UsingUntestedValue(int? a, int? b)\n\t\t{\n\t\t\t// cannot be lifted because the value differs if b == null\n\t\t\treturn a.HasValue ? a.GetValueOrDefault() + b.GetValueOrDefault() : default(int?);\n\t\t}\n\n\t\tstatic void BitNot()\n\t\t{\n\t\t\tUInt32? value = 0;\n\t\t\tAssert(~value == UInt32.MaxValue);\n\t\t\tUInt64? value2 = 0;\n\t\t\tAssert(~value2 == UInt64.MaxValue);\n\t\t\tUInt16? value3 = 0;\n\t\t\tAssert((UInt16)~value3 == (UInt16)UInt16.MaxValue);\n\t\t\tUInt32 value4 = 0;\n\t\t\tAssert(~value4 == UInt32.MaxValue);\n\t\t\tUInt64 value5 = 0;\n\t\t\tAssert(~value5 == UInt64.MaxValue);\n\t\t\tUInt16 value6 = 0;\n\t\t\tAssert((UInt16)~value6 == UInt16.MaxValue);\n\t\t}\n\n\t\tstatic void Assert(bool b)\n\t\t{\n\t\t\tif (!b)\n\t\t\t\tthrow new InvalidOperationException();\n\t\t}\n\n\t\tstatic T GetValue<T>()\n\t\t{\n\t\t\tConsole.WriteLine(\"GetValue\");\n\t\t\treturn default(T);\n\t\t}\n\n\t\tint intField;\n\n\t\tstatic void FieldAccessOrderOfEvaluation(NullableTests c)\n\t\t{\n\t\t\tConsole.WriteLine(\"GetInt, then NRE:\");\n\t\t\ttry\n\t\t\t{\n\t\t\t\tc.intField = GetValue<int>();\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.Message);\n\t\t\t}\n\t\t\tConsole.WriteLine(\"NRE before GetInt:\");\n\t\t\ttry\n\t\t\t{\n#if CS70\n\t\t\t\tref int i = ref c.intField;\n\t\t\t\ti = GetValue<int>();\n#endif\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.Message);\n\t\t\t}\n\t\t}\n\n\t\tSomeStruct structField;\n\n\t\tstatic void FieldAccessOrderOfEvaluationWithStruct(NullableTests c)\n\t\t{\n\t\t\tConsole.WriteLine(\"GetInt, then NRE (with struct):\");\n\t\t\ttry\n\t\t\t{\n\t\t\t\tc.structField.IntField = GetValue<int>();\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.Message);\n\t\t\t}\n\t\t\tConsole.WriteLine(\"NRE before GetInt (with struct):\");\n\t\t\ttry\n\t\t\t{\n#if CS70\n\t\t\t\tref SomeStruct s = ref c.structField;\n\t\t\t\ts.IntField = GetValue<int>();\n#endif\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.Message);\n\t\t\t}\n\t\t}\n\n\t\tstatic T[] GetArray<T>()\n\t\t{\n\t\t\tConsole.WriteLine(\"GetArray\");\n\t\t\treturn null;\n\t\t}\n\n\t\tstatic int GetIndex()\n\t\t{\n\t\t\tConsole.WriteLine(\"GetIndex\");\n\t\t\treturn 0;\n\t\t}\n\n\t\tstatic void ArrayAccessOrderOfEvaluation()\n\t\t{\n\t\t\tConsole.WriteLine(\"GetArray direct:\");\n\t\t\ttry\n\t\t\t{\n\t\t\t\tGetArray<int>()[GetIndex()] = GetValue<int>();\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.Message);\n\t\t\t}\n\t\t\tConsole.WriteLine(\"GetArray with ref:\");\n\t\t\ttry\n\t\t\t{\n#if CS70\n\t\t\t\tref int elem = ref GetArray<int>()[GetIndex()];\n\t\t\t\telem = GetValue<int>();\n#endif\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.Message);\n\t\t\t}\n\t\t\tConsole.WriteLine(\"GetArray direct with value-type:\");\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// This line is mis-compiled by legacy csc:\n\t\t\t\t// with the legacy compiler the NRE is thrown before the GetValue call;\n\t\t\t\t// with Roslyn the NRE is thrown after the GetValue call.\n\t\t\t\tGetArray<TimeSpan>()[GetIndex()] = GetValue<TimeSpan>();\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.Message);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/OverloadResolution.cs",
    "content": "// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tstatic class OverloadResolution\n\t{\n\t\tstatic void Main()\n\t\t{\n\t\t\tCallOverloadedMethod();\n\t\t\tTestBoxing();\n\t\t\tTestIssue180();\n\t\t\tTestExtensionMethod();\n\t\t\tTestParamsMethod();\n\t\t\tGenerics();\n\t\t\tConstructorTest();\n\t\t\tTestIndexer();\n\t\t\tIssue1281();\n\t\t\tIssue1747();\n\t\t\tCallAmbiguousOutParam();\n\t\t\tCallWithInParam();\n\t\t\tCallWithRefReadOnlyParam();\n#if CS90\n\t\t\tNativeIntTests(new IntPtr(1), 2);\n#endif\n\t\t\tIssue2444.M2();\n\t\t\tIssue2741.B.Test(new Issue2741.C());\n\t\t\tExtensionMethodDemo.Issue2165.Test();\n\t\t}\n\n\t\t#region ConstructorTest\n\t\tstatic void ConstructorTest()\n\t\t{\n\t\t\tnew CtorTestObj(1);\n\t\t\tnew CtorTestObj((short)2);\n\t\t\tnew CtorTestObj(3, null);\n\t\t\tnew CtorTestObj(4, null, null);\n\t\t}\n\n\t\tclass CtorTestObj\n\t\t{\n\t\t\tpublic CtorTestObj(int i)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"CtorTestObj(int = \" + i + \")\");\n\t\t\t}\n\n\t\t\tpublic CtorTestObj(short s)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"CtorTestObj(short = \" + s + \")\");\n\t\t\t}\n\n\t\t\tpublic CtorTestObj(int i, object item1, object item2)\n\t\t\t\t: this(i, new object[] { item1, item2 })\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"CtorTestObj(int = \" + i + \", item1 = \" + item1 + \", item2 = \" + item2);\n\t\t\t}\n\n\t\t\tpublic CtorTestObj(int i, params object[] items)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"CtorTestObj(int = \" + i + \", items = \" + (items == null ? \"null\" : items.Length.ToString()) + \")\");\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region params with nulls\n\t\tstatic void TestParamsMethod()\n\t\t{\n\t\t\tTestCall(1, null, (NullReferenceException)null);\n\t\t\tTestCall(2, null, (AccessViolationException)null);\n\t\t\tTestCall(3, null);\n\t\t\tTestCall(3, null, null, null);\n\t\t}\n\n\t\tstatic void TestCall(int v, Type p1, NullReferenceException p2)\n\t\t{\n\t\t\tConsole.WriteLine(\"TestCall without params\");\n\t\t}\n\n\t\tstatic void TestCall(int v, params AccessViolationException[] p2)\n\t\t{\n\t\t\tConsole.WriteLine(\"TestCall with params: \" + (p2 == null ? \"null\" : p2.Length.ToString()));\n\t\t}\n\n\t\tstatic void Issue1281()\n\t\t{\n\t\t\tvar arg = new object[0];\n\t\t\tTestCallIssue1281(arg);\n\t\t\tTestCallIssue1281((object)arg);\n\t\t\tTestCallIssue1281(new[] { arg });\n\t\t}\n\n\t\tstatic void TestCallIssue1281(params object[] args)\n\t\t{\n\t\t\tConsole.Write(\"TestCallIssue1281: count = \" + args.Length + \": \");\n\t\t\tforeach (var arg in args)\n\t\t\t{\n\t\t\t\tConsole.Write(arg);\n\t\t\t\tConsole.Write(\", \");\n\t\t\t}\n\t\t\tConsole.WriteLine();\n\t\t}\n\t\t#endregion\n\n\t\t#region Simple Overloaded Method\n\t\tstatic void CallOverloadedMethod()\n\t\t{\n\t\t\tOverloadedMethod(\"(string)\");\n\t\t\tOverloadedMethod((object)\"(object)\");\n\t\t\tOverloadedMethod(5);\n\t\t\tOverloadedMethod((object)5);\n\t\t\tOverloadedMethod(5L);\n\t\t\tOverloadedMethod((object)null);\n\t\t\tOverloadedMethod((string)null);\n\t\t\tOverloadedMethod((int?)null);\n\t\t}\n\n\t\tstatic void OverloadedMethod(object a)\n\t\t{\n\t\t\tConsole.WriteLine(\"OverloadedMethod(object={0}, object.GetType()={1})\", a, a != null ? a.GetType().Name : \"null\");\n\t\t}\n\n\t\tstatic void OverloadedMethod(int? a)\n\t\t{\n\t\t\tConsole.WriteLine(\"OverloadedMethod(int?={0})\", a);\n\t\t}\n\n\t\tstatic void OverloadedMethod(string a)\n\t\t{\n\t\t\tConsole.WriteLine(\"OverloadedMethod(string={0})\", a);\n\t\t}\n\t\t#endregion\n\n\t\t#region Boxing\n\t\tstatic void TestBoxing()\n\t\t{\n\t\t\tPrint(1);\n\t\t\tPrint((ushort)1);\n\t\t\tPrint(null);\n\t\t}\n\n\t\tstatic void Print(object obj)\n\t\t{\n\t\t\tif (obj == null)\n\t\t\t\tConsole.WriteLine(\"null\");\n\t\t\telse\n\t\t\t\tConsole.WriteLine(\"{0}: {1}\", obj.GetType().Name, obj);\n\t\t}\n\t\t#endregion\n\n\t\t#region #180\n\t\tstatic void TestIssue180()\n\t\t{\n\t\t\tIssue180(null);\n\t\t\tIssue180(new object[1]);\n\t\t\tIssue180((object)new object[1]);\n\t\t}\n\n\t\tstatic void Issue180(object obj)\n\t\t{\n\t\t\tConsole.WriteLine(\"#180: object\");\n\t\t}\n\n\t\tstatic void Issue180(params object[] objs)\n\t\t{\n\t\t\tConsole.WriteLine(\"#180: params object[]\");\n\t\t}\n\t\t#endregion\n\n\t\t#region Extension Method\n\t\tstatic void TestExtensionMethod()\n\t\t{\n\t\t\tnew object().ExtensionMethod();\n\t\t\tExtensionMethod(null); // issue #167\n\t\t}\n\n\t\tpublic static void ExtensionMethod(this object obj)\n\t\t{\n\t\t\tConsole.WriteLine(\"ExtensionMethod(obj)\");\n\t\t}\n\t\t#endregion\n\n\t\t#region Generics\n\t\tstatic void Generics()\n\t\t{\n\t\t\tGenericsTest<int>(null);\n\t\t\tGenericsTest<long>((object)null);\n\t\t}\n\n\t\tstatic void GenericsTest<T>(string x) where T : struct\n\t\t{\n\t\t\tConsole.WriteLine(\"GenericsTest<\" + typeof(T).Name + \">(string: \" + x + \");\");\n\t\t}\n\n\t\tstatic void GenericsTest<T>(object x) where T : struct\n\t\t{\n\t\t\tConsole.WriteLine(\"GenericsTest<\" + typeof(T).Name + \">(object: \" + x + \");\");\n\t\t}\n\t\t#endregion\n\n\t\t#region NullableValueTypes\n\t\tprivate static void Issue1747()\n\t\t{\n\t\t\tConsole.WriteLine(\"Issue1747:\");\n\t\t\tM1747(null);\n\t\t\tM1747(true);\n\t\t\tM1747(false);\n\t\t\tM1747((bool?)true);\n\t\t\tM1747((bool?)false);\n\t\t\tConsole.WriteLine(\"Issue1747, non-constant:\");\n\t\t\tbool b = Get<bool>();\n\t\t\tM1747(b);\n\t\t\tM1747((bool?)b);\n\t\t}\n\n\t\tprivate static void M1747(bool b)\n\t\t{\n\t\t\tConsole.WriteLine(\"bool=\" + b);\n\t\t}\n\n\t\tprivate static void M1747(bool? b)\n\t\t{\n\t\t\tConsole.WriteLine(\"bool?=\" + b);\n\t\t}\n\n\t\tstatic T Get<T>()\n\t\t{\n\t\t\treturn default(T);\n\t\t}\n\t\t#endregion\n\n\t\t#region IndexerTests\n\t\tstatic void TestIndexer()\n\t\t{\n\t\t\tvar obj = new IndexerTests();\n\t\t\tConsole.WriteLine(obj[(object)5]);\n\t\t\tobj[(object)5] = null;\n\t\t\tConsole.WriteLine(obj[5]);\n\t\t\tobj[5] = null;\n\t\t}\n\t\t#endregion\n\n\t\t#region Out Parameter\n\t\tstatic void AmbiguousOutParam(out string a)\n\t\t{\n\t\t\ta = null;\n\t\t\tConsole.WriteLine(\"AmbiguousOutParam(out string)\");\n\t\t}\n\n\t\tstatic void AmbiguousOutParam(out int b)\n\t\t{\n\t\t\tb = 1;\n\t\t\tConsole.WriteLine(\"AmbiguousOutParam(out int)\");\n\t\t}\n\n\t\tstatic void CallAmbiguousOutParam()\n\t\t{\n\t\t\tConsole.WriteLine(\"CallAmbiguousOutParam:\");\n\t\t\tstring a;\n\t\t\tint b;\n\t\t\tAmbiguousOutParam(out a);\n\t\t\tAmbiguousOutParam(out b);\n\t\t}\n\t\t#endregion\n\n\t\t#region Ref readonly Parameter\n\n\t\tstatic void CallWithRefReadOnlyParam()\n\t\t{\n#if CS120\n#pragma warning disable CS9193\n\t\t\tConsole.WriteLine(\"OverloadSetWithRefReadOnlyParam:\");\n\t\t\tOverloadSetWithRefReadOnlyParam(1);\n\t\t\tOverloadSetWithRefReadOnlyParam(2L);\n\t\t\tint i = 3;\n\t\t\tOverloadSetWithRefReadOnlyParam(in i);\n\t\t\tOverloadSetWithRefReadOnlyParam((long)4);\n\n\t\t\tConsole.WriteLine(\"OverloadSetWithRefReadOnlyParam2:\");\n\t\t\tOverloadSetWithRefReadOnlyParam2(1);\n\t\t\tOverloadSetWithRefReadOnlyParam2((object)1);\n\n\t\t\tConsole.WriteLine(\"OverloadSetWithRefReadOnlyParam3:\");\n\t\t\tOverloadSetWithRefReadOnlyParam3(1);\n\t\t\tOverloadSetWithRefReadOnlyParam3<int>(2);\n\t\t\tOverloadSetWithRefReadOnlyParam3((object)3);\n\n\t\t\tConsole.WriteLine(\"RefReadOnlyVsRegularParam:\");\n\t\t\tRefReadOnlyVsRegularParam(1);\n\t\t\ti = 2;\n\t\t\tRefReadOnlyVsRegularParam(in i);\n#endif\n\t\t}\n\n#if CS120\n\t\tstatic void OverloadSetWithRefReadOnlyParam(ref readonly int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"ref readonly int \" + i);\n\t\t}\n\t\tstatic void OverloadSetWithRefReadOnlyParam(long l)\n\t\t{\n\t\t\tConsole.WriteLine(\"long \" + l);\n\t\t}\n\t\tstatic void OverloadSetWithRefReadOnlyParam2(ref readonly long i)\n\t\t{\n\t\t\tConsole.WriteLine(\"ref readonly long \" + i);\n\t\t}\n\t\tstatic void OverloadSetWithRefReadOnlyParam2(object o)\n\t\t{\n\t\t\tConsole.WriteLine(\"object \" + o);\n\t\t}\n\t\tstatic void OverloadSetWithRefReadOnlyParam3(ref readonly int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"ref readonly int \" + i);\n\t\t}\n\t\tstatic void OverloadSetWithRefReadOnlyParam3<T>(T a)\n\t\t{\n\t\t\tConsole.WriteLine(\"T \" + a);\n\t\t}\n\t\tstatic void RefReadOnlyVsRegularParam(ref readonly int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"ref readonly int \" + i);\n\t\t}\n\t\tstatic void RefReadOnlyVsRegularParam(int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"int \" + i);\n\t\t}\n\n#endif\n\n\t\t#endregion\n\n\t\t#region In Parameter\n\t\tstatic void CallWithInParam()\n\t\t{\n#if CS72\n\t\t\tConsole.WriteLine(\"OverloadSetWithInParam:\");\n\t\t\tOverloadSetWithInParam(1);\n\t\t\tOverloadSetWithInParam(2L);\n\t\t\tint i = 3;\n\t\t\tOverloadSetWithInParam(in i);\n\t\t\tOverloadSetWithInParam((long)4);\n\n\t\t\tConsole.WriteLine(\"OverloadSetWithInParam2:\");\n\t\t\tOverloadSetWithInParam2(1);\n\t\t\tOverloadSetWithInParam2((object)1);\n\n\t\t\tConsole.WriteLine(\"OverloadSetWithInParam3:\");\n\t\t\tOverloadSetWithInParam3(1);\n\t\t\tOverloadSetWithInParam3<int>(2);\n\t\t\tOverloadSetWithInParam3((object)3);\n\n\t\t\tConsole.WriteLine(\"InVsRegularParam:\");\n\t\t\tInVsRegularParam(1);\n\t\t\ti = 2;\n\t\t\tInVsRegularParam(in i);\n#endif\n\t\t}\n\n#if CS72\n\t\tstatic void OverloadSetWithInParam(in int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"in int \" + i);\n\t\t}\n\t\tstatic void OverloadSetWithInParam(long l)\n\t\t{\n\t\t\tConsole.WriteLine(\"long \" + l);\n\t\t}\n\t\tstatic void OverloadSetWithInParam2(in long i)\n\t\t{\n\t\t\tConsole.WriteLine(\"in long \" + i);\n\t\t}\n\t\tstatic void OverloadSetWithInParam2(object o)\n\t\t{\n\t\t\tConsole.WriteLine(\"object \" + o);\n\t\t}\n\t\tstatic void OverloadSetWithInParam3(in int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"in int \" + i);\n\t\t}\n\t\tstatic void OverloadSetWithInParam3<T>(T a)\n\t\t{\n\t\t\tConsole.WriteLine(\"T \" + a);\n\t\t}\n\t\tstatic void InVsRegularParam(in int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"in int \" + i);\n\t\t}\n\t\tstatic void InVsRegularParam(int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"int \" + i);\n\t\t}\n#endif\n\t\t#endregion\n\n#if CS90\n\t\tstatic void NativeIntTests(IntPtr i1, nint i2)\n\t\t{\n\t\t\tConsole.WriteLine(\"NativeIntTests(i1):\");\n\t\t\tObjectOrLong((object)i1);\n\t\t\tObjectOrLong((long)i1);\n\t\t\tConsole.WriteLine(\"NativeIntTests(i2):\");\n\t\t\tObjectOrLong((object)i2);\n\t\t\tObjectOrLong((long)i2);\n\t\t\tConsole.WriteLine(\"NativeIntTests(new IntPtr):\");\n\t\t\tObjectOrLong((object)new IntPtr(3));\n\t\t\tObjectOrLong((long)new IntPtr(3));\n\t\t\tConsole.WriteLine(\"NativeIntTests(IntPtr.Zero):\");\n\t\t\tObjectOrLong((object)IntPtr.Zero);\n\t\t\tObjectOrLong((long)IntPtr.Zero);\n\t\t}\n\n\t\tstatic void ObjectOrLong(object o)\n\t\t{\n\t\t\tConsole.WriteLine(\"object \" + o);\n\t\t}\n\n\t\tstatic void ObjectOrLong(long l)\n\t\t{\n\t\t\tConsole.WriteLine(\"long \" + l);\n\t\t}\n#endif\n\n\t\t#region #2444\n\t\tpublic struct Issue2444\n\t\t{\n\t\t\tpublic class X { }\n\t\t\tpublic class Y { }\n\n\t\t\tpublic static implicit operator Issue2444(X x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"#2444: op_Implicit(X)\");\n\t\t\t\treturn new Issue2444();\n\t\t\t}\n\n\t\t\tpublic static implicit operator Issue2444(Y y)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"#2444: op_Implicit(Y)\");\n\t\t\t\treturn new Issue2444();\n\t\t\t}\n\n\t\t\tpublic static void M1(Issue2444 z)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(string.Format(\"#2444: M1({0})\", z));\n\t\t\t}\n\n\t\t\tpublic static void M2()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"#2444: before M1\");\n\t\t\t\tM1((X)null);\n\t\t\t\tConsole.WriteLine(\"#2444: after M1\");\n\t\t\t}\n\t\t}\n\n\t\tpublic class Issue2741\n\t\t{\n\t\t\tpublic class B\n\t\t\t{\n\t\t\t\tprivate void M()\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"B::M\");\n\t\t\t\t}\n\n\t\t\t\tprotected void M2()\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"B::M2\");\n\t\t\t\t}\n\n\t\t\t\tprotected void M3()\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"B::M3\");\n\t\t\t\t}\n\n\t\t\t\tprotected void M4()\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"B::M4\");\n\t\t\t\t}\n\n\t\t\t\tpublic static void Test(C c)\n\t\t\t\t{\n\t\t\t\t\t((B)c).M();\n\t\t\t\t\t((B)c).M2();\n\t\t\t\t\tc.Test();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic class C : B\n\t\t\t{\n\t\t\t\tpublic void M()\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"C::M\");\n\t\t\t\t}\n\n\t\t\t\tpublic new void M2()\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"C::M2\");\n\t\t\t\t}\n\n\t\t\t\tpublic new void M3()\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"C::M3\");\n\t\t\t\t}\n\n\t\t\t\tpublic void Test()\n\t\t\t\t{\n\t\t\t\t\tM3();\n\t\t\t\t\tbase.M3();\n\t\t\t\t\tM4();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\t}\n\n\tclass IndexerTests\n\t{\n\t\tpublic object this[object key] {\n\t\t\tget {\n\t\t\t\tConsole.WriteLine(\"IndexerTests.get_Item(object key)\");\n\t\t\t\treturn new object();\n\t\t\t}\n\t\t\tset {\n\t\t\t\tConsole.WriteLine(\"IndexerTests.set_Item(object key, object value)\");\n\t\t\t}\n\t\t}\n\n\t\tpublic object this[int key] {\n\t\t\tget {\n\t\t\t\tConsole.WriteLine(\"IndexerTests.get_Item(int key)\");\n\t\t\t\treturn new object();\n\t\t\t}\n\t\t\tset {\n\t\t\t\tConsole.WriteLine(\"IndexerTests.set_Item(int key, object value)\");\n\t\t\t}\n\t\t}\n\t}\n}\n\nnamespace ExtensionMethodDemo\n{\n\t// First extension class with an out int parameter\n\tpublic static class StringExtensions\n\t{\n\t\tpublic static bool TryParseCustom(this string input, out int result)\n\t\t{\n\t\t\treturn int.TryParse(input, out result);\n\t\t}\n\t}\n\n\t// Second extension class with an out double parameter\n\tpublic static class StringDoubleExtensions\n\t{\n\t\tpublic static bool TryParseCustom(this string input, out double result)\n\t\t{\n\t\t\treturn double.TryParse(input, out result);\n\t\t}\n\t}\n\n\tclass Issue2165\n\t{\n\t\tpublic static void Test()\n\t\t{\n\t\t\tstring value1 = \"123\";\n\t\t\tstring value2 = \"123.45\";\n#if CS70\n\t\t\t// Use the int version with extension method syntax\n\t\t\tif (value1.TryParseCustom(out int intResult))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Parsed int: \" + intResult);\n\t\t\t}\n\n\t\t\t// Use the double version with extension method syntax\n\t\t\tif (value2.TryParseCustom(out double doubleResult))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Parsed double: \" + doubleResult);\n\t\t\t}\n#endif\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/PropertiesAndEvents.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tclass PropertiesAndEvents\n\t{\n\t\tpublic static int Main(string[] args)\n\t\t{\n\t\t\tIndex i = new Index();\n\t\t\ti.AutoProp = \"Name\";\n\t\t\tConsole.WriteLine(\"AutoProp set!\");\n\t\t\ti[0] = 5;\n\t\t\ti[1] = 2;\n\t\t\tConsole.WriteLine(\"{0} {1}\", i[0], i[5]);\n\t\t\tConsole.WriteLine(\"PI² = {0}\", i.PISquare);\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\tclass Index\n\t{\n\t\tint thisValue;\n\n\t\tpublic int this[int i] {\n\t\t\tget { Console.WriteLine(\"get_this({0})\", i); return i * i; }\n\t\t\tset { Console.WriteLine(\"set_this({0}, {1})\", i, value); thisValue = value; }\n\t\t}\n\n\t\tpublic string AutoProp { get; set; }\n\n\t\tpublic double PISquare {\n\t\t\tget { Console.WriteLine(\"get_PISquare\"); return Math.Pow(Math.PI, 2); }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/Readme.txt",
    "content": "The files in this folder are correctness tests for the decompiler.\n\nThe NUnit class running these tests is ../../CorrectnessTestRunner.cs.\n\nWe:\n* compile/assemble a test case (call the result \"executable 1\")\n* decompile \"executable 1\" to C# (\"decompiled.cs\")\n* compile decompiled.cs, resulting in \"executable 2\"\n* run both executable and compare their output (exit code, stdout, stderr)\n\nWe repeat the steps above with a few different compiler options (/o+ or not; /debug or not).\n\nThe tests pass if the code compiles without error and produces the same output.\nThe tests do not care at all if the resulting code is pretty, or if any high-level constructs like closures were detected.\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/StackTests.il",
    "content": ".assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )\n  .ver 4:0:0:0\n}\n.assembly StackTests\n{\n  .hash algorithm 0x00008004\n  .ver 1:0:4059:39717\n}\n.module StackTests.exe\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000003    //  ILONLY 32BITREQUIRED\n\n.class private auto ansi beforefieldinit StackTests.Program extends [mscorlib]System.Object\n{\n  .method public hidebysig static void  Main(string[] args) cil managed\n  {\n    .entrypoint\n    .maxstack  8\n\t\n\tldc.i4.0\n\tcall string StackTests.Program::Test1(bool cond)\n\tcall void [mscorlib]System.Console::WriteLine(string) // false\n\t\n\tldc.i4.1\n\tcall string StackTests.Program::Test1(bool cond)\n\tcall void [mscorlib]System.Console::WriteLine(string) // true\n\t\n\tldc.i4.0\n\tldc.i4.0\n\tldc.i4.0\n\tcall int32 StackTests.Program::Test2(int32 switch1, int32 br1, int32 br2)\n\tcall void [mscorlib]System.Console::WriteLine(int32)  // 11\n\t\n\tldc.i4.0\n\tldc.i4.1\n\tldc.i4.0\n\tcall int32 StackTests.Program::Test2(int32 switch1, int32 br1, int32 br2)\n\tcall void [mscorlib]System.Console::WriteLine(int32)  // 21\n\t\n\tldc.i4.1\n\tldc.i4.1\n\tldc.i4.1\n\tcall int32 StackTests.Program::Test2(int32 switch1, int32 br1, int32 br2)\n\tcall void [mscorlib]System.Console::WriteLine(int32)  // 32\n\t\n\tldc.i4.2\n\tldc.i4.1\n\tldc.i4.0\n\tcall int32 StackTests.Program::Test2(int32 switch1, int32 br1, int32 br2)\n\tcall void [mscorlib]System.Console::WriteLine(int32)  // 23\n\t\n\tret\n  }\n\n  .method public hidebysig static string Test1(bool cond) cil managed\n  {\n\tldarg.0\n\tbrtrue TRUE\n\t\n\tFALSE:\n\tldstr \"false\"\n\tbr EXIT\n\t\t\n\tTRUE:\n\tldstr \"true\"\n\t\t\n\tEXIT:\n\tret\n  }\n\n  .method public hidebysig static int32 Test2(int32 switch1, int32 br1, int32 br2) cil managed\n  {\n    ldarg.0\n    switch (ENTRY1, ENTRY2, ENTRY3)\n\tldc.i4.0\n    ret\n\n    ENTRY1:\n\tldc.i4.1\n    br BRANCH1\n\n    ENTRY2:\n\tldc.i4.2\n    br BRANCH1\n\n    ENTRY3:\n\tldc.i4.3\n    br BRANCH2\n\t\n\tBRANCH1:\n\tldarg.1\n\tbrtrue BRANCH2\n\t\n\tEXIT1:\n\tldc.i4 10\n\tadd\n\tret\n\t\n\tBRANCH2:\n\tldarg.2\n\tbrtrue.s EXIT3\n\t\n\tEXIT2:\n\tldc.i4 20\n\tadd\n\tret\n\t\n\tEXIT3:\n\tldc.i4 30\n\tadd\n\tret\n  }\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method Program::.ctor\n\n} // end of class StackTests.Program\n\n\n// =============================================================\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/StackTypes.il",
    "content": ".assembly extern mscorlib\n{\n  .publickeytoken = ( b7 7a 5c 56 19 34 e0 89 )\n  .ver 4:0:0:0\n}\n\n.assembly 'StackTypes'\n{\n  .ver 0:0:0:0\n}\n\n.module StackTypes.exe\n.corflags 0x00000001 // ILOnly\n\n.class private auto ansi abstract sealed beforefieldinit Program\nextends [mscorlib]System.Object\n{\n  .method public hidebysig static void Main (string[] args) cil managed \n  {\n    .maxstack 8\n    .entrypoint\n\n    call void Program::InlineAssignByte()\n    call void Program::Int32OrNativeTests()\n    call void Program::ByRefInstanceCallWithTypeMismatchTests()\n\n    ret\n  } // end of method Main\n\n  .method public static void InlineAssignByte()\n  {\n    .locals init (\n      int8 local\n    )\n    ldstr \"InlineAssignByte: WriteLine(local = {0})\"\n    ldc.i4 300\n    dup\n    br pointless // this pointless branch is a workaround for https://github.com/dotnet/coreclr/issues/14784\n    // it doesn't have any effect on ILSpy as TransformAssignment runs after control-flow reconstruction\npointless:\n    // This assignment cannot be turned into a C# inline assignment, because doing so would truncate to 8 bits.\n    stloc.0\n    box int32\n    call void [mscorlib]System.Console::WriteLine(string, object)\n    ldstr \"InlineAssignByte: local is {0}\"\n    ldloc.0\n    box int32\n    call void [mscorlib]System.Console::WriteLine(string, object)\n    ret\n  }\n\n  .method public static void Int32OrNativeTests()\n  {\n    ldstr \"Int32OrNative(0x7fffffff, false) = {0}\"\n    ldc.i4 0x7fffffff\n    ldc.i4 0\n    call native int Program::Int32OrNative(int32, bool)\n    box native int\n    call void [mscorlib]System.Console::WriteLine(string, object)\n\n    ldstr \"Int32OrNative(0x7fffffff, true) = {0}\"\n    ldc.i4 0x7fffffff\n    ldc.i4 1\n    call native int Program::Int32OrNative(int32, bool)\n    box native int\n    call void [mscorlib]System.Console::WriteLine(string, object)\n\n    ldstr \"Int32OrNative(-1, false) = {0}\"\n    ldc.i4.m1\n    ldc.i4 0\n    call native int Program::Int32OrNative(int32, bool)\n    box native int\n    call void [mscorlib]System.Console::WriteLine(string, object)\n\n    ldstr \"Int32OrNative(-1, true) = {0}\"\n    ldc.i4.m1\n    ldc.i4 1\n    call native int Program::Int32OrNative(int32, bool)\n    box native int\n    call void [mscorlib]System.Console::WriteLine(string, object)\n\n    ldstr \"Int32OrNativeReordered(0x7fffffff, false) = {0}\"\n    ldc.i4 0x7fffffff\n    ldc.i4 0\n    call native int Program::Int32OrNativeReordered(int32, bool)\n    box native int\n    call void [mscorlib]System.Console::WriteLine(string, object)\n\n    ldstr \"Int32OrNativeReordered(0x7fffffff, true) = {0}\"\n    ldc.i4 0x7fffffff\n    ldc.i4 1\n    call native int Program::Int32OrNativeReordered(int32, bool)\n    box native int\n    call void [mscorlib]System.Console::WriteLine(string, object)\n\n    ldstr \"Int32OrNativeReordered(-1, false) = {0}\"\n    ldc.i4.m1\n    ldc.i4 0\n    call native int Program::Int32OrNativeReordered(int32, bool)\n    box native int\n    call void [mscorlib]System.Console::WriteLine(string, object)\n\n    ldstr \"Int32OrNativeReordered(-1, true) = {0}\"\n    ldc.i4.m1\n    ldc.i4 1\n    call native int Program::Int32OrNativeReordered(int32, bool)\n    box native int\n    call void [mscorlib]System.Console::WriteLine(string, object)\n\n    ldstr \"Int32OrNativeLoopStyle(0x7fffffff):\"\n    call void [mscorlib]System.Console::WriteLine(string)\n    ldc.i4 0x7fffffff\n    call void Program::Int32OrNativeLoopStyle(int32)\n\n    ldstr \"Int32OrNativeLoopStyle(-1):\"\n    call void [mscorlib]System.Console::WriteLine(string)\n    ldc.i4.m1\n    call void Program::Int32OrNativeLoopStyle(int32)\n\n    ldstr \"Int32OrNativeDeadCode(0x7fffffff) = {0}\"\n    ldc.i4 0x7fffffff\n    call native int Program::Int32OrNativeDeadCode(int32)\n    box native int\n    call void [mscorlib]System.Console::WriteLine(string, object)\n\n    ldstr \"Int32OrNativeDeadCode(-1) = {0}\"\n    ldc.i4.m1\n    call native int Program::Int32OrNativeDeadCode(int32)\n    box native int\n    call void [mscorlib]System.Console::WriteLine(string, object)\n\n    ldc.i4 0x7fffffff\n    call void Program::RunInt32OrNativeMultiUse(int32)\n    ldc.i4.m1\n    call void Program::RunInt32OrNativeMultiUse(int32)\n\n    ret\n  }\n  .method public static native int Int32OrNative(int32 val, bool use_native)\n  {\n    ldarg.1\n    brtrue use_native_int\n  use_i4:\n    ldarg.0\n    br after_if\n  use_native_int:\n    ldarg.0\n    conv.u\n    br after_if\n  after_if:\n    ldc.i4.1\n    add\n    ret\n  }\n  \n  .method public static native int Int32OrNativeReordered(int32 val, bool use_native)\n  {\n    // The spec is ambiguous whether the addition will be in 32-bits or native size.\n    // The microsoft runtime picks native size.\n    ldarg.1\n    brtrue use_native_int\n  use_i4:\n    ldarg.0\n    br after_if\n  after_if:\n    ldc.i4.1\n    add\n    ret\n  use_native_int:\n    ldarg.0\n    conv.u\n    br after_if\n  }\n  \n  .method public static void Int32OrNativeLoopStyle(int32 val)\n  {\n    // The spec is ambiguous whether the addition will be in 32-bits or native size.\n    // The microsoft runtime picks native size.\n    .locals init (\n      int32 i\n    )\n    ldarg.0\n  loop:\n    ldc.i4.1\n    add\n    call void Program::Print(native int)\n    ldloc.0\n    brtrue end\n\n    ldc.i4.1\n    stloc.0\n    ldarg.0\n    conv.u\n    br loop\n  end:\n    ret\n  }\n\n  .method public static native int Int32OrNativeDeadCode(int32 val)\n  {\n    // The spec is ambiguous whether the addition will be in 32-bits or native size.\n    // The microsoft runtime picks 32-bits.\n  use_i4:\n    ldarg.0\n    br after_if\n  after_if:\n    ldc.i4.1\n    add\n    ret\n  use_native_int: // dead code\n    ldarg.0\n    conv.u\n    br after_if\n  }\n\n  .method public static void RunInt32OrNativeMultiUse(int32 val)\n  {\n    ldstr \"RunInt32OrNativeMultiUse({0}, push_i: false, use2: false) = {1}\"\n    ldarg val\n    box int32\n    ldarg val\n    ldc.i4 0 // push_i\n    ldc.i4 0 // use2\n    call native int Program::Int32OrNativeMultiUse(int32 val, bool push_i, bool use2)\n    box native int\n    call void [mscorlib]System.Console::WriteLine(string, object, object)\n\n    ldstr \"RunInt32OrNativeMultiUse({0}, push_i: false, use2: true) = {1}\"\n    ldarg val\n    box int32\n    ldarg val\n    ldc.i4 0 // push_i\n    ldc.i4 1 // use2\n    call native int Program::Int32OrNativeMultiUse(int32 val, bool push_i, bool use2)\n    box native int\n    call void [mscorlib]System.Console::WriteLine(string, object, object)\n\n    ldstr \"RunInt32OrNativeMultiUse({0}, push_i: true, use2: false) = {1}\"\n    ldarg val\n    box int32\n    ldarg val\n    ldc.i4 1 // push_i\n    ldc.i4 0 // use2\n    call native int Program::Int32OrNativeMultiUse(int32 val, bool push_i, bool use2)\n    box native int\n    call void [mscorlib]System.Console::WriteLine(string, object, object)\n\n    ldstr \"RunInt32OrNativeMultiUse({0}, push_i: true, use2: true) = {1}\"\n    ldarg val\n    box int32\n    ldarg val\n    ldc.i4 1 // push_i\n    ldc.i4 1 // use2\n    call native int Program::Int32OrNativeMultiUse(int32 val, bool push_i, bool use2)\n    box native int\n    call void [mscorlib]System.Console::WriteLine(string, object, object)\n    ret\n  }\n\n  .method public static native int Int32OrNativeMultiUse(int32 val, bool push_i, bool use2)\n  {\n    ldarg.1\n    brtrue push_i\n    br push_i4\n  push_i4:\n    ldarg.0\n    ldarg.2\n    brtrue use2\n    br use1\n  push_i:\n    ldarg.0\n    conv.u\n    br use1\n  use1:\n    ldc.i4.1\n    add\n    ret\n  use2:\n    ldc.i4.2\n    add\n    ret\n  }\n\n  .method public static void RefOrNull(uint8& r, bool use_null)\n  {\n    // Not quite valid IL due to ref<->I mismatch.\n    // https://github.com/icsharpcode/ILSpy/issues/981\n    ldarg.1\n    brtrue push_null\n    ldarg.0\n    br done\n  push_null:\n    ldc.i4.0\n    conv.u\n  done:\n    call void Program::UseRef(uint8&)\n    ret\n  }\n\n  .method public static void UseRef(uint8& r)\n  {\n    ret\n  }\n\n  .method public static void Print(native int val)\n  {\n    ldarg.0\n    box native int\n    call void [mscorlib]System.Console::WriteLine(object)\n    ret\n  }\n\n  .method public static void ByRefInstanceCallWithTypeMismatchTests()\n  {\n    ldstr \"ByRefInstanceCallWithTypeMismatch(0) = {0}\"\n    ldc.i4.0\n    call string Program::ByRefInstanceCallWithTypeMismatch(int32)\n    call void [mscorlib]System.Console::WriteLine(string, object)\n\n    ldstr \"ByRefInstanceCallWithTypeMismatch(1) = {0}\"\n    ldc.i4.1\n    call string Program::ByRefInstanceCallWithTypeMismatch(int32)\n    call void [mscorlib]System.Console::WriteLine(string, object)\n\n    ldstr \"Issue1333() = {0}\"\n    call string Program::Issue1333()\n    call void [mscorlib]System.Console::WriteLine(string, object)\n\n    ret\n  }\n  \n  .method public hidebysig static string ByRefInstanceCallWithTypeMismatch(int32 val) cil managed\n  {\n    ldarga val\n    constrained. [mscorlib]System.Boolean\n    callvirt instance string [mscorlib]System.Object::ToString()\n    ret\n  }\n  \n  .method public hidebysig static string Issue1333() cil managed\n  {\n    .locals (bool)\n    ldc.i4.0\n    stloc.0\n    ldloca.s 0\n    constrained. [mscorlib]System.Boolean\n    callvirt instance string [mscorlib]System.Object::ToString()\n    ret\n  }\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/StringConcat.cs",
    "content": "using System;\nusing System.Runtime.CompilerServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tclass StringConcat\n\t{\n\t\tprivate class C\n\t\t{\n\t\t\tint i;\n\n\t\t\tpublic C(int i)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"  new C(\" + i + \")\");\n\t\t\t\tthis.i = i;\n\t\t\t}\n\n\t\t\tpublic override string ToString()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"  C(\" + i + \").ToString()\");\n\t\t\t\treturn (i++).ToString();\n\t\t\t}\n\t\t}\n\n\t\tprivate struct S\n\t\t{\n\t\t\tint i;\n\n\t\t\tpublic S(int i)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"  new C(\" + i + \")\");\n\t\t\t\tthis.i = i;\n\t\t\t}\n\n\t\t\tpublic override string ToString()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"  S(\" + i + \").ToString()\");\n\t\t\t\treturn (i++).ToString();\n\t\t\t}\n\t\t}\n\n\t\tstatic string Space()\n\t\t{\n\t\t\tConsole.WriteLine(\"  Space()\");\n\t\t\treturn \" \";\n\t\t}\n\n\t\tstatic void TestClass()\n\t\t{\n\t\t\tConsole.WriteLine(\"string + C:\");\n\t\t\tConsole.WriteLine(Space() + new C(1));\n\n\t\t\tConsole.WriteLine(\"C + string:\");\n\t\t\tConsole.WriteLine(new C(2) + Space());\n\n\t\t\tConsole.WriteLine(\"C + string + C:\");\n\t\t\tConsole.WriteLine(new C(3) + Space() + new C(4));\n\n\t\t\tConsole.WriteLine(\"string + C + C:\");\n\t\t\tConsole.WriteLine(Space() + new C(5) + new C(6));\n\n\t\t\tConsole.WriteLine(\"string.Concat(C, string, C):\");\n\t\t\tConsole.WriteLine(string.Concat(new C(10), Space(), new C(11)));\n\n\t\t\tConsole.WriteLine(\"string.Concat(string.Concat(C, string), C):\");\n\t\t\tConsole.WriteLine(string.Concat(string.Concat(new C(15), Space()), new C(16)));\n\n\t\t\tConsole.WriteLine(\"string.Concat(C, string.Concat(string, C)):\");\n\t\t\tConsole.WriteLine(string.Concat(new C(20), string.Concat(Space(), new C(21))));\n\n\t\t\tConsole.WriteLine(\"string.Concat(C, string) + C:\");\n\t\t\tConsole.WriteLine(string.Concat(new C(30), Space()) + new C(31));\n\t\t}\n\n\t\tstatic void TestStruct()\n\t\t{\n\t\t\tConsole.WriteLine(\"string + S:\");\n\t\t\tConsole.WriteLine(Space() + new S(1));\n\n\t\t\tConsole.WriteLine(\"S + string:\");\n\t\t\tConsole.WriteLine(new S(2) + Space());\n\n\t\t\tConsole.WriteLine(\"S + string + S:\");\n\t\t\tConsole.WriteLine(new S(3) + Space() + new S(4));\n\n\t\t\tConsole.WriteLine(\"string + S + S:\");\n\t\t\tConsole.WriteLine(Space() + new S(5) + new S(6));\n\n\t\t\tConsole.WriteLine(\"string.Concat(S, string, S):\");\n\t\t\tConsole.WriteLine(string.Concat(new S(10), Space(), new S(11)));\n\n\t\t\tConsole.WriteLine(\"string.Concat(string.Concat(S, string), S):\");\n\t\t\tConsole.WriteLine(string.Concat(string.Concat(new S(15), Space()), new S(16)));\n\n\t\t\tConsole.WriteLine(\"string.Concat(S, string.Concat(string, S)):\");\n\t\t\tConsole.WriteLine(string.Concat(new S(20), string.Concat(Space(), new S(21))));\n\n\t\t\tConsole.WriteLine(\"string.Concat(S, string) + S:\");\n\t\t\tConsole.WriteLine(string.Concat(new S(30), Space()) + new S(31));\n\t\t}\n\n\t\tstatic void TestStructMutation()\n\t\t{\n\t\t\tConsole.WriteLine(\"TestStructMutation:\");\n\t\t\tS s = new S(0);\n\t\t\tConsole.WriteLine(Space() + s);\n\t\t\tConsole.WriteLine(Space() + s.ToString());\n\t\t\tConsole.WriteLine(s);\n\t\t}\n\n\t\tstatic void TestCharPlusChar(string a)\n\t\t{\n\t\t\tConsole.WriteLine(\"TestCharPlusChar:\");\n\t\t\tConsole.WriteLine(a[0] + a[1]);\n\t\t\tConsole.WriteLine(a[0].ToString() + a[1].ToString());\n\t\t}\n\n#if NET60 && ROSLYN2\n\t\tstatic void TestManualDefaultStringInterpolationHandler()\n\t\t{\n\t\t\tConsole.WriteLine(\"TestManualDefaultStringInterpolationHandler:\");\n\t\t\tC c = new C(42);\n\t\t\tDefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(0, 1);\n\t\t\tdefaultInterpolatedStringHandler.AppendFormatted(c);\n\t\t\tM2(Space(), defaultInterpolatedStringHandler.ToStringAndClear());\n\t\t}\n\n\t\tstatic void M2(object x, string y) { }\n#endif\n\n\t\tstatic void Main()\n\t\t{\n\t\t\tTestClass();\n\t\t\tTestStruct();\n\t\t\tTestStructMutation();\n\t\t\tTestCharPlusChar(\"ab\");\n#if NET60 && ROSLYN2\n\t\t\tTestManualDefaultStringInterpolationHandler();\n#endif\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/Switch.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tpublic static class Switch\n\t{\n\t\tpublic static void Main()\n\t\t{\n\t\t\tTestCase(SparseIntegerSwitch, -100, 1, 2, 3, 4);\n\t\t\tTestCase(ShortSwitchOverString, \"First case\", \"Else\");\n\t\t\tTestCase(ShortSwitchOverString2, \"First case\", \"Second case\", \"Third case\", \"Else\");\n\t\t\tTestCase(ShortSwitchOverStringNoExplicitDefault, \"First case\", \"Second case\", \"Third case\", \"Else\");\n\t\t\tTestCase(SwitchOverString1, \"First case\", \"Second case\", \"2nd case\", \"Third case\", \"Fourth case\", \"Fifth case\", \"Sixth case\", null, \"default\", \"else\");\n\t\t\tConsole.WriteLine(SwitchOverString2());\n\t\t\tConsole.WriteLine(SwitchOverBool(true));\n\t\t\tConsole.WriteLine(SwitchOverBool(false));\n\t\t\tSwitchInLoop(0);\n\t\t\tSwitchWithGoto(1);\n\t\t\tSwitchWithGoto(2);\n\t\t\tSwitchWithGoto(3);\n\t\t\tSwitchWithGoto(4);\n\t\t}\n\n\t\tstatic void TestCase<T>(Func<T, string> target, params T[] args)\n\t\t{\n\t\t\tforeach (var arg in args)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(target(arg));\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SparseIntegerSwitch(int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"SparseIntegerSwitch: \" + i);\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase -10000000:\n\t\t\t\t\treturn \"-10 mln\";\n\t\t\t\tcase -100:\n\t\t\t\t\treturn \"-hundred\";\n\t\t\t\tcase -1:\n\t\t\t\t\treturn \"-1\";\n\t\t\t\tcase 0:\n\t\t\t\t\treturn \"0\";\n\t\t\t\tcase 1:\n\t\t\t\t\treturn \"1\";\n\t\t\t\tcase 2:\n\t\t\t\t\treturn \"2\";\n\t\t\t\tcase 4:\n\t\t\t\t\treturn \"4\";\n\t\t\t\tcase 100:\n\t\t\t\t\treturn \"hundred\";\n\t\t\t\tcase 10000:\n\t\t\t\t\treturn \"ten thousand\";\n\t\t\t\tcase 10001:\n\t\t\t\t\treturn \"ten thousand and one\";\n\t\t\t\tcase int.MaxValue:\n\t\t\t\t\treturn \"int.MaxValue\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"something else\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string ShortSwitchOverString(string text)\n\t\t{\n\t\t\tConsole.WriteLine(\"ShortSwitchOverString: \" + text);\n\t\t\tswitch (text)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string ShortSwitchOverString2(string text)\n\t\t{\n\t\t\tConsole.WriteLine(\"ShortSwitchOverString2: \" + text);\n\t\t\tswitch (text)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase \"Third case\":\n\t\t\t\t\treturn \"Text3\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string ShortSwitchOverStringNoExplicitDefault(string text)\n\t\t{\n\t\t\tConsole.WriteLine(\"ShortSwitchOverStringNoExplicitDefault: \" + text);\n\t\t\tswitch (text)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase \"Third case\":\n\t\t\t\t\treturn \"Text3\";\n\t\t\t}\n\t\t\treturn \"Default\";\n\t\t}\n\n\t\tpublic static string SwitchOverString1(string text)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchOverString1: \" + text);\n\t\t\tswitch (text)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\tcase \"2nd case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase \"Third case\":\n\t\t\t\t\treturn \"Text3\";\n\t\t\t\tcase \"Fourth case\":\n\t\t\t\t\treturn \"Text4\";\n\t\t\t\tcase \"Fifth case\":\n\t\t\t\t\treturn \"Text5\";\n\t\t\t\tcase \"Sixth case\":\n\t\t\t\t\treturn \"Text6\";\n\t\t\t\tcase null:\n\t\t\t\t\treturn null;\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverString2()\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchOverString2:\");\n\t\t\tswitch (Environment.UserName)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase \"Third case\":\n\t\t\t\t\treturn \"Text3\";\n\t\t\t\tcase \"Fourth case\":\n\t\t\t\t\treturn \"Text4\";\n\t\t\t\tcase \"Fifth case\":\n\t\t\t\t\treturn \"Text5\";\n\t\t\t\tcase \"Sixth case\":\n\t\t\t\t\treturn \"Text6\";\n\t\t\t\tcase \"Seventh case\":\n\t\t\t\t\treturn \"Text7\";\n\t\t\t\tcase \"Eighth case\":\n\t\t\t\t\treturn \"Text8\";\n\t\t\t\tcase \"Ninth case\":\n\t\t\t\t\treturn \"Text9\";\n\t\t\t\tcase \"Tenth case\":\n\t\t\t\t\treturn \"Text10\";\n\t\t\t\tcase \"Eleventh case\":\n\t\t\t\t\treturn \"Text11\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverBool(bool b)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchOverBool: \" + b);\n\t\t\tswitch (b)\n\t\t\t{\n\t\t\t\tcase true:\n\t\t\t\t\treturn bool.TrueString;\n\t\t\t\tcase false:\n\t\t\t\t\treturn bool.FalseString;\n\t\t\t\tdefault:\n#pragma warning disable CS0162\n\t\t\t\t\treturn null;\n#pragma warning restore CS0162\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SwitchInLoop(int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchInLoop: \" + i);\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tswitch (i)\n\t\t\t\t{\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tConsole.WriteLine(\"one\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tConsole.WriteLine(\"two\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\tConsole.WriteLine(\"three\");\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tcase 4:\n\t\t\t\t\t\tConsole.WriteLine(\"four\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t\t\t\tConsole.WriteLine(\"more code\");\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SwitchWithGoto(int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchWithGoto: \" + i);\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase 1:\n\t\t\t\t\tConsole.WriteLine(\"one\");\n\t\t\t\t\tgoto default;\n\t\t\t\tcase 2:\n\t\t\t\t\tConsole.WriteLine(\"two\");\n\t\t\t\t\tgoto case 3;\n\t\t\t\tcase 3:\n\t\t\t\t\tConsole.WriteLine(\"three\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 4:\n\t\t\t\t\tConsole.WriteLine(\"four\");\n\t\t\t\t\treturn;\n\t\t\t\tdefault:\n\t\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/TrickyTypes.cs",
    "content": "// Copyright (c) 2017 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Linq;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tclass TrickyTypes\n\t{\n\t\tstatic void Main()\n\t\t{\n\t\t\tInterestingConstants();\n\t\t\tTruncatedComp();\n\t\t\tStringConcat();\n\t\t\tLinqNullableMin();\n\t\t\tLinqNullableMin(1, 2, 3);\n\t\t\tUnboxingToWrongType();\n\t\t}\n\n\t\tstatic void Print<T>(T val)\n\t\t{\n\t\t\tConsole.Write(typeof(T).Name + \": \");\n\t\t\tif (val == null)\n\t\t\t\tConsole.WriteLine(\"null\");\n\t\t\telse\n\t\t\t\tConsole.WriteLine(val);\n\t\t}\n\n\t\tstatic void InterestingConstants()\n\t\t{\n\t\t\tlong val1 = 2147483648L;\n\t\t\tuint val2 = 2147483648u;\n\t\t\tConsole.WriteLine(\"InterestingConstants:\");\n\t\t\tPrint(val1);\n\t\t\tPrint(2147483648L);\n\t\t\tPrint(val2);\n\t\t\tPrint(2147483648u);\n\t\t}\n\n\t\tstatic void TruncatedComp()\n\t\t{\n\t\t\tConsole.WriteLine(\"TruncatedComp1(1):\");\n\t\t\tTruncatedComp1(1);\n\n\t\t\tConsole.WriteLine(\"TruncatedComp1(-1):\");\n\t\t\tTruncatedComp1(-1);\n\n\t\t\tConsole.WriteLine(\"TruncatedComp1(0x100000001):\");\n\t\t\tTruncatedComp1(0x100000001);\n\n\t\t\tConsole.WriteLine(\"TruncatedComp1(long.MinValue):\");\n\t\t\tTruncatedComp1(long.MinValue);\n\n\t\t\tConsole.WriteLine(\"TruncatedComp2(1):\");\n\t\t\tTruncatedComp2(1, 1);\n\n\t\t\tConsole.WriteLine(\"TruncatedComp2(-1):\");\n\t\t\tTruncatedComp2(-1, -1);\n\n\t\t\tConsole.WriteLine(\"TruncatedComp2(0x100000001):\");\n\t\t\tTruncatedComp2(0x100000001, 1);\n\n\t\t\tConsole.WriteLine(\"TruncatedComp2(long.MinValue):\");\n\t\t\tTruncatedComp2(long.MinValue, int.MinValue);\n\t\t}\n\n\t\tstatic void TruncatedComp1(long val)\n\t\t{\n\t\t\tPrint((int)val == val);\n\t\t\tPrint(val == (int)val);\n\t\t\tPrint(val < (int)val);\n\t\t\tPrint((int)val >= val);\n\t\t}\n\n\t\tstatic void TruncatedComp2(long val1, int val2)\n\t\t{\n\t\t\tPrint(val1 == val2);\n\t\t\tPrint((int)val1 == val2);\n\t\t\tPrint(val1 < val2);\n\t\t\tPrint((int)val1 < val2);\n\t\t\tPrint(val1 <= val2);\n\t\t\tPrint((int)val1 <= val2);\n\t\t}\n\n\t\tstatic void StringConcat()\n\t\t{\n\t\t\t// Some string.Concat()-cases that cannot be replaced using operator+\n\t\t\tPrint(string.Concat(\"String concat:\"));\n\t\t\tPrint(string.Concat(1, 2));\n\t\t\tPrint(string.Concat(1, 2, \"str\"));\n\t\t}\n\n\t\tstatic void LinqNullableMin(params int[] arr)\n\t\t{\n\t\t\tPrint(string.Format(\"LinqNullableMin {0}:\", arr.Length));\n\t\t\tPrint(arr.Min(v => (int?)v));\n\t\t}\n\n\t\tstatic void UnboxingToWrongType()\n\t\t{\n\t\t\tConsole.WriteLine(\"UnboxingToWrongType:\");\n\t\t\tobject o = 3.50;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tPrint((long)o);\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.GetType().Name + \": \" + ex.Message);\n\t\t\t}\n\t\t\ttry\n\t\t\t{\n\t\t\t\tPrint(o as long?);\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.GetType().Name + \": \" + ex.Message);\n\t\t\t}\n\t\t\ttry\n\t\t\t{\n\t\t\t\tPrint((long)(o as long?));\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.GetType().Name + \": \" + ex.Message);\n\t\t\t}\n\t\t\ttry\n\t\t\t{\n\t\t\t\tPrint((long)(o is long ? o : null));\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.GetType().Name + \": \" + ex.Message);\n\t\t\t}\n#if CS90\n\t\t\tif (o is not 0L)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Not 0L\");\n\t\t\t}\n#endif\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/UndocumentedExpressions.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tpublic class UndocumentedExpressions\n\t{\n\t\tstatic void Main(string[] args)\n\t\t{\n\t\t\tMakeTypedRef(\"abc\");\n\t\t\tVarArgs(1, __arglist());\n\t\t\tVarArgs(__arglist(1));\n\t\t\tVarArgs(1, __arglist(\"abc\", 2, true));\n\t\t\tVarArgs(1, __arglist((object)\"abc\", 2, true));\n\t\t\tVarArgs(1, __arglist((short)1));\n\t\t\tVarArgs(1, __arglist(ConsoleColor.Red));\n\t\t}\n\n\t\tpublic static void VarArgs(int normalArg, __arglist)\n\t\t{\n\t\t\tArgIterator argIterator = new ArgIterator(__arglist);\n\t\t\tConsole.WriteLine(\"Called with {0} arguments\", argIterator.GetRemainingCount());\n\t\t\tint pos = 0;\n\t\t\twhile (argIterator.GetRemainingCount() > 0)\n\t\t\t{\n\t\t\t\tTypedReference tr = argIterator.GetNextArg();\n\t\t\t\tobject val;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tval = __refvalue(tr, object);\n\t\t\t\t}\n\t\t\t\tcatch (Exception ex)\n\t\t\t\t{\n\t\t\t\t\tval = ex.GetType().Name;\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(\"{0} : {1} = {2}\", pos++, __reftype(tr).Name, val);\n\t\t\t}\n\t\t}\n\n\t\tpublic static void VarArgs(__arglist)\n\t\t{\n\t\t\tConsole.WriteLine(\"The other varargs overload\");\n\t\t}\n\n\t\tpublic static void MakeTypedRef(object o)\n\t\t{\n\t\t\tTypedReference tr = __makeref(o);\n\t\t\tUndocumentedExpressions.AcceptTypedRef(tr);\n\t\t}\n\n\t\tprivate static void AcceptTypedRef(TypedReference tr)\n\t\t{\n\t\t\tConsole.WriteLine(\"Value is: \" + __refvalue(tr, object).ToString());\n\t\t\tConsole.WriteLine(\"Type is: \" + __reftype(tr).Name);\n\t\t\t__refvalue(tr, object) = 1;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/Uninit.vb",
    "content": "Imports System\n\nModule UninitTest\n    Sub Main()\n        Dim i = 0\n        Dim result As Integer = -5\n        Dim num As Integer\n        Do\n            If num > result Then\n                num += 5\n                result += 5\n            End If\n            result += 1\n            i += 1\n            If i > 10 Then\n                Exit Do\n            End If\n        Loop\n        Console.WriteLine(result)\n    End Sub\nEnd Module"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/UnsafeCode.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tpublic class UnsafeCode\n\t{\n\t\tprivate struct SimpleStruct\n\t\t{\n\t\t\tpublic int X;\n\t\t\tpublic double Y;\n\t\t}\n\n\t\tstatic void Main()\n\t\t{\n\t\t\t// TODO: test behavior, or convert this into a pretty-test\n\t\t\t// (but for now, it's already valuable knowing whether the decompiled code can be re-compiled)\n\t\t}\n\n\t\tpublic unsafe int MultipleExitsOutOfFixedBlock(int[] arr)\n\t\t{\n\t\t\tfixed (int* ptr = &arr[0])\n\t\t\t{\n\t\t\t\tif (*ptr < 0)\n\t\t\t\t\treturn *ptr;\n\t\t\t\tif (*ptr == 21)\n\t\t\t\t\treturn 42;\n\t\t\t\tif (*ptr == 42)\n\t\t\t\t\tgoto outside;\n\t\t\t}\n\t\t\treturn 1;\n\t\t\toutside:\n\t\t\tConsole.WriteLine(\"outside\");\n\t\t\treturn 2;\n\t\t}\n\n\t\tpublic unsafe void FixMultipleStrings(string text)\n\t\t{\n\t\t\tfixed (char* ptr = text, userName = Environment.UserName, ptr2 = text)\n\t\t\t{\n\t\t\t\t*ptr = 'c';\n\t\t\t\t*userName = 'd';\n\t\t\t\t*ptr2 = 'e';\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe byte* PointerArithmetic2(long* p, int y, int x)\n\t\t{\n\t\t\treturn (byte*)((short*)p + (y * x));\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/Using.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tclass Using\n\t{\n\t\tclass PrintOnDispose : IDisposable\n\t\t{\n\t\t\tprivate string v;\n\n\t\t\tpublic PrintOnDispose(string v)\n\t\t\t{\n\t\t\t\tthis.v = v;\n\t\t\t}\n\n\t\t\tpublic void Dispose()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(this.v);\n\t\t\t}\n\t\t}\n\n\t\tstatic void Main()\n\t\t{\n\t\t\tSimpleUsingNullStatement();\n\t\t\tNoUsingDueToAssignment();\n\t\t\tNoUsingDueToAssignment2();\n\t\t\tNoUsingDueToByRefCall();\n\t\t\tNoUsingDueToContinuedDisposableUse();\n\t\t\tContinuedObjectUse();\n\t\t\tVariableAlreadyUsedBefore();\n\t\t\tUsingObject();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Special case: Roslyn eliminates the try-finally altogether.\n\t\t/// </summary>\n\t\tpublic static void SimpleUsingNullStatement()\n\t\t{\n\t\t\tConsole.WriteLine(\"before using\");\n\t\t\t// Mono has a compiler bug and introduces an assembly reference to [gmcs] here...\n#if !MCS\n\t\t\tusing (null)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"using (null)\");\n\t\t\t}\n#endif\n\t\t\tConsole.WriteLine(\"after using\");\n\t\t}\n\n\t\tpublic static void NoUsingDueToAssignment()\n\t\t{\n\t\t\tPrintOnDispose printOnDispose = new PrintOnDispose(\"Wrong\");\n\t\t\ttry\n\t\t\t{\n\t\t\t\tprintOnDispose = new PrintOnDispose(\"Correct\");\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tprintOnDispose.Dispose();\n\t\t\t}\n\t\t}\n\n\t\tpublic static void NoUsingDueToAssignment2()\n\t\t{\n\t\t\tPrintOnDispose printOnDispose = new PrintOnDispose(\"NoUsing(): Wrong\");\n\t\t\ttry\n\t\t\t{\n\t\t\t\tprintOnDispose = new PrintOnDispose(\"NoUsing(): Correct\");\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tIDisposable disposable = (object)printOnDispose as IDisposable;\n\t\t\t\tif (disposable != null)\n\t\t\t\t{\n\t\t\t\t\tdisposable.Dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic void Clear<T>(ref T t)\n\t\t{\n\t\t\tt = default(T);\n\t\t}\n\n\t\tpublic static void NoUsingDueToByRefCall()\n\t\t{\n\t\t\tPrintOnDispose printOnDispose = new PrintOnDispose(\"NoUsingDueToByRefCall(): Wrong\");\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"NoUsingDueToByRefCall\");\n\t\t\t\tClear(ref printOnDispose);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tIDisposable disposable = (object)printOnDispose as IDisposable;\n\t\t\t\tif (disposable != null)\n\t\t\t\t{\n\t\t\t\t\tdisposable.Dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static void NoUsingDueToContinuedDisposableUse()\n\t\t{\n\t\t\tvar obj = new System.IO.StringWriter();\n\t\t\tIDisposable disposable;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tobj.WriteLine(\"NoUsingDueToContinuedDisposableUse\");\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tdisposable = (object)obj as IDisposable;\n\t\t\t\tif (disposable != null)\n\t\t\t\t{\n\t\t\t\t\tdisposable.Dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t\tConsole.WriteLine(disposable);\n\t\t}\n\n\t\tpublic static void ContinuedObjectUse()\n\t\t{\n\t\t\tvar obj = new System.IO.StringWriter();\n\t\t\ttry\n\t\t\t{\n\t\t\t\tobj.WriteLine(\"ContinuedObjectUse\");\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tIDisposable disposable = (object)obj as IDisposable;\n\t\t\t\tif (disposable != null)\n\t\t\t\t{\n\t\t\t\t\tdisposable.Dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t\tConsole.WriteLine(obj);\n\t\t}\n\n\t\tpublic static void VariableAlreadyUsedBefore()\n\t\t{\n\t\t\tSystem.IO.StringWriter obj = new System.IO.StringWriter();\n\t\t\tobj.Write(\"VariableAlreadyUsedBefore - 1\");\n\t\t\tConsole.WriteLine(obj);\n\t\t\tobj = new System.IO.StringWriter();\n\t\t\ttry\n\t\t\t{\n\t\t\t\tobj.WriteLine(\"VariableAlreadyUsedBefore - 2\");\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tIDisposable disposable = (object)obj as IDisposable;\n\t\t\t\tif (disposable != null)\n\t\t\t\t{\n\t\t\t\t\tdisposable.Dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static void UsingObject()\n\t\t{\n\t\t\tobject obj = new object();\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"UsingObject: {0}\", obj);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tIDisposable disposable = obj as IDisposable;\n\t\t\t\tif (disposable != null)\n\t\t\t\t{\n\t\t\t\t\tdisposable.Dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/ValueTypeCall.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tpublic struct MutValueType : IDisposable\n\t{\n\t\tpublic int val;\n\n\t\tpublic void Increment()\n\t\t{\n\t\t\tConsole.WriteLine(\"Inc() called on {0}\", val);\n\t\t\tval = val + 1;\n\t\t}\n\n\t\tpublic void Dispose()\n\t\t{\n\t\t\tConsole.WriteLine(\"MutValueType disposed on {0}\", val);\n\t\t\tval = val + 1;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn \"MutValueType.ToString() \" + (++val);\n\t\t}\n\t}\n\n\tpublic struct GenericValueType<T>\n\t{\n\t\tT data;\n\t\tint num;\n\n\t\tpublic GenericValueType(T data)\n\t\t{\n\t\t\tthis.data = data;\n\t\t\tthis.num = 1;\n\t\t}\n\n\t\tpublic void Call(ref GenericValueType<T> v)\n\t\t{\n\t\t\tnum++;\n\t\t\tConsole.WriteLine(\"Call #{0}: {1} with v=#{2}\", num, data, v.num);\n\t\t}\n\t}\n\n\tpublic struct ValueTypeWithReadOnlyMember\n\t{\n\t\tpublic readonly int Member;\n\n\t\tpublic ValueTypeWithReadOnlyMember(int member)\n\t\t{\n\t\t\tthis.Member = member;\n\t\t}\n\t}\n\n\tpublic class ValueTypeCall\n\t{\n\t\tpublic static void Main()\n\t\t{\n\t\t\tMutValueType m = new MutValueType();\n\t\t\tRefParameter(ref m);\n\t\t\tValueParameter(m);\n\t\t\tField();\n\t\t\tBox();\n\t\t\tBoxToStringCalls();\n\t\t\tUsing();\n\t\t\tvar gvt = new GenericValueType<string>(\"Test\");\n\t\t\tgvt.Call(ref gvt);\n\t\t\tnew ValueTypeCall().InstanceFieldTests();\n\t\t\tForEach();\n#if CS73\n\t\t\tDisposeMultipleTimes(ref m, in m);\n\t\t\tToStringGeneric(ref m, in m);\n#endif\n\t\t}\n\n\t\tstatic void RefParameter(ref MutValueType m)\n\t\t{\n\t\t\tm.Increment();\n\t\t\tm.Increment();\n\t\t}\n\n\t\tstatic void ValueParameter(MutValueType m)\n\t\t{\n\t\t\tm.Increment();\n\t\t\tm.Increment();\n\t\t}\n\n\t\tstatic readonly MutValueType ReadonlyField = new MutValueType { val = 100 };\n\t\tstatic MutValueType MutableField = new MutValueType { val = 200 };\n\n\t\tstatic void Field()\n\t\t{\n\t\t\tReadonlyField.Increment();\n\t\t\tReadonlyField.Increment();\n\t\t\tMutableField.Increment();\n\t\t\tMutableField.Increment();\n\t\t\t// Ensure that 'v' isn't incorrectly removed\n\t\t\t// as a compiler-generated temporary\n\t\t\tMutValueType v = MutableField;\n\t\t\tv.Increment();\n\t\t\tConsole.WriteLine(\"Final value in MutableField: \" + MutableField.val);\n\t\t\t// Read-only field copies cannot be inlined for static methods:\n\t\t\tMutValueType localCopy = ReadonlyField;\n\t\t\tRefParameter(ref localCopy);\n\t\t}\n\n\t\tstatic void Box()\n\t\t{\n\t\t\tConsole.WriteLine(\"Box\");\n\t\t\tobject o = new MutValueType { val = 300 };\n\t\t\t((MutValueType)o).Increment();\n\t\t\t((MutValueType)o).Increment();\n\t\t\tMutValueType unboxed1 = (MutValueType)o;\n\t\t\tunboxed1.Increment();\n\t\t\tunboxed1.Increment();\n\t\t\t((MutValueType)o).Increment();\n\t\t\tMutValueType unboxed2 = (MutValueType)o;\n\t\t\tunboxed2.val = 100;\n\t\t\t((MutValueType)o).Dispose();\n\t\t}\n\n\t\tstatic void BoxToStringCalls()\n\t\t{\n\t\t\tConsole.WriteLine(\"BoxToStringCalls:\");\n\t\t\tMutValueType m = new MutValueType { val = 400 };\n\t\t\tConsole.WriteLine(m.ToString());\n\t\t\tConsole.WriteLine(((object)m).ToString());\n\t\t\tConsole.WriteLine(m.ToString());\n\t\t}\n\n\t\tMutValueType instanceField;\n\t\tValueTypeWithReadOnlyMember mutableInstanceFieldWithReadOnlyMember;\n\n\t\tvoid InstanceFieldTests()\n\t\t{\n\t\t\tthis.instanceField.val = 42;\n\t\t\tConsole.WriteLine(this.instanceField.val);\n\t\t\tmutableInstanceFieldWithReadOnlyMember = new ValueTypeWithReadOnlyMember(45);\n\t\t\tConsole.WriteLine(this.mutableInstanceFieldWithReadOnlyMember.Member);\n\t\t}\n\n\t\tstatic void Using()\n\t\t{\n\t\t\tUsing1();\n\t\t\tUsing2();\n\t\t\tUsing3();\n\t\t}\n\n\t\tstatic void Using1()\n\t\t{\n\t\t\tConsole.WriteLine(\"Using:\");\n\t\t\tusing (var x = new MutValueType())\n\t\t\t{\n\t\t\t\tx.Increment();\n\t\t\t}\n\t\t}\n\n\t\tstatic void Using2()\n\t\t{\n\t\t\tConsole.WriteLine(\"Not using:\");\n\t\t\tvar y = new MutValueType();\n\t\t\ttry\n\t\t\t{\n\t\t\t\ty.Increment();\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tMutValueType x = y;\n\t\t\t\tx.Dispose();\n\t\t\t}\n\t\t}\n\n\t\tstatic void Using3()\n\t\t{\n\t\t\tConsole.WriteLine(\"Using with variable declared outside:\");\n\t\t\tMutValueType z;\n\t\t\tusing (z = new MutValueType())\n\t\t\t{\n\t\t\t\tz.Increment();\n\t\t\t}\n\t\t}\n\n\t\tstatic void ForEach()\n\t\t{\n\t\t\tvar list = new List<MutValueType> {\n\t\t\t\tnew MutValueType { val = 10 },\n\t\t\t\tnew MutValueType { val = 20 },\n\t\t\t\tnew MutValueType { val = 30 },\n\t\t\t};\n\t\t\tForEach1(list);\n\t\t\tvar array = new MutValueType[] {\n\t\t\t\tnew MutValueType { val = 100 },\n\t\t\t\tnew MutValueType { val = 200 },\n\t\t\t\tnew MutValueType { val = 300 },\n\t\t\t};\n\t\t\tForEachArray1(array);\n\t\t}\n\n\t\tstatic void ForEach1(List<MutValueType> list)\n\t\t{\n\t\t\tConsole.WriteLine(\"ForEach1:\");\n\t\t\tforeach (var val in list)\n\t\t\t{\n\t\t\t\tval.Increment();\n\t\t\t\tval.Increment();\n\t\t\t}\n\t\t\tConsole.WriteLine(\"after: \" + list[0].val);\n\t\t}\n\n\t\tstatic void ForEachArray1(MutValueType[] list)\n\t\t{\n\t\t\tConsole.WriteLine(\"ForEachArray1:\");\n\t\t\tforeach (var val in list)\n\t\t\t{\n\t\t\t\tval.Increment();\n\t\t\t\tval.Increment();\n\t\t\t}\n\t\t\tConsole.WriteLine(\"after: \" + list[0].val);\n\t\t}\n\n#if CS73\n\t\tstatic void DisposeMultipleTimes<T>(ref T mutRef, in T immutableRef) where T : struct, IDisposable\n\t\t{\n\t\t\tConsole.WriteLine(\"DisposeMultipleTimes:\");\n\t\t\tmutRef.Dispose();\n\t\t\tmutRef.Dispose();\n\t\t\tT copyFromMut = mutRef;\n\t\t\tcopyFromMut.Dispose();\n\t\t\timmutableRef.Dispose();\n\t\t\timmutableRef.Dispose();\n\t\t\tT copyFromImmutable = immutableRef;\n\t\t\tcopyFromImmutable.Dispose();\n\t\t\tmutRef.Dispose();\n\t\t\timmutableRef.Dispose();\n\t\t}\n\n\t\tstatic void ToStringGeneric<T>(ref T mutRef, in T immutableRef) where T : struct\n\t\t{\n\t\t\tConsole.WriteLine(\"ToStringGeneric:\");\n\t\t\tConsole.WriteLine(mutRef.ToString());\n\t\t\tConsole.WriteLine(mutRef.ToString());\n\t\t\tT copyFromMut = mutRef;\n\t\t\tConsole.WriteLine(copyFromMut.ToString());\n\t\t\tConsole.WriteLine(immutableRef.ToString());\n\t\t\tConsole.WriteLine(immutableRef.ToString());\n\t\t\tT copyFromImmutable = immutableRef;\n\t\t\tConsole.WriteLine(copyFromImmutable.ToString());\n\t\t\tConsole.WriteLine(mutRef.ToString());\n\t\t\tConsole.WriteLine(immutableRef.ToString());\n\t\t}\n#endif\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Correctness/YieldReturn.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Correctness\n{\n\tpublic class YieldReturnTest\n\t{\n\t\tstatic void Main()\n\t\t{\n\t\t\tPrint(\"SimpleYieldReturn\", SimpleYieldReturn().GetEnumerator());\n\t\t\tPrint(\"SimpleYieldReturnEnumerator\", SimpleYieldReturnEnumerator());\n\t\t\tPrint(\"YieldReturnParameters\",\n\t\t\t\tnew YieldReturnTest { fieldOnThis = 1 }.YieldReturnParameters(2).GetEnumerator());\n\t\t\tPrint(\"YieldReturnParametersEnumerator\",\n\t\t\t\tnew YieldReturnTest { fieldOnThis = 1 }.YieldReturnParametersEnumerator(2));\n\t\t\tPrint(\"YieldReturnInLoop\", YieldReturnInLoop().GetEnumerator());\n\t\t\tPrint(\"YieldReturnWithTryFinally\", YieldReturnWithTryFinally().GetEnumerator());\n\t\t\tPrint(\"YieldReturnInLock1\", YieldReturnInLock1(new object()).GetEnumerator());\n\t\t\tPrint(\"YieldReturnInLock2\", YieldReturnInLock2(new object()).GetEnumerator());\n\t\t\tPrint(\"YieldReturnWithNestedTryFinally(false)\", YieldReturnWithNestedTryFinally(false).GetEnumerator());\n\t\t\tPrint(\"YieldReturnWithNestedTryFinally(true)\", YieldReturnWithNestedTryFinally(true).GetEnumerator());\n\t\t\tPrint(\"YieldReturnWithTwoNonNestedFinallyBlocks\", YieldReturnWithTwoNonNestedFinallyBlocks(SimpleYieldReturn()).GetEnumerator());\n\t\t\t// TODO: check anon methods\n\t\t\tPrint(\"GetEvenNumbers\", GetEvenNumbers(3).GetEnumerator());\n\t\t\tPrint(\"YieldChars\", YieldChars.GetEnumerator());\n\t\t\tPrint(\"ExceptionHandling\", ExceptionHandling().GetEnumerator());\n\t\t\tPrint(\"YieldBreakInCatch\", YieldBreakInCatch().GetEnumerator());\n\t\t\tPrint(\"YieldBreakInCatchInTryFinally\", YieldBreakInCatchInTryFinally().GetEnumerator());\n\t\t\tPrint(\"YieldBreakInTryCatchInTryFinally\", YieldBreakInTryCatchInTryFinally().GetEnumerator());\n\t\t\tPrint(\"YieldBreakInTryFinallyInTryFinally(false)\", YieldBreakInTryFinallyInTryFinally(false).GetEnumerator());\n\t\t\tPrint(\"YieldBreakInTryFinallyInTryFinally(true)\", YieldBreakInTryFinallyInTryFinally(true).GetEnumerator());\n\t\t\ttry\n\t\t\t{\n\t\t\t\tPrint(\"UnconditionalThrowInTryFinally()\", UnconditionalThrowInTryFinally().GetEnumerator());\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.Message);\n\t\t\t}\n\t\t\tPrint(\"NestedTryFinallyStartingOnSamePosition\", NestedTryFinallyStartingOnSamePosition().GetEnumerator());\n\t\t\tPrint(\"TryFinallyWithTwoExitPoints(false)\", TryFinallyWithTwoExitPoints(false).GetEnumerator());\n\t\t\tPrint(\"TryFinallyWithTwoExitPoints(true)\", TryFinallyWithTwoExitPoints(true).GetEnumerator());\n#if !LEGACY_CSC\n\t\t\tPrint(\"YieldBreakInNestedTryFinally()\", YieldBreakInNestedTryFinally().GetEnumerator());\n\t\t\tPrint(\"TryFinallyWithTwoExitPointsInNestedTry(false)\", TryFinallyWithTwoExitPointsInNestedTry(false).GetEnumerator());\n\t\t\tPrint(\"TryFinallyWithTwoExitPointsInNestedTry(true)\", TryFinallyWithTwoExitPointsInNestedTry(true).GetEnumerator());\n\t\t\tPrint(\"TryFinallyWithTwoExitPointsInNestedCatch(false)\", TryFinallyWithTwoExitPointsInNestedCatch(false).GetEnumerator());\n\t\t\tPrint(\"TryFinallyWithTwoExitPointsInNestedCatch(true)\", TryFinallyWithTwoExitPointsInNestedCatch(true).GetEnumerator());\n#endif\n\t\t\tPrint(\"GenericYield<int>()\", GenericYield<int>().GetEnumerator());\n\t\t\tStructWithYieldReturn.Run();\n\t\t}\n\n\t\tinternal static void Print<T>(string name, IEnumerator<T> enumerator)\n\t\t{\n\t\t\tConsole.WriteLine(name + \": Test start\");\n\t\t\twhile (enumerator.MoveNext())\n\t\t\t{\n\t\t\t\tConsole.WriteLine(name + \": \" + enumerator.Current);\n\t\t\t}\n\t\t}\n\n\t\tint fieldOnThis;\n\n\t\tpublic static IEnumerable<char> YieldChars {\n\t\t\tget {\n\t\t\t\tyield return 'a';\n\t\t\t\tyield return 'b';\n\t\t\t\tyield return 'c';\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<string> SimpleYieldReturn()\n\t\t{\n\t\t\tyield return \"A\";\n\t\t\tyield return \"B\";\n\t\t\tyield return \"C\";\n\t\t}\n\n\t\tpublic static IEnumerator<string> SimpleYieldReturnEnumerator()\n\t\t{\n\t\t\tyield return \"A\";\n\t\t\tyield return \"B\";\n\t\t\tyield return \"C\";\n\t\t}\n\n\t\tpublic IEnumerable<int> YieldReturnParameters(int p)\n\t\t{\n\t\t\tyield return p;\n\t\t\tyield return fieldOnThis;\n\t\t}\n\n\t\tpublic IEnumerator<int> YieldReturnParametersEnumerator(int p)\n\t\t{\n\t\t\tyield return p;\n\t\t\tyield return fieldOnThis;\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldReturnInLoop()\n\t\t{\n\t\t\tfor (int i = 0; i < 100; i++)\n\t\t\t{\n\t\t\t\tyield return i;\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldReturnWithTryFinally()\n\t\t{\n\t\t\tyield return 0;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 1;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally!\");\n\t\t\t}\n\t\t\tyield return 2;\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldReturnInLock1(object o)\n\t\t{\n\t\t\tlock (o)\n\t\t\t{\n\t\t\t\tyield return 1;\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldReturnInLock2(object o)\n\t\t{\n\t\t\tlock (o)\n\t\t\t{\n\t\t\t\tyield return 1;\n\t\t\t\to = null;\n\t\t\t\tyield return 2;\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<string> YieldReturnWithNestedTryFinally(bool breakInMiddle)\n\t\t{\n\t\t\tConsole.WriteLine(\"Start of method - 1\");\n\t\t\tyield return \"Start of method\";\n\t\t\tConsole.WriteLine(\"Start of method - 2\");\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Within outer try - 1\");\n\t\t\t\tyield return \"Within outer try\";\n\t\t\t\tConsole.WriteLine(\"Within outer try - 2\");\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Within inner try - 1\");\n\t\t\t\t\tyield return \"Within inner try\";\n\t\t\t\t\tConsole.WriteLine(\"Within inner try - 2\");\n\t\t\t\t\tif (breakInMiddle)\n\t\t\t\t\t{\n\t\t\t\t\t\tConsole.WriteLine(\"Breaking...\");\n\t\t\t\t\t\tyield break;\n\t\t\t\t\t}\n\t\t\t\t\tConsole.WriteLine(\"End of inner try - 1\");\n\t\t\t\t\tyield return \"End of inner try\";\n\t\t\t\t\tConsole.WriteLine(\"End of inner try - 2\");\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Inner Finally\");\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(\"End of outer try - 1\");\n\t\t\t\tyield return \"End of outer try\";\n\t\t\t\tConsole.WriteLine(\"End of outer try - 2\");\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Outer Finally\");\n\t\t\t}\n\t\t\tConsole.WriteLine(\"End of method - 1\");\n\t\t\tyield return \"End of method\";\n\t\t\tConsole.WriteLine(\"End of method - 2\");\n\t\t}\n\n\t\tpublic static IEnumerable<string> YieldReturnWithTwoNonNestedFinallyBlocks(IEnumerable<string> input)\n\t\t{\n\t\t\t// outer try-finally block\n\t\t\tforeach (string line in input)\n\t\t\t{\n\t\t\t\t// nested try-finally block\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tyield return line;\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Processed \" + line);\n\t\t\t\t}\n\t\t\t}\n\t\t\tyield return \"A\";\n\t\t\tyield return \"B\";\n\t\t\tyield return \"C\";\n\t\t\tyield return \"D\";\n\t\t\tyield return \"E\";\n\t\t\tyield return \"F\";\n\t\t\t// outer try-finally block\n\t\t\tforeach (string line in input)\n\t\t\t{\n\t\t\t\tyield return line.ToUpper();\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<Func<string>> YieldReturnWithAnonymousMethods1(IEnumerable<string> input)\n\t\t{\n\t\t\tforeach (string line in input)\n\t\t\t{\n\t\t\t\tyield return () => line;\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<Func<string>> YieldReturnWithAnonymousMethods2(IEnumerable<string> input)\n\t\t{\n\t\t\tforeach (string line in input)\n\t\t\t{\n\t\t\t\tstring copy = line;\n\t\t\t\tyield return () => copy;\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> GetEvenNumbers(int n)\n\t\t{\n\t\t\tfor (int i = 0; i < n; i++)\n\t\t\t{\n\t\t\t\tif (i % 2 == 0)\n\t\t\t\t{\n\t\t\t\t\tyield return i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<char> ExceptionHandling()\n\t\t{\n\t\t\tyield return 'a';\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"1 - try\");\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"1 - catch\");\n\t\t\t}\n\t\t\tyield return 'b';\n\t\t\ttry\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"2 - try\");\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"2 - finally\");\n\t\t\t\t}\n\t\t\t\tyield return 'c';\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"outer finally\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldBreakInCatch()\n\t\t{\n\t\t\tyield return 0;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"In Try\");\n\t\t\t}\n\t\t\tcatch\n\t\t\t{\n\t\t\t\t// yield return is not allowed in catch, but yield break is\n\t\t\t\tyield break;\n\t\t\t}\n\t\t\tyield return 1;\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldBreakInCatchInTryFinally()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 0;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"In Try\");\n\t\t\t\t}\n\t\t\t\tcatch\n\t\t\t\t{\n\t\t\t\t\t// yield return is not allowed in catch, but yield break is\n\t\t\t\t\t// Note that pre-roslyn, this code triggers a compiler bug:\n\t\t\t\t\t// If the finally block throws an exception, it ends up getting\n\t\t\t\t\t// called a second time.\n\t\t\t\t\tyield break;\n\t\t\t\t}\n\t\t\t\tyield return 1;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldBreakInTryCatchInTryFinally()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 0;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"In Try\");\n\t\t\t\t\t// same compiler bug as in YieldBreakInCatchInTryFinally\n\t\t\t\t\tyield break;\n\t\t\t\t}\n\t\t\t\tcatch\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Catch\");\n\t\t\t\t}\n\t\t\t\tyield return 1;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldBreakInTryFinallyInTryFinally(bool b)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 0;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"In Try\");\n\t\t\t\t\tif (b)\n\t\t\t\t\t{\n\t\t\t\t\t\t// same compiler bug as in YieldBreakInCatchInTryFinally\n\t\t\t\t\t\tyield break;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Inner Finally\");\n\t\t\t\t}\n\t\t\t\tyield return 1;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldBreakOnly()\n\t\t{\n\t\t\tyield break;\n\t\t}\n\n\t\tpublic static IEnumerable<int> UnconditionalThrowInTryFinally()\n\t\t{\n\t\t\t// Here, MoveNext() doesn't call the finally methods at all\n\t\t\t// (only indirectly via Dispose())\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 0;\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> NestedTryFinallyStartingOnSamePosition()\n\t\t{\n\t\t\t// The first user IL instruction is already in 2 nested try blocks.\n\t\t\ttry\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tyield return 0;\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Inner Finally\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Outer Finally\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> TryFinallyWithTwoExitPoints(bool b)\n\t\t{\n\t\t\t// Uses goto for multiple non-exceptional exits out of try-finally.\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (b)\n\t\t\t\t{\n\t\t\t\t\tyield return 1;\n\t\t\t\t\tgoto exit1;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tyield return 2;\n\t\t\t\t\tgoto exit2;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally\");\n\t\t\t}\n\t\t\texit1:\n\t\t\tConsole.WriteLine(\"Exit1\");\n\t\t\tyield break;\n\t\t\texit2:\n\t\t\tConsole.WriteLine(\"Exit2\");\n\t\t}\n\n#if !LEGACY_CSC\n\t\tpublic static IEnumerable<int> YieldBreakInNestedTryFinally()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 1;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\t// Compiler bug: pre-Roslyn, the finally blocks will execute in the wrong order\n\t\t\t\t\tyield break;\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Inner Finally\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Outer Finally\");\n\t\t\t}\n\t\t}\n\n\t\t// Legacy csc has a compiler bug with this type of code:\n\t\t// If the goto statements triggers a finally block, and the finally block throws an exception,\n\t\t// that exception gets caught by the catch block.\n\t\tpublic static IEnumerable<int> TryFinallyWithTwoExitPointsInNestedTry(bool b)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 1;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tif (b)\n\t\t\t\t\t\tgoto exit1;\n\t\t\t\t\telse\n\t\t\t\t\t\tgoto exit2;\n\t\t\t\t}\n\t\t\t\tcatch\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Catch\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally\");\n\t\t\t}\n\t\t\texit1:\n\t\t\tConsole.WriteLine(\"Exit1\");\n\t\t\tyield break;\n\t\t\texit2:\n\t\t\tConsole.WriteLine(\"Exit2\");\n\t\t}\n\n\t\tpublic static IEnumerable<int> TryFinallyWithTwoExitPointsInNestedCatch(bool b)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 1;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Nested Try\");\n\t\t\t\t}\n\t\t\t\tcatch\n\t\t\t\t{\n\t\t\t\t\tif (b)\n\t\t\t\t\t\tgoto exit1;\n\t\t\t\t\telse\n\t\t\t\t\t\tgoto exit2;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally\");\n\t\t\t}\n\t\t\texit1:\n\t\t\tConsole.WriteLine(\"Exit1\");\n\t\t\tyield break;\n\t\t\texit2:\n\t\t\tConsole.WriteLine(\"Exit2\");\n\t\t}\n#endif\n\n\t\tpublic static IEnumerable<int> LocalInFinally<T>(T a) where T : IDisposable\n\t\t{\n\t\t\tyield return 1;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 2;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tT val = a;\n\t\t\t\tval.Dispose();\n\t\t\t\tval.Dispose();\n\t\t\t}\n\t\t\tyield return 3;\n\t\t}\n\n\t\tpublic static IEnumerable<T> GenericYield<T>() where T : new()\n\t\t{\n\t\t\tT val = new T();\n\t\t\tfor (int i = 0; i < 3; i++)\n\t\t\t{\n\t\t\t\tyield return val;\n\t\t\t}\n\t\t}\n\t}\n\n\tstruct StructWithYieldReturn\n\t{\n\t\tpublic static void Run()\n\t\t{\n\t\t\tvar s = new StructWithYieldReturn { val = 2 };\n\t\t\tvar count = s.Count();\n\t\t\tYieldReturnTest.Print(\"StructWithYieldReturn\", count.GetEnumerator());\n\t\t\tYieldReturnTest.Print(\"StructWithYieldReturn (again)\", count.GetEnumerator());\n\t\t}\n\n\t\tint val;\n\n\t\tpublic IEnumerable<int> Count()\n\t\t{\n\t\t\tyield return val++;\n\t\t\tyield return val++;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Disassembler/Pretty/.gitignore",
    "content": "*.result.il\n*.dll\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Disassembler/Pretty/GenericConstraints.il",
    "content": ".assembly extern mscorlib\n{\n\t.publickeytoken = (\n\t\tb7 7a 5c 56 19 34 e0 89\n\t)\n\t.ver 4:0:0:0\n}\n.assembly GenericConstraints\n{\n\t.custom instance void [mscorlib]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = (\n\t\t01 00 07 31 2e 30 2e 30 2e 30 00 00\n\t)\n\t.hash algorithm 0x00008004 // SHA1\n\t.ver 1:0:0:0\n}\n\n.module GenericConstraints.dll\n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003 // WindowsCui\n.corflags 0x00000001 // ILOnly\n\n.class private auto ansi '<Module>'\n{\n} // end of class <Module>\n\n.class public auto ansi beforefieldinit TestType`1<byreflike T>\n\textends [mscorlib]System.Object\n{\n\t// Methods\n\t.method public hidebysig specialname rtspecialname\n\t\tinstance void .ctor () cil managed\n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Header size: 1\n\t\t// Code size: 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: ret\n\t} // end of method TestType::.ctor\n\n} // end of class TestType\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Disassembler/Pretty/InterfaceImplAttributes.il",
    "content": ".assembly extern mscorlib\n{\n\t.publickeytoken = (\n\t\tb7 7a 5c 56 19 34 e0 89\n\t)\n\t.ver 4:0:0:0\n}\n.assembly InterfaceImplAttributes\n{\n\t.custom instance void [mscorlib]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = (\n\t\t01 00 07 31 2e 30 2e 30 2e 30 00 00\n\t)\n\t.hash algorithm 0x00008004 // SHA1\n\t.ver 1:0:0:0\n}\n\n.module InterfaceImplAttributes.dll\n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003 // WindowsCui\n.corflags 0x00000001 // ILOnly\n\n.class private auto ansi '<Module>'\n{\n} // end of class <Module>\n\n.class public auto ansi beforefieldinit TestType\n\textends [mscorlib]System.Object\n\timplements ITestInterfaceA\n{\n\t.interfaceimpl type ITestInterfaceA\n\t.custom instance void TestAttributeA::.ctor() = (\n\t\t01 00 00 00\n\t)\n\n\t// Methods\n\t.method public hidebysig specialname rtspecialname\n\t\tinstance void .ctor () cil managed\n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Header size: 1\n\t\t// Code size: 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: ret\n\t} // end of method TestType::.ctor\n\n} // end of class TestType\n\n.class interface public auto ansi abstract ITestInterfaceA\n{\n} // end of class ITestInterfaceA\n\n.class public auto ansi beforefieldinit TestAttributeA\n\textends [mscorlib]System.Attribute\n{\n\t// Methods\n\t.method public hidebysig specialname rtspecialname\n\t\tinstance void .ctor () cil managed\n\t{\n\t\t// Method begins at RVA 0x2058\n\t\t// Header size: 1\n\t\t// Code size: 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Attribute::.ctor()\n\t\tIL_0006: ret\n\t} // end of method TestAttributeA::.ctor\n\n} // end of class TestAttributeA\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Disassembler/Pretty/SecurityDeclarations.il",
    "content": ".assembly extern mscorlib\n{\n\t.publickeytoken = (\n\t\tb7 7a 5c 56 19 34 e0 89\n\t)\n\t.ver 4:0:0:0\n}\n.assembly SecurityDeclarations\n{\n\t.custom instance void [mscorlib]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = (\n\t\t01 00 07 31 2e 30 2e 30 2e 30 00 00\n\t)\n\t.hash algorithm 0x00008004 // SHA1\n\t.ver 1:0:0:0\n}\n\n.module SecurityDeclarations.dll\n// MVID: {761F919A-2373-48EB-9282-9DAB26913D43}\n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003 // WindowsCui\n.corflags 0x00000001 // ILOnly\n\n\n.class private auto ansi '<Module>'\n{\n} // end of class <Module>\n\n.class private sequential ansi sealed beforefieldinit SecurityDeclarations.TestStruct\n\textends [mscorlib]System.ValueType\n{\n\t.pack 0\n\t.size 1\n\n} // end of class SecurityDeclarations.TestStruct\n\n.class private auto ansi beforefieldinit SecurityDeclarations.SimpleType\n\textends [mscorlib]System.Object\n{\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method SimpleType::.ctor\n\n} // end of class SecurityDeclarations.SimpleType\n\n.class private auto ansi sealed SecurityDeclarations.TestEnum\n\textends [mscorlib]System.Enum\n{\n\t// Fields\n\t.field public specialname rtspecialname int32 value__\n\t.field public static literal valuetype SecurityDeclarations.TestEnum A = int32(0)\n\t.field public static literal valuetype SecurityDeclarations.TestEnum B = int32(1)\n\t.field public static literal valuetype SecurityDeclarations.TestEnum C = int32(2)\n\n} // end of class SecurityDeclarations.TestEnum\n\n.class private auto ansi beforefieldinit SecurityDeclarations.SecurityAttrTest\n\textends [mscorlib]System.Security.Permissions.SecurityAttribute\n{\n\t// Fields\n\t.field private string[] _testStringArray\n\t.field private int32[] _testInt32Array\n\t.field private valuetype SecurityDeclarations.TestEnum[] _testEnumArray\n\t.field private class [mscorlib]System.Type[] _testTypeArray\n\t.field public int32 TestInt32\n\t.field public class [mscorlib]System.Type TestType\n\t.field public valuetype SecurityDeclarations.TestEnum TestEnumType\n\t.field public object TestBoxed\n\t.field public object TestBoxed2\n\t.field public string TestString\n\t.field public object TestBoxedString\n\t.field public object TestBoxedArray\n\t.field public object TestBoxedType\n\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor (\n\t\t\tvaluetype [mscorlib]System.Security.Permissions.SecurityAction action\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x2059\n\t\t// Code size 10 (0xa)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldarg.1\n\t\tIL_0002: call instance void [mscorlib]System.Security.Permissions.SecurityAttribute::.ctor(valuetype [mscorlib]System.Security.Permissions.SecurityAction)\n\t\tIL_0007: nop\n\t\tIL_0008: nop\n\t\tIL_0009: ret\n\t} // end of method SecurityAttrTest::.ctor\n\n\t.method public hidebysig virtual \n\t\tinstance class [mscorlib]System.Security.IPermission CreatePermission () cil managed \n\t{\n\t\t// Method begins at RVA 0x2064\n\t\t// Code size 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: nop\n\t\tIL_0001: newobj instance void [mscorlib]System.NotImplementedException::.ctor()\n\t\tIL_0006: throw\n\t} // end of method SecurityAttrTest::CreatePermission\n\n\t.method public hidebysig specialname \n\t\tinstance string[] get_TestStringArray () cil managed \n\t{\n\t\t// Method begins at RVA 0x206c\n\t\t// Code size 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldfld string[] SecurityDeclarations.SecurityAttrTest::_testStringArray\n\t\tIL_0006: ret\n\t} // end of method SecurityAttrTest::get_TestStringArray\n\n\t.method public hidebysig specialname \n\t\tinstance void set_TestStringArray (\n\t\t\tstring[] 'value'\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x2074\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldarg.1\n\t\tIL_0002: stfld string[] SecurityDeclarations.SecurityAttrTest::_testStringArray\n\t\tIL_0007: ret\n\t} // end of method SecurityAttrTest::set_TestStringArray\n\n\t.method public hidebysig specialname \n\t\tinstance int32[] get_TestInt32Array () cil managed \n\t{\n\t\t// Method begins at RVA 0x207d\n\t\t// Code size 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldfld int32[] SecurityDeclarations.SecurityAttrTest::_testInt32Array\n\t\tIL_0006: ret\n\t} // end of method SecurityAttrTest::get_TestInt32Array\n\n\t.method public hidebysig specialname \n\t\tinstance void set_TestInt32Array (\n\t\t\tint32[] 'value'\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x2085\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldarg.1\n\t\tIL_0002: stfld int32[] SecurityDeclarations.SecurityAttrTest::_testInt32Array\n\t\tIL_0007: ret\n\t} // end of method SecurityAttrTest::set_TestInt32Array\n\n\t.method public hidebysig specialname \n\t\tinstance valuetype SecurityDeclarations.TestEnum[] get_TestEnumArray () cil managed \n\t{\n\t\t// Method begins at RVA 0x208e\n\t\t// Code size 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldfld valuetype SecurityDeclarations.TestEnum[] SecurityDeclarations.SecurityAttrTest::_testEnumArray\n\t\tIL_0006: ret\n\t} // end of method SecurityAttrTest::get_TestEnumArray\n\n\t.method public hidebysig specialname \n\t\tinstance void set_TestEnumArray (\n\t\t\tvaluetype SecurityDeclarations.TestEnum[] 'value'\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x2096\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldarg.1\n\t\tIL_0002: stfld valuetype SecurityDeclarations.TestEnum[] SecurityDeclarations.SecurityAttrTest::_testEnumArray\n\t\tIL_0007: ret\n\t} // end of method SecurityAttrTest::set_TestEnumArray\n\n\t.method public hidebysig specialname \n\t\tinstance class [mscorlib]System.Type[] get_TestTypeArray () cil managed \n\t{\n\t\t// Method begins at RVA 0x209f\n\t\t// Code size 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldfld class [mscorlib]System.Type[] SecurityDeclarations.SecurityAttrTest::_testTypeArray\n\t\tIL_0006: ret\n\t} // end of method SecurityAttrTest::get_TestTypeArray\n\n\t.method public hidebysig specialname \n\t\tinstance void set_TestTypeArray (\n\t\t\tclass [mscorlib]System.Type[] 'value'\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x20a7\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldarg.1\n\t\tIL_0002: stfld class [mscorlib]System.Type[] SecurityDeclarations.SecurityAttrTest::_testTypeArray\n\t\tIL_0007: ret\n\t} // end of method SecurityAttrTest::set_TestTypeArray\n\n\t// Properties\n\t.property instance string[] TestStringArray()\n\t{\n\t\t.get instance string[] SecurityDeclarations.SecurityAttrTest::get_TestStringArray()\n\t\t.set instance void SecurityDeclarations.SecurityAttrTest::set_TestStringArray(string[])\n\t}\n\t.property instance int32[] TestInt32Array()\n\t{\n\t\t.get instance int32[] SecurityDeclarations.SecurityAttrTest::get_TestInt32Array()\n\t\t.set instance void SecurityDeclarations.SecurityAttrTest::set_TestInt32Array(int32[])\n\t}\n\t.property instance valuetype SecurityDeclarations.TestEnum[] TestEnumArray()\n\t{\n\t\t.get instance valuetype SecurityDeclarations.TestEnum[] SecurityDeclarations.SecurityAttrTest::get_TestEnumArray()\n\t\t.set instance void SecurityDeclarations.SecurityAttrTest::set_TestEnumArray(valuetype SecurityDeclarations.TestEnum[])\n\t}\n\t.property instance class [mscorlib]System.Type[] TestTypeArray()\n\t{\n\t\t.get instance class [mscorlib]System.Type[] SecurityDeclarations.SecurityAttrTest::get_TestTypeArray()\n\t\t.set instance void SecurityDeclarations.SecurityAttrTest::set_TestTypeArray(class [mscorlib]System.Type[])\n\t}\n\n} // end of class SecurityDeclarations.SecurityAttrTest\n\n.class private auto ansi beforefieldinit SecurityDeclarations.TestStringTypes\n\textends [mscorlib]System.Object\n{\n\t.permissionset assert = {\n\t\tclass 'SecurityDeclarations.SecurityAttrTest, SecurityDeclarations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' = {\n\t\t\tfield string TestString = string('Hello World!')\n\t\t\tfield object TestBoxedString = object(string('Boxed String'))\n\t\t\tproperty string[] TestStringArray = string[2]('a' 'b')\n\t\t\tfield object TestBoxedArray = object(string[2]('c' 'd'))\n\t\t}\n\t}\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method TestStringTypes::.ctor\n\n} // end of class SecurityDeclarations.TestStringTypes\n\n.class private auto ansi beforefieldinit SecurityDeclarations.TestTypeTypes\n\textends [mscorlib]System.Object\n{\n\t.permissionset demand = {\n\t\tclass 'SecurityDeclarations.SecurityAttrTest, SecurityDeclarations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' = {\n\t\t\tfield type TestType = type(SecurityDeclarations.SimpleType)\n\t\t\tfield object TestBoxed = object(type(SecurityDeclarations.TestEnum))\n\t\t\tproperty type[] TestTypeArray = type[2](SecurityDeclarations.TestStruct SecurityDeclarations.SimpleType)\n\t\t\tfield object TestBoxedArray = object(type[2](SecurityDeclarations.TestStringTypes SecurityDeclarations.TestTypeTypes))\n\t\t}\n\t}\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method TestTypeTypes::.ctor\n\n} // end of class SecurityDeclarations.TestTypeTypes\n\n.class private auto ansi beforefieldinit SecurityDeclarations.TestEnumTypes\n\textends [mscorlib]System.Object\n{\n\t.permissionset inheritcheck = {\n\t\tclass 'SecurityDeclarations.SecurityAttrTest, SecurityDeclarations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' = {\n\t\t\tfield enum SecurityDeclarations.TestEnum TestEnumType = int32(0)\n\t\t\tfield object TestBoxed = object(int32(1))\n\t\t\tproperty enum SecurityDeclarations.TestEnum[] TestEnumArray = int32[3](0 1 2)\n\t\t\tfield object TestBoxed2 = object(object[4](int32(0) int32(1) int32(2) object[1](int32(3))))\n\t\t\tfield object TestBoxedArray = object(int32[3](0 1 2))\n\t\t}\n\t}\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method TestEnumTypes::.ctor\n\n} // end of class SecurityDeclarations.TestEnumTypes\n\n.class private auto ansi beforefieldinit SecurityDeclarations.TestInt32Types\n\textends [mscorlib]System.Object\n{\n\t.permissionset permitonly = {\n\t\tclass 'SecurityDeclarations.SecurityAttrTest, SecurityDeclarations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' = {\n\t\t\tfield int32 TestInt32 = int32(5)\n\t\t\tfield object TestBoxed = object(int32(10))\n\t\t\tproperty int32[] TestInt32Array = int32[3](1 2 3)\n\t\t\tfield object TestBoxedArray = object(int32[3](4 5 6))\n\t\t\tfield object TestBoxed2 = object(object[3](int32(7) int32(8) int32(9)))\n\t\t}\n\t}\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method TestInt32Types::.ctor\n\n} // end of class SecurityDeclarations.TestInt32Types\n\n.class private auto ansi beforefieldinit SecurityDeclarations.NestedArrays\n\textends [mscorlib]System.Object\n{\n\t.permissionset assert = {\n\t\tclass 'SecurityDeclarations.SecurityAttrTest, SecurityDeclarations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' = {\n\t\t\tfield object TestBoxed2 = object(object[4](int32(1) int32(2) int32(3) object[3](int32(4) int32(5) int32(6))))\n\t\t}\n\t}\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method NestedArrays::.ctor\n\n} // end of class SecurityDeclarations.NestedArrays\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Disassembler/Pretty/SortMembers.expected.il",
    "content": ".assembly extern mscorlib\n{\n\t.publickeytoken = (\n\t\tb7 7a 5c 56 19 34 e0 89\n\t)\n\t.ver 4:0:0:0\n}\n.assembly SecurityDeclarations\n{\n\t.custom instance void [mscorlib]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = (\n\t\t01 00 07 31 2e 30 2e 30 2e 30 00 00\n\t)\n\t.hash algorithm 0x00008004 // SHA1\n\t.ver 1:0:0:0\n}\n\n.module SecurityDeclarations.dll\n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003 // WindowsCui\n.corflags 0x00000001 // ILOnly\n\n.class private auto ansi '<Module>'\n{\n} // end of class <Module>\n\n.class private auto ansi beforefieldinit SecurityDeclarations.NestedArrays\n\textends [mscorlib]System.Object\n{\n\t.permissionset assert = {\n\t\tclass 'SecurityDeclarations.SecurityAttrTest, SecurityDeclarations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' = {\n\t\t\tfield object TestBoxed2 = object(object[4](int32(1) int32(2) int32(3) object[3](int32(4) int32(5) int32(6))))\n\t\t}\n\t}\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x20d4\n\t\t// Header size: 1\n\t\t// Code size: 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method NestedArrays::.ctor\n\n} // end of class SecurityDeclarations.NestedArrays\n\n.class private auto ansi beforefieldinit SecurityDeclarations.SecurityAttrTest\n\textends [mscorlib]System.Security.Permissions.SecurityAttribute\n{\n\t// Fields\n\t.field private valuetype SecurityDeclarations.TestEnum[] _testEnumArray\n\t.field private int32[] _testInt32Array\n\t.field private string[] _testStringArray\n\t.field private class [mscorlib]System.Type[] _testTypeArray\n\t.field public object TestBoxed\n\t.field public object TestBoxed2\n\t.field public object TestBoxedArray\n\t.field public object TestBoxedString\n\t.field public object TestBoxedType\n\t.field public valuetype SecurityDeclarations.TestEnum TestEnumType\n\t.field public int32 TestInt32\n\t.field public string TestString\n\t.field public class [mscorlib]System.Type TestType\n\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor (\n\t\t\tvaluetype [mscorlib]System.Security.Permissions.SecurityAction action\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x2059\n\t\t// Header size: 1\n\t\t// Code size: 10 (0xa)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldarg.1\n\t\tIL_0002: call instance void [mscorlib]System.Security.Permissions.SecurityAttribute::.ctor(valuetype [mscorlib]System.Security.Permissions.SecurityAction)\n\t\tIL_0007: nop\n\t\tIL_0008: nop\n\t\tIL_0009: ret\n\t} // end of method SecurityAttrTest::.ctor\n\n\t.method public hidebysig virtual \n\t\tinstance class [mscorlib]System.Security.IPermission CreatePermission () cil managed \n\t{\n\t\t// Method begins at RVA 0x2064\n\t\t// Header size: 1\n\t\t// Code size: 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: nop\n\t\tIL_0001: newobj instance void [mscorlib]System.NotImplementedException::.ctor()\n\t\tIL_0006: throw\n\t} // end of method SecurityAttrTest::CreatePermission\n\n\t.method public hidebysig specialname \n\t\tinstance valuetype SecurityDeclarations.TestEnum[] get_TestEnumArray () cil managed \n\t{\n\t\t// Method begins at RVA 0x208e\n\t\t// Header size: 1\n\t\t// Code size: 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldfld valuetype SecurityDeclarations.TestEnum[] SecurityDeclarations.SecurityAttrTest::_testEnumArray\n\t\tIL_0006: ret\n\t} // end of method SecurityAttrTest::get_TestEnumArray\n\n\t.method public hidebysig specialname \n\t\tinstance int32[] get_TestInt32Array () cil managed \n\t{\n\t\t// Method begins at RVA 0x207d\n\t\t// Header size: 1\n\t\t// Code size: 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldfld int32[] SecurityDeclarations.SecurityAttrTest::_testInt32Array\n\t\tIL_0006: ret\n\t} // end of method SecurityAttrTest::get_TestInt32Array\n\n\t.method public hidebysig specialname \n\t\tinstance string[] get_TestStringArray () cil managed \n\t{\n\t\t// Method begins at RVA 0x206c\n\t\t// Header size: 1\n\t\t// Code size: 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldfld string[] SecurityDeclarations.SecurityAttrTest::_testStringArray\n\t\tIL_0006: ret\n\t} // end of method SecurityAttrTest::get_TestStringArray\n\n\t.method public hidebysig specialname \n\t\tinstance class [mscorlib]System.Type[] get_TestTypeArray () cil managed \n\t{\n\t\t// Method begins at RVA 0x209f\n\t\t// Header size: 1\n\t\t// Code size: 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldfld class [mscorlib]System.Type[] SecurityDeclarations.SecurityAttrTest::_testTypeArray\n\t\tIL_0006: ret\n\t} // end of method SecurityAttrTest::get_TestTypeArray\n\n\t.method public hidebysig specialname \n\t\tinstance void set_TestEnumArray (\n\t\t\tvaluetype SecurityDeclarations.TestEnum[] 'value'\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x2096\n\t\t// Header size: 1\n\t\t// Code size: 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldarg.1\n\t\tIL_0002: stfld valuetype SecurityDeclarations.TestEnum[] SecurityDeclarations.SecurityAttrTest::_testEnumArray\n\t\tIL_0007: ret\n\t} // end of method SecurityAttrTest::set_TestEnumArray\n\n\t.method public hidebysig specialname \n\t\tinstance void set_TestInt32Array (\n\t\t\tint32[] 'value'\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x2085\n\t\t// Header size: 1\n\t\t// Code size: 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldarg.1\n\t\tIL_0002: stfld int32[] SecurityDeclarations.SecurityAttrTest::_testInt32Array\n\t\tIL_0007: ret\n\t} // end of method SecurityAttrTest::set_TestInt32Array\n\n\t.method public hidebysig specialname \n\t\tinstance void set_TestStringArray (\n\t\t\tstring[] 'value'\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x2074\n\t\t// Header size: 1\n\t\t// Code size: 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldarg.1\n\t\tIL_0002: stfld string[] SecurityDeclarations.SecurityAttrTest::_testStringArray\n\t\tIL_0007: ret\n\t} // end of method SecurityAttrTest::set_TestStringArray\n\n\t.method public hidebysig specialname \n\t\tinstance void set_TestTypeArray (\n\t\t\tclass [mscorlib]System.Type[] 'value'\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x20a7\n\t\t// Header size: 1\n\t\t// Code size: 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldarg.1\n\t\tIL_0002: stfld class [mscorlib]System.Type[] SecurityDeclarations.SecurityAttrTest::_testTypeArray\n\t\tIL_0007: ret\n\t} // end of method SecurityAttrTest::set_TestTypeArray\n\n\t// Properties\n\t.property instance valuetype SecurityDeclarations.TestEnum[] TestEnumArray()\n\t{\n\t\t.get instance valuetype SecurityDeclarations.TestEnum[] SecurityDeclarations.SecurityAttrTest::get_TestEnumArray()\n\t\t.set instance void SecurityDeclarations.SecurityAttrTest::set_TestEnumArray(valuetype SecurityDeclarations.TestEnum[])\n\t}\n\t.property instance int32[] TestInt32Array()\n\t{\n\t\t.get instance int32[] SecurityDeclarations.SecurityAttrTest::get_TestInt32Array()\n\t\t.set instance void SecurityDeclarations.SecurityAttrTest::set_TestInt32Array(int32[])\n\t}\n\t.property instance string[] TestStringArray()\n\t{\n\t\t.get instance string[] SecurityDeclarations.SecurityAttrTest::get_TestStringArray()\n\t\t.set instance void SecurityDeclarations.SecurityAttrTest::set_TestStringArray(string[])\n\t}\n\t.property instance class [mscorlib]System.Type[] TestTypeArray()\n\t{\n\t\t.get instance class [mscorlib]System.Type[] SecurityDeclarations.SecurityAttrTest::get_TestTypeArray()\n\t\t.set instance void SecurityDeclarations.SecurityAttrTest::set_TestTypeArray(class [mscorlib]System.Type[])\n\t}\n\n} // end of class SecurityDeclarations.SecurityAttrTest\n\n.class private auto ansi beforefieldinit SecurityDeclarations.SimpleType\n\textends [mscorlib]System.Object\n{\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Header size: 1\n\t\t// Code size: 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method SimpleType::.ctor\n\n} // end of class SecurityDeclarations.SimpleType\n\n.class private auto ansi sealed SecurityDeclarations.TestEnum\n\textends [mscorlib]System.Enum\n{\n\t// Fields\n\t.field public static literal valuetype SecurityDeclarations.TestEnum A = int32(0)\n\t.field public static literal valuetype SecurityDeclarations.TestEnum B = int32(1)\n\t.field public static literal valuetype SecurityDeclarations.TestEnum C = int32(2)\n\t.field public specialname rtspecialname int32 value__\n\n} // end of class SecurityDeclarations.TestEnum\n\n.class private auto ansi beforefieldinit SecurityDeclarations.TestEnumTypes\n\textends [mscorlib]System.Object\n{\n\t.permissionset inheritcheck = {\n\t\tclass 'SecurityDeclarations.SecurityAttrTest, SecurityDeclarations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' = {\n\t\t\tfield enum SecurityDeclarations.TestEnum TestEnumType = int32(0)\n\t\t\tfield object TestBoxed = object(int32(1))\n\t\t\tproperty enum SecurityDeclarations.TestEnum[] TestEnumArray = int32[3](0 1 2)\n\t\t\tfield object TestBoxed2 = object(object[4](int32(0) int32(1) int32(2) object[1](int32(3))))\n\t\t\tfield object TestBoxedArray = object(int32[3](0 1 2))\n\t\t}\n\t}\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x20c2\n\t\t// Header size: 1\n\t\t// Code size: 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method TestEnumTypes::.ctor\n\n} // end of class SecurityDeclarations.TestEnumTypes\n\n.class private auto ansi beforefieldinit SecurityDeclarations.TestInt32Types\n\textends [mscorlib]System.Object\n{\n\t.permissionset permitonly = {\n\t\tclass 'SecurityDeclarations.SecurityAttrTest, SecurityDeclarations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' = {\n\t\t\tfield int32 TestInt32 = int32(5)\n\t\t\tfield object TestBoxed = object(int32(10))\n\t\t\tproperty int32[] TestInt32Array = int32[3](1 2 3)\n\t\t\tfield object TestBoxedArray = object(int32[3](4 5 6))\n\t\t\tfield object TestBoxed2 = object(object[3](int32(7) int32(8) int32(9)))\n\t\t}\n\t}\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x20cb\n\t\t// Header size: 1\n\t\t// Code size: 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method TestInt32Types::.ctor\n\n} // end of class SecurityDeclarations.TestInt32Types\n\n.class private auto ansi beforefieldinit SecurityDeclarations.TestStringTypes\n\textends [mscorlib]System.Object\n{\n\t.permissionset assert = {\n\t\tclass 'SecurityDeclarations.SecurityAttrTest, SecurityDeclarations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' = {\n\t\t\tfield string TestString = string('Hello World!')\n\t\t\tfield object TestBoxedString = object(string('Boxed String'))\n\t\t\tproperty string[] TestStringArray = string[2]('a' 'b')\n\t\t\tfield object TestBoxedArray = object(string[2]('c' 'd'))\n\t\t}\n\t}\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x20b0\n\t\t// Header size: 1\n\t\t// Code size: 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method TestStringTypes::.ctor\n\n} // end of class SecurityDeclarations.TestStringTypes\n\n.class private sequential ansi sealed beforefieldinit SecurityDeclarations.TestStruct\n\textends [mscorlib]System.ValueType\n{\n\t.pack 0\n\t.size 1\n\n} // end of class SecurityDeclarations.TestStruct\n\n.class private auto ansi beforefieldinit SecurityDeclarations.TestTypeTypes\n\textends [mscorlib]System.Object\n{\n\t.permissionset demand = {\n\t\tclass 'SecurityDeclarations.SecurityAttrTest, SecurityDeclarations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' = {\n\t\t\tfield type TestType = type(SecurityDeclarations.SimpleType)\n\t\t\tfield object TestBoxed = object(type(SecurityDeclarations.TestEnum))\n\t\t\tproperty type[] TestTypeArray = type[2](SecurityDeclarations.TestStruct SecurityDeclarations.SimpleType)\n\t\t\tfield object TestBoxedArray = object(type[2](SecurityDeclarations.TestStringTypes SecurityDeclarations.TestTypeTypes))\n\t\t}\n\t}\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x20b9\n\t\t// Header size: 1\n\t\t// Code size: 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method TestTypeTypes::.ctor\n\n} // end of class SecurityDeclarations.TestTypeTypes\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Disassembler/Pretty/SortMembers.il",
    "content": ".assembly extern mscorlib\n{\n\t.publickeytoken = (\n\t\tb7 7a 5c 56 19 34 e0 89\n\t)\n\t.ver 4:0:0:0\n}\n.assembly SecurityDeclarations\n{\n\t.custom instance void [mscorlib]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = (\n\t\t01 00 07 31 2e 30 2e 30 2e 30 00 00\n\t)\n\t.hash algorithm 0x00008004 // SHA1\n\t.ver 1:0:0:0\n}\n\n.module SecurityDeclarations.dll\n// MVID: {761F919A-2373-48EB-9282-9DAB26913D43}\n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003 // WindowsCui\n.corflags 0x00000001 // ILOnly\n\n\n.class private auto ansi '<Module>'\n{\n} // end of class <Module>\n\n.class private sequential ansi sealed beforefieldinit SecurityDeclarations.TestStruct\n\textends [mscorlib]System.ValueType\n{\n\t.pack 0\n\t.size 1\n\n} // end of class SecurityDeclarations.TestStruct\n\n.class private auto ansi beforefieldinit SecurityDeclarations.SimpleType\n\textends [mscorlib]System.Object\n{\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method SimpleType::.ctor\n\n} // end of class SecurityDeclarations.SimpleType\n\n.class private auto ansi sealed SecurityDeclarations.TestEnum\n\textends [mscorlib]System.Enum\n{\n\t// Fields\n\t.field public specialname rtspecialname int32 value__\n\t.field public static literal valuetype SecurityDeclarations.TestEnum A = int32(0)\n\t.field public static literal valuetype SecurityDeclarations.TestEnum B = int32(1)\n\t.field public static literal valuetype SecurityDeclarations.TestEnum C = int32(2)\n\n} // end of class SecurityDeclarations.TestEnum\n\n.class private auto ansi beforefieldinit SecurityDeclarations.SecurityAttrTest\n\textends [mscorlib]System.Security.Permissions.SecurityAttribute\n{\n\t// Fields\n\t.field private string[] _testStringArray\n\t.field private int32[] _testInt32Array\n\t.field private valuetype SecurityDeclarations.TestEnum[] _testEnumArray\n\t.field private class [mscorlib]System.Type[] _testTypeArray\n\t.field public int32 TestInt32\n\t.field public class [mscorlib]System.Type TestType\n\t.field public valuetype SecurityDeclarations.TestEnum TestEnumType\n\t.field public object TestBoxed\n\t.field public object TestBoxed2\n\t.field public string TestString\n\t.field public object TestBoxedString\n\t.field public object TestBoxedArray\n\t.field public object TestBoxedType\n\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor (\n\t\t\tvaluetype [mscorlib]System.Security.Permissions.SecurityAction action\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x2059\n\t\t// Code size 10 (0xa)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldarg.1\n\t\tIL_0002: call instance void [mscorlib]System.Security.Permissions.SecurityAttribute::.ctor(valuetype [mscorlib]System.Security.Permissions.SecurityAction)\n\t\tIL_0007: nop\n\t\tIL_0008: nop\n\t\tIL_0009: ret\n\t} // end of method SecurityAttrTest::.ctor\n\n\t.method public hidebysig virtual \n\t\tinstance class [mscorlib]System.Security.IPermission CreatePermission () cil managed \n\t{\n\t\t// Method begins at RVA 0x2064\n\t\t// Code size 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: nop\n\t\tIL_0001: newobj instance void [mscorlib]System.NotImplementedException::.ctor()\n\t\tIL_0006: throw\n\t} // end of method SecurityAttrTest::CreatePermission\n\n\t.method public hidebysig specialname \n\t\tinstance string[] get_TestStringArray () cil managed \n\t{\n\t\t// Method begins at RVA 0x206c\n\t\t// Code size 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldfld string[] SecurityDeclarations.SecurityAttrTest::_testStringArray\n\t\tIL_0006: ret\n\t} // end of method SecurityAttrTest::get_TestStringArray\n\n\t.method public hidebysig specialname \n\t\tinstance void set_TestStringArray (\n\t\t\tstring[] 'value'\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x2074\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldarg.1\n\t\tIL_0002: stfld string[] SecurityDeclarations.SecurityAttrTest::_testStringArray\n\t\tIL_0007: ret\n\t} // end of method SecurityAttrTest::set_TestStringArray\n\n\t.method public hidebysig specialname \n\t\tinstance int32[] get_TestInt32Array () cil managed \n\t{\n\t\t// Method begins at RVA 0x207d\n\t\t// Code size 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldfld int32[] SecurityDeclarations.SecurityAttrTest::_testInt32Array\n\t\tIL_0006: ret\n\t} // end of method SecurityAttrTest::get_TestInt32Array\n\n\t.method public hidebysig specialname \n\t\tinstance void set_TestInt32Array (\n\t\t\tint32[] 'value'\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x2085\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldarg.1\n\t\tIL_0002: stfld int32[] SecurityDeclarations.SecurityAttrTest::_testInt32Array\n\t\tIL_0007: ret\n\t} // end of method SecurityAttrTest::set_TestInt32Array\n\n\t.method public hidebysig specialname \n\t\tinstance valuetype SecurityDeclarations.TestEnum[] get_TestEnumArray () cil managed \n\t{\n\t\t// Method begins at RVA 0x208e\n\t\t// Code size 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldfld valuetype SecurityDeclarations.TestEnum[] SecurityDeclarations.SecurityAttrTest::_testEnumArray\n\t\tIL_0006: ret\n\t} // end of method SecurityAttrTest::get_TestEnumArray\n\n\t.method public hidebysig specialname \n\t\tinstance void set_TestEnumArray (\n\t\t\tvaluetype SecurityDeclarations.TestEnum[] 'value'\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x2096\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldarg.1\n\t\tIL_0002: stfld valuetype SecurityDeclarations.TestEnum[] SecurityDeclarations.SecurityAttrTest::_testEnumArray\n\t\tIL_0007: ret\n\t} // end of method SecurityAttrTest::set_TestEnumArray\n\n\t.method public hidebysig specialname \n\t\tinstance class [mscorlib]System.Type[] get_TestTypeArray () cil managed \n\t{\n\t\t// Method begins at RVA 0x209f\n\t\t// Code size 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldfld class [mscorlib]System.Type[] SecurityDeclarations.SecurityAttrTest::_testTypeArray\n\t\tIL_0006: ret\n\t} // end of method SecurityAttrTest::get_TestTypeArray\n\n\t.method public hidebysig specialname \n\t\tinstance void set_TestTypeArray (\n\t\t\tclass [mscorlib]System.Type[] 'value'\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x20a7\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldarg.1\n\t\tIL_0002: stfld class [mscorlib]System.Type[] SecurityDeclarations.SecurityAttrTest::_testTypeArray\n\t\tIL_0007: ret\n\t} // end of method SecurityAttrTest::set_TestTypeArray\n\n\t// Properties\n\t.property instance string[] TestStringArray()\n\t{\n\t\t.get instance string[] SecurityDeclarations.SecurityAttrTest::get_TestStringArray()\n\t\t.set instance void SecurityDeclarations.SecurityAttrTest::set_TestStringArray(string[])\n\t}\n\t.property instance int32[] TestInt32Array()\n\t{\n\t\t.get instance int32[] SecurityDeclarations.SecurityAttrTest::get_TestInt32Array()\n\t\t.set instance void SecurityDeclarations.SecurityAttrTest::set_TestInt32Array(int32[])\n\t}\n\t.property instance valuetype SecurityDeclarations.TestEnum[] TestEnumArray()\n\t{\n\t\t.get instance valuetype SecurityDeclarations.TestEnum[] SecurityDeclarations.SecurityAttrTest::get_TestEnumArray()\n\t\t.set instance void SecurityDeclarations.SecurityAttrTest::set_TestEnumArray(valuetype SecurityDeclarations.TestEnum[])\n\t}\n\t.property instance class [mscorlib]System.Type[] TestTypeArray()\n\t{\n\t\t.get instance class [mscorlib]System.Type[] SecurityDeclarations.SecurityAttrTest::get_TestTypeArray()\n\t\t.set instance void SecurityDeclarations.SecurityAttrTest::set_TestTypeArray(class [mscorlib]System.Type[])\n\t}\n\n} // end of class SecurityDeclarations.SecurityAttrTest\n\n.class private auto ansi beforefieldinit SecurityDeclarations.TestStringTypes\n\textends [mscorlib]System.Object\n{\n\t.permissionset assert = {\n\t\tclass 'SecurityDeclarations.SecurityAttrTest, SecurityDeclarations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' = {\n\t\t\tfield string TestString = string('Hello World!')\n\t\t\tfield object TestBoxedString = object(string('Boxed String'))\n\t\t\tproperty string[] TestStringArray = string[2]('a' 'b')\n\t\t\tfield object TestBoxedArray = object(string[2]('c' 'd'))\n\t\t}\n\t}\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method TestStringTypes::.ctor\n\n} // end of class SecurityDeclarations.TestStringTypes\n\n.class private auto ansi beforefieldinit SecurityDeclarations.TestTypeTypes\n\textends [mscorlib]System.Object\n{\n\t.permissionset demand = {\n\t\tclass 'SecurityDeclarations.SecurityAttrTest, SecurityDeclarations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' = {\n\t\t\tfield type TestType = type(SecurityDeclarations.SimpleType)\n\t\t\tfield object TestBoxed = object(type(SecurityDeclarations.TestEnum))\n\t\t\tproperty type[] TestTypeArray = type[2](SecurityDeclarations.TestStruct SecurityDeclarations.SimpleType)\n\t\t\tfield object TestBoxedArray = object(type[2](SecurityDeclarations.TestStringTypes SecurityDeclarations.TestTypeTypes))\n\t\t}\n\t}\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method TestTypeTypes::.ctor\n\n} // end of class SecurityDeclarations.TestTypeTypes\n\n.class private auto ansi beforefieldinit SecurityDeclarations.TestEnumTypes\n\textends [mscorlib]System.Object\n{\n\t.permissionset inheritcheck = {\n\t\tclass 'SecurityDeclarations.SecurityAttrTest, SecurityDeclarations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' = {\n\t\t\tfield enum SecurityDeclarations.TestEnum TestEnumType = int32(0)\n\t\t\tfield object TestBoxed = object(int32(1))\n\t\t\tproperty enum SecurityDeclarations.TestEnum[] TestEnumArray = int32[3](0 1 2)\n\t\t\tfield object TestBoxed2 = object(object[4](int32(0) int32(1) int32(2) object[1](int32(3))))\n\t\t\tfield object TestBoxedArray = object(int32[3](0 1 2))\n\t\t}\n\t}\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method TestEnumTypes::.ctor\n\n} // end of class SecurityDeclarations.TestEnumTypes\n\n.class private auto ansi beforefieldinit SecurityDeclarations.TestInt32Types\n\textends [mscorlib]System.Object\n{\n\t.permissionset permitonly = {\n\t\tclass 'SecurityDeclarations.SecurityAttrTest, SecurityDeclarations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' = {\n\t\t\tfield int32 TestInt32 = int32(5)\n\t\t\tfield object TestBoxed = object(int32(10))\n\t\t\tproperty int32[] TestInt32Array = int32[3](1 2 3)\n\t\t\tfield object TestBoxedArray = object(int32[3](4 5 6))\n\t\t\tfield object TestBoxed2 = object(object[3](int32(7) int32(8) int32(9)))\n\t\t}\n\t}\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method TestInt32Types::.ctor\n\n} // end of class SecurityDeclarations.TestInt32Types\n\n.class private auto ansi beforefieldinit SecurityDeclarations.NestedArrays\n\textends [mscorlib]System.Object\n{\n\t.permissionset assert = {\n\t\tclass 'SecurityDeclarations.SecurityAttrTest, SecurityDeclarations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' = {\n\t\t\tfield object TestBoxed2 = object(object[4](int32(1) int32(2) int32(3) object[3](int32(4) int32(5) int32(6))))\n\t\t}\n\t}\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method NestedArrays::.ctor\n\n} // end of class SecurityDeclarations.NestedArrays\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/.gitignore",
    "content": "/*.dll\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/CS1xSwitch_Debug.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections;\nusing System.Reflection;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class Switch\n\t{\n\t\tpublic class SetProperty\n\t\t{\n\t\t\tpublic readonly PropertyInfo Property;\n\t\t\tprivate int _set;\n\n\t\t\tpublic int Set {\n\t\t\t\tget {\n\t\t\t\t\treturn _set;\n\t\t\t\t}\n\n\t\t\t\tset {\n\t\t\t\t\t_set = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic SetProperty(PropertyInfo property)\n\t\t\t{\n\t\t\t\tProperty = property;\n\t\t\t}\n\t\t}\n\n\t\tpublic enum State\n\t\t{\n\t\t\tFalse,\n\t\t\tTrue,\n\t\t\tNull\n\t\t}\n\n\t\tpublic static string SparseIntegerSwitch(int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"SparseIntegerSwitch: \" + i);\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase -10000000:\n\t\t\t\t\treturn \"-10 mln\";\n\t\t\t\tcase -100:\n\t\t\t\t\treturn \"-hundred\";\n\t\t\t\tcase -1:\n\t\t\t\t\treturn \"-1\";\n\t\t\t\tcase 0:\n\t\t\t\t\treturn \"0\";\n\t\t\t\tcase 1:\n\t\t\t\t\treturn \"1\";\n\t\t\t\tcase 2:\n\t\t\t\t\treturn \"2\";\n\t\t\t\tcase 4:\n\t\t\t\t\treturn \"4\";\n\t\t\t\tcase 100:\n\t\t\t\t\treturn \"hundred\";\n\t\t\t\tcase 10000:\n\t\t\t\t\treturn \"ten thousand\";\n\t\t\t\tcase 10001:\n\t\t\t\t\treturn \"ten thousand and one\";\n\t\t\t\tcase int.MaxValue:\n\t\t\t\t\treturn \"int.MaxValue\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"something else\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SwitchOverInt(int i)\n\t\t{\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tConsole.WriteLine(\"zero\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 5:\n\t\t\t\t\tConsole.WriteLine(\"five\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 10:\n\t\t\t\t\tConsole.WriteLine(\"ten\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 15:\n\t\t\t\t\tConsole.WriteLine(\"fifteen\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 20:\n\t\t\t\t\tConsole.WriteLine(\"twenty\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 25:\n\t\t\t\t\tConsole.WriteLine(\"twenty-five\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 30:\n\t\t\t\t\tConsole.WriteLine(\"thirty\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic static string ShortSwitchOverString(string text)\n\t\t{\n\t\t\tConsole.WriteLine(\"ShortSwitchOverString: \" + text);\n\t\t\tswitch (text)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase \"Third case\":\n\t\t\t\t\treturn \"Text3\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string ShortSwitchOverStringWithNullCase(string text)\n\t\t{\n\t\t\tConsole.WriteLine(\"ShortSwitchOverStringWithNullCase: \" + text);\n\t\t\tswitch (text)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase null:\n\t\t\t\t\treturn \"null\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverString1(string text)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchOverString1: \" + text);\n\t\t\tswitch (text)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\tcase \"2nd case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase \"Third case\":\n\t\t\t\t\treturn \"Text3\";\n\t\t\t\tcase \"Fourth case\":\n\t\t\t\t\treturn \"Text4\";\n\t\t\t\tcase \"Fifth case\":\n\t\t\t\t\treturn \"Text5\";\n\t\t\t\tcase \"Sixth case\":\n\t\t\t\t\treturn \"Text6\";\n\t\t\t\tcase null:\n\t\t\t\t\treturn null;\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverString2()\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchOverString2:\");\n\t\t\tswitch (Environment.UserName)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase \"Third case\":\n\t\t\t\t\treturn \"Text3\";\n\t\t\t\tcase \"Fourth case\":\n\t\t\t\t\treturn \"Text4\";\n\t\t\t\tcase \"Fifth case\":\n\t\t\t\t\treturn \"Text5\";\n\t\t\t\tcase \"Sixth case\":\n\t\t\t\t\treturn \"Text6\";\n\t\t\t\tcase \"Seventh case\":\n\t\t\t\t\treturn \"Text7\";\n\t\t\t\tcase \"Eighth case\":\n\t\t\t\t\treturn \"Text8\";\n\t\t\t\tcase \"Ninth case\":\n\t\t\t\t\treturn \"Text9\";\n\t\t\t\tcase \"Tenth case\":\n\t\t\t\t\treturn \"Text10\";\n\t\t\t\tcase \"Eleventh case\":\n\t\t\t\t\treturn \"Text11\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string TwoDifferentSwitchBlocksInTryFinally()\n\t\t{\n\t\t\ttry \n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"TwoDifferentSwitchBlocks:\");\n\t\t\t\tswitch (Environment.UserName)\n\t\t\t\t{\n\t\t\t\t\tcase \"First case\":\n\t\t\t\t\t\treturn \"Text1\";\n\t\t\t\t\tcase \"Second case\":\n\t\t\t\t\t\treturn \"Text2\";\n\t\t\t\t\tcase \"Third case\":\n\t\t\t\t\t\treturn \"Text3\";\n\t\t\t\t\tcase \"Fourth case\":\n\t\t\t\t\t\treturn \"Text4\";\n\t\t\t\t\tcase \"Fifth case\":\n\t\t\t\t\t\treturn \"Text5\";\n\t\t\t\t\tcase \"Sixth case\":\n\t\t\t\t\t\treturn \"Text6\";\n\t\t\t\t\tcase \"Seventh case\":\n\t\t\t\t\t\treturn \"Text7\";\n\t\t\t\t\tcase \"Eighth case\":\n\t\t\t\t\t\treturn \"Text8\";\n\t\t\t\t\tcase \"Ninth case\":\n\t\t\t\t\t\treturn \"Text9\";\n\t\t\t\t\tcase \"Tenth case\":\n\t\t\t\t\t\treturn \"Text10\";\n\t\t\t\t\tcase \"Eleventh case\":\n\t\t\t\t\t\treturn \"Text11\";\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn \"Default\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Second switch:\");\n\t\t\t\tswitch (Console.ReadLine())\n\t\t\t\t{\n\t\t\t\t\tcase \"12\":\n\t\t\t\t\t\tConsole.WriteLine(\"Te43234xt1\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"13\":\n\t\t\t\t\t\tConsole.WriteLine(\"Te223443xt2\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"14\":\n\t\t\t\t\t\tConsole.WriteLine(\"Te234xt3\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"15\":\n\t\t\t\t\t\tConsole.WriteLine(\"Tex243t4\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"16\":\n\t\t\t\t\t\tConsole.WriteLine(\"Tex243t5\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"17\":\n\t\t\t\t\t\tConsole.WriteLine(\"Text2346\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"18\":\n\t\t\t\t\t\tConsole.WriteLine(\"Text234234\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"19 case\":\n\t\t\t\t\t\tConsole.WriteLine(\"Text8234\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"20 case\":\n\t\t\t\t\t\tConsole.WriteLine(\"Text923423\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"21 case\":\n\t\t\t\t\t\tConsole.WriteLine(\"Text10\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"22 case\":\n\t\t\t\t\t\tConsole.WriteLine(\"Text1134123\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tConsole.WriteLine(\"Defa234234ult\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverBool(bool b)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchOverBool: \" + b);\n\t\t\tswitch (b)\n\t\t\t{\n\t\t\t\tcase true:\n\t\t\t\t\treturn bool.TrueString;\n\t\t\t\tcase false:\n\t\t\t\t\treturn bool.FalseString;\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SwitchInLoop(int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchInLoop: \" + i);\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tswitch (i)\n\t\t\t\t{\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tConsole.WriteLine(\"one\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tConsole.WriteLine(\"two\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t//case 3:\n\t\t\t\t\t//\t\tConsole.WriteLine(\"three\");\n\t\t\t\t\t//\t\tcontinue;\n\t\t\t\t\tcase 4:\n\t\t\t\t\t\tConsole.WriteLine(\"four\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t\t\t\tConsole.WriteLine(\"more code\");\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SwitchWithGoto(int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchWithGoto: \" + i);\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase 1:\n\t\t\t\t\tConsole.WriteLine(\"one\");\n\t\t\t\t\tgoto default;\n\t\t\t\tcase 2:\n\t\t\t\t\tConsole.WriteLine(\"two\");\n\t\t\t\t\tgoto case 3;\n\t\t\t\tcase 3:\n\t\t\t\t\tConsole.WriteLine(\"three\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 4:\n\t\t\t\t\tConsole.WriteLine(\"four\");\n\t\t\t\t\treturn;\n\t\t\t\tdefault:\n\t\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"End of method\");\n\t\t}\n\n\t\tprivate static SetProperty[] GetProperties()\n\t\t{\n\t\t\treturn new SetProperty[0];\n\t\t}\n\n\t\tpublic static void SwitchOnStringInForLoop()\n\t\t{\n\t\t\tArrayList arrayList = new ArrayList();\n\t\t\tArrayList arrayList2 = new ArrayList();\n\t\t\tSetProperty[] properties = GetProperties();\n\t\t\tfor (int i = 0; i < properties.Length; i++)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"In for-loop\");\n\t\t\t\tSetProperty setProperty = properties[i];\n\t\t\t\tswitch (setProperty.Property.Name)\n\t\t\t\t{\n\t\t\t\t\tcase \"Name1\":\n\t\t\t\t\t\tsetProperty.Set = 1;\n\t\t\t\t\t\tarrayList.Add(setProperty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Name2\":\n\t\t\t\t\t\tsetProperty.Set = 2;\n\t\t\t\t\t\tarrayList.Add(setProperty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Name3\":\n\t\t\t\t\t\tsetProperty.Set = 3;\n\t\t\t\t\t\tarrayList.Add(setProperty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Name4\":\n\t\t\t\t\t\tsetProperty.Set = 4;\n\t\t\t\t\t\tarrayList.Add(setProperty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Name5\":\n\t\t\t\t\tcase \"Name6\":\n\t\t\t\t\t\tarrayList.Add(setProperty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tarrayList2.Add(setProperty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SwitchWithComplexCondition(string[] args)\n\t\t{\n\t\t\tswitch ((args.Length == 0) ? \"dummy\" : args[0])\n\t\t\t{\n\t\t\t\tcase \"a\":\n\t\t\t\t\tConsole.WriteLine(\"a\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"b\":\n\t\t\t\t\tConsole.WriteLine(\"b\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"c\":\n\t\t\t\t\tConsole.WriteLine(\"c\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"d\":\n\t\t\t\t\tConsole.WriteLine(\"d\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\n\t\tpublic static void SwitchWithArray(string[] args)\n\t\t{\n\t\t\tswitch (args[0])\n\t\t\t{\n\t\t\t\tcase \"a\":\n\t\t\t\t\tConsole.WriteLine(\"a\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"b\":\n\t\t\t\t\tConsole.WriteLine(\"b\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"c\":\n\t\t\t\t\tConsole.WriteLine(\"c\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"d\":\n\t\t\t\t\tConsole.WriteLine(\"d\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/CS1xSwitch_Debug.il",
    "content": "\n//  Microsoft (R) .NET Framework IL Disassembler.  Version 4.6.1055.0\n//  Copyright (c) Microsoft Corporation.  All rights reserved.\n\n\n\n// Metadata version: v1.1.4322\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 1:0:5000:0\n}\n.assembly CS1xSwitch_Debug\n{\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(bool,\n  //                                                                                bool) = ( 01 00 00 01 00 00 ) \n\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module CS1xSwitch_Debug.dll\n// MVID: {3797A9DC-06AE-42B7-994E-BDC70F8FF69B}\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n// Image base: 0x07560000\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch\n       extends [mscorlib]System.Object\n{\n  .class auto ansi nested public beforefieldinit SetProperty\n         extends [mscorlib]System.Object\n  {\n    .field public initonly class [mscorlib]System.Reflection.PropertyInfo Property\n    .field private int32 _set\n    .method public hidebysig specialname \n            instance int32  get_Set() cil managed\n    {\n      // Code size       11 (0xb)\n      .maxstack  1\n      .locals init (int32 V_0)\n      IL_0000:  ldarg.0\n      IL_0001:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::_set\n      IL_0006:  stloc.0\n      IL_0007:  br.s       IL_0009\n\n      IL_0009:  ldloc.0\n      IL_000a:  ret\n    } // end of method SetProperty::get_Set\n\n    .method public hidebysig specialname \n            instance void  set_Set(int32 'value') cil managed\n    {\n      // Code size       8 (0x8)\n      .maxstack  2\n      IL_0000:  ldarg.0\n      IL_0001:  ldarg.1\n      IL_0002:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::_set\n      IL_0007:  ret\n    } // end of method SetProperty::set_Set\n\n    .method public hidebysig specialname rtspecialname \n            instance void  .ctor(class [mscorlib]System.Reflection.PropertyInfo 'property') cil managed\n    {\n      // Code size       14 (0xe)\n      .maxstack  2\n      IL_0000:  ldarg.0\n      IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n      IL_0006:  ldarg.0\n      IL_0007:  ldarg.1\n      IL_0008:  stfld      class [mscorlib]System.Reflection.PropertyInfo ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::Property\n      IL_000d:  ret\n    } // end of method SetProperty::.ctor\n\n    .property instance int32 Set()\n    {\n      .get instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::get_Set()\n      .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::set_Set(int32)\n    } // end of property SetProperty::Set\n  } // end of class SetProperty\n\n  .class auto ansi sealed nested public State\n         extends [mscorlib]System.Enum\n  {\n    .field public specialname rtspecialname int32 value__\n    .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State False = int32(0x00000000)\n    .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State True = int32(0x00000001)\n    .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State Null = int32(0x00000002)\n  } // end of class State\n\n  .method public hidebysig static string \n          SparseIntegerSwitch(int32 i) cil managed\n  {\n    // Code size       207 (0xcf)\n    .maxstack  2\n    .locals init (string V_0,\n             int32 V_1)\n    IL_0000:  ldstr      \"SparseIntegerSwitch: \"\n    IL_0005:  ldarg.0\n    IL_0006:  box        [mscorlib]System.Int32\n    IL_000b:  call       string [mscorlib]System.String::Concat(object,\n                                                                object)\n    IL_0010:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0015:  ldarg.0\n    IL_0016:  stloc.1\n    IL_0017:  ldloc.1\n    IL_0018:  ldc.i4.4\n    IL_0019:  bgt.s      IL_004a\n\n    IL_001b:  ldloc.1\n    IL_001c:  ldc.i4     0xff676980\n    IL_0021:  beq.s      IL_006d\n\n    IL_0023:  ldloc.1\n    IL_0024:  ldc.i4.s   -100\n    IL_0026:  beq.s      IL_0075\n\n    IL_0028:  ldloc.1\n    IL_0029:  ldc.i4.m1\n    IL_002a:  sub\n    IL_002b:  switch     ( \n                          IL_007d,\n                          IL_0085,\n                          IL_008d,\n                          IL_0095,\n                          IL_00c5,\n                          IL_009d)\n    IL_0048:  br.s       IL_00c5\n\n    IL_004a:  ldloc.1\n    IL_004b:  ldc.i4.s   100\n    IL_004d:  beq.s      IL_00a5\n\n    IL_004f:  ldloc.1\n    IL_0050:  ldc.i4     0x2710\n    IL_0055:  sub\n    IL_0056:  switch     ( \n                          IL_00ad,\n                          IL_00b5)\n    IL_0063:  ldloc.1\n    IL_0064:  ldc.i4     0x7fffffff\n    IL_0069:  beq.s      IL_00bd\n\n    IL_006b:  br.s       IL_00c5\n\n    IL_006d:  ldstr      \"-10 mln\"\n    IL_0072:  stloc.0\n    IL_0073:  br.s       IL_00cd\n\n    IL_0075:  ldstr      \"-hundred\"\n    IL_007a:  stloc.0\n    IL_007b:  br.s       IL_00cd\n\n    IL_007d:  ldstr      \"-1\"\n    IL_0082:  stloc.0\n    IL_0083:  br.s       IL_00cd\n\n    IL_0085:  ldstr      \"0\"\n    IL_008a:  stloc.0\n    IL_008b:  br.s       IL_00cd\n\n    IL_008d:  ldstr      \"1\"\n    IL_0092:  stloc.0\n    IL_0093:  br.s       IL_00cd\n\n    IL_0095:  ldstr      \"2\"\n    IL_009a:  stloc.0\n    IL_009b:  br.s       IL_00cd\n\n    IL_009d:  ldstr      \"4\"\n    IL_00a2:  stloc.0\n    IL_00a3:  br.s       IL_00cd\n\n    IL_00a5:  ldstr      \"hundred\"\n    IL_00aa:  stloc.0\n    IL_00ab:  br.s       IL_00cd\n\n    IL_00ad:  ldstr      \"ten thousand\"\n    IL_00b2:  stloc.0\n    IL_00b3:  br.s       IL_00cd\n\n    IL_00b5:  ldstr      \"ten thousand and one\"\n    IL_00ba:  stloc.0\n    IL_00bb:  br.s       IL_00cd\n\n    IL_00bd:  ldstr      \"int.MaxValue\"\n    IL_00c2:  stloc.0\n    IL_00c3:  br.s       IL_00cd\n\n    IL_00c5:  ldstr      \"something else\"\n    IL_00ca:  stloc.0\n    IL_00cb:  br.s       IL_00cd\n\n    IL_00cd:  ldloc.0\n    IL_00ce:  ret\n  } // end of method Switch::SparseIntegerSwitch\n\n  .method public hidebysig static void  SwitchOverInt(int32 i) cil managed\n  {\n    // Code size       136 (0x88)\n    .maxstack  2\n    .locals init (int32 V_0)\n    IL_0000:  ldarg.0\n    IL_0001:  stloc.0\n    IL_0002:  ldloc.0\n    IL_0003:  ldc.i4.s   10\n    IL_0005:  bgt.s      IL_0016\n\n    IL_0007:  ldloc.0\n    IL_0008:  ldc.i4.0\n    IL_0009:  beq.s      IL_0033\n\n    IL_000b:  ldloc.0\n    IL_000c:  ldc.i4.5\n    IL_000d:  beq.s      IL_003f\n\n    IL_000f:  ldloc.0\n    IL_0010:  ldc.i4.s   10\n    IL_0012:  beq.s      IL_004b\n\n    IL_0014:  br.s       IL_0087\n\n    IL_0016:  ldloc.0\n    IL_0017:  ldc.i4.s   20\n    IL_0019:  bgt.s      IL_0027\n\n    IL_001b:  ldloc.0\n    IL_001c:  ldc.i4.s   15\n    IL_001e:  beq.s      IL_0057\n\n    IL_0020:  ldloc.0\n    IL_0021:  ldc.i4.s   20\n    IL_0023:  beq.s      IL_0063\n\n    IL_0025:  br.s       IL_0087\n\n    IL_0027:  ldloc.0\n    IL_0028:  ldc.i4.s   25\n    IL_002a:  beq.s      IL_006f\n\n    IL_002c:  ldloc.0\n    IL_002d:  ldc.i4.s   30\n    IL_002f:  beq.s      IL_007b\n\n    IL_0031:  br.s       IL_0087\n\n    IL_0033:  ldstr      \"zero\"\n    IL_0038:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_003d:  br.s       IL_0087\n\n    IL_003f:  ldstr      \"five\"\n    IL_0044:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0049:  br.s       IL_0087\n\n    IL_004b:  ldstr      \"ten\"\n    IL_0050:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0055:  br.s       IL_0087\n\n    IL_0057:  ldstr      \"fifteen\"\n    IL_005c:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0061:  br.s       IL_0087\n\n    IL_0063:  ldstr      \"twenty\"\n    IL_0068:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_006d:  br.s       IL_0087\n\n    IL_006f:  ldstr      \"twenty-five\"\n    IL_0074:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0079:  br.s       IL_0087\n\n    IL_007b:  ldstr      \"thirty\"\n    IL_0080:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0085:  br.s       IL_0087\n\n    IL_0087:  ret\n  } // end of method Switch::SwitchOverInt\n\n  .method public hidebysig static string \n          ShortSwitchOverString(string text) cil managed\n  {\n    // Code size       105 (0x69)\n    .maxstack  3\n    .locals init (string V_0,\n             string V_1)\n    IL_0000:  ldstr      \"ShortSwitchOverString: \"\n    IL_0005:  ldarg.0\n    IL_0006:  call       string [mscorlib]System.String::Concat(string,\n                                                                string)\n    IL_000b:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0010:  ldstr      \"First case\"\n    IL_0015:  ldstr      \"Second case\"\n    IL_001a:  ldstr      \"Third case\"\n    IL_001f:  leave.s    IL_0021\n\n    IL_0021:  ldarg.0\n    IL_0022:  dup\n    IL_0023:  stloc.1\n    IL_0024:  brfalse.s  IL_005f\n\n    IL_0026:  ldloc.1\n    IL_0027:  call       string [mscorlib]System.String::IsInterned(string)\n    IL_002c:  stloc.1\n    IL_002d:  ldloc.1\n    IL_002e:  ldstr      \"First case\"\n    IL_0033:  beq.s      IL_0047\n\n    IL_0035:  ldloc.1\n    IL_0036:  ldstr      \"Second case\"\n    IL_003b:  beq.s      IL_004f\n\n    IL_003d:  ldloc.1\n    IL_003e:  ldstr      \"Third case\"\n    IL_0043:  beq.s      IL_0057\n\n    IL_0045:  br.s       IL_005f\n\n    IL_0047:  ldstr      \"Text1\"\n    IL_004c:  stloc.0\n    IL_004d:  br.s       IL_0067\n\n    IL_004f:  ldstr      \"Text2\"\n    IL_0054:  stloc.0\n    IL_0055:  br.s       IL_0067\n\n    IL_0057:  ldstr      \"Text3\"\n    IL_005c:  stloc.0\n    IL_005d:  br.s       IL_0067\n\n    IL_005f:  ldstr      \"Default\"\n    IL_0064:  stloc.0\n    IL_0065:  br.s       IL_0067\n\n    IL_0067:  ldloc.0\n    IL_0068:  ret\n  } // end of method Switch::ShortSwitchOverString\n\n  .method public hidebysig static string \n          ShortSwitchOverStringWithNullCase(string text) cil managed\n  {\n    // Code size       92 (0x5c)\n    .maxstack  2\n    .locals init (string V_0,\n             string V_1)\n    IL_0000:  ldstr      \"ShortSwitchOverStringWithNullCase: \"\n    IL_0005:  ldarg.0\n    IL_0006:  call       string [mscorlib]System.String::Concat(string,\n                                                                string)\n    IL_000b:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0010:  ldstr      \"First case\"\n    IL_0015:  ldstr      \"Second case\"\n    IL_001a:  leave.s    IL_001c\n\n    IL_001c:  ldarg.0\n    IL_001d:  dup\n    IL_001e:  stloc.1\n    IL_001f:  brfalse.s  IL_004a\n\n    IL_0021:  ldloc.1\n    IL_0022:  call       string [mscorlib]System.String::IsInterned(string)\n    IL_0027:  stloc.1\n    IL_0028:  ldloc.1\n    IL_0029:  ldstr      \"First case\"\n    IL_002e:  beq.s      IL_003a\n\n    IL_0030:  ldloc.1\n    IL_0031:  ldstr      \"Second case\"\n    IL_0036:  beq.s      IL_0042\n\n    IL_0038:  br.s       IL_0052\n\n    IL_003a:  ldstr      \"Text1\"\n    IL_003f:  stloc.0\n    IL_0040:  br.s       IL_005a\n\n    IL_0042:  ldstr      \"Text2\"\n    IL_0047:  stloc.0\n    IL_0048:  br.s       IL_005a\n\n    IL_004a:  ldstr      \"null\"\n    IL_004f:  stloc.0\n    IL_0050:  br.s       IL_005a\n\n    IL_0052:  ldstr      \"Default\"\n    IL_0057:  stloc.0\n    IL_0058:  br.s       IL_005a\n\n    IL_005a:  ldloc.0\n    IL_005b:  ret\n  } // end of method Switch::ShortSwitchOverStringWithNullCase\n\n  .method public hidebysig static string \n          SwitchOverString1(string text) cil managed\n  {\n    // Code size       185 (0xb9)\n    .maxstack  7\n    .locals init (string V_0,\n             string V_1)\n    IL_0000:  ldstr      \"SwitchOverString1: \"\n    IL_0005:  ldarg.0\n    IL_0006:  call       string [mscorlib]System.String::Concat(string,\n                                                                string)\n    IL_000b:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0010:  ldstr      \"First case\"\n    IL_0015:  ldstr      \"Second case\"\n    IL_001a:  ldstr      \"2nd case\"\n    IL_001f:  ldstr      \"Third case\"\n    IL_0024:  ldstr      \"Fourth case\"\n    IL_0029:  ldstr      \"Fifth case\"\n    IL_002e:  ldstr      \"Sixth case\"\n    IL_0033:  leave.s    IL_0035\n\n    IL_0035:  ldarg.0\n    IL_0036:  dup\n    IL_0037:  stloc.1\n    IL_0038:  brfalse.s  IL_00ab\n\n    IL_003a:  ldloc.1\n    IL_003b:  call       string [mscorlib]System.String::IsInterned(string)\n    IL_0040:  stloc.1\n    IL_0041:  ldloc.1\n    IL_0042:  ldstr      \"First case\"\n    IL_0047:  beq.s      IL_007b\n\n    IL_0049:  ldloc.1\n    IL_004a:  ldstr      \"Second case\"\n    IL_004f:  beq.s      IL_0083\n\n    IL_0051:  ldloc.1\n    IL_0052:  ldstr      \"2nd case\"\n    IL_0057:  beq.s      IL_0083\n\n    IL_0059:  ldloc.1\n    IL_005a:  ldstr      \"Third case\"\n    IL_005f:  beq.s      IL_008b\n\n    IL_0061:  ldloc.1\n    IL_0062:  ldstr      \"Fourth case\"\n    IL_0067:  beq.s      IL_0093\n\n    IL_0069:  ldloc.1\n    IL_006a:  ldstr      \"Fifth case\"\n    IL_006f:  beq.s      IL_009b\n\n    IL_0071:  ldloc.1\n    IL_0072:  ldstr      \"Sixth case\"\n    IL_0077:  beq.s      IL_00a3\n\n    IL_0079:  br.s       IL_00af\n\n    IL_007b:  ldstr      \"Text1\"\n    IL_0080:  stloc.0\n    IL_0081:  br.s       IL_00b7\n\n    IL_0083:  ldstr      \"Text2\"\n    IL_0088:  stloc.0\n    IL_0089:  br.s       IL_00b7\n\n    IL_008b:  ldstr      \"Text3\"\n    IL_0090:  stloc.0\n    IL_0091:  br.s       IL_00b7\n\n    IL_0093:  ldstr      \"Text4\"\n    IL_0098:  stloc.0\n    IL_0099:  br.s       IL_00b7\n\n    IL_009b:  ldstr      \"Text5\"\n    IL_00a0:  stloc.0\n    IL_00a1:  br.s       IL_00b7\n\n    IL_00a3:  ldstr      \"Text6\"\n    IL_00a8:  stloc.0\n    IL_00a9:  br.s       IL_00b7\n\n    IL_00ab:  ldnull\n    IL_00ac:  stloc.0\n    IL_00ad:  br.s       IL_00b7\n\n    IL_00af:  ldstr      \"Default\"\n    IL_00b4:  stloc.0\n    IL_00b5:  br.s       IL_00b7\n\n    IL_00b7:  ldloc.0\n    IL_00b8:  ret\n  } // end of method Switch::SwitchOverString1\n\n  .method public hidebysig static string \n          SwitchOverString2() cil managed\n  {\n    // Code size       418 (0x1a2)\n    .maxstack  4\n    .locals init (string V_0,\n             object V_1)\n    IL_0000:  volatile.\n    IL_0002:  ldsfld     class [mscorlib]System.Collections.Hashtable '<PrivateImplementationDetails>'::'$$method0x6000006-1'\n    IL_0007:  brtrue     IL_00dc\n\n    IL_000c:  ldc.i4.s   24\n    IL_000e:  ldc.r4     0.5\n    IL_0013:  newobj     instance void [mscorlib]System.Collections.Hashtable::.ctor(int32,\n                                                                                     float32)\n    IL_0018:  dup\n    IL_0019:  ldstr      \"First case\"\n    IL_001e:  ldc.i4.0\n    IL_001f:  box        [mscorlib]System.Int32\n    IL_0024:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_0029:  dup\n    IL_002a:  ldstr      \"Second case\"\n    IL_002f:  ldc.i4.1\n    IL_0030:  box        [mscorlib]System.Int32\n    IL_0035:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_003a:  dup\n    IL_003b:  ldstr      \"Third case\"\n    IL_0040:  ldc.i4.2\n    IL_0041:  box        [mscorlib]System.Int32\n    IL_0046:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_004b:  dup\n    IL_004c:  ldstr      \"Fourth case\"\n    IL_0051:  ldc.i4.3\n    IL_0052:  box        [mscorlib]System.Int32\n    IL_0057:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_005c:  dup\n    IL_005d:  ldstr      \"Fifth case\"\n    IL_0062:  ldc.i4.4\n    IL_0063:  box        [mscorlib]System.Int32\n    IL_0068:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_006d:  dup\n    IL_006e:  ldstr      \"Sixth case\"\n    IL_0073:  ldc.i4.5\n    IL_0074:  box        [mscorlib]System.Int32\n    IL_0079:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_007e:  dup\n    IL_007f:  ldstr      \"Seventh case\"\n    IL_0084:  ldc.i4.6\n    IL_0085:  box        [mscorlib]System.Int32\n    IL_008a:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_008f:  dup\n    IL_0090:  ldstr      \"Eighth case\"\n    IL_0095:  ldc.i4.7\n    IL_0096:  box        [mscorlib]System.Int32\n    IL_009b:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_00a0:  dup\n    IL_00a1:  ldstr      \"Ninth case\"\n    IL_00a6:  ldc.i4.8\n    IL_00a7:  box        [mscorlib]System.Int32\n    IL_00ac:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_00b1:  dup\n    IL_00b2:  ldstr      \"Tenth case\"\n    IL_00b7:  ldc.i4.s   9\n    IL_00b9:  box        [mscorlib]System.Int32\n    IL_00be:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_00c3:  dup\n    IL_00c4:  ldstr      \"Eleventh case\"\n    IL_00c9:  ldc.i4.s   10\n    IL_00cb:  box        [mscorlib]System.Int32\n    IL_00d0:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_00d5:  volatile.\n    IL_00d7:  stsfld     class [mscorlib]System.Collections.Hashtable '<PrivateImplementationDetails>'::'$$method0x6000006-1'\n    IL_00dc:  ldstr      \"SwitchOverString2:\"\n    IL_00e1:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_00e6:  call       string [mscorlib]System.Environment::get_UserName()\n    IL_00eb:  dup\n    IL_00ec:  stloc.1\n    IL_00ed:  brfalse    IL_0198\n\n    IL_00f2:  volatile.\n    IL_00f4:  ldsfld     class [mscorlib]System.Collections.Hashtable '<PrivateImplementationDetails>'::'$$method0x6000006-1'\n    IL_00f9:  ldloc.1\n    IL_00fa:  call       instance object [mscorlib]System.Collections.Hashtable::get_Item(object)\n    IL_00ff:  dup\n    IL_0100:  stloc.1\n    IL_0101:  brfalse    IL_0198\n\n    IL_0106:  ldloc.1\n    IL_0107:  unbox      [mscorlib]System.Int32\n    IL_010c:  ldind.i4\n    IL_010d:  switch     ( \n                          IL_0140,\n                          IL_0148,\n                          IL_0150,\n                          IL_0158,\n                          IL_0160,\n                          IL_0168,\n                          IL_0170,\n                          IL_0178,\n                          IL_0180,\n                          IL_0188,\n                          IL_0190)\n    IL_013e:  br.s       IL_0198\n\n    IL_0140:  ldstr      \"Text1\"\n    IL_0145:  stloc.0\n    IL_0146:  br.s       IL_01a0\n\n    IL_0148:  ldstr      \"Text2\"\n    IL_014d:  stloc.0\n    IL_014e:  br.s       IL_01a0\n\n    IL_0150:  ldstr      \"Text3\"\n    IL_0155:  stloc.0\n    IL_0156:  br.s       IL_01a0\n\n    IL_0158:  ldstr      \"Text4\"\n    IL_015d:  stloc.0\n    IL_015e:  br.s       IL_01a0\n\n    IL_0160:  ldstr      \"Text5\"\n    IL_0165:  stloc.0\n    IL_0166:  br.s       IL_01a0\n\n    IL_0168:  ldstr      \"Text6\"\n    IL_016d:  stloc.0\n    IL_016e:  br.s       IL_01a0\n\n    IL_0170:  ldstr      \"Text7\"\n    IL_0175:  stloc.0\n    IL_0176:  br.s       IL_01a0\n\n    IL_0178:  ldstr      \"Text8\"\n    IL_017d:  stloc.0\n    IL_017e:  br.s       IL_01a0\n\n    IL_0180:  ldstr      \"Text9\"\n    IL_0185:  stloc.0\n    IL_0186:  br.s       IL_01a0\n\n    IL_0188:  ldstr      \"Text10\"\n    IL_018d:  stloc.0\n    IL_018e:  br.s       IL_01a0\n\n    IL_0190:  ldstr      \"Text11\"\n    IL_0195:  stloc.0\n    IL_0196:  br.s       IL_01a0\n\n    IL_0198:  ldstr      \"Default\"\n    IL_019d:  stloc.0\n    IL_019e:  br.s       IL_01a0\n\n    IL_01a0:  ldloc.0\n    IL_01a1:  ret\n  } // end of method Switch::SwitchOverString2\n\n  .method public hidebysig static string \n          TwoDifferentSwitchBlocksInTryFinally() cil managed\n  {\n    // Code size       925 (0x39d)\n    .maxstack  4\n    .locals init (string V_0,\n             object V_1)\n    IL_0000:  volatile.\n    IL_0002:  ldsfld     class [mscorlib]System.Collections.Hashtable '<PrivateImplementationDetails>'::'$$method0x6000007-1'\n    IL_0007:  brtrue     IL_01b8\n\n    IL_000c:  ldc.i4.s   24\n    IL_000e:  ldc.r4     0.5\n    IL_0013:  newobj     instance void [mscorlib]System.Collections.Hashtable::.ctor(int32,\n                                                                                     float32)\n    IL_0018:  dup\n    IL_0019:  ldstr      \"12\"\n    IL_001e:  ldc.i4.0\n    IL_001f:  box        [mscorlib]System.Int32\n    IL_0024:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_0029:  dup\n    IL_002a:  ldstr      \"13\"\n    IL_002f:  ldc.i4.1\n    IL_0030:  box        [mscorlib]System.Int32\n    IL_0035:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_003a:  dup\n    IL_003b:  ldstr      \"14\"\n    IL_0040:  ldc.i4.2\n    IL_0041:  box        [mscorlib]System.Int32\n    IL_0046:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_004b:  dup\n    IL_004c:  ldstr      \"15\"\n    IL_0051:  ldc.i4.3\n    IL_0052:  box        [mscorlib]System.Int32\n    IL_0057:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_005c:  dup\n    IL_005d:  ldstr      \"16\"\n    IL_0062:  ldc.i4.4\n    IL_0063:  box        [mscorlib]System.Int32\n    IL_0068:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_006d:  dup\n    IL_006e:  ldstr      \"17\"\n    IL_0073:  ldc.i4.5\n    IL_0074:  box        [mscorlib]System.Int32\n    IL_0079:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_007e:  dup\n    IL_007f:  ldstr      \"18\"\n    IL_0084:  ldc.i4.6\n    IL_0085:  box        [mscorlib]System.Int32\n    IL_008a:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_008f:  dup\n    IL_0090:  ldstr      \"19 case\"\n    IL_0095:  ldc.i4.7\n    IL_0096:  box        [mscorlib]System.Int32\n    IL_009b:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_00a0:  dup\n    IL_00a1:  ldstr      \"20 case\"\n    IL_00a6:  ldc.i4.8\n    IL_00a7:  box        [mscorlib]System.Int32\n    IL_00ac:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_00b1:  dup\n    IL_00b2:  ldstr      \"21 case\"\n    IL_00b7:  ldc.i4.s   9\n    IL_00b9:  box        [mscorlib]System.Int32\n    IL_00be:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_00c3:  dup\n    IL_00c4:  ldstr      \"22 case\"\n    IL_00c9:  ldc.i4.s   10\n    IL_00cb:  box        [mscorlib]System.Int32\n    IL_00d0:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_00d5:  volatile.\n    IL_00d7:  stsfld     class [mscorlib]System.Collections.Hashtable '<PrivateImplementationDetails>'::'$$method0x6000007-1'\n    IL_00dc:  volatile.\n    IL_00de:  ldsfld     class [mscorlib]System.Collections.Hashtable '<PrivateImplementationDetails>'::'$$method0x6000007-2'\n    IL_00e3:  brtrue     IL_01b8\n\n    IL_00e8:  ldc.i4.s   24\n    IL_00ea:  ldc.r4     0.5\n    IL_00ef:  newobj     instance void [mscorlib]System.Collections.Hashtable::.ctor(int32,\n                                                                                     float32)\n    IL_00f4:  dup\n    IL_00f5:  ldstr      \"First case\"\n    IL_00fa:  ldc.i4.0\n    IL_00fb:  box        [mscorlib]System.Int32\n    IL_0100:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_0105:  dup\n    IL_0106:  ldstr      \"Second case\"\n    IL_010b:  ldc.i4.1\n    IL_010c:  box        [mscorlib]System.Int32\n    IL_0111:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_0116:  dup\n    IL_0117:  ldstr      \"Third case\"\n    IL_011c:  ldc.i4.2\n    IL_011d:  box        [mscorlib]System.Int32\n    IL_0122:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_0127:  dup\n    IL_0128:  ldstr      \"Fourth case\"\n    IL_012d:  ldc.i4.3\n    IL_012e:  box        [mscorlib]System.Int32\n    IL_0133:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_0138:  dup\n    IL_0139:  ldstr      \"Fifth case\"\n    IL_013e:  ldc.i4.4\n    IL_013f:  box        [mscorlib]System.Int32\n    IL_0144:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_0149:  dup\n    IL_014a:  ldstr      \"Sixth case\"\n    IL_014f:  ldc.i4.5\n    IL_0150:  box        [mscorlib]System.Int32\n    IL_0155:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_015a:  dup\n    IL_015b:  ldstr      \"Seventh case\"\n    IL_0160:  ldc.i4.6\n    IL_0161:  box        [mscorlib]System.Int32\n    IL_0166:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_016b:  dup\n    IL_016c:  ldstr      \"Eighth case\"\n    IL_0171:  ldc.i4.7\n    IL_0172:  box        [mscorlib]System.Int32\n    IL_0177:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_017c:  dup\n    IL_017d:  ldstr      \"Ninth case\"\n    IL_0182:  ldc.i4.8\n    IL_0183:  box        [mscorlib]System.Int32\n    IL_0188:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_018d:  dup\n    IL_018e:  ldstr      \"Tenth case\"\n    IL_0193:  ldc.i4.s   9\n    IL_0195:  box        [mscorlib]System.Int32\n    IL_019a:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_019f:  dup\n    IL_01a0:  ldstr      \"Eleventh case\"\n    IL_01a5:  ldc.i4.s   10\n    IL_01a7:  box        [mscorlib]System.Int32\n    IL_01ac:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_01b1:  volatile.\n    IL_01b3:  stsfld     class [mscorlib]System.Collections.Hashtable '<PrivateImplementationDetails>'::'$$method0x6000007-2'\n    .try\n    {\n      IL_01b8:  ldstr      \"TwoDifferentSwitchBlocks:\"\n      IL_01bd:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_01c2:  call       string [mscorlib]System.Environment::get_UserName()\n      IL_01c7:  dup\n      IL_01c8:  stloc.1\n      IL_01c9:  brfalse    IL_0295\n\n      IL_01ce:  volatile.\n      IL_01d0:  ldsfld     class [mscorlib]System.Collections.Hashtable '<PrivateImplementationDetails>'::'$$method0x6000007-2'\n      IL_01d5:  ldloc.1\n      IL_01d6:  call       instance object [mscorlib]System.Collections.Hashtable::get_Item(object)\n      IL_01db:  dup\n      IL_01dc:  stloc.1\n      IL_01dd:  brfalse    IL_0295\n\n      IL_01e2:  ldloc.1\n      IL_01e3:  unbox      [mscorlib]System.Int32\n      IL_01e8:  ldind.i4\n      IL_01e9:  switch     ( \n                            IL_021c,\n                            IL_0227,\n                            IL_0232,\n                            IL_023d,\n                            IL_0248,\n                            IL_0253,\n                            IL_025e,\n                            IL_0269,\n                            IL_0274,\n                            IL_027f,\n                            IL_028a)\n      IL_021a:  br.s       IL_0295\n\n      IL_021c:  ldstr      \"Text1\"\n      IL_0221:  stloc.0\n      IL_0222:  leave      IL_039b\n\n      IL_0227:  ldstr      \"Text2\"\n      IL_022c:  stloc.0\n      IL_022d:  leave      IL_039b\n\n      IL_0232:  ldstr      \"Text3\"\n      IL_0237:  stloc.0\n      IL_0238:  leave      IL_039b\n\n      IL_023d:  ldstr      \"Text4\"\n      IL_0242:  stloc.0\n      IL_0243:  leave      IL_039b\n\n      IL_0248:  ldstr      \"Text5\"\n      IL_024d:  stloc.0\n      IL_024e:  leave      IL_039b\n\n      IL_0253:  ldstr      \"Text6\"\n      IL_0258:  stloc.0\n      IL_0259:  leave      IL_039b\n\n      IL_025e:  ldstr      \"Text7\"\n      IL_0263:  stloc.0\n      IL_0264:  leave      IL_039b\n\n      IL_0269:  ldstr      \"Text8\"\n      IL_026e:  stloc.0\n      IL_026f:  leave      IL_039b\n\n      IL_0274:  ldstr      \"Text9\"\n      IL_0279:  stloc.0\n      IL_027a:  leave      IL_039b\n\n      IL_027f:  ldstr      \"Text10\"\n      IL_0284:  stloc.0\n      IL_0285:  leave      IL_039b\n\n      IL_028a:  ldstr      \"Text11\"\n      IL_028f:  stloc.0\n      IL_0290:  leave      IL_039b\n\n      IL_0295:  ldstr      \"Default\"\n      IL_029a:  stloc.0\n      IL_029b:  leave      IL_039b\n\n    }  // end .try\n    finally\n    {\n      IL_02a0:  ldstr      \"Second switch:\"\n      IL_02a5:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_02aa:  call       string [mscorlib]System.Console::ReadLine()\n      IL_02af:  dup\n      IL_02b0:  stloc.1\n      IL_02b1:  brfalse    IL_038e\n\n      IL_02b6:  volatile.\n      IL_02b8:  ldsfld     class [mscorlib]System.Collections.Hashtable '<PrivateImplementationDetails>'::'$$method0x6000007-1'\n      IL_02bd:  ldloc.1\n      IL_02be:  call       instance object [mscorlib]System.Collections.Hashtable::get_Item(object)\n      IL_02c3:  dup\n      IL_02c4:  stloc.1\n      IL_02c5:  brfalse    IL_038e\n\n      IL_02ca:  ldloc.1\n      IL_02cb:  unbox      [mscorlib]System.Int32\n      IL_02d0:  ldind.i4\n      IL_02d1:  switch     ( \n                            IL_0307,\n                            IL_0316,\n                            IL_0322,\n                            IL_032e,\n                            IL_033a,\n                            IL_0346,\n                            IL_0352,\n                            IL_035e,\n                            IL_036a,\n                            IL_0376,\n                            IL_0382)\n      IL_0302:  br         IL_038e\n\n      IL_0307:  ldstr      \"Te43234xt1\"\n      IL_030c:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_0311:  br         IL_039a\n\n      IL_0316:  ldstr      \"Te223443xt2\"\n      IL_031b:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_0320:  br.s       IL_039a\n\n      IL_0322:  ldstr      \"Te234xt3\"\n      IL_0327:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_032c:  br.s       IL_039a\n\n      IL_032e:  ldstr      \"Tex243t4\"\n      IL_0333:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_0338:  br.s       IL_039a\n\n      IL_033a:  ldstr      \"Tex243t5\"\n      IL_033f:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_0344:  br.s       IL_039a\n\n      IL_0346:  ldstr      \"Text2346\"\n      IL_034b:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_0350:  br.s       IL_039a\n\n      IL_0352:  ldstr      \"Text234234\"\n      IL_0357:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_035c:  br.s       IL_039a\n\n      IL_035e:  ldstr      \"Text8234\"\n      IL_0363:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_0368:  br.s       IL_039a\n\n      IL_036a:  ldstr      \"Text923423\"\n      IL_036f:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_0374:  br.s       IL_039a\n\n      IL_0376:  ldstr      \"Text10\"\n      IL_037b:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_0380:  br.s       IL_039a\n\n      IL_0382:  ldstr      \"Text1134123\"\n      IL_0387:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_038c:  br.s       IL_039a\n\n      IL_038e:  ldstr      \"Defa234234ult\"\n      IL_0393:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_0398:  br.s       IL_039a\n\n      IL_039a:  endfinally\n    }  // end handler\n    IL_039b:  ldloc.0\n    IL_039c:  ret\n  } // end of method Switch::TwoDifferentSwitchBlocksInTryFinally\n\n  .method public hidebysig static string \n          SwitchOverBool(bool b) cil managed\n  {\n    // Code size       62 (0x3e)\n    .maxstack  2\n    .locals init (string V_0,\n             bool V_1)\n    IL_0000:  ldstr      \"SwitchOverBool: \"\n    IL_0005:  ldarga.s   b\n    IL_0007:  call       instance string [mscorlib]System.Boolean::ToString()\n    IL_000c:  call       string [mscorlib]System.String::Concat(string,\n                                                                string)\n    IL_0011:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0016:  ldarg.0\n    IL_0017:  stloc.1\n    IL_0018:  ldloc.1\n    IL_0019:  switch     ( \n                          IL_0030,\n                          IL_0028)\n    IL_0026:  br.s       IL_0038\n\n    IL_0028:  ldsfld     string [mscorlib]System.Boolean::TrueString\n    IL_002d:  stloc.0\n    IL_002e:  br.s       IL_003c\n\n    IL_0030:  ldsfld     string [mscorlib]System.Boolean::FalseString\n    IL_0035:  stloc.0\n    IL_0036:  br.s       IL_003c\n\n    IL_0038:  ldnull\n    IL_0039:  stloc.0\n    IL_003a:  br.s       IL_003c\n\n    IL_003c:  ldloc.0\n    IL_003d:  ret\n  } // end of method Switch::SwitchOverBool\n\n  .method public hidebysig static void  SwitchInLoop(int32 i) cil managed\n  {\n    // Code size       117 (0x75)\n    .maxstack  2\n    .locals init (int32 V_0)\n    IL_0000:  ldstr      \"SwitchInLoop: \"\n    IL_0005:  ldarg.0\n    IL_0006:  box        [mscorlib]System.Int32\n    IL_000b:  call       string [mscorlib]System.String::Concat(object,\n                                                                object)\n    IL_0010:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0015:  br.s       IL_0072\n\n    IL_0017:  ldarg.0\n    IL_0018:  stloc.0\n    IL_0019:  ldloc.0\n    IL_001a:  ldc.i4.1\n    IL_001b:  sub\n    IL_001c:  switch     ( \n                          IL_0033,\n                          IL_003f,\n                          IL_0057,\n                          IL_004b)\n    IL_0031:  br.s       IL_0057\n\n    IL_0033:  ldstr      \"one\"\n    IL_0038:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_003d:  br.s       IL_006d\n\n    IL_003f:  ldstr      \"two\"\n    IL_0044:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0049:  br.s       IL_006d\n\n    IL_004b:  ldstr      \"four\"\n    IL_0050:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0055:  br.s       IL_0074\n\n    IL_0057:  ldstr      \"default\"\n    IL_005c:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0061:  ldstr      \"more code\"\n    IL_0066:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_006b:  br.s       IL_0074\n\n    IL_006d:  ldarg.0\n    IL_006e:  ldc.i4.1\n    IL_006f:  add\n    IL_0070:  starg.s    i\n    IL_0072:  br.s       IL_0017\n\n    IL_0074:  ret\n  } // end of method Switch::SwitchInLoop\n\n  .method public hidebysig static void  SwitchWithGoto(int32 i) cil managed\n  {\n    // Code size       120 (0x78)\n    .maxstack  2\n    .locals init (int32 V_0)\n    IL_0000:  ldstr      \"SwitchWithGoto: \"\n    IL_0005:  ldarg.0\n    IL_0006:  box        [mscorlib]System.Int32\n    IL_000b:  call       string [mscorlib]System.String::Concat(object,\n                                                                object)\n    IL_0010:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0015:  ldarg.0\n    IL_0016:  stloc.0\n    IL_0017:  ldloc.0\n    IL_0018:  ldc.i4.1\n    IL_0019:  sub\n    IL_001a:  switch     ( \n                          IL_0031,\n                          IL_003d,\n                          IL_0049,\n                          IL_0055)\n    IL_002f:  br.s       IL_0061\n\n    IL_0031:  ldstr      \"one\"\n    IL_0036:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_003b:  br.s       IL_0061\n\n    IL_003d:  ldstr      \"two\"\n    IL_0042:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0047:  br.s       IL_0049\n\n    IL_0049:  ldstr      \"three\"\n    IL_004e:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0053:  br.s       IL_006d\n\n    IL_0055:  ldstr      \"four\"\n    IL_005a:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_005f:  br.s       IL_0077\n\n    IL_0061:  ldstr      \"default\"\n    IL_0066:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_006b:  br.s       IL_006d\n\n    IL_006d:  ldstr      \"End of method\"\n    IL_0072:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0077:  ret\n  } // end of method Switch::SwitchWithGoto\n\n  .method private hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty[] \n          GetProperties() cil managed\n  {\n    // Code size       11 (0xb)\n    .maxstack  1\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty[] V_0)\n    IL_0000:  ldc.i4.0\n    IL_0001:  newarr     ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty\n    IL_0006:  stloc.0\n    IL_0007:  br.s       IL_0009\n\n    IL_0009:  ldloc.0\n    IL_000a:  ret\n  } // end of method Switch::GetProperties\n\n  .method public hidebysig static void  SwitchOnStringInForLoop() cil managed\n  {\n    // Code size       269 (0x10d)\n    .maxstack  6\n    .locals init (class [mscorlib]System.Collections.ArrayList V_0,\n             class [mscorlib]System.Collections.ArrayList V_1,\n             class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty[] V_2,\n             int32 V_3,\n             class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty V_4,\n             string V_5)\n    IL_0000:  newobj     instance void [mscorlib]System.Collections.ArrayList::.ctor()\n    IL_0005:  stloc.0\n    IL_0006:  newobj     instance void [mscorlib]System.Collections.ArrayList::.ctor()\n    IL_000b:  stloc.1\n    IL_000c:  call       class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch::GetProperties()\n    IL_0011:  stloc.2\n    IL_0012:  ldc.i4.0\n    IL_0013:  stloc.3\n    IL_0014:  br         IL_0103\n\n    IL_0019:  ldstr      \"In for-loop\"\n    IL_001e:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0023:  ldloc.2\n    IL_0024:  ldloc.3\n    IL_0025:  ldelem.ref\n    IL_0026:  stloc.s    V_4\n    IL_0028:  ldstr      \"Name1\"\n    IL_002d:  ldstr      \"Name2\"\n    IL_0032:  ldstr      \"Name3\"\n    IL_0037:  ldstr      \"Name4\"\n    IL_003c:  ldstr      \"Name5\"\n    IL_0041:  ldstr      \"Name6\"\n    IL_0046:  leave.s    IL_0048\n\n    IL_0048:  ldloc.s    V_4\n    IL_004a:  ldfld      class [mscorlib]System.Reflection.PropertyInfo ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::Property\n    IL_004f:  callvirt   instance string [mscorlib]System.Reflection.MemberInfo::get_Name()\n    IL_0054:  dup\n    IL_0055:  stloc.s    V_5\n    IL_0057:  brfalse    IL_00f4\n\n    IL_005c:  ldloc.s    V_5\n    IL_005e:  call       string [mscorlib]System.String::IsInterned(string)\n    IL_0063:  stloc.s    V_5\n    IL_0065:  ldloc.s    V_5\n    IL_0067:  ldstr      \"Name1\"\n    IL_006c:  beq.s      IL_009d\n\n    IL_006e:  ldloc.s    V_5\n    IL_0070:  ldstr      \"Name2\"\n    IL_0075:  beq.s      IL_00b0\n\n    IL_0077:  ldloc.s    V_5\n    IL_0079:  ldstr      \"Name3\"\n    IL_007e:  beq.s      IL_00c3\n\n    IL_0080:  ldloc.s    V_5\n    IL_0082:  ldstr      \"Name4\"\n    IL_0087:  beq.s      IL_00d6\n\n    IL_0089:  ldloc.s    V_5\n    IL_008b:  ldstr      \"Name5\"\n    IL_0090:  beq.s      IL_00e9\n\n    IL_0092:  ldloc.s    V_5\n    IL_0094:  ldstr      \"Name6\"\n    IL_0099:  beq.s      IL_00e9\n\n    IL_009b:  br.s       IL_00f4\n\n    IL_009d:  ldloc.s    V_4\n    IL_009f:  ldc.i4.1\n    IL_00a0:  callvirt   instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::set_Set(int32)\n    IL_00a5:  ldloc.0\n    IL_00a6:  ldloc.s    V_4\n    IL_00a8:  callvirt   instance int32 [mscorlib]System.Collections.ArrayList::Add(object)\n    IL_00ad:  pop\n    IL_00ae:  br.s       IL_00ff\n\n    IL_00b0:  ldloc.s    V_4\n    IL_00b2:  ldc.i4.2\n    IL_00b3:  callvirt   instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::set_Set(int32)\n    IL_00b8:  ldloc.0\n    IL_00b9:  ldloc.s    V_4\n    IL_00bb:  callvirt   instance int32 [mscorlib]System.Collections.ArrayList::Add(object)\n    IL_00c0:  pop\n    IL_00c1:  br.s       IL_00ff\n\n    IL_00c3:  ldloc.s    V_4\n    IL_00c5:  ldc.i4.3\n    IL_00c6:  callvirt   instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::set_Set(int32)\n    IL_00cb:  ldloc.0\n    IL_00cc:  ldloc.s    V_4\n    IL_00ce:  callvirt   instance int32 [mscorlib]System.Collections.ArrayList::Add(object)\n    IL_00d3:  pop\n    IL_00d4:  br.s       IL_00ff\n\n    IL_00d6:  ldloc.s    V_4\n    IL_00d8:  ldc.i4.4\n    IL_00d9:  callvirt   instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::set_Set(int32)\n    IL_00de:  ldloc.0\n    IL_00df:  ldloc.s    V_4\n    IL_00e1:  callvirt   instance int32 [mscorlib]System.Collections.ArrayList::Add(object)\n    IL_00e6:  pop\n    IL_00e7:  br.s       IL_00ff\n\n    IL_00e9:  ldloc.0\n    IL_00ea:  ldloc.s    V_4\n    IL_00ec:  callvirt   instance int32 [mscorlib]System.Collections.ArrayList::Add(object)\n    IL_00f1:  pop\n    IL_00f2:  br.s       IL_00ff\n\n    IL_00f4:  ldloc.1\n    IL_00f5:  ldloc.s    V_4\n    IL_00f7:  callvirt   instance int32 [mscorlib]System.Collections.ArrayList::Add(object)\n    IL_00fc:  pop\n    IL_00fd:  br.s       IL_00ff\n\n    IL_00ff:  ldloc.3\n    IL_0100:  ldc.i4.1\n    IL_0101:  add\n    IL_0102:  stloc.3\n    IL_0103:  ldloc.3\n    IL_0104:  ldloc.2\n    IL_0105:  ldlen\n    IL_0106:  conv.i4\n    IL_0107:  blt        IL_0019\n\n    IL_010c:  ret\n  } // end of method Switch::SwitchOnStringInForLoop\n\n  .method public hidebysig static void  SwitchWithComplexCondition(string[] args) cil managed\n  {\n    // Code size       141 (0x8d)\n    .maxstack  4\n    .locals init (string V_0)\n    IL_0000:  ldstr      \"a\"\n    IL_0005:  ldstr      \"b\"\n    IL_000a:  ldstr      \"c\"\n    IL_000f:  ldstr      \"d\"\n    IL_0014:  leave.s    IL_0016\n\n    IL_0016:  ldarg.0\n    IL_0017:  ldlen\n    IL_0018:  conv.i4\n    IL_0019:  brfalse.s  IL_0020\n\n    IL_001b:  ldarg.0\n    IL_001c:  ldc.i4.0\n    IL_001d:  ldelem.ref\n    IL_001e:  br.s       IL_0025\n\n    IL_0020:  ldstr      \"dummy\"\n    IL_0025:  dup\n    IL_0026:  stloc.0\n    IL_0027:  brfalse.s  IL_0082\n\n    IL_0029:  ldloc.0\n    IL_002a:  call       string [mscorlib]System.String::IsInterned(string)\n    IL_002f:  stloc.0\n    IL_0030:  ldloc.0\n    IL_0031:  ldstr      \"a\"\n    IL_0036:  beq.s      IL_0052\n\n    IL_0038:  ldloc.0\n    IL_0039:  ldstr      \"b\"\n    IL_003e:  beq.s      IL_005e\n\n    IL_0040:  ldloc.0\n    IL_0041:  ldstr      \"c\"\n    IL_0046:  beq.s      IL_006a\n\n    IL_0048:  ldloc.0\n    IL_0049:  ldstr      \"d\"\n    IL_004e:  beq.s      IL_0076\n\n    IL_0050:  br.s       IL_0082\n\n    IL_0052:  ldstr      \"a\"\n    IL_0057:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_005c:  br.s       IL_0082\n\n    IL_005e:  ldstr      \"b\"\n    IL_0063:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0068:  br.s       IL_0082\n\n    IL_006a:  ldstr      \"c\"\n    IL_006f:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0074:  br.s       IL_0082\n\n    IL_0076:  ldstr      \"d\"\n    IL_007b:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0080:  br.s       IL_0082\n\n    IL_0082:  ldstr      \"end\"\n    IL_0087:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_008c:  ret\n  } // end of method Switch::SwitchWithComplexCondition\n\n  .method public hidebysig static void  SwitchWithArray(string[] args) cil managed\n  {\n    // Code size       129 (0x81)\n    .maxstack  4\n    .locals init (string V_0)\n    IL_0000:  ldstr      \"a\"\n    IL_0005:  ldstr      \"b\"\n    IL_000a:  ldstr      \"c\"\n    IL_000f:  ldstr      \"d\"\n    IL_0014:  leave.s    IL_0016\n\n    IL_0016:  ldarg.0\n    IL_0017:  ldc.i4.0\n    IL_0018:  ldelem.ref\n    IL_0019:  dup\n    IL_001a:  stloc.0\n    IL_001b:  brfalse.s  IL_0076\n\n    IL_001d:  ldloc.0\n    IL_001e:  call       string [mscorlib]System.String::IsInterned(string)\n    IL_0023:  stloc.0\n    IL_0024:  ldloc.0\n    IL_0025:  ldstr      \"a\"\n    IL_002a:  beq.s      IL_0046\n\n    IL_002c:  ldloc.0\n    IL_002d:  ldstr      \"b\"\n    IL_0032:  beq.s      IL_0052\n\n    IL_0034:  ldloc.0\n    IL_0035:  ldstr      \"c\"\n    IL_003a:  beq.s      IL_005e\n\n    IL_003c:  ldloc.0\n    IL_003d:  ldstr      \"d\"\n    IL_0042:  beq.s      IL_006a\n\n    IL_0044:  br.s       IL_0076\n\n    IL_0046:  ldstr      \"a\"\n    IL_004b:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0050:  br.s       IL_0076\n\n    IL_0052:  ldstr      \"b\"\n    IL_0057:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_005c:  br.s       IL_0076\n\n    IL_005e:  ldstr      \"c\"\n    IL_0063:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0068:  br.s       IL_0076\n\n    IL_006a:  ldstr      \"d\"\n    IL_006f:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0074:  br.s       IL_0076\n\n    IL_0076:  ldstr      \"end\"\n    IL_007b:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0080:  ret\n  } // end of method Switch::SwitchWithArray\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  1\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method Switch::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch\n\n.class private auto ansi '<PrivateImplementationDetails>'\n       extends [mscorlib]System.Object\n{\n  .field static assembly class [mscorlib]System.Collections.Hashtable '$$method0x6000006-1'\n  .field static assembly class [mscorlib]System.Collections.Hashtable '$$method0x6000007-1'\n  .field static assembly class [mscorlib]System.Collections.Hashtable '$$method0x6000007-2'\n} // end of class '<PrivateImplementationDetails>'\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n// WARNING: Created Win32 resource file C:\\Users\\Siegfried\\Projects\\ILSpy master\\ICSharpCode.Decompiler.Tests\\TestCases\\ILPretty\\CS1xSwitch_Debug.res\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/CS1xSwitch_Release.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections;\nusing System.Reflection;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class Switch\n\t{\n\t\tpublic class SetProperty\n\t\t{\n\t\t\tpublic readonly PropertyInfo Property;\n\t\t\tprivate int _set;\n\n\t\t\tpublic int Set {\n\t\t\t\tget {\n\t\t\t\t\treturn _set;\n\t\t\t\t}\n\n\t\t\t\tset {\n\t\t\t\t\t_set = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic SetProperty(PropertyInfo property)\n\t\t\t{\n\t\t\t\tProperty = property;\n\t\t\t}\n\t\t}\n\n\t\tpublic enum State\n\t\t{\n\t\t\tFalse,\n\t\t\tTrue,\n\t\t\tNull\n\t\t}\n\n\t\tpublic static string SparseIntegerSwitch(int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"SparseIntegerSwitch: \" + i);\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase -10000000:\n\t\t\t\t\treturn \"-10 mln\";\n\t\t\t\tcase -100:\n\t\t\t\t\treturn \"-hundred\";\n\t\t\t\tcase -1:\n\t\t\t\t\treturn \"-1\";\n\t\t\t\tcase 0:\n\t\t\t\t\treturn \"0\";\n\t\t\t\tcase 1:\n\t\t\t\t\treturn \"1\";\n\t\t\t\tcase 2:\n\t\t\t\t\treturn \"2\";\n\t\t\t\tcase 4:\n\t\t\t\t\treturn \"4\";\n\t\t\t\tcase 100:\n\t\t\t\t\treturn \"hundred\";\n\t\t\t\tcase 10000:\n\t\t\t\t\treturn \"ten thousand\";\n\t\t\t\tcase 10001:\n\t\t\t\t\treturn \"ten thousand and one\";\n\t\t\t\tcase int.MaxValue:\n\t\t\t\t\treturn \"int.MaxValue\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"something else\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SwitchOverInt(int i)\n\t\t{\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tConsole.WriteLine(\"zero\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 5:\n\t\t\t\t\tConsole.WriteLine(\"five\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 10:\n\t\t\t\t\tConsole.WriteLine(\"ten\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 15:\n\t\t\t\t\tConsole.WriteLine(\"fifteen\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 20:\n\t\t\t\t\tConsole.WriteLine(\"twenty\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 25:\n\t\t\t\t\tConsole.WriteLine(\"twenty-five\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 30:\n\t\t\t\t\tConsole.WriteLine(\"thirty\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic static string ShortSwitchOverString(string text)\n\t\t{\n\t\t\tConsole.WriteLine(\"ShortSwitchOverString: \" + text);\n\t\t\tswitch (text)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase \"Third case\":\n\t\t\t\t\treturn \"Text3\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string ShortSwitchOverStringWithNullCase(string text)\n\t\t{\n\t\t\tConsole.WriteLine(\"ShortSwitchOverStringWithNullCase: \" + text);\n\t\t\tswitch (text)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase null:\n\t\t\t\t\treturn \"null\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverString1(string text)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchOverString1: \" + text);\n\t\t\tswitch (text)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\tcase \"2nd case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase \"Third case\":\n\t\t\t\t\treturn \"Text3\";\n\t\t\t\tcase \"Fourth case\":\n\t\t\t\t\treturn \"Text4\";\n\t\t\t\tcase \"Fifth case\":\n\t\t\t\t\treturn \"Text5\";\n\t\t\t\tcase \"Sixth case\":\n\t\t\t\t\treturn \"Text6\";\n\t\t\t\tcase null:\n\t\t\t\t\treturn null;\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverString2()\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchOverString2:\");\n\t\t\tswitch (Environment.UserName)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase \"Third case\":\n\t\t\t\t\treturn \"Text3\";\n\t\t\t\tcase \"Fourth case\":\n\t\t\t\t\treturn \"Text4\";\n\t\t\t\tcase \"Fifth case\":\n\t\t\t\t\treturn \"Text5\";\n\t\t\t\tcase \"Sixth case\":\n\t\t\t\t\treturn \"Text6\";\n\t\t\t\tcase \"Seventh case\":\n\t\t\t\t\treturn \"Text7\";\n\t\t\t\tcase \"Eighth case\":\n\t\t\t\t\treturn \"Text8\";\n\t\t\t\tcase \"Ninth case\":\n\t\t\t\t\treturn \"Text9\";\n\t\t\t\tcase \"Tenth case\":\n\t\t\t\t\treturn \"Text10\";\n\t\t\t\tcase \"Eleventh case\":\n\t\t\t\t\treturn \"Text11\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string TwoDifferentSwitchBlocksInTryFinally()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"TwoDifferentSwitchBlocks:\");\n\t\t\t\tswitch (Environment.UserName)\n\t\t\t\t{\n\t\t\t\t\tcase \"First case\":\n\t\t\t\t\t\treturn \"Text1\";\n\t\t\t\t\tcase \"Second case\":\n\t\t\t\t\t\treturn \"Text2\";\n\t\t\t\t\tcase \"Third case\":\n\t\t\t\t\t\treturn \"Text3\";\n\t\t\t\t\tcase \"Fourth case\":\n\t\t\t\t\t\treturn \"Text4\";\n\t\t\t\t\tcase \"Fifth case\":\n\t\t\t\t\t\treturn \"Text5\";\n\t\t\t\t\tcase \"Sixth case\":\n\t\t\t\t\t\treturn \"Text6\";\n\t\t\t\t\tcase \"Seventh case\":\n\t\t\t\t\t\treturn \"Text7\";\n\t\t\t\t\tcase \"Eighth case\":\n\t\t\t\t\t\treturn \"Text8\";\n\t\t\t\t\tcase \"Ninth case\":\n\t\t\t\t\t\treturn \"Text9\";\n\t\t\t\t\tcase \"Tenth case\":\n\t\t\t\t\t\treturn \"Text10\";\n\t\t\t\t\tcase \"Eleventh case\":\n\t\t\t\t\t\treturn \"Text11\";\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn \"Default\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Second switch:\");\n\t\t\t\tswitch (Console.ReadLine())\n\t\t\t\t{\n\t\t\t\t\tcase \"12\":\n\t\t\t\t\t\tConsole.WriteLine(\"Te43234xt1\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"13\":\n\t\t\t\t\t\tConsole.WriteLine(\"Te223443xt2\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"14\":\n\t\t\t\t\t\tConsole.WriteLine(\"Te234xt3\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"15\":\n\t\t\t\t\t\tConsole.WriteLine(\"Tex243t4\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"16\":\n\t\t\t\t\t\tConsole.WriteLine(\"Tex243t5\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"17\":\n\t\t\t\t\t\tConsole.WriteLine(\"Text2346\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"18\":\n\t\t\t\t\t\tConsole.WriteLine(\"Text234234\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"19 case\":\n\t\t\t\t\t\tConsole.WriteLine(\"Text8234\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"20 case\":\n\t\t\t\t\t\tConsole.WriteLine(\"Text923423\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"21 case\":\n\t\t\t\t\t\tConsole.WriteLine(\"Text10\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"22 case\":\n\t\t\t\t\t\tConsole.WriteLine(\"Text1134123\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tConsole.WriteLine(\"Defa234234ult\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverBool(bool b)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchOverBool: \" + b);\n\t\t\tswitch (b)\n\t\t\t{\n\t\t\t\tcase true:\n\t\t\t\t\treturn bool.TrueString;\n\t\t\t\tcase false:\n\t\t\t\t\treturn bool.FalseString;\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SwitchInLoop(int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchInLoop: \" + i);\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tswitch (i)\n\t\t\t\t{\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tConsole.WriteLine(\"one\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tConsole.WriteLine(\"two\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t//case 3:\n\t\t\t\t\t//\t\tConsole.WriteLine(\"three\");\n\t\t\t\t\t//\t\tcontinue;\n\t\t\t\t\tcase 4:\n\t\t\t\t\t\tConsole.WriteLine(\"four\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t\t\t\tConsole.WriteLine(\"more code\");\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SwitchWithGoto(int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchWithGoto: \" + i);\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase 1:\n\t\t\t\t\tConsole.WriteLine(\"one\");\n\t\t\t\t\tgoto default;\n\t\t\t\tcase 2:\n\t\t\t\t\tConsole.WriteLine(\"two\");\n\t\t\t\t\tgoto case 3;\n\t\t\t\tcase 3:\n\t\t\t\t\tConsole.WriteLine(\"three\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 4:\n\t\t\t\t\tConsole.WriteLine(\"four\");\n\t\t\t\t\treturn;\n\t\t\t\tdefault:\n\t\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"End of method\");\n\t\t}\n\n\t\tprivate static SetProperty[] GetProperties()\n\t\t{\n\t\t\treturn new SetProperty[0];\n\t\t}\n\n\t\tpublic static void SwitchOnStringInForLoop()\n\t\t{\n\t\t\tArrayList arrayList = new ArrayList();\n\t\t\tArrayList arrayList2 = new ArrayList();\n\t\t\tSetProperty[] properties = GetProperties();\n\t\t\tfor (int i = 0; i < properties.Length; i++)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"In for-loop\");\n\t\t\t\tSetProperty setProperty = properties[i];\n\t\t\t\tswitch (setProperty.Property.Name)\n\t\t\t\t{\n\t\t\t\t\tcase \"Name1\":\n\t\t\t\t\t\tsetProperty.Set = 1;\n\t\t\t\t\t\tarrayList.Add(setProperty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Name2\":\n\t\t\t\t\t\tsetProperty.Set = 2;\n\t\t\t\t\t\tarrayList.Add(setProperty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Name3\":\n\t\t\t\t\t\tsetProperty.Set = 3;\n\t\t\t\t\t\tarrayList.Add(setProperty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Name4\":\n\t\t\t\t\t\tsetProperty.Set = 4;\n\t\t\t\t\t\tarrayList.Add(setProperty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Name5\":\n\t\t\t\t\tcase \"Name6\":\n\t\t\t\t\t\tarrayList.Add(setProperty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tarrayList2.Add(setProperty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SwitchWithComplexCondition(string[] args)\n\t\t{\n\t\t\tswitch ((args.Length == 0) ? \"dummy\" : args[0])\n\t\t\t{\n\t\t\t\tcase \"a\":\n\t\t\t\t\tConsole.WriteLine(\"a\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"b\":\n\t\t\t\t\tConsole.WriteLine(\"b\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"c\":\n\t\t\t\t\tConsole.WriteLine(\"c\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"d\":\n\t\t\t\t\tConsole.WriteLine(\"d\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\n\t\tpublic static void SwitchWithArray(string[] args)\n\t\t{\n\t\t\tswitch (args[0])\n\t\t\t{\n\t\t\t\tcase \"a\":\n\t\t\t\t\tConsole.WriteLine(\"a\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"b\":\n\t\t\t\t\tConsole.WriteLine(\"b\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"c\":\n\t\t\t\t\tConsole.WriteLine(\"c\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"d\":\n\t\t\t\t\tConsole.WriteLine(\"d\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/CS1xSwitch_Release.il",
    "content": "\n//  Microsoft (R) .NET Framework IL Disassembler.  Version 4.6.1055.0\n//  Copyright (c) Microsoft Corporation.  All rights reserved.\n\n\n\n// Metadata version: v1.1.4322\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 1:0:5000:0\n}\n.assembly CS1xSwitch_Release\n{\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module CS1xSwitch_Release.dll\n// MVID: {E26201E5-5EC1-412E-BE6D-AE48AFAE6535}\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n// Image base: 0x07560000\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch\n       extends [mscorlib]System.Object\n{\n  .class auto ansi nested public beforefieldinit SetProperty\n         extends [mscorlib]System.Object\n  {\n    .field public initonly class [mscorlib]System.Reflection.PropertyInfo Property\n    .field private int32 _set\n    .method public hidebysig specialname \n            instance int32  get_Set() cil managed\n    {\n      // Code size       7 (0x7)\n      .maxstack  1\n      IL_0000:  ldarg.0\n      IL_0001:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::_set\n      IL_0006:  ret\n    } // end of method SetProperty::get_Set\n\n    .method public hidebysig specialname \n            instance void  set_Set(int32 'value') cil managed\n    {\n      // Code size       8 (0x8)\n      .maxstack  2\n      IL_0000:  ldarg.0\n      IL_0001:  ldarg.1\n      IL_0002:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::_set\n      IL_0007:  ret\n    } // end of method SetProperty::set_Set\n\n    .method public hidebysig specialname rtspecialname \n            instance void  .ctor(class [mscorlib]System.Reflection.PropertyInfo 'property') cil managed\n    {\n      // Code size       14 (0xe)\n      .maxstack  2\n      IL_0000:  ldarg.0\n      IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n      IL_0006:  ldarg.0\n      IL_0007:  ldarg.1\n      IL_0008:  stfld      class [mscorlib]System.Reflection.PropertyInfo ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::Property\n      IL_000d:  ret\n    } // end of method SetProperty::.ctor\n\n    .property instance int32 Set()\n    {\n      .get instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::get_Set()\n      .set instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::set_Set(int32)\n    } // end of property SetProperty::Set\n  } // end of class SetProperty\n\n  .class auto ansi sealed nested public State\n         extends [mscorlib]System.Enum\n  {\n    .field public specialname rtspecialname int32 value__\n    .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State False = int32(0x00000000)\n    .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State True = int32(0x00000001)\n    .field public static literal valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/State Null = int32(0x00000002)\n  } // end of class State\n\n  .method public hidebysig static string \n          SparseIntegerSwitch(int32 i) cil managed\n  {\n    // Code size       181 (0xb5)\n    .maxstack  2\n    .locals init (int32 V_0)\n    IL_0000:  ldstr      \"SparseIntegerSwitch: \"\n    IL_0005:  ldarg.0\n    IL_0006:  box        [mscorlib]System.Int32\n    IL_000b:  call       string [mscorlib]System.String::Concat(object,\n                                                                object)\n    IL_0010:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0015:  ldarg.0\n    IL_0016:  stloc.0\n    IL_0017:  ldloc.0\n    IL_0018:  ldc.i4.4\n    IL_0019:  bgt.s      IL_004a\n\n    IL_001b:  ldloc.0\n    IL_001c:  ldc.i4     0xff676980\n    IL_0021:  beq.s      IL_006d\n\n    IL_0023:  ldloc.0\n    IL_0024:  ldc.i4.s   -100\n    IL_0026:  beq.s      IL_0073\n\n    IL_0028:  ldloc.0\n    IL_0029:  ldc.i4.m1\n    IL_002a:  sub\n    IL_002b:  switch     ( \n                          IL_0079,\n                          IL_007f,\n                          IL_0085,\n                          IL_008b,\n                          IL_00af,\n                          IL_0091)\n    IL_0048:  br.s       IL_00af\n\n    IL_004a:  ldloc.0\n    IL_004b:  ldc.i4.s   100\n    IL_004d:  beq.s      IL_0097\n\n    IL_004f:  ldloc.0\n    IL_0050:  ldc.i4     0x2710\n    IL_0055:  sub\n    IL_0056:  switch     ( \n                          IL_009d,\n                          IL_00a3)\n    IL_0063:  ldloc.0\n    IL_0064:  ldc.i4     0x7fffffff\n    IL_0069:  beq.s      IL_00a9\n\n    IL_006b:  br.s       IL_00af\n\n    IL_006d:  ldstr      \"-10 mln\"\n    IL_0072:  ret\n\n    IL_0073:  ldstr      \"-hundred\"\n    IL_0078:  ret\n\n    IL_0079:  ldstr      \"-1\"\n    IL_007e:  ret\n\n    IL_007f:  ldstr      \"0\"\n    IL_0084:  ret\n\n    IL_0085:  ldstr      \"1\"\n    IL_008a:  ret\n\n    IL_008b:  ldstr      \"2\"\n    IL_0090:  ret\n\n    IL_0091:  ldstr      \"4\"\n    IL_0096:  ret\n\n    IL_0097:  ldstr      \"hundred\"\n    IL_009c:  ret\n\n    IL_009d:  ldstr      \"ten thousand\"\n    IL_00a2:  ret\n\n    IL_00a3:  ldstr      \"ten thousand and one\"\n    IL_00a8:  ret\n\n    IL_00a9:  ldstr      \"int.MaxValue\"\n    IL_00ae:  ret\n\n    IL_00af:  ldstr      \"something else\"\n    IL_00b4:  ret\n  } // end of method Switch::SparseIntegerSwitch\n\n  .method public hidebysig static void  SwitchOverInt(int32 i) cil managed\n  {\n    // Code size       125 (0x7d)\n    .maxstack  2\n    .locals init (int32 V_0)\n    IL_0000:  ldarg.0\n    IL_0001:  stloc.0\n    IL_0002:  ldloc.0\n    IL_0003:  ldc.i4.s   10\n    IL_0005:  bgt.s      IL_0015\n\n    IL_0007:  ldloc.0\n    IL_0008:  ldc.i4.0\n    IL_0009:  beq.s      IL_0030\n\n    IL_000b:  ldloc.0\n    IL_000c:  ldc.i4.5\n    IL_000d:  beq.s      IL_003b\n\n    IL_000f:  ldloc.0\n    IL_0010:  ldc.i4.s   10\n    IL_0012:  beq.s      IL_0046\n\n    IL_0014:  ret\n\n    IL_0015:  ldloc.0\n    IL_0016:  ldc.i4.s   20\n    IL_0018:  bgt.s      IL_0025\n\n    IL_001a:  ldloc.0\n    IL_001b:  ldc.i4.s   15\n    IL_001d:  beq.s      IL_0051\n\n    IL_001f:  ldloc.0\n    IL_0020:  ldc.i4.s   20\n    IL_0022:  beq.s      IL_005c\n\n    IL_0024:  ret\n\n    IL_0025:  ldloc.0\n    IL_0026:  ldc.i4.s   25\n    IL_0028:  beq.s      IL_0067\n\n    IL_002a:  ldloc.0\n    IL_002b:  ldc.i4.s   30\n    IL_002d:  beq.s      IL_0072\n\n    IL_002f:  ret\n\n    IL_0030:  ldstr      \"zero\"\n    IL_0035:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_003a:  ret\n\n    IL_003b:  ldstr      \"five\"\n    IL_0040:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0045:  ret\n\n    IL_0046:  ldstr      \"ten\"\n    IL_004b:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0050:  ret\n\n    IL_0051:  ldstr      \"fifteen\"\n    IL_0056:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_005b:  ret\n\n    IL_005c:  ldstr      \"twenty\"\n    IL_0061:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0066:  ret\n\n    IL_0067:  ldstr      \"twenty-five\"\n    IL_006c:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0071:  ret\n\n    IL_0072:  ldstr      \"thirty\"\n    IL_0077:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_007c:  ret\n  } // end of method Switch::SwitchOverInt\n\n  .method public hidebysig static string \n          ShortSwitchOverString(string text) cil managed\n  {\n    // Code size       95 (0x5f)\n    .maxstack  3\n    .locals init (string V_0)\n    IL_0000:  ldstr      \"ShortSwitchOverString: \"\n    IL_0005:  ldarg.0\n    IL_0006:  call       string [mscorlib]System.String::Concat(string,\n                                                                string)\n    IL_000b:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0010:  ldstr      \"First case\"\n    IL_0015:  ldstr      \"Second case\"\n    IL_001a:  ldstr      \"Third case\"\n    IL_001f:  leave.s    IL_0021\n\n    IL_0021:  ldarg.0\n    IL_0022:  dup\n    IL_0023:  stloc.0\n    IL_0024:  brfalse.s  IL_0059\n\n    IL_0026:  ldloc.0\n    IL_0027:  call       string [mscorlib]System.String::IsInterned(string)\n    IL_002c:  stloc.0\n    IL_002d:  ldloc.0\n    IL_002e:  ldstr      \"First case\"\n    IL_0033:  beq.s      IL_0047\n\n    IL_0035:  ldloc.0\n    IL_0036:  ldstr      \"Second case\"\n    IL_003b:  beq.s      IL_004d\n\n    IL_003d:  ldloc.0\n    IL_003e:  ldstr      \"Third case\"\n    IL_0043:  beq.s      IL_0053\n\n    IL_0045:  br.s       IL_0059\n\n    IL_0047:  ldstr      \"Text1\"\n    IL_004c:  ret\n\n    IL_004d:  ldstr      \"Text2\"\n    IL_0052:  ret\n\n    IL_0053:  ldstr      \"Text3\"\n    IL_0058:  ret\n\n    IL_0059:  ldstr      \"Default\"\n    IL_005e:  ret\n  } // end of method Switch::ShortSwitchOverString\n\n  .method public hidebysig static string \n          ShortSwitchOverStringWithNullCase(string text) cil managed\n  {\n    // Code size       82 (0x52)\n    .maxstack  2\n    .locals init (string V_0)\n    IL_0000:  ldstr      \"ShortSwitchOverStringWithNullCase: \"\n    IL_0005:  ldarg.0\n    IL_0006:  call       string [mscorlib]System.String::Concat(string,\n                                                                string)\n    IL_000b:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0010:  ldstr      \"First case\"\n    IL_0015:  ldstr      \"Second case\"\n    IL_001a:  leave.s    IL_001c\n\n    IL_001c:  ldarg.0\n    IL_001d:  dup\n    IL_001e:  stloc.0\n    IL_001f:  brfalse.s  IL_0046\n\n    IL_0021:  ldloc.0\n    IL_0022:  call       string [mscorlib]System.String::IsInterned(string)\n    IL_0027:  stloc.0\n    IL_0028:  ldloc.0\n    IL_0029:  ldstr      \"First case\"\n    IL_002e:  beq.s      IL_003a\n\n    IL_0030:  ldloc.0\n    IL_0031:  ldstr      \"Second case\"\n    IL_0036:  beq.s      IL_0040\n\n    IL_0038:  br.s       IL_004c\n\n    IL_003a:  ldstr      \"Text1\"\n    IL_003f:  ret\n\n    IL_0040:  ldstr      \"Text2\"\n    IL_0045:  ret\n\n    IL_0046:  ldstr      \"null\"\n    IL_004b:  ret\n\n    IL_004c:  ldstr      \"Default\"\n    IL_0051:  ret\n  } // end of method Switch::ShortSwitchOverStringWithNullCase\n\n  .method public hidebysig static string \n          SwitchOverString1(string text) cil managed\n  {\n    // Code size       167 (0xa7)\n    .maxstack  7\n    .locals init (string V_0)\n    IL_0000:  ldstr      \"SwitchOverString1: \"\n    IL_0005:  ldarg.0\n    IL_0006:  call       string [mscorlib]System.String::Concat(string,\n                                                                string)\n    IL_000b:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0010:  ldstr      \"First case\"\n    IL_0015:  ldstr      \"Second case\"\n    IL_001a:  ldstr      \"2nd case\"\n    IL_001f:  ldstr      \"Third case\"\n    IL_0024:  ldstr      \"Fourth case\"\n    IL_0029:  ldstr      \"Fifth case\"\n    IL_002e:  ldstr      \"Sixth case\"\n    IL_0033:  leave.s    IL_0035\n\n    IL_0035:  ldarg.0\n    IL_0036:  dup\n    IL_0037:  stloc.0\n    IL_0038:  brfalse.s  IL_009f\n\n    IL_003a:  ldloc.0\n    IL_003b:  call       string [mscorlib]System.String::IsInterned(string)\n    IL_0040:  stloc.0\n    IL_0041:  ldloc.0\n    IL_0042:  ldstr      \"First case\"\n    IL_0047:  beq.s      IL_007b\n\n    IL_0049:  ldloc.0\n    IL_004a:  ldstr      \"Second case\"\n    IL_004f:  beq.s      IL_0081\n\n    IL_0051:  ldloc.0\n    IL_0052:  ldstr      \"2nd case\"\n    IL_0057:  beq.s      IL_0081\n\n    IL_0059:  ldloc.0\n    IL_005a:  ldstr      \"Third case\"\n    IL_005f:  beq.s      IL_0087\n\n    IL_0061:  ldloc.0\n    IL_0062:  ldstr      \"Fourth case\"\n    IL_0067:  beq.s      IL_008d\n\n    IL_0069:  ldloc.0\n    IL_006a:  ldstr      \"Fifth case\"\n    IL_006f:  beq.s      IL_0093\n\n    IL_0071:  ldloc.0\n    IL_0072:  ldstr      \"Sixth case\"\n    IL_0077:  beq.s      IL_0099\n\n    IL_0079:  br.s       IL_00a1\n\n    IL_007b:  ldstr      \"Text1\"\n    IL_0080:  ret\n\n    IL_0081:  ldstr      \"Text2\"\n    IL_0086:  ret\n\n    IL_0087:  ldstr      \"Text3\"\n    IL_008c:  ret\n\n    IL_008d:  ldstr      \"Text4\"\n    IL_0092:  ret\n\n    IL_0093:  ldstr      \"Text5\"\n    IL_0098:  ret\n\n    IL_0099:  ldstr      \"Text6\"\n    IL_009e:  ret\n\n    IL_009f:  ldnull\n    IL_00a0:  ret\n\n    IL_00a1:  ldstr      \"Default\"\n    IL_00a6:  ret\n  } // end of method Switch::SwitchOverString1\n\n  .method public hidebysig static string \n          SwitchOverString2() cil managed\n  {\n    // Code size       389 (0x185)\n    .maxstack  4\n    .locals init (object V_0)\n    IL_0000:  volatile.\n    IL_0002:  ldsfld     class [mscorlib]System.Collections.Hashtable '<PrivateImplementationDetails>'::'$$method0x6000006-1'\n    IL_0007:  brtrue     IL_00dc\n\n    IL_000c:  ldc.i4.s   24\n    IL_000e:  ldc.r4     0.5\n    IL_0013:  newobj     instance void [mscorlib]System.Collections.Hashtable::.ctor(int32,\n                                                                                     float32)\n    IL_0018:  dup\n    IL_0019:  ldstr      \"First case\"\n    IL_001e:  ldc.i4.0\n    IL_001f:  box        [mscorlib]System.Int32\n    IL_0024:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_0029:  dup\n    IL_002a:  ldstr      \"Second case\"\n    IL_002f:  ldc.i4.1\n    IL_0030:  box        [mscorlib]System.Int32\n    IL_0035:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_003a:  dup\n    IL_003b:  ldstr      \"Third case\"\n    IL_0040:  ldc.i4.2\n    IL_0041:  box        [mscorlib]System.Int32\n    IL_0046:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_004b:  dup\n    IL_004c:  ldstr      \"Fourth case\"\n    IL_0051:  ldc.i4.3\n    IL_0052:  box        [mscorlib]System.Int32\n    IL_0057:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_005c:  dup\n    IL_005d:  ldstr      \"Fifth case\"\n    IL_0062:  ldc.i4.4\n    IL_0063:  box        [mscorlib]System.Int32\n    IL_0068:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_006d:  dup\n    IL_006e:  ldstr      \"Sixth case\"\n    IL_0073:  ldc.i4.5\n    IL_0074:  box        [mscorlib]System.Int32\n    IL_0079:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_007e:  dup\n    IL_007f:  ldstr      \"Seventh case\"\n    IL_0084:  ldc.i4.6\n    IL_0085:  box        [mscorlib]System.Int32\n    IL_008a:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_008f:  dup\n    IL_0090:  ldstr      \"Eighth case\"\n    IL_0095:  ldc.i4.7\n    IL_0096:  box        [mscorlib]System.Int32\n    IL_009b:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_00a0:  dup\n    IL_00a1:  ldstr      \"Ninth case\"\n    IL_00a6:  ldc.i4.8\n    IL_00a7:  box        [mscorlib]System.Int32\n    IL_00ac:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_00b1:  dup\n    IL_00b2:  ldstr      \"Tenth case\"\n    IL_00b7:  ldc.i4.s   9\n    IL_00b9:  box        [mscorlib]System.Int32\n    IL_00be:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_00c3:  dup\n    IL_00c4:  ldstr      \"Eleventh case\"\n    IL_00c9:  ldc.i4.s   10\n    IL_00cb:  box        [mscorlib]System.Int32\n    IL_00d0:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_00d5:  volatile.\n    IL_00d7:  stsfld     class [mscorlib]System.Collections.Hashtable '<PrivateImplementationDetails>'::'$$method0x6000006-1'\n    IL_00dc:  ldstr      \"SwitchOverString2:\"\n    IL_00e1:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_00e6:  call       string [mscorlib]System.Environment::get_UserName()\n    IL_00eb:  dup\n    IL_00ec:  stloc.0\n    IL_00ed:  brfalse    IL_017f\n\n    IL_00f2:  volatile.\n    IL_00f4:  ldsfld     class [mscorlib]System.Collections.Hashtable '<PrivateImplementationDetails>'::'$$method0x6000006-1'\n    IL_00f9:  ldloc.0\n    IL_00fa:  call       instance object [mscorlib]System.Collections.Hashtable::get_Item(object)\n    IL_00ff:  dup\n    IL_0100:  stloc.0\n    IL_0101:  brfalse.s  IL_017f\n\n    IL_0103:  ldloc.0\n    IL_0104:  unbox      [mscorlib]System.Int32\n    IL_0109:  ldind.i4\n    IL_010a:  switch     ( \n                          IL_013d,\n                          IL_0143,\n                          IL_0149,\n                          IL_014f,\n                          IL_0155,\n                          IL_015b,\n                          IL_0161,\n                          IL_0167,\n                          IL_016d,\n                          IL_0173,\n                          IL_0179)\n    IL_013b:  br.s       IL_017f\n\n    IL_013d:  ldstr      \"Text1\"\n    IL_0142:  ret\n\n    IL_0143:  ldstr      \"Text2\"\n    IL_0148:  ret\n\n    IL_0149:  ldstr      \"Text3\"\n    IL_014e:  ret\n\n    IL_014f:  ldstr      \"Text4\"\n    IL_0154:  ret\n\n    IL_0155:  ldstr      \"Text5\"\n    IL_015a:  ret\n\n    IL_015b:  ldstr      \"Text6\"\n    IL_0160:  ret\n\n    IL_0161:  ldstr      \"Text7\"\n    IL_0166:  ret\n\n    IL_0167:  ldstr      \"Text8\"\n    IL_016c:  ret\n\n    IL_016d:  ldstr      \"Text9\"\n    IL_0172:  ret\n\n    IL_0173:  ldstr      \"Text10\"\n    IL_0178:  ret\n\n    IL_0179:  ldstr      \"Text11\"\n    IL_017e:  ret\n\n    IL_017f:  ldstr      \"Default\"\n    IL_0184:  ret\n  } // end of method Switch::SwitchOverString2\n\n  .method public hidebysig static string \n          TwoDifferentSwitchBlocksInTryFinally() cil managed\n  {\n    // Code size       923 (0x39b)\n    .maxstack  4\n    .locals init (string V_0,\n             object V_1)\n    IL_0000:  volatile.\n    IL_0002:  ldsfld     class [mscorlib]System.Collections.Hashtable '<PrivateImplementationDetails>'::'$$method0x6000007-1'\n    IL_0007:  brtrue     IL_01b8\n\n    IL_000c:  ldc.i4.s   24\n    IL_000e:  ldc.r4     0.5\n    IL_0013:  newobj     instance void [mscorlib]System.Collections.Hashtable::.ctor(int32,\n                                                                                     float32)\n    IL_0018:  dup\n    IL_0019:  ldstr      \"12\"\n    IL_001e:  ldc.i4.0\n    IL_001f:  box        [mscorlib]System.Int32\n    IL_0024:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_0029:  dup\n    IL_002a:  ldstr      \"13\"\n    IL_002f:  ldc.i4.1\n    IL_0030:  box        [mscorlib]System.Int32\n    IL_0035:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_003a:  dup\n    IL_003b:  ldstr      \"14\"\n    IL_0040:  ldc.i4.2\n    IL_0041:  box        [mscorlib]System.Int32\n    IL_0046:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_004b:  dup\n    IL_004c:  ldstr      \"15\"\n    IL_0051:  ldc.i4.3\n    IL_0052:  box        [mscorlib]System.Int32\n    IL_0057:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_005c:  dup\n    IL_005d:  ldstr      \"16\"\n    IL_0062:  ldc.i4.4\n    IL_0063:  box        [mscorlib]System.Int32\n    IL_0068:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_006d:  dup\n    IL_006e:  ldstr      \"17\"\n    IL_0073:  ldc.i4.5\n    IL_0074:  box        [mscorlib]System.Int32\n    IL_0079:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_007e:  dup\n    IL_007f:  ldstr      \"18\"\n    IL_0084:  ldc.i4.6\n    IL_0085:  box        [mscorlib]System.Int32\n    IL_008a:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_008f:  dup\n    IL_0090:  ldstr      \"19 case\"\n    IL_0095:  ldc.i4.7\n    IL_0096:  box        [mscorlib]System.Int32\n    IL_009b:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_00a0:  dup\n    IL_00a1:  ldstr      \"20 case\"\n    IL_00a6:  ldc.i4.8\n    IL_00a7:  box        [mscorlib]System.Int32\n    IL_00ac:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_00b1:  dup\n    IL_00b2:  ldstr      \"21 case\"\n    IL_00b7:  ldc.i4.s   9\n    IL_00b9:  box        [mscorlib]System.Int32\n    IL_00be:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_00c3:  dup\n    IL_00c4:  ldstr      \"22 case\"\n    IL_00c9:  ldc.i4.s   10\n    IL_00cb:  box        [mscorlib]System.Int32\n    IL_00d0:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_00d5:  volatile.\n    IL_00d7:  stsfld     class [mscorlib]System.Collections.Hashtable '<PrivateImplementationDetails>'::'$$method0x6000007-1'\n    IL_00dc:  volatile.\n    IL_00de:  ldsfld     class [mscorlib]System.Collections.Hashtable '<PrivateImplementationDetails>'::'$$method0x6000007-2'\n    IL_00e3:  brtrue     IL_01b8\n\n    IL_00e8:  ldc.i4.s   24\n    IL_00ea:  ldc.r4     0.5\n    IL_00ef:  newobj     instance void [mscorlib]System.Collections.Hashtable::.ctor(int32,\n                                                                                     float32)\n    IL_00f4:  dup\n    IL_00f5:  ldstr      \"First case\"\n    IL_00fa:  ldc.i4.0\n    IL_00fb:  box        [mscorlib]System.Int32\n    IL_0100:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_0105:  dup\n    IL_0106:  ldstr      \"Second case\"\n    IL_010b:  ldc.i4.1\n    IL_010c:  box        [mscorlib]System.Int32\n    IL_0111:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_0116:  dup\n    IL_0117:  ldstr      \"Third case\"\n    IL_011c:  ldc.i4.2\n    IL_011d:  box        [mscorlib]System.Int32\n    IL_0122:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_0127:  dup\n    IL_0128:  ldstr      \"Fourth case\"\n    IL_012d:  ldc.i4.3\n    IL_012e:  box        [mscorlib]System.Int32\n    IL_0133:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_0138:  dup\n    IL_0139:  ldstr      \"Fifth case\"\n    IL_013e:  ldc.i4.4\n    IL_013f:  box        [mscorlib]System.Int32\n    IL_0144:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_0149:  dup\n    IL_014a:  ldstr      \"Sixth case\"\n    IL_014f:  ldc.i4.5\n    IL_0150:  box        [mscorlib]System.Int32\n    IL_0155:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_015a:  dup\n    IL_015b:  ldstr      \"Seventh case\"\n    IL_0160:  ldc.i4.6\n    IL_0161:  box        [mscorlib]System.Int32\n    IL_0166:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_016b:  dup\n    IL_016c:  ldstr      \"Eighth case\"\n    IL_0171:  ldc.i4.7\n    IL_0172:  box        [mscorlib]System.Int32\n    IL_0177:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_017c:  dup\n    IL_017d:  ldstr      \"Ninth case\"\n    IL_0182:  ldc.i4.8\n    IL_0183:  box        [mscorlib]System.Int32\n    IL_0188:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_018d:  dup\n    IL_018e:  ldstr      \"Tenth case\"\n    IL_0193:  ldc.i4.s   9\n    IL_0195:  box        [mscorlib]System.Int32\n    IL_019a:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_019f:  dup\n    IL_01a0:  ldstr      \"Eleventh case\"\n    IL_01a5:  ldc.i4.s   10\n    IL_01a7:  box        [mscorlib]System.Int32\n    IL_01ac:  call       instance void [mscorlib]System.Collections.Hashtable::Add(object,\n                                                                                   object)\n    IL_01b1:  volatile.\n    IL_01b3:  stsfld     class [mscorlib]System.Collections.Hashtable '<PrivateImplementationDetails>'::'$$method0x6000007-2'\n    .try\n    {\n      IL_01b8:  ldstr      \"TwoDifferentSwitchBlocks:\"\n      IL_01bd:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_01c2:  call       string [mscorlib]System.Environment::get_UserName()\n      IL_01c7:  dup\n      IL_01c8:  stloc.1\n      IL_01c9:  brfalse    IL_0295\n\n      IL_01ce:  volatile.\n      IL_01d0:  ldsfld     class [mscorlib]System.Collections.Hashtable '<PrivateImplementationDetails>'::'$$method0x6000007-2'\n      IL_01d5:  ldloc.1\n      IL_01d6:  call       instance object [mscorlib]System.Collections.Hashtable::get_Item(object)\n      IL_01db:  dup\n      IL_01dc:  stloc.1\n      IL_01dd:  brfalse    IL_0295\n\n      IL_01e2:  ldloc.1\n      IL_01e3:  unbox      [mscorlib]System.Int32\n      IL_01e8:  ldind.i4\n      IL_01e9:  switch     ( \n                            IL_021c,\n                            IL_0227,\n                            IL_0232,\n                            IL_023d,\n                            IL_0248,\n                            IL_0253,\n                            IL_025e,\n                            IL_0269,\n                            IL_0274,\n                            IL_027f,\n                            IL_028a)\n      IL_021a:  br.s       IL_0295\n\n      IL_021c:  ldstr      \"Text1\"\n      IL_0221:  stloc.0\n      IL_0222:  leave      IL_0399\n\n      IL_0227:  ldstr      \"Text2\"\n      IL_022c:  stloc.0\n      IL_022d:  leave      IL_0399\n\n      IL_0232:  ldstr      \"Text3\"\n      IL_0237:  stloc.0\n      IL_0238:  leave      IL_0399\n\n      IL_023d:  ldstr      \"Text4\"\n      IL_0242:  stloc.0\n      IL_0243:  leave      IL_0399\n\n      IL_0248:  ldstr      \"Text5\"\n      IL_024d:  stloc.0\n      IL_024e:  leave      IL_0399\n\n      IL_0253:  ldstr      \"Text6\"\n      IL_0258:  stloc.0\n      IL_0259:  leave      IL_0399\n\n      IL_025e:  ldstr      \"Text7\"\n      IL_0263:  stloc.0\n      IL_0264:  leave      IL_0399\n\n      IL_0269:  ldstr      \"Text8\"\n      IL_026e:  stloc.0\n      IL_026f:  leave      IL_0399\n\n      IL_0274:  ldstr      \"Text9\"\n      IL_0279:  stloc.0\n      IL_027a:  leave      IL_0399\n\n      IL_027f:  ldstr      \"Text10\"\n      IL_0284:  stloc.0\n      IL_0285:  leave      IL_0399\n\n      IL_028a:  ldstr      \"Text11\"\n      IL_028f:  stloc.0\n      IL_0290:  leave      IL_0399\n\n      IL_0295:  ldstr      \"Default\"\n      IL_029a:  stloc.0\n      IL_029b:  leave      IL_0399\n\n    }  // end .try\n    finally\n    {\n      IL_02a0:  ldstr      \"Second switch:\"\n      IL_02a5:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_02aa:  call       string [mscorlib]System.Console::ReadLine()\n      IL_02af:  dup\n      IL_02b0:  stloc.1\n      IL_02b1:  brfalse    IL_038e\n\n      IL_02b6:  volatile.\n      IL_02b8:  ldsfld     class [mscorlib]System.Collections.Hashtable '<PrivateImplementationDetails>'::'$$method0x6000007-1'\n      IL_02bd:  ldloc.1\n      IL_02be:  call       instance object [mscorlib]System.Collections.Hashtable::get_Item(object)\n      IL_02c3:  dup\n      IL_02c4:  stloc.1\n      IL_02c5:  brfalse    IL_038e\n\n      IL_02ca:  ldloc.1\n      IL_02cb:  unbox      [mscorlib]System.Int32\n      IL_02d0:  ldind.i4\n      IL_02d1:  switch     ( \n                            IL_0307,\n                            IL_0316,\n                            IL_0322,\n                            IL_032e,\n                            IL_033a,\n                            IL_0346,\n                            IL_0352,\n                            IL_035e,\n                            IL_036a,\n                            IL_0376,\n                            IL_0382)\n      IL_0302:  br         IL_038e\n\n      IL_0307:  ldstr      \"Te43234xt1\"\n      IL_030c:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_0311:  br         IL_0398\n\n      IL_0316:  ldstr      \"Te223443xt2\"\n      IL_031b:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_0320:  br.s       IL_0398\n\n      IL_0322:  ldstr      \"Te234xt3\"\n      IL_0327:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_032c:  br.s       IL_0398\n\n      IL_032e:  ldstr      \"Tex243t4\"\n      IL_0333:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_0338:  br.s       IL_0398\n\n      IL_033a:  ldstr      \"Tex243t5\"\n      IL_033f:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_0344:  br.s       IL_0398\n\n      IL_0346:  ldstr      \"Text2346\"\n      IL_034b:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_0350:  br.s       IL_0398\n\n      IL_0352:  ldstr      \"Text234234\"\n      IL_0357:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_035c:  br.s       IL_0398\n\n      IL_035e:  ldstr      \"Text8234\"\n      IL_0363:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_0368:  br.s       IL_0398\n\n      IL_036a:  ldstr      \"Text923423\"\n      IL_036f:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_0374:  br.s       IL_0398\n\n      IL_0376:  ldstr      \"Text10\"\n      IL_037b:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_0380:  br.s       IL_0398\n\n      IL_0382:  ldstr      \"Text1134123\"\n      IL_0387:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_038c:  br.s       IL_0398\n\n      IL_038e:  ldstr      \"Defa234234ult\"\n      IL_0393:  call       void [mscorlib]System.Console::WriteLine(string)\n      IL_0398:  endfinally\n    }  // end handler\n    IL_0399:  ldloc.0\n    IL_039a:  ret\n  } // end of method Switch::TwoDifferentSwitchBlocksInTryFinally\n\n  .method public hidebysig static string \n          SwitchOverBool(bool b) cil managed\n  {\n    // Code size       54 (0x36)\n    .maxstack  2\n    .locals init (bool V_0)\n    IL_0000:  ldstr      \"SwitchOverBool: \"\n    IL_0005:  ldarga.s   b\n    IL_0007:  call       instance string [mscorlib]System.Boolean::ToString()\n    IL_000c:  call       string [mscorlib]System.String::Concat(string,\n                                                                string)\n    IL_0011:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0016:  ldarg.0\n    IL_0017:  stloc.0\n    IL_0018:  ldloc.0\n    IL_0019:  switch     ( \n                          IL_002e,\n                          IL_0028)\n    IL_0026:  br.s       IL_0034\n\n    IL_0028:  ldsfld     string [mscorlib]System.Boolean::TrueString\n    IL_002d:  ret\n\n    IL_002e:  ldsfld     string [mscorlib]System.Boolean::FalseString\n    IL_0033:  ret\n\n    IL_0034:  ldnull\n    IL_0035:  ret\n  } // end of method Switch::SwitchOverBool\n\n  .method public hidebysig static void  SwitchInLoop(int32 i) cil managed\n  {\n    // Code size       112 (0x70)\n    .maxstack  2\n    .locals init (int32 V_0)\n    IL_0000:  ldstr      \"SwitchInLoop: \"\n    IL_0005:  ldarg.0\n    IL_0006:  box        [mscorlib]System.Int32\n    IL_000b:  call       string [mscorlib]System.String::Concat(object,\n                                                                object)\n    IL_0010:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0015:  ldarg.0\n    IL_0016:  stloc.0\n    IL_0017:  ldloc.0\n    IL_0018:  ldc.i4.1\n    IL_0019:  sub\n    IL_001a:  switch     ( \n                          IL_0031,\n                          IL_003d,\n                          IL_0054,\n                          IL_0049)\n    IL_002f:  br.s       IL_0054\n\n    IL_0031:  ldstr      \"one\"\n    IL_0036:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_003b:  br.s       IL_0069\n\n    IL_003d:  ldstr      \"two\"\n    IL_0042:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0047:  br.s       IL_0069\n\n    IL_0049:  ldstr      \"four\"\n    IL_004e:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0053:  ret\n\n    IL_0054:  ldstr      \"default\"\n    IL_0059:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_005e:  ldstr      \"more code\"\n    IL_0063:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0068:  ret\n\n    IL_0069:  ldarg.0\n    IL_006a:  ldc.i4.1\n    IL_006b:  add\n    IL_006c:  starg.s    i\n    IL_006e:  br.s       IL_0015\n  } // end of method Switch::SwitchInLoop\n\n  .method public hidebysig static void  SwitchWithGoto(int32 i) cil managed\n  {\n    // Code size       115 (0x73)\n    .maxstack  2\n    .locals init (int32 V_0)\n    IL_0000:  ldstr      \"SwitchWithGoto: \"\n    IL_0005:  ldarg.0\n    IL_0006:  box        [mscorlib]System.Int32\n    IL_000b:  call       string [mscorlib]System.String::Concat(object,\n                                                                object)\n    IL_0010:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0015:  ldarg.0\n    IL_0016:  stloc.0\n    IL_0017:  ldloc.0\n    IL_0018:  ldc.i4.1\n    IL_0019:  sub\n    IL_001a:  switch     ( \n                          IL_0031,\n                          IL_003d,\n                          IL_0047,\n                          IL_0053)\n    IL_002f:  br.s       IL_005e\n\n    IL_0031:  ldstr      \"one\"\n    IL_0036:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_003b:  br.s       IL_005e\n\n    IL_003d:  ldstr      \"two\"\n    IL_0042:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0047:  ldstr      \"three\"\n    IL_004c:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0051:  br.s       IL_0068\n\n    IL_0053:  ldstr      \"four\"\n    IL_0058:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_005d:  ret\n\n    IL_005e:  ldstr      \"default\"\n    IL_0063:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0068:  ldstr      \"End of method\"\n    IL_006d:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0072:  ret\n  } // end of method Switch::SwitchWithGoto\n\n  .method private hidebysig static class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty[] \n          GetProperties() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  1\n    IL_0000:  ldc.i4.0\n    IL_0001:  newarr     ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty\n    IL_0006:  ret\n  } // end of method Switch::GetProperties\n\n  .method public hidebysig static void  SwitchOnStringInForLoop() cil managed\n  {\n    // Code size       267 (0x10b)\n    .maxstack  6\n    .locals init (class [mscorlib]System.Collections.ArrayList V_0,\n             class [mscorlib]System.Collections.ArrayList V_1,\n             class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty[] V_2,\n             int32 V_3,\n             class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty V_4,\n             string V_5)\n    IL_0000:  newobj     instance void [mscorlib]System.Collections.ArrayList::.ctor()\n    IL_0005:  stloc.0\n    IL_0006:  newobj     instance void [mscorlib]System.Collections.ArrayList::.ctor()\n    IL_000b:  stloc.1\n    IL_000c:  call       class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch::GetProperties()\n    IL_0011:  stloc.2\n    IL_0012:  ldc.i4.0\n    IL_0013:  stloc.3\n    IL_0014:  br         IL_0101\n\n    IL_0019:  ldstr      \"In for-loop\"\n    IL_001e:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0023:  ldloc.2\n    IL_0024:  ldloc.3\n    IL_0025:  ldelem.ref\n    IL_0026:  stloc.s    V_4\n    IL_0028:  ldstr      \"Name1\"\n    IL_002d:  ldstr      \"Name2\"\n    IL_0032:  ldstr      \"Name3\"\n    IL_0037:  ldstr      \"Name4\"\n    IL_003c:  ldstr      \"Name5\"\n    IL_0041:  ldstr      \"Name6\"\n    IL_0046:  leave.s    IL_0048\n\n    IL_0048:  ldloc.s    V_4\n    IL_004a:  ldfld      class [mscorlib]System.Reflection.PropertyInfo ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::Property\n    IL_004f:  callvirt   instance string [mscorlib]System.Reflection.MemberInfo::get_Name()\n    IL_0054:  dup\n    IL_0055:  stloc.s    V_5\n    IL_0057:  brfalse    IL_00f4\n\n    IL_005c:  ldloc.s    V_5\n    IL_005e:  call       string [mscorlib]System.String::IsInterned(string)\n    IL_0063:  stloc.s    V_5\n    IL_0065:  ldloc.s    V_5\n    IL_0067:  ldstr      \"Name1\"\n    IL_006c:  beq.s      IL_009d\n\n    IL_006e:  ldloc.s    V_5\n    IL_0070:  ldstr      \"Name2\"\n    IL_0075:  beq.s      IL_00b0\n\n    IL_0077:  ldloc.s    V_5\n    IL_0079:  ldstr      \"Name3\"\n    IL_007e:  beq.s      IL_00c3\n\n    IL_0080:  ldloc.s    V_5\n    IL_0082:  ldstr      \"Name4\"\n    IL_0087:  beq.s      IL_00d6\n\n    IL_0089:  ldloc.s    V_5\n    IL_008b:  ldstr      \"Name5\"\n    IL_0090:  beq.s      IL_00e9\n\n    IL_0092:  ldloc.s    V_5\n    IL_0094:  ldstr      \"Name6\"\n    IL_0099:  beq.s      IL_00e9\n\n    IL_009b:  br.s       IL_00f4\n\n    IL_009d:  ldloc.s    V_4\n    IL_009f:  ldc.i4.1\n    IL_00a0:  callvirt   instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::set_Set(int32)\n    IL_00a5:  ldloc.0\n    IL_00a6:  ldloc.s    V_4\n    IL_00a8:  callvirt   instance int32 [mscorlib]System.Collections.ArrayList::Add(object)\n    IL_00ad:  pop\n    IL_00ae:  br.s       IL_00fd\n\n    IL_00b0:  ldloc.s    V_4\n    IL_00b2:  ldc.i4.2\n    IL_00b3:  callvirt   instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::set_Set(int32)\n    IL_00b8:  ldloc.0\n    IL_00b9:  ldloc.s    V_4\n    IL_00bb:  callvirt   instance int32 [mscorlib]System.Collections.ArrayList::Add(object)\n    IL_00c0:  pop\n    IL_00c1:  br.s       IL_00fd\n\n    IL_00c3:  ldloc.s    V_4\n    IL_00c5:  ldc.i4.3\n    IL_00c6:  callvirt   instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::set_Set(int32)\n    IL_00cb:  ldloc.0\n    IL_00cc:  ldloc.s    V_4\n    IL_00ce:  callvirt   instance int32 [mscorlib]System.Collections.ArrayList::Add(object)\n    IL_00d3:  pop\n    IL_00d4:  br.s       IL_00fd\n\n    IL_00d6:  ldloc.s    V_4\n    IL_00d8:  ldc.i4.4\n    IL_00d9:  callvirt   instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch/SetProperty::set_Set(int32)\n    IL_00de:  ldloc.0\n    IL_00df:  ldloc.s    V_4\n    IL_00e1:  callvirt   instance int32 [mscorlib]System.Collections.ArrayList::Add(object)\n    IL_00e6:  pop\n    IL_00e7:  br.s       IL_00fd\n\n    IL_00e9:  ldloc.0\n    IL_00ea:  ldloc.s    V_4\n    IL_00ec:  callvirt   instance int32 [mscorlib]System.Collections.ArrayList::Add(object)\n    IL_00f1:  pop\n    IL_00f2:  br.s       IL_00fd\n\n    IL_00f4:  ldloc.1\n    IL_00f5:  ldloc.s    V_4\n    IL_00f7:  callvirt   instance int32 [mscorlib]System.Collections.ArrayList::Add(object)\n    IL_00fc:  pop\n    IL_00fd:  ldloc.3\n    IL_00fe:  ldc.i4.1\n    IL_00ff:  add\n    IL_0100:  stloc.3\n    IL_0101:  ldloc.3\n    IL_0102:  ldloc.2\n    IL_0103:  ldlen\n    IL_0104:  conv.i4\n    IL_0105:  blt        IL_0019\n\n    IL_010a:  ret\n  } // end of method Switch::SwitchOnStringInForLoop\n\n  .method public hidebysig static void  SwitchWithComplexCondition(string[] args) cil managed\n  {\n    // Code size       139 (0x8b)\n    .maxstack  4\n    .locals init (string V_0)\n    IL_0000:  ldstr      \"a\"\n    IL_0005:  ldstr      \"b\"\n    IL_000a:  ldstr      \"c\"\n    IL_000f:  ldstr      \"d\"\n    IL_0014:  leave.s    IL_0016\n\n    IL_0016:  ldarg.0\n    IL_0017:  ldlen\n    IL_0018:  conv.i4\n    IL_0019:  brfalse.s  IL_0020\n\n    IL_001b:  ldarg.0\n    IL_001c:  ldc.i4.0\n    IL_001d:  ldelem.ref\n    IL_001e:  br.s       IL_0025\n\n    IL_0020:  ldstr      \"dummy\"\n    IL_0025:  dup\n    IL_0026:  stloc.0\n    IL_0027:  brfalse.s  IL_0080\n\n    IL_0029:  ldloc.0\n    IL_002a:  call       string [mscorlib]System.String::IsInterned(string)\n    IL_002f:  stloc.0\n    IL_0030:  ldloc.0\n    IL_0031:  ldstr      \"a\"\n    IL_0036:  beq.s      IL_0052\n\n    IL_0038:  ldloc.0\n    IL_0039:  ldstr      \"b\"\n    IL_003e:  beq.s      IL_005e\n\n    IL_0040:  ldloc.0\n    IL_0041:  ldstr      \"c\"\n    IL_0046:  beq.s      IL_006a\n\n    IL_0048:  ldloc.0\n    IL_0049:  ldstr      \"d\"\n    IL_004e:  beq.s      IL_0076\n\n    IL_0050:  br.s       IL_0080\n\n    IL_0052:  ldstr      \"a\"\n    IL_0057:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_005c:  br.s       IL_0080\n\n    IL_005e:  ldstr      \"b\"\n    IL_0063:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0068:  br.s       IL_0080\n\n    IL_006a:  ldstr      \"c\"\n    IL_006f:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0074:  br.s       IL_0080\n\n    IL_0076:  ldstr      \"d\"\n    IL_007b:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0080:  ldstr      \"end\"\n    IL_0085:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_008a:  ret\n  } // end of method Switch::SwitchWithComplexCondition\n\n  .method public hidebysig static void  SwitchWithArray(string[] args) cil managed\n  {\n    // Code size       127 (0x7f)\n    .maxstack  4\n    .locals init (string V_0)\n    IL_0000:  ldstr      \"a\"\n    IL_0005:  ldstr      \"b\"\n    IL_000a:  ldstr      \"c\"\n    IL_000f:  ldstr      \"d\"\n    IL_0014:  leave.s    IL_0016\n\n    IL_0016:  ldarg.0\n    IL_0017:  ldc.i4.0\n    IL_0018:  ldelem.ref\n    IL_0019:  dup\n    IL_001a:  stloc.0\n    IL_001b:  brfalse.s  IL_0074\n\n    IL_001d:  ldloc.0\n    IL_001e:  call       string [mscorlib]System.String::IsInterned(string)\n    IL_0023:  stloc.0\n    IL_0024:  ldloc.0\n    IL_0025:  ldstr      \"a\"\n    IL_002a:  beq.s      IL_0046\n\n    IL_002c:  ldloc.0\n    IL_002d:  ldstr      \"b\"\n    IL_0032:  beq.s      IL_0052\n\n    IL_0034:  ldloc.0\n    IL_0035:  ldstr      \"c\"\n    IL_003a:  beq.s      IL_005e\n\n    IL_003c:  ldloc.0\n    IL_003d:  ldstr      \"d\"\n    IL_0042:  beq.s      IL_006a\n\n    IL_0044:  br.s       IL_0074\n\n    IL_0046:  ldstr      \"a\"\n    IL_004b:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0050:  br.s       IL_0074\n\n    IL_0052:  ldstr      \"b\"\n    IL_0057:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_005c:  br.s       IL_0074\n\n    IL_005e:  ldstr      \"c\"\n    IL_0063:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0068:  br.s       IL_0074\n\n    IL_006a:  ldstr      \"d\"\n    IL_006f:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0074:  ldstr      \"end\"\n    IL_0079:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_007e:  ret\n  } // end of method Switch::SwitchWithArray\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  1\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method Switch::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.Switch\n\n.class private auto ansi '<PrivateImplementationDetails>'\n       extends [mscorlib]System.Object\n{\n  .field static assembly class [mscorlib]System.Collections.Hashtable '$$method0x6000006-1'\n  .field static assembly class [mscorlib]System.Collections.Hashtable '$$method0x6000007-1'\n  .field static assembly class [mscorlib]System.Collections.Hashtable '$$method0x6000007-2'\n} // end of class '<PrivateImplementationDetails>'\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n// WARNING: Created Win32 resource file C:\\Users\\Siegfried\\Projects\\ILSpy master\\ICSharpCode.Decompiler.Tests\\TestCases\\ILPretty\\CS1xSwitch_Release.res\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/CallIndirect.cs",
    "content": "using System;\ninternal class CallIndirect\n{\n\tprivate unsafe void Test(IntPtr f)\n\t{\n\t\t((delegate* unmanaged[Stdcall]<int, void>)f)(42);\n\t}\n\n\tprivate unsafe void UnmanagedDefaultCall(IntPtr f)\n\t{\n\t\t((delegate* unmanaged<int, void>)f)(42);\n\t}\n\n\tprivate unsafe void CustomCall(IntPtr f)\n\t{\n\t\t((delegate* unmanaged[Custom]<int, void>)f)(42);\n\t}\n\n\tprivate unsafe void MultipleCustomCall(IntPtr f)\n\t{\n\t\t((delegate* unmanaged[SuppressGCTransition, Custom]<int, void>)f)(42);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/CallIndirect.il",
    "content": "#define CORE_ASSEMBLY \"System.Runtime\"\n\n.assembly extern CORE_ASSEMBLY\n{\n  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )                         // .?_....:\n  .ver 4:0:0:0\n}\n\n.class private auto ansi beforefieldinit CallIndirect\n    extends [System.Private.CoreLib]System.Object\n{\n    // Methods\n    .method private hidebysig \n        instance void Test (\n            native int f\n        ) cil managed \n    {\n        .maxstack 8\n\n        ldc.i4.s 42\n        ldarg.1\n        calli unmanaged stdcall void(int32)\n        ret\n    } // end of method Example::Test\n\n    .method private hidebysig \n        instance void UnmanagedDefaultCall (\n            native int f\n        ) cil managed \n    {\n        .maxstack 8\n\n        ldc.i4.s 42\n        ldarg.1\n        calli unmanaged void(int32)\n        ret\n    } // end of method Example::Test\n    \n    .method private hidebysig \n        instance void CustomCall (\n            native int f\n        ) cil managed \n    {\n        .maxstack 8\n\n        ldc.i4.s 42\n        ldarg.1\n        calli unmanaged void modreq([System.Private.CoreLib] System.Runtime.CompilerServices.CallConvCustom)(int32)\n        ret\n    } // end of method Example::Test\n    \n    .method private hidebysig \n        instance void MultipleCustomCall (\n            native int f\n        ) cil managed \n    {\n        .maxstack 8\n\n        ldc.i4.s 42\n        ldarg.1\n        calli unmanaged void modreq([System.Private.CoreLib] System.Runtime.CompilerServices.CallConvCustom) modreq([System.Private.CoreLib] System.Runtime.CompilerServices.CallConvSuppressGCTransition) (int32)\n        ret\n    } // end of method Example::Test\n\n    .method public hidebysig specialname rtspecialname \n        instance void .ctor () cil managed \n    {\n        // Method begins at RVA 0x206e\n        // Code size 8 (0x8)\n        .maxstack 8\n\n        IL_0000: ldarg.0\n        IL_0001: call instance void [System.Private.CoreLib]System.Object::.ctor()\n        IL_0006: nop\n        IL_0007: ret\n    } // end of method Example::.ctor\n\n} // end of class Example\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/ConstantBlobs.cs",
    "content": "namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n\tinternal class ConstantBlobs\n\t{\n\t\tpublic static void Float_Int32(float f1 = 0f, float f2 = -1f, float f3 = int.MaxValue, float f4 = int.MinValue)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/ConstantBlobs.il",
    "content": "// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly ConstantBlobs\n{\n  .ver 1:0:0:0\n}\n.module ConstantBlobs.exe\n// MVID: {B973FCD6-A9C4-48A9-8291-26DDC248E208}\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00020003    //  ILONLY 32BITPREFERRED\n// Image base: 0x000001C4B6C90000\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.ConstantBlobs\n       extends [mscorlib]System.Object\n{\n.method public hidebysig static void Float_Int32(\n            [opt] float32 f1,\n            [opt] float32 f2,\n            [opt] float32 f3,\n            [opt] float32 f4\n        ) cil managed\n{\n  .param [1] = int32(0)\n  .param [2] = int32(-1)\n  .param [3] = int32(2147483647)\n  .param [4] = int32(-2147483648)\n  \n  // Code size 1 (0x1)\n  .maxstack  8\n\tIL_0000: ret\n} // end of method Program::Float_Int32\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/DirectCallToExplicitInterfaceImpl.cs",
    "content": "using System;\n\npublic sealed class TestClass : IDisposable\n{\n\tvoid IDisposable.Dispose()\n\t{\n\t}\n\n\tpublic void Test(TestClass other)\n\t{\n\t\t((IDisposable)this).Dispose();\n\t\t((IDisposable)other).Dispose();\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/DirectCallToExplicitInterfaceImpl.il",
    "content": ".assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly DirectCallToExplicitInterfaceImpl\n{\n  .ver 1:0:0:0\n}\n.module DirectCallToExplicitInterfaceImpl.exe\n\n.class public auto ansi sealed TestClass\n\textends [mscorlib]System.Object\n  implements [mscorlib]System.IDisposable\n{\n\t// Methods\n\t\n  .method private final hidebysig newslot virtual \n\tinstance void System.IDisposable.Dispose () cil managed \n  {\n    .override method instance void [mscorlib]System.IDisposable::Dispose()\n    ret\n  }\n\n  .method public hidebysig void Test (class TestClass other) cil managed \n  {\n    ldarg.0\n    call instance void TestClass::System.IDisposable.Dispose()\n\n    ldarg.1\n    call instance void TestClass::System.IDisposable.Dispose()\n\n    ret\n  }\n\n} // end of class TestClass\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/EmptyBodies.cs",
    "content": "internal class EmptyBodies\n{\n\tpublic static void RetVoid()\n\t{\n\t}\n\tpublic static int RetInt()\n\t{\n\t\t/*Error: Method body consists only of 'ret', but nothing is being returned. Decompiled assembly might be a reference assembly.*/;\n\t}\n\tpublic static void Nop()\n\t{\n\t\t/*Error: End of method reached without returning.*/;\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/EmptyBodies.il",
    "content": "#define CORE_ASSEMBLY \"System.Runtime\"\n\n.assembly extern CORE_ASSEMBLY\n{\n  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )                         // .?_....:\n  .ver 4:0:0:0\n}\n\n.class private auto ansi beforefieldinit EmptyBodies\n    extends [CORE_ASSEMBLY]System.Object\n{\n    // I cannot test a truly empty body because the assembler will automatically add a ret instruction.\n\n    .method public hidebysig static void RetVoid () cil managed \n    {\n\t    .maxstack 8\n\t\tret\n    }\n\n\t.method public hidebysig static int32 RetInt () cil managed \n    {\n\t    .maxstack 8\n\t\tret\n    }\n\n\t.method public hidebysig static void Nop () cil managed \n    {\n\t    .maxstack 8\n\t\tnop\n    }\n\n    .method public hidebysig specialname rtspecialname \n        instance void .ctor () cil managed \n    {\n        // Method begins at RVA 0x206e\n        // Code size 8 (0x8)\n        .maxstack 8\n\n        IL_0000: ldarg.0\n        IL_0001: call instance void [System.Private.CoreLib]System.Object::.ctor()\n        IL_0006: nop\n        IL_0007: ret\n    } // end of method Example::.ctor\n\n} // end of class EmptyBodies\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/EvalOrder.cs",
    "content": "using System;\nusing System.Runtime.InteropServices;\ninternal class EvalOrder\n{\n\tprivate SimpleStruct field;\n\n\tpublic static void Test(EvalOrder p)\n\t{\n\t\t// ldflda (and potential NRE) before MyStruct ctor call\n\t\tref SimpleStruct reference = ref p.field;\n\t\treference = new SimpleStruct(1);\n\t}\n}\n[StructLayout(LayoutKind.Sequential, Size = 1)]\ninternal struct SimpleStruct\n{\n\tpublic SimpleStruct(int val)\n\t{\n\t\tConsole.WriteLine(val);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/EvalOrder.il",
    "content": "#define CORE_ASSEMBLY \"System.Runtime\"\n\n.assembly extern CORE_ASSEMBLY\n{\n  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )                         // .?_....:\n  .ver 4:0:0:0\n}\n\n.class private auto ansi beforefieldinit EvalOrder\n    extends [System.Private.CoreLib]System.Object\n{\n    .field private valuetype SimpleStruct 'field'\n\n    // Methods\n    .method public hidebysig static \n\t    void Test (\n\t\t    class EvalOrder p\n\t    ) cil managed \n    {\n\t    // Method begins at RVA 0x20f0\n\t    // Code size 14 (0xe)\n\t    .maxstack 8\n\n\t    ldarg.0\n\t    ldflda valuetype SimpleStruct EvalOrder::'field'\n\t    ldc.i4.1\n\t    call instance void SimpleStruct::.ctor(int32)\n\t    ret\n    } // end of method EvalOrder::Test\n\n    .method public hidebysig specialname rtspecialname \n        instance void .ctor () cil managed \n    {\n        // Method begins at RVA 0x206e\n        // Code size 8 (0x8)\n        .maxstack 8\n\n        IL_0000: ldarg.0\n        IL_0001: call instance void [System.Private.CoreLib]System.Object::.ctor()\n        IL_0006: nop\n        IL_0007: ret\n    } // end of method Example::.ctor\n\n} // end of class Example\n\n.class private sequential ansi sealed beforefieldinit SimpleStruct\n\textends [System.Runtime]System.ValueType\n{\n\t.pack 0\n\t.size 1\n\n\t// Methods\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor (\n\t\t\tint32 val\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x20f9\n\t\t// Code size 9 (0x9)\n\t\t.maxstack 8\n\n\t\tIL_0000: nop\n\t\tIL_0001: ldarg.1\n\t\tIL_0002: call void [System.Console]System.Console::WriteLine(int32)\n\t\tIL_0007: nop\n\t\tIL_0008: ret\n\t} // end of method SimpleStruct::.ctor\n\n} // end of class SimpleStruct\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/ExtensionEncodingV1.cs",
    "content": "using System.Collections.Generic;\nusing System.Linq;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n\tinternal static class ExtensionPropertiesV1\n\t{\n\t\textension<T>(ICollection<T> collection) where T : notnull\n\t\t{\n\t\t\tpublic bool IsEmpty => collection.Count == 0;\n\n\t\t\tpublic int Test {\n\t\t\t\tget {\n\t\t\t\t\treturn 42;\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic void AddIfNotNull(T item)\n\t\t\t{\n\t\t\t\tif (item != null)\n\t\t\t\t{\n\t\t\t\t\tcollection.Add(item);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic T2 Cast<T2>(int index) where T2 : T\n\t\t\t{\n\t\t\t\treturn (T2)(object)collection.ElementAt(index);\n\t\t\t}\n\n\t\t\tpublic static void StaticExtension()\n\t\t\t{\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/ExtensionEncodingV1.il",
    "content": "// To extend use:\n// see https://lab.razor.fyi/#fVHNbhMxEFYRqrBP0CcYbpsDVlioVDU_UrSNUBCqImVPnHC8k8TgtRd7tiSqcuMh-gbceQBeihdA66bJNlK5WDPzfTPffGP-65TzqXdLL0uhwtndaR20XcJsEwjLHm9nInPGoCLtbBAf0KLX6j-MSVnWJOcGjzhXWi6tC6RVeBoRmStwZKXZBH1M-6Tt96NSvvIoC22XT9VFLsO30OPcyhJDJRXCJJutpK8aIXGFypWVNuhFjoFCfDMZMIipR6INv-VMW0JvpYFAkrQCZWQIMF4T2qCdnXpXoSeNgbNbzhg-AP18mEwOl-nnQ1D7rAM_VugRcrgE68jWxnAW-1lVz41WMHfOwCSMy4o2MGj3iszVlmAwgG6Ptzq0JWgMQBzDlvgQMY9Uewvv017Mt_ENezzm2_aoG6cLGBXFZHHt6Lo2JslBE5adhnPfpBeQNCV4PYBm_QjtMNZadlQUkddpaT_SylPIZKB-ng6TxoK2Ba7390nhEvKD6s5JkqedxM2_oqJOS2tssERLI0ruh0TJR2K7P4z-ZjHef2RyMNcsueVsy7f87NW56Irum1Sk5-8uuuJt9-LjM20-sxd3P__-_rN4-fzLyfrkHw\n// created using https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-tools/NuGet/Microsoft.Net.Compilers.Toolset/overview/5.0.0-2.25380.108\n\n.class private auto ansi abstract sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.ExtensionPropertiesV1\n    extends [System.Runtime]System.Object\n{\n    .custom instance void [System.Runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = (\n        01 00 01 00 00\n    )\n    .custom instance void [System.Runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = (\n        01 00 00 00 00\n    )\n    .custom instance void [System.Runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = (\n        01 00 00 00\n    )\n    // Nested Types\n    .class nested public auto ansi sealed specialname beforefieldinit '<>E__0`1'<T>\n        extends [System.Runtime]System.Object\n    {\n        // Methods\n        .method private hidebysig specialname static \n            void '<Extension>$' (\n                class [System.Runtime]System.Collections.Generic.ICollection`1<!T> collection\n            ) cil managed \n        {\n            .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n                01 00 00 00\n            )\n            // Method begins at RVA 0x209d\n            // Header size: 1\n            // Code size: 1 (0x1)\n            .maxstack 8\n\n            IL_0000: ret\n        } // end of method '<>E__0`1'::'<Extension>$'\n\n        .method public hidebysig specialname \n            instance bool get_IsEmpty () cil managed \n        {\n            // Method begins at RVA 0x209f\n            // Header size: 1\n            // Code size: 2 (0x2)\n            .maxstack 8\n\n            IL_0000: ldnull\n            IL_0001: throw\n        } // end of method '<>E__0`1'::get_IsEmpty\n\n        .method public hidebysig specialname \n            instance int32 get_Test () cil managed \n        {\n            // Method begins at RVA 0x209f\n            // Header size: 1\n            // Code size: 2 (0x2)\n            .maxstack 8\n\n            IL_0000: ldnull\n            IL_0001: throw\n        } // end of method '<>E__0`1'::get_Test\n\n        .method public hidebysig specialname \n            instance void set_Test (\n                int32 'value'\n            ) cil managed \n        {\n            // Method begins at RVA 0x209f\n            // Header size: 1\n            // Code size: 2 (0x2)\n            .maxstack 8\n\n            IL_0000: ldnull\n            IL_0001: throw\n        } // end of method '<>E__0`1'::set_Test\n\n        .method public hidebysig \n            instance void AddIfNotNull (\n                !T item\n            ) cil managed \n        {\n            // Method begins at RVA 0x209f\n            // Header size: 1\n            // Code size: 2 (0x2)\n            .maxstack 8\n\n            IL_0000: ldnull\n            IL_0001: throw\n        } // end of method '<>E__0`1'::AddIfNotNull\n\n        .method public hidebysig \n            instance !!T2 Cast<(!T) T2> (\n                int32 index\n            ) cil managed \n        {\n            .param type T2\n                .custom instance void [System.Runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = (\n                    01 00 00 00 00\n                )\n            // Method begins at RVA 0x209f\n            // Header size: 1\n            // Code size: 2 (0x2)\n            .maxstack 8\n\n            IL_0000: ldnull\n            IL_0001: throw\n        } // end of method '<>E__0`1'::Cast\n\n        .method public hidebysig static \n            void StaticExtension () cil managed \n        {\n            // Method begins at RVA 0x209f\n            // Header size: 1\n            // Code size: 2 (0x2)\n            .maxstack 8\n\n            IL_0000: ldnull\n            IL_0001: throw\n        } // end of method '<>E__0`1'::StaticExtension\n\n        // Properties\n        .property instance bool IsEmpty()\n        {\n            .get instance bool ICSharpCode.Decompiler.Tests.TestCases.ILPretty.ExtensionPropertiesV1/'<>E__0`1'::get_IsEmpty()\n        }\n        .property instance int32 Test()\n        {\n            .get instance int32 ICSharpCode.Decompiler.Tests.TestCases.ILPretty.ExtensionPropertiesV1/'<>E__0`1'::get_Test()\n            .set instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.ExtensionPropertiesV1/'<>E__0`1'::set_Test(int32)\n        }\n\n    } // end of class <>E__0`1\n\n\n    // Methods\n    .method public hidebysig static \n        bool get_IsEmpty<T> (\n            class [System.Runtime]System.Collections.Generic.ICollection`1<!!T> collection\n        ) cil managed \n    {\n        // Method begins at RVA 0x2050\n        // Header size: 1\n        // Code size: 10 (0xa)\n        .maxstack 8\n\n        IL_0000: ldarg.0\n        IL_0001: callvirt instance int32 class [System.Runtime]System.Collections.Generic.ICollection`1<!!T>::get_Count()\n        IL_0006: ldc.i4.0\n        IL_0007: ceq\n        IL_0009: ret\n    } // end of method ExtensionProperties::get_IsEmpty\n\n    .method public hidebysig static \n        int32 get_Test<T> (\n            class [System.Runtime]System.Collections.Generic.ICollection`1<!!T> collection\n        ) cil managed \n    {\n        // Method begins at RVA 0x205b\n        // Header size: 1\n        // Code size: 4 (0x4)\n        .maxstack 8\n\n        IL_0000: nop\n        IL_0001: ldc.i4.s 42\n        IL_0003: ret\n    } // end of method ExtensionProperties::get_Test\n\n    .method public hidebysig static \n        void set_Test<T> (\n            class [System.Runtime]System.Collections.Generic.ICollection`1<!!T> collection,\n            int32 'value'\n        ) cil managed \n    {\n        // Method begins at RVA 0x2060\n        // Header size: 1\n        // Code size: 2 (0x2)\n        .maxstack 8\n\n        IL_0000: nop\n        IL_0001: ret\n    } // end of method ExtensionProperties::set_Test\n\n    .method public hidebysig static \n        void AddIfNotNull<T> (\n            class [System.Runtime]System.Collections.Generic.ICollection`1<!!T> collection,\n            !!T item\n        ) cil managed \n    {\n        .custom instance void [System.Runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = (\n            01 00 00 00\n        )\n        // Method begins at RVA 0x2064\n        // Header size: 12\n        // Code size: 25 (0x19)\n        .maxstack 2\n        .locals init (\n            [0] bool\n        )\n\n        IL_0000: nop\n        IL_0001: ldarg.1\n        IL_0002: box !!T\n        IL_0007: ldnull\n        IL_0008: cgt.un\n        IL_000a: stloc.0\n        IL_000b: ldloc.0\n        IL_000c: brfalse.s IL_0018\n\n        IL_000e: nop\n        IL_000f: ldarg.0\n        IL_0010: ldarg.1\n        IL_0011: callvirt instance void class [System.Runtime]System.Collections.Generic.ICollection`1<!!T>::Add(!0)\n        IL_0016: nop\n        IL_0017: nop\n\n        IL_0018: ret\n    } // end of method ExtensionProperties::AddIfNotNull\n\n    .method public hidebysig static \n        !!T2 Cast<T, (!!T) T2> (\n            class [System.Runtime]System.Collections.Generic.ICollection`1<!!T> collection,\n            int32 index\n        ) cil managed \n    {\n        .custom instance void [System.Runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = (\n            01 00 00 00\n        )\n        // Method begins at RVA 0x2089\n        // Header size: 1\n        // Code size: 19 (0x13)\n        .maxstack 8\n\n        IL_0000: nop\n        IL_0001: ldarg.0\n        IL_0002: ldarg.1\n        IL_0003: call !!0 [System.Linq]System.Linq.Enumerable::ElementAt<!!T>(class [System.Runtime]System.Collections.Generic.IEnumerable`1<!!0>, int32)\n        IL_0008: box !!T\n        IL_000d: unbox.any !!T2\n        IL_0012: ret\n    } // end of method ExtensionProperties::Cast\n\n    .method public hidebysig static \n        void StaticExtension<T> () cil managed \n    {\n        // Method begins at RVA 0x2060\n        // Header size: 1\n        // Code size: 2 (0x2)\n        .maxstack 8\n\n        IL_0000: nop\n        IL_0001: ret\n    } // end of method ExtensionProperties::StaticExtension\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.ExtensionPropertiesV1\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/ExtensionEncodingV2.cs",
    "content": "using System.Collections.Generic;\nusing System.Linq;\nnamespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n\tinternal static class ExtensionPropertiesV2\n\t{\n\t\textension<T>(ICollection<T> collection) where T : notnull\n\t\t{\n\t\t\tpublic bool IsEmpty => collection.Count == 0;\n\t\t\tpublic int Test {\n\t\t\t\tget {\n\t\t\t\t\treturn 42;\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t}\n\t\t\t}\n\t\t\tpublic void AddIfNotNull(T item)\n\t\t\t{\n\t\t\t\tif (item != null)\n\t\t\t\t{\n\t\t\t\t\tcollection.Add(item);\n\t\t\t\t}\n\t\t\t}\n\t\t\tpublic T2 Cast<T2>(int index) where T2 : T\n\t\t\t{\n\t\t\t\treturn (T2)(object)collection.ElementAt(index);\n\t\t\t}\n\t\t\tpublic static void StaticExtension()\n\t\t\t{\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/ExtensionEncodingV2.il",
    "content": "// To extend use:\n// see https://lab.razor.fyi/#fVHBbtNAEFUQArwn6BcMPdkSrFyrFVKbVIrcgIKqKKKrHkBIbOyps3S9a3bHtFEViQvfwy9w4Qf4D66ckd00dSOVy2pn3nvz5u2y748ZmzpbOFnyzG_9fVR7ZQo4WXjC8oB1K55arTEjZY3nb9CgU9l_GOOyrEnONG5wjpQsjPWkMn8_wlOb49BIvfBqk3aszJeNlpg7lLkyxX19LqQ_3xz0rjakSuSn6LyyppWzD9J7LGd6sQ9CugLptZMlXlh3Hm7zyUik1uGwql6sRIOdmMfb0UfGjCzRVzJDGKcnc-mqJgI_wsyWldLouEBPvj1T6dHz8fHUIdGCXbFAGUJnpAZPklQGmZbew-iS0DQuU2crdKTQnyYsuGJBgDdQXxyG49t374tDyNZVBBdzdAgC9sFYMrXWLGj1QVXPtMpgZq2GsR-VFS1g0NXy1NaGYDCA-IB1FMoQNCGgHRMUeHMLHFLtDOwmB229bE-_xtt62R311aochnk-PptYmtRahwIUYRk1nGuROoOwacHzATTrt9AKCzrLDvO85UUd7zteIoFUeuqL5DBsIiiT4-X6fRLYB3HrukoSiiQK7ewzZhR1vEYaSzQ0pPB6SGt5x2z1i22-k_a-_srwNlyz5JIFS7ZkW8_2eMzjlwlP9nb3dvhO_OrtA6XfB09-__n14-fZ04efevPeZe9br_cP\n// created using https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-tools/NuGet/Microsoft.Net.Compilers.Toolset/overview/5.0.0-2.25451.107\n\n.assembly TestProject\n{\n    .custom instance void [System.Runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = {\n    }\n    .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = {\n        int32(8)\n    }\n    .custom instance void [System.Runtime]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = {\n        property bool WrapNonExceptionThrows = bool(true)\n    }\n    .custom instance void [System.Runtime]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [System.Runtime]System.Diagnostics.DebuggableAttribute/DebuggingModes) = {\n        int32(263)\n    }\n    .custom instance void [System.Runtime]System.Runtime.Versioning.TargetFrameworkAttribute::.ctor(string) = {\n        string('.NETCoreApp,Version=10.0')\n    }\n    .permissionset reqmin = {\n        [System.Runtime]System.Security.Permissions.SecurityPermissionAttribute = {\n            property bool SkipVerification = bool(true)\n        }\n    }\n    .hash algorithm 0x00008004 // SHA1\n    .ver 0:0:0:0\n}\n\n.class private auto ansi '<Module>'\n{\n} // end of class <Module>\n\n.class private auto ansi abstract sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.ExtensionPropertiesV2\n    extends [System.Runtime]System.Object\n{\n    .custom instance void [System.Runtime]System.Runtime.CompilerServices.NullableContextAttribute::.ctor(uint8) = {\n        uint8(1)\n    }\n    .custom instance void [System.Runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = {\n        uint8(0)\n    }\n    .custom instance void [System.Runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = {\n    }\n    // Nested Types\n    .class nested public auto ansi sealed specialname '<G>$847CB318C385471B1F4E7BD0A197DBCA'<$T0>\n        extends [System.Runtime]System.Object\n    {\n        .custom instance void [System.Runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = {\n        }\n        // Nested Types\n        .class nested public auto ansi abstract sealed specialname '<M>$6A79ECC07A7731C57E8EB4E3D9C8B38B'<T>\n            extends [System.Runtime]System.Object\n        {\n            // Methods\n            .method public hidebysig specialname static \n                void '<Extension>$' (\n                    class [System.Runtime]System.Collections.Generic.ICollection`1<!T> collection\n                ) cil managed \n            {\n                .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = {\n                }\n                // Method begins at RVA 0x20a0\n                // Header size: 1\n                // Code size: 1 (0x1)\n                .maxstack 8\n\n                IL_0000: ret\n            } // end of method '<M>$6A79ECC07A7731C57E8EB4E3D9C8B38B'::'<Extension>$'\n\n        } // end of class <M>$6A79ECC07A7731C57E8EB4E3D9C8B38B\n\n\n        // Methods\n        .method public hidebysig specialname \n            instance bool get_IsEmpty () cil managed \n        {\n            .custom instance void [System.Runtime]System.Runtime.CompilerServices.ExtensionMarkerAttribute::.ctor(string) = {\n                string('<M>$6A79ECC07A7731C57E8EB4E3D9C8B38B')\n            }\n            // Method begins at RVA 0x209d\n            // Header size: 1\n            // Code size: 2 (0x2)\n            .maxstack 8\n\n            IL_0000: ldnull\n            IL_0001: throw\n        } // end of method '<G>$847CB318C385471B1F4E7BD0A197DBCA'::get_IsEmpty\n\n        .method public hidebysig specialname \n            instance int32 get_Test () cil managed \n        {\n            .custom instance void [System.Runtime]System.Runtime.CompilerServices.ExtensionMarkerAttribute::.ctor(string) = {\n                string('<M>$6A79ECC07A7731C57E8EB4E3D9C8B38B')\n            }\n            // Method begins at RVA 0x209d\n            // Header size: 1\n            // Code size: 2 (0x2)\n            .maxstack 8\n\n            IL_0000: ldnull\n            IL_0001: throw\n        } // end of method '<G>$847CB318C385471B1F4E7BD0A197DBCA'::get_Test\n\n        .method public hidebysig specialname \n            instance void set_Test (\n                int32 'value'\n            ) cil managed \n        {\n            .custom instance void [System.Runtime]System.Runtime.CompilerServices.ExtensionMarkerAttribute::.ctor(string) = {\n                string('<M>$6A79ECC07A7731C57E8EB4E3D9C8B38B')\n            }\n            // Method begins at RVA 0x209d\n            // Header size: 1\n            // Code size: 2 (0x2)\n            .maxstack 8\n\n            IL_0000: ldnull\n            IL_0001: throw\n        } // end of method '<G>$847CB318C385471B1F4E7BD0A197DBCA'::set_Test\n\n        .method public hidebysig \n            instance void AddIfNotNull (\n                !$T0 item\n            ) cil managed \n        {\n            .custom instance void [System.Runtime]System.Runtime.CompilerServices.ExtensionMarkerAttribute::.ctor(string) = {\n                string('<M>$6A79ECC07A7731C57E8EB4E3D9C8B38B')\n            }\n            // Method begins at RVA 0x209d\n            // Header size: 1\n            // Code size: 2 (0x2)\n            .maxstack 8\n\n            IL_0000: ldnull\n            IL_0001: throw\n        } // end of method '<G>$847CB318C385471B1F4E7BD0A197DBCA'::AddIfNotNull\n\n        .method public hidebysig \n            instance !!T2 Cast<(!$T0) T2> (\n                int32 index\n            ) cil managed \n        {\n            .custom instance void [System.Runtime]System.Runtime.CompilerServices.ExtensionMarkerAttribute::.ctor(string) = {\n                string('<M>$6A79ECC07A7731C57E8EB4E3D9C8B38B')\n            }\n            .param type T2\n                .custom instance void [System.Runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = {\n                    uint8(0)\n                }\n            // Method begins at RVA 0x209d\n            // Header size: 1\n            // Code size: 2 (0x2)\n            .maxstack 8\n\n            IL_0000: ldnull\n            IL_0001: throw\n        } // end of method '<G>$847CB318C385471B1F4E7BD0A197DBCA'::Cast\n\n        .method public hidebysig static \n            void StaticExtension () cil managed \n        {\n            .custom instance void [System.Runtime]System.Runtime.CompilerServices.ExtensionMarkerAttribute::.ctor(string) = {\n                string('<M>$6A79ECC07A7731C57E8EB4E3D9C8B38B')\n            }\n            // Method begins at RVA 0x209d\n            // Header size: 1\n            // Code size: 2 (0x2)\n            .maxstack 8\n\n            IL_0000: ldnull\n            IL_0001: throw\n        } // end of method '<G>$847CB318C385471B1F4E7BD0A197DBCA'::StaticExtension\n\n        // Properties\n        .property instance bool IsEmpty()\n        {\n            .custom instance void [System.Runtime]System.Runtime.CompilerServices.ExtensionMarkerAttribute::.ctor(string) = {\n                string('<M>$6A79ECC07A7731C57E8EB4E3D9C8B38B')\n            }\n            .get instance bool ICSharpCode.Decompiler.Tests.TestCases.ILPretty.ExtensionPropertiesV2/'<G>$847CB318C385471B1F4E7BD0A197DBCA'::get_IsEmpty()\n        }\n        .property instance int32 Test()\n        {\n            .custom instance void [System.Runtime]System.Runtime.CompilerServices.ExtensionMarkerAttribute::.ctor(string) = {\n                string('<M>$6A79ECC07A7731C57E8EB4E3D9C8B38B')\n            }\n            .get instance int32 ICSharpCode.Decompiler.Tests.TestCases.ILPretty.ExtensionPropertiesV2/'<G>$847CB318C385471B1F4E7BD0A197DBCA'::get_Test()\n            .set instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.ExtensionPropertiesV2/'<G>$847CB318C385471B1F4E7BD0A197DBCA'::set_Test(int32)\n        }\n\n    } // end of class <G>$847CB318C385471B1F4E7BD0A197DBCA\n\n\n    // Methods\n    .method public hidebysig static \n        bool get_IsEmpty<T> (\n            class [System.Runtime]System.Collections.Generic.ICollection`1<!!T> collection\n        ) cil managed \n    {\n        // Method begins at RVA 0x2050\n        // Header size: 1\n        // Code size: 10 (0xa)\n        .maxstack 8\n\n        IL_0000: ldarg.0\n        IL_0001: callvirt instance int32 class [System.Runtime]System.Collections.Generic.ICollection`1<!!T>::get_Count()\n        IL_0006: ldc.i4.0\n        IL_0007: ceq\n        IL_0009: ret\n    } // end of method ExtensionPropertiesV2::get_IsEmpty\n\n    .method public hidebysig static \n        int32 get_Test<T> (\n            class [System.Runtime]System.Collections.Generic.ICollection`1<!!T> collection\n        ) cil managed \n    {\n        // Method begins at RVA 0x205b\n        // Header size: 1\n        // Code size: 4 (0x4)\n        .maxstack 8\n\n        IL_0000: nop\n        IL_0001: ldc.i4.s 42\n        IL_0003: ret\n    } // end of method ExtensionPropertiesV2::get_Test\n\n    .method public hidebysig static \n        void set_Test<T> (\n            class [System.Runtime]System.Collections.Generic.ICollection`1<!!T> collection,\n            int32 'value'\n        ) cil managed \n    {\n        // Method begins at RVA 0x2060\n        // Header size: 1\n        // Code size: 2 (0x2)\n        .maxstack 8\n\n        IL_0000: nop\n        IL_0001: ret\n    } // end of method ExtensionPropertiesV2::set_Test\n\n    .method public hidebysig static \n        void AddIfNotNull<T> (\n            class [System.Runtime]System.Collections.Generic.ICollection`1<!!T> collection,\n            !!T item\n        ) cil managed \n    {\n        .custom instance void [System.Runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = {\n        }\n        // Method begins at RVA 0x2064\n        // Header size: 12\n        // Code size: 25 (0x19)\n        .maxstack 2\n        .locals init (\n            [0] bool\n        )\n\n        IL_0000: nop\n        IL_0001: ldarg.1\n        IL_0002: box !!T\n        IL_0007: ldnull\n        IL_0008: cgt.un\n        IL_000a: stloc.0\n        IL_000b: ldloc.0\n        IL_000c: brfalse.s IL_0018\n\n        IL_000e: nop\n        IL_000f: ldarg.0\n        IL_0010: ldarg.1\n        IL_0011: callvirt instance void class [System.Runtime]System.Collections.Generic.ICollection`1<!!T>::Add(!0)\n        IL_0016: nop\n        IL_0017: nop\n\n        IL_0018: ret\n    } // end of method ExtensionPropertiesV2::AddIfNotNull\n\n    .method public hidebysig static \n        !!T2 Cast<T, (!!T) T2> (\n            class [System.Runtime]System.Collections.Generic.ICollection`1<!!T> collection,\n            int32 index\n        ) cil managed \n    {\n        .custom instance void [System.Runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = {\n        }\n        // Method begins at RVA 0x2089\n        // Header size: 1\n        // Code size: 19 (0x13)\n        .maxstack 8\n\n        IL_0000: nop\n        IL_0001: ldarg.0\n        IL_0002: ldarg.1\n        IL_0003: call !!0 [System.Linq]System.Linq.Enumerable::ElementAt<!!T>(class [System.Runtime]System.Collections.Generic.IEnumerable`1<!!0>, int32)\n        IL_0008: box !!T\n        IL_000d: unbox.any !!T2\n        IL_0012: ret\n    } // end of method ExtensionPropertiesV2::Cast\n\n    .method public hidebysig static \n        void StaticExtension<T> () cil managed \n    {\n        // Method begins at RVA 0x2060\n        // Header size: 1\n        // Code size: 2 (0x2)\n        .maxstack 8\n\n        IL_0000: nop\n        IL_0001: ret\n    } // end of method ExtensionPropertiesV2::StaticExtension\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.ExtensionPropertiesV2\n\n// references\n.assembly extern System.Runtime\n{\n    .publickeytoken = (\n        b0 3f 5f 7f 11 d5 0a 3a\n    )\n    .ver 10:0:0:0\n}\n.assembly extern System.Linq\n{\n    .publickeytoken = (\n        b0 3f 5f 7f 11 d5 0a 3a\n    )\n    .ver 10:0:0:0\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops.fs",
    "content": "open System\n\nlet disposable() = { new IDisposable with member x.Dispose() = () }\n\nlet getSeq() = seq { yield 1; }\nlet getList() = [ 1 ]\nlet getArray() = [| 1 |]\n\n[<EntryPoint>]\nlet main argv =\n\n    // nested using scopes?\n    use disp1 =\n        use disp2 = disposable()\n        Console.WriteLine \"Hello 1\"\n        disposable()\n    \n    // for loop over seq\n    for i in getSeq() do\n        Console.WriteLine i\n        \n    // for loop over list\n    for i in getList() do\n        Console.WriteLine i\n        \n    // for loop over array\n    for i in getArray() do\n        Console.WriteLine i\n        \n    0 // return an integer exit code"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Debug.cs",
    "content": "// C:\\Users\\Siegfried\\Documents\\Visual Studio 2017\\Projects\\ConsoleApp13\\ConsoleApplication1\\bin\\Debug\\ConsoleApplication1.exe\n// ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null\n// Global type: <Module>\n// Entry point: Program.main\n// Architecture: AnyCPU (32-bit preferred)\n// Runtime: .NET 4.0\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\nusing Microsoft.FSharp.Collections;\nusing Microsoft.FSharp.Core;\nusing Microsoft.FSharp.Core.CompilerServices;\n\n[assembly: FSharpInterfaceDataVersion(2, 0, 0)]\n[assembly: AssemblyTitle(\"ConsoleApplication1\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"ConsoleApplication1\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2017\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n[assembly: ComVisible(false)]\n[assembly: Guid(\"e0674ff5-5e8f-4d4e-a88f-e447192454c7\")]\n[CompilationMapping(SourceConstructFlags.Module)]\npublic static class Program\n{\n\t[Serializable]\n\t[SpecialName]\n\t[CompilationMapping(SourceConstructFlags.Closure)]\n\tinternal sealed class disposable_00403 : IDisposable\n\t{\n\t\tprivate void System_002DIDisposable_002DDispose()\n\t\t{\n\t\t}\n\n\t\tvoid IDisposable.Dispose()\n\t\t{\n\t\t\t//ILSpy generated this explicit interface implementation from .override directive in System-IDisposable-Dispose\n\t\t\tthis.System_002DIDisposable_002DDispose();\n\t\t}\n\t}\n\n\t[Serializable]\n\t[SpecialName]\n\t[CompilationMapping(SourceConstructFlags.Closure)]\n\tinternal sealed class getSeq_00405(int pc, int current) : GeneratedSequenceBase<int>\n\t{\n\t\t[DebuggerNonUserCode]\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\t[CompilerGenerated]\n\t\tpublic int pc = pc;\n\n\t\t[DebuggerNonUserCode]\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\t[CompilerGenerated]\n\t\tpublic int current = current;\n\n\t\tpublic override int GenerateNext(ref IEnumerable<int> next)\n\t\t{\n\t\t\tswitch (pc)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\tpc = 1;\n\t\t\t\t\tcurrent = 1;\n\t\t\t\t\treturn 1;\n\t\t\t\tcase 1:\n\t\t\t\t\tpc = 2;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcurrent = 0;\n\t\t\treturn 0;\n\t\t}\n\n\t\tpublic override void Close()\n\t\t{\n\t\t\tpc = 2;\n\t\t}\n\n\t\tpublic bool get_CheckClose()\n\t\t{\n\t\t\tswitch (pc)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t\tcase 0:\n\t\t\t\tcase 2:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t[DebuggerNonUserCode]\n\t\t[CompilerGenerated]\n\t\tpublic int get_LastGenerated()\n\t\t{\n\t\t\treturn current;\n\t\t}\n\n\t\t[DebuggerNonUserCode]\n\t\t[CompilerGenerated]\n\t\tpublic override IEnumerator<int> GetFreshEnumerator()\n\t\t{\n\t\t\treturn new getSeq_00405(0, 0);\n\t\t}\n\t}\n\n\tpublic static IDisposable disposable()\n\t{\n\t\treturn new disposable_00403();\n\t}\n\n\tpublic static IEnumerable<int> getSeq()\n\t{\n\t\treturn new getSeq_00405(0, 0);\n\t}\n\n\tpublic static FSharpList<int> getList()\n\t{\n\t\treturn FSharpList<int>.Cons(1, FSharpList<int>.Empty);\n\t}\n\n\tpublic static int[] getArray()\n\t{\n\t\treturn new int[1] { 1 };\n\t}\n\n\t[EntryPoint]\n\tpublic static int main(string[] argv)\n\t{\n\t\tIDisposable disposable;\n\t\tusing (Program.disposable())\n\t\t{\n\t\t\tConsole.WriteLine(\"Hello 1\");\n\t\t\tdisposable = Program.disposable();\n\t\t}\n\t\tusing (disposable)\n\t\t{\n\t\t\tIEnumerable<int> seq = getSeq();\n\t\t\tforeach (int item in seq)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(item);\n\t\t\t}\n\t\t\tFSharpList<int> fSharpList = getList();\n\t\t\tfor (FSharpList<int> tailOrNull = fSharpList.TailOrNull; tailOrNull != null; tailOrNull = fSharpList.TailOrNull)\n\t\t\t{\n\t\t\t\tint headOrDefault = fSharpList.HeadOrDefault;\n\t\t\t\tConsole.WriteLine(headOrDefault);\n\t\t\t\tfSharpList = tailOrNull;\n\t\t\t}\n\t\t\tint[] array = getArray();\n\t\t\tforeach (int value in array)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(value);\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\t}\n}\nnamespace _003CStartupCode_0024ConsoleApplication1_003E\n{\n\tinternal static class _0024AssemblyInfo\n\t{\n\t}\n\tinternal static class _0024Program\n\t{\n\t}\n}\nnamespace _003CStartupCode_0024ConsoleApplication1_003E._0024.NETFramework_002CVersion_003Dv4._6._1\n{\n\tinternal static class AssemblyAttributes\n\t{\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Debug.il",
    "content": "// C:\\Users\\Siegfried\\Documents\\Visual Studio 2017\\Projects\\ConsoleApp13\\ConsoleApplication1\\bin\\Debug\\ConsoleApplication1.exe\n\n.assembly extern mscorlib\n{\n\t.publickeytoken = (\n\t\tb7 7a 5c 56 19 34 e0 89\n\t)\n\t.ver 4:0:0:0\n}\n.assembly extern FSharp.Core\n{\n\t.publickeytoken = (\n\t\tb0 3f 5f 7f 11 d5 0a 3a\n\t)\n\t.ver 4:4:1:0\n}\n.assembly ConsoleApplication1\n{\n\t.custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, int32, int32) = (\n\t\t01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00\n\t)\n\t.custom instance void [mscorlib]System.Runtime.Versioning.TargetFrameworkAttribute::.ctor(string) = (\n\t\t01 00 1c 2e 4e 45 54 46 72 61 6d 65 77 6f 72 6b\n\t\t2c 56 65 72 73 69 6f 6e 3d 76 34 2e 36 2e 31 01\n\t\t00 54 0e 14 46 72 61 6d 65 77 6f 72 6b 44 69 73\n\t\t70 6c 61 79 4e 61 6d 65 14 2e 4e 45 54 20 46 72\n\t\t61 6d 65 77 6f 72 6b 20 34 2e 36 2e 31\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyTitleAttribute::.ctor(string) = (\n\t\t01 00 13 43 6f 6e 73 6f 6c 65 41 70 70 6c 69 63\n\t\t61 74 69 6f 6e 31 00 00\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyDescriptionAttribute::.ctor(string) = (\n\t\t01 00 00 00 00\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyConfigurationAttribute::.ctor(string) = (\n\t\t01 00 00 00 00\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyCompanyAttribute::.ctor(string) = (\n\t\t01 00 00 00 00\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyProductAttribute::.ctor(string) = (\n\t\t01 00 13 43 6f 6e 73 6f 6c 65 41 70 70 6c 69 63\n\t\t61 74 69 6f 6e 31 00 00\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyCopyrightAttribute::.ctor(string) = (\n\t\t01 00 12 43 6f 70 79 72 69 67 68 74 20 c2 a9 20\n\t\t20 32 30 31 37 00 00\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyTrademarkAttribute::.ctor(string) = (\n\t\t01 00 00 00 00\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyCultureAttribute::.ctor(string) = (\n\t\t01 00 00 00 00\n\t)\n\t.custom instance void [mscorlib]System.Runtime.InteropServices.ComVisibleAttribute::.ctor(bool) = (\n\t\t01 00 00 00 00\n\t)\n\t.custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = (\n\t\t01 00 24 65 30 36 37 34 66 66 35 2d 35 65 38 66\n\t\t2d 34 64 34 65 2d 61 38 38 66 2d 65 34 34 37 31\n\t\t39 32 34 35 34 63 37 00 00\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyVersionAttribute::.ctor(string) = (\n\t\t01 00 07 31 2e 30 2e 30 2e 30 00 00\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = (\n\t\t01 00 07 31 2e 30 2e 30 2e 30 00 00\n\t)\n\t.custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = (\n\t\t01 00 01 01 00 00 00 00\n\t)\n\t.hash algorithm 0x00008004 // SHA1\n\t.ver 1:0:0:0\n}\n\n.module ConsoleApplication1.exe\n// MVID: {59F64D20-6A1F-D4CE-A745-0383204DF659}\n.corflags 0x00020003 // ILOnly, Required32Bit, Preferred32Bit\n\n\n.class private auto ansi '<Module>'\n\textends [mscorlib]System.Object\n{\n} // end of class <Module>\n\n.class public auto ansi abstract sealed Program\n\textends [mscorlib]System.Object\n{\n\t.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (\n\t\t01 00 07 00 00 00 00 00\n\t)\n\t// Nested Types\n\t.class nested assembly auto auto sealed specialname serializable beforefieldinit disposable@3\n\t\textends [mscorlib]System.Object\n\t\timplements [mscorlib]System.IDisposable\n\t{\n\t\t.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (\n\t\t\t01 00 06 00 00 00 00 00\n\t\t)\n\t\t// Methods\n\t\t.method public specialname rtspecialname \n\t\t\tinstance void .ctor () cil managed \n\t\t{\n\t\t\t// Method begins at RVA 0x21c8\n\t\t\t// Code size 9 (0x9)\n\t\t\t.maxstack 8\n\n\t\t\tIL_0000: ldarg.0\n\t\t\tIL_0001: callvirt instance void [mscorlib]System.Object::.ctor()\n\t\t\tIL_0006: ldarg.0\n\t\t\tIL_0007: pop\n\t\t\tIL_0008: ret\n\t\t} // end of method disposable@3::.ctor\n\n\t\t.method private final hidebysig newslot virtual \n\t\t\tinstance void 'System-IDisposable-Dispose' () cil managed \n\t\t{\n\t\t\t.override method instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\t// Method begins at RVA 0x21d4\n\t\t\t// Code size 1 (0x1)\n\t\t\t.maxstack 8\n\n\t\t\tIL_0000: ret\n\t\t} // end of method disposable@3::'System-IDisposable-Dispose'\n\n\t} // end of class disposable@3\n\n\t.class nested assembly auto auto sealed specialname serializable beforefieldinit getSeq@5\n\t\textends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1<int32>\n\t{\n\t\t.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (\n\t\t\t01 00 06 00 00 00 00 00\n\t\t)\n\t\t// Fields\n\t\t.field public int32 pc\n\t\t.custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = (\n\t\t\t01 00 00 00 00 00 00 00\n\t\t)\n\t\t.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n\t\t\t01 00 00 00\n\t\t)\n\t\t.custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = (\n\t\t\t01 00 00 00\n\t\t)\n\t\t.field public int32 current\n\t\t.custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = (\n\t\t\t01 00 00 00 00 00 00 00\n\t\t)\n\t\t.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n\t\t\t01 00 00 00\n\t\t)\n\t\t.custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = (\n\t\t\t01 00 00 00\n\t\t)\n\n\t\t// Methods\n\t\t.method public specialname rtspecialname \n\t\t\tinstance void .ctor (\n\t\t\t\tint32 pc,\n\t\t\t\tint32 current\n\t\t\t) cil managed \n\t\t{\n\t\t\t// Method begins at RVA 0x21d8\n\t\t\t// Code size 21 (0x15)\n\t\t\t.maxstack 8\n\n\t\t\tIL_0000: ldarg.0\n\t\t\tIL_0001: ldarg.1\n\t\t\tIL_0002: stfld int32 Program/getSeq@5::pc\n\t\t\tIL_0007: ldarg.0\n\t\t\tIL_0008: ldarg.2\n\t\t\tIL_0009: stfld int32 Program/getSeq@5::current\n\t\t\tIL_000e: ldarg.0\n\t\t\tIL_000f: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1<int32>::.ctor()\n\t\t\tIL_0014: ret\n\t\t} // end of method getSeq@5::.ctor\n\n\t\t.method public strict virtual \n\t\t\tinstance int32 GenerateNext (\n\t\t\t\tclass [mscorlib]System.Collections.Generic.IEnumerable`1<int32>& next\n\t\t\t) cil managed \n\t\t{\n\t\t\t// Method begins at RVA 0x21f0\n\t\t\t// Code size 66 (0x42)\n\t\t\t.maxstack 6\n\n\t\t\tIL_0000: ldarg.0\n\t\t\tIL_0001: ldfld int32 Program/getSeq@5::pc\n\t\t\tIL_0006: ldc.i4.1\n\t\t\tIL_0007: sub\n\t\t\tIL_0008: switch (IL_0017, IL_0019)\n\n\t\t\tIL_0015: br.s IL_0021\n\n\t\t\tIL_0017: br.s IL_001b\n\n\t\t\tIL_0019: br.s IL_001e\n\n\t\t\tIL_001b: nop\n\t\t\tIL_001c: br.s IL_0032\n\n\t\t\tIL_001e: nop\n\t\t\tIL_001f: br.s IL_0039\n\n\t\t\tIL_0021: nop\n\t\t\tIL_0022: ldarg.0\n\t\t\tIL_0023: ldc.i4.1\n\t\t\tIL_0024: stfld int32 Program/getSeq@5::pc\n\t\t\tIL_0029: ldarg.0\n\t\t\tIL_002a: ldc.i4.1\n\t\t\tIL_002b: stfld int32 Program/getSeq@5::current\n\t\t\tIL_0030: ldc.i4.1\n\t\t\tIL_0031: ret\n\n\t\t\tIL_0032: ldarg.0\n\t\t\tIL_0033: ldc.i4.2\n\t\t\tIL_0034: stfld int32 Program/getSeq@5::pc\n\n\t\t\tIL_0039: ldarg.0\n\t\t\tIL_003a: ldc.i4.0\n\t\t\tIL_003b: stfld int32 Program/getSeq@5::current\n\t\t\tIL_0040: ldc.i4.0\n\t\t\tIL_0041: ret\n\t\t} // end of method getSeq@5::GenerateNext\n\n\t\t.method public strict virtual \n\t\t\tinstance void Close () cil managed \n\t\t{\n\t\t\t// Method begins at RVA 0x2240\n\t\t\t// Code size 8 (0x8)\n\t\t\t.maxstack 8\n\n\t\t\tIL_0000: ldarg.0\n\t\t\tIL_0001: ldc.i4.2\n\t\t\tIL_0002: stfld int32 Program/getSeq@5::pc\n\t\t\tIL_0007: ret\n\t\t} // end of method getSeq@5::Close\n\n\t\t.method public strict virtual \n\t\t\tinstance bool get_CheckClose () cil managed \n\t\t{\n\t\t\t// Method begins at RVA 0x224c\n\t\t\t// Code size 45 (0x2d)\n\t\t\t.maxstack 8\n\n\t\t\tIL_0000: ldarg.0\n\t\t\tIL_0001: ldfld int32 Program/getSeq@5::pc\n\t\t\tIL_0006: switch (IL_0019, IL_001b, IL_001d)\n\n\t\t\tIL_0017: br.s IL_0028\n\n\t\t\tIL_0019: br.s IL_001f\n\n\t\t\tIL_001b: br.s IL_0022\n\n\t\t\tIL_001d: br.s IL_0025\n\n\t\t\tIL_001f: nop\n\t\t\tIL_0020: br.s IL_002b\n\n\t\t\tIL_0022: nop\n\t\t\tIL_0023: br.s IL_0029\n\n\t\t\tIL_0025: nop\n\t\t\tIL_0026: br.s IL_002b\n\n\t\t\tIL_0028: nop\n\n\t\t\tIL_0029: ldc.i4.0\n\t\t\tIL_002a: ret\n\n\t\t\tIL_002b: ldc.i4.0\n\t\t\tIL_002c: ret\n\t\t} // end of method getSeq@5::get_CheckClose\n\n\t\t.method public strict virtual \n\t\t\tinstance int32 get_LastGenerated () cil managed \n\t\t{\n\t\t\t.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n\t\t\t\t01 00 00 00\n\t\t\t)\n\t\t\t.custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = (\n\t\t\t\t01 00 00 00\n\t\t\t)\n\t\t\t// Method begins at RVA 0x227c\n\t\t\t// Code size 7 (0x7)\n\t\t\t.maxstack 8\n\n\t\t\tIL_0000: ldarg.0\n\t\t\tIL_0001: ldfld int32 Program/getSeq@5::current\n\t\t\tIL_0006: ret\n\t\t} // end of method getSeq@5::get_LastGenerated\n\n\t\t.method public strict virtual \n\t\t\tinstance class [mscorlib]System.Collections.Generic.IEnumerator`1<int32> GetFreshEnumerator () cil managed \n\t\t{\n\t\t\t.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n\t\t\t\t01 00 00 00\n\t\t\t)\n\t\t\t.custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = (\n\t\t\t\t01 00 00 00\n\t\t\t)\n\t\t\t// Method begins at RVA 0x2284\n\t\t\t// Code size 8 (0x8)\n\t\t\t.maxstack 8\n\n\t\t\tIL_0000: ldc.i4.0\n\t\t\tIL_0001: ldc.i4.0\n\t\t\tIL_0002: newobj instance void Program/getSeq@5::.ctor(int32, int32)\n\t\t\tIL_0007: ret\n\t\t} // end of method getSeq@5::GetFreshEnumerator\n\n\t} // end of class getSeq@5\n\n\n\t// Methods\n\t.method public static \n\t\tclass [mscorlib]System.IDisposable disposable () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 6 (0x6)\n\t\t.maxstack 8\n\n\t\tIL_0000: newobj instance void Program/disposable@3::.ctor()\n\t\tIL_0005: ret\n\t} // end of method Program::disposable\n\n\t.method public static \n\t\tclass [mscorlib]System.Collections.Generic.IEnumerable`1<int32> getSeq () cil managed \n\t{\n\t\t// Method begins at RVA 0x2058\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldc.i4.0\n\t\tIL_0001: ldc.i4.0\n\t\tIL_0002: newobj instance void Program/getSeq@5::.ctor(int32, int32)\n\t\tIL_0007: ret\n\t} // end of method Program::getSeq\n\n\t.method public static \n\t\tclass [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> getList () cil managed \n\t{\n\t\t// Method begins at RVA 0x2064\n\t\t// Code size 12 (0xc)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldc.i4.1\n\t\tIL_0001: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_Empty()\n\t\tIL_0006: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0>)\n\t\tIL_000b: ret\n\t} // end of method Program::getList\n\n\t.method public static \n\t\tint32[] getArray () cil managed \n\t{\n\t\t// Method begins at RVA 0x2074\n\t\t// Code size 15 (0xf)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldc.i4.1\n\t\tIL_0001: newarr [mscorlib]System.Int32\n\t\tIL_0006: dup\n\t\tIL_0007: ldc.i4.0\n\t\tIL_0008: ldc.i4.1\n\t\tIL_0009: stelem.any [mscorlib]System.Int32\n\t\tIL_000e: ret\n\t} // end of method Program::getArray\n\n\t.method public static \n\t\tint32 main (\n\t\t\tstring[] argv\n\t\t) cil managed \n\t{\n\t\t.custom instance void [FSharp.Core]Microsoft.FSharp.Core.EntryPointAttribute::.ctor() = (\n\t\t\t01 00 00 00\n\t\t)\n\t\t// Method begins at RVA 0x2084\n\t\t// Code size 270 (0x10e)\n\t\t.maxstack 4\n\t\t.entrypoint\n\t\t.locals init (\n\t\t\t[0] class [mscorlib]System.IDisposable,\n\t\t\t[1] class [mscorlib]System.IDisposable,\n\t\t\t[2] class [mscorlib]System.IDisposable,\n\t\t\t[3] class [mscorlib]System.IDisposable,\n\t\t\t[4] int32,\n\t\t\t[5] class [mscorlib]System.Collections.Generic.IEnumerable`1<int32>,\n\t\t\t[6] class [mscorlib]System.Collections.Generic.IEnumerator`1<int32>,\n\t\t\t[7] class [FSharp.Core]Microsoft.FSharp.Core.Unit,\n\t\t\t[8] int32,\n\t\t\t[9] class [mscorlib]System.IDisposable,\n\t\t\t[10] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>,\n\t\t\t[11] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>,\n\t\t\t[12] int32,\n\t\t\t[13] int32[],\n\t\t\t[14] int32,\n\t\t\t[15] int32,\n\t\t\t[16] class [mscorlib]System.IDisposable\n\t\t)\n\n\t\tIL_0000: call class [mscorlib]System.IDisposable Program::disposable()\n\t\tIL_0005: stloc.1\n\t\t.try\n\t\t{\n\t\t\tIL_0006: ldstr \"Hello 1\"\n\t\t\tIL_000b: call void [mscorlib]System.Console::WriteLine(string)\n\t\t\tIL_0010: call class [mscorlib]System.IDisposable Program::disposable()\n\t\t\tIL_0015: stloc.2\n\t\t\tIL_0016: leave.s IL_0032\n\t\t} // end .try\n\t\tfinally\n\t\t{\n\t\t\tIL_0018: ldloc.1\n\t\t\tIL_0019: isinst [mscorlib]System.IDisposable\n\t\t\tIL_001e: stloc.3\n\t\t\tIL_001f: ldloc.3\n\t\t\tIL_0020: brfalse.s IL_0024\n\n\t\t\tIL_0022: br.s IL_0026\n\n\t\t\tIL_0024: br.s IL_002f\n\n\t\t\tIL_0026: ldloc.3\n\t\t\tIL_0027: callvirt instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\tIL_002c: ldnull\n\t\t\tIL_002d: pop\n\t\t\tIL_002e: endfinally\n\n\t\t\tIL_002f: ldnull\n\t\t\tIL_0030: pop\n\t\t\tIL_0031: endfinally\n\t\t} // end handler\n\n\t\tIL_0032: ldloc.2\n\t\tIL_0033: stloc.0\n\t\t.try\n\t\t{\n\t\t\tIL_0034: call class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> Program::getSeq()\n\t\t\tIL_0039: stloc.s 5\n\t\t\tIL_003b: ldloc.s 5\n\t\t\tIL_003d: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> class [mscorlib]System.Collections.Generic.IEnumerable`1<int32>::GetEnumerator()\n\t\t\tIL_0042: stloc.s 6\n\t\t\t.try\n\t\t\t{\n\t\t\t\t// loop start (head: IL_0044)\n\t\t\t\t\tIL_0044: ldloc.s 6\n\t\t\t\t\tIL_0046: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()\n\t\t\t\t\tIL_004b: brfalse.s IL_0060\n\n\t\t\t\t\tIL_004d: ldloc.s 6\n\t\t\t\t\tIL_004f: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1<int32>::get_Current()\n\t\t\t\t\tIL_0054: stloc.s 8\n\t\t\t\t\tIL_0056: ldloc.s 8\n\t\t\t\t\tIL_0058: call void [mscorlib]System.Console::WriteLine(int32)\n\t\t\t\t\tIL_005d: nop\n\t\t\t\t\tIL_005e: br.s IL_0044\n\t\t\t\t// end loop\n\n\t\t\t\tIL_0060: ldnull\n\t\t\t\tIL_0061: stloc.s 7\n\t\t\t\tIL_0063: leave.s IL_0083\n\t\t\t} // end .try\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tIL_0065: ldloc.s 6\n\t\t\t\tIL_0067: isinst [mscorlib]System.IDisposable\n\t\t\t\tIL_006c: stloc.s 9\n\t\t\t\tIL_006e: ldloc.s 9\n\t\t\t\tIL_0070: brfalse.s IL_0074\n\n\t\t\t\tIL_0072: br.s IL_0076\n\n\t\t\t\tIL_0074: br.s IL_0080\n\n\t\t\t\tIL_0076: ldloc.s 9\n\t\t\t\tIL_0078: callvirt instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\t\tIL_007d: ldnull\n\t\t\t\tIL_007e: pop\n\t\t\t\tIL_007f: endfinally\n\n\t\t\t\tIL_0080: ldnull\n\t\t\t\tIL_0081: pop\n\t\t\t\tIL_0082: endfinally\n\t\t\t} // end handler\n\n\t\t\tIL_0083: ldloc.s 7\n\t\t\tIL_0085: pop\n\t\t\tIL_0086: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> Program::getList()\n\t\t\tIL_008b: stloc.s 10\n\t\t\tIL_008d: ldloc.s 10\n\t\t\tIL_008f: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_TailOrNull()\n\t\t\tIL_0094: stloc.s 11\n\t\t\t// loop start (head: IL_0096)\n\t\t\t\tIL_0096: ldloc.s 11\n\t\t\t\tIL_0098: ldnull\n\t\t\t\tIL_0099: cgt.un\n\t\t\t\tIL_009b: brfalse.s IL_00bd\n\n\t\t\t\tIL_009d: ldloc.s 10\n\t\t\t\tIL_009f: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_HeadOrDefault()\n\t\t\t\tIL_00a4: stloc.s 12\n\t\t\t\tIL_00a6: ldloc.s 12\n\t\t\t\tIL_00a8: call void [mscorlib]System.Console::WriteLine(int32)\n\t\t\t\tIL_00ad: ldloc.s 11\n\t\t\t\tIL_00af: stloc.s 10\n\t\t\t\tIL_00b1: ldloc.s 10\n\t\t\t\tIL_00b3: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_TailOrNull()\n\t\t\t\tIL_00b8: stloc.s 11\n\t\t\t\tIL_00ba: nop\n\t\t\t\tIL_00bb: br.s IL_0096\n\t\t\t// end loop\n\n\t\t\tIL_00bd: call int32[] Program::getArray()\n\t\t\tIL_00c2: stloc.s 13\n\t\t\tIL_00c4: ldc.i4.0\n\t\t\tIL_00c5: stloc.s 14\n\t\t\tIL_00c7: br.s IL_00e1\n\t\t\t// loop start (head: IL_00e1)\n\t\t\t\tIL_00c9: ldloc.s 13\n\t\t\t\tIL_00cb: ldloc.s 14\n\t\t\t\tIL_00cd: ldelem.any [mscorlib]System.Int32\n\t\t\t\tIL_00d2: stloc.s 15\n\t\t\t\tIL_00d4: ldloc.s 15\n\t\t\t\tIL_00d6: call void [mscorlib]System.Console::WriteLine(int32)\n\t\t\t\tIL_00db: ldloc.s 14\n\t\t\t\tIL_00dd: ldc.i4.1\n\t\t\t\tIL_00de: add\n\t\t\t\tIL_00df: stloc.s 14\n\n\t\t\t\tIL_00e1: ldloc.s 14\n\t\t\t\tIL_00e3: ldloc.s 13\n\t\t\t\tIL_00e5: ldlen\n\t\t\t\tIL_00e6: conv.i4\n\t\t\t\tIL_00e7: blt.s IL_00c9\n\t\t\t// end loop\n\n\t\t\tIL_00e9: ldc.i4.0\n\t\t\tIL_00ea: stloc.s 4\n\t\t\tIL_00ec: leave.s IL_010b\n\t\t} // end .try\n\t\tfinally\n\t\t{\n\t\t\tIL_00ee: ldloc.0\n\t\t\tIL_00ef: isinst [mscorlib]System.IDisposable\n\t\t\tIL_00f4: stloc.s 16\n\t\t\tIL_00f6: ldloc.s 16\n\t\t\tIL_00f8: brfalse.s IL_00fc\n\n\t\t\tIL_00fa: br.s IL_00fe\n\n\t\t\tIL_00fc: br.s IL_0108\n\n\t\t\tIL_00fe: ldloc.s 16\n\t\t\tIL_0100: callvirt instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\tIL_0105: ldnull\n\t\t\tIL_0106: pop\n\t\t\tIL_0107: endfinally\n\n\t\t\tIL_0108: ldnull\n\t\t\tIL_0109: pop\n\t\t\tIL_010a: endfinally\n\t\t} // end handler\n\n\t\tIL_010b: ldloc.s 4\n\t\tIL_010d: ret\n\t} // end of method Program::main\n\n} // end of class Program\n\n.class private auto ansi abstract sealed '<StartupCode$ConsoleApplication1>.$Program'\n\textends [mscorlib]System.Object\n{\n} // end of class <StartupCode$ConsoleApplication1>.$Program\n\n.class private auto ansi abstract sealed '<StartupCode$ConsoleApplication1>.$AssemblyInfo'\n\textends [mscorlib]System.Object\n{\n} // end of class <StartupCode$ConsoleApplication1>.$AssemblyInfo\n\n.class private auto ansi abstract sealed '<StartupCode$ConsoleApplication1>.$.NETFramework,Version=v4.6.1.AssemblyAttributes'\n\textends [mscorlib]System.Object\n{\n} // end of class <StartupCode$ConsoleApplication1>.$.NETFramework,Version=v4.6.1.AssemblyAttributes\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Release.cs",
    "content": "// C:\\Users\\Siegfried\\Documents\\Visual Studio 2017\\Projects\\ConsoleApp13\\ConsoleApplication1\\bin\\Release\\ConsoleApplication1.exe\n// ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null\n// Global type: <Module>\n// Entry point: Program.main\n// Architecture: AnyCPU (32-bit preferred)\n// Runtime: .NET 4.0\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\nusing Microsoft.FSharp.Collections;\nusing Microsoft.FSharp.Core;\nusing Microsoft.FSharp.Core.CompilerServices;\n\n[assembly: FSharpInterfaceDataVersion(2, 0, 0)]\n[assembly: AssemblyTitle(\"ConsoleApplication1\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"ConsoleApplication1\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2017\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n[assembly: ComVisible(false)]\n[assembly: Guid(\"e0674ff5-5e8f-4d4e-a88f-e447192454c7\")]\n[CompilationMapping(SourceConstructFlags.Module)]\npublic static class Program\n{\n\t[Serializable]\n\t[SpecialName]\n\t[CompilationMapping(SourceConstructFlags.Closure)]\n\tinternal sealed class disposable_00403 : IDisposable\n\t{\n\t\tprivate void System_002DIDisposable_002DDispose()\n\t\t{\n\t\t}\n\n\t\tvoid IDisposable.Dispose()\n\t\t{\n\t\t\t//ILSpy generated this explicit interface implementation from .override directive in System-IDisposable-Dispose\n\t\t\tthis.System_002DIDisposable_002DDispose();\n\t\t}\n\t}\n\n\t[Serializable]\n\t[SpecialName]\n\t[CompilationMapping(SourceConstructFlags.Closure)]\n\tinternal sealed class getSeq_00405(int pc, int current) : GeneratedSequenceBase<int>\n\t{\n\t\t[DebuggerNonUserCode]\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\t[CompilerGenerated]\n\t\tpublic int pc = pc;\n\n\t\t[DebuggerNonUserCode]\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n\t\t[CompilerGenerated]\n\t\tpublic int current = current;\n\n\t\tpublic override int GenerateNext(ref IEnumerable<int> next)\n\t\t{\n\t\t\tswitch (pc)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\tpc = 1;\n\t\t\t\t\tcurrent = 1;\n\t\t\t\t\treturn 1;\n\t\t\t\tcase 1:\n\t\t\t\t\tpc = 2;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcurrent = 0;\n\t\t\treturn 0;\n\t\t}\n\n\t\tpublic override void Close()\n\t\t{\n\t\t\tpc = 2;\n\t\t}\n\n\t\tpublic bool get_CheckClose()\n\t\t{\n\t\t\tswitch (pc)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t\tcase 0:\n\t\t\t\tcase 2:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t[DebuggerNonUserCode]\n\t\t[CompilerGenerated]\n\t\tpublic int get_LastGenerated()\n\t\t{\n\t\t\treturn current;\n\t\t}\n\n\t\t[DebuggerNonUserCode]\n\t\t[CompilerGenerated]\n\t\tpublic override IEnumerator<int> GetFreshEnumerator()\n\t\t{\n\t\t\treturn new getSeq_00405(0, 0);\n\t\t}\n\t}\n\n\tpublic static IDisposable disposable()\n\t{\n\t\treturn new disposable_00403();\n\t}\n\n\tpublic static IEnumerable<int> getSeq()\n\t{\n\t\treturn new getSeq_00405(0, 0);\n\t}\n\n\tpublic static FSharpList<int> getList()\n\t{\n\t\treturn FSharpList<int>.Cons(1, FSharpList<int>.Empty);\n\t}\n\n\tpublic static int[] getArray()\n\t{\n\t\treturn new int[1] { 1 };\n\t}\n\n\t[EntryPoint]\n\tpublic static int main(string[] argv)\n\t{\n\t\tIDisposable disposable;\n\t\tusing (Program.disposable())\n\t\t{\n\t\t\tConsole.WriteLine(\"Hello 1\");\n\t\t\tdisposable = Program.disposable();\n\t\t}\n\t\tusing (disposable)\n\t\t{\n\t\t\tIEnumerable<int> seq = getSeq();\n\t\t\tforeach (int item in seq)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(item);\n\t\t\t}\n\t\t\tFSharpList<int> fSharpList = FSharpList<int>.Cons(1, FSharpList<int>.Empty);\n\t\t\tfor (FSharpList<int> tailOrNull = fSharpList.TailOrNull; tailOrNull != null; tailOrNull = fSharpList.TailOrNull)\n\t\t\t{\n\t\t\t\tint headOrDefault = fSharpList.HeadOrDefault;\n\t\t\t\tConsole.WriteLine(headOrDefault);\n\t\t\t\tfSharpList = tailOrNull;\n\t\t\t}\n\t\t\tint[] array = new int[1] { 1 };\n\t\t\tfor (int headOrDefault = 0; headOrDefault < array.Length; headOrDefault++)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(array[headOrDefault]);\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\t}\n}\nnamespace _003CStartupCode_0024ConsoleApplication1_003E\n{\n\tinternal static class _0024AssemblyInfo\n\t{\n\t}\n\tinternal static class _0024Program\n\t{\n\t}\n}\nnamespace _003CStartupCode_0024ConsoleApplication1_003E._0024.NETFramework_002CVersion_003Dv4._6._1\n{\n\tinternal static class AssemblyAttributes\n\t{\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpLoops_Release.il",
    "content": "// C:\\Users\\Siegfried\\Documents\\Visual Studio 2017\\Projects\\ConsoleApp13\\ConsoleApplication1\\bin\\Release\\ConsoleApplication1.exe\n\n.assembly extern mscorlib\n{\n\t.publickeytoken = (\n\t\tb7 7a 5c 56 19 34 e0 89\n\t)\n\t.ver 4:0:0:0\n}\n.assembly extern FSharp.Core\n{\n\t.publickeytoken = (\n\t\tb0 3f 5f 7f 11 d5 0a 3a\n\t)\n\t.ver 4:4:1:0\n}\n.assembly ConsoleApplication1\n{\n\t.custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, int32, int32) = (\n\t\t01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00\n\t)\n\t.custom instance void [mscorlib]System.Runtime.Versioning.TargetFrameworkAttribute::.ctor(string) = (\n\t\t01 00 1c 2e 4e 45 54 46 72 61 6d 65 77 6f 72 6b\n\t\t2c 56 65 72 73 69 6f 6e 3d 76 34 2e 36 2e 31 01\n\t\t00 54 0e 14 46 72 61 6d 65 77 6f 72 6b 44 69 73\n\t\t70 6c 61 79 4e 61 6d 65 14 2e 4e 45 54 20 46 72\n\t\t61 6d 65 77 6f 72 6b 20 34 2e 36 2e 31\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyTitleAttribute::.ctor(string) = (\n\t\t01 00 13 43 6f 6e 73 6f 6c 65 41 70 70 6c 69 63\n\t\t61 74 69 6f 6e 31 00 00\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyDescriptionAttribute::.ctor(string) = (\n\t\t01 00 00 00 00\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyConfigurationAttribute::.ctor(string) = (\n\t\t01 00 00 00 00\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyCompanyAttribute::.ctor(string) = (\n\t\t01 00 00 00 00\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyProductAttribute::.ctor(string) = (\n\t\t01 00 13 43 6f 6e 73 6f 6c 65 41 70 70 6c 69 63\n\t\t61 74 69 6f 6e 31 00 00\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyCopyrightAttribute::.ctor(string) = (\n\t\t01 00 12 43 6f 70 79 72 69 67 68 74 20 c2 a9 20\n\t\t20 32 30 31 37 00 00\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyTrademarkAttribute::.ctor(string) = (\n\t\t01 00 00 00 00\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyCultureAttribute::.ctor(string) = (\n\t\t01 00 00 00 00\n\t)\n\t.custom instance void [mscorlib]System.Runtime.InteropServices.ComVisibleAttribute::.ctor(bool) = (\n\t\t01 00 00 00 00\n\t)\n\t.custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = (\n\t\t01 00 24 65 30 36 37 34 66 66 35 2d 35 65 38 66\n\t\t2d 34 64 34 65 2d 61 38 38 66 2d 65 34 34 37 31\n\t\t39 32 34 35 34 63 37 00 00\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyVersionAttribute::.ctor(string) = (\n\t\t01 00 07 31 2e 30 2e 30 2e 30 00 00\n\t)\n\t.custom instance void [mscorlib]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = (\n\t\t01 00 07 31 2e 30 2e 30 2e 30 00 00\n\t)\n\t.custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = (\n\t\t01 00 00 00 00 00 00 00\n\t)\n\t.hash algorithm 0x00008004 // SHA1\n\t.ver 1:0:0:0\n}\n\n.module ConsoleApplication1.exe\n// MVID: {59F64D28-6A1F-D4CE-A745-0383284DF659}\n.corflags 0x00020003 // ILOnly, Required32Bit, Preferred32Bit\n\n\n.class private auto ansi '<Module>'\n\textends [mscorlib]System.Object\n{\n} // end of class <Module>\n\n.class public auto ansi abstract sealed Program\n\textends [mscorlib]System.Object\n{\n\t.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (\n\t\t01 00 07 00 00 00 00 00\n\t)\n\t// Nested Types\n\t.class nested assembly auto auto sealed specialname serializable beforefieldinit disposable@3\n\t\textends [mscorlib]System.Object\n\t\timplements [mscorlib]System.IDisposable\n\t{\n\t\t.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (\n\t\t\t01 00 06 00 00 00 00 00\n\t\t)\n\t\t// Methods\n\t\t.method public specialname rtspecialname \n\t\t\tinstance void .ctor () cil managed \n\t\t{\n\t\t\t// Method begins at RVA 0x21bc\n\t\t\t// Code size 9 (0x9)\n\t\t\t.maxstack 8\n\n\t\t\tIL_0000: ldarg.0\n\t\t\tIL_0001: callvirt instance void [mscorlib]System.Object::.ctor()\n\t\t\tIL_0006: ldarg.0\n\t\t\tIL_0007: pop\n\t\t\tIL_0008: ret\n\t\t} // end of method disposable@3::.ctor\n\n\t\t.method private final hidebysig newslot virtual \n\t\t\tinstance void 'System-IDisposable-Dispose' () cil managed \n\t\t{\n\t\t\t.override method instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\t// Method begins at RVA 0x21c8\n\t\t\t// Code size 1 (0x1)\n\t\t\t.maxstack 8\n\n\t\t\tIL_0000: ret\n\t\t} // end of method disposable@3::'System-IDisposable-Dispose'\n\n\t} // end of class disposable@3\n\n\t.class nested assembly auto auto sealed specialname serializable beforefieldinit getSeq@5\n\t\textends class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1<int32>\n\t{\n\t\t.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (\n\t\t\t01 00 06 00 00 00 00 00\n\t\t)\n\t\t// Fields\n\t\t.field public int32 pc\n\t\t.custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = (\n\t\t\t01 00 00 00 00 00 00 00\n\t\t)\n\t\t.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n\t\t\t01 00 00 00\n\t\t)\n\t\t.custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = (\n\t\t\t01 00 00 00\n\t\t)\n\t\t.field public int32 current\n\t\t.custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = (\n\t\t\t01 00 00 00 00 00 00 00\n\t\t)\n\t\t.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n\t\t\t01 00 00 00\n\t\t)\n\t\t.custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = (\n\t\t\t01 00 00 00\n\t\t)\n\n\t\t// Methods\n\t\t.method public specialname rtspecialname \n\t\t\tinstance void .ctor (\n\t\t\t\tint32 pc,\n\t\t\t\tint32 current\n\t\t\t) cil managed \n\t\t{\n\t\t\t// Method begins at RVA 0x21cc\n\t\t\t// Code size 21 (0x15)\n\t\t\t.maxstack 8\n\n\t\t\tIL_0000: ldarg.0\n\t\t\tIL_0001: ldarg.1\n\t\t\tIL_0002: stfld int32 Program/getSeq@5::pc\n\t\t\tIL_0007: ldarg.0\n\t\t\tIL_0008: ldarg.2\n\t\t\tIL_0009: stfld int32 Program/getSeq@5::current\n\t\t\tIL_000e: ldarg.0\n\t\t\tIL_000f: call instance void class [FSharp.Core]Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase`1<int32>::.ctor()\n\t\t\tIL_0014: ret\n\t\t} // end of method getSeq@5::.ctor\n\n\t\t.method public strict virtual \n\t\t\tinstance int32 GenerateNext (\n\t\t\t\tclass [mscorlib]System.Collections.Generic.IEnumerable`1<int32>& next\n\t\t\t) cil managed \n\t\t{\n\t\t\t// Method begins at RVA 0x21e4\n\t\t\t// Code size 62 (0x3e)\n\t\t\t.maxstack 8\n\n\t\t\tIL_0000: ldarg.0\n\t\t\tIL_0001: ldfld int32 Program/getSeq@5::pc\n\t\t\tIL_0006: ldc.i4.1\n\t\t\tIL_0007: sub\n\t\t\tIL_0008: switch (IL_0018, IL_001b)\n\n\t\t\tIL_0015: nop\n\t\t\tIL_0016: br.s IL_001e\n\n\t\t\tIL_0018: nop\n\t\t\tIL_0019: br.s IL_002e\n\n\t\t\tIL_001b: nop\n\t\t\tIL_001c: br.s IL_0035\n\n\t\t\tIL_001e: ldarg.0\n\t\t\tIL_001f: ldc.i4.1\n\t\t\tIL_0020: stfld int32 Program/getSeq@5::pc\n\t\t\tIL_0025: ldarg.0\n\t\t\tIL_0026: ldc.i4.1\n\t\t\tIL_0027: stfld int32 Program/getSeq@5::current\n\t\t\tIL_002c: ldc.i4.1\n\t\t\tIL_002d: ret\n\n\t\t\tIL_002e: ldarg.0\n\t\t\tIL_002f: ldc.i4.2\n\t\t\tIL_0030: stfld int32 Program/getSeq@5::pc\n\n\t\t\tIL_0035: ldarg.0\n\t\t\tIL_0036: ldc.i4.0\n\t\t\tIL_0037: stfld int32 Program/getSeq@5::current\n\t\t\tIL_003c: ldc.i4.0\n\t\t\tIL_003d: ret\n\t\t} // end of method getSeq@5::GenerateNext\n\n\t\t.method public strict virtual \n\t\t\tinstance void Close () cil managed \n\t\t{\n\t\t\t// Method begins at RVA 0x2224\n\t\t\t// Code size 8 (0x8)\n\t\t\t.maxstack 8\n\n\t\t\tIL_0000: ldarg.0\n\t\t\tIL_0001: ldc.i4.2\n\t\t\tIL_0002: stfld int32 Program/getSeq@5::pc\n\t\t\tIL_0007: ret\n\t\t} // end of method getSeq@5::Close\n\n\t\t.method public strict virtual \n\t\t\tinstance bool get_CheckClose () cil managed \n\t\t{\n\t\t\t// Method begins at RVA 0x2230\n\t\t\t// Code size 39 (0x27)\n\t\t\t.maxstack 8\n\n\t\t\tIL_0000: ldarg.0\n\t\t\tIL_0001: ldfld int32 Program/getSeq@5::pc\n\t\t\tIL_0006: switch (IL_001a, IL_001d, IL_0020)\n\n\t\t\tIL_0017: nop\n\t\t\tIL_0018: br.s IL_0023\n\n\t\t\tIL_001a: nop\n\t\t\tIL_001b: br.s IL_0025\n\n\t\t\tIL_001d: nop\n\t\t\tIL_001e: br.s IL_0023\n\n\t\t\tIL_0020: nop\n\t\t\tIL_0021: br.s IL_0025\n\n\t\t\tIL_0023: ldc.i4.0\n\t\t\tIL_0024: ret\n\n\t\t\tIL_0025: ldc.i4.0\n\t\t\tIL_0026: ret\n\t\t} // end of method getSeq@5::get_CheckClose\n\n\t\t.method public strict virtual \n\t\t\tinstance int32 get_LastGenerated () cil managed \n\t\t{\n\t\t\t.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n\t\t\t\t01 00 00 00\n\t\t\t)\n\t\t\t.custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = (\n\t\t\t\t01 00 00 00\n\t\t\t)\n\t\t\t// Method begins at RVA 0x2258\n\t\t\t// Code size 7 (0x7)\n\t\t\t.maxstack 8\n\n\t\t\tIL_0000: ldarg.0\n\t\t\tIL_0001: ldfld int32 Program/getSeq@5::current\n\t\t\tIL_0006: ret\n\t\t} // end of method getSeq@5::get_LastGenerated\n\n\t\t.method public strict virtual \n\t\t\tinstance class [mscorlib]System.Collections.Generic.IEnumerator`1<int32> GetFreshEnumerator () cil managed \n\t\t{\n\t\t\t.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n\t\t\t\t01 00 00 00\n\t\t\t)\n\t\t\t.custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = (\n\t\t\t\t01 00 00 00\n\t\t\t)\n\t\t\t// Method begins at RVA 0x2260\n\t\t\t// Code size 8 (0x8)\n\t\t\t.maxstack 8\n\n\t\t\tIL_0000: ldc.i4.0\n\t\t\tIL_0001: ldc.i4.0\n\t\t\tIL_0002: newobj instance void Program/getSeq@5::.ctor(int32, int32)\n\t\t\tIL_0007: ret\n\t\t} // end of method getSeq@5::GetFreshEnumerator\n\n\t} // end of class getSeq@5\n\n\n\t// Methods\n\t.method public static \n\t\tclass [mscorlib]System.IDisposable disposable () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 6 (0x6)\n\t\t.maxstack 8\n\n\t\tIL_0000: newobj instance void Program/disposable@3::.ctor()\n\t\tIL_0005: ret\n\t} // end of method Program::disposable\n\n\t.method public static \n\t\tclass [mscorlib]System.Collections.Generic.IEnumerable`1<int32> getSeq () cil managed \n\t{\n\t\t// Method begins at RVA 0x2058\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldc.i4.0\n\t\tIL_0001: ldc.i4.0\n\t\tIL_0002: newobj instance void Program/getSeq@5::.ctor(int32, int32)\n\t\tIL_0007: ret\n\t} // end of method Program::getSeq\n\n\t.method public static \n\t\tclass [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> getList () cil managed \n\t{\n\t\t// Method begins at RVA 0x2064\n\t\t// Code size 12 (0xc)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldc.i4.1\n\t\tIL_0001: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_Empty()\n\t\tIL_0006: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0>)\n\t\tIL_000b: ret\n\t} // end of method Program::getList\n\n\t.method public static \n\t\tint32[] getArray () cil managed \n\t{\n\t\t// Method begins at RVA 0x2074\n\t\t// Code size 15 (0xf)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldc.i4.1\n\t\tIL_0001: newarr [mscorlib]System.Int32\n\t\tIL_0006: dup\n\t\tIL_0007: ldc.i4.0\n\t\tIL_0008: ldc.i4.1\n\t\tIL_0009: stelem.any [mscorlib]System.Int32\n\t\tIL_000e: ret\n\t} // end of method Program::getArray\n\n\t.method public static \n\t\tint32 main (\n\t\t\tstring[] argv\n\t\t) cil managed \n\t{\n\t\t.custom instance void [FSharp.Core]Microsoft.FSharp.Core.EntryPointAttribute::.ctor() = (\n\t\t\t01 00 00 00\n\t\t)\n\t\t// Method begins at RVA 0x2084\n\t\t// Code size 259 (0x103)\n\t\t.maxstack 6\n\t\t.entrypoint\n\t\t.locals init (\n\t\t\t[0] class [mscorlib]System.IDisposable,\n\t\t\t[1] class [mscorlib]System.IDisposable,\n\t\t\t[2] class [mscorlib]System.IDisposable,\n\t\t\t[3] class [mscorlib]System.IDisposable,\n\t\t\t[4] int32,\n\t\t\t[5] class [mscorlib]System.Collections.Generic.IEnumerable`1<int32>,\n\t\t\t[6] class [mscorlib]System.Collections.Generic.IEnumerator`1<int32>,\n\t\t\t[7] class [FSharp.Core]Microsoft.FSharp.Core.Unit,\n\t\t\t[8] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>,\n\t\t\t[9] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>,\n\t\t\t[10] int32,\n\t\t\t[11] int32[]\n\t\t)\n\n\t\tIL_0000: call class [mscorlib]System.IDisposable Program::disposable()\n\t\tIL_0005: stloc.1\n\t\t.try\n\t\t{\n\t\t\tIL_0006: ldstr \"Hello 1\"\n\t\t\tIL_000b: call void [mscorlib]System.Console::WriteLine(string)\n\t\t\tIL_0010: call class [mscorlib]System.IDisposable Program::disposable()\n\t\t\tIL_0015: stloc.2\n\t\t\tIL_0016: leave.s IL_002e\n\t\t} // end .try\n\t\tfinally\n\t\t{\n\t\t\tIL_0018: ldloc.1\n\t\t\tIL_0019: isinst [mscorlib]System.IDisposable\n\t\t\tIL_001e: stloc.3\n\t\t\tIL_001f: ldloc.3\n\t\t\tIL_0020: brfalse.s IL_002b\n\n\t\t\tIL_0022: ldloc.3\n\t\t\tIL_0023: callvirt instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\tIL_0028: ldnull\n\t\t\tIL_0029: pop\n\t\t\tIL_002a: endfinally\n\n\t\t\tIL_002b: ldnull\n\t\t\tIL_002c: pop\n\t\t\tIL_002d: endfinally\n\t\t} // end handler\n\n\t\tIL_002e: ldloc.2\n\t\tIL_002f: stloc.0\n\t\t.try\n\t\t{\n\t\t\tIL_0030: call class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> Program::getSeq()\n\t\t\tIL_0035: stloc.s 5\n\t\t\tIL_0037: ldloc.s 5\n\t\t\tIL_0039: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> class [mscorlib]System.Collections.Generic.IEnumerable`1<int32>::GetEnumerator()\n\t\t\tIL_003e: stloc.s 6\n\t\t\t.try\n\t\t\t{\n\t\t\t\t// loop start (head: IL_0040)\n\t\t\t\t\tIL_0040: ldloc.s 6\n\t\t\t\t\tIL_0042: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()\n\t\t\t\t\tIL_0047: brfalse.s IL_0058\n\n\t\t\t\t\tIL_0049: ldloc.s 6\n\t\t\t\t\tIL_004b: callvirt instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1<int32>::get_Current()\n\t\t\t\t\tIL_0050: call void [mscorlib]System.Console::WriteLine(int32)\n\t\t\t\t\tIL_0055: nop\n\t\t\t\t\tIL_0056: br.s IL_0040\n\t\t\t\t// end loop\n\n\t\t\t\tIL_0058: ldnull\n\t\t\t\tIL_0059: stloc.s 7\n\t\t\t\tIL_005b: leave.s IL_0074\n\t\t\t} // end .try\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tIL_005d: ldloc.s 6\n\t\t\t\tIL_005f: isinst [mscorlib]System.IDisposable\n\t\t\t\tIL_0064: stloc.1\n\t\t\t\tIL_0065: ldloc.1\n\t\t\t\tIL_0066: brfalse.s IL_0071\n\n\t\t\t\tIL_0068: ldloc.1\n\t\t\t\tIL_0069: callvirt instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\t\tIL_006e: ldnull\n\t\t\t\tIL_006f: pop\n\t\t\t\tIL_0070: endfinally\n\n\t\t\t\tIL_0071: ldnull\n\t\t\t\tIL_0072: pop\n\t\t\t\tIL_0073: endfinally\n\t\t\t} // end handler\n\n\t\t\tIL_0074: ldloc.s 7\n\t\t\tIL_0076: pop\n\t\t\tIL_0077: ldc.i4.1\n\t\t\tIL_0078: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_Empty()\n\t\t\tIL_007d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0>)\n\t\t\tIL_0082: stloc.s 8\n\t\t\tIL_0084: ldloc.s 8\n\t\t\tIL_0086: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_TailOrNull()\n\t\t\tIL_008b: stloc.s 9\n\t\t\t// loop start (head: IL_008d)\n\t\t\t\tIL_008d: ldloc.s 9\n\t\t\t\tIL_008f: ldnull\n\t\t\t\tIL_0090: cgt.un\n\t\t\t\tIL_0092: brfalse.s IL_00b4\n\n\t\t\t\tIL_0094: ldloc.s 8\n\t\t\t\tIL_0096: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_HeadOrDefault()\n\t\t\t\tIL_009b: stloc.s 10\n\t\t\t\tIL_009d: ldloc.s 10\n\t\t\t\tIL_009f: call void [mscorlib]System.Console::WriteLine(int32)\n\t\t\t\tIL_00a4: ldloc.s 9\n\t\t\t\tIL_00a6: stloc.s 8\n\t\t\t\tIL_00a8: ldloc.s 8\n\t\t\t\tIL_00aa: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_TailOrNull()\n\t\t\t\tIL_00af: stloc.s 9\n\t\t\t\tIL_00b1: nop\n\t\t\t\tIL_00b2: br.s IL_008d\n\t\t\t// end loop\n\n\t\t\tIL_00b4: ldc.i4.1\n\t\t\tIL_00b5: newarr [mscorlib]System.Int32\n\t\t\tIL_00ba: dup\n\t\t\tIL_00bb: ldc.i4.0\n\t\t\tIL_00bc: ldc.i4.1\n\t\t\tIL_00bd: stelem.any [mscorlib]System.Int32\n\t\t\tIL_00c2: stloc.s 11\n\t\t\tIL_00c4: ldc.i4.0\n\t\t\tIL_00c5: stloc.s 10\n\t\t\tIL_00c7: br.s IL_00dd\n\t\t\t// loop start (head: IL_00dd)\n\t\t\t\tIL_00c9: ldloc.s 11\n\t\t\t\tIL_00cb: ldloc.s 10\n\t\t\t\tIL_00cd: ldelem.any [mscorlib]System.Int32\n\t\t\t\tIL_00d2: call void [mscorlib]System.Console::WriteLine(int32)\n\t\t\t\tIL_00d7: ldloc.s 10\n\t\t\t\tIL_00d9: ldc.i4.1\n\t\t\t\tIL_00da: add\n\t\t\t\tIL_00db: stloc.s 10\n\n\t\t\t\tIL_00dd: ldloc.s 10\n\t\t\t\tIL_00df: ldloc.s 11\n\t\t\t\tIL_00e1: ldlen\n\t\t\t\tIL_00e2: conv.i4\n\t\t\t\tIL_00e3: blt.s IL_00c9\n\t\t\t// end loop\n\n\t\t\tIL_00e5: ldc.i4.0\n\t\t\tIL_00e6: stloc.s 4\n\t\t\tIL_00e8: leave.s IL_0100\n\t\t} // end .try\n\t\tfinally\n\t\t{\n\t\t\tIL_00ea: ldloc.0\n\t\t\tIL_00eb: isinst [mscorlib]System.IDisposable\n\t\t\tIL_00f0: stloc.1\n\t\t\tIL_00f1: ldloc.1\n\t\t\tIL_00f2: brfalse.s IL_00fd\n\n\t\t\tIL_00f4: ldloc.1\n\t\t\tIL_00f5: callvirt instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\tIL_00fa: ldnull\n\t\t\tIL_00fb: pop\n\t\t\tIL_00fc: endfinally\n\n\t\t\tIL_00fd: ldnull\n\t\t\tIL_00fe: pop\n\t\t\tIL_00ff: endfinally\n\t\t} // end handler\n\n\t\tIL_0100: ldloc.s 4\n\t\tIL_0102: ret\n\t} // end of method Program::main\n\n} // end of class Program\n\n.class private auto ansi abstract sealed '<StartupCode$ConsoleApplication1>.$Program'\n\textends [mscorlib]System.Object\n{\n} // end of class <StartupCode$ConsoleApplication1>.$Program\n\n.class private auto ansi abstract sealed '<StartupCode$ConsoleApplication1>.$AssemblyInfo'\n\textends [mscorlib]System.Object\n{\n} // end of class <StartupCode$ConsoleApplication1>.$AssemblyInfo\n\n.class private auto ansi abstract sealed '<StartupCode$ConsoleApplication1>.$.NETFramework,Version=v4.6.1.AssemblyAttributes'\n\textends [mscorlib]System.Object\n{\n} // end of class <StartupCode$ConsoleApplication1>.$.NETFramework,Version=v4.6.1.AssemblyAttributes\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing.fs",
    "content": "module FSharpUsingPatterns\n\nopen System\nopen System.IO\n\nlet sample1() = \n    use fs = File.Create(\"x.txt\")\n    fs.WriteByte(byte 1)\n\nlet sample2() = \n    Console.WriteLine(\"some text\")\n    use fs = File.Create(\"x.txt\")\n    fs.WriteByte(byte 2)\n    Console.WriteLine(\"some text\")\n\nlet sample3() = \n    Console.WriteLine(\"some text\")\n    do use fs = File.Create(\"x.txt\")\n       fs.WriteByte(byte 3)\n    Console.WriteLine(\"some text\")\n\nlet sample4() = \n    Console.WriteLine(\"some text\")\n    let firstByte = \n        use fs = File.OpenRead(\"x.txt\")\n        fs.ReadByte()\n    Console.WriteLine(\"read:\" + firstByte.ToString())\n\nlet sample5() =\n    Console.WriteLine(\"some text\")\n    let firstByte = \n        use fs = File.OpenRead(\"x.txt\")\n        fs.ReadByte()\n    let secondByte =\n        use fs = File.OpenRead(\"x.txt\")\n        fs.ReadByte() |> ignore\n        fs.ReadByte()\n    Console.WriteLine(\"read: {0}, {1}\", firstByte, secondByte)\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Debug.cs",
    "content": "using System;\nusing System.IO;\n\npublic static class FSharpUsingPatterns\n{\n\tpublic static void sample1()\n\t{\n\t\tusing (FileStream fileStream = File.Create(\"x.txt\"))\n\t\t{\n\t\t\tfileStream.WriteByte((byte)1);\n\t\t}\n\t}\n\n\tpublic static void sample2()\n\t{\n\t\tConsole.WriteLine(\"some text\");\n\t\tusing (FileStream fileStream = File.Create(\"x.txt\"))\n\t\t{\n\t\t\tfileStream.WriteByte((byte)2);\n\t\t\tConsole.WriteLine(\"some text\");\n\t\t}\n\t}\n\n\tpublic static void sample3()\n\t{\n\t\tConsole.WriteLine(\"some text\");\n\t\tusing (FileStream fileStream = File.Create(\"x.txt\"))\n\t\t{\n\t\t\tfileStream.WriteByte((byte)3);\n\t\t}\n\t\tConsole.WriteLine(\"some text\");\n\t}\n\n\tpublic static void sample4()\n\t{\n\t\tConsole.WriteLine(\"some text\");\n\t\tint num;\n\t\tusing (FileStream fileStream = File.OpenRead(\"x.txt\"))\n\t\t{\n\t\t\tnum = fileStream.ReadByte();\n\t\t}\n\t\tint num2 = num;\n\t\tConsole.WriteLine(\"read:\" + num2);\n\t}\n\n\tpublic static void sample5()\n\t{\n\t\tConsole.WriteLine(\"some text\");\n\t\tint num;\n\t\tusing (FileStream fileStream = File.OpenRead(\"x.txt\"))\n\t\t{\n\t\t\tnum = fileStream.ReadByte();\n\t\t}\n\t\tint num2 = num;\n\t\tint num3;\n\t\tusing (FileStream fileStream = File.OpenRead(\"x.txt\"))\n\t\t{\n\t\t\tfileStream.ReadByte();\n\t\t\tnum3 = fileStream.ReadByte();\n\t\t}\n\t\tint num4 = num3;\n\t\tConsole.WriteLine(\"read: {0}, {1}\", num2, num4);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Debug.il",
    "content": ".class public auto ansi abstract sealed FSharpUsingPatterns\n\textends [mscorlib]System.Object\n{\n\t// Methods\n\t.method public static \n\t\tvoid sample1 () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 53 (0x35)\n\t\t.maxstack 4\n\t\t.locals init (\n\t\t\t[0] class [mscorlib]System.IO.FileStream fs,\n\t\t\t[1] class [mscorlib]System.Object,\n\t\t\t[2] class [mscorlib]System.IDisposable\n\t\t)\n\n\t\tIL_0000: nop\n\t\tIL_0001: ldstr \"x.txt\"\n\t\tIL_0006: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::Create(string)\n\t\tIL_000b: stloc.0\n\t\t.try\n\t\t{\n\t\t\tIL_000c: ldloc.0\n\t\t\tIL_000d: ldc.i4.1\n\t\t\tIL_000e: conv.u1\n\t\t\tIL_000f: callvirt instance void [mscorlib]System.IO.Stream::WriteByte(uint8)\n\t\t\tIL_0014: ldnull\n\t\t\tIL_0015: stloc.1\n\t\t\tIL_0016: leave.s IL_0032\n\t\t} // end .try\n\t\tfinally\n\t\t{\n\t\t\tIL_0018: ldloc.0\n\t\t\tIL_0019: isinst [mscorlib]System.IDisposable\n\t\t\tIL_001e: stloc.2\n\t\t\tIL_001f: ldloc.2\n\t\t\tIL_0020: brfalse.s IL_0024\n\n\t\t\tIL_0022: br.s IL_0026\n\n\t\t\tIL_0024: br.s IL_002f\n\n\t\t\tIL_0026: ldloc.2\n\t\t\tIL_0027: callvirt instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\tIL_002c: ldnull\n\t\t\tIL_002d: pop\n\t\t\tIL_002e: endfinally\n\n\t\t\tIL_002f: ldnull\n\t\t\tIL_0030: pop\n\t\t\tIL_0031: endfinally\n\t\t} // end handler\n\n\t\tIL_0032: ldloc.1\n\t\tIL_0033: pop\n\t\tIL_0034: ret\n\t} // end of method FSharpUsingPatterns::sample1\n\n\t.method public static \n\t\tvoid sample2 () cil managed \n\t{\n\t\t// Method begins at RVA 0x20a4\n\t\t// Code size 73 (0x49)\n\t\t.maxstack 4\n\t\t.locals init (\n\t\t\t[0] class [mscorlib]System.IO.FileStream fs,\n\t\t\t[1] class [mscorlib]System.Object,\n\t\t\t[2] class [mscorlib]System.IDisposable\n\t\t)\n\n\t\tIL_0000: nop\n\t\tIL_0001: ldstr \"some text\"\n\t\tIL_0006: call void [mscorlib]System.Console::WriteLine(string)\n\t\tIL_000b: ldstr \"x.txt\"\n\t\tIL_0010: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::Create(string)\n\t\tIL_0015: stloc.0\n\t\t.try\n\t\t{\n\t\t\tIL_0016: ldloc.0\n\t\t\tIL_0017: ldc.i4.2\n\t\t\tIL_0018: conv.u1\n\t\t\tIL_0019: callvirt instance void [mscorlib]System.IO.Stream::WriteByte(uint8)\n\t\t\tIL_001e: ldstr \"some text\"\n\t\t\tIL_0023: call void [mscorlib]System.Console::WriteLine(string)\n\t\t\tIL_0028: ldnull\n\t\t\tIL_0029: stloc.1\n\t\t\tIL_002a: leave.s IL_0046\n\t\t} // end .try\n\t\tfinally\n\t\t{\n\t\t\tIL_002c: ldloc.0\n\t\t\tIL_002d: isinst [mscorlib]System.IDisposable\n\t\t\tIL_0032: stloc.2\n\t\t\tIL_0033: ldloc.2\n\t\t\tIL_0034: brfalse.s IL_0038\n\n\t\t\tIL_0036: br.s IL_003a\n\n\t\t\tIL_0038: br.s IL_0043\n\n\t\t\tIL_003a: ldloc.2\n\t\t\tIL_003b: callvirt instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\tIL_0040: ldnull\n\t\t\tIL_0041: pop\n\t\t\tIL_0042: endfinally\n\n\t\t\tIL_0043: ldnull\n\t\t\tIL_0044: pop\n\t\t\tIL_0045: endfinally\n\t\t} // end handler\n\n\t\tIL_0046: ldloc.1\n\t\tIL_0047: pop\n\t\tIL_0048: ret\n\t} // end of method FSharpUsingPatterns::sample2\n\n\t.method public static \n\t\tvoid sample3 () cil managed \n\t{\n\t\t// Method begins at RVA 0x210c\n\t\t// Code size 73 (0x49)\n\t\t.maxstack 4\n\t\t.locals init (\n\t\t\t[0] class [mscorlib]System.IO.FileStream fs,\n\t\t\t[1] class [mscorlib]System.Object,\n\t\t\t[2] class [mscorlib]System.IDisposable\n\t\t)\n\n\t\tIL_0000: nop\n\t\tIL_0001: ldstr \"some text\"\n\t\tIL_0006: call void [mscorlib]System.Console::WriteLine(string)\n\t\tIL_000b: ldstr \"x.txt\"\n\t\tIL_0010: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::Create(string)\n\t\tIL_0015: stloc.0\n\t\t.try\n\t\t{\n\t\t\tIL_0016: ldloc.0\n\t\t\tIL_0017: ldc.i4.3\n\t\t\tIL_0018: conv.u1\n\t\t\tIL_0019: callvirt instance void [mscorlib]System.IO.Stream::WriteByte(uint8)\n\t\t\tIL_001e: ldnull\n\t\t\tIL_001f: stloc.1\n\t\t\tIL_0020: leave.s IL_003c\n\t\t} // end .try\n\t\tfinally\n\t\t{\n\t\t\tIL_0022: ldloc.0\n\t\t\tIL_0023: isinst [mscorlib]System.IDisposable\n\t\t\tIL_0028: stloc.2\n\t\t\tIL_0029: ldloc.2\n\t\t\tIL_002a: brfalse.s IL_002e\n\n\t\t\tIL_002c: br.s IL_0030\n\n\t\t\tIL_002e: br.s IL_0039\n\n\t\t\tIL_0030: ldloc.2\n\t\t\tIL_0031: callvirt instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\tIL_0036: ldnull\n\t\t\tIL_0037: pop\n\t\t\tIL_0038: endfinally\n\n\t\t\tIL_0039: ldnull\n\t\t\tIL_003a: pop\n\t\t\tIL_003b: endfinally\n\t\t} // end handler\n\n\t\tIL_003c: ldloc.1\n\t\tIL_003d: pop\n\t\tIL_003e: ldstr \"some text\"\n\t\tIL_0043: call void [mscorlib]System.Console::WriteLine(string)\n\t\tIL_0048: ret\n\t} // end of method FSharpUsingPatterns::sample3\n\n\t.method public static \n\t\tvoid sample4 () cil managed \n\t{\n\t\t// Method begins at RVA 0x2174\n\t\t// Code size 89 (0x59)\n\t\t.maxstack 4\n\t\t.locals init (\n\t\t\t[0] int32 firstByte,\n\t\t\t[1] class [mscorlib]System.IO.FileStream fs,\n\t\t\t[2] int32,\n\t\t\t[3] class [mscorlib]System.IDisposable\n\t\t)\n\n\t\tIL_0000: nop\n\t\tIL_0001: ldstr \"some text\"\n\t\tIL_0006: call void [mscorlib]System.Console::WriteLine(string)\n\t\tIL_000b: nop\n\t\tIL_000c: ldstr \"x.txt\"\n\t\tIL_0011: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::OpenRead(string)\n\t\tIL_0016: stloc.1\n\t\t.try\n\t\t{\n\t\t\tIL_0017: ldloc.1\n\t\t\tIL_0018: callvirt instance int32 [mscorlib]System.IO.Stream::ReadByte()\n\t\t\tIL_001d: stloc.2\n\t\t\tIL_001e: leave.s IL_003a\n\t\t} // end .try\n\t\tfinally\n\t\t{\n\t\t\tIL_0020: ldloc.1\n\t\t\tIL_0021: isinst [mscorlib]System.IDisposable\n\t\t\tIL_0026: stloc.3\n\t\t\tIL_0027: ldloc.3\n\t\t\tIL_0028: brfalse.s IL_002c\n\n\t\t\tIL_002a: br.s IL_002e\n\n\t\t\tIL_002c: br.s IL_0037\n\n\t\t\tIL_002e: ldloc.3\n\t\t\tIL_002f: callvirt instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\tIL_0034: ldnull\n\t\t\tIL_0035: pop\n\t\t\tIL_0036: endfinally\n\n\t\t\tIL_0037: ldnull\n\t\t\tIL_0038: pop\n\t\t\tIL_0039: endfinally\n\t\t} // end handler\n\n\t\tIL_003a: ldloc.2\n\t\tIL_003b: stloc.0\n\t\tIL_003c: ldstr \"read:\"\n\t\tIL_0041: ldloca.s firstByte\n\t\tIL_0043: constrained. [mscorlib]System.Int32\n\t\tIL_0049: callvirt instance string [mscorlib]System.Object::ToString()\n\t\tIL_004e: call string [mscorlib]System.String::Concat(string, string)\n\t\tIL_0053: call void [mscorlib]System.Console::WriteLine(string)\n\t\tIL_0058: ret\n\t} // end of method FSharpUsingPatterns::sample4\n\n\t.method public static \n\t\tvoid sample5 () cil managed \n\t{\n\t\t// Method begins at RVA 0x21ec\n\t\t// Code size 155 (0x9b)\n\t\t.maxstack 5\n\t\t.locals init (\n\t\t\t[0] int32 firstByte,\n\t\t\t[1] class [mscorlib]System.IO.FileStream fs,\n\t\t\t[2] int32,\n\t\t\t[3] class [mscorlib]System.IDisposable,\n\t\t\t[4] int32 secondByte,\n\t\t\t[5] class [mscorlib]System.IO.FileStream fs,\n\t\t\t[6] int32,\n\t\t\t[7] int32,\n\t\t\t[8] int32,\n\t\t\t[9] class [mscorlib]System.IDisposable\n\t\t)\n\n\t\tIL_0000: nop\n\t\tIL_0001: ldstr \"some text\"\n\t\tIL_0006: call void [mscorlib]System.Console::WriteLine(string)\n\t\tIL_000b: nop\n\t\tIL_000c: ldstr \"x.txt\"\n\t\tIL_0011: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::OpenRead(string)\n\t\tIL_0016: stloc.1\n\t\t.try\n\t\t{\n\t\t\tIL_0017: ldloc.1\n\t\t\tIL_0018: callvirt instance int32 [mscorlib]System.IO.Stream::ReadByte()\n\t\t\tIL_001d: stloc.2\n\t\t\tIL_001e: leave.s IL_003a\n\t\t} // end .try\n\t\tfinally\n\t\t{\n\t\t\tIL_0020: ldloc.1\n\t\t\tIL_0021: isinst [mscorlib]System.IDisposable\n\t\t\tIL_0026: stloc.3\n\t\t\tIL_0027: ldloc.3\n\t\t\tIL_0028: brfalse.s IL_002c\n\n\t\t\tIL_002a: br.s IL_002e\n\n\t\t\tIL_002c: br.s IL_0037\n\n\t\t\tIL_002e: ldloc.3\n\t\t\tIL_002f: callvirt instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\tIL_0034: ldnull\n\t\t\tIL_0035: pop\n\t\t\tIL_0036: endfinally\n\n\t\t\tIL_0037: ldnull\n\t\t\tIL_0038: pop\n\t\t\tIL_0039: endfinally\n\t\t} // end handler\n\n\t\tIL_003a: ldloc.2\n\t\tIL_003b: stloc.0\n\t\tIL_003c: nop\n\t\tIL_003d: ldstr \"x.txt\"\n\t\tIL_0042: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::OpenRead(string)\n\t\tIL_0047: stloc.s fs\n\t\t.try\n\t\t{\n\t\t\tIL_0049: ldloc.s fs\n\t\t\tIL_004b: callvirt instance int32 [mscorlib]System.IO.Stream::ReadByte()\n\t\t\tIL_0050: stloc.s 7\n\t\t\tIL_0052: ldloc.s 7\n\t\t\tIL_0054: stloc.s 8\n\t\t\tIL_0056: ldloc.s fs\n\t\t\tIL_0058: callvirt instance int32 [mscorlib]System.IO.Stream::ReadByte()\n\t\t\tIL_005d: stloc.s 6\n\t\t\tIL_005f: leave.s IL_007f\n\t\t} // end .try\n\t\tfinally\n\t\t{\n\t\t\tIL_0061: ldloc.s fs\n\t\t\tIL_0063: isinst [mscorlib]System.IDisposable\n\t\t\tIL_0068: stloc.s 9\n\t\t\tIL_006a: ldloc.s 9\n\t\t\tIL_006c: brfalse.s IL_0070\n\n\t\t\tIL_006e: br.s IL_0072\n\n\t\t\tIL_0070: br.s IL_007c\n\n\t\t\tIL_0072: ldloc.s 9\n\t\t\tIL_0074: callvirt instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\tIL_0079: ldnull\n\t\t\tIL_007a: pop\n\t\t\tIL_007b: endfinally\n\n\t\t\tIL_007c: ldnull\n\t\t\tIL_007d: pop\n\t\t\tIL_007e: endfinally\n\t\t} // end handler\n\n\t\tIL_007f: ldloc.s 6\n\t\tIL_0081: stloc.s secondByte\n\t\tIL_0083: ldstr \"read: {0}, {1}\"\n\t\tIL_0088: ldloc.0\n\t\tIL_0089: box [mscorlib]System.Int32\n\t\tIL_008e: ldloc.s secondByte\n\t\tIL_0090: box [mscorlib]System.Int32\n\t\tIL_0095: call void [mscorlib]System.Console::WriteLine(string, object, object)\n\t\tIL_009a: ret\n\t} // end of method FSharpUsingPatterns::sample5\n\n} // end of class FSharpUsingPatterns\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Release.cs",
    "content": "using System;\nusing System.IO;\n\npublic static class FSharpUsingPatterns\n{\n\tpublic static void sample1()\n\t{\n\t\tusing (FileStream fileStream = File.Create(\"x.txt\"))\n\t\t{\n\t\t\tfileStream.WriteByte(1);\n\t\t}\n\t}\n\n\tpublic static void sample2()\n\t{\n\t\tConsole.WriteLine(\"some text\");\n\t\tusing (FileStream fileStream = File.Create(\"x.txt\"))\n\t\t{\n\t\t\tfileStream.WriteByte(2);\n\t\t\tConsole.WriteLine(\"some text\");\n\t\t}\n\t}\n\n\tpublic static void sample3()\n\t{\n\t\tConsole.WriteLine(\"some text\");\n\t\tusing (FileStream fileStream = File.Create(\"x.txt\"))\n\t\t{\n\t\t\tfileStream.WriteByte(3);\n\t\t}\n\t\tConsole.WriteLine(\"some text\");\n\t}\n\n\tpublic static void sample4()\n\t{\n\t\tConsole.WriteLine(\"some text\");\n\t\tint num;\n\t\tusing (FileStream fileStream = File.OpenRead(\"x.txt\"))\n\t\t{\n\t\t\tnum = fileStream.ReadByte();\n\t\t}\n\t\tint num2 = num;\n\t\tConsole.WriteLine(\"read:\" + num2);\n\t}\n\n\tpublic static void sample5()\n\t{\n\t\tConsole.WriteLine(\"some text\");\n\t\tint num;\n\t\tusing (FileStream fileStream = File.OpenRead(\"x.txt\"))\n\t\t{\n\t\t\tnum = fileStream.ReadByte();\n\t\t}\n\t\tint num2 = num;\n\t\tint num3;\n\t\tusing (FileStream fileStream = File.OpenRead(\"x.txt\"))\n\t\t{\n\t\t\tfileStream.ReadByte();\n\t\t\tnum3 = fileStream.ReadByte();\n\t\t}\n\t\tnum = num3;\n\t\tConsole.WriteLine(\"read: {0}, {1}\", num2, num);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/FSharpUsing_Release.il",
    "content": ".class public auto ansi abstract sealed FSharpUsingPatterns\n\textends [mscorlib]System.Object\n{\n\t// Methods\n\t.method public static \n\t\tvoid sample1 () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 48 (0x30)\n\t\t.maxstack 4\n\t\t.locals init (\n\t\t\t[0] class [mscorlib]System.IO.FileStream fs,\n\t\t\t[1] class [mscorlib]System.Object,\n\t\t\t[2] class [mscorlib]System.IDisposable\n\t\t)\n\n\t\tIL_0000: nop\n\t\tIL_0001: ldstr \"x.txt\"\n\t\tIL_0006: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::Create(string)\n\t\tIL_000b: stloc.0\n\t\t.try\n\t\t{\n\t\t\tIL_000c: ldloc.0\n\t\t\tIL_000d: ldc.i4.1\n\t\t\tIL_000e: callvirt instance void [mscorlib]System.IO.Stream::WriteByte(uint8)\n\t\t\tIL_0013: ldnull\n\t\t\tIL_0014: stloc.1\n\t\t\tIL_0015: leave.s IL_002d\n\t\t} // end .try\n\t\tfinally\n\t\t{\n\t\t\tIL_0017: ldloc.0\n\t\t\tIL_0018: isinst [mscorlib]System.IDisposable\n\t\t\tIL_001d: stloc.2\n\t\t\tIL_001e: ldloc.2\n\t\t\tIL_001f: brfalse.s IL_002a\n\n\t\t\tIL_0021: ldloc.2\n\t\t\tIL_0022: callvirt instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\tIL_0027: ldnull\n\t\t\tIL_0028: pop\n\t\t\tIL_0029: endfinally\n\n\t\t\tIL_002a: ldnull\n\t\t\tIL_002b: pop\n\t\t\tIL_002c: endfinally\n\t\t} // end handler\n\n\t\tIL_002d: ldloc.1\n\t\tIL_002e: pop\n\t\tIL_002f: ret\n\t} // end of method FSharpUsingPatterns::sample1\n\n\t.method public static \n\t\tvoid sample2 () cil managed \n\t{\n\t\t// Method begins at RVA 0x209c\n\t\t// Code size 68 (0x44)\n\t\t.maxstack 4\n\t\t.locals init (\n\t\t\t[0] class [mscorlib]System.IO.FileStream fs,\n\t\t\t[1] class [mscorlib]System.Object,\n\t\t\t[2] class [mscorlib]System.IDisposable\n\t\t)\n\n\t\tIL_0000: nop\n\t\tIL_0001: ldstr \"some text\"\n\t\tIL_0006: call void [mscorlib]System.Console::WriteLine(string)\n\t\tIL_000b: ldstr \"x.txt\"\n\t\tIL_0010: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::Create(string)\n\t\tIL_0015: stloc.0\n\t\t.try\n\t\t{\n\t\t\tIL_0016: ldloc.0\n\t\t\tIL_0017: ldc.i4.2\n\t\t\tIL_0018: callvirt instance void [mscorlib]System.IO.Stream::WriteByte(uint8)\n\t\t\tIL_001d: ldstr \"some text\"\n\t\t\tIL_0022: call void [mscorlib]System.Console::WriteLine(string)\n\t\t\tIL_0027: ldnull\n\t\t\tIL_0028: stloc.1\n\t\t\tIL_0029: leave.s IL_0041\n\t\t} // end .try\n\t\tfinally\n\t\t{\n\t\t\tIL_002b: ldloc.0\n\t\t\tIL_002c: isinst [mscorlib]System.IDisposable\n\t\t\tIL_0031: stloc.2\n\t\t\tIL_0032: ldloc.2\n\t\t\tIL_0033: brfalse.s IL_003e\n\n\t\t\tIL_0035: ldloc.2\n\t\t\tIL_0036: callvirt instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\tIL_003b: ldnull\n\t\t\tIL_003c: pop\n\t\t\tIL_003d: endfinally\n\n\t\t\tIL_003e: ldnull\n\t\t\tIL_003f: pop\n\t\t\tIL_0040: endfinally\n\t\t} // end handler\n\n\t\tIL_0041: ldloc.1\n\t\tIL_0042: pop\n\t\tIL_0043: ret\n\t} // end of method FSharpUsingPatterns::sample2\n\n\t.method public static \n\t\tvoid sample3 () cil managed \n\t{\n\t\t// Method begins at RVA 0x20fc\n\t\t// Code size 68 (0x44)\n\t\t.maxstack 4\n\t\t.locals init (\n\t\t\t[0] class [mscorlib]System.IO.FileStream fs,\n\t\t\t[1] class [mscorlib]System.Object,\n\t\t\t[2] class [mscorlib]System.IDisposable\n\t\t)\n\n\t\tIL_0000: nop\n\t\tIL_0001: ldstr \"some text\"\n\t\tIL_0006: call void [mscorlib]System.Console::WriteLine(string)\n\t\tIL_000b: ldstr \"x.txt\"\n\t\tIL_0010: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::Create(string)\n\t\tIL_0015: stloc.0\n\t\t.try\n\t\t{\n\t\t\tIL_0016: ldloc.0\n\t\t\tIL_0017: ldc.i4.3\n\t\t\tIL_0018: callvirt instance void [mscorlib]System.IO.Stream::WriteByte(uint8)\n\t\t\tIL_001d: ldnull\n\t\t\tIL_001e: stloc.1\n\t\t\tIL_001f: leave.s IL_0037\n\t\t} // end .try\n\t\tfinally\n\t\t{\n\t\t\tIL_0021: ldloc.0\n\t\t\tIL_0022: isinst [mscorlib]System.IDisposable\n\t\t\tIL_0027: stloc.2\n\t\t\tIL_0028: ldloc.2\n\t\t\tIL_0029: brfalse.s IL_0034\n\n\t\t\tIL_002b: ldloc.2\n\t\t\tIL_002c: callvirt instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\tIL_0031: ldnull\n\t\t\tIL_0032: pop\n\t\t\tIL_0033: endfinally\n\n\t\t\tIL_0034: ldnull\n\t\t\tIL_0035: pop\n\t\t\tIL_0036: endfinally\n\t\t} // end handler\n\n\t\tIL_0037: ldloc.1\n\t\tIL_0038: pop\n\t\tIL_0039: ldstr \"some text\"\n\t\tIL_003e: call void [mscorlib]System.Console::WriteLine(string)\n\t\tIL_0043: ret\n\t} // end of method FSharpUsingPatterns::sample3\n\n\t.method public static \n\t\tvoid sample4 () cil managed \n\t{\n\t\t// Method begins at RVA 0x215c\n\t\t// Code size 85 (0x55)\n\t\t.maxstack 4\n\t\t.locals init (\n\t\t\t[0] int32 firstByte,\n\t\t\t[1] class [mscorlib]System.IO.FileStream fs,\n\t\t\t[2] int32,\n\t\t\t[3] class [mscorlib]System.IDisposable\n\t\t)\n\n\t\tIL_0000: nop\n\t\tIL_0001: ldstr \"some text\"\n\t\tIL_0006: call void [mscorlib]System.Console::WriteLine(string)\n\t\tIL_000b: nop\n\t\tIL_000c: ldstr \"x.txt\"\n\t\tIL_0011: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::OpenRead(string)\n\t\tIL_0016: stloc.1\n\t\t.try\n\t\t{\n\t\t\tIL_0017: ldloc.1\n\t\t\tIL_0018: callvirt instance int32 [mscorlib]System.IO.Stream::ReadByte()\n\t\t\tIL_001d: stloc.2\n\t\t\tIL_001e: leave.s IL_0036\n\t\t} // end .try\n\t\tfinally\n\t\t{\n\t\t\tIL_0020: ldloc.1\n\t\t\tIL_0021: isinst [mscorlib]System.IDisposable\n\t\t\tIL_0026: stloc.3\n\t\t\tIL_0027: ldloc.3\n\t\t\tIL_0028: brfalse.s IL_0033\n\n\t\t\tIL_002a: ldloc.3\n\t\t\tIL_002b: callvirt instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\tIL_0030: ldnull\n\t\t\tIL_0031: pop\n\t\t\tIL_0032: endfinally\n\n\t\t\tIL_0033: ldnull\n\t\t\tIL_0034: pop\n\t\t\tIL_0035: endfinally\n\t\t} // end handler\n\n\t\tIL_0036: ldloc.2\n\t\tIL_0037: stloc.0\n\t\tIL_0038: ldstr \"read:\"\n\t\tIL_003d: ldloca.s firstByte\n\t\tIL_003f: constrained. [mscorlib]System.Int32\n\t\tIL_0045: callvirt instance string [mscorlib]System.Object::ToString()\n\t\tIL_004a: call string [mscorlib]System.String::Concat(string, string)\n\t\tIL_004f: call void [mscorlib]System.Console::WriteLine(string)\n\t\tIL_0054: ret\n\t} // end of method FSharpUsingPatterns::sample4\n\n\t.method public static \n\t\tvoid sample5 () cil managed \n\t{\n\t\t// Method begins at RVA 0x21d0\n\t\t// Code size 134 (0x86)\n\t\t.maxstack 5\n\t\t.locals init (\n\t\t\t[0] int32 firstByte,\n\t\t\t[1] class [mscorlib]System.IO.FileStream fs,\n\t\t\t[2] int32 secondByte,\n\t\t\t[3] class [mscorlib]System.IDisposable,\n\t\t\t[4] int32,\n\t\t\t[5] int32\n\t\t)\n\n\t\tIL_0000: nop\n\t\tIL_0001: ldstr \"some text\"\n\t\tIL_0006: call void [mscorlib]System.Console::WriteLine(string)\n\t\tIL_000b: nop\n\t\tIL_000c: ldstr \"x.txt\"\n\t\tIL_0011: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::OpenRead(string)\n\t\tIL_0016: stloc.1\n\t\t.try\n\t\t{\n\t\t\tIL_0017: ldloc.1\n\t\t\tIL_0018: callvirt instance int32 [mscorlib]System.IO.Stream::ReadByte()\n\t\t\tIL_001d: stloc.2\n\t\t\tIL_001e: leave.s IL_0036\n\t\t} // end .try\n\t\tfinally\n\t\t{\n\t\t\tIL_0020: ldloc.1\n\t\t\tIL_0021: isinst [mscorlib]System.IDisposable\n\t\t\tIL_0026: stloc.3\n\t\t\tIL_0027: ldloc.3\n\t\t\tIL_0028: brfalse.s IL_0033\n\n\t\t\tIL_002a: ldloc.3\n\t\t\tIL_002b: callvirt instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\tIL_0030: ldnull\n\t\t\tIL_0031: pop\n\t\t\tIL_0032: endfinally\n\n\t\t\tIL_0033: ldnull\n\t\t\tIL_0034: pop\n\t\t\tIL_0035: endfinally\n\t\t} // end handler\n\n\t\tIL_0036: ldloc.2\n\t\tIL_0037: stloc.0\n\t\tIL_0038: nop\n\t\tIL_0039: ldstr \"x.txt\"\n\t\tIL_003e: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::OpenRead(string)\n\t\tIL_0043: stloc.1\n\t\t.try\n\t\t{\n\t\t\tIL_0044: ldloc.1\n\t\t\tIL_0045: callvirt instance int32 [mscorlib]System.IO.Stream::ReadByte()\n\t\t\tIL_004a: stloc.s 5\n\t\t\tIL_004c: ldloc.1\n\t\t\tIL_004d: callvirt instance int32 [mscorlib]System.IO.Stream::ReadByte()\n\t\t\tIL_0052: stloc.s 4\n\t\t\tIL_0054: leave.s IL_006c\n\t\t} // end .try\n\t\tfinally\n\t\t{\n\t\t\tIL_0056: ldloc.1\n\t\t\tIL_0057: isinst [mscorlib]System.IDisposable\n\t\t\tIL_005c: stloc.3\n\t\t\tIL_005d: ldloc.3\n\t\t\tIL_005e: brfalse.s IL_0069\n\n\t\t\tIL_0060: ldloc.3\n\t\t\tIL_0061: callvirt instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\tIL_0066: ldnull\n\t\t\tIL_0067: pop\n\t\t\tIL_0068: endfinally\n\n\t\t\tIL_0069: ldnull\n\t\t\tIL_006a: pop\n\t\t\tIL_006b: endfinally\n\t\t} // end handler\n\n\t\tIL_006c: ldloc.s 4\n\t\tIL_006e: stloc.2\n\t\tIL_006f: ldstr \"read: {0}, {1}\"\n\t\tIL_0074: ldloc.0\n\t\tIL_0075: box [mscorlib]System.Int32\n\t\tIL_007a: ldloc.2\n\t\tIL_007b: box [mscorlib]System.Int32\n\t\tIL_0080: call void [mscorlib]System.Console::WriteLine(string, object, object)\n\t\tIL_0085: ret\n\t} // end of method FSharpUsingPatterns::sample5\n\n} // end of class FSharpUsingPatterns\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/GuessAccessors.cs",
    "content": "\n\n// ClassLibrary1.UnknownClassTest\nusing System;\nusing System.Collections.Generic;\n\nusing UnknownNamespace;\nnamespace ClassLibrary1\n{\n\tpublic class UnknownClassTest : EventArgs\n\t{\n\t\tpublic void MethodUnknownClass()\n\t\t{\n\t\t\t//IL_0001: Unknown result type (might be due to invalid IL or missing references)\n\t\t\t//IL_0007: Expected O, but got Unknown\n\t\t\tUnknownClass val = new UnknownClass();\n\t\t\tint? unknownProperty = val.UnknownProperty;\n\t\t\tint? num = (val.UnknownProperty = unknownProperty.GetValueOrDefault());\n\t\t\tint? num3 = num;\n\t\t\tList<object> list = new List<object> {\n\t\t\tval[unknownProperty.Value] ?? \"\",\n\t\t\tval.NotProperty,\n\t\t\tval.get_NotPropertyWithGeneric<string>(42),\n\t\t\tval[42],\n\t\t\tval.get_NotPropertyWithParameterAndGeneric<object>(int.MinValue),\n\t\t\tval.get_PropertyCalledGet,\n\t\t\tval.set_HasReturnType(),\n\t\t\tval.set_HasReturnType(\"\")\n\t\t};\n\t\t\tval.get_NoReturnType();\n\t\t\tval.set_NoValue();\n\t\t\tval.OnEvent += Instance_OnEvent;\n\t\t\tval.OnEvent -= Instance_OnEvent;\n\t\t\tstring text = val[(long?)null];\n\t\t\tval[(long?)long.MaxValue] = text;\n\t\t\tIntPtr intPtr = val[UIntPtr.Zero, \"Hello\"];\n\t\t\tval[(UIntPtr)32uL, \"World\"] = intPtr;\n\t\t}\n\n\t\tpublic void MethodUnknownGenericClass()\n\t\t{\n\t\t\t//IL_00b1: Unknown result type (might be due to invalid IL or missing references)\n\t\t\t//IL_00bc: Expected O, but got Unknown\n\t\t\t//IL_00be: Unknown result type (might be due to invalid IL or missing references)\n\t\t\t//IL_00c3: Unknown result type (might be due to invalid IL or missing references)\n\t\t\t//IL_00cd: Expected O, but got Unknown\n\t\t\t//IL_00cd: Expected O, but got Unknown\n\t\t\t//IL_00d0: Unknown result type (might be due to invalid IL or missing references)\n\t\t\t//IL_00d5: Unknown result type (might be due to invalid IL or missing references)\n\t\t\t//IL_00e1: Expected O, but got Unknown\n\t\t\t//IL_00e1: Expected O, but got Unknown\n\t\t\tUnknownGenericClass<UnknownEventArgs> val = new UnknownGenericClass<UnknownEventArgs>();\n\t\t\tUnknownEventArgs e = (val.UnknownProperty = val.UnknownProperty);\n\t\t\tList<object> list = new List<object> {\n\t\t\t\tval[((object)e).GetHashCode()] ?? \"\",\n\t\t\t\tval.NotProperty,\n\t\t\t\tval.get_NotPropertyWithGeneric<string>(42),\n\t\t\t\tval[42],\n\t\t\t\tval.get_NotPropertyWithParameterAndGeneric<object>(int.MinValue),\n\t\t\t\tval.get_PropertyCalledGet\n\t\t\t};\n\t\t\tval.OnEvent += Instance_OnEvent;\n\t\t\tval.OnEvent -= Instance_OnEvent;\n\t\t\tUnknownEventArgs e2 = val[(UnknownEventArgs)null];\n\t\t\tval[new UnknownEventArgs()] = e2;\n\t\t\tUnknownEventArgs e3 = val[new UnknownEventArgs(), new UnknownEventArgs()];\n\t\t\tval[new UnknownEventArgs(), new UnknownEventArgs()] = e3;\n\t\t}\n\n\t\tpublic void MethodUnknownStatic()\n\t\t{\n\t\t\tint? num = (UnknownStaticClass.UnknownProperty = UnknownStaticClass.UnknownProperty);\n\t\t\tList<object> list = new List<object> {\n\t\t\t\tUnknownStaticClass[num.Value] ?? \"\",\n\t\t\t\tUnknownStaticClass.NotProperty,\n\t\t\t\tUnknownStaticClass.get_NotPropertyWithGeneric<string>(42),\n\t\t\t\tUnknownStaticClass[42],\n\t\t\t\tUnknownStaticClass.get_NotPropertyWithParameterAndGeneric<object>(int.MinValue),\n\t\t\t\tUnknownStaticClass.get_PropertyCalledGet\n\t\t\t};\n\t\t\tUnknownStaticClass.OnEvent += Instance_OnEvent;\n\t\t\tUnknownStaticClass.OnEvent -= Instance_OnEvent;\n\t\t}\n\n\t\tpublic void MethodUnknownStaticGeneric()\n\t\t{\n\t\t\tstring text = (UnknownStaticGenericClass<string>.UnknownProperty = UnknownStaticGenericClass<string>.UnknownProperty);\n\t\t\tList<object> list = new List<object> {\n\t\t\t\tUnknownStaticGenericClass<string>[text.Length] ?? \"\",\n\t\t\t\tUnknownStaticGenericClass<string>.NotProperty,\n\t\t\t\tUnknownStaticGenericClass<string>.get_NotPropertyWithGeneric<string>(42),\n\t\t\t\tUnknownStaticGenericClass<string>[42],\n\t\t\t\tUnknownStaticGenericClass<string>.get_NotPropertyWithParameterAndGeneric<object>(int.MinValue),\n\t\t\t\tUnknownStaticGenericClass<string>.get_PropertyCalledGet\n\t\t\t};\n\t\t\tUnknownStaticGenericClass<string>.OnEvent += Instance_OnEvent;\n\t\t\tUnknownStaticGenericClass<string>.OnEvent -= Instance_OnEvent;\n\t\t}\n\n\t\tpublic void MethodUnknownIndexerInitializer()\n\t\t{\n\t\t\t//IL_0006: Unknown result type (might be due to invalid IL or missing references)\n\t\t\tnew UnknownClass {\n\t\t\t\t[\"a\"] = 1,\n\t\t\t\t[\"b\"] = 2\n\t\t\t};\n\t\t}\n\n\t\tprivate void Instance_OnEvent(object sender, EventArgs e)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tprivate void Instance_OnEvent(object sender, UnknownEventArgs e)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tprivate void Instance_OnEvent(object sender, string e)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tprivate static void Instance_OnEvent(object sender, object e)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/GuessAccessors.il",
    "content": ".class /* 33554434 */ public auto ansi beforefieldinit ClassLibrary1.UnknownClassTest\n\textends [netstandard]System.EventArgs\n{\n\t// Methods\n\t.method /* 100663297 */ public hidebysig \n\t\tinstance void MethodUnknownClass () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Header size: 12\n\t\t// Code size: 325 (0x145)\n\t\t.maxstack 4\n\t\t.locals /* 285212673 */ init (\n\t\t\t[0] class [UnknownAssembly]UnknownNamespace.UnknownClass 'instance',\n\t\t\t[1] valuetype [netstandard]System.Nullable`1<int32> valueOfProp,\n\t\t\t[2] valuetype [netstandard]System.Nullable`1<int32> x,\n\t\t\t[3] class [netstandard]System.Collections.Generic.List`1<object> list,\n\t\t\t[4] string valueOfIndexer,\n\t\t\t[5] native int valueOfMultiIndexer,\n\t\t\t[6] valuetype [netstandard]System.Nullable`1<int32>,\n\t\t\t[7] valuetype [netstandard]System.Nullable`1<int64>\n\t\t)\n\n\t\tIL_0000: nop\n\t\tIL_0001: newobj instance void [UnknownAssembly]UnknownNamespace.UnknownClass::.ctor() /* 167772171 */\n\t\tIL_0006: stloc.0\n\t\tIL_0007: ldloc.0\n\t\tIL_0008: callvirt instance valuetype [netstandard]System.Nullable`1<int32> [UnknownAssembly]UnknownNamespace.UnknownClass::get_UnknownProperty() /* 167772172 */\n\t\tIL_000d: stloc.1\n\t\tIL_000e: ldloc.0\n\t\tIL_000f: ldloca.s 6\n\t\tIL_0011: ldloca.s 1\n\t\tIL_0013: call instance !0 valuetype [netstandard]System.Nullable`1<int32>::GetValueOrDefault() /* 167772173 */\n\t\tIL_0018: call instance void valuetype [netstandard]System.Nullable`1<int32>::.ctor(!0) /* 167772174 */\n\t\tIL_001d: ldloc.s 6\n\t\tIL_001f: callvirt instance void [UnknownAssembly]UnknownNamespace.UnknownClass::set_UnknownProperty(valuetype [netstandard]System.Nullable`1<int32>) /* 167772175 */\n\t\tIL_0024: nop\n\t\tIL_0025: ldloc.s 6\n\t\tIL_0027: stloc.2\n\t\tIL_0028: newobj instance void class [netstandard]System.Collections.Generic.List`1<object>::.ctor() /* 167772176 */\n\t\tIL_002d: dup\n\t\tIL_002e: ldloc.0\n\t\tIL_002f: ldloca.s 1\n\t\tIL_0031: call instance !0 valuetype [netstandard]System.Nullable`1<int32>::get_Value() /* 167772177 */\n\t\tIL_0036: callvirt instance string [UnknownAssembly]UnknownNamespace.UnknownClass::get_NotPropertyWithParameter(int32) /* 167772178 */\n\t\tIL_003b: dup\n\t\tIL_003c: brtrue.s IL_0044\n\n\t\tIL_003e: pop\n\t\tIL_003f: ldstr \"\" /* 1879048193 */\n\n\t\tIL_0044: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0049: nop\n\t\tIL_004a: dup\n\t\tIL_004b: ldloc.0\n\t\tIL_004c: callvirt instance string [UnknownAssembly]UnknownNamespace.UnknownClass::get_NotProperty() /* 167772180 */\n\t\tIL_0051: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0056: nop\n\t\tIL_0057: dup\n\t\tIL_0058: ldloc.0\n\t\tIL_0059: ldc.i4.s 42\n\t\tIL_005b: callvirt instance string [UnknownAssembly]UnknownNamespace.UnknownClass::get_NotPropertyWithGeneric<string>(int32) /* 721420289 */\n\t\tIL_0060: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0065: nop\n\t\tIL_0066: dup\n\t\tIL_0067: ldloc.0\n\t\tIL_0068: ldc.i4.s 42\n\t\tIL_006a: callvirt instance string [UnknownAssembly]UnknownNamespace.UnknownClass::get_NotPropertyWithParameter(int32) /* 167772178 */\n\t\tIL_006f: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0074: nop\n\t\tIL_0075: dup\n\t\tIL_0076: ldloc.0\n\t\tIL_0077: ldc.i4 -2147483648\n\t\tIL_007c: callvirt instance string [UnknownAssembly]UnknownNamespace.UnknownClass::get_NotPropertyWithParameterAndGeneric<object>(int32) /* 721420290 */\n\t\tIL_0081: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0086: nop\n\t\tIL_0087: dup\n\t\tIL_0088: ldloc.0\n\t\tIL_0089: callvirt instance string [UnknownAssembly]UnknownNamespace.UnknownClass::get_get_PropertyCalledGet() /* 167772183 */\n\t\tIL_008e: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0093: nop\n\t\tIL_0094: dup\n\t\tIL_0095: ldloc.0\n\t\tIL_0096: callvirt instance int32 [UnknownAssembly]UnknownNamespace.UnknownClass::set_HasReturnType() /* 167772184 */\n\t\tIL_009b: box [netstandard]System.Int32 /* 16777235 */\n\t\tIL_00a0: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_00a5: nop\n\t\tIL_00a6: dup\n\t\tIL_00a7: ldloc.0\n\t\tIL_00a8: ldstr \"\" /* 1879048193 */\n\t\tIL_00ad: callvirt instance int32 [UnknownAssembly]UnknownNamespace.UnknownClass::set_HasReturnType(string) /* 167772185 */\n\t\tIL_00b2: box [netstandard]System.Int32 /* 16777235 */\n\t\tIL_00b7: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_00bc: nop\n\t\tIL_00bd: stloc.3\n\t\tIL_00be: ldloc.0\n\t\tIL_00bf: callvirt instance void [UnknownAssembly]UnknownNamespace.UnknownClass::get_NoReturnType() /* 167772186 */\n\t\tIL_00c4: nop\n\t\tIL_00c5: ldloc.0\n\t\tIL_00c6: callvirt instance void [UnknownAssembly]UnknownNamespace.UnknownClass::set_NoValue() /* 167772187 */\n\t\tIL_00cb: nop\n\t\tIL_00cc: ldloc.0\n\t\tIL_00cd: ldarg.0\n\t\tIL_00ce: ldftn instance void ClassLibrary1.UnknownClassTest::Instance_OnEvent(object, class [netstandard]System.EventArgs) /* 100663301 */\n\t\tIL_00d4: newobj instance void [netstandard]System.EventHandler::.ctor(object, native int) /* 167772188 */\n\t\tIL_00d9: callvirt instance void [UnknownAssembly]UnknownNamespace.UnknownClass::add_OnEvent(class [netstandard]System.EventHandler) /* 167772189 */\n\t\tIL_00de: nop\n\t\tIL_00df: ldloc.0\n\t\tIL_00e0: ldarg.0\n\t\tIL_00e1: ldftn instance void ClassLibrary1.UnknownClassTest::Instance_OnEvent(object, class [netstandard]System.EventArgs) /* 100663301 */\n\t\tIL_00e7: newobj instance void [netstandard]System.EventHandler::.ctor(object, native int) /* 167772188 */\n\t\tIL_00ec: callvirt instance void [UnknownAssembly]UnknownNamespace.UnknownClass::remove_OnEvent(class [netstandard]System.EventHandler) /* 167772190 */\n\t\tIL_00f1: nop\n\t\tIL_00f2: ldloc.0\n\t\tIL_00f3: ldloca.s 7\n\t\tIL_00f5: initobj valuetype [netstandard]System.Nullable`1<int64> /* 452984835 */\n\t\tIL_00fb: ldloc.s 7\n\t\tIL_00fd: callvirt instance string [UnknownAssembly]UnknownNamespace.UnknownClass::get_Item(valuetype [netstandard]System.Nullable`1<int64>) /* 167772191 */\n\t\tIL_0102: stloc.s 4\n\t\tIL_0104: ldloc.0\n\t\tIL_0105: ldc.i8 9223372036854775807\n\t\tIL_010e: newobj instance void valuetype [netstandard]System.Nullable`1<int64>::.ctor(!0) /* 167772192 */\n\t\tIL_0113: ldloc.s 4\n\t\tIL_0115: callvirt instance void [UnknownAssembly]UnknownNamespace.UnknownClass::set_Item(valuetype [netstandard]System.Nullable`1<int64>, string) /* 167772193 */\n\t\tIL_011a: nop\n\t\tIL_011b: ldloc.0\n\t\tIL_011c: ldsfld native uint [netstandard]System.UIntPtr::Zero /* 167772194 */\n\t\tIL_0121: ldstr \"Hello\" /* 1879048195 */\n\t\tIL_0126: callvirt instance native int& [UnknownAssembly]UnknownNamespace.UnknownClass::get_Item(native uint, string) /* 167772195 */\n\t\tIL_012b: ldind.i\n\t\tIL_012c: stloc.s 5\n\t\tIL_012e: ldloc.0\n\t\tIL_012f: ldc.i4.s 32\n\t\tIL_0131: conv.i8\n\t\tIL_0132: call native uint [netstandard]System.UIntPtr::op_Explicit(uint64) /* 167772196 */\n\t\tIL_0137: ldstr \"World\" /* 1879048207 */\n\t\tIL_013c: callvirt instance native int& [UnknownAssembly]UnknownNamespace.UnknownClass::get_Item(native uint, string) /* 167772195 */\n\t\tIL_0141: ldloc.s 5\n\t\tIL_0143: stind.i\n\t\tIL_0144: ret\n\t} // end of method UnknownClassTest::MethodUnknownClass\n\n\t.method /* 100663298 */ public hidebysig \n\t\tinstance void MethodUnknownGenericClass () cil managed \n\t{\n\t\t// Method begins at RVA 0x21a4\n\t\t// Header size: 12\n\t\t// Code size: 227 (0xe3)\n\t\t.maxstack 4\n\t\t.locals /* 285212674 */ init (\n\t\t\t[0] class [UnknownAssembly]UnknownNamespace.UnknownGenericClass`1<class [UnknownAssembly]UnknownNamespace.UnknownEventArgs> 'instance',\n\t\t\t[1] class [UnknownAssembly]UnknownNamespace.UnknownEventArgs valueOfProp,\n\t\t\t[2] class [netstandard]System.Collections.Generic.List`1<object> list,\n\t\t\t[3] class [UnknownAssembly]UnknownNamespace.UnknownEventArgs valueOfIndexer,\n\t\t\t[4] class [UnknownAssembly]UnknownNamespace.UnknownEventArgs valueOfMultiIndexer\n\t\t)\n\n\t\tIL_0000: nop\n\t\tIL_0001: newobj instance void class [UnknownAssembly]UnknownNamespace.UnknownGenericClass`1<class [UnknownAssembly]UnknownNamespace.UnknownEventArgs>::.ctor() /* 167772197 */\n\t\tIL_0006: stloc.0\n\t\tIL_0007: ldloc.0\n\t\tIL_0008: callvirt instance !0 class [UnknownAssembly]UnknownNamespace.UnknownGenericClass`1<class [UnknownAssembly]UnknownNamespace.UnknownEventArgs>::get_UnknownProperty() /* 167772198 */\n\t\tIL_000d: stloc.1\n\t\tIL_000e: ldloc.0\n\t\tIL_000f: ldloc.1\n\t\tIL_0010: callvirt instance void class [UnknownAssembly]UnknownNamespace.UnknownGenericClass`1<class [UnknownAssembly]UnknownNamespace.UnknownEventArgs>::set_UnknownProperty(!0) /* 167772199 */\n\t\tIL_0015: nop\n\t\tIL_0016: newobj instance void class [netstandard]System.Collections.Generic.List`1<object>::.ctor() /* 167772176 */\n\t\tIL_001b: dup\n\t\tIL_001c: ldloc.0\n\t\tIL_001d: ldloc.1\n\t\tIL_001e: callvirt instance int32 [netstandard]System.Object::GetHashCode() /* 167772200 */\n\t\tIL_0023: callvirt instance string class [UnknownAssembly]UnknownNamespace.UnknownGenericClass`1<class [UnknownAssembly]UnknownNamespace.UnknownEventArgs>::get_NotPropertyWithParameter(int32) /* 167772201 */\n\t\tIL_0028: dup\n\t\tIL_0029: brtrue.s IL_0031\n\n\t\tIL_002b: pop\n\t\tIL_002c: ldstr \"\" /* 1879048193 */\n\n\t\tIL_0031: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0036: nop\n\t\tIL_0037: dup\n\t\tIL_0038: ldloc.0\n\t\tIL_0039: callvirt instance string class [UnknownAssembly]UnknownNamespace.UnknownGenericClass`1<class [UnknownAssembly]UnknownNamespace.UnknownEventArgs>::get_NotProperty() /* 167772202 */\n\t\tIL_003e: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0043: nop\n\t\tIL_0044: dup\n\t\tIL_0045: ldloc.0\n\t\tIL_0046: ldc.i4.s 42\n\t\tIL_0048: callvirt instance string class [UnknownAssembly]UnknownNamespace.UnknownGenericClass`1<class [UnknownAssembly]UnknownNamespace.UnknownEventArgs>::get_NotPropertyWithGeneric<string>(int32) /* 721420291 */\n\t\tIL_004d: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0052: nop\n\t\tIL_0053: dup\n\t\tIL_0054: ldloc.0\n\t\tIL_0055: ldc.i4.s 42\n\t\tIL_0057: callvirt instance string class [UnknownAssembly]UnknownNamespace.UnknownGenericClass`1<class [UnknownAssembly]UnknownNamespace.UnknownEventArgs>::get_NotPropertyWithParameter(int32) /* 167772201 */\n\t\tIL_005c: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0061: nop\n\t\tIL_0062: dup\n\t\tIL_0063: ldloc.0\n\t\tIL_0064: ldc.i4 -2147483648\n\t\tIL_0069: callvirt instance string class [UnknownAssembly]UnknownNamespace.UnknownGenericClass`1<class [UnknownAssembly]UnknownNamespace.UnknownEventArgs>::get_NotPropertyWithParameterAndGeneric<object>(int32) /* 721420292 */\n\t\tIL_006e: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0073: nop\n\t\tIL_0074: dup\n\t\tIL_0075: ldloc.0\n\t\tIL_0076: callvirt instance string class [UnknownAssembly]UnknownNamespace.UnknownGenericClass`1<class [UnknownAssembly]UnknownNamespace.UnknownEventArgs>::get_get_PropertyCalledGet() /* 167772205 */\n\t\tIL_007b: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0080: nop\n\t\tIL_0081: stloc.2\n\t\tIL_0082: ldloc.0\n\t\tIL_0083: ldarg.0\n\t\tIL_0084: ldftn instance void ClassLibrary1.UnknownClassTest::Instance_OnEvent(object, class [UnknownAssembly]UnknownNamespace.UnknownEventArgs) /* 100663302 */\n\t\tIL_008a: newobj instance void class [netstandard]System.EventHandler`1<class [UnknownAssembly]UnknownNamespace.UnknownEventArgs>::.ctor(object, native int) /* 167772206 */\n\t\tIL_008f: callvirt instance void class [UnknownAssembly]UnknownNamespace.UnknownGenericClass`1<class [UnknownAssembly]UnknownNamespace.UnknownEventArgs>::add_OnEvent(class [netstandard]System.EventHandler`1<!0>) /* 167772207 */\n\t\tIL_0094: nop\n\t\tIL_0095: ldloc.0\n\t\tIL_0096: ldarg.0\n\t\tIL_0097: ldftn instance void ClassLibrary1.UnknownClassTest::Instance_OnEvent(object, class [UnknownAssembly]UnknownNamespace.UnknownEventArgs) /* 100663302 */\n\t\tIL_009d: newobj instance void class [netstandard]System.EventHandler`1<class [UnknownAssembly]UnknownNamespace.UnknownEventArgs>::.ctor(object, native int) /* 167772206 */\n\t\tIL_00a2: callvirt instance void class [UnknownAssembly]UnknownNamespace.UnknownGenericClass`1<class [UnknownAssembly]UnknownNamespace.UnknownEventArgs>::remove_OnEvent(class [netstandard]System.EventHandler`1<!0>) /* 167772208 */\n\t\tIL_00a7: nop\n\t\tIL_00a8: ldloc.0\n\t\tIL_00a9: ldnull\n\t\tIL_00aa: callvirt instance !0 class [UnknownAssembly]UnknownNamespace.UnknownGenericClass`1<class [UnknownAssembly]UnknownNamespace.UnknownEventArgs>::get_Item(!0) /* 167772209 */\n\t\tIL_00af: stloc.3\n\t\tIL_00b0: ldloc.0\n\t\tIL_00b1: newobj instance void [UnknownAssembly]UnknownNamespace.UnknownEventArgs::.ctor() /* 167772210 */\n\t\tIL_00b6: ldloc.3\n\t\tIL_00b7: callvirt instance void class [UnknownAssembly]UnknownNamespace.UnknownGenericClass`1<class [UnknownAssembly]UnknownNamespace.UnknownEventArgs>::set_Item(!0, !0) /* 167772211 */\n\t\tIL_00bc: nop\n\t\tIL_00bd: ldloc.0\n\t\tIL_00be: newobj instance void [UnknownAssembly]UnknownNamespace.UnknownEventArgs::.ctor() /* 167772210 */\n\t\tIL_00c3: newobj instance void [UnknownAssembly]UnknownNamespace.UnknownEventArgs::.ctor() /* 167772210 */\n\t\tIL_00c8: callvirt instance !0 class [UnknownAssembly]UnknownNamespace.UnknownGenericClass`1<class [UnknownAssembly]UnknownNamespace.UnknownEventArgs>::get_Item(!0, !0) /* 167772212 */\n\t\tIL_00cd: stloc.s 4\n\t\tIL_00cf: ldloc.0\n\t\tIL_00d0: newobj instance void [UnknownAssembly]UnknownNamespace.UnknownEventArgs::.ctor() /* 167772210 */\n\t\tIL_00d5: newobj instance void [UnknownAssembly]UnknownNamespace.UnknownEventArgs::.ctor() /* 167772210 */\n\t\tIL_00da: ldloc.s 4\n\t\tIL_00dc: callvirt instance void class [UnknownAssembly]UnknownNamespace.UnknownGenericClass`1<class [UnknownAssembly]UnknownNamespace.UnknownEventArgs>::set_Item(!0, !0, !0) /* 167772213 */\n\t\tIL_00e1: nop\n\t\tIL_00e2: ret\n\t} // end of method UnknownClassTest::MethodUnknownGenericClass\n\n\t.method /* 100663299 */ public hidebysig \n\t\tinstance void MethodUnknownStatic () cil managed \n\t{\n\t\t// Method begins at RVA 0x2294\n\t\t// Header size: 12\n\t\t// Code size: 154 (0x9a)\n\t\t.maxstack 4\n\t\t.locals /* 285212675 */ init (\n\t\t\t[0] valuetype [netstandard]System.Nullable`1<int32> valueOfProp,\n\t\t\t[1] class [netstandard]System.Collections.Generic.List`1<object> list\n\t\t)\n\n\t\tIL_0000: nop\n\t\tIL_0001: call valuetype [netstandard]System.Nullable`1<int32> [UnknownAssembly]UnknownNamespace.UnknownStaticClass::get_UnknownProperty() /* 167772214 */\n\t\tIL_0006: stloc.0\n\t\tIL_0007: ldloc.0\n\t\tIL_0008: call void [UnknownAssembly]UnknownNamespace.UnknownStaticClass::set_UnknownProperty(valuetype [netstandard]System.Nullable`1<int32>) /* 167772215 */\n\t\tIL_000d: nop\n\t\tIL_000e: newobj instance void class [netstandard]System.Collections.Generic.List`1<object>::.ctor() /* 167772176 */\n\t\tIL_0013: dup\n\t\tIL_0014: ldloca.s 0\n\t\tIL_0016: call instance !0 valuetype [netstandard]System.Nullable`1<int32>::get_Value() /* 167772177 */\n\t\tIL_001b: call string [UnknownAssembly]UnknownNamespace.UnknownStaticClass::get_NotPropertyWithParameter(int32) /* 167772216 */\n\t\tIL_0020: dup\n\t\tIL_0021: brtrue.s IL_0029\n\n\t\tIL_0023: pop\n\t\tIL_0024: ldstr \"\" /* 1879048193 */\n\n\t\tIL_0029: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_002e: nop\n\t\tIL_002f: dup\n\t\tIL_0030: call string [UnknownAssembly]UnknownNamespace.UnknownStaticClass::get_NotProperty() /* 167772217 */\n\t\tIL_0035: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_003a: nop\n\t\tIL_003b: dup\n\t\tIL_003c: ldc.i4.s 42\n\t\tIL_003e: call string [UnknownAssembly]UnknownNamespace.UnknownStaticClass::get_NotPropertyWithGeneric<string>(int32) /* 721420293 */\n\t\tIL_0043: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0048: nop\n\t\tIL_0049: dup\n\t\tIL_004a: ldc.i4.s 42\n\t\tIL_004c: call string [UnknownAssembly]UnknownNamespace.UnknownStaticClass::get_NotPropertyWithParameter(int32) /* 167772216 */\n\t\tIL_0051: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0056: nop\n\t\tIL_0057: dup\n\t\tIL_0058: ldc.i4 -2147483648\n\t\tIL_005d: call string [UnknownAssembly]UnknownNamespace.UnknownStaticClass::get_NotPropertyWithParameterAndGeneric<object>(int32) /* 721420294 */\n\t\tIL_0062: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0067: nop\n\t\tIL_0068: dup\n\t\tIL_0069: call string [UnknownAssembly]UnknownNamespace.UnknownStaticClass::get_get_PropertyCalledGet() /* 167772220 */\n\t\tIL_006e: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0073: nop\n\t\tIL_0074: stloc.1\n\t\tIL_0075: ldarg.0\n\t\tIL_0076: ldftn instance void ClassLibrary1.UnknownClassTest::Instance_OnEvent(object, class [netstandard]System.EventArgs) /* 100663301 */\n\t\tIL_007c: newobj instance void [netstandard]System.EventHandler::.ctor(object, native int) /* 167772188 */\n\t\tIL_0081: call void [UnknownAssembly]UnknownNamespace.UnknownStaticClass::add_OnEvent(class [netstandard]System.EventHandler) /* 167772221 */\n\t\tIL_0086: nop\n\t\tIL_0087: ldarg.0\n\t\tIL_0088: ldftn instance void ClassLibrary1.UnknownClassTest::Instance_OnEvent(object, class [netstandard]System.EventArgs) /* 100663301 */\n\t\tIL_008e: newobj instance void [netstandard]System.EventHandler::.ctor(object, native int) /* 167772188 */\n\t\tIL_0093: call void [UnknownAssembly]UnknownNamespace.UnknownStaticClass::remove_OnEvent(class [netstandard]System.EventHandler) /* 167772222 */\n\t\tIL_0098: nop\n\t\tIL_0099: ret\n\t} // end of method UnknownClassTest::MethodUnknownStatic\n\n\t.method /* 100663300 */ public hidebysig \n\t\tinstance void MethodUnknownStaticGeneric () cil managed \n\t{\n\t\t// Method begins at RVA 0x233c\n\t\t// Header size: 12\n\t\t// Code size: 153 (0x99)\n\t\t.maxstack 4\n\t\t.locals /* 285212676 */ init (\n\t\t\t[0] string valueOfProp,\n\t\t\t[1] class [netstandard]System.Collections.Generic.List`1<object> list\n\t\t)\n\n\t\tIL_0000: nop\n\t\tIL_0001: call !0 class [UnknownAssembly]UnknownNamespace.UnknownStaticGenericClass`1<string>::get_UnknownProperty() /* 167772223 */\n\t\tIL_0006: stloc.0\n\t\tIL_0007: ldloc.0\n\t\tIL_0008: call void class [UnknownAssembly]UnknownNamespace.UnknownStaticGenericClass`1<string>::set_UnknownProperty(!0) /* 167772224 */\n\t\tIL_000d: nop\n\t\tIL_000e: newobj instance void class [netstandard]System.Collections.Generic.List`1<object>::.ctor() /* 167772176 */\n\t\tIL_0013: dup\n\t\tIL_0014: ldloc.0\n\t\tIL_0015: callvirt instance int32 [netstandard]System.String::get_Length() /* 167772225 */\n\t\tIL_001a: call string class [UnknownAssembly]UnknownNamespace.UnknownStaticGenericClass`1<string>::get_NotPropertyWithParameter(int32) /* 167772226 */\n\t\tIL_001f: dup\n\t\tIL_0020: brtrue.s IL_0028\n\n\t\tIL_0022: pop\n\t\tIL_0023: ldstr \"\" /* 1879048193 */\n\n\t\tIL_0028: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_002d: nop\n\t\tIL_002e: dup\n\t\tIL_002f: call string class [UnknownAssembly]UnknownNamespace.UnknownStaticGenericClass`1<string>::get_NotProperty() /* 167772227 */\n\t\tIL_0034: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0039: nop\n\t\tIL_003a: dup\n\t\tIL_003b: ldc.i4.s 42\n\t\tIL_003d: call string class [UnknownAssembly]UnknownNamespace.UnknownStaticGenericClass`1<string>::get_NotPropertyWithGeneric<string>(int32) /* 721420295 */\n\t\tIL_0042: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0047: nop\n\t\tIL_0048: dup\n\t\tIL_0049: ldc.i4.s 42\n\t\tIL_004b: call string class [UnknownAssembly]UnknownNamespace.UnknownStaticGenericClass`1<string>::get_NotPropertyWithParameter(int32) /* 167772226 */\n\t\tIL_0050: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0055: nop\n\t\tIL_0056: dup\n\t\tIL_0057: ldc.i4 -2147483648\n\t\tIL_005c: call string class [UnknownAssembly]UnknownNamespace.UnknownStaticGenericClass`1<string>::get_NotPropertyWithParameterAndGeneric<object>(int32) /* 721420296 */\n\t\tIL_0061: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0066: nop\n\t\tIL_0067: dup\n\t\tIL_0068: call string class [UnknownAssembly]UnknownNamespace.UnknownStaticGenericClass`1<string>::get_get_PropertyCalledGet() /* 167772230 */\n\t\tIL_006d: callvirt instance void class [netstandard]System.Collections.Generic.List`1<object>::Add(!0) /* 167772179 */\n\t\tIL_0072: nop\n\t\tIL_0073: stloc.1\n\t\tIL_0074: ldarg.0\n\t\tIL_0075: ldftn instance void ClassLibrary1.UnknownClassTest::Instance_OnEvent(object, string) /* 100663303 */\n\t\tIL_007b: newobj instance void class [netstandard]System.EventHandler`1<string>::.ctor(object, native int) /* 167772231 */\n\t\tIL_0080: call void class [UnknownAssembly]UnknownNamespace.UnknownStaticGenericClass`1<string>::add_OnEvent(class [netstandard]System.EventHandler`1<!0>) /* 167772232 */\n\t\tIL_0085: nop\n\t\tIL_0086: ldarg.0\n\t\tIL_0087: ldftn instance void ClassLibrary1.UnknownClassTest::Instance_OnEvent(object, string) /* 100663303 */\n\t\tIL_008d: newobj instance void class [netstandard]System.EventHandler`1<string>::.ctor(object, native int) /* 167772231 */\n\t\tIL_0092: call void class [UnknownAssembly]UnknownNamespace.UnknownStaticGenericClass`1<string>::remove_OnEvent(class [netstandard]System.EventHandler`1<!0>) /* 167772233 */\n\t\tIL_0097: nop\n\t\tIL_0098: ret\n\t} // end of method UnknownClassTest::MethodUnknownStaticGeneric\n\n\t.method public hidebysig \n\t\tinstance void MethodUnknownIndexerInitializer () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 32 (0x20)\n\t\t.maxstack 8\n\n\t\tIL_0000: nop\n\t\tIL_0001: newobj instance void [UnknownAssembly]UnknownNamespace.UnknownClass::.ctor()\n\t\tIL_0006: dup\n\t\tIL_0007: ldstr \"a\"\n\t\tIL_000c: ldc.i4.1\n\t\tIL_000d: callvirt instance void [UnknownAssembly]UnknownNamespace.UnknownClass::set_Item(string, int32)\n\t\tIL_0012: nop\n\t\tIL_0013: ldstr \"b\"\n\t\tIL_0018: ldc.i4.2\n\t\tIL_0019: callvirt instance void [UnknownAssembly]UnknownNamespace.UnknownClass::set_Item(string, int32)\n\t\tIL_001e: nop\n\t\tIL_001f: ret\n\t} // end of method C::MethodUnknownIndexerInitializer\n\n\n\t.method /* 100663301 */ private hidebysig \n\t\tinstance void Instance_OnEvent (\n\t\t\tobject sender,\n\t\t\tclass [netstandard]System.EventArgs e\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x23e1\n\t\t// Header size: 1\n\t\t// Code size: 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: nop\n\t\tIL_0001: newobj instance void [netstandard]System.NotImplementedException::.ctor() /* 167772234 */\n\t\tIL_0006: throw\n\t} // end of method UnknownClassTest::Instance_OnEvent\n\n\t.method /* 100663302 */ private hidebysig \n\t\tinstance void Instance_OnEvent (\n\t\t\tobject sender,\n\t\t\tclass [UnknownAssembly]UnknownNamespace.UnknownEventArgs e\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x23e9\n\t\t// Header size: 1\n\t\t// Code size: 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: nop\n\t\tIL_0001: newobj instance void [netstandard]System.NotImplementedException::.ctor() /* 167772234 */\n\t\tIL_0006: throw\n\t} // end of method UnknownClassTest::Instance_OnEvent\n\n\t.method /* 100663303 */ private hidebysig \n\t\tinstance void Instance_OnEvent (\n\t\t\tobject sender,\n\t\t\tstring e\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x23f1\n\t\t// Header size: 1\n\t\t// Code size: 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: nop\n\t\tIL_0001: newobj instance void [netstandard]System.NotImplementedException::.ctor() /* 167772234 */\n\t\tIL_0006: throw\n\t} // end of method UnknownClassTest::Instance_OnEvent\n\n\t.method /* 100663304 */ private hidebysig static \n\t\tvoid Instance_OnEvent (\n\t\t\tobject sender,\n\t\t\tobject e\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x23f9\n\t\t// Header size: 1\n\t\t// Code size: 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: nop\n\t\tIL_0001: newobj instance void [netstandard]System.NotImplementedException::.ctor() /* 167772234 */\n\t\tIL_0006: throw\n\t} // end of method UnknownClassTest::Instance_OnEvent\n\n\t.method /* 100663305 */ public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x2401\n\t\t// Header size: 1\n\t\t// Code size: 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [netstandard]System.EventArgs::.ctor() /* 167772235 */\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method UnknownClassTest::.ctor\n\n} // end of class ClassLibrary1.UnknownClassTest\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1038.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n\tpublic class Issue1038<TK, TR> where TR : class, new()\n\t{\n\t\tpublic event Action<TK, TR> TestEvent = delegate {\n\t\t};\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1038.il",
    "content": "// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly extern System\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly extern System.Core\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly ConsoleApp11\n{\n  .ver 1:0:0:0\n}\n.module ConsoleApp11.exe\n// MVID: {B973FCD6-A9C4-48A9-8291-26DDC248E208}\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00020003    //  ILONLY 32BITPREFERRED\n// Image base: 0x000001C4B6C90000\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1038`2<TK, class .ctor TR>\n{\n\t// Fields\n\t.field private class [System.Core]System.Action`2<!TK, !TR> TestEvent\n\t.field private static class [System.Core]System.Action`2<!TK, !TR> '<>f__am$cache0'\n\t.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )\n\n\t// Methods\n\t.method public hidebysig specialname rtspecialname instance void .ctor () cil managed\n\t{\n\t\t.maxstack 8\n\n\t\tldarg.0\n\t\tldsfld class [System.Core]System.Action`2<!0, !1> class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1038`2<!TK, !TR>::'<>f__am$cache0'\n\t\tbrtrue.s IL_0019\n\n\t\tldnull\n\t\tldftn void class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1038`2<!TK, !TR>::'<TestEvent>m__0'(!0, !1)\n\t\tnewobj instance void class [System.Core]System.Action`2<!TK, !TR>::.ctor(object, native int)\n\t\tstsfld class [System.Core]System.Action`2<!0, !1> class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1038`2<!TK, !TR>::'<>f__am$cache0'\n\n\t\tIL_0019: ldsfld class [System.Core]System.Action`2<!0, !1> class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1038`2<!TK, !TR>::'<>f__am$cache0'\n\t\tstfld class [System.Core]System.Action`2<!0, !1> class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1038`2<!TK, !TR>::TestEvent\n\t\tret\n\t}\n\n\t.method public hidebysig specialname instance void add_TestEvent (class [System.Core]System.Action`2<!TK, !TR> 'value') cil managed \n\t{\n\t\t.maxstack 3\n\t\t.locals init (\n\t\t\t[0] class [System.Core]System.Action`2<!TK, !TR>,\n\t\t\t[1] class [System.Core]System.Action`2<!TK, !TR>\n\t\t)\n\n\t\tldarg.0\n\t\tldfld class [System.Core]System.Action`2<!0, !1> class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1038`2<!TK, !TR>::TestEvent\n\t\tstloc.0\n\t\t\tIL_0007: ldloc.0\n\t\t\tstloc.1\n\t\t\tldarg.0\n\t\t\tldflda class [System.Core]System.Action`2<!0, !1> class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1038`2<!TK, !TR>::TestEvent\n\t\t\tldloc.1\n\t\t\tldarg.1\n\t\t\tcall class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)\n\t\t\tcastclass class [System.Core]System.Action`2<!TK, !TR>\n\t\t\tldloc.0\n\t\t\tcall !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [System.Core]System.Action`2<!TK, !TR>>(!!0&, !!0, !!0)\n\t\t\tstloc.0\n\t\t\tldloc.0\n\t\t\tldloc.1\n\t\t\tbne.un IL_0007\n\t\tret\n\t}\n\n\t.method public hidebysig specialname instance void remove_TestEvent (class [System.Core]System.Action`2<!TK, !TR> 'value') cil managed \n\t{\n\t\t.maxstack 3\n\t\t.locals init (\n\t\t\t[0] class [System.Core]System.Action`2<!TK, !TR>,\n\t\t\t[1] class [System.Core]System.Action`2<!TK, !TR>\n\t\t)\n\n\t\tldarg.0\n\t\tldfld class [System.Core]System.Action`2<!0, !1> class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1038`2<!TK, !TR>::TestEvent\n\t\tstloc.0\n\t\t\tIL_0007: ldloc.0\n\t\t\tstloc.1\n\t\t\tldarg.0\n\t\t\tldflda class [System.Core]System.Action`2<!0, !1> class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1038`2<!TK, !TR>::TestEvent\n\t\t\tldloc.1\n\t\t\tldarg.1\n\t\t\tcall class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)\n\t\t\tcastclass class [System.Core]System.Action`2<!TK, !TR>\n\t\t\tldloc.0\n\t\t\tcall !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [System.Core]System.Action`2<!TK, !TR>>(!!0&, !!0, !!0)\n\t\t\tstloc.0\n\t\t\tldloc.0\n\t\t\tldloc.1\n\t\t\tbne.un IL_0007\n\t\tret\n\t}\n\n\t.method private hidebysig static void '<TestEvent>m__0' (!TK '', !TR '') cil managed\n\t{\n\t\t.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )\n\t\t.maxstack 8\n\t\tret\n\t}\n\n\t// Events\n\t.event class [System.Core]System.Action`2<!TK, !TR> TestEvent\n\t{\n\t\t.addon instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1038`2::add_TestEvent(class [System.Core]System.Action`2<!0, !1>)\n\t\t.removeon instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1038`2::remove_TestEvent(class [System.Core]System.Action`2<!0, !1>)\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1047.cs",
    "content": "namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n\tpublic class Issue1047\n\t{\n\t\tprivate static bool dummy;\n\n\t\tprivate void ProblemMethod()\n\t\t{\n\t\t\twhile (!dummy)\n\t\t\t{\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1047.il",
    "content": "// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly extern System\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly extern System.Core\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly ConsoleApp11\n{\n  .ver 1:0:0:0\n}\n.module ConsoleApp11.exe\n// MVID: {B973FCD6-A9C4-48A9-8291-26DDC248E208}\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00020003    //  ILONLY 32BITPREFERRED\n// Image base: 0x000001C4B6C90000\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1047\n{\n\t.field private static bool dummy;\n\t.method private hidebysig instance void ProblemMethod() cil managed \n\t{\n\t\tIL_0000: ldfld bool ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1047::dummy;\n\t\tbrfalse L_tgt1\n\t\tbr L_exit\n\t\tL_tgt1: br IL_0000\n\t\tbr IL_0000\n\t\tL_exit: ret\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1145.cs",
    "content": "using System;\n\npublic sealed class EvType : MulticastDelegate\n{\n\n}\n\n[Serializable]\npublic class OwningClass\n{\n\tpublic event EvType EvName;\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1145.il",
    "content": ".class public auto ansi sealed EvType extends [mscorlib]System.MulticastDelegate\n{\n\t// Methods not included. Just the run of the mill ctor + {Begin|End}?Invoke \n}\n\n.class public auto ansi serializable beforefieldinit OwningClass \n{\n\n.field class EvType EvName\n\n.event EvType EvName\n{\n\t.addon instance void OwningClass::add_EvName(class EvType)\n\t.removeon instance void OwningClass::remove_EvName(class EvType)\n}\n\n.method public hidebysig specialname \n\tinstance void add_EvName (\n\t\tclass EvType 'value'\n\t) cil managed \n{\n\t.maxstack 3\n\t.locals init (\n\t\t[0] class EvType,\n\t\t[1] class EvType\n\t)\n\n\tIL_0000: ldarg.0\n\tIL_0001: ldfld class EvType OwningClass::EvName\n\tIL_0006: stloc.0\n\t// loop start (head: IL_0007)\n\t\tIL_0007: ldloc.0\n\t\tIL_0008: stloc.1\n\t\tIL_0009: ldarg.0\n\t\tIL_000a: ldflda class EvType OwningClass::EvName\n\t\tIL_000f: ldloc.1\n\t\tIL_0010: ldarg.1\n\t\tIL_0011: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)\n\t\tIL_0016: castclass EvType\n\t\tIL_001b: ldloc.0\n\t\tIL_001c: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class EvType>(!!0&, !!0, !!0)\n\t\tIL_0021: stloc.0\n\t\tIL_0022: ldloc.0\n\t\tIL_0023: ldloc.1\n\t\tIL_0024: bne.un IL_0007\n\t// end loop\n\tIL_0029: ret\n} // end of method OwningClass::add_EvName\n\n.method public hidebysig specialname \n\tinstance void remove_EvName (\n\t\tclass EvType 'value'\n\t) cil managed \n{\n\t.maxstack 3\n\t.locals init (\n\t\t[0] class EvType,\n\t\t[1] class EvType\n\t)\n\n\tIL_0000: ldarg.0\n\tIL_0001: ldfld class EvType OwningClass::EvName\n\tIL_0006: stloc.0\n\t// loop start (head: IL_0007)\n\t\tIL_0007: ldloc.0\n\t\tIL_0008: stloc.1\n\t\tIL_0009: ldarg.0\n\t\tIL_000a: ldflda class EvType OwningClass::EvName\n\t\tIL_000f: ldloc.1\n\t\tIL_0010: ldarg.1\n\t\tIL_0011: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)\n\t\tIL_0016: castclass EvType\n\t\tIL_001b: ldloc.0\n\t\tIL_001c: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class EvType>(!!0&, !!0, !!0)\n\t\tIL_0021: stloc.0\n\t\tIL_0022: ldloc.0\n\t\tIL_0023: ldloc.1\n\t\tIL_0024: bne.un IL_0007\n\t// end loop\n\tIL_0029: ret\n} // end of method OwningClass::remove_EvName\n\n} // end of class OwningClass"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1157.cs",
    "content": "using System;\n\nnamespace Issue1157\n{\n\tinternal abstract class BaseClass\n\t{\n\t\tpublic abstract event EventHandler IDontKnowMeHereOut;\n\t}\n\n\tinternal class OtherClass : BaseClass\n\t{\n\t\tpublic override event EventHandler IDontKnowMeHereOut;\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1157.il",
    "content": ".assembly Issue1157\n{\n\t.hash algorithm 0x00008004 // SHA1\n\t.ver 1:0:0:0\n}\n\n.module Issue1157.exe\n// MVID: {4C6C7F98-AEB2-4A19-BE6F-43171E6113F1}\n.corflags 0x00020003 // ILOnly, Required32Bit, Preferred32Bit\n\n.class private auto ansi abstract beforefieldinit Issue1157.BaseClass\n\textends [mscorlib]System.Object\n{\n\t// Methods\n\t.method public hidebysig specialname newslot abstract virtual \n\t\tinstance void add_IDontKnowMeHereOut (\n\t\t\tclass [mscorlib]System.EventHandler 'value'\n\t\t) cil managed \n\t{\n\t\t.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n\t\t\t01 00 00 00\n\t\t)\n\t} // end of method BaseClass::add_IDontKnowMeHereOut\n\n\t.method public hidebysig specialname newslot abstract virtual \n\t\tinstance void remove_IDontKnowMeHereOut (\n\t\t\tclass [mscorlib]System.EventHandler 'value'\n\t\t) cil managed \n\t{\n\t\t.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n\t\t\t01 00 00 00\n\t\t)\n\t} // end of method BaseClass::remove_IDontKnowMeHereOut\n\n\t.method family hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x2063\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method BaseClass::.ctor\n\n\t// Events\n\t.event [mscorlib]System.EventHandler IDontKnowMeHereOut\n\t{\n\t\t.addon instance void Issue1157.BaseClass::add_IDontKnowMeHereOut(class [mscorlib]System.EventHandler)\n\t\t.removeon instance void Issue1157.BaseClass::remove_IDontKnowMeHereOut(class [mscorlib]System.EventHandler)\n\t}\n\n\n} // end of class Issue1157.BaseClass\n\n.class private auto ansi beforefieldinit Issue1157.OtherClass\n\textends Issue1157.BaseClass\n{\n\t// Fields\n\t.field private class [mscorlib]System.EventHandler IDontKnowMeHereOut\n\t.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n\t\t01 00 00 00\n\t)\n\t.custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = (\n\t\t01 00 00 00 00 00 00 00\n\t)\n\n\t// Methods\n\t.method public hidebysig specialname virtual \n\t\tinstance void add_IDontKnowMeHereOut (\n\t\t\tclass [mscorlib]System.EventHandler 'value'\n\t\t) cil managed \n\t{\n\t\t.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n\t\t\t01 00 00 00\n\t\t)\n\t\t// Method begins at RVA 0x206c\n\t\t// Code size 41 (0x29)\n\t\t.maxstack 3\n\t\t.locals init (\n\t\t\t[0] class [mscorlib]System.EventHandler,\n\t\t\t[1] class [mscorlib]System.EventHandler,\n\t\t\t[2] class [mscorlib]System.EventHandler\n\t\t)\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldfld class [mscorlib]System.EventHandler Issue1157.OtherClass::IDontKnowMeHereOut\n\t\tIL_0006: stloc.0\n\t\t// loop start (head: IL_0007)\n\t\t\tIL_0007: ldloc.0\n\t\t\tIL_0008: stloc.1\n\t\t\tIL_0009: ldloc.1\n\t\t\tIL_000a: ldarg.1\n\t\t\tIL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)\n\t\t\tIL_0010: castclass [mscorlib]System.EventHandler\n\t\t\tIL_0015: stloc.2\n\t\t\tIL_0016: ldarg.0\n\t\t\tIL_0017: ldflda class [mscorlib]System.EventHandler Issue1157.OtherClass::IDontKnowMeHereOut\n\t\t\tIL_001c: ldloc.2\n\t\t\tIL_001d: ldloc.1\n\t\t\tIL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler>(!!0&, !!0, !!0)\n\t\t\tIL_0023: stloc.0\n\t\t\tIL_0024: ldloc.0\n\t\t\tIL_0025: ldloc.1\n\t\t\tIL_0026: bne.un.s IL_0007\n\t\t// end loop\n\t\tIL_0028: ret\n\t} // end of method OtherClass::add_IDontKnowMeHereOut\n\n\t.method public hidebysig specialname virtual \n\t\tinstance void remove_IDontKnowMeHereOut (\n\t\t\tclass [mscorlib]System.EventHandler 'value'\n\t\t) cil managed \n\t{\n\t\t.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n\t\t\t01 00 00 00\n\t\t)\n\t\t// Method begins at RVA 0x20a4\n\t\t// Code size 41 (0x29)\n\t\t.maxstack 3\n\t\t.locals init (\n\t\t\t[0] class [mscorlib]System.EventHandler,\n\t\t\t[1] class [mscorlib]System.EventHandler,\n\t\t\t[2] class [mscorlib]System.EventHandler\n\t\t)\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: ldfld class [mscorlib]System.EventHandler Issue1157.OtherClass::IDontKnowMeHereOut\n\t\tIL_0006: stloc.0\n\t\t// loop start (head: IL_0007)\n\t\t\tIL_0007: ldloc.0\n\t\t\tIL_0008: stloc.1\n\t\t\tIL_0009: ldloc.1\n\t\t\tIL_000a: ldarg.1\n\t\t\tIL_000b: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)\n\t\t\tIL_0010: castclass [mscorlib]System.EventHandler\n\t\t\tIL_0015: stloc.2\n\t\t\tIL_0016: ldarg.0\n\t\t\tIL_0017: ldflda class [mscorlib]System.EventHandler Issue1157.OtherClass::IDontKnowMeHereOut\n\t\t\tIL_001c: ldloc.2\n\t\t\tIL_001d: ldloc.1\n\t\t\tIL_001e: call !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler>(!!0&, !!0, !!0)\n\t\t\tIL_0023: stloc.0\n\t\t\tIL_0024: ldloc.0\n\t\t\tIL_0025: ldloc.1\n\t\t\tIL_0026: bne.un.s IL_0007\n\t\t// end loop\n\t\tIL_0028: ret\n\t} // end of method OtherClass::remove_IDontKnowMeHereOut\n\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x20d9\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void Issue1157.BaseClass::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method OtherClass::.ctor\n\n\t// Events\n\t.event [mscorlib]System.EventHandler IDontKnowMeHereOut\n\t{\n\t\t.addon instance void Issue1157.OtherClass::add_IDontKnowMeHereOut(class [mscorlib]System.EventHandler)\n\t\t.removeon instance void Issue1157.OtherClass::remove_IDontKnowMeHereOut(class [mscorlib]System.EventHandler)\n\t}\n\n} // end of class Issue1157.OtherClass"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1256.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n\tinternal class Issue1256\n\t{\n\t\tpublic void Method(Enum e, object o, string s)\n\t\t{\n\t\t\tint num = (int)(object)e;\n\t\t\tobject obj = new object();\n\t\t\tint num2 = (int)obj;\n\t\t\tlong num3 = (long)o;\n\t\t\tint num4 = (int)(object)s;\n\t\t\tint num5 = (int)num3;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1256.il",
    "content": ".class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1256\n\textends [mscorlib]System.Object\n{\n\t// Methods\n\t.method public hidebysig \n\t\tinstance void Method (\n\t\t\tclass [mscorlib]System.Enum e,\n\t\t\tobject o,\n\t\t\tstring s\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 41 (0x29)\n\t\t.maxstack 1\n\t\t.locals init (\n\t\t\t[0] int32,\n\t\t\t[1] object,\n\t\t\t[2] int32,\n\t\t\t[3] int64,\n\t\t\t[4] int32,\n\t\t\t[5] int32\n\t\t)\n\n\t\tIL_0000: nop\n\t\tIL_0001: ldarg.1\n\t\tIL_0002: unbox.any [mscorlib]System.Int32\n\t\tIL_0007: stloc.0\n\t\tIL_0008: newobj instance void [mscorlib]System.Object::.ctor()\n\t\tIL_000d: stloc.1\n\t\tIL_000e: ldloc.1\n\t\tIL_000f: unbox.any [mscorlib]System.Int32\n\t\tIL_0014: stloc.2\n\t\tIL_0015: ldarg.2\n\t\tIL_0016: unbox.any [mscorlib]System.Int64\n\t\tIL_001b: stloc.3\n\t\tIL_001c: ldarg.3\n\t\tIL_001d: unbox.any [mscorlib]System.Int32\n\t\tIL_0022: stloc.s 4\n\t\tIL_0024: ldloc.3\n\t\tIL_0025: conv.i4\n\t\tIL_0026: stloc.s 5\n\t\tIL_0028: ret\n\t} // end of method Issue1256::Method\n\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x2085\n\t\t// Code size 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [mscorlib]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method Issue1256::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1256\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1323.cs",
    "content": "public enum Enum0\n{\n\t// error: enumerator has no value\n\tconst_0,\n\t// error: enumerator has no value\n\tconst_1,\n\t// error: enumerator has no value\n\tconst_2,\n\t// error: enumerator has no value\n\tconst_3\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1323.il",
    "content": "// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly extern System\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly extern System.Core\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly Issue1323\n{\n  .ver 1:0:0:0\n}\n.module Issue1323.dll\n// MVID: {B973FCD6-A9C4-48A9-8291-26DDC248E208}\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00020003    //  ILONLY 32BITPREFERRED\n// Image base: 0x000001C4B6C90000\n\n.class public auto ansi sealed Enum0\n\textends [mscorlib]System.Enum\n{\n\t// Fields\n\t.field public specialname rtspecialname int32 value__\n\t.field public static literal valuetype Enum0 const_0\n\t.field public static literal valuetype Enum0 const_1\n\t.field public static literal valuetype Enum0 const_2\n\t.field public static literal valuetype Enum0 const_3\n\n} // end of class Enum0"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1325.cs",
    "content": "using System;\nusing System.ComponentModel;\nusing System.IO;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\n\nusing Microsoft.VisualBasic;\nusing Microsoft.VisualBasic.CompilerServices;\n\n[assembly: Embedded]\n[assembly: AssemblyInformationalVersion(\"1.0.0\")]\n[assembly: AssemblyConfiguration(\"Debug\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n\n#pragma warning disable format \n\nnamespace Issue1325\n{\n\t[StandardModule]\n\tinternal sealed class Program\n\t{\n\t\t[STAThread]\n\t\tpublic static void Main(string[] args)\n\t\t{\n\t\t}\n\t\tpublic static void TestCode(Test t, int i)\n\t\t{\n\t\t\tstring text = \"\";\n\t\t\ttext += File.ReadAllText(\"Test.txt\");\n\t\t\ttext += \"asdf\";\n\t\t\tt.set_Parameterized(i, text);\n\t\t\tt.Unparameterized = text + \"asdf\";\n\t\t}\n\t}\n\n\tinternal class Test\n\t{\n\t\tpublic string Parameterized {\n\t\t\tget {\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tset {\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n\t\tpublic string Unparameterized { get; set; }\n\t}\n}\nnamespace Microsoft.VisualBasic\n{\n\t[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class, Inherited = false)]\n\t[CompilerGenerated]\n\t[EditorBrowsable(EditorBrowsableState.Never)]\n\t[Embedded]\n\tinternal sealed class Embedded : Attribute\n\t{\n\t}\n}\nnamespace Microsoft.VisualBasic.CompilerServices\n{\n\t[EditorBrowsable(EditorBrowsableState.Never)]\n\t[AttributeUsage(AttributeTargets.Class, Inherited = false)]\n\t[CompilerGenerated]\n\t[Embedded]\n\tinternal sealed class StandardModuleAttribute : Attribute\n\t{\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1325.il",
    "content": "\n//  Microsoft (R) .NET Framework IL Disassembler.  Version 4.6.1055.0\n//  Copyright (c) Microsoft Corporation.  All rights reserved.\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern System.Runtime\n{\n  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )                         // .?_....:\n  .ver 4:2:1:0\n}\n.assembly extern System.Diagnostics.Debug\n{\n  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )                         // .?_....:\n  .ver 4:1:1:0\n}\n.assembly extern System.IO.FileSystem\n{\n  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )                         // .?_....:\n  .ver 4:1:1:0\n}\n.assembly Issue1325\n{\n  .custom instance void Microsoft.VisualBasic.Embedded::.ctor() = ( 01 00 00 00 ) \n  .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [System.Runtime]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                                   63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [System.Runtime]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [System.Runtime]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) \n\n  .custom instance void [System.Runtime]System.Runtime.Versioning.TargetFrameworkAttribute::.ctor(string) = ( 01 00 18 2E 4E 45 54 43 6F 72 65 41 70 70 2C 56   // ....NETCoreApp,V\n                                                                                                              65 72 73 69 6F 6E 3D 76 32 2E 32 01 00 54 0E 14   // ersion=v2.2..T..\n                                                                                                              46 72 61 6D 65 77 6F 72 6B 44 69 73 70 6C 61 79   // FrameworkDisplay\n                                                                                                              4E 61 6D 65 00 )                                  // Name.\n  .custom instance void [System.Runtime]System.Reflection.AssemblyConfigurationAttribute::.ctor(string) = ( 01 00 05 44 65 62 75 67 00 00 )                   // ...Debug..\n  .custom instance void [System.Runtime]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = ( 01 00 07 31 2E 30 2E 30 2E 30 00 00 )             // ...1.0.0.0..\n  .custom instance void [System.Runtime]System.Reflection.AssemblyInformationalVersionAttribute::.ctor(string) = ( 01 00 05 31 2E 30 2E 30 00 00 )                   // ...1.0.0..\n  .hash algorithm 0x00008004\n  .ver 1:0:0:0\n}\n.module Issue1325.dll\n// MVID: {CE79A917-9454-47A4-8FF9-0348706BB573}\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n// Image base: 0x01240000\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi sealed Issue1325.Program\n       extends [System.Runtime]System.Object\n{\n  .custom instance void Microsoft.VisualBasic.CompilerServices.StandardModuleAttribute::.ctor() = ( 01 00 00 00 ) \n  .method public static void  Main(string[] args) cil managed\n  {\n    .entrypoint\n    .custom instance void [System.Runtime]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       2 (0x2)\n    .maxstack  8\n    IL_0000:  nop\n    IL_0001:  ret\n  } // end of method Program::Main\n\n  .method public static void  TestCode(class Issue1325.Test t,\n                                       int32 i) cil managed\n  {\n    // Code size       64 (0x40)\n    .maxstack  3\n    .locals init (string V_0)\n    IL_0000:  nop\n    IL_0001:  ldstr      \"\"\n    IL_0006:  stloc.0\n    IL_0007:  ldloc.0\n    IL_0008:  ldstr      \"Test.txt\"\n    IL_000d:  call       string [System.IO.FileSystem]System.IO.File::ReadAllText(string)\n    IL_0012:  call       string [System.Runtime]System.String::Concat(string,\n                                                                      string)\n    IL_0017:  stloc.0\n    IL_0018:  ldloc.0\n    IL_0019:  ldstr      \"asdf\"\n    IL_001e:  call       string [System.Runtime]System.String::Concat(string,\n                                                                      string)\n    IL_0023:  stloc.0\n    IL_0024:  ldarg.0\n    IL_0025:  ldarg.1\n    IL_0026:  ldloc.0\n    IL_0027:  callvirt   instance void Issue1325.Test::set_Parameterized(int32,\n                                                                            string)\n    IL_002c:  nop\n    IL_002d:  ldarg.0\n    IL_002e:  ldloc.0\n    IL_002f:  ldstr      \"asdf\"\n    IL_0034:  call       string [System.Runtime]System.String::Concat(string,\n                                                                      string)\n    IL_0039:  callvirt   instance void Issue1325.Test::set_Unparameterized(string)\n    IL_003e:  nop\n    IL_003f:  ret\n  } // end of method Program::TestCode\n\n} // end of class Issue1325.Program\n\n.class private auto ansi Issue1325.Test\n       extends [System.Runtime]System.Object\n{\n  .field private string _Unparameterized\n  .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n  .custom instance void [System.Diagnostics.Debug]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [System.Diagnostics.Debug]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) \n  .method public specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [System.Runtime]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method Test::.ctor\n\n  .method public specialname instance string \n          get_Parameterized(int32 i) cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  1\n    .locals init (string V_0)\n    IL_0000:  nop\n    IL_0001:  newobj     instance void [System.Runtime]System.NotImplementedException::.ctor()\n    IL_0006:  throw\n  } // end of method Test::get_Parameterized\n\n  .method public specialname instance void \n          set_Parameterized(int32 i,\n                            string 'value') cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  nop\n    IL_0001:  newobj     instance void [System.Runtime]System.NotImplementedException::.ctor()\n    IL_0006:  throw\n  } // end of method Test::set_Parameterized\n\n  .method public specialname instance string \n          get_Unparameterized() cil managed\n  {\n    .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       9 (0x9)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  ldfld      string Issue1325.Test::_Unparameterized\n    IL_0006:  br.s       IL_0008\n\n    IL_0008:  ret\n  } // end of method Test::get_Unparameterized\n\n  .method public specialname instance void \n          set_Unparameterized(string AutoPropertyValue) cil managed\n  {\n    .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  ldarg.1\n    IL_0002:  stfld      string Issue1325.Test::_Unparameterized\n    IL_0007:  ret\n  } // end of method Test::set_Unparameterized\n\n  .property instance string Parameterized(int32)\n  {\n    .get instance string Issue1325.Test::get_Parameterized(int32)\n    .set instance void Issue1325.Test::set_Parameterized(int32,\n                                                            string)\n  } // end of property Test::Parameterized\n  .property instance string Unparameterized()\n  {\n    .get instance string Issue1325.Test::get_Unparameterized()\n    .set instance void Issue1325.Test::set_Unparameterized(string)\n  } // end of property Test::Unparameterized\n} // end of class Issue1325.Test\n\n.class private auto ansi sealed Microsoft.VisualBasic.CompilerServices.StandardModuleAttribute\n       extends [System.Runtime]System.Attribute\n{\n  .custom instance void Microsoft.VisualBasic.Embedded::.ctor() = ( 01 00 00 00 ) \n  .custom instance void [System.Runtime]System.AttributeUsageAttribute::.ctor(valuetype [System.Runtime]System.AttributeTargets) = ( 01 00 04 00 00 00 01 00 54 02 09 49 6E 68 65 72   // ........T..Inher\n                                                                                                                                     69 74 65 64 00 )                                  // ited.\n  .custom instance void [System.Runtime]System.ComponentModel.EditorBrowsableAttribute::.ctor(valuetype [System.Runtime]System.ComponentModel.EditorBrowsableState) = ( 01 00 01 00 00 00 00 00 ) \n  .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n  .method public specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [System.Runtime]System.Attribute::.ctor()\n    IL_0006:  ret\n  } // end of method StandardModuleAttribute::.ctor\n\n} // end of class Microsoft.VisualBasic.CompilerServices.StandardModuleAttribute\n\n.class private auto ansi sealed Microsoft.VisualBasic.Embedded\n       extends [System.Runtime]System.Attribute\n{\n  .custom instance void Microsoft.VisualBasic.Embedded::.ctor() = ( 01 00 00 00 ) \n  .custom instance void [System.Runtime]System.AttributeUsageAttribute::.ctor(valuetype [System.Runtime]System.AttributeTargets) = ( 01 00 07 00 00 00 01 00 54 02 09 49 6E 68 65 72   // ........T..Inher\n                                                                                                                                     69 74 65 64 00 )                                  // ited.\n  .custom instance void [System.Runtime]System.ComponentModel.EditorBrowsableAttribute::.ctor(valuetype [System.Runtime]System.ComponentModel.EditorBrowsableState) = ( 01 00 01 00 00 00 00 00 ) \n  .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n  .method public specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [System.Runtime]System.Attribute::.ctor()\n    IL_0006:  ret\n  } // end of method Embedded::.ctor\n\n} // end of class Microsoft.VisualBasic.Embedded"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1325.vb",
    "content": "Imports System\nImports System.IO\n\nModule Program\n    Sub Main(args As String())\n\n    End Sub\n\n    Sub TestCode(ByVal t As Test, ByVal i As Integer)\n        Dim s As String = \"\"\n        s += File.ReadAllText(\"Test.txt\")\n        s += \"asdf\"\n        t.Parameterized(i) = s\n        t.Unparameterized = s + \"asdf\"\n    End Sub\nEnd Module\n\nClass Test\n    Public Property Parameterized(ByVal i As Integer) As String\n        Get\n            Throw New NotImplementedException()\n        End Get\n        Set(value As String)\n            Throw New NotImplementedException()\n        End Set\n    End Property\n\n    Public Property Unparameterized As String\nEnd Class"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1389.cs",
    "content": "// Issue1389.Program\nusing System;\n\nnamespace Issue1389\n{\n\tpublic class Program\n\t{\n\t\tprivate static object GetObject()\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\n\t\tprivate static void UnusedResultOfIsinst()\n\t\t{\n\t\t\t_ = GetObject() is TypeCode;\n\t\t}\n\n\t\tprivate static bool BoolResultOfIsinst()\n\t\t{\n\t\t\treturn GetObject() is TypeCode;\n\t\t}\n\n\t\tprivate static object EnumResultOfIsinst(object A_0)\n\t\t{\n\t\t\treturn (A_0 is TypeCode) ? A_0 : null;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1389.il",
    "content": ".assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )\n  .ver 4:0:0:0\n}\n.assembly Issue1389\n{\n  .hash algorithm 0x00008004\n  .ver 1:0:4059:39717\n}\n.module Issue1389.dll\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000003    //  ILONLY 32BITREQUIRED\n\n.class public auto ansi beforefieldinit Issue1389.Program\n\textends [mscorlib]System.Object\n{\n\t// Methods\n\t.method /* 06000001 */ private hidebysig static \n\t\tobject GetObject () cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 2 (0x2)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldnull\n\t\tIL_0001: throw\n\t} // end of method Program::GetObject\n\n\t.method /* 06000002 */ private hidebysig static \n\t\tvoid UnusedResultOfIsinst () cil managed \n\t{\n\t\t// Method begins at RVA 0x2053\n\t\t// Code size 12 (0xc)\n\t\t.maxstack 8\n\n\t\tIL_0000: call object Issue1389.Program::GetObject() /* 06000001 */\n\t\tIL_0005: isinst [mscorlib]System.TypeCode /* 01000002 */\n\t\tIL_000a: pop\n\t\tIL_000b: ret\n\t} // end of method Program::UnusedResultOfIsinst\n\n\t.method /* 06000003 */ private hidebysig static \n\t\tbool BoolResultOfIsinst () cil managed \n\t{\n\t\t// Method begins at RVA 0x2060\n\t\t// Code size 14 (0xe)\n\t\t.maxstack 8\n\n\t\tIL_0000: call object Issue1389.Program::GetObject() /* 06000001 */\n\t\tIL_0005: isinst [mscorlib]System.TypeCode /* 01000002 */\n\t\tIL_000a: ldnull\n\t\tIL_000b: cgt.un\n\t\tIL_000d: ret\n\t} // end of method Program::BoolResultOfIsinst\n\n\t.method /* 06000004 */ private hidebysig static \n\t\tobject EnumResultOfIsinst (\n\t\t\tobject A_0\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x206f\n\t\t// Code size 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: isinst [mscorlib]System.TypeCode /* 01000002 */\n\t\tIL_0006: ret\n\t} // end of method Program::EnumResultOfIsinst\n\n} // end of class Issue1389.Program"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1454.cs",
    "content": "using System.Collections;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n\tpublic class Issue1454\n\t{\n\t\tpublic static int GetCardinality(BitArray bitArray)\n\t\t{\n\t\t\tint[] array = new int[(bitArray.Count >> 5) + 1];\n\t\t\tbitArray.CopyTo(array, 0);\n\t\t\tint num = 0;\n\t\t\tarray[array.Length - 1] &= ~(-1 << bitArray.Count % 32);\n\t\t\tfor (int i = 0; i < array.Length; i++)\n\t\t\t{\n\t\t\t\tint num2 = array[i];\n\t\t\t\tnum2 -= (num2 >> 1) & 0x55555555;\n\t\t\t\tnum2 = (num2 & 0x33333333) + ((num2 >> 2) & 0x33333333);\n\t\t\t\tnum2 = ((num2 + (num2 >> 4)) & 0xF0F0F0F) * 16843009 >> 24;\n\t\t\t\tnum += num2;\n\t\t\t}\n\t\t\treturn num;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1454.il",
    "content": ".assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )\n  .ver 4:0:0:0\n}\n.assembly Issue1454\n{\n  .hash algorithm 0x00008004\n  .ver 1:0:4059:39717\n}\n.module Issue1454.dll\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000003    //  ILONLY 32BITREQUIRED\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1454 extends [mscorlib]System.Object\n{\n\n.method public hidebysig static \n\tint32 GetCardinality (\n\t\tclass [mscorlib]System.Collections.BitArray bitArray\n\t) cil managed \n{\n\t.maxstack 5\n\t.locals init (\n\t\t[0] int32[],\n\t\t[1] int32,\n\t\t[2] int32,\n\t\t[3] int32\n\t)\n\n\tIL_0000: ldarg.0\n\tIL_0001: callvirt instance int32 [mscorlib]System.Collections.BitArray::get_Count()\n\tIL_0006: ldc.i4.5\n\tIL_0007: shr\n\tIL_0008: ldc.i4.1\n\tIL_0009: add\n\tIL_000a: newarr [mscorlib]System.Int32\n\tIL_000f: stloc.0\n\tIL_0010: ldarg.0\n\tIL_0011: ldloc.0\n\tIL_0012: ldc.i4.0\n\tIL_0013: callvirt instance void [mscorlib]System.Collections.BitArray::CopyTo(class [mscorlib]System.Array, int32)\n\tIL_0018: ldc.i4.0\n\tIL_0019: stloc.1\n\tIL_001a: ldloc.0\n\tIL_001b: ldloc.0\n\tIL_001c: ldlen\n\tIL_001d: conv.i4\n\tIL_001e: ldc.i4.1\n\tIL_001f: sub\n\tIL_0020: ldelema [mscorlib]System.Int32\n\tIL_0025: dup\n\tIL_0026: ldind.i4\n\tIL_0027: ldc.i4.m1\n\tIL_0028: ldarg.0\n\tIL_0029: callvirt instance int32 [mscorlib]System.Collections.BitArray::get_Count()\n\tIL_002e: ldc.i4.s 32\n\tIL_0030: rem\n\tIL_0031: ldc.i4.s 31\n\tIL_0033: and\n\tIL_0034: shl\n\tIL_0035: not\n\tIL_0036: and\n\tIL_0037: stind.i4\n\tIL_0038: ldc.i4.0\n\tIL_0039: stloc.2\n\tIL_003a: br.s IL_007b\n\t// loop start (head: IL_007b)\n\t\tIL_003c: ldloc.0\n\t\tIL_003d: ldloc.2\n\t\tIL_003e: ldelem.i4\n\t\tIL_003f: stloc.3\n\t\tIL_0040: ldloc.3\n\t\tIL_0041: ldloc.3\n\t\tIL_0042: ldc.i4.1\n\t\tIL_0043: shr\n\t\tIL_0044: ldc.i4 1431655765\n\t\tIL_0049: and\n\t\tIL_004a: sub\n\t\tIL_004b: stloc.3\n\t\tIL_004c: ldloc.3\n\t\tIL_004d: ldc.i4 858993459\n\t\tIL_0052: and\n\t\tIL_0053: ldloc.3\n\t\tIL_0054: ldc.i4.2\n\t\tIL_0055: shr\n\t\tIL_0056: ldc.i4 858993459\n\t\tIL_005b: and\n\t\tIL_005c: add\n\t\tIL_005d: stloc.3\n\t\tIL_005e: ldloc.3\n\t\tIL_005f: ldloc.3\n\t\tIL_0060: ldc.i4.4\n\t\tIL_0061: shr\n\t\tIL_0062: add\n\t\tIL_0063: ldc.i4 252645135\n\t\tIL_0068: and\n\t\tIL_0069: ldc.i4 16843009\n\t\tIL_006e: mul\n\t\tIL_006f: ldc.i4.s 24\n\t\tIL_0071: shr\n\t\tIL_0072: stloc.3\n\t\tIL_0073: ldloc.1\n\t\tIL_0074: ldloc.3\n\t\tIL_0075: add\n\t\tIL_0076: stloc.1\n\t\tIL_0077: ldloc.2\n\t\tIL_0078: ldc.i4.1\n\t\tIL_0079: add\n\t\tIL_007a: stloc.2\n\n\t\tIL_007b: ldloc.2\n\t\tIL_007c: ldloc.0\n\t\tIL_007d: ldlen\n\t\tIL_007e: conv.i4\n\t\tIL_007f: blt.s IL_003c\n\t// end loop\n\n\tIL_0081: ldloc.1\n\tIL_0082: ret\n}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1681.cs",
    "content": "namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n\tinternal class BaseClass\n\t{\n\t\tpublic int importsClausePosition;\n\t}\n\n\tinternal class Issue1681 : BaseClass\n\t{\n\t\tpublic void Test()\n\t\t{\n\t\t\t_ = importsClausePosition;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1681.il",
    "content": "// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly ConsoleApp11\n{\n  .ver 1:0:0:0\n}\n.module ConsoleApp11.exe\n// MVID: {B973FCD6-A9C4-48A9-8291-26DDC248E208}\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00020003    //  ILONLY 32BITPREFERRED\n// Image base: 0x000001C4B6C90000\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.BaseClass\n       extends [mscorlib]System.Object\n{\n\n.field public int32 importsClausePosition\n\n}\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1681\n       extends ICSharpCode.Decompiler.Tests.TestCases.ILPretty.BaseClass\n{\n\n.method public hidebysig instance void  Test() cil managed\n{\n  // Code size 18 (0x12)\n  .maxstack  8\n  ldarg.0\n\tldfld int32 class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.BaseClass::importsClausePosition\n  pop\n\tret\n} // end of method Issue1681::Test\n\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1918.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n\tinternal class Issue1918\n\t{\n\t\tpublic static Guid[] NullVal;\n\n\t\tpublic unsafe void ProblemFunction(Guid[] A_0, int A_1)\n\t\t{\n\t\t\tfixed (Guid* ptr = A_0)\n\t\t\t{\n\t\t\t\tvoid* ptr2 = ptr;\n\t\t\t\tUIntPtr* ptr3 = (UIntPtr*)ptr2 - 1;\n\t\t\t\tUIntPtr uIntPtr = *ptr3;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\t*ptr3 = (UIntPtr)(ulong)A_1;\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\t*ptr3 = uIntPtr;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfixed (Guid[] ptr = NullVal)\n\t\t\t{\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1918.il",
    "content": "// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly Issue1918\n{\n  .ver 1:0:0:0\n}\n.module Issue1918.exe\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00020003    //  ILONLY 32BITPREFERRED\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1918\n       extends [mscorlib]System.Object\n{\n\n.method public hidebysig \n\tinstance void ProblemFunction (valuetype [mscorlib]System.Guid[] '', int32 ''\n\t) cil managed \n{\n\t.maxstack 2\n\t.locals init (\n\t\t[0] valuetype [mscorlib]System.Guid[],\n\t\t[1] int32,\n\t\t[2] void*,\n\t\t[3] valuetype [mscorlib]System.Guid[] pinned,\n\t\t[4] native uint*,\n\t\t[5] native uint\n\t)\n\n\tIL_0000: ldarg.1\n\tstloc.0\n\n\tIL_0010:\n\tldarg.2\n\tstloc.1\n\tldloc.0\n\tdup\n\tstloc.3\n\tbrfalse.s IL_0026\n\n\tldloc.3\n\tldlen\n\tconv.i4\n\tbrtrue.s IL_002b\n\n\tIL_0026: ldc.i4.0\n\tconv.u\n\tstloc.2\n\tbr.s IL_0034\n\n\tIL_002b: ldloc.3\n\tldc.i4.0\n\tldelema [mscorlib]System.Guid\n\tconv.u\n\tstloc.2\n\n\tIL_0034: ldloc.2\n\tsizeof [mscorlib]System.UIntPtr\n\tsub\n\tstloc.s 4\n\tldloc.s 4\n\tldind.i\n\tstloc.s 5\n\t.try\n\t{\n\t\tldloc.s 4\n\t\tldloc.1\n\t\tconv.i8\n\t\tcall native uint [mscorlib]System.UIntPtr::op_Explicit(uint64)\n\t\tstind.i\n\t\tldarg.1\n\t\t\n\t\tleave.s IL_005c\n\t} // end .try\n\tfinally\n\t{\n\t\tldloc.s 4\n\t\tldloc.s 5\n\t\tstind.i\n\t\tendfinally\n\t} // end handler\n\n\tIL_005c: ldsfld valuetype [mscorlib]System.Guid[] ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue1918::NullVal\n\tstloc.3\n\tret\n}\n\n.field public static valuetype [mscorlib]System.Guid[] NullVal\n\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1922.cs",
    "content": "namespace Issue1922\n{\n\tpublic class Program\n\t{\n\t\tpublic static long fnWorks(int x, int y)\n\t\t{\n\t\t\treturn (long)((((ulong)y & 0xFFFFFFuL) << 24) | ((ulong)x & 0xFFFFFFuL));\n\t\t}\n\n\t\tpublic static long fnFails(int x, int y)\n\t\t{\n\t\t\treturn ((y & 0xFFFFFFL) << 24) | (x & 0xFFFFFFL);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue1922.il",
    "content": ".assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )\n  .ver 4:0:0:0\n}\n.assembly Issue1922\n{\n  .hash algorithm 0x00008004\n  .ver 1:0:4059:39717\n}\n.module Issue1389.dll\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000003    //  ILONLY 32BITREQUIRED\n\n.class public auto ansi beforefieldinit Issue1922.Program\n\textends [mscorlib]System.Object\n{\n\t// Methods\n  .method public hidebysig static int64 fnWorks (int32 x, int32 y) cil managed \n  {\n    .maxstack 8\n\n    ldarg.1\n    conv.i8\n    ldc.i4 16777215\n    conv.i8\n    and\n    ldc.i4.s 24\n    shl\n    ldarg.0\n    conv.i8\n    ldc.i4 16777215\n    conv.i8\n    and\n    or\n    ret\n  }\n\n  .method public hidebysig static int64 fnFails (int32 x, int32 y) cil managed \n  {\n    .maxstack 8\n\n    ldarg.1\n    conv.i8\n    ldc.i8 16777215\n    and\n    ldc.i4.s 24\n    shl\n    ldarg.0\n    conv.i8\n    ldc.i8 16777215\n    and\n    or\n    ret\n  }\n} // end of class Issue1922.Program"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue2104.cs",
    "content": "using System.Runtime.CompilerServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n\tinternal class Issue2104\n\t{\n\t\t[CompilerGenerated]\n\t\tprivate readonly string text;\n\t\tpublic string Text {\n\t\t\t[CompilerGenerated]\n\t\t\tget {\n\t\t\t\treturn text;\n\t\t\t}\n\t\t}\n\t\tpublic Issue2104(string text)\n\t\t{\n\t\t\tthis.text = text;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue2104.il",
    "content": ".assembly issue2104\n{\n\t.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = (\n\t\t01 00 08 00 00 00 00 00\n\t)\n\t.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = (\n\t\t01 00 01 00 54 02 16 57 72 61 70 4e 6f 6e 45 78\n\t\t63 65 70 74 69 6f 6e 54 68 72 6f 77 73 01\n\t)\n\t.custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = (\n\t\t01 00 07 01 00 00 00 00\n\t)\n\t.hash algorithm 0x00008004 // SHA1\n\t.ver 0:0:0:0\n}\n\n.module issue2104.exe\n// MVID: {A7498FA1-F4D7-486E-A872-3DC0CAFD87E2}\n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003 // WindowsCui\n.corflags 0x00000001 // ILOnly\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = (\n\t01 00 00 00\n)\n\n.class private auto ansi '<Module>'\n{\n} // end of class <Module>\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue2104\n    extends [mscorlib]System.Object\n{\n    // Fields\n    .field private initonly string 'text'\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n        01 00 00 00\n    )\n\n    // Methods\n    .method public hidebysig specialname \n        instance string get_Text () cil managed \n    {\n        .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n            01 00 00 00\n        )\n        // Method begins at RVA 0x2074\n        // Code size 7 (0x7)\n        .maxstack 8\n\n        IL_0000: ldarg.0\n        IL_0001: ldfld string ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue2104::text\n        IL_0006: ret\n    } // end of method ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue2104::get_Text\n\n    .method public hidebysig specialname rtspecialname \n        instance void .ctor (\n            string text\n        ) cil managed \n    {\n        // Method begins at RVA 0x207c\n        // Code size 14 (0xe)\n        .maxstack 8\n\n        IL_0000: ldarg.0\n        IL_0001: call instance void [mscorlib]System.Object::.ctor()\n        IL_0006: ldarg.0\n        IL_0007: ldarg.1\n        IL_0008: stfld string ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue2104::'text'\n        IL_000d: ret\n    } // end of method ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue2104::.ctor\n\n    // Properties\n    .property instance string Text()\n    {\n        .get instance string ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue2104::get_Text()\n    }\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue2104\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue2260SwitchString.cs",
    "content": "using System.Windows.Forms;\nnamespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n\tinternal class Issue2260\n\t{\n\t\tprivate void dgvItemList_CellValueChanged(object sender, DataGridViewCellEventArgs e)\n\t\t{\n\t\t\tstring text = default(string);\n\t\t\tstring s = default(string);\n\t\t\tswitch (text)\n\t\t\t{\n\t\t\t\tcase \"rowno\":\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"item_no\":\n\t\t\t\t\tnew object();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"stock_qty\":\n\t\t\t\t\t{\n\t\t\t\t\t\tdecimal result2 = default(decimal);\n\t\t\t\t\t\tif (!decimal.TryParse(s, out result2))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnew object();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (result2 < 1m)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnew object();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\tcase \"new_price\":\n\t\t\t\t\t{\n\t\t\t\t\t\tdecimal num = default(decimal);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\tcase \"new_price4\":\n\t\t\t\t\t{\n\t\t\t\t\t\tdecimal result4 = default(decimal);\n\t\t\t\t\t\tif (decimal.TryParse(s, out result4) && !(result4 < 0m))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\tcase \"new_price1\":\n\t\t\t\t\t{\n\t\t\t\t\t\tdecimal result3 = default(decimal);\n\t\t\t\t\t\tif (!decimal.TryParse(s, out result3))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnew object();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (result3 < 0m)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnew object();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnew object();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\tcase \"new_price2\":\n\t\t\t\t\t{\n\t\t\t\t\t\tdecimal result = default(decimal);\n\t\t\t\t\t\tif (!decimal.TryParse(s, out result))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnew object();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (result < 0m)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnew object();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue2260SwitchString.il",
    "content": ".assembly extern System.Data\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n\n.assembly extern System.Windows.Forms\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n\n.assembly Issue2260\n{\n\t.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = (\n\t\t01 00 08 00 00 00 00 00\n\t)\n\t.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = (\n\t\t01 00 01 00 54 02 16 57 72 61 70 4e 6f 6e 45 78\n\t\t63 65 70 74 69 6f 6e 54 68 72 6f 77 73 01\n\t)\n\t.custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = (\n\t\t01 00 07 01 00 00 00 00\n\t)\n\t.hash algorithm 0x00008004 // SHA1\n\t.ver 0:0:0:0\n}\n\n.module Issue2260.exe\n// MVID: {A7498FA1-F4D7-486E-A872-3DC0CAFD87E2}\n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003 // WindowsCui\n.corflags 0x00000001 // ILOnly\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = (\n\t01 00 00 00\n)\n\n.class private auto ansi '<Module>'\n{\n} // end of class <Module>\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue2260\n    extends [mscorlib]System.Object\n{\n    \n    .method public hidebysig specialname rtspecialname \n        instance void .ctor () cil managed \n    {\n        .maxstack 8\n\n        ldarg.0\n        call instance void [mscorlib]System.Object::.ctor()\n        ret\n    }\n\n  .method private hidebysig \n\t  instance void dgvItemList_CellValueChanged (\n\t\t  object sender,\n\t\t  class [System.Windows.Forms]System.Windows.Forms.DataGridViewCellEventArgs e\n\t  ) cil managed \n  {\n\t  // Method begins at RVA 0x2088\n\t  // Code size 885 (0x375)\n\t  .maxstack 2\n\t  .locals init (\n\t\t  [0] string,\n\t\t  [1] class [System.Data]System.Data.DataRow,\n\t\t  [2] string,\n\t\t  [3] class [System.Data]System.Data.DataTable,\n\t\t  [4] string,\n\t\t  [5] uint32,\n\t\t  [6] object,\n\t\t  [7] class [System.Data]System.Data.DataTable,\n\t\t  [8] valuetype [mscorlib]System.Decimal,\n\t\t  [9] valuetype [mscorlib]System.Decimal,\n\t\t  [10] valuetype [mscorlib]System.Decimal,\n\t\t  [11] valuetype [mscorlib]System.Decimal,\n\t\t  [12] valuetype [mscorlib]System.Decimal,\n\t\t  [13] valuetype [mscorlib]System.Decimal,\n\t\t  [14] valuetype [mscorlib]System.Decimal,\n\t\t  [15] valuetype [mscorlib]System.Decimal,\n\t\t  [16] valuetype [mscorlib]System.Decimal,\n\t\t  [17] valuetype [mscorlib]System.Decimal,\n\t\t  [18] valuetype [mscorlib]System.Decimal,\n\t\t  [19] valuetype [mscorlib]System.Decimal,\n\t\t  [20] valuetype [mscorlib]System.Decimal,\n\t\t  [21] valuetype [mscorlib]System.Decimal,\n\t\t  [22] valuetype [mscorlib]System.Decimal,\n\t\t  [23] valuetype [mscorlib]System.Decimal,\n\t\t  [24] valuetype [mscorlib]System.Decimal,\n\t\t  [25] valuetype [mscorlib]System.Decimal,\n\t\t  [26] valuetype [mscorlib]System.Decimal\n\t  )\n\n\t  IL_0000: ldloc.0\n\t  IL_0001: stloc.s 4\n\t  IL_0003: ldloc.s 4\n\t  IL_0005: call uint32 '<PrivateImplementationDetails>'::ComputeStringHash(string)\n\t  IL_000a: stloc.s 5\n\t  IL_000c: ldloc.s 5\n\t  IL_000e: ldc.i4 -1481643850\n\t  IL_0013: bgt.un.s IL_0031\n\n\t  IL_0015: ldloc.s 5\n\t  IL_0017: ldc.i4 1288728352\n\t  IL_001c: beq.s IL_0063\n\n\t  IL_001e: ldloc.s 5\n\t  IL_0020: ldc.i4 -1700853173\n\t  IL_0025: beq.s IL_0092\n\n\t  IL_0027: ldloc.s 5\n\t  IL_0029: ldc.i4 -1481643850\n\t  IL_002e: beq.s IL_0080\n\n\t  IL_0030: ret\n\n\t  IL_0031: ldloc.s 5\n\t  IL_0033: ldc.i4 -497189362\n\t  IL_0038: bgt.un.s IL_0050\n\n\t  IL_003a: ldloc.s 5\n\t  IL_003c: ldc.i4 -513966981\n\t  IL_0041: beq IL_00c8\n\n\t  IL_0046: ldloc.s 5\n\t  IL_0048: ldc.i4 -497189362\n\t  IL_004d: beq.s IL_00b6\n\n\t  IL_004f: ret\n\n\t  IL_0050: ldloc.s 5\n\t  IL_0052: ldc.i4 -451434784\n\t  IL_0057: beq.s IL_0071\n\n\t  IL_0059: ldloc.s 5\n\t  IL_005b: ldc.i4 -413301267\n\t  IL_0060: beq.s IL_00a4\n\n\t  IL_0062: ret\n\n\t  IL_0063: ldloc.s 4\n\t  IL_0065: ldstr \"rowno\"\n\t  IL_006a: call bool [mscorlib]System.String::op_Equality(string, string)\n\t  IL_006f: pop\n\t  IL_0070: ret\n\n\t  IL_0071: ldloc.s 4\n\t  IL_0073: ldstr \"item_no\"\n\t  IL_0078: call bool [mscorlib]System.String::op_Equality(string, string)\n\t  IL_007d: brtrue.s IL_00da\n\n\t  IL_007f: ret\n\n\t  IL_0080: ldloc.s 4\n\t  IL_0082: ldstr \"stock_qty\"\n\t  IL_0087: call bool [mscorlib]System.String::op_Equality(string, string)\n\t  IL_008c: brtrue IL_021f\n\n\t  IL_0091: ret\n\n\t  IL_0092: ldloc.s 4\n\t  IL_0094: ldstr \"new_price\"\n\t  IL_0099: call bool [mscorlib]System.String::op_Equality(string, string)\n\t  IL_009e: brtrue IL_0285\n\n\t  IL_00a3: ret\n\n\t  IL_00a4: ldloc.s 4\n\t  IL_00a6: ldstr \"new_price4\"\n\t  IL_00ab: call bool [mscorlib]System.String::op_Equality(string, string)\n\t  IL_00b0: brtrue IL_02d6\n\n\t  IL_00b5: ret\n\n\t  IL_00b6: ldloc.s 4\n\t  IL_00b8: ldstr \"new_price1\"\n\t  IL_00bd: call bool [mscorlib]System.String::op_Equality(string, string)\n\t  IL_00c2: brtrue IL_0303\n\n\t  IL_00c7: ret\n\n\t  IL_00c8: ldloc.s 4\n\t  IL_00ca: ldstr \"new_price2\"\n\t  IL_00cf: call bool [mscorlib]System.String::op_Equality(string, string)\n\t  IL_00d4: brtrue IL_0338\n\n\t  IL_00d9: ret\n\n\t  IL_00da: nop\n\t  IL_00db: nop\n\t  IL_00dc: nop\n\t  IL_00dd: nop\n\t  IL_00de: nop\n\t  IL_00df: nop\n\t  IL_00e0: nop\n\t  IL_00e1: nop\n\t  IL_00e2: nop\n\t  IL_00e3: nop\n\t  IL_00e4: nop\n\t  IL_00e5: nop\n\t  IL_00e6: nop\n\t  IL_00e7: nop\n\t  IL_00e8: nop\n\t  IL_00e9: nop\n\t  IL_00ea: nop\n\t  IL_00eb: nop\n\t  IL_00ec: nop\n\t  IL_00ed: nop\n\t  IL_00ee: nop\n\t  IL_00ef: nop\n\t  IL_00f0: nop\n\t  IL_00f1: nop\n\t  IL_00f2: nop\n\t  IL_00f3: nop\n\t  IL_00f4: nop\n\t  IL_00f5: nop\n\t  IL_00f6: nop\n\t  IL_00f7: nop\n\t  IL_00f8: nop\n\t  IL_00f9: nop\n\t  IL_00fa: nop\n\t  IL_00fb: nop\n\t  IL_00fc: nop\n\t  IL_00fd: nop\n\t  IL_00fe: nop\n\t  IL_00ff: nop\n\t  IL_0100: nop\n\t  IL_0101: nop\n\t  IL_0102: nop\n\t  IL_0103: nop\n\t  IL_0104: nop\n\t  IL_0105: nop\n\t  IL_0106: nop\n\t  IL_0107: nop\n\t  IL_0108: nop\n\t  IL_0109: nop\n\t  IL_010a: nop\n\t  IL_010b: nop\n\t  IL_010c: nop\n\t  IL_010d: nop\n\t  IL_010e: nop\n\t  IL_010f: nop\n\t  IL_0110: nop\n\t  IL_0111: nop\n\t  IL_0112: nop\n\t  IL_0113: nop\n\t  IL_0114: nop\n\t  IL_0115: nop\n\t  IL_0116: nop\n\t  IL_0117: nop\n\t  IL_0118: nop\n\t  IL_0119: nop\n\t  IL_011a: nop\n\t  IL_011b: nop\n\t  IL_011c: nop\n\t  IL_011d: nop\n\t  IL_011e: nop\n\t  IL_011f: nop\n\t  IL_0120: nop\n\t  IL_0121: nop\n\t  IL_0122: nop\n\t  IL_0123: nop\n\t  IL_0124: nop\n\t  IL_0125: nop\n\t  IL_0126: nop\n\t  IL_0127: nop\n\t  IL_0128: nop\n\t  IL_0129: nop\n\t  IL_012a: nop\n\t  IL_012b: nop\n\t  IL_012c: nop\n\t  IL_012d: nop\n\t  IL_012e: nop\n\t  IL_012f: nop\n\t  IL_0130: nop\n\t  IL_0131: nop\n\t  IL_0132: nop\n\t  IL_0133: nop\n\t  IL_0134: nop\n\t  IL_0135: nop\n\t  IL_0136: nop\n\t  IL_0137: nop\n\t  IL_0138: nop\n\t  IL_0139: nop\n\t  IL_013a: nop\n\t  IL_013b: nop\n\t  IL_013c: nop\n\t  IL_013d: nop\n\t  IL_013e: nop\n\t  IL_013f: nop\n\t  IL_0140: nop\n\t  IL_0141: nop\n\t  IL_0142: nop\n\t  IL_0143: nop\n\t  IL_0144: nop\n\t  IL_0145: nop\n\t  IL_0146: nop\n\t  IL_0147: nop\n\t  IL_0148: nop\n\t  IL_0149: nop\n\t  IL_014a: nop\n\t  IL_014b: nop\n\t  IL_014c: nop\n\t  IL_014d: nop\n\t  IL_014e: nop\n\t  IL_014f: nop\n\t  IL_0150: nop\n\t  IL_0151: nop\n\t  IL_0152: nop\n\t  IL_0153: nop\n\t  IL_0154: nop\n\t  IL_0155: nop\n\t  IL_0156: nop\n\t  IL_0157: nop\n\t  IL_0158: nop\n\t  IL_0159: nop\n\t  IL_015a: nop\n\t  IL_015b: nop\n\t  IL_015c: nop\n\t  IL_015d: nop\n\t  IL_015e: nop\n\t  IL_015f: nop\n\t  IL_0160: nop\n\t  IL_0161: nop\n\t  IL_0162: nop\n\t  IL_0163: nop\n\t  IL_0164: nop\n\t  IL_0165: nop\n\t  IL_0166: nop\n\t  IL_0167: nop\n\t  IL_0168: nop\n\t  IL_0169: nop\n\t  IL_016a: nop\n\t  IL_016b: nop\n\t  IL_016c: nop\n\t  IL_016d: nop\n\t  IL_016e: nop\n\t  IL_016f: nop\n\t  IL_0170: nop\n\t  IL_0171: nop\n\t  IL_0172: nop\n\t  IL_0173: nop\n\t  IL_0174: nop\n\t  IL_0175: nop\n\t  IL_0176: nop\n\t  IL_0177: nop\n\t  IL_0178: nop\n\t  IL_0179: nop\n\t  IL_017a: nop\n\t  IL_017b: nop\n\t  IL_017c: nop\n\t  IL_017d: nop\n\t  IL_017e: nop\n\t  IL_017f: nop\n\t  IL_0180: nop\n\t  IL_0181: nop\n\t  IL_0182: nop\n\t  IL_0183: nop\n\t  IL_0184: nop\n\t  IL_0185: nop\n\t  IL_0186: nop\n\t  IL_0187: nop\n\t  IL_0188: nop\n\t  IL_0189: nop\n\t  IL_018a: nop\n\t  IL_018b: nop\n\t  IL_018c: nop\n\t  IL_018d: nop\n\t  IL_018e: nop\n\t  IL_018f: nop\n\t  IL_0190: nop\n\t  IL_0191: nop\n\t  IL_0192: nop\n\t  IL_0193: nop\n\t  IL_0194: nop\n\t  IL_0195: nop\n\t  IL_0196: nop\n\t  IL_0197: nop\n\t  IL_0198: nop\n\t  IL_0199: nop\n\t  IL_019a: nop\n\t  IL_019b: nop\n\t  IL_019c: nop\n\t  IL_019d: nop\n\t  IL_019e: nop\n\t  IL_019f: nop\n\t  IL_01a0: nop\n\t  IL_01a1: nop\n\t  IL_01a2: nop\n\t  IL_01a3: nop\n\t  IL_01a4: nop\n\t  IL_01a5: nop\n\t  IL_01a6: nop\n\t  IL_01a7: nop\n\t  IL_01a8: nop\n\t  IL_01a9: nop\n\t  IL_01aa: nop\n\t  IL_01ab: nop\n\t  IL_01ac: nop\n\t  IL_01ad: nop\n\t  IL_01ae: nop\n\t  IL_01af: nop\n\t  IL_01b0: nop\n\t  IL_01b1: nop\n\t  IL_01b2: nop\n\t  IL_01b3: nop\n\t  IL_01b4: nop\n\t  IL_01b5: nop\n\t  IL_01b6: nop\n\t  IL_01b7: nop\n\t  IL_01b8: nop\n\t  IL_01b9: nop\n\t  IL_01ba: nop\n\t  IL_01bb: nop\n\t  IL_01bc: nop\n\t  IL_01bd: nop\n\t  IL_01be: nop\n\t  IL_01bf: nop\n\t  IL_01c0: nop\n\t  IL_01c1: nop\n\t  IL_01c2: nop\n\t  IL_01c3: nop\n\t  IL_01c4: nop\n\t  IL_01c5: nop\n\t  IL_01c6: nop\n\t  IL_01c7: nop\n\t  IL_01c8: nop\n\t  IL_01c9: nop\n\t  IL_01ca: nop\n\t  IL_01cb: nop\n\t  IL_01cc: nop\n\t  IL_01cd: nop\n\t  IL_01ce: nop\n\t  IL_01cf: nop\n\t  IL_01d0: nop\n\t  IL_01d1: nop\n\t  IL_01d2: nop\n\t  IL_01d3: nop\n\t  IL_01d4: nop\n\t  IL_01d5: nop\n\t  IL_01d6: nop\n\t  IL_01d7: nop\n\t  IL_01d8: nop\n\t  IL_01d9: nop\n\t  IL_01da: nop\n\t  IL_01db: nop\n\t  IL_01dc: nop\n\t  IL_01dd: nop\n\t  IL_01de: nop\n\t  IL_01df: nop\n\t  IL_01e0: nop\n\t  IL_01e1: nop\n\t  IL_01e2: nop\n\t  IL_01e3: nop\n\t  IL_01e4: nop\n\t  IL_01e5: nop\n\t  IL_01e6: nop\n\t  IL_01e7: nop\n\t  IL_01e8: nop\n\t  IL_01e9: nop\n\t  IL_01ea: nop\n\t  IL_01eb: nop\n\t  IL_01ec: nop\n\t  IL_01ed: nop\n\t  IL_01ee: nop\n\t  IL_01ef: nop\n\t  IL_01f0: nop\n\t  IL_01f1: nop\n\t  IL_01f2: nop\n\t  IL_01f3: nop\n\t  IL_01f4: nop\n\t  IL_01f5: nop\n\t  IL_01f6: nop\n\t  IL_01f7: nop\n\t  IL_01f8: nop\n\t  IL_01f9: nop\n\t  IL_01fa: nop\n\t  IL_01fb: nop\n\t  IL_01fc: nop\n\t  IL_01fd: nop\n\t  IL_01fe: nop\n\t  IL_01ff: nop\n\t  IL_0200: nop\n\t  IL_0201: nop\n\t  IL_0202: nop\n\t  IL_0203: nop\n\t  IL_0204: nop\n\t  IL_0205: nop\n\t  IL_0206: nop\n\t  IL_0207: nop\n\t  IL_0208: nop\n\t  IL_0209: nop\n\t  IL_020a: nop\n\t  IL_020b: nop\n\t  IL_020c: nop\n\t  IL_020d: nop\n\t  IL_020e: nop\n\t  IL_020f: nop\n\t  IL_0210: nop\n\t  IL_0211: nop\n\t  IL_0212: nop\n\t  IL_0213: nop\n\t  IL_0214: nop\n\t  IL_0215: nop\n\t  IL_0216: nop\n\t  IL_0217: newobj instance void [mscorlib]System.Object::.ctor()\n\t  IL_021c: pop\n\t  IL_021d: nop\n\t  IL_021e: ret\n\n\t  IL_021f: ldloca.s 10\n\t  IL_0221: initobj [mscorlib]System.Decimal\n\t  IL_0227: ldloc.2\n\t  IL_0228: ldloca.s 10\n\t  IL_022a: call bool [mscorlib]System.Decimal::TryParse(string, valuetype [mscorlib]System.Decimal&)\n\t  IL_022f: brtrue.s IL_023c\n\n\t  IL_0231: nop\n\t  IL_0232: newobj instance void [mscorlib]System.Object::.ctor()\n\t  IL_0237: pop\n\t  IL_0238: nop\n\t  IL_0239: nop\n\t  IL_023a: nop\n\t  IL_023b: ret\n\n\t  IL_023c: ldloc.s 10\n\t  IL_023e: ldsfld valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::One\n\t  IL_0243: call bool [mscorlib]System.Decimal::op_LessThan(valuetype [mscorlib]System.Decimal, valuetype [mscorlib]System.Decimal)\n\t  IL_0248: brfalse.s IL_025c\n\n\t  IL_024a: nop\n\t  IL_024b: nop\n\t  IL_024c: nop\n\t  IL_024d: nop\n\t  IL_024e: nop\n\t  IL_024f: nop\n\t  IL_0250: nop\n\t  IL_0251: newobj instance void [mscorlib]System.Object::.ctor()\n\t  IL_0256: pop\n\t  IL_0257: nop\n\t  IL_0258: nop\n\t  IL_0259: nop\n\t  IL_025a: nop\n\t  IL_025b: nop\n\n\t  IL_025c: nop\n\t  IL_025d: nop\n\t  IL_025e: nop\n\t  IL_025f: nop\n\t  IL_0260: nop\n\t  IL_0261: nop\n\t  IL_0262: nop\n\t  IL_0263: nop\n\t  IL_0264: nop\n\t  IL_0265: nop\n\t  IL_0266: nop\n\t  IL_0267: nop\n\t  IL_0268: nop\n\t  IL_0269: nop\n\t  IL_026a: nop\n\t  IL_026b: nop\n\t  IL_026c: nop\n\t  IL_026d: nop\n\t  IL_026e: nop\n\t  IL_026f: nop\n\t  IL_0270: nop\n\t  IL_0271: nop\n\t  IL_0272: nop\n\t  IL_0273: nop\n\t  IL_0274: nop\n\t  IL_0275: nop\n\t  IL_0276: nop\n\t  IL_0277: nop\n\t  IL_0278: nop\n\t  IL_0279: nop\n\t  IL_027a: nop\n\t  IL_027b: nop\n\t  IL_027c: nop\n\t  IL_027d: nop\n\t  IL_027e: nop\n\t  IL_027f: nop\n\t  IL_0280: nop\n\t  IL_0281: nop\n\t  IL_0282: nop\n\t  IL_0283: nop\n\t  IL_0284: ret\n\n\t  IL_0285: ldloca.s 15\n\t  IL_0287: initobj [mscorlib]System.Decimal\n\t  IL_028d: nop\n\t  IL_028e: nop\n\t  IL_028f: nop\n\t  IL_0290: nop\n\t  IL_0291: nop\n\t  IL_0292: nop\n\t  IL_0293: nop\n\t  IL_0294: nop\n\t  IL_0295: nop\n\t  IL_0296: nop\n\t  IL_0297: nop\n\t  IL_0298: nop\n\t  IL_0299: nop\n\t  IL_029a: nop\n\t  IL_029b: nop\n\t  IL_029c: nop\n\t  IL_029d: nop\n\t  IL_029e: nop\n\t  IL_029f: nop\n\t  IL_02a0: nop\n\t  IL_02a1: nop\n\t  IL_02a2: nop\n\t  IL_02a3: nop\n\t  IL_02a4: nop\n\t  IL_02a5: nop\n\t  IL_02a6: nop\n\t  IL_02a7: nop\n\t  IL_02a8: nop\n\t  IL_02a9: nop\n\t  IL_02aa: nop\n\t  IL_02ab: nop\n\t  IL_02ac: nop\n\t  IL_02ad: nop\n\t  IL_02ae: nop\n\t  IL_02af: nop\n\t  IL_02b0: nop\n\t  IL_02b1: nop\n\t  IL_02b2: nop\n\t  IL_02b3: nop\n\t  IL_02b4: nop\n\t  IL_02b5: nop\n\t  IL_02b6: nop\n\t  IL_02b7: nop\n\t  IL_02b8: nop\n\t  IL_02b9: nop\n\t  IL_02ba: nop\n\t  IL_02bb: nop\n\t  IL_02bc: nop\n\t  IL_02bd: nop\n\t  IL_02be: nop\n\t  IL_02bf: nop\n\t  IL_02c0: nop\n\t  IL_02c1: nop\n\t  IL_02c2: nop\n\t  IL_02c3: nop\n\t  IL_02c4: nop\n\t  IL_02c5: nop\n\t  IL_02c6: nop\n\t  IL_02c7: nop\n\t  IL_02c8: nop\n\t  IL_02c9: nop\n\t  IL_02ca: nop\n\t  IL_02cb: nop\n\t  IL_02cc: nop\n\t  IL_02cd: nop\n\t  IL_02ce: nop\n\t  IL_02cf: nop\n\t  IL_02d0: nop\n\t  IL_02d1: nop\n\t  IL_02d2: nop\n\t  IL_02d3: nop\n\t  IL_02d4: nop\n\t  IL_02d5: ret\n\n\t  IL_02d6: ldloca.s 20\n\t  IL_02d8: initobj [mscorlib]System.Decimal\n\t  IL_02de: ldloc.2\n\t  IL_02df: ldloca.s 20\n\t  IL_02e1: call bool [mscorlib]System.Decimal::TryParse(string, valuetype [mscorlib]System.Decimal&)\n\t  IL_02e6: brtrue.s IL_02ed\n\n\t  IL_02e8: nop\n\t  IL_02e9: nop\n\t  IL_02ea: nop\n\t  IL_02eb: nop\n\t  IL_02ec: ret\n\n\t  IL_02ed: ldloc.s 20\n\t  IL_02ef: ldsfld valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::Zero\n\t  IL_02f4: call bool [mscorlib]System.Decimal::op_LessThan(valuetype [mscorlib]System.Decimal, valuetype [mscorlib]System.Decimal)\n\t  IL_02f9: brfalse IL_0374\n\n\t  IL_02fe: nop\n\t  IL_02ff: nop\n\t  IL_0300: nop\n\t  IL_0301: nop\n\t  IL_0302: ret\n\n\t  IL_0303: ldloca.s 21\n\t  IL_0305: initobj [mscorlib]System.Decimal\n\t  IL_030b: ldloc.2\n\t  IL_030c: ldloca.s 21\n\t  IL_030e: call bool [mscorlib]System.Decimal::TryParse(string, valuetype [mscorlib]System.Decimal&)\n\t  IL_0313: brtrue.s IL_031c\n\n\t  IL_0315: newobj instance void [mscorlib]System.Object::.ctor()\n\t  IL_031a: pop\n\t  IL_031b: ret\n\n\t  IL_031c: ldloc.s 21\n\t  IL_031e: ldsfld valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::Zero\n\t  IL_0323: call bool [mscorlib]System.Decimal::op_LessThan(valuetype [mscorlib]System.Decimal, valuetype [mscorlib]System.Decimal)\n\t  IL_0328: brfalse.s IL_0330\n\n\t  IL_032a: newobj instance void [mscorlib]System.Object::.ctor()\n\t  IL_032f: pop\n\n\t  IL_0330: nop\n\t  IL_0331: newobj instance void [mscorlib]System.Object::.ctor()\n\t  IL_0336: pop\n\t  IL_0337: ret\n\n\t  IL_0338: ldloca.s 26\n\t  IL_033a: initobj [mscorlib]System.Decimal\n\t  IL_0340: ldloc.2\n\t  IL_0341: ldloca.s 26\n\t  IL_0343: call bool [mscorlib]System.Decimal::TryParse(string, valuetype [mscorlib]System.Decimal&)\n\t  IL_0348: brtrue.s IL_0354\n\n\t  IL_034a: nop\n\t  IL_034b: nop\n\t  IL_034c: newobj instance void [mscorlib]System.Object::.ctor()\n\t  IL_0351: pop\n\t  IL_0352: nop\n\t  IL_0353: ret\n\n\t  IL_0354: ldloc.s 26\n\t  IL_0356: ldsfld valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::Zero\n\t  IL_035b: call bool [mscorlib]System.Decimal::op_LessThan(valuetype [mscorlib]System.Decimal, valuetype [mscorlib]System.Decimal)\n\t  IL_0360: brfalse.s IL_0374\n\n\t  IL_0362: nop\n\t  IL_0363: nop\n\t  IL_0364: nop\n\t  IL_0365: nop\n\t  IL_0366: nop\n\t  IL_0367: newobj instance void [mscorlib]System.Object::.ctor()\n\t  IL_036c: pop\n\t  IL_036d: nop\n\t  IL_036e: nop\n\t  IL_036f: nop\n\t  IL_0370: nop\n\t  IL_0371: nop\n\t  IL_0372: nop\n\t  IL_0373: nop\n\n\t  IL_0374: ret\n  } // end of method FrmSheetPX::dgvItemList_CellValueChanged\n\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue2260\n\n\n.class private auto ansi sealed '<PrivateImplementationDetails>'\n\textends [mscorlib]System.Object\n{\n\t.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n\t\t01 00 00 00\n\t)\n\t// Methods\n\t.method assembly hidebysig static \n\t\tuint32 ComputeStringHash (\n\t\t\tstring s\n\t\t) cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 44 (0x2c)\n\t\t.maxstack 2\n\t\t.locals init (\n\t\t\t[0] uint32,\n\t\t\t[1] int32\n\t\t)\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: brfalse.s IL_002a\n\n\t\tIL_0003: ldc.i4 -2128831035\n\t\tIL_0008: stloc.0\n\t\tIL_0009: ldc.i4.0\n\t\tIL_000a: stloc.1\n\t\tIL_000b: br.s IL_0021\n\t\t// loop start (head: IL_0021)\n\t\t\tIL_000d: ldarg.0\n\t\t\tIL_000e: ldloc.1\n\t\t\tIL_000f: callvirt instance char [mscorlib]System.String::get_Chars(int32)\n\t\t\tIL_0014: ldloc.0\n\t\t\tIL_0015: xor\n\t\t\tIL_0016: ldc.i4 16777619\n\t\t\tIL_001b: mul\n\t\t\tIL_001c: stloc.0\n\t\t\tIL_001d: ldloc.1\n\t\t\tIL_001e: ldc.i4.1\n\t\t\tIL_001f: add\n\t\t\tIL_0020: stloc.1\n\n\t\t\tIL_0021: ldloc.1\n\t\t\tIL_0022: ldarg.0\n\t\t\tIL_0023: callvirt instance int32 [mscorlib]System.String::get_Length()\n\t\t\tIL_0028: blt.s IL_000d\n\t\t// end loop\n\n\t\tIL_002a: ldloc.0\n\t\tIL_002b: ret\n\t} // end of method '<PrivateImplementationDetails>'::ComputeStringHash\n\n} // end of class <PrivateImplementationDetails>\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue2443.cs",
    "content": "using System;\nusing System.Reflection;\nusing ClassLibrary1;\n\n[assembly: AssemblyCompany(\"ConsoleApp8\")]\n[assembly: AssemblyConfiguration(\"Release\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n[assembly: AssemblyInformationalVersion(\"1.0.0\")]\n[assembly: AssemblyProduct(\"ConsoleApp8\")]\n[assembly: AssemblyTitle(\"ConsoleApp8\")]\n\nnamespace ConsoleApp8\n{\n\tinternal class Program : Class1\n\t{\n\t\tpublic Program(string _)\n\t\t\t: base(_)\n\t\t{\n\t\t\tConsole.WriteLine(\"Class1(string)<-Program(string)\");\n\t\t}\n\n\t\tprivate static void Main(string[] args)\n\t\t{\n\t\t\tnew Program(\"\");\n\t\t\tConsole.WriteLine(\"Hello World!\");\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue2443.il",
    "content": "\n//  Microsoft (R) .NET Framework IL Disassembler.  Version 4.6.1055.0\n//  Copyright (c) Microsoft Corporation.  All rights reserved.\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly extern ClassLibrary1\n{\n  .ver 1:0:0:0\n}\n.assembly ConsoleApp8\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) \n\n  .custom instance void [mscorlib]System.Runtime.Versioning.TargetFrameworkAttribute::.ctor(string) = ( 01 00 1C 2E 4E 45 54 46 72 61 6D 65 77 6F 72 6B   // ....NETFramework\n                                                                                                        2C 56 65 72 73 69 6F 6E 3D 76 34 2E 37 2E 32 01   // ,Version=v4.7.2.\n                                                                                                        00 54 0E 14 46 72 61 6D 65 77 6F 72 6B 44 69 73   // .T..FrameworkDis\n                                                                                                        70 6C 61 79 4E 61 6D 65 14 2E 4E 45 54 20 46 72   // playName..NET Fr\n                                                                                                        61 6D 65 77 6F 72 6B 20 34 2E 37 2E 32 )          // amework 4.7.2\n  .custom instance void [mscorlib]System.Reflection.AssemblyCompanyAttribute::.ctor(string) = ( 01 00 0B 43 6F 6E 73 6F 6C 65 41 70 70 38 00 00 ) // ...ConsoleApp8..\n  .custom instance void [mscorlib]System.Reflection.AssemblyConfigurationAttribute::.ctor(string) = ( 01 00 07 52 65 6C 65 61 73 65 00 00 )             // ...Release..\n  .custom instance void [mscorlib]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = ( 01 00 07 31 2E 30 2E 30 2E 30 00 00 )             // ...1.0.0.0..\n  .custom instance void [mscorlib]System.Reflection.AssemblyInformationalVersionAttribute::.ctor(string) = ( 01 00 05 31 2E 30 2E 30 00 00 )                   // ...1.0.0..\n  .custom instance void [mscorlib]System.Reflection.AssemblyProductAttribute::.ctor(string) = ( 01 00 0B 43 6F 6E 73 6F 6C 65 41 70 70 38 00 00 ) // ...ConsoleApp8..\n  .custom instance void [mscorlib]System.Reflection.AssemblyTitleAttribute::.ctor(string) = ( 01 00 0B 43 6F 6E 73 6F 6C 65 41 70 70 38 00 00 ) // ...ConsoleApp8..\n  .hash algorithm 0x00008004\n  .ver 1:0:0:0\n}\n.module ConsoleApp8.exe\n// MVID: {C71BB5CC-A98C-4CF4-B8A4-000055F94187}\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n// Image base: 0x02890000\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi beforefieldinit ConsoleApp8.Program\n       extends [ClassLibrary1]ClassLibrary1.Class1\n{\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor(string _) cil managed\n  {\n    // Code size       18 (0x12)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  ldarg.1\n    IL_0002:  call       instance void [ClassLibrary1]ClassLibrary1.Class1::.ctor(string)\n    IL_0007:  ldstr      \"Class1(string)<-Program(string)\"\n    IL_000c:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0011:  ret\n  } // end of method Program::.ctor\n\n  .method private hidebysig static void  Main(string[] args) cil managed\n  {\n    .entrypoint\n    // Code size       22 (0x16)\n    .maxstack  8\n    IL_0000:  ldstr      \"\"\n    IL_0005:  newobj     instance void ConsoleApp8.Program::.ctor(string)\n    IL_000a:  pop\n    IL_000b:  ldstr      \"Hello World!\"\n    IL_0010:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0015:  ret\n  } // end of method Program::Main\n\n} // end of class ConsoleApp8.Program\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n// WARNING: Created Win32 resource file Issue2443.res\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3344CkFinite.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n\tpublic class Issue3344\n\t{\n\t\tprivate static float GetFloat()\n\t\t{\n\t\t\treturn 3.5f;\n\t\t}\n\n\t\tprivate static float CkFinite()\n\t\t{\n\t\t\tfloat num = GetFloat();\n\t\t\tif (!float.IsFinite(num))\n\t\t\t{\n\t\t\t\tthrow new ArithmeticException();\n\t\t\t}\n\t\t\treturn num;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3344CkFinite.il",
    "content": ".assembly extern System.Runtime\n{\n\t.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n\t.ver 4:0:0:0\n}\n\n.assembly Issue3344\n{\n\t.hash algorithm 0x00008004 // SHA1\n\t.ver 0:0:0:0\n}\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3344\n\textends [System.Runtime]System.Object\n{\n    .method private hidebysig static \n        float32 GetFloat () cil managed \n    {\n        .maxstack 8\n\n        IL_0000: ldc.r4 3.5\n        IL_0005: ret\n    }\n\n    .method private hidebysig static \n        float32 CkFinite () cil managed \n    {\n        .maxstack 1\n        .locals init (\n            [0] float32\n        )\n\n        call float32 ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3344::GetFloat()\n        ckfinite\n        ret\n    }\n\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [System.Runtime]System.Object::.ctor()\n\t\tIL_0006: ret\n\t}\n\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3421.cs",
    "content": "internal class Issue3421\n{\n\tprivate string name;\n\tprivate object value;\n\n\tpublic virtual void SetValue(object value)\n\t{\n\t\tswitch (name)\n\t\t{\n\t\t\tcase \"##Name##\":\n\t\t\t\treturn;\n\t\t\tcase \"##Value##\":\n\t\t\t\tthis.value = value;\n\t\t\t\treturn;\n\t\t\tcase \"##InnerText##\":\n\t\t\t\tthis.value = value.ToString();\n\t\t\t\treturn;\n\t\t\tcase null:\n\t\t\t\treturn;\n\t\t}\n\t\tif (this.value == null)\n\t\t{\n\t\t\tthis.value = \"\";\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3421.il",
    "content": "#define CORE_ASSEMBLY \"System.Runtime\"\n\n.assembly extern CORE_ASSEMBLY\n{\n  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )                         // .?_....:\n  .ver 4:0:0:0\n}\n\n.class private auto ansi beforefieldinit Issue3421\n    extends [CORE_ASSEMBLY]System.Object\n{\n    // Fields\n    .field private string name\n    .field private object 'value'\n    .field private static class [CORE_ASSEMBLY]System.Collections.Generic.Dictionary`2<string, int32> '<>f__switch$map1D'\n    .custom instance void [CORE_ASSEMBLY]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n        01 00 00 00\n    )\n\n    // Methods\n    .method public hidebysig virtual \n        instance void SetValue (\n            object 'value'\n        ) cil managed \n    {\n        // Method begins at RVA 0x2050\n        // Header size: 12\n        // Code size: 180 (0xb4)\n        .maxstack 27\n        .locals init (\n            [0] string,\n            [1] class [CORE_ASSEMBLY]System.Collections.Generic.Dictionary`2<string, int32>,\n            [2] int32\n        )\n\n        IL_0000: ldarg.0\n        IL_0001: ldfld string Issue3421::name\n        IL_0006: stloc.0\n        IL_0007: ldloc.0\n        IL_0008: brfalse IL_0093\n\n        IL_000d: ldsfld class [CORE_ASSEMBLY]System.Collections.Generic.Dictionary`2<string, int32> Issue3421::'<>f__switch$map1D'\n        IL_0012: brtrue IL_0048\n\n        IL_0017: ldc.i4.3\n        IL_0018: newobj instance void class [CORE_ASSEMBLY]System.Collections.Generic.Dictionary`2<string, int32>::.ctor(int32)\n        IL_001d: stloc.1\n        IL_001e: ldloc.1\n        IL_001f: ldstr \"##Name##\"\n        IL_0024: ldc.i4.0\n        IL_0025: callvirt instance void class [CORE_ASSEMBLY]System.Collections.Generic.Dictionary`2<string, int32>::Add(!0, !1)\n        IL_002a: ldloc.1\n        IL_002b: ldstr \"##Value##\"\n        IL_0030: ldc.i4.1\n        IL_0031: callvirt instance void class [CORE_ASSEMBLY]System.Collections.Generic.Dictionary`2<string, int32>::Add(!0, !1)\n        IL_0036: ldloc.1\n        IL_0037: ldstr \"##InnerText##\"\n        IL_003c: ldc.i4.2\n        IL_003d: callvirt instance void class [CORE_ASSEMBLY]System.Collections.Generic.Dictionary`2<string, int32>::Add(!0, !1)\n        IL_0042: ldloc.1\n        IL_0043: stsfld class [CORE_ASSEMBLY]System.Collections.Generic.Dictionary`2<string, int32> Issue3421::'<>f__switch$map1D'\n\n        IL_0048: ldsfld class [CORE_ASSEMBLY]System.Collections.Generic.Dictionary`2<string, int32> Issue3421::'<>f__switch$map1D'\n        IL_004d: ldloc.0\n        IL_004e: ldloca.s 2\n        IL_0050: callvirt instance bool class [CORE_ASSEMBLY]System.Collections.Generic.Dictionary`2<string, int32>::TryGetValue(!0, !1&)\n        IL_0055: brfalse IL_0098\n\n        IL_005a: ldloc.2\n        IL_005b: switch (IL_0071, IL_0076, IL_0082)\n\n        IL_006c: br IL_0098\n\n        IL_0071: br IL_00b3\n\n        IL_0076: ldarg.0\n        IL_0077: ldarg.1\n        IL_0078: stfld object Issue3421::'value'\n        IL_007d: br IL_00b3\n\n        IL_0082: ldarg.0\n        IL_0083: ldarg.1\n        IL_0084: callvirt instance string [CORE_ASSEMBLY]System.Object::ToString()\n        IL_0089: stfld object Issue3421::'value'\n        IL_008e: br IL_00b3\n\n        IL_0093: br IL_00b3\n\n        IL_0098: ldarg.0\n        IL_0099: ldfld object Issue3421::'value'\n        IL_009e: brtrue IL_00ae\n\n        IL_00a3: ldarg.0\n        IL_00a4: ldstr \"\"\n        IL_00a9: stfld object Issue3421::'value'\n\n        IL_00ae: br IL_00b3\n\n        IL_00b3: ret\n    } // end of method Issue3421::SetValue\n\n    .method public hidebysig specialname rtspecialname \n        instance void .ctor () cil managed \n    {\n        // Method begins at RVA 0x2110\n        // Header size: 1\n        // Code size: 8 (0x8)\n        .maxstack 8\n\n        IL_0000: ldarg.0\n        IL_0001: call instance void [CORE_ASSEMBLY]System.Object::.ctor()\n        IL_0006: nop\n        IL_0007: ret\n    } // end of method Issue3421::.ctor\n\n} // end of class Issue3421\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3442.cs",
    "content": "namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3442\n{\n\tpublic class Class : Interface\n\t{\n\t\tprivate void M<T>() where T : Interface\n\t\t{\n\t\t}\n\n\t\tvoid Interface.M<T>()\n\t\t{\n\t\t\t//ILSpy generated this explicit interface implementation from .override directive in M\n\t\t\tthis.M<T>();\n\t\t}\n\t}\n\tpublic interface Interface\n\t{\n\t\tvoid M<T>() where T : Interface;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3442.il",
    "content": ".assembly extern System.Runtime\n{\n\t.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n\t.ver 4:0:0:0\n}\n\n.assembly Issue3442\n{\n\t.custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = (\n\t\t01 00 08 00 00 00 00 00\n\t)\n\t.custom instance void [System.Runtime]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = (\n\t\t01 00 01 00 54 02 16 57 72 61 70 4e 6f 6e 45 78\n\t\t63 65 70 74 69 6f 6e 54 68 72 6f 77 73 01\n\t)\n\t.custom instance void [System.Runtime]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [System.Runtime]System.Diagnostics.DebuggableAttribute/DebuggingModes) = (\n\t\t01 00 02 00 00 00 00 00\n\t)\n\t.permissionset reqmin = (\n\t\t2e 01 80 8a 53 79 73 74 65 6d 2e 53 65 63 75 72\n\t\t69 74 79 2e 50 65 72 6d 69 73 73 69 6f 6e 73 2e\n\t\t53 65 63 75 72 69 74 79 50 65 72 6d 69 73 73 69\n\t\t6f 6e 41 74 74 72 69 62 75 74 65 2c 20 53 79 73\n\t\t74 65 6d 2e 52 75 6e 74 69 6d 65 2c 20 56 65 72\n\t\t73 69 6f 6e 3d 39 2e 30 2e 30 2e 30 2c 20 43 75\n\t\t6c 74 75 72 65 3d 6e 65 75 74 72 61 6c 2c 20 50\n\t\t75 62 6c 69 63 4b 65 79 54 6f 6b 65 6e 3d 62 30\n\t\t33 66 35 66 37 66 31 31 64 35 30 61 33 61 15 01\n\t\t54 02 10 53 6b 69 70 56 65 72 69 66 69 63 61 74\n\t\t69 6f 6e 01\n\t)\n\t.hash algorithm 0x00008004 // SHA1\n\t.ver 0:0:0:0\n}\n\n.class private auto ansi '<Module>'\n{\n} // end of class <Module>\n\n.class interface public auto ansi abstract beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3442.Interface\n{\n\t// Methods\n\t.method public hidebysig newslot abstract virtual \n\t\tinstance void M<(ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3442.Interface) T> () cil managed \n\t{\n\t} // end of method Interface::M\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3442.Interface\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3442.Class\n\textends [System.Runtime]System.Object\n\timplements ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3442.Interface\n{\n\t// Methods\n\t.method private final hidebysig newslot virtual \n\t\tinstance void M<(ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3442.Interface) T> () cil managed \n\t{\n\t\t.override method instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3442.Interface::M()\n\t\t// Method begins at RVA 0x2050\n\t\t// Code size 1 (0x1)\n\t\t.maxstack 8\n\n\t\tIL_0000: ret\n\t} // end of method Class::M\n\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x2052\n\t\t// Code size 7 (0x7)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [System.Runtime]System.Object::.ctor()\n\t\tIL_0006: ret\n\t} // end of method Class::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3442.Class"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3465.cs",
    "content": "using System;\n#if EXPECTED_OUTPUT\nusing System.Runtime.CompilerServices;\n#endif\nnamespace Issue3465\n{\n\tinternal class Program\n\t{\n\t\tprivate static Program programNull;\n\n\t\tprivate static Program GetProgram()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tprivate static bool Test3465()\n\t\t{\n\t\t\tProgram program = GetProgram();\n\t\t\treturn System.Runtime.CompilerServices.Unsafe.As<Program, UIntPtr>(ref program) > System.Runtime.CompilerServices.Unsafe.As<Program, UIntPtr>(ref programNull);\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3465.il",
    "content": ".class private auto ansi '<Module>'\n{\n} // end of class <Module>\n\n.class private auto ansi beforefieldinit Issue3465.Program\n    extends [System.Runtime]System.Object\n{\n    // Fields\n    .field private static class Issue3465.Program programNull\n\n    // Methods\n    .method private hidebysig static \n        class Issue3465.Program GetProgram () cil managed \n    {\n        // Method begins at RVA 0x2050\n        // Header size: 1\n        // Code size: 2 (0x2)\n        .maxstack 8\n\n        IL_0000: ldnull\n        IL_0001: ret\n    } // end of method Issue3465.Program::GetProgram\n\n    .method private hidebysig static \n        bool Test3465 () cil managed \n    {\n        // Method begins at RVA 0x2054\n        // Header size: 12\n        // Code size: 7 (0x7)\n        .maxstack 1\n        .locals init (\n            [0] bool\n        )\n\n        IL_0000: call class Issue3465.Program Issue3465.Program::GetProgram()\n        IL_0001: ldsfld class Issue3465.Program Issue3465.Program::programNull\n                 cgt.un\n        IL_0002: stloc.0\n        IL_0003: br.s IL_0005\n\n        IL_0005: ldloc.0\n        IL_0006: ret\n    } // end of method Program::Test3465\n\n    .method public hidebysig specialname rtspecialname \n        instance void .ctor () cil managed \n    {\n        // Method begins at RVA 0x2067\n        // Header size: 1\n        // Code size: 8 (0x8)\n        .maxstack 8\n\n        IL_0000: ldarg.0\n        IL_0001: call instance void [System.Runtime]System.Object::.ctor()\n        IL_0006: nop\n        IL_0007: ret\n    } // end of method Issue3465.Program::.ctor\n\n} // end of class Issue3465.Program\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3466.cs",
    "content": "namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n\tpublic class Issue3466<T>\n\t{\n\t\tpublic static implicit operator Issue3466<T>(T t)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\t\tpublic static bool M(Issue3466<object> x)\n\t\t{\n\t\t\treturn x != null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3466.il",
    "content": ".assembly extern System.Runtime\n{\n\t.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n\t.ver 4:0:0:0\n}\n\n.assembly Issue3466\n{\n\t.hash algorithm 0x00008004 // SHA1\n\t.ver 0:0:0:0\n}\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3466`1<T>\n\textends [System.Runtime]System.Object\n{\n\t.method public hidebysig specialname static \n\t\tclass ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3466`1<!T> op_Implicit (\n\t\t\t!T t\n\t\t) cil managed \n\t{\n\t\t.maxstack 8\n\n\t\tIL_0000: ldnull\n\t\tIL_0001: ret\n\t}\n\n\t.method public final hidebysig static bool M(class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3466`1<object> x) cil managed \n\t{\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: brtrue.s IL_0004\n\t\tIL_0002: ldc.i4.0\n\t\tIL_0003: br.s IL_0005\n\t\tIL_0004: ldc.i4.1\n\t\tIL_0005: ret\n\t}\n\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [System.Runtime]System.Object::.ctor()\n\t\tIL_0006: ret\n\t}\n\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3504.cs",
    "content": "using System;\n\ninternal class Issue3504\n{\n\tprivate void Method(Console console)\n\t{\n\t\tconsole.WriteLine(\"Hello.\");\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3504.il",
    "content": ".class private auto ansi beforefieldinit Issue3504\n\textends [System.Runtime]System.Object\n{\n\t// Methods\n\t.method private hidebysig \n\t\tinstance void Method (class [System.Console]System.Console console) cil managed \n\t{\n\t\t// Method begins at RVA 0x2050\n\t\t// Header size: 1\n\t\t// Code size: 13 (0xd)\n\t\t.maxstack 8\n\n\t\tIL_0000: nop\n\t\tIL_0001: ldarg.1\n        IL_0002: ldstr \"Hello.\"\n\t\tIL_0007: call instance void [System.Console]System.Console::WriteLine(string)\n\t\tIL_000b: nop\n\t\tIL_000c: ret\n\t} // end of method Issue3504::Method\n\n\t.method public hidebysig specialname rtspecialname \n\t\tinstance void .ctor () cil managed \n\t{\n\t\t// Method begins at RVA 0x205e\n\t\t// Header size: 1\n\t\t// Code size: 8 (0x8)\n\t\t.maxstack 8\n\n\t\tIL_0000: ldarg.0\n\t\tIL_0001: call instance void [System.Runtime]System.Object::.ctor()\n\t\tIL_0006: nop\n\t\tIL_0007: ret\n\t} // end of method Issue3504::.ctor\n\n} // end of class Issue3504\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3524.cs",
    "content": "public class C\n{\n\tpublic static int X {\n\t\tget {\n\t\t\treturn 32;\n\t\t}\n\t\tset {\n\t\t}\n\t}\n\tstatic C()\n\t{\n\t\tX = 1;\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3524.il",
    "content": ".assembly _\n{\n    .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = (\n        01 00 08 00 00 00 00 00\n    )\n    .custom instance void [System.Runtime]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = (\n        01 00 01 00 54 02 16 57 72 61 70 4e 6f 6e 45 78\n        63 65 70 74 69 6f 6e 54 68 72 6f 77 73 01\n    )\n    .custom instance void [System.Runtime]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [System.Runtime]System.Diagnostics.DebuggableAttribute/DebuggingModes) = (\n        01 00 07 01 00 00 00 00\n    )\n    .hash algorithm 0x00008004 // SHA1\n    .ver 0:0:0:0\n}\n\n.class public auto ansi beforefieldinit C\n    extends [System.Runtime]System.Object\n{\n    // Methods\n    .method public hidebysig specialname static \n        int32 get_X () cil managed \n    {\n        // Method begins at RVA 0x2050\n        // Code size 6 (0x6)\n        .maxstack 8\n\n        IL_0000: ldc.i4 32\n        IL_0005: ret\n    } // end of method C::get_X\n\n    .method public hidebysig specialname static \n        void set_X (\n            int32 'value'\n        ) cil managed \n    {\n        // Method begins at RVA 0x2058\n        // Code size 1 (0x1)\n        .maxstack 8\n\n        IL_0000: ret\n    } // end of method C::set_X\n\n    .method public hidebysig specialname rtspecialname \n        instance void .ctor () cil managed \n    {\n        // Method begins at RVA 0x2068\n        // Code size 8 (0x8)\n        .maxstack 8\n\n        IL_0000: ldarg.0\n        IL_0001: call instance void [System.Runtime]System.Object::.ctor()\n        IL_0006: nop\n        IL_0007: ret\n    } // end of method C::.ctor\n\n    .method private hidebysig specialname rtspecialname static \n        void .cctor () cil managed \n    {\n        // Method begins at RVA 0x2074\n        // Code size 11 (0xb)\n        .maxstack 8\n\n        IL_0000: ldc.i4 1\n        IL_0005: call void C::set_X(int32)\n        IL_000a: ret\n    } // end of method C::.cctor\n\n    // Properties\n    .property int32 X()\n    {\n        .get int32 C::get_X()\n        .set void C::set_X(int32)\n    }\n\n} // end of class C\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3552.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n\tpublic static class Issue3552\n\t{\n\t\tpublic static Issue3552_IntegerPair MakePair1(int x, int y)\n\t\t{\n\t\t\tIssue3552_IntegerPairBuilder issue3552_IntegerPairBuilder = new Issue3552_IntegerPairBuilder { x, y };\n\t\t\treturn issue3552_IntegerPairBuilder.ToPair();\n\t\t}\n\t\tpublic static Issue3552_IntegerPair MakePair2(int x, int y)\n\t\t{\n\t\t\tIssue3552_IntegerPairBuilder issue3552_IntegerPairBuilder = new Issue3552_IntegerPairBuilder { x, y };\n\t\t\treturn issue3552_IntegerPairBuilder.ToPair();\n\t\t}\n\t\tpublic static Issue3552_IntegerPair MakePair3(int x, int y)\n\t\t{\n\t\t\tIssue3552_IntegerPairBuilder issue3552_IntegerPairBuilder = new Issue3552_IntegerPairBuilder { x, y };\n\t\t\treturn issue3552_IntegerPairBuilder.ToPair();\n\t\t}\n\t}\n\tpublic struct Issue3552_IntegerPair\n\t{\n\t\tpublic int X;\n\t\tpublic int Y;\n\t}\n\tpublic struct Issue3552_IntegerPairBuilder : IEnumerable<int>, IEnumerable\n\t{\n\t\tprivate int index;\n\t\tprivate Issue3552_IntegerPair pair;\n\n\t\tpublic readonly Issue3552_IntegerPair ToPair()\n\t\t{\n\t\t\treturn pair;\n\t\t}\n\n\t\tpublic void Add(int value)\n\t\t{\n\t\t\tswitch (index)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tpair.X = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tpair.Y = value;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IndexOutOfRangeException();\n\t\t\t}\n\t\t\tindex++;\n\t\t}\n\n\t\tpublic IEnumerator<int> GetEnumerator()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tIEnumerator IEnumerable.GetEnumerator()\n\t\t{\n\t\t\treturn GetEnumerator();\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3552.il",
    "content": ".class public auto ansi abstract sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552\n    extends [System.Runtime]System.Object\n{\n    // Methods\n    .method public hidebysig static \n        valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair MakePair1 (\n            int32 x,\n            int32 y\n        ) cil managed \n    {\n        // Method begins at RVA 0x2050\n        // Header size: 12\n        // Code size: 34 (0x22)\n        .maxstack 2\n        .locals init (\n            [0] valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder\n        )\n\n        IL_0000: ldloca.s 0\n        IL_0002: initobj ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder\n        IL_0008: ldloca.s 0\n        IL_000a: ldarg.0\n        IL_000b: call instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::Add(int32)\n        IL_0010: ldloca.s 0\n        IL_0012: ldarg.1\n        IL_0013: call instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::Add(int32)\n        IL_0015: ldloca.s 0\n        IL_001c: call instance valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::ToPair()\n        IL_0021: ret\n    } // end of method Issue3552::MakePair1\n\n    .method public hidebysig static \n        valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair MakePair2 (\n            int32 x,\n            int32 y\n        ) cil managed \n    {\n        // Method begins at RVA 0x2050\n        // Header size: 12\n        // Code size: 34 (0x22)\n        .maxstack 2\n        .locals init (\n            [0] valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder\n        )\n\n        IL_0000: ldloca.s 0\n        IL_0001: dup\n        IL_0002: initobj ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder\n        IL_0008: dup\n        IL_000a: ldarg.0\n        IL_000b: call instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::Add(int32)\n        IL_0012: ldarg.1\n        IL_0013: call instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::Add(int32)\n        IL_0015: ldloca.s 0\n        IL_001c: call instance valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::ToPair()\n        IL_0021: ret\n    } // end of method Issue3552::MakePair2\n\n    .method public hidebysig static \n        valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair MakePair3 (\n            int32 x,\n            int32 y\n        ) cil managed \n    {\n        // Method begins at RVA 0x2050\n        // Header size: 12\n        // Code size: 34 (0x22)\n        .maxstack 2\n        .locals init (\n            [0] valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder\n        )\n\n        IL_0000: ldloca.s 0\n        IL_0001: dup\n        IL_0002: initobj ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder\n        IL_0008: dup\n        IL_000a: ldarg.0\n        IL_000b: call instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::Add(int32)\n        IL_0010: dup\n        IL_0012: ldarg.1\n        IL_0013: call instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::Add(int32)\n        IL_001c: call instance valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::ToPair()\n        IL_0021: ret\n    } // end of method Issue3552::MakePair3\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552\n\n.class public sequential ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair\n    extends [System.Runtime]System.ValueType\n{\n    // Fields\n    .field public int32 X\n    .field public int32 Y\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair\n\n.class public sequential ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder\n    extends [System.Runtime]System.ValueType\n    implements class [System.Runtime]System.Collections.Generic.IEnumerable`1<int32>,\n               [System.Runtime]System.Collections.IEnumerable\n{\n    // Fields\n    .field private int32 index\n    .field private valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair pair\n\n    // Methods\n    .method public hidebysig \n        instance valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair ToPair () cil managed \n    {\n        .custom instance void [System.Runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = (\n            01 00 00 00\n        )\n        // Method begins at RVA 0x207e\n        // Header size: 1\n        // Code size: 7 (0x7)\n        .maxstack 8\n\n        IL_0000: ldarg.0\n        IL_0001: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::pair\n        IL_0006: ret\n    } // end of method Issue3552_IntegerPairBuilder::ToPair\n\n    .method public hidebysig \n        instance void Add (\n            int32 'value'\n        ) cil managed \n    {\n        // Method begins at RVA 0x2088\n        // Header size: 12\n        // Code size: 65 (0x41)\n        .maxstack 3\n        .locals init (\n            [0] int32\n        )\n\n        IL_0000: ldarg.0\n        IL_0001: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::index\n        IL_0006: stloc.0\n        IL_0007: ldloc.0\n        IL_0008: brfalse.s IL_0010\n\n        IL_000a: ldloc.0\n        IL_000b: ldc.i4.1\n        IL_000c: beq.s IL_001e\n\n        IL_000e: br.s IL_002c\n\n        IL_0010: ldarg.0\n        IL_0011: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::pair\n        IL_0016: ldarg.1\n        IL_0017: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair::X\n        IL_001c: br.s IL_0032\n\n        IL_001e: ldarg.0\n        IL_001f: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::pair\n        IL_0024: ldarg.1\n        IL_0025: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair::Y\n        IL_002a: br.s IL_0032\n\n        IL_002c: newobj instance void [System.Runtime]System.IndexOutOfRangeException::.ctor()\n        IL_0031: throw\n\n        IL_0032: ldarg.0\n        IL_0033: ldarg.0\n        IL_0034: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::index\n        IL_0039: ldc.i4.1\n        IL_003a: add\n        IL_003b: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::index\n        IL_0040: ret\n    } // end of method Issue3552_IntegerPairBuilder::Add\n\n    .method public final hidebysig newslot virtual \n        instance class [System.Runtime]System.Collections.Generic.IEnumerator`1<int32> GetEnumerator () cil managed \n    {\n        // Method begins at RVA 0x20d5\n        // Header size: 1\n        // Code size: 2 (0x2)\n        .maxstack 8\n\n        IL_0000: ldnull\n        IL_0001: ret\n    } // end of method Issue3552_IntegerPairBuilder::GetEnumerator\n\n    .method private final hidebysig newslot virtual \n        instance class [System.Runtime]System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () cil managed \n    {\n        .override method instance class [System.Runtime]System.Collections.IEnumerator [System.Runtime]System.Collections.IEnumerable::GetEnumerator()\n        // Method begins at RVA 0x20d8\n        // Header size: 1\n        // Code size: 7 (0x7)\n        .maxstack 8\n\n        IL_0000: ldarg.0\n        IL_0001: call instance class [System.Runtime]System.Collections.Generic.IEnumerator`1<int32> ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::GetEnumerator()\n        IL_0006: ret\n    } // end of method Issue3552_IntegerPairBuilder::System.Collections.IEnumerable.GetEnumerator\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue379.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n\tinternal class Issue379\n\t{\n\t\tpublic virtual void Test<T>() where T : new()\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue379.il",
    "content": "// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly ConsoleApp11\n{\n  .ver 1:0:0:0\n}\n.module ConsoleApp11.exe\n// MVID: {B973FCD6-A9C4-48A9-8291-26DDC248E208}\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00020003    //  ILONLY 32BITPREFERRED\n// Image base: 0x000001C4B6C90000\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue379\n       extends [mscorlib]System.Object\n{\n.method public hidebysig virtual \n        instance void  Test<.ctor T>() cil managed\n{\n  // Code size       2 (0x2)\n  .maxstack  8\n  IL_0000:  nop\n  IL_0001:  ret\n} // end of method Program::Test\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue646.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\n\nusing Microsoft.VisualBasic.CompilerServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n\t[StandardModule]\n\tinternal sealed class Issue646\n\t{\n\t\t[STAThread]\n\t\tpublic static void Main()\n\t\t{\n\t\t\tList<string> list = new List<string>();\n\t\t\tforeach (string item in list)\n\t\t\t{\n\t\t\t\tDebug.WriteLine(item);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue646.il",
    "content": "// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly extern System\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly extern Microsoft.VisualBasic\n{\n  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )                         // .?_....:\n  .ver 10:0:0:0\n}\n.assembly ConsoleApp11\n{\n  .ver 1:0:0:0\n}\n.module ConsoleApp11.exe\n// MVID: {B973FCD6-A9C4-48A9-8291-26DDC248E208}\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00020003    //  ILONLY 32BITPREFERRED\n// Image base: 0x000001C4B6C90000\n\n.class private auto ansi sealed ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue646\n\textends [mscorlib]System.Object\n{\n\t.custom instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.StandardModuleAttribute::.ctor() = (\n\t\t01 00 00 00\n\t)\n\t// Methods\n\t.method public static \n\t\tvoid Main () cil managed \n\t{\n\t\t.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = (\n\t\t\t01 00 00 00\n\t\t)\n\t\t// Method begins at RVA 0x21b4\n\t\t// Code size 61 (0x3d)\n\t\t.maxstack 1\n\t\t.entrypoint\n\t\t.locals init (\n\t\t\t[0] class [mscorlib]System.Collections.Generic.List`1<string>,\n\t\t\t[1] valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<string>,\n\t\t\t[2] string,\n\t\t\t[3] bool\n\t\t)\n\n\t\tIL_0000: nop\n\t\tIL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1<string>::.ctor()\n\t\tIL_0006: stloc.0\n\t\t.try\n\t\t{\n\t\t\tIL_0007: ldloc.0\n\t\t\tIL_0008: callvirt instance valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<!0> class [mscorlib]System.Collections.Generic.List`1<string>::GetEnumerator()\n\t\t\tIL_000d: stloc.1\n\t\t\tIL_000e: br.s IL_0020\n\t\t\t// loop start (head: IL_0020)\n\t\t\t\tIL_0010: ldloca.s 1\n\t\t\t\tIL_0012: call instance !0 valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<string>::get_Current()\n\t\t\t\tIL_0017: stloc.2\n\t\t\t\tIL_0018: ldloc.2\n\t\t\t\tIL_0019: call void [System]System.Diagnostics.Debug::WriteLine(string)\n\t\t\t\tIL_001e: nop\n\t\t\t\tIL_001f: nop\n\n\t\t\t\tIL_0020: ldloca.s 1\n\t\t\t\tIL_0022: call instance bool valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<string>::MoveNext()\n\t\t\t\tIL_0027: stloc.3\n\t\t\t\tIL_0028: ldloc.3\n\t\t\t\tIL_0029: brtrue.s IL_0010\n\t\t\t// end loop\n\n\t\t\tIL_002b: leave.s IL_003c\n\t\t} // end .try\n\t\tfinally\n\t\t{\n\t\t\tIL_002d: ldloca.s 1\n\t\t\tIL_002f: constrained. valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<string>\n\t\t\tIL_0035: callvirt instance void [mscorlib]System.IDisposable::Dispose()\n\t\t\tIL_003a: nop\n\t\t\tIL_003b: endfinally\n\t\t} // end handler\n\n\t\tIL_003c: ret\n\t} // end of method Module1::Main\n\n} // end of class ConsoleApp11.Module1\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue684.cs",
    "content": "using System;\n\npublic static class Issue684\n{\n\tstatic int Main(string[] A_0)\n\t{\n\t\tint[] array = new int[1000];\n\t\tint num = int.Parse(Console.ReadLine());\n\t\t// Point of this test was to ensure the stack slot here uses an appropriate type,\n\t\t// (bool instead of int). Unfortunately our type fixup runs too late to affect variable names.\n\t\tbool num2 = num >= 1000;\n\t\tif (!num2)\n\t\t{\n\t\t\tnum2 = num < 2;\n\t\t}\n\t\tif (num2)\n\t\t{\n\t\t\tConsole.WriteLine(-1);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tint i = 2;\n\t\t\tfor (int num3 = 2; num3 <= num; num3 = i)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(num3);\n\t\t\t\tfor (; i <= num; i += num3)\n\t\t\t\t{\n\t\t\t\t\tint num4 = 1;\n\t\t\t\t\tarray[i] = num4;\n\t\t\t\t}\n\t\t\t\ti = num3;\n\t\t\t\twhile (true)\n\t\t\t\t{\n\t\t\t\t\tbool num5 = i <= num;\n\t\t\t\t\tif (num5)\n\t\t\t\t\t{\n\t\t\t\t\t\tnum5 = array[i] != 0;\n\t\t\t\t\t}\n\t\t\t\t\tif (!num5)\n\t\t\t\t\t{\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue684.il",
    "content": ".assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly Issue684\n{\n  .ver 1:0:0:0\n}\n.module Issue684.exe\n\n.class public auto ansi abstract sealed Issue684\n\textends [mscorlib]System.Object\n{\n\t// Methods\n\t\n  .method static privatescope \n\t  int32 Main$PST06000001 (\n\t\t  string[] ''\n\t  ) cil managed \n  {\n\t  // Method begins at RVA 0x2050\n\t  // Code size 196 (0xc4)\n\t  .maxstack 11\n\t  .entrypoint\n\t  .locals init (\n\t\t  [0] int32,\n\t\t  [1] int32,\n\t\t  [2] int32,\n\t\t  [3] int32[],\n\t\t  [4] int32\n\t  )\n\n\t  IL_0000: ldc.i4 1000\n\t  IL_0005: newarr [mscorlib]System.Int32\n\t  IL_000a: stloc.3\n\t  IL_000b: call string [mscorlib]System.Console::ReadLine()\n\t  IL_0010: call int32 [mscorlib]System.Int32::Parse(string)\n\t  IL_0015: stloc.2\n\t  IL_0016: ldloc.2\n\t  IL_0017: ldc.i4 1000\n\t  IL_001c: clt\n\t  IL_001e: ldc.i4.0\n\t  IL_001f: ceq\n\t  IL_0021: dup\n\t  IL_0022: brtrue IL_0030\n\n\t  IL_0027: pop\n\t  IL_0028: ldloc.2\n\t  IL_0029: ldc.i4 2\n\t  IL_002e: clt\n\n\t  IL_0030: brfalse IL_0045\n\n\t  IL_0035: ldc.i4 1\n\t  IL_003a: neg\n\t  IL_003b: call void [mscorlib]System.Console::WriteLine(int32)\n\t  IL_0040: br IL_00c2\n\n\t  IL_0045: ldc.i4 2\n\t  IL_004a: stloc.0\n\t  IL_004b: ldc.i4 2\n\t  IL_0050: stloc.1\n\t  // loop start (head: IL_0051)\n\t\t  IL_0051: ldloc.1\n\t\t  IL_0052: ldloc.2\n\t\t  IL_0053: cgt\n\t\t  IL_0055: ldc.i4.0\n\t\t  IL_0056: ceq\n\t\t  IL_0058: brfalse IL_00c2\n\n\t\t  IL_005d: ldloc.1\n\t\t  IL_005e: call void [mscorlib]System.Console::WriteLine(int32)\n\t\t  // loop start (head: IL_0063)\n\t\t\t  IL_0063: ldloc.0\n\t\t\t  IL_0064: ldloc.2\n\t\t\t  IL_0065: cgt\n\t\t\t  IL_0067: ldc.i4.0\n\t\t\t  IL_0068: ceq\n\t\t\t  IL_006a: brfalse IL_0088\n\n\t\t\t  IL_006f: ldc.i4 1\n\t\t\t  IL_0074: stloc.s 4\n\t\t\t  IL_0076: ldloc.3\n\t\t\t  IL_0077: ldloc.0\n\t\t\t  IL_0078: ldloc.s 4\n\t\t\t  IL_007a: stelem.any [mscorlib]System.Int32\n\t\t\t  IL_007f: ldloc.0\n\t\t\t  IL_0080: ldloc.1\n\t\t\t  IL_0081: add\n\t\t\t  IL_0082: stloc.0\n\t\t\t  IL_0083: br IL_0063\n\t\t  // end loop\n\n\t\t  IL_0088: ldloc.1\n\t\t  IL_0089: stloc.0\n\t\t  // loop start (head: IL_008a)\n\t\t\t  IL_008a: ldloc.0\n\t\t\t  IL_008b: ldloc.2\n\t\t\t  IL_008c: cgt\n\t\t\t  IL_008e: ldc.i4.0\n\t\t\t  IL_008f: ceq\n\t\t\t  IL_0091: dup\n\t\t\t  IL_0092: brfalse IL_00a9\n\n\t\t\t  IL_0097: pop\n\t\t\t  IL_0098: ldloc.3\n\t\t\t  IL_0099: ldloc.0\n\t\t\t  IL_009a: ldelem.any [mscorlib]System.Int32\n\t\t\t  IL_009f: ldc.i4 0\n\t\t\t  IL_00a4: ceq\n\t\t\t  IL_00a6: ldc.i4.0\n\t\t\t  IL_00a7: ceq\n\n\t\t\t  IL_00a9: brfalse IL_00bb\n\n\t\t\t  IL_00ae: ldloc.0\n\t\t\t  IL_00af: ldc.i4 1\n\t\t\t  IL_00b4: add\n\t\t\t  IL_00b5: stloc.0\n\t\t\t  IL_00b6: br IL_008a\n\t\t  // end loop\n\n\t\t  IL_00bb: ldloc.0\n\t\t  IL_00bc: stloc.1\n\t\t  IL_00bd: br IL_0051\n\t  // end loop\n\n\t  IL_00c2: ldc.i4.0\n\t  IL_00c3: ret\n  } // end of method Program::Main\n\n} // end of class Issue684\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue959.cs",
    "content": "namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n\tinternal class Issue959\n\t{\n\t\tpublic void Test(bool arg)\n\t\t{\n\t\t\tif (!arg && arg)\n\t\t\t{\n\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue959.il",
    "content": "// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly ConsoleApp11\n{\n  .ver 1:0:0:0\n}\n.module ConsoleApp11.exe\n// MVID: {B973FCD6-A9C4-48A9-8291-26DDC248E208}\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00020003    //  ILONLY 32BITPREFERRED\n// Image base: 0x000001C4B6C90000\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue959\n       extends [mscorlib]System.Object\n{\n.method public hidebysig instance void  Test(\n            bool arg\n        ) cil managed\n{\n  // Code size 18 (0x12)\n  .maxstack  8\n\tIL_0000: ldarg.1\n\tIL_0001: brfalse IL_000b\n\tIL_0006: br IL_0011\n\tIL_000b: ldarg.1\n\tIL_000c: brtrue IL_0011\n\tIL_0011: ret\n} // end of method Program::Test\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue982.cs",
    "content": "using System.Runtime.CompilerServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n\tinternal class Issue982\n\t{\n\t\tprivate string textStr;\n\n\t\tprivate string textStr2;\n\n\t\tpublic string Text {\n\t\t\tget {\n\t\t\t\treturn textStr;\n\t\t\t}\n\t\t\tset {\n\t\t\t\ttextStr = value;\n\t\t\t}\n\t\t}\n\n\t\t[IndexerName(\"Text2\")]\n\t\tpublic string this[int index] {\n\t\t\tget {\n\t\t\t\treturn textStr2;\n\t\t\t}\n\t\t\tset {\n\t\t\t\ttextStr2 = value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue982.il",
    "content": "\n//  Microsoft (R) .NET Framework IL Disassembler.  Version 3.5.30729.1\n//  Copyright (c) Microsoft Corporation.  All rights reserved.\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly extern System\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly extern Microsoft.VisualBasic\n{\n  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )                         // .?_....:\n  .ver 10:0:0:0\n}\n.assembly ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n  .hash algorithm 0x00008004\n  .ver 1:0:0:0\n}\n\n.module Issue982.exe\n// MVID: {1DAED9CF-459B-4BA6-A091-CB3BDEF963F8}\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00020003    //  ILONLY 32BITREQUIRED\n// Image base: 0x06E80000\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982\n       extends [mscorlib]System.Object\n{\n  .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = ( 01 00 05 54 65 78 74 32 00 00 )                   // ...Text2..\n  .field private string textStr\n  .field private string textStr2\n  .method public specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method Issue982::.ctor\n\n  .method public specialname instance string \n          get_Text() cil managed\n  {\n    // Code size       12 (0xc)\n    .maxstack  1\n    .locals init ([0] string Text)\n    IL_0000:  nop\n    IL_0001:  ldarg.0\n    IL_0002:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982::textStr\n    IL_0007:  stloc.0\n    IL_0008:  br.s       IL_000a\n\n    IL_000a:  ldloc.0\n    IL_000b:  ret\n  } // end of method Issue982::get_Text\n\n  .method public specialname instance void \n          set_Text(string str) cil managed\n  {\n    // Code size       9 (0x9)\n    .maxstack  8\n    IL_0000:  nop\n    IL_0001:  ldarg.0\n    IL_0002:  ldarg.1\n    IL_0003:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982::textStr\n    IL_0008:  ret\n  } // end of method Issue982::set_Text\n\n  .method public specialname instance string \n          get_Text2(int32 index) cil managed\n  {\n    // Code size       12 (0xc)\n    .maxstack  1\n    .locals init ([0] string Text2)\n    IL_0000:  nop\n    IL_0001:  ldarg.0\n    IL_0002:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982::textStr2\n    IL_0007:  stloc.0\n    IL_0008:  br.s       IL_000a\n\n    IL_000a:  ldloc.0\n    IL_000b:  ret\n  } // end of method Issue982::get_Text2\n\n  .method public specialname instance void \n          set_Text2(int32 index,\n                    string str) cil managed\n  {\n    // Code size       9 (0x9)\n    .maxstack  8\n    IL_0000:  nop\n    IL_0001:  ldarg.0\n    IL_0002:  ldarg.2\n    IL_0003:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982::textStr2\n    IL_0008:  ret\n  } // end of method Issue982::set_Text2\n\n  .property instance string Text()\n  {\n    .get instance string ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982::get_Text()\n    .set instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982::set_Text(string)\n  } // end of property Issue982::Text\n  .property instance string Text2(int32)\n  {\n    .get instance string ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982::get_Text2(int32)\n    .set instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982::set_Text2(int32,\n                                                      string)\n  } // end of property Issue982::Text2\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/MonoFixed.cs",
    "content": "using System;\n\npublic class MonoFixed\n{\n\tpublic unsafe void FixMultipleStrings(string text)\n\t{\n\t\tfixed (char* ptr = text)\n\t\t{\n\t\t\tfixed (char* userName = Environment.UserName)\n\t\t\t{\n\t\t\t\tfixed (char* ptr2 = text)\n\t\t\t\t{\n\t\t\t\t\t*ptr = 'c';\n\t\t\t\t\t*userName = 'd';\n\t\t\t\t\t*ptr2 = 'e';\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/MonoFixed.il",
    "content": ".assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )\n  .ver 4:0:0:0\n}\n.assembly MonoFixed\n{\n  .ver 1:0:0:0\n}\n\n.module MonoFixed.exe\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003 // WindowsCui\n.corflags 0x00000001 // ILOnly\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = (\n\t01 00 00 00\n)\n\n.class public auto ansi beforefieldinit MonoFixed\n\t   extends [mscorlib]System.Object\n{\n  .method public hidebysig instance void FixMultipleStrings (string text) cil managed\n\t{\n\t\t.maxstack 7\n\t\t.locals init (\n\t\t\t[0] char* pinned,\n\t\t\t[1] char* pinned,\n\t\t\t[2] char* pinned,\n\t\t\t[3] string pinned,\n\t\t\t[4] string pinned,\n\t\t\t[5] string pinned\n\t\t)\n\n\t\tIL_0000: ldarg.1\n\t\tIL_0001: stloc.3\n\t\tIL_0002: ldloc.3\n\t\tIL_0003: conv.i\n\t\tIL_0004: call int32 [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::get_OffsetToStringData()\n\t\tIL_0009: add\n\t\tIL_000a: stloc.0\n\t\tIL_000b: call string [mscorlib]System.Environment::get_UserName()\n\t\tIL_0010: stloc.s 4\n\t\tIL_0012: ldloc.s 4\n\t\tIL_0014: conv.i\n\t\tIL_0015: call int32 [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::get_OffsetToStringData()\n\t\tIL_001a: add\n\t\tIL_001b: stloc.1\n\t\tIL_001c: ldarg.1\n\t\tIL_001d: stloc.s 5\n\t\tIL_001f: ldloc.s 5\n\t\tIL_0021: conv.i\n\t\tIL_0022: call int32 [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::get_OffsetToStringData()\n\t\tIL_0027: add\n\t\tIL_0028: stloc.2\n\t\tIL_0029: ldloc.0\n\t\tIL_002a: ldc.i4.s 99\n\t\tIL_002c: stind.i2\n\t\tIL_002d: ldloc.1\n\t\tIL_002e: ldc.i4.s 100\n\t\tIL_0030: stind.i2\n\t\tIL_0031: ldloc.2\n\t\tIL_0032: ldc.i4.s 101\n\t\tIL_0034: stind.i2\n\t\tIL_0035: ldnull\n\t\tIL_0036: stloc.3\n\t\tIL_0037: ldnull\n\t\tIL_0038: stloc.s 4\n\t\tIL_003a: ldnull\n\t\tIL_003b: stloc.s 5\n\t\tIL_003d: ret\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/SequenceOfNestedIfs.cs",
    "content": "using System;\n[Serializable]\npublic class Material\n{\n\tpublic static implicit operator bool(Material m)\n\t{\n\t\treturn m == null;\n\t}\n}\n[Serializable]\npublic class SequenceOfNestedIfs\n{\n\tpublic bool _clear;\n\tpublic Material _material;\n\tpublic virtual bool CheckShader()\n\t{\n\t\treturn false;\n\t}\n\tpublic virtual void CreateMaterials()\n\t{\n\t\tif (!_clear)\n\t\t{\n\t\t\tif (!CheckShader())\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t_material = new Material();\n\t\t}\n\t\tif (!_material)\n\t\t{\n\t\t\tif (!CheckShader())\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t_material = new Material();\n\t\t}\n\t\tif (!_material)\n\t\t{\n\t\t\tif (!CheckShader())\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t_material = new Material();\n\t\t}\n\t\tif (!_material && CheckShader())\n\t\t{\n\t\t\t_material = new Material();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/SequenceOfNestedIfs.il",
    "content": "// Metadata version: v2.0.50727\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 2:0:0:0\n}\n\n.assembly SequenceOfNestedIfs\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module SequenceOfNestedIfs\n// MVID: {DCEC8A87-5679-4EBE-89A3-51274D8B5446}\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n// Image base: 0x01D60000\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public auto ansi serializable beforefieldinit Material\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method Material::.ctor\n\n  .method public hidebysig specialname static \n          bool  op_Implicit(class Material m) cil managed\n  {\n    // Code size       11 (0xb)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  ldnull\n    IL_0008:  ceq\n    IL_000a:  ret\n  } // end of method Material::op_Implicit\n\n} // end of class Material\n\n.class public auto ansi serializable beforefieldinit SequenceOfNestedIfs\n       extends [mscorlib]System.Object\n{\n  .field public bool _clear\n  .field public class Material _material\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void  [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method SequenceOfNestedIfs::.ctor\n\n  .method public hidebysig virtual instance bool \n          CheckShader() cil managed\n  {\n    // Code size       2 (0x2)\n    .maxstack  8\n    IL_0000:  ldc.i4.0\n    IL_0001:  ret\n  } // end of method SequenceOfNestedIfs::CheckShader\n\n  .method public hidebysig virtual instance void \n          CreateMaterials() cil managed\n  {\n    // Code size       168 (0xa8)\n    .maxstack  13\n    IL_0000:  ldarg.0\n    IL_0001:  ldfld      bool SequenceOfNestedIfs::_clear\n    IL_0006:  brtrue     IL_0026\n\n    IL_000b:  ldarg.0\n    IL_000c:  callvirt   instance bool SequenceOfNestedIfs::CheckShader()\n    IL_0011:  brtrue     IL_001b\n\n    IL_0016:  br         IL_00a7\n\n    IL_001b:  ldarg.0\n    IL_001c:  newobj     instance void Material::.ctor()\n    IL_0021:  stfld      class Material SequenceOfNestedIfs::_material\n    IL_0026:  ldarg.0\n    IL_0027:  ldfld      class Material SequenceOfNestedIfs::_material\n    IL_002c:  call       bool Material::op_Implicit(class Material)\n    IL_0031:  brtrue     IL_0051\n\n    IL_0036:  ldarg.0\n    IL_0037:  callvirt   instance bool SequenceOfNestedIfs::CheckShader()\n    IL_003c:  brtrue     IL_0046\n\n    IL_0041:  br         IL_00a7\n\n    IL_0046:  ldarg.0\n    IL_0047:  newobj     instance void Material::.ctor()\n    IL_004c:  stfld      class Material SequenceOfNestedIfs::_material\n    IL_0051:  ldarg.0\n    IL_0052:  ldfld      class Material SequenceOfNestedIfs::_material\n    IL_0057:  call       bool Material::op_Implicit(class Material)\n    IL_005c:  brtrue     IL_007c\n\n    IL_0061:  ldarg.0\n    IL_0062:  callvirt   instance bool SequenceOfNestedIfs::CheckShader()\n    IL_0067:  brtrue     IL_0071\n\n    IL_006c:  br         IL_00a7\n\n    IL_0071:  ldarg.0\n    IL_0072:  newobj     instance void Material::.ctor()\n    IL_0077:  stfld      class Material SequenceOfNestedIfs::_material\n    IL_007c:  ldarg.0\n    IL_007d:  ldfld      class Material SequenceOfNestedIfs::_material\n    IL_0082:  call       bool Material::op_Implicit(class Material)\n    IL_0087:  brtrue     IL_00a7\n\n    IL_008c:  ldarg.0\n    IL_008d:  callvirt   instance bool SequenceOfNestedIfs::CheckShader()\n    IL_0092:  brtrue     IL_009c\n\n    IL_0097:  br         IL_00a7\n\n    IL_009c:  ldarg.0\n    IL_009d:  newobj     instance void Material::.ctor()\n    IL_00a2:  stfld      class Material SequenceOfNestedIfs::_material\n    IL_00a7:  ret\n  } // end of method SequenceOfNestedIfs::CreateMaterials\n\n} // end of class SequenceOfNestedIfs"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/UnknownTypes.cs",
    "content": "internal class UnknownTypes\n{\n\tprivate readonly IInterface memberField;\n\n\tpublic virtual bool CanExecute(CallbackQuery message)\n\t{\n\t\treturn ((IInterface<SomeClass, bool>)(object)memberField).Execute(new SomeClass {\n\t\t\tChatId = StaticClass.GetChatId(message),\n\t\t\tMessageId = StaticClass.GetMessageId(message)\n\t\t});\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/UnknownTypes.il",
    "content": "#define CORE_ASSEMBLY \"System.Runtime\"\n\n.assembly extern CORE_ASSEMBLY\n{\n  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )                         // .?_....:\n  .ver 4:0:0:0\n}\n.assembly extern UnknownAssembly\n{\n  .publickeytoken = (01 02 03 04 05 06 07 08 )\n  .ver 1:0:0:0\n}\n\n.class private auto ansi beforefieldinit UnknownTypes\n    extends [System.Private.CoreLib]System.Object\n{\n    .field private initonly class [UnknownAssembly]IInterface memberField\n\n    // Methods\n    .method public hidebysig specialname rtspecialname \n        instance void .ctor () cil managed \n    {\n        // Method begins at RVA 0x206e\n        // Code size 8 (0x8)\n        .maxstack 8\n\n        IL_0000: ldarg.0\n        IL_0001: call instance void [CORE_ASSEMBLY]System.Object::.ctor()\n        IL_0006: nop\n        IL_0007: ret\n    } // end of method UnknownTypes::.ctor\n\n    .method public hidebysig virtual \n\t    instance bool CanExecute (\n\t\t    class [UnknownAssembly]CallbackQuery message\n\t    ) cil managed \n    {\n\t    // Method begins at RVA 0x4dbc\n\t    // Code size 44 (0x2c)\n\t    .maxstack 8\n\n\t    IL_0000: ldarg.0\n\t    IL_0001: ldfld class [UnknownAssembly]IInterface UnknownTypes::memberField\n\t    IL_0006: newobj instance void [UnknownAssembly]SomeClass::.ctor()\n\t    IL_000b: dup\n\t    IL_000d: ldarg.1\n\t    IL_000e: call int64 [UnknownAssembly]StaticClass::GetChatId(class [UnknownAssembly]CallbackQuery)\n\t    IL_0013: stfld int64 [UnknownAssembly]SomeClass::ChatId\n\t    IL_0018: dup\n\t    IL_001a: ldarg.1\n\t    IL_001b: call int32 [UnknownAssembly]StaticClass::GetMessageId(class [UnknownAssembly]CallbackQuery)\n\t    IL_0020: conv.i8\n\t    IL_0021: stfld int64 [UnknownAssembly]SomeClass::MessageId\n\t    IL_0026: callvirt instance !1 class [UnknownAssembly]IInterface`2<class [UnknownAssembly]SomeClass, bool>::Execute(!0)\n\t    IL_002b: ret\n    } // end of method CanExecute\n\n\n} // end of class UnknownTypes\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Unsafe.cs",
    "content": "using System;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\n\n[assembly: AssemblyMetadata(\".NETFrameworkAssembly\", \"\")]\n[assembly: CLSCompliant(false)]\n[assembly: AssemblyFileVersion(\"4.0.0.0\")]\n[assembly: AssemblyInformationalVersion(\"4.0.0.0\")]\n[assembly: AssemblyTitle(\"System.Runtime.CompilerServices.Unsafe\")]\n[assembly: AssemblyDescription(\"System.Runtime.CompilerServices.Unsafe\")]\n[assembly: AssemblyMetadata(\"Serviceable\", \"True\")]\n[assembly: AssemblyCopyright(\"© Microsoft Corporation.  All rights reserved.\")]\n[assembly: AssemblyCompany(\"Microsoft Corporation\")]\n[assembly: AssemblyProduct(\"Microsoft® .NET Framework\")]\n\ninternal sealed class ExtraUnsafeTests\n{\n\tpublic unsafe static void PinWithTypeMismatch(ref uint managedPtr)\n\t{\n\t\tfixed (ushort* ptr = &Unsafe.As<uint, ushort>(ref managedPtr))\n\t\t{\n\t\t}\n\t}\n\n\tpublic unsafe static uint* RefToPointerWithoutPinning(ref uint managedPtr)\n\t{\n\t\treturn (uint*)Unsafe.AsPointer(ref managedPtr);\n\t}\n\n\tpublic static ref ulong RefAssignTypeMismatch(ref uint a, ref uint b)\n\t{\n\t\tref ushort reference = ref Unsafe.As<uint, ushort>(ref a);\n\t\tif (a != 0)\n\t\t{\n\t\t\treference = ref Unsafe.As<uint, ushort>(ref b);\n\t\t}\n\t\tConsole.WriteLine(reference);\n\t\treturn ref Unsafe.As<ushort, ulong>(ref reference);\n\t}\n\n\tpublic unsafe static byte[] Issue1292(int val, byte[] arr)\n\t{\n\t\tfixed (byte* ptr = arr)\n\t\t{\n\t\t\t*(int*)ptr = val;\n\t\t}\n\t\treturn arr;\n\t}\n\n\tpublic unsafe void pin_ptr_test(int[] a, int[] b)\n\t{\n\t\t//The blocks IL_0016 are reachable both inside and outside the pinned region starting at IL_0007. ILSpy has duplicated these blocks in order to place them both within and outside the `fixed` statement.\n\t\tref int reference;\n\t\tfixed (int* ptr = &a[0])\n\t\t{\n\t\t\tif (*ptr <= 0)\n\t\t\t{\n\t\t\t\tUnsafe.AddByteOffset(ref *ptr, 4 * 0) = 1;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treference = ref *ptr;\n\t\t}\n\t\tfixed (int* ptr = &b[reference])\n\t\t{\n\t\t\tUnsafe.AddByteOffset(ref *ptr, 4 * 0) = 1;\n\t\t}\n\t}\n\n\tprivate static void Issue2148(string[] args)\n\t{\n\t\tfor (int/*pinned*/ i = 0; i < 100; i++)\n\t\t{\n\t\t\tConsole.WriteLine(\"Hello World!\");\n\t\t}\n\t}\n\n\tprivate unsafe static void Issue2189()\n\t{\n\t\tfixed (int* ptr = &Unsafe.AsRef<int>((int*)Unsafe.AsPointer(ref SomeStruct.instance.mtfhist)))\n\t\t{\n\t\t\tint num = *ptr;\n\t\t}\n\t}\n\tprivate unsafe static void PinUnmanagedPtr(int* A_0)\n\t{\n\t\tfixed (int* ptr = &Unsafe.AsRef<int>(A_0))\n\t\t{\n\t\t\tint num = *ptr;\n\t\t}\n\t}\n\tprivate static ref float AddressTypeMismatch(ref int A_0)\n\t{\n\t\treturn ref Unsafe.As<int, float>(ref A_0);\n\t}\n\tprivate unsafe static ref float AddressTypeMismatch(int* A_0)\n\t{\n\t\treturn ref *(float*)A_0;\n\t}\n\tprivate static float LoadWithTypeMismatch(ref int A_0)\n\t{\n\t\treturn Unsafe.As<int, float>(ref A_0);\n\t}\n\tprivate unsafe static float LoadWithTypeMismatch(int* A_0)\n\t{\n\t\treturn *(float*)A_0;\n\t}\n\tprivate static void StoreWithTypeMismatch(ref int A_0)\n\t{\n\t\tUnsafe.As<int, float>(ref A_0) = 1f;\n\t}\n\tprivate unsafe static void StoreWithTypeMismatch(int* A_0)\n\t{\n\t\t*(float*)A_0 = 1f;\n\t}\n\tprivate static ref float AddressOfFieldTypeMismatch(ref int A_0)\n\t{\n\t\treturn ref Unsafe.As<int, SomeStruct>(ref A_0).float_field;\n\t}\n\tprivate unsafe static ref float AddressOfFieldTypeMismatch(int* A_0)\n\t{\n\t\treturn ref ((SomeStruct*)A_0)->float_field;\n\t}\n\tprivate static float LoadOfFieldTypeMismatch(ref int A_0)\n\t{\n\t\treturn Unsafe.As<int, SomeStruct>(ref A_0).float_field;\n\t}\n\tprivate unsafe static float LoadOfFieldTypeMismatch(int* A_0)\n\t{\n\t\treturn ((SomeStruct*)A_0)->float_field;\n\t}\n\tprivate static void StoreOfFieldTypeMismatch(ref int A_0)\n\t{\n\t\tUnsafe.As<int, SomeStruct>(ref A_0).float_field = 1f;\n\t}\n\tprivate unsafe static void StoreOfFieldTypeMismatch(int* A_0)\n\t{\n\t\t((SomeStruct*)A_0)->float_field = 1f;\n\t}\n}\ninternal struct SomeStruct\n{\n\tpublic int int_field;\n\tpublic float float_field;\n}\n\nnamespace System.Runtime.CompilerServices\n{\n\tpublic static class Unsafe\n\t{\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic unsafe static T Read<T>(void* source)\n\t\t{\n\t\t\treturn Unsafe.Read<T>(source);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic unsafe static T ReadUnaligned<T>(void* source)\n\t\t{\n\t\t\treturn Unsafe.ReadUnaligned<T>(source);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static T ReadUnaligned<T>(ref byte source)\n\t\t{\n\t\t\treturn Unsafe.ReadUnaligned<T>(ref source);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic unsafe static void Write<T>(void* destination, T value)\n\t\t{\n\t\t\tUnsafe.Write(destination, value);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic unsafe static void WriteUnaligned<T>(void* destination, T value)\n\t\t{\n\t\t\tUnsafe.WriteUnaligned(destination, value);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static void WriteUnaligned<T>(ref byte destination, T value)\n\t\t{\n\t\t\tUnsafe.WriteUnaligned(ref destination, value);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic unsafe static void Copy<T>(void* destination, ref T source)\n\t\t{\n\t\t\tUnsafe.Write(destination, source);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic unsafe static void Copy<T>(ref T destination, void* source)\n\t\t{\n\t\t\tdestination = Unsafe.Read<T>(source);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic unsafe static void* AsPointer<T>(ref T value)\n\t\t{\n\t\t\treturn Unsafe.AsPointer(ref value);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static void SkipInit<T>(out T value)\n\t\t{\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static int SizeOf<T>()\n\t\t{\n\t\t\treturn Unsafe.SizeOf<T>();\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic unsafe static void CopyBlock(void* destination, void* source, uint byteCount)\n\t\t{\n\t\t\t// IL cpblk instruction\n\t\t\tUnsafe.CopyBlock(destination, source, byteCount);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static void CopyBlock(ref byte destination, ref byte source, uint byteCount)\n\t\t{\n\t\t\t// IL cpblk instruction\n\t\t\tUnsafe.CopyBlock(ref destination, ref source, byteCount);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic unsafe static void CopyBlockUnaligned(void* destination, void* source, uint byteCount)\n\t\t{\n\t\t\t// IL cpblk instruction\n\t\t\tUnsafe.CopyBlockUnaligned(destination, source, byteCount);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static void CopyBlockUnaligned(ref byte destination, ref byte source, uint byteCount)\n\t\t{\n\t\t\t// IL cpblk instruction\n\t\t\tUnsafe.CopyBlockUnaligned(ref destination, ref source, byteCount);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic unsafe static void InitBlock(void* startAddress, byte value, uint byteCount)\n\t\t{\n\t\t\t// IL initblk instruction\n\t\t\tUnsafe.InitBlock(startAddress, value, byteCount);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static void InitBlock(ref byte startAddress, byte value, uint byteCount)\n\t\t{\n\t\t\t// IL initblk instruction\n\t\t\tUnsafe.InitBlock(ref startAddress, value, byteCount);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount)\n\t\t{\n\t\t\t// IL initblk instruction\n\t\t\tUnsafe.InitBlockUnaligned(startAddress, value, byteCount);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount)\n\t\t{\n\t\t\t// IL initblk instruction\n\t\t\tUnsafe.InitBlockUnaligned(ref startAddress, value, byteCount);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static T As<T>(object o) where T : class\n\t\t{\n\t\t\treturn (T)o;\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic unsafe static ref T AsRef<T>(void* source)\n\t\t{\n\t\t\treturn ref *(T*)source;\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static ref T AsRef<T>(in T source)\n\t\t{\n\t\t\treturn ref source;\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static ref TTo As<TFrom, TTo>(ref TFrom source)\n\t\t{\n\t\t\treturn ref Unsafe.As<TFrom, TTo>(ref source);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static ref T Unbox<T>(object box) where T : struct\n\t\t{\n\t\t\treturn ref (T)box;\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static ref T Add<T>(ref T source, int elementOffset)\n\t\t{\n\t\t\treturn ref Unsafe.Add(ref source, elementOffset);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic unsafe static void* Add<T>(void* source, int elementOffset)\n\t\t{\n\t\t\treturn (byte*)source + (nint)elementOffset * (nint)Unsafe.SizeOf<T>();\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static ref T Add<T>(ref T source, IntPtr elementOffset)\n\t\t{\n\t\t\treturn ref Unsafe.Add(ref source, elementOffset);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static ref T Add<T>(ref T source, UIntPtr elementOffset)\n\t\t{\n\t\t\treturn ref Unsafe.Add(ref source, elementOffset);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static ref T AddByteOffset<T>(ref T source, IntPtr byteOffset)\n\t\t{\n\t\t\treturn ref Unsafe.AddByteOffset(ref source, byteOffset);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static ref T AddByteOffset<T>(ref T source, UIntPtr byteOffset)\n\t\t{\n\t\t\treturn ref Unsafe.AddByteOffset(ref source, byteOffset);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static ref T Subtract<T>(ref T source, int elementOffset)\n\t\t{\n\t\t\treturn ref Unsafe.Subtract(ref source, elementOffset);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic unsafe static void* Subtract<T>(void* source, int elementOffset)\n\t\t{\n\t\t\treturn (byte*)source - (nint)elementOffset * (nint)Unsafe.SizeOf<T>();\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static ref T Subtract<T>(ref T source, IntPtr elementOffset)\n\t\t{\n\t\t\treturn ref Unsafe.Subtract(ref source, elementOffset);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static ref T Subtract<T>(ref T source, UIntPtr elementOffset)\n\t\t{\n\t\t\treturn ref Unsafe.Subtract(ref source, elementOffset);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static ref T SubtractByteOffset<T>(ref T source, IntPtr byteOffset)\n\t\t{\n\t\t\treturn ref Unsafe.SubtractByteOffset(ref source, byteOffset);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static ref T SubtractByteOffset<T>(ref T source, UIntPtr byteOffset)\n\t\t{\n\t\t\treturn ref Unsafe.SubtractByteOffset(ref source, byteOffset);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static IntPtr ByteOffset<T>(ref T origin, ref T target)\n\t\t{\n\t\t\treturn Unsafe.ByteOffset(target: ref target, origin: ref origin);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static bool AreSame<T>(ref T left, ref T right)\n\t\t{\n\t\t\treturn Unsafe.AreSame(ref left, ref right);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static bool IsAddressGreaterThan<T>(ref T left, ref T right)\n\t\t{\n\t\t\treturn Unsafe.IsAddressGreaterThan(ref left, ref right);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static bool IsAddressLessThan<T>(ref T left, ref T right)\n\t\t{\n\t\t\treturn Unsafe.IsAddressLessThan(ref left, ref right);\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic unsafe static bool IsNullRef<T>(ref T source)\n\t\t{\n\t\t\treturn Unsafe.AsPointer(ref source) == null;\n\t\t}\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic unsafe static ref T NullRef<T>()\n\t\t{\n\t\t\treturn ref *(T*)null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Unsafe.il",
    "content": "#define CORE_ASSEMBLY \"System.Runtime\"\n\n.assembly extern CORE_ASSEMBLY\n{\n  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )                         // .?_....:\n  .ver 4:0:0:0\n}\n\n.assembly extern System.Console\n{\n  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )\n  .ver 4:0:0:0\n}\n\n.assembly System.Runtime.CompilerServices.Unsafe\n{\n  .custom instance void [CORE_ASSEMBLY]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [CORE_ASSEMBLY]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                                   63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [CORE_ASSEMBLY]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [CORE_ASSEMBLY]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) \n\n  .custom instance void [CORE_ASSEMBLY]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = ( 01 00 07 34 2E 30 2E 30 2E 30 00 00 )             // ...4.0.0.0..\n  .custom instance void [CORE_ASSEMBLY]System.Reflection.AssemblyInformationalVersionAttribute::.ctor(string) = ( 01 00 07 34 2E 30 2E 30 2E 30 00 00 )             // ...4.0.0.0..\n  .custom instance void [CORE_ASSEMBLY]System.Reflection.AssemblyTitleAttribute::.ctor(string) = ( 01 00 26 53 79 73 74 65 6D 2E 52 75 6E 74 69 6D   // ..&System.Runtim\n                                                                                              65 2E 43 6F 6D 70 69 6C 65 72 53 65 72 76 69 63   // e.CompilerServic\n                                                                                              65 73 2E 55 6E 73 61 66 65 00 00 )                // es.Unsafe..\n  .custom instance void [CORE_ASSEMBLY]System.Reflection.AssemblyDescriptionAttribute::.ctor(string) = ( 01 00 26 53 79 73 74 65 6D 2E 52 75 6E 74 69 6D   // ..&System.Runtim\n                                                                                                    65 2E 43 6F 6D 70 69 6C 65 72 53 65 72 76 69 63   // e.CompilerServic\n                                                                                                    65 73 2E 55 6E 73 61 66 65 00 00 )                // es.Unsafe..\n  .custom instance void [CORE_ASSEMBLY]System.Reflection.AssemblyMetadataAttribute::.ctor(string, string) = (\n    01 00 15 2e 4e 45 54 46 72 61 6d 65 77 6f 72 6b\n    41 73 73 65 6d 62 6c 79 00 00 00\n  ) // \".NETFrameworkAssembly\", \"\"\n  .custom instance void [CORE_ASSEMBLY]System.Reflection.AssemblyMetadataAttribute::.ctor(string, string) = (\n    01 00 0b 53 65 72 76 69 63 65 61 62 6c 65 04 54\n    72 75 65 00 00\n  ) // \"Serviceable\", \"True\"\n  .custom instance void [CORE_ASSEMBLY]System.Reflection.AssemblyCopyrightAttribute::.ctor(string) = ( 01 00 2F C2 A9 20 4D 69 63 72 6F 73 6F 66 74 20   // ../.. Microsoft \n                                                                                        43 6F 72 70 6F 72 61 74 69 6F 6E 2E 20 20 41 6C   // Corporation.  Al\n                                                                                        6C 20 72 69 67 68 74 73 20 72 65 73 65 72 76 65   // l rights reserve\n                                                                                        64 2E 00 00 )                                     // d...\n  .custom instance void [CORE_ASSEMBLY]System.Reflection.AssemblyCompanyAttribute::.ctor(string) = ( 01 00 15 4D 69 63 72 6F 73 6F 66 74 20 43 6F 72   // ...Microsoft Cor\n                                                                                      70 6F 72 61 74 69 6F 6E 00 00 )                   // poration..\n  .custom instance void [CORE_ASSEMBLY]System.Reflection.AssemblyProductAttribute::.ctor(string) = ( 01 00 1A 4D 69 63 72 6F 73 6F 66 74 C2 AE 20 2E   // ...Microsoft.. .\n                                                                                      4E 45 54 20 46 72 61 6D 65 77 6F 72 6B 00 00 )    // NET Framework..\n  .custom instance void [CORE_ASSEMBLY]System.CLSCompliantAttribute::.ctor(bool) = (\n    01 00 00 00 00\n  ) // false\n  .hash algorithm 0x00008004\n  .ver 4:0:5:0\n}\n.module System.Runtime.CompilerServices.Unsafe.dll\n// MVID: {1E97D84A-565B-49C5-B60A-F31A1A4ACE13}\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n// Image base: 0x02ED0000\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public abstract auto ansi sealed beforefieldinit System.Runtime.CompilerServices.Unsafe\n       extends [CORE_ASSEMBLY]System.Object\n{\n  .method public hidebysig static !!T Read<T>(void* source) cil managed aggressiveinlining\n  {\n        .maxstack 1\n        ldarg.0\n        ldobj !!T\n        ret\n  } // end of method Unsafe::Read\n\n  .method public hidebysig static !!T ReadUnaligned<T>(void* source) cil managed aggressiveinlining\n  {\n        .maxstack 1\n        ldarg.0\n        unaligned. 0x1\n        ldobj !!T\n        ret\n  } // end of method Unsafe::ReadUnaligned\n\n  .method public hidebysig static !!T ReadUnaligned<T>(uint8& source) cil managed aggressiveinlining\n  {\n        .maxstack 1\n        ldarg.0\n        unaligned. 0x1\n        ldobj !!T\n        ret\n  } // end of method Unsafe::ReadUnaligned\n\n  .method public hidebysig static void Write<T>(void* destination,\n                                                 !!T 'value') cil managed aggressiveinlining\n  {\n        .maxstack 2\n        ldarg.0\n        ldarg.1\n        stobj !!T\n        ret\n  } // end of method Unsafe::Write\n\n  .method public hidebysig static void WriteUnaligned<T>(void* destination,\n                                                 !!T 'value') cil managed aggressiveinlining\n  {\n        .maxstack 2\n        ldarg.0\n        ldarg.1\n        unaligned. 0x01\n        stobj !!T\n        ret\n  } // end of method Unsafe::WriteUnaligned\n\n  .method public hidebysig static void WriteUnaligned<T>(uint8& destination,\n                                                 !!T 'value') cil managed aggressiveinlining\n  {\n        .maxstack 2\n        ldarg.0\n        ldarg.1\n        unaligned. 0x01\n        stobj !!T\n        ret\n  } // end of method Unsafe::WriteUnaligned\n\n  .method public hidebysig static void Copy<T>(void* destination,\n                                                !!T& source) cil managed aggressiveinlining\n  {\n        .maxstack 2\n        ldarg.0\n        ldarg.1\n        ldobj !!T\n        stobj !!T\n        ret\n  } // end of method Unsafe::Copy\n\n  .method public hidebysig static void Copy<T>(!!T& destination,\n                                                void* source) cil managed aggressiveinlining\n  {\n        .maxstack 2\n        ldarg.0\n        ldarg.1\n        ldobj !!T\n        stobj !!T\n        ret\n  } // end of method Unsafe::Copy\n\n  .method public hidebysig static void* AsPointer<T>(!!T& 'value') cil managed aggressiveinlining\n  {\n        .maxstack 1\n        ldarg.0\n        conv.u\n        ret\n  } // end of method Unsafe::AsPointer\n\n  .method public hidebysig static void SkipInit<T> ([out] !!T& 'value') cil managed aggressiveinlining\n  {\n        .maxstack 0\n        ret\n  } // end of method Unsafe::SkipInit\n\n  .method public hidebysig static int32 SizeOf<T>() cil managed aggressiveinlining\n  {\n        .maxstack 1\n        sizeof !!T\n        ret\n  } // end of method Unsafe::SizeOf\n\n  .method public hidebysig static void CopyBlock(void* destination, void* source, uint32 byteCount) cil managed aggressiveinlining\n  {\n        .maxstack 3\n        ldarg.0\n        ldarg.1\n        ldarg.2\n        cpblk\n        ret\n  } // end of method Unsafe::CopyBlock\n\n  .method public hidebysig static void CopyBlock(uint8& destination, uint8& source, uint32 byteCount) cil managed aggressiveinlining\n  {\n        .maxstack 3\n        ldarg.0\n        ldarg.1\n        ldarg.2\n        cpblk\n        ret\n  } // end of method Unsafe::CopyBlock\n\n  .method public hidebysig static void CopyBlockUnaligned(void* destination, void* source, uint32 byteCount) cil managed aggressiveinlining\n  {\n        .maxstack 3\n        ldarg.0\n        ldarg.1\n        ldarg.2\n        unaligned. 0x1\n        cpblk\n        ret\n  } // end of method Unsafe::CopyBlockUnaligned\n\n  .method public hidebysig static void CopyBlockUnaligned(uint8& destination, uint8& source, uint32 byteCount) cil managed aggressiveinlining\n  {\n        .maxstack 3\n        ldarg.0\n        ldarg.1\n        ldarg.2\n        unaligned. 0x1\n        cpblk\n        ret\n  } // end of method Unsafe::CopyBlockUnaligned\n\n  .method public hidebysig static void InitBlock(void* startAddress, uint8 'value', uint32 byteCount) cil managed aggressiveinlining\n  {\n        .maxstack 3\n        ldarg.0\n        ldarg.1\n        ldarg.2\n        initblk\n        ret\n  } // end of method Unsafe::InitBlock\n\n  .method public hidebysig static void InitBlock(uint8& startAddress, uint8 'value', uint32 byteCount) cil managed aggressiveinlining\n  {\n        .maxstack 3\n        ldarg.0\n        ldarg.1\n        ldarg.2\n        initblk\n        ret\n  } // end of method Unsafe::InitBlock\n\n  .method public hidebysig static void InitBlockUnaligned(void* startAddress, uint8 'value', uint32 byteCount) cil managed aggressiveinlining\n  {\n        .maxstack 3\n        ldarg.0\n        ldarg.1\n        ldarg.2\n        unaligned. 0x1\n        initblk\n        ret\n  } // end of method Unsafe::InitBlockUnaligned\n\n  .method public hidebysig static void InitBlockUnaligned(uint8& startAddress, uint8 'value', uint32 byteCount) cil managed aggressiveinlining\n  {\n        .maxstack 3\n        ldarg.0\n        ldarg.1\n        ldarg.2\n        unaligned. 0x1\n        initblk\n        ret\n  } // end of method Unsafe::InitBlockUnaligned\n\n  .method public hidebysig static !!T As<class T>(object o) cil managed aggressiveinlining\n  {\n        .maxstack 1\n        ldarg.0\n        ret\n  } // end of method Unsafe::As\n\n  .method public hidebysig static !!T& AsRef<T>(void* source) cil managed aggressiveinlining\n  {\n// For .NET Core the roundtrip via a local is no longer needed see:\n// https://github.com/dotnet/runtime/issues/8730\n// and\n// https://github.com/dotnet/coreclr/pull/11218\n#ifdef netcoreapp\n        .maxstack 1\n        ldarg.0\n        ret\n#else\n        .locals (int32&)\n        .maxstack 1\n        ldarg.0\n        // Roundtrip via a local to avoid type mismatch on return that the JIT inliner chokes on.\n        stloc.0\n        ldloc.0\n        ret\n#endif\n  } // end of method Unsafe::AsRef\n\n  .method public hidebysig static !!T& AsRef<T>(!!T& source) cil managed aggressiveinlining\n  {\n        .param [1]\n#ifdef netcoreapp\n        .custom instance void [CORE_ASSEMBLY]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )\n#else\n        .custom instance void System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )\n#endif\n        .maxstack 1\n        ldarg.0\n        ret\n  } // end of method Unsafe::AsRef\n\n  .method public hidebysig static !!TTo& As<TFrom, TTo>(!!TFrom& source) cil managed aggressiveinlining\n  {\n        .maxstack 1\n        ldarg.0\n        ret\n  } // end of method Unsafe::As\n\n  .method public hidebysig static !!T& Unbox<valuetype .ctor ([CORE_ASSEMBLY]System.ValueType) T> (object 'box') cil managed aggressiveinlining\n  {\n        .maxstack 1\n        ldarg.0\n        unbox !!T\n        ret\n  } // end of method Unsafe::Unbox\n\n  .method public hidebysig static !!T& Add<T>(!!T& source, int32 elementOffset) cil managed aggressiveinlining\n  {\n        .maxstack 3\n        ldarg.0\n        ldarg.1\n        sizeof !!T\n        conv.i\n        mul\n        add\n        ret\n  } // end of method Unsafe::Add\n\n  .method public hidebysig static void* Add<T>(void* source, int32 elementOffset) cil managed aggressiveinlining\n  {\n        .maxstack 3\n        ldarg.0\n        ldarg.1\n        sizeof !!T\n        conv.i\n        mul\n        add\n        ret\n  } // end of method Unsafe::Add\n\n  .method public hidebysig static !!T& Add<T>(!!T& source, native int elementOffset) cil managed aggressiveinlining\n  {\n        .maxstack 3\n        ldarg.0\n        ldarg.1\n        sizeof !!T\n        mul\n        add\n        ret\n  } // end of method Unsafe::Add\n\n  .method public hidebysig static !!T& Add<T>(!!T& source, native uint elementOffset) cil managed aggressiveinlining\n  {\n        .maxstack 3\n        ldarg.0\n        ldarg.1\n        sizeof !!T\n        mul\n        add\n        ret\n  } // end of method Unsafe::Add\n\n  .method public hidebysig static !!T& AddByteOffset<T>(!!T& source, native int byteOffset) cil managed aggressiveinlining\n  {\n        .maxstack 2\n        ldarg.0\n        ldarg.1\n        add\n        ret\n  } // end of method Unsafe::AddByteOffset\n\n  .method public hidebysig static !!T& AddByteOffset<T>(!!T& source, native uint byteOffset) cil managed aggressiveinlining\n  {\n        .maxstack 2\n        ldarg.0\n        ldarg.1\n        add\n        ret\n  } // end of method Unsafe::AddByteOffset\n\n  .method public hidebysig static !!T& Subtract<T>(!!T& source, int32 elementOffset) cil managed aggressiveinlining\n  {\n        .maxstack 3\n        ldarg.0\n        ldarg.1\n        sizeof !!T\n        conv.i\n        mul\n        sub\n        ret\n  } // end of method Unsafe::Subtract\n\n  .method public hidebysig static void* Subtract<T>(void* source, int32 elementOffset) cil managed aggressiveinlining\n  {\n        .maxstack 3\n        ldarg.0\n        ldarg.1\n        sizeof !!T\n        conv.i\n        mul\n        sub\n        ret\n  } // end of method Unsafe::Subtract\n\n  .method public hidebysig static !!T& Subtract<T>(!!T& source, native int elementOffset) cil managed aggressiveinlining\n  {\n        .maxstack 3\n        ldarg.0\n        ldarg.1\n        sizeof !!T\n        mul\n        sub\n        ret\n  } // end of method Unsafe::Subtract\n\n  .method public hidebysig static !!T& Subtract<T>(!!T& source, native uint elementOffset) cil managed aggressiveinlining\n  {\n        .maxstack 3\n        ldarg.0\n        ldarg.1\n        sizeof !!T\n        mul\n        sub\n        ret\n  } // end of method Unsafe::Subtract\n\n  .method public hidebysig static !!T& SubtractByteOffset<T>(!!T& source, native int byteOffset) cil managed aggressiveinlining\n  {\n        .maxstack 2\n        ldarg.0\n        ldarg.1\n        sub\n        ret\n  } // end of method Unsafe::SubtractByteOffset\n\n  .method public hidebysig static !!T& SubtractByteOffset<T>(!!T& source, native uint byteOffset) cil managed aggressiveinlining\n  {\n        .maxstack 2\n        ldarg.0\n        ldarg.1\n        sub\n        ret\n  } // end of method Unsafe::SubtractByteOffset\n\n  .method public hidebysig static native int ByteOffset<T>(!!T& origin, !!T& target) cil managed aggressiveinlining\n  {\n        .maxstack 2\n        ldarg.1\n        ldarg.0\n        sub\n        ret\n  } // end of method Unsafe::ByteOffset\n\n  .method public hidebysig static bool AreSame<T>(!!T& left, !!T& right) cil managed aggressiveinlining\n  {\n        .maxstack 2\n        ldarg.0\n        ldarg.1\n        ceq\n        ret\n  } // end of method Unsafe::AreSame\n\n  .method public hidebysig static bool IsAddressGreaterThan<T>(!!T& left, !!T& right) cil managed aggressiveinlining\n  {\n        .maxstack 2\n        ldarg.0\n        ldarg.1\n        cgt.un\n        ret\n  } // end of method Unsafe::IsAddressGreaterThan\n\n  .method public hidebysig static bool IsAddressLessThan<T>(!!T& left, !!T& right) cil managed aggressiveinlining\n  {\n        .maxstack 2\n        ldarg.0\n        ldarg.1\n        clt.un\n        ret\n  } // end of method Unsafe::IsAddressLessThan\n\n  .method public hidebysig static bool IsNullRef<T>(!!T& source) cil managed aggressiveinlining\n  {\n        .maxstack 2\n        ldarg.0\n        ldc.i4.0\n        conv.u\n        ceq\n        ret\n  } // end of method Unsafe::IsNullRef\n\n  .method public hidebysig static !!T& NullRef<T>() cil managed aggressiveinlining\n  {\n        .maxstack 1\n        ldc.i4.0\n        conv.u\n        ret\n  } // end of method Unsafe::NullRef\n\n} // end of class System.Runtime.CompilerServices.Unsafe\n\n#ifdef netcoreapp\n#else\n.class private auto ansi sealed beforefieldinit Microsoft.CodeAnalysis.EmbeddedAttribute\n  extends [CORE_ASSEMBLY]System.Attribute\n{\n  .custom instance void [CORE_ASSEMBLY]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n      01 00 00 00\n  )\n  .custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = (\n      01 00 00 00\n  )\n  .method public hidebysig specialname rtspecialname \n      instance void .ctor () cil managed \n  {\n      .maxstack 8\n      IL_0000: ldarg.0\n      IL_0001: call instance void [CORE_ASSEMBLY]System.Attribute::.ctor()\n      IL_0006: ret\n  } // end of method EmbeddedAttribute::.ctor\n\n} // end of class Microsoft.CodeAnalysis.EmbeddedAttribute\n\n.class private auto ansi sealed beforefieldinit System.Runtime.CompilerServices.IsReadOnlyAttribute\n       extends [CORE_ASSEMBLY]System.Attribute\n{\n  .custom instance void [CORE_ASSEMBLY]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (\n  \t01 00 00 00\n  )\n  .custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = (\n  \t01 00 00 00\n  )\n  .method public hidebysig specialname rtspecialname \n          instance void .ctor () cil managed \n  {\n        .maxstack 1\n        ldarg.0\n        call instance void [CORE_ASSEMBLY]System.Attribute::.ctor()\n        ret\n  } // end of method IsReadOnlyAttribute::.ctor\n\n} // end of class System.Runtime.CompilerServices.IsReadOnlyAttribute\n#endif\n\n.class private auto ansi sealed beforefieldinit ExtraUnsafeTests\n  extends [CORE_ASSEMBLY]System.Object\n{\n  .method public hidebysig specialname rtspecialname \n          instance void .ctor () cil managed \n  {\n        .maxstack 1\n        ldarg.0\n        call instance void [CORE_ASSEMBLY]System.Object::.ctor()\n        ret\n  } // end of method ExtraUnsafeTests::.ctor\n\n  .method public hidebysig static void PinWithTypeMismatch(uint32& managedPtr)\n  {\n    .maxstack 8\n    .locals (\n      [0] uint16& pinned\n    )\n    // Pin:\n    ldarg.0\n    stloc.0\n\n    // Unpin:\n    ldc.i4 0\n    stloc.0\n\n    ret\n  }\n\n  .method public hidebysig static uint32* RefToPointerWithoutPinning(uint32& managedPtr)\n  {\n    .maxstack 8\n\n    ldarg.0\n    ret\n  }\n\n  .method public hidebysig static uint64& RefAssignTypeMismatch(uint32& a, uint32& b)\n  {\n    .maxstack 8\n    .locals (\n      [0] uint16&\n    )\n\n    ldarg.0\n    stloc.0\n    \n    ldarg.0\n    ldind.i4\n    brfalse lbl\n\n    ldarg.1\n    stloc.0\n\nlbl:\n    ldloc.0\n    ldind.i2\n    call       void [System.Console]System.Console::WriteLine(uint16)\n\n    ldloc.0\n    ret\n  }\n\n  .method public hidebysig static \n\t  uint8[] Issue1292 (\n\t\t  int32 val,\n\t\t  uint8[] arr\n\t  ) cil managed \n  {\n\t  .maxstack 2\n\t  .locals init (\n\t\t  [0] uint8[],\n\t\t  [1] uint8[],\n\t\t  [2] uint8& pinned\n\t  )\n\n\t  IL_0000: ldarg.1\n\t  IL_0001: stloc.0\n\t  IL_0002: ldloc.0\n\t  IL_0003: dup\n\t  IL_0004: stloc.1\n\t  IL_0005: brfalse.s IL_0016\n\n\t  IL_0007: ldloc.1\n\t  IL_0008: ldlen\n\t  IL_0009: conv.i4\n\t  IL_000a: brfalse.s IL_0016\n\n\t  IL_000c: ldloc.1\n\t  IL_000d: ldc.i4.0\n\t  IL_000e: ldelema [System.Runtime]System.Byte\n\t  IL_0013: stloc.2\n\t  IL_0014: br.s IL_0019\n\n\t  IL_0016: ldc.i4.0\n\t  IL_0017: conv.u\n\t  IL_0018: stloc.2\n\n\t  IL_0019: ldloc.2\n\t  IL_001a: conv.i\n\t  IL_001b: ldarg.0\n\t  IL_001c: stind.i4\n\t  IL_001d: ldc.i4.0\n\t  IL_001e: conv.u\n\t  IL_001f: stloc.2\n\t  IL_0020: ldloc.0\n\t  IL_0021: ret\n  } // end of method Issue1292\n\n.method /* 06000066 */ public hidebysig \n\tinstance void pin_ptr_test (\n\t\tint32[] a,\n\t\tint32[] b\n\t) cil managed \n{\n\t/* From C++/CLI:\n      void pin_ptr_test(array<int>^ a, array<int>^ b)\n        {\n            pin_ptr<int> p = &a[0];\n            if (*p > 0)\n            {\n                p = &b[*p];\n            }\n            p[0] = 1;\n        }\n   */\n\t.maxstack 3\n\t.locals /* 11000004 */ (\n\t\t[0] int32& pinned modopt([System.Runtime]System.Runtime.CompilerServices.IsExplicitlyDereferenced) p\n\t)\n\n\tIL_0000: ldarg.1\n\tIL_0001: ldc.i4.0\n\tIL_0002: ldelema [System.Runtime]System.Int32 /* 01000016 */\n\tIL_0007: stloc.0\n\tIL_0008: ldloc.0\n\tIL_0009: ldind.i4\n\tIL_000a: ldc.i4.0\n\tIL_000b: ble.s IL_0016\n\n\tIL_000d: ldarg.2\n\tIL_000e: ldloc.0\n\tIL_000f: ldind.i4\n\tIL_0010: ldelema [System.Runtime]System.Int32 /* 01000016 */\n\tIL_0015: stloc.0\n\n\tIL_0016: ldloc.0\n\tIL_0017: ldc.i4.4\n\tIL_0018: ldc.i4.0\n\tIL_0019: mul\n\tIL_001a: add\n\tIL_001b: ldc.i4.1\n\tIL_001c: stind.i4\n\tIL_001d: ret\n} // end of method pin_ptr_test\n\n.method private hidebysig static \n\tvoid Issue2148 (\n\t\tstring[] args\n\t) cil managed \n{\n\t// Header Size: 12 bytes\n\t// Code Size: 24 (0x18) bytes\n\t// LocalVarSig Token: 0x11000001 RID: 1\n\t.maxstack 2\n\t.locals init (\n\t\t[0] int32 pinned\n\t)\n\n\t/* 0x00000264 16           */ IL_0000: ldc.i4.0\n\t/* 0x00000265 0A           */ IL_0001: stloc.0\n\t/* 0x00000266 2B0E         */ IL_0002: br.s      IL_0012\n\t// loop start (head: IL_0012)\n\t\t/* 0x00000268 7201000070   */ IL_0004: ldstr     \"Hello World!\"\n\t\t/* 0x0000026D 280B00000A   */ IL_0009: call      void [System.Console]System.Console::WriteLine(string)\n\t\t/* 0x00000272 06           */ IL_000E: ldloc.0\n\t\t/* 0x00000273 17           */ IL_000F: ldc.i4.1\n\t\t/* 0x00000274 58           */ IL_0010: add\n\t\t/* 0x00000275 0A           */ IL_0011: stloc.0\n\n\t\t/* 0x00000276 06           */ IL_0012: ldloc.0\n\t\t/* 0x00000277 1F64         */ IL_0013: ldc.i4.s  100\n\t\t/* 0x00000279 32ED         */ IL_0015: blt.s     IL_0004\n\t// end loop\n\n\t/* 0x0000027B 2A           */ IL_0017: ret\n} // end of method Issue2148\n\n\n.method private hidebysig static \n\tvoid Issue2189 () cil managed \n{\n\t.maxstack 2\n\t.locals init (\n    [0] int32,\n\t\t[1] int32& pinned\n\t)\n\n\tIL_0000: ldsflda valuetype [CORE_ASSEMBLY]SomeStruct [CORE_ASSEMBLY]SomeStruct::'instance'\n\tIL_0005: ldflda uint32 [CORE_ASSEMBLY]SomeStruct::mtfhist\n\tIL_000a: conv.u\n\tIL_000b: stloc.1\n\n  ldloc.1\n  ldind.i4\n  stloc.0\n\n\tIL_0185: ldc.i4.0\n\tIL_0186: conv.i\n\tIL_0187: stloc.1\n\tIL_0188: ret\n\n} // end of method Issue2189\n\n.method private hidebysig static \n\tvoid PinUnmanagedPtr (int32*) cil managed \n{\n\t.maxstack 2\n\t.locals init (\n    [0] int32,\n\t\t[1] int32& pinned\n\t)\n\n\tldarg.0\n\tstloc.1\n\n  ldloc.1\n  ldind.i4\n  stloc.0\n\n\tldc.i4.0\n\tconv.i\n\tstloc.1\n\tret\n\n} // end of method Issue2189\n\n\n.method private hidebysig static \n\tfloat32& AddressTypeMismatch (int32&) cil managed\n{\n\tldarg.0\n\tret\n}\n.method private hidebysig static \n\tfloat32& AddressTypeMismatch (int32*) cil managed\n{\n\tldarg.0\n\tret\n}\n\n.method private hidebysig static \n\tfloat32 LoadWithTypeMismatch (int32&) cil managed\n{\n\tldarg.0\n\tldind.r4\n\tret\n}\n.method private hidebysig static \n\tfloat32 LoadWithTypeMismatch (int32*) cil managed\n{\n\tldarg.0\n\tldind.r4\n\tret\n}\n\n.method private hidebysig static \n\tvoid StoreWithTypeMismatch (int32&) cil managed\n{\n\tldarg.0\n\tldc.r4 1\n  stind.r4\n\tret\n}\n.method private hidebysig static \n\tvoid StoreWithTypeMismatch (int32*) cil managed\n{\n\tldarg.0\n\tldc.r4 1\n  stind.r4\n\tret\n}\n\n.method private hidebysig static \n\tfloat32& AddressOfFieldTypeMismatch (int32&) cil managed\n{\n\tldarg.0\n  ldflda float32 SomeStruct::float_field\n\tret\n}\n.method private hidebysig static \n\tfloat32& AddressOfFieldTypeMismatch (int32*) cil managed\n{\n\tldarg.0\n  ldflda float32 SomeStruct::float_field\n\tret\n}\n\n.method private hidebysig static \n\tfloat32 LoadOfFieldTypeMismatch (int32&) cil managed\n{\n\tldarg.0\n  ldfld float32 SomeStruct::float_field\n\tret\n}\n.method private hidebysig static \n\tfloat32 LoadOfFieldTypeMismatch (int32*) cil managed\n{\n\tldarg.0\n  ldfld float32 SomeStruct::float_field\n\tret\n}\n\n.method private hidebysig static \n\tvoid StoreOfFieldTypeMismatch (int32&) cil managed\n{\n\tldarg.0\n\tldc.r4 1\n  stfld float32 SomeStruct::float_field\n\tret\n}\n.method private hidebysig static \n\tvoid StoreOfFieldTypeMismatch (int32*) cil managed\n{\n\tldarg.0\n\tldc.r4 1\n  stfld float32 SomeStruct::float_field\n\tret\n}\n\n} // class ExtraUnsafeTests\n\n.class  private sequential ansi sealed beforefieldinit SomeStruct\n\textends [mscorlib]System.ValueType\n{\n\t// Fields\n\t.field public int32 int_field\n\t.field public float32 float_field\n} // end of class SomeStruct\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/WeirdEnums.cs",
    "content": "using System;\n\nnamespace TestEnum\n{\n\tpublic enum BooleanEnum : bool\n\t{\n\t\tMin = false,\n\t\tZero = false,\n\t\tOne = true,\n\t\tMax = byte.MaxValue\n\t}\n\n\tpublic enum EnumWithNestedClass\n\t{\n#pragma warning disable format\n\t\t// error: nested types are not permitted in C#.\n\t\tpublic class NestedClass\n\t\t{\n\t\t}\n\t\t,\n#pragma warning enable format\n\t\tZero,\n\t\tOne\n\t}\n\n\tpublic enum NativeIntEnum : IntPtr\n\t{\n\t\tZero = 0L,\n\t\tOne = 1L,\n\t\tFortyTwo = 42L\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/ILPretty/WeirdEnums.il",
    "content": "// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly BoolEnum\n{\n  .ver 1:0:0:0\n}\n.module BoolEnum.exe\n.imagebase 0x00400000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00020003    //  ILONLY 32BITPREFERRED\n// Image base: 0x000001C4B6C90000\n\n.class public auto ansi sealed TestEnum.BooleanEnum\n\t   extends [mscorlib]System.Enum\n{\n\t.field public specialname rtspecialname bool value__\n\t.field public static literal valuetype TestEnum.BooleanEnum Min = bool(false)\n\t.field public static literal valuetype TestEnum.BooleanEnum Zero = bool(false)\n  .field public static literal valuetype TestEnum.BooleanEnum One = bool(true)\n\t.field public static literal valuetype TestEnum.BooleanEnum Max = uint8(255)\n}\n\n.class public auto ansi sealed TestEnum.NativeIntEnum\n\t   extends [mscorlib]System.Enum\n{\n\t.field public specialname rtspecialname native int value__\n\t.field public static literal valuetype TestEnum.NativeIntEnum Zero = int64(0)\n\t.field public static literal valuetype TestEnum.NativeIntEnum One = int64(1)\n\t.field public static literal valuetype TestEnum.NativeIntEnum FortyTwo = int64(42)\n}\n\n.class nested public auto ansi sealed TestEnum.EnumWithNestedClass\n    extends [System.Runtime]System.Enum\n{\n        // Nested Types\n    .class nested public auto ansi beforefieldinit NestedClass\n        extends [mscorlib]System.Object\n    {\n        // Methods\n        .method public hidebysig specialname rtspecialname \n            instance void .ctor () cil managed \n        {\n            // Method begins at RVA 0x206c\n            // Code size 8 (0x8)\n            .maxstack 8\n\n            IL_0000: ldarg.0\n            IL_0001: call instance void [mscorlib]System.Object::.ctor()\n            IL_0006: nop\n            IL_0007: ret\n        } // end of method TestEnum.NestedClass::.ctor\n\n    } // end of class NestedClass\n\n    // Fields\n    .field public specialname rtspecialname int32 value__\n    .field public static literal valuetype TestEnum.EnumWithNestedClass Zero = int32(0)\n    .field public static literal valuetype TestEnum.EnumWithNestedClass One = int32(1)\n    \n} // end of class EnumWithNestedClass"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/PdbGen/.gitignore",
    "content": "/*.dll\n/*.pdb\n/*.expected.xml\n/*.generated.xml\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/PdbGen/CustomPdbId.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<symbols>\n  <files>\n    <file id=\"1\" name=\"ICSharpCode.Decompiler.Tests.TestCases.PdbGen\\CustomPdbId.cs\" language=\"C#\" checksumAlgorithm=\"SHA256\"><![CDATA[using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.PdbGen;\n\npublic class CustomPdbId\n{\n\tpublic static void Main(string[] args)\n\t{\n\t\tConsole.ReadKey();\n\t\tConsole.WriteLine(\"Hello World!\");\n\t\tConsole.ReadKey();\n\t}\n}\n]]></file>\n  </files>\n</symbols>"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/PdbGen/ForLoopTests.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<symbols>\n  <files>\n    <file id=\"1\" name=\"ICSharpCode.Decompiler.Tests.TestCases.PdbGen\\ForLoopTests.cs\" language=\"C#\" checksumAlgorithm=\"SHA256\"><![CDATA[using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.PdbGen;\n\npublic class ForLoopTests\n{\n\tpublic static void SimplePrintLoop(string[] args)\n\t{\n\t\tfor (int i = 0; i < args.Length; i++)\n\t\t{\n\t\t\tConsole.WriteLine(args[i]);\n\t\t}\n\t}\n\n\tpublic static void SimplePrintLoopWithCondition(string[] args)\n\t{\n\t\tfor (int i = 0; i < args.Length; i++)\n\t\t{\n\t\t\tif (i % 2 != 0)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(args[i]);\n\t\t\t}\n\t\t}\n\t}\n}\n]]></file>\n  </files>\n  <methods>\n    <method containingType=\"ICSharpCode.Decompiler.Tests.TestCases.PdbGen.ForLoopTests\" name=\"SimplePrintLoop\" parameterNames=\"args\" token=\"0x6000001\">\n      <sequencePoints>\n        <entry offset=\"0x0\" startLine=\"9\" startColumn=\"9\" endLine=\"9\" endColumn=\"18\" document=\"1\" />\n        <entry offset=\"0x2\" hidden=\"true\" document=\"1\" />\n        <entry offset=\"0x4\" startLine=\"11\" startColumn=\"5\" endLine=\"11\" endColumn=\"32\" document=\"1\" />\n        <entry offset=\"0xc\" startLine=\"9\" startColumn=\"37\" endLine=\"9\" endColumn=\"40\" document=\"1\" />\n        <entry offset=\"0x10\" startLine=\"9\" startColumn=\"20\" endLine=\"9\" endColumn=\"35\" document=\"1\" />\n        <entry offset=\"0x16\" startLine=\"13\" startColumn=\"3\" endLine=\"13\" endColumn=\"4\" document=\"1\" />\n      </sequencePoints>\n      <scope startOffset=\"0x0\" endOffset=\"0x17\">\n        <scope startOffset=\"0x0\" endOffset=\"0x16\">\n          <local name=\"i\" il_index=\"0\" il_start=\"0x0\" il_end=\"0x16\" attributes=\"0\" />\n        </scope>\n      </scope>\n    </method>\n    <method containingType=\"ICSharpCode.Decompiler.Tests.TestCases.PdbGen.ForLoopTests\" name=\"SimplePrintLoopWithCondition\" parameterNames=\"args\" token=\"0x6000002\">\n      <sequencePoints>\n        <entry offset=\"0x0\" startLine=\"17\" startColumn=\"9\" endLine=\"17\" endColumn=\"18\" document=\"1\" />\n        <entry offset=\"0x2\" hidden=\"true\" document=\"1\" />\n        <entry offset=\"0x4\" startLine=\"19\" startColumn=\"5\" endLine=\"19\" endColumn=\"20\" document=\"1\" />\n        <entry offset=\"0x9\" startLine=\"21\" startColumn=\"6\" endLine=\"21\" endColumn=\"33\" document=\"1\" />\n        <entry offset=\"0x11\" startLine=\"17\" startColumn=\"37\" endLine=\"17\" endColumn=\"40\" document=\"1\" />\n        <entry offset=\"0x15\" startLine=\"17\" startColumn=\"20\" endLine=\"17\" endColumn=\"35\" document=\"1\" />\n        <entry offset=\"0x1b\" startLine=\"24\" startColumn=\"3\" endLine=\"24\" endColumn=\"4\" document=\"1\" />\n      </sequencePoints>\n      <scope startOffset=\"0x0\" endOffset=\"0x1c\">\n        <scope startOffset=\"0x0\" endOffset=\"0x1b\">\n          <local name=\"i\" il_index=\"0\" il_start=\"0x0\" il_end=\"0x1b\" attributes=\"0\" />\n        </scope>\n      </scope>\n    </method>\n  </methods>\n  <method-spans>\n    <method declaringType=\"ICSharpCode.Decompiler.Tests.TestCases.PdbGen.ForLoopTests\" methodName=\"SimplePrintLoop\" parameterNames=\"args\" token=\"0x6000001\">\n      <document startLine=\"9\" endLine=\"13\" />\n    </method>\n    <method declaringType=\"ICSharpCode.Decompiler.Tests.TestCases.PdbGen.ForLoopTests\" methodName=\"SimplePrintLoopWithCondition\" parameterNames=\"args\" token=\"0x6000002\">\n      <document startLine=\"17\" endLine=\"24\" />\n    </method>\n  </method-spans>\n</symbols>"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/PdbGen/HelloWorld.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<symbols>\n  <files>\n    <file id=\"1\" name=\"ICSharpCode.Decompiler.Tests.TestCases.PdbGen\\HelloWorld.cs\" language=\"C#\" checksumAlgorithm=\"SHA256\"><![CDATA[using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.PdbGen;\n\npublic class HelloWorld\n{\n\tpublic static void Main(string[] args)\n\t{\n\t\tConsole.ReadKey();\n\t\tConsole.WriteLine(\"Hello World!\");\n\t\tConsole.ReadKey();\n\t}\n}\n]]></file>\n  </files>\n  <methods>\n    <method containingType=\"ICSharpCode.Decompiler.Tests.TestCases.PdbGen.HelloWorld\" name=\"Main\" parameterNames=\"args\" token=\"0x6000001\">\n      <sequencePoints>\n        <entry offset=\"0x0\" startLine=\"9\" startColumn=\"4\" endLine=\"9\" endColumn=\"22\" document=\"1\" />\n        <entry offset=\"0x6\" startLine=\"10\" startColumn=\"4\" endLine=\"10\" endColumn=\"38\" document=\"1\" />\n        <entry offset=\"0x10\" startLine=\"11\" startColumn=\"4\" endLine=\"11\" endColumn=\"22\" document=\"1\" />\n        <entry offset=\"0x16\" startLine=\"12\" startColumn=\"3\" endLine=\"12\" endColumn=\"4\" document=\"1\" />\n      </sequencePoints>\n      <scope startOffset=\"0x0\" endOffset=\"0x17\" />\n    </method>\n  </methods>\n  <method-spans>\n    <method declaringType=\"ICSharpCode.Decompiler.Tests.TestCases.PdbGen.HelloWorld\" methodName=\"Main\" parameterNames=\"args\" token=\"0x6000001\">\n      <document startLine=\"9\" endLine=\"12\" />\n    </method>\n  </method-spans>\n</symbols>"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/PdbGen/LambdaCapturing.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<symbols>\n  <files>\n    <file id=\"1\" name=\"ICSharpCode.Decompiler.Tests.TestCases.PdbGen\\LambdaCapturing.cs\" language=\"C#\" checksumAlgorithm=\"SHA256\"><![CDATA[using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.PdbGen;\n\npublic class LambdaCapturing\n{\n\tpublic static void Main(string[] args)\n\t{\n\t\tint num = 4;\n\t\tint captured = Environment.TickCount + num;\n\t\tTest((int a, int b) => a + b + captured);\n\t}\n\n\tprivate static void Test(Func<int, int, int> p)\n\t{\n\t\tp(1, 2);\n\t}\n}\n]]></file>\n  </files>\n  <methods>\n    <method containingType=\"ICSharpCode.Decompiler.Tests.TestCases.PdbGen.LambdaCapturing\" name=\"Main\" parameterNames=\"args\" token=\"0x6000001\">\n      <sequencePoints>\n        <entry offset=\"0x0\" hidden=\"true\" document=\"1\" />\n        <entry offset=\"0x5\" startLine=\"9\" startColumn=\"13\" endLine=\"9\" endColumn=\"27\" document=\"1\" />\n        <entry offset=\"0x7\" startLine=\"10\" startColumn=\"13\" endLine=\"10\" endColumn=\"58\" document=\"1\" />\n        <entry offset=\"0x14\" startLine=\"11\" startColumn=\"13\" endLine=\"11\" endColumn=\"46\" document=\"1\" />\n        <entry offset=\"0x24\" startLine=\"12\" startColumn=\"9\" endLine=\"12\" endColumn=\"10\" document=\"1\" />\n      </sequencePoints>\n      <scope startOffset=\"0x0\" endOffset=\"0x25\">\n        <local name=\"local\" il_index=\"0\" il_start=\"0x0\" il_end=\"0x25\" attributes=\"0\" />\n      </scope>\n    </method>\n    <method containingType=\"ICSharpCode.Decompiler.Tests.TestCases.PdbGen.LambdaCapturing\" name=\"Test\" parameterNames=\"p\" token=\"0x6000002\">\n      <sequencePoints>\n        <entry offset=\"0x0\" startLine=\"16\" startColumn=\"13\" endLine=\"16\" endColumn=\"21\" document=\"1\" />\n        <entry offset=\"0x9\" startLine=\"17\" startColumn=\"9\" endLine=\"17\" endColumn=\"10\" document=\"1\" />\n      </sequencePoints>\n      <scope startOffset=\"0x0\" endOffset=\"0xa\" />\n    </method>\n    <method containingType=\"ICSharpCode.Decompiler.Tests.TestCases.PdbGen.LambdaCapturing+&lt;&gt;c__DisplayClass0_0\" name=\"&lt;Main&gt;b__0\" parameterNames=\"a, b\" token=\"0x6000005\">\n      <sequencePoints>\n        <entry offset=\"0x0\" startLine=\"11\" startColumn=\"28\" endLine=\"11\" endColumn=\"44\" document=\"1\" />\n      </sequencePoints>\n      <scope startOffset=\"0x0\" endOffset=\"0xb\" />\n    </method>\n  </methods>\n  <method-spans>\n    <method declaringType=\"ICSharpCode.Decompiler.Tests.TestCases.PdbGen.LambdaCapturing\" methodName=\"Main\" parameterNames=\"args\" token=\"0x6000001\">\n      <document startLine=\"9\" endLine=\"12\" />\n    </method>\n    <method declaringType=\"ICSharpCode.Decompiler.Tests.TestCases.PdbGen.LambdaCapturing\" methodName=\"Test\" parameterNames=\"p\" token=\"0x6000002\">\n      <document startLine=\"16\" endLine=\"17\" />\n    </method>\n    <method declaringType=\"ICSharpCode.Decompiler.Tests.TestCases.PdbGen.LambdaCapturing+&lt;&gt;c__DisplayClass0_0\" methodName=\"&lt;Main&gt;b__0\" parameterNames=\"a, b\" token=\"0x6000005\">\n      <document startLine=\"11\" endLine=\"11\" />\n    </method>\n  </method-spans>\n</symbols>"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/PdbGen/Members.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<symbols>\n  <files>\n    <file id=\"1\" name=\"-\\C.cs\" language=\"C#\" checksumAlgorithm=\"SHA256\">\n\t<![CDATA[using System;\n\ninternal class C : IDisposable\n{\n\tprivate int ExpressionProperty => 42;\n\n    private int Property \n    {\n        get\n\t\t{\n\t\t\treturn 0;\n\t\t}\n        set\n\t\t{\n\t\t}\n    }\n\n    private C this[int index] => null;\n\n    private C this[string s]\n    {\n        get\n\t\t{\n\t\t\treturn null;\n\t\t}\n        set\n\t\t{\n\t\t}\n    }\n\n    public event Action Event\n    {\n        add\n        {\n        }\n        remove\n        {\n        }\n    }\n\n    public static implicit operator C(int i)\n    {\n        return null;\n    }\n\n    static C()\n    {\n    }\n\n    public C()\n    {\n\t\tConsole.WriteLine();\n    }\n\n    ~C()\n    {\n    }\n\n    void IDisposable.Dispose()\n    {\n    }\n\n    private static void Main()\n    {\n        C c = new C();\n\n        c.Event += delegate\n\t\t{\n\t\t};\n        _ = c.Property;\n        _ = c.ExpressionProperty;\n        _ = c[0];\n        _ = c[\"\"];\n\n        _ = (C)1;\n\n        Local();\n\n        static void Local()\n        {\n\t\t\tConsole.WriteLine();\n        }\n    }\n}\n]]></file>\n  </files>\n  <methods>\n  </methods>\n  <method-spans>\n  </method-spans>\n</symbols>"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/PdbGen/ProgressReporting.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<symbols>\n  <files>\n    <file id=\"1\" name=\"ICSharpCode.Decompiler.Tests.TestCases.PdbGen\\ProgressReporting.cs\" language=\"C#\" checksumAlgorithm=\"SHA256\">\n\t<![CDATA[using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.PdbGen;\n\npublic class ProgressReporting\n{\n\tpublic static void Main(string[] args)\n\t{\n\t\tConsole.ReadKey();\n\t\tConsole.WriteLine(\"Hello World!\");\n\t\tConsole.ReadKey();\n\t}\n}\n\npublic class Class1\n{\n\tpublic static void Test()\n\t{\n\t\tConsole.WriteLine(\"Class1\");\n\t}\n}\n\npublic class Class2\n{\n\tpublic static void Test()\n\t{\n\t\tConsole.WriteLine(\"Class2\");\n\t}\n}\n\npublic class Class3\n{\n\tpublic static void Test()\n\t{\n\t\tConsole.WriteLine(\"Class3\");\n\t}\n}\n]]></file>\n  </files>\n</symbols>"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/.gitignore",
    "content": "/*.res\n/*.dll\n/*.exe\n/*.pdb\n/*.xml"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/AnonymousTypes.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class AnonymousTypes\n\t{\n\t\tprivate void SimpleTypes()\n\t\t{\n\t\t\tvar value = new { };\n\t\t\tvar anon = new {\n\t\t\t\tX = 5\n\t\t\t};\n\t\t\tvar anon2 = new {\n\t\t\t\tX = 5,\n\t\t\t\tY = 10\n\t\t\t};\n\n\t\t\tConsole.WriteLine(value);\n\t\t\tConsole.WriteLine(anon.X);\n\t\t\tConsole.WriteLine(anon2.Y + anon2.X);\n\t\t}\n\n\t\tprivate void SimpleArray()\n\t\t{\n#if ROSLYN && OPT\n\t\t\tvar obj = new[] {\n#else\n\t\t\tvar array = new[] {\n#endif\n\t\t\t\tnew {\n\t\t\t\t\tX = 5,\n\t\t\t\t\tY = 2,\n\t\t\t\t\tZ = -1\n\t\t\t\t},\n\t\t\t\tnew {\n\t\t\t\t\tX = 3,\n\t\t\t\t\tY = 6,\n\t\t\t\t\tZ = -6\n\t\t\t\t}\n\t\t\t};\n\n#if ROSLYN && OPT\n\t\t\tConsole.WriteLine(obj[0].X);\n\t\t\tConsole.WriteLine(obj[1].X);\n#else\n\t\t\tConsole.WriteLine(array[0].X);\n\t\t\tConsole.WriteLine(array[1].X);\n#endif\n\t\t}\n#if !MCS\n\t\tprivate void JaggedArray()\n\t\t{\n\t\t\tvar array = new[] {\n\t\t\t\tnew {\n\t\t\t\t\tX = 5,\n\t\t\t\t\tY = 2,\n\t\t\t\t\tZ = -1\n\t\t\t\t},\n\t\t\t\tnew {\n\t\t\t\t\tX = 3,\n\t\t\t\t\tY = 6,\n\t\t\t\t\tZ = -6\n\t\t\t\t}\n\t\t\t};\n#if ROSLYN && OPT\n\t\t\tvar obj = new[] { array, array };\n\n\t\t\tConsole.WriteLine(array[0].X);\n\t\t\tConsole.WriteLine(array[1].X);\n\t\t\tConsole.WriteLine(obj.Length);\n#else\n\t\t\tvar array2 = new[] { array, array };\n\n\t\t\tConsole.WriteLine(array[0].X);\n\t\t\tConsole.WriteLine(array[1].X);\n\t\t\tConsole.WriteLine(array2.Length);\n#endif\n\t\t}\n#endif\n#if CS70\n\t\tprivate void AnonymousTypeOutVar()\n\t\t{\n\t\t\tInlineVarDecl(out var v, new {\n\t\t\t\tX = 1,\n\t\t\t\tY = 2\n\t\t\t});\n\t\t\tConsole.WriteLine(v.X);\n\t\t}\n#endif\n\n\t\tprivate static void InlineVarDecl<T>(out T v, T init)\n\t\t{\n\t\t\tv = init;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/AssemblyCustomAttributes.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\n[assembly: CLSCompliant(false)]\n//[module: CLSCompliant(false)]"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Async.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#pragma warning disable 1998\nusing System;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class Async\n\t{\n\t\tprivate int memberField;\n\n\t\tprivate static bool True()\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic async void SimpleVoidMethod()\n\t\t{\n\t\t\tConsole.WriteLine(\"Before\");\n\t\t\tawait Task.Delay(TimeSpan.FromSeconds(1.0));\n\t\t\tConsole.WriteLine(\"After\");\n\t\t}\n\n\t\tpublic async void VoidMethodWithoutAwait()\n\t\t{\n\t\t\tConsole.WriteLine(\"No Await\");\n\t\t}\n\n\t\tpublic async void EmptyVoidMethod()\n\t\t{\n\t\t}\n\n\t\tpublic async void AwaitYield()\n\t\t{\n\t\t\tawait Task.Yield();\n\t\t}\n\n\t\tpublic async void AwaitDefaultYieldAwaitable()\n\t\t{\n\t\t\tawait default(YieldAwaitable);\n\t\t}\n\n\t\tpublic async void AwaitDefaultHopToThreadPool()\n\t\t{\n\t\t\t// unlike YieldAwaitable which implements ICriticalNotifyCompletion,\n\t\t\t// the HopToThreadPoolAwaitable struct only implements\n\t\t\t// INotifyCompletion, so this results in different codegen\n\t\t\tawait default(HopToThreadPoolAwaitable);\n\t\t}\n\n\t\tpublic async Task SimpleVoidTaskMethod()\n\t\t{\n\t\t\tConsole.WriteLine(\"Before\");\n\t\t\tawait Task.Delay(TimeSpan.FromSeconds(1.0));\n\t\t\tConsole.WriteLine(\"After\");\n\t\t}\n\n\t\tpublic async Task TaskMethodWithoutAwait()\n\t\t{\n\t\t\tConsole.WriteLine(\"No Await\");\n\t\t}\n\n\t\tpublic async Task CapturingThis()\n\t\t{\n\t\t\tawait Task.Delay(memberField);\n\t\t}\n\n\t\tpublic async Task CapturingThisWithoutAwait()\n\t\t{\n\t\t\tConsole.WriteLine(memberField);\n\t\t}\n\n\t\tpublic async Task<bool> SimpleBoolTaskMethod()\n\t\t{\n\t\t\tConsole.WriteLine(\"Before\");\n\t\t\tawait Task.Delay(TimeSpan.FromSeconds(1.0));\n\t\t\tConsole.WriteLine(\"After\");\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic async void TwoAwaitsWithDifferentAwaiterTypes()\n\t\t{\n\t\t\tConsole.WriteLine(\"Before\");\n\t\t\tif (await SimpleBoolTaskMethod())\n\t\t\t{\n\t\t\t\tawait Task.Delay(TimeSpan.FromSeconds(1.0));\n\t\t\t}\n\t\t\tConsole.WriteLine(\"After\");\n\t\t}\n\n\t\tpublic async void AwaitInLoopCondition()\n\t\t{\n\t\t\twhile (await SimpleBoolTaskMethod())\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Body\");\n\t\t\t}\n\t\t}\n\n#if CS60\n\t\tpublic async Task AwaitInCatch(bool b, Task<int> task1, Task<int> task2)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Start try\");\n\t\t\t\tawait task1;\n\t\t\t\tConsole.WriteLine(\"End try\");\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\tif (!b)\n\t\t\t\t{\n\t\t\t\t\tawait task2;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"No await\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task AwaitInFinally(bool b, Task<int> task1, Task<int> task2)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Start try\");\n\t\t\t\tawait task1;\n\t\t\t\tConsole.WriteLine(\"End try\");\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tif (!b)\n\t\t\t\t{\n\t\t\t\t\tawait task2;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"No await\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task AnonymousThrow()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tawait Task.Delay(0);\n\t\t\t}\n\t\t\tcatch\n\t\t\t{\n\t\t\t\tawait Task.Delay(0);\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task DeclaredException()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tawait Task.Delay(0);\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\tawait Task.Delay(0);\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task RethrowDeclared()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tawait Task.Delay(0);\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tawait Task.Delay(0);\n#pragma warning disable CA2200 // Rethrow to preserve stack details\n\t\t\t\tthrow ex;\n#pragma warning restore CA2200 // Rethrow to preserve stack details\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task RethrowDeclaredWithFilter()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tawait Task.Delay(0);\n\t\t\t}\n\t\t\tcatch (Exception ex) when (ex.GetType().FullName.Contains(\"asdf\"))\n\t\t\t{\n\t\t\t\tawait Task.Delay(0);\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task ComplexCatchBlock()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tawait Task.Delay(0);\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tif (ex.GetHashCode() != 0)\n\t\t\t\t{\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t\tawait Task.Delay(0);\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task ComplexCatchBlockWithFilter()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tawait Task.Delay(0);\n\t\t\t}\n\t\t\tcatch (Exception ex) when (ex.GetType().FullName.Contains(\"asdf\"))\n\t\t\t{\n\t\t\t\tif (ex.GetHashCode() != 0)\n\t\t\t\t{\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t\tawait Task.Delay(0);\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task LoadsToCatch(int i)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tthrow null;\n\t\t\t}\n\t\t\tcatch (Exception ex) when (i == 0)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"First!\");\n\t\t\t\tif (i == 1)\n\t\t\t\t{\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t\tawait Task.Yield();\n\t\t\t\tConsole.WriteLine(ex.StackTrace);\n\t\t\t}\n\t\t\tcatch (Exception ex2) when (True())\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Second!\");\n\t\t\t\tif (i == 1)\n\t\t\t\t{\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t\tawait Task.Yield();\n\t\t\t\tConsole.WriteLine(ex2.StackTrace);\n\t\t\t}\n\t\t\tcatch (Exception ex3)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Third!\");\n\t\t\t\tif (i == 1)\n\t\t\t\t{\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t\tawait Task.Yield();\n\t\t\t\tConsole.WriteLine(ex3.StackTrace);\n\t\t\t}\n\t\t\tcatch when (i == 0)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Fourth!\");\n\t\t\t\tif (i == 1)\n\t\t\t\t{\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t\tawait Task.Yield();\n\t\t\t}\n\t\t\tcatch when (True())\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Fifth!\");\n\t\t\t\tif (i == 1)\n\t\t\t\t{\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t\tawait Task.Yield();\n\t\t\t}\n\t\t\tcatch\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Sixth!\");\n\t\t\t\tif (i == 1)\n\t\t\t\t{\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t\tawait Task.Yield();\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task Issue2366a()\n\t\t{\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tawait Task.CompletedTask;\n\t\t\t\t}\n\t\t\t\tcatch\n\t\t\t\t{\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task Issue2366b()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tawait Task.CompletedTask;\n\t\t\t}\n\t\t\tcatch (NullReferenceException)\n\t\t\t{\n\t\t\t\tawait Task.CompletedTask;\n\t\t\t}\n\t\t\tcatch (InvalidOperationException)\n\t\t\t{\n\t\t\t\tawait Task.CompletedTask;\n\t\t\t}\n\t\t\tcatch (ArgumentException)\n\t\t\t{\n\t\t\t\tawait Task.CompletedTask;\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task<object> Issue2436()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tcatch (Exception result)\n\t\t\t{\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tawait Task.CompletedTask;\n\t\t\t}\n\t\t\treturn new object();\n\t\t}\n#endif\n\n\t\tpublic static async Task<int> GetIntegerSumAsync(IEnumerable<int> items)\n\t\t{\n\t\t\tawait Task.Delay(100);\n\t\t\tint num = 0;\n\t\t\tforeach (int item in items)\n\t\t\t{\n\t\t\t\tnum += item;\n\t\t\t}\n\t\t\treturn num;\n\t\t}\n\n\t\tpublic static Func<Task<int>> AsyncLambda()\n\t\t{\n\t\t\treturn async () => await GetIntegerSumAsync(new int[3] { 1, 2, 3 });\n\t\t}\n\n\t\tpublic static Func<Task<int>> AsyncDelegate()\n\t\t{\n\t\t\treturn async delegate {\n\t\t\t\tawait Task.Delay(10);\n\t\t\t\treturn 2;\n\t\t\t};\n\t\t}\n\n\t\tpublic static async Task AlwaysThrow()\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\n\t\tpublic static async Task InfiniteLoop()\n\t\t{\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic static async Task InfiniteLoopWithAwait()\n\t\t{\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tawait Task.Delay(10);\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task AsyncWithLocalVar()\n\t\t{\n\t\t\tobject a = new object();\n#if CS70\n\t\t\t(object, string) tuple = (new object(), \"abc\");\n#endif\n\t\t\tawait UseObj(a);\n\t\t\tawait UseObj(a);\n#if CS70\n\t\t\tawait UseObj(tuple);\n#endif\n\t\t}\n\n\t\tpublic static async Task UseObj(object a)\n\t\t{\n\t\t}\n\n#if CS70\n\t\tpublic static async Task<int> AsyncLocalFunctions()\n\t\t{\n\t\t\treturn await Nested(1) + await Nested(2);\n\n#if CS80\n\t\t\tstatic async Task<int> Nested(int i)\n#else\n\t\t\tasync Task<int> Nested(int i)\n#endif\n\t\t\t{\n\t\t\t\tawait Task.Delay(i);\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\n\tpublic struct AsyncInStruct\n\t{\n\t\tprivate int i;\n\n\t\tpublic async Task<int> Test(AsyncInStruct xx)\n\t\t{\n\t\t\txx.i++;\n\t\t\ti++;\n\t\t\tawait Task.Yield();\n\t\t\treturn i + xx.i;\n\t\t}\n\t}\n\n\tpublic struct HopToThreadPoolAwaitable : INotifyCompletion\n\t{\n\t\tpublic bool IsCompleted { get; set; }\n\n\t\tpublic HopToThreadPoolAwaitable GetAwaiter()\n\t\t{\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic void OnCompleted(Action continuation)\n\t\t{\n\t\t\tTask.Run(continuation);\n\t\t}\n\n\t\tpublic void GetResult()\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncForeach.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class AsyncForeach\n\t{\n\t\tpublic async Task<int> SumIntegers(IAsyncEnumerable<int> items, CancellationToken token)\n\t\t{\n\t\t\tint sum = 0;\n\t\t\tawait foreach (int item in items.WithCancellation(token))\n\t\t\t{\n\t\t\t\tif (!token.IsCancellationRequested)\n\t\t\t\t{\n\t\t\t\t\tsum += item;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn sum;\n\t\t}\n\n\t\tpublic async Task<int> MaxInteger(IAsyncEnumerable<int> items)\n\t\t{\n\t\t\tint max = int.MinValue;\n\t\t\tawait foreach (int item in items)\n\t\t\t{\n\t\t\t\tif (item > max)\n\t\t\t\t{\n\t\t\t\t\tmax = item;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn max;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncMain.cs",
    "content": "using System;\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class AsyncMain\n\t{\n\t\tpublic static async Task Main(string[] args)\n\t\t{\n\t\t\tawait Task.Delay(1000);\n\t\t\tConsole.WriteLine(\"Hello Wolrd!\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncStreams.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class AsyncStreams\n\t{\n\t\tpublic static async IAsyncEnumerable<int> CountTo(int until)\n\t\t{\n\t\t\tfor (int i = 0; i < until; i++)\n\t\t\t{\n\t\t\t\tyield return i;\n\t\t\t\tawait Task.Delay(10);\n\t\t\t}\n\t\t}\n\n\t\tpublic static async IAsyncEnumerable<int> AlwaysThrow()\n\t\t{\n\t\t\tthrow null;\n\t\t\tyield break;\n\t\t}\n\n\t\tpublic static async IAsyncEnumerator<int> InfiniteLoop()\n\t\t{\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t}\n\t\t\tyield break;\n\t\t}\n\n\t\tpublic static async IAsyncEnumerable<int> InfiniteLoopWithAwait()\n\t\t{\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tawait Task.Delay(10);\n\t\t\t}\n\t\t\tyield break;\n\t\t}\n\n\t\tpublic async IAsyncEnumerable<int> AwaitInFinally()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"try\");\n\t\t\t\tyield return 1;\n\t\t\t\tConsole.WriteLine(\"end try\");\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"finally\");\n\t\t\t\tawait Task.Yield();\n\t\t\t\tConsole.WriteLine(\"end finally\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static async IAsyncEnumerable<int> SimpleCancellation([EnumeratorCancellation] CancellationToken cancellationToken)\n\t\t{\n\t\t\tyield return 1;\n\t\t\tawait Task.Delay(100, cancellationToken);\n\t\t\tyield return 2;\n\t\t}\n\t}\n\n\tpublic struct TestStruct\n\t{\n\t\tprivate int i;\n\n\t\tpublic async IAsyncEnumerable<int> AwaitInStruct(TestStruct xx)\n\t\t{\n\t\t\txx.i++;\n\t\t\ti++;\n\t\t\tawait Task.Yield();\n\t\t\tyield return i;\n\t\t\tyield return xx.i;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncUsing.cs",
    "content": "using System;\nusing System.Runtime.InteropServices;\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class AsyncUsing\n\t{\n\t\tinternal class AsyncDisposableClass : IAsyncDisposable\n\t\t{\n\t\t\tpublic ValueTask DisposeAsync()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n\n\t\t[StructLayout(LayoutKind.Sequential, Size = 1)]\n\t\tinternal struct AsyncDisposableStruct : IAsyncDisposable\n\t\t{\n\t\t\tpublic ValueTask DisposeAsync()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n\n\t\tpublic static async void TestAsyncUsing(IAsyncDisposable disposable)\n\t\t{\n\t\t\tawait using (disposable)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Hello\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static async void TestAsyncUsingClass()\n\t\t{\n\t\t\tawait using (AsyncDisposableClass test = new AsyncDisposableClass())\n\t\t\t{\n\t\t\t\tUse(test);\n\t\t\t}\n\t\t}\n\n\t\tpublic static async void TestAsyncUsingStruct()\n\t\t{\n\t\t\tawait using (AsyncDisposableStruct asyncDisposableStruct = default(AsyncDisposableStruct))\n\t\t\t{\n\t\t\t\tUse(asyncDisposableStruct);\n\t\t\t}\n\t\t}\n\n\t\tpublic static async void TestAsyncUsingNullableStruct()\n\t\t{\n\t\t\tawait using (AsyncDisposableStruct? asyncDisposableStruct = new AsyncDisposableStruct?(default(AsyncDisposableStruct)))\n\t\t\t{\n\t\t\t\tUse(asyncDisposableStruct);\n\t\t\t}\n\t\t}\n\n\t\tprivate static void Use(IAsyncDisposable test)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/AutoProperties.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class AutoProperties\n\t{\n#if CS110\n\t\tpublic required int RequiredField;\n#endif\n\t\tpublic int A { get; } = 1;\n\n\t\tpublic int B { get; set; } = 2;\n\n\t\tpublic static int C { get; } = 3;\n\n\t\tpublic static int D { get; set; } = 4;\n\n\t\tpublic string value { get; set; }\n\n\t\t[Obsolete(\"Property\")]\n#if CS70\n\t\t[field: Obsolete(\"Field\")]\n#endif\n\t\tpublic int PropertyWithAttributeOnBackingField { get; set; }\n\n\t\tpublic int issue1319 { get; }\n\n#if CS110\n\t\tpublic required int RequiredProperty { get; set; }\n#endif\n\n\t\tpublic AutoProperties(int issue1319)\n\t\t{\n\t\t\tthis.issue1319 = issue1319;\n#if CS110\n\t\t\tRequiredProperty = 42;\n\t\t\tRequiredField = 42;\n#endif\n\t\t}\n\t}\n#if !NET70\n\t[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]\n\tinternal sealed class RequiredMemberAttribute : Attribute\n\t{\n\t}\n#endif\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS72_PrivateProtected.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class CS72_PrivateProtected\n\t{\n\t\tprivate protected int Property { get; }\n\n\t\tprivate protected void Method()\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS73_StackAllocInitializers.cs",
    "content": "#pragma warning disable format\n// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Runtime.InteropServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class CS73_StackAllocInitializers\n\t{\n#if CS120\n\t\t[StructLayout(LayoutKind.Sequential, Size = 5)]\n\t\tprivate struct StructWithSize5(byte a, byte b, byte c, byte d, byte e)\n\t\t{\n\t\t\tpublic byte a = a;\n\t\t\tpublic byte b = b;\n\t\t\tpublic byte c = c;\n\t\t\tpublic byte d = d;\n\t\t\tpublic byte e = e;\n\t\t}\n#else\n\t\t[StructLayout(LayoutKind.Sequential, Size = 5)]\n\t\tprivate struct StructWithSize5\n\t\t{\n\t\t\tpublic byte a;\n\t\t\tpublic byte b;\n\t\t\tpublic byte c;\n\t\t\tpublic byte d;\n\t\t\tpublic byte e;\n\n\t\t\tpublic StructWithSize5(byte a, byte b, byte c, byte d, byte e)\n\t\t\t{\n\t\t\t\tthis.a = a;\n\t\t\t\tthis.b = b;\n\t\t\t\tthis.c = c;\n\t\t\t\tthis.d = d;\n\t\t\t\tthis.e = e;\n\t\t\t}\n\t\t}\n#endif\n\n#if CS80\n\t\tprivate class NestedContext1\n\t\t{\n\t\t\tpublic NestedContext1(object result)\n\t\t\t{\n\t\t\t}\n\n\t\t\tpublic NestedContext1()\n\t\t\t\t: this(UseNested(GetInt(), stackalloc int[2] {\n\t\t\t\t\tGetInt(),\n\t\t\t\t\tGetInt()\n\t\t\t\t}))\n\t\t\t{\n\t\t\t}\n\t\t}\n\t\t\n\t\tpublic static object UseNested(object a, Span<int> span)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static int GetInt()\n\t\t{\n\t\t\treturn 42;\n\t\t}\n#endif\n\n\t\tpublic unsafe string SimpleStackAllocStruct1()\n\t\t{\n\t\t\tStructWithSize5* ptr = stackalloc StructWithSize5[4] {\n\t\t\t\tnew StructWithSize5(1, 2, 3, 4, 5),\n\t\t\t\tnew StructWithSize5(11, 22, 33, 44, 55),\n\t\t\t\tnew StructWithSize5(1, 4, 8, 6, 2),\n\t\t\t\tnew StructWithSize5(12, 23, 34, 45, 56)\n\t\t\t};\n\t\t\tConsole.WriteLine(*ptr);\n\t\t\treturn UsePointer((byte*)ptr);\n\t\t}\n\n\t\tpublic unsafe string SimpleStackAllocBool()\n\t\t{\n\t\t\tbool* ptr = stackalloc bool[4] { false, true, false, true };\n\t\t\tConsole.WriteLine(*ptr);\n\t\t\treturn UsePointer((byte*)ptr);\n\t\t}\n\n\t\tpublic unsafe string DoNotInlineTest()\n\t\t{\n\t\t\tbool* ptr = stackalloc bool[4] { false, true, false, true };\n\t\t\treturn UsePointer((byte*)ptr);\n\t\t}\n\n\t\tpublic unsafe string SimpleStackAllocByte()\n\t\t{\n\t\t\tbyte* ptr = stackalloc byte[2] { 0, 1 };\n\t\t\tConsole.WriteLine(*ptr);\n\t\t\treturn UsePointer(ptr);\n\t\t}\n\n\t\tpublic unsafe string SimpleStackAllocPrimesAsBytes()\n\t\t{\n\t\t\tbyte* ptr = stackalloc byte[55] {\n\t\t\t\t1, 2, 3, 5, 7, 11, 13, 17, 19, 23,\n\t\t\t\t29, 31, 37, 41, 43, 47, 53, 59, 61, 67,\n\t\t\t\t71, 73, 79, 83, 89, 97, 101, 103, 107, 109,\n\t\t\t\t113, 127, 131, 137, 139, 149, 151, 157, 163, 167,\n\t\t\t\t173, 179, 181, 191, 193, 197, 199, 211, 223, 227,\n\t\t\t\t229, 233, 239, 241, 251\n\t\t\t};\n\t\t\tConsole.WriteLine(*ptr);\n\t\t\treturn UsePointer(ptr);\n\t\t}\n\n\t\tpublic unsafe string SimpleStackAllocChar()\n\t\t{\n\t\t\tchar* ptr = stackalloc char[4] { '1', '2', '3', '4' };\n\t\t\tConsole.WriteLine(*ptr);\n\t\t\treturn UsePointer((byte*)ptr);\n\t\t}\n\n\t\tpublic unsafe string SimpleStackAllocCharAlphabet()\n\t\t{\n\t\t\tchar* ptr = stackalloc char[26] {\n\t\t\t\t'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',\n\t\t\t\t'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',\n\t\t\t\t'U', 'V', 'W', 'X', 'Y', 'Z'\n\t\t\t};\n\t\t\tConsole.WriteLine(*ptr);\n\t\t\treturn UsePointer((byte*)ptr);\n\t\t}\n\n\t\tpublic unsafe string SimpleStackAllocSByte()\n\t\t{\n\t\t\tsbyte* ptr = stackalloc sbyte[3] { 1, 2, 3 };\n\t\t\tConsole.WriteLine(*ptr);\n\t\t\treturn UsePointer((byte*)ptr);\n\t\t}\n\n\t\tpublic unsafe string SimpleStackAllocInt16()\n\t\t{\n\t\t\tshort* ptr = stackalloc short[3] { 1, 2, 3 };\n\t\t\tConsole.WriteLine(*ptr);\n\t\t\treturn UsePointer((byte*)ptr);\n\t\t}\n\n\t\tpublic unsafe string SimpleStackAllocUInt16()\n\t\t{\n\t\t\tushort* ptr = stackalloc ushort[3] { 1, 2, 3 };\n\t\t\tConsole.WriteLine(*ptr);\n\t\t\treturn UsePointer((byte*)ptr);\n\t\t}\n\n\t\tpublic unsafe string SimpleStackAllocInt32()\n\t\t{\n\t\t\tint* ptr = stackalloc int[3] { 1, 2, 3 };\n\t\t\tConsole.WriteLine(*ptr);\n\t\t\treturn UsePointer((byte*)ptr);\n\t\t}\n\n\t\tpublic unsafe string SimpleStackAllocInt32(int a, int b, int c)\n\t\t{\n\t\t\tint* ptr = stackalloc int[6] { 1, a, 2, b, 3, c };\n\t\t\tConsole.WriteLine(*ptr);\n\t\t\treturn UsePointer((byte*)ptr);\n\t\t}\n\n\t\tpublic unsafe string SimpleStackAllocInt32Fibonacci()\n\t\t{\n\t\t\tint* ptr = stackalloc int[17] {\n\t\t\t\t1, 1, 2, 3, 5, 8, 13, 21, 34, 55,\n\t\t\t\t89, 144, 233, 377, 610, 987, 1597\n\t\t\t};\n\t\t\tConsole.WriteLine(*ptr);\n\t\t\treturn UsePointer((byte*)ptr);\n\t\t}\n\n\t\tpublic unsafe string SimpleStackAllocUInt32()\n\t\t{\n\t\t\tuint* ptr = stackalloc uint[3] { 1u, 2u, 3u };\n\t\t\tConsole.WriteLine(*ptr);\n\t\t\treturn UsePointer((byte*)ptr);\n\t\t}\n\n\t\tpublic unsafe string SimpleStackAllocInt64()\n\t\t{\n\t\t\tlong* ptr = stackalloc long[3] { 1L, 2L, 3L };\n\t\t\tConsole.WriteLine(*ptr);\n\t\t\treturn UsePointer((byte*)ptr);\n\t\t}\n\n\t\tpublic unsafe string SimpleStackAllocUInt64()\n\t\t{\n\t\t\tulong* ptr = stackalloc ulong[3] { 1uL, 2uL, 3uL };\n\t\t\tConsole.WriteLine(*ptr);\n\t\t\treturn UsePointer((byte*)ptr);\n\t\t}\n\n\t\tpublic unsafe string SimpleStackAllocInt32NonConstant(int a, int b, int c)\n\t\t{\n\t\t\tint* ptr = stackalloc int[6] { 0, 1, 0, a, b, c };\n\t\t\tConsole.WriteLine(*ptr);\n\t\t\treturn UsePointer((byte*)ptr);\n\t\t}\n\n\t\tpublic unsafe string NotAnInitializer(int a, int b, int c)\n\t\t{\n\t\t\tint* ptr = stackalloc int[6];\n\t\t\tptr[1] = a;\n\t\t\tptr[3] = b;\n\t\t\tptr[5] = c;\n\t\t\tConsole.WriteLine(*ptr);\n\t\t\treturn UsePointer((byte*)ptr);\n\t\t}\n\n\t\tpublic unsafe string NegativeOffsets(int a, int b, int c)\n\t\t{\n#if OPT\n\t\t\tbyte* num = stackalloc byte[12];\n\t\t\t*(int*)num = 1;\n\t\t\t*((int*)num - 1) = 2;\n\t\t\t*((int*)num - 2) = 3;\n\t\t\tint* ptr = (int*)num;\n\t\t\tConsole.WriteLine(*ptr);\n\t\t\treturn UsePointer((byte*)ptr);\n#else\n\t\t\tbyte* ptr = stackalloc byte[12];\n\t\t\t*(int*)ptr = 1;\n\t\t\t*((int*)ptr - 1) = 2;\n\t\t\t*((int*)ptr - 2) = 3;\n\t\t\tint* ptr2 = (int*)ptr;\n\t\t\tConsole.WriteLine(*ptr2);\n\t\t\treturn UsePointer((byte*)ptr2);\n#endif\n\t\t}\n\n\t\tpublic unsafe string UsePointer(byte* ptr)\n\t\t{\n\t\t\treturn ptr->ToString();\n\t\t}\n\n\t\tpublic string GetSpan()\n\t\t{\n\t\t\tSpan<int> span = stackalloc int[GetSize()];\n\t\t\treturn UseSpan(span);\n\t\t}\n\n\t\tpublic string GetSpan2()\n\t\t{\n\t\t\tSpan<int> span = stackalloc int[4] { 1, 2, 3, 4 };\n\t\t\treturn UseSpan(span);\n\t\t}\n\n\t\tpublic string GetSpan3()\n\t\t{\n\t\t\tSpan<decimal> span = stackalloc decimal[GetSize()];\n\t\t\treturn UseSpan(span);\n\t\t}\n\n\t\tpublic string GetSpan4()\n\t\t{\n\t\t\tSpan<decimal> span = stackalloc decimal[4] { 1m, 2m, 3m, 4m };\n\t\t\treturn UseSpan(span);\n\t\t}\n\n\t\tpublic void Issue2103a()\n\t\t{\n\t\t\tSpan<byte> span = stackalloc byte[3] { 1, 2, 3 };\n\t\t\tConsole.WriteLine(span[2] + span[0]);\n\t\t}\n\n\t\tpublic void Issue2103b()\n\t\t{\n\t\t\tSpan<byte> span = stackalloc byte[3];\n\t\t\tConsole.WriteLine(span[0] + span[1]);\n\t\t}\n\n\t\tpublic void Issue2103c()\n\t\t{\n\t\t\tConsole.WriteLine((stackalloc byte[3] { 1, 2, 3 })[2]);\n\t\t}\n\n\t\tpublic void Issue2103d()\n\t\t{\n\t\t\tConsole.WriteLine((stackalloc byte[3])[1]);\n\t\t}\n\n\t\tpublic string UseSpan(Span<int> span)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tpublic string UseSpan(Span<decimal> span)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tpublic int GetSize()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/CS9_ExtensionGetEnumerator.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class CS9_ExtensionGetEnumerator\n\t{\n\t\tpublic class NonGeneric\n\t\t{\n\t\t}\n\n\t\tpublic class Generic<T>\n\t\t{\n\t\t}\n\n\t\tpublic void Test(NonGeneric c)\n\t\t{\n\t\t\tforeach (object item in c)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(item);\n\t\t\t}\n\t\t}\n\n\t\tpublic void Test(Generic<int> c)\n\t\t{\n\t\t\tforeach (int item in c)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(item);\n\t\t\t}\n\t\t}\n#if !NET40\n\t\tpublic async void TestAsync(Generic<int> c)\n\t\t{\n\t\t\tawait foreach (int item in c)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(item);\n\t\t\t}\n\t\t}\n#endif\n\t}\n\n\tpublic static class CS9_ExtensionGetEnumerator_Ext\n\t{\n\t\tpublic static IEnumerator GetEnumerator(this CS9_ExtensionGetEnumerator.NonGeneric c)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static IEnumerator<T> GetEnumerator<T>(this CS9_ExtensionGetEnumerator.Generic<T> c)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n#if !NET40\n\t\tpublic static IAsyncEnumerator<T> GetAsyncEnumerator<T>(this CS9_ExtensionGetEnumerator.Generic<T> c)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n#endif\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/CheckedUnchecked.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class Box<T>\n\t{\n\t\tpublic readonly T Value;\n\t}\n\n\tpublic class CheckedUnchecked\n\t{\n\t\tpublic int Operators(int a, int b)\n\t\t{\n\t\t\tint num = checked(a + b);\n\t\t\tint num2 = a + b;\n\t\t\tint num3 = checked(a - b);\n\t\t\tint num4 = a - b;\n\t\t\tint num5 = checked(a * b);\n\t\t\tint num6 = a * b;\n\t\t\tint num7 = a / b;\n\t\t\tint num8 = a % b;\n\t\t\t// The division operators / and % only exist in one form (checked vs. unchecked doesn't matter for them)\n\t\t\treturn num * num2 * num3 * num4 * num5 * num6 * num7 * num8;\n\t\t}\n\n\t\tpublic int Cast(int a)\n\t\t{\n\t\t\tshort num = checked((short)a);\n\t\t\tshort num2 = (short)a;\n\t\t\tbyte b = checked((byte)a);\n\t\t\tbyte b2 = (byte)a;\n\t\t\treturn num * num2 * b * b2;\n\t\t}\n\n\t\tpublic void ForWithCheckedIteratorAndUncheckedBody(int n)\n\t\t{\n\t\t\tchecked\n\t\t\t{\n\t\t\t\tfor (int i = n + 1; i < n + 1; i++)\n\t\t\t\t{\n\t\t\t\t\tn = unchecked(i * i);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic void ForWithCheckedInitializerAndUncheckedIterator(int n)\n\t\t{\n\t\t\tint num = n;\n\t\t\tfor (num = checked(num - 10); num < n; num++)\n\t\t\t{\n\t\t\t\tn--;\n\t\t\t}\n\t\t}\n\t\tpublic void ObjectCreationInitializerChecked()\n\t\t{\n\t\t\tTestHelp(new {\n\t\t\t\tx = 0,\n\t\t\t\tl = 0\n\t\t\t}, n => checked(new {\n\t\t\t\tx = n.x + 1,\n\t\t\t\tl = n.l + 1\n\t\t\t}));\n\t\t}\n\n\t\tpublic void ObjectCreationWithOneFieldChecked()\n\t\t{\n\t\t\tTestHelp(new {\n\t\t\t\tx = 0,\n\t\t\t\tl = 0\n\t\t\t}, n => new {\n\t\t\t\tx = checked(n.x + 1),\n\t\t\t\tl = n.l + 1\n\t\t\t});\n\t\t}\n\n\t\tpublic void ArrayInitializerChecked()\n\t\t{\n\t\t\tTestHelp(new int[2] { 1, 2 }, (int[] n) => checked(new int[2] {\n\t\t\t\tn[0] + 1,\n\t\t\t\tn[1] + 1\n\t\t\t}));\n\t\t}\n\n\t\tpublic T TestHelp<T>(T t, Func<T, T> f)\n\t\t{\n\t\t\treturn f(t);\n\t\t}\n\n\t\tpublic void CheckedInArrayCreationArgument(int a, int b)\n\t\t{\n\t\t\tConsole.WriteLine(new int[checked(a + b)]);\n\t\t}\n\n\t\tpublic short Unbox(TypeCode c, object b)\n\t\t{\n\t\t\tchecked\n\t\t\t{\n\t\t\t\tswitch (c)\n\t\t\t\t{\n\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\treturn (short)((Box<int>)b).Value;\n\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\treturn (short)((Box<uint>)b).Value;\n\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t{\n\t\t\t\t\t\tfloat num = (float)((Box<double>)b).Value;\n\t\t\t\t\t\tConsole.WriteLine(num);\n\t\t\t\t\t\treturn (short)num;\n\t\t\t\t\t}\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new Exception();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Comparisons.cs",
    "content": "namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class Comparisons\n\t{\n\t\tprivate class A\n\t\t{\n\t\t}\n\n\t\tprivate class B\n\t\t{\n\t\t}\n\n\t\tprivate bool CompareUnrelatedNeedsCast(A a, B b)\n\t\t{\n\t\t\treturn (object)a == b;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class CompoundAssignmentTest\n\t{\n\t\t[Flags]\n\t\tprivate enum MyEnum\n\t\t{\n\t\t\tNone = 0,\n\t\t\tOne = 1,\n\t\t\tTwo = 2,\n\t\t\tFour = 4\n\t\t}\n\n\t\tpublic enum ShortEnum : short\n\t\t{\n\t\t\tNone = 0,\n\t\t\tOne = 1,\n\t\t\tTwo = 2,\n\t\t\tFour = 4\n\t\t}\n\n\t\tprivate struct StructContainer\n\t\t{\n\t\t\tpublic bool HasIndex;\n\t\t\tpublic int Field;\n\t\t}\n\n\t\tpublic class MutableClass\n\t\t{\n\t\t\tpublic int Field;\n\t\t\tpublic short ShortField;\n\n\t\t\tpublic int Property { get; set; }\n\n\t\t\tpublic byte ByteProperty { get; set; }\n\n\t\t\tpublic bool BoolProperty { get; set; }\n\n\t\t\tpublic uint this[string name] {\n\t\t\t\tget {\n\t\t\t\t\treturn 0u;\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate class Item\n\t\t{\n\t\t\tpublic Item Self;\n\t\t}\n\n\t\tpublic class CustomClass\n\t\t{\n\t\t\tpublic byte ByteField;\n\t\t\tpublic sbyte SbyteField;\n\t\t\tpublic short ShortField;\n\t\t\tpublic ushort UshortField;\n\t\t\tpublic int IntField;\n\t\t\tpublic uint UintField;\n\t\t\tpublic long LongField;\n\t\t\tpublic ulong UlongField;\n\t\t\tpublic CustomClass CustomClassField;\n\t\t\tpublic CustomStruct CustomStructField;\n\n\t\t\tpublic byte ByteProp { get; set; }\n\t\t\tpublic sbyte SbyteProp { get; set; }\n\t\t\tpublic short ShortProp { get; set; }\n\t\t\tpublic ushort UshortProp { get; set; }\n\t\t\tpublic int IntProp { get; set; }\n\t\t\tpublic uint UintProp { get; set; }\n\t\t\tpublic long LongProp { get; set; }\n\t\t\tpublic ulong UlongProp { get; set; }\n\t\t\tpublic string StringProp { get; set; }\n\n\t\t\tpublic CustomClass CustomClassProp { get; set; }\n\t\t\tpublic CustomStruct CustomStructProp { get; set; }\n\n\t\t\tpublic static CustomClass operator +(CustomClass lhs, CustomClass rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomClass operator +(CustomClass lhs, int rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomClass operator -(CustomClass lhs, CustomClass rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomClass operator *(CustomClass lhs, CustomClass rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomClass operator /(CustomClass lhs, CustomClass rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomClass operator %(CustomClass lhs, CustomClass rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomClass operator <<(CustomClass lhs, int rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomClass operator >>(CustomClass lhs, int rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomClass operator &(CustomClass lhs, CustomClass rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomClass operator |(CustomClass lhs, CustomClass rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomClass operator ^(CustomClass lhs, CustomClass rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomClass operator ++(CustomClass lhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomClass operator --(CustomClass lhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n\n\t\tpublic struct CustomStruct\n\t\t{\n\t\t\tpublic byte ByteField;\n\t\t\tpublic sbyte SbyteField;\n\t\t\tpublic short ShortField;\n\t\t\tpublic ushort UshortField;\n\t\t\tpublic int IntField;\n\t\t\tpublic uint UintField;\n\t\t\tpublic long LongField;\n\t\t\tpublic ulong UlongField;\n\t\t\tpublic CustomClass CustomClassField;\n\n\t\t\tpublic CustomClass CustomClassProp { get; set; }\n\t\t\tpublic byte ByteProp { get; set; }\n\t\t\tpublic sbyte SbyteProp { get; set; }\n\t\t\tpublic short ShortProp { get; set; }\n\t\t\tpublic ushort UshortProp { get; set; }\n\t\t\tpublic int IntProp { get; set; }\n\t\t\tpublic uint UintProp { get; set; }\n\t\t\tpublic long LongProp { get; set; }\n\t\t\tpublic ulong UlongProp { get; set; }\n\n\t\t\tpublic static CustomStruct operator +(CustomStruct lhs, CustomStruct rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomStruct operator -(CustomStruct lhs, CustomStruct rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomStruct operator *(CustomStruct lhs, CustomStruct rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomStruct operator /(CustomStruct lhs, CustomStruct rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomStruct operator %(CustomStruct lhs, CustomStruct rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomStruct operator <<(CustomStruct lhs, int rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomStruct operator >>(CustomStruct lhs, int rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n#if CS110\n\t\t\tpublic static CustomStruct operator >>>(CustomStruct lhs, int rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n#endif\n\t\t\tpublic static CustomStruct operator &(CustomStruct lhs, CustomStruct rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomStruct operator |(CustomStruct lhs, CustomStruct rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomStruct operator ^(CustomStruct lhs, CustomStruct rhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomStruct operator ++(CustomStruct lhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tpublic static CustomStruct operator --(CustomStruct lhs)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n\n\t\tpublic struct CustomStruct2\n\t\t{\n\t\t\tpublic CustomClass CustomClassField;\n\t\t\tpublic CustomStruct CustomStructField;\n\n\t\t\tpublic byte ByteField;\n\t\t\tpublic sbyte SbyteField;\n\t\t\tpublic short ShortField;\n\t\t\tpublic ushort UshortField;\n\t\t\tpublic int IntField;\n\t\t\tpublic uint UintField;\n\t\t\tpublic long LongField;\n\t\t\tpublic ulong UlongField;\n\n\t\t\tpublic CustomClass CustomClassProp { get; set; }\n\t\t\tpublic CustomStruct CustomStructProp { get; set; }\n\t\t\tpublic byte ByteProp { get; set; }\n\t\t\tpublic sbyte SbyteProp { get; set; }\n\t\t\tpublic short ShortProp { get; set; }\n\t\t\tpublic ushort UshortProp { get; set; }\n\t\t\tpublic int IntProp { get; set; }\n\t\t\tpublic uint UintProp { get; set; }\n\t\t\tpublic long LongProp { get; set; }\n\t\t\tpublic ulong UlongProp { get; set; }\n\t\t}\n\n\t\tprivate int test1;\n\t\tprivate int[] array1;\n\t\tprivate StructContainer field1;\n\t\tprivate MyEnum enumField;\n\t\tprivate Dictionary<ushort, ushort> ushortDict = new Dictionary<ushort, ushort>();\n\t\tprivate ShortEnum shortEnumField;\n\t\tpublic static int StaticField;\n\t\tpublic static short StaticShortField;\n\n\t\tprivate static CustomClass customClassField;\n\t\tprivate static CustomStruct customStructField;\n\t\tprivate static CustomStruct2 otherCustomStructField;\n\t\tprivate static byte byteField;\n\t\tprivate static sbyte sbyteField;\n\t\tprivate static short shortField;\n\t\tprivate static ushort ushortField;\n\t\tprivate static int intField;\n\t\tprivate static uint uintField;\n\t\tprivate static long longField;\n\t\tprivate static ulong ulongField;\n\n\t\tprivate static CustomClass CustomClassProp { get; set; }\n\t\tprivate static CustomStruct CustomStructProp { get; set; }\n\t\tprivate static byte ByteProp { get; set; }\n\t\tprivate static sbyte SbyteProp { get; set; }\n\t\tprivate static short ShortProp { get; set; }\n\t\tprivate static ushort UshortProp { get; set; }\n\t\tprivate static int IntProp { get; set; }\n\t\tprivate static uint UintProp { get; set; }\n\t\tprivate static long LongProp { get; set; }\n\t\tprivate static ulong UlongProp { get; set; }\n\n\t\tpublic static int StaticProperty { get; set; }\n\n\t\tpublic static ShortEnum StaticShortProperty { get; set; }\n\n\t\tpublic static string StaticStringProperty { get; set; }\n\n\t\tprivate static void Use(ref byte b)\n\t\t{\n\t\t}\n\n\t\tprivate static void Use(ref sbyte b)\n\t\t{\n\t\t}\n\n\t\tprivate static void Use<T>(ref T num)\n\t\t{\n\t\t}\n\n\t\tprivate static CustomStruct2 GetStruct()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n#if CS70\n\t\tprivate static ref CustomStruct2 GetRefStruct()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tprivate static ref CustomStruct GetRefCustomStruct()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tprivate static ref CustomClass GetRefCustomClass()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tprivate static ref byte GetRefByte()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tprivate static ref sbyte GetRefSbyte()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tprivate static ref short GetRefShort()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tprivate static ref int GetRefInt()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tprivate static ref long GetRefLong()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tprivate static ref ushort GetRefUshort()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tprivate static ref uint GetRefUint()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tprivate static ref ulong GetRefUlong()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n#endif\n\n\t\tprivate static CustomClass GetClass()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tprivate static void X<T>(T result)\n\t\t{\n\n\t\t}\n\n\t\tprivate MutableClass M()\n\t\t{\n\t\t\treturn new MutableClass();\n\t\t}\n\n\t\tprivate int[,] Array()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tprivate unsafe int* GetPointer()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic int GetIndex()\n\t\t{\n\t\t\treturn new Random().Next(0, 100);\n\t\t}\n\n\t\tpublic int[] GetArray()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tpublic int GetValue(int value)\n\t\t{\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic bool IsUpperCaseA(char a)\n\t\t{\n\t\t\treturn a == 'A';\n\t\t}\n\n\t\tpublic void Int32_Local_Add(int i)\n\t\t{\n\t\t\ti++;\n\t\t\tConsole.WriteLine(i++);\n\t\t\tConsole.WriteLine(++i);\n\t\t\ti += 5;\n\t\t\tConsole.WriteLine(i += 5);\n\t\t}\n\n\t\tpublic void Int32_Local_Sub(int i)\n\t\t{\n\t\t\ti--;\n\t\t\tConsole.WriteLine(i--);\n\t\t\tConsole.WriteLine(--i);\n\t\t\ti -= 5;\n\t\t\tConsole.WriteLine(i -= 5);\n\t\t}\n\n\t\tpublic void Int32_Local_Mul(int i)\n\t\t{\n\t\t\ti *= 5;\n\t\t\tConsole.WriteLine(i *= 5);\n\t\t}\n\n\t\tpublic void Int32_Local_Div(int i)\n\t\t{\n\t\t\ti /= 5;\n\t\t\tConsole.WriteLine(i /= 5);\n\t\t}\n\n\t\tpublic void Int32_Local_Rem(int i)\n\t\t{\n\t\t\ti %= 5;\n\t\t\tConsole.WriteLine(i %= 5);\n\t\t}\n\n\t\tpublic void Int32_Local_BitAnd(int i)\n\t\t{\n\t\t\ti &= 5;\n\t\t\tConsole.WriteLine(i &= 5);\n\t\t}\n\n\t\tpublic void Int32_Local_BitOr(int i)\n\t\t{\n\t\t\ti |= 5;\n\t\t\tConsole.WriteLine(i |= 5);\n\t\t}\n\n\t\tpublic void Int32_Local_BitXor(int i)\n\t\t{\n\t\t\ti ^= 5;\n\t\t\tConsole.WriteLine(i ^= 5);\n\t\t}\n\n\t\tpublic void Int32_Local_ShiftLeft(int i)\n\t\t{\n\t\t\ti <<= 5;\n\t\t\tConsole.WriteLine(i <<= 5);\n\t\t}\n\n\t\tpublic void Int32_Local_ShiftRight(int i)\n\t\t{\n\t\t\ti >>= 5;\n\t\t\tConsole.WriteLine(i >>= 5);\n\t\t}\n\n\t\tpublic void IntegerWithInline(int i)\n\t\t{\n\t\t\tConsole.WriteLine(i += 5);\n\t\t\tConsole.WriteLine(i);\n\t\t}\n\n\t\tpublic void IntegerField(int i)\n\t\t{\n\t\t\tConsole.WriteLine(test1 += i);\n\t\t\tConsole.WriteLine(test1);\n\t\t\tConsole.WriteLine(test1 -= i);\n\t\t\tConsole.WriteLine(test1);\n\t\t}\n\n\t\tpublic void Array(int i)\n\t\t{\n\t\t\tConsole.WriteLine(array1[i] += i);\n\t\t\tConsole.WriteLine(array1[i * 2] += i * 2);\n\t\t}\n\n\t\tpublic int ArrayUsageWithMethods()\n\t\t{\n\t\t\treturn GetArray()[GetIndex()]++;\n\t\t}\n\n\t\tpublic void NestedField()\n\t\t{\n\t\t\tif (field1.HasIndex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(field1.Field *= 2);\n\t\t\t\tfield1.Field++;\n\t\t\t\tConsole.WriteLine(field1.Field++);\n\t\t\t}\n\t\t}\n\n\t\tpublic void Enum()\n\t\t{\n\t\t\tenumField |= MyEnum.Two;\n\t\t\tenumField &= ~MyEnum.Four;\n\t\t\tenumField += 2;\n\t\t\tenumField -= 3;\n\t\t}\n\n\t\tpublic void ShortEnumTest()\n\t\t{\n\t\t\tshortEnumField |= ShortEnum.Two;\n\t\t\tshortEnumField &= ShortEnum.Four;\n\t\t\tshortEnumField += 2;\n\t\t\tshortEnumField -= 3;\n\t\t}\n\n\t\tpublic int PreIncrementInAddition(int i, int j)\n\t\t{\n\t\t\treturn i + ++j;\n\t\t}\n\n\t\tpublic int PreIncrementArrayElement(int[] array, int pos)\n\t\t{\n\t\t\treturn --array[pos];\n\t\t}\n\n\t\tpublic int PostIncrementArrayElement(int[] array, int pos)\n\t\t{\n\t\t\treturn array[pos]++;\n\t\t}\n\n\t\tpublic void IncrementArrayElement(int[] array, int pos)\n\t\t{\n\t\t\tarray[pos]++;\n\t\t}\n\n\t\tpublic void DoubleArrayElement(int[] array, int pos)\n\t\t{\n\t\t\tarray[pos] *= 2;\n\t\t}\n\n\t\tpublic int DoubleArrayElementAndReturn(int[] array, int pos)\n\t\t{\n\t\t\treturn array[pos] *= 2;\n\t\t}\n\n\t\tpublic int PreIncrementArrayElementShort(short[] array, int pos)\n\t\t{\n\t\t\treturn --array[pos];\n\t\t}\n\n\t\tpublic int PostIncrementArrayElementShort(short[] array, int pos)\n\t\t{\n\t\t\treturn array[pos]++;\n\t\t}\n\n\t\tpublic void IncrementArrayElementShort(short[] array, int pos)\n\t\t{\n\t\t\tarray[pos]++;\n\t\t}\n\n\t\tpublic void DoubleArrayElementShort(short[] array, int pos)\n\t\t{\n\t\t\tarray[pos] *= 2;\n\t\t}\n\n\t\tpublic short DoubleArrayElementShortAndReturn(short[] array, int pos)\n\t\t{\n\t\t\treturn array[pos] *= 2;\n\t\t}\n\n\t\tpublic int PreIncrementInstanceField()\n\t\t{\n\t\t\treturn ++M().Field;\n\t\t}\n\n\t\tpublic int PostIncrementInstanceField()\n\t\t{\n\t\t\treturn M().Field++;\n\t\t}\n\n\t\tpublic void IncrementInstanceField()\n\t\t{\n\t\t\tM().Field++;\n\t\t}\n\n\t\tpublic void DoubleInstanceField()\n\t\t{\n\t\t\tM().Field *= 2;\n\t\t}\n\n\t\tpublic int DoubleInstanceFieldAndReturn()\n\t\t{\n\t\t\treturn M().Field *= 2;\n\t\t}\n\n\t\tpublic int PreIncrementInstanceField2(MutableClass m)\n\t\t{\n\t\t\treturn ++m.Field;\n\t\t}\n\n\t\tpublic int PostIncrementInstanceField2(MutableClass m)\n\t\t{\n\t\t\treturn m.Field++;\n\t\t}\n\n\t\tpublic void IncrementInstanceField2(MutableClass m)\n\t\t{\n\t\t\tm.Field++;\n\t\t}\n\n\t\tpublic int PreIncrementInstanceFieldShort()\n\t\t{\n\t\t\treturn ++M().ShortField;\n\t\t}\n\n\t\tpublic int PostIncrementInstanceFieldShort()\n\t\t{\n\t\t\treturn M().ShortField++;\n\t\t}\n\n\t\tpublic void IncrementInstanceFieldShort()\n\t\t{\n\t\t\tM().ShortField++;\n\t\t}\n\n\t\tpublic int PreIncrementInstanceProperty()\n\t\t{\n\t\t\treturn ++M().Property;\n\t\t}\n\n\t\tpublic int PostIncrementInstanceProperty()\n\t\t{\n\t\t\treturn M().Property++;\n\t\t}\n\n\t\tpublic void IncrementInstanceProperty()\n\t\t{\n\t\t\tM().Property++;\n\t\t}\n\n\t\tpublic void DoubleInstanceProperty()\n\t\t{\n\t\t\tM().Property *= 2;\n\t\t}\n\n\t\tpublic int DoubleInstancePropertyAndReturn()\n\t\t{\n\t\t\treturn M().Property *= 2;\n\t\t}\n\n\t\tpublic int PreIncrementInstancePropertyByte()\n\t\t{\n\t\t\treturn ++M().ByteProperty;\n\t\t}\n\n\t\tpublic int PostIncrementInstancePropertyByte()\n\t\t{\n\t\t\treturn M().ByteProperty++;\n\t\t}\n\n\t\tpublic void IncrementInstancePropertyByte()\n\t\t{\n\t\t\tM().ByteProperty++;\n\t\t}\n\n\t\tpublic void DoubleInstancePropertyByte()\n\t\t{\n\t\t\tM().ByteProperty *= 2;\n\t\t}\n\n\t\tpublic int DoubleInstancePropertyByteAndReturn()\n\t\t{\n\t\t\treturn M().ByteProperty *= 2;\n\t\t}\n\n\t\tpublic void BitManipBoolProperty(bool b)\n\t\t{\n\t\t\tM().BoolProperty |= b;\n\t\t\tM().BoolProperty &= b;\n\t\t\tM().BoolProperty ^= b;\n\t\t}\n\n\t\tpublic bool BitOrBoolPropertyAndReturn(bool b)\n\t\t{\n\t\t\treturn M().BoolProperty |= b;\n\t\t}\n\n\t\tpublic bool BitAndBoolPropertyAndReturn(bool b)\n\t\t{\n\t\t\treturn M().BoolProperty &= b;\n\t\t}\n\n\t\tpublic int PreIncrementStaticField()\n\t\t{\n\t\t\treturn ++StaticField;\n\t\t}\n\n\t\tpublic int PostIncrementStaticField()\n\t\t{\n\t\t\treturn StaticField++;\n\t\t}\n\n\t\tpublic void IncrementStaticField()\n\t\t{\n\t\t\tStaticField++;\n\t\t}\n\n\t\tpublic void DoubleStaticField()\n\t\t{\n\t\t\tStaticField *= 2;\n\t\t}\n\n\t\tpublic int DoubleStaticFieldAndReturn()\n\t\t{\n\t\t\treturn StaticField *= 2;\n\t\t}\n\n\t\tpublic int PreIncrementStaticFieldShort()\n\t\t{\n\t\t\treturn ++StaticShortField;\n\t\t}\n\n\t\tpublic int PostIncrementStaticFieldShort()\n\t\t{\n\t\t\treturn StaticShortField++;\n\t\t}\n\n\t\tpublic void IncrementStaticFieldShort()\n\t\t{\n\t\t\tStaticShortField++;\n\t\t}\n\n\t\tpublic void DoubleStaticFieldShort()\n\t\t{\n\t\t\tStaticShortField *= 2;\n\t\t}\n\n\t\tpublic short DoubleStaticFieldAndReturnShort()\n\t\t{\n\t\t\treturn StaticShortField *= 2;\n\t\t}\n\n\t\tpublic int PreIncrementStaticProperty()\n\t\t{\n\t\t\treturn ++StaticProperty;\n\t\t}\n\n\t\tpublic int PostIncrementStaticProperty()\n\t\t{\n\t\t\treturn StaticProperty++;\n\t\t}\n\n\t\tpublic void IncrementStaticProperty()\n\t\t{\n\t\t\tStaticProperty++;\n\t\t}\n\n\t\tpublic void DoubleStaticProperty()\n\t\t{\n\t\t\tStaticProperty *= 2;\n\t\t}\n\n\t\tpublic int DoubleStaticPropertyAndReturn()\n\t\t{\n\t\t\treturn StaticProperty *= 2;\n\t\t}\n\n\t\tpublic ShortEnum PreIncrementStaticPropertyShort()\n\t\t{\n\t\t\treturn ++StaticShortProperty;\n\t\t}\n\n\t\tpublic ShortEnum PostIncrementStaticPropertyShort()\n\t\t{\n\t\t\treturn StaticShortProperty++;\n\t\t}\n\n\t\tpublic void IncrementStaticPropertyShort()\n\t\t{\n\t\t\tStaticShortProperty++;\n\t\t}\n\n\t\t#region Generated Tests\n\n\t\tpublic static void ByteAddTest(byte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tbyte b = 0;\n\t\t\tp += 5;\n\t\t\tb += 5;\n\t\t\tUse(ref b);\n\t\t\tbyteField += 5;\n\t\t\tByteProp += 5;\n\t\t\tc.ByteField += 5;\n\t\t\tc.ByteProp += 5;\n\t\t\ts.ByteField += 5;\n\t\t\ts.ByteProp += 5;\n\t\t\tcustomClassField.ByteField += 5;\n\t\t\tcustomClassField.ByteProp += 5;\n\t\t\totherCustomStructField.ByteField += 5;\n\t\t\totherCustomStructField.ByteProp += 5;\n\t\t\tCustomClassProp.ByteField += 5;\n\t\t\tCustomClassProp.ByteProp += 5;\n\t\t\tGetClass().ByteField += 5;\n\t\t\tGetClass().ByteProp += 5;\n#if CS70\n\t\t\tGetRefStruct().ByteField += 5;\n\t\t\tGetRefStruct().ByteProp += 5;\n\t\t\tGetRefByte() += 5;\n#endif\n\t\t}\n\n\t\tpublic static void ByteSubtractTest(byte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tbyte b = 0;\n\t\t\tp -= 5;\n\t\t\tb -= 5;\n\t\t\tUse(ref b);\n\t\t\tbyteField -= 5;\n\t\t\tByteProp -= 5;\n\t\t\tc.ByteField -= 5;\n\t\t\tc.ByteProp -= 5;\n\t\t\ts.ByteField -= 5;\n\t\t\ts.ByteProp -= 5;\n\t\t\tcustomClassField.ByteField -= 5;\n\t\t\tcustomClassField.ByteProp -= 5;\n\t\t\totherCustomStructField.ByteField -= 5;\n\t\t\totherCustomStructField.ByteProp -= 5;\n\t\t\tCustomClassProp.ByteField -= 5;\n\t\t\tCustomClassProp.ByteProp -= 5;\n\t\t\tGetClass().ByteField -= 5;\n\t\t\tGetClass().ByteProp -= 5;\n#if CS70\n\t\t\tGetRefStruct().ByteField -= 5;\n\t\t\tGetRefStruct().ByteProp -= 5;\n\t\t\tGetRefByte() -= 5;\n#endif\n\t\t}\n\n\t\tpublic static void ByteMultiplyTest(byte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tbyte b = 0;\n\t\t\tp *= 5;\n\t\t\tb *= 5;\n\t\t\tUse(ref b);\n\t\t\tbyteField *= 5;\n\t\t\tByteProp *= 5;\n\t\t\tc.ByteField *= 5;\n\t\t\tc.ByteProp *= 5;\n\t\t\ts.ByteField *= 5;\n\t\t\ts.ByteProp *= 5;\n\t\t\tcustomClassField.ByteField *= 5;\n\t\t\tcustomClassField.ByteProp *= 5;\n\t\t\totherCustomStructField.ByteField *= 5;\n\t\t\totherCustomStructField.ByteProp *= 5;\n\t\t\tCustomClassProp.ByteField *= 5;\n\t\t\tCustomClassProp.ByteProp *= 5;\n\t\t\tGetClass().ByteField *= 5;\n\t\t\tGetClass().ByteProp *= 5;\n#if CS70\n\t\t\tGetRefStruct().ByteField *= 5;\n\t\t\tGetRefStruct().ByteProp *= 5;\n\t\t\tGetRefByte() *= 5;\n#endif\n\t\t}\n\n\t\tpublic static void ByteDivideTest(byte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tbyte b = 0;\n\t\t\tp /= 5;\n\t\t\tb /= 5;\n\t\t\tUse(ref b);\n\t\t\tbyteField /= 5;\n\t\t\tByteProp /= 5;\n\t\t\tc.ByteField /= 5;\n\t\t\tc.ByteProp /= 5;\n\t\t\ts.ByteField /= 5;\n\t\t\ts.ByteProp /= 5;\n\t\t\tcustomClassField.ByteField /= 5;\n\t\t\tcustomClassField.ByteProp /= 5;\n\t\t\totherCustomStructField.ByteField /= 5;\n\t\t\totherCustomStructField.ByteProp /= 5;\n\t\t\tCustomClassProp.ByteField /= 5;\n\t\t\tCustomClassProp.ByteProp /= 5;\n\t\t\tGetClass().ByteField /= 5;\n\t\t\tGetClass().ByteProp /= 5;\n#if CS70\n\t\t\tGetRefStruct().ByteField /= 5;\n\t\t\tGetRefStruct().ByteProp /= 5;\n\t\t\tGetRefByte() /= 5;\n#endif\n\t\t}\n\n\t\tpublic static void ByteModulusTest(byte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tbyte b = 0;\n\t\t\tp %= 5;\n\t\t\tb %= 5;\n\t\t\tUse(ref b);\n\t\t\tbyteField %= 5;\n\t\t\tByteProp %= 5;\n\t\t\tc.ByteField %= 5;\n\t\t\tc.ByteProp %= 5;\n\t\t\ts.ByteField %= 5;\n\t\t\ts.ByteProp %= 5;\n\t\t\tcustomClassField.ByteField %= 5;\n\t\t\tcustomClassField.ByteProp %= 5;\n\t\t\totherCustomStructField.ByteField %= 5;\n\t\t\totherCustomStructField.ByteProp %= 5;\n\t\t\tCustomClassProp.ByteField %= 5;\n\t\t\tCustomClassProp.ByteProp %= 5;\n\t\t\tGetClass().ByteField %= 5;\n\t\t\tGetClass().ByteProp %= 5;\n#if CS70\n\t\t\tGetRefStruct().ByteField %= 5;\n\t\t\tGetRefStruct().ByteProp %= 5;\n\t\t\tGetRefByte() %= 5;\n#endif\n\t\t}\n\n\t\tpublic static void ByteLeftShiftTest(byte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tbyte b = 0;\n\t\t\tp <<= 5;\n\t\t\tb <<= 5;\n\t\t\tUse(ref b);\n\t\t\tbyteField <<= 5;\n\t\t\tByteProp <<= 5;\n\t\t\tc.ByteField <<= 5;\n\t\t\tc.ByteProp <<= 5;\n\t\t\ts.ByteField <<= 5;\n\t\t\ts.ByteProp <<= 5;\n\t\t\tcustomClassField.ByteField <<= 5;\n\t\t\tcustomClassField.ByteProp <<= 5;\n\t\t\totherCustomStructField.ByteField <<= 5;\n\t\t\totherCustomStructField.ByteProp <<= 5;\n\t\t\tCustomClassProp.ByteField <<= 5;\n\t\t\tCustomClassProp.ByteProp <<= 5;\n\t\t\tGetClass().ByteField <<= 5;\n\t\t\tGetClass().ByteProp <<= 5;\n#if CS70\n\t\t\tGetRefStruct().ByteField <<= 5;\n\t\t\tGetRefStruct().ByteProp <<= 5;\n\t\t\tGetRefByte() <<= 5;\n#endif\n\t\t}\n\n\t\tpublic static void ByteRightShiftTest(byte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tbyte b = 0;\n\t\t\tp >>= 5;\n\t\t\tb >>= 5;\n\t\t\tUse(ref b);\n\t\t\tbyteField >>= 5;\n\t\t\tByteProp >>= 5;\n\t\t\tc.ByteField >>= 5;\n\t\t\tc.ByteProp >>= 5;\n\t\t\ts.ByteField >>= 5;\n\t\t\ts.ByteProp >>= 5;\n\t\t\tcustomClassField.ByteField >>= 5;\n\t\t\tcustomClassField.ByteProp >>= 5;\n\t\t\totherCustomStructField.ByteField >>= 5;\n\t\t\totherCustomStructField.ByteProp >>= 5;\n\t\t\tCustomClassProp.ByteField >>= 5;\n\t\t\tCustomClassProp.ByteProp >>= 5;\n\t\t\tGetClass().ByteField >>= 5;\n\t\t\tGetClass().ByteProp >>= 5;\n#if CS70\n\t\t\tGetRefStruct().ByteField >>= 5;\n\t\t\tGetRefStruct().ByteProp >>= 5;\n\t\t\tGetRefByte() >>= 5;\n#endif\n\t\t}\n\n\t\tpublic static void ByteBitAndTest(byte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tbyte b = 0;\n\t\t\tp &= c.ByteField;\n\t\t\tb &= c.ByteField;\n\t\t\tUse(ref b);\n\t\t\tbyteField &= 5;\n\t\t\tByteProp &= 5;\n\t\t\tc.ByteField &= 5;\n\t\t\tc.ByteProp &= 5;\n\t\t\ts.ByteField &= 5;\n\t\t\ts.ByteProp &= 5;\n\t\t\tcustomClassField.ByteField &= 5;\n\t\t\tcustomClassField.ByteProp &= 5;\n\t\t\totherCustomStructField.ByteField &= 5;\n\t\t\totherCustomStructField.ByteProp &= 5;\n\t\t\tCustomClassProp.ByteField &= 5;\n\t\t\tCustomClassProp.ByteProp &= 5;\n\t\t\tGetClass().ByteField &= 5;\n\t\t\tGetClass().ByteProp &= 5;\n#if CS70\n\t\t\tGetRefStruct().ByteField &= 5;\n\t\t\tGetRefStruct().ByteProp &= 5;\n\t\t\tGetRefByte() &= 5;\n#endif\n\t\t}\n\n\t\tpublic static void ByteBitOrTest(byte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tbyte b = 0;\n\t\t\tp |= c.ByteField;\n\t\t\tb |= c.ByteField;\n\t\t\tUse(ref b);\n\t\t\tbyteField |= 5;\n\t\t\tByteProp |= 5;\n\t\t\tc.ByteField |= 5;\n\t\t\tc.ByteProp |= 5;\n\t\t\ts.ByteField |= 5;\n\t\t\ts.ByteProp |= 5;\n\t\t\tcustomClassField.ByteField |= 5;\n\t\t\tcustomClassField.ByteProp |= 5;\n\t\t\totherCustomStructField.ByteField |= 5;\n\t\t\totherCustomStructField.ByteProp |= 5;\n\t\t\tCustomClassProp.ByteField |= 5;\n\t\t\tCustomClassProp.ByteProp |= 5;\n\t\t\tGetClass().ByteField |= 5;\n\t\t\tGetClass().ByteProp |= 5;\n#if CS70\n\t\t\tGetRefStruct().ByteField |= 5;\n\t\t\tGetRefStruct().ByteProp |= 5;\n\t\t\tGetRefByte() |= 5;\n#endif\n\t\t}\n\n\t\tpublic static void ByteBitXorTest(byte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tbyte b = 0;\n\t\t\tp ^= c.ByteField;\n\t\t\tb ^= c.ByteField;\n\t\t\tUse(ref b);\n\t\t\tbyteField ^= 5;\n\t\t\tByteProp ^= 5;\n\t\t\tc.ByteField ^= 5;\n\t\t\tc.ByteProp ^= 5;\n\t\t\ts.ByteField ^= 5;\n\t\t\ts.ByteProp ^= 5;\n\t\t\tcustomClassField.ByteField ^= 5;\n\t\t\tcustomClassField.ByteProp ^= 5;\n\t\t\totherCustomStructField.ByteField ^= 5;\n\t\t\totherCustomStructField.ByteProp ^= 5;\n\t\t\tCustomClassProp.ByteField ^= 5;\n\t\t\tCustomClassProp.ByteProp ^= 5;\n\t\t\tGetClass().ByteField ^= 5;\n\t\t\tGetClass().ByteProp ^= 5;\n#if CS70\n\t\t\tGetRefStruct().ByteField ^= 5;\n\t\t\tGetRefStruct().ByteProp ^= 5;\n\t\t\tGetRefByte() ^= 5;\n#endif\n\t\t}\n\n\t\tpublic static void BytePostIncTest(byte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tbyte b = 0;\n\t\t\tX(p++);\n\t\t\tX(b++);\n\t\t\tUse(ref b);\n\t\t\tX(byteField++);\n\t\t\tX(ByteProp++);\n\t\t\tX(c.ByteField++);\n\t\t\tX(c.ByteProp++);\n\t\t\tX(s.ByteField++);\n\t\t\tX(s.ByteProp++);\n\t\t\tX(customClassField.ByteField++);\n\t\t\tX(customClassField.ByteProp++);\n\t\t\tX(otherCustomStructField.ByteField++);\n\t\t\tX(otherCustomStructField.ByteProp++);\n\t\t\tX(CustomClassProp.ByteField++);\n\t\t\tX(CustomClassProp.ByteProp++);\n\t\t\tX(GetClass().ByteField++);\n\t\t\tX(GetClass().ByteProp++);\n#if CS70\n\t\t\tX(GetRefStruct().ByteField++);\n\t\t\tX(GetRefStruct().ByteProp++);\n\t\t\tX(GetRefByte()++);\n#endif\n\t\t}\n\n\t\tpublic static void BytePreIncTest(byte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tbyte b = 0;\n\t\t\tX(++p);\n\t\t\tX(++b);\n\t\t\tUse(ref b);\n\t\t\tX(++byteField);\n\t\t\tX(++ByteProp);\n\t\t\tX(++c.ByteField);\n\t\t\tX(++c.ByteProp);\n\t\t\tX(++s.ByteField);\n\t\t\tX(++s.ByteProp);\n\t\t\tX(++customClassField.ByteField);\n\t\t\tX(++customClassField.ByteProp);\n\t\t\tX(++otherCustomStructField.ByteField);\n\t\t\tX(++otherCustomStructField.ByteProp);\n\t\t\tX(++CustomClassProp.ByteField);\n\t\t\tX(++CustomClassProp.ByteProp);\n\t\t\tX(++GetClass().ByteField);\n\t\t\tX(++GetClass().ByteProp);\n#if CS70\n\t\t\tX(++GetRefStruct().ByteField);\n\t\t\tX(++GetRefStruct().ByteProp);\n\t\t\tX(++GetRefByte());\n#endif\n\t\t}\n\t\tpublic static void BytePostDecTest(byte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tbyte b = 0;\n\t\t\tX(p--);\n\t\t\tX(b--);\n\t\t\tUse(ref b);\n\t\t\tX(byteField--);\n\t\t\tX(ByteProp--);\n\t\t\tX(c.ByteField--);\n\t\t\tX(c.ByteProp--);\n\t\t\tX(s.ByteField--);\n\t\t\tX(s.ByteProp--);\n\t\t\tX(customClassField.ByteField--);\n\t\t\tX(customClassField.ByteProp--);\n\t\t\tX(otherCustomStructField.ByteField--);\n\t\t\tX(otherCustomStructField.ByteProp--);\n\t\t\tX(CustomClassProp.ByteField--);\n\t\t\tX(CustomClassProp.ByteProp--);\n\t\t\tX(GetClass().ByteField--);\n\t\t\tX(GetClass().ByteProp--);\n#if CS70\n\t\t\tX(GetRefStruct().ByteField--);\n\t\t\tX(GetRefStruct().ByteProp--);\n\t\t\tX(GetRefByte()--);\n#endif\n\t\t}\n\n\t\tpublic static void BytePreDecTest(byte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tbyte b = 0;\n\t\t\tX(--p);\n\t\t\tX(--b);\n\t\t\tUse(ref b);\n\t\t\tX(--byteField);\n\t\t\tX(--ByteProp);\n\t\t\tX(--c.ByteField);\n\t\t\tX(--c.ByteProp);\n\t\t\tX(--s.ByteField);\n\t\t\tX(--s.ByteProp);\n\t\t\tX(--customClassField.ByteField);\n\t\t\tX(--customClassField.ByteProp);\n\t\t\tX(--otherCustomStructField.ByteField);\n\t\t\tX(--otherCustomStructField.ByteProp);\n\t\t\tX(--CustomClassProp.ByteField);\n\t\t\tX(--CustomClassProp.ByteProp);\n\t\t\tX(--GetClass().ByteField);\n\t\t\tX(--GetClass().ByteProp);\n#if CS70\n\t\t\tX(--GetRefStruct().ByteField);\n\t\t\tX(--GetRefStruct().ByteProp);\n\t\t\tX(--GetRefByte());\n#endif\n\t\t}\n\t\tpublic static void SbyteAddTest(sbyte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tsbyte b = 0;\n\t\t\tp += 5;\n\t\t\tb += 5;\n\t\t\tUse(ref b);\n\t\t\tsbyteField += 5;\n\t\t\tSbyteProp += 5;\n\t\t\tc.SbyteField += 5;\n\t\t\tc.SbyteProp += 5;\n\t\t\ts.SbyteField += 5;\n\t\t\ts.SbyteProp += 5;\n\t\t\tcustomClassField.SbyteField += 5;\n\t\t\tcustomClassField.SbyteProp += 5;\n\t\t\totherCustomStructField.SbyteField += 5;\n\t\t\totherCustomStructField.SbyteProp += 5;\n\t\t\tCustomClassProp.SbyteField += 5;\n\t\t\tCustomClassProp.SbyteProp += 5;\n\t\t\tGetClass().SbyteField += 5;\n\t\t\tGetClass().SbyteProp += 5;\n#if CS70\n\t\t\tGetRefStruct().SbyteField += 5;\n\t\t\tGetRefStruct().SbyteProp += 5;\n\t\t\tGetRefSbyte() += 5;\n#endif\n\t\t}\n\n\t\tpublic static void SbyteSubtractTest(sbyte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tsbyte b = 0;\n\t\t\tp -= 5;\n\t\t\tb -= 5;\n\t\t\tUse(ref b);\n\t\t\tsbyteField -= 5;\n\t\t\tSbyteProp -= 5;\n\t\t\tc.SbyteField -= 5;\n\t\t\tc.SbyteProp -= 5;\n\t\t\ts.SbyteField -= 5;\n\t\t\ts.SbyteProp -= 5;\n\t\t\tcustomClassField.SbyteField -= 5;\n\t\t\tcustomClassField.SbyteProp -= 5;\n\t\t\totherCustomStructField.SbyteField -= 5;\n\t\t\totherCustomStructField.SbyteProp -= 5;\n\t\t\tCustomClassProp.SbyteField -= 5;\n\t\t\tCustomClassProp.SbyteProp -= 5;\n\t\t\tGetClass().SbyteField -= 5;\n\t\t\tGetClass().SbyteProp -= 5;\n#if CS70\n\t\t\tGetRefStruct().SbyteField -= 5;\n\t\t\tGetRefStruct().SbyteProp -= 5;\n\t\t\tGetRefSbyte() -= 5;\n#endif\n\t\t}\n\n\t\tpublic static void SbyteMultiplyTest(sbyte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tsbyte b = 0;\n\t\t\tp *= 5;\n\t\t\tb *= 5;\n\t\t\tUse(ref b);\n\t\t\tsbyteField *= 5;\n\t\t\tSbyteProp *= 5;\n\t\t\tc.SbyteField *= 5;\n\t\t\tc.SbyteProp *= 5;\n\t\t\ts.SbyteField *= 5;\n\t\t\ts.SbyteProp *= 5;\n\t\t\tcustomClassField.SbyteField *= 5;\n\t\t\tcustomClassField.SbyteProp *= 5;\n\t\t\totherCustomStructField.SbyteField *= 5;\n\t\t\totherCustomStructField.SbyteProp *= 5;\n\t\t\tCustomClassProp.SbyteField *= 5;\n\t\t\tCustomClassProp.SbyteProp *= 5;\n\t\t\tGetClass().SbyteField *= 5;\n\t\t\tGetClass().SbyteProp *= 5;\n#if CS70\n\t\t\tGetRefStruct().SbyteField *= 5;\n\t\t\tGetRefStruct().SbyteProp *= 5;\n\t\t\tGetRefSbyte() *= 5;\n#endif\n\t\t}\n\n\t\tpublic static void SbyteDivideTest(sbyte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tsbyte b = 0;\n\t\t\tp /= 5;\n\t\t\tb /= 5;\n\t\t\tUse(ref b);\n\t\t\tsbyteField /= 5;\n\t\t\tSbyteProp /= 5;\n\t\t\tc.SbyteField /= 5;\n\t\t\tc.SbyteProp /= 5;\n\t\t\ts.SbyteField /= 5;\n\t\t\ts.SbyteProp /= 5;\n\t\t\tcustomClassField.SbyteField /= 5;\n\t\t\tcustomClassField.SbyteProp /= 5;\n\t\t\totherCustomStructField.SbyteField /= 5;\n\t\t\totherCustomStructField.SbyteProp /= 5;\n\t\t\tCustomClassProp.SbyteField /= 5;\n\t\t\tCustomClassProp.SbyteProp /= 5;\n\t\t\tGetClass().SbyteField /= 5;\n\t\t\tGetClass().SbyteProp /= 5;\n#if CS70\n\t\t\tGetRefStruct().SbyteField /= 5;\n\t\t\tGetRefStruct().SbyteProp /= 5;\n\t\t\tGetRefSbyte() /= 5;\n#endif\n\t\t}\n\n\t\tpublic static void SbyteModulusTest(sbyte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tsbyte b = 0;\n\t\t\tp %= 5;\n\t\t\tb %= 5;\n\t\t\tUse(ref b);\n\t\t\tsbyteField %= 5;\n\t\t\tSbyteProp %= 5;\n\t\t\tc.SbyteField %= 5;\n\t\t\tc.SbyteProp %= 5;\n\t\t\ts.SbyteField %= 5;\n\t\t\ts.SbyteProp %= 5;\n\t\t\tcustomClassField.SbyteField %= 5;\n\t\t\tcustomClassField.SbyteProp %= 5;\n\t\t\totherCustomStructField.SbyteField %= 5;\n\t\t\totherCustomStructField.SbyteProp %= 5;\n\t\t\tCustomClassProp.SbyteField %= 5;\n\t\t\tCustomClassProp.SbyteProp %= 5;\n\t\t\tGetClass().SbyteField %= 5;\n\t\t\tGetClass().SbyteProp %= 5;\n#if CS70\n\t\t\tGetRefStruct().SbyteField %= 5;\n\t\t\tGetRefStruct().SbyteProp %= 5;\n\t\t\tGetRefSbyte() %= 5;\n#endif\n\t\t}\n\n\t\tpublic static void SbyteLeftShiftTest(sbyte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tsbyte b = 0;\n\t\t\tp <<= 5;\n\t\t\tb <<= 5;\n\t\t\tUse(ref b);\n\t\t\tsbyteField <<= 5;\n\t\t\tSbyteProp <<= 5;\n\t\t\tc.SbyteField <<= 5;\n\t\t\tc.SbyteProp <<= 5;\n\t\t\ts.SbyteField <<= 5;\n\t\t\ts.SbyteProp <<= 5;\n\t\t\tcustomClassField.SbyteField <<= 5;\n\t\t\tcustomClassField.SbyteProp <<= 5;\n\t\t\totherCustomStructField.SbyteField <<= 5;\n\t\t\totherCustomStructField.SbyteProp <<= 5;\n\t\t\tCustomClassProp.SbyteField <<= 5;\n\t\t\tCustomClassProp.SbyteProp <<= 5;\n\t\t\tGetClass().SbyteField <<= 5;\n\t\t\tGetClass().SbyteProp <<= 5;\n#if CS70\n\t\t\tGetRefStruct().SbyteField <<= 5;\n\t\t\tGetRefStruct().SbyteProp <<= 5;\n\t\t\tGetRefSbyte() <<= 5;\n#endif\n\t\t}\n\n\t\tpublic static void SbyteRightShiftTest(sbyte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tsbyte b = 0;\n\t\t\tp >>= 5;\n\t\t\tb >>= 5;\n\t\t\tUse(ref b);\n\t\t\tsbyteField >>= 5;\n\t\t\tSbyteProp >>= 5;\n\t\t\tc.SbyteField >>= 5;\n\t\t\tc.SbyteProp >>= 5;\n\t\t\ts.SbyteField >>= 5;\n\t\t\ts.SbyteProp >>= 5;\n\t\t\tcustomClassField.SbyteField >>= 5;\n\t\t\tcustomClassField.SbyteProp >>= 5;\n\t\t\totherCustomStructField.SbyteField >>= 5;\n\t\t\totherCustomStructField.SbyteProp >>= 5;\n\t\t\tCustomClassProp.SbyteField >>= 5;\n\t\t\tCustomClassProp.SbyteProp >>= 5;\n\t\t\tGetClass().SbyteField >>= 5;\n\t\t\tGetClass().SbyteProp >>= 5;\n#if CS70\n\t\t\tGetRefStruct().SbyteField >>= 5;\n\t\t\tGetRefStruct().SbyteProp >>= 5;\n\t\t\tGetRefSbyte() >>= 5;\n#endif\n\t\t}\n\n\t\tpublic static void SbyteBitAndTest(sbyte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tsbyte b = 0;\n\t\t\tp &= 5;\n\t\t\tb &= 5;\n\t\t\tUse(ref b);\n\t\t\tsbyteField &= 5;\n\t\t\tSbyteProp &= 5;\n\t\t\tc.SbyteField &= 5;\n\t\t\tc.SbyteProp &= 5;\n\t\t\ts.SbyteField &= 5;\n\t\t\ts.SbyteProp &= 5;\n\t\t\tcustomClassField.SbyteField &= 5;\n\t\t\tcustomClassField.SbyteProp &= 5;\n\t\t\totherCustomStructField.SbyteField &= 5;\n\t\t\totherCustomStructField.SbyteProp &= 5;\n\t\t\tCustomClassProp.SbyteField &= 5;\n\t\t\tCustomClassProp.SbyteProp &= 5;\n\t\t\tGetClass().SbyteField &= 5;\n\t\t\tGetClass().SbyteProp &= 5;\n#if CS70\n\t\t\tGetRefStruct().SbyteField &= 5;\n\t\t\tGetRefStruct().SbyteProp &= 5;\n\t\t\tGetRefSbyte() &= 5;\n#endif\n\t\t}\n\n\t\tpublic static void SbyteBitOrTest(sbyte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tsbyte b = 0;\n\t\t\tp |= 5;\n\t\t\tb |= 5;\n\t\t\tUse(ref b);\n\t\t\tsbyteField |= 5;\n\t\t\tSbyteProp |= 5;\n\t\t\tc.SbyteField |= 5;\n\t\t\tc.SbyteProp |= 5;\n\t\t\ts.SbyteField |= 5;\n\t\t\ts.SbyteProp |= 5;\n\t\t\tcustomClassField.SbyteField |= 5;\n\t\t\tcustomClassField.SbyteProp |= 5;\n\t\t\totherCustomStructField.SbyteField |= 5;\n\t\t\totherCustomStructField.SbyteProp |= 5;\n\t\t\tCustomClassProp.SbyteField |= 5;\n\t\t\tCustomClassProp.SbyteProp |= 5;\n\t\t\tGetClass().SbyteField |= 5;\n\t\t\tGetClass().SbyteProp |= 5;\n#if CS70\n\t\t\tGetRefStruct().SbyteField |= 5;\n\t\t\tGetRefStruct().SbyteProp |= 5;\n\t\t\tGetRefSbyte() |= 5;\n#endif\n\t\t}\n\n\t\tpublic static void SbyteBitXorTest(sbyte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tsbyte b = 0;\n\t\t\tp ^= 5;\n\t\t\tb ^= 5;\n\t\t\tUse(ref b);\n\t\t\tsbyteField ^= 5;\n\t\t\tSbyteProp ^= 5;\n\t\t\tc.SbyteField ^= 5;\n\t\t\tc.SbyteProp ^= 5;\n\t\t\ts.SbyteField ^= 5;\n\t\t\ts.SbyteProp ^= 5;\n\t\t\tcustomClassField.SbyteField ^= 5;\n\t\t\tcustomClassField.SbyteProp ^= 5;\n\t\t\totherCustomStructField.SbyteField ^= 5;\n\t\t\totherCustomStructField.SbyteProp ^= 5;\n\t\t\tCustomClassProp.SbyteField ^= 5;\n\t\t\tCustomClassProp.SbyteProp ^= 5;\n\t\t\tGetClass().SbyteField ^= 5;\n\t\t\tGetClass().SbyteProp ^= 5;\n#if CS70\n\t\t\tGetRefStruct().SbyteField ^= 5;\n\t\t\tGetRefStruct().SbyteProp ^= 5;\n\t\t\tGetRefSbyte() ^= 5;\n#endif\n\t\t}\n\n\t\tpublic static void SbytePostIncTest(sbyte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tsbyte b = 0;\n\t\t\tX(p++);\n\t\t\tX(b++);\n\t\t\tUse(ref b);\n\t\t\tX(sbyteField++);\n\t\t\tX(SbyteProp++);\n\t\t\tX(c.SbyteField++);\n\t\t\tX(c.SbyteProp++);\n\t\t\tX(s.SbyteField++);\n\t\t\tX(s.SbyteProp++);\n\t\t\tX(customClassField.SbyteField++);\n\t\t\tX(customClassField.SbyteProp++);\n\t\t\tX(otherCustomStructField.SbyteField++);\n\t\t\tX(otherCustomStructField.SbyteProp++);\n\t\t\tX(CustomClassProp.SbyteField++);\n\t\t\tX(CustomClassProp.SbyteProp++);\n\t\t\tX(GetClass().SbyteField++);\n\t\t\tX(GetClass().SbyteProp++);\n#if CS70\n\t\t\tX(GetRefStruct().SbyteField++);\n\t\t\tX(GetRefStruct().SbyteProp++);\n\t\t\tX(GetRefSbyte()++);\n#endif\n\t\t}\n\n\t\tpublic static void SbytePreIncTest(sbyte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tsbyte b = 0;\n\t\t\tX(++p);\n\t\t\tX(++b);\n\t\t\tUse(ref b);\n\t\t\tX(++sbyteField);\n\t\t\tX(++SbyteProp);\n\t\t\tX(++c.SbyteField);\n\t\t\tX(++c.SbyteProp);\n\t\t\tX(++s.SbyteField);\n\t\t\tX(++s.SbyteProp);\n\t\t\tX(++customClassField.SbyteField);\n\t\t\tX(++customClassField.SbyteProp);\n\t\t\tX(++otherCustomStructField.SbyteField);\n\t\t\tX(++otherCustomStructField.SbyteProp);\n\t\t\tX(++CustomClassProp.SbyteField);\n\t\t\tX(++CustomClassProp.SbyteProp);\n\t\t\tX(++GetClass().SbyteField);\n\t\t\tX(++GetClass().SbyteProp);\n#if CS70\n\t\t\tX(++GetRefStruct().SbyteField);\n\t\t\tX(++GetRefStruct().SbyteProp);\n\t\t\tX(++GetRefSbyte());\n#endif\n\t\t}\n\t\tpublic static void SbytePostDecTest(sbyte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tsbyte b = 0;\n\t\t\tX(p--);\n\t\t\tX(b--);\n\t\t\tUse(ref b);\n\t\t\tX(sbyteField--);\n\t\t\tX(SbyteProp--);\n\t\t\tX(c.SbyteField--);\n\t\t\tX(c.SbyteProp--);\n\t\t\tX(s.SbyteField--);\n\t\t\tX(s.SbyteProp--);\n\t\t\tX(customClassField.SbyteField--);\n\t\t\tX(customClassField.SbyteProp--);\n\t\t\tX(otherCustomStructField.SbyteField--);\n\t\t\tX(otherCustomStructField.SbyteProp--);\n\t\t\tX(CustomClassProp.SbyteField--);\n\t\t\tX(CustomClassProp.SbyteProp--);\n\t\t\tX(GetClass().SbyteField--);\n\t\t\tX(GetClass().SbyteProp--);\n#if CS70\n\t\t\tX(GetRefStruct().SbyteField--);\n\t\t\tX(GetRefStruct().SbyteProp--);\n\t\t\tX(GetRefSbyte()--);\n#endif\n\t\t}\n\n\t\tpublic static void SbytePreDecTest(sbyte p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tsbyte b = 0;\n\t\t\tX(--p);\n\t\t\tX(--b);\n\t\t\tUse(ref b);\n\t\t\tX(--sbyteField);\n\t\t\tX(--SbyteProp);\n\t\t\tX(--c.SbyteField);\n\t\t\tX(--c.SbyteProp);\n\t\t\tX(--s.SbyteField);\n\t\t\tX(--s.SbyteProp);\n\t\t\tX(--customClassField.SbyteField);\n\t\t\tX(--customClassField.SbyteProp);\n\t\t\tX(--otherCustomStructField.SbyteField);\n\t\t\tX(--otherCustomStructField.SbyteProp);\n\t\t\tX(--CustomClassProp.SbyteField);\n\t\t\tX(--CustomClassProp.SbyteProp);\n\t\t\tX(--GetClass().SbyteField);\n\t\t\tX(--GetClass().SbyteProp);\n#if CS70\n\t\t\tX(--GetRefStruct().SbyteField);\n\t\t\tX(--GetRefStruct().SbyteProp);\n\t\t\tX(--GetRefSbyte());\n#endif\n\t\t}\n\t\tpublic static void ShortAddTest(short p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tshort num = 0;\n\t\t\tp += 5;\n\t\t\tnum += 5;\n\t\t\tUse(ref num);\n\t\t\tshortField += 5;\n\t\t\tShortProp += 5;\n\t\t\tc.ShortField += 5;\n\t\t\tc.ShortProp += 5;\n\t\t\ts.ShortField += 5;\n\t\t\ts.ShortProp += 5;\n\t\t\tcustomClassField.ShortField += 5;\n\t\t\tcustomClassField.ShortProp += 5;\n\t\t\totherCustomStructField.ShortField += 5;\n\t\t\totherCustomStructField.ShortProp += 5;\n\t\t\tCustomClassProp.ShortField += 5;\n\t\t\tCustomClassProp.ShortProp += 5;\n\t\t\tGetClass().ShortField += 5;\n\t\t\tGetClass().ShortProp += 5;\n#if CS70\n\t\t\tGetRefStruct().ShortField += 5;\n\t\t\tGetRefStruct().ShortProp += 5;\n\t\t\tGetRefShort() += 5;\n#endif\n\t\t}\n\n\t\tpublic static void ShortSubtractTest(short p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tshort num = 0;\n\t\t\tp -= 5;\n\t\t\tnum -= 5;\n\t\t\tUse(ref num);\n\t\t\tshortField -= 5;\n\t\t\tShortProp -= 5;\n\t\t\tc.ShortField -= 5;\n\t\t\tc.ShortProp -= 5;\n\t\t\ts.ShortField -= 5;\n\t\t\ts.ShortProp -= 5;\n\t\t\tcustomClassField.ShortField -= 5;\n\t\t\tcustomClassField.ShortProp -= 5;\n\t\t\totherCustomStructField.ShortField -= 5;\n\t\t\totherCustomStructField.ShortProp -= 5;\n\t\t\tCustomClassProp.ShortField -= 5;\n\t\t\tCustomClassProp.ShortProp -= 5;\n\t\t\tGetClass().ShortField -= 5;\n\t\t\tGetClass().ShortProp -= 5;\n#if CS70\n\t\t\tGetRefStruct().ShortField -= 5;\n\t\t\tGetRefStruct().ShortProp -= 5;\n\t\t\tGetRefShort() -= 5;\n#endif\n\t\t}\n\n\t\tpublic static void ShortMultiplyTest(short p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tshort num = 0;\n\t\t\tp *= 5;\n\t\t\tnum *= 5;\n\t\t\tUse(ref num);\n\t\t\tshortField *= 5;\n\t\t\tShortProp *= 5;\n\t\t\tc.ShortField *= 5;\n\t\t\tc.ShortProp *= 5;\n\t\t\ts.ShortField *= 5;\n\t\t\ts.ShortProp *= 5;\n\t\t\tcustomClassField.ShortField *= 5;\n\t\t\tcustomClassField.ShortProp *= 5;\n\t\t\totherCustomStructField.ShortField *= 5;\n\t\t\totherCustomStructField.ShortProp *= 5;\n\t\t\tCustomClassProp.ShortField *= 5;\n\t\t\tCustomClassProp.ShortProp *= 5;\n\t\t\tGetClass().ShortField *= 5;\n\t\t\tGetClass().ShortProp *= 5;\n#if CS70\n\t\t\tGetRefStruct().ShortField *= 5;\n\t\t\tGetRefStruct().ShortProp *= 5;\n\t\t\tGetRefShort() *= 5;\n#endif\n\t\t}\n\n\t\tpublic static void ShortDivideTest(short p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tshort num = 0;\n\t\t\tp /= 5;\n\t\t\tnum /= 5;\n\t\t\tUse(ref num);\n\t\t\tshortField /= 5;\n\t\t\tShortProp /= 5;\n\t\t\tc.ShortField /= 5;\n\t\t\tc.ShortProp /= 5;\n\t\t\ts.ShortField /= 5;\n\t\t\ts.ShortProp /= 5;\n\t\t\tcustomClassField.ShortField /= 5;\n\t\t\tcustomClassField.ShortProp /= 5;\n\t\t\totherCustomStructField.ShortField /= 5;\n\t\t\totherCustomStructField.ShortProp /= 5;\n\t\t\tCustomClassProp.ShortField /= 5;\n\t\t\tCustomClassProp.ShortProp /= 5;\n\t\t\tGetClass().ShortField /= 5;\n\t\t\tGetClass().ShortProp /= 5;\n#if CS70\n\t\t\tGetRefStruct().ShortField /= 5;\n\t\t\tGetRefStruct().ShortProp /= 5;\n\t\t\tGetRefShort() /= 5;\n#endif\n\t\t}\n\n\t\tpublic static void ShortModulusTest(short p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tshort num = 0;\n\t\t\tp %= 5;\n\t\t\tnum %= 5;\n\t\t\tUse(ref num);\n\t\t\tshortField %= 5;\n\t\t\tShortProp %= 5;\n\t\t\tc.ShortField %= 5;\n\t\t\tc.ShortProp %= 5;\n\t\t\ts.ShortField %= 5;\n\t\t\ts.ShortProp %= 5;\n\t\t\tcustomClassField.ShortField %= 5;\n\t\t\tcustomClassField.ShortProp %= 5;\n\t\t\totherCustomStructField.ShortField %= 5;\n\t\t\totherCustomStructField.ShortProp %= 5;\n\t\t\tCustomClassProp.ShortField %= 5;\n\t\t\tCustomClassProp.ShortProp %= 5;\n\t\t\tGetClass().ShortField %= 5;\n\t\t\tGetClass().ShortProp %= 5;\n#if CS70\n\t\t\tGetRefStruct().ShortField %= 5;\n\t\t\tGetRefStruct().ShortProp %= 5;\n\t\t\tGetRefShort() %= 5;\n#endif\n\t\t}\n\n\t\tpublic static void ShortLeftShiftTest(short p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tshort num = 0;\n\t\t\tp <<= 5;\n\t\t\tnum <<= 5;\n\t\t\tUse(ref num);\n\t\t\tshortField <<= 5;\n\t\t\tShortProp <<= 5;\n\t\t\tc.ShortField <<= 5;\n\t\t\tc.ShortProp <<= 5;\n\t\t\ts.ShortField <<= 5;\n\t\t\ts.ShortProp <<= 5;\n\t\t\tcustomClassField.ShortField <<= 5;\n\t\t\tcustomClassField.ShortProp <<= 5;\n\t\t\totherCustomStructField.ShortField <<= 5;\n\t\t\totherCustomStructField.ShortProp <<= 5;\n\t\t\tCustomClassProp.ShortField <<= 5;\n\t\t\tCustomClassProp.ShortProp <<= 5;\n\t\t\tGetClass().ShortField <<= 5;\n\t\t\tGetClass().ShortProp <<= 5;\n#if CS70\n\t\t\tGetRefStruct().ShortField <<= 5;\n\t\t\tGetRefStruct().ShortProp <<= 5;\n\t\t\tGetRefShort() <<= 5;\n#endif\n\t\t}\n\n\t\tpublic static void ShortRightShiftTest(short p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tshort num = 0;\n\t\t\tp >>= 5;\n\t\t\tnum >>= 5;\n\t\t\tUse(ref num);\n\t\t\tshortField >>= 5;\n\t\t\tShortProp >>= 5;\n\t\t\tc.ShortField >>= 5;\n\t\t\tc.ShortProp >>= 5;\n\t\t\ts.ShortField >>= 5;\n\t\t\ts.ShortProp >>= 5;\n\t\t\tcustomClassField.ShortField >>= 5;\n\t\t\tcustomClassField.ShortProp >>= 5;\n\t\t\totherCustomStructField.ShortField >>= 5;\n\t\t\totherCustomStructField.ShortProp >>= 5;\n\t\t\tCustomClassProp.ShortField >>= 5;\n\t\t\tCustomClassProp.ShortProp >>= 5;\n\t\t\tGetClass().ShortField >>= 5;\n\t\t\tGetClass().ShortProp >>= 5;\n#if CS70\n\t\t\tGetRefStruct().ShortField >>= 5;\n\t\t\tGetRefStruct().ShortProp >>= 5;\n\t\t\tGetRefShort() >>= 5;\n#endif\n\t\t}\n\n#if CS110\n\t\tpublic static void ShortUnsignedRightShiftTest(short p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\t//X(p >>>= 5);\n\t\t\tshortField >>>= 5;\n\t\t\tShortProp >>>= 5;\n\t\t\tc.ShortField >>>= 5;\n\t\t\tc.ShortProp >>>= 5;\n\t\t\ts.ShortField >>>= 5;\n\t\t\ts.ShortProp >>>= 5;\n\t\t\tcustomClassField.ShortField >>>= 5;\n\t\t\tcustomClassField.ShortProp >>>= 5;\n\t\t\totherCustomStructField.ShortField >>>= 5;\n\t\t\totherCustomStructField.ShortProp >>>= 5;\n\t\t\tCustomClassProp.ShortField >>>= 5;\n\t\t\tCustomClassProp.ShortProp >>>= 5;\n\t\t\tGetClass().ShortField >>>= 5;\n\t\t\tGetClass().ShortProp >>>= 5;\n\t\t\tGetRefStruct().ShortField >>>= 5;\n\t\t\tGetRefStruct().ShortProp >>>= 5;\n\t\t\tGetRefShort() >>>= 5;\n\t\t}\n#endif\n\n\t\tpublic static void ShortBitAndTest(short p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tshort num = 0;\n\t\t\tp &= 5;\n\t\t\tnum &= 5;\n\t\t\tUse(ref num);\n\t\t\tshortField &= 5;\n\t\t\tShortProp &= 5;\n\t\t\tc.ShortField &= 5;\n\t\t\tc.ShortProp &= 5;\n\t\t\ts.ShortField &= 5;\n\t\t\ts.ShortProp &= 5;\n\t\t\tcustomClassField.ShortField &= 5;\n\t\t\tcustomClassField.ShortProp &= 5;\n\t\t\totherCustomStructField.ShortField &= 5;\n\t\t\totherCustomStructField.ShortProp &= 5;\n\t\t\tCustomClassProp.ShortField &= 5;\n\t\t\tCustomClassProp.ShortProp &= 5;\n\t\t\tGetClass().ShortField &= 5;\n\t\t\tGetClass().ShortProp &= 5;\n#if CS70\n\t\t\tGetRefStruct().ShortField &= 5;\n\t\t\tGetRefStruct().ShortProp &= 5;\n\t\t\tGetRefShort() &= 5;\n#endif\n\t\t}\n\n\t\tpublic static void ShortBitOrTest(short p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tshort num = 0;\n\t\t\tp |= 5;\n\t\t\tnum |= 5;\n\t\t\tUse(ref num);\n\t\t\tshortField |= 5;\n\t\t\tShortProp |= 5;\n\t\t\tc.ShortField |= 5;\n\t\t\tc.ShortProp |= 5;\n\t\t\ts.ShortField |= 5;\n\t\t\ts.ShortProp |= 5;\n\t\t\tcustomClassField.ShortField |= 5;\n\t\t\tcustomClassField.ShortProp |= 5;\n\t\t\totherCustomStructField.ShortField |= 5;\n\t\t\totherCustomStructField.ShortProp |= 5;\n\t\t\tCustomClassProp.ShortField |= 5;\n\t\t\tCustomClassProp.ShortProp |= 5;\n\t\t\tGetClass().ShortField |= 5;\n\t\t\tGetClass().ShortProp |= 5;\n#if CS70\n\t\t\tGetRefStruct().ShortField |= 5;\n\t\t\tGetRefStruct().ShortProp |= 5;\n\t\t\tGetRefShort() |= 5;\n#endif\n\t\t}\n\n\t\tpublic static void ShortBitXorTest(short p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tshort num = 0;\n\t\t\tp ^= 5;\n\t\t\tnum ^= 5;\n\t\t\tUse(ref num);\n\t\t\tshortField ^= 5;\n\t\t\tShortProp ^= 5;\n\t\t\tc.ShortField ^= 5;\n\t\t\tc.ShortProp ^= 5;\n\t\t\ts.ShortField ^= 5;\n\t\t\ts.ShortProp ^= 5;\n\t\t\tcustomClassField.ShortField ^= 5;\n\t\t\tcustomClassField.ShortProp ^= 5;\n\t\t\totherCustomStructField.ShortField ^= 5;\n\t\t\totherCustomStructField.ShortProp ^= 5;\n\t\t\tCustomClassProp.ShortField ^= 5;\n\t\t\tCustomClassProp.ShortProp ^= 5;\n\t\t\tGetClass().ShortField ^= 5;\n\t\t\tGetClass().ShortProp ^= 5;\n#if CS70\n\t\t\tGetRefStruct().ShortField ^= 5;\n\t\t\tGetRefStruct().ShortProp ^= 5;\n\t\t\tGetRefShort() ^= 5;\n#endif\n\t\t}\n\n\t\tpublic static void ShortPostIncTest(short p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tshort num = 0;\n\t\t\tX(p++);\n\t\t\tX(num++);\n\t\t\tUse(ref num);\n\t\t\tX(shortField++);\n\t\t\tX(ShortProp++);\n\t\t\tX(c.ShortField++);\n\t\t\tX(c.ShortProp++);\n\t\t\tX(s.ShortField++);\n\t\t\tX(s.ShortProp++);\n\t\t\tX(customClassField.ShortField++);\n\t\t\tX(customClassField.ShortProp++);\n\t\t\tX(otherCustomStructField.ShortField++);\n\t\t\tX(otherCustomStructField.ShortProp++);\n\t\t\tX(CustomClassProp.ShortField++);\n\t\t\tX(CustomClassProp.ShortProp++);\n\t\t\tX(GetClass().ShortField++);\n\t\t\tX(GetClass().ShortProp++);\n#if CS70\n\t\t\tX(GetRefStruct().ShortField++);\n\t\t\tX(GetRefStruct().ShortProp++);\n\t\t\tX(GetRefShort()++);\n#endif\n\t\t}\n\n\t\tpublic static void ShortPreIncTest(short p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tshort num = 0;\n\t\t\tX(++p);\n\t\t\tX(++num);\n\t\t\tUse(ref num);\n\t\t\tX(++shortField);\n\t\t\tX(++ShortProp);\n\t\t\tX(++c.ShortField);\n\t\t\tX(++c.ShortProp);\n\t\t\tX(++s.ShortField);\n\t\t\tX(++s.ShortProp);\n\t\t\tX(++customClassField.ShortField);\n\t\t\tX(++customClassField.ShortProp);\n\t\t\tX(++otherCustomStructField.ShortField);\n\t\t\tX(++otherCustomStructField.ShortProp);\n\t\t\tX(++CustomClassProp.ShortField);\n\t\t\tX(++CustomClassProp.ShortProp);\n\t\t\tX(++GetClass().ShortField);\n\t\t\tX(++GetClass().ShortProp);\n#if CS70\n\t\t\tX(++GetRefStruct().ShortField);\n\t\t\tX(++GetRefStruct().ShortProp);\n\t\t\tX(++GetRefShort());\n#endif\n\t\t}\n\t\tpublic static void ShortPostDecTest(short p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tshort num = 0;\n\t\t\tX(p--);\n\t\t\tX(num--);\n\t\t\tUse(ref num);\n\t\t\tX(shortField--);\n\t\t\tX(ShortProp--);\n\t\t\tX(c.ShortField--);\n\t\t\tX(c.ShortProp--);\n\t\t\tX(s.ShortField--);\n\t\t\tX(s.ShortProp--);\n\t\t\tX(customClassField.ShortField--);\n\t\t\tX(customClassField.ShortProp--);\n\t\t\tX(otherCustomStructField.ShortField--);\n\t\t\tX(otherCustomStructField.ShortProp--);\n\t\t\tX(CustomClassProp.ShortField--);\n\t\t\tX(CustomClassProp.ShortProp--);\n\t\t\tX(GetClass().ShortField--);\n\t\t\tX(GetClass().ShortProp--);\n#if CS70\n\t\t\tX(GetRefStruct().ShortField--);\n\t\t\tX(GetRefStruct().ShortProp--);\n\t\t\tX(GetRefShort()--);\n#endif\n\t\t}\n\n\t\tpublic static void ShortPreDecTest(short p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tshort num = 0;\n\t\t\tX(--p);\n\t\t\tX(--num);\n\t\t\tUse(ref num);\n\t\t\tX(--shortField);\n\t\t\tX(--ShortProp);\n\t\t\tX(--c.ShortField);\n\t\t\tX(--c.ShortProp);\n\t\t\tX(--s.ShortField);\n\t\t\tX(--s.ShortProp);\n\t\t\tX(--customClassField.ShortField);\n\t\t\tX(--customClassField.ShortProp);\n\t\t\tX(--otherCustomStructField.ShortField);\n\t\t\tX(--otherCustomStructField.ShortProp);\n\t\t\tX(--CustomClassProp.ShortField);\n\t\t\tX(--CustomClassProp.ShortProp);\n\t\t\tX(--GetClass().ShortField);\n\t\t\tX(--GetClass().ShortProp);\n#if CS70\n\t\t\tX(--GetRefStruct().ShortField);\n\t\t\tX(--GetRefStruct().ShortProp);\n\t\t\tX(--GetRefShort());\n#endif\n\t\t}\n\t\tpublic static void UshortAddTest(ushort p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tushort num = 0;\n\t\t\tp += 5;\n\t\t\tnum += 5;\n\t\t\tUse(ref num);\n\t\t\tushortField += 5;\n\t\t\tUshortProp += 5;\n\t\t\tc.UshortField += 5;\n\t\t\tc.UshortProp += 5;\n\t\t\ts.UshortField += 5;\n\t\t\ts.UshortProp += 5;\n\t\t\tcustomClassField.UshortField += 5;\n\t\t\tcustomClassField.UshortProp += 5;\n\t\t\totherCustomStructField.UshortField += 5;\n\t\t\totherCustomStructField.UshortProp += 5;\n\t\t\tCustomClassProp.UshortField += 5;\n\t\t\tCustomClassProp.UshortProp += 5;\n\t\t\tGetClass().UshortField += 5;\n\t\t\tGetClass().UshortProp += 5;\n#if CS70\n\t\t\tGetRefStruct().UshortField += 5;\n\t\t\tGetRefStruct().UshortProp += 5;\n\t\t\tGetRefUshort() += 5;\n#endif\n\t\t}\n\n\t\tpublic static void UshortSubtractTest(ushort p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tushort num = 0;\n\t\t\tp -= 5;\n\t\t\tnum -= 5;\n\t\t\tUse(ref num);\n\t\t\tushortField -= 5;\n\t\t\tUshortProp -= 5;\n\t\t\tc.UshortField -= 5;\n\t\t\tc.UshortProp -= 5;\n\t\t\ts.UshortField -= 5;\n\t\t\ts.UshortProp -= 5;\n\t\t\tcustomClassField.UshortField -= 5;\n\t\t\tcustomClassField.UshortProp -= 5;\n\t\t\totherCustomStructField.UshortField -= 5;\n\t\t\totherCustomStructField.UshortProp -= 5;\n\t\t\tCustomClassProp.UshortField -= 5;\n\t\t\tCustomClassProp.UshortProp -= 5;\n\t\t\tGetClass().UshortField -= 5;\n\t\t\tGetClass().UshortProp -= 5;\n#if CS70\n\t\t\tGetRefStruct().UshortField -= 5;\n\t\t\tGetRefStruct().UshortProp -= 5;\n\t\t\tGetRefUshort() -= 5;\n#endif\n\t\t}\n\n\t\tpublic static void UshortMultiplyTest(ushort p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tushort num = 0;\n\t\t\tp *= 5;\n\t\t\tnum *= 5;\n\t\t\tUse(ref num);\n\t\t\tushortField *= 5;\n\t\t\tUshortProp *= 5;\n\t\t\tc.UshortField *= 5;\n\t\t\tc.UshortProp *= 5;\n\t\t\ts.UshortField *= 5;\n\t\t\ts.UshortProp *= 5;\n\t\t\tcustomClassField.UshortField *= 5;\n\t\t\tcustomClassField.UshortProp *= 5;\n\t\t\totherCustomStructField.UshortField *= 5;\n\t\t\totherCustomStructField.UshortProp *= 5;\n\t\t\tCustomClassProp.UshortField *= 5;\n\t\t\tCustomClassProp.UshortProp *= 5;\n\t\t\tGetClass().UshortField *= 5;\n\t\t\tGetClass().UshortProp *= 5;\n#if CS70\n\t\t\tGetRefStruct().UshortField *= 5;\n\t\t\tGetRefStruct().UshortProp *= 5;\n\t\t\tGetRefUshort() *= 5;\n#endif\n\t\t}\n\n\t\tpublic static void UshortDivideTest(ushort p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tushort num = 0;\n\t\t\tp /= 5;\n\t\t\tnum /= 5;\n\t\t\tUse(ref num);\n\t\t\tushortField /= 5;\n\t\t\tUshortProp /= 5;\n\t\t\tc.UshortField /= 5;\n\t\t\tc.UshortProp /= 5;\n\t\t\ts.UshortField /= 5;\n\t\t\ts.UshortProp /= 5;\n\t\t\tcustomClassField.UshortField /= 5;\n\t\t\tcustomClassField.UshortProp /= 5;\n\t\t\totherCustomStructField.UshortField /= 5;\n\t\t\totherCustomStructField.UshortProp /= 5;\n\t\t\tCustomClassProp.UshortField /= 5;\n\t\t\tCustomClassProp.UshortProp /= 5;\n\t\t\tGetClass().UshortField /= 5;\n\t\t\tGetClass().UshortProp /= 5;\n#if CS70\n\t\t\tGetRefStruct().UshortField /= 5;\n\t\t\tGetRefStruct().UshortProp /= 5;\n\t\t\tGetRefUshort() /= 5;\n#endif\n\t\t}\n\n\t\tpublic static void UshortModulusTest(ushort p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tushort num = 0;\n\t\t\tp %= 5;\n\t\t\tnum %= 5;\n\t\t\tUse(ref num);\n\t\t\tushortField %= 5;\n\t\t\tUshortProp %= 5;\n\t\t\tc.UshortField %= 5;\n\t\t\tc.UshortProp %= 5;\n\t\t\ts.UshortField %= 5;\n\t\t\ts.UshortProp %= 5;\n\t\t\tcustomClassField.UshortField %= 5;\n\t\t\tcustomClassField.UshortProp %= 5;\n\t\t\totherCustomStructField.UshortField %= 5;\n\t\t\totherCustomStructField.UshortProp %= 5;\n\t\t\tCustomClassProp.UshortField %= 5;\n\t\t\tCustomClassProp.UshortProp %= 5;\n\t\t\tGetClass().UshortField %= 5;\n\t\t\tGetClass().UshortProp %= 5;\n#if CS70\n\t\t\tGetRefStruct().UshortField %= 5;\n\t\t\tGetRefStruct().UshortProp %= 5;\n\t\t\tGetRefUshort() %= 5;\n#endif\n\t\t}\n\n\t\tpublic static void UshortLeftShiftTest(ushort p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tushort num = 0;\n\t\t\tp <<= 5;\n\t\t\tnum <<= 5;\n\t\t\tUse(ref num);\n\t\t\tushortField <<= 5;\n\t\t\tUshortProp <<= 5;\n\t\t\tc.UshortField <<= 5;\n\t\t\tc.UshortProp <<= 5;\n\t\t\ts.UshortField <<= 5;\n\t\t\ts.UshortProp <<= 5;\n\t\t\tcustomClassField.UshortField <<= 5;\n\t\t\tcustomClassField.UshortProp <<= 5;\n\t\t\totherCustomStructField.UshortField <<= 5;\n\t\t\totherCustomStructField.UshortProp <<= 5;\n\t\t\tCustomClassProp.UshortField <<= 5;\n\t\t\tCustomClassProp.UshortProp <<= 5;\n\t\t\tGetClass().UshortField <<= 5;\n\t\t\tGetClass().UshortProp <<= 5;\n#if CS70\n\t\t\tGetRefStruct().UshortField <<= 5;\n\t\t\tGetRefStruct().UshortProp <<= 5;\n\t\t\tGetRefUshort() <<= 5;\n#endif\n\t\t}\n\n\t\tpublic static void UshortRightShiftTest(ushort p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tushort num = 0;\n\t\t\tp >>= 5;\n\t\t\tnum >>= 5;\n\t\t\tUse(ref num);\n\t\t\tushortField >>= 5;\n\t\t\tUshortProp >>= 5;\n\t\t\tc.UshortField >>= 5;\n\t\t\tc.UshortProp >>= 5;\n\t\t\ts.UshortField >>= 5;\n\t\t\ts.UshortProp >>= 5;\n\t\t\tcustomClassField.UshortField >>= 5;\n\t\t\tcustomClassField.UshortProp >>= 5;\n\t\t\totherCustomStructField.UshortField >>= 5;\n\t\t\totherCustomStructField.UshortProp >>= 5;\n\t\t\tCustomClassProp.UshortField >>= 5;\n\t\t\tCustomClassProp.UshortProp >>= 5;\n\t\t\tGetClass().UshortField >>= 5;\n\t\t\tGetClass().UshortProp >>= 5;\n#if CS70\n\t\t\tGetRefStruct().UshortField >>= 5;\n\t\t\tGetRefStruct().UshortProp >>= 5;\n\t\t\tGetRefUshort() >>= 5;\n#endif\n\t\t}\n\n#if CS110\n\t\tpublic static void UshortUnsignedRightShiftTest(ushort p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\t//ushort l = 0;\n\t\t\t//p >>>= 5;\n\t\t\t//l >>>= 5;\n\t\t\tushortField >>>= 5;\n\t\t\tUshortProp >>>= 5;\n\t\t\tc.UshortField >>>= 5;\n\t\t\tc.UshortProp >>>= 5;\n\t\t\ts.UshortField >>>= 5;\n\t\t\ts.UshortProp >>>= 5;\n\t\t\tcustomClassField.UshortField >>>= 5;\n\t\t\tcustomClassField.UshortProp >>>= 5;\n\t\t\totherCustomStructField.UshortField >>>= 5;\n\t\t\totherCustomStructField.UshortProp >>>= 5;\n\t\t\tCustomClassProp.UshortField >>>= 5;\n\t\t\tCustomClassProp.UshortProp >>>= 5;\n\t\t\tGetClass().UshortField >>>= 5;\n\t\t\tGetClass().UshortProp >>>= 5;\n\t\t\tGetRefStruct().UshortField >>>= 5;\n\t\t\tGetRefStruct().UshortProp >>>= 5;\n\t\t\tGetRefUshort() >>>= 5;\n\t\t}\n#endif\n\n\t\tpublic static void UshortBitAndTest(ushort p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tushort num = 0;\n\t\t\tp &= c.UshortField;\n\t\t\tnum &= c.UshortField;\n\t\t\tUse(ref num);\n\t\t\tushortField &= 5;\n\t\t\tUshortProp &= 5;\n\t\t\tc.UshortField &= 5;\n\t\t\tc.UshortProp &= 5;\n\t\t\ts.UshortField &= 5;\n\t\t\ts.UshortProp &= 5;\n\t\t\tcustomClassField.UshortField &= 5;\n\t\t\tcustomClassField.UshortProp &= 5;\n\t\t\totherCustomStructField.UshortField &= 5;\n\t\t\totherCustomStructField.UshortProp &= 5;\n\t\t\tCustomClassProp.UshortField &= 5;\n\t\t\tCustomClassProp.UshortProp &= 5;\n\t\t\tGetClass().UshortField &= 5;\n\t\t\tGetClass().UshortProp &= 5;\n#if CS70\n\t\t\tGetRefStruct().UshortField &= 5;\n\t\t\tGetRefStruct().UshortProp &= 5;\n\t\t\tGetRefUshort() &= 5;\n#endif\n\t\t}\n\n\t\tpublic static void UshortBitOrTest(ushort p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tushort num = 0;\n\t\t\tp |= c.UshortField;\n\t\t\tnum |= c.UshortField;\n\t\t\tUse(ref num);\n\t\t\tushortField |= 5;\n\t\t\tUshortProp |= 5;\n\t\t\tc.UshortField |= 5;\n\t\t\tc.UshortProp |= 5;\n\t\t\ts.UshortField |= 5;\n\t\t\ts.UshortProp |= 5;\n\t\t\tcustomClassField.UshortField |= 5;\n\t\t\tcustomClassField.UshortProp |= 5;\n\t\t\totherCustomStructField.UshortField |= 5;\n\t\t\totherCustomStructField.UshortProp |= 5;\n\t\t\tCustomClassProp.UshortField |= 5;\n\t\t\tCustomClassProp.UshortProp |= 5;\n\t\t\tGetClass().UshortField |= 5;\n\t\t\tGetClass().UshortProp |= 5;\n#if CS70\n\t\t\tGetRefStruct().UshortField |= 5;\n\t\t\tGetRefStruct().UshortProp |= 5;\n\t\t\tGetRefUshort() |= 5;\n#endif\n\t\t}\n\n\t\tpublic static void UshortBitXorTest(ushort p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tushort num = 0;\n\t\t\tp ^= c.UshortField;\n\t\t\tnum ^= c.UshortField;\n\t\t\tUse(ref num);\n\t\t\tushortField ^= 5;\n\t\t\tUshortProp ^= 5;\n\t\t\tc.UshortField ^= 5;\n\t\t\tc.UshortProp ^= 5;\n\t\t\ts.UshortField ^= 5;\n\t\t\ts.UshortProp ^= 5;\n\t\t\tcustomClassField.UshortField ^= 5;\n\t\t\tcustomClassField.UshortProp ^= 5;\n\t\t\totherCustomStructField.UshortField ^= 5;\n\t\t\totherCustomStructField.UshortProp ^= 5;\n\t\t\tCustomClassProp.UshortField ^= 5;\n\t\t\tCustomClassProp.UshortProp ^= 5;\n\t\t\tGetClass().UshortField ^= 5;\n\t\t\tGetClass().UshortProp ^= 5;\n#if CS70\n\t\t\tGetRefStruct().UshortField ^= 5;\n\t\t\tGetRefStruct().UshortProp ^= 5;\n\t\t\tGetRefUshort() ^= 5;\n#endif\n\t\t}\n\n\t\tpublic static void UshortPostIncTest(ushort p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tushort num = 0;\n\t\t\tX(p++);\n\t\t\tX(num++);\n\t\t\tUse(ref num);\n\t\t\tX(ushortField++);\n\t\t\tX(UshortProp++);\n\t\t\tX(c.UshortField++);\n\t\t\tX(c.UshortProp++);\n\t\t\tX(s.UshortField++);\n\t\t\tX(s.UshortProp++);\n\t\t\tX(customClassField.UshortField++);\n\t\t\tX(customClassField.UshortProp++);\n\t\t\tX(otherCustomStructField.UshortField++);\n\t\t\tX(otherCustomStructField.UshortProp++);\n\t\t\tX(CustomClassProp.UshortField++);\n\t\t\tX(CustomClassProp.UshortProp++);\n\t\t\tX(GetClass().UshortField++);\n\t\t\tX(GetClass().UshortProp++);\n#if CS70\n\t\t\tX(GetRefStruct().UshortField++);\n\t\t\tX(GetRefStruct().UshortProp++);\n\t\t\tX(GetRefUshort()++);\n#endif\n\t\t}\n\n\t\tpublic static void UshortPreIncTest(ushort p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tushort num = 0;\n\t\t\tX(++p);\n\t\t\tX(++num);\n\t\t\tUse(ref num);\n\t\t\tX(++ushortField);\n\t\t\tX(++UshortProp);\n\t\t\tX(++c.UshortField);\n\t\t\tX(++c.UshortProp);\n\t\t\tX(++s.UshortField);\n\t\t\tX(++s.UshortProp);\n\t\t\tX(++customClassField.UshortField);\n\t\t\tX(++customClassField.UshortProp);\n\t\t\tX(++otherCustomStructField.UshortField);\n\t\t\tX(++otherCustomStructField.UshortProp);\n\t\t\tX(++CustomClassProp.UshortField);\n\t\t\tX(++CustomClassProp.UshortProp);\n\t\t\tX(++GetClass().UshortField);\n\t\t\tX(++GetClass().UshortProp);\n#if CS70\n\t\t\tX(++GetRefStruct().UshortField);\n\t\t\tX(++GetRefStruct().UshortProp);\n\t\t\tX(++GetRefUshort());\n#endif\n\t\t}\n\t\tpublic static void UshortPostDecTest(ushort p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tushort num = 0;\n\t\t\tX(p--);\n\t\t\tX(num--);\n\t\t\tUse(ref num);\n\t\t\tX(ushortField--);\n\t\t\tX(UshortProp--);\n\t\t\tX(c.UshortField--);\n\t\t\tX(c.UshortProp--);\n\t\t\tX(s.UshortField--);\n\t\t\tX(s.UshortProp--);\n\t\t\tX(customClassField.UshortField--);\n\t\t\tX(customClassField.UshortProp--);\n\t\t\tX(otherCustomStructField.UshortField--);\n\t\t\tX(otherCustomStructField.UshortProp--);\n\t\t\tX(CustomClassProp.UshortField--);\n\t\t\tX(CustomClassProp.UshortProp--);\n\t\t\tX(GetClass().UshortField--);\n\t\t\tX(GetClass().UshortProp--);\n#if CS70\n\t\t\tX(GetRefStruct().UshortField--);\n\t\t\tX(GetRefStruct().UshortProp--);\n\t\t\tX(GetRefUshort()--);\n#endif\n\t\t}\n\n\t\tpublic static void UshortPreDecTest(ushort p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tushort num = 0;\n\t\t\tX(--p);\n\t\t\tX(--num);\n\t\t\tUse(ref num);\n\t\t\tX(--ushortField);\n\t\t\tX(--UshortProp);\n\t\t\tX(--c.UshortField);\n\t\t\tX(--c.UshortProp);\n\t\t\tX(--s.UshortField);\n\t\t\tX(--s.UshortProp);\n\t\t\tX(--customClassField.UshortField);\n\t\t\tX(--customClassField.UshortProp);\n\t\t\tX(--otherCustomStructField.UshortField);\n\t\t\tX(--otherCustomStructField.UshortProp);\n\t\t\tX(--CustomClassProp.UshortField);\n\t\t\tX(--CustomClassProp.UshortProp);\n\t\t\tX(--GetClass().UshortField);\n\t\t\tX(--GetClass().UshortProp);\n#if CS70\n\t\t\tX(--GetRefStruct().UshortField);\n\t\t\tX(--GetRefStruct().UshortProp);\n\t\t\tX(--GetRefUshort());\n#endif\n\t\t}\n\t\tpublic static void IntAddTest(int p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tint num = 0;\n\t\t\tp += 5;\n\t\t\tnum += 5;\n\t\t\tUse(ref num);\n\t\t\tintField += 5;\n\t\t\tIntProp += 5;\n\t\t\tc.IntField += 5;\n\t\t\tc.IntProp += 5;\n\t\t\ts.IntField += 5;\n\t\t\ts.IntProp += 5;\n\t\t\tcustomClassField.IntField += 5;\n\t\t\tcustomClassField.IntProp += 5;\n\t\t\totherCustomStructField.IntField += 5;\n\t\t\totherCustomStructField.IntProp += 5;\n\t\t\tCustomClassProp.IntField += 5;\n\t\t\tCustomClassProp.IntProp += 5;\n\t\t\tGetClass().IntField += 5;\n\t\t\tGetClass().IntProp += 5;\n#if CS70\n\t\t\tGetRefStruct().IntField += 5;\n\t\t\tGetRefStruct().IntProp += 5;\n\t\t\tGetRefInt() += 5;\n#endif\n\t\t}\n\n\t\tpublic static void IntSubtractTest(int p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tint num = 0;\n\t\t\tp -= 5;\n\t\t\tnum -= 5;\n\t\t\tUse(ref num);\n\t\t\tintField -= 5;\n\t\t\tIntProp -= 5;\n\t\t\tc.IntField -= 5;\n\t\t\tc.IntProp -= 5;\n\t\t\ts.IntField -= 5;\n\t\t\ts.IntProp -= 5;\n\t\t\tcustomClassField.IntField -= 5;\n\t\t\tcustomClassField.IntProp -= 5;\n\t\t\totherCustomStructField.IntField -= 5;\n\t\t\totherCustomStructField.IntProp -= 5;\n\t\t\tCustomClassProp.IntField -= 5;\n\t\t\tCustomClassProp.IntProp -= 5;\n\t\t\tGetClass().IntField -= 5;\n\t\t\tGetClass().IntProp -= 5;\n#if CS70\n\t\t\tGetRefStruct().IntField -= 5;\n\t\t\tGetRefStruct().IntProp -= 5;\n\t\t\tGetRefInt() -= 5;\n#endif\n\t\t}\n\n\t\tpublic static void IntMultiplyTest(int p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tint num = 0;\n\t\t\tp *= 5;\n\t\t\tnum *= 5;\n\t\t\tUse(ref num);\n\t\t\tintField *= 5;\n\t\t\tIntProp *= 5;\n\t\t\tc.IntField *= 5;\n\t\t\tc.IntProp *= 5;\n\t\t\ts.IntField *= 5;\n\t\t\ts.IntProp *= 5;\n\t\t\tcustomClassField.IntField *= 5;\n\t\t\tcustomClassField.IntProp *= 5;\n\t\t\totherCustomStructField.IntField *= 5;\n\t\t\totherCustomStructField.IntProp *= 5;\n\t\t\tCustomClassProp.IntField *= 5;\n\t\t\tCustomClassProp.IntProp *= 5;\n\t\t\tGetClass().IntField *= 5;\n\t\t\tGetClass().IntProp *= 5;\n#if CS70\n\t\t\tGetRefStruct().IntField *= 5;\n\t\t\tGetRefStruct().IntProp *= 5;\n\t\t\tGetRefInt() *= 5;\n#endif\n\t\t}\n\n\t\tpublic static void IntDivideTest(int p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tint num = 0;\n\t\t\tp /= 5;\n\t\t\tnum /= 5;\n\t\t\tUse(ref num);\n\t\t\tintField /= 5;\n\t\t\tIntProp /= 5;\n\t\t\tc.IntField /= 5;\n\t\t\tc.IntProp /= 5;\n\t\t\ts.IntField /= 5;\n\t\t\ts.IntProp /= 5;\n\t\t\tcustomClassField.IntField /= 5;\n\t\t\tcustomClassField.IntProp /= 5;\n\t\t\totherCustomStructField.IntField /= 5;\n\t\t\totherCustomStructField.IntProp /= 5;\n\t\t\tCustomClassProp.IntField /= 5;\n\t\t\tCustomClassProp.IntProp /= 5;\n\t\t\tGetClass().IntField /= 5;\n\t\t\tGetClass().IntProp /= 5;\n#if CS70\n\t\t\tGetRefStruct().IntField /= 5;\n\t\t\tGetRefStruct().IntProp /= 5;\n\t\t\tGetRefInt() /= 5;\n#endif\n\t\t}\n\n\t\tpublic static void IntModulusTest(int p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tint num = 0;\n\t\t\tp %= 5;\n\t\t\tnum %= 5;\n\t\t\tUse(ref num);\n\t\t\tintField %= 5;\n\t\t\tIntProp %= 5;\n\t\t\tc.IntField %= 5;\n\t\t\tc.IntProp %= 5;\n\t\t\ts.IntField %= 5;\n\t\t\ts.IntProp %= 5;\n\t\t\tcustomClassField.IntField %= 5;\n\t\t\tcustomClassField.IntProp %= 5;\n\t\t\totherCustomStructField.IntField %= 5;\n\t\t\totherCustomStructField.IntProp %= 5;\n\t\t\tCustomClassProp.IntField %= 5;\n\t\t\tCustomClassProp.IntProp %= 5;\n\t\t\tGetClass().IntField %= 5;\n\t\t\tGetClass().IntProp %= 5;\n#if CS70\n\t\t\tGetRefStruct().IntField %= 5;\n\t\t\tGetRefStruct().IntProp %= 5;\n\t\t\tGetRefInt() %= 5;\n#endif\n\t\t}\n\n\t\tpublic static void IntLeftShiftTest(int p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tint num = 0;\n\t\t\tp <<= 5;\n\t\t\tnum <<= 5;\n\t\t\tUse(ref num);\n\t\t\tintField <<= 5;\n\t\t\tIntProp <<= 5;\n\t\t\tc.IntField <<= 5;\n\t\t\tc.IntProp <<= 5;\n\t\t\ts.IntField <<= 5;\n\t\t\ts.IntProp <<= 5;\n\t\t\tcustomClassField.IntField <<= 5;\n\t\t\tcustomClassField.IntProp <<= 5;\n\t\t\totherCustomStructField.IntField <<= 5;\n\t\t\totherCustomStructField.IntProp <<= 5;\n\t\t\tCustomClassProp.IntField <<= 5;\n\t\t\tCustomClassProp.IntProp <<= 5;\n\t\t\tGetClass().IntField <<= 5;\n\t\t\tGetClass().IntProp <<= 5;\n#if CS70\n\t\t\tGetRefStruct().IntField <<= 5;\n\t\t\tGetRefStruct().IntProp <<= 5;\n\t\t\tGetRefInt() <<= 5;\n#endif\n\t\t}\n\n\t\tpublic static void IntRightShiftTest(int p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tint num = 0;\n\t\t\tp >>= 5;\n\t\t\tnum >>= 5;\n\t\t\tUse(ref num);\n\t\t\tintField >>= 5;\n\t\t\tIntProp >>= 5;\n\t\t\tc.IntField >>= 5;\n\t\t\tc.IntProp >>= 5;\n\t\t\ts.IntField >>= 5;\n\t\t\ts.IntProp >>= 5;\n\t\t\tcustomClassField.IntField >>= 5;\n\t\t\tcustomClassField.IntProp >>= 5;\n\t\t\totherCustomStructField.IntField >>= 5;\n\t\t\totherCustomStructField.IntProp >>= 5;\n\t\t\tCustomClassProp.IntField >>= 5;\n\t\t\tCustomClassProp.IntProp >>= 5;\n\t\t\tGetClass().IntField >>= 5;\n\t\t\tGetClass().IntProp >>= 5;\n#if CS70\n\t\t\tGetRefStruct().IntField >>= 5;\n\t\t\tGetRefStruct().IntProp >>= 5;\n\t\t\tGetRefInt() >>= 5;\n#endif\n\t\t}\n\n#if CS110\n\t\tpublic static void IntUnsignedRightShiftTest(int p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tX(p >>>= 5);\n\t\t\tintField >>>= 5;\n\t\t\tIntProp >>>= 5;\n\t\t\tc.IntField >>>= 5;\n\t\t\tc.IntProp >>>= 5;\n\t\t\ts.IntField >>>= 5;\n\t\t\ts.IntProp >>>= 5;\n\t\t\tcustomClassField.IntField >>>= 5;\n\t\t\tcustomClassField.IntProp >>>= 5;\n\t\t\totherCustomStructField.IntField >>>= 5;\n\t\t\totherCustomStructField.IntProp >>>= 5;\n\t\t\tCustomClassProp.IntField >>>= 5;\n\t\t\tCustomClassProp.IntProp >>>= 5;\n\t\t\tGetClass().IntField >>>= 5;\n\t\t\tGetClass().IntProp >>>= 5;\n\t\t\tGetRefStruct().IntField >>>= 5;\n\t\t\tGetRefStruct().IntProp >>>= 5;\n\t\t\tGetRefInt() >>>= 5;\n\t\t}\n#endif\n\n\t\tpublic static void IntBitAndTest(int p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tint num = 0;\n\t\t\tp &= 5;\n\t\t\tnum &= 5;\n\t\t\tUse(ref num);\n\t\t\tintField &= 5;\n\t\t\tIntProp &= 5;\n\t\t\tc.IntField &= 5;\n\t\t\tc.IntProp &= 5;\n\t\t\ts.IntField &= 5;\n\t\t\ts.IntProp &= 5;\n\t\t\tcustomClassField.IntField &= 5;\n\t\t\tcustomClassField.IntProp &= 5;\n\t\t\totherCustomStructField.IntField &= 5;\n\t\t\totherCustomStructField.IntProp &= 5;\n\t\t\tCustomClassProp.IntField &= 5;\n\t\t\tCustomClassProp.IntProp &= 5;\n\t\t\tGetClass().IntField &= 5;\n\t\t\tGetClass().IntProp &= 5;\n#if CS70\n\t\t\tGetRefStruct().IntField &= 5;\n\t\t\tGetRefStruct().IntProp &= 5;\n\t\t\tGetRefInt() &= 5;\n#endif\n\t\t}\n\n\t\tpublic static void IntBitOrTest(int p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tint num = 0;\n\t\t\tp |= 5;\n\t\t\tnum |= 5;\n\t\t\tUse(ref num);\n\t\t\tintField |= 5;\n\t\t\tIntProp |= 5;\n\t\t\tc.IntField |= 5;\n\t\t\tc.IntProp |= 5;\n\t\t\ts.IntField |= 5;\n\t\t\ts.IntProp |= 5;\n\t\t\tcustomClassField.IntField |= 5;\n\t\t\tcustomClassField.IntProp |= 5;\n\t\t\totherCustomStructField.IntField |= 5;\n\t\t\totherCustomStructField.IntProp |= 5;\n\t\t\tCustomClassProp.IntField |= 5;\n\t\t\tCustomClassProp.IntProp |= 5;\n\t\t\tGetClass().IntField |= 5;\n\t\t\tGetClass().IntProp |= 5;\n#if CS70\n\t\t\tGetRefStruct().IntField |= 5;\n\t\t\tGetRefStruct().IntProp |= 5;\n\t\t\tGetRefInt() |= 5;\n#endif\n\t\t}\n\n\t\tpublic static void IntBitXorTest(int p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tint num = 0;\n\t\t\tp ^= 5;\n\t\t\tnum ^= 5;\n\t\t\tUse(ref num);\n\t\t\tintField ^= 5;\n\t\t\tIntProp ^= 5;\n\t\t\tc.IntField ^= 5;\n\t\t\tc.IntProp ^= 5;\n\t\t\ts.IntField ^= 5;\n\t\t\ts.IntProp ^= 5;\n\t\t\tcustomClassField.IntField ^= 5;\n\t\t\tcustomClassField.IntProp ^= 5;\n\t\t\totherCustomStructField.IntField ^= 5;\n\t\t\totherCustomStructField.IntProp ^= 5;\n\t\t\tCustomClassProp.IntField ^= 5;\n\t\t\tCustomClassProp.IntProp ^= 5;\n\t\t\tGetClass().IntField ^= 5;\n\t\t\tGetClass().IntProp ^= 5;\n#if CS70\n\t\t\tGetRefStruct().IntField ^= 5;\n\t\t\tGetRefStruct().IntProp ^= 5;\n\t\t\tGetRefInt() ^= 5;\n#endif\n\t\t}\n\n\t\tpublic static void IntPostIncTest(int p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tint num = 0;\n\t\t\tX(p++);\n\t\t\tX(num++);\n\t\t\tUse(ref num);\n\t\t\tX(intField++);\n\t\t\tX(IntProp++);\n\t\t\tX(c.IntField++);\n\t\t\tX(c.IntProp++);\n\t\t\tX(s.IntField++);\n\t\t\tX(s.IntProp++);\n\t\t\tX(customClassField.IntField++);\n\t\t\tX(customClassField.IntProp++);\n\t\t\tX(otherCustomStructField.IntField++);\n\t\t\tX(otherCustomStructField.IntProp++);\n\t\t\tX(CustomClassProp.IntField++);\n\t\t\tX(CustomClassProp.IntProp++);\n\t\t\tX(GetClass().IntField++);\n\t\t\tX(GetClass().IntProp++);\n#if CS70\n\t\t\tX(GetRefStruct().IntField++);\n\t\t\tX(GetRefStruct().IntProp++);\n\t\t\tX(GetRefInt()++);\n#endif\n\t\t}\n\n\t\tpublic static void IntPreIncTest(int p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tint num = 0;\n\t\t\tX(++p);\n\t\t\tX(++num);\n\t\t\tUse(ref num);\n\t\t\tX(++intField);\n\t\t\tX(++IntProp);\n\t\t\tX(++c.IntField);\n\t\t\tX(++c.IntProp);\n\t\t\tX(++s.IntField);\n\t\t\tX(++s.IntProp);\n\t\t\tX(++customClassField.IntField);\n\t\t\tX(++customClassField.IntProp);\n\t\t\tX(++otherCustomStructField.IntField);\n\t\t\tX(++otherCustomStructField.IntProp);\n\t\t\tX(++CustomClassProp.IntField);\n\t\t\tX(++CustomClassProp.IntProp);\n\t\t\tX(++GetClass().IntField);\n\t\t\tX(++GetClass().IntProp);\n#if CS70\n\t\t\tX(++GetRefStruct().IntField);\n\t\t\tX(++GetRefStruct().IntProp);\n\t\t\tX(++GetRefInt());\n#endif\n\t\t}\n\t\tpublic static void IntPostDecTest(int p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tint num = 0;\n\t\t\tX(p--);\n\t\t\tX(num--);\n\t\t\tUse(ref num);\n\t\t\tX(intField--);\n\t\t\tX(IntProp--);\n\t\t\tX(c.IntField--);\n\t\t\tX(c.IntProp--);\n\t\t\tX(s.IntField--);\n\t\t\tX(s.IntProp--);\n\t\t\tX(customClassField.IntField--);\n\t\t\tX(customClassField.IntProp--);\n\t\t\tX(otherCustomStructField.IntField--);\n\t\t\tX(otherCustomStructField.IntProp--);\n\t\t\tX(CustomClassProp.IntField--);\n\t\t\tX(CustomClassProp.IntProp--);\n\t\t\tX(GetClass().IntField--);\n\t\t\tX(GetClass().IntProp--);\n#if CS70\n\t\t\tX(GetRefStruct().IntField--);\n\t\t\tX(GetRefStruct().IntProp--);\n\t\t\tX(GetRefInt()--);\n#endif\n\t\t}\n\n\t\tpublic static void IntPreDecTest(int p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tint num = 0;\n\t\t\tX(--p);\n\t\t\tX(--num);\n\t\t\tUse(ref num);\n\t\t\tX(--intField);\n\t\t\tX(--IntProp);\n\t\t\tX(--c.IntField);\n\t\t\tX(--c.IntProp);\n\t\t\tX(--s.IntField);\n\t\t\tX(--s.IntProp);\n\t\t\tX(--customClassField.IntField);\n\t\t\tX(--customClassField.IntProp);\n\t\t\tX(--otherCustomStructField.IntField);\n\t\t\tX(--otherCustomStructField.IntProp);\n\t\t\tX(--CustomClassProp.IntField);\n\t\t\tX(--CustomClassProp.IntProp);\n\t\t\tX(--GetClass().IntField);\n\t\t\tX(--GetClass().IntProp);\n#if CS70\n\t\t\tX(--GetRefStruct().IntField);\n\t\t\tX(--GetRefStruct().IntProp);\n\t\t\tX(--GetRefInt());\n#endif\n\t\t}\n\t\tpublic static void UintAddTest(uint p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tuint num = 0u;\n\t\t\tp += 5;\n\t\t\tnum += 5;\n\t\t\tUse(ref num);\n\t\t\tuintField += 5u;\n\t\t\tUintProp += 5u;\n\t\t\tc.UintField += 5u;\n\t\t\tc.UintProp += 5u;\n\t\t\ts.UintField += 5u;\n\t\t\ts.UintProp += 5u;\n\t\t\tcustomClassField.UintField += 5u;\n\t\t\tcustomClassField.UintProp += 5u;\n\t\t\totherCustomStructField.UintField += 5u;\n\t\t\totherCustomStructField.UintProp += 5u;\n\t\t\tCustomClassProp.UintField += 5u;\n\t\t\tCustomClassProp.UintProp += 5u;\n\t\t\tGetClass().UintField += 5u;\n\t\t\tGetClass().UintProp += 5u;\n#if CS70\n\t\t\tGetRefStruct().UintField += 5u;\n\t\t\tGetRefStruct().UintProp += 5u;\n\t\t\tGetRefUint() += 5u;\n#endif\n\t\t}\n\n\t\tpublic static void UintSubtractTest(uint p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tuint num = 0u;\n\t\t\tp -= 5;\n\t\t\tnum -= 5;\n\t\t\tUse(ref num);\n\t\t\tuintField -= 5u;\n\t\t\tUintProp -= 5u;\n\t\t\tc.UintField -= 5u;\n\t\t\tc.UintProp -= 5u;\n\t\t\ts.UintField -= 5u;\n\t\t\ts.UintProp -= 5u;\n\t\t\tcustomClassField.UintField -= 5u;\n\t\t\tcustomClassField.UintProp -= 5u;\n\t\t\totherCustomStructField.UintField -= 5u;\n\t\t\totherCustomStructField.UintProp -= 5u;\n\t\t\tCustomClassProp.UintField -= 5u;\n\t\t\tCustomClassProp.UintProp -= 5u;\n\t\t\tGetClass().UintField -= 5u;\n\t\t\tGetClass().UintProp -= 5u;\n#if CS70\n\t\t\tGetRefStruct().UintField -= 5u;\n\t\t\tGetRefStruct().UintProp -= 5u;\n\t\t\tGetRefUint() -= 5u;\n#endif\n\t\t}\n\n\t\tpublic static void UintMultiplyTest(uint p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tuint num = 0u;\n\t\t\tp *= 5;\n\t\t\tnum *= 5;\n\t\t\tUse(ref num);\n\t\t\tuintField *= 5u;\n\t\t\tUintProp *= 5u;\n\t\t\tc.UintField *= 5u;\n\t\t\tc.UintProp *= 5u;\n\t\t\ts.UintField *= 5u;\n\t\t\ts.UintProp *= 5u;\n\t\t\tcustomClassField.UintField *= 5u;\n\t\t\tcustomClassField.UintProp *= 5u;\n\t\t\totherCustomStructField.UintField *= 5u;\n\t\t\totherCustomStructField.UintProp *= 5u;\n\t\t\tCustomClassProp.UintField *= 5u;\n\t\t\tCustomClassProp.UintProp *= 5u;\n\t\t\tGetClass().UintField *= 5u;\n\t\t\tGetClass().UintProp *= 5u;\n#if CS70\n\t\t\tGetRefStruct().UintField *= 5u;\n\t\t\tGetRefStruct().UintProp *= 5u;\n\t\t\tGetRefUint() *= 5u;\n#endif\n\t\t}\n\n\t\tpublic static void UintDivideTest(uint p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tuint num = 0u;\n\t\t\tp /= 5;\n\t\t\tnum /= 5;\n\t\t\tUse(ref num);\n\t\t\tuintField /= 5u;\n\t\t\tUintProp /= 5u;\n\t\t\tc.UintField /= 5u;\n\t\t\tc.UintProp /= 5u;\n\t\t\ts.UintField /= 5u;\n\t\t\ts.UintProp /= 5u;\n\t\t\tcustomClassField.UintField /= 5u;\n\t\t\tcustomClassField.UintProp /= 5u;\n\t\t\totherCustomStructField.UintField /= 5u;\n\t\t\totherCustomStructField.UintProp /= 5u;\n\t\t\tCustomClassProp.UintField /= 5u;\n\t\t\tCustomClassProp.UintProp /= 5u;\n\t\t\tGetClass().UintField /= 5u;\n\t\t\tGetClass().UintProp /= 5u;\n#if CS70\n\t\t\tGetRefStruct().UintField /= 5u;\n\t\t\tGetRefStruct().UintProp /= 5u;\n\t\t\tGetRefUint() /= 5u;\n#endif\n\t\t}\n\n\t\tpublic static void UintModulusTest(uint p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tuint num = 0u;\n\t\t\tp %= 5;\n\t\t\tnum %= 5;\n\t\t\tUse(ref num);\n\t\t\tuintField %= 5u;\n\t\t\tUintProp %= 5u;\n\t\t\tc.UintField %= 5u;\n\t\t\tc.UintProp %= 5u;\n\t\t\ts.UintField %= 5u;\n\t\t\ts.UintProp %= 5u;\n\t\t\tcustomClassField.UintField %= 5u;\n\t\t\tcustomClassField.UintProp %= 5u;\n\t\t\totherCustomStructField.UintField %= 5u;\n\t\t\totherCustomStructField.UintProp %= 5u;\n\t\t\tCustomClassProp.UintField %= 5u;\n\t\t\tCustomClassProp.UintProp %= 5u;\n\t\t\tGetClass().UintField %= 5u;\n\t\t\tGetClass().UintProp %= 5u;\n#if CS70\n\t\t\tGetRefStruct().UintField %= 5u;\n\t\t\tGetRefStruct().UintProp %= 5u;\n\t\t\tGetRefUint() %= 5u;\n#endif\n\t\t}\n\n\t\tpublic static void UintLeftShiftTest(uint p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tuint num = 0u;\n\t\t\tp <<= 5;\n\t\t\tnum <<= 5;\n\t\t\tUse(ref num);\n\t\t\tuintField <<= 5;\n\t\t\tUintProp <<= 5;\n\t\t\tc.UintField <<= 5;\n\t\t\tc.UintProp <<= 5;\n\t\t\ts.UintField <<= 5;\n\t\t\ts.UintProp <<= 5;\n\t\t\tcustomClassField.UintField <<= 5;\n\t\t\tcustomClassField.UintProp <<= 5;\n\t\t\totherCustomStructField.UintField <<= 5;\n\t\t\totherCustomStructField.UintProp <<= 5;\n\t\t\tCustomClassProp.UintField <<= 5;\n\t\t\tCustomClassProp.UintProp <<= 5;\n\t\t\tGetClass().UintField <<= 5;\n\t\t\tGetClass().UintProp <<= 5;\n#if CS70\n\t\t\tGetRefStruct().UintField <<= 5;\n\t\t\tGetRefStruct().UintProp <<= 5;\n\t\t\tGetRefUint() <<= 5;\n#endif\n\t\t}\n\n\t\tpublic static void UintRightShiftTest(uint p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tuint num = 0u;\n\t\t\tp >>= 5;\n\t\t\tnum >>= 5;\n\t\t\tUse(ref num);\n\t\t\tuintField >>= 5;\n\t\t\tUintProp >>= 5;\n\t\t\tc.UintField >>= 5;\n\t\t\tc.UintProp >>= 5;\n\t\t\ts.UintField >>= 5;\n\t\t\ts.UintProp >>= 5;\n\t\t\tcustomClassField.UintField >>= 5;\n\t\t\tcustomClassField.UintProp >>= 5;\n\t\t\totherCustomStructField.UintField >>= 5;\n\t\t\totherCustomStructField.UintProp >>= 5;\n\t\t\tCustomClassProp.UintField >>= 5;\n\t\t\tCustomClassProp.UintProp >>= 5;\n\t\t\tGetClass().UintField >>= 5;\n\t\t\tGetClass().UintProp >>= 5;\n#if CS70\n\t\t\tGetRefStruct().UintField >>= 5;\n\t\t\tGetRefStruct().UintProp >>= 5;\n\t\t\tGetRefUint() >>= 5;\n#endif\n\t\t}\n\n\t\tpublic static void UintBitAndTest(uint p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tuint num = 0u;\n\t\t\tp &= 5;\n\t\t\tnum &= 5;\n\t\t\tUse(ref num);\n\t\t\tuintField &= 5u;\n\t\t\tUintProp &= 5u;\n\t\t\tc.UintField &= 5u;\n\t\t\tc.UintProp &= 5u;\n\t\t\ts.UintField &= 5u;\n\t\t\ts.UintProp &= 5u;\n\t\t\tcustomClassField.UintField &= 5u;\n\t\t\tcustomClassField.UintProp &= 5u;\n\t\t\totherCustomStructField.UintField &= 5u;\n\t\t\totherCustomStructField.UintProp &= 5u;\n\t\t\tCustomClassProp.UintField &= 5u;\n\t\t\tCustomClassProp.UintProp &= 5u;\n\t\t\tGetClass().UintField &= 5u;\n\t\t\tGetClass().UintProp &= 5u;\n#if CS70\n\t\t\tGetRefStruct().UintField &= 5u;\n\t\t\tGetRefStruct().UintProp &= 5u;\n\t\t\tGetRefUint() &= 5u;\n#endif\n\t\t}\n\n\t\tpublic static void UintBitOrTest(uint p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tuint num = 0u;\n\t\t\tp |= 5;\n\t\t\tnum |= 5;\n\t\t\tUse(ref num);\n\t\t\tuintField |= 5u;\n\t\t\tUintProp |= 5u;\n\t\t\tc.UintField |= 5u;\n\t\t\tc.UintProp |= 5u;\n\t\t\ts.UintField |= 5u;\n\t\t\ts.UintProp |= 5u;\n\t\t\tcustomClassField.UintField |= 5u;\n\t\t\tcustomClassField.UintProp |= 5u;\n\t\t\totherCustomStructField.UintField |= 5u;\n\t\t\totherCustomStructField.UintProp |= 5u;\n\t\t\tCustomClassProp.UintField |= 5u;\n\t\t\tCustomClassProp.UintProp |= 5u;\n\t\t\tGetClass().UintField |= 5u;\n\t\t\tGetClass().UintProp |= 5u;\n#if CS70\n\t\t\tGetRefStruct().UintField |= 5u;\n\t\t\tGetRefStruct().UintProp |= 5u;\n\t\t\tGetRefUint() |= 5u;\n#endif\n\t\t}\n\n\t\tpublic static void UintBitXorTest(uint p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tuint num = 0u;\n\t\t\tp ^= 5;\n\t\t\tnum ^= 5;\n\t\t\tUse(ref num);\n\t\t\tuintField ^= 5u;\n\t\t\tUintProp ^= 5u;\n\t\t\tc.UintField ^= 5u;\n\t\t\tc.UintProp ^= 5u;\n\t\t\ts.UintField ^= 5u;\n\t\t\ts.UintProp ^= 5u;\n\t\t\tcustomClassField.UintField ^= 5u;\n\t\t\tcustomClassField.UintProp ^= 5u;\n\t\t\totherCustomStructField.UintField ^= 5u;\n\t\t\totherCustomStructField.UintProp ^= 5u;\n\t\t\tCustomClassProp.UintField ^= 5u;\n\t\t\tCustomClassProp.UintProp ^= 5u;\n\t\t\tGetClass().UintField ^= 5u;\n\t\t\tGetClass().UintProp ^= 5u;\n#if CS70\n\t\t\tGetRefStruct().UintField ^= 5u;\n\t\t\tGetRefStruct().UintProp ^= 5u;\n\t\t\tGetRefUint() ^= 5u;\n#endif\n\t\t}\n\n\t\tpublic static void UintPostIncTest(uint p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tuint num = 0u;\n\t\t\tX(p++);\n\t\t\tX(num++);\n\t\t\tUse(ref num);\n\t\t\tX(uintField++);\n\t\t\tX(UintProp++);\n\t\t\tX(c.UintField++);\n\t\t\tX(c.UintProp++);\n\t\t\tX(s.UintField++);\n\t\t\tX(s.UintProp++);\n\t\t\tX(customClassField.UintField++);\n\t\t\tX(customClassField.UintProp++);\n\t\t\tX(otherCustomStructField.UintField++);\n\t\t\tX(otherCustomStructField.UintProp++);\n\t\t\tX(CustomClassProp.UintField++);\n\t\t\tX(CustomClassProp.UintProp++);\n\t\t\tX(GetClass().UintField++);\n\t\t\tX(GetClass().UintProp++);\n#if CS70\n\t\t\tX(GetRefStruct().UintField++);\n\t\t\tX(GetRefStruct().UintProp++);\n\t\t\tX(GetRefUint()++);\n#endif\n\t\t}\n\n\t\tpublic static void UintPreIncTest(uint p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tuint num = 0u;\n\t\t\tX(++p);\n\t\t\tX(++num);\n\t\t\tUse(ref num);\n\t\t\tX(++uintField);\n\t\t\tX(++UintProp);\n\t\t\tX(++c.UintField);\n\t\t\tX(++c.UintProp);\n\t\t\tX(++s.UintField);\n\t\t\tX(++s.UintProp);\n\t\t\tX(++customClassField.UintField);\n\t\t\tX(++customClassField.UintProp);\n\t\t\tX(++otherCustomStructField.UintField);\n\t\t\tX(++otherCustomStructField.UintProp);\n\t\t\tX(++CustomClassProp.UintField);\n\t\t\tX(++CustomClassProp.UintProp);\n\t\t\tX(++GetClass().UintField);\n\t\t\tX(++GetClass().UintProp);\n#if CS70\n\t\t\tX(++GetRefStruct().UintField);\n\t\t\tX(++GetRefStruct().UintProp);\n\t\t\tX(++GetRefUint());\n#endif\n\t\t}\n\t\tpublic static void UintPostDecTest(uint p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tuint num = 0u;\n\t\t\tX(p--);\n\t\t\tX(num--);\n\t\t\tUse(ref num);\n\t\t\tX(uintField--);\n\t\t\tX(UintProp--);\n\t\t\tX(c.UintField--);\n\t\t\tX(c.UintProp--);\n\t\t\tX(s.UintField--);\n\t\t\tX(s.UintProp--);\n\t\t\tX(customClassField.UintField--);\n\t\t\tX(customClassField.UintProp--);\n\t\t\tX(otherCustomStructField.UintField--);\n\t\t\tX(otherCustomStructField.UintProp--);\n\t\t\tX(CustomClassProp.UintField--);\n\t\t\tX(CustomClassProp.UintProp--);\n\t\t\tX(GetClass().UintField--);\n\t\t\tX(GetClass().UintProp--);\n#if CS70\n\t\t\tX(GetRefStruct().UintField--);\n\t\t\tX(GetRefStruct().UintProp--);\n\t\t\tX(GetRefUint()--);\n#endif\n\t\t}\n\n\t\tpublic static void UintPreDecTest(uint p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tuint num = 0u;\n\t\t\tX(--p);\n\t\t\tX(--num);\n\t\t\tUse(ref num);\n\t\t\tX(--uintField);\n\t\t\tX(--UintProp);\n\t\t\tX(--c.UintField);\n\t\t\tX(--c.UintProp);\n\t\t\tX(--s.UintField);\n\t\t\tX(--s.UintProp);\n\t\t\tX(--customClassField.UintField);\n\t\t\tX(--customClassField.UintProp);\n\t\t\tX(--otherCustomStructField.UintField);\n\t\t\tX(--otherCustomStructField.UintProp);\n\t\t\tX(--CustomClassProp.UintField);\n\t\t\tX(--CustomClassProp.UintProp);\n\t\t\tX(--GetClass().UintField);\n\t\t\tX(--GetClass().UintProp);\n#if CS70\n\t\t\tX(--GetRefStruct().UintField);\n\t\t\tX(--GetRefStruct().UintProp);\n\t\t\tX(--GetRefUint());\n#endif\n\t\t}\n\t\tpublic static void LongAddTest(long p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tlong num = 0L;\n\t\t\tp += 5;\n\t\t\tnum += 5;\n\t\t\tUse(ref num);\n\t\t\tlongField += 5L;\n\t\t\tLongProp += 5L;\n\t\t\tc.LongField += 5L;\n\t\t\tc.LongProp += 5L;\n\t\t\ts.LongField += 5L;\n\t\t\ts.LongProp += 5L;\n\t\t\tcustomClassField.LongField += 5L;\n\t\t\tcustomClassField.LongProp += 5L;\n\t\t\totherCustomStructField.LongField += 5L;\n\t\t\totherCustomStructField.LongProp += 5L;\n\t\t\tCustomClassProp.LongField += 5L;\n\t\t\tCustomClassProp.LongProp += 5L;\n\t\t\tGetClass().LongField += 5L;\n\t\t\tGetClass().LongProp += 5L;\n#if CS70\n\t\t\tGetRefStruct().LongField += 5L;\n\t\t\tGetRefStruct().LongProp += 5L;\n\t\t\tGetRefLong() += 5L;\n#endif\n\t\t}\n\n\t\tpublic static void LongSubtractTest(long p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tlong num = 0L;\n\t\t\tp -= 5;\n\t\t\tnum -= 5;\n\t\t\tUse(ref num);\n\t\t\tlongField -= 5L;\n\t\t\tLongProp -= 5L;\n\t\t\tc.LongField -= 5L;\n\t\t\tc.LongProp -= 5L;\n\t\t\ts.LongField -= 5L;\n\t\t\ts.LongProp -= 5L;\n\t\t\tcustomClassField.LongField -= 5L;\n\t\t\tcustomClassField.LongProp -= 5L;\n\t\t\totherCustomStructField.LongField -= 5L;\n\t\t\totherCustomStructField.LongProp -= 5L;\n\t\t\tCustomClassProp.LongField -= 5L;\n\t\t\tCustomClassProp.LongProp -= 5L;\n\t\t\tGetClass().LongField -= 5L;\n\t\t\tGetClass().LongProp -= 5L;\n#if CS70\n\t\t\tGetRefStruct().LongField -= 5L;\n\t\t\tGetRefStruct().LongProp -= 5L;\n\t\t\tGetRefLong() -= 5L;\n#endif\n\t\t}\n\n\t\tpublic static void LongMultiplyTest(long p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tlong num = 0L;\n\t\t\tp *= 5;\n\t\t\tnum *= 5;\n\t\t\tUse(ref num);\n\t\t\tlongField *= 5L;\n\t\t\tLongProp *= 5L;\n\t\t\tc.LongField *= 5L;\n\t\t\tc.LongProp *= 5L;\n\t\t\ts.LongField *= 5L;\n\t\t\ts.LongProp *= 5L;\n\t\t\tcustomClassField.LongField *= 5L;\n\t\t\tcustomClassField.LongProp *= 5L;\n\t\t\totherCustomStructField.LongField *= 5L;\n\t\t\totherCustomStructField.LongProp *= 5L;\n\t\t\tCustomClassProp.LongField *= 5L;\n\t\t\tCustomClassProp.LongProp *= 5L;\n\t\t\tGetClass().LongField *= 5L;\n\t\t\tGetClass().LongProp *= 5L;\n#if CS70\n\t\t\tGetRefStruct().LongField *= 5L;\n\t\t\tGetRefStruct().LongProp *= 5L;\n\t\t\tGetRefLong() *= 5L;\n#endif\n\t\t}\n\n\t\tpublic static void LongDivideTest(long p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tlong num = 0L;\n\t\t\tp /= 5;\n\t\t\tnum /= 5;\n\t\t\tUse(ref num);\n\t\t\tlongField /= 5L;\n\t\t\tLongProp /= 5L;\n\t\t\tc.LongField /= 5L;\n\t\t\tc.LongProp /= 5L;\n\t\t\ts.LongField /= 5L;\n\t\t\ts.LongProp /= 5L;\n\t\t\tcustomClassField.LongField /= 5L;\n\t\t\tcustomClassField.LongProp /= 5L;\n\t\t\totherCustomStructField.LongField /= 5L;\n\t\t\totherCustomStructField.LongProp /= 5L;\n\t\t\tCustomClassProp.LongField /= 5L;\n\t\t\tCustomClassProp.LongProp /= 5L;\n\t\t\tGetClass().LongField /= 5L;\n\t\t\tGetClass().LongProp /= 5L;\n#if CS70\n\t\t\tGetRefStruct().LongField /= 5L;\n\t\t\tGetRefStruct().LongProp /= 5L;\n\t\t\tGetRefLong() /= 5L;\n#endif\n\t\t}\n\n\t\tpublic static void LongModulusTest(long p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tlong num = 0L;\n\t\t\tp %= 5;\n\t\t\tnum %= 5;\n\t\t\tUse(ref num);\n\t\t\tlongField %= 5L;\n\t\t\tLongProp %= 5L;\n\t\t\tc.LongField %= 5L;\n\t\t\tc.LongProp %= 5L;\n\t\t\ts.LongField %= 5L;\n\t\t\ts.LongProp %= 5L;\n\t\t\tcustomClassField.LongField %= 5L;\n\t\t\tcustomClassField.LongProp %= 5L;\n\t\t\totherCustomStructField.LongField %= 5L;\n\t\t\totherCustomStructField.LongProp %= 5L;\n\t\t\tCustomClassProp.LongField %= 5L;\n\t\t\tCustomClassProp.LongProp %= 5L;\n\t\t\tGetClass().LongField %= 5L;\n\t\t\tGetClass().LongProp %= 5L;\n#if CS70\n\t\t\tGetRefStruct().LongField %= 5L;\n\t\t\tGetRefStruct().LongProp %= 5L;\n\t\t\tGetRefLong() %= 5L;\n#endif\n\t\t}\n\n\t\tpublic static void LongLeftShiftTest(long p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tlong num = 0L;\n\t\t\tp <<= 5;\n\t\t\tnum <<= 5;\n\t\t\tUse(ref num);\n\t\t\tlongField <<= 5;\n\t\t\tLongProp <<= 5;\n\t\t\tc.LongField <<= 5;\n\t\t\tc.LongProp <<= 5;\n\t\t\ts.LongField <<= 5;\n\t\t\ts.LongProp <<= 5;\n\t\t\tcustomClassField.LongField <<= 5;\n\t\t\tcustomClassField.LongProp <<= 5;\n\t\t\totherCustomStructField.LongField <<= 5;\n\t\t\totherCustomStructField.LongProp <<= 5;\n\t\t\tCustomClassProp.LongField <<= 5;\n\t\t\tCustomClassProp.LongProp <<= 5;\n\t\t\tGetClass().LongField <<= 5;\n\t\t\tGetClass().LongProp <<= 5;\n#if CS70\n\t\t\tGetRefStruct().LongField <<= 5;\n\t\t\tGetRefStruct().LongProp <<= 5;\n\t\t\tGetRefLong() <<= 5;\n#endif\n\t\t}\n\n\t\tpublic static void LongRightShiftTest(long p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tlong num = 0L;\n\t\t\tp >>= 5;\n\t\t\tnum >>= 5;\n\t\t\tUse(ref num);\n\t\t\tlongField >>= 5;\n\t\t\tLongProp >>= 5;\n\t\t\tc.LongField >>= 5;\n\t\t\tc.LongProp >>= 5;\n\t\t\ts.LongField >>= 5;\n\t\t\ts.LongProp >>= 5;\n\t\t\tcustomClassField.LongField >>= 5;\n\t\t\tcustomClassField.LongProp >>= 5;\n\t\t\totherCustomStructField.LongField >>= 5;\n\t\t\totherCustomStructField.LongProp >>= 5;\n\t\t\tCustomClassProp.LongField >>= 5;\n\t\t\tCustomClassProp.LongProp >>= 5;\n\t\t\tGetClass().LongField >>= 5;\n\t\t\tGetClass().LongProp >>= 5;\n#if CS70\n\t\t\tGetRefStruct().LongField >>= 5;\n\t\t\tGetRefStruct().LongProp >>= 5;\n\t\t\tGetRefLong() >>= 5;\n#endif\n\t\t}\n\n\t\tpublic static void LongBitAndTest(long p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tlong num = 0L;\n\t\t\tp &= 5;\n\t\t\tnum &= 5;\n\t\t\tUse(ref num);\n\t\t\tlongField &= 5L;\n\t\t\tLongProp &= 5L;\n\t\t\tc.LongField &= 5L;\n\t\t\tc.LongProp &= 5L;\n\t\t\ts.LongField &= 5L;\n\t\t\ts.LongProp &= 5L;\n\t\t\tcustomClassField.LongField &= 5L;\n\t\t\tcustomClassField.LongProp &= 5L;\n\t\t\totherCustomStructField.LongField &= 5L;\n\t\t\totherCustomStructField.LongProp &= 5L;\n\t\t\tCustomClassProp.LongField &= 5L;\n\t\t\tCustomClassProp.LongProp &= 5L;\n\t\t\tGetClass().LongField &= 5L;\n\t\t\tGetClass().LongProp &= 5L;\n#if CS70\n\t\t\tGetRefStruct().LongField &= 5L;\n\t\t\tGetRefStruct().LongProp &= 5L;\n\t\t\tGetRefLong() &= 5L;\n#endif\n\t\t}\n\n\t\tpublic static void LongBitOrTest(long p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tlong num = 0L;\n\t\t\tp |= 5;\n\t\t\tnum |= 5;\n\t\t\tUse(ref num);\n\t\t\tlongField |= 5L;\n\t\t\tLongProp |= 5L;\n\t\t\tc.LongField |= 5L;\n\t\t\tc.LongProp |= 5L;\n\t\t\ts.LongField |= 5L;\n\t\t\ts.LongProp |= 5L;\n\t\t\tcustomClassField.LongField |= 5L;\n\t\t\tcustomClassField.LongProp |= 5L;\n\t\t\totherCustomStructField.LongField |= 5L;\n\t\t\totherCustomStructField.LongProp |= 5L;\n\t\t\tCustomClassProp.LongField |= 5L;\n\t\t\tCustomClassProp.LongProp |= 5L;\n\t\t\tGetClass().LongField |= 5L;\n\t\t\tGetClass().LongProp |= 5L;\n#if CS70\n\t\t\tGetRefStruct().LongField |= 5L;\n\t\t\tGetRefStruct().LongProp |= 5L;\n\t\t\tGetRefLong() |= 5L;\n#endif\n\t\t}\n\n\t\tpublic static void LongBitXorTest(long p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tlong num = 0L;\n\t\t\tp ^= 5;\n\t\t\tnum ^= 5;\n\t\t\tUse(ref num);\n\t\t\tlongField ^= 5L;\n\t\t\tLongProp ^= 5L;\n\t\t\tc.LongField ^= 5L;\n\t\t\tc.LongProp ^= 5L;\n\t\t\ts.LongField ^= 5L;\n\t\t\ts.LongProp ^= 5L;\n\t\t\tcustomClassField.LongField ^= 5L;\n\t\t\tcustomClassField.LongProp ^= 5L;\n\t\t\totherCustomStructField.LongField ^= 5L;\n\t\t\totherCustomStructField.LongProp ^= 5L;\n\t\t\tCustomClassProp.LongField ^= 5L;\n\t\t\tCustomClassProp.LongProp ^= 5L;\n\t\t\tGetClass().LongField ^= 5L;\n\t\t\tGetClass().LongProp ^= 5L;\n#if CS70\n\t\t\tGetRefStruct().LongField ^= 5L;\n\t\t\tGetRefStruct().LongProp ^= 5L;\n\t\t\tGetRefLong() ^= 5L;\n#endif\n\t\t}\n\n\t\tpublic static void LongPostIncTest(long p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tlong num = 0L;\n\t\t\tX(p++);\n\t\t\tX(num++);\n\t\t\tUse(ref num);\n\t\t\tX(longField++);\n\t\t\tX(LongProp++);\n\t\t\tX(c.LongField++);\n\t\t\tX(c.LongProp++);\n\t\t\tX(s.LongField++);\n\t\t\tX(s.LongProp++);\n\t\t\tX(customClassField.LongField++);\n\t\t\tX(customClassField.LongProp++);\n\t\t\tX(otherCustomStructField.LongField++);\n\t\t\tX(otherCustomStructField.LongProp++);\n\t\t\tX(CustomClassProp.LongField++);\n\t\t\tX(CustomClassProp.LongProp++);\n\t\t\tX(GetClass().LongField++);\n\t\t\tX(GetClass().LongProp++);\n#if CS70\n\t\t\tX(GetRefStruct().LongField++);\n\t\t\tX(GetRefStruct().LongProp++);\n\t\t\tX(GetRefLong()++);\n#endif\n\t\t}\n\n\t\tpublic static void LongPreIncTest(long p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tlong num = 0L;\n\t\t\tX(++p);\n\t\t\tX(++num);\n\t\t\tUse(ref num);\n\t\t\tX(++longField);\n\t\t\tX(++LongProp);\n\t\t\tX(++c.LongField);\n\t\t\tX(++c.LongProp);\n\t\t\tX(++s.LongField);\n\t\t\tX(++s.LongProp);\n\t\t\tX(++customClassField.LongField);\n\t\t\tX(++customClassField.LongProp);\n\t\t\tX(++otherCustomStructField.LongField);\n\t\t\tX(++otherCustomStructField.LongProp);\n\t\t\tX(++CustomClassProp.LongField);\n\t\t\tX(++CustomClassProp.LongProp);\n\t\t\tX(++GetClass().LongField);\n\t\t\tX(++GetClass().LongProp);\n#if CS70\n\t\t\tX(++GetRefStruct().LongField);\n\t\t\tX(++GetRefStruct().LongProp);\n\t\t\tX(++GetRefLong());\n#endif\n\t\t}\n\t\tpublic static void LongPostDecTest(long p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tlong num = 0L;\n\t\t\tX(p--);\n\t\t\tX(num--);\n\t\t\tUse(ref num);\n\t\t\tX(longField--);\n\t\t\tX(LongProp--);\n\t\t\tX(c.LongField--);\n\t\t\tX(c.LongProp--);\n\t\t\tX(s.LongField--);\n\t\t\tX(s.LongProp--);\n\t\t\tX(customClassField.LongField--);\n\t\t\tX(customClassField.LongProp--);\n\t\t\tX(otherCustomStructField.LongField--);\n\t\t\tX(otherCustomStructField.LongProp--);\n\t\t\tX(CustomClassProp.LongField--);\n\t\t\tX(CustomClassProp.LongProp--);\n\t\t\tX(GetClass().LongField--);\n\t\t\tX(GetClass().LongProp--);\n#if CS70\n\t\t\tX(GetRefStruct().LongField--);\n\t\t\tX(GetRefStruct().LongProp--);\n\t\t\tX(GetRefLong()--);\n#endif\n\t\t}\n\n\t\tpublic static void LongPreDecTest(long p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tlong num = 0L;\n\t\t\tX(--p);\n\t\t\tX(--num);\n\t\t\tUse(ref num);\n\t\t\tX(--longField);\n\t\t\tX(--LongProp);\n\t\t\tX(--c.LongField);\n\t\t\tX(--c.LongProp);\n\t\t\tX(--s.LongField);\n\t\t\tX(--s.LongProp);\n\t\t\tX(--customClassField.LongField);\n\t\t\tX(--customClassField.LongProp);\n\t\t\tX(--otherCustomStructField.LongField);\n\t\t\tX(--otherCustomStructField.LongProp);\n\t\t\tX(--CustomClassProp.LongField);\n\t\t\tX(--CustomClassProp.LongProp);\n\t\t\tX(--GetClass().LongField);\n\t\t\tX(--GetClass().LongProp);\n#if CS70\n\t\t\tX(--GetRefStruct().LongField);\n\t\t\tX(--GetRefStruct().LongProp);\n\t\t\tX(--GetRefLong());\n#endif\n\t\t}\n\t\tpublic static void UlongAddTest(ulong p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tulong num = 0uL;\n\t\t\tp += 5;\n\t\t\tnum += 5;\n\t\t\tUse(ref num);\n\t\t\tulongField += 5uL;\n\t\t\tUlongProp += 5uL;\n\t\t\tc.UlongField += 5uL;\n\t\t\tc.UlongProp += 5uL;\n\t\t\ts.UlongField += 5uL;\n\t\t\ts.UlongProp += 5uL;\n\t\t\tcustomClassField.UlongField += 5uL;\n\t\t\tcustomClassField.UlongProp += 5uL;\n\t\t\totherCustomStructField.UlongField += 5uL;\n\t\t\totherCustomStructField.UlongProp += 5uL;\n\t\t\tCustomClassProp.UlongField += 5uL;\n\t\t\tCustomClassProp.UlongProp += 5uL;\n\t\t\tGetClass().UlongField += 5uL;\n\t\t\tGetClass().UlongProp += 5uL;\n#if CS70\n\t\t\tGetRefStruct().UlongField += 5uL;\n\t\t\tGetRefStruct().UlongProp += 5uL;\n\t\t\tGetRefUlong() += 5uL;\n#endif\n\t\t}\n\n\t\tpublic static void UlongSubtractTest(ulong p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tulong num = 0uL;\n\t\t\tp -= 5;\n\t\t\tnum -= 5;\n\t\t\tUse(ref num);\n\t\t\tulongField -= 5uL;\n\t\t\tUlongProp -= 5uL;\n\t\t\tc.UlongField -= 5uL;\n\t\t\tc.UlongProp -= 5uL;\n\t\t\ts.UlongField -= 5uL;\n\t\t\ts.UlongProp -= 5uL;\n\t\t\tcustomClassField.UlongField -= 5uL;\n\t\t\tcustomClassField.UlongProp -= 5uL;\n\t\t\totherCustomStructField.UlongField -= 5uL;\n\t\t\totherCustomStructField.UlongProp -= 5uL;\n\t\t\tCustomClassProp.UlongField -= 5uL;\n\t\t\tCustomClassProp.UlongProp -= 5uL;\n\t\t\tGetClass().UlongField -= 5uL;\n\t\t\tGetClass().UlongProp -= 5uL;\n#if CS70\n\t\t\tGetRefStruct().UlongField -= 5uL;\n\t\t\tGetRefStruct().UlongProp -= 5uL;\n\t\t\tGetRefUlong() -= 5uL;\n#endif\n\t\t}\n\n\t\tpublic static void UlongMultiplyTest(ulong p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tulong num = 0uL;\n\t\t\tp *= 5;\n\t\t\tnum *= 5;\n\t\t\tUse(ref num);\n\t\t\tulongField *= 5uL;\n\t\t\tUlongProp *= 5uL;\n\t\t\tc.UlongField *= 5uL;\n\t\t\tc.UlongProp *= 5uL;\n\t\t\ts.UlongField *= 5uL;\n\t\t\ts.UlongProp *= 5uL;\n\t\t\tcustomClassField.UlongField *= 5uL;\n\t\t\tcustomClassField.UlongProp *= 5uL;\n\t\t\totherCustomStructField.UlongField *= 5uL;\n\t\t\totherCustomStructField.UlongProp *= 5uL;\n\t\t\tCustomClassProp.UlongField *= 5uL;\n\t\t\tCustomClassProp.UlongProp *= 5uL;\n\t\t\tGetClass().UlongField *= 5uL;\n\t\t\tGetClass().UlongProp *= 5uL;\n#if CS70\n\t\t\tGetRefStruct().UlongField *= 5uL;\n\t\t\tGetRefStruct().UlongProp *= 5uL;\n\t\t\tGetRefUlong() *= 5uL;\n#endif\n\t\t}\n\n\t\tpublic static void UlongDivideTest(ulong p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tulong num = 0uL;\n\t\t\tp /= 5;\n\t\t\tnum /= 5;\n\t\t\tUse(ref num);\n\t\t\tulongField /= 5uL;\n\t\t\tUlongProp /= 5uL;\n\t\t\tc.UlongField /= 5uL;\n\t\t\tc.UlongProp /= 5uL;\n\t\t\ts.UlongField /= 5uL;\n\t\t\ts.UlongProp /= 5uL;\n\t\t\tcustomClassField.UlongField /= 5uL;\n\t\t\tcustomClassField.UlongProp /= 5uL;\n\t\t\totherCustomStructField.UlongField /= 5uL;\n\t\t\totherCustomStructField.UlongProp /= 5uL;\n\t\t\tCustomClassProp.UlongField /= 5uL;\n\t\t\tCustomClassProp.UlongProp /= 5uL;\n\t\t\tGetClass().UlongField /= 5uL;\n\t\t\tGetClass().UlongProp /= 5uL;\n#if CS70\n\t\t\tGetRefStruct().UlongField /= 5uL;\n\t\t\tGetRefStruct().UlongProp /= 5uL;\n\t\t\tGetRefUlong() /= 5uL;\n#endif\n\t\t}\n\n\t\tpublic static void UlongModulusTest(ulong p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tulong num = 0uL;\n\t\t\tp %= 5;\n\t\t\tnum %= 5;\n\t\t\tUse(ref num);\n\t\t\tulongField %= 5uL;\n\t\t\tUlongProp %= 5uL;\n\t\t\tc.UlongField %= 5uL;\n\t\t\tc.UlongProp %= 5uL;\n\t\t\ts.UlongField %= 5uL;\n\t\t\ts.UlongProp %= 5uL;\n\t\t\tcustomClassField.UlongField %= 5uL;\n\t\t\tcustomClassField.UlongProp %= 5uL;\n\t\t\totherCustomStructField.UlongField %= 5uL;\n\t\t\totherCustomStructField.UlongProp %= 5uL;\n\t\t\tCustomClassProp.UlongField %= 5uL;\n\t\t\tCustomClassProp.UlongProp %= 5uL;\n\t\t\tGetClass().UlongField %= 5uL;\n\t\t\tGetClass().UlongProp %= 5uL;\n#if CS70\n\t\t\tGetRefStruct().UlongField %= 5uL;\n\t\t\tGetRefStruct().UlongProp %= 5uL;\n\t\t\tGetRefUlong() %= 5uL;\n#endif\n\t\t}\n\n\t\tpublic static void UlongLeftShiftTest(ulong p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tulong num = 0uL;\n\t\t\tp <<= 5;\n\t\t\tnum <<= 5;\n\t\t\tUse(ref num);\n\t\t\tulongField <<= 5;\n\t\t\tUlongProp <<= 5;\n\t\t\tc.UlongField <<= 5;\n\t\t\tc.UlongProp <<= 5;\n\t\t\ts.UlongField <<= 5;\n\t\t\ts.UlongProp <<= 5;\n\t\t\tcustomClassField.UlongField <<= 5;\n\t\t\tcustomClassField.UlongProp <<= 5;\n\t\t\totherCustomStructField.UlongField <<= 5;\n\t\t\totherCustomStructField.UlongProp <<= 5;\n\t\t\tCustomClassProp.UlongField <<= 5;\n\t\t\tCustomClassProp.UlongProp <<= 5;\n\t\t\tGetClass().UlongField <<= 5;\n\t\t\tGetClass().UlongProp <<= 5;\n#if CS70\n\t\t\tGetRefStruct().UlongField <<= 5;\n\t\t\tGetRefStruct().UlongProp <<= 5;\n\t\t\tGetRefUlong() <<= 5;\n#endif\n\t\t}\n\n\t\tpublic static void UlongRightShiftTest(ulong p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tulong num = 0uL;\n\t\t\tp >>= 5;\n\t\t\tnum >>= 5;\n\t\t\tUse(ref num);\n\t\t\tulongField >>= 5;\n\t\t\tUlongProp >>= 5;\n\t\t\tc.UlongField >>= 5;\n\t\t\tc.UlongProp >>= 5;\n\t\t\ts.UlongField >>= 5;\n\t\t\ts.UlongProp >>= 5;\n\t\t\tcustomClassField.UlongField >>= 5;\n\t\t\tcustomClassField.UlongProp >>= 5;\n\t\t\totherCustomStructField.UlongField >>= 5;\n\t\t\totherCustomStructField.UlongProp >>= 5;\n\t\t\tCustomClassProp.UlongField >>= 5;\n\t\t\tCustomClassProp.UlongProp >>= 5;\n\t\t\tGetClass().UlongField >>= 5;\n\t\t\tGetClass().UlongProp >>= 5;\n#if CS70\n\t\t\tGetRefStruct().UlongField >>= 5;\n\t\t\tGetRefStruct().UlongProp >>= 5;\n\t\t\tGetRefUlong() >>= 5;\n#endif\n\t\t}\n\n\t\tpublic static void UlongBitAndTest(ulong p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tulong num = 0uL;\n\t\t\tp &= 5;\n\t\t\tnum &= 5;\n\t\t\tUse(ref num);\n\t\t\tulongField &= 5uL;\n\t\t\tUlongProp &= 5uL;\n\t\t\tc.UlongField &= 5uL;\n\t\t\tc.UlongProp &= 5uL;\n\t\t\ts.UlongField &= 5uL;\n\t\t\ts.UlongProp &= 5uL;\n\t\t\tcustomClassField.UlongField &= 5uL;\n\t\t\tcustomClassField.UlongProp &= 5uL;\n\t\t\totherCustomStructField.UlongField &= 5uL;\n\t\t\totherCustomStructField.UlongProp &= 5uL;\n\t\t\tCustomClassProp.UlongField &= 5uL;\n\t\t\tCustomClassProp.UlongProp &= 5uL;\n\t\t\tGetClass().UlongField &= 5uL;\n\t\t\tGetClass().UlongProp &= 5uL;\n#if CS70\n\t\t\tGetRefStruct().UlongField &= 5uL;\n\t\t\tGetRefStruct().UlongProp &= 5uL;\n\t\t\tGetRefUlong() &= 5uL;\n#endif\n\t\t}\n\n\t\tpublic static void UlongBitOrTest(ulong p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tulong num = 0uL;\n\t\t\tp |= 5;\n\t\t\tnum |= 5;\n\t\t\tUse(ref num);\n\t\t\tulongField |= 5uL;\n\t\t\tUlongProp |= 5uL;\n\t\t\tc.UlongField |= 5uL;\n\t\t\tc.UlongProp |= 5uL;\n\t\t\ts.UlongField |= 5uL;\n\t\t\ts.UlongProp |= 5uL;\n\t\t\tcustomClassField.UlongField |= 5uL;\n\t\t\tcustomClassField.UlongProp |= 5uL;\n\t\t\totherCustomStructField.UlongField |= 5uL;\n\t\t\totherCustomStructField.UlongProp |= 5uL;\n\t\t\tCustomClassProp.UlongField |= 5uL;\n\t\t\tCustomClassProp.UlongProp |= 5uL;\n\t\t\tGetClass().UlongField |= 5uL;\n\t\t\tGetClass().UlongProp |= 5uL;\n#if CS70\n\t\t\tGetRefStruct().UlongField |= 5uL;\n\t\t\tGetRefStruct().UlongProp |= 5uL;\n\t\t\tGetRefUlong() |= 5uL;\n#endif\n\t\t}\n\n\t\tpublic static void UlongBitXorTest(ulong p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tulong num = 0uL;\n\t\t\tp ^= 5;\n\t\t\tnum ^= 5;\n\t\t\tUse(ref num);\n\t\t\tulongField ^= 5uL;\n\t\t\tUlongProp ^= 5uL;\n\t\t\tc.UlongField ^= 5uL;\n\t\t\tc.UlongProp ^= 5uL;\n\t\t\ts.UlongField ^= 5uL;\n\t\t\ts.UlongProp ^= 5uL;\n\t\t\tcustomClassField.UlongField ^= 5uL;\n\t\t\tcustomClassField.UlongProp ^= 5uL;\n\t\t\totherCustomStructField.UlongField ^= 5uL;\n\t\t\totherCustomStructField.UlongProp ^= 5uL;\n\t\t\tCustomClassProp.UlongField ^= 5uL;\n\t\t\tCustomClassProp.UlongProp ^= 5uL;\n\t\t\tGetClass().UlongField ^= 5uL;\n\t\t\tGetClass().UlongProp ^= 5uL;\n#if CS70\n\t\t\tGetRefStruct().UlongField ^= 5uL;\n\t\t\tGetRefStruct().UlongProp ^= 5uL;\n\t\t\tGetRefUlong() ^= 5uL;\n#endif\n\t\t}\n\n\t\tpublic static void UlongPostIncTest(ulong p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tulong num = 0uL;\n\t\t\tX(p++);\n\t\t\tX(num++);\n\t\t\tUse(ref num);\n\t\t\tX(ulongField++);\n\t\t\tX(UlongProp++);\n\t\t\tX(c.UlongField++);\n\t\t\tX(c.UlongProp++);\n\t\t\tX(s.UlongField++);\n\t\t\tX(s.UlongProp++);\n\t\t\tX(customClassField.UlongField++);\n\t\t\tX(customClassField.UlongProp++);\n\t\t\tX(otherCustomStructField.UlongField++);\n\t\t\tX(otherCustomStructField.UlongProp++);\n\t\t\tX(CustomClassProp.UlongField++);\n\t\t\tX(CustomClassProp.UlongProp++);\n\t\t\tX(GetClass().UlongField++);\n\t\t\tX(GetClass().UlongProp++);\n#if CS70\n\t\t\tX(GetRefStruct().UlongField++);\n\t\t\tX(GetRefStruct().UlongProp++);\n\t\t\tX(GetRefUlong()++);\n#endif\n\t\t}\n\n\t\tpublic static void UlongPreIncTest(ulong p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tulong num = 0uL;\n\t\t\tX(++p);\n\t\t\tX(++num);\n\t\t\tUse(ref num);\n\t\t\tX(++ulongField);\n\t\t\tX(++UlongProp);\n\t\t\tX(++c.UlongField);\n\t\t\tX(++c.UlongProp);\n\t\t\tX(++s.UlongField);\n\t\t\tX(++s.UlongProp);\n\t\t\tX(++customClassField.UlongField);\n\t\t\tX(++customClassField.UlongProp);\n\t\t\tX(++otherCustomStructField.UlongField);\n\t\t\tX(++otherCustomStructField.UlongProp);\n\t\t\tX(++CustomClassProp.UlongField);\n\t\t\tX(++CustomClassProp.UlongProp);\n\t\t\tX(++GetClass().UlongField);\n\t\t\tX(++GetClass().UlongProp);\n#if CS70\n\t\t\tX(++GetRefStruct().UlongField);\n\t\t\tX(++GetRefStruct().UlongProp);\n\t\t\tX(++GetRefUlong());\n#endif\n\t\t}\n\t\tpublic static void UlongPostDecTest(ulong p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tulong num = 0uL;\n\t\t\tX(p--);\n\t\t\tX(num--);\n\t\t\tUse(ref num);\n\t\t\tX(ulongField--);\n\t\t\tX(UlongProp--);\n\t\t\tX(c.UlongField--);\n\t\t\tX(c.UlongProp--);\n\t\t\tX(s.UlongField--);\n\t\t\tX(s.UlongProp--);\n\t\t\tX(customClassField.UlongField--);\n\t\t\tX(customClassField.UlongProp--);\n\t\t\tX(otherCustomStructField.UlongField--);\n\t\t\tX(otherCustomStructField.UlongProp--);\n\t\t\tX(CustomClassProp.UlongField--);\n\t\t\tX(CustomClassProp.UlongProp--);\n\t\t\tX(GetClass().UlongField--);\n\t\t\tX(GetClass().UlongProp--);\n#if CS70\n\t\t\tX(GetRefStruct().UlongField--);\n\t\t\tX(GetRefStruct().UlongProp--);\n\t\t\tX(GetRefUlong()--);\n#endif\n\t\t}\n\n\t\tpublic static void UlongPreDecTest(ulong p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tulong num = 0uL;\n\t\t\tX(--p);\n\t\t\tX(--num);\n\t\t\tUse(ref num);\n\t\t\tX(--ulongField);\n\t\t\tX(--UlongProp);\n\t\t\tX(--c.UlongField);\n\t\t\tX(--c.UlongProp);\n\t\t\tX(--s.UlongField);\n\t\t\tX(--s.UlongProp);\n\t\t\tX(--customClassField.UlongField);\n\t\t\tX(--customClassField.UlongProp);\n\t\t\tX(--otherCustomStructField.UlongField);\n\t\t\tX(--otherCustomStructField.UlongProp);\n\t\t\tX(--CustomClassProp.UlongField);\n\t\t\tX(--CustomClassProp.UlongProp);\n\t\t\tX(--GetClass().UlongField);\n\t\t\tX(--GetClass().UlongProp);\n#if CS70\n\t\t\tX(--GetRefStruct().UlongField);\n\t\t\tX(--GetRefStruct().UlongProp);\n\t\t\tX(--GetRefUlong());\n#endif\n\t\t}\n\t\tpublic static void CustomClassAddTest(CustomClass p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomClass num = null;\n\t\t\tp += (CustomClass)null;\n\t\t\tnum += (CustomClass)null;\n\t\t\tUse(ref num);\n\t\t\tcustomClassField += (CustomClass)null;\n\t\t\tCustomClassProp += (CustomClass)null;\n\t\t\tc.CustomClassField += (CustomClass)null;\n\t\t\tc.CustomClassProp += (CustomClass)null;\n\t\t\ts.CustomClassField += (CustomClass)null;\n\t\t\ts.CustomClassProp += (CustomClass)null;\n\t\t\tcustomClassField.CustomClassField += (CustomClass)null;\n\t\t\tcustomClassField.CustomClassProp += (CustomClass)null;\n\t\t\totherCustomStructField.CustomClassField += (CustomClass)null;\n\t\t\totherCustomStructField.CustomClassProp += (CustomClass)null;\n\t\t\tCustomClassProp.CustomClassField += (CustomClass)null;\n\t\t\tCustomClassProp.CustomClassProp += (CustomClass)null;\n\t\t\tGetClass().CustomClassField += (CustomClass)null;\n\t\t\tGetClass().CustomClassProp += (CustomClass)null;\n#if CS70\n\t\t\tGetRefStruct().CustomClassField += (CustomClass)null;\n\t\t\tGetRefStruct().CustomClassProp += (CustomClass)null;\n\t\t\tGetRefCustomClass() += (CustomClass)null;\n#endif\n\t\t}\n\n\t\tpublic static void CustomClassSubtractTest(CustomClass p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomClass num = null;\n\t\t\tp -= (CustomClass)null;\n\t\t\tnum -= (CustomClass)null;\n\t\t\tUse(ref num);\n\t\t\tcustomClassField -= (CustomClass)null;\n\t\t\tCustomClassProp -= (CustomClass)null;\n\t\t\tc.CustomClassField -= (CustomClass)null;\n\t\t\tc.CustomClassProp -= (CustomClass)null;\n\t\t\ts.CustomClassField -= (CustomClass)null;\n\t\t\ts.CustomClassProp -= (CustomClass)null;\n\t\t\tcustomClassField.CustomClassField -= (CustomClass)null;\n\t\t\tcustomClassField.CustomClassProp -= (CustomClass)null;\n\t\t\totherCustomStructField.CustomClassField -= (CustomClass)null;\n\t\t\totherCustomStructField.CustomClassProp -= (CustomClass)null;\n\t\t\tCustomClassProp.CustomClassField -= (CustomClass)null;\n\t\t\tCustomClassProp.CustomClassProp -= (CustomClass)null;\n\t\t\tGetClass().CustomClassField -= (CustomClass)null;\n\t\t\tGetClass().CustomClassProp -= (CustomClass)null;\n#if CS70\n\t\t\tGetRefStruct().CustomClassField -= (CustomClass)null;\n\t\t\tGetRefStruct().CustomClassProp -= (CustomClass)null;\n\t\t\tGetRefCustomClass() -= (CustomClass)null;\n#endif\n\t\t}\n\n\t\tpublic static void CustomClassMultiplyTest(CustomClass p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomClass num = null;\n\t\t\tp *= (CustomClass)null;\n\t\t\tnum *= (CustomClass)null;\n\t\t\tUse(ref num);\n\t\t\tcustomClassField *= (CustomClass)null;\n\t\t\tCustomClassProp *= (CustomClass)null;\n\t\t\tc.CustomClassField *= (CustomClass)null;\n\t\t\tc.CustomClassProp *= (CustomClass)null;\n\t\t\ts.CustomClassField *= (CustomClass)null;\n\t\t\ts.CustomClassProp *= (CustomClass)null;\n\t\t\tcustomClassField.CustomClassField *= (CustomClass)null;\n\t\t\tcustomClassField.CustomClassProp *= (CustomClass)null;\n\t\t\totherCustomStructField.CustomClassField *= (CustomClass)null;\n\t\t\totherCustomStructField.CustomClassProp *= (CustomClass)null;\n\t\t\tCustomClassProp.CustomClassField *= (CustomClass)null;\n\t\t\tCustomClassProp.CustomClassProp *= (CustomClass)null;\n\t\t\tGetClass().CustomClassField *= (CustomClass)null;\n\t\t\tGetClass().CustomClassProp *= (CustomClass)null;\n#if CS70\n\t\t\tGetRefStruct().CustomClassField *= (CustomClass)null;\n\t\t\tGetRefStruct().CustomClassProp *= (CustomClass)null;\n\t\t\tGetRefCustomClass() *= (CustomClass)null;\n#endif\n\t\t}\n\n\t\tpublic static void CustomClassDivideTest(CustomClass p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomClass num = null;\n\t\t\tp /= (CustomClass)null;\n\t\t\tnum /= (CustomClass)null;\n\t\t\tUse(ref num);\n\t\t\tcustomClassField /= (CustomClass)null;\n\t\t\tCustomClassProp /= (CustomClass)null;\n\t\t\tc.CustomClassField /= (CustomClass)null;\n\t\t\tc.CustomClassProp /= (CustomClass)null;\n\t\t\ts.CustomClassField /= (CustomClass)null;\n\t\t\ts.CustomClassProp /= (CustomClass)null;\n\t\t\tcustomClassField.CustomClassField /= (CustomClass)null;\n\t\t\tcustomClassField.CustomClassProp /= (CustomClass)null;\n\t\t\totherCustomStructField.CustomClassField /= (CustomClass)null;\n\t\t\totherCustomStructField.CustomClassProp /= (CustomClass)null;\n\t\t\tCustomClassProp.CustomClassField /= (CustomClass)null;\n\t\t\tCustomClassProp.CustomClassProp /= (CustomClass)null;\n\t\t\tGetClass().CustomClassField /= (CustomClass)null;\n\t\t\tGetClass().CustomClassProp /= (CustomClass)null;\n#if CS70\n\t\t\tGetRefStruct().CustomClassField /= (CustomClass)null;\n\t\t\tGetRefStruct().CustomClassProp /= (CustomClass)null;\n\t\t\tGetRefCustomClass() /= (CustomClass)null;\n#endif\n\t\t}\n\n\t\tpublic static void CustomClassModulusTest(CustomClass p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomClass num = null;\n\t\t\tp %= (CustomClass)null;\n\t\t\tnum %= (CustomClass)null;\n\t\t\tUse(ref num);\n\t\t\tcustomClassField %= (CustomClass)null;\n\t\t\tCustomClassProp %= (CustomClass)null;\n\t\t\tc.CustomClassField %= (CustomClass)null;\n\t\t\tc.CustomClassProp %= (CustomClass)null;\n\t\t\ts.CustomClassField %= (CustomClass)null;\n\t\t\ts.CustomClassProp %= (CustomClass)null;\n\t\t\tcustomClassField.CustomClassField %= (CustomClass)null;\n\t\t\tcustomClassField.CustomClassProp %= (CustomClass)null;\n\t\t\totherCustomStructField.CustomClassField %= (CustomClass)null;\n\t\t\totherCustomStructField.CustomClassProp %= (CustomClass)null;\n\t\t\tCustomClassProp.CustomClassField %= (CustomClass)null;\n\t\t\tCustomClassProp.CustomClassProp %= (CustomClass)null;\n\t\t\tGetClass().CustomClassField %= (CustomClass)null;\n\t\t\tGetClass().CustomClassProp %= (CustomClass)null;\n#if CS70\n\t\t\tGetRefStruct().CustomClassField %= (CustomClass)null;\n\t\t\tGetRefStruct().CustomClassProp %= (CustomClass)null;\n\t\t\tGetRefCustomClass() %= (CustomClass)null;\n#endif\n\t\t}\n\n\t\tpublic static void CustomClassLeftShiftTest(CustomClass p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomClass num = null;\n\t\t\tp <<= 5;\n\t\t\tnum <<= 5;\n\t\t\tUse(ref num);\n\t\t\tcustomClassField <<= 5;\n\t\t\tCustomClassProp <<= 5;\n\t\t\tc.CustomClassField <<= 5;\n\t\t\tc.CustomClassProp <<= 5;\n\t\t\ts.CustomClassField <<= 5;\n\t\t\ts.CustomClassProp <<= 5;\n\t\t\tcustomClassField.CustomClassField <<= 5;\n\t\t\tcustomClassField.CustomClassProp <<= 5;\n\t\t\totherCustomStructField.CustomClassField <<= 5;\n\t\t\totherCustomStructField.CustomClassProp <<= 5;\n\t\t\tCustomClassProp.CustomClassField <<= 5;\n\t\t\tCustomClassProp.CustomClassProp <<= 5;\n\t\t\tGetClass().CustomClassField <<= 5;\n\t\t\tGetClass().CustomClassProp <<= 5;\n#if CS70\n\t\t\tGetRefStruct().CustomClassField <<= 5;\n\t\t\tGetRefStruct().CustomClassProp <<= 5;\n\t\t\tGetRefCustomClass() <<= 5;\n#endif\n\t\t}\n\n\t\tpublic static void CustomClassRightShiftTest(CustomClass p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomClass num = null;\n\t\t\tp >>= 5;\n\t\t\tnum >>= 5;\n\t\t\tUse(ref num);\n\t\t\tcustomClassField >>= 5;\n\t\t\tCustomClassProp >>= 5;\n\t\t\tc.CustomClassField >>= 5;\n\t\t\tc.CustomClassProp >>= 5;\n\t\t\ts.CustomClassField >>= 5;\n\t\t\ts.CustomClassProp >>= 5;\n\t\t\tcustomClassField.CustomClassField >>= 5;\n\t\t\tcustomClassField.CustomClassProp >>= 5;\n\t\t\totherCustomStructField.CustomClassField >>= 5;\n\t\t\totherCustomStructField.CustomClassProp >>= 5;\n\t\t\tCustomClassProp.CustomClassField >>= 5;\n\t\t\tCustomClassProp.CustomClassProp >>= 5;\n\t\t\tGetClass().CustomClassField >>= 5;\n\t\t\tGetClass().CustomClassProp >>= 5;\n#if CS70\n\t\t\tGetRefStruct().CustomClassField >>= 5;\n\t\t\tGetRefStruct().CustomClassProp >>= 5;\n\t\t\tGetRefCustomClass() >>= 5;\n#endif\n\t\t}\n\n\t\tpublic static void CustomClassBitAndTest(CustomClass p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomClass num = null;\n\t\t\tp &= (CustomClass)null;\n\t\t\tnum &= (CustomClass)null;\n\t\t\tUse(ref num);\n\t\t\tcustomClassField &= (CustomClass)null;\n\t\t\tCustomClassProp &= (CustomClass)null;\n\t\t\tc.CustomClassField &= (CustomClass)null;\n\t\t\tc.CustomClassProp &= (CustomClass)null;\n\t\t\ts.CustomClassField &= (CustomClass)null;\n\t\t\ts.CustomClassProp &= (CustomClass)null;\n\t\t\tcustomClassField.CustomClassField &= (CustomClass)null;\n\t\t\tcustomClassField.CustomClassProp &= (CustomClass)null;\n\t\t\totherCustomStructField.CustomClassField &= (CustomClass)null;\n\t\t\totherCustomStructField.CustomClassProp &= (CustomClass)null;\n\t\t\tCustomClassProp.CustomClassField &= (CustomClass)null;\n\t\t\tCustomClassProp.CustomClassProp &= (CustomClass)null;\n\t\t\tGetClass().CustomClassField &= (CustomClass)null;\n\t\t\tGetClass().CustomClassProp &= (CustomClass)null;\n#if CS70\n\t\t\tGetRefStruct().CustomClassField &= (CustomClass)null;\n\t\t\tGetRefStruct().CustomClassProp &= (CustomClass)null;\n\t\t\tGetRefCustomClass() &= (CustomClass)null;\n#endif\n\t\t}\n\n\t\tpublic static void CustomClassBitOrTest(CustomClass p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomClass num = null;\n\t\t\tp |= (CustomClass)null;\n\t\t\tnum |= (CustomClass)null;\n\t\t\tUse(ref num);\n\t\t\tcustomClassField |= (CustomClass)null;\n\t\t\tCustomClassProp |= (CustomClass)null;\n\t\t\tc.CustomClassField |= (CustomClass)null;\n\t\t\tc.CustomClassProp |= (CustomClass)null;\n\t\t\ts.CustomClassField |= (CustomClass)null;\n\t\t\ts.CustomClassProp |= (CustomClass)null;\n\t\t\tcustomClassField.CustomClassField |= (CustomClass)null;\n\t\t\tcustomClassField.CustomClassProp |= (CustomClass)null;\n\t\t\totherCustomStructField.CustomClassField |= (CustomClass)null;\n\t\t\totherCustomStructField.CustomClassProp |= (CustomClass)null;\n\t\t\tCustomClassProp.CustomClassField |= (CustomClass)null;\n\t\t\tCustomClassProp.CustomClassProp |= (CustomClass)null;\n\t\t\tGetClass().CustomClassField |= (CustomClass)null;\n\t\t\tGetClass().CustomClassProp |= (CustomClass)null;\n#if CS70\n\t\t\tGetRefStruct().CustomClassField |= (CustomClass)null;\n\t\t\tGetRefStruct().CustomClassProp |= (CustomClass)null;\n\t\t\tGetRefCustomClass() |= (CustomClass)null;\n#endif\n\t\t}\n\n\t\tpublic static void CustomClassBitXorTest(CustomClass p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomClass num = null;\n\t\t\tp ^= (CustomClass)null;\n\t\t\tnum ^= (CustomClass)null;\n\t\t\tUse(ref num);\n\t\t\tcustomClassField ^= (CustomClass)null;\n\t\t\tCustomClassProp ^= (CustomClass)null;\n\t\t\tc.CustomClassField ^= (CustomClass)null;\n\t\t\tc.CustomClassProp ^= (CustomClass)null;\n\t\t\ts.CustomClassField ^= (CustomClass)null;\n\t\t\ts.CustomClassProp ^= (CustomClass)null;\n\t\t\tcustomClassField.CustomClassField ^= (CustomClass)null;\n\t\t\tcustomClassField.CustomClassProp ^= (CustomClass)null;\n\t\t\totherCustomStructField.CustomClassField ^= (CustomClass)null;\n\t\t\totherCustomStructField.CustomClassProp ^= (CustomClass)null;\n\t\t\tCustomClassProp.CustomClassField ^= (CustomClass)null;\n\t\t\tCustomClassProp.CustomClassProp ^= (CustomClass)null;\n\t\t\tGetClass().CustomClassField ^= (CustomClass)null;\n\t\t\tGetClass().CustomClassProp ^= (CustomClass)null;\n#if CS70\n\t\t\tGetRefStruct().CustomClassField ^= (CustomClass)null;\n\t\t\tGetRefStruct().CustomClassProp ^= (CustomClass)null;\n\t\t\tGetRefCustomClass() ^= (CustomClass)null;\n#endif\n\t\t}\n\n\t\tpublic static void CustomClassPostIncTest(CustomClass p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomClass num = null;\n\t\t\tX(p++);\n\t\t\tX(num++);\n\t\t\tUse(ref num);\n\t\t\tX(customClassField++);\n\t\t\tX(CustomClassProp++);\n\t\t\tX(c.CustomClassField++);\n\t\t\tX(c.CustomClassProp++);\n\t\t\tX(s.CustomClassField++);\n\t\t\tX(s.CustomClassProp++);\n\t\t\tX(customClassField.CustomClassField++);\n\t\t\tX(customClassField.CustomClassProp++);\n\t\t\tX(otherCustomStructField.CustomClassField++);\n\t\t\tX(otherCustomStructField.CustomClassProp++);\n\t\t\tX(CustomClassProp.CustomClassField++);\n\t\t\tX(CustomClassProp.CustomClassProp++);\n\t\t\tX(GetClass().CustomClassField++);\n\t\t\tX(GetClass().CustomClassProp++);\n#if CS70\n\t\t\tX(GetRefStruct().CustomClassField++);\n\t\t\tX(GetRefStruct().CustomClassProp++);\n\t\t\tX(GetRefCustomClass()++);\n#endif\n\t\t}\n\n\t\tpublic static void CustomClassPreIncTest(CustomClass p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomClass num = null;\n\t\t\tX(++p);\n\t\t\tX(++num);\n\t\t\tUse(ref num);\n\t\t\tX(++customClassField);\n\t\t\tX(++CustomClassProp);\n\t\t\tX(++c.CustomClassField);\n\t\t\tX(++c.CustomClassProp);\n\t\t\tX(++s.CustomClassField);\n\t\t\tX(++s.CustomClassProp);\n\t\t\tX(++customClassField.CustomClassField);\n\t\t\tX(++customClassField.CustomClassProp);\n\t\t\tX(++otherCustomStructField.CustomClassField);\n\t\t\tX(++otherCustomStructField.CustomClassProp);\n\t\t\tX(++CustomClassProp.CustomClassField);\n\t\t\tX(++CustomClassProp.CustomClassProp);\n\t\t\tX(++GetClass().CustomClassField);\n\t\t\tX(++GetClass().CustomClassProp);\n#if CS70\n\t\t\tX(++GetRefStruct().CustomClassField);\n\t\t\tX(++GetRefStruct().CustomClassProp);\n\t\t\tX(++GetRefCustomClass());\n#endif\n\t\t}\n\t\tpublic static void CustomClassPostDecTest(CustomClass p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomClass num = null;\n\t\t\tX(p--);\n\t\t\tX(num--);\n\t\t\tUse(ref num);\n\t\t\tX(customClassField--);\n\t\t\tX(CustomClassProp--);\n\t\t\tX(c.CustomClassField--);\n\t\t\tX(c.CustomClassProp--);\n\t\t\tX(s.CustomClassField--);\n\t\t\tX(s.CustomClassProp--);\n\t\t\tX(customClassField.CustomClassField--);\n\t\t\tX(customClassField.CustomClassProp--);\n\t\t\tX(otherCustomStructField.CustomClassField--);\n\t\t\tX(otherCustomStructField.CustomClassProp--);\n\t\t\tX(CustomClassProp.CustomClassField--);\n\t\t\tX(CustomClassProp.CustomClassProp--);\n\t\t\tX(GetClass().CustomClassField--);\n\t\t\tX(GetClass().CustomClassProp--);\n#if CS70\n\t\t\tX(GetRefStruct().CustomClassField--);\n\t\t\tX(GetRefStruct().CustomClassProp--);\n\t\t\tX(GetRefCustomClass()--);\n#endif\n\t\t}\n\n\t\tpublic static void CustomClassPreDecTest(CustomClass p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomClass num = null;\n\t\t\tX(--p);\n\t\t\tX(--num);\n\t\t\tUse(ref num);\n\t\t\tX(--customClassField);\n\t\t\tX(--CustomClassProp);\n\t\t\tX(--c.CustomClassField);\n\t\t\tX(--c.CustomClassProp);\n\t\t\tX(--s.CustomClassField);\n\t\t\tX(--s.CustomClassProp);\n\t\t\tX(--customClassField.CustomClassField);\n\t\t\tX(--customClassField.CustomClassProp);\n\t\t\tX(--otherCustomStructField.CustomClassField);\n\t\t\tX(--otherCustomStructField.CustomClassProp);\n\t\t\tX(--CustomClassProp.CustomClassField);\n\t\t\tX(--CustomClassProp.CustomClassProp);\n\t\t\tX(--GetClass().CustomClassField);\n\t\t\tX(--GetClass().CustomClassProp);\n#if CS70\n\t\t\tX(--GetRefStruct().CustomClassField);\n\t\t\tX(--GetRefStruct().CustomClassProp);\n\t\t\tX(--GetRefCustomClass());\n#endif\n\t\t}\n\t\tpublic static void CustomStructAddTest(CustomStruct p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomStruct num = default(CustomStruct);\n\t\t\tp += default(CustomStruct);\n\t\t\tnum += default(CustomStruct);\n\t\t\tUse(ref num);\n\t\t\tcustomStructField += default(CustomStruct);\n\t\t\tCustomStructProp += default(CustomStruct);\n\t\t\tc.CustomStructField += default(CustomStruct);\n\t\t\tc.CustomStructProp += default(CustomStruct);\n\t\t\ts.CustomStructField += default(CustomStruct);\n\t\t\ts.CustomStructProp += default(CustomStruct);\n\t\t\tcustomClassField.CustomStructField += default(CustomStruct);\n\t\t\tcustomClassField.CustomStructProp += default(CustomStruct);\n\t\t\totherCustomStructField.CustomStructField += default(CustomStruct);\n\t\t\totherCustomStructField.CustomStructProp += default(CustomStruct);\n\t\t\tCustomClassProp.CustomStructField += default(CustomStruct);\n\t\t\tCustomClassProp.CustomStructProp += default(CustomStruct);\n\t\t\tGetClass().CustomStructField += default(CustomStruct);\n\t\t\tGetClass().CustomStructProp += default(CustomStruct);\n#if CS70\n\t\t\tGetRefStruct().CustomStructField += default(CustomStruct);\n\t\t\tGetRefStruct().CustomStructProp += default(CustomStruct);\n\t\t\tGetRefCustomStruct() += default(CustomStruct);\n#endif\n\t\t}\n\n\t\tpublic static void CustomStructSubtractTest(CustomStruct p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomStruct num = default(CustomStruct);\n\t\t\tp -= default(CustomStruct);\n\t\t\tnum -= default(CustomStruct);\n\t\t\tUse(ref num);\n\t\t\tcustomStructField -= default(CustomStruct);\n\t\t\tCustomStructProp -= default(CustomStruct);\n\t\t\tc.CustomStructField -= default(CustomStruct);\n\t\t\tc.CustomStructProp -= default(CustomStruct);\n\t\t\ts.CustomStructField -= default(CustomStruct);\n\t\t\ts.CustomStructProp -= default(CustomStruct);\n\t\t\tcustomClassField.CustomStructField -= default(CustomStruct);\n\t\t\tcustomClassField.CustomStructProp -= default(CustomStruct);\n\t\t\totherCustomStructField.CustomStructField -= default(CustomStruct);\n\t\t\totherCustomStructField.CustomStructProp -= default(CustomStruct);\n\t\t\tCustomClassProp.CustomStructField -= default(CustomStruct);\n\t\t\tCustomClassProp.CustomStructProp -= default(CustomStruct);\n\t\t\tGetClass().CustomStructField -= default(CustomStruct);\n\t\t\tGetClass().CustomStructProp -= default(CustomStruct);\n#if CS70\n\t\t\tGetRefStruct().CustomStructField -= default(CustomStruct);\n\t\t\tGetRefStruct().CustomStructProp -= default(CustomStruct);\n\t\t\tGetRefCustomStruct() -= default(CustomStruct);\n#endif\n\t\t}\n\n\t\tpublic static void CustomStructMultiplyTest(CustomStruct p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomStruct num = default(CustomStruct);\n\t\t\tp *= default(CustomStruct);\n\t\t\tnum *= default(CustomStruct);\n\t\t\tUse(ref num);\n\t\t\tcustomStructField *= default(CustomStruct);\n\t\t\tCustomStructProp *= default(CustomStruct);\n\t\t\tc.CustomStructField *= default(CustomStruct);\n\t\t\tc.CustomStructProp *= default(CustomStruct);\n\t\t\ts.CustomStructField *= default(CustomStruct);\n\t\t\ts.CustomStructProp *= default(CustomStruct);\n\t\t\tcustomClassField.CustomStructField *= default(CustomStruct);\n\t\t\tcustomClassField.CustomStructProp *= default(CustomStruct);\n\t\t\totherCustomStructField.CustomStructField *= default(CustomStruct);\n\t\t\totherCustomStructField.CustomStructProp *= default(CustomStruct);\n\t\t\tCustomClassProp.CustomStructField *= default(CustomStruct);\n\t\t\tCustomClassProp.CustomStructProp *= default(CustomStruct);\n\t\t\tGetClass().CustomStructField *= default(CustomStruct);\n\t\t\tGetClass().CustomStructProp *= default(CustomStruct);\n#if CS70\n\t\t\tGetRefStruct().CustomStructField *= default(CustomStruct);\n\t\t\tGetRefStruct().CustomStructProp *= default(CustomStruct);\n\t\t\tGetRefCustomStruct() *= default(CustomStruct);\n#endif\n\t\t}\n\n\t\tpublic static void CustomStructDivideTest(CustomStruct p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomStruct num = default(CustomStruct);\n\t\t\tp /= default(CustomStruct);\n\t\t\tnum /= default(CustomStruct);\n\t\t\tUse(ref num);\n\t\t\tcustomStructField /= default(CustomStruct);\n\t\t\tCustomStructProp /= default(CustomStruct);\n\t\t\tc.CustomStructField /= default(CustomStruct);\n\t\t\tc.CustomStructProp /= default(CustomStruct);\n\t\t\ts.CustomStructField /= default(CustomStruct);\n\t\t\ts.CustomStructProp /= default(CustomStruct);\n\t\t\tcustomClassField.CustomStructField /= default(CustomStruct);\n\t\t\tcustomClassField.CustomStructProp /= default(CustomStruct);\n\t\t\totherCustomStructField.CustomStructField /= default(CustomStruct);\n\t\t\totherCustomStructField.CustomStructProp /= default(CustomStruct);\n\t\t\tCustomClassProp.CustomStructField /= default(CustomStruct);\n\t\t\tCustomClassProp.CustomStructProp /= default(CustomStruct);\n\t\t\tGetClass().CustomStructField /= default(CustomStruct);\n\t\t\tGetClass().CustomStructProp /= default(CustomStruct);\n#if CS70\n\t\t\tGetRefStruct().CustomStructField /= default(CustomStruct);\n\t\t\tGetRefStruct().CustomStructProp /= default(CustomStruct);\n\t\t\tGetRefCustomStruct() /= default(CustomStruct);\n#endif\n\t\t}\n\n\t\tpublic static void CustomStructModulusTest(CustomStruct p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomStruct num = default(CustomStruct);\n\t\t\tp %= default(CustomStruct);\n\t\t\tnum %= default(CustomStruct);\n\t\t\tUse(ref num);\n\t\t\tcustomStructField %= default(CustomStruct);\n\t\t\tCustomStructProp %= default(CustomStruct);\n\t\t\tc.CustomStructField %= default(CustomStruct);\n\t\t\tc.CustomStructProp %= default(CustomStruct);\n\t\t\ts.CustomStructField %= default(CustomStruct);\n\t\t\ts.CustomStructProp %= default(CustomStruct);\n\t\t\tcustomClassField.CustomStructField %= default(CustomStruct);\n\t\t\tcustomClassField.CustomStructProp %= default(CustomStruct);\n\t\t\totherCustomStructField.CustomStructField %= default(CustomStruct);\n\t\t\totherCustomStructField.CustomStructProp %= default(CustomStruct);\n\t\t\tCustomClassProp.CustomStructField %= default(CustomStruct);\n\t\t\tCustomClassProp.CustomStructProp %= default(CustomStruct);\n\t\t\tGetClass().CustomStructField %= default(CustomStruct);\n\t\t\tGetClass().CustomStructProp %= default(CustomStruct);\n#if CS70\n\t\t\tGetRefStruct().CustomStructField %= default(CustomStruct);\n\t\t\tGetRefStruct().CustomStructProp %= default(CustomStruct);\n\t\t\tGetRefCustomStruct() %= default(CustomStruct);\n#endif\n\t\t}\n\n\t\tpublic static void CustomStructLeftShiftTest(CustomStruct p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomStruct num = default(CustomStruct);\n\t\t\tp <<= 5;\n\t\t\tnum <<= 5;\n\t\t\tUse(ref num);\n\t\t\tcustomStructField <<= 5;\n\t\t\tCustomStructProp <<= 5;\n\t\t\tc.CustomStructField <<= 5;\n\t\t\tc.CustomStructProp <<= 5;\n\t\t\ts.CustomStructField <<= 5;\n\t\t\ts.CustomStructProp <<= 5;\n\t\t\tcustomClassField.CustomStructField <<= 5;\n\t\t\tcustomClassField.CustomStructProp <<= 5;\n\t\t\totherCustomStructField.CustomStructField <<= 5;\n\t\t\totherCustomStructField.CustomStructProp <<= 5;\n\t\t\tCustomClassProp.CustomStructField <<= 5;\n\t\t\tCustomClassProp.CustomStructProp <<= 5;\n\t\t\tGetClass().CustomStructField <<= 5;\n\t\t\tGetClass().CustomStructProp <<= 5;\n#if CS70\n\t\t\tGetRefStruct().CustomStructField <<= 5;\n\t\t\tGetRefStruct().CustomStructProp <<= 5;\n\t\t\tGetRefCustomStruct() <<= 5;\n#endif\n\t\t}\n\n\t\tpublic static void CustomStructRightShiftTest(CustomStruct p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomStruct num = default(CustomStruct);\n\t\t\tp >>= 5;\n\t\t\tnum >>= 5;\n\t\t\tUse(ref num);\n\t\t\tcustomStructField >>= 5;\n\t\t\tCustomStructProp >>= 5;\n\t\t\tc.CustomStructField >>= 5;\n\t\t\tc.CustomStructProp >>= 5;\n\t\t\ts.CustomStructField >>= 5;\n\t\t\ts.CustomStructProp >>= 5;\n\t\t\tcustomClassField.CustomStructField >>= 5;\n\t\t\tcustomClassField.CustomStructProp >>= 5;\n\t\t\totherCustomStructField.CustomStructField >>= 5;\n\t\t\totherCustomStructField.CustomStructProp >>= 5;\n\t\t\tCustomClassProp.CustomStructField >>= 5;\n\t\t\tCustomClassProp.CustomStructProp >>= 5;\n\t\t\tGetClass().CustomStructField >>= 5;\n\t\t\tGetClass().CustomStructProp >>= 5;\n#if CS70\n\t\t\tGetRefStruct().CustomStructField >>= 5;\n\t\t\tGetRefStruct().CustomStructProp >>= 5;\n\t\t\tGetRefCustomStruct() >>= 5;\n#endif\n\t\t}\n\n#if CS110\n\t\tpublic static void CustomStructUnsignedRightShiftTest(CustomStruct p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\t//CustomStruct l = default(CustomStruct);\n\t\t\t//p >>>= 5;\n\t\t\t//l >>>= 5;\n\t\t\tcustomStructField >>>= 5;\n\t\t\tCustomStructProp >>>= 5;\n\t\t\tc.CustomStructField >>>= 5;\n\t\t\tc.CustomStructProp >>>= 5;\n\t\t\ts.CustomStructField >>>= 5;\n\t\t\ts.CustomStructProp >>>= 5;\n\t\t\tcustomClassField.CustomStructField >>>= 5;\n\t\t\tcustomClassField.CustomStructProp >>>= 5;\n\t\t\totherCustomStructField.CustomStructField >>>= 5;\n\t\t\totherCustomStructField.CustomStructProp >>>= 5;\n\t\t\tCustomClassProp.CustomStructField >>>= 5;\n\t\t\tCustomClassProp.CustomStructProp >>>= 5;\n\t\t\tGetClass().CustomStructField >>>= 5;\n\t\t\tGetClass().CustomStructProp >>>= 5;\n\t\t\tGetRefStruct().CustomStructField >>>= 5;\n\t\t\tGetRefStruct().CustomStructProp >>>= 5;\n\t\t\tGetRefCustomStruct() >>>= 5;\n\t\t}\n#endif\n\n\t\tpublic static void CustomStructBitAndTest(CustomStruct p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomStruct num = default(CustomStruct);\n\t\t\tp &= default(CustomStruct);\n\t\t\tnum &= default(CustomStruct);\n\t\t\tUse(ref num);\n\t\t\tcustomStructField &= default(CustomStruct);\n\t\t\tCustomStructProp &= default(CustomStruct);\n\t\t\tc.CustomStructField &= default(CustomStruct);\n\t\t\tc.CustomStructProp &= default(CustomStruct);\n\t\t\ts.CustomStructField &= default(CustomStruct);\n\t\t\ts.CustomStructProp &= default(CustomStruct);\n\t\t\tcustomClassField.CustomStructField &= default(CustomStruct);\n\t\t\tcustomClassField.CustomStructProp &= default(CustomStruct);\n\t\t\totherCustomStructField.CustomStructField &= default(CustomStruct);\n\t\t\totherCustomStructField.CustomStructProp &= default(CustomStruct);\n\t\t\tCustomClassProp.CustomStructField &= default(CustomStruct);\n\t\t\tCustomClassProp.CustomStructProp &= default(CustomStruct);\n\t\t\tGetClass().CustomStructField &= default(CustomStruct);\n\t\t\tGetClass().CustomStructProp &= default(CustomStruct);\n#if CS70\n\t\t\tGetRefStruct().CustomStructField &= default(CustomStruct);\n\t\t\tGetRefStruct().CustomStructProp &= default(CustomStruct);\n\t\t\tGetRefCustomStruct() &= default(CustomStruct);\n#endif\n\t\t}\n\n\t\tpublic static void CustomStructBitOrTest(CustomStruct p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomStruct num = default(CustomStruct);\n\t\t\tp |= default(CustomStruct);\n\t\t\tnum |= default(CustomStruct);\n\t\t\tUse(ref num);\n\t\t\tcustomStructField |= default(CustomStruct);\n\t\t\tCustomStructProp |= default(CustomStruct);\n\t\t\tc.CustomStructField |= default(CustomStruct);\n\t\t\tc.CustomStructProp |= default(CustomStruct);\n\t\t\ts.CustomStructField |= default(CustomStruct);\n\t\t\ts.CustomStructProp |= default(CustomStruct);\n\t\t\tcustomClassField.CustomStructField |= default(CustomStruct);\n\t\t\tcustomClassField.CustomStructProp |= default(CustomStruct);\n\t\t\totherCustomStructField.CustomStructField |= default(CustomStruct);\n\t\t\totherCustomStructField.CustomStructProp |= default(CustomStruct);\n\t\t\tCustomClassProp.CustomStructField |= default(CustomStruct);\n\t\t\tCustomClassProp.CustomStructProp |= default(CustomStruct);\n\t\t\tGetClass().CustomStructField |= default(CustomStruct);\n\t\t\tGetClass().CustomStructProp |= default(CustomStruct);\n#if CS70\n\t\t\tGetRefStruct().CustomStructField |= default(CustomStruct);\n\t\t\tGetRefStruct().CustomStructProp |= default(CustomStruct);\n\t\t\tGetRefCustomStruct() |= default(CustomStruct);\n#endif\n\t\t}\n\n\t\tpublic static void CustomStructBitXorTest(CustomStruct p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomStruct num = default(CustomStruct);\n\t\t\tp ^= default(CustomStruct);\n\t\t\tnum ^= default(CustomStruct);\n\t\t\tUse(ref num);\n\t\t\tcustomStructField ^= default(CustomStruct);\n\t\t\tCustomStructProp ^= default(CustomStruct);\n\t\t\tc.CustomStructField ^= default(CustomStruct);\n\t\t\tc.CustomStructProp ^= default(CustomStruct);\n\t\t\ts.CustomStructField ^= default(CustomStruct);\n\t\t\ts.CustomStructProp ^= default(CustomStruct);\n\t\t\tcustomClassField.CustomStructField ^= default(CustomStruct);\n\t\t\tcustomClassField.CustomStructProp ^= default(CustomStruct);\n\t\t\totherCustomStructField.CustomStructField ^= default(CustomStruct);\n\t\t\totherCustomStructField.CustomStructProp ^= default(CustomStruct);\n\t\t\tCustomClassProp.CustomStructField ^= default(CustomStruct);\n\t\t\tCustomClassProp.CustomStructProp ^= default(CustomStruct);\n\t\t\tGetClass().CustomStructField ^= default(CustomStruct);\n\t\t\tGetClass().CustomStructProp ^= default(CustomStruct);\n#if CS70\n\t\t\tGetRefStruct().CustomStructField ^= default(CustomStruct);\n\t\t\tGetRefStruct().CustomStructProp ^= default(CustomStruct);\n\t\t\tGetRefCustomStruct() ^= default(CustomStruct);\n#endif\n\t\t}\n\n\t\tpublic static void CustomStructPostIncTest(CustomStruct p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomStruct num = default(CustomStruct);\n\t\t\tX(p++);\n\t\t\tX(num++);\n\t\t\tUse(ref num);\n\t\t\tX(customStructField++);\n\t\t\tX(CustomStructProp++);\n\t\t\tX(c.CustomStructField++);\n\t\t\tX(c.CustomStructProp++);\n\t\t\tX(s.CustomStructField++);\n\t\t\tX(s.CustomStructProp++);\n\t\t\tX(customClassField.CustomStructField++);\n\t\t\tX(customClassField.CustomStructProp++);\n\t\t\tX(otherCustomStructField.CustomStructField++);\n\t\t\tX(otherCustomStructField.CustomStructProp++);\n\t\t\tX(CustomClassProp.CustomStructField++);\n\t\t\tX(CustomClassProp.CustomStructProp++);\n\t\t\tX(GetClass().CustomStructField++);\n\t\t\tX(GetClass().CustomStructProp++);\n#if CS70\n\t\t\tX(GetRefStruct().CustomStructField++);\n\t\t\tX(GetRefStruct().CustomStructProp++);\n\t\t\tX(GetRefCustomStruct()++);\n#endif\n\t\t}\n\n\t\tpublic static void CustomStructPreIncTest(CustomStruct p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomStruct num = default(CustomStruct);\n\t\t\tX(++p);\n\t\t\tX(++num);\n\t\t\tUse(ref num);\n\t\t\tX(++customStructField);\n\t\t\tX(++CustomStructProp);\n\t\t\tX(++c.CustomStructField);\n\t\t\tX(++c.CustomStructProp);\n\t\t\tX(++s.CustomStructField);\n\t\t\tX(++s.CustomStructProp);\n\t\t\tX(++customClassField.CustomStructField);\n\t\t\tX(++customClassField.CustomStructProp);\n\t\t\tX(++otherCustomStructField.CustomStructField);\n\t\t\tX(++otherCustomStructField.CustomStructProp);\n\t\t\tX(++CustomClassProp.CustomStructField);\n\t\t\tX(++CustomClassProp.CustomStructProp);\n\t\t\tX(++GetClass().CustomStructField);\n\t\t\tX(++GetClass().CustomStructProp);\n#if CS70\n\t\t\tX(++GetRefStruct().CustomStructField);\n\t\t\tX(++GetRefStruct().CustomStructProp);\n\t\t\tX(++GetRefCustomStruct());\n#endif\n\t\t}\n\t\tpublic static void CustomStructPostDecTest(CustomStruct p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomStruct num = default(CustomStruct);\n\t\t\tX(p--);\n\t\t\tX(num--);\n\t\t\tUse(ref num);\n\t\t\tX(customStructField--);\n\t\t\tX(CustomStructProp--);\n\t\t\tX(c.CustomStructField--);\n\t\t\tX(c.CustomStructProp--);\n\t\t\tX(s.CustomStructField--);\n\t\t\tX(s.CustomStructProp--);\n\t\t\tX(customClassField.CustomStructField--);\n\t\t\tX(customClassField.CustomStructProp--);\n\t\t\tX(otherCustomStructField.CustomStructField--);\n\t\t\tX(otherCustomStructField.CustomStructProp--);\n\t\t\tX(CustomClassProp.CustomStructField--);\n\t\t\tX(CustomClassProp.CustomStructProp--);\n\t\t\tX(GetClass().CustomStructField--);\n\t\t\tX(GetClass().CustomStructProp--);\n#if CS70\n\t\t\tX(GetRefStruct().CustomStructField--);\n\t\t\tX(GetRefStruct().CustomStructProp--);\n\t\t\tX(GetRefCustomStruct()--);\n#endif\n\t\t}\n\n\t\tpublic static void CustomStructPreDecTest(CustomStruct p, CustomClass c, CustomStruct2 s)\n\t\t{\n\t\t\tCustomStruct num = default(CustomStruct);\n\t\t\tX(--p);\n\t\t\tX(--num);\n\t\t\tUse(ref num);\n\t\t\tX(--customStructField);\n\t\t\tX(--CustomStructProp);\n\t\t\tX(--c.CustomStructField);\n\t\t\tX(--c.CustomStructProp);\n\t\t\tX(--s.CustomStructField);\n\t\t\tX(--s.CustomStructProp);\n\t\t\tX(--customClassField.CustomStructField);\n\t\t\tX(--customClassField.CustomStructProp);\n\t\t\tX(--otherCustomStructField.CustomStructField);\n\t\t\tX(--otherCustomStructField.CustomStructProp);\n\t\t\tX(--CustomClassProp.CustomStructField);\n\t\t\tX(--CustomClassProp.CustomStructProp);\n\t\t\tX(--GetClass().CustomStructField);\n\t\t\tX(--GetClass().CustomStructProp);\n#if CS70\n\t\t\tX(--GetRefStruct().CustomStructField);\n\t\t\tX(--GetRefStruct().CustomStructProp);\n\t\t\tX(--GetRefCustomStruct());\n#endif\n\t\t}\n\t\t#endregion\n\n\t\tpublic static void AddOneToCustomClass(ref CustomClass c)\n\t\t{\n\t\t\t// This should not be turned into post-increment:\n\t\t\tc += 1;\n\t\t\tc.CustomClassProp += 1;\n\t\t}\n\n\t\tprivate static Item GetItem(object obj)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tprivate static void Issue882()\n\t\t{\n\t\t\tItem item = GetItem(null);\n\t\t\titem.Self = item;\n\t\t}\n\n\t\tprivate void Issue954(ref MyEnum a, MyEnum b)\n\t\t{\n\t\t\t// cannot decompile to: \"a %= b;\", because the % operator does not apply to enums\n\t\t\ta = (MyEnum)((int)a % (int)b);\n\t\t\t// same with enum field:\n\t\t\tenumField = (MyEnum)((int)enumField % (int)b);\n\t\t}\n\n\t\tprivate void Issue588(ushort val)\n\t\t{\n\t\t\tushortDict.Add(ushortField++, val);\n\t\t}\n\n\t\tprivate void Issue1007(TimeSpan[] items, int startIndex, TimeSpan item)\n\t\t{\n\t\t\tint num = startIndex;\n\t\t\titems[num++] = item;\n\t\t\titems[num++] = item;\n\t\t}\n\n#if !LEGACY_CSC\n\t\t// Legacy csc generates a slightly different pattern for string compound assignment\n\t\t// as for all other compound assignments. We'll ignore that edge case.\n\t\t// Note: it's possible that the pre-CopyPropagation run of TransformAssignments is causing trouble there,\n\t\t// and that the compound assignment transform would be fine if it didn't get disrupted.\n\n\t\tprivate static void Issue1082(string[] strings, List<char> chars, bool flag, int i)\n\t\t{\n\t\t\t// The 'chars[i]' result is stored in a temporary, and both branches use the\n\t\t\t// same temporary. In order to inline the generated value-type temporary, we\n\t\t\t// need to split it, even though it has the address taken for the ToString() call.\n\t\t\tif (flag)\n\t\t\t{\n\t\t\t\tstrings[1] += chars[i];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tstrings[0] += chars[i];\n\t\t\t}\n\t\t}\n#endif\n\n\t\tprivate static void StringPropertyCompoundAssign(char c)\n\t\t{\n\t\t\tStaticStringProperty += \"a\";\n\t\t\tStaticStringProperty += 1;\n\t\t\tStaticStringProperty += c;\n\t\t\tnew CustomClass().StringProp += \"a\";\n\t\t\tnew CustomClass().StringProp += 1;\n\t\t\tnew CustomClass().StringProp += c;\n\t\t}\n\n\t\tpublic uint PreIncrementIndexer(string name)\n\t\t{\n\t\t\treturn ++M()[name];\n\t\t}\n\n\t\tpublic int PreIncrementByRef(ref int i)\n\t\t{\n\t\t\treturn ++i;\n\t\t}\n\n\t\tpublic unsafe int PreIncrementByPointer()\n\t\t{\n\t\t\treturn ++(*GetPointer());\n\t\t}\n\n\t\tpublic unsafe int PreIncrementOfPointer(int* ptr)\n\t\t{\n\t\t\treturn *(++ptr);\n\t\t}\n\n\t\tpublic int PreIncrement2DArray()\n\t\t{\n\t\t\treturn ++Array()[1, 2];\n\t\t}\n\n\t\tpublic int CompoundAssignInstanceField()\n\t\t{\n\t\t\treturn M().Field *= 10;\n\t\t}\n\n\t\tpublic int CompoundAssignInstanceProperty()\n\t\t{\n\t\t\treturn M().Property *= 10;\n\t\t}\n\n\t\tpublic int CompoundAssignStaticField()\n\t\t{\n\t\t\treturn StaticField ^= 100;\n\t\t}\n\n\t\tpublic int CompoundAssignStaticProperty()\n\t\t{\n\t\t\treturn StaticProperty &= 10;\n\t\t}\n\n\t\tpublic int CompoundAssignArrayElement1(int[] array, int pos)\n\t\t{\n\t\t\treturn array[pos] *= 10;\n\t\t}\n\n\t\tpublic int CompoundAssignArrayElement2(int[] array)\n\t\t{\n\t\t\treturn array[Environment.TickCount] *= 10;\n\t\t}\n\n\t\tpublic uint CompoundAssignIndexer(string name)\n\t\t{\n\t\t\treturn M()[name] -= 2u;\n\t\t}\n\n\t\tpublic uint CompoundAssignIndexerComplexIndex()\n\t\t{\n\t\t\treturn M()[ToString()] -= 2u;\n\t\t}\n\n\t\tpublic int CompoundAssignIncrement2DArray()\n\t\t{\n\t\t\treturn Array()[1, 2] %= 10;\n\t\t}\n\n\t\tpublic int CompoundAssignByRef(ref int i)\n\t\t{\n\t\t\treturn i <<= 2;\n\t\t}\n\n\t\tpublic unsafe int* CompoundAssignOfPointer(int* ptr)\n\t\t{\n\t\t\treturn ptr += 10;\n\t\t}\n\n\t\tpublic unsafe double CompoundAssignByPointer(double* ptr)\n\t\t{\n\t\t\treturn *ptr /= 1.5;\n\t\t}\n\n\t\tpublic void CompoundAssignEnum()\n\t\t{\n\t\t\tenumField |= MyEnum.Two;\n\t\t\tenumField &= ~MyEnum.Four;\n\t\t}\n\n\t\tpublic int PostIncrementInAddition(int i, int j)\n\t\t{\n\t\t\treturn i++ + j;\n\t\t}\n\n\t\tpublic void PostIncrementInlineLocalVariable(Func<int, int> f)\n\t\t{\n\t\t\tint num = 0;\n\t\t\tf(num++);\n\t\t}\n\n\t\tpublic int PostDecrementArrayElement(int[] array, int pos)\n\t\t{\n\t\t\treturn array[pos]--;\n\t\t}\n\n\t\tpublic uint PostIncrementIndexer(string name)\n\t\t{\n\t\t\treturn M()[name]++;\n\t\t}\n\n\t\tpublic unsafe int PostIncrementOfPointer(int* ptr)\n\t\t{\n\t\t\treturn *(ptr++);\n\t\t}\n\n\t\tpublic unsafe int PostIncrementOfSmallIntegerPointerDereference(byte* ptr)\n\t\t{\n\t\t\treturn (*ptr)++ * (*ptr)++;\n\t\t}\n\n\t\tpublic unsafe int PreIncrementOfSmallIntegerPointerDereference(byte* ptr)\n\t\t{\n\t\t\treturn ++(*ptr) * ++(*ptr);\n\t\t}\n\n\t\tpublic unsafe int CompoundAssignSmallIntegerPointerDereference(byte* ptr)\n\t\t{\n\t\t\treturn (*ptr += 5) * (*ptr += 5);\n\t\t}\n\n\t\tpublic int PostDecrementInstanceField()\n\t\t{\n\t\t\treturn M().Field--;\n\t\t}\n\n\t\tpublic int PostDecrementInstanceProperty()\n\t\t{\n\t\t\treturn M().Property--;\n\t\t}\n\n\t\tpublic int PostIncrement2DArray()\n\t\t{\n\t\t\treturn Array()[StaticField, StaticProperty]++;\n\t\t}\n\n\t\tpublic int PostIncrementByRef(ref int i)\n\t\t{\n\t\t\treturn i++;\n\t\t}\n\n\t\tpublic unsafe int PostIncrementByPointer()\n\t\t{\n\t\t\treturn (*GetPointer())++;\n\t\t}\n\n\t\tpublic float PostIncrementFloat(float f)\n\t\t{\n\t\t\treturn f++;\n\t\t}\n\n\t\tpublic double PostIncrementDouble(double d)\n\t\t{\n\t\t\treturn d++;\n\t\t}\n\n\t\tpublic void Issue1552Pre(CustomStruct a, CustomStruct b)\n\t\t{\n\t\t\tCustomStruct customStruct = a + b;\n\t\t\tConsole.WriteLine(++customStruct);\n\t\t}\n\n\t\tpublic void Issue1552Stmt(CustomStruct a, CustomStruct b)\n\t\t{\n\t\t\tCustomStruct customStruct = a + b;\n\t\t\t++customStruct;\n\t\t}\n\n\t\tpublic void Issue1552StmtUseLater(CustomStruct a, CustomStruct b)\n\t\t{\n\t\t\tCustomStruct customStruct = a + b;\n\t\t\t++customStruct;\n\t\t\tConsole.WriteLine();\n\t\t\tConsole.WriteLine(customStruct * b);\n\t\t}\n\n\t\tpublic void Issue1552Decimal(decimal a)\n\t\t{\n\t\t\t// Legacy csc compiles this using op_Increment,\n\t\t\t// ensure we don't misdetect this as an invalid pre-increment \"++(a * 10m)\"\n\t\t\tConsole.WriteLine(a * 10m + 1m);\n\t\t}\n\n#if !(ROSLYN && OPT)\n\t\t// Roslyn opt no longer has a detectable post-increment pattern\n\t\t// due to optimizing out some of the stores.\n\t\t// Our emitted code is valid but has some additional temporaries.\n\t\tpublic void Issue1552Post(CustomStruct a, CustomStruct b)\n\t\t{\n\t\t\tCustomStruct customStruct = a + b;\n\t\t\tConsole.WriteLine(customStruct++);\n\t\t}\n\n\t\tpublic void Issue1552StmtTwice(CustomStruct a, CustomStruct b)\n\t\t{\n\t\t\tCustomStruct customStruct = a + b;\n\t\t\t++customStruct;\n\t\t\t++customStruct;\n\t\t}\n#endif\n\n\t\tpublic void Issue1779(int value)\n\t\t{\n\t\t\tCustomStruct2 customStruct = GetStruct();\n\t\t\tcustomStruct.IntProp += value;\n\t\t}\n\n#if ROSLYN2\n\t\tpublic static string PreIncrementWithMethodCall(int value)\n\t\t{\n\t\t\treturn (++value).ToString();\n\t\t}\n#endif\n\n#if CS72\n\t\tpublic static string PreIncrementWithInParameter(int value)\n\t\t{\n\t\t\tPreIncrementWithInParameter_Helper(++value);\n\t\t\treturn value.ToString();\n\t\t}\n\t\tpublic static void PreIncrementWithInParameter_Helper(in int value)\n\t\t{\n\t\t}\n#endif\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.cs",
    "content": "#if !(CS110 && NET70)\nusing System;\n#endif\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class ConstantsTests\n\t{\n#if CS90\n\t\tpublic nint? NullableNInt()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic nuint? NullableNUInt()\n\t\t{\n\t\t\treturn null;\n\t\t}\n#endif\n\n#if !(CS110 && NET70)\n\t\tpublic IntPtr? NullableIntPtr()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic UIntPtr? NullableUIntPtr()\n\t\t{\n\t\t\treturn null;\n\t\t}\n#endif\n\n\t\tpublic ulong Issue1308(ulong u = 8uL)\n\t\t{\n\t\t\tTest((u & 0xFFFFFFFFu) != 0);\n\t\t\treturn 18446744069414584320uL;\n\t\t}\n\n\t\tpublic void Byte_BitmaskingInCondition(byte v)\n\t\t{\n\t\t\tTest((v & 0xF) == 0);\n\t\t\tTest((v & 0x123) == 0);\n\t\t\tTest((v | 0xF) == 0);\n\t\t\tTest((v | 0x123) == 0);\n\t\t}\n\n\t\tpublic void SByte_BitmaskingInCondition(sbyte v)\n\t\t{\n\t\t\tTest((v & 0xF) == 0);\n\t\t\tTest((v & 0x123) == 0);\n\t\t\tTest((v | 0xF) == 0);\n\t\t\tTest((v | 0x123) == 0);\n\t\t}\n\n\t\tpublic void Enum_Flag_Check(TaskCreationOptions v)\n\t\t{\n\t\t\tTest((v & TaskCreationOptions.AttachedToParent) != 0);\n\t\t\tTest((v & TaskCreationOptions.AttachedToParent) == 0);\n\t\t}\n\n\t\tprivate void Test(bool expr)\n\t\t{\n\t\t}\n\n\t\tprivate void Test(decimal expr)\n\t\t{\n\t\t}\n\n\t\tpublic void Decimal()\n\t\t{\n\t\t\t// Roslyn and legacy csc both normalize the decimal constant references,\n\t\t\t// but to a different representation (ctor call vs. field use)\n\t\t\tTest(0m);\n\t\t\tTest(1m);\n\t\t\tTest(-1m);\n\t\t\tTest(decimal.MinValue);\n\t\t\tTest(decimal.MaxValue);\n\t\t}\n\n\t\tpublic void BitwiseAndWithConstantUInt64(ulong a)\n\t\t{\n\t\t\tExpectUInt64(a & 7);\n\t\t\tExpectUInt64(a & 0x7FFFFFFF);\n\t\t\tExpectUInt64(a & 0xFFFFFFFFu);\n\t\t\tExpectUInt64(a & 0x7FFFFFFFFFFFFFFFL);\n\t\t\tExpectUInt64(a & 0xFFFFFFFFFFFFFFFFuL);\n\t\t}\n\n\t\tpublic void BitwiseAndWithConstantInt64(long a)\n\t\t{\n\t\t\tExpectInt64(a & 7);\n\t\t\tExpectInt64(a & 0x7FFFFFFF);\n\t\t\tExpectInt64(a & 0xFFFFFFFFu);\n\t\t\tExpectInt64(a & 0x7FFFFFFFFFFFFFFFL);\n\t\t}\n\n\t\tpublic void BitwiseAndWithConstantUInt32(uint a)\n\t\t{\n\t\t\tExpectUInt32(a & 7);\n\t\t\tExpectUInt32(a & 0x7FFFFFFF);\n\t\t\tExpectUInt32(a & 0xFFFFFFFFu);\n\t\t}\n\n\t\tpublic void BitwiseAndWithConstantInt32(int a)\n\t\t{\n\t\t\tExpectInt32(a & 7);\n\t\t\tExpectInt32(a & 0x7FFFFFFF);\n\t\t}\n\n\t\tpublic void BitwiseAndWithConstantUInt16(ushort a)\n\t\t{\n\t\t\tExpectUInt16((ushort)(a & 7));\n\t\t\tExpectUInt16((ushort)(a & 0x7FFF));\n\t\t\tExpectUInt16((ushort)(a & 0xFFFF));\n\t\t}\n\n\t\tpublic void BitwiseAndWithConstantInt16(short a)\n\t\t{\n\t\t\tExpectInt16((short)(a & 7));\n\t\t\tExpectInt16((short)(a & 0x7FFF));\n\t\t}\n\n\t\tpublic void BitwiseAndWithConstantUInt8(byte a)\n\t\t{\n\t\t\tExpectUInt8((byte)(a & 7));\n\t\t\tExpectUInt8((byte)(a & 0x7F));\n\t\t\tExpectUInt8((byte)(a & 0xFF));\n\t\t}\n\n\t\tpublic void BitwiseAndWithConstantInt8(sbyte a)\n\t\t{\n\t\t\tExpectInt8((sbyte)(a & 7));\n\t\t\tExpectInt8((sbyte)(a & 0x7F));\n\t\t}\n\n\t\tpublic void BitwiseOrWithConstantUInt64(ulong a)\n\t\t{\n\t\t\tExpectUInt64(a | 7);\n\t\t\tExpectUInt64(a | 0x7FFFFFFF);\n\t\t\tExpectUInt64(a | 0xFFFFFFFFu);\n\t\t\tExpectUInt64(a | 0x7FFFFFFFFFFFFFFFL);\n\t\t\tExpectUInt64(a | 0xFFFFFFFFFFFFFFFFuL);\n\t\t}\n\n\t\tpublic void BitwiseOrWithConstantInt64(long a)\n\t\t{\n\t\t\tExpectInt64(a | 7);\n\t\t\tExpectInt64(a | 0x7FFFFFFF);\n\t\t\tExpectInt64(a | 0xFFFFFFFFu);\n\t\t\tExpectInt64(a | 0x7FFFFFFFFFFFFFFFL);\n\t\t}\n\n\t\tpublic void BitwiseOrWithConstantUInt32(uint a)\n\t\t{\n\t\t\tExpectUInt32(a | 7);\n\t\t\tExpectUInt32(a | 0x7FFFFFFF);\n\t\t\tExpectUInt32(a | 0xFFFFFFFFu);\n\t\t}\n\n\t\tpublic void BitwiseOrWithConstantInt32(int a)\n\t\t{\n\t\t\tExpectInt32(a | 7);\n\t\t\tExpectInt32(a | 0x7FFFFFFF);\n\t\t}\n\n\t\tpublic void BitwiseOrWithConstantUInt16(ushort a)\n\t\t{\n\t\t\tExpectUInt16((ushort)(a | 7));\n\t\t\tExpectUInt16((ushort)(a | 0x7FFF));\n\t\t\tExpectUInt16((ushort)(a | 0xFFFF));\n\t\t}\n\n\t\tpublic void BitwiseOrWithConstantInt16(short a)\n\t\t{\n\t\t\tExpectInt16((short)(a | 7));\n\t\t\tExpectInt16((short)(a | 0x7FFF));\n\t\t}\n\n\t\tpublic void BitwiseOrWithConstantUInt8(byte a)\n\t\t{\n\t\t\tExpectUInt8((byte)(a | 7));\n\t\t\tExpectUInt8((byte)(a | 0x7F));\n\t\t\tExpectUInt8((byte)(a | 0xFF));\n\t\t}\n\n\t\tpublic void BitwiseOrWithConstantInt8(sbyte a)\n\t\t{\n\t\t\tExpectInt8((sbyte)(a | 7));\n\t\t\tExpectInt8((sbyte)(a | 0x7F));\n\t\t}\n\n\t\tpublic void BitwiseXorWithConstantUInt64(ulong a)\n\t\t{\n\t\t\tExpectUInt64(a ^ 7);\n\t\t\tExpectUInt64(a ^ 0x7FFFFFFF);\n\t\t\tExpectUInt64(a ^ 0xFFFFFFFFu);\n\t\t\tExpectUInt64(a ^ 0x7FFFFFFFFFFFFFFFL);\n\t\t\tExpectUInt64(a ^ 0xFFFFFFFFFFFFFFFFuL);\n\t\t}\n\n\t\tpublic void BitwiseXorWithConstantInt64(long a)\n\t\t{\n\t\t\tExpectInt64(a ^ 7);\n\t\t\tExpectInt64(a ^ 0x7FFFFFFF);\n\t\t\tExpectInt64(a ^ 0xFFFFFFFFu);\n\t\t\tExpectInt64(a ^ 0x7FFFFFFFFFFFFFFFL);\n\t\t}\n\n\t\tpublic void BitwiseXorWithConstantUInt32(uint a)\n\t\t{\n\t\t\tExpectUInt32(a ^ 7);\n\t\t\tExpectUInt32(a ^ 0x7FFFFFFF);\n\t\t\tExpectUInt32(a ^ 0xFFFFFFFFu);\n\t\t}\n\n\t\tpublic void BitwiseXorWithConstantInt32(int a)\n\t\t{\n\t\t\tExpectInt32(a ^ 7);\n\t\t\tExpectInt32(a ^ 0x7FFFFFFF);\n\t\t}\n\n\t\tpublic void BitwiseXorWithConstantUInt16(ushort a)\n\t\t{\n\t\t\tExpectUInt16((ushort)(a ^ 7));\n\t\t\tExpectUInt16((ushort)(a ^ 0x7FFF));\n\t\t\tExpectUInt16((ushort)(a ^ 0xFFFF));\n\t\t}\n\n\t\tpublic void BitwiseXorWithConstantInt16(short a)\n\t\t{\n\t\t\tExpectInt16((short)(a ^ 7));\n\t\t\tExpectInt16((short)(a ^ 0x7FFF));\n\t\t}\n\n\t\tpublic void BitwiseXorWithConstantUInt8(byte a)\n\t\t{\n\t\t\tExpectUInt8((byte)(a ^ 7));\n\t\t\tExpectUInt8((byte)(a ^ 0x7F));\n\t\t\tExpectUInt8((byte)(a ^ 0xFF));\n\t\t}\n\n\t\tpublic void BitwiseXorWithConstantInt8(sbyte a)\n\t\t{\n\t\t\tExpectInt8((sbyte)(a ^ 7));\n\t\t\tExpectInt8((sbyte)(a ^ 0x7F));\n\t\t}\n\n\t\tpublic int Issue2166a(int x)\n\t\t{\n\t\t\tif ((x & 0x10) != 0)\n\t\t\t{\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\n\t\tpublic byte Issue2166b(int x)\n\t\t{\n\t\t\treturn (byte)(x & 0x10);\n\t\t}\n\n\t\tpublic decimal Issue3367()\n\t\t{\n#if CS70\n\t\t\treturn new decimal(0, 0, 0, isNegative: false, 29);\n#else\n\t\t\treturn new decimal(0, 0, 0, false, 29);\n#endif\n\t\t}\n\n\t\tprivate void ExpectUInt64(ulong _)\n\t\t{\n\n\t\t}\n\n\t\tprivate void ExpectInt64(long _)\n\t\t{\n\n\t\t}\n\n\t\tprivate void ExpectUInt32(uint _)\n\t\t{\n\n\t\t}\n\n\t\tprivate void ExpectInt32(int _)\n\t\t{\n\n\t\t}\n\n\t\tprivate void ExpectUInt16(ushort _)\n\t\t{\n\n\t\t}\n\n\t\tprivate void ExpectInt16(short _)\n\t\t{\n\n\t\t}\n\n\t\tprivate void ExpectUInt8(byte _)\n\t\t{\n\t\t}\n\n\t\tprivate void ExpectInt8(sbyte _)\n\t\t{\n\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstructorInitializers.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#pragma warning disable CS9113\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class ConstructorInitializers\n\t{\n\t\tpublic class JArray\n\t\t{\n\t\t\tprivate readonly List<object> objects = new List<object>();\n\t\t\tprivate readonly List<string> strings = new List<string>();\n\n\t\t\tpublic JArray()\n\t\t\t{\n\t\t\t}\n\n\t\t\tpublic JArray(params object[] items)\n\t\t\t{\n\t\t\t\tforeach (object item in items)\n\t\t\t\t{\n\t\t\t\t\tobjects.Add(item);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic JArray(object content)\n\t\t\t{\n\t\t\t\tobjects.Add(content);\n\t\t\t}\n\n\t\t\tpublic JArray(string content)\n\t\t\t{\n\t\t\t\tstrings.Add(content);\n\t\t\t}\n\t\t}\n\n\t\tpublic struct Issue1743\n\t\t{\n\t\t\tpublic int Leet;\n\n\t\t\tpublic Issue1743(int dummy)\n\t\t\t\t: this(dummy, dummy)\n\t\t\t{\n\t\t\t\tLeet += dummy;\n\t\t\t}\n\n\t\t\tpublic Issue1743(int dummy1, int dummy2)\n\t\t\t{\n\t\t\t\tLeet = dummy1 + dummy2;\n\t\t\t}\n\t\t}\n\n#if CS120\n\t\tpublic struct Issue1743WithPrimaryCtor(int dummy1, int dummy2)\n\t\t{\n\t\t\tpublic int Leet = dummy1 + dummy2;\n\n\t\t\tpublic Issue1743WithPrimaryCtor(int dummy)\n\t\t\t\t: this(dummy, dummy)\n\t\t\t{\n\t\t\t\tLeet += dummy;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// This is info about the class\n\t\t/// </summary>\n\t\tprivate struct StructWithXmlDocCtor\n\t\t{\n\t\t\tpublic int A;\n\n\t\t\tpublic int B;\n\n\t\t\t/// <summary>\n\t\t\t/// This is info about the constructor\n\t\t\t/// </summary>\n\t\t\tpublic StructWithXmlDocCtor(int a, int b)\n\t\t\t{\n\t\t\t\tA = a;\n\t\t\t\tB = b;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// This is info about the class\n\t\t/// </summary>\n\t\tprivate struct StructWithoutXmlDocCtor(int a, int b)\n\t\t{\n\t\t\tpublic int A = a;\n\n\t\t\tpublic int B = b;\n\t\t}\n#endif\n\n\t\tpublic class ClassWithConstant\n\t\t{\n\t\t\t// using decimal constants has the effect that there is a cctor\n\t\t\t// generated containing the explicit initialization of this field.\n\t\t\t// The type is marked beforefieldinit\n\t\t\tprivate const decimal a = 1.0m;\n\t\t}\n\n\t\tpublic class ClassWithConstantAndStaticCtor\n\t\t{\n\t\t\t// The type is not marked beforefieldinit\n\t\t\tprivate const decimal a = 1.0m;\n\n\t\t\tstatic ClassWithConstantAndStaticCtor()\n\t\t\t{\n\n\t\t\t}\n\t\t}\n\n\t\tpublic class MethodCallInCtorInit\n\t\t{\n\t\t\tpublic MethodCallInCtorInit(ConsoleKey key)\n#if MCS5\n\t\t\t\t: this(((int)key/*cast due to .constrained prefix*/).ToString())\n#else\n\t\t\t\t: this(((int)key).ToString())\n#endif\n\t\t\t{\n\t\t\t}\n\n\t\t\tpublic MethodCallInCtorInit(string s)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic struct SimpleStruct\n\t\t{\n\t\t\tpublic int Field1;\n\t\t\tpublic int Field2;\n\t\t}\n\n\t\tpublic class UnsafeFields\n\t\t{\n\t\t\tpublic unsafe static int StaticSizeOf = sizeof(SimpleStruct);\n\t\t\tpublic unsafe int SizeOf = sizeof(SimpleStruct);\n\t\t}\n\n#if CS120\n\t\tpublic class ClassWithPrimaryCtorUsingGlobalParameter(int a)\n\t\t{\n\t\t\tpublic void Print()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(a);\n\t\t\t}\n\t\t}\n\n\t\tpublic class ClassWithPrimaryCtorUsingGlobalParameterAssignedToField(int a)\n\t\t{\n#pragma warning disable CS9124 // Parameter is captured into the state of the enclosing type and its value is also used to initialize a field, property, or event.\n\t\t\tprivate readonly int _a = a;\n#pragma warning restore CS9124 // Parameter is captured into the state of the enclosing type and its value is also used to initialize a field, property, or event.\n\n\t\t\tpublic void Print()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(_a);\n\t\t\t}\n\t\t}\n\n\t\tpublic class ClassWithPrimaryCtorUsingGlobalParameterAssignedToFieldAndUsedInMethod(int a)\n\t\t{\n#pragma warning disable CS9124 // Parameter is captured into the state of the enclosing type and its value is also used to initialize a field, property, or event.\n\t\t\tprivate readonly int _a = a;\n#pragma warning restore CS9124 // Parameter is captured into the state of the enclosing type and its value is also used to initialize a field, property, or event.\n\n\t\t\tpublic void Print()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(a);\n\t\t\t}\n\t\t}\n\n\t\tpublic class ClassWithPrimaryCtorUsingGlobalParameterAssignedToProperty(int a)\n\t\t{\n\t\t\tpublic int A { get; set; } = a;\n\n\t\t\tpublic void Print()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(A);\n\t\t\t}\n\t\t}\n\n\t\tpublic class ClassWithPrimaryCtorUsingGlobalParameterInExpressionAssignedToProperty(int a)\n\t\t{\n\t\t\tpublic int A { get; set; } = (int)Math.Abs(Math.PI * (double)a);\n\n\t\t\tpublic void Print()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(A);\n\t\t\t}\n\t\t}\n\n\t\tpublic class ClassWithPrimaryCtorUsingGlobalParameterAssignedToEvent(EventHandler a)\n\t\t{\n\t\t\tpublic event EventHandler A = a;\n\n\t\t\tpublic void Print()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(this.A);\n\t\t\t}\n\t\t}\n#endif\n\n\t\tpublic class NoRecordButCopyConstructorLike\n\t\t{\n\t\t\tprivate NoRecordButCopyConstructorLike parent;\n\n\t\t\tpublic NoRecordButCopyConstructorLike(NoRecordButCopyConstructorLike parent)\n\t\t\t{\n\t\t\t\tthis.parent = parent;\n\t\t\t}\n\t\t}\n\n#if CS100\n\t\tpublic class PrimaryCtorClassThisChain(Guid id)\n\t\t{\n\t\t\tpublic Guid guid { get; } = id;\n\n\t\t\tpublic PrimaryCtorClassThisChain(Guid id, int value)\n\t\t\t\t: this(Guid.NewGuid())\n\t\t\t{\n\n\t\t\t}\n\t\t\tpublic PrimaryCtorClassThisChain()\n\t\t\t\t: this(Guid.NewGuid(), 222)\n\t\t\t{\n\n\t\t\t}\n\t\t}\n#if EXPECTED_OUTPUT\n\t\tpublic class UnusedPrimaryCtorParameter\n\t\t{\n\t\t\tpublic UnusedPrimaryCtorParameter(int unused)\n\t\t\t{\n\t\t\t}\n\t\t}\n#else\n\t\tpublic class UnusedPrimaryCtorParameter(int unused)\n\t\t{\n\t\t}\n#endif\n#if OPT && EXPECTED_OUTPUT\n\t\tpublic class C8(object obj)\n\t\t{\n\t\t\tpublic int Test()\n\t\t\t{\n\t\t\t\tobject obj2 = obj;\n\t\t\t\tif (obj2 is int)\n\t\t\t\t{\n\t\t\t\t\treturn (int)obj2;\n\t\t\t\t}\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n#else\n\t\tpublic class C8(object obj)\n\t\t{\n\t\t\tpublic int Test()\n\t\t\t{\n\t\t\t\tif (obj is int result)\n\t\t\t\t{\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n#endif\n#endif\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/CovariantReturns.cs",
    "content": "namespace ICSharpCode.Decompiler.Tests.TestCases.CovariantReturns\n{\n\tpublic abstract class AbstractDerived : Base\n\t{\n\t\tpublic abstract override AbstractDerived Instance { get; }\n\n\t\tpublic abstract override AbstractDerived this[int index] { get; }\n\n\t\tpublic abstract override AbstractDerived Build();\n\n\t\tprotected abstract override AbstractDerived SetParent(object parent);\n\t}\n\n\tpublic abstract class Base\n\t{\n\t\tpublic abstract Base Instance { get; }\n\n\t\tpublic abstract Base this[int index] { get; }\n\n\t\tpublic virtual Base Build()\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\n\t\tprotected abstract Base SetParent(object parent);\n\t}\n\n\tpublic class Derived : Base\n\t{\n\t\tpublic override Derived Instance { get; }\n\n\t\tpublic override Derived this[int index] {\n\t\t\tget {\n\t\t\t\tthrow null;\n\t\t\t}\n\t\t}\n\n\t\tpublic override Derived Build()\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\n\t\tprotected override Derived SetParent(object parent)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t}\n\n\tpublic class UseSites\n\t{\n\t\tpublic Base Test(Base x)\n\t\t{\n\t\t\treturn x.Build();\n\t\t}\n\n\t\tpublic Derived Test(Derived x)\n\t\t{\n\t\t\treturn x.Build();\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomAttributeConflicts.cs",
    "content": "using System;\n\nusing CustomAttributeConflicts.NS1;\nusing CustomAttributeConflicts.NS2;\nusing CustomAttributeConflicts.NSWithConflictingTypes;\nusing CustomAttributeConflicts.NSWithConflictingTypes2;\n\nnamespace CustomAttributeConflicts\n{\n\tinternal class AttributeWithSameNameAsNormalType\n\t{\n\t}\n\n\tinternal class TestClass\n\t{\n\t\t[Other]\n\t\tpublic void Test1()\n\t\t{\n\t\t}\n\n\t\t[CustomAttributeConflicts.NS1.Simple]\n\t\tpublic void Test2()\n\t\t{\n\t\t}\n\n\t\t[CustomAttributeConflicts.NS2.Simple]\n\t\tpublic void Test3()\n\t\t{\n\t\t}\n\n\t\t[CustomAttributeConflicts.NS1.AttributeWithSameNameAsNormalType]\n\t\tpublic void Test4()\n\t\t{\n\t\t}\n\n\t\t[@My]\n\t\tpublic void Test5()\n\t\t{\n\t\t}\n\n\t\t[@MyAttribute]\n\t\tpublic void Test6()\n\t\t{\n\t\t}\n\n\t\t[CustomAttributeConflicts.NSWithConflictingTypes2.@MyOther]\n\t\tpublic void Test7()\n\t\t{\n\t\t}\n\n\t\t[CustomAttributeConflicts.NSWithConflictingTypes2.@MyOtherAttribute]\n\t\tpublic void Test8()\n\t\t{\n\t\t}\n\t}\n}\nnamespace CustomAttributeConflicts.NS1\n{\n\tinternal class AttributeWithSameNameAsNormalType : Attribute\n\t{\n\t}\n\tinternal class OtherAttribute : Attribute\n\t{\n\t}\n\tinternal class SimpleAttribute : Attribute\n\t{\n\t}\n}\nnamespace CustomAttributeConflicts.NS2\n{\n\tinternal class SimpleAttribute : Attribute\n\t{\n\t}\n}\nnamespace CustomAttributeConflicts.NSWithConflictingTypes\n{\n\tinternal class My : Attribute\n\t{\n\t}\n\tinternal class MyAttribute : Attribute\n\t{\n\t}\n\tinternal class MyAttributeAttribute : Attribute\n\t{\n\t}\n\tinternal class MyOther : Attribute\n\t{\n\t}\n\tinternal class MyOtherAttribute : Attribute\n\t{\n\t}\n\tinternal class MyOtherAttributeAttribute : Attribute\n\t{\n\t}\n}\nnamespace CustomAttributeConflicts.NSWithConflictingTypes2\n{\n\n\tinternal class MyOther : Attribute\n\t{\n\t}\n\tinternal class MyOtherAttribute : Attribute\n\t{\n\t}\n\tinternal class MyOtherAttributeAttribute : Attribute\n\t{\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomAttributeSamples.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomAttributeSamples\n{\n\t[Obsolete(\"reason\")]\n\tpublic delegate int AppliedToDelegate();\n\n\t[Obsolete(\"reason\")]\n\tpublic interface AppliedToInterface\n\t{\n\t}\n\n\t[Obsolete(\"reason\")]\n\tpublic struct AppliedToStruct\n\t{\n\t\tpublic int Field;\n\t}\n\n\t[Flags]\n\tpublic enum EnumWithFlagsAttribute\n\t{\n\t\tNone = 0\n\t}\n\n\t[AttributeUsage(AttributeTargets.All)]\n\tpublic class MyAttributeAttribute : Attribute\n\t{\n\t}\n\n\t[AttributeUsage(AttributeTargets.All)]\n\tpublic class MyAttributeNamedInitializerFieldEnumAttribute : Attribute\n\t{\n\t\tpublic AttributeTargets Field;\n\t}\n\n\t[AttributeUsage(AttributeTargets.All)]\n\tpublic class MyAttributeNamedInitializerPropertyEnumAttribute : Attribute\n\t{\n\t\tpublic AttributeTargets Prop {\n\t\t\tget {\n\t\t\t\treturn AttributeTargets.All;\n\t\t\t}\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\n\t[AttributeUsage(AttributeTargets.All)]\n\tpublic class MyAttributeOnReturnTypeOfDelegateAttribute : Attribute\n\t{\n\t}\n\n\t[AttributeUsage(AttributeTargets.All)]\n\tpublic class MyAttributeTargetPropertyIndexSetMultiParamAttribute : Attribute\n\t{\n\t\tpublic int Field;\n\t}\n\n\t[AttributeUsage(AttributeTargets.All)]\n\tpublic class MyAttributeWithCustomPropertyAttribute : Attribute\n\t{\n\t\tpublic string Prop {\n\t\t\tget {\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\n\t[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]\n\tpublic class MyAttributeWithNamedArgumentAppliedAttribute : Attribute\n\t{\n\t}\n\n\t[AttributeUsage(AttributeTargets.All)]\n\tpublic class MyAttributeWithNamedInitializerPropertyTypeAttribute : Attribute\n\t{\n\t\tpublic Type Prop {\n\t\t\tget {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\n\t[MyAttributeWithCustomProperty(Prop = \"value\")]\n\tpublic class MyClass\n\t{\n\t}\n\n\tpublic class MyClass<[MyClassAttributeOnTypeParameter] T>\n\t{\n\t}\n\n\t[MyAttributeWithNamedInitializerPropertyType(Prop = typeof(Enum))]\n\tpublic class MyClass02\n\t{\n\t}\n\n\t[MyAttributeNamedInitializerPropertyEnum(Prop = (AttributeTargets.Class | AttributeTargets.Method))]\n\tpublic class MyClass03\n\t{\n\t}\n\n\t[MyAttributeNamedInitializerFieldEnum(Field = (AttributeTargets.Class | AttributeTargets.Method))]\n\tpublic class MyClass04\n\t{\n\t}\n\n\tpublic class MyClass05\n\t{\n\t\t[return: MyAttribute]\n\t\tpublic int MyMethod()\n\t\t{\n\t\t\treturn 5;\n\t\t}\n\t}\n\n\tpublic class MyClass06\n\t{\n\t\tpublic int Prop {\n\t\t\t[return: MyAttribute]\n\t\t\tget {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic class MyClass07\n\t{\n\t\tpublic int Prop {\n\t\t\t[param: MyAttribute]\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic class MyClass08\n\t{\n\t\tpublic int Prop {\n\t\t\tget {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t\t[return: MyAttribute]\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic class MyClass09\n\t{\n\t\tpublic int this[string s] {\n\t\t\t[return: MyAttribute]\n\t\t\tget {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic class MyClass10\n\t{\n\t\tpublic int this[[MyAttribute] string s] {\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic class MyClass11\n\t{\n#if ROSLYN\n\t\tpublic int this[[MyAttribute] string s] => 3;\n#else\n\t\tpublic int this[[MyAttribute] string s] {\n\t\t\tget {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\n\tpublic class MyClass12\n\t{\n\t\tpublic string this[int index] {\n\t\t\tget {\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t\t[return: MyAttribute]\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic class MyClass13\n\t{\n\t\tpublic string this[[MyAttributeTargetPropertyIndexSetMultiParam(Field = 2)] int index1, [MyAttributeTargetPropertyIndexSetMultiParam(Field = 3)] int index2] {\n\t\t\tget {\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t\t[param: MyAttribute]\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\n\t[AttributeUsage(AttributeTargets.All)]\n\tpublic class MyClassAttributeOnTypeParameterAttribute : Attribute\n\t{\n\t}\n\n\t[AttributeUsage(AttributeTargets.Method | AttributeTargets.Interface)]\n\tpublic class MyMethodOrInterfaceAttributeAttribute : Attribute\n\t{\n\t}\n\n\t[AttributeUsage(AttributeTargets.All)]\n\tpublic class MyTypeAttribute : Attribute\n\t{\n\t\tpublic MyTypeAttribute(Type t)\n\t\t{\n\t\t}\n\t}\n\n\t[Obsolete(\"message\")]\n\tpublic class ObsoleteClass\n\t{\n\t}\n\n\t[MyType(typeof(Attribute))]\n\tpublic class SomeClass\n\t{\n\t}\n\n\t[return: MyAttributeOnReturnTypeOfDelegate]\n\tpublic delegate void Test();\n\n\tpublic class TestClass\n\t{\n\t\t[MyAttribute]\n\t\tpublic int Field;\n\n\t\t[Obsolete(\"reason\")]\n#if ROSLYN\n\t\tpublic int Property => 0;\n#else\n\t\tpublic int Property {\n\t\t\tget {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n#endif\n\n\t\tpublic int PropertyAttributeOnGetter {\n\t\t\t[MyAttribute]\n\t\t\tget {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\n\t\tpublic int PropertyAttributeOnSetter {\n\t\t\tget {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t\t[MyAttribute]\n\t\t\tset {\n\t\t\t}\n\t\t}\n\n\t\t[Obsolete(\"reason\")]\n#if ROSLYN\n\t\tpublic int this[int i] => 0;\n#else\n\t\tpublic int this[int i] {\n\t\t\tget {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n#endif\n\t\t[MyAttribute]\n\t\tpublic event EventHandler MyEvent;\n\n\t\t[method: MyAttribute]\n\t\tpublic event EventHandler MyEvent2;\n\n\t\t[MyAttribute]\n\t\tpublic void Method()\n\t\t{\n\t\t}\n\n\t\tpublic void Method([MyAttribute] int val)\n\t\t{\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomAttributes.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace CustomAttributes\n{\n\tpublic static class CustomAttributes\n\t{\n\t\t[Flags]\n\t\tpublic enum EnumWithFlag\n\t\t{\n\t\t\tAll = 0xF,\n\t\t\tNone = 0,\n\t\t\tItem1 = 1,\n\t\t\tItem2 = 2,\n\t\t\tItem3 = 4,\n\t\t\tItem4 = 8\n\t\t}\n\t\t[AttributeUsage(AttributeTargets.All)]\n\t\tpublic class MyAttribute : Attribute\n\t\t{\n\t\t\tpublic MyAttribute(object val)\n\t\t\t{\n\t\t\t}\n\t\t}\n#if CS110\n\t\t[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]\n\t\tpublic class GenericAttribute<T> : Attribute\n\t\t{\n\t\t\tpublic GenericAttribute()\n\t\t\t{\n\t\t\t}\n\t\t\tpublic GenericAttribute(T val)\n\t\t\t{\n\t\t\t}\n\t\t}\n#endif\n\t\t[My(ULongEnum.MaxUInt64)]\n\t\tpublic enum ULongEnum : ulong\n\t\t{\n\t\t\t[My(null)]\n\t\t\tMaxUInt64 = ulong.MaxValue\n\t\t}\n\t\t[AttributeUsage(AttributeTargets.Field)]\n\t\tpublic class TypesAttribute : Attribute\n\t\t{\n\t\t\tpublic TypesAttribute(Type type)\n\t\t\t{\n\t\t\t}\n\t\t}\n\t\tprivate class SomeType<T>\n\t\t{\n\t\t}\n\t\tprivate class SomeType<K, V>\n\t\t{\n\t\t}\n\t\tprivate struct DataType\n\t\t{\n\t\t\tprivate int i;\n\t\t}\n\t\t[Types(typeof(int))]\n\t\tprivate static int typeattr_int;\n\t\t[Types(null)]\n\t\tprivate static int typeattr_null;\n\t\t[Types(typeof(List<int>))]\n\t\tprivate static int typeattr_list_of_int;\n\t\t[Types(typeof(List<>))]\n\t\tprivate static int typeattr_list_unbound;\n\t\t[Types(typeof(SomeType<DataType>))]\n\t\tprivate static int typeattr_sometype_of_datatype;\n\t\t[Types(typeof(SomeType<DataType, DataType>))]\n\t\tprivate static int typeattr_sometype_of_datatype2;\n\t\t[Types(typeof(SomeType<DataType, int>))]\n\t\tprivate static int typeattr_sometype_of_datatype_and_int;\n\t\t[Types(typeof(SomeType<DataType[], int>))]\n\t\tprivate static int typeattr_sometype_of_datatype_array_and_int;\n\t\t[Types(typeof(SomeType<SomeType<DataType>, int>))]\n\t\tprivate static int typeattr_sometype_of_nested_sometype;\n\t\t[Types(typeof(SomeType<int, DataType>))]\n\t\tprivate static int typeattr_sometype_of_int_and_datatype;\n\t\t[Types(typeof(int[]))]\n\t\tprivate static int typeattr_array_of_int;\n\t\t[Types(typeof(int[,,,][,]))]\n\t\tprivate static int typeattr_multidim_array_of_int;\n\n\t\t[My(EnumWithFlag.Item1 | EnumWithFlag.Item2)]\n\t\tprivate static int field;\n\t\t[My(EnumWithFlag.All)]\n#if ROSLYN\n\t\tpublic static string Property => \"aa\";\n#else\n\t\tpublic static string Property {\n\t\t\tget {\n\t\t\t\treturn \"aa\";\n\t\t\t}\n\t\t}\n#endif\n\t\t[Obsolete(\"some message\")]\n\t\tpublic static void ObsoletedMethod()\n\t\t{\n\t\t}\n\t\t// No Boxing\n\t\t[My(new StringComparison[] {\n\t\t\tStringComparison.Ordinal,\n\t\t\tStringComparison.CurrentCulture\n\t\t})]\n\t\tpublic static void EnumArray()\n\t\t{\n\t\t}\n\t\t// Boxing of each array element\n\t\t[My(new object[] {\n\t\t\tStringComparison.Ordinal,\n\t\t\tStringComparison.CurrentCulture\n\t\t})]\n\t\tpublic static void BoxedEnumArray()\n\t\t{\n\t\t}\n\t\t[My(new object[] {\n\t\t\t1,\n\t\t\t2u,\n\t\t\t3L,\n\t\t\t4uL,\n\t\t\t// Ensure the decompiler doesn't leave these casts out:\n\t\t\t(short)5,\n\t\t\t(ushort)6,\n\t\t\t(byte)7,\n\t\t\t(sbyte)8,\n\t\t\t'a',\n\t\t\t'\\0',\n\t\t\t'\\ufeff',\n\t\t\t'\\uffff',\n\t\t\t1f,\n\t\t\t2.0,\n\t\t\t\"text\",\n\t\t\tnull,\n\t\t\ttypeof(int),\n\t\t\tnew object[] { 1 },\n\t\t\tnew int[] { 1 }\n\t\t})]\n\t\tpublic static void BoxedLiteralsArray()\n\t\t{\n\t\t}\n#if CS110\n\t\t[Generic<int>]\n\t\t[Generic<string>]\n\t\tpublic static void UseGenericAttribute()\n\t\t{\n\t\t}\n\t\t[Generic<int>(42)]\n\t\t[Generic<string>(\"Hi\")]\n\t\t[Generic<object>(\"Hi\")]\n\t\t[Generic<object>((short)42)]\n\t\tpublic static void UseGenericAttributeWithArg()\n\t\t{\n\t\t}\n#endif\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomAttributes2.cs",
    "content": "using System;\nnamespace CustomAttributes2\n{\n\tpublic static class CustomAttributes\n\t{\n\t\t[Flags]\n\t\tpublic enum EnumWithFlag\n\t\t{\n\t\t\tAll = 0xF,\n\t\t\tNone = 0,\n\t\t\tItem1 = 1,\n\t\t\tItem2 = 2,\n\t\t\tItem3 = 4,\n\t\t\tItem4 = 8\n\t\t}\n\t\t[AttributeUsage(AttributeTargets.All)]\n\t\tpublic class MyAttribute : Attribute\n\t\t{\n\t\t\tpublic MyAttribute(EnumWithFlag en)\n\t\t\t{\n\t\t\t}\n\t\t}\n\t\t[My(EnumWithFlag.Item1 | EnumWithFlag.Item2)]\n\t\tprivate static int field;\n\t\t[My(EnumWithFlag.All)]\n#if ROSLYN\n\t\tpublic static string Property => \"aa\";\n#else\n\t\tpublic static string Property {\n\t\t\tget {\n\t\t\t\treturn \"aa\";\n\t\t\t}\n\t\t}\n#endif\n\t\tpublic static string GetterOnlyPropertyWithAttributeOnGetter {\n\t\t\t[My(EnumWithFlag.Item1)]\n\t\t\tget {\n\t\t\t\treturn \"aa\";\n\t\t\t}\n\t\t}\n\t\t[My(EnumWithFlag.All)]\n\t\tpublic static string GetterOnlyPropertyWithAttributeOnGetter2 {\n\t\t\t[My(EnumWithFlag.Item1)]\n\t\t\tget {\n\t\t\t\treturn \"aa\";\n\t\t\t}\n\t\t}\n\t\t[Obsolete(\"some message\")]\n\t\tpublic static void ObsoletedMethod()\n\t\t{\n\t\t\tConsole.WriteLine(\"{0} $$$ {1}\", AttributeTargets.Interface, AttributeTargets.Property | AttributeTargets.Field);\n\t\t\tAttributeTargets attributeTargets = AttributeTargets.Property | AttributeTargets.Field;\n\t\t\tConsole.WriteLine(\"{0} $$$ {1}\", AttributeTargets.Interface, attributeTargets);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomShortCircuitOperators.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.CustomShortCircuitOperators\n{\n\tinternal class BaseClass\n\t{\n\t\tpublic static bool operator true(BaseClass x)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic static bool operator false(BaseClass x)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tinternal class C : BaseClass\n\t{\n\t\tpublic static C operator &(C x, C y)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static C operator |(C x, C y)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static C operator !(C x)\n\t\t{\n\t\t\treturn x;\n\t\t}\n\n\t\tpublic static C GetC(int a)\n\t\t{\n\t\t\treturn new C();\n\t\t}\n\n\t\tpublic static C LogicAnd()\n\t\t{\n\t\t\treturn GetC(1) && GetC(2);\n\t\t}\n\n\t\tpublic static C LogicOr()\n\t\t{\n\t\t\treturn GetC(1) || GetC(2);\n\t\t}\n\n\t\tpublic static C Complex()\n\t\t{\n\t\t\treturn (GetC(1) || GetC(2)) && GetC(3) && !(GetC(4) || GetC(5));\n\t\t}\n\n\t\tprivate static void Main()\n\t\t{\n\t\t\tC c = new C();\n\t\t\tC c2 = new C();\n\t\t\tC c3 = c && c2;\n\t\t\tC c4 = c || c2;\n\t\t\tConsole.WriteLine(c3.ToString());\n\t\t\tConsole.WriteLine(c4.ToString());\n\t\t}\n\n\t\tprivate static void Test2()\n\t\t{\n\t\t\tif (GetC(1) && GetC(2))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(GetC(3));\n\t\t\t}\n\t\t\tif (GetC(1) || GetC(2))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(GetC(3));\n\t\t\t}\n\t\t\tif (!(GetC(1) && GetC(2)))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(GetC(3));\n\t\t\t}\n\t\t}\n\n\t\tprivate static void Test3()\n\t\t{\n\t\t\tC c = new C();\n\t\t\tif (c)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(c.ToString());\n\t\t\t}\n\t\t\tif (!c)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(c.ToString());\n\t\t\t}\n\t\t}\n\n\t\tpublic void WithDynamic(dynamic d)\n\t\t{\n\t\t\tConsole.WriteLine(GetC(1) && d.P);\n\t\t\tConsole.WriteLine(GetC(2) || d.P);\n\t\t\tif (GetC(3) && d.P)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(GetC(4));\n\t\t\t}\n\t\t\tif (GetC(5) || d.P)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(GetC(6));\n\t\t\t}\n\t\t}\n\t}\n\n\tinternal struct S\n\t{\n\t\tprivate readonly bool val;\n\n\t\tpublic bool Val {\n\t\t\tget {\n\t\t\t\treturn val;\n\t\t\t}\n\t\t\tset {\n\t\t\t}\n\t\t}\n\n\t\tpublic S(bool val)\n\t\t{\n\t\t\tthis.val = val;\n\t\t}\n\n\t\tpublic static bool operator true(S x)\n\t\t{\n\t\t\treturn x.val;\n\t\t}\n\n\t\tpublic static bool operator false(S x)\n\t\t{\n\t\t\treturn x.val;\n\t\t}\n\n\t\tpublic static S operator &(S x, S y)\n\t\t{\n\t\t\treturn new S(x.val & y.val);\n\t\t}\n\n\t\tpublic static S operator |(S x, S y)\n\t\t{\n\t\t\treturn new S(x.val | y.val);\n\t\t}\n\n\t\tpublic static S operator !(S x)\n\t\t{\n\t\t\treturn new S(!x.val);\n\t\t}\n\n\t\tpublic static S Get(int i)\n\t\t{\n\t\t\treturn new S(i > 0);\n\t\t}\n\n\t\tpublic static S LogicAnd()\n\t\t{\n\t\t\treturn Get(1) && Get(2);\n\t\t}\n\n\t\tpublic static S LogicOr()\n\t\t{\n\t\t\treturn Get(1) || Get(2);\n\t\t}\n\n\t\tpublic void InConditionDetection()\n\t\t{\n\t\t\tConsole.WriteLine(\"a\");\n\t\t\tif (Get(1) && Get(2))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"b\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"c\");\n\t\t\t}\n\t\t\tif (Get(1) || Get(2))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"d\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"e\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void WithDynamic(dynamic d)\n\t\t{\n\t\t\tConsole.WriteLine(Get(1) && d.P);\n\t\t\tConsole.WriteLine(Get(2) || d.P);\n\t\t\tif (Get(3) && d.P)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(Get(4));\n\t\t\t}\n\t\t\tif (Get(5) || d.P)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(Get(6));\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/CustomTaskType.cs",
    "content": "#pragma warning disable 1998\n\nusing System;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class ValueTaskType\n\t{\n\t\tprivate int memberField;\n\n\t\tpublic async ValueTask SimpleVoidTaskMethod()\n\t\t{\n\t\t\tConsole.WriteLine(\"Before\");\n\t\t\tawait Task.Delay(TimeSpan.FromSeconds(1.0));\n\t\t\tConsole.WriteLine(\"After\");\n\t\t}\n\n\t\tpublic async ValueTask TaskMethodWithoutAwait()\n\t\t{\n\t\t\tConsole.WriteLine(\"No Await\");\n\t\t}\n\n\t\tpublic async ValueTask CapturingThis()\n\t\t{\n\t\t\tawait Task.Delay(memberField);\n\t\t}\n\n\t\tpublic async ValueTask CapturingThisWithoutAwait()\n\t\t{\n\t\t\tConsole.WriteLine(memberField);\n\t\t}\n\n\t\tpublic async ValueTask<bool> SimpleBoolTaskMethod()\n\t\t{\n\t\t\tConsole.WriteLine(\"Before\");\n\t\t\tawait Task.Delay(TimeSpan.FromSeconds(1.0));\n\t\t\tConsole.WriteLine(\"After\");\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic async void TwoAwaitsWithDifferentAwaiterTypes()\n\t\t{\n\t\t\tConsole.WriteLine(\"Before\");\n\t\t\tif (await SimpleBoolTaskMethod())\n\t\t\t{\n\t\t\t\tawait Task.Delay(TimeSpan.FromSeconds(1.0));\n\t\t\t}\n\t\t\tConsole.WriteLine(\"After\");\n\t\t}\n\n\t\tpublic async void AwaitInLoopCondition()\n\t\t{\n\t\t\twhile (await SimpleBoolTaskMethod())\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Body\");\n\t\t\t}\n\t\t}\n\n\t\tpublic async ValueTask AwaitInCatch(bool b, ValueTask<int> task1, ValueTask<int> task2)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Start try\");\n\t\t\t\tawait task1;\n\t\t\t\tConsole.WriteLine(\"End try\");\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\tif (!b)\n\t\t\t\t{\n\t\t\t\t\tawait task2;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"No await\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic async ValueTask AwaitInFinally(bool b, ValueTask<int> task1, ValueTask<int> task2)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Start try\");\n\t\t\t\tawait task1;\n\t\t\t\tConsole.WriteLine(\"End try\");\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tif (!b)\n\t\t\t\t{\n\t\t\t\t\tawait task2;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"No await\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static async ValueTask<int> GetIntegerSumAsync(IEnumerable<int> items)\n\t\t{\n\t\t\tawait Task.Delay(100);\n\t\t\tint num = 0;\n\t\t\tforeach (int item in items)\n\t\t\t{\n\t\t\t\tnum += item;\n\t\t\t}\n\t\t\treturn num;\n\t\t}\n\n\t\tpublic static Func<ValueTask<int>> AsyncLambda()\n\t\t{\n\t\t\treturn async () => await GetIntegerSumAsync(new int[3] { 1, 2, 3 });\n\t\t}\n\n\t\tpublic static Func<ValueTask<int>> AsyncDelegate()\n\t\t{\n\t\t\treturn async delegate {\n\t\t\t\tawait Task.Delay(10);\n\t\t\t\treturn 2;\n\t\t\t};\n\t\t}\n\n\t\tpublic static async ValueTask<int> AsyncLocalFunctions()\n\t\t{\n\t\t\treturn await Nested(1) + await Nested(2);\n\n#if CS80\n\t\t\tstatic async ValueTask<int> Nested(int i)\n#else\n\t\t\tasync ValueTask<int> Nested(int i)\n#endif\n\t\t\t{\n\t\t\t\tawait Task.Delay(i);\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t}\n}\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue1788\n{\n#pragma warning disable CS8981\n\t[AsyncMethodBuilder(typeof(builder))]\n\tinternal class async\n\t{\n\t\tpublic awaiter GetAwaiter()\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t}\n\tinternal class await\n\t{\n\t\tpublic awaiter GetAwaiter()\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t}\n\n\tinternal class awaiter : INotifyCompletion\n\t{\n\t\tpublic bool IsCompleted => true;\n\t\tpublic void GetResult()\n\t\t{\n\t\t}\n\t\tpublic void OnCompleted(Action continuation)\n\t\t{\n\t\t}\n\t}\n\n\tinternal class builder\n\t{\n\t\tpublic async Task {\n\t\t\tget {\n\t\t\t\tthrow null;\n\t\t\t}\n\t\t}\n\t\tpublic static builder Create()\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic void SetResult()\n\t\t{\n\t\t}\n\t\tpublic void SetException(Exception e)\n\t\t{\n\t\t}\n\t\tpublic void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic void SetStateMachine(IAsyncStateMachine stateMachine)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t}\n\n\tpublic class C\n\t{\n\t\tinternal async async @await(@await async)\n\t\t{\n\t\t\tawait async;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/DeconstructionTests.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Runtime.InteropServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic static class DeconstructionExt\n\t{\n\t\tpublic static void Deconstruct<K, V>(this KeyValuePair<K, V> pair, out K key, out V value)\n\t\t{\n\t\t\tkey = pair.Key;\n\t\t\tvalue = pair.Value;\n\t\t}\n\t}\n\n\tinternal class DeconstructionTests\n\t{\n\t\t[StructLayout(LayoutKind.Sequential, Size = 1)]\n\t\tpublic struct MyInt\n\t\t{\n\t\t\tpublic static implicit operator int(MyInt x)\n\t\t\t{\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tpublic static implicit operator MyInt(int x)\n\t\t\t{\n\t\t\t\treturn default(MyInt);\n\t\t\t}\n\t\t}\n\n\t\tprivate class DeconstructionSource<T, T2>\n\t\t{\n\t\t\tpublic int Dummy { get; set; }\n\n\t\t\tpublic void Deconstruct(out T a, out T2 b)\n\t\t\t{\n\t\t\t\ta = default(T);\n\t\t\t\tb = default(T2);\n\t\t\t}\n\t\t}\n\n\t\tprivate class DeconstructionSource<T, T2, T3>\n\t\t{\n\t\t\tpublic int Dummy { get; set; }\n\n\t\t\tpublic void Deconstruct(out T a, out T2 b, out T3 c)\n\t\t\t{\n\t\t\t\ta = default(T);\n\t\t\t\tb = default(T2);\n\t\t\t\tc = default(T3);\n\t\t\t}\n\t\t}\n\n\t\tprivate class AssignmentTargets\n\t\t{\n\t\t\tpublic int IntField;\n\t\t\tpublic long LongField;\n\t\t\tpublic float FloatField;\n\t\t\tpublic double DoubleField;\n\t\t\tpublic decimal DecimalField;\n\n\t\t\tpublic MyInt MyField;\n\t\t\tpublic MyInt? NMyField;\n\n\t\t\tpublic string StringField;\n\t\t\tpublic object ObjectField;\n\t\t\tpublic dynamic DynamicField;\n\n\t\t\tpublic int? NullableIntField;\n\n\t\t\tpublic MyInt MyIntField;\n\n\t\t\tpublic MyInt? NullableMyIntField;\n\n\t\t\tpublic int Int { get; set; }\n\n\t\t\tpublic long Long { get; set; }\n\n\t\t\tpublic float Float { get; set; }\n\n\t\t\tpublic double Double { get; set; }\n\n\t\t\tpublic decimal Decimal { get; set; }\n\n\t\t\tpublic string String { get; set; }\n\n\t\t\tpublic object Object { get; set; }\n\n\t\t\tpublic dynamic Dynamic { get; set; }\n\n\t\t\tpublic int? NInt { get; set; }\n\n\t\t\tpublic MyInt My { get; set; }\n\n\t\t\tpublic MyInt? NMy { get; set; }\n\n\t\t\tpublic static MyInt StaticMy { get; set; }\n\n\t\t\tpublic static MyInt? StaticNMy { get; set; }\n\t\t}\n\n\t\tprivate DeconstructionSource<T, T2> GetSource<T, T2>()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tprivate DeconstructionSource<T, T2, T3> GetSource<T, T2, T3>()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tprivate ref T GetRef<T>()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tprivate (T, T2) GetTuple<T, T2>()\n\t\t{\n\t\t\treturn default((T, T2));\n\t\t}\n\n\t\tprivate (T, T2, T3) GetTuple<T, T2, T3>()\n\t\t{\n\t\t\treturn default((T, T2, T3));\n\t\t}\n\n\t\tprivate AssignmentTargets Get(int i)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic void LocalVariable_NoConversion_Custom()\n\t\t{\n\t\t\tvar (myInt3, myInt4) = GetSource<MyInt?, MyInt>();\n\t\t\tConsole.WriteLine(myInt3);\n\t\t\tConsole.WriteLine(myInt4);\n\t\t}\n\n\t\tpublic void LocalVariable_NoConversion_Tuple()\n\t\t{\n\t\t\tvar (myInt, myInt2) = GetTuple<MyInt?, MyInt>();\n\t\t\tConsole.WriteLine(myInt);\n\t\t\tConsole.WriteLine(myInt2);\n\t\t}\n\n\t\tpublic void LocalVariable_NoConversion_Custom_DiscardFirst()\n\t\t{\n\t\t\tvar (_, myInt3, value) = GetSource<MyInt?, MyInt, int>();\n\t\t\tConsole.WriteLine(myInt3);\n\t\t\tConsole.WriteLine(value);\n\t\t}\n\n\t\t// currently we detect deconstruction, iff the first element is not discarded\n\t\t//public void LocalVariable_NoConversion_Tuple_DiscardFirst()\n\t\t//{\n\t\t//\tvar (_, x, value) = GetTuple<MyInt?, MyInt, int>();\n\t\t//\tConsole.WriteLine(x);\n\t\t//\tConsole.WriteLine(value);\n\t\t//}\n\n\t\tpublic void LocalVariable_NoConversion_Custom_DiscardLast()\n\t\t{\n\t\t\tvar (myInt3, myInt4, _) = GetSource<MyInt?, MyInt, int>();\n\t\t\tConsole.WriteLine(myInt3);\n\t\t\tConsole.WriteLine(myInt4);\n\t\t}\n\n\t\tpublic void LocalVariable_NoConversion_Tuple_DiscardLast()\n\t\t{\n\t\t\tvar (myInt, myInt2, _) = GetTuple<MyInt?, MyInt, int>();\n\t\t\tConsole.WriteLine(myInt);\n\t\t\tConsole.WriteLine(myInt2);\n\t\t}\n\n\t\tpublic void LocalVariable_NoConversion_Custom_DiscardSecond()\n\t\t{\n\t\t\tvar (myInt3, _, value) = GetSource<MyInt?, MyInt, int>();\n\t\t\tConsole.WriteLine(myInt3);\n\t\t\tConsole.WriteLine(value);\n\t\t}\n\n\t\tpublic void LocalVariable_NoConversion_Tuple_DiscardSecond()\n\t\t{\n\t\t\tvar (myInt, _, value) = GetTuple<MyInt?, MyInt, int>();\n\t\t\tConsole.WriteLine(myInt);\n\t\t\tConsole.WriteLine(value);\n\t\t}\n\n\t\tpublic void LocalVariable_NoConversion_Custom_ReferenceTypes()\n\t\t{\n\t\t\tvar (value, value2) = GetSource<string, string>();\n\t\t\tConsole.WriteLine(value);\n\t\t\tConsole.WriteLine(value2);\n\t\t}\n\n\t\tpublic void LocalVariable_NoConversion_Tuple_ReferenceTypes()\n\t\t{\n\t\t\tvar (value, value2) = GetTuple<string, string>();\n\t\t\tConsole.WriteLine(value);\n\t\t\tConsole.WriteLine(value2);\n\t\t}\n\n\t\tpublic void Issue2378(Tuple<object, object> tuple)\n\t\t{\n\t\t\tvar (value, value2) = tuple;\n\t\t\tConsole.WriteLine(value2);\n\t\t\tConsole.WriteLine(value);\n\t\t}\n\n\t\tpublic void Issue2378_IntToLongConversion(Tuple<int, int> tuple)\n\t\t{\n\t\t\tint value;\n\t\t\tlong value2;\n\t\t\t(value, value2) = tuple;\n\t\t\tConsole.WriteLine(value2);\n\t\t\tConsole.WriteLine(value);\n\t\t}\n\n\t\tpublic void LocalVariable_IntToLongConversion_Custom()\n\t\t{\n\t\t\tint value;\n\t\t\tlong value2;\n\t\t\t(value, value2) = GetSource<int, int>();\n\t\t\tConsole.WriteLine(value);\n\t\t\tConsole.WriteLine(value2);\n\t\t}\n\n\t\tpublic void LocalVariable_IntToLongConversion_Tuple()\n\t\t{\n\t\t\tint value;\n\t\t\tlong value2;\n\t\t\t(value, value2) = GetTuple<int, int>();\n\t\t\tConsole.WriteLine(value);\n\t\t\tConsole.WriteLine(value2);\n\t\t}\n\n\t\tpublic void LocalVariable_FloatToDoubleConversion_Custom()\n\t\t{\n\t\t\tint value;\n\t\t\tdouble value2;\n\t\t\t(value, value2) = GetSource<int, float>();\n\t\t\tConsole.WriteLine(value);\n\t\t\tConsole.WriteLine(value2);\n\t\t}\n\n\t\tpublic void LocalVariable_FloatToDoubleConversion_Tuple()\n\t\t{\n\t\t\tint value;\n\t\t\tdouble value2;\n\t\t\t(value, value2) = GetTuple<int, float>();\n\t\t\tConsole.WriteLine(value);\n\t\t\tConsole.WriteLine(value2);\n\t\t}\n\n\t\t// dynamic conversion is currently not supported\n\t\t//public void LocalVariable_ImplicitReferenceConversion_Custom()\n\t\t//{\n\t\t//\tobject value;\n\t\t//\tdynamic value2;\n\t\t//\t(value, value2) = GetSource<string, string>();\n\t\t//\tConsole.WriteLine(value);\n\t\t//\tvalue2.UseMe();\n\t\t//}\n\n\t\t//public void LocalVariable_ImplicitReferenceConversion_Tuple()\n\t\t//{\n\t\t//\tobject value;\n\t\t//\tdynamic value2;\n\t\t//\t(value, value2) = GetTuple<string, string>();\n\t\t//\tConsole.WriteLine(value);\n\t\t//\tvalue2.UseMe();\n\t\t//}\n\n\t\tpublic void LocalVariable_NoConversion_ComplexValue_Custom()\n\t\t{\n\t\t\tvar (myInt3, myInt4) = new DeconstructionSource<MyInt?, MyInt> {\n\t\t\t\tDummy = 3\n\t\t\t};\n\t\t\tConsole.WriteLine(myInt3);\n\t\t\tConsole.WriteLine(myInt4);\n\t\t}\n\n\t\tpublic void Property_NoConversion_Custom()\n\t\t{\n\t\t\t(Get(0).NMy, Get(1).My) = GetSource<MyInt?, MyInt>();\n\t\t}\n\n\t\tpublic void Property_IntToLongConversion_Custom()\n\t\t{\n\t\t\t(Get(0).Int, Get(1).Long) = GetSource<int, int>();\n\t\t}\n\n\t\tpublic void Property_FloatToDoubleConversion_Custom()\n\t\t{\n\t\t\t(Get(0).Int, Get(1).Double) = GetSource<int, float>();\n\t\t}\n\n\t\t// dynamic conversion is not supported\n\t\t//public void Property_ImplicitReferenceConversion_Custom()\n\t\t//{\n\t\t//\t(Get(0).Object, Get(1).Dynamic) = GetSource<string, string>();\n\t\t//}\n\n\t\tpublic void Property_NoConversion_Custom_DiscardFirst()\n\t\t{\n\t\t\t(_, Get(1).My) = GetSource<MyInt?, MyInt>();\n\t\t}\n\n\t\tpublic void Property_NoConversion_Custom_DiscardLast()\n\t\t{\n\t\t\t(Get(0).NMy, _) = GetSource<MyInt?, MyInt>();\n\t\t}\n\n\t\tpublic void Property_NoConversion_Tuple()\n\t\t{\n\t\t\t(Get(0).NMy, Get(1).My) = GetTuple<MyInt?, MyInt>();\n\t\t}\n\n\t\tpublic void Property_NoConversion_Tuple_DiscardLast()\n\t\t{\n\t\t\t(Get(0).NMy, Get(1).My, _) = GetTuple<MyInt?, MyInt, int>();\n\t\t}\n\n\t\t// currently we detect deconstruction, iff the first element is not discarded\n\t\t//public void Property_NoConversion_Tuple_DiscardFirst()\n\t\t//{\n\t\t//\t(_, Get(1).My, Get(2).Int) = GetTuple<MyInt?, MyInt, int>();\n\t\t//}\n\n\t\tpublic void Property_NoConversion_Custom_DiscardSecond()\n\t\t{\n\t\t\t(Get(0).NMy, _, Get(2).Int) = GetSource<MyInt?, MyInt, int>();\n\t\t}\n\n\t\tpublic void Property_NoConversion_Tuple_DiscardSecond()\n\t\t{\n\t\t\t(Get(0).NMy, _, Get(2).Int) = GetTuple<MyInt?, MyInt, int>();\n\t\t}\n\n\t\tpublic void Property_NoConversion_Custom_ReferenceTypes()\n\t\t{\n\t\t\t(Get(0).String, Get(1).String) = GetSource<string, string>();\n\t\t}\n\n\t\tpublic void Property_NoConversion_Tuple_ReferenceTypes()\n\t\t{\n\t\t\t(Get(0).String, Get(1).String) = GetTuple<string, string>();\n\t\t}\n\n\t\tpublic void Property_IntToLongConversion_Tuple()\n\t\t{\n\t\t\t(Get(0).Int, Get(1).Long) = GetTuple<int, int>();\n\t\t}\n\n\t\tpublic void Property_FloatToDoubleConversion_Tuple()\n\t\t{\n\t\t\t(Get(0).Int, Get(1).Double) = GetTuple<int, float>();\n\t\t}\n\n\t\tpublic void RefLocal_NoConversion_Custom(out double a)\n\t\t{\n\t\t\t(a, GetRef<float>()) = GetSource<double, float>();\n\t\t}\n\n\t\tpublic void RefLocal_NoConversion_Tuple(out double a)\n\t\t{\n\t\t\t(a, GetRef<float>()) = GetTuple<double, float>();\n\t\t}\n\n\t\tpublic void RefLocal_FloatToDoubleConversion_Custom(out double a)\n\t\t{\n\t\t\t(a, GetRef<double>()) = GetSource<double, float>();\n\t\t}\n\n\t\tpublic void RefLocal_FloatToDoubleConversion_Custom2(out double a)\n\t\t{\n\t\t\t(a, GetRef<double>()) = GetSource<float, float>();\n\t\t}\n\n\t\tpublic void RefLocal_FloatToDoubleConversion_Tuple(out double a)\n\t\t{\n\t\t\t(a, GetRef<double>()) = GetTuple<double, float>();\n\t\t}\n\n\t\tpublic void RefLocal_NoConversion_Custom(out MyInt? a)\n\t\t{\n\t\t\t(a, GetRef<MyInt>()) = GetSource<MyInt?, MyInt>();\n\t\t}\n\n\t\tpublic void RefLocal_IntToLongConversion_Custom(out long a)\n\t\t{\n\t\t\t(a, GetRef<long>()) = GetSource<int, int>();\n\t\t}\n\n\t\t// dynamic conversion is not supported\n\t\t//public void RefLocal_ImplicitReferenceConversion_Custom(out object a)\n\t\t//{\n\t\t//\t(a, GetRef<dynamic>()) = GetSource<string, string>();\n\t\t//}\n\n\t\tpublic void RefLocal_NoConversion_Custom_DiscardFirst()\n\t\t{\n\t\t\t(_, GetRef<MyInt>()) = GetSource<MyInt?, MyInt>();\n\t\t}\n\n\t\tpublic void RefLocal_NoConversion_Custom_DiscardLast(out MyInt? a)\n\t\t{\n\t\t\t(a, _) = GetSource<MyInt?, MyInt>();\n\t\t}\n\n\t\tpublic void RefLocal_NoConversion_Tuple(out MyInt? a)\n\t\t{\n\t\t\t(a, GetRef<MyInt>()) = GetTuple<MyInt?, MyInt>();\n\t\t}\n\n\t\tpublic void RefLocal_NoConversion_Tuple_DiscardLast(out MyInt? a)\n\t\t{\n\t\t\t(a, GetRef<MyInt>(), _) = GetTuple<MyInt?, MyInt, int>();\n\t\t}\n\n\t\t// currently we detect deconstruction, iff the first element is not discarded\n\t\t//public void RefLocal_NoConversion_Tuple_DiscardFirst(out var a)\n\t\t//{\n\t\t//\t(_, GetRef<var>(), GetRef<var>()) = GetTuple<MyInt?, MyInt, int>();\n\t\t//}\n\n\t\tpublic void RefLocal_NoConversion_Custom_DiscardSecond(out MyInt? a)\n\t\t{\n\t\t\t(a, _, GetRef<int>()) = GetSource<MyInt?, MyInt, int>();\n\t\t}\n\n\t\tpublic void RefLocal_NoConversion_Tuple_DiscardSecond(out MyInt? a)\n\t\t{\n\t\t\t(a, _, GetRef<int>()) = GetTuple<MyInt?, MyInt, int>();\n\t\t}\n\n\t\tpublic void RefLocal_NoConversion_Custom_ReferenceTypes(out string a)\n\t\t{\n\t\t\t(a, GetRef<string>()) = GetSource<string, string>();\n\t\t}\n\n\t\tpublic void RefLocal_NoConversion_Tuple_ReferenceTypes(out string a)\n\t\t{\n\t\t\t(a, GetRef<string>()) = GetTuple<string, string>();\n\t\t}\n\n\t\tpublic void RefLocal_IntToLongConversion_Tuple(out long a)\n\t\t{\n\t\t\t(a, GetRef<long>()) = GetTuple<int, int>();\n\t\t}\n\n\t\t//public void ArrayAssign_FloatToDoubleConversion_Custom(double[] arr)\n\t\t//{\n\t\t//\t(arr[0], arr[1], arr[2]) = GetSource<double, float, double>();\n\t\t//}\n\n\t\tpublic void Field_NoConversion_Custom()\n\t\t{\n\t\t\t(Get(0).IntField, Get(1).IntField) = GetSource<int, int>();\n\t\t}\n\n\t\tpublic void Field_NoConversion_Tuple()\n\t\t{\n\t\t\t(Get(0).IntField, Get(1).IntField) = GetTuple<int, int>();\n\t\t}\n\n\t\tpublic void Field_IntToLongConversion_Custom()\n\t\t{\n\t\t\t(Get(0).IntField, Get(1).LongField) = GetSource<int, int>();\n\t\t}\n\n\t\tpublic void Field_IntToLongConversion_Tuple()\n\t\t{\n\t\t\t(Get(0).IntField, Get(1).LongField) = GetTuple<int, int>();\n\t\t}\n\n\t\tpublic void Field_FloatToDoubleConversion_Custom()\n\t\t{\n\t\t\t(Get(0).DoubleField, Get(1).DoubleField) = GetSource<double, float>();\n\t\t}\n\n\t\tpublic void Field_FloatToDoubleConversion_Tuple()\n\t\t{\n\t\t\t(Get(0).DoubleField, Get(1).DoubleField) = GetTuple<double, float>();\n\t\t}\n\n\t\t// dynamic conversion is not supported\n\t\t//public void Field_ImplicitReferenceConversion_Custom()\n\t\t//{\n\t\t//\t(Get(0).ObjectField, Get(1).DynamicField) = GetSource<string, string>();\n\t\t//}\n\n\t\tpublic void Field_NoConversion_Custom_DiscardFirst()\n\t\t{\n\t\t\t(_, Get(1).MyField) = GetSource<MyInt?, MyInt>();\n\t\t}\n\n\t\tpublic void Field_NoConversion_Custom_DiscardLast()\n\t\t{\n\t\t\t(Get(0).NMyField, _) = GetSource<MyInt?, MyInt>();\n\t\t}\n\n\t\tpublic void Field_NoConversion_Tuple_DiscardLast()\n\t\t{\n\t\t\t(Get(0).NMyField, Get(1).MyField, _) = GetTuple<MyInt?, MyInt, int>();\n\t\t}\n\n\t\t// currently we detect deconstruction, iff the first element is not discarded\n\t\t//public void Field_NoConversion_Tuple_DiscardFirst()\n\t\t//{\n\t\t//\t(_, Get(1).MyField, Get(2).IntField) = GetTuple<MyInt?, MyInt, int>();\n\t\t//}\n\n\t\tpublic void Field_NoConversion_Custom_DiscardSecond()\n\t\t{\n\t\t\t(Get(0).NMyField, _, Get(2).IntField) = GetSource<MyInt?, MyInt, int>();\n\t\t}\n\n\t\tpublic void Field_NoConversion_Tuple_DiscardSecond()\n\t\t{\n\t\t\t(Get(0).NMyField, _, Get(2).IntField) = GetTuple<MyInt?, MyInt, int>();\n\t\t}\n\n\t\tpublic void Field_NoConversion_Custom_ReferenceTypes()\n\t\t{\n\t\t\t(Get(0).StringField, Get(1).StringField) = GetSource<string, string>();\n\t\t}\n\n\t\tpublic void Field_NoConversion_Tuple_ReferenceTypes()\n\t\t{\n\t\t\t(Get(0).StringField, Get(1).StringField) = GetTuple<string, string>();\n\t\t}\n\n\t\tpublic void DeconstructDictionaryForEach(Dictionary<string, int> dictionary)\n\t\t{\n\t\t\tforeach (var (text2, num2) in dictionary)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(text2 + \": \" + num2);\n\t\t\t}\n\t\t}\n\n\t\tpublic void DeconstructTupleListForEach(List<(string, int)> tuples)\n\t\t{\n\t\t\tforeach (var (text, num) in tuples)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(text + \": \" + num);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/DelegateConstruction.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\n#if CS100\nusing System.Threading.Tasks;\n\n#endif\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction\n{\n\tpublic static class DelegateConstruction\n\t{\n\t\tinternal class Dummy\n\t\t{\n\t\t\tpublic int baz;\n\n\t\t\tpublic List<Dummy> more;\n\t\t}\n\n\t\t[CompilerGenerated]\n\t\tinternal class Helper\n\t\t{\n\t\t\t[CompilerGenerated]\n\t\t\tinternal bool HelpMe(Dummy dum)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tprivate class InstanceTests\n\t\t{\n\t\t\tpublic struct SomeData\n\t\t\t{\n\t\t\t\tpublic string Value;\n\t\t\t}\n\n\t\t\tprivate int x;\n\n\t\t\tpublic Action CaptureOfThis()\n\t\t\t{\n\t\t\t\treturn delegate {\n\t\t\t\t\tCaptureOfThis();\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tpublic Action CaptureOfThisAndParameter(int a)\n\t\t\t{\n\t\t\t\treturn delegate {\n\t\t\t\t\tCaptureOfThisAndParameter(a);\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tpublic Action CaptureOfThisAndParameterInForEach(int a)\n\t\t\t{\n\t\t\t\tforeach (int item in Enumerable.Empty<int>())\n\t\t\t\t{\n\t\t\t\t\tif (item > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn delegate {\n\t\t\t\t\t\t\tCaptureOfThisAndParameter(item + a);\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tpublic Action CaptureOfThisAndParameterInForEachWithItemCopy(int a)\n\t\t\t{\n\t\t\t\tforeach (int item in Enumerable.Empty<int>())\n\t\t\t\t{\n\t\t\t\t\tint copyOfItem = item;\n\t\t\t\t\tif (item > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn delegate {\n\t\t\t\t\t\t\tCaptureOfThisAndParameter(item + a + copyOfItem);\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tpublic void LambdaInForLoop()\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < 100000; i++)\n\t\t\t\t{\n\t\t\t\t\tBar(() => Foo());\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic int Foo()\n\t\t\t{\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tpublic void Bar(Func<int> f)\n\t\t\t{\n\t\t\t}\n\n\t\t\tprivate void Bug955()\n\t\t\t{\n\t\t\t\tnew Thread((ThreadStart)delegate {\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tpublic void Bug951(int amount)\n\t\t\t{\n\t\t\t\tDoAction(delegate {\n\t\t\t\t\tif (amount < 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tamount = 0;\n\t\t\t\t\t}\n\t\t\t\t\tDoAction(delegate {\n\t\t\t\t\t\tNoOp(amount);\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tpublic void Bug951b()\n\t\t\t{\n\t\t\t\tint amount = Foo();\n\t\t\t\tDoAction(delegate {\n\t\t\t\t\tif (amount < 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tamount = 0;\n\t\t\t\t\t}\n\t\t\t\t\tDoAction(delegate {\n\t\t\t\t\t\tNoOp(amount);\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tpublic void Bug951c(SomeData data)\n\t\t\t{\n\t\t\t\tDoAction(delegate {\n\t\t\t\t\tDoAction(delegate {\n\t\t\t\t\t\tDoSomething(data.Value);\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tpublic Func<int, int> Issue2143()\n\t\t\t{\n\t\t\t\treturn (int x) => this.x;\n\t\t\t}\n\n\t\t\tpublic Action<object> Bug971_DelegateWithoutParameterList()\n\t\t\t{\n\t\t\t\treturn delegate {\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tprivate void DoAction(Action action)\n\t\t\t{\n\t\t\t}\n\n\t\t\tprivate void NoOp(int a)\n\t\t\t{\n\t\t\t}\n\n\t\t\tprivate void DoSomething(string text)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic interface IM3\n\t\t{\n\t\t\tvoid M();\n\t\t}\n\n\t\tpublic class BaseClass : IM3\n\t\t{\n\t\t\tprotected virtual void M1()\n\t\t\t{\n\t\t\t}\n\t\t\tprotected virtual void M2()\n\t\t\t{\n\t\t\t}\n\t\t\tpublic virtual void M()\n\t\t\t{\n\t\t\t}\n\n\t\t\tpublic static void StaticMethod()\n\t\t\t{\n\n\t\t\t}\n\t\t}\n\n\t\tpublic class SubClass : BaseClass\n\t\t{\n\t\t\tprotected override void M2()\n\t\t\t{\n\t\t\t}\n\t\t\tpublic new void M()\n\t\t\t{\n\t\t\t}\n\n\t\t\tpublic void Test()\n\t\t\t{\n\t\t\t\tNoop(\"M1.base\", base.M1);\n\t\t\t\tNoop(\"M1\", M1);\n\t\t\t\tNoop(\"M2.base\", base.M2);\n\t\t\t\tNoop(\"M2\", M2);\n\t\t\t\tNoop(\"M.base\", base.M);\n\t\t\t\tNoop(\"M.base_virt\", ((BaseClass)this).M);\n\t\t\t\tNoop(\"M.base_interface\", ((IM3)this).M);\n#if CS70\n\t\t\t\tNoop(\"M\", this.M);\n\t\t\t\tNoop(\"M\", M);\n\n#if CS80\n\t\t\t\tstatic void M()\n#else\n\t\t\t\tvoid M()\n#endif\n\t\t\t\t{\n\n\t\t\t\t}\n#else\n\t\t\t\tNoop(\"M\", M);\n#endif\n\t\t\t}\n\n\t\t\tpublic void Test2()\n\t\t\t{\n\t\t\t\tNoop(\"M.new\", new BaseClass().M);\n\t\t\t\tNoop(\"M.new\", new SubClass().M);\n\t\t\t}\n\n\t\t\tprivate void Noop(string name, Action _)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic class GenericTest<TNonCaptured, TCaptured>\n\t\t{\n\t\t\tpublic Func<TCaptured> GetFunc(Func<TNonCaptured, TCaptured> f)\n\t\t\t{\n\t\t\t\tTCaptured captured = f(default(TNonCaptured));\n\t\t\t\treturn delegate {\n\t\t\t\t\tConsole.WriteLine(captured.GetType().FullName);\n\t\t\t\t\treturn captured;\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tpublic Func<TNonCaptured, TNonCapturedMP, TCaptured> GetFunc<TNonCapturedMP>(Func<TCaptured> f)\n\t\t\t{\n\t\t\t\tTCaptured captured = f();\n\t\t\t\treturn delegate (TNonCaptured a, TNonCapturedMP d) {\n\t\t\t\t\tConsole.WriteLine(a.GetHashCode());\n\t\t\t\t\tConsole.WriteLine(captured.GetType().FullName);\n\t\t\t\t\treturn captured;\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tprivate delegate void GenericDelegate<T>();\n\t\tpublic delegate void RefRecursiveDelegate(ref RefRecursiveDelegate d);\n\n\t\tpublic static Func<string, string, bool> test0 = (string a, string b) => string.IsNullOrEmpty(a) || string.IsNullOrEmpty(b);\n\t\tpublic static Func<string, string, bool> test1 = (string a, string b) => string.IsNullOrEmpty(a) || !string.IsNullOrEmpty(b);\n\t\tpublic static Func<string, string, bool> test2 = (string a, string b) => !string.IsNullOrEmpty(a) || string.IsNullOrEmpty(b);\n\t\tpublic static Func<string, string, bool> test3 = (string a, string b) => !string.IsNullOrEmpty(a) || !string.IsNullOrEmpty(b);\n\t\tpublic static Func<string, string, bool> test4 = (string a, string b) => string.IsNullOrEmpty(a) && string.IsNullOrEmpty(b);\n\t\tpublic static Func<string, string, bool> test5 = (string a, string b) => string.IsNullOrEmpty(a) && !string.IsNullOrEmpty(b);\n\t\tpublic static Func<string, string, bool> test6 = (string a, string b) => !string.IsNullOrEmpty(a) && string.IsNullOrEmpty(b);\n\t\tpublic static Func<string, string, bool> test7 = (string a, string b) => !string.IsNullOrEmpty(a) && !string.IsNullOrEmpty(b);\n\n\t\tpublic static void Test(this string a)\n\t\t{\n\t\t}\n\n\t\tpublic static Predicate<T> And<T>(this Predicate<T> filter1, Predicate<T> filter2)\n\t\t{\n\t\t\tif (filter1 == null)\n\t\t\t{\n\t\t\t\treturn filter2;\n\t\t\t}\n\t\t\tif (filter2 == null)\n\t\t\t{\n\t\t\t\treturn filter1;\n\t\t\t}\n\t\t\treturn (T m) => filter1(m) && filter2(m);\n\t\t}\n\n\t\tpublic static Action<string> ExtensionMethodUnbound()\n\t\t{\n\t\t\treturn Test;\n\t\t}\n\n\t\tpublic static Action ExtensionMethodBound()\n\t\t{\n\t\t\treturn \"abc\".Test;\n\t\t}\n\n\t\tpublic static Action ExtensionMethodBoundOnNull()\n\t\t{\n\t\t\treturn ((string)null).Test;\n\t\t}\n\n\t\tpublic static Predicate<int> NoExtensionMethodOnLambda()\n\t\t{\n\t\t\treturn And((int x) => x >= 0, (int x) => x <= 100);\n\t\t}\n\n\t\tpublic static object StaticMethod()\n\t\t{\n\t\t\treturn new Func<Action>(ExtensionMethodBound);\n\t\t}\n\n\t\tpublic static object InstanceMethod()\n\t\t{\n\t\t\treturn new Func<string>(\"hello\".ToUpper);\n\t\t}\n\n\t\tpublic static object InstanceMethodOnNull()\n\t\t{\n\t\t\treturn new Func<string>(((string)null).ToUpper);\n\t\t}\n\n\t\tpublic static List<Action<int>> AnonymousMethodStoreWithinLoop()\n\t\t{\n\t\t\tList<Action<int>> list = new List<Action<int>>();\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tint counter;\n\t\t\t\tlist.Add(delegate (int x) {\n\t\t\t\t\tcounter = x;\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tpublic static List<Action<int>> AnonymousMethodStoreOutsideLoop()\n\t\t{\n\t\t\tList<Action<int>> list = new List<Action<int>>();\n\t\t\tint counter;\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tlist.Add(delegate (int x) {\n\t\t\t\t\tcounter = x;\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tpublic static Action StaticAnonymousMethodNoClosure()\n\t\t{\n\t\t\treturn delegate {\n\t\t\t\tConsole.WriteLine();\n\t\t\t};\n\t\t}\n\n\t\tpublic static void NameConflict()\n\t\t{\n\t\t\t// i is local in main method,\n\t\t\t// j is captured variable,\n\t\t\t// k is parameter in anonymous method\n\t\t\t// l is local in anonymous method,\n\t\t\t// Ensure that the decompiler doesn't introduce name conflicts\n\t\t\tList<Action<int>> list = new List<Action<int>>();\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tint j;\n\t\t\t\tfor (j = 0; j < 10; j++)\n\t\t\t\t{\n\t\t\t\t\tlist.Add(delegate (int k) {\n\t\t\t\t\t\tfor (int l = 0; l < j; l += k)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tConsole.WriteLine();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static void NameConflict2(int j)\n\t\t{\n\t\t\tList<Action<int>> list = new List<Action<int>>();\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tlist.Add(delegate (int k) {\n\t\t\t\t\tConsole.WriteLine(k);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tpublic static Action<int> NameConflict3(int i)\n\t\t{\n\t\t\treturn delegate (int j) {\n\t\t\t\tfor (int k = 0; k < j; k++)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(k);\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\tpublic static Func<int, Func<int, int>> CurriedAddition(int a)\n\t\t{\n\t\t\treturn (int b) => (int c) => a + b + c;\n\t\t}\n\n\t\tpublic static Func<int, Func<int, Func<int, int>>> CurriedAddition2(int a)\n\t\t{\n\t\t\treturn (int b) => (int c) => (int d) => a + b + c + d;\n\t\t}\n\n\t\tpublic static Func<TCaptured> CapturedTypeParameter1<TNonCaptured, TCaptured>(TNonCaptured a, Func<TNonCaptured, TCaptured> f)\n\t\t{\n\t\t\tTCaptured captured = f(a);\n\t\t\treturn delegate {\n\t\t\t\tConsole.WriteLine(captured.GetType().FullName);\n\t\t\t\treturn captured;\n\t\t\t};\n\t\t}\n\n\t\tpublic static Func<TCaptured> CapturedTypeParameter2<TNonCaptured, TCaptured>(TNonCaptured a, Func<TNonCaptured, List<TCaptured>> f)\n\t\t{\n\t\t\tList<TCaptured> captured = f(a);\n\t\t\treturn delegate {\n\t\t\t\tConsole.WriteLine(captured.GetType().FullName);\n\t\t\t\treturn captured.FirstOrDefault();\n\t\t\t};\n\t\t}\n\n\t\tpublic static Func<int> Issue1773(short data)\n\t\t{\n\t\t\tint integerData = data;\n\t\t\treturn () => integerData;\n\t\t}\n\n#if !MCS\n\t\t// does not compile with mcs...\n\t\tpublic static Func<int> Issue1773b(object data)\n\t\t{\n#if ROSLYN\n\t\t\tdynamic dynamicData = data;\n\t\t\treturn () => dynamicData.DynamicCall();\n#else\n\t\t\t// This is a bug in the old csc: captured dynamic local variables did not have the [DynamicAttribute]\n\t\t\t// on the display-class field.\n\t\t\treturn () => ((dynamic)data).DynamicCall();\n#endif\n\t\t}\n\n\t\tpublic static Func<int> Issue1773c(object data)\n\t\t{\n#if ROSLYN\n\t\t\tdynamic dynamicData = data;\n\t\t\treturn () => dynamicData;\n#else\n\t\t\treturn () => (dynamic)data;\n#endif\n\t\t}\n#endif\n\n#if CS70\n\t\tpublic static Func<string> Issue1773d((int Integer, string String) data)\n\t\t{\n\t\t\t(int Integer, string RenamedString) valueTuple = data;\n\t\t\treturn () => valueTuple.RenamedString;\n\t\t}\n#endif\n\n\t\tpublic static Func<T, T> Identity<T>()\n\t\t{\n\t\t\treturn (T _) => _;\n\t\t}\n\n\t\tprivate static void Use(Action a)\n\t\t{\n\n\t\t}\n\n\t\tprivate static void Use2(Func<Func<int, int>, IEnumerable<int>> a)\n\t\t{\n\n\t\t}\n\t\tprivate static void Use2<T>(GenericDelegate<T> a)\n\t\t{\n\t\t}\n\n\t\tprivate static void Use3<T>(Func<Func<T, T>> a)\n\t\t{\n\t\t}\n\n\t\tpublic static void SimpleDelegateReference()\n\t\t{\n\t\t\tUse(SimpleDelegateReference);\n#if !MCS2\n\t\t\tUse3(Identity<int>);\n#endif\n\t\t}\n\n\t\tpublic static void DelegateReferenceWithStaticTarget()\n\t\t{\n\t\t\tUse(NameConflict);\n\t\t\tUse(BaseClass.StaticMethod);\n\t\t}\n\n\t\tpublic static void ExtensionDelegateReference(IEnumerable<int> ints)\n\t\t{\n\t\t\tUse2(ints.Select<int, int>);\n\t\t}\n\n#if CS70\n\t\tpublic static void LocalFunctionDelegateReference()\n\t\t{\n\t\t\tUse(LocalFunction);\n\t\t\tUse2<int>(LocalFunction2<int>);\n#if CS80\n\t\t\tstatic void LocalFunction()\n#else\n\t\t\tvoid LocalFunction()\n#endif\n\t\t\t{\n\t\t\t}\n#if CS80\n\t\t\tstatic void LocalFunction2<T>()\n#else\n\t\t\tvoid LocalFunction2<T>()\n#endif\n\t\t\t{\n\t\t\t}\n\t\t}\n#endif\n\n#if CS90\n\t\tpublic static Func<int, int, int, int> LambdaParameterDiscard()\n\t\t{\n\t\t\treturn (int _, int _, int _) => 0;\n\t\t}\n#endif\n\n#if CS100\n\t\tpublic static Func<int> LambdaWithAttribute0()\n\t\t{\n\t\t\treturn [My] () => 0;\n\t\t}\n\n\t\tpublic static Func<int, int> LambdaWithAttribute1()\n\t\t{\n\t\t\treturn [My] (int x) => 0;\n\t\t}\n\n\t\tpublic static Func<int, int> LambdaWithAttributeOnParam()\n\t\t{\n\t\t\treturn ([My] int x) => 0;\n\t\t}\n\n\t\tpublic static Func<Task<int>> AsyncLambdaWithAttribute0()\n\t\t{\n\t\t\treturn [My] async () => 0;\n\t\t}\n\t\tpublic static Action StatementLambdaWithAttribute0()\n\t\t{\n\t\t\treturn [My] () => {\n\t\t\t};\n\t\t}\n\n\t\tpublic static Action<int> StatementLambdaWithAttribute1()\n\t\t{\n\t\t\treturn [return: My] (int x) => {\n\t\t\t\tConsole.WriteLine(x);\n\t\t\t};\n\t\t}\n\t\tpublic static Action<int> StatementLambdaWithAttribute2()\n\t\t{\n\t\t\treturn ([My] int x) => {\n\t\t\t\tConsole.WriteLine(x);\n\t\t\t};\n\t\t}\n#endif\n\n\t\tpublic static void CallRecursiveDelegate(ref RefRecursiveDelegate d)\n\t\t{\n\t\t\td(ref d);\n\t\t}\n\t}\n\n\tpublic class Issue1867\n\t{\n\t\tprivate int value;\n\n\t\tpublic Func<bool> TestLambda(Issue1867 x)\n\t\t{\n\t\t\tIssue1867 m1;\n\t\t\tIssue1867 m2;\n\t\t\tif (x.value > value)\n\t\t\t{\n\t\t\t\tm1 = this;\n\t\t\t\tm2 = x;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tm1 = x;\n\t\t\t\tm2 = this;\n\t\t\t}\n\n\t\t\treturn () => m1.value + 1 == 4 && m2.value > 5;\n\t\t}\n\t}\n\n\tinternal class Issue2791\n\t{\n\t\tpublic void M()\n\t\t{\n\t\t\tRun(delegate (object o) {\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tList<int> list = o as List<int>;\n\t\t\t\t\tAction action = delegate {\n\t\t\t\t\t\tlist.Select((int x) => x * 2);\n\t\t\t\t\t};\n\t\t\t\t\tAction action2 = delegate {\n\t\t\t\t\t\tlist.Select((int x) => x * 2);\n\t\t\t\t\t};\n\t\t\t\t\tConsole.WriteLine();\n\t\t\t\t\taction();\n\t\t\t\t\tConsole.WriteLine();\n\t\t\t\t\taction2();\n\t\t\t\t}\n\t\t\t\tcatch (Exception)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"catch\");\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"finally\");\n\t\t\t\t}\n\t\t\t}, null);\n\t\t}\n\n\t\tprivate void Run(ParameterizedThreadStart del, object x)\n\t\t{\n\t\t\tdel(x);\n\t\t}\n\n\t\tpublic void Issue1572(DelegateConstruction.Dummy dum)\n\t\t{\n#if EXPECTED_OUTPUT\n\t\t\tDelegateConstruction.Helper CS_0024_003C_003E8__locals0 = new DelegateConstruction.Helper();\n\t\t\tDelegateConstruction.Dummy dummy = dum.more.Where((DelegateConstruction.Dummy dummy2) => true).Where((DelegateConstruction.Dummy dummy2) => true).FirstOrDefault();\n\t\t\tConsole.WriteLine();\n\t\t\tdummy.baz++;\n#else\n\t\t\tDelegateConstruction.Helper h = new DelegateConstruction.Helper();\n\t\t\tDelegateConstruction.Dummy localDummy = dum.more.Where(h.HelpMe).Where(h.HelpMe).FirstOrDefault();\n\t\t\tConsole.WriteLine();\n\t\t\tlocalDummy.baz++;\n#endif\n\t\t}\n\t}\n\n\t[AttributeUsage(AttributeTargets.All)]\n\tinternal class MyAttribute : Attribute\n\t{\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Discards.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class Discards\n\t{\n\t\tpublic class @_\n\t\t{\n\n\t\t}\n\n\t\tpublic void GetOut(out int value)\n\t\t{\n\t\t\tvalue = 0;\n\t\t}\n\n\t\tpublic void GetOutOverloaded(out int value)\n\t\t{\n\t\t\tvalue = 0;\n\t\t}\n\n\t\tpublic void GetOutOverloaded(out string value)\n\t\t{\n\t\t\tvalue = \"Hello World\";\n\t\t}\n\n\t\tpublic void MakeValue(Func<object, string, int> func)\n\t\t{\n\n\t\t}\n\n\t\tpublic void MakeValue(Func<@_, int> func)\n\t\t{\n\n\t\t}\n\n\t\tpublic void SimpleParameter(@_ _)\n\t\t{\n\t\t}\n\n\t\tpublic void ParameterHiddenByLocal(@_ _)\n\t\t{\n\t\t\tGetOut(out var _);\n\t\t}\n\n\t\tpublic void ExplicitlyTypedDiscard()\n\t\t{\n\t\t\tGetOutOverloaded(out string _);\n\t\t\tGetOutOverloaded(out int _);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/DynamicTests.cs",
    "content": "using System;\n#if CS120\nusing System.Collections.Generic;\n#endif\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class DynamicTests\n\t{\n\n\t\tprivate class Base\n\t\t{\n\t\t\tpublic Base(object baseObj)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tprivate class Derived : Base\n\t\t{\n\t\t\tpublic Derived(dynamic d)\n\t\t\t\t: base((object)d)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tprivate struct MyValueType\n\t\t{\n\t\t\tprivate readonly dynamic _getOnlyProperty;\n\t\t\tpublic dynamic Field;\n#if CS60\n\t\t\tpublic dynamic GetOnlyProperty => _getOnlyProperty;\n#else\n\t\t\tpublic dynamic GetOnlyProperty {\n\t\t\t\tget {\n\t\t\t\t\treturn _getOnlyProperty;\n\t\t\t\t}\n\t\t\t}\n#endif\n\n\t\t\tpublic dynamic Property { get; set; }\n\n\t\t\tpublic void Method(dynamic a)\n\t\t\t{\n\n\t\t\t}\n\t\t}\n\n\t\tpublic interface I\n\t\t{\n\t\t}\n\n\t\tprivate static dynamic field;\n\t\tprivate static volatile dynamic volatileField;\n\t\tprivate static object objectField;\n\t\tpublic dynamic Property { get; set; }\n\n\t\tpublic DynamicTests()\n\t\t{\n\t\t}\n\n\t\tpublic DynamicTests(dynamic test)\n\t\t{\n\t\t}\n\n\t\tpublic DynamicTests(DynamicTests test)\n\t\t{\n\t\t}\n\n\t\tprivate static void CallWithOut(out dynamic d)\n\t\t{\n\t\t\td = null;\n\t\t}\n\n#if CS70\n\t\tprivate static void CallWithIn(in dynamic d)\n\t\t{\n\t\t}\n#endif\n\n#if CS120\n\t\tprivate static void CallWithRefReadonly(ref readonly Dictionary<object, dynamic> d)\n\t\t{\n\t\t}\n#endif\n\n\t\tprivate static void CallWithRef(ref dynamic d)\n\t\t{\n\t\t}\n\n\t\tprivate static void RefCallSiteTests()\n\t\t{\n#if CS70\n\t\t\tCallWithOut(out var d);\n\t\t\tCallWithIn(in d);\n#else\n\t\t\tdynamic d;\n\t\t\tCallWithOut(out d);\n#endif\n\t\t\tCallWithRef(ref d);\n\t\t\td.SomeCall();\n\t\t}\n\n\t\tprivate static void InvokeConstructor()\n\t\t{\n\t\t\tDynamicTests dynamicTests = new DynamicTests();\n\t\t\tdynamic val = new DynamicTests();\n\t\t\tval.Test(new UnauthorizedAccessException());\n\t\t\tdynamic val2 = new DynamicTests(val);\n\t\t\tval2.Get(new DynamicTests((DynamicTests)val));\n\t\t\tval2.Call(new DynamicTests((dynamic)dynamicTests));\n\t\t}\n\n\t\tprivate static dynamic InlineAssign(object a, out dynamic b)\n\t\t{\n\t\t\treturn b = ((dynamic)a).Test;\n\t\t}\n\n\t\tprivate static dynamic SelfReference(dynamic d)\n\t\t{\n\t\t\treturn d[d, d] = d;\n\t\t}\n\n\t\tprivate static dynamic LongArgumentListFunc(dynamic d)\n\t\t{\n\t\t\t// Func`13\n\t\t\treturn d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\n\t\t}\n\n\t\tprivate static void LongArgumentListAction(dynamic d)\n\t\t{\n\t\t\t// Action`13\n\t\t\td(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);\n\t\t}\n\n\t\tprivate static void DynamicThrow()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tthrow (Exception)field;\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.ToString());\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}\n\n\t\tprivate static void MemberAccess(dynamic a)\n\t\t{\n\t\t\ta.Test1();\n\t\t\ta.GenericTest<int, int>();\n\t\t\ta.Test2(1);\n\t\t\ta.Test3(a.InnerTest(1, 2, 3, 4, 5));\n\t\t\ta.Test4(2, null, a.Index[0]);\n\t\t\ta.Test5(a, a.Number, a.String);\n\t\t\ta[0] = 3;\n\t\t\ta.Index[a.Number] = 5;\n\t\t\ta.Index[a.Number] += 5;\n\t\t\ta.Setter = new DynamicTests();\n\t\t\ta.Setter2 = 5;\n\t\t}\n\n\t\tprivate static void StructMemberAccess(MyValueType valueType)\n\t\t{\n\t\t\tvalueType.Field = 0;\n\t\t\tvalueType.Field += 5;\n\t\t\tvalueType.Field[1] = 5;\n\t\t\tvalueType.Field.CallMe();\n\t\t\tDynamicTests.Casts(valueType.GetOnlyProperty);\n\t\t\tvalueType.GetOnlyProperty.CallMe();\n\t\t\tvalueType.Property = 0;\n\t\t\tvalueType.Property += 5;\n\t\t\tvalueType.Property[1] = 5;\n\t\t\tvalueType.Property.CallMe(5.ToDynamic((object)valueType.Property.Call()));\n\t\t\tvalueType.Method(valueType.GetOnlyProperty + valueType.Field);\n\t\t}\n\n\t\tprivate static void RequiredCasts()\n\t\t{\n\t\t\t((dynamic)objectField).A = 5;\n\t\t\t((dynamic)objectField).B += 5;\n\t\t\t((dynamic)objectField).Call();\n\t\t\t((object)field).ToString();\n\t\t\tfield.Call(\"Hello World\");\n\t\t\tfield.Call((object)\"Hello World\");\n\t\t\tfield.Call((dynamic)\"Hello World\");\n\t\t}\n\n\t\tprivate void StaticCallWithDynamicArgument(dynamic d)\n\t\t{\n\t\t\tM3(d + 5);\n\t\t}\n\n\t\tprivate static void StaticCallWithDynamicArgumentInStaticContext(dynamic d)\n\t\t{\n\t\t\tDynamicTests.M3(d + 5);\n\t\t}\n\n\t\tprivate static void DynamicCallWithString()\n\t\t{\n\t\t\tfield.Call(\"Hello World\");\n\t\t}\n\n\t\tprivate static void DynamicCallWithNamedArgs()\n\t\t{\n\t\t\tfield.Call(a: \"Hello World\");\n\t\t}\n\n\t\tprivate static void DynamicCallWithRefOutArg(int a, out int b)\n\t\t{\n\t\t\tfield.Call(ref a, out b);\n\t\t}\n\n\t\tprivate static void DynamicCallWithStringCastToObj()\n\t\t{\n\t\t\tfield.Call((object)\"Hello World\");\n\t\t}\n\n\t\tprivate static void DynamicCallWithStringCastToDynamic()\n\t\t{\n\t\t\tfield.Call((dynamic)\"Hello World\");\n\t\t}\n\n\t\tprivate static void DynamicCallWithStringCastToDynamic2()\n\t\t{\n\t\t\tfield.Call((dynamic)\"Hello World\", 5, null);\n\t\t}\n\n\t\tprivate static void DynamicCallWithStringCastToDynamic3()\n\t\t{\n\t\t\tfield.Call((dynamic)\"Hello World\", 5u, null);\n\t\t}\n\n\t\tprivate static void Invocation(dynamic a, dynamic b)\n\t\t{\n\t\t\ta(null, b.Test());\n\t\t}\n\n\t\tprivate static dynamic Test1(dynamic a)\n\t\t{\n\t\t\tdynamic val = a.IndexedProperty;\n\t\t\treturn val[0];\n\t\t}\n\n\t\tprivate static dynamic Test2(dynamic a)\n\t\t{\n\t\t\treturn a.IndexedProperty[0];\n\t\t}\n\n\t\tprivate static void ArithmeticBinaryOperators(dynamic a, dynamic b)\n\t\t{\n\t\t\tDynamicTests.MemberAccess(a + b);\n\t\t\tDynamicTests.MemberAccess(a + 1);\n\t\t\tDynamicTests.MemberAccess(a + null);\n\t\t\tDynamicTests.MemberAccess(a - b);\n\t\t\tDynamicTests.MemberAccess(a - 1);\n\t\t\tDynamicTests.MemberAccess(a - null);\n\t\t\tDynamicTests.MemberAccess(a * b);\n\t\t\tDynamicTests.MemberAccess(a * 1);\n\t\t\tDynamicTests.MemberAccess(a * null);\n\t\t\tDynamicTests.MemberAccess(a / b);\n\t\t\tDynamicTests.MemberAccess(a / 1);\n\t\t\tDynamicTests.MemberAccess(a / null);\n\t\t\tDynamicTests.MemberAccess(a % b);\n\t\t\tDynamicTests.MemberAccess(a % 1);\n\t\t\tDynamicTests.MemberAccess(a % null);\n\t\t}\n\n\t\tprivate static void CheckedArithmeticBinaryOperators(dynamic a, dynamic b)\n\t\t{\n\t\t\tchecked\n\t\t\t{\n\t\t\t\tDynamicTests.MemberAccess(a + b);\n\t\t\t\tDynamicTests.MemberAccess(a + 1);\n\t\t\t\tDynamicTests.MemberAccess(a + null);\n\t\t\t\tDynamicTests.MemberAccess(a - b);\n\t\t\t\tDynamicTests.MemberAccess(a - 1);\n\t\t\t\tDynamicTests.MemberAccess(a - null);\n\t\t\t\tDynamicTests.MemberAccess(a * b);\n\t\t\t\tDynamicTests.MemberAccess(a * 1);\n\t\t\t\tDynamicTests.MemberAccess(a * null);\n\t\t\t\tDynamicTests.MemberAccess(a / b);\n\t\t\t\tDynamicTests.MemberAccess(a / 1);\n\t\t\t\tDynamicTests.MemberAccess(a / null);\n\t\t\t\tDynamicTests.MemberAccess(a % b);\n\t\t\t\tDynamicTests.MemberAccess(a % 1);\n\t\t\t\tDynamicTests.MemberAccess(a % null);\n\t\t\t}\n\t\t}\n\n\t\tprivate static void UncheckedArithmeticBinaryOperators(dynamic a, dynamic b)\n\t\t{\n\t\t\tchecked\n\t\t\t{\n\t\t\t\tDynamicTests.MemberAccess(a + b);\n\t\t\t\tDynamicTests.MemberAccess(a + 1);\n\t\t\t\tDynamicTests.MemberAccess(a + null);\n\t\t\t\tDynamicTests.MemberAccess(unchecked(a - b));\n\t\t\t\tDynamicTests.MemberAccess(a - 1);\n\t\t\t\tDynamicTests.MemberAccess(a - null);\n\t\t\t\tDynamicTests.MemberAccess(unchecked(a * b));\n\t\t\t\tDynamicTests.MemberAccess(a * 1);\n\t\t\t\tDynamicTests.MemberAccess(a * null);\n\t\t\t\tDynamicTests.MemberAccess(a / b);\n\t\t\t\tDynamicTests.MemberAccess(a / 1);\n\t\t\t\tDynamicTests.MemberAccess(a / null);\n\t\t\t\tDynamicTests.MemberAccess(a % b);\n\t\t\t\tDynamicTests.MemberAccess(a % 1);\n\t\t\t\tDynamicTests.MemberAccess(a % null);\n\t\t\t}\n\t\t}\n\n\t\tprivate static void RelationalOperators(dynamic a, dynamic b)\n\t\t{\n\t\t\tDynamicTests.MemberAccess(a == b);\n\t\t\tDynamicTests.MemberAccess(a == 1);\n\t\t\tDynamicTests.MemberAccess(a == null);\n\t\t\tDynamicTests.MemberAccess(a != b);\n\t\t\tDynamicTests.MemberAccess(a != 1);\n\t\t\tDynamicTests.MemberAccess(a != null);\n\t\t\tDynamicTests.MemberAccess(a < b);\n\t\t\tDynamicTests.MemberAccess(a < 1);\n\t\t\tDynamicTests.MemberAccess(a < null);\n\t\t\tDynamicTests.MemberAccess(a > b);\n\t\t\tDynamicTests.MemberAccess(a > 1);\n\t\t\tDynamicTests.MemberAccess(a > null);\n\t\t\tDynamicTests.MemberAccess(a >= b);\n\t\t\tDynamicTests.MemberAccess(a >= 1);\n\t\t\tDynamicTests.MemberAccess(a >= null);\n\t\t\tDynamicTests.MemberAccess(a <= b);\n\t\t\tDynamicTests.MemberAccess(a <= 1);\n\t\t\tDynamicTests.MemberAccess(a <= null);\n\t\t}\n\n\t\tprivate static void Casts(dynamic a)\n\t\t{\n\t\t\tConsole.WriteLine();\n\t\t\tMemberAccess((int)a);\n\t\t\tMemberAccess(checked((int)a));\n\t\t}\n\n\t\tprivate static void M(object o)\n\t\t{\n\t\t}\n\n\t\tprivate static void M2(dynamic d)\n\t\t{\n\t\t}\n\n\t\tprivate static void M3(int i)\n\t\t{\n\t\t}\n\n\t\tprivate static void NotDynamicDispatch(dynamic d)\n\t\t{\n\t\t\tDynamicTests.M(d);\n\t\t\tM((object)d);\n\t\t\tDynamicTests.M2(d);\n\t\t\tM2((object)d);\n\t\t}\n\n\t\tprivate static void CompoundAssignment(dynamic a, dynamic b)\n\t\t{\n\t\t\ta.Setter2 += 5;\n\t\t\ta.Setter2 -= 1;\n\t\t\ta.Setter2 *= 2;\n\t\t\ta.Setter2 /= 5;\n\t\t\ta.Setter2 += b;\n\t\t\ta.Setter2 -= b;\n\t\t\ta.Setter2 *= b;\n\t\t\ta.Setter2 /= b;\n\t\t\tfield.Setter += 5;\n\t\t\tfield.Setter -= 5;\n\t\t}\n\n\t\tprivate static void InlineCompoundAssignment(dynamic a, dynamic b)\n\t\t{\n\t\t\tConsole.WriteLine(a.Setter2 += 5);\n\t\t\tConsole.WriteLine(a.Setter2 -= 1);\n\t\t\tConsole.WriteLine(a.Setter2 *= 2);\n\t\t\tConsole.WriteLine(a.Setter2 /= 5);\n\t\t\tConsole.WriteLine(a.Setter2 += b);\n\t\t\tConsole.WriteLine(a.Setter2 -= b);\n\t\t\tConsole.WriteLine(a.Setter2 *= b);\n\t\t\tConsole.WriteLine(a.Setter2 /= b);\n\t\t}\n\n\t\tprivate static void UnaryOperators(dynamic a)\n\t\t{\n\t\t\t// TODO : beautify inc/dec on locals and fields\n\t\t\t//a--;\n\t\t\t//a++;\n\t\t\t//--a;\n\t\t\t//++a;\n\t\t\tDynamicTests.Casts(-a);\n\t\t\tDynamicTests.Casts(+a);\n\t\t}\n\n\t\tprivate static void Loops(dynamic list)\n\t\t{\n\t\t\tforeach (dynamic item in list)\n\t\t\t{\n\t\t\t\tDynamicTests.UnaryOperators(item);\n\t\t\t}\n\t\t}\n\n\t\tprivate static void If(dynamic a, dynamic b)\n\t\t{\n\t\t\tif (a == b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Equal\");\n\t\t\t}\n\t\t}\n\n\t\tprivate static void If2(dynamic a, dynamic b)\n\t\t{\n\t\t\tif (a == null || b == null)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"One is null\");\n\t\t\t}\n\t\t}\n\n\t\tprivate static void If3(dynamic a, dynamic b)\n\t\t{\n\t\t\tif (a == null && b == null)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Both are null\");\n\t\t\t}\n\t\t}\n\n\t\tprivate static void If4(dynamic a, dynamic b)\n\t\t{\n\t\t\tif ((a == null || b == null) && GetDynamic(1) && !(GetDynamic(2) && GetDynamic(3)))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"then\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"else\");\n\t\t\t}\n\t\t}\n\n\t\tprivate static bool ConstantTarget(dynamic a)\n\t\t{\n\t\t\treturn true.Equals(a);\n\t\t}\n\n#if CS110 && NET70\n\t\tprivate static nint NewIntPtr(dynamic a)\n\t\t{\n\t\t\treturn new nint(a);\n\t\t}\n#else\n\t\tprivate static IntPtr NewIntPtr(dynamic a)\n\t\t{\n\t\t\treturn new IntPtr(a);\n\t\t}\n#endif\n\n\t\tprivate static dynamic GetDynamic(int i)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tprivate static bool GetBool(int i)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tprivate static dynamic LogicAnd()\n\t\t{\n\t\t\treturn GetDynamic(1) && GetDynamic(2);\n\t\t}\n\n\t\tprivate static dynamic LogicAnd(dynamic a, dynamic b)\n\t\t{\n\t\t\treturn a && b;\n\t\t}\n\n\t\tprivate static void LogicAndExtended(int i, dynamic d)\n\t\t{\n\t\t\tConsole.WriteLine(GetDynamic(1) && GetDynamic(2));\n\t\t\tConsole.WriteLine(GetDynamic(1) && GetBool(2));\n\t\t\tConsole.WriteLine(GetBool(1) && GetDynamic(2));\n\t\t\tConsole.WriteLine(i == 1 && d == null);\n\t\t}\n\n\t\tprivate static dynamic LogicOr()\n\t\t{\n\t\t\treturn GetDynamic(1) || GetDynamic(2);\n\t\t}\n\n\t\tprivate static dynamic LogicOr(dynamic a, dynamic b)\n\t\t{\n\t\t\treturn a || b;\n\t\t}\n\n\t\tprivate static void LogicOrExtended(int i, dynamic d)\n\t\t{\n\t\t\tConsole.WriteLine(GetDynamic(1) || GetDynamic(2));\n\t\t\tConsole.WriteLine(GetDynamic(1) || GetBool(2));\n\t\t\tConsole.WriteLine(GetBool(1) || GetDynamic(2));\n\t\t\tConsole.WriteLine(i == 1 || d == null);\n\t\t}\n\n\t\tprivate static int ImplicitCast(object o)\n\t\t{\n\t\t\treturn (dynamic)o;\n\t\t}\n\n\t\tprivate static int ExplicitCast(object o)\n\t\t{\n\t\t\treturn (int)(dynamic)o;\n\t\t}\n\n\t\tprivate static dynamic GetI()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic I Test()\n\t\t{\n\t\t\treturn GetI();\n\t\t}\n\n\t\tpublic I Test1()\n\t\t{\n\t\t\treturn (I)GetI();\n\t\t}\n\n\t\tpublic I Test2()\n\t\t{\n\t\t\treturn (I)(object)GetI();\n\t\t}\n\n#if CS72\n\t\tpublic void RefParams(ref object a, ref dynamic b, ref dynamic c)\n\t\t{\n\t\t}\n\t\tpublic void RefParams2(in object a, ref dynamic b, out dynamic c)\n\t\t{\n\t\t\tc = null;\n\t\t}\n\n\t\tpublic ref dynamic RefReturn(ref object o)\n\t\t{\n\t\t\treturn ref o;\n\t\t}\n\n\t\tpublic ref readonly dynamic RefReadonlyReturn(in object o)\n\t\t{\n\t\t\treturn ref o;\n\t\t}\n#endif\n\t}\n\n\tinternal static class Extension\n\t{\n\t\tpublic static dynamic ToDynamic(this int i, dynamic info)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/EnumTests.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class EnumTests\n\t{\n\t\tpublic enum SimpleEnum\n\t\t{\n\t\t\tItem1,\n\t\t\tItem2\n\t\t}\n\n\t\tpublic enum NoZero\n\t\t{\n\t\t\tItem1 = 1,\n\t\t\tItem2\n\t\t}\n\n\t\tpublic enum OutOfOrderMembers\n\t\t{\n\t\t\tItem1 = 1,\n\t\t\tItem0 = 0\n\t\t}\n\n\t\tpublic enum EnumSkippedItemTest\n\t\t{\n\t\t\tItem0 = 0,\n\t\t\tItem2 = 2\n\t\t}\n\n\t\tpublic enum EnumDuplicateItemTest\n\t\t{\n\t\t\tItem0 = 0,\n\t\t\tItem1 = 1,\n\t\t\tItem2A = 2,\n\t\t\tItem2B = 2\n\t\t}\n\n\t\tpublic enum LongBasedEnum : long\n\t\t{\n\t\t\tItem1,\n\t\t\tItem2\n\t\t}\n\n\t\tpublic enum LongWithInitializers : long\n\t\t{\n\t\t\tItem1 = 0L,\n\t\t\tItem2 = 20L,\n\t\t\tItem3 = 21L\n\t\t}\n\n\t\tpublic enum ShortWithInitializers : short\n\t\t{\n\t\t\tItem1 = 0,\n\t\t\tItem2 = 20,\n\t\t\tItem3 = 21\n\t\t}\n\n\t\tpublic enum ByteWithInitializers : byte\n\t\t{\n\t\t\tItem1 = 0,\n\t\t\tItem2 = 20,\n\t\t\tItem3 = 21\n\t\t}\n\n\t\t[Flags]\n\t\tpublic enum SimpleFlagsEnum\n\t\t{\n\t\t\tNone = 0,\n\t\t\tItem1 = 1,\n\t\t\tItem2 = 2,\n\t\t\tItem3 = 4,\n\t\t\tAll = 7\n\t\t}\n\n\t\t[Flags]\n\t\tpublic enum NegativeValueWithFlags\n\t\t{\n\t\t\tValue = -2147483647\n\t\t}\n\n\t\tpublic enum NegativeValueWithoutFlags\n\t\t{\n\t\t\tValue = -2147483647\n\t\t}\n\n\t\tpublic AttributeTargets SingleEnumValue()\n\t\t{\n\t\t\treturn AttributeTargets.Class;\n\t\t}\n\n\t\tpublic AttributeTargets TwoEnumValuesOr()\n\t\t{\n\t\t\treturn AttributeTargets.Class | AttributeTargets.Method;\n\t\t}\n\n\t\tpublic AttributeTargets ThreeEnumValuesOr()\n\t\t{\n\t\t\treturn AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Parameter;\n\t\t}\n\n\t\tpublic AttributeTargets UnknownEnumValue()\n\t\t{\n\t\t\treturn (AttributeTargets)1000000;\n\t\t}\n\n\t\tpublic AttributeTargets EnumAllValue()\n\t\t{\n\t\t\treturn AttributeTargets.All;\n\t\t}\n\n\t\tpublic AttributeTargets EnumZeroValue()\n\t\t{\n\t\t\treturn (AttributeTargets)0;\n\t\t}\n\n\t\tpublic object PreservingTypeWhenBoxed()\n\t\t{\n\t\t\treturn AttributeTargets.Delegate;\n\t\t}\n\n\t\tpublic object PreservingTypeWhenBoxedTwoEnum()\n\t\t{\n\t\t\treturn AttributeTargets.Class | AttributeTargets.Delegate;\n\t\t}\n\n\t\tpublic void EnumInNotZeroCheck(SimpleEnum value, NoZero value2)\n\t\t{\n\t\t\tif (value != SimpleEnum.Item1)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\n\t\t\tif (value2 != 0)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExceptionHandling.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n#if CS60\nusing System.IO;\n#endif\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic abstract class ExceptionHandling\n\t{\n\t\tpublic abstract bool B(int i);\n\t\tpublic abstract Task<bool> T();\n\t\tpublic abstract void M(int i);\n\n\t\tpublic bool ConditionalReturnInThrow()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (B(0))\n\t\t\t\t{\n\t\t\t\t\treturn B(1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch\n\t\t\t{\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool SimpleTryCatchException()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Try\");\n\t\t\t\treturn B(new Random().Next());\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"CatchException\");\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool SimpleTryCatchExceptionWithName()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Try\");\n\t\t\t\treturn B(new Random().Next());\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"CatchException ex: \" + ex.ToString());\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n#if CS60\n\t\tpublic bool SimpleTryCatchExceptionWithNameAndCondition()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Try\");\n\t\t\t\treturn B(new Random().Next());\n\t\t\t}\n\t\t\tcatch (Exception ex) when (ex.Message.Contains(\"test\"))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"CatchException ex: \" + ex.ToString());\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool SimpleTryCatchExceptionWithNameAndConditionWithOr()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Try\");\n\t\t\t\treturn B(new Random().Next());\n\t\t\t}\n\t\t\tcatch (Exception ex) when (ex is ArgumentException || ex is IOException)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"CatchException ex: \" + ex.ToString());\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic async Task<bool> SimpleAsyncTryCatchExceptionWithNameAndConditionWithOr()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Try\");\n\t\t\t\treturn await T();\n\t\t\t}\n\t\t\tcatch (Exception ex) when (ex is ArgumentException || ex is IOException)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"CatchException ex: \" + ex.ToString());\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic void CatchWhenWithConditionWithoutExceptionVar()\n\t\t{\n\t\t\tint num = 0;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tthrow new Exception();\n\t\t\t}\n\t\t\tcatch (Exception) when (num == 0)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"jo\");\n\t\t\t}\n\t\t}\n\n#endif\n\n\t\tpublic bool SimpleTryFinally()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Try\");\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally\");\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic void MethodEndingWithEndFinally()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tthrow null;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t}\n\n\t\tpublic void MethodEndingWithRethrow()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tthrow null;\n\t\t\t}\n\t\t\tcatch\n\t\t\t{\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}\n\n\t\tpublic void TryCatchFinally()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Try\");\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.Message);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void TryCatchMultipleHandlers()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Try\");\n\t\t\t}\n\t\t\tcatch (InvalidOperationException ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.Message);\n\t\t\t}\n\t\t\tcatch (SystemException ex2)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex2.Message);\n\t\t\t}\n\t\t\tcatch\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"other\");\n\t\t\t}\n\t\t}\n\n\t\t//public void TwoCatchBlocksWithSameVariable()\n\t\t//{\n\t\t//\ttry {\n\t\t//\t\tConsole.WriteLine(\"Try1\");\n\t\t//\t} catch (Exception ex) {\n\t\t//\t\tConsole.WriteLine(ex.Message);\n\t\t//\t}\n\t\t//\ttry {\n\t\t//\t\tConsole.WriteLine(\"Try2\");\n\t\t//\t} catch (Exception ex) {\n\t\t//\t\tConsole.WriteLine(ex.Message);\n\t\t//\t}\n\t\t//}\n\n\t\tpublic void NoUsingStatementBecauseTheVariableIsAssignedTo()\n\t\t{\n\t\t\tCancellationTokenSource cancellationTokenSource = null;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tcancellationTokenSource = new CancellationTokenSource();\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tif (cancellationTokenSource != null)\n\t\t\t\t{\n\t\t\t\t\tcancellationTokenSource.Dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic void ThrowInFinally()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tthrow new Exception();\n\t\t\t}\n\t\t}\n\n\t\tinternal void EarlyReturnInTryBlock(bool a, bool b)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (a)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"a\");\n\t\t\t\t}\n\t\t\t\telse if (b)\n\t\t\t\t{\n\t\t\t\t\t// #2379: The only goto-free way of representing this code is to use a return statement\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tConsole.WriteLine(\"a || !b\");\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"finally\");\n\t\t\t}\n\t\t}\n\n#if ROSLYN || !OPT\n\t\t// TODO Non-Roslyn compilers create a second while loop inside the try, by inverting the if\n\t\t// This is fixed in the non-optimised version by the enabling the RemoveDeadCode flag\n\t\t//public bool EarlyExitInLoopTry()\n\t\t//{\n\t\t//\twhile (true) {\n\t\t//\t\ttry {\n\t\t//\t\t\twhile (B(0)) {\n\t\t//\t\t\t\tConsole.WriteLine();\n\t\t//\t\t\t}\n\t\t//\n\t\t//\t\t\treturn false;\n\t\t//\t\t} catch {\n\t\t//\t\t}\n\t\t//\t}\n\t\t//}\n\t\tpublic bool EarlyExitInLoopTry()\n\t\t{\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tif (!B(0))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\tConsole.WriteLine();\n\t\t\t\t}\n\t\t\t\tcatch\n\t\t\t\t{\n\t\t\t\t}\n\t\t\t}\n\t\t}\n#endif\n\n\t\tpublic bool ComplexConditionalReturnInThrow()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (B(0))\n\t\t\t\t{\n\t\t\t\t\tif (B(1))\n\t\t\t\t\t{\n\t\t\t\t\t\tConsole.WriteLine(\"0 && 1\");\n\t\t\t\t\t\treturn B(2);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (B(3))\n\t\t\t\t\t{\n\t\t\t\t\t\tConsole.WriteLine(\"0 && 3\");\n\t\t\t\t\t\treturn !B(2);\n\t\t\t\t\t}\n\n\t\t\t\t\tConsole.WriteLine(\"0\");\n\t\t\t\t}\n\n\t\t\t\tConsole.WriteLine(\"End Try\");\n\n\t\t\t}\n\t\t\tcatch\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tif (((B(0) || B(1)) && B(2)) || B(3))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn B(4) && !B(5);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (B(6) || B(7))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn B(8) || B(9);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcatch\n\t\t\t\t\t{\n\t\t\t\t\t\tConsole.WriteLine(\"Catch2\");\n\t\t\t\t\t}\n\t\t\t\t\treturn B(10) && B(11);\n\t\t\t\t}\n\t\t\t\tcatch\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Catch\");\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Finally\");\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic void AppropriateLockExit()\n\t\t{\n\t\t\tint num = 0;\n\t\t\tlock (this)\n\t\t\t{\n\t\t\t\tif (num <= 256)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(0);\n\t\t\t\t}\n\t\t\t\telse if (num <= 1024)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(1);\n\t\t\t\t}\n\t\t\t\telse if (num <= 16384)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(2);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic void ReassignExceptionVar()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"ReassignExceptionVar\");\n\t\t\t}\n\t\t\tcatch (Exception innerException)\n\t\t\t{\n\t\t\t\tif (innerException.InnerException != null)\n\t\t\t\t{\n\t\t\t\t\tinnerException = innerException.InnerException;\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(innerException);\n\t\t\t}\n\t\t}\n\n\t\tpublic int UseExceptionVarOutsideCatch()\n\t\t{\n\t\t\tException ex2;\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tex2 = ex;\n\t\t\t}\n\t\t\tConsole.WriteLine(ex2 != null);\n\t\t\treturn 2;\n\t\t}\n\n\t\tpublic void GenericException<TException>(int input) where TException : Exception\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(input);\n\t\t\t}\n\t\t\tcatch (TException ex)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.Message);\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}\n\n\t\tpublic void GenericException2<T>() where T : Exception\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"CatchT\");\n#if ROSLYN\n\t\t\t}\n\t\t\tcatch (T val)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"{0} {1}\", val, val.ToString());\n\t\t\t}\n#else\n\t\t\t}\n\t\t\tcatch (T arg)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"{0} {1}\", arg, arg.ToString());\n\t\t\t}\n#endif\n\t\t}\n\n#if CS60\n\t\tpublic void GenericExceptionWithCondition<TException>(int input) where TException : Exception\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(input);\n\t\t\t}\n\t\t\tcatch (TException ex) when (ex.Message.Contains(\"Test\"))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.Message);\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}\n\n\t\tpublic void GenericException2WithCondition<TException>(int input) where TException : Exception\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(input);\n\t\t\t}\n\t\t\tcatch (TException ex) when (ex.Message.Contains(\"Test\"))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"{0} {1}\", ex, ex.ToString());\n\t\t\t}\n\t\t}\n\n\t\tpublic void XXX1()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tcatch (Exception ex) when (ex.Data.IsFixedSize)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.ToString());\n#pragma warning disable CA2200 // Rethrow to preserve stack details\n\t\t\t\tthrow ex;\n#pragma warning restore CA2200 // Rethrow to preserve stack details\n\t\t\t}\n\t\t}\n\n\t\tpublic void XXX2()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tcatch (Exception ex) when (ex is InternalBufferOverflowException)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(ex.ToString());\n#pragma warning disable CA2200 // Rethrow to preserve stack details\n\t\t\t\tthrow ex;\n#pragma warning restore CA2200 // Rethrow to preserve stack details\n\t\t\t}\n\t\t}\n#endif\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExpandParamsArgumentsDisabled.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class ExpandParamsArgumentsDisabled\n\t{\n\t\tpublic void Test()\n\t\t{\n\t\t\tMethodWithParams(Array.Empty<int>());\n\t\t\tMethodWithParams(new int[1] { 5 });\n\t\t}\n\n\t\tpublic void MethodWithParams(params int[] b)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExpressionTrees.cs",
    "content": "#pragma warning disable format\n// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Linq.Expressions;\nusing System.Reflection;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Xml;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class ExpressionTrees\n\t{\n\t\tprivate class GenericClass<X>\n\t\t{\n\t\t\tpublic static X StaticField;\n\t\t\tpublic X InstanceField;\n\n\t\t\tpublic static X StaticProperty { get; set; }\n\n\t\t\tpublic X InstanceProperty { get; set; }\n\n\t\t\tpublic static bool GenericMethod<Y>()\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tinternal class GenericClassWithCtor<T>\n\t\t{\n\t\t}\n\n\t\tinternal class GenericClassWithMultipleCtors<T>\n\t\t{\n\t\t\tpublic GenericClassWithMultipleCtors()\n\t\t\t{\n\t\t\t}\n\n\t\t\tpublic GenericClassWithMultipleCtors(int x)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tprivate class AssertTest\n\t\t{\n\t\t\tprivate struct DataStruct\n\t\t\t{\n\t\t\t\tprivate int dummy;\n\t\t\t}\n\n\t\t\tprivate struct WrapperStruct\n\t\t\t{\n\t\t\t\tinternal DataStruct Data;\n\t\t\t}\n\n\t\t\tprivate class SomeClass\n\t\t\t{\n\t\t\t\tinternal WrapperStruct DataWrapper;\n\t\t\t}\n\n\t\t\tprivate SomeClass someClass;\n\n\t\t\tpublic void Test()\n\t\t\t{\n\t\t\t\tGetMember(() => someClass.DataWrapper.Data);\n\t\t\t}\n\n\t\t\tpublic static MemberInfo GetMember<T>(Expression<Func<T>> p)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tpublic class Administrator\n\t\t{\n\t\t\tpublic int ID { get; set; }\n\n\t\t\tpublic string TrueName { get; set; }\n\n\t\t\tpublic string Phone { get; set; }\n\t\t}\n\n\t\tpublic class Contract\n\t\t{\n\t\t\tpublic int ID { get; set; }\n\n\t\t\tpublic string ContractNo { get; set; }\n\n\t\t\tpublic string HouseAddress { get; set; }\n\n\t\t\tpublic DateTime SigningTime { get; set; }\n\n\t\t\tpublic string BuyerName { get; set; }\n\n\t\t\tpublic string BuyerTelephone { get; set; }\n\n\t\t\tpublic string Customer { get; set; }\n\n\t\t\tpublic string CustTelephone { get; set; }\n\n\t\t\tpublic int AdminID { get; set; }\n\n\t\t\tpublic int StoreID { get; set; }\n\t\t}\n\n\t\tpublic class Database\n\t\t{\n\t\t\tpublic IQueryable<Contract> Contracts { get; set; }\n\n\t\t\tpublic IQueryable<Loan> Loan { get; set; }\n\n\t\t\tpublic IQueryable<Administrator> Administrator { get; set; }\n\n\t\t\tpublic IQueryable<Store> Store { get; set; }\n\t\t}\n\n\t\tpublic class Loan\n\t\t{\n\t\t\tpublic string ContractNo { get; set; }\n\n\t\t\tpublic DateTime? ShenDate { get; set; }\n\n\t\t\tpublic DateTime? LoanDate { get; set; }\n\n\t\t\tpublic string Credit { get; set; }\n\n\t\t\tpublic string LoanBank { get; set; }\n\n\t\t\tpublic string Remarks { get; set; }\n\t\t}\n\n\t\tpublic class Store\n\t\t{\n\t\t\tpublic int ID { get; set; }\n\n\t\t\tpublic string Name { get; set; }\n\t\t}\n\n\t\tinternal class MyClass\n\t\t{\n\t\t\tpublic static MyClass operator +(MyClass a, MyClass b)\n\t\t\t{\n\t\t\t\treturn new MyClass();\n\t\t\t}\n\t\t}\n\n\t\tinternal class SimpleType\n\t\t{\n\t\t\tpublic const int ConstField = 1;\n\n\t\t\tpublic static readonly int StaticReadonlyField = 2;\n\n\t\t\tpublic static int StaticField = 3;\n\n\t\t\tpublic readonly int ReadonlyField = 2;\n\n\t\t\tpublic int Field = 3;\n\n#if CS60\n\t\t\tpublic static int StaticReadonlyProperty => 0;\n#else\n\t\tpublic static int StaticReadonlyProperty {\n\t\t\tget {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n#endif\n\n\t\t\tpublic static int StaticProperty { get; set; }\n\n#if CS60\n\t\t\tpublic int ReadonlyProperty => 0;\n#else\n\t\tpublic int ReadonlyProperty {\n\t\t\tget {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n#endif\n\n\t\t\tpublic int Property { get; set; }\n\t\t}\n\n\t\tinternal class SimpleTypeWithCtor\n\t\t{\n\t\t\tpublic SimpleTypeWithCtor(int i)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tinternal class SimpleTypeWithMultipleCtors\n\t\t{\n\t\t\tpublic SimpleTypeWithMultipleCtors()\n\t\t\t{\n\t\t\t}\n\n\t\t\tpublic SimpleTypeWithMultipleCtors(int i)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tprivate int field;\n\t\tprivate Database db;\n\t\tprivate dynamic ViewBag;\n\n\t\tpublic static readonly object[] SupportedMethods = new object[2] {\n\t\t\tToCode(null, () => ((IQueryable<object>)null).Aggregate((object o1, object o2) => (object)null)),\n\t\t\tToCode(null, () => ((IEnumerable<object>)null).Aggregate((object o1, object o2) => (object)null))\n\t\t};\n\n\t\tpublic static readonly object[] SupportedMethods2 = new object[4] {\n\t\t\tToCode(null, () => ((IQueryable<object>)null).Aggregate(null, (object o1, object o2) => (object)null)),\n\t\t\tToCode(null, () => ((IQueryable<object>)null).Aggregate(null, (object o1, object o2) => (object)null, (object o) => (object)null)),\n\t\t\tToCode(null, () => ((IEnumerable<object>)null).Aggregate(null, (object o1, object o2) => (object)null)),\n\t\t\tToCode(null, () => ((IEnumerable<object>)null).Aggregate(null, (object o1, object o2) => (object)null, (object o) => (object)null))\n\t\t};\n\n\t\tpublic static void TestCall(object a)\n\t\t{\n\n\t\t}\n\n\t\tpublic static void TestCall(ref object a)\n\t\t{\n\n\t\t}\n\n\t\tprivate void Issue1249(int ID)\n\t\t{\n\t\t\tif (ID == 0)\n\t\t\t{\n\t\t\t\tViewBag.data = \"''\";\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar model = (from a in db.Contracts\n\t\t\t\t\t\t where a.ID == ID\n\t\t\t\t\t\t select new {\n\t\t\t\t\t\t\t ID = a.ID,\n\t\t\t\t\t\t\t ContractNo = a.ContractNo,\n\t\t\t\t\t\t\t HouseAddress = a.HouseAddress,\n\t\t\t\t\t\t\t AdminID = (from b in db.Administrator\n\t\t\t\t\t\t\t\t\t\twhere b.ID == a.AdminID\n\t\t\t\t\t\t\t\t\t\tselect b.TrueName).FirstOrDefault(),\n\t\t\t\t\t\t\t StoreID = (from b in db.Store\n\t\t\t\t\t\t\t\t\t\twhere b.ID == a.StoreID\n\t\t\t\t\t\t\t\t\t\tselect b.Name).FirstOrDefault(),\n\t\t\t\t\t\t\t SigningTime = a.SigningTime,\n\t\t\t\t\t\t\t YeWuPhone = (from b in db.Administrator\n\t\t\t\t\t\t\t\t\t\t  where b.ID == a.AdminID\n\t\t\t\t\t\t\t\t\t\t  select b.Phone).FirstOrDefault(),\n\t\t\t\t\t\t\t BuyerName = a.BuyerName,\n\t\t\t\t\t\t\t BuyerTelephone = a.BuyerTelephone,\n\t\t\t\t\t\t\t Customer = a.Customer,\n\t\t\t\t\t\t\t CustTelephone = a.CustTelephone,\n\t\t\t\t\t\t\t Credit = (from b in db.Loan\n\t\t\t\t\t\t\t\t\t   where b.ContractNo == a.ContractNo\n\t\t\t\t\t\t\t\t\t   select b.Credit).FirstOrDefault(),\n\t\t\t\t\t\t\t LoanBank = (from b in db.Loan\n\t\t\t\t\t\t\t\t\t\t where b.ContractNo == a.ContractNo\n\t\t\t\t\t\t\t\t\t\t select b.LoanBank).FirstOrDefault(),\n\t\t\t\t\t\t\t Remarks = (from b in db.Loan\n\t\t\t\t\t\t\t\t\t\twhere b.ContractNo == a.ContractNo\n\t\t\t\t\t\t\t\t\t\tselect b.Remarks).FirstOrDefault()\n\t\t\t\t\t\t }).FirstOrDefault();\n\t\t\tViewBag.data = model.ToJson();\n\t\t\tDateTime? dateTime = (from b in db.Loan\n\t\t\t\t\t\t\t\t  where b.ContractNo == model.ContractNo\n\t\t\t\t\t\t\t\t  select b.ShenDate).FirstOrDefault();\n\t\t\tDateTime? dateTime2 = (from b in db.Loan\n\t\t\t\t\t\t\t\t   where b.ContractNo == model.ContractNo\n\t\t\t\t\t\t\t\t   select b.LoanDate).FirstOrDefault();\n\t\t\tViewBag.ShenDate = ((!dateTime.HasValue) ? \"\" : dateTime.ParseDateTime().ToString(\"yyyy-MM-dd\"));\n\t\t\tViewBag.LoanDate = ((!dateTime2.HasValue) ? \"\" : dateTime2.ParseDateTime().ToString(\"yyyy-MM-dd\"));\n\t\t}\n\n\t\tprivate static object ToCode<R>(object x, Expression<Action<R>> expr)\n\t\t{\n\t\t\treturn expr;\n\t\t}\n\n\t\tprivate static object ToCode<R>(object x, Expression<Func<R>> expr)\n\t\t{\n\t\t\treturn expr;\n\t\t}\n\n\t\tprivate static object ToCode<T, R>(object x, Expression<Func<T, R>> expr)\n\t\t{\n\t\t\treturn expr;\n\t\t}\n\n\t\tprivate static object ToCode<T, T2, R>(object x, Expression<Func<T, T2, R>> expr)\n\t\t{\n\t\t\treturn expr;\n\t\t}\n\n\t\tprivate static object X()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic void Parameter(bool a)\n\t\t{\n\t\t\tToCode(X(), () => a);\n\t\t}\n\n\t\tpublic void LocalVariable()\n\t\t{\n\t\t\tbool a = true;\n\t\t\tToCode(X(), () => a);\n\t\t}\n\n\t\tpublic void LambdaParameter()\n\t\t{\n\t\t\tToCode(X(), (bool a) => a);\n\t\t}\n\n\t\tpublic void AddOperator(int x)\n\t\t{\n\t\t\tToCode(X(), () => 1 + x + 2);\n\t\t}\n\n\t\tpublic void AnonymousClasses()\n\t\t{\n\t\t\tToCode(X(), () => new {\n\t\t\t\tX = 3,\n\t\t\t\tA = \"a\"\n\t\t\t});\n\t\t}\n\n\t\tpublic void ArrayIndex()\n\t\t{\n\t\t\tToCode(X(), () => (new int[3] { 3, 4, 5 })[0 + (int)(DateTime.Now.Ticks % 3)]);\n\t\t}\n\n\t\tpublic void ArrayLengthAndDoubles()\n\t\t{\n\t\t\tToCode(X(), () => new double[3] { 1.0, 2.01, 3.5 }.Concat(new double[2] { 1.0, 2.0 }).ToArray().Length);\n\t\t}\n\n\t\tpublic void AsOperator()\n\t\t{\n\t\t\tToCode(X(), () => new object() as string);\n\t\t}\n\n\t\tpublic void ComplexGenericName()\n\t\t{\n\t\t\tToCode(X(), () => ((Func<int, bool>)((int x) => x > 0))(0));\n\t\t}\n\n\t\tpublic void DefaultValue()\n\t\t{\n\t\t\tToCode(X(), () => new TimeSpan(1, 2, 3) == default(TimeSpan));\n\t\t}\n\n\t\tpublic void EnumConstant()\n\t\t{\n\t\t\tToCode(X(), () => new object().Equals(MidpointRounding.ToEven));\n\t\t}\n\n\t\tpublic void IndexerAccess()\n\t\t{\n\t\t\tDictionary<string, int> dict = Enumerable.Range(1, 20).ToDictionary((int n) => n.ToString());\n\t\t\tToCode(X(), () => dict[\"3\"] == 3);\n\t\t}\n\n\t\tpublic void IsOperator()\n\t\t{\n\t\t\tToCode(X(), () => new object() is string);\n\t\t}\n\n\t\tpublic void ListInitializer()\n\t\t{\n\t\t\tToCode(X(), () => new Dictionary<int, int> {\n\t\t\t\t{ 1, 1 },\n\t\t\t\t{ 2, 2 },\n\t\t\t\t{ 3, 4 }\n\t\t\t}.Count == 3);\n\t\t}\n\n\t\tpublic void ListInitializer2()\n\t\t{\n\t\t\tToCode(X(), () => new List<int>(50) { 1, 2, 3 }.Count == 3);\n\t\t}\n\n\t\tpublic void ListInitializer3()\n\t\t{\n\t\t\tToCode(X(), () => new List<int> { 1, 2, 3 }.Count == 3);\n\t\t}\n\n\t\tpublic void LiteralCharAndProperty()\n\t\t{\n\t\t\tToCode(X(), () => new string(' ', 3).Length == 1);\n\t\t}\n\n\t\tpublic void CharNoCast()\n\t\t{\n\t\t\tToCode(X(), () => \"abc\"[1] == 'b');\n\t\t}\n\n\t\tpublic void StringsImplicitCast()\n\t\t{\n\t\t\tint i = 1;\n\t\t\tstring x = \"X\";\n\t\t\tToCode(X(), () => (((\"a\\n\\\\b\" ?? x) + x).Length == 2) ? false : (true && (1m + (decimal)(-i) > 0m || false)));\n\t\t}\n\n\t\tpublic void NotImplicitCast()\n\t\t{\n\t\t\tbyte z = 42;\n\t\t\tToCode(X(), () => ~z == 0);\n\t\t}\n\n\t\tpublic void MembersBuiltin()\n\t\t{\n\t\t\tToCode(X(), () => 1.23m.ToString());\n\t\t\tToCode(X(), () => AttributeTargets.All.HasFlag(AttributeTargets.Assembly));\n\t\t\tToCode(X(), () => \"abc\".Length == 3);\n\t\t\tToCode(X(), () => 'a'.CompareTo('b') < 0);\n\t\t}\n\n\t\tpublic void MembersDefault()\n\t\t{\n\t\t\tToCode(X(), () => default(DateTime).Ticks == 0);\n\t\t\tToCode(X(), () => ((Array)null).Length == 0);\n\t\t\tToCode(X(), () => ((Type)null).IsLayoutSequential);\n\t\t\tToCode(X(), () => ((List<int>)null).Count);\n\t\t\tToCode(X(), () => ((Array)null).Clone() == null);\n\t\t\tToCode(X(), () => ((Type)null).IsInstanceOfType(new object()));\n\t\t\tToCode(X(), () => ((List<int>)null).AsReadOnly());\n\t\t}\n\n\t\tpublic void DoAssert()\n\t\t{\n\t\t\tToCode(X(), () => field != C());\n\t\t\tToCode(X(), () => !object.ReferenceEquals(this, new ExpressionTrees()));\n\t\t\tToCode(X(), () => MyEquals(this) && !MyEquals(null));\n\t\t}\n\n\t\tprivate int C()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tprivate bool MyEquals(ExpressionTrees other)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tpublic void MethodGroupAsExtensionMethod()\n\t\t{\n\t\t\tToCode(X(), (Expression<Func<Func<bool>>>)(() => ((IEnumerable<int>)new int[4] { 2000, 2004, 2008, 2012 }).Any<int>));\n\t\t}\n\n\t\tpublic void MethodGroupConstant()\n\t\t{\n\t\t\tToCode(X(), () => Array.TrueForAll(new int[4] { 2000, 2004, 2008, 2012 }, DateTime.IsLeapYear));\n\n\t\t\tHashSet<int> set = new HashSet<int>();\n\t\t\tToCode(X(), () => new int[4] { 2000, 2004, 2008, 2012 }.All(set.Add));\n\n\t\t\tFunc<Func<object, object, bool>, bool> sink = (Func<object, object, bool> f) => f(null, null);\n\t\t\tToCode(X(), () => sink(object.Equals));\n\t\t}\n\n\t\tpublic void MultipleCasts()\n\t\t{\n\t\t\tToCode(X(), () => 1 == (int)(object)1);\n\t\t}\n\n\t\tpublic void MultipleDots()\n\t\t{\n\t\t\tToCode(X(), () => 3.ToString().ToString().Length > 0);\n\t\t}\n\n\t\tpublic void NestedLambda()\n\t\t{\n\t\t\tFunc<Func<int>, int> call = (Func<int> f) => f();\n\t\t\t//no params\n\t\t\tToCode(X(), () => call(() => 42));\n\t\t\t//one param\n\t\t\tToCode(X(), () => new int[2] { 37, 42 }.Select((int x) => x * 2));\n\t\t\t//two params\n\t\t\tToCode(X(), () => new int[2] { 37, 42 }.Select((int x, int i) => x * 2));\n\t\t}\n\n\t\tpublic void CurriedLambda()\n\t\t{\n\t\t\tToCode(X(), (Expression<Func<int, Func<int, Func<int, int>>>>)((int a) => (int b) => (int c) => a + b + c));\n\t\t}\n\n\t\tprivate bool Fizz(Func<int, bool> a)\n\t\t{\n\t\t\treturn a(42);\n\t\t}\n\n\t\tprivate bool Buzz(Func<int, bool> a)\n\t\t{\n\t\t\treturn a(42);\n\t\t}\n\n\t\tprivate bool Fizz(Func<string, bool> a)\n\t\t{\n\t\t\treturn a(\"42\");\n\t\t}\n\n\t\tprivate bool Fizz(Func<Action, bool> a)\n\t\t{\n\t\t\treturn a(null);\n\t\t}\n\n\t\tpublic void NestedLambda2()\n\t\t{\n\t\t\tToCode(X(), () => Fizz((string x) => x == \"a\"));\n\t\t\tToCode(X(), () => Fizz((string x) => x != \"a\"));\n\t\t\tToCode(X(), () => Fizz((Action x) => x == new Action(NestedLambda2)));\n\t\t\tToCode(X(), () => Fizz((Action x) => x != new Action(NestedLambda2)));\n\t\t\tToCode(X(), () => Fizz((int x) => x == 37));\n\n\t\t\tToCode(X(), () => Fizz((int x) => true));\n\t\t\tToCode(X(), () => Buzz((int x) => true));\n\t\t}\n\n\t\tpublic void NewArrayAndExtensionMethod()\n\t\t{\n\t\t\tToCode(X(), () => new double[3] { 1.0, 2.01, 3.5 }.SequenceEqual(new double[3] { 1.0, 2.01, 3.5 }));\n\t\t}\n\n\t\tpublic void NewMultiDimArray()\n\t\t{\n\t\t\tToCode(X(), () => new int[3, 4].Length == 1);\n\t\t}\n\n\t\tpublic void NewObject()\n\t\t{\n\t\t\tToCode(X(), () => new object() != new object());\n\t\t}\n\n\t\tpublic void NotOperator()\n\t\t{\n\t\t\tbool x = true;\n\t\t\tint y = 3;\n\t\t\tbyte z = 42;\n\t\t\tToCode(X(), () => ~z == 0);\n\t\t\tToCode(X(), () => ~y == 0);\n\t\t\tToCode(X(), () => !x);\n\t\t}\n\n\t\tpublic void ObjectInitializers()\n\t\t{\n\t\t\tXmlReaderSettings s = new XmlReaderSettings {\n\t\t\t\tCloseInput = false,\n\t\t\t\tCheckCharacters = false\n\t\t\t};\n\t\t\tToCode(X(), () => new XmlReaderSettings {\n\t\t\t\tCloseInput = s.CloseInput,\n\t\t\t\tCheckCharacters = s.CheckCharacters\n\t\t\t}.Equals(s));\n\t\t}\n\n\t\tpublic void Quoted()\n\t\t{\n\t\t\tToCode(X(), () => (Expression<Func<int, string, string>>)((int n, string s) => s + n.ToString()) != null);\n\t\t}\n\n\t\tpublic void Quoted2()\n\t\t{\n\t\t\tToCode(X(), () => ToCode(X(), () => true).Equals(null));\n\t\t}\n\n\t\tpublic void QuotedWithAnonymous()\n\t\t{\n\t\t\tToCode(X(), () => new[] {\n\t\t\t\tnew {\n\t\t\t\t\tX = \"a\",\n\t\t\t\t\tY = \"b\"\n\t\t\t\t}\n\t\t\t}.Select(o => o.X + o.Y).Single());\n\t\t}\n\n\t\tpublic void StaticCall()\n\t\t{\n\t\t\tToCode(X(), () => object.Equals(3, 0));\n\t\t}\n\n\t\tpublic void ThisCall()\n\t\t{\n\t\t\tToCode(X(), () => !Equals(3));\n\t\t}\n\n\t\tpublic void ThisExplicit()\n\t\t{\n\t\t\tToCode(X(), () => object.Equals(this, 3));\n\t\t}\n\n\t\tpublic void TypedConstant()\n\t\t{\n\t\t\tToCode(X(), () => new Type[2] {\n\t\t\t\ttypeof(int),\n\t\t\t\ttypeof(string)\n\t\t\t});\n\t\t}\n\n\t\tpublic void StaticCallImplicitCast()\n\t\t{\n\t\t\tToCode(X(), () => object.Equals(3, 0));\n\t\t}\n\n\t\tpublic void StaticMembers()\n\t\t{\n\t\t\tToCode(X(), () => (DateTime.Now > DateTime.Now + TimeSpan.FromMilliseconds(10.001)).ToString() == \"False\");\n\t\t}\n\n\t\tpublic void Strings()\n\t\t{\n\t\t\tint i = 1;\n\t\t\tstring x = \"X\";\n\t\t\tToCode(X(), () => (((\"a\\n\\\\b\" ?? x) + x).Length == 2) ? false : (true && (1m + (decimal)(-i) > 0m || false)));\n\t\t}\n\n\t\tpublic void GenericClassInstance()\n\t\t{\n\t\t\tToCode(X(), () => (double)new GenericClass<int>().InstanceField + new GenericClass<double>().InstanceProperty);\n\t\t}\n\n\t\tpublic void GenericClassStatic()\n\t\t{\n\t\t\tToCode(X(), () => (double)GenericClass<int>.StaticField + GenericClass<double>.StaticProperty);\n\t\t}\n\n\t\tpublic void InvokeGenericMethod()\n\t\t{\n\t\t\tToCode(X(), () => GenericClass<int>.GenericMethod<double>());\n\t\t}\n\n\t\tprivate static void Test<T>(T delegateExpression, Expression<T> expressionTree)\n\t\t{\n\t\t}\n\n\t\tpublic static void ArrayIndexer()\n\t\t{\n\t\t\tTest<Func<int[], int>>((int[] array) => array[0], (int[] array) => array[0]);\n\t\t\tTest<Func<int[], int, int>>((int[] array, int index) => array[index], (int[] array, int index) => array[index]);\n\t\t\tTest<Func<int[,], int>>((int[,] array) => array[0, 5], (int[,] array) => array[0, 5]);\n\t\t\tTest<Func<int[,], int, int>>((int[,] array, int index) => array[index, 7], (int[,] array, int index) => array[index, 7]);\n\t\t\tTest<Func<int[][], int, int>>((int[][] array, int index) => array[index][7], (int[][] array, int index) => array[index][7]);\n\t\t}\n\n\t\tpublic static void ArrayLength()\n\t\t{\n\t\t\tTest<Func<int[], int>>((int[] array) => array.Length, (int[] array) => array.Length);\n\t\t\tTest<Func<int>>(() => ((Array)null).Length, () => ((Array)null).Length);\n\t\t}\n\n\t\tpublic static void NewObj()\n\t\t{\n\t\t\tTest<Func<object>>(() => new SimpleType(), () => new SimpleType());\n\t\t\tTest<Func<object>>(() => new SimpleTypeWithCtor(5), () => new SimpleTypeWithCtor(5));\n\t\t\tTest<Func<object>>(() => new SimpleTypeWithMultipleCtors(), () => new SimpleTypeWithMultipleCtors());\n\t\t\tTest<Func<object>>(() => new SimpleTypeWithMultipleCtors(5), () => new SimpleTypeWithMultipleCtors(5));\n\t\t\tTest<Func<object>>(() => new GenericClass<int>(), () => new GenericClass<int>());\n\t\t\tTest<Func<object>>(() => new GenericClassWithCtor<int>(), () => new GenericClassWithCtor<int>());\n\t\t\tTest<Func<object>>(() => new GenericClassWithMultipleCtors<int>(5), () => new GenericClassWithMultipleCtors<int>(5));\n\t\t}\n\n\t\tpublic unsafe static void TypeOfExpr()\n\t\t{\n\t\t\tTest<Func<Type>>(() => typeof(int), () => typeof(int));\n\t\t\tTest<Func<Type>>(() => typeof(object), () => typeof(object));\n\t\t\tTest<Func<Type>>(() => typeof(List<>), () => typeof(List<>));\n\t\t\tTest<Func<Type>>(() => typeof(List<int>), () => typeof(List<int>));\n\t\t\tTest<Func<Type>>(() => typeof(int*), () => typeof(int*));\n\t\t}\n\n\t\tpublic static void AsTypeExpr()\n\t\t{\n\t\t\tTest<Func<object, MyClass>>((object obj) => obj as MyClass, (object obj) => obj as MyClass);\n\t\t\tTest<Func<object, int?>>((object obj) => obj as int?, (object obj) => obj as int?);\n\t\t\tTest<Func<object, GenericClass<object>>>((object obj) => obj as GenericClass<object>, (object obj) => obj as GenericClass<object>);\n\t\t}\n\n\t\tpublic static void IsTypeExpr()\n\t\t{\n\t\t\tTest<Func<object, bool>>((object obj) => obj is MyClass, (object obj) => obj is MyClass);\n\t\t\tTest<Func<object, bool>>((object obj) => obj is int?, (object obj) => obj is int?);\n\t\t}\n\n\t\tpublic static void UnaryLogicalOperators()\n\t\t{\n\t\t\tTest<Func<bool, bool>>((bool a) => !a, (bool a) => !a);\n\t\t}\n\n\t\tpublic static void ConditionalOperator()\n\t\t{\n\t\t\tToCode(null, (bool a) => a ? 5 : 10);\n\t\t\tToCode(null, (object a) => a ?? new MyClass());\n\t\t}\n\n\t\tpublic static void ComparisonOperators()\n\t\t{\n\t\t\tToCode(null, (int a, int b) => a == b);\n\t\t\tToCode(null, (int a, int b) => a != b);\n\t\t\tToCode(null, (int a, int b) => a < b);\n\t\t\tToCode(null, (int a, int b) => a <= b);\n\t\t\tToCode(null, (int a, int b) => a > b);\n\t\t\tToCode(null, (int a, int b) => a >= b);\n\t\t\tToCode(null, (int a, int b) => a == 1 && b == 2);\n\t\t\tToCode(null, (int a, int b) => a == 1 || b == 2);\n\t\t\tToCode(null, (int a, short b) => a == b);\n\t\t\tToCode(null, (ushort a, int b) => a != b);\n\t\t\tToCode(null, (int a, long b) => (long)a < b);\n\t\t\tToCode(null, (ulong a, uint b) => a <= (ulong)b);\n\t\t\tToCode(null, (int a, uint b) => (long)a <= (long)b);\n\t\t\tToCode(null, (int a, long b) => (long)a > b);\n\t\t\tToCode(null, (short a, long b) => (long)a >= b);\n\t\t\tToCode(null, (int a, int b) => a == 1 && b == 2);\n\t\t\tToCode(null, (int a, int b) => a == 1 || b == 2);\n\t\t}\n\n\t\tpublic static void LiftedComparisonOperators()\n\t\t{\n\t\t\tToCode(X(), (int? a, int? b) => a == b);\n\t\t\tToCode(X(), (int? a, int? b) => a != b);\n\t\t\tToCode(X(), (int? a, int? b) => a < b);\n\t\t\tToCode(X(), (int? a, int? b) => a <= b);\n\t\t\tToCode(X(), (int? a, int? b) => a > b);\n\t\t\tToCode(X(), (int? a, int? b) => a >= b);\n\t\t}\n\n\t\tpublic static void UnaryArithmeticOperators()\n\t\t{\n\t\t\tTest<Func<int, int>>((int a) => a, (int a) => a);\n\t\t\tTest<Func<int, int>>((int a) => -a, (int a) => -a);\n\t\t}\n\n\t\tpublic static void BinaryArithmeticOperators()\n\t\t{\n\t\t\tTest<Func<int, int, int>>((int a, int b) => a + b, (int a, int b) => a + b);\n\t\t\tTest<Func<int, int, int>>((int a, int b) => a - b, (int a, int b) => a - b);\n\t\t\tTest<Func<int, int, int>>((int a, int b) => a * b, (int a, int b) => a * b);\n\t\t\tTest<Func<int, int, int>>((int a, int b) => a / b, (int a, int b) => a / b);\n\t\t\tTest<Func<int, int, int>>((int a, int b) => a % b, (int a, int b) => a % b);\n\t\t\tTest<Func<long, int, long>>((long a, int b) => a + b, (long a, int b) => a + (long)b);\n\t\t\tTest<Func<long, int, long>>((long a, int b) => a - b, (long a, int b) => a - (long)b);\n\t\t\tTest<Func<long, int, long>>((long a, int b) => a * b, (long a, int b) => a * (long)b);\n\t\t\tTest<Func<long, int, long>>((long a, int b) => a / b, (long a, int b) => a / (long)b);\n\t\t\tTest<Func<long, int, long>>((long a, int b) => a % b, (long a, int b) => a % (long)b);\n\t\t\tTest<Func<short, int, int>>((short a, int b) => a + b, (short a, int b) => a + b);\n\t\t\tTest<Func<int, short, int>>((int a, short b) => a - b, (int a, short b) => a - b);\n\t\t\tTest<Func<short, int, int>>((short a, int b) => a * b, (short a, int b) => a * b);\n\t\t\tTest<Func<int, short, int>>((int a, short b) => a / b, (int a, short b) => a / b);\n\t\t\tTest<Func<short, int, int>>((short a, int b) => a % b, (short a, int b) => a % b);\n\t\t}\n\n\t\tpublic static void BitOperators()\n\t\t{\n\t\t\tTest<Func<int, int>>((int a) => ~a, (int a) => ~a);\n\t\t\tTest<Func<int, int, int>>((int a, int b) => a & b, (int a, int b) => a & b);\n\t\t\tTest<Func<int, int, int>>((int a, int b) => a | b, (int a, int b) => a | b);\n\t\t\tTest<Func<int, int, int>>((int a, int b) => a ^ b, (int a, int b) => a ^ b);\n\t\t}\n\n\t\tpublic static void ShiftOperators()\n\t\t{\n\t\t\tTest<Func<int, int>>((int a) => a >> 2, (int a) => a >> 2);\n\t\t\tTest<Func<int, int>>((int a) => a << 2, (int a) => a << 2);\n\t\t\tTest<Func<long, long>>((long a) => a >> 2, (long a) => a >> 2);\n\t\t\tTest<Func<long, long>>((long a) => a << 2, (long a) => a << 2);\n\t\t}\n\n\t\tpublic static void SimpleExpressions()\n\t\t{\n\t\t\tTest<Func<int>>(() => 0, () => 0);\n\t\t\tTest<Func<int, int>>((int a) => a, (int a) => a);\n\t\t}\n\n\t\tpublic static void Capturing()\n\t\t{\n\t\t\tint captured = 5;\n\t\t\tTest<Func<int>>(() => captured, () => captured);\n\t\t}\n\n\t\tpublic static void FieldAndPropertyAccess()\n\t\t{\n\t\t\tToCode(null, () => 1);\n\t\t\tToCode(null, () => SimpleType.StaticField);\n\t\t\tToCode(null, () => SimpleType.StaticReadonlyField);\n\t\t\tToCode(null, () => SimpleType.StaticProperty);\n\t\t\tToCode(null, () => SimpleType.StaticReadonlyProperty);\n\t\t\tToCode(null, (SimpleType a) => a.Field);\n\t\t\tToCode(null, (SimpleType a) => a.Property);\n\t\t\tToCode(null, (SimpleType a) => a.ReadonlyField);\n\t\t\tToCode(null, (SimpleType a) => a.ReadonlyProperty);\n\t\t}\n\n\t\tpublic static void Call()\n\t\t{\n\t\t\tToCode(null, (string a) => Console.WriteLine(a));\n\t\t\tTest<Func<string, string>>((string a) => a.ToString(), (string a) => a.ToString());\n\t\t\tTest<Func<int, string>>((int a) => a.ToString(), (int a) => a.ToString());\n\t\t\tTest<Func<string, char[]>>((string a) => a.ToArray(), (string a) => a.ToArray());\n\t\t\tTest<Func<bool>>(() => 'a'.CompareTo('b') < 0, () => 'a'.CompareTo('b') < 0);\n\t\t\tTest<Action<object, bool>>(delegate (object lockObj, bool lockTaken) {\n\t\t\t\tMonitor.Enter(lockObj, ref lockTaken);\n\t\t\t}, (object lockObj, bool lockTaken) => Monitor.Enter(lockObj, ref lockTaken));\n\t\t\tTest<Func<string, int, bool>>((string str, int num) => int.TryParse(str, out num), (string str, int num) => int.TryParse(str, out num));\n\t\t\tTest<Func<string, SimpleType, bool>>((string str, SimpleType t) => int.TryParse(str, out t.Field), (string str, SimpleType t) => int.TryParse(str, out t.Field));\n\t\t\tTest<Action<object>>(delegate (object o) {\n\t\t\t\tTestCall(o);\n\t\t\t}, (object o) => TestCall(o));\n\t\t\tTest<Action<object>>(delegate (object o) {\n\t\t\t\tTestCall(ref o);\n\t\t\t}, (object o) => TestCall(ref o));\n\t\t}\n\n\t\tpublic static void Quote()\n\t\t{\n\t\t\tTest<Func<bool>>(() => (Expression<Func<int, string, string>>)((int n, string s) => s + n.ToString()) != null, () => (Expression<Func<int, string, string>>)((int n, string s) => s + n.ToString()) != null);\n\t\t}\n\n\t\tpublic static void ArrayInitializer()\n\t\t{\n\t\t\tTest<Func<int[]>>(() => new int[3] { 1, 2, 3 }, () => new int[3] { 1, 2, 3 });\n\t\t\tTest<Func<int[]>>(() => new int[3], () => new int[3]);\n\t\t\tTest<Func<int[,]>>(() => new int[3, 5], () => new int[3, 5]);\n\t\t\tTest<Func<int[][]>>(() => new int[3][], () => new int[3][]);\n\t\t\tTest<Func<int[][]>>(() => new int[1][] { new int[3] { 1, 2, 3 } }, () => new int[1][] { new int[3] { 1, 2, 3 } });\n\t\t}\n\n\t\tpublic static void AnonymousTypes()\n\t\t{\n\t\t\tTest<Func<object>>(() => new {\n\t\t\t\tA = 5,\n\t\t\t\tB = \"Test\"\n\t\t\t}, () => new {\n\t\t\t\tA = 5,\n\t\t\t\tB = \"Test\"\n\t\t\t});\n\t\t}\n\n\t\tpublic static void ObjectInit()\n\t\t{\n\t\t\tToCode(null, () => new SimpleType {\n\t\t\t\tProperty = 4,\n\t\t\t\tField = 3\n\t\t\t});\n\t\t}\n\n\t\tpublic static void StringConcat()\n\t\t{\n\t\t\tTest<Func<string, object, string>>(null, (string a, object b) => a + b);\n\t\t\tTest<Func<string, object, string>>(null, (string a, object b) => a + b.ToString());\n\t\t\tTest<Func<string, int, string>>(null, (string a, int b) => a + b);\n\t\t\tTest<Func<string, int, string>>(null, (string a, int b) => a + b.ToString());\n\t\t}\n\n\t\tpublic async Task Issue1524(string str)\n\t\t{\n\t\t\tawait Task.Delay(100);\n#if CS70\n\t\t\tif (string.IsNullOrEmpty(str) && int.TryParse(str, out var id))\n\t\t\t{\n#else\n\t\t\tint id;\n\t\t\tif (string.IsNullOrEmpty(str) && int.TryParse(str, out id))\n\t\t\t{\n#endif\n\t\t\t\t(from a in new List<int>().AsQueryable()\n\t\t\t\t where a == id\n\t\t\t\t select a).FirstOrDefault();\n\t\t\t}\n\t\t}\n\n\t\tpublic void NullCoalescing()\n\t\t{\n\t\t\tTest<Func<string, string, string>>((string a, string b) => a ?? b, (string a, string b) => a ?? b);\n\t\t\tTest<Func<int?, int>>((int? a) => a ?? 1, (int? a) => a ?? 1);\n\t\t}\n\n\t\tpublic void NullableLifting(Guid? a, Guid? b)\n\t\t{\n\t\t\tToCode(null, () => a == b);\n\t\t\tToCode(null, () => (Guid)a == (Guid)b);\n\t\t}\n\n\t\tpublic void NullableLifting_UnaryOperators()\n\t\t{\n\t\t\tToCode(null, (int? a) => -a);\n\t\t\tToCode(null, (int? a) => ~a);\n\t\t\tToCode(null, (byte? a) => -(int?)a);\n\t\t\tToCode(null, (byte? a) => ~(int?)a);\n\t\t\tToCode(null, (short? a) => -(int?)a);\n\t\t\tToCode(null, (short? a) => ~(int?)a);\n\t\t\tToCode(null, (long? a) => -a);\n\t\t\tToCode(null, (long? a) => ~a);\n\t\t\tToCode(null, (uint? a) => -(long?)a);\n\t\t\tToCode(null, (uint? a) => ~a);\n\t\t\tToCode(null, (sbyte? a) => -(int?)a);\n\t\t\tToCode(null, (sbyte? a) => ~(int?)a);\n\t\t\tToCode(null, (ushort? a) => -(int?)a);\n\t\t\tToCode(null, (ushort? a) => ~(int?)a);\n\t\t\tToCode(null, (ulong? a) => ~a);\n\t\t\tToCode(null, (bool? a) => !a);\n\t\t}\n\n\t\tpublic void NullableLifting_Arithmetic_BinaryOperators()\n\t\t{\n\t\t\tToCode(null, (int? a) => a + (int?)1);\n\t\t\tToCode(null, (int? a) => a + a);\n\t\t\tToCode(null, (int? a) => a - (int?)1);\n\t\t\tToCode(null, (int? a) => a - a);\n\t\t\tToCode(null, (int? a) => a * (int?)2);\n\t\t\tToCode(null, (int? a) => a * a);\n\t\t\tToCode(null, (int? a) => a / (int?)2);\n\t\t\tToCode(null, (int? a) => a / a);\n\t\t\tToCode(null, (int? a) => a % (int?)2);\n\t\t\tToCode(null, (int? a) => a % a);\n\t\t\tToCode(null, (int? a) => a << (int?)2);\n\t\t\tToCode(null, (int? a) => a << a);\n\t\t\tToCode(null, (int? a) => a >> (int?)2);\n\t\t\tToCode(null, (int? a) => a >> a);\n\t\t\tToCode(null, (int? a) => a ^ (int?)2);\n\t\t\tToCode(null, (int? a) => a ^ a);\n\t\t\tToCode(null, (int? a) => a | (int?)2);\n\t\t\tToCode(null, (int? a) => a | a);\n\t\t\tToCode(null, (int? a) => a & (int?)2);\n\t\t\tToCode(null, (int? a) => a & a);\n\t\t}\n\t}\n\n\tinternal static class Extensions\n\t{\n\t\tpublic static dynamic ToJson(this object o)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static DateTime ParseDateTime(this object str)\n\t\t{\n\t\t\treturn default(DateTime);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/ExtensionProperties.cs",
    "content": "using System.Collections.Generic;\nusing System.Linq;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal static class ExtensionProperties\n\t{\n\t\textension<T>(ICollection<T> collection) where T : notnull\n\t\t{\n\t\t\tpublic bool IsEmpty => collection.Count == 0;\n\n\t\t\tpublic int Test {\n\t\t\t\tget {\n\t\t\t\t\treturn 42;\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic void AddIfNotNull(T item)\n\t\t\t{\n\t\t\t\tif (item != null)\n\t\t\t\t{\n\t\t\t\t\tcollection.Add(item);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic T2 Cast<T2>(int index) where T2 : T\n\t\t\t{\n\t\t\t\treturn (T2)(object)collection.ElementAt(index);\n\t\t\t}\n\n\t\t\tpublic static void StaticExtension()\n\t\t\t{\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/FileScopedNamespaces.cs",
    "content": "namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty;\n\ninternal delegate void DelegateInFileScopedNamespace();\n\ninternal class FileScopedNamespaces\n{\n\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/FixProxyCalls.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty\n{\n\tinternal class A\n\t{\n\t\tprotected internal virtual Task<string> Test(string test)\n\t\t{\n\t\t\treturn Task.Run(() => test.ToUpper());\n\t\t}\n\t}\n\n\tinternal class B : A\n\t{\n\t\tprotected internal override async Task<string> Test(string test)\n\t\t{\n\t\t\treturn await base.Test(test);\n\t\t}\n\t}\n\n\tinternal class B2<T> : A\n\t{\n\t\tprotected internal override async Task<string> Test(string test)\n\t\t{\n\t\t\treturn await base.Test(test);\n\t\t}\n\t}\n\n\tinternal class C\n\t{\n\t\tprotected internal virtual string Test(string test)\n\t\t{\n\t\t\treturn string.Join(test, \"fsdf\");\n\t\t}\n\t}\n\n\tinternal class D : C\n\t{\n\t\tprotected internal IEnumerable<string> Test2(string test)\n\t\t{\n\t\t\tyield return base.Test(test);\n\t\t}\n\t}\n\n\tinternal class E\n\t{\n\t\tprotected internal virtual string Test(string test)\n\t\t{\n\t\t\treturn string.Join(test, \"fsdf\");\n\t\t}\n\t}\n\n\tinternal class F : E\n\t{\n\t\tprotected internal override string Test(string test)\n\t\t{\n\t\t\tFunc<string, string> func = (string a) => base.Test(a);\n\t\t\ttest = string.Join(test, \"aa\");\n\t\t\treturn func(test);\n\t\t}\n\t}\n\n\t[CompilerGenerated]\n\tinternal class FalsePositive_Issue1443\n\t{\n\t\tprivate static void WrongMethod()\n\t\t{\n\t\t\tConsole.WriteLine(\"Wrong!\");\n\t\t}\n\n\t\tprivate void CorrectMethod()\n\t\t{\n\t\t\tWrongMethod();\n\t\t}\n\n\t\tprivate void Use()\n\t\t{\n\t\t\tCorrectMethod();\n\t\t}\n\t}\n\n\tinternal class G\n\t{\n\t\tprotected internal virtual void Test(string test)\n\t\t{\n\t\t\tstring.Join(test, \"fsdf\");\n\t\t}\n\t}\n\n\tinternal class H : G\n\t{\n\t\tprivate Action<string> action;\n\n\t\tprotected internal override void Test(string test)\n\t\t{\n\t\t\taction = delegate (string a) {\n\t\t\t\tbase.Test(a);\n\t\t\t};\n\t\t\tif (test.Equals(1))\n\t\t\t{\n\t\t\t\tthrow new Exception(\"roslyn optimizes is inlining the assignment which lets the test fail\");\n\t\t\t}\n\t\t\taction(test);\n\t\t}\n\t}\n\n\tinternal class I\n\t{\n\t\tprotected internal virtual void Test(int a)\n\t\t{\n\n\t\t}\n\t}\n\n\tpublic class Issue1660 : Issue1660Base\n\t{\n\t\tpublic Action<object> M(object state)\n\t\t{\n\t\t\treturn delegate (object x) {\n\t\t\t\tbase.BaseCall(x, state, () => (object)null);\n\t\t\t};\n\t\t}\n\t}\n\n\tpublic class Issue1660Base\n\t{\n\t\tprotected virtual void BaseCall<T>(object x, object state, Func<T> action)\n\t\t{\n\t\t}\n\t}\n\n\tinternal class J : I\n\t{\n\t\tprotected internal override void Test(int a)\n\t\t{\n\t\t\tAction action = delegate {\n\t\t\t\tbase.Test(a);\n\t\t\t};\n\t\t\tif (a.Equals(1))\n\t\t\t{\n\t\t\t\tthrow new Exception(\"roslyn optimize is inlining the assignment which lets the test fail\");\n\t\t\t}\n\t\t\taction();\n\n\t\t}\n\t}\n\n\tinternal class K\n\t{\n\t\tprotected internal virtual IEnumerable<int> Test(int p)\n\t\t{\n\t\t\tyield return p + 1;\n\t\t\tyield return p + 2;\n\t\t}\n\t}\n\n\tinternal class L : K\n\t{\n\t\tprotected internal override IEnumerable<int> Test(int p)\n\t\t{\n\t\t\tyield return base.Test(base.Test(0).GetEnumerator().Current).GetEnumerator().Current;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/FunctionPointers.cs",
    "content": "using System;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class FunctionPointerAddressOf\n\t{\n\t\tpublic static void Overloaded()\n\t\t{\n\t\t}\n\t\tpublic static void Overloaded(int a)\n\t\t{\n\t\t}\n\n\t\tpublic unsafe delegate*<void> GetAddress()\n\t\t{\n\t\t\treturn &Overloaded;\n\t\t}\n\n#if !(CS110 && NET70)\n\t\tpublic unsafe IntPtr GetAddressAsIntPtr()\n\t\t{\n\t\t\treturn (IntPtr)(delegate*<void>)(&Overloaded);\n\t\t}\n#endif\n\n\t\tpublic unsafe nint GetAddressAsNInt()\n\t\t{\n\t\t\treturn (nint)(delegate*<void>)(&Overloaded);\n\t\t}\n\n\t\tpublic unsafe void* GetAddressAsVoidPtr()\n\t\t{\n\t\t\treturn (delegate*<int, void>)(&Overloaded);\n\t\t}\n\n\t\tpublic static string VarianceTest(object o)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic unsafe delegate*<StringBuilder, object> Variance()\n\t\t{\n\t\t\treturn (delegate*<object, string>)(&VarianceTest);\n\t\t}\n\n\t\tpublic unsafe delegate*<void> AddressOfLocalFunction_Managed()\n\t\t{\n\t\t\treturn &LocalFunction;\n\n\t\t\tstatic void LocalFunction()\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe delegate* unmanaged<void> AddressOfLocalFunction_Unmanaged()\n\t\t{\n\t\t\treturn &LocalFunction;\n\n\t\t\t[UnmanagedCallersOnly]\n\t\t\tstatic void LocalFunction()\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe delegate* unmanaged[Cdecl]<void> AddressOfLocalFunction_CDecl()\n\t\t{\n\t\t\treturn &LocalFunction;\n\n\t\t\t[UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvCdecl) })]\n\t\t\tstatic void LocalFunction()\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe delegate* unmanaged[Fastcall]<void> AddressOfLocalFunction_Fastcall()\n\t\t{\n\t\t\treturn &LocalFunction;\n\n\t\t\t[UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvFastcall) })]\n\t\t\tstatic void LocalFunction()\n\t\t\t{\n\t\t\t}\n\t\t}\n\n#if NET60\n\t\tpublic unsafe delegate* unmanaged[MemberFunction]<void> AddressOfLocalFunction_MemberFunction()\n\t\t{\n\t\t\treturn &LocalFunction;\n\n\t\t\t[UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvMemberFunction) })]\n\t\t\tstatic void LocalFunction()\n\t\t\t{\n\t\t\t}\n\t\t}\n#endif\n\n\t\tpublic unsafe delegate* unmanaged[Stdcall]<void> AddressOfLocalFunction_Stdcall()\n\t\t{\n\t\t\treturn &LocalFunction;\n\n\t\t\t[UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvStdcall) })]\n\t\t\tstatic void LocalFunction()\n\t\t\t{\n\t\t\t}\n\t\t}\n\n#if NET60\n\t\tpublic unsafe delegate* unmanaged[SuppressGCTransition]<void> AddressOfLocalFunction_SuppressGCTransition()\n\t\t{\n\t\t\treturn &LocalFunction;\n\n\t\t\t[UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvSuppressGCTransition) })]\n\t\t\tstatic void LocalFunction()\n\t\t\t{\n\t\t\t}\n\t\t}\n#endif\n\n\t\tpublic unsafe delegate* unmanaged[Thiscall]<void> AddressOfLocalFunction_Thiscall()\n\t\t{\n\t\t\treturn &LocalFunction;\n\n\t\t\t[UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvThiscall) })]\n\t\t\tstatic void LocalFunction()\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe delegate* unmanaged[Cdecl, Fastcall]<void> AddressOfLocalFunction_CDeclAndFastcall()\n\t\t{\n\t\t\treturn &LocalFunction;\n\n\t\t\t[UnmanagedCallersOnly(CallConvs = new Type[] {\n\t\t\t\ttypeof(CallConvCdecl),\n\t\t\t\ttypeof(CallConvFastcall)\n\t\t\t})]\n\t\t\tstatic void LocalFunction()\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe delegate* unmanaged[Fastcall, Cdecl]<void> AddressOfLocalFunction_FastcallAndCDecl()\n\t\t{\n\t\t\treturn &LocalFunction;\n\n\t\t\t[UnmanagedCallersOnly(CallConvs = new Type[] {\n\t\t\t\ttypeof(CallConvFastcall),\n\t\t\t\ttypeof(CallConvCdecl)\n\t\t\t})]\n\t\t\tstatic void LocalFunction()\n\t\t\t{\n\t\t\t}\n\t\t}\n\n#if NET60\n\t\tpublic unsafe delegate* unmanaged[Cdecl, SuppressGCTransition]<void> AddressOfLocalFunction_CDeclAndSuppressGCTransition()\n\t\t{\n\t\t\treturn &LocalFunction;\n\n\t\t\t[UnmanagedCallersOnly(CallConvs = new Type[] {\n\t\t\t\ttypeof(CallConvCdecl),\n\t\t\t\ttypeof(CallConvSuppressGCTransition)\n\t\t\t})]\n\t\t\tstatic void LocalFunction()\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe delegate* unmanaged[Fastcall, SuppressGCTransition]<void> AddressOfLocalFunction_FastcallAndSuppressGCTransition()\n\t\t{\n\t\t\treturn &LocalFunction;\n\n\t\t\t[UnmanagedCallersOnly(CallConvs = new Type[] {\n\t\t\t\ttypeof(CallConvFastcall),\n\t\t\t\ttypeof(CallConvSuppressGCTransition)\n\t\t\t})]\n\t\t\tstatic void LocalFunction()\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe delegate* unmanaged[Stdcall, SuppressGCTransition]<void> AddressOfLocalFunction_StdcallAndSuppressGCTransition()\n\t\t{\n\t\t\treturn &LocalFunction;\n\n\t\t\t[UnmanagedCallersOnly(CallConvs = new Type[] {\n\t\t\t\ttypeof(CallConvStdcall),\n\t\t\t\ttypeof(CallConvSuppressGCTransition)\n\t\t\t})]\n\t\t\tstatic void LocalFunction()\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe delegate* unmanaged[Thiscall, SuppressGCTransition]<void> AddressOfLocalFunction_ThiscallAndSuppressGCTransition()\n\t\t{\n\t\t\treturn &LocalFunction;\n\n\t\t\t[UnmanagedCallersOnly(CallConvs = new Type[] {\n\t\t\t\ttypeof(CallConvThiscall),\n\t\t\t\ttypeof(CallConvSuppressGCTransition)\n\t\t\t})]\n\t\t\tstatic void LocalFunction()\n\t\t\t{\n\t\t\t}\n\t\t}\n#endif\n\t}\n\n\tinternal class FunctionPointersWithCallingConvention\n\t{\n\t\tpublic unsafe delegate*<void> fn_default;\n\t\t// Unmanaged without explicit callconv is only supported with .NET 5,\n\t\t// and emits metadata that cannot be parsed by older SRM versions.\n\t\t//public delegate* unmanaged<void> fn_unmanaged;\n\t\tpublic unsafe delegate* unmanaged[Cdecl]<void> fn_cdecl;\n\t\tpublic unsafe delegate* unmanaged[Fastcall]<void> fn_fastcall;\n\t\tpublic unsafe delegate* unmanaged[Stdcall]<void> fn_stdcall;\n\t\tpublic unsafe delegate* unmanaged[Thiscall]<void> fn_thiscall;\n\t}\n\n\tinternal class FunctionPointersWithDynamicTypes\n\t{\n\t\tpublic class D<T, U>\n\t\t{\n\t\t}\n\t\tpublic class A<T>\n\t\t{\n\t\t\tpublic class B<U>\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe delegate*<dynamic, dynamic, dynamic> F1;\n\t\tpublic unsafe delegate*<object, object, dynamic> F2;\n\t\tpublic unsafe delegate*<dynamic, object, object> F3;\n\t\tpublic unsafe delegate*<object, dynamic, object> F4;\n\t\tpublic unsafe delegate*<object, object, object> F5;\n\t\tpublic unsafe delegate*<object, object, ref dynamic> F6;\n\t\tpublic unsafe delegate*<ref dynamic, object, object> F7;\n\t\tpublic unsafe delegate*<object, ref dynamic, object> F8;\n\t\tpublic unsafe delegate*<ref object, ref object, dynamic> F9;\n\t\tpublic unsafe delegate*<dynamic, ref object, ref object> F10;\n\t\tpublic unsafe delegate*<ref object, dynamic, ref object> F11;\n\t\tpublic unsafe delegate*<object, ref readonly dynamic> F12;\n\t\tpublic unsafe delegate*<in dynamic, object> F13;\n\t\tpublic unsafe delegate*<out dynamic, object> F14;\n#if CS120\n\t\tpublic unsafe delegate*<ref readonly dynamic, object> F15;\n#endif\n\t\tpublic unsafe D<delegate*<dynamic>[], dynamic> F16;\n\t\tpublic unsafe delegate*<A<object>.B<dynamic>> F17;\n\t}\n\n\tinternal class FunctionPointersWithNativeIntegerTypes\n\t{\n\t\tpublic unsafe delegate*<nint, nint, nint> F1;\n#if !(CS110 && NET70)\n\t\tpublic unsafe delegate*<IntPtr, IntPtr, nint> F2;\n\t\tpublic unsafe delegate*<nint, IntPtr, IntPtr> F3;\n\t\tpublic unsafe delegate*<IntPtr, nint, IntPtr> F4;\n\t\tpublic unsafe delegate*<delegate*<IntPtr, IntPtr, IntPtr>, nint> F5;\n\t\tpublic unsafe delegate*<nint, delegate*<IntPtr, IntPtr, IntPtr>> F6;\n\t\tpublic unsafe delegate*<delegate*<IntPtr, IntPtr, nint>, IntPtr> F7;\n\t\tpublic unsafe delegate*<IntPtr, delegate*<IntPtr, nint, IntPtr>> F8;\n\t\tpublic unsafe delegate*<IntPtr, delegate*<IntPtr, IntPtr, IntPtr>> F9;\n#endif\n\t}\n\n\tinternal class FunctionPointersWithRefParams\n\t{\n\t\tpublic unsafe delegate*<in byte, ref char, out float, ref readonly int> F1;\n\t\tpublic unsafe delegate*<ref char, out float, ref int> F2;\n\n\t\tpublic unsafe int CallF1(byte b, char c, out float f)\n\t\t{\n\t\t\treturn F1(in b, ref c, out f);\n\t\t}\n\n\t\tpublic unsafe void CallF2(byte b, char c, out float f)\n\t\t{\n\t\t\tF2(ref c, out f) = b;\n\t\t}\n\t}\n\n\tinternal class FunctionPointerTypeInference\n\t{\n\t\tprivate static char Test(int i)\n\t\t{\n\t\t\treturn (char)i;\n\t\t}\n\n\t\tpublic unsafe R GenericMethod<T, R>(delegate*<T, R> f, T arg)\n\t\t{\n\t\t\treturn f(arg);\n\t\t}\n\n\t\tpublic unsafe void Call()\n\t\t{\n\t\t\tdelegate*<int, char> f = &Test;\n\t\t\tGenericMethod(f, 0);\n\t\t\tGenericMethod((delegate*<int, char>)(&Test), 1);\n\t\t\tGenericMethod<int, char>(null, 2);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Generics.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class Generics\n\t{\n\t\tprivate class GenericClass<T>\n\t\t{\n\t\t\tprivate readonly T issue1760;\n\n\t\t\tpublic void M(out GenericClass<T> self)\n\t\t\t{\n\t\t\t\tself = this;\n\t\t\t}\n\n\t\t\tpublic void Issue1760()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\", \" + issue1760);\n\t\t\t}\n\t\t}\n\n\t\tpublic class BaseClass\n\t\t{\n\t\t}\n\n\t\tpublic class DerivedClass : BaseClass\n\t\t{\n\t\t}\n\n\t\tpublic class MyArray<T>\n\t\t{\n\t\t\tpublic class NestedClass<Y>\n\t\t\t{\n\t\t\t\tpublic T Item1;\n\t\t\t\tpublic Y Item2;\n\t\t\t}\n\n\t\t\tpublic enum NestedEnum\n\t\t\t{\n\t\t\t\tA,\n\t\t\t\tB\n\t\t\t}\n\n\t\t\tprivate T[] arr;\n\n\t\t\tpublic MyArray(int capacity)\n\t\t\t{\n\t\t\t\tarr = new T[capacity];\n\t\t\t}\n\n\t\t\tpublic void Size(int capacity)\n\t\t\t{\n\t\t\t\tArray.Resize(ref arr, capacity);\n\t\t\t}\n\n\t\t\tpublic void Grow(int capacity)\n\t\t\t{\n\t\t\t\tif (capacity >= arr.Length)\n\t\t\t\t{\n\t\t\t\t\tSize(capacity);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic interface IInterface\n\t\t{\n\t\t\tvoid Method1<T>() where T : class;\n\t\t\tvoid Method2<T>() where T : class;\n\n\t\t\tvoid Method3(int a, string b, Type c);\n#if CS72\n\t\t\tvoid Method4(in int a);\n#endif\n\t\t}\n\n\t\tpublic abstract class Base : IInterface\n\t\t{\n\t\t\t// constraints must be repeated on implicit interface implementation\n\t\t\tpublic abstract void Method1<T>() where T : class;\n\n\t\t\t// constraints must not be specified on explicit interface implementation\n\t\t\tvoid IInterface.Method2<T>()\n\t\t\t{\n\t\t\t}\n\n\t\t\tvoid IInterface.Method3(int a, string b, Type c)\n\t\t\t{\n\t\t\t}\n\n#if CS72\n\t\t\tvoid IInterface.Method4(in int a)\n\t\t\t{\n\t\t\t}\n#endif\n\t\t}\n\n\t\tpublic class Derived : Base\n\t\t{\n\t\t\t// constraints are inherited automatically and must not be specified\n\t\t\tpublic override void Method1<T>()\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tprivate const MyArray<string>.NestedEnum enumVal = MyArray<string>.NestedEnum.A;\n\t\tprivate static Type type1 = typeof(List<>);\n\t\tprivate static Type type2 = typeof(MyArray<>);\n\t\tprivate static Type type3 = typeof(List<>.Enumerator);\n\t\tprivate static Type type4 = typeof(MyArray<>.NestedClass<>);\n\t\tprivate static Type type5 = typeof(List<int>[]);\n\t\tprivate static Type type6 = typeof(MyArray<>.NestedEnum);\n\n\t\tpublic T CastToTypeParameter<T>(DerivedClass d) where T : BaseClass\n\t\t{\n\t\t\treturn (T)(BaseClass)d;\n\t\t}\n\n\t\tpublic TTarget GenericAsGeneric<TSource, TTarget>(TSource source) where TTarget : class\n\t\t{\n\t\t\treturn source as TTarget;\n\t\t}\n\n\t\tpublic TTarget? GenericAsNullable<TSource, TTarget>(TSource source) where TTarget : struct\n\t\t{\n\t\t\treturn source as TTarget?;\n\t\t}\n\n\t\tpublic TTarget ObjectAsGeneric<TTarget>(object source) where TTarget : class\n\t\t{\n\t\t\treturn source as TTarget;\n\t\t}\n\n\t\tpublic TTarget? ObjectAsNullable<TTarget>(object source) where TTarget : struct\n\t\t{\n\t\t\treturn source as TTarget?;\n\t\t}\n\n\t\tpublic TTarget IntAsGeneric<TTarget>(int source) where TTarget : class\n\t\t{\n\t\t\treturn source as TTarget;\n\t\t}\n\n\t\tpublic TTarget? IntAsNullable<TTarget>(int source) where TTarget : struct\n\t\t{\n\t\t\treturn source as TTarget?;\n\t\t}\n\n\t\tpublic T New<T>() where T : new()\n\t\t{\n\t\t\treturn new T();\n\t\t}\n\n\t\tpublic T NotNew<T>()\n\t\t{\n\t\t\treturn Activator.CreateInstance<T>();\n\t\t}\n\n\t\tpublic bool IsNull<T>(T t)\n\t\t{\n\t\t\treturn t == null;\n\t\t}\n\n\t\tpublic T[] NewArray<T>(int size)\n\t\t{\n\t\t\treturn new T[size];\n\t\t}\n\n\t\tpublic T[,] NewArray<T>(int size1, int size2)\n\t\t{\n\t\t\treturn new T[size1, size2];\n\t\t}\n\n\t\tpublic Type[] TestTypeOf()\n\t\t{\n\t\t\treturn new Type[8] {\n\t\t\t\ttypeof(int),\n\t\t\t\ttypeof(int[]),\n\t\t\t\ttypeof(GenericClass<>),\n\t\t\t\ttypeof(GenericClass<int>),\n\t\t\t\ttypeof(GenericClass<int[]>),\n\t\t\t\ttypeof(Dictionary<, >),\n\t\t\t\ttypeof(List<int>.Enumerator),\n\t\t\t\ttypeof(List<>.Enumerator)\n\t\t\t};\n\t\t}\n\n\t\tpublic static void MethodWithConstraint<T, S>() where T : class, S where S : ICloneable, new()\n\t\t{\n\t\t}\n\n\t\tpublic static void MethodWithStructConstraint<T>() where T : struct\n\t\t{\n\t\t}\n\n\t\tprivate static void MultidimensionalArray<T>(T[,] array)\n\t\t{\n\t\t\tarray[0, 0] = array[0, 1];\n\t\t}\n\n\t\tpublic static Dictionary<string, string>.KeyCollection.Enumerator GetEnumerator(Dictionary<string, string> d, MyArray<string>.NestedClass<int> nc)\n\t\t{\n\t\t\t// Tests references to inner classes in generic classes\n\t\t\treturn d.Keys.GetEnumerator();\n\t\t}\n\n\t\tpublic static bool IsString<T>(T input)\n\t\t{\n\t\t\treturn input is string;\n\t\t}\n\n\t\tpublic static string AsString<T>(T input)\n\t\t{\n\t\t\treturn input as string;\n\t\t}\n\n\t\tpublic static string CastToString<T>(T input)\n\t\t{\n\t\t\treturn (string)(object)input;\n\t\t}\n\n\t\tpublic static T CastFromString<T>(string input)\n\t\t{\n\t\t\treturn (T)(object)input;\n\t\t}\n\n\t\tpublic static bool IsInt<T>(T input)\n\t\t{\n\t\t\treturn input is int;\n\t\t}\n\n\t\tpublic static int CastToInt<T>(T input)\n\t\t{\n\t\t\treturn (int)(object)input;\n\t\t}\n\n\t\tpublic static T CastFromInt<T>(int input)\n\t\t{\n\t\t\treturn (T)(object)input;\n\t\t}\n\n\t\tpublic static bool IsNullableInt<T>(T input)\n\t\t{\n\t\t\treturn input is int?;\n\t\t}\n\n\t\tpublic static int? AsNullableInt<T>(T input)\n\t\t{\n\t\t\treturn input as int?;\n\t\t}\n\n\t\tpublic static int? CastToNullableInt<T>(T input)\n\t\t{\n\t\t\treturn (int?)(object)input;\n\t\t}\n\n\t\tpublic static T CastFromNullableInt<T>(int? input)\n\t\t{\n\t\t\treturn (T)(object)input;\n\t\t}\n\n#if CS73\n\t\tpublic static object CallDelegate<T>(T input) where T : Delegate\n\t\t{\n\t\t\treturn input.DynamicInvoke();\n\t\t}\n\n\t\tpublic static int CountEnumerators<T>() where T : Enum\n\t\t{\n\t\t\treturn typeof(T).GetEnumValues().Length;\n\t\t}\n\n\t\tpublic unsafe static int UnmanagedConstraint<T>() where T : unmanaged\n\t\t{\n\t\t\treturn sizeof(T);\n\t\t}\n#endif\n\n#if NET90\n\t\tpublic static void AllowsRefStruct<T>() where T : allows ref struct\n\t\t{\n\t\t}\n#endif\n\n\t\tpublic static void Issue1959(int a, int b, int? c)\n\t\t{\n\t\t\t// This line requires parentheses around `a < b` to avoid a grammar ambiguity.\n\t\t\tConsole.WriteLine(\"{}, {}\", (a < b), a > (c ?? b));\n\t\t\t// But here there's no ambiguity:\n\t\t\tConsole.WriteLine(\"{}, {}\", a < b, a > b);\n\t\t\tConsole.WriteLine(\"{}, {}\", a < Environment.GetLogicalDrives().Length, a > (c ?? b));\n\t\t}\n\n\t\tpublic static Type Issue2231<T>()\n\t\t{\n\t\t\treturn default(T).GetType();\n\t\t}\n\n\t\tpublic static string Issue2231b<T>()\n\t\t{\n\t\t\treturn default(T).ToString();\n\t\t}\n\n\t\tpublic static void ConstrainedCall<T>(T x, ref T y) where T : IDisposable\n\t\t{\n\t\t\tx.Dispose();\n\t\t\ty.Dispose();\n\t\t}\n\n\t\t// prior to C# 7.0 UseRefLocalsForAccurateOrderOfEvaluation is disabled, so we will inline.\n\t\t// Roslyn 4 generates the explicit ldobj.if.ref pattern, so we can also inline.\n\t\t// The versions in between, we don't inline, so the code doesn't look pretty.\n#if ROSLYN4 || !CS70\n\t\tpublic static int[] Issue3438<T>(T[] array)\n\t\t{\n\t\t\tList<int> list = new List<int>();\n\t\t\tfor (int i = 0; i < array.Length; i++)\n\t\t\t{\n\t\t\t\tif (!array[i].Equals(default(T)))\n\t\t\t\t{\n\t\t\t\t\tlist.Add(i);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn list.ToArray();\n\t\t}\n\t\tpublic void Issue3438b<T>(T[] item1, T item2, int item3) where T : IInterface\n\t\t{\n\t\t\titem1[CastToInt(item2)].Method3(CastToInt(item2), CastToString(item2), TestTypeOf()[1]);\n\t\t}\n\t\tpublic void Issue3438c<T>(T item, T item2, int item3) where T : IInterface\n\t\t{\n\t\t\tCastFromInt<T>(item3).Method3(CastToInt(item2), CastToString(item2), TestTypeOf()[1]);\n\t\t}\n\t\t//#if CS72\n\t\t// Disabled because ILInlining does not support inlining ldloca currently.\n\t\t//\t\tpublic void Issue3438d<T>(T[] item1, T item2, int item3) where T : IInterface\n\t\t//\t\t{\n\t\t//\t\t\titem1[CastToInt(item2)].Method4(CastToInt(item2));\n\t\t//\t\t}\n\t\t//#endif\n#endif\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/GloballyQualifiedTypeInStringInterpolation.cs",
    "content": "namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic static class GloballyQualifiedTypeInStringInterpolation\n\t{\n\t\tpublic static string Root => $\"Prefix {(global::System.DateTime.Now)} suffix\";\n\t\tpublic static string Cast => $\"Prefix {((int)global::System.DateTime.Now.Ticks)} suffix\";\n#if CS100 && NET60\n\t\tpublic static string Lambda1 => $\"Prefix {(() => global::System.DateTime.Now)} suffix\";\n#else\n\t\tpublic static string Lambda1 => $\"Prefix {(global::System.Func<global::System.DateTime>)(() => global::System.DateTime.Now)} suffix\";\n#endif\n\t\tpublic static string Lambda2 => $\"Prefix {((global::System.Func<global::System.DateTime>)(() => global::System.DateTime.Now))()} suffix\";\n\t\tpublic static string Method1 => $\"Prefix {M(global::System.DateTime.Now)} suffix\";\n\t\tpublic static string Method2 => $\"Prefix {(global::System.DateTime.Now.Ticks)} suffix\";\n\t\tpublic static string Method3 => $\"Prefix {(global::System.DateTime.Equals(global::System.DateTime.Now, global::System.DateTime.Now))} suffix\";\n\t\tpublic static string ConditionalExpression1 => $\"Prefix {(Boolean ? global::System.DateTime.Now : global::System.DateTime.UtcNow)} suffix\";\n\t\tpublic static string ConditionalExpression2 => $\"Prefix {(Boolean ? global::System.DateTime.Now : global::System.DateTime.UtcNow).Ticks} suffix\";\n\n\t\tprivate static bool Boolean => false;\n\t\tprivate static long M(global::System.DateTime time)\n\t\t{\n\t\t\treturn time.Ticks;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/HelloWorld.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class HelloWorld\n\t{\n\t\tpublic static void Main()\n\t\t{\n\t\t\tConsole.WriteLine(\"Hello World!\");\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/IndexRangeTest.cs",
    "content": "// Copyright (c) 2020 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class CustomList\n\t{\n\t\tpublic int Count => 0;\n\t\tpublic int this[int index] => 0;\n\n\t\tpublic CustomList Slice(int start, int length)\n\t\t{\n\t\t\treturn this;\n\t\t}\n\t}\n\n\tinternal class CustomList2\n\t{\n\t\tpublic int Count => 0;\n\t\tpublic int this[int index] => 0;\n\t\tpublic int this[Index index] => 0;\n\t\tpublic CustomList2 this[Range range] => this;\n\n\t\tpublic CustomList2 Slice(int start, int length)\n\t\t{\n\t\t\treturn this;\n\t\t}\n\t}\n\n\tinternal class IndexRangeTest\n\t{\n\t\tpublic static int[] GetArray()\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static List<int> GetList()\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static Span<int> GetSpan()\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static string GetString()\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static Index GetIndex(int i = 0)\n\t\t{\n\t\t\treturn i;\n\t\t}\n\t\tpublic static Range GetRange(int i = 0)\n\t\t{\n\t\t\treturn i..^i;\n\t\t}\n\t\tpublic static int GetInt(int i = 0)\n\t\t{\n\t\t\treturn i;\n\t\t}\n\t\tpublic static Range[] SeveralRanges()\n\t\t{\n\t\t\t// Some of these are semantically identical, but we can still distinguish them in the IL code:\n\t\t\treturn new Range[14] {\n\t\t\t\t..,\n\t\t\t\t0..,\n\t\t\t\t^0..,\n\t\t\t\tGetInt(1)..,\n\t\t\t\t^GetInt(2)..,\n\t\t\t\t..0,\n\t\t\t\t..^0,\n\t\t\t\t..GetInt(3),\n\t\t\t\t..^GetInt(4),\n\t\t\t\t0..^0,\n\t\t\t\t^0..0,\n\t\t\t\t0..0,\n\t\t\t\tGetInt(5)..GetInt(6),\n\t\t\t\t0..(GetInt(7) + GetInt(8))\n\t\t\t};\n\t\t}\n\n\t\tpublic static void UseIndex()\n\t\t{\n\t\t\tConsole.WriteLine(GetArray()[GetIndex()]);\n\t\t\tConsole.WriteLine(GetList()[GetIndex()]);\n\t\t\tConsole.WriteLine(GetSpan()[GetIndex()]);\n\t\t\tConsole.WriteLine(GetString()[GetIndex()]);\n\t\t\tConsole.WriteLine(GetString()?[GetIndex()]);\n\t\t\tConsole.WriteLine(new CustomList()[GetIndex()]);\n\t\t\tConsole.WriteLine(new CustomList2()[GetIndex()]);\n\t\t}\n\n\t\tpublic static void UseIndexFromEnd()\n\t\t{\n\t\t\tConsole.WriteLine(GetArray()[^GetInt()]);\n\t\t\tConsole.WriteLine(GetList()[^GetInt()]);\n\t\t\tConsole.WriteLine(GetSpan()[^GetInt()]);\n\t\t\tConsole.WriteLine(GetString()[^GetInt()]);\n\t\t\tConsole.WriteLine(GetString()?[^GetInt()]);\n\t\t\tConsole.WriteLine(new CustomList()[^GetInt()]);\n\t\t\tConsole.WriteLine(new CustomList2()[^GetInt()]);\n\t\t}\n\n\t\tpublic static void UseIndexForWrite()\n\t\t{\n\t\t\tGetArray()[GetIndex()] = GetInt();\n\t\t\tGetList()[GetIndex()] = GetInt();\n\t\t\tGetSpan()[GetIndex()] = GetInt();\n\t\t}\n\n\t\tprivate static void UseRef(ref int i)\n\t\t{\n\t\t}\n\n\t\tpublic static void UseIndexForRef()\n\t\t{\n\t\t\tUseRef(ref GetArray()[GetIndex()]);\n\t\t\tUseRef(ref GetArray()[^GetInt()]);\n\t\t\tUseRef(ref GetSpan()[GetIndex()]);\n\t\t\tUseRef(ref GetSpan()[^GetInt()]);\n\t\t}\n\n\t\tpublic static void UseRange()\n\t\t{\n\t\t\tConsole.WriteLine(GetArray()[GetRange()]);\n\t\t\t//Console.WriteLine(GetList()[GetRange()]); // fails to compile\n\t\t\tConsole.WriteLine(GetSpan()[GetRange()].ToString());\n\t\t\tConsole.WriteLine(GetString()[GetRange()]);\n\t\t\tConsole.WriteLine(GetString()?[GetRange()]);\n\t\t\tConsole.WriteLine(new CustomList()[GetRange()]);\n\t\t\tConsole.WriteLine(new CustomList2()[GetRange()]);\n\t\t}\n\t\tpublic static void UseNewRangeFromIndex()\n\t\t{\n\t\t\tConsole.WriteLine(GetArray()[GetIndex(1)..GetIndex(2)]);\n\t\t\t//Console.WriteLine(GetList()[GetIndex(1)..GetIndex(2)]); // fails to compile\n\t\t\tConsole.WriteLine(GetSpan()[GetIndex(1)..GetIndex(2)].ToString());\n\t\t\tConsole.WriteLine(GetString()[GetIndex(1)..GetIndex(2)]);\n\t\t\tConsole.WriteLine(GetString()?[GetIndex(1)..GetIndex(2)]);\n\t\t\tConsole.WriteLine(new CustomList()[GetIndex(1)..GetIndex(2)]);\n\t\t\tConsole.WriteLine(new CustomList2()[GetIndex(1)..GetIndex(2)]);\n\t\t}\n\t\tpublic static void UseNewRangeFromIntegers_BothFromStart()\n\t\t{\n\t\t\tConsole.WriteLine(GetArray()[GetInt(1)..GetInt(2)]);\n\t\t\t//Console.WriteLine(GetList()[GetInt()..GetInt()]); // fails to compile\n\t\t\tConsole.WriteLine(GetSpan()[GetInt(1)..GetInt(2)].ToString());\n\t\t\tConsole.WriteLine(GetString()[GetInt(1)..GetInt(2)]);\n\t\t\tConsole.WriteLine(GetString()?[GetInt(1)..GetInt(2)]);\n\t\t\tConsole.WriteLine(new CustomList()[GetInt(1)..GetInt(2)]);\n\t\t\tConsole.WriteLine(new CustomList2()[GetInt(1)..GetInt(2)]);\n\t\t}\n\t\tpublic static void UseNewRangeFromIntegers_BothFromEnd()\n\t\t{\n\t\t\tConsole.WriteLine(GetArray()[^GetInt(1)..^GetInt(2)]);\n\t\t\t//Console.WriteLine(GetList()[^GetInt()..^GetInt()]); // fails to compile\n\t\t\tConsole.WriteLine(GetSpan()[^GetInt(1)..^GetInt(2)].ToString());\n\t\t\tConsole.WriteLine(GetString()[^GetInt(1)..^GetInt(2)]);\n\t\t\tConsole.WriteLine(GetString()?[^GetInt(1)..^GetInt(2)]);\n\t\t\tConsole.WriteLine(new CustomList()[^GetInt(1)..^GetInt(2)]);\n\t\t\tConsole.WriteLine(new CustomList2()[^GetInt(1)..^GetInt(2)]);\n\t\t}\n\t\tpublic static void UseNewRangeFromIntegers_FromStartAndEnd()\n\t\t{\n\t\t\tConsole.WriteLine(GetArray()[GetInt(1)..^GetInt(2)]);\n\t\t\t//Console.WriteLine(GetList()[GetInt()..^GetInt()]); // fails to compile\n\t\t\tConsole.WriteLine(GetSpan()[GetInt(1)..^GetInt(2)].ToString());\n\t\t\tConsole.WriteLine(GetString()[GetInt(1)..^GetInt(2)]);\n\t\t\tConsole.WriteLine(GetString()?[GetInt(1)..^GetInt(2)]);\n\t\t\tConsole.WriteLine(new CustomList()[GetInt(1)..^GetInt(2)]);\n\t\t\tConsole.WriteLine(new CustomList2()[GetInt(1)..^GetInt(2)]);\n\t\t}\n\t\tpublic static void UseNewRangeFromIntegers_FromEndAndStart()\n\t\t{\n\t\t\tConsole.WriteLine(GetArray()[^GetInt(1)..GetInt(2)]);\n\t\t\t//Console.WriteLine(GetList()[^GetInt()..GetInt()]);  // fails to compile\n\t\t\tConsole.WriteLine(GetSpan()[^GetInt(1)..GetInt(2)].ToString());\n\t\t\tConsole.WriteLine(GetString()[^GetInt(1)..GetInt(2)]);\n\t\t\tConsole.WriteLine(GetString()?[^GetInt(1)..GetInt(2)]);\n\t\t\tConsole.WriteLine(new CustomList()[^GetInt(1)..GetInt(2)]);\n\t\t\tConsole.WriteLine(new CustomList2()[^GetInt(1)..GetInt(2)]);\n\t\t}\n\n\t\tpublic static void UseNewRangeFromIntegers_OnlyEndPoint()\n\t\t{\n\t\t\tConsole.WriteLine(GetArray()[..GetInt(2)]);\n\t\t\t//Console.WriteLine(GetList()[..GetInt()]);  // fails to compile\n\t\t\tConsole.WriteLine(GetSpan()[..GetInt(2)].ToString());\n\t\t\tConsole.WriteLine(GetString()[..GetInt(2)]);\n\t\t\tConsole.WriteLine(GetString()?[..GetInt(2)]);\n\t\t\tConsole.WriteLine(new CustomList()[..GetInt(2)]);\n\t\t\tConsole.WriteLine(new CustomList2()[..GetInt(2)]);\n\t\t}\n\n\t\tpublic static void UseNewRangeFromIntegers_OnlyEndPoint_FromEnd()\n\t\t{\n\t\t\tConsole.WriteLine(GetArray()[..^GetInt(2)]);\n\t\t\t//Console.WriteLine(GetList()[..^GetInt()]);  // fails to compile\n\t\t\tConsole.WriteLine(GetSpan()[..^GetInt(2)].ToString());\n\t\t\tConsole.WriteLine(GetString()[..^GetInt(2)]);\n\t\t\tConsole.WriteLine(GetString()?[..^GetInt(2)]);\n\t\t\tConsole.WriteLine(new CustomList()[..^GetInt(2)]);\n\t\t\tConsole.WriteLine(new CustomList2()[..^GetInt(2)]);\n\t\t}\n\n\t\tpublic static void UseNewRangeFromIntegers_OnlyStartPoint()\n\t\t{\n\t\t\tConsole.WriteLine(GetArray()[GetInt(1)..]);\n\t\t\t//Console.WriteLine(GetList()[GetInt()..]); // fails to compile\n\t\t\tConsole.WriteLine(GetSpan()[GetInt(1)..].ToString());\n\t\t\tConsole.WriteLine(GetString()[GetInt(1)..]);\n\t\t\tConsole.WriteLine(GetString()?[GetInt(1)..]);\n\t\t\tConsole.WriteLine(new CustomList()[GetInt(1)..]);\n\t\t\tConsole.WriteLine(new CustomList2()[GetInt(1)..]);\n\t\t}\n\n\t\tpublic static void UseNewRangeFromIntegers_OnlyStartPoint_FromEnd()\n\t\t{\n\t\t\tConsole.WriteLine(GetArray()[^GetInt(1)..]);\n\t\t\t//Console.WriteLine(GetList()[^GetInt()..]); // fails to compile\n\t\t\tConsole.WriteLine(GetSpan()[^GetInt(1)..].ToString());\n\t\t\tConsole.WriteLine(GetString()[^GetInt(1)..]);\n\t\t\tConsole.WriteLine(GetString()?[^GetInt(1)..]);\n\t\t\tConsole.WriteLine(new CustomList()[^GetInt(1)..]);\n\t\t\tConsole.WriteLine(new CustomList2()[^GetInt(1)..]);\n\t\t}\n\n\t\tpublic static void UseConstantRange()\n\t\t{\n\t\t\t// Fortunately the C# compiler doesn't optimize\n\t\t\t// \"str.Length - 2 - 1\" here, so the normal pattern applies.\n\t\t\tConsole.WriteLine(GetString()[1..2]);\n\t\t\tConsole.WriteLine(GetString()[1..^1]);\n\t\t\tConsole.WriteLine(GetString()[^2..^1]);\n\n\t\t\tConsole.WriteLine(GetString()[..1]);\n\t\t\tConsole.WriteLine(GetString()[..^1]);\n\t\t\tConsole.WriteLine(GetString()[1..]);\n\t\t\tConsole.WriteLine(GetString()[^1..]);\n\t\t}\n\n\t\tpublic static void UseWholeRange()\n\t\t{\n\t\t\tConsole.WriteLine(GetArray()[..]);\n\t\t\t//Console.WriteLine(GetList()[..]); // fails to compile\n\t\t\tConsole.WriteLine(GetSpan()[..].ToString());\n\t\t\tConsole.WriteLine(GetString()[..]);\n\t\t\tConsole.WriteLine(new CustomList()[..]);\n\t\t\tConsole.WriteLine(new CustomList2()[..]);\n\t\t}\n\n\t\tpublic static void UseIndexForIntIndexerWhenIndexIndexerIsAvailable()\n\t\t{\n\t\t\t// Same code as the compiler emits for CustomList,\n\t\t\t// but here we can't translate it back to `customList[GetIndex()]`\n\t\t\t// because that would call a different overload.\n\t\t\tCustomList2 customList = new CustomList2();\n\t\t\tint count = customList.Count;\n\t\t\tint offset = GetIndex().GetOffset(count);\n\t\t\tConsole.WriteLine(customList[offset]);\n\t\t}\n\n\t\tpublic static void UseSliceWhenRangeIndexerIsAvailable()\n\t\t{\n\t\t\t// Same code as the compiler emits for CustomList,\n\t\t\t// but here we can't translate it back to `customList[GetIndex()]`\n\t\t\t// because that would call a different overload.\n\t\t\tCustomList2 customList = new CustomList2();\n\t\t\tint count = customList.Count;\n\t\t\tRange range = GetRange();\n\t\t\tint offset = range.Start.GetOffset(count);\n\t\t\tint length = range.End.GetOffset(count) - offset;\n\t\t\tConsole.WriteLine(customList.Slice(offset, length));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/InitializerTests.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\nusing System.Threading;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.InitializerTests\n{\n\tpublic static class Extensions\n\t{\n\t\tpublic static void Add(this TestCases.CustomList<int> inst, string a, string b)\n\t\t{\n\t\t}\n\n\t\tpublic static void Add<T>(this IList<KeyValuePair<string, string>> collection, string key, T value, Func<T, string> convert = null)\n\t\t{\n\t\t}\n\n\t\tpublic static void Add(this TestCases collection, string key)\n\t\t{\n\t\t}\n\t}\n\n\tpublic class TestCases\n\t{\n\t\t#region Types\n\t\tpublic class CustomList<T> : IEnumerable<T>, IEnumerable\n\t\t{\n\t\t\tpublic IEnumerator<T> GetEnumerator()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tIEnumerator IEnumerable.GetEnumerator()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic void Add<T2>(string name)\n\t\t\t{\n\t\t\t\tnew Dictionary<string, Type>().Add(name, typeof(T2));\n\t\t\t}\n\n\t\t\tpublic void Add(params int[] ints)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic class C\n\t\t{\n\t\t\tpublic int Z;\n\t\t\tpublic S Y;\n\t\t\tpublic List<S> L;\n\n\t\t\tpublic S this[int index] {\n\t\t\t\tget {\n\t\t\t\t\treturn default(S);\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic S this[object key] {\n\t\t\t\tget {\n\t\t\t\t\treturn default(S);\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic struct S\n\t\t{\n\t\t\tpublic int A;\n\t\t\tpublic int B;\n\n\t\t\tpublic int M()\n\t\t\t{\n\t\t\t\treturn 42;\n\t\t\t}\n\n\t\t\tpublic S(int a)\n\t\t\t{\n\t\t\t\tA = a;\n\t\t\t\tB = 0;\n\t\t\t}\n\t\t}\n\n\t\tprivate enum MyEnum\n\t\t{\n\t\t\ta,\n\t\t\tb\n\t\t}\n\n\t\tprivate enum MyEnum2\n\t\t{\n\t\t\tc,\n\t\t\td\n\t\t}\n\n\t\tprivate class Data\n\t\t{\n\t\t\tpublic List<MyEnum2> FieldList = new List<MyEnum2>();\n\t\t\tpublic MyEnum a { get; set; }\n\t\t\tpublic MyEnum b { get; set; }\n\t\t\tpublic List<MyEnum2> PropertyList { get; set; }\n#if CS60\n\t\t\tpublic List<MyEnum2> ReadOnlyPropertyList { get; }\n#endif\n\t\t\tpublic Data MoreData { get; set; }\n\n\t\t\tpublic StructData NestedStruct { get; set; }\n\n\t\t\tpublic Data this[int i] {\n\t\t\t\tget {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic Data this[int i, string j] {\n\t\t\t\tget {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic event EventHandler TestEvent;\n\t\t}\n\n\t\tprivate struct StructData\n\t\t{\n\t\t\tpublic int Field;\n\t\t\tpublic int Property { get; set; }\n\n\t\t\tpublic Data MoreData { get; set; }\n\n\t\t\tpublic StructData(int initialValue)\n\t\t\t{\n\t\t\t\tthis = default(StructData);\n\t\t\t\tField = initialValue;\n\t\t\t\tProperty = initialValue;\n\t\t\t}\n\t\t}\n\n\t\tpublic class Item\n\t\t{\n\t\t\tpublic string Text { get; set; }\n\n\t\t\tpublic decimal Value { get; set; }\n\n\t\t\tpublic decimal Value2 { get; set; }\n\n\t\t\tpublic string Value3 { get; set; }\n\n\t\t\tpublic string Value4 { get; set; }\n\n\t\t\tpublic string Value5 { get; set; }\n\n\t\t\tpublic string Value6 { get; set; }\n\n#if CS90\n\t\t\tpublic Fields Value7 { get; set; }\n#endif\n\t\t}\n\n\t\tpublic class OtherItem\n\t\t{\n\t\t\tpublic decimal Value { get; set; }\n\n\t\t\tpublic decimal Value2 { get; set; }\n\n\t\t\tpublic decimal? Nullable { get; set; }\n\n\t\t\tpublic decimal? Nullable2 { get; set; }\n\n\t\t\tpublic decimal? Nullable3 { get; set; }\n\n\t\t\tpublic decimal? Nullable4 { get; set; }\n\t\t}\n\n\t\tpublic class OtherItem2\n\t\t{\n\t\t\tpublic readonly OtherItem Data;\n\n\t\t\tpublic OtherItem Data2 { get; private set; }\n#if CS60\n\t\t\tpublic OtherItem Data3 { get; }\n#endif\n\t\t}\n\n\t\tpublic class V3f\n\t\t{\n\t\t\tprivate float x;\n\t\t\tprivate float y;\n\t\t\tprivate float z;\n\n\t\t\tpublic V3f(float _x, float _y, float _z)\n\t\t\t{\n\t\t\t\tx = _x;\n\t\t\t\ty = _y;\n\t\t\t\tz = _z;\n\t\t\t}\n\t\t}\n\n#if CS90\n\t\tpublic record Fields\n\t\t{\n\t\t\tpublic int A;\n\t\t\tpublic double B = 1.0;\n\t\t\tpublic object C;\n\t\t\tpublic dynamic D;\n\t\t\tpublic string S = \"abc\";\n\t\t\tpublic Item I;\n\t\t}\n\n\t\tpublic record DerivedFields : Fields\n\t\t{\n\t\t\tpublic ConsoleKey E;\n\t\t}\n#endif\n\n\t\tpublic interface IData\n\t\t{\n\t\t\tint Property { get; set; }\n\t\t}\n\n#if CS90\n\t\tpublic class Issue3392Type\n\t\t{\n\t\t\tpublic bool Flag { get; init; }\n\t\t\tpublic List<int> List { get; } = new List<int>();\n\n\t\t\tpublic Issue3392Type(object x)\n\t\t\t{\n\n\t\t\t}\n\t\t}\n\n\t\tprivate class StructInitPropertiesTest\n\t\t{\n\t\t\tprivate class TypeA\n\t\t\t{\n\t\t\t\tpublic int A { get; set; }\n\t\t\t\tpublic int B { get; set; }\n\t\t\t}\n\n\t\t\tprivate struct TypeB\n\t\t\t{\n\t\t\t\tpublic int A { get; set; }\n\t\t\t\tpublic int B { get; set; }\n\t\t\t}\n\n\t\t\tprivate struct TypeC\n\t\t\t{\n\t\t\t\tpublic int A { get; init; }\n\t\t\t\tpublic int B { get; init; }\n\t\t\t}\n\n\t\t\tprivate static TypeA TestA()\n\t\t\t{\n\t\t\t\treturn new TypeA {\n\t\t\t\t\tA = 1,\n\t\t\t\t\tB = 2\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tprivate static TypeB TestB()\n\t\t\t{\n\t\t\t\treturn new TypeB {\n\t\t\t\t\tA = 1,\n\t\t\t\t\tB = 2\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tprivate static TypeC TestC()\n\t\t\t{\n\t\t\t\treturn new TypeC {\n\t\t\t\t\tA = 1,\n\t\t\t\t\tB = 2\n\t\t\t\t};\n\t\t\t}\n\t\t}\n#endif\n\t\t#endregion\n\n\t\tprivate S s1;\n\t\tprivate S s2;\n\n\t\t#region Field initializer tests\n\t\tprivate static V3f[] Issue1336_rg0 = new V3f[3] {\n\t\t\tnew V3f(1f, 1f, 1f),\n\t\t\tnew V3f(2f, 2f, 2f),\n\t\t\tnew V3f(3f, 3f, 3f)\n\t\t};\n\n\t\tprivate static V3f[,] Issue1336_rg1 = new V3f[3, 3] {\n\t\t\t{\n\t\t\t\tnew V3f(1f, 1f, 1f),\n\t\t\t\tnew V3f(2f, 2f, 2f),\n\t\t\t\tnew V3f(3f, 3f, 3f)\n\t\t\t},\n\t\t\t{\n\t\t\t\tnew V3f(2f, 2f, 2f),\n\t\t\t\tnew V3f(3f, 3f, 3f),\n\t\t\t\tnew V3f(4f, 4f, 4f)\n\t\t\t},\n\t\t\t{\n\t\t\t\tnew V3f(3f, 3f, 3f),\n\t\t\t\tnew V3f(4f, 4f, 4f),\n\t\t\t\tnew V3f(5f, 5f, 5f)\n\t\t\t}\n\t\t};\n\n\t\tprivate static V3f[][] Issue1336_rg1b = new V3f[3][] {\n\t\t\tnew V3f[3] {\n\t\t\t\tnew V3f(1f, 1f, 1f),\n\t\t\t\tnew V3f(2f, 2f, 2f),\n\t\t\t\tnew V3f(3f, 3f, 3f)\n\t\t\t},\n\t\t\tnew V3f[3] {\n\t\t\t\tnew V3f(2f, 2f, 2f),\n\t\t\t\tnew V3f(3f, 3f, 3f),\n\t\t\t\tnew V3f(4f, 4f, 4f)\n\t\t\t},\n\t\t\tnew V3f[3] {\n\t\t\t\tnew V3f(3f, 3f, 3f),\n\t\t\t\tnew V3f(4f, 4f, 4f),\n\t\t\t\tnew V3f(5f, 5f, 5f)\n\t\t\t}\n\t\t};\n\n\t\tprivate static V3f[,][] Issue1336_rg1c = new V3f[3, 3][] {\n\t\t\t{\n\t\t\t\tnew V3f[3] {\n\t\t\t\t\tnew V3f(1f, 1f, 1f),\n\t\t\t\t\tnew V3f(2f, 2f, 2f),\n\t\t\t\t\tnew V3f(3f, 3f, 3f)\n\t\t\t\t},\n\t\t\t\tnew V3f[3] {\n\t\t\t\t\tnew V3f(2f, 2f, 2f),\n\t\t\t\t\tnew V3f(3f, 3f, 3f),\n\t\t\t\t\tnew V3f(4f, 4f, 4f)\n\t\t\t\t},\n\t\t\t\tnew V3f[3] {\n\t\t\t\t\tnew V3f(3f, 3f, 3f),\n\t\t\t\t\tnew V3f(4f, 4f, 4f),\n\t\t\t\t\tnew V3f(5f, 5f, 5f)\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tnew V3f[3] {\n\t\t\t\t\tnew V3f(1f, 1f, 1f),\n\t\t\t\t\tnew V3f(2f, 2f, 2f),\n\t\t\t\t\tnew V3f(3f, 3f, 3f)\n\t\t\t\t},\n\t\t\t\tnew V3f[3] {\n\t\t\t\t\tnew V3f(2f, 2f, 2f),\n\t\t\t\t\tnew V3f(3f, 3f, 3f),\n\t\t\t\t\tnew V3f(4f, 4f, 4f)\n\t\t\t\t},\n\t\t\t\tnew V3f[3] {\n\t\t\t\t\tnew V3f(3f, 3f, 3f),\n\t\t\t\t\tnew V3f(4f, 4f, 4f),\n\t\t\t\t\tnew V3f(5f, 5f, 5f)\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tnew V3f[3] {\n\t\t\t\t\tnew V3f(1f, 1f, 1f),\n\t\t\t\t\tnew V3f(2f, 2f, 2f),\n\t\t\t\t\tnew V3f(3f, 3f, 3f)\n\t\t\t\t},\n\t\t\t\tnew V3f[3] {\n\t\t\t\t\tnew V3f(2f, 2f, 2f),\n\t\t\t\t\tnew V3f(3f, 3f, 3f),\n\t\t\t\t\tnew V3f(4f, 4f, 4f)\n\t\t\t\t},\n\t\t\t\tnew V3f[3] {\n\t\t\t\t\tnew V3f(3f, 3f, 3f),\n\t\t\t\t\tnew V3f(4f, 4f, 4f),\n\t\t\t\t\tnew V3f(5f, 5f, 5f)\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tprivate static V3f[][,] Issue1336_rg1d = new V3f[2][,] {\n\t\t\tnew V3f[3, 3] {\n\t\t\t\t{\n\t\t\t\t\tnew V3f(1f, 1f, 1f),\n\t\t\t\t\tnew V3f(2f, 2f, 2f),\n\t\t\t\t\tnew V3f(3f, 3f, 3f)\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tnew V3f(2f, 2f, 2f),\n\t\t\t\t\tnew V3f(3f, 3f, 3f),\n\t\t\t\t\tnew V3f(4f, 4f, 4f)\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tnew V3f(3f, 3f, 3f),\n\t\t\t\t\tnew V3f(4f, 4f, 4f),\n\t\t\t\t\tnew V3f(5f, 5f, 5f)\n\t\t\t\t}\n\t\t\t},\n\t\t\tnew V3f[3, 3] {\n\t\t\t\t{\n\t\t\t\t\tnew V3f(1f, 1f, 1f),\n\t\t\t\t\tnew V3f(2f, 2f, 2f),\n\t\t\t\t\tnew V3f(3f, 3f, 3f)\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tnew V3f(2f, 2f, 2f),\n\t\t\t\t\tnew V3f(3f, 3f, 3f),\n\t\t\t\t\tnew V3f(4f, 4f, 4f)\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tnew V3f(3f, 3f, 3f),\n\t\t\t\t\tnew V3f(4f, 4f, 4f),\n\t\t\t\t\tnew V3f(5f, 5f, 5f)\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tprivate static int[,] Issue1336_rg2 = new int[3, 3] {\n\t\t\t{ 1, 1, 1 },\n\t\t\t{ 1, 1, 1 },\n\t\t\t{ 1, 1, 1 }\n\t\t};\n\n#if CS73 && !NET40\n\t\tpublic static ReadOnlySpan<byte> StaticData1 => new byte[1] { 0 };\n\n\t\tpublic static ReadOnlySpan<byte> StaticData3 => new byte[3] { 1, 2, 3 };\n\n\t\tpublic static Span<byte> StaticData3Span => new byte[3] { 1, 2, 3 };\n#endif\n#if CS110 && !NET40\n\t\tpublic static ReadOnlySpan<byte> UTF8Literal => \"Hello, world!\"u8;\n\t\tpublic static ReadOnlySpan<byte> UTF8LiteralWithNullTerminator => \"Hello, world!\\0\"u8;\n#endif\n\t\t#endregion\n\n\t\t#region Helper methods used to ensure initializers used within expressions work correctly\n\t\tprivate static void X(object a, object b)\n\t\t{\n\t\t}\n\n\t\tprivate static object Y()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static void TestCall(int a, Thread thread)\n\t\t{\n\n\t\t}\n\n\t\tpublic static C TestCall(int a, C c)\n\t\t{\n\t\t\treturn c;\n\t\t}\n\n\t\tprivate static int GetInt()\n\t\t{\n\t\t\treturn 1;\n\t\t}\n\n\t\tprivate static string GetString()\n\t\t{\n\t\t\treturn \"Test\";\n\t\t}\n\n\t\tprivate static void NoOp(Guid?[] array)\n\t\t{\n\n\t\t}\n\n\t\tprivate void Data_TestEvent(object sender, EventArgs e)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\t\t#endregion\n\n\t\t#region Array initializers\n\t\tpublic static void Array1()\n\t\t{\n\t\t\tX(Y(), new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });\n\t\t}\n\n\t\tpublic static void Array2(int a, int b, int c)\n\t\t{\n\t\t\tX(Y(), new int[5] { a, 0, b, 0, c });\n\t\t}\n\n\t\tpublic static void NestedArray(int a, int b, int c)\n\t\t{\n\t\t\tX(Y(), new int[3][] {\n\t\t\t\tnew int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },\n\t\t\t\tnew int[3] { a, b, c },\n\t\t\t\tnew int[6] { 1, 2, 3, 4, 5, 6 }\n\t\t\t});\n\t\t}\n\n\t\tpublic static void NestedNullableArray(int a, int b, int c)\n\t\t{\n\t\t\tX(Y(), new int?[3][] {\n\t\t\t\tnew int?[11] {\n\t\t\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t\t\tnull\n\t\t\t\t},\n\t\t\t\tnew int?[4] { a, b, c, null },\n\t\t\t\tnew int?[7] { 1, 2, 3, 4, 5, 6, null }\n\t\t\t  });\n\t\t}\n\n\t\tpublic unsafe static void NestedPointerArray(int a, int b, int c)\n\t\t{\n\t\t\tX(Y(), new void*[3][] {\n\t\t\t\tnew void*[1] { null },\n\t\t\t\tnew void*[2] {\n\t\t\t\t\t(void*)200,\n\t\t\t\t\tnull\n\t\t\t\t},\n\t\t\t\tnew void*[2] {\n\t\t\t\t\t(void*)100,\n\t\t\t\t\tnull\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic static void ArrayBoolean()\n\t\t{\n\t\t\tX(Y(), new bool[8] { true, false, true, false, false, false, true, true });\n\t\t}\n\n\t\tpublic static void ArrayByte()\n\t\t{\n\t\t\tX(Y(), new byte[10] { 1, 2, 3, 4, 5, 6, 7, 8, 254, 255 });\n\t\t}\n\n\t\tpublic static void ArraySByte()\n\t\t{\n\t\t\tX(Y(), new sbyte[8] { -128, -127, 0, 1, 2, 3, 4, 127 });\n\t\t}\n\n\t\tpublic static void ArrayShort()\n\t\t{\n\t\t\tX(Y(), new short[5] { -32768, -1, 0, 1, 32767 });\n\t\t}\n\n\t\tpublic static void ArrayUShort()\n\t\t{\n\t\t\tX(Y(), new ushort[6] { 0, 1, 32767, 32768, 65534, 65535 });\n\t\t}\n\n\t\tpublic static void ArrayInt()\n\t\t{\n\t\t\tX(Y(), new int[10] { 1, -2, 2000000000, 4, 5, -6, 7, 8, 9, 10 });\n\t\t}\n\n\t\tpublic static void ArrayUInt()\n\t\t{\n\t\t\tX(Y(), new uint[10] { 1u, 2000000000u, 3000000000u, 4u, 5u, 6u, 7u, 8u, 9u, 10u });\n\t\t}\n\n\t\tpublic static void ArrayLong()\n\t\t{\n\t\t\tX(Y(), new long[5] { -4999999999999999999L, -1L, 0L, 1L, 4999999999999999999L });\n\t\t}\n\n\t\tpublic static void ArrayULong()\n\t\t{\n\t\t\tX(Y(), new ulong[10] { 1uL, 2000000000uL, 3000000000uL, 4uL, 5uL, 6uL, 7uL, 8uL, 4999999999999999999uL, 9999999999999999999uL });\n\t\t}\n\n\t\tpublic static void ArrayFloat()\n\t\t{\n\t\t\tX(Y(), new float[6] {\n\t\t\t\t-1.5f,\n\t\t\t\t0f,\n\t\t\t\t1.5f,\n\t\t\t\tfloat.NegativeInfinity,\n\t\t\t\tfloat.PositiveInfinity,\n\t\t\t\tfloat.NaN\n\t\t\t});\n\t\t}\n\n\t\tpublic static void ArrayDouble()\n\t\t{\n\t\t\tX(Y(), new double[6] {\n\t\t\t\t-1.5,\n\t\t\t\t0.0,\n\t\t\t\t1.5,\n\t\t\t\tdouble.NegativeInfinity,\n\t\t\t\tdouble.PositiveInfinity,\n\t\t\t\tdouble.NaN\n\t\t\t});\n\t\t}\n\n\t\tpublic static void ArrayDecimal()\n\t\t{\n\t\t\tX(Y(), new decimal[6] { -100m, 0m, 100m, -79228162514264337593543950335m, 79228162514264337593543950335m, 0.0000001m });\n\t\t}\n\n\t\tpublic static void ArrayString()\n\t\t{\n\t\t\tX(Y(), new string[4] { \"\", null, \"Hello\", \"World\" });\n\t\t}\n\n\t\tpublic static void ArrayEnum()\n\t\t{\n\t\t\tX(Y(), new MyEnum[4] {\n\t\t\t\tMyEnum.a,\n\t\t\t\tMyEnum.b,\n\t\t\t\tMyEnum.a,\n\t\t\t\tMyEnum.b\n\t\t\t});\n\t\t}\n\n\t\tpublic int[,] MultidimensionalInit()\n\t\t{\n\t\t\treturn new int[16, 4] {\n\t\t\t\t{ 0, 0, 0, 0 },\n\t\t\t\t{ 1, 1, 1, 1 },\n\t\t\t\t{ 0, 0, 0, 0 },\n\t\t\t\t{ 0, 0, 0, 0 },\n\t\t\t\t{ 0, 0, 1, 0 },\n\t\t\t\t{ 0, 0, 1, 0 },\n\t\t\t\t{ 0, 0, 1, 0 },\n\t\t\t\t{ 0, 0, 1, 0 },\n\t\t\t\t{ 0, 0, 0, 0 },\n\t\t\t\t{ 1, 1, 1, 1 },\n\t\t\t\t{ 0, 0, 0, 0 },\n\t\t\t\t{ 0, 0, 0, 0 },\n\t\t\t\t{ 0, 0, 1, 0 },\n\t\t\t\t{ 0, 0, 1, 0 },\n\t\t\t\t{ 0, 0, 1, 0 },\n\t\t\t\t{ 0, 0, 1, 0 }\n\t\t\t};\n\t\t}\n\n\t\tpublic int[][,] MultidimensionalInit2()\n\t\t{\n\t\t\treturn new int[4][,] {\n\t\t\t\tnew int[4, 4] {\n\t\t\t\t\t{ 0, 0, 0, 0 },\n\t\t\t\t\t{ 1, 1, 1, 1 },\n\t\t\t\t\t{ 0, 0, 0, 0 },\n\t\t\t\t\t{ 0, 0, 0, 0 }\n\t\t\t\t},\n\t\t\t\tnew int[4, 4] {\n\t\t\t\t\t{ 0, 0, 0, 0 },\n\t\t\t\t\t{ 1, 1, 1, 1 },\n\t\t\t\t\t{ 0, 0, 0, 0 },\n\t\t\t\t\t{ 0, 0, 0, 0 }\n\t\t\t\t},\n\t\t\t\tnew int[4, 4] {\n\t\t\t\t\t{ 0, 0, 1, 0 },\n\t\t\t\t\t{ 0, 0, 1, 0 },\n\t\t\t\t\t{ 0, 0, 1, 0 },\n\t\t\t\t\t{ 0, 0, 1, 0 }\n\t\t\t\t},\n\t\t\t\tnew int[4, 4] {\n\t\t\t\t\t{ 0, 0, 1, 0 },\n\t\t\t\t\t{ 0, 0, 1, 0 },\n\t\t\t\t\t{ 0, 0, 1, 0 },\n\t\t\t\t\t{ 0, 0, 1, 0 }\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\tpublic int[][,,] ArrayOfArrayOfArrayInit()\n\t\t{\n\t\t\treturn new int[2][,,] {\n\t\t\t\tnew int[2, 3, 3] {\n\t\t\t\t\t{\n\t\t\t\t\t\t{ 1, 2, 3 },\n\t\t\t\t\t\t{ 4, 5, 6 },\n\t\t\t\t\t\t{ 7, 8, 9 }\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t{ 11, 12, 13 },\n\t\t\t\t\t\t{ 14, 15, 16 },\n\t\t\t\t\t\t{ 17, 18, 19 }\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tnew int[2, 3, 3] {\n\t\t\t\t\t{\n\t\t\t\t\t\t{ 21, 22, 23 },\n\t\t\t\t\t\t{ 24, 25, 26 },\n\t\t\t\t\t\t{ 27, 28, 29 }\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t{ 31, 32, 33 },\n\t\t\t\t\t\t{ 34, 35, 36 },\n\t\t\t\t\t\t{ 37, 38, 39 }\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\tpublic static void RecursiveArrayInitializer()\n\t\t{\n\t\t\tint[] array = new int[3];\n\t\t\tarray[0] = 1;\n\t\t\tarray[1] = 2;\n\t\t\tarray[2] = array[1] + 1;\n\t\t\tarray[0] = 0;\n\t\t}\n\n\t\tpublic static void InvalidIndices(int a)\n\t\t{\n\t\t\tint[] array = new int[1];\n\t\t\tarray[1] = a;\n\t\t\tX(Y(), array);\n\t\t}\n\n\t\tpublic static void InvalidIndices2(int a)\n\t\t{\n#pragma warning disable 251\n\t\t\tint[] array = new int[1];\n\t\t\tarray[-1] = a;\n\t\t\tX(Y(), array);\n#pragma warning restore\n\t\t}\n\n\t\tpublic static void IndicesInWrongOrder(int a, int b)\n\t\t{\n\t\t\tint[] array = new int[5];\n\t\t\tarray[2] = b;\n\t\t\tarray[1] = a;\n\t\t\tX(Y(), array);\n\t\t}\n\n\t\tpublic int[] IndicesInWrongOrderConstantsFull()\n\t\t{\n\t\t\tint[] array = new int[3];\n\t\t\tarray[0] = 0;\n\t\t\tarray[2] = 1;\n\t\t\tarray[1] = 2;\n\t\t\treturn array;\n\t\t}\n\n\t\tpublic static byte[] ReverseInitializer(int i)\n\t\t{\n\t\t\tbyte[] array = new byte[4];\n\t\t\tarray[3] = (byte)i;\n\t\t\tarray[2] = (byte)(i >> 8);\n\t\t\tarray[1] = (byte)(i >> 16);\n\t\t\tarray[0] = (byte)(i >> 24);\n\t\t\treturn array;\n\t\t}\n\n\t\tpublic static void Issue953_MissingNullableSpecifierForArrayInitializer()\n\t\t{\n\t\t\tNoOp(new Guid?[1] { Guid.Empty });\n\t\t}\n\n\t\tprivate void Issue907_Test3(string text)\n\t\t{\n\t\t\tX(Y(), new Dictionary<string, object> { { \"\", text } });\n\t\t}\n\n\t\tprivate int[] Issue1383(int i, int[] array)\n\t\t{\n\t\t\tarray = new int[4];\n\t\t\tarray[i++] = 1;\n\t\t\tarray[i++] = 2;\n\t\t\treturn array;\n\t\t}\n\n\t\tprivate string[,] Issue1382a()\n\t\t{\n\t\t\treturn new string[4, 4] {\n\t\t\t\t{ null, \"test\", \"hello\", \"world\" },\n\t\t\t\t{ \"test\", null, \"hello\", \"world\" },\n\t\t\t\t{ \"test\", \"hello\", null, \"world\" },\n\t\t\t\t{ \"test\", \"hello\", \"world\", null }\n\t\t\t};\n\t\t}\n\n\t\tprivate string[,] Issue1382b()\n\t\t{\n\t\t\treturn new string[4, 4] {\n\t\t\t\t{ \"test\", \"hello\", \"world\", null },\n\t\t\t\t{ \"test\", \"hello\", null, \"world\" },\n\t\t\t\t{ \"test\", null, \"hello\", \"world\" },\n\t\t\t\t{ null, \"test\", \"hello\", \"world\" }\n\t\t\t};\n\t\t}\n\n\t\tprivate static void OutOfMemory()\n\t\t{\n\t\t\tbyte[] array = new byte[int.MaxValue];\n\t\t\tarray[0] = 1;\n\t\t\tConsole.WriteLine(array.Length);\n\t\t}\n\n#if !NET40 && CS70\n\t\tpublic static ReadOnlySpan<byte> ReadOnlySpanInitializer_ByteArray()\n\t\t{\n\t\t\treturn new byte[3] { 1, 2, 3 };\n\t\t}\n\n\t\tpublic static ReadOnlySpan<int> ReadOnlySpanInitializer_Int32Array()\n\t\t{\n\t\t\treturn new int[3] { 1, 2, 3 };\n\t\t}\n#endif\n\n\t\t#endregion\n\n\t\t#region Object initializers\n\t\tpublic C Test1()\n\t\t{\n\t\t\tC c = new C();\n\t\t\tc.L = new List<S>();\n\t\t\tc.L.Add(new S(1));\n\t\t\treturn c;\n\t\t}\n\n\t\tpublic C Test1Alternative()\n\t\t{\n\t\t\treturn TestCall(1, new C {\n\t\t\t\tL = new List<S> {\n\t\t\t\t\tnew S(1)\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic C Test2()\n\t\t{\n\t\t\tC c = new C();\n\t\t\tc.Z = 1;\n\t\t\tc.Z = 2;\n\t\t\treturn c;\n\t\t}\n\n\t\tpublic C Test3()\n\t\t{\n\t\t\tC c = new C();\n\t\t\tc.Y = new S(1);\n\t\t\tc.Y.A = 2;\n\t\t\treturn c;\n\t\t}\n\n\t\tpublic C Test3b()\n\t\t{\n\t\t\treturn TestCall(0, new C {\n\t\t\t\tZ = 1,\n\t\t\t\tY = {\n\t\t\t\t\tA = 2\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic C Test4()\n\t\t{\n\t\t\tC c = new C();\n\t\t\tc.Y.A = 1;\n\t\t\tc.Z = 2;\n\t\t\tc.Y.B = 3;\n\t\t\treturn c;\n\t\t}\n\n\t\tpublic static void ObjectInitializer()\n\t\t{\n\t\t\tX(Y(), new Data {\n\t\t\t\ta = MyEnum.a\n\t\t\t});\n\t\t}\n\n\t\tpublic static void NotAnObjectInitializer()\n\t\t{\n\t\t\tData data = new Data();\n\t\t\tdata.a = MyEnum.a;\n\t\t\tX(Y(), data);\n\t\t}\n\n\t\tpublic static void NotAnObjectInitializerWithEvent()\n\t\t{\n\t\t\tData data = new Data();\n\t\t\tdata.TestEvent += delegate {\n\t\t\t\tConsole.WriteLine();\n\t\t\t};\n\t\t\tX(Y(), data);\n\t\t}\n\n\t\tpublic static void ObjectInitializerAssignCollectionToField()\n\t\t{\n\t\t\tX(Y(), new Data {\n\t\t\t\ta = MyEnum.a,\n\t\t\t\tFieldList = new List<MyEnum2> {\n\t\t\t\t\tMyEnum2.c,\n\t\t\t\t\tMyEnum2.d\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic static void ObjectInitializerAddToCollectionInField()\n\t\t{\n\t\t\tX(Y(), new Data {\n\t\t\t\ta = MyEnum.a,\n\t\t\t\tFieldList = {\n\t\t\t\t\tMyEnum2.c,\n\t\t\t\t\tMyEnum2.d\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic static void ObjectInitializerAssignCollectionToProperty()\n\t\t{\n\t\t\tX(Y(), new Data {\n\t\t\t\ta = MyEnum.a,\n\t\t\t\tPropertyList = new List<MyEnum2> {\n\t\t\t\t\tMyEnum2.c,\n\t\t\t\t\tMyEnum2.d\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic static void ObjectInitializerAddToCollectionInProperty()\n\t\t{\n\t\t\tX(Y(), new Data {\n\t\t\t\ta = MyEnum.a,\n\t\t\t\tPropertyList = {\n\t\t\t\t\tMyEnum2.c,\n\t\t\t\t\tMyEnum2.d\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic static void ObjectInitializerWithInitializationOfNestedObjects()\n\t\t{\n\t\t\tX(Y(), new Data {\n\t\t\t\tMoreData = {\n\t\t\t\t\ta = MyEnum.a,\n\t\t\t\t\tMoreData = {\n\t\t\t\t\t\ta = MyEnum.b\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic static void ObjectInitializerWithInitializationOfDeeplyNestedObjects()\n\t\t{\n\t\t\tX(Y(), new Data {\n\t\t\t\ta = MyEnum.b,\n\t\t\t\tMoreData = {\n\t\t\t\t  a = MyEnum.a,\n\t\t\t\t  MoreData = {\n\t\t\t\t\t\tMoreData = {\n\t\t\t\t\t\t\tMoreData = {\n\t\t\t\t\t\t\t\tMoreData = {\n\t\t\t\t\t\t\t\t\tMoreData = {\n\t\t\t\t\t\t\t\t\t\tMoreData = {\n\t\t\t\t\t\t\t\t\t\t\ta = MyEnum.b\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t  }\n\t\t\t});\n\t\t}\n\n\t\tpublic static void CollectionInitializerInsideObjectInitializers()\n\t\t{\n\t\t\tX(Y(), new Data {\n\t\t\t\tMoreData = new Data {\n\t\t\t\t\ta = MyEnum.a,\n\t\t\t\t\tb = MyEnum.b,\n\t\t\t\t\tPropertyList = { MyEnum2.c }\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic static void StructInitializer_DefaultConstructor()\n\t\t{\n\t\t\tX(Y(), new StructData {\n\t\t\t\tField = 1,\n\t\t\t\tProperty = 2\n\t\t\t});\n\t\t}\n\n\t\tpublic void InliningOfStFldTarget()\n\t\t{\n\t\t\ts1 = new S {\n\t\t\t\tA = 24,\n\t\t\t\tB = 42\n\t\t\t};\n\t\t\ts2 = new S {\n\t\t\t\tA = 42,\n\t\t\t\tB = 24\n\t\t\t};\n\t\t}\n\n\t\tpublic static void StructInitializer_ExplicitConstructor()\n\t\t{\n\t\t\tX(Y(), new StructData(0) {\n\t\t\t\tField = 1,\n\t\t\t\tProperty = 2\n\t\t\t});\n\t\t}\n\n\t\tpublic static void StructInitializerWithInitializationOfNestedObjects()\n\t\t{\n\t\t\tX(Y(), new StructData {\n\t\t\t\tMoreData = {\n\t\t\t\t\ta = MyEnum.a,\n\t\t\t\t\tFieldList = {\n\t\t\t\t\t\tMyEnum2.c,\n\t\t\t\t\t\tMyEnum2.d\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic static void StructInitializerWithinObjectInitializer()\n\t\t{\n\t\t\tX(Y(), new Data {\n\t\t\t\tNestedStruct = new StructData(2) {\n\t\t\t\t\tField = 1,\n\t\t\t\t\tProperty = 2\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic static void Issue270_NestedInitialisers()\n\t\t{\n\t\t\tNumberFormatInfo[] source = null;\n\n\t\t\tTestCall(0, new Thread(Issue270_NestedInitialisers) {\n\t\t\t\tPriority = ThreadPriority.BelowNormal,\n\t\t\t\tCurrentCulture = new CultureInfo(0) {\n\t\t\t\t\tDateTimeFormat = new DateTimeFormatInfo {\n\t\t\t\t\t\tShortDatePattern = \"ddmmyy\"\n\t\t\t\t\t},\n\t\t\t\t\tNumberFormat = source.Where((NumberFormatInfo format) => format.CurrencySymbol == \"$\").First()\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic OtherItem2 Issue1345()\n\t\t{\n\t\t\tOtherItem2 otherItem = new OtherItem2();\n\t\t\totherItem.Data.Nullable = 3m;\n\t\t\treturn otherItem;\n\t\t}\n\n\t\tpublic OtherItem2 Issue1345b()\n\t\t{\n\t\t\tOtherItem2 otherItem = new OtherItem2();\n\t\t\totherItem.Data2.Nullable = 3m;\n\t\t\treturn otherItem;\n\t\t}\n\n#if CS90\n\t\tpublic Issue3392Type Issue3392(Issue3392Type x)\n\t\t{\n\t\t\tx = new Issue3392Type(null) {\n\t\t\t\tFlag = false\n\t\t\t};\n\t\t\tx.List.AddRange(Enumerable.Range(0, 10));\n\t\t\treturn x;\n\t\t}\n#endif\n#if CS60\n\t\tpublic OtherItem2 Issue1345c()\n\t\t{\n\t\t\tOtherItem2 otherItem = new OtherItem2();\n\t\t\totherItem.Data3.Nullable = 3m;\n\t\t\treturn otherItem;\n\t\t}\n\n\t\tprivate Data Issue1345_FalsePositive()\n\t\t{\n\t\t\treturn new Data {\n\t\t\t\tReadOnlyPropertyList = {\n\t\t\t\t\tMyEnum2.c,\n\t\t\t\t\tMyEnum2.d\n\t\t\t\t}\n\t\t\t};\n\t\t}\n#endif\n\n\t\tprivate void Issue1250_Test1(MyEnum value)\n\t\t{\n\t\t\tX(Y(), new C {\n\t\t\t\tZ = (int)value\n\t\t\t});\n\t\t}\n\n\t\tprivate byte[] Issue1314()\n\t\t{\n\t\t\treturn new byte[4] { 0, 1, 2, 255 };\n\t\t}\n\n\t\tprivate void Issue1251_Test(List<Item> list, OtherItem otherItem)\n\t\t{\n\t\t\tlist.Add(new Item {\n\t\t\t\tText = \"Text\",\n\t\t\t\tValue = otherItem.Value,\n\t\t\t\tValue2 = otherItem.Value2,\n\t\t\t\tValue3 = otherItem.Nullable.ToString(),\n\t\t\t\tValue4 = otherItem.Nullable2.ToString(),\n\t\t\t\tValue5 = otherItem.Nullable3.ToString(),\n\t\t\t\tValue6 = otherItem.Nullable4.ToString()\n\t\t\t});\n\t\t}\n\n\t\tprivate Data Issue1279(int p)\n\t\t{\n\t\t\tif (p == 1)\n\t\t\t{\n\t\t\t\tData data = new Data();\n\t\t\t\tdata.a = MyEnum.a;\n\t\t\t\tdata.TestEvent += Data_TestEvent;\n\t\t\t\treturn data;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n#if CS90\n\t\tprivate Fields RecordWithNestedClass(Fields input)\n\t\t{\n\t\t\treturn input with {\n\t\t\t\tA = 42,\n\t\t\t\tI = new Item {\n\t\t\t\t\tValue7 = input with {\n\t\t\t\t\t\tA = 43\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\tpublic DerivedFields DerivedRecordTest(DerivedFields input)\n\t\t{\n\t\t\treturn input with {\n\t\t\t\tA = 42,\n\t\t\t\tD = 43,\n\t\t\t\tI = new Item {\n\t\t\t\t\tValue7 = input with {\n\t\t\t\t\t\tA = 44,\n\t\t\t\t\t\tD = 45\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n#endif\n\n\t\tprivate TData GenericObjectInitializer<TData>() where TData : IData, new()\n\t\t{\n\t\t\treturn new TData {\n\t\t\t\tProperty = 42\n\t\t\t};\n\t\t}\n\t\t#endregion\n\n\t\t#region Collection initializer\n\n\t\tpublic static void ExtensionMethodInCollectionInitializer()\n\t\t{\n#if CS60\n\t\t\tX(Y(), new CustomList<int> { { \"1\", \"2\" } });\n#else\n\t\t\tCustomList<int> customList = new CustomList<int>();\n\t\t\tcustomList.Add(\"1\", \"2\");\n\t\t\tX(Y(), customList);\n#endif\n\t\t}\n\n\t\tpublic static void NoCollectionInitializerBecauseOfTypeArguments()\n\t\t{\n\t\t\tCustomList<int> customList = new CustomList<int>();\n\t\t\tcustomList.Add<int>(\"int\");\n\t\t\tConsole.WriteLine(customList);\n\t\t}\n\n\t\tpublic static TestCases NoCollectionInitializerBecauseOfMissingIEnumerable()\n\t\t{\n\t\t\tTestCases testCases = new TestCases();\n\t\t\ttestCases.Add(\"int\");\n\t\t\ttestCases.Add(\"string\");\n\t\t\treturn testCases;\n\t\t}\n\n\t\tpublic static void CollectionInitializerWithParamsMethod()\n\t\t{\n\t\t\tX(Y(), new CustomList<int> { { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } });\n\t\t}\n\n\t\tpublic static void CollectionInitializerList()\n\t\t{\n\t\t\tX(Y(), new List<int> { 1, 2, 3 });\n\t\t}\n\n\t\tpublic static object RecursiveCollectionInitializer()\n\t\t{\n\t\t\tList<object> list = new List<object>();\n\t\t\tlist.Add(list);\n\t\t\treturn list;\n\t\t}\n\n\t\tpublic static void CollectionInitializerDictionary()\n\t\t{\n\t\t\tX(Y(), new Dictionary<string, int> {\n\t\t\t\t{ \"First\", 1 },\n\t\t\t\t{ \"Second\", 2 },\n\t\t\t\t{ \"Third\", 3 }\n\t\t  });\n\t\t}\n\n\t\tpublic static void CollectionInitializerDictionaryWithEnumTypes()\n\t\t{\n\t\t\tX(Y(), new Dictionary<MyEnum, MyEnum2> {\n\t\t\t{\n\t\t\t\tMyEnum.a,\n\t\t\t\tMyEnum2.c\n\t\t\t},\n\t\t\t{\n\t\t\t\tMyEnum.b,\n\t\t\t\tMyEnum2.d\n\t\t\t}\n\t\t  });\n\t\t}\n\n\t\tpublic static void NotACollectionInitializer()\n\t\t{\n\t\t\tList<int> list = new List<int>();\n\t\t\tlist.Add(1);\n\t\t\tlist.Add(2);\n\t\t\tlist.Add(3);\n\t\t\tX(Y(), list);\n\t\t}\n\n#if CS60\n\t\tpublic static void SimpleDictInitializer()\n\t\t{\n\t\t\tX(Y(), new Data {\n\t\t\t\tMoreData = {\n\t\t\t\t\ta = MyEnum.a,\n\t\t\t\t\t[2] = null\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic static void MixedObjectAndDictInitializer()\n\t\t{\n\t\t\tX(Y(), new Data {\n\t\t\t\tMoreData = {\n\t\t\t\t\ta = MyEnum.a,\n\t\t\t\t\t[GetInt()] = {\n\t\t\t\t\t\ta = MyEnum.b,\n\t\t\t\t\t\tFieldList = { MyEnum2.c },\n\t\t\t\t\t\t[GetInt(), GetString()] = new Data(),\n\t\t\t\t\t\t[2] = null\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tprivate List<List<int>> NestedListWithIndexInitializer(MyEnum myEnum)\n\t\t{\n\t\t\treturn new List<List<int>> {\n\t\t\t\t[0] = { 1, 2, 3 },\n\t\t\t\t[1] = { (int)myEnum }\n\t\t\t};\n\t\t}\n\n\t\tprivate void Issue1250_Test2(MyEnum value)\n\t\t{\n\t\t\tX(Y(), new C { [(int)value] = new S((int)value) });\n\t\t}\n\n\t\tprivate void Issue1250_Test3(int value)\n\t\t{\n\t\t\tX(Y(), new C { [value] = new S(value) });\n\t\t}\n\n\t\tprivate void Issue1250_Test4(int value)\n\t\t{\n\t\t\tX(Y(), new C { [(object)value] = new S(value) });\n\t\t}\n\n\t\tpublic static List<KeyValuePair<string, string>> Issue1390(IEnumerable<string> tokens, bool alwaysAllowAdministrators, char wireDelimiter)\n\t\t{\n\t\t\treturn new List<KeyValuePair<string, string>> {\n\t\t\t{\n\t\t\t\t\"tokens\",\n\t\t\t\t\tstring.Join(wireDelimiter.ToString(), tokens),\n\t\t\t\t\t(Func<string, string>)null\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"alwaysAllowAdministrators\",\n\t\t\t\t\talwaysAllowAdministrators.ToString(),\n\t\t\t\t\t(Func<string, string>)null\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"delimiter\",\n\t\t\t\t\twireDelimiter.ToString(),\n\t\t\t\t\t(Func<string, string>)null\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n#endif\n\t\t#endregion\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/InlineArrayTests.cs",
    "content": "using System;\nusing System.Runtime.CompilerServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class InlineArrayTests\n\t{\n\t\t[InlineArray(16)]\n\t\tpublic struct Byte16\n\t\t{\n\t\t\tprivate byte elem;\n\t\t}\n\n\t\t[InlineArray(16)]\n\t\tpublic struct Generic16<T>\n\t\t{\n\t\t\tprivate T elem;\n\t\t}\n\n\t\tpublic byte Byte0()\n\t\t{\n\t\t\treturn GetByte16()[0];\n\t\t}\n\n\t\tpublic byte GenericByte0()\n\t\t{\n\t\t\treturn GetGeneric<byte>()[0];\n\t\t}\n\n\t\tpublic byte Byte5()\n\t\t{\n\t\t\treturn GetByte16()[5];\n\t\t}\n\n\t\tpublic byte GenericByte5()\n\t\t{\n\t\t\treturn GetGeneric<byte>()[5];\n\t\t}\n\n\t\tpublic byte ByteN()\n\t\t{\n\t\t\treturn GetByte16()[GetIndex()];\n\t\t}\n\n\t\tpublic byte GenericByteN()\n\t\t{\n\t\t\treturn GetGeneric<byte>()[GetIndex()];\n\t\t}\n\n\t\tpublic byte Byte0(Byte16 array, byte value)\n\t\t{\n\t\t\treturn array[0] = value;\n\t\t}\n\n\t\tpublic byte GenericByte0(Generic16<byte> array, byte value)\n\t\t{\n\t\t\treturn array[0] = value;\n\t\t}\n\n\t\tpublic byte Byte5(Byte16 array, byte value)\n\t\t{\n\t\t\treturn array[5] = value;\n\t\t}\n\n\t\tpublic byte GenericByte5(Generic16<byte> array, byte value)\n\t\t{\n\t\t\treturn array[5] = value;\n\t\t}\n\n\t\tpublic byte ByteN(Byte16 array, byte value)\n\t\t{\n\t\t\treturn array[GetIndex()] = value;\n\t\t}\n\n\t\tpublic byte GenericByteN(Generic16<byte> array, byte value)\n\t\t{\n\t\t\treturn array[GetIndex()] = value;\n\t\t}\n\n\t\tpublic void Slice(Byte16 array)\n\t\t{\n\t\t\tReceiver(array[..8]);\n\t\t\tReceiver((ReadOnlySpan<byte>)array[..8]);\n\t\t\tReceiverSpan(array[..8]);\n\t\t\tReceiverReadOnlySpan(array[..8]);\n\t\t}\n\n\t\t// TODO\n\t\t//public void Slice(Byte16 array, int end)\n\t\t//{\n\t\t//\tReceiver(array[..end]);\n\t\t//\tReceiver((ReadOnlySpan<byte>)array[..end]);\n\t\t//\tReceiverSpan(array[..end]);\n\t\t//\tReceiverReadOnlySpan(array[..end]);\n\t\t//}\n\n\t\tpublic byte VariableSplitting(Byte16 array, byte value)\n\t\t{\n\t\t\treturn array[GetIndex()] = (array[GetIndex() + 1] = value);\n\t\t}\n\n\t\tpublic void OverloadResolution()\n\t\t{\n\t\t\tReceiver(GetByte16());\n\t\t\tReceiver((object)GetByte16());\n\t\t\tByte16 buffer = GetByte16();\n\t\t\tReceiver((Span<byte>)buffer);\n\t\t\tByte16 buffer2 = GetByte16();\n\t\t\tReceiver((ReadOnlySpan<byte>)buffer2);\n\t\t\tByte16 buffer3 = GetByte16();\n\t\t\tReceiverSpan(buffer3);\n\t\t\tByte16 buffer4 = GetByte16();\n\t\t\tReceiverReadOnlySpan(buffer4);\n\t\t}\n\n\t\tpublic Byte16 GetByte16()\n\t\t{\n\t\t\treturn default(Byte16);\n\t\t}\n\n\t\tpublic Generic16<T> GetGeneric<T>()\n\t\t{\n\t\t\treturn default(Generic16<T>);\n\t\t}\n\n\t\tpublic int GetIndex()\n\t\t{\n\t\t\treturn 0;\n\t\t}\n\n\t\tpublic void Receiver(Span<byte> span)\n\t\t{\n\t\t}\n\n\t\tpublic void Receiver(ReadOnlySpan<byte> span)\n\t\t{\n\t\t}\n\n\t\tpublic void Receiver(Byte16 span)\n\t\t{\n\t\t}\n\n\t\tpublic void Receiver(object span)\n\t\t{\n\t\t}\n\n\t\tpublic void ReceiverSpan(Span<byte> span)\n\t\t{\n\t\t}\n\n\t\tpublic void ReceiverReadOnlySpan(ReadOnlySpan<byte> span)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/InlineAssignmentTest.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class InlineAssignmentTest\n\t{\n\t\tprivate int field1;\n\t\tprivate static InlineAssignmentTest field2;\n\t\tprivate int[] field3;\n\t\tprivate short field4;\n\n\t\tpublic int InstanceProperty { get; set; }\n\n\t\tpublic static int StaticProperty { get; set; }\n\n\t\tpublic bool BoolProperty { get; set; }\n\n\t\tpublic void SimpleInlineWithLocals()\n\t\t{\n\t\t\tint index;\n\t\t\tConsole.WriteLine(GetFormat(), index = GetIndex());\n\t\t\tConsole.WriteLine(index);\n\t\t\tInlineAssignmentTest value;\n\t\t\tConsole.WriteLine(GetFormat(), value = new InlineAssignmentTest());\n\t\t\tConsole.WriteLine(value);\n\t\t}\n\n\t\tpublic void SimpleInlineWithFields()\n\t\t{\n\t\t\tConsole.WriteLine(field1 = 5);\n\t\t\tConsole.WriteLine(field2 = new InlineAssignmentTest());\n\t\t}\n\n\t\tpublic void SimpleInlineWithFields2()\n\t\t{\n\t\t\tConsole.WriteLine(field1 = 5);\n\t\t\tConsole.WriteLine(field1);\n\t\t\tConsole.WriteLine(field2 = new InlineAssignmentTest());\n\t\t\tConsole.WriteLine(field2);\n\t\t\tUseShort(field4 = 6);\n\t\t\tUseShort(field4 = -10000);\n\t\t\tUseShort(field4 = (short)field1);\n\t\t\tUseShort(field4 = UseShort(0));\n\t\t\tConsole.WriteLine(field4);\n\t\t}\n\n\t\tpublic short UseShort(short s)\n\t\t{\n\t\t\tConsole.WriteLine(s);\n\t\t\treturn s;\n\t\t}\n\n\t\tpublic void ReadLoop1(TextReader r)\n\t\t{\n\t\t\tstring value;\n\t\t\twhile ((value = r.ReadLine()) != null)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(value);\n\t\t\t}\n\t\t}\n\n\t\tpublic void AccessArray(int[] a)\n\t\t{\n\t\t\tint num;\n\t\t\tConsole.WriteLine(num = a[0]);\n\t\t\tConsole.WriteLine(a[num] = num);\n\t\t}\n\n\t\tpublic int Return(ref int a)\n\t\t{\n\t\t\treturn a = 3;\n\t\t}\n\n\t\tpublic int Array(int[] a, int i)\n\t\t{\n\t\t\treturn a[i] = i;\n\t\t}\n\n\t\tpublic int Array2(int i)\n\t\t{\n\t\t\treturn field3[i] = 1;\n\t\t}\n\n\t\tpublic int GetIndex()\n\t\t{\n\t\t\treturn new Random().Next(0, 100);\n\t\t}\n\n\t\tpublic int[] GetArray()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tpublic string GetFormat()\n\t\t{\n\t\t\treturn \"{0}\";\n\t\t}\n\n\t\tpublic int GetValue(int value)\n\t\t{\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic int ArrayUsageWithMethods()\n\t\t{\n\t\t\treturn GetArray()[GetIndex()] = GetValue(GetIndex());\n\t\t}\n\n\t\tpublic int StaticPropertyTest()\n\t\t{\n\t\t\treturn StaticProperty = GetIndex();\n\t\t}\n\n\t\tpublic int InstancePropertyTest()\n\t\t{\n\t\t\treturn InstanceProperty = GetIndex();\n\t\t}\n\n\t\tpublic bool BoolPropertyTest(object x)\n\t\t{\n\t\t\treturn BoolProperty = x != null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/InterfaceTests.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class InterfaceTests\n\t{\n\t\tpublic interface IA\n\t\t{\n#if CS80 && !NET40\n\t\t\tstatic int Field;\n#endif\n\t\t\tint Property1 { get; }\n\t\t\tint Property2 { set; }\n\t\t\tint Property3 { get; set; }\n\n\t\t\tevent EventHandler MyEvent;\n\t\t\tvoid Method();\n\n#if CS80 && !NET40\n\t\t\tstatic IA()\n\t\t\t{\n\n\t\t\t}\n\n\t\t\tvoid DefaultMethod()\n\t\t\t{\n\t\t\t\tMethod();\n\t\t\t\tPrivateMethod();\n\t\t\t}\n\n\t\t\tprivate void PrivateMethod()\n\t\t\t{\n\t\t\t\tMethod();\n\t\t\t}\n\n\t\t\tinternal void InternalMethod()\n\t\t\t{\n\t\t\t\tMethod();\n\t\t\t}\n\n\t\t\tsealed void SealedMethod()\n\t\t\t{\n\t\t\t\tMethod();\n\t\t\t}\n\n\t\t\tstatic void StaticMethod()\n\t\t\t{\n\n\t\t\t}\n#endif\n\t\t}\n\t\tpublic interface IA2 : IA\n\t\t{\n#if CS80 && !NET40\n\t\t\tint IA.Property3 {\n\t\t\t\tget {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tevent EventHandler IA.MyEvent {\n\t\t\t\tadd {\n\t\t\t\t}\n\t\t\t\tremove {\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tnew event EventHandler MyEvent {\n\t\t\t\tadd {\n\t\t\t\t}\n\t\t\t\tremove {\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid IA.InternalMethod()\n\t\t\t{\n\t\t\t}\n\n\t\t\tnew void Method()\n\t\t\t{\n\t\t\t}\n#endif\n\t\t}\n\t\tpublic interface IB\n\t\t{\n\t\t}\n\t\tpublic class C : IA2, IA, IB\n\t\t{\n\t\t\tint IA.Property1 {\n\t\t\t\tget {\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t}\n\t\t\t}\n\t\t\tint IA.Property2 {\n\t\t\t\tset {\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t}\n\t\t\t}\n\t\t\tint IA.Property3 {\n\t\t\t\tget {\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tevent EventHandler IA.MyEvent {\n\t\t\t\tadd {\n\t\t\t\t}\n\t\t\t\tremove {\n\t\t\t\t}\n\t\t\t}\n\t\t\tpublic int Finalize()\n\t\t\t{\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tvoid IA.Method()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n\n\t\tinternal interface IInterfacesCannotDeclareDtors\n\t\t{\n\t\t\tint Finalize();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue1080.cs",
    "content": "using ICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue1080.SpaceA;\nusing ICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue1080.SpaceA.SpaceB;\nusing ICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue1080.SpaceC;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue1080\n{\n\tinternal static class ExtensionsTest\n\t{\n\t\tprivate static void Dummy(ICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue1080.SpaceA.SpaceB.Type2 intf)\n\t\t{\n\t\t}\n\n\t\tprivate static void Test(object obj)\n\t\t{\n\t\t\tICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue1080.SpaceA.Type2 type = obj as ICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue1080.SpaceA.Type2;\n\t\t\tif (type != null)\n\t\t\t{\n\t\t\t\tICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue1080.SpaceC.Extensions.Extension(type);\n\t\t\t}\n\t\t}\n\t}\n}\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue1080.SpaceA\n{\n\tinternal interface Type2 : ICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue1080.SpaceA.SpaceB.Type2, Type1\n\t{\n\t}\n}\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue1080.SpaceA.SpaceB\n{\n\tinternal static class Extensions\n\t{\n\t\tpublic static void Extension(this Type1 obj)\n\t\t{\n\t\t}\n\t}\n\tinternal interface Type1\n\t{\n\t}\n\tinternal interface Type2 : Type1\n\t{\n\t}\n}\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue1080.SpaceC\n{\n\tinternal static class Extensions\n\t{\n\t\tpublic static void Extension(this Type1 obj)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3406.cs",
    "content": "internal class Issue3406\n{\n\tprivate record struct S1(int Value);\n\n\tprivate record struct S2\n\t{\n\t\tpublic int Value;\n\n\t\tpublic S2(int value)\n\t\t{\n\t\t\tValue = value;\n\t\t}\n\n\t\tpublic S2(int a, int b)\n\t\t{\n\t\t\tValue = a + b;\n\t\t}\n\t}\n\n\tprivate record struct S3\n\t{\n\t\tpublic int Value;\n\n\t\tpublic S3(int value)\n\t\t{\n\t\t\tValue = value;\n\t\t}\n\t}\n\n\t// This also generates a hidden backing field\n\tprivate record struct S4(int value)\n\t{\n\t\tpublic int Value = value;\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3439.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\ninternal class VariableScopeTest\n{\n\tprivate class Item\n\t{\n\t\tpublic long Key;\n\n\t\tpublic string Value;\n\t}\n\n\tprivate void Test(List<string> list1)\n\t{\n\t\tAddAction(delegate (List<Item> list2) {\n\t\t\tlong num2 = 1L;\n\t\t\tforeach (string item in list1)\n\t\t\t{\n\t\t\t\tlist2.Add(new Item {\n\t\t\t\t\tKey = num2,\n\t\t\t\t\tValue = item\n\t\t\t\t});\n\t\t\t\tnum2++;\n\t\t\t}\n\t\t});\n\t\tint num = 1;\n\t\tforeach (string item2 in list1)\n\t\t{\n\t\t\tint preservedName = num;\n\t\t\tnum++;\n\t\t\tAddAction(item2, delegate (object x) {\n\t\t\t\tSetValue(x, preservedName);\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate static void AddAction(Action<List<Item>> action)\n\t{\n\t}\n\n\tprivate static void AddAction(string name, Action<object> action)\n\t{\n\t}\n\n\tprivate static void SetValue(object obj, int value)\n\t{\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3442.cs",
    "content": "namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue3442\n{\n\tpublic class Class : Interface\n\t{\n\t\tvoid Interface.M<T>()\n\t\t{\n\t\t}\n\t}\n\tpublic interface Interface\n\t{\n\t\tvoid M<T>() where T : Interface;\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3452.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class Issue3452\n\t{\n\t\tprivate struct Data\n\t\t{\n\t\t\tpublic object Obj;\n\t\t}\n\n\t\tprivate class C1(object obj)\n\t\t{\n\t\t\tinternal Data d = new Data {\n\t\t\t\tObj = obj\n\t\t\t};\n\t\t}\n\n\t\tprivate class C2(object obj)\n\t\t{\n\t\t\tpublic object Obj => obj;\n\t\t}\n\n\t\tprivate class C3(StringComparison comparison)\n\t\t{\n\t\t\tprivate StringComparison _comparison = comparison;\n\n\t\t\tinternal StringComparison Test()\n\t\t\t{\n\t\t\t\treturn _comparison;\n\t\t\t}\n\t\t}\n\n\t\tprivate struct S1(object obj)\n\t\t{\n\t\t\tinternal Data d = new Data {\n\t\t\t\tObj = obj\n\t\t\t};\n\t\t}\n\n\t\tprivate struct S2(object obj)\n\t\t{\n\t\t\tpublic object Obj => obj;\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3483.cs",
    "content": "namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal static class Issue3483\n\t{\n\t\tpublic static int Add_Checked(int x, int y)\n\t\t{\n\t\t\treturn x + y;\n\t\t}\n\t\tpublic static int Add_Unchecked(int x, int y)\n\t\t{\n\t\t\treturn unchecked(x + y);\n\t\t}\n\t\tpublic static int Add_CheckedAndUnchecked_1(int x, int y, int z)\n\t\t{\n\t\t\treturn x + unchecked(y + z);\n\t\t}\n\t\tpublic static int Add_CheckedAndUnchecked_2(int x, int y, int z)\n\t\t{\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\treturn x + checked(y + z);\n\t\t\t}\n\t\t}\n\t\tpublic static uint Cast_Checked(int x)\n\t\t{\n\t\t\treturn (uint)x;\n\t\t}\n\t\tpublic static uint Cast_Unchecked(int x)\n\t\t{\n\t\t\treturn unchecked((uint)x);\n\t\t}\n\t\tpublic static int Cast_CheckedAndUnchecked_1(int x)\n\t\t{\n\t\t\treturn (int)unchecked((uint)x);\n\t\t}\n\t\tpublic static int Cast_CheckedAndUnchecked_2(int x)\n\t\t{\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\treturn (int)checked((uint)x);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3541.cs",
    "content": "namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class Issue3541\n\t{\n\t\tprivate void Test(string format)\n\t\t{\n\t\t\tTestLocal();\n\n\t\t\tvoid TestLocal(int a = 0)\n\t\t\t{\n\t\t\t\ta.ToString(format);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3571_A.cs",
    "content": "using System;\nusing System.Runtime.InteropServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal static class Issue3571_A\n\t{\n\t\t[StructLayout(LayoutKind.Sequential, Size = 1)]\n\t\tpublic readonly struct fsResult\n\t\t{\n\t\t\tpublic static fsResult Success => default(fsResult);\n\t\t\tpublic static fsResult Failure => default(fsResult);\n\t\t\tpublic bool Succeeded => true;\n\t\t\tpublic bool Failed => false;\n\t\t\tpublic static fsResult operator +(fsResult a, fsResult b)\n\t\t\t{\n\t\t\t\treturn default(fsResult);\n\t\t\t}\n\t\t}\n\n\t\tpublic static fsResult M()\n\t\t{\n\t\t\tfsResult success = fsResult.Success;\n\t\t\tfsResult fsResult2 = success + fsResult.Success;\n\t\t\tif (fsResult2.Succeeded)\n\t\t\t{\n\t\t\t\treturn success;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"Failed\");\n\t\t\treturn fsResult2 + fsResult.Failure;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3571_B.cs",
    "content": "using System;\nusing System.Runtime.InteropServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue3571_B\n{\n\t[StructLayout(LayoutKind.Sequential, Size = 1)]\n\tpublic readonly struct fsResult\n\t{\n\t\tpublic static fsResult Success => default(fsResult);\n\t\tpublic static fsResult Failure => default(fsResult);\n\t\tpublic bool Succeeded => true;\n\t\tpublic bool Failed => false;\n\t\tpublic static fsResult operator +(fsResult a, fsResult b)\n\t\t{\n\t\t\treturn default(fsResult);\n\t\t}\n\t}\n\n\tinternal static class Issue3571_B\n\t{\n\t\tpublic static fsResult M()\n\t\t{\n\t\t\tfsResult success = fsResult.Success;\n\t\t\tfsResult fsResult2 = success + fsResult.Success;\n\t\t\tif (fsResult2.Succeeded)\n\t\t\t{\n\t\t\t\treturn success;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"Failed\");\n\t\t\treturn fsResult2 + fsResult.Failure;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3571_C.cs",
    "content": "using System;\nusing System.Runtime.InteropServices;\n\nusing ICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue3571_Helper;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal static class Issue3571_C\n\t{\n\t\tpublic static fsResult M()\n\t\t{\n\t\t\tfsResult success = fsResult.Success;\n\t\t\tfsResult fsResult2 = success + fsResult.Success;\n\t\t\tif (fsResult2.Succeeded)\n\t\t\t{\n\t\t\t\treturn success;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"Failed\");\n\t\t\treturn fsResult2 + fsResult.Failure;\n\t\t}\n\t}\n}\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue3571_Helper\n{\n\t[StructLayout(LayoutKind.Sequential, Size = 1)]\n\tpublic readonly struct fsResult\n\t{\n\t\tpublic static fsResult Success => default(fsResult);\n\t\tpublic static fsResult Failure => default(fsResult);\n\t\tpublic bool Succeeded => true;\n\t\tpublic bool Failed => false;\n\t\tpublic static fsResult operator +(fsResult a, fsResult b)\n\t\t{\n\t\t\treturn default(fsResult);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3576.cs",
    "content": "using System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal static class Issue3576\n\t{\n\t\tpublic static Issue3576_Camera GetOrCreate(long key, int frameCount, Dictionary<long, (Issue3576_Camera, int)> cache)\n\t\t{\n\t\t\tif (!cache.TryGetValue(key, out var value))\n\t\t\t{\n\t\t\t\tIssue3576_GameObject issue3576_GameObject = new Issue3576_GameObject();\n\t\t\t\tvalue = (issue3576_GameObject.AddComponent<Issue3576_Camera>(), frameCount);\n\t\t\t\tvalue.Item1.Property = 1;\n\t\t\t\tissue3576_GameObject.SetActive(value: false);\n\t\t\t\tcache[key] = value;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvalue.Item2 = frameCount;\n\t\t\t\tcache[key] = value;\n\t\t\t}\n\t\t\treturn value.Item1;\n\t\t}\n\t}\n\tinternal sealed class Issue3576_Camera\n\t{\n\t\tpublic int Property { get; set; }\n\t}\n\tinternal sealed class Issue3576_GameObject\n\t{\n\t\tpublic T AddComponent<T>()\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic void SetActive(bool value)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3584.cs",
    "content": "using System.Collections;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal abstract class Issue4000<T> : IEnumerable<T>, IEnumerable\n\t{\n\t\tpublic int Length;\n\n\t\tprotected T[] results;\n\n#if !ROSLYN4\n\t\tpublic T this[int i] {\n\t\t\tget {\n\t\t\t\tif (i >= Length || i < 0)\n\t\t\t\t{\n\t\t\t\t\treturn default(T);\n\t\t\t\t}\n\t\t\t\tif (results[i] != null && results[i].Equals(default(T)))\n\t\t\t\t{\n\t\t\t\t\tresults[i] = CreateIthElement(i);\n\t\t\t\t}\n\t\t\t\treturn results[i];\n\t\t\t}\n\t\t}\n#endif\n\n\t\tprotected abstract T CreateIthElement(int i);\n\n\t\tpublic IEnumerator<T> GetEnumerator()\n\t\t{\n\t\t\tfor (int i = 0; i < Length; i++)\n\t\t\t{\n\t\t\t\tif (results[i] != null && results[i].Equals(default(T)))\n\t\t\t\t{\n\t\t\t\t\tresults[i] = CreateIthElement(i);\n\t\t\t\t}\n\t\t\t\tyield return results[i];\n\t\t\t}\n\t\t}\n\n\t\tIEnumerator IEnumerable.GetEnumerator()\n\t\t{\n\t\t\treturn GetEnumerator();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3598.cs",
    "content": "using System;\nusing System.Diagnostics;\nusing System.Threading;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.Playstation\n{\n#pragma warning disable CS0414, CS9113, CS9124\n\n\tpublic record struct CopilotContextId\n\t{\n\t\tpublic Guid Id { get; }\n\n\t\tpublic CopilotContextId()\n\t\t{\n\t\t\tId = Guid.NewGuid();\n\t\t}\n\n\t\tpublic CopilotContextId(Guid id)\n\t\t{\n\t\t\tId = id;\n\t\t}\n\t}\n\n\tpublic class CopilotContextId_Class(Guid id)\n\t{\n\t\tpublic Guid guid { get; } = id;\n\n\t\tpublic CopilotContextId_Class(Guid id, int value)\n\t\t\t: this(Guid.NewGuid())\n\t\t{\n\n\t\t}\n\t\tpublic CopilotContextId_Class()\n\t\t\t: this(Guid.NewGuid(), 222)\n\t\t{\n\n\t\t}\n\t}\n\n\tpublic record CopilotContextId_RecordClass(Guid id)\n\t{\n\t\tpublic Guid guid { get; } = id;\n\n\t\tpublic CopilotContextId_RecordClass()\n\t\t\t: this(Guid.NewGuid())\n\t\t{\n\n\t\t}\n\t}\n\n\tpublic record struct CopilotContextId_RecordStruct(Guid id)\n\t{\n\t\tpublic Guid guid { get; } = id;\n\n\t\tpublic CopilotContextId_RecordStruct()\n\t\t\t: this(Guid.NewGuid())\n\t\t{\n\n\t\t}\n\t}\n\n\tpublic struct CopilotContextId_Struct\n\t{\n\t\tpublic Guid guid { get; }\n\n\t\tpublic CopilotContextId_Struct(Guid id)\n\t\t{\n\t\t\tguid = id;\n\t\t}\n\n\t\tpublic CopilotContextId_Struct()\n\t\t\t: this(Guid.NewGuid())\n\t\t{\n\n\t\t}\n\t}\n\n\tpublic abstract record CopilotQueriedMention\n\t{\n\t\tpublic abstract ConsoleKey Type { get; }\n\n\t\tpublic string DisplayName { get; init; }\n\n\t\tpublic string FullName { get; init; }\n\n\t\tpublic object ProviderMoniker { get; init; }\n\n\t\tinternal CopilotQueriedMention(object providerMoniker, string fullName, string displayName)\n\t\t{\n\t\t\tProviderMoniker = providerMoniker;\n\t\t\tFullName = fullName;\n\t\t\tDisplayName = displayName;\n\t\t}\n\t}\n\n\tpublic record CopilotQueriedScopeMention : CopilotQueriedMention\n\t{\n\t\tpublic override ConsoleKey Type { get; } = ConsoleKey.Enter;\n\n\t\tpublic CopilotQueriedScopeMention(object providerMoniker, string fullName, string displayName)\n\t\t\t: base(providerMoniker, fullName, displayName)\n\t\t{\n\t\t}\n\t}\n\n\tpublic class DeserializationException(string response, Exception innerException) : Exception(\"Error occured while deserializing the response\", innerException)\n\t{\n\t\tpublic string Response { get; } = response;\n\t}\n\n\tinternal static class Ensure\n\t{\n\t\tpublic static T NotNull<T>(T? value, string name)\n\t\t{\n\t\t\tif (value == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(name);\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic static string NotEmptyString(object? value, string name)\n\t\t{\n#if OPT\n\t\t\tstring obj = (value as string) ?? value?.ToString();\n\t\t\tif (obj == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(name);\n\t\t\t}\n\n\t\t\tif (string.IsNullOrWhiteSpace(obj))\n\t\t\t{\n\t\t\t\tthrow new ArgumentException(\"Parameter cannot be an empty string\", name);\n\t\t\t}\n\t\t\treturn obj;\n#else\n\t\t\tstring text = (value as string) ?? value?.ToString();\n\t\t\tif (text == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(name);\n\t\t\t}\n\n\t\t\tif (string.IsNullOrWhiteSpace(text))\n\t\t\t{\n\t\t\t\tthrow new ArgumentException(\"Parameter cannot be an empty string\", name);\n\t\t\t}\n\t\t\treturn text;\n#endif\n\t\t}\n\t}\n\n\t// always use primary constructor because it is indistinguishable\n\tpublic struct FromBinaryOperator(int dummy1, int dummy2)\n\t{\n\t\tpublic int Leet = dummy1 + dummy2;\n\t}\n\n\tpublic struct FromCall(int dummy1, int dummy2)\n\t{\n\t\tpublic int Leet = Math.Max(dummy1, dummy2);\n\t}\n\n\tpublic struct FromConvert(double dummy1, double dummy2)\n\t{\n\t\tpublic int Leet = (int)Math.Min(dummy1, dummy2);\n\t}\n\n\tpublic record NamedParameter(string name, object? value, bool encode = true) : Parameter(Ensure.NotEmptyString(name, \"name\"), value, encode);\n\n\t[DebuggerDisplay(\"{DebuggerDisplay()}\")]\n\tpublic abstract record Parameter\n\t{\n\t\tpublic string? Name { get; }\n\t\tpublic object? Value { get; }\n\t\tpublic bool Encode { get; }\n\t\tprotected virtual string ValueString => Value?.ToString() ?? \"null\";\n\n\t\tprotected Parameter(string? name, object? value, bool encode)\n\t\t{\n\t\t\tName = name;\n\t\t\tValue = value;\n\t\t\tEncode = encode;\n\t\t}\n\n\t\tpublic sealed override string ToString()\n\t\t{\n#if OPT\n\t\t\tif (Value != null)\n\t\t\t{\n\t\t\t\treturn Name + \"=\" + ValueString;\n\t\t\t}\n\t\t\treturn Name ?? \"\";\n#else\n\t\t\treturn (Value == null) ? (Name ?? \"\") : (Name + \"=\" + ValueString);\n#endif\n\t\t}\n\n\t\tprotected string DebuggerDisplay()\n\t\t{\n\t\t\treturn GetType().Name.Replace(\"Parameter\", \"\") + \" \" + ToString();\n\t\t}\n\t}\n\n\tpublic class Person(string name, int age)\n\t{\n\t\tprivate readonly string _name = name;\n\t\tprivate readonly int _age = age;\n\n\t\tpublic string Email { get; init; }\n\n\t\tpublic Person(string name, int age, string email)\n\t\t\t: this(name, age)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(email))\n\t\t\t{\n\t\t\t\tthrow new ArgumentException(\"Email cannot be empty\");\n\t\t\t}\n\n\t\t\tEmail = email;\n\t\t\tConsole.WriteLine(\"Created person: \" + name);\n\t\t}\n\t}\n\n\tpublic class PersonPrimary(string name, int age)\n\t{\n\t\tprivate readonly string _name = name;\n\t}\n\n\tpublic class PersonPrimary_CaptureParams(string name, int age)\n\t{\n\t\tpublic string GetDetails()\n\t\t{\n\t\t\treturn $\"{name}, {age}\";\n\t\t}\n\t}\n\n\tpublic class PersonRegular1\n\t{\n\t\tprivate readonly string _name = \"name\";\n\t\tprivate readonly int _age = 23;\n\n\t\tpublic PersonRegular1(string name, int age)\n\t\t{\n\t\t\tThread.Sleep(1000);\n\t\t\t_age = name.Length;\n\t\t}\n\t}\n\n\tpublic class PersonRegular2\n\t{\n\t\tprivate readonly string _name = \"name\" + Environment.GetEnvironmentVariable(\"Path\");\n\t\tprivate readonly int _age = Environment.GetEnvironmentVariable(\"Path\")?.Length ?? (-1);\n\n\t\tprivate void Method()\n\t\t{\n\t\t\tConsole.WriteLine(\"Hello\");\n\t\t}\n\n\t\tpublic PersonRegular2(string name, int age)\n\t\t{\n\t\t}\n\t}\n\n\tpublic record QueryParameter(string name, object? value, bool encode = true) : NamedParameter(name, value, encode);\n\n\tinternal ref struct RefFields(ref int v)\n\t{\n\t\tpublic ref int Field0 = ref v;\n\t}\n\n\tinternal struct StructWithDefaultCtor\n\t{\n\t\tprivate int X = 42;\n\n\t\tpublic StructWithDefaultCtor()\n\t\t{\n\t\t}\n\t}\n\n\tinternal struct ValueFields(int v)\n\t{\n\t\tpublic int Field0 = v;\n\t}\n\n\tinternal class WebPair1(string name)\n\t{\n\t\tpublic string Name { get; } = name;\n\t}\n\n\tinternal class WebPair1Primary\n\t{\n\t\tpublic string Name { get; }\n\n\t\tpublic WebPair1Primary(string name)\n\t\t{\n\t\t\tName = name;\n\t\t}\n\t}\n\n\tinternal class WebPair2\n\t{\n\t\tpublic string Name { get; }\n\n\t\tpublic WebPair2(string name, string? value, ref readonly object encode)\n\t\t{\n\t\t\tName = name;\n\t\t}\n\t}\n\n\tinternal class WebPair2Primary(string name, string? value, ref readonly object encode)\n\t{\n\t\tpublic string Name { get; } = name;\n\t}\n\n\tinternal class WebPair3\n\t{\n\t\tpublic string Name { get; }\n\t\tpublic string? Value { get; }\n\t\tprivate string? WebValue { get; }\n\n\t\tpublic WebPair3(string name, string? value, bool encode = false)\n\t\t{\n\t\t\tName = name;\n\t\t\tValue = value;\n\t\t\tWebValue = (encode ? \"111\" : value);\n\t\t}\n\t}\n\n\tinternal class WebPair3Primary(string name, string? value, bool encode = false)\n\t{\n\t\tpublic string Name { get; } = name;\n\t\tpublic string? Value { get; } = value;\n\t\tprivate string? WebValue { get; } = encode ? \"111\" : value;\n\t}\n\n\tinternal class WebPair4\n\t{\n\t\tpublic string Name { get; }\n\t\tpublic string? Value { get; }\n\t\tprivate string? WebValue { get; }\n\t\tprivate string? WebValue2 { get; }\n\n\t\tpublic WebPair4(string name, string? value, ref readonly object encode)\n\t\t{\n\t\t\tName = name;\n\t\t\tValue = value;\n\t\t\tWebValue = ((encode == null) ? \"111\" : value);\n\t\t\tWebValue2 = encode.ToString();\n\t\t}\n\t}\n\n\tinternal class WebPair4Primary(string name, string? value, ref readonly object encode)\n\t{\n\t\tpublic string Name { get; } = name;\n\t\tpublic string? Value { get; } = value;\n\t\tprivate string? WebValue { get; } = (encode == null) ? \"111\" : value;\n\t\tprivate string? WebValue2 { get; } = encode.ToString();\n\t}\n\n\tinternal class WebPair5\n\t{\n\t\tpublic string Name { get; }\n\n\t\tpublic WebPair5(string name, string? value)\n\t\t{\n\t\t\tName = name;\n\t\t}\n\t}\n\n\tinternal class WebPair5Primary(string name, string? value)\n\t{\n\t\tpublic string Name { get; } = name;\n\t}\n\n\tinternal class WebPair6\n\t{\n\t\tpublic string? Value { get; }\n\t\tpublic string Name { get; }\n\t\tprivate string? WebValue { get; }\n\t\tprivate string? WebValue2 { get; }\n\n\t\tpublic WebPair6(string name, string? value, ref readonly object encode)\n\t\t{\n\t\t\tValue = name;\n\t\t\tName = value;\n\t\t\tWebValue = ((name != null) ? \"111\" : value);\n\t\t\tWebValue2 = ((value != null) ? name : \"222\");\n\t\t}\n\t}\n\n\tinternal class WebPair6Primary(string name, string? value, ref readonly object encode)\n\t{\n\t\tpublic string? Value { get; } = name;\n\t\tpublic string Name { get; } = value;\n\t\tprivate string? WebValue { get; } = (name != null) ? \"111\" : value;\n\t\tprivate string? WebValue2 { get; } = (value != null) ? name : \"222\";\n\t}\n\n}\n\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3610.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class Issue3610\n\t{\n\t\tprivate struct CtorDoubleAssignmentTest\n\t\t{\n\t\t\tpublic bool Value;\n\n\t\t\tpublic CtorDoubleAssignmentTest(string arg1, int arg2)\n\t\t\t{\n\t\t\t\tValue = false;\n\t\t\t\tValue = true;\n\t\t\t}\n\t\t}\n\n\t\tprivate struct CtorDoubleAssignmentTest2\n\t\t{\n\t\t\tpublic bool Value;\n\n\t\t\tpublic CtorDoubleAssignmentTest2(string arg1, int arg2)\n\t\t\t{\n\t\t\t\tValue = true;\n\t\t\t\tValue = false;\n\t\t\t}\n\t\t}\n\n\t\tprivate class FieldInitTest\n\t\t{\n\t\t\tpublic bool Flag = true;\n\t\t\tpublic Func<int, int> Action = (int a) => a;\n\t\t\tpublic string Value;\n\n\t\t\tpublic FieldInitTest(string value)\n\t\t\t{\n\t\t\t\tValue = value;\n\t\t\t}\n\t\t}\n\n\t\tprivate abstract class PCFieldInitTest(StringComparison value)\n\t\t{\n\t\t\tprivate StringComparison _value = value;\n\n\t\t\tpublic bool Func()\n\t\t\t{\n\t\t\t\treturn _value == StringComparison.Ordinal;\n\t\t\t}\n\t\t}\n\n\t\tprivate class RecordTest<T>\n\t\t{\n\t\t\tprivate interface IInterface\n\t\t\t{\n\t\t\t\tT[] Objects { get; }\n\t\t\t}\n\n\t\t\tprotected record Record(T[] Objects) : IInterface\n\t\t\t{\n\t\t\t\tpublic Record(List<T> objects)\n\t\t\t\t\t: this(objects.ToArray())\n\t\t\t\t{\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate abstract record RecordTest2(Guid[] Guids);\n\t}\n\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3611.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class Issue3611\n\t{\n\t\tprivate class C4(string value)\n\t\t{\n\t\t\tpublic object Obj { get; } = new object();\n\t\t\tpublic string Value { get; } = value;\n\t\t}\n\n\t\tprivate class C5(C5.ValueArray array)\n\t\t{\n\t\t\tpublic struct ValueArray\n\t\t\t{\n\t\t\t\tprivate bool b;\n\t\t\t\tpublic bool[] ToArray()\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic bool[] Values = array.ToArray();\n\t\t}\n\n\t\tprivate class BaseClass\n\t\t{\n\t\t\tprotected BaseClass(int value)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tprivate class C6(C6.Data2 data) : BaseClass(data.Value)\n\t\t{\n\t\t\tpublic struct Data2\n\t\t\t{\n\t\t\t\tpublic int Value { get; set; }\n\t\t\t}\n\n\t\t\tpublic Data2 Data => data;\n\t\t}\n\n\t\tprivate struct S3<T>(T v)\n\t\t{\n\t\t\tpublic T Value => v;\n\t\t}\n\n\t\tprivate interface I1\n\t\t{\n\t\t\tint Number { get; }\n\t\t}\n\n\t\t// May be the same issue as S3\n\t\tprivate struct S4<T>(int number) : IComparable<T> where T : I1\n\t\t{\n\t\t\tpublic int CompareTo(T other)\n\t\t\t{\n\t\t\t\treturn number.CompareTo(other.Number);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/LiftedOperators.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Runtime.InteropServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic static class T00_LiftedOperators\n\t{\n\t\t// C# uses 4 different patterns of IL for lifted operators: bool, other primitive types, decimal, other structs.\n\t\t// Different patterns are used depending on whether both of the operands are nullable or only the left/right operand is nullable.\n\t\t// Negation must not be pushed through such comparisons because it would change the semantics (except for equality/inequality).\n\t\t// A comparison used in a condition differs somewhat from a comparison used as a simple value.\n\n\t\tpublic static void BoolBasic(bool? a, bool? b)\n\t\t{\n\t\t\tif (a == b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a != b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t}\n\n\t\tpublic static void BoolComplex(bool? a, Func<bool> x)\n\t\t{\n\t\t\tif (a == x())\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a != x())\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\n\t\t\tif (x() == a)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (x() != a)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a ?? x())\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t}\n\n\t\tpublic static void BoolConst(bool? a)\n\t\t{\n\t\t\tif (a == true)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a != true)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a == false)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a != false)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a ?? true)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n#if !ROSLYN\n\t\t\t// Roslyn 3 (VS2019) started optimizing this to \"a.GetValueOrDefault()\"\n\t\t\tif (a ?? false)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n#endif\n\t\t}\n\n\t\tpublic static void BoolValueBasic(bool? a, bool? b)\n\t\t{\n\t\t\tConsole.WriteLine(a == b);\n\t\t\tConsole.WriteLine(a != b);\n\n\t\t\tConsole.WriteLine(a & b);\n\t\t\tConsole.WriteLine(a | b);\n\t\t\tConsole.WriteLine(a ^ b);\n\t\t\tConsole.WriteLine(a ?? b);\n\t\t\tConsole.WriteLine(!a);\n\t\t\ta &= b;\n\t\t\ta |= b;\n\t\t\ta ^= b;\n\t\t}\n\n\t\tpublic static void BoolValueComplex(bool? a, Func<bool> x)\n\t\t{\n\t\t\tConsole.WriteLine(a == x());\n\t\t\tConsole.WriteLine(a != x());\n\n\t\t\tConsole.WriteLine(x() == a);\n\t\t\tConsole.WriteLine(x() != a);\n\n\t\t\t//Console.WriteLine(a & x()); // we currently can't tell the order\n\t\t\t//Console.WriteLine(a | x()); // of the operands in bool [&|] bool?\n\t\t\tConsole.WriteLine(a ^ x());\n\t\t\tConsole.WriteLine(a ?? x());\n\t\t\t//a &= x(); -- also affected by order of operand problem\n\t\t\t//a |= x();\n\t\t\ta ^= x();\n\n\t\t\tConsole.WriteLine(x() & a);\n\t\t\tConsole.WriteLine(x() | a);\n\t\t\tConsole.WriteLine(x() ^ a);\n\t\t\t(new bool?[0])[0] ^= x();\n\t\t\t(new bool?[0])[0] ^= a;\n\t\t}\n\n\t\tpublic static void BoolValueConst(bool? a)\n\t\t{\n\t\t\tConsole.WriteLine(a == true);\n\t\t\tConsole.WriteLine(a != true);\n\t\t\tConsole.WriteLine(a == false);\n\t\t\tConsole.WriteLine(a != false);\n\t\t\tConsole.WriteLine(a ?? true);\n#if !ROSLYN\n\t\t\t// Roslyn 3 (VS2019) started optimizing this to \"a.GetValueOrDefault()\"\n\t\t\tConsole.WriteLine(a ?? false);\n#endif\n\t\t}\n\n\t\tpublic static void IntBasic(int? a, int? b)\n\t\t{\n\t\t\tif (a == b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a != b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a > b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a < b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a >= b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a <= b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\n\t\t\tif (!(a > b))\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (!(a <= b))\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t}\n\n\t\tpublic static void IntComplex(int? a, Func<int> x)\n\t\t{\n\t\t\tif (a == x())\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a != x())\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a > x())\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\n\t\t\tif (x() == a)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (x() != a)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (x() > a)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\n\t\t\tif (!(a > x()))\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (!(a <= x()))\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t}\n\n\t\tpublic static void IntConst(int? a)\n\t\t{\n\t\t\tif (a == 2)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a != 2)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a > 2)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\n\t\t\tif (2 == a)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (2 != a)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (2 > a)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t}\n\n\t\tpublic static void IntValueBasic(int? a, int? b)\n\t\t{\n\t\t\tConsole.WriteLine(a == b);\n\t\t\tConsole.WriteLine(a != b);\n\t\t\tConsole.WriteLine(a > b);\n\n\t\t\tConsole.WriteLine(!(a > b));\n\t\t\tConsole.WriteLine(!(a >= b));\n\n\t\t\tConsole.WriteLine(a + b);\n\t\t\tConsole.WriteLine(a - b);\n\t\t\tConsole.WriteLine(a * b);\n\t\t\tConsole.WriteLine(a / b);\n\t\t\tConsole.WriteLine(a % b);\n\t\t\tConsole.WriteLine(a & b);\n\t\t\tConsole.WriteLine(a | b);\n\t\t\tConsole.WriteLine(a ^ b);\n\t\t\tConsole.WriteLine(a << b);\n\t\t\tConsole.WriteLine(a >> b);\n\t\t\tConsole.WriteLine(a ?? b);\n\t\t\tConsole.WriteLine(-a);\n\t\t\tConsole.WriteLine(~a);\n\t\t\t// TODO:\n\t\t\t//Console.WriteLine(a++);\n\t\t\t//Console.WriteLine(a--);\n\t\t\tConsole.WriteLine(++a);\n\t\t\tConsole.WriteLine(--a);\n\t\t\ta += b;\n\t\t\ta -= b;\n\t\t\ta *= b;\n\t\t\ta /= b;\n\t\t\ta %= b;\n\t\t\ta &= b;\n\t\t\ta |= b;\n\t\t\ta ^= b;\n\t\t\ta <<= b;\n\t\t\ta >>= b;\n\t\t}\n\n\t\tpublic static void IntValueComplex(int? a, Func<int> x)\n\t\t{\n\t\t\tConsole.WriteLine(a == x());\n\t\t\tConsole.WriteLine(a != x());\n\t\t\tConsole.WriteLine(a > x());\n\n\t\t\tConsole.WriteLine(x() == a);\n\t\t\tConsole.WriteLine(x() != a);\n\t\t\tConsole.WriteLine(x() > a);\n\n\t\t\tConsole.WriteLine(a + x());\n\t\t\tConsole.WriteLine(a - x());\n\t\t\tConsole.WriteLine(a * x());\n\t\t\tConsole.WriteLine(a / x());\n\t\t\tConsole.WriteLine(a % x());\n\t\t\tConsole.WriteLine(a & x());\n\t\t\tConsole.WriteLine(a | x());\n\t\t\tConsole.WriteLine(a ^ x());\n\t\t\tConsole.WriteLine(a << x());\n\t\t\tConsole.WriteLine(a >> x());\n\t\t\tConsole.WriteLine(a ?? x());\n\t\t\ta += x();\n\t\t\ta -= x();\n\t\t\ta *= x();\n\t\t\ta /= x();\n\t\t\ta %= x();\n\t\t\ta &= x();\n\t\t\ta |= x();\n\t\t\ta ^= x();\n\t\t\ta <<= x();\n\t\t\ta >>= x();\n\n\t\t\tConsole.WriteLine(x() + a);\n\t\t\t(new int?[0])[0] += x();\n\t\t}\n\n\t\tpublic static void IntValueConst(int? a)\n\t\t{\n\t\t\tConsole.WriteLine(a == 2);\n\t\t\tConsole.WriteLine(a != 2);\n\t\t\tConsole.WriteLine(a > 2);\n\n\t\t\tConsole.WriteLine(2 == a);\n\t\t\tConsole.WriteLine(2 != a);\n\t\t\tConsole.WriteLine(2 > a);\n\n\t\t\tConsole.WriteLine(a + 2);\n\t\t\tConsole.WriteLine(a - 2);\n\t\t\tConsole.WriteLine(a * 2);\n\t\t\tConsole.WriteLine(a / 2);\n\t\t\tConsole.WriteLine(a % 2);\n\t\t\tConsole.WriteLine(a & 2);\n\t\t\tConsole.WriteLine(a | 2);\n\t\t\tConsole.WriteLine(a ^ 2);\n\t\t\tConsole.WriteLine(a << 2);\n\t\t\tConsole.WriteLine(a >> 2);\n\t\t\tConsole.WriteLine(a ?? 2);\n\t\t\ta += 2;\n\t\t\ta -= 2;\n\t\t\ta *= 2;\n\t\t\ta /= 2;\n\t\t\ta %= 2;\n\t\t\ta &= 2;\n\t\t\ta |= 2;\n\t\t\ta ^= 2;\n\t\t\ta <<= 2;\n\t\t\ta >>= 2;\n\n\t\t\tConsole.WriteLine(2 + a);\n\t\t}\n\n\t\tpublic static void NumberBasic(decimal? a, decimal? b)\n\t\t{\n\t\t\tif (a == b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n#if ROSLYN2\n\t\t\t// Roslyn 2.9 started invoking op_Equality even if the source code says 'a != b'\n\t\t\tif (!(a == b))\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n#else\n\t\t\tif (a != b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n#endif\n\t\t\tif (a > b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a < b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a >= b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a <= b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\n\t\t\tif (!(a > b))\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (!(a < b))\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t}\n\n\t\tpublic static void NumberComplex(decimal? a, Func<decimal> x)\n\t\t{\n\t\t\t// Tests deactivated because we insert redundant casts;\n\t\t\t// TODO: revisit after decision has been made regarding the type system.\n\t\t\t//if (a == x()) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\t\t\t//if (a != x()) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\t\t\t//if (a > x()) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\n\t\t\t//if (x() == a) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\t\t\t//if (x() != a) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\t\t\t//if (x() > a) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\t\t}\n\n\t\tpublic static void NumberConst(decimal? a)\n\t\t{\n\t\t\t// Tests deactivated because we insert redundant casts;\n\t\t\t// TODO: revisit after decision has been made regarding the type system.\n\t\t\t//if (a == 2m) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\t\t\t//if (a != 2m) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\t\t\t//if (a > 2m) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\n\t\t\t//if (2m == a) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\t\t\t//if (2m != a) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\t\t\t//if (2m > a) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\t\t}\n\n\t\tpublic static void NumberValueBasic(decimal? a, decimal? b)\n\t\t{\n\t\t\tConsole.WriteLine(a == b);\n#if ROSLYN\n\t\t\t// Roslyn 2.9 started invoking op_Equality even if the source code says 'a != b'\n\t\t\tConsole.WriteLine(!(a == b));\n#else\n\t\t\tConsole.WriteLine(a != b);\n#endif\n\t\t\tConsole.WriteLine(a > b);\n\n\t\t\tConsole.WriteLine(!(a > b));\n\t\t\tConsole.WriteLine(!(a <= b));\n\n\t\t\tConsole.WriteLine(a + b);\n\t\t\tConsole.WriteLine(a - b);\n\t\t\tConsole.WriteLine(a * b);\n\t\t\tConsole.WriteLine(a / b);\n\t\t\tConsole.WriteLine(a % b);\n\t\t\tConsole.WriteLine(a ?? b);\n\t\t\tConsole.WriteLine(-a);\n\t\t\t// TODO:\n\t\t\t//Console.WriteLine(a++);\n\t\t\t//Console.WriteLine(a--);\n\t\t\t//Console.WriteLine(++a);\n\t\t\t//Console.WriteLine(--a);\n\t\t\ta += b;\n\t\t\ta -= b;\n\t\t\ta *= b;\n\t\t\ta /= b;\n\t\t\ta %= b;\n\t\t}\n\n\t\tpublic static void NumberValueComplex(decimal? a, Func<decimal> x)\n\t\t{\n\t\t\t// Tests deactivated because we insert redundant casts;\n\t\t\t// TODO: revisit after decision has been made regarding the type system.\n\t\t\t//Console.WriteLine(a == x());\n\t\t\t//Console.WriteLine(a != x());\n\t\t\t//Console.WriteLine(a > x());\n\n\t\t\t//Console.WriteLine(x() == a);\n\t\t\t//Console.WriteLine(x() != a);\n\t\t\t//Console.WriteLine(x() > a);\n\n\t\t\t//Console.WriteLine(a + x());\n\t\t\t//Console.WriteLine(a - x());\n\t\t\t//Console.WriteLine(a * x());\n\t\t\t//Console.WriteLine(a / x());\n\t\t\t//Console.WriteLine(a % x());\n\t\t\t//Console.WriteLine(a ?? x());\n\t\t\t//a += x();\n\t\t\t//a -= x();\n\t\t\t//a *= x();\n\t\t\t//a /= x();\n\t\t\t//a %= x();\n\n\t\t\t//Console.WriteLine(x() + a);\n\t\t\t//(new decimal?[0])[0] += x();\n\t\t}\n\n\t\tpublic static void NumberValueConst(decimal? a)\n\t\t{\n\t\t\t// Tests deactivated because we insert redundant casts;\n\t\t\t// TODO: revisit after decision has been made regarding the type system.\n\t\t\t//Console.WriteLine(a == 2m);\n\t\t\t//Console.WriteLine(a != 2m);\n\t\t\t//Console.WriteLine(a > 2m);\n\n\t\t\t//Console.WriteLine(2m == a);\n\t\t\t//Console.WriteLine(2m != a);\n\t\t\t//Console.WriteLine(2m > a);\n\n\t\t\t//Console.WriteLine(a + 2m);\n\t\t\t//Console.WriteLine(a - 2m);\n\t\t\t//Console.WriteLine(a * 2m);\n\t\t\t//Console.WriteLine(a / 2m);\n\t\t\t//Console.WriteLine(a % 2m);\n\t\t\t//Console.WriteLine(a ?? 2m);\n\t\t\t//a += 2m;\n\t\t\t//a -= 2m;\n\t\t\t//a *= 2m;\n\t\t\t//a /= 2m;\n\t\t\t//a %= 2m;\n\n\t\t\t//Console.WriteLine(2m + a);\n\t\t}\n\n\t\tpublic static void CompareWithImplictCast(int? a, long? b)\n\t\t{\n\t\t\tif (a < b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a == b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\t// TODO: unnecessary cast\n\t\t\t//if (a < 10L) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\t\t\t//if (a == 10L) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\t\t}\n\n\t\tpublic static void CompareWithSignChange(int? a, int? b)\n\t\t{\n\t\t\tif ((uint?)a < (uint?)b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\t// TODO: unnecessary cast\n\t\t\t//if ((uint?)a < 10) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\t\t}\n\n\t\tpublic static void StructBasic(TS? a, TS? b)\n\t\t{\n\t\t\tif (a == b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a != b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a > b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a < b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a >= b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (a <= b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\n\t\t\tif (!(a == b))\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (!(a != b))\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\tif (!(a > b))\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t}\n\n\t\tpublic static void StructComplex(TS? a, Func<TS> x)\n\t\t{\n\t\t\t// Tests deactivated because we insert redundant casts;\n\t\t\t// TODO: revisit after decision has been made regarding the type system.\n\t\t\t//if (a == x()) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\t\t\t//if (a != x()) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\t\t\t//if (a > x()) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\n\t\t\t//if (x() == a) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\t\t\t//if (x() != a) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\t\t\t//if (x() > a) {\n\t\t\t//\tConsole.WriteLine();\n\t\t\t//}\n\t\t}\n\n\t\tpublic static void StructValueBasic(TS? a, TS? b, int? i)\n\t\t{\n\t\t\tConsole.WriteLine(a == b);\n\t\t\tConsole.WriteLine(a != b);\n\t\t\tConsole.WriteLine(a > b);\n\n\t\t\tConsole.WriteLine(!(a == b));\n\t\t\tConsole.WriteLine(!(a != b));\n\t\t\tConsole.WriteLine(!(a > b));\n\n\t\t\tConsole.WriteLine(a + b);\n\t\t\tConsole.WriteLine(a - b);\n\t\t\tConsole.WriteLine(a * b);\n\t\t\tConsole.WriteLine(a / b);\n\t\t\tConsole.WriteLine(a % b);\n\t\t\tConsole.WriteLine(a & b);\n\t\t\tConsole.WriteLine(a | b);\n\t\t\tConsole.WriteLine(a ^ b);\n\t\t\tConsole.WriteLine(a << i);\n\t\t\tConsole.WriteLine(a >> i);\n\t\t\tConsole.WriteLine(a ?? b);\n\t\t\tConsole.WriteLine(+a);\n\t\t\tConsole.WriteLine(-a);\n\t\t\tConsole.WriteLine(!a);\n\t\t\tConsole.WriteLine(~a);\n\t\t\t// TODO:\n\t\t\t//Console.WriteLine(a++);\n\t\t\t//Console.WriteLine(a--);\n\t\t\t//Console.WriteLine(++a);\n\t\t\t//Console.WriteLine(--a);\n\t\t\t//Console.WriteLine((int?)a);\n\t\t\ta += b;\n\t\t\ta -= b;\n\t\t\ta *= b;\n\t\t\ta /= b;\n\t\t\ta %= b;\n\t\t\ta &= b;\n\t\t\ta |= b;\n\t\t\ta ^= b;\n\t\t\ta <<= i;\n\t\t\ta >>= i;\n\t\t}\n\n\t\tpublic static void StructValueComplex(TS? a, Func<TS> x, Func<int> i)\n\t\t{\n\t\t\t// Tests deactivated because we insert redundant casts;\n\t\t\t// TODO: revisit after decision has been made regarding the type system.\n\t\t\t//Console.WriteLine(a == x());\n\t\t\t//Console.WriteLine(a != x());\n\t\t\t//Console.WriteLine(a > x());\n\n\t\t\t//Console.WriteLine(x() == a);\n\t\t\t//Console.WriteLine(x() != a);\n\t\t\t//Console.WriteLine(x() > a);\n\n\t\t\t//Console.WriteLine(a + x());\n\t\t\t//Console.WriteLine(a - x());\n\t\t\t//Console.WriteLine(a * x());\n\t\t\t//Console.WriteLine(a / x());\n\t\t\t//Console.WriteLine(a % x());\n\t\t\t//Console.WriteLine(a & x());\n\t\t\t//Console.WriteLine(a | x());\n\t\t\t//Console.WriteLine(a ^ x());\n\t\t\t//Console.WriteLine(a << i());\n\t\t\t//Console.WriteLine(a >> i());\n\t\t\t//Console.WriteLine(a ?? x());\n\t\t\t//a += x();\n\t\t\t//a -= x();\n\t\t\t//a *= x();\n\t\t\t//a /= x();\n\t\t\t//a %= x();\n\t\t\t//a &= x();\n\t\t\t//a |= x();\n\t\t\t//a ^= x();\n\t\t\t//a <<= i();\n\t\t\t//a >>= i();\n\n\t\t\t//Console.WriteLine(x() + a);\n\t\t\t//(new TS?[0])[0] += x();\n\t\t}\n\n\t\tpublic static bool RetEq(int? a, int? b)\n\t\t{\n\t\t\treturn a == b;\n\t\t}\n\n\t\tpublic static bool RetEqConv(long? a, int? b)\n\t\t{\n\t\t\treturn a == b;\n\t\t}\n\n\t\tpublic static bool RetEqConst(long? a)\n\t\t{\n\t\t\treturn a == 10;\n\t\t}\n\n\t\tpublic static bool RetIneqConst(long? a)\n\t\t{\n\t\t\treturn a != 10;\n\t\t}\n\n\t\tpublic static bool RetLt(int? a, int? b)\n\t\t{\n\t\t\treturn a < b;\n\t\t}\n\n\t\tpublic static bool RetLtConst(int? a)\n\t\t{\n\t\t\treturn a < 10;\n\t\t}\n\n\t\tpublic static bool RetLtConv(long? a, int? b)\n\t\t{\n\t\t\treturn a < b;\n\t\t}\n\n\t\tpublic static bool RetNotLt(int? a, int? b)\n\t\t{\n\t\t\treturn !(a < b);\n\t\t}\n\t}\n\n\tinternal class T01_LiftedImplicitConversions\n\t{\n\t\tpublic int? ExtendI4(byte? b)\n\t\t{\n\t\t\treturn b;\n\t\t}\n\n\t\tpublic int? ExtendToI4(sbyte? b)\n\t\t{\n\t\t\treturn b;\n\t\t}\n\n\t\tpublic long? ExtendI8(byte? b)\n\t\t{\n\t\t\treturn b;\n\t\t}\n\n\t\tpublic long? ExtendToI8(sbyte? b)\n\t\t{\n\t\t\treturn b;\n\t\t}\n\n\t\tpublic long? ExtendI8(int? b)\n\t\t{\n\t\t\treturn b;\n\t\t}\n\n\t\tpublic long? ExtendToI8(uint? b)\n\t\t{\n\t\t\treturn b;\n\t\t}\n\n\t\t// TODO: unnecessary cast\n\t\t//public double? ToFloat(int? b)\n\t\t//{\n\t\t//\treturn b;\n\t\t//}\n\n\t\t//public long? InArithmetic(uint? b)\n\t\t//{\n\t\t//\treturn 100L + b;\n\t\t//}\n\n\t\tpublic long? AfterArithmetic(uint? b)\n\t\t{\n\t\t\treturn 100 + b;\n\t\t}\n\n\t\t// TODO: unnecessary cast\n\t\t//public static double? InArithmetic2(float? nf, double? nd, float f)\n\t\t//{\n\t\t//\treturn nf + nd + f;\n\t\t//}\n\n\t\tpublic static long? InArithmetic3(int? a, long? b, int? c, long d)\n\t\t{\n\t\t\treturn a + b + c + d;\n\t\t}\n\t}\n\n\tinternal class T02_LiftedExplicitConversions\n\t{\n\t\tprivate static void Print<T>(T? x) where T : struct\n\t\t{\n\t\t\tConsole.WriteLine(x);\n\t\t}\n\n\t\tpublic static void UncheckedCasts(int? i4, long? i8, float? f)\n\t\t{\n\t\t\tPrint((byte?)i4);\n\t\t\tPrint((short?)i4);\n\t\t\tPrint((uint?)i4);\n\t\t\tPrint((uint?)i8);\n\t\t\tPrint((uint?)f);\n\t\t}\n\n\t\tpublic static void CheckedCasts(int? i4, long? i8, float? f)\n\t\t{\n\t\t\tchecked\n\t\t\t{\n\t\t\t\tPrint((byte?)i4);\n\t\t\t\tPrint((short?)i4);\n\t\t\t\tPrint((uint?)i4);\n\t\t\t\tPrint((uint?)i8);\n\t\t\t\t//Print((uint?)f); TODO\n\t\t\t}\n\t\t}\n\t}\n\n\tinternal class T03_NullCoalescingTests\n\t{\n\t\tprivate static void Print<T>(T x)\n\t\t{\n\t\t\tConsole.WriteLine(x);\n\t\t}\n\n\t\tpublic static void Objects(object a, object b)\n\t\t{\n\t\t\tPrint(a ?? b);\n\t\t}\n\n\t\tpublic static void Nullables(int? a, int? b)\n\t\t{\n\t\t\tPrint(a ?? b);\n\t\t}\n\n\t\tpublic static void NullableWithNonNullableFallback(int? a, int b)\n\t\t{\n\t\t\tPrint(a ?? b);\n\t\t}\n\n\t\tpublic static void NullableWithImplicitConversion(short? a, int? b)\n\t\t{\n\t\t\tPrint(a ?? b);\n\t\t}\n\n\t\tpublic static void NullableWithImplicitConversionAndNonNullableFallback(short? a, int b)\n\t\t{\n\t\t\t// TODO: unnecessary cast\n\t\t\t//Print(a ?? b);\n\t\t}\n\n\t\tpublic static void Chain(int? a, int? b, int? c, int d)\n\t\t{\n\t\t\tPrint(a ?? b ?? c ?? d);\n\t\t}\n\n\t\tpublic static void ChainWithImplicitConversions(int? a, short? b, long? c, byte d)\n\t\t{\n\t\t\t// TODO: unnecessary casts\n\t\t\t//Print(a ?? b ?? c ?? d);\n\t\t}\n\n\t\tpublic static void ChainWithComputation(int? a, short? b, long? c, byte d)\n\t\t{\n\t\t\t// TODO: unnecessary casts\n\t\t\t//Print((a + 1) ?? (b + 2) ?? (c + 3) ?? (d + 4));\n\t\t}\n\n\t\tpublic static object ReturnObjects(object a, object b)\n\t\t{\n\t\t\treturn a ?? b;\n\t\t}\n\n\t\tpublic static int? ReturnNullables(int? a, int? b)\n\t\t{\n\t\t\treturn a ?? b;\n\t\t}\n\n\t\tpublic static int ReturnNullableWithNonNullableFallback(int? a, int b)\n\t\t{\n\t\t\treturn a ?? b;\n\t\t}\n\n\t\tpublic static int ReturnChain(int? a, int? b, int? c, int d)\n\t\t{\n\t\t\treturn a ?? b ?? c ?? d;\n\t\t}\n\n\t\tpublic static long ReturnChainWithImplicitConversions(int? a, short? b, long? c, byte d)\n\t\t{\n\t\t\t//TODO: unnecessary casts\n\t\t\t//return a ?? b ?? c ?? d;\n\t\t\treturn 0L;\n\t\t}\n\n\t\tpublic static long ReturnChainWithComputation(int? a, short? b, long? c, byte d)\n\t\t{\n\t\t\t//TODO: unnecessary casts\n\t\t\t//return (a + 1) ?? (b + 2) ?? (c + 3) ?? (d + 4);\n\t\t\treturn 0L;\n\t\t}\n\t}\n\n\t// dummy structure for testing custom operators\n\t[StructLayout(LayoutKind.Sequential, Size = 1)]\n\tpublic struct TS\n\t{\n\t\t// unary\n\t\tpublic static TS operator +(TS a)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static TS operator -(TS a)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static TS operator !(TS a)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static TS operator ~(TS a)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static TS operator ++(TS a)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static TS operator --(TS a)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\n\t\tpublic static explicit operator int(TS a)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\n\t\t// binary\n\t\tpublic static TS operator +(TS a, TS b)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static TS operator -(TS a, TS b)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static TS operator *(TS a, TS b)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static TS operator /(TS a, TS b)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static TS operator %(TS a, TS b)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static TS operator &(TS a, TS b)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static TS operator |(TS a, TS b)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static TS operator ^(TS a, TS b)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static TS operator <<(TS a, int b)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static TS operator >>(TS a, int b)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\n\t\t// comparisons\n\t\tpublic static bool operator ==(TS a, TS b)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static bool operator !=(TS a, TS b)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static bool operator <(TS a, TS b)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static bool operator <=(TS a, TS b)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static bool operator >(TS a, TS b)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic static bool operator >=(TS a, TS b)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\n\t\tpublic override bool Equals(object obj)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t\tpublic override int GetHashCode()\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/LocalFunctions.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n#if CS90\nusing System.Runtime.InteropServices;\n#endif\n\nnamespace LocalFunctions\n{\n\tinternal class LocalFunctions\n\t{\n\t\t[AttributeUsage(AttributeTargets.All)]\n\t\tinternal class MyAttribute : Attribute\n\t\t{\n\n\t\t}\n\n\t\tpublic class Generic<T1> where T1 : struct, ICloneable, IConvertible\n\t\t{\n\t\t\tpublic int MixedLocalFunction<T2>() where T2 : ICloneable, IConvertible\n\t\t\t{\n#pragma warning disable CS0219\n\t\t\t\tT2 t2 = default(T2);\n\t\t\t\tobject z = this;\n\t\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t\t{\n\t\t\t\t\tint i2 = 0;\n\t\t\t\t\ti2 += NonStaticMethod<object>(0);\n#if CS90\n\t\t\t\t\t[My]\n\t\t\t\t\t[return: My]\n\t\t\t\t\tint NonStaticMethod<[My] T3>([My] int unused)\n#else\n\t\t\t\t\tint NonStaticMethod<T3>(int unused)\n#endif\n\t\t\t\t\t{\n\t\t\t\t\t\tt2 = default(T2);\n\t\t\t\t\t\tint l = 0;\n\t\t\t\t\t\treturn NonStaticMethod3<T1>() + NonStaticMethod3<T2>() + z.GetHashCode();\n\t\t\t\t\t\tint NonStaticMethod3<T4>()\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn i2 + l + NonStaticMethod<T4>(0) + StaticMethod<decimal>();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn MixedLocalFunction<T1>() + MixedLocalFunction<T2>() + StaticMethod<decimal>() + StaticMethod<int>() + NonStaticMethod2() + StaticMethod4<object>(null) + StaticMethod5<T1>();\n\t\t\t\tint NonStaticMethod2()\n\t\t\t\t{\n\t\t\t\t\treturn GetHashCode();\n\t\t\t\t}\n#if CS80\n\t\t\t\tstatic int StaticMethod<T3>() where T3 : struct\n#else\n\t\t\t\tint StaticMethod<T3>() where T3 : struct\n#endif\n\t\t\t\t{\n\t\t\t\t\treturn typeof(T1).Name.Length + typeof(T2).Name.Length + typeof(T3).Name.Length + StaticMethod<float>() + StaticMethod2<T3, DayOfWeek>() + StaticMethod3<T2, T3, DayOfWeek>();\n\t\t\t\t}\n#if CS80\n\t\t\t\tstatic int StaticMethod2<T3, T4>() where T3 : struct where T4 : Enum\n#else\n\t\t\t\tint StaticMethod2<T3, T4>() where T3 : struct where T4 : Enum\n#endif\n\t\t\t\t{\n\t\t\t\t\treturn typeof(T1).Name.Length + typeof(T2).Name.Length + typeof(T3).Name.Length + typeof(T4).Name.Length + StaticMethod<float>() + StaticMethod2<T3, DayOfWeek>();\n\t\t\t\t}\n#pragma warning disable CS8387\n#if CS80\n\t\t\t\tstatic int StaticMethod3<T2, T3, T4>() where T2 : IConvertible where T3 : struct where T4 : Enum\n#else\n\t\t\t\tint StaticMethod3<T2, T3, T4>() where T2 : IConvertible where T3 : struct where T4 : Enum\n#endif\n#pragma warning restore CS8387\n\t\t\t\t{\n\t\t\t\t\treturn typeof(T2).Name.Length;\n\t\t\t\t}\n#if CS80\n\t\t\t\tstatic int StaticMethod4<T>(T dd)\n#else\n\t\t\t\tint StaticMethod4<T>(T dd)\n#endif\n\t\t\t\t{\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n#if CS80\n\t\t\t\tstatic int StaticMethod5<T3>()\n#else\n\t\t\t\tint StaticMethod5<T3>()\n#endif\n\t\t\t\t{\n\t\t\t\t\tint k = 0;\n\t\t\t\t\treturn k + NonStaticMethod4<T1>();\n\t\t\t\t\tint NonStaticMethod4<T4>()\n\t\t\t\t\t{\n\t\t\t\t\t\treturn k;\n\t\t\t\t\t}\n\t\t\t\t}\n#pragma warning restore CS0219\n\t\t\t}\n\n\t\t\tpublic int MixedLocalFunction2Delegate<T2>() where T2 : ICloneable, IConvertible\n\t\t\t{\n\t\t\t\tT2 t2 = default(T2);\n\t\t\t\tobject z = this;\n\t\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t\t{\n\t\t\t\t\tint i2 = 0;\n\t\t\t\t\ti2 += StaticInvokeAsFunc(NonStaticMethod<object>);\n\t\t\t\t\tint NonStaticMethod<T3>()\n\t\t\t\t\t{\n\t\t\t\t\t\tt2 = default(T2);\n\t\t\t\t\t\tint l = 0;\n\t\t\t\t\t\treturn StaticInvokeAsFunc(NonStaticMethod3<T1>) + StaticInvokeAsFunc(NonStaticMethod3<T2>) + z.GetHashCode();\n\t\t\t\t\t\tint NonStaticMethod3<T4>()\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn i2 + l + StaticInvokeAsFunc(NonStaticMethod<T4>) + StaticInvokeAsFunc(StaticMethod<decimal>);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(t2);\n\t\t\t\treturn StaticInvokeAsFunc(MixedLocalFunction2Delegate<T1>) + StaticInvokeAsFunc(MixedLocalFunction2Delegate<T2>) + StaticInvokeAsFunc(StaticMethod<decimal>) + StaticInvokeAsFunc(StaticMethod<int>) + StaticInvokeAsFunc(NonStaticMethod2) + StaticInvokeAsFunc(StaticMethod4<T1>) + new Func<object, int>(StaticMethod5<object>)(null) + StaticInvokeAsFunc2<object>(StaticMethod5<object>) + new Func<Func<object, int>, int>(StaticInvokeAsFunc2<object>)(StaticMethod5<object>);\n\t\t\t\tint NonStaticMethod2()\n\t\t\t\t{\n\t\t\t\t\treturn GetHashCode();\n\t\t\t\t}\n#if CS80\n\t\t\t\tstatic int StaticInvokeAsFunc(Func<int> func)\n#else\n\t\t\t\tint StaticInvokeAsFunc(Func<int> func)\n#endif\n\t\t\t\t{\n\t\t\t\t\treturn func();\n\t\t\t\t}\n#if CS80\n\t\t\t\tstatic int StaticInvokeAsFunc2<T>(Func<T, int> func)\n#else\n\t\t\t\tint StaticInvokeAsFunc2<T>(Func<T, int> func)\n#endif\n\t\t\t\t{\n\t\t\t\t\treturn func(default(T));\n\t\t\t\t}\n#if CS80\n\t\t\t\tstatic int StaticMethod<T3>() where T3 : struct\n#else\n\t\t\t\tint StaticMethod<T3>() where T3 : struct\n#endif\n\t\t\t\t{\n\t\t\t\t\treturn typeof(T1).Name.Length + typeof(T2).Name.Length + typeof(T3).Name.Length + StaticInvokeAsFunc(StaticMethod<float>) + StaticInvokeAsFunc(StaticMethod2<T3, DayOfWeek>) + StaticInvokeAsFunc(StaticMethod3<T2, T3, DayOfWeek>);\n\t\t\t\t}\n#if CS80\n\t\t\t\tstatic int StaticMethod2<T3, T4>() where T3 : struct where T4 : Enum\n#else\n\t\t\t\tint StaticMethod2<T3, T4>() where T3 : struct where T4 : Enum\n#endif\n\t\t\t\t{\n\t\t\t\t\treturn typeof(T1).Name.Length + typeof(T2).Name.Length + typeof(T3).Name.Length + typeof(T4).Name.Length + StaticInvokeAsFunc(StaticMethod<float>) + StaticInvokeAsFunc(StaticMethod2<T3, DayOfWeek>);\n\t\t\t\t}\n#pragma warning disable CS8387\n#if CS80\n\t\t\t\tstatic int StaticMethod3<T2, T3, T4>() where T2 : IConvertible where T3 : struct where T4 : Enum\n#else\n\t\t\t\tint StaticMethod3<T2, T3, T4>() where T2 : IConvertible where T3 : struct where T4 : Enum\n#endif\n#pragma warning restore CS8387\n\t\t\t\t{\n\t\t\t\t\treturn typeof(T2).Name.Length;\n\t\t\t\t}\n#if CS80\n\t\t\t\tstatic int StaticMethod4<T3>()\n#else\n\t\t\t\tint StaticMethod4<T3>()\n#endif\n\t\t\t\t{\n\t\t\t\t\tint k = 0;\n\t\t\t\t\treturn k + StaticInvokeAsFunc(NonStaticMethod4<T1>);\n\t\t\t\t\tint NonStaticMethod4<T4>()\n\t\t\t\t\t{\n\t\t\t\t\t\treturn k;\n\t\t\t\t\t}\n\t\t\t\t}\n#if CS80\n\t\t\t\tstatic int StaticMethod5<T>(T dd)\n#else\n\t\t\t\tint StaticMethod5<T>(T dd)\n#endif\n\t\t\t\t{\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic static void Test_CaptureT<T2>()\n\t\t\t{\n#pragma warning disable CS0219\n\t\t\t\tT2 t2 = default(T2);\n\t\t\t\tMethod<int>();\n\t\t\t\tvoid Method<T3>()\n\t\t\t\t{\n\t\t\t\t\tt2 = default(T2);\n\t\t\t\t\tT2 t2x = t2;\n\t\t\t\t\tT3 t3 = default(T3);\n\t\t\t\t\tMethod2();\n\t\t\t\t\tvoid Method2()\n\t\t\t\t\t{\n\t\t\t\t\t\tt2 = default(T2);\n\t\t\t\t\t\tt2x = t2;\n\t\t\t\t\t\tt3 = default(T3);\n\t\t\t\t\t}\n\t\t\t\t}\n#pragma warning restore CS0219\n\t\t\t}\n\n\t\t\tpublic void TestGenericArgs<T2>() where T2 : List<T2>\n\t\t\t{\n\t\t\t\tZZ<T2>(null);\n\t\t\t\tZZ3<object>(null);\n#if CS80\n\t\t\t\tstatic void Nop<T>(T data)\n#else\n\t\t\t\tvoid Nop<T>(T data)\n#endif\n\t\t\t\t{\n\t\t\t\t}\n#if CS80\n\t\t\t\tstatic void ZZ<T3>(T3 t3) where T3 : T2\n#else\n\t\t\t\tvoid ZZ<T3>(T3 t3) where T3 : T2\n#endif\n\t\t\t\t{\n\t\t\t\t\tNop<List<T2>>(t3);\n\t\t\t\t\tZZ2<T3>(t3);\n\t\t\t\t\tZZ4();\n\t\t\t\t\tvoid ZZ4()\n\t\t\t\t\t{\n\t\t\t\t\t\tNop<List<T2>>(t3);\n\t\t\t\t\t}\n\t\t\t\t}\n#if CS80\n\t\t\t\tstatic void ZZ2<T3>(T3 t3)\n#else\n\t\t\t\tvoid ZZ2<T3>(T3 t3)\n#endif\n\t\t\t\t{\n\t\t\t\t\tNop<List<T2>>((List<T2>)(object)t3);\n\t\t\t\t}\n#if CS80\n\t\t\t\tstatic void ZZ3<T3>(T3 t3)\n#else\n\t\t\t\tvoid ZZ3<T3>(T3 t3)\n#endif\n\t\t\t\t{\n\t\t\t\t\tNop<List<T2>>((List<T2>)(object)t3);\n\t\t\t\t}\n\t\t\t}\n\n#if false\n\t\t\tpublic void GenericArgsWithAnonymousType()\n\t\t\t{\n\t\t\t\tMethod<int>();\n#if CS80\n\t\t\t\tstatic void Method<T2>()\n#else\n\t\t\t\tvoid Method<T2>()\n#endif\n\t\t\t\t{\n\t\t\t\t\tint i = 0;\n\t\t\t\t\tvar obj2 = new {\n\t\t\t\t\t\tA = 1\n\t\t\t\t\t};\n\t\t\t\t\tMethod2(obj2);\n\t\t\t\t\tMethod3(obj2);\n\t\t\t\t\tvoid Method2<T3>(T3 obj1)\n\t\t\t\t\t{\n\t\t\t\t\t\t//keep nested\n\t\t\t\t\t\ti = 0;\n\t\t\t\t\t}\n#if CS80\n\t\t\t\t\tstatic void Method3<T3>(T3 obj1)\n#else\n\t\t\t\t\tvoid Method3<T3>(T3 obj1)\n#endif\n\t\t\t\t\t{\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n#if CS80\n\t\t\tpublic void NameConflict()\n\t\t\t{\n\t\t\t\tint i = 0;\n\t\t\t\tMethod<int>();\n\t\t\t\tvoid Method<T2>()\n\t\t\t\t{\n\t\t\t\t\tMethod();\n\t\t\t\t\tvoid Method()\n\t\t\t\t\t{\n\t\t\t\t\t\tMethod<T2>();\n\t\t\t\t\t\ti = 0;\n\t\t\t\t\t\tvoid Method<T2>()\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ti = 0;\n\t\t\t\t\t\t\tMethod();\n\t\t\t\t\t\t\tstatic void Method()\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n#endif\n#endif\n\t\t}\n\n\t\tprivate int field;\n\n\t\tprivate Lazy<object> nonCapturinglocalFunctionInLambda = new Lazy<object>(delegate {\n\t\t\treturn CreateValue();\n\n#if CS80\n\t\t\tstatic object CreateValue()\n#else\n\t\t\tobject CreateValue()\n#endif\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t});\n\n\t\tprivate Lazy<object> capturinglocalFunctionInLambda = new Lazy<object>(delegate {\n\t\t\tint x = 42;\n\t\t\treturn Do();\n\n\t\t\tobject Do()\n\t\t\t{\n\t\t\t\treturn CreateValue();\n\n\t\t\t\tint CreateValue()\n\t\t\t\t{\n\t\t\t\t\treturn x;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tprivate static void Test(int x)\n\t\t{\n\t\t}\n\n\t\tprivate static int GetInt(string a)\n\t\t{\n\t\t\treturn a.Length;\n\t\t}\n\n\t\tprivate static string GetString(int a)\n\t\t{\n\t\t\treturn a.ToString();\n\t\t}\n\n\t\tpublic static void StaticContextNoCapture(int length)\n\t\t{\n\t\t\tfor (int i = 0; i < length; i++)\n\t\t\t{\n\t\t\t\tLocalWrite(\"Hello \" + i);\n\t\t\t}\n\n#if CS80\n\t\t\tstatic void LocalWrite(string s)\n#else\n\t\t\tvoid LocalWrite(string s)\n#endif\n\t\t\t{\n\t\t\t\tConsole.WriteLine(s);\n\t\t\t}\n\t\t}\n\n\t\tpublic static void StaticContextSimpleCapture(int length)\n\t\t{\n\t\t\tfor (int i = 0; i < length; i++)\n\t\t\t{\n\t\t\t\tLocalWrite();\n\t\t\t}\n\n\t\t\tvoid LocalWrite()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Hello \" + length);\n\t\t\t}\n\t\t}\n\n\t\tpublic static void StaticContextCaptureForLoopVariable(int length)\n\t\t{\n\t\t\tint i;\n\t\t\tfor (i = 0; i < length; i++)\n\t\t\t{\n\t\t\t\tLocalWrite();\n\t\t\t}\n\t\t\tvoid LocalWrite()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Hello \" + i + \"/\" + length);\n\t\t\t}\n\t\t}\n\n\t\tpublic void ContextNoCapture()\n\t\t{\n\t\t\tfor (int i = 0; i < field; i++)\n\t\t\t{\n\t\t\t\tLocalWrite(\"Hello \" + i);\n\t\t\t}\n\n#if CS80\n\t\t\tstatic void LocalWrite(string s)\n#else\n\t\t\tvoid LocalWrite(string s)\n#endif\n\t\t\t{\n\t\t\t\tConsole.WriteLine(s);\n\t\t\t}\n\t\t}\n\n\t\tpublic void ContextSimpleCapture()\n\t\t{\n\t\t\tfor (int i = 0; i < field; i++)\n\t\t\t{\n\t\t\t\tLocalWrite();\n\t\t\t}\n\n\t\t\tvoid LocalWrite()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Hello \" + field);\n\t\t\t}\n\t\t}\n\n\t\tpublic void ContextCaptureForLoopVariable()\n\t\t{\n\t\t\tint i;\n\t\t\tfor (i = 0; i < field; i++)\n\t\t\t{\n\t\t\t\tLocalWrite();\n\t\t\t}\n\t\t\tvoid LocalWrite()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Hello \" + i + \"/\" + field);\n\t\t\t}\n\t\t}\n\n\t\tpublic void CapturedOutsideLoop()\n\t\t{\n\t\t\tint i = 0;\n\t\t\twhile (i < field)\n\t\t\t{\n\t\t\t\ti = GetInt(\"asdf\");\n\t\t\t\tLocalWrite();\n\t\t\t}\n\n\t\t\tvoid LocalWrite()\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Hello \" + i + \"/\" + field);\n\t\t\t}\n\t\t}\n\n\t\tpublic void CapturedInForeachLoop(IEnumerable<string> args)\n\t\t{\n\t\t\tforeach (string arg2 in args)\n\t\t\t{\n\t\t\t\tstring arg = arg2;\n\t\t\t\tLocalWrite();\n\t\t\t\tvoid LocalWrite()\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Hello \" + arg);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic void Overloading()\n\t\t{\n\t\t\tTest(5);\n\t\t\tLocalFunctions.Test(2);\n\n#if CS80\n\t\t\tstatic void Test(int x)\n#else\n\t\t\tvoid Test(int x)\n#endif\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"x: {0}\", x);\n\t\t\t}\n\t\t}\n\n\t\tprivate void Name()\n\t\t{\n\n\t\t}\n\n\t\tprivate void LocalFunctionHidingMethod()\n\t\t{\n\t\t\tAction action = this.Name;\n\t\t\tName();\n\t\t\taction();\n\n#if CS80\n\t\t\tstatic void Name()\n#else\n\t\t\tvoid Name()\n#endif\n\t\t\t{\n\n\t\t\t}\n\t\t}\n\n\t\tpublic void NamedArgument()\n\t\t{\n\t\t\tUse(Get(1), Get(2), Get(3));\n\t\t\tUse(Get(1), c: Get(2), b: Get(3));\n\n#if CS80\n\t\t\tstatic int Get(int i)\n#else\n\t\t\tint Get(int i)\n#endif\n\t\t\t{\n\t\t\t\treturn i;\n\t\t\t}\n\n#if CS80\n\t\t\tstatic void Use(int a, int b, int c)\n#else\n\t\t\tvoid Use(int a, int b, int c)\n#endif\n\t\t\t{\n\t\t\t\tConsole.WriteLine(a + b + c);\n\t\t\t}\n\t\t}\n\n\t\tpublic static Func<int> LambdaInLocalFunction()\n\t\t{\n\t\t\tint x = (int)Math.Pow(2.0, 10.0);\n\t\t\treturn Create();\n\n\t\t\tFunc<int> Create()\n\t\t\t{\n\t\t\t\treturn () => x;\n\t\t\t}\n\t\t}\n\n\t\tpublic static Func<int> MethodRef()\n\t\t{\n\t\t\tint x = (int)Math.Pow(2.0, 10.0);\n\t\t\tEnumerable.Range(1, 100).Select(LocalFunction);\n\t\t\treturn null;\n\n\t\t\tint LocalFunction(int y)\n\t\t\t{\n\t\t\t\treturn x * y;\n\t\t\t}\n\t\t}\n\n\t\tpublic static int Fib(int i)\n\t\t{\n\t\t\treturn FibHelper(i);\n\n#if CS80\n\t\t\tstatic int FibHelper(int n)\n#else\n\t\t\tint FibHelper(int n)\n#endif\n\t\t\t{\n\t\t\t\tif (n <= 0)\n\t\t\t\t{\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn FibHelper(n - 1) + FibHelper(n - 2);\n\t\t\t}\n\t\t}\n\t\tpublic int MutuallyRecursiveLocalFunctions()\n\t\t{\n\t\t\treturn B(4) + C(3);\n\n#if CS80\n\t\t\tstatic int A(int i)\n#else\n\t\t\tint A(int i)\n#endif\n\t\t\t{\n\t\t\t\tif (i > 0)\n\t\t\t\t{\n\t\t\t\t\treturn A(i - 1) + 2 * B(i - 1) + 3 * C(i - 1);\n\t\t\t\t}\n\t\t\t\treturn 1;\n\t\t\t}\n\n#if CS80\n\t\t\tstatic int B(int i)\n#else\n\t\t\tint B(int i)\n#endif\n\t\t\t{\n\t\t\t\tif (i > 0)\n\t\t\t\t{\n\t\t\t\t\treturn 3 * A(i - 1) + B(i - 1);\n\t\t\t\t}\n\t\t\t\treturn 1;\n\t\t\t}\n\n#if CS80\n\t\t\tstatic int C(int i)\n#else\n\t\t\tint C(int i)\n#endif\n\t\t\t{\n\t\t\t\tif (i > 0)\n\t\t\t\t{\n\t\t\t\t\treturn 2 * A(i - 1) + C(i - 1);\n\t\t\t\t}\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\tpublic static int NestedLocalFunctions(int i)\n\t\t{\n\t\t\treturn A();\n\n\t\t\tint A()\n\t\t\t{\n\t\t\t\tdouble x = Math.Pow(10.0, 2.0);\n\t\t\t\treturn B();\n\n\t\t\t\tint B()\n\t\t\t\t{\n\t\t\t\t\treturn i + (int)x;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static int LocalFunctionInLambda(IEnumerable<int> xs)\n\t\t{\n\t\t\treturn xs.First(delegate (int x) {\n\t\t\t\treturn Do();\n\n\t\t\t\tbool Do()\n\t\t\t\t{\n\t\t\t\t\treturn x == 3;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldReturn(int n)\n\t\t{\n\t\t\treturn GetNumbers();\n\n\t\t\tIEnumerable<int> GetNumbers()\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < n; i++)\n\t\t\t\t{\n\t\t\t\t\tyield return i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic void WriteCapturedParameter(int i)\n\t\t{\n\t\t\tParamWrite();\n\t\t\tConsole.WriteLine(i);\n\n\t\t\tvoid ParamWrite()\n\t\t\t{\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\n\t\t//public static void LocalFunctionInUsing()\n\t\t//{\n\t\t//\tusing (MemoryStream memoryStream = new MemoryStream()) {\n\t\t//\t\tDo();\n\n\t\t//\t\tvoid Do()\n\t\t//\t\t{\n\t\t//\t\t\tmemoryStream.WriteByte(42);\n\t\t//\t\t}\n\t\t//\t}\n\t\t//}\n\n\t\tpublic void NestedCapture1()\n\t\t{\n\t\t\tMethod(null);\n\n#if CS80\n\t\t\tstatic Action<object> Method(Action<object> action)\n#else\n\t\t\tAction<object> Method(Action<object> action)\n#endif\n\t\t\t{\n\t\t\t\treturn Method2;\n\n\t\t\t\tvoid Method2(object containerBuilder)\n\t\t\t\t{\n\t\t\t\t\tMethod3(containerBuilder);\n\t\t\t\t}\n\n\t\t\t\tvoid Method3(object containerBuilder)\n\t\t\t\t{\n\t\t\t\t\taction(containerBuilder);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic int NestedCapture2()\n\t\t{\n\t\t\treturn Method();\n#if CS80\n\t\t\tstatic int Method()\n#else\n\t\t\tint Method()\n#endif\n\t\t\t{\n\t\t\t\tint t0 = 0;\n\t\t\t\treturn ZZZ();\n\t\t\t\tint ZZZ()\n\t\t\t\t{\n\t\t\t\t\tt0 = 0;\n\t\t\t\t\tint t2 = t0;\n\t\t\t\t\treturn new Func<int>(ZZZ3)();\n\t\t\t\t\tint ZZZ3()\n\t\t\t\t\t{\n\t\t\t\t\t\tt0 = 0;\n\t\t\t\t\t\tt2 = 0;\n\t\t\t\t\t\treturn ZZZ2();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tint ZZZ2()\n\t\t\t\t{\n\t\t\t\t\tt0 = 0;\n\t\t\t\t\tint t3 = t0;\n\t\t\t\t\treturn new Func<int>(ZZZ4)();\n\t\t\t\t\tint ZZZ4()\n\t\t\t\t\t{\n\t\t\t\t\t\tt0 = 0;\n\t\t\t\t\t\tt3 = 0;\n\t\t\t\t\t\treturn 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic int Issue1798_NestedCapture2()\n\t\t{\n\t\t\treturn Method();\n#if CS80\n\t\t\tstatic int Method()\n#else\n\t\t\tint Method()\n#endif\n\t\t\t{\n\t\t\t\tint t0 = 0;\n\t\t\t\treturn ZZZ();\n\t\t\t\tint ZZZ()\n\t\t\t\t{\n\t\t\t\t\tt0 = 0;\n\t\t\t\t\tint t2 = t0;\n\t\t\t\t\treturn ((Func<int>)delegate {\n\t\t\t\t\t\tt0 = 0;\n\t\t\t\t\t\tt2 = 0;\n\t\t\t\t\t\treturn ZZZ2();\n\t\t\t\t\t})();\n\t\t\t\t}\n\t\t\t\tint ZZZ2()\n\t\t\t\t{\n\t\t\t\t\tt0 = 0;\n\t\t\t\t\tint t3 = t0;\n#if !OPT\n\t\t\t\t\tFunc<int> func = delegate {\n#else\n\t\t\t\t\treturn ((Func<int>)delegate {\n#endif\n\t\t\t\t\t\tt0 = 0;\n\t\t\t\t\t\tt3 = 0;\n\t\t\t\t\t\treturn 0;\n#if !OPT\n\t\t\t\t\t};\n\t\t\t\t\treturn func();\n#else\n\t\t\t\t\t})();\n#endif\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic int Issue1798_NestedCapture2b()\n\t\t{\n\t\t\treturn Method();\n#if CS80\n\t\t\tstatic int Method()\n#else\n\t\t\tint Method()\n#endif\n\t\t\t{\n\t\t\t\tint t0 = 0;\n\t\t\t\treturn ZZZ() + ZZZ2();\n\t\t\t\tint ZZZ()\n\t\t\t\t{\n\t\t\t\t\tt0 = 0;\n\t\t\t\t\tint t2 = t0;\n\t\t\t\t\treturn ((Func<int>)delegate {\n\t\t\t\t\t\tt0 = 0;\n\t\t\t\t\t\tt2 = 0;\n\t\t\t\t\t\treturn ZZZ2();\n\t\t\t\t\t})();\n\t\t\t\t}\n\t\t\t\tint ZZZ2()\n\t\t\t\t{\n\t\t\t\t\tt0 = 0;\n\t\t\t\t\tint t3 = t0;\n#if !OPT\n\t\t\t\t\tFunc<int> func = delegate {\n#else\n\t\t\t\t\treturn ((Func<int>)delegate {\n#endif\n\t\t\t\t\t\tt0 = 0;\n\t\t\t\t\t\tt3 = 0;\n\t\t\t\t\t\treturn 0;\n#if !OPT\n\t\t\t\t\t};\n\t\t\t\t\treturn func();\n#else\n\t\t\t\t\t})();\n#endif\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n#if CS90\n\t\tpublic void Issue2196()\n\t\t{\n\t\t\tEnumWindows(0L, 0L);\n\n\t\t\t[DllImport(\"user32.dll\", CallingConvention = CallingConvention.StdCall, EntryPoint = \"EnumWindows\")]\n\t\t\tstatic extern int EnumWindows(long hWnd, long lParam);\n\t\t}\n#endif\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Lock.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class Lock\n\t{\n\t\tpublic void LockThis()\n\t\t{\n\t\t\tlock (this)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t}\n\n\t\tpublic void LockOnType()\n\t\t{\n\t\t\tlock (typeof(Lock))\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Loops.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class Loops\n\t{\n\t\t#region foreach\n\t\tpublic class CustomClassEnumerator\n\t\t{\n\t\t\tpublic object Current {\n\t\t\t\tget {\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic bool MoveNext()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic void Reset()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic CustomClassEnumerator GetEnumerator()\n\t\t\t{\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}\n\n\t\t[StructLayout(LayoutKind.Sequential, Size = 1)]\n\t\tpublic struct CustomStructEnumerator\n\t\t{\n\t\t\tpublic object Current {\n\t\t\t\tget {\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic bool MoveNext()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic void Reset()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic CustomStructEnumerator GetEnumerator()\n\t\t\t{\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}\n\n\t\tpublic class CustomClassEnumerator<T>\n\t\t{\n\t\t\tpublic T Current {\n\t\t\t\tget {\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic void Dispose()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic bool MoveNext()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic void Reset()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic CustomClassEnumerator<T> GetEnumerator()\n\t\t\t{\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}\n\n\t\t[StructLayout(LayoutKind.Sequential, Size = 1)]\n\t\tpublic struct CustomStructEnumerator<T>\n\t\t{\n\t\t\tpublic T Current {\n\t\t\t\tget {\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic void Dispose()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic bool MoveNext()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic void Reset()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic CustomStructEnumerator<T> GetEnumerator()\n\t\t\t{\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}\n\n\t\tpublic class CustomClassEnumeratorWithIDisposable : IDisposable\n\t\t{\n\t\t\tpublic object Current {\n\t\t\t\tget {\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic void Dispose()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic bool MoveNext()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic void Reset()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic CustomClassEnumeratorWithIDisposable GetEnumerator()\n\t\t\t{\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}\n\n\t\t[StructLayout(LayoutKind.Sequential, Size = 1)]\n\t\tpublic struct CustomStructEnumeratorWithIDisposable : IDisposable\n\t\t{\n\t\t\tpublic object Current {\n\t\t\t\tget {\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic void Dispose()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic bool MoveNext()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic void Reset()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic CustomStructEnumeratorWithIDisposable GetEnumerator()\n\t\t\t{\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}\n\n\t\tpublic class CustomClassEnumeratorWithIDisposable<T> : IDisposable\n\t\t{\n\t\t\tpublic T Current {\n\t\t\t\tget {\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic void Dispose()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic bool MoveNext()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic void Reset()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic CustomClassEnumeratorWithIDisposable<T> GetEnumerator()\n\t\t\t{\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}\n\n\t\t[StructLayout(LayoutKind.Sequential, Size = 1)]\n\t\tpublic struct CustomStructEnumeratorWithIDisposable<T> : IDisposable\n\t\t{\n\t\t\tpublic T Current {\n\t\t\t\tget {\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic void Dispose()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic bool MoveNext()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic void Reset()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tpublic CustomStructEnumeratorWithIDisposable<T> GetEnumerator()\n\t\t\t{\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}\n\n#if MCS\n\t\t[StructLayout(LayoutKind.Sequential, Size = 1)]\n#endif\n\t\tpublic struct DataItem\n\t\t{\n\t\t\tpublic int Property { get; set; }\n\n\t\t\tpublic void TestCall()\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic class Item\n\t\t{\n\n\t\t}\n\n\t\tpublic class NonEnumerableArrayLike\n\t\t{\n\t\t\tprivate readonly int length;\n\n\t\t\tpublic Item this[int index] {\n\t\t\t\tget {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic int Length {\n\t\t\t\tget {\n\t\t\t\t\treturn length;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate IEnumerable<string> alternatives;\n\t\tprivate object someObject;\n\n\t\tprivate void TryGetItem(int id, out Item item)\n\t\t{\n\t\t\titem = null;\n\t\t}\n\n\t\tprivate static void Operation(ref int i)\n\t\t{\n\t\t}\n\n\t\tprivate static void Operation(Func<bool> f)\n\t\t{\n\t\t}\n\n\t\tpublic void ForEachOnField()\n\t\t{\n\t\t\tforeach (string alternative in alternatives)\n\t\t\t{\n\t\t\t\talternative.ToLower();\n\t\t\t}\n\t\t}\n\n\t\tpublic void ForEach(IEnumerable<string> alternatives)\n\t\t{\n\t\t\tforeach (string alternative in alternatives)\n\t\t\t{\n\t\t\t\talternative.ToLower();\n\t\t\t}\n\t\t}\n\n\t\tpublic void ForEachOverList(List<string> list)\n\t\t{\n\t\t\t// List has a struct as enumerator, so produces quite different IL than foreach over the IEnumerable interface\n\t\t\tforeach (string item in list)\n\t\t\t{\n\t\t\t\titem.ToLower();\n\t\t\t}\n\t\t}\n\n\t\tpublic void ForEachOverNonGenericEnumerable(IEnumerable enumerable)\n\t\t{\n\t\t\tforeach (object item in enumerable)\n\t\t\t{\n\t\t\t\titem.ToString();\n\t\t\t}\n\t\t}\n\n\t\tpublic void ForEachOverNonGenericEnumerableWithAutomaticCastValueType(IEnumerable enumerable)\n\t\t{\n\t\t\tforeach (int item in enumerable)\n\t\t\t{\n\t\t\t\titem.ToString();\n\t\t\t}\n\t\t}\n\n\t\tpublic void ForEachOverNonGenericEnumerableWithAutomaticCastRefType(IEnumerable enumerable)\n\t\t{\n\t\t\tforeach (string item in enumerable)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(item);\n\t\t\t}\n\t\t}\n\n\t\tpublic void ForEachOnCustomClassEnumerator(CustomClassEnumerator e)\n\t\t{\n\t\t\tforeach (object item in e)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(item);\n\t\t\t}\n\t\t}\n\n\t\t// TODO : Needs additional pattern detection\n\t\t// CustomStructEnumerator does not implement IDisposable\n\t\t// No try-finally-Dispose is generated.\n\t\t//public void ForEachOnCustomStructEnumerator(CustomStructEnumerator e)\n\t\t//{\n\t\t//\tforeach (object item in e) {\n\t\t//\t\tConsole.WriteLine(item);\n\t\t//\t}\n\t\t//}\n\n\t\tpublic void ForEachOnGenericCustomClassEnumerator<T>(CustomClassEnumerator<T> e)\n\t\t{\n\t\t\tforeach (T item in e)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(item);\n\t\t\t}\n\t\t}\n\n\t\t// TODO : Needs additional pattern detection\n\t\t// CustomStructEnumerator does not implement IDisposable\n\t\t// No try-finally-Dispose is generated.\n\t\t//public void ForEachOnGenericCustomStructEnumerator<T>(CustomStructEnumerator<T> e)\n\t\t//{\n\t\t//\tforeach (T item in e) {\n\t\t//\t\tConsole.WriteLine(item);\n\t\t//\t}\n\t\t//}\n\n\t\tpublic void ForEachOnCustomClassEnumeratorWithIDisposable(CustomClassEnumeratorWithIDisposable e)\n\t\t{\n\t\t\tforeach (object item in e)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(item);\n\t\t\t}\n\t\t}\n\n\t\tpublic void ForEachOnCustomStructEnumeratorWithIDisposable(CustomStructEnumeratorWithIDisposable e)\n\t\t{\n\t\t\tforeach (object item in e)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(item);\n\t\t\t}\n\t\t}\n\n\t\tpublic void ForEachOnGenericCustomClassEnumeratorWithIDisposable<T>(CustomClassEnumeratorWithIDisposable<T> e)\n\t\t{\n\t\t\tforeach (T item in e)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(item);\n\t\t\t}\n\t\t}\n\n\t\tpublic void ForEachOnGenericCustomStructEnumeratorWithIDisposable<T>(CustomStructEnumeratorWithIDisposable<T> e)\n\t\t{\n\t\t\tforeach (T item in e)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(item);\n\t\t\t}\n\t\t}\n\n\t\tpublic static void NonGenericForeachWithReturnFallbackTest(IEnumerable e)\n\t\t{\n\t\t\tConsole.WriteLine(\"NonGenericForeachWithReturnFallback:\");\n\t\t\tIEnumerator enumerator = e.GetEnumerator();\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"MoveNext\");\n\t\t\t\tif (enumerator.MoveNext())\n\t\t\t\t{\n\t\t\t\t\tobject current = enumerator.Current;\n\t\t\t\t\tConsole.WriteLine(\"please don't inline 'current'\");\n\t\t\t\t\tConsole.WriteLine(current);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tIDisposable disposable = enumerator as IDisposable;\n\t\t\t\tif (disposable != null)\n\t\t\t\t{\n\t\t\t\t\tdisposable.Dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t\tConsole.WriteLine(\"After finally!\");\n\t\t}\n\n\t\tpublic static void ForeachWithRefUsage(List<int> items)\n\t\t{\n\t\t\tforeach (int item in items)\n\t\t\t{\n#if ROSLYN && OPT\n\t\t\t\t// The variable name differs based on whether roslyn optimizes out the 'item' variable\n\t\t\t\tint i = item;\n\t\t\t\tOperation(ref i);\n#else\n\t\t\t\tint i = item;\n\t\t\t\tOperation(ref i);\n#endif\n\t\t\t}\n\t\t}\n\n\t\tpublic static void ForeachWithCapturedVariable(List<int> items)\n\t\t{\n\t\t\tforeach (int item in items)\n\t\t\t{\n\t\t\t\tint c = item;\n\t\t\t\tOperation(() => c == 5);\n\t\t\t}\n\t\t}\n\n\t\tpublic static T LastOrDefault<T>(IEnumerable<T> items)\n\t\t{\n\t\t\tT result = default(T);\n\t\t\tforeach (T item in items)\n\t\t\t{\n\t\t\t\tresult = item;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic void ForEachOverArray(string[] array)\n\t\t{\n\t\t\tforeach (string text in array)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(text.ToLower() + text.ToUpper());\n\t\t\t}\n\t\t}\n\n\t\tpublic void ForOverNonArray(NonEnumerableArrayLike array)\n\t\t{\n\t\t\tfor (int i = 0; i < array.Length; i++)\n\t\t\t{\n\t\t\t\tItem item = array[i];\n\t\t\t\tConsole.WriteLine(item.ToString() + item.ToString());\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe void ForEachOverArrayOfPointers(int*[] array)\n\t\t{\n\t\t\tforeach (int* value in array)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(new IntPtr(value));\n\t\t\t\tConsole.WriteLine(new IntPtr(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic void ForEachBreakWhenFound(string name, ref StringComparison output)\n\t\t{\n#if MCS2\n\t\t\tforeach (int value in Enum.GetValues(typeof(StringComparison)))\n\t\t\t{\n\t\t\t\tif (((StringComparison)value).ToString() == name)\n\t\t\t\t{\n\t\t\t\t\toutput = (StringComparison)value;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n#elif MCS5\n\t\t\tforeach (int value in Enum.GetValues(typeof(StringComparison)))\n\t\t\t{\n\t\t\t\tStringComparison stringComparison = (StringComparison)value;\n\t\t\t\tif (stringComparison.ToString() == name)\n\t\t\t\t{\n\t\t\t\t\toutput = (StringComparison)value;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n#else\n\t\t\tforeach (StringComparison value in Enum.GetValues(typeof(StringComparison)))\n\t\t\t{\n\t\t\t\tif (value.ToString() == name)\n\t\t\t\t{\n\t\t\t\t\toutput = value;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n#endif\n\t\t}\n\n\t\tpublic void ForEachOverListOfStruct(List<DataItem> items, int value)\n\t\t{\n\t\t\tforeach (DataItem item in items)\n\t\t\t{\n#if ROSLYN && OPT\n\t\t\t\t// The variable name differs based on whether roslyn optimizes out the 'item' variable\n\t\t\t\tDataItem current = item;\n\t\t\t\tcurrent.Property = value;\n#else\n\t\t\t\tDataItem dataItem = item;\n\t\t\t\tdataItem.Property = value;\n#endif\n\t\t\t}\n\t\t}\n\n\t\tpublic void ForEachOverListOfStruct2(List<DataItem> items, int value)\n\t\t{\n\t\t\tforeach (DataItem item in items)\n\t\t\t{\n#if ROSLYN && OPT\n\t\t\t\t// The variable name differs based on whether roslyn optimizes out the 'item' variable\n\t\t\t\tDataItem current = item;\n\t\t\t\tcurrent.TestCall();\n\t\t\t\tcurrent.Property = value;\n#else\n\t\t\t\tDataItem dataItem = item;\n\t\t\t\tdataItem.TestCall();\n\t\t\t\tdataItem.Property = value;\n#endif\n\t\t\t}\n\t\t}\n\n\t\tpublic void ForEachOverListOfStruct3(List<DataItem> items, int value)\n\t\t{\n\t\t\tforeach (DataItem item in items)\n\t\t\t{\n\t\t\t\titem.TestCall();\n\t\t\t}\n\t\t}\n\n#if !MCS\n\t\tpublic void ForEachOverMultiDimArray(int[,] items)\n\t\t{\n\t\t\tforeach (int value in items)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(value);\n\t\t\t\tConsole.WriteLine(value);\n\t\t\t}\n\t\t}\n\n\t\tpublic void ForEachOverMultiDimArray2(int[,,] items)\n\t\t{\n\t\t\tforeach (int value in items)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(value);\n\t\t\t\tConsole.WriteLine(value);\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe void ForEachOverMultiDimArray3(int*[,] items)\n\t\t{\n#if ROSLYN && OPT\n\t\t\tforeach (int* intPtr in items)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(*intPtr);\n\t\t\t\tConsole.WriteLine(*intPtr);\n\t\t\t}\n#else\n\t\t\tforeach (int* ptr in items)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(*ptr);\n\t\t\t\tConsole.WriteLine(*ptr);\n\t\t\t}\n#endif\n\t\t}\n#endif\n\n\t\t#endregion\n\n\t\tpublic void ForOverArray(string[] array)\n\t\t{\n\t\t\tfor (int i = 0; i < array.Length; i++)\n\t\t\t{\n\t\t\t\tarray[i].ToLower();\n\t\t\t}\n\t\t}\n\n\t\tprivate static void AppendNamePart(string part, StringBuilder name)\n\t\t{\n\t\t\tforeach (char c in part)\n\t\t\t{\n\t\t\t\tif (c == '\\\\')\n\t\t\t\t{\n\t\t\t\t\tname.Append('\\\\');\n\t\t\t\t}\n\t\t\t\tname.Append(c);\n\t\t\t}\n\t\t}\n\n\t\tpublic void NoForeachOverArray(string[] array)\n\t\t{\n\t\t\tfor (int i = 0; i < array.Length; i++)\n\t\t\t{\n\t\t\t\tstring value = array[i];\n\t\t\t\tif (i % 5 == 0)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic void NestedLoops()\n\t\t{\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tif (i % 2 == 0)\n\t\t\t\t{\n\t\t\t\t\tfor (int j = 0; j < 5; j++)\n\t\t\t\t\t{\n\t\t\t\t\t\tConsole.WriteLine(\"Y\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"X\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic int MultipleExits()\n\t\t{\n\t\t\tint num = 0;\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tif (num % 4 == 0)\n\t\t\t\t{\n\t\t\t\t\treturn 4;\n\t\t\t\t}\n\t\t\t\tif (num % 7 == 0)\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (num % 9 == 0)\n\t\t\t\t{\n\t\t\t\t\treturn 5;\n\t\t\t\t}\n\t\t\t\tif (num % 11 == 0)\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tnum++;\n\t\t\t}\n\t\t\treturn int.MinValue;\n\t\t}\n\n\t\t//public int InterestingLoop()\n\t\t//{\n\t\t//\tint num = 0;\n\t\t//\tif (num % 11 == 0) {\n\t\t//\t\twhile (true) {\n\t\t//\t\t\tif (num % 4 == 0) {\n\t\t//\t\t\t\tif (num % 7 == 0) {\n\t\t//\t\t\t\t\tif (num % 11 == 0) {\n\t\t//\t\t\t\t\t\t// use a continue here to prevent moving the if (i%7) outside the loop\n\t\t//\t\t\t\t\t\tcontinue;\n\t\t//\t\t\t\t\t}\n\t\t//\t\t\t\t\tConsole.WriteLine(\"7\");\n\t\t//\t\t\t\t} else {\n\t\t//\t\t\t\t\t// this block is not part of the natural loop\n\t\t//\t\t\t\t\tConsole.WriteLine(\"!7\");\n\t\t//\t\t\t\t}\n\t\t//\t\t\t\tbreak;\n\t\t//\t\t\t}\n\t\t//\t\t\tnum++;\n\t\t//\t\t}\n\t\t//\t\t// This instruction is still dominated by the loop header\n\t\t//\t\tnum = int.MinValue;\n\t\t//\t}\n\t\t//\treturn num;\n\t\t//}\n\n\t\tpublic int InterestingLoop()\n\t\t{\n\t\t\tint num = 0;\n\t\t\tif (num % 11 == 0)\n\t\t\t{\n\t\t\t\twhile (true)\n\t\t\t\t{\n\t\t\t\t\tif (num % 4 == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (num % 7 != 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tConsole.WriteLine(\"!7\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (num % 11 != 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tConsole.WriteLine(\"7\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tnum++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnum = int.MinValue;\n\t\t\t}\n\t\t\treturn num;\n\t\t}\n\n\t\tprivate bool Condition(string arg)\n\t\t{\n\t\t\tConsole.WriteLine(\"Condition: \" + arg);\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic void WhileLoop()\n\t\t{\n\t\t\tConsole.WriteLine(\"Initial\");\n\t\t\tif (Condition(\"if\"))\n\t\t\t{\n\t\t\t\twhile (Condition(\"while\"))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Loop Body\");\n\t\t\t\t\tif (Condition(\"test\"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (Condition(\"continue\"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!Condition(\"break\"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tConsole.WriteLine(\"End of loop body\");\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(\"After loop\");\n\t\t\t}\n\t\t\tConsole.WriteLine(\"End of method\");\n\t\t}\n\n\t\t//other configurations work fine, just with different labels\n#if OPT && !MCS\n\t\tpublic void WhileWithGoto()\n\t\t{\n\t\t\twhile (Condition(\"Main Loop\"))\n\t\t\t{\n\t\t\t\tif (Condition(\"Condition\"))\n\t\t\t\t{\n\t\t\t\t\tgoto IL_000f;\n\t\t\t\t}\n\t\t\t\t// TODO reorder branches with successive block?\n\t\t\t\tgoto IL_0026;\n\t\t\t\tIL_000f:\n\t\t\t\tConsole.WriteLine(\"Block1\");\n\t\t\t\tif (Condition(\"Condition2\"))\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// TODO remove redundant goto?\n\t\t\t\tgoto IL_0026;\n\t\t\t\tIL_0026:\n\t\t\t\tConsole.WriteLine(\"Block2\");\n\t\t\t\tgoto IL_000f;\n\t\t\t}\n\t\t}\n#endif\n\n\t\tpublic void DoWhileLoop()\n\t\t{\n\t\t\tConsole.WriteLine(\"Initial\");\n\t\t\tif (Condition(\"if\"))\n\t\t\t{\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Loop Body\");\n\t\t\t\t\tif (Condition(\"test\"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (Condition(\"continue\"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!Condition(\"break\"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tConsole.WriteLine(\"End of loop body\");\n\t\t\t\t} while (Condition(\"while\"));\n\t\t\t\tConsole.WriteLine(\"After loop\");\n\t\t\t}\n\t\t\tConsole.WriteLine(\"End of method\");\n\t\t}\n\n\t\tpublic void Issue1395(int count)\n\t\t{\n\t\t\tEnvironment.GetCommandLineArgs();\n\t\t\tfor (int i = 0; i < count; i++)\n\t\t\t{\n\t\t\t\tEnvironment.GetCommandLineArgs();\n\t\t\t\tdo\n\t\t\t\t{\n#if OPT || MCS\n\t\t\t\t\tIL_0013:\n#else\n\t\t\t\t\tIL_0016:\n#endif\n\t\t\t\t\tEnvironment.GetCommandLineArgs();\n\t\t\t\t\tif (Condition(\"part1\"))\n\t\t\t\t\t{\n\t\t\t\t\t\tEnvironment.GetEnvironmentVariables();\n\t\t\t\t\t\tif (Condition(\"restart\"))\n\t\t\t\t\t\t{\n#if OPT || MCS\n\t\t\t\t\t\t\tgoto IL_0013;\n#else\n\t\t\t\t\t\t\tgoto IL_0016;\n#endif\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tEnvironment.GetLogicalDrives();\n\t\t\t\t\t}\n\t\t\t\t\tEnvironment.GetCommandLineArgs();\n\t\t\t\t\twhile (count > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tswitch (count)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase 0:\n\t\t\t\t\t\t\tcase 1:\n\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\tEnvironment.GetCommandLineArgs();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\tcase 5:\n\t\t\t\t\t\t\tcase 6:\n\t\t\t\t\t\t\t\tEnvironment.GetEnvironmentVariables();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tEnvironment.GetLogicalDrives();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcount++;\n\t\t\t\t} while (Condition(\"do-while\"));\n\t\t\t\tEnvironment.GetCommandLineArgs();\n\t\t\t}\n\t\t\tEnvironment.GetCommandLineArgs();\n\t\t}\n\n\t\tpublic void ForLoop()\n\t\t{\n\t\t\tConsole.WriteLine(\"Initial\");\n\t\t\tif (Condition(\"if\"))\n\t\t\t{\n\t\t\t\tfor (int i = 0; Condition(\"for\"); i++)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Loop Body\");\n\t\t\t\t\tif (Condition(\"test\"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (Condition(\"continue\"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!Condition(\"not-break\"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tConsole.WriteLine(\"End of loop body\");\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(\"After loop\");\n\t\t\t}\n\t\t\tConsole.WriteLine(\"End of method\");\n\t\t}\n\n\t\tpublic void ReturnFromDoWhileInTryFinally()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tif (Condition(\"return\"))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t} while (Condition(\"repeat\"));\n\n\t\t\t\tEnvironment.GetCommandLineArgs();\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tEnvironment.GetCommandLineArgs();\n\t\t\t}\n\n\t\t\tEnvironment.GetCommandLineArgs();\n\t\t}\n\n\t\tpublic void ForLoopWithEarlyReturn(int[] ids)\n\t\t{\n\t\t\tfor (int i = 0; i < ids.Length; i++)\n\t\t\t{\n\t\t\t\tItem item = null;\n\t\t\t\tTryGetItem(ids[i], out item);\n\t\t\t\tif (item == null)\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic void ForeachLoopWithEarlyReturn(List<object> items)\n\t\t{\n\t\t\tforeach (object item in items)\n\t\t\t{\n\t\t\t\tif ((someObject = item) == null)\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic void NestedForeach(List<object> items1, List<object> items2)\n\t\t{\n\t\t\tforeach (object item in items1)\n\t\t\t{\n\t\t\t\tbool flag = false;\n\t\t\t\tforeach (object item2 in items2)\n\t\t\t\t{\n\t\t\t\t\tif (item2 == item)\n\t\t\t\t\t{\n\t\t\t\t\t\tflag = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!flag)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(item);\n\t\t\t\t}\n\t\t\t}\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\n\t\tpublic void MergeAroundContinue()\n\t\t{\n\t\t\tfor (int i = 0; i < 20; i++)\n\t\t\t{\n\t\t\t\tif (i % 3 == 0)\n\t\t\t\t{\n\t\t\t\t\tif (i != 6)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (i % 5 == 0)\n\t\t\t\t{\n\t\t\t\t\tif (i != 5)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (i % 7 == 0)\n\t\t\t\t{\n\t\t\t\t\tif (i != 7)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (i % 11 == 0)\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tConsole.WriteLine(i);\n\t\t\t}\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\n\t\tpublic void ForEachInSwitch(int i, IEnumerable<string> args)\n\t\t{\n\t\t\tswitch (i)\n\t\t\t{\n\n\t\t\t\tcase 1:\n\t\t\t\t\tConsole.WriteLine(\"one\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t{\n\t\t\t\t\tforeach (string arg in args)\n\t\t\t\t\t{\n\t\t\t\t\t\tConsole.WriteLine(arg);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/MemberTests.cs",
    "content": "// Copyright (c) 2008 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class MemberTests\n\t{\n\t\tpublic class IndexerNonDefaultName\n\t\t{\n\t\t\t[IndexerName(\"Foo\")]\n#if ROSLYN\n\t\t\tpublic int this[int index] => 0;\n#else\n\t\t\t#pragma warning disable format\n\t\t\tpublic int this[int index] {\n\t\t\t\tget {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\t#pragma warning restore format\n#endif\n\t\t}\n\n\t\t[DefaultMember(\"Bar\")]\n\t\tpublic class NoDefaultMember\n\t\t{\n\t\t}\n\n\t\tpublic const int IntConstant = 1;\n\t\tpublic const decimal DecimalConstant = 2m;\n\n\t\tprivate volatile int volatileField = 3;\n\t\tprivate static volatile int staticVolatileField = 4;\n\n\t\tpublic extern int ExternGetOnly { get; }\n\t\tpublic extern int ExternSetOnly { set; }\n\t\tpublic extern int ExternProperty { get; set; }\n\n\t\tpublic extern event EventHandler Event;\n\n\t\tpublic void UseVolatileFields()\n\t\t{\n\t\t\tConsole.WriteLine(volatileField + staticVolatileField);\n\t\t\tvolatileField++;\n\t\t\tstaticVolatileField++;\n\t\t}\n\n\t\tpublic extern void ExternMethod();\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/MetadataAttributes.cs",
    "content": "using System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class MetadataAttributes\n\t{\n\t\tprivate class MethodImplAttr\n\t\t{\n\t\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\t\tpublic extern void A();\n#if !NET40 && ROSLYN3\n\t\t\t[MethodImpl(MethodImplOptions.AggressiveOptimization)]\n\t\t\tpublic extern void B();\n#endif\n\t\t\t[MethodImpl(MethodImplOptions.ForwardRef)]\n\t\t\tpublic extern void D();\n\t\t\t[MethodImpl(MethodImplOptions.InternalCall)]\n\t\t\tpublic extern void E();\n\t\t\t[MethodImpl(MethodImplOptions.NoInlining)]\n\t\t\tpublic extern void F();\n\t\t\t[MethodImpl(MethodImplOptions.NoOptimization)]\n\t\t\tpublic extern void G();\n\t\t\t[PreserveSig]\n\t\t\tpublic extern void H();\n\t\t\t[MethodImpl(MethodImplOptions.Synchronized)]\n\t\t\tpublic extern void I();\n\t\t\t[MethodImpl(MethodImplOptions.Unmanaged)]\n\t\t\tpublic extern void J();\n\t\t\t[MethodImpl(MethodImplOptions.AggressiveInlining, MethodCodeType = MethodCodeType.Native)]\n\t\t\tpublic extern void A1();\n#if !NET40 && ROSLYN3\n\t\t\t[MethodImpl(MethodImplOptions.AggressiveOptimization, MethodCodeType = MethodCodeType.Native)]\n\t\t\tpublic extern void B1();\n#endif\n\t\t\t[MethodImpl(MethodImplOptions.ForwardRef, MethodCodeType = MethodCodeType.Native)]\n\t\t\tpublic extern void D1();\n\t\t\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Native)]\n\t\t\tpublic extern void E1();\n\t\t\t[MethodImpl(MethodImplOptions.NoInlining, MethodCodeType = MethodCodeType.Native)]\n\t\t\tpublic extern void F1();\n\t\t\t[MethodImpl(MethodImplOptions.NoOptimization, MethodCodeType = MethodCodeType.Native)]\n\t\t\tpublic extern void G1();\n\t\t\t[MethodImpl(MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Native)]\n\t\t\tpublic extern void H1();\n\t\t\t[MethodImpl(MethodImplOptions.Synchronized, MethodCodeType = MethodCodeType.Native)]\n\t\t\tpublic extern void I1();\n\t\t\t[MethodImpl(MethodImplOptions.Unmanaged, MethodCodeType = MethodCodeType.Native)]\n\t\t\tpublic extern void J1();\n\t\t\t[MethodImpl(MethodImplOptions.AggressiveInlining, MethodCodeType = MethodCodeType.OPTIL)]\n\t\t\tpublic extern void A2();\n#if !NET40 && ROSLYN3\n\t\t\t[MethodImpl(MethodImplOptions.AggressiveOptimization, MethodCodeType = MethodCodeType.OPTIL)]\n\t\t\tpublic extern void B2();\n#endif\n\t\t\t[MethodImpl(MethodImplOptions.ForwardRef, MethodCodeType = MethodCodeType.OPTIL)]\n\t\t\tpublic extern void D2();\n\t\t\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.OPTIL)]\n\t\t\tpublic extern void E2();\n\t\t\t[MethodImpl(MethodImplOptions.NoInlining, MethodCodeType = MethodCodeType.OPTIL)]\n\t\t\tpublic extern void F2();\n\t\t\t[MethodImpl(MethodImplOptions.NoOptimization, MethodCodeType = MethodCodeType.OPTIL)]\n\t\t\tpublic extern void G2();\n\t\t\t[MethodImpl(MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.OPTIL)]\n\t\t\tpublic extern void H2();\n\t\t\t[MethodImpl(MethodImplOptions.Synchronized, MethodCodeType = MethodCodeType.OPTIL)]\n\t\t\tpublic extern void I2();\n\t\t\t[MethodImpl(MethodImplOptions.Unmanaged, MethodCodeType = MethodCodeType.OPTIL)]\n\t\t\tpublic extern void J2();\n\t\t\t[MethodImpl(MethodImplOptions.AggressiveInlining, MethodCodeType = MethodCodeType.OPTIL)]\n\t\t\tpublic extern void A3();\n#if !NET40 && ROSLYN3\n\t\t\t[MethodImpl(MethodImplOptions.AggressiveOptimization, MethodCodeType = MethodCodeType.Runtime)]\n\t\t\tpublic extern void B3();\n#endif\n\t\t\t[MethodImpl(MethodImplOptions.ForwardRef, MethodCodeType = MethodCodeType.Runtime)]\n\t\t\tpublic extern void D3();\n\t\t\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]\n\t\t\tpublic extern void E3();\n\t\t\t[MethodImpl(MethodImplOptions.NoInlining, MethodCodeType = MethodCodeType.Runtime)]\n\t\t\tpublic extern void F3();\n\t\t\t[MethodImpl(MethodImplOptions.NoOptimization, MethodCodeType = MethodCodeType.Runtime)]\n\t\t\tpublic extern void G3();\n\t\t\t[MethodImpl(MethodImplOptions.PreserveSig, MethodCodeType = MethodCodeType.Runtime)]\n\t\t\tpublic extern void H3();\n\t\t\t[MethodImpl(MethodImplOptions.Synchronized, MethodCodeType = MethodCodeType.Runtime)]\n\t\t\tpublic extern void I3();\n\t\t\t[MethodImpl(MethodImplOptions.Unmanaged, MethodCodeType = MethodCodeType.Runtime)]\n\t\t\tpublic extern void J3();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/MultidimensionalArray.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class MultidimensionalArray\n\t{\n\t\tinternal class Generic<T, S> where T : new()\n\t\t{\n\t\t\tprivate T[,] a = new T[20, 20];\n\t\t\tprivate S[,][] b = new S[20, 20][];\n\n\t\t\tpublic T this[int i, int j] {\n\t\t\t\tget {\n\t\t\t\t\treturn a[i, j];\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t\ta[i, j] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic void TestB(S x, ref S y)\n\t\t\t{\n\t\t\t\tb[5, 3] = new S[10];\n\t\t\t\tb[5, 3][0] = default(S);\n\t\t\t\tb[5, 3][1] = x;\n\t\t\t\tb[5, 3][2] = y;\n\t\t\t}\n\n\t\t\tpublic void PassByReference(ref T arr)\n\t\t\t{\n\t\t\t\tPassByReference(ref a[10, 10]);\n\t\t\t}\n\t\t}\n\n\t\tpublic int[][,] MakeArray()\n\t\t{\n\t\t\treturn new int[10][,];\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/NamedArguments.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class NamedArguments\n\t{\n\t\tprivate class ClassWithNamedArgCtor\n\t\t{\n\t\t\tinternal ClassWithNamedArgCtor(bool arg1 = false, bool arg2 = false)\n\t\t\t{\n\t\t\t}\n\n\t\t\tinternal ClassWithNamedArgCtor()\n\t\t\t\t: this(arg2: Get(1) != 1, arg1: Get(2) == 2)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tprivate class MustNotUseNamedArgsInCtor\n\t\t{\n\t\t\tpublic MustNotUseNamedArgsInCtor(string start = \"\", bool enable = false)\n\t\t\t{\n\t\t\t}\n\n\t\t\tpublic MustNotUseNamedArgsInCtor(bool enable, string start = \"\")\n\t\t\t{\n\t\t\t}\n\n\t\t\tpublic static MustNotUseNamedArgsInCtor Use()\n\t\t\t{\n\t\t\t\t// second overload\n\t\t\t\tMustNotUseNamedArgsInCall(true);\n\t\t\t\t// first overload\n\t\t\t\tMustNotUseNamedArgsInCall();\n\t\t\t\treturn new MustNotUseNamedArgsInCtor(true);\n\t\t\t}\n\n\t\t\tpublic static void MustNotUseNamedArgsInCall(string start = \"\", bool enable = false)\n\t\t\t{\n\t\t\t}\n\n\t\t\tpublic static void MustNotUseNamedArgsInCall(bool enable, string start = \"\")\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic void Use(int a, int b, int c)\n\t\t{\n\t\t}\n\n\t\tpublic static int Get(int i)\n\t\t{\n\t\t\treturn i;\n\t\t}\n\n\t\tpublic void Test()\n\t\t{\n\t\t\tUse(Get(1), Get(2), Get(3));\n\t\t\tUse(Get(1), c: Get(2), b: Get(3));\n\t\t\tUse(b: Get(1), a: Get(2), c: Get(3));\n\t\t}\n\n\t\tpublic void NotNamedArgs()\n\t\t{\n\t\t\tint b = Get(1);\n\t\t\tUse(Get(2), b, Get(3));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/NativeInts.cs",
    "content": "// Copyright (c) 2020 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class NativeInts\n\t{\n\t\tprivate const nint nint_const = 42;\n\t\tprivate const nuint nuint_const = 99u;\n\n#if CS110 && NET70\n\t\t// C#11 on .NET7 no longer uses NativeIntegerAttribute,\n\t\t// instead nint+IntPtr are considered to be the same type.\n\t\tprivate nint intptr;\n\t\tprivate nuint uintptr;\n#else\n\t\tprivate IntPtr intptr;\n\t\tprivate UIntPtr uintptr;\n#endif\n\t\tprivate nint i;\n\t\tprivate nuint u;\n\t\tprivate int i32;\n\t\tprivate uint u32;\n\t\tprivate long i64;\n\t\tprivate ulong u64;\n#if !(CS110 && NET70)\n\t\tprivate (IntPtr, nint, UIntPtr, nuint) tuple_field;\n\t\tprivate (object, int, IntPtr, nint, UIntPtr, nuint) tuple_field2;\n\t\tprivate Dictionary<nint, IntPtr> dict1;\n\t\tprivate Dictionary<IntPtr, nint> dict2;\n\t\tprivate Dictionary<IntPtr?, nint?> dict3;\n\t\tprivate Dictionary<IntPtr, nint[]> dict4;\n#endif\n\t\tprivate Dictionary<nuint, nint[]> dict5;\n\n\t\tpublic void Convert()\n\t\t{\n\t\t\ti = (nint)u;\n\t\t\tu = (nuint)i;\n#if !(CS110 && NET70)\n\t\t\tintptr = i;\n\t\t\tintptr = (nint)u;\n\t\t\tintptr = (nint)(nuint)uintptr;\n\n\t\t\tuintptr = (nuint)i;\n\t\t\tuintptr = u;\n\t\t\tuintptr = (nuint)(nint)intptr;\n\n\t\t\ti = intptr;\n\t\t\ti = (nint)u;\n\t\t\ti = (nint)(nuint)uintptr;\n\n\t\t\tu = (nuint)i;\n\t\t\tu = uintptr;\n\t\t\tu = (nuint)(nint)intptr;\n#endif\n\t\t}\n\n\t\tpublic void Convert2()\n\t\t{\n\t\t\ti32 = (int)i;\n\t\t\ti = i32;\n#if !(CS110 && NET70)\n\t\t\tintptr = (IntPtr)i32;\n\n\t\t\ti64 = (long)intptr;\n#endif\n\t\t\ti64 = i;\n\t\t\ti = (nint)i64;\n\n\t\t\tu32 = (uint)i;\n\t\t\ti = (nint)u32;\n\n\t\t\tu64 = (uint)i;\n\t\t\ti = (nint)u64;\n\t\t}\n\n\t\tpublic void Arithmetic()\n\t\t{\n#if !(CS110 && NET70)\n\t\t\tConsole.WriteLine((nint)intptr * 2);\n#endif\n\t\t\tConsole.WriteLine(i * 2);\n\n\t\t\tConsole.WriteLine(i + (nint)u);\n\t\t\tConsole.WriteLine((nuint)i + u);\n\t\t}\n\n\t\tpublic void Shifts()\n\t\t{\n\t\t\tConsole.WriteLine(i << i32);\n\t\t\tConsole.WriteLine(i >> i32);\n\t\t\tConsole.WriteLine(u >> i32);\n\t\t\tConsole.WriteLine(u << i32);\n\t\t}\n\n\t\tpublic void Comparisons()\n\t\t{\n\t\t\tConsole.WriteLine(i < i32);\n\t\t\tConsole.WriteLine(i <= i32);\n\t\t\tConsole.WriteLine(i > i32);\n\t\t\tConsole.WriteLine(i >= i32);\n\t\t\tConsole.WriteLine(i == (nint)u);\n\t\t\tConsole.WriteLine(i < (nint)u);\n\t\t\tConsole.WriteLine((nuint)i < u);\n\t\t}\n\n\t\tpublic void Unary()\n\t\t{\n\t\t\tConsole.WriteLine(~i);\n\t\t\tConsole.WriteLine(~u);\n\t\t\tConsole.WriteLine(-i);\n\t\t}\n\n\t\tpublic unsafe int* PtrArithmetic(int* ptr)\n\t\t{\n\t\t\treturn ptr + i;\n\t\t}\n\n\t\tpublic unsafe nint* PtrArithmetic(nint* ptr)\n\t\t{\n\t\t\treturn ptr + u;\n\t\t}\n\n\t\tpublic object[] Boxing()\n\t\t{\n\t\t\treturn new object[10] {\n\t\t\t\t1,\n\t\t\t\t(nint)2,\n\t\t\t\t3L,\n\t\t\t\t4u,\n\t\t\t\t(nuint)5u,\n\t\t\t\t6uL,\n\t\t\t\tint.MaxValue,\n\t\t\t\t(nint)int.MaxValue,\n\t\t\t\ti64,\n\t\t\t\t(nint)i64\n\t\t\t};\n\t\t}\n\n\t\tpublic NativeInts GetInstance(int i)\n\t\t{\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic void CompoundAssign()\n\t\t{\n\t\t\tGetInstance(0).i += i32;\n\t\t\tchecked\n\t\t\t{\n\t\t\t\tGetInstance(1).i += i32;\n\t\t\t}\n\t\t\tGetInstance(2).u *= 2u;\n\t\t\tchecked\n\t\t\t{\n\t\t\t\tGetInstance(3).u *= 2u;\n\t\t\t}\n#if !(CS110 && NET70)\n\t\t\tGetInstance(4).intptr += (nint)i32;\n\t\t\tchecked\n\t\t\t{\n\t\t\t\t// Note: the cast is necessary here, without it we'd call IntPtr.op_Addition\n\t\t\t\t// but that is always unchecked.\n\t\t\t\tGetInstance(5).intptr += (nint)i32;\n\t\t\t}\n\t\t\t// multiplication results in compiler-error without the cast\n\t\t\tGetInstance(6).intptr *= (nint)2;\n#endif\n\n\t\t\tGetInstance(7).i += i32;\n\t\t\tGetInstance(8).i <<= i32;\n\t\t}\n\n#if !(CS110 && NET70)\n\t\tpublic void LocalTypeFromStore()\n\t\t{\n\t\t\tnint num = 42;\n\t\t\tIntPtr zero = IntPtr.Zero;\n\t\t\tnint zero2 = IntPtr.Zero;\n\t\t\tnuint num2 = 43u;\n\t\t\tnint num3 = i;\n\t\t\tIntPtr intPtr = intptr;\n\n\t\t\tConsole.WriteLine();\n\t\t\tzero2 = 1;\n\t\t\tConsole.WriteLine();\n\n\t\t\tintptr = num;\n\t\t\tintptr = zero;\n\t\t\tintptr = zero2;\n\t\t\tuintptr = num2;\n\t\t\tintptr = num3;\n\t\t\tintptr = intPtr;\n\t\t}\n#endif\n\n\t\tpublic void LocalTypeFromUse()\n\t\t{\n#if CS110 && NET70\n\t\t\tnint num = intptr;\n\t\t\tnint num2 = intptr;\n\n\t\t\tConsole.WriteLine();\n\n\t\t\tintptr = num;\n\t\t\ti = num2 + 1;\n#else\n\t\t\tIntPtr intPtr = intptr;\n\t\t\tnint num = intptr;\n\n\t\t\tConsole.WriteLine();\n\n\t\t\tintptr = intPtr;\n\t\t\ti = num + 1;\n#endif\n\t\t}\n\n\t\tpublic nint NegateUnsigned(nuint x)\n\t\t{\n\t\t\treturn (nint)(0 - x);\n\t\t}\n\n\t\tpublic bool CompareToMinus3(nuint x)\n\t\t{\n\t\t\treturn x == unchecked((nuint)(-3));\n\t\t}\n\n\t\tpublic nint SignedNotFittingIn32Bits()\n\t\t{\n\t\t\t// Explicit `unchecked` is necessary when casting oversized constant to nint\n\t\t\treturn unchecked((nint)9123123123123L);\n\t\t}\n\n\t\tpublic nuint UnsignedNotFittingIn32Bits()\n\t\t{\n\t\t\t// Explicit `unchecked` is necessary when casting oversized constant to nuint\n\t\t\treturn unchecked((nuint)9123123123123uL);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullPropagation.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class NullPropagation\n\t{\n\t\tprivate class MyClass\n\t\t{\n\t\t\tpublic int IntVal;\n\t\t\tpublic readonly int ReadonlyIntVal;\n\t\t\tpublic MyStruct StructField;\n\t\t\tpublic readonly MyStruct ReadonlyStructField;\n\t\t\tpublic string Text;\n\t\t\tpublic MyClass Field;\n\t\t\tpublic MyClass Property { get; set; }\n\t\t\tpublic MyClass this[int index] => null;\n\t\t\tpublic MyClass Method(int arg)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tpublic void Done()\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tprivate struct MyStruct\n\t\t{\n\t\t\tpublic int IntVal;\n\t\t\tpublic readonly int ReadonlyIntVal;\n\t\t\tpublic MyClass Field;\n\t\t\tpublic MyStruct? Property1 => null;\n\t\t\tpublic MyStruct Property2 => default(MyStruct);\n\t\t\tpublic MyStruct? this[int index] => null;\n\t\t\tpublic MyStruct? Method1(int arg)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tpublic MyStruct Method2(int arg)\n\t\t\t{\n\t\t\t\treturn default(MyStruct);\n\t\t\t}\n\n\t\t\tpublic void Done()\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tprivate class Container<T1, T2>\n\t\t{\n\t\t\tpublic GenericStruct<T1, T2> Other;\n\t\t}\n\n\t\tprivate struct GenericStruct<T1, T2>\n\t\t{\n\t\t\tpublic T1 Field1;\n\t\t\tpublic T2 Field2;\n\t\t\tpublic Container<T1, T2> Other;\n\n\t\t\tpublic override string ToString()\n\t\t\t{\n\t\t\t\treturn \"(\" + Field1?.ToString() + \", \" + Field2?.ToString() + \")\";\n\t\t\t}\n\n\t\t\tpublic int? GetTextLength()\n\t\t\t{\n\t\t\t\treturn Field1?.ToString().Length + Field2?.ToString().Length + 4;\n\t\t\t}\n\n\t\t\tpublic string Chain1()\n\t\t\t{\n\t\t\t\treturn Other?.Other.Other?.Other.Field1?.ToString();\n\t\t\t}\n\n\t\t\tpublic string Chain2()\n\t\t\t{\n\t\t\t\treturn Other?.Other.Other?.Other.Field1?.ToString()?.GetType().Name;\n\t\t\t}\n\n\t\t\tpublic int? Test2()\n\t\t\t{\n\t\t\t\treturn Field1?.ToString().Length ?? 42;\n\t\t\t}\n\n\t\t\tpublic int? GetTextLengthNRE()\n\t\t\t{\n\t\t\t\treturn (Field1?.ToString()).Length;\n\t\t\t}\n\t\t}\n\n\t\tpublic interface ITest\n\t\t{\n\t\t\tint Int();\n\t\t\tITest Next();\n\t\t}\n\n\t\tprivate int GetInt()\n\t\t{\n\t\t\treturn 9;\n\t\t}\n\n\t\tprivate string GetString()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tprivate MyClass GetMyClass()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tprivate MyStruct? GetMyStruct()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic string Substring()\n\t\t{\n\t\t\treturn GetString()?.Substring(GetInt());\n\t\t}\n\n\t\tpublic void CallSubstringAndIgnoreResult()\n\t\t{\n\t\t\tGetString()?.Substring(GetInt());\n\t\t}\n\n\t\tprivate void Use<T>(T t)\n\t\t{\n\t\t}\n\n\t\tpublic void CallDone()\n\t\t{\n\t\t\tGetMyClass()?.Done();\n\t\t\tGetMyClass()?.Field?.Done();\n\t\t\tGetMyClass()?.Field.Done();\n\t\t\tGetMyClass()?.Property?.Done();\n\t\t\tGetMyClass()?.Property.Done();\n\t\t\tGetMyClass()?.Method(GetInt())?.Done();\n\t\t\tGetMyClass()?.Method(GetInt()).Done();\n\t\t\tGetMyClass()?[GetInt()]?.Done();\n\t\t\tGetMyClass()?[GetInt()].Done();\n\t\t}\n\n\t\tpublic void CallDoneStruct()\n\t\t{\n\t\t\tGetMyStruct()?.Done();\n\t\t\tGetMyStruct()?.Field?.Done();\n\t\t\tGetMyStruct()?.Field.Done();\n\t\t\tGetMyStruct()?.Property1?.Done();\n\t\t\tGetMyStruct()?.Property2.Done();\n\t\t\tGetMyStruct()?.Method1(GetInt())?.Done();\n\t\t\tGetMyStruct()?.Method2(GetInt()).Done();\n\t\t\tGetMyStruct()?[GetInt()]?.Done();\n\t\t}\n\n\t\tpublic void RequiredParentheses()\n\t\t{\n\t\t\t(GetMyClass()?.Field).Done();\n\t\t\t(GetMyClass()?.Method(GetInt())).Done();\n\t\t\t(GetMyStruct()?.Property2)?.Done();\n\t\t}\n\n\t\tpublic int?[] ChainsOnClass()\n\t\t{\n\t\t\treturn new int?[9] {\n\t\t\t\tGetMyClass()?.IntVal,\n\t\t\t\tGetMyClass()?.Field.IntVal,\n\t\t\t\tGetMyClass()?.Field?.IntVal,\n\t\t\t\tGetMyClass()?.Property.IntVal,\n\t\t\t\tGetMyClass()?.Property?.IntVal,\n\t\t\t\tGetMyClass()?.Method(GetInt()).IntVal,\n\t\t\t\tGetMyClass()?.Method(GetInt())?.IntVal,\n\t\t\t\tGetMyClass()?[GetInt()].IntVal,\n\t\t\t\tGetMyClass()?[GetInt()]?.IntVal\n\t\t\t};\n\t\t}\n\n\t\tpublic int?[] ChainsStruct()\n\t\t{\n\t\t\treturn new int?[8] {\n\t\t\t\tGetMyStruct()?.IntVal,\n\t\t\t\tGetMyStruct()?.Field.IntVal,\n\t\t\t\tGetMyStruct()?.Field?.IntVal,\n\t\t\t\tGetMyStruct()?.Property2.IntVal,\n\t\t\t\tGetMyStruct()?.Property1?.IntVal,\n\t\t\t\tGetMyStruct()?.Method2(GetInt()).IntVal,\n\t\t\t\tGetMyStruct()?.Method1(GetInt())?.IntVal,\n\t\t\t\tGetMyStruct()?[GetInt()]?.IntVal\n\t\t\t};\n\t\t}\n\n\t\tpublic int CoalescingReturn()\n\t\t{\n\t\t\treturn GetMyClass()?.IntVal ?? 1;\n\t\t}\n\n\t\tpublic void Coalescing()\n\t\t{\n\t\t\tUse(GetMyClass()?.IntVal ?? 1);\n\t\t}\n\n\t\tpublic void CoalescingString()\n\t\t{\n\t\t\tUse(GetMyClass()?.Text ?? \"Hello\");\n\t\t}\n\n\t\tpublic void CallOnValueTypeField()\n\t\t{\n\t\t\tUse(GetMyClass()?.IntVal.ToString());\n\t\t\tUse(GetMyStruct()?.IntVal.ToString());\n\t\t\tUse(GetMyClass()?.ReadonlyIntVal.ToString());\n\t\t\tUse(GetMyStruct()?.ReadonlyIntVal.ToString());\n\t\t\tGetMyClass()?.StructField.Done();\n\t\t\tGetMyClass()?.ReadonlyStructField.Done();\n\t\t}\n\n\t\tpublic void InvokeDelegate(EventHandler eh)\n\t\t{\n\t\t\teh?.Invoke(null, EventArgs.Empty);\n\t\t}\n\n\t\tpublic int? InvokeDelegate(Func<int> f)\n\t\t{\n\t\t\treturn f?.Invoke();\n\t\t}\n\n\t\tprivate void NotNullPropagation(MyClass c)\n\t\t{\n\t\t\t// don't decompile this to \"(c?.IntVal ?? 0) != 0\"\n\t\t\tif (c != null && c.IntVal != 0)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"non-zero\");\n\t\t\t}\n\t\t\tif (c == null || c.IntVal == 0)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"null or zero\");\n\t\t\t}\n\t\t\tConsole.WriteLine(\"end of method\");\n\t\t}\n\n\t\tprivate void Setter(MyClass c)\n\t\t{\n\t\t\tif (c != null)\n\t\t\t{\n\t\t\t\tc.IntVal = 1;\n\t\t\t}\n\t\t\tConsole.WriteLine();\n\t\t\tif (c != null)\n\t\t\t{\n\t\t\t\tc.Property = null;\n\t\t\t}\n\t\t}\n\n\t\tprivate static int? GenericUnconstrainedInt<T>(T t) where T : ITest\n\t\t{\n\t\t\treturn t?.Int();\n\t\t}\n\n\t\tprivate static int? GenericClassConstraintInt<T>(T t) where T : class, ITest\n\t\t{\n\t\t\treturn t?.Int();\n\t\t}\n\n\t\tprivate static int? GenericStructConstraintInt<T>(T? t) where T : struct, ITest\n\t\t{\n\t\t\treturn t?.Int();\n\t\t}\n\n\t\tprivate static int? GenericRefUnconstrainedInt<T>(ref T t) where T : ITest\n\t\t{\n\t\t\treturn t?.Int();\n\t\t}\n\n\t\tprivate static int? GenericRefClassConstraintInt<T>(ref T t) where T : class, ITest\n\t\t{\n\t\t\treturn t?.Int();\n\t\t}\n\n\t\tprivate static int? GenericRefStructConstraintInt<T>(ref T? t) where T : struct, ITest\n\t\t{\n\t\t\treturn t?.Int();\n\t\t}\n\n\t\tpublic int? Issue1709(object obj)\n\t\t{\n\t\t\treturn (obj as ICollection)?.Count + (obj as ICollection<int>)?.Count;\n\t\t}\n\n\t\tprivate static void Issue1689(List<byte[]> setsOfNumbers)\n\t\t{\n\t\t\tConsole.WriteLine(setsOfNumbers?[0]?[1].ToString() == \"2\");\n\t\t\tConsole.WriteLine(setsOfNumbers?[1]?[1].ToString() == null);\n\t\t}\n\n\t\tprivate static dynamic DynamicNullProp(dynamic a)\n\t\t{\n\t\t\treturn a?.b.c(1)?.d[10];\n\t\t}\n\n\t\tprivate static string Issue3181()\n\t\t{\n#if EXPECTED_OUTPUT\n\t\t\treturn ((int?)null)?.ToString();\n#else\n\t\t\tint? x = null;\n\t\t\treturn x?.ToString();\n#endif\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullableRefTypes.cs",
    "content": "#nullable enable\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class T01_NullableRefTypes\n\t{\n\t\tprivate string field_string;\n\t\tprivate string? field_nullable_string;\n\t\tprivate dynamic? field_nullable_dynamic;\n\n\t\tprivate Dictionary<string?, string> field_generic;\n\t\tprivate Dictionary<int, string?[]> field_generic2;\n\t\tprivate Dictionary<int?, string?[]> field_generic3;\n\t\tprivate KeyValuePair<string?, string> field_generic_value_type;\n\t\tprivate KeyValuePair<string?, string>? field_generic_nullable_value_type;\n\t\tprivate (string, string?, string) field_tuple;\n\t\tprivate string[]?[] field_array;\n\t\tprivate Dictionary<(string, string?), (int, string[]?, string?[])> field_complex;\n\t\tprivate dynamic[][,]?[,,][,,,] field_complex_nested_array;\n\n\t\tpublic (string A, dynamic? B) PropertyNamedTuple {\n\t\t\tget {\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n\n\t\tpublic (string A, dynamic? B) this[(dynamic? C, string D) weirdIndexer] {\n\t\t\tget {\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n\n\t\tpublic int GetLength1(string[] arr)\n\t\t{\n\t\t\treturn field_string.Length + arr.Length;\n\t\t}\n\n\t\tpublic int GetLength2(string[]? arr)\n\t\t{\n\t\t\treturn field_nullable_string.Length + arr.Length;\n\t\t}\n\n\t\tpublic int? GetLength3(string[]? arr)\n\t\t{\n\t\t\treturn field_nullable_string?.Length + arr?.Length;\n\t\t}\n\n\t\tpublic void GenericNullable<T1, T2>((T1?, T1, T2, T2?, T1, T1?) x) where T1 : class where T2 : struct\n\t\t{\n\t\t}\n\n\t\tpublic T ByRef<T>(ref T t)\n\t\t{\n\t\t\treturn t;\n\t\t}\n\n\t\tpublic void CallByRef(ref string a, ref string? b)\n\t\t{\n\t\t\tByRef(ref a).ToString();\n\t\t\tByRef(ref b).ToString();\n\t\t}\n\n\t\tpublic void Constraints<UC, C, CN, NN, S, SN, D, DN, NND>() where C : class where CN : class? where NN : notnull where S : struct where D : IDisposable where DN : IDisposable? where NND : notnull, IDisposable\n\t\t{\n\t\t}\n\t}\n\n\tpublic class T02_EverythingIsNullableInHere\n\t{\n\t\tprivate string? field1;\n\t\tprivate object? field2;\n\t\t// value types are irrelevant for the nullability attributes:\n\t\tprivate int field3;\n\t\tprivate int? field4;\n\n\t\tpublic string? Property { get; set; }\n\t\tpublic event EventHandler? Event;\n\n\t\tpublic static int? NullConditionalOperator(T02_EverythingIsNullableInHere? x)\n\t\t{\n\t\t\t// This code throws if `x != null && x.field1 == null`.\n\t\t\t// But we can't decompile it to the warning-free \"x?.field1!.Length\",\n\t\t\t// because of https://github.com/dotnet/roslyn/issues/43659\n\t\t\treturn x?.field1.Length;\n\t\t}\n\t}\n\n\tpublic class T03_EverythingIsNotNullableInHere\n\t{\n\t\tprivate string field1;\n\t\tprivate object field2;\n\t\t// value types are irrelevant for the nullability attributes:\n\t\tprivate int field3;\n\t\tprivate int? field4;\n\n\t\tpublic string Property { get; set; }\n\t\tpublic event EventHandler Event;\n\t}\n\n\tpublic class T04_Dictionary<TKey, TValue> where TKey : notnull\n\t{\n\t\tprivate struct Entry\n\t\t{\n\t\t\tpublic TKey key;\n\t\t\tpublic TValue value;\n\t\t}\n\n\t\tprivate int[]? _buckets;\n\t\tprivate Entry[]? _entries;\n\t\tprivate IEqualityComparer<TKey>? _comparer;\n\t}\n\n\tpublic class T05_NullableUnconstrainedGeneric\n\t{\n\t\tpublic static TValue? Default<TValue>()\n\t\t{\n\t\t\treturn default(TValue);\n\t\t}\n\n\t\tpublic static void CallDefault()\n\t\t{\n#if OPT\n\t\t\tstring? format = Default<string>();\n#else\n\t\t\t// With optimizations it's a stack slot, so ILSpy picks a nullable type.\n\t\t\t// Without optimizations it's a local, so the nullability is missing.\n\t\t\tstring format = Default<string>();\n#endif\n\t\t\tint num = Default<int>();\n#if CS110 && NET70\n\t\t\tnint num2 = Default<nint>();\n#else\n\t\t\tint num2 = Default<int>();\n#endif\n\t\t\t(object, string) tuple = Default<(object, string)>();\n\t\t\tConsole.WriteLine(\"No inlining\");\n\t\t\tConsole.WriteLine(format, num, num2, tuple);\n\t\t}\n\t}\n\n\tpublic class T06_ExplicitInterfaceImplementation : IEnumerable<KeyValuePair<string, string?>>, IEnumerable\n\t{\n\t\t// TODO: declaring type is not yet rendered with nullability annotations from the base type\n\t\tIEnumerator<KeyValuePair<string, string?>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator()\n\t\t{\n\t\t\tyield return new KeyValuePair<string, string>(\"a\", \"b\");\n\t\t}\n\n\t\tIEnumerator IEnumerable.GetEnumerator()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\t}\n\n\tpublic class T07_ExplicitInterfaceImplementation : IEnumerator<KeyValuePair<string, string?>>, IEnumerator, IDisposable\n\t{\n\t\tKeyValuePair<string, string?> IEnumerator<KeyValuePair<string, string>>.Current {\n\t\t\tget {\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n\n\t\tobject IEnumerator.Current {\n\t\t\tget {\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n\n\t\tvoid IDisposable.Dispose()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tbool IEnumerator.MoveNext()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tvoid IEnumerator.Reset()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Operators.cs",
    "content": "// Copyright (c) Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class AllOperators\n\t{\n\t\tpublic static AllOperators operator +(AllOperators a, AllOperators b)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static AllOperators operator -(AllOperators a, AllOperators b)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static AllOperators operator *(AllOperators a, AllOperators b)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static AllOperators operator /(AllOperators a, AllOperators b)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n#if CS110\n\t\tpublic static AllOperators operator checked +(AllOperators a, AllOperators b)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static AllOperators operator checked -(AllOperators a, AllOperators b)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static AllOperators operator checked *(AllOperators a, AllOperators b)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static AllOperators operator checked /(AllOperators a, AllOperators b)\n\t\t{\n\t\t\treturn null;\n\t\t}\n#endif\n\n\t\tpublic static AllOperators operator %(AllOperators a, AllOperators b)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static AllOperators operator &(AllOperators a, AllOperators b)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static AllOperators operator |(AllOperators a, AllOperators b)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static AllOperators operator ^(AllOperators a, AllOperators b)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static AllOperators operator <<(AllOperators a, int b)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static AllOperators operator >>(AllOperators a, int b)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n#if CS110\n        public static AllOperators operator >>>(AllOperators a, int b)\n        {\n            return null;\n        }\n#endif\n\n\t\tpublic static AllOperators operator ~(AllOperators a)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static AllOperators operator !(AllOperators a)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static AllOperators operator -(AllOperators a)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static AllOperators operator +(AllOperators a)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static AllOperators operator ++(AllOperators a)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static AllOperators operator --(AllOperators a)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n#if CS110\n\t\tpublic static AllOperators operator checked -(AllOperators a)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static AllOperators operator checked ++(AllOperators a)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static AllOperators operator checked --(AllOperators a)\n\t\t{\n\t\t\treturn null;\n\t\t}\n#endif\n\n\t\tpublic static bool operator true(AllOperators a)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool operator false(AllOperators a)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool operator ==(AllOperators a, AllOperators b)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool operator !=(AllOperators a, AllOperators b)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool operator <(AllOperators a, AllOperators b)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool operator >(AllOperators a, AllOperators b)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool operator <=(AllOperators a, AllOperators b)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool operator >=(AllOperators a, AllOperators b)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static implicit operator AllOperators(int a)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static explicit operator int(AllOperators a)\n\t\t{\n\t\t\treturn 0;\n\t\t}\n\n#if CS110\n\t\tpublic static explicit operator checked int(AllOperators a)\n\t\t{\n\t\t\treturn 0;\n\t\t}\n#endif\n\t}\n\n\tpublic class UseAllOperators\n\t{\n\t\tprivate AllOperators a = new AllOperators();\n\t\tprivate AllOperators b = new AllOperators();\n\t\tprivate AllOperators c;\n\t\tpublic void Test()\n\t\t{\n\t\t\tc = a + b;\n\t\t\tc = a - b;\n\t\t\tc = a * b;\n\t\t\tc = a / b;\n#if CS110\n\t\t\tchecked\n\t\t\t{\n\t\t\t\tc = a + b;\n\t\t\t\tc = a - b;\n\t\t\t\tc = a * b;\n\t\t\t\tc = a / b;\n\t\t\t}\n\t\t\t// force end of checked block:\n\t\t\t++a;\n#endif\n\n\t\t\tc = a % b;\n\t\t\tc = a & b;\n\t\t\tc = a | b;\n\t\t\tc = a ^ b;\n\t\t\tc = a << 5;\n\t\t\tc = a >> 5;\n#if CS110\n            c = a >>> 5;\n#endif\n\t\t\tc = ~a;\n\t\t\tc = !a;\n\t\t\tc = -a;\n\t\t\tc = +a;\n\t\t\tc = ++a;\n\t\t\tc = --a;\n#if CS110\n\t\t\tchecked\n\t\t\t{\n\t\t\t\tc = -a;\n\t\t\t\tc = ++a;\n\t\t\t\tc = --a;\n\t\t\t}\n\t\t\t// force end of checked block:\n\t\t\t++a;\n#endif\n\t\t\tif (a)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"a\");\n\t\t\t}\n\t\t\tif (!a)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"!a\");\n\t\t\t}\n\t\t\tif (a == b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"a == b\");\n\t\t\t}\n\t\t\tif (a != b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"a != b\");\n\t\t\t}\n\t\t\tif (a < b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"a < b\");\n\t\t\t}\n\t\t\tif (a > b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"a > b\");\n\t\t\t}\n\t\t\tif (a <= b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"a <= b\");\n\t\t\t}\n\t\t\tif (a >= b)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"a >= b\");\n\t\t\t}\n\t\t\tint num = (int)a;\n#if CS110\n\t\t\tnum = checked((int)a);\n\t\t\t// force end of checked block:\n\t\t\tnum = (int)a;\n#endif\n\t\t\ta = num;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArguments.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class OptionalArguments : List<int>\n\t{\n\t\tpublic delegate int D(int p = 10);\n\n\t\tpublic enum MyEnum\n\t\t{\n\t\t\tA,\n\t\t\tB\n\t\t}\n\n\t\tinternal class OptionalArgumentTest\n\t\t{\n\t\t\tprivate static void Test()\n\t\t\t{\n\t\t\t\tTest2();\n\t\t\t\tTest3();\n\t\t\t\tTest4();\n\t\t\t}\n\n\t\t\tprivate static void Test2(int a = 0)\n\t\t\t{\n\t\t\t}\n\n\t\t\tprivate static void Test3(int a = 0, int? b = null)\n\t\t\t{\n\t\t\t}\n\n\t\t\tprivate static void Test4(int? b = null, int a = 0)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic OptionalArguments(string name, int a = 5)\n\t\t{\n\n\t\t}\n\t\tpublic OptionalArguments(int num, bool flag = true)\n\t\t{\n\n\t\t}\n\n\t\tpublic void Add(string name, int a = 5)\n\t\t{\n\n\t\t}\n\n\t\tprivate void SimpleTests()\n\t\t{\n\t\t\tTest();\n\t\t\tTest(5);\n\t\t\tTest(10, \"Hello World!\");\n\n\t\t\tDecimal();\n\t\t\tDecimal(5m);\n\n#if CS72\n\t\t\tNamedArgument(flag: true);\n\t\t\tNamedArgument(flag: false);\n#endif\n\t\t}\n\n\t\tprivate void Conflicts()\n\t\t{\n\t\t\tOnlyDifferenceIsLastArgument(5, 3, \"Hello\");\n\t\t\tOnlyDifferenceIsLastArgument(5, 3, 3.141);\n\t\t\tOnlyDifferenceIsLastArgument(5, 3, null);\n\t\t\tOnlyDifferenceIsLastArgument(5, 3, double.NegativeInfinity);\n\n\t\t\tOnlyDifferenceIsLastArgumentCastNecessary(10, \"World\", (string)null);\n\t\t\tOnlyDifferenceIsLastArgumentCastNecessary(10, \"Hello\", (OptionalArguments)null);\n\n\t\t\tDifferenceInArgumentCount();\n\t\t\tDifferenceInArgumentCount(\"Hello\");\n\t\t\tDifferenceInArgumentCount(\"World\");\n\t\t}\n\n\t\tprivate void ParamsTests()\n\t\t{\n\t\t\tParamsMethod(5, 10, 9, 8);\n\t\t\tParamsMethod(null);\n\t\t\tParamsMethod(5);\n\t\t\tParamsMethod(10);\n\t\t\tParamsMethod(null, 1, 2, 3);\n\t\t}\n\n\t\tprivate void CallerInfo()\n\t\t{\n\t\t\tCallerMemberName(\"CallerInfo\");\n\t\t\tCallerMemberName(null);\n\t\t\tCallerLineNumber(60);\n\t\t\tCallerLineNumber(0);\n\t\t}\n\n\t\tprivate void Constructor(out OptionalArguments a, out OptionalArguments b, out OptionalArguments c)\n\t\t{\n\t\t\ta = new OptionalArguments(\"Hallo\");\n\t\t\tb = new OptionalArguments(10);\n\t\t\tc = new OptionalArguments(10) {\n\t\t\t\t{ \"Test\", 10 },\n\t\t\t\t\"Test2\"\n\t\t\t};\n\t\t}\n\n\t\tprivate static string GetStr(int unused)\n\t\t{\n\t\t\treturn \" \";\n\t\t}\n\n\t\tpublic static string Issue1567(string str1, string str2)\n\t\t{\n\t\t\treturn string.Concat(str1.Replace('\"', '\\''), str2: str2.Replace('\"', '\\''), str1: GetStr(42));\n\t\t}\n\n\t\tprivate void CallerMemberName([CallerMemberName] string memberName = null)\n\t\t{\n\n\t\t}\n\n\t\tprivate void CallerFilePath([CallerFilePath] string filePath = null)\n\t\t{\n\n\t\t}\n\n\t\tprivate void CallerLineNumber([CallerLineNumber] int lineNumber = 0)\n\t\t{\n\n\t\t}\n\n\t\tprivate void ParamsMethod(int a = 5, params int[] values)\n\t\t{\n\t\t}\n\n\t\tprivate void ParamsMethod(string a = null, params int[] values)\n\t\t{\n\t\t}\n\n\t\tprivate void DifferenceInArgumentCount()\n\t\t{\n\t\t}\n\n\t\tprivate void DifferenceInArgumentCount(string a = \"Hello\")\n\t\t{\n\t\t}\n\n\t\tprivate void Test(int a = 10, string b = \"Test\")\n\t\t{\n\t\t}\n\n\t\tprivate void Decimal(decimal d = 10m)\n\t\t{\n\t\t}\n\n\t\tprivate void OnlyDifferenceIsLastArgument(int a, int b, string c = null)\n\t\t{\n\t\t}\n\n\t\tprivate void OnlyDifferenceIsLastArgument(int a, int b, double d = double.NegativeInfinity)\n\t\t{\n\t\t}\n\n\t\tprivate void OnlyDifferenceIsLastArgumentCastNecessary(int a, string b, string c = null)\n\t\t{\n\t\t}\n\n\t\tprivate void OnlyDifferenceIsLastArgumentCastNecessary(int a, string b, OptionalArguments args = null)\n\t\t{\n\t\t}\n\n\t\tprivate void NamedArgument(bool flag)\n\t\t{\n\t\t}\n\n\t\tprivate string Get(out int a)\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\n\t\tpublic static void Definition_Enum(MyEnum p = MyEnum.A)\n\t\t{\n\n\t\t}\n\n\t\tpublic static void Definition_Enum_OutOfRangeDefault(MyEnum p = (MyEnum)(-1))\n\t\t{\n\n\t\t}\n\n\t\tpublic static void Definition_NullableEnum(MyEnum? p = MyEnum.A)\n\t\t{\n\n\t\t}\n\n\t\tpublic static void Definition_NullableEnum_OutOfRangeDefault(MyEnum? p = (MyEnum)(-1))\n\t\t{\n\n\t\t}\n\n\t\tpublic static void Definition_Int(int p = 0)\n\t\t{\n\n\t\t}\n\n\t\tpublic static void Definition_NullableInt(int? p = 0)\n\t\t{\n\n\t\t}\n\n\t\tpublic static void Definition_Int100(int p = 100)\n\t\t{\n\n\t\t}\n\n\t\tpublic static void Definition_NullableInt100(int? p = 100)\n\t\t{\n\n\t\t}\n\n#if CS90\n\t\tpublic static void Definition_NInt(nint p = 100)\n\t\t{\n\n\t\t}\n\n\t\tpublic static void Definition_NullableNInt(nint? p = 100)\n\t\t{\n\n\t\t}\n#endif\n\n\t\tpublic static void Issue2920a(int x)\n\t\t{\n\t\t}\n\t\tpublic static void Issue2920b([DefaultParameterValue(3)] int x)\n\t\t{\n\t\t}\n\t\tpublic static void Issue2920c(ref int x)\n\t\t{\n\t\t}\n\t\tpublic static void Issue2920d([DefaultParameterValue(3)] ref int x)\n\t\t{\n\t\t}\n\t\tpublic static void Issue2920e(out int x)\n\t\t{\n\t\t\tx = 0;\n\t\t}\n\t\tpublic static void Issue2920f([DefaultParameterValue(3)] out int x)\n\t\t{\n\t\t\tx = 0;\n\t\t}\n#if CS70\n\t\tpublic static void Issue2920g(in int x)\n\t\t{\n\t\t}\n\t\tpublic static void Issue2920h([DefaultParameterValue(3)] in int x)\n\t\t{\n\t\t}\n#endif\n\t\tpublic static void Issue2920i([Optional] int x)\n\t\t{\n\t\t}\n\t\tpublic static void Issue2920j(int x = 3)\n\t\t{\n\t\t}\n\t\tpublic static void Issue2920k([Optional] ref int x)\n\t\t{\n\t\t}\n\t\tpublic static void Issue2920l([Optional][DefaultParameterValue(3)] ref int x)\n\t\t{\n\t\t}\n\t\tpublic static void Issue2920m([Optional] out int x)\n\t\t{\n\t\t\tx = 0;\n\t\t}\n\t\tpublic static void Issue2920n([Optional][DefaultParameterValue(3)] out int x)\n\t\t{\n\t\t\tx = 0;\n\t\t}\n#if CS70\n\t\tpublic static void Issue2920o([Optional] in int x)\n\t\t{\n\t\t}\n\t\tpublic static void Issue2920p(in int x = 3)\n\t\t{\n\t\t}\n#endif\n\t\tpublic static void Issue3469a([Optional][DefaultParameterValue(0)] int i, [Optional] DateTime d)\n\t\t{\n\t\t}\n#if CS120\n\t\tpublic static Action<int, DateTime> Issue3469b()\n\t\t{\n#pragma warning disable CS9099 // Parameter 1 has default value 'default(int)' in lambda but '<missing>' in the target delegate type\n\t\t\treturn ([Optional][DefaultParameterValue(0)] int i, [Optional] DateTime d) => {\n\t\t\t};\n#pragma warning restore CS9099\n\t\t}\n\t\tpublic static D LambdaWithOptionalParameter()\n\t\t{\n\t\t\treturn (int x = 10) => x;\n\t\t}\n\n\t\tpublic static void Use(D d)\n\t\t{\n\t\t\td();\n\t\t\td(42);\n\t\t}\n#endif\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/OptionalArgumentsDisabled.cs",
    "content": "namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class OptionalArgumentsDisabled\n\t{\n\t\tpublic void Test()\n\t\t{\n\t\t\tMixedArguments(\"123\", 0, 0);\n\t\t\tOnlyOptionalArguments(0, 0);\n\t\t}\n\n\t\tpublic void MixedArguments(string msg, int a = 0, int b = 0)\n\t\t{\n\t\t}\n\n\t\tpublic void OnlyOptionalArguments(int a = 0, int b = 0)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/OutVariables.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class OutVariables\n\t{\n\t\tpublic static void OutVarInShortCircuit(Dictionary<int, string> d)\n\t\t{\n\t\t\tif (d.Count > 2 && d.TryGetValue(42, out var value))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(value);\n\t\t\t}\n\t\t}\n\n\t\tpublic static Action CapturedOutVarInShortCircuit(Dictionary<int, string> d)\n\t\t{\n\t\t\t// Note: needs reasoning about \"definitely assigned if true\"\n\t\t\t// to ensure that the value is initialized when the delegate is declared.\n\t\t\tif (d.Count > 2 && d.TryGetValue(42, out var value))\n\t\t\t{\n\t\t\t\treturn delegate {\n\t\t\t\t\tConsole.WriteLine(value);\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tprivate bool TryGet<T>(out T result)\n\t\t{\n\t\t\tresult = default(T);\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic void M3()\n\t\t{\n\t\t\tTryGet<Dictionary<int, (int, string)>>(out Dictionary<int, (int A, string B)> data);\n\n\t\t\tTest();\n\n\t\t\tint Test()\n\t\t\t{\n\t\t\t\treturn data[0].A;\n\t\t\t}\n\t\t}\n\n\t\tpublic void GetObject(out object obj)\n\t\t{\n\t\t\tobj = null;\n\t\t}\n\n\t\tpublic void M4()\n\t\t{\n\t\t\tGetObject(out dynamic obj);\n\t\t\tobj.Method();\n\t\t}\n\n\t\tpublic void M5()\n\t\t{\n\t\t\tFunc<bool> func = () => TryGet<object>(out var result) && result != null;\n\t\t\tFunc<bool> func2 = () => TryGet<object>(out var result) && result != null;\n\n\t\t\tfunc();\n\t\t\tfunc2();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/PInvoke.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Runtime.InteropServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\t// P/Invoke and marshalling attribute tests\n\tpublic class PInvoke\n\t{\n\t\t[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 2)]\n\t\tpublic struct MarshalAsTest\n\t\t{\n\t\t\t[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]\n\t\t\tpublic uint[] FixedArray;\n\n\t\t\t[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = UnmanagedType.Bool)]\n\t\t\tpublic int[] FixedBoolArray;\n\n\t\t\t[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]\n\t\t\tpublic string[] SafeBStrArray;\n\n\t\t\t[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]\n\t\t\tpublic string FixedString;\n\t\t}\n\n\t\t[StructLayout(LayoutKind.Explicit)]\n\t\tpublic struct Rect\n\t\t{\n\t\t\t[FieldOffset(0)]\n\t\t\tpublic int left;\n\t\t\t[FieldOffset(4)]\n\t\t\tpublic int top;\n\t\t\t[FieldOffset(8)]\n\t\t\tpublic int right;\n\t\t\t[FieldOffset(12)]\n\t\t\tpublic int bottom;\n\t\t}\n\n#pragma warning disable CS0618 // Type or member is obsolete\n\t\tpublic static decimal MarshalAttributesOnPropertyAccessors {\n\t\t\t[return: MarshalAs(UnmanagedType.Currency)]\n\t\t\tget {\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\t[param: MarshalAs(UnmanagedType.Currency)]\n\t\t\tset {\n\t\t\t}\n\t\t}\n#pragma warning restore CS0618 // Type or member is obsolete\n\n\t\t[DllImport(\"xyz.dll\", CharSet = CharSet.Auto)]\n\t\t[return: MarshalAs(UnmanagedType.Bool)]\n\t\tpublic static extern bool Method([MarshalAs(UnmanagedType.LPStr)] string input);\n\n\t\t[DllImport(\"xyz.dll\")]\n\t\tprivate static extern void New1(int ElemCnt, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] int[] ar);\n\n\t\t[DllImport(\"xyz.dll\")]\n\t\tprivate static extern void New2([MarshalAs(UnmanagedType.LPArray, SizeConst = 128)] int[] ar);\n\n\t\t[DllImport(\"xyz.dll\")]\n\t\tprivate static extern void New3([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Bool, SizeConst = 64, SizeParamIndex = 1)] int[] ar);\n\n\t\t[DllImport(\"xyz.dll\")]\n\t\tprivate static extern void New4([MarshalAs(UnmanagedType.LPArray)] int[] ar);\n\n\t\tpublic void CustomMarshal1([MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = \"MyCompany.MyMarshaler\")] object o)\n\t\t{\n\t\t}\n\n\t\tpublic void CustomMarshal2([MarshalAs(UnmanagedType.CustomMarshaler, MarshalType = \"MyCompany.MyMarshaler\", MarshalCookie = \"Cookie\")] object o)\n\t\t{\n\t\t}\n\n#if CS110 && NET70\n\t\t[DllImport(\"ws2_32.dll\", SetLastError = true)]\n\t\tinternal static extern nint ioctlsocket([In] nint socketHandle, [In] int cmd, [In][Out] ref int argp);\n\n#else\n\t\t[DllImport(\"ws2_32.dll\", SetLastError = true)]\n\t\tinternal static extern IntPtr ioctlsocket([In] IntPtr socketHandle, [In] int cmd, [In][Out] ref int argp);\n#endif\n\t\tpublic void CallMethodWithInOutParameter()\n\t\t{\n\t\t\tint argp = 0;\n\t\t\tioctlsocket(IntPtr.Zero, 0, ref argp);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/ParamsCollections.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic static class ParamsCollections\n\t{\n\t\tpublic static void ParamsEnumerable(params IEnumerable<int> values)\n\t\t{\n\t\t}\n\t\tpublic static void ParamsList(params List<int> values)\n\t\t{\n\t\t}\n\t\tpublic static void ParamsReadOnlySpan(params ReadOnlySpan<int> values)\n\t\t{\n\t\t}\n\t\tpublic static void ParamsSpan(params Span<int> values)\n\t\t{\n\t\t\t// note: implicitly \"scoped\", \"params scoped Span<int> values\" is allowed\n\t\t\t// but \"scoped\" is always redundant for params.\n\t\t}\n\t\tpublic static void ParamUnscopedSpan([UnscopedRef] params Span<int> values)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/PatternMatching.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class PatternMatching\n\t{\n\t\tpublic class X\n\t\t{\n\t\t\tpublic int? NullableIntField;\n\t\t\tpublic S? NullableCustomStructField;\n\t\t\tpublic int I { get; set; }\n\t\t\tpublic string Text { get; set; }\n\t\t\tpublic object Obj { get; set; }\n\t\t\tpublic S CustomStruct { get; set; }\n\t\t\tpublic int? NullableIntProp { get; set; }\n\t\t\tpublic S? NullableCustomStructProp { get; set; }\n\t\t}\n\n\t\tpublic struct S\n\t\t{\n\t\t\tpublic int I;\n\t\t\tpublic string Text { get; set; }\n\t\t\tpublic object Obj { get; set; }\n\t\t\tpublic S2 S2 { get; set; }\n\t\t}\n\n\t\tpublic struct S2\n\t\t{\n\t\t\tpublic int I;\n\t\t\tpublic float F;\n\t\t\tpublic decimal D;\n\t\t\tpublic string Text { get; set; }\n\t\t\tpublic object Obj { get; set; }\n\t\t}\n\n\t\tpublic void SimpleTypePattern(object x)\n\t\t{\n\t\t\tif (x is string value)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(value);\n\t\t\t}\n\t\t}\n\n\t\tpublic void TypePatternWithShortcircuit(object x)\n\t\t{\n\t\t\tUse(F() && x is string text && text.Contains(\"a\"));\n\t\t\tif (F() && x is string text2 && text2.Contains(\"a\"))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(text2);\n\t\t\t}\n\t\t}\n\n\t\tpublic void TypePatternWithShortcircuitAnd(object x)\n\t\t{\n\t\t\tif (x is string text && text.Contains(\"a\"))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(text);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t}\n\n\t\tpublic void TypePatternWithShortcircuitOr(object x)\n\t\t{\n\t\t\tif (!(x is string text) || text.Contains(\"a\"))\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(text);\n\t\t\t}\n\t\t}\n\n\t\tpublic void TypePatternWithShortcircuitOr2(object x)\n\t\t{\n\t\t\tif (F() || !(x is string value))\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(value);\n\t\t\t}\n\t\t}\n\n\t\tpublic void TypePatternValueTypesCondition(object x)\n\t\t{\n\t\t\tif (x is int num)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Integer: \" + num);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"else\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void TypePatternValueTypesCondition2()\n\t\t{\n\t\t\tif (GetObject() is int num)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Integer: \" + num);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"else\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void TypePatternValueTypesWithShortcircuitAnd(object x)\n\t\t{\n\t\t\tif (x is int num && num.GetHashCode() > 0)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Positive integer: \" + num);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"else\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void TypePatternValueTypesWithShortcircuitOr(object x)\n\t\t{\n\t\t\tif (!(x is int value) || value.GetHashCode() > 0)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(value);\n\t\t\t}\n\t\t}\n\n#if ROSLYN3 || OPT\n\t\t// Roslyn 2.x generates a complex infeasible path in debug builds, which RemoveInfeasiblePathTransform\n\t\t// currently cannot handle. Because this would increase the complexity of that transform, we ignore\n\t\t// this case.\n\t\tpublic void TypePatternValueTypesWithShortcircuitOr2(object x)\n\t\t{\n\t\t\tif (F() || !(x is int value))\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(value);\n\t\t\t}\n\t\t}\n#endif\n\n\t\tpublic void TypePatternGenerics<T>(object x)\n\t\t{\n\t\t\tif (x is T val)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(val.GetType().FullName);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not a \" + typeof(T).FullName);\n\t\t\t}\n\t\t}\n\n\t\tpublic void TypePatternGenericRefType<T>(object x) where T : class\n\t\t{\n\t\t\tif (x is T val)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(val.GetType().FullName);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not a \" + typeof(T).FullName);\n\t\t\t}\n\t\t}\n\n\t\tpublic void TypePatternGenericValType<T>(object x) where T : struct\n\t\t{\n\t\t\tif (x is T val)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(val.GetType().FullName);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not a \" + typeof(T).FullName);\n\t\t\t}\n\t\t}\n\n\t\tpublic void TypePatternValueTypesWithShortcircuitAndMultiUse(object x)\n\t\t{\n\t\t\tif (x is int num && num.GetHashCode() > 0 && num % 2 == 0)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Positive integer: \" + num);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"else\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void TypePatternValueTypesWithShortcircuitAndMultiUse2(object x)\n\t\t{\n\t\t\tif ((x is int num && num.GetHashCode() > 0 && num % 2 == 0) || F())\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"true\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"else\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void TypePatternValueTypesWithShortcircuitAndMultiUse3(object x)\n\t\t{\n\t\t\tif (F() || (x is int num && num.GetHashCode() > 0 && num % 2 == 0))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"true\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"else\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void TypePatternValueTypes()\n\t\t{\n\t\t\tUse(F() && GetObject() is int num && num.GetHashCode() > 0 && num % 2 == 0);\n\t\t}\n\n\t\tpublic static void NotTypePatternVariableUsedOutsideTrueBranch(object x)\n\t\t{\n\t\t\tstring text = x as string;\n\t\t\tif (text != null && text.Length > 5)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"pattern matches\");\n\t\t\t}\n\t\t\tif (text != null && text.Length > 10)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"other use!\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static void NotTypePatternBecauseVarIsNotDefAssignedInCaseOfFallthrough(object x)\n\t\t{\n#if OPT\n\t\t\tstring obj = x as string;\n\t\t\tif (obj == null)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"pattern doesn't match\");\n\t\t\t}\n\t\t\tConsole.WriteLine(obj == null);\n#else\n\t\t\tstring text = x as string;\n\t\t\tif (text == null)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"pattern doesn't match\");\n\t\t\t}\n\t\t\tConsole.WriteLine(text == null);\n#endif\n\t\t}\n\n\t\tpublic void GenericTypePatternInt<T>(T x)\n\t\t{\n\t\t\tif (x is int value)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(value);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not an int\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void GenericValueTypePatternInt<T>(T x) where T : struct\n\t\t{\n\t\t\tif (x is int value)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(value);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not an int\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void GenericRefTypePatternInt<T>(T x) where T : class\n\t\t{\n\t\t\tif (x is int value)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(value);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not an int\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void GenericTypePatternString<T>(T x)\n\t\t{\n\t\t\tif (x is string value)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(value);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not a string\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void GenericRefTypePatternString<T>(T x) where T : class\n\t\t{\n\t\t\tif (x is string value)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(value);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not a string\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void GenericValueTypePatternStringRequiresCastToObject<T>(T x) where T : struct\n\t\t{\n\t\t\tif ((object)x is string value)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(value);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not a string\");\n\t\t\t}\n\t\t}\n\n#if CS80\n\t\tpublic void RecursivePattern_Type(object x)\n\t\t{\n\t\t\tif (x is X { Obj: string obj })\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + obj);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_TypeAndConst(object x)\n\t\t{\n\t\t\tif (x is X { Obj: string obj, I: 42 })\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + obj);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_Constant(object obj)\n\t\t{\n\t\t\tif (obj is X { Obj: null } x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + x);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_StringConstant(object obj)\n\t\t{\n\t\t\tif (obj is X { Text: \"Hello\" } x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + x);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_MultipleConstants(object obj)\n\t\t{\n\t\t\tif (obj is X { I: 42, Text: \"Hello\" } x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + x);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_ValueTypeWithField(object obj)\n\t\t{\n\t\t\tif (obj is S { I: 42 } s)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + s);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_MultipleConstantsMixedWithVar(object x)\n\t\t{\n\t\t\tif (x is X { I: 42, Obj: var obj, Text: \"Hello\" })\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + obj);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_NonTypePattern(object obj)\n\t\t{\n\t\t\tif (obj is X { I: 42, Text: { Length: 0 } } x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + x);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePatternValueType_NonTypePatternTwoProps(object obj)\n\t\t{\n\t\t\tif (obj is X { I: 42, CustomStruct: { I: 0, Text: \"Test\" } } x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + x);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_NonTypePatternNotNull(object o)\n\t\t{\n\t\t\tif (o is X { I: 42, Text: not null, Obj: var obj } x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + x.I + \" \" + obj.GetType());\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_VarLengthPattern(object obj)\n\t\t{\n\t\t\tif (obj is X { I: 42, Text: { Length: var length } } x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + x.I + \": \" + length);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePatternValueType_VarLengthPattern(object obj)\n\t\t{\n\t\t\tif (obj is S { I: 42, Text: { Length: var length } } s)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + s.I + \": \" + length);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePatternValueType_VarLengthPattern_SwappedProps(object obj)\n\t\t{\n\t\t\tif (obj is S { Text: { Length: var length }, I: 42 } s)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + s.I + \": \" + length);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_VarLengthPattern_SwappedProps(object obj)\n\t\t{\n\t\t\tif (obj is X { Text: { Length: var length }, I: 42 } x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + x.I + \": \" + length);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_NullableIntField_Const(object obj)\n\t\t{\n\t\t\tif (obj is X { NullableIntField: 42 } x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + x);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_NullableIntField_Null(object obj)\n\t\t{\n\t\t\tif (obj is X { NullableIntField: null } x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + x);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_NullableIntField_NotNull(object obj)\n\t\t{\n\t\t\tif (obj is X { NullableIntField: not null } x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + x);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_NullableIntField_Var(object obj)\n\t\t{\n\t\t\tif (obj is X { NullableIntField: var nullableIntField })\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + nullableIntField.Value);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_NullableIntProp_Const(object obj)\n\t\t{\n\t\t\tif (obj is X { NullableIntProp: 42 } x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + x);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_NullableIntProp_Null(object obj)\n\t\t{\n\t\t\tif (obj is X { NullableIntProp: null } x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + x);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_NullableIntProp_NotNull(object obj)\n\t\t{\n\t\t\tif (obj is X { NullableIntProp: not null } x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + x);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_NullableIntProp_Var(object obj)\n\t\t{\n\t\t\tif (obj is X { NullableIntProp: var nullableIntProp })\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + nullableIntProp.Value);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_NullableCustomStructField_Const(object obj)\n\t\t{\n\t\t\tif (obj is X { NullableCustomStructField: { I: 42, Obj: not null } nullableCustomStructField })\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + nullableCustomStructField.I);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_NullableCustomStructField_Null(object obj)\n\t\t{\n\t\t\tif (obj is X { NullableCustomStructField: null } x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + x);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_NullableCustomStructField_NotNull(object obj)\n\t\t{\n\t\t\tif (obj is X { NullableCustomStructField: not null } x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + x);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_NullableCustomStructField_Var(object obj)\n\t\t{\n\t\t\tif (obj is X { NullableCustomStructField: var nullableCustomStructField, Obj: null })\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + nullableCustomStructField.Value);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_NullableCustomStructProp_Const(object obj)\n\t\t{\n\t\t\tif (obj is X { NullableCustomStructProp: { I: 42, Obj: not null } nullableCustomStructProp })\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + nullableCustomStructProp.Text);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_NullableCustomStructProp_Null(object obj)\n\t\t{\n\t\t\tif (obj is X { NullableCustomStructProp: null } x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + x);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_NullableCustomStructProp_NotNull(object obj)\n\t\t{\n\t\t\tif (obj is X { NullableCustomStructProp: not null } x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + x);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_NullableCustomStructProp_Var(object obj)\n\t\t{\n\t\t\tif (obj is X { NullableCustomStructProp: var nullableCustomStructProp, Obj: null })\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + nullableCustomStructProp.Value);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_CustomStructNested_Null(object obj)\n\t\t{\n\t\t\tif (obj is S { S2: { Obj: null } })\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + obj);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_CustomStructNested_TextLengthZero(object obj)\n\t\t{\n\t\t\tif (obj is S { S2: { Text: { Length: 0 } } })\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + obj);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_CustomStructNested_EmptyString(object obj)\n\t\t{\n\t\t\tif (obj is S { S2: { Text: \"\" } })\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + obj);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_CustomStructNested_Float(object obj)\n\t\t{\n\t\t\tif (obj is S { S2: { F: 3.141f, Obj: null } })\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + obj);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void RecursivePattern_CustomStructNested_Decimal(object obj)\n\t\t{\n\t\t\tif (obj is S { S2: { D: 3.141m, Obj: null } })\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Test \" + obj);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"not Test\");\n\t\t\t}\n\t\t}\n#endif\n\t\tprivate bool F()\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\tprivate object GetObject()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tprivate void Use(bool x)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/PointerArithmetic.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class PointerArithmetic\n\t{\n\t\tpublic unsafe static void AssignmentVoidPointerToIntPointer(void* ptr)\n\t\t{\n\t\t\t((int*)ptr)[2] = 1;\n\t\t}\n\n\t\tpublic unsafe static int AccessVoidPointerToIntPointer(void* ptr)\n\t\t{\n\t\t\treturn ((int*)ptr)[2];\n\t\t}\n\n\t\tpublic unsafe static void AssignmentLongPointerToIntPointer_2(long* ptr)\n\t\t{\n\t\t\t((int*)ptr)[2] = 1;\n\t\t}\n\n\t\tpublic unsafe static int AccessLongPointerToIntPointer_2(long* ptr)\n\t\t{\n\t\t\treturn ((int*)ptr)[2];\n\t\t}\n\n\t\tpublic unsafe static void AssignmentLongPointerToIntPointer_3(long* ptr)\n\t\t{\n\t\t\t((int*)ptr)[3] = 1;\n\t\t}\n\n\t\tpublic unsafe static int AccessLongPointerToIntPointer_3(long* ptr)\n\t\t{\n\t\t\treturn ((int*)ptr)[3];\n\t\t}\n\n\t\tpublic unsafe static void AssignmentGuidPointerToIntPointer(Guid* ptr)\n\t\t{\n\t\t\t((int*)ptr)[2] = 1;\n\t\t}\n\n\t\tpublic unsafe static int AccessGuidPointerToIntPointer(Guid* ptr)\n\t\t{\n\t\t\treturn ((int*)ptr)[2];\n\t\t}\n\n\t\tpublic unsafe static uint AccessGuidPointerToUIntPointer(Guid* ptr)\n\t\t{\n\t\t\treturn ((uint*)ptr)[2];\n\t\t}\n\n\t\tpublic unsafe static void AssignmentGuidPointerToDateTimePointer(Guid* ptr)\n\t\t{\n\t\t\t((DateTime*)ptr)[2] = DateTime.Now;\n\t\t}\n\n\t\tpublic unsafe static void AssignmentGuidPointerToDateTimePointerDefault(Guid* ptr)\n\t\t{\n\t\t\t((DateTime*)ptr)[2] = default(DateTime);\n\t\t}\n\n\t\tpublic unsafe static void AssignmentGuidPointerToDateTimePointer_2(Guid* ptr)\n\t\t{\n\t\t\t*(DateTime*)(ptr + 2) = DateTime.Now;\n\t\t}\n\n\t\tpublic unsafe static void AssignmentGuidPointerToDateTimePointerDefault_2(Guid* ptr)\n\t\t{\n\t\t\t*(DateTime*)(ptr + 2) = default(DateTime);\n\t\t}\n\n\t\tpublic unsafe static DateTime AccessGuidPointerToDateTimePointer(Guid* ptr)\n\t\t{\n\t\t\treturn ((DateTime*)ptr)[2];\n\t\t}\n\n\t\tpublic unsafe static DateTime AccessGuidPointerToDateTimePointer_2(Guid* ptr)\n\t\t{\n\t\t\treturn *(DateTime*)(ptr + 2);\n\t\t}\n\n\t\tpublic unsafe static void AssignmentIntPointer(int* ptr)\n\t\t{\n\t\t\tptr[2] = 1;\n\t\t}\n\n\t\tpublic unsafe static int AccessIntPointer(int* ptr)\n\t\t{\n\t\t\treturn ptr[2];\n\t\t}\n\n\t\tpublic unsafe static void AssignmentGuidPointer(Guid* ptr)\n\t\t{\n\t\t\tptr[2] = Guid.NewGuid();\n\t\t}\n\n\t\tpublic unsafe static Guid AccessGuidPointer(Guid* ptr)\n\t\t{\n\t\t\treturn ptr[2];\n\t\t}\n\n\t\tpublic unsafe static void AssignmentVoidPointerToGuidPointer(void* ptr)\n\t\t{\n\t\t\t((Guid*)ptr)[2] = Guid.NewGuid();\n\t\t}\n\n\t\tpublic unsafe static Guid AccessVoidPointerToGuidPointer(void* ptr)\n\t\t{\n\t\t\treturn ((Guid*)ptr)[2];\n\t\t}\n\n\t\tpublic unsafe static void AssignmentIntPointerToGuidPointer(int* ptr)\n\t\t{\n\t\t\t((Guid*)ptr)[2] = Guid.NewGuid();\n\t\t}\n\n\t\tpublic unsafe static void AssignmentIntPointerToGuidPointer_2(int* ptr)\n\t\t{\n\t\t\t*(Guid*)(ptr + 2) = Guid.NewGuid();\n\t\t}\n\n\t\tpublic unsafe static Guid AccessIntPointerToGuidPointer(int* ptr)\n\t\t{\n\t\t\treturn ((Guid*)ptr)[2];\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/PropertiesAndEvents.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class PropertiesAndEvents\n\t{\n\t\tprivate interface IBase\n\t\t{\n\t\t\tint GetterOnly { get; }\n\n\t\t\tint SetterOnly { set; }\n\n\t\t\tint Test { get; set; }\n\n\t\t\tevent Action Event;\n\t\t}\n\n\t\tprivate abstract class BaseClass\n\t\t{\n\t\t\tpublic abstract event EventHandler ThisIsAnAbstractEvent;\n\t\t}\n\n\t\tprivate class OtherClass : BaseClass\n\t\t{\n\t\t\tpublic override event EventHandler ThisIsAnAbstractEvent;\n\t\t}\n\n\t\tprivate class ExplicitImpl : IBase\n\t\t{\n\t\t\tint IBase.Test {\n\t\t\t\tget {\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tint IBase.GetterOnly {\n\t\t\t\tget {\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tint IBase.SetterOnly {\n\t\t\t\tset {\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tevent Action IBase.Event {\n\t\t\t\tadd {\n\t\t\t\t}\n\t\t\t\tremove {\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate class Impl : IBase\n\t\t{\n\t\t\tpublic int GetterOnly {\n\t\t\t\tget {\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic int SetterOnly {\n\t\t\t\tset {\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic int Test {\n\t\t\t\tget {\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic event Action Event;\n\t\t}\n\n\t\tprivate interface IChange\n\t\t{\n\t\t\tint Property { get; set; }\n\n\t\t\tevent EventHandler Changed;\n\t\t}\n\n\t\tprivate class Change : IChange\n\t\t{\n\t\t\tprivate EventHandler Changed;\n\n\t\t\tint IChange.Property { get; set; }\n\n\t\t\tevent EventHandler IChange.Changed {\n\t\t\t\tadd {\n\t\t\t\t\tChanged = (EventHandler)Delegate.Combine(Changed, value);\n\t\t\t\t}\n\t\t\t\tremove {\n\t\t\t\t\tChanged = (EventHandler)Delegate.Remove(Changed, value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t[NonSerialized]\n\t\tprivate int someField;\n\n\t\tprivate object issue1221;\n\n\t\tpublic int Value { get; private set; }\n\n\t\tpublic int AutomaticProperty { get; set; }\n\n\t\tpublic int CustomProperty {\n\t\t\tget {\n\t\t\t\treturn AutomaticProperty;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tAutomaticProperty = value;\n\t\t\t}\n\t\t}\n\n\t\tprivate object Issue1221 {\n\t\t\tset {\n\t\t\t\tissue1221 = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic object Item {\n\t\t\tget {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tset {\n\n\t\t\t}\n\t\t}\n\n#if ROSLYN\n\t\tpublic int NotAnAutoProperty => someField;\n#else\n\t\tpublic int NotAnAutoProperty {\n\t\t\tget {\n\t\t\t\treturn someField;\n\t\t\t}\n\t\t}\n#endif\n\n\t\tpublic event EventHandler AutomaticEvent;\n\n\t\t[field: NonSerialized]\n\t\tpublic event EventHandler AutomaticEventWithInitializer = delegate {\n\t\t};\n\n#if ROSLYN\n\t\t// Legacy csc has a bug where EventHandler<dynamic> is only used for the backing field\n\t\tpublic event EventHandler<dynamic> DynamicAutoEvent;\n#endif\n#if CS73\n\t\tpublic event EventHandler<(int A, string B)> AutoEventWithTuple;\n#endif\n#if CS80\n\t\tpublic event EventHandler<(int a, dynamic? b)> ComplexAutoEvent;\n#endif\n\n\t\tpublic event EventHandler CustomEvent {\n\t\t\tadd {\n\t\t\t\tAutomaticEvent += value;\n\t\t\t}\n\t\t\tremove {\n\t\t\t\tAutomaticEvent -= value;\n\t\t\t}\n\t\t}\n\n\t\tpublic event EventHandler Issue3575_AutoEvent;\n\t\tpublic event EventHandler Issue3575_NonAuto;\n\n\t\tpublic event EventHandler Issue3575_Auto {\n\t\t\tadd {\n\t\t\t}\n\t\t\tremove {\n\t\t\t}\n\t\t}\n\n\t\tpublic event EventHandler Issue3575_NonAutoEvent {\n\t\t\tadd {\n\t\t\t}\n\t\t\tremove {\n\t\t\t}\n\t\t}\n\n\t\tpublic int Getter(StringBuilder b)\n\t\t{\n\t\t\treturn b.Length;\n\t\t}\n\n\t\tpublic void Setter(StringBuilder b)\n\t\t{\n\t\t\tb.Capacity = 100;\n\t\t}\n\n\t\tpublic char IndexerGetter(StringBuilder b)\n\t\t{\n\t\t\treturn b[50];\n\t\t}\n\n\t\tpublic void IndexerSetter(StringBuilder b)\n\t\t{\n\t\t\tb[42] = 'b';\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/QualifierTests.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace ICSharpCode.Decompiler.Tests.Pretty\n{\n\tinternal class QualifierTests\n\t{\n\t\tprivate struct Test\n\t\t{\n\t\t\tprivate int dummy;\n\n\t\t\tprivate void DeclaringType(QualifierTests instance)\n\t\t\t{\n\t\t\t\tinstance.NoParameters();\n\t\t\t}\n\n\t\t\tprivate void DeclaringType()\n\t\t\t{\n\t\t\t\tStaticNoParameteres();\n\t\t\t\tParameter(null);\n\t\t\t\tStaticParameter(null);\n\t\t\t\t// The unnecessary cast is added, because we add casts before we add the qualifier.\n\t\t\t\t// normally it's preferable to have casts over having qualifiers,\n\t\t\t\t// this is an ugly edge case.\n\t\t\t\tQualifierTests.StaticParameter((object)null);\n\t\t\t}\n\n\t\t\tprivate void Parameter(object o)\n\t\t\t{\n\n\t\t\t}\n\n\t\t\tprivate static void StaticParameter(object o)\n\t\t\t{\n\t\t\t}\n\n\t\t\tprivate void Parameter(QualifierTests test)\n\t\t\t{\n\t\t\t\tDelegate(Parameter);\n\t\t\t\tDelegate(StaticParameter);\n\t\t\t\tDelegate(test.Parameter);\n\t\t\t\tDelegate(QualifierTests.StaticParameter);\n\t\t\t}\n\n\t\t\tprivate static void StaticParameter(QualifierTests test)\n\t\t\t{\n\t\t\t}\n\n\t\t\tprivate static void DeclaringTypeStatic()\n\t\t\t{\n\t\t\t}\n\n\t\t\tprivate void DeclaringTypeConflict(QualifierTests instance)\n\t\t\t{\n\t\t\t\tDeclaringType();\n\t\t\t\tinstance.DeclaringType();\n\t\t\t\tfieldConflict();\n\t\t\t\tinstance.fieldConflict = 5;\n\t\t\t}\n\n\t\t\tprivate void DeclaringTypeConflict()\n\t\t\t{\n\t\t\t\tDeclaringTypeStatic();\n\t\t\t\tQualifierTests.DeclaringTypeStatic();\n\t\t\t}\n\n\t\t\tprivate void fieldConflict()\n\t\t\t{\n\n\t\t\t}\n\n\t\t\tprivate void Delegate(Action<object> action)\n\t\t\t{\n\n\t\t\t}\n\n\t\t\tpublic string ThisQualifierWithCast()\n\t\t\t{\n\t\t\t\treturn ((object)this).ToString();\n\t\t\t}\n\n\t\t\tpublic override string ToString()\n\t\t\t{\n\t\t\t\t// decompiled as return ((ValueType)this).ToString();\n\t\t\t\treturn base.ToString();\n\t\t\t}\n\t\t}\n\n\t\tinternal class Parent\n\t\t{\n\t\t\tpublic virtual void Virtual()\n\t\t\t{\n\n\t\t\t}\n\n\t\t\tpublic virtual void NewVirtual()\n\t\t\t{\n\n\t\t\t}\n\n\t\t\tpublic void New()\n\t\t\t{\n\n\t\t\t}\n\n\t\t\tpublic void BaseOnly()\n\t\t\t{\n\n\t\t\t}\n\t\t}\n\n\t\tinternal class Child : Parent\n\t\t{\n\t\t\tpublic override void Virtual()\n\t\t\t{\n\t\t\t\tbase.Virtual();\n\t\t\t}\n\n\t\t\tpublic new void NewVirtual()\n\t\t\t{\n\t\t\t\tbase.NewVirtual();\n\t\t\t}\n\n\t\t\tpublic new void New()\n\t\t\t{\n\t\t\t\tbase.New();\n\t\t\t}\n\n\t\t\tpublic void BaseQualifiers()\n\t\t\t{\n\t\t\t\tVirtual();\n\t\t\t\tbase.Virtual();\n\t\t\t\tNewVirtual();\n\t\t\t\tbase.NewVirtual();\n\t\t\t\tNew();\n\t\t\t\tbase.New();\n\t\t\t\tBaseOnly();\n\t\t\t}\n\t\t}\n\n#pragma warning disable CS8981\n\t\tprivate class i\n\t\t{\n\t\t\tpublic static void Test()\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tprivate class value\n\t\t{\n\t\t\tpublic static int item;\n\n\t\t\tpublic static void Test()\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic class Root\n\t\t{\n\t\t\tprivate int prop;\n\n#if LEGACY_CSC\n\t\t\tpublic int Prop {\n\t\t\t\tget {\n\t\t\t\t\treturn prop;\n\t\t\t\t}\n\t\t\t}\n#else\n\t\t\tpublic int Prop => prop;\n#endif\n\t\t\tpublic void M<T>(T a)\n\t\t\t{\n\n\t\t\t}\n\t\t}\n\n\t\tpublic abstract class Base : Root\n\t\t{\n\t\t\tpublic new abstract int Prop { get; }\n\n\t\t\tpublic new abstract void M<T>(T a);\n\t\t}\n\n\t\tpublic class Derived : Base\n\t\t{\n#if LEGACY_CSC\n\t\t\tpublic override int Prop {\n\t\t\t\tget {\n\t\t\t\t\treturn ((Root)this).Prop;\n\t\t\t\t}\n\t\t\t}\n#else\n\t\t\tpublic override int Prop => ((Root)this).Prop;\n#endif\n\t\t\tpublic override void M<T>(T a)\n\t\t\t{\n\t\t\t\t((Root)this).M(a);\n\t\t\t}\n\t\t}\n\n\t\tprivate int fieldConflict;\n\t\tprivate int innerConflict;\n\n\t\tprivate static int PropertyValueParameterConflictsWithTypeName {\n\t\t\tget {\n\t\t\t\treturn value.item;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tQualifierTests.value.item = value;\n\t\t\t}\n\t\t}\n\n\t\tprivate int this[string[] Array] {\n\t\t\tget {\n\t\t\t\tSystem.Array.Sort(Array);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tSystem.Array.Sort(Array);\n\t\t\t\tQualifierTests.value.item = value;\n\t\t\t}\n\t\t}\n\n\t\tprivate void NoParameters()\n\t\t{\n\t\t\tDelegate(Parameter);\n\t\t\tDelegate(StaticParameter);\n\t\t}\n\n\t\tprivate static void StaticNoParameteres()\n\t\t{\n\n\t\t}\n\n\t\tprivate void Parameter(object o)\n\t\t{\n\n\t\t}\n\n\t\tprivate static void StaticParameter(object o)\n\t\t{\n\n\t\t}\n\n\t\tprivate void DeclaringType()\n\t\t{\n\n\t\t}\n\n\t\tprivate static void DeclaringTypeStatic()\n\t\t{\n\n\t\t}\n\n\t\tprivate void conflictWithParameter()\n\t\t{\n\n\t\t}\n\n\t\tprivate void conflictWithVariable(int val)\n\t\t{\n\n\t\t}\n\n\t\tprivate void Conflicts(int conflictWithParameter)\n\t\t{\n\t\t\tthis.conflictWithParameter();\n\t\t}\n\n\t\tprivate void Conflicts()\n\t\t{\n\t\t\tint conflictWithVariable = 5;\n\t\t\tthis.conflictWithVariable(conflictWithVariable);\n\t\t\t// workaround for missing identifiers in il\n\t\t\tCapturer(() => conflictWithVariable);\n\t\t}\n\n\t\tprivate void Capturing()\n\t\t{\n\t\t\tint fieldConflict = 5;\n\t\t\tCapturer(() => this.fieldConflict + fieldConflict);\n\t\t\tCapturer(delegate {\n\t\t\t\tint innerConflict = 5;\n\t\t\t\treturn this.fieldConflict + fieldConflict + Capturer2(() => this.innerConflict + innerConflict + this.fieldConflict + fieldConflict);\n\t\t\t});\n\t\t}\n\n\t\tprivate void Capturer(Func<int> func)\n\t\t{\n\n\t\t}\n\n\t\tprivate int Capturer2(Func<int> func)\n\t\t{\n\t\t\treturn 0;\n\t\t}\n\n\t\tprivate void Delegate(Action<object> action)\n\t\t{\n\n\t\t}\n\n\t\tprivate void ParameterConflictsWithTypeName(string[] Array)\n\t\t{\n\t\t\tSystem.Array.Sort(Array);\n\t\t}\n#if CS70\n\t\tprivate void LocalConflictsWithLocalFunction()\n\t\t{\n\t\t\tint num = 0;\n\t\t\tLocalFunction();\n\n\t\t\tvoid LocalFunction()\n\t\t\t{\n\t\t\t\tQualifierTests qualifierTests2 = qualifierTests();\n\t\t\t\ti.Test();\n\t\t\t\tZ(qualifierTests2);\n\t\t\t}\n\n\t\t\tQualifierTests qualifierTests()\n\t\t\t{\n\t\t\t\tnum.ToString();\n\t\t\t\treturn new QualifierTests(new string[0]);\n\t\t\t}\n\t\t}\n\n\t\tprivate void Z(QualifierTests qualifierTests)\n\t\t{\n\t\t}\n#endif\n\t\tpublic QualifierTests(string[] Array)\n\t\t{\n\t\t\tSystem.Array.Sort(Array);\n\t\t}\n\t}\n\n\tinternal static class ZExt\n\t{\n\t\tpublic static void Do(this int test)\n\t\t{\n\n\t\t}\n\t\tpublic static void Do(this object test)\n\t\t{\n\n\t\t}\n#if CS72\n\t\tpublic static void Do(this ref DateTime test)\n\t\t{\n\n\t\t}\n#endif\n\n\t\tpublic static void Do2(this int test, DateTime date)\n\t\t{\n\t\t\ttest.Do();\n\t\t\t((IEnumerable<int>)null).Any();\n\t\t\t((object)null).Do();\n#if CS72\n\t\t\tdate.Do();\n#endif\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/QueryExpressions.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic struct Maybe<T>\n\t{\n\t\tpublic T Value;\n\t\tpublic bool HasValue;\n\t}\n\n\tpublic static class MaybeExtensions\n\t{\n\t\tpublic static Maybe<TResult> Select<T, TResult>(this Maybe<T> a, Func<T, TResult> fn)\n\t\t{\n\t\t\treturn default(Maybe<TResult>);\n\t\t}\n\n\t\tpublic static Maybe<T> Where<T>(this Maybe<T> a, Func<T, bool> predicate)\n\t\t{\n\t\t\treturn default(Maybe<T>);\n\t\t}\n\t}\n\n\tpublic class QueryExpressions\n\t{\n\t\tpublic class HbmParam\n\t\t{\n\t\t\tpublic string Name { get; set; }\n\t\t\tpublic string[] Text { get; set; }\n\t\t}\n\n\t\tpublic class Customer\n\t\t{\n\t\t\tpublic int CustomerID;\n\t\t\tpublic IEnumerable<Order> Orders;\n\t\t\tpublic string Name;\n\t\t\tpublic string Country;\n\t\t\tpublic string City;\n\t\t}\n\n\t\tpublic class Order\n\t\t{\n\t\t\tpublic int OrderID;\n\t\t\tpublic DateTime OrderDate;\n\t\t\tpublic Customer Customer;\n\t\t\tpublic int CustomerID;\n\t\t\tpublic decimal Total;\n\t\t\tpublic IEnumerable<OrderDetail> Details;\n\t\t}\n\n\t\tpublic class OrderDetail\n\t\t{\n\t\t\tpublic decimal UnitPrice;\n\t\t\tpublic int Quantity;\n\t\t}\n\n\t\tpublic IEnumerable<Customer> customers;\n\t\tpublic IEnumerable<Order> orders;\n\n\t\tpublic object MultipleWhere()\n\t\t{\n\t\t\treturn from c in customers\n\t\t\t\t   where c.Orders.Count() > 10\n\t\t\t\t   where c.Country == \"DE\"\n\t\t\t\t   select c;\n\t\t}\n\n\t\tpublic object SelectManyFollowedBySelect()\n\t\t{\n\t\t\treturn from c in customers\n\t\t\t\t   from o in c.Orders\n\t\t\t\t   select new { c.Name, o.OrderID, o.Total };\n\t\t}\n\n\t\tpublic object SelectManyFollowedByOrderBy()\n\t\t{\n\t\t\treturn from c in customers\n\t\t\t\t   from o in c.Orders\n\t\t\t\t   orderby o.Total descending\n\t\t\t\t   select new { c.Name, o.OrderID, o.Total };\n\t\t}\n\n\t\tpublic object MultipleSelectManyFollowedBySelect()\n\t\t{\n\t\t\treturn from c in customers\n\t\t\t\t   from o in c.Orders\n\t\t\t\t   from d in o.Details\n\t\t\t\t   select new { c.Name, o.OrderID, d.Quantity };\n\t\t}\n\n\t\tpublic object MultipleSelectManyFollowedByLet()\n\t\t{\n\t\t\treturn from c in customers\n\t\t\t\t   from o in c.Orders\n\t\t\t\t   from d in o.Details\n\t\t\t\t   let x = (decimal)d.Quantity * d.UnitPrice\n\t\t\t\t   select new { c.Name, o.OrderID, x };\n\t\t}\n\n\t\tpublic object FromLetWhereSelect()\n\t\t{\n\t\t\treturn from o in orders\n\t\t\t\t   let t = o.Details.Sum((OrderDetail d) => d.UnitPrice * (decimal)d.Quantity)\n\t\t\t\t   where t >= 1000m\n\t\t\t\t   select new {\n\t\t\t\t\t   OrderID = o.OrderID,\n\t\t\t\t\t   Total = t\n\t\t\t\t   };\n\t\t}\n\n\t\tpublic object MultipleLet()\n\t\t{\n\t\t\treturn from a in customers\n\t\t\t\t   let b = a.Country\n\t\t\t\t   let c = a.Name\n\t\t\t\t   select b + c;\n\t\t}\n\n\t\tpublic object HibernateApplyGeneratorQuery()\n\t\t{\n\t\t\treturn (from pi in customers.GetType().GetProperties()\n\t\t\t\t\tlet pname = pi.Name\n\t\t\t\t\tlet pvalue = pi.GetValue(customers, null)\n\t\t\t\t\tselect new HbmParam {\n\t\t\t\t\t\tName = pname,\n\t\t\t\t\t\tText = new string[1] { (pvalue == null) ? \"null\" : pvalue.ToString() }\n\t\t\t\t\t}).ToArray();\n\t\t}\n\n\t\tpublic object Join()\n\t\t{\n\t\t\treturn from c in customers\n\t\t\t\t   join o in orders on c.CustomerID equals o.CustomerID\n\t\t\t\t   select new { c.Name, o.OrderDate, o.Total };\n\t\t}\n\n\t\tpublic object JoinInto()\n\t\t{\n\t\t\treturn from c in customers\n\t\t\t\t   join o in orders on c.CustomerID equals o.CustomerID into co\n\t\t\t\t   let n = co.Count()\n\t\t\t\t   where n >= 10\n\t\t\t\t   select new {\n\t\t\t\t\t   Name = c.Name,\n\t\t\t\t\t   OrderCount = n\n\t\t\t\t   };\n\t\t}\n\n\t\tpublic object OrderBy()\n\t\t{\n\t\t\treturn from o in orders\n\t\t\t\t   orderby o.Customer.Name, o.Total descending\n\t\t\t\t   select o;\n\t\t}\n\n\t\tpublic object GroupBy()\n\t\t{\n\t\t\treturn from c in customers\n\t\t\t\t   group c.Name by c.Country;\n\t\t}\n\n\t\tpublic object ExplicitType()\n\t\t{\n\t\t\treturn from Customer c in customers\n\t\t\t\t   where c.City == \"London\"\n\t\t\t\t   select c;\n\t\t}\n\n\t\tpublic object QueryContinuation()\n\t\t{\n\t\t\treturn from c in customers\n\t\t\t\t   group c by c.Country into g\n\t\t\t\t   select new {\n\t\t\t\t\t   Country = g.Key,\n\t\t\t\t\t   CustCount = g.Count()\n\t\t\t\t   };\n\t\t}\n\n\t\tpublic object Issue437(bool[] bools)\n\t\t{\n\t\t\treturn from x in bools\n\t\t\t\t   where x\n\t\t\t\t   select (x);\n\t\t}\n\n#if CS60\n\t\tprivate List<string> Issue2545(List<string> arglist)\n\t\t{\n\t\t\treturn arglist?.OrderByDescending((string f) => f.Length).ThenBy((string f) => f.ToLower()).ToList();\n\t\t}\n#endif\n\n\t\tpublic static IEnumerable<char> Issue1310a(bool test)\n\t\t{\n#if ROSLYN && OPT\n\t\t\tIEnumerable<char> obj = (test ? (from c in Enumerable.Range(0, 255)\n\t\t\t\t\t\t\t\t\t\t\t where char.IsLetter((char)c)\n\t\t\t\t\t\t\t\t\t\t\t select (char)c) : (from c in Enumerable.Range(0, 255)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\twhere char.IsDigit((char)c)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tselect (char)c));\n\t\t\treturn obj.Concat(obj);\n#else\n\t\t\tIEnumerable<char> enumerable = (test ? (from c in Enumerable.Range(0, 255)\n\t\t\t\t\t\t\t\t\t\t\t\t\twhere char.IsLetter((char)c)\n\t\t\t\t\t\t\t\t\t\t\t\t\tselect (char)c) : (from c in Enumerable.Range(0, 255)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   where char.IsDigit((char)c)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   select (char)c));\n\t\t\treturn enumerable.Concat(enumerable);\n#endif\n\t\t}\n\n\t\tpublic static Maybe<TB> Cast<TA, TB>(Maybe<TA> a) where TB : class\n\t\t{\n\t\t\treturn from m in a\n\t\t\t\t   let t = m as TB\n\t\t\t\t   where t != null\n\t\t\t\t   select t;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Readme.txt",
    "content": "The files in this folder are prettiness tests for the decompiler.\n\nThe NUnit class running these tests is ../PrettyTestRunner.cs.\n\nEach test case is a C# file.\nThe test runner will:\n 1. Compile the file into an .exe/.dll\n 2. Decompile the .exe/.dll\n 3. Compare the resulting code with the original input code.\n\nThe tests pass if the code looks exactly the same as the input code, ignoring comments, empty lines and preprocessor directives.\nIt also ignores disabled preprocessors sections (e.g. \"#if ROSLYN\") when the test runs with a compiler that does not set this symbol.\nSee Tester.GetPreprocessorSymbols() for the available symbols.\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Records.cs",
    "content": "using System;\n#if CS100\nusing System.Runtime.InteropServices;\n#endif\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class RecordClasses\n\t{\n\t\tpublic record Base(string A);\n\n\t\tpublic record CopyCtor(string A)\n\t\t{\n\t\t\tprotected CopyCtor(CopyCtor _)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic record Derived(int B) : Base(B.ToString());\n\n\t\tpublic record BaseRecordWithObject(object Id);\n\n\t\tpublic record DerivedRecordWithString : BaseRecordWithObject\n\t\t{\n\t\t\tpublic DerivedRecordWithString(string Id)\n\t\t\t\t: base(Id)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic record Empty;\n\n\t\tpublic record EmptyWithStaticField\n\t\t{\n\t\t\tpublic static readonly Empty X = new Empty();\n\t\t}\n\n\t\tpublic record Fields\n\t\t{\n\t\t\tpublic int A;\n\t\t\tpublic double B = 1.0;\n\t\t\tpublic object C;\n\t\t\tpublic dynamic D;\n\t\t\tpublic string S = \"abc\";\n\t\t}\n\n\t\tpublic record Interface(int B) : IRecord;\n\n\t\tpublic interface IRecord\n\t\t{\n\t\t}\n\n\t\tpublic record Pair<A, B>\n\t\t{\n\t\t\tpublic A First { get; init; }\n\t\t\tpublic B Second { get; init; }\n\t\t}\n\n\t\tpublic record PairWithPrimaryCtor<A, B>(A First, B Second);\n\n\t\tpublic record PrimaryCtor(int A, string B);\n\t\tpublic record PrimaryCtorWithAttribute([RecordTest(\"param\")][property: RecordTest(\"property\")][field: RecordTest(\"field\")] int a);\n\t\tpublic record PrimaryCtorWithField(int A, string B)\n\t\t{\n\t\t\tpublic double C = 1.0;\n\t\t\tpublic string D = A + B;\n\t\t}\n\t\tpublic record PrimaryCtorWithInParameter(in int A, in string B);\n\t\tpublic record PrimaryCtorWithProperty(int A, string B)\n\t\t{\n\t\t\tpublic double C { get; init; } = 1.0;\n\t\t\tpublic string D { get; } = A + B;\n\t\t}\n\n\t\tpublic record Properties\n\t\t{\n\t\t\tpublic int A { get; set; }\n\t\t\tpublic int B { get; }\n\t\t\tpublic int C => 43;\n\t\t\tpublic object O { get; set; }\n\t\t\tpublic string S { get; set; }\n\t\t\tpublic dynamic D { get; set; }\n\n\t\t\tpublic Properties()\n\t\t\t{\n\t\t\t\tB = 42;\n\t\t\t}\n\t\t}\n\n\t\t[AttributeUsage(AttributeTargets.All)]\n\t\tpublic class RecordTestAttribute : Attribute\n\t\t{\n\t\t\tpublic RecordTestAttribute(string name)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic sealed record Sealed(string A);\n\n\t\tpublic sealed record SealedDerived(int B) : Base(B.ToString());\n\n\t\tpublic class WithExpressionTests\n\t\t{\n\t\t\tpublic Fields Test(Fields input)\n\t\t\t{\n\t\t\t\treturn input with {\n\t\t\t\t\tA = 42,\n\t\t\t\t\tB = 3.141,\n\t\t\t\t\tC = input\n\t\t\t\t};\n\t\t\t}\n\t\t\tpublic Fields Test2(Fields input)\n\t\t\t{\n\t\t\t\treturn input with {\n\t\t\t\t\tA = 42,\n\t\t\t\t\tB = 3.141,\n\t\t\t\t\tC = input with {\n\t\t\t\t\t\tA = 43\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tpublic abstract record WithNestedRecords\n\t\t{\n\t\t\tpublic record A : WithNestedRecords\n\t\t\t{\n\t\t\t\tpublic override string AbstractProp => \"A\";\n\t\t\t}\n\n\t\t\tpublic record B : WithNestedRecords\n\t\t\t{\n\t\t\t\tpublic override string AbstractProp => \"B\";\n\n\t\t\t\tpublic int? Value { get; set; }\n\t\t\t}\n\n\t\t\tpublic record DerivedGeneric<T> : Pair<T, T?> where T : struct\n\t\t\t{\n\t\t\t\tpublic bool Flag;\n\t\t\t}\n\n\t\t\tpublic abstract string AbstractProp { get; }\n\t\t}\n\n\t\tpublic abstract record BaseRecord\n\t\t{\n\t\t\tpublic string Name { get; }\n\t\t\tpublic object Value { get; }\n\t\t\tpublic bool Encode { get; }\n\n\t\t\tprotected BaseRecord(string name, object value, bool encode)\n\t\t\t{\n\t\t\t\tName = name;\n\t\t\t\tValue = value;\n\t\t\t\tEncode = encode;\n\t\t\t}\n\t\t}\n\n\t\tpublic record DerivedRecord(string name, object value, bool encode = true) : BaseRecord(string.IsNullOrEmpty(name) ? \"name\" : name, value, encode);\n\n\t\tpublic record DefaultValuesRecord() : DerivedRecord(\"default\", 42, encode: false);\n\n\t\tpublic record RecordWithProtectedMember(int Value)\n\t\t{\n\t\t\tprotected int Double => Value * 2;\n\t\t}\n\n\t\tpublic record InheritedRecordWithAdditionalMember(int Value) : RecordWithProtectedMember(Value)\n\t\t{\n\t\t\tpublic int MoreData { get; set; }\n\t\t}\n\n\t\tpublic record InheritedRecordWithAdditionalParameter(int Value, int Value2) : RecordWithProtectedMember(Value);\n\n\t\tpublic record BaseWithString(string S);\n\n\t\tpublic record DerivedWithAdditionalInt(int I) : BaseWithString(I.ToString());\n\n\t\tpublic record DerivedWithNoAdditionalProperty(string S) : BaseWithString(S);\n\n\t\tpublic record DerivedWithAdditionalProperty(string S2) : BaseWithString(S2);\n\n\t\tpublic record DerivedWithAdditionalPropertyDifferentAccessor(string S) : BaseWithString(S)\n\t\t{\n\t\t\tpublic string S2 { get; set; } = S;\n\t\t}\n\n\t\tpublic record MultipleCtorsChainedNoPrimaryCtor\n\t\t{\n\t\t\tpublic int A { get; init; }\n\t\t\tpublic string B { get; init; }\n\n\t\t\tpublic double C { get; init; }\n\n\t\t\tpublic MultipleCtorsChainedNoPrimaryCtor(double c)\n\t\t\t{\n\t\t\t\tA = 0;\n\t\t\t\tB = null;\n\t\t\t\tC = c;\n\t\t\t}\n\n\t\t\tpublic MultipleCtorsChainedNoPrimaryCtor(int a)\n\t\t\t\t: this(3.14)\n\t\t\t{\n\t\t\t\tA = a;\n\t\t\t}\n\n\t\t\tpublic MultipleCtorsChainedNoPrimaryCtor(string b)\n\t\t\t\t: this(4.13)\n\t\t\t{\n\t\t\t\tB = b;\n\t\t\t}\n\t\t}\n\n\t\tpublic record UnexpectedCodeInCtor\n\t\t{\n\t\t\tpublic int A { get; init; }\n\t\t\tpublic string B { get; init; }\n\n\t\t\tpublic UnexpectedCodeInCtor(int A, string B)\n\t\t\t{\n\t\t\t\tthis.A = A;\n\t\t\t\tthis.B = B;\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\n\t\t\tpublic UnexpectedCodeInCtor(int A)\n\t\t\t\t: this(A, null)\n\t\t\t{\n\t\t\t\tthis.A = A;\n\t\t\t}\n\t\t}\n\n\t\tprivate record RecordWithMultipleInitializerAssignmentsInPrimaryCtor(string name, string? value, in object encode)\n\t\t{\n\t\t\tpublic string? Value { get; } = name;\n\n\t\t\tpublic string Name { get; } = value;\n\n\t\t\tprivate string? WebValue { get; } = (name != null) ? \"111\" : value;\n\n\t\t\tprivate string? WebValue2;\n\t\t}\n\t}\n\n#if CS100\n\tinternal class RecordStructs\n\t{\n\t\tpublic record struct Base(string A);\n\n\t\tpublic record CopyCtor(string A)\n\t\t{\n\t\t\tprotected CopyCtor(CopyCtor _)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\t[StructLayout(LayoutKind.Sequential, Size = 1)]\n\t\tpublic record struct Empty;\n\n\t\tpublic record struct Fields\n\t\t{\n\t\t\tpublic int A;\n\t\t\tpublic double B;\n\t\t\tpublic object C;\n\t\t\tpublic dynamic D;\n\t\t\tpublic string S;\n\t\t}\n\n\t\tpublic record struct Interface(int B) : IRecord;\n\n\t\tpublic interface IRecord\n\t\t{\n\t\t}\n\n\t\tpublic record struct Pair<A, B>\n\t\t{\n\t\t\tpublic A First { get; init; }\n\t\t\tpublic B Second { get; init; }\n\t\t}\n\n\t\tpublic record struct PairWithPrimaryCtor<A, B>(A First, B Second);\n\n\t\tpublic record struct PrimaryCtor(int A, string B);\n\n\t\tpublic record struct MultipleCtorsNoPrimaryCtor\n\t\t{\n\t\t\tpublic Guid Id { get; }\n\n\t\t\tpublic MultipleCtorsNoPrimaryCtor()\n\t\t\t{\n\t\t\t\tId = Guid.NewGuid();\n\t\t\t}\n\n\t\t\tpublic MultipleCtorsNoPrimaryCtor(Guid id)\n\t\t\t{\n\t\t\t\tId = id;\n\t\t\t}\n\t\t}\n\n\t\tpublic record struct MultipleCtorsChainedNoPrimaryCtor\n\t\t{\n\t\t\tpublic int A { get; init; }\n\t\t\tpublic string B { get; init; }\n\n\t\t\tpublic double C { get; init; }\n\n\t\t\tpublic MultipleCtorsChainedNoPrimaryCtor(double c)\n\t\t\t{\n\t\t\t\tA = 0;\n\t\t\t\tB = null;\n\t\t\t\tC = c;\n\t\t\t}\n\n\t\t\tpublic MultipleCtorsChainedNoPrimaryCtor(int a)\n\t\t\t\t: this(3.14)\n\t\t\t{\n\t\t\t\tA = a;\n\t\t\t}\n\n\t\t\tpublic MultipleCtorsChainedNoPrimaryCtor(string b)\n\t\t\t\t: this(4.13)\n\t\t\t{\n\t\t\t\tB = b;\n\t\t\t}\n\t\t}\n\n\t\tpublic record struct PrimaryCtorWithAttribute([RecordTest(\"param\")][property: RecordTest(\"property\")][field: RecordTest(\"field\")] int a);\n\t\tpublic record struct PrimaryCtorWithField(int A, string B)\n\t\t{\n\t\t\tpublic double C = 1.0;\n\t\t\tpublic string D = A + B;\n\t\t}\n\t\tpublic record struct PrimaryCtorWithInParameter(in int A, in string B);\n\t\tpublic record struct PrimaryCtorWithProperty(int A, string B)\n\t\t{\n\t\t\tpublic double C { get; init; } = 1.0;\n\t\t\tpublic string D { get; } = A + B;\n\t\t}\n\n\t\tpublic record struct Properties\n\t\t{\n\t\t\tpublic int A { get; set; }\n\t\t\tpublic int B { get; }\n\t\t\tpublic int C => 43;\n\t\t\tpublic object O { get; set; }\n\t\t\tpublic string S { get; set; }\n\t\t\tpublic dynamic D { get; set; }\n\n\t\t\tpublic Properties()\n\t\t\t{\n\t\t\t\tA = 41;\n\t\t\t\tB = 42;\n\t\t\t\tO = null;\n\t\t\t\tS = \"Hello\";\n\t\t\t\tD = null;\n\t\t\t}\n\t\t}\n\n\t\tpublic record struct PropertiesWithInitializers()\n\t\t{\n\t\t\tpublic int A { get; set; } = 41;\n\t\t\tpublic int B { get; } = 42;\n\t\t\tpublic int C => 43;\n\t\t\tpublic object O { get; set; } = null;\n\t\t\tpublic string S { get; set; } = \"Hello\";\n\t\t\tpublic dynamic D { get; set; } = null;\n\t\t}\n\n\t\t[AttributeUsage(AttributeTargets.All)]\n\t\tpublic class RecordTestAttribute : Attribute\n\t\t{\n\t\t\tpublic RecordTestAttribute(string name)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic class WithExpressionTests\n\t\t{\n\t\t\tpublic Fields Test(Fields input)\n\t\t\t{\n\t\t\t\treturn input with {\n\t\t\t\t\tA = 42,\n\t\t\t\t\tB = 3.141,\n\t\t\t\t\tC = input\n\t\t\t\t};\n\t\t\t}\n\t\t\tpublic Fields Test2(Fields input)\n\t\t\t{\n\t\t\t\treturn input with {\n\t\t\t\t\tA = 42,\n\t\t\t\t\tB = 3.141,\n\t\t\t\t\tC = input with {\n\t\t\t\t\t\tA = 43\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t}\n#if CS110\n\t\tpublic record struct WithRequiredMembers\n\t\t{\n\t\t\tpublic int A { get; set; }\n\t\t\tpublic required double B { get; set; }\n\t\t\tpublic object C;\n\t\t\tpublic required dynamic D;\n\t\t}\n#endif\n\t\tpublic record struct RecordWithMultipleCtors\n\t\t{\n\t\t\tpublic int A { get; set; }\n\n\t\t\tpublic RecordWithMultipleCtors()\n\t\t\t{\n\t\t\t\tA = 42;\n\t\t\t}\n\n\t\t\tpublic RecordWithMultipleCtors(int A)\n\t\t\t{\n\t\t\t\tthis.A = A;\n\t\t\t}\n\n\t\t\tpublic RecordWithMultipleCtors(string A)\n\t\t\t{\n\t\t\t\tthis.A = int.Parse(A);\n\t\t\t}\n\t\t}\n\n\t\tpublic record struct RecordCtorChain(int A, string B)\n\t\t{\n#if EXPECTED_OUTPUT\n\t\t\tpublic double C = 0.0;\n#else\n\t\t\tpublic double C;\n#endif\n\t\t\tpublic RecordCtorChain(int A)\n\t\t\t\t: this(A, \"default\")\n\t\t\t{\n\t\t\t\tC = 3.14;\n\t\t\t}\n\t\t\tpublic RecordCtorChain(string B)\n\t\t\t\t: this(42, B)\n\t\t\t{\n\t\t\t\tC = 1.41;\n\t\t\t}\n\t\t}\n\t}\n#endif\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/ReduceNesting.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic abstract class ReduceNesting\n\t{\n\t\tpublic abstract bool B(int i);\n\t\tpublic abstract int I(int i);\n\n\t\tpublic void IfIf()\n\t\t{\n\t\t\tif (B(0))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(0);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (B(1))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(1);\n\t\t\t}\n\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\n\t\tpublic void IfSwitch()\n\t\t{\n\t\t\tif (B(0))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(0);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tConsole.WriteLine(\"switch\");\n\t\t\tswitch (I(0))\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tConsole.WriteLine(\"case 0\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tConsole.WriteLine(\"case 1\");\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tConsole.WriteLine(\"end\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic void IfSwitchSwitch()\n\t\t{\n\t\t\tif (B(0))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(0);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tConsole.WriteLine(\"switch 0\");\n\t\t\tswitch (I(1))\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tConsole.WriteLine(\"case 0\");\n\t\t\t\t\treturn;\n\t\t\t\tcase 1:\n\t\t\t\t\tConsole.WriteLine(\"case 1\");\n\t\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tConsole.WriteLine(\"switch 1\");\n\t\t\tswitch (I(1))\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tConsole.WriteLine(\"case 0\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tConsole.WriteLine(\"case 1\");\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tConsole.WriteLine(\"end\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic void IfLoop()\n\t\t{\n\t\t\tif (B(0))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(0);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(i);\n\t\t\t}\n\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\n\t\tpublic void LoopContinue()\n\t\t{\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(i);\n\t\t\t\tif (B(0))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(0);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (B(1))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(1);\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(\"loop-tail\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void LoopBreak()\n\t\t{\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(i);\n\t\t\t\tif (B(0))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(0);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (B(1))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(1);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (B(2))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(2);\n\t\t\t\t}\n\n\t\t\t\tConsole.WriteLine(\"break\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\n\t\tpublic void LoopBreakElseIf()\n\t\t{\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(i);\n\t\t\t\tif (B(0))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(0);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (B(1))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(1);\n\t\t\t\t}\n\t\t\t\telse if (B(2))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(2);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\n\t\tpublic void SwitchIf()\n\t\t{\n\t\t\tswitch (I(0))\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tConsole.WriteLine(\"case 0\");\n\t\t\t\t\treturn;\n\t\t\t\tcase 1:\n\t\t\t\t\tConsole.WriteLine(\"case 1\");\n\t\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (B(0))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(0);\n\t\t\t}\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\n\t\tpublic void NestedSwitchIf()\n\t\t{\n\t\t\tif (B(0))\n\t\t\t{\n\t\t\t\tswitch (I(0))\n\t\t\t\t{\n\t\t\t\t\tcase 0:\n\t\t\t\t\t\tConsole.WriteLine(\"case 0\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tConsole.WriteLine(\"case 1\");\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (B(1))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(1);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"else\");\n\t\t\t}\n\t\t}\n\n\t\t// nesting should not be reduced as maximum nesting level is 1\n\t\tpublic void EarlyExit1()\n\t\t{\n\t\t\tif (!B(0))\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(i);\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(\"end\");\n\t\t\t}\n\t\t}\n\n\t\t// nesting should be reduced as maximum nesting level is 2\n\t\tpublic void EarlyExit2()\n\t\t{\n\t\t\tif (B(0))\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(i);\n\t\t\t\tif (i % 2 == 0)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"even\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\n\t\t// nesting should not be reduced as maximum nesting level is 1 and the else block has no more instructions than any other block\n\t\tpublic void BalancedIf()\n\t\t{\n\t\t\tif (B(0))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"true\");\n\t\t\t\tif (B(1))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(1);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (B(2))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(2);\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(\"false\");\n\t\t\t}\n\t\t}\n\n\t\tpublic string ComplexCase1(string s)\n\t\t{\n\t\t\tif (B(0))\n\t\t\t{\n\t\t\t\treturn s;\n\t\t\t}\n\n\t\t\tfor (int i = 0; i < s.Length; i++)\n\t\t\t{\n\t\t\t\tif (B(1))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(1);\n\t\t\t\t}\n\t\t\t\telse if (B(2))\n\t\t\t\t{\n\t\t\t\t\tswitch (i)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase 1:\n\t\t\t\t\t\t\tif (B(3))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tConsole.WriteLine(3);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tConsole.WriteLine(\"case1\");\n\t\t\t\t\t\t\tif (B(4))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tConsole.WriteLine(4);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\tConsole.WriteLine(\"case23\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tConsole.WriteLine(2);\n\t\t\t\t}\n\t\t\t\telse if (B(5))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(5);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (B(6))\n\t\t\t\t\t{\n\t\t\t\t\t\tConsole.WriteLine(6);\n\t\t\t\t\t}\n\t\t\t\t\tConsole.WriteLine(\"else\");\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn s;\n\t\t}\n\n\t\tpublic void EarlyExitBeforeTry()\n\t\t{\n\t\t\tif (B(0))\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (B(1))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine();\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic void EarlyExitInTry()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (B(0))\n\t\t\t\t{\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tConsole.WriteLine();\n\n\t\t\t\tif (B(1))\n\t\t\t\t{\n\t\t\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tConsole.WriteLine(i);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic void ContinueLockInLoop()\n\t\t{\n\t\t\twhile (B(0))\n\t\t\t{\n\t\t\t\tlock (Console.Out)\n\t\t\t\t{\n\t\t\t\t\tif (B(1))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tConsole.WriteLine();\n\n\t\t\t\t\tif (B(2))\n\t\t\t\t\t{\n\t\t\t\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tConsole.WriteLine(i);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic void BreakLockInLoop()\n\t\t{\n\t\t\twhile (B(0))\n\t\t\t{\n\t\t\t\tlock (Console.Out)\n\t\t\t\t{\n\t\t\t\t\t// Before ReduceNestingTransform, the rest of the lock body is nested in if(!B(1)) with a continue;\n\t\t\t\t\t// the B(1) case falls through to a break outside the lock\n\t\t\t\t\tif (B(1))\n\t\t\t\t\t{\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tConsole.WriteLine();\n\n\t\t\t\t\tif (B(2))\n\t\t\t\t\t{\n\t\t\t\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tConsole.WriteLine(i);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// the break gets duplicated into the lock (replacing the leave) making the lock 'endpoint unreachable' and the break outside the lock is removed\n\t\t\t\t\t// After the condition is inverted, ReduceNestingTransform isn't smart enough to then move the continue out of the lock\n\t\t\t\t\t// Thus the redundant continue;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tConsole.WriteLine();\n\t\t}\n\n\t\tpublic unsafe void BreakPinnedInLoop(int[] arr)\n\t\t{\n\t\t\twhile (B(0))\n\t\t\t{\n\t\t\t\tfixed (int* ptr = arr)\n\t\t\t\t{\n\t\t\t\t\tif (B(1))\n\t\t\t\t\t{\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tConsole.WriteLine();\n\n\t\t\t\t\tif (B(2))\n\t\t\t\t\t{\n\t\t\t\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tConsole.WriteLine(ptr[i]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Same reason as BreakLockInLoop\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tConsole.WriteLine();\n\t\t}\n\n\t\tpublic void CannotEarlyExitInTry()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (B(0))\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine();\n\n\t\t\t\t\tif (B(1))\n\t\t\t\t\t{\n\t\t\t\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tConsole.WriteLine(i);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch\n\t\t\t{\n\t\t\t}\n\t\t\tConsole.WriteLine();\n\t\t}\n\n\t\tpublic void EndpointUnreachableDueToEarlyExit()\n\t\t{\n\t\t\tusing (Console.Out)\n\t\t\t{\n\t\t\t\tif (B(0))\n\t\t\t\t{\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tif (B(1))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t} while (B(2));\n\t\t\t\tthrow new Exception();\n\t\t\t}\n\t\t}\n\n\t\tpublic void SwitchInTry()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tswitch (I(0))\n\t\t\t\t{\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tConsole.WriteLine(1);\n\t\t\t\t\t\treturn;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tConsole.WriteLine(2);\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(3);\n\t\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(i);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch\n\t\t\t{\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}\n\n\t\tpublic void SwitchInTryInLoopReturn()\n\t\t{\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tswitch (I(0))\n\t\t\t\t\t{\n\t\t\t\t\t\tcase 1:\n\t\t\t\t\t\t\tConsole.WriteLine(1);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\tConsole.WriteLine(2);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tConsole.WriteLine(3);\n\t\t\t\t\tfor (int j = 0; j < 10; j++)\n\t\t\t\t\t{\n\t\t\t\t\t\tConsole.WriteLine(j);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch\n\t\t\t\t{\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic void SwitchInTryInLoopContinue()\n\t\t{\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tswitch (I(0))\n\t\t\t\t\t{\n\t\t\t\t\t\tcase 1:\n\t\t\t\t\t\t\tConsole.WriteLine(1);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\tConsole.WriteLine(2);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tConsole.WriteLine(3);\n\t\t\t\t\tfor (int j = 0; j < 10; j++)\n\t\t\t\t\t{\n\t\t\t\t\t\tConsole.WriteLine(j);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch\n\t\t\t\t{\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate static string ShouldNotDuplicateReturnStatementIntoTry(IDictionary<int, string> dict)\n\t\t{\n\t\t\tstring value;\n\t\t\tlock (dict)\n\t\t\t{\n\t\t\t\tif (!dict.TryGetValue(1, out value))\n\t\t\t\t{\n\t\t\t\t\tvalue = \"test\";\n\t\t\t\t\tdict.Add(1, value);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefFields.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class LifetimeTests\n\t{\n\t\tprivate static int staticField;\n\n\t\tpublic Span<int> CreateWithoutCapture(scoped ref int value)\n\t\t{\n\t\t\t// Okay: value is not captured\n\t\t\treturn new Span<int>(ref staticField);\n\t\t}\n\n\t\tpublic Span<int> CreateAndCapture(ref int value)\n\t\t{\n\t\t\t// Okay: value Rule 3 specifies that the safe-to-escape be limited to the ref-safe-to-escape\n\t\t\t// of the ref argument. That is the *calling method* for value hence this is not allowed.\n\t\t\treturn new Span<int>(ref value);\n\t\t}\n\n\t\tpublic Span<int> ScopedRefSpan(scoped ref Span<int> span)\n\t\t{\n\t\t\treturn span;\n\t\t}\n\n\t\tpublic Span<int> ScopedSpan(scoped Span<int> span)\n\t\t{\n\t\t\treturn default(Span<int>);\n\t\t}\n\n\t\tpublic void OutSpan(out Span<int> span)\n\t\t{\n\t\t\tspan = default(Span<int>);\n\t\t}\n\n\t\tpublic void Calls()\n\t\t{\n\t\t\tint value = 0;\n\t\t\tSpan<int> span = CreateWithoutCapture(ref value);\n\t\t\t//span = CreateAndCapture(ref value); -- would need scoped local, not yet implemented\n\t\t\tspan = ScopedRefSpan(ref span);\n\t\t\tspan = ScopedSpan(span);\n\t\t\tOutSpan(out span);\n\t\t}\n\t}\n\n\tinternal ref struct RefFields\n\t{\n\t\tpublic ref int Field0;\n\t\tpublic ref readonly int Field1;\n\t\tpublic readonly ref int Field2;\n\t\tpublic readonly ref readonly int Field3;\n\n\t\tpublic int PropertyAccessingRefFieldByValue {\n\t\t\tget {\n\t\t\t\treturn Field0;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tField0 = value;\n\t\t\t}\n\t\t}\n\n\t\tpublic ref int PropertyReturningRefFieldByReference => ref Field0;\n\n\t\tpublic void Uses(int[] array)\n\t\t{\n\t\t\tField1 = ref array[0];\n\t\t\tField2 = array[0];\n\t\t}\n\n\t\tpublic void ReadonlyLocal()\n\t\t{\n\t\t\tref readonly int field = ref Field1;\n\t\t\tConsole.WriteLine(\"No inlining\");\n\t\t\tfield.ToString();\n\t\t}\n\n\t\tpublic RefFields(ref int v)\n\t\t{\n\t\t\tField0 = ref v;\n\t\t\tField1 = ref v;\n\t\t\tField2 = ref v;\n\t\t\tField3 = ref v;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal static class Ext\n\t{\n\t\tpublic static void ExtOnRef(this ref RefLocalsAndReturns.NormalStruct s)\n\t\t{\n\t\t}\n\t\tpublic static void ExtOnIn(this in RefLocalsAndReturns.NormalStruct s)\n\t\t{\n\t\t}\n\t\tpublic static void ExtOnRef(this ref RefLocalsAndReturns.ReadOnlyStruct s)\n\t\t{\n\t\t}\n\t\tpublic static void ExtOnIn(this in RefLocalsAndReturns.ReadOnlyStruct s)\n\t\t{\n\t\t}\n\t\tpublic static void ExtOnRef(this ref RefLocalsAndReturns.ReadOnlyRefStruct s)\n\t\t{\n\t\t}\n\t\tpublic static void ExtOnIn(this in RefLocalsAndReturns.ReadOnlyRefStruct s)\n\t\t{\n\t\t}\n\t}\n\n\tinternal class RefLocalsAndReturns\n\t{\n\t\tpublic struct Issue1630\n\t\t{\n\t\t\tprivate object data;\n\n\t\t\tprivate int next;\n\n\t\t\tpublic static void Test()\n\t\t\t{\n\t\t\t\tIssue1630[] array = new Issue1630[1];\n\t\t\t\tint num = 0;\n\t\t\t\twhile (num >= 0)\n\t\t\t\t{\n\t\t\t\t\tref Issue1630 reference = ref array[num];\n\t\t\t\t\tConsole.WriteLine(reference.data);\n\t\t\t\t\tnum = reference.next;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic delegate ref T RefFunc<T>();\n\t\tpublic delegate ref readonly T ReadOnlyRefFunc<T>();\n\t\tpublic delegate ref TReturn RefFunc<T1, TReturn>(T1 param1);\n\n\t\tpublic ref struct RefStruct\n\t\t{\n\t\t\tprivate int dummy;\n\t\t}\n\n\t\tpublic readonly ref struct ReadOnlyRefStruct\n\t\t{\n\t\t\tprivate readonly int dummy;\n\t\t}\n\n\t\tpublic struct NormalStruct\n\t\t{\n\t\t\tprivate readonly int dummy;\n\t\t\tprivate int[] arr;\n\n\t\t\tpublic int Property {\n\t\t\t\tget {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t}\n\t\t\t}\n\n#if CS80\n\t\t\tpublic readonly int ReadOnlyProperty {\n\t\t\t\tget {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic int PropertyWithReadOnlyGetter {\n\t\t\t\treadonly get {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic int PropertyWithReadOnlySetter {\n\t\t\t\tget {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\treadonly set {\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic readonly int ReadOnlyPropertyWithOnlyGetter {\n\t\t\t\tget {\n\t\t\t\t\tConsole.WriteLine(\"No inlining\");\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic ref int RefProperty => ref arr[0];\n\t\t\tpublic ref readonly int RefReadonlyProperty => ref arr[0];\n\t\t\tpublic readonly ref int ReadonlyRefProperty => ref arr[0];\n\t\t\tpublic readonly ref readonly int ReadonlyRefReadonlyProperty => ref arr[0];\n#endif\n\n\t\t\tpublic ref readonly int this[in int index] => ref arr[index];\n\n\t\t\tpublic event EventHandler NormalEvent;\n\n#if CS80\n\t\t\tpublic readonly event EventHandler ReadOnlyEvent {\n\t\t\t\tadd {\n\t\t\t\t}\n\t\t\t\tremove {\n\t\t\t\t}\n\t\t\t}\n#endif\n\t\t\tpublic void Method()\n\t\t\t{\n\t\t\t}\n\n#if CS80\n\t\t\tpublic readonly void ReadOnlyMethod()\n\t\t\t{\n\t\t\t}\n#endif\n\t\t}\n\n\t\tpublic readonly struct ReadOnlyStruct\n\t\t{\n\t\t\tprivate readonly int Field;\n\n\t\t\tpublic void Method()\n\t\t\t{\n\t\t\t\tref readonly int field = ref Field;\n\t\t\t\tConsole.WriteLine(\"No inlining\");\n\t\t\t\tConsole.WriteLine(field.GetHashCode());\n\t\t\t}\n\n\t\t\tpublic void RefReadonlyCallVirt(RefLocalsAndReturns provider)\n\t\t\t{\n\t\t\t\tref readonly NormalStruct readonlyRefInstance = ref provider.GetReadonlyRefInstance<NormalStruct>();\n\t\t\t\tConsole.WriteLine(\"No inlining\");\n\t\t\t\treadonlyRefInstance.Method();\n\t\t\t}\n\t\t}\n\n\t\tprivate static int[] numbers = new int[10] { 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023 };\n\t\tprivate static string[] strings = new string[2] { \"Hello\", \"World\" };\n\n\t\tprivate static string NullString = \"\";\n\n\t\tprivate static int DefaultInt = 0;\n\n\t\tpublic static ref T GetRef<T>()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tpublic static ref readonly T GetReadonlyRef<T>()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tpublic ref readonly T GetReadonlyRefInstance<T>()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tpublic void CallOnRefReturn()\n\t\t{\n\t\t\t// Both direct calls:\n\t\t\tGetRef<NormalStruct>().Method();\n\t\t\tGetRef<ReadOnlyStruct>().Method();\n\n\t\t\t// call on a copy, not the original ref:\n\t\t\tNormalStruct normalStruct = GetRef<NormalStruct>();\n\t\t\tnormalStruct.Method();\n\n\t\t\tReadOnlyStruct readOnlyStruct = GetRef<ReadOnlyStruct>();\n\t\t\treadOnlyStruct.Method();\n\t\t}\n\n\t\tpublic void CallOnReadOnlyRefReturn()\n\t\t{\n\t\t\t// uses implicit temporary:\n\t\t\tGetReadonlyRef<NormalStruct>().Method();\n\t\t\t// direct call:\n\t\t\tGetReadonlyRef<ReadOnlyStruct>().Method();\n\t\t\t// call on a copy, not the original ref:\n\t\t\tReadOnlyStruct readonlyRef = GetReadonlyRef<ReadOnlyStruct>();\n\t\t\treadonlyRef.Method();\n\t\t}\n\n\t\tpublic void CallOnInParam(in NormalStruct ns, in ReadOnlyStruct rs)\n\t\t{\n\t\t\t// uses implicit temporary:\n\t\t\tns.Method();\n\t\t\t// direct call:\n\t\t\trs.Method();\n\t\t\t// call on a copy, not the original ref:\n\t\t\tReadOnlyStruct readOnlyStruct = rs;\n\t\t\treadOnlyStruct.Method();\n\t\t}\n\n\t\tpublic void M(in DateTime a = default(DateTime))\n\t\t{\n\t\t}\n\n\t\tpublic void M2<T>(in T a = default(T))\n\t\t{\n\t\t}\n\n\t\tpublic void M3<T>(in T? a = null) where T : struct\n\t\t{\n\t\t}\n\n\t\tpublic static TReturn Invoker<T1, TReturn>(RefFunc<T1, TReturn> action, T1 value)\n\t\t{\n\t\t\treturn action(value);\n\t\t}\n\n\t\tpublic static ref int FindNumber(int target)\n\t\t{\n\t\t\tfor (int i = 0; i < numbers.Length; i++)\n\t\t\t{\n\t\t\t\tif (numbers[i] >= target)\n\t\t\t\t{\n\t\t\t\t\treturn ref numbers[i];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ref numbers[0];\n\t\t}\n\n\t\tpublic static ref int LastNumber()\n\t\t{\n\t\t\treturn ref numbers[numbers.Length - 1];\n\t\t}\n\n\t\tpublic static ref int ElementAtOrDefault(int index)\n\t\t{\n\t\t\tif (index >= 0 && index < numbers.Length)\n\t\t\t{\n\t\t\t\treturn ref numbers[index];\n\t\t\t}\n\t\t\treturn ref DefaultInt;\n\t\t}\n\n\t\tpublic static ref int LastOrDefault()\n\t\t{\n\t\t\tif (numbers.Length != 0)\n\t\t\t{\n\t\t\t\treturn ref numbers[numbers.Length - 1];\n\t\t\t}\n\t\t\treturn ref DefaultInt;\n\t\t}\n\n\t\tpublic static void DoubleNumber(ref int num)\n\t\t{\n\t\t\tConsole.WriteLine(\"old: \" + num);\n\t\t\tnum *= 2;\n\t\t\tConsole.WriteLine(\"new: \" + num);\n\t\t}\n\n\t\tpublic static ref string GetOrSetString(int index)\n\t\t{\n\t\t\tif (index < 0 || index >= strings.Length)\n\t\t\t{\n\t\t\t\treturn ref NullString;\n\t\t\t}\n\n\t\t\treturn ref strings[index];\n\t\t}\n\n\t\tpublic void CallSiteTests(NormalStruct s, ReadOnlyStruct r, ReadOnlyRefStruct rr)\n\t\t{\n\t\t\ts.ExtOnIn();\n\t\t\ts.ExtOnRef();\n\t\t\tr.ExtOnIn();\n\t\t\tr.ExtOnRef();\n\t\t\trr.ExtOnIn();\n\t\t\trr.ExtOnRef();\n\t\t\tCallOnInParam(in s, in r);\n\t\t}\n\n\t\tpublic void RefReassignment(ref NormalStruct s)\n\t\t{\n\t\t\tref NormalStruct reference = ref GetRef<NormalStruct>();\n\t\t\tRefReassignment(ref reference);\n\t\t\tif (s.GetHashCode() == 0)\n\t\t\t{\n\t\t\t\treference = ref GetRef<NormalStruct>();\n\t\t\t}\n\t\t\tRefReassignment(ref reference.GetHashCode() == 4 ? ref reference : ref s);\n\t\t}\n\n\t\tpublic static void Main(string[] args)\n\t\t{\n\t\t\tDoubleNumber(ref args.Length == 1 ? ref numbers[0] : ref DefaultInt);\n\t\t\tDoubleNumber(ref FindNumber(32));\n\t\t\tConsole.WriteLine(string.Join(\", \", numbers));\n\t\t\tDoubleNumber(ref LastNumber());\n\t\t\tConsole.WriteLine(string.Join(\", \", numbers));\n\t\t\tConsole.WriteLine(GetOrSetString(0));\n\t\t\tGetOrSetString(0) = \"Goodbye\";\n\t\t\tConsole.WriteLine(string.Join(\" \", strings));\n\t\t\tGetOrSetString(5) = \"Here I mutated the null value!?\";\n\t\t\tConsole.WriteLine(GetOrSetString(-5));\n\n\t\t\tConsole.WriteLine(Invoker((int x) => ref numbers[x], 0));\n\t\t\tConsole.WriteLine(LastOrDefault());\n\t\t\tLastOrDefault() = 10000;\n\t\t\tConsole.WriteLine(ElementAtOrDefault(-5));\n\t\t}\n\n#if CS120\n\t\tpublic ref readonly int M(in int x)\n\t\t{\n\t\t\treturn ref x;\n\t\t}\n\n\t\tpublic ref readonly int M2(ref readonly int x)\n\t\t{\n\t\t\treturn ref x;\n\t\t}\n\n\t\tpublic void Test()\n\t\t{\n\t\t\tint x = 32;\n\t\t\tM(in x);\n\t\t\tM2(in x);\n\t\t}\n#endif\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/ShortCircuit.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n// compile:\n//     csc ShortCircuit.cs /t:Library && ildasm /text ShortCircuit.dll >ShortCircuit.il\n//     csc ShortCircuit.cs /t:Library /o /out:ShortCircuit.opt.dll && ildasm /text ShortCircuit.opt.dll >ShortCircuit.opt.il\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic abstract class ShortCircuit\n\t{\n\t\tpublic abstract void B(bool b);\n\t\tpublic abstract bool F(int i);\n\t\tpublic abstract int GetInt(int i);\n\t\tpublic abstract void M1();\n\t\tpublic abstract void M2();\n\t\tpublic abstract void E();\n\n\t\tpublic void ExprAnd()\n\t\t{\n\t\t\tB(F(0) && F(1));\n\t\t}\n\n\t\tpublic void ExprOr()\n\t\t{\n\t\t\tB(F(0) || F(1));\n\t\t}\n\n\t\tpublic void ExprCond()\n\t\t{\n\t\t\tB(F(0) ? F(1) : F(2));\n\t\t}\n\n\t\tpublic void ExprCondAnd()\n\t\t{\n\t\t\tB((F(0) && F(1)) ? F(2) : F(3));\n\t\t}\n\n\t\tpublic void ExprMix4A()\n\t\t{\n\t\t\tB(((F(0) || F(1)) && F(2)) || F(3));\n\t\t}\n\n\t\tpublic void ExprMix4B()\n\t\t{\n\t\t\tB((F(0) || F(1)) && (F(2) || F(3)));\n\t\t}\n\n\t\tpublic void ExprMix4C()\n\t\t{\n\t\t\tB((F(0) && F(1)) || (F(2) && F(3)));\n\t\t}\n\n\t\tpublic void StmtAnd2()\n\t\t{\n\t\t\tif (F(0) && F(1))\n\t\t\t{\n\t\t\t\tM1();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tM2();\n\t\t\t}\n\t\t\tE();\n\t\t}\n\n\t\tpublic void StmtOr2A()\n\t\t{\n\t\t\tif (F(0) || F(1))\n\t\t\t{\n\t\t\t\tM1();\n\t\t\t}\n\t\t}\n\n\t\tpublic void StmtOr2B()\n\t\t{\n\t\t\tif (F(0) || F(1))\n\t\t\t{\n\t\t\t\tM1();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tM2();\n\t\t\t}\n\t\t\tE();\n\t\t}\n\n\t\tpublic void StmtAnd3()\n\t\t{\n\t\t\tif (F(0) && F(1) && F(2))\n\t\t\t{\n\t\t\t\tM1();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tM2();\n\t\t\t}\n\t\t\tE();\n\t\t}\n\n\t\tpublic void StmtOr3()\n\t\t{\n\t\t\tif (F(0) || F(1) || F(2))\n\t\t\t{\n\t\t\t\tM1();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tM2();\n\t\t\t}\n\t\t\tE();\n\t\t}\n\n\t\tpublic void StmtOr4()\n\t\t{\n\t\t\tif (GetInt(0) != 0 || GetInt(1) != 0)\n\t\t\t{\n\t\t\t\tM1();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tM2();\n\t\t\t}\n\t\t\tE();\n\t\t}\n\n\t\tpublic void StmtMix3A()\n\t\t{\n\t\t\tif ((F(0) || F(1)) && F(2))\n\t\t\t{\n\t\t\t\tM1();\n\t\t\t}\n\t\t}\n\n\t\tpublic void StmtMix3B()\n\t\t{\n\t\t\tif ((F(0) || F(1)) && F(2))\n\t\t\t{\n\t\t\t\tM1();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tM2();\n\t\t\t}\n\t\t}\n\n\t\tpublic void StmtMix4V1A()\n\t\t{\n\t\t\tif (((F(0) || F(1)) && F(2)) || F(3))\n\t\t\t{\n\t\t\t\tM1();\n\t\t\t}\n\t\t}\n\n\t\tpublic void StmtMix4V1B()\n\t\t{\n\t\t\tif (((F(0) || F(1)) && F(2)) || F(3))\n\t\t\t{\n\t\t\t\tM1();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tM2();\n\t\t\t}\n\t\t}\n\n\t\tpublic void StmtMix4V2A()\n\t\t{\n\t\t\tif ((F(0) || F(1)) && (F(2) || F(3)))\n\t\t\t{\n\t\t\t\tM1();\n\t\t\t}\n\t\t}\n\n\t\tpublic void StmtMix4V2B()\n\t\t{\n\t\t\tif ((F(0) || F(1)) && (F(2) || F(3)))\n\t\t\t{\n\t\t\t\tM1();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tM2();\n\t\t\t}\n\t\t}\n\n\t\tpublic void StmtMix4V3A()\n\t\t{\n\t\t\tif ((F(0) && F(1)) || (F(2) && F(3)))\n\t\t\t{\n\t\t\t\tM1();\n\t\t\t}\n\t\t}\n\n\t\tpublic void StmtMix4V3B()\n\t\t{\n\t\t\tif ((F(0) && F(1)) || (F(2) && F(3)))\n\t\t\t{\n\t\t\t\tM1();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tM2();\n\t\t\t}\n\t\t}\n\n\t\tpublic void StmtComplex()\n\t\t{\n\t\t\tif (F(0) && F(1) && !F(2) && (F(3) || F(4)))\n\t\t\t{\n\t\t\t\tM1();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tM2();\n\t\t\t}\n\t\t\tE();\n\t\t}\n\n\t\tpublic void StmtComplex2(int i)\n\t\t{\n\t\t\tif (i > 1000 || (i >= 1 && i <= 8) || i == 42)\n\t\t\t{\n\t\t\t\tM1();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tM2();\n\t\t\t}\n\t\t\tE();\n\t\t}\n\n\t\tpublic void StmtComplex3(int i)\n\t\t{\n\t\t\tif (i > 1000 || (i >= 1 && i <= 8) || (i >= 100 && i <= 200) || i == 42)\n\t\t\t{\n\t\t\t\tM1();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tM2();\n\t\t\t}\n\t\t\tE();\n\t\t}\n\n\t\tpublic void StmtComplex4(int i)\n\t\t{\n\t\t\tif (i > 1000 || (i >= 1 && i <= 8) || i == 42 || i == 23)\n\t\t\t{\n\t\t\t\tM1();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tM2();\n\t\t\t}\n\t\t\tE();\n\t\t}\n\n\t\tpublic void StmtComplex5()\n\t\t{\n\t\t\tif (F(0))\n\t\t\t{\n\t\t\t\tif (!F(1) && !F(2))\n\t\t\t\t{\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (!F(3) || !F(4))\n\t\t\t{\n\t\t\t\tM2();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tE();\n\t\t}\n\n\t\tpublic int StmtComplex6()\n\t\t{\n\t\t\tif (F(0))\n\t\t\t{\n\t\t\t\tM1();\n\t\t\t\tif (F(1) || F(2))\n\t\t\t\t{\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn 2;\n\t\t}\n\n\t\tpublic int InferCorrectOrder()\n\t\t{\n\t\t\tif (F(1) || F(2))\n\t\t\t{\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\treturn 2;\n\t\t}\n\n#if !OPT\n\t\tpublic void EmptyIf()\n\t\t{\n\t\t\tif (F(0))\n\t\t\t{\n\t\t\t}\n\t\t\tif (!F(1))\n\t\t\t{\n\t\t\t}\n\t\t\tif (F(4) || F(5))\n\t\t\t{\n\t\t\t}\n\t\t\tE();\n\t\t}\n#endif\n\n\t\tpublic void PreferLogicalToBitwise(bool a, bool b, int i, float f)\n\t\t{\n\t\t\tB(a && b);\n\t\t\tB(a && i == 1);\n\t\t\tB(i == 1 && a);\n\t\t\tB(i > i - 3 && a);\n\t\t\tB(f < 0.1f && a);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/StaticAbstractInterfaceMembers.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.StaticAbstractInterfaceMembers\n{\n\tinternal class C : I<C>\n\t{\n\t\tprivate string _s;\n\n\t\tstatic C I<C>.P { get; set; }\n\t\tstatic event Action I<C>.E {\n\t\t\tadd {\n\n\t\t\t}\n\t\t\tremove {\n\n\t\t\t}\n\t\t}\n\t\tpublic C(string s)\n\t\t{\n\t\t\t_s = s;\n\t\t}\n\n\t\tstatic void I<C>.M(object x)\n\t\t{\n\t\t\tConsole.WriteLine(\"Implementation\");\n\t\t}\n\t\tstatic C I<C>.operator +(C l, C r)\n\t\t{\n\t\t\treturn new C(l._s + \" \" + r._s);\n\t\t}\n\n\t\tstatic bool I<C>.operator ==(C l, C r)\n\t\t{\n\t\t\treturn l._s == r._s;\n\t\t}\n\n\t\tstatic bool I<C>.operator !=(C l, C r)\n\t\t{\n\t\t\treturn l._s != r._s;\n\t\t}\n\n\t\tstatic implicit I<C>.operator C(string s)\n\t\t{\n\t\t\treturn new C(s);\n\t\t}\n\n\t\tstatic explicit I<C>.operator string(C c)\n\t\t{\n\t\t\treturn c._s;\n\t\t}\n\t}\n\n\tinternal interface I<T> where T : I<T>\n\t{\n\t\tstatic abstract T P { get; set; }\n\t\tstatic abstract event Action E;\n\t\tstatic abstract void M(object x);\n\t\tstatic abstract T operator +(T l, T r);\n\t\tstatic abstract bool operator ==(T l, T r);\n\t\tstatic abstract bool operator !=(T l, T r);\n\t\tstatic abstract implicit operator T(string s);\n\t\tstatic abstract explicit operator string(T t);\n\t}\n\n\tpublic interface IAmSimple\n\t{\n\t\tstatic abstract int Capacity { get; }\n\t\tstatic abstract int Count { get; set; }\n\t\tstatic abstract int SetterOnly { set; }\n\t\tstatic abstract event EventHandler E;\n\t\tstatic abstract IAmSimple CreateI();\n\t}\n\n\tinternal interface IAmStatic<T> where T : IAmStatic<T>\n\t{\n\t\tstatic int f = 42;\n\t\tstatic T P { get; set; }\n\t\tstatic event Action E;\n\t\tstatic void M(object x)\n\t\t{\n\t\t}\n\t\tstatic IAmStatic<T> operator +(IAmStatic<T> l, IAmStatic<T> r)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\t}\n\n\tinternal interface IAmVirtual<T> where T : IAmVirtual<T>\n\t{\n\t\tstatic virtual T P { get; set; }\n\t\tstatic virtual event Action E;\n\t\tstatic virtual void M(object x)\n\t\t{\n\t\t}\n\t\tstatic virtual T operator +(T l, T r)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\t\tstatic virtual implicit operator T(string s)\n\t\t{\n\t\t\treturn default(T);\n\t\t}\n\t\tstatic virtual explicit operator string(T t)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tinternal class Uses\n\t{\n\t\tpublic static T TestVirtualStaticUse<T>(T a, T b) where T : IAmVirtual<T>\n\t\t{\n\t\t\tT.P = a;\n\t\t\ta = \"World\";\n\t\t\tT.E += null;\n\t\t\tT.E -= null;\n\t\t\tT.M(\"Hello\");\n\t\t\tUseString((string)b);\n\t\t\treturn a + b;\n\t\t}\n\t\tpublic static IAmStatic<T> TestStaticUse<T>(T a, T b) where T : IAmStatic<T>\n\t\t{\n\t\t\tIAmStatic<T>.f = 11;\n\t\t\tIAmStatic<T>.P = a;\n\t\t\tIAmStatic<T>.E += null;\n\t\t\tIAmStatic<T>.E -= null;\n\t\t\tIAmStatic<T>.M(\"Hello\");\n\t\t\treturn a + b;\n\t\t}\n\t\tpublic static I<T> TestAbstractStaticUse<T>(T a, T b) where T : I<T>\n\t\t{\n\t\t\tT.P = a;\n\t\t\ta = \"World\";\n\t\t\tT.E += null;\n\t\t\tT.E -= null;\n\t\t\tT.M(\"Hello\");\n\t\t\tUseString((string)b);\n\t\t\treturn a + b;\n\t\t}\n\t\tprivate static void UseString(string a)\n\t\t{\n\t\t}\n\t}\n\n\tpublic class X : IAmSimple\n\t{\n\t\tpublic static int Capacity { get; }\n\n\t\tpublic static int Count { get; set; }\n\n\t\tpublic static int SetterOnly {\n\t\t\tset {\n\t\t\t}\n\t\t}\n\n\t\tpublic static event EventHandler E;\n\n\t\tpublic static IAmSimple CreateI()\n\t\t{\n\t\t\treturn new X();\n\t\t}\n\t}\n\n\tpublic class X2 : IAmSimple\n\t{\n\t\tpublic static int Capacity {\n\t\t\tget {\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n\n\t\tpublic static int Count {\n\t\t\tget {\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tset {\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n\t\tpublic static int SetterOnly {\n\t\t\tset {\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n\n\t\tpublic static event EventHandler E {\n\t\t\tadd {\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tremove {\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n\n\t\tpublic static IAmSimple CreateI()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\t}\n\n\tinternal class ZOperatorTest\n\t{\n\n\t\tpublic interface IGetNext<T> where T : IGetNext<T>\n\t\t{\n\t\t\tstatic abstract T operator ++(T other);\n\t\t}\n\n\t\tpublic struct WrappedInteger : IGetNext<WrappedInteger>\n\t\t{\n\t\t\tpublic int Value;\n\n\t\t\tpublic static WrappedInteger operator ++(WrappedInteger other)\n\t\t\t{\n\t\t\t\tWrappedInteger result = other;\n\t\t\t\tresult.Value++;\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\n\t\tpublic void GenericUse<T>(T t) where T : IGetNext<T>\n\t\t{\n\t\t\t++t;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/StringInterpolation.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class StringInterpolation\n\t{\n\t\tpublic static void Main(string[] args)\n\t\t{\n\t\t}\n\n\t\tpublic static void General(string[] args)\n\t\t{\n\t\t\tConsole.WriteLine($\"{args.Length}\");\n\t\t\tConsole.WriteLine($\"a{{0{args.Length}\");\n\t\t\tConsole.WriteLine($\"{args.Length:x}\");\n\t\t\tConsole.WriteLine($\"\\ta{args.Length}b\");\n\t\t\tConsole.WriteLine($\"\\ta{args.Length}ba{args[0]}a{args[args.Length]}a{args.Length}\");\n\t\t\tConsole.WriteLine($\"\\ta{((args.Length != 0) ? 5 : 0)}\");\n\t\t\tConsole.WriteLine($\"\\ta{args ?? args}\");\n\t\t\tConsole.WriteLine($\"\\ta{args[0][0] == 'a'}\");\n\t\t\tConsole.WriteLine($\"\\ta{$\"a{args.Length}\" == args[0]}\");\n\t\t\tConsole.WriteLine($\"\\ta{args.Length}}}\");\n\t\t\tConsole.WriteLine($\"{args.Length,5:x}\");\n\t\t\tConsole.WriteLine($\"{args.Length,5}\");\n\t\t}\n\n\t\tpublic static void Types()\n\t\t{\n\t\t\tConsole.WriteLine($\"{(int)Get<long>()}\");\n\t\t}\n\n\t\tpublic static void ArrayExpansionSpecialCases(object[] args)\n\t\t{\n\t\t\tConsole.WriteLine($\"args: {args}\");\n\t\t\tConsole.WriteLine(string.Format(\"args: {0}\", args));\n\t\t}\n\n\t\tpublic static void InvalidFormatString(string[] args)\n\t\t{\n#pragma warning disable IDE0043\n\t\t\tConsole.WriteLine(string.Format(\"\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"a\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"}\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"{\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\":\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"\\t\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"\\\\\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"\\\"\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"aa\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"a}\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"a{\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"a:\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"a\\t\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"a\\\\\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"a\\\"\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"a{:\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"a{0\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"a{{0\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"}a{{0\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"}{\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"{}\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"{0:}\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"{0{a}0}\", args.Length));\n\t\t\tConsole.WriteLine(string.Format(\"test: {0}\", string.Join(\",\", args)));\n\t\t\tConsole.WriteLine(string.Format(\"test: {0}}\", args.Length));\n#pragma warning restore\n\t\t}\n\n\t\tpublic void FormattableStrings(FormattableString s, string[] args)\n\t\t{\n\t\t\ts = $\"{args.Length}\";\n\t\t\ts = $\"a{{0{args.Length}\";\n\t\t\ts = $\"{args.Length:x}\";\n\t\t\ts = $\"\\ta{args.Length}b\";\n\t\t\ts = $\"\\ta{args.Length}ba{args[0]}a{args[args.Length]}a{args.Length}\";\n\t\t\ts = $\"\\ta{((args.Length != 0) ? 5 : 0)}\";\n\t\t\ts = $\"\\ta{args ?? args}\";\n\t\t\ts = $\"\\ta{args[0][0] == 'a'}\";\n\t\t\ts = $\"\\ta{$\"a{args.Length}\" == args[0]}\";\n\t\t\tRequiresCast($\"{args.Length}\");\n\t\t\tRequiresCast($\"a{{0{args.Length}\");\n\t\t\tRequiresCast($\"{args.Length:x}\");\n\t\t\tRequiresCast($\"\\ta{args.Length}b\");\n\t\t\tRequiresCast($\"\\ta{args.Length}ba{args[0]}a{args[args.Length]}a{args.Length}\");\n\t\t\tRequiresCast($\"\\ta{((args.Length != 0) ? 5 : 0)}\");\n\t\t\tRequiresCast($\"\\ta{args ?? args}\");\n\t\t\tRequiresCast($\"\\ta{args[0][0] == 'a'}\");\n\t\t\tRequiresCast($\"\\ta{$\"a{args.Length}\" == args[0]}\");\n\t\t\tRequiresCast((FormattableString)$\"{args.Length}\");\n\t\t\tRequiresCast((FormattableString)$\"a{{0{args.Length}\");\n\t\t\tRequiresCast((FormattableString)$\"{args.Length:x}\");\n\t\t\tRequiresCast((FormattableString)$\"\\ta{args.Length}b\");\n\t\t\tRequiresCast((FormattableString)$\"\\ta{args.Length}ba{args[0]}a{args[args.Length]}a{args.Length}\");\n\t\t\tRequiresCast((FormattableString)$\"\\ta{((args.Length != 0) ? 5 : 0)}\");\n\t\t\tRequiresCast((FormattableString)$\"\\ta{args ?? args}\");\n\t\t\tRequiresCast((FormattableString)$\"\\ta{args[0][0] == 'a'}\");\n\t\t\tRequiresCast((FormattableString)$\"\\ta{$\"a{args.Length}\" == args[0]}\");\n\t\t\tRequiresCast((IFormattable)$\"{args.Length}\");\n\t\t\tRequiresCast((IFormattable)$\"a{{0{args.Length}\");\n\t\t\tRequiresCast((IFormattable)$\"{args.Length:x}\");\n\t\t\tRequiresCast((IFormattable)$\"\\ta{args.Length}b\");\n\t\t\tRequiresCast((IFormattable)$\"\\ta{args.Length}ba{args[0]}a{args[args.Length]}a{args.Length}\");\n\t\t\tRequiresCast((IFormattable)$\"\\ta{((args.Length != 0) ? 5 : 0)}\");\n\t\t\tRequiresCast((IFormattable)$\"\\ta{args ?? args}\");\n\t\t\tRequiresCast((IFormattable)$\"\\ta{args[0][0] == 'a'}\");\n\t\t\tRequiresCast((IFormattable)$\"\\ta{$\"a{args.Length}\" == args[0]}\");\n\t\t}\n\n\t\tpublic void Issue1497(string[] args)\n\t\t{\n\t\t\tConsole.WriteLine($\"args[0]: {args[0].Trim(':').Trim('&').Trim(':').Trim('&')} asdf {args.Length:x} test\");\n\t\t}\n\n\t\tpublic void RequiresCast(string value)\n\t\t{\n\t\t}\n\n\t\tpublic void RequiresCast(FormattableString value)\n\t\t{\n\t\t}\n\n\t\tpublic void RequiresCast(IFormattable value)\n\t\t{\n\t\t}\n\n\t\tpublic string ConcatStringCharSC(string s, char c)\n\t\t{\n\t\t\treturn s + c;\n\t\t}\n\n\t\tpublic string ConcatStringCharCS(string s, char c)\n\t\t{\n\t\t\treturn c + s;\n\t\t}\n\n\t\tpublic string ConcatStringCharSCS(string s, char c)\n\t\t{\n\t\t\treturn s + c + s;\n\t\t}\n\n\t\tpublic string ConcatStringCharCSS(string s, char c)\n\t\t{\n\t\t\treturn c + s + s;\n\t\t}\n\n\t\tpublic string ConcatStringCharCSSC(string s, char c)\n\t\t{\n\t\t\treturn c + s + s + c;\n\t\t}\n\n\t\tpublic static TReturn Get<TReturn>()\n\t\t{\n\t\t\treturn default(TReturn);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Structs.cs",
    "content": "// Copyright (c) 2021 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Runtime.InteropServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\t[StructLayout(LayoutKind.Sequential, Size = 1)]\n\tpublic struct EmptyStruct\n\t{\n\t}\n\n\tpublic class Structs\n\t{\n#if CS100\n\t\tpublic StructWithDefaultCtor M()\n\t\t{\n\t\t\treturn default(StructWithDefaultCtor);\n\t\t}\n\n\t\tpublic StructWithDefaultCtor M2()\n\t\t{\n\t\t\treturn new StructWithDefaultCtor();\n\t\t}\n#endif\n\t}\n\n#if CS100\n\tpublic struct StructWithDefaultCtor\n\t{\n\t\tpublic int X = 42;\n\n\t\tpublic StructWithDefaultCtor()\n\t\t{\n\t\t}\n\t}\n#endif\n\n#if CS110\n\tpublic struct StructWithRequiredMembers\n\t{\n\t\tpublic required string FirstName;\n\t\tpublic required string LastName { get; set; }\n\t}\n#endif\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic static class Switch\n\t{\n\t\tpublic class SetProperty\n\t\t{\n\t\t\tpublic readonly PropertyInfo Property;\n\n\t\t\tpublic int Set { get; set; }\n\n\t\t\tpublic SetProperty(PropertyInfo property)\n\t\t\t{\n\t\t\t\tProperty = property;\n\t\t\t}\n\t\t}\n\n\t\tpublic class ImplicitString\n\t\t{\n\t\t\tprivate readonly string s;\n\n\t\t\tpublic ImplicitString(string s)\n\t\t\t{\n\t\t\t\tthis.s = s;\n\t\t\t}\n\n\t\t\tpublic static implicit operator string(ImplicitString v)\n\t\t\t{\n\t\t\t\treturn v.s;\n\t\t\t}\n\t\t}\n\n\t\tpublic class ExplicitString\n\t\t{\n\t\t\tprivate readonly string s;\n\n\t\t\tpublic ExplicitString(string s)\n\t\t\t{\n\t\t\t\tthis.s = s;\n\t\t\t}\n\n\t\t\tpublic static explicit operator string(ExplicitString v)\n\t\t\t{\n\t\t\t\treturn v.s;\n\t\t\t}\n\t\t}\n\n\t\tpublic class ImplicitInt\n\t\t{\n\t\t\tprivate readonly int s;\n\n\t\t\tpublic ImplicitInt(int s)\n\t\t\t{\n\t\t\t\tthis.s = s;\n\t\t\t}\n\n\t\t\tpublic static implicit operator int(ImplicitInt v)\n\t\t\t{\n\t\t\t\treturn v.s;\n\t\t\t}\n\t\t}\n\n\t\tpublic class ImplicitConversionConflictWithLong\n\t\t{\n\t\t\tprivate readonly int s;\n\n\t\t\tpublic ImplicitConversionConflictWithLong(int s)\n\t\t\t{\n\t\t\t\tthis.s = s;\n\t\t\t}\n\n\t\t\tpublic static implicit operator int(ImplicitConversionConflictWithLong v)\n\t\t\t{\n\t\t\t\treturn v.s;\n\t\t\t}\n\n\t\t\tpublic static implicit operator long(ImplicitConversionConflictWithLong v)\n\t\t\t{\n\t\t\t\treturn v.s;\n\t\t\t}\n\t\t}\n\n\t\tpublic class ImplicitConversionConflictWithString\n\t\t{\n\t\t\tprivate readonly int s;\n\n\t\t\tpublic ImplicitConversionConflictWithString(int s)\n\t\t\t{\n\t\t\t\tthis.s = s;\n\t\t\t}\n\n\t\t\tpublic static implicit operator int(ImplicitConversionConflictWithString v)\n\t\t\t{\n\t\t\t\treturn v.s;\n\t\t\t}\n\n\t\t\tpublic static implicit operator string(ImplicitConversionConflictWithString v)\n\t\t\t{\n\t\t\t\treturn string.Empty;\n\t\t\t}\n\t\t}\n\n\t\tpublic class ExplicitInt\n\t\t{\n\t\t\tprivate readonly int s;\n\n\t\t\tpublic ExplicitInt(int s)\n\t\t\t{\n\t\t\t\tthis.s = s;\n\t\t\t}\n\n\t\t\tpublic static explicit operator int(ExplicitInt v)\n\t\t\t{\n\t\t\t\treturn v.s;\n\t\t\t}\n\t\t}\n\n\t\tpublic enum State\n\t\t{\n\t\t\tFalse,\n\t\t\tTrue,\n\t\t\tNull\n\t\t}\n\n\t\tpublic enum KnownColor\n\t\t{\n\t\t\tDarkBlue,\n\t\t\tDarkCyan,\n\t\t\tDarkGoldenrod,\n\t\t\tDarkGray,\n\t\t\tDarkGreen,\n\t\t\tDarkKhaki\n\t\t}\n\n\t\tprivate static char ch1767;\n\n#if !ROSLYN\n\t\tpublic static State SwitchOverNullableBool(bool? value)\n\t\t{\n\t\t\tswitch (value)\n\t\t\t{\n\t\t\t\tcase false:\n\t\t\t\t\treturn State.False;\n\t\t\t\tcase true:\n\t\t\t\t\treturn State.True;\n\t\t\t\tcase null:\n\t\t\t\t\treturn State.Null;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new InvalidOperationException();\n\t\t\t}\n\t\t}\n#endif\n\n\t\tpublic static bool? SwitchOverNullableEnum(State? state)\n\t\t{\n\t\t\tswitch (state)\n\t\t\t{\n\t\t\t\tcase State.False:\n\t\t\t\t\treturn false;\n\t\t\t\tcase State.True:\n\t\t\t\t\treturn true;\n\t\t\t\tcase State.Null:\n\t\t\t\t\treturn null;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new InvalidOperationException();\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SparseIntegerSwitch(int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"SparseIntegerSwitch: \" + i);\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase -10000000:\n\t\t\t\t\treturn \"-10 mln\";\n\t\t\t\tcase -100:\n\t\t\t\t\treturn \"-hundred\";\n\t\t\t\tcase -1:\n\t\t\t\t\treturn \"-1\";\n\t\t\t\tcase 0:\n\t\t\t\t\treturn \"0\";\n\t\t\t\tcase 1:\n\t\t\t\t\treturn \"1\";\n\t\t\t\tcase 2:\n\t\t\t\t\treturn \"2\";\n\t\t\t\tcase 4:\n\t\t\t\t\treturn \"4\";\n\t\t\t\tcase 100:\n\t\t\t\t\treturn \"hundred\";\n\t\t\t\tcase 10000:\n\t\t\t\t\treturn \"ten thousand\";\n\t\t\t\tcase 10001:\n\t\t\t\t\treturn \"ten thousand and one\";\n\t\t\t\tcase int.MaxValue:\n\t\t\t\t\treturn \"int.MaxValue\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"something else\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SparseIntegerSwitch2(int i)\n\t\t{\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase 4:\n\t\t\t\tcase 10:\n\t\t\t\tcase 11:\n\t\t\t\tcase 13:\n\t\t\t\tcase 21:\n\t\t\t\tcase 29:\n\t\t\t\tcase 33:\n\t\t\t\tcase 49:\n\t\t\t\tcase 50:\n\t\t\t\tcase 55:\n\t\t\t\t\tConsole.WriteLine();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic static bool SparseIntegerSwitch3(int i)\n\t\t{\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\tcase 10:\n\t\t\t\tcase 11:\n\t\t\t\tcase 12:\n\t\t\t\tcase 100:\n\t\t\t\tcase 101:\n\t\t\t\tcase 200:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverNullableInt(int? i)\n\t\t{\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase null:\n\t\t\t\t\treturn \"null\";\n\t\t\t\tcase 0:\n\t\t\t\t\treturn \"zero\";\n\t\t\t\tcase 5:\n\t\t\t\t\treturn \"five\";\n\t\t\t\tcase 10:\n\t\t\t\t\treturn \"ten\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"large\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverNullableIntNullCaseCombined(int? i)\n\t\t{\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase null:\n\t\t\t\tcase 0:\n\t\t\t\t\treturn \"zero\";\n\t\t\t\tcase 5:\n\t\t\t\t\treturn \"five\";\n\t\t\t\tcase 10:\n\t\t\t\t\treturn \"ten\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"large\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverNullableIntShifted(int? i)\n\t\t{\n\t\t\tswitch (i + 5)\n\t\t\t{\n\t\t\t\tcase null:\n\t\t\t\t\treturn \"null\";\n\t\t\t\tcase 0:\n\t\t\t\t\treturn \"zero\";\n\t\t\t\tcase 5:\n\t\t\t\t\treturn \"five\";\n\t\t\t\tcase 10:\n\t\t\t\t\treturn \"ten\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"large\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverNullableIntShiftedNullCaseCombined(int? i)\n\t\t{\n\t\t\tswitch (i + 5)\n\t\t\t{\n\t\t\t\tcase null:\n\t\t\t\tcase 0:\n\t\t\t\t\treturn \"zero\";\n\t\t\t\tcase 5:\n\t\t\t\t\treturn \"five\";\n\t\t\t\tcase 10:\n\t\t\t\t\treturn \"ten\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"large\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverNullableIntNoNullCase(int? i)\n\t\t{\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn \"zero\";\n\t\t\t\tcase 5:\n\t\t\t\t\treturn \"five\";\n\t\t\t\tcase 10:\n\t\t\t\t\treturn \"ten\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"other\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverNullableIntNoNullCaseShifted(int? i)\n\t\t{\n\t\t\tswitch (i + 5)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn \"zero\";\n\t\t\t\tcase 5:\n\t\t\t\t\treturn \"five\";\n\t\t\t\tcase 10:\n\t\t\t\t\treturn \"ten\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"other\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SwitchOverInt(int i)\n\t\t{\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tConsole.WriteLine(\"zero\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 5:\n\t\t\t\t\tConsole.WriteLine(\"five\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 10:\n\t\t\t\t\tConsole.WriteLine(\"ten\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 15:\n\t\t\t\t\tConsole.WriteLine(\"fifteen\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 20:\n\t\t\t\t\tConsole.WriteLine(\"twenty\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 25:\n\t\t\t\t\tConsole.WriteLine(\"twenty-five\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 30:\n\t\t\t\t\tConsole.WriteLine(\"thirty\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SwitchOverExplicitInt(ExplicitInt i)\n\t\t{\n\t\t\tswitch ((int)i)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tConsole.WriteLine(\"zero\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 5:\n\t\t\t\t\tConsole.WriteLine(\"five\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 10:\n\t\t\t\t\tConsole.WriteLine(\"ten\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 15:\n\t\t\t\t\tConsole.WriteLine(\"fifteen\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 20:\n\t\t\t\t\tConsole.WriteLine(\"twenty\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 25:\n\t\t\t\t\tConsole.WriteLine(\"twenty-five\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 30:\n\t\t\t\t\tConsole.WriteLine(\"thirty\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SwitchOverImplicitInt(ImplicitInt i)\n\t\t{\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tConsole.WriteLine(\"zero\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 5:\n\t\t\t\t\tConsole.WriteLine(\"five\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 10:\n\t\t\t\t\tConsole.WriteLine(\"ten\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 15:\n\t\t\t\t\tConsole.WriteLine(\"fifteen\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 20:\n\t\t\t\t\tConsole.WriteLine(\"twenty\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 25:\n\t\t\t\t\tConsole.WriteLine(\"twenty-five\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 30:\n\t\t\t\t\tConsole.WriteLine(\"thirty\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SwitchOverImplicitIntConflictLong(ImplicitConversionConflictWithLong i)\n\t\t{\n\t\t\tswitch ((int)i)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tConsole.WriteLine(\"zero\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 5:\n\t\t\t\t\tConsole.WriteLine(\"five\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 10:\n\t\t\t\t\tConsole.WriteLine(\"ten\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 15:\n\t\t\t\t\tConsole.WriteLine(\"fifteen\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 20:\n\t\t\t\t\tConsole.WriteLine(\"twenty\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 25:\n\t\t\t\t\tConsole.WriteLine(\"twenty-five\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 30:\n\t\t\t\t\tConsole.WriteLine(\"thirty\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SwitchOverImplicitIntConflictString(ImplicitConversionConflictWithString i)\n\t\t{\n\t\t\tswitch ((string)i)\n\t\t\t{\n\t\t\t\tcase \"0\":\n\t\t\t\t\tConsole.WriteLine(\"zero\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"5\":\n\t\t\t\t\tConsole.WriteLine(\"five\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"10\":\n\t\t\t\t\tConsole.WriteLine(\"ten\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"15\":\n\t\t\t\t\tConsole.WriteLine(\"fifteen\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"20\":\n\t\t\t\t\tConsole.WriteLine(\"twenty\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"25\":\n\t\t\t\t\tConsole.WriteLine(\"twenty-five\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"30\":\n\t\t\t\t\tConsole.WriteLine(\"thirty\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// SwitchDetection.UseCSharpSwitch requires more complex heuristic to identify this when compiled with Roslyn\n\t\tpublic static void CompactSwitchOverInt(int i)\n\t\t{\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\tcase 1:\n\t\t\t\tcase 2:\n\t\t\t\t\tConsole.WriteLine(\"012\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3:\n\t\t\t\t\tConsole.WriteLine(\"3\");\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\n\t\tpublic static string ShortSwitchOverString(string text)\n\t\t{\n\t\t\tConsole.WriteLine(\"ShortSwitchOverString: \" + text);\n\t\t\tswitch (text)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase \"Third case\":\n\t\t\t\t\treturn \"Text3\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string ShortSwitchOverStringWithNullCase(string text)\n\t\t{\n\t\t\tConsole.WriteLine(\"ShortSwitchOverStringWithNullCase: \" + text);\n\t\t\tswitch (text)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase null:\n\t\t\t\t\treturn \"null\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverString1(string text)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchOverString1: \" + text);\n\t\t\tswitch (text)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\tcase \"2nd case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase \"Third case\":\n\t\t\t\t\treturn \"Text3\";\n\t\t\t\tcase \"Fourth case\":\n\t\t\t\t\treturn \"Text4\";\n\t\t\t\tcase \"Fifth case\":\n\t\t\t\t\treturn \"Text5\";\n\t\t\t\tcase \"Sixth case\":\n\t\t\t\t\treturn \"Text6\";\n\t\t\t\tcase null:\n\t\t\t\t\treturn null;\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverString2()\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchOverString2:\");\n\t\t\tswitch (Environment.UserName)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase \"Third case\":\n\t\t\t\t\treturn \"Text3\";\n\t\t\t\tcase \"Fourth case\":\n\t\t\t\t\treturn \"Text4\";\n\t\t\t\tcase \"Fifth case\":\n\t\t\t\t\treturn \"Text5\";\n\t\t\t\tcase \"Sixth case\":\n\t\t\t\t\treturn \"Text6\";\n\t\t\t\tcase \"Seventh case\":\n\t\t\t\t\treturn \"Text7\";\n\t\t\t\tcase \"Eighth case\":\n\t\t\t\t\treturn \"Text8\";\n\t\t\t\tcase \"Ninth case\":\n\t\t\t\t\treturn \"Text9\";\n\t\t\t\tcase \"Tenth case\":\n\t\t\t\t\treturn \"Text10\";\n\t\t\t\tcase \"Eleventh case\":\n\t\t\t\t\treturn \"Text11\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverImplicitString(ImplicitString s)\n\t\t{\n\t\t\tswitch (s)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase \"Third case\":\n\t\t\t\t\treturn \"Text3\";\n\t\t\t\tcase \"Fourth case\":\n\t\t\t\t\treturn \"Text4\";\n\t\t\t\tcase \"Fifth case\":\n\t\t\t\t\treturn \"Text5\";\n\t\t\t\tcase \"Sixth case\":\n\t\t\t\t\treturn \"Text6\";\n\t\t\t\tcase \"Seventh case\":\n\t\t\t\t\treturn \"Text7\";\n\t\t\t\tcase \"Eighth case\":\n\t\t\t\t\treturn \"Text8\";\n\t\t\t\tcase \"Ninth case\":\n\t\t\t\t\treturn \"Text9\";\n\t\t\t\tcase \"Tenth case\":\n\t\t\t\t\treturn \"Text10\";\n\t\t\t\tcase \"Eleventh case\":\n\t\t\t\t\treturn \"Text11\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverExplicitString(ExplicitString s)\n\t\t{\n\t\t\tswitch ((string)s)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase \"Third case\":\n\t\t\t\t\treturn \"Text3\";\n\t\t\t\tcase \"Fourth case\":\n\t\t\t\t\treturn \"Text4\";\n\t\t\t\tcase \"Fifth case\":\n\t\t\t\t\treturn \"Text5\";\n\t\t\t\tcase \"Sixth case\":\n\t\t\t\t\treturn \"Text6\";\n\t\t\t\tcase \"Seventh case\":\n\t\t\t\t\treturn \"Text7\";\n\t\t\t\tcase \"Eighth case\":\n\t\t\t\t\treturn \"Text8\";\n\t\t\t\tcase \"Ninth case\":\n\t\t\t\t\treturn \"Text9\";\n\t\t\t\tcase \"Tenth case\":\n\t\t\t\t\treturn \"Text10\";\n\t\t\t\tcase \"Eleventh case\":\n\t\t\t\t\treturn \"Text11\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n#if !ROSLYN\n\t\tpublic static string SwitchOverBool(bool b)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchOverBool: \" + b);\n\t\t\tswitch (b)\n\t\t\t{\n\t\t\t\tcase true:\n\t\t\t\t\treturn bool.TrueString;\n\t\t\t\tcase false:\n\t\t\t\t\treturn bool.FalseString;\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n#endif\n\n\t\tpublic static void SwitchInLoop(int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchInLoop: \" + i);\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tswitch (i)\n\t\t\t\t{\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tConsole.WriteLine(\"one\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tConsole.WriteLine(\"two\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t//case 3:\n\t\t\t\t\t//\t\tConsole.WriteLine(\"three\");\n\t\t\t\t\t//\t\tcontinue;\n\t\t\t\t\tcase 4:\n\t\t\t\t\t\tConsole.WriteLine(\"four\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t\t\t\tConsole.WriteLine(\"more code\");\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SwitchWithGoto(int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchWithGoto: \" + i);\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase 1:\n\t\t\t\t\tConsole.WriteLine(\"one\");\n\t\t\t\t\tgoto default;\n\t\t\t\tcase 2:\n\t\t\t\t\tConsole.WriteLine(\"two\");\n\t\t\t\t\tgoto case 3;\n\t\t\t\tcase 3:\n\t\t\t\t\tConsole.WriteLine(\"three\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 4:\n\t\t\t\t\tConsole.WriteLine(\"four\");\n\t\t\t\t\treturn;\n\t\t\t\tdefault:\n\t\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"End of method\");\n\t\t}\n\n\t\t// Needs to be long enough to generate a hashtable\n\t\tpublic static void SwitchWithGotoString(string s)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchWithGotoString: \" + s);\n\t\t\tswitch (s)\n\t\t\t{\n\t\t\t\tcase \"1\":\n\t\t\t\t\tConsole.WriteLine(\"one\");\n\t\t\t\t\tgoto default;\n\t\t\t\tcase \"2\":\n\t\t\t\t\tConsole.WriteLine(\"two\");\n\t\t\t\t\tgoto case \"3\";\n\t\t\t\tcase \"3\":\n\t\t\t\t\tConsole.WriteLine(\"three\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"4\":\n\t\t\t\t\tConsole.WriteLine(\"four\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"5\":\n\t\t\t\t\tConsole.WriteLine(\"five\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"6\":\n\t\t\t\t\tConsole.WriteLine(\"six\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"7\":\n\t\t\t\t\tConsole.WriteLine(\"seven\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"8\":\n\t\t\t\t\tConsole.WriteLine(\"eight\");\n\t\t\t\t\treturn;\n\t\t\t\tcase \"9\":\n\t\t\t\t\tConsole.WriteLine(\"nine\");\n\t\t\t\t\treturn;\n\t\t\t\tdefault:\n\t\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"End of method\");\n\t\t}\n\n\t\tpublic static void SwitchWithGotoComplex(string s)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchWithGotoComplex: \" + s);\n\t\t\tswitch (s)\n\t\t\t{\n\t\t\t\tcase \"1\":\n\t\t\t\t\tConsole.WriteLine(\"one\");\n\t\t\t\t\tgoto case \"8\";\n\t\t\t\tcase \"2\":\n\t\t\t\t\tConsole.WriteLine(\"two\");\n\t\t\t\t\tgoto case \"3\";\n\t\t\t\tcase \"3\":\n\t\t\t\t\tConsole.WriteLine(\"three\");\n\t\t\t\t\tif (s.Length != 2)\n\t\t\t\t\t{\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tgoto case \"5\";\n\t\t\t\tcase \"4\":\n\t\t\t\t\tConsole.WriteLine(\"four\");\n\t\t\t\t\tgoto case \"5\";\n\t\t\t\tcase \"5\":\n\t\t\t\t\tConsole.WriteLine(\"five\");\n\t\t\t\t\tgoto case \"8\";\n\t\t\t\tcase \"6\":\n\t\t\t\t\tConsole.WriteLine(\"six\");\n\t\t\t\t\tgoto case \"5\";\n\t\t\t\tcase \"8\":\n\t\t\t\t\tConsole.WriteLine(\"eight\");\n\t\t\t\t\treturn;\n\t\t\t\t// add a default case so that case \"7\": isn't redundant\n\t\t\t\tdefault:\n\t\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t\t\tbreak;\n\t\t\t\t// note that goto case \"7\" will decompile as break;\n\t\t\t\t// cases with a single break have the highest IL offset and are moved to the bottom\n\t\t\t\tcase \"7\":\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"End of method\");\n\t\t}\n\n\t\tprivate static SetProperty[] GetProperties()\n\t\t{\n\t\t\treturn new SetProperty[0];\n\t\t}\n\n\t\tpublic static void SwitchOnStringInForLoop()\n\t\t{\n\t\t\tList<SetProperty> list = new List<SetProperty>();\n\t\t\tList<SetProperty> list2 = new List<SetProperty>();\n\t\t\tSetProperty[] properties = GetProperties();\n\t\t\tfor (int i = 0; i < properties.Length; i++)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"In for-loop\");\n\t\t\t\tSetProperty setProperty = properties[i];\n\t\t\t\tswitch (setProperty.Property.Name)\n\t\t\t\t{\n\t\t\t\t\tcase \"Name1\":\n\t\t\t\t\t\tsetProperty.Set = 1;\n\t\t\t\t\t\tlist.Add(setProperty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Name2\":\n\t\t\t\t\t\tsetProperty.Set = 2;\n\t\t\t\t\t\tlist.Add(setProperty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Name3\":\n\t\t\t\t\t\tsetProperty.Set = 3;\n\t\t\t\t\t\tlist.Add(setProperty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Name4\":\n\t\t\t\t\t\tsetProperty.Set = 4;\n\t\t\t\t\t\tlist.Add(setProperty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Name5\":\n\t\t\t\t\tcase \"Name6\":\n\t\t\t\t\t\tlist.Add(setProperty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tlist2.Add(setProperty);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SwitchInTryBlock(string value)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tswitch (value.Substring(5))\n\t\t\t\t{\n\t\t\t\t\tcase \"Name1\":\n\t\t\t\t\t\tConsole.WriteLine(\"1\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Name2\":\n\t\t\t\t\t\tConsole.WriteLine(\"Name_2\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Name3\":\n\t\t\t\t\t\tConsole.WriteLine(\"Name_3\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Name4\":\n\t\t\t\t\t\tConsole.WriteLine(\"No. 4\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Name5\":\n\t\t\t\t\tcase \"Name6\":\n\t\t\t\t\t\tConsole.WriteLine(\"5+6\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"catch block\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SwitchWithComplexCondition(string[] args)\n\t\t{\n\t\t\tswitch ((args.Length == 0) ? \"dummy\" : args[0])\n\t\t\t{\n\t\t\t\tcase \"a\":\n\t\t\t\t\tConsole.WriteLine(\"a\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"b\":\n\t\t\t\t\tConsole.WriteLine(\"b\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"c\":\n\t\t\t\t\tConsole.WriteLine(\"c\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"d\":\n\t\t\t\t\tConsole.WriteLine(\"d\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\n\t\tpublic static void SwitchWithArray(string[] args)\n\t\t{\n\t\t\tswitch (args[0])\n\t\t\t{\n\t\t\t\tcase \"a\":\n\t\t\t\t\tConsole.WriteLine(\"a\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"b\":\n\t\t\t\t\tConsole.WriteLine(\"b\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"c\":\n\t\t\t\t\tConsole.WriteLine(\"c\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"d\":\n\t\t\t\t\tConsole.WriteLine(\"d\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\n\t\tpublic static void SwitchWithContinue1(int i, bool b)\n\t\t{\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tswitch (i)\n\t\t\t\t{\n#if OPT\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tcontinue;\n#endif\n\t\t\t\t\tcase 0:\n\t\t\t\t\t\tif (b)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tif (!b)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n#if !OPT\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tcontinue;\n#endif\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t}\n\n\t\t// while condition, return and break cases\n\t\tpublic static void SwitchWithContinue2(int i, bool b)\n\t\t{\n\t\t\twhile (i < 10)\n\t\t\t{\n\t\t\t\tswitch (i)\n\t\t\t\t{\n\t\t\t\t\tcase 0:\n\t\t\t\t\t\tif (b)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tConsole.WriteLine(\"0b\");\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tConsole.WriteLine(\"0!b\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n#if OPT\n\t\t\t\t\t\tif (b)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tConsole.WriteLine(\"2b\");\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tConsole.WriteLine(\"2!b\");\n\t\t\t\t\t\tcontinue;\n#else\n\t\t\t\t\t\tif (!b)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tConsole.WriteLine(\"2!b\");\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tConsole.WriteLine(\"2b\");\n\t\t\t\t\t\treturn;\n#endif\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(\"loop-tail\");\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\n\t\t// for loop version\n\t\tpublic static void SwitchWithContinue3(bool b)\n\t\t{\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tswitch (i)\n\t\t\t\t{\n\t\t\t\t\tcase 0:\n\t\t\t\t\t\tif (b)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tConsole.WriteLine(\"0b\");\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tConsole.WriteLine(\"0!b\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n#if OPT\n\t\t\t\t\t\tif (b)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tConsole.WriteLine(\"2b\");\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tConsole.WriteLine(\"2!b\");\n\t\t\t\t\t\tcontinue;\n#else\n\t\t\t\t\t\tif (!b)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tConsole.WriteLine(\"2!b\");\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tConsole.WriteLine(\"2b\");\n\t\t\t\t\t\treturn;\n#endif\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(\"loop-tail\");\n\t\t\t}\n\t\t}\n\n\t\t// foreach version\n\t\tpublic static void SwitchWithContinue4(bool b)\n\t\t{\n\t\t\tforeach (int item in Enumerable.Range(0, 10))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"loop: \" + item);\n\t\t\t\tswitch (item)\n\t\t\t\t{\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tif (b)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\tif (!b)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\tcase 4:\n\t\t\t\t\t\tConsole.WriteLine(4);\n\t\t\t\t\t\tgoto case 7;\n\t\t\t\t\tcase 5:\n\t\t\t\t\t\tConsole.WriteLine(5);\n\t\t\t\t\t\tgoto default;\n\t\t\t\t\tcase 6:\n\t\t\t\t\t\tif (b)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tgoto case 3;\n\t\t\t\t\tcase 7:\n\t\t\t\t\t\tif (item % 2 == 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tgoto case 3;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!b)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tgoto case 8;\n\t\t\t\t\tcase 8:\n\t\t\t\t\t\tif (b)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tgoto case 5;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(\"break: \" + item);\n\t\t\t}\n\t\t}\n\t\t// internal if statement, loop increment block not dominated by the switch head\n\t\tpublic static void SwitchWithContinue5(bool b)\n\t\t{\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tif (i < 5)\n\t\t\t\t{\n\t\t\t\t\tswitch (i)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase 0:\n\t\t\t\t\t\t\tif (b)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tConsole.WriteLine(\"0b\");\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tConsole.WriteLine(\"0!b\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 2:\n#if OPT\n\t\t\t\t\t\t\tif (b)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tConsole.WriteLine(\"2b\");\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tConsole.WriteLine(\"2!b\");\n\t\t\t\t\t\t\tcontinue;\n#else\n\t\t\t\t\t\t\tif (!b)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tConsole.WriteLine(\"2!b\");\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tConsole.WriteLine(\"2b\");\n\t\t\t\t\t\t\treturn;\n#endif\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 1:\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tConsole.WriteLine(\"break-target\");\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(\"loop-tail\");\n\t\t\t}\n\t\t}\n\n\t\t// do-while loop version\n\t\tpublic static void SwitchWithContinue6(int i, bool b)\n\t\t{\n\t\t\tdo\n\t\t\t{\n\t\t\t\tswitch (i)\n\t\t\t\t{\n\t\t\t\t\tcase 0:\n\t\t\t\t\t\tif (!b)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tConsole.WriteLine(\"0!b\");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tConsole.WriteLine(\"0b\");\n\t\t\t\t\t\t// ConditionDetection doesn't recognise Do-While continues yet\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tif (b)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tConsole.WriteLine(\"2b\");\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tConsole.WriteLine(\"2!b\");\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(\"loop-tail\");\n\t\t\t} while (++i < 10);\n\t\t}\n\n\t\t// double break from switch to loop exit requires additional pattern matching in HighLevelLoopTransform\n\t\tpublic static void SwitchWithContinue7()\n\t\t{\n\t\t\tfor (int num = 0; num >= 0; num--)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"loop-head\");\n\t\t\t\tswitch (num)\n\t\t\t\t{\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 0:\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\n\t\tpublic static void SwitchWithContinueInDoubleLoop()\n\t\t{\n\t\t\tbool value = false;\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tfor (int j = 0; j < 10; j++)\n\t\t\t\t{\n\t\t\t\t\tswitch (i + j)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase 1:\n\t\t\t\t\t\tcase 3:\n\t\t\t\t\t\tcase 5:\n\t\t\t\t\t\tcase 7:\n\t\t\t\t\t\tcase 11:\n\t\t\t\t\t\tcase 13:\n\t\t\t\t\t\tcase 17:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tvalue = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tConsole.WriteLine(value);\n\t\t}\n\n\t\tpublic static void SwitchLoopNesting()\n\t\t{\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tswitch (i)\n\t\t\t\t{\n\t\t\t\t\tcase 0:\n\t\t\t\t\t\tConsole.WriteLine(0);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tConsole.WriteLine(1);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif (i % 2 == 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\twhile (i % 3 != 0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tConsole.WriteLine(i++);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tConsole.WriteLine();\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (i > 4)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"high\");\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"low\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// These decompile poorly into switch statements and should be left as is\n\t\t#region Overagressive Switch Use\n\n#if ROSLYN || OPT\n\t\tpublic static void SingleIf1(int i, bool a)\n\t\t{\n\t\t\tif (i == 1 || (i == 2 && a))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(1);\n\t\t\t}\n\t\t\tConsole.WriteLine(2);\n\t\t}\n#endif\n\n\t\tpublic static void SingleIf2(int i, bool a, bool b)\n\t\t{\n\t\t\tif (i == 1 || (i == 2 && a) || (i == 3 && b))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(1);\n\t\t\t}\n\t\t\tConsole.WriteLine(2);\n\t\t}\n\n\t\tpublic static void SingleIf3(int i, bool a, bool b)\n\t\t{\n\t\t\tif (a || i == 1 || (i == 2 && b))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(1);\n\t\t\t}\n\t\t\tConsole.WriteLine(2);\n\t\t}\n\n\t\tpublic static void SingleIf4(int i, bool a)\n\t\t{\n\t\t\tif (i == 1 || i == 2 || (i != 3 && a) || i != 4)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(1);\n\t\t\t}\n\t\t\tConsole.WriteLine(2);\n\t\t}\n\n\t\tpublic static void NestedIf(int i)\n\t\t{\n\t\t\tif (i != 1)\n\t\t\t{\n\t\t\t\tif (i == 2)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(2);\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t}\n\t\t\tConsole.WriteLine();\n\t\t}\n\n\t\tpublic static void IfChainWithCondition(int i)\n\t\t{\n\t\t\tif (i == 0)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(0);\n\t\t\t}\n\t\t\telse if (i == 1)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(1);\n\t\t\t}\n\t\t\telse if (i == 2)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(2);\n\t\t\t}\n\t\t\telse if (i == 3)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(3);\n\t\t\t}\n\t\t\telse if (i == 4)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(4);\n\t\t\t}\n\t\t\telse if (i == 5 && Console.CapsLock)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"5A\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t}\n\n\t\t\tConsole.WriteLine();\n\t\t}\n\n\t\tpublic static bool SwitchlikeIf(int i, int j)\n\t\t{\n\t\t\tif (i != 0 && j != 0)\n\t\t\t{\n\t\t\t\tif (i == -1 && j == -1)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"-1, -1\");\n\t\t\t\t}\n\t\t\t\tif (i == -1 && j == 1)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"-1, 1\");\n\t\t\t\t}\n\t\t\t\tif (i == 1 && j == -1)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"1, -1\");\n\t\t\t\t}\n\t\t\t\tif (i == 1 && j == 1)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"1, 1\");\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (i != 0)\n\t\t\t{\n\t\t\t\tif (i == -1)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"-1, 0\");\n\t\t\t\t}\n\t\t\t\tif (i == 1)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"1, 0\");\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (j != 0)\n\t\t\t{\n\t\t\t\tif (j == -1)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"0, -1\");\n\t\t\t\t}\n\t\t\t\tif (j == 1)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"0, 1\");\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic static bool SwitchlikeIf2(int i)\n\t\t{\n\t\t\tif (i != 0)\n\t\t\t{\n\t\t\t\t// note that using else-if in this chain creates a nice-looking switch here (as expected)\n\t\t\t\tif (i == 1)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(1);\n\t\t\t\t}\n\t\t\t\tif (i == 2)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(2);\n\t\t\t\t}\n\t\t\t\tif (i == 3)\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(3);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static void SingleIntervalIf(char c)\n\t\t{\n\t\t\tif (c >= 'A' && c <= 'Z')\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"alphabet\");\n\t\t\t}\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\n\t\tpublic static bool Loop8(char c, bool b, Func<char> getChar)\n\t\t{\n\t\t\tif (b)\n\t\t\t{\n\t\t\t\twhile ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))\n\t\t\t\t{\n\t\t\t\t\tc = getChar();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic static void Loop9(Func<char> getChar)\n\t\t{\n\t\t\tchar c;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tc = getChar();\n\t\t\t} while (c != -1 && c != '\\n' && c != '\\u2028' && c != '\\u2029');\n\t\t}\n\t\t#endregion\n\n\t\t// Ensure correctness of SwitchDetection.UseCSharpSwitch control flow heuristics\n\t\tpublic static void SwitchWithBreakCase(int i, bool b)\n\t\t{\n\t\t\tif (b)\n\t\t\t{\n\t\t\t\tswitch (i)\n\t\t\t\t{\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tConsole.WriteLine(1);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tConsole.WriteLine(\"default\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(\"b\");\n\t\t\t}\n\t\t\tConsole.WriteLine(\"end\");\n\t\t}\n\n\t\tpublic static void SwitchWithReturnAndBreak(int i, bool b)\n\t\t{\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\tif (b)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tif (!b)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tConsole.WriteLine();\n\t\t}\n\n\t\tpublic static int SwitchWithReturnAndBreak2(int i, bool b)\n\t\t{\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase 4:\n\t\t\t\tcase 33:\n\t\t\t\t\tConsole.WriteLine();\n\t\t\t\t\treturn 1;\n\t\t\t\tcase 334:\n\t\t\t\t\tif (b)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn 2;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 395:\n\t\t\t\tcase 410:\n\t\t\t\tcase 455:\n\t\t\t\t\tConsole.WriteLine();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tConsole.WriteLine();\n\t\t\treturn 0;\n\t\t}\n\n\t\tpublic static void SwitchWithReturnAndBreak3(int i)\n\t\t{\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tdefault:\n\t\t\t\t\treturn;\n\t\t\t\tcase 0:\n\t\t\t\t\tConsole.WriteLine(0);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tConsole.WriteLine(1);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tConsole.WriteLine();\n\t\t}\n\n\t\tpublic static string Issue1621(int x)\n\t\t{\n\t\t\tif (x == 5)\n\t\t\t{\n\t\t\t\treturn \"5\";\n\t\t\t}\n\t\t\tswitch (x)\n\t\t\t{\n\t\t\t\tcase 1:\n\t\t\t\t\treturn \"1\";\n\t\t\t\tcase 2:\n\t\t\t\tcase 6:\n\t\t\t\tcase 7:\n\t\t\t\t\treturn \"2-6-7\";\n\t\t\t\tcase 3:\n\t\t\t\t\treturn \"3\";\n\t\t\t\tcase 4:\n\t\t\t\t\treturn \"4\";\n\t\t\t\tcase 5:\n\t\t\t\t\treturn \"unreachable\";\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Exception();\n\t\t\t}\n\t\t}\n\n\t\tpublic static int Issue1602(string x)\n\t\t{\n\t\t\tswitch (x)\n\t\t\t{\n\t\t\t\tcase null:\n\t\t\t\t\treturn 0;\n\t\t\t\tcase \"\":\n\t\t\t\t\treturn -1;\n\t\t\t\tcase \"A\":\n\t\t\t\t\treturn 65;\n\t\t\t\tcase \"B\":\n\t\t\t\t\treturn 66;\n\t\t\t\tcase \"C\":\n\t\t\t\t\treturn 67;\n\t\t\t\tcase \"D\":\n\t\t\t\t\treturn 68;\n\t\t\t\tcase \"E\":\n\t\t\t\t\treturn 69;\n\t\t\t\tcase \"F\":\n\t\t\t\t\treturn 70;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t}\n\t\t}\n\n\t\tpublic static void Issue1745(string aaa)\n\t\t{\n\t\t\tswitch (aaa)\n\t\t\t{\n\t\t\t\tcase \"a\":\n\t\t\t\tcase \"b\":\n\t\t\t\tcase \"c\":\n\t\t\t\tcase \"d\":\n\t\t\t\tcase \"e\":\n\t\t\t\tcase \"f\":\n\t\t\t\t\tConsole.WriteLine(aaa);\n\t\t\t\t\tbreak;\n\t\t\t\tcase null:\n\t\t\t\t\tConsole.WriteLine(\"<null>\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"\":\n\t\t\t\t\tConsole.WriteLine(\"<empty>\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic static bool DoNotRemoveAssignmentBeforeSwitch(string x, out ConsoleKey key)\n\t\t{\n#if NET40 || !ROSLYN4\n\t\t\tkey = (ConsoleKey)0;\n#else\n\t\t\tkey = ConsoleKey.None;\n#endif\n\t\t\tswitch (x)\n\t\t\t{\n\t\t\t\tcase \"A\":\n\t\t\t\t\tkey = ConsoleKey.A;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"B\":\n\t\t\t\t\tkey = ConsoleKey.B;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"C\":\n\t\t\t\t\tkey = ConsoleKey.C;\n\t\t\t\t\tbreak;\n\t\t\t}\n#if NET40 || !ROSLYN4\n\t\t\treturn key != (ConsoleKey)0;\n#else\n\t\t\treturn key != ConsoleKey.None;\n#endif\n\t\t}\n\n\t\tpublic static void Issue1767(string s)\n\t\t{\n\t\t\tswitch (s)\n\t\t\t{\n\t\t\t\tcase \"a\":\n\t\t\t\t\tch1767 = s[0];\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"b\":\n\t\t\t\t\tch1767 = s[0];\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"c\":\n\t\t\t\t\tch1767 = s[0];\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"d\":\n\t\t\t\t\tch1767 = s[0];\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"e\":\n\t\t\t\t\tch1767 = s[0];\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"f\":\n\t\t\t\t\tch1767 = s[0];\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic static void Issue2763(int value)\n\t\t{\n\t\t\tswitch ((KnownColor)value)\n\t\t\t{\n\t\t\t\tcase KnownColor.DarkBlue:\n\t\t\t\t\tConsole.WriteLine(\"DarkBlue\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase KnownColor.DarkCyan:\n\t\t\t\t\tConsole.WriteLine(\"DarkCyan\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase KnownColor.DarkGoldenrod:\n\t\t\t\t\tConsole.WriteLine(\"DarkGoldenrod\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase KnownColor.DarkGray:\n\t\t\t\t\tConsole.WriteLine(\"DarkGray\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase KnownColor.DarkGreen:\n\t\t\t\t\tConsole.WriteLine(\"DarkGreen\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase KnownColor.DarkKhaki:\n\t\t\t\t\tConsole.WriteLine(\"DarkKhaki\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n#if CS110 && NET70\n\t\tpublic static string SwitchOverReadOnlySpanChar1(ReadOnlySpan<char> text)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchOverReadOnlySpanChar1:\");\n\t\t\tswitch (text)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\tcase \"2nd case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase \"Third case\":\n\t\t\t\t\treturn \"Text3\";\n\t\t\t\tcase \"Fourth case\":\n\t\t\t\t\treturn \"Text4\";\n\t\t\t\tcase \"Fifth case\":\n\t\t\t\t\treturn \"Text5\";\n\t\t\t\tcase \"Sixth case\":\n\t\t\t\t\treturn \"Text6\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverSpanChar1(Span<char> text)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchOverSpanChar1:\");\n\t\t\tswitch (text)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\tcase \"2nd case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase \"Third case\":\n\t\t\t\t\treturn \"Text3\";\n\t\t\t\tcase \"Fourth case\":\n\t\t\t\t\treturn \"Text4\";\n\t\t\t\tcase \"Fifth case\":\n\t\t\t\t\treturn \"Text5\";\n\t\t\t\tcase \"Sixth case\":\n\t\t\t\t\treturn \"Text6\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n#endif\n\n#if ROSLYN\n\t\tpublic static int Issue3577(int what)\n\t\t{\n\t\t\tint result = 0;\n\t\t\tswitch ((long)what)\n\t\t\t{\n\t\t\t\tcase 1L:\n\t\t\t\t\tresult = 1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2L:\n\t\t\t\t\tresult = 2;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n#endif\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/SwitchExpressions.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic static class SwitchExpressions\n\t{\n\t\tpublic class ImplicitlyCastToString\n\t\t{\n\t\t\tpublic static implicit operator string(ImplicitlyCastToString val)\n\t\t\t{\n\t\t\t\treturn \"foo\";\n\t\t\t}\n\t\t}\n\n\t\tpublic enum State\n\t\t{\n\t\t\tFalse,\n\t\t\tTrue,\n\t\t\tNull\n\t\t}\n\n\t\tpublic static bool? SwitchOverNullableEnum(State? state)\n\t\t{\n\t\t\treturn state switch {\n\t\t\t\tState.False => false,\n\t\t\t\tState.True => true,\n\t\t\t\tState.Null => null,\n\t\t\t\t_ => throw new InvalidOperationException(),\n\t\t\t};\n\t\t}\n\n\t\tpublic static string SparseIntegerSwitch(int i)\n\t\t{\n\t\t\tConsole.WriteLine(\"SparseIntegerSwitch: \" + i);\n\t\t\treturn i switch {\n\t\t\t\t-10000000 => \"-10 mln\",\n\t\t\t\t-100 => \"-hundred\",\n\t\t\t\t-1 => \"-1\",\n\t\t\t\t0 => \"0\",\n\t\t\t\t1 => \"1\",\n\t\t\t\t2 => \"2\",\n\t\t\t\t4 => \"4\",\n\t\t\t\t100 => \"hundred\",\n\t\t\t\t10000 => \"ten thousand\",\n\t\t\t\t10001 => \"ten thousand and one\",\n\t\t\t\tint.MaxValue => \"int.MaxValue\",\n\t\t\t\t_ => \"something else\",\n\t\t\t};\n\t\t}\n\n\t\tpublic static bool SparseIntegerSwitch3(int i)\n\t\t{\n\t\t\t// not using a switch expression because we'd have to duplicate the 'true' branch\n\t\t\tswitch (i)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\tcase 10:\n\t\t\t\tcase 11:\n\t\t\t\tcase 12:\n\t\t\t\tcase 100:\n\t\t\t\tcase 101:\n\t\t\t\tcase 200:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic static string SwitchOverNullableInt(int? i, int? j)\n\t\t{\n\t\t\treturn (i + j) switch {\n\t\t\t\tnull => \"null\",\n\t\t\t\t0 => \"zero\",\n\t\t\t\t5 => \"five\",\n\t\t\t\t10 => \"ten\",\n\t\t\t\t_ => \"large\",\n\t\t\t};\n\t\t}\n\n\t\tpublic static void SwitchOverInt(int i)\n\t\t{\n\t\t\tConsole.WriteLine(i switch {\n\t\t\t\t0 => \"zero\",\n\t\t\t\t5 => \"five\",\n\t\t\t\t10 => \"ten\",\n\t\t\t\t15 => \"fifteen\",\n\t\t\t\t20 => \"twenty\",\n\t\t\t\t25 => \"twenty-five\",\n\t\t\t\t30 => \"thirty\",\n\t\t\t\t_ => throw new NotImplementedException(),\n\t\t\t});\n\t\t}\n\n\t\tpublic static string SwitchOverString1(string text)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchOverString1: \" + text);\n\t\t\treturn text switch {\n\t\t\t\t\"First case\" => \"Text1\",\n\t\t\t\t\"Second case\" => \"Text2\",\n\t\t\t\t\"Third case\" => \"Text3\",\n\t\t\t\t\"Fourth case\" => \"Text4\",\n\t\t\t\t\"Fifth case\" => \"Text5\",\n\t\t\t\t\"Sixth case\" => \"Text6\",\n\t\t\t\tnull => null,\n\t\t\t\t_ => \"Default\",\n\t\t\t};\n\t\t}\n\n\t\tpublic static string SwitchOverString2(string text)\n\t\t{\n\t\t\tConsole.WriteLine(\"SwitchOverString1: \" + text);\n\t\t\t// Cannot use switch expression, because \"return Text2;\" would need to be duplicated\n\t\t\tswitch (text)\n\t\t\t{\n\t\t\t\tcase \"First case\":\n\t\t\t\t\treturn \"Text1\";\n\t\t\t\tcase \"Second case\":\n\t\t\t\tcase \"2nd case\":\n\t\t\t\t\treturn \"Text2\";\n\t\t\t\tcase \"Third case\":\n\t\t\t\t\treturn \"Text3\";\n\t\t\t\tcase \"Fourth case\":\n\t\t\t\t\treturn \"Text4\";\n\t\t\t\tcase \"Fifth case\":\n\t\t\t\t\treturn \"Text5\";\n\t\t\t\tcase \"Sixth case\":\n\t\t\t\t\treturn \"Text6\";\n\t\t\t\tcase null:\n\t\t\t\t\treturn null;\n\t\t\t\tdefault:\n\t\t\t\t\treturn \"Default\";\n\t\t\t}\n\t\t}\n\n\t\tpublic static string Issue2222()\n\t\t{\n\t\t\treturn (string)new ImplicitlyCastToString() switch {\n\t\t\t\t\"foo\" => \"foo\",\n\t\t\t\t\"bar\" => \"bar\",\n\t\t\t\t\"quux\" => \"quux\",\n\t\t\t\t_ => \"default\",\n\t\t\t};\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/ThrowExpressions.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class ThrowExpressions\n\t{\n\t\tprivate class ArgumentCheckingCtor\n\t\t{\n\t\t\tprivate int initializedFromCtor = CountSheep() ?? throw new Exception(\"No sheep?!\");\n\t\t\tprivate object cacheObj = TryGetObj() ?? throw new Exception(\"What?\");\n\n\t\t\tprivate object simpleObj;\n\t\t\tprivate int? nullableInt;\n\n\t\t\tpublic ArgumentCheckingCtor(object simpleObj, int? nullableInt)\n\t\t\t{\n\t\t\t\tthis.simpleObj = simpleObj ?? throw new ArgumentNullException(\"simpleObj\");\n\t\t\t\tthis.nullableInt = nullableInt ?? throw new ArgumentNullException(\"nullableInt\");\n\t\t\t}\n\n\t\t\tpublic ArgumentCheckingCtor(string input)\n\t\t\t\t: this(input, GetIntOrNull(input ?? throw new ArgumentNullException(\"input\")))\n\t\t\t{\n\n\t\t\t}\n\n\t\t\tpublic ArgumentCheckingCtor(DataObject obj)\n\t\t\t\t: this(obj ?? throw new Exception(), GetIntOrNull(obj.NullableDataField?.NullableDataField.ToString() ?? throw new ArgumentNullException(\"input\")))\n\t\t\t{\n\n\t\t\t}\n\n\t\t\tprivate static int? GetIntOrNull(string v)\n\t\t\t{\n\t\t\t\tif (int.TryParse(v, out var result))\n\t\t\t\t{\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tprivate static int? CountSheep()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\n\t\t\tprivate static object TryGetObj()\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tpublic override int GetHashCode()\n\t\t\t{\n\t\t\t\treturn initializedFromCtor;\n\t\t\t}\n\n\t\t\tpublic override bool Equals(object obj)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tpublic class DataObject\n\t\t{\n\t\t\tpublic int IntField;\n\t\t\tpublic int? NullableIntField;\n\t\t\tpublic Data DataField;\n\t\t\tpublic Data? NullableDataField;\n\t\t\tpublic int IntProperty { get; set; }\n\t\t\tpublic int? NullableIntProperty { get; set; }\n\t\t\tpublic Data DataProperty { get; }\n\t\t\tpublic Data? NullableDataProperty { get; }\n\t\t}\n\n\t\tpublic struct Data\n\t\t{\n\t\t\tpublic int IntField;\n\t\t\tpublic int? NullableIntField;\n\t\t\tpublic MoreData DataField;\n\t\t\tpublic MoreData? NullableDataField;\n\t\t\tpublic int IntProperty { get; set; }\n\t\t\tpublic int? NullableIntProperty { get; set; }\n\t\t\tpublic MoreData DataProperty { get; }\n\t\t\tpublic MoreData? NullableDataProperty { get; }\n\t\t}\n\n\t\tpublic struct MoreData\n\t\t{\n\t\t\tpublic int IntField;\n\t\t\tpublic int? NullableIntField;\n\t\t\tpublic int IntProperty { get; set; }\n\t\t\tpublic int? NullableIntProperty { get; set; }\n\t\t}\n\n\t\tpublic static int IntField;\n\t\tpublic static int? NullableIntField;\n\t\tpublic static object ObjectField;\n\t\tpublic int InstIntField;\n\t\tpublic int? InstNullableIntField;\n\t\tpublic object InstObjectField;\n\t\tpublic Data DataField;\n\t\tpublic Data? NullableDataField;\n\t\tpublic DataObject DataObjectField;\n\n\t\tpublic static int IntProperty { get; }\n\t\tpublic static int? NullableIntProperty { get; }\n\t\tpublic static object ObjProperty { get; }\n\t\tpublic int InstIntProperty { get; }\n\t\tpublic int? InstNullableIntProperty { get; }\n\t\tpublic object InstObjProperty { get; }\n\t\tpublic Data DataProperty { get; }\n\t\tpublic Data? NullableDataProperty { get; }\n\t\tpublic DataObject DataObjectProperty { get; }\n\n\t\tpublic static int ReturnIntField()\n\t\t{\n\t\t\treturn NullableIntField ?? throw new Exception();\n\t\t}\n\t\tpublic static int ReturnIntProperty()\n\t\t{\n\t\t\treturn NullableIntProperty ?? throw new Exception();\n\t\t}\n\t\tpublic static object ReturnObjField()\n\t\t{\n\t\t\treturn ObjectField ?? throw new Exception();\n\t\t}\n\t\tpublic static object ReturnObjProperty()\n\t\t{\n\t\t\treturn ObjProperty ?? throw new Exception();\n\t\t}\n\t\tpublic static int ReturnIntField(ThrowExpressions inst)\n\t\t{\n\t\t\treturn inst.InstNullableIntField ?? throw new Exception();\n\t\t}\n\t\tpublic static int ReturnIntProperty(ThrowExpressions inst)\n\t\t{\n\t\t\treturn inst.InstNullableIntProperty ?? throw new Exception();\n\t\t}\n\t\tpublic static object ReturnObjField(ThrowExpressions inst)\n\t\t{\n\t\t\treturn inst.InstObjectField ?? throw new Exception();\n\t\t}\n\t\tpublic static object ReturnObjProperty(ThrowExpressions inst)\n\t\t{\n\t\t\treturn inst.InstObjProperty ?? throw new Exception();\n\t\t}\n\n\t\tpublic static void UseComplexNullableStruct(ThrowExpressions inst)\n\t\t{\n\t\t\tUse(inst.InstNullableIntField ?? throw new Exception());\n\t\t\tUse((inst.NullableDataField ?? throw new Exception()).IntField);\n\t\t\tUse(inst.NullableDataField?.NullableIntField ?? throw new Exception());\n\t\t\tUse((inst.NullableDataProperty ?? throw new Exception()).IntField);\n\t\t\tUse(inst.NullableDataProperty?.NullableIntField ?? throw new Exception());\n\t\t\tUse((inst.NullableDataField ?? throw new Exception()).DataField.IntField);\n\t\t\tUse(inst.NullableDataField?.DataField.NullableIntField ?? throw new Exception());\n\t\t\tUse((inst.NullableDataProperty ?? throw new Exception()).DataField.IntField);\n\t\t\tUse(inst.NullableDataProperty?.DataField.NullableIntField ?? throw new Exception());\n\t\t\tUse((inst.NullableDataField ?? throw new Exception()).DataProperty.IntField);\n\t\t\tUse(inst.NullableDataField?.DataProperty.NullableIntField ?? throw new Exception());\n\t\t\tUse((inst.NullableDataProperty ?? throw new Exception()).DataProperty.IntField);\n\t\t\tUse(inst.NullableDataProperty?.DataProperty.NullableIntField ?? throw new Exception());\n\t\t\tUse(inst.NullableDataField?.NullableDataField?.IntField ?? throw new Exception());\n\t\t\tUse(inst.NullableDataField?.NullableDataField?.NullableIntField ?? throw new Exception());\n\t\t\tUse(inst.NullableDataProperty?.NullableDataField?.IntField ?? throw new Exception());\n\t\t\tUse(inst.NullableDataProperty?.NullableDataField?.NullableIntField ?? throw new Exception());\n\t\t\tUse(inst.NullableDataField?.NullableDataProperty?.IntField ?? throw new Exception());\n\t\t\tUse(inst.NullableDataField?.NullableDataProperty?.NullableIntField ?? throw new Exception());\n\t\t\tUse(inst.NullableDataProperty?.NullableDataProperty?.IntField ?? throw new Exception());\n\t\t\tUse(inst.NullableDataProperty?.NullableDataProperty?.NullableIntField ?? throw new Exception());\n\t\t}\n\n\t\tpublic static void UseComplexNullableObject(DataObject inst)\n\t\t{\n\t\t\tUse(inst?.NullableIntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataField?.IntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataField?.NullableIntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataProperty?.IntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataProperty?.NullableIntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataField?.DataField.IntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataField?.DataField.NullableIntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataProperty?.DataField.IntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataProperty?.DataField.NullableIntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataField?.DataProperty.IntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataField?.DataProperty.NullableIntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataProperty?.DataProperty.IntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataProperty?.DataProperty.NullableIntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataField?.NullableDataField?.IntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataField?.NullableDataField?.NullableIntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataProperty?.NullableDataField?.IntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataProperty?.NullableDataField?.NullableIntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataField?.NullableDataProperty?.IntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataField?.NullableDataProperty?.NullableIntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataProperty?.NullableDataProperty?.IntField ?? throw new Exception());\n\t\t\tUse(inst?.NullableDataProperty?.NullableDataProperty?.NullableIntField ?? throw new Exception());\n\t\t}\n\n\t\tpublic static void Use<T>(T usage)\n\t\t{\n\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.cs",
    "content": "// Copyright (c) 2018 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class TupleTests\n\t{\n\t\tprivate abstract class OverloadResolution\n\t\t{\n\t\t\tpublic abstract void M1((long, long) a);\n\t\t\tpublic abstract void M1(object a);\n\n\t\t\tpublic void UseM1((int, int) a)\n\t\t\t{\n\t\t\t\t// M1(a); TODO: tuple conversion transform\n\t\t\t\t// Cast is required to avoid the overload usable via tuple conversion:\n\t\t\t\tM1((object)a);\n\t\t\t}\n\t\t}\n\n\t\tpublic struct GenericStruct<T>\n\t\t{\n\t\t\tpublic T Field;\n\t\t\tpublic T Property { get; set; }\n\t\t}\n\n\t\tpublic ValueTuple VT0;\n\t\tpublic ValueTuple<int> VT1;\n\t\tpublic ValueTuple<int, int, int, int, int, int, int, ValueTuple> VT7EmptyRest;\n\n\t\tpublic (int, uint) Unnamed2;\n\t\tpublic (int, int, int) Unnamed3;\n\t\tpublic (int, int, int, int) Unnamed4;\n\t\tpublic (int, int, int, int, int) Unnamed5;\n\t\tpublic (int, int, int, int, int, int) Unnamed6;\n\t\tpublic (int, int, int, int, int, int, int) Unnamed7;\n\t\tpublic (int, int, int, int, int, int, int, int) Unnamed8;\n\n\t\tpublic (int a, uint b) Named2;\n\t\tpublic (int a, uint b)[] Named2Array;\n\t\tpublic (int a, int b, int c, int d, int e, int f, int g, int h) Named8;\n\n\t\tpublic (int, int a, int, int b, int) PartiallyNamed;\n\n\t\tpublic ((int a, int b) x, (int, int) y, (int c, int d) z) Nested1;\n\t\tpublic ((object a, dynamic b), dynamic, (dynamic c, object d)) Nested2;\n\t\tpublic (ValueTuple a, (int x1, int x2), ValueTuple<int> b, (int y1, int y2), (int, int) c) Nested3;\n\t\tpublic (int a, int b, int c, int d, int e, int f, int g, int h, (int i, int j)) Nested4;\n\n\t\tpublic Dictionary<(int a, string b), (string c, int d)> TupleDict;\n\t\tpublic List<(int, string)> List;\n\t\tpublic bool HasItems => List.Any(((int, string) a) => a.Item1 > 0);\n\n\t\tpublic int VT1Member => VT1.Item1;\n\t\tpublic int AccessUnnamed8 => Unnamed8.Item8;\n\t\tpublic int AccessNamed8 => Named8.h;\n\t\tpublic int AccessPartiallyNamed => PartiallyNamed.a + PartiallyNamed.Item3;\n\n\t\tpublic ValueTuple<int> NewTuple1 => new ValueTuple<int>(1);\n\t\tpublic (int a, int b) NewTuple2 => (a: 1, b: 2);\n\t\tpublic object BoxedTuple10 => (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);\n\n\t\tpublic (uint, int) SwapUnnamed => (Unnamed2.Item2, Unnamed2.Item1);\n\t\tpublic (uint, int) SwapNamed2 => (Named2.b, Named2.a);\n\n\t\tpublic int TupleHash => (1, 2, 3).GetHashCode();\n\t\tpublic int TupleHash2 => Named2.GetHashCode();\n\n\t\tpublic (int, int) AccessRest => (1, 2, 3, 4, 5, 6, 7, 8, 9).Rest;\n\n\t\tpublic (string, object, Action) TargetTyping => (null, 1, delegate {\n#pragma warning disable format\n\t\t});\n#pragma warning restore format\n\n\t\tpublic object NotTargetTyping => ((string)null, (object)1, (Action)delegate {\n#pragma warning disable format\n\t\t});\n#pragma warning restore format\n\n\t\tpublic void UnnamedTupleOut(out (int, string, Action, dynamic) tuple)\n\t\t{\n\t\t\ttuple = (42, \"Hello\", Console.WriteLine, null);\n\t\t}\n\n\t\tpublic void UnnamedTupleIn(in (int, string, Action, dynamic) tuple)\n\t\t{\n\n\t\t}\n\n\t\tpublic void UnnamedTupleRef(ref (int, string, Action, dynamic) tuple)\n\t\t{\n\n\t\t}\n\n\t\tpublic void NamedTupleOut(out (int A, string B, Action C, dynamic D) tuple)\n\t\t{\n\t\t\ttuple = (A: 42, B: \"Hello\", C: Console.WriteLine, D: null);\n\t\t}\n\n\t\tpublic void NamedTupleIn(in (int A, string B, Action C, dynamic D) tuple)\n\t\t{\n\n\t\t}\n\n\t\tpublic void NamedTupleRef(ref (int A, string B, Action C, dynamic D) tuple)\n\t\t{\n\n\t\t}\n\n\t\tpublic void UseDict()\n\t\t{\n\t\t\tif (TupleDict.Count > 10)\n\t\t\t{\n\t\t\t\tTupleDict.Clear();\n\t\t\t}\n\t\t\t// TODO: it would be nice if we could infer the name 'c' for the local\n\t\t\tstring item = TupleDict[(1, \"abc\")].c;\n\t\t\tConsole.WriteLine(item);\n\t\t\tConsole.WriteLine(item);\n\t\t\tConsole.WriteLine(TupleDict.Values.ToList().First().d);\n\t\t}\n\n\t\tprivate static (string, string) Issue3014a(string[] args)\n\t\t{\n\t\t\treturn (from v in args\n\t\t\t\t\tselect (Name: v, Value: v) into kvp\n\t\t\t\t\torderby kvp.Name\n\t\t\t\t\tselect kvp).First();\n\t\t}\n\n\t\tprivate static (string, string) Issue3014b(string[] args)\n\t\t{\n\t\t\treturn (from v in args\n\t\t\t\t\tselect ((string Name, string Value))GetTuple() into kvp\n\t\t\t\t\torderby kvp.Name\n\t\t\t\t\tselect kvp).First();\n\n\t\t\t(string, string) GetTuple()\n\t\t\t{\n\t\t\t\treturn (args[0], args[1]);\n\t\t\t}\n\t\t}\n\n\t\tpublic void Issue1174()\n\t\t{\n\t\t\tConsole.WriteLine((1, 2, 3).GetHashCode());\n\t\t}\n\n\t\tpublic void LocalVariables((int, int) a)\n\t\t{\n\t\t\t(int, int) tuple = (a.Item1 + a.Item2, a.Item1 * a.Item2);\n\t\t\tConsole.WriteLine(tuple.ToString());\n\t\t\tConsole.WriteLine(tuple.GetType().FullName);\n\t\t}\n\n\t\tpublic void Foreach(IEnumerable<(int, string)> input)\n\t\t{\n\t\t\tforeach (var item in input)\n\t\t\t{\n\t\t\t\tConsole.WriteLine($\"{item.Item1}: {item.Item2}\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void ForeachNamedElements(IEnumerable<(int Index, string Data)> input)\n\t\t{\n\t\t\tforeach (var item in input)\n\t\t\t{\n\t\t\t\tConsole.WriteLine($\"{item.Index}: {item.Data}\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void NonGenericForeach(IEnumerable input)\n\t\t{\n\t\t\tforeach ((string, int) item in input)\n\t\t\t{\n\t\t\t\tConsole.WriteLine($\"{item.Item1}: {item.Item2}\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void CallForeach()\n\t\t{\n\t\t\tForeach(new List<(int, string)> {\n\t\t\t\t(1, \"a\"),\n\t\t\t\t(2, \"b\")\n\t\t\t});\n\t\t}\n\n\t\tpublic void DynamicTuple((dynamic A, dynamic B) a)\n\t\t{\n\t\t\ta.A.DynamicCall();\n\t\t\ta.B.Dynamic = 42;\n\t\t}\n\n\t\tpublic void GenericStructWithElementNames(GenericStruct<(int A, int B)> s)\n\t\t{\n\t\t\tConsole.WriteLine(s.Field.A + s.Property.B);\n\t\t}\n\n\t\tpublic void RefCallSites(out (int, string, Action, dynamic) tuple)\n\t\t{\n\t\t\tUnnamedTupleOut(out tuple);\n\t\t\tUnnamedTupleIn(in tuple);\n\t\t\tUnnamedTupleRef(ref tuple);\n\t\t\tNamedTupleOut(out tuple);\n\t\t\tNamedTupleIn(in tuple);\n\t\t\tNamedTupleRef(ref tuple);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeAnalysisTests.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Reflection;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class TypeAnalysisTests\n\t{\n\t\tprivate class @_\n\t\t{\n\t\t}\n\n\t\tprivate byte[] byteArray;\n\t\tprivate ulong uint64Field;\n\n\t\tpublic int Issue1796a {\n\t\t\tget {\n\t\t\t\treturn (int)(uint64Field & 0x7FFFFFFF);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tuint64Field = (uint64Field & 0xFFFFFFFF80000000uL) | (ulong)value;\n\t\t\t}\n\t\t}\n\n\t\tpublic ushort Issue1796b {\n\t\t\tget {\n\t\t\t\treturn (ushort)((uint64Field & 0xFFFF000000000000uL) >> 48);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tuint64Field = (uint64Field & 0xFFFFFFFFFFFFL) | ((ulong)value << 48);\n\t\t\t}\n\t\t}\n\n\t\tpublic byte SubtractFrom256(byte b)\n\t\t{\n\t\t\treturn (byte)(256 - b);\n\t\t}\n\n\t\t#region Shift\n\t\tpublic int LShiftInteger(int num1, int num2)\n\t\t{\n\t\t\treturn num1 << num2;\n\t\t}\n\n\t\tpublic uint LShiftUnsignedInteger(uint num1, uint num2)\n\t\t{\n\t\t\treturn num1 << (int)num2;\n\t\t}\n\n\t\tpublic long LShiftLong(long num1, long num2)\n\t\t{\n\t\t\treturn num1 << (int)num2;\n\t\t}\n\n\t\tpublic ulong LShiftUnsignedLong(ulong num1, ulong num2)\n\t\t{\n\t\t\treturn num1 << (int)num2;\n\t\t}\n\n\t\tpublic int RShiftInteger(int num1, int num2)\n\t\t{\n\t\t\treturn num1 >> num2;\n\t\t}\n\n\t\tpublic uint RShiftUnsignedInteger(uint num1, int num2)\n\t\t{\n\t\t\treturn num1 >> num2;\n\t\t}\n\n\t\tpublic long RShiftLong(long num1, long num2)\n\t\t{\n\t\t\treturn num1 >> (int)num2;\n\t\t}\n\n\t\tpublic ulong RShiftUnsignedLong(ulong num1, ulong num2)\n\t\t{\n\t\t\treturn num1 >> (int)num2;\n\t\t}\n\n\t\tpublic int ShiftByte(byte num)\n\t\t{\n\t\t\treturn num << 8;\n\t\t}\n\n\t\tpublic int RShiftByte(byte num)\n\t\t{\n\t\t\treturn num >> 8;\n\t\t}\n\n\t\tpublic uint RShiftByteWithZeroExtension(byte num)\n\t\t{\n\t\t\t// zero extend -> cast to unsigned -> unsigned shift\n\t\t\treturn (uint)num >> 8;\n\t\t}\n\n\t\tpublic int RShiftByteWithZeroExtensionReturnAsSigned(byte num)\n\t\t{\n#if CS110\n\t\t\t// zero extend -> unsigned shift\n\t\t\treturn num >>> 8;\n#else\n\t\t\t// zero extend -> cast to unsigned -> unsigned shift -> cast to signed\n\t\t\treturn (int)((uint)num >> 8);\n#endif\n\t\t}\n\n\t\tpublic int RShiftByteAsSByte(byte num)\n\t\t{\n\t\t\treturn (sbyte)num >> 8;\n\t\t}\n\n\t\tpublic int RShiftSByte(sbyte num)\n\t\t{\n\t\t\treturn num >> 8;\n\t\t}\n\n\t\tpublic uint RShiftSByteWithZeroExtension(sbyte num)\n\t\t{\n\t\t\treturn (uint)((byte)num >> 4);\n\t\t}\n\n\t\tpublic uint RShiftSByteWithSignExtension(sbyte num)\n\t\t{\n\t\t\t// sign extend -> cast to unsigned -> unsigned shift\n\t\t\treturn (uint)num >> 4;\n\t\t}\n\n\t\tpublic int RShiftSByteWithSignExtensionReturnAsSigned(sbyte num)\n\t\t{\n#if CS110\n\t\t\t// sign extend -> unsigned shift\n\t\t\treturn num >>> 4;\n#else\n\t\t\t// sign extend -> cast to unsigned -> unsigned shift -> cast to signed\n\t\t\treturn (int)((uint)num >> 4);\n#endif\n\t\t}\n\t\tpublic int RShiftSByteAsByte(sbyte num)\n\t\t{\n\t\t\treturn (byte)num >> 8;\n\t\t}\n\t\t#endregion\n\n\t\tpublic int GetHashCode(long num)\n\t\t{\n\t\t\treturn (int)num ^ (int)(num >> 32);\n\t\t}\n\n\t\tpublic void TernaryOp(Random a, Random b, bool c)\n\t\t{\n\t\t\tif ((c ? a : b) == null)\n\t\t\t{\n\t\t\t\tConsole.WriteLine();\n\t\t\t}\n\t\t}\n\n\t\tpublic void OperatorIs(object o)\n\t\t{\n\t\t\tConsole.WriteLine(o is Random);\n\t\t\tConsole.WriteLine(!(o is Random));\n\t\t\t// If we didn't escape the '_' identifier here, this would look like a discard pattern\n\t\t\tConsole.WriteLine(o is @_);\n\t\t}\n\n\t\tpublic byte[] CreateArrayWithInt(int length)\n\t\t{\n\t\t\treturn new byte[length];\n\t\t}\n\n\t\tpublic byte[] CreateArrayWithLong(long length)\n\t\t{\n\t\t\treturn new byte[length];\n\t\t}\n\n\t\tpublic byte[] CreateArrayWithUInt(uint length)\n\t\t{\n\t\t\treturn new byte[length];\n\t\t}\n\n\t\tpublic byte[] CreateArrayWithULong(ulong length)\n\t\t{\n\t\t\treturn new byte[length];\n\t\t}\n\n\t\tpublic byte[] CreateArrayWithShort(short length)\n\t\t{\n\t\t\treturn new byte[length];\n\t\t}\n\n\t\tpublic byte[] CreateArrayWithUShort(ushort length)\n\t\t{\n\t\t\treturn new byte[length];\n\t\t}\n\n\t\tpublic byte UseArrayWithInt(int i)\n\t\t{\n\t\t\treturn byteArray[i];\n\t\t}\n\n\t\tpublic byte UseArrayWithUInt(uint i)\n\t\t{\n\t\t\treturn byteArray[i];\n\t\t}\n\n\t\tpublic byte UseArrayWithLong(long i)\n\t\t{\n\t\t\treturn byteArray[i];\n\t\t}\n\n\t\tpublic byte UseArrayWithULong(ulong i)\n\t\t{\n\t\t\treturn byteArray[i];\n\t\t}\n\n\t\tpublic byte UseArrayWithShort(short i)\n\t\t{\n\t\t\treturn byteArray[i];\n\t\t}\n\n\t\tpublic byte UseArrayWithUShort(ushort i)\n\t\t{\n\t\t\treturn byteArray[i];\n\t\t}\n\n\t\tpublic byte UseArrayWithCastToUShort(int i)\n\t\t{\n\t\t\t// Unchecked cast = truncate to 16 bits\n\t\t\treturn byteArray[(ushort)i];\n\t\t}\n\n\t\tpublic StringComparison EnumDiffNumber(StringComparison data)\n\t\t{\n\t\t\treturn data - 1;\n\t\t}\n\n\t\tpublic int EnumDiff(StringComparison a, StringComparison b)\n\t\t{\n\t\t\treturn Math.Abs(a - b);\n\t\t}\n\n\t\tpublic bool CompareDelegatesByValue(Action a, Action b)\n\t\t{\n\t\t\treturn a == b;\n\t\t}\n\n\t\tpublic bool CompareDelegatesByReference(Action a, Action b)\n\t\t{\n\t\t\treturn (object)a == b;\n\t\t}\n\n\t\tpublic bool CompareDelegateWithNull(Action a)\n\t\t{\n\t\t\treturn a == null;\n\t\t}\n\n\t\tpublic bool CompareStringsByValue(string a, string b)\n\t\t{\n\t\t\treturn a == b;\n\t\t}\n\n\t\tpublic bool CompareStringsByReference(string a, string b)\n\t\t{\n\t\t\treturn (object)a == b;\n\t\t}\n\n\t\tpublic bool CompareStringWithNull(string a)\n\t\t{\n\t\t\treturn a == null;\n\t\t}\n\n\t\tpublic bool CompareType(Type a, Type b)\n\t\t{\n\t\t\treturn a == b;\n\t\t}\n\n\t\tpublic bool CompareTypeByReference(Type a, Type b)\n\t\t{\n\t\t\treturn (object)a == b;\n\t\t}\n\n\t\tpublic bool CompareTypeWithNull(Type t)\n\t\t{\n\t\t\treturn t == null;\n\t\t}\n\n\t\tpublic Attribute CallExtensionMethodViaBaseClass(Type type)\n\t\t{\n\t\t\treturn type.GetCustomAttribute<AttributeUsageAttribute>();\n\t\t}\n\n\t\tpublic decimal ImplicitConversionToDecimal(byte v)\n\t\t{\n\t\t\treturn v;\n\t\t}\n\n\t\tpublic decimal ImplicitConversionToDecimal(ulong v)\n\t\t{\n\t\t\treturn v;\n\t\t}\n\n\t\tpublic bool EnumInConditionalOperator(bool b)\n\t\t{\n\t\t\treturn string.Equals(\"\", \"\", b ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);\n\t\t}\n\n\t\tpublic bool MethodCallOnEnumConstant()\n\t\t{\n\t\t\treturn AttributeTargets.All.HasFlag(AttributeTargets.Assembly);\n\t\t}\n\n\t\tpublic static string ImpossibleCast1(int i)\n\t\t{\n\t\t\treturn (string)(object)i;\n\t\t}\n\n\t\tpublic static string ImpossibleCast2(Action a)\n\t\t{\n\t\t\treturn (string)(object)a;\n\t\t}\n\n\t\tpublic static bool CompareLast32Bits(long a, long b)\n\t\t{\n\t\t\treturn (int)a == (int)b;\n\t\t}\n\n\t\tpublic static bool Last32BitsAreZero(long a)\n\t\t{\n\t\t\treturn (int)a == 0;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeMemberTests.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class T01_IndexerWithGetOnly\n\t{\n#if ROSLYN\n\t\tpublic int this[int i] => i;\n#else\n\t\tpublic int this[int i] {\n\t\t\tget {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\tpublic class T02_IndexerWithSetOnly\n\t{\n\t\tpublic int this[int i] {\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic class T03_IndexerWithMoreParameters\n\t{\n#if ROSLYN\n\t\tpublic int this[int i, string s, Type t] => 0;\n#else\n\t\tpublic int this[int i, string s, Type t] {\n\t\t\tget {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\n\tpublic class T04_IndexerInGenericClass<T>\n\t{\n#if ROSLYN\n\t\tpublic int this[T t] => 0;\n#else\n\t\tpublic int this[T t] {\n\t\t\tget {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\tpublic class T05_OverloadedIndexer\n\t{\n#if ROSLYN\n\t\tpublic int this[int t] => 0;\n#else\n\t\tpublic int this[int t] {\n\t\t\tget {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n#endif\n\t\tpublic int this[string s] {\n\t\t\tget {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tConsole.WriteLine(value + \" \" + s);\n\t\t\t}\n\t\t}\n\t}\n\tpublic interface T06_IIndexerInInterface\n\t{\n\t\tint this[string s, string s2] { set; }\n\t}\n\tpublic interface T07_IMyInterface_IndexerInterfaceExplicitImplementation\n\t{\n\t\tint this[string s] { get; }\n\t}\n\tpublic class T07_MyClass_IndexerInterfaceExplicitImplementation : T07_IMyInterface_IndexerInterfaceExplicitImplementation\n\t{\n#if ROSLYN\n\t\tint T07_IMyInterface_IndexerInterfaceExplicitImplementation.this[string s] => 3;\n#else\n\t\tint T07_IMyInterface_IndexerInterfaceExplicitImplementation.this[string s] {\n\t\t\tget {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\tpublic interface T08_IMyInterface_IndexerInterfaceImplementation\n\t{\n\t\tint this[string s] { get; }\n\t}\n\tpublic class T08_MyClass_IndexerInterfaceImplementation : T08_IMyInterface_IndexerInterfaceImplementation\n\t{\n#if ROSLYN\n\t\tpublic int this[string s] => 3;\n#else\n\t\tpublic int this[string s] {\n\t\t\tget {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\n\tpublic interface T09_IMyInterface_MethodExplicit\n\t{\n\t\tvoid MyMethod();\n\t}\n\tpublic abstract class T09_MyClass_IndexerAbstract\n\t{\n\t\tpublic abstract int this[string s, string s2] { set; }\n\t\tprotected abstract string this[int index] { get; }\n\t}\n\tpublic class T09_MyClass_MethodExplicit : T09_IMyInterface_MethodExplicit\n\t{\n\t\tvoid T09_IMyInterface_MethodExplicit.MyMethod()\n\t\t{\n\t\t}\n\t}\n\n\tpublic interface T10_IMyInterface_MethodFromInterfaceVirtual\n\t{\n\t\tvoid MyMethod();\n\t}\n\tpublic class T10_MyClass : T10_IMyInterface_MethodFromInterfaceVirtual\n\t{\n\t\tpublic virtual void MyMethod()\n\t\t{\n\t\t}\n\t}\n\tpublic interface T11_IMyInterface_MethodFromInterface\n\t{\n\t\tvoid MyMethod();\n\t}\n\tpublic class T11_MyClass_MethodFromInterface : T11_IMyInterface_MethodFromInterface\n\t{\n\t\tpublic void MyMethod()\n\t\t{\n\t\t}\n\t}\n\tpublic interface T12_IMyInterface_MethodFromInterfaceAbstract\n\t{\n\t\tvoid MyMethod();\n\t}\n\tpublic abstract class T12_MyClass_MethodFromInterfaceAbstract : T12_IMyInterface_MethodFromInterfaceAbstract\n\t{\n\t\tpublic abstract void MyMethod();\n\t}\n\tpublic interface T13_IMyInterface_PropertyInterface\n\t{\n\t\tint MyProperty { get; set; }\n\t}\n\tpublic interface T14_IMyInterface_PropertyInterfaceExplicitImplementation\n\t{\n\t\tint MyProperty { get; set; }\n\t}\n\tpublic class T14_MyClass_PropertyInterfaceExplicitImplementation : T14_IMyInterface_PropertyInterfaceExplicitImplementation\n\t{\n\t\tint T14_IMyInterface_PropertyInterfaceExplicitImplementation.MyProperty {\n\t\t\tget {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\tpublic interface T15_IMyInterface_PropertyInterfaceImplementation\n\t{\n\t\tint MyProperty { get; set; }\n\t}\n\tpublic class T15_MyClass_PropertyInterfaceImplementation : T15_IMyInterface_PropertyInterfaceImplementation\n\t{\n\t\tpublic int MyProperty {\n\t\t\tget {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T16_MyClass_PropertyPrivateGetPublicSet\n\t{\n\t\tpublic int MyProperty {\n\t\t\tprivate get {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T17_MyClass_PropertyPublicGetProtectedSet\n\t{\n\t\tpublic int MyProperty {\n\t\t\tget {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t\tprotected set {\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T18_Base_PropertyOverrideDefaultAccessorOnly\n\t{\n\t\tpublic virtual int MyProperty {\n\t\t\tget {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t\tprotected set {\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T18_Derived_PropertyOverrideDefaultAccessorOnly : T18_Base_PropertyOverrideDefaultAccessorOnly\n\t{\n#if ROSLYN\n\t\tpublic override int MyProperty => 4;\n#else\n\t\tpublic override int MyProperty {\n\t\t\tget {\n\t\t\t\treturn 4;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\tpublic class T19_Base_PropertyOverrideRestrictedAccessorOnly\n\t{\n\t\tpublic virtual int MyProperty {\n\t\t\tget {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t\tprotected set {\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T19_Derived_PropertyOverrideRestrictedAccessorOnly : T19_Base_PropertyOverrideRestrictedAccessorOnly\n\t{\n\t\tpublic override int MyProperty {\n\t\t\tprotected set {\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T20_Base_PropertyOverrideOneAccessor\n\t{\n\t\tprotected internal virtual int MyProperty {\n\t\t\tget {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t\tprotected set {\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T20_DerivedNew_PropertyOverrideOneAccessor : T20_Base_PropertyOverrideOneAccessor\n\t{\n\t\tpublic new virtual int MyProperty {\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T20_DerivedOverride_PropertyOverrideOneAccessor : T20_DerivedNew_PropertyOverrideOneAccessor\n\t{\n\t\tpublic override int MyProperty {\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T21_Base_IndexerOverrideRestrictedAccessorOnly\n\t{\n\t\tpublic virtual int this[string s] {\n\t\t\tget {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t\tprotected set {\n\t\t\t}\n\t\t}\n\t\tprotected internal virtual int this[int i] {\n\t\t\tprotected get {\n\t\t\t\treturn 2;\n\t\t\t}\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T21_Derived_IndexerOverrideRestrictedAccessorOnly : T21_Base_IndexerOverrideRestrictedAccessorOnly\n\t{\n\t\tprotected internal override int this[int i] {\n\t\t\tprotected get {\n\t\t\t\treturn 4;\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T22_A_HideProperty\n\t{\n\t\tpublic virtual int P {\n\t\t\tget {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T22_B_HideProperty : T22_A_HideProperty\n\t{\n\t\tprivate new int P {\n\t\t\tget {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T22_C_HideProperty : T22_B_HideProperty\n\t{\n\t\tpublic override int P {\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T23_A_HideMembers\n\t{\n\t\tpublic int F;\n#if ROSLYN\n\t\tpublic int Prop => 3;\n\t\tpublic int G => 3;\n#else\n\t\tpublic int Prop {\n\t\t\tget {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t}\n\t\tpublic int G {\n\t\t\tget {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\tpublic class T23_B_HideMembers : T23_A_HideMembers\n\t{\n#if ROSLYN\n\t\tpublic new int F => 3;\n\t\tpublic new string Prop => \"a\";\n#else\n\t\tpublic new int F {\n\t\t\tget {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t}\n\t\tpublic new string Prop {\n\t\t\tget {\n\t\t\t\treturn \"a\";\n\t\t\t}\n\t\t}\n#endif\n\t}\n\tpublic class T23_C_HideMembers : T23_A_HideMembers\n\t{\n\t\tpublic new int G;\n\t}\n\tpublic class T23_D_HideMembers : T23_A_HideMembers\n\t{\n\t\tpublic new void F()\n\t\t{\n\t\t}\n\t}\n\tpublic class T23_D1_HideMembers : T23_D_HideMembers\n\t{\n\t\tpublic new int F;\n\t}\n\tpublic class T23_E_HideMembers : T23_A_HideMembers\n\t{\n\t\tprivate new class F\n\t\t{\n\t\t}\n\t}\n\tpublic class T23_G_HideMembers2\n\t{\n#if ROSLYN\n\t\tpublic int Item => 1;\n#else\n\t\tpublic int Item {\n\t\t\tget {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\tpublic class T23_G2_HideMembers2 : T23_G_HideMembers2\n\t{\n#if ROSLYN\n\t\tpublic int this[int i] => 2;\n#else\n\t\tpublic int this[int i] {\n\t\t\tget {\n\t\t\t\treturn 2;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\tpublic class T23_G3_HideMembers2 : T23_G2_HideMembers2\n\t{\n#if ROSLYN\n\t\tpublic new int Item => 4;\n#else\n\t\tpublic new int Item {\n\t\t\tget {\n\t\t\t\treturn 4;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\tpublic class T23_H_HideMembers2\n\t{\n#if ROSLYN\n\t\tpublic int this[int j] => 0;\n#else\n\t\tpublic int this[int j] {\n\t\t\tget {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\tpublic class T23_H2_HideMembers2 : T23_H_HideMembers2\n\t{\n#if ROSLYN\n\t\tpublic int Item => 2;\n#else\n\t\tpublic int Item {\n\t\t\tget {\n\t\t\t\treturn 2;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\tpublic class T23_H3_HideMembers2 : T23_H2_HideMembers2\n\t{\n#if ROSLYN\n\t\tpublic new string this[int j] => null;\n#else\n\t\tpublic new string this[int j] {\n\t\t\tget {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\n\tpublic class T24_A_HideMembers2a : T24_IA_HideMembers2a\n\t{\n\t\tint T24_IA_HideMembers2a.this[int i] {\n\t\t\tget {\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T24_A1_HideMembers2a : T24_A_HideMembers2a\n\t{\n#if ROSLYN\n\t\tpublic int this[int i] => 3;\n#else\n\t\tpublic int this[int i] {\n\t\t\tget {\n\t\t\t\treturn 3;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\tpublic interface T24_IA_HideMembers2a\n\t{\n\t\tint this[int i] { get; }\n\t}\n\n\tpublic class T25_G_HideMembers3<T>\n\t{\n\t\tpublic void M1(T p)\n\t\t{\n\t\t}\n\t\tpublic int M2(int t)\n\t\t{\n\t\t\treturn 3;\n\t\t}\n\t}\n\tpublic class T25_G1_HideMembers3<T> : T25_G_HideMembers3<int>\n\t{\n\t\tpublic new int M1(int i)\n\t\t{\n\t\t\treturn 0;\n\t\t}\n\t\tpublic int M2(T i)\n\t\t{\n\t\t\treturn 2;\n\t\t}\n\t}\n\tpublic class T25_G2_HideMembers3<T> : T25_G_HideMembers3<int>\n\t{\n\t\tpublic int M1(T p)\n\t\t{\n\t\t\treturn 4;\n\t\t}\n\t}\n\tpublic class T25_J_HideMembers3\n\t{\n#if ROSLYN\n\t\tpublic int P => 2;\n#else\n\t\tpublic int P {\n\t\t\tget {\n\t\t\t\treturn 2;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\tpublic class T25_J2_HideMembers3 : T25_J_HideMembers3\n\t{\n#pragma warning disable 0108\n\t\t// Deliberate bad code for test case\n\t\tpublic int get_P;\n#pragma warning restore 0108\n\t}\n\tpublic class T26_A_HideMembers4\n\t{\n\t\tpublic void M<T>(T t)\n\t\t{\n\t\t}\n\t}\n\tpublic class T26_A1_HideMembers4 : T26_A_HideMembers4\n\t{\n\t\tpublic new void M<K>(K t)\n\t\t{\n\t\t}\n\t\tpublic void M(int t)\n\t\t{\n\t\t}\n\t}\n\tpublic class T26_B_HideMembers4\n\t{\n\t\tpublic void M<T>()\n\t\t{\n\t\t}\n\t\tpublic void M1<T>()\n\t\t{\n\t\t}\n\t\tpublic void M2<T>(T t)\n\t\t{\n\t\t}\n\t}\n\tpublic class T26_B1_HideMembers4 : T26_B_HideMembers4\n\t{\n\t\tpublic void M<T1, T2>()\n\t\t{\n\t\t}\n\t\tpublic new void M1<R>()\n\t\t{\n\t\t}\n\t\tpublic new void M2<R>(R r)\n\t\t{\n\t\t}\n\t}\n\tpublic class T26_C_HideMembers4<T>\n\t{\n\t\tpublic void M<TT>(T t)\n\t\t{\n\t\t}\n\t}\n\tpublic class T26_C1_HideMembers4<K> : T26_C_HideMembers4<K>\n\t{\n\t\tpublic void M<TT>(TT t)\n\t\t{\n\t\t}\n\t}\n\tpublic class T27_A_HideMembers5\n\t{\n\t\tpublic void M(int t)\n\t\t{\n\t\t}\n\t}\n\tpublic class T27_A1_HideMembers5 : T27_A_HideMembers5\n\t{\n\t\tpublic void M(ref int t)\n\t\t{\n\t\t}\n\t}\n\tpublic class T27_B_HideMembers5\n\t{\n\t\tpublic void M(ref int l)\n\t\t{\n\t\t}\n\t}\n\tpublic class T27_B1_HideMembers5 : T27_B_HideMembers5\n\t{\n\t\tpublic void M(out int l)\n\t\t{\n\t\t\tl = 2;\n\t\t}\n\t\tpublic void M(ref long l)\n\t\t{\n\t\t}\n\t}\n\tpublic class T28_A_HideMemberSkipNotVisible\n\t{\n\t\tprotected int F;\n#if ROSLYN\n\t\tprotected string P => null;\n#else\n\t\tprotected string P {\n\t\t\tget {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\tpublic class T28_B_HideMemberSkipNotVisible : T28_A_HideMemberSkipNotVisible\n\t{\n\t\tprivate new string F;\n\t\tprivate new int P {\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T29_A_HideNestedClass\n\t{\n\t\tpublic class N1\n\t\t{\n\t\t}\n\t\tprotected class N2\n\t\t{\n\t\t}\n\t\tprivate class N3\n\t\t{\n\t\t}\n\t\tinternal class N4\n\t\t{\n\t\t}\n\t\tprotected internal class N5\n\t\t{\n\t\t}\n\t}\n\tpublic class T29_B_HideNestedClass : T29_A_HideNestedClass\n\t{\n\t\tpublic new int N1;\n\t\tpublic new int N2;\n\t\tpublic int N3;\n\t\tpublic new int N4;\n\t\tpublic new int N5;\n\t}\n\tpublic class T30_A_HidePropertyReservedMethod\n\t{\n#if ROSLYN\n\t\tpublic int P => 1;\n#else\n\t\tpublic int P {\n\t\t\tget {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\tpublic class T30_B_HidePropertyReservedMethod : T30_A_HidePropertyReservedMethod\n\t{\n\t\tpublic int get_P()\n\t\t{\n\t\t\treturn 2;\n\t\t}\n\t\tpublic void set_P(int value)\n\t\t{\n\t\t}\n\t}\n\tpublic class T31_A_HideIndexerDiffAccessor\n\t{\n#if ROSLYN\n\t\tpublic int this[int i] => 2;\n#else\n\t\tpublic int this[int i] {\n\t\t\tget {\n\t\t\t\treturn 2;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\tpublic class T31_B_HideIndexerDiffAccessor : T31_A_HideIndexerDiffAccessor\n\t{\n\t\tpublic new int this[int j] {\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T32_A_HideIndexerGeneric<T>\n\t{\n\t\tpublic virtual int this[T r] {\n\t\t\tget {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T32_B_HideIndexerGeneric : T32_A_HideIndexerGeneric<int>\n\t{\n\t\tprivate new int this[int k] {\n\t\t\tget {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T32_C_HideIndexerGeneric<T> : T32_A_HideIndexerGeneric<T>\n\t{\n\t\tpublic override int this[T s] {\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T32_D_HideIndexerGeneric<T> : T32_C_HideIndexerGeneric<T>\n\t{\n\t\tpublic new virtual int this[T s] {\n\t\t\tset {\n\t\t\t}\n\t\t}\n\t}\n\tpublic class T33_A_HideMethod\n\t{\n\t\tpublic virtual void F()\n\t\t{\n\t\t}\n\t}\n\tpublic class T33_B_HideMethod : T33_A_HideMethod\n\t{\n\t\tprivate new void F()\n\t\t{\n\t\t\tbase.F();\n\t\t}\n\t}\n\tpublic class T33_C_HideMethod : T33_B_HideMethod\n\t{\n\t\tpublic override void F()\n\t\t{\n\t\t\tbase.F();\n\t\t}\n\t}\n\tpublic class T34_A_HideMethodGeneric<T>\n\t{\n\t\tpublic virtual void F(T s)\n\t\t{\n\t\t}\n\t\tpublic new static bool Equals(object o1, object o2)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t}\n\tpublic class T34_B_HideMethodGeneric : T34_A_HideMethodGeneric<string>\n\t{\n\t\tprivate new void F(string k)\n\t\t{\n\t\t}\n\t\tpublic void F(int i)\n\t\t{\n\t\t}\n\t}\n\tpublic class T34_C_HideMethodGeneric<T> : T34_A_HideMethodGeneric<T>\n\t{\n\t\tpublic override void F(T r)\n\t\t{\n\t\t}\n\t\tpublic void G(T t)\n\t\t{\n\t\t}\n\t}\n\tpublic class T34_D_HideMethodGeneric<T1> : T34_C_HideMethodGeneric<T1>\n\t{\n\t\tpublic new virtual void F(T1 k)\n\t\t{\n\t\t}\n\t\tpublic virtual void F<T2>(T2 k)\n\t\t{\n\t\t}\n\t\tpublic virtual void G<T2>(T2 t)\n\t\t{\n\t\t}\n\t}\n\tpublic class T35_A_HideMethodGenericSkipPrivate<T>\n\t{\n\t\tpublic virtual void F(T t)\n\t\t{\n\t\t}\n\t}\n\tpublic class T35_B_HideMethodGenericSkipPrivate<T> : T35_A_HideMethodGenericSkipPrivate<T>\n\t{\n\t\tprivate new void F(T t)\n\t\t{\n\t\t}\n\t\tprivate void K()\n\t\t{\n\t\t}\n\t}\n\tpublic class T35_C_HideMethodGenericSkipPrivate<T> : T35_B_HideMethodGenericSkipPrivate<T>\n\t{\n\t\tpublic override void F(T tt)\n\t\t{\n\t\t}\n\t\tpublic void K()\n\t\t{\n\t\t}\n\t}\n\tpublic class T35_D_HideMethodGenericSkipPrivate : T35_B_HideMethodGenericSkipPrivate<int>\n\t{\n\t\tpublic override void F(int t)\n\t\t{\n\t\t}\n\t}\n\tpublic class T36_A_HideMethodGeneric2\n\t{\n\t\tpublic virtual void F(int i)\n\t\t{\n\t\t}\n\t\tpublic void K()\n\t\t{\n\t\t}\n\t}\n\tpublic class T36_B_HideMethodGeneric2<T> : T36_A_HideMethodGeneric2\n\t{\n\t\tprotected virtual void F(T t)\n\t\t{\n\t\t}\n\t\tpublic void K<T2>()\n\t\t{\n\t\t}\n\t}\n\tpublic class T36_C_HideMethodGeneric2 : T36_B_HideMethodGeneric2<int>\n\t{\n\t\tprotected override void F(int k)\n\t\t{\n\t\t}\n\t\tpublic new void K<T3>()\n\t\t{\n\t\t}\n\t}\n\tpublic class T36_D_HideMethodGeneric2 : T36_B_HideMethodGeneric2<string>\n\t{\n\t\tpublic override void F(int k)\n\t\t{\n\t\t}\n\t\tpublic void L<T4>()\n\t\t{\n\t\t}\n\t}\n\tpublic class T36_E_HideMethodGeneric2<T>\n\t{\n\t\tpublic void M<T2>(T t, T2 t2)\n\t\t{\n\t\t}\n\t}\n\tpublic class T36_F_HideMethodGeneric2<T> : T36_E_HideMethodGeneric2<T>\n\t{\n\t\tpublic void M(T t1, T t2)\n\t\t{\n\t\t}\n\t}\n\tpublic class T37_C1_HideMethodDiffSignatures<T>\n\t{\n\t\tpublic virtual void M(T arg)\n\t\t{\n\t\t}\n\t}\n\tpublic class T37_C2_HideMethodDiffSignatures<T1, T2> : T37_C1_HideMethodDiffSignatures<T2>\n\t{\n\t\tpublic new virtual void M(T2 arg)\n\t\t{\n\t\t}\n\t}\n\tpublic class T37_C3_HideMethodDiffSignatures : T37_C2_HideMethodDiffSignatures<int, bool>\n\t{\n\t\tpublic new virtual void M(bool arg)\n\t\t{\n\t\t}\n\t}\n\tpublic class T38_A_HideMethodStatic\n\t{\n#if ROSLYN\n\t\tpublic int N => 0;\n#else\n\t\tpublic int N {\n\t\t\tget {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\tpublic class T38_B_HideMethodStatic\n\t{\n\t\tpublic int N()\n\t\t{\n\t\t\treturn 0;\n\t\t}\n\t}\n\tpublic class T39_A_HideEvent\n\t{\n\t\tpublic virtual event EventHandler E;\n\t\tpublic event EventHandler F;\n\t}\n\tpublic class T39_B_HideEvent : T39_A_HideEvent\n\t{\n\t\tpublic new virtual event EventHandler E;\n\t\tpublic new event EventHandler F;\n\t}\n\tpublic class T39_C_HideEvent : T39_B_HideEvent\n\t{\n\t\tpublic override event EventHandler E;\n\t}\n\n\tpublic class T40_EventVsField\n\t{\n\t\tpublic object KeyDownEvent;\n\t\tprivate event EventHandler KeyDown;\n\n\t\tpublic void UseObject()\n\t\t{\n\t\t\tConsole.WriteLine(KeyDownEvent);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/UnsafeCode.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n#if !NET40 && ROSLYN\nusing System.Runtime.CompilerServices;\n#endif\nusing System.Runtime.InteropServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class SizeofTest\n\t{\n\t\tprivate struct StructWithStaticField\n\t\t{\n\t\t\tpublic static object StaticObj;\n\n#if CS110 && NET70\n\t\t\tpublic nint A;\n#else\n\t\t\tpublic IntPtr A;\n#endif\n\t\t}\n\n\t\tprivate struct UnmanagedStruct\n\t\t{\n\t\t\tpublic StructWithStaticField Value;\n\t\t}\n\n\t\tprivate struct ManagedStruct\n\t\t{\n\t\t\tpublic object Obj;\n\t\t}\n#if CS73\n\t\tprivate unsafe int GenericMethod<T>() where T : unmanaged\n\t\t{\n\t\t\treturn sizeof(T);\n\t\t}\n#endif\n\n\t\tprivate unsafe void Test(out int s1, out int s2, out int s3)\n\t\t{\n\t\t\ts1 = 0;\n\t\t\ts2 = 0;\n\t\t\ts3 = 0;\n#if CS73\n\t\t\tGenericMethod<UnmanagedStruct>();\n#endif\n\t\t\ts1 = sizeof(UnmanagedStruct);\n#if !NET40 && ROSLYN\n\t\t\ts2 = Unsafe.SizeOf<UnmanagedStruct>();\n\t\t\ts3 = Unsafe.SizeOf<ManagedStruct>();\n#endif\n\t\t}\n\t}\n\n\tpublic class UnsafeCode\n\t{\n\t\tpublic struct SimpleStruct\n\t\t{\n\t\t\tpublic int X;\n\t\t\tpublic double Y;\n\t\t}\n\n#if CS120\n\t\tpublic unsafe struct ResultStruct(byte* ptr1, byte* ptr2)\n\t\t{\n\t\t\tpublic unsafe byte* ptr1 = ptr1;\n\t\t\tpublic unsafe byte* ptr2 = ptr2;\n\t\t}\n#else\n\t\tpublic struct ResultStruct\n\t\t{\n\t\t\tpublic unsafe byte* ptr1;\n\t\t\tpublic unsafe byte* ptr2;\n\n\t\t\tpublic unsafe ResultStruct(byte* ptr1, byte* ptr2)\n\t\t\t{\n\t\t\t\tthis.ptr1 = ptr1;\n\t\t\t\tthis.ptr2 = ptr2;\n\t\t\t}\n\t\t}\n#endif\n\n\t\tpublic struct StructWithFixedSizeMembers\n\t\t{\n\t\t\tpublic unsafe fixed int Integers[100];\n\t\t\tpublic int NormalMember;\n\t\t\tpublic unsafe fixed double Doubles[200];\n\n\t\t\t[Obsolete(\"another attribute\")]\n\t\t\tpublic unsafe fixed byte Old[1];\n\t\t}\n\n\t\tprivate struct Data\n\t\t{\n\t\t\tpublic Vector Position;\n\t\t}\n\n\t\t[StructLayout(LayoutKind.Sequential, Size = 1)]\n\t\tprivate struct Vector\n\t\t{\n\t\t\tpublic override int GetHashCode()\n\t\t\t{\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\n#if CS73\n\t\tpublic class CustomPinnable\n\t\t{\n\t\t\tpublic ref int GetPinnableReference()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n#endif\n\n\t\tpublic unsafe delegate void UnsafeDelegate(byte* ptr);\n\n\t\tprivate UnsafeDelegate unsafeDelegate;\n\t\tprivate static UnsafeDelegate staticUnsafeDelegate;\n\n#if CS60\n\t\tpublic unsafe int* NullPointer => null;\n#else\n\t\tpublic unsafe int* NullPointer {\n\t\t\tget {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n#endif\n\n\t\tunsafe static UnsafeCode()\n\t\t{\n\t\t\tstaticUnsafeDelegate = UnsafeStaticMethod;\n\t\t}\n\n\t\tpublic unsafe UnsafeCode()\n\t\t{\n\t\t\tunsafeDelegate = UnsafeMethod;\n\t\t}\n\n\t\tpublic unsafe int SizeOf()\n\t\t{\n\t\t\treturn sizeof(SimpleStruct);\n\t\t}\n\n\t\tprivate static void UseBool(bool b)\n\t\t{\n\t\t}\n\n\t\tprivate unsafe void UnsafeMethod(byte* ptr)\n\t\t{\n\n\t\t}\n\n\t\tprivate unsafe static void UnsafeStaticMethod(byte* ptr)\n\t\t{\n\n\t\t}\n\n\t\tpublic unsafe void PointerComparison(int* a, double* b)\n\t\t{\n\t\t\tUseBool(a == b);\n\t\t\tUseBool(a != b);\n\t\t\tUseBool(a < b);\n\t\t\tUseBool(a > b);\n\t\t\tUseBool(a <= b);\n\t\t\tUseBool(a >= b);\n\t\t}\n\n\t\tpublic unsafe void PointerComparisonWithNull(int* a)\n\t\t{\n\t\t\tUseBool(a == null);\n\t\t\tUseBool(a != null);\n\t\t}\n\n\t\tpublic unsafe int* PointerCast(long* p)\n\t\t{\n\t\t\treturn (int*)p;\n\t\t}\n\n\t\tpublic unsafe long ConvertDoubleToLong(double d)\n\t\t{\n\t\t\treturn *(long*)(&d);\n\t\t}\n\n\t\tpublic unsafe double ConvertLongToDouble(long d)\n\t\t{\n\t\t\treturn *(double*)(&d);\n\t\t}\n\n\t\tpublic unsafe int ConvertFloatToInt(float d)\n\t\t{\n\t\t\treturn *(int*)(&d);\n\t\t}\n\n\t\tpublic unsafe float ConvertIntToFloat(int d)\n\t\t{\n\t\t\treturn *(float*)(&d);\n\t\t}\n\n\t\tpublic unsafe int PointerCasts()\n\t\t{\n\t\t\tint result = 0;\n\t\t\t*(float*)(&result) = 0.5f;\n\t\t\t((sbyte*)(&result))[3] = 3;\n\t\t\t((sbyte*)(&result))[3] = -1;\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic unsafe void PassRefParameterAsPointer(ref int p)\n\t\t{\n\t\t\tfixed (int* ptr = &p)\n\t\t\t{\n\t\t\t\tUsePointer(ptr);\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe void PassPointerAsRefParameter(int* p)\n\t\t{\n\t\t\tUseReference(ref *p);\n\t\t}\n\n\t\tpublic unsafe void PassPointerCastAsRefParameter(uint* p)\n\t\t{\n\t\t\tUseReference(ref *(int*)p);\n\t\t}\n\n\t\tpublic unsafe void AddressInMultiDimensionalArray(double[,] matrix)\n\t\t{\n\t\t\tfixed (double* d = &matrix[1, 2])\n\t\t\t{\n\t\t\t\tPointerReferenceExpression(d);\n\t\t\t\tPointerReferenceExpression(d);\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe void FixedStringAccess(string text)\n\t\t{\n\t\t\tfixed (char* ptr = text)\n\t\t\t{\n\t\t\t\tfor (char* ptr2 = ptr; *ptr2 == 'a'; ptr2++)\n\t\t\t\t{\n\t\t\t\t\t*ptr2 = 'A';\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe void FixedStringNoPointerUse(string text)\n\t\t{\n\t\t\tfixed (char* ptr = text)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n#if !(LEGACY_CSC && OPT)\n\t\t// legacy csc manages to optimize out the pinned variable altogether in this case;\n\t\t// leaving no pinned region we could detect.\n\t\tpublic unsafe void FixedArrayNoPointerUse(int[] arr)\n\t\t{\n\t\t\tfixed (int* ptr = arr)\n\t\t\t{\n\t\t\t}\n\t\t}\n#endif\n\n\t\tpublic unsafe void PutDoubleIntoLongArray1(long[] array, int index, double val)\n\t\t{\n\t\t\tfixed (long* ptr = array)\n\t\t\t{\n\t\t\t\t*(double*)(ptr + index) = val;\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe void PutDoubleIntoLongArray2(long[] array, int index, double val)\n\t\t{\n\t\t\tfixed (long* ptr = &array[index])\n\t\t\t{\n\t\t\t\t*(double*)ptr = val;\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe string PointerReferenceExpression(double* d)\n\t\t{\n\t\t\treturn d->ToString();\n\t\t}\n\n\t\tpublic unsafe string PointerReferenceExpression2(long addr)\n\t\t{\n\t\t\treturn ((int*)addr)->ToString();\n\t\t}\n\n\t\tpublic unsafe int* PointerArithmetic(int* p)\n\t\t{\n\t\t\treturn p + 2;\n\t\t}\n\n\t\tpublic unsafe long* PointerArithmetic2(long* p)\n\t\t{\n\t\t\treturn 3 + p;\n\t\t}\n\n\t\tpublic unsafe long* PointerArithmetic3(long* p)\n\t\t{\n\t\t\treturn (long*)((byte*)p + 3);\n\t\t}\n\n\t\tpublic unsafe long* PointerArithmetic4(void* p)\n\t\t{\n\t\t\treturn (long*)((byte*)p + 3);\n\t\t}\n\n\t\tpublic unsafe int PointerArithmetic5(void* p, byte* q, int i)\n\t\t{\n\t\t\treturn q[i] + *(byte*)p;\n\t\t}\n\n\t\tpublic unsafe int PointerArithmetic6(SimpleStruct* p, int i)\n\t\t{\n\t\t\treturn p[i].X;\n\t\t}\n\n\t\tpublic unsafe int* PointerArithmeticLong1(int* p, long offset)\n\t\t{\n\t\t\treturn p + offset;\n\t\t}\n\n\t\tpublic unsafe int* PointerArithmeticLong2(int* p, long offset)\n\t\t{\n\t\t\treturn offset + p;\n\t\t}\n\n\t\tpublic unsafe int* PointerArithmeticLong3(int* p, long offset)\n\t\t{\n\t\t\treturn p - offset;\n\t\t}\n\n\t\tpublic unsafe SimpleStruct* PointerArithmeticLong1s(SimpleStruct* p, long offset)\n\t\t{\n\t\t\treturn p + offset;\n\t\t}\n\n\t\tpublic unsafe SimpleStruct* PointerArithmeticLong2s(SimpleStruct* p, long offset)\n\t\t{\n\t\t\treturn offset + p;\n\t\t}\n\n\t\tpublic unsafe SimpleStruct* PointerArithmeticLong3s(SimpleStruct* p, long offset)\n\t\t{\n\t\t\treturn p - offset;\n\t\t}\n\n\t\tpublic unsafe int PointerSubtraction(long* p, long* q)\n\t\t{\n\t\t\treturn (int)(p - q);\n\t\t}\n\n\t\tpublic unsafe long PointerSubtractionLong(long* p, long* q)\n\t\t{\n\t\t\treturn p - q;\n\t\t}\n\n\t\tpublic unsafe int PointerSubtraction2(long* p, short* q)\n\t\t{\n\t\t\treturn (int)((byte*)p - (byte*)q);\n\t\t}\n\n\t\tpublic unsafe int PointerSubtraction3(void* p, void* q)\n\t\t{\n\t\t\treturn (int)((byte*)p - (byte*)q);\n\t\t}\n\n\t\tpublic unsafe long PointerSubtraction4(sbyte* p, sbyte* q)\n\t\t{\n\t\t\treturn p - q;\n\t\t}\n\n\t\tpublic unsafe long PointerSubtraction5(SimpleStruct* p, SimpleStruct* q)\n\t\t{\n\t\t\treturn p - q;\n\t\t}\n\n\t\tpublic unsafe long Issue2158a(void* p, void* q)\n\t\t{\n\t\t\treturn (long)p - (long)q;\n\t\t}\n\n\t\tpublic unsafe long Issue2158b(sbyte* p, sbyte* q)\n\t\t{\n\t\t\treturn (long)p - (long)q;\n\t\t}\n\n\t\tpublic unsafe long Issue2158c(int* p, int* q)\n\t\t{\n\t\t\treturn (long)p - (long)q;\n\t\t}\n\n\t\tpublic unsafe long Issue2158d(SimpleStruct* p, SimpleStruct* q)\n\t\t{\n\t\t\treturn (long)p - (long)q;\n\t\t}\n\n\t\tpublic unsafe double FixedMemberAccess(StructWithFixedSizeMembers* m, int i)\n\t\t{\n\t\t\treturn (double)m->Integers[i] + m->Doubles[i];\n\t\t}\n\n\t\tpublic unsafe double* FixedMemberBasePointer(StructWithFixedSizeMembers* m)\n\t\t{\n\t\t\treturn m->Doubles;\n\t\t}\n\n\t\tpublic unsafe void UseFixedMemberAsPointer(StructWithFixedSizeMembers* m)\n\t\t{\n\t\t\tUsePointer(m->Integers);\n\t\t}\n\n\t\tpublic unsafe void UseFixedMemberAsReference(StructWithFixedSizeMembers* m)\n\t\t{\n\t\t\tUseReference(ref *m->Integers);\n\t\t\tUseReference(ref m->Integers[1]);\n\t\t}\n\n\t\tpublic unsafe void PinFixedMember(ref StructWithFixedSizeMembers m)\n\t\t{\n\t\t\tfixed (int* integers = m.Integers)\n\t\t\t{\n\t\t\t\tUsePointer(integers);\n\t\t\t}\n\t\t}\n\n\t\tprivate void UseReference(ref int i)\n\t\t{\n\t\t}\n\n\t\tpublic unsafe string UsePointer(int* ptr)\n\t\t{\n\t\t\treturn ptr->ToString();\n\t\t}\n\n\t\tpublic unsafe string UsePointer(double* ptr)\n\t\t{\n\t\t\treturn ptr->ToString();\n\t\t}\n\n\t\tpublic unsafe void FixedMultiDimArray(int[,] arr)\n\t\t{\n\t\t\tfixed (int* ptr = arr)\n\t\t\t{\n\t\t\t\tUsePointer(ptr);\n\t\t\t}\n\t\t}\n\n#if CS73 && !NET40\n\t\tpublic unsafe void FixedSpan(Span<int> span)\n\t\t{\n\t\t\tfixed (int* ptr = span)\n\t\t\t{\n\t\t\t\tUsePointer(ptr);\n\t\t\t}\n\t\t}\n#endif\n\n#if CS73\n\t\tpublic unsafe void FixedCustomReferenceType(CustomPinnable mem)\n\t\t{\n\t\t\tfixed (int* ptr = mem)\n\t\t\t{\n\t\t\t\tUsePointer(ptr);\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe void FixedCustomReferenceTypeNoPointerUse(CustomPinnable mem)\n\t\t{\n\t\t\tfixed (int* ptr = mem)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Hello World!\");\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe void FixedCustomReferenceTypeExplicitGetPinnableReference(CustomPinnable mem)\n\t\t{\n\t\t\tfixed (int* ptr = &mem.GetPinnableReference())\n\t\t\t{\n\t\t\t\tUsePointer(ptr);\n\t\t\t}\n\t\t}\n#endif\n\n\t\tpublic unsafe string StackAlloc(int count)\n\t\t{\n\t\t\tchar* ptr = stackalloc char[count];\n\t\t\tchar* ptr2 = stackalloc char[100];\n\t\t\tfor (int i = 0; i < count; i++)\n\t\t\t{\n\t\t\t\tptr[i] = (char)i;\n\t\t\t\tptr2[i] = '\\0';\n\t\t\t}\n\t\t\treturn UsePointer((double*)ptr);\n\t\t}\n\n\t\tpublic unsafe string StackAllocStruct(int count)\n\t\t{\n\t\t\tSimpleStruct* ptr = stackalloc SimpleStruct[checked(count * 2)];\n#if !(ROSLYN && OPT)\n\t\t\t// unused stackalloc gets optimized out by roslyn\n\t\t\tSimpleStruct* ptr2 = stackalloc SimpleStruct[10];\n#endif\n\t\t\tptr->X = count;\n\t\t\tptr[1].X = ptr->X;\n\t\t\tfor (int i = 2; i < 10; i++)\n\t\t\t{\n\t\t\t\tptr[i].X = count;\n\t\t\t}\n\t\t\treturn UsePointer(&ptr->Y);\n\t\t}\n\n\t\tunsafe ~UnsafeCode()\n\t\t{\n\t\t\tPassPointerAsRefParameter(NullPointer);\n\t\t}\n\n\t\tprivate unsafe void Issue990()\n\t\t{\n\t\t\tData data = default(Data);\n\t\t\tData* ptr = &data;\n\t\t\tConvertIntToFloat(ptr->Position.GetHashCode());\n\t\t}\n\n\t\tprivate unsafe static void Issue1021(ref byte* bytePtr, ref short* shortPtr)\n\t\t{\n\t\t\tbytePtr += 4;\n\t\t\tshortPtr += 2;\n\t\t\tbytePtr -= 4;\n\t\t\tshortPtr = (short*)((byte*)shortPtr - 3);\n\t\t}\n\n\t\tprivate static T Get<T>()\n\t\t{\n\t\t\treturn default(T);\n\t\t}\n\n\t\tprivate unsafe static ResultStruct NestedFixedBlocks(byte[] array)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tfixed (byte* ptr = array)\n\t\t\t\t{\n\t\t\t\t\tfixed (byte* ptr2 = Get<byte[]>())\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new ResultStruct(ptr, ptr2);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally\");\n\t\t\t}\n\t\t}\n\n\t\tprivate unsafe static object CreateBuffer(int length, byte* ptr)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tprivate unsafe static object Issue1386(int arraySize, bool createFirstBuffer)\n\t\t{\n\t\t\tif (createFirstBuffer)\n\t\t\t{\n\t\t\t\tbyte[] array = new byte[arraySize];\n\t\t\t\tConsole.WriteLine(\"first fixed\");\n\t\t\t\tfixed (byte* ptr = array)\n\t\t\t\t{\n\t\t\t\t\treturn CreateBuffer(array.Length, ptr);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbyte[] array2 = new byte[arraySize];\n\t\t\tConsole.WriteLine(\"second fixed\");\n\t\t\tfixed (byte* ptr2 = array2)\n\t\t\t{\n\t\t\t\treturn CreateBuffer(array2.Length, ptr2);\n\t\t\t}\n\t\t}\n\n\t\tprivate unsafe static void Issue1499(StructWithFixedSizeMembers value, int index)\n\t\t{\n\t\t\tint num = value.Integers[index];\n\t\t\tnum.ToString();\n\t\t}\n\n#if CS73\n\t\tprivate unsafe static int Issue2287(ref StructWithFixedSizeMembers value)\n\t\t{\n\t\t\treturn value.Integers[0] + value.Integers[1];\n\t\t}\n#endif\n\n\t\tprivate unsafe static int Issue2305(StructWithFixedSizeMembers value, StringComparison s)\n\t\t{\n\t\t\treturn value.Integers[(int)s];\n\t\t}\n\n#if CS90\n\t\tprivate unsafe static void* CastNIntToVoidPtr(nint intptr)\n\t\t{\n\t\t\treturn (void*)intptr;\n\t\t}\n\n\t\tprivate unsafe static void* CastNIntToVoidPtr(nuint intptr)\n\t\t{\n\t\t\treturn (void*)intptr;\n\t\t}\n#endif\n#if !(CS110 && NET70)\n\t\tprivate unsafe static void* CastToVoidPtr(IntPtr intptr)\n\t\t{\n\t\t\treturn (void*)intptr;\n\t\t}\n\n\t\tprivate unsafe static void* CastToVoidPtr(UIntPtr intptr)\n\t\t{\n\t\t\treturn (void*)intptr;\n\t\t}\n#endif\n\n\t\tprivate unsafe static void* CastToVoidPtr(int* intptr)\n\t\t{\n\t\t\treturn intptr;\n\t\t}\n\n\t\tpublic unsafe void ConditionalPointer(bool a, int* ptr)\n\t\t{\n\t\t\tUsePointer(a ? ptr : null);\n\t\t}\n\n\t\tpublic unsafe void UseArrayOfPointers(int*[] arr)\n\t\t{\n\t\t\tfor (int i = 0; i < arr.Length; i++)\n\t\t\t{\n\t\t\t\tarr[i] = null;\n\t\t\t}\n\t\t}\n\n\t\tpublic unsafe void PassNullPointer1()\n\t\t{\n\t\t\tPointerReferenceExpression(null);\n\t\t}\n\n\t\tpublic unsafe void PassNullPointer2()\n\t\t{\n\t\t\tUseArrayOfPointers(null);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/UserDefinedConversions.cs",
    "content": "// Copyright (c) 2019 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class T01Issue1574\n\t{\n\t\tprivate struct A\n\t\t{\n\t\t\tprivate bool val;\n\n\t\t\tpublic static implicit operator bool(A a)\n\t\t\t{\n\t\t\t\treturn a.val;\n\t\t\t}\n\t\t}\n\n\t\tprivate struct C\n\t\t{\n\t\t\tprivate int val;\n\n\t\t\tpublic static implicit operator C(bool b)\n\t\t\t{\n\t\t\t\treturn default(C);\n\t\t\t}\n\t\t}\n\n\t\tprivate C ChainedConversion()\n\t\t{\n\t\t\treturn (bool)default(A);\n\t\t}\n\n\t\tpublic void Call_Overloaded()\n\t\t{\n\t\t\tOverloaded((bool)default(A));\n\t\t}\n\n\t\tprivate void Overloaded(A a)\n\t\t{\n\t\t}\n\n\t\tprivate void Overloaded(bool a)\n\t\t{\n\t\t}\n\t}\n\n\tinternal class T02BothDirectAndChainedConversionPossible\n\t{\n\t\tprivate struct A\n\t\t{\n\t\t\tprivate bool val;\n\n\t\t\tpublic static implicit operator bool(A a)\n\t\t\t{\n\t\t\t\treturn a.val;\n\t\t\t}\n\t\t}\n\n\t\tprivate struct C\n\t\t{\n\t\t\tprivate int val;\n\n\t\t\tpublic static implicit operator C(bool b)\n\t\t\t{\n\t\t\t\treturn default(C);\n\t\t\t}\n\n\t\t\tpublic static implicit operator C(A a)\n\t\t\t{\n\t\t\t\treturn default(C);\n\t\t\t}\n\n\t\t\tpublic static bool operator ==(C a, C b)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tpublic static bool operator !=(C a, C b)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tprivate C DirectConvert(A a)\n\t\t{\n\t\t\treturn a;\n\t\t}\n\n\t\tprivate C IndirectConvert(A a)\n\t\t{\n\t\t\treturn (bool)a;\n\t\t}\n\n\t\tprivate C? LiftedDirectConvert(A? a)\n\t\t{\n\t\t\treturn a;\n\t\t}\n\n\t\tprivate C? LiftedIndirectConvert(A? a)\n\t\t{\n\t\t\treturn (bool?)a;\n\t\t}\n\n\t\tprivate bool Compare(A a, C c)\n\t\t{\n\t\t\treturn a == c;\n\t\t}\n\n\t\tprivate void LiftedCompare(A? a, C? c)\n\t\t{\n\t\t\tUseBool(a == c);\n\t\t\tUseBool(a == default(C));\n\t\t\tUseBool(c == default(A));\n\t\t}\n\n\t\tprivate void UseBool(bool b)\n\t\t{\n\t\t}\n\t}\n\n#if CS72\n\tinternal class T03ConversionWithInArgument\n\t{\n\t\tprivate struct T\n\t\t{\n\t\t\tprivate byte dummy;\n\n\t\t\tpublic static implicit operator T(in int val)\n\t\t\t{\n\t\t\t\treturn default(T);\n\t\t\t}\n\n\t\t\tpublic static explicit operator T(in long val)\n\t\t\t{\n\t\t\t\treturn default(T);\n\t\t\t}\n\t\t}\n\n\t\tprivate struct U\n\t\t{\n\t\t\tprivate byte dummy;\n\n\t\t\tpublic static implicit operator T(in U u)\n\t\t\t{\n\t\t\t\treturn default(T);\n\t\t\t}\n\n\t\t\tpublic static explicit operator int(in U u)\n\t\t\t{\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\n\t\tprivate void UseT(T t)\n\t\t{\n\t\t}\n\n\t\tprivate int Test(int i, long l, U u)\n\t\t{\n\t\t\tUseT(i);\n\t\t\tUseT((T)l);\n\t\t\tUseT(u);\n\t\t\treturn (int)u;\n\t\t}\n\t}\n#endif\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/Using.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\nusing System.Runtime.InteropServices;\nusing System.Threading;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class Using\n\t{\n\t\t[StructLayout(LayoutKind.Sequential, Size = 1)]\n\t\tprivate struct UsingStruct : IDisposable\n\t\t{\n\t\t\tpublic UsingStruct(int i)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(i);\n\t\t\t}\n\n\t\t\tvoid IDisposable.Dispose()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n\n\t\tprivate struct TypeA_Issue3385 : IDisposable\n\t\t{\n\t\t\tprivate int dummy;\n\n\t\t\tpublic void Dispose()\n\t\t\t{\n\t\t\t}\n\n#if !ROSLYN3\n\t\t\tpublic static implicit operator TypeB_Issue3385(TypeA_Issue3385 a)\n\t\t\t{\n\t\t\t\treturn default(TypeB_Issue3385);\n\t\t\t}\n#else\n\t\t\tpublic static implicit operator TypeB_Issue3385(in TypeA_Issue3385 a)\n\t\t\t{\n\t\t\t\treturn default(TypeB_Issue3385);\n\t\t\t}\n#endif\n\t\t}\n\n\t\tprivate struct TypeB_Issue3385\n\t\t{\n\t\t\tprivate int dummy;\n\t\t}\n\n#if CS80\n\t\t[StructLayout(LayoutKind.Sequential, Size = 1)]\n\t\tpublic ref struct UsingRefStruct\n\t\t{\n\t\t\tpublic int i;\n\n\t\t\tpublic UsingRefStruct(int i)\n\t\t\t{\n\t\t\t\tthis.i = i;\n\t\t\t\tConsole.WriteLine(i);\n\t\t\t}\n\n\t\t\tpublic void Dispose()\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n#endif\n\n#if LEGACY_CSC\n\t\t// roslyn optimizes out the try-finally; mcs has a compiler bug on using(null-literal)\n\t\tpublic void SimpleUsingNullStatement()\n\t\t{\n\t\t\tusing (null)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"using (null)\");\n\t\t\t}\n\t\t}\n#endif\n\n\t\tpublic void SimpleUsingExpressionStatement()\n\t\t{\n\t\t\tusing (new MemoryStream())\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"using-body\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void SimpleUsingExpressionStatementWithDeclaration()\n\t\t{\n\t\t\tusing (MemoryStream memoryStream = new MemoryStream())\n\t\t\t{\n\t\t\t\tmemoryStream.WriteByte(42);\n\t\t\t\tConsole.WriteLine(\"using-body: \" + memoryStream.Position);\n\t\t\t}\n\t\t}\n\n\t\tpublic void UsingStatementThatChangesTheVariable()\n\t\t{\n\t\t\tCancellationTokenSource cancellationTokenSource = new CancellationTokenSource();\n\t\t\tusing (cancellationTokenSource)\n\t\t\t{\n\t\t\t\tcancellationTokenSource = new CancellationTokenSource();\n\t\t\t}\n\t\t\tcancellationTokenSource.Cancel();\n\t\t}\n\n\t\tpublic void UsingStatementOnStruct()\n\t\t{\n\t\t\tusing (new UsingStruct(1))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"using-body\");\n\t\t\t}\n\t\t}\n\n\t\tpublic void UsingStatementOnStructWithVariable()\n\t\t{\n\t\t\tusing (UsingStruct usingStruct = new UsingStruct(2))\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"using-body: \" + usingStruct);\n\t\t\t}\n\t\t}\n\n\t\tprivate void UsingStatementOnNullableStruct(UsingStruct? us)\n\t\t{\n\t\t\tusing (us)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"using-body: \" + us.ToString());\n\t\t\t}\n\t\t}\n\n\t\tpublic void GenericUsing<T>(T t) where T : IDisposable\n\t\t{\n\t\t\tusing (t)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(t);\n\t\t\t}\n\t\t}\n\n\t\tpublic void GenericStructUsing<T>(T t) where T : struct, IDisposable\n\t\t{\n\t\t\tusing (t)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(t);\n\t\t\t}\n\t\t}\n\n\t\tpublic void GenericClassUsing<T>(T t) where T : class, IDisposable\n\t\t{\n\t\t\tusing (t)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(t);\n\t\t\t}\n\t\t}\n\n\t\tpublic void GenericNullableUsing<T>(T? t) where T : struct, IDisposable\n\t\t{\n\t\t\tusing (t)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(t);\n\t\t\t}\n\t\t}\n\n#if CS80\n\t\tpublic void UsingRefStruct1(UsingRefStruct s)\n\t\t{\n\t\t\tusing (s)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(s.i);\n\t\t\t}\n\t\t}\n#endif\n\n\t\tpublic static void Issue3385()\n\t\t{\n#if ROSLYN3\n\t\t\tusing (TypeA_Issue3385 a = default(TypeA_Issue3385))\n#else\n\t\t\tusing (TypeA_Issue3385 typeA_Issue = default(TypeA_Issue3385))\n#endif\n\t\t\t{\n#if ROSLYN3\n\t\t\t\tEmpty(a);\n#else\n\t\t\t\tEmpty(typeA_Issue);\n#endif\n\t\t\t}\n\t\t}\n\n\t\tprivate static void Empty(TypeB_Issue3385 b)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/UsingVariables.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n#if !NET40\nusing System.Threading.Tasks;\n#endif\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class UsingVariables\n\t{\n\t\tpublic IDisposable GetDisposable()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tprivate void Use(IDisposable disposable)\n\t\t{\n\n\t\t}\n\n#if !NET40\n\t\tpublic IAsyncDisposable GetAsyncDisposable()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tprivate void Use(IAsyncDisposable asyncDisposable)\n\t\t{\n\n\t\t}\n#endif\n\n\t\tpublic void SimpleUsingVar()\n\t\t{\n\t\t\tConsole.WriteLine(\"before using\");\n\t\t\tusing IDisposable disposable = GetDisposable();\n\t\t\tConsole.WriteLine(\"inside using\");\n\t\t\tUse(disposable);\n\t\t}\n\n\t\tpublic void NotAUsingVar()\n\t\t{\n\t\t\tConsole.WriteLine(\"before using\");\n\t\t\tusing (IDisposable disposable = GetDisposable())\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"inside using\");\n\t\t\t\tUse(disposable);\n\t\t\t}\n\t\t\tConsole.WriteLine(\"outside using\");\n\t\t}\n\n\t\tpublic void UsingVarInNestedBlocks(bool condition)\n\t\t{\n\t\t\tif (condition)\n\t\t\t{\n\t\t\t\tusing IDisposable disposable = GetDisposable();\n\t\t\t\tConsole.WriteLine(\"inside using\");\n\t\t\t\tUse(disposable);\n\t\t\t}\n\t\t\tConsole.WriteLine(\"outside using\");\n\t\t}\n\n\t\tpublic void MultipleUsingVars(IDisposable other)\n\t\t{\n\t\t\tConsole.WriteLine(\"before using\");\n\t\t\tusing IDisposable disposable = GetDisposable();\n\t\t\tConsole.WriteLine(\"inside outer using\");\n\t\t\tusing IDisposable disposable2 = other;\n\t\t\tConsole.WriteLine(\"inside inner using\");\n\t\t\tUse(disposable);\n\t\t\tUse(disposable2);\n\t\t}\n#if !NET40\n\t\tpublic async Task SimpleUsingVarAsync()\n\t\t{\n\t\t\tConsole.WriteLine(\"before using\");\n\t\t\tawait using IAsyncDisposable asyncDisposable = GetAsyncDisposable();\n\t\t\tConsole.WriteLine(\"inside using\");\n\t\t\tUse(asyncDisposable);\n\t\t}\n#endif\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/ValueTypes.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic static class ValueTypes\n\t{\n\t\tpublic struct S\n\t\t{\n\t\t\tpublic int Field;\n\n\t\t\tpublic int Property {\n\t\t\t\tget {\n\t\t\t\t\treturn Field;\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t\tField = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic S(int field)\n\t\t\t{\n\t\t\t\tField = field;\n\t\t\t}\n\n\t\t\tpublic void SetField()\n\t\t\t{\n\t\t\t\tField = 5;\n\t\t\t}\n\n\t\t\tpublic void MethodCalls()\n\t\t\t{\n\t\t\t\tSetField();\n\t\t\t\tTest(this);\n\t\t\t\tTest(ref this);\n\t\t\t}\n\n\t\t\tprivate static void Test(S byVal)\n\t\t\t{\n\t\t\t}\n\n\t\t\tprivate static void Test(ref S byRef)\n\t\t\t{\n\t\t\t}\n\n\t\t\tpublic void CallOnThis()\n\t\t\t{\n\t\t\t\t// distinguish calls on 'this' from calls on a copy of 'this'\n\t\t\t\tSetField();\n\t\t\t\tS s = this;\n\t\t\t\ts.SetField();\n\t\t\t}\n\n\t\t\tpublic void UseField(int val)\n\t\t\t{\n\t\t\t\tUseField(Get<S>().Field);\n\t\t\t}\n\t\t}\n\n#if CS72\n\t\tpublic readonly struct R\n\t\t{\n\t\t\tpublic readonly int Field;\n\n\t\t\tpublic int Property {\n\t\t\t\tget {\n\t\t\t\t\treturn Field;\n\t\t\t\t}\n\t\t\t\tset {\n\t\t\t\t\tConsole.WriteLine(\"Setter on readonly struct\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic void Method()\n\t\t\t{\n\t\t\t}\n\n\t\t\tpublic void CallOnThis()\n\t\t\t{\n\t\t\t\t// distinguish calls on 'this' from calls on a copy of 'this'\n\t\t\t\tMethod();\n\t\t\t\tR r = this;\n\t\t\t\tr.Method();\n\t\t\t}\n\t\t}\n#endif\n\n#if ROSLYN\n\t\t// Roslyn optimizes out the explicit default-initialization\n\t\tprivate static readonly S ReadOnlyS;\n\t\tprivate static S MutableS;\n#else\n\t\tprivate static readonly S ReadOnlyS = default(S);\n\t\tprivate static S MutableS = default(S);\n#endif\n\t\tprivate static volatile int VolatileInt;\n#if CS72\n\t\tprivate static readonly R ReadOnlyR;\n\t\tprivate static R MutableR;\n#endif\n\n\t\tpublic static void CallMethodViaField()\n\t\t{\n\t\t\tReadOnlyS.SetField();\n\t\t\tMutableS.SetField();\n\t\t\tS mutableS = MutableS;\n\t\t\tmutableS.SetField();\n\n#if CS72\n\t\t\tReadOnlyR.Method();\n\t\t\tR readOnlyR = ReadOnlyR;\n\t\t\treadOnlyR.Method();\n\t\t\tR mutableR = MutableR;\n\t\t\tmutableR.Method();\n#endif\n\t\t}\n\n#if !(ROSLYN && OPT) || COPY_PROPAGATION_FIXED\n\t\tpublic static S InitObj1()\n\t\t{\n\t\t\tS result = default(S);\n\t\t\tMakeArray();\n\t\t\treturn result;\n\t\t}\n#endif\n\n\t\tpublic static S InitObj2()\n\t\t{\n\t\t\treturn default(S);\n\t\t}\n\n\t\tpublic static void InitObj3(out S p)\n\t\t{\n\t\t\tp = default(S);\n\t\t}\n\n\t\tpublic static S CallValueTypeCtor()\n\t\t{\n\t\t\treturn new S(10);\n\t\t}\n\n\t\tpublic static S Copy1(S p)\n\t\t{\n\t\t\treturn p;\n\t\t}\n\n\t\tpublic static S Copy2(ref S p)\n\t\t{\n\t\t\treturn p;\n\t\t}\n\n\t\tpublic static void Copy3(S p, out S o)\n\t\t{\n\t\t\to = p;\n\t\t}\n\n\t\tpublic static void Copy4(ref S p, out S o)\n\t\t{\n\t\t\to = p;\n\t\t}\n\n\t\tpublic static void Copy4b(ref S p, out S o)\n\t\t{\n\t\t\t// test passing through by-ref arguments\n\t\t\tCopy4(ref p, out o);\n\t\t}\n\n\t\tpublic static void Issue56(int i, out string str)\n\t\t{\n\t\t\tstr = \"qq\";\n\t\t\tstr += i;\n\t\t}\n\n\t\tpublic static void CopyAroundAndModifyField(S s)\n\t\t{\n\t\t\tS s2 = s;\n\t\t\ts2.Field += 10;\n\t\t\ts = s2;\n\t\t}\n\n\t\tprivate static int[] MakeArray()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static void IncrementArrayLocation()\n\t\t{\n\t\t\tMakeArray()[Environment.TickCount]++;\n\t\t}\n\n\t\tpublic static bool Is(object obj)\n\t\t{\n\t\t\treturn obj is S;\n\t\t}\n\n\t\tpublic static bool IsNullable(object obj)\n\t\t{\n\t\t\treturn obj is S?;\n\t\t}\n\n\t\tpublic static S? As(object obj)\n\t\t{\n\t\t\treturn obj as S?;\n\t\t}\n\n\t\tpublic static S OnlyChangeTheCopy(S p)\n\t\t{\n\t\t\tS s = p;\n\t\t\ts.SetField();\n\t\t\treturn p;\n\t\t}\n\n\t\tpublic static void UseRefBoolInCondition(ref bool x)\n\t\t{\n\t\t\tif (x)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"true\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static void CompareNotEqual0IsReallyNotEqual(IComparable<int> a)\n\t\t{\n\t\t\tif (a.CompareTo(0) != 0)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"true\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static void CompareEqual0IsReallyEqual(IComparable<int> a)\n\t\t{\n\t\t\tif (a.CompareTo(0) == 0)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"true\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static T Get<T>()\n\t\t{\n\t\t\treturn default(T);\n\t\t}\n\n\t\tpublic static void CallOnTemporary()\n\t\t{\n\t\t\t// Method can be called directly on temporaries\n\t\t\tGet<S>().MethodCalls();\n\n\t\t\t// Setting a property requires a temporary to avoid\n\t\t\t// CS1612 Cannot modify the return value of 'InitObj2()' because it is not a variable\n\t\t\tS s = Get<S>();\n\t\t\ts.Property = 1;\n\n#if CS72\n\t\t\tGet<R>().Method();\n\t\t\tR r = Get<R>();\n\t\t\tr.Property = 2;\n#endif\n\t\t}\n\n\t\tpublic static void CallOnFieldOfTemporary()\n\t\t{\n\t\t\tGet<S>().Field.ToString();\n\t\t}\n\n\t\tpublic static string CallOnIntegerConstant()\n\t\t{\n\t\t\treturn ulong.MaxValue.ToString();\n\t\t}\n\n\t\tpublic static void InliningDefaultValue()\n\t\t{\n\t\t\tTest(default(DateTime).GetType());\n\t\t\tTest(default(DateTime).ToString());\n\t\t}\n\n\t\tpublic static void Test(object x)\n\t\t{\n\t\t}\n\n#if CS120\n\t\tpublic static void AcceptIn(in S o)\n\t\t{\n\t\t}\n\n\t\tpublic static void AcceptRefReadOnly(ref readonly S o)\n\t\t{\n\t\t}\n\n\t\tprivate static void Use(in S param)\n\t\t{\n\t\t\tAcceptIn(new S(5));\n\t\t\tS o = new S(10);\n\t\t\tAcceptRefReadOnly(in o);\n\t\t\tAcceptIn(in param);\n\t\t\tAcceptRefReadOnly(in param);\n\t\t}\n#endif\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNaming.cs",
    "content": "#if !OPT\nusing System;\n#endif\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class VariableNaming\n\t{\n\t\tprivate enum MyEnum\n\t\t{\n\t\t\tVALUE1 = 1,\n\t\t\tVALUE2\n\t\t}\n\n\t\tprivate class C\n\t\t{\n\t\t\tpublic string Name;\n\t\t\tpublic string Text;\n\t\t}\n\n\t\tprivate void Test(string text, C c)\n\t\t{\n#if CS70\n\t\t\t_ = c.Name;\n#else\n\t\t\tstring name = c.Name;\n#endif\n\t\t}\n\n\t\tprivate void Test2(string text, C c)\n\t\t{\n#if CS70\n\t\t\t_ = c.Text;\n#else\n\t\t\tstring text2 = c.Text;\n#endif\n\t\t}\n\n#if !OPT\n\t\tprivate void Issue1841()\n\t\t{\n\t\t\tC gen1 = new C();\n\t\t\tC gen2 = new C();\n\t\t\tC gen3 = new C();\n\t\t\tC gen4 = new C();\n\t\t}\n\n\t\tprivate void Issue1881()\n\t\t{\n#pragma warning disable CS0219\n\t\t\tMyEnum enumLocal1 = MyEnum.VALUE1;\n\t\t\tMyEnum enumLocal2 = (MyEnum)0;\n\t\t\tenumLocal2 = MyEnum.VALUE1;\n\t\t\tobject enumLocal3 = MyEnum.VALUE2;\n\t\t\tobject enumLocal4 = new object();\n\t\t\tenumLocal4 = MyEnum.VALUE2;\n\t\t\tValueType enumLocal5 = MyEnum.VALUE1;\n\t\t\tValueType enumLocal6 = (MyEnum)0;\n\t\t\tenumLocal6 = MyEnum.VALUE2;\n#pragma warning restore CS0219\n\t\t}\n#endif\n\n\t\tprivate static void NestedForLoopTest(int sizeX, int sizeY, int[] array)\n\t\t{\n\t\t\tfor (int y = 0; y < sizeY; y++)\n\t\t\t{\n\t\t\t\tfor (int x = 0; x < sizeX; x++)\n\t\t\t\t{\n\t\t\t\t\tarray[y * sizeX + x] = 0;\n\t\t\t\t}\n\t\t\t}\n#if !EXPECTED_OUTPUT || (LEGACY_CSC && !OPT)\n\t\t\tfor (int y = 0; y < sizeY; y++)\n\t\t\t{\n\t\t\t\tfor (int x = 0; x < sizeX; x++)\n\t\t\t\t{\n\t\t\t\t\tarray[y * sizeX + x] = 1;\n\t\t\t\t}\n\t\t\t}\n#else\n\t\t\tfor (int i = 0; i < sizeY; i++)\n\t\t\t{\n\t\t\t\tfor (int j = 0; j < sizeX; j++)\n\t\t\t\t{\n\t\t\t\t\tarray[i * sizeX + j] = 1;\n\t\t\t\t}\n\t\t\t}\n#endif\n\t\t}\n\n\t\tprivate static void NestedForLoopTest2()\n\t\t{\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tNop(i);\n\t\t\t}\n#if EXPECTED_OUTPUT && !(LEGACY_CSC && !OPT)\n\t\t\tfor (int j = 0; j < 10; j++)\n\t\t\t{\n\t\t\t\tNop(j);\n\t\t\t}\n\n\t\t\tfor (int k = 0; k < 10; k++)\n\t\t\t{\n\t\t\t\tNop(k);\n\t\t\t}\n\n\t\t\tfor (int l = 0; l < 10; l++)\n\t\t\t{\n\t\t\t\tNop(l);\n\t\t\t}\n\n\t\t\tfor (int m = 0; m < 10; m++)\n\t\t\t{\n\t\t\t\tfor (int n = 0; n < 10; n++)\n\t\t\t\t{\n\t\t\t\t\tNop(n);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (int num = 0; num < 10; num++)\n\t\t\t{\n\t\t\t\tfor (int num2 = 0; num2 < 10; num2++)\n\t\t\t\t{\n\t\t\t\t\tNop(num2);\n\t\t\t\t}\n\t\t\t}\n#else\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tNop(i);\n\t\t\t}\n\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tNop(i);\n\t\t\t}\n\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tNop(i);\n\t\t\t}\n\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tfor (int j = 0; j < 10; j++)\n\t\t\t\t{\n\t\t\t\t\tNop(j);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (int i = 0; i < 10; i++)\n\t\t\t{\n\t\t\t\tfor (int j = 0; j < 10; j++)\n\t\t\t\t{\n\t\t\t\t\tNop(j);\n\t\t\t\t}\n\t\t\t}\n#endif\n\t\t}\n\n\t\tprivate static void Nop(int v)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNamingWithoutSymbols.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal class VariableNamingWithoutSymbols\n\t{\n\t\tprivate class C\n\t\t{\n\t\t\tpublic string Name;\n\t\t\tpublic string Text;\n\t\t}\n\n\t\tprivate void Test(string text, C c)\n\t\t{\n#if CS70\n\t\t\t_ = c.Name;\n#else\n\t\t\tstring name = c.Name;\n#endif\n\t\t}\n\n\t\tprivate void Test2(string text, C c)\n\t\t{\n#if CS70\n\t\t\t_ = c.Text;\n#else\n\t\t\tstring text2 = c.Text;\n#endif\n\t\t}\n\n\t\tprivate static IDisposable GetData()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tprivate static void UseData(IDisposable data)\n\t\t{\n\n\t\t}\n\n\t\tprivate static IEnumerable<int> GetItems()\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\n\t\tprivate static byte[] GetMemory()\n\t\t{\n\t\t\tthrow null;\n\t\t}\n\n\t\tprivate static void Test(int item)\n\t\t{\n\t\t\tforeach (int item2 in GetItems())\n\t\t\t{\n\t\t\t\tConsole.WriteLine(item2);\n\t\t\t}\n\t\t}\n\n\t\tprivate static void Test(IDisposable data)\n\t\t{\n#if CS80\n\t\t\tusing IDisposable data2 = GetData();\n\t\t\tUseData(data2);\n#else\n\t\t\tusing (IDisposable data2 = GetData())\n\t\t\t{\n\t\t\t\tUseData(data2);\n\t\t\t}\n#endif\n\t\t}\n\n\t\tprivate unsafe static void Test(byte[] memory)\n\t\t{\n\t\t\tfixed (byte* memory2 = GetMemory())\n\t\t\t{\n\t\t\t\tConsole.WriteLine(*memory2);\n\t\t\t}\n\t\t}\n\n\t\tprivate static void ForLoopNamingConflict(int i)\n\t\t{\n\t\t\tfor (int j = 0; j < i; j++)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(i + \" of \" + j);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/WellKnownConstants.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tpublic class WellKnownConstants\n\t{\n\t\tpublic const byte ByteMaxValue = byte.MaxValue;\n\t\tpublic const byte ByteMinValue = 0;\n\n\t\tpublic const sbyte SByteMaxValue = sbyte.MaxValue;\n\t\tpublic const sbyte SByteMinValue = sbyte.MinValue;\n\n\t\tpublic const ushort UShortMaxValue = ushort.MaxValue;\n\t\tpublic const ushort UShortMinValue = 0;\n\n\t\tpublic const short ShortMaxValue = short.MinValue;\n\t\tpublic const short ShortMinValue = short.MaxValue;\n\n\t\tpublic const uint UIntMaxValue = uint.MaxValue;\n\t\tpublic const uint UIntMinValue = 0u;\n\n\t\tpublic const int IntMaxValue = int.MaxValue;\n\t\tpublic const int IntMinValue = int.MinValue;\n\n\t\tpublic const ulong ULongMaxValue = ulong.MaxValue;\n\t\tpublic const ulong ULongMinValue = 0uL;\n\n\t\tpublic const long LongMaxValue = long.MaxValue;\n\t\tpublic const long LongMinValue = long.MinValue;\n\n\t\t// This constant is (1 / (double)long.MaxValue). Note that the (double) cast involves\n\t\t// loss of precision: long.MaxValue is rounded up to (long.MaxValue+1), which is a power of two.\n\t\t// The division then is exact, resulting in the double 0x3c00000000000000.\n\t\t// When trying to represent this as a fraction, we get (long.MaxValue+1) as divisor, which\n\t\t// does not fit type long, but compares equals to long.MaxValue due to the long->double conversion.\n\t\tpublic const double Double_One_Div_LongMaxValue = 1.0842021724855044E-19;\n\n\t\tpublic const float FloatZero = 0f;\n\t\tpublic const float FloatMinusZero = -0f;\n\t\tpublic const float FloatNaN = float.NaN;\n\t\tpublic const float FloatPositiveInfinity = float.PositiveInfinity;\n\t\tpublic const float FloatNegativeInfinity = float.NegativeInfinity;\n\t\tpublic const float FloatMaxValue = float.MaxValue;\n\t\tpublic const float FloatMinValue = float.MinValue;\n\t\tpublic const float FloatEpsilon = float.Epsilon;\n\n\t\tpublic const double DoubleZero = 0.0;\n\t\tpublic const double DoubleMinusZero = -0.0;\n\t\tpublic const double DoubleNaN = double.NaN;\n\t\tpublic const double DoublePositiveInfinity = double.PositiveInfinity;\n\t\tpublic const double DoubleNegativeInfinity = double.NegativeInfinity;\n\t\tpublic const double DoubleMaxValue = double.MaxValue;\n\t\tpublic const double DoubleMinValue = double.MinValue;\n\t\tpublic const double DoubleEpsilon = double.Epsilon;\n\n\t\tpublic const decimal DecimalMaxValue = decimal.MaxValue;\n\t\tpublic const decimal DecimalMinValue = decimal.MinValue;\n\n\t\tpublic const float Float_One = 1f;\n\t\tpublic const double Double_One = 1.0;\n\t\tpublic const float Float_Two = 2f;\n\t\tpublic const double Double_Two = 2.0;\n\t\tpublic const float Float_Sixth = 1f / 6f;\n\t\tpublic const double Double_Sixth = 1.0 / 6.0;\n\t\tpublic const float Float_Tenth = 0.1f;\n\t\tpublic const double Double_Tenth = 0.1;\n\n#if ROSLYN2 && !NET40\n\t\tpublic const float Float_PI = MathF.PI;\n\t\tpublic const float Float_HalfOfPI = MathF.PI / 2f;\n\t\tpublic const float Float_QuarterOfPI = MathF.PI / 4f;\n\t\tpublic const float Float_PITimes2 = MathF.PI * 2f;\n\t\tpublic const float Float_3QuartersOfPI = MathF.PI * 3f / 4f;\n\t\tpublic const float Float_PIDiv360 = MathF.PI / 360f;\n\t\tpublic const float Float_PIDiv16 = MathF.PI / 16f;\n\t\tpublic const float Float_PIDiv32 = MathF.PI / 32f;\n\t\tpublic const float Float_PIInverseFraction = 1f / MathF.PI;\n\t\tpublic const float Float_PIInverseFraction2 = 2f / MathF.PI;\n\t\tpublic const float Float_PIInverseFraction5 = 5f / MathF.PI;\n\t\tpublic const float Float_PITimes90 = MathF.PI * 90f;\n\t\tpublic const float Float_PITimes180 = MathF.PI * 180f;\n\t\tpublic const float Float_LooksLikePI = 3.1415925f;\n\t\tpublic const float Float_LooksLikePI2 = 3.14159f;\n\t\tpublic const float Float_LooksLikePI3 = 3.141f;\n\t\tpublic const float Float_BeforePI = 3.1415925f;\n\t\tpublic const float Float_AfterPI = 3.141593f;\n\t\tpublic const float Float_Negated_PI = -MathF.PI;\n\t\tpublic const float Float_Negated_HalfOfPI = -MathF.PI / 2f;\n\t\tpublic const float Float_Negated_QuarterOfPI = -MathF.PI / 4f;\n\t\tpublic const float Float_Negated_PITimes2 = MathF.PI * -2f;\n\t\tpublic const float Float_Negated_3QuartersOfPI = MathF.PI * -3f / 4f;\n\t\tpublic const float Float_Negated_PIDiv360 = -MathF.PI / 360f;\n\t\tpublic const float Float_Negated_PIDiv16 = -MathF.PI / 16f;\n\t\tpublic const float Float_Negated_PIDiv32 = -MathF.PI / 32f;\n\t\tpublic const float Float_Negated_PIInverseFraction = -1f / MathF.PI;\n\t\tpublic const float Float_Negated_PIInverseFraction2 = -2f / MathF.PI;\n\t\tpublic const float Float_Negated_PIInverseFraction5 = -5f / MathF.PI;\n\t\tpublic const float Float_Negated_PITimes90 = MathF.PI * -90f;\n\t\tpublic const float Float_Negated_PITimes180 = MathF.PI * -180f;\n\t\tpublic const float Float_Negated_LooksLikePI = -3.141f;\n\t\tpublic const float Float_Negated_BeforePI = -3.1415925f;\n\t\tpublic const float Float_Negated_AfterPI = -3.141593f;\n\n\t\tpublic const float Float_E = MathF.E;\n\t\tpublic const float Float_Negated_E = -MathF.E;\n#else\n\t\tpublic const float Float_PI = (float)Math.PI;\n\t\tpublic const float Float_HalfOfPI = (float)Math.PI / 2f;\n\t\tpublic const float Float_QuarterOfPI = (float)Math.PI / 4f;\n\t\tpublic const float Float_PITimes2 = (float)Math.PI * 2f;\n\t\tpublic const float Float_3QuartersOfPI = (float)Math.PI * 3f / 4f;\n\t\tpublic const float Float_PIDiv360 = (float)Math.PI / 360f;\n\t\tpublic const float Float_PIDiv16 = (float)Math.PI / 16f;\n\t\tpublic const float Float_PIDiv32 = (float)Math.PI / 32f;\n\t\tpublic const float Float_PIInverseFraction = 1f / (float)Math.PI;\n\t\tpublic const float Float_PIInverseFraction2 = 2f / (float)Math.PI;\n\t\tpublic const float Float_PIInverseFraction5 = 5f / (float)Math.PI;\n\t\tpublic const float Float_PITimes90 = (float)Math.PI * 90f;\n\t\tpublic const float Float_PITimes180 = (float)Math.PI * 180f;\n\t\tpublic const float Float_LooksLikePI = 3.1415925f;\n\t\tpublic const float Float_LooksLikePI2 = 3.14159f;\n\t\tpublic const float Float_LooksLikePI3 = 3.141f;\n\t\tpublic const float Float_BeforePI = 3.1415925f;\n\t\tpublic const float Float_AfterPI = 3.141593f;\n\t\tpublic const float Float_Negated_PI = -(float)Math.PI;\n\t\tpublic const float Float_Negated_HalfOfPI = -(float)Math.PI / 2f;\n\t\tpublic const float Float_Negated_QuarterOfPI = -(float)Math.PI / 4f;\n\t\tpublic const float Float_Negated_PITimes2 = (float)Math.PI * -2f;\n\t\tpublic const float Float_Negated_3QuartersOfPI = (float)Math.PI * -3f / 4f;\n\t\tpublic const float Float_Negated_PIDiv360 = -(float)Math.PI / 360f;\n\t\tpublic const float Float_Negated_PIDiv16 = -(float)Math.PI / 16f;\n\t\tpublic const float Float_Negated_PIDiv32 = -(float)Math.PI / 32f;\n\t\tpublic const float Float_Negated_PIInverseFraction = -1f / (float)Math.PI;\n\t\tpublic const float Float_Negated_PIInverseFraction2 = -2f / (float)Math.PI;\n\t\tpublic const float Float_Negated_PIInverseFraction5 = -5f / (float)Math.PI;\n\t\tpublic const float Float_Negated_PITimes90 = (float)Math.PI * -90f;\n\t\tpublic const float Float_Negated_PITimes180 = (float)Math.PI * -180f;\n\t\tpublic const float Float_Negated_LooksLikePI = -3.141f;\n\t\tpublic const float Float_Negated_BeforePI = -3.1415925f;\n\t\tpublic const float Float_Negated_AfterPI = -3.141593f;\n\n\t\tpublic const float Float_E = (float)Math.E;\n\t\tpublic const float Float_Negated_E = -(float)Math.E;\n#endif\n\n\t\tpublic const double Double_PI = Math.PI;\n\t\tpublic const double Double_HalfOfPI = Math.PI / 2.0;\n\t\tpublic const double Double_QuarterOfPI = Math.PI / 4.0;\n\t\tpublic const double Double_PITimes2 = Math.PI * 2.0;\n\t\tpublic const double Double_3QuartersOfPI = Math.PI * 3.0 / 4.0;\n\t\tpublic const double Double_PIDiv360 = Math.PI / 360.0;\n\t\tpublic const double Double_PIDiv16 = Math.PI / 16.0;\n\t\tpublic const double Double_PIDiv32 = Math.PI / 32.0;\n\t\tpublic const double Double_PIInverseFraction = 1.0 / Math.PI;\n\t\tpublic const double Double_PIInverseFraction2 = 2.0 / Math.PI;\n\t\tpublic const double Double_PIInverseFraction5 = 5.0 / Math.PI;\n\t\tpublic const double Double_PITimes90 = Math.PI * 90.0;\n\t\tpublic const double Double_PITimes180 = Math.PI * 180.0;\n\t\tpublic const double Double_LooksLikePI = 3.1415926;\n\t\tpublic const double Double_LooksLikePI2 = 3.14159;\n\t\tpublic const double Double_LooksLikePI3 = 3.141;\n\t\tpublic const double Double_BeforePI = 3.1415926535897927;\n\t\tpublic const double Double_AfterPI = 3.1415926535897936;\n\t\tpublic const double Double_Negated_PI = -Math.PI;\n\t\tpublic const double Double_Negated_HalfOfPI = -Math.PI / 2.0;\n\t\tpublic const double Double_Negated_QuarterOfPI = -Math.PI / 4.0;\n\t\tpublic const double Double_Negated_PITimes2 = Math.PI * -2.0;\n\t\tpublic const double Double_Negated_3QuartersOfPI = Math.PI * -3.0 / 4.0;\n\t\tpublic const double Double_Negated_PIDiv360 = -Math.PI / 360.0;\n\t\tpublic const double Double_Negated_PIDiv16 = -Math.PI / 16.0;\n\t\tpublic const double Double_Negated_PIDiv32 = -Math.PI / 32.0;\n\t\tpublic const double Double_Negated_PIInverseFraction = -1.0 / Math.PI;\n\t\tpublic const double Double_Negated_PIInverseFraction2 = -2.0 / Math.PI;\n\t\tpublic const double Double_Negated_PIInverseFraction5 = -5.0 / Math.PI;\n\t\tpublic const double Double_Negated_PITimes90 = Math.PI * -90.0;\n\t\tpublic const double Double_Negated_PITimes180 = Math.PI * -180.0;\n\t\tpublic const double Double_Negated_LooksLikePI = -3.141;\n\t\tpublic const double Double_Negated_BeforePI = -3.1415926535897927;\n\t\tpublic const double Double_Negated_AfterPI = -3.1415926535897936;\n\n\t\tpublic const double Double_E = Math.E;\n\t\tpublic const double Double_BeforeE = 2.7182818284590446;\n\t\tpublic const double Double_AfterE = 2.7182818284590455;\n\t\tpublic const double Double_Negated_E = -Math.E;\n\t\tpublic const double Double_Negated_BeforeE = -2.7182818284590446;\n\t\tpublic const double Double_Negated_AfterE = -2.7182818284590455;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Pretty/YieldReturn.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Pretty\n{\n\tinternal struct StructWithYieldReturn\n\t{\n\t\tprivate int val;\n\n\t\tpublic IEnumerable<int> Count()\n\t\t{\n\t\t\tyield return val++;\n\t\t\tyield return val++;\n\t\t}\n\t}\n\n\tpublic class YieldReturnPrettyTest\n\t{\n\t\tprivate int fieldOnThis;\n\n\t\tpublic static IEnumerable<char> YieldChars {\n\t\t\tget {\n\t\t\t\tyield return 'a';\n\t\t\t\tyield return 'b';\n\t\t\t\tyield return 'c';\n\t\t\t}\n\t\t}\n\n\t\tinternal static void Print<T>(string name, IEnumerator<T> enumerator)\n\t\t{\n\t\t\tConsole.WriteLine(name + \": Test start\");\n\t\t\twhile (enumerator.MoveNext())\n\t\t\t{\n\t\t\t\tConsole.WriteLine(name + \": \" + enumerator.Current);\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<string> SimpleYieldReturn()\n\t\t{\n\t\t\tyield return \"A\";\n\t\t\tyield return \"B\";\n\t\t\tyield return \"C\";\n\t\t}\n\n\t\tpublic static IEnumerator<string> SimpleYieldReturnEnumerator()\n\t\t{\n\t\t\tyield return \"A\";\n\t\t\tyield return \"B\";\n\t\t\tyield return \"C\";\n\t\t}\n\n\t\tpublic IEnumerable<int> YieldReturnParameters(int p)\n\t\t{\n\t\t\tyield return p;\n\t\t\tyield return fieldOnThis;\n\t\t}\n\n\t\tpublic IEnumerator<int> YieldReturnParametersEnumerator(int p)\n\t\t{\n\t\t\tyield return p;\n\t\t\tyield return fieldOnThis;\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldReturnInLoop()\n\t\t{\n\t\t\tfor (int i = 0; i < 100; i++)\n\t\t\t{\n\t\t\t\tyield return i;\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldReturnWithTryFinally()\n\t\t{\n\t\t\tyield return 0;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 1;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally!\");\n\t\t\t}\n\t\t\tyield return 2;\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldReturnInLock1(object o)\n\t\t{\n\t\t\tlock (o)\n\t\t\t{\n\t\t\t\tyield return 1;\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldReturnInLock2(object o)\n\t\t{\n\t\t\tlock (o)\n\t\t\t{\n\t\t\t\tyield return 1;\n\t\t\t\to = null;\n\t\t\t\tyield return 2;\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<string> YieldReturnWithNestedTryFinally(bool breakInMiddle)\n\t\t{\n\t\t\tConsole.WriteLine(\"Start of method - 1\");\n\t\t\tyield return \"Start of method\";\n\t\t\tConsole.WriteLine(\"Start of method - 2\");\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Within outer try - 1\");\n\t\t\t\tyield return \"Within outer try\";\n\t\t\t\tConsole.WriteLine(\"Within outer try - 2\");\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Within inner try - 1\");\n\t\t\t\t\tyield return \"Within inner try\";\n\t\t\t\t\tConsole.WriteLine(\"Within inner try - 2\");\n\t\t\t\t\tif (breakInMiddle)\n\t\t\t\t\t{\n\t\t\t\t\t\tConsole.WriteLine(\"Breaking...\");\n\t\t\t\t\t\tyield break;\n\t\t\t\t\t}\n\t\t\t\t\tConsole.WriteLine(\"End of inner try - 1\");\n\t\t\t\t\tyield return \"End of inner try\";\n\t\t\t\t\tConsole.WriteLine(\"End of inner try - 2\");\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Inner Finally\");\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(\"End of outer try - 1\");\n\t\t\t\tyield return \"End of outer try\";\n\t\t\t\tConsole.WriteLine(\"End of outer try - 2\");\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Outer Finally\");\n\t\t\t}\n\t\t\tConsole.WriteLine(\"End of method - 1\");\n\t\t\tyield return \"End of method\";\n\t\t\tConsole.WriteLine(\"End of method - 2\");\n\t\t}\n\n\t\tpublic static IEnumerable<string> YieldReturnWithTwoNonNestedFinallyBlocks(IEnumerable<string> input)\n\t\t{\n\t\t\t// outer try-finally block\n\t\t\tforeach (string line in input)\n\t\t\t{\n\t\t\t\t// nested try-finally block\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tyield return line;\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Processed \" + line);\n\t\t\t\t}\n\t\t\t}\n\t\t\tyield return \"A\";\n\t\t\tyield return \"B\";\n\t\t\tyield return \"C\";\n\t\t\tyield return \"D\";\n\t\t\tyield return \"E\";\n\t\t\tyield return \"F\";\n\t\t\t// outer try-finally block\n\t\t\tforeach (string item in input)\n\t\t\t{\n\t\t\t\tyield return item.ToUpper();\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<Func<string>> YieldReturnWithAnonymousMethods1(IEnumerable<string> input)\n\t\t{\n\t\t\tforeach (string line in input)\n\t\t\t{\n\t\t\t\tyield return () => line;\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<Func<string>> YieldReturnWithAnonymousMethods2(IEnumerable<string> input)\n\t\t{\n\t\t\tforeach (string item in input)\n\t\t\t{\n\t\t\t\tstring copy = item;\n\t\t\t\tyield return () => copy;\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> GetEvenNumbers(int n)\n\t\t{\n\t\t\tfor (int i = 0; i < n; i++)\n\t\t\t{\n\t\t\t\tif (i % 2 == 0)\n\t\t\t\t{\n\t\t\t\t\tyield return i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<char> ExceptionHandling()\n\t\t{\n\t\t\tyield return 'a';\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"1 - try\");\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"1 - catch\");\n\t\t\t}\n\t\t\tyield return 'b';\n\t\t\ttry\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"2 - try\");\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"2 - finally\");\n\t\t\t\t}\n\t\t\t\tyield return 'c';\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"outer finally\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldBreakInCatch()\n\t\t{\n\t\t\tyield return 0;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"In Try\");\n\t\t\t}\n\t\t\tcatch\n\t\t\t{\n\t\t\t\t// yield return is not allowed in catch, but yield break is\n\t\t\t\tyield break;\n\t\t\t}\n\t\t\tyield return 1;\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldBreakInCatchInTryFinally()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 0;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"In Try\");\n\t\t\t\t}\n\t\t\t\tcatch\n\t\t\t\t{\n\t\t\t\t\t// yield return is not allowed in catch, but yield break is\n\t\t\t\t\t// Note that pre-roslyn, this code triggers a compiler bug:\n\t\t\t\t\t// If the finally block throws an exception, it ends up getting\n\t\t\t\t\t// called a second time.\n\t\t\t\t\tyield break;\n\t\t\t\t}\n\t\t\t\tyield return 1;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldBreakInTryCatchInTryFinally()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 0;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"In Try\");\n\t\t\t\t\t// same compiler bug as in YieldBreakInCatchInTryFinally\n\t\t\t\t\tyield break;\n\t\t\t\t}\n\t\t\t\tcatch\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Catch\");\n\t\t\t\t}\n\t\t\t\tyield return 1;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldBreakInTryFinallyInTryFinally(bool b)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 0;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"In Try\");\n\t\t\t\t\tif (b)\n\t\t\t\t\t{\n\t\t\t\t\t\t// same compiler bug as in YieldBreakInCatchInTryFinally\n\t\t\t\t\t\tyield break;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Inner Finally\");\n\t\t\t\t}\n\t\t\t\tyield return 1;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldBreakOnly()\n\t\t{\n\t\t\tyield break;\n\t\t}\n\n\t\tpublic static IEnumerable<int> UnconditionalThrowInTryFinally()\n\t\t{\n\t\t\t// Here, MoveNext() doesn't call the finally methods at all\n\t\t\t// (only indirectly via Dispose())\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 0;\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> NestedTryFinallyStartingOnSamePosition()\n\t\t{\n\t\t\t// The first user IL instruction is already in 2 nested try blocks.\n\t\t\ttry\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tyield return 0;\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Inner Finally\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Outer Finally\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> LocalInFinally<T>(T a) where T : IDisposable\n\t\t{\n\t\t\tyield return 1;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 2;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tT val = a;\n\t\t\t\tval.Dispose();\n\t\t\t\tval.Dispose();\n\t\t\t}\n\t\t\tyield return 3;\n\t\t}\n\n\t\tpublic static IEnumerable<T> GenericYield<T>() where T : new()\n\t\t{\n\t\t\tT val = new T();\n\t\t\tfor (int i = 0; i < 3; i++)\n\t\t\t{\n\t\t\t\tyield return val;\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> MultipleYieldBreakInTryFinally(int i)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (i == 2)\n\t\t\t\t{\n\t\t\t\t\tyield break;\n\t\t\t\t}\n\n\t\t\t\twhile (i < 40)\n\t\t\t\t{\n\t\t\t\t\tif (i % 2 == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tyield break;\n\t\t\t\t\t}\n\t\t\t\t\ti++;\n\n\t\t\t\t\tyield return i;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"finally\");\n\t\t\t}\n\t\t\tConsole.WriteLine(\"normal exit\");\n\t\t}\n\n\t\tinternal IEnumerable<int> ForLoopWithYieldReturn(int end, int evil)\n\t\t{\n\t\t\t// This loop needs to pick the implicit \"yield break;\" as exit point\n\t\t\t// in order to produce pretty code; not the \"throw\" which would\n\t\t\t// be a less-pretty option.\n\t\t\tfor (int i = 0; i < end; i++)\n\t\t\t{\n\t\t\t\tif (i == evil)\n\t\t\t\t{\n\t\t\t\t\tthrow new InvalidOperationException(\"Found evil number\");\n\t\t\t\t}\n\t\t\t\tyield return i;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/.gitignore",
    "content": "/*.res\n/*.dll\n/*.exe\n/*.pdb\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/AggressiveScalarReplacementOfAggregates.Expected.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Ugly\n{\n\tpublic class DisplayClass\n\t{\n\t\tpublic Program thisField;\n\t\tpublic int field1;\n\t\tpublic string field2;\n\t}\n\n\tpublic class NestedDisplayClass\n\t{\n\t\tpublic DisplayClass field3;\n\t\tpublic int field1;\n\t\tpublic string field2;\n\t}\n\n\tpublic class Program\n\t{\n\t\tpublic int Rand()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\t\t\n\t\tpublic void Test1()\n\t\t{\n\t\t\tint field1 = 42;\n\t\t\tstring field2 = \"Hello World!\";\n\t\t\tConsole.WriteLine(\"{0} {1}\", field1, field2);\n\t\t}\n\t\t\n\t\tpublic void Test2()\n\t\t{\n\t\t\tDisplayClass displayClass = new DisplayClass {\n\t\t\t\tfield1 = 42,\n\t\t\t\tfield2 = \"Hello World!\"\n\t\t\t};\n\t\t\tConsole.WriteLine(\"{0} {1}\", displayClass.field1, displayClass.GetHashCode());\n\t\t}\n\n\t\tpublic void Test3()\n\t\t{\n\t\t\tDisplayClass displayClass = new DisplayClass {\n\t\t\t\tfield1 = 42,\n\t\t\t\tfield2 = \"Hello World!\"\n\t\t\t};\n\t\t\tConsole.WriteLine(\"{0} {1}\", displayClass.field1, displayClass);\n\t\t}\n\n\t\tpublic void Test4()\n\t\t{\n\t\t\tDisplayClass displayClass = new DisplayClass {\n\t\t\t\tthisField = this,\n\t\t\t\tfield1 = 42,\n\t\t\t\tfield2 = \"Hello World!\"\n\t\t\t};\n\t\t\tint field1 = 4711;\n\t\t\tstring field2 = \"ILSpy\";\n\t\t\tDisplayClass field3;\n\t\t\tif (displayClass.field1 > 100)\n\t\t\t{\n\t\t\t\tfield3 = displayClass;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfield3 = null;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"{0} {1}\", displayClass, field3);\n\t\t}\n\n\t\tpublic void Test5()\n\t\t{\n\t\t\tDisplayClass displayClass = new DisplayClass {\n\t\t\t\tthisField = this,\n\t\t\t\tfield1 = 42,\n\t\t\t\tfield2 = \"Hello World!\"\n\t\t\t};\n\t\t\tint field1 = 4711;\n\t\t\tstring field2 = \"ILSpy\";\n\t\t\tDisplayClass field3;\n\t\t\tif (displayClass.field1 > 100)\n\t\t\t{\n\t\t\t\tfield3 = displayClass;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfield3 = null;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"{0} {1}\", field2 + field1, field3);\n\t\t}\n\t\t\n\t\tpublic void Issue1898(int i)\n\t\t{\n\t\t\tDisplayClass displayClass = new DisplayClass {\n\t\t\t\tthisField = this,\n\t\t\t\tfield1 = i\n\t\t\t};\n\t\t\tint field5 = default(int);\n\t\t\tstring field4 = default(string);\n\t\t\tDisplayClass field3 = default(DisplayClass);\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tswitch (Rand())\n\t\t\t\t{\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tfield5 = Rand();\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tfield4 = Rand().ToString();\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\tfield3 = displayClass;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(field5);\n\t\t\t\tConsole.WriteLine(field4);\n\t\t\t\tConsole.WriteLine(field3);\n\t\t\t}\n\t\t}\n\n\t\tpublic void Test6(int i)\n\t\t{\n\t\t\tint field1 = i;\n\t\t\tstring field2 = \"Hello World!\";\n\t\t\tif (i < 0)\n\t\t\t{\n\t\t\t\ti = -i;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"{0} {1}\", field1, field2);\n\t\t}\n\n\t\tpublic void Test6b(int i)\n\t\t{\n\t\t\tint num = i;\n\t\t\tint field1 = num;\n\t\t\tstring field2 = \"Hello World!\";\n\t\t\tif (num < 0)\n\t\t\t{\n\t\t\t\tnum = -num;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"{0} {1}\", field1, field2);\n\t\t}\n\n\t\tpublic void Test7(int i)\n\t\t{\n\t\t\tint field1 = i;\n\t\t\tstring field2 = \"Hello World!\";\n\t\t\tConsole.WriteLine(\"{0} {1} {2}\", field1++, field2, i);\n\t\t}\n\n\t\tpublic void Test8(int i)\n\t\t{\n\t\t\tint field1 = i;\n\t\t\tstring field2 = \"Hello World!\";\n\t\t\ti = 42;\n\t\t\tConsole.WriteLine(\"{0} {1}\", field1, field2);\n\t\t}\n\n\t\tpublic void Test8b(int i)\n\t\t{\n\t\t\tint num = i;\n\t\t\tint field1 = num;\n\t\t\tstring field2 = \"Hello World!\";\n\t\t\tnum = 42;\n\t\t\tConsole.WriteLine(\"{0} {1}\", field1, field2);\n\t\t}\n\n//\t\tpublic void Test9()\n//\t\t{\n//\t\t\tProgram thisField = this;\n//\t\t\tint field1 = 1;\n//\t\t\tstring field2 = \"Hello World!\";\n//\t\t\tthisField = new Program();\n//\t\t\tConsole.WriteLine(\"{0} {1}\", this, thisField);\n//\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/AggressiveScalarReplacementOfAggregates.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Ugly\n{\n\tpublic class DisplayClass\n\t{\n\t\tpublic Program thisField;\n\t\tpublic int field1;\n\t\tpublic string field2;\n\t}\n\n\tpublic class NestedDisplayClass\n\t{\n\t\tpublic DisplayClass field3;\n\t\tpublic int field1;\n\t\tpublic string field2;\n\t}\n\n\tpublic class Program\n\t{\n\t\tpublic int Rand()\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\n\t\tpublic void Test1()\n\t\t{\n\t\t\tDisplayClass displayClass = new DisplayClass {\n\t\t\t\tfield1 = 42,\n\t\t\t\tfield2 = \"Hello World!\"\n\t\t\t};\n\t\t\tConsole.WriteLine(\"{0} {1}\", displayClass.field1, displayClass.field2);\n\t\t}\n\n\t\tpublic void Test2()\n\t\t{\n\t\t\tDisplayClass displayClass = new DisplayClass {\n\t\t\t\tfield1 = 42,\n\t\t\t\tfield2 = \"Hello World!\"\n\t\t\t};\n\t\t\tConsole.WriteLine(\"{0} {1}\", displayClass.field1, displayClass.GetHashCode());\n\t\t}\n\n\t\tpublic void Test3()\n\t\t{\n\t\t\tDisplayClass displayClass = new DisplayClass {\n\t\t\t\tfield1 = 42,\n\t\t\t\tfield2 = \"Hello World!\"\n\t\t\t};\n\t\t\tConsole.WriteLine(\"{0} {1}\", displayClass.field1, displayClass);\n\t\t}\n\n\t\tpublic void Test4()\n\t\t{\n\t\t\tDisplayClass displayClass = new DisplayClass {\n\t\t\t\tthisField = this,\n\t\t\t\tfield1 = 42,\n\t\t\t\tfield2 = \"Hello World!\"\n\t\t\t};\n\t\t\tNestedDisplayClass nested = new NestedDisplayClass {\n\t\t\t\tfield1 = 4711,\n\t\t\t\tfield2 = \"ILSpy\"\n\t\t\t};\n\t\t\tif (displayClass.field1 > 100)\n\t\t\t{\n\t\t\t\tnested.field3 = displayClass;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tnested.field3 = null;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"{0} {1}\", displayClass, nested.field3);\n\t\t}\n\n\t\tpublic void Test5()\n\t\t{\n\t\t\tDisplayClass displayClass = new DisplayClass {\n\t\t\t\tthisField = this,\n\t\t\t\tfield1 = 42,\n\t\t\t\tfield2 = \"Hello World!\"\n\t\t\t};\n\t\t\tNestedDisplayClass nested = new NestedDisplayClass {\n\t\t\t\tfield1 = 4711,\n\t\t\t\tfield2 = \"ILSpy\"\n\t\t\t};\n\t\t\tif (displayClass.field1 > 100)\n\t\t\t{\n\t\t\t\tnested.field3 = displayClass;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tnested.field3 = null;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"{0} {1}\", nested.field2 + nested.field1, nested.field3);\n\t\t}\n\n\t\tpublic void Issue1898(int i)\n\t\t{\n\t\t\tDisplayClass displayClass = new DisplayClass {\n\t\t\t\tthisField = this,\n\t\t\t\tfield1 = i\n\t\t\t};\n\t\t\tNestedDisplayClass nested = new NestedDisplayClass();\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tswitch (Rand())\n\t\t\t\t{\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tnested.field1 = Rand();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tnested.field2 = Rand().ToString();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\tnested.field3 = displayClass;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tConsole.WriteLine(nested.field1);\n\t\t\t\t\t\tConsole.WriteLine(nested.field2);\n\t\t\t\t\t\tConsole.WriteLine(nested.field3);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic void Test6(int i)\n\t\t{\n\t\t\tDisplayClass displayClass = new DisplayClass {\n\t\t\t\tfield1 = i,\n\t\t\t\tfield2 = \"Hello World!\"\n\t\t\t};\n\t\t\tif (i < 0)\n\t\t\t{\n\t\t\t\ti = -i;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"{0} {1}\", displayClass.field1, displayClass.field2);\n\t\t}\n\n\t\tpublic void Test6b(int i)\n\t\t{\n\t\t\tint num = i;\n\t\t\tDisplayClass displayClass = new DisplayClass {\n\t\t\t\tfield1 = num,\n\t\t\t\tfield2 = \"Hello World!\"\n\t\t\t};\n\t\t\tif (num < 0)\n\t\t\t{\n\t\t\t\tnum = -num;\n\t\t\t}\n\t\t\tConsole.WriteLine(\"{0} {1}\", displayClass.field1, displayClass.field2);\n\t\t}\n\n\t\tpublic void Test7(int i)\n\t\t{\n\t\t\tDisplayClass displayClass = new DisplayClass {\n\t\t\t\tfield1 = i,\n\t\t\t\tfield2 = \"Hello World!\"\n\t\t\t};\n\t\t\tConsole.WriteLine(\"{0} {1} {2}\", displayClass.field1++, displayClass.field2, i);\n\t\t}\n\n\t\tpublic void Test8(int i)\n\t\t{\n\t\t\tDisplayClass displayClass = new DisplayClass {\n\t\t\t\tfield1 = i,\n\t\t\t\tfield2 = \"Hello World!\"\n\t\t\t};\n\t\t\ti = 42;\n\t\t\tConsole.WriteLine(\"{0} {1}\", displayClass.field1, displayClass.field2);\n\t\t}\n\n\t\tpublic void Test8b(int i)\n\t\t{\n\t\t\tint num = i;\n\t\t\tDisplayClass displayClass = new DisplayClass {\n\t\t\t\tfield1 = num,\n\t\t\t\tfield2 = \"Hello World!\"\n\t\t\t};\n\t\t\tnum = 42;\n\t\t\tConsole.WriteLine(\"{0} {1}\", displayClass.field1, displayClass.field2);\n\t\t}\n\n\t\t//\t\tpublic void Test9()\n\t\t//\t\t{\n\t\t//\t\t\tDisplayClass displayClass = new DisplayClass {\n\t\t//\t\t\t\tthisField = this,\n\t\t//\t\t\t\tfield1 = 1,\n\t\t//\t\t\t\tfield2 = \"Hello World!\"\n\t\t//\t\t\t};\n\t\t//\t\t\tdisplayClass.thisField = new Program();\n\t\t//\t\t\tConsole.WriteLine(\"{0} {1}\", this, displayClass.thisField);\n\t\t//\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/AggressiveScalarReplacementOfAggregates.net40.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmp4B37\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmp4B37.tmp\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass\n       extends [mscorlib]System.Object\n{\n  .field public class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program thisField\n  .field public int32 field1\n  .field public string field2\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  nop\n    IL_0007:  ret\n  } // end of method DisplayClass::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass\n       extends [mscorlib]System.Object\n{\n  .field public class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass field3\n  .field public int32 field1\n  .field public string field2\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  nop\n    IL_0007:  ret\n  } // end of method NestedDisplayClass::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig instance int32 \n          Rand() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  nop\n    IL_0001:  newobj     instance void [mscorlib]System.NotImplementedException::.ctor()\n    IL_0006:  throw\n  } // end of method Program::Rand\n\n  .method public hidebysig instance void \n          Test1() cil managed\n  {\n    // Code size       55 (0x37)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0)\n    IL_0000:  nop\n    IL_0001:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0006:  dup\n    IL_0007:  ldc.i4.s   42\n    IL_0009:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000e:  dup\n    IL_000f:  ldstr      \"Hello World!\"\n    IL_0014:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0019:  stloc.0\n    IL_001a:  ldstr      \"{0} {1}\"\n    IL_001f:  ldloc.0\n    IL_0020:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0025:  box        [mscorlib]System.Int32\n    IL_002a:  ldloc.0\n    IL_002b:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0030:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0035:  nop\n    IL_0036:  ret\n  } // end of method Program::Test1\n\n  .method public hidebysig instance void \n          Test2() cil managed\n  {\n    // Code size       60 (0x3c)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0)\n    IL_0000:  nop\n    IL_0001:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0006:  dup\n    IL_0007:  ldc.i4.s   42\n    IL_0009:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000e:  dup\n    IL_000f:  ldstr      \"Hello World!\"\n    IL_0014:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0019:  stloc.0\n    IL_001a:  ldstr      \"{0} {1}\"\n    IL_001f:  ldloc.0\n    IL_0020:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0025:  box        [mscorlib]System.Int32\n    IL_002a:  ldloc.0\n    IL_002b:  callvirt   instance int32 [mscorlib]System.Object::GetHashCode()\n    IL_0030:  box        [mscorlib]System.Int32\n    IL_0035:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_003a:  nop\n    IL_003b:  ret\n  } // end of method Program::Test2\n\n  .method public hidebysig instance void \n          Test3() cil managed\n  {\n    // Code size       50 (0x32)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0)\n    IL_0000:  nop\n    IL_0001:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0006:  dup\n    IL_0007:  ldc.i4.s   42\n    IL_0009:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000e:  dup\n    IL_000f:  ldstr      \"Hello World!\"\n    IL_0014:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0019:  stloc.0\n    IL_001a:  ldstr      \"{0} {1}\"\n    IL_001f:  ldloc.0\n    IL_0020:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0025:  box        [mscorlib]System.Int32\n    IL_002a:  ldloc.0\n    IL_002b:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0030:  nop\n    IL_0031:  ret\n  } // end of method Program::Test3\n\n  .method public hidebysig instance void \n          Test4() cil managed\n  {\n    // Code size       114 (0x72)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass V_1,\n             bool V_2)\n    IL_0000:  nop\n    IL_0001:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0006:  dup\n    IL_0007:  ldarg.0\n    IL_0008:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::thisField\n    IL_000d:  dup\n    IL_000e:  ldc.i4.s   42\n    IL_0010:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0015:  dup\n    IL_0016:  ldstr      \"Hello World!\"\n    IL_001b:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0020:  stloc.0\n    IL_0021:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::.ctor()\n    IL_0026:  dup\n    IL_0027:  ldc.i4     0x1267\n    IL_002c:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_0031:  dup\n    IL_0032:  ldstr      \"ILSpy\"\n    IL_0037:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_003c:  stloc.1\n    IL_003d:  ldloc.0\n    IL_003e:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0043:  ldc.i4.s   100\n    IL_0045:  cgt\n    IL_0047:  stloc.2\n    IL_0048:  ldloc.2\n    IL_0049:  brfalse.s  IL_0056\n\n    IL_004b:  nop\n    IL_004c:  ldloc.1\n    IL_004d:  ldloc.0\n    IL_004e:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0053:  nop\n    IL_0054:  br.s       IL_005f\n\n    IL_0056:  nop\n    IL_0057:  ldloc.1\n    IL_0058:  ldnull\n    IL_0059:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_005e:  nop\n    IL_005f:  ldstr      \"{0} {1}\"\n    IL_0064:  ldloc.0\n    IL_0065:  ldloc.1\n    IL_0066:  ldfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_006b:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0070:  nop\n    IL_0071:  ret\n  } // end of method Program::Test4\n\n  .method public hidebysig instance void \n          Test5() cil managed\n  {\n    // Code size       135 (0x87)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass V_1,\n             bool V_2)\n    IL_0000:  nop\n    IL_0001:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0006:  dup\n    IL_0007:  ldarg.0\n    IL_0008:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::thisField\n    IL_000d:  dup\n    IL_000e:  ldc.i4.s   42\n    IL_0010:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0015:  dup\n    IL_0016:  ldstr      \"Hello World!\"\n    IL_001b:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0020:  stloc.0\n    IL_0021:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::.ctor()\n    IL_0026:  dup\n    IL_0027:  ldc.i4     0x1267\n    IL_002c:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_0031:  dup\n    IL_0032:  ldstr      \"ILSpy\"\n    IL_0037:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_003c:  stloc.1\n    IL_003d:  ldloc.0\n    IL_003e:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0043:  ldc.i4.s   100\n    IL_0045:  cgt\n    IL_0047:  stloc.2\n    IL_0048:  ldloc.2\n    IL_0049:  brfalse.s  IL_0056\n\n    IL_004b:  nop\n    IL_004c:  ldloc.1\n    IL_004d:  ldloc.0\n    IL_004e:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0053:  nop\n    IL_0054:  br.s       IL_005f\n\n    IL_0056:  nop\n    IL_0057:  ldloc.1\n    IL_0058:  ldnull\n    IL_0059:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_005e:  nop\n    IL_005f:  ldstr      \"{0} {1}\"\n    IL_0064:  ldloc.1\n    IL_0065:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_006a:  ldloc.1\n    IL_006b:  ldflda     int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_0070:  call       instance string [mscorlib]System.Int32::ToString()\n    IL_0075:  call       string [mscorlib]System.String::Concat(string,\n                                                                string)\n    IL_007a:  ldloc.1\n    IL_007b:  ldfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0080:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0085:  nop\n    IL_0086:  ret\n  } // end of method Program::Test5\n\n  .method public hidebysig instance void \n          Issue1898(int32 i) cil managed\n  {\n    // Code size       151 (0x97)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass V_1,\n             int32 V_2,\n             int32 V_3,\n             int32 V_4,\n             bool V_5)\n    IL_0000:  nop\n    IL_0001:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0006:  dup\n    IL_0007:  ldarg.0\n    IL_0008:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::thisField\n    IL_000d:  dup\n    IL_000e:  ldarg.1\n    IL_000f:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0014:  stloc.0\n    IL_0015:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::.ctor()\n    IL_001a:  stloc.1\n    IL_001b:  br.s       IL_0092\n\n    IL_001d:  nop\n    IL_001e:  ldarg.0\n    IL_001f:  call       instance int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program::Rand()\n    IL_0024:  stloc.3\n    IL_0025:  ldloc.3\n    IL_0026:  stloc.2\n    IL_0027:  ldloc.2\n    IL_0028:  ldc.i4.1\n    IL_0029:  sub\n    IL_002a:  switch     ( \n                          IL_003d,\n                          IL_004b,\n                          IL_0062)\n    IL_003b:  br.s       IL_006b\n\n    IL_003d:  ldloc.1\n    IL_003e:  ldarg.0\n    IL_003f:  call       instance int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program::Rand()\n    IL_0044:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_0049:  br.s       IL_0091\n\n    IL_004b:  ldloc.1\n    IL_004c:  ldarg.0\n    IL_004d:  call       instance int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program::Rand()\n    IL_0052:  stloc.s    V_4\n    IL_0054:  ldloca.s   V_4\n    IL_0056:  call       instance string [mscorlib]System.Int32::ToString()\n    IL_005b:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_0060:  br.s       IL_0091\n\n    IL_0062:  ldloc.1\n    IL_0063:  ldloc.0\n    IL_0064:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0069:  br.s       IL_0091\n\n    IL_006b:  ldloc.1\n    IL_006c:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_0071:  call       void [mscorlib]System.Console::WriteLine(int32)\n    IL_0076:  nop\n    IL_0077:  ldloc.1\n    IL_0078:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_007d:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0082:  nop\n    IL_0083:  ldloc.1\n    IL_0084:  ldfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0089:  call       void [mscorlib]System.Console::WriteLine(object)\n    IL_008e:  nop\n    IL_008f:  br.s       IL_0091\n\n    IL_0091:  nop\n    IL_0092:  ldc.i4.1\n    IL_0093:  stloc.s    V_5\n    IL_0095:  br.s       IL_001d\n  } // end of method Program::Issue1898\n\n  .method public hidebysig instance void \n          Test6(int32 i) cil managed\n  {\n    // Code size       68 (0x44)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0,\n             bool V_1)\n    IL_0000:  nop\n    IL_0001:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0006:  dup\n    IL_0007:  ldarg.1\n    IL_0008:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000d:  dup\n    IL_000e:  ldstr      \"Hello World!\"\n    IL_0013:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0018:  stloc.0\n    IL_0019:  ldarg.1\n    IL_001a:  ldc.i4.0\n    IL_001b:  clt\n    IL_001d:  stloc.1\n    IL_001e:  ldloc.1\n    IL_001f:  brfalse.s  IL_0027\n\n    IL_0021:  nop\n    IL_0022:  ldarg.1\n    IL_0023:  neg\n    IL_0024:  starg.s    i\n    IL_0026:  nop\n    IL_0027:  ldstr      \"{0} {1}\"\n    IL_002c:  ldloc.0\n    IL_002d:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0032:  box        [mscorlib]System.Int32\n    IL_0037:  ldloc.0\n    IL_0038:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_003d:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0042:  nop\n    IL_0043:  ret\n  } // end of method Program::Test6\n\n  .method public hidebysig instance void \n          Test6b(int32 i) cil managed\n  {\n    // Code size       69 (0x45)\n    .maxstack  3\n    .locals init (int32 V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_1,\n             bool V_2)\n    IL_0000:  nop\n    IL_0001:  ldarg.1\n    IL_0002:  stloc.0\n    IL_0003:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0008:  dup\n    IL_0009:  ldloc.0\n    IL_000a:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000f:  dup\n    IL_0010:  ldstr      \"Hello World!\"\n    IL_0015:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_001a:  stloc.1\n    IL_001b:  ldloc.0\n    IL_001c:  ldc.i4.0\n    IL_001d:  clt\n    IL_001f:  stloc.2\n    IL_0020:  ldloc.2\n    IL_0021:  brfalse.s  IL_0028\n\n    IL_0023:  nop\n    IL_0024:  ldloc.0\n    IL_0025:  neg\n    IL_0026:  stloc.0\n    IL_0027:  nop\n    IL_0028:  ldstr      \"{0} {1}\"\n    IL_002d:  ldloc.1\n    IL_002e:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0033:  box        [mscorlib]System.Int32\n    IL_0038:  ldloc.1\n    IL_0039:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_003e:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0043:  nop\n    IL_0044:  ret\n  } // end of method Program::Test6b\n\n  .method public hidebysig instance void \n          Test7(int32 i) cil managed\n  {\n    // Code size       71 (0x47)\n    .maxstack  4\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0,\n             int32 V_1)\n    IL_0000:  nop\n    IL_0001:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0006:  dup\n    IL_0007:  ldarg.1\n    IL_0008:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000d:  dup\n    IL_000e:  ldstr      \"Hello World!\"\n    IL_0013:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0018:  stloc.0\n    IL_0019:  ldstr      \"{0} {1} {2}\"\n    IL_001e:  ldloc.0\n    IL_001f:  dup\n    IL_0020:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0025:  stloc.1\n    IL_0026:  ldloc.1\n    IL_0027:  ldc.i4.1\n    IL_0028:  add\n    IL_0029:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_002e:  ldloc.1\n    IL_002f:  box        [mscorlib]System.Int32\n    IL_0034:  ldloc.0\n    IL_0035:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_003a:  ldarg.1\n    IL_003b:  box        [mscorlib]System.Int32\n    IL_0040:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object,\n                                                                  object)\n    IL_0045:  nop\n    IL_0046:  ret\n  } // end of method Program::Test7\n\n  .method public hidebysig instance void \n          Test8(int32 i) cil managed\n  {\n    // Code size       58 (0x3a)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0)\n    IL_0000:  nop\n    IL_0001:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0006:  dup\n    IL_0007:  ldarg.1\n    IL_0008:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000d:  dup\n    IL_000e:  ldstr      \"Hello World!\"\n    IL_0013:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0018:  stloc.0\n    IL_0019:  ldc.i4.s   42\n    IL_001b:  starg.s    i\n    IL_001d:  ldstr      \"{0} {1}\"\n    IL_0022:  ldloc.0\n    IL_0023:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0028:  box        [mscorlib]System.Int32\n    IL_002d:  ldloc.0\n    IL_002e:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0033:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0038:  nop\n    IL_0039:  ret\n  } // end of method Program::Test8\n\n  .method public hidebysig instance void \n          Test8b(int32 i) cil managed\n  {\n    // Code size       59 (0x3b)\n    .maxstack  3\n    .locals init (int32 V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_1)\n    IL_0000:  nop\n    IL_0001:  ldarg.1\n    IL_0002:  stloc.0\n    IL_0003:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0008:  dup\n    IL_0009:  ldloc.0\n    IL_000a:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000f:  dup\n    IL_0010:  ldstr      \"Hello World!\"\n    IL_0015:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_001a:  stloc.1\n    IL_001b:  ldc.i4.s   42\n    IL_001d:  stloc.0\n    IL_001e:  ldstr      \"{0} {1}\"\n    IL_0023:  ldloc.1\n    IL_0024:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0029:  box        [mscorlib]System.Int32\n    IL_002e:  ldloc.1\n    IL_002f:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0034:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0039:  nop\n    IL_003a:  ret\n  } // end of method Program::Test8b\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  nop\n    IL_0007:  ret\n  } // end of method Program::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/AggressiveScalarReplacementOfAggregates.opt.net40.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmp96F5\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmp96F5.tmp\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass\n       extends [mscorlib]System.Object\n{\n  .field public class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program thisField\n  .field public int32 field1\n  .field public string field2\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method DisplayClass::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass\n       extends [mscorlib]System.Object\n{\n  .field public class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass field3\n  .field public int32 field1\n  .field public string field2\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method NestedDisplayClass::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig instance int32 \n          Rand() cil managed\n  {\n    // Code size       6 (0x6)\n    .maxstack  8\n    IL_0000:  newobj     instance void [mscorlib]System.NotImplementedException::.ctor()\n    IL_0005:  throw\n  } // end of method Program::Rand\n\n  .method public hidebysig instance void \n          Test1() cil managed\n  {\n    // Code size       53 (0x35)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldc.i4.s   42\n    IL_0008:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000d:  dup\n    IL_000e:  ldstr      \"Hello World!\"\n    IL_0013:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0018:  stloc.0\n    IL_0019:  ldstr      \"{0} {1}\"\n    IL_001e:  ldloc.0\n    IL_001f:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0024:  box        [mscorlib]System.Int32\n    IL_0029:  ldloc.0\n    IL_002a:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_002f:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0034:  ret\n  } // end of method Program::Test1\n\n  .method public hidebysig instance void \n          Test2() cil managed\n  {\n    // Code size       58 (0x3a)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldc.i4.s   42\n    IL_0008:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000d:  dup\n    IL_000e:  ldstr      \"Hello World!\"\n    IL_0013:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0018:  stloc.0\n    IL_0019:  ldstr      \"{0} {1}\"\n    IL_001e:  ldloc.0\n    IL_001f:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0024:  box        [mscorlib]System.Int32\n    IL_0029:  ldloc.0\n    IL_002a:  callvirt   instance int32 [mscorlib]System.Object::GetHashCode()\n    IL_002f:  box        [mscorlib]System.Int32\n    IL_0034:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0039:  ret\n  } // end of method Program::Test2\n\n  .method public hidebysig instance void \n          Test3() cil managed\n  {\n    // Code size       48 (0x30)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldc.i4.s   42\n    IL_0008:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000d:  dup\n    IL_000e:  ldstr      \"Hello World!\"\n    IL_0013:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0018:  stloc.0\n    IL_0019:  ldstr      \"{0} {1}\"\n    IL_001e:  ldloc.0\n    IL_001f:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0024:  box        [mscorlib]System.Int32\n    IL_0029:  ldloc.0\n    IL_002a:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_002f:  ret\n  } // end of method Program::Test3\n\n  .method public hidebysig instance void \n          Test4() cil managed\n  {\n    // Code size       104 (0x68)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass V_1)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldarg.0\n    IL_0007:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::thisField\n    IL_000c:  dup\n    IL_000d:  ldc.i4.s   42\n    IL_000f:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0014:  dup\n    IL_0015:  ldstr      \"Hello World!\"\n    IL_001a:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_001f:  stloc.0\n    IL_0020:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::.ctor()\n    IL_0025:  dup\n    IL_0026:  ldc.i4     0x1267\n    IL_002b:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_0030:  dup\n    IL_0031:  ldstr      \"ILSpy\"\n    IL_0036:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_003b:  stloc.1\n    IL_003c:  ldloc.0\n    IL_003d:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0042:  ldc.i4.s   100\n    IL_0044:  ble.s      IL_004f\n\n    IL_0046:  ldloc.1\n    IL_0047:  ldloc.0\n    IL_0048:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_004d:  br.s       IL_0056\n\n    IL_004f:  ldloc.1\n    IL_0050:  ldnull\n    IL_0051:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0056:  ldstr      \"{0} {1}\"\n    IL_005b:  ldloc.0\n    IL_005c:  ldloc.1\n    IL_005d:  ldfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0062:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0067:  ret\n  } // end of method Program::Test4\n\n  .method public hidebysig instance void \n          Test5() cil managed\n  {\n    // Code size       125 (0x7d)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass V_1)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldarg.0\n    IL_0007:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::thisField\n    IL_000c:  dup\n    IL_000d:  ldc.i4.s   42\n    IL_000f:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0014:  dup\n    IL_0015:  ldstr      \"Hello World!\"\n    IL_001a:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_001f:  stloc.0\n    IL_0020:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::.ctor()\n    IL_0025:  dup\n    IL_0026:  ldc.i4     0x1267\n    IL_002b:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_0030:  dup\n    IL_0031:  ldstr      \"ILSpy\"\n    IL_0036:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_003b:  stloc.1\n    IL_003c:  ldloc.0\n    IL_003d:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0042:  ldc.i4.s   100\n    IL_0044:  ble.s      IL_004f\n\n    IL_0046:  ldloc.1\n    IL_0047:  ldloc.0\n    IL_0048:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_004d:  br.s       IL_0056\n\n    IL_004f:  ldloc.1\n    IL_0050:  ldnull\n    IL_0051:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0056:  ldstr      \"{0} {1}\"\n    IL_005b:  ldloc.1\n    IL_005c:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_0061:  ldloc.1\n    IL_0062:  ldflda     int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_0067:  call       instance string [mscorlib]System.Int32::ToString()\n    IL_006c:  call       string [mscorlib]System.String::Concat(string,\n                                                                string)\n    IL_0071:  ldloc.1\n    IL_0072:  ldfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0077:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_007c:  ret\n  } // end of method Program::Test5\n\n  .method public hidebysig instance void \n          Issue1898(int32 i) cil managed\n  {\n    // Code size       135 (0x87)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass V_1,\n             int32 V_2,\n             int32 V_3)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldarg.0\n    IL_0007:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::thisField\n    IL_000c:  dup\n    IL_000d:  ldarg.1\n    IL_000e:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0013:  stloc.0\n    IL_0014:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::.ctor()\n    IL_0019:  stloc.1\n    IL_001a:  ldarg.0\n    IL_001b:  call       instance int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program::Rand()\n    IL_0020:  stloc.2\n    IL_0021:  ldloc.2\n    IL_0022:  ldc.i4.1\n    IL_0023:  sub\n    IL_0024:  switch     ( \n                          IL_0037,\n                          IL_0045,\n                          IL_005b)\n    IL_0035:  br.s       IL_0064\n\n    IL_0037:  ldloc.1\n    IL_0038:  ldarg.0\n    IL_0039:  call       instance int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program::Rand()\n    IL_003e:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_0043:  br.s       IL_001a\n\n    IL_0045:  ldloc.1\n    IL_0046:  ldarg.0\n    IL_0047:  call       instance int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program::Rand()\n    IL_004c:  stloc.3\n    IL_004d:  ldloca.s   V_3\n    IL_004f:  call       instance string [mscorlib]System.Int32::ToString()\n    IL_0054:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_0059:  br.s       IL_001a\n\n    IL_005b:  ldloc.1\n    IL_005c:  ldloc.0\n    IL_005d:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0062:  br.s       IL_001a\n\n    IL_0064:  ldloc.1\n    IL_0065:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_006a:  call       void [mscorlib]System.Console::WriteLine(int32)\n    IL_006f:  ldloc.1\n    IL_0070:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_0075:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_007a:  ldloc.1\n    IL_007b:  ldfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0080:  call       void [mscorlib]System.Console::WriteLine(object)\n    IL_0085:  br.s       IL_001a\n  } // end of method Program::Issue1898\n\n  .method public hidebysig instance void \n          Test6(int32 i) cil managed\n  {\n    // Code size       60 (0x3c)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldarg.1\n    IL_0007:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000c:  dup\n    IL_000d:  ldstr      \"Hello World!\"\n    IL_0012:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0017:  stloc.0\n    IL_0018:  ldarg.1\n    IL_0019:  ldc.i4.0\n    IL_001a:  bge.s      IL_0020\n\n    IL_001c:  ldarg.1\n    IL_001d:  neg\n    IL_001e:  starg.s    i\n    IL_0020:  ldstr      \"{0} {1}\"\n    IL_0025:  ldloc.0\n    IL_0026:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_002b:  box        [mscorlib]System.Int32\n    IL_0030:  ldloc.0\n    IL_0031:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0036:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_003b:  ret\n  } // end of method Program::Test6\n\n  .method public hidebysig instance void \n          Test6b(int32 i) cil managed\n  {\n    // Code size       61 (0x3d)\n    .maxstack  3\n    .locals init (int32 V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_1)\n    IL_0000:  ldarg.1\n    IL_0001:  stloc.0\n    IL_0002:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0007:  dup\n    IL_0008:  ldloc.0\n    IL_0009:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000e:  dup\n    IL_000f:  ldstr      \"Hello World!\"\n    IL_0014:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0019:  stloc.1\n    IL_001a:  ldloc.0\n    IL_001b:  ldc.i4.0\n    IL_001c:  bge.s      IL_0021\n\n    IL_001e:  ldloc.0\n    IL_001f:  neg\n    IL_0020:  stloc.0\n    IL_0021:  ldstr      \"{0} {1}\"\n    IL_0026:  ldloc.1\n    IL_0027:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_002c:  box        [mscorlib]System.Int32\n    IL_0031:  ldloc.1\n    IL_0032:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0037:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_003c:  ret\n  } // end of method Program::Test6b\n\n  .method public hidebysig instance void \n          Test7(int32 i) cil managed\n  {\n    // Code size       69 (0x45)\n    .maxstack  4\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0,\n             int32 V_1)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldarg.1\n    IL_0007:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000c:  dup\n    IL_000d:  ldstr      \"Hello World!\"\n    IL_0012:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0017:  stloc.0\n    IL_0018:  ldstr      \"{0} {1} {2}\"\n    IL_001d:  ldloc.0\n    IL_001e:  dup\n    IL_001f:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0024:  stloc.1\n    IL_0025:  ldloc.1\n    IL_0026:  ldc.i4.1\n    IL_0027:  add\n    IL_0028:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_002d:  ldloc.1\n    IL_002e:  box        [mscorlib]System.Int32\n    IL_0033:  ldloc.0\n    IL_0034:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0039:  ldarg.1\n    IL_003a:  box        [mscorlib]System.Int32\n    IL_003f:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object,\n                                                                  object)\n    IL_0044:  ret\n  } // end of method Program::Test7\n\n  .method public hidebysig instance void \n          Test8(int32 i) cil managed\n  {\n    // Code size       56 (0x38)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldarg.1\n    IL_0007:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000c:  dup\n    IL_000d:  ldstr      \"Hello World!\"\n    IL_0012:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0017:  stloc.0\n    IL_0018:  ldc.i4.s   42\n    IL_001a:  starg.s    i\n    IL_001c:  ldstr      \"{0} {1}\"\n    IL_0021:  ldloc.0\n    IL_0022:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0027:  box        [mscorlib]System.Int32\n    IL_002c:  ldloc.0\n    IL_002d:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0032:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0037:  ret\n  } // end of method Program::Test8\n\n  .method public hidebysig instance void \n          Test8b(int32 i) cil managed\n  {\n    // Code size       57 (0x39)\n    .maxstack  3\n    .locals init (int32 V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_1)\n    IL_0000:  ldarg.1\n    IL_0001:  stloc.0\n    IL_0002:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0007:  dup\n    IL_0008:  ldloc.0\n    IL_0009:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000e:  dup\n    IL_000f:  ldstr      \"Hello World!\"\n    IL_0014:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0019:  stloc.1\n    IL_001a:  ldc.i4.s   42\n    IL_001c:  stloc.0\n    IL_001d:  ldstr      \"{0} {1}\"\n    IL_0022:  ldloc.1\n    IL_0023:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0028:  box        [mscorlib]System.Int32\n    IL_002d:  ldloc.1\n    IL_002e:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0033:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0038:  ret\n  } // end of method Program::Test8b\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method Program::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/AggressiveScalarReplacementOfAggregates.opt.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly AggressiveScalarReplacementOfAggregates\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module AggressiveScalarReplacementOfAggregates.dll\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass\n       extends [mscorlib]System.Object\n{\n  .field public class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program thisField\n  .field public int32 field1\n  .field public string field2\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method DisplayClass::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass\n       extends [mscorlib]System.Object\n{\n  .field public class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass field3\n  .field public int32 field1\n  .field public string field2\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method NestedDisplayClass::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig instance int32 \n          Rand() cil managed\n  {\n    // Code size       6 (0x6)\n    .maxstack  8\n    IL_0000:  newobj     instance void [mscorlib]System.NotImplementedException::.ctor()\n    IL_0005:  throw\n  } // end of method Program::Rand\n\n  .method public hidebysig instance void \n          Test1() cil managed\n  {\n    // Code size       53 (0x35)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldc.i4.s   42\n    IL_0008:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000d:  dup\n    IL_000e:  ldstr      \"Hello World!\"\n    IL_0013:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0018:  stloc.0\n    IL_0019:  ldstr      \"{0} {1}\"\n    IL_001e:  ldloc.0\n    IL_001f:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0024:  box        [mscorlib]System.Int32\n    IL_0029:  ldloc.0\n    IL_002a:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_002f:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0034:  ret\n  } // end of method Program::Test1\n\n  .method public hidebysig instance void \n          Test2() cil managed\n  {\n    // Code size       58 (0x3a)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldc.i4.s   42\n    IL_0008:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000d:  dup\n    IL_000e:  ldstr      \"Hello World!\"\n    IL_0013:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0018:  stloc.0\n    IL_0019:  ldstr      \"{0} {1}\"\n    IL_001e:  ldloc.0\n    IL_001f:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0024:  box        [mscorlib]System.Int32\n    IL_0029:  ldloc.0\n    IL_002a:  callvirt   instance int32 [mscorlib]System.Object::GetHashCode()\n    IL_002f:  box        [mscorlib]System.Int32\n    IL_0034:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0039:  ret\n  } // end of method Program::Test2\n\n  .method public hidebysig instance void \n          Test3() cil managed\n  {\n    // Code size       48 (0x30)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldc.i4.s   42\n    IL_0008:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000d:  dup\n    IL_000e:  ldstr      \"Hello World!\"\n    IL_0013:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0018:  stloc.0\n    IL_0019:  ldstr      \"{0} {1}\"\n    IL_001e:  ldloc.0\n    IL_001f:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0024:  box        [mscorlib]System.Int32\n    IL_0029:  ldloc.0\n    IL_002a:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_002f:  ret\n  } // end of method Program::Test3\n\n  .method public hidebysig instance void \n          Test4() cil managed\n  {\n    // Code size       104 (0x68)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass V_1)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldarg.0\n    IL_0007:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::thisField\n    IL_000c:  dup\n    IL_000d:  ldc.i4.s   42\n    IL_000f:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0014:  dup\n    IL_0015:  ldstr      \"Hello World!\"\n    IL_001a:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_001f:  stloc.0\n    IL_0020:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::.ctor()\n    IL_0025:  dup\n    IL_0026:  ldc.i4     0x1267\n    IL_002b:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_0030:  dup\n    IL_0031:  ldstr      \"ILSpy\"\n    IL_0036:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_003b:  stloc.1\n    IL_003c:  ldloc.0\n    IL_003d:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0042:  ldc.i4.s   100\n    IL_0044:  ble.s      IL_004f\n\n    IL_0046:  ldloc.1\n    IL_0047:  ldloc.0\n    IL_0048:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_004d:  br.s       IL_0056\n\n    IL_004f:  ldloc.1\n    IL_0050:  ldnull\n    IL_0051:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0056:  ldstr      \"{0} {1}\"\n    IL_005b:  ldloc.0\n    IL_005c:  ldloc.1\n    IL_005d:  ldfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0062:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0067:  ret\n  } // end of method Program::Test4\n\n  .method public hidebysig instance void \n          Test5() cil managed\n  {\n    // Code size       125 (0x7d)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass V_1)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldarg.0\n    IL_0007:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::thisField\n    IL_000c:  dup\n    IL_000d:  ldc.i4.s   42\n    IL_000f:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0014:  dup\n    IL_0015:  ldstr      \"Hello World!\"\n    IL_001a:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_001f:  stloc.0\n    IL_0020:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::.ctor()\n    IL_0025:  dup\n    IL_0026:  ldc.i4     0x1267\n    IL_002b:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_0030:  dup\n    IL_0031:  ldstr      \"ILSpy\"\n    IL_0036:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_003b:  stloc.1\n    IL_003c:  ldloc.0\n    IL_003d:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0042:  ldc.i4.s   100\n    IL_0044:  ble.s      IL_004f\n\n    IL_0046:  ldloc.1\n    IL_0047:  ldloc.0\n    IL_0048:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_004d:  br.s       IL_0056\n\n    IL_004f:  ldloc.1\n    IL_0050:  ldnull\n    IL_0051:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0056:  ldstr      \"{0} {1}\"\n    IL_005b:  ldloc.1\n    IL_005c:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_0061:  ldloc.1\n    IL_0062:  ldflda     int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_0067:  call       instance string [mscorlib]System.Int32::ToString()\n    IL_006c:  call       string [mscorlib]System.String::Concat(string,\n                                                                string)\n    IL_0071:  ldloc.1\n    IL_0072:  ldfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0077:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_007c:  ret\n  } // end of method Program::Test5\n\n  .method public hidebysig instance void \n          Issue1898(int32 i) cil managed\n  {\n    // Code size       135 (0x87)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass V_1,\n             int32 V_2,\n             int32 V_3)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldarg.0\n    IL_0007:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::thisField\n    IL_000c:  dup\n    IL_000d:  ldarg.1\n    IL_000e:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0013:  stloc.0\n    IL_0014:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::.ctor()\n    IL_0019:  stloc.1\n    IL_001a:  ldarg.0\n    IL_001b:  call       instance int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program::Rand()\n    IL_0020:  stloc.2\n    IL_0021:  ldloc.2\n    IL_0022:  ldc.i4.1\n    IL_0023:  sub\n    IL_0024:  switch     ( \n                          IL_0037,\n                          IL_0045,\n                          IL_005b)\n    IL_0035:  br.s       IL_0064\n\n    IL_0037:  ldloc.1\n    IL_0038:  ldarg.0\n    IL_0039:  call       instance int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program::Rand()\n    IL_003e:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_0043:  br.s       IL_001a\n\n    IL_0045:  ldloc.1\n    IL_0046:  ldarg.0\n    IL_0047:  call       instance int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program::Rand()\n    IL_004c:  stloc.3\n    IL_004d:  ldloca.s   V_3\n    IL_004f:  call       instance string [mscorlib]System.Int32::ToString()\n    IL_0054:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_0059:  br.s       IL_001a\n\n    IL_005b:  ldloc.1\n    IL_005c:  ldloc.0\n    IL_005d:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0062:  br.s       IL_001a\n\n    IL_0064:  ldloc.1\n    IL_0065:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_006a:  call       void [mscorlib]System.Console::WriteLine(int32)\n    IL_006f:  ldloc.1\n    IL_0070:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_0075:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_007a:  ldloc.1\n    IL_007b:  ldfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0080:  call       void [mscorlib]System.Console::WriteLine(object)\n    IL_0085:  br.s       IL_001a\n  } // end of method Program::Issue1898\n\n  .method public hidebysig instance void \n          Test6(int32 i) cil managed\n  {\n    // Code size       60 (0x3c)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldarg.1\n    IL_0007:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000c:  dup\n    IL_000d:  ldstr      \"Hello World!\"\n    IL_0012:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0017:  stloc.0\n    IL_0018:  ldarg.1\n    IL_0019:  ldc.i4.0\n    IL_001a:  bge.s      IL_0020\n\n    IL_001c:  ldarg.1\n    IL_001d:  neg\n    IL_001e:  starg.s    i\n    IL_0020:  ldstr      \"{0} {1}\"\n    IL_0025:  ldloc.0\n    IL_0026:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_002b:  box        [mscorlib]System.Int32\n    IL_0030:  ldloc.0\n    IL_0031:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0036:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_003b:  ret\n  } // end of method Program::Test6\n\n  .method public hidebysig instance void \n          Test6b(int32 i) cil managed\n  {\n    // Code size       61 (0x3d)\n    .maxstack  3\n    .locals init (int32 V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_1)\n    IL_0000:  ldarg.1\n    IL_0001:  stloc.0\n    IL_0002:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0007:  dup\n    IL_0008:  ldloc.0\n    IL_0009:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000e:  dup\n    IL_000f:  ldstr      \"Hello World!\"\n    IL_0014:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0019:  stloc.1\n    IL_001a:  ldloc.0\n    IL_001b:  ldc.i4.0\n    IL_001c:  bge.s      IL_0021\n\n    IL_001e:  ldloc.0\n    IL_001f:  neg\n    IL_0020:  stloc.0\n    IL_0021:  ldstr      \"{0} {1}\"\n    IL_0026:  ldloc.1\n    IL_0027:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_002c:  box        [mscorlib]System.Int32\n    IL_0031:  ldloc.1\n    IL_0032:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0037:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_003c:  ret\n  } // end of method Program::Test6b\n\n  .method public hidebysig instance void \n          Test7(int32 i) cil managed\n  {\n    // Code size       69 (0x45)\n    .maxstack  4\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0,\n             int32 V_1)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldarg.1\n    IL_0007:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000c:  dup\n    IL_000d:  ldstr      \"Hello World!\"\n    IL_0012:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0017:  stloc.0\n    IL_0018:  ldstr      \"{0} {1} {2}\"\n    IL_001d:  ldloc.0\n    IL_001e:  dup\n    IL_001f:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0024:  stloc.1\n    IL_0025:  ldloc.1\n    IL_0026:  ldc.i4.1\n    IL_0027:  add\n    IL_0028:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_002d:  ldloc.1\n    IL_002e:  box        [mscorlib]System.Int32\n    IL_0033:  ldloc.0\n    IL_0034:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0039:  ldarg.1\n    IL_003a:  box        [mscorlib]System.Int32\n    IL_003f:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object,\n                                                                  object)\n    IL_0044:  ret\n  } // end of method Program::Test7\n\n  .method public hidebysig instance void \n          Test8(int32 i) cil managed\n  {\n    // Code size       56 (0x38)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldarg.1\n    IL_0007:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000c:  dup\n    IL_000d:  ldstr      \"Hello World!\"\n    IL_0012:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0017:  stloc.0\n    IL_0018:  ldc.i4.s   42\n    IL_001a:  starg.s    i\n    IL_001c:  ldstr      \"{0} {1}\"\n    IL_0021:  ldloc.0\n    IL_0022:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0027:  box        [mscorlib]System.Int32\n    IL_002c:  ldloc.0\n    IL_002d:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0032:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0037:  ret\n  } // end of method Program::Test8\n\n  .method public hidebysig instance void \n          Test8b(int32 i) cil managed\n  {\n    // Code size       57 (0x39)\n    .maxstack  3\n    .locals init (int32 V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_1)\n    IL_0000:  ldarg.1\n    IL_0001:  stloc.0\n    IL_0002:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0007:  dup\n    IL_0008:  ldloc.0\n    IL_0009:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000e:  dup\n    IL_000f:  ldstr      \"Hello World!\"\n    IL_0014:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0019:  stloc.1\n    IL_001a:  ldc.i4.s   42\n    IL_001c:  stloc.0\n    IL_001d:  ldstr      \"{0} {1}\"\n    IL_0022:  ldloc.1\n    IL_0023:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0028:  box        [mscorlib]System.Int32\n    IL_002d:  ldloc.1\n    IL_002e:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0033:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0038:  ret\n  } // end of method Program::Test8b\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method Program::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/AggressiveScalarReplacementOfAggregates.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly AggressiveScalarReplacementOfAggregates\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module AggressiveScalarReplacementOfAggregates.dll\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass\n       extends [mscorlib]System.Object\n{\n  .field public class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program thisField\n  .field public int32 field1\n  .field public string field2\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  nop\n    IL_0007:  ret\n  } // end of method DisplayClass::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass\n       extends [mscorlib]System.Object\n{\n  .field public class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass field3\n  .field public int32 field1\n  .field public string field2\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  nop\n    IL_0007:  ret\n  } // end of method NestedDisplayClass::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig instance int32 \n          Rand() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  nop\n    IL_0001:  newobj     instance void [mscorlib]System.NotImplementedException::.ctor()\n    IL_0006:  throw\n  } // end of method Program::Rand\n\n  .method public hidebysig instance void \n          Test1() cil managed\n  {\n    // Code size       55 (0x37)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0)\n    IL_0000:  nop\n    IL_0001:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0006:  dup\n    IL_0007:  ldc.i4.s   42\n    IL_0009:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000e:  dup\n    IL_000f:  ldstr      \"Hello World!\"\n    IL_0014:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0019:  stloc.0\n    IL_001a:  ldstr      \"{0} {1}\"\n    IL_001f:  ldloc.0\n    IL_0020:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0025:  box        [mscorlib]System.Int32\n    IL_002a:  ldloc.0\n    IL_002b:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0030:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0035:  nop\n    IL_0036:  ret\n  } // end of method Program::Test1\n\n  .method public hidebysig instance void \n          Test2() cil managed\n  {\n    // Code size       60 (0x3c)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0)\n    IL_0000:  nop\n    IL_0001:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0006:  dup\n    IL_0007:  ldc.i4.s   42\n    IL_0009:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000e:  dup\n    IL_000f:  ldstr      \"Hello World!\"\n    IL_0014:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0019:  stloc.0\n    IL_001a:  ldstr      \"{0} {1}\"\n    IL_001f:  ldloc.0\n    IL_0020:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0025:  box        [mscorlib]System.Int32\n    IL_002a:  ldloc.0\n    IL_002b:  callvirt   instance int32 [mscorlib]System.Object::GetHashCode()\n    IL_0030:  box        [mscorlib]System.Int32\n    IL_0035:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_003a:  nop\n    IL_003b:  ret\n  } // end of method Program::Test2\n\n  .method public hidebysig instance void \n          Test3() cil managed\n  {\n    // Code size       50 (0x32)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0)\n    IL_0000:  nop\n    IL_0001:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0006:  dup\n    IL_0007:  ldc.i4.s   42\n    IL_0009:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000e:  dup\n    IL_000f:  ldstr      \"Hello World!\"\n    IL_0014:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0019:  stloc.0\n    IL_001a:  ldstr      \"{0} {1}\"\n    IL_001f:  ldloc.0\n    IL_0020:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0025:  box        [mscorlib]System.Int32\n    IL_002a:  ldloc.0\n    IL_002b:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0030:  nop\n    IL_0031:  ret\n  } // end of method Program::Test3\n\n  .method public hidebysig instance void \n          Test4() cil managed\n  {\n    // Code size       114 (0x72)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass V_1,\n             bool V_2)\n    IL_0000:  nop\n    IL_0001:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0006:  dup\n    IL_0007:  ldarg.0\n    IL_0008:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::thisField\n    IL_000d:  dup\n    IL_000e:  ldc.i4.s   42\n    IL_0010:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0015:  dup\n    IL_0016:  ldstr      \"Hello World!\"\n    IL_001b:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0020:  stloc.0\n    IL_0021:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::.ctor()\n    IL_0026:  dup\n    IL_0027:  ldc.i4     0x1267\n    IL_002c:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_0031:  dup\n    IL_0032:  ldstr      \"ILSpy\"\n    IL_0037:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_003c:  stloc.1\n    IL_003d:  ldloc.0\n    IL_003e:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0043:  ldc.i4.s   100\n    IL_0045:  cgt\n    IL_0047:  stloc.2\n    IL_0048:  ldloc.2\n    IL_0049:  brfalse.s  IL_0056\n\n    IL_004b:  nop\n    IL_004c:  ldloc.1\n    IL_004d:  ldloc.0\n    IL_004e:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0053:  nop\n    IL_0054:  br.s       IL_005f\n\n    IL_0056:  nop\n    IL_0057:  ldloc.1\n    IL_0058:  ldnull\n    IL_0059:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_005e:  nop\n    IL_005f:  ldstr      \"{0} {1}\"\n    IL_0064:  ldloc.0\n    IL_0065:  ldloc.1\n    IL_0066:  ldfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_006b:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0070:  nop\n    IL_0071:  ret\n  } // end of method Program::Test4\n\n  .method public hidebysig instance void \n          Test5() cil managed\n  {\n    // Code size       135 (0x87)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass V_1,\n             bool V_2)\n    IL_0000:  nop\n    IL_0001:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0006:  dup\n    IL_0007:  ldarg.0\n    IL_0008:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::thisField\n    IL_000d:  dup\n    IL_000e:  ldc.i4.s   42\n    IL_0010:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0015:  dup\n    IL_0016:  ldstr      \"Hello World!\"\n    IL_001b:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0020:  stloc.0\n    IL_0021:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::.ctor()\n    IL_0026:  dup\n    IL_0027:  ldc.i4     0x1267\n    IL_002c:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_0031:  dup\n    IL_0032:  ldstr      \"ILSpy\"\n    IL_0037:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_003c:  stloc.1\n    IL_003d:  ldloc.0\n    IL_003e:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0043:  ldc.i4.s   100\n    IL_0045:  cgt\n    IL_0047:  stloc.2\n    IL_0048:  ldloc.2\n    IL_0049:  brfalse.s  IL_0056\n\n    IL_004b:  nop\n    IL_004c:  ldloc.1\n    IL_004d:  ldloc.0\n    IL_004e:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0053:  nop\n    IL_0054:  br.s       IL_005f\n\n    IL_0056:  nop\n    IL_0057:  ldloc.1\n    IL_0058:  ldnull\n    IL_0059:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_005e:  nop\n    IL_005f:  ldstr      \"{0} {1}\"\n    IL_0064:  ldloc.1\n    IL_0065:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_006a:  ldloc.1\n    IL_006b:  ldflda     int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_0070:  call       instance string [mscorlib]System.Int32::ToString()\n    IL_0075:  call       string [mscorlib]System.String::Concat(string,\n                                                                string)\n    IL_007a:  ldloc.1\n    IL_007b:  ldfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0080:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0085:  nop\n    IL_0086:  ret\n  } // end of method Program::Test5\n\n  .method public hidebysig instance void \n          Issue1898(int32 i) cil managed\n  {\n    // Code size       151 (0x97)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass V_1,\n             int32 V_2,\n             int32 V_3,\n             int32 V_4,\n             bool V_5)\n    IL_0000:  nop\n    IL_0001:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0006:  dup\n    IL_0007:  ldarg.0\n    IL_0008:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::thisField\n    IL_000d:  dup\n    IL_000e:  ldarg.1\n    IL_000f:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0014:  stloc.0\n    IL_0015:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::.ctor()\n    IL_001a:  stloc.1\n    IL_001b:  br.s       IL_0092\n\n    IL_001d:  nop\n    IL_001e:  ldarg.0\n    IL_001f:  call       instance int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program::Rand()\n    IL_0024:  stloc.3\n    IL_0025:  ldloc.3\n    IL_0026:  stloc.2\n    IL_0027:  ldloc.2\n    IL_0028:  ldc.i4.1\n    IL_0029:  sub\n    IL_002a:  switch     ( \n                          IL_003d,\n                          IL_004b,\n                          IL_0062)\n    IL_003b:  br.s       IL_006b\n\n    IL_003d:  ldloc.1\n    IL_003e:  ldarg.0\n    IL_003f:  call       instance int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program::Rand()\n    IL_0044:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_0049:  br.s       IL_0091\n\n    IL_004b:  ldloc.1\n    IL_004c:  ldarg.0\n    IL_004d:  call       instance int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program::Rand()\n    IL_0052:  stloc.s    V_4\n    IL_0054:  ldloca.s   V_4\n    IL_0056:  call       instance string [mscorlib]System.Int32::ToString()\n    IL_005b:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_0060:  br.s       IL_0091\n\n    IL_0062:  ldloc.1\n    IL_0063:  ldloc.0\n    IL_0064:  stfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0069:  br.s       IL_0091\n\n    IL_006b:  ldloc.1\n    IL_006c:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field1\n    IL_0071:  call       void [mscorlib]System.Console::WriteLine(int32)\n    IL_0076:  nop\n    IL_0077:  ldloc.1\n    IL_0078:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field2\n    IL_007d:  call       void [mscorlib]System.Console::WriteLine(string)\n    IL_0082:  nop\n    IL_0083:  ldloc.1\n    IL_0084:  ldfld      class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass ICSharpCode.Decompiler.Tests.TestCases.Ugly.NestedDisplayClass::field3\n    IL_0089:  call       void [mscorlib]System.Console::WriteLine(object)\n    IL_008e:  nop\n    IL_008f:  br.s       IL_0091\n\n    IL_0091:  nop\n    IL_0092:  ldc.i4.1\n    IL_0093:  stloc.s    V_5\n    IL_0095:  br.s       IL_001d\n  } // end of method Program::Issue1898\n\n  .method public hidebysig instance void \n          Test6(int32 i) cil managed\n  {\n    // Code size       68 (0x44)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0,\n             bool V_1)\n    IL_0000:  nop\n    IL_0001:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0006:  dup\n    IL_0007:  ldarg.1\n    IL_0008:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000d:  dup\n    IL_000e:  ldstr      \"Hello World!\"\n    IL_0013:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0018:  stloc.0\n    IL_0019:  ldarg.1\n    IL_001a:  ldc.i4.0\n    IL_001b:  clt\n    IL_001d:  stloc.1\n    IL_001e:  ldloc.1\n    IL_001f:  brfalse.s  IL_0027\n\n    IL_0021:  nop\n    IL_0022:  ldarg.1\n    IL_0023:  neg\n    IL_0024:  starg.s    i\n    IL_0026:  nop\n    IL_0027:  ldstr      \"{0} {1}\"\n    IL_002c:  ldloc.0\n    IL_002d:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0032:  box        [mscorlib]System.Int32\n    IL_0037:  ldloc.0\n    IL_0038:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_003d:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0042:  nop\n    IL_0043:  ret\n  } // end of method Program::Test6\n\n  .method public hidebysig instance void \n          Test6b(int32 i) cil managed\n  {\n    // Code size       69 (0x45)\n    .maxstack  3\n    .locals init (int32 V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_1,\n             bool V_2)\n    IL_0000:  nop\n    IL_0001:  ldarg.1\n    IL_0002:  stloc.0\n    IL_0003:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0008:  dup\n    IL_0009:  ldloc.0\n    IL_000a:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000f:  dup\n    IL_0010:  ldstr      \"Hello World!\"\n    IL_0015:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_001a:  stloc.1\n    IL_001b:  ldloc.0\n    IL_001c:  ldc.i4.0\n    IL_001d:  clt\n    IL_001f:  stloc.2\n    IL_0020:  ldloc.2\n    IL_0021:  brfalse.s  IL_0028\n\n    IL_0023:  nop\n    IL_0024:  ldloc.0\n    IL_0025:  neg\n    IL_0026:  stloc.0\n    IL_0027:  nop\n    IL_0028:  ldstr      \"{0} {1}\"\n    IL_002d:  ldloc.1\n    IL_002e:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0033:  box        [mscorlib]System.Int32\n    IL_0038:  ldloc.1\n    IL_0039:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_003e:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0043:  nop\n    IL_0044:  ret\n  } // end of method Program::Test6b\n\n  .method public hidebysig instance void \n          Test7(int32 i) cil managed\n  {\n    // Code size       71 (0x47)\n    .maxstack  4\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0,\n             int32 V_1)\n    IL_0000:  nop\n    IL_0001:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0006:  dup\n    IL_0007:  ldarg.1\n    IL_0008:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000d:  dup\n    IL_000e:  ldstr      \"Hello World!\"\n    IL_0013:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0018:  stloc.0\n    IL_0019:  ldstr      \"{0} {1} {2}\"\n    IL_001e:  ldloc.0\n    IL_001f:  dup\n    IL_0020:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0025:  stloc.1\n    IL_0026:  ldloc.1\n    IL_0027:  ldc.i4.1\n    IL_0028:  add\n    IL_0029:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_002e:  ldloc.1\n    IL_002f:  box        [mscorlib]System.Int32\n    IL_0034:  ldloc.0\n    IL_0035:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_003a:  ldarg.1\n    IL_003b:  box        [mscorlib]System.Int32\n    IL_0040:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object,\n                                                                  object)\n    IL_0045:  nop\n    IL_0046:  ret\n  } // end of method Program::Test7\n\n  .method public hidebysig instance void \n          Test8(int32 i) cil managed\n  {\n    // Code size       58 (0x3a)\n    .maxstack  3\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_0)\n    IL_0000:  nop\n    IL_0001:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0006:  dup\n    IL_0007:  ldarg.1\n    IL_0008:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000d:  dup\n    IL_000e:  ldstr      \"Hello World!\"\n    IL_0013:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0018:  stloc.0\n    IL_0019:  ldc.i4.s   42\n    IL_001b:  starg.s    i\n    IL_001d:  ldstr      \"{0} {1}\"\n    IL_0022:  ldloc.0\n    IL_0023:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0028:  box        [mscorlib]System.Int32\n    IL_002d:  ldloc.0\n    IL_002e:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0033:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0038:  nop\n    IL_0039:  ret\n  } // end of method Program::Test8\n\n  .method public hidebysig instance void \n          Test8b(int32 i) cil managed\n  {\n    // Code size       59 (0x3b)\n    .maxstack  3\n    .locals init (int32 V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass V_1)\n    IL_0000:  nop\n    IL_0001:  ldarg.1\n    IL_0002:  stloc.0\n    IL_0003:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::.ctor()\n    IL_0008:  dup\n    IL_0009:  ldloc.0\n    IL_000a:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_000f:  dup\n    IL_0010:  ldstr      \"Hello World!\"\n    IL_0015:  stfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_001a:  stloc.1\n    IL_001b:  ldc.i4.s   42\n    IL_001d:  stloc.0\n    IL_001e:  ldstr      \"{0} {1}\"\n    IL_0023:  ldloc.1\n    IL_0024:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field1\n    IL_0029:  box        [mscorlib]System.Int32\n    IL_002e:  ldloc.1\n    IL_002f:  ldfld      string ICSharpCode.Decompiler.Tests.TestCases.Ugly.DisplayClass::field2\n    IL_0034:  call       void [mscorlib]System.Console::WriteLine(string,\n                                                                  object,\n                                                                  object)\n    IL_0039:  nop\n    IL_003a:  ret\n  } // end of method Program::Test8b\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  nop\n    IL_0007:  ret\n  } // end of method Program::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Program\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoArrayInitializers.Expected.cs",
    "content": "using System;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n[CompilerGenerated]\ninternal sealed class _003CPrivateImplementationDetails_003E\n{\n\t[StructLayout(LayoutKind.Explicit, Pack = 1, Size = 12)]\n\tprivate struct __StaticArrayInitTypeSize_003D12\n\t{\n\t}\n\tinternal static readonly __StaticArrayInitTypeSize_003D12 _4636993D3E1DA4E9D6B8F87B79E8F7C6D018580D52661950EABC3845C5897A4D/* Not supported: data(01 00 00 00 02 00 00 00 03 00 00 00) */;\n}\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Ugly\n{\n\tpublic class NoArrayInitializers\n\t{\n\t\tpublic int[] LiteralArray()\n\t\t{\n\t\t\tint[] array = new int[3];\n\t\t\tRuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);\n\t\t\treturn array;\n\t\t}\n\n\t\tpublic int[] VariableArray(int a, int b)\n\t\t{\n\t\t\tint[] array = new int[2];\n\t\t\tarray[0] = a;\n\t\t\tarray[1] = b;\n\t\t\treturn array;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoArrayInitializers.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Ugly\n{\n\tpublic class NoArrayInitializers\n\t{\n\t\tpublic int[] LiteralArray()\n\t\t{\n\t\t\treturn new[] { 1, 2, 3 };\n\t\t}\n\n\t\tpublic int[] VariableArray(int a, int b)\n\t\t{\n\t\t\treturn new[] { a, b };\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoArrayInitializers.net40.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmp9704\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmp9704.tmp\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoArrayInitializers\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig instance int32[] \n          LiteralArray() cil managed\n  {\n    // Code size       23 (0x17)\n    .maxstack  3\n    .locals init (int32[] V_0)\n    IL_0000:  nop\n    IL_0001:  ldc.i4.3\n    IL_0002:  newarr     [mscorlib]System.Int32\n    IL_0007:  dup\n    IL_0008:  ldtoken    field valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=12' '<PrivateImplementationDetails>'::'4636993D3E1DA4E9D6B8F87B79E8F7C6D018580D52661950EABC3845C5897A4D'\n    IL_000d:  call       void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array,\n                                                                                                        valuetype [mscorlib]System.RuntimeFieldHandle)\n    IL_0012:  stloc.0\n    IL_0013:  br.s       IL_0015\n\n    IL_0015:  ldloc.0\n    IL_0016:  ret\n  } // end of method NoArrayInitializers::LiteralArray\n\n  .method public hidebysig instance int32[] \n          VariableArray(int32 a,\n                        int32 b) cil managed\n  {\n    // Code size       20 (0x14)\n    .maxstack  4\n    .locals init (int32[] V_0)\n    IL_0000:  nop\n    IL_0001:  ldc.i4.2\n    IL_0002:  newarr     [mscorlib]System.Int32\n    IL_0007:  dup\n    IL_0008:  ldc.i4.0\n    IL_0009:  ldarg.1\n    IL_000a:  stelem.i4\n    IL_000b:  dup\n    IL_000c:  ldc.i4.1\n    IL_000d:  ldarg.2\n    IL_000e:  stelem.i4\n    IL_000f:  stloc.0\n    IL_0010:  br.s       IL_0012\n\n    IL_0012:  ldloc.0\n    IL_0013:  ret\n  } // end of method NoArrayInitializers::VariableArray\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  nop\n    IL_0007:  ret\n  } // end of method NoArrayInitializers::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoArrayInitializers\n\n.class private auto ansi sealed '<PrivateImplementationDetails>'\n       extends [mscorlib]System.Object\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n  .class explicit ansi sealed nested private '__StaticArrayInitTypeSize=12'\n         extends [mscorlib]System.ValueType\n  {\n    .pack 1\n    .size 12\n  } // end of class '__StaticArrayInitTypeSize=12'\n\n  .field static assembly initonly valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=12' '4636993D3E1DA4E9D6B8F87B79E8F7C6D018580D52661950EABC3845C5897A4D' at I_000026C0\n} // end of class '<PrivateImplementationDetails>'\n\n\n// =============================================================\n\n.data cil I_000026C0 = bytearray (\n                 01 00 00 00 02 00 00 00 03 00 00 00) \n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoArrayInitializers.opt.net40.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmp9705\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmp9705.tmp\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoArrayInitializers\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig instance int32[] \n          LiteralArray() cil managed\n  {\n    // Code size       18 (0x12)\n    .maxstack  8\n    IL_0000:  ldc.i4.3\n    IL_0001:  newarr     [mscorlib]System.Int32\n    IL_0006:  dup\n    IL_0007:  ldtoken    field valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=12' '<PrivateImplementationDetails>'::'4636993D3E1DA4E9D6B8F87B79E8F7C6D018580D52661950EABC3845C5897A4D'\n    IL_000c:  call       void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array,\n                                                                                                        valuetype [mscorlib]System.RuntimeFieldHandle)\n    IL_0011:  ret\n  } // end of method NoArrayInitializers::LiteralArray\n\n  .method public hidebysig instance int32[] \n          VariableArray(int32 a,\n                        int32 b) cil managed\n  {\n    // Code size       15 (0xf)\n    .maxstack  8\n    IL_0000:  ldc.i4.2\n    IL_0001:  newarr     [mscorlib]System.Int32\n    IL_0006:  dup\n    IL_0007:  ldc.i4.0\n    IL_0008:  ldarg.1\n    IL_0009:  stelem.i4\n    IL_000a:  dup\n    IL_000b:  ldc.i4.1\n    IL_000c:  ldarg.2\n    IL_000d:  stelem.i4\n    IL_000e:  ret\n  } // end of method NoArrayInitializers::VariableArray\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method NoArrayInitializers::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoArrayInitializers\n\n.class private auto ansi sealed '<PrivateImplementationDetails>'\n       extends [mscorlib]System.Object\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n  .class explicit ansi sealed nested private '__StaticArrayInitTypeSize=12'\n         extends [mscorlib]System.ValueType\n  {\n    .pack 1\n    .size 12\n  } // end of class '__StaticArrayInitTypeSize=12'\n\n  .field static assembly initonly valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=12' '4636993D3E1DA4E9D6B8F87B79E8F7C6D018580D52661950EABC3845C5897A4D' at I_00002690\n} // end of class '<PrivateImplementationDetails>'\n\n\n// =============================================================\n\n.data cil I_00002690 = bytearray (\n                 01 00 00 00 02 00 00 00 03 00 00 00) \n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoArrayInitializers.opt.roslyn.il",
    "content": "\n//  Microsoft (R) .NET Framework IL Disassembler.  Version 4.6.1055.0\n//  Copyright (c) Microsoft Corporation.  All rights reserved.\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly NoArrayInitializers\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module NoArrayInitializers.dll\n// MVID: {C6AD59A2-7245-425B-A6BB-29F93FAB1116}\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n// Image base: 0x00FD0000\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoArrayInitializers\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig instance int32[] \n          LiteralArray() cil managed\n  {\n    // Code size       18 (0x12)\n    .maxstack  8\n    IL_0000:  ldc.i4.3\n    IL_0001:  newarr     [mscorlib]System.Int32\n    IL_0006:  dup\n    IL_0007:  ldtoken    field valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=12' '<PrivateImplementationDetails>'::'4636993D3E1DA4E9D6B8F87B79E8F7C6D018580D52661950EABC3845C5897A4D'\n    IL_000c:  call       void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array,\n                                                                                                        valuetype [mscorlib]System.RuntimeFieldHandle)\n    IL_0011:  ret\n  } // end of method NoArrayInitializers::LiteralArray\n\n  .method public hidebysig instance int32[] \n          VariableArray(int32 a,\n                        int32 b) cil managed\n  {\n    // Code size       15 (0xf)\n    .maxstack  8\n    IL_0000:  ldc.i4.2\n    IL_0001:  newarr     [mscorlib]System.Int32\n    IL_0006:  dup\n    IL_0007:  ldc.i4.0\n    IL_0008:  ldarg.1\n    IL_0009:  stelem.i4\n    IL_000a:  dup\n    IL_000b:  ldc.i4.1\n    IL_000c:  ldarg.2\n    IL_000d:  stelem.i4\n    IL_000e:  ret\n  } // end of method NoArrayInitializers::VariableArray\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method NoArrayInitializers::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoArrayInitializers\n\n.class private auto ansi sealed '<PrivateImplementationDetails>'\n       extends [mscorlib]System.Object\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n  .class explicit ansi sealed nested private '__StaticArrayInitTypeSize=12'\n         extends [mscorlib]System.ValueType\n  {\n    .pack 1\n    .size 12\n  } // end of class '__StaticArrayInitTypeSize=12'\n\n  .field static assembly initonly valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=12' '4636993D3E1DA4E9D6B8F87B79E8F7C6D018580D52661950EABC3845C5897A4D' at I_00002690\n} // end of class '<PrivateImplementationDetails>'\n\n\n// =============================================================\n\n.data cil I_00002690 = bytearray (\n                 01 00 00 00 02 00 00 00 03 00 00 00) \n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoArrayInitializers.roslyn.il",
    "content": "\n//  Microsoft (R) .NET Framework IL Disassembler.  Version 4.6.1055.0\n//  Copyright (c) Microsoft Corporation.  All rights reserved.\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly NoArrayInitializers\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module NoArrayInitializers.dll\n// MVID: {C1B38171-55C8-4DDA-ACC8-78EFA1168D40}\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n// Image base: 0x03D10000\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoArrayInitializers\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig instance int32[] \n          LiteralArray() cil managed\n  {\n    // Code size       23 (0x17)\n    .maxstack  3\n    .locals init (int32[] V_0)\n    IL_0000:  nop\n    IL_0001:  ldc.i4.3\n    IL_0002:  newarr     [mscorlib]System.Int32\n    IL_0007:  dup\n    IL_0008:  ldtoken    field valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=12' '<PrivateImplementationDetails>'::'4636993D3E1DA4E9D6B8F87B79E8F7C6D018580D52661950EABC3845C5897A4D'\n    IL_000d:  call       void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array,\n                                                                                                        valuetype [mscorlib]System.RuntimeFieldHandle)\n    IL_0012:  stloc.0\n    IL_0013:  br.s       IL_0015\n\n    IL_0015:  ldloc.0\n    IL_0016:  ret\n  } // end of method NoArrayInitializers::LiteralArray\n\n  .method public hidebysig instance int32[] \n          VariableArray(int32 a,\n                        int32 b) cil managed\n  {\n    // Code size       20 (0x14)\n    .maxstack  4\n    .locals init (int32[] V_0)\n    IL_0000:  nop\n    IL_0001:  ldc.i4.2\n    IL_0002:  newarr     [mscorlib]System.Int32\n    IL_0007:  dup\n    IL_0008:  ldc.i4.0\n    IL_0009:  ldarg.1\n    IL_000a:  stelem.i4\n    IL_000b:  dup\n    IL_000c:  ldc.i4.1\n    IL_000d:  ldarg.2\n    IL_000e:  stelem.i4\n    IL_000f:  stloc.0\n    IL_0010:  br.s       IL_0012\n\n    IL_0012:  ldloc.0\n    IL_0013:  ret\n  } // end of method NoArrayInitializers::VariableArray\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  nop\n    IL_0007:  ret\n  } // end of method NoArrayInitializers::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoArrayInitializers\n\n.class private auto ansi sealed '<PrivateImplementationDetails>'\n       extends [mscorlib]System.Object\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n  .class explicit ansi sealed nested private '__StaticArrayInitTypeSize=12'\n         extends [mscorlib]System.ValueType\n  {\n    .pack 1\n    .size 12\n  } // end of class '__StaticArrayInitTypeSize=12'\n\n  .field static assembly initonly valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=12' '4636993D3E1DA4E9D6B8F87B79E8F7C6D018580D52661950EABC3845C5897A4D' at I_000026C0\n} // end of class '<PrivateImplementationDetails>'\n\n\n// =============================================================\n\n.data cil I_000026C0 = bytearray (\n                 01 00 00 00 02 00 00 00 03 00 00 00) \n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoDecimalConstants.Expected.cs",
    "content": "using System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Ugly\n{\n\tpublic class NoDecimalConstants\n\t{\n\t\t[DecimalConstant(1, 0, 0u, 0u, 10u)]\n\t\tprivate static readonly decimal constant = 1.0m;\n\t\tprivate void MethodWithOptionalParameter([Optional][DecimalConstant(1, 0, 0u, 0u, 10u)] decimal parameter)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoDecimalConstants.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Ugly\n{\n\tpublic class NoDecimalConstants\n\t{\n\t\tprivate const decimal constant = 1.0m;\n\n\t\tprivate void MethodWithOptionalParameter(decimal parameter = 1.0m)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoDecimalConstants.net40.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmpA278\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmpA278.tmp\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoDecimalConstants\n       extends [mscorlib]System.Object\n{\n  .field private static initonly valuetype [mscorlib]System.Decimal constant\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8,\n                                                                                                  uint8,\n                                                                                                  uint32,\n                                                                                                  uint32,\n                                                                                                  uint32) = ( 01 00 01 00 00 00 00 00 00 00 00 00 0A 00 00 00 \n                                                                                                              00 00 ) \n  .method private hidebysig instance void \n          MethodWithOptionalParameter([opt] valuetype [mscorlib]System.Decimal parameter) cil managed\n  {\n    .param [1]\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8,\n                                                                                                    uint8,\n                                                                                                    uint32,\n                                                                                                    uint32,\n                                                                                                    uint32) = ( 01 00 01 00 00 00 00 00 00 00 00 00 0A 00 00 00 \n                                                                                                                00 00 ) \n    // Code size       2 (0x2)\n    .maxstack  8\n    IL_0000:  nop\n    IL_0001:  ret\n  } // end of method NoDecimalConstants::MethodWithOptionalParameter\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  nop\n    IL_0007:  ret\n  } // end of method NoDecimalConstants::.ctor\n\n  .method private hidebysig specialname rtspecialname static \n          void  .cctor() cil managed\n  {\n    // Code size       17 (0x11)\n    .maxstack  8\n    IL_0000:  ldc.i4.s   10\n    IL_0002:  ldc.i4.0\n    IL_0003:  ldc.i4.0\n    IL_0004:  ldc.i4.0\n    IL_0005:  ldc.i4.1\n    IL_0006:  newobj     instance void [mscorlib]System.Decimal::.ctor(int32,\n                                                                       int32,\n                                                                       int32,\n                                                                       bool,\n                                                                       uint8)\n    IL_000b:  stsfld     valuetype [mscorlib]System.Decimal ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoDecimalConstants::constant\n    IL_0010:  ret\n  } // end of method NoDecimalConstants::.cctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoDecimalConstants\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoDecimalConstants.opt.net40.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmpA279\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmpA279.tmp\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoDecimalConstants\n       extends [mscorlib]System.Object\n{\n  .field private static initonly valuetype [mscorlib]System.Decimal constant\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8,\n                                                                                                  uint8,\n                                                                                                  uint32,\n                                                                                                  uint32,\n                                                                                                  uint32) = ( 01 00 01 00 00 00 00 00 00 00 00 00 0A 00 00 00 \n                                                                                                              00 00 ) \n  .method private hidebysig instance void \n          MethodWithOptionalParameter([opt] valuetype [mscorlib]System.Decimal parameter) cil managed\n  {\n    .param [1]\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8,\n                                                                                                    uint8,\n                                                                                                    uint32,\n                                                                                                    uint32,\n                                                                                                    uint32) = ( 01 00 01 00 00 00 00 00 00 00 00 00 0A 00 00 00 \n                                                                                                                00 00 ) \n    // Code size       1 (0x1)\n    .maxstack  8\n    IL_0000:  ret\n  } // end of method NoDecimalConstants::MethodWithOptionalParameter\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method NoDecimalConstants::.ctor\n\n  .method private hidebysig specialname rtspecialname static \n          void  .cctor() cil managed\n  {\n    // Code size       17 (0x11)\n    .maxstack  8\n    IL_0000:  ldc.i4.s   10\n    IL_0002:  ldc.i4.0\n    IL_0003:  ldc.i4.0\n    IL_0004:  ldc.i4.0\n    IL_0005:  ldc.i4.1\n    IL_0006:  newobj     instance void [mscorlib]System.Decimal::.ctor(int32,\n                                                                       int32,\n                                                                       int32,\n                                                                       bool,\n                                                                       uint8)\n    IL_000b:  stsfld     valuetype [mscorlib]System.Decimal ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoDecimalConstants::constant\n    IL_0010:  ret\n  } // end of method NoDecimalConstants::.cctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoDecimalConstants\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoDecimalConstants.opt.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly NoDecimalConstants\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module NoDecimalConstants.dll\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoDecimalConstants\n       extends [mscorlib]System.Object\n{\n  .field private static initonly valuetype [mscorlib]System.Decimal constant\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8,\n                                                                                                  uint8,\n                                                                                                  uint32,\n                                                                                                  uint32,\n                                                                                                  uint32) = ( 01 00 01 00 00 00 00 00 00 00 00 00 0A 00 00 00 \n                                                                                                              00 00 ) \n  .method private hidebysig instance void \n          MethodWithOptionalParameter([opt] valuetype [mscorlib]System.Decimal parameter) cil managed\n  {\n    .param [1]\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8,\n                                                                                                    uint8,\n                                                                                                    uint32,\n                                                                                                    uint32,\n                                                                                                    uint32) = ( 01 00 01 00 00 00 00 00 00 00 00 00 0A 00 00 00 \n                                                                                                                00 00 ) \n    // Code size       1 (0x1)\n    .maxstack  8\n    IL_0000:  ret\n  } // end of method NoDecimalConstants::MethodWithOptionalParameter\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method NoDecimalConstants::.ctor\n\n  .method private hidebysig specialname rtspecialname static \n          void  .cctor() cil managed\n  {\n    // Code size       17 (0x11)\n    .maxstack  8\n    IL_0000:  ldc.i4.s   10\n    IL_0002:  ldc.i4.0\n    IL_0003:  ldc.i4.0\n    IL_0004:  ldc.i4.0\n    IL_0005:  ldc.i4.1\n    IL_0006:  newobj     instance void [mscorlib]System.Decimal::.ctor(int32,\n                                                                       int32,\n                                                                       int32,\n                                                                       bool,\n                                                                       uint8)\n    IL_000b:  stsfld     valuetype [mscorlib]System.Decimal ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoDecimalConstants::constant\n    IL_0010:  ret\n  } // end of method NoDecimalConstants::.cctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoDecimalConstants\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoDecimalConstants.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly NoDecimalConstants\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module NoDecimalConstants.dll\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoDecimalConstants\n       extends [mscorlib]System.Object\n{\n  .field private static initonly valuetype [mscorlib]System.Decimal constant\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8,\n                                                                                                  uint8,\n                                                                                                  uint32,\n                                                                                                  uint32,\n                                                                                                  uint32) = ( 01 00 01 00 00 00 00 00 00 00 00 00 0A 00 00 00 \n                                                                                                              00 00 ) \n  .method private hidebysig instance void \n          MethodWithOptionalParameter([opt] valuetype [mscorlib]System.Decimal parameter) cil managed\n  {\n    .param [1]\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.DecimalConstantAttribute::.ctor(uint8,\n                                                                                                    uint8,\n                                                                                                    uint32,\n                                                                                                    uint32,\n                                                                                                    uint32) = ( 01 00 01 00 00 00 00 00 00 00 00 00 0A 00 00 00 \n                                                                                                                00 00 ) \n    // Code size       2 (0x2)\n    .maxstack  8\n    IL_0000:  nop\n    IL_0001:  ret\n  } // end of method NoDecimalConstants::MethodWithOptionalParameter\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  nop\n    IL_0007:  ret\n  } // end of method NoDecimalConstants::.ctor\n\n  .method private hidebysig specialname rtspecialname static \n          void  .cctor() cil managed\n  {\n    // Code size       17 (0x11)\n    .maxstack  8\n    IL_0000:  ldc.i4.s   10\n    IL_0002:  ldc.i4.0\n    IL_0003:  ldc.i4.0\n    IL_0004:  ldc.i4.0\n    IL_0005:  ldc.i4.1\n    IL_0006:  newobj     instance void [mscorlib]System.Decimal::.ctor(int32,\n                                                                       int32,\n                                                                       int32,\n                                                                       bool,\n                                                                       uint8)\n    IL_000b:  stsfld     valuetype [mscorlib]System.Decimal ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoDecimalConstants::constant\n    IL_0010:  ret\n  } // end of method NoDecimalConstants::.cctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoDecimalConstants\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoExtensionMethods.Expected.cs",
    "content": "using System;\nusing System.Runtime.CompilerServices;\n\n[assembly: Extension]\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Ugly\n{\n\t[Extension]\n\tinternal static class NoExtensionMethods\n\t{\n\t\t[Extension]\n\t\tinternal unsafe static Func<T> AsFunc<T>(T value) where T : class\n\t\t{\n\t\t\treturn new Func<T>(value, (nint)(delegate*<T, T>)(&Return));\n\t\t}\n\n\t\t[Extension]\n\t\tprivate static T Return<T>(T value)\n\t\t{\n\t\t\treturn value;\n\t\t}\n\n\t\tinternal static Func<int, int> ExtensionMethodAsStaticFunc()\n\t\t{\n\t\t\treturn Return;\n\t\t}\n\n\t\tinternal unsafe static Func<object> ExtensionMethodBoundToNull()\n\t\t{\n\t\t\treturn new Func<object>(null, (nint)(delegate*<object, object>)(&Return));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoExtensionMethods.cs",
    "content": "using System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Ugly\n{\n\tinternal static class NoExtensionMethods\n\t{\n\t\tinternal static Func<T> AsFunc<T>(this T value) where T : class\n\t\t{\n\t\t\treturn new Func<T>(value.Return);\n\t\t}\n\n\t\tprivate static T Return<T>(this T value)\n\t\t{\n\t\t\treturn value;\n\t\t}\n\n\t\tinternal static Func<int, int> ExtensionMethodAsStaticFunc()\n\t\t{\n\t\t\treturn Return;\n\t\t}\n\n\t\tinternal static Func<object> ExtensionMethodBoundToNull()\n\t\t{\n\t\t\treturn ((object)null).Return;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoExtensionMethods.net40.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmpA29B\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmpA29B.tmp\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private abstract auto ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods\n       extends [mscorlib]System.Object\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) \n  .method assembly hidebysig static class [mscorlib]System.Func`1<!!T> \n          AsFunc<class T>(!!T 'value') cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       23 (0x17)\n    .maxstack  2\n    .locals init (class [mscorlib]System.Func`1<!!T> V_0)\n    IL_0000:  nop\n    IL_0001:  ldarg.0\n    IL_0002:  box        !!T\n    IL_0007:  ldftn      !!0 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods::Return<!!0>(!!0)\n    IL_000d:  newobj     instance void class [mscorlib]System.Func`1<!!T>::.ctor(object,\n                                                                                 native int)\n    IL_0012:  stloc.0\n    IL_0013:  br.s       IL_0015\n\n    IL_0015:  ldloc.0\n    IL_0016:  ret\n  } // end of method NoExtensionMethods::AsFunc\n\n  .method private hidebysig static !!T  Return<T>(!!T 'value') cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       7 (0x7)\n    .maxstack  1\n    .locals init (!!T V_0)\n    IL_0000:  nop\n    IL_0001:  ldarg.0\n    IL_0002:  stloc.0\n    IL_0003:  br.s       IL_0005\n\n    IL_0005:  ldloc.0\n    IL_0006:  ret\n  } // end of method NoExtensionMethods::Return\n\n  .method assembly hidebysig static class [mscorlib]System.Func`2<int32,int32> \n          ExtensionMethodAsStaticFunc() cil managed\n  {\n    // Code size       18 (0x12)\n    .maxstack  2\n    .locals init (class [mscorlib]System.Func`2<int32,int32> V_0)\n    IL_0000:  nop\n    IL_0001:  ldnull\n    IL_0002:  ldftn      !!0 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods::Return<int32>(!!0)\n    IL_0008:  newobj     instance void class [mscorlib]System.Func`2<int32,int32>::.ctor(object,\n                                                                                         native int)\n    IL_000d:  stloc.0\n    IL_000e:  br.s       IL_0010\n\n    IL_0010:  ldloc.0\n    IL_0011:  ret\n  } // end of method NoExtensionMethods::ExtensionMethodAsStaticFunc\n\n  .method assembly hidebysig static class [mscorlib]System.Func`1<object> \n          ExtensionMethodBoundToNull() cil managed\n  {\n    // Code size       18 (0x12)\n    .maxstack  2\n    .locals init (class [mscorlib]System.Func`1<object> V_0)\n    IL_0000:  nop\n    IL_0001:  ldnull\n    IL_0002:  ldftn      !!0 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods::Return<object>(!!0)\n    IL_0008:  newobj     instance void class [mscorlib]System.Func`1<object>::.ctor(object,\n                                                                                    native int)\n    IL_000d:  stloc.0\n    IL_000e:  br.s       IL_0010\n\n    IL_0010:  ldloc.0\n    IL_0011:  ret\n  } // end of method NoExtensionMethods::ExtensionMethodBoundToNull\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoExtensionMethods.opt.net40.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmpA29A\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmpA29A.tmp\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private abstract auto ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods\n       extends [mscorlib]System.Object\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) \n  .method assembly hidebysig static class [mscorlib]System.Func`1<!!T> \n          AsFunc<class T>(!!T 'value') cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       18 (0x12)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  box        !!T\n    IL_0006:  ldftn      !!0 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods::Return<!!0>(!!0)\n    IL_000c:  newobj     instance void class [mscorlib]System.Func`1<!!T>::.ctor(object,\n                                                                                 native int)\n    IL_0011:  ret\n  } // end of method NoExtensionMethods::AsFunc\n\n  .method private hidebysig static !!T  Return<T>(!!T 'value') cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       2 (0x2)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  ret\n  } // end of method NoExtensionMethods::Return\n\n  .method assembly hidebysig static class [mscorlib]System.Func`2<int32,int32> \n          ExtensionMethodAsStaticFunc() cil managed\n  {\n    // Code size       13 (0xd)\n    .maxstack  8\n    IL_0000:  ldnull\n    IL_0001:  ldftn      !!0 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods::Return<int32>(!!0)\n    IL_0007:  newobj     instance void class [mscorlib]System.Func`2<int32,int32>::.ctor(object,\n                                                                                         native int)\n    IL_000c:  ret\n  } // end of method NoExtensionMethods::ExtensionMethodAsStaticFunc\n\n  .method assembly hidebysig static class [mscorlib]System.Func`1<object> \n          ExtensionMethodBoundToNull() cil managed\n  {\n    // Code size       13 (0xd)\n    .maxstack  8\n    IL_0000:  ldnull\n    IL_0001:  ldftn      !!0 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods::Return<object>(!!0)\n    IL_0007:  newobj     instance void class [mscorlib]System.Func`1<object>::.ctor(object,\n                                                                                    native int)\n    IL_000c:  ret\n  } // end of method NoExtensionMethods::ExtensionMethodBoundToNull\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoExtensionMethods.opt.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly NoExtensionMethods\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module NoExtensionMethods.dll\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private abstract auto ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods\n       extends [mscorlib]System.Object\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) \n  .method assembly hidebysig static class [mscorlib]System.Func`1<!!T> \n          AsFunc<class T>(!!T 'value') cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       18 (0x12)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  box        !!T\n    IL_0006:  ldftn      !!0 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods::Return<!!0>(!!0)\n    IL_000c:  newobj     instance void class [mscorlib]System.Func`1<!!T>::.ctor(object,\n                                                                                 native int)\n    IL_0011:  ret\n  } // end of method NoExtensionMethods::AsFunc\n\n  .method private hidebysig static !!T  Return<T>(!!T 'value') cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       2 (0x2)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  ret\n  } // end of method NoExtensionMethods::Return\n\n  .method assembly hidebysig static class [mscorlib]System.Func`2<int32,int32> \n          ExtensionMethodAsStaticFunc() cil managed\n  {\n    // Code size       13 (0xd)\n    .maxstack  8\n    IL_0000:  ldnull\n    IL_0001:  ldftn      !!0 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods::Return<int32>(!!0)\n    IL_0007:  newobj     instance void class [mscorlib]System.Func`2<int32,int32>::.ctor(object,\n                                                                                         native int)\n    IL_000c:  ret\n  } // end of method NoExtensionMethods::ExtensionMethodAsStaticFunc\n\n  .method assembly hidebysig static class [mscorlib]System.Func`1<object> \n          ExtensionMethodBoundToNull() cil managed\n  {\n    // Code size       13 (0xd)\n    .maxstack  8\n    IL_0000:  ldnull\n    IL_0001:  ldftn      !!0 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods::Return<object>(!!0)\n    IL_0007:  newobj     instance void class [mscorlib]System.Func`1<object>::.ctor(object,\n                                                                                    native int)\n    IL_000c:  ret\n  } // end of method NoExtensionMethods::ExtensionMethodBoundToNull\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoExtensionMethods.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly NoExtensionMethods\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module NoExtensionMethods.dll\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private abstract auto ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods\n       extends [mscorlib]System.Object\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) \n  .method assembly hidebysig static class [mscorlib]System.Func`1<!!T> \n          AsFunc<class T>(!!T 'value') cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       23 (0x17)\n    .maxstack  2\n    .locals init (class [mscorlib]System.Func`1<!!T> V_0)\n    IL_0000:  nop\n    IL_0001:  ldarg.0\n    IL_0002:  box        !!T\n    IL_0007:  ldftn      !!0 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods::Return<!!0>(!!0)\n    IL_000d:  newobj     instance void class [mscorlib]System.Func`1<!!T>::.ctor(object,\n                                                                                 native int)\n    IL_0012:  stloc.0\n    IL_0013:  br.s       IL_0015\n\n    IL_0015:  ldloc.0\n    IL_0016:  ret\n  } // end of method NoExtensionMethods::AsFunc\n\n  .method private hidebysig static !!T  Return<T>(!!T 'value') cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       7 (0x7)\n    .maxstack  1\n    .locals init (!!T V_0)\n    IL_0000:  nop\n    IL_0001:  ldarg.0\n    IL_0002:  stloc.0\n    IL_0003:  br.s       IL_0005\n\n    IL_0005:  ldloc.0\n    IL_0006:  ret\n  } // end of method NoExtensionMethods::Return\n\n  .method assembly hidebysig static class [mscorlib]System.Func`2<int32,int32> \n          ExtensionMethodAsStaticFunc() cil managed\n  {\n    // Code size       18 (0x12)\n    .maxstack  2\n    .locals init (class [mscorlib]System.Func`2<int32,int32> V_0)\n    IL_0000:  nop\n    IL_0001:  ldnull\n    IL_0002:  ldftn      !!0 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods::Return<int32>(!!0)\n    IL_0008:  newobj     instance void class [mscorlib]System.Func`2<int32,int32>::.ctor(object,\n                                                                                         native int)\n    IL_000d:  stloc.0\n    IL_000e:  br.s       IL_0010\n\n    IL_0010:  ldloc.0\n    IL_0011:  ret\n  } // end of method NoExtensionMethods::ExtensionMethodAsStaticFunc\n\n  .method assembly hidebysig static class [mscorlib]System.Func`1<object> \n          ExtensionMethodBoundToNull() cil managed\n  {\n    // Code size       18 (0x12)\n    .maxstack  2\n    .locals init (class [mscorlib]System.Func`1<object> V_0)\n    IL_0000:  nop\n    IL_0001:  ldnull\n    IL_0002:  ldftn      !!0 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods::Return<object>(!!0)\n    IL_0008:  newobj     instance void class [mscorlib]System.Func`1<object>::.ctor(object,\n                                                                                    native int)\n    IL_000d:  stloc.0\n    IL_000e:  br.s       IL_0010\n\n    IL_0010:  ldloc.0\n    IL_0011:  ret\n  } // end of method NoExtensionMethods::ExtensionMethodBoundToNull\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoExtensionMethods\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.Expected.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Ugly\n{\n\tinternal class NoForEachStatement\n\t{\n\t\tpublic static void SimpleNonGenericForeach(IEnumerable enumerable)\n\t\t{\n\t\t\tIEnumerator enumerator = enumerable.GetEnumerator();\n\t\t\ttry\n\t\t\t{\n\t\t\t\twhile (enumerator.MoveNext())\n\t\t\t\t{\n#if ROSLYN && OPT\n\t\t\t\t\tConsole.WriteLine(enumerator.Current);\n#else\n\t\t\t\t\tobject current = enumerator.Current;\n\t\t\t\t\tConsole.WriteLine(current);\n#endif\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tIDisposable disposable = enumerator as IDisposable;\n\t\t\t\tif (disposable != null)\n\t\t\t\t{ \n\t\t\t\t\tdisposable.Dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SimpleForeachOverInts(IEnumerable<int> enumerable)\n\t\t{\n\t\t\tusing (IEnumerator<int> enumerator = enumerable.GetEnumerator())\n\t\t\t{\n\t\t\t\twhile (enumerator.MoveNext())\n\t\t\t\t{\n#if ROSLYN && OPT\n\t\t\t\t\tConsole.WriteLine(enumerator.Current);\n#else\n\t\t\t\t\tint current = enumerator.Current;\n\t\t\t\t\tConsole.WriteLine(current);\n#endif\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Ugly\n{\n\tinternal class NoForEachStatement\n\t{\n\t\tpublic static void SimpleNonGenericForeach(IEnumerable enumerable)\n\t\t{\n\t\t\tforeach (object item in enumerable)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(item);\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SimpleForeachOverInts(IEnumerable<int> enumerable)\n\t\t{\n\t\t\tforeach (int item in enumerable)\n\t\t\t{\n\t\t\t\tConsole.WriteLine(item);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly rerff2f0\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module rerff2f0.dll\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig static void  SimpleNonGenericForeach(class [mscorlib]System.Collections.IEnumerable enumerable) cil managed\n  {\n    // Code size       64 (0x40)\n    .maxstack  2\n    .locals init (object V_0,\n             class [mscorlib]System.Collections.IEnumerator V_1,\n             bool V_2,\n             class [mscorlib]System.IDisposable V_3)\n    IL_0000:  nop\n    IL_0001:  nop\n    IL_0002:  ldarg.0\n    IL_0003:  callvirt   instance class [mscorlib]System.Collections.IEnumerator [mscorlib]System.Collections.IEnumerable::GetEnumerator()\n    IL_0008:  stloc.1\n    .try\n    {\n      IL_0009:  br.s       IL_001b\n\n      IL_000b:  ldloc.1\n      IL_000c:  callvirt   instance object [mscorlib]System.Collections.IEnumerator::get_Current()\n      IL_0011:  stloc.0\n      IL_0012:  nop\n      IL_0013:  ldloc.0\n      IL_0014:  call       void [mscorlib]System.Console::WriteLine(object)\n      IL_0019:  nop\n      IL_001a:  nop\n      IL_001b:  ldloc.1\n      IL_001c:  callvirt   instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()\n      IL_0021:  stloc.2\n      IL_0022:  ldloc.2\n      IL_0023:  brtrue.s   IL_000b\n\n      IL_0025:  leave.s    IL_003e\n\n    }  // end .try\n    finally\n    {\n      IL_0027:  ldloc.1\n      IL_0028:  isinst     [mscorlib]System.IDisposable\n      IL_002d:  stloc.3\n      IL_002e:  ldloc.3\n      IL_002f:  ldnull\n      IL_0030:  ceq\n      IL_0032:  stloc.2\n      IL_0033:  ldloc.2\n      IL_0034:  brtrue.s   IL_003d\n\n      IL_0036:  ldloc.3\n      IL_0037:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()\n      IL_003c:  nop\n      IL_003d:  endfinally\n    }  // end handler\n    IL_003e:  nop\n    IL_003f:  ret\n  } // end of method NoForEachStatement::SimpleNonGenericForeach\n\n  .method public hidebysig static void  SimpleForeachOverInts(class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> enumerable) cil managed\n  {\n    // Code size       57 (0x39)\n    .maxstack  2\n    .locals init (int32 V_0,\n             class [mscorlib]System.Collections.Generic.IEnumerator`1<int32> V_1,\n             bool V_2)\n    IL_0000:  nop\n    IL_0001:  nop\n    IL_0002:  ldarg.0\n    IL_0003:  callvirt   instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> class [mscorlib]System.Collections.Generic.IEnumerable`1<int32>::GetEnumerator()\n    IL_0008:  stloc.1\n    .try\n    {\n      IL_0009:  br.s       IL_001b\n\n      IL_000b:  ldloc.1\n      IL_000c:  callvirt   instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1<int32>::get_Current()\n      IL_0011:  stloc.0\n      IL_0012:  nop\n      IL_0013:  ldloc.0\n      IL_0014:  call       void [mscorlib]System.Console::WriteLine(int32)\n      IL_0019:  nop\n      IL_001a:  nop\n      IL_001b:  ldloc.1\n      IL_001c:  callvirt   instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()\n      IL_0021:  stloc.2\n      IL_0022:  ldloc.2\n      IL_0023:  brtrue.s   IL_000b\n\n      IL_0025:  leave.s    IL_0037\n\n    }  // end .try\n    finally\n    {\n      IL_0027:  ldloc.1\n      IL_0028:  ldnull\n      IL_0029:  ceq\n      IL_002b:  stloc.2\n      IL_002c:  ldloc.2\n      IL_002d:  brtrue.s   IL_0036\n\n      IL_002f:  ldloc.1\n      IL_0030:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()\n      IL_0035:  nop\n      IL_0036:  endfinally\n    }  // end handler\n    IL_0037:  nop\n    IL_0038:  ret\n  } // end of method NoForEachStatement::SimpleForeachOverInts\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method NoForEachStatement::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.net40.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmpA7E1\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmpA7E1.tmp\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig static void  SimpleNonGenericForeach(class [mscorlib]System.Collections.IEnumerable enumerable) cil managed\n  {\n    // Code size       56 (0x38)\n    .maxstack  1\n    .locals init (class [mscorlib]System.Collections.IEnumerator V_0,\n             object V_1,\n             class [mscorlib]System.IDisposable V_2)\n    IL_0000:  nop\n    IL_0001:  nop\n    IL_0002:  ldarg.0\n    IL_0003:  callvirt   instance class [mscorlib]System.Collections.IEnumerator [mscorlib]System.Collections.IEnumerable::GetEnumerator()\n    IL_0008:  stloc.0\n    .try\n    {\n      IL_0009:  br.s       IL_001b\n\n      IL_000b:  ldloc.0\n      IL_000c:  callvirt   instance object [mscorlib]System.Collections.IEnumerator::get_Current()\n      IL_0011:  stloc.1\n      IL_0012:  nop\n      IL_0013:  ldloc.1\n      IL_0014:  call       void [mscorlib]System.Console::WriteLine(object)\n      IL_0019:  nop\n      IL_001a:  nop\n      IL_001b:  ldloc.0\n      IL_001c:  callvirt   instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()\n      IL_0021:  brtrue.s   IL_000b\n\n      IL_0023:  leave.s    IL_0037\n\n    }  // end .try\n    finally\n    {\n      IL_0025:  ldloc.0\n      IL_0026:  isinst     [mscorlib]System.IDisposable\n      IL_002b:  stloc.2\n      IL_002c:  ldloc.2\n      IL_002d:  brfalse.s  IL_0036\n\n      IL_002f:  ldloc.2\n      IL_0030:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()\n      IL_0035:  nop\n      IL_0036:  endfinally\n    }  // end handler\n    IL_0037:  ret\n  } // end of method NoForEachStatement::SimpleNonGenericForeach\n\n  .method public hidebysig static void  SimpleForeachOverInts(class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> enumerable) cil managed\n  {\n    // Code size       49 (0x31)\n    .maxstack  1\n    .locals init (class [mscorlib]System.Collections.Generic.IEnumerator`1<int32> V_0,\n             int32 V_1)\n    IL_0000:  nop\n    IL_0001:  nop\n    IL_0002:  ldarg.0\n    IL_0003:  callvirt   instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> class [mscorlib]System.Collections.Generic.IEnumerable`1<int32>::GetEnumerator()\n    IL_0008:  stloc.0\n    .try\n    {\n      IL_0009:  br.s       IL_001b\n\n      IL_000b:  ldloc.0\n      IL_000c:  callvirt   instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1<int32>::get_Current()\n      IL_0011:  stloc.1\n      IL_0012:  nop\n      IL_0013:  ldloc.1\n      IL_0014:  call       void [mscorlib]System.Console::WriteLine(int32)\n      IL_0019:  nop\n      IL_001a:  nop\n      IL_001b:  ldloc.0\n      IL_001c:  callvirt   instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()\n      IL_0021:  brtrue.s   IL_000b\n\n      IL_0023:  leave.s    IL_0030\n\n    }  // end .try\n    finally\n    {\n      IL_0025:  ldloc.0\n      IL_0026:  brfalse.s  IL_002f\n\n      IL_0028:  ldloc.0\n      IL_0029:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()\n      IL_002e:  nop\n      IL_002f:  endfinally\n    }  // end handler\n    IL_0030:  ret\n  } // end of method NoForEachStatement::SimpleForeachOverInts\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  nop\n    IL_0007:  ret\n  } // end of method NoForEachStatement::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.opt.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly prqfqkbt\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module prqfqkbt.dll\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig static void  SimpleNonGenericForeach(class [mscorlib]System.Collections.IEnumerable enumerable) cil managed\n  {\n    // Code size       50 (0x32)\n    .maxstack  1\n    .locals init (object V_0,\n             class [mscorlib]System.Collections.IEnumerator V_1,\n             class [mscorlib]System.IDisposable V_2)\n    IL_0000:  ldarg.0\n    IL_0001:  callvirt   instance class [mscorlib]System.Collections.IEnumerator [mscorlib]System.Collections.IEnumerable::GetEnumerator()\n    IL_0006:  stloc.1\n    .try\n    {\n      IL_0007:  br.s       IL_0016\n\n      IL_0009:  ldloc.1\n      IL_000a:  callvirt   instance object [mscorlib]System.Collections.IEnumerator::get_Current()\n      IL_000f:  stloc.0\n      IL_0010:  ldloc.0\n      IL_0011:  call       void [mscorlib]System.Console::WriteLine(object)\n      IL_0016:  ldloc.1\n      IL_0017:  callvirt   instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()\n      IL_001c:  brtrue.s   IL_0009\n\n      IL_001e:  leave.s    IL_0031\n\n    }  // end .try\n    finally\n    {\n      IL_0020:  ldloc.1\n      IL_0021:  isinst     [mscorlib]System.IDisposable\n      IL_0026:  stloc.2\n      IL_0027:  ldloc.2\n      IL_0028:  brfalse.s  IL_0030\n\n      IL_002a:  ldloc.2\n      IL_002b:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()\n      IL_0030:  endfinally\n    }  // end handler\n    IL_0031:  ret\n  } // end of method NoForEachStatement::SimpleNonGenericForeach\n\n  .method public hidebysig static void  SimpleForeachOverInts(class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> enumerable) cil managed\n  {\n    // Code size       43 (0x2b)\n    .maxstack  1\n    .locals init (int32 V_0,\n             class [mscorlib]System.Collections.Generic.IEnumerator`1<int32> V_1)\n    IL_0000:  ldarg.0\n    IL_0001:  callvirt   instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> class [mscorlib]System.Collections.Generic.IEnumerable`1<int32>::GetEnumerator()\n    IL_0006:  stloc.1\n    .try\n    {\n      IL_0007:  br.s       IL_0016\n\n      IL_0009:  ldloc.1\n      IL_000a:  callvirt   instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1<int32>::get_Current()\n      IL_000f:  stloc.0\n      IL_0010:  ldloc.0\n      IL_0011:  call       void [mscorlib]System.Console::WriteLine(int32)\n      IL_0016:  ldloc.1\n      IL_0017:  callvirt   instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()\n      IL_001c:  brtrue.s   IL_0009\n\n      IL_001e:  leave.s    IL_002a\n\n    }  // end .try\n    finally\n    {\n      IL_0020:  ldloc.1\n      IL_0021:  brfalse.s  IL_0029\n\n      IL_0023:  ldloc.1\n      IL_0024:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()\n      IL_0029:  endfinally\n    }  // end handler\n    IL_002a:  ret\n  } // end of method NoForEachStatement::SimpleForeachOverInts\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method NoForEachStatement::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.opt.net40.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmpAA15\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmpAA15.tmp\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig static void  SimpleNonGenericForeach(class [mscorlib]System.Collections.IEnumerable enumerable) cil managed\n  {\n    // Code size       48 (0x30)\n    .maxstack  1\n    .locals init (class [mscorlib]System.Collections.IEnumerator V_0,\n             class [mscorlib]System.IDisposable V_1)\n    IL_0000:  ldarg.0\n    IL_0001:  callvirt   instance class [mscorlib]System.Collections.IEnumerator [mscorlib]System.Collections.IEnumerable::GetEnumerator()\n    IL_0006:  stloc.0\n    .try\n    {\n      IL_0007:  br.s       IL_0014\n\n      IL_0009:  ldloc.0\n      IL_000a:  callvirt   instance object [mscorlib]System.Collections.IEnumerator::get_Current()\n      IL_000f:  call       void [mscorlib]System.Console::WriteLine(object)\n      IL_0014:  ldloc.0\n      IL_0015:  callvirt   instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()\n      IL_001a:  brtrue.s   IL_0009\n\n      IL_001c:  leave.s    IL_002f\n\n    }  // end .try\n    finally\n    {\n      IL_001e:  ldloc.0\n      IL_001f:  isinst     [mscorlib]System.IDisposable\n      IL_0024:  stloc.1\n      IL_0025:  ldloc.1\n      IL_0026:  brfalse.s  IL_002e\n\n      IL_0028:  ldloc.1\n      IL_0029:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()\n      IL_002e:  endfinally\n    }  // end handler\n    IL_002f:  ret\n  } // end of method NoForEachStatement::SimpleNonGenericForeach\n\n  .method public hidebysig static void  SimpleForeachOverInts(class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> enumerable) cil managed\n  {\n    // Code size       41 (0x29)\n    .maxstack  1\n    .locals init (class [mscorlib]System.Collections.Generic.IEnumerator`1<int32> V_0)\n    IL_0000:  ldarg.0\n    IL_0001:  callvirt   instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> class [mscorlib]System.Collections.Generic.IEnumerable`1<int32>::GetEnumerator()\n    IL_0006:  stloc.0\n    .try\n    {\n      IL_0007:  br.s       IL_0014\n\n      IL_0009:  ldloc.0\n      IL_000a:  callvirt   instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1<int32>::get_Current()\n      IL_000f:  call       void [mscorlib]System.Console::WriteLine(int32)\n      IL_0014:  ldloc.0\n      IL_0015:  callvirt   instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()\n      IL_001a:  brtrue.s   IL_0009\n\n      IL_001c:  leave.s    IL_0028\n\n    }  // end .try\n    finally\n    {\n      IL_001e:  ldloc.0\n      IL_001f:  brfalse.s  IL_0027\n\n      IL_0021:  ldloc.0\n      IL_0022:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()\n      IL_0027:  endfinally\n    }  // end handler\n    IL_0028:  ret\n  } // end of method NoForEachStatement::SimpleForeachOverInts\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method NoForEachStatement::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.opt.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly NoForEachStatement\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module NoForEachStatement.dll\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig static void  SimpleNonGenericForeach(class [mscorlib]System.Collections.IEnumerable enumerable) cil managed\n  {\n    // Code size       48 (0x30)\n    .maxstack  1\n    .locals init (class [mscorlib]System.Collections.IEnumerator V_0,\n             class [mscorlib]System.IDisposable V_1)\n    IL_0000:  ldarg.0\n    IL_0001:  callvirt   instance class [mscorlib]System.Collections.IEnumerator [mscorlib]System.Collections.IEnumerable::GetEnumerator()\n    IL_0006:  stloc.0\n    .try\n    {\n      IL_0007:  br.s       IL_0014\n\n      IL_0009:  ldloc.0\n      IL_000a:  callvirt   instance object [mscorlib]System.Collections.IEnumerator::get_Current()\n      IL_000f:  call       void [mscorlib]System.Console::WriteLine(object)\n      IL_0014:  ldloc.0\n      IL_0015:  callvirt   instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()\n      IL_001a:  brtrue.s   IL_0009\n\n      IL_001c:  leave.s    IL_002f\n\n    }  // end .try\n    finally\n    {\n      IL_001e:  ldloc.0\n      IL_001f:  isinst     [mscorlib]System.IDisposable\n      IL_0024:  stloc.1\n      IL_0025:  ldloc.1\n      IL_0026:  brfalse.s  IL_002e\n\n      IL_0028:  ldloc.1\n      IL_0029:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()\n      IL_002e:  endfinally\n    }  // end handler\n    IL_002f:  ret\n  } // end of method NoForEachStatement::SimpleNonGenericForeach\n\n  .method public hidebysig static void  SimpleForeachOverInts(class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> enumerable) cil managed\n  {\n    // Code size       41 (0x29)\n    .maxstack  1\n    .locals init (class [mscorlib]System.Collections.Generic.IEnumerator`1<int32> V_0)\n    IL_0000:  ldarg.0\n    IL_0001:  callvirt   instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> class [mscorlib]System.Collections.Generic.IEnumerable`1<int32>::GetEnumerator()\n    IL_0006:  stloc.0\n    .try\n    {\n      IL_0007:  br.s       IL_0014\n\n      IL_0009:  ldloc.0\n      IL_000a:  callvirt   instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1<int32>::get_Current()\n      IL_000f:  call       void [mscorlib]System.Console::WriteLine(int32)\n      IL_0014:  ldloc.0\n      IL_0015:  callvirt   instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()\n      IL_001a:  brtrue.s   IL_0009\n\n      IL_001c:  leave.s    IL_0028\n\n    }  // end .try\n    finally\n    {\n      IL_001e:  ldloc.0\n      IL_001f:  brfalse.s  IL_0027\n\n      IL_0021:  ldloc.0\n      IL_0022:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()\n      IL_0027:  endfinally\n    }  // end handler\n    IL_0028:  ret\n  } // end of method NoForEachStatement::SimpleForeachOverInts\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method NoForEachStatement::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoForEachStatement.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly NoForEachStatement\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module NoForEachStatement.dll\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig static void  SimpleNonGenericForeach(class [mscorlib]System.Collections.IEnumerable enumerable) cil managed\n  {\n    // Code size       56 (0x38)\n    .maxstack  1\n    .locals init (class [mscorlib]System.Collections.IEnumerator V_0,\n             object V_1,\n             class [mscorlib]System.IDisposable V_2)\n    IL_0000:  nop\n    IL_0001:  nop\n    IL_0002:  ldarg.0\n    IL_0003:  callvirt   instance class [mscorlib]System.Collections.IEnumerator [mscorlib]System.Collections.IEnumerable::GetEnumerator()\n    IL_0008:  stloc.0\n    .try\n    {\n      IL_0009:  br.s       IL_001b\n\n      IL_000b:  ldloc.0\n      IL_000c:  callvirt   instance object [mscorlib]System.Collections.IEnumerator::get_Current()\n      IL_0011:  stloc.1\n      IL_0012:  nop\n      IL_0013:  ldloc.1\n      IL_0014:  call       void [mscorlib]System.Console::WriteLine(object)\n      IL_0019:  nop\n      IL_001a:  nop\n      IL_001b:  ldloc.0\n      IL_001c:  callvirt   instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()\n      IL_0021:  brtrue.s   IL_000b\n\n      IL_0023:  leave.s    IL_0037\n\n    }  // end .try\n    finally\n    {\n      IL_0025:  ldloc.0\n      IL_0026:  isinst     [mscorlib]System.IDisposable\n      IL_002b:  stloc.2\n      IL_002c:  ldloc.2\n      IL_002d:  brfalse.s  IL_0036\n\n      IL_002f:  ldloc.2\n      IL_0030:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()\n      IL_0035:  nop\n      IL_0036:  endfinally\n    }  // end handler\n    IL_0037:  ret\n  } // end of method NoForEachStatement::SimpleNonGenericForeach\n\n  .method public hidebysig static void  SimpleForeachOverInts(class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> enumerable) cil managed\n  {\n    // Code size       49 (0x31)\n    .maxstack  1\n    .locals init (class [mscorlib]System.Collections.Generic.IEnumerator`1<int32> V_0,\n             int32 V_1)\n    IL_0000:  nop\n    IL_0001:  nop\n    IL_0002:  ldarg.0\n    IL_0003:  callvirt   instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> class [mscorlib]System.Collections.Generic.IEnumerable`1<int32>::GetEnumerator()\n    IL_0008:  stloc.0\n    .try\n    {\n      IL_0009:  br.s       IL_001b\n\n      IL_000b:  ldloc.0\n      IL_000c:  callvirt   instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1<int32>::get_Current()\n      IL_0011:  stloc.1\n      IL_0012:  nop\n      IL_0013:  ldloc.1\n      IL_0014:  call       void [mscorlib]System.Console::WriteLine(int32)\n      IL_0019:  nop\n      IL_001a:  nop\n      IL_001b:  ldloc.0\n      IL_001c:  callvirt   instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()\n      IL_0021:  brtrue.s   IL_000b\n\n      IL_0023:  leave.s    IL_0030\n\n    }  // end .try\n    finally\n    {\n      IL_0025:  ldloc.0\n      IL_0026:  brfalse.s  IL_002f\n\n      IL_0028:  ldloc.0\n      IL_0029:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()\n      IL_002e:  nop\n      IL_002f:  endfinally\n    }  // end handler\n    IL_0030:  ret\n  } // end of method NoForEachStatement::SimpleForeachOverInts\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  nop\n    IL_0007:  ret\n  } // end of method NoForEachStatement::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoForEachStatement\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoLocalFunctions.Expected.cs",
    "content": "using System;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Ugly\n{\n\tpublic sealed class Handle\n\t{\n\t\tprivate readonly Func<int> _func;\n\t\tpublic Handle(Func<int> func)\n\t\t{\n\t\t\t_func = func;\n\t\t}\n\t}\n\n\tpublic static class NoLocalFunctions\n\t{\n\t\t[StructLayout(LayoutKind.Auto)]\n\t\t[CompilerGenerated]\n\t\tprivate struct _003C_003Ec__DisplayClass1_0\n\t\t{\n\t\t\tpublic int x;\n\t\t}\n\n\t\t[CompilerGenerated]\n\t\tprivate sealed class _003C_003Ec__DisplayClass2_0\n\t\t{\n\t\t\tpublic int x;\n\n\t\t\tinternal int _003CSimpleCaptureWithRef_003Eg__F_007C0()\n\t\t\t{\n\t\t\t\t\treturn 42 + x;\n\t\t\t}\n\t\t}\n\n\t\tprivate static void UseLocalFunctionReference()\n\t\t{\n#if OPT\n\t\t\tnew Handle(new Func<int>(_003CUseLocalFunctionReference_003Eg__F_007C0_0));\n#else\n\t\t\tHandle handle = new Handle(new Func<int>(_003CUseLocalFunctionReference_003Eg__F_007C0_0));\n#endif\n\t\t}\n\n\t\tprivate static void SimpleCapture()\n\t\t{\n\t\t\t_003C_003Ec__DisplayClass1_0 A_ = default(_003C_003Ec__DisplayClass1_0);\n\t\t\tA_.x = 1;\n\t\t\t_003CSimpleCapture_003Eg__F_007C1_0(ref A_);\n\t\t}\n\n\t\tprivate static void SimpleCaptureWithRef()\n\t\t{\n#if OPT\n\t\t\t_003C_003Ec__DisplayClass2_0 obj = new _003C_003Ec__DisplayClass2_0();\n\t\t\tobj.x = 1;\n\t\t\tnew Handle(new Func<int>(obj._003CSimpleCaptureWithRef_003Eg__F_007C0));\n#else\n\t\t\t_003C_003Ec__DisplayClass2_0 _003C_003Ec__DisplayClass2_1 = new _003C_003Ec__DisplayClass2_0();\n\t\t\t_003C_003Ec__DisplayClass2_1.x = 1;\n\t\t\tHandle handle = new Handle(new Func<int>(_003C_003Ec__DisplayClass2_1._003CSimpleCaptureWithRef_003Eg__F_007C0));\n#endif\n\t\t}\n\n\t\t[CompilerGenerated]\n\t\tinternal static int _003CUseLocalFunctionReference_003Eg__F_007C0_0()\n\t\t{\n\t\t\treturn 42;\n\t\t}\n\n\t\t[CompilerGenerated]\n\t\tprivate static int _003CSimpleCapture_003Eg__F_007C1_0(ref _003C_003Ec__DisplayClass1_0 A_0)\n\t\t{\n\t\t\treturn 42 + A_0.x;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoLocalFunctions.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Ugly\n{\n\tpublic sealed class Handle\n\t{\n\t\tprivate readonly Func<int> _func;\n\t\tpublic Handle(Func<int> func)\n\t\t{\n\t\t\t_func = func;\n\t\t}\n\t}\n\n\tpublic static class NoLocalFunctions\n\t{\n\t\tprivate static void UseLocalFunctionReference()\n\t\t{\n\t\t\tint F() => 42;\n\t\t\tvar handle = new Handle(F);\n\t\t}\n\t\tprivate static void SimpleCapture()\n\t\t{\n\t\t\tint x = 1;\n\t\t\tint F() => 42 + x;\n\t\t\tF();\n\t\t}\n\t\tprivate static void SimpleCaptureWithRef()\n\t\t{\n\t\t\tint x = 1;\n\t\t\tint F() => 42 + x;\n\t\t\tvar handle = new Handle(F);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoLocalFunctions.net40.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmpADF1\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmpADF1.tmp\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public auto ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle\n       extends [mscorlib]System.Object\n{\n  .field private initonly class [mscorlib]System.Func`1<int32> _func\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor(class [mscorlib]System.Func`1<int32> func) cil managed\n  {\n    // Code size       16 (0x10)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  nop\n    IL_0007:  nop\n    IL_0008:  ldarg.0\n    IL_0009:  ldarg.1\n    IL_000a:  stfld      class [mscorlib]System.Func`1<int32> ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle::_func\n    IL_000f:  ret\n  } // end of method Handle::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle\n\n.class public abstract auto ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions\n       extends [mscorlib]System.Object\n{\n  .class auto ansi sealed nested private beforefieldinit '<>c__DisplayClass1_0'\n         extends [mscorlib]System.ValueType\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    .field public int32 x\n  } // end of class '<>c__DisplayClass1_0'\n\n  .class auto ansi sealed nested private beforefieldinit '<>c__DisplayClass2_0'\n         extends [mscorlib]System.Object\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    .field public int32 x\n    .method public hidebysig specialname rtspecialname \n            instance void  .ctor() cil managed\n    {\n      // Code size       8 (0x8)\n      .maxstack  8\n      IL_0000:  ldarg.0\n      IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n      IL_0006:  nop\n      IL_0007:  ret\n    } // end of method '<>c__DisplayClass2_0'::.ctor\n\n    .method assembly hidebysig instance int32 \n            '<SimpleCaptureWithRef>g__F|0'() cil managed\n    {\n      // Code size       10 (0xa)\n      .maxstack  8\n      IL_0000:  ldc.i4.s   42\n      IL_0002:  ldarg.0\n      IL_0003:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass2_0'::x\n      IL_0008:  add\n      IL_0009:  ret\n    } // end of method '<>c__DisplayClass2_0'::'<SimpleCaptureWithRef>g__F|0'\n\n  } // end of class '<>c__DisplayClass2_0'\n\n  .method private hidebysig static void  UseLocalFunctionReference() cil managed\n  {\n    // Code size       21 (0x15)\n    .maxstack  2\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle V_0)\n    IL_0000:  nop\n    IL_0001:  nop\n    IL_0002:  ldnull\n    IL_0003:  ldftn      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions::'<UseLocalFunctionReference>g__F|0_0'()\n    IL_0009:  newobj     instance void class [mscorlib]System.Func`1<int32>::.ctor(object,\n                                                                                   native int)\n    IL_000e:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle::.ctor(class [mscorlib]System.Func`1<int32>)\n    IL_0013:  stloc.0\n    IL_0014:  ret\n  } // end of method NoLocalFunctions::UseLocalFunctionReference\n\n  .method private hidebysig static void  SimpleCapture() cil managed\n  {\n    // Code size       19 (0x13)\n    .maxstack  2\n    .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0' V_0)\n    IL_0000:  nop\n    IL_0001:  ldloca.s   V_0\n    IL_0003:  ldc.i4.1\n    IL_0004:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0'::x\n    IL_0009:  nop\n    IL_000a:  ldloca.s   V_0\n    IL_000c:  call       int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions::'<SimpleCapture>g__F|1_0'(valuetype ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0'&)\n    IL_0011:  pop\n    IL_0012:  ret\n  } // end of method NoLocalFunctions::SimpleCapture\n\n  .method private hidebysig static void  SimpleCaptureWithRef() cil managed\n  {\n    // Code size       34 (0x22)\n    .maxstack  2\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass2_0' V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle V_1)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass2_0'::.ctor()\n    IL_0005:  stloc.0\n    IL_0006:  nop\n    IL_0007:  ldloc.0\n    IL_0008:  ldc.i4.1\n    IL_0009:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass2_0'::x\n    IL_000e:  nop\n    IL_000f:  ldloc.0\n    IL_0010:  ldftn      instance int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass2_0'::'<SimpleCaptureWithRef>g__F|0'()\n    IL_0016:  newobj     instance void class [mscorlib]System.Func`1<int32>::.ctor(object,\n                                                                                   native int)\n    IL_001b:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle::.ctor(class [mscorlib]System.Func`1<int32>)\n    IL_0020:  stloc.1\n    IL_0021:  ret\n  } // end of method NoLocalFunctions::SimpleCaptureWithRef\n\n  .method assembly hidebysig static int32 \n          '<UseLocalFunctionReference>g__F|0_0'() cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       3 (0x3)\n    .maxstack  8\n    IL_0000:  ldc.i4.s   42\n    IL_0002:  ret\n  } // end of method NoLocalFunctions::'<UseLocalFunctionReference>g__F|0_0'\n\n  .method assembly hidebysig static int32 \n          '<SimpleCapture>g__F|1_0'(valuetype ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0'& A_0) cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       10 (0xa)\n    .maxstack  8\n    IL_0000:  ldc.i4.s   42\n    IL_0002:  ldarg.0\n    IL_0003:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0'::x\n    IL_0008:  add\n    IL_0009:  ret\n  } // end of method NoLocalFunctions::'<SimpleCapture>g__F|1_0'\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoLocalFunctions.opt.net40.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmpAE03\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmpAE03.tmp\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public auto ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle\n       extends [mscorlib]System.Object\n{\n  .field private initonly class [mscorlib]System.Func`1<int32> _func\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor(class [mscorlib]System.Func`1<int32> func) cil managed\n  {\n    // Code size       14 (0xe)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ldarg.0\n    IL_0007:  ldarg.1\n    IL_0008:  stfld      class [mscorlib]System.Func`1<int32> ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle::_func\n    IL_000d:  ret\n  } // end of method Handle::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle\n\n.class public abstract auto ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions\n       extends [mscorlib]System.Object\n{\n  .class auto ansi sealed nested private beforefieldinit '<>c__DisplayClass1_0'\n         extends [mscorlib]System.ValueType\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    .field public int32 x\n  } // end of class '<>c__DisplayClass1_0'\n\n  .class auto ansi sealed nested private beforefieldinit '<>c__DisplayClass2_0'\n         extends [mscorlib]System.Object\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    .field public int32 x\n    .method public hidebysig specialname rtspecialname \n            instance void  .ctor() cil managed\n    {\n      // Code size       7 (0x7)\n      .maxstack  8\n      IL_0000:  ldarg.0\n      IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n      IL_0006:  ret\n    } // end of method '<>c__DisplayClass2_0'::.ctor\n\n    .method assembly hidebysig instance int32 \n            '<SimpleCaptureWithRef>g__F|0'() cil managed\n    {\n      // Code size       10 (0xa)\n      .maxstack  8\n      IL_0000:  ldc.i4.s   42\n      IL_0002:  ldarg.0\n      IL_0003:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass2_0'::x\n      IL_0008:  add\n      IL_0009:  ret\n    } // end of method '<>c__DisplayClass2_0'::'<SimpleCaptureWithRef>g__F|0'\n\n  } // end of class '<>c__DisplayClass2_0'\n\n  .method private hidebysig static void  UseLocalFunctionReference() cil managed\n  {\n    // Code size       19 (0x13)\n    .maxstack  8\n    IL_0000:  ldnull\n    IL_0001:  ldftn      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions::'<UseLocalFunctionReference>g__F|0_0'()\n    IL_0007:  newobj     instance void class [mscorlib]System.Func`1<int32>::.ctor(object,\n                                                                                   native int)\n    IL_000c:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle::.ctor(class [mscorlib]System.Func`1<int32>)\n    IL_0011:  pop\n    IL_0012:  ret\n  } // end of method NoLocalFunctions::UseLocalFunctionReference\n\n  .method private hidebysig static void  SimpleCapture() cil managed\n  {\n    // Code size       17 (0x11)\n    .maxstack  2\n    .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0' V_0)\n    IL_0000:  ldloca.s   V_0\n    IL_0002:  ldc.i4.1\n    IL_0003:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0'::x\n    IL_0008:  ldloca.s   V_0\n    IL_000a:  call       int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions::'<SimpleCapture>g__F|1_0'(valuetype ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0'&)\n    IL_000f:  pop\n    IL_0010:  ret\n  } // end of method NoLocalFunctions::SimpleCapture\n\n  .method private hidebysig static void  SimpleCaptureWithRef() cil managed\n  {\n    // Code size       30 (0x1e)\n    .maxstack  8\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass2_0'::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldc.i4.1\n    IL_0007:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass2_0'::x\n    IL_000c:  ldftn      instance int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass2_0'::'<SimpleCaptureWithRef>g__F|0'()\n    IL_0012:  newobj     instance void class [mscorlib]System.Func`1<int32>::.ctor(object,\n                                                                                   native int)\n    IL_0017:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle::.ctor(class [mscorlib]System.Func`1<int32>)\n    IL_001c:  pop\n    IL_001d:  ret\n  } // end of method NoLocalFunctions::SimpleCaptureWithRef\n\n  .method assembly hidebysig static int32 \n          '<UseLocalFunctionReference>g__F|0_0'() cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       3 (0x3)\n    .maxstack  8\n    IL_0000:  ldc.i4.s   42\n    IL_0002:  ret\n  } // end of method NoLocalFunctions::'<UseLocalFunctionReference>g__F|0_0'\n\n  .method assembly hidebysig static int32 \n          '<SimpleCapture>g__F|1_0'(valuetype ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0'& A_0) cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       10 (0xa)\n    .maxstack  8\n    IL_0000:  ldc.i4.s   42\n    IL_0002:  ldarg.0\n    IL_0003:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0'::x\n    IL_0008:  add\n    IL_0009:  ret\n  } // end of method NoLocalFunctions::'<SimpleCapture>g__F|1_0'\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoLocalFunctions.opt.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly NoLocalFunctions\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module NoLocalFunctions.dll\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public auto ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle\n       extends [mscorlib]System.Object\n{\n  .field private initonly class [mscorlib]System.Func`1<int32> _func\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor(class [mscorlib]System.Func`1<int32> func) cil managed\n  {\n    // Code size       14 (0xe)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ldarg.0\n    IL_0007:  ldarg.1\n    IL_0008:  stfld      class [mscorlib]System.Func`1<int32> ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle::_func\n    IL_000d:  ret\n  } // end of method Handle::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle\n\n.class public abstract auto ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions\n       extends [mscorlib]System.Object\n{\n  .class auto ansi sealed nested private beforefieldinit '<>c__DisplayClass1_0'\n         extends [mscorlib]System.ValueType\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    .field public int32 x\n  } // end of class '<>c__DisplayClass1_0'\n\n  .class auto ansi sealed nested private beforefieldinit '<>c__DisplayClass2_0'\n         extends [mscorlib]System.Object\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    .field public int32 x\n    .method public hidebysig specialname rtspecialname \n            instance void  .ctor() cil managed\n    {\n      // Code size       7 (0x7)\n      .maxstack  8\n      IL_0000:  ldarg.0\n      IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n      IL_0006:  ret\n    } // end of method '<>c__DisplayClass2_0'::.ctor\n\n    .method assembly hidebysig instance int32 \n            '<SimpleCaptureWithRef>g__F|0'() cil managed\n    {\n      // Code size       10 (0xa)\n      .maxstack  8\n      IL_0000:  ldc.i4.s   42\n      IL_0002:  ldarg.0\n      IL_0003:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass2_0'::x\n      IL_0008:  add\n      IL_0009:  ret\n    } // end of method '<>c__DisplayClass2_0'::'<SimpleCaptureWithRef>g__F|0'\n\n  } // end of class '<>c__DisplayClass2_0'\n\n  .method private hidebysig static void  UseLocalFunctionReference() cil managed\n  {\n    // Code size       19 (0x13)\n    .maxstack  8\n    IL_0000:  ldnull\n    IL_0001:  ldftn      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions::'<UseLocalFunctionReference>g__F|0_0'()\n    IL_0007:  newobj     instance void class [mscorlib]System.Func`1<int32>::.ctor(object,\n                                                                                   native int)\n    IL_000c:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle::.ctor(class [mscorlib]System.Func`1<int32>)\n    IL_0011:  pop\n    IL_0012:  ret\n  } // end of method NoLocalFunctions::UseLocalFunctionReference\n\n  .method private hidebysig static void  SimpleCapture() cil managed\n  {\n    // Code size       17 (0x11)\n    .maxstack  2\n    .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0' V_0)\n    IL_0000:  ldloca.s   V_0\n    IL_0002:  ldc.i4.1\n    IL_0003:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0'::x\n    IL_0008:  ldloca.s   V_0\n    IL_000a:  call       int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions::'<SimpleCapture>g__F|1_0'(valuetype ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0'&)\n    IL_000f:  pop\n    IL_0010:  ret\n  } // end of method NoLocalFunctions::SimpleCapture\n\n  .method private hidebysig static void  SimpleCaptureWithRef() cil managed\n  {\n    // Code size       30 (0x1e)\n    .maxstack  8\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass2_0'::.ctor()\n    IL_0005:  dup\n    IL_0006:  ldc.i4.1\n    IL_0007:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass2_0'::x\n    IL_000c:  ldftn      instance int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass2_0'::'<SimpleCaptureWithRef>g__F|0'()\n    IL_0012:  newobj     instance void class [mscorlib]System.Func`1<int32>::.ctor(object,\n                                                                                   native int)\n    IL_0017:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle::.ctor(class [mscorlib]System.Func`1<int32>)\n    IL_001c:  pop\n    IL_001d:  ret\n  } // end of method NoLocalFunctions::SimpleCaptureWithRef\n\n  .method assembly hidebysig static int32 \n          '<UseLocalFunctionReference>g__F|0_0'() cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       3 (0x3)\n    .maxstack  8\n    IL_0000:  ldc.i4.s   42\n    IL_0002:  ret\n  } // end of method NoLocalFunctions::'<UseLocalFunctionReference>g__F|0_0'\n\n  .method assembly hidebysig static int32 \n          '<SimpleCapture>g__F|1_0'(valuetype ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0'& A_0) cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       10 (0xa)\n    .maxstack  8\n    IL_0000:  ldc.i4.s   42\n    IL_0002:  ldarg.0\n    IL_0003:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0'::x\n    IL_0008:  add\n    IL_0009:  ret\n  } // end of method NoLocalFunctions::'<SimpleCapture>g__F|1_0'\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoLocalFunctions.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly NoLocalFunctions\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module NoLocalFunctions.dll\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class public auto ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle\n       extends [mscorlib]System.Object\n{\n  .field private initonly class [mscorlib]System.Func`1<int32> _func\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor(class [mscorlib]System.Func`1<int32> func) cil managed\n  {\n    // Code size       16 (0x10)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  nop\n    IL_0007:  nop\n    IL_0008:  ldarg.0\n    IL_0009:  ldarg.1\n    IL_000a:  stfld      class [mscorlib]System.Func`1<int32> ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle::_func\n    IL_000f:  ret\n  } // end of method Handle::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle\n\n.class public abstract auto ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions\n       extends [mscorlib]System.Object\n{\n  .class auto ansi sealed nested private beforefieldinit '<>c__DisplayClass1_0'\n         extends [mscorlib]System.ValueType\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    .field public int32 x\n  } // end of class '<>c__DisplayClass1_0'\n\n  .class auto ansi sealed nested private beforefieldinit '<>c__DisplayClass2_0'\n         extends [mscorlib]System.Object\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    .field public int32 x\n    .method public hidebysig specialname rtspecialname \n            instance void  .ctor() cil managed\n    {\n      // Code size       8 (0x8)\n      .maxstack  8\n      IL_0000:  ldarg.0\n      IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n      IL_0006:  nop\n      IL_0007:  ret\n    } // end of method '<>c__DisplayClass2_0'::.ctor\n\n    .method assembly hidebysig instance int32 \n            '<SimpleCaptureWithRef>g__F|0'() cil managed\n    {\n      // Code size       10 (0xa)\n      .maxstack  8\n      IL_0000:  ldc.i4.s   42\n      IL_0002:  ldarg.0\n      IL_0003:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass2_0'::x\n      IL_0008:  add\n      IL_0009:  ret\n    } // end of method '<>c__DisplayClass2_0'::'<SimpleCaptureWithRef>g__F|0'\n\n  } // end of class '<>c__DisplayClass2_0'\n\n  .method private hidebysig static void  UseLocalFunctionReference() cil managed\n  {\n    // Code size       21 (0x15)\n    .maxstack  2\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle V_0)\n    IL_0000:  nop\n    IL_0001:  nop\n    IL_0002:  ldnull\n    IL_0003:  ldftn      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions::'<UseLocalFunctionReference>g__F|0_0'()\n    IL_0009:  newobj     instance void class [mscorlib]System.Func`1<int32>::.ctor(object,\n                                                                                   native int)\n    IL_000e:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle::.ctor(class [mscorlib]System.Func`1<int32>)\n    IL_0013:  stloc.0\n    IL_0014:  ret\n  } // end of method NoLocalFunctions::UseLocalFunctionReference\n\n  .method private hidebysig static void  SimpleCapture() cil managed\n  {\n    // Code size       19 (0x13)\n    .maxstack  2\n    .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0' V_0)\n    IL_0000:  nop\n    IL_0001:  ldloca.s   V_0\n    IL_0003:  ldc.i4.1\n    IL_0004:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0'::x\n    IL_0009:  nop\n    IL_000a:  ldloca.s   V_0\n    IL_000c:  call       int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions::'<SimpleCapture>g__F|1_0'(valuetype ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0'&)\n    IL_0011:  pop\n    IL_0012:  ret\n  } // end of method NoLocalFunctions::SimpleCapture\n\n  .method private hidebysig static void  SimpleCaptureWithRef() cil managed\n  {\n    // Code size       34 (0x22)\n    .maxstack  2\n    .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass2_0' V_0,\n             class ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle V_1)\n    IL_0000:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass2_0'::.ctor()\n    IL_0005:  stloc.0\n    IL_0006:  nop\n    IL_0007:  ldloc.0\n    IL_0008:  ldc.i4.1\n    IL_0009:  stfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass2_0'::x\n    IL_000e:  nop\n    IL_000f:  ldloc.0\n    IL_0010:  ldftn      instance int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass2_0'::'<SimpleCaptureWithRef>g__F|0'()\n    IL_0016:  newobj     instance void class [mscorlib]System.Func`1<int32>::.ctor(object,\n                                                                                   native int)\n    IL_001b:  newobj     instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.Handle::.ctor(class [mscorlib]System.Func`1<int32>)\n    IL_0020:  stloc.1\n    IL_0021:  ret\n  } // end of method NoLocalFunctions::SimpleCaptureWithRef\n\n  .method assembly hidebysig static int32 \n          '<UseLocalFunctionReference>g__F|0_0'() cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       3 (0x3)\n    .maxstack  8\n    IL_0000:  ldc.i4.s   42\n    IL_0002:  ret\n  } // end of method NoLocalFunctions::'<UseLocalFunctionReference>g__F|0_0'\n\n  .method assembly hidebysig static int32 \n          '<SimpleCapture>g__F|1_0'(valuetype ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0'& A_0) cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       10 (0xa)\n    .maxstack  8\n    IL_0000:  ldc.i4.s   42\n    IL_0002:  ldarg.0\n    IL_0003:  ldfld      int32 ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions/'<>c__DisplayClass1_0'::x\n    IL_0008:  add\n    IL_0009:  ret\n  } // end of method NoLocalFunctions::'<SimpleCapture>g__F|1_0'\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoLocalFunctions\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoNewOfT.Expected.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Ugly\n{\n\tinternal class NoNewOfT<TOnType> where TOnType : new()\n\t{\n\t\tpublic static TOnType CreateTOnType()\n\t\t{\n#if !ROSLYN\n#if OPT\n\t\t\tif (default(TOnType) != null)\n\t\t\t{\n\t\t\t\treturn default(TOnType);\n\t\t\t}\n\t\t\treturn Activator.CreateInstance<TOnType>();\n#else\n\t\t\treturn (default(TOnType) == null) ? Activator.CreateInstance<TOnType>() : default(TOnType);\n#endif\n#else\n\t\t\treturn Activator.CreateInstance<TOnType>();\n#endif\n\t\t}\n\n\t\tpublic static T CreateUnconstrainedT<T>() where T : new()\n\t\t{\n#if !ROSLYN\n#if OPT\n\t\t\tif (default(T) != null)\n\t\t\t{\n\t\t\t\treturn default(T);\n\t\t\t}\n\t\t\treturn Activator.CreateInstance<T>();\n#else\n\t\t\treturn (default(T) == null) ? Activator.CreateInstance<T>() : default(T);\n#endif\n#else\n\t\t\treturn Activator.CreateInstance<T>();\n#endif\n\t\t}\n\n\t\tpublic static T CreateClassT<T>() where T : class, new()\n\t\t{\n\t\t\treturn Activator.CreateInstance<T>();\n\t\t}\n\n\t\tpublic static T CollectionInitializer<T>() where T : IList<int>, new()\n\t\t{\n#if ROSLYN\n\t\t\tT result = Activator.CreateInstance<T>();\n\t\t\tresult.Add(1);\n\t\t\tresult.Add(2);\n\t\t\tresult.Add(3);\n\t\t\tresult.Add(4);\n\t\t\tresult.Add(5);\n\t\t\treturn result;\n#else\n\t\t\tT val = ((default(T) == null) ? Activator.CreateInstance<T>() : default(T));\n\t\t\tval.Add(1);\n\t\t\tval.Add(2);\n\t\t\tval.Add(3);\n\t\t\tval.Add(4);\n\t\t\tval.Add(5);\n\t\t\treturn val;\n#endif\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoNewOfT.cs",
    "content": "using System.Collections.Generic;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Ugly\n{\n\tinternal class NoNewOfT<TOnType> where TOnType : new()\n\t{\n\t\tpublic static TOnType CreateTOnType()\n\t\t{\n\t\t\treturn new TOnType();\n\t\t}\n\n\t\tpublic static T CreateUnconstrainedT<T>() where T : new()\n\t\t{\n\t\t\treturn new T();\n\t\t}\n\n\t\tpublic static T CreateClassT<T>() where T : class, new()\n\t\t{\n\t\t\treturn new T();\n\t\t}\n\n\t\tpublic static T CollectionInitializer<T>() where T : IList<int>, new()\n\t\t{\n\t\t\treturn new T() { 1, 2, 3, 4, 5 };\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoNewOfT.il",
    "content": "\n//  .NET IL Disassembler.  Version 9.0.4\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmpvpdwr1\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmpvpdwr1.tmp\n// MVID: {8447adbb-757d-4626-b7b7-846d745d90d0}\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoNewOfT`1<.ctor TOnType>\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig static !TOnType \n          CreateTOnType() cil managed\n  {\n    // Code size       39 (0x27)\n    .maxstack  1\n    .locals init (!TOnType V_0,\n             !TOnType V_1)\n    IL_0000:  nop\n    IL_0001:  ldloca.s   V_1\n    IL_0003:  initobj    !TOnType\n    IL_0009:  ldloc.1\n    IL_000a:  box        !TOnType\n    IL_000f:  brfalse.s  IL_001c\n\n    IL_0011:  ldloca.s   V_1\n    IL_0013:  initobj    !TOnType\n    IL_0019:  ldloc.1\n    IL_001a:  br.s       IL_0021\n\n    IL_001c:  call       !!0 [mscorlib]System.Activator::CreateInstance<!TOnType>()\n    IL_0021:  nop\n    IL_0022:  stloc.0\n    IL_0023:  br.s       IL_0025\n\n    IL_0025:  ldloc.0\n    IL_0026:  ret\n  } // end of method NoNewOfT`1::CreateTOnType\n\n  .method public hidebysig static !!T  CreateUnconstrainedT<.ctor T>() cil managed\n  {\n    // Code size       39 (0x27)\n    .maxstack  1\n    .locals init (!!T V_0,\n             !!T V_1)\n    IL_0000:  nop\n    IL_0001:  ldloca.s   V_1\n    IL_0003:  initobj    !!T\n    IL_0009:  ldloc.1\n    IL_000a:  box        !!T\n    IL_000f:  brfalse.s  IL_001c\n\n    IL_0011:  ldloca.s   V_1\n    IL_0013:  initobj    !!T\n    IL_0019:  ldloc.1\n    IL_001a:  br.s       IL_0021\n\n    IL_001c:  call       !!0 [mscorlib]System.Activator::CreateInstance<!!0>()\n    IL_0021:  nop\n    IL_0022:  stloc.0\n    IL_0023:  br.s       IL_0025\n\n    IL_0025:  ldloc.0\n    IL_0026:  ret\n  } // end of method NoNewOfT`1::CreateUnconstrainedT\n\n  .method public hidebysig static !!T  CreateClassT<class .ctor T>() cil managed\n  {\n    // Code size       11 (0xb)\n    .maxstack  1\n    .locals init (!!T V_0)\n    IL_0000:  nop\n    IL_0001:  call       !!0 [mscorlib]System.Activator::CreateInstance<!!0>()\n    IL_0006:  stloc.0\n    IL_0007:  br.s       IL_0009\n\n    IL_0009:  ldloc.0\n    IL_000a:  ret\n  } // end of method NoNewOfT`1::CreateClassT\n\n  .method public hidebysig static !!T  CollectionInitializer<.ctor (class [mscorlib]System.Collections.Generic.IList`1<int32>) T>() cil managed\n  {\n    // Code size       106 (0x6a)\n    .maxstack  2\n    .locals init (!!T V_0,\n             !!T V_1,\n             !!T V_2)\n    IL_0000:  nop\n    IL_0001:  ldloca.s   V_2\n    IL_0003:  initobj    !!T\n    IL_0009:  ldloc.2\n    IL_000a:  box        !!T\n    IL_000f:  brfalse.s  IL_001c\n\n    IL_0011:  ldloca.s   V_2\n    IL_0013:  initobj    !!T\n    IL_0019:  ldloc.2\n    IL_001a:  br.s       IL_0021\n\n    IL_001c:  call       !!0 [mscorlib]System.Activator::CreateInstance<!!0>()\n    IL_0021:  nop\n    IL_0022:  stloc.0\n    IL_0023:  ldloc.0\n    IL_0024:  box        !!T\n    IL_0029:  ldc.i4.1\n    IL_002a:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_002f:  nop\n    IL_0030:  ldloc.0\n    IL_0031:  box        !!T\n    IL_0036:  ldc.i4.2\n    IL_0037:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_003c:  nop\n    IL_003d:  ldloc.0\n    IL_003e:  box        !!T\n    IL_0043:  ldc.i4.3\n    IL_0044:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0049:  nop\n    IL_004a:  ldloc.0\n    IL_004b:  box        !!T\n    IL_0050:  ldc.i4.4\n    IL_0051:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0056:  nop\n    IL_0057:  ldloc.0\n    IL_0058:  box        !!T\n    IL_005d:  ldc.i4.5\n    IL_005e:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0063:  nop\n    IL_0064:  ldloc.0\n    IL_0065:  stloc.1\n    IL_0066:  br.s       IL_0068\n\n    IL_0068:  ldloc.1\n    IL_0069:  ret\n  } // end of method NoNewOfT`1::CollectionInitializer\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method NoNewOfT`1::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoNewOfT`1\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoNewOfT.net40.roslyn.il",
    "content": "\n//  .NET IL Disassembler.  Version 9.0.4\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmpyccvci\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmpyccvci.tmp\n// MVID: {ff6a33b6-7f19-447b-b168-f5c528dc4b6f}\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.custom instance void System.Runtime.CompilerServices.RefSafetyRulesAttribute::.ctor(int32) = ( 01 00 0B 00 00 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi sealed beforefieldinit Microsoft.CodeAnalysis.EmbeddedAttribute\n       extends [mscorlib]System.Attribute\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n  .custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 ) \n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Attribute::.ctor()\n    IL_0006:  nop\n    IL_0007:  ret\n  } // end of method EmbeddedAttribute::.ctor\n\n} // end of class Microsoft.CodeAnalysis.EmbeddedAttribute\n\n.class private auto ansi sealed beforefieldinit System.Runtime.CompilerServices.RefSafetyRulesAttribute\n       extends [mscorlib]System.Attribute\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n  .custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 ) \n  .custom instance void [mscorlib]System.AttributeUsageAttribute::.ctor(valuetype [mscorlib]System.AttributeTargets) = ( 01 00 02 00 00 00 02 00 54 02 0D 41 6C 6C 6F 77   // ........T..Allow\n                                                                                                                         4D 75 6C 74 69 70 6C 65 00 54 02 09 49 6E 68 65   // Multiple.T..Inhe\n                                                                                                                         72 69 74 65 64 00 )                               // rited.\n  .field public initonly int32 Version\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor(int32 A_1) cil managed\n  {\n    // Code size       15 (0xf)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Attribute::.ctor()\n    IL_0006:  nop\n    IL_0007:  ldarg.0\n    IL_0008:  ldarg.1\n    IL_0009:  stfld      int32 System.Runtime.CompilerServices.RefSafetyRulesAttribute::Version\n    IL_000e:  ret\n  } // end of method RefSafetyRulesAttribute::.ctor\n\n} // end of class System.Runtime.CompilerServices.RefSafetyRulesAttribute\n\n.class private auto ansi sealed beforefieldinit System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute\n       extends [mscorlib]System.Attribute\n{\n  .custom instance void [mscorlib]System.AttributeUsageAttribute::.ctor(valuetype [mscorlib]System.AttributeTargets) = ( 01 00 FF 7F 00 00 02 00 54 02 0D 41 6C 6C 6F 77   // ........T..Allow\n                                                                                                                         4D 75 6C 74 69 70 6C 65 01 54 02 09 49 6E 68 65   // Multiple.T..Inhe\n                                                                                                                         72 69 74 65 64 00 )                               // rited.\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor(string featureName) cil managed\n  {\n    // Code size       9 (0x9)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Attribute::.ctor()\n    IL_0006:  nop\n    IL_0007:  nop\n    IL_0008:  ret\n  } // end of method CompilerFeatureRequiredAttribute::.ctor\n\n} // end of class System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute\n\n.class private auto ansi beforefieldinit System.Runtime.CompilerServices.IsExternalInit\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  nop\n    IL_0007:  ret\n  } // end of method IsExternalInit::.ctor\n\n} // end of class System.Runtime.CompilerServices.IsExternalInit\n\n.class private auto ansi sealed beforefieldinit System.Runtime.CompilerServices.RequiredMemberAttribute\n       extends [mscorlib]System.Attribute\n{\n  .custom instance void [mscorlib]System.AttributeUsageAttribute::.ctor(valuetype [mscorlib]System.AttributeTargets) = ( 01 00 8C 01 00 00 02 00 54 02 0D 41 6C 6C 6F 77   // ........T..Allow\n                                                                                                                         4D 75 6C 74 69 70 6C 65 00 54 02 09 49 6E 68 65   // Multiple.T..Inhe\n                                                                                                                         72 69 74 65 64 00 )                               // rited.\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Attribute::.ctor()\n    IL_0006:  nop\n    IL_0007:  ret\n  } // end of method RequiredMemberAttribute::.ctor\n\n} // end of class System.Runtime.CompilerServices.RequiredMemberAttribute\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoNewOfT`1<.ctor TOnType>\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig static !TOnType \n          CreateTOnType() cil managed\n  {\n    // Code size       11 (0xb)\n    .maxstack  1\n    .locals init (!TOnType V_0)\n    IL_0000:  nop\n    IL_0001:  call       !!0 [mscorlib]System.Activator::CreateInstance<!TOnType>()\n    IL_0006:  stloc.0\n    IL_0007:  br.s       IL_0009\n\n    IL_0009:  ldloc.0\n    IL_000a:  ret\n  } // end of method NoNewOfT`1::CreateTOnType\n\n  .method public hidebysig static !!T  CreateUnconstrainedT<.ctor T>() cil managed\n  {\n    // Code size       11 (0xb)\n    .maxstack  1\n    .locals init (!!T V_0)\n    IL_0000:  nop\n    IL_0001:  call       !!0 [mscorlib]System.Activator::CreateInstance<!!0>()\n    IL_0006:  stloc.0\n    IL_0007:  br.s       IL_0009\n\n    IL_0009:  ldloc.0\n    IL_000a:  ret\n  } // end of method NoNewOfT`1::CreateUnconstrainedT\n\n  .method public hidebysig static !!T  CreateClassT<class .ctor T>() cil managed\n  {\n    // Code size       11 (0xb)\n    .maxstack  1\n    .locals init (!!T V_0)\n    IL_0000:  nop\n    IL_0001:  call       !!0 [mscorlib]System.Activator::CreateInstance<!!0>()\n    IL_0006:  stloc.0\n    IL_0007:  br.s       IL_0009\n\n    IL_0009:  ldloc.0\n    IL_000a:  ret\n  } // end of method NoNewOfT`1::CreateClassT\n\n  .method public hidebysig static !!T  CollectionInitializer<.ctor (class [mscorlib]System.Collections.Generic.IList`1<int32>) T>() cil managed\n  {\n    // Code size       88 (0x58)\n    .maxstack  2\n    .locals init (!!T V_0,\n             !!T V_1)\n    IL_0000:  nop\n    IL_0001:  call       !!0 [mscorlib]System.Activator::CreateInstance<!!0>()\n    IL_0006:  stloc.0\n    IL_0007:  ldloca.s   V_0\n    IL_0009:  ldc.i4.1\n    IL_000a:  constrained. !!T\n    IL_0010:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0015:  nop\n    IL_0016:  ldloca.s   V_0\n    IL_0018:  ldc.i4.2\n    IL_0019:  constrained. !!T\n    IL_001f:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0024:  nop\n    IL_0025:  ldloca.s   V_0\n    IL_0027:  ldc.i4.3\n    IL_0028:  constrained. !!T\n    IL_002e:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0033:  nop\n    IL_0034:  ldloca.s   V_0\n    IL_0036:  ldc.i4.4\n    IL_0037:  constrained. !!T\n    IL_003d:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0042:  nop\n    IL_0043:  ldloca.s   V_0\n    IL_0045:  ldc.i4.5\n    IL_0046:  constrained. !!T\n    IL_004c:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0051:  nop\n    IL_0052:  ldloc.0\n    IL_0053:  stloc.1\n    IL_0054:  br.s       IL_0056\n\n    IL_0056:  ldloc.1\n    IL_0057:  ret\n  } // end of method NoNewOfT`1::CollectionInitializer\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  nop\n    IL_0007:  ret\n  } // end of method NoNewOfT`1::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoNewOfT`1\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoNewOfT.opt.il",
    "content": "\n//  .NET IL Disassembler.  Version 9.0.4\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmp1ekgox\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmp1ekgox.tmp\n// MVID: {67ce32bd-0144-4136-a198-2fc9f941f624}\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoNewOfT`1<.ctor TOnType>\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig static !TOnType \n          CreateTOnType() cil managed\n  {\n    // Code size       32 (0x20)\n    .maxstack  1\n    .locals init (!TOnType V_0,\n             !TOnType V_1)\n    IL_0000:  ldloca.s   V_0\n    IL_0002:  initobj    !TOnType\n    IL_0008:  ldloc.0\n    IL_0009:  box        !TOnType\n    IL_000e:  brfalse.s  IL_001a\n\n    IL_0010:  ldloca.s   V_1\n    IL_0012:  initobj    !TOnType\n    IL_0018:  ldloc.1\n    IL_0019:  ret\n\n    IL_001a:  call       !!0 [mscorlib]System.Activator::CreateInstance<!TOnType>()\n    IL_001f:  ret\n  } // end of method NoNewOfT`1::CreateTOnType\n\n  .method public hidebysig static !!T  CreateUnconstrainedT<.ctor T>() cil managed\n  {\n    // Code size       32 (0x20)\n    .maxstack  1\n    .locals init (!!T V_0,\n             !!T V_1)\n    IL_0000:  ldloca.s   V_0\n    IL_0002:  initobj    !!T\n    IL_0008:  ldloc.0\n    IL_0009:  box        !!T\n    IL_000e:  brfalse.s  IL_001a\n\n    IL_0010:  ldloca.s   V_1\n    IL_0012:  initobj    !!T\n    IL_0018:  ldloc.1\n    IL_0019:  ret\n\n    IL_001a:  call       !!0 [mscorlib]System.Activator::CreateInstance<!!0>()\n    IL_001f:  ret\n  } // end of method NoNewOfT`1::CreateUnconstrainedT\n\n  .method public hidebysig static !!T  CreateClassT<class .ctor T>() cil managed\n  {\n    // Code size       6 (0x6)\n    .maxstack  8\n    IL_0000:  call       !!0 [mscorlib]System.Activator::CreateInstance<!!0>()\n    IL_0005:  ret\n  } // end of method NoNewOfT`1::CreateClassT\n\n  .method public hidebysig static !!T  CollectionInitializer<.ctor (class [mscorlib]System.Collections.Generic.IList`1<int32>) T>() cil managed\n  {\n    // Code size       95 (0x5f)\n    .maxstack  2\n    .locals init (!!T V_0,\n             !!T V_1,\n             !!T V_2)\n    IL_0000:  ldloca.s   V_1\n    IL_0002:  initobj    !!T\n    IL_0008:  ldloc.1\n    IL_0009:  box        !!T\n    IL_000e:  brfalse.s  IL_001b\n\n    IL_0010:  ldloca.s   V_2\n    IL_0012:  initobj    !!T\n    IL_0018:  ldloc.2\n    IL_0019:  br.s       IL_0020\n\n    IL_001b:  call       !!0 [mscorlib]System.Activator::CreateInstance<!!0>()\n    IL_0020:  stloc.0\n    IL_0021:  ldloc.0\n    IL_0022:  box        !!T\n    IL_0027:  ldc.i4.1\n    IL_0028:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_002d:  ldloc.0\n    IL_002e:  box        !!T\n    IL_0033:  ldc.i4.2\n    IL_0034:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0039:  ldloc.0\n    IL_003a:  box        !!T\n    IL_003f:  ldc.i4.3\n    IL_0040:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0045:  ldloc.0\n    IL_0046:  box        !!T\n    IL_004b:  ldc.i4.4\n    IL_004c:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0051:  ldloc.0\n    IL_0052:  box        !!T\n    IL_0057:  ldc.i4.5\n    IL_0058:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_005d:  ldloc.0\n    IL_005e:  ret\n  } // end of method NoNewOfT`1::CollectionInitializer\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method NoNewOfT`1::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoNewOfT`1\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoNewOfT.opt.net40.roslyn.il",
    "content": "\n//  .NET IL Disassembler.  Version 9.0.4\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmp4xstme\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmp4xstme.tmp\n// MVID: {a031faef-fcb2-420c-9cd3-6e9b01e7f81e}\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.custom instance void System.Runtime.CompilerServices.RefSafetyRulesAttribute::.ctor(int32) = ( 01 00 0B 00 00 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi sealed beforefieldinit Microsoft.CodeAnalysis.EmbeddedAttribute\n       extends [mscorlib]System.Attribute\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n  .custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 ) \n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Attribute::.ctor()\n    IL_0006:  ret\n  } // end of method EmbeddedAttribute::.ctor\n\n} // end of class Microsoft.CodeAnalysis.EmbeddedAttribute\n\n.class private auto ansi sealed beforefieldinit System.Runtime.CompilerServices.RefSafetyRulesAttribute\n       extends [mscorlib]System.Attribute\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n  .custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 ) \n  .custom instance void [mscorlib]System.AttributeUsageAttribute::.ctor(valuetype [mscorlib]System.AttributeTargets) = ( 01 00 02 00 00 00 02 00 54 02 0D 41 6C 6C 6F 77   // ........T..Allow\n                                                                                                                         4D 75 6C 74 69 70 6C 65 00 54 02 09 49 6E 68 65   // Multiple.T..Inhe\n                                                                                                                         72 69 74 65 64 00 )                               // rited.\n  .field public initonly int32 Version\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor(int32 A_1) cil managed\n  {\n    // Code size       14 (0xe)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Attribute::.ctor()\n    IL_0006:  ldarg.0\n    IL_0007:  ldarg.1\n    IL_0008:  stfld      int32 System.Runtime.CompilerServices.RefSafetyRulesAttribute::Version\n    IL_000d:  ret\n  } // end of method RefSafetyRulesAttribute::.ctor\n\n} // end of class System.Runtime.CompilerServices.RefSafetyRulesAttribute\n\n.class private auto ansi sealed beforefieldinit System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute\n       extends [mscorlib]System.Attribute\n{\n  .custom instance void [mscorlib]System.AttributeUsageAttribute::.ctor(valuetype [mscorlib]System.AttributeTargets) = ( 01 00 FF 7F 00 00 02 00 54 02 0D 41 6C 6C 6F 77   // ........T..Allow\n                                                                                                                         4D 75 6C 74 69 70 6C 65 01 54 02 09 49 6E 68 65   // Multiple.T..Inhe\n                                                                                                                         72 69 74 65 64 00 )                               // rited.\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor(string featureName) cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Attribute::.ctor()\n    IL_0006:  ret\n  } // end of method CompilerFeatureRequiredAttribute::.ctor\n\n} // end of class System.Runtime.CompilerServices.CompilerFeatureRequiredAttribute\n\n.class private auto ansi beforefieldinit System.Runtime.CompilerServices.IsExternalInit\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method IsExternalInit::.ctor\n\n} // end of class System.Runtime.CompilerServices.IsExternalInit\n\n.class private auto ansi sealed beforefieldinit System.Runtime.CompilerServices.RequiredMemberAttribute\n       extends [mscorlib]System.Attribute\n{\n  .custom instance void [mscorlib]System.AttributeUsageAttribute::.ctor(valuetype [mscorlib]System.AttributeTargets) = ( 01 00 8C 01 00 00 02 00 54 02 0D 41 6C 6C 6F 77   // ........T..Allow\n                                                                                                                         4D 75 6C 74 69 70 6C 65 00 54 02 09 49 6E 68 65   // Multiple.T..Inhe\n                                                                                                                         72 69 74 65 64 00 )                               // rited.\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Attribute::.ctor()\n    IL_0006:  ret\n  } // end of method RequiredMemberAttribute::.ctor\n\n} // end of class System.Runtime.CompilerServices.RequiredMemberAttribute\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoNewOfT`1<.ctor TOnType>\n       extends [mscorlib]System.Object\n{\n  .method public hidebysig static !TOnType \n          CreateTOnType() cil managed\n  {\n    // Code size       6 (0x6)\n    .maxstack  8\n    IL_0000:  call       !!0 [mscorlib]System.Activator::CreateInstance<!TOnType>()\n    IL_0005:  ret\n  } // end of method NoNewOfT`1::CreateTOnType\n\n  .method public hidebysig static !!T  CreateUnconstrainedT<.ctor T>() cil managed\n  {\n    // Code size       6 (0x6)\n    .maxstack  8\n    IL_0000:  call       !!0 [mscorlib]System.Activator::CreateInstance<!!0>()\n    IL_0005:  ret\n  } // end of method NoNewOfT`1::CreateUnconstrainedT\n\n  .method public hidebysig static !!T  CreateClassT<class .ctor T>() cil managed\n  {\n    // Code size       6 (0x6)\n    .maxstack  8\n    IL_0000:  call       !!0 [mscorlib]System.Activator::CreateInstance<!!0>()\n    IL_0005:  ret\n  } // end of method NoNewOfT`1::CreateClassT\n\n  .method public hidebysig static !!T  CollectionInitializer<.ctor (class [mscorlib]System.Collections.Generic.IList`1<int32>) T>() cil managed\n  {\n    // Code size       78 (0x4e)\n    .maxstack  2\n    .locals init (!!T V_0)\n    IL_0000:  call       !!0 [mscorlib]System.Activator::CreateInstance<!!0>()\n    IL_0005:  stloc.0\n    IL_0006:  ldloca.s   V_0\n    IL_0008:  ldc.i4.1\n    IL_0009:  constrained. !!T\n    IL_000f:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0014:  ldloca.s   V_0\n    IL_0016:  ldc.i4.2\n    IL_0017:  constrained. !!T\n    IL_001d:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0022:  ldloca.s   V_0\n    IL_0024:  ldc.i4.3\n    IL_0025:  constrained. !!T\n    IL_002b:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0030:  ldloca.s   V_0\n    IL_0032:  ldc.i4.4\n    IL_0033:  constrained. !!T\n    IL_0039:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_003e:  ldloca.s   V_0\n    IL_0040:  ldc.i4.5\n    IL_0041:  constrained. !!T\n    IL_0047:  callvirt   instance void class [mscorlib]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_004c:  ldloc.0\n    IL_004d:  ret\n  } // end of method NoNewOfT`1::CollectionInitializer\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method NoNewOfT`1::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoNewOfT`1\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoNewOfT.opt.roslyn.il",
    "content": "\n//  .NET IL Disassembler.  Version 9.0.4\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern System.Runtime\n{\n  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )                         // .?_....:\n  .ver 10:0:0:0\n}\n.assembly tmpauzspg\n{\n  .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [System.Runtime]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                                   63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [System.Runtime]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [System.Runtime]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) \n\n  .custom instance void [System.Runtime]System.Runtime.Versioning.TargetFrameworkAttribute::.ctor(string) = ( 01 00 19 2E 4E 45 54 43 6F 72 65 41 70 70 2C 56   // ....NETCoreApp,V\n                                                                                                              65 72 73 69 6F 6E 3D 76 31 30 2E 30 00 00 )       // ersion=v10.0..\n  .permissionset reqmin\n             = {[System.Runtime]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmpauzspg.tmp\n// MVID: {6d3a3b63-d01c-49f7-9515-565421f78266}\n.custom instance void [System.Runtime]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.custom instance void [System.Runtime]System.Runtime.CompilerServices.RefSafetyRulesAttribute::.ctor(int32) = ( 01 00 0B 00 00 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoNewOfT`1<.ctor TOnType>\n       extends [System.Runtime]System.Object\n{\n  .method public hidebysig static !TOnType \n          CreateTOnType() cil managed\n  {\n    // Code size       6 (0x6)\n    .maxstack  8\n    IL_0000:  call       !!0 [System.Runtime]System.Activator::CreateInstance<!TOnType>()\n    IL_0005:  ret\n  } // end of method NoNewOfT`1::CreateTOnType\n\n  .method public hidebysig static !!T  CreateUnconstrainedT<.ctor T>() cil managed\n  {\n    // Code size       6 (0x6)\n    .maxstack  8\n    IL_0000:  call       !!0 [System.Runtime]System.Activator::CreateInstance<!!0>()\n    IL_0005:  ret\n  } // end of method NoNewOfT`1::CreateUnconstrainedT\n\n  .method public hidebysig static !!T  CreateClassT<class .ctor T>() cil managed\n  {\n    // Code size       6 (0x6)\n    .maxstack  8\n    IL_0000:  call       !!0 [System.Runtime]System.Activator::CreateInstance<!!0>()\n    IL_0005:  ret\n  } // end of method NoNewOfT`1::CreateClassT\n\n  .method public hidebysig static !!T  CollectionInitializer<.ctor (class [System.Runtime]System.Collections.Generic.IList`1<int32>) T>() cil managed\n  {\n    // Code size       78 (0x4e)\n    .maxstack  2\n    .locals init (!!T V_0)\n    IL_0000:  call       !!0 [System.Runtime]System.Activator::CreateInstance<!!0>()\n    IL_0005:  stloc.0\n    IL_0006:  ldloca.s   V_0\n    IL_0008:  ldc.i4.1\n    IL_0009:  constrained. !!T\n    IL_000f:  callvirt   instance void class [System.Runtime]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0014:  ldloca.s   V_0\n    IL_0016:  ldc.i4.2\n    IL_0017:  constrained. !!T\n    IL_001d:  callvirt   instance void class [System.Runtime]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0022:  ldloca.s   V_0\n    IL_0024:  ldc.i4.3\n    IL_0025:  constrained. !!T\n    IL_002b:  callvirt   instance void class [System.Runtime]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0030:  ldloca.s   V_0\n    IL_0032:  ldc.i4.4\n    IL_0033:  constrained. !!T\n    IL_0039:  callvirt   instance void class [System.Runtime]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_003e:  ldloca.s   V_0\n    IL_0040:  ldc.i4.5\n    IL_0041:  constrained. !!T\n    IL_0047:  callvirt   instance void class [System.Runtime]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_004c:  ldloc.0\n    IL_004d:  ret\n  } // end of method NoNewOfT`1::CollectionInitializer\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [System.Runtime]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method NoNewOfT`1::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoNewOfT`1\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoNewOfT.roslyn.il",
    "content": "\n//  .NET IL Disassembler.  Version 9.0.4\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern System.Runtime\n{\n  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )                         // .?_....:\n  .ver 10:0:0:0\n}\n.assembly tmpybdlca\n{\n  .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [System.Runtime]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                                   63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [System.Runtime]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [System.Runtime]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) \n\n  .custom instance void [System.Runtime]System.Runtime.Versioning.TargetFrameworkAttribute::.ctor(string) = ( 01 00 19 2E 4E 45 54 43 6F 72 65 41 70 70 2C 56   // ....NETCoreApp,V\n                                                                                                              65 72 73 69 6F 6E 3D 76 31 30 2E 30 00 00 )       // ersion=v10.0..\n  .permissionset reqmin\n             = {[System.Runtime]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmpybdlca.tmp\n// MVID: {b57f13a4-d291-42ea-b595-3766c1f1470c}\n.custom instance void [System.Runtime]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.custom instance void [System.Runtime]System.Runtime.CompilerServices.RefSafetyRulesAttribute::.ctor(int32) = ( 01 00 0B 00 00 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoNewOfT`1<.ctor TOnType>\n       extends [System.Runtime]System.Object\n{\n  .method public hidebysig static !TOnType \n          CreateTOnType() cil managed\n  {\n    // Code size       11 (0xb)\n    .maxstack  1\n    .locals init (!TOnType V_0)\n    IL_0000:  nop\n    IL_0001:  call       !!0 [System.Runtime]System.Activator::CreateInstance<!TOnType>()\n    IL_0006:  stloc.0\n    IL_0007:  br.s       IL_0009\n\n    IL_0009:  ldloc.0\n    IL_000a:  ret\n  } // end of method NoNewOfT`1::CreateTOnType\n\n  .method public hidebysig static !!T  CreateUnconstrainedT<.ctor T>() cil managed\n  {\n    // Code size       11 (0xb)\n    .maxstack  1\n    .locals init (!!T V_0)\n    IL_0000:  nop\n    IL_0001:  call       !!0 [System.Runtime]System.Activator::CreateInstance<!!0>()\n    IL_0006:  stloc.0\n    IL_0007:  br.s       IL_0009\n\n    IL_0009:  ldloc.0\n    IL_000a:  ret\n  } // end of method NoNewOfT`1::CreateUnconstrainedT\n\n  .method public hidebysig static !!T  CreateClassT<class .ctor T>() cil managed\n  {\n    // Code size       11 (0xb)\n    .maxstack  1\n    .locals init (!!T V_0)\n    IL_0000:  nop\n    IL_0001:  call       !!0 [System.Runtime]System.Activator::CreateInstance<!!0>()\n    IL_0006:  stloc.0\n    IL_0007:  br.s       IL_0009\n\n    IL_0009:  ldloc.0\n    IL_000a:  ret\n  } // end of method NoNewOfT`1::CreateClassT\n\n  .method public hidebysig static !!T  CollectionInitializer<.ctor (class [System.Runtime]System.Collections.Generic.IList`1<int32>) T>() cil managed\n  {\n    // Code size       88 (0x58)\n    .maxstack  2\n    .locals init (!!T V_0,\n             !!T V_1)\n    IL_0000:  nop\n    IL_0001:  call       !!0 [System.Runtime]System.Activator::CreateInstance<!!0>()\n    IL_0006:  stloc.0\n    IL_0007:  ldloca.s   V_0\n    IL_0009:  ldc.i4.1\n    IL_000a:  constrained. !!T\n    IL_0010:  callvirt   instance void class [System.Runtime]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0015:  nop\n    IL_0016:  ldloca.s   V_0\n    IL_0018:  ldc.i4.2\n    IL_0019:  constrained. !!T\n    IL_001f:  callvirt   instance void class [System.Runtime]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0024:  nop\n    IL_0025:  ldloca.s   V_0\n    IL_0027:  ldc.i4.3\n    IL_0028:  constrained. !!T\n    IL_002e:  callvirt   instance void class [System.Runtime]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0033:  nop\n    IL_0034:  ldloca.s   V_0\n    IL_0036:  ldc.i4.4\n    IL_0037:  constrained. !!T\n    IL_003d:  callvirt   instance void class [System.Runtime]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0042:  nop\n    IL_0043:  ldloca.s   V_0\n    IL_0045:  ldc.i4.5\n    IL_0046:  constrained. !!T\n    IL_004c:  callvirt   instance void class [System.Runtime]System.Collections.Generic.ICollection`1<int32>::Add(!0)\n    IL_0051:  nop\n    IL_0052:  ldloc.0\n    IL_0053:  stloc.1\n    IL_0054:  br.s       IL_0056\n\n    IL_0056:  ldloc.1\n    IL_0057:  ret\n  } // end of method NoNewOfT`1::CollectionInitializer\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [System.Runtime]System.Object::.ctor()\n    IL_0006:  nop\n    IL_0007:  ret\n  } // end of method NoNewOfT`1::.ctor\n\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoNewOfT`1\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.Expected.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n#if ROSLYN\n#if !OPT\nusing System.Diagnostics;\n#endif\nusing System.Runtime.CompilerServices;\n#endif\nusing System.Threading;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Ugly\n{\n\tinternal class NoPropertiesAndEvents\n\t{\n#if ROSLYN\n\t\t[CompilerGenerated]\n#if !OPT\n\t\t[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n#endif\n#endif\n\t\tprivate EventHandler m_MyEvent;\n\n\t\tpublic event EventHandler MyEvent {\n#if ROSLYN\n\t\t[CompilerGenerated]\n#endif\n\t\t\tadd {\n\t\t\t\tEventHandler eventHandler = this.m_MyEvent;\n\t\t\t\tEventHandler eventHandler2;\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\teventHandler2 = eventHandler;\n\t\t\t\t\tEventHandler value2 = (EventHandler)Delegate.Combine(eventHandler2, value);\n\t\t\t\t\teventHandler = Interlocked.CompareExchange(ref this.m_MyEvent, value2, eventHandler2);\n\t\t\t\t} while ((object)eventHandler != eventHandler2);\n\t\t\t}\n#if ROSLYN\n\t\t[CompilerGenerated]\n#endif\n\t\t\tremove {\n\t\t\t\tEventHandler eventHandler = this.m_MyEvent;\n\t\t\t\tEventHandler eventHandler2;\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\teventHandler2 = eventHandler;\n\t\t\t\t\tEventHandler value2 = (EventHandler)Delegate.Remove(eventHandler2, value);\n\t\t\t\t\teventHandler = Interlocked.CompareExchange(ref this.m_MyEvent, value2, eventHandler2);\n\t\t\t\t} while ((object)eventHandler != eventHandler2);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.Ugly\n{\n\tinternal class NoPropertiesAndEvents\n\t{\n\t\tpublic event EventHandler MyEvent;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmp8FA\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmp8FA.tmp\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents\n       extends [mscorlib]System.Object\n{\n  .field private class [mscorlib]System.EventHandler MyEvent\n  .method public hidebysig specialname instance void \n          add_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed\n  {\n    // Code size       48 (0x30)\n    .maxstack  3\n    .locals init (class [mscorlib]System.EventHandler V_0,\n             class [mscorlib]System.EventHandler V_1,\n             class [mscorlib]System.EventHandler V_2,\n             bool V_3)\n    IL_0000:  ldarg.0\n    IL_0001:  ldfld      class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_0006:  stloc.0\n    IL_0007:  ldloc.0\n    IL_0008:  stloc.1\n    IL_0009:  ldloc.1\n    IL_000a:  ldarg.1\n    IL_000b:  call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate,\n                                                                                            class [mscorlib]System.Delegate)\n    IL_0010:  castclass  [mscorlib]System.EventHandler\n    IL_0015:  stloc.2\n    IL_0016:  ldarg.0\n    IL_0017:  ldflda     class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_001c:  ldloc.2\n    IL_001d:  ldloc.1\n    IL_001e:  call       !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler>(!!0&,\n                                                                                                                          !!0,\n                                                                                                                          !!0)\n    IL_0023:  stloc.0\n    IL_0024:  ldloc.0\n    IL_0025:  ldloc.1\n    IL_0026:  ceq\n    IL_0028:  ldc.i4.0\n    IL_0029:  ceq\n    IL_002b:  stloc.3\n    IL_002c:  ldloc.3\n    IL_002d:  brtrue.s   IL_0007\n\n    IL_002f:  ret\n  } // end of method NoPropertiesAndEvents::add_MyEvent\n\n  .method public hidebysig specialname instance void \n          remove_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed\n  {\n    // Code size       48 (0x30)\n    .maxstack  3\n    .locals init (class [mscorlib]System.EventHandler V_0,\n             class [mscorlib]System.EventHandler V_1,\n             class [mscorlib]System.EventHandler V_2,\n             bool V_3)\n    IL_0000:  ldarg.0\n    IL_0001:  ldfld      class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_0006:  stloc.0\n    IL_0007:  ldloc.0\n    IL_0008:  stloc.1\n    IL_0009:  ldloc.1\n    IL_000a:  ldarg.1\n    IL_000b:  call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate,\n                                                                                           class [mscorlib]System.Delegate)\n    IL_0010:  castclass  [mscorlib]System.EventHandler\n    IL_0015:  stloc.2\n    IL_0016:  ldarg.0\n    IL_0017:  ldflda     class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_001c:  ldloc.2\n    IL_001d:  ldloc.1\n    IL_001e:  call       !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler>(!!0&,\n                                                                                                                          !!0,\n                                                                                                                          !!0)\n    IL_0023:  stloc.0\n    IL_0024:  ldloc.0\n    IL_0025:  ldloc.1\n    IL_0026:  ceq\n    IL_0028:  ldc.i4.0\n    IL_0029:  ceq\n    IL_002b:  stloc.3\n    IL_002c:  ldloc.3\n    IL_002d:  brtrue.s   IL_0007\n\n    IL_002f:  ret\n  } // end of method NoPropertiesAndEvents::remove_MyEvent\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method NoPropertiesAndEvents::.ctor\n\n  .event [mscorlib]System.EventHandler MyEvent\n  {\n    .addon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::add_MyEvent(class [mscorlib]System.EventHandler)\n    .removeon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::remove_MyEvent(class [mscorlib]System.EventHandler)\n  } // end of event NoPropertiesAndEvents::MyEvent\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.net40.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmpB115\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmpB115.tmp\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents\n       extends [mscorlib]System.Object\n{\n  .field private class [mscorlib]System.EventHandler MyEvent\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n  .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) \n  .method public hidebysig specialname instance void \n          add_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       41 (0x29)\n    .maxstack  3\n    .locals init (class [mscorlib]System.EventHandler V_0,\n             class [mscorlib]System.EventHandler V_1,\n             class [mscorlib]System.EventHandler V_2)\n    IL_0000:  ldarg.0\n    IL_0001:  ldfld      class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_0006:  stloc.0\n    IL_0007:  ldloc.0\n    IL_0008:  stloc.1\n    IL_0009:  ldloc.1\n    IL_000a:  ldarg.1\n    IL_000b:  call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate,\n                                                                                            class [mscorlib]System.Delegate)\n    IL_0010:  castclass  [mscorlib]System.EventHandler\n    IL_0015:  stloc.2\n    IL_0016:  ldarg.0\n    IL_0017:  ldflda     class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_001c:  ldloc.2\n    IL_001d:  ldloc.1\n    IL_001e:  call       !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler>(!!0&,\n                                                                                                                          !!0,\n                                                                                                                          !!0)\n    IL_0023:  stloc.0\n    IL_0024:  ldloc.0\n    IL_0025:  ldloc.1\n    IL_0026:  bne.un.s   IL_0007\n\n    IL_0028:  ret\n  } // end of method NoPropertiesAndEvents::add_MyEvent\n\n  .method public hidebysig specialname instance void \n          remove_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       41 (0x29)\n    .maxstack  3\n    .locals init (class [mscorlib]System.EventHandler V_0,\n             class [mscorlib]System.EventHandler V_1,\n             class [mscorlib]System.EventHandler V_2)\n    IL_0000:  ldarg.0\n    IL_0001:  ldfld      class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_0006:  stloc.0\n    IL_0007:  ldloc.0\n    IL_0008:  stloc.1\n    IL_0009:  ldloc.1\n    IL_000a:  ldarg.1\n    IL_000b:  call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate,\n                                                                                           class [mscorlib]System.Delegate)\n    IL_0010:  castclass  [mscorlib]System.EventHandler\n    IL_0015:  stloc.2\n    IL_0016:  ldarg.0\n    IL_0017:  ldflda     class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_001c:  ldloc.2\n    IL_001d:  ldloc.1\n    IL_001e:  call       !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler>(!!0&,\n                                                                                                                          !!0,\n                                                                                                                          !!0)\n    IL_0023:  stloc.0\n    IL_0024:  ldloc.0\n    IL_0025:  ldloc.1\n    IL_0026:  bne.un.s   IL_0007\n\n    IL_0028:  ret\n  } // end of method NoPropertiesAndEvents::remove_MyEvent\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  nop\n    IL_0007:  ret\n  } // end of method NoPropertiesAndEvents::.ctor\n\n  .event [mscorlib]System.EventHandler MyEvent\n  {\n    .addon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::add_MyEvent(class [mscorlib]System.EventHandler)\n    .removeon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::remove_MyEvent(class [mscorlib]System.EventHandler)\n  } // end of event NoPropertiesAndEvents::MyEvent\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.opt.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmp8FB\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmp8FB.tmp\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents\n       extends [mscorlib]System.Object\n{\n  .field private class [mscorlib]System.EventHandler MyEvent\n  .method public hidebysig specialname instance void \n          add_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed\n  {\n    // Code size       41 (0x29)\n    .maxstack  3\n    .locals init (class [mscorlib]System.EventHandler V_0,\n             class [mscorlib]System.EventHandler V_1,\n             class [mscorlib]System.EventHandler V_2)\n    IL_0000:  ldarg.0\n    IL_0001:  ldfld      class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_0006:  stloc.0\n    IL_0007:  ldloc.0\n    IL_0008:  stloc.1\n    IL_0009:  ldloc.1\n    IL_000a:  ldarg.1\n    IL_000b:  call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate,\n                                                                                            class [mscorlib]System.Delegate)\n    IL_0010:  castclass  [mscorlib]System.EventHandler\n    IL_0015:  stloc.2\n    IL_0016:  ldarg.0\n    IL_0017:  ldflda     class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_001c:  ldloc.2\n    IL_001d:  ldloc.1\n    IL_001e:  call       !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler>(!!0&,\n                                                                                                                          !!0,\n                                                                                                                          !!0)\n    IL_0023:  stloc.0\n    IL_0024:  ldloc.0\n    IL_0025:  ldloc.1\n    IL_0026:  bne.un.s   IL_0007\n\n    IL_0028:  ret\n  } // end of method NoPropertiesAndEvents::add_MyEvent\n\n  .method public hidebysig specialname instance void \n          remove_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed\n  {\n    // Code size       41 (0x29)\n    .maxstack  3\n    .locals init (class [mscorlib]System.EventHandler V_0,\n             class [mscorlib]System.EventHandler V_1,\n             class [mscorlib]System.EventHandler V_2)\n    IL_0000:  ldarg.0\n    IL_0001:  ldfld      class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_0006:  stloc.0\n    IL_0007:  ldloc.0\n    IL_0008:  stloc.1\n    IL_0009:  ldloc.1\n    IL_000a:  ldarg.1\n    IL_000b:  call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate,\n                                                                                           class [mscorlib]System.Delegate)\n    IL_0010:  castclass  [mscorlib]System.EventHandler\n    IL_0015:  stloc.2\n    IL_0016:  ldarg.0\n    IL_0017:  ldflda     class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_001c:  ldloc.2\n    IL_001d:  ldloc.1\n    IL_001e:  call       !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler>(!!0&,\n                                                                                                                          !!0,\n                                                                                                                          !!0)\n    IL_0023:  stloc.0\n    IL_0024:  ldloc.0\n    IL_0025:  ldloc.1\n    IL_0026:  bne.un.s   IL_0007\n\n    IL_0028:  ret\n  } // end of method NoPropertiesAndEvents::remove_MyEvent\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method NoPropertiesAndEvents::.ctor\n\n  .event [mscorlib]System.EventHandler MyEvent\n  {\n    .addon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::add_MyEvent(class [mscorlib]System.EventHandler)\n    .removeon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::remove_MyEvent(class [mscorlib]System.EventHandler)\n  } // end of event NoPropertiesAndEvents::MyEvent\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.opt.net40.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmpB126\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmpB126.tmp\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents\n       extends [mscorlib]System.Object\n{\n  .field private class [mscorlib]System.EventHandler MyEvent\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n  .method public hidebysig specialname instance void \n          add_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       41 (0x29)\n    .maxstack  3\n    .locals init (class [mscorlib]System.EventHandler V_0,\n             class [mscorlib]System.EventHandler V_1,\n             class [mscorlib]System.EventHandler V_2)\n    IL_0000:  ldarg.0\n    IL_0001:  ldfld      class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_0006:  stloc.0\n    IL_0007:  ldloc.0\n    IL_0008:  stloc.1\n    IL_0009:  ldloc.1\n    IL_000a:  ldarg.1\n    IL_000b:  call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate,\n                                                                                            class [mscorlib]System.Delegate)\n    IL_0010:  castclass  [mscorlib]System.EventHandler\n    IL_0015:  stloc.2\n    IL_0016:  ldarg.0\n    IL_0017:  ldflda     class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_001c:  ldloc.2\n    IL_001d:  ldloc.1\n    IL_001e:  call       !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler>(!!0&,\n                                                                                                                          !!0,\n                                                                                                                          !!0)\n    IL_0023:  stloc.0\n    IL_0024:  ldloc.0\n    IL_0025:  ldloc.1\n    IL_0026:  bne.un.s   IL_0007\n\n    IL_0028:  ret\n  } // end of method NoPropertiesAndEvents::add_MyEvent\n\n  .method public hidebysig specialname instance void \n          remove_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       41 (0x29)\n    .maxstack  3\n    .locals init (class [mscorlib]System.EventHandler V_0,\n             class [mscorlib]System.EventHandler V_1,\n             class [mscorlib]System.EventHandler V_2)\n    IL_0000:  ldarg.0\n    IL_0001:  ldfld      class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_0006:  stloc.0\n    IL_0007:  ldloc.0\n    IL_0008:  stloc.1\n    IL_0009:  ldloc.1\n    IL_000a:  ldarg.1\n    IL_000b:  call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate,\n                                                                                           class [mscorlib]System.Delegate)\n    IL_0010:  castclass  [mscorlib]System.EventHandler\n    IL_0015:  stloc.2\n    IL_0016:  ldarg.0\n    IL_0017:  ldflda     class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_001c:  ldloc.2\n    IL_001d:  ldloc.1\n    IL_001e:  call       !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler>(!!0&,\n                                                                                                                          !!0,\n                                                                                                                          !!0)\n    IL_0023:  stloc.0\n    IL_0024:  ldloc.0\n    IL_0025:  ldloc.1\n    IL_0026:  bne.un.s   IL_0007\n\n    IL_0028:  ret\n  } // end of method NoPropertiesAndEvents::remove_MyEvent\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method NoPropertiesAndEvents::.ctor\n\n  .event [mscorlib]System.EventHandler MyEvent\n  {\n    .addon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::add_MyEvent(class [mscorlib]System.EventHandler)\n    .removeon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::remove_MyEvent(class [mscorlib]System.EventHandler)\n  } // end of event NoPropertiesAndEvents::MyEvent\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.opt.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmp8F9\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmp8F9.tmp\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents\n       extends [mscorlib]System.Object\n{\n  .field private class [mscorlib]System.EventHandler MyEvent\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n  .method public hidebysig specialname instance void \n          add_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       41 (0x29)\n    .maxstack  3\n    .locals init (class [mscorlib]System.EventHandler V_0,\n             class [mscorlib]System.EventHandler V_1,\n             class [mscorlib]System.EventHandler V_2)\n    IL_0000:  ldarg.0\n    IL_0001:  ldfld      class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_0006:  stloc.0\n    IL_0007:  ldloc.0\n    IL_0008:  stloc.1\n    IL_0009:  ldloc.1\n    IL_000a:  ldarg.1\n    IL_000b:  call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate,\n                                                                                            class [mscorlib]System.Delegate)\n    IL_0010:  castclass  [mscorlib]System.EventHandler\n    IL_0015:  stloc.2\n    IL_0016:  ldarg.0\n    IL_0017:  ldflda     class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_001c:  ldloc.2\n    IL_001d:  ldloc.1\n    IL_001e:  call       !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler>(!!0&,\n                                                                                                                          !!0,\n                                                                                                                          !!0)\n    IL_0023:  stloc.0\n    IL_0024:  ldloc.0\n    IL_0025:  ldloc.1\n    IL_0026:  bne.un.s   IL_0007\n\n    IL_0028:  ret\n  } // end of method NoPropertiesAndEvents::add_MyEvent\n\n  .method public hidebysig specialname instance void \n          remove_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       41 (0x29)\n    .maxstack  3\n    .locals init (class [mscorlib]System.EventHandler V_0,\n             class [mscorlib]System.EventHandler V_1,\n             class [mscorlib]System.EventHandler V_2)\n    IL_0000:  ldarg.0\n    IL_0001:  ldfld      class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_0006:  stloc.0\n    IL_0007:  ldloc.0\n    IL_0008:  stloc.1\n    IL_0009:  ldloc.1\n    IL_000a:  ldarg.1\n    IL_000b:  call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate,\n                                                                                           class [mscorlib]System.Delegate)\n    IL_0010:  castclass  [mscorlib]System.EventHandler\n    IL_0015:  stloc.2\n    IL_0016:  ldarg.0\n    IL_0017:  ldflda     class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_001c:  ldloc.2\n    IL_001d:  ldloc.1\n    IL_001e:  call       !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler>(!!0&,\n                                                                                                                          !!0,\n                                                                                                                          !!0)\n    IL_0023:  stloc.0\n    IL_0024:  ldloc.0\n    IL_0025:  ldloc.1\n    IL_0026:  bne.un.s   IL_0007\n\n    IL_0028:  ret\n  } // end of method NoPropertiesAndEvents::remove_MyEvent\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       7 (0x7)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  ret\n  } // end of method NoPropertiesAndEvents::.ctor\n\n  .event [mscorlib]System.EventHandler MyEvent\n  {\n    .addon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::add_MyEvent(class [mscorlib]System.EventHandler)\n    .removeon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::remove_MyEvent(class [mscorlib]System.EventHandler)\n  } // end of event NoPropertiesAndEvents::MyEvent\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoPropertiesAndEvents.roslyn.il",
    "content": "\n\n\n\n// Metadata version: v4.0.30319\n.assembly extern mscorlib\n{\n  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\\V.4..\n  .ver 4:0:0:0\n}\n.assembly tmp8F8\n{\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) \n  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx\n                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.\n\n  // --- The following custom attribute is added automatically, do not uncomment -------\n  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) \n\n  .permissionset reqmin\n             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}\n  .hash algorithm 0x00008004\n  .ver 0:0:0:0\n}\n.module tmp8F8.tmp\n.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) \n.imagebase 0x10000000\n.file alignment 0x00000200\n.stackreserve 0x00100000\n.subsystem 0x0003       // WINDOWS_CUI\n.corflags 0x00000001    //  ILONLY\n\n\n// =============== CLASS MEMBERS DECLARATION ===================\n\n.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents\n       extends [mscorlib]System.Object\n{\n  .field private class [mscorlib]System.EventHandler MyEvent\n  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n  .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) \n  .method public hidebysig specialname instance void \n          add_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       41 (0x29)\n    .maxstack  3\n    .locals init (class [mscorlib]System.EventHandler V_0,\n             class [mscorlib]System.EventHandler V_1,\n             class [mscorlib]System.EventHandler V_2)\n    IL_0000:  ldarg.0\n    IL_0001:  ldfld      class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_0006:  stloc.0\n    IL_0007:  ldloc.0\n    IL_0008:  stloc.1\n    IL_0009:  ldloc.1\n    IL_000a:  ldarg.1\n    IL_000b:  call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate,\n                                                                                            class [mscorlib]System.Delegate)\n    IL_0010:  castclass  [mscorlib]System.EventHandler\n    IL_0015:  stloc.2\n    IL_0016:  ldarg.0\n    IL_0017:  ldflda     class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_001c:  ldloc.2\n    IL_001d:  ldloc.1\n    IL_001e:  call       !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler>(!!0&,\n                                                                                                                          !!0,\n                                                                                                                          !!0)\n    IL_0023:  stloc.0\n    IL_0024:  ldloc.0\n    IL_0025:  ldloc.1\n    IL_0026:  bne.un.s   IL_0007\n\n    IL_0028:  ret\n  } // end of method NoPropertiesAndEvents::add_MyEvent\n\n  .method public hidebysig specialname instance void \n          remove_MyEvent(class [mscorlib]System.EventHandler 'value') cil managed\n  {\n    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) \n    // Code size       41 (0x29)\n    .maxstack  3\n    .locals init (class [mscorlib]System.EventHandler V_0,\n             class [mscorlib]System.EventHandler V_1,\n             class [mscorlib]System.EventHandler V_2)\n    IL_0000:  ldarg.0\n    IL_0001:  ldfld      class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_0006:  stloc.0\n    IL_0007:  ldloc.0\n    IL_0008:  stloc.1\n    IL_0009:  ldloc.1\n    IL_000a:  ldarg.1\n    IL_000b:  call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate,\n                                                                                           class [mscorlib]System.Delegate)\n    IL_0010:  castclass  [mscorlib]System.EventHandler\n    IL_0015:  stloc.2\n    IL_0016:  ldarg.0\n    IL_0017:  ldflda     class [mscorlib]System.EventHandler ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::MyEvent\n    IL_001c:  ldloc.2\n    IL_001d:  ldloc.1\n    IL_001e:  call       !!0 [mscorlib]System.Threading.Interlocked::CompareExchange<class [mscorlib]System.EventHandler>(!!0&,\n                                                                                                                          !!0,\n                                                                                                                          !!0)\n    IL_0023:  stloc.0\n    IL_0024:  ldloc.0\n    IL_0025:  ldloc.1\n    IL_0026:  bne.un.s   IL_0007\n\n    IL_0028:  ret\n  } // end of method NoPropertiesAndEvents::remove_MyEvent\n\n  .method public hidebysig specialname rtspecialname \n          instance void  .ctor() cil managed\n  {\n    // Code size       8 (0x8)\n    .maxstack  8\n    IL_0000:  ldarg.0\n    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()\n    IL_0006:  nop\n    IL_0007:  ret\n  } // end of method NoPropertiesAndEvents::.ctor\n\n  .event [mscorlib]System.EventHandler MyEvent\n  {\n    .addon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::add_MyEvent(class [mscorlib]System.EventHandler)\n    .removeon instance void ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents::remove_MyEvent(class [mscorlib]System.EventHandler)\n  } // end of event NoPropertiesAndEvents::MyEvent\n} // end of class ICSharpCode.Decompiler.Tests.TestCases.Ugly.NoPropertiesAndEvents\n\n\n// =============================================================\n\n// *********** DISASSEMBLY COMPLETE ***********************\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/VBPretty/.gitignore",
    "content": "/*.dll\n/*.exe\n/*.pdb"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/VBPretty/Async.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\n\nusing Microsoft.VisualBasic.CompilerServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.VBPretty\n{\n\tpublic class Async\n\t{\n\t\tprivate int memberField;\n\n\t\tprivate static bool True()\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic async void SimpleVoidMethod()\n\t\t{\n\t\t\tConsole.WriteLine(\"Before\");\n\t\t\tawait Task.Delay(TimeSpan.FromSeconds(1.0));\n\t\t\tConsole.WriteLine(\"After\");\n\t\t}\n\n\t\tpublic async void VoidMethodWithoutAwait()\n\t\t{\n\t\t\tConsole.WriteLine(\"No Await\");\n\t\t}\n\n\t\tpublic async void EmptyVoidMethod()\n\t\t{\n\t\t}\n\n\t\tpublic async void AwaitYield()\n\t\t{\n\t\t\tawait Task.Yield();\n\t\t}\n\n\t\tpublic async void AwaitDefaultYieldAwaitable()\n\t\t{\n#if LEGACY_VBC || (OPTIMIZE && !ROSLYN4)\n\t\t\tYieldAwaitable yieldAwaitable2 = default(YieldAwaitable);\n\t\t\tYieldAwaitable yieldAwaitable = yieldAwaitable2;\n\t\t\tawait yieldAwaitable;\n#else\n\t\t\tawait default(YieldAwaitable);\n#endif\n\t\t}\n\n\t\tpublic async void AwaitDefaultHopToThreadPool()\n\t\t{\n#if LEGACY_VBC || (OPTIMIZE && !ROSLYN4)\n\t\t\tHopToThreadPoolAwaitable hopToThreadPoolAwaitable2 = default(HopToThreadPoolAwaitable);\n\t\t\tHopToThreadPoolAwaitable hopToThreadPoolAwaitable = hopToThreadPoolAwaitable2;\n\t\t\tawait hopToThreadPoolAwaitable;\n#else\n\t\t\tawait default(HopToThreadPoolAwaitable);\n#endif\n\t\t}\n\n\t\tpublic async Task SimpleVoidTaskMethod()\n\t\t{\n\t\t\tConsole.WriteLine(\"Before\");\n\t\t\tawait Task.Delay(TimeSpan.FromSeconds(1.0));\n\t\t\tConsole.WriteLine(\"After\");\n\t\t}\n\n\t\tpublic async Task TaskMethodWithoutAwait()\n\t\t{\n\t\t\tConsole.WriteLine(\"No Await\");\n\t\t}\n\n\t\tpublic async Task CapturingThis()\n\t\t{\n\t\t\tawait Task.Delay(memberField);\n\t\t}\n\n\t\tpublic async Task CapturingThisWithoutAwait()\n\t\t{\n\t\t\tConsole.WriteLine(memberField);\n\t\t}\n\n\t\tpublic async Task<bool> SimpleBoolTaskMethod()\n\t\t{\n\t\t\tConsole.WriteLine(\"Before\");\n\t\t\tawait Task.Delay(TimeSpan.FromSeconds(1.0));\n\t\t\tConsole.WriteLine(\"After\");\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic async void TwoAwaitsWithDifferentAwaiterTypes()\n\t\t{\n\t\t\tConsole.WriteLine(\"Before\");\n\t\t\tif (await SimpleBoolTaskMethod())\n\t\t\t{\n\t\t\t\tawait Task.Delay(TimeSpan.FromSeconds(1.0));\n\t\t\t}\n\t\t\tConsole.WriteLine(\"After\");\n\t\t}\n\n\t\tpublic async void AwaitInLoopCondition()\n\t\t{\n\t\t\twhile (await SimpleBoolTaskMethod())\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Body\");\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task Issue2366a()\n\t\t{\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tawait Task.CompletedTask;\n\t\t\t\t}\n\t\t\t\tcatch (Exception projectError)\n\t\t\t\t{\n\t\t\t\t\tProjectData.SetProjectError(projectError);\n\t\t\t\t\tProjectData.ClearProjectError();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static async Task<int> GetIntegerSumAsync(IEnumerable<int> items)\n\t\t{\n\t\t\tawait Task.Delay(100);\n\t\t\tint num = 0;\n\t\t\tforeach (int item in items)\n\t\t\t{\n\t\t\t\tnum = checked(num + item);\n\t\t\t}\n\t\t\treturn num;\n\t\t}\n\n\t\tpublic async Task AsyncCatch(bool b, Task<int> task1, Task<int> task2)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Start try\");\n\t\t\t\tawait task1;\n\t\t\t\tConsole.WriteLine(\"End try\");\n\t\t\t}\n\t\t\tcatch (Exception projectError)\n\t\t\t{\n\t\t\t\tProjectData.SetProjectError(projectError);\n\t\t\t\tConsole.WriteLine(\"No await\");\n\t\t\t\tProjectData.ClearProjectError();\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task AsyncCatchThrow(bool b, Task<int> task1, Task<int> task2)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Start try\");\n\t\t\t\tawait task1;\n\t\t\t\tConsole.WriteLine(\"End try\");\n\t\t\t}\n\t\t\tcatch (Exception projectError)\n\t\t\t{\n\t\t\t\tProjectData.SetProjectError(projectError);\n\t\t\t\tConsole.WriteLine(\"No await\");\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task AsyncFinally(bool b, Task<int> task1, Task<int> task2)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Start try\");\n\t\t\t\tawait task1;\n\t\t\t\tConsole.WriteLine(\"End try\");\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"No await\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static async Task AlwaysThrow()\n\t\t{\n\t\t\tthrow new Exception();\n\t\t}\n\n\t\tpublic static async Task InfiniteLoop()\n\t\t{\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\tpublic static async Task InfiniteLoopWithAwait()\n\t\t{\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tawait Task.Delay(10);\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task AsyncWithLocalVar()\n\t\t{\n\t\t\tobject objectValue = RuntimeHelpers.GetObjectValue(new object());\n\t\t\tawait UseObj(RuntimeHelpers.GetObjectValue(objectValue));\n\t\t\tawait UseObj(RuntimeHelpers.GetObjectValue(objectValue));\n\t\t}\n\n\t\tpublic static async Task UseObj(object a)\n\t\t{\n\t\t}\n\t}\n\n\tpublic struct AsyncInStruct\n\t{\n\t\tprivate int i;\n\n\t\tpublic async Task<int> Test(AsyncInStruct xx)\n\t\t{\n\t\t\tchecked\n\t\t\t{\n\t\t\t\txx.i++;\n\t\t\t\ti++;\n\t\t\t\tawait Task.Yield();\n\t\t\t\treturn i + xx.i;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic struct HopToThreadPoolAwaitable : INotifyCompletion\n\t{\n\t\tpublic bool IsCompleted { get; set; }\n\n\t\tpublic HopToThreadPoolAwaitable GetAwaiter()\n\t\t{\n\t\t\treturn this;\n\t\t}\n\n\t\tpublic void OnCompleted(Action continuation)\n\t\t{\n\t\t\tTask.Run(continuation);\n\t\t}\n\n\t\tvoid INotifyCompletion.OnCompleted(Action continuation)\n\t\t{\n\t\t\t//ILSpy generated this explicit interface implementation from .override directive in OnCompleted\n\t\t\tthis.OnCompleted(continuation);\n\t\t}\n\n\t\tpublic void GetResult()\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/VBPretty/Async.vb",
    "content": "Imports System\nImports System.Collections.Generic\nImports System.Threading.Tasks\nImports System.Runtime.CompilerServices\n\nNamespace ICSharpCode.Decompiler.Tests.TestCases.VBPretty\n\tPublic Class Async\n\t\tPrivate memberField As Integer\n\n\t\tPrivate Shared Function [True]() As Boolean\n\t        Return True\n\t    End Function\n\n\t    Public Async Sub SimpleVoidMethod()\n\t        Console.WriteLine(\"Before\")\n\t        Await Task.Delay(TimeSpan.FromSeconds(1.0))\n\t        Console.WriteLine(\"After\")\n\t    End Sub\n\n\t    Public Async Sub VoidMethodWithoutAwait()\n\t        Console.WriteLine(\"No Await\")\n\t    End Sub\n\n\t    Public Async Sub EmptyVoidMethod()\n\t    End Sub\n\n\t    Public Async Sub AwaitYield()\n\t        Await Task.Yield()\n\t    End Sub\n\n\t    Public Async Sub AwaitDefaultYieldAwaitable()\n\t        Await CType(Nothing, YieldAwaitable)\n\t    End Sub\n\n\t\tPublic Async Sub AwaitDefaultHopToThreadPool()\n\t\t\t' unlike YieldAwaitable which implements ICriticalNotifyCompletion,\n\t\t\t' the HopToThreadPoolAwaitable struct only implements\n\t\t\t' INotifyCompletion, so this results in different codegen\n\t\t\tAwait CType(Nothing, HopToThreadPoolAwaitable)\n\t\tEnd Sub\n\n\t    Public Async Function SimpleVoidTaskMethod() As Task\n\t        Console.WriteLine(\"Before\")\n\t        Await Task.Delay(TimeSpan.FromSeconds(1.0))\n\t        Console.WriteLine(\"After\")\n\t    End Function\n\n\t    Public Async Function TaskMethodWithoutAwait() As Task\n\t        Console.WriteLine(\"No Await\")\n\t    End Function\n\n\t    Public Async Function CapturingThis() As Task\n\t        Await Task.Delay(memberField)\n\t    End Function\n\n\t    Public Async Function CapturingThisWithoutAwait() As Task\n\t        Console.WriteLine(memberField)\n\t    End Function\n\n\t    Public Async Function SimpleBoolTaskMethod() As Task(Of Boolean)\n\t        Console.WriteLine(\"Before\")\n\t        Await Task.Delay(TimeSpan.FromSeconds(1.0))\n\t        Console.WriteLine(\"After\")\n\t        Return True\n\t    End Function\n\n\t    Public Async Sub TwoAwaitsWithDifferentAwaiterTypes()\n\t        Console.WriteLine(\"Before\")\n\t        If Await SimpleBoolTaskMethod() Then\n\t            Await Task.Delay(TimeSpan.FromSeconds(1.0))\n\t        End If\n\t        Console.WriteLine(\"After\")\n\t    End Sub\n\n\t    Public Async Sub AwaitInLoopCondition()\n\t        While Await SimpleBoolTaskMethod()\n\t            Console.WriteLine(\"Body\")\n\t        End While\n\t    End Sub\n\n\t\tPublic Async Function Issue2366a() As Task\n\t\t\tWhile True\n\t\t\t\tTry\n\t\t\t\t\tAwait Task.CompletedTask\n\t\t\t\tCatch\n\t\t\t\tEnd Try\n\t\t\tEnd While\n\t\tEnd Function\n\n\t    Public Shared Async Function GetIntegerSumAsync(ByVal items As IEnumerable(Of Integer)) As Task(Of Integer)\n\t        Await Task.Delay(100)\n\t        Dim num = 0\n\t        For Each item In items\n\t            num += item\n\t        Next\n\t        Return num\n\t    End Function\n\n\t\t Public Async Function AsyncCatch(ByVal b As Boolean, ByVal task1 As Task(Of Integer), ByVal task2 As Task(Of Integer)) As Task\n\t\t\t Try\n\t\t\t\t Console.WriteLine(\"Start try\")\n\t\t\t\t Await task1\n\t\t\t\t Console.WriteLine(\"End try\")\n\t\t\t Catch ex As Exception\n\t\t\t\t Console.WriteLine(\"No await\")\n\t\t\t End Try\n\t\t End Function\n\n\t\t Public Async Function AsyncCatchThrow(ByVal b As Boolean, ByVal task1 As Task(Of Integer), ByVal task2 As Task(Of Integer)) As Task\n\t\t\t Try\n\t\t\t\t Console.WriteLine(\"Start try\")\n\t\t\t\t Await task1\n\t\t\t\t Console.WriteLine(\"End try\")\n\t\t\t Catch ex As Exception\n\t\t\t\t Console.WriteLine(\"No await\")\n\t\t\t\t Throw\n\t\t\t End Try\n\t\t End Function\n\n\t\t Public Async Function AsyncFinally(ByVal b As Boolean, ByVal task1 As Task(Of Integer), ByVal task2 As Task(Of Integer)) As Task\n\t\t\t Try\n\t\t\t\t Console.WriteLine(\"Start try\")\n\t\t\t\t Await task1\n\t\t\t\t Console.WriteLine(\"End try\")\n\t\t\t Finally\n\t\t\t\t Console.WriteLine(\"No await\")\n\t\t\t End Try\n\t\t End Function\n\n\t    Public Shared Async Function AlwaysThrow() As Task\n\t    Throw New Exception\n\t    End Function\n\n\t    Public Shared Async Function InfiniteLoop() As Task\n\t        While True\n\t        End While\n\t    End Function\n\n\t    Public Shared Async Function InfiniteLoopWithAwait() As Task\n\t        While True\n\t            Await Task.Delay(10)\n\t        End While\n\t    End Function\n\n\t\tPublic Async Function AsyncWithLocalVar() As Task\n\t        Dim a As Object = New Object()\n\t        Await UseObj(a)\n\t        Await UseObj(a)\n\t    End Function\n\n\t    Public Shared Async Function UseObj(ByVal a As Object) As Task\n\t    End Function\n\tEnd Class\n\n\tPublic Structure AsyncInStruct\n\t\tPrivate i As Integer\n\n\t\tPublic Async Function Test(ByVal xx As AsyncInStruct) As Task(Of Integer)\n\t\t\txx.i += 1\n\t\t\ti += 1\n\t\t\tAwait Task.Yield()\n\t\t\tReturn i + xx.i\n\t\tEnd Function\n\tEnd Structure\n\n\tPublic Structure HopToThreadPoolAwaitable\n\t\tImplements INotifyCompletion\n\t\tPublic Property IsCompleted As Boolean\n\n\t\tPublic Function GetAwaiter() As HopToThreadPoolAwaitable\n\t\t\tReturn Me\n\t\tEnd Function\n\n\t\tPublic Sub OnCompleted(ByVal continuation As Action) Implements INotifyCompletion.OnCompleted\n\t\t\tTask.Run(continuation)\n\t\tEnd Sub\n\n\t\tPublic Sub GetResult()\n\t\tEnd Sub\n\tEnd Structure\nEnd Namespace\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/VBPretty/Issue1906.cs",
    "content": "using System;\n\npublic class Issue1906\n{\n\tpublic void M()\n\t{\n\t\tConsole.WriteLine(Math.Min(Math.Max(long.MinValue, default(long)), long.MaxValue));\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/VBPretty/Issue1906.vb",
    "content": "Imports System\nPublic Class Issue1906\n\tPublic Sub M()\n\t\tConsole.WriteLine(Math.Min(Math.Max(Int64.MinValue, New Long), Int64.MaxValue))\n\tEnd Sub\nEnd Class"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/VBPretty/Issue2192.cs",
    "content": "using System;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\n\npublic class Issue2192\n{\n\tpublic static void M()\n\t{\n\t\tstring[] source = new string[3] { \"abc\", \"defgh\", \"ijklm\" };\n\t\tstring text = \"test\";\n\t\tConsole.WriteLine(source.Count([SpecialName] (string w) => w.Length > text.Length));\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/VBPretty/Issue2192.vb",
    "content": "Imports System\nImports System.Linq\nPublic Class Issue2192\n\tPublic Shared Sub M()\n\t\tDim words As String() = {\"abc\", \"defgh\", \"ijklm\"}\n\t\tDim word As String = \"test\"\n\t\tConsole.WriteLine(words.Count(Function(w) w.Length > word.Length))\n\tEnd Sub\nEnd Class"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/VBPretty/Select.cs",
    "content": "using System;\n\nusing Microsoft.VisualBasic.CompilerServices;\n\n[StandardModule]\ninternal sealed class Program\n{\n\tpublic static void SelectOnString()\n\t{\n\t\tswitch (Environment.CommandLine)\n\t\t{\n\t\t\tcase \"123\":\n\t\t\t\tConsole.WriteLine(\"a\");\n\t\t\t\tbreak;\n\t\t\tcase \"444\":\n\t\t\t\tConsole.WriteLine(\"b\");\n\t\t\t\tbreak;\n\t\t\tcase \"222\":\n\t\t\t\tConsole.WriteLine(\"c\");\n\t\t\t\tbreak;\n\t\t\tcase \"11\":\n\t\t\t\tConsole.WriteLine(\"d\");\n\t\t\t\tbreak;\n\t\t\tcase \"dd\":\n\t\t\t\tConsole.WriteLine(\"e\");\n\t\t\t\tbreak;\n\t\t\tcase \"sss\":\n\t\t\t\tConsole.WriteLine(\"f\");\n\t\t\t\tbreak;\n\t\t\tcase \"aa\":\n\t\t\t\tConsole.WriteLine(\"g\");\n\t\t\t\tbreak;\n\t\t\tcase null:\n\t\t\tcase \"\":\n\t\t\t\tConsole.WriteLine(\"empty\");\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/VBPretty/Select.vb",
    "content": "Imports System\n\nModule Program\n\tSub SelectOnString()\n\t\tSelect Case Environment.CommandLine\n\t\t\tCase \"123\"\n\t\t\t\tConsole.WriteLine(\"a\")\n\t\t\tCase \"444\"\n\t\t\t\tConsole.WriteLine(\"b\")\n\t\t\tCase \"222\"\n\t\t\t\tConsole.WriteLine(\"c\")\n\t\t\tCase \"11\"\n\t\t\t\tConsole.WriteLine(\"d\")\n\t\t\tCase \"dd\"\n\t\t\t\tConsole.WriteLine(\"e\")\n\t\t\tCase \"sss\"\n\t\t\t\tConsole.WriteLine(\"f\")\n\t\t\tCase \"aa\"\n\t\t\t\tConsole.WriteLine(\"g\")\n\t\t\tCase \"\"\n\t\t\t\tConsole.WriteLine(\"empty\")\n\t\tEnd Select\n\tEnd Sub\nEnd Module\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBAutomaticEvents.cs",
    "content": "public class VBAutomaticEvents\n{\n\tpublic delegate void EventWithParameterEventHandler(int EventNumber);\n\tpublic delegate void EventWithoutParameterEventHandler();\n\n\tpublic event EventWithParameterEventHandler EventWithParameter;\n\tpublic event EventWithoutParameterEventHandler EventWithoutParameter;\n\n\tpublic void RaiseEvents()\n\t{\n\t\tEventWithParameter?.Invoke(1);\n\t\tEventWithoutParameter?.Invoke();\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBAutomaticEvents.vb",
    "content": "Public Class VBAutomaticEvents\n\tEvent EventWithParameter(ByVal EventNumber As Integer)\n\tEvent EventWithoutParameter()\n\n\tSub RaiseEvents()\n\t\tRaiseEvent EventWithParameter(1)\n\t\tRaiseEvent EventWithoutParameter()\n\tEnd Sub\nEnd Class\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBCompoundAssign.cs",
    "content": "using Microsoft.VisualBasic;\nusing Microsoft.VisualBasic.CompilerServices;\n\n[StandardModule]\ninternal sealed class VBCompoundAssign\n{\n\tpublic static double[] Sum3(int[] v)\n\t{\n\t\tdouble[] array = new double[4];\n\t\tint num = Information.UBound(v);\n\t\tchecked\n\t\t{\n\t\t\tfor (int i = 0; i <= num; i += 3)\n\t\t\t{\n\t\t\t\tarray[0] += v[i];\n\t\t\t\tarray[1] += v[i + 1];\n\t\t\t\tarray[2] += v[i + 2];\n\t\t\t}\n\t\t\treturn array;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBCompoundAssign.vb",
    "content": "Imports System\nImports Microsoft.VisualBasic\n\nModule VBCompoundAssign\n    Function Sum3(v As Int32()) As Double()\n        Dim arr(3) As Double\n        For i = 0 To UBound(v) Step 3\n            arr(0) += v(i)\n            arr(1) += v(i + 1)\n            arr(2) += v(i + 2)\n        Next\n        Return arr\n    End Function\nEnd Module\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBNonGenericForEach.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Runtime.CompilerServices;\n\npublic class VBNonGenericForEach\n{\n\tpublic static void M()\n\t{\n\t\tArrayList arrayList = new ArrayList();\n\t\tforeach (object item in arrayList)\n\t\t{\n#if ROSLYN && OPT\n\t\t\tConsole.WriteLine(RuntimeHelpers.GetObjectValue(RuntimeHelpers.GetObjectValue(item)));\n#else\n\t\t\tobject objectValue = RuntimeHelpers.GetObjectValue(item);\n\t\t\tConsole.WriteLine(RuntimeHelpers.GetObjectValue(objectValue));\n#endif\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBNonGenericForEach.vb",
    "content": "Imports System\nImports System.Collections\n\nPublic Class VBNonGenericForEach\n\tPublic Shared Sub M()\n\t\tDim collection = New ArrayList\n\t\tFor Each element In collection\n\t\t\tConsole.WriteLine(element)\n\t\tNext\n\tEnd Sub\nEnd Class\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBPropertiesTest.cs",
    "content": "using System;\n\npublic class VBPropertiesTest\n{\n\tprivate int _fullProperty;\n\n\tpublic int FullProperty {\n\t\tget {\n\t\t\treturn _fullProperty;\n\t\t}\n\t\tset {\n\t\t\t_fullProperty = value;\n\t\t}\n\t}\n\n\tpublic int AutoProperty { get; set; }\n\n#if ROSLYN\n\tpublic int ReadOnlyAutoProperty { get; }\n\tpublic VBPropertiesTest()\n\t{\n\t\tReadOnlyAutoProperty = 32;\n\t}\n#endif\n\n\tpublic void TestMethod()\n\t{\n\t\tFullProperty = 42;\n\t\t_fullProperty = 24;\n\t\tAutoProperty = 4711;\n\n\t\tConsole.WriteLine(AutoProperty);\n\t\tConsole.WriteLine(_fullProperty);\n\t\tConsole.WriteLine(FullProperty);\n#if ROSLYN\n\t\tConsole.WriteLine(ReadOnlyAutoProperty);\n#endif\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/VBPretty/VBPropertiesTest.vb",
    "content": "Imports System\nPublic Class VBPropertiesTest\n\tPrivate _fullProperty As Integer\n\n\tProperty FullProperty As Integer\n\t\tGet\n\t\t\tReturn _fullProperty\n\t\tEnd Get\n\t\tSet(value As Integer)\n\t\t\t_fullProperty = value\n\t\tEnd Set\n\tEnd Property\n\n\tProperty AutoProperty As Integer\n\n#If ROSLYN Then\n\tReadOnly Property ReadOnlyAutoProperty As Integer\n\n\tSub New()\n\t\tMe.ReadOnlyAutoProperty = 32\n\tEnd Sub\n#End If\n\n\tSub TestMethod()\n\t\tMe.FullProperty = 42\n\t\tMe._fullProperty = 24\n\t\tMe.AutoProperty = 4711\n\n\t\tConsole.WriteLine(Me.AutoProperty)\n\t\tConsole.WriteLine(Me._fullProperty)\n\t\tConsole.WriteLine(Me.FullProperty)\n\n#If ROSLYN Then\n\t\tConsole.WriteLine(Me.ReadOnlyAutoProperty)\n#End If\n\tEnd Sub\nEnd Class"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/VBPretty/YieldReturn.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nusing Microsoft.VisualBasic.CompilerServices;\n\nnamespace ICSharpCode.Decompiler.Tests.TestCases.VBPretty\n{\n\tinternal struct StructWithYieldReturn\n\t{\n\t\tprivate int val;\n\n\t\tpublic IEnumerable<int> Count()\n\t\t{\n\t\t\tyield return val;\n\t\t\tyield return val;\n\t\t}\n\t}\n\n\tpublic class YieldReturnPrettyTest\n\t{\n\t\tprivate int fieldOnThis;\n\n\t\tpublic static IEnumerable<char> YieldChars {\n\t\t\tget {\n\t\t\t\tyield return 'a';\n\t\t\t\tyield return 'b';\n\t\t\t\tyield return 'c';\n\t\t\t}\n\t\t}\n\n\t\tinternal static void Print<T>(string name, IEnumerator<T> enumerator)\n\t\t{\n\t\t\tConsole.WriteLine(name + \": Test start\");\n\t\t\twhile (enumerator.MoveNext())\n\t\t\t{\n\t\t\t\tConsole.WriteLine(name + \": \" + enumerator.Current.ToString());\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<string> SimpleYieldReturn()\n\t\t{\n\t\t\tyield return \"A\";\n\t\t\tyield return \"B\";\n\t\t\tyield return \"C\";\n\t\t}\n\n\t\tpublic static IEnumerator<string> SimpleYieldReturnEnumerator()\n\t\t{\n\t\t\tyield return \"A\";\n\t\t\tyield return \"B\";\n\t\t\tyield return \"C\";\n\t\t}\n\n\t\tpublic IEnumerable<int> YieldReturnParameters(int p)\n\t\t{\n\t\t\tyield return p;\n\t\t\tyield return fieldOnThis;\n\t\t}\n\n\t\tpublic IEnumerator<int> YieldReturnParametersEnumerator(int p)\n\t\t{\n\t\t\tyield return p;\n\t\t\tyield return fieldOnThis;\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldReturnInLoop()\n\t\t{\n\t\t\tint num = 0;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tyield return num;\n\t\t\t\tnum = checked(num + 1);\n\t\t\t} while (num <= 99);\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldReturnWithTryFinally()\n\t\t{\n\t\t\tyield return 0;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 1;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally!\");\n\t\t\t}\n\t\t\tyield return 2;\n\t\t}\n\n\t\tpublic static IEnumerable<string> YieldReturnWithNestedTryFinally(bool breakInMiddle)\n\t\t{\n\t\t\tConsole.WriteLine(\"Start of method - 1\");\n\t\t\tyield return \"Start of method\";\n\t\t\tConsole.WriteLine(\"Start of method - 2\");\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Within outer try - 1\");\n\t\t\t\tyield return \"Within outer try\";\n\t\t\t\tConsole.WriteLine(\"Within outer try - 2\");\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Within inner try - 1\");\n\t\t\t\t\tyield return \"Within inner try\";\n\t\t\t\t\tConsole.WriteLine(\"Within inner try - 2\");\n\t\t\t\t\tif (breakInMiddle)\n\t\t\t\t\t{\n\t\t\t\t\t\tConsole.WriteLine(\"Breaking...\");\n\t\t\t\t\t\tyield break;\n\t\t\t\t\t}\n\t\t\t\t\tConsole.WriteLine(\"End of inner try - 1\");\n\t\t\t\t\tyield return \"End of inner try\";\n\t\t\t\t\tConsole.WriteLine(\"End of inner try - 2\");\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Inner Finally\");\n\t\t\t\t}\n\t\t\t\tConsole.WriteLine(\"End of outer try - 1\");\n\t\t\t\tyield return \"End of outer try\";\n\t\t\t\tConsole.WriteLine(\"End of outer try - 2\");\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Outer Finally\");\n\t\t\t}\n\t\t\tConsole.WriteLine(\"End of method - 1\");\n\t\t\tyield return \"End of method\";\n\t\t\tConsole.WriteLine(\"End of method - 2\");\n\t\t}\n\n\t\tpublic static IEnumerable<string> YieldReturnWithTwoNonNestedFinallyBlocks(IEnumerable<string> input)\n\t\t{\n\t\t\t// outer try-finally block\n\t\t\tforeach (string item in input)\n\t\t\t{\n\t\t\t\t// nested try-finally block\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tyield return item;\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Processed \" + item);\n\t\t\t\t}\n\t\t\t}\n\t\t\tyield return \"A\";\n\t\t\tyield return \"B\";\n\t\t\tyield return \"C\";\n\t\t\tyield return \"D\";\n\t\t\tyield return \"E\";\n\t\t\tyield return \"F\";\n\t\t\t// outer try-finally block\n\t\t\tforeach (string item2 in input)\n\t\t\t{\n\t\t\t\tyield return item2.ToUpper();\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> GetEvenNumbers(int n)\n\t\t{\n\t\t\tint num = checked(n - 1);\n\t\t\tfor (int i = 0; i <= num; i = checked(i + 1))\n\t\t\t{\n\t\t\t\tif (i % 2 == 0)\n\t\t\t\t{\n\t\t\t\t\tyield return i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<char> ExceptionHandling()\n\t\t{\n\t\t\tyield return 'a';\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"1 - try\");\n\t\t\t}\n\t\t\tcatch (Exception projectError)\n\t\t\t{\n\t\t\t\tProjectData.SetProjectError(projectError);\n\t\t\t\tConsole.WriteLine(\"1 - catch\");\n\t\t\t\tProjectData.ClearProjectError();\n\t\t\t}\n\t\t\tyield return 'b';\n\t\t\ttry\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"2 - try\");\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"2 - finally\");\n\t\t\t\t}\n\t\t\t\tyield return 'c';\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"outer finally\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldBreakInCatch()\n\t\t{\n\t\t\tyield return 0;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"In Try\");\n\t\t\t}\n\t\t\tcatch (Exception projectError)\n\t\t\t{\n\t\t\t\tProjectData.SetProjectError(projectError);\n\t\t\t\tProjectData.ClearProjectError();\n\t\t\t\t// yield return is not allowed in catch, but yield break is\n\t\t\t\tyield break;\n\t\t\t}\n\t\t\tyield return 1;\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldBreakInCatchInTryFinally()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 0;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"In Try\");\n\t\t\t\t}\n\t\t\t\tcatch (Exception projectError)\n\t\t\t\t{\n\t\t\t\t\tProjectData.SetProjectError(projectError);\n\t\t\t\t\tProjectData.ClearProjectError();\n\t\t\t\t\t// yield return is not allowed in catch, but yield break is\n\t\t\t\t\t// Note that pre-roslyn, this code triggers a compiler bug:\n\t\t\t\t\t// If the finally block throws an exception, it ends up getting\n\t\t\t\t\t// called a second time.\n\t\t\t\t\tyield break;\n\t\t\t\t}\n\t\t\t\tyield return 1;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldBreakInTryCatchInTryFinally()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 0;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"In Try\");\n\t\t\t\t\t// same compiler bug as in YieldBreakInCatchInTryFinally\n\t\t\t\t\tyield break;\n\t\t\t\t}\n\t\t\t\tcatch (Exception projectError)\n\t\t\t\t{\n\t\t\t\t\tProjectData.SetProjectError(projectError);\n\t\t\t\t\tConsole.WriteLine(\"Catch\");\n\t\t\t\t\tProjectData.ClearProjectError();\n\t\t\t\t}\n\t\t\t\tyield return 1;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldBreakInTryFinallyInTryFinally(bool b)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 0;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"In Try\");\n\t\t\t\t\tif (b)\n\t\t\t\t\t{\n\t\t\t\t\t\t// same compiler bug as in YieldBreakInCatchInTryFinally\n\t\t\t\t\t\tyield break;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Inner Finally\");\n\t\t\t\t}\n\t\t\t\tyield return 1;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> YieldBreakOnly()\n\t\t{\n\t\t\tyield break;\n\t\t}\n\n\t\tpublic static IEnumerable<int> UnconditionalThrowInTryFinally()\n\t\t{\n\t\t\t// Here, MoveNext() doesn't call the finally methods at all\n\t\t\t// (only indirectly via Dispose())\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 0;\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Finally\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<int> NestedTryFinallyStartingOnSamePosition()\n\t\t{\n\t\t\t// The first user IL instruction is already in 2 nested try blocks.\n#if ((ROSLYN2 && !ROSLYN4) && OPT)\n\t\t\tint num = -1;\n#endif\n\t\t\ttry\n\t\t\t{\n#if ((ROSLYN2 && !ROSLYN4) && OPT)\n\t\t\t\t_ = num - 1;\n#endif\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tyield return 0;\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tConsole.WriteLine(\"Inner Finally\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"Outer Finally\");\n\t\t\t}\n\t\t}\n\n#if ROSLYN\n\t\tpublic static IEnumerable<int> LocalInFinally<T>(T a) where T : IDisposable\n\t\t{\n\t\t\tyield return 1;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tyield return 2;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tT val = a;\n\t\t\t\tval.Dispose();\n\t\t\t\tval.Dispose();\n\t\t\t}\n\t\t\tyield return 3;\n\t\t}\n#endif\n\n\t\tpublic static IEnumerable<T> GenericYield<T>() where T : new()\n\t\t{\n\t\t\tT val = new T();\n\t\t\tint num = 0;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tyield return val;\n\t\t\t\tnum = checked(num + 1);\n\t\t\t} while (num <= 2);\n\t\t}\n\n\t\tpublic static IEnumerable<int> MultipleYieldBreakInTryFinally(int i)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (i == 2)\n\t\t\t\t{\n\t\t\t\t\tyield break;\n\t\t\t\t}\n\n\t\t\t\twhile (i < 40)\n\t\t\t\t{\n\t\t\t\t\tif (i % 2 == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tyield break;\n\t\t\t\t\t}\n\t\t\t\t\ti = checked(i + 1);\n\n\t\t\t\t\tyield return i;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tConsole.WriteLine(\"finally\");\n\t\t\t}\n\t\t\tConsole.WriteLine(\"normal exit\");\n\t\t}\n\n\t\tinternal IEnumerable<int> ForLoopWithYieldReturn(int end, int evil)\n\t\t{\n\t\t\t// This loop needs to pick the implicit \"yield break;\" as exit point\n\t\t\t// in order to produce pretty code; not the \"throw\" which would\n\t\t\t// be a less-pretty option.\n\t\t\tchecked\n\t\t\t{\n\t\t\t\tint num = end - 1;\n\t\t\t\tfor (int i = 0; i <= num; i++)\n\t\t\t\t{\n\t\t\t\t\tif (i == evil)\n\t\t\t\t\t{\n\t\t\t\t\t\tthrow new InvalidOperationException(\"Found evil number\");\n\t\t\t\t\t}\n\t\t\t\t\tyield return i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestCases/VBPretty/YieldReturn.vb",
    "content": "Imports System\nImports System.Collections.Generic\n\nNamespace ICSharpCode.Decompiler.Tests.TestCases.VBPretty\n\tFriend Structure StructWithYieldReturn\n\t\tPrivate val As Integer\n\n\t\tPublic Iterator Function Count() As IEnumerable(Of Integer)\n\t\t\tYield val\n\t\t\tYield val\n\t\tEnd Function\n\tEnd Structure\n\n\tPublic Class YieldReturnPrettyTest\n\t\tPrivate fieldOnThis As Integer\n\n\t\tPublic Shared ReadOnly Iterator Property YieldChars As IEnumerable(Of Char)\n\t\t\tGet\n\t\t\t\tYield \"a\"c\n\t\t\t\tYield \"b\"c\n\t\t\t\tYield \"c\"c\n\t\t\tEnd Get\n\t\tEnd Property\n\n\t\tFriend Shared Sub Print(Of T)(ByVal name As String, ByVal enumerator As IEnumerator(Of T))\n\t\t\tConsole.WriteLine(name + \": Test start\")\n\t\t\tWhile enumerator.MoveNext()\n\t\t\t\tConsole.WriteLine(name + \": \" + enumerator.Current.ToString())\n\t\t\tEnd While\n\t\tEnd Sub\n\n\t\tPublic Shared Iterator Function SimpleYieldReturn() As IEnumerable(Of String)\n\t\t\tYield \"A\"\n\t\t\tYield \"B\"\n\t\t\tYield \"C\"\n\t\tEnd Function\n\n\t\tPublic Shared Iterator Function SimpleYieldReturnEnumerator() As IEnumerator(Of String)\n\t\t\tYield \"A\"\n\t\t\tYield \"B\"\n\t\t\tYield \"C\"\n\t\tEnd Function\n\n\t\tPublic Iterator Function YieldReturnParameters(ByVal p As Integer) As IEnumerable(Of Integer)\n\t\t\tYield p\n\t\t\tYield fieldOnThis\n\t\tEnd Function\n\n\t\tPublic Iterator Function YieldReturnParametersEnumerator(ByVal p As Integer) As IEnumerator(Of Integer)\n\t\t\tYield p\n\t\t\tYield fieldOnThis\n\t\tEnd Function\n\n\t\tPublic Shared Iterator Function YieldReturnInLoop() As IEnumerable(Of Integer)\n\t\t\tFor i = 0 To 99\n\t\t\t\tYield i\n\t\t\tNext\n\t\tEnd Function\n\n\t\tPublic Shared Iterator Function YieldReturnWithTryFinally() As IEnumerable(Of Integer)\n\t\t\tYield 0\n\t\t\tTry\n\t\t\t\tYield 1\n\t\t\tFinally\n\t\t\t\tConsole.WriteLine(\"Finally!\")\n\t\t\tEnd Try\n\t\t\tYield 2\n\t\tEnd Function\n\n\t\tPublic Shared Iterator Function YieldReturnWithNestedTryFinally(ByVal breakInMiddle As Boolean) As IEnumerable(Of String)\n\t        Console.WriteLine(\"Start of method - 1\")\n\t        Yield \"Start of method\"\n\t        Console.WriteLine(\"Start of method - 2\")\n\t        Try\n\t            Console.WriteLine(\"Within outer try - 1\")\n\t            Yield \"Within outer try\"\n\t            Console.WriteLine(\"Within outer try - 2\")\n\t            Try\n\t                Console.WriteLine(\"Within inner try - 1\")\n\t                Yield \"Within inner try\"\n\t                Console.WriteLine(\"Within inner try - 2\")\n\t                If breakInMiddle Then\n\t                    Console.WriteLine(\"Breaking...\")\n\t                    Return\n\t                End If\n\t                Console.WriteLine(\"End of inner try - 1\")\n\t                Yield \"End of inner try\"\n\t                Console.WriteLine(\"End of inner try - 2\")\n\t            Finally\n\t                Console.WriteLine(\"Inner Finally\")\n\t            End Try\n\t            Console.WriteLine(\"End of outer try - 1\")\n\t            Yield \"End of outer try\"\n\t            Console.WriteLine(\"End of outer try - 2\")\n\t        Finally\n\t            Console.WriteLine(\"Outer Finally\")\n\t        End Try\n\t        Console.WriteLine(\"End of method - 1\")\n\t        Yield \"End of method\"\n\t        Console.WriteLine(\"End of method - 2\")\n\t    End Function\n\n\t    Public Shared Iterator Function YieldReturnWithTwoNonNestedFinallyBlocks(ByVal input As IEnumerable(Of String)) As IEnumerable(Of String)\n\t        ' outer try-finally block\n\t        For Each line In input\n\t            ' nested try-finally block\n\t            Try\n\t                Yield line\n\t            Finally\n\t                Console.WriteLine(\"Processed \" & line)\n\t            End Try\n\t        Next\n\t        Yield \"A\"\n\t        Yield \"B\"\n\t        Yield \"C\"\n\t        Yield \"D\"\n\t        Yield \"E\"\n\t        Yield \"F\"\n\t        ' outer try-finally block\n\t        For Each item In input\n\t            Yield item.ToUpper()\n\t        Next\n\t    End Function\n\n\t    Public Shared Iterator Function GetEvenNumbers(ByVal n As Integer) As IEnumerable(Of Integer)\n\t        For i = 0 To n - 1\n\t            If i Mod 2 = 0 Then\n\t                Yield i\n\t            End If\n\t        Next\n\t    End Function\n\n\t    Public Shared Iterator Function ExceptionHandling() As IEnumerable(Of Char)\n\t        Yield \"a\"c\n\t        Try\n\t            Console.WriteLine(\"1 - try\")\n\t        Catch __unusedException1__ As Exception\n\t            Console.WriteLine(\"1 - catch\")\n\t        End Try\n\t        Yield \"b\"c\n\t        Try\n\t            Try\n\t                Console.WriteLine(\"2 - try\")\n\t            Finally\n\t                Console.WriteLine(\"2 - finally\")\n\t            End Try\n\t            Yield \"c\"c\n\t        Finally\n\t            Console.WriteLine(\"outer finally\")\n\t        End Try\n\t    End Function\n\n\t    Public Shared Iterator Function YieldBreakInCatch() As IEnumerable(Of Integer)\n\t        Yield 0\n\t        Try\n\t            Console.WriteLine(\"In Try\")\n\t        Catch\n\t            ' yield return is not allowed in catch, but yield break is\n\t            Return\n\t        End Try\n\t        Yield 1\n\t    End Function\n\n\t    Public Shared Iterator Function YieldBreakInCatchInTryFinally() As IEnumerable(Of Integer)\n\t        Try\n\t            Yield 0\n\t            Try\n\t                Console.WriteLine(\"In Try\")\n\t            Catch\n\t                ' yield return is not allowed in catch, but yield break is\n\t                ' Note that pre-roslyn, this code triggers a compiler bug:\n\t                ' If the finally block throws an exception, it ends up getting\n\t                ' called a second time.\n\t                Return\n\t            End Try\n\t            Yield 1\n\t        Finally\n\t            Console.WriteLine(\"Finally\")\n\t        End Try\n\t    End Function\n\n\t    Public Shared Iterator Function YieldBreakInTryCatchInTryFinally() As IEnumerable(Of Integer)\n\t        Try\n\t            Yield 0\n\t            Try\n\t                Console.WriteLine(\"In Try\")\n\t                ' same compiler bug as in YieldBreakInCatchInTryFinally\n\t                Return\n\t            Catch\n\t                Console.WriteLine(\"Catch\")\n\t            End Try\n\t            Yield 1\n\t        Finally\n\t            Console.WriteLine(\"Finally\")\n\t        End Try\n\t    End Function\n\n\t    Public Shared Iterator Function YieldBreakInTryFinallyInTryFinally(ByVal b As Boolean) As IEnumerable(Of Integer)\n\t        Try\n\t            Yield 0\n\t            Try\n\t                Console.WriteLine(\"In Try\")\n\t                If b Then\n\t                    ' same compiler bug as in YieldBreakInCatchInTryFinally\n\t                    Return\n\t                End If\n\n\t            Finally\n\t                Console.WriteLine(\"Inner Finally\")\n\t            End Try\n\t            Yield 1\n\t        Finally\n\t            Console.WriteLine(\"Finally\")\n\t        End Try\n\t    End Function\n\n\t    Public Shared Iterator Function YieldBreakOnly() As IEnumerable(Of Integer)\n\t        Return\n\t    End Function\n\n\t    Public Shared Iterator Function UnconditionalThrowInTryFinally() As IEnumerable(Of Integer)\n\t        ' Here, MoveNext() doesn't call the finally methods at all\n\t        ' (only indirectly via Dispose())\n\t        Try\n\t            Yield 0\n\t            Throw New NotImplementedException()\n\t        Finally\n\t            Console.WriteLine(\"Finally\")\n\t        End Try\n\t    End Function\n\n\t    Public Shared Iterator Function NestedTryFinallyStartingOnSamePosition() As IEnumerable(Of Integer)\n\t        ' The first user IL instruction is already in 2 nested try blocks.\n\t        Try\n\t            Try\n\t                Yield 0\n\t            Finally\n\t                Console.WriteLine(\"Inner Finally\")\n\t            End Try\n\n\t        Finally\n\t            Console.WriteLine(\"Outer Finally\")\n\t        End Try\n\t    End Function\n\n#If ROSLYN Then\n\t    Public Shared Iterator Function LocalInFinally(Of T As IDisposable)(ByVal a As T) As IEnumerable(Of Integer)\n\t        Yield 1\n\t        Try\n\t            Yield 2\n\t        Finally\n\t            Dim val = a\n\t            val.Dispose()\n\t            val.Dispose()\n\t        End Try\n\t        Yield 3\n\t    End Function\n#End If\n\n\t    Public Shared Iterator Function GenericYield(Of T As New)() As IEnumerable(Of T)\n\t        Dim val As T = New T()\n\t        For i = 0 To 2\n\t            Yield val\n\t        Next\n\t    End Function\n\n\t    Public Shared Iterator Function MultipleYieldBreakInTryFinally(ByVal i As Integer) As IEnumerable(Of Integer)\n\t        Try\n\t            If i = 2 Then\n\t                Return\n\t            End If\n\n\t            While i < 40\n\t                If i Mod 2 = 0 Then\n\t                    Return\n\t                End If\n\t                i += 1\n\n\t                Yield i\n\t            End While\n\n\t        Finally\n\t            Console.WriteLine(\"finally\")\n\t        End Try\n\t        Console.WriteLine(\"normal exit\")\n\t    End Function\n\n\t\tFriend Iterator Function ForLoopWithYieldReturn(ByVal [end] As Integer, ByVal evil As Integer) As IEnumerable(Of Integer)\n\t\t\t' This loop needs to pick the implicit \"yield break;\" as exit point\n\t\t\t' in order to produce pretty code; not the \"throw\" which would\n\t\t\t' be a less-pretty option.\n\t\t\tFor i = 0 To [end] - 1\n\t\t\t\tIf i = evil Then\n\t\t\t\t\tThrow New InvalidOperationException(\"Found evil number\")\n\t\t\t\tEnd If\n\t\t\t\tYield i\n\t\t\tNext\n\t\tEnd Function\n\tEnd Class\nEnd Namespace\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TestTraceListener.cs",
    "content": "// Copyright (c) 2016 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.Tests.Helpers;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler\n{\n\t[SetUpFixture]\n\tpublic class TestTraceListener : DefaultTraceListener\n\t{\n\t\t[OneTimeSetUp]\n\t\tpublic void RunBeforeAnyTests()\n\t\t{\n\t\t\tTrace.Listeners.Insert(0, this);\n\t\t}\n\n\t\t[OneTimeTearDown]\n\t\tpublic void RunAfterAnyTests()\n\t\t{\n\t\t\tTrace.Listeners.Remove(this);\n\t\t}\n\n\t\tpublic override void Fail(string message, string detailMessage)\n\t\t{\n\t\t\tAssert.Fail(message + \" \" + detailMessage);\n\t\t}\n\t}\n\n\t[SetUpFixture]\n\tpublic class ToolsetSetup\n\t{\n\t\t[OneTimeSetUp]\n\t\tpublic async Task RunBeforeAnyTests()\n\t\t{\n\t\t\tawait Tester.Initialize().ConfigureAwait(false);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TypeSystem/ReflectionHelperTests.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests.TypeSystem\n{\n\t[TestFixture]\n\tpublic unsafe class ReflectionHelperTests\n\t{\n\t\tICompilation compilation = new SimpleCompilation(TypeSystemLoaderTests.Mscorlib);\n\n\t\tvoid TestFindType(Type type)\n\t\t{\n\t\t\tIType t = compilation.FindType(type);\n\t\t\tAssert.That(t, Is.Not.Null, type.FullName);\n\t\t\tAssert.That(t.ReflectionName, Is.EqualTo(type.FullName));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestGetInnerClass()\n\t\t{\n\t\t\tTestFindType(typeof(Environment.SpecialFolder));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestGetGenericClass1()\n\t\t{\n\t\t\tTestFindType(typeof(Action<>));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestGetGenericClass2()\n\t\t{\n\t\t\tTestFindType(typeof(Action<,>));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestGetInnerClassInGenericClass1()\n\t\t{\n\t\t\tTestFindType(typeof(Dictionary<,>.ValueCollection));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestGetInnerClassInGenericClass2()\n\t\t{\n\t\t\tTestFindType(typeof(Dictionary<,>.ValueCollection.Enumerator));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestFindTypeReflectionNameInnerClass()\n\t\t{\n\t\t\tAssert.That(compilation.FindType(typeof(Environment.SpecialFolder)).ReflectionName, Is.EqualTo(\"System.Environment+SpecialFolder\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestFindTypeReflectionNameUnboundGenericClass()\n\t\t{\n\t\t\tAssert.That(compilation.FindType(typeof(Action<>)).ReflectionName, Is.EqualTo(\"System.Action`1\"));\n\t\t\tAssert.That(compilation.FindType(typeof(Action<,>)).ReflectionName, Is.EqualTo(\"System.Action`2\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestFindTypeReflectionNameBoundGenericClass()\n\t\t{\n\t\t\tAssert.That(compilation.FindType(typeof(Action<string>)).ReflectionName, Is.EqualTo(\"System.Action`1[[System.String]]\"));\n\t\t\tAssert.That(compilation.FindType(typeof(Action<int, short>)).ReflectionName, Is.EqualTo(\"System.Action`2[[System.Int32],[System.Int16]]\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestFindTypeReflectionNameNullableType()\n\t\t{\n\t\t\tAssert.That(compilation.FindType(typeof(int?)).ReflectionName, Is.EqualTo(\"System.Nullable`1[[System.Int32]]\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestFindTypeReflectionNameInnerClassInUnboundGenericType()\n\t\t{\n\t\t\tAssert.That(compilation.FindType(typeof(Dictionary<,>.ValueCollection)).ReflectionName, Is.EqualTo(\"System.Collections.Generic.Dictionary`2+ValueCollection\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestFindTypeReflectionNameInnerClassInBoundGenericType()\n\t\t{\n\t\t\tAssert.That(compilation.FindType(typeof(Dictionary<string, int>.KeyCollection)).ReflectionName, Is.EqualTo(\"System.Collections.Generic.Dictionary`2+KeyCollection[[System.String],[System.Int32]]\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestFindTypeReflectionNameArrayType()\n\t\t{\n\t\t\tAssert.That(compilation.FindType(typeof(int[])).ReflectionName, Is.EqualTo(typeof(int[]).FullName));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestFindTypeReflectionNameMultidimensionalArrayType()\n\t\t{\n\t\t\tAssert.That(compilation.FindType(typeof(int[,])).ReflectionName, Is.EqualTo(typeof(int[,]).FullName));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestFindTypeReflectionNameJaggedMultidimensionalArrayType()\n\t\t{\n\t\t\tAssert.That(compilation.FindType(typeof(int[,][,,])).ReflectionName, Is.EqualTo(typeof(int[,][,,]).FullName));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestFindTypeReflectionNamePointerType()\n\t\t{\n\t\t\tAssert.That(compilation.FindType(typeof(int*)).ReflectionName, Is.EqualTo(typeof(int*).FullName));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestFindTypeReflectionNameByReferenceType()\n\t\t{\n\t\t\tAssert.That(compilation.FindType(typeof(int).MakeByRefType()).ReflectionName, Is.EqualTo(typeof(int).MakeByRefType().FullName));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseReflectionName()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.That(ReflectionHelper.ParseReflectionName(\"System.Int32\", context).ReflectionName, Is.EqualTo(\"System.Int32\"));\n\t\t\tAssert.That(ReflectionHelper.ParseReflectionName(\"System.Int32&\", context).ReflectionName, Is.EqualTo(\"System.Int32&\"));\n\t\t\tAssert.That(ReflectionHelper.ParseReflectionName(\"System.Int32*&\", context).ReflectionName, Is.EqualTo(\"System.Int32*&\"));\n\t\t\tAssert.That(ReflectionHelper.ParseReflectionName(typeof(int).AssemblyQualifiedName, context).ReflectionName, Is.EqualTo(\"System.Int32\"));\n\t\t\tAssert.That(ReflectionHelper.ParseReflectionName(\"System.Action`1[[System.String]]\", context).ReflectionName, Is.EqualTo(\"System.Action`1[[System.String]]\"));\n\t\t\tAssert.That(ReflectionHelper.ParseReflectionName(\"System.Action`1[[System.String, mscorlib]]\", context).ReflectionName, Is.EqualTo(\"System.Action`1[[System.String]]\"));\n\t\t\tAssert.That(ReflectionHelper.ParseReflectionName(typeof(int[,][,,]).AssemblyQualifiedName, context).ReflectionName, Is.EqualTo(\"System.Int32[,,][,]\"));\n\t\t\tAssert.That(ReflectionHelper.ParseReflectionName(\"System.Environment+SpecialFolder\", context).ReflectionName, Is.EqualTo(\"System.Environment+SpecialFolder\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseOpenGenericReflectionName()\n\t\t{\n\t\t\tIType converter = ReflectionHelper.ParseReflectionName(\"System.Converter`2[[`0],[``0]]\", new SimpleTypeResolveContext(compilation.MainModule));\n\t\t\tAssert.That(converter.ReflectionName, Is.EqualTo(\"System.Converter`2[[`0],[``0]]\"));\n\t\t\tIMethod convertAll = compilation.FindType(typeof(List<>)).GetMethods(m => m.Name == \"ConvertAll\").Single();\n\t\t\tIType converter2 = ReflectionHelper.ParseReflectionName(\"System.Converter`2[[`0],[``0]]\", new SimpleTypeResolveContext(convertAll));\n\t\t\tAssert.That(converter2.ReflectionName, Is.EqualTo(\"System.Converter`2[[`0],[``0]]\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ArrayOfTypeParameter()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.That(ReflectionHelper.ParseReflectionName(\"`0[,]\", context).ReflectionName, Is.EqualTo(\"`0[,]\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseNullReflectionName()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.Throws<ArgumentNullException>(() => ReflectionHelper.ParseReflectionName(null, context));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseInvalidReflectionName1()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.Throws<ReflectionNameParseException>(() => ReflectionHelper.ParseReflectionName(string.Empty, context));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseInvalidReflectionName2()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.That(ReflectionHelper.ParseReflectionName(\"`\", context).ReflectionName, Is.EqualTo(\"`\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseInvalidReflectionName3()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.That(ReflectionHelper.ParseReflectionName(\"``\", context).ReflectionName, Is.EqualTo(\"``\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseInvalidReflectionName4()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.That(ReflectionHelper.ParseReflectionName(\"System.Action`A\", context).ReflectionName, Is.EqualTo(\"System.Action`A\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseInvalidReflectionName5()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.Throws<ReflectionNameParseException>(() => ReflectionHelper.ParseReflectionName(\"System.Environment+\", context));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseInvalidReflectionName5b()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.That(ReflectionHelper.ParseReflectionName(\"System.Environment+`\", context).ReflectionName, Is.EqualTo(\"System.Environment+`\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseInvalidReflectionName6()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.Throws<ReflectionNameParseException>(() => ReflectionHelper.ParseReflectionName(\"System.Int32[\", context));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseInvalidReflectionName7()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.That(ReflectionHelper.ParseReflectionName(\"System.Int32[`]\", context).ReflectionName, Is.EqualTo(\"System.Int32\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseInvalidReflectionName8()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.Throws<ReflectionNameParseException>(() => ReflectionHelper.ParseReflectionName(\"System.Int32[,\", context));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseInvalidReflectionName9()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.Throws<ReflectionNameParseException>(() => ReflectionHelper.ParseReflectionName(\"System.Int32]\", context));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseInvalidReflectionName10()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.Throws<ReflectionNameParseException>(() => ReflectionHelper.ParseReflectionName(\"System.Int32*a\", context));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseInvalidReflectionName11()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.Throws<ReflectionNameParseException>(() => ReflectionHelper.ParseReflectionName(\"System.Action`1[[]]\", context));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseInvalidReflectionName12()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.Throws<ReflectionNameParseException>(() => ReflectionHelper.ParseReflectionName(\"System.Action`1[[System.Int32]a]\", context));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseInvalidReflectionName13()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.Throws<ReflectionNameParseException>(() => ReflectionHelper.ParseReflectionName(\"System.Action`1[[System.Int32],]\", context));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseInvalidReflectionName14()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.Throws<ReflectionNameParseException>(() => ReflectionHelper.ParseReflectionName(\"System.Action`1[[System.Int32]\", context));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseInvalidReflectionName15()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.Throws<ReflectionNameParseException>(() => ReflectionHelper.ParseReflectionName(\"System.Action`1[[System.Int32\", context));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParseInvalidReflectionName16()\n\t\t{\n\t\t\tvar context = new SimpleTypeResolveContext(compilation.MainModule);\n\t\t\tAssert.Throws<ReflectionNameParseException>(() => ReflectionHelper.ParseReflectionName(\"System.Action`1[[System.Int32],[System.String\", context));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs",
    "content": "// Copyright (c) 2010-2018 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests.TypeSystem\n{\n\tusing AttributeArray = ImmutableArray<CustomAttributeTypedArgument<IType>>;\n\n\t[TestFixture]\n\tpublic class TypeSystemLoaderTests\n\t{\n\t\tstatic PEFile LoadAssembly(string filename)\n\t\t{\n\t\t\treturn new PEFile(filename, new FileStream(filename, FileMode.Open, FileAccess.Read));\n\t\t}\n\n\t\tstatic readonly Lazy<PEFile> mscorlib = new Lazy<PEFile>(\n\t\t\tdelegate {\n\t\t\t\treturn LoadAssembly(Path.Combine(Helpers.Tester.RefAssembliesToolset.GetPath(\"legacy\"), \"mscorlib.dll\"));\n\t\t\t});\n\n\t\tstatic readonly Lazy<PEFile> systemCore = new Lazy<PEFile>(\n\t\t\tdelegate {\n\t\t\t\treturn LoadAssembly(Path.Combine(Helpers.Tester.RefAssembliesToolset.GetPath(\"legacy\"), \"System.Core.dll\"));\n\t\t\t});\n\n\t\tstatic readonly Lazy<PEFile> testAssembly = new Lazy<PEFile>(\n\t\t\tdelegate {\n\t\t\t\treturn LoadAssembly(typeof(SimplePublicClass).Assembly.Location);\n\t\t\t});\n\n\t\tpublic static PEFile Mscorlib { get { return mscorlib.Value; } }\n\t\tpublic static PEFile SystemCore { get { return systemCore.Value; } }\n\t\tpublic static PEFile TestAssembly { get { return testAssembly.Value; } }\n\n\t\t[OneTimeSetUp]\n\t\tpublic void FixtureSetUp()\n\t\t{\n\t\t\tcompilation = new SimpleCompilation(TestAssembly,\n\t\t\t\tMscorlib.WithOptions(TypeSystemOptions.Default | TypeSystemOptions.OnlyPublicAPI));\n\t\t}\n\n\t\tprotected ICompilation compilation;\n\n\t\tprotected ITypeDefinition GetTypeDefinition(Type type)\n\t\t{\n\t\t\treturn compilation.FindType(type).GetDefinition();\n\t\t}\n\n\t\t[Test]\n\t\tpublic void SimplePublicClassTest()\n\t\t{\n\t\t\tITypeDefinition c = GetTypeDefinition(typeof(SimplePublicClass));\n\t\t\tAssert.That(c.Name, Is.EqualTo(typeof(SimplePublicClass).Name));\n\t\t\tAssert.That(c.FullName, Is.EqualTo(typeof(SimplePublicClass).FullName));\n\t\t\tAssert.That(c.Namespace, Is.EqualTo(typeof(SimplePublicClass).Namespace));\n\t\t\tAssert.That(c.ReflectionName, Is.EqualTo(typeof(SimplePublicClass).FullName));\n\n\t\t\tAssert.That(c.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(!c.IsAbstract);\n\t\t\tAssert.That(!c.IsSealed);\n\t\t\tAssert.That(!c.IsStatic);\n\t\t\tAssert.That(!c.HasAttribute(KnownAttribute.SpecialName));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void SimplePublicClassMethodTest()\n\t\t{\n\t\t\tITypeDefinition c = GetTypeDefinition(typeof(SimplePublicClass));\n\n\t\t\tIMethod method = c.Methods.Single(m => m.Name == \"Method\");\n\t\t\tAssert.That(method.FullName, Is.EqualTo(typeof(SimplePublicClass).FullName + \".Method\"));\n\t\t\tAssert.That(method.DeclaringType, Is.SameAs(c));\n\t\t\tAssert.That(method.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(method.SymbolKind, Is.EqualTo(SymbolKind.Method));\n\t\t\tAssert.That(!method.IsVirtual);\n\t\t\tAssert.That(!method.IsStatic);\n\t\t\tAssert.That(method.Parameters.Count, Is.EqualTo(0));\n\t\t\tAssert.That(method.GetAttributes().Count(), Is.EqualTo(0));\n\t\t\tAssert.That(method.HasBody);\n\t\t\tAssert.That(method.AccessorOwner, Is.Null);\n\t\t\tAssert.That(!method.HasAttribute(KnownAttribute.SpecialName));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void SimplePublicClassCtorTest()\n\t\t{\n\t\t\tITypeDefinition c = GetTypeDefinition(typeof(SimplePublicClass));\n\n\t\t\tIMethod method = c.Methods.Single(m => m.IsConstructor);\n\t\t\tAssert.That(method.FullName, Is.EqualTo(typeof(SimplePublicClass).FullName + \"..ctor\"));\n\t\t\tAssert.That(method.DeclaringType, Is.SameAs(c));\n\t\t\tAssert.That(method.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(method.SymbolKind, Is.EqualTo(SymbolKind.Constructor));\n\t\t\tAssert.That(!method.IsVirtual);\n\t\t\tAssert.That(!method.IsStatic);\n\t\t\tAssert.That(method.Parameters.Count, Is.EqualTo(0));\n\t\t\tAssert.That(method.GetAttributes().Count(), Is.EqualTo(0));\n\t\t\tAssert.That(method.HasBody);\n\t\t\tAssert.That(method.AccessorOwner, Is.Null);\n\t\t\tAssert.That(!method.HasAttribute(KnownAttribute.SpecialName));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void SimplePublicClassDtorTest()\n\t\t{\n\t\t\tITypeDefinition c = GetTypeDefinition(typeof(SimplePublicClass));\n\n\t\t\tIMethod method = c.Methods.Single(m => m.IsDestructor);\n\t\t\tAssert.That(method.FullName, Is.EqualTo(typeof(SimplePublicClass).FullName + \".Finalize\"));\n\t\t\tAssert.That(method.DeclaringType, Is.SameAs(c));\n\t\t\tAssert.That(method.Accessibility, Is.EqualTo(Accessibility.Protected));\n\t\t\tAssert.That(method.SymbolKind, Is.EqualTo(SymbolKind.Destructor));\n\t\t\tAssert.That(!method.IsVirtual);\n\t\t\tAssert.That(!method.IsStatic);\n\t\t\tAssert.That(method.Parameters.Count, Is.EqualTo(0));\n\t\t\tAssert.That(method.GetAttributes().Count(), Is.EqualTo(1));\n\t\t\tAssert.That(method.HasBody);\n\t\t\tAssert.That(method.AccessorOwner, Is.Null);\n\t\t\tAssert.That(!method.HasAttribute(KnownAttribute.SpecialName));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void DynamicType()\n\t\t{\n\t\t\tITypeDefinition testClass = GetTypeDefinition(typeof(DynamicTest));\n\t\t\tAssert.That(testClass.Fields.Single(f => f.Name == \"DynamicField\").ReturnType, Is.EqualTo(SpecialType.Dynamic));\n\t\t\tAssert.That(testClass.Properties.Single().ReturnType, Is.EqualTo(SpecialType.Dynamic));\n\t\t\tAssert.That(testClass.Properties.Single().GetAttributes().Count(), Is.EqualTo(0));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void DynamicTypeInGenerics()\n\t\t{\n\t\t\tITypeDefinition testClass = GetTypeDefinition(typeof(DynamicTest));\n\n\t\t\tIMethod m1 = testClass.Methods.Single(me => me.Name == \"DynamicGenerics1\");\n\t\t\tAssert.That(m1.ReturnType.ReflectionName, Is.EqualTo(\"System.Collections.Generic.List`1[[dynamic]]\"));\n\t\t\tAssert.That(m1.Parameters[0].Type.ReflectionName, Is.EqualTo(\"System.Action`3[[System.Object],[dynamic[]],[System.Object]]\"));\n\n\t\t\tIMethod m2 = testClass.Methods.Single(me => me.Name == \"DynamicGenerics2\");\n\t\t\tAssert.That(m2.Parameters[0].Type.ReflectionName, Is.EqualTo(\"System.Action`3[[System.Object],[dynamic],[System.Object]]\"));\n\n\t\t\tIMethod m3 = testClass.Methods.Single(me => me.Name == \"DynamicGenerics3\");\n\t\t\tAssert.That(m3.Parameters[0].Type.ReflectionName, Is.EqualTo(\"System.Action`3[[System.Int32],[dynamic],[System.Object]]\"));\n\n\t\t\tIMethod m4 = testClass.Methods.Single(me => me.Name == \"DynamicGenerics4\");\n\t\t\tAssert.That(m4.Parameters[0].Type.ReflectionName, Is.EqualTo(\"System.Action`3[[System.Int32[]],[dynamic],[System.Object]]\"));\n\n\t\t\tIMethod m5 = testClass.Methods.Single(me => me.Name == \"DynamicGenerics5\");\n\t\t\tAssert.That(m5.Parameters[0].Type.ReflectionName, Is.EqualTo(\"System.Action`3[[System.Int32*[]],[dynamic],[System.Object]]\"));\n\n\t\t\tIMethod m6 = testClass.Methods.Single(me => me.Name == \"DynamicGenerics6\");\n\t\t\tAssert.That(m6.Parameters[0].Type.ReflectionName, Is.EqualTo(\"System.Action`3[[System.Object],[dynamic],[System.Object]]&\"));\n\n\t\t\tIMethod m7 = testClass.Methods.Single(me => me.Name == \"DynamicGenerics7\");\n\t\t\tAssert.That(m7.Parameters[0].Type.ReflectionName, Is.EqualTo(\"System.Action`3[[System.Int32[][,]],[dynamic],[System.Object]]\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void DynamicParameterHasNoAttributes()\n\t\t{\n\t\t\tITypeDefinition testClass = GetTypeDefinition(typeof(DynamicTest));\n\t\t\tIMethod m1 = testClass.Methods.Single(me => me.Name == \"DynamicGenerics1\");\n\t\t\tAssert.That(m1.Parameters[0].GetAttributes().Count(), Is.EqualTo(0));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void AssemblyAttribute()\n\t\t{\n\t\t\tvar attributes = compilation.MainModule.GetAssemblyAttributes().ToList();\n\t\t\tvar typeTest = attributes.Single(a => a.AttributeType.FullName == typeof(TypeTestAttribute).FullName);\n\t\t\tAssert.That(typeTest.FixedArguments.Length, Is.EqualTo(3));\n\t\t\t// first argument is (int)42\n\t\t\tAssert.That((int)typeTest.FixedArguments[0].Value, Is.EqualTo(42));\n\t\t\t// second argument is typeof(System.Action<>)\n\t\t\tvar ty = (IType)typeTest.FixedArguments[1].Value;\n\t\t\tAssert.That(ty is ParameterizedType, Is.False); // rt must not be constructed - it's just an unbound type\n\t\t\tAssert.That(ty.FullName, Is.EqualTo(\"System.Action\"));\n\t\t\tAssert.That(ty.TypeParameterCount, Is.EqualTo(1));\n\t\t\t// third argument is typeof(IDictionary<string, IList<TestAttribute>>)\n\t\t\tvar crt = (ParameterizedType)typeTest.FixedArguments[2].Value;\n\t\t\tAssert.That(crt.FullName, Is.EqualTo(\"System.Collections.Generic.IDictionary\"));\n\t\t\tAssert.That(crt.TypeArguments[0].FullName, Is.EqualTo(\"System.String\"));\n\t\t\t// we know the name for TestAttribute, but not necessarily the namespace, as NUnit is not in the compilation\n\t\t\tAssert.That(crt.TypeArguments[1].FullName, Is.EqualTo(\"System.Collections.Generic.IList\"));\n\t\t\tvar testAttributeType = ((ParameterizedType)crt.TypeArguments[1]).TypeArguments.Single();\n\t\t\tAssert.That(testAttributeType.Name, Is.EqualTo(\"TestAttribute\"));\n\t\t\tAssert.That(testAttributeType.Kind, Is.EqualTo(TypeKind.Unknown));\n\t\t\t// (more accurately, we know the namespace and reflection name if the type was loaded by cecil,\n\t\t\t// but not if we parsed it from C#)\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TypeForwardedTo_Attribute()\n\t\t{\n\t\t\tvar attributes = compilation.MainModule.GetAssemblyAttributes().ToList();\n\t\t\tvar forwardAttribute = attributes.Single(a => a.AttributeType.FullName == typeof(TypeForwardedToAttribute).FullName);\n\t\t\tAssert.That(forwardAttribute.FixedArguments.Length, Is.EqualTo(1));\n\t\t\tvar rt = (IType)forwardAttribute.FixedArguments[0].Value;\n\t\t\tAssert.That(rt.ReflectionName, Is.EqualTo(\"System.Func`2\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestClassTypeParameters()\n\t\t{\n\t\t\tvar testClass = GetTypeDefinition(typeof(GenericClass<,>));\n\t\t\tAssert.That(testClass.TypeParameters[0].OwnerType, Is.EqualTo(SymbolKind.TypeDefinition));\n\t\t\tAssert.That(testClass.TypeParameters[1].OwnerType, Is.EqualTo(SymbolKind.TypeDefinition));\n\t\t\tAssert.That(testClass.TypeParameters[0].DirectBaseTypes.First(), Is.SameAs(testClass.TypeParameters[1]));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestMethod()\n\t\t{\n\t\t\tvar testClass = GetTypeDefinition(typeof(GenericClass<,>));\n\n\t\t\tIMethod m = testClass.Methods.Single(me => me.Name == \"TestMethod\");\n\t\t\tAssert.That(m.TypeParameters[0].Name, Is.EqualTo(\"K\"));\n\t\t\tAssert.That(m.TypeParameters[1].Name, Is.EqualTo(\"V\"));\n\t\t\tAssert.That(m.TypeParameters[0].OwnerType, Is.EqualTo(SymbolKind.Method));\n\t\t\tAssert.That(m.TypeParameters[1].OwnerType, Is.EqualTo(SymbolKind.Method));\n\n\t\t\tAssert.That(m.TypeParameters[0].DirectBaseTypes.First().ReflectionName, Is.EqualTo(\"System.IComparable`1[[``1]]\"));\n\t\t\tAssert.That(m.TypeParameters[1].DirectBaseTypes.First(), Is.SameAs(m.TypeParameters[0]));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void GetIndex()\n\t\t{\n\t\t\tvar testClass = GetTypeDefinition(typeof(GenericClass<,>));\n\n\t\t\tIMethod m = testClass.Methods.Single(me => me.Name == \"GetIndex\");\n\t\t\tAssert.That(m.TypeParameters[0].Name, Is.EqualTo(\"T\"));\n\t\t\tAssert.That(m.TypeParameters[0].OwnerType, Is.EqualTo(SymbolKind.Method));\n\t\t\tAssert.That(m.TypeParameters[0].Owner, Is.SameAs(m));\n\n\t\t\tParameterizedType constraint = (ParameterizedType)m.TypeParameters[0].DirectBaseTypes.First();\n\t\t\tAssert.That(constraint.Name, Is.EqualTo(\"IEquatable\"));\n\t\t\tAssert.That(constraint.TypeParameterCount, Is.EqualTo(1));\n\t\t\tAssert.That(constraint.TypeArguments.Count, Is.EqualTo(1));\n\t\t\tAssert.That(constraint.TypeArguments[0], Is.SameAs(m.TypeParameters[0]));\n\t\t\tAssert.That(m.Parameters[0].Type, Is.SameAs(m.TypeParameters[0]));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void GetIndexSpecializedTypeParameter()\n\t\t{\n\t\t\tvar testClass = GetTypeDefinition(typeof(GenericClass<,>));\n\t\t\tvar methodDef = testClass.Methods.Single(me => me.Name == \"GetIndex\");\n\t\t\tvar m = methodDef.Specialize(new TypeParameterSubstitution(\n\t\t\t\tnew[] { compilation.FindType(KnownTypeCode.Int16), compilation.FindType(KnownTypeCode.Int32) },\n\t\t\t\tnull\n\t\t\t));\n\n\t\t\tAssert.That(m.TypeParameters[0].Name, Is.EqualTo(\"T\"));\n\t\t\tAssert.That(m.TypeParameters[0].OwnerType, Is.EqualTo(SymbolKind.Method));\n\t\t\tAssert.That(m.TypeParameters[0].Owner, Is.SameAs(m));\n\n\t\t\tParameterizedType constraint = (ParameterizedType)m.TypeParameters[0].DirectBaseTypes.First();\n\t\t\tAssert.That(constraint.Name, Is.EqualTo(\"IEquatable\"));\n\t\t\tAssert.That(constraint.TypeParameterCount, Is.EqualTo(1));\n\t\t\tAssert.That(constraint.TypeArguments.Count, Is.EqualTo(1));\n\t\t\tAssert.That(constraint.TypeArguments[0], Is.SameAs(m.TypeParameters[0]));\n\t\t\tAssert.That(m.Parameters[0].Type, Is.SameAs(m.TypeParameters[0]));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void GetIndexDoubleSpecialization()\n\t\t{\n\t\t\tvar testClass = GetTypeDefinition(typeof(GenericClass<,>));\n\t\t\t// GenericClass<A, B>.GetIndex<T>\n\t\t\tvar methodDef = testClass.Methods.Single(me => me.Name == \"GetIndex\");\n\n\t\t\t// GenericClass<B, A>.GetIndex<A>\n\t\t\tvar m1 = methodDef.Specialize(new TypeParameterSubstitution(\n\t\t\t\tnew[] { testClass.TypeParameters[1], testClass.TypeParameters[0] },\n\t\t\t\tnew[] { testClass.TypeParameters[0] }\n\t\t\t));\n\t\t\t// GenericClass<string, int>.GetIndex<int>\n\t\t\tvar m2 = m1.Specialize(new TypeParameterSubstitution(\n\t\t\t\tnew[] { compilation.FindType(KnownTypeCode.Int32), compilation.FindType(KnownTypeCode.String) },\n\t\t\t\tnull\n\t\t\t));\n\n\t\t\t// GenericClass<string, int>.GetIndex<int>\n\t\t\tvar m12 = methodDef.Specialize(new TypeParameterSubstitution(\n\t\t\t\tnew[] { compilation.FindType(KnownTypeCode.String), compilation.FindType(KnownTypeCode.Int32) },\n\t\t\t\tnew[] { compilation.FindType(KnownTypeCode.Int32) }\n\t\t\t));\n\t\t\tAssert.That(m2, Is.EqualTo(m12));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void SpecializedMethod_AccessorOwner()\n\t\t{\n\t\t\t// NRefactory bug #143 - Accessor Owner throws null reference exception in some cases now\n\t\t\tvar method = compilation.FindType(typeof(GenericClass<string, object>)).GetMethods(m => m.Name == \"GetIndex\").Single();\n\t\t\tAssert.That(method.AccessorOwner, Is.Null);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Specialized_GetIndex_ToMemberReference()\n\t\t{\n\t\t\tvar method = compilation.FindType(typeof(GenericClass<string, object>)).GetMethods(m => m.Name == \"GetIndex\").Single();\n\t\t\tAssert.That(method.Parameters[0].Type, Is.SameAs(method.TypeParameters[0]));\n\t\t\tAssert.That(method.TypeParameters[0].Owner, Is.SameAs(method));\n\t\t\tAssert.That(method, Is.InstanceOf<SpecializedMethod>());\n\t\t\t//Assert.That(!method.IsParameterized); // the method itself is not specialized\n\t\t\tAssert.That(method.TypeArguments, Is.EqualTo(method.TypeParameters));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Specialized_GetIndex_SpecializeWithIdentityHasNoEffect()\n\t\t{\n\t\t\tvar genericClass = compilation.FindType(typeof(GenericClass<string, object>));\n\t\t\tIType[] methodTypeArguments = { DummyTypeParameter.GetMethodTypeParameter(0) };\n\t\t\tvar method = genericClass.GetMethods(methodTypeArguments, m => m.Name == \"GetIndex\").Single();\n\t\t\t// GenericClass<string,object>.GetIndex<!!0>()\n\t\t\tAssert.That(method.TypeParameters[0].Owner, Is.SameAs(method));\n\t\t\tAssert.That(method.TypeArguments[0], Is.Not.EqualTo(method.TypeParameters[0]));\n\t\t\tAssert.That(((ITypeParameter)method.TypeArguments[0]).Owner, Is.Null);\n\t\t\t// Now apply identity substitution:\n\t\t\tvar method2 = method.Specialize(TypeParameterSubstitution.Identity);\n\t\t\tAssert.That(method2.TypeParameters[0].Owner, Is.SameAs(method2));\n\t\t\tAssert.That(method2.TypeArguments[0], Is.Not.EqualTo(method2.TypeParameters[0]));\n\t\t\tAssert.That(((ITypeParameter)method2.TypeArguments[0]).Owner, Is.Null);\n\n\t\t\tAssert.That(method2, Is.EqualTo(method));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void GenericEnum()\n\t\t{\n\t\t\tvar testClass = GetTypeDefinition(typeof(GenericClass<,>.NestedEnum));\n\t\t\tAssert.That(testClass.TypeParameterCount, Is.EqualTo(2));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void FieldInGenericClassWithNestedEnumType()\n\t\t{\n\t\t\tvar testClass = GetTypeDefinition(typeof(GenericClass<,>));\n\t\t\tvar enumClass = GetTypeDefinition(typeof(GenericClass<,>.NestedEnum));\n\t\t\tvar field = testClass.Fields.Single(f => f.Name == \"EnumField\");\n\t\t\tAssert.That(field.ReturnType, Is.EqualTo(new ParameterizedType(enumClass, testClass.TypeParameters)));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void GenericEnumMemberReturnType()\n\t\t{\n\t\t\tvar enumClass = GetTypeDefinition(typeof(GenericClass<,>.NestedEnum));\n\t\t\tvar field = enumClass.Fields.Single(f => f.Name == \"EnumMember\");\n\t\t\tAssert.That(field.ReturnType, Is.EqualTo(new ParameterizedType(enumClass, enumClass.TypeParameters)));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void PropertyWithProtectedSetter()\n\t\t{\n\t\t\tvar testClass = GetTypeDefinition(typeof(PropertyTest));\n\t\t\tIProperty p = testClass.Properties.Single(pr => pr.Name == \"PropertyWithProtectedSetter\");\n\t\t\tAssert.That(p.CanGet);\n\t\t\tAssert.That(p.CanSet);\n\t\t\tAssert.That(p.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(p.Getter.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(p.Setter.Accessibility, Is.EqualTo(Accessibility.Protected));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void PropertyWithPrivateSetter()\n\t\t{\n\t\t\tvar testClass = GetTypeDefinition(typeof(PropertyTest));\n\t\t\tIProperty p = testClass.Properties.Single(pr => pr.Name == \"PropertyWithPrivateSetter\");\n\t\t\tAssert.That(p.CanGet);\n\t\t\tAssert.That(p.CanSet);\n\t\t\tAssert.That(p.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(p.Getter.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(p.Setter.Accessibility, Is.EqualTo(Accessibility.Private));\n\t\t\tAssert.That(p.Getter.HasBody);\n\t\t\tAssert.That(!p.HasAttribute(KnownAttribute.SpecialName));\n\t\t\tAssert.That(!p.Getter.HasAttribute(KnownAttribute.SpecialName));\n\t\t\tAssert.That(!p.Setter.HasAttribute(KnownAttribute.SpecialName));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void PropertyWithPrivateGetter()\n\t\t{\n\t\t\tvar testClass = GetTypeDefinition(typeof(PropertyTest));\n\t\t\tIProperty p = testClass.Properties.Single(pr => pr.Name == \"PropertyWithPrivateGetter\");\n\t\t\tAssert.That(p.CanGet);\n\t\t\tAssert.That(p.CanSet);\n\t\t\tAssert.That(p.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(p.Getter.Accessibility, Is.EqualTo(Accessibility.Private));\n\t\t\tAssert.That(p.Setter.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(p.Getter.HasBody);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void PropertyWithoutSetter()\n\t\t{\n\t\t\tvar testClass = GetTypeDefinition(typeof(PropertyTest));\n\t\t\tIProperty p = testClass.Properties.Single(pr => pr.Name == \"PropertyWithoutSetter\");\n\t\t\tAssert.That(p.CanGet);\n\t\t\tAssert.That(!p.CanSet);\n\t\t\tAssert.That(p.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(p.Getter.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(p.Setter, Is.Null);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Indexer()\n\t\t{\n\t\t\tvar testClass = GetTypeDefinition(typeof(PropertyTest));\n\t\t\tIProperty p = testClass.Properties.Single(pr => pr.IsIndexer);\n\t\t\tAssert.That(p.Name, Is.EqualTo(\"Item\"));\n\t\t\tAssert.That(p.Parameters.Select(x => x.Name).ToArray(), Is.EqualTo(new[] { \"index\" }));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void IndexerGetter()\n\t\t{\n\t\t\tvar testClass = GetTypeDefinition(typeof(PropertyTest));\n\t\t\tIProperty p = testClass.Properties.Single(pr => pr.IsIndexer);\n\t\t\tAssert.That(p.CanGet);\n\t\t\tAssert.That(p.Getter.SymbolKind, Is.EqualTo(SymbolKind.Accessor));\n\t\t\tAssert.That(p.Getter.Name, Is.EqualTo(\"get_Item\"));\n\t\t\tAssert.That(p.Getter.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(p.Getter.Parameters.Select(x => x.Name).ToArray(), Is.EqualTo(new[] { \"index\" }));\n\t\t\tAssert.That(p.Getter.ReturnType.ReflectionName, Is.EqualTo(\"System.String\"));\n\t\t\tAssert.That(p.Getter.AccessorOwner, Is.EqualTo(p));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void IndexerSetter()\n\t\t{\n\t\t\tvar testClass = GetTypeDefinition(typeof(PropertyTest));\n\t\t\tIProperty p = testClass.Properties.Single(pr => pr.IsIndexer);\n\t\t\tAssert.That(p.CanSet);\n\t\t\tAssert.That(p.Setter.SymbolKind, Is.EqualTo(SymbolKind.Accessor));\n\t\t\tAssert.That(p.Setter.Name, Is.EqualTo(\"set_Item\"));\n\t\t\tAssert.That(p.Setter.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(p.Setter.Parameters.Select(x => x.Name).ToArray(), Is.EqualTo(new[] { \"index\", \"value\" }));\n\t\t\tAssert.That(p.Setter.ReturnType.Kind, Is.EqualTo(TypeKind.Void));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void GenericPropertyGetter()\n\t\t{\n\t\t\tvar type = compilation.FindType(typeof(GenericClass<string, object>));\n\t\t\tvar prop = type.GetProperties(p => p.Name == \"Property\").Single();\n\t\t\tAssert.That(prop.Getter.ReturnType.ReflectionName, Is.EqualTo(\"System.String\"));\n\t\t\tAssert.That(prop.Getter.IsAccessor);\n\t\t\tAssert.That(prop.Getter.AccessorOwner, Is.EqualTo(prop));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void EnumTest()\n\t\t{\n\t\t\tvar e = GetTypeDefinition(typeof(MyEnum));\n\t\t\tAssert.That(e.Kind, Is.EqualTo(TypeKind.Enum));\n\t\t\tAssert.That(e.IsReferenceType, Is.EqualTo(false));\n\t\t\tAssert.That(e.EnumUnderlyingType.ReflectionName, Is.EqualTo(\"System.Int16\"));\n\t\t\tAssert.That(e.DirectBaseTypes.Select(t => t.ReflectionName).ToArray(), Is.EqualTo(new[] { \"System.Enum\" }));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void EnumFieldsTest()\n\t\t{\n\t\t\tvar e = GetTypeDefinition(typeof(MyEnum));\n\t\t\tIField valueField = e.Fields.First();\n\t\t\tIField[] fields = e.Fields.Skip(1).ToArray();\n\t\t\tAssert.That(fields.Length, Is.EqualTo(5));\n\n\t\t\tAssert.That(valueField.Name, Is.EqualTo(\"value__\"));\n\t\t\tAssert.That(valueField.Type, Is.EqualTo(GetTypeDefinition(typeof(short))));\n\t\t\tAssert.That(valueField.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(valueField.GetConstantValue(), Is.EqualTo(null));\n\t\t\tAssert.That(!valueField.IsConst);\n\t\t\tAssert.That(!valueField.IsStatic);\n\n\t\t\tforeach (IField f in fields)\n\t\t\t{\n\t\t\t\tAssert.That(f.IsStatic);\n\t\t\t\tAssert.That(f.IsConst);\n\t\t\t\tAssert.That(f.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\t\tAssert.That(f.Type, Is.SameAs(e));\n\t\t\t\tAssert.That(f.GetConstantValue().GetType(), Is.EqualTo(typeof(short)));\n\t\t\t}\n\n\t\t\tAssert.That(fields[0].Name, Is.EqualTo(\"First\"));\n\t\t\tAssert.That(fields[0].GetConstantValue(), Is.EqualTo(0));\n\n\t\t\tAssert.That(fields[1].Name, Is.EqualTo(\"Second\"));\n\t\t\tAssert.That(fields[1].Type, Is.SameAs(e));\n\t\t\tAssert.That(fields[1].GetConstantValue(), Is.EqualTo(1));\n\n\t\t\tAssert.That(fields[2].Name, Is.EqualTo(\"Flag1\"));\n\t\t\tAssert.That(fields[2].GetConstantValue(), Is.EqualTo(0x10));\n\n\t\t\tAssert.That(fields[3].Name, Is.EqualTo(\"Flag2\"));\n\t\t\tAssert.That(fields[3].GetConstantValue(), Is.EqualTo(0x20));\n\n\t\t\tAssert.That(fields[4].Name, Is.EqualTo(\"CombinedFlags\"));\n\t\t\tAssert.That(fields[4].GetConstantValue(), Is.EqualTo(0x30));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void GetNestedTypesFromBaseClassTest()\n\t\t{\n\t\t\tITypeDefinition d = GetTypeDefinition(typeof(Derived<,>));\n\n\t\t\tIType pBase = d.DirectBaseTypes.Single();\n\t\t\tAssert.That(pBase.ReflectionName, Is.EqualTo(typeof(Base<>).FullName + \"[[`1]]\"));\n\t\t\t// Base[`1].GetNestedTypes() = { Base`1+Nested`1[`1, unbound] }\n\t\t\tAssert.That(pBase.GetNestedTypes().Select(n => n.ReflectionName).ToArray(), Is.EqualTo(new[] { typeof(Base<>.Nested<>).FullName + \"[[`1],[]]\" }));\n\n\t\t\t// Derived.GetNestedTypes() = { Base`1+Nested`1[`1, unbound] }\n\t\t\tAssert.That(d.GetNestedTypes().Select(n => n.ReflectionName).ToArray(), Is.EqualTo(new[] { typeof(Base<>.Nested<>).FullName + \"[[`1],[]]\" }));\n\t\t\t// This is 'leaking' the type parameter from B as is usual when retrieving any members from an unbound type.\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParameterizedTypeGetNestedTypesFromBaseClassTest()\n\t\t{\n\t\t\t// Derived[string,int].GetNestedTypes() = { Base`1+Nested`1[int, unbound] }\n\t\t\tvar d = compilation.FindType(typeof(Derived<string, int>));\n\t\t\tAssert.That(d.GetNestedTypes().Select(n => n.ReflectionName).ToArray(), Is.EqualTo(new[] { typeof(Base<>.Nested<>).FullName + \"[[System.Int32],[]]\" }));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ConstraintsOnOverrideAreInherited()\n\t\t{\n\t\t\tITypeDefinition d = GetTypeDefinition(typeof(Derived<,>));\n\t\t\tITypeParameter tp = d.Methods.Single(m => m.Name == \"GenericMethodWithConstraints\").TypeParameters.Single();\n\t\t\tAssert.That(tp.Name, Is.EqualTo(\"Y\"));\n\t\t\tAssert.That(!tp.HasValueTypeConstraint);\n\t\t\tAssert.That(!tp.HasReferenceTypeConstraint);\n\t\t\tAssert.That(tp.HasDefaultConstructorConstraint);\n\t\t\tAssert.That(tp.DirectBaseTypes.Select(t => t.ReflectionName).ToArray(), Is.EqualTo(new string[] { \"System.Collections.Generic.IComparer`1[[`1]]\", \"System.Object\" }));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void DtorInDerivedClass()\n\t\t{\n\t\t\tITypeDefinition c = GetTypeDefinition(typeof(Derived<,>));\n\t\t\tIMethod method = c.Methods.Single(m => m.IsDestructor);\n\t\t\tAssert.That(method.FullName, Is.EqualTo(c.FullName + \".Finalize\"));\n\t\t\tAssert.That(method.DeclaringType, Is.SameAs(c));\n\t\t\tAssert.That(method.Accessibility, Is.EqualTo(Accessibility.Protected));\n\t\t\tAssert.That(method.SymbolKind, Is.EqualTo(SymbolKind.Destructor));\n\t\t\tAssert.That(!method.IsVirtual);\n\t\t\tAssert.That(!method.IsStatic);\n\t\t\tAssert.That(method.Parameters.Count, Is.EqualTo(0));\n\t\t\tAssert.That(method.GetAttributes().Count(), Is.EqualTo(0));\n\t\t\tAssert.That(method.HasBody);\n\t\t\tAssert.That(method.AccessorOwner, Is.Null);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void PrivateFinalizeMethodIsNotADtor()\n\t\t{\n\t\t\tITypeDefinition c = GetTypeDefinition(typeof(TypeTestAttribute));\n\t\t\tIMethod method = c.Methods.Single(m => m.Name == \"Finalize\");\n\t\t\tAssert.That(method.FullName, Is.EqualTo(c.FullName + \".Finalize\"));\n\t\t\tAssert.That(method.DeclaringType, Is.SameAs(c));\n\t\t\tAssert.That(method.Accessibility, Is.EqualTo(Accessibility.Private));\n\t\t\tAssert.That(method.SymbolKind, Is.EqualTo(SymbolKind.Method));\n\t\t\tAssert.That(!method.IsVirtual);\n\t\t\tAssert.That(!method.IsStatic);\n\t\t\tAssert.That(method.Parameters.Count, Is.EqualTo(0));\n\t\t\tAssert.That(method.GetAttributes().Count(), Is.EqualTo(0));\n\t\t\tAssert.That(method.HasBody);\n\t\t\tAssert.That(method.AccessorOwner, Is.Null);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void DefaultConstructorAddedToStruct()\n\t\t{\n\t\t\tvar ctors = compilation.FindType(typeof(MyStructWithCtor)).GetConstructors();\n\t\t\tAssert.That(ctors.Count(), Is.EqualTo(2));\n\t\t\tAssert.That(!ctors.Any(c => c.IsStatic));\n\t\t\tAssert.That(ctors.All(c => c.ReturnType.Kind == TypeKind.Void));\n\t\t\tAssert.That(ctors.All(c => c.Accessibility == Accessibility.Public));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NoDefaultConstructorAddedToStruct()\n\t\t{\n\t\t\tvar ctors = compilation.FindType(typeof(MyStructWithDefaultCtor)).GetConstructors();\n\t\t\tAssert.That(ctors.Count(), Is.EqualTo(1));\n\t\t\tAssert.That(!ctors.Any(c => c.IsStatic));\n\t\t\tAssert.That(ctors.All(c => c.ReturnType.Kind == TypeKind.Void));\n\t\t\tAssert.That(ctors.All(c => c.Accessibility == Accessibility.Public));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NoDefaultConstructorAddedToClass()\n\t\t{\n\t\t\tvar ctors = compilation.FindType(typeof(MyClassWithCtor)).GetConstructors();\n\t\t\tAssert.That(ctors.Single().Accessibility, Is.EqualTo(Accessibility.Private));\n\t\t\tAssert.That(ctors.Single().Parameters.Count, Is.EqualTo(1));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void DefaultConstructorOnAbstractClassIsProtected()\n\t\t{\n\t\t\tvar ctors = compilation.FindType(typeof(AbstractClass)).GetConstructors();\n\t\t\tAssert.That(ctors.Single().Parameters.Count, Is.EqualTo(0));\n\t\t\tAssert.That(ctors.Single().Accessibility, Is.EqualTo(Accessibility.Protected));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void SerializableAttribute()\n\t\t{\n\t\t\tIAttribute attr = GetTypeDefinition(typeof(NonCustomAttributes)).GetAttributes().Single();\n\t\t\tAssert.That(attr.AttributeType.FullName, Is.EqualTo(\"System.SerializableAttribute\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NonSerializedAttribute()\n\t\t{\n\t\t\tIField field = GetTypeDefinition(typeof(NonCustomAttributes)).Fields.Single(f => f.Name == \"NonSerializedField\");\n\t\t\tAssert.That(field.GetAttributes().Single().AttributeType.FullName, Is.EqualTo(\"System.NonSerializedAttribute\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExplicitStructLayoutAttribute()\n\t\t{\n\t\t\tIAttribute attr = GetTypeDefinition(typeof(ExplicitFieldLayoutStruct)).GetAttributes().Single();\n\t\t\tAssert.That(attr.AttributeType.FullName, Is.EqualTo(\"System.Runtime.InteropServices.StructLayoutAttribute\"));\n\t\t\tvar arg1 = attr.FixedArguments.Single();\n\t\t\tAssert.That(arg1.Type.FullName, Is.EqualTo(\"System.Runtime.InteropServices.LayoutKind\"));\n\t\t\tAssert.That(arg1.Value, Is.EqualTo((int)LayoutKind.Explicit));\n\n\t\t\tvar arg2 = attr.NamedArguments[0];\n\t\t\tAssert.That(arg2.Name, Is.EqualTo(\"CharSet\"));\n\t\t\tAssert.That(arg2.Type.FullName, Is.EqualTo(\"System.Runtime.InteropServices.CharSet\"));\n\t\t\tAssert.That(arg2.Value, Is.EqualTo((int)CharSet.Unicode));\n\n\t\t\tvar arg3 = attr.NamedArguments[1];\n\t\t\tAssert.That(arg3.Name, Is.EqualTo(\"Pack\"));\n\t\t\tAssert.That(arg3.Type.FullName, Is.EqualTo(\"System.Int32\"));\n\t\t\tAssert.That(arg3.Value, Is.EqualTo(8));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void FieldOffsetAttribute()\n\t\t{\n\t\t\tIField field = GetTypeDefinition(typeof(ExplicitFieldLayoutStruct)).Fields.Single(f => f.Name == \"Field0\");\n\t\t\tAssert.That(field.GetAttributes().Single().AttributeType.FullName, Is.EqualTo(\"System.Runtime.InteropServices.FieldOffsetAttribute\"));\n\t\t\tvar arg = field.GetAttributes().Single().FixedArguments.Single();\n\t\t\tAssert.That(arg.Type.FullName, Is.EqualTo(\"System.Int32\"));\n\t\t\tAssert.That(arg.Value, Is.EqualTo(0));\n\n\t\t\tfield = GetTypeDefinition(typeof(ExplicitFieldLayoutStruct)).Fields.Single(f => f.Name == \"Field100\");\n\t\t\tAssert.That(field.GetAttributes().Single().AttributeType.FullName, Is.EqualTo(\"System.Runtime.InteropServices.FieldOffsetAttribute\"));\n\t\t\targ = field.GetAttributes().Single().FixedArguments.Single();\n\t\t\tAssert.That(arg.Type.FullName, Is.EqualTo(\"System.Int32\"));\n\t\t\tAssert.That(arg.Value, Is.EqualTo(100));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void DllImportAttribute()\n\t\t{\n\t\t\tIMethod method = GetTypeDefinition(typeof(NonCustomAttributes)).Methods.Single(m => m.Name == \"DllMethod\");\n\t\t\tIAttribute dllImport = method.GetAttributes().Single();\n\t\t\tAssert.That(dllImport.AttributeType.FullName, Is.EqualTo(\"System.Runtime.InteropServices.DllImportAttribute\"));\n\t\t\tAssert.That(dllImport.FixedArguments[0].Value, Is.EqualTo(\"unmanaged.dll\"));\n\t\t\tAssert.That(dllImport.NamedArguments.Single().Value, Is.EqualTo((int)CharSet.Unicode));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void DllImportAttributeWithPreserveSigFalse()\n\t\t{\n\t\t\tIMethod method = GetTypeDefinition(typeof(NonCustomAttributes)).Methods.Single(m => m.Name == \"DoNotPreserveSig\");\n\t\t\tIAttribute dllImport = method.GetAttributes().Single();\n\t\t\tAssert.That(dllImport.AttributeType.FullName, Is.EqualTo(\"System.Runtime.InteropServices.DllImportAttribute\"));\n\t\t\tAssert.That(dllImport.FixedArguments[0].Value, Is.EqualTo(\"unmanaged.dll\"));\n\t\t\tAssert.That(dllImport.NamedArguments.Single().Value, Is.EqualTo(false));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void PreserveSigAttribute()\n\t\t{\n\t\t\tIMethod method = GetTypeDefinition(typeof(NonCustomAttributes)).Methods.Single(m => m.Name == \"PreserveSigAsAttribute\");\n\t\t\tIAttribute preserveSig = method.GetAttributes().Single();\n\t\t\tAssert.That(preserveSig.AttributeType.FullName, Is.EqualTo(\"System.Runtime.InteropServices.PreserveSigAttribute\"));\n\t\t\tAssert.That(preserveSig.FixedArguments.Length == 0);\n\t\t\tAssert.That(preserveSig.NamedArguments.Length == 0);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void InOutParametersOnRefMethod()\n\t\t{\n\t\t\tIParameter p = GetTypeDefinition(typeof(NonCustomAttributes)).Methods.Single(m => m.Name == \"DllMethod\").Parameters.Single();\n\t\t\tAssert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.Ref));\n\t\t\tvar attr = p.GetAttributes().ToList();\n\t\t\tAssert.That(attr.Count, Is.EqualTo(2));\n\t\t\tAssert.That(attr[0].AttributeType.FullName, Is.EqualTo(\"System.Runtime.InteropServices.InAttribute\"));\n\t\t\tAssert.That(attr[1].AttributeType.FullName, Is.EqualTo(\"System.Runtime.InteropServices.OutAttribute\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MarshalAsAttributeOnMethod()\n\t\t{\n\t\t\tIMethod method = GetTypeDefinition(typeof(NonCustomAttributes)).Methods.Single(m => m.Name == \"DllMethod\");\n\t\t\tIAttribute marshalAs = method.GetReturnTypeAttributes().Single();\n\t\t\tAssert.That(marshalAs.FixedArguments.Single().Value, Is.EqualTo((int)UnmanagedType.Bool));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodWithOutParameter()\n\t\t{\n\t\t\tIParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == \"MethodWithOutParameter\").Parameters.Single();\n\t\t\tAssert.That(!p.IsOptional);\n\t\t\tAssert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.Out));\n\t\t\tAssert.That(p.GetAttributes().Count(), Is.EqualTo(0));\n\t\t\tAssert.That(p.Type.Kind == TypeKind.ByReference);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodWithRefParameter()\n\t\t{\n\t\t\tIParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == \"MethodWithRefParameter\").Parameters.Single();\n\t\t\tAssert.That(!p.IsOptional);\n\t\t\tAssert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.Ref));\n\t\t\tAssert.That(p.GetAttributes().Count(), Is.EqualTo(0));\n\t\t\tAssert.That(p.Type.Kind == TypeKind.ByReference);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodWithInParameter()\n\t\t{\n\t\t\tIParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == \"MethodWithInParameter\").Parameters.Single();\n\t\t\tAssert.That(!p.IsOptional);\n\t\t\tAssert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.In));\n\t\t\tAssert.That(p.GetAttributes().Count(), Is.EqualTo(0));\n\t\t\tAssert.That(p.Type.Kind == TypeKind.ByReference);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodWithParamsArray()\n\t\t{\n\t\t\tIParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == \"MethodWithParamsArray\").Parameters.Single();\n\t\t\tAssert.That(!p.IsOptional);\n\t\t\tAssert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None));\n\t\t\tAssert.That(p.IsParams);\n\t\t\tAssert.That(p.GetAttributes().Count(), Is.EqualTo(0));\n\t\t\tAssert.That(p.Type.Kind == TypeKind.Array);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodWithOptionalParameter()\n\t\t{\n\t\t\tIParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == \"MethodWithOptionalParameter\").Parameters.Single();\n\t\t\tAssert.That(p.IsOptional);\n\t\t\tAssert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None));\n\t\t\tAssert.That(!p.IsParams);\n\t\t\tAssert.That(p.HasConstantValueInSignature);\n\t\t\tAssert.That(p.GetAttributes().Count(), Is.EqualTo(0));\n\t\t\tAssert.That(p.GetConstantValue(), Is.EqualTo(4));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodWithExplicitOptionalParameter()\n\t\t{\n\t\t\tIParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == \"MethodWithExplicitOptionalParameter\").Parameters.Single();\n\t\t\tAssert.That(p.IsOptional);\n\t\t\tAssert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None));\n\t\t\tAssert.That(!p.IsParams);\n\t\t\tAssert.That(!p.HasConstantValueInSignature);\n\t\t\t// explicit optional parameter appears in type system if it's read from C#, but not when read from IL\n\t\t\t//Assert.AreEqual(1, p.GetAttributes().Count());\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodWithEnumOptionalParameter()\n\t\t{\n\t\t\tIParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == \"MethodWithEnumOptionalParameter\").Parameters.Single();\n\t\t\tAssert.That(p.IsOptional);\n\t\t\tAssert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None));\n\t\t\tAssert.That(!p.IsParams);\n\t\t\tAssert.That(p.HasConstantValueInSignature);\n\t\t\tAssert.That(p.GetAttributes().Count(), Is.EqualTo(0));\n\t\t\tAssert.That(p.GetConstantValue(), Is.EqualTo((int)StringComparison.OrdinalIgnoreCase));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodWithOptionalNullableParameter()\n\t\t{\n\t\t\tIParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == \"MethodWithOptionalNullableParameter\").Parameters.Single();\n\t\t\tAssert.That(p.IsOptional);\n\t\t\tAssert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None));\n\t\t\tAssert.That(!p.IsParams);\n\t\t\tAssert.That(p.HasConstantValueInSignature);\n\t\t\tAssert.That(p.GetAttributes().Count(), Is.EqualTo(0));\n\t\t\tAssert.That(p.GetConstantValue(), Is.Null);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodWithOptionalLongParameter()\n\t\t{\n\t\t\tIParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == \"MethodWithOptionalLongParameter\").Parameters.Single();\n\t\t\tAssert.That(p.IsOptional);\n\t\t\tAssert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None));\n\t\t\tAssert.That(!p.IsParams);\n\t\t\tAssert.That(p.HasConstantValueInSignature);\n\t\t\tAssert.That(p.GetConstantValue(), Is.EqualTo(1L));\n\t\t\tAssert.That(p.GetConstantValue().GetType(), Is.EqualTo(typeof(long)));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodWithOptionalNullableLongParameter()\n\t\t{\n\t\t\tIParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == \"MethodWithOptionalNullableLongParameter\").Parameters.Single();\n\t\t\tAssert.That(p.IsOptional);\n\t\t\tAssert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None));\n\t\t\tAssert.That(!p.IsParams);\n\t\t\tAssert.That(p.HasConstantValueInSignature);\n\t\t\tAssert.That(p.GetConstantValue(), Is.EqualTo(1L));\n\t\t\tAssert.That(p.GetConstantValue().GetType(), Is.EqualTo(typeof(long)));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MethodWithOptionalDecimalParameter()\n\t\t{\n\t\t\tIParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == \"MethodWithOptionalDecimalParameter\").Parameters.Single();\n\t\t\tAssert.That(p.IsOptional);\n\t\t\tAssert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None));\n\t\t\tAssert.That(!p.IsParams);\n\t\t\tAssert.That(p.HasConstantValueInSignature);\n\t\t\tAssert.That(p.GetConstantValue(), Is.EqualTo(1M));\n\t\t\tAssert.That(p.GetConstantValue().GetType(), Is.EqualTo(typeof(decimal)));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void VarArgsMethod()\n\t\t{\n\t\t\tIParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == \"VarArgsMethod\").Parameters.Single();\n\t\t\tAssert.That(!p.IsOptional);\n\t\t\tAssert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None));\n\t\t\tAssert.That(!p.IsParams);\n\t\t\tAssert.That(p.Type.Kind, Is.EqualTo(TypeKind.ArgList));\n\t\t\tAssert.That(p.Name, Is.EqualTo(\"\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void VarArgsCtor()\n\t\t{\n\t\t\tIParameter p = GetTypeDefinition(typeof(VarArgsCtor)).Methods.Single(m => m.IsConstructor).Parameters.Single();\n\t\t\tAssert.That(!p.IsOptional);\n\t\t\tAssert.That(p.ReferenceKind, Is.EqualTo(ReferenceKind.None));\n\t\t\tAssert.That(!p.IsParams);\n\t\t\tAssert.That(p.Type.Kind, Is.EqualTo(TypeKind.ArgList));\n\t\t\tAssert.That(p.Name, Is.EqualTo(\"\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void GenericDelegate_Variance()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(GenericDelegate<,>));\n\t\t\tAssert.That(type.TypeParameters[0].Variance, Is.EqualTo(VarianceModifier.Contravariant));\n\t\t\tAssert.That(type.TypeParameters[1].Variance, Is.EqualTo(VarianceModifier.Covariant));\n\n\t\t\tAssert.That(type.TypeParameters[0].DirectBaseTypes.FirstOrDefault(), Is.SameAs(type.TypeParameters[1]));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void GenericDelegate_ReferenceTypeConstraints()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(GenericDelegate<,>));\n\t\t\tAssert.That(!type.TypeParameters[0].HasReferenceTypeConstraint);\n\t\t\tAssert.That(type.TypeParameters[1].HasReferenceTypeConstraint);\n\n\t\t\tAssert.That(type.TypeParameters[0].IsReferenceType, Is.Null);\n\t\t\tAssert.That(type.TypeParameters[1].IsReferenceType, Is.EqualTo(true));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void GenericDelegate_GetInvokeMethod()\n\t\t{\n\t\t\tIType type = compilation.FindType(typeof(GenericDelegate<string, object>));\n\t\t\tIMethod m = type.GetDelegateInvokeMethod();\n\t\t\tAssert.That(m.Name, Is.EqualTo(\"Invoke\"));\n\t\t\tAssert.That(m.ReturnType.FullName, Is.EqualTo(\"System.Object\"));\n\t\t\tAssert.That(m.Parameters[0].Type.FullName, Is.EqualTo(\"System.String\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ComInterfaceTest()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(IAssemblyEnum));\n\t\t\t// [ComImport]\n\t\t\tAssert.That(type.GetAttributes().Count(a => a.AttributeType.FullName == typeof(ComImportAttribute).FullName), Is.EqualTo(1));\n\n\t\t\tIMethod m = type.Methods.Single();\n\t\t\tAssert.That(m.Name, Is.EqualTo(\"GetNextAssembly\"));\n\t\t\tAssert.That(m.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(m.IsAbstract);\n\t\t\tAssert.That(!m.IsVirtual);\n\t\t\tAssert.That(!m.IsSealed);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void InnerClassInGenericClassIsReferencedUsingParameterizedType()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(OuterGeneric<>));\n\t\t\tIField field1 = type.Fields.Single(f => f.Name == \"Field1\");\n\t\t\tIField field2 = type.Fields.Single(f => f.Name == \"Field2\");\n\t\t\tIField field3 = type.Fields.Single(f => f.Name == \"Field3\");\n\n\t\t\t// types must be self-parameterized\n\t\t\tAssert.That(field1.Type.ReflectionName, Is.EqualTo(\"ICSharpCode.Decompiler.Tests.TypeSystem.OuterGeneric`1+Inner[[`0]]\"));\n\t\t\tAssert.That(field2.Type.ReflectionName, Is.EqualTo(\"ICSharpCode.Decompiler.Tests.TypeSystem.OuterGeneric`1+Inner[[`0]]\"));\n\t\t\tAssert.That(field3.Type.ReflectionName, Is.EqualTo(\"ICSharpCode.Decompiler.Tests.TypeSystem.OuterGeneric`1+Inner[[ICSharpCode.Decompiler.Tests.TypeSystem.OuterGeneric`1+Inner[[`0]]]]\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void FlagsOnInterfaceMembersAreCorrect()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(IInterfaceWithProperty));\n\t\t\tvar p = type.Properties.Single();\n\t\t\tAssert.That(p.IsIndexer, Is.EqualTo(false));\n\t\t\tAssert.That(p.IsAbstract, Is.EqualTo(true));\n\t\t\tAssert.That(p.IsOverridable, Is.EqualTo(true));\n\t\t\tAssert.That(p.IsOverride, Is.EqualTo(false));\n\t\t\tAssert.That(p.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(p.Getter.IsAbstract, Is.EqualTo(true));\n\t\t\tAssert.That(p.Getter.IsOverridable, Is.EqualTo(true));\n\t\t\tAssert.That(p.Getter.IsOverride, Is.EqualTo(false));\n\t\t\tAssert.That(p.Getter.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(p.Getter.HasBody, Is.EqualTo(false));\n\t\t\tAssert.That(p.Setter.IsAbstract, Is.EqualTo(true));\n\t\t\tAssert.That(p.Setter.IsOverridable, Is.EqualTo(true));\n\t\t\tAssert.That(p.Setter.IsOverride, Is.EqualTo(false));\n\t\t\tAssert.That(p.Setter.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(p.Setter.HasBody, Is.EqualTo(false));\n\n\t\t\ttype = GetTypeDefinition(typeof(IInterfaceWithIndexers));\n\t\t\tp = type.Properties.Single(x => x.Parameters.Count == 2);\n\t\t\tAssert.That(p.IsIndexer, Is.EqualTo(true));\n\t\t\tAssert.That(p.IsAbstract, Is.EqualTo(true));\n\t\t\tAssert.That(p.IsOverridable, Is.EqualTo(true));\n\t\t\tAssert.That(p.IsOverride, Is.EqualTo(false));\n\t\t\tAssert.That(p.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(p.Getter.IsAbstract, Is.EqualTo(true));\n\t\t\tAssert.That(p.Getter.IsOverridable, Is.EqualTo(true));\n\t\t\tAssert.That(p.Getter.IsOverride, Is.EqualTo(false));\n\t\t\tAssert.That(p.Getter.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(p.Setter.IsAbstract, Is.EqualTo(true));\n\t\t\tAssert.That(p.Setter.IsOverridable, Is.EqualTo(true));\n\t\t\tAssert.That(p.Setter.IsOverride, Is.EqualTo(false));\n\t\t\tAssert.That(p.Setter.Accessibility, Is.EqualTo(Accessibility.Public));\n\n\t\t\ttype = GetTypeDefinition(typeof(IHasEvent));\n\t\t\tvar e = type.Events.Single();\n\t\t\tAssert.That(e.IsAbstract, Is.EqualTo(true));\n\t\t\tAssert.That(e.IsOverridable, Is.EqualTo(true));\n\t\t\tAssert.That(e.IsOverride, Is.EqualTo(false));\n\t\t\tAssert.That(e.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(e.AddAccessor.IsAbstract, Is.EqualTo(true));\n\t\t\tAssert.That(e.AddAccessor.IsOverridable, Is.EqualTo(true));\n\t\t\tAssert.That(e.AddAccessor.IsOverride, Is.EqualTo(false));\n\t\t\tAssert.That(e.AddAccessor.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(e.RemoveAccessor.IsAbstract, Is.EqualTo(true));\n\t\t\tAssert.That(e.RemoveAccessor.IsOverridable, Is.EqualTo(true));\n\t\t\tAssert.That(e.RemoveAccessor.IsOverride, Is.EqualTo(false));\n\t\t\tAssert.That(e.RemoveAccessor.Accessibility, Is.EqualTo(Accessibility.Public));\n\n\t\t\ttype = GetTypeDefinition(typeof(IDisposable));\n\t\t\tvar m = type.Methods.Single();\n\t\t\tAssert.That(m.IsAbstract, Is.EqualTo(true));\n\t\t\tAssert.That(m.IsOverridable, Is.EqualTo(true));\n\t\t\tAssert.That(m.IsOverride, Is.EqualTo(false));\n\t\t\tAssert.That(m.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void InnerClassInGenericClass_TypeParameterOwner()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(OuterGeneric<>.Inner));\n\t\t\tAssert.That(type.TypeParameters[0], Is.SameAs(type.DeclaringTypeDefinition.TypeParameters[0]));\n\t\t\tAssert.That(type.TypeParameters[0].Owner, Is.SameAs(type.DeclaringTypeDefinition));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void InnerClassInGenericClass_ReferencesTheOuterClass_Field()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(OuterGeneric<>.Inner));\n\t\t\tIField f = type.Fields.Single();\n\t\t\tAssert.That(f.Type.ReflectionName, Is.EqualTo(\"ICSharpCode.Decompiler.Tests.TypeSystem.OuterGeneric`1[[`0]]\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void InnerClassInGenericClass_ReferencesTheOuterClass_Parameter()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(OuterGeneric<>.Inner));\n\t\t\tIParameter p = type.Methods.Single(m => m.IsConstructor).Parameters.Single();\n\t\t\tAssert.That(p.Type.ReflectionName, Is.EqualTo(\"ICSharpCode.Decompiler.Tests.TypeSystem.OuterGeneric`1[[`0]]\"));\n\t\t}\n\n\t\tCustomAttributeTypedArgument<IType> GetParamsAttributeArgument(int index)\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ParamsAttribute));\n\t\t\tvar arr = (AttributeArray)type.GetAttributes().Single().FixedArguments.Single().Value;\n\t\t\tAssert.That(arr.Length, Is.EqualTo(5));\n\t\t\treturn arr[index];\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParamsAttribute_Integer()\n\t\t{\n\t\t\tvar arg = GetParamsAttributeArgument(0);\n\t\t\tAssert.That(arg.Type.FullName, Is.EqualTo(\"System.Int32\"));\n\t\t\tAssert.That(arg.Value, Is.EqualTo(1));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParamsAttribute_Enum()\n\t\t{\n\t\t\tvar arg = GetParamsAttributeArgument(1);\n\t\t\tAssert.That(arg.Type.FullName, Is.EqualTo(\"System.StringComparison\"));\n\t\t\tAssert.That(arg.Value, Is.EqualTo((int)StringComparison.CurrentCulture));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParamsAttribute_NullReference()\n\t\t{\n\t\t\tvar arg = GetParamsAttributeArgument(2);\n\t\t\t//Assert.AreEqual(\"System.Object\", arg.Type.FullName);\n\t\t\tAssert.That(arg.Value, Is.Null);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParamsAttribute_Double()\n\t\t{\n\t\t\tvar arg = GetParamsAttributeArgument(3);\n\t\t\tAssert.That(arg.Type.FullName, Is.EqualTo(\"System.Double\"));\n\t\t\tAssert.That(arg.Value, Is.EqualTo(4.0));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParamsAttribute_String()\n\t\t{\n\t\t\tvar arg = GetParamsAttributeArgument(4);\n\t\t\tAssert.That(arg.Type.FullName, Is.EqualTo(\"System.String\"));\n\t\t\tAssert.That(arg.Value, Is.EqualTo(\"Test\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParamsAttribute_Property()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ParamsAttribute));\n\t\t\tIProperty prop = type.Properties.Single(p => p.Name == \"Property\");\n\t\t\tvar attr = prop.GetAttributes().Single();\n\t\t\tAssert.That(attr.AttributeType, Is.EqualTo(type));\n\n\t\t\tvar elements = (AttributeArray)attr.FixedArguments.Single().Value;\n\t\t\tAssert.That(elements.Length, Is.EqualTo(0));\n\n\t\t\tvar namedArg = attr.NamedArguments.Single();\n\t\t\tAssert.That(namedArg.Name, Is.EqualTo(prop.Name));\n\t\t\tvar arrayElements = (AttributeArray)namedArg.Value;\n\t\t\tAssert.That(arrayElements.Length, Is.EqualTo(2));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ParamsAttribute_Getter_ReturnType()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ParamsAttribute));\n\t\t\tIProperty prop = type.Properties.Single(p => p.Name == \"Property\");\n\t\t\tAssert.That(prop.Getter.GetAttributes().Count(), Is.EqualTo(0));\n\t\t\tAssert.That(prop.Getter.GetReturnTypeAttributes().Count(), Is.EqualTo(1));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void DoubleAttribute_ImplicitNumericConversion()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(DoubleAttribute));\n\t\t\tvar arg = type.GetAttributes().Single().FixedArguments.Single();\n\t\t\tAssert.That(arg.Type.ReflectionName, Is.EqualTo(\"System.Double\"));\n\t\t\tAssert.That(arg.Value, Is.EqualTo(1.0));\n\t\t}\n\n\t\t/* TS no longer provides implicitly implemented interface members.\n\t\t[Test]\n\t\tpublic void ImplicitImplementationOfUnifiedMethods()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ImplementationOfUnifiedMethods));\n\t\t\tIMethod test = type.Methods.Single(m => m.Name == \"Test\");\n\t\t\tAssert.AreEqual(2, test.ImplementedInterfaceMembers.Count);\n\t\t\tAssert.AreEqual(\"Int32\", ((IMethod)test.ImplementedInterfaceMembers[0]).Parameters.Single().Type.Name);\n\t\t\tAssert.AreEqual(\"Int32\", ((IMethod)test.ImplementedInterfaceMembers[1]).Parameters.Single().Type.Name);\n\t\t\tAssert.AreEqual(\"T\", ((IMethod)test.ImplementedInterfaceMembers[0].MemberDefinition).Parameters.Single().Type.Name);\n\t\t\tAssert.AreEqual(\"S\", ((IMethod)test.ImplementedInterfaceMembers[1].MemberDefinition).Parameters.Single().Type.Name);\n\t\t}\n\t\t*/\n\n\t\t[Test]\n\t\tpublic void StaticityOfEventAccessors()\n\t\t{\n\t\t\t// https://github.com/icsharpcode/NRefactory/issues/20\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ClassWithStaticAndNonStaticMembers));\n\t\t\tvar evt1 = type.Events.Single(e => e.Name == \"Event1\");\n\t\t\tAssert.That(evt1.IsStatic);\n\t\t\tAssert.That(evt1.AddAccessor.IsStatic);\n\t\t\tAssert.That(evt1.RemoveAccessor.IsStatic);\n\n\t\t\tvar evt2 = type.Events.Single(e => e.Name == \"Event2\");\n\t\t\tAssert.That(!evt2.IsStatic);\n\t\t\tAssert.That(!evt2.AddAccessor.IsStatic);\n\t\t\tAssert.That(!evt2.RemoveAccessor.IsStatic);\n\n\t\t\tvar evt3 = type.Events.Single(e => e.Name == \"Event3\");\n\t\t\tAssert.That(evt3.IsStatic);\n\t\t\tAssert.That(evt3.AddAccessor.IsStatic);\n\t\t\tAssert.That(evt3.RemoveAccessor.IsStatic);\n\n\t\t\tvar evt4 = type.Events.Single(e => e.Name == \"Event4\");\n\t\t\tAssert.That(!evt4.IsStatic);\n\t\t\tAssert.That(!evt4.AddAccessor.IsStatic);\n\t\t\tAssert.That(!evt4.RemoveAccessor.IsStatic);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void StaticityOfPropertyAccessors()\n\t\t{\n\t\t\t// https://github.com/icsharpcode/NRefactory/issues/20\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ClassWithStaticAndNonStaticMembers));\n\t\t\tvar prop1 = type.Properties.Single(e => e.Name == \"Prop1\");\n\t\t\tAssert.That(prop1.IsStatic);\n\t\t\tAssert.That(prop1.Getter.IsStatic);\n\t\t\tAssert.That(prop1.Setter.IsStatic);\n\n\t\t\tvar prop2 = type.Properties.Single(e => e.Name == \"Prop2\");\n\t\t\tAssert.That(!prop2.IsStatic);\n\t\t\tAssert.That(!prop2.Getter.IsStatic);\n\t\t\tAssert.That(!prop2.Setter.IsStatic);\n\n\t\t\tvar prop3 = type.Properties.Single(e => e.Name == \"Prop3\");\n\t\t\tAssert.That(prop3.IsStatic);\n\t\t\tAssert.That(prop3.Getter.IsStatic);\n\t\t\tAssert.That(prop3.Setter.IsStatic);\n\n\t\t\tvar prop4 = type.Properties.Single(e => e.Name == \"Prop4\");\n\t\t\tAssert.That(!prop4.IsStatic);\n\t\t\tAssert.That(!prop4.Getter.IsStatic);\n\t\t\tAssert.That(!prop4.Setter.IsStatic);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void PropertyAccessorsHaveBody()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ClassWithStaticAndNonStaticMembers));\n\t\t\tforeach (var prop in type.Properties)\n\t\t\t{\n\t\t\t\tAssert.That(prop.Getter.HasBody, prop.Getter.Name);\n\t\t\t\tAssert.That(prop.Setter.HasBody, prop.Setter.Name);\n\t\t\t}\n\t\t}\n\n\t\t[Test]\n\t\tpublic void EventAccessorNames()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ClassWithStaticAndNonStaticMembers));\n\t\t\tvar customEvent = type.Events.Single(e => e.Name == \"Event1\");\n\t\t\tAssert.That(customEvent.AddAccessor.Name, Is.EqualTo(\"add_Event1\"));\n\t\t\tAssert.That(customEvent.RemoveAccessor.Name, Is.EqualTo(\"remove_Event1\"));\n\n\t\t\tvar normalEvent = type.Events.Single(e => e.Name == \"Event3\");\n\t\t\tAssert.That(normalEvent.AddAccessor.Name, Is.EqualTo(\"add_Event3\"));\n\t\t\tAssert.That(normalEvent.RemoveAccessor.Name, Is.EqualTo(\"remove_Event3\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void EventAccessorHaveBody()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ClassWithStaticAndNonStaticMembers));\n\t\t\tforeach (var ev in type.Events)\n\t\t\t{\n\t\t\t\tAssert.That(ev.AddAccessor.HasBody, ev.AddAccessor.Name);\n\t\t\t\tAssert.That(ev.RemoveAccessor.HasBody, ev.RemoveAccessor.Name);\n\t\t\t}\n\t\t}\n\n\t\t[Test]\n\t\tpublic void InterfacePropertyAccessorsShouldNotBeOverrides()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(IInterfaceWithProperty));\n\t\t\tvar prop = type.Properties.Single(p => p.Name == \"Prop\");\n\t\t\tAssert.That(prop.Getter.IsOverride, Is.False);\n\t\t\tAssert.That(prop.Getter.IsOverridable, Is.True);\n\t\t\tAssert.That(prop.Setter.IsOverride, Is.False);\n\t\t\tAssert.That(prop.Setter.IsOverridable, Is.True);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void InterfaceShouldDeriveFromObject()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(IInterfaceWithProperty));\n\t\t\tAssert.That(type.DirectBaseTypes.Count() == 1, \"Should have exactly one direct base type\");\n\t\t\tAssert.That(type.DirectBaseTypes.First().IsKnownType(KnownTypeCode.Object), \"Base type should be object\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void InterfaceShouldDeriveFromObject2()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(IShadowTestDerived));\n\t\t\tAssert.That(type.DirectBaseTypes.Count() == 2, \"Should have exactly two direct base types\");\n\t\t\tAssert.That(type.DirectBaseTypes.Skip(1).First() == GetTypeDefinition(typeof(IShadowTestBase)), \"Base type should be IShadowTestBase\");\n\t\t\tAssert.That(type.DirectBaseTypes.First().IsKnownType(KnownTypeCode.Object), \"Base type should be object\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void CheckInterfaceDirectBaseTypes()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(IDerived));\n\t\t\tAssert.That(type.DirectBaseTypes.Count() == 3, \"Should have exactly three direct base types\");\n\t\t\tAssert.That(type.DirectBaseTypes.First().IsKnownType(KnownTypeCode.Object), \"Base type should be object\");\n\t\t\tAssert.That(type.DirectBaseTypes.Skip(1).First() == GetTypeDefinition(typeof(IBase1)), \"Base type should be IBase1\");\n\t\t\tAssert.That(type.DirectBaseTypes.Skip(2).First() == GetTypeDefinition(typeof(IBase2)), \"Base type should be IBase2\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void VirtualPropertyAccessorsShouldNotBeOverrides()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ClassWithVirtualProperty));\n\t\t\tvar prop = type.Properties.Single(p => p.Name == \"Prop\");\n\t\t\tAssert.That(prop.Getter.IsOverride, Is.False);\n\t\t\tAssert.That(prop.Getter.IsOverridable, Is.True);\n\t\t\tAssert.That(prop.Setter.IsOverride, Is.False);\n\t\t\tAssert.That(prop.Setter.IsOverridable, Is.True);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ClassThatOverridesGetterOnly()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ClassThatOverridesGetterOnly));\n\t\t\tvar prop = type.Properties.Single(p => p.Name == \"Prop\");\n\t\t\tAssert.That(prop.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(prop.Getter.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ClassThatOverridesSetterOnly()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ClassThatOverridesSetterOnly));\n\t\t\tvar prop = type.Properties.Single(p => p.Name == \"Prop\");\n\t\t\tAssert.That(prop.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(prop.Setter.Accessibility, Is.EqualTo(Accessibility.Protected));\n\t\t}\n\n\t\t/* TS no longer provides implicit interface impls\n\t\t[Test]\n\t\tpublic void PropertyAccessorsShouldBeReportedAsImplementingInterfaceAccessors()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ClassThatImplementsProperty));\n\t\t\tvar prop = type.Properties.Single(p => p.Name == \"Prop\");\n\t\t\tAssert.That(prop.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IInterfaceWithProperty.Prop\" }));\n\t\t\tAssert.That(prop.Getter.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IInterfaceWithProperty.get_Prop\" }));\n\t\t\tAssert.That(prop.Setter.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IInterfaceWithProperty.set_Prop\" }));\n\t\t}\n\t\t*/\n\n\t\t[Test]\n\t\tpublic void PropertyThatImplementsInterfaceIsNotVirtual()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ClassThatImplementsProperty));\n\t\t\tvar prop = type.Properties.Single(p => p.Name == \"Prop\");\n\t\t\tAssert.That(!prop.IsVirtual);\n\t\t\tAssert.That(!prop.IsOverridable);\n\t\t\tAssert.That(!prop.IsSealed);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Property_SealedOverride()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ClassThatOverridesAndSealsVirtualProperty));\n\t\t\tvar prop = type.Properties.Single(p => p.Name == \"Prop\");\n\t\t\tAssert.That(!prop.IsVirtual);\n\t\t\tAssert.That(prop.IsOverride);\n\t\t\tAssert.That(prop.IsSealed);\n\t\t\tAssert.That(!prop.IsOverridable);\n\t\t}\n\n\t\t/* The TS no longer provides implicit interface impls.\n\t\t[Test]\n\t\tpublic void IndexerAccessorsShouldBeReportedAsImplementingTheCorrectInterfaceAccessors()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ClassThatImplementsIndexers));\n\t\t\tvar ix1 = type.Properties.Single(p => p.Parameters.Count == 1 && p.Parameters[0].Type.GetDefinition().KnownTypeCode == KnownTypeCode.Int32);\n\t\t\tvar ix2 = type.Properties.Single(p => p.Parameters.Count == 1 && p.Parameters[0].Type.GetDefinition().KnownTypeCode == KnownTypeCode.String);\n\t\t\tvar ix3 = type.Properties.Single(p => p.Parameters.Count == 2);\n\n\t\t\tAssert.That(ix1.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EquivalentTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IInterfaceWithIndexers.Item\", \"ICSharpCode.Decompiler.Tests.TypeSystem.IGenericInterfaceWithIndexer`1.Item\" }));\n\t\t\tAssert.That(ix1.ImplementedInterfaceMembers.All(p => ((IProperty)p).Parameters.Select(x => x.Type.GetDefinition().KnownTypeCode).SequenceEqual(new[] { KnownTypeCode.Int32 })));\n\t\t\tAssert.That(ix1.Getter.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EquivalentTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IInterfaceWithIndexers.get_Item\", \"ICSharpCode.Decompiler.Tests.TypeSystem.IGenericInterfaceWithIndexer`1.get_Item\" }));\n\t\t\tAssert.That(ix1.Getter.ImplementedInterfaceMembers.All(m => ((IMethod)m).Parameters.Select(p => p.Type.GetDefinition().KnownTypeCode).SequenceEqual(new[] { KnownTypeCode.Int32 })));\n\t\t\tAssert.That(ix1.Setter.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EquivalentTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IInterfaceWithIndexers.set_Item\", \"ICSharpCode.Decompiler.Tests.TypeSystem.IGenericInterfaceWithIndexer`1.set_Item\" }));\n\t\t\tAssert.That(ix1.Setter.ImplementedInterfaceMembers.All(m => ((IMethod)m).Parameters.Select(p => p.Type.GetDefinition().KnownTypeCode).SequenceEqual(new[] { KnownTypeCode.Int32, KnownTypeCode.Int32 })));\n\n\t\t\tAssert.That(ix2.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IInterfaceWithIndexers.Item\" }));\n\t\t\tAssert.That(ix2.ImplementedInterfaceMembers.All(p => ((IProperty)p).Parameters.Select(x => x.Type.GetDefinition().KnownTypeCode).SequenceEqual(new[] { KnownTypeCode.String })));\n\t\t\tAssert.That(ix2.Getter.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IInterfaceWithIndexers.get_Item\" }));\n\t\t\tAssert.That(ix2.Getter.ImplementedInterfaceMembers.All(m => ((IMethod)m).Parameters.Select(p => p.Type.GetDefinition().KnownTypeCode).SequenceEqual(new[] { KnownTypeCode.String })));\n\t\t\tAssert.That(ix2.Setter.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IInterfaceWithIndexers.set_Item\" }));\n\t\t\tAssert.That(ix2.Setter.ImplementedInterfaceMembers.All(m => ((IMethod)m).Parameters.Select(p => p.Type.GetDefinition().KnownTypeCode).SequenceEqual(new[] { KnownTypeCode.String, KnownTypeCode.Int32 })));\n\n\t\t\tAssert.That(ix3.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IInterfaceWithIndexers.Item\" }));\n\t\t\tAssert.That(ix3.ImplementedInterfaceMembers.All(p => ((IProperty)p).Parameters.Select(x => x.Type.GetDefinition().KnownTypeCode).SequenceEqual(new[] { KnownTypeCode.Int32, KnownTypeCode.Int32 })));\n\t\t\tAssert.That(ix3.Getter.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IInterfaceWithIndexers.get_Item\" }));\n\t\t\tAssert.That(ix3.Getter.ImplementedInterfaceMembers.All(m => ((IMethod)m).Parameters.Select(p => p.Type.GetDefinition().KnownTypeCode).SequenceEqual(new[] { KnownTypeCode.Int32, KnownTypeCode.Int32 })));\n\t\t\tAssert.That(ix3.Setter.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IInterfaceWithIndexers.set_Item\" }));\n\t\t\tAssert.That(ix3.Setter.ImplementedInterfaceMembers.All(m => ((IMethod)m).Parameters.Select(p => p.Type.GetDefinition().KnownTypeCode).SequenceEqual(new[] { KnownTypeCode.Int32, KnownTypeCode.Int32, KnownTypeCode.Int32 })));\n\t\t}\n\t\t*/\n\n\t\t[Test]\n\t\tpublic void ExplicitIndexerImplementationReturnsTheCorrectMembers()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ClassThatImplementsIndexersExplicitly));\n\n\t\t\tAssert.That(type.Properties.All(p => p.SymbolKind == SymbolKind.Indexer));\n\n\t\t\tAssert.That(type.Properties.All(p => p.ExplicitlyImplementedInterfaceMembers.Count() == 1));\n\t\t\tAssert.That(type.Properties.All(p => p.Getter.ExplicitlyImplementedInterfaceMembers.Count() == 1));\n\t\t\tAssert.That(type.Properties.All(p => p.Setter.ExplicitlyImplementedInterfaceMembers.Count() == 1));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExplicitDisposableImplementation()\n\t\t{\n\t\t\tITypeDefinition disposable = GetTypeDefinition(typeof(ExplicitDisposableImplementation));\n\t\t\tIMethod method = disposable.Methods.Single(m => !m.IsConstructor);\n\t\t\tAssert.That(method.IsExplicitInterfaceImplementation);\n\t\t\tAssert.That(method.ExplicitlyImplementedInterfaceMembers.Single().FullName, Is.EqualTo(\"System.IDisposable.Dispose\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExplicitImplementationOfUnifiedMethods()\n\t\t{\n\t\t\tIType type = compilation.FindType(typeof(ExplicitGenericInterfaceImplementationWithUnifiableMethods<int, int>));\n\t\t\tAssert.That(type.GetMethods(m => m.IsExplicitInterfaceImplementation).Count(), Is.EqualTo(2));\n\t\t\tforeach (IMethod method in type.GetMethods(m => m.IsExplicitInterfaceImplementation))\n\t\t\t{\n\t\t\t\tAssert.That(method.ExplicitlyImplementedInterfaceMembers.Count(), Is.EqualTo(1), method.ToString());\n\t\t\t\tAssert.That(method.Parameters.Single().Type.ReflectionName, Is.EqualTo(\"System.Int32\"));\n\t\t\t\tIMethod interfaceMethod = (IMethod)method.ExplicitlyImplementedInterfaceMembers.Single();\n\t\t\t\tAssert.That(interfaceMethod.Parameters.Single().Type.ReflectionName, Is.EqualTo(\"System.Int32\"));\n\t\t\t\tvar genericParamType = ((IMethod)method.MemberDefinition).Parameters.Single().Type;\n\t\t\t\tvar interfaceGenericParamType = ((IMethod)interfaceMethod.MemberDefinition).Parameters.Single().Type;\n\t\t\t\tAssert.That(genericParamType.Kind, Is.EqualTo(TypeKind.TypeParameter));\n\t\t\t\tAssert.That(interfaceGenericParamType.Kind, Is.EqualTo(TypeKind.TypeParameter));\n\t\t\t\tAssert.That(interfaceGenericParamType.ReflectionName, Is.EqualTo(genericParamType.ReflectionName));\n\t\t\t}\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExplicitGenericInterfaceImplementation()\n\t\t{\n\t\t\tITypeDefinition impl = GetTypeDefinition(typeof(ExplicitGenericInterfaceImplementation));\n\t\t\tIType genericInterfaceOfString = compilation.FindType(typeof(IGenericInterface<string>));\n\t\t\tIMethod implMethod1 = impl.Methods.Single(m => !m.IsConstructor && m.Parameters[1].ReferenceKind == ReferenceKind.None);\n\t\t\tIMethod implMethod2 = impl.Methods.Single(m => !m.IsConstructor && m.Parameters[1].ReferenceKind == ReferenceKind.Ref);\n\t\t\tAssert.That(implMethod1.IsExplicitInterfaceImplementation);\n\t\t\tAssert.That(implMethod2.IsExplicitInterfaceImplementation);\n\n\t\t\tIMethod interfaceMethod1 = (IMethod)implMethod1.ExplicitlyImplementedInterfaceMembers.Single();\n\t\t\tAssert.That(interfaceMethod1.DeclaringType, Is.EqualTo(genericInterfaceOfString));\n\t\t\tAssert.That(interfaceMethod1.Parameters[1].ReferenceKind == ReferenceKind.None);\n\n\t\t\tIMethod interfaceMethod2 = (IMethod)implMethod2.ExplicitlyImplementedInterfaceMembers.Single();\n\t\t\tAssert.That(interfaceMethod2.DeclaringType, Is.EqualTo(genericInterfaceOfString));\n\t\t\tAssert.That(interfaceMethod2.Parameters[1].ReferenceKind == ReferenceKind.Ref);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExplicitlyImplementedPropertiesShouldBeReportedAsBeingImplemented()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ClassThatImplementsPropertyExplicitly));\n\t\t\tvar prop = type.Properties.Single();\n\t\t\tAssert.That(prop.ExplicitlyImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IInterfaceWithProperty.Prop\" }));\n\t\t\tAssert.That(prop.Getter.ExplicitlyImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IInterfaceWithProperty.get_Prop\" }));\n\t\t\tAssert.That(prop.Setter.ExplicitlyImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IInterfaceWithProperty.set_Prop\" }));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExplicitlyImplementedPropertiesShouldHaveExplicitlyImplementedAccessors()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ClassThatImplementsPropertyExplicitly));\n\t\t\tvar prop = type.Properties.Single();\n\t\t\tAssert.That(prop.IsExplicitInterfaceImplementation);\n\t\t\tAssert.That(prop.Getter.IsExplicitInterfaceImplementation);\n\t\t\tAssert.That(prop.Setter.IsExplicitInterfaceImplementation);\n\t\t}\n\n\t\t/* The TS no longer provides implicit interface impls.\n\t\t[Test]\n\t\tpublic void EventAccessorsShouldBeReportedAsImplementingInterfaceAccessors()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ClassThatImplementsEvent));\n\t\t\tvar evt = type.Events.Single(p => p.Name == \"Event\");\n\t\t\tAssert.That(evt.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IHasEvent.Event\" }));\n\t\t\tAssert.That(evt.AddAccessor.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IHasEvent.add_Event\" }));\n\t\t\tAssert.That(evt.RemoveAccessor.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IHasEvent.remove_Event\" }));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void EventAccessorsShouldBeReportedAsImplementingInterfaceAccessorsWhenCustomAccessorMethodsAreUsed()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ClassThatImplementsEventWithCustomAccessors));\n\t\t\tvar evt = type.Events.Single(p => p.Name == \"Event\");\n\t\t\tAssert.That(evt.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IHasEvent.Event\" }));\n\t\t\tAssert.That(evt.AddAccessor.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IHasEvent.add_Event\" }));\n\t\t\tAssert.That(evt.RemoveAccessor.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IHasEvent.remove_Event\" }));\n\t\t}\n\t\t*/\n\n\t\t[Test]\n\t\tpublic void ExplicitlyImplementedEventsShouldBeReportedAsBeingImplemented()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ClassThatImplementsEventExplicitly));\n\t\t\tvar evt = type.Events.Single();\n\t\t\tAssert.That(evt.ExplicitlyImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IHasEvent.Event\" }));\n\t\t\tAssert.That(evt.AddAccessor.ExplicitlyImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IHasEvent.add_Event\" }));\n\t\t\tAssert.That(evt.RemoveAccessor.ExplicitlyImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { \"ICSharpCode.Decompiler.Tests.TypeSystem.IHasEvent.remove_Event\" }));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MembersDeclaredInDerivedInterfacesDoNotImplementBaseMembers()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(IShadowTestDerived));\n\t\t\tvar method = type.Methods.Single(m => m.Name == \"Method\");\n\t\t\tvar indexer = type.Properties.Single(p => p.IsIndexer);\n\t\t\tvar prop = type.Properties.Single(p => p.Name == \"Prop\");\n\t\t\tvar evt = type.Events.Single(e => e.Name == \"Evt\");\n\n\t\t\tAssert.That(method.ExplicitlyImplementedInterfaceMembers, Is.Empty);\n\t\t\tAssert.That(indexer.ExplicitlyImplementedInterfaceMembers, Is.Empty);\n\t\t\tAssert.That(indexer.Getter.ExplicitlyImplementedInterfaceMembers, Is.Empty);\n\t\t\tAssert.That(indexer.Setter.ExplicitlyImplementedInterfaceMembers, Is.Empty);\n\t\t\tAssert.That(prop.ExplicitlyImplementedInterfaceMembers, Is.Empty);\n\t\t\tAssert.That(prop.Getter.ExplicitlyImplementedInterfaceMembers, Is.Empty);\n\t\t\tAssert.That(prop.Setter.ExplicitlyImplementedInterfaceMembers, Is.Empty);\n\t\t\tAssert.That(evt.ExplicitlyImplementedInterfaceMembers, Is.Empty);\n\t\t\tAssert.That(evt.AddAccessor.ExplicitlyImplementedInterfaceMembers, Is.Empty);\n\t\t\tAssert.That(evt.RemoveAccessor.ExplicitlyImplementedInterfaceMembers, Is.Empty);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void StaticClassTest()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(StaticClass));\n\t\t\tAssert.That(type.IsAbstract);\n\t\t\tAssert.That(type.IsSealed);\n\t\t\tAssert.That(type.IsStatic);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExtensionMethodTest()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(StaticClass));\n\t\t\tvar method = type.Methods.Single(m => m.Name == \"Extension\");\n\n\t\t\tAssert.That(method.IsStatic);\n\t\t\tAssert.That(method.IsExtensionMethod);\n\t\t\tAssert.That(method.ReducedFrom, Is.Null);\n\n\t\t\tAssert.That(type.HasExtensions);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NoDefaultConstructorOnStaticClassTest()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(StaticClass));\n\t\t\tAssert.That(type.GetConstructors().Count(), Is.EqualTo(0));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void IndexerNonDefaultName()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(IndexerNonDefaultName));\n\t\t\tvar indexer = type.GetProperties(p => p.IsIndexer).Single();\n\t\t\tAssert.That(indexer.Name, Is.EqualTo(\"Foo\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestNullableDefaultParameter()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ClassWithMethodThatHasNullableDefaultParameter));\n\t\t\tvar method = type.GetMethods().Single(m => m.Name == \"Foo\");\n\t\t\tAssert.That(method.Parameters.Single().GetConstantValue(), Is.EqualTo(42));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void AccessibilityTests()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(AccessibilityTest));\n\t\t\tAssert.That(type.Methods.Single(m => m.Name == \"Public\").Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(type.Methods.Single(m => m.Name == \"Internal\").Accessibility, Is.EqualTo(Accessibility.Internal));\n\t\t\tAssert.That(type.Methods.Single(m => m.Name == \"ProtectedInternal\").Accessibility, Is.EqualTo(Accessibility.ProtectedOrInternal));\n\t\t\tAssert.That(type.Methods.Single(m => m.Name == \"InternalProtected\").Accessibility, Is.EqualTo(Accessibility.ProtectedOrInternal));\n\t\t\tAssert.That(type.Methods.Single(m => m.Name == \"Protected\").Accessibility, Is.EqualTo(Accessibility.Protected));\n\t\t\tAssert.That(type.Methods.Single(m => m.Name == \"Private\").Accessibility, Is.EqualTo(Accessibility.Private));\n\t\t\tAssert.That(type.Methods.Single(m => m.Name == \"None\").Accessibility, Is.EqualTo(Accessibility.Private));\n\t\t}\n\n\t\tprivate void AssertConstantField<T>(ITypeDefinition type, string name, T expected)\n\t\t{\n\t\t\tvar f = type.GetFields().Single(x => x.Name == name);\n\t\t\tAssert.That(f.IsConst);\n\t\t\tAssert.That(f.GetConstantValue(), Is.EqualTo(expected));\n\t\t\tAssert.That(f.GetAttributes().Count(), Is.EqualTo(0));\n\t\t}\n\n\t\t[Test]\n\t\tpublic unsafe void ConstantFieldsCreatedWithNew()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ConstantFieldTest));\n\t\t\tAssertConstantField<byte>(type, \"CNewb\", new byte());\n\t\t\tAssertConstantField<sbyte>(type, \"CNewsb\", new sbyte());\n\t\t\tAssertConstantField<char>(type, \"CNewc\", new char());\n\t\t\tAssertConstantField<short>(type, \"CNews\", new short());\n\t\t\tAssertConstantField<ushort>(type, \"CNewus\", new ushort());\n\t\t\tAssertConstantField<int>(type, \"CNewi\", new int());\n\t\t\tAssertConstantField<uint>(type, \"CNewui\", new uint());\n\t\t\tAssertConstantField<long>(type, \"CNewl\", new long());\n\t\t\tAssertConstantField<ulong>(type, \"CNewul\", new ulong());\n\t\t\tAssertConstantField<double>(type, \"CNewd\", new double());\n\t\t\tAssertConstantField<float>(type, \"CNewf\", new float());\n\t\t\tAssertConstantField<decimal>(type, \"CNewm\", new decimal());\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ConstantFieldsSizeOf()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ConstantFieldTest));\n\t\t\tAssertConstantField<int>(type, \"SOsb\", sizeof(sbyte));\n\t\t\tAssertConstantField<int>(type, \"SOb\", sizeof(byte));\n\t\t\tAssertConstantField<int>(type, \"SOs\", sizeof(short));\n\t\t\tAssertConstantField<int>(type, \"SOus\", sizeof(ushort));\n\t\t\tAssertConstantField<int>(type, \"SOi\", sizeof(int));\n\t\t\tAssertConstantField<int>(type, \"SOui\", sizeof(uint));\n\t\t\tAssertConstantField<int>(type, \"SOl\", sizeof(long));\n\t\t\tAssertConstantField<int>(type, \"SOul\", sizeof(ulong));\n\t\t\tAssertConstantField<int>(type, \"SOc\", sizeof(char));\n\t\t\tAssertConstantField<int>(type, \"SOf\", sizeof(float));\n\t\t\tAssertConstantField<int>(type, \"SOd\", sizeof(double));\n\t\t\tAssertConstantField<int>(type, \"SObl\", sizeof(bool));\n\t\t\tAssertConstantField<int>(type, \"SOe\", sizeof(MyEnum));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ConstantEnumFromThisAssembly()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ConstantFieldTest));\n\t\t\tIField field = type.Fields.Single(f => f.Name == \"EnumFromThisAssembly\");\n\t\t\tAssert.That(field.IsConst);\n\t\t\tAssert.That(field.GetConstantValue(), Is.EqualTo((short)MyEnum.Second));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ConstantEnumFromAnotherAssembly()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ConstantFieldTest));\n\t\t\tIField field = type.Fields.Single(f => f.Name == \"EnumFromAnotherAssembly\");\n\t\t\tAssert.That(field.IsConst);\n\t\t\tAssert.That(field.GetConstantValue(), Is.EqualTo((int)StringComparison.OrdinalIgnoreCase));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void DefaultOfEnum()\n\t\t{\n\t\t\tITypeDefinition type = GetTypeDefinition(typeof(ConstantFieldTest));\n\t\t\tIField field = type.Fields.Single(f => f.Name == \"DefaultOfEnum\");\n\t\t\tAssert.That(field.IsConst);\n\t\t\tAssert.That(field.GetConstantValue(), Is.EqualTo((short)default(MyEnum)));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExplicitImplementation()\n\t\t{\n\t\t\tvar type = GetTypeDefinition(typeof(ExplicitImplementationTests));\n\t\t\tvar itype = GetTypeDefinition(typeof(IExplicitImplementationTests));\n\n\t\t\tvar methods = type.GetMethods(m => m.Name == \"M\" || m.Name.EndsWith(\".M\")).ToList();\n\t\t\tvar imethod = itype.GetMethods(m => m.Name == \"M\").Single();\n\t\t\tAssert.That(methods.Select(m => m.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 }));\n\t\t\tAssert.That(imethod, Is.EqualTo(methods.SelectMany(m => m.ExplicitlyImplementedInterfaceMembers).Single()));\n\n\t\t\tvar properties = type.GetProperties(p => p.Name == \"P\" || p.Name.EndsWith(\".P\")).ToList();\n\t\t\tvar iproperty = itype.GetProperties(m => m.Name == \"P\").Single();\n\t\t\tAssert.That(properties.Select(p => p.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 }));\n\t\t\tAssert.That(iproperty, Is.EqualTo(properties.SelectMany(p => p.ExplicitlyImplementedInterfaceMembers).Single()));\n\t\t\tAssert.That(properties.Select(p => p.Getter.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 }));\n\t\t\tAssert.That(iproperty.Getter, Is.EqualTo(properties.SelectMany(p => p.Getter.ExplicitlyImplementedInterfaceMembers).Single()));\n\t\t\tAssert.That(properties.Select(p => p.Setter.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 }));\n\t\t\tAssert.That(iproperty.Setter, Is.EqualTo(properties.SelectMany(p => p.Setter.ExplicitlyImplementedInterfaceMembers).Single()));\n\n\t\t\tvar indexers = type.GetProperties(p => p.Name == \"Item\" || p.Name.EndsWith(\".Item\")).ToList();\n\t\t\tvar iindexer = itype.GetProperties(m => m.Name == \"Item\").Single();\n\t\t\tAssert.That(indexers.Select(p => p.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 }));\n\t\t\tAssert.That(iindexer, Is.EqualTo(indexers.SelectMany(p => p.ExplicitlyImplementedInterfaceMembers).Single()));\n\t\t\tAssert.That(indexers.Select(p => p.Getter.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 }));\n\t\t\tAssert.That(iindexer.Getter, Is.EqualTo(indexers.SelectMany(p => p.Getter.ExplicitlyImplementedInterfaceMembers).Single()));\n\t\t\tAssert.That(indexers.Select(p => p.Setter.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 }));\n\t\t\tAssert.That(iindexer.Setter, Is.EqualTo(indexers.SelectMany(p => p.Setter.ExplicitlyImplementedInterfaceMembers).Single()));\n\n\t\t\tvar events = type.GetEvents(e => e.Name == \"E\" || e.Name.EndsWith(\".E\")).ToList();\n\t\t\tvar ievent = itype.GetEvents(m => m.Name == \"E\").Single();\n\t\t\tAssert.That(events.Select(e => e.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 }));\n\t\t\tAssert.That(ievent, Is.EqualTo(events.SelectMany(e => e.ExplicitlyImplementedInterfaceMembers).Single()));\n\t\t\tAssert.That(events.Select(e => e.AddAccessor.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 }));\n\t\t\tAssert.That(ievent.AddAccessor, Is.EqualTo(events.SelectMany(e => e.AddAccessor.ExplicitlyImplementedInterfaceMembers).Single()));\n\t\t\tAssert.That(events.Select(e => e.RemoveAccessor.ExplicitlyImplementedInterfaceMembers.Count()).ToList(), Is.EquivalentTo(new[] { 0, 1 }));\n\t\t\tAssert.That(ievent.RemoveAccessor, Is.EqualTo(events.SelectMany(e => e.RemoveAccessor.ExplicitlyImplementedInterfaceMembers).Single()));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MarshalTests()\n\t\t{\n\t\t\tITypeDefinition c = compilation.FindType(typeof(IMarshalAsTests)).GetDefinition();\n\t\t\tAssert.That(c.GetMethods(m => m.Name == \"GetCollectionByQuery2\").Count(), Is.EqualTo(1));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void AttributesUsingNestedMembers()\n\t\t{\n\t\t\tvar type = GetTypeDefinition(typeof(ClassWithAttributesUsingNestedMembers));\n\t\t\tvar inner = type.GetNestedTypes().Single(t => t.Name == \"Inner\");\n\t\t\tvar myAttribute = type.GetNestedTypes().Single(t => t.Name == \"MyAttribute\");\n\t\t\tvar typeTypeTestAttr = type.GetAttributes().Single(a => a.AttributeType.Name == \"TypeTestAttribute\");\n\t\t\tAssert.That(typeTypeTestAttr.FixedArguments[0].Value, Is.EqualTo(42));\n\t\t\tAssert.That(typeTypeTestAttr.FixedArguments[1].Value, Is.EqualTo(inner));\n\t\t\tvar typeMyAttr = type.GetAttributes().Single(a => a.AttributeType.Name == \"MyAttribute\");\n\t\t\tAssert.That(typeMyAttr.AttributeType, Is.EqualTo(myAttribute));\n\n\t\t\tvar prop = type.GetProperties().Single(p => p.Name == \"P\");\n\t\t\tvar propTypeTestAttr = prop.GetAttributes().Single(a => a.AttributeType.Name == \"TypeTestAttribute\");\n\t\t\tAssert.That(propTypeTestAttr.FixedArguments[0].Value, Is.EqualTo(42));\n\t\t\tAssert.That(propTypeTestAttr.FixedArguments[1].Value, Is.EqualTo(inner));\n\t\t\tvar propMyAttr = prop.GetAttributes().Single(a => a.AttributeType.Name == \"MyAttribute\");\n\t\t\tAssert.That(propMyAttr.AttributeType, Is.EqualTo(myAttribute));\n\n\t\t\tvar attributedInner = (ITypeDefinition)type.GetNestedTypes().Single(t => t.Name == \"AttributedInner\");\n\t\t\tvar innerTypeTestAttr = attributedInner.GetAttributes().Single(a => a.AttributeType.Name == \"TypeTestAttribute\");\n\t\t\tAssert.That(innerTypeTestAttr.FixedArguments[0].Value, Is.EqualTo(42));\n\t\t\tAssert.That(innerTypeTestAttr.FixedArguments[1].Value, Is.EqualTo(inner));\n\t\t\tvar innerMyAttr = attributedInner.GetAttributes().Single(a => a.AttributeType.Name == \"MyAttribute\");\n\t\t\tAssert.That(innerMyAttr.AttributeType, Is.EqualTo(myAttribute));\n\n\t\t\tvar attributedInner2 = (ITypeDefinition)type.GetNestedTypes().Single(t => t.Name == \"AttributedInner2\");\n\t\t\tvar inner2 = attributedInner2.GetNestedTypes().Single(t => t.Name == \"Inner\");\n\t\t\tvar myAttribute2 = attributedInner2.GetNestedTypes().Single(t => t.Name == \"MyAttribute\");\n\t\t\tvar inner2TypeTestAttr = attributedInner2.GetAttributes().Single(a => a.AttributeType.Name == \"TypeTestAttribute\");\n\t\t\tAssert.That(inner2TypeTestAttr.FixedArguments[0].Value, Is.EqualTo(43));\n\t\t\tAssert.That(inner2TypeTestAttr.FixedArguments[1].Value, Is.EqualTo(inner2));\n\t\t\tvar inner2MyAttr = attributedInner2.GetAttributes().Single(a => a.AttributeType.Name == \"MyAttribute\");\n\t\t\tAssert.That(inner2MyAttr.AttributeType, Is.EqualTo(myAttribute2));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ClassWithAttributeOnTypeParameter()\n\t\t{\n\t\t\tvar tp = GetTypeDefinition(typeof(ClassWithAttributeOnTypeParameter<>)).TypeParameters.Single();\n\t\t\tvar attr = tp.GetAttributes().Single();\n\t\t\tAssert.That(attr.AttributeType.Name, Is.EqualTo(\"DoubleAttribute\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void InheritanceTest()\n\t\t{\n\t\t\tITypeDefinition c = compilation.FindType(typeof(SystemException)).GetDefinition();\n\t\t\tITypeDefinition c2 = compilation.FindType(typeof(Exception)).GetDefinition();\n\t\t\tAssert.That(c, Is.Not.Null, \"c is null\");\n\t\t\tAssert.That(c2, Is.Not.Null, \"c2 is null\");\n\t\t\t//Assert.AreEqual(3, c.BaseTypes.Count); // Inherited interfaces are not reported by Cecil\n\t\t\t// which matches the behaviour of our C#/VB parsers\n\t\t\tAssert.That(c.DirectBaseTypes.First().FullName, Is.EqualTo(\"System.Exception\"));\n\t\t\tAssert.That(c.DirectBaseTypes.First(), Is.SameAs(c2));\n\n\t\t\tstring[] superTypes = c.GetAllBaseTypes().Select(t => t.ReflectionName).ToArray();\n\t\t\tAssert.That(superTypes, Is.EqualTo(new string[] {\n\t\t\t\t\t\t\t\t\"System.Object\",\n\t\t\t\t\t\t\t\t\"System.Runtime.Serialization.ISerializable\", \"System.Runtime.InteropServices._Exception\",\n\t\t\t\t\t\t\t\t\"System.Exception\", \"System.SystemException\"\n\t\t\t\t\t\t\t}));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void GenericPropertyTest()\n\t\t{\n\t\t\tITypeDefinition c = compilation.FindType(typeof(Comparer<>)).GetDefinition();\n\t\t\tIProperty def = c.Properties.Single(p => p.Name == \"Default\");\n\t\t\tParameterizedType pt = (ParameterizedType)def.ReturnType;\n\t\t\tAssert.That(pt.FullName, Is.EqualTo(\"System.Collections.Generic.Comparer\"));\n\t\t\tAssert.That(pt.TypeArguments[0], Is.EqualTo(c.TypeParameters[0]));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void PointerTypeTest()\n\t\t{\n\t\t\tITypeDefinition c = compilation.FindType(typeof(IntPtr)).GetDefinition();\n\t\t\tIMethod toPointer = c.Methods.Single(p => p.Name == \"ToPointer\");\n\t\t\tAssert.That(toPointer.ReturnType.ReflectionName, Is.EqualTo(\"System.Void*\"));\n\t\t\tAssert.That(toPointer.ReturnType is PointerType);\n\t\t\tAssert.That(((PointerType)toPointer.ReturnType).ElementType.FullName, Is.EqualTo(\"System.Void\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void DateTimeDefaultConstructor()\n\t\t{\n\t\t\tITypeDefinition c = compilation.FindType(typeof(DateTime)).GetDefinition();\n\t\t\tAssert.That(c.Methods.Count(m => m.IsConstructor && !m.IsStatic && m.Parameters.Count == 0), Is.EqualTo(1));\n\t\t\tAssert.That(c.GetConstructors().Count(m => m.Parameters.Count == 0), Is.EqualTo(1));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NoEncodingInfoDefaultConstructor()\n\t\t{\n\t\t\tITypeDefinition c = compilation.FindType(typeof(EncodingInfo)).GetDefinition();\n\t\t\t// EncodingInfo only has an internal constructor\n\t\t\tAssert.That(!c.Methods.Any(m => m.IsConstructor));\n\t\t\t// and no implicit ctor should be added:\n\t\t\tAssert.That(c.GetConstructors().Count(), Is.EqualTo(0));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void StaticModifierTest()\n\t\t{\n\t\t\tITypeDefinition c = compilation.FindType(typeof(Environment)).GetDefinition();\n\t\t\tAssert.That(c, Is.Not.Null, \"System.Environment not found\");\n\t\t\tAssert.That(c.IsAbstract, \"class should be abstract\");\n\t\t\tAssert.That(c.IsSealed, \"class should be sealed\");\n\t\t\tAssert.That(c.IsStatic, \"class should be static\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void InnerClassReferenceTest()\n\t\t{\n\t\t\tITypeDefinition c = compilation.FindType(typeof(Environment)).GetDefinition();\n\t\t\tAssert.That(c, Is.Not.Null, \"System.Environment not found\");\n\t\t\tIType rt = c.Methods.First(m => m.Name == \"GetFolderPath\").Parameters[0].Type;\n\t\t\tAssert.That(rt, Is.SameAs(c.NestedTypes.Single(ic => ic.Name == \"SpecialFolder\")));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NestedTypesTest()\n\t\t{\n\t\t\tITypeDefinition c = compilation.FindType(typeof(Environment.SpecialFolder)).GetDefinition();\n\t\t\tAssert.That(c, Is.Not.Null, \"c is null\");\n\t\t\tAssert.That(c.FullName, Is.EqualTo(\"System.Environment.SpecialFolder\"));\n\t\t\tAssert.That(c.ReflectionName, Is.EqualTo(\"System.Environment+SpecialFolder\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void VoidHasNoMembers()\n\t\t{\n\t\t\tITypeDefinition c = compilation.FindType(typeof(void)).GetDefinition();\n\t\t\tAssert.That(c, Is.Not.Null, \"System.Void not found\");\n\t\t\tAssert.That(c.Kind, Is.EqualTo(TypeKind.Void));\n\t\t\tAssert.That(c.GetMethods().Count(), Is.EqualTo(0));\n\t\t\tAssert.That(c.GetProperties().Count(), Is.EqualTo(0));\n\t\t\tAssert.That(c.GetEvents().Count(), Is.EqualTo(0));\n\t\t\tAssert.That(c.GetFields().Count(), Is.EqualTo(0));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Void_SerializableAttribute()\n\t\t{\n\t\t\tITypeDefinition c = compilation.FindType(typeof(void)).GetDefinition();\n\t\t\tvar attr = c.GetAttributes().Single(a => a.AttributeType.FullName == \"System.SerializableAttribute\");\n\t\t\tAssert.That(attr.Constructor.Parameters.Count, Is.EqualTo(0));\n\t\t\tAssert.That(attr.FixedArguments.Length, Is.EqualTo(0));\n\t\t\tAssert.That(attr.NamedArguments.Length, Is.EqualTo(0));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Void_StructLayoutAttribute()\n\t\t{\n\t\t\tITypeDefinition c = compilation.FindType(typeof(void)).GetDefinition();\n\t\t\tvar attr = c.GetAttributes().Single(a => a.AttributeType.FullName == \"System.Runtime.InteropServices.StructLayoutAttribute\");\n\t\t\tAssert.That(attr.Constructor.Parameters.Count, Is.EqualTo(1));\n\t\t\tAssert.That(attr.FixedArguments.Length, Is.EqualTo(1));\n\t\t\tAssert.That(attr.FixedArguments[0].Value, Is.EqualTo(0));\n\t\t\tAssert.That(attr.NamedArguments.Length, Is.EqualTo(1));\n\t\t\tAssert.That(attr.NamedArguments[0].Name, Is.EqualTo(\"Size\"));\n\t\t\tAssert.That(attr.NamedArguments[0].Value, Is.EqualTo(1));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Void_ComVisibleAttribute()\n\t\t{\n\t\t\tITypeDefinition c = compilation.FindType(typeof(void)).GetDefinition();\n\t\t\tvar attr = c.GetAttributes().Single(a => a.AttributeType.FullName == \"System.Runtime.InteropServices.ComVisibleAttribute\");\n\t\t\tAssert.That(attr.Constructor.Parameters.Count, Is.EqualTo(1));\n\t\t\tAssert.That(attr.FixedArguments.Length, Is.EqualTo(1));\n\t\t\tAssert.That(attr.FixedArguments[0].Value, Is.EqualTo(true));\n\t\t\tAssert.That(attr.NamedArguments.Length, Is.EqualTo(0));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NestedClassInGenericClassTest()\n\t\t{\n\t\t\tITypeDefinition dictionary = compilation.FindType(typeof(Dictionary<,>)).GetDefinition();\n\t\t\tAssert.That(dictionary, Is.Not.Null);\n\t\t\tITypeDefinition valueCollection = compilation.FindType(typeof(Dictionary<,>.ValueCollection)).GetDefinition();\n\t\t\tAssert.That(valueCollection, Is.Not.Null);\n\t\t\tvar dictionaryRT = new ParameterizedType(dictionary, new[] { compilation.FindType(typeof(string)).GetDefinition(), compilation.FindType(typeof(int)).GetDefinition() });\n\t\t\tIProperty valueProperty = dictionaryRT.GetProperties(p => p.Name == \"Values\").Single();\n\t\t\tIType parameterizedValueCollection = valueProperty.ReturnType;\n\t\t\tAssert.That(parameterizedValueCollection.ReflectionName, Is.EqualTo(\"System.Collections.Generic.Dictionary`2+ValueCollection[[System.String],[System.Int32]]\"));\n\t\t\tAssert.That(parameterizedValueCollection.GetDefinition(), Is.SameAs(valueCollection));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ValueCollectionCountModifiers()\n\t\t{\n\t\t\tITypeDefinition valueCollection = compilation.FindType(typeof(Dictionary<,>.ValueCollection)).GetDefinition();\n\t\t\tAssert.That(valueCollection.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(valueCollection.IsSealed);\n\t\t\tAssert.That(!valueCollection.IsAbstract);\n\t\t\tAssert.That(!valueCollection.IsStatic);\n\n\t\t\tIProperty count = valueCollection.Properties.Single(p => p.Name == \"Count\");\n\t\t\tAssert.That(count.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\t// It's sealed on the IL level; but in C# it's just a normal non-virtual method that happens to implement an interface\n\t\t\tAssert.That(!count.IsSealed);\n\t\t\tAssert.That(!count.IsVirtual);\n\t\t\tAssert.That(!count.IsAbstract);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MathAcosModifiers()\n\t\t{\n\t\t\tITypeDefinition math = compilation.FindType(typeof(Math)).GetDefinition();\n\t\t\tAssert.That(math.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(math.IsSealed);\n\t\t\tAssert.That(math.IsAbstract);\n\t\t\tAssert.That(math.IsStatic);\n\n\t\t\tIMethod acos = math.Methods.Single(p => p.Name == \"Acos\");\n\t\t\tAssert.That(acos.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(acos.IsStatic);\n\t\t\tAssert.That(!acos.IsAbstract);\n\t\t\tAssert.That(!acos.IsSealed);\n\t\t\tAssert.That(!acos.IsVirtual);\n\t\t\tAssert.That(!acos.IsOverride);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void EncodingModifiers()\n\t\t{\n\t\t\tITypeDefinition encoding = compilation.FindType(typeof(Encoding)).GetDefinition();\n\t\t\tAssert.That(encoding.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(!encoding.IsSealed);\n\t\t\tAssert.That(encoding.IsAbstract);\n\n\t\t\tIMethod getDecoder = encoding.Methods.Single(p => p.Name == \"GetDecoder\");\n\t\t\tAssert.That(getDecoder.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(!getDecoder.IsStatic);\n\t\t\tAssert.That(!getDecoder.IsAbstract);\n\t\t\tAssert.That(!getDecoder.IsSealed);\n\t\t\tAssert.That(getDecoder.IsVirtual);\n\t\t\tAssert.That(!getDecoder.IsOverride);\n\n\t\t\tIMethod getMaxByteCount = encoding.Methods.Single(p => p.Name == \"GetMaxByteCount\");\n\t\t\tAssert.That(getMaxByteCount.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(!getMaxByteCount.IsStatic);\n\t\t\tAssert.That(getMaxByteCount.IsAbstract);\n\t\t\tAssert.That(!getMaxByteCount.IsSealed);\n\t\t\tAssert.That(!getMaxByteCount.IsVirtual);\n\t\t\tAssert.That(!getMaxByteCount.IsOverride);\n\n\t\t\tIProperty encoderFallback = encoding.Properties.Single(p => p.Name == \"EncoderFallback\");\n\t\t\tAssert.That(encoderFallback.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(!encoderFallback.IsStatic);\n\t\t\tAssert.That(!encoderFallback.IsAbstract);\n\t\t\tAssert.That(!encoderFallback.IsSealed);\n\t\t\tAssert.That(!encoderFallback.IsVirtual);\n\t\t\tAssert.That(!encoderFallback.IsOverride);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UnicodeEncodingModifiers()\n\t\t{\n\t\t\tITypeDefinition encoding = compilation.FindType(typeof(UnicodeEncoding)).GetDefinition();\n\t\t\tAssert.That(encoding.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(!encoding.IsSealed);\n\t\t\tAssert.That(!encoding.IsAbstract);\n\n\t\t\tIMethod getDecoder = encoding.Methods.Single(p => p.Name == \"GetDecoder\");\n\t\t\tAssert.That(getDecoder.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(!getDecoder.IsStatic);\n\t\t\tAssert.That(!getDecoder.IsAbstract);\n\t\t\tAssert.That(!getDecoder.IsSealed);\n\t\t\tAssert.That(!getDecoder.IsVirtual);\n\t\t\tAssert.That(getDecoder.IsOverride);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UTF32EncodingModifiers()\n\t\t{\n\t\t\tITypeDefinition encoding = compilation.FindType(typeof(UTF32Encoding)).GetDefinition();\n\t\t\tAssert.That(encoding.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(encoding.IsSealed);\n\t\t\tAssert.That(!encoding.IsAbstract);\n\n\t\t\tIMethod getDecoder = encoding.Methods.Single(p => p.Name == \"GetDecoder\");\n\t\t\tAssert.That(getDecoder.Accessibility, Is.EqualTo(Accessibility.Public));\n\t\t\tAssert.That(!getDecoder.IsStatic);\n\t\t\tAssert.That(!getDecoder.IsAbstract);\n\t\t\tAssert.That(!getDecoder.IsSealed);\n\t\t\tAssert.That(!getDecoder.IsVirtual);\n\t\t\tAssert.That(getDecoder.IsOverride);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void FindRedirectedType()\n\t\t{\n\t\t\tvar compilationWithSystemCore = new SimpleCompilation(SystemCore, Mscorlib);\n\n\t\t\tvar type = ReflectionHelper.ParseReflectionName(\"System.Func`2, System.Core\", new SimpleTypeResolveContext(compilationWithSystemCore));\n\t\t\tITypeDefinition c = type.GetDefinition();\n\t\t\tAssert.That(c, Is.Not.Null, \"System.Func<,> not found\");\n\t\t\tAssert.That(c.ParentModule.AssemblyName, Is.EqualTo(\"mscorlib\"));\n\t\t}\n\n\t\tpublic void DelegateIsClass()\n\t\t{\n\t\t\tvar @delegate = compilation.FindType(KnownTypeCode.Delegate).GetDefinition();\n\t\t\tAssert.That(@delegate, Is.EqualTo(TypeKind.Class));\n\t\t\tAssert.That(!@delegate.IsSealed);\n\t\t}\n\n\t\tpublic void MulticastDelegateIsClass()\n\t\t{\n\t\t\tvar multicastDelegate = compilation.FindType(KnownTypeCode.MulticastDelegate).GetDefinition();\n\t\t\tAssert.That(multicastDelegate, Is.EqualTo(TypeKind.Class));\n\t\t\tAssert.That(!multicastDelegate.IsSealed);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void HasSpecialName()\n\t\t{\n\t\t\tvar nonCustomAttributes = compilation.FindType(typeof(NonCustomAttributes)).GetDefinition();\n\n\t\t\tvar method = nonCustomAttributes.GetMethods(m => m.Name == \"SpecialNameMethod\").Single();\n\t\t\tvar property = nonCustomAttributes.GetProperties(p => p.Name == \"SpecialNameProperty\").Single();\n\t\t\tvar @event = nonCustomAttributes.GetEvents(e => e.Name == \"SpecialNameEvent\").Single();\n\t\t\tvar field = nonCustomAttributes.GetFields(f => f.Name == \"SpecialNameField\").Single();\n\n\t\t\tvar @class = nonCustomAttributes.GetNestedTypes(t => t.Name == \"SpecialNameClass\").Single().GetDefinition();\n\t\t\tvar @struct = nonCustomAttributes.GetNestedTypes(t => t.Name == \"SpecialNameStruct\").Single().GetDefinition();\n\n\t\t\tAssert.That(method.HasAttribute(KnownAttribute.SpecialName));\n\t\t\tAssert.That(property.HasAttribute(KnownAttribute.SpecialName));\n\t\t\tAssert.That(@event.HasAttribute(KnownAttribute.SpecialName));\n\t\t\tAssert.That(field.HasAttribute(KnownAttribute.SpecialName));\n\n\t\t\tAssert.That(@class.HasAttribute(KnownAttribute.SpecialName));\n\t\t\tAssert.That(@struct.HasAttribute(KnownAttribute.SpecialName));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExtensionEverything()\n\t\t{\n\t\t\tvar extensionEverything = GetTypeDefinition(typeof(ExtensionEverything));\n\t\t\tAssert.That(extensionEverything.IsStatic, Is.True, \"ExtensionEverything should be static\");\n\t\t\tAssert.That(extensionEverything.HasExtensions, Is.True, \"ExtensionEverything should have extensions\");\n\t\t\tvar info = extensionEverything.ExtensionInfo;\n\t\t\tAssert.That(info, Is.Not.Null, \"ExtensionEverything should have ExtensionInfo\");\n\t\t\tforeach (var method in extensionEverything.Methods)\n\t\t\t{\n\t\t\t\tAssert.That(method.IsStatic, Is.True, \"Method should be static: \" + method.Name);\n\t\t\t\tExtensionMemberInfo? infoOfImpl = info.InfoOfImplementationMember(method);\n\t\t\t\tAssert.That(infoOfImpl, Is.Not.Null, \"Method should have implementation info: \" + method.Name);\n\t\t\t\tExtensionMemberInfo? infoOfExtension = info.InfoOfExtensionMember(infoOfImpl.Value.ExtensionMember);\n\t\t\t\tAssert.That(infoOfExtension, Is.EqualTo(infoOfImpl), \"Info of extension member should be equal to info of implementation member: \" + method.Name);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemTestCase.cs",
    "content": "// Copyright (c) 2010-2018 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n[assembly: ICSharpCode.Decompiler.Tests.TypeSystem.TypeTestAttribute(\n\t42, typeof(System.Action<>), typeof(IDictionary<string, IList<NUnit.Framework.TestAttribute>>))]\n\n[assembly: TypeForwardedTo(typeof(Func<,>))]\n\nnamespace ICSharpCode.Decompiler.Tests.TypeSystem\n{\n\tpublic delegate S GenericDelegate<in T, out S>(T input) where T : S where S : class;\n\n\tpublic class SimplePublicClass\n\t{\n\t\tpublic void Method() { }\n\n\t\tpublic SimplePublicClass() { }\n\t\t[Double(1)]\n\t\t~SimplePublicClass() { }\n\t}\n\n\tpublic class TypeTestAttribute : Attribute\n\t{\n\t\tpublic TypeTestAttribute(int a1, Type a2, Type a3) { }\n\n#pragma warning disable CS0465\n\t\tprivate void Finalize()\n\t\t{\n\n\t\t}\n#pragma warning restore CS0465\n\t}\n\n\t[Params(1, StringComparison.CurrentCulture, null, 4.0, \"Test\")]\n\tpublic class ParamsAttribute : Attribute\n\t{\n\t\tpublic ParamsAttribute(params object[] x) { }\n\n\t\t[Params(Property = new string[] { \"a\", \"b\" })]\n\t\tpublic string[] Property {\n\t\t\t[return: Params(\"Attribute on return type of getter\")]\n\t\t\tget { return null; }\n\t\t\tset { }\n\t\t}\n\t}\n\n\t[Double(1)]\n\tpublic class DoubleAttribute : Attribute\n\t{\n\t\tpublic DoubleAttribute(double val) { }\n\t}\n\n\tpublic unsafe class DynamicTest\n\t{\n\t\tpublic dynamic DynamicField;\n\t\tpublic dynamic SimpleProperty { get; set; }\n\n\t\tpublic List<dynamic> DynamicGenerics1(Action<object, dynamic[], object> param) { return null; }\n\t\tpublic void DynamicGenerics2(Action<object, dynamic, object> param) { }\n\t\tpublic void DynamicGenerics3(Action<int, dynamic, object> param) { }\n\t\tpublic void DynamicGenerics4(Action<int[], dynamic, object> param) { }\n\t\tpublic void DynamicGenerics5(Action<int*[], dynamic, object> param) { }\n\t\tpublic void DynamicGenerics6(ref Action<object, dynamic, object> param) { }\n\t\tpublic void DynamicGenerics7(Action<int[,][], dynamic, object> param) { }\n\t}\n\n\tpublic class GenericClass<A, B> where A : B\n\t{\n\t\tpublic void TestMethod<K, V>(string param) where V : K where K : IComparable<V> { }\n\t\tpublic void GetIndex<T>(T element) where T : IEquatable<T> { }\n\n\t\tpublic NestedEnum EnumField;\n\n\t\tpublic A Property { get; set; }\n\n\t\tpublic enum NestedEnum\n\t\t{\n\t\t\tEnumMember\n\t\t}\n\t}\n\n\tpublic class PropertyTest\n\t{\n\t\tpublic int PropertyWithProtectedSetter { get; protected set; }\n\n\t\tpublic object PropertyWithPrivateSetter { get; private set; }\n\n\t\tpublic object PropertyWithoutSetter { get { return null; } }\n\n\t\tpublic object PropertyWithPrivateGetter { private get; set; }\n\n\t\tpublic string this[int index] { get { return \"Test\"; } set { } }\n\t}\n\n\tpublic enum MyEnum : short\n\t{\n\t\tFirst,\n\t\tSecond,\n\t\tFlag1 = 0x10,\n\t\tFlag2 = 0x20,\n\t\tCombinedFlags = Flag1 | Flag2\n\t}\n\n\tpublic class Base<T>\n\t{\n\t\tpublic class Nested<X> { }\n\n\t\t~Base() { }\n\n\t\tpublic virtual void GenericMethodWithConstraints<X>(T a) where X : IComparer<T>, new() { }\n\t}\n\tpublic class Derived<A, B> : Base<B>\n\t{\n\t\t~Derived() { }\n\t\tpublic override void GenericMethodWithConstraints<Y>(B a) { }\n\t}\n\n\tpublic struct MyStructWithCtor\n\t{\n\t\tpublic MyStructWithCtor(int a) { }\n\t}\n\n\tpublic struct MyStructWithDefaultCtor\n\t{\n\t\tpublic MyStructWithDefaultCtor() { }\n\t}\n\n\tpublic class MyClassWithCtor\n\t{\n\t\tprivate MyClassWithCtor(int a) { }\n\t}\n\n\t[Serializable]\n\tpublic class NonCustomAttributes\n\t{\n\t\t[SpecialName]\n\t\tpublic class SpecialNameClass\n\t\t{\n\t\t}\n\n\t\t[SpecialName]\n\t\tpublic struct SpecialNameStruct\n\t\t{\n\t\t}\n\n\t\t[NonSerialized]\n\t\tpublic readonly int NonSerializedField;\n\n\t\t[SpecialName]\n\t\tpublic readonly int SpecialNameField;\n\n\t\t[SpecialName]\n\t\tpublic event EventHandler SpecialNameEvent;\n\n\t\t[SpecialName]\n\t\tpublic int SpecialNameProperty { get; set; }\n\n\t\t[DllImport(\"unmanaged.dll\", CharSet = CharSet.Unicode)]\n\t\t[return: MarshalAs(UnmanagedType.Bool)]\n\t\tpublic static extern bool DllMethod([In, Out] ref int p);\n\n\t\t[DllImport(\"unmanaged.dll\", PreserveSig = false)]\n\t\tpublic static extern bool DoNotPreserveSig();\n\n\t\t[PreserveSig]\n\t\tpublic static void PreserveSigAsAttribute()\n\t\t{\n\t\t}\n\n\t\t[SpecialName]\n\t\tpublic static void SpecialNameMethod()\n\t\t{\n\t\t}\n\t}\n\n\t[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode, Pack = 8)]\n\tpublic struct ExplicitFieldLayoutStruct\n\t{\n\t\t[FieldOffset(0)]\n\t\tpublic int Field0;\n\n\t\t[FieldOffset(100)]\n\t\tpublic int Field100;\n\t}\n\n\tpublic class ParameterTests\n\t{\n\t\tpublic void MethodWithOutParameter(out int x) { x = 0; }\n\t\tpublic void MethodWithParamsArray(params object[] x) { }\n\t\tpublic void MethodWithOptionalParameter(int x = 4) { }\n\t\tpublic void MethodWithExplicitOptionalParameter([Optional] int x) { }\n\t\tpublic void MethodWithRefParameter(ref int x) { }\n\t\tpublic void MethodWithInParameter(in int x) { }\n\t\tpublic void MethodWithEnumOptionalParameter(StringComparison x = StringComparison.OrdinalIgnoreCase) { }\n\t\tpublic void MethodWithOptionalNullableParameter(int? x = null) { }\n\t\tpublic void MethodWithOptionalLongParameter(long x = 1) { }\n\t\tpublic void MethodWithOptionalNullableLongParameter(long? x = 1) { }\n\t\tpublic void MethodWithOptionalDecimalParameter(decimal x = 1) { }\n\t\tpublic void VarArgsMethod(__arglist) { }\n\t}\n\n\tpublic class VarArgsCtor\n\t{\n\t\tpublic VarArgsCtor(__arglist) { }\n\t}\n\n\t[ComImport(), Guid(\"21B8916C-F28E-11D2-A473-00C04F8EF448\"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]\n\tpublic interface IAssemblyEnum\n\t{\n\t\t[PreserveSig()]\n\t\tint GetNextAssembly(uint dwFlags);\n\t}\n\n\tpublic class OuterGeneric<X>\n\t{\n\t\tpublic class Inner\n\t\t{\n\t\t\tpublic OuterGeneric<X> referenceToOuter;\n\t\t\tpublic Inner(OuterGeneric<X> referenceToOuter) { }\n\t\t}\n\n\t\tpublic OuterGeneric<X>.Inner Field1;\n\t\tpublic Inner Field2;\n\t\tpublic OuterGeneric<OuterGeneric<X>.Inner>.Inner Field3;\n\t}\n\n\tpublic class ExplicitDisposableImplementation : IDisposable\n\t{\n\t\tvoid IDisposable.Dispose() { }\n\t}\n\n\tpublic interface IGenericInterface<T>\n\t{\n\t\tvoid Test<S>(T a, S b) where S : T;\n\t\tvoid Test<S>(T a, ref S b);\n\t}\n\n\tpublic class ExplicitGenericInterfaceImplementation : IGenericInterface<string>\n\t{\n\t\tvoid IGenericInterface<string>.Test<T>(string a, T b) { }\n\t\tvoid IGenericInterface<string>.Test<T>(string a, ref T b) { }\n\t}\n\n\tpublic interface IGenericInterfaceWithUnifiableMethods<T, S>\n\t{\n\t\tvoid Test(T a);\n\t\tvoid Test(S a);\n\t}\n\n\tpublic class ImplementationOfUnifiedMethods : IGenericInterfaceWithUnifiableMethods<int, int>\n\t{\n\t\tpublic void Test(int a) { }\n\t}\n\n\tpublic class ExplicitGenericInterfaceImplementationWithUnifiableMethods<T, S> : IGenericInterfaceWithUnifiableMethods<T, S>\n\t{\n\t\tvoid IGenericInterfaceWithUnifiableMethods<T, S>.Test(T a) { }\n\t\tvoid IGenericInterfaceWithUnifiableMethods<T, S>.Test(S a) { }\n\t}\n\n\tpublic partial class PartialClass\n\t{\n\t\tpartial void PartialMethodWithImplementation(int a);\n\n\t\tpartial void PartialMethodWithImplementation(System.Int32 a)\n\t\t{\n\t\t}\n\n\t\tpartial void PartialMethodWithImplementation(string a);\n\n\t\tpartial void PartialMethodWithImplementation(System.String a)\n\t\t{\n\t\t}\n\n\t\tpartial void PartialMethodWithoutImplementation();\n\t}\n\n\tpublic class ClassWithStaticAndNonStaticMembers\n\t{\n\t\tpublic static event System.EventHandler Event1 { add { } remove { } }\n\t\tpublic event System.EventHandler Event2 { add { } remove { } }\n#pragma warning disable 67\n\t\tpublic static event System.EventHandler Event3;\n\t\tpublic event System.EventHandler Event4;\n\n\t\tpublic static int Prop1 { get { return 0; } set { } }\n\t\tpublic int Prop2 { get { return 0; } set { } }\n\t\tpublic static int Prop3 { get; set; }\n\t\tpublic int Prop4 { get; set; }\n\t}\n\n\tpublic interface IInterfaceWithProperty\n\t{\n\t\tint Prop { get; set; }\n\t}\n\n\tpublic interface IBase1\n\t{\n\t\tint Prop { get; set; }\n\t}\n\n\tpublic interface IBase2\n\t{\n\t\tint Prop { get; set; }\n\t}\n\n\tpublic interface IDerived : IBase1, IBase2\n\t{\n\t\tnew int Prop { get; set; }\n\t}\n\n\tpublic class ClassWithVirtualProperty\n\t{\n\t\tpublic virtual int Prop { get; protected set; }\n\t}\n\n\tpublic class ClassThatOverridesAndSealsVirtualProperty : ClassWithVirtualProperty\n\t{\n\t\tpublic sealed override int Prop { get; protected set; }\n\t}\n\n\tpublic class ClassThatOverridesGetterOnly : ClassWithVirtualProperty\n\t{\n\t\tpublic override int Prop { get { return 1; } }\n\t}\n\n\tpublic class ClassThatOverridesSetterOnly : ClassThatOverridesGetterOnly\n\t{\n\t\tpublic override int Prop { protected set { } }\n\t}\n\n\tpublic class ClassThatImplementsProperty : IInterfaceWithProperty\n\t{\n\t\tpublic int Prop { get; set; }\n\t}\n\n\tpublic class ClassThatImplementsPropertyExplicitly : IInterfaceWithProperty\n\t{\n\t\tint IInterfaceWithProperty.Prop { get; set; }\n\t}\n\n\tpublic interface IInterfaceWithIndexers\n\t{\n\t\tint this[int x] { get; set; }\n\t\tint this[string x] { get; set; }\n\t\tint this[int x, int y] { get; set; }\n\t}\n\n\tpublic interface IGenericInterfaceWithIndexer<T>\n\t{\n\t\tint this[T x] { get; set; }\n\t}\n\n\tpublic interface IInterfaceWithRenamedIndexer\n\t{\n\t\t[IndexerName(\"NewName\")]\n\t\tint this[int x] { get; set; }\n\t}\n\n\tpublic class ClassThatImplementsIndexers : IInterfaceWithIndexers, IGenericInterfaceWithIndexer<int>\n\t{\n\t\tpublic int this[int x] { get { return 0; } set { } }\n\t\tpublic int this[string x] { get { return 0; } set { } }\n\t\tpublic int this[int x, int y] { get { return 0; } set { } }\n\t}\n\n\tpublic class ClassThatImplementsIndexersExplicitly : IInterfaceWithIndexers, IGenericInterfaceWithIndexer<int>, IInterfaceWithRenamedIndexer\n\t{\n\t\tint IInterfaceWithIndexers.this[int x] { get { return 0; } set { } }\n\t\tint IGenericInterfaceWithIndexer<int>.this[int x] { get { return 0; } set { } }\n\t\tint IInterfaceWithIndexers.this[string x] { get { return 0; } set { } }\n\t\tint IInterfaceWithIndexers.this[int x, int y] { get { return 0; } set { } }\n\t\tint IInterfaceWithRenamedIndexer.this[int x] { get { return 0; } set { } }\n\t}\n\n\tpublic interface IHasEvent\n\t{\n\t\tevent EventHandler Event;\n\t}\n\n\tpublic class ClassThatImplementsEvent : IHasEvent\n\t{\n\t\tpublic event EventHandler Event;\n\t}\n\n\tpublic class ClassThatImplementsEventWithCustomAccessors : IHasEvent\n\t{\n\t\tpublic event EventHandler Event { add { } remove { } }\n\t}\n\n\tpublic class ClassThatImplementsEventExplicitly : IHasEvent\n\t{\n\t\tevent EventHandler IHasEvent.Event { add { } remove { } }\n\t}\n\n\tpublic interface IShadowTestBase\n\t{\n\t\tvoid Method();\n\t\tint this[int i] { get; set; }\n\t\tint Prop { get; set; }\n\t\tevent EventHandler Evt;\n\t}\n\n\tpublic interface IShadowTestDerived : IShadowTestBase\n\t{\n\t\tnew void Method();\n\t\tnew int this[int i] { get; set; }\n\t\tnew int Prop { get; set; }\n\t\tnew event EventHandler Evt;\n\t}\n\n\tpublic static class StaticClass\n\t{\n\t\tpublic static void Extension(this object inst) { }\n\t}\n\n\tpublic abstract class AbstractClass { }\n\n\tpublic class IndexerNonDefaultName\n\t{\n\t\t[IndexerName(\"Foo\")]\n\t\tpublic int this[int index] {\n\t\t\tget { return 0; }\n\t\t}\n\t}\n\n\tpublic class ClassWithMethodThatHasNullableDefaultParameter\n\t{\n\t\tpublic void Foo(int? bar = 42) { }\n\t}\n\n\tpublic class AccessibilityTest\n\t{\n\t\tpublic void Public() { }\n\t\tinternal void Internal() { }\n\t\tprotected internal void ProtectedInternal() { }\n\t\tinternal protected void InternalProtected() { }\n\t\tprotected void Protected() { }\n\t\tprivate void Private() { }\n\t\tvoid None() { }\n\t}\n\n\tpublic class ConstantFieldTest\n\t{\n\t\tpublic const byte Cb = 42;\n\t\tpublic const sbyte Csb = 42;\n\t\tpublic const char Cc = '\\x42';\n\t\tpublic const short Cs = 42;\n\t\tpublic const ushort Cus = 42;\n\t\tpublic const int Ci = 42;\n\t\tpublic const uint Cui = 42;\n\t\tpublic const long Cl = 42;\n\t\tpublic const ulong Cul = 42;\n\t\tpublic const double Cd = 42;\n\t\tpublic const float Cf = 42;\n\t\tpublic const decimal Cm = 42;\n\t\tpublic const string S = \"hello, world\";\n\t\tpublic const string NullString = null;\n\n\t\tpublic const MyEnum EnumFromThisAssembly = MyEnum.Second;\n\t\tpublic const StringComparison EnumFromAnotherAssembly = StringComparison.OrdinalIgnoreCase;\n\t\tpublic const MyEnum DefaultOfEnum = default(MyEnum);\n\n\t\tpublic const int SOsb = sizeof(sbyte);\n\t\tpublic const int SOb = sizeof(byte);\n\t\tpublic const int SOs = sizeof(short);\n\t\tpublic const int SOus = sizeof(ushort);\n\t\tpublic const int SOi = sizeof(int);\n\t\tpublic const int SOui = sizeof(uint);\n\t\tpublic const int SOl = sizeof(long);\n\t\tpublic const int SOul = sizeof(ulong);\n\t\tpublic const int SOc = sizeof(char);\n\t\tpublic const int SOf = sizeof(float);\n\t\tpublic const int SOd = sizeof(double);\n\t\tpublic const int SObl = sizeof(bool);\n\t\tpublic const int SOe = sizeof(MyEnum);\n\n\t\tpublic const byte CNewb = new byte();\n\t\tpublic const sbyte CNewsb = new sbyte();\n\t\tpublic const char CNewc = new char();\n\t\tpublic const short CNews = new short();\n\t\tpublic const ushort CNewus = new ushort();\n\t\tpublic const int CNewi = new int();\n\t\tpublic const uint CNewui = new uint();\n\t\tpublic const long CNewl = new long();\n\t\tpublic const ulong CNewul = new ulong();\n\t\tpublic const double CNewd = new double();\n\t\tpublic const float CNewf = new float();\n\t\tpublic const decimal CNewm = new decimal();\n\t}\n\n\tpublic interface IExplicitImplementationTests\n\t{\n\t\tvoid M(int a);\n\t\tint P { get; set; }\n\t\tevent Action E;\n\t\tint this[int x] { get; set; }\n\t}\n\n\tpublic class ExplicitImplementationTests : IExplicitImplementationTests\n\t{\n\t\tpublic void M(int a) { }\n\t\tpublic int P { get; set; }\n\t\tpublic event Action E;\n\t\tpublic int this[int x] { get { return 0; } set { } }\n\n\t\tvoid IExplicitImplementationTests.M(int a) { }\n\t\tint IExplicitImplementationTests.P { get; set; }\n\t\tevent Action IExplicitImplementationTests.E { add { } remove { } }\n\t\tint IExplicitImplementationTests.this[int x] { get { return 0; } set { } }\n\t}\n\n\t[TypeTest(C, typeof(Inner), typeof(int)), My]\n\tpublic class ClassWithAttributesUsingNestedMembers\n\t{\n\t\tsealed class MyAttribute : Attribute { }\n\n\t\tconst int C = 42;\n\t\tclass Inner\n\t\t{\n\t\t}\n\n\t\t[TypeTest(C, typeof(Inner), typeof(int)), My]\n\t\tpublic int P { get; set; }\n\n\t\t[TypeTest(C, typeof(Inner), typeof(int)), My]\n\t\tclass AttributedInner\n\t\t{\n\t\t}\n\n\t\t[TypeTest(C, typeof(Inner), typeof(int)), My]\n\t\tclass AttributedInner2\n\t\t{\n\t\t\tsealed class MyAttribute : Attribute { }\n\n\t\t\tconst int C = 43;\n\t\t\tclass Inner { }\n\t\t}\n\t}\n\n\tpublic struct GenericStructWithIDisposableConstraintAndImplicitConversion<T> where T : IDisposable\n\t{\n\t\tpublic static implicit operator GenericStructWithIDisposableConstraintAndImplicitConversion<T>(T s)\n\t\t{\n\t\t\treturn default(GenericStructWithIDisposableConstraintAndImplicitConversion<T>);\n\t\t}\n\t}\n\n\tpublic class ClassImplementingIDisposable : IDisposable\n\t{\n\t\tpublic void Dispose() { }\n\t}\n\n\tpublic class ClassWithAttributeOnTypeParameter<[Double(2)] T> { }\n\n\t[Guid(\"790C6E0B-9194-4cc9-9426-A48A63185696\"), InterfaceType(ComInterfaceType.InterfaceIsDual)]\n\t[ComImport]\n\tpublic interface IMarshalAsTests\n\t{\n\t\t[DispId(48)]\n\t\tvoid AliasComponent([MarshalAs(UnmanagedType.BStr)][In] string bstrSrcApplicationIDOrName, [MarshalAs(UnmanagedType.BStr)][In] string bstrCLSIDOrProgID, [MarshalAs(UnmanagedType.BStr)][In] string bstrDestApplicationIDOrName, [MarshalAs(UnmanagedType.BStr)][In] string bstrNewProgId, [MarshalAs(UnmanagedType.BStr)][In] string bstrNewClsid);\n\n\t\t[DispId(33)]\n\t\t[return: MarshalAs(UnmanagedType.VariantBool)]\n\t\tbool AreApplicationInstancesPaused([MarshalAs(UnmanagedType.LPStruct)][In] object pVarApplicationInstanceID);\n\n\t\t[DispId(19)]\n\t\tvoid BackupREGDB([MarshalAs(UnmanagedType.BStr)][In] string bstrBackupFilePath);\n\n\t\t[DispId(2)]\n\t\t[return: MarshalAs(UnmanagedType.Interface)]\n\t\tobject Connect([MarshalAs(UnmanagedType.BStr)][In] string connectStr);\n\n\t\t[DispId(45)]\n\t\tvoid CopyApplications([MarshalAs(UnmanagedType.BStr)][In] string bstrSourcePartitionIDOrName, [MarshalAs(UnmanagedType.LPStruct)][In] object pVarApplicationID, [MarshalAs(UnmanagedType.BStr)][In] string bstrDestinationPartitionIDOrName);\n\n\t\t[DispId(46)]\n\t\tvoid CopyComponents([MarshalAs(UnmanagedType.BStr)][In] string bstrSourceApplicationIDOrName, [MarshalAs(UnmanagedType.LPStruct)][In] object pVarCLSIDOrProgID, [MarshalAs(UnmanagedType.BStr)][In] string bstrDestinationApplicationIDOrName);\n\n\t\t[DispId(36)]\n\t\tvoid CreateServiceForApplication([MarshalAs(UnmanagedType.BStr)][In] string bstrApplicationIDOrName, [MarshalAs(UnmanagedType.BStr)][In] string bstrServiceName, [MarshalAs(UnmanagedType.BStr)][In] string bstrStartType, [MarshalAs(UnmanagedType.BStr)][In] string bstrErrorControl, [MarshalAs(UnmanagedType.BStr)][In] string bstrDependencies, [MarshalAs(UnmanagedType.BStr)][In] string bstrRunAs, [MarshalAs(UnmanagedType.BStr)][In] string bstrPassword, [MarshalAs(UnmanagedType.VariantBool)][In] bool bDesktopOk);\n\n\t\t[DispId(40)]\n\t\tvoid CurrentPartition([MarshalAs(UnmanagedType.BStr)][In] string bstrPartitionIDOrName);\n\n\t\t[DispId(41)]\n\t\t[return: MarshalAs(UnmanagedType.BStr)]\n\t\tstring CurrentPartitionID();\n\n\t\t[DispId(42)]\n\t\t[return: MarshalAs(UnmanagedType.BStr)]\n\t\tstring CurrentPartitionName();\n\n\t\t[DispId(37)]\n\t\tvoid DeleteServiceForApplication([MarshalAs(UnmanagedType.BStr)][In] string bstrApplicationIDOrName);\n\n\t\t[DispId(34)]\n\t\t[return: MarshalAs(UnmanagedType.BStr)]\n\t\tstring DumpApplicationInstance([MarshalAs(UnmanagedType.BStr)][In] string bstrApplicationInstanceID, [MarshalAs(UnmanagedType.BStr)][In] string bstrDirectory, [MarshalAs(UnmanagedType.I4)][In] int lMaxImages);\n\n\t\t[DispId(9)]\n\t\tvoid ExportApplication([MarshalAs(UnmanagedType.BStr)][In] string bstrApplIdOrName, [MarshalAs(UnmanagedType.BStr)][In] string bstrApplicationFile, [In] int lOptions);\n\n\t\t[DispId(54)]\n\t\tvoid ExportPartition([MarshalAs(UnmanagedType.BStr)][In] string bstrPartitionIDOrName, [MarshalAs(UnmanagedType.BStr)][In] string bstrPartitionFileName, [MarshalAs(UnmanagedType.I4)][In] int lOptions);\n\n\t\t[DispId(44)]\n\t\tvoid FlushPartitionCache();\n\n\t\t[DispId(28)]\n\t\t[return: MarshalAs(UnmanagedType.BStr)]\n\t\tstring GetApplicationInstanceIDFromProcessID([MarshalAs(UnmanagedType.I4)][In] int lProcessID);\n\n\t\t[DispId(1)]\n\t\t[return: MarshalAs(UnmanagedType.Interface)]\n\t\tobject GetCollection([MarshalAs(UnmanagedType.BStr)][In] string bstrCollName);\n\n\t\t[DispId(5)]\n\t\t[return: MarshalAs(UnmanagedType.Interface)]\n\t\tobject GetCollectionByQuery([MarshalAs(UnmanagedType.BStr)][In] string collName, [MarshalAs(UnmanagedType.SafeArray)][In] ref object[] aQuery);\n\n\t\t[DispId(27)]\n\t\t[return: MarshalAs(UnmanagedType.Interface)]\n\t\tobject GetCollectionByQuery2([MarshalAs(UnmanagedType.BStr)][In] string bstrCollectionName, [MarshalAs(UnmanagedType.LPStruct)][In] object pVarQueryStrings);\n\n\t\t[DispId(57)]\n\t\t[return: MarshalAs(UnmanagedType.I4)]\n\t\tint GetComponentVersionCount([MarshalAs(UnmanagedType.BStr)][In] string bstrCLSIDOrProgID);\n\n\t\t[DispId(26)]\n\t\tvoid GetEventClassesForIID([In] string bstrIID, [MarshalAs(UnmanagedType.SafeArray)][In][Out] ref object[] varCLSIDS, [MarshalAs(UnmanagedType.SafeArray)][In][Out] ref object[] varProgIDs, [MarshalAs(UnmanagedType.SafeArray)][In][Out] ref object[] varDescriptions);\n\n\t\t[DispId(17)]\n\t\tvoid GetMultipleComponentsInfo([MarshalAs(UnmanagedType.BStr)][In] string bstrApplIdOrName, [In] object varFileNames, [MarshalAs(UnmanagedType.SafeArray)] out object[] varCLSIDS, [MarshalAs(UnmanagedType.SafeArray)] out object[] varClassNames, [MarshalAs(UnmanagedType.SafeArray)] out object[] varFileFlags, [MarshalAs(UnmanagedType.SafeArray)] out object[] varComponentFlags);\n\n\t\t[DispId(38)]\n\t\t[return: MarshalAs(UnmanagedType.BStr)]\n\t\tstring GetPartitionID([MarshalAs(UnmanagedType.BStr)][In] string bstrApplicationIDOrName);\n\n\t\t[DispId(39)]\n\t\t[return: MarshalAs(UnmanagedType.BStr)]\n\t\tstring GetPartitionName([MarshalAs(UnmanagedType.BStr)][In] string bstrApplicationIDOrName);\n\n\t\t[DispId(43)]\n\t\t[return: MarshalAs(UnmanagedType.BStr)]\n\t\tstring GlobalPartitionID();\n\n\t\t[DispId(6)]\n\t\tvoid ImportComponent([MarshalAs(UnmanagedType.BStr)][In] string bstrApplIdOrName, [MarshalAs(UnmanagedType.BStr)][In] string bstrCLSIDOrProgId);\n\n\t\t[DispId(52)]\n\t\tvoid ImportComponents([MarshalAs(UnmanagedType.BStr)][In] string bstrApplicationIDOrName, [MarshalAs(UnmanagedType.LPStruct)][In] object pVarCLSIDOrProgID, [MarshalAs(UnmanagedType.LPStruct)][In] object pVarComponentType);\n\n\t\t[DispId(50)]\n\t\tvoid ImportUnconfiguredComponents([MarshalAs(UnmanagedType.BStr)][In] string bstrApplicationIDOrName, [MarshalAs(UnmanagedType.LPStruct)][In] object pVarCLSIDOrProgID, [MarshalAs(UnmanagedType.LPStruct)][In] object pVarComponentType);\n\n\t\t[DispId(10)]\n\t\tvoid InstallApplication([MarshalAs(UnmanagedType.BStr)][In] string bstrApplicationFile, [MarshalAs(UnmanagedType.BStr)][In] string bstrDestinationDirectory, [In] int lOptions, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserId, [MarshalAs(UnmanagedType.BStr)][In] string bstrPassword, [MarshalAs(UnmanagedType.BStr)][In] string bstrRSN);\n\n\t\t[DispId(7)]\n\t\tvoid InstallComponent([MarshalAs(UnmanagedType.BStr)][In] string bstrApplIdOrName, [MarshalAs(UnmanagedType.BStr)][In] string bstrDLL, [MarshalAs(UnmanagedType.BStr)][In] string bstrTLB, [MarshalAs(UnmanagedType.BStr)][In] string bstrPSDLL);\n\n\t\t[DispId(25)]\n\t\tvoid InstallEventClass([MarshalAs(UnmanagedType.BStr)][In] string bstrApplIdOrName, [MarshalAs(UnmanagedType.BStr)][In] string bstrDLL, [MarshalAs(UnmanagedType.BStr)][In] string bstrTLB, [MarshalAs(UnmanagedType.BStr)][In] string bstrPSDLL);\n\n\t\t[DispId(16)]\n\t\tvoid InstallMultipleComponents([MarshalAs(UnmanagedType.BStr)][In] string bstrApplIdOrName, [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)][In] ref object[] fileNames, [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)][In] ref object[] CLSIDS);\n\n\t\t[DispId(24)]\n\t\tvoid InstallMultipleEventClasses([MarshalAs(UnmanagedType.BStr)][In] string bstrApplIdOrName, [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)][In] ref object[] fileNames, [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)][In] ref object[] CLSIDS);\n\n\t\t[DispId(55)]\n\t\tvoid InstallPartition([MarshalAs(UnmanagedType.BStr)][In] string bstrFileName, [MarshalAs(UnmanagedType.BStr)][In] string bstrDestDirectory, [MarshalAs(UnmanagedType.I4)][In] int lOptions, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserID, [MarshalAs(UnmanagedType.BStr)][In] string bstrPassword, [MarshalAs(UnmanagedType.BStr)][In] string bstrRSN);\n\n\t\t[DispId(53)]\n\t\t[return: MarshalAs(UnmanagedType.VariantBool)]\n\t\tbool Is64BitCatalogServer();\n\n\t\t[DispId(35)]\n\t\t[return: MarshalAs(UnmanagedType.VariantBool)]\n\t\tbool IsApplicationInstanceDumpSupported();\n\n\t\t[DispId(49)]\n\t\t[return: MarshalAs(UnmanagedType.Interface)]\n\t\tobject IsSafeToDelete([MarshalAs(UnmanagedType.BStr)][In] string bstrDllName);\n\n\t\t[DispId(3)]\n\t\tint MajorVersion();\n\n\t\t[DispId(4)]\n\t\tint MinorVersion();\n\n\t\t[DispId(47)]\n\t\tvoid MoveComponents([MarshalAs(UnmanagedType.BStr)][In] string bstrSourceApplicationIDOrName, [MarshalAs(UnmanagedType.LPStruct)][In] object pVarCLSIDOrProgID, [MarshalAs(UnmanagedType.BStr)][In] string bstrDestinationApplicationIDOrName);\n\n\t\t[DispId(30)]\n\t\tvoid PauseApplicationInstances([MarshalAs(UnmanagedType.LPStruct)][In] object pVarApplicationInstanceID);\n\n\t\t[DispId(51)]\n\t\tvoid PromoteUnconfiguredComponents([MarshalAs(UnmanagedType.BStr)][In] string bstrApplicationIDOrName, [MarshalAs(UnmanagedType.LPStruct)][In] object pVarCLSIDOrProgID, [MarshalAs(UnmanagedType.LPStruct)][In] object pVarComponentType);\n\n\t\t[DispId(21)]\n\t\tvoid QueryApplicationFile([MarshalAs(UnmanagedType.BStr)][In] string bstrApplicationFile, [MarshalAs(UnmanagedType.BStr)] out string bstrApplicationName, [MarshalAs(UnmanagedType.BStr)] out string bstrApplicationDescription, [MarshalAs(UnmanagedType.VariantBool)] out bool bHasUsers, [MarshalAs(UnmanagedType.VariantBool)] out bool bIsProxy, [MarshalAs(UnmanagedType.SafeArray)] out object[] varFileNames);\n\n\t\t[DispId(56)]\n\t\t[return: MarshalAs(UnmanagedType.IDispatch)]\n\t\tobject QueryApplicationFile2([MarshalAs(UnmanagedType.BStr)][In] string bstrApplicationFile);\n\n\t\t[DispId(32)]\n\t\tvoid RecycleApplicationInstances([MarshalAs(UnmanagedType.LPStruct)][In] object pVarApplicationInstanceID, [MarshalAs(UnmanagedType.I4)][In] int lReasonCode);\n\n\t\t[DispId(18)]\n\t\tvoid RefreshComponents();\n\n\t\t[DispId(12)]\n\t\tvoid RefreshRouter();\n\n\t\t[DispId(14)]\n\t\tvoid Reserved1();\n\n\t\t[DispId(15)]\n\t\tvoid Reserved2();\n\n\t\t[DispId(20)]\n\t\tvoid RestoreREGDB([MarshalAs(UnmanagedType.BStr)][In] string bstrBackupFilePath);\n\n\t\t[DispId(31)]\n\t\tvoid ResumeApplicationInstances([MarshalAs(UnmanagedType.LPStruct)][In] object pVarApplicationInstanceID);\n\n\t\t[DispId(23)]\n\t\tint ServiceCheck([In] int lService);\n\n\t\t[DispId(8)]\n\t\tvoid ShutdownApplication([MarshalAs(UnmanagedType.BStr)][In] string bstrApplIdOrName);\n\n\t\t[DispId(29)]\n\t\tvoid ShutdownApplicationInstances([MarshalAs(UnmanagedType.LPStruct)][In] object pVarApplicationInstanceID);\n\n\t\t[DispId(22)]\n\t\tvoid StartApplication([MarshalAs(UnmanagedType.BStr)][In] string bstrApplIdOrName);\n\n\t\t[DispId(13)]\n\t\tvoid StartRouter();\n\n\t\t[DispId(11)]\n\t\tvoid StopRouter();\n\t}\n\n\tpublic static class ExtensionEverything\n\t{\n\t\textension(int input)\n\t\t{\n\t\t\tpublic void Method() { }\n\t\t\tpublic void Method(char c) { }\n\t\t\tpublic string AsString => input.ToString();\n\t\t\tpublic string Test {\n\t\t\t\tget => \"Test\";\n\t\t\t\tset { }\n\t\t\t}\n\t\t\tpublic static void StaticMethod() { }\n\t\t\tpublic static void StaticMethod(double x) { }\n\t\t\tpublic static string StaticProperty => \"StaticProperty\";\n\t\t\tpublic static void GenericMethod<T>(T value)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\textension(int number)\n\t\t{\n\t\t\tpublic int Squared => number * number;\n\t\t}\n\n\t\textension(string input)\n\t\t{\n\t\t\tpublic void Method() { }\n\t\t\tpublic void Method(char c) { }\n\t\t\tpublic string AsString => input.ToString();\n\t\t\tpublic string Test {\n\t\t\t\tget => \"Test\";\n\t\t\t\tset { }\n\t\t\t}\n\t\t\tpublic static void StaticMethodOnString() { }\n\t\t\tpublic static void StaticMethodOnString(double x) { }\n\t\t\tpublic static string StaticPropertyOnString => \"StaticProperty\";\n\t\t\tpublic static void GenericMethodOnString<T>(T value)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\textension<T>(T input)\n\t\t{\n\t\t\tpublic void Method() { }\n\t\t\tpublic void Method(char c) { }\n\t\t\tpublic string AsString => input.ToString();\n\t\t\tpublic string Test {\n\t\t\t\tget => \"Test\";\n\t\t\t\tset { }\n\t\t\t}\n\t\t\tpublic static void StaticMethodOnGeneric() { }\n\t\t\tpublic static void StaticMethodOnGeneric(double x) { }\n\t\t\tpublic static string StaticPropertyOnGeneric => \"StaticProperty\";\n\t\t\tpublic static void GenericMethodOnGeneric<U>(U value)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\textension<T, T2>(T input)\n\t\t{\n\t\t\tpublic void StaticMethodOnGenericTwoParams(T2 x)\n\t\t\t{\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/UglyTestRunner.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.Tests.Helpers;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests\n{\n\t[TestFixture, Parallelizable(ParallelScope.All)]\n\tpublic class UglyTestRunner\n\t{\n\t\tstatic readonly string TestCasePath = Tester.TestCasePath + \"/Ugly\";\n\n\t\t[Test]\n\t\tpublic void AllFilesHaveTests()\n\t\t{\n\t\t\tvar testNames = GetType().GetMethods()\n\t\t\t\t.Where(m => m.GetCustomAttributes(typeof(TestAttribute), false).Any())\n\t\t\t\t.Select(m => m.Name)\n\t\t\t\t.ToArray();\n\t\t\tforeach (var file in new DirectoryInfo(TestCasePath).EnumerateFiles())\n\t\t\t{\n\t\t\t\tif (file.Extension.Equals(\".il\", StringComparison.OrdinalIgnoreCase)\n\t\t\t\t\t|| file.Extension.Equals(\".cs\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t{\n\t\t\t\t\tvar testName = file.Name.Split('.')[0];\n\t\t\t\t\tAssert.That(testNames, Has.Member(testName));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic readonly CompilerOptions[] noRoslynOptions =\n\t\t{\n\t\t\tCompilerOptions.None,\n\t\t\tCompilerOptions.Optimize\n\t\t};\n\n\t\tstatic readonly CompilerOptions[] roslynOnlyOptions =\n\t\t{\n\t\t\tCompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,\n\t\t};\n\n\t\tstatic readonly CompilerOptions[] defaultOptions =\n\t\t{\n\t\t\tCompilerOptions.None,\n\t\t\tCompilerOptions.Optimize,\n\t\t\tCompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,\n\t\t};\n\n\t\t[Test]\n\t\tpublic async Task NoArrayInitializers([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings(CSharp.LanguageVersion.CSharp1) {\n\t\t\t\tArrayInitializers = false\n\t\t\t});\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task NoDecimalConstants([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings(CSharp.LanguageVersion.CSharp1) {\n\t\t\t\tDecimalConstants = false\n\t\t\t});\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task NoExtensionMethods([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings(CSharp.LanguageVersion.CSharp9_0) {\n\t\t\t\tExtensionMethods = false\n\t\t\t});\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task NoForEachStatement([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings(CSharp.LanguageVersion.CSharp1) {\n\t\t\t\tForEachStatement = false,\n\t\t\t\tUseEnhancedUsing = false,\n\t\t\t});\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task NoLocalFunctions([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings(CSharp.LanguageVersion.CSharp1));\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task NoPropertiesAndEvents([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings(CSharp.LanguageVersion.CSharp1) {\n\t\t\t\tAutomaticEvents = false,\n\t\t\t\tAutomaticProperties = false,\n\t\t\t});\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task AggressiveScalarReplacementOfAggregates([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings(CSharp.LanguageVersion.CSharp3) {\n\t\t\t\tAggressiveScalarReplacementOfAggregates = true\n\t\t\t});\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task NoNewOfT([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)\n\t\t{\n\t\t\tawait RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings(CSharp.LanguageVersion.CSharp1));\n\t\t}\n\n\t\tasync Task RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null)\n\t\t{\n\t\t\tawait Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CompilerOptions.Library, decompilerSettings);\n\t\t}\n\n\t\tasync Task Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null)\n\t\t{\n\t\t\tvar ilFile = Path.Combine(TestCasePath, testName) + Tester.GetSuffix(cscOptions) + \".il\";\n\t\t\tvar csFile = Path.Combine(TestCasePath, testName + \".cs\");\n\t\t\tvar expectedFile = Path.Combine(TestCasePath, testName + \".Expected.cs\");\n\n\t\t\tif (!File.Exists(ilFile))\n\t\t\t{\n\t\t\t\t// re-create .il file if necessary\n\t\t\t\tHelpers.CompilerResults output = null;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\toutput = await Tester.CompileCSharp(csFile, cscOptions).ConfigureAwait(false);\n\t\t\t\t\tawait Tester.Disassemble(output.PathToAssembly, ilFile, asmOptions).ConfigureAwait(false);\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tif (output != null)\n\t\t\t\t\t\toutput.DeleteTempFiles();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar executable = await Tester.AssembleIL(ilFile, asmOptions).ConfigureAwait(false);\n\t\t\tvar decompiled = await Tester.DecompileCSharp(executable, decompilerSettings).ConfigureAwait(false);\n\n\t\t\tCodeAssert.FilesAreEqual(expectedFile, decompiled, Tester.GetPreprocessorSymbols(cscOptions).ToArray());\n\t\t\tTester.RepeatOnIOError(() => File.Delete(decompiled));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/Util/BitSetTests.cs",
    "content": "// Copyright (c) 2017 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.Util;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests.Util\n{\n\t[TestFixture]\n\tpublic class BitSetTests\n\t{\n\t\t[Test]\n\t\tpublic void SetRange()\n\t\t{\n\t\t\tvar bitset = new BitSet(302);\n\t\t\tbitset.Set(2, 300);\n\t\t\tAssert.That(!bitset[0]);\n\t\t\tAssert.That(!bitset[1]);\n\t\t\tfor (int i = 2; i < 300; ++i)\n\t\t\t{\n\t\t\t\tAssert.That(bitset[i]);\n\t\t\t}\n\t\t\tAssert.That(!bitset[301]);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ClearRange()\n\t\t{\n\t\t\tvar bitset = new BitSet(300);\n\t\t\tbitset.Set(0, 300);\n\t\t\tbitset.Clear(1, 299);\n\t\t\tAssert.That(bitset[0]);\n\t\t\tfor (int i = 1; i < 299; ++i)\n\t\t\t{\n\t\t\t\tAssert.That(!bitset[i]);\n\t\t\t}\n\t\t\tAssert.That(bitset[299]);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void AllInRange()\n\t\t{\n\t\t\tvar bitset = new BitSet(300);\n\t\t\tbitset.Set(1, 299);\n\t\t\tAssert.That(bitset.All(1, 299));\n\t\t\tAssert.That(bitset.All(10, 290));\n\t\t\tAssert.That(bitset.All(100, 200));\n\t\t\tAssert.That(!bitset.All(0, 200));\n\t\t\tAssert.That(!bitset.All(0, 1));\n\t\t\tAssert.That(!bitset.All(1, 300));\n\t\t\tbitset[200] = false;\n\t\t\tAssert.That(!bitset.All(1, 299));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NextBitSet()\n\t\t{\n\t\t\tvar bitset = new BitSet(300);\n\t\t\tbitset.Set(0);\n\t\t\tbitset.Set(2);\n\t\t\tbitset.Set(3);\n\t\t\tbitset.Set(130);\n\t\t\tbitset.Set(135);\n\t\t\tbitset.Set(150);\n\t\t\tbitset.Set(190);\n\t\t\tAssert.That(bitset.SetBits(0, 300), Is.EqualTo(new[] { 0, 2, 3, 130, 135, 150, 190 }));\n\t\t\tAssert.That(bitset.SetBits(1, 5), Is.EqualTo(new[] { 2, 3 }));\n\t\t\tAssert.That(bitset.SetBits(5, 132), Is.EqualTo(new[] { 130 }));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/Util/FileUtilityTests.cs",
    "content": "// Copyright (c) 2020 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.Util;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests.Util\n{\n\t[TestFixture]\n\tpublic class FileUtilityTests\n\t{\n\t\t#region NormalizePath\n\t\t[Test]\n\t\tpublic void NormalizePath()\n\t\t{\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"c:\\temp\\project\\..\\test.txt\"), Is.EqualTo(@\"c:\\temp\\test.txt\"));\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"c:\\temp\\project\\.\\..\\test.txt\"), Is.EqualTo(@\"c:\\temp\\test.txt\"));\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"c:\\temp\\\\test.txt\"), Is.EqualTo(@\"c:\\temp\\test.txt\")); // normalize double backslash\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"c:\\temp\\.\"), Is.EqualTo(@\"c:\\temp\"));\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"c:\\temp\\subdir\\..\"), Is.EqualTo(@\"c:\\temp\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NormalizePath_DriveRoot()\n\t\t{\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"C:\\\"), Is.EqualTo(@\"C:\\\"));\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"C:/\"), Is.EqualTo(@\"C:\\\"));\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"C:\"), Is.EqualTo(@\"C:\\\"));\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"C:/.\"), Is.EqualTo(@\"C:\\\"));\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"C:/..\"), Is.EqualTo(@\"C:\\\"));\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"C:/./\"), Is.EqualTo(@\"C:\\\"));\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"C:/..\\\"), Is.EqualTo(@\"C:\\\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NormalizePath_UNC()\n\t\t{\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"\\\\server\\share\"), Is.EqualTo(@\"\\\\server\\share\"));\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"\\\\server\\share\\\"), Is.EqualTo(@\"\\\\server\\share\"));\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"//server/share/\"), Is.EqualTo(@\"\\\\server\\share\"));\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"//server/share/dir/..\\otherdir\"), Is.EqualTo(@\"\\\\server\\share\\otherdir\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NormalizePath_Web()\n\t\t{\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"http://danielgrunwald.de/path/\"), Is.EqualTo(@\"http://danielgrunwald.de/path/\"));\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"browser://http://danielgrunwald.de/wrongpath/../path/\"), Is.EqualTo(@\"browser://http://danielgrunwald.de/path/\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NormalizePath_Relative()\n\t\t{\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"..\\a\\..\\b\"), Is.EqualTo(@\"../b\"));\n\t\t\tAssert.That(FileUtility.NormalizePath(@\".\"), Is.EqualTo(@\".\"));\n\t\t\tAssert.That(FileUtility.NormalizePath(@\"a\\..\"), Is.EqualTo(@\".\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NormalizePath_UnixStyle()\n\t\t{\n\t\t\tAssert.That(FileUtility.NormalizePath(\"/\"), Is.EqualTo(\"/\"));\n\t\t\tAssert.That(FileUtility.NormalizePath(\"/a/b\"), Is.EqualTo(\"/a/b\"));\n\t\t\tAssert.That(FileUtility.NormalizePath(\"/c/../a/./b\"), Is.EqualTo(\"/a/b\"));\n\t\t\tAssert.That(FileUtility.NormalizePath(\"/c/../../a/./b\"), Is.EqualTo(\"/a/b\"));\n\t\t}\n\t\t#endregion\n\n\t\t[Test]\n\t\tpublic void TestIsBaseDirectory()\n\t\t{\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\"C:\\a\", @\"C:\\A\\b\\hello\"));\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\"C:\\a\", @\"C:\\a\"));\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\"C:\\a\\\", @\"C:\\a\\\"));\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\"C:\\a\\\", @\"C:\\a\"));\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\"C:\\a\", @\"C:\\a\\\"));\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\"C:\\A\", @\"C:\\a\"));\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\"C:\\a\", @\"C:\\A\"));\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\"C:\\a\\x\\fWufhweoe\", @\"C:\\a\\x\\fwuFHweoe\\a\\b\\hello\"));\n\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\"C:\\b\\..\\A\", @\"C:\\a\"));\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\"C:\\HELLO\\..\\B\\..\\a\", @\"C:\\b\\..\\a\"));\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\"C:\\.\\B\\..\\.\\.\\a\", @\"C:\\.\\.\\.\\.\\.\\.\\.\\a\"));\n\n\t\t\tAssert.That(!FileUtility.IsBaseDirectory(@\"C:\\b\", @\"C:\\a\\b\\hello\"));\n\t\t\tAssert.That(!FileUtility.IsBaseDirectory(@\"C:\\a\\b\\hello\", @\"C:\\b\"));\n\t\t\tAssert.That(!FileUtility.IsBaseDirectory(@\"C:\\a\\x\\fwufhweoe\", @\"C:\\a\\x\\fwuFHweoex\\a\\b\\hello\"));\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\"C:\\\", @\"C:\\\"));\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\"C:\\\", @\"C:\\a\\b\\hello\"));\n\t\t\tAssert.That(!FileUtility.IsBaseDirectory(@\"C:\\\", @\"D:\\a\\b\\hello\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestIsBaseDirectoryRelative()\n\t\t{\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\".\", @\"a\\b\"));\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\".\", @\"a\"));\n\t\t\tAssert.That(!FileUtility.IsBaseDirectory(@\".\", @\"c:\\\"));\n\t\t\tAssert.That(!FileUtility.IsBaseDirectory(@\".\", @\"/\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestIsBaseDirectoryUnixStyle()\n\t\t{\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\"/\", @\"/\"));\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\"/\", @\"/a\"));\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\"/\", @\"/a/subdir\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestIsBaseDirectoryUNC()\n\t\t{\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\"\\\\server\\share\", @\"\\\\server\\share\\dir\\subdir\"));\n\t\t\tAssert.That(FileUtility.IsBaseDirectory(@\"\\\\server\\share\", @\"\\\\server\\share\\dir\\subdir\"));\n\t\t\tAssert.That(!FileUtility.IsBaseDirectory(@\"\\\\server2\\share\", @\"\\\\server\\share\\dir\\subdir\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestGetRelativePath()\n\t\t{\n\t\t\tAssert.That(FileUtility.GetRelativePath(@\"C:\\hello\\.\\..\\a\", @\"C:\\.\\a\\blub\"), Is.EqualTo(@\"blub\"));\n\t\t\tAssert.That(FileUtility.GetRelativePath(@\"C:\\.\\.\\.\\.\\hello\", @\"C:\\.\\blub\\.\\..\\.\\a\\.\\blub\"), Is.EqualTo(@\"..\\a\\blub\"));\n\t\t\tAssert.That(FileUtility.GetRelativePath(@\"C:\\.\\.\\.\\.\\hello\\\", @\"C:\\.\\blub\\.\\..\\.\\a\\.\\blub\"), Is.EqualTo(@\"..\\a\\blub\"));\n\t\t\tAssert.That(FileUtility.GetRelativePath(@\"C:\\hello\", @\"C:\\.\\hello\"), Is.EqualTo(@\".\"));\n\t\t\tAssert.That(FileUtility.GetRelativePath(@\"C:\\\", @\"C:\\\"), Is.EqualTo(@\".\"));\n\t\t\tAssert.That(FileUtility.GetRelativePath(@\"C:\\\", @\"C:\\blub\"), Is.EqualTo(@\"blub\"));\n\t\t\tAssert.That(FileUtility.GetRelativePath(@\"C:\\\", @\"D:\\\"), Is.EqualTo(@\"D:\\\"));\n\t\t\tAssert.That(FileUtility.GetRelativePath(@\"C:\\abc\", @\"D:\\def\"), Is.EqualTo(@\"D:\\def\"));\n\n\t\t\t// casing troubles\n\t\t\tAssert.That(FileUtility.GetRelativePath(@\"C:\\hello\\.\\..\\A\", @\"C:\\.\\a\\blub\"), Is.EqualTo(@\"blub\"));\n\t\t\tAssert.That(FileUtility.GetRelativePath(@\"C:\\.\\.\\.\\.\\HELlo\", @\"C:\\.\\blub\\.\\..\\.\\a\\.\\blub\"), Is.EqualTo(@\"..\\a\\blub\"));\n\t\t\tAssert.That(FileUtility.GetRelativePath(@\"C:\\.\\.\\.\\.\\heLLo\\A\\..\", @\"C:\\.\\blub\\.\\..\\.\\a\\.\\blub\"), Is.EqualTo(@\"..\\a\\blub\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void RelativeGetRelativePath()\n\t\t{\n\t\t\t// Relative path\n\t\t\tAssert.That(FileUtility.GetRelativePath(@\".\", @\"a\"), Is.EqualTo(@\"a\"));\n\t\t\tAssert.That(FileUtility.GetRelativePath(@\"a\", @\".\"), Is.EqualTo(@\"..\"));\n\t\t\tAssert.That(FileUtility.GetRelativePath(@\"a\", @\"b\"), Is.EqualTo(@\"..\\b\"));\n\t\t\tAssert.That(FileUtility.GetRelativePath(@\"a\", @\"..\"), Is.EqualTo(@\"..\\..\"));\n\n\t\t\t// Getting a path from an absolute path to a relative path isn't really possible;\n\t\t\t// so we just keep the existing relative path (don't introduce incorrect '..\\').\n\t\t\tAssert.That(FileUtility.GetRelativePath(@\"C:\\abc\", @\"def\"), Is.EqualTo(@\"def\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void GetRelativePath_Unix()\n\t\t{\n\t\t\tAssert.That(FileUtility.GetRelativePath(\"/\", \"/a\"), Is.EqualTo(@\"a\"));\n\t\t\tAssert.That(FileUtility.GetRelativePath(\"/\", \"/a/b\"), Is.EqualTo(@\"a\\b\"));\n\t\t\tAssert.That(FileUtility.GetRelativePath(\"/a\", \"/a/b\"), Is.EqualTo(@\"b\"));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void TestIsEqualFile()\n\t\t{\n\t\t\tAssert.That(FileUtility.IsEqualFileName(@\"C:\\.\\Hello World.Exe\", @\"C:\\HELLO WOrld.exe\"));\n\t\t\tAssert.That(FileUtility.IsEqualFileName(@\"C:\\bla\\..\\a\\my.file.is.this\", @\"C:\\gg\\..\\.\\.\\.\\.\\a\\..\\a\\MY.FILE.IS.THIS\"));\n\n\t\t\tAssert.That(!FileUtility.IsEqualFileName(@\"C:\\.\\Hello World.Exe\", @\"C:\\HELLO_WOrld.exe\"));\n\t\t\tAssert.That(!FileUtility.IsEqualFileName(@\"C:\\a\\my.file.is.this\", @\"C:\\gg\\..\\.\\.\\.\\.\\a\\..\\b\\MY.FILE.IS.THIS\"));\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/Util/IntervalTests.cs",
    "content": "// Copyright (c) 2014 Daniel Grunwald\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.Util;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests.Util\n{\n\tpublic class IntervalTests\n\t{\n\t\t[Test]\n\t\tpublic void DefaultIsEmpty()\n\t\t{\n\t\t\tAssert.That(default(Interval).IsEmpty);\n\t\t\tAssert.That(!default(Interval).Contains(-1));\n\t\t\tAssert.That(!default(Interval).Contains(0));\n\t\t\tAssert.That(!default(Interval).Contains(1));\n\t\t}\n\t\t[Test]\n\t\tpublic void EmptyAt1()\n\t\t{\n\t\t\tInterval i = new Interval(1, 1);\n\t\t\tAssert.That(default(Interval).IsEmpty);\n\t\t\tAssert.That(!default(Interval).Contains(-1));\n\t\t\tAssert.That(!default(Interval).Contains(0));\n\t\t\tAssert.That(!default(Interval).Contains(1));\n\t\t\tAssert.That(!default(Interval).Contains(2));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void OneToThree()\n\t\t{\n\t\t\tInterval i = new Interval(1, 3);\n\t\t\tAssert.That(!i.IsEmpty);\n\t\t\tAssert.That(!i.Contains(0));\n\t\t\tAssert.That(i.Contains(1));\n\t\t\tAssert.That(i.Contains(2));\n\t\t\tAssert.That(!i.Contains(3));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void FullInterval()\n\t\t{\n\t\t\tInterval full = new Interval(int.MinValue, int.MinValue);\n\t\t\tAssert.That(!full.IsEmpty);\n\t\t\tAssert.That(full.Contains(int.MinValue));\n\t\t\tAssert.That(full.Contains(0));\n\t\t\tAssert.That(full.Contains(int.MaxValue));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NonNegativeIntegers()\n\t\t{\n\t\t\tInterval i = new Interval(0, int.MinValue);\n\t\t\tAssert.That(!i.IsEmpty);\n\t\t\tAssert.That(i.Contains(0));\n\t\t\tAssert.That(i.Contains(1000));\n\t\t\tAssert.That(i.Contains(int.MaxValue));\n\t\t\tAssert.That(!i.Contains(-1));\n\t\t\tAssert.That(!i.Contains(-1000));\n\t\t\tAssert.That(!i.Contains(int.MinValue));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Intersection()\n\t\t{\n\t\t\tInterval empty = new Interval(0, 0);\n\t\t\tInterval emptyAtOne = new Interval(0, 0);\n\t\t\tInterval zero = new Interval(0, 1);\n\t\t\tInterval full = new Interval(int.MinValue, int.MinValue);\n\t\t\tInterval nonneg = new Interval(0, int.MinValue);\n\t\t\tInterval nonpos = new Interval(int.MinValue, 1);\n\t\t\tInterval maxval = new Interval(int.MaxValue, int.MinValue);\n\t\t\tAssert.That(full.Intersect(nonneg), Is.EqualTo(nonneg));\n\t\t\tAssert.That(nonneg.Intersect(full), Is.EqualTo(nonneg));\n\t\t\tAssert.That(nonneg.Intersect(zero), Is.EqualTo(zero));\n\t\t\tAssert.That(nonneg.Intersect(nonpos), Is.EqualTo(zero));\n\t\t\tAssert.That(nonneg.Intersect(maxval), Is.EqualTo(maxval));\n\t\t\tAssert.That(nonpos.Intersect(maxval), Is.EqualTo(empty));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/Util/LongSetTests.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Immutable;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.Util;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests.Util\n{\n\t[TestFixture]\n\tpublic class LongSetTests\n\t{\n\t\t[Test]\n\t\tpublic void UpperBound()\n\t\t{\n\t\t\tvar longSet = new LongSet(new[] { new LongInterval(1, 5), new LongInterval(6, 7) }.ToImmutableArray());\n\t\t\tAssert.That(longSet.upper_bound(0), Is.EqualTo(0));\n\t\t\tfor (int i = 1; i <= 5; i++)\n\t\t\t\tAssert.That(longSet.upper_bound(i), Is.EqualTo(1));\n\t\t\tfor (int i = 6; i <= 10; i++)\n\t\t\t\tAssert.That(longSet.upper_bound(i), Is.EqualTo(2));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UniverseContainsAll()\n\t\t{\n\t\t\tAssert.That(LongSet.Universe.Contains(long.MinValue));\n\t\t\tAssert.That(LongSet.Universe.Contains(1));\n\t\t\tAssert.That(LongSet.Universe.Contains(long.MaxValue));\n\t\t\tAssert.That(!LongSet.Universe.IsEmpty);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void IntersectUniverse()\n\t\t{\n\t\t\tAssert.That(LongSet.Universe.IntersectWith(LongSet.Universe), Is.EqualTo(LongSet.Universe));\n\t\t\tAssert.That(LongSet.Universe.IntersectWith(LongSet.Empty), Is.EqualTo(LongSet.Empty));\n\t\t\tAssert.That(LongSet.Universe.IntersectWith(new LongSet(long.MaxValue)), Is.EqualTo(new LongSet(long.MaxValue)));\n\t\t\tvar longSet = new LongSet(new[] { new LongInterval(1, 5), new LongInterval(6, 7) }.ToImmutableArray());\n\t\t\tAssert.That(longSet.IntersectWith(LongSet.Universe), Is.EqualTo(longSet));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UnionUniverse()\n\t\t{\n\t\t\tAssert.That(LongSet.Universe.UnionWith(LongSet.Universe), Is.EqualTo(LongSet.Universe));\n\t\t\tAssert.That(LongSet.Universe.UnionWith(LongSet.Empty), Is.EqualTo(LongSet.Universe));\n\t\t\tAssert.That(LongSet.Universe.UnionWith(new LongSet(long.MaxValue)), Is.EqualTo(LongSet.Universe));\n\t\t\tvar longSet = new LongSet(new[] { new LongInterval(1, 5), new LongInterval(6, 7) }.ToImmutableArray());\n\t\t\tAssert.That(longSet.UnionWith(LongSet.Universe), Is.EqualTo(LongSet.Universe));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ExceptWithUniverse()\n\t\t{\n\t\t\tAssert.That(LongSet.Universe.ExceptWith(LongSet.Empty), Is.EqualTo(LongSet.Universe));\n\t\t\tAssert.That(LongSet.Universe.ExceptWith(LongSet.Universe), Is.EqualTo(LongSet.Empty));\n\t\t\tAssert.That(LongSet.Empty.ExceptWith(LongSet.Universe), Is.EqualTo(LongSet.Empty));\n\t\t\tAssert.That(LongSet.Empty.ExceptWith(LongSet.Empty), Is.EqualTo(LongSet.Empty));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void UnionWith()\n\t\t{\n\t\t\tAssert.That(new LongSet(0).UnionWith(new LongSet(1)), Is.EqualTo(new LongSet(new LongInterval(0, 2))));\n\n\t\t\tAssert.That(new LongSet(0).Invert().UnionWith(new LongSet(0)), Is.EqualTo(LongSet.Universe));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void AddTo()\n\t\t{\n\t\t\tAssert.That(new LongSet(0).AddOffset(1), Is.EqualTo(new LongSet(1)));\n\t\t\tAssert.That(new LongSet(long.MaxValue).AddOffset(1), Is.EqualTo(new LongSet(long.MinValue)));\n\n\t\t\tTestAddTo(new LongSet(new LongInterval(-10, 10)), 5);\n\t\t\tTestAddTo(new LongSet(new LongInterval(-10, 10)), long.MaxValue);\n\t\t\tAssert.That(new LongSet(0).Invert().AddOffset(10), Is.EqualTo(new LongSet(10).Invert()));\n\t\t\tAssert.That(new LongSet(30).Invert().AddOffset(-10), Is.EqualTo(new LongSet(20).Invert()));\n\t\t}\n\n\t\tvoid TestAddTo(LongSet input, long constant)\n\t\t{\n\t\t\tAssert.That(\n\t\t\t\tinput.AddOffset(constant).Values.ToList(), Is.EqualTo(input.Values.Select(e => unchecked(e + constant)).OrderBy(e => e).ToList()));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Values()\n\t\t{\n\t\t\tAssert.That(!LongSet.Empty.Values.Any());\n\t\t\tAssert.That(LongSet.Universe.Values.Any());\n\t\t\tAssert.That(new LongSet(LongInterval.Inclusive(1, 3)).Values.ToArray(), Is.EqualTo(new[] { 1, 2, 3 }));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ValueCount()\n\t\t{\n\t\t\tAssert.That(LongSet.Empty.Count(), Is.EqualTo(0));\n\t\t\tAssert.That(new LongSet(3).Invert().Count(), Is.EqualTo(ulong.MaxValue));\n\t\t\tAssert.That(LongSet.Universe.Count(), Is.EqualTo(ulong.MaxValue));\n\t\t\tAssert.That(new LongSet(LongInterval.Inclusive(-1, long.MaxValue)).Count(), Is.EqualTo(long.MaxValue + 2ul));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.Tests.Helpers;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.Decompiler.Tests\n{\n\t[TestFixture, Parallelizable(ParallelScope.All)]\n\tpublic class VBPrettyTestRunner\n\t{\n\t\tstatic readonly string TestCasePath = Tester.TestCasePath + \"/VBPretty\";\n\n\t\t[Test]\n\t\tpublic void AllFilesHaveTests()\n\t\t{\n\t\t\tvar testNames = typeof(VBPrettyTestRunner).GetMethods()\n\t\t\t\t.Where(m => m.GetCustomAttributes(typeof(TestAttribute), false).Any())\n\t\t\t\t.Select(m => m.Name)\n\t\t\t\t.ToArray();\n\t\t\tforeach (var file in new DirectoryInfo(TestCasePath).EnumerateFiles())\n\t\t\t{\n\t\t\t\tif (file.Extension.Equals(\".vb\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t{\n\t\t\t\t\tvar testName = file.Name.Split('.')[0];\n\t\t\t\t\tAssert.That(testNames, Has.Member(testName));\n\t\t\t\t\tAssert.That(File.Exists(Path.Combine(TestCasePath, testName + \".cs\")));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic readonly CompilerOptions[] defaultOptions =\n\t\t{\n\t\t\tCompilerOptions.None,\n\t\t\tCompilerOptions.Optimize,\n\t\t\tCompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn1_3_2,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,\n\t\t\tCompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,\n\t\t};\n\n\t\tstatic readonly CompilerOptions[] roslynOnlyOptions =\n\t\t{\n\t\t\tCompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,\n\t\t\tCompilerOptions.UseRoslyn1_3_2,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,\n\t\t\tCompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,\n\t\t\tCompilerOptions.UseRoslynLatest,\n\t\t\tCompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,\n\t\t};\n\n\t\t[Test]\n\t\tpublic async Task Async([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait Run(options: options | CompilerOptions.Library);\n\t\t}\n\n\t\t[Test] // TODO: legacy VB compound assign\n\t\tpublic async Task VBCompoundAssign([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait Run(options: options | CompilerOptions.Library);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Select([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait Run(options: options | CompilerOptions.Library);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue1906([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait Run(options: options | CompilerOptions.Library);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task Issue2192([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait Run(options: options | CompilerOptions.Library);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task VBPropertiesTest([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait Run(options: options | CompilerOptions.Library);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task VBAutomaticEvents([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait Run(options: options | CompilerOptions.Library);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task VBNonGenericForEach([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait Run(options: options | CompilerOptions.Library);\n\t\t}\n\n\t\t[Test]\n\t\tpublic async Task YieldReturn([ValueSource(nameof(defaultOptions))] CompilerOptions options)\n\t\t{\n\t\t\tawait Run(options: options | CompilerOptions.Library);\n\t\t}\n\n\t\tasync Task Run([CallerMemberName] string testName = null, CompilerOptions options = CompilerOptions.UseDebug, DecompilerSettings settings = null)\n\t\t{\n\t\t\tvar vbFile = Path.Combine(TestCasePath, testName + \".vb\");\n\t\t\tvar csFile = Path.Combine(TestCasePath, testName + \".cs\");\n\t\t\tvar exeFile = TestsAssemblyOutput.GetFilePath(TestCasePath, testName, Tester.GetSuffix(options) + \".exe\");\n\t\t\tif (options.HasFlag(CompilerOptions.Library))\n\t\t\t{\n\t\t\t\texeFile = Path.ChangeExtension(exeFile, \".dll\");\n\t\t\t}\n\n\t\t\tvar executable = await Tester.CompileVB(vbFile, options | CompilerOptions.ReferenceVisualBasic, exeFile).ConfigureAwait(false);\n\t\t\tvar decompiled = await Tester.DecompileCSharp(executable.PathToAssembly, settings ?? new DecompilerSettings { FileScopedNamespaces = false }).ConfigureAwait(false);\n\n\t\t\tCodeAssert.FilesAreEqual(csFile, decompiled, Tester.GetPreprocessorSymbols(options).ToArray());\n\t\t\tTester.RepeatOnIOError(() => File.Delete(decompiled));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyCmd/AsContainer/Dockerfile",
    "content": "FROM mcr.microsoft.com/dotnet/sdk:8.0\n\nRUN useradd -m -s /bin/bash ilspy\nUSER ilspy\n\nWORKDIR /home/ilspy\n\nRUN dotnet tool install -g ilspycmd --version 9.1.0.7988\n\nRUN echo 'export PATH=\"$PATH:/home/ilspy/.dotnet/tools/\"' >> /home/ilspy/.bashrc\n\nENTRYPOINT [ \"/bin/bash\" ]"
  },
  {
    "path": "ICSharpCode.ILSpyCmd/AsContainer/DockerfileForAutomation",
    "content": "FROM mcr.microsoft.com/dotnet/sdk:8.0\n\nRUN useradd -m -s /bin/bash ilspy\nUSER ilspy\n\nWORKDIR /home/ilspy\n\nRUN dotnet tool install -g ilspycmd --version 9.1.0.7988\n\nRUN echo 'export PATH=\"$PATH:/home/ilspy/.dotnet/tools/\"' >> /home/ilspy/.bashrc\n\nENTRYPOINT [ \"/bin/bash\", \"-l\", \"-c\" ]"
  },
  {
    "path": "ICSharpCode.ILSpyCmd/AsContainer/README.md",
    "content": "# ILSpyCmd in Docker\n\nInspired by https://trustedsec.com/blog/hunting-deserialization-vulnerabilities-with-claude (and thus https://github.com/berdav/ilspycmd-docker)\n\n## Building the Image\n\nThere are two dockerfiles available - one for interactive use of ilspycmd (exploration), and the other for driving it from the outside (automation)\n\n### Interactive \n\n`docker build -t ilspycmd:91interactive . -f Dockerfile`\n\n`docker run --rm -it -v ./:/docker ilspycmd:91interactive`\n\n### Automation\n\n`docker build -t ilspycmd:91forautomation . -f DockerfileForAutomation`\n\n`docker run --rm -v ./:/infolder -v ./out:/outfolder ilspycmd:91forautomation \"/home/ilspy/.dotnet/tools/ilspycmd -p -o /outfolder /infolder/sample.dll\"`\n\n"
  },
  {
    "path": "ICSharpCode.ILSpyCmd/DotNetToolUpdateChecker.cs",
    "content": "using System;\nusing System.Linq;\nusing System.Reflection;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nusing NuGet.Common;\nusing NuGet.Protocol;\nusing NuGet.Protocol.Core.Types;\nusing NuGet.Versioning;\n\nnamespace ICSharpCode.ILSpyCmd\n{\n\tinternal record PackageCheckResult(NuGetVersion RunningVersion, NuGetVersion LatestVersion, bool UpdateRecommendation);\n\n\t// Idea from https://github.com/ErikEJ/EFCorePowerTools/blob/master/src/GUI/efcpt/Services/PackageService.cs\n\tinternal static class DotNetToolUpdateChecker\n\t{\n\t\tstatic NuGetVersion CurrentPackageVersion()\n\t\t{\n\t\t\treturn new NuGetVersion(Assembly.GetEntryAssembly()!.GetCustomAttribute<AssemblyInformationalVersionAttribute>()!\n\t\t\t\t.InformationalVersion);\n\t\t}\n\n\t\tpublic static async Task<PackageCheckResult> CheckForPackageUpdateAsync(string packageId)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tusing var cache = new SourceCacheContext();\n\t\t\t\tvar repository = Repository.Factory.GetCoreV3(\"https://api.nuget.org/v3/index.json\");\n\t\t\t\tvar resource = await repository.GetResourceAsync<FindPackageByIdResource>().ConfigureAwait(false);\n\n\t\t\t\tvar versions = await resource.GetAllVersionsAsync(\n\t\t\t\t\tpackageId,\n\t\t\t\t\tcache,\n\t\t\t\t\tnew NullLogger(),\n\t\t\t\t\tCancellationToken.None).ConfigureAwait(false);\n\n\t\t\t\tvar latestVersion = versions.Where(v => v.Release == \"\").MaxBy(v => v);\n\t\t\t\tvar runningVersion = CurrentPackageVersion();\n\t\t\t\tint comparisonResult = latestVersion.CompareTo(runningVersion, VersionComparison.Version);\n\n\t\t\t\treturn new PackageCheckResult(runningVersion, latestVersion, comparisonResult > 0);\n\t\t\t}\n#pragma warning disable RCS1075 // Avoid empty catch clause that catches System.Exception.\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t}\n#pragma warning restore RCS1075 // Avoid empty catch clause that catches System.Exception.\n\n\t\t\treturn null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyCmd/ICSharpCode.ILSpyCmd.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net10.0</TargetFramework>\r\n    <ServerGarbageCollection>true</ServerGarbageCollection>\r\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\r\n    <IsPackable>true</IsPackable>\r\n    <PackAsTool>true</PackAsTool>\r\n    <InvariantGlobalization>true</InvariantGlobalization>\r\n\r\n    <NeutralLanguage>en-US</NeutralLanguage>\r\n    <GenerateAssemblyVersionAttribute>False</GenerateAssemblyVersionAttribute>\r\n    <GenerateAssemblyFileVersionAttribute>False</GenerateAssemblyFileVersionAttribute>\r\n    <GenerateAssemblyInformationalVersionAttribute>False</GenerateAssemblyInformationalVersionAttribute>\r\n    <AssemblyName>ilspycmd</AssemblyName>\r\n    <ToolCommandName>ilspycmd</ToolCommandName>\r\n    <Description>Command-line decompiler using the ILSpy decompilation engine</Description>\r\n    <PackageReadmeFile>README.md</PackageReadmeFile>\r\n    <PackageVersion>8.0.0.0-noversion</PackageVersion>\r\n    <Copyright>Copyright 2011-$([System.DateTime]::Now.Year) AlphaSierraPapa</Copyright>\r\n    <PackageProjectUrl>https://github.com/icsharpcode/ILSpy/</PackageProjectUrl>\r\n    <PackageLicenseExpression>MIT</PackageLicenseExpression>\r\n    <PackageIcon>ILSpyCmdNuGetPackageIcon.png</PackageIcon>\r\n    <RepositoryUrl>https://github.com/icsharpcode/ILSpy/</RepositoryUrl>\r\n    <Company>ic#code</Company>\r\n    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>\r\n    <Authors>ILSpy Team</Authors>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <Compile Remove=\"AsContainer\\**\" />\r\n    <EmbeddedResource Remove=\"AsContainer\\**\" />\r\n    <None Remove=\"AsContainer\\**\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <None Include=\"README.md\" Pack=\"true\" PackagePath=\"\\\" />\r\n  </ItemGroup>\r\n  \r\n  <!-- https://devblogs.microsoft.com/nuget/enable-repeatable-package-restores-using-a-lock-file/ -->\r\n  <PropertyGroup>\r\n    <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>\r\n\t<RestoreLockedMode>true</RestoreLockedMode>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|AnyCPU'\">\r\n    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>\r\n    <WarningsAsErrors>NU1605</WarningsAsErrors>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <None Include=\"ILSpyCmdNuGetPackageIcon.png\" Pack=\"true\" PackagePath=\"\\\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\ICSharpCode.ILSpyX\\ICSharpCode.ILSpyX.csproj\" />\r\n    <ProjectReference Include=\"..\\ICSharpCode.Decompiler\\ICSharpCode.Decompiler.csproj\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"McMaster.Extensions.Hosting.CommandLine\" />\r\n    <PackageReference Include=\"Microsoft.Extensions.Hosting\" />\r\n    <PackageReference Include=\"NuGet.Protocol\" />\r\n    <PackageReference Include=\"System.Security.Cryptography.Pkcs\" />\r\n  </ItemGroup>\r\n\r\n  <Target Name=\"ILSpyUpdateAssemblyInfo\" AfterTargets=\"ResolveProjectReferences\">\r\n    <ReadLinesFromFile ContinueOnError=\"true\" File=\"..\\VERSION\">\r\n      <Output TaskParameter=\"Lines\" PropertyName=\"PackageVersion\" />\r\n    </ReadLinesFromFile>\r\n  </Target>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "ICSharpCode.ILSpyCmd/IlspyCmdProgram.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.IO;\nusing System.IO.Compression;\nusing System.IO.MemoryMappedFiles;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.PortableExecutable;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.CSharp.ProjectDecompiler;\nusing ICSharpCode.Decompiler.DebugInfo;\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Solution;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX.MermaidDiagrammer;\nusing ICSharpCode.ILSpyX.PdbProvider;\n\nusing McMaster.Extensions.CommandLineUtils;\n\nusing Microsoft.Extensions.Hosting;\n\nnamespace ICSharpCode.ILSpyCmd\n{\n\t[Command(Name = \"ilspycmd\", Description = \"dotnet tool for decompiling .NET assemblies and generating portable PDBs\",\n\t\tExtendedHelpText = @\"\nRemarks:\n  -o is valid with every option and required when using -p.\n\nExamples:\n    Decompile assembly to console out.\n        ilspycmd sample.dll\n\n    Decompile assembly to destination directory (single C# file).\n        ilspycmd -o c:\\decompiled sample.dll\n\n    Decompile assembly to destination directory, create a project file, one source file per type.\n        ilspycmd -p -o c:\\decompiled sample.dll\n\n    Decompile assembly to destination directory, create a project file, one source file per type, \n    into nicely nested directories.\n        ilspycmd --nested-directories -p -o c:\\decompiled sample.dll\n\n    Generate a HTML diagrammer containing all type info into a folder next to the input assembly\n        ilspycmd sample.dll --generate-diagrammer\n\n    Generate a HTML diagrammer containing filtered type info into a custom output folder\n    (including types in the LightJson namespace while excluding types in nested LightJson.Serialization namespace)\n        ilspycmd sample.dll --generate-diagrammer -o c:\\diagrammer --generate-diagrammer-include LightJson\\\\..+ --generate-diagrammer-exclude LightJson\\\\.Serialization\\\\..+\n\")]\n\t[HelpOption(\"-h|--help\")]\n\t[ProjectOptionRequiresOutputDirectoryValidation]\n\t[VersionOptionFromMember(\"-v|--version\", Description = \"Show version of ICSharpCode.Decompiler used.\",\n\t\tMemberName = nameof(DecompilerVersion))]\n\tclass ILSpyCmdProgram\n\t{\n\t\t// https://natemcmaster.github.io/CommandLineUtils/docs/advanced/generic-host.html\n\t\t// https://github.com/natemcmaster/CommandLineUtils/blob/main/docs/samples/dependency-injection/generic-host/Program.cs\n\t\tpublic static Task<int> Main(string[] args) => new HostBuilder().RunCommandLineApplicationAsync<ILSpyCmdProgram>(args);\n\n\t\t[FilesExist]\n\t\t[Required]\n\t\t[Argument(0, \"Assembly file name(s)\", \"The list of assemblies that is being decompiled. This argument is mandatory.\")]\n\t\tpublic string[] InputAssemblyNames { get; }\n\n\t\t[Option(\"-o|--outputdir <directory>\", \"The output directory, if omitted decompiler output is written to standard out.\", CommandOptionType.SingleValue)]\n\t\tpublic string OutputDirectory { get; }\n\n\t\t[Option(\"-p|--project\", \"Decompile assembly as compilable project. This requires the output directory option.\", CommandOptionType.NoValue)]\n\t\tpublic bool CreateCompilableProjectFlag { get; }\n\n\t\t[Option(\"-t|--type <type-name>\", \"The fully qualified name of the type to decompile.\", CommandOptionType.SingleValue)]\n\t\tpublic string TypeName { get; }\n\n\t\t[Option(\"-il|--ilcode\", \"Show IL code.\", CommandOptionType.NoValue)]\n\t\tpublic bool ShowILCodeFlag { get; }\n\n\t\t[Option(\"--il-sequence-points\", \"Show IL with sequence points. Implies -il.\", CommandOptionType.NoValue)]\n\t\tpublic bool ShowILSequencePointsFlag { get; }\n\n\t\t[Option(\"-genpdb|--generate-pdb\", \"Generate PDB.\", CommandOptionType.NoValue)]\n\t\tpublic bool CreateDebugInfoFlag { get; }\n\n\t\t[FileExistsOrNull]\n\t\t[Option(\"-usepdb|--use-varnames-from-pdb\", \"Use variable names from PDB.\", CommandOptionType.SingleOrNoValue)]\n\t\tpublic (bool IsSet, string Value) InputPDBFile { get; }\n\n\t\t[Option(\"-l|--list <entity-type(s)>\", \"Lists all entities of the specified type(s). Valid types: c(lass), i(nterface), s(truct), d(elegate), e(num)\", CommandOptionType.MultipleValue)]\n\t\tpublic string[] EntityTypes { get; } = Array.Empty<string>();\n\n\t\tpublic string DecompilerVersion => \"ilspycmd: \" + typeof(ILSpyCmdProgram).Assembly.GetName().Version.ToString() +\n\t\t\t\tEnvironment.NewLine\n\t\t\t\t+ \"ICSharpCode.Decompiler: \" +\n\t\t\t\ttypeof(FullTypeName).Assembly.GetName().Version.ToString();\n\n\t\t[Option(\"-lv|--languageversion <version>\", \"C# Language version: CSharp1, CSharp2, CSharp3, \" +\n\t\t\t\"CSharp4, CSharp5, CSharp6, CSharp7, CSharp7_1, CSharp7_2, CSharp7_3, CSharp8_0, CSharp9_0, \" +\n\t\t\t\"CSharp10_0, CSharp11_0, CSharp12_0, CSharp13_0, Preview or Latest\", CommandOptionType.SingleValue)]\n\t\tpublic LanguageVersion LanguageVersion { get; } = LanguageVersion.Latest;\n\n\t\t[FileExists]\n\t\t[Option(\"--ilspy-settingsfile <path>\", \"Path to an ILSpy settings file.\", CommandOptionType.SingleValue)]\n\t\tpublic string ILSpySettingsFile { get; }\n\n\t\t[Option(\"-ds|--decompiler-setting <name>=<value>\", \"Set a decompiler setting. Use multiple times to set multiple settings.\", CommandOptionType.MultipleValue)]\n\t\tpublic string[] DecompilerSettingOverrides { get; set; } = Array.Empty<string>();\n\n\t\t[DirectoryExists]\n\t\t[Option(\"-r|--referencepath <path>\", \"Path to a directory containing dependencies of the assembly that is being decompiled.\", CommandOptionType.MultipleValue)]\n\t\tpublic string[] ReferencePaths { get; }\n\n\t\t[Option(\"--no-dead-code\", \"Remove dead code.\", CommandOptionType.NoValue)]\n\t\tpublic bool RemoveDeadCode { get; }\n\n\t\t[Option(\"--no-dead-stores\", \"Remove dead stores.\", CommandOptionType.NoValue)]\n\t\tpublic bool RemoveDeadStores { get; }\n\n\t\t[Option(\"-d|--dump-package\", \"Dump package assemblies into a folder. This requires the output directory option.\", CommandOptionType.NoValue)]\n\t\tpublic bool DumpPackageFlag { get; }\n\n\t\t[Option(\"--nested-directories\", \"Use nested directories for namespaces.\", CommandOptionType.NoValue)]\n\t\tpublic bool NestedDirectories { get; }\n\n\t\t[Option(\"--disable-updatecheck\", \"If using ilspycmd in a tight loop or fully automated scenario, you might want to disable the automatic update check.\", CommandOptionType.NoValue)]\n\t\tpublic bool DisableUpdateCheck { get; }\n\n\t\t#region MermaidDiagrammer options\n\n\t\t// reused or quoted commands\n\t\tprivate const string generateDiagrammerCmd = \"--generate-diagrammer\",\n\t\t\texclude = generateDiagrammerCmd + \"-exclude\",\n\t\t\tinclude = generateDiagrammerCmd + \"-include\";\n\n\t\t[Option(generateDiagrammerCmd, \"Generates an interactive HTML diagrammer app from selected types in the target assembly\" +\n\t\t\t\" - to the --outputdir or in a 'diagrammer' folder next to to the assembly by default.\", CommandOptionType.NoValue)]\n\t\tpublic bool GenerateDiagrammer { get; }\n\n\t\t[Option(include, \"An optional regular expression matching Type.FullName used to whitelist types to include in the generated diagrammer.\", CommandOptionType.SingleValue)]\n\t\tpublic string Include { get; set; }\n\n\t\t[Option(exclude, \"An optional regular expression matching Type.FullName used to blacklist types to exclude from the generated diagrammer.\", CommandOptionType.SingleValue)]\n\t\tpublic string Exclude { get; set; }\n\n\t\t[Option(generateDiagrammerCmd + \"-report-excluded\", \"Outputs a report of types excluded from the generated diagrammer\" +\n\t\t\t$\" - whether by default because compiler-generated, explicitly by '{exclude}' or implicitly by '{include}'.\" +\n\t\t\t\" You may find this useful to develop and debug your regular expressions.\", CommandOptionType.NoValue)]\n\t\tpublic bool ReportExcludedTypes { get; set; }\n\n\t\t[Option(generateDiagrammerCmd + \"-docs\", \"The path or file:// URI of the XML file containing the target assembly's documentation comments.\" +\n\t\t\t\" You only need to set this if a) you want your diagrams annotated with them and b) the file name differs from that of the assmbly.\" +\n\t\t\t\" To enable XML documentation output for your assmbly, see https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/xmldoc/#create-xml-documentation-output\",\n\t\t\tCommandOptionType.SingleValue)]\n\t\tpublic string XmlDocs { get; set; }\n\n\t\t/// <inheritdoc cref=\"ILSpyX.MermaidDiagrammer.GenerateHtmlDiagrammer.StrippedNamespaces\" />\n\t\t[Option(generateDiagrammerCmd + \"-strip-namespaces\", \"Optional space-separated namespace names that are removed for brevity from XML documentation comments.\" +\n\t\t\t\" Note that the order matters: e.g. replace 'System.Collections' before 'System' to remove both of them completely.\", CommandOptionType.MultipleValue)]\n\t\tpublic string[] StrippedNamespaces { get; set; }\n\n\t\t[Option(generateDiagrammerCmd + \"-json-only\",\n\t\t\t\"Whether to generate a model.json file instead of baking it into the HTML template.\" +\n\t\t\t\" This is useful for the HTML/JS/CSS development loop.\", CommandOptionType.NoValue,\n\t\t\tShowInHelpText = false)] // developer option, output is really only useful in combination with the corresponding task in html/gulpfile.js\n\t\tpublic bool JsonOnly { get; set; }\n\t\t#endregion\n\n\t\tprivate readonly IHostEnvironment _env;\n\t\tpublic ILSpyCmdProgram(IHostEnvironment env)\n\t\t{\n\t\t\t_env = env;\n\t\t}\n\n\t\tprivate async Task<int> OnExecuteAsync(CommandLineApplication app)\n\t\t{\n\t\t\tTask<PackageCheckResult> updateCheckTask = null;\n\t\t\tif (!DisableUpdateCheck)\n\t\t\t{\n\t\t\t\tupdateCheckTask = DotNetToolUpdateChecker.CheckForPackageUpdateAsync(\"ilspycmd\");\n\t\t\t}\n\n\t\t\tTextWriter output = System.Console.Out;\n\t\t\tstring outputDirectory = ResolveOutputDirectory(OutputDirectory);\n\n\t\t\tif (outputDirectory != null)\n\t\t\t{\n\t\t\t\tDirectory.CreateDirectory(outputDirectory);\n\t\t\t}\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (CreateCompilableProjectFlag)\n\t\t\t\t{\n\t\t\t\t\tif (InputAssemblyNames.Length == 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tstring projectFileName = Path.Combine(outputDirectory, Path.GetFileNameWithoutExtension(InputAssemblyNames[0]) + \".csproj\");\n\t\t\t\t\t\tDecompileAsProject(InputAssemblyNames[0], projectFileName);\n\t\t\t\t\t\treturn 0;\n\t\t\t\t\t}\n\t\t\t\t\tvar projects = new List<ProjectItem>();\n\t\t\t\t\tforeach (var file in InputAssemblyNames)\n\t\t\t\t\t{\n\t\t\t\t\t\tstring projectFileName = Path.Combine(outputDirectory, Path.GetFileNameWithoutExtension(file), Path.GetFileNameWithoutExtension(file) + \".csproj\");\n\t\t\t\t\t\tDirectory.CreateDirectory(Path.GetDirectoryName(projectFileName));\n\t\t\t\t\t\tProjectId projectId = DecompileAsProject(file, projectFileName);\n\t\t\t\t\t\tprojects.Add(new ProjectItem(projectFileName, projectId.PlatformName, projectId.Guid, projectId.TypeGuid));\n\t\t\t\t\t}\n\t\t\t\t\tSolutionCreator.WriteSolutionFile(Path.Combine(outputDirectory, Path.GetFileNameWithoutExtension(outputDirectory) + \".sln\"), projects);\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t\telse if (GenerateDiagrammer)\n\t\t\t\t{\n\t\t\t\t\tforeach (var file in InputAssemblyNames)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar command = new GenerateHtmlDiagrammer {\n\t\t\t\t\t\t\tAssembly = file,\n\t\t\t\t\t\t\tOutputFolder = OutputDirectory,\n\t\t\t\t\t\t\tInclude = Include,\n\t\t\t\t\t\t\tExclude = Exclude,\n\t\t\t\t\t\t\tReportExcludedTypes = ReportExcludedTypes,\n\t\t\t\t\t\t\tJsonOnly = JsonOnly,\n\t\t\t\t\t\t\tXmlDocs = XmlDocs,\n\t\t\t\t\t\t\tStrippedNamespaces = StrippedNamespaces\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tcommand.Run();\n\t\t\t\t\t}\n\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tforeach (var file in InputAssemblyNames)\n\t\t\t\t\t{\n\t\t\t\t\t\tint result = PerformPerFileAction(file);\n\t\t\t\t\t\tif (result != 0)\n\t\t\t\t\t\t\treturn result;\n\t\t\t\t\t}\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tapp.Error.WriteLine(ex.ToString());\n\t\t\t\treturn ProgramExitCodes.EX_SOFTWARE;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\toutput.Close();\n\n\t\t\t\tif (null != updateCheckTask)\n\t\t\t\t{\n\t\t\t\t\tvar checkResult = await updateCheckTask;\n\t\t\t\t\tif (null != checkResult && checkResult.UpdateRecommendation)\n\t\t\t\t\t{\n\t\t\t\t\t\tConsole.WriteLine(\"You are not using the latest version of the tool, please update.\");\n\t\t\t\t\t\tConsole.WriteLine($\"Latest version is '{checkResult.LatestVersion}' (yours is '{checkResult.RunningVersion}')\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tint PerformPerFileAction(string fileName)\n\t\t\t{\n\t\t\t\tif (EntityTypes.Any())\n\t\t\t\t{\n\t\t\t\t\tvar values = EntityTypes.SelectMany(v => v.Split(',', ';')).ToArray();\n\t\t\t\t\tHashSet<TypeKind> kinds = TypesParser.ParseSelection(values);\n\t\t\t\t\tif (outputDirectory != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tstring outputName = Path.GetFileNameWithoutExtension(fileName);\n\t\t\t\t\t\toutput = File.CreateText(Path.Combine(outputDirectory, outputName) + \".list.txt\");\n\t\t\t\t\t}\n\n\t\t\t\t\treturn ListContent(fileName, output, kinds);\n\t\t\t\t}\n\t\t\t\telse if (ShowILCodeFlag || ShowILSequencePointsFlag)\n\t\t\t\t{\n\t\t\t\t\tif (outputDirectory != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tstring outputName = Path.GetFileNameWithoutExtension(fileName);\n\t\t\t\t\t\toutput = File.CreateText(Path.Combine(outputDirectory, outputName) + \".il\");\n\t\t\t\t\t}\n\n\t\t\t\t\treturn ShowIL(fileName, output);\n\t\t\t\t}\n\t\t\t\telse if (CreateDebugInfoFlag)\n\t\t\t\t{\n\t\t\t\t\tstring pdbFileName = null;\n\t\t\t\t\tif (outputDirectory != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tstring outputName = Path.GetFileNameWithoutExtension(fileName);\n\t\t\t\t\t\tpdbFileName = Path.Combine(outputDirectory, outputName) + \".pdb\";\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tpdbFileName = Path.ChangeExtension(fileName, \".pdb\");\n\t\t\t\t\t}\n\n\t\t\t\t\treturn GeneratePdbForAssembly(fileName, pdbFileName, app);\n\t\t\t\t}\n\t\t\t\telse if (DumpPackageFlag)\n\t\t\t\t{\n\t\t\t\t\treturn DumpPackageAssemblies(fileName, outputDirectory, app);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (outputDirectory != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tstring outputName = Path.GetFileNameWithoutExtension(fileName);\n\t\t\t\t\t\toutput = File.CreateText(Path.Combine(outputDirectory,\n\t\t\t\t\t\t\t(string.IsNullOrEmpty(TypeName) ? outputName : TypeName) + \".decompiled.cs\"));\n\t\t\t\t\t}\n\n\t\t\t\t\treturn Decompile(fileName, output, TypeName);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate static string ResolveOutputDirectory(string outputDirectory)\n\t\t{\n\t\t\t// path is not set\n\t\t\tif (string.IsNullOrWhiteSpace(outputDirectory))\n\t\t\t\treturn null;\n\t\t\t// resolve relative path, backreferences ('.' and '..') and other\n\t\t\t// platform-specific path elements, like '~'.\n\t\t\treturn Path.GetFullPath(outputDirectory);\n\t\t}\n\n\t\tDecompilerSettings GetSettings(PEFile module)\n\t\t{\n\t\t\tDecompilerSettings decompilerSettings = null;\n\n\t\t\tif (ILSpySettingsFile != null)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tILSpyX.Settings.ILSpySettings.SettingsFilePathProvider = new ILSpyX.Settings.DefaultSettingsFilePathProvider(ILSpySettingsFile);\n\t\t\t\t\tvar settingsService = new ILSpyX.Settings.SettingsServiceBase(ILSpyX.Settings.ILSpySettings.Load());\n\t\t\t\t\tdecompilerSettings = settingsService.GetSettings<ILSpyX.Settings.DecompilerSettings>();\n\t\t\t\t}\n\t\t\t\tcatch (Exception ex)\n\t\t\t\t{\n\t\t\t\t\tConsole.Error.WriteLine($\"Error loading ILSpy settings file '{ILSpySettingsFile}': {ex.Message}\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (decompilerSettings == null)\n\t\t\t{\n\t\t\t\tdecompilerSettings = new DecompilerSettings(LanguageVersion) {\n\t\t\t\t\tThrowOnAssemblyResolveErrors = false,\n\t\t\t\t\tRemoveDeadCode = RemoveDeadCode,\n\t\t\t\t\tRemoveDeadStores = RemoveDeadStores,\n\t\t\t\t\tUseSdkStyleProjectFormat = WholeProjectDecompiler.CanUseSdkStyleProjectFormat(module),\n\t\t\t\t\tUseNestedDirectoriesForNamespaces = NestedDirectories,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (DecompilerSettingOverrides is { Length: > 0 })\n\t\t\t{\n\t\t\t\tforeach (var entry in DecompilerSettingOverrides)\n\t\t\t\t{\n\t\t\t\t\tint equals = entry.IndexOf('=');\n\t\t\t\t\tif (equals <= 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tConsole.Error.WriteLine($\"Decompiler setting '{entry}' is invalid; use '<Name>=<Value>'\");\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tstring name = entry[..equals].Trim();\n\t\t\t\t\tstring value = entry[(equals + 1)..].Trim();\n\n\t\t\t\t\tif (!ILSpyX.Settings.DecompilerSettings.IsKnownOption(name, out var property))\n\t\t\t\t\t{\n\t\t\t\t\t\tConsole.Error.WriteLine($\"Decompiler setting '{name}' is unknown.\");\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tobject typedValue;\n\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\ttypedValue = Convert.ChangeType(value, property.PropertyType);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (Exception)\n\t\t\t\t\t{\n\t\t\t\t\t\tConsole.Error.WriteLine($\"Decompiler setting '{name}': Value '{value}' could not be converted to '{property.PropertyType.FullName}'.\");\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (typedValue == null && property.PropertyType.IsValueType)\n\t\t\t\t\t{\n\t\t\t\t\t\tConsole.Error.WriteLine($\"Decompiler setting '{name}': Value '{value}' could not be converted to '{property.PropertyType.FullName}'.\");\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tproperty.SetValue(decompilerSettings, typedValue);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn decompilerSettings;\n\t\t}\n\n\t\tCSharpDecompiler GetDecompiler(string assemblyFileName)\n\t\t{\n\t\t\tvar module = new PEFile(assemblyFileName);\n\t\t\tvar resolver = new UniversalAssemblyResolver(assemblyFileName, false, module.Metadata.DetectTargetFrameworkId());\n\t\t\tforeach (var path in (ReferencePaths ?? Array.Empty<string>()))\n\t\t\t{\n\t\t\t\tresolver.AddSearchDirectory(path);\n\t\t\t}\n\t\t\treturn new CSharpDecompiler(assemblyFileName, resolver, GetSettings(module)) {\n\t\t\t\tDebugInfoProvider = TryLoadPDB(module)\n\t\t\t};\n\t\t}\n\n\t\tint ListContent(string assemblyFileName, TextWriter output, ISet<TypeKind> kinds)\n\t\t{\n\t\t\tCSharpDecompiler decompiler = GetDecompiler(assemblyFileName);\n\n\t\t\tforeach (var type in decompiler.TypeSystem.MainModule.TypeDefinitions)\n\t\t\t{\n\t\t\t\tif (!kinds.Contains(type.Kind))\n\t\t\t\t\tcontinue;\n\t\t\t\toutput.WriteLine($\"{type.Kind} {type.FullName}\");\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\n\t\tint ShowIL(string assemblyFileName, TextWriter output)\n\t\t{\n\t\t\tvar module = new PEFile(assemblyFileName);\n\t\t\toutput.WriteLine($\"// IL code: {module.Name}\");\n\t\t\tvar disassembler = new ReflectionDisassembler(new PlainTextOutput(output), CancellationToken.None) {\n\t\t\t\tDebugInfo = TryLoadPDB(module),\n\t\t\t\tShowSequencePoints = ShowILSequencePointsFlag,\n\t\t\t};\n\t\t\tdisassembler.WriteModuleContents(module);\n\t\t\treturn 0;\n\t\t}\n\n\t\tProjectId DecompileAsProject(string assemblyFileName, string projectFileName)\n\t\t{\n\t\t\tvar module = new PEFile(assemblyFileName);\n\t\t\tvar resolver = new UniversalAssemblyResolver(assemblyFileName, false, module.Metadata.DetectTargetFrameworkId());\n\t\t\tforeach (var path in (ReferencePaths ?? Array.Empty<string>()))\n\t\t\t{\n\t\t\t\tresolver.AddSearchDirectory(path);\n\t\t\t}\n\t\t\tvar decompiler = new WholeProjectDecompiler(GetSettings(module), resolver, null, resolver, TryLoadPDB(module));\n\t\t\tusing (var projectFileWriter = new StreamWriter(File.OpenWrite(projectFileName)))\n\t\t\t\treturn decompiler.DecompileProject(module, Path.GetDirectoryName(projectFileName), projectFileWriter);\n\t\t}\n\n\t\tint Decompile(string assemblyFileName, TextWriter output, string typeName = null)\n\t\t{\n\t\t\tCSharpDecompiler decompiler = GetDecompiler(assemblyFileName);\n\n\t\t\tif (typeName == null)\n\t\t\t{\n\t\t\t\toutput.Write(decompiler.DecompileWholeModuleAsString());\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar name = new FullTypeName(typeName);\n\t\t\t\toutput.Write(decompiler.DecompileTypeAsString(name));\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\n\t\tint GeneratePdbForAssembly(string assemblyFileName, string pdbFileName, CommandLineApplication app)\n\t\t{\n\t\t\tvar module = new PEFile(assemblyFileName,\n\t\t\t\tnew FileStream(assemblyFileName, FileMode.Open, FileAccess.Read),\n\t\t\t\tPEStreamOptions.PrefetchEntireImage,\n\t\t\t\tmetadataOptions: MetadataReaderOptions.None);\n\n\t\t\tif (!PortablePdbWriter.HasCodeViewDebugDirectoryEntry(module))\n\t\t\t{\n\t\t\t\tapp.Error.WriteLine($\"Cannot create PDB file for {assemblyFileName}, because it does not contain a PE Debug Directory Entry of type 'CodeView'.\");\n\t\t\t\treturn ProgramExitCodes.EX_DATAERR;\n\t\t\t}\n\n\t\t\tusing (FileStream stream = new FileStream(pdbFileName, FileMode.Create, FileAccess.Write))\n\t\t\t{\n\t\t\t\tvar decompiler = GetDecompiler(assemblyFileName);\n\t\t\t\tPortablePdbWriter.WritePdb(module, decompiler, GetSettings(module), stream);\n\t\t\t}\n\n\t\t\treturn 0;\n\t\t}\n\n\t\tint DumpPackageAssemblies(string packageFileName, string outputDirectory, CommandLineApplication app)\n\t\t{\n\t\t\tusing (var memoryMappedPackage = MemoryMappedFile.CreateFromFile(packageFileName, FileMode.Open, null, 0, MemoryMappedFileAccess.Read))\n\t\t\t{\n\t\t\t\tusing (var packageView = memoryMappedPackage.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read))\n\t\t\t\t{\n\t\t\t\t\tif (!SingleFileBundle.IsBundle(packageView, out long bundleHeaderOffset))\n\t\t\t\t\t{\n\t\t\t\t\t\tapp.Error.WriteLine($\"Cannot dump assembiles for {packageFileName}, because it is not a single file bundle.\");\n\t\t\t\t\t\treturn ProgramExitCodes.EX_DATAERR;\n\t\t\t\t\t}\n\n\t\t\t\t\tvar manifest = SingleFileBundle.ReadManifest(packageView, bundleHeaderOffset);\n\t\t\t\t\tforeach (var entry in manifest.Entries)\n\t\t\t\t\t{\n\t\t\t\t\t\tStream contents;\n\n\t\t\t\t\t\tif (entry.RelativePath.Replace('\\\\', '/').Contains(\"../\", StringComparison.Ordinal) || Path.IsPathRooted(entry.RelativePath))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tapp.Error.WriteLine($\"Skipping single-file entry '{entry.RelativePath}' because it might refer to a location outside of the bundle output directory.\");\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (entry.CompressedSize == 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontents = new UnmanagedMemoryStream(packageView.SafeMemoryMappedViewHandle, entry.Offset, entry.Size);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tStream compressedStream = new UnmanagedMemoryStream(packageView.SafeMemoryMappedViewHandle, entry.Offset, entry.CompressedSize);\n\t\t\t\t\t\t\tStream decompressedStream = new MemoryStream((int)entry.Size);\n\t\t\t\t\t\t\tusing (var deflateStream = new DeflateStream(compressedStream, CompressionMode.Decompress))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdeflateStream.CopyTo(decompressedStream);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (decompressedStream.Length != entry.Size)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tapp.Error.WriteLine($\"Corrupted single-file entry '{entry.RelativePath}'. Declared decompressed size '{entry.Size}' is not the same as actual decompressed size '{decompressedStream.Length}'.\");\n\t\t\t\t\t\t\t\treturn ProgramExitCodes.EX_DATAERR;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tdecompressedStream.Seek(0, SeekOrigin.Begin);\n\t\t\t\t\t\t\tcontents = decompressedStream;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstring target = Path.Combine(outputDirectory, entry.RelativePath);\n\t\t\t\t\t\tDirectory.CreateDirectory(Path.GetDirectoryName(target));\n\t\t\t\t\t\tusing (var fileStream = File.Create(target))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontents.CopyTo(fileStream);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn 0;\n\t\t}\n\n\t\tIDebugInfoProvider TryLoadPDB(PEFile module)\n\t\t{\n\t\t\tif (InputPDBFile.IsSet)\n\t\t\t{\n\t\t\t\tif (InputPDBFile.Value == null)\n\t\t\t\t\treturn DebugInfoUtils.LoadSymbols(module);\n\t\t\t\treturn DebugInfoUtils.FromFile(module, InputPDBFile.Value);\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyCmd/ProgramExitCodes.cs",
    "content": "// ReSharper disable InconsistentNaming\n\nnamespace ICSharpCode.ILSpyCmd\n{\n\tpublic class ProgramExitCodes\n\t{\n\t\t// https://www.freebsd.org/cgi/man.cgi?query=sysexits\n\t\tpublic const int EX_USAGE = 64;\n\t\tpublic const int EX_DATAERR = 65;\n\t\tpublic const int EX_NOINPUT = 66;\n\t\tpublic const int EX_SOFTWARE = 70;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyCmd/Properties/AssemblyInfo.cs",
    "content": "#region Using directives\n\nusing System.Diagnostics.CodeAnalysis;\nusing System.Reflection;\nusing System.Runtime.InteropServices;\n\n#endregion\n\n// This sets the default COM visibility of types in the assembly to invisible.\n// If you need to expose a type to COM, use [ComVisible(true)] on that type.\n[assembly: ComVisible(false)]\n\n[assembly: AssemblyVersion(DecompilerVersionInfo.Major + \".\" + DecompilerVersionInfo.Minor + \".\" + DecompilerVersionInfo.Build + \".\" + DecompilerVersionInfo.Revision)]\n[assembly: AssemblyInformationalVersion(DecompilerVersionInfo.FullVersionWithCommitHash)]\n\n[assembly: SuppressMessage(\"Microsoft.Usage\", \"CA2243:AttributeStringLiteralsShouldParseCorrectly\",\n\tJustification = \"AssemblyInformationalVersion does not need to be a parsable version\")]\n\n"
  },
  {
    "path": "ICSharpCode.ILSpyCmd/Properties/launchSettings.json",
    "content": "{\n\t\"profiles\": {\n\t\t\"no args\": {\n\t\t\t\"commandName\": \"Project\",\n\t\t\t\"commandLineArgs\": \"\"\n\t\t},\n\t\t\"print help\": {\n\t\t\t\"commandName\": \"Project\",\n\t\t\t\"commandLineArgs\": \"--help\"\n\t\t},\n\t\t\"generate diagrammer\": {\n\t\t\t\"commandName\": \"Project\",\n\t\t\t// containing all types\n\n\t\t\t// full diagrammer (~6.3 Mb!)\n\t\t\t//\"commandLineArgs\": \"ICSharpCode.Decompiler.dll --generate-diagrammer\"\n\n\t\t\t// including types in LightJson namespace while excluding types in nested LightJson.Serialization namespace, matched by what returns System.Type.FullName\n\t\t\t//\"commandLineArgs\": \"ICSharpCode.Decompiler.dll --generate-diagrammer --generate-diagrammer-include LightJson\\\\..+ --generate-diagrammer-exclude LightJson\\\\.Serialization\\\\..+\"\n\n\t\t\t// including types in Decompiler.TypeSystem namespace while excluding types in nested Decompiler.TypeSystem.Implementation namespace\n\t\t\t\"commandLineArgs\": \"ICSharpCode.Decompiler.dll --generate-diagrammer --generate-diagrammer-include Decompiler\\\\.TypeSystem\\\\..+ --generate-diagrammer-exclude Decompiler\\\\.TypeSystem\\\\.Implementation\\\\..+\"\n\t\t},\n\t\t\"generate diagrammer model.json\": {\n\t\t\t\"commandName\": \"Project\",\n\t\t\t\"commandLineArgs\": \"ICSharpCode.Decompiler.dll --generate-diagrammer --generate-diagrammer-json-only\"\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.ILSpyCmd/README.md",
    "content": "# ilspycmd .NET Tool \n\nTo install:\n\n```\ndotnet tool install --global ilspycmd\n```\n\nHelp output (`ilspycmd --help`):\n\n```\nilspycmd: 9.0.0.7847\nICSharpCode.Decompiler: 9.0.0.7847\n\ndotnet tool for decompiling .NET assemblies and generating portable PDBs\n\nUsage: ilspycmd [options] <Assembly file name(s)>\n\nArguments:\n  Assembly file name(s)                   The list of assemblies that is being decompiled. This argument is mandatory.\n\nOptions:\n  -v|--version                            Show version of ICSharpCode.Decompiler used.\n  -h|--help                               Show help information.\n  -o|--outputdir <directory>              The output directory, if omitted decompiler output is written to standard out.\n  -p|--project                            Decompile assembly as compilable project. This requires the output directory\n                                          option.\n  -t|--type <type-name>                   The fully qualified name of the type to decompile.\n  -il|--ilcode                            Show IL code.\n  --il-sequence-points                    Show IL with sequence points. Implies -il.\n  -genpdb|--generate-pdb                  Generate PDB.\n  -usepdb|--use-varnames-from-pdb         Use variable names from PDB.\n  -l|--list <entity-type(s)>              Lists all entities of the specified type(s). Valid types: c(lass),\n                                          i(nterface), s(truct), d(elegate), e(num)\n  -lv|--languageversion <version>         C# Language version: CSharp1, CSharp2, CSharp3, CSharp4, CSharp5, CSharp6,\n                                          CSharp7, CSharp7_1, CSharp7_2, CSharp7_3, CSharp8_0, CSharp9_0, CSharp10_0,\n                                          Preview or Latest\n                                          Allowed values are: CSharp1, CSharp2, CSharp3, CSharp4, CSharp5, CSharp6,\n                                          CSharp7, CSharp7_1, CSharp7_2, CSharp7_3, CSharp8_0, CSharp9_0, CSharp10_0,\n                                          CSharp11_0, Preview, CSharp12_0, Latest.\n                                          Default value is: Latest.\n  -r|--referencepath <path>               Path to a directory containing dependencies of the assembly that is being\n                                          decompiled.\n  --no-dead-code                          Remove dead code.\n  --no-dead-stores                        Remove dead stores.\n  -d|--dump-package                       Dump package assemblies into a folder. This requires the output directory\n                                          option.\n  --nested-directories                    Use nested directories for namespaces.\n  --disable-updatecheck                   If using ilspycmd in a tight loop or fully automated scenario, you might want\n                                          to disable the automatic update check.\n  --generate-diagrammer                   Generates an interactive HTML diagrammer app from selected types in the target\n                                          assembly - to the --outputdir or in a 'diagrammer' folder next to to the\n                                          assembly by default.\n  --generate-diagrammer-include           An optional regular expression matching Type.FullName used to whitelist types\n                                          to include in the generated diagrammer.\n  --generate-diagrammer-exclude           An optional regular expression matching Type.FullName used to blacklist types\n                                          to exclude from the generated diagrammer.\n  --generate-diagrammer-report-excluded   Outputs a report of types excluded from the generated diagrammer - whether by\n                                          default because compiler-generated, explicitly by\n                                          '--generate-diagrammer-exclude' or implicitly by\n                                          '--generate-diagrammer-include'. You may find this useful to develop and debug\n                                          your regular expressions.\n  --generate-diagrammer-docs              The path or file:// URI of the XML file containing the target assembly's\n                                          documentation comments. You only need to set this if a) you want your diagrams\n                                          annotated with them and b) the file name differs from that of the assmbly. To\n                                          enable XML documentation output for your assmbly, see\n                                          https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/xmldoc/#create-xml-documentation-output\n  --generate-diagrammer-strip-namespaces  Optional space-separated namespace names that are removed for brevity from XML\n                                          documentation comments. Note that the order matters: e.g. replace\n                                          'System.Collections' before 'System' to remove both of them completely.\n\nRemarks:\n  -o is valid with every option and required when using -p.\n\nExamples:\n    Decompile assembly to console out.\n        ilspycmd sample.dll\n\n    Decompile assembly to destination directory (single C# file).\n        ilspycmd -o c:\\decompiled sample.dll\n\n    Decompile assembly to destination directory, create a project file, one source file per type.\n        ilspycmd -p -o c:\\decompiled sample.dll\n\n    Decompile assembly to destination directory, create a project file, one source file per type,\n    into nicely nested directories.\n        ilspycmd --nested-directories -p -o c:\\decompiled sample.dll\n\n    Generate a HTML diagrammer containing all type info into a folder next to the input assembly\n        ilspycmd sample.dll --generate-diagrammer\n\n    Generate a HTML diagrammer containing filtered type info into a custom output folder\n    (including types in the LightJson namespace while excluding types in nested LightJson.Serialization namespace)\n        ilspycmd sample.dll --generate-diagrammer -o c:\\diagrammer --generate-diagrammer-include LightJson\\\\..+ --generate-diagrammer-exclude LightJson\\\\.Serialization\\\\..+\n```\n\n## Generate HTML diagrammers\n\nOnce you have an output folder in mind, you can adopt either of the following strategies\nto generate a HTML diagrammer from a .Net assembly using the console app.\n\n### Manually before use\n\n**Create the output folder** in your location of choice and inside it **a new shell script**.\n\nUsing the CMD shell in a Windows environment for example, you'd create a `regenerate.cmd` looking somewhat like this:\n\n<pre>\n..\\..\\path\\to\\ilspycmd.exe ..\\path\\to\\your\\assembly.dll --generate-diagrammer --outputdir .\n</pre>\n\nWith this script in place, run it to (re-)generate the HTML diagrammer at your leisure. Note that `--outputdir .` directs the output to the current directory.\n\n### Automatically\n\nIf you want to deploy an up-to-date HTML diagrammer as part of your live documentation,\nyou'll want to automate its regeneration to keep it in sync with your code base.\n\nFor example, you might like to share the diagrammer on a web server or - in general - with users\nwho cannot or may not regenerate it; lacking either access to the ilspycmd console app or permission to use it.\n\nIn such cases, you can dangle the regeneration off the end of either your build or deployment pipeline.\nNote that the macros used here apply to [MSBuild](https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild) for [Visual Studio](https://learn.microsoft.com/en-us/visualstudio/ide/reference/pre-build-event-post-build-event-command-line-dialog-box) and your mileage may vary with VS for Mac or VS Code.\n\n#### After building\n\nTo regenerate the HTML diagrammer from your output assembly after building,\nadd something like the following to your project file.\nNote that the `Condition` here is optional and configures this step to only run after `Release` builds.\n\n```xml\n<Target Name=\"PostBuild\" AfterTargets=\"PostBuildEvent\" Condition=\"'$(Configuration)' == 'Release'\">\n  <Exec Command=\"$(SolutionDir)..\\path\\to\\ilspycmd.exe $(TargetPath) --generate-diagrammer --outputdir $(ProjectDir)diagrammer\" />\n</Target>\n```\n\n#### After publishing\n\nIf you'd rather regenerate the diagram after publishing instead of building, all you have to do is change the `AfterTargets` to `Publish`.\nNote that the `Target` `Name` doesn't matter here and that the diagrammer is generated into a folder in the `PublishDir` instead of the `ProjectDir`.\n\n```xml\n<Target Name=\"GenerateHtmlDiagrammer\" AfterTargets=\"Publish\">\n  <Exec Command=\"$(SolutionDir)..\\path\\to\\ilspycmd.exe $(TargetPath) --generate-diagrammer --outputdir $(PublishDir)diagrammer\" />\n</Target>\n```\n\n### Usage tips\n\n**Compiler-generated** types and their nested types are **excluded by default**.\n\nConsider sussing out **big source assemblies** using [ILSpy](https://github.com/icsharpcode/ILSpy) first to get an idea about which subdomains to include in your diagrammers. Otherwise you may experience long build times and large file sizes for the diagrammer as well as a looong type selection opening it. At some point, mermaid may refuse to render all types in your selection because their definitions exceed the maximum input size. If that's where you find yourself, you may want to consider\n- using `--generate-diagrammer-include` and `--generate-diagrammer-exclude` to **limit the scope of the individual diagrammer to a certain subdomain**\n- generating **multiple diagrammers for different subdomains**.\n\n### Advanced configuration examples\n\nAbove examples show how the most important options are used. Let's have a quick look at the remaining ones, which allow for customization in your project setup and diagrams.\n\n#### Filter extracted types\n\nSometimes the source assembly contains way more types than are sensible to diagram. Types with metadata for validation or mapping for example. Or auto-generated types.\nEspecially if you want to tailor a diagrammer for a certain target audience and hide away most of the supporting type system to avoid noise and unnecessary questions.\n\nIn these scenarios you can supply Regular Expressions for types to `--generate-diagrammer-include` (white-list) and `--generate-diagrammer-exclude` (black-list).\nA third option `--generate-diagrammer-report-excluded` will output a `.txt` containing the list of effectively excluded types next to the HTML diagrammer containing the effectively included types.\n\n<pre>\nilspycmd.exe <b>--generate-diagrammer-include Your\\.Models\\..+ --generate-diagrammer-exclude .+\\+Metadata|.+\\.Data\\..+Map --generate-diagrammer-report-excluded</b> ..\\path\\to\\your\\assembly.dll --generate-diagrammer --outputdir .\n</pre>\n\nThis example\n- includes all types in the top-level namespace `Your.Models`\n- while excluding\n  - nested types called `Metadata` and\n  - types ending in `Map` in descendant `.Data.` namespaces.\n\n#### Strip namespaces from XML comments\n\nYou can reduce the noise in the XML documentation comments on classes on your diagrams by supplying a space-separated list of namespaces to omit from the output like so:\n\n<pre>\nilspycmd.exe <b>--generate-diagrammer-strip-namespaces System.Collections.Generic System</b> ..\\path\\to\\your\\assembly.dll --generate-diagrammer --output-folder .\n</pre>\n\nNote how `System` is replaced **after** other namespaces starting with `System.` to achieve complete removal.\nOtherwise `System.Collections.Generic` wouldn't match the `Collections.Generic` left over after removing `System.`, resulting in partial removal only.\n\n#### Adjust for custom XML documentation file names\n\nIf - for whatever reason - you have customized your XML documentation file output name, you can specify a custom path to pick it up from.\n\n<pre>\nilspycmd.exe <b>--generate-diagrammer-docs ..\\path\\to\\your\\docs.xml</b> ..\\path\\to\\your\\assembly.dll --generate-diagrammer --output-folder .\n</pre>\n"
  },
  {
    "path": "ICSharpCode.ILSpyCmd/TypesParser.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyCmd\n{\n\tpublic static class TypesParser\n\t{\n\t\tpublic static HashSet<TypeKind> ParseSelection(string[] values)\n\t\t{\n\t\t\tvar possibleValues = new Dictionary<string, TypeKind>(StringComparer.OrdinalIgnoreCase) { [\"class\"] = TypeKind.Class, [\"struct\"] = TypeKind.Struct, [\"interface\"] = TypeKind.Interface, [\"enum\"] = TypeKind.Enum, [\"delegate\"] = TypeKind.Delegate };\n\t\t\tHashSet<TypeKind> kinds = new HashSet<TypeKind>();\n\t\t\tif (values.Length == 1 && !possibleValues.Keys.Any(v => values[0].StartsWith(v, StringComparison.OrdinalIgnoreCase)))\n\t\t\t{\n\t\t\t\tforeach (char ch in values[0])\n\t\t\t\t{\n\t\t\t\t\tswitch (ch)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase 'c':\n\t\t\t\t\t\t\tkinds.Add(TypeKind.Class);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'i':\n\t\t\t\t\t\t\tkinds.Add(TypeKind.Interface);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 's':\n\t\t\t\t\t\t\tkinds.Add(TypeKind.Struct);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'd':\n\t\t\t\t\t\t\tkinds.Add(TypeKind.Delegate);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'e':\n\t\t\t\t\t\t\tkinds.Add(TypeKind.Enum);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tforeach (var value in values)\n\t\t\t\t{\n\t\t\t\t\tstring v = value;\n\t\t\t\t\twhile (v.Length > 0 && !possibleValues.ContainsKey(v))\n\t\t\t\t\t\tv = v.Remove(v.Length - 1);\n\t\t\t\t\tif (possibleValues.TryGetValue(v, out var kind))\n\t\t\t\t\t\tkinds.Add(kind);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn kinds;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyCmd/ValidationAttributes.cs",
    "content": "using System;\nusing System.ComponentModel.DataAnnotations;\nusing System.IO;\n\nusing McMaster.Extensions.CommandLineUtils.Abstractions;\nusing McMaster.Extensions.CommandLineUtils.Validation;\n\nnamespace ICSharpCode.ILSpyCmd\n{\n\t[AttributeUsage(AttributeTargets.Class)]\n\tpublic sealed class ProjectOptionRequiresOutputDirectoryValidationAttribute : ValidationAttribute\n\t{\n\t\tpublic ProjectOptionRequiresOutputDirectoryValidationAttribute()\n\t\t{\n\t\t}\n\n\t\tprotected override ValidationResult IsValid(object value, ValidationContext context)\n\t\t{\n\t\t\tif (value is ILSpyCmdProgram obj)\n\t\t\t{\n\t\t\t\tif (obj.CreateCompilableProjectFlag && string.IsNullOrEmpty(obj.OutputDirectory))\n\t\t\t\t{\n\t\t\t\t\treturn new ValidationResult(\"--project cannot be used unless --outputdir is also specified\");\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ValidationResult.Success;\n\t\t}\n\t}\n\n\t[AttributeUsage(AttributeTargets.Property)]\n\tpublic sealed class FileExistsOrNullAttribute : ValidationAttribute\n\t{\n\t\tprotected override ValidationResult IsValid(object value, ValidationContext validationContext)\n\t\t{\n\t\t\tvar path = value as string;\n\t\t\tif (string.IsNullOrEmpty(path))\n\t\t\t{\n\t\t\t\treturn ValidationResult.Success;\n\t\t\t}\n\n\t\t\tif (!Path.IsPathRooted(path) && validationContext.GetService(typeof(CommandLineContext)) is CommandLineContext context)\n\t\t\t{\n\t\t\t\tpath = Path.Combine(context.WorkingDirectory, path);\n\t\t\t}\n\n\t\t\tif (File.Exists(path))\n\t\t\t{\n\t\t\t\treturn ValidationResult.Success;\n\t\t\t}\n\n\t\t\treturn new ValidationResult($\"File '{path}' does not exist!\");\n\t\t}\n\t}\n\n\t[AttributeUsage(AttributeTargets.Property)]\n\tpublic sealed class FilesExistAttribute : ValidationAttribute\n\t{\n\t\tprotected override ValidationResult IsValid(object value, ValidationContext validationContext)\n\t\t{\n\t\t\tswitch (value)\n\t\t\t{\n\t\t\t\tcase string path:\n\t\t\t\t\treturn ValidatePath(path);\n\t\t\t\tcase string[] paths:\n\t\t\t\t{\n\t\t\t\t\tforeach (string path in paths)\n\t\t\t\t\t{\n\t\t\t\t\t\tValidationResult result = ValidatePath(path);\n\t\t\t\t\t\tif (result != ValidationResult.Success)\n\t\t\t\t\t\t\treturn result;\n\t\t\t\t\t}\n\t\t\t\t\treturn ValidationResult.Success;\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\treturn new ValidationResult($\"File '{value}' does not exist!\");\n\t\t\t}\n\n\t\t\tValidationResult ValidatePath(string path)\n\t\t\t{\n\t\t\t\tif (!string.IsNullOrWhiteSpace(path))\n\t\t\t\t{\n\t\t\t\t\tif (!Path.IsPathRooted(path) && validationContext.GetService(typeof(CommandLineContext)) is CommandLineContext context)\n\t\t\t\t\t{\n\t\t\t\t\t\tpath = Path.Combine(context.WorkingDirectory, path);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (File.Exists(path))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn ValidationResult.Success;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn new ValidationResult($\"File '{path}' does not exist!\");\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyCmd/packages.lock.json",
    "content": "{\n  \"version\": 2,\n  \"dependencies\": {\n    \"net10.0\": {\n      \"McMaster.Extensions.Hosting.CommandLine\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[5.0.1, )\",\n        \"resolved\": \"5.0.1\",\n        \"contentHash\": \"5BwLoyjHJESg0Fns+4rokcPP+kBfeZ+1NrZ03MUJsv9kf26s1mOLNgc2M9ju8lMCmJty+pQ2qyFQypVA+kbYhA==\",\n        \"dependencies\": {\n          \"McMaster.Extensions.CommandLineUtils\": \"5.0.1\",\n          \"Microsoft.Extensions.Hosting.Abstractions\": \"10.0.1\",\n          \"Microsoft.Extensions.Logging.Abstractions\": \"10.0.1\"\n        }\n      },\n      \"Microsoft.Extensions.Hosting\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[10.0.5, )\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"8i7e5IBdiKLNqt/+ciWrS8U95Rv5DClaaj7ulkZbimnCi4uREWd+lXzkp3joofFuIPOlAzV4AckxLTIELv2jdg==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.Configuration\": \"10.0.5\",\n          \"Microsoft.Extensions.Configuration.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Configuration.Binder\": \"10.0.5\",\n          \"Microsoft.Extensions.Configuration.CommandLine\": \"10.0.5\",\n          \"Microsoft.Extensions.Configuration.EnvironmentVariables\": \"10.0.5\",\n          \"Microsoft.Extensions.Configuration.FileExtensions\": \"10.0.5\",\n          \"Microsoft.Extensions.Configuration.Json\": \"10.0.5\",\n          \"Microsoft.Extensions.Configuration.UserSecrets\": \"10.0.5\",\n          \"Microsoft.Extensions.DependencyInjection\": \"10.0.5\",\n          \"Microsoft.Extensions.DependencyInjection.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Diagnostics\": \"10.0.5\",\n          \"Microsoft.Extensions.FileProviders.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.FileProviders.Physical\": \"10.0.5\",\n          \"Microsoft.Extensions.Hosting.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging.Configuration\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging.Console\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging.Debug\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging.EventLog\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging.EventSource\": \"10.0.5\",\n          \"Microsoft.Extensions.Options\": \"10.0.5\"\n        }\n      },\n      \"NuGet.Protocol\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[7.3.0, )\",\n        \"resolved\": \"7.3.0\",\n        \"contentHash\": \"QWx4Fko06Act+gVhB9UUc8Hzt0fnA8qQhD5SFn/xEis2ZZVzmatHmMdsc0SV7tyvCUlfG8DzQzYLF7fF4LvTyA==\",\n        \"dependencies\": {\n          \"NuGet.Packaging\": \"7.3.0\"\n        }\n      },\n      \"System.Security.Cryptography.Pkcs\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[10.0.5, )\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"BJEYUZfXpkPIHo2+oFoUemD5CPMFHPJOkRzXrbj/iZrWsjga3ypj8Rqd9bFlSLupEH4IIdD/aBWm/V1gCiBL9w==\"\n      },\n      \"TomsToolbox.Composition.Analyzer\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[2.22.2, )\",\n        \"resolved\": \"2.22.2\",\n        \"contentHash\": \"7gYo8ZR2eq3XkrilvUpLbTypeZy6IlD5FB8jah0YPhMOmDGhya4jJ3kfDMTTRt5m258Ou78P69mHMkG6DKZXsg==\"\n      },\n      \"Microsoft.Extensions.Configuration.Abstractions\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"P09QpTHjqHmCLQOTC+WyLkoRNxek4NIvfWt+TnU0etoDUSRxcltyd6+j/ouRbMdLR0j44GqGO+lhI2M4fAHG4g==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.Primitives\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.Configuration.Binder\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"99Z4rjyXopb1MIazDSPcvwYCUdYNO01Cf1GUs2WUjIFAbkGmwzj2vPa2k+3pheJRV+YgNd2QqRKHAri0oBAU4Q==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.Configuration\": \"10.0.5\",\n          \"Microsoft.Extensions.Configuration.Abstractions\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.Configuration.CommandLine\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"or9fOLopMUTJOQVJ3bou4aD6PwvsiKf4kZC4EE5sRRKSkmh+wfk/LekJXRjAX88X+1JA9zHjDo+5fiQ7z3MY/A==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.Configuration\": \"10.0.5\",\n          \"Microsoft.Extensions.Configuration.Abstractions\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.Configuration.EnvironmentVariables\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"tchMGQ+zVTO40np/Zzg2Li/TIR8bksQgg4UVXZa0OzeFCKWnIYtxE2FVs+eSmjPGCjMS2voZbwN/mUcYfpSTuA==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.Configuration\": \"10.0.5\",\n          \"Microsoft.Extensions.Configuration.Abstractions\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.Configuration.FileExtensions\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"OhTr0O79dP49734lLTqVveivVX9sDXxbI/8vjELAZTHXqoN90mdpgTAgwicJED42iaHMCcZcK6Bj+8wNyBikaw==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.Configuration\": \"10.0.5\",\n          \"Microsoft.Extensions.Configuration.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.FileProviders.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.FileProviders.Physical\": \"10.0.5\",\n          \"Microsoft.Extensions.Primitives\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.Configuration.UserSecrets\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"fhdG6UV9lIp70QhNkVyaHciUVq25IPFkczheVJL9bIFvmnJ+Zghaie6dWkDbbVmxZlHl9gj3zTDxMxJs5zNhIA==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.Configuration.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Configuration.Json\": \"10.0.5\",\n          \"Microsoft.Extensions.FileProviders.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.FileProviders.Physical\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.DependencyInjection\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"v1SVsowG6YE1YnHVGmLWz57YTRCQRx9pH5ebIESXfm5isI9gA3QaMyg/oMTzPpXYZwSAVDzYItGJKfmV+pqXkQ==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.DependencyInjection.Abstractions\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.Diagnostics\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"vAJHd4yOpmKoK+jBuYV7a3y+Ab9U4ARCc29b6qvMy276RgJFw9LFs0DdsPqOL3ahwzyrX7tM+i4cCxU/RX0qAg==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.Configuration\": \"10.0.5\",\n          \"Microsoft.Extensions.Diagnostics.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Options.ConfigurationExtensions\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.Diagnostics.Abstractions\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"/nYGrpa9/0BZofrVpBbbj+Ns8ZesiPE0V/KxsuHgDgHQopIzN54nRaQGSuvPw16/kI9sW1Zox5yyAPqvf0Jz6A==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.DependencyInjection.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Options\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.FileProviders.Abstractions\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"nCBmCx0Xemlu65ZiWMcXbvfvtznKxf4/YYKF9R28QkqdI9lTikedGqzJ28/xmdGGsxUnsP5/3TQGpiPwVjK0dA==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.Primitives\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.FileProviders.Physical\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"dMu5kUPSfol1Rqhmr6nWPSmbFjDe9w6bkoKithG17bWTZA0UyKirTatM5mqYUN3mGpNA0MorlusIoVTh6J7o5g==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.FileProviders.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.FileSystemGlobbing\": \"10.0.5\",\n          \"Microsoft.Extensions.Primitives\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.FileSystemGlobbing\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"mOE3ARusNQR0a5x8YOcnUbfyyXGqoAWQtEc7qFOfNJgruDWQLo39Re+3/Lzj5pLPFuFYj8hN4dgKzaSQDKiOCw==\"\n      },\n      \"Microsoft.Extensions.Hosting.Abstractions\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"+Wb7KAMVZTomwJkQrjuPTe5KBzGod7N8XeG+ScxRlkPOB4sZLG4ccVwjV4Phk5BCJt7uIMnGHVoN6ZMVploX+g==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.Configuration.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.DependencyInjection.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Diagnostics.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.FileProviders.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging.Abstractions\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.Logging\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"+XTMKQyDWg4ODoNHU/BN3BaI1jhGO7VCS+BnzT/4IauiG6y2iPAte7MyD7rHKS+hNP0TkFkjrae8DFjDUxtcxg==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.DependencyInjection\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Options\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.Logging.Abstractions\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"9HOdqlDtPptVcmKAjsQ/Nr5Rxfq6FMYLdhvZh1lVmeKR738qeYecQD7+ldooXf+u2KzzR1kafSphWngIM3C6ug==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.DependencyInjection.Abstractions\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.Logging.Configuration\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"cSgxsDgfP0+gmVRPVoNHI/KIDavIZxh+CxE6tSLPlYTogqccDnjBFI9CgEsiNuMP6+fiuXUwhhlTz36uUEpwbQ==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.Configuration\": \"10.0.5\",\n          \"Microsoft.Extensions.Configuration.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Configuration.Binder\": \"10.0.5\",\n          \"Microsoft.Extensions.DependencyInjection.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Options\": \"10.0.5\",\n          \"Microsoft.Extensions.Options.ConfigurationExtensions\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.Logging.Console\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"PMs2gha2v24hvH5o5KQem5aNK4mN0BhhCWlMqsg9tzifWKzjeQi2tyPOP/RaWMVvalOhVLcrmoMYPqbnia/epg==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.DependencyInjection.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging.Configuration\": \"10.0.5\",\n          \"Microsoft.Extensions.Options\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.Logging.Debug\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"/VacEkBQ02A8PBXSa6YpbIXCuisYy6JJr62/+ANJDZE+RMBfZMcXJXLfr/LpyLE6pgdp17Wxlt7e7R9zvkwZ3Q==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.DependencyInjection.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging.Abstractions\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.Logging.EventLog\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"0ezhWYJS4/6KrqQel9JL+Tr4n+4EX2TF5EYiaysBWNNEM2c3Gtj1moD39esfgk8OHblSX+UFjtZ3z0c4i9tRvw==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.DependencyInjection.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Options\": \"10.0.5\",\n          \"System.Diagnostics.EventLog\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.Logging.EventSource\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"vN+aq1hBFXyYvY5Ow9WyeR66drKQxRZmas4lAjh6QWfryPkjTn1uLtX5AFIxyDaZj78v5TG2sELUyvrXpAPQQw==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.DependencyInjection.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging\": \"10.0.5\",\n          \"Microsoft.Extensions.Logging.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Options\": \"10.0.5\",\n          \"Microsoft.Extensions.Primitives\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.Options\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"MDaQMdUplw0AIRhWWmbLA7yQEXaLIHb+9CTroTiNS8OlI0LMXS4LCxtopqauiqGCWlRgJ+xyraVD8t6veRAFbw==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.DependencyInjection.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Primitives\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.Options.ConfigurationExtensions\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"BB9uUW3+6Rxu1R97OB1H/13lUF8P2+H1+eDhpZlK30kDh/6E4EKHBUqTp+ilXQmZLzsRErxON8aBSR6WpUKJdg==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.Configuration.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Configuration.Binder\": \"10.0.5\",\n          \"Microsoft.Extensions.DependencyInjection.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Options\": \"10.0.5\",\n          \"Microsoft.Extensions.Primitives\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.Primitives\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"/HUHJ0tw/LQvD0DZrz50eQy/3z7PfX7WWEaXnjKTV9/TNdcgFlNTZGo49QhS7PTmhDqMyHRMqAXSBxLh0vso4g==\"\n      },\n      \"Newtonsoft.Json\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"13.0.3\",\n        \"contentHash\": \"HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==\"\n      },\n      \"NuGet.Common\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"7.3.0\",\n        \"contentHash\": \"y+7cQuzc6zePfo3GdueKgFAfE06pyNv1EGeordAMXotm6WEJw/m7UHv7GSLnib2HEPpzUk4Wvxgn9VgWkIe6Yw==\",\n        \"dependencies\": {\n          \"NuGet.Frameworks\": \"7.3.0\"\n        }\n      },\n      \"NuGet.Configuration\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"7.3.0\",\n        \"contentHash\": \"9qNpnZP73pfGm1MYET78OCW/HNnKNZpTfWPB2z/EyxQnfWtJBANeFyogX8s7S+oWMbR+EG2w6jbDVKdvVJfCXA==\",\n        \"dependencies\": {\n          \"NuGet.Common\": \"7.3.0\",\n          \"System.Security.Cryptography.ProtectedData\": \"8.0.0\"\n        }\n      },\n      \"NuGet.Frameworks\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"7.3.0\",\n        \"contentHash\": \"AnhSFUOrCrWp7pGtqhfOxa5HKm4rfpQxuatGDKzpGtTczasj6OcGVtB74PyqW7osdu9/BtkjnkAYvNk5iT82Gg==\"\n      },\n      \"NuGet.Packaging\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"7.3.0\",\n        \"contentHash\": \"yvmJ8LUPUVMm2DAKSK3+QfJKoCxQR1NuyPYLHqFHb1zmUcGwq+IvSl/4JjUivJDztXnI9GSVlE/SjQLsRJPoYw==\",\n        \"dependencies\": {\n          \"Newtonsoft.Json\": \"13.0.3\",\n          \"NuGet.Configuration\": \"7.3.0\",\n          \"NuGet.Versioning\": \"7.3.0\",\n          \"System.Security.Cryptography.Pkcs\": \"8.0.1\"\n        }\n      },\n      \"NuGet.Versioning\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"7.3.0\",\n        \"contentHash\": \"iOQPAdnVgj2U+K3AcdGGGcdS1tWyh3nvr64eqTDFCsDuHySBXSHRhl7eR8hdc0BZHxDjacRstbuaJKCurt2oPw==\"\n      },\n      \"System.Diagnostics.EventLog\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"wugvy+pBVzjQEnRs9wMTWwoaeNFX3hsaHeVHFDIvJSWXp7wfmNWu3mxAwBIE6pyW+g6+rHa1Of5fTzb0QVqUTA==\"\n      },\n      \"System.Security.Cryptography.ProtectedData\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"8.0.0\",\n        \"contentHash\": \"+TUFINV2q2ifyXauQXRwy4CiBhqvDEDZeVJU7qfxya4aRYOKzVBpN+4acx25VcPB9ywUN6C0n8drWl110PhZEg==\"\n      },\n      \"icsharpcode.decompiler\": {\n        \"type\": \"Project\",\n        \"dependencies\": {\n          \"System.Collections.Immutable\": \"[9.0.0, )\",\n          \"System.Reflection.Metadata\": \"[9.0.0, )\"\n        }\n      },\n      \"icsharpcode.ilspyx\": {\n        \"type\": \"Project\",\n        \"dependencies\": {\n          \"ICSharpCode.Decompiler\": \"[8.0.0-noversion, )\",\n          \"K4os.Compression.LZ4\": \"[1.3.8, )\",\n          \"Mono.Cecil\": \"[0.11.6, )\",\n          \"System.Composition.AttributedModel\": \"[10.0.5, )\",\n          \"System.Reflection.Metadata\": \"[10.0.5, )\",\n          \"System.Runtime.CompilerServices.Unsafe\": \"[6.1.2, )\"\n        }\n      },\n      \"K4os.Compression.LZ4\": {\n        \"type\": \"CentralTransitive\",\n        \"requested\": \"[1.3.8, )\",\n        \"resolved\": \"1.3.8\",\n        \"contentHash\": \"LhwlPa7c1zs1OV2XadMtAWdImjLIsqFJPoRcIWAadSRn0Ri1DepK65UbWLPmt4riLqx2d40xjXRk0ogpqNtK7g==\"\n      },\n      \"McMaster.Extensions.CommandLineUtils\": {\n        \"type\": \"CentralTransitive\",\n        \"requested\": \"[5.0.1, )\",\n        \"resolved\": \"5.0.1\",\n        \"contentHash\": \"dXerCHdnTrlpoQjdpxBISv9OIqqziJph1bKOTK95nPG0m7yDyMyVmQDcE1Z10ZZlQeaod1C8zewOW+MQOgPWhw==\"\n      },\n      \"Microsoft.Extensions.Configuration\": {\n        \"type\": \"CentralTransitive\",\n        \"requested\": \"[10.0.5, )\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"8Rx5sqg04FttxrumyG6bmoRuFRgYzK6IVwF1i0/o0cXfKBdDeVpJejKHtJCMjyg9E/DNMVqpqOGe/tCT5gYvVA==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.Configuration.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Primitives\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.Configuration.Json\": {\n        \"type\": \"CentralTransitive\",\n        \"requested\": \"[10.0.5, )\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"brBM/WP0YAUYh2+QqSYVdK8eQHYQTtTEUJXJ+84Zkdo2buGLja9VSrMIhgoeBUU7JBmcskAib8Lb/N83bvxgYQ==\",\n        \"dependencies\": {\n          \"Microsoft.Extensions.Configuration\": \"10.0.5\",\n          \"Microsoft.Extensions.Configuration.Abstractions\": \"10.0.5\",\n          \"Microsoft.Extensions.Configuration.FileExtensions\": \"10.0.5\",\n          \"Microsoft.Extensions.FileProviders.Abstractions\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.Extensions.DependencyInjection.Abstractions\": {\n        \"type\": \"CentralTransitive\",\n        \"requested\": \"[10.0.5, )\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"iVMtq9eRvzyhx8949EGT0OCYJfXi737SbRVzWXE5GrOgGj5AaZ9eUuxA/BSUfmOMALKn/g8KfFaNQw0eiB3lyA==\"\n      },\n      \"Mono.Cecil\": {\n        \"type\": \"CentralTransitive\",\n        \"requested\": \"[0.11.6, )\",\n        \"resolved\": \"0.11.6\",\n        \"contentHash\": \"f33RkDtZO8VlGXCtmQIviOtxgnUdym9xx/b1p9h91CRGOsJFxCFOFK1FDbVt1OCf1aWwYejUFa2MOQyFWTFjbA==\"\n      },\n      \"System.Collections.Immutable\": {\n        \"type\": \"CentralTransitive\",\n        \"requested\": \"[10.0.5, )\",\n        \"resolved\": \"9.0.0\",\n        \"contentHash\": \"QhkXUl2gNrQtvPmtBTQHb0YsUrDiDQ2QS09YbtTTiSjGcf7NBqtYbrG/BE06zcBPCKEwQGzIv13IVdXNOSub2w==\"\n      },\n      \"System.Composition.AttributedModel\": {\n        \"type\": \"CentralTransitive\",\n        \"requested\": \"[10.0.5, )\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"Vgb7wwB7ya+lbcwccXHZPSJxeKR7tCkWLgFXO9Wcgbu/NgO5DvNAIHtEkXaEESkcvXdD1iqp2JBcLWGT/xDxEw==\"\n      },\n      \"System.Reflection.Metadata\": {\n        \"type\": \"CentralTransitive\",\n        \"requested\": \"[10.0.5, )\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"fEAXJCtauNLYr5ESg3t6HE2Av6urWdJdymxZbuSt/DDqhtNtLtUtXTEpKbp0vkTdyBJwmaha8d2454vSzS/lcQ==\"\n      },\n      \"System.Runtime.CompilerServices.Unsafe\": {\n        \"type\": \"CentralTransitive\",\n        \"requested\": \"[6.1.2, )\",\n        \"resolved\": \"6.1.2\",\n        \"contentHash\": \"2hBr6zdbIBTDE3EhK7NSVNdX58uTK6iHW/P/Axmm9sl1xoGSLqDvMtpecn226TNwHByFokYwJmt/aQQNlO5CRw==\"\n      }\n    }\n  }\n}"
  },
  {
    "path": "ICSharpCode.ILSpyX/Abstractions/ILanguage.cs",
    "content": "// Copyright (c) 2022 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Output;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.Abstractions\n{\n\tpublic interface ILanguage\n\t{\n\t\tbool ShowMember(IEntity member);\n\t\tCodeMappingInfo GetCodeMappingInfo(MetadataFile module, EntityHandle member);\n\t\tstring GetEntityName(MetadataFile module, System.Reflection.Metadata.EntityHandle handle, bool fullName, bool omitGenerics);\n\t\tstring GetTooltip(IEntity entity);\n\n\t\tstring TypeToString(IType type, ConversionFlags conversionFlags = ConversionFlags.UseFullyQualifiedEntityNames | ConversionFlags.UseFullyQualifiedTypeNames);\n\t\tstring EntityToString(IEntity entity, ConversionFlags conversionFlags);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Abstractions/ITreeNode.cs",
    "content": "// Copyright (c) 2022 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpyX.Abstractions\n{\n\tpublic interface ITreeNode\n\t{\n\t\tobject Text { get; }\n\t\tobject Icon { get; }\n\t\tIEnumerable<ITreeNode> Children { get; }\n\n\t\tvoid EnsureLazyChildren();\n\t}\n\n\tpublic interface IResourcesFileTreeNode : ITreeNode\n\t{\n\t\tResource Resource { get; }\n\t}\n\n\tpublic interface ITreeNodeFactory\n\t{\n\t\tITreeNode CreateResourcesList(MetadataFile module);\n\t\tITreeNode Create(Resource resource);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/AnalyzerContext.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Concurrent;\nusing System.Reflection.Metadata;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX.Abstractions;\n\nnamespace ICSharpCode.ILSpyX.Analyzers\n{\n\t/// <summary>\n\t/// Provides additional context for analyzers.\n\t/// </summary>\n\tpublic class AnalyzerContext\n\t{\n\t\tpublic required AssemblyList AssemblyList { get; init; }\n\n\t\t/// <summary>\n\t\t/// CancellationToken. Currently Analyzers do not support cancellation from the UI, but it should be checked nonetheless.\n\t\t/// </summary>\n\t\tpublic CancellationToken CancellationToken { get; init; }\n\n\t\t/// <summary>\n\t\t/// Currently used language.\n\t\t/// </summary>\n\t\tpublic required ILanguage Language { get; init; }\n\n\t\t/// <summary>\n\t\t/// Allows the analyzer to control whether the tree nodes will be sorted.\n\t\t/// Must be set within <see cref=\"IAnalyzer.Analyze(ISymbol, AnalyzerContext)\"/>\n\t\t/// before the results are enumerated.\n\t\t/// </summary>\n\t\tpublic bool SortResults { get; set; }\n\n\t\tpublic MethodBodyBlock? GetMethodBody(IMethod method)\n\t\t{\n\t\t\tif (!method.HasBody || method.MetadataToken.IsNil || method.ParentModule?.MetadataFile == null)\n\t\t\t\treturn null;\n\t\t\tvar module = method.ParentModule.MetadataFile;\n\t\t\tvar md = module.Metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken);\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn module.GetMethodBody(md.RelativeVirtualAddress);\n\t\t\t}\n\t\t\tcatch (BadImageFormatException)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tpublic AnalyzerScope GetScopeOf(IEntity entity)\n\t\t{\n\t\t\treturn new AnalyzerScope(AssemblyList, entity);\n\t\t}\n\n\t\treadonly ConcurrentDictionary<MetadataFile, DecompilerTypeSystem> typeSystemCache = new();\n\n\t\tpublic DecompilerTypeSystem GetOrCreateTypeSystem(MetadataFile module)\n\t\t{\n\t\t\treturn typeSystemCache.GetOrAdd(module, m => new DecompilerTypeSystem(m, m.GetAssemblyResolver()));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/AnalyzerHelpers.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.Analyzers\n{\n\tinternal static class AnalyzerHelpers\n\t{\n\t\tpublic static bool IsPossibleReferenceTo(EntityHandle member, MetadataFile module, IMethod analyzedMethod)\n\t\t{\n\t\t\tif (member.IsNil)\n\t\t\t\treturn false;\n\t\t\tMetadataReader metadata = module.Metadata;\n\t\t\tswitch (member.Kind)\n\t\t\t{\n\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\treturn member == analyzedMethod.MetadataToken\n\t\t\t\t\t\t&& module == analyzedMethod.ParentModule?.MetadataFile;\n\t\t\t\tcase HandleKind.MemberReference:\n\t\t\t\t\tvar mr = metadata.GetMemberReference((MemberReferenceHandle)member);\n\t\t\t\t\tif (mr.GetKind() != MemberReferenceKind.Method)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn metadata.StringComparer.Equals(mr.Name, analyzedMethod.Name);\n\t\t\t\tcase HandleKind.MethodSpecification:\n\t\t\t\t\tvar ms = metadata.GetMethodSpecification((MethodSpecificationHandle)member);\n\t\t\t\t\treturn IsPossibleReferenceTo(ms.Method, module, analyzedMethod);\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic static ISymbol? GetParentEntity(DecompilerTypeSystem ts, CustomAttribute customAttribute)\n\t\t{\n\t\t\tvar metadata = ts.MainModule.MetadataFile.Metadata;\n\t\t\tswitch (customAttribute.Parent.Kind)\n\t\t\t{\n\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\tIMethod parent = (IMethod)ts.MainModule.ResolveEntity(customAttribute.Parent);\n\t\t\t\t\treturn parent?.AccessorOwner ?? parent;\n\t\t\t\tcase HandleKind.FieldDefinition:\n\t\t\t\tcase HandleKind.PropertyDefinition:\n\t\t\t\tcase HandleKind.EventDefinition:\n\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\t\treturn ts.MainModule.ResolveEntity(customAttribute.Parent);\n\t\t\t\tcase HandleKind.AssemblyDefinition:\n\t\t\t\tcase HandleKind.ModuleDefinition:\n\t\t\t\t\treturn ts.MainModule;\n\t\t\t\tcase HandleKind.GenericParameterConstraint:\n\t\t\t\t\tvar gpc = metadata.GetGenericParameterConstraint((GenericParameterConstraintHandle)customAttribute.Parent);\n\t\t\t\t\tvar gp = metadata.GetGenericParameter(gpc.Parameter);\n\t\t\t\t\treturn ts.MainModule.ResolveEntity(gp.Parent);\n\t\t\t\tcase HandleKind.GenericParameter:\n\t\t\t\t\tgp = metadata.GetGenericParameter((GenericParameterHandle)customAttribute.Parent);\n\t\t\t\t\treturn ts.MainModule.ResolveEntity(gp.Parent);\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/AnalyzerScope.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.ILSpyX.Analyzers\n{\n\tusing ICSharpCode.Decompiler.TypeSystem;\n\n\tpublic class AnalyzerScope\n\t{\n\t\treadonly ITypeDefinition typeScope;\n\t\treadonly AssemblyListSnapshot assemblyListSnapshot;\n\n\t\t/// <summary>\n\t\t/// Returns whether this scope is local, i.e., AnalyzedSymbol is only reachable\n\t\t/// from the current module or containing type.\n\t\t/// </summary>\n\t\tpublic bool IsLocal { get; }\n\n\t\tpublic ISymbol AnalyzedSymbol { get; }\n\n\t\tpublic ITypeDefinition TypeScope => typeScope;\n\n\t\treadonly Accessibility effectiveAccessibility;\n\n\t\tpublic AnalyzerScope(AssemblyList assemblyList, IEntity entity)\n\t\t{\n\t\t\tassemblyListSnapshot = assemblyList.GetSnapshot();\n\t\t\tAnalyzedSymbol = entity;\n\t\t\tDetermineEffectiveAccessibility(entity, out typeScope, out effectiveAccessibility);\n\t\t\tIsLocal = effectiveAccessibility.LessThanOrEqual(Accessibility.Private);\n\t\t}\n\n\t\tpublic IEnumerable<MetadataFile> GetModulesInScope(CancellationToken ct)\n\t\t{\n\t\t\tif (IsLocal)\n\t\t\t\treturn new[] { TypeScope.ParentModule!.MetadataFile! };\n\n\t\t\tif (effectiveAccessibility.LessThanOrEqual(Accessibility.Internal))\n\t\t\t\treturn GetModuleAndAnyFriends(TypeScope, ct);\n\n\t\t\treturn GetReferencingModules(TypeScope.ParentModule!.MetadataFile!, ct);\n\t\t}\n\n\t\tpublic IEnumerable<MetadataFile> GetAllModules()\n\t\t{\n\t\t\treturn assemblyListSnapshot.GetAllAssembliesAsync().GetAwaiter().GetResult()\n\t\t\t\t.Select(asm => asm.GetMetadataFileOrNull())\n\t\t\t\t.Where(x => x != null && !x.IsMetadataOnly)!;\n\t\t}\n\n\t\tpublic DecompilerTypeSystem ConstructTypeSystem(MetadataFile module)\n\t\t{\n\t\t\treturn new DecompilerTypeSystem(module, module.GetAssemblyResolver(assemblyListSnapshot, loadOnDemand: false));\n\t\t}\n\n\t\tpublic IEnumerable<ITypeDefinition> GetTypesInScope(CancellationToken ct)\n\t\t{\n\t\t\tif (IsLocal)\n\t\t\t{\n\t\t\t\tforeach (var type in TreeTraversal.PreOrder(typeScope, t => t.NestedTypes))\n\t\t\t\t{\n\t\t\t\t\tyield return type;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tforeach (var module in GetModulesInScope(ct))\n\t\t\t\t{\n\t\t\t\t\tvar typeSystem = ConstructTypeSystem(module);\n\t\t\t\t\tforeach (var type in typeSystem.MainModule.TypeDefinitions)\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return type;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic void DetermineEffectiveAccessibility(IEntity input, out ITypeDefinition typeScope, out Accessibility accessibility)\n\t\t{\n\t\t\tif (input is ITypeDefinition td)\n\t\t\t{\n\t\t\t\taccessibility = Accessibility.Public;\n\t\t\t\ttypeScope = td;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\taccessibility = input.Accessibility;\n\t\t\t\ttypeScope = input.DeclaringTypeDefinition!;\n\t\t\t}\n\t\t\t// Once we reach a private entity, we leave the loop with typeScope set to the class that\n\t\t\t// contains the private entity = the scope that needs to be searched.\n\t\t\t// Otherwise (if we don't find a private entity) we return the top-level class.\n\t\t\tvar prevTypeScope = typeScope;\n\t\t\twhile (typeScope != null && !accessibility.LessThanOrEqual(Accessibility.Private))\n\t\t\t{\n\t\t\t\taccessibility = accessibility.Intersect(typeScope.Accessibility);\n\t\t\t\tprevTypeScope = typeScope;\n\t\t\t\ttypeScope = prevTypeScope.DeclaringTypeDefinition!;\n\t\t\t}\n\t\t\tif (typeScope == null)\n\t\t\t{\n\t\t\t\ttypeScope = prevTypeScope;\n\t\t\t}\n\t\t}\n\n\t\t#region Find modules\n\t\tIEnumerable<MetadataFile> GetReferencingModules(MetadataFile self, CancellationToken ct)\n\t\t{\n\t\t\tyield return self;\n\n\t\t\tstring reflectionTypeScopeName = typeScope.Name;\n\t\t\tif (typeScope.TypeParameterCount > 0)\n\t\t\t\treflectionTypeScopeName += \"`\" + typeScope.TypeParameterCount;\n\n\t\t\tvar toWalkFiles = new Stack<MetadataFile>();\n\t\t\tvar checkedFiles = new HashSet<MetadataFile>();\n\n\t\t\ttoWalkFiles.Push(self);\n\t\t\tcheckedFiles.Add(self);\n\t\t\tIList<LoadedAssembly> assemblies = assemblyListSnapshot.GetAllAssembliesAsync().GetAwaiter().GetResult();\n\n\t\t\tdo\n\t\t\t{\n\t\t\t\tMetadataFile curFile = toWalkFiles.Pop();\n\t\t\t\tforeach (var assembly in assemblies)\n\t\t\t\t{\n\t\t\t\t\tct.ThrowIfCancellationRequested();\n\t\t\t\t\tbool found = false;\n\t\t\t\t\tvar module = assembly.GetMetadataFileOrNull();\n\t\t\t\t\tif (module == null || !module.IsAssembly)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tif (checkedFiles.Contains(module))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tvar resolver = assembly.GetAssemblyResolver(assemblyListSnapshot, loadOnDemand: false);\n\t\t\t\t\tforeach (var reference in module.AssemblyReferences)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (resolver.Resolve(reference) == curFile)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (found && checkedFiles.Add(module))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (ModuleReferencesScopeType(module.Metadata, reflectionTypeScopeName, typeScope.Namespace))\n\t\t\t\t\t\t\tyield return module;\n\t\t\t\t\t\tif (ModuleForwardsScopeType(module.Metadata, reflectionTypeScopeName, typeScope.Namespace))\n\t\t\t\t\t\t\ttoWalkFiles.Push(module);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} while (toWalkFiles.Count > 0);\n\t\t}\n\n\t\tIEnumerable<MetadataFile> GetModuleAndAnyFriends(ITypeDefinition typeScope, CancellationToken ct)\n\t\t{\n\t\t\tvar self = typeScope.ParentModule!.MetadataFile!;\n\n\t\t\tyield return self;\n\n\t\t\tvar typeProvider = MetadataExtensions.MinimalAttributeTypeProvider;\n\t\t\tvar attributes = self.Metadata.CustomAttributes.Select(h => self.Metadata.GetCustomAttribute(h))\n\t\t\t\t.Where(ca => ca.GetAttributeType(self.Metadata).GetFullTypeName(self.Metadata).ToString() == \"System.Runtime.CompilerServices.InternalsVisibleToAttribute\");\n\t\t\tvar friendAssemblies = new HashSet<string>();\n\t\t\tforeach (var attribute in attributes)\n\t\t\t{\n\t\t\t\tstring? assemblyName = attribute.DecodeValue(typeProvider).FixedArguments[0].Value as string;\n\t\t\t\tassemblyName = assemblyName?.Split(',')[0]; // strip off any public key info\n\t\t\t\tif (assemblyName != null)\n\t\t\t\t\tfriendAssemblies.Add(assemblyName);\n\t\t\t}\n\n\t\t\tif (friendAssemblies.Count > 0)\n\t\t\t{\n\t\t\t\tIEnumerable<LoadedAssembly> assemblies = assemblyListSnapshot.GetAllAssembliesAsync()\n\t\t\t\t\t.GetAwaiter().GetResult();\n\n\t\t\t\tforeach (var assembly in assemblies)\n\t\t\t\t{\n\t\t\t\t\tct.ThrowIfCancellationRequested();\n\t\t\t\t\tif (friendAssemblies.Contains(assembly.ShortName))\n\t\t\t\t\t{\n\t\t\t\t\t\tvar module = assembly.GetMetadataFileOrNull();\n\t\t\t\t\t\tif (module == null || module.IsMetadataOnly)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tif (ModuleReferencesScopeType(module.Metadata, typeScope.Name, typeScope.Namespace))\n\t\t\t\t\t\t\tyield return module;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool ModuleReferencesScopeType(MetadataReader metadata, string typeScopeName, string typeScopeNamespace)\n\t\t{\n\t\t\tbool hasRef = false;\n\t\t\tforeach (var h in metadata.TypeReferences)\n\t\t\t{\n\t\t\t\tvar typeRef = metadata.GetTypeReference(h);\n\t\t\t\tif (metadata.StringComparer.Equals(typeRef.Name, typeScopeName)\n\t\t\t\t\t&& metadata.StringComparer.Equals(typeRef.Namespace, typeScopeNamespace))\n\t\t\t\t{\n\t\t\t\t\thasRef = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn hasRef;\n\t\t}\n\n\t\tbool ModuleForwardsScopeType(MetadataReader metadata, string typeScopeName, string typeScopeNamespace)\n\t\t{\n\t\t\tbool hasForward = false;\n\t\t\tforeach (var h in metadata.ExportedTypes)\n\t\t\t{\n\t\t\t\tvar exportedType = metadata.GetExportedType(h);\n\t\t\t\tif (exportedType.IsForwarder\n\t\t\t\t\t&& metadata.StringComparer.Equals(exportedType.Name, typeScopeName)\n\t\t\t\t\t&& metadata.StringComparer.Equals(exportedType.Namespace, typeScopeNamespace))\n\t\t\t\t{\n\t\t\t\t\thasForward = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn hasForward;\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/Builtin/AttributeAppliedToAnalyzer.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.ILSpyX.Analyzers.Builtin\n{\n\t[ExportAnalyzer(Header = \"Applied To\", Order = 10)]\n\t[Shared]\n\tclass AttributeAppliedToAnalyzer : IAnalyzer\n\t{\n\t\tpublic IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)\n\t\t{\n\t\t\tif (!(analyzedSymbol is ITypeDefinition attributeType))\n\t\t\t\treturn Empty<ISymbol>.Array;\n\n\t\t\tvar scope = context.GetScopeOf(attributeType);\n\t\t\t// TODO: DeclSecurity attributes are not supported.\n\t\t\tif (!IsBuiltinAttribute(attributeType, out var knownAttribute))\n\t\t\t{\n\t\t\t\treturn HandleCustomAttribute(attributeType, scope, context.CancellationToken).Distinct();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn HandleBuiltinAttribute(knownAttribute, scope, context.CancellationToken).SelectMany(s => s);\n\t\t\t}\n\t\t}\n\n\t\tbool IsBuiltinAttribute(ITypeDefinition attributeType, out KnownAttribute knownAttribute)\n\t\t{\n\t\t\tknownAttribute = attributeType.IsBuiltinAttribute();\n\t\t\treturn !knownAttribute.IsCustomAttribute();\n\t\t}\n\n\t\tIEnumerable<IEnumerable<ISymbol>> HandleBuiltinAttribute(KnownAttribute attribute, AnalyzerScope scope, CancellationToken ct)\n\t\t{\n\t\t\tIEnumerable<ISymbol> ScanTypes(DecompilerTypeSystem ts)\n\t\t\t{\n\t\t\t\treturn ts.MainModule.TypeDefinitions\n\t\t\t\t\t.Where(t => t.HasAttribute(attribute));\n\t\t\t}\n\n\t\t\tIEnumerable<ISymbol> ScanMethods(DecompilerTypeSystem ts)\n\t\t\t{\n\t\t\t\treturn ts.MainModule.TypeDefinitions\n\t\t\t\t\t.SelectMany(t => t.Members.OfType<IMethod>())\n\t\t\t\t\t.Where(m => m.HasAttribute(attribute))\n\t\t\t\t\t.Select(m => m.AccessorOwner ?? m);\n\t\t\t}\n\n\t\t\tIEnumerable<ISymbol> ScanFields(DecompilerTypeSystem ts)\n\t\t\t{\n\t\t\t\treturn ts.MainModule.TypeDefinitions\n\t\t\t\t\t.SelectMany(t => t.Fields)\n\t\t\t\t\t.Where(f => f.HasAttribute(attribute));\n\t\t\t}\n\n\t\t\tIEnumerable<ISymbol> ScanProperties(DecompilerTypeSystem ts)\n\t\t\t{\n\t\t\t\treturn ts.MainModule.TypeDefinitions\n\t\t\t\t\t.SelectMany(t => t.Properties)\n\t\t\t\t\t.Where(p => p.HasAttribute(attribute));\n\t\t\t}\n\n\t\t\tIEnumerable<ISymbol> ScanParameters(DecompilerTypeSystem ts)\n\t\t\t{\n\t\t\t\treturn ts.MainModule.TypeDefinitions\n\t\t\t\t\t.SelectMany(t => t.Members.OfType<IMethod>())\n\t\t\t\t\t.Where(m => m.Parameters.Any(p => p.HasAttribute(attribute)))\n\t\t\t\t\t.Select(m => m.AccessorOwner ?? m);\n\t\t\t}\n\n\t\t\tforeach (Decompiler.Metadata.PEFile module in scope.GetModulesInScope(ct))\n\t\t\t{\n\t\t\t\tvar ts = scope.ConstructTypeSystem(module);\n\t\t\t\tct.ThrowIfCancellationRequested();\n\n\t\t\t\tswitch (attribute)\n\t\t\t\t{\n\t\t\t\t\tcase KnownAttribute.Serializable:\n\t\t\t\t\tcase KnownAttribute.ComImport:\n\t\t\t\t\tcase KnownAttribute.StructLayout:\n\t\t\t\t\t\tyield return ScanTypes(ts);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownAttribute.DllImport:\n\t\t\t\t\tcase KnownAttribute.PreserveSig:\n\t\t\t\t\tcase KnownAttribute.MethodImpl:\n\t\t\t\t\t\tyield return ScanMethods(ts);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownAttribute.FieldOffset:\n\t\t\t\t\tcase KnownAttribute.NonSerialized:\n\t\t\t\t\t\tyield return ScanFields(ts);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownAttribute.MarshalAs:\n\t\t\t\t\t\tyield return ScanFields(ts);\n\t\t\t\t\t\tyield return ScanParameters(ts);\n\t\t\t\t\t\tgoto case KnownAttribute.Out;\n\t\t\t\t\tcase KnownAttribute.Optional:\n\t\t\t\t\tcase KnownAttribute.In:\n\t\t\t\t\tcase KnownAttribute.Out:\n\t\t\t\t\t\tyield return ScanParameters(ts);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase KnownAttribute.IndexerName:\n\t\t\t\t\t\tyield return ScanProperties(ts);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tIEnumerable<ISymbol> HandleCustomAttribute(ITypeDefinition attributeType, AnalyzerScope scope, CancellationToken ct)\n\t\t{\n\t\t\tvar genericContext = new Decompiler.TypeSystem.GenericContext(); // type arguments do not matter for this analyzer.\n\n\t\t\tforeach (var module in scope.GetModulesInScope(ct))\n\t\t\t{\n\t\t\t\tvar ts = scope.ConstructTypeSystem(module);\n\t\t\t\tct.ThrowIfCancellationRequested();\n\t\t\t\tvar decoder = new FindTypeDecoder(ts.MainModule, attributeType);\n\n\t\t\t\tvar referencedParameters = new HashSet<ParameterHandle>();\n\t\t\t\tforeach (var h in module.Metadata.CustomAttributes)\n\t\t\t\t{\n\t\t\t\t\tvar customAttribute = module.Metadata.GetCustomAttribute(h);\n\t\t\t\t\tif (IsCustomAttributeOfType(customAttribute.Constructor, module.Metadata, decoder))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (customAttribute.Parent.Kind == HandleKind.Parameter)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treferencedParameters.Add((ParameterHandle)customAttribute.Parent);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar parent = AnalyzerHelpers.GetParentEntity(ts, customAttribute);\n\t\t\t\t\t\t\tif (parent != null)\n\t\t\t\t\t\t\t\tyield return parent;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (referencedParameters.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tforeach (var h in module.Metadata.MethodDefinitions)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar md = module.Metadata.GetMethodDefinition(h);\n\t\t\t\t\t\tforeach (var p in md.GetParameters())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (referencedParameters.Contains(p))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvar method = ts.MainModule.ResolveMethod(h, genericContext);\n\t\t\t\t\t\t\t\tif (method != null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif (method.IsAccessor)\n\t\t\t\t\t\t\t\t\t\tyield return method.AccessorOwner;\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\tyield return method;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tinternal static bool IsCustomAttributeOfType(EntityHandle customAttributeCtor, MetadataReader metadata, FindTypeDecoder decoder)\n\t\t{\n\t\t\tvar declaringAttributeType = customAttributeCtor.GetDeclaringType(metadata);\n\t\t\treturn decoder.GetTypeFromEntity(metadata, declaringAttributeType);\n\t\t}\n\n\t\tpublic bool Show(ISymbol symbol)\n\t\t{\n\t\t\treturn symbol is ITypeDefinition type && type.GetNonInterfaceBaseTypes()\n\t\t\t\t.Any(t => t.IsKnownType(KnownTypeCode.Attribute));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/Builtin/EventImplementedByAnalyzer.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.Analyzers.Builtin\n{\n\t/// <summary>\n\t/// Shows events that implement an interface event.\n\t/// </summary>\n\t[ExportAnalyzer(Header = \"Implemented By\", Order = 10)]\n\t[Shared]\n\tclass EventImplementedByAnalyzer : IAnalyzer\n\t{\n\t\tpublic IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)\n\t\t{\n\t\t\tDebug.Assert(analyzedSymbol is IEvent);\n\t\t\tvar scope = context.GetScopeOf((IEvent)analyzedSymbol);\n\t\t\tforeach (var type in scope.GetTypesInScope(context.CancellationToken))\n\t\t\t{\n\t\t\t\tforeach (var result in AnalyzeType((IEvent)analyzedSymbol, type))\n\t\t\t\t\tyield return result;\n\t\t\t}\n\t\t}\n\n\t\tIEnumerable<IEntity> AnalyzeType(IEvent analyzedEntity, ITypeDefinition type)\n\t\t{\n\t\t\tif (analyzedEntity.DeclaringTypeDefinition?.ParentModule?.MetadataFile == null)\n\t\t\t\tyield break;\n\t\t\tvar token = analyzedEntity.MetadataToken;\n\t\t\tvar declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken;\n\t\t\tvar module = analyzedEntity.DeclaringTypeDefinition.ParentModule.MetadataFile;\n\t\t\tvar allTypes = type.GetAllBaseTypeDefinitions();\n\t\t\tif (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule?.MetadataFile == module))\n\t\t\t\tyield break;\n\n\t\t\tforeach (var @event in type.Events)\n\t\t\t{\n\t\t\t\tvar baseMembers = InheritanceHelper.GetBaseMembers(@event, true);\n\t\t\t\tif (baseMembers.Any(m => m.MetadataToken == token && m.ParentModule?.MetadataFile == module))\n\t\t\t\t\tyield return @event;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool Show(ISymbol symbol)\n\t\t{\n\t\t\treturn symbol is IEvent entity && entity.DeclaringType.Kind == TypeKind.Interface;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/Builtin/EventOverriddenByAnalyzer.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.Analyzers.Builtin\n{\n\t/// <summary>\n\t/// Shows events that override an event.\n\t/// </summary>\n\t[ExportAnalyzer(Header = \"Overridden By\", Order = 20)]\n\t[Shared]\n\tclass EventOverriddenByAnalyzer : IAnalyzer\n\t{\n\t\tpublic IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)\n\t\t{\n\t\t\tDebug.Assert(analyzedSymbol is IEvent);\n\t\t\tvar scope = context.GetScopeOf((IEvent)analyzedSymbol);\n\t\t\tforeach (var type in scope.GetTypesInScope(context.CancellationToken))\n\t\t\t{\n\t\t\t\tforeach (var result in AnalyzeType((IEvent)analyzedSymbol, type))\n\t\t\t\t\tyield return result;\n\t\t\t}\n\t\t}\n\n\t\tIEnumerable<IEntity> AnalyzeType(IEvent analyzedEntity, ITypeDefinition type)\n\t\t{\n\t\t\tif (analyzedEntity.DeclaringTypeDefinition?.ParentModule?.MetadataFile == null)\n\t\t\t\tyield break;\n\t\t\tvar token = analyzedEntity.MetadataToken;\n\t\t\tvar declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken;\n\t\t\tvar module = analyzedEntity.DeclaringTypeDefinition.ParentModule.MetadataFile;\n\t\t\tvar allTypes = type.GetAllBaseTypeDefinitions();\n\t\t\tif (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule?.MetadataFile == module))\n\t\t\t\tyield break;\n\n\t\t\tforeach (var @event in type.Events)\n\t\t\t{\n\t\t\t\tif (!@event.IsOverride)\n\t\t\t\t\tcontinue;\n\t\t\t\tvar baseMembers = InheritanceHelper.GetBaseMembers(@event, false);\n\t\t\t\tif (baseMembers.Any(p => p.MetadataToken == token && p.ParentModule?.MetadataFile == module))\n\t\t\t\t{\n\t\t\t\t\tyield return @event;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic bool Show(ISymbol symbol)\n\t\t{\n\t\t\treturn symbol is IEvent entity && entity.IsOverridable && entity.DeclaringType.Kind != TypeKind.Interface;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/Builtin/FieldAccessAnalyzer.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nusing ILOpCode = System.Reflection.Metadata.ILOpCode;\n\nnamespace ICSharpCode.ILSpyX.Analyzers.Builtin\n{\n\t/// <summary>\n\t/// Finds methods where this field is read.\n\t/// </summary>\n\t[ExportAnalyzer(Header = \"Assigned By\", Order = 20)]\n\t[Shared]\n\tclass AssignedByFieldAccessAnalyzer : FieldAccessAnalyzer\n\t{\n\t\tpublic AssignedByFieldAccessAnalyzer() : base(true) { }\n\t}\n\n\t/// <summary>\n\t/// Finds methods where this field is written.\n\t/// </summary>\n\t[ExportAnalyzer(Header = \"Read By\", Order = 10)]\n\t[Shared]\n\tclass ReadByFieldAccessAnalyzer : FieldAccessAnalyzer\n\t{\n\t\tpublic ReadByFieldAccessAnalyzer() : base(false) { }\n\t}\n\n\t/// <summary>\n\t/// Finds methods where this field is read or written.\n\t/// </summary>\n\tclass FieldAccessAnalyzer : IAnalyzer\n\t{\n\t\tconst GetMemberOptions Options = GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions;\n\n\t\treadonly bool showWrites; // true: show writes; false: show read access\n\n\t\tpublic FieldAccessAnalyzer(bool showWrites)\n\t\t{\n\t\t\tthis.showWrites = showWrites;\n\t\t}\n\n\t\tpublic bool Show(ISymbol symbol)\n\t\t{\n\t\t\treturn symbol is IField field && (!showWrites || !field.IsConst);\n\t\t}\n\n\t\tpublic IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)\n\t\t{\n\t\t\tDebug.Assert(analyzedSymbol is IField);\n\t\t\tvar scope = context.GetScopeOf((IEntity)analyzedSymbol);\n\t\t\tforeach (var type in scope.GetTypesInScope(context.CancellationToken))\n\t\t\t{\n\t\t\t\tif (type.ParentModule?.MetadataFile == null)\n\t\t\t\t\tcontinue;\n\t\t\t\tvar mappingInfo = context.Language.GetCodeMappingInfo(type.ParentModule.MetadataFile, type.MetadataToken);\n\t\t\t\tvar methods = type.GetMembers(m => m is IMethod, Options).OfType<IMethod>();\n\t\t\t\tforeach (var method in methods)\n\t\t\t\t{\n\t\t\t\t\tif (IsUsedInMethod((IField)analyzedSymbol, method, mappingInfo, context))\n\t\t\t\t\t\tyield return method;\n\t\t\t\t}\n\n\t\t\t\tforeach (var property in type.Properties)\n\t\t\t\t{\n\t\t\t\t\tif (property.CanGet && IsUsedInMethod((IField)analyzedSymbol, property.Getter, mappingInfo, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return property;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (property.CanSet && IsUsedInMethod((IField)analyzedSymbol, property.Setter, mappingInfo, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return property;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tforeach (var @event in type.Events)\n\t\t\t\t{\n\t\t\t\t\tif (@event.CanAdd && IsUsedInMethod((IField)analyzedSymbol, @event.AddAccessor, mappingInfo, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return @event;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (@event.CanRemove && IsUsedInMethod((IField)analyzedSymbol, @event.RemoveAccessor, mappingInfo, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return @event;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (@event.CanInvoke && IsUsedInMethod((IField)analyzedSymbol, @event.InvokeAccessor, mappingInfo, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return @event;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool IsUsedInMethod(IField analyzedField, IMethod method, CodeMappingInfo mappingInfo, AnalyzerContext context)\n\t\t{\n\t\t\tif (method.MetadataToken.IsNil || method.ParentModule?.MetadataFile == null)\n\t\t\t\treturn false;\n\t\t\tvar module = method.ParentModule.MetadataFile;\n\t\t\tforeach (var part in mappingInfo.GetMethodParts((MethodDefinitionHandle)method.MetadataToken))\n\t\t\t{\n\t\t\t\tvar md = module.Metadata.GetMethodDefinition(part);\n\t\t\t\tif (!md.HasBody())\n\t\t\t\t\tcontinue;\n\t\t\t\tMethodBodyBlock body;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tbody = module.GetMethodBody(md.RelativeVirtualAddress);\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (ScanMethodBody(analyzedField, method, body))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tbool ScanMethodBody(IField analyzedField, IMethod method, MethodBodyBlock methodBody)\n\t\t{\n\t\t\tif (methodBody == null || method.ParentModule?.MetadataFile == null)\n\t\t\t\treturn false;\n\n\t\t\tvar mainModule = (MetadataModule)method.ParentModule;\n\t\t\tvar blob = methodBody.GetILReader();\n\t\t\tvar genericContext = new Decompiler.TypeSystem.GenericContext(); // type parameters don't matter for this analyzer\n\n\t\t\twhile (blob.RemainingBytes > 0)\n\t\t\t{\n\t\t\t\tILOpCode opCode;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\topCode = blob.DecodeOpCode();\n\t\t\t\t\tif (!CanBeReference(opCode))\n\t\t\t\t\t{\n\t\t\t\t\t\tblob.SkipOperand(opCode);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tEntityHandle fieldHandle = MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32());\n\t\t\t\tif (!fieldHandle.Kind.IsMemberKind())\n\t\t\t\t\tcontinue;\n\t\t\t\tIField? field;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tfield = mainModule.ResolveEntity(fieldHandle, genericContext) as IField;\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (field == null)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (field.MetadataToken == analyzedField.MetadataToken\n\t\t\t\t\t&& field.ParentModule?.MetadataFile == analyzedField.ParentModule!.MetadataFile)\n\t\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tbool CanBeReference(ILOpCode code)\n\t\t{\n\t\t\tswitch (code)\n\t\t\t{\n\t\t\t\tcase ILOpCode.Ldfld:\n\t\t\t\tcase ILOpCode.Ldsfld:\n\t\t\t\t\treturn !showWrites;\n\t\t\t\tcase ILOpCode.Stfld:\n\t\t\t\tcase ILOpCode.Stsfld:\n\t\t\t\t\treturn showWrites;\n\t\t\t\tcase ILOpCode.Ldflda:\n\t\t\t\tcase ILOpCode.Ldsflda:\n\t\t\t\t\treturn true; // always show address-loading\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/Builtin/FindTypeInAttributeDecoder.cs",
    "content": "// Copyright (c) 2022 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.Analyzers.Builtin\n{\n\tpublic enum TokenSearchResult : byte\n\t{\n\t\tNoResult = 0,\n\t\tByte = PrimitiveTypeCode.Byte,\n\t\tSByte = PrimitiveTypeCode.SByte,\n\t\tInt16 = PrimitiveTypeCode.Int16,\n\t\tUInt16 = PrimitiveTypeCode.UInt16,\n\t\tInt32 = PrimitiveTypeCode.Int32,\n\t\tUInt32 = PrimitiveTypeCode.UInt32,\n\t\tInt64 = PrimitiveTypeCode.Int64,\n\t\tUInt64 = PrimitiveTypeCode.UInt64,\n\t\tIntPtr = PrimitiveTypeCode.IntPtr,\n\t\tUIntPtr = PrimitiveTypeCode.UIntPtr,\n\n\t\t// lowest PrimitiveTypeCode is 1\n\t\t// highest PrimitiveTypeCode is 28 (0b0001_1100)\n\t\t// TokenSearchResult with a PrimitiveTypeCode set is only used when decoding an enum-type.\n\t\t// It is used for GetUnderlyingEnumType and should be masked out in all other uses.\n\t\t// MSB = Found\n\t\t// 127 = System.Type\n\t\tTypeCodeMask = 0b0111_1111,\n\t\tFound = 0b1000_0000,\n\t\tSystemType = 127,\n\t}\n\n\tclass FindTypeInAttributeDecoder : ICustomAttributeTypeProvider<TokenSearchResult>\n\t{\n\t\treadonly MetadataFile declaringModule;\n\t\treadonly MetadataModule currentModule;\n\t\treadonly TypeDefinitionHandle handle;\n\t\treadonly PrimitiveTypeCode primitiveType;\n\n\t\t/// <summary>\n\t\t/// Constructs a FindTypeInAttributeDecoder that can be used to find <paramref name=\"type\"/> in signatures from <paramref name=\"currentModule\"/>.\n\t\t/// </summary>\n\t\tpublic FindTypeInAttributeDecoder(MetadataModule currentModule, ITypeDefinition type)\n\t\t{\n\t\t\tthis.currentModule = currentModule;\n\t\t\tthis.declaringModule = type.ParentModule?.MetadataFile ?? throw new InvalidOperationException(\"Cannot use MetadataModule without PEFile as context.\");\n\t\t\tthis.handle = (TypeDefinitionHandle)type.MetadataToken;\n\t\t\tthis.primitiveType = type.KnownTypeCode == KnownTypeCode.None ? 0 : type.KnownTypeCode.ToPrimitiveTypeCode();\n\t\t}\n\n\t\tpublic TokenSearchResult GetPrimitiveType(PrimitiveTypeCode typeCode)\n\t\t{\n\t\t\treturn typeCode == primitiveType ? TokenSearchResult.Found : 0;\n\t\t}\n\n\t\tpublic TokenSearchResult GetSystemType() => TokenSearchResult.SystemType;\n\n\t\tpublic TokenSearchResult GetSZArrayType(TokenSearchResult elementType) => elementType & TokenSearchResult.Found;\n\n\t\tpublic TokenSearchResult GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)\n\t\t{\n\t\t\tTokenSearchResult result = TokenSearchResult.NoResult;\n\n\t\t\tif (handle.IsEnum(reader, out PrimitiveTypeCode underlyingType))\n\t\t\t{\n\t\t\t\tresult = (TokenSearchResult)underlyingType;\n\t\t\t}\n\t\t\telse if (((EntityHandle)handle).IsKnownType(reader, KnownTypeCode.Type))\n\t\t\t{\n\t\t\t\tresult = TokenSearchResult.SystemType;\n\t\t\t}\n\t\t\tif (this.handle == handle && reader == declaringModule.Metadata)\n\t\t\t{\n\t\t\t\tresult |= TokenSearchResult.Found;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic TokenSearchResult GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)\n\t\t{\n\t\t\tvar t = currentModule.ResolveType(handle, default);\n\t\t\treturn GetResultFromResolvedType(t);\n\t\t}\n\n\t\tpublic TokenSearchResult GetTypeFromSerializedName(string name)\n\t\t{\n\t\t\tif (name == null)\n\t\t\t{\n\t\t\t\treturn TokenSearchResult.NoResult;\n\t\t\t}\n\t\t\ttry\n\t\t\t{\n\t\t\t\tIType type = ReflectionHelper.ParseReflectionName(name, new SimpleTypeResolveContext(currentModule));\n\t\t\t\treturn GetResultFromResolvedType(type);\n\t\t\t}\n\t\t\tcatch (ReflectionNameParseException)\n\t\t\t{\n\t\t\t\treturn TokenSearchResult.NoResult;\n\t\t\t}\n\t\t}\n\n\t\tprivate TokenSearchResult GetResultFromResolvedType(IType type)\n\t\t{\n\t\t\tvar td = type.GetDefinition();\n\t\t\tif (td == null)\n\t\t\t\treturn TokenSearchResult.NoResult;\n\n\t\t\tTokenSearchResult result = TokenSearchResult.NoResult;\n\t\t\tvar underlyingType = td.EnumUnderlyingType?.GetDefinition();\n\t\t\tif (underlyingType != null)\n\t\t\t{\n\t\t\t\tresult = (TokenSearchResult)underlyingType.KnownTypeCode.ToPrimitiveTypeCode();\n\t\t\t}\n\t\t\telse if (td.KnownTypeCode == KnownTypeCode.Type)\n\t\t\t{\n\t\t\t\tresult = TokenSearchResult.SystemType;\n\t\t\t}\n\t\t\tif (td.MetadataToken == this.handle && td.ParentModule?.MetadataFile == declaringModule)\n\t\t\t{\n\t\t\t\tresult |= TokenSearchResult.Found;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic PrimitiveTypeCode GetUnderlyingEnumType(TokenSearchResult type)\n\t\t{\n\t\t\tTokenSearchResult typeCode = type & TokenSearchResult.TypeCodeMask;\n\t\t\tif (typeCode == 0 || typeCode == TokenSearchResult.SystemType)\n\t\t\t\tthrow new EnumUnderlyingTypeResolveException();\n\t\t\treturn (PrimitiveTypeCode)typeCode;\n\t\t}\n\n\t\tpublic bool IsSystemType(TokenSearchResult type) => (type & TokenSearchResult.TypeCodeMask) == TokenSearchResult.SystemType;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/Builtin/MemberImplementsInterfaceAnalyzer.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.Analyzers.Builtin\n{\n\t/// <summary>\n\t/// Shows members from all corresponding interfaces the selected member implements.\n\t/// </summary>\n\t[ExportAnalyzer(Header = \"Implements\", Order = 40)]\n\t[Shared]\n\tclass MemberImplementsInterfaceAnalyzer : IAnalyzer\n\t{\n\t\tpublic IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)\n\t\t{\n\t\t\tDebug.Assert(analyzedSymbol is IMember);\n\t\t\tvar member = (IMember)analyzedSymbol;\n\n\t\t\tDebug.Assert(!member.IsStatic);\n\n\t\t\tvar baseMembers = InheritanceHelper.GetBaseMembers(member, includeImplementedInterfaces: true);\n\t\t\treturn baseMembers.Where(m => m.DeclaringTypeDefinition?.Kind == TypeKind.Interface);\n\t\t}\n\n\t\tpublic bool Show(ISymbol symbol)\n\t\t{\n\t\t\tswitch (symbol?.SymbolKind)\n\t\t\t{\n\t\t\t\tcase SymbolKind.Event:\n\t\t\t\tcase SymbolKind.Indexer:\n\t\t\t\tcase SymbolKind.Method:\n\t\t\t\tcase SymbolKind.Property:\n\t\t\t\t\tvar member = (IMember)symbol;\n\t\t\t\t\tvar type = member.DeclaringTypeDefinition;\n\t\t\t\t\treturn !member.IsStatic && type is not null && (type.Kind == TypeKind.Class || type.Kind == TypeKind.Struct);\n\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/Builtin/MethodImplementedByAnalyzer.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.Analyzers.Builtin\n{\n\t/// <summary>\n\t/// Shows methods that implement an interface method.\n\t/// </summary>\n\t[ExportAnalyzer(Header = \"Implemented By\", Order = 40)]\n\t[Shared]\n\tclass MethodImplementedByAnalyzer : IAnalyzer\n\t{\n\t\tpublic IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)\n\t\t{\n\t\t\tDebug.Assert(analyzedSymbol is IMethod);\n\t\t\tvar scope = context.GetScopeOf((IEntity)analyzedSymbol);\n\t\t\tforeach (var type in scope.GetTypesInScope(context.CancellationToken))\n\t\t\t{\n\t\t\t\tforeach (var result in AnalyzeType((IMethod)analyzedSymbol, type))\n\t\t\t\t\tyield return result;\n\t\t\t}\n\t\t}\n\n\t\tIEnumerable<IEntity> AnalyzeType(IMethod analyzedEntity, ITypeDefinition type)\n\t\t{\n\t\t\tif (analyzedEntity.DeclaringTypeDefinition?.ParentModule?.MetadataFile == null)\n\t\t\t\tyield break;\n\t\t\tvar token = analyzedEntity.MetadataToken;\n\t\t\tvar declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken;\n\t\t\tvar module = analyzedEntity.DeclaringTypeDefinition.ParentModule.MetadataFile;\n\t\t\tvar allTypes = type.GetAllBaseTypeDefinitions();\n\t\t\tif (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule?.MetadataFile == module))\n\t\t\t\tyield break;\n\n\t\t\tforeach (var method in type.Methods)\n\t\t\t{\n\t\t\t\tvar baseMembers = InheritanceHelper.GetBaseMembers(method, true);\n\t\t\t\tif (baseMembers.Any(m => m.MetadataToken == token && m.ParentModule?.MetadataFile == module))\n\t\t\t\t\tyield return method;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool Show(ISymbol entity)\n\t\t{\n\t\t\treturn entity is IMethod method && method.DeclaringType.Kind == TypeKind.Interface;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/Builtin/MethodOverriddenByAnalyzer.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.Analyzers.Builtin\n{\n\t/// <summary>\n\t/// Shows methods that override a method.\n\t/// </summary>\n\t[ExportAnalyzer(Header = \"Overridden By\", Order = 30)]\n\t[Shared]\n\tclass MethodOverriddenByAnalyzer : IAnalyzer\n\t{\n\t\tconst GetMemberOptions Options = GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions;\n\n\t\tpublic IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)\n\t\t{\n\t\t\tDebug.Assert(analyzedSymbol is IMethod);\n\t\t\tvar scope = context.GetScopeOf((IEntity)analyzedSymbol);\n\t\t\tforeach (var type in scope.GetTypesInScope(context.CancellationToken))\n\t\t\t{\n\t\t\t\tforeach (var result in AnalyzeType((IMethod)analyzedSymbol, type))\n\t\t\t\t\tyield return result;\n\t\t\t}\n\t\t}\n\n\t\tIEnumerable<IEntity> AnalyzeType(IMethod analyzedEntity, ITypeDefinition type)\n\t\t{\n\t\t\tif (analyzedEntity.DeclaringTypeDefinition?.ParentModule?.MetadataFile == null)\n\t\t\t\tyield break;\n\t\t\tvar token = analyzedEntity.MetadataToken;\n\t\t\tvar declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken;\n\t\t\tvar module = analyzedEntity.DeclaringTypeDefinition.ParentModule.MetadataFile;\n\t\t\tvar allTypes = type.GetAllBaseTypeDefinitions();\n\t\t\tif (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule?.MetadataFile == module))\n\t\t\t\tyield break;\n\n\t\t\tforeach (var method in type.Methods)\n\t\t\t{\n\t\t\t\tif (!method.IsOverride)\n\t\t\t\t\tcontinue;\n\t\t\t\tvar baseMembers = InheritanceHelper.GetBaseMembers(method, false);\n\t\t\t\tif (baseMembers.Any(p => p.MetadataToken == token && p.ParentModule?.MetadataFile == module))\n\t\t\t\t{\n\t\t\t\t\tyield return method;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic bool Show(ISymbol entity)\n\t\t{\n\t\t\treturn entity is IMethod method && method.IsOverridable && method.DeclaringType.Kind != TypeKind.Interface;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/Builtin/MethodUsedByAnalyzer.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.Analyzers.Builtin\n{\n\t/// <summary>\n\t/// Shows entities that are used by a method.\n\t/// </summary>\n\t[ExportAnalyzer(Header = \"Used By\", Order = 20)]\n\t[Shared]\n\tclass MethodUsedByAnalyzer : IAnalyzer\n\t{\n\t\tconst GetMemberOptions Options = GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions;\n\n\t\tpublic bool Show(ISymbol symbol) => symbol is IMethod method && !method.IsVirtual && method.ParentModule is not null;\n\n\t\tpublic IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)\n\t\t{\n\t\t\tDebug.Assert(analyzedSymbol is IMethod);\n\n\t\t\tvar analyzedMethod = (IMethod)analyzedSymbol;\n\t\t\tvar analyzedBaseMethod = (IMethod?)InheritanceHelper.GetBaseMember(analyzedMethod);\n\t\t\tif (analyzedMethod.ParentModule?.MetadataFile == null)\n\t\t\t\tyield break;\n\t\t\tvar mapping = context.Language\n\t\t\t\t.GetCodeMappingInfo(analyzedMethod.ParentModule.MetadataFile,\n\t\t\t\t\tanalyzedMethod.DeclaringTypeDefinition!.MetadataToken);\n\n\t\t\tvar parentMethod = mapping.GetParentMethod((MethodDefinitionHandle)analyzedMethod.MetadataToken);\n\t\t\tif (parentMethod != analyzedMethod.MetadataToken)\n\t\t\t\tyield return ((MetadataModule)analyzedMethod.ParentModule).GetDefinition(parentMethod);\n\n\t\t\tvar scope = context.GetScopeOf(analyzedMethod);\n\t\t\tforeach (var type in scope.GetTypesInScope(context.CancellationToken))\n\t\t\t{\n\t\t\t\tif (type.ParentModule?.MetadataFile == null)\n\t\t\t\t\tcontinue;\n\t\t\t\tvar parentModule = (MetadataModule)type.ParentModule;\n\t\t\t\tmapping = null;\n\t\t\t\tvar methods = type.GetMembers(m => m is IMethod, Options).OfType<IMethod>();\n\t\t\t\tforeach (var method in methods)\n\t\t\t\t{\n\t\t\t\t\tif (IsUsedInMethod(analyzedMethod, analyzedBaseMethod, method, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tmapping ??= context.Language.GetCodeMappingInfo(parentModule.MetadataFile, type.MetadataToken);\n\t\t\t\t\t\tvar parent = mapping.GetParentMethod((MethodDefinitionHandle)method.MetadataToken);\n\t\t\t\t\t\tyield return parentModule.GetDefinition(parent);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tforeach (var property in type.Properties)\n\t\t\t\t{\n\t\t\t\t\tif (property.CanGet && IsUsedInMethod(analyzedMethod, analyzedBaseMethod, property.Getter, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return property;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (property.CanSet && IsUsedInMethod(analyzedMethod, analyzedBaseMethod, property.Setter, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return property;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tforeach (var @event in type.Events)\n\t\t\t\t{\n\t\t\t\t\tif (@event.CanAdd && IsUsedInMethod(analyzedMethod, analyzedBaseMethod, @event.AddAccessor, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return @event;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (@event.CanRemove && IsUsedInMethod(analyzedMethod, analyzedBaseMethod, @event.RemoveAccessor, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return @event;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (@event.CanInvoke && IsUsedInMethod(analyzedMethod, analyzedBaseMethod, @event.InvokeAccessor, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return @event;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool IsUsedInMethod(IMethod analyzedEntity, IMethod? analyzedBaseMethod, IMethod method, AnalyzerContext context)\n\t\t{\n\t\t\treturn ScanMethodBody(analyzedEntity, method, analyzedBaseMethod, context.GetMethodBody(method));\n\t\t}\n\n\t\tstatic bool ScanMethodBody(IMethod analyzedMethod, IMethod method, IMethod? analyzedBaseMethod, MethodBodyBlock? methodBody)\n\t\t{\n\t\t\tif (methodBody == null || method.ParentModule?.MetadataFile == null)\n\t\t\t\treturn false;\n\n\t\t\tvar mainModule = (MetadataModule)method.ParentModule;\n\t\t\tvar blob = methodBody.GetILReader();\n\n\t\t\tvar genericContext = new Decompiler.TypeSystem.GenericContext(); // type parameters don't matter for this analyzer\n\n\t\t\twhile (blob.RemainingBytes > 0)\n\t\t\t{\n\t\t\t\tILOpCode opCode;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\topCode = blob.DecodeOpCode();\n\t\t\t\t\tif (!IsSupportedOpCode(opCode))\n\t\t\t\t\t{\n\t\t\t\t\t\tILParser.SkipOperand(ref blob, opCode);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\treturn false; // unexpected end of blob\n\t\t\t\t}\n\t\t\t\tvar member = MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32());\n\t\t\t\tif (!AnalyzerHelpers.IsPossibleReferenceTo(member, mainModule.MetadataFile, analyzedMethod))\n\t\t\t\t{\n\t\t\t\t\tif (analyzedBaseMethod == null || !AnalyzerHelpers.IsPossibleReferenceTo(member, mainModule.MetadataFile, analyzedBaseMethod))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tIMember? m;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tm = (mainModule.ResolveEntity(member, genericContext) as IMember)?.MemberDefinition;\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (m == null)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (opCode == ILOpCode.Callvirt && analyzedBaseMethod != null)\n\t\t\t\t{\n\t\t\t\t\tif (IsSameMember(analyzedBaseMethod, m))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (IsSameMember(analyzedMethod, m))\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tstatic bool IsSupportedOpCode(ILOpCode opCode)\n\t\t{\n\t\t\tswitch (opCode)\n\t\t\t{\n\t\t\t\tcase ILOpCode.Call:\n\t\t\t\tcase ILOpCode.Callvirt:\n\t\t\t\tcase ILOpCode.Ldtoken:\n\t\t\t\tcase ILOpCode.Ldftn:\n\t\t\t\tcase ILOpCode.Ldvirtftn:\n\t\t\t\tcase ILOpCode.Newobj:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tstatic bool IsSameMember(IMember analyzedMethod, IMember m)\n\t\t{\n\t\t\treturn m.MetadataToken == analyzedMethod.MetadataToken\n\t\t\t\t&& m.ParentModule?.MetadataFile == analyzedMethod.ParentModule!.MetadataFile;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/Builtin/MethodUsesAnalyzer.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.Analyzers.Builtin\n{\n\t/// <summary>\n\t/// Shows entities that are used by a method.\n\t/// </summary>\n\t[ExportAnalyzer(Header = \"Uses\", Order = 10)]\n\t[Shared]\n\tclass MethodUsesAnalyzer : IAnalyzer\n\t{\n\t\tpublic bool Show(ISymbol symbol) => symbol is IMethod method && method.HasBody;\n\n\t\tpublic IEnumerable<ISymbol> Analyze(ISymbol symbol, AnalyzerContext context)\n\t\t{\n\t\t\tif (symbol is IMethod method && method.ParentModule?.MetadataFile is MetadataFile corFile)\n\t\t\t{\n\t\t\t\tvar typeSystem = context.GetOrCreateTypeSystem(corFile);\n\t\t\t\treturn context.Language.GetCodeMappingInfo(corFile, method.MetadataToken)\n\t\t\t\t\t.GetMethodParts((MethodDefinitionHandle)method.MetadataToken)\n\t\t\t\t\t.SelectMany(h => ScanMethod(h, typeSystem)).Distinct();\n\t\t\t}\n\t\t\tthrow new InvalidOperationException(\"Should never happen.\");\n\t\t}\n\n\t\tIEnumerable<IEntity> ScanMethod(MethodDefinitionHandle handle, DecompilerTypeSystem typeSystem)\n\t\t{\n\t\t\tvar module = typeSystem.MainModule;\n\t\t\tvar md = module.MetadataFile.Metadata.GetMethodDefinition(handle);\n\t\t\tif (!md.HasBody())\n\t\t\t\tyield break;\n\n\t\t\tBlobReader blob;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tblob = module.MetadataFile.GetMethodBody(md.RelativeVirtualAddress).GetILReader();\n\t\t\t}\n\t\t\tcatch (BadImageFormatException)\n\t\t\t{\n\t\t\t\tyield break;\n\t\t\t}\n\t\t\tvar visitor = new TypeDefinitionCollector();\n\t\t\tvar genericContext = new Decompiler.TypeSystem.GenericContext(); // type parameters don't matter for this analyzer\n\n\t\t\twhile (blob.RemainingBytes > 0)\n\t\t\t{\n\t\t\t\tILOpCode opCode;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\topCode = blob.DecodeOpCode();\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\tyield break;\n\t\t\t\t}\n\t\t\t\tswitch (opCode.GetOperandType())\n\t\t\t\t{\n\t\t\t\t\tcase OperandType.Field:\n\t\t\t\t\tcase OperandType.Method:\n\t\t\t\t\tcase OperandType.Sig:\n\t\t\t\t\tcase OperandType.Tok:\n\t\t\t\t\t\tvar member = MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32());\n\t\t\t\t\t\tif (member.IsNil)\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\tswitch (member.Kind)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase HandleKind.StandaloneSignature:\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\t\t\t\tcase HandleKind.TypeReference:\n\t\t\t\t\t\t\tcase HandleKind.TypeSpecification:\n\t\t\t\t\t\t\t\tIType? ty;\n\t\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tty = module.ResolveType(member, genericContext);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tty = null;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tty?.AcceptVisitor(visitor);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\t\t\tcase HandleKind.MethodSpecification:\n\t\t\t\t\t\t\tcase HandleKind.MemberReference:\n\t\t\t\t\t\t\tcase HandleKind.FieldDefinition:\n\t\t\t\t\t\t\t\tIEntity? m;\n\t\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tm = module.ResolveEntity(member, genericContext);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tm = null;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (m != null)\n\t\t\t\t\t\t\t\t\tyield return m;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tILParser.SkipOperand(ref blob, opCode);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tyield break;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach (var type in visitor.UsedTypes)\n\t\t\t{\n\t\t\t\tyield return type;\n\t\t\t}\n\t\t}\n\n\t\tclass TypeDefinitionCollector : TypeVisitor\n\t\t{\n\t\t\tpublic readonly List<ITypeDefinition> UsedTypes = new List<ITypeDefinition>();\n\n\t\t\tpublic override IType VisitTypeDefinition(ITypeDefinition type)\n\t\t\t{\n\t\t\t\tUsedTypes.Add(type);\n\t\t\t\treturn base.VisitTypeDefinition(type);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/Builtin/MethodVirtualUsedByAnalyzer.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.Analyzers.Builtin\n{\n\t/// <summary>\n\t/// Shows entities that are used by a method.\n\t/// </summary>\n\t[ExportAnalyzer(Header = \"Used By\", Order = 20)]\n\t[Shared]\n\tclass MethodVirtualUsedByAnalyzer : IAnalyzer\n\t{\n\t\tconst GetMemberOptions Options = GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions;\n\n\t\tpublic bool Show(ISymbol symbol) => symbol is IMethod method && method.IsVirtual;\n\n\t\tpublic IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)\n\t\t{\n\t\t\tDebug.Assert(analyzedSymbol is IMethod);\n\t\t\tvar analyzedMethod = (IMethod)analyzedSymbol;\n\n\t\t\tif (analyzedMethod.ParentModule?.MetadataFile == null)\n\t\t\t\tyield break;\n\n\t\t\tif (analyzedMethod.DeclaringTypeDefinition?.MetadataToken.IsNil != false)\n\t\t\t\tyield break;\n\n\t\t\tvar mapping = context.Language\n\t\t\t\t.GetCodeMappingInfo(analyzedMethod.ParentModule.MetadataFile,\n\t\t\t\t\tanalyzedMethod.DeclaringTypeDefinition?.MetadataToken ?? default);\n\n\t\t\tvar parentMethod = mapping.GetParentMethod((MethodDefinitionHandle)analyzedMethod.MetadataToken);\n\t\t\tif (parentMethod != analyzedMethod.MetadataToken)\n\t\t\t\tyield return ((MetadataModule)analyzedMethod.ParentModule).GetDefinition(parentMethod);\n\n\t\t\tvar scope = context.GetScopeOf(analyzedMethod);\n\t\t\tforeach (var type in scope.GetTypesInScope(context.CancellationToken))\n\t\t\t{\n\t\t\t\tvar parentModule = (MetadataModule?)type.ParentModule;\n\t\t\t\tif (parentModule?.MetadataFile == null)\n\t\t\t\t\tcontinue;\n\t\t\t\tmapping = context.Language.GetCodeMappingInfo(parentModule.MetadataFile, type.MetadataToken);\n\t\t\t\tvar methods = type.GetMembers(m => m is IMethod, Options).OfType<IMethod>();\n\t\t\t\tforeach (var method in methods)\n\t\t\t\t{\n\t\t\t\t\tif (IsUsedInMethod((IMethod)analyzedSymbol, method, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tvar parent = mapping.GetParentMethod((MethodDefinitionHandle)method.MetadataToken);\n\t\t\t\t\t\tyield return parentModule.GetDefinition(parent);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tforeach (var property in type.Properties)\n\t\t\t\t{\n\t\t\t\t\tif (property.CanGet && IsUsedInMethod((IMethod)analyzedSymbol, property.Getter, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return property;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (property.CanSet && IsUsedInMethod((IMethod)analyzedSymbol, property.Setter, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return property;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tforeach (var @event in type.Events)\n\t\t\t\t{\n\t\t\t\t\tif (@event.CanAdd && IsUsedInMethod((IMethod)analyzedSymbol, @event.AddAccessor, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return @event;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (@event.CanRemove && IsUsedInMethod((IMethod)analyzedSymbol, @event.RemoveAccessor, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return @event;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (@event.CanInvoke && IsUsedInMethod((IMethod)analyzedSymbol, @event.InvokeAccessor, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return @event;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\n\t\tbool IsUsedInMethod(IMethod analyzedEntity, IMethod method, AnalyzerContext context)\n\t\t{\n\t\t\treturn ScanMethodBody(analyzedEntity, method, context.GetMethodBody(method));\n\t\t}\n\n\t\tstatic bool ScanMethodBody(IMethod analyzedMethod, IMethod method, MethodBodyBlock? methodBody)\n\t\t{\n\t\t\tif (methodBody == null || method.ParentModule?.MetadataFile == null)\n\t\t\t\treturn false;\n\t\t\tvar mainModule = (MetadataModule)method.ParentModule;\n\t\t\tvar blob = methodBody.GetILReader();\n\t\t\tvar genericContext = new Decompiler.TypeSystem.GenericContext();\n\n\t\t\twhile (blob.RemainingBytes > 0)\n\t\t\t{\n\t\t\t\tvar opCode = blob.DecodeOpCode();\n\t\t\t\tswitch (opCode.GetOperandType())\n\t\t\t\t{\n\t\t\t\t\tcase OperandType.Method:\n\t\t\t\t\tcase OperandType.Sig:\n\t\t\t\t\tcase OperandType.Tok:\n\t\t\t\t\t\tvar member = MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32());\n\t\t\t\t\t\tif (member.IsNil)\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\tswitch (member.Kind)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\t\t\tcase HandleKind.MethodSpecification:\n\t\t\t\t\t\t\tcase HandleKind.MemberReference:\n\t\t\t\t\t\t\t\tvar m = (mainModule.ResolveEntity(member, genericContext) as IMember)?.MemberDefinition;\n\t\t\t\t\t\t\t\tif (m != null && m.MetadataToken == analyzedMethod.MetadataToken && m.ParentModule?.MetadataFile == analyzedMethod.ParentModule!.MetadataFile)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tILParser.SkipOperand(ref blob, opCode);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/Builtin/PropertyImplementedByAnalyzer.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.Analyzers.Builtin\n{\n\t/// <summary>\n\t/// Shows properties that implement an interface property.\n\t/// </summary>\n\t[ExportAnalyzer(Header = \"Implemented By\", Order = 10)]\n\t[Shared]\n\tclass PropertyImplementedByAnalyzer : IAnalyzer\n\t{\n\t\tpublic IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)\n\t\t{\n\t\t\tDebug.Assert(analyzedSymbol is IProperty);\n\t\t\tvar scope = context.GetScopeOf((IProperty)analyzedSymbol);\n\t\t\tforeach (var type in scope.GetTypesInScope(context.CancellationToken))\n\t\t\t{\n\t\t\t\tforeach (var result in AnalyzeType((IProperty)analyzedSymbol, type))\n\t\t\t\t\tyield return result;\n\t\t\t}\n\t\t}\n\n\t\tIEnumerable<IEntity> AnalyzeType(IProperty analyzedEntity, ITypeDefinition type)\n\t\t{\n\t\t\tif (analyzedEntity.DeclaringTypeDefinition?.ParentModule?.MetadataFile == null)\n\t\t\t\tyield break;\n\t\t\tvar token = analyzedEntity.MetadataToken;\n\t\t\tvar declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken;\n\t\t\tvar module = analyzedEntity.DeclaringTypeDefinition.ParentModule.MetadataFile;\n\t\t\tvar allTypes = type.GetAllBaseTypeDefinitions();\n\t\t\tif (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule?.MetadataFile == module))\n\t\t\t\tyield break;\n\n\t\t\tforeach (var property in type.Properties)\n\t\t\t{\n\t\t\t\tvar baseMembers = InheritanceHelper.GetBaseMembers(property, true);\n\t\t\t\tif (baseMembers.Any(m => m.MetadataToken == token && m.ParentModule?.MetadataFile == module))\n\t\t\t\t\tyield return property;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool Show(ISymbol symbol)\n\t\t{\n\t\t\treturn symbol is IProperty entity && entity.DeclaringType.Kind == TypeKind.Interface;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/Builtin/PropertyOverriddenByAnalyzer.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.Analyzers.Builtin\n{\n\t/// <summary>\n\t/// Shows properties that override a property.\n\t/// </summary>\n\t[ExportAnalyzer(Header = \"Overridden By\", Order = 20)]\n\t[Shared]\n\tclass PropertyOverriddenByAnalyzer : IAnalyzer\n\t{\n\t\tpublic IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)\n\t\t{\n\t\t\tDebug.Assert(analyzedSymbol is IProperty);\n\t\t\tvar scope = context.GetScopeOf((IProperty)analyzedSymbol);\n\t\t\tforeach (var type in scope.GetTypesInScope(context.CancellationToken))\n\t\t\t{\n\t\t\t\tforeach (var result in AnalyzeType((IProperty)analyzedSymbol, type))\n\t\t\t\t\tyield return result;\n\t\t\t}\n\t\t}\n\n\t\tIEnumerable<IEntity> AnalyzeType(IProperty analyzedEntity, ITypeDefinition type)\n\t\t{\n\t\t\tif (analyzedEntity.DeclaringTypeDefinition?.ParentModule?.MetadataFile == null)\n\t\t\t\tyield break;\n\t\t\tvar token = analyzedEntity.MetadataToken;\n\t\t\tvar declaringTypeToken = analyzedEntity.DeclaringTypeDefinition.MetadataToken;\n\t\t\tvar module = analyzedEntity.DeclaringTypeDefinition.ParentModule.MetadataFile;\n\t\t\tvar allTypes = type.GetAllBaseTypeDefinitions();\n\t\t\tif (!allTypes.Any(t => t.MetadataToken == declaringTypeToken && t.ParentModule?.MetadataFile == module))\n\t\t\t\tyield break;\n\n\t\t\tforeach (var property in type.Properties)\n\t\t\t{\n\t\t\t\tif (!property.IsOverride)\n\t\t\t\t\tcontinue;\n\t\t\t\tvar baseMembers = InheritanceHelper.GetBaseMembers(property, false);\n\t\t\t\tif (baseMembers.Any(p => p.MetadataToken == token && p.ParentModule?.MetadataFile == module))\n\t\t\t\t{\n\t\t\t\t\tyield return property;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic bool Show(ISymbol entity)\n\t\t{\n\t\t\treturn entity is IProperty property && property.IsOverridable && property.DeclaringType.Kind != TypeKind.Interface;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/Builtin/TypeExposedByAnalyzer.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Diagnostics;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.Analyzers.Builtin\n{\n\t/// <summary>\n\t/// Finds all entities that expose a type.\n\t/// </summary>\n\t[ExportAnalyzer(Header = \"Exposed By\", Order = 40)]\n\t[Shared]\n\tclass TypeExposedByAnalyzer : IAnalyzer\n\t{\n\t\tpublic bool Show(ISymbol entity) => entity is ITypeDefinition;\n\n\t\tpublic IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)\n\t\t{\n\t\t\tDebug.Assert(analyzedSymbol is ITypeDefinition);\n\t\t\tvar scope = context.GetScopeOf((ITypeDefinition)analyzedSymbol);\n\t\t\tforeach (var type in scope.GetTypesInScope(context.CancellationToken))\n\t\t\t{\n\t\t\t\tforeach (var result in ScanType((ITypeDefinition)analyzedSymbol, type, context))\n\t\t\t\t\tyield return result;\n\t\t\t}\n\t\t}\n\n\t\tIEnumerable<IEntity> ScanType(ITypeDefinition analyzedType, ITypeDefinition type, AnalyzerContext context)\n\t\t{\n\t\t\tif (analyzedType.Kind == TypeKind.Enum\n\t\t\t\t&& type.MetadataToken == analyzedType.MetadataToken\n\t\t\t\t&& type.ParentModule?.MetadataFile == analyzedType.ParentModule?.MetadataFile)\n\t\t\t\tyield break;\n\n\t\t\tif (!context.Language.ShowMember(type))\n\t\t\t\tyield break;\n\n\t\t\tvar visitor = new TypeDefinitionUsedVisitor(analyzedType, true);\n\n\t\t\tforeach (IField field in type.Fields)\n\t\t\t{\n\t\t\t\tif (TypeIsExposedBy(visitor, field))\n\t\t\t\t\tyield return field;\n\t\t\t}\n\n\t\t\tforeach (IProperty property in type.Properties)\n\t\t\t{\n\t\t\t\tif (TypeIsExposedBy(visitor, property))\n\t\t\t\t\tyield return property;\n\t\t\t}\n\n\t\t\tforeach (IEvent @event in type.Events)\n\t\t\t{\n\t\t\t\tif (TypeIsExposedBy(visitor, @event))\n\t\t\t\t\tyield return @event;\n\t\t\t}\n\n\t\t\tforeach (IMethod method in type.Methods)\n\t\t\t{\n\t\t\t\tif (TypeIsExposedBy(visitor, method))\n\t\t\t\t\tyield return method;\n\t\t\t}\n\t\t}\n\n\t\tbool TypeIsExposedBy(TypeDefinitionUsedVisitor visitor, IField field)\n\t\t{\n\t\t\tif (field.Accessibility == Accessibility.Private)\n\t\t\t\treturn false;\n\n\t\t\tvisitor.Found = false;\n\t\t\tfield.ReturnType.AcceptVisitor(visitor);\n\n\t\t\treturn visitor.Found;\n\t\t}\n\n\t\tbool TypeIsExposedBy(TypeDefinitionUsedVisitor visitor, IProperty property)\n\t\t{\n\t\t\tif (property.Accessibility == Accessibility.Private)\n\t\t\t{\n\t\t\t\tif (!property.IsExplicitInterfaceImplementation)\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvisitor.Found = false;\n\t\t\tproperty.ReturnType.AcceptVisitor(visitor);\n\n\t\t\tforeach (var p in property.Parameters)\n\t\t\t{\n\t\t\t\tp.Type.AcceptVisitor(visitor);\n\t\t\t}\n\n\t\t\treturn visitor.Found;\n\t\t}\n\n\t\tbool TypeIsExposedBy(TypeDefinitionUsedVisitor visitor, IEvent @event)\n\t\t{\n\t\t\tif (@event.Accessibility == Accessibility.Private)\n\t\t\t{\n\t\t\t\tif (!@event.IsExplicitInterfaceImplementation)\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvisitor.Found = false;\n\t\t\t@event.ReturnType.AcceptVisitor(visitor);\n\n\t\t\treturn visitor.Found;\n\t\t}\n\n\t\tbool TypeIsExposedBy(TypeDefinitionUsedVisitor visitor, IMethod method)\n\t\t{\n\t\t\tif (method.Accessibility == Accessibility.Private)\n\t\t\t{\n\t\t\t\tif (!method.IsExplicitInterfaceImplementation)\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvisitor.Found = false;\n\t\t\tmethod.ReturnType.AcceptVisitor(visitor);\n\n\t\t\tforeach (var p in method.Parameters)\n\t\t\t{\n\t\t\t\tp.Type.AcceptVisitor(visitor);\n\t\t\t}\n\n\t\t\treturn visitor.Found;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/Builtin/TypeExtensionMethodsAnalyzer.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Diagnostics;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.Analyzers.Builtin\n{\n\t/// <summary>\n\t/// Finds all extension methods defined for a type.\n\t/// </summary>\n\t[ExportAnalyzer(Header = \"Extension Methods\", Order = 50)]\n\t[Shared]\n\tclass TypeExtensionMethodsAnalyzer : IAnalyzer\n\t{\n\t\tpublic bool Show(ISymbol symbol) => symbol is ITypeDefinition entity && !entity.IsStatic;\n\n\t\tpublic IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)\n\t\t{\n\t\t\tDebug.Assert(analyzedSymbol is ITypeDefinition);\n\t\t\tvar scope = context.GetScopeOf((ITypeDefinition)analyzedSymbol);\n\t\t\tforeach (var type in scope.GetTypesInScope(context.CancellationToken))\n\t\t\t{\n\t\t\t\tforeach (var result in ScanType((ITypeDefinition)analyzedSymbol, type, context))\n\t\t\t\t\tyield return result;\n\t\t\t}\n\t\t}\n\n\t\tIEnumerable<IEntity> ScanType(ITypeDefinition analyzedType, ITypeDefinition type, AnalyzerContext context)\n\t\t{\n\t\t\tif (!type.HasExtensions)\n\t\t\t\tyield break;\n\n\t\t\tif (analyzedType.ParentModule?.MetadataFile == null)\n\t\t\t\tyield break;\n\n\t\t\tforeach (IMethod method in type.Methods)\n\t\t\t{\n\t\t\t\tif (!method.IsExtensionMethod)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tvar firstParamType = method.Parameters[0].Type.GetDefinition();\n\t\t\t\tif (firstParamType != null &&\n\t\t\t\t\tfirstParamType.MetadataToken == analyzedType.MetadataToken &&\n\t\t\t\t\tfirstParamType.ParentModule?.MetadataFile == analyzedType.ParentModule.MetadataFile)\n\t\t\t\t\tyield return method;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/Builtin/TypeInstantiatedByAnalyzer.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.Analyzers.Builtin\n{\n\t/// <summary>\n\t/// Shows methods that instantiate a type.\n\t/// </summary>\n\t[ExportAnalyzer(Header = \"Instantiated By\", Order = 20)]\n\t[Shared]\n\tclass TypeInstantiatedByAnalyzer : IAnalyzer\n\t{\n\t\tconst GetMemberOptions Options = GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions;\n\n\t\tpublic IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)\n\t\t{\n\t\t\tDebug.Assert(analyzedSymbol is ITypeDefinition);\n\t\t\tvar scope = context.GetScopeOf((ITypeDefinition)analyzedSymbol);\n\t\t\tforeach (var type in scope.GetTypesInScope(context.CancellationToken))\n\t\t\t{\n\t\t\t\tif (type.ParentModule?.MetadataFile == null)\n\t\t\t\t\tcontinue;\n\t\t\t\tvar mappingInfo = context.Language.GetCodeMappingInfo(type.ParentModule.MetadataFile, type.MetadataToken);\n\t\t\t\tvar methods = type.GetMembers(m => m is IMethod, Options).OfType<IMethod>();\n\t\t\t\tforeach (var method in methods)\n\t\t\t\t{\n\t\t\t\t\tif (IsUsedInMethod((ITypeDefinition)analyzedSymbol, method, mappingInfo, context))\n\t\t\t\t\t\tyield return method;\n\t\t\t\t}\n\n\t\t\t\tforeach (var property in type.Properties)\n\t\t\t\t{\n\t\t\t\t\tif (property.CanGet && IsUsedInMethod((ITypeDefinition)analyzedSymbol, property.Getter, mappingInfo, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return property;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (property.CanSet && IsUsedInMethod((ITypeDefinition)analyzedSymbol, property.Setter, mappingInfo, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return property;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tforeach (var @event in type.Events)\n\t\t\t\t{\n\t\t\t\t\tif (@event.CanAdd && IsUsedInMethod((ITypeDefinition)analyzedSymbol, @event.AddAccessor, mappingInfo, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return @event;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (@event.CanRemove && IsUsedInMethod((ITypeDefinition)analyzedSymbol, @event.RemoveAccessor, mappingInfo, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return @event;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (@event.CanInvoke && IsUsedInMethod((ITypeDefinition)analyzedSymbol, @event.InvokeAccessor, mappingInfo, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return @event;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool IsUsedInMethod(ITypeDefinition analyzedEntity, IMethod method, CodeMappingInfo mappingInfo, AnalyzerContext context)\n\t\t{\n\t\t\treturn ScanMethodBody(analyzedEntity, method, context.GetMethodBody(method));\n\t\t}\n\n\t\tbool ScanMethodBody(ITypeDefinition analyzedEntity, IMethod method, MethodBodyBlock? methodBody)\n\t\t{\n\t\t\tif (methodBody == null || method.ParentModule?.MetadataFile == null)\n\t\t\t\treturn false;\n\t\t\tvar blob = methodBody.GetILReader();\n\t\t\tvar module = (MetadataModule)method.ParentModule;\n\t\t\tvar genericContext = new Decompiler.TypeSystem.GenericContext(); // type parameters don't matter for this analyzer\n\n\t\t\twhile (blob.RemainingBytes > 0)\n\t\t\t{\n\t\t\t\tILOpCode opCode;\n\t\t\t\tEntityHandle handle;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\topCode = blob.DecodeOpCode();\n\t\t\t\t\tswitch (opCode)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase ILOpCode.Newobj:\n\t\t\t\t\t\tcase ILOpCode.Call when analyzedEntity.Kind == TypeKind.Struct:\n\t\t\t\t\t\tcase ILOpCode.Initobj:\n\t\t\t\t\t\t\thandle = MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32());\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tblob.SkipOperand(opCode);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tITypeDefinition? foundTypeDefinition;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tswitch (handle.Kind)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\t\tcase HandleKind.MemberReference:\n\t\t\t\t\t\t\tvar ctor = module.ResolveMethod(handle, genericContext);\n\t\t\t\t\t\t\tif (ctor == null || !ctor.IsConstructor)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfoundTypeDefinition = ctor.DeclaringTypeDefinition;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\t\t\tcase HandleKind.TypeReference:\n\t\t\t\t\t\t\tfoundTypeDefinition = module.ResolveType(handle, genericContext)?.GetDefinition();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (foundTypeDefinition?.ParentModule == null)\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (foundTypeDefinition.MetadataToken == analyzedEntity.MetadataToken\n\t\t\t\t\t&& foundTypeDefinition.ParentModule.MetadataFile == analyzedEntity.ParentModule!.MetadataFile)\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool Show(ISymbol symbol) => symbol is ITypeDefinition entity && !entity.IsAbstract && !entity.IsStatic;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/Builtin/TypeUsedByAnalyzer.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.Analyzers.Builtin\n{\n\t/// <summary>\n\t/// Shows entities that use a type.\n\t/// </summary>\n\t[ExportAnalyzer(Header = \"Used By\", Order = 30)]\n\t[Shared]\n\tclass TypeUsedByAnalyzer : IAnalyzer\n\t{\n\t\tpublic IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)\n\t\t{\n\t\t\tDebug.Assert(analyzedSymbol is ITypeDefinition);\n\t\t\tvar analyzedType = (ITypeDefinition)analyzedSymbol;\n\t\t\tvar scope = context.GetScopeOf(analyzedType);\n\t\t\tcontext.SortResults = true;\n\n\t\t\treturn scope.GetModulesInScope(context.CancellationToken)\n\t\t\t\t.AsParallel().AsOrdered()\n\t\t\t\t.SelectMany(AnalyzeModuleAndFilter);\n\n\t\t\tIEnumerable<ISymbol> AnalyzeModuleAndFilter(MetadataFile module)\n\t\t\t{\n\t\t\t\treturn AnalyzeModule(analyzedType, scope, module)\n\t\t\t\t\t.Distinct()\n\t\t\t\t\t.Where(s => !analyzedType.Equals((s as IEntity)?.DeclaringTypeDefinition));\n\t\t\t}\n\t\t}\n\n\t\tstatic IEnumerable<ISymbol> AnalyzeModule(ITypeDefinition analyzedType, AnalyzerScope scope, MetadataFile module)\n\t\t{\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar typeSystem = scope.ConstructTypeSystem(module);\n\t\t\tvar decoder = new FindTypeDecoder(typeSystem.MainModule, analyzedType);\n\n\t\t\t//// resolve type refs\n\t\t\t//int rowCount = metadata.GetTableRowCount(TableIndex.TypeRef);\n\t\t\t//BitSet typeReferences = new BitSet(rowCount);\n\t\t\t//for (int row = 0; row < rowCount; row++)\n\t\t\t//{\n\t\t\t//\tvar h = MetadataTokens.TypeReferenceHandle(row + 1);\n\t\t\t//\ttypeReferences[row] = decoder.GetTypeFromReference(metadata, h, 0);\n\t\t\t//}\n\n\t\t\t//// resolve type specs\n\t\t\t//rowCount = metadata.GetTableRowCount(TableIndex.TypeSpec);\n\t\t\t//BitSet typeSpecifications = new BitSet(rowCount);\n\t\t\t//for (int row = 0; row < rowCount; row++)\n\t\t\t//{\n\t\t\t//\tvar h = MetadataTokens.TypeSpecificationHandle(row + 1);\n\t\t\t//\ttypeSpecifications[row] = decoder.GetTypeFromSpecification(metadata, default, h, 0);\n\t\t\t//}\n\n\t\t\tforeach (ISymbol result in FindUsesInAttributes(typeSystem, metadata, decoder, analyzedType))\n\t\t\t\tyield return result;\n\n\t\t\tforeach (var h in metadata.TypeDefinitions)\n\t\t\t{\n\t\t\t\tvar td = metadata.GetTypeDefinition(h);\n\t\t\t\tbool found = decoder.GetTypeFromEntity(metadata, td.GetBaseTypeOrNil());\n\t\t\t\tforeach (var ih in td.GetInterfaceImplementations())\n\t\t\t\t{\n\t\t\t\t\tvar ii = metadata.GetInterfaceImplementation(ih);\n\t\t\t\t\tfound |= decoder.GetTypeFromEntity(metadata, ii.Interface);\n\t\t\t\t}\n\n\t\t\t\tfound |= FindUsesInGenericConstraints(metadata, td.GetGenericParameters(), decoder);\n\n\t\t\t\tif (found)\n\t\t\t\t\tyield return typeSystem.MainModule.GetDefinition(h);\n\t\t\t}\n\n\t\t\tforeach (var h in metadata.MethodDefinitions)\n\t\t\t{\n\t\t\t\tvar md = metadata.GetMethodDefinition(h);\n\t\t\t\tvar msig = md.DecodeSignature(decoder, default);\n\t\t\t\tbool found = FindTypeDecoder.AnyInMethodSignature(msig);\n\t\t\t\tfound |= FindUsesInGenericConstraints(metadata, md.GetGenericParameters(), decoder);\n\t\t\t\tif (found || ScanMethodBody(analyzedType, module, md, decoder))\n\t\t\t\t{\n\t\t\t\t\tvar method = typeSystem.MainModule.GetDefinition(h);\n\t\t\t\t\tyield return method.AccessorOwner ?? method;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach (var h in metadata.FieldDefinitions)\n\t\t\t{\n\t\t\t\tvar fd = metadata.GetFieldDefinition(h);\n\t\t\t\tif (fd.DecodeSignature(decoder, default))\n\t\t\t\t\tyield return typeSystem.MainModule.GetDefinition(h);\n\t\t\t}\n\n\t\t\tforeach (var h in metadata.PropertyDefinitions)\n\t\t\t{\n\t\t\t\tvar pd = metadata.GetPropertyDefinition(h);\n\t\t\t\tvar psig = pd.DecodeSignature(decoder, default);\n\t\t\t\tif (FindTypeDecoder.AnyInMethodSignature(psig))\n\t\t\t\t\tyield return typeSystem.MainModule.GetDefinition(h);\n\t\t\t}\n\n\t\t\tforeach (var h in metadata.EventDefinitions)\n\t\t\t{\n\t\t\t\tvar ed = metadata.GetEventDefinition(h);\n\t\t\t\tif (decoder.GetTypeFromEntity(metadata, ed.Type))\n\t\t\t\t\tyield return typeSystem.MainModule.GetDefinition(h);\n\t\t\t}\n\t\t}\n\n\t\tstatic bool FindUsesInGenericConstraints(MetadataReader metadata, GenericParameterHandleCollection collection, FindTypeDecoder decoder)\n\t\t{\n\t\t\tforeach (var h in collection)\n\t\t\t{\n\t\t\t\tvar gp = metadata.GetGenericParameter(h);\n\t\t\t\tforeach (var hc in gp.GetConstraints())\n\t\t\t\t{\n\t\t\t\t\tvar gc = metadata.GetGenericParameterConstraint(hc);\n\t\t\t\t\tif (decoder.GetTypeFromEntity(metadata, gc.Type))\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tstatic IEnumerable<ISymbol> FindUsesInAttributes(DecompilerTypeSystem typeSystem, MetadataReader metadata, FindTypeDecoder decoder, ITypeDefinition analyzedType)\n\t\t{\n\t\t\tvar attrDecoder = new FindTypeInAttributeDecoder(typeSystem.MainModule, analyzedType);\n\t\t\tvar referencedParameters = new HashSet<ParameterHandle>();\n\n\t\t\tforeach (var h in metadata.CustomAttributes)\n\t\t\t{\n\t\t\t\tvar customAttribute = metadata.GetCustomAttribute(h);\n\t\t\t\tCustomAttributeValue<TokenSearchResult> value;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tvalue = customAttribute.DecodeValue(attrDecoder);\n\t\t\t\t}\n\t\t\t\tcatch (EnumUnderlyingTypeResolveException)\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (AttributeAppliedToAnalyzer.IsCustomAttributeOfType(customAttribute.Constructor, metadata, decoder)\n\t\t\t\t\t|| AnalyzeCustomAttributeValue(value))\n\t\t\t\t{\n\t\t\t\t\tif (customAttribute.Parent.Kind == HandleKind.Parameter)\n\t\t\t\t\t{\n\t\t\t\t\t\treferencedParameters.Add((ParameterHandle)customAttribute.Parent);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tvar parent = AnalyzerHelpers.GetParentEntity(typeSystem, customAttribute);\n\t\t\t\t\t\tif (parent != null)\n\t\t\t\t\t\t\tyield return parent;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (referencedParameters.Count > 0)\n\t\t\t{\n\t\t\t\tforeach (var h in metadata.MethodDefinitions)\n\t\t\t\t{\n\t\t\t\t\tvar md = metadata.GetMethodDefinition(h);\n\t\t\t\t\tforeach (var p in md.GetParameters())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (referencedParameters.Contains(p))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar method = typeSystem.MainModule.ResolveMethod(h, default);\n\t\t\t\t\t\t\tif (method != null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (method.IsAccessor)\n\t\t\t\t\t\t\t\t\tyield return method.AccessorOwner;\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\tyield return method;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\tprivate static bool AnalyzeCustomAttributeValue(CustomAttributeValue<TokenSearchResult> attribute)\n\t\t{\n\t\t\tforeach (var fa in attribute.FixedArguments)\n\t\t\t{\n\t\t\t\tif (CheckAttributeValue(fa.Value))\n\t\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tforeach (var na in attribute.NamedArguments)\n\t\t\t{\n\t\t\t\tif (CheckAttributeValue(na.Value))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\n\t\t\tbool CheckAttributeValue(object? value)\n\t\t\t{\n\t\t\t\tif (value is TokenSearchResult typeofType)\n\t\t\t\t{\n\t\t\t\t\tif ((typeofType & TokenSearchResult.Found) != 0)\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse if (value is ImmutableArray<CustomAttributeTypedArgument<IType>> arr)\n\t\t\t\t{\n\t\t\t\t\tforeach (var element in arr)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (CheckAttributeValue(element.Value))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tstatic bool ScanMethodBody(ITypeDefinition analyzedType, MetadataFile module, in MethodDefinition md, FindTypeDecoder decoder)\n\t\t{\n\t\t\tif (!md.HasBody())\n\t\t\t\treturn false;\n\n\t\t\tvar methodBody = module.GetMethodBody(md.RelativeVirtualAddress);\n\t\t\tvar metadata = module.Metadata;\n\n\t\t\tif (!methodBody.LocalSignature.IsNil)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tvar ss = metadata.GetStandaloneSignature(methodBody.LocalSignature);\n\t\t\t\t\tif (HandleStandaloneSignature(ss))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\t// Issue #2197: ignore invalid local signatures\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar blob = methodBody.GetILReader();\n\n\t\t\twhile (blob.RemainingBytes > 0)\n\t\t\t{\n\t\t\t\tvar opCode = blob.DecodeOpCode();\n\t\t\t\tswitch (opCode.GetOperandType())\n\t\t\t\t{\n\t\t\t\t\tcase OperandType.Field:\n\t\t\t\t\tcase OperandType.Method:\n\t\t\t\t\tcase OperandType.Sig:\n\t\t\t\t\tcase OperandType.Tok:\n\t\t\t\t\tcase OperandType.Type:\n\t\t\t\t\t\tif (HandleMember(MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32())))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tblob.SkipOperand(opCode);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t\tbool HandleMember(EntityHandle member)\n\t\t\t{\n\t\t\t\tif (member.IsNil)\n\t\t\t\t\treturn false;\n\t\t\t\tswitch (member.Kind)\n\t\t\t\t{\n\t\t\t\t\tcase HandleKind.TypeReference:\n\t\t\t\t\t\treturn decoder.GetTypeFromReference(metadata, (TypeReferenceHandle)member, 0);\n\n\t\t\t\t\tcase HandleKind.TypeSpecification:\n\t\t\t\t\t\treturn decoder.GetTypeFromSpecification(metadata, default, (TypeSpecificationHandle)member, 0);\n\n\t\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\t\t\treturn decoder.GetTypeFromDefinition(metadata, (TypeDefinitionHandle)member, 0);\n\n\t\t\t\t\tcase HandleKind.FieldDefinition:\n\t\t\t\t\t\tvar fd = metadata.GetFieldDefinition((FieldDefinitionHandle)member);\n\t\t\t\t\t\treturn HandleMember(fd.GetDeclaringType()) || fd.DecodeSignature(decoder, default);\n\n\t\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\t\tvar md = metadata.GetMethodDefinition((MethodDefinitionHandle)member);\n\t\t\t\t\t\tif (HandleMember(md.GetDeclaringType()))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tvar msig = md.DecodeSignature(decoder, default);\n\t\t\t\t\t\tif (msig.ReturnType)\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tforeach (var t in msig.ParameterTypes)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (t)\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase HandleKind.MemberReference:\n\t\t\t\t\t\tvar mr = metadata.GetMemberReference((MemberReferenceHandle)member);\n\t\t\t\t\t\tif (HandleMember(mr.Parent))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tswitch (mr.GetKind())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase MemberReferenceKind.Method:\n\t\t\t\t\t\t\t\tmsig = mr.DecodeMethodSignature(decoder, default);\n\t\t\t\t\t\t\t\tif (msig.ReturnType)\n\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\tforeach (var t in msig.ParameterTypes)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif (t)\n\t\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase MemberReferenceKind.Field:\n\t\t\t\t\t\t\t\treturn mr.DecodeFieldSignature(decoder, default);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase HandleKind.MethodSpecification:\n\t\t\t\t\t\tvar ms = metadata.GetMethodSpecification((MethodSpecificationHandle)member);\n\t\t\t\t\t\tif (HandleMember(ms.Method))\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tvar mssig = ms.DecodeSignature(decoder, default);\n\t\t\t\t\t\tforeach (var t in mssig)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (t)\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase HandleKind.StandaloneSignature:\n\t\t\t\t\t\tvar ss = metadata.GetStandaloneSignature((StandaloneSignatureHandle)member);\n\t\t\t\t\t\treturn HandleStandaloneSignature(ss);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tbool HandleStandaloneSignature(StandaloneSignature signature)\n\t\t\t{\n\t\t\t\tswitch (signature.GetKind())\n\t\t\t\t{\n\t\t\t\t\tcase StandaloneSignatureKind.Method:\n\t\t\t\t\t\tvar msig = signature.DecodeMethodSignature(decoder, default);\n\t\t\t\t\t\tif (msig.ReturnType)\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tforeach (var t in msig.ParameterTypes)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (t)\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase StandaloneSignatureKind.LocalVariables:\n\t\t\t\t\t\tvar sig = signature.DecodeLocalSignature(decoder, default);\n\t\t\t\t\t\tforeach (var t in sig)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (t)\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool Show(ISymbol symbol) => symbol is ITypeDefinition;\n\t}\n\n\tclass TypeDefinitionUsedVisitor : TypeVisitor\n\t{\n\t\tpublic readonly ITypeDefinition TypeDefinition;\n\n\t\tpublic bool Found { get; set; }\n\n\t\treadonly bool topLevelOnly;\n\n\t\tpublic TypeDefinitionUsedVisitor(ITypeDefinition definition, bool topLevelOnly)\n\t\t{\n\t\t\tthis.TypeDefinition = definition;\n\t\t\tthis.topLevelOnly = topLevelOnly;\n\t\t}\n\n\t\tpublic override IType VisitTypeDefinition(ITypeDefinition type)\n\t\t{\n\t\t\tFound |= TypeDefinition.MetadataToken == type.MetadataToken\n\t\t\t\t&& TypeDefinition.ParentModule!.MetadataFile == type.ParentModule?.MetadataFile;\n\t\t\treturn base.VisitTypeDefinition(type);\n\t\t}\n\n\t\tpublic override IType VisitParameterizedType(ParameterizedType type)\n\t\t{\n\t\t\tif (topLevelOnly)\n\t\t\t\treturn type.GenericType.AcceptVisitor(this);\n\t\t\treturn base.VisitParameterizedType(type);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/ExportAnalyzerAttribute.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Linq;\nusing System.Reflection;\n\nnamespace ICSharpCode.ILSpyX.Analyzers\n{\n\t[MetadataAttribute]\n\t[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]\n\tpublic class ExportAnalyzerAttribute : ExportAttribute, IAnalyzerMetadata\n\t{\n\t\tpublic ExportAnalyzerAttribute() : base(\"Analyzer\", typeof(IAnalyzer))\n\t\t{ }\n\n\t\tpublic required string Header { get; init; }\n\n\t\tpublic int Order { get; set; }\n\n\t\tpublic static IEnumerable<(ExportAnalyzerAttribute AttributeData, Type AnalyzerType)> GetAnnotatedAnalyzers()\n\t\t{\n\t\t\tforeach (var type in typeof(ExportAnalyzerAttribute).Assembly.GetTypes())\n\t\t\t{\n\t\t\t\tif (type.GetCustomAttribute(typeof(ExportAnalyzerAttribute), false) is ExportAnalyzerAttribute exportAnalyzerAttribute)\n\t\t\t\t{\n\t\t\t\t\tyield return (exportAnalyzerAttribute, type);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Analyzers/IAnalyzer.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.Analyzers\n{\n\t/// <summary>\n\t/// Base interface for all analyzers. You can register an analyzer for any <see cref=\"ISymbol\"/> by implementing\n\t/// this interface and adding an <see cref=\"ExportAnalyzerAttribute\"/>.\n\t/// </summary>\n\tpublic interface IAnalyzer\n\t{\n\t\t/// <summary>\n\t\t/// Returns true, if the analyzer should be shown for a symbol, otherwise false.\n\t\t/// </summary>\n\t\tbool Show(ISymbol symbol);\n\n\t\t/// <summary>\n\t\t/// Returns all symbols found by this analyzer.\n\t\t/// </summary>\n\t\tIEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context);\n\t}\n\n\tpublic interface IAnalyzerMetadata\n\t{\n\t\tstring Header { get; }\n\n\t\tint Order { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/ApiVisibility.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.ILSpyX\n{\n\tpublic enum ApiVisibility\n\t{\n\t\tPublicOnly,\n\t\tPublicAndInternal,\n\t\tAll\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/AssemblyList.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Collections.ObjectModel;\nusing System.Collections.Specialized;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Xml.Linq;\n\nusing ICSharpCode.ILSpyX.Extensions;\nusing ICSharpCode.ILSpyX.FileLoaders;\n\nnamespace ICSharpCode.ILSpyX\n{\n\t/// <summary>\n\t/// A list of assemblies.\n\t/// </summary>\n\tpublic sealed class AssemblyList\n\t{\n\t\treadonly Thread ownerThread;\n\t\treadonly SynchronizationContext? synchronizationContext;\n\t\treadonly AssemblyListManager manager;\n\t\treadonly string listName;\n\n\t\t/// <summary>Dirty flag, used to mark modifications so that the list is saved later</summary>\n\t\tbool dirty;\n\t\treadonly object lockObj = new object();\n\n\t\t/// <summary>\n\t\t/// The assemblies in this list.\n\t\t/// Needs locking for multi-threaded access!\n\t\t/// Write accesses are allowed on the GUI thread only (but still need locking!)\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Technically read accesses need locking when done on non-GUI threads... but whenever possible, use the\n\t\t/// thread-safe <see cref=\"GetAssemblies()\"/> method.\n\t\t/// </remarks>\n\t\treadonly ObservableCollection<LoadedAssembly> assemblies = new ObservableCollection<LoadedAssembly>();\n\n\t\t/// <summary>\n\t\t/// Assembly lookup by filename.\n\t\t/// Usually byFilename.Values == assemblies; but when an assembly is loaded by a background thread,\n\t\t/// that assembly is added to byFilename immediately, and to assemblies only later on the main thread.\n\t\t/// </summary>\n\t\treadonly Dictionary<string, LoadedAssembly> byFilename = new Dictionary<string, LoadedAssembly>(StringComparer.OrdinalIgnoreCase);\n\n\t\t/// <summary>\n\t\t/// Exists for testing only.\n\t\t/// </summary>\n\t\tinternal AssemblyList()\n\t\t{\n\t\t\townerThread = Thread.CurrentThread;\n\t\t\tmanager = null!;\n\t\t\tlistName = \"Testing Only\";\n\t\t}\n\n\t\tinternal AssemblyList(AssemblyListManager manager, string listName)\n\t\t{\n\t\t\tthis.manager = manager ?? throw new ArgumentNullException(nameof(manager));\n\t\t\tthis.listName = listName;\n\t\t\tthis.ApplyWinRTProjections = manager.ApplyWinRTProjections;\n\t\t\tthis.UseDebugSymbols = manager.UseDebugSymbols;\n\t\t\townerThread = Thread.CurrentThread;\n\t\t\tsynchronizationContext = SynchronizationContext.Current;\n\t\t\tassemblies.CollectionChanged += Assemblies_CollectionChanged;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Loads an assembly list from XML.\n\t\t/// </summary>\n\t\tinternal AssemblyList(AssemblyListManager manager, XElement listElement)\n\t\t\t: this(manager, (string?)listElement.Attribute(\"name\") ?? AssemblyListManager.DefaultListName)\n\t\t{\n\t\t\tforeach (var asm in listElement.Elements(\"Assembly\"))\n\t\t\t{\n\t\t\t\tOpenAssembly((string)asm);\n\t\t\t}\n\t\t\tthis.dirty = false; // OpenAssembly() sets dirty, so reset it afterwards\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a copy of an assembly list.\n\t\t/// </summary>\n\t\tpublic AssemblyList(AssemblyList list, string newName)\n\t\t\t: this(list.manager, newName)\n\t\t{\n\t\t\tlock (lockObj)\n\t\t\t{\n\t\t\t\tlock (list.lockObj)\n\t\t\t\t{\n\t\t\t\t\tthis.assemblies.AddRange(list.assemblies);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.dirty = false;\n\t\t}\n\n\t\tpublic event NotifyCollectionChangedEventHandler CollectionChanged {\n\t\t\tadd {\n\t\t\t\tVerifyAccess();\n\t\t\t\tthis.assemblies.CollectionChanged += value;\n\t\t\t}\n\t\t\tremove {\n\t\t\t\tVerifyAccess();\n\t\t\t\tthis.assemblies.CollectionChanged -= value;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool ApplyWinRTProjections { get; set; }\n\t\tpublic bool UseDebugSymbols { get; set; }\n\t\tpublic FileLoaderRegistry LoaderRegistry => this.manager.LoaderRegistry;\n\n\t\t/// <summary>\n\t\t/// Gets the loaded assemblies. This method is thread-safe.\n\t\t/// </summary>\n\t\tpublic LoadedAssembly[] GetAssemblies()\n\t\t{\n\t\t\tlock (lockObj)\n\t\t\t{\n\t\t\t\treturn assemblies.ToArray();\n\t\t\t}\n\t\t}\n\n\t\tinternal AssemblyListSnapshot GetSnapshot()\n\t\t{\n\t\t\tlock (lockObj)\n\t\t\t{\n\t\t\t\treturn new AssemblyListSnapshot(assemblies.ToImmutableArray());\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets all loaded assemblies recursively, including assemblies found in bundles or packages.\n\t\t/// </summary>\n\t\tpublic Task<IList<LoadedAssembly>> GetAllAssemblies()\n\t\t{\n\t\t\treturn GetSnapshot().GetAllAssembliesAsync();\n\t\t}\n\n\t\tpublic int Count {\n\t\t\tget {\n\t\t\t\tlock (lockObj)\n\t\t\t\t{\n\t\t\t\t\treturn assemblies.Count;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Saves this assembly list to XML.\n\t\t/// </summary>\n\t\tinternal XElement SaveAsXml()\n\t\t{\n\t\t\treturn new XElement(\n\t\t\t\t\"List\",\n\t\t\t\tnew XAttribute(\"name\", this.ListName),\n\t\t\t\tassemblies.Where(asm => !asm.IsAutoLoaded).Select(asm => new XElement(\"Assembly\", asm.FileName))\n\t\t\t);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the name of this list.\n\t\t/// </summary>\n\t\tpublic string ListName {\n\t\t\tget { return listName; }\n\t\t}\n\n\t\tpublic void Move(LoadedAssembly[] assembliesToMove, int index)\n\t\t{\n\t\t\tVerifyAccess();\n\t\t\tlock (lockObj)\n\t\t\t{\n\t\t\t\tforeach (LoadedAssembly asm in assembliesToMove)\n\t\t\t\t{\n\t\t\t\t\tint nodeIndex = assemblies.IndexOf(asm);\n\t\t\t\t\tDebug.Assert(nodeIndex >= 0);\n\t\t\t\t\tif (nodeIndex < index)\n\t\t\t\t\t\tindex--;\n\t\t\t\t\tassemblies.RemoveAt(nodeIndex);\n\t\t\t\t}\n\t\t\t\tArray.Reverse(assembliesToMove);\n\t\t\t\tforeach (LoadedAssembly asm in assembliesToMove)\n\t\t\t\t{\n\t\t\t\t\tassemblies.Insert(index, asm);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid Assemblies_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)\n\t\t{\n\t\t\tDebug.Assert(Monitor.IsEntered(lockObj));\n\t\t\tif (CollectionChangeHasEffectOnSave(e))\n\t\t\t{\n\t\t\t\tRefreshSave();\n\t\t\t}\n\t\t}\n\n\t\tstatic bool CollectionChangeHasEffectOnSave(NotifyCollectionChangedEventArgs e)\n\t\t{\n\t\t\t// Auto-loading dependent assemblies shouldn't trigger saving the assembly list\n\t\t\tswitch (e.Action)\n\t\t\t{\n\t\t\t\tcase NotifyCollectionChangedAction.Add:\n\t\t\t\t\treturn e.NewItems.EmptyIfNull().Cast<LoadedAssembly>().Any(asm => !asm.IsAutoLoaded);\n\t\t\t\tcase NotifyCollectionChangedAction.Remove:\n\t\t\t\t\treturn e.OldItems.EmptyIfNull().Cast<LoadedAssembly>().Any(asm => !asm.IsAutoLoaded);\n\t\t\t\tdefault:\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tpublic void RefreshSave()\n\t\t{\n\t\t\t// Whenever the assembly list is modified, mark it as dirty\n\t\t\t// and enqueue a task that saves it once the UI has finished modifying the assembly list.\n\t\t\tif (!dirty)\n\t\t\t{\n\t\t\t\tdirty = true;\n\t\t\t\tBeginInvoke(\n\t\t\t\t\tdelegate {\n\t\t\t\t\t\tif (dirty)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdirty = false;\n\t\t\t\t\t\t\tthis.manager.SaveList(this);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Find an assembly that was previously opened.\n\t\t/// </summary>\n\t\tpublic LoadedAssembly? FindAssembly(string file)\n\t\t{\n\t\t\tfile = Path.GetFullPath(file);\n\t\t\tlock (lockObj)\n\t\t\t{\n\t\t\t\tif (byFilename.TryGetValue(file, out var asm))\n\t\t\t\t\treturn asm;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic LoadedAssembly Open(string assemblyUri, bool isAutoLoaded = false)\n\t\t{\n\t\t\treturn OpenAssembly(assemblyUri, isAutoLoaded);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Opens an assembly from disk.\n\t\t/// Returns the existing assembly node if it is already loaded.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// If called on the UI thread, the newly opened assembly is added to the list synchronously.\n\t\t/// If called on another thread, the newly opened assembly won't be returned by GetAssemblies()\n\t\t/// until the UI thread gets around to adding the assembly.\n\t\t/// </remarks>\n\t\tpublic LoadedAssembly OpenAssembly(string file, bool isAutoLoaded = false)\n\t\t{\n\t\t\tfile = Path.GetFullPath(file);\n\t\t\treturn OpenAssembly(file, () => {\n\t\t\t\tvar newAsm = new LoadedAssembly(this, file, fileLoaders: manager?.LoaderRegistry, applyWinRTProjections: ApplyWinRTProjections, useDebugSymbols: UseDebugSymbols) {\n\t\t\t\t\tIsAutoLoaded = isAutoLoaded\n\t\t\t\t};\n\t\t\t\treturn newAsm;\n\t\t\t});\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Opens an assembly from a stream.\n\t\t/// </summary>\n\t\tpublic LoadedAssembly OpenAssembly(string file, Stream? stream, bool isAutoLoaded = false)\n\t\t{\n\t\t\tfile = Path.GetFullPath(file);\n\t\t\treturn OpenAssembly(file, () => {\n\t\t\t\tvar newAsm = new LoadedAssembly(this, file, stream: Task.FromResult(stream),\n\t\t\t\t\tfileLoaders: manager?.LoaderRegistry,\n\t\t\t\t\tapplyWinRTProjections: ApplyWinRTProjections, useDebugSymbols: UseDebugSymbols);\n\t\t\t\tnewAsm.IsAutoLoaded = isAutoLoaded;\n\t\t\t\treturn newAsm;\n\t\t\t});\n\t\t}\n\n\t\tLoadedAssembly OpenAssembly(string file, Func<LoadedAssembly> load)\n\t\t{\n\t\t\tbool isUIThread = ownerThread == Thread.CurrentThread;\n\t\t\tLoadedAssembly? asm;\n\t\t\tlock (lockObj)\n\t\t\t{\n\t\t\t\tif (byFilename.TryGetValue(file, out asm))\n\t\t\t\t\treturn asm;\n\t\t\t\tasm = load();\n\t\t\t\tDebug.Assert(asm.FileName == file);\n\t\t\t\tbyFilename.Add(asm.FileName, asm);\n\n\t\t\t\tif (isUIThread)\n\t\t\t\t{\n\t\t\t\t\tassemblies.Add(asm);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!isUIThread)\n\t\t\t{\n\t\t\t\tBeginInvoke(delegate () {\n\t\t\t\t\tlock (lockObj)\n\t\t\t\t\t{\n\t\t\t\t\t\tassemblies.Add(asm);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn asm;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Replace the assembly object model from a crafted stream, without disk I/O\n\t\t/// Returns null if it is not already loaded.\n\t\t/// </summary>\n\t\tpublic LoadedAssembly? HotReplaceAssembly(string file, Stream stream)\n\t\t{\n\t\t\tVerifyAccess();\n\t\t\tfile = Path.GetFullPath(file);\n\t\t\tlock (lockObj)\n\t\t\t{\n\t\t\t\tif (!byFilename.TryGetValue(file, out LoadedAssembly? target))\n\t\t\t\t\treturn null;\n\t\t\t\tint index = this.assemblies.IndexOf(target);\n\t\t\t\tif (index < 0)\n\t\t\t\t\treturn null;\n\n\t\t\t\tvar newAsm = new LoadedAssembly(this, file, stream: Task.FromResult<Stream?>(stream),\n\t\t\t\t\tfileLoaders: manager?.LoaderRegistry,\n\t\t\t\t\tapplyWinRTProjections: ApplyWinRTProjections, useDebugSymbols: UseDebugSymbols);\n\t\t\t\tnewAsm.IsAutoLoaded = target.IsAutoLoaded;\n\n\t\t\t\tDebug.Assert(newAsm.FileName == file);\n\t\t\t\tbyFilename[file] = newAsm;\n\t\t\t\tthis.assemblies[index] = newAsm;\n\t\t\t\treturn newAsm;\n\t\t\t}\n\t\t}\n\n\t\tpublic LoadedAssembly? ReloadAssembly(string file)\n\t\t{\n\t\t\tVerifyAccess();\n\t\t\tfile = Path.GetFullPath(file);\n\n\t\t\tvar target = this.assemblies.FirstOrDefault(asm => file.Equals(asm.FileName, StringComparison.OrdinalIgnoreCase));\n\t\t\tif (target == null)\n\t\t\t\treturn null;\n\n\t\t\treturn ReloadAssembly(target);\n\t\t}\n\n\t\tpublic LoadedAssembly? ReloadAssembly(LoadedAssembly target)\n\t\t{\n\t\t\tVerifyAccess();\n\t\t\tvar index = this.assemblies.IndexOf(target);\n\t\t\tif (index < 0)\n\t\t\t\treturn null;\n\t\t\tvar newAsm = new LoadedAssembly(this, target.FileName, pdbFileName: target.PdbFileName,\n\t\t\t\tfileLoaders: manager?.LoaderRegistry,\n\t\t\t\tapplyWinRTProjections: ApplyWinRTProjections, useDebugSymbols: UseDebugSymbols);\n\t\t\tnewAsm.IsAutoLoaded = target.IsAutoLoaded;\n\t\t\tlock (lockObj)\n\t\t\t{\n\t\t\t\tthis.assemblies.Remove(target);\n\t\t\t\tthis.assemblies.Insert(index, newAsm);\n\t\t\t}\n\t\t\treturn newAsm;\n\t\t}\n\n\t\tpublic void Unload(LoadedAssembly assembly)\n\t\t{\n\t\t\tVerifyAccess();\n\t\t\tlock (lockObj)\n\t\t\t{\n\t\t\t\tassemblies.Remove(assembly);\n\t\t\t\tbyFilename.Remove(assembly.FileName);\n\t\t\t}\n\t\t}\n\n\t\tpublic void Clear()\n\t\t{\n\t\t\tVerifyAccess();\n\t\t\tlock (lockObj)\n\t\t\t{\n\t\t\t\tassemblies.Clear();\n\t\t\t\tbyFilename.Clear();\n\t\t\t}\n\t\t}\n\t\tpublic void Sort(IComparer<LoadedAssembly> comparer)\n\t\t{\n\t\t\tSort(0, int.MaxValue, comparer);\n\t\t}\n\n\t\tpublic void Sort(int index, int count, IComparer<LoadedAssembly> comparer)\n\t\t{\n\t\t\tVerifyAccess();\n\t\t\tlock (lockObj)\n\t\t\t{\n\t\t\t\tList<LoadedAssembly> list = new List<LoadedAssembly>(assemblies);\n\t\t\t\tlist.Sort(index, Math.Min(count, list.Count - index), comparer);\n\t\t\t\tassemblies.Clear();\n\t\t\t\tassemblies.AddRange(list);\n\t\t\t}\n\t\t}\n\n\t\tprivate void BeginInvoke(Action action)\n\t\t{\n\t\t\tif (synchronizationContext == null)\n\t\t\t{\n\t\t\t\taction();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsynchronizationContext.Post(new SendOrPostCallback(_ => action()), null);\n\t\t\t}\n\t\t}\n\n\t\tprivate void VerifyAccess()\n\t\t{\n\t\t\tif (this.ownerThread != Thread.CurrentThread)\n\t\t\t\tthrow new InvalidOperationException(\"This method must always be called on the thread that owns the assembly list: \" + ownerThread.ManagedThreadId + \" \" + ownerThread.Name);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/AssemblyListManager.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.ObjectModel;\nusing System.IO;\nusing System.Linq;\nusing System.Xml.Linq;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpyX.FileLoaders;\nusing ICSharpCode.ILSpyX.Settings;\n\nnamespace ICSharpCode.ILSpyX\n{\n\t/// <summary>\n\t/// Manages the available assembly lists.\n\t/// \n\t/// Contains the list of list names; and provides methods for loading/saving and creating/deleting lists.\n\t/// </summary>\n\tpublic sealed class AssemblyListManager\n\t{\n\t\tpublic const string DotNet4List = \".NET 4 (WPF)\";\n\t\tpublic const string DotNet35List = \".NET 3.5\";\n\t\tpublic const string ASPDotNetMVC3List = \"ASP.NET (MVC3)\";\n\n\t\tprivate readonly ISettingsProvider settingsProvider;\n\n\t\tpublic AssemblyListManager(ISettingsProvider settingsProvider)\n\t\t{\n\t\t\tthis.settingsProvider = settingsProvider;\n\t\t\tXElement doc = this.settingsProvider[\"AssemblyLists\"];\n\t\t\tforeach (var list in doc.Elements(\"List\"))\n\t\t\t{\n\t\t\t\tvar name = (string?)list.Attribute(\"name\");\n\t\t\t\tif (name != null)\n\t\t\t\t{\n\t\t\t\t\tAssemblyLists.Add(name);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic bool ApplyWinRTProjections { get; set; }\n\n\t\tpublic bool UseDebugSymbols { get; set; }\n\n\t\tpublic ObservableCollection<string> AssemblyLists { get; } = [];\n\n\t\tpublic FileLoaderRegistry LoaderRegistry { get; } = new();\n\n\t\t/// <summary>\n\t\t/// Loads an assembly list from the ILSpySettings.\n\t\t/// If no list with the specified name is found, the default list is loaded instead.\n\t\t/// </summary>\n\t\tpublic AssemblyList LoadList(string listName)\n\t\t{\n\t\t\tAssemblyList list = DoLoadList(listName);\n\t\t\tif (!AssemblyLists.Contains(list.ListName))\n\t\t\t\tAssemblyLists.Add(list.ListName);\n\t\t\treturn list;\n\t\t}\n\n\t\tAssemblyList DoLoadList(string? listName)\n\t\t{\n\t\t\tXElement doc = this.settingsProvider[\"AssemblyLists\"];\n\t\t\tif (listName != null)\n\t\t\t{\n\t\t\t\tforeach (var list in doc.Elements(\"List\"))\n\t\t\t\t{\n\t\t\t\t\tif ((string?)list.Attribute(\"name\") == listName)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new AssemblyList(this, list);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn new AssemblyList(this, listName ?? DefaultListName);\n\t\t}\n\n\t\tpublic bool CloneList(string selectedAssemblyList, string newListName)\n\t\t{\n\t\t\tvar list = DoLoadList(selectedAssemblyList);\n\t\t\tvar newList = new AssemblyList(list, newListName);\n\t\t\treturn AddListIfNotExists(newList);\n\t\t}\n\n\t\tpublic bool RenameList(string selectedAssemblyList, string newListName)\n\t\t{\n\t\t\tvar list = DoLoadList(selectedAssemblyList);\n\t\t\tvar newList = new AssemblyList(list, newListName);\n\t\t\treturn DeleteList(selectedAssemblyList) && AddListIfNotExists(newList);\n\t\t}\n\n\t\tpublic const string DefaultListName = \"(Default)\";\n\n\t\t/// <summary>\n\t\t/// Saves the specified assembly list into the config file.\n\t\t/// </summary>\n\t\tpublic void SaveList(AssemblyList list)\n\t\t{\n\t\t\tthis.settingsProvider.Update(\n\t\t\t\troot => {\n\t\t\t\t\tXElement? doc = root.Element(\"AssemblyLists\");\n\t\t\t\t\tif (doc == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tdoc = new XElement(\"AssemblyLists\");\n\t\t\t\t\t\troot.Add(doc);\n\t\t\t\t\t}\n\n\t\t\t\t\tXElement? listElement = doc.Elements(\"List\")\n\t\t\t\t\t\t.FirstOrDefault(e => (string?)e.Attribute(\"name\") == list.ListName);\n\t\t\t\t\tif (listElement != null)\n\t\t\t\t\t\tlistElement.ReplaceWith(list.SaveAsXml());\n\t\t\t\t\telse\n\t\t\t\t\t\tdoc.Add(list.SaveAsXml());\n\t\t\t\t});\n\t\t}\n\n\t\tpublic bool AddListIfNotExists(AssemblyList list)\n\t\t{\n\t\t\tif (!AssemblyLists.Contains(list.ListName))\n\t\t\t{\n\t\t\t\tAssemblyLists.Add(list.ListName);\n\t\t\t\tSaveList(list);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool DeleteList(string Name)\n\t\t{\n\t\t\tif (AssemblyLists.Remove(Name))\n\t\t\t{\n\t\t\t\tthis.settingsProvider.Update(\n\t\t\t\t\tdelegate (XElement root) {\n\t\t\t\t\t\tXElement? doc = root.Element(\"AssemblyLists\");\n\t\t\t\t\t\tif (doc == null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tXElement? listElement = doc.Elements(\"List\").FirstOrDefault(e => (string?)e.Attribute(\"name\") == Name);\n\t\t\t\t\t\tif (listElement != null)\n\t\t\t\t\t\t\tlistElement.Remove();\n\t\t\t\t\t});\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic void ClearAll()\n\t\t{\n\t\t\tAssemblyLists.Clear();\n\t\t\tthis.settingsProvider.Update(\n\t\t\t\troot => {\n\t\t\t\t\tXElement? doc = root.Element(\"AssemblyLists\");\n\t\t\t\t\tdoc?.Remove();\n\t\t\t\t});\n\t\t}\n\n\t\tpublic void CreateDefaultAssemblyLists()\n\t\t{\n\t\t\tif (AssemblyLists.Count > 0)\n\t\t\t\treturn;\n\n\t\t\tif (!AssemblyLists.Contains(DotNet4List))\n\t\t\t{\n\t\t\t\tAssemblyList dotnet4 = CreateDefaultList(DotNet4List);\n\t\t\t\tif (dotnet4.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tAddListIfNotExists(dotnet4);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!AssemblyLists.Contains(DotNet35List))\n\t\t\t{\n\t\t\t\tAssemblyList dotnet35 = CreateDefaultList(DotNet35List);\n\t\t\t\tif (dotnet35.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tAddListIfNotExists(dotnet35);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!AssemblyLists.Contains(ASPDotNetMVC3List))\n\t\t\t{\n\t\t\t\tAssemblyList mvc = CreateDefaultList(ASPDotNetMVC3List);\n\t\t\t\tif (mvc.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tAddListIfNotExists(mvc);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic AssemblyList CreateList(string name)\n\t\t{\n\t\t\treturn new AssemblyList(this, name);\n\t\t}\n\n\t\tpublic AssemblyList CreateDefaultList(string name, string? path = null, string? newName = null)\n\t\t{\n\t\t\tvar list = new AssemblyList(this, newName ?? name);\n\t\t\tswitch (name)\n\t\t\t{\n\t\t\t\tcase DotNet4List:\n\t\t\t\t\tAddToListFromGAC(\"mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System.Data.DataSetExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System.Xaml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\");\n\t\t\t\t\tAddToListFromGAC(\"PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\");\n\t\t\t\t\tAddToListFromGAC(\"PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\");\n\t\t\t\t\tAddToListFromGAC(\"WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase DotNet35List:\n\t\t\t\t\tAddToListFromGAC(\"mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\");\n\t\t\t\t\tAddToListFromGAC(\"PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\");\n\t\t\t\t\tAddToListFromGAC(\"WindowsBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase ASPDotNetMVC3List:\n\t\t\t\t\tAddToListFromGAC(\"mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System.ComponentModel.DataAnnotations, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\");\n\t\t\t\t\tAddToListFromGAC(\"System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\");\n\t\t\t\t\tAddToListFromGAC(\"System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System.Data.DataSetExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\");\n\t\t\t\t\tAddToListFromGAC(\"System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\");\n\t\t\t\t\tAddToListFromGAC(\"System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\");\n\t\t\t\t\tAddToListFromGAC(\"System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\");\n\t\t\t\t\tAddToListFromGAC(\"System.Web.ApplicationServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\");\n\t\t\t\t\tAddToListFromGAC(\"System.Web.DynamicData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\");\n\t\t\t\t\tAddToListFromGAC(\"System.Web.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\");\n\t\t\t\t\tAddToListFromGAC(\"System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\");\n\t\t\t\t\tAddToListFromGAC(\"System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\");\n\t\t\t\t\tAddToListFromGAC(\"System.Web.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\");\n\t\t\t\t\tAddToListFromGAC(\"System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\");\n\t\t\t\t\tAddToListFromGAC(\"System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35\");\n\t\t\t\t\tAddToListFromGAC(\"System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\");\n\t\t\t\t\tAddToListFromGAC(\"Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase object _ when path != null:\n\t\t\t\t\tforeach (var file in Directory.GetFiles(path, \"*.dll\"))\n\t\t\t\t\t{\n\t\t\t\t\t\tvar dllname = Path.GetFileName(file);\n\t\t\t\t\t\tif (DoIncludeFile(dllname))\n\t\t\t\t\t\t\tAddToListFromDirectory(file);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn list;\n\n\t\t\tvoid AddToListFromGAC(string fullName)\n\t\t\t{\n\t\t\t\tAssemblyNameReference reference = AssemblyNameReference.Parse(fullName);\n\t\t\t\tstring? file = UniversalAssemblyResolver.GetAssemblyInGac(reference);\n\t\t\t\tif (file != null)\n\t\t\t\t\tlist.OpenAssembly(file);\n\t\t\t}\n\n\t\t\tvoid AddToListFromDirectory(string file)\n\t\t\t{\n\t\t\t\tif (File.Exists(file))\n\t\t\t\t\tlist.OpenAssembly(file);\n\t\t\t}\n\n\t\t\tbool DoIncludeFile(string fileName)\n\t\t\t{\n\t\t\t\tif (fileName == \"Microsoft.DiaSymReader.Native.amd64.dll\")\n\t\t\t\t\treturn false;\n\t\t\t\tif (fileName.EndsWith(\"_cor3.dll\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\treturn false;\n\t\t\t\tif (char.IsUpper(fileName[0]))\n\t\t\t\t\treturn true;\n\t\t\t\tif (fileName == \"netstandard.dll\")\n\t\t\t\t\treturn true;\n\t\t\t\tif (fileName == \"mscorlib.dll\")\n\t\t\t\t\treturn true;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/AssemblyListSnapshot.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Util;\nusing ICSharpCode.ILSpyX.Extensions;\nusing ICSharpCode.ILSpyX.FileLoaders;\n\nnamespace ICSharpCode.ILSpyX\n{\n\tclass AssemblyListSnapshot\n\t{\n\t\treadonly ImmutableArray<LoadedAssembly> assemblies;\n\t\tDictionary<string, MetadataFile>? asmLookupByFullName;\n\t\tDictionary<string, MetadataFile>? asmLookupByShortName;\n\t\tDictionary<string, List<(MetadataFile module, Version version)>>? asmLookupByShortNameGrouped;\n\t\tpublic ImmutableArray<LoadedAssembly> Assemblies => assemblies;\n\n\t\tpublic AssemblyListSnapshot(ImmutableArray<LoadedAssembly> assemblies)\n\t\t{\n\t\t\tthis.assemblies = assemblies;\n\t\t}\n\n\t\tpublic async Task<MetadataFile?> TryGetModuleAsync(IAssemblyReference reference, string tfm)\n\t\t{\n\t\t\tbool isWinRT = reference.IsWindowsRuntime;\n\t\t\tif (tfm.StartsWith(\".NETFramework,Version=v4.\", StringComparison.Ordinal))\n\t\t\t{\n\t\t\t\ttfm = \".NETFramework,Version=v4\";\n\t\t\t}\n\t\t\tstring key = tfm + \";\" + (isWinRT ? reference.Name : reference.FullName);\n\t\t\tvar lookup = LazyInit.VolatileRead(ref isWinRT ? ref asmLookupByShortName : ref asmLookupByFullName);\n\t\t\tif (lookup == null)\n\t\t\t{\n\t\t\t\tlookup = await CreateLoadedAssemblyLookupAsync(shortNames: isWinRT).ConfigureAwait(false);\n\t\t\t\tlookup = LazyInit.GetOrSet(ref isWinRT ? ref asmLookupByShortName : ref asmLookupByFullName, lookup);\n\t\t\t}\n\t\t\tif (lookup.TryGetValue(key, out MetadataFile? module))\n\t\t\t\treturn module;\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic async Task<MetadataFile?> TryGetSimilarModuleAsync(IAssemblyReference reference)\n\t\t{\n\t\t\tvar lookup = LazyInit.VolatileRead(ref asmLookupByShortNameGrouped);\n\t\t\tif (lookup == null)\n\t\t\t{\n\t\t\t\tlookup = await CreateLoadedAssemblyShortNameGroupLookupAsync().ConfigureAwait(false);\n\t\t\t\tlookup = LazyInit.GetOrSet(ref asmLookupByShortNameGrouped, lookup);\n\t\t\t}\n\n\t\t\tif (!lookup.TryGetValue(reference.Name, out var candidates))\n\t\t\t\treturn null;\n\t\t\treturn candidates.FirstOrDefault(c => c.version >= reference.Version).module ?? candidates.Last().module;\n\t\t}\n\n\t\tprivate async Task<Dictionary<string, MetadataFile>> CreateLoadedAssemblyLookupAsync(bool shortNames)\n\t\t{\n\t\t\tvar result = new Dictionary<string, MetadataFile>(StringComparer.OrdinalIgnoreCase);\n\t\t\tforeach (LoadedAssembly loaded in assemblies)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tvar module = await loaded.GetMetadataFileOrNullAsync().ConfigureAwait(false);\n\t\t\t\t\tif (module == null)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tvar reader = module.Metadata;\n\t\t\t\t\tif (reader == null || !reader.IsAssembly)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tstring tfm = await loaded.GetTargetFrameworkIdAsync().ConfigureAwait(false);\n\t\t\t\t\tif (tfm.StartsWith(\".NETFramework,Version=v4.\", StringComparison.Ordinal))\n\t\t\t\t\t{\n\t\t\t\t\t\ttfm = \".NETFramework,Version=v4\";\n\t\t\t\t\t}\n\t\t\t\t\tstring key = tfm + \";\"\n\t\t\t\t\t\t+ (shortNames ? module.Name : module.FullName);\n\t\t\t\t\tif (!result.ContainsKey(key))\n\t\t\t\t\t{\n\t\t\t\t\t\tresult.Add(key, module);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tprivate async Task<Dictionary<string, List<(MetadataFile module, Version version)>>> CreateLoadedAssemblyShortNameGroupLookupAsync()\n\t\t{\n\t\t\tvar result = new Dictionary<string, List<(MetadataFile module, Version version)>>(StringComparer.OrdinalIgnoreCase);\n\n\t\t\tforeach (LoadedAssembly loaded in assemblies)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tvar module = await loaded.GetMetadataFileOrNullAsync().ConfigureAwait(false);\n\t\t\t\t\tvar reader = module?.Metadata;\n\t\t\t\t\tif (reader == null || !reader.IsAssembly)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tvar asmDef = reader.GetAssemblyDefinition();\n\t\t\t\t\tvar asmDefName = reader.GetString(asmDef.Name);\n\n\t\t\t\t\tvar line = (module!, version: asmDef.Version);\n\n\t\t\t\t\tif (!result.TryGetValue(asmDefName, out var existing))\n\t\t\t\t\t{\n\t\t\t\t\t\texisting = new List<(MetadataFile module, Version version)>();\n\t\t\t\t\t\tresult.Add(asmDefName, existing);\n\t\t\t\t\t\texisting.Add(line);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tint index = existing.BinarySearch(line.version, l => l.version);\n\t\t\t\t\tindex = index < 0 ? ~index : index + 1;\n\t\t\t\t\texisting.Insert(index, line);\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn result;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets all loaded assemblies recursively, including assemblies found in bundles or packages.\n\t\t/// </summary>\n\t\tpublic async Task<IList<LoadedAssembly>> GetAllAssembliesAsync()\n\t\t{\n\t\t\tvar results = new List<LoadedAssembly>(assemblies.Length);\n\n\t\t\tforeach (var asm in assemblies)\n\t\t\t{\n\t\t\t\tLoadResult result;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tresult = await asm.GetLoadResultAsync().ConfigureAwait(false);\n\t\t\t\t}\n\t\t\t\tcatch\n\t\t\t\t{\n\t\t\t\t\tresults.Add(asm);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (result.Package != null)\n\t\t\t\t{\n\t\t\t\t\tAddDescendants(result.Package.RootFolder);\n\t\t\t\t}\n\t\t\t\telse if (result.MetadataFile != null)\n\t\t\t\t{\n\t\t\t\t\tresults.Add(asm);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid AddDescendants(PackageFolder folder)\n\t\t\t{\n\t\t\t\tforeach (var subFolder in folder.Folders)\n\t\t\t\t{\n\t\t\t\t\tAddDescendants(subFolder);\n\t\t\t\t}\n\n\t\t\t\tforeach (var entry in folder.Entries)\n\t\t\t\t{\n\t\t\t\t\tif (!entry.Name.EndsWith(\".dll\", StringComparison.OrdinalIgnoreCase) && !entry.Name.EndsWith(\".exe\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tvar asm = folder.ResolveFileName(entry.Name);\n\t\t\t\t\tif (asm == null)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tresults.Add(asm);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn results;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Extensions/CollectionExtensions.cs",
    "content": "// Copyright (c) 2022 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.ILSpyX.Extensions\n{\n\tpublic static class CollectionExtensions\n\t{\n\t\tinternal static void AddRange<T>(this ICollection<T> list, IEnumerable<T> items)\n\t\t{\n\t\t\tforeach (T item in items)\n\t\t\t\tif (!list.Contains(item))\n\t\t\t\t\tlist.Add(item);\n\t\t}\n\n\t\tpublic static T? PeekOrDefault<T>(this Stack<T> stack)\n\t\t{\n\t\t\tif (stack.Count == 0)\n\t\t\t\treturn default(T);\n\t\t\treturn stack.Peek();\n\t\t}\n\n\t\tpublic static int BinarySearch<T>(this IList<T> list, T item, int start, int count, IComparer<T> comparer)\n\t\t{\n\t\t\tif (list == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(list));\n\t\t\tif (start < 0 || start >= list.Count)\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(start), start, \"Value must be between 0 and \" + (list.Count - 1));\n\t\t\tif (count < 0 || count > list.Count - start)\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(count), count, \"Value must be between 0 and \" + (list.Count - start));\n\t\t\tint end = start + count - 1;\n\t\t\twhile (start <= end)\n\t\t\t{\n\t\t\t\tint pivot = (start + end) / 2;\n\t\t\t\tint result = comparer.Compare(item, list[pivot]);\n\t\t\t\tif (result == 0)\n\t\t\t\t\treturn pivot;\n\t\t\t\tif (result < 0)\n\t\t\t\t\tend = pivot - 1;\n\t\t\t\telse\n\t\t\t\t\tstart = pivot + 1;\n\t\t\t}\n\t\t\treturn ~start;\n\t\t}\n\n\t\tpublic static int BinarySearch<T, TKey>(this IList<T> instance, TKey itemKey, Func<T, TKey> keySelector)\n\t\t\twhere TKey : IComparable<TKey>, IComparable\n\t\t{\n\t\t\tif (instance == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(instance));\n\t\t\tif (keySelector == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(keySelector));\n\n\t\t\tint start = 0;\n\t\t\tint end = instance.Count - 1;\n\n\t\t\twhile (start <= end)\n\t\t\t{\n\t\t\t\tint m = (start + end) / 2;\n\t\t\t\tTKey key = keySelector(instance[m]);\n\t\t\t\tint result = key.CompareTo(itemKey);\n\t\t\t\tif (result == 0)\n\t\t\t\t\treturn m;\n\t\t\t\tif (result < 0)\n\t\t\t\t\tstart = m + 1;\n\t\t\t\telse\n\t\t\t\t\tend = m - 1;\n\t\t\t}\n\t\t\treturn ~start;\n\t\t}\n\n\t\tpublic static void InsertSorted<T>(this IList<T> list, T item, IComparer<T> comparer)\n\t\t{\n\t\t\tif (list == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(list));\n\t\t\tif (comparer == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(comparer));\n\n\t\t\tif (list.Count == 0)\n\t\t\t{\n\t\t\t\tlist.Add(item);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tint index = list.BinarySearch(item, 0, list.Count, comparer);\n\t\t\t\tlist.Insert(index < 0 ? ~index : index, item);\n\t\t\t}\n\t\t}\n\n\t\tinternal static void Deconstruct<TKey, TValue>(this KeyValuePair<TKey, TValue> pair, out TKey key, out TValue value)\n\t\t{\n\t\t\tkey = pair.Key;\n\t\t\tvalue = pair.Value;\n\t\t}\n\n\t\tinternal static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T>? inst) => inst ?? Enumerable.Empty<T>();\n\t\tinternal static IEnumerable EmptyIfNull(this IEnumerable? inst) => inst ?? Enumerable.Empty<object>();\n\t\tinternal static IList<T> EmptyIfNull<T>(this IList<T>? inst) => inst ?? EmptyList<T>.Instance;\n\t\tinternal static IList EmptyIfNull(this IList? inst) => inst ?? Array.Empty<object>();\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/FileLoaders/ArchiveFileLoader.cs",
    "content": "// Copyright (c) 2024 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.IO;\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.ILSpyX.FileLoaders\n{\n\tpublic sealed class ArchiveFileLoader : IFileLoader\n\t{\n\t\tpublic Task<LoadResult?> Load(string fileName, Stream stream, FileLoadContext settings)\n\t\t{\n\t\t\tif (settings.ParentBundle != null)\n\t\t\t{\n\t\t\t\treturn Task.FromResult<LoadResult?>(null);\n\t\t\t}\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar zip = LoadedPackage.FromZipFile(fileName);\n\t\t\t\tvar result = zip != null ? new LoadResult { Package = zip } : null;\n\t\t\t\treturn Task.FromResult(result);\n\t\t\t}\n\t\t\tcatch (InvalidDataException)\n\t\t\t{\n\t\t\t\treturn Task.FromResult<LoadResult?>(null);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/FileLoaders/BundleFileLoader.cs",
    "content": "// Copyright (c) 2024 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.IO;\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.ILSpyX.FileLoaders\n{\n\tpublic sealed class BundleFileLoader : IFileLoader\n\t{\n\t\tpublic Task<LoadResult?> Load(string fileName, Stream stream, FileLoadContext settings)\n\t\t{\n\t\t\tif (settings.ParentBundle != null)\n\t\t\t{\n\t\t\t\treturn Task.FromResult<LoadResult?>(null);\n\t\t\t}\n\n\t\t\tvar bundle = LoadedPackage.FromBundle(fileName);\n\t\t\tvar result = bundle != null ? new LoadResult { Package = bundle } : null;\n\t\t\treturn Task.FromResult(result);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/FileLoaders/FileLoaderRegistry.cs",
    "content": "// Copyright (c) 2024 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.ILSpyX.FileLoaders\n{\n\tpublic sealed class FileLoaderRegistry\n\t{\n\t\treadonly List<IFileLoader> registeredLoaders = new List<IFileLoader>();\n\n\t\tpublic IReadOnlyList<IFileLoader> RegisteredLoaders => registeredLoaders;\n\n\t\tpublic void Register(IFileLoader loader)\n\t\t{\n\t\t\tif (loader is null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(loader));\n\t\t\t}\n\n\t\t\tregisteredLoaders.Add(loader);\n\t\t}\n\n\t\tpublic FileLoaderRegistry()\n\t\t{\n\t\t\tRegister(new XamarinCompressedFileLoader());\n\t\t\tRegister(new WebCilFileLoader());\n\t\t\tRegister(new MetadataFileLoader());\n\t\t\tRegister(new BundleFileLoader()); // bundles are PE files with a special signature, prefer over normal PE files\n\t\t\tRegister(new PEFileLoader()); // prefer PE format over archives, because ZIP has no fixed header\n\t\t\tRegister(new ArchiveFileLoader());\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/FileLoaders/LoadResult.cs",
    "content": "// Copyright (c) 2024 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpyX.FileLoaders\n{\n\tpublic sealed class LoadResult\n\t{\n\t\tpublic MetadataFile? MetadataFile { get; init; }\n\t\tpublic Exception? FileLoadException { get; init; }\n\t\tpublic LoadedPackage? Package { get; init; }\n\n\t\tpublic bool IsSuccess => FileLoadException == null;\n\t}\n\n\tpublic record FileLoadContext(bool ApplyWinRTProjections, LoadedAssembly? ParentBundle);\n\n\tpublic interface IFileLoader\n\t{\n\t\tTask<LoadResult?> Load(string fileName, Stream stream, FileLoadContext context);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/FileLoaders/MetadataFileLoader.cs",
    "content": "// Copyright (c) 2024 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\nusing System.Reflection.Metadata;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nusing static ICSharpCode.Decompiler.Metadata.MetadataFile;\n\nnamespace ICSharpCode.ILSpyX.FileLoaders\n{\n\tpublic sealed class MetadataFileLoader : IFileLoader\n\t{\n\t\tpublic Task<LoadResult?> Load(string fileName, Stream stream, FileLoadContext settings)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar kind = Path.GetExtension(fileName).Equals(\".pdb\", StringComparison.OrdinalIgnoreCase)\n\t\t\t\t\t? MetadataFileKind.ProgramDebugDatabase : MetadataFileKind.Metadata;\n\t\t\t\tvar metadata = MetadataReaderProvider.FromMetadataStream(stream, MetadataStreamOptions.PrefetchMetadata | MetadataStreamOptions.LeaveOpen);\n\t\t\t\tvar metadataFile = new MetadataFile(kind, fileName, metadata);\n\t\t\t\treturn Task.FromResult<LoadResult?>(new LoadResult { MetadataFile = metadataFile });\n\t\t\t}\n\t\t\tcatch (BadImageFormatException)\n\t\t\t{\n\t\t\t\treturn Task.FromResult<LoadResult?>(null);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/FileLoaders/PEFileLoader.cs",
    "content": "// Copyright (c) 2024 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.IO;\nusing System.Reflection.Metadata;\nusing System.Reflection.PortableExecutable;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpyX.FileLoaders\n{\n\tpublic sealed class PEFileLoader : IFileLoader\n\t{\n\t\tpublic async Task<LoadResult?> Load(string fileName, Stream stream, FileLoadContext context)\n\t\t{\n\t\t\tif (stream.Length < 2 || stream.ReadByte() != 'M' || stream.ReadByte() != 'Z')\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn await LoadPEFile(fileName, stream, context).ConfigureAwait(false);\n\t\t}\n\n\t\tpublic static Task<LoadResult> LoadPEFile(string fileName, Stream stream, FileLoadContext context)\n\t\t{\n\t\t\tMetadataReaderOptions options = context.ApplyWinRTProjections\n\t\t\t\t? MetadataReaderOptions.ApplyWindowsRuntimeProjections\n\t\t\t\t: MetadataReaderOptions.None;\n\t\t\tstream.Position = 0;\n\t\t\tPEFile module = new PEFile(fileName, stream, PEStreamOptions.PrefetchEntireImage | PEStreamOptions.LeaveOpen, metadataOptions: options);\n\t\t\treturn Task.FromResult(new LoadResult { MetadataFile = module });\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/FileLoaders/WebCilFileLoader.cs",
    "content": "// Copyright (c) 2024 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.IO;\nusing System.Reflection.Metadata;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpyX.FileLoaders\n{\n\tpublic sealed class WebCilFileLoader : IFileLoader\n\t{\n\t\tpublic Task<LoadResult?> Load(string fileName, Stream stream, FileLoadContext settings)\n\t\t{\n\t\t\tif (settings.ParentBundle != null)\n\t\t\t{\n\t\t\t\treturn Task.FromResult<LoadResult?>(null);\n\t\t\t}\n\n\t\t\tMetadataReaderOptions options = settings.ApplyWinRTProjections\n\t\t\t\t\t\t\t? MetadataReaderOptions.ApplyWindowsRuntimeProjections\n\t\t\t\t\t\t\t: MetadataReaderOptions.None;\n\n\t\t\tvar wasm = WebCilFile.FromFile(fileName, options);\n\t\t\tvar result = wasm != null ? new LoadResult { MetadataFile = wasm } : null;\n\t\t\treturn Task.FromResult(result);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/FileLoaders/XamarinCompressedFileLoader.cs",
    "content": "// Copyright (c) 2024 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Buffers;\nusing System.IO;\nusing System.Reflection.Metadata;\nusing System.Reflection.PortableExecutable;\nusing System.Text;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nusing K4os.Compression.LZ4;\n\nnamespace ICSharpCode.ILSpyX.FileLoaders\n{\n\tpublic sealed class XamarinCompressedFileLoader : IFileLoader\n\t{\n\t\tpublic async Task<LoadResult?> Load(string fileName, Stream stream, FileLoadContext context)\n\t\t{\n\t\t\tconst uint CompressedDataMagic = 0x5A4C4158; // Magic used for Xamarin compressed module header ('XALZ', little-endian)\n\t\t\tusing var fileReader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true);\n\t\t\t// Read compressed file header\n\t\t\tvar magic = fileReader.ReadUInt32();\n\t\t\tif (magic != CompressedDataMagic)\n\t\t\t\treturn null;\n\t\t\t_ = fileReader.ReadUInt32(); // skip index into descriptor table, unused\n\t\t\tint uncompressedLength = (int)fileReader.ReadUInt32();\n\t\t\tint compressedLength = (int)stream.Length;  // Ensure we read all of compressed data\n\t\t\tArrayPool<byte> pool = ArrayPool<byte>.Shared;\n\t\t\tvar src = pool.Rent(compressedLength);\n\t\t\tvar dst = pool.Rent(uncompressedLength);\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// fileReader stream position is now at compressed module data\n\t\t\t\tawait stream.ReadAsync(src, 0, compressedLength).ConfigureAwait(false);\n\t\t\t\t// Decompress\n\t\t\t\tLZ4Codec.Decode(src, 0, compressedLength, dst, 0, uncompressedLength);\n\t\t\t\t// Load module from decompressed data buffer\n\t\t\t\tusing (var uncompressedStream = new MemoryStream(dst, writable: false))\n\t\t\t\t{\n\t\t\t\t\tMetadataReaderOptions options = context.ApplyWinRTProjections\n\t\t\t\t\t\t? MetadataReaderOptions.ApplyWindowsRuntimeProjections\n\t\t\t\t\t\t: MetadataReaderOptions.None;\n\n\t\t\t\t\treturn new LoadResult {\n\t\t\t\t\t\tMetadataFile = new PEFile(fileName, uncompressedStream, PEStreamOptions.PrefetchEntireImage, metadataOptions: options)\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tpool.Return(dst);\n\t\t\t\tpool.Return(src);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/ICSharpCode.ILSpyX.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <TargetFramework>net10.0</TargetFramework>\r\n    <Nullable>enable</Nullable>\r\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\r\n    <WarningsAsErrors>nullable</WarningsAsErrors>\r\n\r\n    <SignAssembly>True</SignAssembly>\r\n    <AssemblyOriginatorKeyFile>..\\ICSharpCode.Decompiler\\ICSharpCode.Decompiler.snk</AssemblyOriginatorKeyFile>\r\n\r\n    <NeutralLanguage>en-US</NeutralLanguage>\r\n    <GenerateAssemblyVersionAttribute>False</GenerateAssemblyVersionAttribute>\r\n    <GenerateAssemblyFileVersionAttribute>False</GenerateAssemblyFileVersionAttribute>\r\n    <GenerateAssemblyInformationalVersionAttribute>False</GenerateAssemblyInformationalVersionAttribute>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup>\r\n    <PackageId>ICSharpCode.ILSpyX</PackageId>\r\n    <PackageVersion>8.0.0.0-noversion</PackageVersion>\r\n    <Title>ILSpyX Platform</Title>\r\n    <Authors>ILSpy Contributors</Authors>\r\n    <PackageLicenseExpression>MIT</PackageLicenseExpression>\r\n    <PackageProjectUrl>https://github.com/icsharpcode/ILSpy/</PackageProjectUrl>\r\n    <Description>Core cross-platform library used by ILSpy.</Description>\r\n    <PackageReadmeFile>PackageReadme.md</PackageReadmeFile>\r\n    <Company>ic#code</Company>\r\n    <Product>ILSpyX</Product>\r\n    <RepositoryType>git</RepositoryType>\r\n    <RepositoryUrl>https://github.com/icsharpcode/ILSpy.git</RepositoryUrl>\r\n    <PackageIconUrl>../ICSharpCode.Decompiler/DecompilerNuGetPackageIcon.png</PackageIconUrl>\r\n    <PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>\r\n    <Copyright>Copyright 2022-$([System.DateTime]::Now.Year) AlphaSierraPapa</Copyright>\r\n    <PackageTags>C# Decompiler ILSpy</PackageTags>\r\n    <GenerateSBOM>true</GenerateSBOM>\r\n\r\n    <DebugType>embedded</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n    <EmbedUntrackedSources>true</EmbedUntrackedSources>\r\n    <PublishRepositoryUrl>true</PublishRepositoryUrl>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <InternalsVisibleTo Include=\"ILSpy.Tests\" Key=\"00240000048000009400000006020000002400005253413100040000010001004dcf3979c4e902efa4dd2163a039701ed5822e6f1134d77737296abbb97bf0803083cfb2117b4f5446a217782f5c7c634f9fe1fc60b4c11d62c5b3d33545036706296d31903ddcf750875db38a8ac379512f51620bb948c94d0831125fbc5fe63707cbb93f48c1459c4d1749eb7ac5e681a2f0d6d7c60fa527a3c0b8f92b02bf\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <None Include=\"PackageReadme.md\" Pack=\"true\" PackagePath=\"\\\" />\r\n  </ItemGroup>\r\n\r\n  <!-- https://devblogs.microsoft.com/nuget/enable-repeatable-package-restores-using-a-lock-file/ -->\r\n  <PropertyGroup>\r\n    <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>\r\n\t<RestoreLockedMode>true</RestoreLockedMode>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <Compile Remove=\"Properties\\AssemblyInfo.template.cs\" />\r\n  </ItemGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(GITHUB_ACTIONS)' == 'true'\">\r\n    <ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>\r\n  </PropertyGroup>\r\n\r\n  <!-- Inject ILSpyUpdateAssemblyInfo as dependency of the GetPackageVersion\r\n    target so Pack uses the generated version when evaluating project references. -->\r\n  <PropertyGroup>\r\n    <GetPackageVersionDependsOn>\r\n      ILSpyUpdateAssemblyInfo;\r\n      $(GetPackageVersionDependsOn)\r\n    </GetPackageVersionDependsOn>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <None Remove=\"MermaidDiagrammer\\html\\node_modules\\**\" />\r\n    <None Remove=\"MermaidDiagrammer\\html\\.eslintrc.js\" />\r\n    <None Remove=\"MermaidDiagrammer\\html\\.gitignore\" />\r\n    <None Remove=\"MermaidDiagrammer\\html\\class-diagrammer.html\" />\r\n    <None Remove=\"MermaidDiagrammer\\html\\gulpfile.js\" />\r\n    <None Remove=\"MermaidDiagrammer\\html\\model.json\" />\r\n    <None Remove=\"MermaidDiagrammer\\html\\package-lock.json\" />\r\n    <None Remove=\"MermaidDiagrammer\\html\\package.json\" />\r\n    <None Remove=\"MermaidDiagrammer\\html\\styles.less\" />\r\n    <EmbeddedResource Include=\"..\\ILSpy\\Images\\ILSpy.ico\" Link=\"MermaidDiagrammer\\html\\ILSpy.ico\" />\r\n    <EmbeddedResource Include=\"MermaidDiagrammer\\html\\script.js\" />\r\n    <EmbeddedResource Include=\"MermaidDiagrammer\\html\\styles.css\" />\r\n    <EmbeddedResource Include=\"MermaidDiagrammer\\html\\template.html\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"System.Composition.AttributedModel\" />\r\n    <PackageReference Include=\"System.Reflection.Metadata\" />\r\n    <PackageReference Include=\"System.Runtime.CompilerServices.Unsafe\" />\r\n    <PackageReference Include=\"Mono.Cecil\" />\r\n    <PackageReference Include=\"K4os.Compression.LZ4\" />\r\n    <PackageReference Include=\"Microsoft.SourceLink.GitHub\">\r\n      <PrivateAssets>all</PrivateAssets>\r\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\r\n    </PackageReference>\r\n    <PackageReference Include=\"Microsoft.Sbom.Targets\">\r\n      <PrivateAssets>all</PrivateAssets>\r\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\r\n    </PackageReference>\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\ICSharpCode.Decompiler\\ICSharpCode.Decompiler.csproj\" />\r\n  </ItemGroup>\r\n\r\n  <Target Name=\"ILSpyUpdateAssemblyInfo\" AfterTargets=\"ResolveProjectReferences\">\r\n    <ReadLinesFromFile ContinueOnError=\"true\" File=\"..\\VERSION\">\r\n      <Output TaskParameter=\"Lines\" PropertyName=\"PackageVersion\" />\r\n      <Output TaskParameter=\"Lines\" PropertyName=\"SbomGenerationPackageVersion\" />\r\n    </ReadLinesFromFile>\r\n  </Target>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/LanguageVersion.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.ILSpyX\n{\n\t/// <summary>\n\t/// Version-DisplayName pair used in UI scenarios, for example ILSpy's language version dropdown.\n\t/// </summary>\n\tpublic class LanguageVersion\n\t{\n\t\tpublic string Version { get; }\n\t\tpublic string DisplayName { get; }\n\n\t\tpublic LanguageVersion(string version, string? name = null)\n\t\t{\n\t\t\tVersion = version ?? \"\";\n\t\t\tDisplayName = name ?? Version.ToString();\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn $\"[LanguageVersion DisplayName={DisplayName}, Version={Version}]\";\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/LoadedAssembly.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Reflection.Metadata;\nusing System.Reflection.PortableExecutable;\nusing System.Runtime.CompilerServices;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler.DebugInfo;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.Decompiler.Util;\nusing ICSharpCode.ILSpyX.FileLoaders;\nusing ICSharpCode.ILSpyX.PdbProvider;\n\n#nullable enable\n\nnamespace ICSharpCode.ILSpyX\n{\n\t/// <summary>\n\t/// Represents a file loaded into ILSpy.\n\t/// \n\t/// Note: this class is misnamed.\n\t/// The file is not necessarily an assembly, nor is it necessarily loaded.\n\t/// \n\t/// A LoadedAssembly can refer to:\n\t///   * a .NET module (single-file) loaded into ILSpy\n\t///   * a non-existant file\n\t///   * a file of unknown format that could not be loaded\n\t///   * a .nupkg file or .NET core bundle\n\t///   * a standalone portable pdb file or metadata stream\n\t///   * a file that is still being loaded in the background\n\t/// </summary>\n\t[DebuggerDisplay(\"[LoadedAssembly {shortName}]\")]\n\tpublic sealed class LoadedAssembly\n\t{\n\t\t/// <summary>\n\t\t/// Maps from MetadataFile (successfully loaded .NET module) back to the LoadedAssembly instance\n\t\t/// that was used to load the module.\n\t\t/// </summary>\n\t\tinternal static readonly ConditionalWeakTable<MetadataFile, LoadedAssembly> loadedAssemblies = new ConditionalWeakTable<MetadataFile, LoadedAssembly>();\n\n\t\treadonly Task<LoadResult> loadingTask;\n\t\treadonly AssemblyList assemblyList;\n\t\treadonly string fileName;\n\t\treadonly string shortName;\n\t\treadonly IAssemblyResolver? providedAssemblyResolver;\n\t\treadonly FileLoaderRegistry? fileLoaders;\n\t\treadonly bool applyWinRTProjections;\n\t\treadonly bool useDebugSymbols;\n\n\t\tpublic LoadedAssembly? ParentBundle { get; }\n\n\t\tpublic LoadedAssembly(AssemblyList assemblyList, string fileName,\n\t\t\tTask<Stream?>? stream = null,\n\t\t\tFileLoaderRegistry? fileLoaders = null,\n\t\t\tIAssemblyResolver? assemblyResolver = null,\n\t\t\tstring? pdbFileName = null,\n\t\t\tbool applyWinRTProjections = false, bool useDebugSymbols = false)\n\t\t{\n\t\t\tthis.assemblyList = assemblyList ?? throw new ArgumentNullException(nameof(assemblyList));\n\t\t\tthis.fileName = fileName ?? throw new ArgumentNullException(nameof(fileName));\n\t\t\tthis.PdbFileName = pdbFileName;\n\t\t\tthis.providedAssemblyResolver = assemblyResolver;\n\t\t\tthis.fileLoaders = fileLoaders;\n\t\t\tthis.applyWinRTProjections = applyWinRTProjections;\n\t\t\tthis.useDebugSymbols = useDebugSymbols;\n\n\t\t\tthis.loadingTask = Task.Run(() => LoadAsync(stream)); // requires that this.fileName is set\n\t\t\tthis.shortName = Path.GetFileNameWithoutExtension(fileName);\n\t\t}\n\n\t\tpublic LoadedAssembly(LoadedAssembly bundle, string fileName, Task<Stream?>? stream,\n\t\t\tFileLoaderRegistry? fileLoaders = null,\n\t\t\tIAssemblyResolver? assemblyResolver = null,\n\t\t\tbool applyWinRTProjections = false, bool useDebugSymbols = false)\n\t\t\t: this(bundle.assemblyList, fileName, stream, fileLoaders, assemblyResolver, null,\n\t\t\t\t  applyWinRTProjections, useDebugSymbols)\n\t\t{\n\t\t\tthis.ParentBundle = bundle;\n\t\t}\n\n\t\tstring? targetFrameworkId;\n\n\t\t/// <summary>\n\t\t/// Returns a target framework identifier in the form '&lt;framework&gt;Version=v&lt;version&gt;'.\n\t\t/// Returns an empty string if no TargetFrameworkAttribute was found\n\t\t/// or the file doesn't contain an assembly header, i.e., is only a module.\n\t\t/// \n\t\t/// Throws an exception if the file does not contain any .NET metadata (e.g. file of unknown format).\n\t\t/// </summary>\n\t\tpublic async Task<string> GetTargetFrameworkIdAsync()\n\t\t{\n\t\t\tvar value = LazyInit.VolatileRead(ref targetFrameworkId);\n\t\t\tif (value == null)\n\t\t\t{\n\t\t\t\tvar assembly = await GetMetadataFileAsync().ConfigureAwait(false);\n\t\t\t\tvalue = assembly.DetectTargetFrameworkId() ?? string.Empty;\n\t\t\t\tvalue = LazyInit.GetOrSet(ref targetFrameworkId, value);\n\t\t\t}\n\n\t\t\treturn value;\n\t\t}\n\n\t\tstring? runtimePack;\n\n\t\tpublic async Task<string> GetRuntimePackAsync()\n\t\t{\n\t\t\tvar value = LazyInit.VolatileRead(ref runtimePack);\n\t\t\tif (value == null)\n\t\t\t{\n\t\t\t\tvar assembly = await GetMetadataFileAsync().ConfigureAwait(false);\n\t\t\t\tvalue = assembly.DetectRuntimePack() ?? string.Empty;\n\t\t\t\tvalue = LazyInit.GetOrSet(ref runtimePack, value);\n\t\t\t}\n\n\t\t\treturn value;\n\t\t}\n\n\t\tpublic ReferenceLoadInfo LoadedAssemblyReferencesInfo { get; } = new ReferenceLoadInfo();\n\n\t\tIDebugInfoProvider? debugInfoProvider;\n\n\t\t/// <summary>\n\t\t/// Gets the <see cref=\"LoadResult\"/>.\n\t\t/// </summary>\n\t\tpublic Task<LoadResult> GetLoadResultAsync()\n\t\t{\n\t\t\treturn loadingTask;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the <see cref=\"MetadataFile\"/>.\n\t\t/// </summary>\n\t\tpublic async Task<MetadataFile> GetMetadataFileAsync()\n\t\t{\n\t\t\tvar loadResult = await loadingTask.ConfigureAwait(false);\n\t\t\tif (loadResult.MetadataFile != null)\n\t\t\t\treturn loadResult.MetadataFile;\n\t\t\telse\n\t\t\t\tthrow loadResult.FileLoadException ?? new MetadataFileNotSupportedException();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the <see cref=\"PEFile\"/>.\n\t\t/// Returns null in case of load errors.\n\t\t/// </summary>\n\t\tpublic MetadataFile? GetMetadataFileOrNull()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar loadResult = loadingTask.GetAwaiter().GetResult();\n\t\t\t\treturn loadResult.MetadataFile;\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tSystem.Diagnostics.Trace.TraceError(ex.ToString());\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the <see cref=\"MetadataFile\"/>.\n\t\t/// Returns null in case of load errors.\n\t\t/// </summary>\n\t\tpublic async Task<MetadataFile?> GetMetadataFileOrNullAsync()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar loadResult = await loadingTask.ConfigureAwait(false);\n\t\t\t\treturn loadResult.MetadataFile;\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tSystem.Diagnostics.Trace.TraceError(ex.ToString());\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tICompilation? typeSystem;\n\n\t\t/// <summary>\n\t\t/// Gets a type system containing all types from this assembly + primitive types from mscorlib.\n\t\t/// Returns null in case of load errors.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This is an uncached type system.\n\t\t/// </remarks>\n\t\tpublic ICompilation? GetTypeSystemOrNull()\n\t\t{\n\t\t\tvar value = Volatile.Read(ref this.typeSystem);\n\t\t\tif (value == null)\n\t\t\t{\n\t\t\t\tvar module = GetMetadataFileOrNull();\n\t\t\t\tif (module == null || module.IsMetadataOnly)\n\t\t\t\t\treturn null;\n\t\t\t\tvalue = new SimpleCompilation(\n\t\t\t\t\tmodule.WithOptions(TypeSystemOptions.Default | TypeSystemOptions.Uncached | TypeSystemOptions.KeepModifiers),\n\t\t\t\t\tMinimalCorlib.Instance);\n\t\t\t\tvalue = LazyInit.GetOrSet(ref this.typeSystem, value);\n\t\t\t}\n\n\t\t\treturn value;\n\t\t}\n\n\t\treadonly object typeSystemWithOptionsLockObj = new object();\n\t\tICompilation? typeSystemWithOptions;\n\t\tTypeSystemOptions? currentTypeSystemOptions;\n\n\t\tpublic ICompilation? GetTypeSystemOrNull(TypeSystemOptions options)\n\t\t{\n\t\t\tlock (typeSystemWithOptionsLockObj)\n\t\t\t{\n\t\t\t\tif (typeSystemWithOptions != null && options == currentTypeSystemOptions)\n\t\t\t\t\treturn typeSystemWithOptions;\n\t\t\t\tvar module = GetMetadataFileOrNull();\n\t\t\t\tif (module == null || module.IsMetadataOnly)\n\t\t\t\t\treturn null;\n\t\t\t\tcurrentTypeSystemOptions = options;\n\t\t\t\treturn typeSystemWithOptions = new SimpleCompilation(\n\t\t\t\t\tmodule.WithOptions(options | TypeSystemOptions.Uncached | TypeSystemOptions.KeepModifiers),\n\t\t\t\t\tMinimalCorlib.Instance);\n\t\t\t}\n\t\t}\n\n\t\tpublic AssemblyList AssemblyList => assemblyList;\n\n\t\tpublic string FileName => fileName;\n\n\t\tpublic string ShortName => shortName;\n\n\t\tpublic string Text {\n\t\t\tget {\n\t\t\t\tif (IsLoaded && !HasLoadError)\n\t\t\t\t{\n\t\t\t\t\tvar result = GetLoadResultAsync().GetAwaiter().GetResult();\n\t\t\t\t\tif (result.MetadataFile != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tswitch (result.MetadataFile.Kind)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase MetadataFile.MetadataFileKind.PortableExecutable:\n\t\t\t\t\t\t\t\tvar metadata = result.MetadataFile.Metadata;\n\t\t\t\t\t\t\t\tstring? versionOrInfo;\n\t\t\t\t\t\t\t\tif (metadata.IsAssembly)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tversionOrInfo = metadata.GetAssemblyDefinition().Version?.ToString();\n\t\t\t\t\t\t\t\t\tstring tfId = GetTargetFrameworkIdAsync().GetAwaiter().GetResult();\n\t\t\t\t\t\t\t\t\tif (!string.IsNullOrEmpty(tfId))\n\t\t\t\t\t\t\t\t\t\tversionOrInfo += \", \" + tfId.Replace(\"Version=\", \" \");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tversionOrInfo = \".netmodule\";\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (versionOrInfo == null)\n\t\t\t\t\t\t\t\t\treturn ShortName;\n\t\t\t\t\t\t\t\treturn string.Format(\"{0} ({1})\", ShortName, versionOrInfo);\n\t\t\t\t\t\t\tcase MetadataFile.MetadataFileKind.ProgramDebugDatabase:\n\t\t\t\t\t\t\t\treturn ShortName + \" (Debug Metadata)\";\n\t\t\t\t\t\t\tcase MetadataFile.MetadataFileKind.Metadata:\n\t\t\t\t\t\t\t\treturn ShortName + \" (Metadata)\";\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\treturn ShortName;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn ShortName;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether loading finished for this file (either successfully or unsuccessfully).\n\t\t/// </summary>\n\t\tpublic bool IsLoaded => loadingTask.IsCompleted;\n\n\t\t/// <summary>\n\t\t/// Gets whether this file was loaded successfully as an assembly (not as a bundle).\n\t\t/// </summary>\n\t\tpublic bool IsLoadedAsValidAssembly {\n\t\t\tget {\n\t\t\t\treturn loadingTask.Status == TaskStatus.RanToCompletion && loadingTask.Result.MetadataFile is { IsMetadataOnly: false };\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets whether loading failed (file does not exist, unknown file format).\n\t\t/// Returns false for valid assemblies and valid bundles.\n\t\t/// </summary>\n\t\tpublic bool HasLoadError => loadingTask.IsFaulted;\n\n\t\tpublic bool IsAutoLoaded { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets the PDB file name or null, if no PDB was found or it's embedded.\n\t\t/// </summary>\n\t\tpublic string? PdbFileName { get; private set; }\n\n\t\tasync Task<LoadResult> LoadAsync(Task<Stream?>? streamTask)\n\t\t{\n\t\t\tusing var stream = await PrepareStream();\n\t\t\tFileLoadContext settings = new FileLoadContext(applyWinRTProjections, ParentBundle);\n\n\t\t\tLoadResult? result = null;\n\n\t\t\tif (fileLoaders != null)\n\t\t\t{\n\t\t\t\tforeach (var loader in fileLoaders.RegisteredLoaders)\n\t\t\t\t{\n\t\t\t\t\t// In each iteration any of the following things may happen:\n\t\t\t\t\t// Load returns null because the loader is unable to handle the file, we simply continue without recording the result.\n\t\t\t\t\t// Load returns a non-null value that is either a valid result or an exception:\n\t\t\t\t\t// - if it's a success, we use that and end the loop,\n\t\t\t\t\t// - if it's an error, we remember the error, discarding any previous errors.\n\t\t\t\t\t// Load throws an exception, remember the error, discarding any previous errors.\n\t\t\t\t\tstream.Position = 0;\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tvar nextResult = await loader.Load(fileName, stream, settings).ConfigureAwait(false);\n\t\t\t\t\t\tif (nextResult != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tresult = nextResult;\n\t\t\t\t\t\t\tif (result.IsSuccess)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcatch (Exception ex)\n\t\t\t\t\t{\n\t\t\t\t\t\tresult = new LoadResult { FileLoadException = ex };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (result?.IsSuccess != true)\n\t\t\t{\n\t\t\t\tstream.Position = 0;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tresult = await PEFileLoader.LoadPEFile(fileName, stream, settings).ConfigureAwait(false);\n\t\t\t\t}\n\t\t\t\tcatch (Exception ex)\n\t\t\t\t{\n\t\t\t\t\tresult = new LoadResult { FileLoadException = ex };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (result.MetadataFile != null)\n\t\t\t{\n\t\t\t\tlock (loadedAssemblies)\n\t\t\t\t{\n\t\t\t\t\tloadedAssemblies.Add(result.MetadataFile, this);\n\t\t\t\t}\n\n\t\t\t\tif (result.MetadataFile is PEFile module)\n\t\t\t\t{\n\t\t\t\t\tdebugInfoProvider = LoadDebugInfo(module);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (result.Package != null)\n\t\t\t{\n\t\t\t\tresult.Package.LoadedAssembly = this;\n\t\t\t}\n\t\t\telse if (result.FileLoadException != null)\n\t\t\t{\n\t\t\t\tthrow result.FileLoadException;\n\t\t\t}\n\t\t\treturn result;\n\n\t\t\tasync Task<Stream> PrepareStream()\n\t\t\t{\n\t\t\t\t// runs on background thread\n\t\t\t\tvar stream = streamTask != null ? await streamTask.ConfigureAwait(false) : null;\n\t\t\t\tif (stream != null)\n\t\t\t\t{\n\t\t\t\t\t// Read the module from a precrafted stream\n\t\t\t\t\tif (!stream.CanSeek)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar memoryStream = new MemoryStream();\n\t\t\t\t\t\tstream.CopyTo(memoryStream);\n\t\t\t\t\t\tstream.Close();\n\t\t\t\t\t\tmemoryStream.Position = 0;\n\t\t\t\t\t\tstream = memoryStream;\n\t\t\t\t\t}\n\t\t\t\t\treturn stream;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn new FileStream(fileName, FileMode.Open, FileAccess.Read);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tIDebugInfoProvider? LoadDebugInfo(PEFile? module)\n\t\t{\n\t\t\tif (module == null)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (useDebugSymbols)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\treturn (PdbFileName != null ? DebugInfoUtils.FromFile(module, PdbFileName) : null)\n\t\t\t\t\t\t?? DebugInfoUtils.LoadSymbols(module);\n\t\t\t\t}\n\t\t\t\tcatch (IOException)\n\t\t\t\t{\n\t\t\t\t}\n\t\t\t\tcatch (UnauthorizedAccessException)\n\t\t\t\t{\n\t\t\t\t}\n\t\t\t\tcatch (InvalidOperationException)\n\t\t\t\t{\n\t\t\t\t\t// ignore any errors during symbol loading\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic async Task<IDebugInfoProvider?> LoadDebugInfo(string fileName)\n\t\t{\n\t\t\tthis.PdbFileName = fileName;\n\t\t\tvar assembly = await GetMetadataFileAsync().ConfigureAwait(false);\n\t\t\tdebugInfoProvider = await Task.Run(() => LoadDebugInfo(assembly as PEFile));\n\t\t\treturn debugInfoProvider;\n\t\t}\n\n\t\tsealed class MyAssemblyResolver : IAssemblyResolver\n\t\t{\n\t\t\treadonly LoadedAssembly parent;\n\t\t\treadonly bool loadOnDemand;\n\t\t\treadonly bool applyWinRTProjections;\n\n\t\t\treadonly IAssemblyResolver? providedAssemblyResolver;\n\t\t\treadonly AssemblyList assemblyList;\n\t\t\treadonly AssemblyListSnapshot alreadyLoadedAssemblies;\n\t\t\treadonly Task<string> tfmTask;\n\t\t\treadonly ReferenceLoadInfo referenceLoadInfo;\n\n\t\t\tpublic MyAssemblyResolver(LoadedAssembly parent, AssemblyListSnapshot assemblyListSnapshot,\n\t\t\t\tbool loadOnDemand, bool applyWinRTProjections)\n\t\t\t{\n\t\t\t\tthis.parent = parent;\n\t\t\t\tthis.loadOnDemand = loadOnDemand;\n\t\t\t\tthis.applyWinRTProjections = applyWinRTProjections;\n\n\t\t\t\tthis.providedAssemblyResolver = parent.providedAssemblyResolver;\n\t\t\t\tthis.assemblyList = parent.assemblyList;\n\t\t\t\t// Note: we cache a copy of the assembly list in the constructor, so that the\n\t\t\t\t// resolve calls only search-by-asm-name in the assemblies that were already loaded\n\t\t\t\t// at the time of the GetResolver() call.\n\t\t\t\tthis.alreadyLoadedAssemblies = assemblyListSnapshot;\n\t\t\t\t// If we didn't do this, we'd also search in the assemblies that we just started to load\n\t\t\t\t// in previous Resolve() calls; but we don't want to wait for those to be loaded.\n\t\t\t\tthis.tfmTask = parent.GetTargetFrameworkIdAsync();\n\t\t\t\tthis.referenceLoadInfo = parent.LoadedAssemblyReferencesInfo;\n\t\t\t}\n\n\t\t\tpublic MetadataFile? Resolve(IAssemblyReference reference)\n\t\t\t{\n\t\t\t\treturn ResolveAsync(reference).GetAwaiter().GetResult();\n\t\t\t}\n\n\t\t\t/// <summary>\n\t\t\t/// 0) if we're inside a package, look for filename.dll in parent directories\n\t\t\t/// 1) try to find exact match by tfm + full asm name in loaded assemblies\n\t\t\t/// 2) try to find match in search paths\n\t\t\t/// 3) if a.deps.json is found: search %USERPROFILE%/.nuget/packages/* as well\n\t\t\t/// 4) look in /dotnet/shared/{runtime-pack}/{closest-version}\n\t\t\t/// 5) if the version is retargetable or all zeros or ones, search C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\n\t\t\t/// 6) For \"mscorlib.dll\" we use the exact same assembly with which ILSpy runs\n\t\t\t/// 7) Search the GAC\n\t\t\t/// 8) search C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\n\t\t\t/// 9) try to find match by asm name (no tfm/version) in loaded assemblies\n\t\t\t/// </summary>\n\t\t\tpublic async Task<MetadataFile?> ResolveAsync(IAssemblyReference reference)\n\t\t\t{\n\t\t\t\tMetadataFile? module;\n\t\t\t\t// 0) if we're inside a package, look for filename.dll in parent directories\n\t\t\t\tif (providedAssemblyResolver != null)\n\t\t\t\t{\n\t\t\t\t\tmodule = await providedAssemblyResolver.ResolveAsync(reference).ConfigureAwait(false);\n\t\t\t\t\tif (module != null)\n\t\t\t\t\t\treturn module;\n\t\t\t\t}\n\n\t\t\t\tstring tfm = await tfmTask.ConfigureAwait(false);\n\n\t\t\t\t// 1) try to find exact match by tfm + full asm name in loaded assemblies\n\t\t\t\tmodule = await alreadyLoadedAssemblies.TryGetModuleAsync(reference, tfm).ConfigureAwait(false);\n\t\t\t\tif (module != null)\n\t\t\t\t{\n\t\t\t\t\treferenceLoadInfo.AddMessageOnce(reference.FullName, MessageKind.Info, \"Success - Found in Assembly List\");\n\t\t\t\t\treturn module;\n\t\t\t\t}\n\n\t\t\t\tstring? file = parent.GetUniversalResolver(applyWinRTProjections).FindAssemblyFile(reference);\n\n\t\t\t\tif (file != null)\n\t\t\t\t{\n\t\t\t\t\t// Load assembly from disk\n\t\t\t\t\tLoadedAssembly? asm;\n\t\t\t\t\tif (loadOnDemand)\n\t\t\t\t\t{\n\t\t\t\t\t\tasm = assemblyList.OpenAssembly(file, isAutoLoaded: true);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tasm = assemblyList.FindAssembly(file);\n\t\t\t\t\t}\n\t\t\t\t\tif (asm != null)\n\t\t\t\t\t{\n\t\t\t\t\t\treferenceLoadInfo.AddMessage(reference.FullName, MessageKind.Info, \"Success - Loading from: \" + file);\n\t\t\t\t\t\treturn await asm.GetMetadataFileOrNullAsync().ConfigureAwait(false);\n\t\t\t\t\t}\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// Assembly not found; try to find a similar-enough already-loaded assembly\n\t\t\t\t\tmodule = await alreadyLoadedAssemblies.TryGetSimilarModuleAsync(reference).ConfigureAwait(false);\n\t\t\t\t\tif (module == null)\n\t\t\t\t\t{\n\t\t\t\t\t\treferenceLoadInfo.AddMessageOnce(reference.FullName, MessageKind.Error, \"Could not find reference: \" + reference.FullName);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treferenceLoadInfo.AddMessageOnce(reference.FullName, MessageKind.Info, \"Success - Found in Assembly List with different TFM or version: \" + module.FileName);\n\t\t\t\t\t}\n\t\t\t\t\treturn module;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic MetadataFile? ResolveModule(MetadataFile mainModule, string moduleName)\n\t\t\t{\n\t\t\t\treturn ResolveModuleAsync(mainModule, moduleName).GetAwaiter().GetResult();\n\t\t\t}\n\n\t\t\tpublic async Task<MetadataFile?> ResolveModuleAsync(MetadataFile mainModule, string moduleName)\n\t\t\t{\n\t\t\t\tif (providedAssemblyResolver != null)\n\t\t\t\t{\n\t\t\t\t\tvar module = await providedAssemblyResolver.ResolveModuleAsync(mainModule, moduleName).ConfigureAwait(false);\n\t\t\t\t\tif (module != null)\n\t\t\t\t\t\treturn module;\n\t\t\t\t}\n\n\t\t\t\tstring? directory = Path.GetDirectoryName(mainModule.FileName);\n\t\t\t\tif (directory != null)\n\t\t\t\t{\n\t\t\t\t\tstring file = Path.Combine(directory, moduleName);\n\t\t\t\t\tif (File.Exists(file))\n\t\t\t\t\t{\n\t\t\t\t\t\t// Load module from disk\n\t\t\t\t\t\tLoadedAssembly? asm;\n\t\t\t\t\t\tif (loadOnDemand)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tasm = assemblyList.OpenAssembly(file, isAutoLoaded: true);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tasm = assemblyList.FindAssembly(file);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (asm != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn await asm.GetMetadataFileOrNullAsync().ConfigureAwait(false);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Module does not exist on disk, look for one with a matching name in the assemblylist:\n\t\t\t\tforeach (LoadedAssembly loaded in alreadyLoadedAssemblies.Assemblies)\n\t\t\t\t{\n\t\t\t\t\tvar module = await loaded.GetMetadataFileOrNullAsync().ConfigureAwait(false);\n\t\t\t\t\tvar reader = module?.Metadata;\n\t\t\t\t\tif (reader == null || reader.IsAssembly)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tvar moduleDef = reader.GetModuleDefinition();\n\t\t\t\t\tif (moduleName.Equals(reader.GetString(moduleDef.Name), StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\t{\n\t\t\t\t\t\treferenceLoadInfo.AddMessageOnce(moduleName, MessageKind.Info, \"Success - Found in Assembly List\");\n\t\t\t\t\t\treturn module;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tpublic IAssemblyResolver GetAssemblyResolver(bool loadOnDemand = true, bool applyWinRTProjections = false)\n\t\t{\n\t\t\treturn new MyAssemblyResolver(this, AssemblyList.GetSnapshot(), loadOnDemand, applyWinRTProjections);\n\t\t}\n\n\t\tinternal IAssemblyResolver GetAssemblyResolver(AssemblyListSnapshot snapshot,\n\t\t\tbool loadOnDemand = true, bool applyWinRTProjections = false)\n\t\t{\n\t\t\treturn new MyAssemblyResolver(this, snapshot, loadOnDemand, applyWinRTProjections);\n\t\t}\n\n\t\tprivate UniversalAssemblyResolver GetUniversalResolver(bool applyWinRTProjections)\n\t\t{\n\t\t\treturn LazyInitializer.EnsureInitialized(ref this.universalResolver, () => {\n\t\t\t\tvar targetFramework = this.GetTargetFrameworkIdAsync().GetAwaiter().GetResult();\n\t\t\t\tvar runtimePack = this.GetRuntimePackAsync().GetAwaiter().GetResult();\n\n\t\t\t\tvar readerOptions = applyWinRTProjections\n\t\t\t\t\t? MetadataReaderOptions.ApplyWindowsRuntimeProjections\n\t\t\t\t\t: MetadataReaderOptions.None;\n\n\t\t\t\tvar rootedPath = Path.IsPathRooted(this.FileName) ? this.FileName : null;\n\n\t\t\t\treturn new UniversalAssemblyResolver(rootedPath, throwOnError: false, targetFramework,\n\t\t\t\t\truntimePack, PEStreamOptions.PrefetchEntireImage, readerOptions);\n\t\t\t})!;\n\t\t}\n\n\t\tpublic AssemblyReferenceClassifier GetAssemblyReferenceClassifier(bool applyWinRTProjections)\n\t\t{\n\t\t\treturn GetUniversalResolver(applyWinRTProjections);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the debug info for this assembly. Returns null in case of load errors or no debug info is available.\n\t\t/// </summary>\n\t\tpublic IDebugInfoProvider? GetDebugInfoOrNull()\n\t\t{\n\t\t\tif (GetMetadataFileOrNull() == null)\n\t\t\t\treturn null;\n\t\t\treturn debugInfoProvider;\n\t\t}\n\n\t\tUniversalAssemblyResolver? universalResolver;\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/LoadedAssemblyExtensions.cs",
    "content": "using System;\nusing System.IO;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.DebugInfo;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX\n{\n\tpublic static class LoadedAssemblyExtensions\n\t{\n\t\t/// <summary>\n\t\t/// This method creates a Cecil object model from a PEFile. It is intended as helper method for plugins.\n\t\t/// Note that this method is expensive and creates high memory pressure!\n\t\t/// Note that accessing the Cecil objects created by this method after an assembly has been unloaded by ILSpy\n\t\t/// might lead to <see cref=\"AccessViolationException\"/> or similar.\n\t\t/// </summary>\n\t\t/// <remarks>Use only as last resort if there is something missing in the official ILSpy API.\n\t\t/// Consider creating an issue at https://github.com/icsharpcode/ILSpy/issues/new\n\t\t/// and discussing the problem with us.</remarks>\n\t\tpublic unsafe static Mono.Cecil.ModuleDefinition CreateCecilObjectModel(this PEFile file)\n\t\t{\n\t\t\tif (!file.Reader.IsEntireImageAvailable)\n\t\t\t\tthrow new InvalidOperationException(\"Need full image to create Cecil object model!\");\n\t\t\tvar image = file.Reader.GetEntireImage();\n\t\t\treturn Mono.Cecil.ModuleDefinition.ReadModule(new UnmanagedMemoryStream(image.Pointer, image.Length));\n\t\t}\n\n\t\tpublic static IAssemblyResolver GetAssemblyResolver(this MetadataFile file, bool loadOnDemand = true)\n\t\t{\n\t\t\treturn GetLoadedAssembly(file).GetAssemblyResolver(loadOnDemand);\n\t\t}\n\n\t\tinternal static IAssemblyResolver GetAssemblyResolver(this MetadataFile file, AssemblyListSnapshot snapshot, bool loadOnDemand = true)\n\t\t{\n\t\t\treturn GetLoadedAssembly(file).GetAssemblyResolver(snapshot, loadOnDemand);\n\t\t}\n\n\t\tpublic static IDebugInfoProvider? GetDebugInfoOrNull(this MetadataFile file)\n\t\t{\n\t\t\treturn GetLoadedAssembly(file).GetDebugInfoOrNull();\n\t\t}\n\n\t\tpublic static ICompilation? GetTypeSystemOrNull(this MetadataFile file)\n\t\t{\n\t\t\treturn GetLoadedAssembly(file).GetTypeSystemOrNull();\n\t\t}\n\n\t\tpublic static ICompilation? GetTypeSystemWithDecompilerSettingsOrNull(this MetadataFile file, DecompilerSettings settings)\n\t\t{\n\t\t\treturn GetLoadedAssembly(file).GetTypeSystemOrNull(DecompilerTypeSystem.GetOptions(settings));\n\t\t}\n\n\t\tpublic static LoadedAssembly GetLoadedAssembly(this MetadataFile file)\n\t\t{\n\t\t\tif (file == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(file));\n\t\t\tLoadedAssembly? loadedAssembly;\n\t\t\tlock (LoadedAssembly.loadedAssemblies)\n\t\t\t{\n\t\t\t\tif (!LoadedAssembly.loadedAssemblies.TryGetValue(file, out loadedAssembly))\n\t\t\t\t\tthrow new ArgumentException(\"The specified file is not associated with a LoadedAssembly!\");\n\t\t\t}\n\t\t\treturn loadedAssembly;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/LoadedPackage.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.IO.Compression;\nusing System.IO.MemoryMappedFiles;\nusing System.Linq;\nusing System.Reflection;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpyX\n{\n\t/// <summary>\n\t/// NuGet package or .NET bundle:\n\t/// </summary>\n\tpublic class LoadedPackage\n\t{\n\t\tpublic enum PackageKind\n\t\t{\n\t\t\tZip,\n\t\t\tBundle,\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the LoadedAssembly instance representing this bundle.\n\t\t/// </summary>\n\t\tinternal LoadedAssembly? LoadedAssembly { get; set; }\n\n\t\tpublic PackageKind Kind { get; }\n\n\t\tpublic SingleFileBundle.Header BundleHeader { get; set; }\n\n\t\t/// <summary>\n\t\t/// List of all entries, including those in sub-directories within the package.\n\t\t/// </summary>\n\t\tpublic IReadOnlyList<PackageEntry> Entries { get; }\n\n\t\tpublic PackageFolder RootFolder { get; }\n\n\t\tpublic LoadedPackage(PackageKind kind, IEnumerable<PackageEntry> entries)\n\t\t{\n\t\t\tthis.Kind = kind;\n\t\t\tthis.Entries = entries.ToArray();\n\t\t\tvar topLevelEntries = new List<PackageEntry>();\n\t\t\tvar folders = new Dictionary<string, PackageFolder>();\n\t\t\tvar rootFolder = new PackageFolder(this, null, \"\");\n\t\t\tfolders.Add(\"\", rootFolder);\n\t\t\tforeach (var entry in this.Entries)\n\t\t\t{\n\t\t\t\tvar (dirname, filename) = SplitName(entry.Name);\n\t\t\t\tif (!string.IsNullOrEmpty(filename))\n\t\t\t\t{\n\t\t\t\t\tGetFolder(dirname).Entries.Add(new FolderEntry(filename, entry));\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.RootFolder = rootFolder;\n\n\t\t\tstatic (string, string) SplitName(string filename)\n\t\t\t{\n\t\t\t\tint pos = filename.LastIndexOfAny(new char[] { '/', '\\\\' });\n\t\t\t\tif (pos == -1)\n\t\t\t\t\treturn (\"\", filename); // file in root\n\t\t\t\telse\n\t\t\t\t\treturn (filename.Substring(0, pos), filename.Substring(pos + 1));\n\t\t\t}\n\n\t\t\tPackageFolder GetFolder(string name)\n\t\t\t{\n\t\t\t\tif (folders.TryGetValue(name, out var result))\n\t\t\t\t\treturn result;\n\t\t\t\tvar (dirname, basename) = SplitName(name);\n\t\t\t\tPackageFolder parent = GetFolder(dirname);\n\t\t\t\tresult = new PackageFolder(this, parent, basename);\n\t\t\t\tparent.Folders.Add(result);\n\t\t\t\tfolders.Add(name, result);\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\n\t\tpublic static LoadedPackage FromZipFile(string file)\n\t\t{\n\t\t\tDebug.WriteLine($\"LoadedPackage.FromZipFile({file})\");\n\t\t\tusing var archive = ZipFile.OpenRead(file);\n\t\t\treturn new LoadedPackage(PackageKind.Zip,\n\t\t\t\tarchive.Entries.Select(entry => new ZipFileEntry(file, entry)));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Load a .NET single-file bundle.\n\t\t/// </summary>\n\t\tpublic static LoadedPackage? FromBundle(string fileName)\n\t\t{\n\t\t\tusing var memoryMappedFile = MemoryMappedFile.CreateFromFile(fileName, FileMode.Open, null, 0, MemoryMappedFileAccess.Read);\n\t\t\tvar view = memoryMappedFile.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read);\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (!SingleFileBundle.IsBundle(view, out long bundleHeaderOffset))\n\t\t\t\t\treturn null;\n\t\t\t\tvar manifest = SingleFileBundle.ReadManifest(view, bundleHeaderOffset);\n\t\t\t\tvar entries = manifest.Entries.Select(e => new BundleEntry(fileName, view, e)).ToList();\n\t\t\t\tvar result = new LoadedPackage(PackageKind.Bundle, entries);\n\t\t\t\tresult.BundleHeader = manifest;\n\t\t\t\tview = null; // don't dispose the view, we're still using it in the bundle entries\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\tcatch (InvalidDataException)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tview?.Dispose();\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Entry inside a package folder. Effectively renames the entry.\n\t\t/// </summary>\n\t\tsealed class FolderEntry : PackageEntry\n\t\t{\n\t\t\treadonly PackageEntry originalEntry;\n\t\t\tpublic override string Name { get; }\n\t\t\tpublic override string FullName => originalEntry.Name;\n\n\t\t\tpublic FolderEntry(string name, PackageEntry originalEntry)\n\t\t\t{\n\t\t\t\tthis.Name = name;\n\t\t\t\tthis.originalEntry = originalEntry;\n\t\t\t}\n\n\t\t\tpublic override ManifestResourceAttributes Attributes => originalEntry.Attributes;\n\t\t\tpublic override string PackageQualifiedFileName => originalEntry.PackageQualifiedFileName;\n\t\t\tpublic override ResourceType ResourceType => originalEntry.ResourceType;\n\t\t\tpublic override Stream? TryOpenStream() => originalEntry.TryOpenStream();\n\t\t\tpublic override long? TryGetLength() => originalEntry.TryGetLength();\n\t\t}\n\n\t\tsealed class ZipFileEntry : PackageEntry\n\t\t{\n\t\t\treadonly string zipFile;\n\t\t\tpublic override string Name { get; }\n\t\t\tpublic override string PackageQualifiedFileName => $\"zip://{zipFile};{Name}\";\n\n\t\t\tpublic override string FullName => Name;\n\n\t\t\tpublic ZipFileEntry(string zipFile, ZipArchiveEntry entry)\n\t\t\t{\n\t\t\t\tthis.zipFile = zipFile;\n\t\t\t\tthis.Name = entry.FullName;\n\t\t\t}\n\n\t\t\tpublic override Stream? TryOpenStream()\n\t\t\t{\n\t\t\t\tDebug.WriteLine(\"Decompress \" + Name);\n\t\t\t\tusing var archive = ZipFile.OpenRead(zipFile);\n\t\t\t\tvar entry = archive.GetEntry(Name);\n\t\t\t\tif (entry == null)\n\t\t\t\t\treturn null;\n\t\t\t\tvar memoryStream = new MemoryStream();\n\t\t\t\tusing (var s = entry.Open())\n\t\t\t\t{\n\t\t\t\t\ts.CopyTo(memoryStream);\n\t\t\t\t}\n\t\t\t\tmemoryStream.Position = 0;\n\t\t\t\treturn memoryStream;\n\t\t\t}\n\n\t\t\tpublic override long? TryGetLength()\n\t\t\t{\n\t\t\t\tDebug.WriteLine(\"TryGetLength \" + Name);\n\t\t\t\tusing var archive = ZipFile.OpenRead(zipFile);\n\t\t\t\tvar entry = archive.GetEntry(Name);\n\t\t\t\tif (entry == null)\n\t\t\t\t\treturn null;\n\t\t\t\treturn entry.Length;\n\t\t\t}\n\t\t}\n\n\t\tsealed class BundleEntry : PackageEntry\n\t\t{\n\t\t\treadonly string bundleFile;\n\t\t\treadonly MemoryMappedViewAccessor view;\n\t\t\treadonly SingleFileBundle.Entry entry;\n\n\t\t\tpublic BundleEntry(string bundleFile, MemoryMappedViewAccessor view, SingleFileBundle.Entry entry)\n\t\t\t{\n\t\t\t\tthis.bundleFile = bundleFile;\n\t\t\t\tthis.view = view;\n\t\t\t\tthis.entry = entry;\n\t\t\t}\n\n\t\t\tpublic override string Name => entry.RelativePath;\n\t\t\tpublic override string FullName => Name;\n\t\t\tpublic override string PackageQualifiedFileName => $\"bundle://{bundleFile};{Name}\";\n\n\t\t\tpublic override Stream TryOpenStream()\n\t\t\t{\n\t\t\t\tDebug.WriteLine(\"Open bundle member \" + Name);\n\n\t\t\t\tif (entry.CompressedSize == 0)\n\t\t\t\t{\n\t\t\t\t\treturn new UnmanagedMemoryStream(view.SafeMemoryMappedViewHandle, entry.Offset, entry.Size);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tStream compressedStream = new UnmanagedMemoryStream(view.SafeMemoryMappedViewHandle, entry.Offset, entry.CompressedSize);\n\t\t\t\t\tusing var deflateStream = new DeflateStream(compressedStream, CompressionMode.Decompress);\n\t\t\t\t\tStream decompressedStream = new MemoryStream((int)entry.Size);\n\t\t\t\t\tdeflateStream.CopyTo(decompressedStream);\n\t\t\t\t\tif (decompressedStream.Length != entry.Size)\n\t\t\t\t\t{\n\t\t\t\t\t\tthrow new InvalidDataException($\"Corrupted single-file entry '{entry.RelativePath}'. Declared decompressed size '{entry.Size}' is not the same as actual decompressed size '{decompressedStream.Length}'.\");\n\t\t\t\t\t}\n\n\t\t\t\t\tdecompressedStream.Seek(0, SeekOrigin.Begin);\n\t\t\t\t\treturn decompressedStream;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override long? TryGetLength()\n\t\t\t{\n\t\t\t\treturn entry.Size;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic abstract class PackageEntry : Resource\n\t{\n\t\t/// <summary>\n\t\t/// Gets the file name of the entry (may include path components, relative to the package root).\n\t\t/// </summary>\n\t\tpublic abstract override string Name { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the full file name including the full file name of the package (prefixed with e.g., bundle:// or zip://).\n\t\t/// </summary>\n\t\tpublic abstract string PackageQualifiedFileName { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the full name of the file name relative to the package root.\n\t\t/// </summary>\n\t\tpublic abstract string FullName { get; }\n\t}\n\n\tpublic sealed class PackageFolder : IAssemblyResolver\n\t{\n\t\t/// <summary>\n\t\t/// Gets the short name of the folder.\n\t\t/// </summary>\n\t\tpublic string Name { get; }\n\n\t\treadonly LoadedPackage package;\n\t\treadonly PackageFolder? parent;\n\n\t\tinternal PackageFolder(LoadedPackage package, PackageFolder? parent, string name)\n\t\t{\n\t\t\tthis.package = package;\n\t\t\tthis.parent = parent;\n\t\t\tthis.Name = name;\n\t\t}\n\n\t\tpublic PackageFolder? Parent => parent;\n\t\tpublic List<PackageFolder> Folders { get; } = new List<PackageFolder>();\n\t\tpublic List<PackageEntry> Entries { get; } = new List<PackageEntry>();\n\n\t\tpublic MetadataFile? Resolve(IAssemblyReference reference)\n\t\t{\n\t\t\tvar asm = ResolveFileName(reference.Name + \".dll\");\n\t\t\tif (asm != null)\n\t\t\t{\n\t\t\t\treturn asm.GetMetadataFileOrNull();\n\t\t\t}\n\t\t\treturn parent?.Resolve(reference);\n\t\t}\n\n\t\tpublic Task<MetadataFile?> ResolveAsync(IAssemblyReference reference)\n\t\t{\n\t\t\tvar asm = ResolveFileName(reference.Name + \".dll\");\n\t\t\tif (asm != null)\n\t\t\t{\n\t\t\t\treturn asm.GetMetadataFileOrNullAsync();\n\t\t\t}\n\t\t\tif (parent != null)\n\t\t\t{\n\t\t\t\treturn parent.ResolveAsync(reference);\n\t\t\t}\n\t\t\treturn Task.FromResult<MetadataFile?>(null);\n\t\t}\n\n\t\tpublic MetadataFile? ResolveModule(MetadataFile mainModule, string moduleName)\n\t\t{\n\t\t\tvar asm = ResolveFileName(moduleName + \".dll\");\n\t\t\tif (asm != null)\n\t\t\t{\n\t\t\t\treturn asm.GetMetadataFileOrNull();\n\t\t\t}\n\t\t\treturn parent?.ResolveModule(mainModule, moduleName);\n\t\t}\n\n\t\tpublic Task<MetadataFile?> ResolveModuleAsync(MetadataFile mainModule, string moduleName)\n\t\t{\n\t\t\tvar asm = ResolveFileName(moduleName + \".dll\");\n\t\t\tif (asm != null)\n\t\t\t{\n\t\t\t\treturn asm.GetMetadataFileOrNullAsync();\n\t\t\t}\n\t\t\tif (parent != null)\n\t\t\t{\n\t\t\t\treturn parent.ResolveModuleAsync(mainModule, moduleName);\n\t\t\t}\n\t\t\treturn Task.FromResult<MetadataFile?>(null);\n\t\t}\n\n\t\treadonly Dictionary<string, LoadedAssembly?> assemblies = new Dictionary<string, LoadedAssembly?>(StringComparer.OrdinalIgnoreCase);\n\n\t\tpublic LoadedAssembly? ResolveFileName(string name)\n\t\t{\n\t\t\tif (package.LoadedAssembly == null)\n\t\t\t\treturn null;\n\t\t\tlock (assemblies)\n\t\t\t{\n\t\t\t\tif (assemblies.TryGetValue(name, out var asm))\n\t\t\t\t\treturn asm;\n\t\t\t\tvar entry = Entries.FirstOrDefault(e => string.Equals(name, e.Name, StringComparison.OrdinalIgnoreCase));\n\t\t\t\tif (entry != null)\n\t\t\t\t{\n\t\t\t\t\tasm = new LoadedAssembly(\n\t\t\t\t\t\tpackage.LoadedAssembly, entry.Name,\n\t\t\t\t\t\tfileLoaders: package.LoadedAssembly.AssemblyList.LoaderRegistry,\n\t\t\t\t\t\tassemblyResolver: this,\n\t\t\t\t\t\tstream: Task.Run(entry.TryOpenStream),\n\t\t\t\t\t\tapplyWinRTProjections: package.LoadedAssembly.AssemblyList.ApplyWinRTProjections,\n\t\t\t\t\t\tuseDebugSymbols: package.LoadedAssembly.AssemblyList.UseDebugSymbols\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tasm = null;\n\t\t\t\t}\n\t\t\t\tassemblies.Add(name, asm);\n\t\t\t\treturn asm;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/ClassDiagrammer.cs",
    "content": "// Copyright (c) 2024 Holger Schmidt\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.MermaidDiagrammer\n{\n\t/// <summary>Contains type info and metadata for generating a HTML class diagrammer from a source assembly.\n\t/// Serialized into JSON by <see cref=\"GenerateHtmlDiagrammer.SerializeModel(ClassDiagrammer)\"/>.</summary>\n\tpublic sealed class ClassDiagrammer\n\t{\n\t\tinternal const string NewLine = \"\\n\";\n\n\t\tinternal string SourceAssemblyName { get; set; } = null!;\n\t\tinternal string SourceAssemblyVersion { get; set; } = null!;\n\n\t\t/// <summary>Types selectable in the diagrammer, grouped by their\n\t\t/// <see cref=\"System.Type.Namespace\"/> to facilitate a structured type selection.</summary>\n\t\tinternal Dictionary<string, Type[]> TypesByNamespace { get; set; } = null!;\n\n\t\t/// <summary>Types not included in the <see cref=\"ClassDiagrammer\"/>,\n\t\t/// but referenced by <see cref=\"Type\"/>s that are.\n\t\t/// Contains display names (values; similar to <see cref=\"Type.Name\"/>)\n\t\t/// by their referenced IDs (keys; similar to <see cref=\"Type.Id\"/>).</summary>\n\t\tinternal Dictionary<string, string> OutsideReferences { get; set; } = null!;\n\n\t\t/// <summary>Types excluded from the <see cref=\"ClassDiagrammer\"/>;\n\t\t/// used to support <see cref=\"GenerateHtmlDiagrammer.ReportExludedTypes\"/>.</summary>\n\t\tinternal string[] Excluded { get; set; } = null!;\n\n\t\t/// <summary>A <see cref=\"Type\"/>-like structure with collections\n\t\t/// of property relations to one or many other <see cref=\"Type\"/>s.</summary>\n\t\tpublic abstract class Relationships\n\t\t{\n\t\t\t/// <summary>Relations to zero or one other instances of <see cref=\"Type\"/>s included in the <see cref=\"ClassDiagrammer\"/>,\n\t\t\t/// with the display member names as keys and the related <see cref=\"Type.Id\"/> as values.\n\t\t\t/// This is because member names must be unique within the owning <see cref=\"Type\"/>,\n\t\t\t/// while the related <see cref=\"Type\"/> may be the same for multiple properties.</summary>\n\t\t\tpublic Dictionary<string, string>? HasOne { get; set; }\n\n\t\t\t/// <summary>Relations to zero to infinite other instances of <see cref=\"Type\"/>s included in the <see cref=\"ClassDiagrammer\"/>,\n\t\t\t/// with the display member names as keys and the related <see cref=\"Type.Id\"/> as values.\n\t\t\t/// This is because member names must be unique within the owning <see cref=\"Type\"/>,\n\t\t\t/// while the related <see cref=\"Type\"/> may be the same for multiple properties.</summary>\n\t\t\tpublic Dictionary<string, string>? HasMany { get; set; }\n\t\t}\n\n\t\t/// <summary>The mermaid class diagram definition, inheritance and relationships metadata\n\t\t/// and XML documentation for a <see cref=\"System.Type\"/> from the source assembly.</summary>\n\t\tpublic sealed class Type : Relationships\n\t\t{\n\t\t\t/// <summary>Uniquely identifies the <see cref=\"System.Type\"/> in the scope of the source assembly\n\t\t\t/// as well as any HTML diagrammer generated from it.\n\t\t\t/// Should match \\w+ to be safe to use as select option value and\n\t\t\t/// part of the DOM id of the SVG node rendered for this type.\n\t\t\t/// May be the type name itself.</summary>\n\t\t\tinternal string Id { get; set; } = null!;\n\n\t\t\t/// <summary>The human-readable label for the type, if different from <see cref=\"Id\"/>.\n\t\t\t/// Not guaranteed to be unique in the scope of the <see cref=\"ClassDiagrammer\"/>.</summary>\n\t\t\tpublic string? Name { get; set; }\n\n\t\t\t/// <summary>Contains the definition of the type and its own (not inherited) flat members\n\t\t\t/// in mermaid class diagram syntax, see https://mermaid.js.org/syntax/classDiagram.html .</summary>\n\t\t\tpublic string Body { get; set; } = null!;\n\n\t\t\t/// <summary>The base type directly implemented by this type, with the <see cref=\"Id\"/> as key\n\t\t\t/// and the (optional) differing display name as value of the single entry\n\t\t\t/// - or null if the base type is <see cref=\"object\"/>.\n\t\t\t/// Yes, Christopher Lambert, there can only be one. For now.\n\t\t\t/// But using the same interface as for <see cref=\"Interfaces\"/> is convenient\n\t\t\t/// and who knows - at some point the .Net bus may roll up with multi-inheritance.\n\t\t\t/// Then this'll look visionary!</summary>\n\t\t\tpublic Dictionary<string, string?>? BaseType { get; set; }\n\n\t\t\t/// <summary>Interfaces directly implemented by this type, with their <see cref=\"Id\"/> as keys\n\t\t\t/// and their (optional) differing display names as values.</summary>\n\t\t\tpublic Dictionary<string, string?[]>? Interfaces { get; set; }\n\n\t\t\t/// <summary>Contains inherited members by the <see cref=\"Id\"/> of their <see cref=\"IMember.DeclaringType\"/>\n\t\t\t/// for the consumer to choose which of them to display in an inheritance scenario.</summary>\n\t\t\tpublic IDictionary<string, InheritedMembers>? Inherited { get; set; }\n\n\t\t\t/// <summary>Contains the XML documentation comments for this type\n\t\t\t/// (using a <see cref=\"string.Empty\"/> key) and its members, if available.</summary>\n\t\t\tpublic IDictionary<string, string>? XmlDocs { get; set; }\n\n\t\t\t/// <summary>Members inherited from an ancestor type specified by the Key of <see cref=\"Inherited\"/>.</summary>\n\t\t\tpublic class InheritedMembers : Relationships\n\t\t\t{\n\t\t\t\t/// <summary>The simple, non-complex members inherited from another <see cref=\"Type\"/>\n\t\t\t\t/// in mermaid class diagram syntax.</summary>\n\t\t\t\tpublic string? FlatMembers { get; set; }\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/ClassDiagrammerFactory.cs",
    "content": "// Copyright (c) 2024 Holger Schmidt\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text.RegularExpressions;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.MermaidDiagrammer\n{\n\tusing CD = ClassDiagrammer;\n\n\t/* See class diagram syntax\n\t * reference (may be outdated!) https://mermaid.js.org/syntax/classDiagram.html\n\t * lexical definition https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/diagrams/class/parser/classDiagram.jison */\n\n\t/// <summary>Produces mermaid class diagram syntax for a filtered list of types from a specified .Net assembly.</summary>\n\tpublic partial class ClassDiagrammerFactory\n\t{\n\t\tprivate readonly XmlDocumentationFormatter? xmlDocs;\n\t\tprivate readonly DecompilerSettings decompilerSettings;\n\n\t\tprivate ITypeDefinition[]? selectedTypes;\n\t\tprivate Dictionary<IType, string>? uniqueIds;\n\t\tprivate Dictionary<IType, string>? labels;\n\t\tprivate Dictionary<string, string>? outsideReferences;\n\n\t\tpublic ClassDiagrammerFactory(XmlDocumentationFormatter? xmlDocs)\n\t\t{\n\t\t\tthis.xmlDocs = xmlDocs;\n\n\t\t\t//TODO not sure LanguageVersion.Latest is the wisest choice here; maybe cap this for better mermaid compatibility?\n\t\t\tdecompilerSettings = new DecompilerSettings(Decompiler.CSharp.LanguageVersion.Latest) {\n\t\t\t\tAutomaticProperties = true // for IsHidden to return true for backing fields\n\t\t\t};\n\t\t}\n\n\t\tpublic CD BuildModel(string assemblyPath, string? include, string? exclude)\n\t\t{\n\t\t\tCSharpDecompiler decompiler = new(assemblyPath, decompilerSettings);\n\t\t\tMetadataModule mainModule = decompiler.TypeSystem.MainModule;\n\t\t\tIEnumerable<ITypeDefinition> allTypes = mainModule.TypeDefinitions;\n\n\t\t\tselectedTypes = FilterTypes(allTypes,\n\t\t\t\tinclude == null ? null : new Regex(include, RegexOptions.Compiled),\n\t\t\t\texclude == null ? null : new Regex(exclude, RegexOptions.Compiled)).ToArray();\n\n\t\t\t// generate dictionary to read names from later\n\t\t\tuniqueIds = GenerateUniqueIds(selectedTypes);\n\t\t\tlabels = [];\n\t\t\toutsideReferences = [];\n\n\t\t\tDictionary<string, CD.Type[]> typesByNamespace = selectedTypes.GroupBy(t => t.Namespace).OrderBy(g => g.Key).ToDictionary(g => g.Key,\n\t\t\t\tns => ns.OrderBy(t => t.FullName).Select(type => type.Kind == TypeKind.Enum ? BuildEnum(type) : BuildType(type)).ToArray());\n\n\t\t\tstring[] excluded = allTypes.Except(selectedTypes).Select(t => t.ReflectionName).ToArray();\n\n\t\t\treturn new CD {\n\t\t\t\tSourceAssemblyName = mainModule.AssemblyName,\n\t\t\t\tSourceAssemblyVersion = mainModule.AssemblyVersion.ToString(),\n\t\t\t\tTypesByNamespace = typesByNamespace,\n\t\t\t\tOutsideReferences = outsideReferences,\n\t\t\t\tExcluded = excluded\n\t\t\t};\n\t\t}\n\n\t\t/// <summary>The default strategy for pre-filtering the <paramref name=\"typeDefinitions\"/> available in the HTML diagrammer.\n\t\t/// Applies <see cref=\"IsIncludedByDefault(ITypeDefinition)\"/> as well as\n\t\t/// matching by <paramref name=\"include\"/> and not by <paramref name=\"exclude\"/>.</summary>\n\t\t/// <returns>The types to effectively include in the HTML diagrammer.</returns>\n\t\tprotected virtual IEnumerable<ITypeDefinition> FilterTypes(IEnumerable<ITypeDefinition> typeDefinitions, Regex? include, Regex? exclude)\n\t\t\t=> typeDefinitions.Where(type => IsIncludedByDefault(type)\n\t\t\t\t&& (include?.IsMatch(type.ReflectionName) != false) // applying optional whitelist filter\n\t\t\t\t&& (exclude?.IsMatch(type.ReflectionName) != true)); // applying optional blacklist filter\n\n\t\t/// <summary>The strategy for deciding whether a <paramref name=\"type\"/> should be included\n\t\t/// in the HTML diagrammer by default. Excludes compiler-generated and their nested types.</summary>\n\t\tprotected virtual bool IsIncludedByDefault(ITypeDefinition type)\n\t\t\t=> !type.IsCompilerGeneratedOrIsInCompilerGeneratedClass();\n\t}\n}"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/EmbeddedResource.cs",
    "content": "// Copyright (c) 2024 Holger Schmidt\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.IO;\n\nnamespace ICSharpCode.ILSpyX.MermaidDiagrammer\n{\n\tpublic partial class GenerateHtmlDiagrammer\n\t{\n\t\t/// <summary>A helper for loading resources embedded in the nested html folder.</summary>\n\t\tprivate static class EmbeddedResource\n\t\t{\n\t\t\tinternal static string ReadText(string resourceName)\n\t\t\t{\n\t\t\t\tStream stream = GetStream(resourceName);\n\t\t\t\tusing StreamReader reader = new(stream);\n\t\t\t\treturn reader.ReadToEnd();\n\t\t\t}\n\n\t\t\tinternal static void CopyTo(string outputFolder, string resourceName)\n\t\t\t{\n\t\t\t\tStream resourceStream = GetStream(resourceName);\n\t\t\t\tusing FileStream output = new(Path.Combine(outputFolder, resourceName), FileMode.Create, FileAccess.Write);\n\t\t\t\tresourceStream.CopyTo(output);\n\t\t\t}\n\n\t\t\tprivate static Stream GetStream(string resourceName)\n\t\t\t{\n\t\t\t\tvar type = typeof(EmbeddedResource);\n\t\t\t\tvar assembly = type.Assembly;\n\t\t\t\tvar fullResourceName = $\"{type.Namespace}.html.{resourceName}\";\n\t\t\t\tStream? stream = assembly.GetManifestResourceStream(fullResourceName);\n\n\t\t\t\tif (stream == null)\n\t\t\t\t\tthrow new FileNotFoundException(\"Resource not found.\", fullResourceName);\n\n\t\t\t\treturn stream;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/Extensions/StringExtensions.cs",
    "content": "// Copyright (c) 2024 Holger Schmidt\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text.RegularExpressions;\n\nnamespace ICSharpCode.ILSpyX.MermaidDiagrammer.Extensions\n{\n\tinternal static class StringExtensions\n\t{\n\t\t/// <summary>Replaces all consecutive horizontal white space characters in\n\t\t/// <paramref name=\"input\"/> with <paramref name=\"normalizeTo\"/> while leaving line breaks intact.</summary>\n\t\tinternal static string NormalizeHorizontalWhiteSpace(this string input, string normalizeTo = \" \")\n\t\t\t=> Regex.Replace(input, @\"[ \\t]+\", normalizeTo);\n\n\t\t/// <summary>Replaces all occurrences of <paramref name=\"oldValues\"/> in\n\t\t/// <paramref name=\"input\"/> with <paramref name=\"newValue\"/>.</summary>\n\t\tinternal static string ReplaceAll(this string input, IEnumerable<string> oldValues, string? newValue)\n\t\t\t=> oldValues.Aggregate(input, (aggregate, oldValue) => aggregate.Replace(oldValue, newValue));\n\n\t\t/// <summary>Joins the specified <paramref name=\"strings\"/> to a single one\n\t\t/// using the specified <paramref name=\"separator\"/> as a delimiter.</summary>\n\t\t/// <param name=\"pad\">Whether to pad the start and end of the string with the <paramref name=\"separator\"/> as well.</param>\n\t\tinternal static string Join(this IEnumerable<string?>? strings, string separator, bool pad = false)\n\t\t{\n\t\t\tif (strings == null)\n\t\t\t\treturn string.Empty;\n\n\t\t\tvar joined = string.Join(separator, strings);\n\t\t\treturn pad ? string.Concat(separator, joined, separator) : joined;\n\t\t}\n\n\t\t/// <summary>Formats all items in <paramref name=\"collection\"/> using the supplied <paramref name=\"format\"/> strategy\n\t\t/// and returns a string collection - even if the incoming <paramref name=\"collection\"/> is null.</summary>\n\t\tinternal static IEnumerable<string> FormatAll<T>(this IEnumerable<T>? collection, Func<T, string> format)\n\t\t\t=> collection?.Select(format) ?? [];\n\t}\n}"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/Extensions/TypeExtensions.cs",
    "content": "// Copyright (c) 2024 Holger Schmidt\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpyX.MermaidDiagrammer.Extensions\n{\n\tinternal static class TypeExtensions\n\t{\n\t\tinternal static bool IsObject(this IType t) => t.IsKnownType(KnownTypeCode.Object);\n\t\tinternal static bool IsInterface(this IType t) => t.Kind == TypeKind.Interface;\n\n\t\tinternal static bool TryGetNullableType(this IType type, [MaybeNullWhen(false)] out IType typeArg)\n\t\t{\n\t\t\tbool isNullable = type.IsKnownType(KnownTypeCode.NullableOfT);\n\t\t\ttypeArg = isNullable ? type.TypeArguments.Single() : null;\n\t\t\treturn isNullable;\n\t\t}\n\t}\n\n\tinternal static class MemberInfoExtensions\n\t{\n\t\t/// <summary>Groups the <paramref name=\"members\"/> into a dictionary\n\t\t/// with <see cref=\"IMember.DeclaringType\"/> keys.</summary>\n\t\tinternal static Dictionary<IType, T[]> GroupByDeclaringType<T>(this IEnumerable<T> members) where T : IMember\n\t\t\t=> members.GroupByDeclaringType(m => m);\n\n\t\t/// <summary>Groups the <paramref name=\"objectsWithMembers\"/> into a dictionary\n\t\t/// with <see cref=\"IMember.DeclaringType\"/> keys using <paramref name=\"getMember\"/>.</summary>\n\t\tinternal static Dictionary<IType, T[]> GroupByDeclaringType<T>(this IEnumerable<T> objectsWithMembers, Func<T, IMember> getMember)\n\t\t\t=> objectsWithMembers.GroupBy(m => getMember(m).DeclaringType).ToDictionary(g => g.Key, g => g.ToArray());\n\t}\n\n\tinternal static class DictionaryExtensions\n\t{\n\t\t/// <summary>Returns the <paramref name=\"dictionary\"/>s value for the specified <paramref name=\"key\"/>\n\t\t/// if available and otherwise the default for <typeparamref name=\"Tout\"/>.</summary>\n\t\tinternal static Tout? GetValue<T, Tout>(this IDictionary<T, Tout> dictionary, T key)\n\t\t\t=> dictionary.TryGetValue(key, out Tout? value) ? value : default;\n\t}\n}"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/Factory.BuildTypes.cs",
    "content": "// Copyright (c) 2024 Holger Schmidt\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX.MermaidDiagrammer.Extensions;\n\nnamespace ICSharpCode.ILSpyX.MermaidDiagrammer\n{\n\tusing CD = ClassDiagrammer;\n\n\tpartial class ClassDiagrammerFactory\n\t{\n\t\tprivate CD.Type BuildEnum(ITypeDefinition type)\n\t\t{\n\t\t\tIField[] fields = type.GetFields(f => f.IsConst && f.IsStatic && f.Accessibility == Accessibility.Public).ToArray();\n\t\t\tDictionary<string, string>? docs = xmlDocs?.GetXmlDocs(type, fields);\n\t\t\tstring name = GetName(type), typeId = GetId(type);\n\n\t\t\tvar body = fields.Select(f => f.Name).Prepend(\"<<Enumeration>>\")\n\t\t\t\t.Join(CD.NewLine + \"    \", pad: true).TrimEnd(' ');\n\n\t\t\treturn new CD.Type {\n\t\t\t\tId = typeId,\n\t\t\t\tName = name == typeId ? null : name,\n\t\t\t\tBody = $\"class {typeId} {{{body}}}\",\n\t\t\t\tXmlDocs = docs\n\t\t\t};\n\t\t}\n\n\t\tprivate CD.Type BuildType(ITypeDefinition type)\n\t\t{\n\t\t\tstring typeId = GetId(type);\n\t\t\tIMethod[] methods = GetMethods(type).ToArray();\n\t\t\tIProperty[] properties = type.GetProperties().ToArray();\n\t\t\tIProperty[] hasOneRelations = GetHasOneRelations(properties);\n\t\t\t(IProperty property, IType elementType)[] hasManyRelations = GetManyRelations(properties);\n\n\t\t\tvar propertyNames = properties.Select(p => p.Name).ToArray();\n\t\t\tIField[] fields = GetFields(type, properties);\n\n\t\t\t#region split members up by declaring type\n\t\t\t// enables the diagrammer to exclude inherited members from derived types if they are already rendered in a base type\n\t\t\tDictionary<IType, IProperty[]> flatPropertiesByType = properties.Except(hasOneRelations)\n\t\t\t\t.Except(hasManyRelations.Select(r => r.property)).GroupByDeclaringType();\n\n\t\t\tDictionary<IType, IProperty[]> hasOneRelationsByType = hasOneRelations.GroupByDeclaringType();\n\t\t\tDictionary<IType, (IProperty property, IType elementType)[]> hasManyRelationsByType = hasManyRelations.GroupByDeclaringType(r => r.property);\n\t\t\tDictionary<IType, IField[]> fieldsByType = fields.GroupByDeclaringType();\n\t\t\tDictionary<IType, IMethod[]> methodsByType = methods.GroupByDeclaringType();\n\t\t\t#endregion\n\n\t\t\t#region build diagram definitions for the type itself and members declared by it\n\t\t\tstring members = flatPropertiesByType.GetValue(type).FormatAll(FormatFlatProperty)\n\t\t\t\t.Concat(methodsByType.GetValue(type).FormatAll(FormatMethod))\n\t\t\t\t.Concat(fieldsByType.GetValue(type).FormatAll(FormatField))\n\t\t\t\t.Join(CD.NewLine + \"    \", pad: true);\n\n\t\t\t// see https://mermaid.js.org/syntax/classDiagram.html#annotations-on-classes\n\t\t\tstring? annotation = type.IsInterface() ? \"Interface\" : type.IsAbstract ? type.IsSealed ? \"Service\" : \"Abstract\" : null;\n\n\t\t\tstring body = annotation == null ? members.TrimEnd(' ') : members + $\"<<{annotation}>>\" + CD.NewLine;\n\t\t\t#endregion\n\n\t\t\tDictionary<string, string>? docs = xmlDocs?.GetXmlDocs(type, fields, properties, methods);\n\n\t\t\t#region build diagram definitions for inherited members by declaring type\n\t\t\tstring explicitTypePrefix = typeId + \" : \";\n\n\t\t\t// get ancestor types this one is inheriting members from\n\t\t\tDictionary<string, CD.Type.InheritedMembers> inheritedMembersByType = type.GetNonInterfaceBaseTypes().Where(t => t != type && !t.IsObject())\n\t\t\t\t// and group inherited members by declaring type\n\t\t\t\t.ToDictionary(GetId, t => {\n\t\t\t\t\tIEnumerable<string> flatMembers = flatPropertiesByType.GetValue(t).FormatAll(p => explicitTypePrefix + FormatFlatProperty(p))\n\t\t\t\t\t\t.Concat(methodsByType.GetValue(t).FormatAll(m => explicitTypePrefix + FormatMethod(m)))\n\t\t\t\t\t\t.Concat(fieldsByType.GetValue(t).FormatAll(f => explicitTypePrefix + FormatField(f)));\n\n\t\t\t\t\treturn new CD.Type.InheritedMembers {\n\t\t\t\t\t\tFlatMembers = flatMembers.Any() ? flatMembers.Join(CD.NewLine) : null,\n\t\t\t\t\t\tHasOne = MapHasOneRelations(hasOneRelationsByType, t),\n\t\t\t\t\t\tHasMany = MapHasManyRelations(hasManyRelationsByType, t)\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t#endregion\n\n\t\t\tstring typeName = GetName(type);\n\n\t\t\treturn new CD.Type {\n\t\t\t\tId = typeId,\n\t\t\t\tName = typeName == typeId ? null : typeName,\n\t\t\t\tBody = $\"class {typeId} {{{body}}}\",\n\t\t\t\tHasOne = MapHasOneRelations(hasOneRelationsByType, type),\n\t\t\t\tHasMany = MapHasManyRelations(hasManyRelationsByType, type),\n\t\t\t\tBaseType = GetBaseType(type),\n\t\t\t\tInterfaces = GetInterfaces(type),\n\t\t\t\tInherited = inheritedMembersByType,\n\t\t\t\tXmlDocs = docs\n\t\t\t};\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/Factory.FlatMembers.cs",
    "content": "// Copyright (c) 2024 Holger Schmidt\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text.RegularExpressions;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX.MermaidDiagrammer.Extensions;\n\nnamespace ICSharpCode.ILSpyX.MermaidDiagrammer\n{\n\tpartial class ClassDiagrammerFactory\n\t{\n\t\t/// <summary>Wraps a <see cref=\"CSharpDecompiler\"/> method configurable via <see cref=\"decompilerSettings\"/>\n\t\t/// that can be used to determine whether a member should be hidden.</summary>\n\t\tprivate bool IsHidden(IEntity entity) => CSharpDecompiler.MemberIsHidden(entity.ParentModule!.MetadataFile, entity.MetadataToken, decompilerSettings);\n\n\t\tprivate IField[] GetFields(ITypeDefinition type, IProperty[] properties)\n\t\t\t// only display fields that are not backing properties of the same name and type\n\t\t\t=> type.GetFields(f => !IsHidden(f) // removes compiler-generated backing fields\n\t\t\t\t/* tries to remove remaining manual backing fields by matching type and name */\n\t\t\t\t&& !properties.Any(p => f.ReturnType.Equals(p.ReturnType)\n\t\t\t\t\t&& Regex.IsMatch(f.Name, \"_?\" + p.Name, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.NonBacktracking))).ToArray();\n\n\t\tprivate static IEnumerable<IMethod> GetMethods(ITypeDefinition type)\n\t\t{\n\t\t\treturn type.GetMethods(IsDeclaredMethod);\n\n\t\t\tbool IsDeclaredMethod(IMethod m)\n\t\t\t{\n\t\t\t\tif (m.IsOperator || m.IsCompilerGenerated())\n\t\t\t\t\treturn false;\n\t\t\t\tif (m.DeclaringTypeDefinition == type)\n\t\t\t\t{\n\t\t\t\t\t// include methods if self-declared\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t//  but exclude methods declared by object and their overrides, if inherited\n\t\t\t\t\tif (m.DeclaringType.IsObject())\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tIMember? baseMember;\n\t\t\t\t\tif (m.IsOverride && (baseMember = InheritanceHelper.GetBaseMember(m)) != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (baseMember.DeclaringType.IsObject())\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tprivate string FormatMethod(IMethod method)\n\t\t{\n\t\t\tstring parameters = method.Parameters.Select(p => $\"{GetName(p.Type)} {p.Name}\").Join(\", \");\n\t\t\tstring? modifier = method.IsAbstract ? \"*\" : method.IsStatic ? \"$\" : default;\n\t\t\tstring name = method.Name;\n\n\t\t\tif (method.IsExplicitInterfaceImplementation)\n\t\t\t{\n\t\t\t\tIMember member = method.ExplicitlyImplementedInterfaceMembers.Single();\n\t\t\t\tname = GetName(member.DeclaringType) + '.' + member.Name;\n\t\t\t}\n\n\t\t\tstring? typeArguments = method.TypeArguments.Count == 0 ? null : $\"❰{method.TypeArguments.Select(GetName).Join(\", \")}❱\";\n\t\t\treturn $\"{GetAccessibility(method.Accessibility)}{name}{typeArguments}({parameters}){modifier} {GetName(method.ReturnType)}\";\n\t\t}\n\n\t\tprivate string FormatFlatProperty(IProperty property)\n\t\t{\n\t\t\tchar? visibility = GetAccessibility(property.Accessibility);\n\t\t\tstring? modifier = property.IsAbstract ? \"*\" : property.IsStatic ? \"$\" : default;\n\t\t\treturn $\"{visibility}{GetName(property.ReturnType)} {property.Name}{modifier}\";\n\t\t}\n\n\t\tprivate string FormatField(IField field)\n\t\t{\n\t\t\tstring? modifier = field.IsAbstract ? \"*\" : field.IsStatic ? \"$\" : default;\n\t\t\treturn $\"{GetAccessibility(field.Accessibility)}{GetName(field.ReturnType)} {field.Name}{modifier}\";\n\t\t}\n\n\t\t// see https://stackoverflow.com/a/16024302 for accessibility modifier flags\n\t\tprivate static char? GetAccessibility(Accessibility access) => access switch {\n\t\t\tAccessibility.Private => '-',\n\t\t\tAccessibility.ProtectedAndInternal or Accessibility.Internal => '~',\n\t\t\tAccessibility.Protected or Accessibility.ProtectedOrInternal => '#',\n\t\t\tAccessibility.Public => '+',\n\t\t\t_ => default,\n\t\t};\n\t}\n}"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/Factory.Relationships.cs",
    "content": "// Copyright (c) 2024 Holger Schmidt\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX.MermaidDiagrammer.Extensions;\n\nnamespace ICSharpCode.ILSpyX.MermaidDiagrammer\n{\n\tusing CD = ClassDiagrammer;\n\n\tpartial class ClassDiagrammerFactory\n\t{\n\t\tprivate IProperty[] GetHasOneRelations(IProperty[] properties) => properties.Where(property => {\n\t\t\tIType type = property.ReturnType;\n\n\t\t\tif (type.TryGetNullableType(out var typeArg))\n\t\t\t\ttype = typeArg;\n\n\t\t\treturn selectedTypes!.Contains(type);\n\t\t}).ToArray();\n\n\t\tprivate (IProperty property, IType elementType)[] GetManyRelations(IProperty[] properties)\n\t\t\t=> properties.Select(property => {\n\t\t\t\tIType elementType = property.ReturnType.GetElementTypeFromIEnumerable(property.Compilation, true, out bool? isGeneric);\n\n\t\t\t\tif (isGeneric == false && elementType.IsObject())\n\t\t\t\t{\n\t\t\t\t\tIProperty[] indexers = property.ReturnType.GetProperties(\n\t\t\t\t\t\tp => p.IsIndexer && !p.ReturnType.IsObject(),\n\t\t\t\t\t\tGetMemberOptions.IgnoreInheritedMembers).ToArray(); // TODO mayb order by declaring type instead of filtering\n\n\t\t\t\t\tif (indexers.Length > 0)\n\t\t\t\t\t\telementType = indexers[0].ReturnType;\n\t\t\t\t}\n\n\t\t\t\treturn isGeneric == true && selectedTypes!.Contains(elementType) ? (property, elementType) : default;\n\t\t\t}).Where(pair => pair != default).ToArray();\n\n\t\t/// <summary>Returns the relevant direct super type the <paramref name=\"type\"/> inherits from\n\t\t/// in a format matching <see cref=\"CD.Type.BaseType\"/>.</summary>\n\t\tprivate Dictionary<string, string?>? GetBaseType(IType type)\n\t\t{\n\t\t\tIType? relevantBaseType = type.DirectBaseTypes.SingleOrDefault(t => !t.IsInterface() && !t.IsObject());\n\t\t\treturn relevantBaseType == null ? default : new[] { BuildRelationship(relevantBaseType) }.ToDictionary(r => r.to, r => r.label);\n\t\t}\n\n\t\t/// <summary>Returns the direct interfaces implemented by <paramref name=\"type\"/>\n\t\t/// in a format matching <see cref=\"CD.Type.Interfaces\"/>.</summary>\n\t\tprivate Dictionary<string, string?[]>? GetInterfaces(ITypeDefinition type)\n\t\t{\n\t\t\tvar interfaces = type.DirectBaseTypes.Where(t => t.IsInterface()).ToArray();\n\n\t\t\treturn interfaces.Length == 0 ? null\n\t\t\t\t: interfaces.Select(i => BuildRelationship(i)).GroupBy(r => r.to)\n\t\t\t\t\t.ToDictionary(g => g.Key, g => g.Select(r => r.label).ToArray());\n\t\t}\n\n\t\t/// <summary>Returns the one-to-one relations from <paramref name=\"type\"/> to other <see cref=\"CD.Type\"/>s\n\t\t/// in a format matching <see cref=\"CD.Relationships.HasOne\"/>.</summary>\n\t\tprivate Dictionary<string, string>? MapHasOneRelations(Dictionary<IType, IProperty[]> hasOneRelationsByType, IType type)\n\t\t\t=> hasOneRelationsByType.GetValue(type)?.Select(p => {\n\t\t\t\tIType type = p.ReturnType;\n\t\t\t\tstring label = p.Name;\n\n\t\t\t\tif (p.IsIndexer)\n\t\t\t\t\tlabel += $\"[{p.Parameters.Single().Type.Name} {p.Parameters.Single().Name}]\";\n\n\t\t\t\tif (type.TryGetNullableType(out var typeArg))\n\t\t\t\t{\n\t\t\t\t\ttype = typeArg;\n\t\t\t\t\tlabel += \" ?\";\n\t\t\t\t}\n\n\t\t\t\treturn BuildRelationship(type, label);\n\t\t\t}).ToDictionary(r => r.label!, r => r.to);\n\n\t\t/// <summary>Returns the one-to-many relations from <paramref name=\"type\"/> to other <see cref=\"CD.Type\"/>s\n\t\t/// in a format matching <see cref=\"CD.Relationships.HasMany\"/>.</summary>\n\t\tprivate Dictionary<string, string>? MapHasManyRelations(Dictionary<IType, (IProperty property, IType elementType)[]> hasManyRelationsByType, IType type)\n\t\t\t=> hasManyRelationsByType.GetValue(type)?.Select(relation => {\n\t\t\t\t(IProperty property, IType elementType) = relation;\n\t\t\t\treturn BuildRelationship(elementType, property.Name);\n\t\t\t}).ToDictionary(r => r.label!, r => r.to);\n\n\t\t/// <summary>Builds references to super types and (one/many) relations,\n\t\t/// recording outside references on the way and applying labels if required.</summary>\n\t\t/// <param name=\"type\">The type to reference.</param>\n\t\t/// <param name=\"propertyName\">Used only for property one/many relations.</param>\n\t\tprivate (string to, string? label) BuildRelationship(IType type, string? propertyName = null)\n\t\t{\n\t\t\t(string id, IType? openGeneric) = GetIdAndOpenGeneric(type);\n\t\t\tAddOutsideReference(id, openGeneric ?? type);\n\n\t\t\t// label the relation with the property name if provided or the closed generic type for super types\n\t\t\tstring? label = propertyName ?? (openGeneric == null ? null : GetName(type));\n\n\t\t\treturn (to: id, label);\n\t\t}\n\n\t\tprivate void AddOutsideReference(string typeId, IType type)\n\t\t{\n\t\t\tif (!selectedTypes!.Contains(type) && outsideReferences?.ContainsKey(typeId) == false)\n\t\t\t\toutsideReferences.Add(typeId, type.Namespace + '.' + GetName(type));\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/Factory.TypeIds.cs",
    "content": "// Copyright (c) 2024 Holger Schmidt\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX.MermaidDiagrammer.Extensions;\n\nnamespace ICSharpCode.ILSpyX.MermaidDiagrammer\n{\n\tusing CD = ClassDiagrammer;\n\n\tpublic partial class ClassDiagrammerFactory\n\t{\n\t\t/// <summary>Generates a dictionary of unique and short, but human readable identifiers for\n\t\t/// <paramref name=\"types\"/> to be able to safely reference them in any combination.</summary>\n\t\tprivate static Dictionary<IType, string> GenerateUniqueIds(IEnumerable<ITypeDefinition> types)\n\t\t{\n\t\t\tDictionary<IType, string> uniqueIds = [];\n\t\t\tvar groups = types.GroupBy(t => t.Name);\n\n\t\t\t// simplified handling for the majority of unique types\n\t\t\tforeach (var group in groups.Where(g => g.Count() == 1))\n\t\t\t\tuniqueIds[group.First()] = SanitizeTypeName(group.Key);\n\n\t\t\t// number non-unique types\n\t\t\tforeach (var group in groups.Where(g => g.Count() > 1))\n\t\t\t{\n\t\t\t\tvar counter = 0;\n\n\t\t\t\tforeach (var type in group)\n\t\t\t\t\tuniqueIds[type] = type.Name + ++counter;\n\t\t\t}\n\n\t\t\treturn uniqueIds;\n\t\t}\n\n\t\tprivate string GetId(IType type) => GetIdAndOpenGeneric(type).id;\n\n\t\t/// <summary>For a non- or open generic <paramref name=\"type\"/>, returns a unique identifier and null.\n\t\t/// For a closed generic <paramref name=\"type\"/>, returns the open generic type and the unique identifier of it.\n\t\t/// That helps connecting closed generic references (e.g. Store&lt;int>) to their corresponding\n\t\t/// open generic <see cref=\"CD.Type\"/> (e.g. Store&lt;T>) like in <see cref=\"BuildRelationship(IType, string?)\"/>.</summary>\n\t\tprivate (string id, IType? openGeneric) GetIdAndOpenGeneric(IType type)\n\t\t{\n\t\t\t// get open generic type if type is a closed generic (i.e. has type args none of which are parameters)\n\t\t\tvar openGeneric = type is ParameterizedType generic && !generic.TypeArguments.Any(a => a is ITypeParameter)\n\t\t\t\t? generic.GenericType : null;\n\n\t\t\ttype = openGeneric ?? type; // reference open instead of closed generic type\n\n\t\t\tif (uniqueIds!.TryGetValue(type, out var uniqueId))\n\t\t\t\treturn (uniqueId, openGeneric); // types included by FilterTypes\n\n\t\t\t// types excluded by FilterTypes\n\t\t\tstring? typeParams = type.TypeParameterCount == 0 ? null : (\"_\" + type.TypeParameters.Select(GetId).Join(\"_\"));\n\n\t\t\tvar id = SanitizeTypeName(type.FullName.Replace('.', '_'))\n\t\t\t\t+ typeParams; // to achieve uniqueness for types with same FullName (i.e. generic overloads)\n\n\t\t\tuniqueIds![type] = id; // update dictionary to avoid re-generation\n\t\t\treturn (id, openGeneric);\n\t\t}\n\n\t\tprivate static string SanitizeTypeName(string typeName)\n\t\t\t=> typeName.Replace('<', '_').Replace('>', '_'); // for module of executable\n\t}\n}"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/Factory.TypeNames.cs",
    "content": "// Copyright (c) 2024 Holger Schmidt\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX.MermaidDiagrammer.Extensions;\n\nnamespace ICSharpCode.ILSpyX.MermaidDiagrammer\n{\n\tpublic partial class ClassDiagrammerFactory\n\t{\n\t\t/// <summary>Returns a cached display name for <paramref name=\"type\"/>.</summary>\n\t\tprivate string GetName(IType type)\n\t\t{\n\t\t\tif (labels!.TryGetValue(type, out string? value))\n\t\t\t\treturn value; // return cached value\n\n\t\t\treturn labels[type] = GenerateName(type); // generate and cache new value\n\t\t}\n\n\t\t/// <summary>Generates a display name for <paramref name=\"type\"/>.</summary>\n\t\tprivate string GenerateName(IType type)\n\t\t{\n\t\t\t// non-generic types\n\t\t\tif (type.TypeParameterCount < 1)\n\t\t\t{\n\t\t\t\tif (type is ArrayType array)\n\t\t\t\t\treturn GetName(array.ElementType) + \"[]\";\n\n\t\t\t\tif (type is ByReferenceType byReference)\n\t\t\t\t\treturn \"&\" + GetName(byReference.ElementType);\n\n\t\t\t\tITypeDefinition? typeDefinition = type.GetDefinition();\n\n\t\t\t\tif (typeDefinition == null)\n\t\t\t\t\treturn type.Name;\n\n\t\t\t\tif (typeDefinition.KnownTypeCode == KnownTypeCode.None)\n\t\t\t\t{\n\t\t\t\t\tif (type.DeclaringType == null)\n\t\t\t\t\t\treturn type.Name.Replace('<', '❰').Replace('>', '❱'); // for module of executable\n\t\t\t\t\telse\n\t\t\t\t\t\treturn type.DeclaringType.Name + '+' + type.Name; // nested types\n\t\t\t\t}\n\n\t\t\t\treturn KnownTypeReference.GetCSharpNameByTypeCode(typeDefinition.KnownTypeCode) ?? type.Name;\n\t\t\t}\n\n\t\t\t// nullable types\n\t\t\tif (type.TryGetNullableType(out var nullableType))\n\t\t\t\treturn GetName(nullableType) + \"?\";\n\n\t\t\t// other generic types\n\t\t\tstring typeArguments = type.TypeArguments.Select(GetName).Join(\", \");\n\t\t\treturn type.Name + $\"❰{typeArguments}❱\";\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/GenerateHtmlDiagrammer.cs",
    "content": "// Copyright (c) 2024 Holger Schmidt\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.ILSpyX.MermaidDiagrammer\n{\n\t/// <summary>The command for creating an HTML5 diagramming app with an API optimized for binding command line parameters.\n\t/// To use it outside of that context, set its properties and call <see cref=\"Run\"/>.</summary>\n\tpublic partial class GenerateHtmlDiagrammer\n\t{\n\t\tinternal const string RepoUrl = \"https://github.com/icsharpcode/ILSpy\";\n\n\t\tpublic required string Assembly { get; set; }\n\t\tpublic string? OutputFolder { get; set; }\n\n\t\tpublic string? Include { get; set; }\n\t\tpublic string? Exclude { get; set; }\n\t\tpublic bool JsonOnly { get; set; }\n\t\tpublic bool ReportExcludedTypes { get; set; }\n\t\tpublic string? XmlDocs { get; set; }\n\n\t\t/// <summary>Namespaces to strip from <see cref=\"XmlDocs\"/>.\n\t\t/// Implemented as a list of exact replacements instead of a single, more powerful RegEx because replacement in\n\t\t/// <see cref=\"XmlDocumentationFormatter.GetDoco(Decompiler.TypeSystem.IEntity)\"/>\n\t\t/// happens on the unstructured string where matching and replacing the namespaces of referenced types, members and method parameters\n\t\t/// using RegExes would add a lot of complicated RegEx-heavy code for a rather unimportant feature.</summary>\n\t\tpublic IEnumerable<string>? StrippedNamespaces { get; set; }\n\t}\n}"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/Generator.Run.cs",
    "content": "// Copyright (c) 2024 Holger Schmidt\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\n\nusing ICSharpCode.Decompiler.Documentation;\nusing ICSharpCode.ILSpyX.MermaidDiagrammer.Extensions;\n\nnamespace ICSharpCode.ILSpyX.MermaidDiagrammer\n{\n\tpartial class GenerateHtmlDiagrammer\n\t{\n\t\tpublic void Run()\n\t\t{\n\t\t\tvar assemblyPath = Assembly;\n\t\t\tXmlDocumentationFormatter? xmlDocs = CreateXmlDocsFormatter(assemblyPath);\n\t\t\tClassDiagrammer model = BuildModel(assemblyPath, xmlDocs);\n\t\t\tGenerateOutput(assemblyPath, model);\n\t\t}\n\n\t\tprotected virtual XmlDocumentationFormatter? CreateXmlDocsFormatter(string assemblyPath)\n\t\t{\n\t\t\tvar xmlDocsPath = XmlDocs == null ? Path.ChangeExtension(assemblyPath, \".xml\") : XmlDocs;\n\t\t\tXmlDocumentationFormatter? xmlDocs = null;\n\n\t\t\tif (File.Exists(xmlDocsPath))\n\t\t\t\txmlDocs = new XmlDocumentationFormatter(new XmlDocumentationProvider(xmlDocsPath), StrippedNamespaces?.ToArray());\n\t\t\telse\n\t\t\t\tDebug.WriteLine(\"No XML documentation file found. Continuing without.\");\n\n\t\t\treturn xmlDocs;\n\t\t}\n\n\t\tprotected virtual ClassDiagrammer BuildModel(string assemblyPath, XmlDocumentationFormatter? xmlDocs)\n\t\t\t=> new ClassDiagrammerFactory(xmlDocs).BuildModel(assemblyPath, Include, Exclude);\n\n\t\tprivate string SerializeModel(ClassDiagrammer diagrammer)\n\t\t{\n\t\t\tobject jsonModel = new {\n\t\t\t\tdiagrammer.OutsideReferences,\n\n\t\t\t\t/* convert collections to dictionaries for easier access in ES using\n\t\t\t\t * for (let [key, value] of Object.entries(dictionary)) */\n\t\t\t\tTypesByNamespace = diagrammer.TypesByNamespace.ToDictionary(ns => ns.Key,\n\t\t\t\t\tns => ns.Value.ToDictionary(t => t.Id, t => t))\n\t\t\t};\n\n\t\t\t// wrap model including the data required for doing the template replacement in a JS build task\n\t\t\tif (JsonOnly)\n\t\t\t{\n\t\t\t\tjsonModel = new {\n\t\t\t\t\tdiagrammer.SourceAssemblyName,\n\t\t\t\t\tdiagrammer.SourceAssemblyVersion,\n\t\t\t\t\tBuilderVersion = DecompilerVersionInfo.FullVersionWithCommitHash,\n\t\t\t\t\tRepoUrl,\n\t\t\t\t\t// pre-serialize to a string so that we don't have to re-serialize it in the JS build task\n\t\t\t\t\tModel = Serialize(jsonModel)\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn Serialize(jsonModel);\n\t\t}\n\n\t\tprivate static JsonSerializerOptions serializerOptions = new() {\n\t\t\tWriteIndented = true,\n\t\t\t// avoid outputting null properties unnecessarily\n\t\t\tDefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull\n\t\t};\n\n\t\tprivate static string Serialize(object json) => JsonSerializer.Serialize(json, serializerOptions);\n\n\t\tprivate void GenerateOutput(string assemblyPath, ClassDiagrammer model)\n\t\t{\n\t\t\tstring modelJson = SerializeModel(model);\n\n\t\t\t// If no out folder is specified, default to a \"<Input.Assembly.Name> diagrammer\" folder next to the input assembly.\n\t\t\tvar outputFolder = OutputFolder\n\t\t\t\t?? Path.Combine(\n\t\t\t\t\tPath.GetDirectoryName(assemblyPath) ?? string.Empty,\n\t\t\t\t\tPath.GetFileNameWithoutExtension(assemblyPath) + \" diagrammer\");\n\n\t\t\tif (!Directory.Exists(outputFolder))\n\t\t\t\tDirectory.CreateDirectory(outputFolder);\n\n\t\t\tif (JsonOnly)\n\t\t\t{\n\t\t\t\tFile.WriteAllText(Path.Combine(outputFolder, \"model.json\"), modelJson);\n\t\t\t\tDebug.WriteLine(\"Successfully generated model.json for HTML diagrammer.\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar htmlTemplate = EmbeddedResource.ReadText(\"template.html\");\n\n\t\t\t\tvar html = htmlTemplate\n\t\t\t\t\t.Replace(\"{{SourceAssemblyName}}\", model.SourceAssemblyName)\n\t\t\t\t\t.Replace(\"{{SourceAssemblyVersion}}\", model.SourceAssemblyVersion)\n\t\t\t\t\t.Replace(\"{{BuilderVersion}}\", DecompilerVersionInfo.FullVersionWithCommitHash)\n\t\t\t\t\t.Replace(\"{{RepoUrl}}\", RepoUrl)\n\t\t\t\t\t.Replace(\"{{Model}}\", modelJson);\n\n\t\t\t\tFile.WriteAllText(Path.Combine(outputFolder, \"index.html\"), html);\n\n\t\t\t\t// copy required resources to output folder while flattening paths if required\n\t\t\t\tforeach (var resource in new[] { \"styles.css\", \"ILSpy.ico\", \"script.js\" })\n\t\t\t\t\tEmbeddedResource.CopyTo(outputFolder, resource);\n\n\t\t\t\tDebug.WriteLine(\"Successfully generated HTML diagrammer.\");\n\t\t\t}\n\n\t\t\tif (ReportExcludedTypes)\n\t\t\t{\n\t\t\t\tstring excludedTypes = model.Excluded.Join(Environment.NewLine);\n\t\t\t\tFile.WriteAllText(Path.Combine(outputFolder, \"excluded types.txt\"), excludedTypes);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/ReadMe.md",
    "content": "# How does it work?\n\nTo **extract the type info from the source assembly**, ILSpy side-loads it including all its dependencies.\n\nThe extracted type info is **structured into a model optimized for the HTML diagrammer** and serialized to JSON. The model is a mix between drop-in type definitions in mermaid class diagram syntax and destructured metadata about relations, inheritance and documentation comments.\n\n> The JSON type info is injected into the `template.html` alongside other resources like the `script.js` at corresponding `{{placeholders}}`. It comes baked into the HTML diagrammer to enable\n> - accessing the data and\n> - importing the mermaid module from a CDN\n>\n> locally without running a web server [while also avoiding CORS restrictions.](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#file_origins)\n\nIn the final step, the **HTML diagrammer app re-assembles the type info** based on the in-app type selection and rendering options **to generate [mermaid class diagrams](https://mermaid.js.org/syntax/classDiagram.html)** with the types, their relations and as much inheritance detail as you need.\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/XmlDocumentationFormatter.cs",
    "content": "// Copyright (c) 2024 Holger Schmidt\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text.RegularExpressions;\n\nusing ICSharpCode.Decompiler.Documentation;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX.MermaidDiagrammer.Extensions;\n\nnamespace ICSharpCode.ILSpyX.MermaidDiagrammer\n{\n\t/// <summary>Wraps the <see cref=\"IDocumentationProvider\"/> to prettify XML documentation comments.\n\t/// Make sure to enable XML documentation output, see\n\t/// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/xmldoc/#create-xml-documentation-output .</summary>\n\tpublic class XmlDocumentationFormatter\n\t{\n\t\t/// <summary>Matches XML indent.</summary>\n\t\tprotected const string linePadding = @\"^[ \\t]+|[ \\t]+$\";\n\n\t\t/// <summary>Matches reference tags including \"see href\", \"see cref\" and \"paramref name\"\n\t\t/// with the cref value being prefixed by symbol-specific letter and a colon\n\t\t/// including the quotes around the attribute value and the closing slash of the tag containing the attribute.</summary>\n\t\tprotected const string referenceAttributes = @\"(see\\s.ref=\"\"(.:)?)|(paramref\\sname=\"\")|(\"\"\\s/)\";\n\n\t\tprivate readonly IDocumentationProvider docs;\n\t\tprivate readonly Regex noiseAndPadding;\n\n\t\tpublic XmlDocumentationFormatter(IDocumentationProvider docs, string[]? strippedNamespaces)\n\t\t{\n\t\t\tthis.docs = docs;\n\t\t\tList<string> regexes = new() { linePadding, referenceAttributes };\n\n\t\t\tif (strippedNamespaces?.Length > 0)\n\t\t\t\tregexes.AddRange(strippedNamespaces.Select(ns => $\"({ns.Replace(\".\", \"\\\\.\")}\\\\.)\"));\n\n\t\t\tnoiseAndPadding = new Regex(regexes.Join(\"|\"), RegexOptions.Multiline); // builds an OR | combined regex\n\t\t}\n\n\t\tinternal Dictionary<string, string>? GetXmlDocs(ITypeDefinition type, params IMember[][] memberCollections)\n\t\t{\n\t\t\tDictionary<string, string>? docs = new();\n\t\t\tAddXmlDocEntry(docs, type);\n\n\t\t\tforeach (IMember[] members in memberCollections)\n\t\t\t{\n\t\t\t\tforeach (IMember member in members)\n\t\t\t\t\tAddXmlDocEntry(docs, member);\n\t\t\t}\n\n\t\t\treturn docs?.Keys.Count != 0 ? docs : default;\n\t\t}\n\n\t\tprotected virtual string? GetDoco(IEntity entity)\n\t\t{\n\t\t\tstring? comment = docs.GetDocumentation(entity)?\n\t\t\t\t.ReplaceAll([\"<summary>\", \"</summary>\"], null)\n\t\t\t\t.ReplaceAll([\"<para>\", \"</para>\"], ClassDiagrammer.NewLine).Trim() // to format\n\t\t\t\t.Replace('<', '[').Replace('>', ']'); // to prevent ugly escaped output\n\n\t\t\treturn comment == null ? null : noiseAndPadding.Replace(comment, string.Empty).NormalizeHorizontalWhiteSpace();\n\t\t}\n\n\t\tprivate void AddXmlDocEntry(Dictionary<string, string> docs, IEntity entity)\n\t\t{\n\t\t\tstring? doc = GetDoco(entity);\n\n\t\t\tif (string.IsNullOrEmpty(doc))\n\t\t\t\treturn;\n\n\t\t\tstring key = entity is IMember member ? member.Name : string.Empty;\n\t\t\tdocs[key] = doc;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/html/.eslintrc.js",
    "content": "module.exports = {\n    'env': {\n        'commonjs': true,\n        'es6': true,\n        'browser': true\n    },\n    'extends': 'eslint:recommended',\n    'parserOptions': {\n        'sourceType': 'module',\n        'ecmaVersion': 'latest'\n    },\n    'rules': {\n        'indent': ['error', 4, { 'SwitchCase': 1 }],\n        'semi': ['error', 'always']\n    }\n};"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/html/.gitignore",
    "content": "/node_modules\n/class-diagrammer.html\n/model.json\n/package-lock.json\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/html/README.txt",
    "content": "To edit the HTML/JS/CSS for the HTML diagrammer, open this folder in Visual Studio Code.\n\nIn that environment you'll find tasks (see https://code.visualstudio.com/Docs/editor/tasks to run and configure)\nthat you can run to\n\n1.  Generate a model.json using the current Debug build of ilspycmd.\n    This is required to build a diagrammer for testing in development using task 3.\n2.  Transpile the .less into .css that is tracked by source control and embedded into ILSpyX.\n3.  Generate a diagrammer for testing in development from template.html and the model.json generated by task 1.\n4.  Auto-rebuild the development diagrammer by running either task 2 or 3 when the corresponding source files change."
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/html/gulpfile.js",
    "content": "const gulp = require('gulp');\nconst less = require('gulp-less');\nconst fs = require('fs');\n\nfunction transpileLess (done) {\n    gulp\n        .src('styles.less') // source file(s) to process\n        .pipe(less()) // pass them through the LESS compiler\n        .pipe(gulp.dest(f => f.base)); // Use the base directory of the source file for output\n\n    done(); // signal task completion\n}\n\nfunction generateHtmlDiagrammer (done) {\n    // Read and parse model.json\n    fs.readFile('model.json', 'utf8', function (err, data) {\n        if (err) {\n            console.error('Error reading model.json:', err);\n            done(err);\n            return;\n        }\n\n        const model = JSON.parse(data); // Parse the JSON data\n\n        // Read template.html\n        fs.readFile('template.html', 'utf8', function (err, templateContent) {\n            if (err) {\n                console.error('Error reading template.html:', err);\n                done(err);\n                return;\n            }\n\n            // Replace placeholders in template with values from model\n            let outputContent = templateContent;\n\n            for (const [key, value] of Object.entries(model)) {\n                const placeholder = `{{${key}}}`; // Create the placeholder\n                outputContent = outputContent.replace(new RegExp(placeholder, 'g'), value); // Replace all occurrences\n            }\n\n            // Save the replaced content\n            fs.writeFile('class-diagrammer.html', outputContent, 'utf8', function (err) {\n                if (err) {\n                    console.error('Error writing class-diagrammer.html:', err);\n                    done(err);\n                    return;\n                }\n\n                console.log('class-diagrammer.html generated successfully.');\n                done(); // Signal completion\n            });\n        });\n    });\n}\n\nexports.transpileLess = transpileLess;\nexports.generateHtmlDiagrammer = generateHtmlDiagrammer;\n\n/*  Run individual build tasks first, then start watching for changes\n    see https://code.visualstudio.com/Docs/languages/CSS#_automating-sassless-compilation */\nexports.autoRebuildOnChange = gulp.series(transpileLess, generateHtmlDiagrammer, function (done) {\n    // Watch for changes in source files and rerun the corresponding build task\n    gulp.watch('styles.less', gulp.series(transpileLess));\n    gulp.watch(['template.html', 'model.json'], gulp.series(generateHtmlDiagrammer));\n    done(); // signal task completion\n});\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/html/package.json",
    "content": "{\n  \"devDependencies\": {\n    \"eslint\": \"^8.57.1\",\n    \"gulp\": \"^4.0.2\",\n    \"gulp-less\": \"^5.0.0\"\n  }\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/html/script.js",
    "content": "/*globals mermaid:false*/\n(async () => {\n    const getById = id => document.getElementById(id),\n        triggerChangeOn = element => { element.dispatchEvent(new Event('change')); },\n        hasProperty = (obj, name) => Object.prototype.hasOwnProperty.call(obj, name);\n\n    const checkable = (() => {\n        const checked = ':checked',\n            inputsByName = name => `input[name=${name}]`,\n            getInput = (name, filter, context) => (context || document).querySelector(inputsByName(name) + filter),\n            getInputs = (name, context) => (context || document).querySelectorAll(inputsByName(name));\n\n        return {\n            getValue: (name, context) => getInput(name, checked, context).value,\n\n            onChange: (name, handle, context) => {\n                for (let input of getInputs(name, context)) input.onchange = handle;\n            },\n\n            setChecked: (name, value, triggerChange, context) => {\n                const input = getInput(name, `[value=\"${value}\"]`, context);\n                input.checked = true;\n                if (triggerChange !== false) triggerChangeOn(input);\n            }\n        };\n    })();\n\n    const collapse = (() => {\n        const open = 'open',\n            isOpen = element => element.classList.contains(open),\n\n            /** Toggles the open class on the collapse.\n             *  @param {HTMLElement} element The collapse to toggle.\n             *  @param {boolean} force The state to force. */\n            toggle = (element, force) => element.classList.toggle(open, force);\n\n        return {\n            toggle,\n\n            open: element => {\n                if (isOpen(element)) return false; // return whether collapse was opened by this process\n                return toggle(element, true);\n            },\n\n            initToggles: () => {\n                for (let trigger of [...document.querySelectorAll('.toggle[href],[data-toggles]')]) {\n                    trigger.addEventListener('click', event => {\n                        event.preventDefault(); // to avoid pop-state event\n                        const trigger = event.currentTarget;\n                        trigger.ariaExpanded = !(trigger.ariaExpanded === 'true');\n                        toggle(document.querySelector(trigger.attributes.href?.value || trigger.dataset.toggles));\n                    });\n                }\n            }\n        };\n    })();\n\n    const notify = (() => {\n        const toaster = getById('toaster');\n\n        return message => {\n            const toast = document.createElement('span');\n            toast.innerText = message;\n            toaster.appendChild(toast); // fades in the message\n\n            setTimeout(() => {\n                toast.classList.add('leaving'); // fades out the message\n\n                // ...and removes it. Note this timeout has to match the animation duration for '.leaving' in the .less file.\n                setTimeout(() => { toast.remove(); }, 1000);\n            }, 5000);\n        };\n    })();\n\n    const output = (function () {\n        const output = getById('output'),\n            hasSVG = () => output.childElementCount > 0,\n            getSVG = () => hasSVG() ? output.children[0] : null,\n\n            updateSvgViewBox = (svg, viewBox) => {\n                if (svg.originalViewBox === undefined) {\n                    const vb = svg.viewBox.baseVal;\n                    svg.originalViewBox = { x: vb.x, y: vb.y, width: vb.width, height: vb.height, };\n                }\n\n                svg.setAttribute('viewBox', `${viewBox.x} ${viewBox.y} ${viewBox.width} ${viewBox.height}`);\n            };\n\n        // enable zooming SVG using Ctrl + mouse wheel\n        const zoomFactor = 0.1, panFactor = 2023; // to go with the Zeitgeist\n\n        output.addEventListener('wheel', event => {\n            if (!event.ctrlKey || !hasSVG()) return;\n            event.preventDefault();\n\n            const svg = getSVG(),\n                delta = event.deltaY < 0 ? 1 : -1,\n                zoomDelta = 1 + zoomFactor * delta,\n                viewBox = svg.viewBox.baseVal;\n\n            viewBox.width *= zoomDelta;\n            viewBox.height *= zoomDelta;\n            updateSvgViewBox(svg, viewBox);\n        });\n\n        // enable panning SVG by grabbing and dragging\n        let isPanning = false, panStartX = 0, panStartY = 0;\n\n        output.addEventListener('mousedown', event => {\n            isPanning = true;\n            panStartX = event.clientX;\n            panStartY = event.clientY;\n        });\n\n        output.addEventListener('mouseup', () => { isPanning = false; });\n\n        output.addEventListener('mousemove', event => {\n            if (!isPanning || !hasSVG()) return;\n            event.preventDefault();\n\n            const svg = getSVG(),\n                viewBox = svg.viewBox.baseVal,\n                dx = event.clientX - panStartX,\n                dy = event.clientY - panStartY;\n\n            viewBox.x -= dx * panFactor / viewBox.width;\n            viewBox.y -= dy * panFactor / viewBox.height;\n            panStartX = event.clientX;\n            panStartY = event.clientY;\n            updateSvgViewBox(svg, viewBox);\n        });\n\n        return {\n            getDiagramTitle: () => output.dataset.title,\n            setSVG: svg => { output.innerHTML = svg; },\n            getSVG,\n\n            resetZoomAndPan: () => {\n                const svg = getSVG();\n                if (svg !== null) updateSvgViewBox(svg, svg.originalViewBox);\n            }\n        };\n    })();\n\n    const mermaidExtensions = (() => {\n\n        const logLevel = (() => {\n            /* int indexes as well as string values can identify a valid log level;\n                see log levels and logger definition at https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/logger.ts .\n                Note the names correspond to console output methods https://developer.mozilla.org/en-US/docs/Web/API/console .*/\n            const names = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'],\n                maxIndex = names.length - 1,\n\n                getIndex = level => {\n                    const index = Number.isInteger(level) ? level : names.indexOf(level);\n                    return index < 0 ? maxIndex : Math.min(index, maxIndex); // normalize, but return maxIndex (i.e. lowest level) by default\n                };\n\n            let requested; // the log level index of the in-coming config or the default\n\n            return {\n                /** Sets the desired log level.\n                 * @param {string|int} level The name or index of the desired log level. */\n                setRequested: level => { requested = getIndex(level); },\n\n                /** Returns all names above (not including) the given level.\n                 * @param {int} level The excluded lower boundary log level index (not name).\n                 * @returns an array. */\n                above: level => names.slice(level + 1),\n\n                /** Indicates whether the log level is configured to be enabled.\n                 * @param {string|int} level The log level to test.\n                 * @returns a boolean. */\n                isEnabled: level => requested <= getIndex(level)\n            };\n        })();\n\n        /** Calculates the shortest distance in pixels between a point\n         *  represented by 'top' and 'left' and the closest side of an axis-aligned rectangle.\n         *  Returns 0 if the point is inside or on the edge of the rectangle.\n         *  Inspired by https://gamedev.stackexchange.com/a/50722 .\n         *  @param {int} top The distance of the point from the top of the viewport.\n         *  @param {int} left The distance of the point from the left of the viewport.\n         *  @param {DOMRect} rect The bounding box to get the distance to.\n         *  @returns {int} The distance of the outside point or 0. */\n        function getDistanceToRect(top, left, rect) {\n            const dx = Math.max(rect.left, Math.min(left, rect.right)),\n                dy = Math.max(rect.top, Math.min(top, rect.bottom));\n\n            return Math.sqrt((left - dx) * (left - dx) + (top - dy) * (top - dy));\n        }\n\n        /** Calculates the distance between two non-overlapping axis-aligned rectangles.\n         *  Returns 0 if the rectangles touch or overlap.\n         *  @param {DOMRect} a The first bounding box.\n         *  @param {DOMRect} b The second bounding box.\n         *  @returns {int} The distance between the two bounding boxes or 0 if they touch or overlap. */\n        function getDistance(a, b) {\n            /** Gets coordinate pairs for the corners of a rectangle r.\n             * @param {DOMRect} r the rectangle.\n             * @returns {Array}} */\n            const getCorners = r => [[r.top, r.left], [r.top, r.right], [r.bottom, r.left], [r.bottom, r.right]],\n                /** Gets the distances of the corners of rectA to rectB. */\n                getCornerDistances = (rectA, rectB) => getCorners(rectA).map(c => getDistanceToRect(c[0], c[1], rectB)),\n                aRect = a.getBoundingClientRect(),\n                bRect = b.getBoundingClientRect(),\n                cornerDistances = getCornerDistances(aRect, bRect).concat(getCornerDistances(bRect, aRect));\n\n            return Math.min(...cornerDistances);\n        }\n\n        function interceptConsole(interceptorsByLevel) {\n            const originals = {};\n\n            for (let [level, interceptor] of Object.entries(interceptorsByLevel)) {\n                if (typeof console[level] !== 'function') continue;\n                originals[level] = console[level];\n                console[level] = function () { interceptor.call(this, originals[level], arguments); };\n            }\n\n            return () => { // call to detach interceptors\n                for (let [level, original] of Object.entries(originals))\n                    console[level] = original;\n            };\n        }\n\n        let renderedEdges = [], // contains info about the arrows between types on the diagram once rendered\n            lastRenderedDiagram;\n\n        function getRelationLabels(svg, typeId) {\n            const edgeLabels = [...svg.querySelectorAll('.edgeLabels span.edgeLabel span')],\n                extension = 'extension';\n\n            return renderedEdges.filter(e => e.v === typeId // type name needs to match\n                && e.value.arrowTypeStart !== extension && e.value.arrowTypeEnd !== extension) // exclude inheritance arrows\n                .map(edge => {\n                    const labelHtml = edge.value.label,\n                        // filter edge labels with matching HTML\n                        labels = edgeLabels.filter(l => l.outerHTML === labelHtml);\n\n                    if (labels.length === 1) return labels[0]; // return the only matching label\n                    else if (labels.length < 1) console.error(\n                        \"Tried to find a relation label for the following edge (by its value.label) but couldn't.\", edge);\n                    else { // there are multiple edge labels with the same HTML (i.e. matching relation name)\n                        // find the path that is rendered for the edge\n                        const path = svg.querySelector('.edgePaths>path.relation#' + edge.value.id),\n                            labelsByDistance = labels.sort((a, b) => getDistance(path, a) - getDistance(path, b));\n\n                        console.warn('Found multiple relation labels matching the following edge (by its value.label). Returning the closest/first.',\n                            edge, labelsByDistance);\n\n                        return labelsByDistance[0]; // and return the matching label closest to it\n                    }\n                });\n        }\n\n        return {\n            init: config => {\n\n                /* Override console.info to intercept a message posted by mermaid including information about the edges\n                    (represented by arrows between types in the rendered diagram) to access the relationship info\n                    parsed from the diagram descriptions of selected types.\n                    This works around the mermaid API currently not providing access to this information\n                    and it being hard to reconstruct from the rendered SVG alone.\n                    Why do we need that info? Knowing about the relationships between types, we can find the label\n                    corresponding to a relation and attach XML documentation information to it, if available.\n                    See how getRelationLabels is used. */\n                const requiredLevel = 2, // to enable intercepting info message\n\n                    interceptors = {\n                        info: function (overridden, args) {\n                            // intercept message containing rendered edges\n                            if (args[2] === 'Graph in recursive render: XXX') renderedEdges = args[3].edges;\n\n                            // only forward to overridden method if this log level was originally enabled\n                            if (logLevel.isEnabled(requiredLevel)) overridden.call(this, ...args);\n                        }\n                    };\n\n                logLevel.setRequested(config.logLevel); // remember original log level\n\n                // lower configured log level if required to guarantee above interceptor gets called\n                if (!logLevel.isEnabled(requiredLevel)) config.logLevel = requiredLevel;\n\n                // suppress console output for higher log levels accidentally activated by lowering to required level\n                for (let level of logLevel.above(requiredLevel))\n                    if (!logLevel.isEnabled(level)) interceptors[level] = () => { };\n\n                const detachInterceptors = interceptConsole(interceptors); // attaches console interceptors\n                mermaid.initialize(config); // init the mermaid sub-system with interceptors in place\n                detachInterceptors(); // to avoid intercepting messages outside of that context we're not interested in\n            },\n\n            /** Processes the type selection into mermaid diagram syntax (and the corresponding XML documentation data, if available).\n             * @param {object} typeDetails An object with the IDs of types to display in detail (i.e. with members) for keys\n             * and objects with the data structure of ClassDiagrammer.Type (excluding the Id) for values.\n             * @param {function} getTypeLabel A strategy for getting the type label for a type ID.\n             * @param {string} direction The layout direction of the resulting diagram.\n             * @param {object} showInherited A regular expression matching things to exclude from the diagram definition.\n             * @returns {object} An object like { diagram, detailedTypes, xmlDocs } with 'diagram' being the mermaid diagram syntax,\n             * 'xmlDocs' the corresponding XML documentation to be injected into the rendered diagram in the 'postProcess' step and\n             * 'detailedTypes' being a flat list of IDs of types that will be rendered in detail (including their members and relations). */\n            processTypes: (typeDetails, getTypeLabel, direction, showInherited) => {\n                const detailedTypes = Object.keys(typeDetails), // types that will be rendered including their members and relations\n                    xmlDocs = {}, // to be appended with docs of selected types below\n                    getAncestorTypes = typeDetails => Object.keys(typeDetails.Inherited),\n                    isRendered = type => detailedTypes.includes(type),\n\n                    mayNeedLabelling = new Set(),\n\n                    cleanUpDiagramMmd = mmd => mmd.replace(/(\\r?\\n){3,}/g, '\\n\\n'), // squash more than two consecutive line breaks down into two\n\n                    // renders base type and interfaces depending on settings and selected types\n                    renderSuperType = (supertTypeId, link, typeId, name, displayAll) => {\n                        /* display relation arrow if either the user chose to display this kind of super type\n                            or the super type is selected to be rendered anyway and we might as well for completeness */\n                        if (displayAll || isRendered(supertTypeId)) {\n                            const label = name ? ' : ' + name : '';\n                            diagram += `${supertTypeId} <|${link} ${typeId}${label}\\n`;\n                            mayNeedLabelling.add(supertTypeId);\n                        }\n                    },\n\n                    /*  TODO watch https://github.com/mermaid-js/mermaid/issues/6034 for a solution to render multiple self-references,\n                        which is currently broken. E.g. for LightJson.JsonValue (compare console log) */\n                    // renders HasOne and HasMany relations\n                    renderRelations = (typeId, relations, many) => {\n                        if (relations) // expecting object; only process if not null or undefined\n                            for (let [label, relatedId] of Object.entries(relations)) {\n                                const nullable = label.endsWith(' ?');\n                                const cardinality = many ? '\"*\" ' : nullable ? '\"?\" ' : '';\n                                if (nullable) label = label.substring(0, label.length - 2); // nullability is expressed via cardinality\n                                diagram += `${typeId} --> ${cardinality}${relatedId} : ${label}\\n`;\n                                mayNeedLabelling.add(relatedId);\n                            }\n                    },\n\n                    renderInheritedMembers = (typeId, details) => {\n                        const ancestorTypes = getAncestorTypes(details);\n\n                        // only include inherited members in sub classes if they aren't already rendered in a super class\n                        for (let [ancestorType, members] of Object.entries(details.Inherited)) {\n                            if (isRendered(ancestorType)) continue; // inherited members will be rendered in base type\n\n                            let ancestorsOfDetailedAncestors = ancestorTypes.filter(t => detailedTypes.includes(t)) // get detailed ancestor types\n                                .map(type => getAncestorTypes(typeDetails[type])) // select their ancestor types\n                                .reduce((union, ancestors) => union.concat(ancestors), []); // squash them into a one-dimensional array (ignoring duplicates)\n\n                            // skip displaying inherited members already displayed by detailed ancestor types\n                            if (ancestorsOfDetailedAncestors.includes(ancestorType)) continue;\n\n                            diagram += members.FlatMembers + '\\n';\n                            renderRelations(typeId, members.HasOne);\n                            renderRelations(typeId, members.HasMany, true);\n                        }\n                    };\n\n                // init diagram code with header and layout direction to be appended to below\n                let diagram = 'classDiagram' + '\\n'\n                    + 'direction ' + direction + '\\n\\n';\n\n                // process selected types\n                for (let [typeId, details] of Object.entries(typeDetails)) {\n                    mayNeedLabelling.add(typeId);\n                    diagram += details.Body + '\\n\\n';\n\n                    if (details.BaseType) // expecting object; only process if not null or undefined\n                        for (let [baseTypeId, label] of Object.entries(details.BaseType))\n                            renderSuperType(baseTypeId, '--', typeId, label, showInherited.types);\n\n                    if (details.Interfaces) // expecting object; only process if not null or undefined\n                        for (let [ifaceId, labels] of Object.entries(details.Interfaces))\n                            for (let label of labels)\n                                renderSuperType(ifaceId, '..', typeId, label, showInherited.interfaces);\n\n                    renderRelations(typeId, details.HasOne);\n                    renderRelations(typeId, details.HasMany, true);\n                    xmlDocs[typeId] = details.XmlDocs;\n                    if (showInherited.members && details.Inherited) renderInheritedMembers(typeId, details);\n                }\n\n                for (let typeId of mayNeedLabelling) {\n                    const label = getTypeLabel(typeId);\n                    if (label !== typeId) diagram += `class ${typeId} [\"${label}\"]\\n`;\n                }\n\n                diagram = cleanUpDiagramMmd(diagram);\n                lastRenderedDiagram = diagram; // store diagram syntax for export\n                return { diagram, detailedTypes, xmlDocs };\n            },\n\n            getDiagram: () => lastRenderedDiagram,\n\n            /** Enhances the SVG rendered by mermaid by injecting xmlDocs if available\n             * and attaching type click handlers, if available.\n             * @param {SVGElement} svg The SVG containing the rendered mermaid diagram.\n             * @param {object} options An object like { xmlDocs, onTypeClick }\n             * with 'xmlDocs' being the XML docs by type ID\n             * and 'onTypeClick' being an event listener for the click event\n             * that gets the event and the typeId as parameters. */\n            postProcess: (svg, options) => {\n                // matches 'MyClass2' from generated id attributes in the form of 'classId-MyClass2-0'\n                const typeIdFromDomId = /(?<=classId-)\\w+(?=-\\d+)/;\n\n                for (let entity of svg.querySelectorAll('g.nodes>g.node').values()) {\n                    const typeId = typeIdFromDomId.exec(entity.id)[0];\n\n                    // clone to have a modifiable collection without affecting the original\n                    const docs = structuredClone((options.xmlDocs || [])[typeId]);\n\n                    // splice in XML documentation as label titles if available\n                    if (docs) {\n                        const typeKey = '', nodeLabel = 'span.nodeLabel',\n                            title = entity.querySelector('.label-group'),\n                            relationLabels = getRelationLabels(svg, typeId),\n\n                            setDocs = (label, member) => {\n                                label.title = docs[member];\n                                delete docs[member];\n                            },\n\n                            documentOwnLabel = (label, member) => {\n                                setDocs(label, member);\n                                ownLabels = ownLabels.filter(l => l !== label); // remove label\n                            };\n\n                        let ownLabels = [...entity.querySelectorAll('g.label ' + nodeLabel)];\n\n                        // document the type label itself\n                        if (hasProperty(docs, typeKey)) documentOwnLabel(title.querySelector(nodeLabel), typeKey);\n\n                        // loop through documented members longest name first\n                        for (let member of Object.keys(docs).sort((a, b) => b.length - a.length)) {\n                            // matches only whole words in front of method signatures starting with (\n                            const memberName = new RegExp(`(?<!.*\\\\(.*)\\\\b${member}\\\\b`),\n                                matchingLabels = ownLabels.filter(l => memberName.test(l.textContent)),\n                                related = relationLabels.find(l => l.textContent === member);\n\n                            if (related) matchingLabels.push(related);\n                            if (matchingLabels.length === 0) continue; // members may be rendered in an ancestor type\n\n                            if (matchingLabels.length > 1) console.warn(\n                                `Expected to find one member or relation label for ${title.textContent}.${member}`\n                                + ' to attach the XML documentation to but found multiple. Applying the first.', matchingLabels);\n\n                            documentOwnLabel(matchingLabels[0], member);\n                        }\n                    }\n\n                    if (typeof options.onTypeClick === 'function') entity.addEventListener('click',\n                        function (event) { options.onTypeClick.call(this, event, typeId); });\n                }\n            }\n        };\n    })();\n\n    const state = (() => {\n        const typeUrlDelimiter = '-',\n            originalTitle = document.head.getElementsByTagName('title')[0].textContent;\n\n        const restore = async data => {\n            if (data.d) layoutDirection.set(data.d);\n\n            if (data.t) {\n                inheritanceFilter.setFlagHash(data.i || ''); // if types are set, enable deselecting all options\n                typeSelector.setSelected(data.t.split(typeUrlDelimiter));\n                await render(true);\n            }\n        };\n\n        function updateQueryString(href, params) {\n            // see https://developer.mozilla.org/en-US/docs/Web/API/URL\n            const url = new URL(href), search = url.searchParams;\n\n            for (const [name, value] of Object.entries(params)) {\n                //see https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams\n                if (value === null || value === undefined || value === '') search.delete(name);\n                else if (Array.isArray(value)) {\n                    search.delete(name);\n                    for (let item of value) search.append(name, item);\n                }\n                else search.set(name, value);\n            }\n\n            url.search = search.toString();\n            return url.href;\n        }\n\n        window.onpopstate = async event => { await restore(event.state); };\n\n        return {\n            update: () => {\n                const types = typeSelector.getSelected(),\n                    t = Object.keys(types).join(typeUrlDelimiter),\n                    d = layoutDirection.get(),\n                    i = inheritanceFilter.getFlagHash(),\n                    data = { t, d, i },\n                    typeNames = Object.values(types).map(t => t.Name);\n\n                history.pushState(data, '', updateQueryString(location.href, data));\n\n                // record selected types in title so users see which selection they return to when using a history link\n                document.title = (typeNames.length ? typeNames.join(', ') + ' - ' : '') + originalTitle;\n            },\n            restore: async () => {\n                if (!location.search) return; // assume fresh open and don't try to restore state, preventing inheritance options from being unset\n                const search = new URLSearchParams(location.search);\n                await restore({ d: search.get('d'), i: search.get('i'), t: search.get('t') });\n            }\n        };\n    })();\n\n    const typeSelector = (() => {\n        const select = getById('type-select'),\n            preFilter = getById('pre-filter-types'),\n            renderBtn = getById('render'),\n            model = JSON.parse(getById('model').innerHTML),\n            tags = { optgroup: 'OPTGROUP', option: 'option' },\n            getNamespace = option => option.parentElement.nodeName === tags.optgroup ? option.parentElement.label : '',\n            getOption = typeId => select.querySelector(tags.option + `[value='${typeId}']`);\n\n        // fill select list\n        for (let [namespace, types] of Object.entries(model.TypesByNamespace)) {\n            let optionParent;\n\n            if (namespace) {\n                const group = document.createElement(tags.optgroup);\n                group.label = namespace;\n                select.appendChild(group);\n                optionParent = group;\n            } else optionParent = select;\n\n            for (let typeId of Object.keys(types)) {\n                const type = types[typeId],\n                    option = document.createElement(tags.option);\n\n                option.value = typeId;\n                if (!type.Name) type.Name = typeId; // set omitted label to complete structure\n                option.innerText = type.Name;\n                optionParent.appendChild(option);\n            }\n        }\n\n        // only enable render button if types are selected\n        select.onchange = () => { renderBtn.disabled = select.selectedOptions.length < 1; };\n\n        preFilter.addEventListener('input', () => {\n            const regex = preFilter.value ? new RegExp(preFilter.value, 'i') : null;\n\n            for (let option of select.options)\n                option.hidden = regex !== null && !regex.test(option.innerHTML);\n\n            // toggle option groups hidden depending on whether they have visible children\n            for (let group of select.getElementsByTagName(tags.optgroup))\n                group.hidden = regex !== null && [...group.children].filter(o => !o.hidden).length === 0;\n        });\n\n        return {\n            focus: () => select.focus(),\n            focusFilter: () => preFilter.focus(),\n\n            setSelected: types => {\n                for (let option of select.options)\n                    option.selected = types.includes(option.value);\n\n                triggerChangeOn(select);\n            },\n\n            toggleOption: typeId => {\n                const option = getOption(typeId);\n\n                if (option !== null) {\n                    option.selected = !option.selected;\n                    triggerChangeOn(select);\n                }\n            },\n\n            /** Returns the types selected by the user in the form of an object with the type IDs for keys\n             *  and objects with the data structure of ClassDiagrammer.Type (excluding the Id) for values. */\n            getSelected: () => Object.fromEntries([...select.selectedOptions].map(option => {\n                const namespace = getNamespace(option), typeId = option.value,\n                    details = model.TypesByNamespace[namespace][typeId];\n\n                return [typeId, details];\n            })),\n\n            moveSelection: up => {\n                // inspired by https://stackoverflow.com/a/25851154\n                for (let option of select.selectedOptions) {\n                    if (up && option.previousElementSibling) { // move up\n                        option.parentElement.insertBefore(option, option.previousElementSibling);\n                    } else if (!up && option.nextElementSibling) { // move down\n                        // see https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore\n                        option.parentElement.insertBefore(option, option.nextElementSibling.nextElementSibling);\n                    }\n                }\n            },\n\n            //TODO add method returning namespace to add to title\n            getLabel: typeId => {\n                const option = getOption(typeId);\n                return option ? option.innerText : model.OutsideReferences[typeId];\n            }\n        };\n    })();\n\n    const inheritanceFilter = (() => {\n        const baseType = getById('show-base-types'),\n            interfaces = getById('show-interfaces'),\n            members = getById('show-inherited-members'),\n            getFlags = () => { return { types: baseType.checked, interfaces: interfaces.checked, members: members.checked }; };\n\n        // automatically re-render on change\n        for (let checkbox of [baseType, interfaces, members])\n            checkbox.onchange = async () => { await render(); };\n\n        return {\n            getFlags,\n\n            getFlagHash: () => Object.entries(getFlags())\n                .filter(([, value]) => value) // only true flags\n                .map(([key]) => key[0]).join(''), // first character of each flag\n\n            setFlagHash: hash => {\n                baseType.checked = hash.includes('t');\n                interfaces.checked = hash.includes('i');\n                members.checked = hash.includes('m');\n            }\n        };\n    })();\n\n    const layoutDirection = (() => {\n        const inputName = 'direction';\n\n        // automatically re-render on change\n        checkable.onChange(inputName, async () => { await render(); });\n\n        return {\n            get: () => checkable.getValue(inputName),\n            set: (value, event) => {\n                const hasEvent = event !== undefined;\n                checkable.setChecked(inputName, value, hasEvent);\n                if (hasEvent) event.preventDefault();\n            }\n        };\n    })();\n\n    const render = async isRestoringState => {\n        const { diagram, detailedTypes, xmlDocs } = mermaidExtensions.processTypes(\n            typeSelector.getSelected(), typeSelector.getLabel, layoutDirection.get(), inheritanceFilter.getFlags());\n\n        console.info(diagram);\n        const titledDiagram = diagram + '\\naccTitle: ' + output.getDiagramTitle().replaceAll('\\n', '#10;') + '\\n';\n\n        /* Renders response and deconstructs returned object because we're only interested in the svg.\n            Note that the ID supplied as the first argument must not match any existing element ID\n            unless you want its contents to be replaced. See https://mermaid.js.org/config/usage.html#api-usage */\n        const { svg } = await mermaid.render('foo', titledDiagram);\n        output.setSVG(svg);\n\n        mermaidExtensions.postProcess(output.getSVG(), {\n            xmlDocs,\n\n            onTypeClick: async (event, typeId) => {\n                // toggle selection and re-render on clicking entity\n                typeSelector.toggleOption(typeId);\n                await render();\n            }\n        });\n\n        exportOptions.enable(detailedTypes.length > 0);\n        if (!isRestoringState) state.update();\n    };\n\n    const filterSidebar = (() => {\n        const filterForm = getById('filter'),\n            resizing = 'resizing',\n            toggleBtn = getById('filter-toggle'),\n            toggle = () => collapse.toggle(filterForm);\n\n        // enable rendering by hitting Enter on filter form\n        filterForm.onsubmit = async (event) => {\n            event.preventDefault();\n            await render();\n        };\n\n        // enable adjusting max sidebar width\n        (() => {\n            const filterWidthOverride = getById('filter-width'), // a style tag dedicated to overriding the default filter max-width\n                minWidth = 210, maxWidth = window.innerWidth / 2; // limit the width of the sidebar\n\n            let isDragging = false; // tracks whether the sidebar is being dragged\n            let pickedUp = 0; // remembers where the dragging started from\n            let widthBefore = 0; // remembers the width when dragging starts\n            let change = 0; // remembers the total distance of the drag\n\n            toggleBtn.addEventListener('mousedown', (event) => {\n                isDragging = true;\n                pickedUp = event.clientX;\n                widthBefore = filterForm.offsetWidth;\n            });\n\n            document.addEventListener('mousemove', (event) => {\n                if (!isDragging) return;\n\n                const delta = event.clientX - pickedUp,\n                    newWidth = Math.max(minWidth, Math.min(maxWidth, widthBefore + delta));\n\n                change = delta;\n                filterForm.classList.add(resizing);\n                filterWidthOverride.innerHTML = `#filter.open { max-width: ${newWidth}px; }`;\n            });\n\n            document.addEventListener('mouseup', () => {\n                if (!isDragging) return;\n                isDragging = false;\n                filterForm.classList.remove(resizing);\n            });\n\n            // enable toggling filter info on click\n            toggleBtn.addEventListener('click', () => {\n                if (Math.abs(change) < 5) toggle(); // prevent toggling for small, accidental drags\n                change = 0; // reset the remembered distance to enable subsequent clicks\n            });\n        })();\n\n        return {\n            toggle,\n            open: () => collapse.open(filterForm)\n        };\n    })();\n\n    /* Shamelessly copied from https://github.com/mermaid-js/mermaid-live-editor/blob/develop/src/lib/components/Actions.svelte\n        with only a few modifications after I failed to get the solutions described here working:\n        https://stackoverflow.com/questions/28226677/save-inline-svg-as-jpeg-png-svg/28226736#28226736\n        The closest I got was with this example https://canvg.js.org/examples/offscreen , but the shapes would remain empty. */\n    const exporter = (() => {\n        const getSVGstring = (svg, width, height) => {\n            height && svg?.setAttribute('height', `${height}px`);\n            width && svg?.setAttribute('width', `${width}px`); // Workaround https://stackoverflow.com/questions/28690643/firefox-error-rendering-an-svg-image-to-html5-canvas-with-drawimage\n            if (!svg) svg = getSvgEl();\n\n            return svg.outerHTML.replaceAll('<br>', '<br/>')\n                .replaceAll(/<img([^>]*)>/g, (m, g) => `<img ${g} />`);\n        };\n\n        const toBase64 = utf8String => {\n            const bytes = new TextEncoder().encode(utf8String);\n            return window.btoa(String.fromCharCode.apply(null, bytes));\n        };\n\n        const getBase64SVG = (svg, width, height) => toBase64(getSVGstring(svg, width, height));\n\n        const exportImage = (event, exporter, imagemodeselected, userimagesize) => {\n            const canvas = document.createElement('canvas');\n            const svg = document.querySelector('#output svg');\n            if (!svg) {\n                throw new Error('svg not found');\n            }\n            const box = svg.getBoundingClientRect();\n            canvas.width = box.width;\n            canvas.height = box.height;\n            if (imagemodeselected === 'width') {\n                const ratio = box.height / box.width;\n                canvas.width = userimagesize;\n                canvas.height = userimagesize * ratio;\n            } else if (imagemodeselected === 'height') {\n                const ratio = box.width / box.height;\n                canvas.width = userimagesize * ratio;\n                canvas.height = userimagesize;\n            }\n            const context = canvas.getContext('2d');\n            if (!context) {\n                throw new Error('context not found');\n            }\n            context.fillStyle = 'white';\n            context.fillRect(0, 0, canvas.width, canvas.height);\n            const image = new Image();\n            image.onload = exporter(context, image);\n            image.src = `data:image/svg+xml;base64,${getBase64SVG(svg, canvas.width, canvas.height)}`;\n            event.stopPropagation();\n            event.preventDefault();\n        };\n\n        const getSvgEl = () => {\n            const svgEl = document.querySelector('#output svg').cloneNode(true);\n            svgEl.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');\n            const fontAwesomeCdnUrl = Array.from(document.head.getElementsByTagName('link'))\n                .map((l) => l.href)\n                .find((h) => h.includes('font-awesome'));\n            if (fontAwesomeCdnUrl == null) {\n                return svgEl;\n            }\n            const styleEl = document.createElement('style');\n            styleEl.innerText = `@import url(\"${fontAwesomeCdnUrl}\");'`;\n            svgEl.prepend(styleEl);\n            return svgEl;\n        };\n\n        const simulateDownload = (download, href) => {\n            const a = document.createElement('a');\n            a.download = download;\n            a.href = href;\n            a.click();\n            a.remove();\n        };\n\n        const downloadImage = (context, image) => {\n            return () => {\n                const { canvas } = context;\n                context.drawImage(image, 0, 0, canvas.width, canvas.height);\n                simulateDownload(\n                    exportOptions.getFileName('png'),\n                    canvas.toDataURL('image/png').replace('image/png', 'image/octet-stream')\n                );\n            };\n        };\n\n        const tryWriteToClipboard = blob => {\n            try {\n                if (!blob) throw new Error('blob is empty');\n                void navigator.clipboard.write([new ClipboardItem({ [blob.type]: blob })]);\n                return true;\n            } catch (error) {\n                console.error(error);\n                return false;\n            }\n        };\n\n        const copyPNG = (context, image) => {\n            return () => {\n                const { canvas } = context;\n                context.drawImage(image, 0, 0, canvas.width, canvas.height);\n                canvas.toBlob(blob => { tryWriteToClipboard(blob); });\n            };\n        };\n\n        const tryWriteTextToClipboard = async text => {\n            try {\n                if (!text) throw new Error('text is empty');\n                await navigator.clipboard.writeText(text);\n                return true;\n            } catch (error) {\n                console.error(error);\n                return false;\n            }\n        };\n\n        const copyText = async (event, text) => {\n            if (await tryWriteTextToClipboard(text)) {\n                event.stopPropagation();\n                event.preventDefault();\n            }\n        };\n\n        return {\n            isClipboardAvailable: () => hasProperty(window, 'ClipboardItem'),\n            onCopyPNG: (event, imagemodeselected, userimagesize) => {\n                exportImage(event, copyPNG, imagemodeselected, userimagesize);\n            },\n            onCopySVG: event => { void copyText(event, getSVGstring()); },\n            onCopyMMD: (event, diagram) => { void copyText(event, diagram); },\n            onDownloadPNG: (event, imagemodeselected, userimagesize) => {\n                exportImage(event, downloadImage, imagemodeselected, userimagesize);\n            },\n            onDownloadSVG: () => {\n                simulateDownload(exportOptions.getFileName('svg'), `data:image/svg+xml;base64,${getBase64SVG()}`);\n            },\n            onDownloadMMD: diagram => {\n                simulateDownload(exportOptions.getFileName('mmd'), `data:text/vnd.mermaid;base64,${toBase64(diagram)}`);\n            }\n        };\n    })();\n\n    const exportOptions = (() => {\n        let wereOpened = false; // used to track whether user was able to see save options and may quick-save\n\n        const container = getById('exportOptions'),\n            toggle = getById('exportOptions-toggle'),\n            saveBtn = getById('save'),\n            copyBtn = getById('copy'),\n            saveAs = 'saveAs',\n            png = 'png',\n            svg = 'svg',\n            isDisabled = () => toggle.hidden, // using toggle visibility as indicator\n\n            open = () => {\n                wereOpened = true;\n                return collapse.open(container);\n            },\n\n            copy = event => {\n                if (isDisabled()) return; // allow the default for copying text if no types are rendered\n\n                if (!exporter.isClipboardAvailable()) notify('The clipboard seems unavailable in this browser :(');\n                else {\n                    const type = checkable.getValue(saveAs);\n\n                    try {\n                        if (type === png) {\n                            const [dimension, size] = getDimensions();\n                            exporter.onCopyPNG(event, dimension, size);\n                        }\n                        else if (type === svg) exporter.onCopySVG(event);\n                        else exporter.onCopyMMD(event, mermaidExtensions.getDiagram());\n\n                        notify(`The diagram ${type.toUpperCase()} is in your clipboard.`);\n                    } catch (e) {\n                        notify(e.toString());\n                    }\n                }\n            },\n\n            save = event => {\n                const type = checkable.getValue(saveAs);\n\n                if (type === png) {\n                    const [dimension, size] = getDimensions();\n                    exporter.onDownloadPNG(event, dimension, size);\n                }\n                else if (type === svg) exporter.onDownloadSVG();\n                else exporter.onDownloadMMD(mermaidExtensions.getDiagram());\n            };\n\n        const getDimensions = (() => {\n            const inputName = 'dimension',\n                scale = 'scale',\n                dimensions = getById('dimensions'),\n                scaleInputs = container.querySelectorAll('#scale-controls input');\n\n            // enable toggling dimension controls\n            checkable.onChange(saveAs, event => {\n                collapse.toggle(dimensions, event.target.value === png);\n            }, container);\n\n            // enable toggling scale controls\n            checkable.onChange(inputName, event => {\n                const disabled = event.target.value !== scale;\n                for (let input of scaleInputs) input.disabled = disabled;\n            }, container);\n\n            return () => {\n                let dimension = checkable.getValue(inputName);\n\n                // return dimension to scale to desired size if not exporting in current size\n                if (dimension !== 'auto') dimension = checkable.getValue(scale);\n\n                return [dimension, getById('scale-size').value];\n            };\n        })();\n\n        if (exporter.isClipboardAvailable()) copyBtn.onclick = copy;\n        else copyBtn.hidden = true;\n\n        saveBtn.onclick = save;\n\n        return {\n            copy,\n            getFileName: ext => `${saveBtn.dataset.assembly}-diagram-${new Date().toISOString().replace(/[Z:.]/g, '')}.${ext}`,\n\n            enable: enable => {\n                if (!enable) collapse.toggle(container, false); // make sure the container is closed when disabling\n                toggle.hidden = !enable;\n            },\n\n            quickSave: event => {\n                if (isDisabled()) return; // allow the default for saving HTML doc if no types are rendered\n\n                if (wereOpened) {\n                    save(event); // allow quick save\n                    return;\n                }\n\n                const filterOpened = filterSidebar.open(),\n                    optionsOpenend = open();\n\n                /* Make sure the collapses containing the save options are open and visible when user hits Ctrl + S.\n                    If neither needed opening, trigger saving. I.e. hitting Ctrl + S again should do it. */\n                if (!filterOpened && !optionsOpenend) save(event);\n                else event.preventDefault(); // prevent saving HTML page\n            }\n        };\n    })();\n\n    // displays pressed keys and highlights mouse cursor for teaching usage and other presentations\n    const controlDisplay = (function () {\n        let used = new Set(), enabled = false, wheelTimeout;\n\n        const alt = 'Alt',\n            display = getById('pressed-keys'), // a label displaying the keys being pressed and mouse wheel being scrolled\n            mouse = getById('mouse'), // a circle tracking the mouse to make following it easier\n\n            translateKey = key => key.length === 1 ? key.toUpperCase() : key,\n\n            updateDisplay = () => {\n                display.textContent = [...used].join(' + ');\n                display.classList.toggle('hidden', used.size === 0);\n            },\n\n            eventHandlers = {\n                keydown: event => {\n                    if (event.altKey) used.add(alt); // handle separately because Alt key alone doesn't trigger a key event\n                    used.add(translateKey(event.key));\n                    updateDisplay();\n                },\n\n                keyup: event => {\n                    setTimeout(() => {\n                        if (!event.altKey && used.has(alt)) used.delete(alt);\n                        used.delete(translateKey(event.key));\n                        updateDisplay();\n                    }, 500);\n                },\n\n                wheel: event => {\n                    const label = 'wheel ' + (event.deltaY < 0 ? 'up' : 'down'),\n                        wasUsed = used.has(label);\n\n                    if (wasUsed) {\n                        if (wheelTimeout) clearTimeout(wheelTimeout);\n                    } else {\n                        used.add(label);\n                        updateDisplay();\n                    }\n\n                    // automatically remove\n                    wheelTimeout = setTimeout(() => {\n                        used.delete(label);\n                        updateDisplay();\n                        wheelTimeout = undefined;\n                    }, 500);\n                },\n\n                mousemove: event => {\n                    mouse.style.top = event.clientY + 'px';\n                    mouse.style.left = event.clientX + 'px';\n                },\n\n                mousedown: () => { mouse.classList.add('down'); },\n                mouseup: () => { setTimeout(() => { mouse.classList.remove('down'); }, 300); }\n            };\n\n        return {\n            toggle: () => {\n                enabled = !enabled;\n\n                if (enabled) {\n                    mouse.hidden = false;\n\n                    for (let [event, handler] of Object.entries(eventHandlers))\n                        document.addEventListener(event, handler);\n                } else {\n                    mouse.hidden = true;\n\n                    for (let [event, handler] of Object.entries(eventHandlers))\n                        document.removeEventListener(event, handler);\n\n                    used.clear();\n                    updateDisplay();\n                }\n            }\n        };\n    })();\n\n    // key bindings\n    document.onkeydown = async (event) => {\n        const arrowUp = 'ArrowUp', arrowDown = 'ArrowDown';\n\n        // support Cmd key as alternative on Mac, see https://stackoverflow.com/a/5500536\n        if (event.ctrlKey || event.metaKey) {\n            switch (event.key) {\n                case 'b': filterSidebar.toggle(); return;\n                case 'k':\n                    event.preventDefault();\n                    filterSidebar.open();\n                    typeSelector.focusFilter();\n                    return;\n                case 's': exportOptions.quickSave(event); return;\n                case 'c': exportOptions.copy(event); return;\n                case 'i':\n                    event.preventDefault();\n                    controlDisplay.toggle();\n                    return;\n                case 'ArrowLeft': layoutDirection.set('RL', event); return;\n                case 'ArrowRight': layoutDirection.set('LR', event); return;\n                case arrowUp: layoutDirection.set('BT', event); return;\n                case arrowDown: layoutDirection.set('TB', event); return;\n                case '0': output.resetZoomAndPan(); return;\n            }\n        }\n\n        if (event.altKey) { // naturally triggered by Mac's option key as well\n            // enable moving selected types up and down using arrow keys while holding [Alt]\n            const upOrDown = event.key === arrowUp ? true : event.key === arrowDown ? false : null;\n\n            if (upOrDown !== null) {\n                typeSelector.focus();\n                typeSelector.moveSelection(upOrDown);\n                event.preventDefault();\n                return;\n            }\n\n            // pulse-animate elements with helping title attributes to point them out\n            if (event.key === 'i') {\n                event.preventDefault();\n                const pulsing = 'pulsing';\n\n                for (let element of document.querySelectorAll('[title],:has(title)')) {\n                    element.addEventListener('animationend', () => { element.classList.remove(pulsing); }, { once: true });\n                    element.classList.add(pulsing);\n                }\n            }\n        }\n    };\n\n    // rewrite help replacing references to 'Ctrl' with 'Cmd' for Mac users\n    if (/(Mac)/i.test(navigator.userAgent)) {\n        const ctrl = /Ctrl/mg,\n            replace = source => source.replaceAll(ctrl, '⌘');\n\n        for (let titled of document.querySelectorAll('[title]'))\n            if (ctrl.test(titled.title)) titled.title = replace(titled.title);\n\n        for (let titled of document.querySelectorAll('[data-title]'))\n            if (ctrl.test(titled.dataset.title)) titled.dataset.title = replace(titled.dataset.title);\n\n        for (let element of getById('info').querySelectorAll('*')) {\n            const text = element.innerText || element.textContent; // Get the text content of the element\n            if (ctrl.test(text)) element.innerHTML = replace(text);\n        }\n    }\n\n    collapse.initToggles();\n    mermaidExtensions.init({ startOnLoad: false }); // initializes mermaid as well\n    typeSelector.focus(); // focus type filter initially to enable keyboard input\n    await state.restore();\n})();\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/html/styles.css",
    "content": "@keyframes fadeIn {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n@keyframes fadeOut {\n  from {\n    opacity: 1;\n  }\n  to {\n    opacity: 0;\n  }\n}\nbody {\n  font-family: system-ui, sans-serif;\n  background: #4e54c8;\n  background-image: linear-gradient(to left, #8f94fb, #4e54c8);\n}\ninput[type=text] {\n  border-radius: 3px;\n}\nbutton {\n  border-radius: 3px;\n  background-color: #aad;\n  border: none;\n  color: #117;\n  cursor: pointer;\n}\nbutton.icon {\n  font-size: 1em;\n  background-color: transparent;\n}\nbutton:disabled {\n  opacity: 0.5;\n}\n[type=checkbox],\n[type=radio] {\n  cursor: pointer;\n}\n[type=checkbox] ~ label,\n[type=radio] ~ label {\n  cursor: pointer;\n}\nfieldset {\n  border-radius: 5px;\n}\nselect {\n  border: none;\n  border-radius: 3px;\n  background-color: rgba(0, 0, 0, calc(3/16 * 1));\n  color: whitesmoke;\n}\nselect option:checked {\n  background-color: rgba(0, 0, 0, calc(3/16 * 1));\n  color: darkorange;\n}\n.flx:not([hidden]) {\n  display: flex;\n}\n.flx:not([hidden]).col {\n  flex-direction: column;\n}\n.flx:not([hidden]).spaced {\n  justify-content: space-between;\n}\n.flx:not([hidden]).gap {\n  gap: 0.5em;\n}\n.flx:not([hidden]).aligned {\n  align-items: center;\n}\n.flx:not([hidden]) .grow {\n  flex-grow: 1;\n}\n.collapse.vertical {\n  max-height: 0;\n  overflow: hidden;\n  transition: max-height ease-in-out 0.5s;\n}\n.collapse.vertical.open {\n  max-height: 100vh;\n}\n.collapse.horizontal {\n  max-width: 0;\n  padding: 0;\n  margin: 0;\n  transition: all ease-in-out 0.5s;\n  overflow: hidden;\n}\n.collapse.horizontal.open {\n  padding: revert;\n  max-width: 100vw;\n}\n.toggle,\n[data-toggles] {\n  cursor: pointer;\n}\n.container {\n  position: absolute;\n  inset: 0;\n  margin: 0;\n}\n.scndry {\n  font-size: smaller;\n}\n.mano-a-borsa {\n  transform: rotate(95deg);\n  cursor: pointer;\n}\n.mano-a-borsa:after {\n  content: '🤏';\n}\n.trawl-net {\n  transform: rotate(180deg) translateY(-2px);\n  display: inline-block;\n}\n.trawl-net:after {\n  content: '🥅';\n}\n.torch {\n  display: inline-block;\n}\n.torch:after {\n  content: '🔦';\n}\n.pulsing {\n  animation: whiteBoxShadowPulse 2s 3;\n}\n@keyframes whiteBoxShadowPulse {\n  0% {\n    box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);\n  }\n  5% {\n    box-shadow: 0 0 0 15px rgba(255, 255, 255, 0.5);\n  }\n  50% {\n    box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.1);\n  }\n  90% {\n    box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);\n  }\n}\n#content {\n  height: 100%;\n  position: relative;\n}\n#filter {\n  max-width: 0;\n  transition: max-width ease-in-out 0.5s;\n  overflow: hidden;\n  background-color: rgba(0, 0, 0, calc(3/16 * 1));\n  color: whitesmoke;\n}\n#filter.open {\n  max-width: 15em;\n  overflow: auto;\n}\n#filter.resizing {\n  transition: none;\n}\n#filter > * {\n  margin: 0.3em 0.3em 0;\n}\n#filter > *:last-child {\n  margin-bottom: 0.3em;\n}\n#filter #pre-filter-types {\n  min-width: 3em;\n}\n#filter [data-toggles=\"#info\"] .torch {\n  transform: rotate(-90deg);\n  transition: transform 0.5s;\n}\n#filter [data-toggles=\"#info\"][aria-expanded=true] .torch {\n  transform: rotate(-255deg);\n}\n#filter #info {\n  overflow: auto;\n  background-color: rgba(255, 255, 255, calc(1/16 * 2));\n}\n#filter #info a.toggle {\n  color: whitesmoke;\n}\n#filter #info a.toggle img {\n  height: 1em;\n}\n#filter #type-select {\n  overflow: auto;\n}\n#filter #inheritance {\n  padding: 0.1em 0.75em 0.2em;\n}\n#filter #direction [type=radio] {\n  display: none;\n}\n#filter #direction [type=radio]:checked + label {\n  background-color: rgba(255, 255, 255, calc(1/16 * 4));\n}\n#filter #direction label {\n  flex-grow: 1;\n  text-align: center;\n  margin: -1em 0 -0.7em;\n  padding-top: 0.2em;\n}\n#filter #direction label:first-of-type {\n  margin-left: -0.8em;\n  border-top-left-radius: 5px;\n  border-bottom-left-radius: 5px;\n}\n#filter #direction label:last-of-type {\n  margin-right: -0.8em;\n  border-top-right-radius: 5px;\n  border-bottom-right-radius: 5px;\n}\n#filter #actions {\n  margin-top: 1em;\n  justify-content: space-between;\n}\n#filter #actions #render {\n  font-weight: bold;\n}\n#filter #exportOptions {\n  overflow: auto;\n  background-color: rgba(255, 255, 255, calc(1/16 * 2));\n}\n#filter #exportOptions #save {\n  margin-right: 0.5em;\n}\n#filter #exportOptions #dimensions fieldset {\n  padding: 0.5em;\n}\n#filter #exportOptions #dimensions fieldset .scale-size {\n  margin-left: 0.5em;\n}\n#filter #exportOptions #dimensions fieldset .scale-size #scale-size {\n  width: 2.5em;\n  margin: 0 0.2em;\n}\n#filter-toggle {\n  padding: 0;\n  border-radius: 0;\n  background-color: #117;\n  color: whitesmoke;\n}\n#output {\n  overflow: auto;\n}\n#output > svg {\n  cursor: grab;\n}\n#output > svg:active {\n  cursor: grabbing;\n}\n#output .edgeLabels .edgeTerminals .edgeLabel {\n  color: whitesmoke;\n}\n#output .edgeLabels .edgeLabel {\n  border-radius: 3px;\n}\n#output .edgeLabels .edgeLabel .edgeLabel[title] {\n  color: darkgoldenrod;\n}\n#output path.relation {\n  stroke: whitesmoke;\n}\n#output g.nodes > g {\n  cursor: pointer;\n}\n#output g.nodes > g > rect {\n  rx: 5px;\n  ry: 5px;\n}\n#output g.nodes g.label .nodeLabel[title] {\n  color: darkgoldenrod;\n}\n#about {\n  position: absolute;\n  bottom: 2em;\n  right: 2em;\n  align-items: end;\n}\n#about #toaster {\n  margin-right: 2.8em;\n}\n#about #toaster span {\n  animation: 0.5s ease-in fadeIn;\n  border-radius: 0.5em;\n  padding: 0.5em;\n  background-color: rgba(0, 0, 0, calc(3/16 * 2));\n  color: whitesmoke;\n}\n#about #toaster span.leaving {\n  animation: 1s ease-in-out fadeOut;\n}\n#about .build-info {\n  align-items: end;\n  height: 2.3em;\n  border-radius: 7px;\n  background-color: rgba(0, 0, 0, calc(3/16 * 3));\n  color: whitesmoke;\n}\n#about .build-info > * {\n  height: 100%;\n}\n#about .build-info #build-info {\n  text-align: right;\n}\n#about .build-info #build-info > * {\n  padding: 0 0.5em;\n}\n#about .build-info #build-info a {\n  color: whitesmoke;\n}\n#about .build-info #build-info a:not(.project) {\n  text-decoration: none;\n}\n#about .build-info #build-info a span {\n  display: inline-block;\n}\n#pressed-keys {\n  position: fixed;\n  left: 50%;\n  transform: translateX(-50%);\n  font-size: 3em;\n  bottom: 1em;\n  opacity: 1;\n  border-radius: 0.5em;\n  padding: 0.5em;\n  background-color: rgba(0, 0, 0, calc(3/16 * 2));\n  color: whitesmoke;\n}\n#pressed-keys.hidden {\n  transition: opacity 0.5s ease-in-out;\n  opacity: 0;\n}\n#mouse {\n  position: fixed;\n  transform: translateX(-50%) translateY(-50%);\n  height: 2em;\n  width: 2em;\n  pointer-events: none;\n  z-index: 9999;\n  border-radius: 1em;\n  border: solid 0.1em yellow;\n}\n#mouse.down {\n  background-color: #ff08;\n}\n/* hide stuff in print view */\n@media print {\n  #filter,\n  #filter-toggle,\n  #about,\n  img,\n  .bubbles {\n    display: none;\n  }\n}\n/* ANIMATED BACKGROUND, from https://codepen.io/alvarotrigo/pen/GRvYNax\n    found in https://alvarotrigo.com/blog/animated-backgrounds-css/ */\n@keyframes rotateUp {\n  0% {\n    transform: translateY(0) rotate(0deg);\n    opacity: 1;\n    border-radius: 100%;\n  }\n  100% {\n    transform: translateY(-150vh) rotate(720deg);\n    opacity: 0;\n    border-radius: 0;\n  }\n}\n.bubbles {\n  overflow: hidden;\n}\n.bubbles li {\n  position: absolute;\n  display: block;\n  list-style: none;\n  width: 20px;\n  height: 20px;\n  background: rgba(255, 255, 255, 0.2);\n  animation: rotateUp 25s linear infinite;\n  bottom: -150px;\n}\n.bubbles li:nth-child(1) {\n  left: 25%;\n  width: 80px;\n  height: 80px;\n  animation-delay: 0s;\n}\n.bubbles li:nth-child(2) {\n  left: 10%;\n  width: 20px;\n  height: 20px;\n  animation-delay: 2s;\n  animation-duration: 12s;\n}\n.bubbles li:nth-child(3) {\n  left: 70%;\n  width: 20px;\n  height: 20px;\n  animation-delay: 4s;\n}\n.bubbles li:nth-child(4) {\n  left: 40%;\n  width: 60px;\n  height: 60px;\n  animation-delay: 0s;\n  animation-duration: 18s;\n}\n.bubbles li:nth-child(5) {\n  left: 65%;\n  width: 20px;\n  height: 20px;\n  animation-delay: 0s;\n}\n.bubbles li:nth-child(6) {\n  left: 75%;\n  width: 110px;\n  height: 110px;\n  animation-delay: 3s;\n}\n.bubbles li:nth-child(7) {\n  left: 35%;\n  width: 150px;\n  height: 150px;\n  animation-delay: 7s;\n}\n.bubbles li:nth-child(8) {\n  left: 50%;\n  width: 25px;\n  height: 25px;\n  animation-delay: 15s;\n  animation-duration: 45s;\n}\n.bubbles li:nth-child(9) {\n  left: 20%;\n  width: 15px;\n  height: 15px;\n  animation-delay: 2s;\n  animation-duration: 35s;\n}\n.bubbles li:nth-child(10) {\n  left: 85%;\n  width: 150px;\n  height: 150px;\n  animation-delay: 0s;\n  animation-duration: 11s;\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/html/styles.less",
    "content": "@darkBlue: #117;\n\n@keyframes fadeIn {\n    from {\n        opacity: 0;\n    }\n\n    to {\n        opacity: 1;\n    }\n}\n\n@keyframes fadeOut {\n    from {\n        opacity: 1;\n    }\n\n    to {\n        opacity: 0;\n    }\n}\n\n.clickable() {\n    cursor: pointer;\n}\n\n.useBrightText() {\n    color: whitesmoke;\n}\n\n.colorLabelWithDocs() {\n    color: darkgoldenrod;\n}\n\n.darkenBg(@times: 1) {\n    background-color: rgba(0,0,0, calc(3/16 * @times));\n}\n\n.brightenBg(@times: 1) {\n    background-color: rgba(255,255,255, calc(1/16 * @times));\n}\n\nbody {\n    font-family: system-ui, sans-serif;\n    background: #4e54c8;\n    background-image: linear-gradient(to left, #8f94fb, #4e54c8);\n}\n\ninput[type=text] {\n    border-radius: 3px;\n}\n\nbutton {\n    border-radius: 3px;\n    background-color: #aad;\n    border: none;\n    color: @darkBlue;\n    .clickable;\n\n    &.icon {\n        font-size: 1em;\n        background-color: transparent;\n    }\n\n    &:disabled {\n        opacity: .5;\n    }\n}\n\n[type=checkbox], [type=radio] {\n    .clickable;\n\n    & ~ label {\n        .clickable;\n    }\n}\n\nfieldset {\n    border-radius: 5px;\n}\n\nselect {\n    border: none;\n    border-radius: 3px;\n    .darkenBg;\n    .useBrightText;\n\n    option:checked {\n        .darkenBg;\n        color: darkorange;\n    }\n}\n\n.flx:not([hidden]) {\n    display: flex;\n\n    &.col {\n        flex-direction: column;\n    }\n\n    &.spaced {\n        justify-content: space-between;\n    }\n\n    &.gap {\n        gap: .5em;\n    }\n\n    &.aligned {\n        align-items: center;\n    }\n\n    .grow {\n        flex-grow: 1;\n    }\n}\n\n.collapse {\n    &.vertical {\n        max-height: 0;\n        overflow: hidden;\n        transition: max-height ease-in-out .5s;\n\n        &.open {\n            max-height: 100vh;\n        }\n    }\n\n    &.horizontal {\n        max-width: 0;\n        padding: 0;\n        margin: 0;\n        transition: all ease-in-out .5s;\n        overflow: hidden;\n\n        &.open {\n            padding: revert;\n            max-width: 100vw;\n        }\n    }\n}\n\n.toggle, [data-toggles] {\n    .clickable;\n}\n\n.container {\n    position: absolute;\n    inset: 0;\n    margin: 0;\n}\n\n.scndry {\n    font-size: smaller;\n}\n\n.mano-a-borsa {\n    transform: rotate(95deg);\n    .clickable;\n\n    &:after {\n        content: '🤏';\n    }\n}\n\n.trawl-net {\n    transform: rotate(180deg) translateY(-2px);\n    display: inline-block;\n\n    &:after {\n        content: '🥅';\n    }\n}\n\n.torch {\n    display: inline-block;\n\n    &:after {\n        content: '🔦';\n    }\n}\n\n.pulsing {\n    animation: whiteBoxShadowPulse 2s 3;\n}\n\n@keyframes whiteBoxShadowPulse {\n    0% {\n        box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);\n    }\n\n    5% {\n        box-shadow: 0 0 0 15px rgba(255, 255, 255, 0.5);\n    }\n\n    50% {\n        box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.1);\n    }\n\n    90% {\n        box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);\n    }\n}\n\n#content {\n    height: 100%;\n    position: relative;\n}\n\n#filter {\n    max-width: 0;\n    transition: max-width ease-in-out .5s;\n    overflow: hidden;\n    .darkenBg;\n    .useBrightText;\n\n    &.open {\n        max-width: 15em;\n        overflow: auto;\n    }\n\n    &.resizing {\n        transition: none;\n    }\n\n    > * {\n        margin: .3em .3em 0;\n\n        &:last-child {\n            margin-bottom: .3em;\n        }\n    }\n\n    #pre-filter-types {\n        min-width: 3em;\n    }\n\n    [data-toggles=\"#info\"] {\n        .torch {\n            transform: rotate(-90deg);\n            transition: transform .5s;\n        }\n\n        &[aria-expanded=true] {\n            .torch {\n                transform: rotate(-255deg);\n            }\n        }\n    }\n\n    #info {\n        overflow: auto;\n        .brightenBg(2);\n\n        a.toggle {\n            .useBrightText;\n\n            img {\n                height: 1em;\n            }\n        }\n    }\n\n    #type-select {\n        overflow: auto;\n    }\n\n    #inheritance {\n        padding: .1em .75em .2em;\n    }\n\n    #direction {\n        [type=radio] {\n            display: none;\n\n            &:checked + label {\n                .brightenBg(4);\n            }\n        }\n\n        label {\n            flex-grow: 1;\n            text-align: center;\n            margin: -1em 0 -.7em;\n            padding-top: .2em;\n\n            &:first-of-type {\n                margin-left: -.8em;\n                border-top-left-radius: 5px;\n                border-bottom-left-radius: 5px;\n            }\n\n            &:last-of-type {\n                margin-right: -.8em;\n                border-top-right-radius: 5px;\n                border-bottom-right-radius: 5px;\n            }\n        }\n    }\n\n    #actions {\n        margin-top: 1em;\n        justify-content: space-between;\n\n        #render {\n            font-weight: bold;\n        }\n    }\n\n    #exportOptions {\n        overflow: auto;\n        .brightenBg(2);\n\n        #save {\n            margin-right: .5em;\n        }\n\n        #dimensions fieldset {\n            padding: .5em;\n\n            .scale-size {\n                margin-left: .5em;\n\n                #scale-size {\n                    width: 2.5em;\n                    margin: 0 .2em;\n                }\n            }\n        }\n    }\n}\n\n#filter-toggle {\n    padding: 0;\n    border-radius: 0;\n    background-color: @darkBlue;\n    .useBrightText;\n}\n\n#output {\n    overflow: auto;\n\n    > svg {\n        cursor: grab;\n\n        &:active {\n            cursor: grabbing;\n        }\n    }\n\n    .edgeLabels {\n        .edgeTerminals .edgeLabel {\n            .useBrightText;\n        }\n\n        .edgeLabel {\n            border-radius: 3px;\n\n            .edgeLabel[title] {\n                .colorLabelWithDocs;\n            }\n        }\n    }\n\n    path.relation {\n        stroke: whitesmoke;\n    }\n\n    g.nodes {\n        > g {\n            .clickable;\n\n            > rect {\n                rx: 5px;\n                ry: 5px;\n            }\n        }\n\n        g.label .nodeLabel[title] {\n            .colorLabelWithDocs;\n        }\n    }\n}\n\n#about {\n    position: absolute;\n    bottom: 2em;\n    right: 2em;\n    align-items: end;\n    @logoWidth: 2.3em;\n\n    #toaster {\n        margin-right: @logoWidth + .5em;\n\n        span {\n            animation: .5s ease-in fadeIn;\n            border-radius: .5em;\n            padding: .5em;\n            .darkenBg(2);\n            .useBrightText;\n\n            &.leaving {\n                animation: 1s ease-in-out fadeOut;\n            }\n        }\n    }\n\n    .build-info {\n        align-items: end;\n        height: @logoWidth;\n        border-radius: 7px;\n        .darkenBg(3);\n        .useBrightText;\n\n        > * {\n            height: 100%;\n        }\n\n        #build-info {\n            text-align: right;\n\n            > * {\n                padding: 0 .5em;\n            }\n\n            a {\n                .useBrightText;\n\n                &:not(.project) {\n                    text-decoration: none;\n                }\n\n                span {\n                    display: inline-block;\n                }\n            }\n        }\n    }\n}\n\n#pressed-keys {\n    position: fixed;\n    left: 50%;\n    transform: translateX(-50%);\n    font-size: 3em;\n    bottom: 1em;\n    opacity: 1;\n    border-radius: .5em;\n    padding: .5em;\n    .darkenBg(2);\n    .useBrightText;\n\n    &.hidden {\n        transition: opacity 0.5s ease-in-out;\n        opacity: 0;\n    }\n}\n\n#mouse {\n    position: fixed;\n    transform: translateX(-50%) translateY(-50%);\n    height: 2em;\n    width: 2em;\n    pointer-events: none;\n    z-index: 9999;\n    border-radius: 1em;\n    border: solid .1em yellow;\n\n    &.down {\n        background-color: #ff08;\n    }\n}\n\n/* hide stuff in print view */\n@media print {\n    #filter, #filter-toggle, #about, img, .bubbles {\n        display: none;\n    }\n}\n\n/* ANIMATED BACKGROUND, from https://codepen.io/alvarotrigo/pen/GRvYNax\n    found in https://alvarotrigo.com/blog/animated-backgrounds-css/ */\n\n@keyframes rotateUp {\n    0% {\n        transform: translateY(0) rotate(0deg);\n        opacity: 1;\n        border-radius: 100%;\n    }\n\n    100% {\n        transform: translateY(-150vh) rotate(720deg);\n        opacity: 0;\n        border-radius: 0;\n    }\n}\n\n.bubbles {\n    overflow: hidden;\n\n    li {\n        position: absolute;\n        display: block;\n        list-style: none;\n        width: 20px;\n        height: 20px;\n        background: rgba(255, 255, 255, .2);\n        animation: rotateUp 25s linear infinite;\n        bottom: -150px;\n\n        &:nth-child(1) {\n            left: 25%;\n            width: 80px;\n            height: 80px;\n            animation-delay: 0s;\n        }\n\n        &:nth-child(2) {\n            left: 10%;\n            width: 20px;\n            height: 20px;\n            animation-delay: 2s;\n            animation-duration: 12s;\n        }\n\n        &:nth-child(3) {\n            left: 70%;\n            width: 20px;\n            height: 20px;\n            animation-delay: 4s;\n        }\n\n        &:nth-child(4) {\n            left: 40%;\n            width: 60px;\n            height: 60px;\n            animation-delay: 0s;\n            animation-duration: 18s;\n        }\n\n        &:nth-child(5) {\n            left: 65%;\n            width: 20px;\n            height: 20px;\n            animation-delay: 0s;\n        }\n\n        &:nth-child(6) {\n            left: 75%;\n            width: 110px;\n            height: 110px;\n            animation-delay: 3s;\n        }\n\n        &:nth-child(7) {\n            left: 35%;\n            width: 150px;\n            height: 150px;\n            animation-delay: 7s;\n        }\n\n        &:nth-child(8) {\n            left: 50%;\n            width: 25px;\n            height: 25px;\n            animation-delay: 15s;\n            animation-duration: 45s;\n        }\n\n        &:nth-child(9) {\n            left: 20%;\n            width: 15px;\n            height: 15px;\n            animation-delay: 2s;\n            animation-duration: 35s;\n        }\n\n        &:nth-child(10) {\n            left: 85%;\n            width: 150px;\n            height: 150px;\n            animation-delay: 0s;\n            animation-duration: 11s;\n        }\n    }\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/MermaidDiagrammer/html/template.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\" />\n    <title>{{SourceAssemblyName}} class diagrammer - ILSpy</title>\n    <link rel=\"icon\" type=\"image/x-icon\" href=\"ILSpy.ico\" />\n    <link rel=\"stylesheet\" href=\"styles.css\" type=\"text/css\" />\n    <style id=\"filter-width\"></style>\n</head>\n<body class=\"container\">\n\n    <!-- for animated background -->\n    <ul class=\"bubbles container\">\n        <li></li>\n        <li></li>\n        <li></li>\n        <li></li>\n        <li></li>\n        <li></li>\n        <li></li>\n        <li></li>\n        <li></li>\n        <li></li>\n    </ul>\n\n    <div id=\"content\" class=\"flx\">\n        <form id=\"filter\" class=\"flx col open\">\n            <div class=\"flx gap\">\n                <input id=\"pre-filter-types\" placeholder=\"pre-filter\" class=\"grow\"\n                       title=\"🐋 I sift through the types for you.&#10;Feed me vanilla 🦐 plain text or ES/JS flavored 🍤 RegEx.&#10;🔭 Focus me with [Ctrl + K]. \" />\n                <label for=\"type-select\" class=\"grow\">types</label>\n                <button type=\"button\" class=\"icon\" data-toggles=\"#info\" title=\"🕯️ Shed light on the type selection\"><span class=\"torch\"></span></button>\n            </div>\n\n            <div id=\"info\" class=\"scndry vertical collapse\">\n                <p>\n                    The <big>type picker</big> is ✜ focused when you open the app.\n                    You can just <b>⌨️ key in the first letter/s</b> of the type\n                    you want to start your diagram with and <b>hit [Enter] to render</b> it.\n                </p>\n                <p>\n                    After rendering you can 👆 <b>tap types</b> on the diagram\n                    to update your selection and redraw.\n                    This allows you to <b>explore the domain</b> along relations.\n                </p>\n                <p>\n                    Don't forget that you can hold [Shift] to <b>↕ range-select</b>\n                    and [Ctrl] to <b>± add to or subtract from</b> your selection.\n                </p>\n                <p>\n                    Note that the diagram has a 🟈 <b>layout direction</b> -\n                    i.e. it depends on how you <b>⇅ sort selected types</b> using [Alt + Arrow Up|Down].\n                </p>\n                <p>\n                    Changing the type selection or rendering options\n                    updates the URL in the location bar. That means you can\n                    <ul>\n                        <li><b>🔖 bookmark or 📣 share the URL</b> to your diagram with whoever has access to this diagrammer,</li>\n                        <li><b>access 🕔 earlier diagrams</b> recorded in your 🧾 browser history and</li>\n                        <li><b>⇥ restore your type selection</b> to the picker from the URL using ⟳ Refresh [F5] if you lose it.</li>\n                    </ul>\n                </p>\n                <h3>Looking for help with something else?</h3>\n                <p>\n                    <b>Stop and spot the tooltips.</b> 🌷 They'll give you more info where necessary.\n                    Get a hint for elements with helping tooltips using [Alt + i].\n                </p>\n                <p>Alternatively, find helpful links to the docs and discussions in the\n                    <a href=\"#build-info\" class=\"toggle\">build info <img src=\"ILSpy.ico\" /> ➪</a></p>\n                <p>If you find this helpful and want to share your 📺 screen and 🎓 wisdom on how it works\n                    with a 🦗 newcomer, try toggling <b>presentation mode</b> using [Ctrl + i].</p>\n            </div>\n\n            <select multiple id=\"type-select\" class=\"grow\" title=\"🥢 pick types to include in your diagram\"></select>\n\n            <fieldset id=\"inheritance\" class=\"scndry flx\" title=\"You may find these options useful to reason about type inheritance - probably less so when looking at entity relations.\">\n                <legend>show inherited</legend>\n\n                <span class=\"scndry flx\" title=\"Render direct base types.\">\n                    <input type=\"checkbox\" id=\"show-base-types\" checked />\n                    <label for=\"show-base-types\">types</label>\n                </span>\n                <span class=\"scndry flx\" title=\"Render direct interfaces.\">\n                    <input type=\"checkbox\" id=\"show-interfaces\" checked />\n                    <label for=\"show-interfaces\">interfaces</label>\n                </span>\n                <span class=\"scndry flx\" title=\"Render members inherited from ancestor types - unless those are also selected and rendered in detail.\">\n                    <input type=\"checkbox\" id=\"show-inherited-members\" checked />\n                    <label for=\"show-inherited-members\">members</label>\n                </span>\n            </fieldset>\n\n            <fieldset id=\"direction\" class=\"scndry flx\" title=\"[Ctrl + arrow keys] You may want to change this depending on your screen or printer and the size of the diagram.\">\n                <legend>layout direction</legend>\n                <input type=\"radio\" name=\"direction\" value=\"RL\" id=\"dir-rl\" />\n                <label for=\"dir-rl\">⮘</label>\n                <input type=\"radio\" name=\"direction\" value=\"TB\" id=\"dir-tb\" />\n                <label for=\"dir-tb\">⮛</label>\n                <input type=\"radio\" name=\"direction\" value=\"BT\" id=\"dir-bt\" />\n                <label for=\"dir-bt\">⮙</label>\n                <input type=\"radio\" name=\"direction\" value=\"LR\" id=\"dir-lr\" checked />\n                <label for=\"dir-lr\">⮚</label>\n            </fieldset>\n\n            <div id=\"actions\" class=\"flx spaced\">\n                <button title=\"Render the selected types. [Enter] with the side bar in focus will do.\"\n                        type=\"submit\" id=\"render\" disabled><span class=\"trawl-net\"></span> Cast the diagram</button>\n                <button type=\"button\" class=\"icon\" data-toggles=\"#exportOptions\" id=\"exportOptions-toggle\" hidden title=\"toggle 🥡 export options\">🎣</button>\n            </div>\n\n            <div id=\"exportOptions\" class=\"scndry vertical collapse aligned spaced flx gap col\">\n\n                <div class=\"flx gap\" title=\"Note that you can also use your browser's Print function [Ctrl + P] to export to PDF or paper or split up the diagram into multiple pages.\">\n                    <button type=\"button\" id=\"save\" data-assembly=\"{{SourceAssemblyName}}\" title=\"[Ctrl + S] Saves the diagram in the selected format using a generated name.\">💾 Save</button>\n                    <label>or</label>\n                    <button type=\"button\" id=\"copy\" title=\"[Ctrl + C] Copies the diagram in the selected format to your clipboard for you to paste directly into a messenger, word- or image processor.\">📋 Copy to clipboard</button>\n                </div>\n\n                <div class=\"flx\">\n                    <label>as</label>\n                    <span class=\"flx\" title=\"Exports the diagram as SVG to render in an HTML document or SVG-enabled word processor.\">\n                        <input type=\"radio\" name=\"saveAs\" value=\"svg\" id=\"saveAs-svg\" />\n                        <label for=\"saveAs-svg\">svg</label>\n                    </span>\n                    <span class=\"flx\" title=\"Exports the diagram as a base-64 encoded PNG.\">\n                        <input type=\"radio\" name=\"saveAs\" value=\"png\" id=\"saveAs-png\" checked />\n                        <label for=\"saveAs-png\">png</label>\n                    </span>\n                    <span class=\"flx\" title=\"Exports the mermaid syntax for the diagram.\">\n                        <input type=\"radio\" name=\"saveAs\" value=\"mmd\" id=\"saveAs-mmd\" />\n                        <label for=\"saveAs-mmd\">mmd</label>\n                    </span>\n                </div>\n\n                <div id=\"dimensions\" class=\"vertical open collapse\">\n                    <fieldset title=\"Applied when saving and in (unscalable) image format. Note these settings indirectly determine the resolution.\">\n                        <legend>png dimensions</legend>\n\n                        <div class=\"flx\">\n                            <input type=\"radio\" name=\"dimension\" value=\"auto\" id=\"dimension-current\" checked />\n                            <label for=\"dimension-current\">current</label>\n                            <input type=\"radio\" name=\"dimension\" value=\"scale\" id=\"dimension-scale\" />\n                            <label for=\"dimension-scale\">scale to fixed</label>\n                        </div>\n\n                        <div id=\"scale-controls\" class=\"flx aligned\">\n                            <input type=\"radio\" name=\"scale\" value=\"width\" id=\"scale-width\" checked disabled />\n                            <label for=\"scale-width\">width</label>\n                            <input type=\"radio\" name=\"scale\" value=\"height\" id=\"scale-height\" disabled />\n                            <label for=\"scale-height\">height</label>\n                            <div class=\"scale-size flx aligned\">\n                                <label for=\"scale-size\">of</label>\n                                <input type=\"text\" id=\"scale-size\" value=\"1080\" disabled />\n                                <label for=\"scale-size\">px</label>\n                            </div>\n                        </div>\n                    </fieldset>\n                </div>\n            </div>\n        </form>\n\n        <button type=\"button\" class=\"icon\" id=\"filter-toggle\" title=\"🧜‍♂️ Let me lay it out for you.&#10👆 Tap me to toggle the side bar [Ctrl + B].&#10;👌 Grab and drag me if you need ⇢ more space for the type selection.\">⥂</button>\n\n        <div id=\"output\" class=\"grow\" data-title=\"🧜‍♀️ I'm not your basic diagram.&#10;👆 Tap my types to toggle them.&#10;&#10;🔍 Zoom me with [Ctrl + mouse wheel].&#10;👌 Grab and drag me around to pan after.&#10;🧽 Reset zoom and pan with [Ctrl + 0].\"></div>\n    </div>\n\n    <div id=\"about\" class=\"flx col gap\" title=\"🐙 build info and project links\">\n        <div id=\"toaster\" class=\"flx col gap\"></div>\n        <div class=\"build-info flx\">\n            <div id=\"build-info\" class=\"scndry horizontal collapse flx col\">\n                <span>built from {{SourceAssemblyName}} v{{SourceAssemblyVersion}} and mermaid.js from CDN\n                    <a target=\"_blank\" href=\"https://cdn.jsdelivr.net/npm/mermaid@11.4.0/dist/mermaid.min.js\" download=\"mermaid.min.js\"\n                        title=\"For off-line use, download a copy and save it in the diagrammer folder. At the bottom of the index.html you'll find a script with a reference to the mermaid CDN. Replace its 'src' with the file name of your local copy, e.g. 'mermaid.min.js'.\">📥</a>\n                </span>\n                <span>\n                    using <a class=\"project\" target=\"_blank\" href=\"{{RepoUrl}}#readme\" title=\"🤿 get learned and find out about or 🔱 fork the project\">ICSharpCode.ILSpyX</a> v{{BuilderVersion}}\n                    <a target=\"_blank\" href=\"{{RepoUrl}}/wiki/Diagramming\" title=\"the manual\">📜</a>\n                    <a target=\"_blank\" href=\"{{RepoUrl}}/discussions\" title=\"🤔 ask questions, share and discuss 💡 ideas\">💬</a>\n                    <a target=\"_blank\" href=\"{{RepoUrl}}/issues\" title=\"🦟 feed bugs to the fishes and request 🌱 new features\"><span class=\"mano-a-borsa\"></span></a>\n                    <a target=\"_blank\" href=\"{{RepoUrl}}/releases/latest\" title=\"☄️ download the latest bits to 🌊 generate better diagrammers\">🌩️</a>\n                </span>\n            </div>\n            <img data-toggles=\"#build-info\" src=\"ILSpy.ico\" />\n        </div>\n    </div>\n\n    <div id=\"pressed-keys\" class=\"hidden\"></div>\n    <div id=\"mouse\" hidden></div>\n\n    <script id=\"model\" type=\"application/json\">{{Model}}</script>\n    <script src=\"https://cdn.jsdelivr.net/npm/mermaid@11.4.0/dist/mermaid.min.js\"></script>\n    <script src=\"script.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/PackageReadme.md",
    "content": "## About\n\nICSharpCode.ILSpyX is the core cross-platform implemenation of [ILSpy](https://github.com/icsharpcode/ILSpy/) that can be reused to build alternate frontends more easily.\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/PdbProvider/DebugInfoUtils.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing System.Reflection.Metadata;\nusing System.Reflection.PortableExecutable;\nusing System.Runtime.InteropServices;\n\nusing ICSharpCode.Decompiler.DebugInfo;\nusing ICSharpCode.Decompiler.Metadata;\n\n#nullable enable\n\nnamespace ICSharpCode.ILSpyX.PdbProvider\n{\n\tpublic static class DebugInfoUtils\n\t{\n\t\tpublic static IDebugInfoProvider? LoadSymbols(PEFile module)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// try to open portable pdb file/embedded pdb info:\n\t\t\t\tif (TryOpenPortablePdb(module, out var provider, out var pdbFileName))\n\t\t\t\t{\n\t\t\t\t\treturn new PortableDebugInfoProvider(module.FileName, provider, MetadataReaderOptions.Default, pdbFileName);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// search for pdb in same directory as dll\n\t\t\t\t\tpdbFileName = Path.Combine(\n\t\t\t\t\t\tPath.GetDirectoryName(module.FileName)!,\n\t\t\t\t\t\tPath.GetFileNameWithoutExtension(module.FileName) + \".pdb\"\n\t\t\t\t\t);\n\t\t\t\t\tif (File.Exists(pdbFileName))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new MonoCecilDebugInfoProvider(module, pdbFileName);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (Exception ex) when (ex is BadImageFormatException || ex is COMException)\n\t\t\t{\n\t\t\t\t// Ignore PDB load errors\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static IDebugInfoProvider? FromFile(PEFile module, string pdbFileName)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(pdbFileName))\n\t\t\t\treturn null;\n\n\t\t\tStream? stream = OpenStream(pdbFileName);\n\t\t\tif (stream == null)\n\t\t\t\treturn null;\n\n\t\t\tif (stream.Read(buffer, 0, buffer.Length) == LegacyPDBPrefix.Length\n\t\t\t\t&& System.Text.Encoding.ASCII.GetString(buffer) == LegacyPDBPrefix)\n\t\t\t{\n\t\t\t\tstream.Position = 0;\n\t\t\t\treturn new MonoCecilDebugInfoProvider(module, pdbFileName);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tstream.Position = 0;\n\t\t\t\tvar provider = MetadataReaderProvider.FromPortablePdbStream(stream);\n\t\t\t\treturn new PortableDebugInfoProvider(module.FileName, provider, MetadataReaderOptions.Default, pdbFileName);\n\t\t\t}\n\t\t}\n\n\t\tconst string LegacyPDBPrefix = \"Microsoft C/C++ MSF 7.00\";\n\t\tstatic readonly byte[] buffer = new byte[LegacyPDBPrefix.Length];\n\n\t\tstatic bool TryOpenPortablePdb(PEFile module,\n\t\t\t[NotNullWhen(true)] out MetadataReaderProvider? provider,\n\t\t\t[NotNullWhen(true)] out string? pdbFileName)\n\t\t{\n\t\t\tprovider = null;\n\t\t\tpdbFileName = null;\n\t\t\tvar reader = module.Reader;\n\t\t\tforeach (var entry in reader.ReadDebugDirectory())\n\t\t\t{\n\t\t\t\tif (entry.IsPortableCodeView)\n\t\t\t\t{\n\t\t\t\t\treturn reader.TryOpenAssociatedPortablePdb(module.FileName, OpenStream,\n\t\t\t\t\t\tout provider, out pdbFileName);\n\t\t\t\t}\n\t\t\t\tif (entry.Type == DebugDirectoryEntryType.CodeView)\n\t\t\t\t{\n\t\t\t\t\tstring pdbDirectory = Path.GetDirectoryName(module.FileName)!;\n\t\t\t\t\tpdbFileName = Path.Combine(\n\t\t\t\t\t\tpdbDirectory, Path.GetFileNameWithoutExtension(module.FileName) + \".pdb\");\n\t\t\t\t\tStream? stream = OpenStream(pdbFileName);\n\t\t\t\t\tif (stream != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (stream.Read(buffer, 0, buffer.Length) == LegacyPDBPrefix.Length\n\t\t\t\t\t\t\t&& System.Text.Encoding.ASCII.GetString(buffer) == LegacyPDBPrefix)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstream.Position = 0;\n\t\t\t\t\t\tprovider = MetadataReaderProvider.FromPortablePdbStream(stream);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tstatic Stream? OpenStream(string fileName)\n\t\t{\n\t\t\tif (!File.Exists(fileName))\n\t\t\t\treturn null;\n\t\t\tvar memory = new MemoryStream();\n\t\t\tusing (var stream = File.OpenRead(fileName))\n\t\t\t\tstream.CopyTo(memory);\n\t\t\tmemory.Position = 0;\n\t\t\treturn memory;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/PdbProvider/MonoCecilDebugInfoProvider.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.DebugInfo;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Util;\n\nusing Mono.Cecil;\nusing Mono.Cecil.Pdb;\n\nusing SRM = System.Reflection.Metadata;\n\n#nullable enable\n\nnamespace ICSharpCode.ILSpyX.PdbProvider\n{\n\tpublic class MonoCecilDebugInfoProvider : IDebugInfoProvider\n\t{\n\t\treadonly Dictionary<SRM.MethodDefinitionHandle, (IList<SequencePoint> SequencePoints, IList<Variable> Variables)> debugInfo;\n\n\t\tpublic unsafe MonoCecilDebugInfoProvider(PEFile module, string pdbFileName, string? description = null)\n\t\t{\n\t\t\tif (module == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(module));\n\t\t\t}\n\n\t\t\tif (!module.Reader.IsEntireImageAvailable)\n\t\t\t{\n\t\t\t\tthrow new ArgumentException(\"This provider needs access to the full image!\");\n\t\t\t}\n\n\t\t\tthis.SourceFileName = pdbFileName ?? throw new ArgumentNullException(nameof(pdbFileName));\n\t\t\tthis.Description = description ?? $\"Loaded from PDB file: {pdbFileName}\";\n\n\t\t\tvar image = module.Reader.GetEntireImage();\n\t\t\tthis.debugInfo = new Dictionary<SRM.MethodDefinitionHandle, (IList<SequencePoint> SequencePoints, IList<Variable> Variables)>();\n\t\t\tusing (UnmanagedMemoryStream stream = new UnmanagedMemoryStream(image.Pointer, image.Length))\n\t\t\tusing (var moduleDef = ModuleDefinition.ReadModule(stream))\n\t\t\t{\n\t\t\t\tmoduleDef.ReadSymbols(new PdbReaderProvider().GetSymbolReader(moduleDef, pdbFileName));\n\n\t\t\t\tforeach (var method in module.Metadata.MethodDefinitions)\n\t\t\t\t{\n\t\t\t\t\tvar cecilMethod = moduleDef.LookupToken(MetadataTokens.GetToken(method)) as MethodDefinition;\n\t\t\t\t\tvar debugInfo = cecilMethod?.DebugInformation;\n\t\t\t\t\tif (debugInfo == null)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tIList<SequencePoint> sequencePoints = EmptyList<SequencePoint>.Instance;\n\t\t\t\t\tif (debugInfo.HasSequencePoints)\n\t\t\t\t\t{\n\t\t\t\t\t\tsequencePoints = new List<SequencePoint>(debugInfo.SequencePoints.Count);\n\t\t\t\t\t\tforeach (var point in debugInfo.SequencePoints)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsequencePoints.Add(new SequencePoint {\n\t\t\t\t\t\t\t\tOffset = point.Offset,\n\t\t\t\t\t\t\t\tStartLine = point.StartLine,\n\t\t\t\t\t\t\t\tStartColumn = point.StartColumn,\n\t\t\t\t\t\t\t\tEndLine = point.EndLine,\n\t\t\t\t\t\t\t\tEndColumn = point.EndColumn,\n\t\t\t\t\t\t\t\tDocumentUrl = point.Document.Url\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tvar variables = new List<Variable>();\n\t\t\t\t\tforeach (var scope in debugInfo.GetScopes())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!scope.HasVariables)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tforeach (var v in scope.Variables)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvariables.Add(new Variable(v.Index, v.Name));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis.debugInfo.Add(method, (sequencePoints, variables));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic string Description { get; }\n\n\t\tpublic string SourceFileName { get; }\n\n\t\tpublic IList<SequencePoint> GetSequencePoints(SRM.MethodDefinitionHandle handle)\n\t\t{\n\t\t\tif (!debugInfo.TryGetValue(handle, out var info))\n\t\t\t{\n\t\t\t\treturn EmptyList<SequencePoint>.Instance;\n\t\t\t}\n\n\t\t\treturn info.SequencePoints;\n\t\t}\n\n\t\tpublic IList<Variable> GetVariables(SRM.MethodDefinitionHandle handle)\n\t\t{\n\t\t\tif (!debugInfo.TryGetValue(handle, out var info))\n\t\t\t{\n\t\t\t\treturn EmptyList<Variable>.Instance;\n\t\t\t}\n\n\t\t\treturn info.Variables;\n\t\t}\n\n\t\tpublic bool TryGetName(SRM.MethodDefinitionHandle handle, int index, [NotNullWhen(true)] out string? name)\n\t\t{\n\t\t\tname = null;\n\t\t\tif (!debugInfo.TryGetValue(handle, out var info))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar variable = info.Variables.FirstOrDefault(v => v.Index == index);\n\t\t\tname = variable.Name;\n\t\t\treturn name != null;\n\t\t}\n\n\t\tpublic bool TryGetExtraTypeInfo(SRM.MethodDefinitionHandle method, int index, out PdbExtraTypeInfo extraTypeInfo)\n\t\t{\n\t\t\t// Mono.Cecil's WindowsPDB reader is unable to read tuple element names\n\t\t\t// and dynamic flags custom debug information.\n\t\t\textraTypeInfo = default;\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.DebugInfo;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Util;\n\nusing static ICSharpCode.Decompiler.Metadata.MetadataFile;\n\n#nullable enable\n\nnamespace ICSharpCode.ILSpyX.PdbProvider\n{\n\tpublic class PortableDebugInfoProvider : IDebugInfoProvider\n\t{\n\t\tstring? pdbFileName;\n\t\tstring moduleFileName;\n\t\treadonly MetadataReaderProvider provider;\n\t\tMetadataReaderOptions options;\n\t\tbool hasError;\n\n\t\tpublic bool IsEmbedded => pdbFileName == null;\n\n\t\tpublic PortableDebugInfoProvider(string moduleFileName, MetadataReaderProvider provider,\n\t\t\tMetadataReaderOptions options = MetadataReaderOptions.Default,\n\t\t\tstring? pdbFileName = null)\n\t\t{\n\t\t\tthis.moduleFileName = moduleFileName ?? throw new ArgumentNullException(nameof(moduleFileName));\n\t\t\tthis.provider = provider ?? throw new ArgumentNullException(nameof(provider));\n\t\t\tthis.options = options;\n\t\t\tthis.pdbFileName = pdbFileName;\n\t\t}\n\n\t\tpublic string Description {\n\t\t\tget {\n\t\t\t\tif (pdbFileName == null)\n\t\t\t\t{\n\t\t\t\t\tif (hasError)\n\t\t\t\t\t\treturn \"Error while loading the PDB stream embedded in this assembly\";\n\t\t\t\t\treturn \"Embedded in this assembly\";\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (hasError)\n\t\t\t\t\t\treturn $\"Error while loading portable PDB: {pdbFileName}\";\n\t\t\t\t\treturn $\"Loaded from portable PDB: {pdbFileName}\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic MetadataReader? GetMetadataReader()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\thasError = false;\n\t\t\t\treturn provider.GetMetadataReader();\n\t\t\t}\n\t\t\tcatch (BadImageFormatException)\n\t\t\t{\n\t\t\t\thasError = true;\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tcatch (IOException)\n\t\t\t{\n\t\t\t\thasError = true;\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tpublic string SourceFileName => pdbFileName ?? moduleFileName;\n\n\t\tpublic IList<Decompiler.DebugInfo.SequencePoint> GetSequencePoints(MethodDefinitionHandle method)\n\t\t{\n\t\t\tvar metadata = GetMetadataReader();\n\t\t\tif (metadata == null)\n\t\t\t\treturn EmptyList<Decompiler.DebugInfo.SequencePoint>.Instance;\n\t\t\tvar debugInfo = metadata.GetMethodDebugInformation(method);\n\t\t\tvar sequencePoints = new List<Decompiler.DebugInfo.SequencePoint>();\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tforeach (var point in debugInfo.GetSequencePoints())\n\t\t\t\t{\n\t\t\t\t\tstring documentFileName;\n\n\t\t\t\t\tif (!point.Document.IsNil)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar document = metadata.GetDocument(point.Document);\n\t\t\t\t\t\tdocumentFileName = metadata.GetString(document.Name);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tdocumentFileName = \"\";\n\t\t\t\t\t}\n\n\t\t\t\t\tsequencePoints.Add(new Decompiler.DebugInfo.SequencePoint() {\n\t\t\t\t\t\tOffset = point.Offset,\n\t\t\t\t\t\tStartLine = point.StartLine,\n\t\t\t\t\t\tStartColumn = point.StartColumn,\n\t\t\t\t\t\tEndLine = point.EndLine,\n\t\t\t\t\t\tEndColumn = point.EndColumn,\n\t\t\t\t\t\tDocumentUrl = documentFileName\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn sequencePoints;\n\t\t\t}\n\t\t\tcatch (BadImageFormatException)\n\t\t\t{\n\t\t\t\treturn EmptyList<Decompiler.DebugInfo.SequencePoint>.Instance;\n\t\t\t}\n\t\t}\n\n\t\tpublic IList<Variable> GetVariables(MethodDefinitionHandle method)\n\t\t{\n\t\t\tvar metadata = GetMetadataReader();\n\t\t\tvar variables = new List<Variable>();\n\t\t\tif (metadata == null)\n\t\t\t\treturn variables;\n\n\t\t\tforeach (var h in metadata.GetLocalScopes(method))\n\t\t\t{\n\t\t\t\tvar scope = metadata.GetLocalScope(h);\n\t\t\t\tforeach (var v in scope.GetLocalVariables())\n\t\t\t\t{\n\t\t\t\t\tvar var = metadata.GetLocalVariable(v);\n\t\t\t\t\tvariables.Add(new Variable(var.Index, metadata.GetString(var.Name)));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn variables;\n\t\t}\n\n\t\tpublic bool TryGetName(MethodDefinitionHandle method, int index, [NotNullWhen(true)] out string? name)\n\t\t{\n\t\t\tvar metadata = GetMetadataReader();\n\t\t\tname = null;\n\t\t\tif (metadata == null)\n\t\t\t\treturn false;\n\n\t\t\tforeach (var h in metadata.GetLocalScopes(method))\n\t\t\t{\n\t\t\t\tvar scope = metadata.GetLocalScope(h);\n\t\t\t\tforeach (var v in scope.GetLocalVariables())\n\t\t\t\t{\n\t\t\t\t\tvar var = metadata.GetLocalVariable(v);\n\t\t\t\t\tif (var.Index == index)\n\t\t\t\t\t{\n\t\t\t\t\t\tname = metadata.GetString(var.Name);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool TryGetExtraTypeInfo(MethodDefinitionHandle method, int index, out PdbExtraTypeInfo extraTypeInfo)\n\t\t{\n\t\t\tvar metadata = GetMetadataReader();\n\t\t\textraTypeInfo = default;\n\n\t\t\tif (metadata == null)\n\t\t\t\treturn false;\n\n\t\t\tLocalVariableHandle localVariableHandle = default;\n\t\t\tforeach (var h in metadata.GetLocalScopes(method))\n\t\t\t{\n\t\t\t\tvar scope = metadata.GetLocalScope(h);\n\t\t\t\tforeach (var v in scope.GetLocalVariables())\n\t\t\t\t{\n\t\t\t\t\tvar var = metadata.GetLocalVariable(v);\n\t\t\t\t\tif (var.Index == index)\n\t\t\t\t\t{\n\t\t\t\t\t\tlocalVariableHandle = v;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!localVariableHandle.IsNil)\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tforeach (var h in metadata.CustomDebugInformation)\n\t\t\t{\n\t\t\t\tvar cdi = metadata.GetCustomDebugInformation(h);\n\t\t\t\tif (cdi.Parent.IsNil || cdi.Parent.Kind != HandleKind.LocalVariable)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (localVariableHandle != (LocalVariableHandle)cdi.Parent)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (cdi.Value.IsNil || cdi.Kind.IsNil)\n\t\t\t\t\tcontinue;\n\t\t\t\tvar kind = metadata.GetGuid(cdi.Kind);\n\t\t\t\tif (kind == KnownGuids.TupleElementNames && extraTypeInfo.TupleElementNames is null)\n\t\t\t\t{\n\t\t\t\t\tvar reader = metadata.GetBlobReader(cdi.Value);\n\t\t\t\t\tvar list = new List<string?>();\n\t\t\t\t\twhile (reader.RemainingBytes > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Read a UTF8 null-terminated string\n\t\t\t\t\t\tint length = reader.IndexOf(0);\n\t\t\t\t\t\tstring s = reader.ReadUTF8(length);\n\t\t\t\t\t\t// Skip null terminator\n\t\t\t\t\t\treader.ReadByte();\n\t\t\t\t\t\tlist.Add(string.IsNullOrWhiteSpace(s) ? null : s);\n\t\t\t\t\t}\n\n\t\t\t\t\textraTypeInfo.TupleElementNames = list.ToArray();\n\t\t\t\t}\n\t\t\t\telse if (kind == KnownGuids.DynamicLocalVariables && extraTypeInfo.DynamicFlags is null)\n\t\t\t\t{\n\t\t\t\t\tvar reader = metadata.GetBlobReader(cdi.Value);\n\t\t\t\t\textraTypeInfo.DynamicFlags = new bool[reader.Length * 8];\n\t\t\t\t\tint j = 0;\n\t\t\t\t\twhile (reader.RemainingBytes > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tint b = reader.ReadByte();\n\t\t\t\t\t\tfor (int i = 1; i < 0x100; i <<= 1)\n\t\t\t\t\t\t\textraTypeInfo.DynamicFlags[j++] = (b & i) != 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (extraTypeInfo.TupleElementNames != null && extraTypeInfo.DynamicFlags != null)\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\treturn extraTypeInfo.TupleElementNames != null || extraTypeInfo.DynamicFlags != null;\n\t\t}\n\n\t\tpublic MetadataFile ToMetadataFile()\n\t\t{\n\t\t\tvar kind = IsEmbedded || Path.GetExtension(SourceFileName).Equals(\".pdb\", StringComparison.OrdinalIgnoreCase) ? MetadataFileKind.ProgramDebugDatabase : MetadataFileKind.Metadata;\n\t\t\treturn new MetadataFile(kind, SourceFileName, provider, options, 0, IsEmbedded);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Properties/AssemblyInfo.cs",
    "content": "#region Using directives\n\nusing System.Diagnostics.CodeAnalysis;\nusing System.Reflection;\nusing System.Runtime.InteropServices;\n\n#endregion\n\n// This sets the default COM visibility of types in the assembly to invisible.\n// If you need to expose a type to COM, use [ComVisible(true)] on that type.\n[assembly: ComVisible(false)]\n\n[assembly: AssemblyVersion(DecompilerVersionInfo.Major + \".\" + DecompilerVersionInfo.Minor + \".\" + DecompilerVersionInfo.Build + \".\" + DecompilerVersionInfo.Revision)]\n[assembly: AssemblyInformationalVersion(DecompilerVersionInfo.FullVersionWithCommitHash)]\n\n[assembly: SuppressMessage(\"Microsoft.Usage\", \"CA2243:AttributeStringLiteralsShouldParseCorrectly\",\n\tJustification = \"AssemblyInformationalVersion does not need to be a parsable version\")]\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Search/AbstractEntitySearchStrategy.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Concurrent;\nusing System.IO;\n\nnamespace ICSharpCode.ILSpyX.Search\n{\n\tusing ICSharpCode.Decompiler.TypeSystem;\n\tusing ICSharpCode.ILSpyX.Abstractions;\n\n\tpublic abstract class AbstractEntitySearchStrategy : AbstractSearchStrategy\n\t{\n\t\tprotected readonly ILanguage language;\n\t\tprotected readonly ApiVisibility apiVisibility;\n\n\t\tprotected AbstractEntitySearchStrategy(ILanguage language, ApiVisibility apiVisibility,\n\t\t\tSearchRequest searchRequest, IProducerConsumerCollection<SearchResult> resultQueue)\n\t\t\t: base(searchRequest, resultQueue)\n\t\t{\n\t\t\tthis.language = language;\n\t\t\tthis.apiVisibility = apiVisibility;\n\t\t}\n\n\t\tprotected bool CheckVisibility(IEntity? entity)\n\t\t{\n\t\t\tif (apiVisibility == ApiVisibility.All)\n\t\t\t\treturn true;\n\n\t\t\twhile (entity != null)\n\t\t\t{\n\t\t\t\tif (apiVisibility == ApiVisibility.PublicOnly)\n\t\t\t\t{\n\t\t\t\t\tif (!(entity.Accessibility == Accessibility.Public ||\n\t\t\t\t\t\tentity.Accessibility == Accessibility.Protected ||\n\t\t\t\t\t\tentity.Accessibility == Accessibility.ProtectedOrInternal))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse if (apiVisibility == ApiVisibility.PublicAndInternal)\n\t\t\t\t{\n\t\t\t\t\tif (!language.ShowMember(entity))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tentity = entity.DeclaringTypeDefinition;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tprotected bool IsInNamespaceOrAssembly(IEntity entity)\n\t\t{\n\t\t\tif (searchRequest.InAssembly != null)\n\t\t\t{\n\t\t\t\tif (entity.ParentModule?.MetadataFile == null ||\n\t\t\t\t\t!(Path.GetFileName(entity.ParentModule.MetadataFile.FileName).Contains(searchRequest.InAssembly, StringComparison.OrdinalIgnoreCase)\n\t\t\t\t\t|| entity.ParentModule.FullAssemblyName.Contains(searchRequest.InAssembly, StringComparison.OrdinalIgnoreCase)))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (searchRequest.InNamespace != null)\n\t\t\t{\n\t\t\t\tif (searchRequest.InNamespace.Length == 0)\n\t\t\t\t{\n\t\t\t\t\treturn entity.Namespace.Length == 0;\n\t\t\t\t}\n\t\t\t\telse if (!entity.Namespace.Contains(searchRequest.InNamespace, StringComparison.OrdinalIgnoreCase))\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tprotected void OnFoundResult(IEntity entity)\n\t\t{\n\t\t\tOnFoundResult(searchRequest.SearchResultFactory.Create(entity));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Search/AbstractSearchStrategy.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Concurrent;\nusing System.Text.RegularExpressions;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpyX.Abstractions;\n\nnamespace ICSharpCode.ILSpyX.Search\n{\n\tpublic enum SearchMode\n\t{\n\t\tTypeAndMember,\n\t\tType,\n\t\tMember,\n\t\tMethod,\n\t\tField,\n\t\tProperty,\n\t\tEvent,\n\t\tLiteral,\n\t\tToken,\n\t\tResource,\n\t\tAssembly,\n\t\tNamespace\n\t}\n\n\tpublic struct SearchRequest\n\t{\n\t\tpublic DecompilerSettings DecompilerSettings;\n\t\tpublic ITreeNodeFactory TreeNodeFactory;\n\t\tpublic ISearchResultFactory SearchResultFactory;\n\t\tpublic SearchMode Mode;\n\t\tpublic AssemblySearchKind AssemblySearchKind;\n\t\tpublic MemberSearchKind MemberSearchKind;\n\t\tpublic string[] Keywords;\n\t\tpublic Regex? RegEx;\n\t\tpublic bool FullNameSearch;\n\t\tpublic bool OmitGenerics;\n\t\tpublic string InNamespace;\n\t\tpublic string InAssembly;\n\t}\n\n\tpublic abstract class AbstractSearchStrategy\n\t{\n\t\tprotected readonly string[] searchTerm;\n\t\tprotected readonly Regex? regex;\n\t\tprotected readonly bool fullNameSearch;\n\t\tprotected readonly bool omitGenerics;\n\t\tprotected readonly SearchRequest searchRequest;\n\t\tprivate readonly IProducerConsumerCollection<SearchResult> resultQueue;\n\n\t\tprotected AbstractSearchStrategy(SearchRequest request, IProducerConsumerCollection<SearchResult> resultQueue)\n\t\t{\n\t\t\tthis.resultQueue = resultQueue;\n\t\t\tthis.searchTerm = request.Keywords;\n\t\t\tthis.regex = request.RegEx;\n\t\t\tthis.searchRequest = request;\n\t\t\tthis.fullNameSearch = request.FullNameSearch;\n\t\t\tthis.omitGenerics = request.OmitGenerics;\n\t\t}\n\n\t\tpublic abstract void Search(MetadataFile module, CancellationToken cancellationToken);\n\n\t\tprotected virtual bool IsMatch(string name)\n\t\t{\n\t\t\tif (regex != null)\n\t\t\t{\n\t\t\t\treturn regex.IsMatch(name);\n\t\t\t}\n\n\t\t\tfor (int i = 0; i < searchTerm.Length; ++i)\n\t\t\t{\n\t\t\t\t// How to handle overlapping matches?\n\t\t\t\tvar term = searchTerm[i];\n\t\t\t\tif (string.IsNullOrEmpty(term))\n\t\t\t\t\tcontinue;\n\t\t\t\tstring text = name;\n\t\t\t\tswitch (term[0])\n\t\t\t\t{\n\t\t\t\t\tcase '+': // must contain\n\t\t\t\t\t\tterm = term.Substring(1);\n\t\t\t\t\t\tgoto default;\n\t\t\t\t\tcase '-': // should not contain\n\t\t\t\t\t\tif (term.Length > 1 && text.IndexOf(term.Substring(1), StringComparison.OrdinalIgnoreCase) >= 0)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '=': // exact match\n\t\t\t\t\t{\n\t\t\t\t\t\tvar equalCompareLength = text.IndexOf('`');\n\t\t\t\t\t\tif (equalCompareLength == -1)\n\t\t\t\t\t\t\tequalCompareLength = text.Length;\n\n\t\t\t\t\t\tif (term.Length > 1 && String.Compare(term, 1, text, 0, Math.Max(term.Length, equalCompareLength),\n\t\t\t\t\t\t\tStringComparison.OrdinalIgnoreCase) != 0)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase '~':\n\t\t\t\t\t\tif (term.Length > 1 && !IsNoncontiguousMatch(text.ToLower(), term.Substring(1).ToLower()))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif (text.IndexOf(term, StringComparison.OrdinalIgnoreCase) < 0)\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tbool IsNoncontiguousMatch(string text, string searchTerm)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(searchTerm))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar textLength = text.Length;\n\t\t\tif (searchTerm.Length > textLength)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar i = 0;\n\t\t\tfor (int searchIndex = 0; searchIndex < searchTerm.Length;)\n\t\t\t{\n\t\t\t\twhile (i != textLength)\n\t\t\t\t{\n\t\t\t\t\tif (text[i] == searchTerm[searchIndex])\n\t\t\t\t\t{\n\t\t\t\t\t\t// Check if all characters in searchTerm have been matched\n\t\t\t\t\t\tif (searchTerm.Length == ++searchIndex)\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\ti++;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t\tif (i == textLength)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tprotected void OnFoundResult(SearchResult result)\n\t\t{\n\t\t\tresultQueue.TryAdd(result);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Search/AssemblySearchStrategy.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\nusing System.Collections.Concurrent;\nusing System.IO;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpyX.Search\n{\n\tpublic class AssemblySearchStrategy : AbstractSearchStrategy\n\t{\n\t\treadonly AssemblySearchKind searchKind;\n\n\t\tpublic AssemblySearchStrategy(SearchRequest request,\n\t\t\tIProducerConsumerCollection<SearchResult> resultQueue, AssemblySearchKind searchKind)\n\t\t\t: base(request, resultQueue)\n\t\t{\n\t\t\tthis.searchKind = searchKind;\n\t\t}\n\n\t\tpublic override void Search(MetadataFile module, CancellationToken cancellationToken)\n\t\t{\n\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\n\t\t\tif (searchKind == AssemblySearchKind.NameOrFileName)\n\t\t\t{\n\t\t\t\tstring? localName = GetNameToMatch(module, AssemblySearchKind.Name);\n\t\t\t\tstring? filePath = GetNameToMatch(module, AssemblySearchKind.FilePath);\n\t\t\t\tif (localName != null && IsMatch(localName))\n\t\t\t\t{\n\t\t\t\t\tOnFoundResult(module);\n\t\t\t\t}\n\t\t\t\telse if (filePath != null)\n\t\t\t\t{\n\t\t\t\t\tstring fileName = Path.GetFileName(filePath);\n\t\t\t\t\tif (IsMatch(fileName))\n\t\t\t\t\t\tOnFoundResult(module);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tstring? name = GetNameToMatch(module, searchKind);\n\t\t\tif (name != null && IsMatch(name))\n\t\t\t\tOnFoundResult(module);\n\t\t}\n\n\t\tstring? GetNameToMatch(MetadataFile module, AssemblySearchKind kind)\n\t\t{\n\t\t\tswitch (kind)\n\t\t\t{\n\t\t\t\tcase AssemblySearchKind.FullName:\n\t\t\t\t\treturn module.FullName;\n\t\t\t\tcase AssemblySearchKind.Name:\n\t\t\t\t\treturn module.Name;\n\t\t\t\tcase AssemblySearchKind.FilePath:\n\t\t\t\t\treturn module.FileName;\n\t\t\t}\n\n\t\t\tif (!module.IsAssembly)\n\t\t\t\treturn null;\n\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar definition = module.Metadata.GetAssemblyDefinition();\n\n\t\t\tswitch (kind)\n\t\t\t{\n\t\t\t\tcase AssemblySearchKind.Culture:\n\t\t\t\t\tif (definition.Culture.IsNil)\n\t\t\t\t\t\treturn \"neutral\";\n\t\t\t\t\treturn metadata.GetString(definition.Culture);\n\t\t\t\tcase AssemblySearchKind.Version:\n\t\t\t\t\treturn definition.Version.ToString();\n\t\t\t\tcase AssemblySearchKind.PublicKey:\n\t\t\t\t\treturn module.Metadata.GetPublicKeyToken();\n\t\t\t\tcase AssemblySearchKind.HashAlgorithm:\n\t\t\t\t\treturn definition.HashAlgorithm.ToString();\n\t\t\t\tcase AssemblySearchKind.Flags:\n\t\t\t\t\treturn definition.Flags.ToString();\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tvoid OnFoundResult(MetadataFile module)\n\t\t{\n\t\t\tOnFoundResult(searchRequest.SearchResultFactory.Create(module));\n\t\t}\n\t}\n\n\tpublic enum AssemblySearchKind\n\t{\n\t\tNameOrFileName,\n\t\tName,\n\t\tFullName,\n\t\tFilePath,\n\t\tCulture,\n\t\tVersion,\n\t\tPublicKey,\n\t\tHashAlgorithm,\n\t\tFlags\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Search/CSharpLexer.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable disable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.IO;\nusing System.Text;\n\nnamespace ICSharpCode.ILSpyX.Search\n{\n\tclass LATextReader : TextReader\n\t{\n\t\tList<int> buffer;\n\t\tTextReader reader;\n\n\t\tpublic LATextReader(TextReader reader)\n\t\t{\n\t\t\tthis.buffer = new List<int>();\n\t\t\tthis.reader = reader;\n\t\t}\n\n\t\tpublic override int Peek()\n\t\t{\n\t\t\treturn Peek(0);\n\t\t}\n\n\t\tpublic override int Read()\n\t\t{\n\t\t\tint c = Peek();\n\t\t\tbuffer.RemoveAt(0);\n\t\t\treturn c;\n\t\t}\n\n\t\tpublic int Peek(int step)\n\t\t{\n\t\t\twhile (step >= buffer.Count)\n\t\t\t{\n\t\t\t\tbuffer.Add(reader.Read());\n\t\t\t}\n\n\t\t\tif (step < 0)\n\t\t\t\treturn -1;\n\n\t\t\treturn buffer[step];\n\t\t}\n\n\t\tprotected override void Dispose(bool disposing)\n\t\t{\n\t\t\tif (disposing)\n\t\t\t\treader.Dispose();\n\t\t\tbase.Dispose(disposing);\n\t\t}\n\t}\n\n\tenum TokenKind : byte\n\t{\n\t\tEOF,\n\t\tLiteral,\n\t\tIdentifier,\n\t\tSymbol,\n\t}\n\n\tenum LiteralFormat : byte\n\t{\n\t\tNone,\n\t\tDecimalNumber,\n\t\tHexadecimalNumber,\n\t\tOctalNumber,\n\t\tStringLiteral,\n\t\tVerbatimStringLiteral,\n\t\tCharLiteral\n\t}\n\n\tclass Literal\n\t{\n\t\tinternal readonly TokenKind tokenKind;\n\t\tinternal readonly LiteralFormat literalFormat;\n\t\tinternal readonly object literalValue;\n\t\tinternal readonly string val;\n\t\tinternal Literal next;\n\n\t\tpublic TokenKind TokenKind {\n\t\t\tget { return tokenKind; }\n\t\t}\n\n\t\tpublic LiteralFormat LiteralFormat {\n\t\t\tget { return literalFormat; }\n\t\t}\n\n\t\tpublic object LiteralValue {\n\t\t\tget { return literalValue; }\n\t\t}\n\n\t\tpublic string Value {\n\t\t\tget { return val; }\n\t\t}\n\n\t\tpublic Literal(string val, TokenKind tokenKind)\n\t\t{\n\t\t\tthis.val = val;\n\t\t\tthis.tokenKind = tokenKind;\n\t\t}\n\n\t\tpublic Literal(string val, object literalValue, LiteralFormat literalFormat)\n\t\t{\n\t\t\tthis.val = val;\n\t\t\tthis.literalValue = literalValue;\n\t\t\tthis.literalFormat = literalFormat;\n\t\t\tthis.tokenKind = TokenKind.Literal;\n\t\t}\n\t}\n\n\tinternal abstract class AbstractLexer : IDisposable\n\t{\n\t\tLATextReader reader;\n\t\tint col = 1;\n\t\tint line = 1;\n\n\t\tprotected Literal lastToken = null;\n\t\tprotected Literal curToken = null;\n\t\tprotected Literal peekToken = null;\n\n\t\tprotected StringBuilder sb = new StringBuilder();\n\n\t\t// used for the original value of strings (with escape sequences).\n\t\tprotected StringBuilder originalValue = new StringBuilder();\n\n\t\tprotected int Line {\n\t\t\tget {\n\t\t\t\treturn line;\n\t\t\t}\n\t\t}\n\t\tprotected int Col {\n\t\t\tget {\n\t\t\t\treturn col;\n\t\t\t}\n\t\t}\n\n\t\tprotected bool recordRead = false;\n\t\tprotected StringBuilder recordedText = new StringBuilder();\n\n\t\tprotected int ReaderRead()\n\t\t{\n\t\t\tint val = reader.Read();\n\t\t\tif (recordRead && val >= 0)\n\t\t\t\trecordedText.Append((char)val);\n\t\t\tif ((val == '\\r' && reader.Peek() != '\\n') || val == '\\n')\n\t\t\t{\n\t\t\t\t++line;\n\t\t\t\tcol = 1;\n\t\t\t\tLineBreak();\n\t\t\t}\n\t\t\telse if (val >= 0)\n\t\t\t{\n\t\t\t\tcol++;\n\t\t\t}\n\t\t\treturn val;\n\t\t}\n\n\t\tprotected int ReaderPeek()\n\t\t{\n\t\t\treturn reader.Peek();\n\t\t}\n\n\t\tprotected int ReaderPeek(int step)\n\t\t{\n\t\t\treturn reader.Peek(step);\n\t\t}\n\n\t\tprotected void ReaderSkip(int steps)\n\t\t{\n\t\t\tfor (int i = 0; i < steps; i++)\n\t\t\t{\n\t\t\t\tReaderRead();\n\t\t\t}\n\t\t}\n\n\t\tprotected string ReaderPeekString(int length)\n\t\t{\n\t\t\tStringBuilder builder = new StringBuilder();\n\n\t\t\tfor (int i = 0; i < length; i++)\n\t\t\t{\n\t\t\t\tint peek = ReaderPeek(i);\n\t\t\t\tif (peek != -1)\n\t\t\t\t\tbuilder.Append((char)peek);\n\t\t\t}\n\n\t\t\treturn builder.ToString();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// The current Token. <seealso cref=\"ICSharpCode.NRefactory.Parser.Token\"/>\n\t\t/// </summary>\n\t\tpublic Literal Token {\n\t\t\tget {\n\t\t\t\treturn lastToken;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// The next Token (The <see cref=\"Token\"/> after <see cref=\"NextToken\"/> call) . <seealso cref=\"ICSharpCode.NRefactory.Parser.Token\"/>\n\t\t/// </summary>\n\t\tpublic Literal LookAhead {\n\t\t\tget {\n\t\t\t\treturn curToken;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Constructor for the abstract lexer class.\n\t\t/// </summary>\n\t\tprotected AbstractLexer(TextReader reader)\n\t\t{\n\t\t\tthis.reader = new LATextReader(reader);\n\t\t}\n\n\t\t#region System.IDisposable interface implementation\n\t\tpublic virtual void Dispose()\n\t\t{\n\t\t\treader.Close();\n\t\t\treader = null;\n\t\t\tlastToken = curToken = peekToken = null;\n\t\t\tsb = originalValue = null;\n\t\t}\n\t\t#endregion\n\n\t\t/// <summary>\n\t\t/// Must be called before a peek operation.\n\t\t/// </summary>\n\t\tpublic void StartPeek()\n\t\t{\n\t\t\tpeekToken = curToken;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gives back the next token. A second call to Peek() gives the next token after the last call for Peek() and so on.\n\t\t/// </summary>\n\t\t/// <returns>An <see cref=\"Token\"/> object.</returns>\n\t\tpublic Literal Peek()\n\t\t{\n\t\t\t// Debug.WriteLine(\"Call to Peek\");\n\t\t\tif (peekToken.next == null)\n\t\t\t{\n\t\t\t\tpeekToken.next = Next();\n\t\t\t}\n\t\t\tpeekToken = peekToken.next;\n\t\t\treturn peekToken;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Reads the next token and gives it back.\n\t\t/// </summary>\n\t\t/// <returns>An <see cref=\"Token\"/> object.</returns>\n\t\tpublic virtual Literal NextToken()\n\t\t{\n\t\t\tif (curToken == null)\n\t\t\t{\n\t\t\t\tcurToken = Next();\n\t\t\t\t// Debug.WriteLine(ICSharpCode.NRefactory.Parser.CSharp.Tokens.GetTokenString(curToken.kind) + \" -- \" + curToken.val + \"(\" + curToken.kind + \")\");\n\t\t\t\treturn curToken;\n\t\t\t}\n\n\t\t\tlastToken = curToken;\n\n\t\t\tif (curToken.next == null)\n\t\t\t{\n\t\t\t\tcurToken.next = Next();\n\t\t\t}\n\n\t\t\tcurToken = curToken.next;\n\t\t\t// Debug.WriteLine(ICSharpCode.NRefactory.Parser.CSharp.Tokens.GetTokenString(curToken.kind) + \" -- \" + curToken.val + \"(\" + curToken.kind + \")\");\n\t\t\treturn curToken;\n\t\t}\n\n\t\tprotected abstract Literal Next();\n\n\t\tprotected static bool IsIdentifierPart(int ch)\n\t\t{\n\t\t\tif (ch == 95)\n\t\t\t\treturn true;  // 95 = '_'\n\t\t\tif (ch == -1)\n\t\t\t\treturn false;\n\t\t\treturn char.IsLetterOrDigit((char)ch); // accept unicode letters\n\t\t}\n\n\t\tprotected static bool IsHex(char digit)\n\t\t{\n\t\t\treturn Char.IsDigit(digit) || ('A' <= digit && digit <= 'F') || ('a' <= digit && digit <= 'f');\n\t\t}\n\n\t\tprotected int GetHexNumber(char digit)\n\t\t{\n\t\t\tif (Char.IsDigit(digit))\n\t\t\t{\n\t\t\t\treturn digit - '0';\n\t\t\t}\n\t\t\tif ('A' <= digit && digit <= 'F')\n\t\t\t{\n\t\t\t\treturn digit - 'A' + 0xA;\n\t\t\t}\n\t\t\tif ('a' <= digit && digit <= 'f')\n\t\t\t{\n\t\t\t\treturn digit - 'a' + 0xA;\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\t\tprotected void LineBreak()\n\t\t{\n\t\t}\n\t\tprotected bool HandleLineEnd(char ch)\n\t\t{\n\t\t\t// Handle MS-DOS or MacOS line ends.\n\t\t\tif (ch == '\\r')\n\t\t\t{\n\t\t\t\tif (reader.Peek() == '\\n')\n\t\t\t\t{ // MS-DOS line end '\\r\\n'\n\t\t\t\t\tReaderRead(); // LineBreak (); called by ReaderRead ();\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{ // assume MacOS line end which is '\\r'\n\t\t\t\t\tLineBreak();\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (ch == '\\n')\n\t\t\t{\n\t\t\t\tLineBreak();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tprotected void SkipToEndOfLine()\n\t\t{\n\t\t\tint nextChar;\n\t\t\twhile ((nextChar = reader.Read()) != -1)\n\t\t\t{\n\t\t\t\tif (nextChar == '\\r')\n\t\t\t\t{\n\t\t\t\t\tif (reader.Peek() == '\\n')\n\t\t\t\t\t\treader.Read();\n\t\t\t\t\tnextChar = '\\n';\n\t\t\t\t}\n\t\t\t\tif (nextChar == '\\n')\n\t\t\t\t{\n\t\t\t\t\t++line;\n\t\t\t\t\tcol = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected string ReadToEndOfLine()\n\t\t{\n\t\t\tsb.Length = 0;\n\t\t\tint nextChar;\n\t\t\twhile ((nextChar = reader.Read()) != -1)\n\t\t\t{\n\t\t\t\tchar ch = (char)nextChar;\n\n\t\t\t\tif (nextChar == '\\r')\n\t\t\t\t{\n\t\t\t\t\tif (reader.Peek() == '\\n')\n\t\t\t\t\t\treader.Read();\n\t\t\t\t\tnextChar = '\\n';\n\t\t\t\t}\n\t\t\t\t// Return read string, if EOL is reached\n\t\t\t\tif (nextChar == '\\n')\n\t\t\t\t{\n\t\t\t\t\t++line;\n\t\t\t\t\tcol = 1;\n\t\t\t\t\treturn sb.ToString();\n\t\t\t\t}\n\n\t\t\t\tsb.Append(ch);\n\t\t\t}\n\n\t\t\t// Got EOF before EOL\n\t\t\tstring retStr = sb.ToString();\n\t\t\tcol += retStr.Length;\n\t\t\treturn retStr;\n\t\t}\n\t}\n\n\tinternal sealed class Lexer : AbstractLexer\n\t{\n\t\tpublic Lexer(TextReader reader) : base(reader)\n\t\t{\n\t\t}\n\n\t\tprotected override Literal Next()\n\t\t{\n\t\t\tchar ch;\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tint nextChar = ReaderRead();\n\t\t\t\tif (nextChar == -1)\n\t\t\t\t\tbreak;\n\n\t\t\t\tLiteral token = null;\n\n\t\t\t\tswitch (nextChar)\n\t\t\t\t{\n\t\t\t\t\tcase ' ':\n\t\t\t\t\tcase '\\t':\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tcase '\\r':\n\t\t\t\t\tcase '\\n':\n\t\t\t\t\t\tHandleLineEnd((char)nextChar);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tcase '\"':\n\t\t\t\t\t\ttoken = ReadString();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\\'':\n\t\t\t\t\t\ttoken = ReadChar();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '@':\n\t\t\t\t\t\tint next = ReaderRead();\n\t\t\t\t\t\tif (next == -1)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tError(Line, Col, String.Format(\"EOF after @\"));\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tint x = Col - 1;\n\t\t\t\t\t\t\tint y = Line;\n\t\t\t\t\t\t\tch = (char)next;\n\t\t\t\t\t\t\tif (ch == '\"')\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttoken = ReadVerbatimString();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (Char.IsLetterOrDigit(ch) || ch == '_')\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstring s = ReadIdent(ch, out _);\n\t\t\t\t\t\t\t\treturn new Literal(s, TokenKind.Identifier);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tHandleLineEnd(ch);\n\t\t\t\t\t\t\t\tError(y, x, String.Format(\"Unexpected char in Lexer.Next() : {0}\", ch));\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault: // non-ws chars are handled here\n\t\t\t\t\t\tch = (char)nextChar;\n\t\t\t\t\t\tif (Char.IsLetter(ch) || ch == '_' || ch == '\\\\')\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tint x = Col - 1; // Col was incremented above, but we want the start of the identifier\n\t\t\t\t\t\t\tint y = Line;\n\t\t\t\t\t\t\tstring s = ReadIdent(ch, out _);\n\t\t\t\t\t\t\treturn new Literal(s, TokenKind.Identifier);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (Char.IsDigit(ch))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttoken = ReadDigit(ch, Col - 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// try error recovery (token = null -> continue with next char)\n\t\t\t\tif (token != null)\n\t\t\t\t{\n\t\t\t\t\treturn token;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn new Literal(null, TokenKind.EOF);\n\t\t}\n\n\t\t// The C# compiler has a fixed size length therefore we'll use a fixed size char array for identifiers\n\t\t// it's also faster than using a string builder.\n\t\tconst int MAX_IDENTIFIER_LENGTH = 512;\n\t\tchar[] identBuffer = new char[MAX_IDENTIFIER_LENGTH];\n\n\t\tstring ReadIdent(char ch, out bool canBeKeyword)\n\t\t{\n\t\t\tint peek;\n\t\t\tint curPos = 0;\n\t\t\tcanBeKeyword = true;\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tif (ch == '\\\\')\n\t\t\t\t{\n\t\t\t\t\tpeek = ReaderPeek();\n\t\t\t\t\tif (peek != 'u' && peek != 'U')\n\t\t\t\t\t{\n\t\t\t\t\t\tError(Line, Col, \"Identifiers can only contain unicode escape sequences\");\n\t\t\t\t\t}\n\t\t\t\t\tcanBeKeyword = false;\n\t\t\t\t\tstring surrogatePair;\n\t\t\t\t\tReadEscapeSequence(out ch, out surrogatePair);\n\t\t\t\t\tif (surrogatePair != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!char.IsLetterOrDigit(surrogatePair, 0))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tError(Line, Col, \"Unicode escape sequences in identifiers cannot be used to represent characters that are invalid in identifiers\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (int i = 0; i < surrogatePair.Length - 1; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (curPos < MAX_IDENTIFIER_LENGTH)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tidentBuffer[curPos++] = surrogatePair[i];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tch = surrogatePair[surrogatePair.Length - 1];\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!IsIdentifierPart(ch))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tError(Line, Col, \"Unicode escape sequences in identifiers cannot be used to represent characters that are invalid in identifiers\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (curPos < MAX_IDENTIFIER_LENGTH)\n\t\t\t\t{\n\t\t\t\t\tif (ch != '\\0') // only add character, if it is valid\n\t\t\t\t\t\t\t\t\t// prevents \\ from being added\n\t\t\t\t\t\tidentBuffer[curPos++] = ch;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tError(Line, Col, String.Format(\"Identifier too long\"));\n\t\t\t\t\twhile (IsIdentifierPart(ReaderPeek()))\n\t\t\t\t\t{\n\t\t\t\t\t\tReaderRead();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tpeek = ReaderPeek();\n\t\t\t\tif (IsIdentifierPart(peek) || peek == '\\\\')\n\t\t\t\t{\n\t\t\t\t\tch = (char)ReaderRead();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn new String(identBuffer, 0, curPos);\n\t\t}\n\n\t\tLiteral ReadDigit(char ch, int x)\n\t\t{\n\t\t\tunchecked\n\t\t\t{ // prevent exception when ReaderPeek() = -1 is cast to char\n\t\t\t\tint y = Line;\n\t\t\t\tsb.Length = 0;\n\t\t\t\tsb.Append(ch);\n\t\t\t\tstring prefix = null;\n\t\t\t\tstring suffix = null;\n\n\t\t\t\tbool ishex = false;\n\t\t\t\tbool isunsigned = false;\n\t\t\t\tbool islong = false;\n\t\t\t\tbool isfloat = false;\n\t\t\t\tbool isdouble = false;\n\t\t\t\tbool isdecimal = false;\n\n\t\t\t\tchar peek = (char)ReaderPeek();\n\n\t\t\t\tif (ch == '.')\n\t\t\t\t{\n\t\t\t\t\tisdouble = true;\n\n\t\t\t\t\twhile (Char.IsDigit((char)ReaderPeek()))\n\t\t\t\t\t{ // read decimal digits beyond the dot\n\t\t\t\t\t\tsb.Append((char)ReaderRead());\n\t\t\t\t\t}\n\t\t\t\t\tpeek = (char)ReaderPeek();\n\t\t\t\t}\n\t\t\t\telse if (ch == '0' && (peek == 'x' || peek == 'X'))\n\t\t\t\t{\n\t\t\t\t\tReaderRead(); // skip 'x'\n\t\t\t\t\tsb.Length = 0; // Remove '0' from 0x prefix from the stringvalue\n\t\t\t\t\twhile (IsHex((char)ReaderPeek()))\n\t\t\t\t\t{\n\t\t\t\t\t\tsb.Append((char)ReaderRead());\n\t\t\t\t\t}\n\t\t\t\t\tif (sb.Length == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tsb.Append('0'); // dummy value to prevent exception\n\t\t\t\t\t\tError(y, x, \"Invalid hexadecimal integer literal\");\n\t\t\t\t\t}\n\t\t\t\t\tishex = true;\n\t\t\t\t\tprefix = \"0x\";\n\t\t\t\t\tpeek = (char)ReaderPeek();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\twhile (Char.IsDigit((char)ReaderPeek()))\n\t\t\t\t\t{\n\t\t\t\t\t\tsb.Append((char)ReaderRead());\n\t\t\t\t\t}\n\t\t\t\t\tpeek = (char)ReaderPeek();\n\t\t\t\t}\n\n\t\t\t\tLiteral nextToken = null; // if we accidently read a 'dot'\n\t\t\t\tif (peek == '.')\n\t\t\t\t{ // read floating point number\n\t\t\t\t\tReaderRead();\n\t\t\t\t\tpeek = (char)ReaderPeek();\n\t\t\t\t\tif (!Char.IsDigit(peek))\n\t\t\t\t\t{\n\t\t\t\t\t\tnextToken = new Literal(\".\", TokenKind.Symbol);\n\t\t\t\t\t\tpeek = '.';\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tisdouble = true; // double is default\n\t\t\t\t\t\tif (ishex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tError(y, x, \"No hexadecimal floating point values allowed\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsb.Append('.');\n\n\t\t\t\t\t\twhile (Char.IsDigit((char)ReaderPeek()))\n\t\t\t\t\t\t{ // read decimal digits beyond the dot\n\t\t\t\t\t\t\tsb.Append((char)ReaderRead());\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpeek = (char)ReaderPeek();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (peek == 'e' || peek == 'E')\n\t\t\t\t{ // read exponent\n\t\t\t\t\tisdouble = true;\n\t\t\t\t\tsb.Append((char)ReaderRead());\n\t\t\t\t\tpeek = (char)ReaderPeek();\n\t\t\t\t\tif (peek == '-' || peek == '+')\n\t\t\t\t\t{\n\t\t\t\t\t\tsb.Append((char)ReaderRead());\n\t\t\t\t\t}\n\t\t\t\t\twhile (Char.IsDigit((char)ReaderPeek()))\n\t\t\t\t\t{ // read exponent value\n\t\t\t\t\t\tsb.Append((char)ReaderRead());\n\t\t\t\t\t}\n\t\t\t\t\tisunsigned = true;\n\t\t\t\t\tpeek = (char)ReaderPeek();\n\t\t\t\t}\n\n\t\t\t\tif (peek == 'f' || peek == 'F')\n\t\t\t\t{ // float value\n\t\t\t\t\tReaderRead();\n\t\t\t\t\tsuffix = \"f\";\n\t\t\t\t\tisfloat = true;\n\t\t\t\t}\n\t\t\t\telse if (peek == 'd' || peek == 'D')\n\t\t\t\t{ // double type suffix (obsolete, double is default)\n\t\t\t\t\tReaderRead();\n\t\t\t\t\tsuffix = \"d\";\n\t\t\t\t\tisdouble = true;\n\t\t\t\t}\n\t\t\t\telse if (peek == 'm' || peek == 'M')\n\t\t\t\t{ // decimal value\n\t\t\t\t\tReaderRead();\n\t\t\t\t\tsuffix = \"m\";\n\t\t\t\t\tisdecimal = true;\n\t\t\t\t}\n\t\t\t\telse if (!isdouble)\n\t\t\t\t{\n\t\t\t\t\tif (peek == 'u' || peek == 'U')\n\t\t\t\t\t{\n\t\t\t\t\t\tReaderRead();\n\t\t\t\t\t\tsuffix = \"u\";\n\t\t\t\t\t\tisunsigned = true;\n\t\t\t\t\t\tpeek = (char)ReaderPeek();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (peek == 'l' || peek == 'L')\n\t\t\t\t\t{\n\t\t\t\t\t\tReaderRead();\n\t\t\t\t\t\tpeek = (char)ReaderPeek();\n\t\t\t\t\t\tislong = true;\n\t\t\t\t\t\tif (!isunsigned && (peek == 'u' || peek == 'U'))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tReaderRead();\n\t\t\t\t\t\t\tsuffix = \"Lu\";\n\t\t\t\t\t\t\tisunsigned = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsuffix = isunsigned ? \"uL\" : \"L\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tstring digit = sb.ToString();\n\t\t\t\tstring stringValue = prefix + digit + suffix;\n\n\t\t\t\tif (isfloat)\n\t\t\t\t{\n\t\t\t\t\tfloat num;\n\t\t\t\t\tif (float.TryParse(digit, NumberStyles.Any, CultureInfo.InvariantCulture, out num))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new Literal(stringValue, num, LiteralFormat.DecimalNumber);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tError(y, x, String.Format(\"Can't parse float {0}\", digit));\n\t\t\t\t\t\treturn new Literal(stringValue, 0f, LiteralFormat.DecimalNumber);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (isdecimal)\n\t\t\t\t{\n\t\t\t\t\tdecimal num;\n\t\t\t\t\tif (decimal.TryParse(digit, NumberStyles.Any, CultureInfo.InvariantCulture, out num))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new Literal(stringValue, num, LiteralFormat.DecimalNumber);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tError(y, x, String.Format(\"Can't parse decimal {0}\", digit));\n\t\t\t\t\t\treturn new Literal(stringValue, 0m, LiteralFormat.DecimalNumber);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (isdouble)\n\t\t\t\t{\n\t\t\t\t\tdouble num;\n\t\t\t\t\tif (double.TryParse(digit, NumberStyles.Any, CultureInfo.InvariantCulture, out num))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new Literal(stringValue, num, LiteralFormat.DecimalNumber);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tError(y, x, String.Format(\"Can't parse double {0}\", digit));\n\t\t\t\t\t\treturn new Literal(stringValue, 0d, LiteralFormat.DecimalNumber);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Try to determine a parsable value using ranges.\n\t\t\t\tulong result;\n\t\t\t\tif (ishex)\n\t\t\t\t{\n\t\t\t\t\tif (!ulong.TryParse(digit, NumberStyles.HexNumber, null, out result))\n\t\t\t\t\t{\n\t\t\t\t\t\tError(y, x, String.Format(\"Can't parse hexadecimal constant {0}\", digit));\n\t\t\t\t\t\treturn new Literal(stringValue.ToString(), 0, LiteralFormat.HexadecimalNumber);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (!ulong.TryParse(digit, NumberStyles.Integer, null, out result))\n\t\t\t\t\t{\n\t\t\t\t\t\tError(y, x, String.Format(\"Can't parse integral constant {0}\", digit));\n\t\t\t\t\t\treturn new Literal(stringValue.ToString(), 0, LiteralFormat.DecimalNumber);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (result > long.MaxValue)\n\t\t\t\t{\n\t\t\t\t\tislong = true;\n\t\t\t\t\tisunsigned = true;\n\t\t\t\t}\n\t\t\t\telse if (result > uint.MaxValue)\n\t\t\t\t{\n\t\t\t\t\tislong = true;\n\t\t\t\t}\n\t\t\t\telse if (islong == false && result > int.MaxValue)\n\t\t\t\t{\n\t\t\t\t\tisunsigned = true;\n\t\t\t\t}\n\n\t\t\t\tLiteral token;\n\n\t\t\t\tLiteralFormat literalFormat = ishex ? LiteralFormat.HexadecimalNumber : LiteralFormat.DecimalNumber;\n\t\t\t\tif (islong)\n\t\t\t\t{\n\t\t\t\t\tif (isunsigned)\n\t\t\t\t\t{\n\t\t\t\t\t\tulong num;\n\t\t\t\t\t\tif (ulong.TryParse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number, CultureInfo.InvariantCulture, out num))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttoken = new Literal(stringValue, num, literalFormat);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tError(y, x, String.Format(\"Can't parse unsigned long {0}\", digit));\n\t\t\t\t\t\t\ttoken = new Literal(stringValue, 0UL, literalFormat);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tlong num;\n\t\t\t\t\t\tif (long.TryParse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number, CultureInfo.InvariantCulture, out num))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttoken = new Literal(stringValue, num, literalFormat);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tError(y, x, String.Format(\"Can't parse long {0}\", digit));\n\t\t\t\t\t\t\ttoken = new Literal(stringValue, 0L, literalFormat);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (isunsigned)\n\t\t\t\t\t{\n\t\t\t\t\t\tuint num;\n\t\t\t\t\t\tif (uint.TryParse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number, CultureInfo.InvariantCulture, out num))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttoken = new Literal(stringValue, num, literalFormat);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tError(y, x, String.Format(\"Can't parse unsigned int {0}\", digit));\n\t\t\t\t\t\t\ttoken = new Literal(stringValue, (uint)0, literalFormat);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tint num;\n\t\t\t\t\t\tif (int.TryParse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number, CultureInfo.InvariantCulture, out num))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttoken = new Literal(stringValue, num, literalFormat);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tError(y, x, String.Format(\"Can't parse int {0}\", digit));\n\t\t\t\t\t\t\ttoken = new Literal(stringValue, 0, literalFormat);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ttoken.next = nextToken;\n\t\t\t\treturn token;\n\t\t\t}\n\t\t}\n\n\t\tLiteral ReadString()\n\t\t{\n\t\t\tint x = Col - 1;\n\t\t\tint y = Line;\n\n\t\t\tsb.Length = 0;\n\t\t\toriginalValue.Length = 0;\n\t\t\toriginalValue.Append('\"');\n\t\t\tbool doneNormally = false;\n\t\t\tint nextChar;\n\t\t\twhile ((nextChar = ReaderRead()) != -1)\n\t\t\t{\n\t\t\t\tchar ch = (char)nextChar;\n\n\t\t\t\tif (ch == '\"')\n\t\t\t\t{\n\t\t\t\t\tdoneNormally = true;\n\t\t\t\t\toriginalValue.Append('\"');\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (ch == '\\\\')\n\t\t\t\t{\n\t\t\t\t\toriginalValue.Append('\\\\');\n\t\t\t\t\tstring surrogatePair;\n\t\t\t\t\toriginalValue.Append(ReadEscapeSequence(out ch, out surrogatePair));\n\t\t\t\t\tif (surrogatePair != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tsb.Append(surrogatePair);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tsb.Append(ch);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (HandleLineEnd(ch))\n\t\t\t\t{\n\t\t\t\t\t// call HandleLineEnd to ensure line numbers are still correct after the error\n\t\t\t\t\tError(y, x, \"No new line is allowed inside a string literal\");\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\toriginalValue.Append(ch);\n\t\t\t\t\tsb.Append(ch);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!doneNormally)\n\t\t\t{\n\t\t\t\tError(y, x, \"End of file reached inside string literal\");\n\t\t\t}\n\n\t\t\treturn new Literal(originalValue.ToString(), sb.ToString(), LiteralFormat.StringLiteral);\n\t\t}\n\n\t\tLiteral ReadVerbatimString()\n\t\t{\n\t\t\tsb.Length = 0;\n\t\t\toriginalValue.Length = 0;\n\t\t\toriginalValue.Append(\"@\\\"\");\n\t\t\tint nextChar;\n\t\t\twhile ((nextChar = ReaderRead()) != -1)\n\t\t\t{\n\t\t\t\tchar ch = (char)nextChar;\n\n\t\t\t\tif (ch == '\"')\n\t\t\t\t{\n\t\t\t\t\tif (ReaderPeek() != '\"')\n\t\t\t\t\t{\n\t\t\t\t\t\toriginalValue.Append('\"');\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\toriginalValue.Append(\"\\\"\\\"\");\n\t\t\t\t\tsb.Append('\"');\n\t\t\t\t\tReaderRead();\n\t\t\t\t}\n\t\t\t\telse if (HandleLineEnd(ch))\n\t\t\t\t{\n\t\t\t\t\tsb.Append(\"\\r\\n\");\n\t\t\t\t\toriginalValue.Append(\"\\r\\n\");\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tsb.Append(ch);\n\t\t\t\t\toriginalValue.Append(ch);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (nextChar == -1)\n\t\t\t{\n\t\t\t\tError(Line, Col, \"End of file reached inside verbatim string literal\");\n\t\t\t}\n\n\t\t\treturn new Literal(originalValue.ToString(), sb.ToString(), LiteralFormat.VerbatimStringLiteral);\n\t\t}\n\n\t\treadonly char[] escapeSequenceBuffer = new char[12];\n\n\t\t/// <summary>\n\t\t/// reads an escape sequence\n\t\t/// </summary>\n\t\t/// <param name=\"ch\">The character represented by the escape sequence,\n\t\t/// or '\\0' if there was an error or the escape sequence represents a character that\n\t\t/// can be represented only be a suggorate pair</param>\n\t\t/// <param name=\"surrogatePair\">Null, except when the character represented\n\t\t/// by the escape sequence can only be represented by a surrogate pair (then the string\n\t\t/// contains the surrogate pair)</param>\n\t\t/// <returns>The escape sequence</returns>\n\t\tstring ReadEscapeSequence(out char ch, out string surrogatePair)\n\t\t{\n\t\t\tsurrogatePair = null;\n\n\t\t\tint nextChar = ReaderRead();\n\t\t\tif (nextChar == -1)\n\t\t\t{\n\t\t\t\tError(Line, Col, \"End of file reached inside escape sequence\");\n\t\t\t\tch = '\\0';\n\t\t\t\treturn String.Empty;\n\t\t\t}\n\t\t\tint number;\n\t\t\tchar c = (char)nextChar;\n\t\t\tint curPos = 1;\n\t\t\tescapeSequenceBuffer[0] = c;\n\t\t\tswitch (c)\n\t\t\t{\n\t\t\t\tcase '\\'':\n\t\t\t\t\tch = '\\'';\n\t\t\t\t\tbreak;\n\t\t\t\tcase '\\\"':\n\t\t\t\t\tch = '\\\"';\n\t\t\t\t\tbreak;\n\t\t\t\tcase '\\\\':\n\t\t\t\t\tch = '\\\\';\n\t\t\t\t\tbreak;\n\t\t\t\tcase '0':\n\t\t\t\t\tch = '\\0';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'a':\n\t\t\t\t\tch = '\\a';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'b':\n\t\t\t\t\tch = '\\b';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'f':\n\t\t\t\t\tch = '\\f';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'n':\n\t\t\t\t\tch = '\\n';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'r':\n\t\t\t\t\tch = '\\r';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 't':\n\t\t\t\t\tch = '\\t';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'v':\n\t\t\t\t\tch = '\\v';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'u':\n\t\t\t\tcase 'x':\n\t\t\t\t\t// 16 bit unicode character\n\t\t\t\t\tc = (char)ReaderRead();\n\t\t\t\t\tnumber = GetHexNumber(c);\n\t\t\t\t\tescapeSequenceBuffer[curPos++] = c;\n\n\t\t\t\t\tif (number < 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tError(Line, Col - 1, String.Format(\"Invalid char in literal : {0}\", c));\n\t\t\t\t\t}\n\t\t\t\t\tfor (int i = 0; i < 3; ++i)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (IsHex((char)ReaderPeek()))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tc = (char)ReaderRead();\n\t\t\t\t\t\t\tint idx = GetHexNumber(c);\n\t\t\t\t\t\t\tescapeSequenceBuffer[curPos++] = c;\n\t\t\t\t\t\t\tnumber = 16 * number + idx;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tch = (char)number;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'U':\n\t\t\t\t\t// 32 bit unicode character\n\t\t\t\t\tnumber = 0;\n\t\t\t\t\tfor (int i = 0; i < 8; ++i)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (IsHex((char)ReaderPeek()))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tc = (char)ReaderRead();\n\t\t\t\t\t\t\tint idx = GetHexNumber(c);\n\t\t\t\t\t\t\tescapeSequenceBuffer[curPos++] = c;\n\t\t\t\t\t\t\tnumber = 16 * number + idx;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tError(Line, Col - 1, String.Format(\"Invalid char in literal : {0}\", (char)ReaderPeek()));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (number > 0xffff)\n\t\t\t\t\t{\n\t\t\t\t\t\tch = '\\0';\n\t\t\t\t\t\tsurrogatePair = char.ConvertFromUtf32(number);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tch = (char)number;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tError(Line, Col, String.Format(\"Unexpected escape sequence : {0}\", c));\n\t\t\t\t\tch = '\\0';\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn new String(escapeSequenceBuffer, 0, curPos);\n\t\t}\n\n\t\tLiteral ReadChar()\n\t\t{\n\t\t\tint x = Col - 1;\n\t\t\tint y = Line;\n\t\t\tint nextChar = ReaderRead();\n\t\t\tif (nextChar == -1 || HandleLineEnd((char)nextChar))\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tchar ch = (char)nextChar;\n\t\t\tchar chValue = ch;\n\t\t\tstring escapeSequence = String.Empty;\n\t\t\tif (ch == '\\\\')\n\t\t\t{\n\t\t\t\tstring surrogatePair;\n\t\t\t\tescapeSequence = ReadEscapeSequence(out chValue, out surrogatePair);\n\t\t\t\tif (surrogatePair != null)\n\t\t\t\t{\n\t\t\t\t\tError(y, x, \"The unicode character must be represented by a surrogate pair and does not fit into a System.Char\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tunchecked\n\t\t\t{\n\t\t\t\tif ((char)ReaderRead() != '\\'')\n\t\t\t\t{\n\t\t\t\t\tError(y, x, \"Char not terminated\");\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn new Literal(\"'\" + ch + escapeSequence + \"'\", chValue, LiteralFormat.CharLiteral);\n\t\t}\n\n\t\tvoid Error(int y, int x, string message)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Search/LiteralSearchStrategy.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\nusing System;\nusing System.Collections.Concurrent;\nusing System.Diagnostics;\nusing System.Reflection.Metadata;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\nusing ICSharpCode.ILSpyX.Abstractions;\n\nusing ILOpCode = System.Reflection.Metadata.ILOpCode;\n\nnamespace ICSharpCode.ILSpyX.Search\n{\n\tpublic class LiteralSearchStrategy : AbstractEntitySearchStrategy\n\t{\n\t\treadonly TypeCode searchTermLiteralType = TypeCode.Empty;\n\t\treadonly object? searchTermLiteralValue;\n\n\t\tpublic LiteralSearchStrategy(ILanguage language, ApiVisibility apiVisibility, SearchRequest request,\n\t\t\tIProducerConsumerCollection<SearchResult> resultQueue)\n\t\t\t: base(language, apiVisibility, request, resultQueue)\n\t\t{\n\t\t\tvar terms = request.Keywords;\n\t\t\tif (terms.Length == 1)\n\t\t\t{\n\t\t\t\tvar lexer = new Lexer(new LATextReader(new System.IO.StringReader(terms[0])));\n\t\t\t\tvar value = lexer.NextToken();\n\t\t\t\tvar following = lexer.NextToken();\n\n\t\t\t\tif (value != null && value.LiteralValue != null && following != null && following.TokenKind == TokenKind.EOF)\n\t\t\t\t{\n\t\t\t\t\tTypeCode valueType = Type.GetTypeCode(value.LiteralValue.GetType());\n\t\t\t\t\tswitch (valueType)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase TypeCode.Byte:\n\t\t\t\t\t\tcase TypeCode.SByte:\n\t\t\t\t\t\tcase TypeCode.Int16:\n\t\t\t\t\t\tcase TypeCode.UInt16:\n\t\t\t\t\t\tcase TypeCode.Int32:\n\t\t\t\t\t\tcase TypeCode.UInt32:\n\t\t\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\t\tcase TypeCode.UInt64:\n\t\t\t\t\t\t\tsearchTermLiteralType = TypeCode.Int64;\n\t\t\t\t\t\t\tsearchTermLiteralValue = CSharpPrimitiveCast.Cast(TypeCode.Int64, value.LiteralValue, false);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\tcase TypeCode.String:\n\t\t\t\t\t\t\tsearchTermLiteralType = valueType;\n\t\t\t\t\t\t\tsearchTermLiteralValue = value.LiteralValue;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Note: if searchTermLiteralType remains TypeCode.Empty, we'll do a substring search via base.IsMatch\n\t\t}\n\n\t\tpublic override void Search(MetadataFile module, CancellationToken cancellationToken)\n\t\t{\n\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar typeSystem = module.GetTypeSystemWithDecompilerSettingsOrNull(searchRequest.DecompilerSettings);\n\t\t\tif (typeSystem == null)\n\t\t\t\treturn;\n\n\t\t\tforeach (var handle in metadata.MethodDefinitions)\n\t\t\t{\n\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tvar md = metadata.GetMethodDefinition(handle);\n\t\t\t\tif (!md.HasBody() || !MethodIsLiteralMatch(module, md))\n\t\t\t\t\tcontinue;\n\t\t\t\tvar method = ((MetadataModule)typeSystem.MainModule).GetDefinition(handle);\n\t\t\t\tvar result = method.AccessorOwner ?? method;\n\t\t\t\tif (!CheckVisibility(result) || !IsInNamespaceOrAssembly(result))\n\t\t\t\t\tcontinue;\n\t\t\t\tOnFoundResult(result);\n\t\t\t}\n\n\t\t\tforeach (var handle in metadata.FieldDefinitions)\n\t\t\t{\n\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tvar fd = metadata.GetFieldDefinition(handle);\n\t\t\t\tif (!fd.HasFlag(System.Reflection.FieldAttributes.Literal))\n\t\t\t\t\tcontinue;\n\t\t\t\tvar constantHandle = fd.GetDefaultValue();\n\t\t\t\tif (constantHandle.IsNil)\n\t\t\t\t\tcontinue;\n\t\t\t\tvar constant = metadata.GetConstant(constantHandle);\n\t\t\t\tvar blob = metadata.GetBlobReader(constant.Value);\n\t\t\t\tif (!IsLiteralMatch(metadata, blob.ReadConstant(constant.TypeCode)))\n\t\t\t\t\tcontinue;\n\t\t\t\tIField field = ((MetadataModule)typeSystem.MainModule).GetDefinition(handle);\n\t\t\t\tif (!CheckVisibility(field) || !IsInNamespaceOrAssembly(field))\n\t\t\t\t\tcontinue;\n\t\t\t\tOnFoundResult(field);\n\t\t\t}\n\t\t}\n\n\t\tbool IsLiteralMatch(MetadataReader metadata, object? val)\n\t\t{\n\t\t\tif (val == null)\n\t\t\t\treturn false;\n\t\t\tswitch (searchTermLiteralType)\n\t\t\t{\n\t\t\t\tcase TypeCode.Int64:\n\t\t\t\t\tTypeCode tc = Type.GetTypeCode(val.GetType());\n\t\t\t\t\tif (tc >= TypeCode.SByte && tc <= TypeCode.UInt64)\n\t\t\t\t\t\treturn CSharpPrimitiveCast.Cast(TypeCode.Int64, val, false).Equals(searchTermLiteralValue);\n\t\t\t\t\telse\n\t\t\t\t\t\treturn false;\n\t\t\t\tcase TypeCode.Single:\n\t\t\t\tcase TypeCode.Double:\n\t\t\t\tcase TypeCode.String:\n\t\t\t\t\tDebug.Assert(searchTermLiteralValue != null);\n\t\t\t\t\treturn searchTermLiteralValue.Equals(val);\n\t\t\t\tdefault:\n\t\t\t\t\t// substring search with searchTerm\n\t\t\t\t\tstring? valAsString = val.ToString();\n\t\t\t\t\treturn valAsString != null && IsMatch(valAsString);\n\t\t\t}\n\t\t}\n\n\t\tbool MethodIsLiteralMatch(MetadataFile module, MethodDefinition methodDefinition)\n\t\t{\n\t\t\tvar blob = module.GetMethodBody(methodDefinition.RelativeVirtualAddress).GetILReader();\n\t\t\tif (searchTermLiteralType == TypeCode.Int64)\n\t\t\t{\n\t\t\t\tDebug.Assert(searchTermLiteralValue != null);\n\t\t\t\tlong val = (long)searchTermLiteralValue;\n\t\t\t\twhile (blob.RemainingBytes > 0)\n\t\t\t\t{\n\t\t\t\t\tILOpCode code;\n\t\t\t\t\tswitch (code = ILParser.DecodeOpCode(ref blob))\n\t\t\t\t\t{\n\t\t\t\t\t\tcase ILOpCode.Ldc_i8:\n\t\t\t\t\t\t\tif (val == blob.ReadInt64())\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ILOpCode.Ldc_i4:\n\t\t\t\t\t\t\tif (val == blob.ReadInt32())\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ILOpCode.Ldc_i4_s:\n\t\t\t\t\t\t\tif (val == blob.ReadSByte())\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ILOpCode.Ldc_i4_m1:\n\t\t\t\t\t\t\tif (val == -1)\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ILOpCode.Ldc_i4_0:\n\t\t\t\t\t\t\tif (val == 0)\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ILOpCode.Ldc_i4_1:\n\t\t\t\t\t\t\tif (val == 1)\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ILOpCode.Ldc_i4_2:\n\t\t\t\t\t\t\tif (val == 2)\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ILOpCode.Ldc_i4_3:\n\t\t\t\t\t\t\tif (val == 3)\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ILOpCode.Ldc_i4_4:\n\t\t\t\t\t\t\tif (val == 4)\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ILOpCode.Ldc_i4_5:\n\t\t\t\t\t\t\tif (val == 5)\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ILOpCode.Ldc_i4_6:\n\t\t\t\t\t\t\tif (val == 6)\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ILOpCode.Ldc_i4_7:\n\t\t\t\t\t\t\tif (val == 7)\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ILOpCode.Ldc_i4_8:\n\t\t\t\t\t\t\tif (val == 8)\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tILParser.SkipOperand(ref blob, code);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (searchTermLiteralType != TypeCode.Empty)\n\t\t\t{\n\t\t\t\tDebug.Assert(searchTermLiteralValue != null);\n\t\t\t\tILOpCode expectedCode;\n\t\t\t\tswitch (searchTermLiteralType)\n\t\t\t\t{\n\t\t\t\t\tcase TypeCode.Single:\n\t\t\t\t\t\texpectedCode = ILOpCode.Ldc_r4;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.Double:\n\t\t\t\t\t\texpectedCode = ILOpCode.Ldc_r8;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeCode.String:\n\t\t\t\t\t\texpectedCode = ILOpCode.Ldstr;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new InvalidOperationException();\n\t\t\t\t}\n\t\t\t\twhile (blob.RemainingBytes > 0)\n\t\t\t\t{\n\t\t\t\t\tvar code = ILParser.DecodeOpCode(ref blob);\n\t\t\t\t\tif (code != expectedCode)\n\t\t\t\t\t{\n\t\t\t\t\t\tILParser.SkipOperand(ref blob, code);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tswitch (code)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase ILOpCode.Ldc_r4:\n\t\t\t\t\t\t\tif ((float)searchTermLiteralValue == blob.ReadSingle())\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ILOpCode.Ldc_r8:\n\t\t\t\t\t\t\tif ((double)searchTermLiteralValue == blob.ReadDouble())\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ILOpCode.Ldstr:\n\t\t\t\t\t\t\tif ((string)searchTermLiteralValue == ILParser.DecodeUserString(ref blob, module.Metadata))\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\twhile (blob.RemainingBytes > 0)\n\t\t\t\t{\n\t\t\t\t\tvar code = ILParser.DecodeOpCode(ref blob);\n\t\t\t\t\tif (code != ILOpCode.Ldstr)\n\t\t\t\t\t{\n\t\t\t\t\t\tILParser.SkipOperand(ref blob, code);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (IsMatch(ILParser.DecodeUserString(ref blob, module.Metadata)))\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Search/MemberSearchStrategy.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\nusing System.Collections.Concurrent;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX.Abstractions;\n\nnamespace ICSharpCode.ILSpyX.Search\n{\n\tpublic class MemberSearchStrategy : AbstractEntitySearchStrategy\n\t{\n\t\treadonly MemberSearchKind searchKind;\n\n\t\tpublic MemberSearchStrategy(ILanguage language, ApiVisibility apiVisibility, SearchRequest searchRequest,\n\t\t\tIProducerConsumerCollection<SearchResult> resultQueue, MemberSearchKind searchKind = MemberSearchKind.All)\n\t\t\t: base(language, apiVisibility, searchRequest, resultQueue)\n\t\t{\n\t\t\tthis.searchKind = searchKind;\n\t\t}\n\n\t\tpublic override void Search(MetadataFile module, CancellationToken cancellationToken)\n\t\t{\n\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar typeSystem = module.GetTypeSystemWithDecompilerSettingsOrNull(searchRequest.DecompilerSettings);\n\t\t\tif (typeSystem == null)\n\t\t\t\treturn;\n\n\t\t\tif (searchKind == MemberSearchKind.All || searchKind == MemberSearchKind.Type)\n\t\t\t{\n\t\t\t\tforeach (var handle in metadata.TypeDefinitions)\n\t\t\t\t{\n\t\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tstring languageSpecificName = language.GetEntityName(module, handle, fullNameSearch, omitGenerics);\n\t\t\t\t\tif (languageSpecificName != null && !IsMatch(languageSpecificName))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tvar type = ((MetadataModule)typeSystem.MainModule).GetDefinition(handle);\n\t\t\t\t\tif (!CheckVisibility(type) || !IsInNamespaceOrAssembly(type))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tOnFoundResult(type);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (searchKind == MemberSearchKind.All || searchKind == MemberSearchKind.Member || searchKind == MemberSearchKind.Method)\n\t\t\t{\n\t\t\t\tforeach (var handle in metadata.MethodDefinitions)\n\t\t\t\t{\n\t\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tstring languageSpecificName = language.GetEntityName(module, handle, fullNameSearch, omitGenerics);\n\t\t\t\t\tif (languageSpecificName != null && !IsMatch(languageSpecificName))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tvar method = ((MetadataModule)typeSystem.MainModule).GetDefinition(handle);\n\t\t\t\t\tif (!CheckVisibility(method) || !IsInNamespaceOrAssembly(method))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tOnFoundResult(method);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (searchKind == MemberSearchKind.All || searchKind == MemberSearchKind.Member || searchKind == MemberSearchKind.Field)\n\t\t\t{\n\t\t\t\tforeach (var handle in metadata.FieldDefinitions)\n\t\t\t\t{\n\t\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tstring languageSpecificName = language.GetEntityName(module, handle, fullNameSearch, omitGenerics);\n\t\t\t\t\tif (languageSpecificName != null && !IsMatch(languageSpecificName))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tvar field = ((MetadataModule)typeSystem.MainModule).GetDefinition(handle);\n\t\t\t\t\tif (!CheckVisibility(field) || !IsInNamespaceOrAssembly(field))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tOnFoundResult(field);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (searchKind == MemberSearchKind.All || searchKind == MemberSearchKind.Member || searchKind == MemberSearchKind.Property)\n\t\t\t{\n\t\t\t\tforeach (var handle in metadata.PropertyDefinitions)\n\t\t\t\t{\n\t\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tstring languageSpecificName = language.GetEntityName(module, handle, fullNameSearch, omitGenerics);\n\t\t\t\t\tif (languageSpecificName != null && !IsMatch(languageSpecificName))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tvar property = ((MetadataModule)typeSystem.MainModule).GetDefinition(handle);\n\t\t\t\t\tif (!CheckVisibility(property) || !IsInNamespaceOrAssembly(property))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tOnFoundResult(property);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (searchKind == MemberSearchKind.All || searchKind == MemberSearchKind.Member || searchKind == MemberSearchKind.Event)\n\t\t\t{\n\t\t\t\tforeach (var handle in metadata.EventDefinitions)\n\t\t\t\t{\n\t\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tstring languageSpecificName = language.GetEntityName(module, handle, fullNameSearch, omitGenerics);\n\t\t\t\t\tif (!IsMatch(languageSpecificName))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tvar @event = ((MetadataModule)typeSystem.MainModule).GetDefinition(handle);\n\t\t\t\t\tif (!CheckVisibility(@event) || !IsInNamespaceOrAssembly(@event))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tOnFoundResult(@event);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic enum MemberSearchKind\n\t{\n\t\tAll,\n\t\tType,\n\t\tMember,\n\t\tField,\n\t\tProperty,\n\t\tEvent,\n\t\tMethod\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Search/MetadataTokenSearchStrategy.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\nusing System.Collections.Concurrent;\nusing System.Globalization;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX.Abstractions;\n\nnamespace ICSharpCode.ILSpyX.Search\n{\n\tpublic class MetadataTokenSearchStrategy : AbstractEntitySearchStrategy\n\t{\n\t\treadonly EntityHandle searchTermToken;\n\n\t\tpublic MetadataTokenSearchStrategy(ILanguage language, ApiVisibility apiVisibility, SearchRequest request,\n\t\t\tIProducerConsumerCollection<SearchResult> resultQueue)\n\t\t\t: base(language, apiVisibility, request, resultQueue)\n\t\t{\n\t\t\tvar terms = request.Keywords;\n\t\t\tif (terms.Length == 1)\n\t\t\t{\n\t\t\t\tint.TryParse(terms[0], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var token);\n\t\t\t\tsearchTermToken = MetadataTokenHelpers.EntityHandleOrNil(token);\n\t\t\t}\n\t\t}\n\n\t\tpublic override void Search(MetadataFile module, CancellationToken cancellationToken)\n\t\t{\n\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\tif (searchTermToken.IsNil)\n\t\t\t\treturn;\n\t\t\tvar typeSystem = module.GetTypeSystemWithDecompilerSettingsOrNull(searchRequest.DecompilerSettings);\n\t\t\tif (typeSystem == null)\n\t\t\t\treturn;\n\t\t\tvar metadataModule = (MetadataModule)typeSystem.MainModule;\n\t\t\tint row = module.Metadata.GetRowNumber(searchTermToken);\n\n\t\t\tswitch (searchTermToken.Kind)\n\t\t\t{\n\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\t\tif (row < 1 || row > module.Metadata.TypeDefinitions.Count)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tvar type = metadataModule.GetDefinition((TypeDefinitionHandle)searchTermToken);\n\t\t\t\t\tif (!CheckVisibility(type) || !IsInNamespaceOrAssembly(type))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tOnFoundResult(type);\n\t\t\t\t\tbreak;\n\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\tif (row < 1 || row > module.Metadata.MethodDefinitions.Count)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tvar method = metadataModule.GetDefinition((MethodDefinitionHandle)searchTermToken);\n\t\t\t\t\tif (!CheckVisibility(method) || !IsInNamespaceOrAssembly(method))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tOnFoundResult(method);\n\t\t\t\t\tbreak;\n\t\t\t\tcase HandleKind.FieldDefinition:\n\t\t\t\t\tif (row < 1 || row > module.Metadata.FieldDefinitions.Count)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tvar field = metadataModule.GetDefinition((FieldDefinitionHandle)searchTermToken);\n\t\t\t\t\tif (!CheckVisibility(field) || !IsInNamespaceOrAssembly(field))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tOnFoundResult(field);\n\t\t\t\t\tbreak;\n\t\t\t\tcase HandleKind.PropertyDefinition:\n\t\t\t\t\tif (row < 1 || row > module.Metadata.PropertyDefinitions.Count)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tvar property = metadataModule.GetDefinition((PropertyDefinitionHandle)searchTermToken);\n\t\t\t\t\tif (!CheckVisibility(property) || !IsInNamespaceOrAssembly(property))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tOnFoundResult(property);\n\t\t\t\t\tbreak;\n\t\t\t\tcase HandleKind.EventDefinition:\n\t\t\t\t\tif (row < 1 || row > module.Metadata.EventDefinitions.Count)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tvar @event = metadataModule.GetDefinition((EventDefinitionHandle)searchTermToken);\n\t\t\t\t\tif (!CheckVisibility(@event) || !IsInNamespaceOrAssembly(@event))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tOnFoundResult(@event);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Search/NamespaceSearchStrategy.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Concurrent;\nusing System.Linq;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.ILSpyX.Search\n{\n\tpublic class NamespaceSearchStrategy : AbstractSearchStrategy\n\t{\n\t\tpublic NamespaceSearchStrategy(SearchRequest request, IProducerConsumerCollection<SearchResult> resultQueue)\n\t\t\t: base(request, resultQueue)\n\t\t{\n\t\t}\n\n\t\tpublic override void Search(MetadataFile module, CancellationToken cancellationToken)\n\t\t{\n\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\tvar typeSystem = module.GetTypeSystemWithDecompilerSettingsOrNull(searchRequest.DecompilerSettings);\n\t\t\tif (typeSystem == null)\n\t\t\t\treturn;\n\n\t\t\tvar root = ((MetadataModule)typeSystem.MainModule).RootNamespace;\n\t\t\tSearch(module, root);\n\t\t}\n\n\t\tprivate void Search(MetadataFile module, INamespace ns)\n\t\t{\n\t\t\tif (ns.Types.Any())\n\t\t\t{\n\t\t\t\tif (IsMatch(ns.FullName.Length == 0 ? \"-\" : ns.FullName))\n\t\t\t\t\tOnFoundResult(module, ns);\n\t\t\t}\n\n\t\t\tforeach (var child in ns.ChildNamespaces)\n\t\t\t\tSearch(module, child);\n\t\t}\n\n\t\tvoid OnFoundResult(MetadataFile module, INamespace ns)\n\t\t{\n\t\t\tOnFoundResult(searchRequest.SearchResultFactory.Create(module, ns));\n\t\t}\n\t}\n}"
  },
  {
    "path": "ICSharpCode.ILSpyX/Search/ResourceSearchStrategy.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\nusing System.Collections.Concurrent;\nusing System.Reflection;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpyX.Abstractions;\n\nnamespace ICSharpCode.ILSpyX.Search\n{\n\tpublic class ResourceSearchStrategy : AbstractSearchStrategy\n\t{\n\t\tprotected readonly bool searchInside;\n\t\tprotected readonly ApiVisibility apiVisibility;\n\t\tprotected readonly ITreeNodeFactory treeNodeFactory;\n\n\t\tpublic ResourceSearchStrategy(ApiVisibility apiVisibility, SearchRequest request, IProducerConsumerCollection<SearchResult> resultQueue)\n\t\t\t: base(request, resultQueue)\n\t\t{\n\t\t\tthis.treeNodeFactory = request.TreeNodeFactory;\n\t\t\tthis.apiVisibility = apiVisibility;\n\t\t\tthis.searchInside = true;\n\t\t}\n\n\t\tprotected bool CheckVisibility(Resource resource)\n\t\t{\n\t\t\tif (apiVisibility == ApiVisibility.All)\n\t\t\t\treturn true;\n\n\t\t\tif (apiVisibility == ApiVisibility.PublicOnly && (resource.Attributes & ManifestResourceAttributes.VisibilityMask) == ManifestResourceAttributes.Private)\n\t\t\t\treturn false;\n\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic override void Search(MetadataFile module, CancellationToken cancellationToken)\n\t\t{\n\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\tvar resourcesNode = treeNodeFactory.CreateResourcesList(module);\n\n\t\t\tforeach (Resource resource in module.Resources)\n\t\t\t\tSearch(module, resource, resourcesNode, treeNodeFactory.Create(resource), cancellationToken);\n\t\t}\n\n\t\tvoid Search(MetadataFile module, Resource resource, ITreeNode parent, ITreeNode node, CancellationToken cancellationToken)\n\t\t{\n\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\n\t\t\tif (node is IResourcesFileTreeNode treeNode)\n\t\t\t{\n\t\t\t\tif (!CheckVisibility(treeNode.Resource))\n\t\t\t\t\treturn;\n\t\t\t\tresource = treeNode.Resource;\n\t\t\t}\n\n\t\t\tif (node.Text is string s && IsMatch(s))\n\t\t\t\tOnFoundResult(module, resource, node, parent);\n\n\t\t\tif (!searchInside)\n\t\t\t\treturn;\n\n\t\t\tnode.EnsureLazyChildren();\n\t\t\tforeach (var child in node.Children)\n\t\t\t\tSearch(module, resource, node, child, cancellationToken);\n\t\t}\n\n\t\tvoid OnFoundResult(MetadataFile module, Resource resource, ITreeNode node, ITreeNode parent)\n\t\t{\n\t\t\tOnFoundResult(searchRequest.SearchResultFactory.Create(module, resource, node, parent));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Search/SearchResult.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX.Abstractions;\n\nnamespace ICSharpCode.ILSpyX.Search\n{\n\tpublic interface ISearchResultFactory\n\t{\n\t\tMemberSearchResult Create(IEntity entity);\n\t\tResourceSearchResult Create(MetadataFile module, Resource resource, ITreeNode node, ITreeNode parent);\n\t\tAssemblySearchResult Create(MetadataFile module);\n\t\tNamespaceSearchResult Create(MetadataFile module, INamespace @namespace);\n\t}\n\n\tpublic class SearchResult\n\t{\n\t\tpublic static readonly IComparer<SearchResult> ComparerByName = new SearchResultNameComparer();\n\t\tpublic static readonly IComparer<SearchResult> ComparerByFitness = new SearchResultFitnessComparer();\n\n\t\tpublic virtual object? Reference => null;\n\n\t\tpublic float Fitness { get; set; }\n\n\t\tpublic required string Name { get; set; }\n\t\tpublic required string Location { get; set; }\n\t\tpublic required string Assembly { get; set; }\n\t\tpublic object? ToolTip { get; set; }\n\t\tpublic required object Image { get; set; }\n\t\tpublic required object LocationImage { get; set; }\n\n\t\tpublic required object AssemblyImage { get; set; }\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn Name;\n\t\t}\n\n\t\tclass SearchResultNameComparer : IComparer<SearchResult>\n\t\t{\n\t\t\tpublic int Compare(SearchResult? x, SearchResult? y)\n\t\t\t{\n\t\t\t\treturn StringComparer.Ordinal.Compare(x?.Name ?? \"\", y?.Name ?? \"\");\n\t\t\t}\n\t\t}\n\n\t\tclass SearchResultFitnessComparer : IComparer<SearchResult>\n\t\t{\n\t\t\tpublic int Compare(SearchResult? x, SearchResult? y)\n\t\t\t{\n\t\t\t\t//elements with higher Fitness come first\n\t\t\t\treturn Comparer<float>.Default.Compare(y?.Fitness ?? 0, x?.Fitness ?? 0);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic class MemberSearchResult : SearchResult\n\t{\n#nullable disable\n\t\tpublic IEntity Member { get; set; }\n\t\tpublic override object Reference => Member;\n#nullable enable\n\t}\n\n\tpublic class ResourceSearchResult : SearchResult\n\t{\n#nullable disable\n\t\tpublic Resource Resource { get; set; }\n#nullable enable\n\t\tpublic override object Reference => ValueTuple.Create(Resource, Name);\n\t}\n\n\tpublic class AssemblySearchResult : SearchResult\n\t{\n#nullable disable\n\t\tpublic MetadataFile Module { get; set; }\n\t\tpublic override object Reference => Module;\n#nullable enable\n\t}\n\n\tpublic class NamespaceSearchResult : SearchResult\n\t{\n#nullable disable\n\t\tpublic INamespace Namespace { get; set; }\n\t\tpublic override object Reference => Namespace;\n#nullable enable\n\t}\n}"
  },
  {
    "path": "ICSharpCode.ILSpyX/Settings/DecompilerSettings.cs",
    "content": "// Copyright (c) 2024 Tom Englert\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.ComponentModel;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing System.Reflection;\nusing System.Xml.Linq;\n\nnamespace ICSharpCode.ILSpyX.Settings\n{\n\tpublic class DecompilerSettings : Decompiler.DecompilerSettings, ISettingsSection\n\t{\n\t\tstatic readonly PropertyInfo[] properties = typeof(Decompiler.DecompilerSettings).GetProperties()\n\t\t\t\t.Where(p => p.GetCustomAttribute<BrowsableAttribute>()?.Browsable != false)\n\t\t\t\t.ToArray();\n\n\t\tpublic XName SectionName => \"DecompilerSettings\";\n\n\t\tpublic XElement SaveToXml()\n\t\t{\n\t\t\tvar section = new XElement(SectionName);\n\n\t\t\tforeach (var p in properties)\n\t\t\t{\n\t\t\t\tsection.SetAttributeValue(p.Name, p.GetValue(this));\n\t\t\t}\n\n\t\t\treturn section;\n\t\t}\n\n\t\tpublic void LoadFromXml(XElement section)\n\t\t{\n\t\t\tforeach (var p in properties)\n\t\t\t{\n\t\t\t\tvar value = (bool?)section.Attribute(p.Name);\n\t\t\t\tif (value.HasValue)\n\t\t\t\t\tp.SetValue(this, value.Value);\n\t\t\t}\n\t\t}\n\n\t\tpublic override DecompilerSettings Clone()\n\t\t{\n\t\t\treturn (DecompilerSettings)base.Clone();\n\t\t}\n\n\t\tpublic static bool IsKnownOption(string name, [NotNullWhen(true)] out PropertyInfo? property)\n\t\t{\n\t\t\tproperty = null;\n\t\t\tforeach (var item in properties)\n\t\t\t{\n\t\t\t\tif (item.Name != name)\n\t\t\t\t\tcontinue;\n\t\t\t\tproperty = item;\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Settings/DefaultSettingsFilePathProvider.cs",
    "content": "// Copyright (c) 2022 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.ILSpyX.Settings\n{\n\t/// <summary>\n\t/// Used in scenarios where the user passes a path and that is to be used, eg ilspycmd parameter\n\t/// </summary>\n\tpublic class DefaultSettingsFilePathProvider : ISettingsFilePathProvider\n\t{\n\t\tprivate readonly string _providedPath;\n\n\t\tpublic DefaultSettingsFilePathProvider(string providedPath)\n\t\t{\n\t\t\t_providedPath = providedPath;\n\t\t}\n\n\t\tpublic string GetSettingsFilePath()\n\t\t{\n\t\t\treturn _providedPath;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Settings/ILSpySettings.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\nusing System.Threading;\nusing System.Xml;\nusing System.Xml.Linq;\n\nnamespace ICSharpCode.ILSpyX.Settings\n{\n\t/// <summary>\n\t/// Manages IL Spy settings.\n\t/// </summary>\n\tpublic class ILSpySettings : ISettingsProvider\n\t{\n\t\t/// <summary>\n\t\t/// This settings file path provider determines where to load settings file from, includes filename\n\t\t/// </summary>\n\t\tpublic static ISettingsFilePathProvider? SettingsFilePathProvider { get; set; }\n\n\t\tXElement root;\n\n\t\tILSpySettings(XElement? root = null)\n\t\t{\n\t\t\tthis.root = root ?? new XElement(\"ILSpy\");\n\t\t}\n\n\t\tpublic XElement this[XName section] {\n\t\t\tget {\n\t\t\t\treturn root.Element(section) ?? new XElement(section);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Loads the settings file from disk.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// An instance used to access the loaded settings.\n\t\t/// </returns>\n\t\tpublic static ILSpySettings Load()\n\t\t{\n\t\t\tusing (new MutexProtector(ConfigFileMutex))\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\treturn new ILSpySettings(LoadFile(GetConfigFile()).Root);\n\t\t\t\t}\n\t\t\t\tcatch (IOException)\n\t\t\t\t{\n\t\t\t\t\treturn new ILSpySettings();\n\t\t\t\t}\n\t\t\t\tcatch (XmlException)\n\t\t\t\t{\n\t\t\t\t\treturn new ILSpySettings();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic XDocument LoadFile(string fileName)\n\t\t{\n\t\t\treturn XDocument.Load(fileName, LoadOptions.None);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Saves a setting section.\n\t\t/// </summary>\n\t\tpublic void SaveSettings(XElement section)\n\t\t{\n\t\t\tUpdate(rootElement => {\n\t\t\t\tXElement? existingElement = rootElement.Element(section.Name);\n\t\t\t\tif (existingElement != null)\n\t\t\t\t\texistingElement.ReplaceWith(section);\n\t\t\t\telse\n\t\t\t\t\trootElement.Add(section);\n\t\t\t});\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Updates the saved settings.\n\t\t/// We always reload the file on updates to ensure we aren't overwriting unrelated changes performed\n\t\t/// by another ILSpy instance.\n\t\t/// </summary>\n\t\tpublic void Update(Action<XElement> action)\n\t\t{\n\t\t\tusing (new MutexProtector(ConfigFileMutex))\n\t\t\t{\n\t\t\t\tstring config = GetConfigFile();\n\t\t\t\tXDocument doc;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tdoc = LoadFile(config);\n\t\t\t\t}\n\t\t\t\tcatch (IOException)\n\t\t\t\t{\n\t\t\t\t\t// ensure the directory exists\n\t\t\t\t\tDirectory.CreateDirectory(Path.GetDirectoryName(config)!);\n\t\t\t\t\tdoc = new XDocument(new XElement(\"ILSpy\"));\n\t\t\t\t}\n\t\t\t\tcatch (XmlException)\n\t\t\t\t{\n\t\t\t\t\tdoc = new XDocument(new XElement(\"ILSpy\"));\n\t\t\t\t}\n\t\t\t\tdoc.Root!.SetAttributeValue(\"version\", DecompilerVersionInfo.Major + \".\" + DecompilerVersionInfo.Minor + \".\" + DecompilerVersionInfo.Build + \".\" + DecompilerVersionInfo.Revision);\n\t\t\t\taction(doc.Root);\n\t\t\t\tdoc.Save(config, SaveOptions.None);\n\t\t\t\tthis.root = doc.Root;\n\t\t\t}\n\t\t}\n\n\t\tstatic string GetConfigFile()\n\t\t{\n\t\t\tif (null != SettingsFilePathProvider)\n\t\t\t\treturn SettingsFilePathProvider.GetSettingsFilePath();\n\n\t\t\tthrow new ArgumentNullException(nameof(SettingsFilePathProvider));\n\t\t\t// return \"ILSpy.xml\";\n\t\t}\n\n\t\tconst string ConfigFileMutex = \"01A91708-49D1-410D-B8EB-4DE2662B3971\";\n\n\t\t/// <summary>\n\t\t/// Helper class for serializing access to the config file when multiple ILSpy instances are running.\n\t\t/// </summary>\n\t\tsealed class MutexProtector : IDisposable\n\t\t{\n\t\t\treadonly Mutex mutex;\n\n\t\t\tpublic MutexProtector(string name)\n\t\t\t{\n\t\t\t\tthis.mutex = new Mutex(true, name, out bool createdNew);\n\t\t\t\tif (createdNew)\n\t\t\t\t\treturn;\n\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tmutex.WaitOne();\n\t\t\t\t}\n\t\t\t\tcatch (AbandonedMutexException)\n\t\t\t\t{\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic void Dispose()\n\t\t\t{\n\t\t\t\tmutex.ReleaseMutex();\n\t\t\t\tmutex.Dispose();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Settings/ISettingsFilePathProvider.cs",
    "content": "// Copyright (c) 2022 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.ILSpyX.Settings\n{\n\tpublic interface ISettingsFilePathProvider\n\t{\n\t\tstring GetSettingsFilePath();\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Settings/ISettingsProvider.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Xml.Linq;\n\nnamespace ICSharpCode.ILSpyX.Settings\n{\n\tpublic interface ISettingsProvider\n\t{\n\t\tXElement this[XName section] { get; }\n\n\t\tvoid Update(Action<XElement> action);\n\n\t\tvoid SaveSettings(XElement section);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/Settings/SettingsServiceBase.cs",
    "content": "// Copyright (c) 2024 Tom Englert\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Concurrent;\nusing System.ComponentModel;\nusing System.Xml.Linq;\n\nnamespace ICSharpCode.ILSpyX.Settings\n{\n\tpublic interface IChildSettings\n\t{\n\t\tISettingsSection Parent { get; }\n\t}\n\n\tpublic interface ISettingsSection : INotifyPropertyChanged\n\t{\n\t\tXName SectionName { get; }\n\n\t\tvoid LoadFromXml(XElement section);\n\n\t\tXElement SaveToXml();\n\t}\n\n\tpublic class SettingsServiceBase(ISettingsProvider spySettings)\n\t{\n\t\tprotected readonly ConcurrentDictionary<Type, ISettingsSection> sections = new();\n\n\t\tprotected ISettingsProvider SpySettings { get; set; } = spySettings;\n\n\t\tpublic T GetSettings<T>() where T : ISettingsSection, new()\n\t\t{\n\t\t\treturn (T)sections.GetOrAdd(typeof(T), _ => {\n\t\t\t\tT section = new T();\n\n\t\t\t\tvar sectionElement = SpySettings[section.SectionName];\n\n\t\t\t\tsection.LoadFromXml(sectionElement);\n\t\t\t\tsection.PropertyChanged += Section_PropertyChanged;\n\n\t\t\t\treturn section;\n\t\t\t});\n\t\t}\n\n\t\tprotected static void SaveSection(ISettingsSection section, XElement root)\n\t\t{\n\t\t\tvar element = section.SaveToXml();\n\n\t\t\tvar existingElement = root.Element(section.SectionName);\n\t\t\tif (existingElement != null)\n\t\t\t\texistingElement.ReplaceWith(element);\n\t\t\telse\n\t\t\t\troot.Add(element);\n\t\t}\n\n\t\tprotected virtual void Section_PropertyChanged(object? sender, PropertyChangedEventArgs e)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/TreeView/FlatListTreeNode.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\n\n#nullable disable\n\nnamespace ICSharpCode.ILSpyX.TreeView\n{\n\t// This part of SharpTreeNode controls the 'flat list' data structure, which emulates\n\t// a big flat list containing the whole tree; allowing access by visible index.\n\tpartial class SharpTreeNode\n\t{\n\t\t/// <summary>The parent in the flat list</summary>\n\t\tinternal SharpTreeNode listParent;\n\t\t/// <summary>Left/right nodes in the flat list</summary>\n\t\tSharpTreeNode left, right;\n\n\t\tinternal TreeFlattener treeFlattener;\n\n\t\t/// <summary>Subtree height in the flat list tree</summary>\n\t\tbyte height = 1;\n\n\t\t/// <summary>Length in the flat list, including children (children within the flat list). -1 = invalidated</summary>\n\t\tint totalListLength = -1;\n\n\t\tint Balance {\n\t\t\tget { return Height(right) - Height(left); }\n\t\t}\n\n\t\tstatic int Height(SharpTreeNode node)\n\t\t{\n\t\t\treturn node != null ? node.height : 0;\n\t\t}\n\n\t\tinternal SharpTreeNode GetListRoot()\n\t\t{\n\t\t\tSharpTreeNode node = this;\n\t\t\twhile (node.listParent != null)\n\t\t\t\tnode = node.listParent;\n\t\t\treturn node;\n\t\t}\n\n\t\t#region Debugging\n\t\t[Conditional(\"DEBUG\")]\n\t\tvoid CheckRootInvariants()\n\t\t{\n\t\t\tGetListRoot().CheckInvariants();\n\t\t}\n\n\t\t[Conditional(\"DATACONSISTENCYCHECK\")]\n\t\tvoid CheckInvariants()\n\t\t{\n\t\t\tDebug.Assert(left == null || left.listParent == this);\n\t\t\tDebug.Assert(right == null || right.listParent == this);\n\t\t\tDebug.Assert(height == 1 + Math.Max(Height(left), Height(right)));\n\t\t\tDebug.Assert(Math.Abs(this.Balance) <= 1);\n\t\t\tDebug.Assert(totalListLength == -1 || totalListLength == (left != null ? left.totalListLength : 0) + (isVisible ? 1 : 0) + (right != null ? right.totalListLength : 0));\n\t\t\tif (left != null)\n\t\t\t\tleft.CheckInvariants();\n\t\t\tif (right != null)\n\t\t\t\tright.CheckInvariants();\n\t\t}\n\n\t\t[Conditional(\"DEBUG\")]\n\t\tstatic void DumpTree(SharpTreeNode node)\n\t\t{\n\t\t\tnode.GetListRoot().DumpTree();\n\t\t}\n\n\t\t[Conditional(\"DEBUG\")]\n\t\tvoid DumpTree()\n\t\t{\n\t\t\tDebug.Indent();\n\t\t\tif (left != null)\n\t\t\t\tleft.DumpTree();\n\t\t\tDebug.Unindent();\n\t\t\tDebug.WriteLine(\"{0}, totalListLength={1}, height={2}, Balance={3}, isVisible={4}\", ToString(), totalListLength, height, Balance, isVisible);\n\t\t\tDebug.Indent();\n\t\t\tif (right != null)\n\t\t\t\tright.DumpTree();\n\t\t\tDebug.Unindent();\n\t\t}\n\t\t#endregion\n\n\t\t#region GetNodeByVisibleIndex / GetVisibleIndexForNode\n\t\tinternal static SharpTreeNode GetNodeByVisibleIndex(SharpTreeNode root, int index)\n\t\t{\n\t\t\troot.GetTotalListLength(); // ensure all list lengths are calculated\n\t\t\tDebug.Assert(index >= 0);\n\t\t\tDebug.Assert(index < root.totalListLength);\n\t\t\tSharpTreeNode node = root;\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tif (node.left != null && index < node.left.totalListLength)\n\t\t\t\t{\n\t\t\t\t\tnode = node.left;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (node.left != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tindex -= node.left.totalListLength;\n\t\t\t\t\t}\n\t\t\t\t\tif (node.isVisible)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (index == 0)\n\t\t\t\t\t\t\treturn node;\n\t\t\t\t\t\tindex--;\n\t\t\t\t\t}\n\t\t\t\t\tnode = node.right;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tinternal static int GetVisibleIndexForNode(SharpTreeNode node)\n\t\t{\n\t\t\tint index = node.left != null ? node.left.GetTotalListLength() : 0;\n\t\t\twhile (node.listParent != null)\n\t\t\t{\n\t\t\t\tif (node == node.listParent.right)\n\t\t\t\t{\n\t\t\t\t\tif (node.listParent.left != null)\n\t\t\t\t\t\tindex += node.listParent.left.GetTotalListLength();\n\t\t\t\t\tif (node.listParent.isVisible)\n\t\t\t\t\t\tindex++;\n\t\t\t\t}\n\t\t\t\tnode = node.listParent;\n\t\t\t}\n\t\t\treturn index;\n\t\t}\n\t\t#endregion\n\n\t\t#region Balancing\n\t\t/// <summary>\n\t\t/// Balances the subtree rooted in <paramref name=\"node\"/> and recomputes the 'height' field.\n\t\t/// This method assumes that the children of this node are already balanced and have an up-to-date 'height' value.\n\t\t/// </summary>\n\t\t/// <returns>The new root node</returns>\n\t\tstatic SharpTreeNode Rebalance(SharpTreeNode node)\n\t\t{\n\t\t\tDebug.Assert(node.left == null || Math.Abs(node.left.Balance) <= 1);\n\t\t\tDebug.Assert(node.right == null || Math.Abs(node.right.Balance) <= 1);\n\t\t\t// Keep looping until it's balanced. Not sure if this is stricly required; this is based on\n\t\t\t// the Rope code where node merging made this necessary.\n\t\t\twhile (Math.Abs(node.Balance) > 1)\n\t\t\t{\n\t\t\t\t// AVL balancing\n\t\t\t\t// note: because we don't care about the identity of concat nodes, this works a little different than usual\n\t\t\t\t// tree rotations: in our implementation, the \"this\" node will stay at the top, only its children are rearranged\n\t\t\t\tif (node.Balance > 1)\n\t\t\t\t{\n\t\t\t\t\tif (node.right.Balance < 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tnode.right = node.right.RotateRight();\n\t\t\t\t\t}\n\t\t\t\t\tnode = node.RotateLeft();\n\t\t\t\t\t// If 'node' was unbalanced by more than 2, we've shifted some of the inbalance to the left node; so rebalance that.\n\t\t\t\t\tnode.left = Rebalance(node.left);\n\t\t\t\t}\n\t\t\t\telse if (node.Balance < -1)\n\t\t\t\t{\n\t\t\t\t\tif (node.left.Balance > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tnode.left = node.left.RotateLeft();\n\t\t\t\t\t}\n\t\t\t\t\tnode = node.RotateRight();\n\t\t\t\t\t// If 'node' was unbalanced by more than 2, we've shifted some of the inbalance to the right node; so rebalance that.\n\t\t\t\t\tnode.right = Rebalance(node.right);\n\t\t\t\t}\n\t\t\t}\n\t\t\tDebug.Assert(Math.Abs(node.Balance) <= 1);\n\t\t\tnode.height = (byte)(1 + Math.Max(Height(node.left), Height(node.right)));\n\t\t\tnode.totalListLength = -1; // mark for recalculation\n\t\t\t\t\t\t\t\t\t   // since balancing checks the whole tree up to the root, the whole path will get marked as invalid\n\t\t\treturn node;\n\t\t}\n\n\t\tinternal int GetTotalListLength()\n\t\t{\n\t\t\tif (totalListLength >= 0)\n\t\t\t\treturn totalListLength;\n\t\t\tint length = (isVisible ? 1 : 0);\n\t\t\tif (left != null)\n\t\t\t{\n\t\t\t\tlength += left.GetTotalListLength();\n\t\t\t}\n\t\t\tif (right != null)\n\t\t\t{\n\t\t\t\tlength += right.GetTotalListLength();\n\t\t\t}\n\t\t\treturn totalListLength = length;\n\t\t}\n\n\t\tSharpTreeNode RotateLeft()\n\t\t{\n\t\t\t/* Rotate tree to the left\n\t\t\t * \n\t\t\t *       this               right\n\t\t\t *       /  \\               /  \\\n\t\t\t *      A   right   ===>  this  C\n\t\t\t *           / \\          / \\\n\t\t\t *          B   C        A   B\n\t\t\t */\n\t\t\tSharpTreeNode b = right.left;\n\t\t\tSharpTreeNode newTop = right;\n\n\t\t\tif (b != null)\n\t\t\t\tb.listParent = this;\n\t\t\tthis.right = b;\n\t\t\tnewTop.left = this;\n\t\t\tnewTop.listParent = this.listParent;\n\t\t\tthis.listParent = newTop;\n\t\t\t// rebalance the 'this' node - this is necessary in some bulk insertion cases:\n\t\t\tnewTop.left = Rebalance(this);\n\t\t\treturn newTop;\n\t\t}\n\n\t\tSharpTreeNode RotateRight()\n\t\t{\n\t\t\t/* Rotate tree to the right\n\t\t\t * \n\t\t\t *       this             left\n\t\t\t *       /  \\             /  \\\n\t\t\t *     left  C   ===>    A   this\n\t\t\t *     / \\                   /  \\\n\t\t\t *    A   B                 B    C\n\t\t\t */\n\t\t\tSharpTreeNode b = left.right;\n\t\t\tSharpTreeNode newTop = left;\n\n\t\t\tif (b != null)\n\t\t\t\tb.listParent = this;\n\t\t\tthis.left = b;\n\t\t\tnewTop.right = this;\n\t\t\tnewTop.listParent = this.listParent;\n\t\t\tthis.listParent = newTop;\n\t\t\tnewTop.right = Rebalance(this);\n\t\t\treturn newTop;\n\t\t}\n\n\t\tstatic void RebalanceUntilRoot(SharpTreeNode pos)\n\t\t{\n\t\t\twhile (pos.listParent != null)\n\t\t\t{\n\t\t\t\tif (pos == pos.listParent.left)\n\t\t\t\t{\n\t\t\t\t\tpos = pos.listParent.left = Rebalance(pos);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(pos == pos.listParent.right);\n\t\t\t\t\tpos = pos.listParent.right = Rebalance(pos);\n\t\t\t\t}\n\t\t\t\tpos = pos.listParent;\n\t\t\t}\n\t\t\tSharpTreeNode newRoot = Rebalance(pos);\n\t\t\tif (newRoot != pos && pos.treeFlattener != null)\n\t\t\t{\n\t\t\t\tDebug.Assert(newRoot.treeFlattener == null);\n\t\t\t\tnewRoot.treeFlattener = pos.treeFlattener;\n\t\t\t\tpos.treeFlattener = null;\n\t\t\t\tnewRoot.treeFlattener.root = newRoot;\n\t\t\t}\n\t\t\tDebug.Assert(newRoot.listParent == null);\n\t\t\tnewRoot.CheckInvariants();\n\t\t}\n\t\t#endregion\n\n\t\t#region Insertion\n\t\tstatic void InsertNodeAfter(SharpTreeNode pos, SharpTreeNode newNode)\n\t\t{\n\t\t\t// newNode might be the model root of a whole subtree, so go to the list root of that subtree:\n\t\t\tnewNode = newNode.GetListRoot();\n\t\t\tif (pos.right == null)\n\t\t\t{\n\t\t\t\tpos.right = newNode;\n\t\t\t\tnewNode.listParent = pos;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// insert before pos.right's leftmost:\n\t\t\t\tpos = pos.right;\n\t\t\t\twhile (pos.left != null)\n\t\t\t\t\tpos = pos.left;\n\t\t\t\tDebug.Assert(pos.left == null);\n\t\t\t\tpos.left = newNode;\n\t\t\t\tnewNode.listParent = pos;\n\t\t\t}\n\t\t\tRebalanceUntilRoot(pos);\n\t\t}\n\t\t#endregion\n\n\t\t#region Removal\n\t\tvoid RemoveNodes(SharpTreeNode start, SharpTreeNode end)\n\t\t{\n\t\t\t// Removes all nodes from start to end (inclusive)\n\t\t\t// All removed nodes will be reorganized in a separate tree, do not delete\n\t\t\t// regions that don't belong together in the tree model!\n\n\t\t\tList<SharpTreeNode> removedSubtrees = new List<SharpTreeNode>();\n\t\t\tSharpTreeNode oldPos;\n\t\t\tSharpTreeNode pos = start;\n\t\t\tdo\n\t\t\t{\n\t\t\t\t// recalculate the endAncestors every time, because the tree might have been rebalanced\n\t\t\t\tHashSet<SharpTreeNode> endAncestors = new HashSet<SharpTreeNode>();\n\t\t\t\tfor (SharpTreeNode tmp = end; tmp != null; tmp = tmp.listParent)\n\t\t\t\t\tendAncestors.Add(tmp);\n\n\t\t\t\tremovedSubtrees.Add(pos);\n\t\t\t\tif (!endAncestors.Contains(pos))\n\t\t\t\t{\n\t\t\t\t\t// we can remove pos' right subtree in a single step:\n\t\t\t\t\tif (pos.right != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tremovedSubtrees.Add(pos.right);\n\t\t\t\t\t\tpos.right.listParent = null;\n\t\t\t\t\t\tpos.right = null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tSharpTreeNode succ = pos.Successor();\n\t\t\t\tDeleteNode(pos); // this will also rebalance out the deletion of the right subtree\n\n\t\t\t\toldPos = pos;\n\t\t\t\tpos = succ;\n\t\t\t} while (oldPos != end);\n\n\t\t\t// merge back together the removed subtrees:\n\t\t\tSharpTreeNode removed = removedSubtrees[0];\n\t\t\tfor (int i = 1; i < removedSubtrees.Count; i++)\n\t\t\t{\n\t\t\t\tremoved = ConcatTrees(removed, removedSubtrees[i]);\n\t\t\t}\n\t\t}\n\n\t\tstatic SharpTreeNode ConcatTrees(SharpTreeNode first, SharpTreeNode second)\n\t\t{\n\t\t\tSharpTreeNode tmp = first;\n\t\t\twhile (tmp.right != null)\n\t\t\t\ttmp = tmp.right;\n\t\t\tInsertNodeAfter(tmp, second);\n\t\t\treturn tmp.GetListRoot();\n\t\t}\n\n\t\tSharpTreeNode Successor()\n\t\t{\n\t\t\tif (right != null)\n\t\t\t{\n\t\t\t\tSharpTreeNode node = right;\n\t\t\t\twhile (node.left != null)\n\t\t\t\t\tnode = node.left;\n\t\t\t\treturn node;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tSharpTreeNode node = this;\n\t\t\t\tSharpTreeNode oldNode;\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\toldNode = node;\n\t\t\t\t\tnode = node.listParent;\n\t\t\t\t\t// loop while we are on the way up from the right part\n\t\t\t\t} while (node != null && node.right == oldNode);\n\t\t\t\treturn node;\n\t\t\t}\n\t\t}\n\n\t\tstatic void DeleteNode(SharpTreeNode node)\n\t\t{\n\t\t\tSharpTreeNode balancingNode;\n\t\t\tif (node.left == null)\n\t\t\t{\n\t\t\t\tbalancingNode = node.listParent;\n\t\t\t\tnode.ReplaceWith(node.right);\n\t\t\t\tnode.right = null;\n\t\t\t}\n\t\t\telse if (node.right == null)\n\t\t\t{\n\t\t\t\tbalancingNode = node.listParent;\n\t\t\t\tnode.ReplaceWith(node.left);\n\t\t\t\tnode.left = null;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tSharpTreeNode tmp = node.right;\n\t\t\t\twhile (tmp.left != null)\n\t\t\t\t\ttmp = tmp.left;\n\t\t\t\t// First replace tmp with tmp.right\n\t\t\t\tbalancingNode = tmp.listParent;\n\t\t\t\ttmp.ReplaceWith(tmp.right);\n\t\t\t\ttmp.right = null;\n\t\t\t\tDebug.Assert(tmp.left == null);\n\t\t\t\tDebug.Assert(tmp.listParent == null);\n\t\t\t\t// Now move node's children to tmp:\n\t\t\t\ttmp.left = node.left;\n\t\t\t\tnode.left = null;\n\t\t\t\ttmp.right = node.right;\n\t\t\t\tnode.right = null;\n\t\t\t\tif (tmp.left != null)\n\t\t\t\t\ttmp.left.listParent = tmp;\n\t\t\t\tif (tmp.right != null)\n\t\t\t\t\ttmp.right.listParent = tmp;\n\t\t\t\t// Then replace node with tmp\n\t\t\t\tnode.ReplaceWith(tmp);\n\t\t\t\tif (balancingNode == node)\n\t\t\t\t\tbalancingNode = tmp;\n\t\t\t}\n\t\t\tDebug.Assert(node.listParent == null);\n\t\t\tDebug.Assert(node.left == null);\n\t\t\tDebug.Assert(node.right == null);\n\t\t\tnode.height = 1;\n\t\t\tnode.totalListLength = -1;\n\t\t\tif (balancingNode != null)\n\t\t\t\tRebalanceUntilRoot(balancingNode);\n\t\t}\n\n\t\tvoid ReplaceWith(SharpTreeNode node)\n\t\t{\n\t\t\tif (listParent != null)\n\t\t\t{\n\t\t\t\tif (listParent.left == this)\n\t\t\t\t{\n\t\t\t\t\tlistParent.left = node;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(listParent.right == this);\n\t\t\t\t\tlistParent.right = node;\n\t\t\t\t}\n\t\t\t\tif (node != null)\n\t\t\t\t\tnode.listParent = listParent;\n\t\t\t\tlistParent = null;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// this was a root node\n\t\t\t\tDebug.Assert(node != null); // cannot delete the only node in the tree\n\t\t\t\tnode.listParent = null;\n\t\t\t\tif (treeFlattener != null)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(node.treeFlattener == null);\n\t\t\t\t\tnode.treeFlattener = this.treeFlattener;\n\t\t\t\t\tthis.treeFlattener = null;\n\t\t\t\t\tnode.treeFlattener.root = node;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/TreeView/PlatformAbstractions/IPlatformDataObject.cs",
    "content": "namespace ICSharpCode.ILSpyX.TreeView.PlatformAbstractions\n{\n\tpublic interface IPlatformDataObject\n\t{\n\t\tbool GetDataPresent(string format);\n\t\tobject GetData(string format);\n\t\tvoid SetData(string format, object data);\n\t\tobject UnderlyingDataObject { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/TreeView/PlatformAbstractions/IPlatformDragDrop.cs",
    "content": "namespace ICSharpCode.ILSpyX.TreeView.PlatformAbstractions\n{\n\tpublic interface IPlatformDragDrop\n\t{\n\t\tXPlatDragDropEffects DoDragDrop(object dragSource, IPlatformDataObject data, XPlatDragDropEffects allowedEffects);\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/TreeView/PlatformAbstractions/IPlatformDragEventArgs.cs",
    "content": "namespace ICSharpCode.ILSpyX.TreeView.PlatformAbstractions\n{\n\tpublic interface IPlatformDragEventArgs\n\t{\n\t\tXPlatDragDropEffects Effects { get; set; }\n\t\tIPlatformDataObject Data { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/TreeView/PlatformAbstractions/IPlatformRoutedEventArgs.cs",
    "content": "namespace ICSharpCode.ILSpyX.TreeView.PlatformAbstractions\n{\n\tpublic interface IPlatformRoutedEventArgs\n\t{\n\t\tbool Handled { get; set; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/TreeView/PlatformAbstractions/ITreeNodeImagesProvider.cs",
    "content": "namespace ICSharpCode.ILSpyX.TreeView.PlatformAbstractions\n{\n\tpublic interface ITreeNodeImagesProvider\n\t{\n\t\tobject Assembly { get; }\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/TreeView/PlatformAbstractions/XPlatDragDropEffects.cs",
    "content": "using System;\n\nnamespace ICSharpCode.ILSpyX.TreeView.PlatformAbstractions\n{\n\t//\n\t// Summary:\n\t//     Specifies the effects of a drag-and-drop operation.\n\t[Flags]\n\tpublic enum XPlatDragDropEffects\n\t{\n\t\t//\n\t\t// Summary:\n\t\t//     Scrolling is about to start or is currently occurring in the drop target.\n\t\tScroll = int.MinValue,\n\t\t//\n\t\t// Summary:\n\t\t//     The data is copied, removed from the drag source, and scrolled in the drop target.\n\t\tAll = -2147483645,\n\t\t//\n\t\t// Summary:\n\t\t//     The drop target does not accept the data.\n\t\tNone = 0,\n\t\t//\n\t\t// Summary:\n\t\t//     The data is copied to the drop target.\n\t\tCopy = 1,\n\t\t//\n\t\t// Summary:\n\t\t//     The data from the drag source is moved to the drop target.\n\t\tMove = 2,\n\t\t//\n\t\t// Summary:\n\t\t//     The data from the drag source is linked to the drop target.\n\t\tLink = 4\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\n\nusing ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;\n\nnamespace ICSharpCode.ILSpyX.TreeView\n{\n\tpublic partial class SharpTreeNode : INotifyPropertyChanged\n\t{\n\t\t[AllowNull]\n\t\tprotected static ITreeNodeImagesProvider ImagesProvider { get; private set; }\n\t\tpublic static void SetImagesProvider(ITreeNodeImagesProvider provider) => ImagesProvider = provider;\n\n\t\tSharpTreeNodeCollection? modelChildren;\n\t\tinternal SharpTreeNode? modelParent;\n\t\tbool isVisible = true;\n\n\t\tvoid UpdateIsVisible(bool parentIsVisible, bool updateFlattener)\n\t\t{\n\t\t\tbool newIsVisible = parentIsVisible && !isHidden;\n\t\t\tif (isVisible != newIsVisible)\n\t\t\t{\n\t\t\t\tisVisible = newIsVisible;\n\n\t\t\t\t// invalidate the augmented data\n\t\t\t\tSharpTreeNode node = this;\n\t\t\t\twhile (node != null && node.totalListLength >= 0)\n\t\t\t\t{\n\t\t\t\t\tnode.totalListLength = -1;\n\t\t\t\t\tnode = node.listParent;\n\t\t\t\t}\n\t\t\t\t// Remember the removed nodes:\n\t\t\t\tList<SharpTreeNode>? removedNodes = null;\n\t\t\t\tif (updateFlattener && !newIsVisible)\n\t\t\t\t{\n\t\t\t\t\tremovedNodes = VisibleDescendantsAndSelf().ToList();\n\t\t\t\t}\n\t\t\t\t// also update the model children:\n\t\t\t\tUpdateChildIsVisible(false);\n\n\t\t\t\t// Validate our invariants:\n\t\t\t\tif (updateFlattener)\n\t\t\t\t\tCheckRootInvariants();\n\n\t\t\t\t// Tell the flattener about the removed nodes:\n\t\t\t\tif (removedNodes != null)\n\t\t\t\t{\n\t\t\t\t\tvar flattener = GetListRoot().treeFlattener;\n\t\t\t\t\tif (flattener != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tflattener.NodesRemoved(GetVisibleIndexForNode(this), removedNodes);\n\t\t\t\t\t\tforeach (var n in removedNodes)\n\t\t\t\t\t\t\tn.OnIsVisibleChanged();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Tell the flattener about the new nodes:\n\t\t\t\tif (updateFlattener && newIsVisible)\n\t\t\t\t{\n\t\t\t\t\tvar flattener = GetListRoot().treeFlattener;\n\t\t\t\t\tif (flattener != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tflattener.NodesInserted(GetVisibleIndexForNode(this), VisibleDescendantsAndSelf());\n\t\t\t\t\t\tforeach (var n in VisibleDescendantsAndSelf())\n\t\t\t\t\t\t\tn.OnIsVisibleChanged();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual void OnIsVisibleChanged() { }\n\n\t\tvoid UpdateChildIsVisible(bool updateFlattener)\n\t\t{\n\t\t\tif (modelChildren != null && modelChildren.Count > 0)\n\t\t\t{\n\t\t\t\tbool showChildren = isVisible && isExpanded;\n\t\t\t\tforeach (SharpTreeNode child in modelChildren)\n\t\t\t\t{\n\t\t\t\t\tchild.UpdateIsVisible(showChildren, updateFlattener);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t#region Main\n\n\t\tpublic SharpTreeNode()\n\t\t{\n\t\t}\n\n\t\tpublic SharpTreeNodeCollection Children {\n\t\t\tget {\n\t\t\t\tif (modelChildren == null)\n\t\t\t\t\tmodelChildren = new SharpTreeNodeCollection(this);\n\t\t\t\treturn modelChildren;\n\t\t\t}\n\t\t}\n\n\t\tpublic SharpTreeNode? Parent {\n\t\t\tget { return modelParent; }\n\t\t}\n\n\t\tpublic virtual object? Text {\n\t\t\tget { return null; }\n\t\t}\n\n\t\tpublic virtual object? NavigationText {\n\t\t\tget { return Text; }\n\t\t}\n\n\t\tpublic virtual object? Icon {\n\t\t\tget { return null; }\n\t\t}\n\n\t\tpublic virtual object? ToolTip {\n\t\t\tget { return null; }\n\t\t}\n\n\t\tpublic virtual object? Background {\n\t\t\tget { return null; }\n\t\t}\n\n\t\tpublic virtual object? Foreground {\n\t\t\tget { return null; }\n\t\t}\n\n\t\tpublic int Level {\n\t\t\tget { return Parent != null ? Parent.Level + 1 : 0; }\n\t\t}\n\n\t\tpublic bool IsRoot {\n\t\t\tget { return Parent == null; }\n\t\t}\n\n\t\tbool isHidden;\n\n\t\tpublic bool IsHidden {\n\t\t\tget { return isHidden; }\n\t\t\tset {\n\t\t\t\tif (isHidden != value)\n\t\t\t\t{\n\t\t\t\t\tisHidden = value;\n\t\t\t\t\tif (modelParent != null)\n\t\t\t\t\t\tUpdateIsVisible(modelParent.isVisible && modelParent.isExpanded, true);\n\t\t\t\t\tRaisePropertyChanged(nameof(IsHidden));\n\t\t\t\t\tif (Parent != null)\n\t\t\t\t\t\tParent.RaisePropertyChanged(nameof(ShowExpander));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Return true when this node is not hidden and when all parent nodes are expanded and not hidden.\n\t\t/// </summary>\n\t\tpublic bool IsVisible {\n\t\t\tget { return isVisible; }\n\t\t}\n\n\t\tbool isSelected;\n\n\t\tpublic bool IsSelected {\n\t\t\tget { return isSelected; }\n\t\t\tset {\n\t\t\t\tif (isSelected != value)\n\t\t\t\t{\n\t\t\t\t\tisSelected = value;\n\t\t\t\t\tRaisePropertyChanged(nameof(IsSelected));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t#endregion\n\n\t\t#region OnParentChanged / OnChildrenChanged\n\t\tpublic virtual void OnParentChanged()\n\t\t{ }\n\n\t\tpublic virtual void OnChildrenChanged(NotifyCollectionChangedEventArgs e)\n\t\t{\n\t\t\tif (e.OldItems != null)\n\t\t\t{\n\t\t\t\tforeach (SharpTreeNode node in e.OldItems)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(node.modelParent == this);\n\t\t\t\t\tnode.modelParent = null;\n\t\t\t\t\tnode.OnParentChanged();\n\t\t\t\t\tDebug.WriteLine(\"Removing {0} from {1}\", node, this);\n\t\t\t\t\tSharpTreeNode removeEnd = node;\n\t\t\t\t\twhile (removeEnd.modelChildren != null && removeEnd.modelChildren.Count > 0)\n\t\t\t\t\t\tremoveEnd = removeEnd.modelChildren.Last();\n\n\t\t\t\t\tList<SharpTreeNode>? removedNodes = null;\n\t\t\t\t\tint visibleIndexOfRemoval = 0;\n\t\t\t\t\tif (node.isVisible)\n\t\t\t\t\t{\n\t\t\t\t\t\tvisibleIndexOfRemoval = GetVisibleIndexForNode(node);\n\t\t\t\t\t\tremovedNodes = node.VisibleDescendantsAndSelf().ToList();\n\t\t\t\t\t}\n\n\t\t\t\t\tRemoveNodes(node, removeEnd);\n\n\t\t\t\t\tif (removedNodes != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar flattener = GetListRoot().treeFlattener;\n\t\t\t\t\t\tif (flattener != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tflattener.NodesRemoved(visibleIndexOfRemoval, removedNodes);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (e.NewItems != null)\n\t\t\t{\n\t\t\t\tSharpTreeNode? insertionPos;\n\t\t\t\tif (e.NewStartingIndex == 0)\n\t\t\t\t\tinsertionPos = null;\n\t\t\t\telse\n\t\t\t\t\tinsertionPos = modelChildren?[e.NewStartingIndex - 1];\n\n\t\t\t\tforeach (SharpTreeNode node in e.NewItems)\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(node.modelParent == null);\n\t\t\t\t\tnode.modelParent = this;\n\t\t\t\t\tnode.OnParentChanged();\n\t\t\t\t\tnode.UpdateIsVisible(isVisible && isExpanded, false);\n\t\t\t\t\t//Debug.WriteLine(\"Inserting {0} after {1}\", node, insertionPos);\n\n\t\t\t\t\twhile (insertionPos != null && insertionPos.modelChildren != null && insertionPos.modelChildren.Count > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tinsertionPos = insertionPos.modelChildren.Last();\n\t\t\t\t\t}\n\t\t\t\t\tInsertNodeAfter(insertionPos ?? this, node);\n\n\t\t\t\t\tinsertionPos = node;\n\t\t\t\t\tif (node.isVisible)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar flattener = GetListRoot().treeFlattener;\n\t\t\t\t\t\tif (flattener != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tflattener.NodesInserted(GetVisibleIndexForNode(node), node.VisibleDescendantsAndSelf());\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tRaisePropertyChanged(nameof(ShowExpander));\n\t\t\tRaiseIsLastChangedIfNeeded(e);\n\t\t}\n\t\t#endregion\n\n\t\t#region Expanding / LazyLoading\n\n\t\tpublic virtual object? ExpandedIcon {\n\t\t\tget { return Icon; }\n\t\t}\n\n\t\tpublic virtual bool ShowExpander {\n\t\t\tget { return LazyLoading || Children.Any(c => !c.isHidden); }\n\t\t}\n\n\t\tbool isExpanded;\n\n\t\tpublic bool IsExpanded {\n\t\t\tget { return isExpanded; }\n\t\t\tset {\n\t\t\t\tif (isExpanded != value)\n\t\t\t\t{\n\t\t\t\t\tisExpanded = value;\n\t\t\t\t\tif (isExpanded)\n\t\t\t\t\t{\n\t\t\t\t\t\tEnsureLazyChildren();\n\t\t\t\t\t\tOnExpanding();\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tOnCollapsing();\n\t\t\t\t\t}\n\t\t\t\t\tUpdateChildIsVisible(true);\n\t\t\t\t\tRaisePropertyChanged(nameof(IsExpanded));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual void OnExpanding() { }\n\t\tprotected virtual void OnCollapsing() { }\n\n\t\tbool lazyLoading;\n\n\t\tpublic bool LazyLoading {\n\t\t\tget { return lazyLoading; }\n\t\t\tset {\n\t\t\t\tlazyLoading = value;\n\t\t\t\tif (lazyLoading)\n\t\t\t\t{\n\t\t\t\t\tIsExpanded = false;\n\t\t\t\t\tif (canExpandRecursively)\n\t\t\t\t\t{\n\t\t\t\t\t\tcanExpandRecursively = false;\n\t\t\t\t\t\tRaisePropertyChanged(nameof(CanExpandRecursively));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tRaisePropertyChanged(nameof(LazyLoading));\n\t\t\t\tRaisePropertyChanged(nameof(ShowExpander));\n\t\t\t}\n\t\t}\n\n\t\tbool canExpandRecursively = true;\n\n\t\t/// <summary>\n\t\t/// Gets whether this node can be expanded recursively.\n\t\t/// If not overridden, this property returns false if the node is using lazy-loading, and true otherwise.\n\t\t/// </summary>\n\t\tpublic virtual bool CanExpandRecursively {\n\t\t\tget { return canExpandRecursively; }\n\t\t}\n\n\t\tpublic virtual bool ShowIcon {\n\t\t\tget { return Icon != null; }\n\t\t}\n\n\t\tprotected virtual void LoadChildren()\n\t\t{\n\t\t\tthrow new NotSupportedException(GetType().Name + \" does not support lazy loading\");\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Ensures the children were initialized (loads children if lazy loading is enabled)\n\t\t/// </summary>\n\t\tpublic void EnsureLazyChildren()\n\t\t{\n\t\t\tif (LazyLoading)\n\t\t\t{\n\t\t\t\tLazyLoading = false;\n\t\t\t\tLoadChildren();\n\t\t\t}\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Ancestors / Descendants\n\n\t\tpublic IEnumerable<SharpTreeNode> Descendants()\n\t\t{\n\t\t\treturn TreeTraversal.PreOrder(this.Children, n => n.Children);\n\t\t}\n\n\t\tpublic IEnumerable<SharpTreeNode> DescendantsAndSelf()\n\t\t{\n\t\t\treturn TreeTraversal.PreOrder(this, n => n.Children);\n\t\t}\n\n\t\tinternal IEnumerable<SharpTreeNode> VisibleDescendants()\n\t\t{\n\t\t\treturn TreeTraversal.PreOrder(this.Children.Where(c => c.isVisible), n => n.Children.Where(c => c.isVisible));\n\t\t}\n\n\t\tpublic IEnumerable<SharpTreeNode> VisibleDescendantsAndSelf()\n\t\t{\n\t\t\treturn TreeTraversal.PreOrder(this, n => n.Children.Where(c => c.isVisible));\n\t\t}\n\n\t\tpublic IEnumerable<SharpTreeNode> Ancestors()\n\t\t{\n\t\t\tfor (SharpTreeNode? n = this.Parent; n != null; n = n.Parent)\n\t\t\t\tyield return n;\n\t\t}\n\n\t\tpublic IEnumerable<SharpTreeNode> AncestorsAndSelf()\n\t\t{\n\t\t\tfor (SharpTreeNode? n = this; n != null; n = n.Parent)\n\t\t\t\tyield return n;\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Editing\n\n\t\tpublic virtual bool IsEditable {\n\t\t\tget { return false; }\n\t\t}\n\n\t\tbool isEditing;\n\n\t\tpublic bool IsEditing {\n\t\t\tget { return isEditing; }\n\t\t\tset {\n\t\t\t\tif (isEditing != value)\n\t\t\t\t{\n\t\t\t\t\tisEditing = value;\n\t\t\t\t\tRaisePropertyChanged(nameof(IsEditing));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic virtual string? LoadEditText()\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic virtual bool SaveEditText(string value)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Checkboxes\n\n\t\tpublic virtual bool IsCheckable {\n\t\t\tget { return false; }\n\t\t}\n\n\t\tbool? isChecked;\n\n\t\tpublic bool? IsChecked {\n\t\t\tget { return isChecked; }\n\t\t\tset {\n\t\t\t\tSetIsChecked(value, true);\n\t\t\t}\n\t\t}\n\n\t\tvoid SetIsChecked(bool? value, bool update)\n\t\t{\n\t\t\tif (isChecked != value)\n\t\t\t{\n\t\t\t\tisChecked = value;\n\n\t\t\t\tif (update)\n\t\t\t\t{\n\t\t\t\t\tif (IsChecked != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var child in Descendants())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (child.IsCheckable)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tchild.SetIsChecked(IsChecked, false);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tforeach (var parent in Ancestors())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (parent.IsCheckable)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!parent.TryValueForIsChecked(true))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (!parent.TryValueForIsChecked(false))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tparent.SetIsChecked(null, false);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tRaisePropertyChanged(nameof(IsChecked));\n\t\t\t}\n\t\t}\n\n\t\tbool TryValueForIsChecked(bool? value)\n\t\t{\n\t\t\tif (Children.Where(n => n.IsCheckable).All(n => n.IsChecked == value))\n\t\t\t{\n\t\t\t\tSetIsChecked(value, false);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Cut / Copy / Paste / Delete\n\n\t\tpublic bool IsCut { get { return false; } }\n\t\t/*\n\t\t\tstatic List<SharpTreeNode> cuttedNodes = new List<SharpTreeNode>();\n\t\t\tstatic IDataObject cuttedData;\n\t\t\tstatic EventHandler requerySuggestedHandler; // for weak event\n\t\n\t\t\tstatic void StartCuttedDataWatcher()\n\t\t\t{\n\t\t\t\trequerySuggestedHandler = new EventHandler(CommandManager_RequerySuggested);\n\t\t\t\tCommandManager.RequerySuggested += requerySuggestedHandler;\n\t\t\t}\n\t\n\t\t\tstatic void CommandManager_RequerySuggested(object sender, EventArgs e)\n\t\t\t{\n\t\t\t\tif (cuttedData != null && !Clipboard.IsCurrent(cuttedData)) {\n\t\t\t\t\tClearCuttedData();\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tstatic void ClearCuttedData()\n\t\t\t{\n\t\t\t\tforeach (var node in cuttedNodes) {\n\t\t\t\t\tnode.IsCut = false;\n\t\t\t\t}\n\t\t\t\tcuttedNodes.Clear();\n\t\t\t\tcuttedData = null;\n\t\t\t}\n\t\n\t\t\t//static public IEnumerable<SharpTreeNode> PurifyNodes(IEnumerable<SharpTreeNode> nodes)\n\t\t\t//{\n\t\t\t//    var list = nodes.ToList();\n\t\t\t//    var array = list.ToArray();\n\t\t\t//    foreach (var node1 in array) {\n\t\t\t//        foreach (var node2 in array) {\n\t\t\t//            if (node1.Descendants().Contains(node2)) {\n\t\t\t//                list.Remove(node2);\n\t\t\t//            }\n\t\t\t//        }\n\t\t\t//    }\n\t\t\t//    return list;\n\t\t\t//}\n\t\n\t\t\tbool isCut;\n\t\n\t\t\tpublic bool IsCut\n\t\t\t{\n\t\t\t\tget { return isCut; }\n\t\t\t\tprivate set\n\t\t\t\t{\n\t\t\t\t\tisCut = value;\n\t\t\t\t\tRaisePropertyChanged(\"IsCut\");\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tinternal bool InternalCanCut()\n\t\t\t{\n\t\t\t\treturn InternalCanCopy() && InternalCanDelete();\n\t\t\t}\n\t\n\t\t\tinternal void InternalCut()\n\t\t\t{\n\t\t\t\tClearCuttedData();\n\t\t\t\tcuttedData = Copy(ActiveNodesArray);\n\t\t\t\tClipboard.SetDataObject(cuttedData);\n\t\n\t\t\t\tforeach (var node in ActiveNodes) {\n\t\t\t\t\tnode.IsCut = true;\n\t\t\t\t\tcuttedNodes.Add(node);\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tinternal bool InternalCanCopy()\n\t\t\t{\n\t\t\t\treturn CanCopy(ActiveNodesArray);\n\t\t\t}\n\t\n\t\t\tinternal void InternalCopy()\n\t\t\t{\n\t\t\t\tClipboard.SetDataObject(Copy(ActiveNodesArray));\n\t\t\t}\n\t\n\t\t\tinternal bool InternalCanPaste()\n\t\t\t{\n\t\t\t\treturn CanPaste(Clipboard.GetDataObject());\n\t\t\t}\n\t\n\t\t\tinternal void InternalPaste()\n\t\t\t{\n\t\t\t\tPaste(Clipboard.GetDataObject());\n\t\n\t\t\t\tif (cuttedData != null) {\n\t\t\t\t\tDeleteCore(cuttedNodes.ToArray());\n\t\t\t\t\tClearCuttedData();\n\t\t\t\t}\n\t\t\t}\n\t\t */\n\n\t\tpublic virtual bool CanDelete()\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic virtual void Delete()\n\t\t{\n\t\t\tthrow new NotSupportedException(GetType().Name + \" does not support deletion\");\n\t\t}\n\n\t\tpublic virtual void DeleteCore()\n\t\t{\n\t\t\tthrow new NotSupportedException(GetType().Name + \" does not support deletion\");\n\t\t}\n\n\t\tpublic virtual IPlatformDataObject Copy(SharpTreeNode[] nodes)\n\t\t{\n\t\t\tthrow new NotSupportedException(GetType().Name + \" does not support copy/paste or drag'n'drop\");\n\t\t}\n\n\t\t/*\n\t\t\tpublic virtual bool CanCopy(SharpTreeNode[] nodes)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\n\t\t\tpublic virtual bool CanPaste(IDataObject data)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\n\t\t\tpublic virtual void Paste(IDataObject data)\n\t\t\t{\n\t\t\t\tEnsureLazyChildren();\n\t\t\t\tDrop(data, Children.Count, DropEffect.Copy);\n\t\t\t}\n\t\t */\n\t\t#endregion\n\n\t\t#region Drag and Drop\n\t\tpublic virtual bool CanDrag(SharpTreeNode[] nodes)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic virtual void StartDrag(object dragSource, SharpTreeNode[] nodes, IPlatformDragDrop dragdropManager)\n\t\t{\n\t\t\tXPlatDragDropEffects effects = XPlatDragDropEffects.All;\n\t\t\tif (!nodes.All(n => n.CanDelete()))\n\t\t\t\teffects &= ~XPlatDragDropEffects.Move;\n\n\t\t\tXPlatDragDropEffects result = dragdropManager.DoDragDrop(dragSource, Copy(nodes), effects);\n\t\t\tif (result == XPlatDragDropEffects.Move)\n\t\t\t{\n\t\t\t\tforeach (SharpTreeNode node in nodes)\n\t\t\t\t\tnode.DeleteCore();\n\t\t\t}\n\t\t}\n\n\t\tpublic virtual bool CanDrop(IPlatformDragEventArgs e, int index)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic void InternalDrop(IPlatformDragEventArgs e, int index)\n\t\t{\n\t\t\tif (LazyLoading)\n\t\t\t{\n\t\t\t\tEnsureLazyChildren();\n\t\t\t\tindex = Children.Count;\n\t\t\t}\n\n\t\t\tDrop(e, index);\n\t\t}\n\n\t\tpublic virtual void Drop(IPlatformDragEventArgs e, int index)\n\t\t{\n\t\t\tthrow new NotSupportedException(GetType().Name + \" does not support Drop()\");\n\t\t}\n\t\t#endregion\n\n\t\t#region IsLast (for TreeView lines)\n\n\t\tpublic bool IsLast {\n\t\t\tget {\n\t\t\t\treturn Parent == null\n\t\t\t\t\t|| Parent.Children.Count == 0\n\t\t\t\t\t|| Parent.Children[^1] == this;\n\t\t\t}\n\t\t}\n\n\t\tvoid RaiseIsLastChangedIfNeeded(NotifyCollectionChangedEventArgs e)\n\t\t{\n\t\t\tswitch (e.Action)\n\t\t\t{\n\t\t\t\tcase NotifyCollectionChangedAction.Add:\n\t\t\t\t\tif (e.NewStartingIndex == Children.Count - 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (Children.Count > 1)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tChildren[Children.Count - 2].RaisePropertyChanged(nameof(IsLast));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tChildren[Children.Count - 1].RaisePropertyChanged(nameof(IsLast));\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase NotifyCollectionChangedAction.Remove:\n\t\t\t\t\tif (e.OldStartingIndex == Children.Count)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (Children.Count > 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tChildren[Children.Count - 1].RaisePropertyChanged(nameof(IsLast));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t#endregion\n\n\t\t#region INotifyPropertyChanged Members\n\n\t\tpublic event PropertyChangedEventHandler? PropertyChanged;\n\n\t\tpublic void RaisePropertyChanged(string name)\n\t\t{\n\t\t\tif (PropertyChanged != null)\n\t\t\t{\n\t\t\t\tPropertyChanged(this, new PropertyChangedEventArgs(name));\n\t\t\t}\n\t\t}\n\n\t\t#endregion\n\n\t\t/// <summary>\n\t\t/// Gets called when the item is double-clicked.\n\t\t/// </summary>\n\t\tpublic virtual void ActivateItem(IPlatformRoutedEventArgs e)\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets called when the item is clicked with the middle mouse button.\n\t\t/// </summary>\n\t\tpublic virtual void ActivateItemSecondary(IPlatformRoutedEventArgs e)\n\t\t{\n\t\t}\n\n\t\tpublic override string? ToString()\n\t\t{\n\t\t\t// used for keyboard navigation\n\t\t\tobject? text = this.Text;\n\t\t\treturn text != null ? text.ToString() : string.Empty;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/TreeView/SharpTreeNodeCollection.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.Diagnostics;\nusing System.Linq;\n\n#nullable disable\n\nnamespace ICSharpCode.ILSpyX.TreeView\n{\n\t/// <summary>\n\t/// Collection that validates that inserted nodes do not have another parent.\n\t/// </summary>\n\tpublic sealed class SharpTreeNodeCollection : IList<SharpTreeNode>, INotifyCollectionChanged\n\t{\n\t\treadonly SharpTreeNode parent;\n\t\tList<SharpTreeNode> list = new List<SharpTreeNode>();\n\t\tbool isRaisingEvent;\n\n\t\tpublic SharpTreeNodeCollection(SharpTreeNode parent)\n\t\t{\n\t\t\tthis.parent = parent;\n\t\t}\n\n\t\tpublic event NotifyCollectionChangedEventHandler CollectionChanged;\n\n\t\tvoid OnCollectionChanged(NotifyCollectionChangedEventArgs e)\n\t\t{\n\t\t\tDebug.Assert(!isRaisingEvent);\n\t\t\tisRaisingEvent = true;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tparent.OnChildrenChanged(e);\n\t\t\t\tCollectionChanged?.Invoke(this, e);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tisRaisingEvent = false;\n\t\t\t}\n\t\t}\n\n\t\tvoid ThrowOnReentrancy()\n\t\t{\n\t\t\tif (isRaisingEvent)\n\t\t\t\tthrow new InvalidOperationException();\n\t\t}\n\n\t\tvoid ThrowIfValueIsNullOrHasParent(SharpTreeNode node)\n\t\t{\n\t\t\tif (node == null)\n\t\t\t\tthrow new ArgumentNullException(\"node\");\n\t\t\tif (node.modelParent != null)\n\t\t\t\tthrow new ArgumentException(\"The node already has a parent\", \"node\");\n\t\t}\n\n\t\tpublic SharpTreeNode this[int index] {\n\t\t\tget {\n\t\t\t\treturn list[index];\n\t\t\t}\n\t\t\tset {\n\t\t\t\tThrowOnReentrancy();\n\t\t\t\tvar oldItem = list[index];\n\t\t\t\tif (oldItem == value)\n\t\t\t\t\treturn;\n\t\t\t\tThrowIfValueIsNullOrHasParent(value);\n\t\t\t\tlist[index] = value;\n\t\t\t\tOnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, value, oldItem, index));\n\t\t\t}\n\t\t}\n\n\t\tpublic int Count {\n\t\t\tget { return list.Count; }\n\t\t}\n\n\t\tbool ICollection<SharpTreeNode>.IsReadOnly {\n\t\t\tget { return false; }\n\t\t}\n\n\t\tpublic int IndexOf(SharpTreeNode node)\n\t\t{\n\t\t\tif (node == null || node.modelParent != parent)\n\t\t\t\treturn -1;\n\t\t\telse\n\t\t\t\treturn list.IndexOf(node);\n\t\t}\n\n\t\tpublic void Insert(int index, SharpTreeNode node)\n\t\t{\n\t\t\tThrowOnReentrancy();\n\t\t\tThrowIfValueIsNullOrHasParent(node);\n\t\t\tlist.Insert(index, node);\n\t\t\tOnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, node, index));\n\t\t}\n\n\t\tpublic void InsertRange(int index, IEnumerable<SharpTreeNode> nodes)\n\t\t{\n\t\t\tif (nodes == null)\n\t\t\t\tthrow new ArgumentNullException(\"nodes\");\n\t\t\tThrowOnReentrancy();\n\t\t\tList<SharpTreeNode> newNodes = nodes.ToList();\n\t\t\tif (newNodes.Count == 0)\n\t\t\t\treturn;\n\t\t\tforeach (SharpTreeNode node in newNodes)\n\t\t\t{\n\t\t\t\tThrowIfValueIsNullOrHasParent(node);\n\t\t\t}\n\t\t\tlist.InsertRange(index, newNodes);\n\t\t\tOnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, newNodes, index));\n\t\t}\n\n\t\tpublic void RemoveAt(int index)\n\t\t{\n\t\t\tThrowOnReentrancy();\n\t\t\tvar oldItem = list[index];\n\t\t\tlist.RemoveAt(index);\n\t\t\tOnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, oldItem, index));\n\t\t}\n\n\t\tpublic void RemoveRange(int index, int count)\n\t\t{\n\t\t\tThrowOnReentrancy();\n\t\t\tif (count == 0)\n\t\t\t\treturn;\n\t\t\tvar oldItems = list.GetRange(index, count);\n\t\t\tlist.RemoveRange(index, count);\n\t\t\tOnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, oldItems, index));\n\t\t}\n\n\t\tpublic void Add(SharpTreeNode node)\n\t\t{\n\t\t\tThrowOnReentrancy();\n\t\t\tThrowIfValueIsNullOrHasParent(node);\n\t\t\tlist.Add(node);\n\t\t\tOnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, node, list.Count - 1));\n\t\t}\n\n\t\tpublic void AddRange(IEnumerable<SharpTreeNode> nodes)\n\t\t{\n\t\t\tInsertRange(this.Count, nodes);\n\t\t}\n\n\t\tpublic void Clear()\n\t\t{\n\t\t\tThrowOnReentrancy();\n\t\t\tvar oldList = list;\n\t\t\tlist = new List<SharpTreeNode>();\n\t\t\tOnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, oldList, 0));\n\t\t}\n\n\t\tpublic bool Contains(SharpTreeNode node)\n\t\t{\n\t\t\treturn IndexOf(node) >= 0;\n\t\t}\n\n\t\tpublic void CopyTo(SharpTreeNode[] array, int arrayIndex)\n\t\t{\n\t\t\tlist.CopyTo(array, arrayIndex);\n\t\t}\n\n\t\tpublic bool Remove(SharpTreeNode item)\n\t\t{\n\t\t\tint pos = IndexOf(item);\n\t\t\tif (pos >= 0)\n\t\t\t{\n\t\t\t\tRemoveAt(pos);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerator<SharpTreeNode> GetEnumerator()\n\t\t{\n\t\t\treturn list.GetEnumerator();\n\t\t}\n\n\t\tSystem.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\n\t\t{\n\t\t\treturn list.GetEnumerator();\n\t\t}\n\n\t\tpublic void RemoveAll(Predicate<SharpTreeNode> match)\n\t\t{\n\t\t\tif (match == null)\n\t\t\t\tthrow new ArgumentNullException(\"match\");\n\t\t\tThrowOnReentrancy();\n\t\t\tint firstToRemove = 0;\n\t\t\tfor (int i = 0; i < list.Count; i++)\n\t\t\t{\n\t\t\t\tbool removeNode;\n\t\t\t\tisRaisingEvent = true;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tremoveNode = match(list[i]);\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tisRaisingEvent = false;\n\t\t\t\t}\n\t\t\t\tif (!removeNode)\n\t\t\t\t{\n\t\t\t\t\tif (firstToRemove < i)\n\t\t\t\t\t{\n\t\t\t\t\t\tRemoveRange(firstToRemove, i - firstToRemove);\n\t\t\t\t\t\ti = firstToRemove - 1;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tfirstToRemove = i + 1;\n\t\t\t\t\t}\n\t\t\t\t\tDebug.Assert(firstToRemove == i + 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (firstToRemove < list.Count)\n\t\t\t{\n\t\t\t\tRemoveRange(firstToRemove, list.Count - firstToRemove);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/TreeView/TreeFlattener.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.Diagnostics;\n\n#nullable disable\n\nnamespace ICSharpCode.ILSpyX.TreeView\n{\n\tpublic sealed class TreeFlattener : IList, INotifyCollectionChanged\n\t{\n\t\t/// <summary>\n\t\t/// The root node of the flat list tree.\n\t\t/// Tjis is not necessarily the root of the model!\n\t\t/// </summary>\n\t\tinternal SharpTreeNode root;\n\t\treadonly bool includeRoot;\n\t\treadonly object syncRoot = new object();\n\n\t\tpublic TreeFlattener(SharpTreeNode modelRoot, bool includeRoot)\n\t\t{\n\t\t\tthis.root = modelRoot;\n\t\t\twhile (root.listParent != null)\n\t\t\t\troot = root.listParent;\n\t\t\troot.treeFlattener = this;\n\t\t\tthis.includeRoot = includeRoot;\n\t\t}\n\n\t\tpublic event NotifyCollectionChangedEventHandler CollectionChanged;\n\n\t\tpublic void RaiseCollectionChanged(NotifyCollectionChangedEventArgs e)\n\t\t{\n\t\t\tCollectionChanged?.Invoke(this, e);\n\t\t}\n\n\t\tpublic void NodesInserted(int index, IEnumerable<SharpTreeNode> nodes)\n\t\t{\n\t\t\tif (!includeRoot)\n\t\t\t\tindex--;\n\t\t\tforeach (SharpTreeNode node in nodes)\n\t\t\t{\n\t\t\t\tRaiseCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, node, index++));\n\t\t\t}\n\t\t}\n\n\t\tpublic void NodesRemoved(int index, IEnumerable<SharpTreeNode> nodes)\n\t\t{\n\t\t\tif (!includeRoot)\n\t\t\t\tindex--;\n\t\t\tforeach (SharpTreeNode node in nodes)\n\t\t\t{\n\t\t\t\tRaiseCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, node, index));\n\t\t\t}\n\t\t}\n\n\t\tpublic void Stop()\n\t\t{\n\t\t\tDebug.Assert(root.treeFlattener == this);\n\t\t\troot.treeFlattener = null;\n\t\t}\n\n\t\tpublic object this[int index] {\n\t\t\tget {\n\t\t\t\tif (index < 0 || index >= this.Count)\n\t\t\t\t\tthrow new ArgumentOutOfRangeException();\n\t\t\t\treturn SharpTreeNode.GetNodeByVisibleIndex(root, includeRoot ? index : index + 1);\n\t\t\t}\n\t\t\tset {\n\t\t\t\tthrow new NotSupportedException();\n\t\t\t}\n\t\t}\n\n\t\tpublic int Count {\n\t\t\tget {\n\t\t\t\treturn includeRoot ? root.GetTotalListLength() : root.GetTotalListLength() - 1;\n\t\t\t}\n\t\t}\n\n\t\tpublic int IndexOf(object item)\n\t\t{\n\t\t\tSharpTreeNode node = item as SharpTreeNode;\n\t\t\tif (node != null && node.IsVisible && node.GetListRoot() == root)\n\t\t\t{\n\t\t\t\tif (includeRoot)\n\t\t\t\t\treturn SharpTreeNode.GetVisibleIndexForNode(node);\n\t\t\t\telse\n\t\t\t\t\treturn SharpTreeNode.GetVisibleIndexForNode(node) - 1;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\n\t\tbool IList.IsReadOnly {\n\t\t\tget { return true; }\n\t\t}\n\n\t\tbool IList.IsFixedSize {\n\t\t\tget { return false; }\n\t\t}\n\n\t\tbool ICollection.IsSynchronized {\n\t\t\tget { return false; }\n\t\t}\n\n\t\tobject ICollection.SyncRoot {\n\t\t\tget {\n\t\t\t\treturn syncRoot;\n\t\t\t}\n\t\t}\n\n\t\tvoid IList.Insert(int index, object item)\n\t\t{\n\t\t\tthrow new NotSupportedException();\n\t\t}\n\n\t\tvoid IList.RemoveAt(int index)\n\t\t{\n\t\t\tthrow new NotSupportedException();\n\t\t}\n\n\t\tint IList.Add(object item)\n\t\t{\n\t\t\tthrow new NotSupportedException();\n\t\t}\n\n\t\tvoid IList.Clear()\n\t\t{\n\t\t\tthrow new NotSupportedException();\n\t\t}\n\n\t\tpublic bool Contains(object item)\n\t\t{\n\t\t\treturn IndexOf(item) >= 0;\n\t\t}\n\n\t\tpublic void CopyTo(Array array, int arrayIndex)\n\t\t{\n\t\t\tforeach (object item in this)\n\t\t\t\tarray.SetValue(item, arrayIndex++);\n\t\t}\n\n\t\tvoid IList.Remove(object item)\n\t\t{\n\t\t\tthrow new NotSupportedException();\n\t\t}\n\n\t\tpublic IEnumerator GetEnumerator()\n\t\t{\n\t\t\tfor (int i = 0; i < this.Count; i++)\n\t\t\t{\n\t\t\t\tyield return this[i];\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/TreeView/TreeTraversal.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.ILSpyX.TreeView\n{\n\t/// <summary>\n\t/// Static helper methods for traversing trees.\n\t/// </summary>\n\tstatic class TreeTraversal\n\t{\n\t\t/// <summary>\n\t\t/// Converts a tree data structure into a flat list by traversing it in pre-order.\n\t\t/// </summary>\n\t\t/// <param name=\"root\">The root element of the tree.</param>\n\t\t/// <param name=\"recursion\">The function that gets the children of an element.</param>\n\t\t/// <returns>Iterator that enumerates the tree structure in pre-order.</returns>\n\t\tpublic static IEnumerable<T> PreOrder<T>(T root, Func<T, IEnumerable<T>> recursion)\n\t\t{\n\t\t\treturn PreOrder(new T[] { root }, recursion);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts a tree data structure into a flat list by traversing it in pre-order.\n\t\t/// </summary>\n\t\t/// <param name=\"input\">The root elements of the forest.</param>\n\t\t/// <param name=\"recursion\">The function that gets the children of an element.</param>\n\t\t/// <returns>Iterator that enumerates the tree structure in pre-order.</returns>\n\t\tpublic static IEnumerable<T> PreOrder<T>(IEnumerable<T> input, Func<T, IEnumerable<T>> recursion)\n\t\t{\n\t\t\tStack<IEnumerator<T>> stack = new Stack<IEnumerator<T>>();\n\t\t\ttry\n\t\t\t{\n\t\t\t\tstack.Push(input.GetEnumerator());\n\t\t\t\twhile (stack.Count > 0)\n\t\t\t\t{\n\t\t\t\t\twhile (stack.Peek().MoveNext())\n\t\t\t\t\t{\n\t\t\t\t\t\tT element = stack.Peek().Current;\n\t\t\t\t\t\tyield return element;\n\t\t\t\t\t\tIEnumerable<T> children = recursion(element);\n\t\t\t\t\t\tif (children != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstack.Push(children.GetEnumerator());\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tstack.Pop().Dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\twhile (stack.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tstack.Pop().Dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ICSharpCode.ILSpyX/packages.lock.json",
    "content": "{\n  \"version\": 2,\n  \"dependencies\": {\n    \"net10.0\": {\n      \"K4os.Compression.LZ4\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[1.3.8, )\",\n        \"resolved\": \"1.3.8\",\n        \"contentHash\": \"LhwlPa7c1zs1OV2XadMtAWdImjLIsqFJPoRcIWAadSRn0Ri1DepK65UbWLPmt4riLqx2d40xjXRk0ogpqNtK7g==\"\n      },\n      \"Microsoft.Sbom.Targets\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[4.1.5, )\",\n        \"resolved\": \"4.1.5\",\n        \"contentHash\": \"i5z+cNu/cOcdO0AgFB8aXk8w6In2H+haaDfSgd9ImvQIK+rSHavHZIogVoAZLL8jLwYx4bAcs5b7EyuMMG4mQQ==\"\n      },\n      \"Microsoft.SourceLink.GitHub\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[10.0.201, )\",\n        \"resolved\": \"10.0.201\",\n        \"contentHash\": \"qxYAmO4ktzd9L+HMdnqWucxpu7bI9undPyACXOMqPyhaiMtbpbYL/n0ACyWIJlbyEJrXFwxiOaBOSasLtDvsCg==\",\n        \"dependencies\": {\n          \"Microsoft.Build.Tasks.Git\": \"10.0.201\",\n          \"Microsoft.SourceLink.Common\": \"10.0.201\",\n          \"System.IO.Hashing\": \"10.0.5\"\n        }\n      },\n      \"Mono.Cecil\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[0.11.6, )\",\n        \"resolved\": \"0.11.6\",\n        \"contentHash\": \"f33RkDtZO8VlGXCtmQIviOtxgnUdym9xx/b1p9h91CRGOsJFxCFOFK1FDbVt1OCf1aWwYejUFa2MOQyFWTFjbA==\"\n      },\n      \"System.Composition.AttributedModel\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[10.0.5, )\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"Vgb7wwB7ya+lbcwccXHZPSJxeKR7tCkWLgFXO9Wcgbu/NgO5DvNAIHtEkXaEESkcvXdD1iqp2JBcLWGT/xDxEw==\"\n      },\n      \"System.Reflection.Metadata\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[10.0.5, )\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"fEAXJCtauNLYr5ESg3t6HE2Av6urWdJdymxZbuSt/DDqhtNtLtUtXTEpKbp0vkTdyBJwmaha8d2454vSzS/lcQ==\"\n      },\n      \"System.Runtime.CompilerServices.Unsafe\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[6.1.2, )\",\n        \"resolved\": \"6.1.2\",\n        \"contentHash\": \"2hBr6zdbIBTDE3EhK7NSVNdX58uTK6iHW/P/Axmm9sl1xoGSLqDvMtpecn226TNwHByFokYwJmt/aQQNlO5CRw==\"\n      },\n      \"TomsToolbox.Composition.Analyzer\": {\n        \"type\": \"Direct\",\n        \"requested\": \"[2.22.2, )\",\n        \"resolved\": \"2.22.2\",\n        \"contentHash\": \"7gYo8ZR2eq3XkrilvUpLbTypeZy6IlD5FB8jah0YPhMOmDGhya4jJ3kfDMTTRt5m258Ou78P69mHMkG6DKZXsg==\"\n      },\n      \"Microsoft.Build.Tasks.Git\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.201\",\n        \"contentHash\": \"DMYBnrFZvLnBKn14VavEuuIr31CY6YY2i2L9P8DorS/Qp6ifRR8ZPLdJCFLFfjikNq8DykbYyLd/RP6lSqHcWw==\",\n        \"dependencies\": {\n          \"System.IO.Hashing\": \"10.0.5\"\n        }\n      },\n      \"Microsoft.SourceLink.Common\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.201\",\n        \"contentHash\": \"QbBYhkjgL6rCnBfDbzsAJLlsad13TlBHqYCFDIw56OO2g6ix+9RsmY8uxiQGdWwFKbZXaXyAA6jDCzFYVGCZDw==\"\n      },\n      \"System.IO.Hashing\": {\n        \"type\": \"Transitive\",\n        \"resolved\": \"10.0.5\",\n        \"contentHash\": \"8IBJWcCT9+e4Bmevm4T7+fQEiAh133KGiz4oiVTgJckd3Q76OFdR1falgn9lpz7+C4HJvogCDJeAa2QmvbeVtg==\"\n      },\n      \"icsharpcode.decompiler\": {\n        \"type\": \"Project\",\n        \"dependencies\": {\n          \"System.Collections.Immutable\": \"[9.0.0, )\",\n          \"System.Reflection.Metadata\": \"[9.0.0, )\"\n        }\n      },\n      \"System.Collections.Immutable\": {\n        \"type\": \"CentralTransitive\",\n        \"requested\": \"[10.0.5, )\",\n        \"resolved\": \"9.0.0\",\n        \"contentHash\": \"QhkXUl2gNrQtvPmtBTQHb0YsUrDiDQ2QS09YbtTTiSjGcf7NBqtYbrG/BE06zcBPCKEwQGzIv13IVdXNOSub2w==\"\n      }\n    }\n  }\n}"
  },
  {
    "path": "ILSpy/AboutPage.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.IO;\nusing System.Text.RegularExpressions;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Controls.Primitives;\nusing System.Windows.Data;\nusing System.Windows.Input;\nusing System.Windows.Navigation;\n\nusing ICSharpCode.AvalonEdit.Rendering;\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.Themes;\nusing ICSharpCode.ILSpy.Updates;\nusing ICSharpCode.ILSpy.ViewModels;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportMainMenuCommand(ParentMenuID = nameof(Resources._Help), Header = nameof(Resources._About), MenuOrder = 99999)]\n\t[Shared]\n\tpublic sealed class AboutPage : SimpleCommand\n\t{\n\t\treadonly SettingsService settingsService;\n\t\treadonly IEnumerable<IAboutPageAddition> aboutPageAdditions;\n\n\t\tpublic AboutPage(SettingsService settingsService, IEnumerable<IAboutPageAddition> aboutPageAdditions)\n\t\t{\n\t\t\tthis.settingsService = settingsService;\n\t\t\tthis.aboutPageAdditions = aboutPageAdditions;\n\t\t\tMessageBus<ShowAboutPageEventArgs>.Subscribers += (_, e) => ShowAboutPage(e.TabPage);\n\t\t}\n\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tMessageBus.Send(this, new NavigateToEventArgs(new RequestNavigateEventArgs(new Uri(\"resource://aboutpage\"), null), inNewTabPage: true));\n\t\t}\n\n\t\tprivate void ShowAboutPage(TabPageModel tabPage)\n\t\t{\n\t\t\ttabPage.ShowTextView(Display);\n\t\t}\n\n\t\tprivate void Display(DecompilerTextView textView)\n\t\t{\n\t\t\tAvalonEditTextOutput output = new AvalonEditTextOutput() {\n\t\t\t\tTitle = Resources.About,\n\t\t\t\tEnableHyperlinks = true\n\t\t\t};\n\t\t\toutput.WriteLine(Resources.ILSpyVersion + DecompilerVersionInfo.FullVersionWithCommitHash);\n\n\t\t\tstring prodVersion = GetDotnetProductVersion();\n\t\t\toutput.WriteLine(Resources.NETFrameworkVersion + prodVersion);\n\n\t\t\toutput.AddUIElement(\n\t\t\tdelegate {\n\t\t\t\tvar stackPanel = new StackPanel {\n\t\t\t\t\tHorizontalAlignment = HorizontalAlignment.Center,\n\t\t\t\t\tOrientation = Orientation.Horizontal\n\t\t\t\t};\n\t\t\t\tif (UpdateService.LatestAvailableVersion == null)\n\t\t\t\t{\n\t\t\t\t\tAddUpdateCheckButton(stackPanel, textView);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// we already retrieved the latest version sometime earlier\n\t\t\t\t\tShowAvailableVersion(UpdateService.LatestAvailableVersion, stackPanel);\n\t\t\t\t}\n\t\t\t\tvar checkBox = new CheckBox {\n\t\t\t\t\tMargin = new Thickness(4),\n\t\t\t\t\tContent = Resources.AutomaticallyCheckUpdatesEveryWeek\n\t\t\t\t};\n\n\t\t\t\tvar settings = settingsService.GetSettings<UpdateSettings>();\n\t\t\t\tcheckBox.SetBinding(ToggleButton.IsCheckedProperty, new Binding(\"AutomaticUpdateCheckEnabled\") { Source = settings });\n\t\t\t\treturn new StackPanel {\n\t\t\t\t\tMargin = new Thickness(0, 4, 0, 0),\n\t\t\t\t\tCursor = Cursors.Arrow,\n\t\t\t\t\tChildren = { stackPanel, checkBox }\n\t\t\t\t};\n\t\t\t});\n\t\t\toutput.WriteLine();\n\n\t\t\tforeach (var plugin in aboutPageAdditions)\n\t\t\t\tplugin.Write(output);\n\t\t\toutput.WriteLine();\n\t\t\toutput.Address = new Uri(\"resource://AboutPage\");\n\t\t\tusing (Stream s = typeof(AboutPage).Assembly.GetManifestResourceStream(typeof(AboutPage), Resources.ILSpyAboutPageTxt))\n\t\t\t{\n\t\t\t\tusing (StreamReader r = new StreamReader(s))\n\t\t\t\t{\n\t\t\t\t\twhile (r.ReadLine() is { } line)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.WriteLine(line);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\toutput.AddVisualLineElementGenerator(new MyLinkElementGenerator(\"MIT License\", \"resource:license.txt\"));\n\t\t\toutput.AddVisualLineElementGenerator(new MyLinkElementGenerator(\"third-party notices\", \"resource:third-party-notices.txt\"));\n\t\t\ttextView.ShowText(output);\n\t\t}\n\n\t\tprivate static string GetDotnetProductVersion()\n\t\t{\n\t\t\t// In case of AOT .Location is null, we need a fallback for that\n\t\t\tstring assemblyLocation = typeof(Uri).Assembly.Location;\n\n\t\t\tif (!String.IsNullOrWhiteSpace(assemblyLocation))\n\t\t\t{\n\t\t\t\treturn System.Diagnostics.FileVersionInfo.GetVersionInfo(assemblyLocation).ProductVersion;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar version = typeof(Object).Assembly.GetName().Version;\n\t\t\t\tif (version != null)\n\t\t\t\t{\n\t\t\t\t\treturn version.ToString();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn \"UNKNOWN\";\n\t\t}\n\n\t\tsealed class MyLinkElementGenerator : LinkElementGenerator\n\t\t{\n\t\t\treadonly Uri uri;\n\n\t\t\tpublic MyLinkElementGenerator(string matchText, string url) : base(new Regex(Regex.Escape(matchText)))\n\t\t\t{\n\t\t\t\tthis.uri = new Uri(url);\n\t\t\t\tthis.RequireControlModifierForClick = false;\n\t\t\t}\n\n\t\t\tprotected override Uri GetUriFromMatch(Match match)\n\t\t\t{\n\t\t\t\treturn uri;\n\t\t\t}\n\t\t}\n\n\t\tstatic void AddUpdateCheckButton(StackPanel stackPanel, DecompilerTextView textView)\n\t\t{\n\t\t\tButton button = ThemeManager.Current.CreateButton();\n\t\t\tbutton.Content = Resources.CheckUpdates;\n\t\t\tbutton.Cursor = Cursors.Arrow;\n\t\t\tstackPanel.Children.Add(button);\n\n\t\t\tbutton.Click += async delegate {\n\t\t\t\tbutton.Content = Resources.Checking;\n\t\t\t\tbutton.IsEnabled = false;\n\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tAvailableVersionInfo vInfo = await UpdateService.GetLatestVersionAsync();\n\t\t\t\t\tstackPanel.Children.Clear();\n\t\t\t\t\tShowAvailableVersion(vInfo, stackPanel);\n\t\t\t\t}\n\t\t\t\tcatch (Exception ex)\n\t\t\t\t{\n\t\t\t\t\tAvalonEditTextOutput exceptionOutput = new AvalonEditTextOutput();\n\t\t\t\t\texceptionOutput.WriteLine(ex.ToString());\n\t\t\t\t\ttextView.ShowText(exceptionOutput);\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\tstatic void ShowAvailableVersion(AvailableVersionInfo availableVersion, StackPanel stackPanel)\n\t\t{\n\t\t\tif (AppUpdateService.CurrentVersion == availableVersion.Version)\n\t\t\t{\n\t\t\t\tstackPanel.Children.Add(\n\t\t\t\t\tnew Image {\n\t\t\t\t\t\tWidth = 16, Height = 16,\n\t\t\t\t\t\tSource = Images.OK,\n\t\t\t\t\t\tMargin = new Thickness(4, 0, 4, 0)\n\t\t\t\t\t});\n\t\t\t\tstackPanel.Children.Add(\n\t\t\t\t\tnew TextBlock {\n\t\t\t\t\t\tText = Resources.UsingLatestRelease,\n\t\t\t\t\t\tVerticalAlignment = VerticalAlignment.Bottom\n\t\t\t\t\t});\n\t\t\t}\n\t\t\telse if (AppUpdateService.CurrentVersion < availableVersion.Version)\n\t\t\t{\n\t\t\t\tstackPanel.Children.Add(\n\t\t\t\t\tnew TextBlock {\n\t\t\t\t\t\tText = string.Format(Resources.VersionAvailable, availableVersion.Version),\n\t\t\t\t\t\tMargin = new Thickness(0, 0, 8, 0),\n\t\t\t\t\t\tVerticalAlignment = VerticalAlignment.Bottom\n\t\t\t\t\t});\n\t\t\t\tif (availableVersion.DownloadUrl != null)\n\t\t\t\t{\n\t\t\t\t\tButton button = ThemeManager.Current.CreateButton();\n\t\t\t\t\tbutton.Content = Resources.Download;\n\t\t\t\t\tbutton.Cursor = Cursors.Arrow;\n\t\t\t\t\tbutton.Click += delegate {\n\t\t\t\t\t\tGlobalUtils.OpenLink(availableVersion.DownloadUrl);\n\t\t\t\t\t};\n\t\t\t\t\tstackPanel.Children.Add(button);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tstackPanel.Children.Add(new TextBlock { Text = Resources.UsingNightlyBuildNewerThanLatestRelease });\n\t\t\t}\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Interface that allows plugins to extend the about page.\n\t/// </summary>\n\tpublic interface IAboutPageAddition\n\t{\n\t\tvoid Write(ISmartTextOutput textOutput);\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Analyzers/AnalyzeCommand.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nusing TomsToolbox.Composition;\n\nnamespace ICSharpCode.ILSpy.Analyzers\n{\n\t[ExportContextMenuEntry(Header = nameof(Resources.Analyze), Icon = \"Images/Search\", Category = nameof(Resources.Analyze), InputGestureText = \"Ctrl+R\", Order = 100)]\n\t[Shared]\n\tinternal sealed class AnalyzeContextMenuCommand(AnalyzerTreeViewModel analyzerTreeView) : IContextMenuEntry\n\t{\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\tif (context.TreeView is AnalyzerTreeView && context.SelectedTreeNodes != null && context.SelectedTreeNodes.All(n => n.Parent.IsRoot))\n\t\t\t\treturn false;\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn context.Reference != null && IsValidReference(context.Reference.Reference);\n\t\t\treturn context.SelectedTreeNodes.All(n => n is IMemberTreeNode);\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t{\n\t\t\t\treturn context.Reference is { Reference: IEntity };\n\t\t\t}\n\t\t\treturn context.SelectedTreeNodes\n\t\t\t\t.OfType<IMemberTreeNode>()\n\t\t\t\t.All(node => IsValidReference(node.Member));\n\t\t}\n\n\t\tstatic bool IsValidReference(object reference)\n\t\t{\n\t\t\treturn reference is IEntity and not IField { IsConst: true };\n\t\t}\n\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes != null)\n\t\t\t{\n\t\t\t\tforeach (var node in context.SelectedTreeNodes.OfType<IMemberTreeNode>().ToArray())\n\t\t\t\t{\n\t\t\t\t\tanalyzerTreeView.Analyze(node.Member);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (context.Reference is { Reference: IEntity entity })\n\t\t\t{\n\t\t\t\tanalyzerTreeView.Analyze(entity);\n\t\t\t}\n\t\t}\n\t}\n\n\t[Export]\n\t[Shared]\n\tpublic sealed class AnalyzeCommand(AssemblyTreeModel assemblyTreeModel, AnalyzerTreeViewModel analyzerTreeViewModel) : SimpleCommand\n\t{\n\t\tpublic override bool CanExecute(object parameter)\n\t\t{\n\t\t\treturn assemblyTreeModel.SelectedNodes.All(n => n is IMemberTreeNode);\n\t\t}\n\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tforeach (var node in assemblyTreeModel.SelectedNodes.OfType<IMemberTreeNode>())\n\t\t\t{\n\t\t\t\tanalyzerTreeViewModel.Analyze(node.Member);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Analyzers/AnalyzerEntityTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Windows;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.TreeView;\nusing ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;\n\n#nullable enable\n\nnamespace ICSharpCode.ILSpy.Analyzers\n{\n\t/// <summary>\n\t/// Base class for entity nodes.\n\t/// </summary>\n\tpublic abstract class AnalyzerEntityTreeNode : AnalyzerTreeNode, IMemberTreeNode\n\t{\n\t\tpublic abstract IEntity? Member { get; }\n\n\t\tpublic IEntity? SourceMember { get; protected set; }\n\n\t\tpublic override void ActivateItem(IPlatformRoutedEventArgs e)\n\t\t{\n\t\t\te.Handled = true;\n\t\t\tif (this.Member == null || this.Member.MetadataToken.IsNil)\n\t\t\t{\n\t\t\t\tMessageBox.Show(Properties.Resources.CannotAnalyzeMissingRef, \"ILSpy\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar module = this.Member.ParentModule?.MetadataFile;\n\n\t\t\tDebug.Assert(module != null);\n\n\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(module, this.Member.MetadataToken), this.SourceMember));\n\t\t}\n\n\t\tpublic override object? ToolTip => Member?.ParentModule?.MetadataFile?.FileName;\n\n\t\tpublic override bool HandleAssemblyListChanged(ICollection<LoadedAssembly> removedAssemblies, ICollection<LoadedAssembly> addedAssemblies)\n\t\t{\n\t\t\tif (Member == null)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tforeach (LoadedAssembly asm in removedAssemblies)\n\t\t\t{\n\t\t\t\tif (this.Member.ParentModule!.MetadataFile == asm.GetMetadataFileOrNull())\n\t\t\t\t\treturn false; // remove this node\n\t\t\t}\n\t\t\tthis.Children.RemoveAll(\n\t\t\t\tdelegate (SharpTreeNode n) {\n\t\t\t\t\treturn n is not AnalyzerTreeNode an || !an.HandleAssemblyListChanged(removedAssemblies, addedAssemblies);\n\t\t\t\t});\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Analyzers/AnalyzerRootNode.cs",
    "content": "// Copyright (c) 2024 Tom Englert for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.Linq;\n\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.TreeView;\n\nnamespace ICSharpCode.ILSpy.Analyzers;\n\npublic sealed class AnalyzerRootNode : AnalyzerTreeNode\n{\n\tpublic AnalyzerRootNode()\n\t{\n\t\tMessageBus<CurrentAssemblyListChangedEventArgs>.Subscribers += (sender, e) => CurrentAssemblyList_Changed(sender, e);\n\t}\n\n\tvoid CurrentAssemblyList_Changed(object sender, NotifyCollectionChangedEventArgs e)\n\t{\n\t\tif (e.Action == NotifyCollectionChangedAction.Reset)\n\t\t{\n\t\t\tthis.Children.Clear();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tvar removedAssemblies = e.OldItems?.Cast<LoadedAssembly>().ToArray() ?? [];\n\t\t\tvar addedAssemblies = e.NewItems?.Cast<LoadedAssembly>().ToArray() ?? [];\n\n\t\t\tHandleAssemblyListChanged(removedAssemblies, addedAssemblies);\n\t\t}\n\t}\n\n\tpublic override bool HandleAssemblyListChanged(ICollection<LoadedAssembly> removedAssemblies, ICollection<LoadedAssembly> addedAssemblies)\n\t{\n\t\tthis.Children.RemoveAll(\n\t\t\tdelegate (SharpTreeNode n) {\n\t\t\t\tAnalyzerTreeNode an = n as AnalyzerTreeNode;\n\t\t\t\treturn an == null || !an.HandleAssemblyListChanged(removedAssemblies, addedAssemblies);\n\t\t\t});\n\t\treturn true;\n\t}\n}"
  },
  {
    "path": "ILSpy/Analyzers/AnalyzerSearchTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.Analyzers.TreeNodes;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.Analyzers;\n\nnamespace ICSharpCode.ILSpy.Analyzers\n{\n\tclass AnalyzerSearchTreeNode : AnalyzerTreeNode\n\t{\n\t\tprivate readonly ThreadingSupport threading = new ThreadingSupport();\n\t\treadonly ISymbol symbol;\n\t\treadonly IAnalyzer analyzer;\n\t\treadonly string analyzerHeader;\n\n\t\tpublic AnalyzerSearchTreeNode(ISymbol symbol, IAnalyzer analyzer, string analyzerHeader)\n\t\t{\n\t\t\tthis.symbol = symbol;\n\t\t\tthis.analyzer = analyzer ?? throw new ArgumentNullException(nameof(analyzer));\n\t\t\tthis.LazyLoading = true;\n\t\t\tthis.analyzerHeader = analyzerHeader;\n\t\t}\n\n\t\tpublic override object Text => analyzerHeader\n\t\t\t+ (Children.Count > 0 && !threading.IsRunning ? \" (\" + Children.Count + \" in \" + threading.EllapsedMilliseconds + \"ms)\" : \"\");\n\n\t\tpublic override object Icon => Images.Search;\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tthreading.LoadChildren(this, FetchChildren);\n\t\t}\n\n\t\tprotected IEnumerable<AnalyzerTreeNode> FetchChildren(CancellationToken ct)\n\t\t{\n\t\t\tif (symbol is IEntity)\n\t\t\t{\n\t\t\t\tvar context = new AnalyzerContext {\n\t\t\t\t\tCancellationToken = ct,\n\t\t\t\t\tLanguage = Language,\n\t\t\t\t\tAssemblyList = AssemblyList\n\t\t\t\t};\n\t\t\t\tvar results = analyzer.Analyze(symbol, context).Select(SymbolTreeNodeFactory);\n\t\t\t\tif (context.SortResults)\n\t\t\t\t{\n\t\t\t\t\tresults = results.OrderBy(tn => tn.Text?.ToString(), NaturalStringComparer.Instance);\n\t\t\t\t}\n\t\t\t\treturn results;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthrow new NotSupportedException(\"Currently symbols that are not entities are not supported!\");\n\t\t\t}\n\t\t}\n\n\t\tAnalyzerTreeNode SymbolTreeNodeFactory(ISymbol resultSymbol)\n\t\t{\n\t\t\tif (resultSymbol == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(resultSymbol));\n\t\t\t}\n\n\t\t\tswitch (resultSymbol)\n\t\t\t{\n\t\t\t\tcase IModule module:\n\t\t\t\t\treturn new AnalyzedModuleTreeNode(module, (IEntity)this.symbol);\n\t\t\t\tcase ITypeDefinition td:\n\t\t\t\t\treturn new AnalyzedTypeTreeNode(td, (IEntity)this.symbol);\n\t\t\t\tcase IField fd:\n\t\t\t\t\treturn new AnalyzedFieldTreeNode(fd, (IEntity)this.symbol);\n\t\t\t\tcase IMethod md:\n\t\t\t\t\treturn new AnalyzedMethodTreeNode(md, (IEntity)this.symbol);\n\t\t\t\tcase IProperty pd:\n\t\t\t\t\treturn new AnalyzedPropertyTreeNode(pd, (IEntity)this.symbol);\n\t\t\t\tcase IEvent ed:\n\t\t\t\t\treturn new AnalyzedEventTreeNode(ed, (IEntity)this.symbol);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(resultSymbol), $\"Symbol {resultSymbol.GetType().FullName} is not supported.\");\n\t\t\t}\n\t\t}\n\n\t\tprotected override void OnIsVisibleChanged()\n\t\t{\n\t\t\tbase.OnIsVisibleChanged();\n\t\t\tif (!this.IsVisible && threading.IsRunning)\n\t\t\t{\n\t\t\t\tthis.LazyLoading = true;\n\t\t\t\tthreading.Cancel();\n\t\t\t\tthis.Children.Clear();\n\t\t\t\tRaisePropertyChanged(nameof(Text));\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool HandleAssemblyListChanged(ICollection<LoadedAssembly> removedAssemblies, ICollection<LoadedAssembly> addedAssemblies)\n\t\t{\n\t\t\t// only cancel a running analysis if user has manually added/removed assemblies\n\t\t\tbool manualAdd = false;\n\t\t\tforeach (var asm in addedAssemblies)\n\t\t\t{\n\t\t\t\tif (!asm.IsAutoLoaded)\n\t\t\t\t\tmanualAdd = true;\n\t\t\t}\n\t\t\tif (removedAssemblies.Count > 0 || manualAdd)\n\t\t\t{\n\t\t\t\tthis.LazyLoading = true;\n\t\t\t\tthreading.Cancel();\n\t\t\t\tthis.Children.Clear();\n\t\t\t\tRaisePropertyChanged(nameof(Text));\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Analyzers/AnalyzerTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.Analyzers;\nusing ICSharpCode.ILSpyX.TreeView;\n\nusing TomsToolbox.Composition;\n\nnamespace ICSharpCode.ILSpy.Analyzers\n{\n\tpublic abstract class AnalyzerTreeNode : SharpTreeNode\n\t{\n\t\tprotected static Language Language => App.ExportProvider.GetExportedValue<LanguageService>().Language;\n\n\t\tprotected static AssemblyList AssemblyList => App.ExportProvider.GetExportedValue<AssemblyList>();\n\n\t\tpublic override bool CanDelete()\n\t\t{\n\t\t\treturn Parent is { IsRoot: true };\n\t\t}\n\n\t\tpublic override void DeleteCore()\n\t\t{\n\t\t\tParent.Children.Remove(this);\n\t\t}\n\n\t\tpublic override void Delete()\n\t\t{\n\t\t\tDeleteCore();\n\t\t}\n\n\t\tpublic static ICollection<IExport<IAnalyzer, IAnalyzerMetadata>> Analyzers => App.ExportProvider\n\t\t\t.GetExports<IAnalyzer, IAnalyzerMetadata>(\"Analyzer\")\n\t\t\t.OrderBy(item => item.Metadata?.Order)\n\t\t\t.ToArray();\n\n\t\t/// <summary>\n\t\t/// Handles changes to the assembly list.\n\t\t/// </summary>\n\t\tpublic abstract bool HandleAssemblyListChanged(ICollection<LoadedAssembly> removedAssemblies, ICollection<LoadedAssembly> addedAssemblies);\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Analyzers/AnalyzerTreeView.xaml",
    "content": "<treeView:SharpTreeView\n\tx:Class=\"ICSharpCode.ILSpy.Analyzers.AnalyzerTreeView\"\n\txmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n\txmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n\txmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n\txmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n\txmlns:toms=\"urn:TomsToolbox\"\n\txmlns:treeView=\"clr-namespace:ICSharpCode.ILSpy.Controls.TreeView\"\n\txmlns:analyzers=\"clr-namespace:ICSharpCode.ILSpy.Analyzers\"\n\tmc:Ignorable=\"d\" d:DesignHeight=\"450\" d:DesignWidth=\"800\"\n\td:DataContext=\"{d:DesignInstance analyzers:AnalyzerTreeViewModel}\"\n\tShowRoot=\"False\"\n\tBorderThickness=\"0\"\n\tRoot=\"{Binding Root}\"\n\ttoms:MultiSelectorExtensions.SelectionBinding=\"{Binding SelectedItems, Mode=TwoWay}\"\n\tSelectionChanged=\"AnalyzerTreeView_OnSelectionChanged\">\n\n\t<UIElement.InputBindings>\n\t\t<KeyBinding Key=\"R\" Modifiers=\"Control\" Command=\"{Binding AnalyzeCommand}\" />\n\t</UIElement.InputBindings>\n\n</treeView:SharpTreeView>"
  },
  {
    "path": "ILSpy/Analyzers/AnalyzerTreeView.xaml.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Windows.Controls;\n\nusing ICSharpCode.ILSpyX.TreeView;\n\nusing TomsToolbox.Wpf.Composition.AttributedModel;\n\nnamespace ICSharpCode.ILSpy.Analyzers\n{\n\t/// <summary>\n\t/// Interaction logic for AnalyzerTreeView.xaml\n\t/// </summary>\n\t[DataTemplate(typeof(AnalyzerTreeViewModel))]\n\t[NonShared]\n\t[Export]\n\tpublic partial class AnalyzerTreeView\n\t{\n\t\tpublic AnalyzerTreeView()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t\tContextMenuProvider.Add(this);\n\t\t}\n\n\t\tprivate void AnalyzerTreeView_OnSelectionChanged(object sender, SelectionChangedEventArgs e)\n\t\t{\n\t\t\tif (SelectedItem is SharpTreeNode sharpTreeNode)\n\t\t\t{\n\t\t\t\tFocusNode(sharpTreeNode);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Analyzers/AnalyzerTreeViewModel.cs",
    "content": "// Copyright (c) 2024 Tom Englert for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Composition;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Input;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.Analyzers.TreeNodes;\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.ViewModels;\n\nusing TomsToolbox.Wpf;\n\nnamespace ICSharpCode.ILSpy.Analyzers\n{\n\t[ExportToolPane]\n\t[Shared]\n\t[Export]\n\tpublic class AnalyzerTreeViewModel : ToolPaneModel\n\t{\n\t\tpublic const string PaneContentId = \"analyzerPane\";\n\n\t\tpublic AnalyzerTreeViewModel(AssemblyTreeModel assemblyTreeModel)\n\t\t{\n\t\t\tContentId = PaneContentId;\n\t\t\tTitle = Properties.Resources.Analyze;\n\t\t\tShortcutKey = new(Key.R, ModifierKeys.Control);\n\t\t\tAssociatedCommand = new AnalyzeCommand(assemblyTreeModel, this);\n\t\t}\n\n\t\tpublic AnalyzerRootNode Root { get; } = new();\n\n\t\tpublic ICommand AnalyzeCommand => new DelegateCommand(AnalyzeSelected);\n\n\t\tprivate AnalyzerTreeNode[] selectedItems = [];\n\n\t\tpublic AnalyzerTreeNode[] SelectedItems {\n\t\t\tget => selectedItems ?? [];\n\t\t\tset {\n\t\t\t\tif (SelectedItems.SequenceEqual(value))\n\t\t\t\t\treturn;\n\n\t\t\t\tselectedItems = value;\n\t\t\t\tOnPropertyChanged();\n\t\t\t}\n\t\t}\n\n\t\tprivate void AnalyzeSelected()\n\t\t{\n\t\t\tforeach (var node in SelectedItems.OfType<IMemberTreeNode>())\n\t\t\t{\n\t\t\t\tAnalyze(node.Member);\n\t\t\t}\n\t\t}\n\n\t\tvoid AddOrSelect(AnalyzerTreeNode node)\n\t\t{\n\t\t\tShow();\n\n\t\t\tAnalyzerTreeNode target = default;\n\n\t\t\tif (node is AnalyzerEntityTreeNode { Member: { } member })\n\t\t\t{\n\t\t\t\ttarget = this.Root.Children.OfType<AnalyzerEntityTreeNode>().FirstOrDefault(item => item.Member == member);\n\t\t\t}\n\n\t\t\tif (target == null)\n\t\t\t{\n\t\t\t\tthis.Root.Children.Add(node);\n\t\t\t\ttarget = node;\n\t\t\t}\n\n\t\t\ttarget.IsExpanded = true;\n\t\t\tthis.SelectedItems = [target];\n\t\t}\n\n\t\tpublic void Analyze(IEntity entity)\n\t\t{\n\t\t\tif (entity == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(entity));\n\t\t\t}\n\n\t\t\tif (entity.MetadataToken.IsNil)\n\t\t\t{\n\t\t\t\tMessageBox.Show(Properties.Resources.CannotAnalyzeMissingRef, \"ILSpy\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tswitch (entity)\n\t\t\t{\n\t\t\t\tcase ITypeDefinition td:\n\t\t\t\t\tAddOrSelect(new AnalyzedTypeTreeNode(td, null));\n\t\t\t\t\tbreak;\n\t\t\t\tcase IField fd:\n\t\t\t\t\tif (!fd.IsConst)\n\t\t\t\t\t\tAddOrSelect(new AnalyzedFieldTreeNode(fd, null));\n\t\t\t\t\tbreak;\n\t\t\t\tcase IMethod md:\n\t\t\t\t\tAddOrSelect(new AnalyzedMethodTreeNode(md, null));\n\t\t\t\t\tbreak;\n\t\t\t\tcase IProperty pd:\n\t\t\t\t\tAddOrSelect(new AnalyzedPropertyTreeNode(pd, null));\n\t\t\t\t\tbreak;\n\t\t\t\tcase IEvent ed:\n\t\t\t\t\tAddOrSelect(new AnalyzedEventTreeNode(ed, null));\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(entity), $@\"Entity {entity.GetType().FullName} is not supported.\");\n\t\t\t}\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ILSpy/Analyzers/CopyAnalysisResultsContextMenuEntry.cs",
    "content": "// Copyright (c) 2022 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Linq;\nusing System.Text;\nusing System.Windows;\n\nnamespace ICSharpCode.ILSpy.Analyzers\n{\n\t[ExportContextMenuEntry(Header = \"Copy results\", Category = \"Analyze\", Order = 200)]\n\t[Shared]\n\tinternal sealed class CopyAnalysisResultsContextMenuEntry : IContextMenuEntry\n\t{\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\tif (context.TreeView is AnalyzerTreeView && context.SelectedTreeNodes != null && context.SelectedTreeNodes.All(n => n is AnalyzerSearchTreeNode))\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tStringBuilder sb = new StringBuilder();\n\t\t\tif (context.SelectedTreeNodes != null)\n\t\t\t{\n\t\t\t\tforeach (var node in context.SelectedTreeNodes)\n\t\t\t\t{\n\t\t\t\t\tforeach (var item in node.Children)\n\t\t\t\t\t{\n\t\t\t\t\t\tsb.AppendLine(item.Text.ToString());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tClipboard.SetText(sb.ToString());\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Analyzers/RemoveAnalyzeContextMenuEntry.cs",
    "content": "// Copyright (c) 2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Linq;\n\nnamespace ICSharpCode.ILSpy.Analyzers\n{\n\t[ExportContextMenuEntry(Header = \"Remove\", Icon = \"images/Delete\", Category = \"Analyze\", Order = 200)]\n\t[Shared]\n\tinternal sealed class RemoveAnalyzeContextMenuEntry : IContextMenuEntry\n\t{\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\tif (context.TreeView is AnalyzerTreeView && context.SelectedTreeNodes != null && context.SelectedTreeNodes.All(n => n.Parent.IsRoot))\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes != null)\n\t\t\t{\n\t\t\t\tforeach (var node in context.SelectedTreeNodes)\n\t\t\t\t{\n\t\t\t\t\tnode.Parent.Children.Remove(node);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Analyzers/TreeNodes/AnalyzedAccessorTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpy.Analyzers.TreeNodes\n{\n\tclass AnalyzedAccessorTreeNode : AnalyzedMethodTreeNode\n\t{\n\t\treadonly string name;\n\n\t\tpublic AnalyzedAccessorTreeNode(IMethod analyzedMethod, IEntity source, string name)\n\t\t\t: base(analyzedMethod, source)\n\t\t{\n\t\t\tif (string.IsNullOrWhiteSpace(name))\n\t\t\t{\n\t\t\t\tthrow new System.ArgumentException(\"name must be a non-empty string\", nameof(name));\n\t\t\t}\n\n\t\t\tthis.name = name;\n\t\t}\n\n\t\tpublic override object Text => name;\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Analyzers/TreeNodes/AnalyzedEventTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\n\nusing ICSharpCode.Decompiler.Output;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.TreeNodes;\n\n#nullable enable\n\nnamespace ICSharpCode.ILSpy.Analyzers.TreeNodes\n{\n\tinternal sealed class AnalyzedEventTreeNode : AnalyzerEntityTreeNode\n\t{\n\t\treadonly IEvent analyzedEvent;\n\t\treadonly string prefix;\n\n\t\tpublic AnalyzedEventTreeNode(IEvent analyzedEvent, IEntity? source, string prefix = \"\")\n\t\t{\n\t\t\tthis.analyzedEvent = analyzedEvent ?? throw new ArgumentNullException(nameof(analyzedEvent));\n\t\t\tthis.prefix = prefix;\n\t\t\tthis.LazyLoading = true;\n\t\t\tthis.SourceMember = source;\n\t\t}\n\n\t\tpublic override IEntity Member => analyzedEvent;\n\n\t\tpublic override object Icon => EventTreeNode.GetIcon(analyzedEvent);\n\n\t\t// TODO: This way of formatting is not suitable for events which explicitly implement interfaces.\n\t\tpublic override object Text => prefix + Language.EntityToString(analyzedEvent, ConversionFlags.ShowDeclaringType | ConversionFlags.UseFullyQualifiedEntityNames);\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tif (analyzedEvent.CanAdd)\n\t\t\t\tthis.Children.Add(new AnalyzedAccessorTreeNode(analyzedEvent.AddAccessor, this.SourceMember, \"add\"));\n\t\t\tif (analyzedEvent.CanRemove)\n\t\t\t\tthis.Children.Add(new AnalyzedAccessorTreeNode(analyzedEvent.RemoveAccessor, this.SourceMember, \"remove\"));\n\t\t\tif (TryFindBackingField(analyzedEvent, out var backingField))\n\t\t\t\tthis.Children.Add(new AnalyzedFieldTreeNode(backingField, this.SourceMember));\n\n\t\t\tforeach (var lazy in Analyzers)\n\t\t\t{\n\t\t\t\tvar analyzer = lazy.Value;\n\t\t\t\tDebug.Assert(analyzer != null);\n\t\t\t\tif (analyzer.Show(analyzedEvent))\n\t\t\t\t{\n\t\t\t\t\tthis.Children.Add(new AnalyzerSearchTreeNode(analyzedEvent, analyzer, lazy.Metadata?.Header));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool TryFindBackingField(IEvent analyzedEvent, [NotNullWhen(true)] out IField? backingField)\n\t\t{\n\t\t\tbackingField = null;\n\t\t\tforeach (var field in analyzedEvent.DeclaringTypeDefinition?.GetFields(options: GetMemberOptions.IgnoreInheritedMembers) ?? [])\n\t\t\t{\n\t\t\t\tif (field.Name == analyzedEvent.Name && field.Accessibility == Decompiler.TypeSystem.Accessibility.Private)\n\t\t\t\t{\n\t\t\t\t\tbackingField = field;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Analyzers/TreeNodes/AnalyzedFieldTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\n\nusing ICSharpCode.Decompiler.Output;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.TreeNodes;\n\n#nullable enable\n\nnamespace ICSharpCode.ILSpy.Analyzers.TreeNodes\n{\n\tclass AnalyzedFieldTreeNode : AnalyzerEntityTreeNode\n\t{\n\t\treadonly IField analyzedField;\n\n\t\tpublic AnalyzedFieldTreeNode(IField analyzedField, IEntity? source)\n\t\t{\n\t\t\tthis.analyzedField = analyzedField ?? throw new ArgumentNullException(nameof(analyzedField));\n\t\t\tthis.SourceMember = source;\n\t\t\tthis.LazyLoading = true;\n\t\t}\n\n\t\tpublic override object Icon => FieldTreeNode.GetIcon(analyzedField);\n\n\t\tpublic override object Text => Language.EntityToString(analyzedField, ConversionFlags.ShowDeclaringType | ConversionFlags.UseFullyQualifiedEntityNames);\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tforeach (var lazy in Analyzers)\n\t\t\t{\n\t\t\t\tvar analyzer = lazy.Value;\n\t\t\t\tDebug.Assert(analyzer != null);\n\t\t\t\tif (analyzer.Show(analyzedField))\n\t\t\t\t{\n\t\t\t\t\tthis.Children.Add(new AnalyzerSearchTreeNode(analyzedField, analyzer, lazy.Metadata?.Header));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic override IEntity Member => analyzedField;\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Analyzers/TreeNodes/AnalyzedMethodTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\n\nusing ICSharpCode.Decompiler.Output;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.TreeNodes;\n\n#nullable enable\n\nnamespace ICSharpCode.ILSpy.Analyzers.TreeNodes\n{\n\tinternal class AnalyzedMethodTreeNode : AnalyzerEntityTreeNode\n\t{\n\t\treadonly IMethod analyzedMethod;\n\t\treadonly string prefix;\n\n\t\tpublic AnalyzedMethodTreeNode(IMethod analyzedMethod, IEntity? source, string prefix = \"\")\n\t\t{\n\t\t\tthis.analyzedMethod = analyzedMethod ?? throw new ArgumentNullException(nameof(analyzedMethod));\n\t\t\tthis.SourceMember = source;\n\t\t\tthis.prefix = prefix;\n\t\t\tthis.LazyLoading = true;\n\t\t}\n\n\t\tpublic override object Icon => MethodTreeNode.GetIcon(analyzedMethod);\n\n\t\tpublic override object Text => prefix + Language.EntityToString(analyzedMethod, ConversionFlags.ShowDeclaringType | ConversionFlags.UseFullyQualifiedEntityNames);\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tforeach (var lazy in Analyzers)\n\t\t\t{\n\t\t\t\tvar analyzer = lazy.Value;\n\t\t\t\tDebug.Assert(analyzer != null);\n\t\t\t\tif (analyzer.Show(analyzedMethod))\n\t\t\t\t{\n\t\t\t\t\tthis.Children.Add(new AnalyzerSearchTreeNode(analyzedMethod, analyzer, lazy.Metadata!.Header));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic override IEntity Member => analyzedMethod;\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Windows;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.TreeView;\nusing ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;\n\n#nullable enable\n\nnamespace ICSharpCode.ILSpy.Analyzers.TreeNodes\n{\n\tinternal class AnalyzedModuleTreeNode : AnalyzerEntityTreeNode\n\t{\n\t\treadonly IModule analyzedModule;\n\n\t\tpublic AnalyzedModuleTreeNode(IModule analyzedModule, IEntity? source)\n\t\t{\n\t\t\tthis.analyzedModule = analyzedModule ?? throw new ArgumentNullException(nameof(analyzedModule));\n\t\t\tthis.SourceMember = source;\n\t\t\tthis.LazyLoading = true;\n\t\t}\n\n\t\tpublic override object Icon => Images.Assembly;\n\n\t\tpublic override object Text => analyzedModule.AssemblyName;\n\n\t\tpublic override object? ToolTip => analyzedModule.MetadataFile?.FileName;\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tforeach (var lazy in Analyzers)\n\t\t\t{\n\t\t\t\tvar analyzer = lazy.Value;\n\t\t\t\tDebug.Assert(analyzer != null);\n\t\t\t\tif (analyzer.Show(analyzedModule))\n\t\t\t\t{\n\t\t\t\t\tthis.Children.Add(new AnalyzerSearchTreeNode(analyzedModule, analyzer, lazy.Metadata!.Header));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic override void ActivateItem(IPlatformRoutedEventArgs e)\n\t\t{\n\t\t\te.Handled = true;\n\t\t\tif (analyzedModule.MetadataFile == null)\n\t\t\t{\n\t\t\t\tMessageBox.Show(Properties.Resources.CannotAnalyzeMissingRef, \"ILSpy\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(analyzedModule.MetadataFile));\n\t\t}\n\n\t\tpublic override IEntity? Member => null;\n\n\t\tpublic override bool HandleAssemblyListChanged(ICollection<LoadedAssembly> removedAssemblies, ICollection<LoadedAssembly> addedAssemblies)\n\t\t{\n\t\t\tif (analyzedModule == null)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tforeach (LoadedAssembly asm in removedAssemblies)\n\t\t\t{\n\t\t\t\tif (this.analyzedModule.MetadataFile == asm.GetMetadataFileOrNull())\n\t\t\t\t\treturn false; // remove this node\n\t\t\t}\n\t\t\tthis.Children.RemoveAll(\n\t\t\t\tdelegate (SharpTreeNode n) {\n\t\t\t\t\treturn n is not AnalyzerTreeNode an || !an.HandleAssemblyListChanged(removedAssemblies, addedAssemblies);\n\t\t\t\t});\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Analyzers/TreeNodes/AnalyzedPropertyTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\n\nusing ICSharpCode.Decompiler.Output;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.TreeNodes;\n\n#nullable enable\n\nnamespace ICSharpCode.ILSpy.Analyzers.TreeNodes\n{\n\tsealed class AnalyzedPropertyTreeNode : AnalyzerEntityTreeNode\n\t{\n\t\treadonly IProperty analyzedProperty;\n\t\treadonly string prefix;\n\n\t\tpublic AnalyzedPropertyTreeNode(IProperty analyzedProperty, IEntity? source, string prefix = \"\")\n\t\t{\n\t\t\tthis.analyzedProperty = analyzedProperty ?? throw new ArgumentNullException(nameof(analyzedProperty));\n\t\t\tthis.prefix = prefix;\n\t\t\tthis.LazyLoading = true;\n\t\t\tthis.SourceMember = source;\n\t\t}\n\n\t\tpublic override object Icon => PropertyTreeNode.GetIcon(analyzedProperty);\n\n\t\t// TODO: This way of formatting is not suitable for properties which explicitly implement interfaces.\n\t\tpublic override object Text => prefix + Language.EntityToString(analyzedProperty, ConversionFlags.ShowDeclaringType | ConversionFlags.UseFullyQualifiedEntityNames);\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tif (analyzedProperty.CanGet)\n\t\t\t\tthis.Children.Add(new AnalyzedAccessorTreeNode(analyzedProperty.Getter, this.SourceMember, \"get\"));\n\t\t\tif (analyzedProperty.CanSet)\n\t\t\t\tthis.Children.Add(new AnalyzedAccessorTreeNode(analyzedProperty.Setter, this.SourceMember, \"set\"));\n\n\t\t\tforeach (var lazy in Analyzers)\n\t\t\t{\n\t\t\t\tvar analyzer = lazy.Value;\n\t\t\t\tDebug.Assert(analyzer != null);\n\t\t\t\tif (analyzer.Show(analyzedProperty))\n\t\t\t\t{\n\t\t\t\t\tthis.Children.Add(new AnalyzerSearchTreeNode(analyzedProperty, analyzer, lazy.Metadata!.Header));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic override IEntity Member => analyzedProperty;\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Analyzers/TreeNodes/AnalyzedTypeTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.TreeNodes;\n\n#nullable enable\n\nnamespace ICSharpCode.ILSpy.Analyzers.TreeNodes\n{\n\tinternal class AnalyzedTypeTreeNode : AnalyzerEntityTreeNode\n\t{\n\t\treadonly ITypeDefinition analyzedType;\n\n\t\tpublic AnalyzedTypeTreeNode(ITypeDefinition analyzedType, IEntity? source)\n\t\t{\n\t\t\tthis.analyzedType = analyzedType ?? throw new ArgumentNullException(nameof(analyzedType));\n\t\t\tthis.SourceMember = source;\n\t\t\tthis.LazyLoading = true;\n\t\t}\n\n\t\tpublic override object Icon => TypeTreeNode.GetIcon(analyzedType);\n\n\t\tpublic override object Text => Language.TypeToString(analyzedType);\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tforeach (var lazy in Analyzers)\n\t\t\t{\n\t\t\t\tvar analyzer = lazy.Value;\n\t\t\t\tDebug.Assert(analyzer != null);\n\t\t\t\tif (analyzer.Show(analyzedType))\n\t\t\t\t{\n\t\t\t\t\tthis.Children.Add(new AnalyzerSearchTreeNode(analyzedType, analyzer, lazy.Metadata!.Header));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic override IEntity Member => analyzedType;\n\t}\n}\n"
  },
  {
    "path": "ILSpy/App.xaml",
    "content": "<Application x:Class=\"ICSharpCode.ILSpy.App\"\n\t\t\t xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n\t\t\t xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n\t\t\t xmlns:styles=\"urn:TomsToolbox.Wpf.Styles\"\n\t\t\t xmlns:toms=\"urn:TomsToolbox\"\n\t\t\t xmlns:themes=\"clr-namespace:ICSharpCode.ILSpy.Themes\"\n\t\t\t xmlns:composition=\"urn:TomsToolbox.Composition\"\n\t\t\t xmlns:util=\"clr-namespace:ICSharpCode.ILSpy.Util\">\n\t<Application.Resources>\n\t\t<Style x:Key=\"DialogWindow\" TargetType=\"{x:Type Window}\">\n\t\t\t<Setter Property=\"ShowInTaskbar\" Value=\"False\" />\n\t\t\t<Setter Property=\"UseLayoutRounding\" Value=\"True\" />\n\t\t\t<Setter Property=\"TextOptions.TextFormattingMode\" Value=\"Display\" />\n\t\t\t<Setter Property=\"toms:StyleBindings.Behaviors\">\n\t\t\t\t<Setter.Value>\n\t\t\t\t\t<toms:BehaviorCollection>\n\t\t\t\t\t\t<themes:WindowStyleManagerBehavior />\n\t\t\t\t\t</toms:BehaviorCollection>\n\t\t\t\t</Setter.Value>\n\t\t\t</Setter>\n\t\t</Style>\n\n\t\t<Style TargetType=\"{x:Type Button}\" BasedOn=\"{StaticResource {x:Static styles:ResourceKeys.ButtonStyle}}\">\n\t\t\t<Setter Property=\"MinWidth\" Value=\"73\" />\n\t\t\t<Setter Property=\"Padding\" Value=\"9,1,9,1\" />\n\t\t</Style>\n\n\t\t<Style TargetType=\"ScrollViewer\">\n\t\t\t<Setter Property=\"toms:StyleBindings.Behaviors\">\n\t\t\t\t<Setter.Value>\n\t\t\t\t\t<toms:BehaviorCollection>\n\t\t\t\t\t\t<toms:AdvancedScrollWheelBehavior UseScrollingAnimation=\"{Binding Path=(util:SettingsService.DisplaySettings).EnableSmoothScrolling, Source={composition:Import util:SettingsService}}\"/>\n\t\t\t\t\t</toms:BehaviorCollection>\n\t\t\t\t</Setter.Value>\n\t\t\t</Setter>\n\t\t</Style>\n\n\t</Application.Resources>\n</Application>"
  },
  {
    "path": "ILSpy/App.xaml.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.Loader;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Threading;\n\nusing ICSharpCode.ILSpy.AppEnv;\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpyX.Analyzers;\n\nusing Medo.Application;\n\nusing TomsToolbox.Wpf.Styles;\nusing ICSharpCode.ILSpyX.TreeView;\n\nusing TomsToolbox.Composition;\nusing TomsToolbox.Wpf.Composition;\nusing ICSharpCode.ILSpy.Themes;\nusing System.Globalization;\nusing System.Threading;\n\nusing Microsoft.Extensions.DependencyInjection;\n\nusing TomsToolbox.Composition.MicrosoftExtensions;\nusing TomsToolbox.Essentials;\n\nnamespace ICSharpCode.ILSpy\n{\n\t/// <summary>\n\t/// Interaction logic for App.xaml\n\t/// </summary>\n\tpublic partial class App : Application\n\t{\n\t\tinternal static CommandLineArguments CommandLineArguments;\n\t\tinternal static readonly IList<ExceptionData> StartupExceptions = new List<ExceptionData>();\n\n\t\tpublic static IExportProvider ExportProvider { get; private set; }\n\n\t\tinternal record ExceptionData(Exception Exception)\n\t\t{\n\t\t\tpublic string PluginName { get; init; }\n\t\t}\n\n\t\tpublic App()\n\t\t{\n\t\t\tvar cmdArgs = Environment.GetCommandLineArgs().Skip(1);\n\t\t\tCommandLineArguments = CommandLineArguments.Create(cmdArgs);\n\n\t\t\t// This is only a temporary, read only handle to the settings service to access the AllowMultipleInstances setting before DI is initialized.\n\t\t\t// At runtime, you must use the service via DI!\n\t\t\tvar settingsService = new SettingsService();\n\n\t\t\tbool forceSingleInstance = (CommandLineArguments.SingleInstance ?? true)\n\t\t\t\t\t\t\t\t\t   && !settingsService.MiscSettings.AllowMultipleInstances;\n\t\t\tif (forceSingleInstance)\n\t\t\t{\n\t\t\t\tSingleInstance.Attach();  // will auto-exit for second instance\n\t\t\t\tSingleInstance.NewInstanceDetected += SingleInstance_NewInstanceDetected;\n\t\t\t}\n\n\t\t\tInitializeComponent();\n\n\t\t\tif (!InitializeDependencyInjection(settingsService))\n\t\t\t{\n\t\t\t\t// There is something completely wrong with DI, probably some service registration is missing => nothing we can do to recover, so stop and shut down.\n\t\t\t\tExit += (_, _) => MessageBox.Show(StartupExceptions.FormatExceptions(), \"Sorry we crashed!\", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly);\n\t\t\t\tShutdown(1);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!Debugger.IsAttached)\n\t\t\t{\n\t\t\t\tAppDomain.CurrentDomain.UnhandledException += ShowErrorBox;\n\t\t\t\tDispatcher.CurrentDispatcher.UnhandledException += Dispatcher_UnhandledException;\n\t\t\t}\n\n\t\t\tTaskScheduler.UnobservedTaskException += DotNet40_UnobservedTaskException;\n\n\t\t\tSharpTreeNode.SetImagesProvider(new WpfWindowsTreeNodeImagesProvider());\n\n\t\t\tResources.RegisterDefaultStyles();\n\n\t\t\t// Register the export provider so that it can be accessed from WPF/XAML components.\n\t\t\tExportProviderLocator.Register(ExportProvider);\n\t\t\t// Add data templates registered via MEF.\n\t\t\tResources.MergedDictionaries.Add(DataTemplateManager.CreateDynamicDataTemplates(ExportProvider));\n\n\t\t\tvar sessionSettings = settingsService.SessionSettings;\n\t\t\tThemeManager.Current.Theme = sessionSettings.Theme;\n\t\t\tif (!string.IsNullOrEmpty(sessionSettings.CurrentCulture))\n\t\t\t{\n\t\t\t\tThread.CurrentThread.CurrentUICulture = CultureInfo.DefaultThreadCurrentUICulture = new(sessionSettings.CurrentCulture);\n\t\t\t}\n\n\t\t\tILSpyTraceListener.Install();\n\n\t\t\tif (CommandLineArguments.ArgumentsParser.IsShowingInformation)\n\t\t\t{\n\t\t\t\tMessageBox.Show(CommandLineArguments.ArgumentsParser.GetHelpText(), \"ILSpy Command Line Arguments\");\n\t\t\t}\n\n\t\t\tif (CommandLineArguments.ArgumentsParser.RemainingArguments.Any())\n\t\t\t{\n\t\t\t\tstring unknownArguments = string.Join(\", \", CommandLineArguments.ArgumentsParser.RemainingArguments);\n\t\t\t\tMessageBox.Show(unknownArguments, \"ILSpy Unknown Command Line Arguments Passed\");\n\t\t\t}\n\n\t\t\tsettingsService.AssemblyListManager.CreateDefaultAssemblyLists();\n\t\t}\n\n\t\tpublic new static App Current => (App)Application.Current;\n\n\t\tpublic new MainWindow MainWindow {\n\t\t\tget => (MainWindow)base.MainWindow;\n\t\t\tprivate set => base.MainWindow = value;\n\t\t}\n\n\t\tprivate static void SingleInstance_NewInstanceDetected(object sender, NewInstanceEventArgs e) => ExportProvider.GetExportedValue<AssemblyTreeModel>().HandleSingleInstanceCommandLineArguments(e.Args).HandleExceptions();\n\n\t\tstatic Assembly ResolvePluginDependencies(AssemblyLoadContext context, AssemblyName assemblyName)\n\t\t{\n\t\t\tvar rootPath = Path.GetDirectoryName(typeof(App).Assembly.Location);\n\t\t\tvar assemblyFileName = Path.Combine(rootPath, assemblyName.Name + \".dll\");\n\t\t\tif (!File.Exists(assemblyFileName))\n\t\t\t\treturn null;\n\t\t\treturn context.LoadFromAssemblyPath(assemblyFileName);\n\t\t}\n\n\t\tprivate bool InitializeDependencyInjection(SettingsService settingsService)\n\t\t{\n\t\t\t// Add custom logic for resolution of dependencies.\n\t\t\t// This necessary because the AssemblyLoadContext.LoadFromAssemblyPath and related methods,\n\t\t\t// do not automatically load dependencies.\n\t\t\tAssemblyLoadContext.Default.Resolving += ResolvePluginDependencies;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar services = new ServiceCollection();\n\n\t\t\t\tvar pluginDir = Path.GetDirectoryName(typeof(App).Module.FullyQualifiedName);\n\t\t\t\tif (pluginDir != null)\n\t\t\t\t{\n\t\t\t\t\tforeach (var plugin in Directory.GetFiles(pluginDir, \"*.Plugin.dll\"))\n\t\t\t\t\t{\n\t\t\t\t\t\tvar name = Path.GetFileNameWithoutExtension(plugin);\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(plugin);\n\t\t\t\t\t\t\tservices.BindExports(assembly);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (Exception ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Cannot show MessageBox here, because WPF would crash with a XamlParseException\n\t\t\t\t\t\t\t// Remember and show exceptions in text output, once MainWindow is properly initialized\n\t\t\t\t\t\t\tStartupExceptions.Add(new(ex) { PluginName = name });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Add the built-in parts: First, from ILSpyX\n\t\t\t\tservices.BindExports(typeof(IAnalyzer).Assembly);\n\t\t\t\t// Then from ILSpy itself\n\t\t\t\tservices.BindExports(Assembly.GetExecutingAssembly());\n\t\t\t\t// Add the settings service\n\t\t\t\tservices.AddSingleton(settingsService);\n\t\t\t\t// Add the export provider\n\t\t\t\tservices.AddSingleton(_ => ExportProvider);\n\t\t\t\t// Add the docking manager\n\t\t\t\tservices.AddSingleton(serviceProvider => serviceProvider.GetService<MainWindow>().DockManager);\n\t\t\t\tservices.AddTransient(serviceProvider => serviceProvider.GetService<AssemblyTreeModel>().AssemblyList);\n\n\t\t\t\tvar serviceProvider = services.BuildServiceProvider(new ServiceProviderOptions { ValidateOnBuild = true });\n\n\t\t\t\tExportProvider = new ExportProviderAdapter(serviceProvider);\n\n\t\t\t\tExit += (_, _) => serviceProvider.Dispose();\n\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tif (ex is AggregateException aggregate)\n\t\t\t\t\tStartupExceptions.AddRange(aggregate.InnerExceptions.Select(item => new ExceptionData(ex)));\n\t\t\t\telse\n\t\t\t\t\tStartupExceptions.Add(new(ex));\n\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tprotected override void OnStartup(StartupEventArgs e)\n\t\t{\n\t\t\tbase.OnStartup(e);\n\n\t\t\tMainWindow = ExportProvider.GetExportedValue<MainWindow>();\n\t\t\tMainWindow.Show();\n\t\t}\n\n\t\tvoid DotNet40_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)\n\t\t{\n\t\t\t// On .NET 4.0, an unobserved exception in a task terminates the process unless we mark it as observed\n\t\t\te.SetObserved();\n\t\t}\n\n\t\t#region Exception Handling\n\t\tstatic void Dispatcher_UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)\n\t\t{\n\t\t\tUnhandledException(e.Exception);\n\t\t\te.Handled = true;\n\t\t}\n\n\t\tstatic void ShowErrorBox(object sender, UnhandledExceptionEventArgs e)\n\t\t{\n\t\t\tException ex = e.ExceptionObject as Exception;\n\t\t\tif (ex != null)\n\t\t\t{\n\t\t\t\tUnhandledException(ex);\n\t\t\t}\n\t\t}\n\n\t\t[ThreadStatic]\n\t\tstatic bool showingError;\n\n\t\tinternal static void UnhandledException(Exception exception)\n\t\t{\n\t\t\tDebug.WriteLine(exception.ToString());\n\t\t\tfor (Exception ex = exception; ex != null; ex = ex.InnerException)\n\t\t\t{\n\t\t\t\tReflectionTypeLoadException rtle = ex as ReflectionTypeLoadException;\n\t\t\t\tif (rtle != null && rtle.LoaderExceptions.Length > 0)\n\t\t\t\t{\n\t\t\t\t\texception = rtle.LoaderExceptions[0];\n\t\t\t\t\tDebug.WriteLine(exception.ToString());\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (showingError)\n\t\t\t{\n\t\t\t\t// Ignore re-entrant calls\n\t\t\t\t// We run the risk of opening an infinite number of exception dialogs.\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tshowingError = true;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tMessageBox.Show(exception.ToString(), \"Sorry, we crashed\");\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tshowingError = false;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\t}\n}"
  },
  {
    "path": "ILSpy/AppEnv/AppEnvironment.cs",
    "content": "using System.Runtime.InteropServices;\n\nnamespace ICSharpCode.ILSpy.AppEnv\n{\n\tpublic static class AppEnvironment\n\t{\n\t\tpublic static bool IsWindows => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);\n\t}\n}\n"
  },
  {
    "path": "ILSpy/AppEnv/CommandLineArguments.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing McMaster.Extensions.CommandLineUtils;\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace ICSharpCode.ILSpy.AppEnv\n{\n\tpublic sealed class CommandLineArguments\n\t{\n\t\t// see /doc/Command Line.txt for details\n\t\tpublic List<string> AssembliesToLoad = new List<string>();\n\t\tpublic bool? SingleInstance;\n\t\tpublic string NavigateTo;\n\t\tpublic string Search;\n\t\tpublic string Language;\n\t\tpublic bool NoActivate;\n\t\tpublic string ConfigFile;\n\n\t\tpublic CommandLineApplication ArgumentsParser { get; }\n\n\t\tprivate CommandLineArguments(CommandLineApplication app)\n\t\t{\n\t\t\tArgumentsParser = app;\n\t\t}\n\n\t\tpublic static CommandLineArguments Create(IEnumerable<string> arguments)\n\t\t{\n\t\t\tvar app = new CommandLineApplication() {\n\t\t\t\t// https://natemcmaster.github.io/CommandLineUtils/docs/response-file-parsing.html?tabs=using-attributes\n\t\t\t\tResponseFileHandling = ResponseFileHandling.ParseArgsAsLineSeparated,\n\n\t\t\t\t// Note: options are case-sensitive (!), and, default behavior would be UnrecognizedArgumentHandling.Throw on Parse()\n\t\t\t\tUnrecognizedArgumentHandling = UnrecognizedArgumentHandling.CollectAndContinue\n\t\t\t};\n\n\t\t\tapp.HelpOption();\n\t\t\tvar instance = new CommandLineArguments(app);\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar oForceNewInstance = app.Option(\"--newinstance\",\n\t\t\t\t\t\"Start a new instance of ILSpy even if the user configuration is set to single-instance\",\n\t\t\t\t\tCommandOptionType.NoValue);\n\n\t\t\t\tvar oNavigateTo = app.Option<string>(\"-n|--navigateto <TYPENAME>\",\n\t\t\t\t\t\"Navigates to the member specified by the given ID string.\\r\\nThe member is searched for only in the assemblies specified on the command line.\\r\\nExample: 'ILSpy ILSpy.exe --navigateto T:ICSharpCode.ILSpy.CommandLineArguments'\",\n\t\t\t\t\tCommandOptionType.SingleValue);\n\t\t\t\toNavigateTo.DefaultValue = null;\n\n\t\t\t\tvar oSearch = app.Option<string>(\"-s|--search <SEARCHTERM>\",\n\t\t\t\t\t\"Search for t:TypeName, m:Member or c:Constant; use exact match (=term), 'should not contain' (-term) or 'must contain' (+term); use /reg(ular)?Ex(pressions)?/ or both - t:/Type(Name)?/...\",\n\t\t\t\t\tCommandOptionType.SingleValue);\n\t\t\t\toSearch.DefaultValue = null;\n\n\t\t\t\tvar oLanguage = app.Option<string>(\"-l|--language <LANGUAGEIDENTIFIER>\",\n\t\t\t\t\t\"Selects the specified language.\\r\\nExample: 'ILSpy --language:C#' or 'ILSpy --language IL'\",\n\t\t\t\t\tCommandOptionType.SingleValue);\n\t\t\t\toLanguage.DefaultValue = null;\n\n\t\t\t\tvar oConfig = app.Option<string>(\"-c|--config <CONFIGFILENAME>\",\n\t\t\t\t\t\"Provide a specific configuration file.\\r\\nExample: 'ILSpy --config myconfig.xml'\",\n\t\t\t\t\tCommandOptionType.SingleValue);\n\t\t\t\toConfig.DefaultValue = null;\n\n\t\t\t\tvar oNoActivate = app.Option(\"--noactivate\",\n\t\t\t\t\t\"Do not activate the existing ILSpy instance. This option has no effect if a new ILSpy instance is being started.\",\n\t\t\t\t\tCommandOptionType.NoValue);\n\n\t\t\t\t// https://natemcmaster.github.io/CommandLineUtils/docs/arguments.html#variable-numbers-of-arguments\n\t\t\t\t// To enable this, MultipleValues must be set to true, and the argument must be the last one specified.\n\t\t\t\tvar files = app.Argument(\"Assemblies\", \"Assemblies to load\", multipleValues: true);\n\n\t\t\t\tapp.Parse(arguments.ToArray());\n\n\t\t\t\tif (oForceNewInstance.HasValue())\n\t\t\t\t\tinstance.SingleInstance = false;\n\n\t\t\t\tinstance.NavigateTo = oNavigateTo.ParsedValue;\n\t\t\t\tinstance.Search = oSearch.ParsedValue;\n\t\t\t\tinstance.Language = oLanguage.ParsedValue;\n\t\t\t\tinstance.ConfigFile = oConfig.ParsedValue;\n\n\t\t\t\tif (oNoActivate.HasValue())\n\t\t\t\t\tinstance.NoActivate = true;\n\n\t\t\t\tforeach (var assembly in files.Values)\n\t\t\t\t{\n\t\t\t\t\tif (!string.IsNullOrWhiteSpace(assembly))\n\t\t\t\t\t\tinstance.AssembliesToLoad.Add(assembly);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\t// Intentionally ignore exceptions if any, this is only added to always have an exception-free startup\n\t\t\t}\n\n\t\t\treturn instance;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/AppEnv/CommandLineTools.cs",
    "content": "// Copyright (c) 2024 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Text;\n\nnamespace ICSharpCode.ILSpy.AppEnv\n{\n\tpublic class CommandLineTools\n\t{\n\t\t/// <summary>\n\t\t/// Decodes a command line into an array of arguments according to the CommandLineToArgvW rules.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Command line parsing rules:\n\t\t/// - 2n backslashes followed by a quotation mark produce n backslashes, and the quotation mark is considered to be the end of the argument.\n\t\t/// - (2n) + 1 backslashes followed by a quotation mark again produce n backslashes followed by a quotation mark.\n\t\t/// - n backslashes not followed by a quotation mark simply produce n backslashes.\n\t\t/// </remarks>\n\t\tpublic static string[] CommandLineToArgumentArray(string commandLine)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(commandLine))\n\t\t\t\treturn Array.Empty<string>();\n\n\t\t\tvar results = new List<string>();\n\t\t\tParseArgv.ParseArgumentsIntoList(commandLine, results);\n\n\t\t\treturn results.ToArray();\n\t\t}\n\n\t\tstatic readonly char[] charsNeedingQuoting = { ' ', '\\t', '\\n', '\\v', '\"' };\n\n\t\t/// <summary>\n\t\t/// Escapes a set of arguments according to the CommandLineToArgvW rules.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Command line parsing rules:\n\t\t/// - 2n backslashes followed by a quotation mark produce n backslashes, and the quotation mark is considered to be the end of the argument.\n\t\t/// - (2n) + 1 backslashes followed by a quotation mark again produce n backslashes followed by a quotation mark.\n\t\t/// - n backslashes not followed by a quotation mark simply produce n backslashes.\n\t\t/// </remarks>\n\t\tpublic static string ArgumentArrayToCommandLine(params string[] arguments)\n\t\t{\n\t\t\tif (arguments == null)\n\t\t\t\treturn null;\n\t\t\tStringBuilder b = new StringBuilder();\n\t\t\tfor (int i = 0; i < arguments.Length; i++)\n\t\t\t{\n\t\t\t\tif (i > 0)\n\t\t\t\t\tb.Append(' ');\n\t\t\t\tAppendArgument(b, arguments[i]);\n\t\t\t}\n\t\t\treturn b.ToString();\n\t\t}\n\n\t\tstatic void AppendArgument(StringBuilder b, string arg)\n\t\t{\n\t\t\tif (arg == null)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (arg.Length > 0 && arg.IndexOfAny(charsNeedingQuoting) < 0)\n\t\t\t{\n\t\t\t\tb.Append(arg);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tb.Append('\"');\n\t\t\t\tfor (int j = 0; ; j++)\n\t\t\t\t{\n\t\t\t\t\tint backslashCount = 0;\n\t\t\t\t\twhile (j < arg.Length && arg[j] == '\\\\')\n\t\t\t\t\t{\n\t\t\t\t\t\tbackslashCount++;\n\t\t\t\t\t\tj++;\n\t\t\t\t\t}\n\t\t\t\t\tif (j == arg.Length)\n\t\t\t\t\t{\n\t\t\t\t\t\tb.Append('\\\\', backslashCount * 2);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\telse if (arg[j] == '\"')\n\t\t\t\t\t{\n\t\t\t\t\t\tb.Append('\\\\', backslashCount * 2 + 1);\n\t\t\t\t\t\tb.Append('\"');\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tb.Append('\\\\', backslashCount);\n\t\t\t\t\t\tb.Append(arg[j]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tb.Append('\"');\n\t\t\t}\n\t\t}\n\n\t\tpublic static string FullyQualifyPath(string argument)\n\t\t{\n\t\t\t// Fully qualify the paths before passing them to another process,\n\t\t\t// because that process might use a different current directory.\n\t\t\tif (string.IsNullOrEmpty(argument) || argument[0] == '-')\n\t\t\t\treturn argument;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (argument.StartsWith(\"@\"))\n\t\t\t\t{\n\t\t\t\t\treturn \"@\" + FullyQualifyPath(argument.Substring(1));\n\t\t\t\t}\n\t\t\t\treturn Path.Combine(Environment.CurrentDirectory, argument);\n\t\t\t}\n\t\t\tcatch (ArgumentException)\n\t\t\t{\n\t\t\t\treturn argument;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Source: https://github.com/dotnet/runtime/blob/bc9fc5a774d96f95abe0ea5c90fac48b38ed2e67/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs#L574-L606\n\t// Minor adaptations in GetNextArgument (ValueStringBuilder replaced), otherwise kept as identical as possible\n\tpublic static class ParseArgv\n\t{\n\t\t/// <summary>Parses a command-line argument string into a list of arguments.</summary>\n\t\t/// <param name=\"arguments\">The argument string.</param>\n\t\t/// <param name=\"results\">The list into which the component arguments should be stored.</param>\n\t\t/// <remarks>\n\t\t/// This follows the rules outlined in \"Parsing C++ Command-Line Arguments\" at\n\t\t/// https://msdn.microsoft.com/en-us/library/17w5ykft.aspx.\n\t\t/// </remarks>\n\t\tpublic static void ParseArgumentsIntoList(string arguments, List<string> results)\n\t\t{\n\t\t\t// Iterate through all of the characters in the argument string.\n\t\t\tfor (int i = 0; i < arguments.Length; i++)\n\t\t\t{\n\t\t\t\twhile (i < arguments.Length && (arguments[i] == ' ' || arguments[i] == '\\t'))\n\t\t\t\t\ti++;\n\n\t\t\t\tif (i == arguments.Length)\n\t\t\t\t\tbreak;\n\n\t\t\t\tresults.Add(GetNextArgument(arguments, ref i));\n\t\t\t}\n\t\t}\n\n\t\tprivate static string GetNextArgument(string arguments, ref int i)\n\t\t{\n\t\t\tvar currentArgument = new StringBuilder();\n\t\t\tbool inQuotes = false;\n\n\t\t\twhile (i < arguments.Length)\n\t\t\t{\n\t\t\t\t// From the current position, iterate through contiguous backslashes.\n\t\t\t\tint backslashCount = 0;\n\t\t\t\twhile (i < arguments.Length && arguments[i] == '\\\\')\n\t\t\t\t{\n\t\t\t\t\ti++;\n\t\t\t\t\tbackslashCount++;\n\t\t\t\t}\n\n\t\t\t\tif (backslashCount > 0)\n\t\t\t\t{\n\t\t\t\t\tif (i >= arguments.Length || arguments[i] != '\"')\n\t\t\t\t\t{\n\t\t\t\t\t\t// Backslashes not followed by a double quote:\n\t\t\t\t\t\t// they should all be treated as literal backslashes.\n\t\t\t\t\t\tcurrentArgument.Append('\\\\', backslashCount);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// Backslashes followed by a double quote:\n\t\t\t\t\t\t// - Output a literal slash for each complete pair of slashes\n\t\t\t\t\t\t// - If one remains, use it to make the subsequent quote a literal.\n\t\t\t\t\t\tcurrentArgument.Append('\\\\', backslashCount / 2);\n\t\t\t\t\t\tif (backslashCount % 2 != 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcurrentArgument.Append('\"');\n\t\t\t\t\t\t\ti++;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tchar c = arguments[i];\n\n\t\t\t\t// If this is a double quote, track whether we're inside of quotes or not.\n\t\t\t\t// Anything within quotes will be treated as a single argument, even if\n\t\t\t\t// it contains spaces.\n\t\t\t\tif (c == '\"')\n\t\t\t\t{\n\t\t\t\t\tif (inQuotes && i < arguments.Length - 1 && arguments[i + 1] == '\"')\n\t\t\t\t\t{\n\t\t\t\t\t\t// Two consecutive double quotes inside an inQuotes region should result in a literal double quote\n\t\t\t\t\t\t// (the parser is left in the inQuotes region).\n\t\t\t\t\t\t// This behavior is not part of the spec of code:ParseArgumentsIntoList, but is compatible with CRT\n\t\t\t\t\t\t// and .NET Framework.\n\t\t\t\t\t\tcurrentArgument.Append('\"');\n\t\t\t\t\t\ti++;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tinQuotes = !inQuotes;\n\t\t\t\t\t}\n\n\t\t\t\t\ti++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// If this is a space/tab and we're not in quotes, we're done with the current\n\t\t\t\t// argument, it should be added to the results and then reset for the next one.\n\t\t\t\tif ((c == ' ' || c == '\\t') && !inQuotes)\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// Nothing special; add the character to the current argument.\n\t\t\t\tcurrentArgument.Append(c);\n\t\t\t\ti++;\n\t\t\t}\n\n\t\t\treturn currentArgument.ToString();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/AppEnv/SingleInstance.cs",
    "content": "// Source: https://github.com/medo64/Medo/blob/main/src/Medo/Application/SingleInstance.cs\n\n/* Josip Medved <jmedved@jmedved.com> * www.medo64.com * MIT License */\n\n//2022-12-01: Compatible with .NET 6 and 7\n//2012-11-24: Suppressing bogus CA5122 warning (http://connect.microsoft.com/VisualStudio/feedback/details/729254/bogus-ca5122-warning-about-p-invoke-declarations-should-not-be-safe-critical)\n//2010-10-07: Added IsOtherInstanceRunning method\n//2008-11-14: Reworked code to use SafeHandle\n//2008-04-11: Cleaned code to match FxCop 1.36 beta 2 (SpecifyMarshalingForPInvokeStringArguments, NestedTypesShouldNotBeVisible)\n//2008-04-10: NewInstanceEventArgs is not nested class anymore\n//2008-01-26: AutoExit parameter changed to NoAutoExit\n//2008-01-08: Main method is now called Attach\n//2008-01-06: System.Environment.Exit returns E_ABORT (0x80004004)\n//2008-01-03: Added Resources\n//2007-12-29: New version\n\n#nullable enable\n\nnamespace Medo.Application;\n\nusing System;\nusing System.Diagnostics;\nusing System.IO.Pipes;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.InteropServices;\nusing System.Security.Cryptography;\nusing System.Text;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\nusing System.Threading;\n\nusing ICSharpCode.ILSpy.AppEnv;\n\n/// <summary>\n/// Handles detection and communication of programs multiple instances.\n/// This class is thread safe.\n/// </summary>\npublic static class SingleInstance\n{\n\n\tprivate static Mutex? _mtxFirstInstance;\n\tprivate static Thread? _thread;\n\tprivate static readonly object _syncRoot = new();\n\n\t/// <summary>\n\t/// Returns true if this application is not already started.\n\t/// Another instance is contacted via named pipe.\n\t/// </summary>\n\t/// <exception cref=\"InvalidOperationException\">API call failed.</exception>\n\tpublic static bool Attach()\n\t{\n\t\treturn Attach(false);\n\t}\n\n\tprivate static string[] GetILSpyCommandLineArgs()\n\t{\n\t\t// Note: NO Skip(1) here because .Args property on SingleInstanceArguments does this for us\n\t\treturn Environment.GetCommandLineArgs().AsEnumerable()\n\t\t\t.Select(CommandLineTools.FullyQualifyPath)\n\t\t\t.ToArray();\n\t}\n\n\t/// <summary>\n\t/// Returns true if this application is not already started.\n\t/// Another instance is contacted via named pipe.\n\t/// </summary>\n\t/// <param name=\"noAutoExit\">If true, application will exit after informing another instance.</param>\n\t/// <exception cref=\"InvalidOperationException\">API call failed.</exception>\n\tpublic static bool Attach(bool noAutoExit)\n\t{\n\t\tlock (_syncRoot)\n\t\t{\n\t\t\tvar isFirstInstance = false;\n\t\t\ttry\n\t\t\t{\n\t\t\t\t_mtxFirstInstance = new Mutex(initiallyOwned: true, @\"Global\\\" + MutexName, out isFirstInstance);\n\t\t\t\tif (isFirstInstance == false)\n\t\t\t\t{ //we need to contact previous instance\n\t\t\t\t\tvar contentObject = new SingleInstanceArguments() {\n\t\t\t\t\t\tCommandLine = Environment.CommandLine,\n\t\t\t\t\t\tCommandLineArgs = GetILSpyCommandLineArgs(),\n\t\t\t\t\t};\n\t\t\t\t\tvar contentBytes = JsonSerializer.SerializeToUtf8Bytes(contentObject);\n\t\t\t\t\tusing var clientPipe = new NamedPipeClientStream(\".\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t MutexName,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t PipeDirection.Out,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t PipeOptions.CurrentUserOnly | PipeOptions.WriteThrough);\n\t\t\t\t\tclientPipe.Connect();\n\t\t\t\t\tclientPipe.Write(contentBytes, 0, contentBytes.Length);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{  //there is no application already running.\n\t\t\t\t\t_thread = new Thread(Run) {\n\t\t\t\t\t\tName = typeof(SingleInstance).FullName,\n\t\t\t\t\t\tIsBackground = true\n\t\t\t\t\t};\n\t\t\t\t\t_thread.Start();\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tTrace.TraceWarning(ex.Message + \"  {Medo.Application.SingleInstance}\");\n\t\t\t}\n\n\t\t\tif ((isFirstInstance == false) && (noAutoExit == false))\n\t\t\t{\n\t\t\t\tTrace.TraceInformation(\"Exit due to another instance running.\" + \" [\" + nameof(SingleInstance) + \"]\");\n\t\t\t\tif (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))\n\t\t\t\t{\n\t\t\t\t\tEnvironment.Exit(unchecked((int)0x80004004));  // E_ABORT(0x80004004)\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tEnvironment.Exit(114);  // EALREADY(114)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn isFirstInstance;\n\t\t}\n\t}\n\n\tprivate static string? _mutexName;\n\tprivate static string MutexName {\n\t\tget {\n\t\t\tlock (_syncRoot)\n\t\t\t{\n\t\t\t\tif (_mutexName == null)\n\t\t\t\t{\n\t\t\t\t\tvar assembly = Assembly.GetEntryAssembly();\n\n\t\t\t\t\tvar sbMutextName = new StringBuilder();\n\t\t\t\t\tvar assName = assembly?.GetName().Name;\n\t\t\t\t\tif (assName != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tsbMutextName.Append(assName, 0, Math.Min(assName.Length, 31));\n\t\t\t\t\t\tsbMutextName.Append('.');\n\t\t\t\t\t}\n\n\t\t\t\t\tvar sbHash = new StringBuilder();\n\t\t\t\t\tsbHash.AppendLine(Environment.MachineName);\n\t\t\t\t\tsbHash.AppendLine(Environment.UserName);\n\t\t\t\t\tif (assembly != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tsbHash.AppendLine(assembly.FullName);\n\t\t\t\t\t\tsbHash.AppendLine(assembly.Location);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tvar args = Environment.GetCommandLineArgs();\n\t\t\t\t\t\tif (args.Length > 0)\n\t\t\t\t\t\t{ sbHash.AppendLine(args[0]); }\n\t\t\t\t\t}\n\t\t\t\t\tforeach (var b in SHA256.HashData(Encoding.UTF8.GetBytes(sbHash.ToString())))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (sbMutextName.Length == 63)\n\t\t\t\t\t\t{ sbMutextName.AppendFormat(\"{0:X1}\", b >> 4); }  // just take the first nubble\n\t\t\t\t\t\tif (sbMutextName.Length == 64)\n\t\t\t\t\t\t{ break; }\n\t\t\t\t\t\tsbMutextName.AppendFormat(\"{0:X2}\", b);\n\t\t\t\t\t}\n\t\t\t\t\t_mutexName = sbMutextName.ToString();\n\t\t\t\t}\n\t\t\t\treturn _mutexName;\n\t\t\t}\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Gets whether there is another instance running.\n\t/// It temporary creates mutex.\n\t/// </summary>\n\tpublic static bool IsOtherInstanceRunning {\n\t\tget {\n\t\t\tlock (_syncRoot)\n\t\t\t{\n\t\t\t\tif (_mtxFirstInstance != null)\n\t\t\t\t{\n\t\t\t\t\treturn false; //no other instance is running\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar tempInstance = new Mutex(true, MutexName, out var isFirstInstance);\n\t\t\t\t\ttempInstance.Close();\n\t\t\t\t\treturn (isFirstInstance == false);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Occurs in first instance when new instance is detected.\n\t/// </summary>\n\tpublic static event EventHandler<NewInstanceEventArgs>? NewInstanceDetected;\n\n\t/// <summary>\n\t/// Thread function.\n\t/// </summary>\n\tprivate static void Run()\n\t{\n\t\tusing var serverPipe = new NamedPipeServerStream(MutexName,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t PipeDirection.In,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t maxNumberOfServerInstances: 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t PipeTransmissionMode.Byte,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t PipeOptions.CurrentUserOnly | PipeOptions.WriteThrough);\n\t\twhile (_mtxFirstInstance != null)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (!serverPipe.IsConnected)\n\t\t\t\t{ serverPipe.WaitForConnection(); }\n\t\t\t\tvar contentObject = JsonSerializer.Deserialize<SingleInstanceArguments>(serverPipe);\n\t\t\t\tserverPipe.Disconnect();\n\t\t\t\tif (contentObject != null)\n\t\t\t\t{\n\t\t\t\t\tNewInstanceDetected?.Invoke(null,\n\t\t\t\t\t\t\t\t\t\t\t\tnew NewInstanceEventArgs(\n\t\t\t\t\t\t\t\t\t\t\t\t\tcontentObject.CommandLine,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcontentObject.CommandLineArgs));\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tTrace.TraceWarning(ex.Message + \" [\" + nameof(SingleInstance) + \"]\");\n\t\t\t\tThread.Sleep(100);\n\t\t\t}\n\t\t}\n\t}\n\n\t[Serializable]\n\tprivate sealed record SingleInstanceArguments\n\t{  // just a storage\n\t\t[JsonInclude]\n\t\tpublic required string CommandLine;\n\n\t\t[JsonInclude]\n\t\tpublic required string[] CommandLineArgs;\n\t}\n\n}\n\n/// <summary>\n/// Arguments for newly detected application instance.\n/// </summary>\npublic sealed class NewInstanceEventArgs : EventArgs\n{\n\t/// <summary>\n\t/// Creates new instance.\n\t/// </summary>\n\t/// <param name=\"commandLine\">Command line.</param>\n\t/// <param name=\"commandLineArgs\">String array containing the command line arguments in the same format as Environment.GetCommandLineArgs.</param>\n\tinternal NewInstanceEventArgs(string commandLine, string[] commandLineArgs)\n\t{\n\t\tCommandLine = commandLine;\n\t\t_commandLineArgs = new string[commandLineArgs.Length];\n\t\tArray.Copy(commandLineArgs, _commandLineArgs, _commandLineArgs.Length);\n\t}\n\n\t/// <summary>\n\t/// Gets the command line.\n\t/// </summary>\n\tpublic string CommandLine { get; }\n\n\tprivate readonly string[] _commandLineArgs;\n\t/// <summary>\n\t/// Returns a string array containing the command line arguments.\n\t/// </summary>\n\tpublic string[] GetCommandLineArgs()\n\t{\n\t\tvar argCopy = new string[_commandLineArgs.Length];\n\t\tArray.Copy(_commandLineArgs, argCopy, argCopy.Length);\n\t\treturn argCopy;\n\t}\n\n\t/// <summary>\n\t/// Gets a string array containing the command line arguments without the name of exectuable.\n\t/// </summary>\n\tpublic string[] Args {\n\t\tget {\n\t\t\tvar argCopy = new string[_commandLineArgs.Length - 1];\n\t\t\tArray.Copy(_commandLineArgs, 1, argCopy, 0, argCopy.Length);\n\t\t\treturn argCopy;\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "ILSpy/AssemblyTree/AssemblyListPane.xaml",
    "content": "<treeView:SharpTreeView x:Class=\"ICSharpCode.ILSpy.AssemblyTree.AssemblyListPane\"\n\t\t\t\t\t\txmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n\t\t\t\t\t\txmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n\t\t\t\t\t\txmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n\t\t\t\t\t\txmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n\t\t\t\t\t\txmlns:treeView=\"clr-namespace:ICSharpCode.ILSpy.Controls.TreeView\"\n\t\t\t\t\t\txmlns:treeNodes=\"clr-namespace:ICSharpCode.ILSpy.TreeNodes\"\n\t\t\t\t\t\txmlns:assemblyTree=\"clr-namespace:ICSharpCode.ILSpy.AssemblyTree\"\n\t\t\t\t\t\txmlns:toms=\"urn:TomsToolbox\"\n\t\t\t\t\t\txmlns:viewModels=\"clr-namespace:ICSharpCode.ILSpy.ViewModels\"\n\t\t\t\t\t\tmc:Ignorable=\"d\" d:DesignHeight=\"450\" d:DesignWidth=\"800\"\n\t\t\t\t\t\td:DataContext=\"{d:DesignInstance assemblyTree:AssemblyTreeModel}\"\n\t\t\t\t\t\tAutomationProperties.Name=\"Assemblies and Classes\"\n\t\t\t\t\t\tShowRoot=\"False\"\n\t\t\t\t\t\tAllowDropOrder=\"True\"\n\t\t\t\t\t\tAllowDrop=\"True\"\n\t\t\t\t\t\tBorderThickness=\"0\" Visibility=\"Visible\"\n\t\t\t\t\t\tRoot=\"{Binding Root}\"\n\t\t\t\t\t\ttoms:MultiSelectorExtensions.SelectionBinding=\"{Binding SelectedItems, Mode=TwoWay}\"\n\t\t\t\t\t\tviewModels:Pane.IsActive=\"{Binding IsActive}\">\n\t<treeView:SharpTreeView.ItemContainerStyle>\n\t\t<Style TargetType=\"treeView:SharpTreeViewItem\">\n\t\t\t<Setter Property=\"Template\">\n\t\t\t\t<Setter.Value>\n\t\t\t\t\t<ControlTemplate TargetType=\"{x:Type treeView:SharpTreeViewItem}\"\n\t\t\t\t\t\t\t\t\t d:DataContext=\"{d:DesignInstance treeNodes:ILSpyTreeNode}\">\n\t\t\t\t\t\t<Border Background=\"Transparent\">\n\t\t\t\t\t\t\t<Border Background=\"{TemplateBinding Background}\">\n\t\t\t\t\t\t\t\t<treeView:SharpTreeNodeView x:Name=\"nodeView\" HorizontalAlignment=\"Left\" />\n\t\t\t\t\t\t\t</Border>\n\t\t\t\t\t\t</Border>\n\t\t\t\t\t\t<ControlTemplate.Triggers>\n\t\t\t\t\t\t\t<DataTrigger Binding=\"{Binding IsAutoLoaded}\" Value=\"True\">\n\t\t\t\t\t\t\t\t<Setter Property=\"Foreground\" Value=\"SteelBlue\" />\n\t\t\t\t\t\t\t</DataTrigger>\n\t\t\t\t\t\t\t<DataTrigger Binding=\"{Binding IsPublicAPI}\" Value=\"False\">\n\t\t\t\t\t\t\t\t<Setter Property=\"Foreground\" Value=\"{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}\" />\n\t\t\t\t\t\t\t</DataTrigger>\n\t\t\t\t\t\t\t<Trigger Property=\"IsSelected\" Value=\"True\">\n\t\t\t\t\t\t\t\t<Setter TargetName=\"nodeView\" Property=\"TextBackground\"\n\t\t\t\t\t\t\t\t\t\tValue=\"{DynamicResource {x:Static SystemColors.HighlightBrushKey}}\" />\n\t\t\t\t\t\t\t\t<Setter TargetName=\"nodeView\" Property=\"Foreground\"\n\t\t\t\t\t\t\t\t\t\tValue=\"{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}\" />\n\t\t\t\t\t\t\t</Trigger>\n\t\t\t\t\t\t\t<Trigger Property=\"IsEnabled\" Value=\"False\">\n\t\t\t\t\t\t\t\t<Setter TargetName=\"nodeView\" Property=\"Foreground\"\n\t\t\t\t\t\t\t\t\t\tValue=\"{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}\" />\n\t\t\t\t\t\t\t</Trigger>\n\t\t\t\t\t\t</ControlTemplate.Triggers>\n\t\t\t\t\t</ControlTemplate>\n\t\t\t\t</Setter.Value>\n\t\t\t</Setter>\n\t\t</Style>\n\t</treeView:SharpTreeView.ItemContainerStyle>\n</treeView:SharpTreeView>"
  },
  {
    "path": "ILSpy/AssemblyTree/AssemblyListPane.xaml.cs",
    "content": "// Copyright (c) 2024 Tom Englert for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Windows;\nusing System.Windows.Threading;\n\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX.TreeView;\n\nusing TomsToolbox.Wpf;\nusing TomsToolbox.Wpf.Composition.AttributedModel;\n\nnamespace ICSharpCode.ILSpy.AssemblyTree\n{\n\t/// <summary>\n\t/// Interaction logic for AssemblyListPane.xaml\n\t/// </summary>\n\t[DataTemplate(typeof(AssemblyTreeModel))]\n\t[NonShared]\n\tpublic partial class AssemblyListPane\n\t{\n\t\tpublic AssemblyListPane()\n\t\t{\n\t\t\tInitializeComponent();\n\n\t\t\tContextMenuProvider.Add(this);\n\t\t}\n\n\t\tprotected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)\n\t\t{\n\t\t\tbase.OnPropertyChanged(e);\n\n\t\t\tif (e.Property == DataContextProperty)\n\t\t\t{\n\t\t\t\tif (e.NewValue is not AssemblyTreeModel model)\n\t\t\t\t\treturn;\n\n\t\t\t\tmodel.SetActiveView(this);\n\n\t\t\t\t// If there is already a selected item in the model, we need to scroll it into view, so it can be selected in the UI.\n\t\t\t\tvar selected = model.SelectedItem;\n\t\t\t\tif (selected != null)\n\t\t\t\t{\n\t\t\t\t\tthis.BeginInvoke(DispatcherPriority.Background, () => {\n\t\t\t\t\t\tScrollIntoView(selected);\n\t\t\t\t\t\tthis.SelectedItem = selected;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (e.Property == Pane.IsActiveProperty)\n\t\t\t{\n\t\t\t\tif (!true.Equals(e.NewValue))\n\t\t\t\t\treturn;\n\n\t\t\t\tif (SelectedItem is SharpTreeNode selectedItem)\n\t\t\t\t{\n\t\t\t\t\t// defer focusing, so it does not interfere with selection via mouse click\n\t\t\t\t\tthis.BeginInvoke(() => {\n\t\t\t\t\t\tif (this.SelectedItem == selectedItem)\n\t\t\t\t\t\t\tFocusNode(selectedItem);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tFocus();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/AssemblyTree/AssemblyTreeModel.cs",
    "content": "// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.ComponentModel;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Documents;\nusing System.Windows.Input;\nusing System.Windows.Navigation;\nusing System.Windows.Threading;\n\nusing ICSharpCode.Decompiler.Documentation;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.ILSpy.AppEnv;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.Updates;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.TreeView;\n\nusing TomsToolbox.Composition;\nusing TomsToolbox.Essentials;\nusing TomsToolbox.Wpf;\n\n#nullable enable\n\nnamespace ICSharpCode.ILSpy.AssemblyTree\n{\n\t[ExportToolPane]\n\t[Shared]\n\tpublic class AssemblyTreeModel : ToolPaneModel\n\t{\n\t\tpublic const string PaneContentId = \"assemblyListPane\";\n\n\t\tprivate AssemblyListPane? activeView;\n\t\tprivate AssemblyListTreeNode? assemblyListTreeNode;\n\t\tprivate readonly DispatcherThrottle refreshThrottle;\n\n\t\tprivate readonly NavigationHistory<NavigationState> history = new();\n\t\tprivate NavigationState? navigatingToState;\n\t\tprivate object? sourceOfReference;\n\t\tprivate readonly SettingsService settingsService;\n\t\tprivate readonly LanguageService languageService;\n\t\tprivate readonly IExportProvider exportProvider;\n\n\t\tprivate static Dispatcher UIThreadDispatcher => Application.Current.Dispatcher;\n\n\t\tpublic AssemblyTreeModel(SettingsService settingsService, LanguageService languageService, IExportProvider exportProvider)\n\t\t{\n\t\t\tthis.settingsService = settingsService;\n\t\t\tthis.languageService = languageService;\n\t\t\tthis.exportProvider = exportProvider;\n\n\t\t\tTitle = Resources.Assemblies;\n\t\t\tContentId = PaneContentId;\n\t\t\tIsCloseable = false;\n\t\t\tShortcutKey = new KeyGesture(Key.F6);\n\n\t\t\tMessageBus<NavigateToReferenceEventArgs>.Subscribers += JumpToReference;\n\t\t\tMessageBus<SettingsChangedEventArgs>.Subscribers += (sender, e) => Settings_PropertyChanged(sender, e);\n\t\t\tMessageBus<ApplySessionSettingsEventArgs>.Subscribers += ApplySessionSettings;\n\t\t\tMessageBus<ActiveTabPageChangedEventArgs>.Subscribers += ActiveTabPageChanged;\n\t\t\tMessageBus<TabPagesCollectionChangedEventArgs>.Subscribers += (_, e) => history.RemoveAll(s => !DockWorkspace.TabPages.Contains(s.TabPage));\n\t\t\tMessageBus<ResetLayoutEventArgs>.Subscribers += ResetLayout;\n\t\t\tMessageBus<NavigateToEventArgs>.Subscribers += (_, e) => NavigateTo(e.Request, e.InNewTabPage);\n\t\t\tMessageBus<MainWindowLoadedEventArgs>.Subscribers += (_, _) => {\n\t\t\t\tInitialize();\n\t\t\t\tShow();\n\t\t\t};\n\n\t\t\tEventManager.RegisterClassHandler(typeof(Window), Hyperlink.RequestNavigateEvent, new RequestNavigateEventHandler((_, e) => NavigateTo(e)));\n\n\t\t\trefreshThrottle = new(DispatcherPriority.Background, RefreshInternal);\n\n\t\t\tAssemblyList = settingsService.CreateEmptyAssemblyList();\n\t\t}\n\n\t\tprivate void Settings_PropertyChanged(object? sender, PropertyChangedEventArgs e)\n\t\t{\n\t\t\tif (sender is SessionSettings sessionSettings)\n\t\t\t{\n\t\t\t\tswitch (e.PropertyName)\n\t\t\t\t{\n\t\t\t\t\tcase nameof(SessionSettings.ActiveAssemblyList):\n\t\t\t\t\t\tShowAssemblyList(sessionSettings.ActiveAssemblyList);\n\t\t\t\t\t\tRefreshDecompiledView();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase nameof(SessionSettings.Theme):\n\t\t\t\t\t\t// update syntax highlighting and force reload (AvalonEdit does not automatically refresh on highlighting change)\n\t\t\t\t\t\tDecompilerTextView.RegisterHighlighting();\n\t\t\t\t\t\tRefreshDecompiledView();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase nameof(SessionSettings.CurrentCulture):\n\t\t\t\t\t\tMessageBox.Show(Resources.SettingsChangeRestartRequired, \"ILSpy\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (sender is LanguageSettings)\n\t\t\t{\n\t\t\t\tswitch (e.PropertyName)\n\t\t\t\t{\n\t\t\t\t\tcase nameof(LanguageSettings.LanguageId) or nameof(LanguageSettings.LanguageVersionId):\n\t\t\t\t\t\tRefreshDecompiledView();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tRefresh();\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic AssemblyList AssemblyList { get; private set; }\n\n\t\tprivate SharpTreeNode? root;\n\t\tpublic SharpTreeNode? Root {\n\t\t\tget => root;\n\t\t\tset => SetProperty(ref root, value);\n\t\t}\n\n\t\tpublic SharpTreeNode? SelectedItem {\n\t\t\tget => SelectedItems.FirstOrDefault();\n\t\t\tset => SelectedItems = value is null ? [] : [value];\n\t\t}\n\n\t\tprivate SharpTreeNode[] selectedItems = [];\n\t\tpublic SharpTreeNode[] SelectedItems {\n\t\t\tget => selectedItems;\n\t\t\tset {\n\t\t\t\tif (selectedItems.SequenceEqual(value))\n\t\t\t\t\treturn;\n\n\t\t\t\tvar oldSelection = selectedItems;\n\t\t\t\tselectedItems = value;\n\t\t\t\tOnPropertyChanged();\n\t\t\t\tTreeView_SelectionChanged(oldSelection, selectedItems);\n\t\t\t}\n\t\t}\n\n\t\tpublic string[]? SelectedPath => GetPathForNode(SelectedItem);\n\n\t\tprivate readonly List<LoadedAssembly> commandLineLoadedAssemblies = [];\n\n\t\tprivate bool HandleCommandLineArguments(CommandLineArguments args)\n\t\t{\n\t\t\tLoadAssemblies(args.AssembliesToLoad, commandLineLoadedAssemblies, focusNode: false);\n\t\t\tif (args.Language != null)\n\t\t\t\tlanguageService.Language = languageService.GetLanguage(args.Language);\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Called on startup or when passed arguments via WndProc from a second instance.\n\t\t/// In the format case, updateSettings is non-null; in the latter it is null.\n\t\t/// </summary>\n\t\tprivate async Task HandleCommandLineArgumentsAfterShowList(CommandLineArguments args, UpdateSettings? updateSettings = null)\n\t\t{\n\t\t\tvar sessionSettings = settingsService.SessionSettings;\n\n\t\t\tvar relevantAssemblies = commandLineLoadedAssemblies.ToList();\n\t\t\tcommandLineLoadedAssemblies.Clear(); // clear references once we don't need them anymore\n\n\t\t\tawait NavigateOnLaunch(args.NavigateTo, sessionSettings.ActiveTreeViewPath, updateSettings, relevantAssemblies);\n\n\t\t\tif (args.Search != null)\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new ShowSearchPageEventArgs(args.Search));\n\t\t\t}\n\t\t}\n\n\t\tpublic async Task HandleSingleInstanceCommandLineArguments(string[] args)\n\t\t{\n\t\t\tvar cmdArgs = CommandLineArguments.Create(args);\n\n\t\t\tawait UIThreadDispatcher.InvokeAsync(async () => {\n\n\t\t\t\tif (!HandleCommandLineArguments(cmdArgs))\n\t\t\t\t\treturn;\n\n\t\t\t\tvar window = Application.Current.MainWindow;\n\n\t\t\t\tif (!cmdArgs.NoActivate && window is { WindowState: WindowState.Minimized })\n\t\t\t\t{\n\t\t\t\t\twindow.WindowState = WindowState.Normal;\n\t\t\t\t}\n\n\t\t\t\tawait HandleCommandLineArgumentsAfterShowList(cmdArgs);\n\t\t\t});\n\t\t}\n\n\t\tprivate async Task NavigateOnLaunch(string? navigateTo, string[]? activeTreeViewPath, UpdateSettings? updateSettings, List<LoadedAssembly> relevantAssemblies)\n\t\t{\n\t\t\tvar initialSelection = SelectedItem;\n\t\t\tif (navigateTo != null)\n\t\t\t{\n\t\t\t\tbool found = false;\n\t\t\t\tif (navigateTo.StartsWith(\"N:\", StringComparison.Ordinal))\n\t\t\t\t{\n\t\t\t\t\tstring namespaceName = navigateTo.Substring(2);\n\t\t\t\t\tforeach (LoadedAssembly asm in relevantAssemblies)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar asmNode = assemblyListTreeNode?.FindAssemblyNode(asm);\n\t\t\t\t\t\tif (asmNode != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// FindNamespaceNode() blocks the UI if the assembly is not yet loaded,\n\t\t\t\t\t\t\t// so use an async wait instead.\n\t\t\t\t\t\t\tawait asm.GetMetadataFileAsync().Catch<Exception>(_ => { });\n\t\t\t\t\t\t\tNamespaceTreeNode nsNode = asmNode.FindNamespaceNode(namespaceName);\n\t\t\t\t\t\t\tif (nsNode != null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\t\t\tif (SelectedItem == initialSelection)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tSelectNode(nsNode);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (navigateTo == \"none\")\n\t\t\t\t{\n\t\t\t\t\t// Don't navigate anywhere; start empty.\n\t\t\t\t\t// Used by ILSpy VS addin, it'll send us the real location to navigate to via IPC.\n\t\t\t\t\tfound = true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tIEntity? mr = await Task.Run(() => FindEntityInRelevantAssemblies(navigateTo, relevantAssemblies));\n\n\t\t\t\t\t// Make sure we wait for assemblies being loaded...\n\t\t\t\t\t// BeginInvoke in LoadedAssembly.LookupReferencedAssemblyInternal\n\t\t\t\t\tawait UIThreadDispatcher.InvokeAsync(delegate { }, DispatcherPriority.Normal);\n\n\t\t\t\t\tif (mr is { ParentModule.MetadataFile: not null })\n\t\t\t\t\t{\n\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\tif (SelectedItem == initialSelection)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tawait JumpToReferenceAsync(mr, null);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!found && SelectedItem == initialSelection)\n\t\t\t\t{\n\t\t\t\t\tAvalonEditTextOutput output = new AvalonEditTextOutput();\n\t\t\t\t\toutput.Write($\"Cannot find '{navigateTo}' in command line specified assemblies.\");\n\t\t\t\t\tDockWorkspace.ShowText(output);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (relevantAssemblies.Count == 1)\n\t\t\t{\n\t\t\t\t// NavigateTo == null and an assembly was given on the command-line:\n\t\t\t\t// Select the newly loaded assembly\n\t\t\t\tvar asmNode = assemblyListTreeNode?.FindAssemblyNode(relevantAssemblies[0]);\n\t\t\t\tif (asmNode != null && SelectedItem == initialSelection)\n\t\t\t\t{\n\t\t\t\t\tSelectNode(asmNode);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (updateSettings != null)\n\t\t\t{\n\t\t\t\tSharpTreeNode? node = null;\n\t\t\t\tif (activeTreeViewPath?.Length > 0)\n\t\t\t\t{\n\t\t\t\t\tforeach (var asm in AssemblyList.GetAssemblies())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (asm.FileName == activeTreeViewPath[0])\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// FindNodeByPath() blocks the UI if the assembly is not yet loaded,\n\t\t\t\t\t\t\t// so use an async wait instead.\n\t\t\t\t\t\t\tawait asm.GetMetadataFileAsync().Catch<Exception>(_ => { });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tnode = FindNodeByPath(activeTreeViewPath, true);\n\t\t\t\t}\n\t\t\t\tif (SelectedItem == initialSelection)\n\t\t\t\t{\n\t\t\t\t\tif (node != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tSelectNode(node);\n\n\t\t\t\t\t\t// only if not showing the about page, perform the update check:\n\t\t\t\t\t\tMessageBus.Send(this, new CheckIfUpdateAvailableEventArgs());\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tMessageBus.Send(this, new ShowAboutPageEventArgs(DockWorkspace.ActiveTabPage));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEntity? FindEntityInRelevantAssemblies(string navigateTo, IEnumerable<LoadedAssembly> relevantAssemblies)\n\t\t{\n\t\t\tITypeReference typeRef;\n\t\t\tIMemberReference? memberRef = null;\n\t\t\tif (navigateTo.StartsWith(\"T:\", StringComparison.Ordinal))\n\t\t\t{\n\t\t\t\ttypeRef = IdStringProvider.ParseTypeName(navigateTo);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tmemberRef = IdStringProvider.ParseMemberIdString(navigateTo);\n\t\t\t\ttypeRef = memberRef.DeclaringTypeReference;\n\t\t\t}\n\t\t\tforeach (LoadedAssembly asm in relevantAssemblies.ToList())\n\t\t\t{\n\t\t\t\tvar module = asm.GetMetadataFileOrNull();\n\t\t\t\tif (module != null && CanResolveTypeInPEFile(module, typeRef, out var typeHandle))\n\t\t\t\t{\n\t\t\t\t\tICompilation compilation = typeHandle.Kind == HandleKind.ExportedType\n\t\t\t\t\t\t? new DecompilerTypeSystem(module, module.GetAssemblyResolver())\n\t\t\t\t\t\t: new SimpleCompilation((PEFile)module, MinimalCorlib.Instance);\n\t\t\t\t\treturn memberRef == null\n\t\t\t\t\t\t? typeRef.Resolve(new SimpleTypeResolveContext(compilation)) as ITypeDefinition\n\t\t\t\t\t\t: memberRef.Resolve(new SimpleTypeResolveContext(compilation));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tprivate static bool CanResolveTypeInPEFile(MetadataFile module, ITypeReference typeRef, out EntityHandle typeHandle)\n\t\t{\n\t\t\t// We intentionally ignore reference assemblies, so that the loop continues looking for another assembly that might have a usable definition.\n\t\t\tif (module.IsReferenceAssembly())\n\t\t\t{\n\t\t\t\ttypeHandle = default;\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tswitch (typeRef)\n\t\t\t{\n\t\t\t\tcase GetPotentiallyNestedClassTypeReference topLevelType:\n\t\t\t\t\ttypeHandle = topLevelType.ResolveInPEFile(module);\n\t\t\t\t\treturn !typeHandle.IsNil;\n\t\t\t\tcase NestedTypeReference nestedType:\n\t\t\t\t\tif (!CanResolveTypeInPEFile(module, nestedType.DeclaringTypeReference, out typeHandle))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (typeHandle.Kind == HandleKind.ExportedType)\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tvar typeDef = module.Metadata.GetTypeDefinition((TypeDefinitionHandle)typeHandle);\n\t\t\t\t\ttypeHandle = typeDef.GetNestedTypes().FirstOrDefault(t => {\n\t\t\t\t\t\tvar td = module.Metadata.GetTypeDefinition(t);\n\t\t\t\t\t\tvar typeName = ReflectionHelper.SplitTypeParameterCountFromReflectionName(module.Metadata.GetString(td.Name), out int typeParameterCount);\n\t\t\t\t\t\treturn nestedType.AdditionalTypeParameterCount == typeParameterCount && nestedType.Name == typeName;\n\t\t\t\t\t});\n\t\t\t\t\treturn !typeHandle.IsNil;\n\t\t\t\tdefault:\n\t\t\t\t\ttypeHandle = default;\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic void Initialize()\n\t\t{\n\t\t\tAssemblyList = settingsService.LoadInitialAssemblyList();\n\n\t\t\tHandleCommandLineArguments(App.CommandLineArguments);\n\n\t\t\tvar loadPreviousAssemblies = settingsService.MiscSettings.LoadPreviousAssemblies;\n\t\t\tif (AssemblyList.GetAssemblies().Length == 0\n\t\t\t\t&& AssemblyList.ListName == AssemblyListManager.DefaultListName\n\t\t\t\t&& loadPreviousAssemblies)\n\t\t\t{\n\t\t\t\tLoadInitialAssemblies(AssemblyList);\n\t\t\t}\n\n\t\t\tShowAssemblyList(AssemblyList);\n\n\t\t\tvar sessionSettings = settingsService.SessionSettings;\n\t\t\tif (sessionSettings.ActiveAutoLoadedAssembly != null\n\t\t\t\t&& File.Exists(sessionSettings.ActiveAutoLoadedAssembly))\n\t\t\t{\n\t\t\t\tAssemblyList.Open(sessionSettings.ActiveAutoLoadedAssembly, true);\n\t\t\t}\n\n\t\t\tUIThreadDispatcher.BeginInvoke(DispatcherPriority.Loaded, OpenAssemblies);\n\t\t}\n\n\t\tprivate async Task OpenAssemblies()\n\t\t{\n\t\t\tawait HandleCommandLineArgumentsAfterShowList(App.CommandLineArguments, settingsService.GetSettings<UpdateSettings>());\n\n\t\t\tif (FormatExceptions(App.StartupExceptions.ToArray(), out var output))\n\t\t\t{\n\t\t\t\toutput.Title = \"Startup errors\";\n\n\t\t\t\tDockWorkspace.AddTabPage();\n\t\t\t\tDockWorkspace.ShowText(output);\n\t\t\t}\n\t\t}\n\n\t\tprivate static bool FormatExceptions(App.ExceptionData[] exceptions, [NotNullWhen(true)] out AvalonEditTextOutput? output)\n\t\t{\n\t\t\toutput = null;\n\n\t\t\tvar result = exceptions.FormatExceptions();\n\t\t\tif (result.IsNullOrEmpty())\n\t\t\t\treturn false;\n\n\t\t\toutput = new();\n\t\t\toutput.Write(result);\n\t\t\treturn true;\n\n\t\t}\n\n\t\tprivate void ShowAssemblyList(string name)\n\t\t{\n\t\t\tAssemblyList list = settingsService.AssemblyListManager.LoadList(name);\n\t\t\t//Only load a new list when it is a different one\n\t\t\tif (list.ListName != AssemblyList.ListName)\n\t\t\t{\n\t\t\t\tShowAssemblyList(list);\n\t\t\t\tSelectNode(Root?.Children.FirstOrDefault());\n\t\t\t}\n\t\t}\n\n\t\tprivate void ShowAssemblyList(AssemblyList assemblyList)\n\t\t{\n\t\t\thistory.Clear();\n\n\t\t\tAssemblyList.CollectionChanged -= assemblyList_CollectionChanged;\n\t\t\tAssemblyList = assemblyList;\n\t\t\tassemblyList.CollectionChanged += assemblyList_CollectionChanged;\n\n\t\t\tassemblyListTreeNode = new(assemblyList) {\n\t\t\t\tSelect = x => SelectNode(x)\n\t\t\t};\n\n\t\t\tRoot = assemblyListTreeNode;\n\n\t\t\tvar mainWindow = Application.Current?.MainWindow;\n\n\t\t\tif (mainWindow == null)\n\t\t\t\treturn;\n\n\t\t\tif (assemblyList.ListName == AssemblyListManager.DefaultListName)\n#if DEBUG\n\t\t\t\tmainWindow.Title = $\"ILSpy {DecompilerVersionInfo.FullVersion}\";\n#else\n\t\t\t\tmainWindow.Title = \"ILSpy\";\n#endif\n\t\t\telse\n#if DEBUG\n\t\t\t\tmainWindow.Title = string.Format(settingsService.MiscSettings.AllowMultipleInstances ? \"{1} - {0}\" : \"{0} - {1}\", $\"ILSpy {DecompilerVersionInfo.FullVersion}\", assemblyList.ListName);\n#else\n\t\t\t\tmainWindow.Title = string.Format(settingsService.MiscSettings.AllowMultipleInstances ? \"{1} - {0}\" : \"{0} - {1}\", \"ILSpy\", assemblyList.ListName);\n#endif\n\t\t}\n\n\t\tprivate void assemblyList_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)\n\t\t{\n\t\t\tif (e.Action == NotifyCollectionChangedAction.Reset)\n\t\t\t{\n\t\t\t\thistory.RemoveAll(_ => true);\n\t\t\t}\n\t\t\tif (e.OldItems != null)\n\t\t\t{\n\t\t\t\tvar oldAssemblies = new HashSet<LoadedAssembly>(e.OldItems.Cast<LoadedAssembly>());\n\t\t\t\thistory.RemoveAll(n => n.TreeNodes.Any(\n\t\t\t\t\tnd => nd.AncestorsAndSelf().OfType<AssemblyTreeNode>().Any(\n\t\t\t\t\t\ta => oldAssemblies.Contains(a.LoadedAssembly))));\n\t\t\t}\n\n\t\t\tMessageBus.Send(this, new CurrentAssemblyListChangedEventArgs(e));\n\t\t}\n\n\t\tprivate static void LoadInitialAssemblies(AssemblyList assemblyList)\n\t\t{\n\t\t\t// Called when loading an empty assembly list; so that\n\t\t\t// the user can see something initially.\n\t\t\tSystem.Reflection.Assembly[] initialAssemblies = {\n\t\t\t\ttypeof(object).Assembly,\n\t\t\t\ttypeof(Uri).Assembly,\n\t\t\t\ttypeof(System.Linq.Enumerable).Assembly,\n\t\t\t\ttypeof(System.Xml.XmlDocument).Assembly,\n\t\t\t\ttypeof(System.Windows.Markup.MarkupExtension).Assembly,\n\t\t\t\ttypeof(System.Windows.Rect).Assembly,\n\t\t\t\ttypeof(System.Windows.UIElement).Assembly,\n\t\t\t\ttypeof(System.Windows.FrameworkElement).Assembly\n\t\t\t};\n\t\t\tforeach (System.Reflection.Assembly asm in initialAssemblies)\n\t\t\t\tassemblyList.OpenAssembly(asm.Location);\n\t\t}\n\n\t\tpublic AssemblyTreeNode? FindAssemblyNode(LoadedAssembly asm)\n\t\t{\n\t\t\treturn assemblyListTreeNode?.FindAssemblyNode(asm);\n\t\t}\n\n\t\t#region Node Selection\n\n\t\tpublic void SelectNode(SharpTreeNode? node, bool inNewTabPage = false)\n\t\t{\n\t\t\tif (node == null)\n\t\t\t\treturn;\n\n\t\t\tif (node.AncestorsAndSelf().Any(item => item.IsHidden))\n\t\t\t{\n\t\t\t\tMessageBox.Show(Resources.NavigationFailed, \"ILSpy\", MessageBoxButton.OK, MessageBoxImage.Exclamation);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (inNewTabPage)\n\t\t\t{\n\t\t\t\tDockWorkspace.AddTabPage();\n\t\t\t\tSelectedItem = null;\n\t\t\t}\n\n\t\t\tif (SelectedItem == node)\n\t\t\t{\n\t\t\t\tUIThreadDispatcher.BeginInvoke(RefreshDecompiledView);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tactiveView?.ScrollIntoView(node);\n\t\t\t\tSelectedItem = node;\n\n\t\t\t\tUIThreadDispatcher.BeginInvoke(DispatcherPriority.Background, () => {\n\t\t\t\t\tactiveView?.ScrollIntoView(node);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tpublic void SelectNodes(IEnumerable<SharpTreeNode> nodes)\n\t\t{\n\t\t\t// Ensure nodes exist\n\t\t\tvar nodesList = nodes.Select(n => FindNodeByPath(GetPathForNode(n), true))\n\t\t\t\t.ExceptNullItems()\n\t\t\t\t.ToArray();\n\n\t\t\tif (!nodesList.Any() || nodesList.Any(n => n.AncestorsAndSelf().Any(a => a.IsHidden)))\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tforeach (var node in nodesList)\n\t\t\t{\n\t\t\t\tactiveView?.ScrollIntoView(node);\n\t\t\t}\n\n\t\t\tSelectedItems = nodesList.ToArray();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Retrieves a node using the .ToString() representations of its ancestors.\n\t\t/// </summary>\n\t\tpublic SharpTreeNode? FindNodeByPath(string[]? path, bool returnBestMatch)\n\t\t{\n\t\t\tif (path == null)\n\t\t\t\treturn null;\n\t\t\tvar node = Root;\n\t\t\tvar bestMatch = node;\n\t\t\tforeach (var element in path)\n\t\t\t{\n\t\t\t\tif (node == null)\n\t\t\t\t\tbreak;\n\t\t\t\tbestMatch = node;\n\t\t\t\tnode.EnsureLazyChildren();\n\t\t\t\tif (node is ILSpyTreeNode ilSpyTreeNode)\n\t\t\t\t\tilSpyTreeNode.EnsureChildrenFiltered();\n\t\t\t\tnode = node.Children.FirstOrDefault(c => c.ToString() == element);\n\t\t\t}\n\n\t\t\treturn returnBestMatch ? node ?? bestMatch : node;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the .ToString() representation of the node's ancestors.\n\t\t/// </summary>\n\t\tpublic static string[]? GetPathForNode(SharpTreeNode? node)\n\t\t{\n\t\t\tif (node == null)\n\t\t\t\treturn null;\n\t\t\tList<string> path = new List<string>();\n\t\t\twhile (node.Parent != null)\n\t\t\t{\n\t\t\t\tpath.Add(node.ToString()!);\n\t\t\t\tnode = node.Parent;\n\t\t\t}\n\t\t\tpath.Reverse();\n\t\t\treturn path.ToArray();\n\t\t}\n\n\t\tpublic ILSpyTreeNode? FindTreeNode(object? reference)\n\t\t{\n\t\t\tif (assemblyListTreeNode == null)\n\t\t\t\treturn null;\n\n\t\t\tswitch (reference)\n\t\t\t{\n\t\t\t\tcase LoadedAssembly lasm:\n\t\t\t\t\treturn assemblyListTreeNode.FindAssemblyNode(lasm);\n\t\t\t\tcase MetadataFile asm:\n\t\t\t\t\treturn assemblyListTreeNode.FindAssemblyNode(asm);\n\t\t\t\tcase Resource res:\n\t\t\t\t\treturn assemblyListTreeNode.FindResourceNode(res);\n\t\t\t\tcase ValueTuple<Resource, string> resName:\n\t\t\t\t\treturn assemblyListTreeNode.FindResourceNode(resName.Item1, resName.Item2);\n\t\t\t\tcase ITypeDefinition type:\n\t\t\t\t\treturn assemblyListTreeNode.FindTypeNode(type);\n\t\t\t\tcase IField fd:\n\t\t\t\t\treturn assemblyListTreeNode.FindFieldNode(fd);\n\t\t\t\tcase IMethod md:\n\t\t\t\t\treturn assemblyListTreeNode.FindMethodNode(md);\n\t\t\t\tcase IProperty pd:\n\t\t\t\t\treturn assemblyListTreeNode.FindPropertyNode(pd);\n\t\t\t\tcase IEvent ed:\n\t\t\t\t\treturn assemblyListTreeNode.FindEventNode(ed);\n\t\t\t\tcase INamespace nd:\n\t\t\t\t\treturn assemblyListTreeNode.FindNamespaceNode(nd);\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tprivate void JumpToReference(object? sender, NavigateToReferenceEventArgs e)\n\t\t{\n\t\t\tJumpToReferenceAsync(e.Reference, e.Source, e.InNewTabPage).HandleExceptions();\n\t\t\tIsActive = true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Jumps to the specified reference.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// Returns a task that will signal completion when the decompilation of the jump target has finished.\n\t\t/// The task will be marked as canceled if the decompilation is canceled.\n\t\t/// </returns>\n\t\tprivate Task JumpToReferenceAsync(object? reference, object? source, bool inNewTabPage = false)\n\t\t{\n\t\t\tthis.sourceOfReference = source;\n\t\t\tvar decompilationTask = Task.CompletedTask;\n\n\t\t\tswitch (reference)\n\t\t\t{\n\t\t\t\tcase Decompiler.Disassembler.OpCodeInfo opCode:\n\t\t\t\t\tGlobalUtils.OpenLink(opCode.Link);\n\t\t\t\t\tbreak;\n\t\t\t\tcase EntityReference unresolvedEntity:\n\t\t\t\t\tstring protocol = unresolvedEntity.Protocol;\n\t\t\t\t\tvar file = unresolvedEntity.ResolveAssembly(AssemblyList);\n\t\t\t\t\tif (file == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (protocol != \"decompile\")\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (var handler in exportProvider.GetExportedValues<IProtocolHandler>())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar node = handler.Resolve(protocol, file, unresolvedEntity.Handle, out bool newTabPage);\n\t\t\t\t\t\t\tif (node != null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tSelectNode(node, newTabPage || inNewTabPage);\n\t\t\t\t\t\t\t\treturn decompilationTask;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tvar possibleToken = MetadataTokenHelpers.TryAsEntityHandle(MetadataTokens.GetToken(unresolvedEntity.Handle));\n\t\t\t\t\tif (possibleToken != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar typeSystem = new DecompilerTypeSystem(file, file.GetAssemblyResolver(), TypeSystemOptions.Default | TypeSystemOptions.Uncached);\n\t\t\t\t\t\treference = typeSystem.MainModule.ResolveEntity(possibleToken.Value);\n\t\t\t\t\t\tgoto default;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tvar treeNode = FindTreeNode(reference);\n\t\t\t\t\tif (treeNode != null)\n\t\t\t\t\t\tSelectNode(treeNode, inNewTabPage);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn decompilationTask;\n\t\t}\n\n\t\t#endregion\n\n\t\tprivate void LoadAssemblies(IEnumerable<string> fileNames, List<LoadedAssembly>? loadedAssemblies = null, bool focusNode = true)\n\t\t{\n\t\t\tusing (Keyboard.FocusedElement.PreserveFocus(!focusNode))\n\t\t\t{\n\t\t\t\tAssemblyTreeNode? lastNode = null;\n\n\t\t\t\tvar assemblyList = AssemblyList;\n\n\t\t\t\tforeach (string file in fileNames)\n\t\t\t\t{\n\t\t\t\t\tvar assembly = assemblyList.OpenAssembly(file);\n\n\t\t\t\t\tif (loadedAssemblies != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tloadedAssemblies.Add(assembly);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tvar node = assemblyListTreeNode?.FindAssemblyNode(assembly);\n\t\t\t\t\t\tif (node != null && focusNode)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlastNode = node;\n\t\t\t\t\t\t\tactiveView?.ScrollIntoView(node);\n\t\t\t\t\t\t\tSelectedItems = [.. SelectedItems, node];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (focusNode && lastNode != null)\n\t\t\t\t{\n\t\t\t\t\tactiveView?.FocusNode(lastNode);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t#region Decompile (TreeView_SelectionChanged)\n\n\t\tprivate void TreeView_SelectionChanged(SharpTreeNode[] oldSelection, SharpTreeNode[] newSelection)\n\t\t{\n\t\t\tvar activeTabPage = DockWorkspace.ActiveTabPage;\n\t\t\tViewState? oldState = activeTabPage.GetState();\n\t\t\tViewState? newState;\n\n\t\t\tif (navigatingToState == null)\n\t\t\t{\n\t\t\t\tif (oldState != null)\n\t\t\t\t{\n\t\t\t\t\thistory.UpdateCurrent(new NavigationState(activeTabPage, oldState));\n\t\t\t\t}\n\n\t\t\t\tnewState = new ViewState { DecompiledNodes = [.. newSelection.Cast<ILSpyTreeNode>()] };\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tnewState = navigatingToState.ViewState;\n\t\t\t}\n\n\t\t\tif (newSelection.Length == 0)\n\t\t\t{\n\t\t\t\t// To cancel any pending decompilation requests and show an empty tab\n\t\t\t\tDecompileSelectedNodes(newState);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar delayDecompilationRequestDueToContextMenu = Mouse.RightButton == MouseButtonState.Pressed;\n\n\t\t\t\tif (!delayDecompilationRequestDueToContextMenu)\n\t\t\t\t{\n\t\t\t\t\tvar previousNodes = oldState?.DecompiledNodes\n\t\t\t\t\t\t?.Select(n => FindNodeByPath(GetPathForNode(n), true))\n\t\t\t\t\t\t.ExceptNullItems()\n\t\t\t\t\t\t.ToArray() ?? [];\n\n\t\t\t\t\tif (!previousNodes.SequenceEqual(SelectedItems))\n\t\t\t\t\t{\n\t\t\t\t\t\tDecompileSelectedNodes(newState);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// ensure that we are only connected once to the event, else we might get multiple notifications\n\t\t\t\t\tContextMenuProvider.ContextMenuClosed -= ContextMenuClosed;\n\t\t\t\t\tContextMenuProvider.ContextMenuClosed += ContextMenuClosed;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tMessageBus.Send(this, new AssemblyTreeSelectionChangedEventArgs());\n\n\t\t\treturn;\n\n\t\t\tvoid ContextMenuClosed(object? sender, EventArgs e)\n\t\t\t{\n\t\t\t\tContextMenuProvider.ContextMenuClosed -= ContextMenuClosed;\n\n\t\t\t\tUIThreadDispatcher.BeginInvoke(DispatcherPriority.Background, () => {\n\t\t\t\t\tif (Mouse.RightButton != MouseButtonState.Pressed)\n\t\t\t\t\t{\n\t\t\t\t\t\tRefreshDecompiledView();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tpublic void DecompileSelectedNodes(ViewState? newState = null)\n\t\t{\n\t\t\tobject? source = this.sourceOfReference;\n\t\t\tthis.sourceOfReference = null;\n\t\t\tvar activeTabPage = DockWorkspace.ActiveTabPage;\n\n\t\t\tif (activeTabPage.FrozenContent)\n\t\t\t{\n\t\t\t\tactiveTabPage = DockWorkspace.AddTabPage();\n\t\t\t}\n\n\t\t\tactiveTabPage.SupportsLanguageSwitching = true;\n\n\t\t\tif (newState != null && navigatingToState == null)\n\t\t\t{\n\t\t\t\thistory.Record(new NavigationState(activeTabPage, newState));\n\t\t\t}\n\n\t\t\tif (SelectedItems.Length == 1)\n\t\t\t{\n\t\t\t\tif (SelectedItem is ILSpyTreeNode node && node.View(activeTabPage))\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (newState?.ViewedUri != null)\n\t\t\t{\n\t\t\t\tNavigateTo(new(newState.ViewedUri, null));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar options = activeTabPage.CreateDecompilationOptions();\n\t\t\toptions.TextViewState = newState as DecompilerTextViewState;\n\t\t\tactiveTabPage.ShowTextViewAsync(textView => {\n\t\t\t\treturn textView.DecompileAsync(this.CurrentLanguage, this.SelectedNodes, source, options);\n\t\t\t});\n\t\t}\n\n\t\tpublic void RefreshDecompiledView()\n\t\t{\n\t\t\tDecompileSelectedNodes(DockWorkspace.ActiveTabPage.GetState() as DecompilerTextViewState);\n\t\t}\n\n\t\tpublic Language CurrentLanguage => languageService.Language;\n\n\t\tpublic LanguageVersion? CurrentLanguageVersion => languageService.LanguageVersion;\n\n\t\tpublic IEnumerable<ILSpyTreeNode> SelectedNodes => GetTopLevelSelection().OfType<ILSpyTreeNode>();\n\n\t\t#endregion\n\n\t\tpublic void NavigateHistory(bool forward, NavigationState? toState = null)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tTabPageModel tabPage = DockWorkspace.ActiveTabPage;\n\t\t\t\tvar currentState = tabPage.GetState();\n\t\t\t\tif (currentState != null)\n\t\t\t\t\thistory.UpdateCurrent(new NavigationState(tabPage, currentState));\n\n\t\t\t\tNavigationState newState;\n\t\t\t\tdo\n\t\t\t\t{\n\t\t\t\t\tnewState = forward ? history.GoForward() : history.GoBack();\n\t\t\t\t} while (newState != null && toState != null && toState != newState);\n\n\t\t\t\tif (newState == null)\n\t\t\t\t\treturn;\n\n\t\t\t\tnavigatingToState = newState;\n\n\t\t\t\tTabPageModel activeTabPage = newState.TabPage;\n\n\t\t\t\tDebug.Assert(DockWorkspace.TabPages.Contains(activeTabPage));\n\t\t\t\tDockWorkspace.ActiveTabPage = activeTabPage;\n\n\t\t\t\tif (newState.TreeNodes.Any())\n\t\t\t\t{\n\t\t\t\t\tSelectNodes(newState.TreeNodes);\n\t\t\t\t}\n\t\t\t\telse if (newState.ViewState.ViewedUri != null)\n\t\t\t\t{\n\t\t\t\t\tNavigateTo(new(newState.ViewState.ViewedUri, null));\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tnavigatingToState = null;\n\t\t\t}\n\t\t}\n\n\t\tpublic NavigationState[] GetNavigateHistory(bool forward) => forward ? history.ForwardList : history.BackList;\n\n\t\tpublic bool CanNavigateBack => history.CanNavigateBack;\n\n\t\tpublic bool CanNavigateForward => history.CanNavigateForward;\n\n\t\tprivate void NavigateTo(RequestNavigateEventArgs e, bool inNewTabPage = false)\n\t\t{\n\t\t\tif (e.Uri.Scheme != \"resource\")\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tTabPageModel tabPage = DockWorkspace.ActiveTabPage;\n\t\t\tViewState? oldState = tabPage.GetState();\n\t\t\tViewState? newState;\n\n\t\t\tif (navigatingToState == null)\n\t\t\t{\n\t\t\t\tif (oldState != null)\n\t\t\t\t{\n\t\t\t\t\thistory.UpdateCurrent(new NavigationState(tabPage, oldState));\n\t\t\t\t}\n\n\t\t\t\tnewState = new ViewState { ViewedUri = e.Uri };\n\n\t\t\t\tif (inNewTabPage)\n\t\t\t\t{\n\t\t\t\t\ttabPage = DockWorkspace.AddTabPage();\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tnewState = navigatingToState.ViewState;\n\t\t\t\ttabPage = DockWorkspace.ActiveTabPage = navigatingToState.TabPage;\n\t\t\t}\n\n\t\t\tbool needsNewNavigationEntry = !inNewTabPage && selectedItems?.Length == 0;\n\n\t\t\tUnselectAll();\n\n\t\t\tif (e.Uri.Host == \"aboutpage\")\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new ShowAboutPageEventArgs(DockWorkspace.ActiveTabPage));\n\t\t\t\te.Handled = true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tAvalonEditTextOutput output = new AvalonEditTextOutput {\n\t\t\t\t\tAddress = e.Uri,\n\t\t\t\t\tTitle = e.Uri.AbsolutePath,\n\t\t\t\t\tEnableHyperlinks = true\n\t\t\t\t};\n\t\t\t\tusing (Stream? s = typeof(App).Assembly.GetManifestResourceStream(typeof(App), e.Uri.AbsolutePath))\n\t\t\t\t{\n\t\t\t\t\tif (s != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tusing StreamReader r = new StreamReader(s);\n\t\t\t\t\t\tstring? line;\n\t\t\t\t\t\twhile ((line = r.ReadLine()) != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toutput.Write(line);\n\t\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tDockWorkspace.ShowText(output);\n\t\t\t\te.Handled = true;\n\t\t\t}\n\n\t\t\tif (navigatingToState == null)\n\t\t\t{\n\t\t\t\t// the call to UnselectAll() above already creates a new navigation entry,\n\t\t\t\t// we just need to make sure it contains something useful.\n\t\t\t\tif (!needsNewNavigationEntry)\n\t\t\t\t{\n\t\t\t\t\thistory.UpdateCurrent(new NavigationState(tabPage, tabPage.GetState()));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\thistory.Record(new NavigationState(tabPage, tabPage.GetState()));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic void Refresh()\n\t\t{\n\t\t\trefreshThrottle.Tick();\n\t\t}\n\n\t\tprivate void RefreshInternal()\n\t\t{\n\t\t\tusing (Keyboard.FocusedElement.PreserveFocus())\n\t\t\t{\n\t\t\t\tvar path = GetPathForNode(SelectedItem);\n\n\t\t\t\tShowAssemblyList(settingsService.AssemblyListManager.LoadList(AssemblyList.ListName));\n\t\t\t\tSelectNode(FindNodeByPath(path, true), inNewTabPage: false);\n\n\t\t\t\tRefreshDecompiledView();\n\t\t\t}\n\t\t}\n\n\t\tprivate void UnselectAll()\n\t\t{\n\t\t\tSelectedItems = [];\n\t\t}\n\n\t\tprivate IEnumerable<SharpTreeNode> GetTopLevelSelection()\n\t\t{\n\t\t\tvar selection = this.SelectedItems;\n\t\t\tvar selectionHash = new HashSet<SharpTreeNode>(selection);\n\n\t\t\treturn selection.Where(item => item.Ancestors().All(a => !selectionHash.Contains(a)));\n\t\t}\n\n\t\tpublic void SetActiveView(AssemblyListPane activeView)\n\t\t{\n\t\t\tthis.activeView = activeView;\n\t\t}\n\n\t\tpublic void SortAssemblyList()\n\t\t{\n\t\t\tusing (activeView?.LockUpdates())\n\t\t\t{\n\t\t\t\tAssemblyList.Sort(AssemblyComparer.Instance);\n\t\t\t}\n\t\t}\n\n\t\tprivate class AssemblyComparer : IComparer<LoadedAssembly>\n\t\t{\n\t\t\tpublic static readonly AssemblyComparer Instance = new();\n\t\t\tint IComparer<LoadedAssembly>.Compare(LoadedAssembly? x, LoadedAssembly? y)\n\t\t\t{\n\t\t\t\treturn string.Compare(x?.ShortName, y?.ShortName, StringComparison.CurrentCulture);\n\t\t\t}\n\t\t}\n\n\t\tpublic void CollapseAll()\n\t\t{\n\t\t\tusing (activeView?.LockUpdates())\n\t\t\t{\n\t\t\t\tCollapseChildren(Root);\n\t\t\t}\n\t\t}\n\n\t\tprivate static void CollapseChildren(SharpTreeNode? node)\n\t\t{\n\t\t\tif (node is null)\n\t\t\t\treturn;\n\n\t\t\tforeach (var child in node.Children)\n\t\t\t{\n\t\t\t\tif (!child.IsExpanded)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tCollapseChildren(child);\n\t\t\t\tchild.IsExpanded = false;\n\t\t\t}\n\t\t}\n\n\t\tpublic void OpenFiles(string[] fileNames, bool focusNode = true)\n\t\t{\n\t\t\tif (fileNames == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(fileNames));\n\n\t\t\tif (focusNode)\n\t\t\t\tUnselectAll();\n\n\t\t\tLoadAssemblies(fileNames, focusNode: focusNode);\n\t\t}\n\n\t\tprivate void ApplySessionSettings(object? sender, ApplySessionSettingsEventArgs e)\n\t\t{\n\t\t\tvar settings = e.SessionSettings;\n\n\t\t\tsettings.ActiveAssemblyList = AssemblyList.ListName;\n\t\t\tsettings.ActiveTreeViewPath = SelectedPath;\n\t\t\tsettings.ActiveAutoLoadedAssembly = GetAutoLoadedAssemblyNode(SelectedItem);\n\t\t}\n\n\t\tprivate static string? GetAutoLoadedAssemblyNode(SharpTreeNode? node)\n\t\t{\n\t\t\tvar assemblyTreeNode = node?\n\t\t\t\t.AncestorsAndSelf()\n\t\t\t\t.OfType<AssemblyTreeNode>()\n\t\t\t\t.FirstOrDefault();\n\n\t\t\tvar loadedAssembly = assemblyTreeNode?.LoadedAssembly;\n\n\t\t\treturn loadedAssembly is not { IsLoaded: true, IsAutoLoaded: true }\n\t\t\t\t? null\n\t\t\t\t: loadedAssembly.FileName;\n\t\t}\n\n\t\tprivate void ActiveTabPageChanged(object? sender, ActiveTabPageChangedEventArgs e)\n\t\t{\n\t\t\tif (e.ViewState is not { } state)\n\t\t\t\treturn;\n\n\t\t\tif (state.DecompiledNodes != null)\n\t\t\t{\n\t\t\t\tSelectNodes(state.DecompiledNodes);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tNavigateTo(new(state.ViewedUri, null));\n\t\t\t}\n\t\t}\n\n\t\tprivate void ResetLayout(object? sender, ResetLayoutEventArgs e)\n\t\t{\n\t\t\tRefreshDecompiledView();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/AvalonEdit/ITextMarker.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Windows;\nusing System.Windows.Media;\n\nnamespace ICSharpCode.ILSpy.AvalonEdit\n{\n\t/// <summary>\n\t/// Represents a text marker.\n\t/// </summary>\n\tpublic interface ITextMarker\n\t{\n\t\t/// <summary>\n\t\t/// Gets the start offset of the marked text region.\n\t\t/// </summary>\n\t\tint StartOffset { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the end offset of the marked text region.\n\t\t/// </summary>\n\t\tint EndOffset { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the length of the marked region.\n\t\t/// </summary>\n\t\tint Length { get; }\n\n\t\t/// <summary>\n\t\t/// Deletes the text marker.\n\t\t/// </summary>\n\t\tvoid Delete();\n\n\t\t/// <summary>\n\t\t/// Gets whether the text marker was deleted.\n\t\t/// </summary>\n\t\tbool IsDeleted { get; }\n\n\t\t/// <summary>\n\t\t/// Event that occurs when the text marker is deleted.\n\t\t/// </summary>\n\t\tevent EventHandler Deleted;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the background color.\n\t\t/// </summary>\n\t\tColor? BackgroundColor { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the foreground color.\n\t\t/// </summary>\n\t\tColor? ForegroundColor { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the font weight.\n\t\t/// </summary>\n\t\tFontWeight? FontWeight { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the font style.\n\t\t/// </summary>\n\t\tFontStyle? FontStyle { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the type of the marker. Use TextMarkerType.None for normal markers.\n\t\t/// </summary>\n\t\tTextMarkerTypes MarkerTypes { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the color of the marker.\n\t\t/// </summary>\n\t\tColor MarkerColor { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets/Sets an object with additional data for this text marker.\n\t\t/// </summary>\n\t\tobject Tag { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets/Sets an object that will be displayed as tooltip in the text editor.\n\t\t/// </summary>\n\t\tobject ToolTip { get; set; }\n\t}\n\n\t[Flags]\n\tpublic enum TextMarkerTypes\n\t{\n\t\t/// <summary>\n\t\t/// Use no marker\n\t\t/// </summary>\n\t\tNone = 0x0000,\n\t\t/// <summary>\n\t\t/// Use squiggly underline marker\n\t\t/// </summary>\n\t\tSquigglyUnderline = 0x001,\n\t\t/// <summary>\n\t\t/// Normal underline.\n\t\t/// </summary>\n\t\tNormalUnderline = 0x002,\n\t\t/// <summary>\n\t\t/// Dotted underline.\n\t\t/// </summary>\n\t\tDottedUnderline = 0x004,\n\n\t\t/// <summary>\n\t\t/// Horizontal line in the scroll bar.\n\t\t/// </summary>\n\t\tLineInScrollBar = 0x0100,\n\t\t/// <summary>\n\t\t/// Small triangle in the scroll bar, pointing to the right.\n\t\t/// </summary>\n\t\tScrollBarRightTriangle = 0x0400,\n\t\t/// <summary>\n\t\t/// Small triangle in the scroll bar, pointing to the left.\n\t\t/// </summary>\n\t\tScrollBarLeftTriangle = 0x0800,\n\t\t/// <summary>\n\t\t/// Small circle in the scroll bar.\n\t\t/// </summary>\n\t\tCircleInScrollBar = 0x1000\n\t}\n\n\tpublic interface ITextMarkerService\n\t{\n\t\t/// <summary>\n\t\t/// Creates a new text marker. The text marker will be invisible at first,\n\t\t/// you need to set one of the Color properties to make it visible.\n\t\t/// </summary>\n\t\tITextMarker Create(int startOffset, int length);\n\n\t\t/// <summary>\n\t\t/// Gets the list of text markers.\n\t\t/// </summary>\n\t\tIEnumerable<ITextMarker> TextMarkers { get; }\n\n\t\t/// <summary>\n\t\t/// Removes the specified text marker.\n\t\t/// </summary>\n\t\tvoid Remove(ITextMarker marker);\n\n\t\t/// <summary>\n\t\t/// Removes all text markers that match the condition.\n\t\t/// </summary>\n\t\tvoid RemoveAll(Predicate<ITextMarker> predicate);\n\n\t\t/// <summary>\n\t\t/// Finds all text markers at the specified offset.\n\t\t/// </summary>\n\t\tIEnumerable<ITextMarker> GetMarkersAtOffset(int offset);\n\t}\n}\n"
  },
  {
    "path": "ILSpy/AvalonEdit/TextMarkerService.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Media;\nusing System.Windows.Threading;\n\nusing ICSharpCode.AvalonEdit.Document;\nusing ICSharpCode.AvalonEdit.Rendering;\n\nnamespace ICSharpCode.ILSpy.AvalonEdit\n{\n\tusing TextView = ICSharpCode.AvalonEdit.Rendering.TextView;\n\t/// <summary>\n\t/// Handles the text markers for a code editor.\n\t/// </summary>\n\tsealed class TextMarkerService : DocumentColorizingTransformer, IBackgroundRenderer, ITextMarkerService\n\t{\n\t\tTextSegmentCollection<TextMarker> markers;\n\t\tTextView textView;\n\n\t\tpublic TextMarkerService(TextView textView)\n\t\t{\n\t\t\tif (textView == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(textView));\n\t\t\tthis.textView = textView;\n\t\t\ttextView.DocumentChanged += OnDocumentChanged;\n\t\t\tOnDocumentChanged(null, null);\n\t\t}\n\n\t\tvoid OnDocumentChanged(object sender, EventArgs e)\n\t\t{\n\t\t\tif (textView.Document != null)\n\t\t\t\tmarkers = new TextSegmentCollection<TextMarker>(textView.Document);\n\t\t\telse\n\t\t\t\tmarkers = null;\n\t\t}\n\n\t\t#region ITextMarkerService\n\t\tpublic ITextMarker Create(int startOffset, int length)\n\t\t{\n\t\t\tif (markers == null)\n\t\t\t\tthrow new InvalidOperationException(\"Cannot create a marker when not attached to a document\");\n\n\t\t\tint textLength = textView.Document.TextLength;\n\t\t\tif (startOffset < 0 || startOffset > textLength)\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(startOffset), startOffset, \"Value must be between 0 and \" + textLength);\n\t\t\tif (length < 0 || startOffset + length > textLength)\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(length), length, \"length must not be negative and startOffset+length must not be after the end of the document\");\n\n\t\t\tTextMarker m = new TextMarker(this, startOffset, length);\n\t\t\tmarkers.Add(m);\n\t\t\t// no need to mark segment for redraw: the text marker is invisible until a property is set\n\t\t\treturn m;\n\t\t}\n\n\t\tpublic IEnumerable<ITextMarker> GetMarkersAtOffset(int offset)\n\t\t{\n\t\t\tif (markers == null)\n\t\t\t\treturn Enumerable.Empty<ITextMarker>();\n\t\t\telse\n\t\t\t\treturn markers.FindSegmentsContaining(offset);\n\t\t}\n\n\t\tpublic IEnumerable<ITextMarker> TextMarkers {\n\t\t\tget { return markers ?? Enumerable.Empty<ITextMarker>(); }\n\t\t}\n\n\t\tpublic void RemoveAll(Predicate<ITextMarker> predicate)\n\t\t{\n\t\t\tif (predicate == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(predicate));\n\t\t\tif (markers != null)\n\t\t\t{\n\t\t\t\tforeach (TextMarker m in markers.ToArray())\n\t\t\t\t{\n\t\t\t\t\tif (predicate(m))\n\t\t\t\t\t\tRemove(m);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic void Remove(ITextMarker marker)\n\t\t{\n\t\t\tif (marker == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(marker));\n\t\t\tTextMarker m = marker as TextMarker;\n\t\t\tif (markers != null && markers.Remove(m))\n\t\t\t{\n\t\t\t\tRedraw(m);\n\t\t\t\tm.OnDeleted();\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Redraws the specified text segment.\n\t\t/// </summary>\n\t\tinternal void Redraw(ISegment segment)\n\t\t{\n\t\t\ttextView.Redraw(segment, DispatcherPriority.Normal);\n\t\t\tRedrawRequested?.Invoke(this, EventArgs.Empty);\n\t\t}\n\n\t\tpublic event EventHandler RedrawRequested;\n\t\t#endregion\n\n\t\t#region DocumentColorizingTransformer\n\t\tprotected override void ColorizeLine(DocumentLine line)\n\t\t{\n\t\t\tif (markers == null)\n\t\t\t\treturn;\n\t\t\tint lineStart = line.Offset;\n\t\t\tint lineEnd = lineStart + line.Length;\n\t\t\tforeach (TextMarker marker in markers.FindOverlappingSegments(lineStart, line.Length))\n\t\t\t{\n\t\t\t\tBrush foregroundBrush = null;\n\t\t\t\tif (marker.ForegroundColor != null)\n\t\t\t\t{\n\t\t\t\t\tforegroundBrush = new SolidColorBrush(marker.ForegroundColor.Value);\n\t\t\t\t\tforegroundBrush.Freeze();\n\t\t\t\t}\n\t\t\t\tChangeLinePart(\n\t\t\t\t\tMath.Max(marker.StartOffset, lineStart),\n\t\t\t\t\tMath.Min(marker.EndOffset, lineEnd),\n\t\t\t\t\telement => {\n\t\t\t\t\t\tif (foregroundBrush != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\telement.TextRunProperties.SetForegroundBrush(foregroundBrush);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tTypeface tf = element.TextRunProperties.Typeface;\n\t\t\t\t\t\telement.TextRunProperties.SetTypeface(new Typeface(\n\t\t\t\t\t\t\ttf.FontFamily,\n\t\t\t\t\t\t\tmarker.FontStyle ?? tf.Style,\n\t\t\t\t\t\t\tmarker.FontWeight ?? tf.Weight,\n\t\t\t\t\t\t\ttf.Stretch\n\t\t\t\t\t\t));\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region IBackgroundRenderer\n\t\tpublic KnownLayer Layer {\n\t\t\tget {\n\t\t\t\t// draw behind selection\n\t\t\t\treturn KnownLayer.Selection;\n\t\t\t}\n\t\t}\n\n\t\tpublic void Draw(ICSharpCode.AvalonEdit.Rendering.TextView textView, DrawingContext drawingContext)\n\t\t{\n\t\t\tif (textView == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(textView));\n\t\t\tif (drawingContext == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(drawingContext));\n\t\t\tif (markers == null || !textView.VisualLinesValid)\n\t\t\t\treturn;\n\t\t\tvar visualLines = textView.VisualLines;\n\t\t\tif (visualLines.Count == 0)\n\t\t\t\treturn;\n\t\t\tint viewStart = visualLines.First().FirstDocumentLine.Offset;\n\t\t\tint viewEnd = visualLines.Last().LastDocumentLine.EndOffset;\n\t\t\tforeach (TextMarker marker in markers.FindOverlappingSegments(viewStart, viewEnd - viewStart))\n\t\t\t{\n\t\t\t\tif (marker.BackgroundColor != null)\n\t\t\t\t{\n\t\t\t\t\tBackgroundGeometryBuilder geoBuilder = new BackgroundGeometryBuilder();\n\t\t\t\t\tgeoBuilder.AlignToWholePixels = true;\n\t\t\t\t\tgeoBuilder.CornerRadius = 3;\n\t\t\t\t\tgeoBuilder.AddSegment(textView, marker);\n\t\t\t\t\tGeometry geometry = geoBuilder.CreateGeometry();\n\t\t\t\t\tif (geometry != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tColor color = marker.BackgroundColor.Value;\n\t\t\t\t\t\tSolidColorBrush brush = new SolidColorBrush(color);\n\t\t\t\t\t\tbrush.Freeze();\n\t\t\t\t\t\tdrawingContext.DrawGeometry(brush, null, geometry);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvar underlineMarkerTypes = TextMarkerTypes.SquigglyUnderline | TextMarkerTypes.NormalUnderline | TextMarkerTypes.DottedUnderline;\n\t\t\t\tif ((marker.MarkerTypes & underlineMarkerTypes) != 0)\n\t\t\t\t{\n\t\t\t\t\tforeach (Rect r in BackgroundGeometryBuilder.GetRectsForSegment(textView, marker))\n\t\t\t\t\t{\n\t\t\t\t\t\tPoint startPoint = r.BottomLeft;\n\t\t\t\t\t\tPoint endPoint = r.BottomRight;\n\n\t\t\t\t\t\tBrush usedBrush = new SolidColorBrush(marker.MarkerColor);\n\t\t\t\t\t\tusedBrush.Freeze();\n\t\t\t\t\t\tif ((marker.MarkerTypes & TextMarkerTypes.SquigglyUnderline) != 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdouble offset = 2.5;\n\n\t\t\t\t\t\t\tint count = Math.Max((int)((endPoint.X - startPoint.X) / offset) + 1, 4);\n\n\t\t\t\t\t\t\tStreamGeometry geometry = new StreamGeometry();\n\n\t\t\t\t\t\t\tusing (StreamGeometryContext ctx = geometry.Open())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tctx.BeginFigure(startPoint, false, false);\n\t\t\t\t\t\t\t\tctx.PolyLineTo(CreatePoints(startPoint, endPoint, offset, count).ToArray(), true, false);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tgeometry.Freeze();\n\n\t\t\t\t\t\t\tPen usedPen = new Pen(usedBrush, 1);\n\t\t\t\t\t\t\tusedPen.Freeze();\n\t\t\t\t\t\t\tdrawingContext.DrawGeometry(Brushes.Transparent, usedPen, geometry);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ((marker.MarkerTypes & TextMarkerTypes.NormalUnderline) != 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPen usedPen = new Pen(usedBrush, 1);\n\t\t\t\t\t\t\tusedPen.Freeze();\n\t\t\t\t\t\t\tdrawingContext.DrawLine(usedPen, startPoint, endPoint);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ((marker.MarkerTypes & TextMarkerTypes.DottedUnderline) != 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPen usedPen = new Pen(usedBrush, 1);\n\t\t\t\t\t\t\tusedPen.DashStyle = DashStyles.Dot;\n\t\t\t\t\t\t\tusedPen.Freeze();\n\t\t\t\t\t\t\tdrawingContext.DrawLine(usedPen, startPoint, endPoint);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tIEnumerable<Point> CreatePoints(Point start, Point end, double offset, int count)\n\t\t{\n\t\t\tfor (int i = 0; i < count; i++)\n\t\t\t\tyield return new Point(start.X + i * offset, start.Y - ((i + 1) % 2 == 0 ? offset : 0));\n\t\t}\n\t\t#endregion\n\t}\n\n\tsealed class TextMarker : TextSegment, ITextMarker\n\t{\n\t\treadonly TextMarkerService service;\n\n\t\tpublic TextMarker(TextMarkerService service, int startOffset, int length)\n\t\t{\n\t\t\tif (service == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(service));\n\t\t\tthis.service = service;\n\t\t\tthis.StartOffset = startOffset;\n\t\t\tthis.Length = length;\n\t\t\tthis.markerTypes = TextMarkerTypes.None;\n\t\t}\n\n\t\tpublic event EventHandler Deleted;\n\n\t\tpublic bool IsDeleted {\n\t\t\tget { return !this.IsConnectedToCollection; }\n\t\t}\n\n\t\tpublic void Delete()\n\t\t{\n\t\t\tservice.Remove(this);\n\t\t}\n\n\t\tinternal void OnDeleted()\n\t\t{\n\t\t\tDeleted?.Invoke(this, EventArgs.Empty);\n\t\t}\n\n\t\tvoid Redraw()\n\t\t{\n\t\t\tservice.Redraw(this);\n\t\t}\n\n\t\tColor? backgroundColor;\n\n\t\tpublic Color? BackgroundColor {\n\t\t\tget { return backgroundColor; }\n\t\t\tset {\n\t\t\t\tif (backgroundColor != value)\n\t\t\t\t{\n\t\t\t\t\tbackgroundColor = value;\n\t\t\t\t\tRedraw();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tColor? foregroundColor;\n\n\t\tpublic Color? ForegroundColor {\n\t\t\tget { return foregroundColor; }\n\t\t\tset {\n\t\t\t\tif (foregroundColor != value)\n\t\t\t\t{\n\t\t\t\t\tforegroundColor = value;\n\t\t\t\t\tRedraw();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tFontWeight? fontWeight;\n\n\t\tpublic FontWeight? FontWeight {\n\t\t\tget { return fontWeight; }\n\t\t\tset {\n\t\t\t\tif (fontWeight != value)\n\t\t\t\t{\n\t\t\t\t\tfontWeight = value;\n\t\t\t\t\tRedraw();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tFontStyle? fontStyle;\n\n\t\tpublic FontStyle? FontStyle {\n\t\t\tget { return fontStyle; }\n\t\t\tset {\n\t\t\t\tif (fontStyle != value)\n\t\t\t\t{\n\t\t\t\t\tfontStyle = value;\n\t\t\t\t\tRedraw();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic object Tag { get; set; }\n\n\t\tTextMarkerTypes markerTypes;\n\n\t\tpublic TextMarkerTypes MarkerTypes {\n\t\t\tget { return markerTypes; }\n\t\t\tset {\n\t\t\t\tif (markerTypes != value)\n\t\t\t\t{\n\t\t\t\t\tmarkerTypes = value;\n\t\t\t\t\tRedraw();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tColor markerColor;\n\n\t\tpublic Color MarkerColor {\n\t\t\tget { return markerColor; }\n\t\t\tset {\n\t\t\t\tif (markerColor != value)\n\t\t\t\t{\n\t\t\t\t\tmarkerColor = value;\n\t\t\t\t\tRedraw();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic object ToolTip { get; set; }\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/BrowseBackCommand.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections;\nusing System.Composition;\nusing System.Linq;\nusing System.Windows.Input;\n\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Properties;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportToolbarCommand(ToolTip = nameof(Resources.Back), ToolbarIcon = \"Images/Back\", ToolbarCategory = nameof(Resources.Navigation), ToolbarOrder = 0)]\n\t[Shared]\n\tsealed class BrowseBackCommand : CommandWrapper, IProvideParameterList\n\t{\n\t\treadonly AssemblyTreeModel assemblyTreeModel;\n\n\t\tpublic BrowseBackCommand(AssemblyTreeModel assemblyTreeModel)\n\t\t\t: base(NavigationCommands.BrowseBack)\n\t\t{\n\t\t\tthis.assemblyTreeModel = assemblyTreeModel;\n\t\t}\n\n\t\tprotected override void OnCanExecute(object sender, CanExecuteRoutedEventArgs e)\n\t\t{\n\t\t\tbase.OnCanExecute(sender, e);\n\n\t\t\te.Handled = true;\n\t\t\te.CanExecute = assemblyTreeModel.CanNavigateBack;\n\t\t}\n\n\t\tprotected override void OnExecute(object sender, ExecutedRoutedEventArgs e)\n\t\t{\n\t\t\tif (assemblyTreeModel.CanNavigateBack)\n\t\t\t{\n\t\t\t\te.Handled = true;\n\t\t\t\tassemblyTreeModel.NavigateHistory(false, e.Parameter as NavigationState);\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable ParameterList => assemblyTreeModel.GetNavigateHistory(false).Reverse();\n\n\t\tpublic object GetParameterText(object parameter)\n\t\t{\n\t\t\treturn (parameter as NavigationState)?.NavigationText;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/BrowseForwardCommand.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections;\nusing System.Composition;\nusing System.Linq;\nusing System.Windows.Input;\n\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Properties;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportToolbarCommand(ToolTip = nameof(Resources.Forward), ToolbarIcon = \"Images/Forward\", ToolbarCategory = nameof(Resources.Navigation), ToolbarOrder = 1)]\n\t[Shared]\n\tsealed class BrowseForwardCommand : CommandWrapper, IProvideParameterList\n\t{\n\t\tprivate readonly AssemblyTreeModel assemblyTreeModel;\n\n\t\tpublic BrowseForwardCommand(AssemblyTreeModel assemblyTreeModel)\n\t\t\t: base(NavigationCommands.BrowseForward)\n\t\t{\n\t\t\tthis.assemblyTreeModel = assemblyTreeModel;\n\t\t}\n\n\t\tprotected override void OnCanExecute(object sender, CanExecuteRoutedEventArgs e)\n\t\t{\n\t\t\tbase.OnCanExecute(sender, e);\n\n\t\t\te.Handled = true;\n\t\t\te.CanExecute = assemblyTreeModel.CanNavigateForward;\n\t\t}\n\n\t\tprotected override void OnExecute(object sender, ExecutedRoutedEventArgs e)\n\t\t{\n\t\t\tif (assemblyTreeModel.CanNavigateForward)\n\t\t\t{\n\t\t\t\te.Handled = true;\n\t\t\t\tassemblyTreeModel.NavigateHistory(true, e.Parameter as NavigationState);\n\t\t\t}\n\t\t}\n\n\t\tpublic IEnumerable ParameterList => assemblyTreeModel.GetNavigateHistory(true).Reverse();\n\n\t\tpublic object GetParameterText(object parameter)\n\t\t{\n\t\t\treturn (parameter as NavigationState)?.NavigationText;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/CheckForUpdatesCommand.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\n\nusing ICSharpCode.ILSpy.Properties;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportMainMenuCommand(ParentMenuID = nameof(Resources._Help), Header = nameof(Resources._CheckUpdates), MenuOrder = 5000)]\n\t[Shared]\n\tsealed class CheckForUpdatesCommand : SimpleCommand\n\t{\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tMessageBus.Send(this, new CheckIfUpdateAvailableEventArgs(notify: true));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/CommandWrapper.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Windows;\nusing System.Windows.Input;\n\nnamespace ICSharpCode.ILSpy\n{\n\tabstract class CommandWrapper : ICommand\n\t{\n\t\tprivate readonly ICommand wrappedCommand;\n\n\t\tprotected CommandWrapper(ICommand wrappedCommand)\n\t\t{\n\t\t\tthis.wrappedCommand = wrappedCommand;\n\n\t\t\tApplication.Current.MainWindow?.CommandBindings.Add(new CommandBinding(wrappedCommand, OnExecute, OnCanExecute));\n\t\t}\n\n\t\tpublic static ICommand Unwrap(ICommand command)\n\t\t{\n\t\t\tif (command is CommandWrapper w)\n\t\t\t\treturn w.wrappedCommand;\n\n\t\t\treturn command;\n\t\t}\n\n\t\tpublic event EventHandler CanExecuteChanged {\n\t\t\tadd { wrappedCommand.CanExecuteChanged += value; }\n\t\t\tremove { wrappedCommand.CanExecuteChanged -= value; }\n\t\t}\n\n\t\tpublic void Execute(object parameter)\n\t\t{\n\t\t\twrappedCommand.Execute(parameter);\n\t\t}\n\n\t\tpublic bool CanExecute(object parameter)\n\t\t{\n\t\t\treturn wrappedCommand.CanExecute(parameter);\n\t\t}\n\n\t\tprotected abstract void OnExecute(object sender, ExecutedRoutedEventArgs e);\n\n\t\tprotected virtual void OnCanExecute(object sender, CanExecuteRoutedEventArgs e)\n\t\t{\n\t\t\te.CanExecute = true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/CompareContextMenuEntry.cs",
    "content": "// Copyright (c) 2025 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpy.Views;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportContextMenuEntry(Header = \"Compare...\", Order = 9999)]\n\t[Shared]\n\tinternal sealed class CompareContextMenuEntry(AssemblyTreeModel assemblyTreeModel, DockWorkspace dockWorkspace) : IContextMenuEntry\n\t{\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tvar left = ((AssemblyTreeNode)context.SelectedTreeNodes[0]).LoadedAssembly;\n\t\t\tvar right = ((AssemblyTreeNode)context.SelectedTreeNodes[1]).LoadedAssembly;\n\n\t\t\tvar tabPage = dockWorkspace.AddTabPage();\n\t\t\tCompareViewModel.Show(tabPage, left, right, assemblyTreeModel);\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\treturn context.SelectedTreeNodes is [AssemblyTreeNode { LoadedAssembly.IsLoadedAsValidAssembly: true }, AssemblyTreeNode { LoadedAssembly.IsLoadedAsValidAssembly: true }];\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Commands/CopyFullyQualifiedNameContextMenuEntry.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\nusing System.Composition;\nusing System.Windows;\n\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportContextMenuEntry(Header = nameof(Resources.CopyName), Icon = \"images/Copy\", Order = 9999)]\n\t[Shared]\n\tpublic class CopyFullyQualifiedNameContextMenuEntry : IContextMenuEntry\n\t{\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\treturn GetMemberNodeFromContext(context) != null;\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context) => true;\n\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tvar member = GetMemberNodeFromContext(context)?.Member;\n\t\t\tif (member == null)\n\t\t\t\treturn;\n\t\t\tClipboard.SetText(member.ReflectionName);\n\t\t}\n\n\t\tprivate IMemberTreeNode GetMemberNodeFromContext(TextViewContext context)\n\t\t{\n\t\t\treturn context.SelectedTreeNodes?.Length == 1 ? context.SelectedTreeNodes[0] as IMemberTreeNode : null;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Commands/CreateDiagramContextMenuEntry.cs",
    "content": "// Copyright (c) 2024 Christoph Wille for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Windows;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpyX.MermaidDiagrammer;\n\nusing Microsoft.Win32;\n\nnamespace ICSharpCode.ILSpy.TextView\n{\n\t[ExportContextMenuEntry(Header = nameof(Resources._CreateDiagram), Category = nameof(Resources.Save), Icon = \"Images/Save\")]\n\t[Shared]\n\tsealed class CreateDiagramContextMenuEntry(DockWorkspace dockWorkspace) : IContextMenuEntry\n\t{\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tvar assembly = (context.SelectedTreeNodes?.FirstOrDefault() as AssemblyTreeNode)?.LoadedAssembly;\n\t\t\tif (assembly == null)\n\t\t\t\treturn;\n\n\t\t\tvar selectedPath = SelectDestinationFolder();\n\t\t\tif (string.IsNullOrEmpty(selectedPath))\n\t\t\t\treturn;\n\n\t\t\tdockWorkspace.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {\n\t\t\t\tAvalonEditTextOutput output = new() {\n\t\t\t\t\tEnableHyperlinks = true\n\t\t\t\t};\n\t\t\t\tStopwatch stopwatch = Stopwatch.StartNew();\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tvar command = new GenerateHtmlDiagrammer {\n\t\t\t\t\t\tAssembly = assembly.FileName,\n\t\t\t\t\t\tOutputFolder = selectedPath\n\t\t\t\t\t};\n\n\t\t\t\t\tcommand.Run();\n\t\t\t\t}\n\t\t\t\tcatch (OperationCanceledException)\n\t\t\t\t{\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\toutput.WriteLine(Resources.GenerationWasCancelled);\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t\tstopwatch.Stop();\n\t\t\t\toutput.WriteLine(Resources.GenerationCompleteInSeconds, stopwatch.Elapsed.TotalSeconds.ToString(\"F1\"));\n\t\t\t\toutput.WriteLine();\n\t\t\t\toutput.WriteLine(\"Learn more: \" + \"https://github.com/icsharpcode/ILSpy/wiki/Diagramming#tips-for-using-the-html-diagrammer\");\n\t\t\t\toutput.WriteLine();\n\n\t\t\t\tvar diagramHtml = Path.Combine(selectedPath, \"index.html\");\n\t\t\t\toutput.AddButton(null, Resources.OpenExplorer, delegate { ShellHelper.OpenFolderAndSelectItem(diagramHtml); });\n\t\t\t\toutput.WriteLine();\n\t\t\t\treturn output;\n\t\t\t}, ct), Properties.Resources.CreatingDiagram).Then(dockWorkspace.ShowText).HandleExceptions();\n\n\t\t\treturn;\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context) => true;\n\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\treturn context.SelectedTreeNodes?.Length == 1\n\t\t\t\t&& context.SelectedTreeNodes?.FirstOrDefault() is AssemblyTreeNode tn\n\t\t\t\t&& tn.LoadedAssembly.IsLoadedAsValidAssembly;\n\t\t}\n\n\t\tstatic string SelectDestinationFolder()\n\t\t{\n\t\t\tOpenFolderDialog dialog = new();\n\t\t\tdialog.Multiselect = false;\n\t\t\tdialog.Title = \"Select target folder\";\n\n\t\t\tif (dialog.ShowDialog() != true)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tstring selectedPath = Path.GetDirectoryName(dialog.FolderName);\n\t\t\tbool directoryNotEmpty;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tdirectoryNotEmpty = Directory.EnumerateFileSystemEntries(selectedPath).Any();\n\t\t\t}\n\t\t\tcatch (Exception e) when (e is IOException || e is UnauthorizedAccessException || e is System.Security.SecurityException)\n\t\t\t{\n\t\t\t\tMessageBox.Show(\n\t\t\t\t\t\"The directory cannot be accessed. Please ensure it exists and you have sufficient rights to access it.\",\n\t\t\t\t\t\"Target directory not accessible\",\n\t\t\t\t\tMessageBoxButton.OK, MessageBoxImage.Error);\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn dialog.FolderName;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/DecompileAllCommand.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#if DEBUG\n\nusing System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDecompile), MenuCategory = nameof(Resources.Open), MenuOrder = 2.5)]\n\t[Shared]\n\tsealed class DecompileAllCommand(AssemblyTreeModel assemblyTreeModel, DockWorkspace dockWorkspace) : SimpleCommand\n\t{\n\t\tpublic override bool CanExecute(object parameter)\n\t\t{\n\t\t\treturn System.IO.Directory.Exists(\"c:\\\\temp\\\\decompiled\");\n\t\t}\n\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tdockWorkspace.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {\n\t\t\t\tAvalonEditTextOutput output = new AvalonEditTextOutput();\n\t\t\t\tParallel.ForEach(\n\t\t\t\t\tPartitioner.Create(assemblyTreeModel.AssemblyList.GetAssemblies(), loadBalance: true),\n\t\t\t\t\tnew ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = ct },\n\t\t\t\t\tdelegate (LoadedAssembly asm) {\n\t\t\t\t\t\tif (!asm.HasLoadError)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tStopwatch w = Stopwatch.StartNew();\n\t\t\t\t\t\t\tException exception = null;\n\t\t\t\t\t\t\tusing (var writer = new System.IO.StreamWriter(\"c:\\\\temp\\\\decompiled\\\\\" + asm.ShortName + \".cs\"))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tvar options = dockWorkspace.ActiveTabPage.CreateDecompilationOptions();\n\t\t\t\t\t\t\t\t\toptions.CancellationToken = ct;\n\t\t\t\t\t\t\t\t\toptions.FullDecompilation = true;\n\t\t\t\t\t\t\t\t\tnew CSharpLanguage().DecompileAssembly(asm, new PlainTextOutput(writer), options);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch (Exception ex)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\twriter.WriteLine(ex.ToString());\n\t\t\t\t\t\t\t\t\texception = ex;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tlock (output)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutput.Write(asm.ShortName + \" - \" + w.Elapsed);\n\t\t\t\t\t\t\t\tif (exception != null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\toutput.Write(\" - \");\n\t\t\t\t\t\t\t\t\toutput.Write(exception.GetType().Name);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\treturn output;\n\t\t\t}, ct)).Then(dockWorkspace.ShowText).HandleExceptions();\n\t\t}\n\t}\n\n\t[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDecompile100x), MenuCategory = nameof(Resources.Open), MenuOrder = 2.6)]\n\t[Shared]\n\tsealed class Decompile100TimesCommand(AssemblyTreeModel assemblyTreeModel, LanguageService languageService, DockWorkspace dockWorkspace) : SimpleCommand\n\t{\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tconst int numRuns = 100;\n\t\t\tvar language = languageService.Language;\n\t\t\tvar nodes = assemblyTreeModel.SelectedNodes.ToArray();\n\t\t\tvar options = dockWorkspace.ActiveTabPage.CreateDecompilationOptions();\n\t\t\tdockWorkspace.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {\n\t\t\t\toptions.CancellationToken = ct;\n\t\t\t\tStopwatch w = Stopwatch.StartNew();\n\t\t\t\tfor (int i = 0; i < numRuns; ++i)\n\t\t\t\t{\n\t\t\t\t\tforeach (var node in nodes)\n\t\t\t\t\t{\n\t\t\t\t\t\tnode.Decompile(language, new PlainTextOutput(), options);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tw.Stop();\n\t\t\t\tAvalonEditTextOutput output = new AvalonEditTextOutput();\n\t\t\t\tdouble msPerRun = w.Elapsed.TotalMilliseconds / numRuns;\n\t\t\t\toutput.Write($\"Average time: {msPerRun.ToString(\"f1\")}ms\\n\");\n\t\t\t\treturn output;\n\t\t\t}, ct)).Then(output => dockWorkspace.ShowText(output)).HandleExceptions();\n\t\t}\n\t}\n}\n\n#endif"
  },
  {
    "path": "ILSpy/Commands/DecompileCommand.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nnamespace ICSharpCode.ILSpy.Commands\n{\n\t[ExportContextMenuEntry(Header = nameof(Resources.Decompile), Order = 10)]\n\t[Shared]\n\tclass DecompileCommand : IContextMenuEntry\n\t{\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn context.Reference?.Reference is IEntity;\n\t\t\treturn context.SelectedTreeNodes.Length == 1 && context.SelectedTreeNodes.All(n => n is IMemberTreeNode);\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn context.Reference?.Reference is IEntity;\n\t\t\tforeach (IMemberTreeNode node in context.SelectedTreeNodes)\n\t\t\t{\n\t\t\t\tif (!IsValidReference(node.Member))\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tbool IsValidReference(object reference)\n\t\t{\n\t\t\treturn reference is IEntity;\n\t\t}\n\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tIEntity selection = null;\n\t\t\tif (context.SelectedTreeNodes?[0] is IMemberTreeNode node)\n\t\t\t{\n\t\t\t\tselection = node.Member;\n\t\t\t}\n\t\t\telse if (context.Reference?.Reference is IEntity entity)\n\t\t\t{\n\t\t\t\tselection = entity;\n\t\t\t}\n\t\t\tif (selection != null)\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(selection));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/DecompileInNewViewCommand.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nusing TomsToolbox.Essentials;\n\nnamespace ICSharpCode.ILSpy.Commands\n{\n\t[ExportContextMenuEntry(Header = nameof(Resources.DecompileToNewPanel), InputGestureText = \"MMB\", Icon = \"images/Search\", Category = nameof(Resources.Analyze), Order = 90)]\n\t[Shared]\n\tinternal sealed class DecompileInNewViewCommand(AssemblyTreeModel assemblyTreeModel, DockWorkspace dockWorkspace) : IContextMenuEntry\n\t{\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\treturn context.SelectedTreeNodes != null || context.Reference?.Reference is IEntity;\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\treturn GetNodes(context).Any();\n\t\t}\n\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tDecompileNodes(GetNodes(context).ToArray());\n\t\t}\n\n\t\tIEnumerable<ILSpyTreeNode> GetNodes(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes != null)\n\t\t\t{\n\t\t\t\tif (context.TreeView.DataContext != assemblyTreeModel)\n\t\t\t\t{\n\t\t\t\t\treturn context.SelectedTreeNodes.OfType<IMemberTreeNode>().Select(FindTreeNode).ExceptNullItems();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn context.SelectedTreeNodes.OfType<ILSpyTreeNode>();\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (context.Reference?.Reference is IEntity entity)\n\t\t\t{\n\t\t\t\tif (assemblyTreeModel.FindTreeNode(entity) is { } node)\n\t\t\t\t{\n\t\t\t\t\treturn new[] { node };\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn Array.Empty<ILSpyTreeNode>();\n\n\t\t\tILSpyTreeNode FindTreeNode(IMemberTreeNode node)\n\t\t\t{\n\t\t\t\tif (node is ILSpyTreeNode ilspyNode)\n\t\t\t\t\treturn ilspyNode;\n\t\t\t\treturn assemblyTreeModel.FindTreeNode(node.Member);\n\t\t\t}\n\t\t}\n\n\t\tvoid DecompileNodes(ILSpyTreeNode[] nodes)\n\t\t{\n\t\t\tif (nodes.Length == 0)\n\t\t\t\treturn;\n\n\t\t\tdockWorkspace.ActiveTabPage = dockWorkspace.AddTabPage();\n\n\t\t\tif (assemblyTreeModel.SelectedItems.SequenceEqual(nodes))\n\t\t\t\tassemblyTreeModel.DecompileSelectedNodes();\n\t\t\telse\n\t\t\t\tassemblyTreeModel.SelectNodes(nodes);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/DelegateCommand.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Input;\n\nnamespace ICSharpCode.ILSpy.Commands\n{\n\tpublic class DelegateCommand : ICommand\n\t{\n\t\tprivate readonly Action action;\n\t\tprivate readonly Func<bool> canExecute;\n\n\t\tpublic event EventHandler CanExecuteChanged {\n\t\t\tadd { CommandManager.RequerySuggested += value; }\n\t\t\tremove { CommandManager.RequerySuggested -= value; }\n\t\t}\n\n\t\tpublic DelegateCommand(Action action)\n\t\t\t: this(action, () => true)\n\t\t{\n\t\t}\n\n\t\tpublic DelegateCommand(Action action, Func<bool> canExecute)\n\t\t{\n\t\t\tthis.action = action;\n\t\t\tthis.canExecute = canExecute;\n\t\t}\n\n\t\tpublic bool CanExecute(object parameter)\n\t\t{\n\t\t\treturn canExecute();\n\t\t}\n\n\t\tpublic void Execute(object parameter)\n\t\t{\n\t\t\taction();\n\t\t}\n\t}\n\n\tpublic class DelegateCommand<T> : ICommand\n\t{\n\t\tprivate readonly Action<T> action;\n\t\tprivate readonly Func<T, bool> canExecute;\n\n\t\tpublic event EventHandler CanExecuteChanged {\n\t\t\tadd { CommandManager.RequerySuggested += value; }\n\t\t\tremove { CommandManager.RequerySuggested -= value; }\n\t\t}\n\n\t\tpublic DelegateCommand(Action<T> action)\n\t\t\t: this(action, _ => true)\n\t\t{\n\t\t}\n\n\t\tpublic DelegateCommand(Action<T> action, Func<T, bool> canExecute)\n\t\t{\n\t\t\tthis.action = action;\n\t\t\tthis.canExecute = canExecute;\n\t\t}\n\n\t\tpublic bool CanExecute(object parameter)\n\t\t{\n\t\t\treturn canExecute((T)parameter);\n\t\t}\n\n\t\tpublic void Execute(object parameter)\n\t\t{\n\t\t\taction((T)parameter);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/DisassembleAllCommand.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#if DEBUG\n\nusing System;\nusing System.Collections.Concurrent;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.ViewModels;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDisassemble), MenuCategory = nameof(Resources.Open), MenuOrder = 2.5)]\n\t[Shared]\n\tsealed class DisassembleAllCommand(AssemblyTreeModel assemblyTreeModel, DockWorkspace dockWorkspace) : SimpleCommand\n\t{\n\t\tpublic override bool CanExecute(object parameter)\n\t\t{\n\t\t\treturn System.IO.Directory.Exists(\"c:\\\\temp\\\\disassembled\");\n\t\t}\n\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tdockWorkspace.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {\n\t\t\t\tAvalonEditTextOutput output = new();\n\t\t\t\tParallel.ForEach(\n\t\t\t\t\tPartitioner.Create(assemblyTreeModel.AssemblyList.GetAssemblies(), loadBalance: true),\n\t\t\t\t\tnew() { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = ct },\n\t\t\t\t\tasm => {\n\t\t\t\t\t\tif (!asm.HasLoadError)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tStopwatch w = Stopwatch.StartNew();\n\t\t\t\t\t\t\tException exception = null;\n\t\t\t\t\t\t\tusing (var writer = new System.IO.StreamWriter(\"c:\\\\temp\\\\disassembled\\\\\" + asm.Text.Replace(\"(\", \"\").Replace(\")\", \"\").Replace(' ', '_') + \".il\"))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tvar options = dockWorkspace.ActiveTabPage.CreateDecompilationOptions();\n\t\t\t\t\t\t\t\t\toptions.FullDecompilation = true;\n\t\t\t\t\t\t\t\t\toptions.CancellationToken = ct;\n\t\t\t\t\t\t\t\t\tnew ILLanguage(dockWorkspace).DecompileAssembly(asm, new Decompiler.PlainTextOutput(writer), options);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch (Exception ex)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\twriter.WriteLine(ex.ToString());\n\t\t\t\t\t\t\t\t\texception = ex;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tlock (output)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutput.Write(asm.ShortName + \" - \" + w.Elapsed);\n\t\t\t\t\t\t\t\tif (exception != null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\toutput.Write(\" - \");\n\t\t\t\t\t\t\t\t\toutput.Write(exception.GetType().Name);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\treturn output;\n\t\t\t}, ct)).Then(dockWorkspace.ShowText).HandleExceptions();\n\t\t}\n\t}\n}\n\n#endif"
  },
  {
    "path": "ILSpy/Commands/ExitCommand.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\nusing System.Composition;\n\nusing ICSharpCode.ILSpy.Properties;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.E_xit), MenuOrder = 99999, MenuCategory = nameof(Resources.Exit))]\n\t[Shared]\n\tsealed class ExitCommand(MainWindow mainWindow) : SimpleCommand\n\t{\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tmainWindow.Close();\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Commands/ExportCommandAttribute.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Composition;\nusing System.Windows.Input;\n\nnamespace ICSharpCode.ILSpy\n{\n\t#region Toolbar\n\tpublic interface IToolbarCommandMetadata\n\t{\n\t\tstring ToolbarIcon { get; }\n\t\tstring ToolTip { get; }\n\t\tstring ToolbarCategory { get; }\n\t\tobject Tag { get; }\n\t\tdouble ToolbarOrder { get; }\n\t}\n\n\t[MetadataAttribute]\n\t[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]\n\tpublic class ExportToolbarCommandAttribute : ExportAttribute, IToolbarCommandMetadata\n\t{\n\t\tpublic ExportToolbarCommandAttribute()\n\t\t\t: base(\"ToolbarCommand\", typeof(ICommand))\n\t\t{\n\t\t}\n\n\t\tpublic string ToolTip { get; set; }\n\t\tpublic string ToolbarIcon { get; set; }\n\t\tpublic string ToolbarCategory { get; set; }\n\t\tpublic double ToolbarOrder { get; set; }\n\t\tpublic object Tag { get; set; }\n\t}\n\t#endregion\n\n\t#region Main Menu\n\tpublic interface IMainMenuCommandMetadata\n\t{\n\t\tstring MenuID { get; }\n\t\tstring MenuIcon { get; }\n\t\tstring Header { get; }\n\t\tstring ParentMenuID { get; }\n\t\tstring MenuCategory { get; }\n\t\tstring InputGestureText { get; }\n\t\tbool IsEnabled { get; }\n\t\tdouble MenuOrder { get; }\n\t}\n\n\t[MetadataAttribute]\n\t[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]\n\tpublic class ExportMainMenuCommandAttribute : ExportAttribute, IMainMenuCommandMetadata\n\t{\n\t\tpublic ExportMainMenuCommandAttribute()\n\t\t\t: base(\"MainMenuCommand\", typeof(ICommand))\n\t\t{\n\t\t}\n\t\t/// <summary>\n\t\t/// Gets/Sets the ID of this menu item. Menu entries are not required to have an ID,\n\t\t/// however, setting it allows to declare nested menu structures.\n\t\t/// The built-in menus have the IDs \"_File\", \"_View\", \"_Window\" and \"_Help\".\n\t\t/// Plugin authors are advised to use GUIDs as identifiers to prevent conflicts.\n\t\t/// <para/>\n\t\t/// NOTE: Defining cycles (for example by accidentally setting <see cref=\"MenuID\"/> equal to <see cref=\"ParentMenuID\"/>)\n\t\t/// will lead to a stack-overflow and crash of ILSpy at startup.\n\t\t/// </summary>\n\t\tpublic string MenuID { get; set; }\n\t\tpublic string MenuIcon { get; set; }\n\t\tpublic string Header { get; set; }\n\t\t/// <summary>\n\t\t/// Gets/Sets the parent of this menu item. All menu items sharing the same parent will be displayed as sub-menu items.\n\t\t/// If this property is set to <see langword=\"null\"/>, the menu item is displayed in the top-level menu.\n\t\t/// The built-in menus have the IDs \"_File\", \"_View\", \"_Window\" and \"_Help\".\n\t\t/// <para/>\n\t\t/// NOTE: Defining cycles (for example by accidentally setting <see cref=\"MenuID\"/> equal to <see cref=\"ParentMenuID\"/>)\n\t\t/// will lead to a stack-overflow and crash of ILSpy at startup.\n\t\t/// </summary>\n\t\tpublic string ParentMenuID { get; set; }\n\t\tpublic string MenuCategory { get; set; }\n\t\tpublic string InputGestureText { get; set; }\n\t\tpublic bool IsEnabled { get; set; } = true;\n\t\tpublic double MenuOrder { get; set; }\n\t}\n\t#endregion\n\n\t#region Tool Panes\n\n\t[MetadataAttribute]\n\t[AttributeUsage(AttributeTargets.Class)]\n\tpublic class ExportToolPaneAttribute : ExportAttribute\n\t{\n\t\tpublic ExportToolPaneAttribute()\n\t\t\t: base(\"ToolPane\", typeof(ViewModels.ToolPaneModel))\n\t\t{\n\t\t}\n\t}\n\t#endregion\n}\n"
  },
  {
    "path": "ILSpy/Commands/ExtractPackageEntryContextMenuEntry.cs",
    "content": "// Copyright (c) 2021 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Windows;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.CSharp.ProjectDecompiler;\nusing ICSharpCode.Decompiler.Util;\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.TreeView;\n\nusing Microsoft.Win32;\n\nusing static ICSharpCode.ILSpyX.LoadedPackage;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportContextMenuEntry(Header = nameof(Resources.ExtractPackageEntry), Category = nameof(Resources.Save), Icon = \"Images/Save\")]\n\t[Shared]\n\tsealed class ExtractPackageEntryContextMenuEntry(DockWorkspace dockWorkspace) : IContextMenuEntry\n\t{\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tvar selectedNodes = Array.FindAll(context.SelectedTreeNodes, IsBundleItem);\n\t\t\t// Get root assembly to infer the initial directory for the save dialog.\n\t\t\tvar bundleNode = selectedNodes.FirstOrDefault()?.Ancestors().OfType<AssemblyTreeNode>()\n\t\t\t\t.FirstOrDefault(asm => asm.PackageEntry == null);\n\t\t\tif (bundleNode == null)\n\t\t\t\treturn;\n\t\t\tif (selectedNodes is [AssemblyTreeNode { PackageEntry: { } assembly }])\n\t\t\t{\n\t\t\t\tSaveFileDialog dlg = new SaveFileDialog();\n\t\t\t\tdlg.FileName = Path.GetFileName(WholeProjectDecompiler.SanitizeFileName(assembly.Name));\n\t\t\t\tdlg.Filter = \".NET assemblies|*.dll;*.exe;*.winmd\" + Resources.AllFiles;\n\t\t\t\tdlg.InitialDirectory = Path.GetDirectoryName(bundleNode.LoadedAssembly.FileName);\n\t\t\t\tif (dlg.ShowDialog() == true)\n\t\t\t\t\tSave(dockWorkspace, selectedNodes, dlg.FileName, true);\n\t\t\t}\n\t\t\telse if (selectedNodes is [ResourceTreeNode { Resource: { } resource }])\n\t\t\t{\n\t\t\t\tSaveFileDialog dlg = new SaveFileDialog();\n\t\t\t\tdlg.FileName = Path.GetFileName(WholeProjectDecompiler.SanitizeFileName(resource.Name));\n\t\t\t\tdlg.Filter = Resources.AllFiles[1..];\n\t\t\t\tdlg.InitialDirectory = Path.GetDirectoryName(bundleNode.LoadedAssembly.FileName);\n\t\t\t\tif (dlg.ShowDialog() == true)\n\t\t\t\t\tSave(dockWorkspace, selectedNodes, dlg.FileName, true);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tOpenFolderDialog dlg = new OpenFolderDialog();\n\t\t\t\tdlg.InitialDirectory = Path.GetDirectoryName(bundleNode.LoadedAssembly.FileName);\n\t\t\t\tif (dlg.ShowDialog() != true)\n\t\t\t\t\treturn;\n\n\t\t\t\tstring folderName = dlg.FolderName;\n\t\t\t\tif (Directory.EnumerateFileSystemEntries(folderName).Any())\n\t\t\t\t{\n\t\t\t\t\tvar result = MessageBox.Show(\n\t\t\t\t\t\tResources.AssemblySaveCodeDirectoryNotEmpty,\n\t\t\t\t\t\tResources.AssemblySaveCodeDirectoryNotEmptyTitle,\n\t\t\t\t\t\tMessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No);\n\t\t\t\t\tif (result == MessageBoxResult.No)\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tSave(dockWorkspace, selectedNodes, folderName, false);\n\t\t\t}\n\t\t}\n\n\t\tinternal static void Save(DockWorkspace dockWorkspace, ICollection<SharpTreeNode> nodes, string path, bool isFile)\n\t\t{\n\t\t\tdockWorkspace.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {\n\t\t\t\tAvalonEditTextOutput output = new AvalonEditTextOutput();\n\t\t\t\tStopwatch stopwatch = Stopwatch.StartNew();\n\t\t\t\tDictionary<string, int> fileNameCounts = new Dictionary<string, int>(Platform.FileNameComparer);\n\t\t\t\tforeach (var (entry, fileName) in CollectAllFiles(nodes))\n\t\t\t\t{\n\t\t\t\t\tstring actualFileName = WholeProjectDecompiler.SanitizeFileName(fileName);\n\t\t\t\t\twhile (fileNameCounts.TryGetValue(actualFileName, out int index))\n\t\t\t\t\t{\n\t\t\t\t\t\tindex++;\n\t\t\t\t\t\tfileNameCounts[actualFileName] = index;\n\t\t\t\t\t\tactualFileName = Path.ChangeExtension(actualFileName, index + Path.GetExtension(actualFileName));\n\t\t\t\t\t}\n\t\t\t\t\tif (!fileNameCounts.ContainsKey(actualFileName))\n\t\t\t\t\t{\n\t\t\t\t\t\tfileNameCounts[actualFileName] = 1;\n\t\t\t\t\t}\n\t\t\t\t\tSaveEntry(output, entry, Path.Combine(path, actualFileName));\n\t\t\t\t}\n\t\t\t\tstopwatch.Stop();\n\t\t\t\toutput.WriteLine(Resources.GenerationCompleteInSeconds, stopwatch.Elapsed.TotalSeconds.ToString(\"F1\"));\n\t\t\t\toutput.WriteLine();\n\t\t\t\t// If we have written files, open explorer and select them grouped by folder; otherwise fall back to opening containing folder.\n\t\t\t\tif (isFile && File.Exists(path))\n\t\t\t\t\toutput.AddButton(null, Resources.OpenExplorer, delegate { ShellHelper.OpenFolderAndSelectItem(path); });\n\t\t\t\telse\n\t\t\t\t\toutput.AddButton(null, Resources.OpenExplorer, delegate { ShellHelper.OpenFolder(path); });\n\t\t\t\toutput.WriteLine();\n\t\t\t\treturn output;\n\t\t\t}, ct)).Then(dockWorkspace.ShowText).HandleExceptions();\n\n\t\t\tstatic IEnumerable<(PackageEntry Entry, string TargetFileName)> CollectAllFiles(ICollection<SharpTreeNode> nodes)\n\t\t\t{\n\t\t\t\tforeach (var node in nodes)\n\t\t\t\t{\n\t\t\t\t\tif (node is AssemblyTreeNode { PackageEntry: { } assembly })\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return (assembly, Path.GetFileName(assembly.FullName));\n\t\t\t\t\t}\n\t\t\t\t\telse if (node is ResourceTreeNode { Resource: PackageEntry { } resource })\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return (resource, Path.GetFileName(resource.FullName));\n\t\t\t\t\t}\n\t\t\t\t\telse if (node is AssemblyTreeNode { PackageKind: not null } asm)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar package = asm.LoadedAssembly.GetLoadResultAsync().GetAwaiter().GetResult().Package;\n\t\t\t\t\t\tforeach (var entry in package.Entries)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tyield return (entry, entry.FullName);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (node is PackageFolderTreeNode folder)\n\t\t\t\t\t{\n\t\t\t\t\t\tint prefixLength = 0;\n\t\t\t\t\t\tPackageFolder current = folder.Folder;\n\t\t\t\t\t\tif (nodes.Count > 1)\n\t\t\t\t\t\t\tcurrent = current.Parent;\n\t\t\t\t\t\twhile (current != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tprefixLength += current.Name.Length + 1;\n\t\t\t\t\t\t\tcurrent = current.Parent;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (prefixLength > 0)\n\t\t\t\t\t\t\tprefixLength--;\n\t\t\t\t\t\tforeach (var item in TreeTraversal.PreOrder(folder.Folder, f => f.Folders).SelectMany(f => f.Entries))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tyield return (item, item.FullName.Substring(prefixLength));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic void SaveEntry(ITextOutput output, PackageEntry entry, string targetFileName)\n\t\t{\n\t\t\toutput.Write(entry.Name + \": \");\n\t\t\tusing Stream stream = entry.TryOpenStream();\n\t\t\tif (stream == null)\n\t\t\t{\n\t\t\t\toutput.WriteLine(\"Could not open stream!\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tDirectory.CreateDirectory(Path.GetDirectoryName(targetFileName));\n\n\t\t\tstream.Position = 0;\n\t\t\tusing FileStream fileStream = new FileStream(targetFileName, FileMode.OpenOrCreate);\n\t\t\tstream.CopyTo(fileStream);\n\t\t\toutput.WriteLine(\"Written to \" + targetFileName);\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context) => true;\n\n\t\tpublic bool IsVisible(TextViewContext context) => context.SelectedTreeNodes?.Any(IsBundleItem) == true;\n\n\t\tstatic bool IsBundleItem(SharpTreeNode node)\n\t\t{\n\t\t\tif (node is AssemblyTreeNode { PackageEntry: { } } or PackageFolderTreeNode)\n\t\t\t\treturn true;\n\t\t\tif (node is ResourceTreeNode { Resource: PackageEntry { } resource } && resource.PackageQualifiedFileName.StartsWith(\"bundle://\"))\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t[ExportContextMenuEntry(Header = nameof(Resources.ExtractAllPackageEntries), Category = nameof(Resources.Save), Icon = \"Images/Save\")]\n\t[Shared]\n\tsealed class ExtractAllPackageEntriesContextMenuEntry(DockWorkspace dockWorkspace) : IContextMenuEntry\n\t{\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes is not [AssemblyTreeNode { PackageEntry: null } asm])\n\t\t\t\treturn;\n\t\t\tOpenFolderDialog dlg = new OpenFolderDialog();\n\t\t\tdlg.InitialDirectory = Path.GetDirectoryName(asm.LoadedAssembly.FileName);\n\t\t\tif (dlg.ShowDialog() != true)\n\t\t\t\treturn;\n\n\t\t\tstring folderName = dlg.FolderName;\n\t\t\tif (Directory.EnumerateFileSystemEntries(folderName).Any())\n\t\t\t{\n\t\t\t\tvar result = MessageBox.Show(\n\t\t\t\t\tResources.AssemblySaveCodeDirectoryNotEmpty,\n\t\t\t\t\tResources.AssemblySaveCodeDirectoryNotEmptyTitle,\n\t\t\t\t\tMessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No);\n\t\t\t\tif (result == MessageBoxResult.No)\n\t\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tExtractPackageEntryContextMenuEntry.Save(dockWorkspace, [asm], folderName, false);\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context) => true;\n\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\treturn context.SelectedTreeNodes is [AssemblyTreeNode { PackageEntry: null, PackageKind: PackageKind.Bundle }];\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/GeneratePdbContextMenuEntry.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Windows;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.CSharp.ProjectDecompiler;\nusing ICSharpCode.Decompiler.DebugInfo;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX;\n\nusing Microsoft.Win32;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportContextMenuEntry(Header = nameof(Resources.GeneratePortable))]\n\t[Shared]\n\tclass GeneratePdbContextMenuEntry(LanguageService languageService, DockWorkspace dockWorkspace) : IContextMenuEntry\n\t{\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tvar selectedNodes = context.SelectedTreeNodes?.OfType<AssemblyTreeNode>().ToArray();\n\t\t\tif (selectedNodes == null || selectedNodes.Length == 0)\n\t\t\t\treturn;\n\n\t\t\tGeneratePdbForAssemblies(selectedNodes.Select(n => n.LoadedAssembly), languageService, dockWorkspace);\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context) => true;\n\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\tvar selectedNodes = context.SelectedTreeNodes;\n\t\t\treturn selectedNodes?.Any() == true\n\t\t\t\t&& selectedNodes.All(n => n is AssemblyTreeNode asm && asm.LoadedAssembly.IsLoadedAsValidAssembly);\n\t\t}\n\n\t\tinternal static void GeneratePdbForAssemblies(IEnumerable<LoadedAssembly> assemblies, LanguageService languageService, DockWorkspace dockWorkspace)\n\t\t{\n\t\t\tvar assemblyArray = assemblies?.Where(a => a != null).ToArray() ?? [];\n\t\t\tif (assemblyArray == null || assemblyArray.Length == 0)\n\t\t\t\treturn;\n\n\t\t\t// Ensure at least one assembly supports PDB generation\n\t\t\tvar supported = new Dictionary<LoadedAssembly, PEFile>();\n\t\t\tvar unsupported = new List<LoadedAssembly>();\n\t\t\tforeach (var a in assemblyArray)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tvar file = a.GetMetadataFileOrNull() as PEFile;\n\t\t\t\t\tif (PortablePdbWriter.HasCodeViewDebugDirectoryEntry(file))\n\t\t\t\t\t\tsupported.Add(a, file);\n\t\t\t\t\telse\n\t\t\t\t\t\tunsupported.Add(a);\n\t\t\t\t}\n\t\t\t\tcatch\n\t\t\t\t{\n\t\t\t\t\tunsupported.Add(a);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (supported.Count == 0)\n\t\t\t{\n\t\t\t\t// none can be generated\n\t\t\t\tstring msg = string.Format(Resources.CannotCreatePDBFile, \":\" + Environment.NewLine +\n\t\t\t\t\tstring.Join(Environment.NewLine, unsupported.Select(u => Path.GetFileName(u.FileName)))\n\t\t\t\t\t+ Environment.NewLine);\n\t\t\t\tMessageBox.Show(msg);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Ask for target folder\n\t\t\tvar dlg = new OpenFolderDialog();\n\t\t\tdlg.Title = Resources.SelectPDBOutputFolder;\n\t\t\tif (dlg.ShowDialog() != true || string.IsNullOrWhiteSpace(dlg.FolderName))\n\t\t\t\treturn;\n\n\t\t\tstring targetFolder = dlg.FolderName;\n\t\t\tDecompilationOptions options = dockWorkspace.ActiveTabPage.CreateDecompilationOptions();\n\n\t\t\tdockWorkspace.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {\n\t\t\t\tAvalonEditTextOutput output = new AvalonEditTextOutput();\n\t\t\t\tStopwatch totalWatch = Stopwatch.StartNew();\n\t\t\t\toptions.CancellationToken = ct;\n\n\t\t\t\tint total = assemblyArray.Length;\n\t\t\t\tint processed = 0;\n\t\t\t\tforeach (var assembly in assemblyArray)\n\t\t\t\t{\n\t\t\t\t\t// only process supported assemblies\n\t\t\t\t\tif (!supported.TryGetValue(assembly, out var file))\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.WriteLine(string.Format(Resources.CannotCreatePDBFile, Path.GetFileName(assembly.FileName)));\n\t\t\t\t\t\tprocessed++;\n\t\t\t\t\t\tif (options.Progress != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toptions.Progress.Report(new DecompilationProgress {\n\t\t\t\t\t\t\t\tTitle = string.Format(Resources.GeneratingPortablePDB, Path.GetFileName(assembly.FileName)),\n\t\t\t\t\t\t\t\tTotalUnits = total,\n\t\t\t\t\t\t\t\tUnitsCompleted = processed\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tstring fileName = Path.Combine(targetFolder, WholeProjectDecompiler.CleanUpFileName(assembly.ShortName, \".pdb\"));\n\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tusing (FileStream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar decompiler = new CSharpDecompiler(file, assembly.GetAssemblyResolver(options.DecompilerSettings.AutoLoadAssemblyReferences), options.DecompilerSettings);\n\t\t\t\t\t\t\tdecompiler.CancellationToken = ct;\n\t\t\t\t\t\t\tPortablePdbWriter.WritePdb(file, decompiler, options.DecompilerSettings, stream, progress: options.Progress, currentProgressTitle: string.Format(Resources.GeneratingPortablePDB, Path.GetFileName(assembly.FileName)));\n\t\t\t\t\t\t}\n\t\t\t\t\t\toutput.WriteLine(string.Format(Resources.GeneratedPDBFile, fileName));\n\t\t\t\t\t}\n\t\t\t\t\tcatch (OperationCanceledException)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t\toutput.WriteLine(Resources.GenerationWasCancelled);\n\t\t\t\t\t\tthrow;\n\t\t\t\t\t}\n\t\t\t\t\tcatch (Exception ex)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.WriteLine(string.Format(Resources.GenerationFailedForAssembly, assembly.FileName, ex.Message));\n\t\t\t\t\t}\n\t\t\t\t\tprocessed++;\n\t\t\t\t\tif (options.Progress != null)\n\t\t\t\t\t{\n\t\t\t\t\t\toptions.Progress.Report(new DecompilationProgress {\n\t\t\t\t\t\t\tTitle = string.Format(Resources.GeneratingPortablePDB, Path.GetFileName(assembly.FileName)),\n\t\t\t\t\t\t\tTotalUnits = total,\n\t\t\t\t\t\t\tUnitsCompleted = processed\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\ttotalWatch.Stop();\n\t\t\t\toutput.WriteLine();\n\t\t\t\toutput.WriteLine(Resources.GenerationCompleteInSeconds, totalWatch.Elapsed.TotalSeconds.ToString(\"F1\"));\n\t\t\t\toutput.WriteLine();\n\t\t\t\t// Select all generated pdb files in explorer\n\t\t\t\tvar generatedFiles = assemblyArray\n\t\t\t\t\t.Select(a => Path.Combine(targetFolder, WholeProjectDecompiler.CleanUpFileName(a.ShortName, \".pdb\")))\n\t\t\t\t\t.Where(File.Exists)\n\t\t\t\t\t.ToList();\n\t\t\t\tif (generatedFiles.Any())\n\t\t\t\t{\n\t\t\t\t\toutput.AddButton(null, Resources.OpenExplorer, delegate { ShellHelper.OpenFolderAndSelectItems(generatedFiles); });\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\toutput.AddButton(null, Resources.OpenExplorer, delegate { ShellHelper.OpenFolder(targetFolder); });\n\t\t\t\t}\n\t\t\t\toutput.WriteLine();\n\t\t\t\treturn output;\n\t\t\t}, ct)).Then(dockWorkspace.ShowText).HandleExceptions();\n\t\t}\n\t}\n\n\t[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.GeneratePortable), MenuCategory = nameof(Resources.Save))]\n\t[Shared]\n\tclass GeneratePdbMainMenuEntry(AssemblyTreeModel assemblyTreeModel, LanguageService languageService, DockWorkspace dockWorkspace) : SimpleCommand\n\t{\n\t\tpublic override bool CanExecute(object parameter)\n\t\t{\n\t\t\treturn assemblyTreeModel.SelectedNodes?.Any() == true\n\t\t\t\t&& assemblyTreeModel.SelectedNodes?.All(n => n is AssemblyTreeNode tn && !tn.LoadedAssembly.HasLoadError) == true;\n\t\t}\n\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tvar selectedNodes = assemblyTreeModel.SelectedNodes?.OfType<AssemblyTreeNode>().ToArray();\n\t\t\tif (selectedNodes == null || selectedNodes.Length == 0)\n\t\t\t\treturn;\n\n\t\t\tGeneratePdbContextMenuEntry.GeneratePdbForAssemblies(selectedNodes.Select(n => n.LoadedAssembly), languageService, dockWorkspace);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/IProtocolHandler.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nnamespace ICSharpCode.ILSpy\n{\n\tpublic interface IProtocolHandler\n\t{\n\t\tILSpyTreeNode Resolve(string protocol, MetadataFile module, Handle handle, out bool newTabPage);\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/ManageAssemblyListsCommand.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Windows;\nusing System.Windows.Data;\n\nusing ICSharpCode.ILSpy.Properties;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.ManageAssembly_Lists), MenuIcon = \"Images/AssemblyList\", MenuCategory = nameof(Resources.Open), MenuOrder = 1.7)]\n\t[Shared]\n\tsealed class ManageAssemblyListsCommand(SettingsService settingsService) : SimpleCommand, IProvideParameterBinding\n\t{\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tManageAssemblyListsDialog dlg = new(settingsService) {\n\t\t\t\tOwner = parameter as Window\n\t\t\t};\n\n\t\t\tdlg.ShowDialog();\n\t\t}\n\n\t\tpublic Binding ParameterBinding => new() {\n\t\t\tRelativeSource = new(RelativeSourceMode.FindAncestor) {\n\t\t\t\tAncestorType = typeof(Window)\n\t\t\t}\n\t\t};\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/OpenCommand.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Windows.Input;\n\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Properties;\n\nusing Microsoft.Win32;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportToolbarCommand(ToolTip = nameof(Resources.Open), ToolbarIcon = \"Images/Open\", ToolbarCategory = nameof(Resources.Open), ToolbarOrder = 0)]\n\t[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources._Open), MenuIcon = \"Images/Open\", MenuCategory = nameof(Resources.Open), MenuOrder = 0)]\n\t[Shared]\n\tsealed class OpenCommand : CommandWrapper\n\t{\n\t\tprivate readonly AssemblyTreeModel assemblyTreeModel;\n\n\t\tpublic OpenCommand(AssemblyTreeModel assemblyTreeModel)\n\t\t\t: base(ApplicationCommands.Open)\n\t\t{\n\t\t\tthis.assemblyTreeModel = assemblyTreeModel;\n\t\t}\n\n\t\tprotected override void OnExecute(object sender, ExecutedRoutedEventArgs e)\n\t\t{\n\t\t\te.Handled = true;\n\t\t\tOpenFileDialog dlg = new OpenFileDialog {\n\t\t\t\tFilter = \".NET assemblies|*.dll;*.exe;*.winmd;*.wasm|Nuget Packages (*.nupkg)|*.nupkg|Portable Program Database (*.pdb)|*.pdb|All files|*.*\",\n\t\t\t\tMultiselect = true,\n\t\t\t\tRestoreDirectory = true\n\t\t\t};\n\n\t\t\tif (dlg.ShowDialog() == true)\n\t\t\t{\n\t\t\t\tassemblyTreeModel.OpenFiles(dlg.FileNames);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/OpenFromGacCommand.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\n\nusing ICSharpCode.ILSpy.AppEnv;\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Properties;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.OpenFrom_GAC), MenuIcon = \"Images/AssemblyListGAC\", MenuCategory = nameof(Resources.Open), MenuOrder = 1)]\n\t[Shared]\n\tsealed class OpenFromGacCommand(AssemblyTreeModel assemblyTreeModel, MainWindow mainWindow) : SimpleCommand\n\t{\n\t\tpublic override bool CanExecute(object parameter)\n\t\t{\n\t\t\treturn AppEnvironment.IsWindows;\n\t\t}\n\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tOpenFromGacDialog dlg = new() {\n\t\t\t\tOwner = mainWindow\n\t\t\t};\n\n\t\t\tif (dlg.ShowDialog() == true)\n\t\t\t{\n\t\t\t\tassemblyTreeModel.OpenFiles(dlg.SelectedFileNames);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/Pdb2XmlCommand.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#if DEBUG\n\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nusing Microsoft.DiaSymReader.Tools;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDumpPDBAsXML), MenuCategory = nameof(Resources.Open), MenuOrder = 2.6)]\n\t[Shared]\n\tsealed class Pdb2XmlCommand(AssemblyTreeModel assemblyTreeModel, DockWorkspace dockWorkspace) : SimpleCommand\n\t{\n\t\tpublic override bool CanExecute(object parameter)\n\t\t{\n\t\t\tvar selectedNodes = assemblyTreeModel.SelectedNodes;\n\t\t\treturn selectedNodes?.Any() == true\n\t\t\t\t&& selectedNodes.All(n => n is AssemblyTreeNode asm && !asm.LoadedAssembly.HasLoadError);\n\t\t}\n\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tExecute(assemblyTreeModel.SelectedNodes.OfType<AssemblyTreeNode>(), dockWorkspace);\n\t\t}\n\n\t\tinternal static void Execute(IEnumerable<AssemblyTreeNode> nodes, DockWorkspace dockWorkspace)\n\t\t{\n\t\t\tvar highlighting = HighlightingManager.Instance.GetDefinitionByExtension(\".xml\");\n\t\t\tvar options = PdbToXmlOptions.IncludeEmbeddedSources | PdbToXmlOptions.IncludeMethodSpans | PdbToXmlOptions.IncludeTokens;\n\t\t\tdockWorkspace.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {\n\t\t\t\tAvalonEditTextOutput output = new AvalonEditTextOutput();\n\t\t\t\tvar writer = new TextOutputWriter(output);\n\t\t\t\tforeach (var node in nodes)\n\t\t\t\t{\n\t\t\t\t\tstring pdbFileName = Path.ChangeExtension(node.LoadedAssembly.FileName, \".pdb\");\n\t\t\t\t\tif (!File.Exists(pdbFileName))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tusing (var pdbStream = File.OpenRead(pdbFileName))\n\t\t\t\t\tusing (var peStream = File.OpenRead(node.LoadedAssembly.FileName))\n\t\t\t\t\t\tPdbToXmlConverter.ToXml(writer, pdbStream, peStream, options);\n\t\t\t\t}\n\t\t\t\treturn output;\n\t\t\t}, ct)).Then(output => dockWorkspace.ShowNodes(output, null, highlighting)).HandleExceptions();\n\t\t}\n\t}\n\n\t[ExportContextMenuEntry(Header = nameof(Resources.DEBUGDumpPDBAsXML))]\n\t[Shared]\n\tclass Pdb2XmlCommandContextMenuEntry(DockWorkspace dockWorkspace) : IContextMenuEntry\n\t{\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tPdb2XmlCommand.Execute(context.SelectedTreeNodes.OfType<AssemblyTreeNode>(), dockWorkspace);\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context) => true;\n\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\tvar selectedNodes = context.SelectedTreeNodes;\n\t\t\treturn selectedNodes?.Any() == true\n\t\t\t\t&& selectedNodes.All(n => n is AssemblyTreeNode asm && asm.LoadedAssembly.IsLoadedAsValidAssembly);\n\t\t}\n\t}\n\n}\n\n#endif\n"
  },
  {
    "path": "ILSpy/Commands/RefreshCommand.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Windows.Input;\n\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Properties;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportToolbarCommand(ToolTip = nameof(Resources.RefreshCommand_ReloadAssemblies), ToolbarIcon = \"Images/Refresh\", ToolbarCategory = nameof(Resources.Open), ToolbarOrder = 2)]\n\t[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources._Reload), MenuIcon = \"Images/Refresh\", MenuCategory = nameof(Resources.Open), MenuOrder = 2)]\n\t[Shared]\n\tsealed class RefreshCommand : CommandWrapper\n\t{\n\t\tprivate readonly AssemblyTreeModel assemblyTreeModel;\n\n\t\tpublic RefreshCommand(AssemblyTreeModel assemblyTreeModel)\n\t\t\t: base(NavigationCommands.Refresh)\n\t\t{\n\t\t\tthis.assemblyTreeModel = assemblyTreeModel;\n\t\t}\n\n\t\tprotected override void OnExecute(object sender, ExecutedRoutedEventArgs e)\n\t\t{\n\t\t\tassemblyTreeModel.Refresh();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/RemoveAssembliesWithLoadErrors.cs",
    "content": "// Copyright (c) 2018 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Linq;\n\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Properties;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources._RemoveAssembliesWithLoadErrors), MenuCategory = nameof(Resources.Remove), MenuOrder = 2.6)]\n\t[Shared]\n\tclass RemoveAssembliesWithLoadErrors(AssemblyTreeModel assemblyTreeModel) : SimpleCommand\n\t{\n\t\tpublic override bool CanExecute(object parameter)\n\t\t{\n\t\t\treturn assemblyTreeModel.AssemblyList.GetAssemblies().Any(l => l.HasLoadError);\n\t\t}\n\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tforeach (var assembly in assemblyTreeModel.AssemblyList.GetAssemblies())\n\t\t\t{\n\t\t\t\tif (!assembly.HasLoadError)\n\t\t\t\t\tcontinue;\n\t\t\t\tvar node = assemblyTreeModel.FindAssemblyNode(assembly);\n\t\t\t\tif (node != null && node.CanDelete())\n\t\t\t\t\tnode.Delete();\n\t\t\t}\n\t\t}\n\t}\n\n\t[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.ClearAssemblyList), MenuCategory = nameof(Resources.Remove), MenuOrder = 2.6)]\n\t[Shared]\n\tclass ClearAssemblyList : SimpleCommand\n\t{\n\t\tprivate readonly AssemblyTreeModel assemblyTreeModel;\n\n\t\tpublic ClearAssemblyList(AssemblyTreeModel assemblyTreeModel)\n\t\t{\n\t\t\tthis.assemblyTreeModel = assemblyTreeModel;\n\t\t}\n\n\t\tpublic override bool CanExecute(object parameter)\n\t\t{\n\t\t\treturn assemblyTreeModel.AssemblyList.Count > 0;\n\t\t}\n\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tassemblyTreeModel.AssemblyList.Clear();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/SaveCodeContextMenuEntry.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.IO;\nusing System.Linq;\nusing System.Windows;\n\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX.TreeView;\n\nusing Microsoft.Win32;\n\nnamespace ICSharpCode.ILSpy.TextView\n{\n\t[ExportContextMenuEntry(Header = nameof(Resources._SaveCode), Category = nameof(Resources.Save), Icon = \"Images/Save\")]\n\t[Shared]\n\tsealed class SaveCodeContextMenuEntry(LanguageService languageService, DockWorkspace dockWorkspace) : IContextMenuEntry\n\t{\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tExecute(context.SelectedTreeNodes, languageService, dockWorkspace);\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context) => true;\n\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\treturn CanExecute(context.SelectedTreeNodes);\n\t\t}\n\n\t\tpublic static bool CanExecute(IReadOnlyList<SharpTreeNode> selectedNodes)\n\t\t{\n\t\t\tif (selectedNodes == null || selectedNodes.Any(n => !(n is ILSpyTreeNode)))\n\t\t\t\treturn false;\n\t\t\treturn selectedNodes.Count == 1\n\t\t\t\t|| (selectedNodes.Count > 1 && (selectedNodes.All(n => n is AssemblyTreeNode) || selectedNodes.All(n => n is IMemberTreeNode)));\n\t\t}\n\n\t\tpublic static void Execute(IReadOnlyList<SharpTreeNode> selectedNodes, LanguageService languageService, DockWorkspace dockWorkspace)\n\t\t{\n\t\t\tvar currentLanguage = languageService.Language;\n\t\t\tvar tabPage = dockWorkspace.ActiveTabPage;\n\t\t\ttabPage.ShowTextView(textView => {\n\t\t\t\tif (selectedNodes.Count == 1 && selectedNodes[0] is ILSpyTreeNode singleSelection)\n\t\t\t\t{\n\t\t\t\t\t// if there's only one treenode selected\n\t\t\t\t\t// we will invoke the custom Save logic\n\t\t\t\t\tif (singleSelection.Save(tabPage))\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\telse if (selectedNodes.Count > 1 && selectedNodes.All(n => n is AssemblyTreeNode { LoadedAssembly.IsLoadedAsValidAssembly: true }))\n\t\t\t\t{\n\t\t\t\t\tvar selectedPath = SelectSolutionFile();\n\n\t\t\t\t\tif (!string.IsNullOrEmpty(selectedPath))\n\t\t\t\t\t{\n\t\t\t\t\t\tvar assemblies = selectedNodes.OfType<AssemblyTreeNode>()\n\t\t\t\t\t\t\t.Select(n => n.LoadedAssembly)\n\t\t\t\t\t\t\t.Where(a => a.IsLoadedAsValidAssembly).ToList();\n\t\t\t\t\t\tSolutionWriter.CreateSolution(tabPage, textView, selectedPath, currentLanguage, assemblies);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Fallback: if nobody was able to handle the request, use default behavior.\n\t\t\t\t// try to save all nodes to disk.\n\t\t\t\tvar options = dockWorkspace.ActiveTabPage.CreateDecompilationOptions();\n\t\t\t\toptions.FullDecompilation = true;\n\t\t\t\ttextView.SaveToDisk(currentLanguage, selectedNodes.OfType<ILSpyTreeNode>(), options);\n\t\t\t});\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Shows a File Selection dialog where the user can select the target file for the solution.\n\t\t/// </summary>\n\t\t/// <param name=\"path\">The initial path to show in the dialog. If not specified, the 'Documents' directory\n\t\t/// will be used.</param>\n\t\t/// \n\t\t/// <returns>The full path of the selected target file, or <c>null</c> if the user canceled.</returns>\n\t\tstatic string SelectSolutionFile()\n\t\t{\n\t\t\tSaveFileDialog dlg = new SaveFileDialog();\n\t\t\tdlg.FileName = \"Solution.sln\";\n\t\t\tdlg.Filter = Resources.VisualStudioSolutionFileSlnAllFiles;\n\n\t\t\tif (dlg.ShowDialog() != true)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tstring selectedPath = Path.GetDirectoryName(dlg.FileName);\n\t\t\tbool directoryNotEmpty;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tdirectoryNotEmpty = Directory.EnumerateFileSystemEntries(selectedPath).Any();\n\t\t\t}\n\t\t\tcatch (Exception e) when (e is IOException || e is UnauthorizedAccessException || e is System.Security.SecurityException)\n\t\t\t{\n\t\t\t\tMessageBox.Show(\n\t\t\t\t\t\"The directory cannot be accessed. Please ensure it exists and you have sufficient rights to access it.\",\n\t\t\t\t\t\"Solution directory not accessible\",\n\t\t\t\t\tMessageBoxButton.OK, MessageBoxImage.Error);\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif (directoryNotEmpty)\n\t\t\t{\n\t\t\t\tvar result = MessageBox.Show(\n\t\t\t\t\tResources.AssemblySaveCodeDirectoryNotEmpty,\n\t\t\t\t\tResources.AssemblySaveCodeDirectoryNotEmptyTitle,\n\t\t\t\t\tMessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No);\n\t\t\t\tif (result == MessageBoxResult.No)\n\t\t\t\t\treturn null; // -> abort\n\t\t\t}\n\n\t\t\treturn dlg.FileName;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/SaveCommand.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Linq;\nusing System.Windows.Input;\n\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TextView;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources._SaveCode), MenuIcon = \"Images/Save\", MenuCategory = nameof(Resources.Save), MenuOrder = 0)]\n\t[Shared]\n\tsealed class SaveCommand(AssemblyTreeModel assemblyTreeModel, LanguageService languageService, DockWorkspace dockWorkspace) : CommandWrapper(ApplicationCommands.Save)\n\t{\n\t\tprotected override void OnCanExecute(object sender, CanExecuteRoutedEventArgs e)\n\t\t{\n\t\t\te.Handled = true;\n\t\t\te.CanExecute = SaveCodeContextMenuEntry.CanExecute(assemblyTreeModel.SelectedNodes.ToList());\n\t\t}\n\n\t\tprotected override void OnExecute(object sender, ExecutedRoutedEventArgs e)\n\t\t{\n\t\t\tSaveCodeContextMenuEntry.Execute(assemblyTreeModel.SelectedNodes.ToList(), languageService, dockWorkspace);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/ScopeSearchToAssembly.cs",
    "content": "// Copyright (c) 2021 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n#nullable enable\n\nusing System;\nusing System.Composition;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.AppEnv;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.Search;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportContextMenuEntry(Header = nameof(Resources.ScopeSearchToThisAssembly), Category = nameof(Resources.Analyze), Order = 9999)]\n\t[Shared]\n\tpublic class ScopeSearchToAssembly : IContextMenuEntry\n\t{\n\t\tprivate readonly SearchPaneModel searchPane;\n\n\t\tpublic ScopeSearchToAssembly(SearchPaneModel searchPane)\n\t\t{\n\t\t\tthis.searchPane = searchPane;\n\t\t}\n\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\t// asmName cannot be null here, because Execute is only called if IsEnabled/IsVisible return true.\n\t\t\tstring asmName = GetAssembly(context)!;\n\t\t\tstring searchTerm = searchPane.SearchTerm;\n\t\t\tstring[] args = CommandLineTools.CommandLineToArgumentArray(searchTerm);\n\t\t\tbool replaced = false;\n\t\t\tfor (int i = 0; i < args.Length; i++)\n\t\t\t{\n\t\t\t\tif (args[i].StartsWith(\"inassembly:\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t{\n\t\t\t\t\targs[i] = \"inassembly:\" + asmName;\n\t\t\t\t\treplaced = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!replaced)\n\t\t\t{\n\t\t\t\tsearchTerm += \" inassembly:\" + asmName;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsearchTerm = CommandLineTools.ArgumentArrayToCommandLine(args);\n\t\t\t}\n\t\t\tsearchPane.SearchTerm = searchTerm;\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\treturn GetAssembly(context) != null;\n\t\t}\n\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\treturn GetAssembly(context) != null;\n\t\t}\n\n\t\tstring? GetAssembly(TextViewContext context)\n\t\t{\n\t\t\tif (context.Reference?.Reference is IEntity entity)\n\t\t\t\treturn entity.ParentModule?.AssemblyName;\n\t\t\tif (context.SelectedTreeNodes?.Length != 1)\n\t\t\t\treturn null;\n\t\t\tswitch (context.SelectedTreeNodes[0])\n\t\t\t{\n\t\t\t\tcase AssemblyTreeNode tn:\n\t\t\t\t\treturn tn.LoadedAssembly.ShortName;\n\t\t\t\tcase IMemberTreeNode member:\n\t\t\t\t\treturn member.Member?.ParentModule?.AssemblyName;\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Commands/ScopeSearchToNamespace.cs",
    "content": "// Copyright (c) 2021 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\nusing System;\nusing System.Composition;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.AppEnv;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.Search;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportContextMenuEntry(Header = nameof(Resources.ScopeSearchToThisNamespace), Category = nameof(Resources.Analyze), Order = 9999)]\n\t[Shared]\n\tpublic class ScopeSearchToNamespace : IContextMenuEntry\n\t{\n\t\tprivate readonly SearchPaneModel searchPane;\n\n\t\tpublic ScopeSearchToNamespace(SearchPaneModel searchPane)\n\t\t{\n\t\t\tthis.searchPane = searchPane;\n\t\t}\n\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tstring ns = GetNamespace(context);\n\t\t\tstring searchTerm = searchPane.SearchTerm;\n\t\t\tstring[] args = CommandLineTools.CommandLineToArgumentArray(searchTerm);\n\t\t\tbool replaced = false;\n\t\t\tfor (int i = 0; i < args.Length; i++)\n\t\t\t{\n\t\t\t\tif (args[i].StartsWith(\"innamespace:\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t{\n\t\t\t\t\targs[i] = \"innamespace:\" + ns;\n\t\t\t\t\treplaced = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!replaced)\n\t\t\t{\n\t\t\t\tsearchTerm += \" innamespace:\" + ns;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsearchTerm = CommandLineTools.ArgumentArrayToCommandLine(args);\n\t\t\t}\n\n\t\t\tsearchPane.SearchTerm = searchTerm;\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\treturn GetNamespace(context) != null;\n\t\t}\n\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\treturn GetNamespace(context) != null;\n\t\t}\n\n\t\tstring GetNamespace(TextViewContext context)\n\t\t{\n\t\t\tif (context.Reference?.Reference is IEntity entity)\n\t\t\t\treturn entity.Namespace;\n\t\t\tif (context.SelectedTreeNodes?.Length != 1)\n\t\t\t\treturn null;\n\t\t\tswitch (context.SelectedTreeNodes[0])\n\t\t\t{\n\t\t\t\tcase NamespaceTreeNode tn:\n\t\t\t\t\treturn tn.Name;\n\t\t\t\tcase IMemberTreeNode member:\n\t\t\t\t\treturn member.Member.Namespace;\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Commands/SearchMsdnContextMenuEntry.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Linq;\n\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TreeNodes;\nnamespace ICSharpCode.ILSpy\n{\n\tusing System.Composition;\n\n\tusing ICSharpCode.Decompiler.TypeSystem;\n\n\t[ExportContextMenuEntry(Header = nameof(Resources.SearchMSDN), Icon = \"images/SearchMsdn\", Order = 9999)]\n\t[Shared]\n\tinternal sealed class SearchMsdnContextMenuEntry : IContextMenuEntry\n\t{\n\t\tprivate static string msdnAddress = \"https://docs.microsoft.com/dotnet/api/{0}\";\n\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn false;\n\n\t\t\treturn context.SelectedTreeNodes.All(\n\t\t\t\tn => n is NamespaceTreeNode\n\t\t\t\t|| n is TypeTreeNode\n\t\t\t\t|| n is EventTreeNode\n\t\t\t\t|| n is FieldTreeNode\n\t\t\t\t|| n is PropertyTreeNode\n\t\t\t\t|| n is MethodTreeNode);\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn false;\n\n\t\t\tforeach (var node in context.SelectedTreeNodes)\n\t\t\t{\n\t\t\t\tif (node is TypeTreeNode typeNode && !typeNode.IsPublicAPI)\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (node is EventTreeNode eventNode && (!eventNode.IsPublicAPI || !IsAccessible(eventNode.EventDefinition)))\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (node is FieldTreeNode fieldNode && (!fieldNode.IsPublicAPI || !IsAccessible(fieldNode.FieldDefinition) || IsDelegateOrEnumMember(fieldNode.FieldDefinition)))\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (node is PropertyTreeNode propertyNode && (!propertyNode.IsPublicAPI || !IsAccessible(propertyNode.PropertyDefinition)))\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (node is MethodTreeNode methodNode && (!methodNode.IsPublicAPI || !IsAccessible(methodNode.MethodDefinition) || IsDelegateOrEnumMember(methodNode.MethodDefinition)))\n\t\t\t\t\treturn false;\n\n\t\t\t\tif (node is NamespaceTreeNode namespaceNode && string.IsNullOrEmpty(namespaceNode.Name))\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tbool IsAccessible(IEntity entity)\n\t\t{\n\t\t\tif (entity.DeclaringTypeDefinition == null)\n\t\t\t\treturn false;\n\t\t\tswitch (entity.DeclaringTypeDefinition.Accessibility)\n\t\t\t{\n\t\t\t\tcase Accessibility.Public:\n\t\t\t\tcase Accessibility.Protected:\n\t\t\t\tcase Accessibility.ProtectedOrInternal:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tbool IsDelegateOrEnumMember(IMember member)\n\t\t{\n\t\t\tif (member.DeclaringTypeDefinition == null)\n\t\t\t\treturn false;\n\t\t\tswitch (member.DeclaringTypeDefinition.Kind)\n\t\t\t{\n\t\t\t\tcase TypeKind.Delegate:\n\t\t\t\tcase TypeKind.Enum:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes != null)\n\t\t\t{\n\t\t\t\tforeach (ILSpyTreeNode node in context.SelectedTreeNodes)\n\t\t\t\t{\n\t\t\t\t\tSearchMsdn(node);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static void SearchMsdn(ILSpyTreeNode node)\n\t\t{\n\t\t\tvar address = string.Empty;\n\n\t\t\tif (node is NamespaceTreeNode namespaceNode)\n\t\t\t{\n\t\t\t\taddress = string.Format(msdnAddress, namespaceNode.Name);\n\t\t\t}\n\t\t\telse if (node is IMemberTreeNode memberNode)\n\t\t\t{\n\t\t\t\tvar member = memberNode.Member;\n\t\t\t\tvar memberName = member.ReflectionName.Replace('`', '-').Replace('+', '.');\n\t\t\t\tif (memberName.EndsWith(\"..ctor\", System.StringComparison.Ordinal))\n\t\t\t\t\tmemberName = memberName.Substring(0, memberName.Length - 5) + \"-ctor\";\n\n\t\t\t\taddress = string.Format(msdnAddress, memberName);\n\t\t\t}\n\n\t\t\taddress = address.ToLower();\n\t\t\tif (!string.IsNullOrEmpty(address))\n\t\t\t\tGlobalUtils.OpenLink(address);\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Commands/SelectPdbContextMenuEntry.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.IO;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.CSharp.ProjectDecompiler;\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nusing Microsoft.Win32;\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportContextMenuEntry(Header = nameof(Resources.SelectPDB))]\n\t[Shared]\n\tclass SelectPdbContextMenuEntry(AssemblyTreeModel assemblyTreeModel) : IContextMenuEntry\n\t{\n\t\tpublic async void Execute(TextViewContext context)\n\t\t{\n\t\t\tvar assembly = (context.SelectedTreeNodes?.FirstOrDefault() as AssemblyTreeNode)?.LoadedAssembly;\n\t\t\tif (assembly == null)\n\t\t\t\treturn;\n\t\t\tOpenFileDialog dlg = new OpenFileDialog();\n\t\t\tdlg.FileName = WholeProjectDecompiler.CleanUpFileName(assembly.ShortName, \".pdb\");\n\t\t\tdlg.Filter = Resources.PortablePDBPdbAllFiles;\n\t\t\tdlg.InitialDirectory = Path.GetDirectoryName(assembly.FileName);\n\t\t\tif (dlg.ShowDialog() != true)\n\t\t\t\treturn;\n\n\t\t\tusing (context.TreeView.LockUpdates())\n\t\t\t{\n\t\t\t\tawait assembly.LoadDebugInfo(dlg.FileName);\n\t\t\t}\n\n\t\t\tvar node = (AssemblyTreeNode)assemblyTreeModel.FindNodeByPath(new[] { assembly.FileName }, true);\n\t\t\tnode.UpdateToolTip();\n\t\t\tassemblyTreeModel.SelectNode(node);\n\t\t\tassemblyTreeModel.RefreshDecompiledView();\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context) => true;\n\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\treturn context.SelectedTreeNodes?.Length == 1\n\t\t\t\t&& context.SelectedTreeNodes?.FirstOrDefault() is AssemblyTreeNode asm\n\t\t\t\t&& asm.LoadedAssembly.IsLoadedAsValidAssembly;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/SetThemeCommand.cs",
    "content": "\nusing System.Composition;\n\nnamespace ICSharpCode.ILSpy.Commands\n{\n\t[Export]\n\t[Shared]\n\tpublic class SetThemeCommand(SettingsService settingsService) : SimpleCommand\n\t{\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tif (parameter is string theme)\n\t\t\t{\n\t\t\t\tsettingsService.SessionSettings.Theme = theme;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/ShowCFGContextMenuEntry.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Windows;\n\nusing ICSharpCode.Decompiler.FlowAnalysis;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.IL.ControlFlow;\n\nnamespace ICSharpCode.ILSpy.Commands\n{\n#if DEBUG\n\t[ExportContextMenuEntry(Header = \"DEBUG -- Show CFG\")]\n\t[Shared]\n\tinternal class ShowCFGContextMenuEntry : IContextMenuEntry\n\t{\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar container = (BlockContainer)context.Reference.Reference;\n\t\t\t\tvar cfg = new ControlFlowGraph(container);\n\t\t\t\tExportGraph(cfg.Nodes).Show();\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tMessageBox.Show(\"Error generating CFG - requires GraphViz dot.exe in PATH\" + Environment.NewLine + Environment.NewLine + ex.ToString());\n\t\t\t}\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\treturn context.Reference?.Reference is BlockContainer;\n\t\t}\n\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\treturn context.Reference?.Reference is BlockContainer;\n\t\t}\n\n\t\tinternal static GraphVizGraph ExportGraph(IReadOnlyList<ControlFlowNode> nodes, Func<ControlFlowNode, string> labelFunc = null)\n\t\t{\n\t\t\tif (labelFunc == null)\n\t\t\t{\n\t\t\t\tlabelFunc = node => {\n\t\t\t\t\tvar block = node.UserData as Block;\n\t\t\t\t\treturn block != null ? block.Label : node.UserData?.ToString();\n\t\t\t\t};\n\t\t\t}\n\t\t\tGraphVizGraph g = new GraphVizGraph();\n\t\t\tGraphVizNode[] n = new GraphVizNode[nodes.Count];\n\t\t\tfor (int i = 0; i < n.Length; i++)\n\t\t\t{\n\t\t\t\tn[i] = new GraphVizNode(nodes[i].UserIndex);\n\t\t\t\tn[i].shape = \"box\";\n\t\t\t\tn[i].label = labelFunc(nodes[i]);\n\t\t\t\tg.AddNode(n[i]);\n\t\t\t}\n\t\t\tforeach (var source in nodes)\n\t\t\t{\n\t\t\t\tforeach (var target in source.Successors)\n\t\t\t\t{\n\t\t\t\t\tg.AddEdge(new GraphVizEdge(source.UserIndex, target.UserIndex));\n\t\t\t\t}\n\t\t\t\tif (source.ImmediateDominator != null)\n\t\t\t\t{\n\t\t\t\t\tg.AddEdge(\n\t\t\t\t\t\tnew GraphVizEdge(source.ImmediateDominator.UserIndex, source.UserIndex) {\n\t\t\t\t\t\t\tcolor = \"green\"\n\t\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn g;\n\t\t}\n\t}\n#endif\n}\n"
  },
  {
    "path": "ILSpy/Commands/ShowPane.cs",
    "content": "using ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpy.ViewModels;\n\nnamespace ICSharpCode.ILSpy.Commands\n{\n\tclass ToolPaneCommand(string contentId, DockWorkspace dockWorkspace) : SimpleCommand\n\t{\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tdockWorkspace.ShowToolPane(contentId);\n\t\t}\n\t}\n\n\tclass TabPageCommand(TabPageModel model, DockWorkspace dockWorkspace) : SimpleCommand\n\t{\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\t// ensure the tab control is focused before setting the active tab page, else the tab will not be focused\n\t\t\tdockWorkspace.ActiveTabPage?.Focus();\n\t\t\t// reset first, else clicking on the already active tab will not focus the tab and the menu checkmark will not be updated\n\t\t\tdockWorkspace.ActiveTabPage = null;\n\t\t\tdockWorkspace.ActiveTabPage = model;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Commands/SimpleCommand.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections;\nusing System.Windows.Data;\nusing System.Windows.Input;\n\nnamespace ICSharpCode.ILSpy\n{\n\tpublic abstract class SimpleCommand : ICommand\n\t{\n\t\tpublic event EventHandler CanExecuteChanged {\n\t\t\tadd { CommandManager.RequerySuggested += value; }\n\t\t\tremove { CommandManager.RequerySuggested -= value; }\n\t\t}\n\n\t\tpublic abstract void Execute(object parameter);\n\n\t\tpublic virtual bool CanExecute(object parameter)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic interface IProvideParameterBinding\n\t{\n\t\tBinding ParameterBinding { get; }\n\t}\n\n\tpublic interface IProvideParameterList\n\t{\n\t\tIEnumerable ParameterList { get; }\n\t\tobject GetParameterText(object parameter);\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Commands/SortAssemblyListCommand.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Composition;\n\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.TreeView;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[ExportMainMenuCommand(ParentMenuID = nameof(Resources._View), Header = nameof(Resources.SortAssembly_listName), MenuIcon = \"Images/Sort\", MenuCategory = nameof(Resources.View))]\n\t[ExportToolbarCommand(ToolTip = nameof(Resources.SortAssemblyListName), ToolbarIcon = \"Images/Sort\", ToolbarCategory = nameof(Resources.View))]\n\t[Shared]\n\tsealed class SortAssemblyListCommand(AssemblyTreeModel assemblyTreeModel) : SimpleCommand\n\t{\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tassemblyTreeModel.SortAssemblyList();\n\t\t}\n\t}\n\n\t[ExportMainMenuCommand(ParentMenuID = nameof(Resources._View), Header = nameof(Resources._CollapseTreeNodes), MenuIcon = \"Images/CollapseAll\", MenuCategory = nameof(Resources.View))]\n\t[ExportToolbarCommand(ToolTip = nameof(Resources.CollapseTreeNodes), ToolbarIcon = \"Images/CollapseAll\", ToolbarCategory = nameof(Resources.View))]\n\t[Shared]\n\tsealed class CollapseAllCommand(AssemblyTreeModel assemblyTreeModel) : SimpleCommand\n\t{\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tassemblyTreeModel.CollapseAll();\n\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/ContextMenuEntry.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Controls;\n\nusing ICSharpCode.AvalonEdit;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpyX.Search;\nusing ICSharpCode.ILSpy.Controls.TreeView;\nusing ICSharpCode.ILSpyX.TreeView;\n\nusing TomsToolbox.Composition;\nusing TomsToolbox.Essentials;\nusing TomsToolbox.Wpf.Composition;\n\nnamespace ICSharpCode.ILSpy\n{\n\tpublic interface IContextMenuEntry\n\t{\n\t\tbool IsVisible(TextViewContext context);\n\t\tbool IsEnabled(TextViewContext context);\n\t\tvoid Execute(TextViewContext context);\n\t}\n\n\tpublic class TextViewContext\n\t{\n\t\t/// <summary>\n\t\t/// Returns the selected nodes in the tree view.\n\t\t/// Returns null, if context menu does not belong to a tree view.\n\t\t/// </summary>\n\t\tpublic SharpTreeNode[] SelectedTreeNodes { get; private set; }\n\n\t\t/// <summary>\n\t\t/// Returns the tree view the context menu is assigned to.\n\t\t/// Returns null, if context menu is not assigned to a tree view.\n\t\t/// </summary>\n\t\tpublic SharpTreeView TreeView { get; private set; }\n\n\t\t/// <summary>\n\t\t/// Returns the text view the context menu is assigned to.\n\t\t/// Returns null, if context menu is not assigned to a text view.\n\t\t/// </summary>\n\t\tpublic DecompilerTextView TextView { get; private set; }\n\n\t\t/// <summary>\n\t\t/// Returns the list box the context menu is assigned to.\n\t\t/// Returns null, if context menu is not assigned to a list box.\n\t\t/// </summary>\n\t\tpublic ListBox ListBox { get; private set; }\n\n\t\t/// <summary>\n\t\t/// Returns the data grid the context menu is assigned to.\n\t\t/// Returns null, if context menu is not assigned to a data grid.\n\t\t/// </summary>\n\t\tpublic DataGrid DataGrid { get; private set; }\n\n\t\t/// <summary>\n\t\t/// Returns the reference the mouse cursor is currently hovering above.\n\t\t/// Returns null, if there was no reference found.\n\t\t/// </summary>\n\t\tpublic ReferenceSegment Reference { get; private set; }\n\n\t\t/// <summary>\n\t\t/// Returns the position in TextView the mouse cursor is currently hovering above.\n\t\t/// Returns null, if TextView returns null;\n\t\t/// </summary>\n\t\tpublic TextViewPosition? Position { get; private set; }\n\n\t\t/// <summary>\n\t\t/// Returns the original source of the context menu event.\n\t\t/// </summary>\n\t\tpublic DependencyObject OriginalSource { get; private set; }\n\n\t\tpublic static TextViewContext Create(ContextMenuEventArgs eventArgs, SharpTreeView treeView = null, DecompilerTextView textView = null, ListBox listBox = null, DataGrid dataGrid = null)\n\t\t{\n\t\t\tReferenceSegment reference;\n\n\t\t\tif (textView is not null)\n\t\t\t{\n\t\t\t\treference = textView.GetReferenceSegmentAtMousePosition();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treference = (listBox?.SelectedItem ?? dataGrid?.SelectedItem) switch {\n\t\t\t\t\tSearchResult searchResult => new() { Reference = searchResult.Reference },\n\t\t\t\t\tTreeNodes.IMemberTreeNode treeNode => new() { Reference = treeNode.Member }, { } value => new() { Reference = value },\n\t\t\t\t\t_ => null\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tvar position = textView?.GetPositionFromMousePosition();\n\t\t\tvar selectedTreeNodes = treeView?.GetTopLevelSelection().ToArray();\n\n\t\t\treturn new() {\n\t\t\t\tListBox = listBox,\n\t\t\t\tDataGrid = dataGrid,\n\t\t\t\tTreeView = treeView,\n\t\t\t\tTextView = textView,\n\t\t\t\tSelectedTreeNodes = selectedTreeNodes,\n\t\t\t\tReference = reference,\n\t\t\t\tPosition = position,\n\t\t\t\tOriginalSource = eventArgs.OriginalSource as DependencyObject\n\t\t\t};\n\t\t}\n\t}\n\n\tpublic interface IContextMenuEntryMetadata\n\t{\n\t\tstring MenuID { get; }\n\t\tstring ParentMenuID { get; }\n\t\tstring Icon { get; }\n\t\tstring Header { get; }\n\t\tstring Category { get; }\n\t\tstring InputGestureText { get; }\n\n\t\tdouble Order { get; }\n\t}\n\n\t[MetadataAttribute]\n\t[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]\n\tpublic class ExportContextMenuEntryAttribute : ExportAttribute, IContextMenuEntryMetadata\n\t{\n\t\tpublic ExportContextMenuEntryAttribute()\n\t\t\t: base(typeof(IContextMenuEntry))\n\t\t{\n\t\t\t// entries default to end of menu unless given specific order position\n\t\t\tOrder = double.MaxValue;\n\t\t}\n\t\t/// <summary>\n\t\t/// Gets/Sets the ID of this menu item. Menu entries are not required to have an ID,\n\t\t/// however, setting it allows to declare nested menu structures.\n\t\t/// Plugin authors are advised to use GUIDs as identifiers to prevent conflicts.\n\t\t/// <para/>\n\t\t/// NOTE: Defining cycles (for example by accidentally setting <see cref=\"MenuID\"/> equal to <see cref=\"ParentMenuID\"/>)\n\t\t/// will lead to a stack-overflow and crash of ILSpy at startup.\n\t\t/// </summary>\n\t\tpublic string MenuID { get; set; }\n\t\t/// <summary>\n\t\t/// Gets/Sets the parent of this menu item. All menu items sharing the same parent will be displayed as sub-menu items.\n\t\t/// If this property is set to <see langword=\"null\"/>, the menu item is displayed in the top-level menu.\n\t\t/// <para/>\n\t\t/// NOTE: Defining cycles (for example by accidentally setting <see cref=\"MenuID\"/> equal to <see cref=\"ParentMenuID\"/>)\n\t\t/// will lead to a stack-overflow and crash of ILSpy at startup.\n\t\t/// </summary>\n\t\tpublic string ParentMenuID { get; set; }\n\t\tpublic string Icon { get; set; }\n\t\tpublic string Header { get; set; }\n\t\tpublic string Category { get; set; }\n\t\tpublic string InputGestureText { get; set; }\n\t\tpublic double Order { get; set; }\n\t}\n\n\tinternal class ContextMenuProvider\n\t{\n\t\tprivate static readonly WeakEventSource<EventArgs> ContextMenuClosedEventSource = new();\n\n\t\tpublic static event EventHandler<EventArgs> ContextMenuClosed {\n\t\t\tadd => ContextMenuClosedEventSource.Subscribe(value);\n\t\t\tremove => ContextMenuClosedEventSource.Unsubscribe(value);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Enables extensible context menu support for the specified tree view.\n\t\t/// </summary>\n\t\tpublic static void Add(SharpTreeView treeView)\n\t\t{\n\t\t\tvar provider = new ContextMenuProvider(treeView);\n\t\t\ttreeView.ContextMenuOpening += provider.treeView_ContextMenuOpening;\n\t\t\t// Context menu is shown only when the ContextMenu property is not null before the\n\t\t\t// ContextMenuOpening event handler is called.\n\t\t\ttreeView.ContextMenu = new ContextMenu();\n\t\t}\n\n\t\tpublic static void Add(DecompilerTextView textView)\n\t\t{\n\t\t\tvar provider = new ContextMenuProvider(textView);\n\t\t\ttextView.ContextMenuOpening += provider.textView_ContextMenuOpening;\n\t\t\t// Context menu is shown only when the ContextMenu property is not null before the\n\t\t\t// ContextMenuOpening event handler is called.\n\t\t\ttextView.ContextMenu = new ContextMenu();\n\t\t}\n\n\t\tpublic static void Add(ListBox listBox)\n\t\t{\n\t\t\tvar provider = new ContextMenuProvider(listBox);\n\t\t\tlistBox.ContextMenuOpening += provider.listBox_ContextMenuOpening;\n\t\t\tlistBox.ContextMenu = new ContextMenu();\n\t\t}\n\n\t\tpublic static void Add(DataGrid dataGrid)\n\t\t{\n\t\t\tvar provider = new ContextMenuProvider(dataGrid);\n\t\t\tdataGrid.ContextMenuOpening += provider.dataGrid_ContextMenuOpening;\n\t\t\tdataGrid.ContextMenu = new ContextMenu();\n\t\t}\n\n\t\treadonly Control control;\n\t\treadonly SharpTreeView treeView;\n\t\treadonly DecompilerTextView textView;\n\t\treadonly ListBox listBox;\n\t\treadonly DataGrid dataGrid;\n\t\treadonly IExport<IContextMenuEntry, IContextMenuEntryMetadata>[] entries;\n\n\t\tprivate ContextMenuProvider(Control control)\n\t\t{\n\t\t\tentries = control.GetExportProvider().GetExports<IContextMenuEntry, IContextMenuEntryMetadata>().ToArray();\n\n\t\t\tthis.control = control;\n\t\t}\n\n\t\tContextMenuProvider(DecompilerTextView textView)\n\t\t\t: this((Control)textView)\n\t\t{\n\t\t\tthis.textView = textView ?? throw new ArgumentNullException(nameof(textView));\n\t\t}\n\n\t\tContextMenuProvider(SharpTreeView treeView)\n\t\t\t: this((Control)treeView)\n\t\t{\n\t\t\tthis.treeView = treeView ?? throw new ArgumentNullException(nameof(treeView));\n\t\t}\n\n\t\tContextMenuProvider(ListBox listBox)\n\t\t\t: this((Control)listBox)\n\t\t{\n\t\t\tthis.listBox = listBox ?? throw new ArgumentNullException(nameof(listBox));\n\t\t}\n\n\t\tContextMenuProvider(DataGrid dataGrid)\n\t\t\t: this((Control)dataGrid)\n\t\t{\n\t\t\tthis.dataGrid = dataGrid ?? throw new ArgumentNullException(nameof(dataGrid));\n\t\t}\n\n\t\tvoid treeView_ContextMenuOpening(object sender, ContextMenuEventArgs e)\n\t\t{\n\t\t\tvar context = TextViewContext.Create(e, treeView: treeView);\n\t\t\tif (context.SelectedTreeNodes.Length == 0)\n\t\t\t{\n\t\t\t\te.Handled = true; // don't show the menu\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (ShowContextMenu(context, out var menu))\n\t\t\t\ttreeView.ContextMenu = menu;\n\t\t\telse\n\t\t\t\t// hide the context menu.\n\t\t\t\te.Handled = true;\n\t\t}\n\n\t\tvoid textView_ContextMenuOpening(object sender, ContextMenuEventArgs e)\n\t\t{\n\t\t\tvar context = TextViewContext.Create(e, textView: textView);\n\t\t\tif (ShowContextMenu(context, out var menu))\n\t\t\t\ttextView.ContextMenu = menu;\n\t\t\telse\n\t\t\t\t// hide the context menu.\n\t\t\t\te.Handled = true;\n\t\t}\n\n\t\tvoid listBox_ContextMenuOpening(object sender, ContextMenuEventArgs e)\n\t\t{\n\t\t\tvar context = TextViewContext.Create(e, listBox: listBox);\n\t\t\tif (ShowContextMenu(context, out var menu))\n\t\t\t\tlistBox.ContextMenu = menu;\n\t\t\telse\n\t\t\t\t// hide the context menu.\n\t\t\t\te.Handled = true;\n\t\t}\n\n\t\tvoid dataGrid_ContextMenuOpening(object sender, ContextMenuEventArgs e)\n\t\t{\n\t\t\tvar context = TextViewContext.Create(e, dataGrid: dataGrid);\n\t\t\tif (ShowContextMenu(context, out var menu))\n\t\t\t\tdataGrid.ContextMenu = menu;\n\t\t\telse\n\t\t\t\t// hide the context menu.\n\t\t\t\te.Handled = true;\n\t\t}\n\n\t\tbool ShowContextMenu(TextViewContext context, out ContextMenu menu)\n\t\t{\n\t\t\t// Closing event is raised on the control where mouse is clicked, not on the control that opened the menu, so we hook on the global window event.\n\t\t\tvar window = Window.GetWindow(control)!;\n\t\t\twindow.ContextMenuClosing += ContextMenu_Closing;\n\n\t\t\tvoid ContextMenu_Closing(object sender, EventArgs e)\n\t\t\t{\n\t\t\t\twindow.ContextMenuClosing -= ContextMenu_Closing;\n\t\t\t\tContextMenuClosedEventSource.Raise(this, EventArgs.Empty);\n\t\t\t}\n\n\t\t\tmenu = new ContextMenu();\n\n\t\t\tvar menuGroups = new Dictionary<string, IExport<IContextMenuEntry, IContextMenuEntryMetadata>[]>();\n\t\t\tIExport<IContextMenuEntry, IContextMenuEntryMetadata>[] topLevelGroup = null;\n\t\t\tforeach (var group in entries.OrderBy(c => c.Metadata.Order).GroupBy(c => c.Metadata.ParentMenuID))\n\t\t\t{\n\t\t\t\tif (group.Key == null)\n\t\t\t\t{\n\t\t\t\t\ttopLevelGroup = group.ToArray();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tmenuGroups.Add(group.Key, group.ToArray());\n\t\t\t\t}\n\t\t\t}\n\t\t\tBuildMenu(topLevelGroup ?? Array.Empty<IExport<IContextMenuEntry, IContextMenuEntryMetadata>>(), menu.Items);\n\t\t\treturn menu.Items.Count > 0;\n\n\t\t\tvoid BuildMenu(IExport<IContextMenuEntry, IContextMenuEntryMetadata>[] menuGroup, ItemCollection parent)\n\t\t\t{\n\t\t\t\tforeach (var category in menuGroup.GroupBy(c => c.Metadata.Category))\n\t\t\t\t{\n\t\t\t\t\tvar needSeparatorForCategory = parent.Count > 0;\n\t\t\t\t\tforeach (var entryPair in category)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar entry = entryPair.Value;\n\t\t\t\t\t\tif (entry.IsVisible(context))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (needSeparatorForCategory)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tparent.Add(new Separator());\n\t\t\t\t\t\t\t\tneedSeparatorForCategory = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tvar menuItem = new MenuItem();\n\t\t\t\t\t\t\tmenuItem.Header = ResourceHelper.GetString(entryPair.Metadata.Header);\n\t\t\t\t\t\t\tmenuItem.InputGestureText = entryPair.Metadata.InputGestureText;\n\t\t\t\t\t\t\tif (!string.IsNullOrEmpty(entryPair.Metadata.Icon))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmenuItem.Icon = new Image {\n\t\t\t\t\t\t\t\t\tWidth = 16,\n\t\t\t\t\t\t\t\t\tHeight = 16,\n\t\t\t\t\t\t\t\t\tSource = Images.Load(entryPair.Value, entryPair.Metadata.Icon)\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (entryPair.Value.IsEnabled(context))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmenuItem.Click += delegate { entry.Execute(context); };\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tmenuItem.IsEnabled = false;\n\t\t\t\t\t\t\tparent.Add(menuItem);\n\n\t\t\t\t\t\t\tif (entryPair.Metadata.MenuID != null && menuGroups.TryGetValue(entryPair.Metadata.MenuID, out var group))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tBuildMenu(group, menuItem.Items);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/CollapsiblePanel.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Input;\nusing System.Windows.Media.Animation;\nusing System.Windows.Threading;\n\nnamespace ICSharpCode.ILSpy.Controls\n{\n\t/// <summary>\n\t/// Allows animated collapsing of the content of this panel.\n\t/// </summary>\n\tpublic class CollapsiblePanel : ContentControl\n\t{\n\t\tstatic CollapsiblePanel()\n\t\t{\n\t\t\tDefaultStyleKeyProperty.OverrideMetadata(typeof(CollapsiblePanel),\n\t\t\t\t\t\t\t\t\t\t\t\t\t new FrameworkPropertyMetadata(typeof(CollapsiblePanel)));\n\t\t\tFocusableProperty.OverrideMetadata(typeof(CollapsiblePanel),\n\t\t\t\t\t\t\t\t\t\t\t   new FrameworkPropertyMetadata(false));\n\t\t}\n\n\t\tpublic static readonly DependencyProperty IsCollapsedProperty = DependencyProperty.Register(\n\t\t\t\"IsCollapsed\", typeof(bool), typeof(CollapsiblePanel),\n\t\t\tnew UIPropertyMetadata(false, new PropertyChangedCallback(OnIsCollapsedChanged)));\n\n\t\tpublic bool IsCollapsed {\n\t\t\tget { return (bool)GetValue(IsCollapsedProperty); }\n\t\t\tset { SetValue(IsCollapsedProperty, value); }\n\t\t}\n\n\t\tpublic static readonly DependencyProperty CollapseOrientationProperty =\n\t\t\tDependencyProperty.Register(\"CollapseOrientation\", typeof(Orientation), typeof(CollapsiblePanel),\n\t\t\t\t\t\t\t\t\t\tnew FrameworkPropertyMetadata(Orientation.Vertical));\n\n\t\tpublic Orientation CollapseOrientation {\n\t\t\tget { return (Orientation)GetValue(CollapseOrientationProperty); }\n\t\t\tset { SetValue(CollapseOrientationProperty, value); }\n\t\t}\n\n\t\tpublic static readonly DependencyProperty DurationProperty = DependencyProperty.Register(\n\t\t\t\"Duration\", typeof(TimeSpan), typeof(CollapsiblePanel),\n\t\t\tnew UIPropertyMetadata(TimeSpan.FromMilliseconds(250)));\n\n\t\t/// <summary>\n\t\t/// The duration in milliseconds of the animation.\n\t\t/// </summary>\n\t\tpublic TimeSpan Duration {\n\t\t\tget { return (TimeSpan)GetValue(DurationProperty); }\n\t\t\tset { SetValue(DurationProperty, value); }\n\t\t}\n\n\t\tprotected internal static readonly DependencyProperty AnimationProgressProperty = DependencyProperty.Register(\n\t\t\t\"AnimationProgress\", typeof(double), typeof(CollapsiblePanel),\n\t\t\tnew FrameworkPropertyMetadata(1.0));\n\n\t\t/// <summary>\n\t\t/// Value between 0 and 1 specifying how far the animation currently is.\n\t\t/// </summary>\n\t\tprotected internal double AnimationProgress {\n\t\t\tget { return (double)GetValue(AnimationProgressProperty); }\n\t\t\tset { SetValue(AnimationProgressProperty, value); }\n\t\t}\n\n\t\tprotected internal static readonly DependencyProperty AnimationProgressXProperty = DependencyProperty.Register(\n\t\t\t\"AnimationProgressX\", typeof(double), typeof(CollapsiblePanel),\n\t\t\tnew FrameworkPropertyMetadata(1.0));\n\n\t\t/// <summary>\n\t\t/// Value between 0 and 1 specifying how far the animation currently is.\n\t\t/// </summary>\n\t\tprotected internal double AnimationProgressX {\n\t\t\tget { return (double)GetValue(AnimationProgressXProperty); }\n\t\t\tset { SetValue(AnimationProgressXProperty, value); }\n\t\t}\n\n\t\tprotected internal static readonly DependencyProperty AnimationProgressYProperty = DependencyProperty.Register(\n\t\t\t\"AnimationProgressY\", typeof(double), typeof(CollapsiblePanel),\n\t\t\tnew FrameworkPropertyMetadata(1.0));\n\n\t\t/// <summary>\n\t\t/// Value between 0 and 1 specifying how far the animation currently is.\n\t\t/// </summary>\n\t\tprotected internal double AnimationProgressY {\n\t\t\tget { return (double)GetValue(AnimationProgressYProperty); }\n\t\t\tset { SetValue(AnimationProgressYProperty, value); }\n\t\t}\n\n\t\tstatic void OnIsCollapsedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)\n\t\t{\n\t\t\t((CollapsiblePanel)d).SetupAnimation((bool)e.NewValue);\n\t\t}\n\n\t\tvoid SetupAnimation(bool isCollapsed)\n\t\t{\n\t\t\tif (this.IsLoaded)\n\t\t\t{\n\t\t\t\t// If the animation is already running, calculate remaining portion of the time\n\t\t\t\tdouble currentProgress = AnimationProgress;\n\t\t\t\tif (!isCollapsed)\n\t\t\t\t{\n\t\t\t\t\tcurrentProgress = 1.0 - currentProgress;\n\t\t\t\t}\n\n\t\t\t\tDoubleAnimation animation = new DoubleAnimation();\n\t\t\t\tanimation.To = isCollapsed ? 0.0 : 1.0;\n\t\t\t\tanimation.Duration = TimeSpan.FromSeconds(Duration.TotalSeconds * currentProgress);\n\t\t\t\tanimation.FillBehavior = FillBehavior.HoldEnd;\n\n\t\t\t\tthis.BeginAnimation(AnimationProgressProperty, animation);\n\t\t\t\tif (CollapseOrientation == Orientation.Horizontal)\n\t\t\t\t{\n\t\t\t\t\tthis.BeginAnimation(AnimationProgressXProperty, animation);\n\t\t\t\t\tthis.AnimationProgressY = 1.0;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthis.AnimationProgressX = 1.0;\n\t\t\t\t\tthis.BeginAnimation(AnimationProgressYProperty, animation);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.AnimationProgress = isCollapsed ? 0.0 : 1.0;\n\t\t\t\tthis.AnimationProgressX = (CollapseOrientation == Orientation.Horizontal) ? this.AnimationProgress : 1.0;\n\t\t\t\tthis.AnimationProgressY = (CollapseOrientation == Orientation.Vertical) ? this.AnimationProgress : 1.0;\n\t\t\t}\n\t\t}\n\t}\n\n\tsealed class CollapsiblePanelProgressToVisibilityConverter : IValueConverter\n\t{\n\t\tpublic object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)\n\t\t{\n\t\t\tif (value is double)\n\t\t\t\treturn (double)value > 0 ? Visibility.Visible : Visibility.Collapsed;\n\t\t\telse\n\t\t\t\treturn Visibility.Visible;\n\t\t}\n\n\t\tpublic object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\t}\n\n\tpublic class SelfCollapsingPanel : CollapsiblePanel\n\t{\n\t\tpublic static readonly DependencyProperty CanCollapseProperty =\n\t\t\tDependencyProperty.Register(\"CanCollapse\", typeof(bool), typeof(SelfCollapsingPanel),\n\t\t\t\t\t\t\t\t\t\tnew FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnCanCollapseChanged)));\n\n\t\tpublic bool CanCollapse {\n\t\t\tget { return (bool)GetValue(CanCollapseProperty); }\n\t\t\tset { SetValue(CanCollapseProperty, value); }\n\t\t}\n\n\t\tstatic void OnCanCollapseChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)\n\t\t{\n\t\t\tSelfCollapsingPanel panel = (SelfCollapsingPanel)d;\n\t\t\tif ((bool)e.NewValue)\n\t\t\t{\n\t\t\t\tif (!panel.HeldOpenByMouse)\n\t\t\t\t\tpanel.IsCollapsed = true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tpanel.IsCollapsed = false;\n\t\t\t}\n\t\t}\n\n\t\tbool HeldOpenByMouse {\n\t\t\tget { return IsMouseOver || IsMouseCaptureWithin; }\n\t\t}\n\n\t\tprotected override void OnMouseLeave(MouseEventArgs e)\n\t\t{\n\t\t\tbase.OnMouseLeave(e);\n\t\t\tif (CanCollapse && !HeldOpenByMouse)\n\t\t\t\tIsCollapsed = true;\n\t\t}\n\n\t\tprotected override void OnLostMouseCapture(MouseEventArgs e)\n\t\t{\n\t\t\tbase.OnLostMouseCapture(e);\n\t\t\tif (CanCollapse && !HeldOpenByMouse)\n\t\t\t\tIsCollapsed = true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/CultureSelectionConverter.cs",
    "content": "// Copyright (c) 2021 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE\n\nusing System;\nusing System.Globalization;\nusing System.Windows.Data;\nusing System.Windows.Markup;\n\nnamespace ICSharpCode.ILSpy.Controls\n{\n\tpublic class CultureSelectionConverter : MarkupExtension, IValueConverter\n\t{\n\t\tpublic object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n\t\t{\n\t\t\tif (value is string s)\n\t\t\t\treturn s.Equals(parameter);\n\t\t\treturn value == parameter;\n\t\t}\n\n\t\tpublic object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n\t\t{\n\t\t\tif ((bool)value)\n\t\t\t\treturn parameter;\n\t\t\treturn Binding.DoNothing;\n\t\t}\n\n\t\tpublic override object ProvideValue(IServiceProvider serviceProvider)\n\t\t{\n\t\t\treturn this;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/CustomDialog.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace ICSharpCode.ILSpy.Controls\n{\n\tpublic sealed class CustomDialog : System.Windows.Forms.Form\n\t{\n\t\tSystem.Windows.Forms.Label label;\n\t\tSystem.Windows.Forms.Panel panel;\n\t\tint acceptButton;\n\t\tint cancelButton;\n\t\tint result = -1;\n\n\t\t/// <summary>\n\t\t/// Gets the index of the button pressed.\n\t\t/// </summary>\n\t\tpublic int Result {\n\t\t\tget {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\n\t\tpublic CustomDialog(string caption, string message, int acceptButton, int cancelButton, string[] buttonLabels)\n\t\t{\n\t\t\tthis.SuspendLayout();\n\t\t\tMyInitializeComponent();\n\n\t\t\tthis.Icon = null;\n\t\t\tthis.acceptButton = acceptButton;\n\t\t\tthis.cancelButton = cancelButton;\n\t\t\tthis.Text = caption;\n\n\t\t\tusing (Graphics g = this.CreateGraphics())\n\t\t\t{\n\t\t\t\tSize size = TextRenderer.MeasureText(message, label.Font, new((int)(Screen.FromControl(this).WorkingArea.Width * 0.9), int.MaxValue), TextFormatFlags.NoPrefix | TextFormatFlags.WordBreak);\n\t\t\t\tSize clientSize = new Size((int)Math.Ceiling(size.Width * 96 / g.DpiX) + DockPadding.Left + DockPadding.Right, (int)Math.Ceiling(size.Height * 96 / g.DpiY) + DockPadding.Top + DockPadding.Bottom);\n\t\t\t\tButton[] buttons = new Button[buttonLabels.Length];\n\t\t\t\tint[] positions = new int[buttonLabels.Length];\n\t\t\t\tint pos = 0;\n\t\t\t\tfor (int i = 0; i < buttons.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tButton newButton = new Button();\n\t\t\t\t\tnewButton.FlatStyle = FlatStyle.System;\n\t\t\t\t\tnewButton.Tag = i;\n\t\t\t\t\tstring buttonLabel = buttonLabels[i];\n\t\t\t\t\tnewButton.Text = buttonLabel;\n\t\t\t\t\tnewButton.Click += new EventHandler(ButtonClick);\n\t\t\t\t\tSize buttonSize = TextRenderer.MeasureText(buttonLabel, newButton.Font);\n\t\t\t\t\tnewButton.Width = Math.Max(newButton.Width, ((int)Math.Ceiling(buttonSize.Width * 96 / g.DpiX / 8.0) + 1) * 8);\n\t\t\t\t\tpositions[i] = pos;\n\t\t\t\t\tbuttons[i] = newButton;\n\t\t\t\t\tpos += newButton.Width + 4;\n\t\t\t\t}\n\t\t\t\tif (acceptButton >= 0)\n\t\t\t\t{\n\t\t\t\t\tAcceptButton = buttons[acceptButton];\n\t\t\t\t}\n\t\t\t\tif (cancelButton >= 0)\n\t\t\t\t{\n\t\t\t\t\tCancelButton = buttons[cancelButton];\n\t\t\t\t}\n\n\t\t\t\tpos += 4; // add space before first button\n\t\t\t\t\t\t  // (we don't start with pos=4 because this space doesn't belong to the button panel)\n\n\t\t\t\tif (pos > clientSize.Width)\n\t\t\t\t{\n\t\t\t\t\tclientSize.Width = pos;\n\t\t\t\t}\n\t\t\t\tclientSize.Height += panel.Height;\n\t\t\t\tthis.ClientSize = clientSize;\n\t\t\t\tint start = (clientSize.Width - pos) / 2;\n\t\t\t\tfor (int i = 0; i < buttons.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tbuttons[i].Location = new Point(start + positions[i], 4);\n\t\t\t\t}\n\t\t\t\tpanel.Controls.AddRange(buttons);\n\t\t\t}\n\t\t\tlabel.Text = message;\n\n\t\t\tthis.ResumeLayout(false);\n\t\t}\n\n\t\tprotected override void OnKeyDown(KeyEventArgs e)\n\t\t{\n\t\t\tif (cancelButton == -1 && e.KeyCode == Keys.Escape)\n\t\t\t{\n\t\t\t\tthis.Close();\n\t\t\t}\n\t\t\telse if (e.KeyCode == Keys.C && e.Control)\n\t\t\t{\n\t\t\t\tClipboard.SetText(this.Text + Environment.NewLine + label.Text);\n\t\t\t}\n\t\t}\n\n\t\tvoid ButtonClick(object sender, EventArgs e)\n\t\t{\n\t\t\tresult = (int)((Control)sender).Tag;\n\t\t\tthis.Close();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// This method is required for Windows Forms designer support.\n\t\t/// Do not change the method contents inside the source code editor. The Forms designer might\n\t\t/// not be able to load this method if it was changed manually.\n\t\t/// </summary>\n\t\tvoid MyInitializeComponent()\n\t\t{\n\t\t\tthis.panel = new System.Windows.Forms.Panel();\n\t\t\tthis.label = new System.Windows.Forms.Label();\n\t\t\t// \n\t\t\t// panel\n\t\t\t// \n\t\t\tthis.panel.Dock = System.Windows.Forms.DockStyle.Bottom;\n\t\t\tthis.panel.Location = new System.Drawing.Point(4, 80);\n\t\t\tthis.panel.Name = \"panel\";\n\t\t\tthis.panel.Size = new System.Drawing.Size(266, 32);\n\t\t\tthis.panel.TabIndex = 0;\n\t\t\t// \n\t\t\t// label\n\t\t\t// \n\t\t\tthis.label.Dock = System.Windows.Forms.DockStyle.Fill;\n\t\t\tthis.label.FlatStyle = System.Windows.Forms.FlatStyle.System;\n\t\t\tthis.label.Location = new System.Drawing.Point(4, 4);\n\t\t\tthis.label.Name = \"label\";\n\t\t\tthis.label.Size = new System.Drawing.Size(266, 76);\n\t\t\tthis.label.TabIndex = 1;\n\t\t\tthis.label.UseMnemonic = false;\n\t\t\t// \n\t\t\t// CustomDialog\n\t\t\t// \n\t\t\tthis.ClientSize = new System.Drawing.Size(274, 112);\n\t\t\tthis.Controls.Add(this.label);\n\t\t\tthis.Controls.Add(this.panel);\n\t\t\tthis.DockPadding.Left = 4;\n\t\t\tthis.DockPadding.Right = 4;\n\t\t\tthis.DockPadding.Top = 4;\n\t\t\tthis.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;\n\t\t\tthis.ShowInTaskbar = false;\n\t\t\tthis.MaximizeBox = false;\n\t\t\tthis.MinimizeBox = false;\n\t\t\tthis.Name = \"CustomDialog\";\n\t\t\tthis.KeyPreview = true;\n\t\t\tthis.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;\n\t\t\tthis.Text = \"CustomDialog\";\n\t\t\tthis.AutoScaleMode = AutoScaleMode.Dpi;\n\t\t\tthis.AutoScaleDimensions = new SizeF(96, 96);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/ExtensionMethods.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Windows;\nusing System.Windows.Markup;\n\nnamespace ICSharpCode.ILSpy.Controls\n{\n\t/// <summary>\n\t/// ExtensionMethods used in ILSpy.\n\t/// </summary>\n\tpublic static class ExtensionMethods\n\t{\n\t\t/// <summary>\n\t\t/// Sets the value of a dependency property on <paramref name=\"targetObject\"/> using a markup extension.\n\t\t/// </summary>\n\t\t/// <remarks>This method does not support markup extensions like x:Static that depend on\n\t\t/// having a XAML file as context.</remarks>\n\t\tpublic static void SetValueToExtension(this DependencyObject targetObject, DependencyProperty property, MarkupExtension markupExtension)\n\t\t{\n\t\t\t// This method was copied from ICSharpCode.Core.Presentation (with permission to switch license to X11)\n\n\t\t\tif (targetObject == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(targetObject));\n\t\t\tif (property == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(property));\n\t\t\tif (markupExtension == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(markupExtension));\n\n\t\t\tvar serviceProvider = new SetValueToExtensionServiceProvider(targetObject, property);\n\t\t\ttargetObject.SetValue(property, markupExtension.ProvideValue(serviceProvider));\n\t\t}\n\n\t\tsealed class SetValueToExtensionServiceProvider : IServiceProvider, IProvideValueTarget\n\t\t{\n\t\t\t// This class was copied from ICSharpCode.Core.Presentation (with permission to switch license to X11)\n\n\t\t\treadonly DependencyObject targetObject;\n\t\t\treadonly DependencyProperty targetProperty;\n\n\t\t\tpublic SetValueToExtensionServiceProvider(DependencyObject targetObject, DependencyProperty property)\n\t\t\t{\n\t\t\t\tthis.targetObject = targetObject;\n\t\t\t\tthis.targetProperty = property;\n\t\t\t}\n\n\t\t\tpublic object GetService(Type serviceType)\n\t\t\t{\n\t\t\t\tif (serviceType == typeof(IProvideValueTarget))\n\t\t\t\t\treturn this;\n\t\t\t\telse\n\t\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tpublic object TargetObject {\n\t\t\t\tget { return targetObject; }\n\t\t\t}\n\n\t\t\tpublic object TargetProperty {\n\t\t\t\tget { return targetProperty; }\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/GridViewColumnAutoSize.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Windows;\nusing System.Windows.Controls;\n\nnamespace ICSharpCode.ILSpy.Controls\n{\n\t/// <summary>\n\t/// This class adds the AutoWidth property to the WPF ListView.\n\t/// It supports a semi-colon-separated list of values, for each defined cell.\n\t/// Each value can either be a fixed size double, or a percentage.\n\t/// The sizes of columns with a percentage will be calculated from the\n\t/// remaining width (after assigning the fixed sizes).\n\t/// Examples: 50%;25%;25% or 30;100%;50\n\t/// </summary>\n\tpublic class GridViewColumnAutoSize\n\t{\n\t\t// This class was copied from ICSharpCode.Core.Presentation.\n\n\t\tpublic static readonly DependencyProperty AutoWidthProperty =\n\t\t\tDependencyProperty.RegisterAttached(\"AutoWidth\", typeof(string), typeof(GridViewColumnAutoSize),\n\t\t\t\t\t\t\t\t\t\t\t\tnew FrameworkPropertyMetadata(null, AutoWidthPropertyChanged));\n\n\t\tpublic static string GetAutoWidth(DependencyObject obj)\n\t\t{\n\t\t\treturn (string)obj.GetValue(AutoWidthProperty);\n\t\t}\n\n\t\tpublic static void SetAutoWidth(DependencyObject obj, string value)\n\t\t{\n\t\t\tobj.SetValue(AutoWidthProperty, value);\n\t\t}\n\n\t\tstatic void AutoWidthPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)\n\t\t{\n\t\t\tListView grid = sender as ListView;\n\t\t\tif (grid == null)\n\t\t\t\treturn;\n\t\t\tgrid.SizeChanged += delegate (object listView, SizeChangedEventArgs e) {\n\t\t\t\tListView lv = listView as ListView;\n\t\t\t\tif (lv == null)\n\t\t\t\t\treturn;\n\t\t\t\tGridView v = lv.View as GridView;\n\t\t\t\tif (v == null)\n\t\t\t\t\treturn;\n\t\t\t\tCalculateSizes(v, GetAutoWidth(lv), e.NewSize.Width);\n\t\t\t};\n\t\t\tGridView view = grid.View as GridView;\n\t\t\tif (view == null)\n\t\t\t\treturn;\n\t\t\tCalculateSizes(view, args.NewValue as string, grid.ActualWidth);\n\t\t}\n\n\t\tstatic void CalculateSizes(GridView view, string sizeValue, double fullWidth)\n\t\t{\n\t\t\tstring[] sizes = (sizeValue ?? \"\").Split(';');\n\n\t\t\tif (sizes.Length != view.Columns.Count)\n\t\t\t\treturn;\n\t\t\tDictionary<int, Func<double, double>> percentages = new Dictionary<int, Func<double, double>>();\n\t\t\tdouble remainingWidth = fullWidth - 30; // 30 is a good offset for the scrollbar\n\n\t\t\tfor (int i = 0; i < view.Columns.Count; i++)\n\t\t\t{\n\t\t\t\tvar column = view.Columns[i];\n\t\t\t\tdouble size;\n\t\t\t\tbool isPercentage = !double.TryParse(sizes[i], out size);\n\t\t\t\tif (isPercentage)\n\t\t\t\t{\n\t\t\t\t\tsize = double.Parse(sizes[i].TrimEnd('%', ' '));\n\t\t\t\t\tpercentages.Add(i, w => w * size / 100.0);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcolumn.Width = size;\n\t\t\t\t\tremainingWidth -= size;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (remainingWidth < 0)\n\t\t\t\treturn;\n\t\t\tforeach (var p in percentages)\n\t\t\t{\n\t\t\t\tvar column = view.Columns[p.Key];\n\t\t\t\tcolumn.Width = p.Value(remainingWidth);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/MainMenu.xaml",
    "content": "<UserControl x:Class=\"ICSharpCode.ILSpy.Controls.MainMenu\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n             xmlns:local=\"clr-namespace:ICSharpCode.ILSpy.Controls\"\n             xmlns:properties=\"clr-namespace:ICSharpCode.ILSpy.Properties\"\n             xmlns:themes=\"clr-namespace:ICSharpCode.ILSpy.Themes\"\n             xmlns:composition=\"urn:TomsToolbox.Composition\"\n             xmlns:toms=\"urn:TomsToolbox\"\n             xmlns:commands=\"clr-namespace:ICSharpCode.ILSpy.Commands\"\n             mc:Ignorable=\"d\" d:DesignWidth=\"800\" DataContext=\"{Binding RelativeSource={RelativeSource Self}}\">\n\t<Menu DockPanel.Dock=\"Top\" Name=\"Menu\" Height=\"23\" KeyboardNavigation.TabNavigation=\"None\">\n\t\t<MenuItem Header=\"{x:Static properties:Resources._File}\" Tag=\"_File\">\n\t\t\t<!-- content of file menu is added using MEF -->\n\t\t</MenuItem>\n\t\t<MenuItem Header=\"{x:Static properties:Resources._View}\" Tag=\"_View\">\n\t\t\t<MenuItem Header=\"{x:Static properties:Resources.Show_publiconlyTypesMembers}\" IsCheckable=\"True\"\n\t\t\t          IsChecked=\"{Binding SessionSettings.LanguageSettings.ApiVisPublicOnly}\" />\n\t\t\t<MenuItem Header=\"{x:Static properties:Resources.Show_internalTypesMembers}\" IsCheckable=\"True\"\n\t\t\t          IsChecked=\"{Binding SessionSettings.LanguageSettings.ApiVisPublicAndInternal}\" />\n\t\t\t<MenuItem Header=\"{x:Static properties:Resources.Show_allTypesAndMembers}\" IsCheckable=\"True\"\n\t\t\t          IsChecked=\"{Binding SessionSettings.LanguageSettings.ApiVisAll}\" />\n\t\t\t<Separator />\n\t\t\t<MenuItem Header=\"{x:Static properties:Resources.Theme}\" ItemsSource=\"{x:Static themes:ThemeManager.AllThemes}\">\n\t\t\t\t<MenuItem.ItemContainerStyle>\n\t\t\t\t\t<Style TargetType=\"{x:Type MenuItem}\" BasedOn=\"{StaticResource {x:Type MenuItem}}\">\n\t\t\t\t\t\t<Setter Property=\"Command\" Value=\"{composition:Import commands:SetThemeCommand}\" />\n\t\t\t\t\t\t<Setter Property=\"CommandParameter\" Value=\"{Binding}\" />\n\t\t\t\t\t\t<Setter Property=\"IsCheckable\" Value=\"True\" />\n\t\t\t\t\t\t<!-- Required by AvalonDock's MenuItem style to show the checkmark -->\n\t\t\t\t\t\t<Setter Property=\"IsChecked\">\n\t\t\t\t\t\t\t<Setter.Value>\n\t\t\t\t\t\t\t\t<MultiBinding Converter=\"{x:Static toms:BinaryOperationConverter.Equality}\" Mode=\"OneWay\">\n\t\t\t\t\t\t\t\t\t<Binding />\n\t\t\t\t\t\t\t\t\t<Binding Path=\"SessionSettings.Theme\"\n\t\t\t\t\t\t\t\t\t         RelativeSource=\"{RelativeSource FindAncestor, AncestorType=UserControl}\" />\n\t\t\t\t\t\t\t\t</MultiBinding>\n\t\t\t\t\t\t\t</Setter.Value>\n\t\t\t\t\t\t</Setter>\n\t\t\t\t\t</Style>\n\t\t\t\t</MenuItem.ItemContainerStyle>\n\t\t\t</MenuItem>\n\t\t\t<MenuItem Header=\"{x:Static properties:Resources.UILanguage}\">\n\t\t\t\t<MenuItem Header=\"{x:Static properties:Resources.UILanguage_System}\" IsCheckable=\"True\"\n\t\t\t\t          IsChecked=\"{Binding SessionSettings.CurrentCulture, Converter={local:CultureSelectionConverter}, ConverterParameter={x:Null}}\" />\n\t\t\t</MenuItem>\n\t\t</MenuItem>\n\t\t<MenuItem x:Name=\"WindowMenuItem\" Header=\"{x:Static properties:Resources._Window}\" Tag=\"_Window\">\n\t\t\t<!-- content of window menu is added using MEF -->\n\t\t</MenuItem>\n\t</Menu>\n</UserControl>"
  },
  {
    "path": "ILSpy/Controls/MainMenu.xaml.cs",
    "content": "// Copyright (c) 2024 Tom Englert for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Globalization;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Input;\n\nusing ICSharpCode.ILSpy.Commands;\n\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpy.ViewModels;\n\nusing TomsToolbox.Composition;\nusing TomsToolbox.ObservableCollections;\nusing TomsToolbox.Wpf;\nusing TomsToolbox.Wpf.Converters;\n\nnamespace ICSharpCode.ILSpy.Controls\n{\n\t/// <summary>\n\t/// Interaction logic for MainMenu.xaml\n\t/// </summary>\n\t[Export]\n\t[NonShared]\n\tpublic partial class MainMenu\n\t{\n\t\tpublic MainMenu(SettingsService settingsService, IExportProvider exportProvider, DockWorkspace dockWorkspace)\n\t\t{\n\t\t\tSessionSettings = settingsService.SessionSettings;\n\n\t\t\tInitializeComponent();\n\n\t\t\tthis.BeginInvoke(() => {\n\t\t\t\tInitMainMenu(Menu, exportProvider);\n\t\t\t\tInitWindowMenu(WindowMenuItem, Window.GetWindow(this)!.InputBindings, dockWorkspace);\n\t\t\t});\n\t\t}\n\n\t\tpublic SessionSettings SessionSettings { get; }\n\n\t\tstatic void InitMainMenu(Menu mainMenu, IExportProvider exportProvider)\n\t\t{\n\t\t\tvar mainMenuCommands = exportProvider.GetExports<ICommand, IMainMenuCommandMetadata>(\"MainMenuCommand\");\n\t\t\t// Start by constructing the individual flat menus\n\t\t\tvar parentMenuItems = new Dictionary<string, MenuItem>();\n\t\t\tvar menuGroups = mainMenuCommands.OrderBy(c => c.Metadata?.MenuOrder).GroupBy(c => c.Metadata?.ParentMenuID).ToArray();\n\t\t\tforeach (var menu in menuGroups)\n\t\t\t{\n\t\t\t\t// Get or add the target menu item and add all items grouped by menu category\n\t\t\t\tvar parentMenuItem = GetOrAddParentMenuItem(menu.Key, menu.Key);\n\t\t\t\tforeach (var category in menu.GroupBy(c => c.Metadata?.MenuCategory))\n\t\t\t\t{\n\t\t\t\t\tif (parentMenuItem.Items.Count > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tparentMenuItem.Items.Add(new Separator { Tag = category.Key });\n\t\t\t\t\t}\n\t\t\t\t\tforeach (var entry in category)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (menuGroups.Any(g => g.Key == entry.Metadata?.MenuID))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar menuItem = GetOrAddParentMenuItem(entry.Metadata?.MenuID, entry.Metadata?.Header);\n\t\t\t\t\t\t\t// replace potential dummy text with real name\n\t\t\t\t\t\t\tmenuItem.Header = ResourceHelper.GetString(entry.Metadata?.Header);\n\t\t\t\t\t\t\tparentMenuItem.Items.Add(menuItem);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar command = entry.Value;\n\n\t\t\t\t\t\t\tvar menuItem = new MenuItem {\n\t\t\t\t\t\t\t\tCommand = CommandWrapper.Unwrap(command),\n\t\t\t\t\t\t\t\tTag = entry.Metadata?.MenuID,\n\t\t\t\t\t\t\t\tHeader = ResourceHelper.GetString(entry.Metadata?.Header)\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\tif (!string.IsNullOrEmpty(entry.Metadata?.MenuIcon))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmenuItem.Icon = new Image {\n\t\t\t\t\t\t\t\t\tWidth = 16,\n\t\t\t\t\t\t\t\t\tHeight = 16,\n\t\t\t\t\t\t\t\t\tSource = Images.Load(command, entry.Metadata.MenuIcon)\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tmenuItem.IsEnabled = entry.Metadata?.IsEnabled ?? false;\n\t\t\t\t\t\t\tmenuItem.InputGestureText = entry.Metadata?.InputGestureText;\n\n\t\t\t\t\t\t\tif (command is IProvideParameterBinding parameterBinding)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tBindingOperations.SetBinding(menuItem, MenuItem.CommandParameterProperty, parameterBinding.ParameterBinding);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tparentMenuItem.Items.Add(menuItem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach (var item in parentMenuItems.Values.Where(item => item.Parent == null))\n\t\t\t{\n\t\t\t\tmainMenu.Items.Add(item);\n\t\t\t}\n\n\t\t\tMenuItem GetOrAddParentMenuItem(string menuId, string resourceKey)\n\t\t\t{\n\t\t\t\tif (!parentMenuItems.TryGetValue(menuId, out var parentMenuItem))\n\t\t\t\t{\n\t\t\t\t\tvar topLevelMenuItem = mainMenu.Items.OfType<MenuItem>().FirstOrDefault(m => (string)m.Tag == menuId);\n\t\t\t\t\tif (topLevelMenuItem == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tparentMenuItem = new() {\n\t\t\t\t\t\t\tHeader = ResourceHelper.GetString(resourceKey),\n\t\t\t\t\t\t\tTag = menuId\n\t\t\t\t\t\t};\n\t\t\t\t\t\tparentMenuItems.Add(menuId, parentMenuItem);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tparentMenuItems.Add(menuId, topLevelMenuItem);\n\t\t\t\t\t\tparentMenuItem = topLevelMenuItem;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn parentMenuItem;\n\t\t\t}\n\t\t}\n\n\t\tstatic void InitWindowMenu(MenuItem windowMenuItem, InputBindingCollection inputBindings, DockWorkspace dockWorkspace)\n\t\t{\n\t\t\tvar defaultItems = windowMenuItem.Items.Cast<Control>().ToArray();\n\n\t\t\twindowMenuItem.Items.Clear();\n\n\t\t\tvar toolItems = dockWorkspace.ToolPanes.Select(toolPane => CreateMenuItem(toolPane, inputBindings, dockWorkspace)).ToArray();\n\t\t\tvar tabItems = dockWorkspace.TabPages.ObservableSelect(tabPage => CreateMenuItem(tabPage, dockWorkspace));\n\n\t\t\tvar allItems = new ObservableCompositeCollection<Control>(defaultItems, [new Separator()], toolItems, [new Separator()], tabItems);\n\n\t\t\twindowMenuItem.ItemsSource = allItems;\n\t\t}\n\n\t\tstatic Control CreateMenuItem(TabPageModel pane, DockWorkspace dockWorkspace)\n\t\t{\n\t\t\tvar header = new TextBlock {\n\t\t\t\tMaxWidth = 200,\n\t\t\t\tTextTrimming = TextTrimming.CharacterEllipsis\n\t\t\t};\n\n\t\t\theader.SetBinding(TextBlock.TextProperty, new Binding(nameof(pane.Title)) {\n\t\t\t\tSource = pane\n\t\t\t});\n\n\t\t\tvar menuItem = new MenuItem {\n\t\t\t\tCommand = new TabPageCommand(pane, dockWorkspace),\n\t\t\t\tHeader = header,\n\t\t\t\tIsCheckable = true\n\t\t\t};\n\n\t\t\tmenuItem.SetBinding(MenuItem.IsCheckedProperty, new Binding(nameof(dockWorkspace.ActiveTabPage)) {\n\t\t\t\tSource = dockWorkspace,\n\t\t\t\tConverterParameter = pane,\n\t\t\t\tConverter = BinaryOperationConverter.Equality,\n\t\t\t\tMode = BindingMode.OneWay\n\t\t\t});\n\n\t\t\treturn menuItem;\n\t\t}\n\n\t\tstatic Control CreateMenuItem(ToolPaneModel pane, InputBindingCollection inputBindings, DockWorkspace dockWorkspace)\n\t\t{\n\t\t\tvar menuItem = new MenuItem {\n\t\t\t\tCommand = pane.AssociatedCommand ?? new ToolPaneCommand(pane.ContentId, dockWorkspace),\n\t\t\t\tHeader = pane.Title\n\t\t\t};\n\t\t\tvar shortcutKey = pane.ShortcutKey;\n\t\t\tif (shortcutKey != null)\n\t\t\t{\n\t\t\t\tinputBindings.Add(new InputBinding(menuItem.Command, shortcutKey));\n\t\t\t\tmenuItem.InputGestureText = shortcutKey.GetDisplayStringForCulture(CultureInfo.CurrentUICulture);\n\t\t\t}\n\t\t\tif (!string.IsNullOrEmpty(pane.Icon))\n\t\t\t{\n\t\t\t\tmenuItem.Icon = new Image {\n\t\t\t\t\tWidth = 16,\n\t\t\t\t\tHeight = 16,\n\t\t\t\t\tSource = Images.Load(pane, pane.Icon)\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn menuItem;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/MainToolBar.xaml",
    "content": "<UserControl x:Class=\"ICSharpCode.ILSpy.Controls.MainToolBar\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n             xmlns:toms=\"urn:TomsToolbox\"\n             xmlns:properties=\"clr-namespace:ICSharpCode.ILSpy.Properties\"\n             xmlns:controls=\"clr-namespace:ICSharpCode.ILSpy.Controls\"\n             xmlns:themes=\"clr-namespace:ICSharpCode.ILSpy.Themes\"\n             xmlns:composition=\"urn:TomsToolbox.Composition\"\n             xmlns:ilSpy=\"clr-namespace:ICSharpCode.ILSpy\"\n             mc:Ignorable=\"d\" d:DesignWidth=\"800\">\n\t<ToolBar Name=\"ToolBar\"\n\t         DockPanel.Dock=\"Top\" ToolBarTray.IsLocked=\"True\" KeyboardNavigation.TabNavigation=\"None\">\n\t\t<ToolBar.Resources>\n\t\t\t<!-- Make images transparent if menu command is disabled -->\n\t\t\t<Style TargetType=\"{x:Type Image}\">\n\t\t\t\t<Style.Triggers>\n\t\t\t\t\t<DataTrigger Binding=\"{Binding RelativeSource={RelativeSource AncestorType={x:Type ButtonBase}, AncestorLevel=1}, Path=IsEnabled}\" Value=\"False\">\n\t\t\t\t\t\t<Setter Property=\"Opacity\" Value=\"0.30\" />\n\t\t\t\t\t</DataTrigger>\n\t\t\t\t</Style.Triggers>\n\t\t\t</Style>\n\t\t\t<Style TargetType=\"{x:Type Image}\" x:Key=\"DarkModeAwareImageStyle\">\n\t\t\t\t<Setter Property=\"Effect\" Value=\"{DynamicResource {x:Static themes:ResourceKeys.ThemeAwareButtonEffect}}\" />\n\t\t\t\t<Style.Triggers>\n\t\t\t\t\t<DataTrigger Binding=\"{Binding RelativeSource={RelativeSource AncestorType={x:Type ButtonBase}, AncestorLevel=1}, Path=IsEnabled}\" Value=\"False\">\n\t\t\t\t\t\t<Setter Property=\"Opacity\" Value=\"0.30\" />\n\t\t\t\t\t</DataTrigger>\n\t\t\t\t</Style.Triggers>\n\t\t\t</Style>\n\t\t</ToolBar.Resources>\n\t\t<!-- 'Navigation' toolbar category is inserted here -->\n\t\t<Separator />\n\t\t<!-- 'Open' toolbar category is inserted here -->\n\t\t<Separator />\n\t\t<Grid Margin=\"2,0\">\n\t\t\t<ItemsControl ItemsSource=\"{Binding AssemblyListManager.AssemblyLists}\" Height=\"0\" Margin=\"15,0\" />\n\t\t\t<ComboBox Name=\"assemblyListComboBox\" MaxDropDownHeight=\"Auto\"\n\t\t\t          ItemsSource=\"{Binding AssemblyListManager.AssemblyLists}\"\n\t\t\t          ToolTip=\"{x:Static properties:Resources.SelectAssemblyListDropdownTooltip}\"\n\t\t\t          SelectedItem=\"{Binding SessionSettings.ActiveAssemblyList}\" />\n\t\t</Grid>\n\t\t<Button Command=\"{composition:Import ilSpy:ManageAssemblyListsCommand}\"\n\t\t        CommandParameter=\"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}\"\n\t\t        ToolTip=\"{x:Static properties:Resources.ManageAssemblyLists}\">\n\t\t\t<Image Width=\"16\" Height=\"16\" Source=\"{controls:XamlResource Images/AssemblyList}\"\n\t\t\t       Style=\"{StaticResource DarkModeAwareImageStyle}\" />\n\t\t</Button>\n\t\t<Separator />\n\t\t<CheckBox IsChecked=\"{Binding SessionSettings.LanguageSettings.ApiVisPublicOnly}\"\n\t\t          ToolTip=\"{x:Static properties:Resources.ShowPublicOnlyTypesMembers}\">\n\t\t\t<Image Width=\"16\" Height=\"16\" Source=\"{controls:XamlResource Images/ShowPublicOnly}\"\n\t\t\t       Style=\"{StaticResource DarkModeAwareImageStyle}\" />\n\t\t</CheckBox>\n\t\t<CheckBox IsChecked=\"{Binding SessionSettings.LanguageSettings.ApiVisPublicAndInternal}\"\n\t\t          ToolTip=\"{x:Static properties:Resources.ShowInternalTypesMembers}\">\n\t\t\t<Image Width=\"16\" Height=\"16\" Source=\"{controls:XamlResource Images/ShowPrivateInternal}\"\n\t\t\t       Style=\"{StaticResource DarkModeAwareImageStyle}\" />\n\t\t</CheckBox>\n\t\t<CheckBox IsChecked=\"{Binding SessionSettings.LanguageSettings.ApiVisAll}\"\n\t\t          ToolTip=\"{x:Static properties:Resources.ShowAllTypesAndMembers}\">\n\t\t\t<Image Width=\"16\" Height=\"16\" Source=\"{controls:XamlResource Images/ShowAll}\"\n\t\t\t       Style=\"{StaticResource DarkModeAwareImageStyle}\" />\n\t\t</CheckBox>\n\t\t<Separator />\n\t\t<Grid Margin=\"2,0\">\n\t\t\t<ItemsControl ItemsSource=\"{Binding LanguageService.AllLanguages}\" DisplayMemberPath=\"Name\" Height=\"0\" Margin=\"15,0\" />\n\t\t\t<ComboBox Name=\"languageComboBox\" DisplayMemberPath=\"Name\" MaxDropDownHeight=\"Auto\"\n\t\t\t          IsEnabled=\"{Binding Workspace.ActiveTabPage.SupportsLanguageSwitching}\"\n\t\t\t          ItemsSource=\"{Binding LanguageService.AllLanguages}\"\n\t\t\t          ToolTip=\"{x:Static properties:Resources.SelectLanguageDropdownTooltip}\"\n\t\t\t          SelectedItem=\"{Binding LanguageService.Language}\" />\n\t\t</Grid>\n\t\t<Grid Margin=\"2,0\">\n\t\t\t<ItemsControl\n\t\t\t\tItemsSource=\"{Binding SelectedItem.LanguageVersions, ElementName=languageComboBox, UpdateSourceTrigger=PropertyChanged}\"\n\t\t\t\tVisibility=\"{Binding SelectedItem.HasLanguageVersions, ElementName=languageComboBox, Converter={toms:BooleanToVisibilityConverter}}\"\n\t\t\t\tDisplayMemberPath=\"DisplayName\" Height=\"0\" Margin=\"15,0\" />\n\t\t\t<ComboBox Name=\"languageVersionComboBox\" DisplayMemberPath=\"DisplayName\" MaxDropDownHeight=\"Auto\"\n\t\t\t          ToolTip=\"{x:Static properties:Resources.SelectVersionDropdownTooltip}\"\n\t\t\t          Visibility=\"{Binding SelectedItem.HasLanguageVersions, ElementName=languageComboBox, Converter={toms:BooleanToVisibilityConverter}}\"\n\t\t\t          IsEnabled=\"{Binding Workspace.ActiveTabPage.SupportsLanguageSwitching}\"\n\t\t\t          ItemsSource=\"{Binding SelectedItem.LanguageVersions, ElementName=languageComboBox, UpdateSourceTrigger=PropertyChanged}\"\n\t\t\t          SelectedItem=\"{Binding LanguageService.LanguageVersion, UpdateSourceTrigger=PropertyChanged}\" />\n\t\t</Grid>\n\t</ToolBar>\n</UserControl>"
  },
  {
    "path": "ILSpy/Controls/MainToolBar.xaml.cs",
    "content": "// Copyright (c) 2024 Tom Englert for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.ComponentModel;\nusing System.Composition;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Controls.Primitives;\nusing System.Windows.Data;\nusing System.Windows.Input;\nusing System.Windows.Media;\nusing System.Windows.Threading;\n\nusing ICSharpCode.ILSpy.Themes;\nusing ICSharpCode.ILSpyX.TreeView;\n\nusing TomsToolbox.Composition;\n\nnamespace ICSharpCode.ILSpy.Controls\n{\n\t/// <summary>\n\t/// Interaction logic for MainToolBar.xaml\n\t/// </summary>\n\t[Export]\n\t[NonShared]\n\tpublic partial class MainToolBar\n\t{\n\t\tpublic MainToolBar(IExportProvider exportProvider)\n\t\t{\n\t\t\tInitializeComponent();\n\n\t\t\tthis.Dispatcher.BeginInvoke(DispatcherPriority.Background, () => {\n\t\t\t\tInitToolbar(ToolBar, exportProvider);\n\t\t\t\tWindow.GetWindow(this)!.KeyDown += MainWindow_KeyDown;\n\t\t\t});\n\t\t}\n\n\t\tstatic void InitToolbar(ToolBar toolBar, IExportProvider exportProvider)\n\t\t{\n\t\t\tint navigationPos = 0;\n\t\t\tint openPos = 1;\n\t\t\tvar toolbarCommandsByCategory = exportProvider\n\t\t\t\t.GetExports<ICommand, IToolbarCommandMetadata>(\"ToolbarCommand\")\n\t\t\t\t.OrderBy(c => c.Metadata?.ToolbarOrder)\n\t\t\t\t.GroupBy(c => c.Metadata?.ToolbarCategory);\n\n\t\t\tforeach (var commandCategory in toolbarCommandsByCategory)\n\t\t\t{\n\t\t\t\tif (commandCategory.Key == nameof(Properties.Resources.Navigation))\n\t\t\t\t{\n\t\t\t\t\tforeach (var command in commandCategory)\n\t\t\t\t\t{\n\t\t\t\t\t\ttoolBar.Items.Insert(navigationPos++, CreateToolbarItem(command));\n\t\t\t\t\t\topenPos++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (commandCategory.Key == nameof(Properties.Resources.Open))\n\t\t\t\t{\n\t\t\t\t\tforeach (var command in commandCategory)\n\t\t\t\t\t{\n\t\t\t\t\t\ttoolBar.Items.Insert(openPos++, CreateToolbarItem(command));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ttoolBar.Items.Add(new Separator());\n\t\t\t\t\tforeach (var command in commandCategory)\n\t\t\t\t\t{\n\t\t\t\t\t\ttoolBar.Items.Add(CreateToolbarItem(command));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic UIElement CreateToolbarItem(IExport<ICommand, IToolbarCommandMetadata> commandExport)\n\t\t{\n\t\t\tvar command = commandExport.Value;\n\n\t\t\tButton toolbarItem = new() {\n\t\t\t\tStyle = ThemeManager.Current.CreateToolBarButtonStyle(),\n\t\t\t\tCommand = CommandWrapper.Unwrap(command),\n\t\t\t\tToolTip = Properties.Resources.ResourceManager.GetString(\n\t\t\t\t\tcommandExport.Metadata?.ToolTip ?? string.Empty),\n\t\t\t\tTag = commandExport.Metadata?.Tag,\n\t\t\t\tContent = new Image {\n\t\t\t\t\tWidth = 16,\n\t\t\t\t\tHeight = 16,\n\t\t\t\t\tSource = Images.Load(command, commandExport.Metadata?.ToolbarIcon)\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tif (command is IProvideParameterBinding parameterBinding)\n\t\t\t{\n\t\t\t\tBindingOperations.SetBinding(toolbarItem, ButtonBase.CommandParameterProperty,\n\t\t\t\t\tparameterBinding.ParameterBinding);\n\t\t\t}\n\n\t\t\tif (command is IProvideParameterList parameterList)\n\t\t\t{\n\t\t\t\ttoolbarItem.Margin = new Thickness(2, 0, 0, 0);\n\n\t\t\t\tvar dropDownPanel = new StackPanel { Orientation = Orientation.Horizontal };\n\n\t\t\t\tvar dropDownToggle = new ToggleButton {\n\t\t\t\t\tStyle = ThemeManager.Current.CreateToolBarToggleButtonStyle(),\n\t\t\t\t\tContent = \"▾\",\n\t\t\t\t\tPadding = new Thickness(0),\n\t\t\t\t\tMinWidth = 0,\n\t\t\t\t\tMargin = new Thickness(0, 0, 2, 0)\n\t\t\t\t};\n\n\t\t\t\tvar contextMenu = new ContextMenu {\n\t\t\t\t\tPlacementTarget = dropDownPanel,\n\t\t\t\t\tTag = command\n\t\t\t\t};\n\n\t\t\t\tContextMenuService.SetPlacement(toolbarItem, PlacementMode.Bottom);\n\t\t\t\ttoolbarItem.ContextMenu = contextMenu;\n\t\t\t\ttoolbarItem.ContextMenuOpening += (_, _) =>\n\t\t\t\t\tPrepareParameterList(contextMenu);\n\t\t\t\tdropDownToggle.Checked += (_, _) => {\n\t\t\t\t\tPrepareParameterList(contextMenu);\n\t\t\t\t\tcontextMenu.Placement = PlacementMode.Bottom;\n\t\t\t\t\tcontextMenu.SetCurrentValue(ContextMenu.IsOpenProperty, true);\n\t\t\t\t};\n\n\t\t\t\tBindingOperations.SetBinding(dropDownToggle, ToggleButton.IsCheckedProperty,\n\t\t\t\t\tnew Binding(nameof(contextMenu.IsOpen)) { Source = contextMenu });\n\n\t\t\t\tBindingOperations.SetBinding(dropDownToggle, IsEnabledProperty,\n\t\t\t\t\tnew Binding(nameof(IsEnabled)) { Source = toolbarItem });\n\n\t\t\t\t// When the toggle button is checked, clicking it to uncheck will dismiss the menu first\n\t\t\t\t// which unchecks the toggle button via binding above and the click is used to open it again.\n\t\t\t\t// This is a workaround to ignore the click to uncheck the already unchecked toggle button.\n\t\t\t\t// We have to ensure the dismissing click is on the toggle button, otherwise the flag\n\t\t\t\t// will not get cleared and menu will not open next time.\n\t\t\t\tMouse.AddPreviewMouseDownOutsideCapturedElementHandler(contextMenu, (_, e) => {\n\t\t\t\t\tvar point = e.GetPosition(dropDownToggle);\n\t\t\t\t\tdropDownToggle.Tag = dropDownToggle.InputHitTest(point);\n\t\t\t\t});\n\t\t\t\tdropDownToggle.PreviewMouseLeftButtonDown += (_, e) => {\n\t\t\t\t\te.Handled = dropDownToggle.Tag != null;\n\t\t\t\t\tdropDownToggle.Tag = null;\n\t\t\t\t};\n\n\t\t\t\tdropDownPanel.Children.Add(toolbarItem);\n\t\t\t\tdropDownPanel.Children.Add(dropDownToggle);\n\t\t\t\treturn dropDownPanel;\n\t\t\t}\n\n\t\t\treturn toolbarItem;\n\t\t}\n\n\t\tstatic void PrepareParameterList(ContextMenu menu)\n\t\t{\n\t\t\tconst int maximumParameterListCount = 20;\n\n\t\t\tvar command = (ICommand)menu.Tag;\n\t\t\tvar parameterList = (IProvideParameterList)command;\n\n\t\t\tmenu.Items.Clear();\n\t\t\tforeach (var parameter in parameterList.ParameterList)\n\t\t\t{\n\t\t\t\tMenuItem parameterItem = new MenuItem();\n\t\t\t\tparameterItem.Command = CommandWrapper.Unwrap(command);\n\t\t\t\tparameterItem.CommandParameter = parameter;\n\t\t\t\tparameterItem.CommandTarget = menu.PlacementTarget;\n\t\t\t\tparameterItem.InputGestureText = \" \";\n\n\t\t\t\tvar headerPresenter = new ContentPresenter { RecognizesAccessKey = false };\n\t\t\t\tparameterItem.Header = headerPresenter;\n\n\t\t\t\tvar header = parameterList.GetParameterText(parameter);\n\t\t\t\tswitch (header)\n\t\t\t\t{\n\t\t\t\t\tcase SharpTreeNode node:\n\t\t\t\t\t\theaderPresenter.Content = node.NavigationText;\n\t\t\t\t\t\tif (node.Icon is ImageSource icon)\n\t\t\t\t\t\t\tparameterItem.Icon = new Image {\n\t\t\t\t\t\t\t\tWidth = 16,\n\t\t\t\t\t\t\t\tHeight = 16,\n\t\t\t\t\t\t\t\tSource = icon\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\theaderPresenter.Content = header;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tmenu.Items.Add(parameterItem);\n\t\t\t\tif (menu.Items.Count >= maximumParameterListCount)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tvoid MainWindow_KeyDown(object sender, KeyEventArgs e)\n\t\t{\n\t\t\tif (e.Handled || e.KeyboardDevice.Modifiers != ModifierKeys.Alt || e.Key != Key.System)\n\t\t\t\treturn;\n\n\t\t\tswitch (e.SystemKey)\n\t\t\t{\n\t\t\t\tcase Key.A:\n\t\t\t\t\tassemblyListComboBox.Focus();\n\t\t\t\t\te.Handled = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase Key.L:\n\t\t\t\t\tlanguageComboBox.Focus();\n\t\t\t\t\te.Handled = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase Key.E: // Alt+V was already taken by _View menu\n\t\t\t\t\tlanguageVersionComboBox.Focus();\n\t\t\t\t\te.Handled = true;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Controls/MarkupExtensions.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Windows;\nusing System.Windows.Markup;\nusing System.Windows.Media;\n\nnamespace ICSharpCode.ILSpy.Controls\n{\n\t[MarkupExtensionReturnType(typeof(Color))]\n\tclass ControlColor : MarkupExtension\n\t{\n\t\treadonly float val;\n\n\t\t/// <summary>\n\t\t/// Amount of highlight (0..1)\n\t\t/// </summary>\n\t\tpublic float Highlight { get; set; }\n\n\t\t/// <summary>\n\t\t/// val: Color value in the range 105..255.\n\t\t/// </summary>\n\t\tpublic ControlColor(float val)\n\t\t{\n\t\t\tif (!(val >= 105 && val <= 255))\n\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(val));\n\t\t\tthis.val = val;\n\t\t}\n\n\t\tpublic override object ProvideValue(IServiceProvider serviceProvider)\n\t\t{\n\t\t\tif (val > 227)\n\t\t\t{\n\t\t\t\treturn Interpolate(227, SystemColors.ControlLightColor, 255, SystemColors.ControlLightLightColor);\n\t\t\t}\n\t\t\telse if (val > 160)\n\t\t\t{\n\t\t\t\treturn Interpolate(160, SystemColors.ControlDarkColor, 227, SystemColors.ControlLightColor);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn Interpolate(105, SystemColors.ControlDarkDarkColor, 160, SystemColors.ControlDarkColor);\n\t\t\t}\n\t\t}\n\n\t\tColor Interpolate(float v1, Color c1, float v2, Color c2)\n\t\t{\n\t\t\tfloat v = (val - v1) / (v2 - v1);\n\t\t\tColor c = c1 * (1 - v) + c2 * v;\n\t\t\treturn c * (1 - Highlight) + SystemColors.HighlightColor * Highlight;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Controls/ResourceObjectTable.xaml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<UserControl x:Class=\"ICSharpCode.ILSpy.Controls.ResourceObjectTable\"\n\t\t\t xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n\t\t\t xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n\t\t\t xmlns:properties=\"clr-namespace:ICSharpCode.ILSpy.Properties\"\n\t\t\t xmlns:local=\"clr-namespace:ICSharpCode.ILSpy.Controls\"\n\t\t\t Cursor=\"Arrow\">\n\t<UserControl.CommandBindings>\n\t\t<CommandBinding Command=\"ApplicationCommands.Copy\"\n\t\t\t\t\t\tExecuted=\"ExecuteCopy\"\n\t\t\t\t\t\tCanExecute=\"CanExecuteCopy\" />\n\t</UserControl.CommandBindings>\n\t<Grid Margin=\"5,0,0,0\">\n\t\t<Grid.Resources>\n\t\t\t<AlternationConverter x:Key=\"BackgroundConverter\">\n\t\t\t\t<SolidColorBrush Color=\"Transparent\" />\n\t\t\t\t<SolidColorBrush Color=\"#CCCC33\" Opacity=\"0.15\" />\n\t\t\t</AlternationConverter>\n\t\t\t<Style x:Key=\"alternatingWithBinding\"\n\t\t\t\t   TargetType=\"{x:Type ListViewItem}\" BasedOn=\"{StaticResource {x:Type ListViewItem}}\">\n\t\t\t\t<Setter Property=\"Background\"\n\t\t\t\t\t\tValue=\"{Binding RelativeSource={RelativeSource Self},\n\t\t\t\t\t Path=(ItemsControl.AlternationIndex),\n\t\t\t\t\t Converter={StaticResource BackgroundConverter}}\" />\n\t\t\t\t<Setter Property=\"ContextMenu\">\n\t\t\t\t\t<Setter.Value>\n\t\t\t\t\t\t<ContextMenu>\n\t\t\t\t\t\t\t<MenuItem Header=\"_Copy\" Command=\"ApplicationCommands.Copy\" />\n\t\t\t\t\t\t\t<MenuItem Header=\"Copy _name\" Command=\"ApplicationCommands.Copy\" CommandParameter=\"Key\" InputGestureText=\" \" />\n\t\t\t\t\t\t\t<MenuItem Header=\"Copy _value\" Command=\"ApplicationCommands.Copy\" CommandParameter=\"Value\" InputGestureText=\" \" />\n\t\t\t\t\t\t\t<MenuItem Header=\"Copy _type\" Command=\"ApplicationCommands.Copy\" CommandParameter=\"Type\" InputGestureText=\" \" />\n\t\t\t\t\t\t</ContextMenu>\n\t\t\t\t\t</Setter.Value>\n\t\t\t\t</Setter>\n\t\t\t</Style>\n\t\t</Grid.Resources>\n\t\t<Grid.RowDefinitions>\n\t\t\t<RowDefinition />\n\t\t\t<RowDefinition />\n\t\t\t<RowDefinition />\n\t\t</Grid.RowDefinitions>\n\t\t<Label Content=\"{x:Static properties:Resources.OtherResources}\"\n\t\t\t   FontFamily=\"Segoe UI\"\n\t\t\t   FontWeight=\"Bold\"\n\t\t\t   FontSize=\"12pt\" />\n\t\t<local:SearchBox x:Name=\"resourceFilterBox\" \n\t\t\t   FontFamily=\"Segoe UI\"\n\t\t\t   FontSize=\"9pt\"\n\t\t\t   Grid.Row=\"1\"\n\t\t\t   TextChanged=\"OnFilterTextChanged\" />\n\t\t<ListView Name=\"resourceListView\"\n\t\t\t\t  FontFamily=\"Segoe UI\"\n\t\t\t\t  FontSize=\"9pt\"\n\t\t\t\t  Foreground=\"Black\"\n\t\t\t\t  Grid.Row=\"2\"\n\t\t\t\t  AlternationCount=\"2\"\n\t\t\t\t  ItemContainerStyle=\"{StaticResource alternatingWithBinding}\"\n\t\t\t\t  local:SortableGridViewColumn.SortMode=\"Automatic\">\n\t\t\t<ListView.View>\n\t\t\t\t<GridView AllowsColumnReorder=\"False\">\n\t\t\t\t\t<GridView.Columns>\n\t\t\t\t\t\t<local:SortableGridViewColumn DisplayMemberBinding=\"{Binding Key}\" SortBy=\"Key\">\n\t\t\t\t\t\t\t<GridViewColumnHeader Content=\"{x:Static properties:Resources.Name}\"\n\t\t\t\t\t\t\t\t\t\t\t\t  HorizontalContentAlignment=\"Left\"\n\t\t\t\t\t\t\t\t\t\t\t\t  FontWeight=\"Bold\" />\n\t\t\t\t\t\t</local:SortableGridViewColumn>\n\t\t\t\t\t\t<local:SortableGridViewColumn DisplayMemberBinding=\"{Binding Value}\" SortBy=\"Value\">\n\t\t\t\t\t\t\t<GridViewColumnHeader Content=\"{x:Static properties:Resources.ValueString}\"\n\t\t\t\t\t\t\t\t\t\t\t\t  HorizontalContentAlignment=\"Left\"\n\t\t\t\t\t\t\t\t\t\t\t\t  FontWeight=\"Bold\" />\n\t\t\t\t\t\t</local:SortableGridViewColumn>\n\t\t\t\t\t\t<local:SortableGridViewColumn DisplayMemberBinding=\"{Binding Type}\" SortBy=\"Type\">\n\t\t\t\t\t\t\t<GridViewColumnHeader Content=\"{x:Static properties:Resources.Type}\"\n\t\t\t\t\t\t\t\t\t\t\t\t  HorizontalContentAlignment=\"Left\"\n\t\t\t\t\t\t\t\t\t\t\t\t  FontWeight=\"Bold\" />\n\t\t\t\t\t\t</local:SortableGridViewColumn>\n\t\t\t\t\t</GridView.Columns>\n\t\t\t\t</GridView>\n\t\t\t</ListView.View>\n\t\t</ListView>\n\t</Grid>\n</UserControl>"
  },
  {
    "path": "ILSpy/Controls/ResourceObjectTable.xaml.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Text;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Input;\n\nnamespace ICSharpCode.ILSpy.Controls\n{\n\t/// <summary>\n\t/// Interaction logic for ResourceObjectTable.xaml\n\t/// </summary>\n\tpublic partial class ResourceObjectTable : UserControl\n\t{\n\t\tICollectionView filteredView;\n\t\tstring filter;\n\n\t\tpublic ResourceObjectTable(IEnumerable resources, FrameworkElement container)\n\t\t{\n\t\t\tInitializeComponent();\n\t\t\t// set size to fit decompiler window\n\t\t\tcontainer.SizeChanged += OnParentSizeChanged;\n\t\t\tif (!double.IsNaN(container.ActualWidth))\n\t\t\t\tWidth = Math.Max(container.ActualWidth - 45, 0);\n\t\t\tMaxHeight = container.ActualHeight;\n\n\t\t\tfilteredView = CollectionViewSource.GetDefaultView(resources);\n\t\t\tfilteredView.Filter = OnResourceFilter;\n\t\t\tresourceListView.ItemsSource = filteredView;\n\t\t}\n\n\t\tprivate bool OnResourceFilter(object obj)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(filter))\n\t\t\t\treturn true;\n\n\t\t\tif (obj is TreeNodes.ResourcesFileTreeNode.SerializedObjectRepresentation item)\n\t\t\t\treturn item.Key?.Contains(filter, StringComparison.OrdinalIgnoreCase) == true ||\n\t\t\t\t\t   item.Value?.Contains(filter, StringComparison.OrdinalIgnoreCase) == true;\n\n\t\t\treturn false; // make it obvious search is not working\n\t\t}\n\n\t\tprivate void OnParentSizeChanged(object sender, SizeChangedEventArgs e)\n\t\t{\n\t\t\tif (e.WidthChanged && !double.IsNaN(e.NewSize.Width))\n\t\t\t\tWidth = Math.Max(e.NewSize.Width - 45, 0);\n\t\t\tif (e.HeightChanged)\n\t\t\t\tMaxHeight = e.NewSize.Height;\n\t\t}\n\n\t\tprivate void OnFilterTextChanged(object sender, TextChangedEventArgs e)\n\t\t{\n\t\t\tfilter = resourceFilterBox.Text;\n\t\t\tfilteredView?.Refresh();\n\t\t}\n\n\t\tvoid ExecuteCopy(object sender, ExecutedRoutedEventArgs args)\n\t\t{\n\t\t\tStringBuilder sb = new StringBuilder();\n\t\t\tforeach (var item in resourceListView.SelectedItems)\n\t\t\t{\n\t\t\t\tif (item is TreeNodes.ResourcesFileTreeNode.SerializedObjectRepresentation so)\n\t\t\t\t{\n\t\t\t\t\tswitch (args.Parameter)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase \"Key\":\n\t\t\t\t\t\t\tsb.AppendLine(so.Key);\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\tcase \"Value\":\n\t\t\t\t\t\t\tsb.AppendLine(so.Value);\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\tcase \"Type\":\n\t\t\t\t\t\t\tsb.AppendLine(so.Type);\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tsb.AppendLine($\"{so.Key}\\t{so.Value}\\t{so.Type}\");\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsb.AppendLine(item.ToString());\n\t\t\t}\n\t\t\tClipboard.SetText(sb.ToString());\n\t\t}\n\n\t\tvoid CanExecuteCopy(object sender, CanExecuteRoutedEventArgs args)\n\t\t{\n\t\t\targs.CanExecute = true;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Controls/ResourceStringTable.xaml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<UserControl x:Class=\"ICSharpCode.ILSpy.Controls.ResourceStringTable\"\n\t\t\t xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n\t\t\t xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n\t\t\t xmlns:local=\"clr-namespace:ICSharpCode.ILSpy.Controls\"\n\t\t\t xmlns:properties=\"clr-namespace:ICSharpCode.ILSpy.Properties\"\n\t\t\t Cursor=\"Arrow\">\n\t<UserControl.CommandBindings>\n\t\t<CommandBinding Command=\"ApplicationCommands.Copy\"\n\t\t\t\t\t\tExecuted=\"ExecuteCopy\"\n\t\t\t\t\t\tCanExecute=\"CanExecuteCopy\" />\n\t</UserControl.CommandBindings>\n\t<Grid Margin=\"5,0,0,0\">\n\t\t<Grid.Resources>\n\t\t\t<AlternationConverter x:Key=\"BackgroundConverter\">\n\t\t\t\t<SolidColorBrush Color=\"Transparent\" />\n\t\t\t\t<SolidColorBrush Color=\"#CCCC33\" Opacity=\"0.15\" />\n\t\t\t</AlternationConverter>\n\t\t\t<Style x:Key=\"alternatingWithBinding\"\n\t\t\t\t   TargetType=\"{x:Type ListViewItem}\" BasedOn=\"{StaticResource {x:Type ListViewItem}}\">\n\t\t\t\t<Setter Property=\"Background\"\n\t\t\t\t\t\tValue=\"{Binding RelativeSource={RelativeSource Self},\n\t\t\t\t\t Path=(ItemsControl.AlternationIndex),\n\t\t\t\t\t Converter={StaticResource BackgroundConverter}}\" />\n\t\t\t\t<Setter Property=\"ContextMenu\">\n\t\t\t\t\t<Setter.Value>\n\t\t\t\t\t\t<ContextMenu>\n\t\t\t\t\t\t\t<MenuItem Header=\"_Copy\" Command=\"ApplicationCommands.Copy\" />\n\t\t\t\t\t\t\t<MenuItem Header=\"Copy _name\" Command=\"ApplicationCommands.Copy\" CommandParameter=\"Key\" InputGestureText=\" \" />\n\t\t\t\t\t\t\t<MenuItem Header=\"Copy _value\" Command=\"ApplicationCommands.Copy\" CommandParameter=\"Value\" InputGestureText=\" \" />\n\t\t\t\t\t\t</ContextMenu>\n\t\t\t\t\t</Setter.Value>\n\t\t\t\t</Setter>\n\t\t\t</Style>\n\t\t</Grid.Resources>\n\t\t<Grid.RowDefinitions>\n\t\t\t<RowDefinition />\n\t\t\t<RowDefinition />\n\t\t\t<RowDefinition />\n\t\t</Grid.RowDefinitions>\n\t\t<Label Content=\"{x:Static properties:Resources.StringTable}\"\n\t\t\t   FontFamily=\"Segoe UI\"\n\t\t\t   FontWeight=\"Bold\"\n\t\t\t   FontSize=\"12pt\" />\n\t\t<local:SearchBox x:Name=\"resourceFilterBox\" \n\t\t\t   FontFamily=\"Segoe UI\"\n\t\t\t   FontSize=\"9pt\"\n\t\t\t   Grid.Row=\"1\"\n\t\t\t   TextChanged=\"OnFilterTextChanged\" />\n\t\t<ListView Name=\"resourceListView\"\n\t\t\t  FontFamily=\"Segoe UI\"\n\t\t\t  FontSize=\"9pt\"\n\t\t\t  Grid.Row=\"2\"\n\t\t\t  AlternationCount=\"2\"\n\t\t\t  ItemContainerStyle=\"{StaticResource alternatingWithBinding}\"\n\t\t\t  local:SortableGridViewColumn.SortMode=\"Automatic\">\n\t\t\t<ListView.View>\n\t\t\t\t<GridView AllowsColumnReorder=\"False\">\n\t\t\t\t\t<GridView.Columns>\n\t\t\t\t\t\t<local:SortableGridViewColumn DisplayMemberBinding=\"{Binding Key}\" SortBy=\"Key\">\n\t\t\t\t\t\t\t<GridViewColumnHeader Content=\"{x:Static properties:Resources.Name}\"\n\t\t\t\t\t\t\t\t\t\t\t  HorizontalContentAlignment=\"Left\"\n\t\t\t\t\t\t\t\t\t\t\t  FontWeight=\"Bold\" />\n\t\t\t\t\t\t</local:SortableGridViewColumn>\n\t\t\t\t\t\t<local:SortableGridViewColumn DisplayMemberBinding=\"{Binding Value}\" SortBy=\"Value\">\n\t\t\t\t\t\t\t<GridViewColumnHeader Content=\"{x:Static properties:Resources.Value}\"\n\t\t\t\t\t\t\t\t\t\t\t  HorizontalContentAlignment=\"Left\"\n\t\t\t\t\t\t\t\t\t\t\t  FontWeight=\"Bold\" />\n\t\t\t\t\t\t</local:SortableGridViewColumn>\n\t\t\t\t\t</GridView.Columns>\n\t\t\t\t</GridView>\n\t\t\t</ListView.View>\n\t\t</ListView>\n\t</Grid>\n</UserControl>"
  },
  {
    "path": "ILSpy/Controls/ResourceStringTable.xaml.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Text;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Input;\n\nnamespace ICSharpCode.ILSpy.Controls\n{\n\t/// <summary>\n\t/// Interaction logic for ResourceStringTable.xaml\n\t/// </summary>\n\tpublic partial class ResourceStringTable : UserControl\n\t{\n\t\tICollectionView filteredView;\n\t\tstring filter;\n\n\t\tpublic ResourceStringTable(IEnumerable strings, FrameworkElement container)\n\t\t{\n\t\t\tInitializeComponent();\n\t\t\t// set size to fit decompiler window\n\t\t\tcontainer.SizeChanged += OnParentSizeChanged;\n\t\t\tif (!double.IsNaN(container.ActualWidth))\n\t\t\t\tWidth = Math.Max(container.ActualWidth - 45, 0);\n\t\t\tMaxHeight = container.ActualHeight;\n\n\t\t\tfilteredView = CollectionViewSource.GetDefaultView(strings);\n\t\t\tfilteredView.Filter = OnResourceFilter;\n\t\t\tresourceListView.ItemsSource = filteredView;\n\t\t}\n\n\t\tprivate bool OnResourceFilter(object obj)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(filter))\n\t\t\t\treturn true;\n\n\t\t\tif (obj is KeyValuePair<string, string> item)\n\t\t\t\treturn item.Key?.Contains(filter, StringComparison.OrdinalIgnoreCase) == true ||\n\t\t\t\t\t   item.Value?.Contains(filter, StringComparison.OrdinalIgnoreCase) == true;\n\n\t\t\treturn false; // make it obvious search is not working\n\t\t}\n\n\t\tprivate void OnParentSizeChanged(object sender, SizeChangedEventArgs e)\n\t\t{\n\t\t\tif (e.WidthChanged && !double.IsNaN(e.NewSize.Width))\n\t\t\t\tWidth = Math.Max(e.NewSize.Width - 45, 0);\n\t\t\tif (e.HeightChanged)\n\t\t\t\tMaxHeight = e.NewSize.Height;\n\t\t}\n\n\t\tprivate void OnFilterTextChanged(object sender, TextChangedEventArgs e)\n\t\t{\n\t\t\tfilter = resourceFilterBox.Text;\n\t\t\tfilteredView?.Refresh();\n\t\t}\n\n\t\tvoid ExecuteCopy(object sender, ExecutedRoutedEventArgs args)\n\t\t{\n\t\t\tStringBuilder sb = new StringBuilder();\n\t\t\tforeach (var item in resourceListView.SelectedItems)\n\t\t\t{\n\t\t\t\tif (item is KeyValuePair<string, string> pair)\n\t\t\t\t{\n\t\t\t\t\tswitch (args.Parameter)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase \"Key\":\n\t\t\t\t\t\t\tsb.AppendLine(pair.Key);\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\tcase \"Value\":\n\t\t\t\t\t\t\tsb.AppendLine(pair.Value);\n\t\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tsb.AppendLine($\"{pair.Key}\\t{pair.Value}\");\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsb.AppendLine(item.ToString());\n\t\t\t}\n\t\t\tClipboard.SetText(sb.ToString());\n\t\t}\n\n\t\tvoid CanExecuteCopy(object sender, CanExecuteRoutedEventArgs args)\n\t\t{\n\t\t\targs.CanExecute = true;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Controls/SearchBox.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Input;\nusing System.Windows.Media;\nusing System.Windows.Threading;\n\nnamespace ICSharpCode.ILSpy.Controls\n{\n\tpublic class SearchBox : TextBox\n\t{\n\t\tstatic SearchBox()\n\t\t{\n\t\t\tDefaultStyleKeyProperty.OverrideMetadata(\n\t\t\t\ttypeof(SearchBox),\n\t\t\t\tnew FrameworkPropertyMetadata(typeof(SearchBox)));\n\t\t}\n\n\t\t#region Dependency properties\n\n\t\tpublic static DependencyProperty WatermarkTextProperty = DependencyProperty.Register(\"WatermarkText\", typeof(string), typeof(SearchBox));\n\n\t\tpublic static DependencyProperty WatermarkColorProperty = DependencyProperty.Register(\"WatermarkColor\", typeof(Brush), typeof(SearchBox));\n\n\t\tpublic static DependencyProperty HasTextProperty = DependencyProperty.Register(\"HasText\", typeof(bool), typeof(SearchBox));\n\n\t\tpublic static readonly DependencyProperty UpdateDelayProperty =\n\t\t\tDependencyProperty.Register(\"UpdateDelay\", typeof(TimeSpan), typeof(SearchBox),\n\t\t\t\t\t\t\t\t\t\tnew FrameworkPropertyMetadata(TimeSpan.FromMilliseconds(200)));\n\n\t\t#endregion\n\n\t\t#region Public Properties\n\n\t\tpublic string WatermarkText {\n\t\t\tget { return (string)GetValue(WatermarkTextProperty); }\n\t\t\tset { SetValue(WatermarkTextProperty, value); }\n\t\t}\n\n\t\tpublic Brush WatermarkColor {\n\t\t\tget { return (Brush)GetValue(WatermarkColorProperty); }\n\t\t\tset { SetValue(WatermarkColorProperty, value); }\n\t\t}\n\n\t\tpublic bool HasText {\n\t\t\tget { return (bool)GetValue(HasTextProperty); }\n\t\t\tprivate set { SetValue(HasTextProperty, value); }\n\t\t}\n\n\t\tpublic TimeSpan UpdateDelay {\n\t\t\tget { return (TimeSpan)GetValue(UpdateDelayProperty); }\n\t\t\tset { SetValue(UpdateDelayProperty, value); }\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Handlers\n\n\t\tprivate void IconBorder_MouseLeftButtonUp(object obj, MouseButtonEventArgs e)\n\t\t{\n\t\t\tif (this.HasText)\n\t\t\t\tthis.Text = string.Empty;\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Overrides\n\n\t\tDispatcherTimer timer;\n\n\t\tprotected override void OnTextChanged(TextChangedEventArgs e)\n\t\t{\n\t\t\tbase.OnTextChanged(e);\n\n\t\t\tHasText = this.Text.Length > 0;\n\t\t\tif (timer == null)\n\t\t\t{\n\t\t\t\ttimer = new DispatcherTimer();\n\t\t\t\ttimer.Tick += timer_Tick;\n\t\t\t}\n\t\t\ttimer.Stop();\n\t\t\ttimer.Interval = this.UpdateDelay;\n\t\t\ttimer.Start();\n\n\t\t\tUpdateWatermarkLabel();\n\t\t}\n\n\t\tprivate void UpdateWatermarkLabel()\n\t\t{\n\t\t\tLabel wl = (Label)GetTemplateChild(\"WatermarkLabel\");\n\t\t\tif (wl != null)\n\t\t\t\twl.Visibility = HasText ? Visibility.Hidden : Visibility.Visible;\n\t\t}\n\n\t\tvoid timer_Tick(object sender, EventArgs e)\n\t\t{\n\t\t\ttimer.Stop();\n\t\t\ttimer = null;\n\t\t\tvar textBinding = GetBindingExpression(TextProperty);\n\t\t\tif (textBinding != null)\n\t\t\t{\n\t\t\t\ttextBinding.UpdateSource();\n\t\t\t}\n\t\t}\n\n\t\tprotected override void OnLostFocus(RoutedEventArgs e)\n\t\t{\n\t\t\tUpdateWatermarkLabel();\n\t\t\tbase.OnLostFocus(e);\n\t\t}\n\n\t\tprotected override void OnGotFocus(RoutedEventArgs e)\n\t\t{\n\t\t\tUpdateWatermarkLabel();\n\t\t\tbase.OnGotFocus(e);\n\t\t}\n\n\t\tpublic override void OnApplyTemplate()\n\t\t{\n\t\t\tbase.OnApplyTemplate();\n\n\t\t\tBorder iconBorder = GetTemplateChild(\"PART_IconBorder\") as Border;\n\t\t\tif (iconBorder != null)\n\t\t\t{\n\t\t\t\ticonBorder.MouseLeftButtonUp += IconBorder_MouseLeftButtonUp;\n\t\t\t}\n\t\t}\n\n\t\tprotected override void OnKeyDown(KeyEventArgs e)\n\t\t{\n\t\t\tif (e.Key == Key.Escape && this.Text.Length > 0)\n\t\t\t{\n\t\t\t\tthis.Text = string.Empty;\n\t\t\t\te.Handled = true;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbase.OnKeyDown(e);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/SearchBoxStyle.xaml",
    "content": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n\txmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n\txmlns:local=\"clr-namespace:ICSharpCode.ILSpy.Controls\">\n\t\n\t<Style x:Key=\"{x:Type local:SearchBox}\" TargetType=\"{x:Type local:SearchBox}\" BasedOn=\"{StaticResource {x:Type TextBox}}\">\n\t\t<Setter Property=\"BorderThickness\" Value=\"1\" />\n\t\t<Setter Property=\"SnapsToDevicePixels\" Value=\"True\" />\n\t\t<Setter Property=\"FocusVisualStyle\" Value=\"{x:Null}\"/>\n\t\t<Setter Property=\"Template\">\n\t\t\t<Setter.Value>\n\t\t\t\t<ControlTemplate TargetType=\"{x:Type local:SearchBox}\">\n\t\t\t\t\t<Border x:Name=\"Border\"\n\t\t\t\t\t        Cursor=\"IBeam\"\n\t\t\t\t\t        Background=\"{TemplateBinding Background}\"\n\t\t\t\t\t        BorderBrush=\"{TemplateBinding BorderBrush}\"\n\t\t\t\t\t        BorderThickness=\"{TemplateBinding BorderThickness}\">\n\t\t\t\t\t\t<Grid x:Name=\"LayoutGrid\">\n\t\t\t\t\t\t\t<Grid.ColumnDefinitions>\n\t\t\t\t\t\t\t\t<ColumnDefinition Width=\"*\" />\n\t\t\t\t\t\t\t\t<ColumnDefinition Width=\"{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualHeight}\" />\n\t\t\t\t\t\t\t</Grid.ColumnDefinitions>\n\t\t\t\t\t\t\t<ScrollViewer Margin=\"2\" x:Name=\"PART_ContentHost\" Grid.Column=\"0\" />\n\t\t\t\t\t\t\t<Label x:Name=\"WatermarkLabel\"\n\t\t\t\t\t\t\t       Margin=\"2\"\n\t\t\t\t\t\t\t       Grid.Column=\"0\"\n\t\t\t\t\t\t\t       Foreground=\"{Binding RelativeSource={RelativeSource TemplatedParent}, Path=WatermarkColor}\"\n\t\t\t\t\t\t\t       Content=\"{Binding RelativeSource={RelativeSource TemplatedParent}, Path=WatermarkText}\"\n\t\t\t\t\t\t\t       Padding=\"2,0,0,0\"\n\t\t\t\t\t\t\t       FontStyle=\"Italic\" />\n\t\t\t\t\t\t\t<Border x:Name=\"PART_IconBorder\"\n\t\t\t\t\t\t\t        Grid.Column=\"1\"\n\t\t\t\t\t\t\t        BorderThickness=\"1\"\n\t\t\t\t\t\t\t        VerticalAlignment=\"Stretch\"\n\t\t\t\t\t\t\t        HorizontalAlignment=\"Stretch\"\n\t\t\t\t\t\t\t        BorderBrush=\"Transparent\"\n\t\t\t\t\t\t\t        Background=\"Transparent\">\n\t\t\t\t\t\t\t\t<Image x:Name=\"SearchIcon\"\n\t\t\t\t\t\t\t\t       Cursor=\"Arrow\"\n\t\t\t\t\t\t\t\t       Stretch=\"None\"\n\t\t\t\t\t\t\t\t       HorizontalAlignment=\"Center\"\n\t\t\t\t\t\t\t\t       VerticalAlignment=\"Center\"\n\t\t\t\t\t\t\t\t       ToolTip=\"Search\"\n\t\t\t\t\t\t\t\t       Source=\"{local:XamlResource Images/Search}\" />\n\t\t\t\t\t\t\t</Border>\n\t\t\t\t\t\t</Grid>\n\t\t\t\t\t</Border>\n\t\t\t\t\t<ControlTemplate.Triggers>\n\t\t\t\t\t\t<Trigger Property=\"HasText\" Value=\"True\">\n\t\t\t\t\t\t\t<Setter Property=\"Visibility\" TargetName=\"WatermarkLabel\" Value=\"Hidden\" />\n\t\t\t\t\t\t</Trigger>\n\t\t\t\t\t\t<MultiTrigger>\n\t\t\t\t\t\t\t<MultiTrigger.Conditions>\n\t\t\t\t\t\t\t\t<Condition Property=\"HasText\" Value=\"True\" />\n\t\t\t\t\t\t\t</MultiTrigger.Conditions>\n\t\t\t\t\t\t\t<Setter Property=\"Source\"\n\t\t\t\t\t\t\t        TargetName=\"SearchIcon\"\n\t\t\t\t\t\t\t        Value=\"{local:XamlResource Images/Close}\" />\n\t\t\t\t\t\t\t<Setter Property=\"ToolTip\" TargetName=\"SearchIcon\" Value=\"Clear\"/>\n\t\t\t\t\t\t</MultiTrigger>\n\t\t\t\t\t</ControlTemplate.Triggers>\n\t\t\t\t</ControlTemplate>\n\t\t\t</Setter.Value>\n\t\t</Setter>\n\t</Style>\n</ResourceDictionary>"
  },
  {
    "path": "ILSpy/Controls/SortableGridViewColumn.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.ComponentModel;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\n\nnamespace ICSharpCode.ILSpy.Controls\n{\n\t/// <summary>\n\t/// Allows to automatically sort a grid view.\n\t/// </summary>\n\tpublic class SortableGridViewColumn : GridViewColumn\n\t{\n\t\t// This class was copied from ICSharpCode.Core.Presentation.\n\n\t\tstatic readonly ComponentResourceKey headerTemplateKey = new ComponentResourceKey(typeof(SortableGridViewColumn), \"ColumnHeaderTemplate\");\n\n\t\tpublic SortableGridViewColumn()\n\t\t{\n\t\t\tthis.SetValueToExtension(HeaderTemplateProperty, new DynamicResourceExtension(headerTemplateKey));\n\t\t}\n\n\t\tstring sortBy;\n\n\t\tpublic string SortBy {\n\t\t\tget { return sortBy; }\n\t\t\tset {\n\t\t\t\tif (sortBy != value)\n\t\t\t\t{\n\t\t\t\t\tsortBy = value;\n\t\t\t\t\tOnPropertyChanged(new PropertyChangedEventArgs(\"SortBy\"));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t#region SortDirection property\n\t\tpublic static readonly DependencyProperty SortDirectionProperty =\n\t\t\tDependencyProperty.RegisterAttached(\"SortDirection\", typeof(ColumnSortDirection), typeof(SortableGridViewColumn),\n\t\t\t\t\t\t\t\t\t\t\t\tnew FrameworkPropertyMetadata(ColumnSortDirection.None, OnSortDirectionChanged));\n\n\t\tpublic ColumnSortDirection SortDirection {\n\t\t\tget { return (ColumnSortDirection)GetValue(SortDirectionProperty); }\n\t\t\tset { SetValue(SortDirectionProperty, value); }\n\t\t}\n\n\t\tpublic static ColumnSortDirection GetSortDirection(ListView listView)\n\t\t{\n\t\t\treturn (ColumnSortDirection)listView.GetValue(SortDirectionProperty);\n\t\t}\n\n\t\tpublic static void SetSortDirection(ListView listView, ColumnSortDirection value)\n\t\t{\n\t\t\tlistView.SetValue(SortDirectionProperty, value);\n\t\t}\n\n\t\tstatic void OnSortDirectionChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)\n\t\t{\n\t\t\tListView grid = sender as ListView;\n\t\t\tif (grid != null)\n\t\t\t{\n\t\t\t\tSortableGridViewColumn col = GetCurrentSortColumn(grid);\n\t\t\t\tif (col != null)\n\t\t\t\t\tcol.SortDirection = (ColumnSortDirection)args.NewValue;\n\t\t\t\tSort(grid);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region CurrentSortColumn property\n\t\tpublic static readonly DependencyProperty CurrentSortColumnProperty =\n\t\t\tDependencyProperty.RegisterAttached(\"CurrentSortColumn\", typeof(SortableGridViewColumn), typeof(SortableGridViewColumn),\n\t\t\t\t\t\t\t\t\t\t\t\tnew FrameworkPropertyMetadata(OnCurrentSortColumnChanged));\n\n\t\tpublic static SortableGridViewColumn GetCurrentSortColumn(ListView listView)\n\t\t{\n\t\t\treturn (SortableGridViewColumn)listView.GetValue(CurrentSortColumnProperty);\n\t\t}\n\n\t\tpublic static void SetCurrentSortColumn(ListView listView, SortableGridViewColumn value)\n\t\t{\n\t\t\tlistView.SetValue(CurrentSortColumnProperty, value);\n\t\t}\n\n\t\tstatic void OnCurrentSortColumnChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)\n\t\t{\n\t\t\tListView grid = sender as ListView;\n\t\t\tif (grid != null)\n\t\t\t{\n\t\t\t\tSortableGridViewColumn oldColumn = (SortableGridViewColumn)args.OldValue;\n\t\t\t\tif (oldColumn != null)\n\t\t\t\t\toldColumn.SortDirection = ColumnSortDirection.None;\n\t\t\t\tSortableGridViewColumn newColumn = (SortableGridViewColumn)args.NewValue;\n\t\t\t\tif (newColumn != null)\n\t\t\t\t{\n\t\t\t\t\tnewColumn.SortDirection = GetSortDirection(grid);\n\t\t\t\t}\n\t\t\t\tSort(grid);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region SortMode property\n\t\tpublic static readonly DependencyProperty SortModeProperty =\n\t\t\tDependencyProperty.RegisterAttached(\"SortMode\", typeof(ListViewSortMode), typeof(SortableGridViewColumn),\n\t\t\t\t\t\t\t\t\t\t\t\tnew FrameworkPropertyMetadata(ListViewSortMode.None, OnSortModeChanged));\n\n\t\tpublic static ListViewSortMode GetSortMode(ListView listView)\n\t\t{\n\t\t\treturn (ListViewSortMode)listView.GetValue(SortModeProperty);\n\t\t}\n\n\t\tpublic static void SetSortMode(ListView listView, ListViewSortMode value)\n\t\t{\n\t\t\tlistView.SetValue(SortModeProperty, value);\n\t\t}\n\n\t\tstatic void OnSortModeChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)\n\t\t{\n\t\t\tListView grid = sender as ListView;\n\t\t\tif (grid != null)\n\t\t\t{\n\t\t\t\tif ((ListViewSortMode)args.NewValue != ListViewSortMode.None)\n\t\t\t\t\tgrid.AddHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(GridViewColumnHeaderClickHandler));\n\t\t\t\telse\n\t\t\t\t\tgrid.RemoveHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(GridViewColumnHeaderClickHandler));\n\t\t\t}\n\t\t}\n\n\t\tstatic void GridViewColumnHeaderClickHandler(object sender, RoutedEventArgs e)\n\t\t{\n\t\t\tListView grid = sender as ListView;\n\t\t\tGridViewColumnHeader headerClicked = e.OriginalSource as GridViewColumnHeader;\n\t\t\tif (grid != null && headerClicked != null && headerClicked.Role != GridViewColumnHeaderRole.Padding)\n\t\t\t{\n\t\t\t\tif (headerClicked.Column == GetCurrentSortColumn(grid))\n\t\t\t\t{\n\t\t\t\t\tswitch (GetSortDirection(grid))\n\t\t\t\t\t{\n\t\t\t\t\t\tcase ColumnSortDirection.None:\n\t\t\t\t\t\t\tSetSortDirection(grid, ColumnSortDirection.Ascending);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ColumnSortDirection.Ascending:\n\t\t\t\t\t\t\tSetSortDirection(grid, ColumnSortDirection.Descending);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase ColumnSortDirection.Descending:\n\t\t\t\t\t\t\tSetSortDirection(grid, ColumnSortDirection.None);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tSetSortDirection(grid, ColumnSortDirection.Ascending);\n\t\t\t\t\tSetCurrentSortColumn(grid, headerClicked.Column as SortableGridViewColumn);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tstatic void Sort(ListView grid)\n\t\t{\n\t\t\tColumnSortDirection currentDirection = GetSortDirection(grid);\n\t\t\tSortableGridViewColumn column = GetCurrentSortColumn(grid);\n\t\t\tICollectionView dataView = CollectionViewSource.GetDefaultView(grid.ItemsSource);\n\n\t\t\tif (dataView == null)\n\t\t\t\treturn;\n\n\t\t\tif (column != null && GetSortMode(grid) == ListViewSortMode.Automatic && currentDirection != ColumnSortDirection.None)\n\t\t\t{\n\t\t\t\tstring sortBy = column.SortBy;\n\t\t\t\tif (sortBy == null)\n\t\t\t\t{\n\t\t\t\t\tBinding binding = column.DisplayMemberBinding as Binding;\n\t\t\t\t\tif (binding != null && binding.Path != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tsortBy = binding.Path.Path;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tdataView.SortDescriptions.Clear();\n\t\t\t\tif (sortBy != null)\n\t\t\t\t{\n\t\t\t\t\tListSortDirection direction;\n\t\t\t\t\tif (currentDirection == ColumnSortDirection.Descending)\n\t\t\t\t\t\tdirection = ListSortDirection.Descending;\n\t\t\t\t\telse\n\t\t\t\t\t\tdirection = ListSortDirection.Ascending;\n\t\t\t\t\tdataView.SortDescriptions.Add(new SortDescription(sortBy, direction));\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tdataView.SortDescriptions.Clear();\n\t\t\t}\n\n\t\t\tdataView.Refresh();\n\t\t}\n\t}\n\n\tpublic enum ColumnSortDirection\n\t{\n\t\tNone,\n\t\tAscending,\n\t\tDescending\n\t}\n\n\tpublic enum ListViewSortMode\n\t{\n\t\t/// <summary>\n\t\t/// Disable automatic sorting when sortable columns are clicked.\n\t\t/// </summary>\n\t\tNone,\n\t\t/// <summary>\n\t\t/// Fully automatic sorting.\n\t\t/// </summary>\n\t\tAutomatic,\n\t\t/// <summary>\n\t\t/// Automatically update SortDirection and CurrentSortColumn properties,\n\t\t/// but do not actually sort the data.\n\t\t/// </summary>\n\t\tHalfAutomatic\n\t}\n\n\tsealed class ColumnSortDirectionToVisibilityConverter : IValueConverter\n\t{\n\t\tpublic object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)\n\t\t{\n\t\t\treturn Equals(value, parameter) ? Visibility.Visible : Visibility.Collapsed;\n\t\t}\n\n\t\tpublic object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)\n\t\t{\n\t\t\tthrow new NotSupportedException();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/TreeView/EditTextBox.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Input;\n\nusing ICSharpCode.ILSpyX.TreeView;\n\nnamespace ICSharpCode.ILSpy.Controls.TreeView\n{\n\tclass EditTextBox : TextBox\n\t{\n\t\tstatic EditTextBox()\n\t\t{\n\t\t\tDefaultStyleKeyProperty.OverrideMetadata(typeof(EditTextBox),\n\t\t\t\tnew FrameworkPropertyMetadata(typeof(EditTextBox)));\n\t\t}\n\n\t\tpublic EditTextBox()\n\t\t{\n\t\t\tLoaded += delegate { Init(); };\n\t\t}\n\n\t\tpublic SharpTreeViewItem Item { get; set; }\n\n\t\tpublic SharpTreeNode Node {\n\t\t\tget { return Item.Node; }\n\t\t}\n\n\t\tvoid Init()\n\t\t{\n\t\t\tText = Node.LoadEditText();\n\t\t\tFocus();\n\t\t\tSelectAll();\n\t\t}\n\n\t\tprotected override void OnKeyDown(KeyEventArgs e)\n\t\t{\n\t\t\tif (e.Key == Key.Enter)\n\t\t\t{\n\t\t\t\tCommit();\n\t\t\t}\n\t\t\telse if (e.Key == Key.Escape)\n\t\t\t{\n\t\t\t\tNode.IsEditing = false;\n\t\t\t}\n\t\t}\n\n\t\tprotected override void OnLostKeyboardFocus(KeyboardFocusChangedEventArgs e)\n\t\t{\n\t\t\tif (Node.IsEditing)\n\t\t\t{\n\t\t\t\tCommit();\n\t\t\t}\n\t\t}\n\n\t\tbool committing;\n\n\t\tvoid Commit()\n\t\t{\n\t\t\tif (!committing)\n\t\t\t{\n\t\t\t\tcommitting = true;\n\n\t\t\t\tNode.IsEditing = false;\n\t\t\t\tif (!Node.SaveEditText(Text))\n\t\t\t\t{\n\t\t\t\t\tItem.Focus();\n\t\t\t\t}\n\t\t\t\tNode.RaisePropertyChanged(nameof(Text));\n\n\t\t\t\t//if (Node.SaveEditText(Text)) {\n\t\t\t\t//    Node.IsEditing = false;\n\t\t\t\t//    Node.RaisePropertyChanged(\"Text\");\n\t\t\t\t//}\n\t\t\t\t//else {\n\t\t\t\t//    Init();\n\t\t\t\t//}\n\n\t\t\t\tcommitting = false;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/TreeView/ExtensionMethods.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Media;\n\nnamespace ICSharpCode.ILSpy.Controls.TreeView\n{\n\tstatic class ExtensionMethods\n\t{\n\t\tpublic static T FindAncestor<T>(this DependencyObject d) where T : class\n\t\t{\n\t\t\treturn AncestorsAndSelf(d).OfType<T>().FirstOrDefault();\n\t\t}\n\n\t\tpublic static IEnumerable<DependencyObject> AncestorsAndSelf(this DependencyObject d)\n\t\t{\n\t\t\twhile (d != null)\n\t\t\t{\n\t\t\t\tyield return d;\n\t\t\t\td = VisualTreeHelper.GetParent(d);\n\t\t\t}\n\t\t}\n\n\t\tpublic static void AddOnce(this IList list, object item)\n\t\t{\n\t\t\tif (!list.Contains(item))\n\t\t\t{\n\t\t\t\tlist.Add(item);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/TreeView/GeneralAdorner.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Windows;\nusing System.Windows.Documents;\nusing System.Windows.Media;\n\nnamespace ICSharpCode.ILSpy.Controls.TreeView\n{\n\tpublic class GeneralAdorner : Adorner\n\t{\n\t\tpublic GeneralAdorner(UIElement target)\n\t\t\t: base(target)\n\t\t{\n\t\t}\n\n\t\tFrameworkElement child;\n\n\t\tpublic FrameworkElement Child {\n\t\t\tget {\n\t\t\t\treturn child;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tif (child != value)\n\t\t\t\t{\n\t\t\t\t\tRemoveVisualChild(child);\n\t\t\t\t\tRemoveLogicalChild(child);\n\t\t\t\t\tchild = value;\n\t\t\t\t\tAddLogicalChild(value);\n\t\t\t\t\tAddVisualChild(value);\n\t\t\t\t\tInvalidateMeasure();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected override int VisualChildrenCount {\n\t\t\tget { return child == null ? 0 : 1; }\n\t\t}\n\n\t\tprotected override Visual GetVisualChild(int index)\n\t\t{\n\t\t\treturn child;\n\t\t}\n\n\t\tprotected override Size MeasureOverride(Size constraint)\n\t\t{\n\t\t\tif (child != null)\n\t\t\t{\n\t\t\t\tchild.Measure(constraint);\n\t\t\t\treturn child.DesiredSize;\n\t\t\t}\n\t\t\treturn new Size();\n\t\t}\n\n\t\tprotected override Size ArrangeOverride(Size finalSize)\n\t\t{\n\t\t\tif (child != null)\n\t\t\t{\n\t\t\t\tchild.Arrange(new Rect(finalSize));\n\t\t\t\treturn finalSize;\n\t\t\t}\n\t\t\treturn new Size();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/TreeView/InsertMarker.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Windows;\nusing System.Windows.Controls;\n\nnamespace ICSharpCode.ILSpy.Controls.TreeView\n{\n\tpublic class InsertMarker : Control\n\t{\n\t\tstatic InsertMarker()\n\t\t{\n\t\t\tDefaultStyleKeyProperty.OverrideMetadata(typeof(InsertMarker),\n\t\t\t\tnew FrameworkPropertyMetadata(typeof(InsertMarker)));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/TreeView/LinesRenderer.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Diagnostics;\nusing System.Windows;\nusing System.Windows.Media;\n\nnamespace ICSharpCode.ILSpy.Controls.TreeView\n{\n\tclass LinesRenderer : FrameworkElement\n\t{\n\t\tstatic LinesRenderer()\n\t\t{\n\t\t\tpen = new Pen(Brushes.LightGray, 1);\n\t\t\tpen.Freeze();\n\t\t}\n\n\t\tstatic Pen pen;\n\n\t\tSharpTreeNodeView NodeView {\n\t\t\tget { return TemplatedParent as SharpTreeNodeView; }\n\t\t}\n\n\t\tprotected override void OnRender(DrawingContext dc)\n\t\t{\n\t\t\tif (NodeView.Node == null)\n\t\t\t{\n\t\t\t\t// This seems to happen sometimes with DataContext==DisconnectedItem,\n\t\t\t\t// though I'm not sure why WPF would call OnRender() on a disconnected node\n\t\t\t\tDebug.WriteLine($\"LinesRenderer.OnRender() called with DataContext={NodeView.DataContext}\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar indent = NodeView.CalculateIndent();\n\t\t\tvar p = new Point(indent + 4.5, 0);\n\n\t\t\tif (!NodeView.Node.IsRoot || NodeView.ParentTreeView.ShowRootExpander)\n\t\t\t{\n\t\t\t\tdc.DrawLine(pen, new Point(p.X, ActualHeight / 2), new Point(p.X + 10, ActualHeight / 2));\n\t\t\t}\n\n\t\t\tif (NodeView.Node.IsRoot)\n\t\t\t\treturn;\n\n\t\t\tif (NodeView.Node.IsLast)\n\t\t\t{\n\t\t\t\tdc.DrawLine(pen, p, new Point(p.X, ActualHeight / 2));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tdc.DrawLine(pen, p, new Point(p.X, ActualHeight));\n\t\t\t}\n\n\t\t\tvar current = NodeView.Node;\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tp.X -= 19;\n\t\t\t\tcurrent = current.Parent;\n\t\t\t\tif (p.X < 0)\n\t\t\t\t\tbreak;\n\t\t\t\tif (!current.IsLast)\n\t\t\t\t{\n\t\t\t\t\tdc.DrawLine(pen, p, new Point(p.X, ActualHeight));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/TreeView/SharpGridView.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Windows;\nusing System.Windows.Controls;\n\nnamespace ICSharpCode.ILSpy.Controls.TreeView\n{\n\tpublic class SharpGridView : GridView\n\t{\n\t\tstatic SharpGridView()\n\t\t{\n\t\t\tItemContainerStyleKey =\n\t\t\t\tnew ComponentResourceKey(typeof(SharpTreeView), \"GridViewItemContainerStyleKey\");\n\t\t}\n\n\t\tpublic static ResourceKey ItemContainerStyleKey { get; private set; }\n\n\t\tprotected override object ItemContainerDefaultStyleKey {\n\t\t\tget {\n\t\t\t\treturn ItemContainerStyleKey;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/TreeView/SharpTreeNodeView.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Controls.Primitives;\nusing System.Windows.Media;\n\nusing ICSharpCode.ILSpyX.TreeView;\n\nnamespace ICSharpCode.ILSpy.Controls.TreeView\n{\n\tpublic class SharpTreeNodeView : Control\n\t{\n\t\tstatic SharpTreeNodeView()\n\t\t{\n\t\t\tDefaultStyleKeyProperty.OverrideMetadata(typeof(SharpTreeNodeView),\n\t\t\t\t\t\t\t\t\t\t\t\t\t new FrameworkPropertyMetadata(typeof(SharpTreeNodeView)));\n\t\t}\n\n\t\tpublic static readonly DependencyProperty TextBackgroundProperty =\n\t\t\tDependencyProperty.Register(\"TextBackground\", typeof(Brush), typeof(SharpTreeNodeView));\n\n\t\tpublic Brush TextBackground {\n\t\t\tget { return (Brush)GetValue(TextBackgroundProperty); }\n\t\t\tset { SetValue(TextBackgroundProperty, value); }\n\t\t}\n\n\t\tpublic SharpTreeNode Node {\n\t\t\tget { return DataContext as SharpTreeNode; }\n\t\t}\n\n\t\tpublic SharpTreeViewItem ParentItem { get; private set; }\n\n\t\tpublic static readonly DependencyProperty CellEditorProperty =\n\t\t\tDependencyProperty.Register(\"CellEditor\", typeof(Control), typeof(SharpTreeNodeView),\n\t\t\t\t\t\t\t\t\t\tnew FrameworkPropertyMetadata());\n\n\t\tpublic Control CellEditor {\n\t\t\tget { return (Control)GetValue(CellEditorProperty); }\n\t\t\tset { SetValue(CellEditorProperty, value); }\n\t\t}\n\n\t\tpublic SharpTreeView ParentTreeView {\n\t\t\tget { return ParentItem.ParentTreeView; }\n\t\t}\n\n\t\tinternal LinesRenderer LinesRenderer { get; private set; }\n\n\t\tpublic override void OnApplyTemplate()\n\t\t{\n\t\t\tbase.OnApplyTemplate();\n\t\t\tLinesRenderer = Template.FindName(\"linesRenderer\", this) as LinesRenderer;\n\t\t\tUpdateTemplate();\n\t\t}\n\n\t\tprotected override void OnVisualParentChanged(DependencyObject oldParent)\n\t\t{\n\t\t\tbase.OnVisualParentChanged(oldParent);\n\t\t\tParentItem = this.FindAncestor<SharpTreeViewItem>();\n\t\t\tParentItem.NodeView = this;\n\t\t}\n\n\t\tprotected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)\n\t\t{\n\t\t\tbase.OnPropertyChanged(e);\n\t\t\tif (e.Property == DataContextProperty)\n\t\t\t{\n\t\t\t\tUpdateDataContext(e.OldValue as SharpTreeNode, e.NewValue as SharpTreeNode);\n\t\t\t}\n\t\t}\n\n\t\tvoid UpdateDataContext(SharpTreeNode oldNode, SharpTreeNode newNode)\n\t\t{\n\t\t\tif (newNode != null)\n\t\t\t{\n\t\t\t\tnewNode.PropertyChanged += Node_PropertyChanged;\n\t\t\t\tif (Template != null)\n\t\t\t\t{\n\t\t\t\t\tUpdateTemplate();\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (oldNode != null)\n\t\t\t{\n\t\t\t\toldNode.PropertyChanged -= Node_PropertyChanged;\n\t\t\t}\n\t\t}\n\n\t\tvoid Node_PropertyChanged(object sender, PropertyChangedEventArgs e)\n\t\t{\n\t\t\tif (e.PropertyName == \"IsEditing\")\n\t\t\t{\n\t\t\t\tOnIsEditingChanged();\n\t\t\t}\n\t\t\telse if (e.PropertyName == \"IsLast\")\n\t\t\t{\n\t\t\t\tif (ParentTreeView.ShowLines)\n\t\t\t\t{\n\t\t\t\t\tforeach (var child in Node.VisibleDescendantsAndSelf())\n\t\t\t\t\t{\n\t\t\t\t\t\tvar container = ParentTreeView.ItemContainerGenerator.ContainerFromItem(child) as SharpTreeViewItem;\n\t\t\t\t\t\tif (container != null && container.NodeView != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontainer.NodeView.LinesRenderer.InvalidateVisual();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (e.PropertyName == \"IsExpanded\")\n\t\t\t{\n\t\t\t\tif (Node.IsExpanded)\n\t\t\t\t\tParentTreeView.HandleExpanding(Node);\n\t\t\t}\n\t\t}\n\n\t\tvoid OnIsEditingChanged()\n\t\t{\n\t\t\tvar textEditorContainer = Template.FindName(\"textEditorContainer\", this) as Border;\n\t\t\tif (Node.IsEditing)\n\t\t\t{\n\t\t\t\tif (CellEditor == null)\n\t\t\t\t\ttextEditorContainer.Child = new EditTextBox() { Item = ParentItem };\n\t\t\t\telse\n\t\t\t\t\ttextEditorContainer.Child = CellEditor;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttextEditorContainer.Child = null;\n\t\t\t}\n\t\t}\n\n\t\tvoid UpdateTemplate()\n\t\t{\n\t\t\tvar spacer = Template.FindName(\"spacer\", this) as FrameworkElement;\n\t\t\tspacer.Width = CalculateIndent();\n\n\t\t\tvar expander = Template.FindName(\"expander\", this) as ToggleButton;\n\t\t\tif (ParentTreeView.Root == Node && !ParentTreeView.ShowRootExpander)\n\t\t\t{\n\t\t\t\texpander.Visibility = Visibility.Collapsed;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\texpander.ClearValue(VisibilityProperty);\n\t\t\t}\n\t\t}\n\n\t\tinternal double CalculateIndent()\n\t\t{\n\t\t\tvar result = 19 * Node.Level;\n\t\t\tif (ParentTreeView.ShowRoot)\n\t\t\t{\n\t\t\t\tif (!ParentTreeView.ShowRootExpander)\n\t\t\t\t{\n\t\t\t\t\tif (ParentTreeView.Root != Node)\n\t\t\t\t\t{\n\t\t\t\t\t\tresult -= 15;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tresult -= 19;\n\t\t\t}\n\t\t\tif (result < 0)\n\t\t\t{\n\t\t\t\tDebug.WriteLine(\"Negative indent level detected for node \" + Node);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/TreeView/SharpTreeView.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Controls.Primitives;\nusing System.Windows.Documents;\nusing System.Windows.Input;\nusing System.Windows.Threading;\n\nusing ICSharpCode.ILSpyX.TreeView;\n\nusing TomsToolbox.Wpf;\n\nnamespace ICSharpCode.ILSpy.Controls.TreeView\n{\n\tpublic class SharpTreeView : ListView\n\t{\n\t\tstatic SharpTreeView()\n\t\t{\n\t\t\tDefaultStyleKeyProperty.OverrideMetadata(typeof(SharpTreeView),\n\t\t\t\t\t\t\t\t\t\t\t\t\t new FrameworkPropertyMetadata(typeof(SharpTreeView)));\n\n\t\t\tSelectionModeProperty.OverrideMetadata(typeof(SharpTreeView),\n\t\t\t\t\t\t\t\t\t\t\t\t   new FrameworkPropertyMetadata(SelectionMode.Extended));\n\n\t\t\tAlternationCountProperty.OverrideMetadata(typeof(SharpTreeView),\n\t\t\t\t\t\t\t\t\t\t\t\t\t  new FrameworkPropertyMetadata(2));\n\n\t\t\tDefaultItemContainerStyleKey =\n\t\t\t\tnew ComponentResourceKey(typeof(SharpTreeView), \"DefaultItemContainerStyleKey\");\n\n\t\t\tVirtualizingStackPanel.VirtualizationModeProperty.OverrideMetadata(typeof(SharpTreeView),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   new FrameworkPropertyMetadata(VirtualizationMode.Recycling));\n\n\t\t\tRegisterCommands();\n\t\t}\n\n\t\tpublic static ResourceKey DefaultItemContainerStyleKey { get; }\n\n\t\tpublic SharpTreeView()\n\t\t{\n\t\t\tSetResourceReference(ItemContainerStyleProperty, DefaultItemContainerStyleKey);\n\t\t}\n\n\t\tpublic static readonly DependencyProperty RootProperty =\n\t\t\tDependencyProperty.Register(nameof(Root), typeof(SharpTreeNode), typeof(SharpTreeView));\n\n\t\tpublic SharpTreeNode Root {\n\t\t\tget { return (SharpTreeNode)GetValue(RootProperty); }\n\t\t\tset { SetValue(RootProperty, value); }\n\t\t}\n\n\t\tpublic static readonly DependencyProperty ShowRootProperty =\n\t\t\tDependencyProperty.Register(nameof(ShowRoot), typeof(bool), typeof(SharpTreeView),\n\t\t\t\t\t\t\t\t\t\tnew FrameworkPropertyMetadata(true));\n\n\t\tpublic bool ShowRoot {\n\t\t\tget { return (bool)GetValue(ShowRootProperty); }\n\t\t\tset { SetValue(ShowRootProperty, value); }\n\t\t}\n\n\t\tpublic static readonly DependencyProperty ShowRootExpanderProperty =\n\t\t\tDependencyProperty.Register(nameof(ShowRootExpander), typeof(bool), typeof(SharpTreeView),\n\t\t\t\t\t\t\t\t\t\tnew FrameworkPropertyMetadata(false));\n\n\t\tpublic bool ShowRootExpander {\n\t\t\tget { return (bool)GetValue(ShowRootExpanderProperty); }\n\t\t\tset { SetValue(ShowRootExpanderProperty, value); }\n\t\t}\n\n\t\tpublic static readonly DependencyProperty AllowDropOrderProperty =\n\t\t\tDependencyProperty.Register(nameof(AllowDropOrder), typeof(bool), typeof(SharpTreeView));\n\n\t\tpublic bool AllowDropOrder {\n\t\t\tget { return (bool)GetValue(AllowDropOrderProperty); }\n\t\t\tset { SetValue(AllowDropOrderProperty, value); }\n\t\t}\n\n\t\tpublic static readonly DependencyProperty ShowLinesProperty =\n\t\t\tDependencyProperty.Register(nameof(ShowLines), typeof(bool), typeof(SharpTreeView),\n\t\t\t\t\t\t\t\t\t\tnew FrameworkPropertyMetadata(true));\n\n\t\tpublic bool ShowLines {\n\t\t\tget { return (bool)GetValue(ShowLinesProperty); }\n\t\t\tset { SetValue(ShowLinesProperty, value); }\n\t\t}\n\n\t\tpublic static bool GetShowAlternation(DependencyObject obj)\n\t\t{\n\t\t\treturn (bool)obj.GetValue(ShowAlternationProperty);\n\t\t}\n\n\t\tpublic static void SetShowAlternation(DependencyObject obj, bool value)\n\t\t{\n\t\t\tobj.SetValue(ShowAlternationProperty, value);\n\t\t}\n\n\t\tpublic static readonly DependencyProperty ShowAlternationProperty =\n\t\t\tDependencyProperty.RegisterAttached(\"ShowAlternation\", typeof(bool), typeof(SharpTreeView),\n\t\t\t\t\t\t\t\t\t\t\t\tnew FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits));\n\n\t\tprotected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)\n\t\t{\n\t\t\tbase.OnPropertyChanged(e);\n\t\t\tif (e.Property == RootProperty ||\n\t\t\t\te.Property == ShowRootProperty ||\n\t\t\t\te.Property == ShowRootExpanderProperty)\n\t\t\t{\n\t\t\t\tReload();\n\t\t\t}\n\t\t}\n\n\t\tTreeFlattener flattener;\n\t\tbool updatesLocked;\n\n\t\tpublic IDisposable LockUpdates()\n\t\t{\n\t\t\treturn new UpdateLock(this);\n\t\t}\n\n\t\tclass UpdateLock : IDisposable\n\t\t{\n\t\t\tSharpTreeView instance;\n\n\t\t\tpublic UpdateLock(SharpTreeView instance)\n\t\t\t{\n\t\t\t\tthis.instance = instance;\n\t\t\t\tthis.instance.updatesLocked = true;\n\t\t\t}\n\n\t\t\tpublic void Dispose()\n\t\t\t{\n\t\t\t\tthis.instance.updatesLocked = false;\n\t\t\t}\n\t\t}\n\n\t\tvoid Reload()\n\t\t{\n\t\t\tif (flattener != null)\n\t\t\t{\n\t\t\t\tflattener.Stop();\n\t\t\t\tflattener.CollectionChanged -= flattener_CollectionChanged;\n\t\t\t}\n\t\t\tif (Root != null)\n\t\t\t{\n\t\t\t\tif (!(ShowRoot && ShowRootExpander))\n\t\t\t\t{\n\t\t\t\t\tRoot.IsExpanded = true;\n\t\t\t\t}\n\t\t\t\tflattener = new TreeFlattener(Root, ShowRoot);\n\t\t\t\tflattener.CollectionChanged += flattener_CollectionChanged;\n\t\t\t\tthis.ItemsSource = flattener;\n\t\t\t}\n\t\t}\n\n\t\tvoid flattener_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)\n\t\t{\n\t\t\t// Deselect nodes that are being hidden, if any remain in the tree\n\t\t\tif (e.Action == NotifyCollectionChangedAction.Remove && Items.Count > 0)\n\t\t\t{\n\t\t\t\tList<SharpTreeNode> selectedOldItems = null;\n\t\t\t\tforeach (SharpTreeNode node in e.OldItems)\n\t\t\t\t{\n\t\t\t\t\tif (node.IsSelected)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (selectedOldItems == null)\n\t\t\t\t\t\t\tselectedOldItems = new List<SharpTreeNode>();\n\t\t\t\t\t\tselectedOldItems.Add(node);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!updatesLocked && selectedOldItems != null)\n\t\t\t\t{\n\t\t\t\t\tvar list = SelectedItems.Cast<SharpTreeNode>().Except(selectedOldItems).ToList();\n\t\t\t\t\tUpdateFocusedNode(list, Math.Max(0, e.OldStartingIndex - 1));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid UpdateFocusedNode(List<SharpTreeNode> newSelection, int topSelectedIndex)\n\t\t{\n\t\t\tif (updatesLocked)\n\t\t\t\treturn;\n\t\t\tSetSelectedItems(newSelection ?? Enumerable.Empty<SharpTreeNode>());\n\t\t\tif (SelectedItem == null && this.IsKeyboardFocusWithin)\n\t\t\t{\n\t\t\t\t// if we removed all selected nodes, then move the focus to the node \n\t\t\t\t// preceding the first of the old selected nodes\n\t\t\t\tSelectedIndex = topSelectedIndex;\n\t\t\t\tif (SelectedItem != null)\n\t\t\t\t\tFocusNode((SharpTreeNode)SelectedItem);\n\t\t\t}\n\t\t}\n\n\t\tprotected override DependencyObject GetContainerForItemOverride()\n\t\t{\n\t\t\treturn new SharpTreeViewItem();\n\t\t}\n\n\t\tprotected override bool IsItemItsOwnContainerOverride(object item)\n\t\t{\n\t\t\treturn item is SharpTreeViewItem;\n\t\t}\n\n\t\tprotected override void PrepareContainerForItemOverride(DependencyObject element, object item)\n\t\t{\n\t\t\tbase.PrepareContainerForItemOverride(element, item);\n\t\t\tSharpTreeViewItem container = element as SharpTreeViewItem;\n\t\t\tcontainer.ParentTreeView = this;\n\t\t\t// Make sure that the line renderer takes into account the new bound data\n\t\t\tif (container.NodeView != null)\n\t\t\t{\n\t\t\t\tcontainer.NodeView.LinesRenderer.InvalidateVisual();\n\t\t\t}\n\t\t}\n\n\t\tbool doNotScrollOnExpanding;\n\n\t\t/// <summary>\n\t\t/// Handles the node expanding event in the tree view.\n\t\t/// This method gets called only if the node is in the visible region (a SharpTreeNodeView exists).\n\t\t/// </summary>\n\t\tinternal void HandleExpanding(SharpTreeNode node)\n\t\t{\n\t\t\tif (doNotScrollOnExpanding)\n\t\t\t\treturn;\n\t\t\tSharpTreeNode lastVisibleChild = node;\n\t\t\twhile (true)\n\t\t\t{\n\t\t\t\tSharpTreeNode tmp = lastVisibleChild.Children.LastOrDefault(c => c.IsVisible);\n\t\t\t\tif (tmp != null)\n\t\t\t\t{\n\t\t\t\t\tlastVisibleChild = tmp;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (lastVisibleChild != node)\n\t\t\t{\n\t\t\t\t// Make the the expanded children are visible; but don't scroll down\n\t\t\t\t// to much (keep node itself visible)\n\t\t\t\tbase.ScrollIntoView(lastVisibleChild);\n\t\t\t\t// For some reason, this only works properly when delaying it...\n\t\t\t\tDispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(\n\t\t\t\t\tdelegate {\n\t\t\t\t\t\tbase.ScrollIntoView(node);\n\t\t\t\t\t}));\n\t\t\t}\n\t\t}\n\n\t\tprotected override void OnKeyDown(KeyEventArgs e)\n\t\t{\n\t\t\tSharpTreeViewItem container = e.OriginalSource as SharpTreeViewItem;\n\t\t\tswitch (e.Key)\n\t\t\t{\n\t\t\t\tcase Key.Left:\n\t\t\t\t\tif (container != null && ItemsControl.ItemsControlFromItemContainer(container) == this)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (container.Node.IsExpanded)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontainer.Node.IsExpanded = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (container.Node.Parent != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tthis.FocusNode(container.Node.Parent);\n\t\t\t\t\t\t}\n\t\t\t\t\t\te.Handled = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase Key.Right:\n\t\t\t\t\tif (container != null && ItemsControl.ItemsControlFromItemContainer(container) == this)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!container.Node.IsExpanded && container.Node.ShowExpander)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontainer.Node.IsExpanded = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (container.Node.Children.Count > 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// jump to first child:\n\t\t\t\t\t\t\tcontainer.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down));\n\t\t\t\t\t\t}\n\t\t\t\t\t\te.Handled = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase Key.Return:\n\t\t\t\t\tif (container != null && Keyboard.Modifiers == ModifierKeys.None && this.SelectedItems.Count == 1 && this.SelectedItem == container.Node)\n\t\t\t\t\t{\n\t\t\t\t\t\te.Handled = true;\n\t\t\t\t\t\tcontainer.Node.ActivateItem(new WpfWindowsRoutedEventArgs(e));\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase Key.Space:\n\t\t\t\t\tif (container != null && Keyboard.Modifiers == ModifierKeys.None && this.SelectedItems.Count == 1 && this.SelectedItem == container.Node)\n\t\t\t\t\t{\n\t\t\t\t\t\te.Handled = true;\n\t\t\t\t\t\tif (container.Node.IsCheckable)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (container.Node.IsChecked == null) // If partially selected, we want to select everything\n\t\t\t\t\t\t\t\tcontainer.Node.IsChecked = true;\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tcontainer.Node.IsChecked = !container.Node.IsChecked;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcontainer.Node.ActivateItem(new WpfWindowsRoutedEventArgs(e));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase Key.Add:\n\t\t\t\t\tif (container != null && ItemsControl.ItemsControlFromItemContainer(container) == this)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontainer.Node.IsExpanded = true;\n\t\t\t\t\t\te.Handled = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase Key.Subtract:\n\t\t\t\t\tif (container != null && ItemsControl.ItemsControlFromItemContainer(container) == this)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontainer.Node.IsExpanded = false;\n\t\t\t\t\t\te.Handled = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase Key.Multiply:\n\t\t\t\t\tif (container != null && ItemsControl.ItemsControlFromItemContainer(container) == this)\n\t\t\t\t\t{\n\t\t\t\t\t\tcontainer.Node.IsExpanded = true;\n\t\t\t\t\t\tExpandRecursively(container.Node);\n\t\t\t\t\t\te.Handled = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase Key.Back:\n\t\t\t\t\tif (IsTextSearchEnabled)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar instance = SharpTreeViewTextSearch.GetInstance(this);\n\t\t\t\t\t\tif (instance != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tinstance.RevertLastCharacter();\n\t\t\t\t\t\t\te.Handled = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase Key.System:\n\t\t\t\t\t// https://github.com/icsharpcode/ILSpy/issues/3378:\n\t\t\t\t\t// Behavior got broken when upgrading to .NET 8.0 for unknown reasons and without\n\t\t\t\t\t// any more specific known cause. We fix it by not handling Alt+Left or Right\n\t\t\t\t\t// in SharpTreeView so it is handled by the window.\n\t\t\t\t\tif (e.SystemKey is Key.Left or Key.Right)\n\t\t\t\t\t{\n\t\t\t\t\t\t// yes, we do NOT call base.OnKeyDown(e); in this case.\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!e.Handled)\n\t\t\t\tbase.OnKeyDown(e);\n\t\t}\n\n\t\tprotected override void OnTextInput(TextCompositionEventArgs e)\n\t\t{\n\t\t\tif (!string.IsNullOrEmpty(e.Text) && IsTextSearchEnabled && (e.OriginalSource == this || ItemsControl.ItemsControlFromItemContainer(e.OriginalSource as DependencyObject) == this))\n\t\t\t{\n\t\t\t\tvar instance = SharpTreeViewTextSearch.GetInstance(this);\n\t\t\t\tif (instance != null)\n\t\t\t\t{\n\t\t\t\t\tinstance.Search(e.Text);\n\t\t\t\t\te.Handled = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!e.Handled)\n\t\t\t\tbase.OnTextInput(e);\n\t\t}\n\n\t\tvoid ExpandRecursively(SharpTreeNode node)\n\t\t{\n\t\t\tif (node.CanExpandRecursively)\n\t\t\t{\n\t\t\t\tnode.IsExpanded = true;\n\t\t\t\tforeach (SharpTreeNode child in node.Children)\n\t\t\t\t{\n\t\t\t\t\tExpandRecursively(child);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Scrolls the specified node in view and sets keyboard focus on it.\n\t\t/// </summary>\n\t\tpublic void FocusNode(SharpTreeNode node)\n\t\t{\n\t\t\tArgumentNullException.ThrowIfNull(node);\n\n\t\t\tScrollIntoView(node);\n\n\t\t\t// WPF's ScrollIntoView() uses the same if/dispatcher construct, so we call OnFocusItem() after the item was brought into view.\n\t\t\tif (this.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)\n\t\t\t{\n\t\t\t\tOnFocusItem(node);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis.BeginInvoke(DispatcherPriority.Loaded, () => OnFocusItem(node));\n\t\t\t}\n\t\t}\n\n\t\tpublic void ScrollIntoView(SharpTreeNode node)\n\t\t{\n\t\t\tif (node == null)\n\t\t\t\tthrow new ArgumentNullException(\"node\");\n\t\t\tdoNotScrollOnExpanding = true;\n\t\t\tforeach (SharpTreeNode ancestor in node.Ancestors())\n\t\t\t{\n\t\t\t\tancestor.IsExpanded = true;\n\t\t\t}\n\t\t\tdoNotScrollOnExpanding = false;\n\t\t\tbase.ScrollIntoView(node);\n\t\t}\n\n\t\tobject OnFocusItem(object item)\n\t\t{\n\t\t\tFrameworkElement element = this.ItemContainerGenerator.ContainerFromItem(item) as FrameworkElement;\n\t\t\tif (element != null)\n\t\t\t{\n\t\t\t\telement.Focus();\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tprotected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()\n\t\t{\n\t\t\treturn new SharpTreeViewAutomationPeer(this);\n\t\t}\n\t\t#region Track selection\n\n\t\tprotected override void OnSelectionChanged(SelectionChangedEventArgs e)\n\t\t{\n\t\t\tforeach (SharpTreeNode node in e.RemovedItems)\n\t\t\t{\n\t\t\t\tnode.IsSelected = false;\n\t\t\t}\n\t\t\tforeach (SharpTreeNode node in e.AddedItems)\n\t\t\t{\n\t\t\t\tnode.IsSelected = true;\n\t\t\t}\n\t\t\tbase.OnSelectionChanged(e);\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Drag and Drop\n\t\tprotected override void OnDragEnter(DragEventArgs e)\n\t\t{\n\t\t\tOnDragOver(e);\n\t\t}\n\n\t\tprotected override void OnDragOver(DragEventArgs e)\n\t\t{\n\t\t\te.Effects = DragDropEffects.None;\n\n\t\t\tif (Root != null && !ShowRoot)\n\t\t\t{\n\t\t\t\te.Handled = true;\n\t\t\t\tRoot.CanDrop(new WpfWindowsDragEventArgs(e), Root.Children.Count);\n\t\t\t}\n\t\t}\n\n\t\tprotected override void OnDrop(DragEventArgs e)\n\t\t{\n\t\t\te.Effects = DragDropEffects.None;\n\n\t\t\tif (Root != null && !ShowRoot)\n\t\t\t{\n\t\t\t\te.Handled = true;\n\t\t\t\tRoot.InternalDrop(new WpfWindowsDragEventArgs(e), Root.Children.Count);\n\t\t\t}\n\t\t}\n\n\t\tinternal void HandleDragEnter(SharpTreeViewItem item, DragEventArgs e)\n\t\t{\n\t\t\tHandleDragOver(item, e);\n\t\t}\n\n\t\tinternal void HandleDragOver(SharpTreeViewItem item, DragEventArgs e)\n\t\t{\n\t\t\tHidePreview();\n\n\t\t\tvar target = GetDropTarget(item, e);\n\t\t\tif (target != null)\n\t\t\t{\n\t\t\t\te.Handled = true;\n\t\t\t\tShowPreview(target.Item, target.Place);\n\t\t\t}\n\t\t}\n\n\t\tinternal void HandleDrop(SharpTreeViewItem item, DragEventArgs e)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tHidePreview();\n\n\t\t\t\tvar target = GetDropTarget(item, e);\n\t\t\t\tif (target != null)\n\t\t\t\t{\n\t\t\t\t\te.Handled = true;\n\t\t\t\t\ttarget.Node.InternalDrop(new WpfWindowsDragEventArgs(e), target.Index);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tDebug.WriteLine(ex.ToString());\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}\n\n\t\tinternal void HandleDragLeave(SharpTreeViewItem item, DragEventArgs e)\n\t\t{\n\t\t\tHidePreview();\n\t\t\te.Handled = true;\n\t\t}\n\n\t\tclass DropTarget\n\t\t{\n\t\t\tpublic SharpTreeViewItem Item;\n\t\t\tpublic DropPlace Place;\n\t\t\tpublic double Y;\n\t\t\tpublic SharpTreeNode Node;\n\t\t\tpublic int Index;\n\t\t}\n\n\t\tDropTarget GetDropTarget(SharpTreeViewItem item, DragEventArgs e)\n\t\t{\n\t\t\tvar dropTargets = BuildDropTargets(item, e);\n\t\t\tvar y = e.GetPosition(item).Y;\n\t\t\tforeach (var target in dropTargets)\n\t\t\t{\n\t\t\t\tif (target.Y >= y)\n\t\t\t\t{\n\t\t\t\t\treturn target;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tList<DropTarget> BuildDropTargets(SharpTreeViewItem item, DragEventArgs e)\n\t\t{\n\t\t\tvar result = new List<DropTarget>();\n\t\t\tvar node = item.Node;\n\n\t\t\tif (AllowDropOrder)\n\t\t\t{\n\t\t\t\tTryAddDropTarget(result, item, DropPlace.Before, e);\n\t\t\t}\n\n\t\t\tTryAddDropTarget(result, item, DropPlace.Inside, e);\n\n\t\t\tif (AllowDropOrder)\n\t\t\t{\n\t\t\t\tif (node.IsExpanded && node.Children.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tvar firstChildItem = ItemContainerGenerator.ContainerFromItem(node.Children[0]) as SharpTreeViewItem;\n\t\t\t\t\tTryAddDropTarget(result, firstChildItem, DropPlace.Before, e);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tTryAddDropTarget(result, item, DropPlace.After, e);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar h = item.ActualHeight;\n\t\t\tvar y1 = 0.2 * h;\n\t\t\tvar y2 = h / 2;\n\t\t\tvar y3 = h - y1;\n\n\t\t\tif (result.Count == 2)\n\t\t\t{\n\t\t\t\tif (result[0].Place == DropPlace.Inside &&\n\t\t\t\t\tresult[1].Place != DropPlace.Inside)\n\t\t\t\t{\n\t\t\t\t\tresult[0].Y = y3;\n\t\t\t\t}\n\t\t\t\telse if (result[0].Place != DropPlace.Inside &&\n\t\t\t\t\t\t result[1].Place == DropPlace.Inside)\n\t\t\t\t{\n\t\t\t\t\tresult[0].Y = y1;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tresult[0].Y = y2;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (result.Count == 3)\n\t\t\t{\n\t\t\t\tresult[0].Y = y1;\n\t\t\t\tresult[1].Y = y3;\n\t\t\t}\n\t\t\tif (result.Count > 0)\n\t\t\t{\n\t\t\t\tresult[result.Count - 1].Y = h;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tvoid TryAddDropTarget(List<DropTarget> targets, SharpTreeViewItem item, DropPlace place, DragEventArgs e)\n\t\t{\n\t\t\tSharpTreeNode node;\n\t\t\tint index;\n\n\t\t\tGetNodeAndIndex(item, place, out node, out index);\n\n\t\t\tif (node != null)\n\t\t\t{\n\t\t\t\te.Effects = DragDropEffects.None;\n\t\t\t\tif (node.CanDrop(new WpfWindowsDragEventArgs(e), index))\n\t\t\t\t{\n\t\t\t\t\tDropTarget target = new DropTarget() {\n\t\t\t\t\t\tItem = item,\n\t\t\t\t\t\tPlace = place,\n\t\t\t\t\t\tNode = node,\n\t\t\t\t\t\tIndex = index\n\t\t\t\t\t};\n\t\t\t\t\ttargets.Add(target);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid GetNodeAndIndex(SharpTreeViewItem item, DropPlace place, out SharpTreeNode node, out int index)\n\t\t{\n\t\t\tnode = null;\n\t\t\tindex = 0;\n\n\t\t\tif (place == DropPlace.Inside)\n\t\t\t{\n\t\t\t\tnode = item.Node;\n\t\t\t\tindex = node.Children.Count;\n\t\t\t}\n\t\t\telse if (place == DropPlace.Before)\n\t\t\t{\n\t\t\t\tif (item.Node.Parent != null)\n\t\t\t\t{\n\t\t\t\t\tnode = item.Node.Parent;\n\t\t\t\t\tindex = node.Children.IndexOf(item.Node);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (item.Node.Parent != null)\n\t\t\t\t{\n\t\t\t\t\tnode = item.Node.Parent;\n\t\t\t\t\tindex = node.Children.IndexOf(item.Node) + 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tSharpTreeNodeView previewNodeView;\n\t\tInsertMarker insertMarker;\n\t\tDropPlace previewPlace;\n\n\t\tenum DropPlace\n\t\t{\n\t\t\tBefore, Inside, After\n\t\t}\n\n\t\tvoid ShowPreview(SharpTreeViewItem item, DropPlace place)\n\t\t{\n\t\t\tpreviewNodeView = item.NodeView;\n\t\t\tpreviewPlace = place;\n\n\t\t\tif (place == DropPlace.Inside)\n\t\t\t{\n\t\t\t\tpreviewNodeView.SetResourceReference(SharpTreeNodeView.TextBackgroundProperty, SystemColors.HighlightBrushKey);\n\t\t\t\tpreviewNodeView.SetResourceReference(SharpTreeNodeView.ForegroundProperty, SystemColors.HighlightTextBrushKey);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (insertMarker == null)\n\t\t\t\t{\n\t\t\t\t\tvar adornerLayer = AdornerLayer.GetAdornerLayer(this);\n\t\t\t\t\tvar adorner = new GeneralAdorner(this);\n\t\t\t\t\tinsertMarker = new InsertMarker();\n\t\t\t\t\tadorner.Child = insertMarker;\n\t\t\t\t\tadornerLayer.Add(adorner);\n\t\t\t\t}\n\n\t\t\t\tinsertMarker.Visibility = Visibility.Visible;\n\n\t\t\t\tvar p1 = previewNodeView.TransformToVisual(this).Transform(new Point());\n\t\t\t\tvar p = new Point(p1.X + previewNodeView.CalculateIndent() + 4.5, p1.Y - 3);\n\n\t\t\t\tif (place == DropPlace.After)\n\t\t\t\t{\n\t\t\t\t\tp.Y += previewNodeView.ActualHeight;\n\t\t\t\t}\n\n\t\t\t\tinsertMarker.Margin = new Thickness(p.X, p.Y, 0, 0);\n\n\t\t\t\tSharpTreeNodeView secondNodeView = null;\n\t\t\t\tvar index = flattener.IndexOf(item.Node);\n\n\t\t\t\tif (place == DropPlace.Before)\n\t\t\t\t{\n\t\t\t\t\tif (index > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tsecondNodeView = (ItemContainerGenerator.ContainerFromIndex(index - 1) as SharpTreeViewItem).NodeView;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (index + 1 < flattener.Count)\n\t\t\t\t{\n\t\t\t\t\tsecondNodeView = (ItemContainerGenerator.ContainerFromIndex(index + 1) as SharpTreeViewItem).NodeView;\n\t\t\t\t}\n\n\t\t\t\tvar w = p1.X + previewNodeView.ActualWidth - p.X;\n\n\t\t\t\tif (secondNodeView != null)\n\t\t\t\t{\n\t\t\t\t\tvar p2 = secondNodeView.TransformToVisual(this).Transform(new Point());\n\t\t\t\t\tw = Math.Max(w, p2.X + secondNodeView.ActualWidth - p.X);\n\t\t\t\t}\n\n\t\t\t\tinsertMarker.Width = w + 10;\n\t\t\t}\n\t\t}\n\n\t\tvoid HidePreview()\n\t\t{\n\t\t\tif (previewNodeView != null)\n\t\t\t{\n\t\t\t\tpreviewNodeView.ClearValue(SharpTreeNodeView.TextBackgroundProperty);\n\t\t\t\tpreviewNodeView.ClearValue(SharpTreeNodeView.ForegroundProperty);\n\t\t\t\tif (insertMarker != null)\n\t\t\t\t{\n\t\t\t\t\tinsertMarker.Visibility = Visibility.Collapsed;\n\t\t\t\t}\n\t\t\t\tpreviewNodeView = null;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Cut / Copy / Paste / Delete Commands\n\n\t\tstatic void RegisterCommands()\n\t\t{\n\t\t\tCommandManager.RegisterClassCommandBinding(typeof(SharpTreeView),\n\t\t\t\t\t\t\t\t\t\t\t\t\t   new CommandBinding(ApplicationCommands.Cut, HandleExecuted_Cut, HandleCanExecute_Cut));\n\n\t\t\tCommandManager.RegisterClassCommandBinding(typeof(SharpTreeView),\n\t\t\t\t\t\t\t\t\t\t\t\t\t   new CommandBinding(ApplicationCommands.Copy, HandleExecuted_Copy, HandleCanExecute_Copy));\n\n\t\t\tCommandManager.RegisterClassCommandBinding(typeof(SharpTreeView),\n\t\t\t\t\t\t\t\t\t\t\t\t\t   new CommandBinding(ApplicationCommands.Paste, HandleExecuted_Paste, HandleCanExecute_Paste));\n\n\t\t\tCommandManager.RegisterClassCommandBinding(typeof(SharpTreeView),\n\t\t\t\t\t\t\t\t\t\t\t\t\t   new CommandBinding(ApplicationCommands.Delete, HandleExecuted_Delete, HandleCanExecute_Delete));\n\t\t}\n\n\t\tstatic void HandleExecuted_Cut(object sender, ExecutedRoutedEventArgs e)\n\t\t{\n\n\t\t}\n\n\t\tstatic void HandleCanExecute_Cut(object sender, CanExecuteRoutedEventArgs e)\n\t\t{\n\t\t\te.CanExecute = false;\n\t\t}\n\n\t\tstatic void HandleExecuted_Copy(object sender, ExecutedRoutedEventArgs e)\n\t\t{\n\n\t\t}\n\n\t\tstatic void HandleCanExecute_Copy(object sender, CanExecuteRoutedEventArgs e)\n\t\t{\n\t\t\te.CanExecute = false;\n\t\t}\n\n\t\tstatic void HandleExecuted_Paste(object sender, ExecutedRoutedEventArgs e)\n\t\t{\n\n\t\t}\n\n\t\tstatic void HandleCanExecute_Paste(object sender, CanExecuteRoutedEventArgs e)\n\t\t{\n\t\t\te.CanExecute = false;\n\t\t}\n\n\t\tstatic void HandleExecuted_Delete(object sender, ExecutedRoutedEventArgs e)\n\t\t{\n\t\t\tSharpTreeView treeView = (SharpTreeView)sender;\n\t\t\ttreeView.updatesLocked = true;\n\t\t\tint selectedIndex = -1;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tforeach (SharpTreeNode node in treeView.GetTopLevelSelection().ToArray())\n\t\t\t\t{\n\t\t\t\t\tif (selectedIndex == -1)\n\t\t\t\t\t\tselectedIndex = treeView.flattener.IndexOf(node);\n\t\t\t\t\tnode.Delete();\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\ttreeView.updatesLocked = false;\n\t\t\t\ttreeView.UpdateFocusedNode(null, Math.Max(0, selectedIndex - 1));\n\t\t\t}\n\t\t}\n\n\t\tstatic void HandleCanExecute_Delete(object sender, CanExecuteRoutedEventArgs e)\n\t\t{\n\t\t\tSharpTreeView treeView = (SharpTreeView)sender;\n\t\t\te.CanExecute = treeView.GetTopLevelSelection().All(node => node.CanDelete());\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the selected items which do not have any of their ancestors selected.\n\t\t/// </summary>\n\t\tpublic IEnumerable<SharpTreeNode> GetTopLevelSelection()\n\t\t{\n\t\t\tvar selection = this.SelectedItems.OfType<SharpTreeNode>().ToHashSet();\n\n\t\t\treturn selection.Where(item => item.Ancestors().All(a => !selection.Contains(a)));\n\t\t}\n\n\t\t#endregion\n\n\t\tpublic void SetSelectedNodes(IEnumerable<SharpTreeNode> nodes)\n\t\t{\n\t\t\tbool success = this.SetSelectedItems(nodes.ToList());\n\t\t\tDebug.Assert(success);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/TreeView/SharpTreeView.xaml",
    "content": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n                    xmlns:Default=\"clr-namespace:ICSharpCode.ILSpy.Controls.TreeView\"\n                    xmlns:styles=\"urn:TomsToolbox.Wpf.Styles\"\n                    xmlns:toms=\"urn:TomsToolbox\">\n\n    <Style x:Key=\"ExpandCollapseToggleStyle\"\n           TargetType=\"{x:Type ToggleButton}\" BasedOn=\"{StaticResource {x:Type ToggleButton}}\">\n        <Setter Property=\"Focusable\"\n                Value=\"False\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ToggleButton}\">\n                    <Border Width=\"9\"\n                            Height=\"9\"\n                            BorderThickness=\"1\"\n                            BorderBrush=\"{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}\"\n                            CornerRadius=\"1\"\n                            SnapsToDevicePixels=\"True\">\n                        <Border.Background>\n                            <LinearGradientBrush StartPoint=\"0,0\"\n                                                 EndPoint=\"1,1\">\n                                <LinearGradientBrush.GradientStops>\n                                    <GradientStop Color=\"White\"\n                                                  Offset=\".2\" />\n                                    <GradientStop Color=\"#FFC0B7A6\"\n                                                  Offset=\"1\" />\n                                </LinearGradientBrush.GradientStops>\n                            </LinearGradientBrush>\n                        </Border.Background>\n                        <Path Name=\"ExpandPath\"\n                              Margin=\"1,1,1,1\"\n                              Fill=\"Black\"\n                              Data=\"M 0 2 L 0 3 L 2 3 L 2 5 L 3 5 L 3 3 L 5 3 L 5 2 L 3 2 L 3 0 L 2 0 L 2 2 Z\" />\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsChecked\"\n                                 Value=\"True\">\n                            <Setter Property=\"Data\"\n                                    TargetName=\"ExpandPath\"\n                                    Value=\"M 0 2 L 0 3 L 5 3 L 5 2 Z\" />\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style TargetType=\"{x:Type Default:InsertMarker}\">\n        <Setter Property=\"IsHitTestVisible\"\n                Value=\"False\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Default:InsertMarker}\">\n                    <Grid>\n                        <Border VerticalAlignment=\"Center\"\n                                Height=\"2\"\n                                Background=\"{DynamicResource {x:Static SystemColors.HighlightBrushKey}}\" />\n                        <Path Data=\"m 0 0 l 3 3 l -3 3\"\n                              Fill=\"{DynamicResource {x:Static SystemColors.HighlightBrushKey}}\"\n                              HorizontalAlignment=\"Left\" />\n                        <Path Data=\"m 0 0 l -3 3 l 3 3\"\n                              Fill=\"{DynamicResource {x:Static SystemColors.HighlightBrushKey}}\"\n                              HorizontalAlignment=\"Right\" />\n                    </Grid>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style TargetType=\"{x:Type Default:EditTextBox}\">\n        <Setter Property=\"Foreground\"\n                Value=\"{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}\" />\n        <Setter Property=\"KeyboardNavigation.TabNavigation\"\n                Value=\"None\" />\n        <Setter Property=\"HorizontalContentAlignment\"\n                Value=\"Left\" />\n        <Setter Property=\"FocusVisualStyle\"\n                Value=\"{x:Null}\" />\n        <Setter Property=\"AllowDrop\"\n                Value=\"True\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Default:EditTextBox}\">\n                    <Border Background=\"{DynamicResource {x:Static SystemColors.WindowBrushKey}}\"\n                            BorderThickness=\"1\"\n                            BorderBrush=\"{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}\"\n                            Padding=\"0 1 2 0\">\n                        <ScrollViewer Name=\"PART_ContentHost\" />\n                    </Border>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    \n    <Style TargetType=\"{x:Type Default:SharpTreeView}\"\n           BasedOn=\"{StaticResource {x:Static styles:ResourceKeys.ListBoxStyle}}\">\n        <Style.Triggers>\n            <Trigger Property=\"ShowRoot\"\n                     Value=\"False\">\n                <Setter Property=\"Padding\"\n                        Value=\"5 0 0 0\" />\n            </Trigger>\n        </Style.Triggers>\n    </Style>\n\n    <Style x:Key=\"{x:Static Default:SharpTreeView.DefaultItemContainerStyleKey}\"\n           TargetType=\"{x:Type Default:SharpTreeViewItem}\">\n        <Style.Triggers>\n            <MultiTrigger>\n                <MultiTrigger.Conditions>\n                    <Condition Property=\"ItemsControl.AlternationIndex\"\n                               Value=\"1\" />\n                    <Condition Property=\"Default:SharpTreeView.ShowAlternation\"\n                               Value=\"True\" />\n                </MultiTrigger.Conditions>\n                <Setter Property=\"Background\"\n                        Value=\"{DynamicResource {x:Static SystemColors.ControlLightLightBrushKey}}\" />\n            </MultiTrigger>\n        </Style.Triggers>\n    </Style>\n\n    <Style x:Key=\"{x:Static Default:SharpGridView.ItemContainerStyleKey}\"\n           TargetType=\"{x:Type ListViewItem}\" BasedOn=\"{StaticResource {x:Type ListViewItem}}\">\n        <Setter Property=\"Background\"\n                Value=\"Transparent\" />\n        <Setter Property=\"VerticalContentAlignment\"\n                Value=\"Center\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ListViewItem}\">\n                    <Border Name=\"Bd\"\n                            Background=\"{TemplateBinding Background}\"\n                            BorderBrush=\"{TemplateBinding BorderBrush}\"\n                            BorderThickness=\"{TemplateBinding BorderThickness}\"\n                            Padding=\"{TemplateBinding Padding}\"\n                            SnapsToDevicePixels=\"true\">\n                        <GridViewRowPresenter VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"\n                                              SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" />\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsSelected\"\n                                 Value=\"true\">\n                            <Setter TargetName=\"Bd\"\n                                    Property=\"Background\"\n                                    Value=\"{DynamicResource {x:Static SystemColors.HighlightBrushKey}}\" />\n                            <Setter Property=\"Foreground\"\n                                    Value=\"{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}\" />\n                        </Trigger>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsSelected\"\n                                           Value=\"true\" />\n                                <Condition Property=\"Selector.IsSelectionActive\"\n                                           Value=\"false\" />\n                            </MultiTrigger.Conditions>\n                            <Setter TargetName=\"Bd\"\n                                    Property=\"Background\"\n                                    Value=\"{DynamicResource {x:Static SystemColors.ControlBrushKey}}\" />\n                            <Setter Property=\"Foreground\"\n                                    Value=\"{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}\" />\n                        </MultiTrigger>\n                        <Trigger Property=\"IsEnabled\"\n                                 Value=\"false\">\n                            <Setter Property=\"Foreground\"\n                                    Value=\"{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}\" />\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style TargetType=\"{x:Type Default:SharpTreeViewItem}\">\n        <Setter Property=\"FocusVisualStyle\"\n                Value=\"{x:Null}\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Default:SharpTreeViewItem}\">\n                    <Border Background=\"Transparent\">\n                        <Border Background=\"{TemplateBinding Background}\">\n                            <Default:SharpTreeNodeView x:Name=\"nodeView\"\n                                                       HorizontalAlignment=\"Left\" />\n                        </Border>\n                    </Border>\n                    <ControlTemplate.Triggers>\n\t                    <Trigger Property=\"IsSelected\"\n\t                             Value=\"True\">\n                            <Setter TargetName=\"nodeView\"\n                                    Property=\"TextBackground\"\n                                    Value=\"{DynamicResource {x:Static SystemColors.HighlightBrushKey}}\" />\n                            <Setter TargetName=\"nodeView\"\n                                    Property=\"Foreground\"\n                                    Value=\"{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}\" />\n                        </Trigger>\n                        <!--<MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsSelected\"\n                                           Value=\"True\" />\n                                <Condition Property=\"Selector.IsSelectionActive\"\n                                           Value=\"False\" />\n                            </MultiTrigger.Conditions>\n                            <Setter TargetName=\"nodeView\"\n                                    Property=\"TextBackground\"\n                                    Value=\"{DynamicResource {x:Static SystemColors.ControlBrushKey}}\" />\n                            <Setter TargetName=\"nodeView\"\n                                    Property=\"Foreground\"\n                                    Value=\"{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}\" />\n                        </MultiTrigger>-->\n                        <Trigger Property=\"IsEnabled\"\n                                 Value=\"False\">\n                            <Setter TargetName=\"nodeView\"\n                                    Property=\"Foreground\"\n                                    Value=\"{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}\" />\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style TargetType=\"{x:Type Default:SharpTreeNodeView}\">\n        <Setter Property=\"Focusable\"\n                Value=\"False\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Default:SharpTreeNodeView}\">\n                    <Grid>\n                        <Default:LinesRenderer x:Name=\"linesRenderer\"\n                                               ClipToBounds=\"True\"\n                                               Visibility=\"{Binding ShowLines, RelativeSource={RelativeSource AncestorType={x:Type Default:SharpTreeView}}, Converter={toms:BooleanToVisibilityConverter}}\" />\n                        <StackPanel Orientation=\"Horizontal\">\n                            <FrameworkElement Name=\"spacer\" />\n                            <ToggleButton Name=\"expander\"\n                                          Style=\"{StaticResource ExpandCollapseToggleStyle}\"\n                                          IsChecked=\"{Binding IsExpanded}\"\n                                          Visibility=\"Hidden\"\n                                          Margin=\"0 0 7 0\"\n                                          VerticalAlignment=\"Center\" />\n                            <Border Name=\"checkBoxContainer\"\n                                    Width=\"16\"\n                                    Margin=\"0 0 3 0\"\n                                    Visibility=\"Collapsed\">\n                                <CheckBox IsChecked=\"{Binding IsChecked}\"\n                                          HorizontalAlignment=\"Center\"\n                                          VerticalAlignment=\"Center\" />\n                            </Border>\n                            <StackPanel Orientation=\"Horizontal\"\n                                        Background=\"{Binding Background}\"\n                                        ToolTip=\"{Binding ToolTip}\">\n\t\t\t\t\t\t\t\t<ContentPresenter Name=\"icon\"\n                                                  Content=\"{Binding Icon}\"\n                                                  Width=\"16\"\n                                                  Height=\"16\"\n                                                  Margin=\"0 0 5 1\"\n                                                  VerticalAlignment=\"Center\"\n                                                  Focusable=\"False\">\n\t\t\t\t\t\t\t\t\t<ContentPresenter.ContentTemplate>\n\t\t\t\t\t\t\t\t\t\t<DataTemplate>\n\t\t\t\t\t\t\t\t\t\t\t<Image Source=\"{Binding}\"/>\n\t\t\t\t\t\t\t\t\t\t</DataTemplate>\n\t\t\t\t\t\t\t\t\t</ContentPresenter.ContentTemplate>\n\t\t\t\t\t\t\t\t</ContentPresenter>\n\t\t\t\t\t\t\t\t<Border Name=\"textContainer\"\n                                        Background=\"{TemplateBinding TextBackground}\">\n                                    <ContentPresenter Content=\"{Binding Text}\"\n                                                      Margin=\"2 0 6 0\"\n                                                      VerticalAlignment=\"Center\"\n                                                      Focusable=\"False\" />\n                                </Border>\n                                <Border Name=\"textEditorContainer\" />\n                            </StackPanel>\n                        </StackPanel>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <DataTrigger Binding=\"{Binding IsEditing}\"\n                                     Value=\"True\">\n                            <Setter TargetName=\"textContainer\"\n                                    Property=\"Visibility\"\n                                    Value=\"Collapsed\" />\n                        </DataTrigger>\n                    \t  <DataTrigger Binding=\"{Binding ShowIcon}\"\n                                     Value=\"False\">\n                    \t\t  <Setter TargetName=\"icon\"\n                                    Property=\"Visibility\"\n                                   Value=\"Collapsed\" />\n \t\t\t\t\t\t  </DataTrigger>\n                        <DataTrigger Binding=\"{Binding IsExpanded}\"\n                                     Value=\"True\">\n                            <Setter TargetName=\"icon\"\n                                    Property=\"Content\"\n                                    Value=\"{Binding ExpandedIcon}\" />\n                        </DataTrigger>\n                        <DataTrigger Binding=\"{Binding ShowExpander}\"\n                                     Value=\"True\">\n                            <Setter TargetName=\"expander\"\n                                    Property=\"Visibility\"\n                                    Value=\"Visible\" />\n                        </DataTrigger>\n                        <DataTrigger Binding=\"{Binding IsCheckable}\"\n                                     Value=\"True\">\n                            <Setter TargetName=\"checkBoxContainer\"\n                                    Property=\"Visibility\"\n                                    Value=\"Visible\" />\n                        </DataTrigger>\n                        <DataTrigger Binding=\"{Binding IsCut}\"\n                                     Value=\"True\">\n                            <Setter TargetName=\"icon\"\n                                    Property=\"Opacity\"\n                                    Value=\"0.5\" />\n                        </DataTrigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n</ResourceDictionary>\n"
  },
  {
    "path": "ILSpy/Controls/TreeView/SharpTreeViewAutomationPeer.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Windows.Automation.Peers;\n\nnamespace ICSharpCode.ILSpy.Controls.TreeView\n{\n\tclass SharpTreeViewAutomationPeer : FrameworkElementAutomationPeer\n\t{\n\t\tinternal SharpTreeViewAutomationPeer(SharpTreeView owner) : base(owner)\n\t\t{\n\t\t}\n\n\t\tprotected override AutomationControlType GetAutomationControlTypeCore()\n\t\t{\n\t\t\treturn AutomationControlType.Tree;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/TreeView/SharpTreeViewItem.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Input;\n\nusing ICSharpCode.ILSpyX.TreeView;\n\nnamespace ICSharpCode.ILSpy.Controls.TreeView\n{\n\tpublic class SharpTreeViewItem : ListViewItem\n\t{\n\t\tstatic SharpTreeViewItem()\n\t\t{\n\t\t\tDefaultStyleKeyProperty.OverrideMetadata(typeof(SharpTreeViewItem),\n\t\t\t\t\t\t\t\t\t\t\t\t\t new FrameworkPropertyMetadata(typeof(SharpTreeViewItem)));\n\t\t}\n\n\t\tpublic SharpTreeNode Node {\n\t\t\tget { return DataContext as SharpTreeNode; }\n\t\t}\n\n\t\tpublic SharpTreeNodeView NodeView { get; internal set; }\n\t\tpublic SharpTreeView ParentTreeView { get; internal set; }\n\n\t\tprotected override void OnKeyDown(KeyEventArgs e)\n\t\t{\n\t\t\tswitch (e.Key)\n\t\t\t{\n\t\t\t\tcase Key.F2:\n\t\t\t\t\tif (Node.IsEditable && ParentTreeView != null && ParentTreeView.SelectedItems.Count == 1 && ParentTreeView.SelectedItems[0] == Node)\n\t\t\t\t\t{\n\t\t\t\t\t\tNode.IsEditing = true;\n\t\t\t\t\t\te.Handled = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase Key.Escape:\n\t\t\t\t\tif (Node.IsEditing)\n\t\t\t\t\t{\n\t\t\t\t\t\tNode.IsEditing = false;\n\t\t\t\t\t\te.Handled = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tprotected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer()\n\t\t{\n\t\t\treturn new SharpTreeViewItemAutomationPeer(this);\n\t\t}\n\n\t\t#region Mouse\n\n\t\tPoint startPoint;\n\t\tbool wasSelected;\n\t\tbool wasDoubleClick;\n\n\t\tprotected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)\n\t\t{\n\t\t\twasSelected = IsSelected;\n\t\t\tif (!IsSelected)\n\t\t\t{\n\t\t\t\tbase.OnMouseLeftButtonDown(e);\n\t\t\t}\n\n\t\t\tif (Mouse.LeftButton == MouseButtonState.Pressed)\n\t\t\t{\n\t\t\t\tstartPoint = e.GetPosition(null);\n\t\t\t\tCaptureMouse();\n\n\t\t\t\tif (e.ClickCount == 2)\n\t\t\t\t{\n\t\t\t\t\twasDoubleClick = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected override void OnMouseMove(MouseEventArgs e)\n\t\t{\n\t\t\tif (IsMouseCaptured)\n\t\t\t{\n\t\t\t\tvar currentPoint = e.GetPosition(null);\n\t\t\t\tif (Math.Abs(currentPoint.X - startPoint.X) >= SystemParameters.MinimumHorizontalDragDistance ||\n\t\t\t\t\tMath.Abs(currentPoint.Y - startPoint.Y) >= SystemParameters.MinimumVerticalDragDistance)\n\t\t\t\t{\n\n\t\t\t\t\tvar selection = ParentTreeView.GetTopLevelSelection().ToArray();\n\t\t\t\t\tif (Node.CanDrag(selection))\n\t\t\t\t\t{\n\t\t\t\t\t\tNode.StartDrag(this, selection, new WpfWindowsDragDropManager());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)\n\t\t{\n\t\t\tif (wasDoubleClick)\n\t\t\t{\n\t\t\t\twasDoubleClick = false;\n\t\t\t\tNode.ActivateItem(new WpfWindowsRoutedEventArgs(e));\n\t\t\t\tif (!e.Handled)\n\t\t\t\t{\n\t\t\t\t\tif (!Node.IsRoot || ParentTreeView.ShowRootExpander)\n\t\t\t\t\t{\n\t\t\t\t\t\tNode.IsExpanded = !Node.IsExpanded;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tReleaseMouseCapture();\n\t\t\tif (wasSelected)\n\t\t\t{\n\t\t\t\tbase.OnMouseLeftButtonDown(e);\n\t\t\t}\n\t\t}\n\n\t\tprotected override void OnMouseUp(MouseButtonEventArgs e)\n\t\t{\n\t\t\tif (e.ChangedButton == MouseButton.Middle)\n\t\t\t{\n\t\t\t\tNode.ActivateItemSecondary(new WpfWindowsRoutedEventArgs(e));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbase.OnMouseUp(e);\n\t\t\t}\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Drag and Drop\n\n\t\tprotected override void OnDragEnter(DragEventArgs e)\n\t\t{\n\t\t\tParentTreeView.HandleDragEnter(this, e);\n\t\t}\n\n\t\tprotected override void OnDragOver(DragEventArgs e)\n\t\t{\n\t\t\tParentTreeView.HandleDragOver(this, e);\n\t\t}\n\n\t\tprotected override void OnDrop(DragEventArgs e)\n\t\t{\n\t\t\tParentTreeView.HandleDrop(this, e);\n\t\t}\n\n\t\tprotected override void OnDragLeave(DragEventArgs e)\n\t\t{\n\t\t\tParentTreeView.HandleDragLeave(this, e);\n\t\t}\n\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/TreeView/SharpTreeViewItemAutomationPeer.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.ComponentModel;\nusing System.Windows;\nusing System.Windows.Automation;\nusing System.Windows.Automation.Peers;\nusing System.Windows.Automation.Provider;\n\nusing ICSharpCode.ILSpyX.TreeView;\n\nnamespace ICSharpCode.ILSpy.Controls.TreeView\n{\n\tclass SharpTreeViewItemAutomationPeer : FrameworkElementAutomationPeer, IExpandCollapseProvider\n\t{\n\t\tinternal SharpTreeViewItemAutomationPeer(SharpTreeViewItem owner)\n\t\t\t: base(owner)\n\t\t{\n\t\t\tSharpTreeViewItem.DataContextChanged += OnDataContextChanged;\n\t\t\tSharpTreeNode node = SharpTreeViewItem.DataContext as SharpTreeNode;\n\t\t\tif (node == null)\n\t\t\t\treturn;\n\n\t\t\tnode.PropertyChanged += OnPropertyChanged;\n\t\t}\n\t\tprivate SharpTreeViewItem SharpTreeViewItem { get { return (SharpTreeViewItem)base.Owner; } }\n\t\tprotected override AutomationControlType GetAutomationControlTypeCore()\n\t\t{\n\t\t\treturn AutomationControlType.TreeItem;\n\t\t}\n\n\t\tpublic override object GetPattern(PatternInterface patternInterface)\n\t\t{\n\t\t\tif (patternInterface == PatternInterface.ExpandCollapse)\n\t\t\t\treturn this;\n\t\t\treturn base.GetPattern(patternInterface);\n\t\t}\n\n\t\tpublic void Collapse()\n\t\t{\n\t\t}\n\n\t\tpublic void Expand()\n\t\t{\n\t\t}\n\n\t\tpublic ExpandCollapseState ExpandCollapseState {\n\t\t\tget {\n\t\t\t\tSharpTreeNode node = SharpTreeViewItem.DataContext as SharpTreeNode;\n\t\t\t\tif (node == null || !node.ShowExpander)\n\t\t\t\t\treturn ExpandCollapseState.LeafNode;\n\t\t\t\treturn node.IsExpanded ? ExpandCollapseState.Expanded : ExpandCollapseState.Collapsed;\n\t\t\t}\n\t\t}\n\n\t\tprivate void OnPropertyChanged(object sender, PropertyChangedEventArgs e)\n\t\t{\n\t\t\tif (e.PropertyName != \"IsExpanded\")\n\t\t\t\treturn;\n\t\t\tSharpTreeNode node = sender as SharpTreeNode;\n\t\t\tif (node == null || node.Children.Count == 0)\n\t\t\t\treturn;\n\t\t\tbool newValue = node.IsExpanded;\n\t\t\tbool oldValue = !newValue;\n\t\t\tRaisePropertyChangedEvent(\n\t\t\t\tExpandCollapsePatternIdentifiers.ExpandCollapseStateProperty,\n\t\t\t\toldValue ? ExpandCollapseState.Expanded : ExpandCollapseState.Collapsed,\n\t\t\t\tnewValue ? ExpandCollapseState.Expanded : ExpandCollapseState.Collapsed);\n\t\t}\n\n\t\tprivate void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)\n\t\t{\n\t\t\tSharpTreeNode oldNode = e.OldValue as SharpTreeNode;\n\t\t\tif (oldNode != null)\n\t\t\t\toldNode.PropertyChanged -= OnPropertyChanged;\n\t\t\tSharpTreeNode newNode = e.NewValue as SharpTreeNode;\n\t\t\tif (newNode != null)\n\t\t\t\tnewNode.PropertyChanged += OnPropertyChanged;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/TreeView/SharpTreeViewTextSearch.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Runtime.InteropServices;\nusing System.Windows;\nusing System.Windows.Threading;\n\nusing ICSharpCode.ILSpyX.TreeView;\n\nnamespace ICSharpCode.ILSpy.Controls.TreeView\n{\n\t/// <summary>\n\t/// Custom TextSearch-implementation.\n\t/// Fixes #67 - Moving to class member in tree view by typing in first character of member name selects parent assembly\n\t/// </summary>\n\tpublic partial class SharpTreeViewTextSearch : DependencyObject\n\t{\n\t\tstatic readonly DependencyPropertyKey TextSearchInstancePropertyKey = DependencyProperty.RegisterAttachedReadOnly(\"TextSearchInstance\",\n\t\t\ttypeof(SharpTreeViewTextSearch), typeof(SharpTreeViewTextSearch), new FrameworkPropertyMetadata(null));\n\t\tstatic readonly DependencyProperty TextSearchInstanceProperty = TextSearchInstancePropertyKey.DependencyProperty;\n\n\t\tDispatcherTimer timer;\n\n\t\tbool isActive;\n\t\tint lastMatchIndex;\n\t\tstring matchPrefix;\n\n\t\treadonly Stack<string> inputStack;\n\t\treadonly SharpTreeView treeView;\n\n\t\tprivate SharpTreeViewTextSearch(SharpTreeView treeView)\n\t\t{\n\t\t\tif (treeView == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(treeView));\n\t\t\tthis.treeView = treeView;\n\t\t\tinputStack = new Stack<string>(8);\n\t\t\tClearState();\n\t\t}\n\n\t\tpublic static SharpTreeViewTextSearch GetInstance(SharpTreeView sharpTreeView)\n\t\t{\n\t\t\tvar textSearch = (SharpTreeViewTextSearch)sharpTreeView.GetValue(TextSearchInstanceProperty);\n\t\t\tif (textSearch == null)\n\t\t\t{\n\t\t\t\ttextSearch = new SharpTreeViewTextSearch(sharpTreeView);\n\t\t\t\tsharpTreeView.SetValue(TextSearchInstancePropertyKey, textSearch);\n\t\t\t}\n\t\t\treturn textSearch;\n\t\t}\n\n\t\tpublic bool RevertLastCharacter()\n\t\t{\n\t\t\tif (!isActive || inputStack.Count == 0)\n\t\t\t\treturn false;\n\t\t\tmatchPrefix = matchPrefix.Substring(0, matchPrefix.Length - inputStack.Pop().Length);\n\t\t\tResetTimeout();\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic bool Search(string nextChar)\n\t\t{\n\t\t\tint startIndex = isActive ? lastMatchIndex : Math.Max(0, treeView.SelectedIndex);\n\t\t\tbool lookBackwards = inputStack.Count > 0 && string.Compare(inputStack.Peek(), nextChar, StringComparison.OrdinalIgnoreCase) == 0;\n\t\t\tint nextMatchIndex = IndexOfMatch(matchPrefix + nextChar, startIndex, lookBackwards, out bool wasNewCharUsed);\n\t\t\tif (nextMatchIndex != -1)\n\t\t\t{\n\t\t\t\tif (!isActive || nextMatchIndex != startIndex)\n\t\t\t\t{\n\t\t\t\t\ttreeView.SelectedItem = treeView.Items[nextMatchIndex];\n\t\t\t\t\ttreeView.FocusNode((SharpTreeNode)treeView.SelectedItem);\n\t\t\t\t\tlastMatchIndex = nextMatchIndex;\n\t\t\t\t}\n\t\t\t\tif (wasNewCharUsed)\n\t\t\t\t{\n\t\t\t\t\tmatchPrefix += nextChar;\n\t\t\t\t\tinputStack.Push(nextChar);\n\t\t\t\t}\n\t\t\t\tisActive = true;\n\t\t\t}\n\t\t\tif (isActive)\n\t\t\t{\n\t\t\t\tResetTimeout();\n\t\t\t}\n\t\t\treturn nextMatchIndex != -1;\n\t\t}\n\n\t\tint IndexOfMatch(string needle, int startIndex, bool tryBackward, out bool charWasUsed)\n\t\t{\n\t\t\tcharWasUsed = false;\n\t\t\tif (treeView.Items.Count == 0 || string.IsNullOrEmpty(needle))\n\t\t\t\treturn -1;\n\t\t\tint index = -1;\n\t\t\tint fallbackIndex = -1;\n\t\t\tbool fallbackMatch = false;\n\t\t\tint i = startIndex;\n\t\t\tvar comparisonType = treeView.IsTextSearchCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tvar item = (SharpTreeNode)treeView.Items[i];\n\t\t\t\tif (item != null && item.Text != null)\n\t\t\t\t{\n\t\t\t\t\tstring text = item.Text.ToString();\n\t\t\t\t\tif (text.StartsWith(needle, comparisonType))\n\t\t\t\t\t{\n\t\t\t\t\t\tcharWasUsed = true;\n\t\t\t\t\t\tindex = i;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (tryBackward)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (fallbackMatch && matchPrefix != string.Empty)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (fallbackIndex == -1 && text.StartsWith(matchPrefix, comparisonType))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfallbackIndex = i;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfallbackMatch = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ti++;\n\t\t\t\tif (i >= treeView.Items.Count)\n\t\t\t\t\ti = 0;\n\t\t\t} while (i != startIndex);\n\t\t\treturn index == -1 ? fallbackIndex : index;\n\t\t}\n\n\t\tvoid ClearState()\n\t\t{\n\t\t\tisActive = false;\n\t\t\tmatchPrefix = string.Empty;\n\t\t\tlastMatchIndex = -1;\n\t\t\tinputStack.Clear();\n\t\t\ttimer?.Stop();\n\t\t\ttimer = null;\n\t\t}\n\n\t\tvoid ResetTimeout()\n\t\t{\n\t\t\tif (timer == null)\n\t\t\t{\n\t\t\t\ttimer = new DispatcherTimer(DispatcherPriority.Normal);\n\t\t\t\ttimer.Tick += (sender, e) => ClearState();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\ttimer.Stop();\n\t\t\t}\n\t\t\ttimer.Interval = TimeSpan.FromMilliseconds(NativeMethods.GetDoubleClickTime() * 2);\n\t\t\ttimer.Start();\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Controls/TreeView/WpfWindowsDataObject.cs",
    "content": "using System.Windows;\n\nusing ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;\n\nnamespace ICSharpCode.ILSpy.Controls.TreeView\n{\n\tpublic sealed class WpfWindowsDataObject : IPlatformDataObject\n\t{\n\t\tprivate readonly IDataObject _dataObject;\n\n\t\tpublic WpfWindowsDataObject(IDataObject dataObject)\n\t\t{\n\t\t\t_dataObject = dataObject;\n\t\t}\n\n\t\tpublic object GetData(string format)\n\t\t{\n\t\t\treturn _dataObject.GetData(format);\n\t\t}\n\n\t\tpublic bool GetDataPresent(string format)\n\t\t{\n\t\t\treturn _dataObject.GetDataPresent(format);\n\t\t}\n\n\t\tpublic void SetData(string format, object data)\n\t\t{\n\t\t\t_dataObject.SetData(format, data);\n\t\t}\n\n\t\tobject IPlatformDataObject.UnderlyingDataObject => _dataObject;\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/TreeView/WpfWindowsDragDropManager.cs",
    "content": "using System.Windows;\n\nusing ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;\n\nnamespace ICSharpCode.ILSpy.Controls.TreeView\n{\n\tpublic class WpfWindowsDragDropManager : IPlatformDragDrop\n\t{\n\t\tpublic XPlatDragDropEffects DoDragDrop(object dragSource, IPlatformDataObject data, XPlatDragDropEffects allowedEffects)\n\t\t{\n\t\t\treturn (XPlatDragDropEffects)DragDrop.DoDragDrop(dragSource as DependencyObject, data.UnderlyingDataObject, (DragDropEffects)allowedEffects);\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Controls/TreeView/WpfWindowsDragEventArgs.cs",
    "content": "using System.Windows;\n\nusing ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;\n\nnamespace ICSharpCode.ILSpy.Controls.TreeView\n{\n\tpublic class WpfWindowsDragEventArgs : IPlatformDragEventArgs\n\t{\n\t\tprivate readonly DragEventArgs _eventArgs;\n\n\t\tpublic WpfWindowsDragEventArgs(DragEventArgs eventArgs)\n\t\t{\n\t\t\t_eventArgs = eventArgs;\n\t\t}\n\n\t\tpublic XPlatDragDropEffects Effects { get => (XPlatDragDropEffects)_eventArgs.Effects; set => _eventArgs.Effects = (DragDropEffects)value; }\n\n\t\tpublic IPlatformDataObject Data => new WpfWindowsDataObject(_eventArgs.Data);\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/TreeView/WpfWindowsRoutedEventArgs.cs",
    "content": "using System.Windows;\n\nusing ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;\n\nnamespace ICSharpCode.ILSpy.Controls.TreeView\n{\n\tpublic class WpfWindowsRoutedEventArgs : IPlatformRoutedEventArgs\n\t{\n\t\tprivate readonly RoutedEventArgs _eventArgs;\n\n\t\tpublic WpfWindowsRoutedEventArgs(RoutedEventArgs eventArgs)\n\t\t{\n\t\t\t_eventArgs = eventArgs;\n\t\t}\n\n\t\tpublic bool Handled { get => _eventArgs.Handled; set => _eventArgs.Handled = value; }\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/XamlResourceExtension.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Windows.Markup;\n\nnamespace ICSharpCode.ILSpy.Controls\n{\n\tclass XamlResourceExtension : MarkupExtension\n\t{\n\t\treadonly string name;\n\n\t\tpublic XamlResourceExtension(string name)\n\t\t{\n\t\t\tthis.name = name ?? throw new ArgumentNullException(nameof(name));\n\t\t}\n\n\t\tpublic override object ProvideValue(IServiceProvider serviceProvider)\n\t\t{\n\t\t\treturn Images.Load(null, name);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/ZoomButtons.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Controls.Primitives;\nusing System.Windows.Data;\nusing System.Windows.Documents;\nusing System.Windows.Input;\nusing System.Windows.Media;\n\nnamespace ICSharpCode.ILSpy.Controls\n{\n\tpublic class ZoomButtons : RangeBase\n\t{\n\t\tstatic ZoomButtons()\n\t\t{\n\t\t\tDefaultStyleKeyProperty.OverrideMetadata(typeof(ZoomButtons),\n\t\t\t\t\t\t\t\t\t\t\t\t\t new FrameworkPropertyMetadata(typeof(ZoomButtons)));\n\t\t}\n\n\t\tpublic override void OnApplyTemplate()\n\t\t{\n\t\t\tbase.OnApplyTemplate();\n\n\t\t\tvar uxPlus = (ButtonBase)Template.FindName(\"uxPlus\", this);\n\t\t\tvar uxMinus = (ButtonBase)Template.FindName(\"uxMinus\", this);\n\t\t\tvar uxReset = (ButtonBase)Template.FindName(\"uxReset\", this);\n\n\t\t\tif (uxPlus != null)\n\t\t\t\tuxPlus.Click += OnZoomInClick;\n\t\t\tif (uxMinus != null)\n\t\t\t\tuxMinus.Click += OnZoomOutClick;\n\t\t\tif (uxReset != null)\n\t\t\t\tuxReset.Click += OnResetClick;\n\t\t}\n\n\t\tconst double ZoomFactor = 1.1;\n\n\t\tvoid OnZoomInClick(object sender, EventArgs e)\n\t\t{\n\t\t\tSetCurrentValue(ValueProperty, ZoomScrollViewer.RoundToOneIfClose(this.Value * ZoomFactor));\n\t\t}\n\n\t\tvoid OnZoomOutClick(object sender, EventArgs e)\n\t\t{\n\t\t\tSetCurrentValue(ValueProperty, ZoomScrollViewer.RoundToOneIfClose(this.Value / ZoomFactor));\n\t\t}\n\n\t\tvoid OnResetClick(object sender, EventArgs e)\n\t\t{\n\t\t\tSetCurrentValue(ValueProperty, 1.0);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/ZoomScrollViewer.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Text;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Controls.Primitives;\nusing System.Windows.Data;\nusing System.Windows.Documents;\nusing System.Windows.Input;\nusing System.Windows.Media;\n\nnamespace ICSharpCode.ILSpy.Controls\n{\n\tpublic class ZoomScrollViewer : ScrollViewer\n\t{\n\t\tstatic ZoomScrollViewer()\n\t\t{\n\t\t\tDefaultStyleKeyProperty.OverrideMetadata(typeof(ZoomScrollViewer),\n\t\t\t\t\t\t\t\t\t\t\t\t\t new FrameworkPropertyMetadata(typeof(ZoomScrollViewer)));\n\t\t}\n\n\t\tpublic static readonly DependencyProperty CurrentZoomProperty =\n\t\t\tDependencyProperty.Register(\"CurrentZoom\", typeof(double), typeof(ZoomScrollViewer),\n\t\t\t\t\t\t\t\t\t\tnew FrameworkPropertyMetadata(1.0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, CalculateZoomButtonCollapsed, CoerceZoom));\n\n\t\tpublic double CurrentZoom {\n\t\t\tget { return (double)GetValue(CurrentZoomProperty); }\n\t\t\tset { SetValue(CurrentZoomProperty, value); }\n\t\t}\n\n\t\tstatic object CoerceZoom(DependencyObject d, object baseValue)\n\t\t{\n\t\t\tvar zoom = (double)baseValue;\n\t\t\tZoomScrollViewer sv = (ZoomScrollViewer)d;\n\t\t\treturn Math.Max(sv.MinimumZoom, Math.Min(sv.MaximumZoom, zoom));\n\t\t}\n\n\t\tpublic static readonly DependencyProperty MinimumZoomProperty =\n\t\t\tDependencyProperty.Register(\"MinimumZoom\", typeof(double), typeof(ZoomScrollViewer),\n\t\t\t\t\t\t\t\t\t\tnew FrameworkPropertyMetadata(0.2));\n\n\t\tpublic double MinimumZoom {\n\t\t\tget { return (double)GetValue(MinimumZoomProperty); }\n\t\t\tset { SetValue(MinimumZoomProperty, value); }\n\t\t}\n\n\t\tpublic static readonly DependencyProperty MaximumZoomProperty =\n\t\t\tDependencyProperty.Register(\"MaximumZoom\", typeof(double), typeof(ZoomScrollViewer),\n\t\t\t\t\t\t\t\t\t\tnew FrameworkPropertyMetadata(5.0));\n\n\t\tpublic double MaximumZoom {\n\t\t\tget { return (double)GetValue(MaximumZoomProperty); }\n\t\t\tset { SetValue(MaximumZoomProperty, value); }\n\t\t}\n\n\t\tpublic static readonly DependencyProperty MouseWheelZoomProperty =\n\t\t\tDependencyProperty.Register(\"MouseWheelZoom\", typeof(bool), typeof(ZoomScrollViewer),\n\t\t\t\t\t\t\t\t\t\tnew FrameworkPropertyMetadata(true));\n\n\t\tpublic bool MouseWheelZoom {\n\t\t\tget { return (bool)GetValue(MouseWheelZoomProperty); }\n\t\t\tset { SetValue(MouseWheelZoomProperty, value); }\n\t\t}\n\n\t\tpublic static readonly DependencyProperty AlwaysShowZoomButtonsProperty =\n\t\t\tDependencyProperty.Register(\"AlwaysShowZoomButtons\", typeof(bool), typeof(ZoomScrollViewer),\n\t\t\t\t\t\t\t\t\t\tnew FrameworkPropertyMetadata(false, CalculateZoomButtonCollapsed));\n\n\t\tpublic bool AlwaysShowZoomButtons {\n\t\t\tget { return (bool)GetValue(AlwaysShowZoomButtonsProperty); }\n\t\t\tset { SetValue(AlwaysShowZoomButtonsProperty, value); }\n\t\t}\n\n\t\tstatic readonly DependencyPropertyKey ComputedZoomButtonCollapsedPropertyKey =\n\t\t\tDependencyProperty.RegisterReadOnly(\"ComputedZoomButtonCollapsed\", typeof(bool), typeof(ZoomScrollViewer),\n\t\t\t\t\t\t\t\t\t\t\t\tnew FrameworkPropertyMetadata(true));\n\n\t\tpublic static readonly DependencyProperty ComputedZoomButtonCollapsedProperty = ComputedZoomButtonCollapsedPropertyKey.DependencyProperty;\n\n\t\tpublic bool ComputedZoomButtonCollapsed {\n\t\t\tget { return (bool)GetValue(ComputedZoomButtonCollapsedProperty); }\n\t\t\tprivate set { SetValue(ComputedZoomButtonCollapsedPropertyKey, value); }\n\t\t}\n\n\t\tstatic void CalculateZoomButtonCollapsed(DependencyObject d, DependencyPropertyChangedEventArgs e)\n\t\t{\n\t\t\tZoomScrollViewer z = d as ZoomScrollViewer;\n\t\t\tif (z != null)\n\t\t\t\tz.ComputedZoomButtonCollapsed = (z.AlwaysShowZoomButtons == false) && (z.CurrentZoom == 1.0);\n\t\t}\n\n\t\tprotected override void OnPreviewMouseWheel(MouseWheelEventArgs e)\n\t\t{\n\t\t\tif (!e.Handled && Keyboard.Modifiers == ModifierKeys.Control && MouseWheelZoom)\n\t\t\t{\n\t\t\t\tdouble oldZoom = CurrentZoom;\n\t\t\t\tdouble newZoom = RoundToOneIfClose(CurrentZoom * Math.Pow(1.001, e.Delta));\n\t\t\t\tnewZoom = Math.Max(this.MinimumZoom, Math.Min(this.MaximumZoom, newZoom));\n\n\t\t\t\t// adjust scroll position so that mouse stays over the same virtual coordinate\n\t\t\t\tContentPresenter presenter = Template.FindName(\"PART_Presenter\", this) as ContentPresenter;\n\t\t\t\tVector relMousePos;\n\t\t\t\tif (presenter != null)\n\t\t\t\t{\n\t\t\t\t\tPoint mousePos = e.GetPosition(presenter);\n\t\t\t\t\trelMousePos = new Vector(mousePos.X / presenter.ActualWidth, mousePos.Y / presenter.ActualHeight);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\trelMousePos = new Vector(0.5, 0.5);\n\t\t\t\t}\n\n\t\t\t\tPoint scrollOffset = new Point(this.HorizontalOffset, this.VerticalOffset);\n\t\t\t\tVector oldHalfViewport = new Vector(this.ViewportWidth / 2, this.ViewportHeight / 2);\n\t\t\t\tVector newHalfViewport = oldHalfViewport / newZoom * oldZoom;\n\t\t\t\tPoint oldCenter = scrollOffset + oldHalfViewport;\n\t\t\t\tPoint virtualMousePos = scrollOffset + new Vector(relMousePos.X * this.ViewportWidth, relMousePos.Y * this.ViewportHeight);\n\n\t\t\t\t// As newCenter, we want to choose a point between oldCenter and virtualMousePos. The more we zoom in, the closer\n\t\t\t\t// to virtualMousePos. We'll create the line x = oldCenter + lambda * (virtualMousePos-oldCenter).\n\t\t\t\t// On this line, we need to choose lambda between -1 and 1:\n\t\t\t\t// -1 = zoomed out completely\n\t\t\t\t//  0 = zoom unchanged\n\t\t\t\t// +1 = zoomed in completely\n\t\t\t\t// But the zoom factor (newZoom/oldZoom) we have is in the range [0,+Infinity].\n\n\t\t\t\t// Basically, I just played around until I found a function that maps this to [-1,1] and works well.\n\t\t\t\t// \"f\" is squared because otherwise the mouse simply stays over virtualMousePos, but I wanted virtualMousePos\n\t\t\t\t// to move towards the middle -> squaring f causes lambda to be closer to 1, giving virtualMousePos more weight\n\t\t\t\t// then oldCenter.\n\n\t\t\t\tdouble f = Math.Min(newZoom, oldZoom) / Math.Max(newZoom, oldZoom);\n\t\t\t\tdouble lambda = 1 - f * f;\n\t\t\t\tif (oldZoom > newZoom)\n\t\t\t\t\tlambda = -lambda;\n\n\t\t\t\tDebug.Print(\"old: \" + oldZoom + \", new: \" + newZoom);\n\n\t\t\t\tPoint newCenter = oldCenter + lambda * (virtualMousePos - oldCenter);\n\t\t\t\tscrollOffset = newCenter - newHalfViewport;\n\n\t\t\t\tSetCurrentValue(CurrentZoomProperty, newZoom);\n\n\t\t\t\tthis.ScrollToHorizontalOffset(scrollOffset.X);\n\t\t\t\tthis.ScrollToVerticalOffset(scrollOffset.Y);\n\n\t\t\t\te.Handled = true;\n\t\t\t}\n\t\t\tbase.OnPreviewMouseWheel(e);\n\t\t}\n\n\t\tinternal static double RoundToOneIfClose(double val)\n\t\t{\n\t\t\tif (Math.Abs(val - 1.0) < 0.001)\n\t\t\t\treturn 1.0;\n\t\t\telse\n\t\t\t\treturn val;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Controls/ZoomScrollViewer.xaml",
    "content": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n\txmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n\txmlns:Controls=\"clr-namespace:ICSharpCode.ILSpy.Controls\"\n\txmlns:toms=\"urn:TomsToolbox\"\n\txmlns:composition=\"urn:TomsToolbox.Composition\"\n\txmlns:util=\"clr-namespace:ICSharpCode.ILSpy.Util\">\n\t\n\t<Style TargetType=\"{x:Type Controls:ZoomScrollViewer}\">\n\t\t<Setter Property=\"toms:StyleBindings.Behaviors\">\n\t\t\t<Setter.Value>\n\t\t\t\t<toms:BehaviorCollection>\n\t\t\t\t\t<toms:AdvancedScrollWheelBehavior UseScrollingAnimation=\"{Binding Path=(util:SettingsService.DisplaySettings).EnableSmoothScrolling, Source={composition:Import util:SettingsService}}\"/>\n\t\t\t\t</toms:BehaviorCollection>\n\t\t\t</Setter.Value>\n\t\t</Setter>\n\t\t<Setter Property=\"Template\">\n\t\t\t<Setter.Value>\n\t\t\t\t<ControlTemplate TargetType=\"{x:Type Controls:ZoomScrollViewer}\">\n\t\t\t\t\t<Grid Background=\"{TemplateBinding Panel.Background}\">\n\t\t\t\t\t\t<Grid.ColumnDefinitions>\n\t\t\t\t\t\t\t<ColumnDefinition Width=\"Auto\" />\n\t\t\t\t\t\t\t<ColumnDefinition Width=\"*\" />\n\t\t\t\t\t\t\t<ColumnDefinition Width=\"Auto\" />\n\t\t\t\t\t\t</Grid.ColumnDefinitions>\n\t\t\t\t\t\t<Grid.RowDefinitions>\n\t\t\t\t\t\t\t<RowDefinition Height=\"*\" />\n\t\t\t\t\t\t\t<RowDefinition Height=\"Auto\" />\n\t\t\t\t\t\t</Grid.RowDefinitions>\n\t\t\t\t\t\t<Controls:SelfCollapsingPanel Grid.Column=\"0\" Grid.Row=\"1\" CollapseOrientation=\"Horizontal\" CanCollapse=\"{Binding Path=ComputedZoomButtonCollapsed, Mode=OneWay, RelativeSource={RelativeSource Mode=TemplatedParent}}\">\n\t\t\t\t\t\t\t<Controls:ZoomButtons x:Name=\"zoomButtons\" Value=\"{Binding Path=CurrentZoom, RelativeSource={RelativeSource Mode=TemplatedParent}}\" Minimum=\"{TemplateBinding MinimumZoom}\" Maximum=\"{TemplateBinding MaximumZoom}\" />\n\t\t\t\t\t\t</Controls:SelfCollapsingPanel>\n\t\t\t\t\t\t<Rectangle Grid.Column=\"2\" Grid.Row=\"1\" Fill=\"{DynamicResource {x:Static SystemColors.ControlBrushKey}}\" />\n\t\t\t\t\t\t<ScrollContentPresenter Name=\"PART_Presenter\" Grid.Column=\"0\" Grid.ColumnSpan=\"2\" Grid.Row=\"0\" Margin=\"{TemplateBinding Control.Padding}\" Content=\"{TemplateBinding ContentControl.Content}\" ContentTemplate=\"{TemplateBinding ContentControl.ContentTemplate}\" CanContentScroll=\"{TemplateBinding ScrollViewer.CanContentScroll}\">\n\t\t\t\t\t\t\t<ScrollContentPresenter.LayoutTransform>\n\t\t\t\t\t\t\t\t<ScaleTransform ScaleX=\"{Binding Path=CurrentZoom, RelativeSource={RelativeSource Mode=TemplatedParent}}\" ScaleY=\"{Binding Path=CurrentZoom, RelativeSource={RelativeSource Mode=TemplatedParent}}\"/>\n\t\t\t\t\t\t\t</ScrollContentPresenter.LayoutTransform>\n\t\t\t\t\t\t</ScrollContentPresenter>\n\t\t\t\t\t\t<ScrollBar Name=\"PART_VerticalScrollBar\" Grid.Column=\"2\" Grid.Row=\"0\" Minimum=\"0\" Maximum=\"{TemplateBinding ScrollableHeight}\" ViewportSize=\"{TemplateBinding ViewportHeight}\" Value=\"{TemplateBinding VerticalOffset}\" Visibility=\"{TemplateBinding ComputedVerticalScrollBarVisibility}\" />\n\t\t\t\t\t\t<ScrollBar Name=\"PART_HorizontalScrollBar\" Orientation=\"Horizontal\" Grid.Column=\"1\" Grid.Row=\"1\" Minimum=\"0\" Maximum=\"{TemplateBinding ScrollableWidth}\" ViewportSize=\"{TemplateBinding ViewportWidth}\" Value=\"{TemplateBinding HorizontalOffset}\" Visibility=\"{TemplateBinding ComputedHorizontalScrollBarVisibility}\" />\n\t\t\t\t\t</Grid>\n\t\t\t\t</ControlTemplate>\n\t\t\t</Setter.Value>\n\t\t</Setter>\n\t</Style>\n\n\t<!-- Template for CollapsiblePanel -->\n\t<Style TargetType=\"{x:Type Controls:CollapsiblePanel}\">\n\t\t<Setter Property=\"Template\">\n\t\t\t<Setter.Value>\n\t\t\t\t<ControlTemplate TargetType=\"Controls:CollapsiblePanel\">\n\t\t\t\t\t<ControlTemplate.Resources>\n\t\t\t\t\t\t<Controls:CollapsiblePanelProgressToVisibilityConverter x:Key=\"visibilityConverter\"/>\n\t\t\t\t\t</ControlTemplate.Resources>\n\t\t\t\t\t<Border\n\t\t\t\t\t\tBorderThickness=\"{TemplateBinding Border.BorderThickness}\"\n\t\t\t\t\t\tBorderBrush=\"{TemplateBinding Border.BorderBrush}\"\n\t\t\t\t\t\tBackground=\"{TemplateBinding Panel.Background}\"\n\t\t\t\t\t\tSnapsToDevicePixels=\"{TemplateBinding UIElement.SnapsToDevicePixels}\"\n\t\t\t\t\t\tName=\"PART_Border\"\n\t\t\t\t\t\tVisibility=\"{Binding RelativeSource={RelativeSource TemplatedParent}, Path=AnimationProgress, Converter={StaticResource visibilityConverter}}\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<Border.LayoutTransform>\n\t\t\t\t\t\t\t<ScaleTransform ScaleX=\"{Binding RelativeSource={RelativeSource TemplatedParent}, Path=AnimationProgressX}\"\n\t\t\t\t\t\t\t                ScaleY=\"{Binding RelativeSource={RelativeSource TemplatedParent}, Path=AnimationProgressY}\"/>\n\t\t\t\t\t\t</Border.LayoutTransform>\n\t\t\t\t\t\t<ContentPresenter\n\t\t\t\t\t\t\tMargin=\"{TemplateBinding Control.Padding}\"\n\t\t\t\t\t\t\tContent=\"{TemplateBinding ContentControl.Content}\"\n\t\t\t\t\t\t\tContentTemplate=\"{TemplateBinding ContentControl.ContentTemplate}\"\n\t\t\t\t\t\t\tContentStringFormat=\"{TemplateBinding ContentControl.ContentStringFormat}\"\n\t\t\t\t\t\t\tHorizontalAlignment=\"{TemplateBinding Control.HorizontalContentAlignment}\"\n\t\t\t\t\t\t\tVerticalAlignment=\"{TemplateBinding Control.VerticalContentAlignment}\"\n\t\t\t\t\t\t\tSnapsToDevicePixels=\"{TemplateBinding UIElement.SnapsToDevicePixels}\" />\n\t\t\t\t\t</Border>\n\t\t\t\t</ControlTemplate>\n\t\t\t</Setter.Value>\n\t\t</Setter>\n\t</Style>\n\n\t<Style x:Key=\"ZoomButtonStyle\"\n\t       TargetType=\"RepeatButton\">\n\t\t<Setter Property=\"Delay\" Value=\"0\" />\n\t\t<Setter Property=\"Focusable\" Value=\"False\" />\n\t\t<Setter Property=\"Opacity\" Value=\"0.5\" />\n\t\t<Setter Property=\"Template\">\n\t\t\t<Setter.Value>\n\t\t\t\t<ControlTemplate TargetType=\"RepeatButton\">\n\t\t\t\t\t<ContentPresenter />\n\t\t\t\t\t<ControlTemplate.Triggers>\n\t\t\t\t\t\t<Trigger Property=\"IsMouseOver\" Value=\"True\">\n\t\t\t\t\t\t\t<Setter Property=\"Opacity\" Value=\"1\" />\n\t\t\t\t\t\t</Trigger>\n\t\t\t\t\t</ControlTemplate.Triggers>\n\t\t\t\t</ControlTemplate>\n\t\t\t</Setter.Value>\n\t\t</Setter>\n\t</Style>\n\t\n\t<Style TargetType=\"{x:Type Controls:ZoomButtons}\">\n\t\t<Setter Property=\"Minimum\" Value=\"0.2\"/>\n\t\t<Setter Property=\"Maximum\" Value=\"10\"/>\n\t\t<Setter Property=\"Value\" Value=\"1\"/>\n\t\t<Setter Property=\"Template\">\n\t\t\t<Setter.Value>\n\t\t\t\t<ControlTemplate TargetType=\"{x:Type Controls:ZoomButtons}\">\n\t\t\t\t\t<Border Background=\"{TemplateBinding Background}\"\n\t\t\t\t\t        BorderBrush=\"{TemplateBinding BorderBrush}\"\n\t\t\t\t\t        BorderThickness=\"{TemplateBinding BorderThickness}\">\n\t\t\t\t\t\t<StackPanel Orientation=\"Horizontal\"\n\t\t\t\t\t\t            Background=\"#3000\">\n\t\t\t\t\t\t\t<RepeatButton x:Name=\"uxPlus\"\n\t\t\t\t\t\t\t              Width=\"16\" Height=\"16\" Padding=\"0\" BorderThickness=\"0\"\n\t\t\t\t\t\t\t              Style=\"{StaticResource ZoomButtonStyle}\">\n\t\t\t\t\t\t\t\t<Image Source=\"{Controls:XamlResource Images/ZoomIn}\"\n\t\t\t\t\t\t\t\t       Stretch=\"Uniform\"/>\n\t\t\t\t\t\t\t</RepeatButton>\n\t\t\t\t\t\t\t<RepeatButton x:Name=\"uxMinus\"\n\t\t\t\t\t\t\t              Width=\"16\" Height=\"16\" Padding=\"0\" BorderThickness=\"0\"\n\t\t\t\t\t\t\t              Style=\"{StaticResource ZoomButtonStyle}\">\n\t\t\t\t\t\t\t\t<Image Source=\"{Controls:XamlResource Images/ZoomOut}\"\n\t\t\t\t\t\t\t\t       Stretch=\"Uniform\" />\n\t\t\t\t\t\t\t</RepeatButton>\n\t\t\t\t\t\t\t<RepeatButton x:Name=\"uxReset\"\n\t\t\t\t\t\t\t              Width=\"16\" Height=\"16\" Padding=\"0\" BorderThickness=\"0\"\n\t\t\t\t\t\t\t              Style=\"{StaticResource ZoomButtonStyle}\">\n\t\t\t\t\t\t\t\t<Border Background=\"#5000\">\n\t\t\t\t\t\t\t\t\t<TextBlock Foreground=\"White\"\n\t\t\t\t\t\t\t\t\t           HorizontalAlignment=\"Center\"\n\t\t\t\t\t\t\t\t\t           VerticalAlignment=\"Center\">1</TextBlock>\n\t\t\t\t\t\t\t\t</Border>\n\t\t\t\t\t\t\t</RepeatButton>\n\t\t\t\t\t\t</StackPanel>\n\t\t\t\t\t</Border>\n\t\t\t\t</ControlTemplate>\n\t\t\t</Setter.Value>\n\t\t</Setter>\n\t</Style>\n</ResourceDictionary>"
  },
  {
    "path": "ILSpy/DecompilationOptions.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.ILSpy.Options;\nusing ICSharpCode.ILSpyX;\n\nusing DecompilerSettings = ICSharpCode.ILSpyX.Settings.DecompilerSettings;\n\nnamespace ICSharpCode.ILSpy\n{\n\t/// <summary>\n\t/// Options passed to the decompiler.\n\t/// </summary>\n\tpublic class DecompilationOptions\n\t{\n\t\t/// <summary>\n\t\t/// Gets whether a full decompilation (all members recursively) is desired.\n\t\t/// If this option is false, language bindings are allowed to show the only headers of the decompiled element's children.\n\t\t/// </summary>\n\t\tpublic bool FullDecompilation { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the directory into which the project is saved.\n\t\t/// </summary>\n\t\tpublic string SaveAsProjectDirectory { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets/sets whether invalid identifiers should be escaped (and therefore the code be made compilable).\n\t\t/// This setting is ignored in case <see cref=\"SaveAsProjectDirectory\"/> is set.\n\t\t/// </summary>\n\t\tpublic bool EscapeInvalidIdentifiers { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets the cancellation token that is used to abort the decompiler.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Decompilers should regularly call <c>options.CancellationToken.ThrowIfCancellationRequested();</c>\n\t\t/// to allow for cooperative cancellation of the decompilation task.\n\t\t/// </remarks>\n\t\tpublic CancellationToken CancellationToken { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets the progress reporter.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// If decompilers do not implement progress reporting, an indeterminate wait bar is displayed.\n\t\t/// </remarks>\n\t\tpublic IProgress<DecompilationProgress> Progress { get; set; }\n\n\t\t/// <summary>\n\t\t/// Gets the settings for the decompiler.\n\t\t/// </summary>\n\t\tpublic DecompilerSettings DecompilerSettings { get; private set; }\n\n\t\t/// <summary>\n\t\t/// Gets/sets an optional state of a decompiler text view.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// This state is used to restore test view's state when decompilation is started by Go Back/Forward action.\n\t\t/// </remarks>\n\t\tpublic TextView.DecompilerTextViewState TextViewState { get; set; }\n\n\t\t/// <summary>\n\t\t/// Used internally for debugging.\n\t\t/// </summary>\n\t\tinternal int StepLimit = int.MaxValue;\n\t\tinternal bool IsDebug = false;\n\n\t\tpublic DecompilationOptions(LanguageVersion version, DecompilerSettings settings, DisplaySettings displaySettings)\n\t\t{\n\t\t\tif (!Enum.TryParse(version?.Version, out Decompiler.CSharp.LanguageVersion languageVersion))\n\t\t\t\tlanguageVersion = Decompiler.CSharp.LanguageVersion.Latest;\n\n\t\t\tvar newSettings = this.DecompilerSettings = settings.Clone();\n\n\t\t\tnewSettings.SetLanguageVersion(languageVersion);\n\t\t\tnewSettings.ExpandMemberDefinitions = displaySettings.ExpandMemberDefinitions;\n\t\t\tnewSettings.ExpandUsingDeclarations = displaySettings.ExpandUsingDeclarations;\n\t\t\tnewSettings.FoldBraces = displaySettings.FoldBraces;\n\t\t\tnewSettings.ShowDebugInfo = displaySettings.ShowDebugInfo;\n\t\t\tnewSettings.CSharpFormattingOptions.IndentationString = GetIndentationString(displaySettings);\n\t\t}\n\n\t\tprivate string GetIndentationString(DisplaySettings displaySettings)\n\t\t{\n\t\t\tif (displaySettings.IndentationUseTabs)\n\t\t\t{\n\t\t\t\tint numberOfTabs = displaySettings.IndentationSize / displaySettings.IndentationTabSize;\n\t\t\t\tint numberOfSpaces = displaySettings.IndentationSize % displaySettings.IndentationTabSize;\n\t\t\t\treturn new string('\\t', numberOfTabs) + new string(' ', numberOfSpaces);\n\t\t\t}\n\t\t\treturn new string(' ', displaySettings.IndentationSize);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Docking/CloseAllDocumentsCommand.cs",
    "content": "using System.Composition;\n\nusing ICSharpCode.ILSpy.Properties;\n\nnamespace ICSharpCode.ILSpy.Docking\n{\n\t[ExportMainMenuCommand(Header = nameof(Resources.Window_CloseAllDocuments), ParentMenuID = nameof(Resources._Window))]\n\t[Shared]\n\tclass CloseAllDocumentsCommand(DockWorkspace dockWorkspace) : SimpleCommand\n\t{\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tdockWorkspace.CloseAllTabs();\n\t\t}\n\t}\n\n\t[ExportMainMenuCommand(Header = nameof(Resources.Window_ResetLayout), ParentMenuID = nameof(Resources._Window))]\n\t[Shared]\n\tclass ResetLayoutCommand(DockWorkspace dockWorkspace) : SimpleCommand\n\t{\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tdockWorkspace.ResetLayout();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Docking/DockLayoutSettings.cs",
    "content": "// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\nusing System.Linq;\nusing System.Xml.Linq;\n\nusing AvalonDock.Layout.Serialization;\n\nnamespace ICSharpCode.ILSpy.Docking\n{\n\tpublic class DockLayoutSettings\n\t{\n\t\t/// <remarks>NOTE: do NOT remove any of the (empty) sections, the deserializer is not very resilient and expects this exact order of elements!</remarks>\n\t\tprivate const string DefaultLayout = @\"\n<LayoutRoot>\n\t<RootPanel Orientation=\"\"Horizontal\"\">\n\t\t<LayoutAnchorablePaneGroup Orientation=\"\"Horizontal\"\" DockWidth=\"\"300\"\">\n\t\t\t<LayoutAnchorablePane>\n\t\t\t\t<LayoutAnchorable ContentId=\"\"assemblyListPane\"\" />\n\t\t\t</LayoutAnchorablePane>\n\t\t</LayoutAnchorablePaneGroup>\n\t\t<LayoutPanel Orientation=\"\"Vertical\"\">\n\t\t\t<LayoutAnchorablePaneGroup Orientation=\"\"Horizontal\"\" DockHeight=\"\"225\"\">\n\t\t\t\t<LayoutAnchorablePane Id=\"\"3ce12a2b-e6be-47cd-9787-fbf74bb9f157\"\" />\n\t\t\t</LayoutAnchorablePaneGroup>\n\t\t\t<LayoutDocumentPane />\n\t\t\t<LayoutAnchorablePaneGroup Orientation=\"\"Horizontal\"\" DockHeight=\"\"225\"\">\n\t\t\t\t<LayoutAnchorablePane Id=\"\"8858bc50-019a-480e-b402-30a890e7c68f\"\" />\n\t\t\t</LayoutAnchorablePaneGroup>\n\t\t</LayoutPanel>\n\t</RootPanel>\n\t<TopSide />\n\t<RightSide />\n\t<LeftSide />\n\t<BottomSide />\n\t<FloatingWindows />\n\t<Hidden>\n\t\t<LayoutAnchorable ContentId=\"\"debugStepsPane\"\" PreviousContainerId=\"\"3ce12a2b-e6be-47cd-9787-fbf74bb9f157\"\" PreviousContainerIndex=\"\"0\"\" />\n\t\t<LayoutAnchorable ContentId=\"\"searchPane\"\" PreviousContainerId=\"\"3ce12a2b-e6be-47cd-9787-fbf74bb9f157\"\" PreviousContainerIndex=\"\"0\"\" />\n\t\t<LayoutAnchorable ContentId=\"\"analyzerPane\"\" PreviousContainerId=\"\"8858bc50-019a-480e-b402-30a890e7c68f\"\" PreviousContainerIndex=\"\"0\"\" />\n\t</Hidden>\n</LayoutRoot>\n\";\n\n\t\tprivate string rawSettings;\n\n\t\tpublic bool Valid => rawSettings != null;\n\n\t\tpublic void Reset()\n\t\t{\n\t\t\tthis.rawSettings = DefaultLayout;\n\t\t}\n\n\t\tpublic DockLayoutSettings(XElement element)\n\t\t{\n\t\t\tif ((element != null) && element.HasElements)\n\t\t\t{\n\t\t\t\trawSettings = element.Elements().FirstOrDefault()?.ToString();\n\t\t\t}\n\t\t}\n\n\t\tpublic XElement SaveAsXml()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn XElement.Parse(rawSettings);\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tpublic void Deserialize(XmlLayoutSerializer serializer)\n\t\t{\n\t\t\tif (!Valid)\n\t\t\t\trawSettings = DefaultLayout;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tDeserialize(rawSettings);\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\tDeserialize(DefaultLayout);\n\t\t\t}\n\n\t\t\tvoid Deserialize(string settings)\n\t\t\t{\n\t\t\t\tusing (StringReader reader = new StringReader(settings))\n\t\t\t\t{\n\t\t\t\t\tserializer.Deserialize(reader);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic void Serialize(XmlLayoutSerializer serializer)\n\t\t{\n\t\t\tusing (StringWriter fs = new StringWriter())\n\t\t\t{\n\t\t\t\tserializer.Serialize(fs);\n\t\t\t\trawSettings = fs.ToString();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Docking/DockWorkspace.cs",
    "content": "// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Collections.Specialized;\nusing System.Composition;\nusing System.Linq;\nusing System.Reflection;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Windows.Data;\nusing System.Windows.Threading;\n\nusing AvalonDock;\nusing AvalonDock.Layout;\nusing AvalonDock.Layout.Serialization;\n\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.ILSpy.Analyzers;\nusing ICSharpCode.ILSpy.Search;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.ViewModels;\n\nusing TomsToolbox.Composition;\nusing TomsToolbox.Essentials;\nusing TomsToolbox.Wpf;\n\nnamespace ICSharpCode.ILSpy.Docking\n{\n\t[Export]\n\t[Shared]\n\tpublic class DockWorkspace : ObservableObjectBase, ILayoutUpdateStrategy\n\t{\n\t\tprivate readonly IExportProvider exportProvider;\n\n\t\tprivate readonly ObservableCollection<TabPageModel> tabPages = [];\n\t\tprivate ReadOnlyCollection<ToolPaneModel> toolPanes;\n\n\t\treadonly SessionSettings sessionSettings;\n\n\t\tprivate DockingManager DockingManager => exportProvider.GetExportedValue<DockingManager>();\n\n\t\tpublic DockWorkspace(SettingsService settingsService, IExportProvider exportProvider)\n\t\t{\n\t\t\tthis.exportProvider = exportProvider;\n\n\t\t\tsessionSettings = settingsService.SessionSettings;\n\n\t\t\tthis.tabPages.CollectionChanged += TabPages_CollectionChanged;\n\t\t\tTabPages = new(tabPages);\n\n\t\t\tMessageBus<CurrentAssemblyListChangedEventArgs>.Subscribers += (sender, e) => CurrentAssemblyList_Changed(sender, e);\n\t\t}\n\n\t\tprivate void CurrentAssemblyList_Changed(object sender, NotifyCollectionChangedEventArgs e)\n\t\t{\n\t\t\tif (e.OldItems is not { } oldItems)\n\t\t\t\treturn;\n\n\t\t\tforeach (var tab in tabPages.ToArray())\n\t\t\t{\n\t\t\t\tvar state = tab.GetState();\n\t\t\t\tvar decompiledNodes = state?.DecompiledNodes;\n\t\t\t\tif (decompiledNodes == null)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tbool found = decompiledNodes\n\t\t\t\t\t.Select(node => node.Ancestors().OfType<TreeNodes.AssemblyTreeNode>().LastOrDefault())\n\t\t\t\t\t.ExceptNullItems()\n\t\t\t\t\t.Any(assemblyNode => !oldItems.Contains(assemblyNode.LoadedAssembly));\n\n\t\t\t\tif (!found)\n\t\t\t\t{\n\t\t\t\t\ttabPages.Remove(tab);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (tabPages.Count == 0)\n\t\t\t{\n\t\t\t\tAddTabPage();\n\t\t\t}\n\t\t}\n\n\t\tprivate void TabPages_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)\n\t\t{\n\t\t\tif (e.Action == NotifyCollectionChangedAction.Add)\n\t\t\t{\n\t\t\t\tif (e.NewItems?[0] is TabPageModel model)\n\t\t\t\t{\n\t\t\t\t\tActiveTabPage = model;\n\t\t\t\t\tmodel.IsActive = true;\n\t\t\t\t\tmodel.IsVisible = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbool canClose = tabPages.Count > 1;\n\n\t\t\tforeach (var item in tabPages)\n\t\t\t{\n\t\t\t\titem.IsCloseable = canClose;\n\t\t\t}\n\n\t\t\tMessageBus.Send(this, new TabPagesCollectionChangedEventArgs(e));\n\t\t}\n\n\t\tpublic TabPageModel AddTabPage(TabPageModel tabPage = null)\n\t\t{\n\t\t\tTabPageModel item = tabPage ?? exportProvider.GetExportedValue<TabPageModel>();\n\t\t\ttabPages.Add(item);\n\t\t\treturn item;\n\t\t}\n\n\t\tpublic ReadOnlyObservableCollection<TabPageModel> TabPages { get; }\n\n\t\tpublic ReadOnlyCollection<ToolPaneModel> ToolPanes => toolPanes ??= exportProvider\n\t\t\t.GetExportedValues<ToolPaneModel>(\"ToolPane\")\n\t\t\t.OrderBy(item => item.Title)\n\t\t\t.ToArray()\n\t\t\t.AsReadOnly();\n\n\t\tpublic bool ShowToolPane(string contentId)\n\t\t{\n\t\t\tvar pane = ToolPanes.FirstOrDefault(p => p.ContentId == contentId);\n\t\t\tif (pane != null)\n\t\t\t{\n\t\t\t\tpane.Show();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic void Remove(PaneModel model)\n\t\t{\n\t\t\tswitch (model)\n\t\t\t{\n\t\t\t\tcase TabPageModel document:\n\t\t\t\t\ttabPages.Remove(document);\n\t\t\t\t\tbreak;\n\t\t\t\tcase ToolPaneModel tool:\n\t\t\t\t\ttool.IsVisible = false;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tprivate TabPageModel activeTabPage = null;\n\t\tpublic TabPageModel ActiveTabPage {\n\t\t\tget {\n\t\t\t\treturn activeTabPage;\n\t\t\t}\n\t\t\tset {\n\t\t\t\tif (!SetProperty(ref activeTabPage, value))\n\t\t\t\t\treturn;\n\n\t\t\t\tvar state = value?.GetState();\n\t\t\t\tif (state == null)\n\t\t\t\t\treturn;\n\n\t\t\t\tMessageBus.Send(this, new ActiveTabPageChangedEventArgs(value?.GetState()));\n\t\t\t}\n\t\t}\n\n\t\tpublic PaneModel ActivePane {\n\t\t\tget => DockingManager.ActiveContent as PaneModel;\n\t\t\tset => DockingManager.ActiveContent = value;\n\t\t}\n\n\t\tpublic void InitializeLayout()\n\t\t{\n\t\t\tif (tabPages.Count == 0)\n\t\t\t{\n\t\t\t\t// Make sure there is at least one tab open\n\t\t\t\tAddTabPage();\n\t\t\t}\n\n\t\t\tDockingManager.LayoutUpdateStrategy = this;\n\t\t\tXmlLayoutSerializer serializer = new XmlLayoutSerializer(DockingManager);\n\t\t\tserializer.LayoutSerializationCallback += LayoutSerializationCallback;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tsessionSettings.DockLayout.Deserialize(serializer);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tserializer.LayoutSerializationCallback -= LayoutSerializationCallback;\n\t\t\t}\n\n\t\t\tDockingManager.SetBinding(DockingManager.AnchorablesSourceProperty, new Binding(nameof(ToolPanes)));\n\t\t\tDockingManager.SetBinding(DockingManager.DocumentsSourceProperty, new Binding(nameof(TabPages)));\n\t\t}\n\n\t\tvoid LayoutSerializationCallback(object sender, LayoutSerializationCallbackEventArgs e)\n\t\t{\n\t\t\tswitch (e.Model)\n\t\t\t{\n\t\t\t\tcase LayoutAnchorable la:\n\t\t\t\t\te.Content = this.ToolPanes.FirstOrDefault(p => p.ContentId == la.ContentId);\n\t\t\t\t\te.Cancel = e.Content == null;\n\t\t\t\t\tla.CanDockAsTabbedDocument = false;\n\t\t\t\t\tif (e.Content is ToolPaneModel toolPaneModel)\n\t\t\t\t\t{\n\t\t\t\t\t\te.Cancel = toolPaneModel.IsVisible;\n\t\t\t\t\t\ttoolPaneModel.IsVisible = true;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\te.Cancel = true;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic void ShowText(AvalonEditTextOutput textOutput)\n\t\t{\n\t\t\tActiveTabPage.ShowTextView(textView => textView.ShowText(textOutput));\n\t\t}\n\n\t\tpublic Task<T> RunWithCancellation<T>(Func<CancellationToken, Task<T>> taskCreation)\n\t\t{\n\t\t\treturn ActiveTabPage.ShowTextViewAsync(textView => textView.RunWithCancellation(taskCreation));\n\t\t}\n\n\t\tpublic Task<T> RunWithCancellation<T>(Func<CancellationToken, Task<T>> taskCreation, string progressTitle)\n\t\t{\n\t\t\treturn ActiveTabPage.ShowTextViewAsync(textView => textView.RunWithCancellation(taskCreation, progressTitle));\n\t\t}\n\n\t\tinternal void ShowNodes(AvalonEditTextOutput output, TreeNodes.ILSpyTreeNode[] nodes, IHighlightingDefinition highlighting)\n\t\t{\n\t\t\tActiveTabPage.ShowTextView(textView => textView.ShowNodes(output, nodes, highlighting));\n\t\t}\n\n\t\tinternal void CloseAllTabs()\n\t\t{\n\t\t\tvar activePage = ActiveTabPage;\n\n\t\t\ttabPages.RemoveWhere(page => page != activePage);\n\t\t}\n\n\t\tinternal void ResetLayout()\n\t\t{\n\t\t\tforeach (var pane in ToolPanes)\n\t\t\t{\n\t\t\t\tpane.IsVisible = false;\n\t\t\t}\n\t\t\tCloseAllTabs();\n\t\t\tsessionSettings.DockLayout.Reset();\n\t\t\tInitializeLayout();\n\n\t\t\tApp.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, () => MessageBus.Send(this, new ResetLayoutEventArgs()));\n\t\t}\n\n\t\tstatic readonly PropertyInfo previousContainerProperty = typeof(LayoutContent).GetProperty(\"PreviousContainer\", BindingFlags.NonPublic | BindingFlags.Instance);\n\n\t\tpublic bool BeforeInsertAnchorable(LayoutRoot layout, LayoutAnchorable anchorableToShow, ILayoutContainer destinationContainer)\n\t\t{\n\t\t\tif (!(anchorableToShow.Content is LegacyToolPaneModel legacyContent))\n\t\t\t\treturn false;\n\t\t\tanchorableToShow.CanDockAsTabbedDocument = false;\n\n\t\t\tLayoutAnchorablePane previousContainer;\n\t\t\tswitch (legacyContent.Location)\n\t\t\t{\n\t\t\t\tcase LegacyToolPaneLocation.Top:\n\t\t\t\t\tpreviousContainer = GetContainer<SearchPaneModel>();\n\t\t\t\t\tpreviousContainer.Children.Add(anchorableToShow);\n\t\t\t\t\treturn true;\n\t\t\t\tcase LegacyToolPaneLocation.Bottom:\n\t\t\t\t\tpreviousContainer = GetContainer<AnalyzerTreeViewModel>();\n\t\t\t\t\tpreviousContainer.Children.Add(anchorableToShow);\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tLayoutAnchorablePane GetContainer<T>()\n\t\t\t{\n\t\t\t\tvar anchorable = layout.Descendents().OfType<LayoutAnchorable>().FirstOrDefault(x => x.Content is T)\n\t\t\t\t\t?? layout.Hidden.First(x => x.Content is T);\n\t\t\t\treturn (LayoutAnchorablePane)previousContainerProperty.GetValue(anchorable) ?? (LayoutAnchorablePane)anchorable.Parent;\n\t\t\t}\n\t\t}\n\n\t\tpublic void AfterInsertAnchorable(LayoutRoot layout, LayoutAnchorable anchorableShown)\n\t\t{\n\t\t\tanchorableShown.IsActive = true;\n\t\t\tanchorableShown.IsSelected = true;\n\t\t}\n\n\t\tpublic bool BeforeInsertDocument(LayoutRoot layout, LayoutDocument anchorableToShow, ILayoutContainer destinationContainer)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic void AfterInsertDocument(LayoutRoot layout, LayoutDocument anchorableShown)\n\t\t{\n\t\t}\n\n\t\t// Dummy property to make the XAML designer happy, the model is provided by the AvalonDock PaneStyleSelectors, not by the DockWorkspace, but the designer assumes the data context in the PaneStyleSelectors is the DockWorkspace.\n\t\tpublic PaneModel Model { get; } = null;\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Docking/PaneStyleSelector.cs",
    "content": "using System.Windows;\nusing System.Windows.Controls;\n\nusing ICSharpCode.ILSpy.ViewModels;\n// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.ILSpy.Docking\n{\n\tpublic class PaneStyleSelector : StyleSelector\n\t{\n\t\tpublic Style ToolPaneStyle { get; set; }\n\n\t\tpublic Style TabPageStyle { get; set; }\n\n\t\tpublic override Style SelectStyle(object item, DependencyObject container)\n\t\t{\n\t\t\tif (item is TabPageModel)\n\t\t\t\treturn TabPageStyle;\n\n\t\t\tif (item is ToolPaneModel)\n\t\t\t\treturn ToolPaneStyle;\n\n\t\t\treturn base.SelectStyle(item, container);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Docking/TabPageGuardConverter.cs",
    "content": "// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Windows.Data;\n\nusing ICSharpCode.ILSpy.ViewModels;\n\nusing TomsToolbox.Wpf.Converters;\n\nnamespace ICSharpCode.ILSpy.Docking\n{\n\tpublic class TabPageGuardConverter : ValueConverter\n\t{\n\t\tprotected override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)\n\t\t{\n\t\t\treturn value is TabPageModel ? value : Binding.DoNothing;\n\t\t}\n\n\t\tprotected override object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)\n\t\t{\n\t\t\treturn value is TabPageModel ? value : Binding.DoNothing;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/EntityReference.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n#nullable enable\n\nusing System.Diagnostics;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpyX;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[DebuggerDisplay(\"EntityReference Module={Module}, Handle={Handle}, Protocol={Protocol}\")]\n\tpublic class EntityReference\n\t{\n\t\treadonly MetadataFile? peFile;\n\t\tpublic string Module { get; }\n\t\tpublic Handle Handle { get; }\n\t\tpublic string Protocol { get; }\n\n\t\tpublic EntityReference(string moduleFileName, Handle handle)\n\t\t{\n\t\t\tthis.Module = moduleFileName;\n\t\t\tthis.Handle = handle;\n\t\t\tthis.Protocol = \"decompile\";\n\t\t}\n\n\t\tpublic EntityReference(string? protocol, string moduleFileName, Handle handle)\n\t\t\t: this(moduleFileName, handle)\n\t\t{\n\t\t\tthis.Protocol = protocol ?? \"decompile\";\n\t\t}\n\n\t\tpublic EntityReference(MetadataFile module, Handle handle, string protocol = \"decompile\")\n\t\t{\n\t\t\tthis.peFile = module;\n\t\t\tthis.Module = module.FileName;\n\t\t\tthis.Handle = handle;\n\t\t\tthis.Protocol = protocol;\n\t\t}\n\n\t\tpublic MetadataFile? ResolveAssembly(AssemblyList context)\n\t\t{\n\t\t\treturn peFile ?? context.FindAssembly(Module)?.GetMetadataFileOrNull();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/ExtensionMethods.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Media;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX;\n\nusing TomsToolbox.Essentials;\n\nnamespace ICSharpCode.ILSpy\n{\n\t/// <summary>\n\t/// ExtensionMethods used in ILSpy.\n\t/// </summary>\n\tpublic static class ExtensionMethods\n\t{\n\t\tpublic static string ToSuffixString(this System.Reflection.Metadata.EntityHandle handle, bool showMetadataTokens, bool useBase10)\n\t\t{\n\t\t\tif (!showMetadataTokens)\n\t\t\t\treturn string.Empty;\n\n\t\t\tint token = System.Reflection.Metadata.Ecma335.MetadataTokens.GetToken(handle);\n\t\t\tif (useBase10)\n\t\t\t\treturn \" @\" + token;\n\t\t\treturn \" @\" + token.ToString(\"x8\");\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Takes at most <paramref name=\"length\" /> first characters from string, and appends '...' if string is longer.\n\t\t/// String can be null.\n\t\t/// </summary>\n\t\tpublic static string TakeStartEllipsis(this string s, int length)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(s) || length >= s.Length)\n\t\t\t\treturn s;\n\t\t\treturn s.Substring(0, length) + \"...\";\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Equivalent to <code>collection.Select(func).ToArray()</code>, but more efficient as it makes\n\t\t/// use of the input collection's known size.\n\t\t/// </summary>\n\t\tpublic static U[] SelectArray<T, U>(this ICollection<T> collection, Func<T, U> func)\n\t\t{\n\t\t\tU[] result = new U[collection.Count];\n\t\t\tint index = 0;\n\t\t\tforeach (var element in collection)\n\t\t\t{\n\t\t\t\tresult[index++] = func(element);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic static ICompilation? GetTypeSystemWithCurrentOptionsOrNull(this MetadataFile file, SettingsService settingsService, LanguageVersion languageVersion)\n\t\t{\n\t\t\tvar decompilerSettings = settingsService.DecompilerSettings.Clone();\n\t\t\tif (!Enum.TryParse(languageVersion?.Version, out Decompiler.CSharp.LanguageVersion csharpLanguageVersion))\n\t\t\t\tcsharpLanguageVersion = Decompiler.CSharp.LanguageVersion.Latest;\n\t\t\tdecompilerSettings.SetLanguageVersion(csharpLanguageVersion);\n\t\t\treturn file\n\t\t\t\t.GetLoadedAssembly()\n\t\t\t\t.GetTypeSystemOrNull(DecompilerTypeSystem.GetOptions(decompilerSettings));\n\t\t}\n\n\t\t#region DPI independence\n\t\tpublic static Rect TransformToDevice(this Rect rect, Visual visual)\n\t\t{\n\t\t\tMatrix matrix = PresentationSource.FromVisual(visual).CompositionTarget.TransformToDevice;\n\t\t\treturn Rect.Transform(rect, matrix);\n\t\t}\n\n\t\tpublic static Rect TransformFromDevice(this Rect rect, Visual visual)\n\t\t{\n\t\t\tMatrix matrix = PresentationSource.FromVisual(visual).CompositionTarget.TransformFromDevice;\n\t\t\treturn Rect.Transform(rect, matrix);\n\t\t}\n\n\t\tpublic static Size TransformToDevice(this Size size, Visual visual)\n\t\t{\n\t\t\tMatrix matrix = PresentationSource.FromVisual(visual).CompositionTarget.TransformToDevice;\n\t\t\treturn new Size(size.Width * matrix.M11, size.Height * matrix.M22);\n\t\t}\n\n\t\tpublic static Size TransformFromDevice(this Size size, Visual visual)\n\t\t{\n\t\t\tMatrix matrix = PresentationSource.FromVisual(visual).CompositionTarget.TransformFromDevice;\n\t\t\treturn new Size(size.Width * matrix.M11, size.Height * matrix.M22);\n\t\t}\n\n\t\tpublic static Point TransformToDevice(this Point point, Visual visual)\n\t\t{\n\t\t\tMatrix matrix = PresentationSource.FromVisual(visual).CompositionTarget.TransformToDevice;\n\t\t\treturn matrix.Transform(point);\n\t\t}\n\n\t\tpublic static Point TransformFromDevice(this Point point, Visual visual)\n\t\t{\n\t\t\tMatrix matrix = PresentationSource.FromVisual(visual).CompositionTarget.TransformFromDevice;\n\t\t\treturn matrix.Transform(point);\n\t\t}\n\t\t#endregion\n\n\t\tpublic static T? FindVisualChild<T>(this DependencyObject? depObj) where T : DependencyObject\n\t\t{\n\t\t\tif (depObj != null)\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)\n\t\t\t\t{\n\t\t\t\t\tDependencyObject child = VisualTreeHelper.GetChild(depObj, i);\n\t\t\t\t\tif (child is T dependencyObject)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn dependencyObject;\n\t\t\t\t\t}\n\n\t\t\t\t\tT? childItem = FindVisualChild<T>(child);\n\t\t\t\t\tif (childItem != null)\n\t\t\t\t\t\treturn childItem;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static T? GetParent<T>(this DependencyObject? depObj) where T : DependencyObject\n\t\t{\n\t\t\tif (depObj == null)\n\t\t\t\treturn null;\n\t\t\twhile (!(depObj is T))\n\t\t\t{\n\t\t\t\tvar parent = VisualTreeHelper.GetParent(depObj);\n\t\t\t\tif (parent == null)\n\t\t\t\t\treturn null;\n\t\t\t\tdepObj = parent;\n\t\t\t}\n\t\t\treturn (T)depObj;\n\t\t}\n\n\t\tpublic static void SelectItem(this DataGrid view, object item)\n\t\t{\n\t\t\tvar container = (DataGridRow)view.ItemContainerGenerator.ContainerFromItem(item);\n\t\t\tif (container != null)\n\t\t\t\tcontainer.IsSelected = true;\n\t\t\tview.Focus();\n\t\t}\n\n\t\tpublic static double ToGray(this Color? color)\n\t\t{\n\t\t\treturn color?.R * 0.3 + color?.G * 0.6 + color?.B * 0.1 ?? 0.0;\n\t\t}\n\n\t\tinternal static string? FormatExceptions(this IList<App.ExceptionData> exceptions)\n\t\t{\n\t\t\tif (exceptions.Count == 0)\n\t\t\t\treturn null;\n\n\t\t\tstring delimiter = $\"-------------------------------------------------{Environment.NewLine}\";\n\n\t\t\treturn string.Join(delimiter, exceptions.Select(FormatException));\n\t\t}\n\n\t\tprivate static string FormatException(App.ExceptionData item)\n\t\t{\n\t\t\tvar output = new StringBuilder();\n\n\t\t\tif (!item.PluginName.IsNullOrEmpty())\n\t\t\t\toutput.AppendLine(\"Error(s) loading plugin: \" + item.PluginName);\n\n\t\t\tif (item.Exception is System.Reflection.ReflectionTypeLoadException exception)\n\t\t\t{\n\t\t\t\tforeach (var ex in exception.LoaderExceptions.ExceptNullItems())\n\t\t\t\t{\n\t\t\t\t\toutput.AppendLine(ex.ToString());\n\t\t\t\t\toutput.AppendLine();\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\toutput.AppendLine(item.Exception.ToString());\n\t\t\t}\n\n\t\t\treturn output.ToString();\n\t\t}\n\n\t\tpublic static IDisposable PreserveFocus(this IInputElement? inputElement, bool preserve = true)\n\t\t{\n\t\t\treturn new RestoreFocusHelper(inputElement, preserve);\n\t\t}\n\n\t\tprivate sealed class RestoreFocusHelper(IInputElement? inputElement, bool preserve) : IDisposable\n\t\t{\n\t\t\tpublic void Dispose()\n\t\t\t{\n\t\t\t\tif (preserve)\n\t\t\t\t{\n\t\t\t\t\tinputElement?.Focus();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/GlobalUsings.cs",
    "content": "// Copyright (c) 2024 Tom Englert for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nglobal using ICSharpCode.ILSpy.Util;"
  },
  {
    "path": "ILSpy/GuessFileType.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\nusing System.Text;\nusing System.Xml;\n\nnamespace ICSharpCode.ILSpy\n{\n\t/// <summary>\n\t/// Static methods for determining the type of a file.\n\t/// </summary>\n\tstatic class GuessFileType\n\t{\n\t\tpublic static FileType DetectFileType(Stream stream)\n\t\t{\n\t\t\tStreamReader reader;\n\t\t\tif (stream.Length >= 2)\n\t\t\t{\n\t\t\t\tint firstByte = stream.ReadByte();\n\t\t\t\tint secondByte = stream.ReadByte();\n\t\t\t\tswitch ((firstByte << 8) | secondByte)\n\t\t\t\t{\n\t\t\t\t\tcase 0xfffe: // UTF-16 LE BOM / UTF-32 LE BOM\n\t\t\t\t\tcase 0xfeff: // UTF-16 BE BOM\n\t\t\t\t\t\tstream.Position -= 2;\n\t\t\t\t\t\treader = new StreamReader(stream, detectEncodingFromByteOrderMarks: true);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 0xefbb: // start of UTF-8 BOM\n\t\t\t\t\t\tif (stream.ReadByte() == 0xbf)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treader = new StreamReader(stream, Encoding.UTF8);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn FileType.Binary;\n\t\t\t\t\t\t}\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif (IsUTF8(stream, (byte)firstByte, (byte)secondByte))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstream.Position = 0;\n\t\t\t\t\t\t\treader = new StreamReader(stream, Encoding.UTF8);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn FileType.Binary;\n\t\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn FileType.Binary;\n\t\t\t}\n\t\t\t// Now we got a StreamReader with the correct encoding\n\t\t\t// Check for XML now\n\t\t\ttry\n\t\t\t{\n\t\t\t\tXmlTextReader xmlReader = new XmlTextReader(reader);\n\t\t\t\txmlReader.XmlResolver = null;\n\t\t\t\txmlReader.MoveToContent();\n\t\t\t\treturn FileType.Xml;\n\t\t\t}\n\t\t\tcatch (XmlException)\n\t\t\t{\n\t\t\t\treturn FileType.Text;\n\t\t\t}\n\t\t}\n\n\t\tstatic bool IsUTF8(Stream fs, byte firstByte, byte secondByte)\n\t\t{\n\t\t\tint max = (int)Math.Min(fs.Length, 500000); // look at max. 500 KB\n\t\t\tconst int ASCII = 0;\n\t\t\tconst int Error = 1;\n\t\t\tconst int UTF8 = 2;\n\t\t\tconst int UTF8Sequence = 3;\n\t\t\tint state = ASCII;\n\t\t\tint sequenceLength = 0;\n\t\t\tbyte b;\n\t\t\tfor (int i = 0; i < max; i++)\n\t\t\t{\n\t\t\t\tif (i == 0)\n\t\t\t\t{\n\t\t\t\t\tb = firstByte;\n\t\t\t\t}\n\t\t\t\telse if (i == 1)\n\t\t\t\t{\n\t\t\t\t\tb = secondByte;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tb = (byte)fs.ReadByte();\n\t\t\t\t}\n\t\t\t\tif (b < 0x80)\n\t\t\t\t{\n\t\t\t\t\t// normal ASCII character\n\t\t\t\t\tif (state == UTF8Sequence)\n\t\t\t\t\t{\n\t\t\t\t\t\tstate = Error;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (b < 0xc0)\n\t\t\t\t{\n\t\t\t\t\t// 10xxxxxx : continues UTF8 byte sequence\n\t\t\t\t\tif (state == UTF8Sequence)\n\t\t\t\t\t{\n\t\t\t\t\t\t--sequenceLength;\n\t\t\t\t\t\tif (sequenceLength < 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstate = Error;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (sequenceLength == 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstate = UTF8;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tstate = Error;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (b >= 0xc2 && b < 0xf5)\n\t\t\t\t{\n\t\t\t\t\t// beginning of byte sequence\n\t\t\t\t\tif (state == UTF8 || state == ASCII)\n\t\t\t\t\t{\n\t\t\t\t\t\tstate = UTF8Sequence;\n\t\t\t\t\t\tif (b < 0xe0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsequenceLength = 1; // one more byte following\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (b < 0xf0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsequenceLength = 2; // two more bytes following\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsequenceLength = 3; // three more bytes following\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tstate = Error;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// 0xc0, 0xc1, 0xf5 to 0xff are invalid in UTF-8 (see RFC 3629)\n\t\t\t\t\tstate = Error;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn state != Error;\n\t\t}\n\t}\n\n\tenum FileType\n\t{\n\t\tBinary,\n\t\tText,\n\t\tXml\n\t}\n}\n"
  },
  {
    "path": "ILSpy/ILSpy.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>WinExe</OutputType>\r\n    <TargetFramework>net10.0-windows</TargetFramework>\r\n    <RollForward>major</RollForward>\r\n    <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers>\r\n    <GenerateAssemblyInfo>False</GenerateAssemblyInfo>\r\n    <AutoGenerateBindingRedirects>false</AutoGenerateBindingRedirects>\r\n    <GenerateSupportedRuntime>false</GenerateSupportedRuntime>\r\n    <UseWpf>true</UseWpf>\r\n    <RootNamespace>ICSharpCode.ILSpy</RootNamespace>\r\n\r\n    <AllowUnsafeBlocks>True</AllowUnsafeBlocks>\r\n\r\n    <ApplicationIcon>Images\\ILSpy-Large.ico</ApplicationIcon>\r\n    <ApplicationManifest>app.manifest</ApplicationManifest>\r\n\r\n    <SignAssembly>True</SignAssembly>\r\n    <AssemblyOriginatorKeyFile>..\\ICSharpCode.Decompiler\\ICSharpCode.Decompiler.snk</AssemblyOriginatorKeyFile>\r\n    <ServerGarbageCollection>true</ServerGarbageCollection>\r\n    <GarbageCollectionAdaptationMode>1</GarbageCollectionAdaptationMode>\r\n    <EnableWindowsTargeting>true</EnableWindowsTargeting>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <RuntimeHostConfigurationOption Include=\"Switch.System.Windows.Media.EnableHardwareAccelerationInRdp\" Value=\"true\" />\r\n  </ItemGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Debug'\">\r\n    <DebugType>full</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n    <CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\r\n    <DebugType>pdbonly</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"AvalonEdit\" />\r\n    <PackageReference Include=\"Dirkster.AvalonDock.Themes.VS2013\" />\r\n    <PackageReference Include=\"McMaster.Extensions.CommandLineUtils\" />\r\n    <PackageReference Include=\"Microsoft.Extensions.DependencyInjection.Abstractions\" />\r\n    <PackageReference Include=\"DataGridExtensions\" />\r\n    <PackageReference Include=\"Microsoft.Xaml.Behaviors.Wpf\" />\r\n    <PackageReference Include=\"TomsToolbox.Composition.MicrosoftExtensions\" />\r\n    <PackageReference Include=\"TomsToolbox.Wpf.Composition.AttributedModel\" />\r\n    <PackageReference Include=\"TomsToolbox.Wpf.Styles\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <EmbeddedResource Include=\"..\\doc\\ILSpyAboutPage.txt\" />\r\n    <EmbeddedResource Include=\"..\\doc\\third-party-notices.txt\" />\r\n    <EmbeddedResource Include=\"..\\LICENSE\">\r\n      <Link>license.txt</Link>\r\n    </EmbeddedResource>\r\n    <Resource Include=\"Images\\NuGet.png\" />\r\n    <Resource Include=\"Images\\ILSpy.ico\" />\r\n    <EmbeddedResource Include=\"TextView\\CSharp-Mode.xshd\" />\r\n    <EmbeddedResource Include=\"TextView\\ILAsm-Mode.xshd\" />\r\n    <EmbeddedResource Include=\"TextView\\Asm-Mode.xshd\" />\r\n    <EmbeddedResource Include=\"TextView\\XML-Mode.xshd\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <Compile Update=\"Properties\\Resources.Designer.cs\">\r\n      <DesignTime>True</DesignTime>\r\n      <AutoGen>True</AutoGen>\r\n      <DependentUpon>Resources.resx</DependentUpon>\r\n    </Compile>\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <EmbeddedResource Update=\"Properties\\Resources.resx\">\r\n      <Generator>PublicResXFileCodeGenerator</Generator>\r\n      <LastGenOutput>Resources.Designer.cs</LastGenOutput>\r\n    </EmbeddedResource>\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\ICSharpCode.ILSpyX\\ICSharpCode.ILSpyX.csproj\" />\r\n    <ProjectReference Include=\"..\\ICSharpCode.Decompiler\\ICSharpCode.Decompiler.csproj\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup Condition=\"'$(Configuration)' == 'Debug'\">\r\n    <PackageReference Include=\"Microsoft.DiaSymReader.Converter.Xml\" />\r\n    <PackageReference Include=\"Microsoft.DiaSymReader\" />\r\n    <PackageReference Include=\"Microsoft.DiaSymReader.Native\" />\r\n\r\n    <!-- 4.3.0 of all those have security vulnerabilities, and although only a debug build, we'll override the versions for good measure -->\r\n    <PackageReference Include=\"System.Net.Http\" />\r\n    <PackageReference Include=\"System.Private.Uri\" />\r\n    <PackageReference Include=\"System.Text.RegularExpressions\" />\r\n  </ItemGroup>\r\n\r\n  <PropertyGroup>\r\n    <VCToolsVersionPropsFileNameDefault>Microsoft.VCToolsVersion.default.props</VCToolsVersionPropsFileNameDefault>\r\n    <VCBasePath>$(MSBuildToolsPath)\\..\\..\\..\\VC\\</VCBasePath>\r\n    <!-- In VS 2022 there is an extra directory level that's why we need to add one more '..'  -->\r\n    <VCBasePath Condition=\"!Exists('$(VCBasePath)Auxiliary\\Build\\$(VCToolsVersionPropsFileNameDefault)')\">$(MSBuildToolsPath)\\..\\..\\..\\..\\VC\\</VCBasePath>\r\n    <VCToolsVersionPropsFile>$(VCBasePath)Auxiliary\\Build\\$(VCToolsVersionPropsFileNameDefault)</VCToolsVersionPropsFile>\r\n    <EnableNETAnalyzers>True</EnableNETAnalyzers>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|AnyCPU'\">\r\n    <NoWarn>$(NoWarn);1701;1702;CA1001;CA2213</NoWarn>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|AnyCPU'\">\r\n    <NoWarn>$(NoWarn);1701;1702;CA1001;CA2213</NoWarn>\r\n  </PropertyGroup>\r\n\r\n  <Import Project=\"$(VCToolsVersionPropsFile)\" Condition=\"Exists('$(VCToolsVersionPropsFile)')\" />\r\n\r\n  <ItemGroup>\r\n    <SortResXInput Include=\"Properties\\*.resx\" />\r\n    <SortResXInput Include=\"..\\ILSpy.AddIn\\*.resx\" />\r\n    <SortResXInput Include=\"..\\ILSpy.ReadyToRun\\Properties\\*.resx\" />\r\n    <SortResXStamp Include=\"obj\\sort-resx.stamp\" />\r\n  </ItemGroup>\r\n\r\n  <Target Name=\"SortResX\" BeforeTargets=\"BeforeBuild\" Inputs=\"@(SortResXInput)\" Outputs=\"@(SortResXStamp)\" Condition=\"'$(GITHUB_ACTIONS)' != 'true'\">\r\n    <PropertyGroup Condition=\" '$(OS)' == 'Windows_NT' \">\r\n      <SortResX>powershell -NoProfile -ExecutionPolicy Bypass -File BuildTools/sort-resx.ps1</SortResX>\r\n    </PropertyGroup>\r\n    <Exec WorkingDirectory=\"..\" Command=\"$(SortResX)\" Timeout=\"60000\" />\r\n    <Touch Files=\"@(SortResXStamp)\" AlwaysCreate=\"true\" />\r\n  </Target>\r\n\r\n  <Target Name=\"ApplyStackExtension\" AfterTargets=\"PostBuildEvent\" Condition=\"'$(VCToolsVersion)'!=''\">\r\n    <Exec Command=\"&quot;$(VCBasePath)Tools\\MSVC\\$(VCToolsVersion)\\bin\\Hostx64\\x64\\editbin.exe&quot; /stack:16777216 &quot;$(TargetDir)$(TargetName).exe&quot;&#xD;&#xA;EXIT 0\" />\r\n  </Target>\r\n</Project>\r\n"
  },
  {
    "path": "ILSpy/ILSpySettingsFilePathProvider.cs",
    "content": "// Copyright (c) 2022 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\n\nusing ICSharpCode.ILSpyX.Settings;\n\nnamespace ICSharpCode.ILSpy\n{\n\tinternal class ILSpySettingsFilePathProvider : ISettingsFilePathProvider\n\t{\n\t\tpublic string GetSettingsFilePath()\n\t\t{\n\t\t\tif (App.CommandLineArguments.ConfigFile != null)\n\t\t\t\treturn App.CommandLineArguments.ConfigFile;\n\n\t\t\tvar assemblyLocation = typeof(MainWindow).Assembly.Location;\n\t\t\tif (!String.IsNullOrWhiteSpace(assemblyLocation))\n\t\t\t{\n\t\t\t\tstring localPath = Path.Combine(Path.GetDirectoryName(assemblyLocation), \"ILSpy.xml\");\n\t\t\t\tif (File.Exists(localPath))\n\t\t\t\t\treturn localPath;\n\t\t\t}\n\n\t\t\treturn Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), \"ICSharpCode\", \"ILSpy.xml\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/ILSpyTraceListener.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Threading;\n\nusing ICSharpCode.ILSpy.Controls;\n\nnamespace ICSharpCode.ILSpy\n{\n\tclass ILSpyTraceListener : DefaultTraceListener\n\t{\n\t\t[Conditional(\"DEBUG\")]\n\t\tpublic static void Install()\n\t\t{\n\t\t\tTrace.Listeners.Clear();\n\t\t\tTrace.Listeners.Add(new ILSpyTraceListener());\n\t\t}\n\n\t\tpublic ILSpyTraceListener()\n\t\t{\n\t\t\tbase.AssertUiEnabled = false;\n\t\t}\n\n\t\tHashSet<string> ignoredStacks = new HashSet<string>();\n\t\tbool dialogIsOpen;\n\n\t\tpublic override void Fail(string message)\n\t\t{\n\t\t\tthis.Fail(message, null);\n\t\t}\n\n\t\tpublic override void Fail(string message, string detailMessage)\n\t\t{\n\t\t\tbase.Fail(message, detailMessage); // let base class write the assert to the debug console\n\t\t\tstring topFrame = \"\";\n\t\t\tstring stackTrace = \"\";\n\t\t\ttry\n\t\t\t{\n\t\t\t\tstackTrace = new StackTrace(true).ToString();\n\t\t\t\tvar frames = stackTrace.Split('\\r', '\\n')\n\t\t\t\t\t.Where(f => f.Length > 0)\n\t\t\t\t\t.SkipWhile(f => f.Contains(\"ILSpyTraceListener\") || f.Contains(\"System.Diagnostics\"))\n\t\t\t\t\t.ToList();\n\t\t\t\ttopFrame = frames[0];\n\t\t\t\tstackTrace = string.Join(Environment.NewLine, frames);\n\t\t\t}\n\t\t\tcatch { }\n\t\t\tlock (ignoredStacks)\n\t\t\t{\n\t\t\t\tif (ignoredStacks.Contains(topFrame))\n\t\t\t\t\treturn;\n\t\t\t\tif (dialogIsOpen)\n\t\t\t\t\treturn;\n\t\t\t\tdialogIsOpen = true;\n\t\t\t}\n\t\t\t// We might be unable to display a dialog here, e.g. because\n\t\t\t// we're on the UI thread but dispatcher processing is disabled.\n\t\t\t// In any case, we don't want to pump messages while the dialog is displaying,\n\t\t\t// so we create a separate UI thread for the dialog:\n\t\t\tint result = 0;\n\t\t\tvar thread = new Thread(() => result = ShowAssertionDialog(message, detailMessage, stackTrace));\n\t\t\tthread.SetApartmentState(ApartmentState.STA);\n\t\t\tthread.Start();\n\t\t\tthread.Join();\n\t\t\tif (result == 0)\n\t\t\t{ // throw\n\t\t\t\tthrow new AssertionFailedException(message);\n\t\t\t}\n\t\t\telse if (result == 1)\n\t\t\t{ // debug\n\t\t\t\tDebugger.Break();\n\t\t\t}\n\t\t\telse if (result == 2)\n\t\t\t{ // ignore\n\t\t\t}\n\t\t\telse if (result == 3)\n\t\t\t{\n\t\t\t\tlock (ignoredStacks)\n\t\t\t\t{\n\t\t\t\t\tignoredStacks.Add(topFrame);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tint ShowAssertionDialog(string message, string detailMessage, string stackTrace)\n\t\t{\n\t\t\tmessage = message + Environment.NewLine + detailMessage + Environment.NewLine + stackTrace;\n\t\t\tstring[] buttonTexts = { \"Throw\", \"Debug\", \"Ignore\", \"Ignore All\" };\n\t\t\tCustomDialog inputBox = new CustomDialog(\"Assertion Failed\", message.TakeStartEllipsis(750), -1, 2, buttonTexts);\n\t\t\tinputBox.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\n\t\t\tinputBox.ShowInTaskbar = true; // make this window more visible, because it effectively interrupts the decompilation process.\n\t\t\ttry\n\t\t\t{\n\t\t\t\tinputBox.ShowDialog();\n\t\t\t\treturn inputBox.Result;\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tdialogIsOpen = false;\n\t\t\t\tinputBox.Dispose();\n\t\t\t}\n\t\t}\n\t}\n\n\tclass AssertionFailedException : Exception\n\t{\n\t\tpublic AssertionFailedException(string message) : base(message) { }\n\t}\n}\n"
  },
  {
    "path": "ILSpy/ISmartTextOutput.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Input;\nusing System.Windows.Media;\n\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.ILSpy.Themes;\n\nnamespace ICSharpCode.ILSpy\n{\n\t/// <summary>\n\t/// Adds additional WPF-specific output features to <see cref=\"ITextOutput\"/>.\n\t/// </summary>\n\tpublic interface ISmartTextOutput : ITextOutput\n\t{\n\t\t/// <summary>\n\t\t/// Inserts an interactive UI element at the current position in the text output.\n\t\t/// </summary>\n\t\tvoid AddUIElement(Func<UIElement> element);\n\n\t\tvoid BeginSpan(HighlightingColor highlightingColor);\n\t\tvoid EndSpan();\n\n\t\t/// <summary>\n\t\t/// Gets/sets the title displayed in the document tab's header.\n\t\t/// </summary>\n\t\tstring Title { get; set; }\n\t}\n\n\tpublic static class SmartTextOutputExtensions\n\t{\n\t\t/// <summary>\n\t\t/// Creates a button.\n\t\t/// </summary>\n\t\tpublic static void AddButton(this ISmartTextOutput output, ImageSource icon, string text, RoutedEventHandler click)\n\t\t{\n\t\t\toutput.AddUIElement(\n\t\t\t\tdelegate {\n\t\t\t\t\tButton button = ThemeManager.Current.CreateButton();\n\t\t\t\t\tbutton.Cursor = Cursors.Arrow;\n\t\t\t\t\tbutton.Margin = new Thickness(2);\n\t\t\t\t\tbutton.Padding = new Thickness(9, 1, 9, 1);\n\t\t\t\t\tbutton.MinWidth = 73;\n\t\t\t\t\tif (icon != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tbutton.Content = new StackPanel {\n\t\t\t\t\t\t\tOrientation = Orientation.Horizontal,\n\t\t\t\t\t\t\tChildren = {\n\t\t\t\t\t\t\t\tnew Image { Width = 16, Height = 16, Source = icon, Margin = new Thickness(0, 0, 4, 0) },\n\t\t\t\t\t\t\t\tnew TextBlock { Text = text }\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tbutton.Content = text;\n\t\t\t\t\t}\n\t\t\t\t\tbutton.Click += click;\n\t\t\t\t\treturn button;\n\t\t\t\t});\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Images/AccessOverlayIcon.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.ILSpy\n{\n\tinternal enum AccessOverlayIcon\n\t{\n\t\tPublic,\n\t\tProtected,\n\t\tInternal,\n\t\tProtectedInternal,\n\t\tPrivate,\n\t\tPrivateProtected,\n\t\tCompilerControlled\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Images/Assembly.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M8.0001,3.0004L8.0001,6.0004 6.0001,6.0004 6.0001,4.0004 9.99999999997669E-05,4.0004 9.99999999997669E-05,10.9994 6.0001,10.9994 6.0001,8.9994 8.0001,8.9994 8.0001,12.0004 16.0001,12.0004 16.0001,3.0004z\" />\n\t\t<GeometryDrawing Brush=\"#FF414141\" Geometry=\"F1M1,10L5,10 5,5 1,5z\" />\n\t\t<GeometryDrawing Brush=\"#FF414141\" Geometry=\"F1M9,11L15,11 15,4 9,4z\" />\n\t\t<GeometryDrawing Brush=\"#FF414141\" Geometry=\"F1M6,8L8,8 8,7 6,7z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/AssemblyList.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M2.0187,-0.000199999999999534L2.0187,2.0188 -0.000300000000000189,2.0188 -0.000300000000000189,5.9998 2.0187,5.9998 2.0187,6.9998 -0.000300000000000189,6.9998 -0.000300000000000189,13.9998 6.0007,13.9998 6.0007,12.0008 7.9997,12.0008 7.9997,14.9998 15.9997,14.9998 15.9997,5.9998 7.9997,5.9998 7.9997,8.9998 6.0007,8.9998 6.0007,5.9998 7.9997,5.9998 7.9997,2.0188 6.0007,2.0188 6.0007,-0.000199999999999534z\" />\n    <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M8,10L6,10 6,11 8,11z M5,8L1,8 1,13 5,13z M15,14L9,14 9,7 15,7z\" />\n    <GeometryDrawing Brush=\"#FF388A34\" Geometry=\"F1M7,3.0181L5,3.0181 5,1.0001 3.019,1.0001 3.019,3.0181 1,3.0181 1,5.0001 3.019,5.0001 3.019,7.0001 5,7.0001 5,5.0001 7,5.0001z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/AssemblyListGAC.xaml",
    "content": "<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ClipGeometry=\"M0,0 V16 H16 V0 H0 Z\">\n  <GeometryDrawing>\n\t<GeometryDrawing.Brush>\n\t  <SolidColorBrush Color=\"#FFF6F6F6\" Opacity=\"0\" />\n\t</GeometryDrawing.Brush>\n\t<GeometryDrawing.Geometry>\n\t  <RectangleGeometry RadiusX=\"0\" RadiusY=\"0\" Rect=\"0,0,16,16\" />\n\t</GeometryDrawing.Geometry>\n  </GeometryDrawing>\n  <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M16,6L16,15 8,15 8,12 6,12 6,14 0,14 0,7 2.019,7 2.019,6 0,6 0,2.018 2.019,2.018 2.019,0 6,0 6,2.018 8,2.018 8,6 6,6 6,9 8,9 8,6z\" />\n  <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1 M16,16z M0,0z M15,14L9,14 9,7 15,7z M5,8L1,8 1,13 5,13z M8,10L6,10 6,11 8,11z\" />\n  <GeometryDrawing Brush=\"#FF388A34\" Geometry=\"F1 M16,16z M0,0z M7,3.018L5,3.018 5,1 3.019,1 3.019,3.018 1,3.018 1,5 3.019,5 3.019,7 5,7 5,5 7,5z\" />\n  <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M12.115051,12.119209L14.846892,12.119209 14.846892,14.36933 12.115051,14.36933z\">\n\t<GeometryDrawing.Pen>\n\t  <Pen Brush=\"#FFF6F6F6\" Thickness=\"0.92304718\" StartLineCap=\"Round\" EndLineCap=\"Round\" LineJoin=\"Round\" />\n\t</GeometryDrawing.Pen>\n  </GeometryDrawing>\n  <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M3.2681589,12L8,12 8,14.250121 3.2681589,14.250121z\">\n\t<GeometryDrawing.Pen>\n\t  <Pen Brush=\"#FFF6F6F6\" Thickness=\"1.21481812\" StartLineCap=\"Round\" EndLineCap=\"Round\" LineJoin=\"Round\" />\n\t</GeometryDrawing.Pen>\n  </GeometryDrawing>\n  <GeometryDrawing Brush=\"#FF090909\" Geometry=\"F1 M16,16z M0,0z M4.6532176,13.643132L4.6532176,13.145349 6.4487914,13.145349 6.4487914,14.715735C6.176196,14.940923 5.8917487,15.100925 5.5954494,15.213518 5.3050761,15.326112 5.0028508,15.379446 4.6946995,15.379446 4.2798805,15.379446 3.9006174,15.290556 3.5569102,15.112777 3.219129,14.934997 2.9583856,14.674254 2.7865321,14.336472 2.6146785,13.998691 2.5257887,13.625354 2.5257887,13.210535 2.5257887,12.795716 2.6146787,12.410527 2.7865321,12.049042 2.9583856,11.693483 3.2072771,11.426813 3.5332063,11.25496 3.8532095,11.083106 4.2265466,10.994216 4.6532176,10.994216 4.9554429,10.994216 5.2339642,11.041626 5.4828556,11.142366 5.7317471,11.243108 5.9273046,11.379405 6.0636023,11.557185 6.2058259,11.734965 6.3124937,11.966078 6.3895315,12.250525L5.8798967,12.392749C5.8147109,12.173488 5.737673,12.00756 5.6428573,11.883114 5.5480415,11.758668 5.4117438,11.657927 5.2398902,11.586815 5.0621106,11.509777 4.8665531,11.474221 4.6532176,11.474221 4.3984002,11.474221 4.1732128,11.515701 3.9895072,11.592741 3.7998756,11.669781 3.651726,11.77052 3.5332063,11.900892 3.4206125,12.025338 3.3317228,12.167562 3.2665369,12.321637 3.1598692,12.582381 3.1065353,12.866828 3.1065353,13.174979 3.1065353,13.548316 3.1717213,13.868319 3.3020928,14.123137 3.4324645,14.377954 3.6220961,14.567586 3.8709875,14.692032 4.1198789,14.810551 4.3806223,14.875737 4.6650696,14.875737 4.908035,14.875737 5.1450745,14.828327 5.3761879,14.733513 5.6073014,14.638693 5.7791549,14.537956 5.9036006,14.437214L5.9036006,13.643132z\">\n\t<GeometryDrawing.Pen>\n\t  <Pen Brush=\"#FFF6F6F6\" Thickness=\"1.42003238\" StartLineCap=\"Flat\" EndLineCap=\"Flat\" LineJoin=\"Round\" />\n\t</GeometryDrawing.Pen>\n  </GeometryDrawing>\n  <GeometryDrawing Brush=\"#FF090909\" Geometry=\"F1 M16,16z M0,0z M6.8152247,15.308334L8.4389448,11.065328 9.0433954,11.065328 10.779709,15.308334 10.145629,15.308334 9.647846,14.022395 7.8759762,14.022395 7.4078233,15.308334z M8.0359778,13.566094L9.4759924,13.566094 9.0315434,12.392749C8.8952458,12.03719 8.794504,11.740891 8.7293181,11.509777 8.6759841,11.782372 8.5989465,12.054968 8.5041307,12.321637z\">\n\t<GeometryDrawing.Pen>\n\t  <Pen Brush=\"#FFF6F6F6\" Thickness=\"1.42003238\" StartLineCap=\"Flat\" EndLineCap=\"Flat\" LineJoin=\"Round\" />\n\t</GeometryDrawing.Pen>\n  </GeometryDrawing>\n  <GeometryDrawing Brush=\"#FF090909\" Geometry=\"F1 M16,16z M0,0z M14.258214,13.820912L14.821182,13.963135C14.702663,14.425362 14.489327,14.774995 14.181176,15.017961 13.878951,15.260926 13.505613,15.379446 13.061164,15.379446 12.604864,15.379446 12.231526,15.290556 11.947079,15.100925 11.662632,14.917219 11.44337,14.644624 11.295221,14.29499 11.141145,13.939431 11.070033,13.560168 11.070033,13.157201 11.070033,12.712752 11.152993,12.327563 11.324851,12.001634 11.490778,11.669779 11.733744,11.420887 12.041895,11.249034 12.355972,11.07718 12.699679,10.994216 13.073016,10.994216 13.493761,10.994216 13.855247,11.100884 14.139694,11.320146 14.430067,11.533481 14.631551,11.835706 14.744144,12.226821L14.193028,12.357193C14.098208,12.049042 13.950062,11.823854 13.766357,11.687557 13.576725,11.545333 13.345612,11.474221 13.061164,11.474221 12.735235,11.474221 12.46264,11.551261 12.243378,11.711261 12.024117,11.865336 11.870041,12.072746 11.781152,12.339415 11.692262,12.600158 11.644854,12.872754 11.644854,13.151275 11.644854,13.51276 11.698184,13.826838 11.804855,14.099433 11.911523,14.366102 12.071525,14.567586 12.296712,14.697958 12.515974,14.834255 12.758939,14.899441 13.013757,14.899441 13.327834,14.899441 13.594503,14.810551 13.813765,14.626846 14.033026,14.449066 14.181176,14.176471 14.258214,13.820912z\">\n\t<GeometryDrawing.Pen>\n\t  <Pen Brush=\"#FFF6F6F6\" Thickness=\"1.42003238\" StartLineCap=\"Flat\" EndLineCap=\"Flat\" LineJoin=\"Round\" />\n\t</GeometryDrawing.Pen>\n  </GeometryDrawing>\n  <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M14.258214,13.820912L14.821182,13.963135C14.702663,14.425362 14.489327,14.774995 14.181176,15.017961 13.878951,15.260926 13.505613,15.379446 13.061164,15.379446 12.604864,15.379446 12.231526,15.290556 11.947079,15.100925 11.662632,14.917219 11.44337,14.644624 11.295221,14.29499 11.141145,13.939431 11.070033,13.560168 11.070033,13.157201 11.070033,12.712752 11.152993,12.327563 11.324851,12.001634 11.490778,11.669779 11.733744,11.420887 12.041895,11.249034 12.355972,11.07718 12.699679,10.994216 13.073016,10.994216 13.493761,10.994216 13.855247,11.100884 14.139694,11.320146 14.430067,11.533481 14.631551,11.835706 14.744144,12.226821L14.193028,12.357193C14.098208,12.049042 13.950062,11.823854 13.766357,11.687557 13.576725,11.545333 13.345612,11.474221 13.061164,11.474221 12.735235,11.474221 12.46264,11.551261 12.243378,11.711261 12.024117,11.865336 11.870041,12.072746 11.781152,12.339415 11.692262,12.600158 11.644854,12.872754 11.644854,13.151275 11.644854,13.51276 11.698184,13.826838 11.804855,14.099433 11.911523,14.366102 12.071525,14.567586 12.296712,14.697958 12.515974,14.834255 12.758939,14.899441 13.013757,14.899441 13.327834,14.899441 13.594503,14.810551 13.813765,14.626846 14.033026,14.449066 14.181176,14.176471 14.258214,13.820912z M6.8152247,15.308334L8.4389448,11.065328 9.0433954,11.065328 10.779709,15.308334 10.145629,15.308334 9.647846,14.022395 7.8759762,14.022395 7.4078233,15.308334z M8.0359778,13.566094L9.4759924,13.566094 9.0315434,12.392749C8.8952458,12.03719 8.794504,11.740891 8.7293181,11.509777 8.6759841,11.782372 8.5989465,12.054968 8.5041307,12.321637z M4.6532176,13.643134L4.6532176,13.145351 6.4487914,13.145351 6.4487914,14.715737C6.176196,14.940925 5.8917487,15.100927 5.5954494,15.21352 5.3050761,15.326114 5.0028508,15.379448 4.6946995,15.379448 4.2798805,15.379448 3.9006174,15.290558 3.5569102,15.112779 3.219129,14.934997 2.9583856,14.674254 2.7865321,14.336472 2.6146785,13.998691 2.5257887,13.625354 2.5257887,13.210535 2.5257887,12.795716 2.6146787,12.410527 2.7865321,12.049042 2.9583856,11.693483 3.2072771,11.426813 3.5332063,11.25496 3.8532095,11.083106 4.2265466,10.994216 4.6532176,10.994216 4.9554429,10.994216 5.2339642,11.041626 5.4828556,11.142366 5.7317471,11.243108 5.9273046,11.379405 6.0636023,11.557185 6.2058259,11.734965 6.3124937,11.966078 6.3895315,12.250525L5.8798967,12.392749C5.8147109,12.173488 5.737673,12.00756 5.6428573,11.883114 5.5480415,11.758668 5.4117438,11.657927 5.2398902,11.586815 5.0621106,11.509777 4.8665531,11.474221 4.6532176,11.474221 4.3984002,11.474221 4.1732128,11.515701 3.9895072,11.592741 3.7998756,11.669781 3.651726,11.77052 3.5332063,11.900892 3.4206125,12.025338 3.3317228,12.167562 3.2665369,12.321637 3.1598692,12.582381 3.1065353,12.866828 3.1065353,13.174979 3.1065353,13.548316 3.1717213,13.868319 3.3020928,14.123137 3.4324645,14.377954 3.6220961,14.567586 3.8709875,14.692032 4.1198789,14.810551 4.3806223,14.875737 4.6650696,14.875737 4.908035,14.875737 5.1450745,14.828327 5.3761879,14.733513 5.6073014,14.638693 5.7791549,14.537956 5.9036006,14.437214L5.9036006,13.643132z\">\n\t<GeometryDrawing.Pen>\n\t  <Pen Brush=\"#FFF6F6F6\" Thickness=\"1.42003238\" StartLineCap=\"Flat\" EndLineCap=\"Flat\" LineJoin=\"Round\" />\n\t</GeometryDrawing.Pen>\n  </GeometryDrawing>\n  <GeometryDrawing Brush=\"#FF0000FF\" Geometry=\"F1 M16,16z M0,0z M14.258214,13.820911L14.821182,13.963134C14.702663,14.425361 14.489327,14.774994 14.181176,15.01796 13.878951,15.260925 13.505613,15.379445 13.061164,15.379445 12.604864,15.379445 12.231526,15.290555 11.947079,15.100924 11.662632,14.917218 11.44337,14.644623 11.295221,14.294989 11.141145,13.93943 11.070033,13.560167 11.070033,13.1572 11.070033,12.712751 11.152993,12.327563 11.324851,12.001634 11.490778,11.669779 11.733744,11.420887 12.041895,11.249034 12.355972,11.07718 12.699679,10.994216 13.073016,10.994216 13.493761,10.994216 13.855247,11.100884 14.139694,11.320146 14.430067,11.533481 14.631551,11.835706 14.744144,12.226821L14.193028,12.357193C14.098208,12.049042 13.950062,11.823854 13.766357,11.687557 13.576725,11.545333 13.345612,11.474221 13.061164,11.474221 12.735235,11.474221 12.46264,11.551261 12.243378,11.711261 12.024117,11.865336 11.870041,12.072746 11.781152,12.339415 11.692262,12.600157 11.644854,12.872753 11.644854,13.151274 11.644854,13.512759 11.698184,13.826837 11.804855,14.099432 11.911523,14.366101 12.071525,14.567585 12.296712,14.697957 12.515974,14.834254 12.758939,14.89944 13.013757,14.89944 13.327834,14.89944 13.594503,14.81055 13.813765,14.626845 14.033026,14.449065 14.181176,14.17647 14.258214,13.820911z M6.815226,15.308333L8.438945,11.065328 9.043396,11.065328 10.779709,15.308333 10.145629,15.308333 9.647846,14.022394 7.875976,14.022394 7.407823,15.308333z M8.035978,13.566093L9.475993,13.566093 9.031544,12.392749C8.895246,12.03719 8.794504,11.740891 8.729319,11.509777 8.675989,11.782372 8.598947,12.054968 8.504131,12.321637z M4.6532189,13.643133L4.6532189,13.14535 6.448793,13.14535 6.448793,14.715736C6.176197,14.940924 5.89175,15.100926 5.595451,15.213519 5.305077,15.326113 5.002852,15.379447 4.6947009,15.379447 4.2798819,15.379447 3.9006189,15.290557 3.5569109,15.112778 3.2191299,14.934998 2.9583869,14.674255 2.7865329,14.336473 2.6146799,13.998692 2.5257899,13.625355 2.5257899,13.210536 2.5257899,12.795717 2.6146799,12.410528 2.7865329,12.049044 2.9583869,11.693485 3.2072779,11.426814 3.5332069,11.254961 3.8532109,11.083107 4.2265479,10.994217 4.6532189,10.994217 4.9554439,10.994217 5.233965,11.041627 5.482857,11.142367 5.731748,11.243109 5.927306,11.379406 6.063603,11.557186 6.205827,11.734967 6.312495,11.96608 6.389533,12.250527L5.879898,12.392751C5.814708,12.17349 5.737674,12.007562 5.642858,11.883116 5.548038,11.75867 5.411745,11.657929 5.239891,11.586817 5.062112,11.509779 4.8665539,11.474223 4.6532189,11.474223 4.3984009,11.474223 4.1732139,11.515703 3.9895079,11.592743 3.7998769,11.669783 3.6517269,11.770522 3.5332069,11.900894 3.4206139,12.02534 3.3317239,12.167564 3.2665379,12.321639 3.1598699,12.582382 3.1065359,12.866829 3.1065359,13.17498 3.1065359,13.548317 3.1717259,13.86832 3.3020939,14.123138 3.4324659,14.377955 3.6220969,14.567587 3.8709889,14.692033 4.1198799,14.810552 4.3806229,14.875738 4.6650709,14.875738 4.9080359,14.875738 5.145076,14.828328 5.376189,14.733514 5.607303,14.638694 5.779156,14.537957 5.903602,14.437215L5.903602,13.643131z\" />\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/AssemblyLoading.xaml",
    "content": "<?xml version=\"1.0\" ?>\n<DrawingGroup  xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.ClipGeometry>\n\t\t<RectangleGeometry Rect=\"0.0,0.0,16.0,16.0\"/>\n\t</DrawingGroup.ClipGeometry>\n\t<GeometryDrawing Brush=\"#fff6f6f6\">\n\t\t<GeometryDrawing.Geometry>\n\t\t\t<PathGeometry Figures=\"M 16 3 v 9 H 8 V 9 H 6 v 2 H 0 V 4 h 6 v 2 h 2 V 3 h 8 z\" FillRule=\"Nonzero\"/>\n\t\t</GeometryDrawing.Geometry>\n\t</GeometryDrawing>\n\t<GeometryDrawing Brush=\"#ff424242\">\n\t\t<GeometryDrawing.Geometry>\n\t\t\t<PathGeometry Figures=\"M 1 5 h 4 v 5 H 1 z M 9 4 h 6 v 7 H 9 z M 6 7 h 2 v 1 H 6 z\" FillRule=\"Nonzero\"/>\n\t\t</GeometryDrawing.Geometry>\n\t</GeometryDrawing>\n\t<GeometryDrawing Brush=\"#fff6f6f6\">\n\t\t<GeometryDrawing.Geometry>\n\t\t\t<PathGeometry Figures=\"m 16 12 c 0 2.2055 -1.7945 4 -4 4 C 9.7945 16 8 14.2055 8 12 A 3.995 3.995 0 0 1 8.544 10 H 8 v -2 H 12 V 12 h -2 c 0 1.103 0.896999 2 2 2 c 1.103 0 2 -0.897 2 -2 c 0 -0.672 -0.3345 -1.295 -0.895 -1.667 l -0.4165 -0.277 l 1.1075 -1.666 l 0.4165 0.2765 A 3.996 3.996 0 0 1 16 12 Z\" FillRule=\"Nonzero\"/>\n\t\t</GeometryDrawing.Geometry>\n\t</GeometryDrawing>\n\t<DrawingGroup Transform=\"0.49999992,0.0,0.0,0.49999992,8.000001,8.000001\">\n\t\t<GeometryDrawing Brush=\"#ff00539c\">\n\t\t\t<GeometryDrawing.Geometry>\n\t\t\t\t<PathGeometry Figures=\"m 15 8 c 0 3.859 -3.141 7 -7 7 C 4.14 15 1 11.859 1 8 A 7 7 0 0 1 3.12 3 H 1 V 1 H 7 V 7 H 5 V 4.002 A 5.01 5.01 0 0 0 3 8 c 0 2.757 2.243 5 5 5 c 2.757 0 5 -2.243 5 -5 A 4.993 4.993 0 0 0 10.764 3.833 L 11.871 2.167 A 6.989 6.989 0 0 1 15 8 Z\" FillRule=\"Nonzero\"/>\n\t\t\t</GeometryDrawing.Geometry>\n\t\t</GeometryDrawing>\n\t</DrawingGroup>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/AssemblyWarning.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M8.0001,1.9996L8.0001,5.0006 6.0001,5.0006 6.0001,3.0006 9.99999999997669E-05,3.0006 9.99999999997669E-05,9.9996 6.0001,9.9996 6.0001,7.9996 8.0001,7.9996 8.0001,10.9996 8.4991,10.9996 7.0001,14.0006 8.0001,15.9996 15.0001,15.9996 16.0001,14.0006 14.5001,10.9996 16.0001,10.9996 16.0001,1.9996z\" />\n\t\t<GeometryDrawing Brush=\"#FF414141\" Geometry=\"F1M12.5,7L14,10 15,10 15,3 9,3 9,10 10.5,7z M8,6L6,6 6,7 8,7z M5,9L1,9 1,4 5,4z\" />\n\t\t<GeometryDrawing Brush=\"#FFFFCC00\" Geometry=\"F1M12,12L11,12 11,10 12,10z M12,14L11,14 11,13 12,13z M11.891,8.016L11.109,8.016 8.094,14.016 8.609,15 14.375,15 14.859,14z\" />\n\t\t<GeometryDrawing Brush=\"#FF000000\" Geometry=\"F1M11,12L12,12 12,9.999 11,9.999z M11,14L12,14 12,13 11,13z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/Back.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M15,8C15,11.866 11.866,15 8,15 4.134,15 1,11.866 1,8 1,4.134 4.134,1 8,1 11.866,1 15,4.134 15,8\" />\n    <GeometryDrawing Brush=\"#FF00539C\" Geometry=\"F1M4,8L7,5 9,5 7,7 12,7 12,9 7,9 9,11 7,11z M2,8C2,11.247 4.755,14 8,14 11.245,14 14,11.247 14,8 14,4.756 11.245,2 8,2 4.755,2 2,4.756 2,8\" />\n    <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M4,8L7,5 9,5 7,7 12,7 12,9 7,9 9,11 7,11z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Class.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M5.5863,-0.000199999999999534L0.000299999999999301,5.5858 0.000299999999999301,6.4138 3.9993,10.4138 6.4143,7.9998 7.0003,7.9998 7.0003,9.9998 7.0003,13.0008 8.5863,13.0008 11.5853,15.9998 12.4133,15.9998 16.0003,12.4148 16.0003,11.5858 13.9143,9.4998 16.0003,7.4138 16.0003,6.5858 12.9993,3.5868 11.5853,4.9998 10.0003,4.9998 9.4143,4.9998 10.4143,4.0008 6.4143,-0.000199999999999534z\" />\n    <GeometryDrawing Brush=\"#FFC17C1A\" Geometry=\"F1M13,10L15,12 12,15 10,13 11,12 8,12 8,7 6,7 4,9 1,6 6,1 9,4 7,6 12,6 13,5 15,7 12,10 10,8 11,7 9,7 9,11 11.999,11.002z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Close.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M8.0001,5.1721L3.4571,0.6291 0.629099999999999,3.4571 5.1721,8.0001 0.629099999999999,12.5431 3.4571,15.3711 8.0001,10.8281 12.5431,15.3711 15.3711,12.5431 10.8281,8.0001 15.3711,3.4571 12.5431,0.6291z\" />\n    <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M9.4141,8L13.9571,12.543 12.5431,13.957 8.0001,9.414 3.4571,13.957 2.0431,12.543 6.5861,8 2.0431,3.457 3.4571,2.043 8.0001,6.586 12.5431,2.043 13.9571,3.457z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/CollapseAll.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M15,10L13,10 13,12 11,12 11,14 2,14 2,5 4,5 4,3 6,3 6,1 15,1z\" />\n    <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M9,7L4,7 4,12 9,12z M10,13L3,13 3,6 10,6z M5,4L5,5 6,5 11,5 11,10 11,11 12,11 12,4z M14,2L14,9 13,9 13,8 13,3 8,3 7,3 7,2z\" />\n    <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M8,10L5,10 5,9 8,9z M4,12L9,12 9,7 4,7z\" />\n    <GeometryDrawing Brush=\"#FF00539C\" Geometry=\"F1M8,10L5,10 5,8.969 8,9z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Constructor.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ClipGeometry=\"M0,0 V16 H16 V0 H0 Z\">\n  <GeometryDrawing Geometry=\"F1 M16,16z M0,0z M16,16L0,16 0,0 16,0 16,16z\">\n\t<GeometryDrawing.Brush>\n\t  <SolidColorBrush Color=\"#FFF6F6F6\" Opacity=\"0\" />\n\t</GeometryDrawing.Brush>\n  </GeometryDrawing>\n  <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M15,3.349L15,11.752 8.975,16 8.07,16 1,11.582 1,3.327 7.595,0 8.713,0 15,3.349z\" />\n  <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1 M16,16z M0,0z M12.715,4.398L8.487,7.02 3.565,4.272 8.143,1.963 12.715,4.398z M3,5.102L8,7.894 8,13.599 3,10.474 3,5.102z M9,13.536L9,7.878 13,5.398 13,10.715 9,13.536z\" />\n  <GeometryDrawing Brush=\"#FF218022\" Geometry=\"F1 M16,16z M0,0z M8.156,0.837L2,3.942 2,11.027 8.517,15.1 14,11.233 14,3.95 8.156,0.837z M12.715,4.398L8.487,7.02 3.565,4.272 8.143,1.963 12.715,4.398z M3,5.102L8,7.894 8,13.599 3,10.474 3,5.102z M9,13.536L9,7.878 13,5.398 13,10.715 9,13.536z\" />\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/Copy.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M0.9999,-0.000199999999999534L0.9999,13.0008 5.0009,13.0008 5.0009,15.9998 15.9999,15.9998 15.9999,7.3788 11.6209,3.0008 10.6049,3.0008 7.6179,-0.000199999999999534z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M14,14L7,14 7,5 10,5 10,9 14,9z M6,11L3,11 3,2 6.798,2 8.81,4 6,4z M11,5.207L13.793,8 11,8z M11.207,4L10.19,4 7.202,1 2,1 2,12 6,12 6,15 15,15 15,7.793z\" />\n\t\t<GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M14,14L7,14 7,5 10,5 10,9 14,9z M6,11L3,11 3,2 6.798,2 8.81,4 6,4z M11,5.207L13.793,8 11,8z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/Delegate.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M2.75,16C1.233,16,0,14.767,0,13.25L0,5.75C0,4.233,1.233,3,2.75,3L4,3 4,2.25C4,1.009,5.009,0,6.25,0L9.75,0C10.99,0,12,1.009,12,2.25L12,3 13.25,3C14.767,3,16,4.233,16,5.75L16,13.25C16,14.767,14.767,16,13.25,16z\" />\n    <GeometryDrawing Brush=\"#FF642D90\" Geometry=\"F1M13,13L12,13 12,6 13,6z M10,4L6,4 6,2.25C6,2.112,6.112,2,6.25,2L9.75,2C9.888,2,10,2.112,10,2.25z M4,13L3,13 3,6 4,6z M13.25,4L12,4 11,4 11,2.25C11,1.56,10.44,1,9.75,1L6.25,1C5.56,1,5,1.56,5,2.25L5,4 4,4 2.75,4C1.785,4,1,4.785,1,5.75L1,13.25C1,14.215,1.785,15,2.75,15L13.25,15C14.215,15,15,14.215,15,13.25L15,5.75C15,4.785,14.215,4,13.25,4\" />\n    <GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M13,13L12,13 12,6 13,6z M4,13L3,13 3,6 4,6z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Delete.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M0,10L16,10 16,6 0,6z\" />\n    <GeometryDrawing Brush=\"#FFA1260C\" Geometry=\"F1M15,9L1,9 1,7 15,7z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/DictionaryContain.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ClipGeometry=\"M0,0 V16 H16 V0 H0 Z\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M15,2L15,11 11,11C10.836,11.005,10,12,10,12L8,12C8,12,7.164,11.005,7,11L7,13 2,13 2,8 3,8 3,2 7.5,2C8.146,2.004 8.62,2.191 9,2.5 9.381,2.191 9.863,2 10.5,2z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M13,9L11,9C10.565,9,10.33,8.795,10,9L10,5C10,4.615,10.41,4,11,4L13,4z M10.5,3C9.876,3 9.516,3.365 9,4 8.492,3.374 8.139,3.004 7.5,3L4,3 4,8 5,8 5,4 7,4C7.566,4,8,4.663,8,5L8,9C7.67,8.795,7.436,9,7,9L7,10C7.549,10 8.778,9.975 9,10.5 9.221,9.975 10.451,10 11,10L14,10 14,3z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M3,11L6,11 6,12 3,12z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M3,10L6,10 6,9 3,9z\" />\n\t\t<GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M7,4L5,4 5,8 7,8 7,9C7.436,9,7.67,8.795,8,9L8,5C8,4.663,7.566,4,7,4\" />\n\t\t<GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M11,4C10.41,4,10,4.615,10,5L10,9C10.33,8.795,10.565,9,11,9L13,9 13,4z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Enum.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M7.5861,0.999700000000001L6.0001,2.5867 6.0001,5.9997 1.5861,5.9997 9.99999999997669E-05,7.5867 9.99999999997669E-05,13.4157 1.5861,14.9997 8.4141,14.9997 10.0001,13.4157 10.0001,9.9997 14.4141,9.9997 16.0001,8.4147 16.0001,2.5867 14.4141,0.999700000000001z\" />\n    <GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M13,5L9,5 9,4 13,4z M14,6L14,3 8,3 8,6 8.414,6 9,6.586 9,6 13,6 13,7 9.414,7 10,7.586 10,8 14,8z M3,11L7,11 7,12 3,12z M3,9L7,9 7,10 3,10z M2,13L8,13 8,11 8,8 2,8z\" />\n    <GeometryDrawing Brush=\"#FFC17C1A\" Geometry=\"F1M14,2.0005L8,2.0005 7,3.0005 7,6.0005 8,6.0005 8,3.0005 14,3.0005 14,6.0005 14,8.0005 10,8.0005 10,9.0005 14,9.0005 15,8.0005 15,3.0005z M9,5.0005L13,5.0005 13,4.0005 9,4.0005z M9,6.0005L10,7.0005 13,7.0005 13,6.0005z M8,8.0005L2,8.0005 2,13.0005 8,13.0005 8,11.0005z M9,8.0005L9,13.0005 8,14.0005 2,14.0005 1,13.0005 1,8.0005 2,7.0005 8,7.0005z M3,10.0005L7.001,10.0005 7.001,9.0005 3,9.0005z M3,11.0005L7.001,11.0005 7.001,12.0005 3,12.0005z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/EnumValue.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M7.5852,0.999700000000001L6.0002,2.5867 6.0002,5.9997 0.000200000000000422,5.9997 0.000200000000000422,14.9997 10.0002,14.9997 10.0002,9.9997 14.4142,9.9997 16.0002,8.4147 16.0002,2.5867 14.4142,0.999700000000001z\" />\n\t\t<GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M7,11L3,11 3,10 7,10z M2,13L8,13 8,8 2,8z M13,5L9,5 9,4 13,4z M8,3L8,6 9,6 10,6 13,6 13,7 10,7 10,8 14,8 14,6 14,3z\" />\n\t\t<GeometryDrawing Brush=\"#FF00529C\" Geometry=\"F1M8,8L2,8 2,13 8,13z M9,14L1,14 1,7 9,7z M7,10L3,10 3,11 7,11z M14,2L8,2 7,3 7,6 8,6 8,3 14,3 14,6 14,8 10,8 10,9 14,9 15,8 15,3z M9,5L13,5 13,4 9,4z M10,6L13,6 13,7 10,7z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Event.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M6.3819,-0.000199999999999534L1.9999,8.7638 1.9999,9.9998 5.3709,9.9998 2.9999,14.7648 2.9999,15.9998 5.4149,15.9998 13.9999,7.4138 13.9999,5.9998 9.4139,5.9998 13.9999,1.4138 13.9999,-0.000199999999999534z\" />\n\t\t<GeometryDrawing Brush=\"#FFC17C1A\" Geometry=\"F1M7,7L13,7 5,15 4,15 6.985,9 3,9 7,1 13,1z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/ExpandAll.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M15,10L13,10 13,12 11,12 11,14 2,14 2,5 4,5 4,3 6,3 6,1 15,1z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M9,7L4,7 4,12 9,12z M10,13L3,13 3,6 10,6z M5,4L5,5 6,5 11,5 11,10 11,11 12,11 12,4z M14,2L14,9 13,9 13,8 13,3 8,3 7,3 7,2z\" />\n\t\t<GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M8,10L7,10 7,11 6.984,11 6,11 6,10 5,10 5,9 6,9 6,8 7,8 7,9 8,9z M4,12L9,12 9,7 4,7z\" />\n\t\t<GeometryDrawing Brush=\"#FF00539C\" Geometry=\"F1M7,9L8,9 8,10 6.995,10 6.984,11 6,11 6,10 5,10 5,9 6,9 6,8 7,8z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/ExportOverlay.xaml",
    "content": "<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ClipGeometry=\"M0,0 V16 H16 V0 H0 Z\">\n\t<DrawingGroup.Transform>\n\t\t<TranslateTransform X=\"12.444443702697754\" Y=\"12.444443702697754\" />\n\t</DrawingGroup.Transform>\n\t<DrawingGroup Opacity=\"1\" Transform=\"0.5625,0,0,1,7,12.444445\">\n\t\t<GeometryDrawing Geometry=\"F1 M16,16z M0,0z M16,-12.444444L16,3.5555556 -12.444444,3.5555556 -12.444444,-12.444444z\">\n\t\t\t<GeometryDrawing.Brush>\n\t\t\t\t<SolidColorBrush Color=\"#FFF6F6F6\" Opacity=\"0\" />\n\t\t\t</GeometryDrawing.Brush>\n\t\t</GeometryDrawing>\n\t</DrawingGroup>\n\t<DrawingGroup Opacity=\"1\" Transform=\"0.5625,0,0,0.5625,7,7\">\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M5.793,0.879L8.621,3.707 7.328,5 10.5,5C13.533,5 16,7.467 16,10.5 16,13.532 13.533,16 10.5,16L9.5,16 9.5,12 10.5,12C11.327,12 12,11.327 12,10.5 12,9.673 11.327,9 10.5,9L7.328,9 8.621,10.293 5.793,13.121 0,7.328 0,6.672z\" />\n\t</DrawingGroup>\n\t<DrawingGroup Opacity=\"1\" Transform=\"0.5625,0,0,0.5625,7,7\">\n\t\t<GeometryDrawing Brush=\"#FF00539C\" Geometry=\"F1 M16,16z M0,0z M5.793,2.293L7.207,3.707 4.914,6 10.5,6C12.981,6 15,8.019 15,10.5 15,12.981 12.981,15 10.5,15L10.5,13C11.878,13 13,11.879 13,10.5 13,9.121 11.878,8 10.5,8L4.914,8 7.207,10.293 5.793,11.707 1.086,7z\" />\n\t</DrawingGroup>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/ExtensionMethod.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M0.1674,2.8564L0.1674,8.4254 5.2914,11.6534 9.7554,8.3804 9.7554,2.8684 5.0504,0.386400000000001z M9.9994,5.0004L9.9994,9.5254 9.5304,9.0554 8.0004,10.5854 8.0004,12.4744 11.5254,16.0004 12.4744,16.0004 16.0004,12.4744 16.0004,10.5854 14.4694,9.0554 14.0004,9.5254 14.0004,5.0004z\" />\n\t\t<GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M8.1904,4.4258L5.6144,5.9918 5.6144,9.4548 8.1904,7.5988z M4.9954,9.5438L4.9954,5.9708 1.7864,4.1778 1.7864,7.4968 4.9534,9.5618 4.9534,9.5768 4.9614,9.5698 4.9704,9.5768 4.9704,9.5618z M4.9954,2.1878L8.0654,3.7008 5.2014,5.4198 2.1064,3.6548z\" />\n\t\t<GeometryDrawing Brush=\"#FF642D90\" Geometry=\"F1M8.1904,7.5986L5.6144,9.4546 5.6144,5.9926 8.1904,4.4256z M4.9704,9.5616L4.9704,9.5776 4.9614,9.5696 4.9534,9.5776 4.9534,9.5616 1.7864,7.4966 1.7864,4.1776 4.9954,5.9706 4.9954,9.5436z M4.9954,2.1876L8.0654,3.7016 5.2014,5.4196 2.1064,3.6546z M8.7544,7.8736L8.7544,3.4706 5.0414,1.5116 1.1674,3.4706 1.1674,7.8736 5.2484,10.4446z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M11,7L13,7 13,6 11,6z M11,9L13,9 13,8 11,8z M11,10L11,11.939 9.53,10.469 8.47,11.531 12,15.06 15.53,11.531 14.469,10.469 13,11.939 13,10z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/Field.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M9,-0.000199999999999534L0,4.4998 0,10.7358 7,14.2358 16,9.7358 16,3.4998z\" />\n\t\t<GeometryDrawing Brush=\"#FF00529C\" Geometry=\"F1M7,6.8818L3.236,4.9998 9,2.1178 12.764,3.9998z M9,0.9998L1,4.9998 1,9.9998 7,12.9998 15,8.9998 15,3.9998z\" />\n\t\t<GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M9,2.1182L12.764,4.0002 7,6.8822 3.236,5.0002z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/FieldReadOnly.xaml",
    "content": "<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ClipGeometry=\"M0,0 V16 H16 V0 H0 Z\">\n  <GeometryDrawing Geometry=\"F1 M16,16z M0,0z M16,16L0,16 0,0 16,0 16,16z\">\n    <GeometryDrawing.Brush>\n      <SolidColorBrush Color=\"#FFF6F6F6\" Opacity=\"0\" />\n    </GeometryDrawing.Brush>\n  </GeometryDrawing>\n  <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M0,10.736L0,4.5 9,8.88178419700125E-16 16,3.5 16,9.736 7,14.236 0,10.736z\" />\n  <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1 M16,16z M0,0z M9,1L1,5 1,10 7,13 15,9 15,4 9,1z M7,6.882L3.236,5 9,2.118 12.764,4 7,6.882z\" />\n  <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1 M16,16z M0,0z M9,2.118L12.764,4 7,6.882 3.236,5 9,2.118z\" />\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/FindAssembly.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ClipGeometry=\"M0,0 V16 H16 V0 H0 Z\">\n  <GeometryDrawing Geometry=\"F1 M16,16z M0,0z M0,0L16,0 16,16 0,16z\">\n    <GeometryDrawing.Brush>\n      <SolidColorBrush Color=\"#FFF6F6F6\" Opacity=\"0\" />\n    </GeometryDrawing.Brush>\n  </GeometryDrawing>\n  <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M16,3L16,12 8,12 8,9 6,9 6,11 0,11 0,4 6,4 6,6 8,6 8,3z\" />\n  <GeometryDrawing Geometry=\"F1 M16,16z M0,0z M16,15.999054L7,15.999054 7,7 16,7z\">\n    <GeometryDrawing.Brush>\n      <SolidColorBrush Color=\"#FFF6F6F6\" Opacity=\"0\" />\n    </GeometryDrawing.Brush>\n  </GeometryDrawing>\n  <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1 M16,16z M0,0z M1,5L5,5 5,10 1,10z M9,4L15,4 15,11 9,11z M6,7L8,7 8,8 6,8z\" />\n  <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M12.71875,7C10.909188,7,9.4375,8.4719028,9.4375,10.28125A3.200625,3.2002886,0,0,0,9.8867188,11.917969L7.2460938,14.558594A0.8443125,0.84422376,0,0,0,7.2460938,15.751953A0.840375,0.84028667,0,0,0,8.4394531,15.751953L11.080078,13.111328A3.1995,3.1991637,0,0,0,12.71875,13.560547A3.285,3.2846547,0,0,0,16,10.28125C16,8.4724398,14.528313,7,12.71875,7z M12.71875,8.125A2.158875,2.1586481,0,0,1,14.875,10.28125A2.1583125,2.1580857,0,0,1,12.71875,12.4375C11.529626,12.4375 10.5625,11.469687 10.5625,10.28125 10.5625,9.0928121 11.529626,8.125 12.71875,8.125z\" />\n  <GeometryDrawing Geometry=\"F1 M16,16z M0,0z M14.875,10.280718A2.1583125,2.1580857,0,0,1,12.718937,12.436554C11.529813,12.436554 10.562875,11.469155 10.562875,10.280718 10.562875,9.0922801 11.529813,8.1248818 12.718937,8.1248818A2.158875,2.1586481,0,0,1,14.875,10.280718z\">\n    <GeometryDrawing.Brush>\n      <SolidColorBrush Color=\"#FFF0EFF1\" Opacity=\"0.75\" />\n    </GeometryDrawing.Brush>\n  </GeometryDrawing>\n  <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1 M16,16z M0,0z M12.718937,7.5624409A2.7225,2.7222139,0,0,0,9.9998125,10.280718C9.9998125,10.92865,10.237188,11.5164,10.616875,11.983789L7.644625,14.956289A0.28160528,0.28157568,0,0,0,8.042875,15.354497L11.015125,12.381997C11.483125,12.762207 12.070937,12.999557 12.718937,12.999557 14.218,12.999557 15.4375,11.780185 15.4375,10.28128 15.4375,8.7823751 14.218,7.5624409 12.718937,7.5624409z M12.718937,12.437116C11.529813,12.437116 10.562875,11.469718 10.562875,10.28128 10.562875,9.0928425 11.529813,8.1248818 12.718937,8.1248818 13.9075,8.1248818 14.875,9.0922801 14.875,10.280718 14.875,11.469155 13.9075,12.437116 12.718937,12.437116z\" />\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Folder.Closed.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M0,0L16,0 16,16 0,16z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M1.5,1L9.61,1 10.61,3 13.496,3C14.323,3,14.996,3.673,14.996,4.5L14.996,12.5C14.996,13.327,14.323,14,13.496,14L1.5,14C0.673,14,0,13.327,0,12.5L0,2.5C0,1.673,0.673,1,1.5,1\" />\n\t\t<GeometryDrawing Brush=\"#FFDCB67A\" Geometry=\"F1M2,3L8.374,3 8.874,4 2,4z M13.496,4L10,4 9.992,4 8.992,2 1.5,2C1.225,2,1,2.224,1,2.5L1,12.5C1,12.776,1.225,13,1.5,13L13.496,13C13.773,13,13.996,12.776,13.996,12.5L13.996,4.5C13.996,4.224,13.773,4,13.496,4\" />\n\t\t<GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M2,3L8.374,3 8.874,4 2,4z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/Folder.Open.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M0,0L16,0 16,16 0,16z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M0,2.9688L0,11.9688C0,12.5858 0.227,13.0718 0.57,13.4038 1.14,13.9478 2,13.9688 2,13.9688L13.677,13.9688 16,8.1648 16,6.9688 15,6.9688 15,4.9688C15,3.6698,13.97,2.9688,13,2.9688L10.116,2.9688 9.116,0.9688 2,0.9688C1.005,0.9688,0,1.6658,0,2.9688\" />\n\t\t<GeometryDrawing Brush=\"#FFDCB67A\" Geometry=\"F1M1,3L1,12C1,12.97,1.94,12.984,1.997,12.984L2,12.984 2,3 8,3 9,5 13,5 13,8 4,8 2,13 13,13 15,8 14,8 14,5C14,4,12.764,4,13,4L9.5,4 8.5,2 2,2C2,2,1,2,1,3\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/Forward.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M15,8C15,11.866 11.866,15 8,15 4.134,15 1,11.866 1,8 1,4.134 4.134,1 8,1 11.866,1 15,4.134 15,8\" />\n    <GeometryDrawing Brush=\"#FF00539C\" Geometry=\"F1M9,11L7,11 9,9 4,9 4,7 9,7 7,5 9,5 12,8z M8,2C4.755,2 2,4.756 2,8 2,11.247 4.755,14 8,14 11.245,14 14,11.247 14,8 14,4.756 11.245,2 8,2\" />\n    <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M9,11L7,11 9,9 4,9 4,7 9,7 7,5 9,5 12,8z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Header.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M1,16L15,16 15,0 1,0z\" />\n    <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M12,9L4,9 4,8 12,8z M12,11L4,11 4,10 12,10z M12,13L4,13 4,12 12,12z M13,14L3,14 3,2 13,2z M2,15L14,15 14,1 2,1z\" />\n    <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M12,3L4,3 4,6 12,6z M12,8L4,8 4,9 12,9z M12,10L4,10 4,11 12,11z M12,12L4,12 4,13 12,13z M13,14L3,14 3,2 13,2z M11,5L5,5 5,4 11,4z\" />\n    <GeometryDrawing Brush=\"#FF1BA1E2\" Geometry=\"F1M11,5L5,5 5,4 11,4z M12,3L4,3 4,6 12,6z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Heap.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M15.993,16L-0.00699999999999967,16 -0.00699999999999967,0 15.993,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M1,15L16,15 16,1 1,1z\" />\n    <GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M14,7L3,7 3,5 14,5z M14,10L3,10 3,8 14,8z M14,13L3,13 3,11 14,11z\" />\n    <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M14,7L3,7 3,5 14,5z M14,10L3,10 3,8 14,8z M14,13L3,13 3,11 14,11z M2,14L15,14 15,2 2,2z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Images.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Windows;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\n\nnamespace ICSharpCode.ILSpy\n{\n\tusing ICSharpCode.Decompiler.TypeSystem;\n\n\tstatic class Images\n\t{\n\t\tprivate static readonly Rect iconRect = new Rect(0, 0, 16, 16);\n\n\t\tstatic ImageSource Load(string icon)\n\t\t{\n\t\t\tvar image = new DrawingImage(LoadDrawingGroup(null, \"Images/\" + icon));\n\t\t\tif (image.CanFreeze)\n\t\t\t{\n\t\t\t\timage.Freeze();\n\t\t\t}\n\n\t\t\treturn image;\n\t\t}\n\n\t\tpublic static readonly ImageSource ILSpyIcon = new BitmapImage(new Uri(\"pack://application:,,,/ILSpy;component/images/ILSpy.ico\"));\n\n\t\tpublic static readonly ImageSource ViewCode = Load(\"ViewCode\");\n\t\tpublic static readonly ImageSource Save = Load(\"Save\");\n\t\tpublic static readonly ImageSource OK = Load(\"OK\");\n\n\t\tpublic static readonly ImageSource Delete = Load(\"Delete\");\n\t\tpublic static readonly ImageSource Search = Load(\"Search\");\n\n\t\tpublic static readonly ImageSource Assembly = Load(\"Assembly\");\n\t\tpublic static readonly ImageSource AssemblyWarning = Load(\"AssemblyWarning\");\n\t\tpublic static readonly ImageSource AssemblyLoading = Load(nameof(AssemblyLoading));\n\t\tpublic static readonly ImageSource FindAssembly = Load(\"FindAssembly\");\n\n\t\tpublic static readonly ImageSource Library = Load(\"Library\");\n\t\tpublic static readonly ImageSource Namespace = Load(\"Namespace\");\n\n\t\tpublic static readonly ImageSource ReferenceFolder = Load(\"ReferenceFolder\");\n\t\tpublic static readonly ImageSource NuGet = Load(null, \"Images/NuGet.png\");\n\t\tpublic static readonly ImageSource MetadataFile = Load(\"MetadataFile\");\n\t\tpublic static readonly ImageSource WebAssemblyFile = Load(\"WebAssembly\");\n\t\tpublic static readonly ImageSource ProgramDebugDatabase = Load(\"ProgramDebugDatabase\");\n\n\t\tpublic static readonly ImageSource Metadata = Load(\"Metadata\");\n\t\tpublic static readonly ImageSource Heap = Load(\"Heap\");\n\t\tpublic static readonly ImageSource Header = Load(\"Header\");\n\t\tpublic static readonly ImageSource MetadataTable = Load(\"MetadataTable\");\n\t\tpublic static readonly ImageSource MetadataTableGroup = Load(\"MetadataTableGroup\");\n\t\tpublic static readonly ImageSource ListFolder = Load(\"ListFolder\");\n\t\tpublic static readonly ImageSource ListFolderOpen = Load(\"ListFolder.Open\");\n\n\t\tpublic static readonly ImageSource SubTypes = Load(\"SubTypes\");\n\t\tpublic static readonly ImageSource SuperTypes = Load(\"SuperTypes\");\n\n\t\tpublic static readonly ImageSource FolderOpen = Load(\"Folder.Open\");\n\t\tpublic static readonly ImageSource FolderClosed = Load(\"Folder.Closed\");\n\n\t\tpublic static readonly ImageSource Resource = Load(\"Resource\");\n\t\tpublic static readonly ImageSource ResourceImage = Load(\"ResourceImage\");\n\t\tpublic static readonly ImageSource ResourceResourcesFile = Load(\"ResourceResourcesFile\");\n\t\tpublic static readonly ImageSource ResourceXml = Load(\"ResourceXml\");\n\t\tpublic static readonly ImageSource ResourceXsd = Load(\"ResourceXslt\");\n\t\tpublic static readonly ImageSource ResourceXslt = Load(\"ResourceXslt\");\n\n\t\tpublic static readonly ImageSource Class = Load(\"Class\");\n\t\tpublic static readonly ImageSource Struct = Load(\"Struct\");\n\t\tpublic static readonly ImageSource Interface = Load(\"Interface\");\n\t\tpublic static readonly ImageSource Delegate = Load(\"Delegate\");\n\t\tpublic static readonly ImageSource Enum = Load(\"Enum\");\n\t\tpublic static readonly ImageSource Type = Load(\"ShowPublicOnly\");\n\n\t\tpublic static readonly ImageSource Field = Load(\"Field\");\n\t\tpublic static readonly ImageSource FieldReadOnly = Load(\"FieldReadOnly\");\n\t\tpublic static readonly ImageSource Literal = Load(\"Literal\");\n\t\tpublic static readonly ImageSource EnumValue = Load(\"EnumValue\");\n\n\t\tpublic static readonly ImageSource Method = Load(\"Method\");\n\t\tpublic static readonly ImageSource Constructor = Load(\"Constructor\");\n\t\tpublic static readonly ImageSource VirtualMethod = Load(\"VirtualMethod\");\n\t\tpublic static readonly ImageSource Operator = Load(\"Operator\");\n\t\tpublic static readonly ImageSource ExtensionMethod = Load(\"ExtensionMethod\");\n\t\tpublic static readonly ImageSource PInvokeMethod = Load(\"PInvokeMethod\");\n\n\t\tpublic static readonly ImageSource Property = Load(\"Property\");\n\t\tpublic static readonly ImageSource Indexer = Load(\"Indexer\");\n\n\t\tpublic static readonly ImageSource Event = Load(\"Event\");\n\n\t\tprivate static readonly ImageSource OverlayProtected = Load(\"OverlayProtected\");\n\t\tprivate static readonly ImageSource OverlayInternal = Load(\"OverlayInternal\");\n\t\tprivate static readonly ImageSource OverlayProtectedInternal = Load(\"OverlayProtectedInternal\");\n\t\tprivate static readonly ImageSource OverlayPrivate = Load(\"OverlayPrivate\");\n\t\tprivate static readonly ImageSource OverlayPrivateProtected = Load(\"OverlayPrivateProtected\");\n\t\tprivate static readonly ImageSource OverlayCompilerControlled = Load(\"OverlayCompilerControlled\");\n\t\tprivate static readonly ImageSource OverlayReference = Load(\"ReferenceOverlay\");\n\n\t\tprivate static readonly ImageSource OverlayStatic = Load(\"OverlayStatic\");\n\n\t\tpublic static readonly ImageSource TypeReference = GetIcon(\"ShowPublicOnly\", \"ReferenceOverlay\");\n\t\tpublic static readonly ImageSource MethodReference = GetIcon(\"Method\", \"ReferenceOverlay\");\n\t\tpublic static readonly ImageSource FieldReference = GetIcon(\"Field\", \"ReferenceOverlay\");\n\t\tpublic static readonly ImageSource ExportedType = GetIcon(\"ShowPublicOnly\", \"ExportOverlay\");\n\n\t\tpublic static ImageSource Load(object part, string icon)\n\t\t{\n\t\t\tif (icon.EndsWith(\".png\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\treturn LoadImage(part, icon);\n\t\t\tUri uri = GetUri(part, icon + \".xaml\");\n\t\t\tif (ResourceExists(uri))\n\t\t\t{\n\t\t\t\tvar image = new DrawingImage(LoadDrawingGroup(part, icon));\n\t\t\t\tif (image.CanFreeze)\n\t\t\t\t{\n\t\t\t\t\timage.Freeze();\n\t\t\t\t}\n\t\t\t\treturn image;\n\t\t\t}\n\t\t\treturn LoadImage(part, icon + \".png\");\n\t\t}\n\n\t\tstatic BitmapImage LoadImage(object part, string icon)\n\t\t{\n\t\t\tUri uri = GetUri(part, icon);\n\t\t\tBitmapImage image = new BitmapImage(uri);\n\t\t\tif (image.CanFreeze)\n\t\t\t{\n\t\t\t\timage.Freeze();\n\t\t\t}\n\t\t\treturn image;\n\t\t}\n\n\t\tpublic static Drawing LoadDrawingGroup(object part, string icon)\n\t\t{\n\t\t\treturn (Drawing)Application.LoadComponent(GetUri(part, icon + \".xaml\", absolute: false));\n\t\t}\n\n\t\tprivate static Uri GetUri(object part, string icon, bool absolute = true)\n\t\t{\n\t\t\tUri uri;\n\t\t\tvar assembly = part?.GetType().Assembly;\n\t\t\tstring prefix;\n\t\t\tUriKind kind;\n\t\t\tif (absolute)\n\t\t\t{\n\t\t\t\tprefix = \"pack://application:,,,/\";\n\t\t\t\tkind = UriKind.Absolute;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tprefix = \"/\";\n\t\t\t\tkind = UriKind.Relative;\n\t\t\t}\n\t\t\tif (part == null || assembly == typeof(Images).Assembly)\n\t\t\t{\n\t\t\t\turi = new Uri(prefix + icon, kind);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar name = assembly.GetName();\n\t\t\t\turi = new Uri(prefix + name.Name + \";v\" + name.Version + \";component/\" + icon, kind);\n\t\t\t}\n\n\t\t\treturn uri;\n\t\t}\n\n\t\tprivate static bool ResourceExists(Uri uri)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tApplication.GetResourceStream(uri);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tcatch (IOException)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tprivate static readonly TypeIconCache typeIconCache = new TypeIconCache();\n\t\tprivate static readonly MemberIconCache memberIconCache = new MemberIconCache();\n\n\t\tpublic static ImageSource GetIcon(TypeIcon icon, AccessOverlayIcon overlay, bool isStatic = false)\n\t\t{\n\t\t\tlock (typeIconCache)\n\t\t\t\treturn typeIconCache.GetIcon(icon, overlay, isStatic);\n\t\t}\n\n\t\tpublic static ImageSource GetIcon(MemberIcon icon, AccessOverlayIcon overlay, bool isStatic)\n\t\t{\n\t\t\tlock (memberIconCache)\n\t\t\t\treturn memberIconCache.GetIcon(icon, overlay, isStatic);\n\t\t}\n\n\t\tpublic static AccessOverlayIcon GetOverlayIcon(Accessibility accessibility)\n\t\t{\n\t\t\tswitch (accessibility)\n\t\t\t{\n\t\t\t\tcase Accessibility.Public:\n\t\t\t\t\treturn AccessOverlayIcon.Public;\n\t\t\t\tcase Accessibility.Internal:\n\t\t\t\t\treturn AccessOverlayIcon.Internal;\n\t\t\t\tcase Accessibility.ProtectedAndInternal:\n\t\t\t\t\treturn AccessOverlayIcon.PrivateProtected;\n\t\t\t\tcase Accessibility.Protected:\n\t\t\t\t\treturn AccessOverlayIcon.Protected;\n\t\t\t\tcase Accessibility.ProtectedOrInternal:\n\t\t\t\t\treturn AccessOverlayIcon.ProtectedInternal;\n\t\t\t\tcase Accessibility.Private:\n\t\t\t\t\treturn AccessOverlayIcon.Private;\n\t\t\t\tdefault:\n\t\t\t\t\treturn AccessOverlayIcon.CompilerControlled;\n\t\t\t}\n\t\t}\n\n\t\tprivate static ImageSource GetIcon(string baseImage, string overlay = null, bool isStatic = false)\n\t\t{\n\t\t\tImageSource baseImageSource = Load(baseImage);\n\t\t\tImageSource overlayImageSource = overlay != null ? Load(overlay) : null;\n\n\t\t\treturn CreateOverlayImage(baseImageSource, overlayImageSource, isStatic);\n\t\t}\n\n\t\tprivate static ImageSource CreateOverlayImage(ImageSource baseImage, ImageSource overlay, bool isStatic)\n\t\t{\n\t\t\tvar group = new DrawingGroup();\n\n\t\t\tDrawing baseDrawing = new ImageDrawing(baseImage, iconRect);\n\n\t\t\tif (overlay != null)\n\t\t\t{\n\t\t\t\tvar nestedGroup = new DrawingGroup { Transform = new ScaleTransform(0.8, 0.8) };\n\t\t\t\tnestedGroup.Children.Add(baseDrawing);\n\t\t\t\tgroup.Children.Add(nestedGroup);\n\t\t\t\tgroup.Children.Add(new ImageDrawing(overlay, iconRect));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tgroup.Children.Add(baseDrawing);\n\t\t\t}\n\n\t\t\tif (isStatic)\n\t\t\t{\n\t\t\t\tgroup.Children.Add(new ImageDrawing(Images.OverlayStatic, iconRect));\n\t\t\t}\n\n\t\t\tvar image = new DrawingImage(group);\n\t\t\tif (image.CanFreeze)\n\t\t\t{\n\t\t\t\timage.Freeze();\n\t\t\t}\n\t\t\treturn image;\n\t\t}\n\n\t\t#region icon caches & overlay management\n\n\t\tprivate class TypeIconCache : IconCache<TypeIcon>\n\t\t{\n\t\t\tpublic TypeIconCache()\n\t\t\t{\n\t\t\t\tPreloadPublicIconToCache(TypeIcon.Class, Images.Class);\n\t\t\t\tPreloadPublicIconToCache(TypeIcon.Enum, Images.Enum);\n\t\t\t\tPreloadPublicIconToCache(TypeIcon.Struct, Images.Struct);\n\t\t\t\tPreloadPublicIconToCache(TypeIcon.Interface, Images.Interface);\n\t\t\t\tPreloadPublicIconToCache(TypeIcon.Delegate, Images.Delegate);\n\t\t\t}\n\n\t\t\tprotected override ImageSource GetBaseImage(TypeIcon icon)\n\t\t\t{\n\t\t\t\tImageSource baseImage;\n\t\t\t\tswitch (icon)\n\t\t\t\t{\n\t\t\t\t\tcase TypeIcon.Class:\n\t\t\t\t\t\tbaseImage = Images.Class;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeIcon.Enum:\n\t\t\t\t\t\tbaseImage = Images.Enum;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeIcon.Struct:\n\t\t\t\t\t\tbaseImage = Images.Struct;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeIcon.Interface:\n\t\t\t\t\t\tbaseImage = Images.Interface;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase TypeIcon.Delegate:\n\t\t\t\t\t\tbaseImage = Images.Delegate;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(icon), $\"TypeIcon.{icon} is not supported!\");\n\t\t\t\t}\n\n\t\t\t\treturn baseImage;\n\t\t\t}\n\t\t}\n\n\t\tprivate class MemberIconCache : IconCache<MemberIcon>\n\t\t{\n\t\t\tpublic MemberIconCache()\n\t\t\t{\n\t\t\t\tPreloadPublicIconToCache(MemberIcon.Field, Images.Field);\n\t\t\t\tPreloadPublicIconToCache(MemberIcon.FieldReadOnly, Images.FieldReadOnly);\n\t\t\t\tPreloadPublicIconToCache(MemberIcon.Literal, Images.Literal);\n\t\t\t\tPreloadPublicIconToCache(MemberIcon.EnumValue, Images.EnumValue);\n\t\t\t\tPreloadPublicIconToCache(MemberIcon.Property, Images.Property);\n\t\t\t\tPreloadPublicIconToCache(MemberIcon.Indexer, Images.Indexer);\n\t\t\t\tPreloadPublicIconToCache(MemberIcon.Method, Images.Method);\n\t\t\t\tPreloadPublicIconToCache(MemberIcon.Constructor, Images.Constructor);\n\t\t\t\tPreloadPublicIconToCache(MemberIcon.VirtualMethod, Images.VirtualMethod);\n\t\t\t\tPreloadPublicIconToCache(MemberIcon.Operator, Images.Operator);\n\t\t\t\tPreloadPublicIconToCache(MemberIcon.ExtensionMethod, Images.ExtensionMethod);\n\t\t\t\tPreloadPublicIconToCache(MemberIcon.PInvokeMethod, Images.PInvokeMethod);\n\t\t\t\tPreloadPublicIconToCache(MemberIcon.Event, Images.Event);\n\t\t\t}\n\n\t\t\tprotected override ImageSource GetBaseImage(MemberIcon icon)\n\t\t\t{\n\t\t\t\tImageSource baseImage;\n\t\t\t\tswitch (icon)\n\t\t\t\t{\n\t\t\t\t\tcase MemberIcon.Field:\n\t\t\t\t\t\tbaseImage = Images.Field;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MemberIcon.FieldReadOnly:\n\t\t\t\t\t\tbaseImage = Images.FieldReadOnly;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MemberIcon.Literal:\n\t\t\t\t\t\tbaseImage = Images.Literal;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MemberIcon.EnumValue:\n\t\t\t\t\t\tbaseImage = Images.EnumValue;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MemberIcon.Property:\n\t\t\t\t\t\tbaseImage = Images.Property;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MemberIcon.Indexer:\n\t\t\t\t\t\tbaseImage = Images.Indexer;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MemberIcon.Method:\n\t\t\t\t\t\tbaseImage = Images.Method;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MemberIcon.Constructor:\n\t\t\t\t\t\tbaseImage = Images.Constructor;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MemberIcon.VirtualMethod:\n\t\t\t\t\t\tbaseImage = Images.VirtualMethod;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MemberIcon.Operator:\n\t\t\t\t\t\tbaseImage = Images.Operator;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MemberIcon.ExtensionMethod:\n\t\t\t\t\t\tbaseImage = Images.ExtensionMethod;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MemberIcon.PInvokeMethod:\n\t\t\t\t\t\tbaseImage = Images.PInvokeMethod;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MemberIcon.Event:\n\t\t\t\t\t\tbaseImage = Images.Event;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(icon), $\"MemberIcon.{icon} is not supported!\");\n\t\t\t\t}\n\n\t\t\t\treturn baseImage;\n\t\t\t}\n\t\t}\n\n\t\tprivate abstract class IconCache<T>\n\t\t{\n\t\t\tprivate readonly Dictionary<(T, AccessOverlayIcon, bool), ImageSource> cache = new Dictionary<(T, AccessOverlayIcon, bool), ImageSource>();\n\n\t\t\tprotected void PreloadPublicIconToCache(T icon, ImageSource image)\n\t\t\t{\n\t\t\t\tvar iconKey = (icon, AccessOverlayIcon.Public, false);\n\t\t\t\tcache.Add(iconKey, image);\n\t\t\t}\n\n\t\t\tpublic ImageSource GetIcon(T icon, AccessOverlayIcon overlay, bool isStatic)\n\t\t\t{\n\t\t\t\tvar iconKey = (icon, overlay, isStatic);\n\t\t\t\tif (cache.ContainsKey(iconKey))\n\t\t\t\t{\n\t\t\t\t\treturn cache[iconKey];\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tImageSource result = BuildMemberIcon(icon, overlay, isStatic);\n\t\t\t\t\tcache.Add(iconKey, result);\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tprivate ImageSource BuildMemberIcon(T icon, AccessOverlayIcon overlay, bool isStatic)\n\t\t\t{\n\t\t\t\tImageSource baseImage = GetBaseImage(icon);\n\t\t\t\tImageSource overlayImage = GetOverlayImage(overlay);\n\n\t\t\t\treturn CreateOverlayImage(baseImage, overlayImage, isStatic);\n\t\t\t}\n\n\t\t\tprotected abstract ImageSource GetBaseImage(T icon);\n\n\t\t\tprivate static ImageSource GetOverlayImage(AccessOverlayIcon overlay)\n\t\t\t{\n\t\t\t\tImageSource overlayImage;\n\t\t\t\tswitch (overlay)\n\t\t\t\t{\n\t\t\t\t\tcase AccessOverlayIcon.Public:\n\t\t\t\t\t\toverlayImage = null;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AccessOverlayIcon.Protected:\n\t\t\t\t\t\toverlayImage = Images.OverlayProtected;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AccessOverlayIcon.Internal:\n\t\t\t\t\t\toverlayImage = Images.OverlayInternal;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AccessOverlayIcon.ProtectedInternal:\n\t\t\t\t\t\toverlayImage = Images.OverlayProtectedInternal;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AccessOverlayIcon.Private:\n\t\t\t\t\t\toverlayImage = Images.OverlayPrivate;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AccessOverlayIcon.PrivateProtected:\n\t\t\t\t\t\toverlayImage = Images.OverlayPrivateProtected;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AccessOverlayIcon.CompilerControlled:\n\t\t\t\t\t\toverlayImage = Images.OverlayCompilerControlled;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new ArgumentOutOfRangeException(nameof(overlay), $\"AccessOverlayIcon.{overlay} is not supported!\");\n\t\t\t\t}\n\t\t\t\treturn overlayImage;\n\t\t\t}\n\t\t}\n\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Images/Indexer.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M10.9998,0.999700000000001L10.9998,4.0007 12.9998,4.0007 12.9998,12.0007 10.9998,12.0007 10.9998,14.9997 15.9998,14.9997 15.9998,0.999700000000001z M-0.000199999999999534,0.999700000000001L-0.000199999999999534,14.9997 5.0008,14.9997 5.0008,12.0007 2.9998,12.0007 2.9998,4.0007 5.0008,4.0007 5.0008,0.999700000000001z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M15,2L12,2 12,3 14,3 14,13 12,13 12,14 15,14z M4,14L1,14 1,2 4,2 4,3 2,3 2,13 4,13z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/Interface.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M11.5,12C9.585,12,7.898,10.759,7.272,9L5.862,9C5.326,9.985 4.29,10.625 3.125,10.625 1.402,10.625 0,9.223 0,7.5 0,5.777 1.402,4.375 3.125,4.375 4.29,4.375 5.326,5.014 5.862,6L7.272,6C7.898,4.241 9.585,3 11.5,3 13.981,3 16,5.019 16,7.5 16,9.981 13.981,12 11.5,12\" />\n    <GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M11.5,9C10.673,9 10,8.326 10,7.5 10,6.672 10.673,6 11.5,6 12.327,6 13,6.672 13,7.5 13,8.326 12.327,9 11.5,9\" />\n    <GeometryDrawing Brush=\"#FF00529C\" Geometry=\"F1M11.5,9C10.673,9 10,8.327 10,7.5 10,6.673 10.673,6 11.5,6 12.327,6 13,6.673 13,7.5 13,8.327 12.327,9 11.5,9 M11.5,4C9.738,4,8.295,5.306,8.05,7L5.185,7C4.959,6.069 4.125,5.375 3.125,5.375 1.951,5.375 1,6.326 1,7.5 1,8.674 1.951,9.625 3.125,9.625 4.125,9.625 4.959,8.931 5.185,8L8.05,8C8.295,9.694 9.738,11 11.5,11 13.433,11 15,9.433 15,7.5 15,5.567 13.433,4 11.5,4\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Library.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M5.0004,0.999700000000001L5.0004,1.9997 0.000399999999999956,1.9997 0.000399999999999956,14.9997 16.0004,14.9997 16.0004,1.9997 10.9994,1.9997 10.9994,0.999700000000001z\" />\n\t\t<GeometryDrawing Brush=\"#FF414141\" Geometry=\"F1M14,6L12,6 12,4 14,4z M14,11L12,11 12,10 14,10z M14,13L12,13 12,12 14,12z M11,14L15,14 15,3 11,3z\" />\n\t\t<GeometryDrawing Brush=\"#FF414141\" Geometry=\"F1M7,12L9,12 9,13 7,13z M7,10L9,10 9,11 7,11z M7,3L9,3 9,4 7,4z M6,14L10,14 10,2 6,2z\" />\n\t\t<GeometryDrawing Brush=\"#FF414141\" Geometry=\"F1M2,12L4,12 4,13 2,13z M2,10L4,10 4,11 2,11z M2,4L4,4 4,6 2,6z M1,14L5,14 5,3 1,3z\" />\n\t\t<GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M4,4L2,4 2,6 4,6z M4,10L2,10 2,11 4,11z M4,12L2,12 2,13 4,13z M9,3L7,3 7,4 9,4z M9,10L7,10 7,11 9,11z M9,12L7,12 7,13 9,13z M14,4L12,4 12,6 14,6z M14,10L12,10 12,11 14,11z M14,13L12,13 12,12 14,12z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/ListFolder.Open.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M0,0L16,0 16,16 0,16z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M16,6.9688L16,6.9998 16,8.1648 16,15.9998 5,15.9998 5,13.9688 2,13.9688C2,13.9688 1.14,13.9478 0.57,13.4038 0.227,13.0718 0,12.5858 0,11.9688L0,2.9688C0,1.6658,1.005,0.9688,2,0.9688L9.116,0.9688 10.116,2.9688 13,2.9688C13.97,2.9688,15,3.6698,15,4.9688L15,6.9688z\" />\n    <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M9,10L14,10 14,9 9,9z M9,12L14,12 14,11 9,11z M9,14L14,14 14,13 9,13z M7,14L8,14 8,13 7,13z M7,12L8,12 8,11 7,11z M7,9L8,9 8,10 7,10z\" />\n    <GeometryDrawing Brush=\"#FFDCB67A\" Geometry=\"F1M2,3L8,3 9,5 13,5 13,7 14,7 14,5C14,4,12.764,4,13,4L9.5,4 8.5,2 2,2C2,2,1,2,1,3L1,12C1,12.97,1.94,12.984,1.997,12.984L2,12.984z\" />\n    <GeometryDrawing Brush=\"#FFDCB67A\" Geometry=\"F1M5,8L4,8 2,13 5,13z\" />\n    <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M14,10L9,10 9,9 14,9z M14,12L9,12 9,11 14,11z M14,14L9,14 9,13 14,13z M7,13L8,13 8,14 7,14z M7,11L8,11 8,12 7,12z M7,9L8,9 8,10 7,10z M6,15L15,15 15,8 6,8z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/ListFolder.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M0,0L16,0 16,16 0,16z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M14.9961,4.5L14.9961,12.5C14.9961,13.327,14.3231,14,13.4961,14L11.0001,14 11.0001,16 9.99999999997669E-05,16 9.99999999997669E-05,12.5 9.99999999997669E-05,7 9.99999999997669E-05,2.5C9.99999999997669E-05,1.673,0.6731,1,1.5001,1L9.6101,1 10.6101,3 13.4961,3C14.3231,3,14.9961,3.673,14.9961,4.5\" />\n    <GeometryDrawing Brush=\"#FFDCB67A\" Geometry=\"F1M2,4L2,3 8.374,3 8.874,4z M13.496,4L10,4 9.992,4 8.992,2 1.5,2C1.225,2,1,2.224,1,2.5L1,7 11,7 11,13 13.496,13C13.773,13,13.996,12.776,13.996,12.5L13.996,4.5C13.996,4.224,13.773,4,13.496,4\" />\n    <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M9,10L4,10 4,9 9,9z M9,12L4,12 4,11 9,11z M9,14L4,14 4,13 9,13z M2,13L3,13 3,14 2,14z M2,11L3,11 3,12 2,12z M2,9L3,9 3,10 2,10z M1,15L10,15 10,8 1,8z\" />\n    <GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M2,3L8.374,3 8.874,4 2,4z M9,10L4,10 4,9 9,9z M9,12L4,12 4,11 9,11z M9,14L4,14 4,13 9,13z M2,13L3,13 3,14 2,14z M2,11L3,11 3,12 2,12z M2,9L3,9 3,10 2,10z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Literal.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M0.9999,-0.000199999999999534L0.9999,5.9998 -9.9999999999989E-05,5.9998 -9.9999999999989E-05,15.9998 8.9999,15.9998 8.9999,13.9998 15.9999,13.9998 15.9999,-0.000199999999999534z\" />\n\t\t<GeometryDrawing Brush=\"#FF414141\" Geometry=\"F1M14,12L8,12 8,7 3,7 3,2 14,2z M7,14L2,14 2,8 7,8z M2,1L2,7 1,7 1,15 8,15 8,13 15,13 15,1z\" />\n\t\t<GeometryDrawing Brush=\"#FF414141\" Geometry=\"F1M4.6016,12.2578C4.5126,12.3248 4.3886,12.3298 4.2646,12.3298 4.1746,12.3298 4.0946,12.3168 4.0226,12.2888 3.9496,12.2618 3.8876,12.2248 3.8366,12.1758 3.7876,12.1288 3.7476,12.0698 3.7206,12.0038 3.6936,11.9358 3.6796,11.8628 3.6796,11.7848 3.6796,11.6988 3.6896,11.6208 3.7066,11.5528 3.7246,11.4848 3.7576,11.4258 3.8046,11.3728 3.8526,11.3198 3.9166,11.2758 3.9996,11.2398 4.0826,11.2068 4.1896,11.1798 4.3206,11.1618L5.0186,11.0528 5.0186,11.3988C5.0186,11.3988,4.9216,12.0158,4.6016,12.2578 M5.5276,9.3788C5.4156,9.2498 5.2746,9.1528 5.1036,9.0838 4.9326,9.0158 4.7296,8.9828 4.4956,8.9828 4.3756,8.9828 4.2536,8.9938 4.1266,9.0158 4.0006,9.0388 3.8786,9.0668 3.7646,9.1018 3.6516,9.1348 3.5476,9.1718 3.4556,9.2108 3.3636,9.2518 3.2926,9.2888 3.2426,9.3238L3.2426,10.0918C3.4006,9.9608 3.5826,9.8578 3.7866,9.7788 3.9906,9.7008 4.1996,9.6618 4.4136,9.6618 4.6256,9.6618 4.7896,9.7248 4.9076,9.8478 5.0236,9.9728 5.0806,10.1718 5.0806,10.4468L4.0506,10.6018C3.8466,10.6288 3.6716,10.6798 3.5256,10.7538 3.3796,10.8278 3.2606,10.9198 3.1676,11.0328 3.0746,11.1448 3.0066,11.2718 2.9626,11.4138 2.9186,11.5568 2.8976,11.7108 2.8976,11.8748 2.8976,12.0448 2.9226,12.1968 2.9716,12.3378 3.0206,12.4788 3.0926,12.5978 3.1876,12.6988 3.2806,12.7988 3.3976,12.8768 3.5386,12.9338 3.6786,12.9898 3.8366,13.0178 4.0176,13.0178 4.2476,13.0178 4.4486,12.9648 4.6216,12.8578 4.7936,12.7518 4.9406,12.5978 5.0606,12.3948L5.0066,12.4618 5.0066,12.9908 5.8596,12.9998 5.8596,10.4868C5.8596,10.2478 5.8316,10.0348 5.7766,9.8498 5.7216,9.6658 5.6376,9.5078 5.5276,9.3788\" />\n\t\t<GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M3,2L3,7 8,7 8,12 14,12 14,2z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/MemberIcon.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.ILSpy\n{\n\tinternal enum MemberIcon\n\t{\n\t\tLiteral,\n\t\tFieldReadOnly,\n\t\tField,\n\t\tEnumValue,\n\t\tProperty,\n\t\tIndexer,\n\t\tMethod,\n\t\tConstructor,\n\t\tVirtualMethod,\n\t\tOperator,\n\t\tExtensionMethod,\n\t\tPInvokeMethod,\n\t\tEvent\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Images/Metadata.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M7.6977,-0.000199999999999534L0.9997,4.4648 0.9997,11.5348 7.6977,15.9998 8.3027,15.9998 15.0007,11.5348 15.0007,4.4648 8.3027,-0.000199999999999534z\" />\n    <GeometryDrawing Brush=\"#FF414141\" Geometry=\"F1M13,7.7324L8.5,10.7324 8.5,9.2674 13,6.2674z M13,10.4644L8.5,13.4644 8.5,11.9344 13,8.9344z M3.353,5.3004L5.201,4.0684 9.854,7.1624 8,8.3984z M7.5,10.7324L3,7.7324 3,6.2674 7.5,9.2674z M7.5,13.4644L3,10.4644 3,8.9344 7.5,11.9344z M8,2.2014L12.647,5.3004 10.756,6.5614 6.102,3.4664z M8,1.0004L2,5.0004 2,11.0004 8,15.0004 14,11.0004 14,5.0004z\" />\n    <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M8,2.2012L12.647,5.3012 10.756,6.5612 6.102,3.4672z\" />\n    <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M7.5,13.4648L3,10.4648 3,8.9348 7.5,11.9348z\" />\n    <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M7.5,10.7324L3,7.7324 3,6.2674 7.5,9.2674z\" />\n    <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M3.3525,5.3008L5.2015,4.0688 9.8545,7.1618 7.9995,8.3988z\" />\n    <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M13,10.4648L8.5,13.4648 8.5,11.9348 13,8.9348z\" />\n    <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M13,7.7324L8.5,10.7324 8.5,9.2674 13,6.2674z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/MetadataFile.xaml",
    "content": "<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ClipGeometry=\"M0,0 V16 H16 V0 H0 Z\">\n  <DrawingGroup Opacity=\"1\">\n    <GeometryDrawing Geometry=\"F1 M16,16z M0,0z M0,0L16,0 16,16 0,16z\">\n      <GeometryDrawing.Brush>\n        <SolidColorBrush Color=\"#FFF6F6F6\" Opacity=\"0\" />\n      </GeometryDrawing.Brush>\n    </GeometryDrawing>\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M10.023,1L3.964,1C3.012,1,2,1.701,2,3L2,8.556C0.81,9.25 0,10.525 0,12 0,14.206 1.794,16 4,16A3.971,3.971,0,0,0,6.618,15L11.965,15C13.407,15,13.972,13.825,14,13L14,4.552z\" />\n  </DrawingGroup>\n  <DrawingGroup Opacity=\"1\">\n    <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1 M16,16z M0,0z M6,6L8,6 8,7 6,7z M6,8L6,8.555C6.222,8.684,6.428,8.832,6.62,9L10,9 10,8z M7.858,11L10,11 10,10 7.445,10C7.626,10.311,7.766,10.644,7.858,11z\" />\n    <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1 M16,16z M0,0z M9.641,2L3.964,2C3.964,2,3,2,3,3L3,8.142A3.978,3.978,0,0,1,4,8L4,3 9,3 9,6 12,6 12,13 7.858,13A3.945,3.945,0,0,1,7.444,14L11.965,14C12.965,14,13,13,13,13L13,5z\" />\n  </DrawingGroup>\n  <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1 M16,16z M0,0z M9,6L9,3 4,3 4,8C4.735,8,5.417,8.213,6.009,8.562L6,8.555 6,8 10,8 10,9 6.62,9C6.615,8.995 6.608,8.992 6.602,8.987 6.946,9.285 7.235,9.636 7.462,10.034 7.456,10.023 7.452,10.011 7.445,10L10,10 10,11 7.858,11 7.853,10.983C7.939,11.311 8,11.646 8,12 8,12.348 7.941,12.679 7.858,13L12,13 12,6 9,6z M8,7L6,7 6,6 8,6 8,7z\" />\n  <DrawingGroup Opacity=\"1\" Transform=\"0.5,0,0,0.5,0,8\">\n    <DrawingGroup Opacity=\"1\">\n      <GeometryDrawing Geometry=\"F1 M16,16z M0,0z M0,0L16,0 16,16 0,16z\">\n        <GeometryDrawing.Brush>\n          <SolidColorBrush Color=\"#FFF6F6F6\" Opacity=\"0\" />\n        </GeometryDrawing.Brush>\n      </GeometryDrawing>\n      <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M15,4.465L15,11.535 8.303,16 7.697,16 1,11.535 1,4.465 7.697,0 8.302,0z\" />\n    </DrawingGroup>\n    <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1 M16,16z M0,0z M8,1L2,5 2,11 8,15 14,11 14,5z M8,2.201L12.648,5.301 10.756,6.562 6.102,3.467z M7.5,13.465L3,10.465 3,8.935 7.5,11.935z M7.5,10.732L3,7.732 3,6.268 7.5,9.268z M3.353,5.301L5.202,4.069 9.855,7.163 8,8.398z M13,10.465L8.5,13.465 8.5,11.935 13,8.935z M13,7.732L8.5,10.732 8.5,9.268 13,6.268z\" />\n    <DrawingGroup Opacity=\"1\">\n      <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1 M16,16z M0,0z M8,2.201L12.648,5.301 10.756,6.562 6.102,3.467z M7.5,13.465L3,10.465 3,8.935 7.5,11.935z M7.5,10.732L3,7.732 3,6.268 7.5,9.268z M3.353,5.301L5.201,4.068 9.854,7.162 8,8.398z M13,10.465L8.5,13.465 8.5,11.935 13,8.935z M13,7.732L8.5,10.732 8.5,9.268 13,6.268z\" />\n    </DrawingGroup>\n  </DrawingGroup>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/MetadataTable.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M16,1L16,15 11.22,15C10.67,15.609,9.883,16,9,16L5,16C4.116,16,3.326,15.61,2.776,15L1,15 1,13.204C0.378,12.643 0,11.851 0,11 0,10.117 0.391,9.33 1,8.78L1,1z\" />\n    <GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M11,10L14,10 14,8 11,8z M12,13L14,13 14,11 11.202,11C11.699,11.544,12,12.249,12,13 M11,7L14,7 14,5 11,5z M3,7L6,7 6,5 3,5z M7,7L10,7 10,5 7,5z M7,8L10,8 10,10 9.826,10C9.412,8.837,8.303,8,7,8\" />\n    <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M3,10L7,10C7.552,10 8,10.449 8,11 8,11.551 7.552,12 7,12L6,13 7,13C8.103,13 9,12.104 9,11 9,9.896 8.103,9 7,9L3,9C1.897,9 1,9.896 1,11 1,11.748 1.417,12.394 2.027,12.736 2.059,12.372 2.15,12.027 2.302,11.713 2.116,11.531 2,11.279 2,11 2,10.449 2.449,10 3,10 M9.974,11.264C9.941,11.628 9.85,11.973 9.698,12.287 9.884,12.469 10,12.721 10,13 10,13.552 9.552,14 9,14L5,14C4.449,14 4,13.552 4,13 4,12.449 4.449,12 5,12L6,11 5,11C3.897,11 3,11.896 3,13 3,14.103 3.897,15 5,15L9,15C10.103,15 11,14.103 11,13 11,12.252 10.583,11.606 9.974,11.264 M14,5L11,5 11,7 14,7z M14,8L11,8 11,10 14,10z M10,5L7,5 7,7 10,7z M6,5L3,5 3,7 6,7z M15,2L15,14 11.815,14C11.928,13.686,12,13.353,12,13L14,13 14,11 11.202,11C10.988,10.766,10.75,10.553,10.465,10.393L9.844,10.043C9.839,10.027,9.831,10.015,9.826,10L10,10 10,8 7,8 6,8 3,8C2.647,8,2.314,8.072,2,8.184L2,2z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/MetadataTableGroup.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M2.9997,-0.000199999999999534L2.9997,3.0008 -0.000300000000000189,3.0008 -0.000300000000000189,13.0008 3.9997,13.0008 3.9997,15.9998 16.0007,15.9998 16.0007,5.9998 15.0007,5.9998 15.0007,-0.000199999999999534z\" />\n    <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M14,9L12,9 12,10 14,10z M14,11L12,11 12,12 14,12z M14,13L12,13 12,14 14,14z M11,9L9,9 9,10 11,10z M11,11L9,11 9,12 11,12z M11,13L9,13 9,14 11,14z M8,9L6,9 6,10 8,10z M8,11L6,11 6,12 8,12z M8,13L6,13 6,14 8,14z M15,15L5,15 5,7 15,7z M13,4L12,4 12,5 13,5 13,6 14,6 14,1 4,1 4,3 13,3z M2,7L4,7 4,8 2,8 2,9 4,9 4,10 2,10 2,11 4,11 4,12 1,12 1,4 11,4 11,6 2,6z\" />\n    <GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M9,10L11,10 11,9 9,9z M9,12L11,12 11,11 9,11z M12,12L14,12 14,11 12,11z M12,10L14,10 14,9 12,9z M12,14L14,14 14,13 12,13z M6,10L8,10 8,9 6,9z M9,14L11,14 11,13 9,13z M6,12L8,12 8,11 6,11z M2,11L4,11 4,10 2,10z M13,3L12,3 12,4 13,4z M13,5L12,5 12,6 13,6z M6,14L8,14 8,13 6,13z M2,9L4,9 4,8 2,8z M2,6L4,6 4,7 2,7z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Method.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M7.5951,-0.000199999999999534L1.0001,3.3268 1.0001,11.5818 8.0701,15.9998 8.9751,15.9998 15.0001,11.7518 15.0001,3.3488 8.7131,-0.000199999999999534z\" />\n\t\t<GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M9,13.5361L9,7.8781 13,5.3981 13,10.7161z M3,5.1021L8,7.8941 8,13.5981 3,10.4731z M12.715,4.3981L8.487,7.0201 3.565,4.2721 8.144,1.9631z\" />\n\t\t<GeometryDrawing Brush=\"#FF642D90\" Geometry=\"F1M1.9998,3.9427L1.9998,11.0277 8.5168,15.0997 14.0008,11.2337 14.0008,3.9497 8.1558,0.8367z M3.5658,4.2717L8.1428,1.9627 12.7148,4.3977 8.4868,7.0197z M2.9998,10.4727L2.9998,5.1017 7.9998,7.8937 7.9998,13.5977z M8.9998,7.8787L12.9998,5.3977 12.9998,10.7157 8.9998,13.5357z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/Namespace.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M5.7388,15.0156C2.6498,14.9806,2.3168,12.8516,2.3168,11.9376L2.3168,9.9206C2.3168,9.5936,2.2498,9.4896,2.2498,9.4886L1.3128,9.4286 1.2498,8.4986 1.2498,6.5626C1.2498,6.5626 2.1898,6.5036 2.1918,6.5036 2.2498,6.5036 2.3168,6.3896 2.3168,6.0516L2.3168,4.0896C2.3168,2.1406,3.5638,1.0086,5.7388,0.984599999999999L6.7498,0.973599999999999 6.7498,4.0196 5.7748,4.0436C5.7298,4.0446 5.6998,4.0486 5.6818,4.0526 5.6878,4.0746 5.6628,4.1676 5.6628,4.3496L5.6628,6.2776C5.6628,6.9526 5.4778,7.5306 5.1298,7.9816 5.4778,8.4316 5.6628,9.0096 5.6628,9.6886L5.6628,11.5956C5.6628,11.7706 5.6768,11.8866 5.6898,11.9586 5.7128,11.9606 6.7498,11.9846 6.7498,11.9846L6.7498,15.0276z M9.2598,11.9846L10.2378,11.9626C10.2738,11.9616 10.3038,11.9596 10.3268,11.9566 10.3378,11.8936 10.3538,11.7786 10.3538,11.5956L10.3538,9.6886C10.3538,9.0096 10.5378,8.4316 10.8838,7.9816 10.5378,7.5306 10.3538,6.9526 10.3538,6.2776L10.3538,4.3496C10.3538,4.1826 10.3328,4.0906 10.3198,4.0476 10.3178,4.0476 9.2598,4.0196 9.2598,4.0196L9.2598,0.973599999999999 10.2708,0.984599999999999C12.4378,1.0086,13.6798,2.1406,13.6798,4.0896L13.6798,6.0516C13.6798,6.4026,13.7508,6.5136,13.7518,6.5146L14.6878,6.5746 14.7398,7.5006 14.7398,9.4366 13.8048,9.4966C13.7288,9.5126,13.6798,9.6436,13.6798,9.9206L13.6798,11.9376C13.6798,12.8516,13.3478,14.9806,10.2718,15.0156L9.2598,15.0276z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M13.7397,8.499C13.0337,8.544,12.6797,9.019,12.6797,9.921L12.6797,11.937C12.6797,13.305,11.8737,13.997,10.2607,14.016L10.2607,12.963C10.6567,12.954 10.9377,12.845 11.1037,12.635 11.2707,12.425 11.3537,12.079 11.3537,11.596L11.3537,9.688C11.3537,8.763,11.8027,8.201,12.7007,8L12.7007,7.979C11.8027,7.765,11.3537,7.198,11.3537,6.277L11.3537,4.35C11.3537,3.498,10.9897,3.062,10.2607,3.044L10.2607,1.984C11.8737,2.002,12.6797,2.705,12.6797,4.09L12.6797,6.052C12.6797,6.972,13.0337,7.456,13.7397,7.501z M5.7497,14.016C4.1277,13.997,3.3167,13.305,3.3167,11.937L3.3167,9.921C3.3167,9.019,2.9607,8.544,2.2497,8.499L2.2497,7.501C2.9607,7.456,3.3167,6.972,3.3167,6.052L3.3167,4.09C3.3167,2.705,4.1277,2.002,5.7497,1.984L5.7497,3.044C5.0257,3.062,4.6627,3.498,4.6627,4.35L4.6627,6.277C4.6627,7.198,4.2097,7.765,3.3027,7.979L3.3027,8C4.2097,8.201,4.6627,8.763,4.6627,9.688L4.6627,11.596C4.6627,12.083 4.7437,12.431 4.9057,12.638 5.0677,12.846 5.3487,12.954 5.7497,12.963z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/OK.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M8,16C3.589,16 0,12.411 0,8 0,3.589 3.589,0 8,0 12.411,0 16,3.589 16,8 16,12.411 12.411,16 8,16\" />\n    <GeometryDrawing Brush=\"#FF329932\" Geometry=\"F1M6.2998,12.3887L3.0428,9.1317 4.4568,7.7177 6.2998,9.5607 11.5428,4.3177 12.9568,5.7317z M7.9998,0.999700000000001C4.1338,0.999700000000001 0.9998,4.1337 0.9998,7.9997 0.9998,11.8657 4.1338,14.9997 7.9998,14.9997 11.8658,14.9997 14.9998,11.8657 14.9998,7.9997 14.9998,4.1337 11.8658,0.999700000000001 7.9998,0.999700000000001\" />\n    <GeometryDrawing Brush=\"#FFFFFFFF\" Geometry=\"F1M6.2998,12.3887L3.0428,9.1317 4.4568,7.7177 6.2998,9.5607 11.5428,4.3177 12.9568,5.7317z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Open.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M16,9L16,10.196 13.677,16 2,16C2,16 1.14,15.979 0.57,15.435 0.227,15.103 0,14.617 0,14L0,5C0,3.697,1.005,3,2,3L4.486,3 3.607,2.121 5.729,0 10.246,4.518 9.999,4.765 10.116,5 13,5C13.97,5,15,5.701,15,7L15,9z\" />\n    <GeometryDrawing Brush=\"#FFDCB67A\" Geometry=\"F1M14,10.0313L14,7.0313C14,6.0313,12.764,6.0313,13,6.0313L9.5,6.0313 9.244,5.5193 8.578,6.1863 9,7.0313 13,7.0313 13,10.0313 4,10.0313 2,15.0313 13,15.0313 15,10.0313z M2,15.0153L1.997,15.0153C1.94,15.0153,1,15.0013,1,14.0313L1,8.9593C1.286,9.2523,1.626,9.4873,2,9.6663z\" />\n    <GeometryDrawing Brush=\"#FF00529C\" Geometry=\"F1M8.832,4.5176L5.728,7.6216 5.021,6.9136 6.918,5.0176 3.5,5.0176C2.673,5.0176 2,5.6906 2,6.5176 2,7.3446 2.673,8.0176 3.5,8.0176L3.5,9.0176C2.122,9.0176 1,7.8966 1,6.5176 1,5.1396 2.122,4.0176 3.5,4.0176L6.918,4.0176 5.021,2.1216 5.728,1.4136z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Operator.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M0,16L16,16 16,0 0,0z\" />\n\t\t<GeometryDrawing Brush=\"#FF00529C\" Geometry=\"F1M14,5L9,5 9,4 14,4z M10.281,13L8.719,13 11.719,9 13.281,9z M7,5L5,5 5,7 4,7 4,5 2,5 2,4 4,4 4,2 5,2 5,4 7,4z M7,10L3,10 3,9 7,9z M7,13L3,13 3,12 7,12z M1,15L15,15 15,1 1,1z\" />\n\t\t<GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M10.2812,13L13.2812,9 11.7182,9 8.7192,13z M7.0002,12L3.0002,12 3.0002,13 7.0002,13z M7.0002,9L3.0002,9 3.0002,10 7.0002,10z M14.0002,4L9.0002,4 9.0002,5 14.0002,5z M7.0002,5L5.0002,5 5.0002,7 4.0002,7 4.0002,5 2.0002,5 2.0002,4 4.0002,4 4.0002,2 5.0002,2 5.0002,4 7.0002,4z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/OverlayCompilerControlled.xaml",
    "content": "<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ClipGeometry=\"M0,0 V16 H16 V0 H0 Z\">\n  <GeometryDrawing Geometry=\"F1 M16,16z M0,0z M16.016949,16L9.0169494,16 9.0169494,9 16.016949,9z\">\n    <GeometryDrawing.Brush>\n      <SolidColorBrush Color=\"#FFF6F6F6\" Opacity=\"0\" />\n    </GeometryDrawing.Brush>\n  </GeometryDrawing>\n  <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M9.0169494,12.5C9.0169494,10.567125 10.584082,9 12.516949,9 14.449832,9 16.016949,10.567125 16.016949,12.5 16.016949,14.432875 14.449832,16 12.516949,16 10.584082,16 9.0169494,14.432875 9.0169494,12.5z\" />\n  <GeometryDrawing Brush=\"#FFE51400\" Geometry=\"F1 M16,16z M0,0z M12.516949,9.4375003C10.826015,9.4375003 9.4544494,10.808625 9.4544494,12.5 9.4544494,14.190937 10.826015,15.5625 12.516949,15.5625 14.207883,15.5625 15.579449,14.190937 15.579449,12.5 15.579449,10.808625 14.207883,9.4375003 12.516949,9.4375003z M10.329449,12.9375L10.329449,12.0625 14.704449,12.0625 14.704449,12.9375z\" />\n  <GeometryDrawing Brush=\"#FFFFFFFF\" Geometry=\"F1 M16,16z M0,0z M14.704449,12.9375L10.329449,12.9375 10.329449,12.0625 14.704449,12.0625z\" />\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/PInvokeMethod.xaml",
    "content": "<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ClipGeometry=\"M0,0 V16 H16 V0 H0 Z\">\n  <DrawingGroup.Transform>\n    <TranslateTransform X=\"0.021484375\" Y=\"0\" />\n  </DrawingGroup.Transform>\n  <GeometryDrawing Geometry=\"F1 M16,16z M0,0z M16,16L0,16 0,0 16,0 16,16z\">\n    <GeometryDrawing.Brush>\n      <SolidColorBrush Color=\"#FFF6F6F6\" Opacity=\"0\" />\n    </GeometryDrawing.Brush>\n  </GeometryDrawing>\n  <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M10.580078,0L9.0507812,1.5292969 9.5195312,2 4.9941406,2 4.9941406,4.7753906 4.8632812,4.7070312 -0.021484375,7.1757812 -0.021484375,12.746094 5.1015625,15.972656 9.5664062,12.701172 9.5664062,7.1875 7.3144531,6 9.5195312,6 9.0507812,6.4707031 10.580078,8 12.470703,8 15.994141,4.4746094 15.994141,3.5253906 12.470703,0 10.580078,0z\" />\n  <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1 M16,16z M0,0z M8.965,3.03L8.965,5.03 7.965,5.03 7.965,3.03z M5.965,3.03L5.965,5.03 6.965,5.03 6.965,3.03z M10.435,1.56L11.904,3.03 9.965,3.03 9.965,5.03 11.904,5.03 10.434,6.5 11.495,7.56 15.025,4.03 11.495,0.5z\" />\n  <GeometryDrawing Brush=\"#FF652D90\" Geometry=\"F1 M16,16z M0,0z M8.5663208,12.194755L8.5663208,7.7917547 4.8523208,5.8327547 0.97832075,7.7917547 0.97832075,12.194755 5.0593208,14.764755z M4.8063208,6.5087547L7.8763208,8.0227547 5.0123208,9.7407547 1.9173208,7.9747547z M4.7823208,13.882755L4.7823208,13.898755 4.7723208,13.890755 4.7643208,13.897755 4.7643208,13.882755 1.5973208,11.817755 1.5973208,8.4987547 4.8063208,10.291755 4.8063208,13.864755z M8.0013208,11.919755L5.4253208,13.775755 5.4253208,10.312755 8.0013208,8.7467547z\" />\n  <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1 M16,16z M0,0z M4.8063208,6.5087547L7.8763208,8.0227547 5.0123208,9.7407547 1.9173208,7.9747547z M4.8063208,13.864755L4.8063208,10.291755 1.5973208,8.4987547 1.5973208,11.817755 4.7643208,13.881755 4.7643208,13.897755 4.7723208,13.889755 4.7823208,13.897755 4.7823208,13.882755z M8.0013208,8.7467547L5.4253208,10.312755 5.4253208,13.775755 8.0013208,11.919755z\" />\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/ProgramDebugDatabase.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ClipGeometry=\"M0,0 V16 H16 V0 H0 Z\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M10.0225,1L3.9635,1C3.0115,1,2.0005,1.701,2.0005,3L2.0005,8.556C0.810500000000001,9.25 0.000500000000000611,10.525 0.000500000000000611,12 0.000500000000000611,14.206 1.7945,16 4.0005,16 5.0055,16 5.9145,15.614 6.6175,15L11.9645,15C13.4075,15,13.9715,13.825,14.0005,13L14.0005,4.552z\" />\n    <GeometryDrawing Brush=\"#FF414141\" Geometry=\"F1M6,7L8,7 8,6 6,6z\" />\n    <GeometryDrawing Brush=\"#FF414141\" Geometry=\"F1M6,8L6,8.555C6.222,8.684,6.428,8.832,6.62,9L10,9 10,8z\" />\n    <GeometryDrawing Brush=\"#FF414141\" Geometry=\"F1M7.8584,11L10.0004,11 10.0004,10 7.4454,10C7.6264,10.311,7.7664,10.644,7.8584,11\" />\n    <GeometryDrawing Brush=\"#FF414141\" Geometry=\"F1M7,12C7,10.344 5.657,9 4,9 2.343,9 1,10.344 1,12 1,13.656 2.343,15 4,15 5.657,15 7,13.656 7,12\" />\n    <GeometryDrawing Brush=\"#FF414141\" Geometry=\"F1M9.6406,2L3.9636,2C3.9636,2,2.9996,2,2.9996,3L2.9996,8.142C3.3216,8.059,3.6526,8,3.9996,8L3.9996,3 8.9996,3 8.9996,6 11.9996,6 11.9996,13 7.8576,13C7.7656,13.355,7.6246,13.689,7.4436,14L11.9646,14C12.9646,14,12.9996,13,12.9996,13L12.9996,5z\" />\n    <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M8,7L6,7 6,6 8,6z M9,6L9,3 4,3 4,8C4.735,8 5.417,8.213 6.009,8.562 6.006,8.56 6.003,8.557 6,8.555L6,8 10,8 10,9 6.62,9C6.615,8.995 6.608,8.992 6.602,8.987 6.946,9.285 7.235,9.637 7.462,10.034 7.456,10.023 7.452,10.011 7.445,10L10,10 10,11 7.858,11C7.857,10.994 7.854,10.989 7.853,10.983 7.939,11.311 8,11.646 8,12 8,12.348 7.941,12.679 7.858,13L12,13 12,6z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Property.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M16,5.5C16,8.538 13.538,11 10.5,11 10.225,11 9.957,10.973 9.693,10.934 9.667,10.93 9.641,10.927 9.615,10.922 9.337,10.877 9.066,10.816 8.804,10.731L4.268,15.268C3.795,15.74 3.167,16 2.5,16 1.833,16 1.205,15.74 0.731999999999999,15.268 -0.242000000000001,14.293 -0.242000000000001,12.707 0.731999999999999,11.732L5.269,7.196C5.184,6.934 5.123,6.662 5.078,6.384 5.073,6.359 5.07,6.333 5.066,6.307 5.027,6.043 5,5.775 5,5.5 5,2.462 7.462,0 10.5,0 13.538,0 16,2.462 16,5.5\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M15,5.5C15,7.985 12.985,10 10.5,10 9.807,10 9.158,9.83 8.571,9.55L3.561,14.561C3.268,14.854 2.884,15 2.5,15 2.116,15 1.732,14.854 1.439,14.561 0.853999999999999,13.975 0.853999999999999,13.025 1.439,12.439L6.45,7.429C6.17,6.842 6,6.193 6,5.5 6,3.015 8.015,1 10.5,1 11.193,1 11.842,1.17 12.429,1.45L9.636,4.243 11.757,6.364 14.55,3.571C14.83,4.158,15,4.807,15,5.5\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/README.md",
    "content": "Icons used in ILSpy:\n--------------------\n\n|                           | SVG | XAML | Origin                                                                          | Notes   |\n|---------------------------|-----|------|---------------------------------------------------------------------------------|---------|\n| Assembly                  |  x  |  x   | VS 2017 Icon Pack (Reference)                                                   |         |\n| AssemblyList              |  x  |  x   | VS 2017 Icon Pack (AddReference)                                                |         |\n| AssemblyListGAC           |  x  |  x   | based on VS 2017 Icon Pack (AddReference) + \"GAC\" text                          |         |\n| AssemblyWarning           |  x  |  x   | VS 2017 Icon Pack (ReferenceWarning)                                            |         |\n| Back                      |  x  |  x   | VS 2017 Icon Pack (Backward)                                                    |         |\n| Class                     |  x  |  x   | VS 2017 Icon Pack (Class)                                                       |         |\n| Close                     |  x  |  x   | VS 2017 Icon Pack (Clear)                                                       |         |\n| CollapseAll               |  x  |  x   | VS 2017 Icon Pack (CollapseAll)                                                 |         |\n| Constructor               |  x  |  x   | based on VS 2017 Icon Pack (Method) using a different colour                    |         |\n| Copy                      |  x  |  x   | VS 2017 Icon Pack (Copy)                                                        |         |\n| Delegate                  |  x  |  x   | VS 2017 Icon Pack (Delegate)                                                    |         |\n| Delete                    |  x  |  x   | VS 2017 Icon Pack (Remove_color)                                                |         |\n| DictionaryContain         |  x  |  x   | VS 2017 Icon Pack (DictionaryContain)                                           |         |\n| Enum                      |  x  |  x   | VS 2017 Icon Pack (Enumerator)                                                  |         |\n| EnumValue                 |  x  |  x   | VS 2017 Icon Pack (EnumItem)                                                    |         |\n| Event                     |  x  |  x   | VS 2017 Icon Pack (Event)                                                       |         |\n| ExpandAll                 |  x  |  x   | VS 2017 Icon Pack (ExpandAll)                                                   |         |\n| ExportOverlay             |  x  |  x   | slightly modified VS 2017 Icon Pack (Export)                                    |         |\n| ExtensionMethod           |  x  |  x   | VS 2017 Icon Pack (ExtensionMethod)                                             |         |\n| Field                     |  x  |  x   | VS 2017 Icon Pack (Field)                                                       |         |\n| FieldReadOnly             |  x  |  x   | VS 2017 Icon Pack (Field) with different color                                  |         |\n| FindAssembly              |  x  |  x   | based on VS 2017 Icon Pack (Reference + Search) with transparency modifications |         |\n| Folder.Closed             |  x  |  x   | VS 2017 Icon Pack (Folder)                                                      |         |\n| Folder.Open               |  x  |  x   | VS 2017 Icon Pack (FolderOpen)                                                  |         |\n| Forward                   |  x  |  x   | VS 2017 Icon Pack (Forward)                                                     |         |\n| Header                    |  x  |  x   | VS 2017 Icon Pack (PageHeader)                                                  |         |\n| Heap                      |  x  |  x   | VS 2017 Icon Pack (Datalist)                                                    |         |\n| Indexer                   |  x  |  x   | VS 2017 Icon Pack (Indexer)                                                     |         |\n| Interface                 |  x  |  x   | VS 2017 Icon Pack (Interface)                                                   |         |\n| Library                   |  x  |  x   | VS 2017 Icon Pack (Library)                                                     |         |\n| ListFolder                |  x  |  x   | VS 2017 Icon Pack (ListFolder)                                                  |         |\n| ListFolder.Open           |  x  |  x   | VS 2017 Icon Pack (ListFolderOpen)                                              |         |\n| Literal                   |  x  |  x   | VS 2017 Icon Pack (Literal)                                                     |         |\n| Metadata                  |  x  |  x   | VS 2017 Icon Pack (Metadata)                                                    |         |\n| MetadataFile              |  x  |  x   | combined ProgramDebugDatabase + Metadata                                        |         |\n| MetadataTable             |  x  |  x   | VS 2017 Icon Pack (LinkedTable)                                                 |         |\n| MetadataTableGroup        |  x  |  x   | VS 2017 Icon Pack (LinkedTableGroup)                                            |         |\n| Method                    |  x  |  x   | VS 2017 Icon Pack (Method)                                                      |         |\n| Namespace                 |  x  |  x   | VS 2017 Icon Pack (Namespace)                                                   |         |\n| OK                        |  x  |  x   | VS 2017 Icon Pack (StatusOK)                                                    |         |\n| Open                      |  x  |  x   | VS 2017 Icon Pack (Open)                                                        |         |\n| Operator                  |  x  |  x   | VS 2017 Icon Pack (Operator)                                                    |         |\n| OverlayCompilerControlled |  x  |  x   | based on VS 2017 Icon Pack (StatusBlocked)                                      |         |\n| OverlayInternal           |  x  |  x   | based on VS 2017 Icon Pack (Friend)                                             |         |\n| OverlayPrivate            |  x  |  x   | extracted from VS 2017 Icon Pack (ActionPrivate)                                |         |\n| OverlayPrivateProtected   |  x  |  x   | combined OverlayPrivate and OverlayProtected                                    |         |\n| OverlayProtected          |  x  |  x   | extracted from VS 2017 Icon Pack (ActionProtected)                              |         |\n| OverlayProtectedInternal  |  x  |  x   | combined OverlayProtected and OverlayInternal                                   |         |\n| OverlayStatic             |  x  |  x   | custom                                                                          |         |\n| PInvokeMethod             |  x  |  x   | based on VS 2017 Icon Pack (ExtensionMethod) with rotated arrow                 |         |\n| ProgramDebugDatabase      |  x  |  x   | VS 2017 Icon Pack (ProgramDebugDatabase)                                        |         |\n| Property                  |  x  |  x   | VS 2017 Icon Pack (Property)                                                    |         |\n| ReferenceFolder           |  x  |  x   | combined VS 2017 Icon Pack (Reference) two times                                |         |\n| ReferenceOverlay          |  x  |  x   | extracted arrow from VS 2017 Icon Pack (TypeShortcut)                           |         |\n| Refresh                   |  x  |  x   | VS 2017 Icon Pack (Refresh)                                                     |         |\n| Resource                  |  x  |  x   | VS 2017 Icon Pack (Document)                                                    |         |\n| ResourceImage             |  x  |  x   | VS 2017 Icon Pack (Image)                                                       |         |\n| ResourceResourcesFile     |  x  |  x   | VS 2017 Icon Pack (LocalResources)                                              |         |\n| ResourceXml               |  x  |  x   | VS 2017 Icon Pack (XMLFile)                                                     |         |\n| ResourceXsd               |  x  |  x   | combined VS 2017 Icon Pack (XMLSchema) with the file symbol in ResourceXslt     |         |\n| ResourceXsl               |  x  |  x   | VS 2017 Icon Pack (XMLTransformation)                                           |         |\n| ResultToJSON              |  x  |  x   | VS 2017 Icon Pack (ResultToJSON)                                                |         |\n| ResourceXslt              |  x  |  x   | VS 2017 Icon Pack (XSLTTemplate)                                                |         |\n| Save                      |  x  |  x   | VS 2017 Icon Pack (Save)                                                        |         |\n| Search                    |  x  |  x   | VS 2017 Icon Pack (Search)                                                      |         |\n| SearchMsdn                |  x  |  x   | based on VS 2017 Icon Pack (Search) + Microsoft Logo                            |         |\n| ShowAll                   |  x  |  x   | combined PublicOnly, OverlayPrivate, OverlayProtected, OverlayInternal          |         |\n| ShowPrivateInternal       |  x  |  x   | combined OverlayPrivate and OverlayInternal                                     |         |\n| ShowPublicOnly            |  x  |  x   | VS 2017 Icon Pack (Type)                                                        |         |\n| Sort                      |  x  |  x   | VS 2017 Icon Pack (SortAscending)                                               |         |\n| Struct                    |  x  |  x   | VS 2017 Icon Pack (Structure)                                                   |         |\n| SubTypes                  |  x  |  x   | based on VS 2017 Icon Pack (BaseType) rotated +90°                              |         |\n| SuperTypes                |  x  |  x   | based on VS 2017 Icon Pack (BaseType) rotated -90°                              |         |\n| SwitchSourceOrTarget      |  x  |  x   | VS 2017 Icon Pack (SwitchSourceOrTarget)                                        |         |\n| ViewCode                  |  x  |  x   | VS 2017 Icon Pack (GoToSourceCode)                                              |         |\n| VirtualMethod             |  x  |  x   | combined VS 2017 Icon Pack (Method) two times                                   |         |\n| Warning                   |  x  |  x   | VS 2017 Icon Pack (StatusWarning)                                               |         |\n\nNote: All XAML icons from VS 2017 Icon Pack are modified to not include a `Viewbox` XAML root element. We always use a `Drawing`-derived root element.\nNote: When changing an icon, start with SVG and use https://github.com/BerndK/SvgToXaml to generate the XAML. The result is much better XAML than what Inkscape produces."
  },
  {
    "path": "ILSpy/Images/ReferenceOverlay.xaml",
    "content": "<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ClipGeometry=\"M0,0 V16 H16 V0 H0 Z\">\n\t<DrawingGroup Opacity=\"1\">\n\t\t<GeometryDrawing Geometry=\"F1 M16,16z M0,0z M0,0L16,0 16,16 0,16z\">\n\t\t\t<GeometryDrawing.Brush>\n\t\t\t\t<SolidColorBrush Color=\"#FFF6F6F6\" Opacity=\"0\" />\n\t\t\t</GeometryDrawing.Brush>\n\t\t</GeometryDrawing>\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M9,9L9,16 16,16 16,9z\" />\n\t</DrawingGroup>\n\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1 M16,16z M0,0z M10,10L10,15 15,15 15,10 10,10z M14,13L13,14 13,12.5 11.5,14 11,13.5 12.5,12 11,12 12,11 14,11 14,13z\" />\n\t<GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1 M16,16z M0,0z M14,11L14,13 13,14 13,12.5 11.5,14 11,13.5 12.5,12 11,12 12,11z\" />\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Refresh.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M16,8C16,12.411 12.411,16 8,16 3.589,16 0,12.411 0,8 0,6.597 0.384,5.212 1.088,4L0,4 0,0 8,0 8,8 4,8C4,10.206 5.794,12 8,12 10.206,12 12,10.206 12,8 12,6.656 11.331,5.41 10.21,4.666L9.377,4.112 11.592,0.78 12.425,1.333C14.663,2.822,16,5.314,16,8\" />\n    <GeometryDrawing Brush=\"#FF00529C\" Geometry=\"F1M15,8C15,11.859 11.859,15 8,15 4.14,15 1,11.859 1,8 1,6.076 1.801,4.292 3.121,3L1,3 1,1 7,1 7,7 5,7 5,4.002C3.766,4.931 3,6.401 3,8 3,10.757 5.243,13 8,13 10.757,13 13,10.757 13,8 13,6.321 12.164,4.763 10.764,3.833L11.871,2.167C13.83,3.469,15,5.649,15,8\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Resource.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M4,15C3.03,15,2,14.299,2,13L2,3C2,1.701,3.03,1,4,1L10.061,1 14,4.556 14,13C14,13.97,13.299,15,12,15z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M12,13L4,13 4,3 9,3 9,6 12,6z M9.641,2L3.964,2C3.964,2,3,2,3,3L3,13C3,14,3.965,14,3.965,14L11.965,14C12.965,14,13,13,13,13L13,5z\" />\n\t\t<GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M4,3L9,3 9,6 12,6 12,13 4,13z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/ResourceImage.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M0,15L16,15 16,0 0,0z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M1,1L1,10 2,9.073 2,2 14,2 14,11.098 15,12 15,1z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M1,1L1,10 2,9.073 2,2 14,2 14,11.098 15,12 15,1z\" />\n\t\t<GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M10,4.5C10,5.328 10.672,6 11.5,6 12.328,6 13,5.328 13,4.5 13,3.672 12.328,3 11.5,3 10.672,3 10,3.672 10,4.5 M5,6.293L2,9.293 2,2 14,2 14,11.293 12,9.293 10,11.293z\" />\n\t\t<GeometryDrawing Brush=\"#FF1AA1E2\" Geometry=\"F1M1,10L5,6.293 10,11.293 12,9.293 15,12 15,14 1,14z\" />\n\t\t<GeometryDrawing Brush=\"#FFC17C1A\" Geometry=\"F1M11.5,3C10.672,3 10,3.672 10,4.5 10,5.328 10.672,6 11.5,6 12.328,6 13,5.328 13,4.5 13,3.672 12.328,3 11.5,3\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/ResourceResourcesFile.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M12.9824,0L7.9414,0C7.0014,0,6.0004,0.701,6.0004,2L2.9414,2C2.0014,2,1.0004,2.701,1.0004,4L1.0004,7 0.000400000000000844,7 0.000400000000000844,16 7.9764,16 8.9684,16 12.9414,16C14.3674,16,14.9524,14.839,15.0004,14L15.0004,8.875 16.0004,8.875 16.0004,2.688z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M5.75,11C6.164,11 6.5,10.664 6.5,10.25 6.5,9.836 6.164,9.5 5.75,9.5 5.336,9.5 5,9.836 5,10.25 5,10.664 5.336,11 5.75,11\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M7,13.5L3.5,11 2,12.5 2,9 7,9z M2,14L3.5,12.5 5.5,14z M1,15L8,15 8,8 1,8z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M15.0234,3.1362L12.6254,1.0002 7.9644,1.0002C7.9644,1.0002,7.0234,1.0002,7.0234,2.0002L8.0234,2.0002 12.0234,2.0002 12.0234,4.0002 14.0234,4.0002 14.0234,5.0002 14.0234,6.0002 14.0234,7.2402 14.7784,7.8752 15.0234,7.8752z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M3.0234,7L3.0234,4 7.0234,4 7.0234,5 9.8704,5 7.6254,3 2.9644,3C2.9644,3,2.0234,3,2.0234,4L2.0234,7z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M11.625,6L6.965,6C6.965,6,6.023,6,6.023,7L7.023,7 9,7 11.023,7 11.023,9 13.023,9 13.023,10 13.023,11 13.023,14 9,14 9,15 12.965,15C13.965,15,14.023,14,14.023,14L14.023,8.137z\" />\n\t\t<GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M2,14L5.5,14 3.5,12.5z\" />\n\t\t<GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M5.75,11C5.336,11 5,10.664 5,10.25 5,9.836 5.336,9.5 5.75,9.5 6.164,9.5 6.5,9.836 6.5,10.25 6.5,10.664 6.164,11 5.75,11 M2,9L2,12.5 3.5,11 7,13.5 7,9z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M5.75,11C6.164,11 6.5,10.664 6.5,10.25 6.5,9.836 6.164,9.5 5.75,9.5 5.336,9.5 5,9.836 5,10.25 5,10.664 5.336,11 5.75,11\">\n\t\t\t<GeometryDrawing.Pen>\n\t\t\t\t<Pen Brush=\"#FF414141\" Thickness=\"0.20000007748603821\" DashCap=\"Flat\" />\n\t\t\t</GeometryDrawing.Pen>\n\t\t</GeometryDrawing>\n\t\t<GeometryDrawing Brush=\"#FFEFEEF0\" Geometry=\"F1M8,2L11.936,2 11.936,3.96 14,3.996 14,7.221 8.023,2\" />\n\t\t<GeometryDrawing Brush=\"#FFEFEEF0\" Geometry=\"F1M5,7C5,5.73,5.986,5.036,6.936,5.006L6.936,4 3,4 3,7z\" />\n\t\t<GeometryDrawing Brush=\"#FFEFEEF0\" Geometry=\"F1M10.9355,8.96L10.9355,7 8.9995,7 8.9995,14 12.9995,14 12.9995,8.996z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/ResourceXml.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M2.9648,16C2.0118,16,0.9998,15.299,0.9998,14L0.9998,2C0.9998,0.701000000000001,2.0118,0,2.9638,0L11.0228,0 14.9998,3.553 14.9998,14C14.9718,14.825,14.4068,16,12.9648,16z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M5.7334,10.6582L4.0264,8.9512 5.7334,7.2442 6.4404,7.9512 5.4404,8.9512 6.4404,9.9512z M9.0134,13.0282L7.0624,13.0282 7.0624,11.0182 9.0134,11.0182z M8.9254,9.9482L7.0214,9.9482 7.0214,4.9962 8.9254,4.9962z M10.3554,7.2932L12.0624,9.0002 10.3554,10.7072 9.6484,10.0002 10.6484,9.0002 9.6484,8.0002z M13.0004,14.0002L3.0004,14.0002 3.0004,2.0002 10.0004,2.0002 10.0004,5.0002 13.0004,5.0002z M10.6404,1.0002L2.9634,1.0002C2.9634,1.0002,2.0004,1.0002,2.0004,2.0002L2.0004,14.0002C2.0004,15.0002,2.9644,15.0002,2.9644,15.0002L12.9644,15.0002C13.9644,15.0002,14.0004,14.0002,14.0004,14.0002L14.0004,4.0002z\" />\n\t\t<GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M10.3555,10.707L9.6485,10 10.6485,9 9.6485,8 10.3555,7.293 12.0625,9z M9.0135,13.028L7.0625,13.028 7.0625,11.018 9.0135,11.018z M7.0215,4.997L8.9255,4.997 8.9255,9.949 7.0215,9.949z M6.4405,9.951L5.7335,10.658 4.0265,8.951 5.7335,7.244 6.4405,7.951 5.4405,8.951z M10.0185,5L10.0185,2 3.0005,2 3.0005,14 13.0005,14 13.0005,5z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/ResourceXsd.xaml",
    "content": "<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ClipGeometry=\"M0,0 V16 H16 V0 H0 Z\">\n  <GeometryDrawing Geometry=\"F1 M16,16z M0,0z M16,16L0,16 0,5.9E-07 16,5.9E-07z\">\n    <GeometryDrawing.Brush>\n      <SolidColorBrush Color=\"#FFF6F6F6\" Opacity=\"0\" />\n    </GeometryDrawing.Brush>\n  </GeometryDrawing>\n  <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M2.965,16C2.012,16,1,15.299,1,14L1,2.0000004C1,0.70100059,2.012,5.9E-07,2.964,5.9E-07L11.023,5.9E-07 15,3.5530004 15,14C14.972,14.825,14.407,16,12.965,16z\" />\n  <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1 M16,16z M0,0z M10.641,1.0000006L2.964,1.0000006C2.964,1.0000006 2,1.0000006 2,2.0000004 2,2.8050004 2,11.441 2,14 2,15 2.965,15 2.965,15 2.965,15 11.965,15 12.965,15 13.965,15 14,14 14,14L14,4.0000004z M13,14L3,14 3,2.0000004 10,2.0000004 10,5.0000004 13,5.0000004z M6,4.0000004L4,4.0000004 4,3.0000004 6,3.0000004z M9,4.0000004L7,4.0000004 7,3.0000004 9,3.0000004z M6,6.0000004L4,6.0000004 4,5.0000004 6,5.0000004z M9,6.0000004L7,6.0000004 7,5.0000004 9,5.0000004z M6,8.0000004L4,8.0000004 4,7.0000004 6,7.0000004z M9,8.0000004L7,8.0000004 7,7.0000004 9,7.0000004z\" />\n  <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1 M16,16z M0,0z M10,5.0000004L10,2.0000004 3,2.0000004 3,14 13,14 13,5.0000004z\" />\n  <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M8.2694915,13L8.2694915,10.305085 7.7305084,10.305085 7.7305084,13 3.957627,13 3.957627,10.305085 5.0355931,10.305085 5.0355931,8.6881359 7.1915253,8.6881359 7.1915253,7.8343868 6.6525423,8.3722918 4.8124541,6.5322037 6.6525423,4.6921156 7.6841558,5.7237292 6.8767592,6.5322037 7.4152033,7.0711868 8.5847966,7.0711868 9.1232407,6.5322037 8.315844,5.7237292 9.3474576,4.6921156 11.187546,6.5322037 9.3474576,8.3722918 8.8084746,7.8343868 8.8084746,8.6881359 10.964407,8.6881359 10.964407,10.305085 12.042373,10.305085 12.042373,13z\" />\n  <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1 M16,16z M0,0z M5.5745762,6.4206341L6.6525423,7.4986002 6.9220338,7.2291087 6.1135592,6.4206341 6.9220338,5.6121596 6.6525423,5.3426681z M10.425424,6.4206341L9.3474575,5.3426681 9.077966,5.6121596 9.8864406,6.4206341 9.077966,7.2291087 9.3474575,7.4986002z M5.5745762,9.1155495L7.7305084,9.1155495 7.7305084,7.4986002 8.2694914,7.4986002 8.2694914,9.1155495 10.425424,9.1155495 10.425424,10.732499 11.50339,10.732499 11.50339,12.349448 8.8084745,12.349448 8.8084745,10.732499 9.8864406,10.732499 9.8864406,9.654532 6.1135592,9.654532 6.1135592,10.732499 7.1915253,10.732499 7.1915253,12.349448 4.4966101,12.349448 4.4966101,10.732499 5.5745762,10.732499z\" />\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/ResourceXsl.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M13.6885,0L15.9995,2.179 15.9995,11.043C15.9995,11.043,16.1955,13,13.9975,13L10.9995,13 10.9995,14.016C10.9995,14.016,11.1245,16,9.0155,16L2.0165,16C-0.000500000000000611,16,-0.000500000000000611,13.969,-0.000500000000000611,13.969L-0.000500000000000611,3.5C-0.000500000000000611,2.396,0.718499999999999,1.458,1.7125,1.127L1.9995,1 1.9995,0z\" />\n    <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M13,1L6.964,1C6.964,1,6.522,1.008,6.237,1.323L7,2.086 7,2 12,2 12,4 14,4 14,11 7,11 7,2.914 6,3.914 6,11C6,12,6.964,12,6.964,12L13.965,12C14.965,12,15,11,15,11L15,3z M2,3.5C2,3.225,2.225,3,2.5,3L4,3 3,4 4.5,4 6,2.5 4.5,1 3,1 4,2 2.5,2C1.673,2,1,2.673,1,3.5L1,5 2,5z M13,8L11,8 11,10 13,10z M8,10L10,10 10,8 8,8z M9,7L10,7 10,8 11,8 11,7 12,7 12,4 9,4z M1,7L1,14C1,14.986,2,15,2,15L9.031,15C9.031,15,10,14.844,10,13.984L10,13 9,13 9,14 2,14 2,7 5,7 5,6 2,6C1.048,6,1,7,1,7 M3,13L5,13 5,12 3,12z M5,10L3,10 3,11 5,11z M5,9L3,9 3,8 5,8z\" />\n    <GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M14,4L14,11 7,11 7,2.914 7.414,2.5 7,2.086 7,2 12,2 12,4 9,4 9,7 10,7 10,8 8,8 8,10 10,10 10,8 11,8 11,10 13,10 13,8 11,8 11,7 12,7 12,4z M3,13L3,12 5.031,12 5.016,13z M8,13L6.512,13C4.959,12.697,5,11,5,11L3,11 3,10 5,10 5,9 3,9 3,8 5,8 5,7 2,7 2,14 9,14 9,13z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/ResourceXslt.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M3.5856,-0.000199999999999534L-0.000399999999999956,3.5868 -0.000399999999999956,4.0008 2.5856,4.0008 -0.000399999999999956,6.5858 -0.000399999999999956,14.9998 7.0006,14.9998 7.0006,12.0008 6.0006,12.0008 6.0006,10.9998 8.0006,10.9998 8.0006,8.9998 10.9996,8.9998 10.9996,6.9998 11.9996,6.9998 11.9996,8.9998 16.0006,8.9998 16.0006,4.9998 15.0006,4.9998 15.0006,4.0008 14.0006,4.0008 14.0006,-0.000199999999999534z M5.0006,6.4138L5.0006,7.9998 3.4136,7.9998z M7.0006,7.4138L7.0006,7.9998 6.4146,7.9998z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M1,14L6,14 6,13 1,13z M5,11L1,11 1,12 5,12z M1,10L7,10 7,9 1,9z M14,6L14,5 12,5 12,4 13,4 13,1 10,1 10,4 11,4 11,5 9,5 9,6 8,6 8,8 10,8 10,6 13,6 13,8 15,8 15,6z\" />\n\t\t<GeometryDrawing Brush=\"#FF00529C\" Geometry=\"F1M5,3L2,3 4,1 8,1 8,2 8,3 8,5 6,7 6,4 3,7 1,7z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/ResultToJSON.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ClipGeometry=\"M0,0 V16 H16 V0 H0 Z\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M9.4141,4L5.4141,0 0.5861,0 2.5861,2 9.99999999997669E-05,2 9.99999999997669E-05,6 2.0001,6 2.0001,6.586 1.5861,7 1.0001,7 1.0001,7.586 0.5861,8 1.0001,8 1.0001,9.638 1.3291,11 2.0001,11 2.0001,12.536C2.0001,13.783 2.4951,14.686 3.1901,15.247 3.8311,15.764 4.8871,16 6.1271,16L7.0001,16 7.0001,12.753C7.0001,12.753 5.9891,12.752 5.9671,12.75 5.9591,12.697 6.0001,12.623 6.0001,12.522L6.0001,11.121C6.0001,10.159 5.7761,9.484 5.4571,9.01 5.7131,8.632 5.9011,8.119 5.9681,7.446z M16.0001,8.38L16.0001,10.638C16.0001,10.638 15.0081,10.637 15.0031,10.635 14.9911,10.687 15.0001,10.775 15.0001,10.916L15.0001,12.495C15.0001,13.766 14.6301,14.68 13.9461,15.241 13.3081,15.763 12.3701,16 11.1241,16L10.0001,16 10.0001,12.753C10.0001,12.753 11.0141,12.752 11.0371,12.75 11.0411,12.704 11.0001,12.633 11.0001,12.536L11.0001,11.08C11.0001,10.137 11.2221,9.474 11.5391,9.008 11.2231,8.527 11.0001,7.843 11.0001,6.869L11.0001,5.468C11.0001,5.38 11.1021,5.182 11.0941,5.143 11.0741,5.141 11.1571,5 11.1241,5L10.0001,5 10.0001,2 11.1241,2C12.3751,2 13.3171,2.265 13.9561,2.81 14.6331,3.387 15.0001,4.3 15.0001,5.522L15.0001,7 15.9191,7z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M5.0332,12.5225L5.0332,11.1215C5.0332,10.0045,4.6822,9.3055,3.9802,9.0225L3.9802,8.9955C4.4092,8.8195,4.6902,8.4755,4.8572,8.0005L3.0492,8.0005C2.8762,8.2475,2.6132,8.3795,2.2442,8.3795L2.2442,9.6375C2.9362,9.6375,3.2832,10.0575,3.2832,10.8955L3.2832,12.5365C3.2832,13.4705 3.5092,14.1205 3.9602,14.4845 4.4112,14.8485 5.1342,15.0315 6.1272,15.0315L6.1272,13.7525C5.7392,13.7525 5.4612,13.6595 5.2892,13.4725 5.1192,13.2855 5.0332,12.9695 5.0332,12.5225 M15.0002,8.3795L15.0002,9.6375C14.3032,9.6375,13.9542,10.0645,13.9542,10.9165L13.9542,12.4955C13.9542,13.4565 13.7312,14.1205 13.2882,14.4845 12.8432,14.8485 12.1222,15.0315 11.1242,15.0315L11.1242,13.7525C11.5072,13.7525 11.7852,13.6605 11.9582,13.4765 12.1312,13.2915 12.2182,12.9785 12.2182,12.5365L12.2182,11.0805C12.2182,9.9905,12.5662,9.3095,13.2632,9.0365L13.2632,9.0085C12.5662,8.7215,12.2182,8.0085,12.2182,6.8695L12.2182,5.4675C12.2182,4.6745,11.8532,4.2785,11.1242,4.2785L11.1242,3.0005C12.1172,3.0005 12.8382,3.1905 13.2842,3.5705 13.7302,3.9515 13.9542,4.6025 13.9542,5.5225L13.9542,7.0875C13.9542,7.9495,14.3032,8.3795,15.0002,8.3795\" />\n\t\t<GeometryDrawing Brush=\"#FF00529C\" Geometry=\"F1M8,4L5,7 3,7 5,5 1,5 1,3 5,3 3,1 5,1z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Save.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M16,2L16,16 2.586,16 0,13.414 0,2C0,0.897,0.897,0,2,0L14,0C15.103,0,16,0.897,16,2\" />\n    <GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M4,10L4,15 6,15 6,12 8,12 8,15 12,15 12,10z M13,7L3,7 3,3 13,3z\" />\n    <GeometryDrawing Brush=\"#FF00529C\" Geometry=\"F1M13,3L3,3 3,7 13,7z M15,2L15,15 12,15 12,10 4,10 4,15 3,15 1,13 1,2C1,1.448,1.448,1,2,1L14,1C14.553,1,15,1.448,15,2 M6,12L8,12 8,15 6,15z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Search.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M16,5.8335C16,9.0495 13.384,11.6665 10.167,11.6665 9.136,11.6665 8.144,11.3925 7.254,10.8675L2.561,15.5605C2.277,15.8435 1.9,16.0005 1.5,16.0005 1.1,16.0005 0.723000000000001,15.8435 0.439,15.5605 -0.146000000000001,14.9755 -0.146000000000001,14.0245 0.439,13.4395L5.133,8.7445C4.608,7.8555 4.333,6.8635 4.333,5.8335 4.333,2.6165 6.95,0.000500000000000611 10.167,0.000500000000000611 13.384,0.000500000000000611 16,2.6165 16,5.8335\" />\n    <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M14,5.8335C14,7.9475 12.28,9.6665 10.167,9.6665 8.053,9.6665 6.333,7.9475 6.333,5.8335 6.333,3.7195 8.053,2.0005 10.167,2.0005 12.28,2.0005 14,3.7195 14,5.8335\" />\n    <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M10.167,9.667C8.053,9.667 6.334,7.947 6.334,5.834 6.334,3.72 8.053,2 10.167,2 12.28,2 14,3.72 14,5.834 14,7.947 12.28,9.667 10.167,9.667 M10.167,1C7.502,1 5.334,3.168 5.334,5.834 5.334,6.985 5.755,8.03 6.431,8.862L1.147,14.146C0.951000000000001,14.342 0.951000000000001,14.658 1.147,14.854 1.244,14.951 1.372,15 1.5,15 1.628,15 1.756,14.951 1.854,14.854L7.138,9.569C7.969,10.245 9.015,10.667 10.167,10.667 12.832,10.667 15,8.499 15,5.834 15,3.168 12.832,1 10.167,1\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/SearchMsdn.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ClipGeometry=\"M0,0 V16 H16 V0 H0 Z\">\n  <GeometryDrawing Geometry=\"F1 M16,16z M0,0z M16,16L0,16 0,0 16,0 16,16z\">\n    <GeometryDrawing.Brush>\n      <SolidColorBrush Color=\"#FFF6F6F6\" Opacity=\"0\" />\n    </GeometryDrawing.Brush>\n  </GeometryDrawing>\n  <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M16,5.833A5.84,5.84,0,0,1,10.167,11.666A5.688,5.688,0,0,1,7.254,10.866L2.56,15.559A1.494,1.494,0,0,1,0.439,15.561A1.501,1.501,0,0,1,0.439,13.44L5.133,8.745A5.69,5.69,0,0,1,4.333,5.834C4.333,2.617 6.95,0 10.167,0 13.384,0 16,2.617 16,5.833z\" />\n  <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1 M16,16z M0,0z M14,5.833A3.837,3.837,0,0,1,10.167,9.666C8.053,9.666 6.334,7.946 6.334,5.833 6.334,3.72 8.053,2 10.167,2A3.838,3.838,0,0,1,14,5.833z\" />\n  <GeometryDrawing Brush=\"#FF03A5EF\" Geometry=\"F1 M16,16z M0,0z M2,8L8,8 8,14 2,14z\" />\n  <GeometryDrawing Brush=\"#FFFFB803\" Geometry=\"F1 M16,16z M0,0z M9,8L15,8 15,14 9,14z\" />\n  <GeometryDrawing Brush=\"#FF7FBB03\" Geometry=\"F1 M16,16z M0,0z M9,1L15,1 15,7 9,7z\" />\n  <GeometryDrawing Brush=\"#FFF25021\" Geometry=\"F1 M16,16z M0,0z M2,1L8,1 8,7 2,7z\" />\n  <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1 M16,16z M0,0z M10.167,1A4.84,4.84,0,0,0,5.333,5.833C5.333,6.985,5.755,8.03,6.43,8.861L1.146,14.146A0.5,0.5,0,0,0,1.854,14.854L7.138,9.569C7.97,10.245 9.015,10.667 10.167,10.667 12.832,10.667 15,8.499 15,5.834 15,3.169 12.832,1 10.167,1z M10.167,9.667C8.053,9.667 6.334,7.947 6.334,5.834 6.334,3.721 8.053,2 10.167,2 12.28,2 14,3.72 14,5.833 14,7.946 12.28,9.667 10.167,9.667z\" />\n  <GeometryDrawing Geometry=\"F1 M16,16z M0,0z M14,5.833A3.837,3.837,0,0,1,10.167,9.6659996C8.053,9.6659996 6.3339999,7.9459996 6.3339999,5.833 6.3339999,3.72 8.053,2 10.167,2A3.838,3.838,0,0,1,14,5.833z\">\n    <GeometryDrawing.Brush>\n      <SolidColorBrush Color=\"#FFF0EFF1\" Opacity=\"0.76862746\" />\n    </GeometryDrawing.Brush>\n  </GeometryDrawing>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/ShowPublicOnly.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M3.9996,-0.000199999999999534L3.9996,4.9998 -0.000399999999999956,4.9998 -0.000399999999999956,15.9998 11.9996,15.9998 11.9996,10.9998 16.0006,10.9998 16.0006,-0.000199999999999534z\" />\n    <GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M14,9L11,9 11,6 6,6 6,2 14,2z M10,14L2,14 2,7 10,7z\" />\n    <GeometryDrawing Brush=\"#FF00529C\" Geometry=\"F1M14,9L11,9 11,6 6,6 6,2 14,2z M10,14L2,14 2,7 10,7z M5,1L5,6 1,6 1,15 11,15 11,10 15,10 15,1z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Sort.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M0,-0.000199999999999534L0,8.9998 1,8.9998 1,12.0008 2.586,12.0008 1,13.5858 1,15.9998 8,15.9998 8,13.0008 6.449,13.0008 8,12.0008 8,10.9998 12,14.9998 16,10.9998 16,4.9998 14,6.9998 14,3.0008 10,3.0008 10,6.9998 9,5.9998 9,-0.000199999999999534z\" />\n    <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M7,7L5,2 4,2 2,7 3,7 3.399,6 5.601,6 6,7z M8,8L1,8 1,1 8,1z M4.5,3.25L5.2,5 3.8,5z M2,11L5,11 2,14 2,15 7,15 7,14 4.013,14 7,11.051 6.952,11 7,11 7,10 2,10z\" />\n    <GeometryDrawing Brush=\"#FFEFEFF0\" Geometry=\"F1M3.7998,5L4.4998,3.25 5.1998,5z M5.9998,7L6.9998,7 4.9998,2 3.9998,2 1.9998,7 2.9998,7 3.3998,6 5.6008,6z\" />\n    <GeometryDrawing Brush=\"#FF00529C\" Geometry=\"F1M15,8L15,10 12,13 9,10 9,8 11,10 11,4 13,4 13,10z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Struct.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M9,14L9,8 7,8 7,14 1,14 1,2 15,2 15,14z\" />\n    <GeometryDrawing Brush=\"#FF00529C\" Geometry=\"F1M2,7L14,7 14,3 2,3z M2,13L6,13 6,9 2,9z M10,9L14,9 14,13 10,13z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/SubTypes.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Transform>\n\t\t<RotateTransform Angle=\"90\"/>\n\t</DrawingGroup.Transform>\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M12.996,6.5874L12.996,8.4144 9.412,12.0004 8.586,12.0004 7,10.4144 7,9.0004 4,9.0004 4,6.0014 7,6.0014 7,4.5874 8.586,3.0014 9.412,3.0014z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M10.996,7.5869L9,9.5859 9,5.4159 10.996,7.4159z M9,4.0019L8,5.0019 8,7.0019 5,7.0019 5,8.0019 8,8.0019 8,9.9999 9,10.9999 11.996,8.0019 11.996,7.0019z\" />\n\t\t<GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M9,5.4155L10.996,7.4155 10.996,7.5865 9,9.5855z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/SuperTypes.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<DrawingGroup.Transform>\n\t\t<RotateTransform Angle=\"-90\"/>\n\t</DrawingGroup.Transform>\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M12.996,6.5874L12.996,8.4144 9.412,12.0004 8.586,12.0004 7,10.4144 7,9.0004 4,9.0004 4,6.0014 7,6.0014 7,4.5874 8.586,3.0014 9.412,3.0014z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M10.996,7.5869L9,9.5859 9,5.4159 10.996,7.4159z M9,4.0019L8,5.0019 8,7.0019 5,7.0019 5,8.0019 8,8.0019 8,9.9999 9,10.9999 11.996,8.0019 11.996,7.0019z\" />\n\t\t<GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1M9,5.4155L10.996,7.4155 10.996,7.5865 9,9.5855z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/SwitchSourceOrTarget.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ClipGeometry=\"M0,0 V16 H16 V0 H0 Z\">\n\t<DrawingGroup.Children>\n\t\t<GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n\t\t<GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M4.5855,1.9996L0.5855,6.0006 2.5855,7.9996 2.9995,7.9996 2.9995,12.0006 8.5865,12.0006 6.5865,14.0006 11.4135,14.0006 15.4145,9.9996 13.4145,7.9996 12.9995,7.9996 12.9995,4.0006 7.4145,4.0006 9.4145,1.9996z\" />\n\t\t<GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M13,9L4,9 4,11 11,11 9,13 11,13 14,10z M12,7L3,7 2,6 5,3 7,3 5,5 12,5z\" />\n\t</DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/TypeIcon.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.ILSpy\n{\n\tinternal enum TypeIcon\n\t{\n\t\tClass,\n\t\tEnum,\n\t\tStruct,\n\t\tInterface,\n\t\tDelegate\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Images/ViewCode.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M4.2327,2.3533L5.8787,4.0003 -0.000299999999999301,4.0003 -0.000299999999999301,7.0003 5.8787,7.0003 4.2327,8.6463 4.5857,8.9993 1.9997,8.9993 1.9997,12.0003 6.0007,12.0003 6.0007,15.0003 15.0007,15.0003 15.0007,12.0003 14.0007,12.0003 14.0007,8.9993 15.0007,8.9993 15.0007,6.0003 16.0007,6.0003 16.0007,3.0003 9.9997,3.0003 9.9997,3.8783 6.3527,0.232300000000001z M8.9997,8.1213L8.9997,8.9993 8.1207,8.9993z\" />\n    <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1M7,14L14,14 14,13 7,13z M13,10L3,10 3,11 13,11z M14,7L10,7 10,8 14,8z M15,5L11,5 11,4 15,4z\" />\n    <GeometryDrawing Brush=\"#FF00529C\" Geometry=\"F1M10.207,5.5L6.353,9.354 5.646,8.646 8.293,6 1,6 1,5 8.293,5 5.646,2.354 6.353,1.646z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/VirtualMethod.xaml",
    "content": "<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ClipGeometry=\"M0,0 V16 H16 V0 H0 Z\">\n  <GeometryDrawing Geometry=\"F1 M16,16z M0,0z M16,16L0,16 0,0 16,0 16,16z\">\n    <GeometryDrawing.Brush>\n      <SolidColorBrush Color=\"#FFF6F6F6\" Opacity=\"0\" />\n    </GeometryDrawing.Brush>\n  </GeometryDrawing>\n  <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M14.712363,1.9097912L14.712363,6.7016619 11.276564,9.1241143 10.760481,9.1241143 6.7287634,6.6047182 6.7287634,1.8972455 10.48961,0 11.127156,0z\" />\n  <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1 M16,16z M0,0z M13.409326,2.5079909L10.998279,4.0032051 8.1914729,2.4361385 10.802111,1.1194148z M7.8692777,2.909452L10.720563,4.5016099 10.720563,7.7549269 7.8692777,5.9728733z M11.290821,7.7190006L11.290821,4.4924858 13.571849,3.0782481 13.571849,6.1103053z\" />\n  <GeometryDrawing Brush=\"#FF652D90\" Geometry=\"F1 M16,16z M0,0z M10.809523,0.47730523L7.2990205,2.2479537 7.2990205,6.2882255 11.015387,8.6108829 14.142106,6.4056984 14.142106,2.2525157z M13.409326,2.5079909L10.998279,4.0032051 8.1914729,2.4361385 10.802111,1.1194148z M7.8692777,2.909452L10.720563,4.5016099 10.720563,7.7549269 7.8692777,5.9728733z M11.290821,7.7190006L11.290821,4.4924858 13.571849,3.0782481 13.571849,6.1103053z\" />\n  <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M9.6816129,8.7585278L9.6816129,13.548601 6.2471024,15.970143 5.7312144,15.970143 1.7010089,13.451692 1.7010089,8.7459868 5.4604432,6.8494533 6.0977517,6.8494533z\" />\n  <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1 M16,16z M0,0z M8.3790645,9.3565032L5.9689214,10.851156 3.16317,9.2846777 5.7728268,7.9684481z M2.8410948,9.7578136L5.6913109,11.349374 5.6913109,14.60147 2.8410948,12.820085z M6.2613539,14.565557L6.2613539,11.340253 8.541527,9.9265461 8.541527,12.957466z\" />\n  <GeometryDrawing Brush=\"#FF652D90\" Geometry=\"F1 M16,16z M0,0z M5.7802377,7.3265795L2.271052,9.0965632 2.271052,13.135319 5.9860227,15.457105 9.1115699,13.252748 9.1115699,9.1011244z M8.3790645,9.3565032L5.9689214,10.851156 3.16317,9.2846777 5.7728268,7.9684481z M2.8410948,9.7578136L5.6913109,11.349374 5.6913109,14.60147 2.8410948,12.820085z M6.2613539,14.565557L6.2613539,11.340253 8.541527,9.9265461 8.541527,12.957466z\" />\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/Warning.xaml",
    "content": "<!-- This file was generated by the AiToXaml tool.-->\n<!-- Tool Version: 14.0.22307.0 -->\n<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Children>\n    <GeometryDrawing Brush=\"#00FFFFFF\" Geometry=\"F1M16,16L0,16 0,0 16,0z\" />\n    <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1M7.0002,-0.000199999999999534L0.000200000000000422,13.9998 2.0002,15.9998 14.0002,15.9998 16.0002,13.9998 9.0002,-0.000199999999999534z\" />\n    <GeometryDrawing Brush=\"#FFFFCC00\" Geometry=\"F1M9,10L7,10 7,5 9,5z M9,13L7,13 7,11 9,11z M8.382,1L7.618,1 1.217,13.803 2.5,15 13.5,15 14.783,13.803z\" />\n    <GeometryDrawing Brush=\"#FF000000\" Geometry=\"F1M9,11L7,11 7,13 9,13z M9,10L7,10 7,5 9,5z\" />\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/WebAssembly.xaml",
    "content": "<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ClipGeometry=\"M0,0 V612 H612 V0 H0 Z\">\n  <DrawingGroup.Transform>\n\t<TranslateTransform X=\"0\" Y=\"2.6645352591003757E-15\" />\n  </DrawingGroup.Transform>\n  <GeometryDrawing Brush=\"#FF654FF0\" Geometry=\"F1 M612,612z M0,0z M376,0C376,1.08 376,2.16 376,3.3 376,42.06 344.58,73.47 305.83,73.47 267.07,73.47 235.66,42.05 235.66,3.3L235.66,3.3C235.66,2.16,235.66,1.08,235.66,-2.66453525910038E-15L0,0 0,612 612,612 612,0z\" />\n  <GeometryDrawing Brush=\"#FFFFFFFF\" Geometry=\"F1 M612,612z M0,0z M142.16,329.81L182.72,329.81 210.41,477.28 210.91,477.28 244.19,329.81 282.13,329.81 312.19,479.09 312.78,479.09 344.34,329.81 384.12,329.81 332.43,546.5 292.18,546.5 262.37,399.03 261.59,399.03 229.68,546.5 188.68,546.5z M429.85,329.81L493.79,329.81 557.29,546.5 515.45,546.5 501.64,498.28 428.8,498.28 418.14,546.5 377.39,546.5z M454.19,383.22L436.5,462.72 491.56,462.72 471.25,383.22z\" />\n</DrawingGroup>\n"
  },
  {
    "path": "ILSpy/Images/WpfWindowsTreeNodeImagesProvider.cs",
    "content": "using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;\n\nnamespace ICSharpCode.ILSpy\n{\n\tpublic class WpfWindowsTreeNodeImagesProvider : ITreeNodeImagesProvider\n\t{\n\t\tpublic object Assembly => Images.Assembly;\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Images/ZoomIn.xaml",
    "content": "<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Transform>\n    <TranslateTransform X=\"0\" Y=\"10.615\" />\n  </DrawingGroup.Transform>\n  <DrawingGroup.Children>\n    <GeometryDrawing Geometry=\"F1 M16,16z M0,0z M16,16L0,16 0,0 16,0 16,16z\">\n    <GeometryDrawing.Brush>\n      <SolidColorBrush Color=\"#FFF6F6F6\" Opacity=\"0\" />\n    </GeometryDrawing.Brush>\n  </GeometryDrawing>\n  <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M16,5.833A5.84,5.84,0,0,1,10.167,11.666A5.688,5.688,0,0,1,7.254,10.866L2.56,15.559A1.494,1.494,0,0,1,0.439,15.561A1.501,1.501,0,0,1,0.439,13.44L5.133,8.745A5.69,5.69,0,0,1,4.333,5.834C4.333,2.617 6.95,0 10.167,0 13.384,0 16,2.617 16,5.833z\" />\n  <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1 M16,16z M0,0z M14,5.833A3.837,3.837,0,0,1,10.167,9.666C8.053,9.666 6.334,7.946 6.334,5.833 6.334,3.72 8.053,2 10.167,2A3.838,3.838,0,0,1,14,5.833z\" />\n  <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1 M16,16z M0,0z M10.167,1A4.84,4.84,0,0,0,5.333,5.833C5.333,6.985,5.755,8.03,6.43,8.861L1.146,14.146A0.5,0.5,0,0,0,1.854,14.854L7.138,9.569C7.97,10.245 9.015,10.667 10.167,10.667 12.832,10.667 15,8.499 15,5.834 15,3.169 12.832,1 10.167,1z M10.167,9.667C8.053,9.667 6.334,7.947 6.334,5.834 6.334,3.721 8.053,2 10.167,2 12.28,2 14,3.72 14,5.833 14,7.946 12.28,9.667 10.167,9.667z\" />\n  <GeometryDrawing Brush=\"#FF424242\">\n    <GeometryDrawing.Geometry>\n      <RectangleGeometry RadiusX=\"0\" RadiusY=\"0\" Rect=\"7.865,5.3462,4.6154,0.8846\" />\n    </GeometryDrawing.Geometry>\n  </GeometryDrawing>\n  <DrawingGroup Transform=\"6.12303176911189E-17,1,-1,6.12303176911189E-17,0,0\">\n    <GeometryDrawing Brush=\"#FF424242\">\n      <GeometryDrawing.Geometry>\n        <RectangleGeometry RadiusX=\"0\" RadiusY=\"0\" Rect=\"3.4808,-10.615,4.6154,0.8846\" />\n      </GeometryDrawing.Geometry>\n    </GeometryDrawing>\n  </DrawingGroup>\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/Images/ZoomOut.xaml",
    "content": "<DrawingGroup xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n  <DrawingGroup.Transform>\n    <TranslateTransform X=\"0\" Y=\"10.615\" />\n  </DrawingGroup.Transform>\n  <DrawingGroup.Children>\n  <GeometryDrawing Geometry=\"F1 M16,16z M0,0z M16,16L0,16 0,0 16,0 16,16z\">\n    <GeometryDrawing.Brush>\n      <SolidColorBrush Color=\"#FFF6F6F6\" Opacity=\"0\" />\n    </GeometryDrawing.Brush>\n  </GeometryDrawing>\n  <GeometryDrawing Brush=\"#FFF6F6F6\" Geometry=\"F1 M16,16z M0,0z M16,5.833A5.84,5.84,0,0,1,10.167,11.666A5.688,5.688,0,0,1,7.254,10.866L2.56,15.559A1.494,1.494,0,0,1,0.439,15.561A1.501,1.501,0,0,1,0.439,13.44L5.133,8.745A5.69,5.69,0,0,1,4.333,5.834C4.333,2.617 6.95,0 10.167,0 13.384,0 16,2.617 16,5.833z\" />\n  <GeometryDrawing Brush=\"#FFF0EFF1\" Geometry=\"F1 M16,16z M0,0z M14,5.833A3.837,3.837,0,0,1,10.167,9.666C8.053,9.666 6.334,7.946 6.334,5.833 6.334,3.72 8.053,2 10.167,2A3.838,3.838,0,0,1,14,5.833z\" />\n  <GeometryDrawing Brush=\"#FF424242\" Geometry=\"F1 M16,16z M0,0z M10.167,1A4.84,4.84,0,0,0,5.333,5.833C5.333,6.985,5.755,8.03,6.43,8.861L1.146,14.146A0.5,0.5,0,0,0,1.854,14.854L7.138,9.569C7.97,10.245 9.015,10.667 10.167,10.667 12.832,10.667 15,8.499 15,5.834 15,3.169 12.832,1 10.167,1z M10.167,9.667C8.053,9.667 6.334,7.947 6.334,5.834 6.334,3.721 8.053,2 10.167,2 12.28,2 14,3.72 14,5.833 14,7.946 12.28,9.667 10.167,9.667z\" />\n  <GeometryDrawing Brush=\"#FF424242\">\n    <GeometryDrawing.Geometry>\n      <RectangleGeometry RadiusX=\"0\" RadiusY=\"0\" Rect=\"7.865,5.3462,4.6154,0.8846\" />\n    </GeometryDrawing.Geometry>\n  </GeometryDrawing>\n  </DrawingGroup.Children>\n</DrawingGroup>"
  },
  {
    "path": "ILSpy/LanguageSettings.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Xml.Linq;\n\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.Settings;\n\nusing TomsToolbox.Wpf;\n\n#nullable enable\n\nnamespace ICSharpCode.ILSpy\n{\n\t/// <summary>\n\t/// Represents the filters applied to the tree view.\n\t/// </summary>\n\tpublic class LanguageSettings : ObservableObjectBase, IChildSettings\n\t{\n\t\t/// <summary>\n\t\t/// This dictionary is necessary to remember language versions across language changes. For example, \n\t\t/// the user first select C# 10, then switches to IL, then switches back to C#. After that we must be\n\t\t/// able to restore the original selection (i.e., C# 10).\n\t\t/// </summary>\n\t\tprivate readonly Dictionary<Language, LanguageVersion> languageVersionHistory = new Dictionary<Language, LanguageVersion>();\n\n\t\tpublic LanguageSettings(XElement element, ISettingsSection parent)\n\t\t{\n\t\t\tParent = parent;\n\t\t\tthis.ShowApiLevel = (ApiVisibility?)(int?)element.Element(\"ShowAPILevel\") ?? ApiVisibility.PublicAndInternal;\n\t\t\tthis.LanguageId = (string?)element.Element(\"Language\");\n\t\t\tthis.LanguageVersionId = (string?)element.Element(\"LanguageVersion\");\n\t\t}\n\n\t\tpublic ISettingsSection Parent { get; }\n\n\t\tpublic XElement SaveAsXml()\n\t\t{\n\t\t\treturn new XElement(\n\t\t\t\t\"FilterSettings\",\n\t\t\t\tnew XElement(\"ShowAPILevel\", (int)this.ShowApiLevel),\n\t\t\t\tnew XElement(\"Language\", this.LanguageId),\n\t\t\t\tnew XElement(\"LanguageVersion\", this.LanguageVersionId)\n\t\t\t);\n\t\t}\n\n\t\tApiVisibility showApiLevel;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets whether public, internal or all API members should be shown.\n\t\t/// </summary>\n\t\tpublic ApiVisibility ShowApiLevel {\n\t\t\tget { return showApiLevel; }\n\t\t\tset {\n\t\t\t\tif (showApiLevel != value)\n\t\t\t\t{\n\t\t\t\t\tshowApiLevel = value;\n\t\t\t\t\tOnPropertyChanged(nameof(ShowApiLevel));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic bool ApiVisPublicOnly {\n\t\t\tget { return showApiLevel == ApiVisibility.PublicOnly; }\n\t\t\tset {\n\t\t\t\tif (value == (showApiLevel == ApiVisibility.PublicOnly))\n\t\t\t\t\treturn;\n\t\t\t\tShowApiLevel = ApiVisibility.PublicOnly;\n\t\t\t\tOnPropertyChanged(nameof(ApiVisPublicOnly));\n\t\t\t\tOnPropertyChanged(nameof(ApiVisPublicAndInternal));\n\t\t\t\tOnPropertyChanged(nameof(ApiVisAll));\n\t\t\t}\n\t\t}\n\n\t\tpublic bool ApiVisPublicAndInternal {\n\t\t\tget { return showApiLevel == ApiVisibility.PublicAndInternal; }\n\t\t\tset {\n\t\t\t\tif (value == (showApiLevel == ApiVisibility.PublicAndInternal))\n\t\t\t\t\treturn;\n\t\t\t\tShowApiLevel = ApiVisibility.PublicAndInternal;\n\t\t\t\tOnPropertyChanged(nameof(ApiVisPublicOnly));\n\t\t\t\tOnPropertyChanged(nameof(ApiVisPublicAndInternal));\n\t\t\t\tOnPropertyChanged(nameof(ApiVisAll));\n\t\t\t}\n\t\t}\n\n\t\tpublic bool ApiVisAll {\n\t\t\tget { return showApiLevel == ApiVisibility.All; }\n\t\t\tset {\n\t\t\t\tif (value == (showApiLevel == ApiVisibility.All))\n\t\t\t\t\treturn;\n\t\t\t\tShowApiLevel = ApiVisibility.All;\n\t\t\t\tOnPropertyChanged(nameof(ApiVisPublicOnly));\n\t\t\t\tOnPropertyChanged(nameof(ApiVisPublicAndInternal));\n\t\t\t\tOnPropertyChanged(nameof(ApiVisAll));\n\t\t\t}\n\t\t}\n\n\t\tstring? languageId;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the current language.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// While this isn't related to filtering, having it as part of the FilterSettings\n\t\t/// makes it easy to pass it down into all tree nodes.\n\t\t/// </remarks>\n\t\tpublic string? LanguageId {\n\t\t\tget => languageId;\n\t\t\tset => SetProperty(ref languageId, value);\n\t\t}\n\n\t\tstring? languageVersionId;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the current language version.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// While this isn't related to filtering, having it as part of the FilterSettings\n\t\t/// makes it easy to pass it down into all tree nodes.\n\t\t/// </remarks>\n\t\tpublic string? LanguageVersionId {\n\t\t\tget { return languageVersionId; }\n\t\t\tset => SetProperty(ref languageVersionId, value);\n\t\t}\n\n\t\t// This class has been initially called FilterSettings, but then has been Hijacked to store language settings as well.\n\t\t// While the filter settings were some sort of local, the language settings are global. This is a bit of a mess.\n\t\t// There has been a lot of workarounds cloning the FilterSettings to pass them down to the tree nodes, without messing up the global language settings.\n\t\t// Finally, this filtering was not used at all, so this SearchTerm is just a placeholder to make the filtering code compile, in case someone wants to reactivate filtering in the future.\n\t\tpublic string SearchTerm => string.Empty;\n\n\t\tpublic bool SearchTermMatches(string value)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Languages/CSharpBracketSearcher.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\n\nusing ICSharpCode.AvalonEdit.Document;\nusing ICSharpCode.ILSpy.TextView;\n\nnamespace ICSharpCode.ILSpy\n{\n\t/// <summary>\n\t/// Searches matching brackets for C#.\n\t/// </summary>\n\tclass CSharpBracketSearcher : IBracketSearcher\n\t{\n\t\tstring openingBrackets = \"([{\";\n\t\tstring closingBrackets = \")]}\";\n\n\t\tpublic BracketSearchResult SearchBracket(IDocument document, int offset)\n\t\t{\n\t\t\tif (offset > 0)\n\t\t\t{\n\t\t\t\tchar c = document.GetCharAt(offset - 1);\n\t\t\t\tint index = openingBrackets.IndexOf(c);\n\t\t\t\tint otherOffset = -1;\n\t\t\t\tif (index > -1)\n\t\t\t\t\totherOffset = SearchBracketForward(document, offset, openingBrackets[index], closingBrackets[index]);\n\n\t\t\t\tindex = closingBrackets.IndexOf(c);\n\t\t\t\tif (index > -1)\n\t\t\t\t\totherOffset = SearchBracketBackward(document, offset - 2, openingBrackets[index], closingBrackets[index]);\n\n\t\t\t\tif (otherOffset > -1)\n\t\t\t\t{\n\t\t\t\t\tvar result = new BracketSearchResult(Math.Min(offset - 1, otherOffset), 1,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t Math.Max(offset - 1, otherOffset), 1);\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\t#region SearchBracket helper functions\n\t\tstatic int ScanLineStart(IDocument document, int offset)\n\t\t{\n\t\t\tfor (int i = offset - 1; i > 0; --i)\n\t\t\t{\n\t\t\t\tif (document.GetCharAt(i) == '\\n')\n\t\t\t\t\treturn i + 1;\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the type of code at offset.<br/>\n\t\t/// 0 = Code,<br/>\n\t\t/// 1 = Comment,<br/>\n\t\t/// 2 = String<br/>\n\t\t/// Block comments and multiline strings are not supported.\n\t\t/// </summary>\n\t\tstatic int GetStartType(IDocument document, int linestart, int offset)\n\t\t{\n\t\t\tbool inString = false;\n\t\t\tbool inChar = false;\n\t\t\tbool verbatim = false;\n\t\t\tint result = 0;\n\t\t\tfor (int i = linestart; i < offset; i++)\n\t\t\t{\n\t\t\t\tswitch (document.GetCharAt(i))\n\t\t\t\t{\n\t\t\t\t\tcase '/':\n\t\t\t\t\t\tif (!inString && !inChar && i + 1 < document.TextLength)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (document.GetCharAt(i + 1) == '/')\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tresult = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\"':\n\t\t\t\t\t\tif (!inChar)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (inString && verbatim)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (i + 1 < document.TextLength && document.GetCharAt(i + 1) == '\"')\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t++i; // skip escaped quote\n\t\t\t\t\t\t\t\t\tinString = false; // let the string go on\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tverbatim = false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (!inString && i > 0 && document.GetCharAt(i - 1) == '@')\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tverbatim = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tinString = !inString;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\\'':\n\t\t\t\t\t\tif (!inString)\n\t\t\t\t\t\t\tinChar = !inChar;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\\\\':\n\t\t\t\t\t\tif ((inString && !verbatim) || inChar)\n\t\t\t\t\t\t\t++i; // skip next character\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn (inString || inChar) ? 2 : result;\n\t\t}\n\t\t#endregion\n\n\t\t#region SearchBracketBackward\n\t\tint SearchBracketBackward(IDocument document, int offset, char openBracket, char closingBracket)\n\t\t{\n\t\t\tif (offset + 1 >= document.TextLength)\n\t\t\t\treturn -1;\n\t\t\t// this method parses a c# document backwards to find the matching bracket\n\n\t\t\t// first try \"quick find\" - find the matching bracket if there is no string/comment in the way\n\t\t\tint quickResult = QuickSearchBracketBackward(document, offset, openBracket, closingBracket);\n\t\t\tif (quickResult >= 0)\n\t\t\t\treturn quickResult;\n\n\t\t\t// we need to parse the line from the beginning, so get the line start position\n\t\t\tint linestart = ScanLineStart(document, offset + 1);\n\n\t\t\t// we need to know where offset is - in a string/comment or in normal code?\n\t\t\t// ignore cases where offset is in a block comment\n\t\t\tint starttype = GetStartType(document, linestart, offset + 1);\n\t\t\tif (starttype == 1)\n\t\t\t{\n\t\t\t\treturn -1; // start position is in a comment\n\t\t\t}\n\n\t\t\t// I don't see any possibility to parse a C# document backwards...\n\t\t\t// We have to do it forwards and push all bracket positions on a stack.\n\t\t\tStack<int> bracketStack = new Stack<int>();\n\t\t\tbool blockComment = false;\n\t\t\tbool lineComment = false;\n\t\t\tbool inChar = false;\n\t\t\tbool inString = false;\n\t\t\tbool verbatim = false;\n\n\t\t\tfor (int i = 0; i <= offset; ++i)\n\t\t\t{\n\t\t\t\tchar ch = document.GetCharAt(i);\n\t\t\t\tswitch (ch)\n\t\t\t\t{\n\t\t\t\t\tcase '\\r':\n\t\t\t\t\tcase '\\n':\n\t\t\t\t\t\tlineComment = false;\n\t\t\t\t\t\tinChar = false;\n\t\t\t\t\t\tif (!verbatim)\n\t\t\t\t\t\t\tinString = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '/':\n\t\t\t\t\t\tif (blockComment)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tDebug.Assert(i > 0);\n\t\t\t\t\t\t\tif (document.GetCharAt(i - 1) == '*')\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tblockComment = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!inString && !inChar && i + 1 < document.TextLength)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!blockComment && document.GetCharAt(i + 1) == '/')\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlineComment = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!lineComment && document.GetCharAt(i + 1) == '*')\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tblockComment = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\"':\n\t\t\t\t\t\tif (!(inChar || lineComment || blockComment))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (inString && verbatim)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (i + 1 < document.TextLength && document.GetCharAt(i + 1) == '\"')\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t++i; // skip escaped quote\n\t\t\t\t\t\t\t\t\tinString = false; // let the string go\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tverbatim = false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (!inString && offset > 0 && document.GetCharAt(i - 1) == '@')\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tverbatim = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tinString = !inString;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\\'':\n\t\t\t\t\t\tif (!(inString || lineComment || blockComment))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tinChar = !inChar;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\\\\':\n\t\t\t\t\t\tif ((inString && !verbatim) || inChar)\n\t\t\t\t\t\t\t++i; // skip next character\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif (ch == openBracket)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!(inString || inChar || lineComment || blockComment))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tbracketStack.Push(i);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (ch == closingBracket)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!(inString || inChar || lineComment || blockComment))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (bracketStack.Count > 0)\n\t\t\t\t\t\t\t\t\tbracketStack.Pop();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (bracketStack.Count > 0)\n\t\t\t\treturn (int)bracketStack.Pop();\n\t\t\treturn -1;\n\t\t}\n\t\t#endregion\n\n\t\t#region SearchBracketForward\n\t\tint SearchBracketForward(IDocument document, int offset, char openBracket, char closingBracket)\n\t\t{\n\t\t\tbool inString = false;\n\t\t\tbool inChar = false;\n\t\t\tbool verbatim = false;\n\n\t\t\tbool lineComment = false;\n\t\t\tbool blockComment = false;\n\n\t\t\tif (offset < 0)\n\t\t\t\treturn -1;\n\n\t\t\t// first try \"quick find\" - find the matching bracket if there is no string/comment in the way\n\t\t\tint quickResult = QuickSearchBracketForward(document, offset, openBracket, closingBracket);\n\t\t\tif (quickResult >= 0)\n\t\t\t\treturn quickResult;\n\n\t\t\t// we need to parse the line from the beginning, so get the line start position\n\t\t\tint linestart = ScanLineStart(document, offset);\n\n\t\t\t// we need to know where offset is - in a string/comment or in normal code?\n\t\t\t// ignore cases where offset is in a block comment\n\t\t\tint starttype = GetStartType(document, linestart, offset);\n\t\t\tif (starttype != 0)\n\t\t\t\treturn -1; // start position is in a comment/string\n\n\t\t\tint brackets = 1;\n\n\t\t\twhile (offset < document.TextLength)\n\t\t\t{\n\t\t\t\tchar ch = document.GetCharAt(offset);\n\t\t\t\tswitch (ch)\n\t\t\t\t{\n\t\t\t\t\tcase '\\r':\n\t\t\t\t\tcase '\\n':\n\t\t\t\t\t\tlineComment = false;\n\t\t\t\t\t\tinChar = false;\n\t\t\t\t\t\tif (!verbatim)\n\t\t\t\t\t\t\tinString = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '/':\n\t\t\t\t\t\tif (blockComment)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tDebug.Assert(offset > 0);\n\t\t\t\t\t\t\tif (document.GetCharAt(offset - 1) == '*')\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tblockComment = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!inString && !inChar && offset + 1 < document.TextLength)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!blockComment && document.GetCharAt(offset + 1) == '/')\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlineComment = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!lineComment && document.GetCharAt(offset + 1) == '*')\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tblockComment = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\"':\n\t\t\t\t\t\tif (!(inChar || lineComment || blockComment))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (inString && verbatim)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (offset + 1 < document.TextLength && document.GetCharAt(offset + 1) == '\"')\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t++offset; // skip escaped quote\n\t\t\t\t\t\t\t\t\tinString = false; // let the string go\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tverbatim = false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (!inString && offset > 0 && document.GetCharAt(offset - 1) == '@')\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tverbatim = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tinString = !inString;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\\'':\n\t\t\t\t\t\tif (!(inString || lineComment || blockComment))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tinChar = !inChar;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '\\\\':\n\t\t\t\t\t\tif ((inString && !verbatim) || inChar)\n\t\t\t\t\t\t\t++offset; // skip next character\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif (ch == openBracket)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!(inString || inChar || lineComment || blockComment))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t++brackets;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (ch == closingBracket)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!(inString || inChar || lineComment || blockComment))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t--brackets;\n\t\t\t\t\t\t\t\tif (brackets == 0)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\treturn offset;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t++offset;\n\t\t\t}\n\t\t\treturn -1;\n\t\t}\n\t\t#endregion\n\n\t\tint QuickSearchBracketBackward(IDocument document, int offset, char openBracket, char closingBracket)\n\t\t{\n\t\t\tint brackets = -1;\n\t\t\t// first try \"quick find\" - find the matching bracket if there is no string/comment in the way\n\t\t\tfor (int i = offset; i >= 0; --i)\n\t\t\t{\n\t\t\t\tchar ch = document.GetCharAt(i);\n\t\t\t\tif (ch == openBracket)\n\t\t\t\t{\n\t\t\t\t\t++brackets;\n\t\t\t\t\tif (brackets == 0)\n\t\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t\telse if (ch == closingBracket)\n\t\t\t\t{\n\t\t\t\t\t--brackets;\n\t\t\t\t}\n\t\t\t\telse if (ch == '\"')\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse if (ch == '\\'')\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse if (ch == '/' && i > 0)\n\t\t\t\t{\n\t\t\t\t\tif (document.GetCharAt(i - 1) == '/')\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tif (document.GetCharAt(i - 1) == '*')\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1;\n\t\t}\n\n\t\tint QuickSearchBracketForward(IDocument document, int offset, char openBracket, char closingBracket)\n\t\t{\n\t\t\tint brackets = 1;\n\t\t\t// try \"quick find\" - find the matching bracket if there is no string/comment in the way\n\t\t\tfor (int i = offset; i < document.TextLength; ++i)\n\t\t\t{\n\t\t\t\tchar ch = document.GetCharAt(i);\n\t\t\t\tif (ch == openBracket)\n\t\t\t\t{\n\t\t\t\t\t++brackets;\n\t\t\t\t}\n\t\t\t\telse if (ch == closingBracket)\n\t\t\t\t{\n\t\t\t\t\t--brackets;\n\t\t\t\t\tif (brackets == 0)\n\t\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t\telse if (ch == '\"')\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse if (ch == '\\'')\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse if (ch == '/' && i > 0)\n\t\t\t\t{\n\t\t\t\t\tif (document.GetCharAt(i - 1) == '/')\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse if (ch == '*' && i > 0)\n\t\t\t\t{\n\t\t\t\t\tif (document.GetCharAt(i - 1) == '/')\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Languages/CSharpHighlightingTokenWriter.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX.Extensions;\n\nnamespace ICSharpCode.ILSpy\n{\n\tclass CSharpHighlightingTokenWriter : DecoratingTokenWriter\n\t{\n\t\tHighlightingColor visibilityKeywordsColor;\n\t\tHighlightingColor namespaceKeywordsColor;\n\t\tHighlightingColor structureKeywordsColor;\n\t\tHighlightingColor gotoKeywordsColor;\n\t\tHighlightingColor queryKeywordsColor;\n\t\tHighlightingColor exceptionKeywordsColor;\n\t\tHighlightingColor checkedKeywordColor;\n\t\tHighlightingColor unsafeKeywordsColor;\n\t\tHighlightingColor valueTypeKeywordsColor;\n\t\tHighlightingColor referenceTypeKeywordsColor;\n\t\tHighlightingColor operatorKeywordsColor;\n\t\tHighlightingColor parameterModifierColor;\n\t\tHighlightingColor modifiersColor;\n\t\tHighlightingColor accessorKeywordsColor;\n\t\tHighlightingColor attributeKeywordsColor;\n\n\t\tHighlightingColor referenceTypeColor;\n\t\tHighlightingColor valueTypeColor;\n\t\tHighlightingColor interfaceTypeColor;\n\t\tHighlightingColor enumerationTypeColor;\n\t\tHighlightingColor typeParameterTypeColor;\n\t\tHighlightingColor delegateTypeColor;\n\n\t\tHighlightingColor methodCallColor;\n\t\tHighlightingColor methodDeclarationColor;\n\t\tHighlightingColor fieldDeclarationColor;\n\t\tHighlightingColor fieldAccessColor;\n\t\tHighlightingColor propertyDeclarationColor;\n\t\tHighlightingColor propertyAccessColor;\n\t\tHighlightingColor eventDeclarationColor;\n\t\tHighlightingColor eventAccessColor;\n\n\t\tHighlightingColor variableColor;\n\t\tHighlightingColor parameterColor;\n\n\t\tHighlightingColor valueKeywordColor;\n\t\tHighlightingColor thisKeywordColor;\n\t\tHighlightingColor trueKeywordColor;\n\t\tHighlightingColor typeKeywordsColor;\n\n\t\tpublic RichTextModel HighlightingModel { get; } = new RichTextModel();\n\n\t\tpublic CSharpHighlightingTokenWriter(TokenWriter decoratedWriter, ISmartTextOutput textOutput = null, ILocatable locatable = null)\n\t\t\t: base(decoratedWriter)\n\t\t{\n\t\t\tvar highlighting = HighlightingManager.Instance.GetDefinition(\"C#\");\n\n\t\t\tthis.locatable = locatable;\n\t\t\tthis.textOutput = textOutput;\n\n\t\t\tthis.visibilityKeywordsColor = highlighting.GetNamedColor(\"Visibility\");\n\t\t\tthis.namespaceKeywordsColor = highlighting.GetNamedColor(\"NamespaceKeywords\");\n\t\t\tthis.structureKeywordsColor = highlighting.GetNamedColor(\"Keywords\");\n\t\t\tthis.gotoKeywordsColor = highlighting.GetNamedColor(\"GotoKeywords\");\n\t\t\tthis.queryKeywordsColor = highlighting.GetNamedColor(\"QueryKeywords\");\n\t\t\tthis.exceptionKeywordsColor = highlighting.GetNamedColor(\"ExceptionKeywords\");\n\t\t\tthis.checkedKeywordColor = highlighting.GetNamedColor(\"CheckedKeyword\");\n\t\t\tthis.unsafeKeywordsColor = highlighting.GetNamedColor(\"UnsafeKeywords\");\n\t\t\tthis.valueTypeKeywordsColor = highlighting.GetNamedColor(\"ValueTypeKeywords\");\n\t\t\tthis.referenceTypeKeywordsColor = highlighting.GetNamedColor(\"ReferenceTypeKeywords\");\n\t\t\tthis.operatorKeywordsColor = highlighting.GetNamedColor(\"OperatorKeywords\");\n\t\t\tthis.parameterModifierColor = highlighting.GetNamedColor(\"ParameterModifiers\");\n\t\t\tthis.modifiersColor = highlighting.GetNamedColor(\"Modifiers\");\n\t\t\tthis.accessorKeywordsColor = highlighting.GetNamedColor(\"GetSetAddRemove\");\n\n\t\t\tthis.referenceTypeColor = highlighting.GetNamedColor(\"ReferenceTypes\");\n\t\t\tthis.valueTypeColor = highlighting.GetNamedColor(\"ValueTypes\");\n\t\t\tthis.interfaceTypeColor = highlighting.GetNamedColor(\"InterfaceTypes\");\n\t\t\tthis.enumerationTypeColor = highlighting.GetNamedColor(\"EnumTypes\");\n\t\t\tthis.typeParameterTypeColor = highlighting.GetNamedColor(\"TypeParameters\");\n\t\t\tthis.delegateTypeColor = highlighting.GetNamedColor(\"DelegateTypes\");\n\t\t\tthis.methodDeclarationColor = highlighting.GetNamedColor(\"MethodDeclaration\");\n\t\t\tthis.methodCallColor = highlighting.GetNamedColor(\"MethodCall\");\n\t\t\tthis.fieldDeclarationColor = highlighting.GetNamedColor(\"FieldDeclaration\");\n\t\t\tthis.fieldAccessColor = highlighting.GetNamedColor(\"FieldAccess\");\n\t\t\tthis.propertyDeclarationColor = highlighting.GetNamedColor(\"PropertyDeclaration\");\n\t\t\tthis.propertyAccessColor = highlighting.GetNamedColor(\"PropertyAccess\");\n\t\t\tthis.eventDeclarationColor = highlighting.GetNamedColor(\"EventDeclaration\");\n\t\t\tthis.eventAccessColor = highlighting.GetNamedColor(\"EventAccess\");\n\t\t\tthis.variableColor = highlighting.GetNamedColor(\"Variable\");\n\t\t\tthis.parameterColor = highlighting.GetNamedColor(\"Parameter\");\n\t\t\tthis.valueKeywordColor = highlighting.GetNamedColor(\"NullOrValueKeywords\");\n\t\t\tthis.thisKeywordColor = highlighting.GetNamedColor(\"ThisOrBaseReference\");\n\t\t\tthis.trueKeywordColor = highlighting.GetNamedColor(\"TrueFalse\");\n\t\t\tthis.typeKeywordsColor = highlighting.GetNamedColor(\"TypeKeywords\");\n\t\t\tthis.attributeKeywordsColor = highlighting.GetNamedColor(\"AttributeKeywords\");\n\t\t\t//this.externAliasKeywordColor = ...;\n\t\t}\n\n\t\tpublic override void WriteKeyword(Role role, string keyword)\n\t\t{\n\t\t\tHighlightingColor color = null;\n\t\t\tswitch (keyword)\n\t\t\t{\n\t\t\t\tcase \"namespace\":\n\t\t\t\tcase \"using\":\n\t\t\t\t\tif (role == UsingStatement.UsingKeywordRole)\n\t\t\t\t\t\tcolor = structureKeywordsColor;\n\t\t\t\t\telse\n\t\t\t\t\t\tcolor = namespaceKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"this\":\n\t\t\t\tcase \"base\":\n\t\t\t\t\tcolor = thisKeywordColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"true\":\n\t\t\t\tcase \"false\":\n\t\t\t\t\tcolor = trueKeywordColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"public\":\n\t\t\t\tcase \"internal\":\n\t\t\t\tcase \"protected\":\n\t\t\t\tcase \"private\":\n\t\t\t\t\tcolor = visibilityKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"if\":\n\t\t\t\tcase \"else\":\n\t\t\t\tcase \"switch\":\n\t\t\t\tcase \"case\":\n\t\t\t\tcase \"default\":\n\t\t\t\tcase \"while\":\n\t\t\t\tcase \"do\":\n\t\t\t\tcase \"for\":\n\t\t\t\tcase \"foreach\":\n\t\t\t\tcase \"lock\":\n\t\t\t\tcase \"await\":\n\t\t\t\t\tcolor = structureKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"where\":\n\t\t\t\t\tif (nodeStack.PeekOrDefault() is QueryClause)\n\t\t\t\t\t\tcolor = queryKeywordsColor;\n\t\t\t\t\telse\n\t\t\t\t\t\tcolor = structureKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"in\":\n\t\t\t\t\tif (nodeStack.PeekOrDefault() is ForeachStatement)\n\t\t\t\t\t\tcolor = structureKeywordsColor;\n\t\t\t\t\telse if (nodeStack.PeekOrDefault() is QueryClause)\n\t\t\t\t\t\tcolor = queryKeywordsColor;\n\t\t\t\t\telse\n\t\t\t\t\t\tcolor = parameterModifierColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"as\":\n\t\t\t\tcase \"is\":\n\t\t\t\tcase \"new\":\n\t\t\t\tcase \"sizeof\":\n\t\t\t\tcase \"typeof\":\n\t\t\t\tcase \"nameof\":\n\t\t\t\tcase \"stackalloc\":\n\t\t\t\t\tcolor = typeKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"with\":\n\t\t\t\t\tif (role == WithInitializerExpression.WithKeywordRole)\n\t\t\t\t\t\tcolor = typeKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"try\":\n\t\t\t\tcase \"throw\":\n\t\t\t\tcase \"catch\":\n\t\t\t\tcase \"finally\":\n\t\t\t\t\tcolor = exceptionKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"when\":\n\t\t\t\t\tif (role == CatchClause.WhenKeywordRole)\n\t\t\t\t\t\tcolor = exceptionKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"get\":\n\t\t\t\tcase \"set\":\n\t\t\t\tcase \"add\":\n\t\t\t\tcase \"remove\":\n\t\t\t\tcase \"init\":\n\t\t\t\t\tif (role == PropertyDeclaration.GetKeywordRole ||\n\t\t\t\t\t\trole == PropertyDeclaration.SetKeywordRole ||\n\t\t\t\t\t\trole == PropertyDeclaration.InitKeywordRole ||\n\t\t\t\t\t\trole == CustomEventDeclaration.AddKeywordRole ||\n\t\t\t\t\t\trole == CustomEventDeclaration.RemoveKeywordRole)\n\t\t\t\t\t\tcolor = accessorKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"abstract\":\n\t\t\t\tcase \"const\":\n\t\t\t\tcase \"event\":\n\t\t\t\tcase \"extern\":\n\t\t\t\tcase \"override\":\n\t\t\t\tcase \"sealed\":\n\t\t\t\tcase \"static\":\n\t\t\t\tcase \"virtual\":\n\t\t\t\tcase \"volatile\":\n\t\t\t\tcase \"async\":\n\t\t\t\tcase \"partial\":\n\t\t\t\t\tcolor = modifiersColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"readonly\":\n\t\t\t\t\tif (role == ComposedType.ReadonlyRole)\n\t\t\t\t\t\tcolor = parameterModifierColor;\n\t\t\t\t\telse\n\t\t\t\t\t\tcolor = modifiersColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"checked\":\n\t\t\t\tcase \"unchecked\":\n\t\t\t\t\tcolor = checkedKeywordColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"fixed\":\n\t\t\t\tcase \"unsafe\":\n\t\t\t\t\tcolor = unsafeKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"enum\":\n\t\t\t\tcase \"struct\":\n\t\t\t\t\tcolor = valueTypeKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"class\":\n\t\t\t\tcase \"interface\":\n\t\t\t\tcase \"delegate\":\n\t\t\t\tcase \"extension\":\n\t\t\t\t\tcolor = referenceTypeKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"record\":\n\t\t\t\t\tcolor = role == Roles.RecordKeyword ? referenceTypeKeywordsColor : valueTypeKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"select\":\n\t\t\t\tcase \"group\":\n\t\t\t\tcase \"by\":\n\t\t\t\tcase \"into\":\n\t\t\t\tcase \"from\":\n\t\t\t\tcase \"orderby\":\n\t\t\t\tcase \"let\":\n\t\t\t\tcase \"join\":\n\t\t\t\tcase \"on\":\n\t\t\t\tcase \"equals\":\n\t\t\t\t\tif (nodeStack.PeekOrDefault() is QueryClause)\n\t\t\t\t\t\tcolor = queryKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"ascending\":\n\t\t\t\tcase \"descending\":\n\t\t\t\t\tif (nodeStack.PeekOrDefault() is QueryOrdering)\n\t\t\t\t\t\tcolor = queryKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"explicit\":\n\t\t\t\tcase \"implicit\":\n\t\t\t\tcase \"operator\":\n\t\t\t\t\tcolor = operatorKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"params\":\n\t\t\t\tcase \"ref\":\n\t\t\t\tcase \"out\":\n\t\t\t\tcase \"scoped\":\n\t\t\t\t\tcolor = parameterModifierColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"break\":\n\t\t\t\tcase \"continue\":\n\t\t\t\tcase \"goto\":\n\t\t\t\tcase \"yield\":\n\t\t\t\tcase \"return\":\n\t\t\t\t\tcolor = gotoKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (nodeStack.PeekOrDefault() is AttributeSection)\n\t\t\t\tcolor = attributeKeywordsColor;\n\t\t\tif (color != null)\n\t\t\t{\n\t\t\t\tBeginSpan(color);\n\t\t\t}\n\t\t\tbase.WriteKeyword(role, keyword);\n\t\t\tif (color != null)\n\t\t\t{\n\t\t\t\tEndSpan();\n\t\t\t}\n\t\t}\n\n\t\tpublic override void WritePrimitiveType(string type)\n\t\t{\n\t\t\tHighlightingColor color = null;\n\t\t\tswitch (type)\n\t\t\t{\n\t\t\t\tcase \"new\":\n\t\t\t\tcase \"notnull\":\n\t\t\t\t\t// Not sure if reference type or value type\n\t\t\t\t\tcolor = referenceTypeKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"bool\":\n\t\t\t\tcase \"byte\":\n\t\t\t\tcase \"char\":\n\t\t\t\tcase \"decimal\":\n\t\t\t\tcase \"double\":\n\t\t\t\tcase \"enum\":\n\t\t\t\tcase \"float\":\n\t\t\t\tcase \"int\":\n\t\t\t\tcase \"long\":\n\t\t\t\tcase \"sbyte\":\n\t\t\t\tcase \"short\":\n\t\t\t\tcase \"struct\":\n\t\t\t\tcase \"uint\":\n\t\t\t\tcase \"ushort\":\n\t\t\t\tcase \"ulong\":\n\t\t\t\tcase \"unmanaged\":\n\t\t\t\tcase \"nint\":\n\t\t\t\tcase \"nuint\":\n\t\t\t\t\tcolor = valueTypeKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"class\":\n\t\t\t\tcase \"object\":\n\t\t\t\tcase \"string\":\n\t\t\t\tcase \"void\":\n\t\t\t\tcase \"dynamic\":\n\t\t\t\t\tcolor = referenceTypeKeywordsColor;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (color != null)\n\t\t\t{\n\t\t\t\tBeginSpan(color);\n\t\t\t}\n\t\t\tbase.WritePrimitiveType(type);\n\t\t\tif (color != null)\n\t\t\t{\n\t\t\t\tEndSpan();\n\t\t\t}\n\t\t}\n\n\t\tpublic override void WriteIdentifier(Identifier identifier)\n\t\t{\n\t\t\tHighlightingColor color = null;\n\t\t\tif (identifier.Parent?.GetResolveResult() is ILVariableResolveResult rr)\n\t\t\t{\n\t\t\t\tif (rr.Variable.Kind == VariableKind.Parameter)\n\t\t\t\t{\n\t\t\t\t\tif (identifier.Name == \"value\"\n\t\t\t\t\t\t&& identifier.Ancestors.OfType<Accessor>().FirstOrDefault() is { } accessor\n\t\t\t\t\t\t&& accessor.Role != PropertyDeclaration.GetterRole)\n\t\t\t\t\t{\n\t\t\t\t\t\tcolor = valueKeywordColor;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tcolor = parameterColor;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tcolor = variableColor;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (identifier.Parent is AstType)\n\t\t\t{\n\t\t\t\tswitch (identifier.Name)\n\t\t\t\t{\n\t\t\t\t\tcase \"var\":\n\t\t\t\t\t\tcolor = queryKeywordsColor;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"global\":\n\t\t\t\t\t\tcolor = structureKeywordsColor;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tswitch (GetCurrentDefinition())\n\t\t\t{\n\t\t\t\tcase ITypeDefinition t:\n\t\t\t\t\tApplyTypeColor(t, ref color);\n\t\t\t\t\tbreak;\n\t\t\t\tcase IMethod:\n\t\t\t\t\tcolor = methodDeclarationColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase IField:\n\t\t\t\t\tcolor = fieldDeclarationColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase IProperty:\n\t\t\t\t\tcolor = propertyDeclarationColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase IEvent:\n\t\t\t\t\tcolor = eventDeclarationColor;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tswitch (GetCurrentMemberReference())\n\t\t\t{\n\t\t\t\tcase IType t:\n\t\t\t\t\tApplyTypeColor(t, ref color);\n\t\t\t\t\tbreak;\n\t\t\t\tcase IMethod m:\n\t\t\t\t\tcolor = methodCallColor;\n\t\t\t\t\tif (m.IsConstructor)\n\t\t\t\t\t\tApplyTypeColor(m.DeclaringType, ref color);\n\t\t\t\t\tbreak;\n\t\t\t\tcase IField:\n\t\t\t\t\tcolor = fieldAccessColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase IProperty:\n\t\t\t\t\tcolor = propertyAccessColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase IEvent:\n\t\t\t\t\tcolor = eventAccessColor;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (color != null)\n\t\t\t{\n\t\t\t\tBeginSpan(color);\n\t\t\t}\n\t\t\tbase.WriteIdentifier(identifier);\n\t\t\tif (color != null)\n\t\t\t{\n\t\t\t\tEndSpan();\n\t\t\t}\n\t\t}\n\n\t\tvoid ApplyTypeColor(IType type, ref HighlightingColor color)\n\t\t{\n\t\t\tswitch (type?.Kind)\n\t\t\t{\n\t\t\t\tcase TypeKind.Delegate:\n\t\t\t\t\tcolor = delegateTypeColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeKind.Class:\n\t\t\t\t\tcolor = referenceTypeColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeKind.Interface:\n\t\t\t\t\tcolor = interfaceTypeColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeKind.Enum:\n\t\t\t\t\tcolor = enumerationTypeColor;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TypeKind.Struct:\n\t\t\t\t\tcolor = valueTypeColor;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void WritePrimitiveValue(object value, Decompiler.CSharp.Syntax.LiteralFormat format)\n\t\t{\n\t\t\tHighlightingColor color = null;\n\t\t\tif (value is null)\n\t\t\t{\n\t\t\t\tcolor = valueKeywordColor;\n\t\t\t}\n\t\t\tif (value is true || value is false)\n\t\t\t{\n\t\t\t\tcolor = trueKeywordColor;\n\t\t\t}\n\t\t\tif (color != null)\n\t\t\t{\n\t\t\t\tBeginSpan(color);\n\t\t\t}\n\t\t\tbase.WritePrimitiveValue(value, format);\n\t\t\tif (color != null)\n\t\t\t{\n\t\t\t\tEndSpan();\n\t\t\t}\n\t\t}\n\n\t\tISymbol GetCurrentDefinition()\n\t\t{\n\t\t\tif (nodeStack == null || nodeStack.Count == 0)\n\t\t\t\treturn null;\n\n\t\t\tvar node = nodeStack.Peek();\n\t\t\tif (node is Identifier)\n\t\t\t\tnode = node.Parent;\n\t\t\tif (Decompiler.TextTokenWriter.IsDefinition(ref node))\n\t\t\t\treturn node.GetSymbol();\n\n\t\t\treturn null;\n\t\t}\n\n\t\tISymbol GetCurrentMemberReference()\n\t\t{\n\t\t\tif (nodeStack == null || nodeStack.Count == 0)\n\t\t\t\treturn null;\n\n\t\t\tAstNode node = nodeStack.Peek();\n\t\t\tvar symbol = node.GetSymbol();\n\t\t\tif (symbol == null && node.Role == Roles.TargetExpression && node.Parent is InvocationExpression)\n\t\t\t{\n\t\t\t\tsymbol = node.Parent.GetSymbol();\n\t\t\t}\n\t\t\tif (symbol != null && node.Role == Roles.Type && node.Parent is ObjectCreateExpression)\n\t\t\t{\n\t\t\t\tvar ctorSymbol = node.Parent.GetSymbol();\n\t\t\t\tif (ctorSymbol != null)\n\t\t\t\t\tsymbol = ctorSymbol;\n\t\t\t}\n\t\t\tif (node is IdentifierExpression && node.Role == Roles.TargetExpression && node.Parent is InvocationExpression && symbol is IMember member)\n\t\t\t{\n\t\t\t\tvar declaringType = member.DeclaringType;\n\t\t\t\tif (declaringType != null && declaringType.Kind == TypeKind.Delegate)\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn symbol;\n\t\t}\n\n\t\treadonly Stack<AstNode> nodeStack = new Stack<AstNode>();\n\n\t\tpublic override void StartNode(AstNode node)\n\t\t{\n\t\t\tnodeStack.Push(node);\n\t\t\tbase.StartNode(node);\n\t\t}\n\n\t\tpublic override void EndNode(AstNode node)\n\t\t{\n\t\t\tbase.EndNode(node);\n\t\t\tnodeStack.Pop();\n\t\t}\n\n\t\treadonly Stack<HighlightingColor> colorStack = new Stack<HighlightingColor>();\n\t\tHighlightingColor currentColor = new HighlightingColor();\n\t\tint currentColorBegin = -1;\n\t\treadonly ILocatable locatable;\n\t\treadonly ISmartTextOutput textOutput;\n\n\t\tprivate void BeginSpan(HighlightingColor highlightingColor)\n\t\t{\n\t\t\tif (textOutput != null)\n\t\t\t{\n\t\t\t\ttextOutput.BeginSpan(highlightingColor);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (currentColorBegin > -1)\n\t\t\t\tHighlightingModel.SetHighlighting(currentColorBegin, locatable.Length - currentColorBegin, currentColor);\n\t\t\tcolorStack.Push(currentColor);\n\t\t\tcurrentColor = currentColor.Clone();\n\t\t\tcurrentColorBegin = locatable.Length;\n\t\t\tcurrentColor.MergeWith(highlightingColor);\n\t\t\tcurrentColor.Freeze();\n\t\t}\n\n\t\tprivate void EndSpan()\n\t\t{\n\t\t\tif (textOutput != null)\n\t\t\t{\n\t\t\t\ttextOutput.EndSpan();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tHighlightingModel.SetHighlighting(currentColorBegin, locatable.Length - currentColorBegin, currentColor);\n\t\t\tcurrentColor = colorStack.Pop();\n\t\t\tcurrentColorBegin = locatable.Length;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Languages/CSharpILMixedLanguage.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Windows.Media;\n\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.Extensions;\n\nnamespace ICSharpCode.ILSpy\n{\n\tusing SequencePoint = ICSharpCode.Decompiler.DebugInfo.SequencePoint;\n\n\t[Export(typeof(Language))]\n\t[Shared]\n\tclass CSharpILMixedLanguage(SettingsService settingsService, DockWorkspace dockWorkspace) : ILLanguage(dockWorkspace)\n\t{\n\t\tpublic override string Name => \"IL with C#\";\n\n\t\tprotected override ReflectionDisassembler CreateDisassembler(ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tvar displaySettings = settingsService.DisplaySettings;\n\t\t\treturn new ReflectionDisassembler(output,\n\t\t\t\tnew MixedMethodBodyDisassembler(output, options) {\n\t\t\t\t\tDetectControlStructure = detectControlStructure,\n\t\t\t\t\tShowSequencePoints = options.DecompilerSettings.ShowDebugInfo\n\t\t\t\t},\n\t\t\t\toptions.CancellationToken) {\n\t\t\t\tShowMetadataTokens = displaySettings.ShowMetadataTokens,\n\t\t\t\tShowMetadataTokensInBase10 = displaySettings.ShowMetadataTokensInBase10,\n\t\t\t\tShowRawRVAOffsetAndBytes = displaySettings.ShowRawOffsetsAndBytesBeforeInstruction,\n\t\t\t\tExpandMemberDefinitions = options.DecompilerSettings.ExpandMemberDefinitions,\n\t\t\t\tDecodeCustomAttributeBlobs = displaySettings.DecodeCustomAttributeBlobs\n\t\t\t};\n\t\t}\n\n\t\tstatic CSharpDecompiler CreateDecompiler(MetadataFile module, DecompilationOptions options)\n\t\t{\n\t\t\tCSharpDecompiler decompiler = new CSharpDecompiler(module, module.GetAssemblyResolver(), options.DecompilerSettings);\n\t\t\tdecompiler.CancellationToken = options.CancellationToken;\n\t\t\treturn decompiler;\n\t\t}\n\n\t\tstatic void WriteCode(TextWriter output, DecompilerSettings settings, SyntaxTree syntaxTree, IDecompilerTypeSystem typeSystem)\n\t\t{\n\t\t\tsyntaxTree.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true });\n\t\t\tTokenWriter tokenWriter = new TextWriterTokenWriter(output) { IndentationString = settings.CSharpFormattingOptions.IndentationString };\n\t\t\ttokenWriter = TokenWriter.WrapInWriterThatSetsLocationsInAST(tokenWriter);\n\t\t\tsyntaxTree.AcceptVisitor(new CSharpOutputVisitor(tokenWriter, settings.CSharpFormattingOptions));\n\t\t}\n\n\t\tclass MixedMethodBodyDisassembler : MethodBodyDisassembler\n\t\t{\n\t\t\treadonly DecompilationOptions options;\n\t\t\t// list sorted by IL offset\n\t\t\tIList<SequencePoint> sequencePoints;\n\t\t\t// lines of raw c# source code\n\t\t\tstring[] codeLines;\n\n\t\t\tpublic MixedMethodBodyDisassembler(ITextOutput output, DecompilationOptions options)\n\t\t\t\t: base(output, options.CancellationToken)\n\t\t\t{\n\t\t\t\tthis.options = options;\n\t\t\t}\n\n\t\t\tpublic override void Disassemble(MetadataFile module, MethodDefinitionHandle handle)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tvar csharpOutput = new StringWriter();\n\t\t\t\t\tCSharpDecompiler decompiler = CreateDecompiler(module, options);\n\t\t\t\t\tvar st = decompiler.Decompile(handle);\n\t\t\t\t\tWriteCode(csharpOutput, options.DecompilerSettings, st, decompiler.TypeSystem);\n\t\t\t\t\tvar mapping = decompiler.CreateSequencePoints(st).FirstOrDefault(kvp => (kvp.Key.MoveNextMethod ?? kvp.Key.Method)?.MetadataToken == handle);\n\t\t\t\t\tthis.sequencePoints = mapping.Value ?? (IList<SequencePoint>)EmptyList<SequencePoint>.Instance;\n\t\t\t\t\tthis.codeLines = csharpOutput.ToString().Split(new[] { Environment.NewLine }, StringSplitOptions.None);\n\t\t\t\t\tbase.Disassemble(module, handle);\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tthis.sequencePoints = null;\n\t\t\t\t\tthis.codeLines = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tprotected override void WriteInstruction(ITextOutput output, MetadataFile metadata, MethodDefinitionHandle methodHandle, ref BlobReader blob, int methodRva)\n\t\t\t{\n\t\t\t\tint index = sequencePoints.BinarySearch(blob.Offset, seq => seq.Offset);\n\t\t\t\tif (index >= 0)\n\t\t\t\t{\n\t\t\t\t\tvar info = sequencePoints[index];\n\t\t\t\t\tvar highlightingOutput = output as ISmartTextOutput;\n\t\t\t\t\tif (!info.IsHidden)\n\t\t\t\t\t{\n\t\t\t\t\t\tfor (int line = info.StartLine; line <= info.EndLine; line++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (highlightingOutput != null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstring text = codeLines[line - 1];\n\t\t\t\t\t\t\t\tint startColumn = 1;\n\t\t\t\t\t\t\t\tint endColumn = text.Length + 1;\n\t\t\t\t\t\t\t\tif (line == info.StartLine)\n\t\t\t\t\t\t\t\t\tstartColumn = info.StartColumn;\n\t\t\t\t\t\t\t\tif (line == info.EndLine)\n\t\t\t\t\t\t\t\t\tendColumn = info.EndColumn;\n\t\t\t\t\t\t\t\tWriteHighlightedCommentLine(highlightingOutput, text, startColumn - 1, endColumn - 1, info.StartLine == info.EndLine);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tWriteCommentLine(output, codeLines[line - 1]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(\"// \");\n\t\t\t\t\t\thighlightingOutput?.BeginSpan(gray);\n\t\t\t\t\t\toutput.WriteLine(\"(no C# code)\");\n\t\t\t\t\t\thighlightingOutput?.EndSpan();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbase.WriteInstruction(output, metadata, methodHandle, ref blob, methodRva);\n\t\t\t}\n\n\t\t\tHighlightingColor gray = new HighlightingColor { Foreground = new SimpleHighlightingBrush(Colors.DarkGray) };\n\n\t\t\tvoid WriteHighlightedCommentLine(ISmartTextOutput output, string text, int startColumn, int endColumn, bool isSingleLine)\n\t\t\t{\n\t\t\t\tif (startColumn > text.Length)\n\t\t\t\t{\n\t\t\t\t\tDebug.Fail(\"startColumn is invalid\");\n\t\t\t\t\tstartColumn = text.Length;\n\t\t\t\t}\n\t\t\t\tif (endColumn > text.Length)\n\t\t\t\t{\n\t\t\t\t\tDebug.Fail(\"endColumn is invalid\");\n\t\t\t\t\tendColumn = text.Length;\n\t\t\t\t}\n\t\t\t\toutput.Write(\"// \");\n\t\t\t\toutput.BeginSpan(gray);\n\t\t\t\tif (isSingleLine)\n\t\t\t\t\toutput.Write(text.Substring(0, startColumn).TrimStart());\n\t\t\t\telse\n\t\t\t\t\toutput.Write(text.Substring(0, startColumn));\n\t\t\t\toutput.EndSpan();\n\t\t\t\toutput.Write(text.Substring(startColumn, endColumn - startColumn));\n\t\t\t\toutput.BeginSpan(gray);\n\t\t\t\toutput.Write(text.Substring(endColumn));\n\t\t\t\toutput.EndSpan();\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\n\t\t\tvoid WriteCommentLine(ITextOutput output, string text)\n\t\t\t{\n\t\t\t\toutput.WriteLine(\"// \" + text);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Languages/CSharpLanguage.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.PortableExecutable;\nusing System.Windows;\nusing System.Windows.Controls;\n\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\nusing ICSharpCode.Decompiler.CSharp.ProjectDecompiler;\nusing ICSharpCode.Decompiler.CSharp.Syntax;\nusing ICSharpCode.Decompiler.CSharp.Transforms;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Output;\nusing ICSharpCode.Decompiler.Solution;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpyX;\n\nusing LanguageVersion = ICSharpCode.ILSpyX.LanguageVersion;\n\nnamespace ICSharpCode.ILSpy\n{\n\t/// <summary>\n\t/// C# decompiler integration into ILSpy.\n\t/// Note: if you're interested in using the decompiler without the ILSpy UI,\n\t/// please directly use the CSharpDecompiler class.\n\t/// </summary>\n\t[Export(typeof(Language))]\n\t[Shared]\n\tpublic class CSharpLanguage : Language\n\t{\n\t\tstring name = \"C#\";\n\t\tbool showAllMembers = false;\n\t\tint transformCount = int.MaxValue;\n\n#if DEBUG\n\t\tinternal static IEnumerable<CSharpLanguage> GetDebugLanguages()\n\t\t{\n\t\t\tstring lastTransformName = \"no transforms\";\n\t\t\tint transformCount = 0;\n\t\t\tforeach (var transform in CSharpDecompiler.GetAstTransforms())\n\t\t\t{\n\t\t\t\tyield return new() {\n\t\t\t\t\ttransformCount = transformCount,\n\t\t\t\t\tname = \"C# - \" + lastTransformName,\n\t\t\t\t\tshowAllMembers = true\n\t\t\t\t};\n\t\t\t\tlastTransformName = \"after \" + transform.GetType().Name;\n\t\t\t\ttransformCount++;\n\t\t\t}\n\t\t\tyield return new() {\n\t\t\t\tname = \"C# - \" + lastTransformName,\n\t\t\t\tshowAllMembers = true\n\t\t\t};\n\t\t}\n#endif\n\n\t\tpublic override string Name {\n\t\t\tget { return name; }\n\t\t}\n\n\t\tpublic override string FileExtension {\n\t\t\tget { return \".cs\"; }\n\t\t}\n\n\t\tpublic override string ProjectFileExtension {\n\t\t\tget { return \".csproj\"; }\n\t\t}\n\n\t\tIReadOnlyList<LanguageVersion> versions;\n\n\t\tpublic override IReadOnlyList<LanguageVersion> LanguageVersions {\n\t\t\tget {\n\t\t\t\tif (versions == null)\n\t\t\t\t{\n\t\t\t\t\tversions = new List<LanguageVersion>() {\n\t\t\t\t\t\tnew LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp1.ToString(), \"C# 1.0 / VS .NET\"),\n\t\t\t\t\t\tnew LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp2.ToString(), \"C# 2.0 / VS 2005\"),\n\t\t\t\t\t\tnew LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp3.ToString(), \"C# 3.0 / VS 2008\"),\n\t\t\t\t\t\tnew LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp4.ToString(), \"C# 4.0 / VS 2010\"),\n\t\t\t\t\t\tnew LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp5.ToString(), \"C# 5.0 / VS 2012\"),\n\t\t\t\t\t\tnew LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp6.ToString(), \"C# 6.0 / VS 2015\"),\n\t\t\t\t\t\tnew LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp7.ToString(), \"C# 7.0 / VS 2017\"),\n\t\t\t\t\t\tnew LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp7_1.ToString(), \"C# 7.1 / VS 2017.3\"),\n\t\t\t\t\t\tnew LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp7_2.ToString(), \"C# 7.2 / VS 2017.4\"),\n\t\t\t\t\t\tnew LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp7_3.ToString(), \"C# 7.3 / VS 2017.7\"),\n\t\t\t\t\t\tnew LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp8_0.ToString(), \"C# 8.0 / VS 2019\"),\n\t\t\t\t\t\tnew LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp9_0.ToString(), \"C# 9.0 / VS 2019.8\"),\n\t\t\t\t\t\tnew LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp10_0.ToString(), \"C# 10.0 / VS 2022\"),\n\t\t\t\t\t\tnew LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp11_0.ToString(), \"C# 11.0 / VS 2022.4\"),\n\t\t\t\t\t\tnew LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp12_0.ToString(), \"C# 12.0 / VS 2022.8\"),\n\t\t\t\t\t\tnew LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp13_0.ToString(), \"C# 13.0 / VS 2022.12\"),\n\t\t\t\t\t\tnew LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp14_0.ToString(), \"C# 14.0 / VS 2026\"),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn versions;\n\t\t\t}\n\t\t}\n\n\t\tCSharpDecompiler CreateDecompiler(MetadataFile module, DecompilationOptions options)\n\t\t{\n\t\t\tCSharpDecompiler decompiler = new CSharpDecompiler(module, module.GetAssemblyResolver(options.DecompilerSettings.AutoLoadAssemblyReferences), options.DecompilerSettings);\n\t\t\tdecompiler.CancellationToken = options.CancellationToken;\n\t\t\tdecompiler.DebugInfoProvider = module.GetDebugInfoOrNull();\n\t\t\twhile (decompiler.AstTransforms.Count > transformCount)\n\t\t\t\tdecompiler.AstTransforms.RemoveAt(decompiler.AstTransforms.Count - 1);\n\t\t\tif (options.EscapeInvalidIdentifiers)\n\t\t\t{\n\t\t\t\tdecompiler.AstTransforms.Add(new EscapeInvalidIdentifiers());\n\t\t\t}\n\t\t\treturn decompiler;\n\t\t}\n\n\t\tvoid WriteCode(ITextOutput output, DecompilerSettings settings, SyntaxTree syntaxTree, IDecompilerTypeSystem typeSystem)\n\t\t{\n\t\t\tsyntaxTree.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true });\n\t\t\toutput.IndentationString = settings.CSharpFormattingOptions.IndentationString;\n\t\t\tTokenWriter tokenWriter = new TextTokenWriter(output, settings, typeSystem);\n\t\t\tif (output is ISmartTextOutput highlightingOutput)\n\t\t\t{\n\t\t\t\ttokenWriter = new CSharpHighlightingTokenWriter(tokenWriter, highlightingOutput);\n\t\t\t}\n\t\t\tsyntaxTree.AcceptVisitor(new CSharpOutputVisitor(tokenWriter, settings.CSharpFormattingOptions));\n\t\t}\n\n\t\tpublic override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tMetadataFile assembly = method.ParentModule.MetadataFile;\n\t\t\tCSharpDecompiler decompiler = CreateDecompiler(assembly, options);\n\t\t\tAddReferenceAssemblyWarningMessage(assembly, output);\n\t\t\tAddReferenceWarningMessage(assembly, output);\n\t\t\tWriteCommentLine(output, assembly.FullName);\n\t\t\tWriteCommentLine(output, TypeToString(method.DeclaringType));\n\t\t\tvar methodDefinition = decompiler.TypeSystem.MainModule.ResolveEntity(method.MetadataToken) as IMethod;\n\t\t\tif (methodDefinition.IsConstructor && methodDefinition.DeclaringType.IsReferenceType != false)\n\t\t\t{\n\t\t\t\tvar members = CollectFieldsAndCtors(methodDefinition.DeclaringTypeDefinition, methodDefinition.IsStatic);\n\t\t\t\tdecompiler.AstTransforms.Add(new SelectCtorTransform(methodDefinition));\n\t\t\t\tWriteCode(output, options.DecompilerSettings, decompiler.Decompile(members), decompiler.TypeSystem);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tWriteCode(output, options.DecompilerSettings, decompiler.Decompile(method.MetadataToken), decompiler.TypeSystem);\n\t\t\t}\n\t\t}\n\n\t\tclass SelectCtorTransform : IAstTransform\n\t\t{\n\t\t\treadonly IMethod ctor;\n\t\t\treadonly HashSet<ISymbol> removedSymbols = new HashSet<ISymbol>();\n\n\t\t\tpublic SelectCtorTransform(IMethod ctor)\n\t\t\t{\n\t\t\t\tthis.ctor = ctor;\n\t\t\t}\n\n\t\t\tpublic void Run(AstNode rootNode, TransformContext context)\n\t\t\t{\n\t\t\t\tConstructorDeclaration ctorDecl = null;\n\t\t\t\tforeach (var node in rootNode.Children)\n\t\t\t\t{\n\t\t\t\t\tswitch (node)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase ConstructorDeclaration ctor:\n\t\t\t\t\t\t\tif (ctor.GetSymbol() == this.ctor)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tctorDecl = ctor;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// remove other ctors\n\t\t\t\t\t\t\t\tctor.Remove();\n\t\t\t\t\t\t\t\tremovedSymbols.Add(ctor.GetSymbol());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase FieldDeclaration fd:\n\t\t\t\t\t\t\t// Remove any fields without initializers\n\t\t\t\t\t\t\tif (fd.Variables.All(v => v.Initializer.IsNull))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfd.Remove();\n\t\t\t\t\t\t\t\tremovedSymbols.Add(fd.GetSymbol());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase EventDeclaration ed:\n\t\t\t\t\t\t\t// Remove any events without initializers\n\t\t\t\t\t\t\tif (ed.Variables.All(v => v.Initializer.IsNull))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ted.Remove();\n\t\t\t\t\t\t\t\tremovedSymbols.Add(ed.GetSymbol());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase PropertyDeclaration pd:\n\t\t\t\t\t\t\t// Remove any properties without initializers\n\t\t\t\t\t\t\tif (pd.Initializer.IsNull)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tpd.Remove();\n\t\t\t\t\t\t\t\tremovedSymbols.Add(pd.GetSymbol());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase CustomEventDeclaration ced:\n\t\t\t\t\t\tcase IndexerDeclaration id:\n\t\t\t\t\t\t\tnode.Remove();\n\t\t\t\t\t\t\tremovedSymbols.Add(node.GetSymbol());\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (ctorDecl?.Initializer.ConstructorInitializerType == ConstructorInitializerType.This)\n\t\t\t\t{\n\t\t\t\t\t// remove all non-constructor declarations\n\t\t\t\t\tforeach (var node in rootNode.Children)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (node is not ConstructorDeclaration)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnode.Remove();\n\t\t\t\t\t\t\tremovedSymbols.Add(node.GetSymbol());\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tforeach (var node in rootNode.Children)\n\t\t\t\t{\n\t\t\t\t\tif (node is Comment && removedSymbols.Contains(node.GetSymbol()))\n\t\t\t\t\t\tnode.Remove();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic override void DecompileProperty(IProperty property, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tMetadataFile assembly = property.ParentModule.MetadataFile;\n\t\t\tCSharpDecompiler decompiler = CreateDecompiler(assembly, options);\n\t\t\tAddReferenceAssemblyWarningMessage(assembly, output);\n\t\t\tAddReferenceWarningMessage(assembly, output);\n\t\t\tWriteCommentLine(output, assembly.FullName);\n\t\t\tWriteCommentLine(output, TypeToString(property.DeclaringType));\n\t\t\tWriteCode(output, options.DecompilerSettings, decompiler.Decompile(property.MetadataToken), decompiler.TypeSystem);\n\t\t}\n\n\t\tpublic override void DecompileField(IField field, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tMetadataFile assembly = field.ParentModule.MetadataFile;\n\t\t\tCSharpDecompiler decompiler = CreateDecompiler(assembly, options);\n\t\t\tAddReferenceAssemblyWarningMessage(assembly, output);\n\t\t\tAddReferenceWarningMessage(assembly, output);\n\t\t\tWriteCommentLine(output, assembly.FullName);\n\t\t\tWriteCommentLine(output, TypeToString(field.DeclaringType));\n\t\t\tif (field.IsConst)\n\t\t\t{\n\t\t\t\tWriteCode(output, options.DecompilerSettings, decompiler.Decompile(field.MetadataToken), decompiler.TypeSystem);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar members = CollectFieldsAndCtors(field.DeclaringTypeDefinition, field.IsStatic);\n\t\t\t\tvar resolvedField = decompiler.TypeSystem.MainModule.GetDefinition((FieldDefinitionHandle)field.MetadataToken);\n\t\t\t\tdecompiler.AstTransforms.Add(new SelectFieldTransform(resolvedField));\n\t\t\t\tWriteCode(output, options.DecompilerSettings, decompiler.Decompile(members), decompiler.TypeSystem);\n\t\t\t}\n\t\t}\n\n\t\tstatic List<EntityHandle> CollectFieldsAndCtors(ITypeDefinition type, bool isStatic)\n\t\t{\n\t\t\tvar members = new List<EntityHandle>();\n\t\t\tforeach (var field in type.Fields)\n\t\t\t{\n\t\t\t\tif (!field.MetadataToken.IsNil && field.IsStatic == isStatic)\n\t\t\t\t\tmembers.Add(field.MetadataToken);\n\t\t\t}\n\t\t\tforeach (var e in type.Events)\n\t\t\t{\n\t\t\t\tif (!e.MetadataToken.IsNil && e.IsStatic == isStatic)\n\t\t\t\t\tmembers.Add(e.MetadataToken);\n\t\t\t}\n\t\t\tforeach (var p in type.Properties)\n\t\t\t{\n\t\t\t\tif (!p.MetadataToken.IsNil && p.IsStatic == isStatic && !p.IsIndexer)\n\t\t\t\t\tmembers.Add(p.MetadataToken);\n\t\t\t}\n\t\t\tforeach (var ctor in type.Methods)\n\t\t\t{\n\t\t\t\tif (!ctor.MetadataToken.IsNil && ctor.IsConstructor && ctor.IsStatic == isStatic)\n\t\t\t\t\tmembers.Add(ctor.MetadataToken);\n\t\t\t}\n\n\t\t\treturn members;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Removes all top-level members except for the specified fields.\n\t\t/// </summary>\n\t\tsealed class SelectFieldTransform : IAstTransform\n\t\t{\n\t\t\treadonly IField field;\n\n\t\t\tpublic SelectFieldTransform(IField field)\n\t\t\t{\n\t\t\t\tthis.field = field;\n\t\t\t}\n\n\t\t\tpublic void Run(AstNode rootNode, TransformContext context)\n\t\t\t{\n\t\t\t\tforeach (var node in rootNode.Children)\n\t\t\t\t{\n\t\t\t\t\tswitch (node)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase EntityDeclaration ed:\n\t\t\t\t\t\t\tif (node.GetSymbol() != field)\n\t\t\t\t\t\t\t\tnode.Remove();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase Comment c:\n\t\t\t\t\t\t\tif (c.GetSymbol() != field)\n\t\t\t\t\t\t\t\tnode.Remove();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic override void DecompileEvent(IEvent @event, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tMetadataFile assembly = @event.ParentModule.MetadataFile;\n\t\t\tCSharpDecompiler decompiler = CreateDecompiler(assembly, options);\n\t\t\tAddReferenceAssemblyWarningMessage(assembly, output);\n\t\t\tAddReferenceWarningMessage(assembly, output);\n\t\t\tWriteCommentLine(output, assembly.FullName);\n\t\t\tWriteCommentLine(output, TypeToString(@event.DeclaringType));\n\t\t\tWriteCode(output, options.DecompilerSettings, decompiler.Decompile(@event.MetadataToken), decompiler.TypeSystem);\n\t\t}\n\n\t\tpublic override void DecompileType(ITypeDefinition type, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tMetadataFile assembly = type.ParentModule.MetadataFile;\n\t\t\tCSharpDecompiler decompiler = CreateDecompiler(assembly, options);\n\t\t\tAddReferenceAssemblyWarningMessage(assembly, output);\n\t\t\tAddReferenceWarningMessage(assembly, output);\n\t\t\tWriteCommentLine(output, assembly.FullName);\n\t\t\tWriteCommentLine(output, TypeToString(type, ConversionFlags.UseFullyQualifiedTypeNames | ConversionFlags.UseFullyQualifiedEntityNames));\n\t\t\tWriteCode(output, options.DecompilerSettings, decompiler.Decompile(type.MetadataToken), decompiler.TypeSystem);\n\t\t}\n\n\t\tvoid AddReferenceWarningMessage(MetadataFile module, ITextOutput output)\n\t\t{\n\t\t\tvar loadedAssembly = AssemblyTreeModel.AssemblyList.GetAssemblies().FirstOrDefault(la => la.GetMetadataFileOrNull() == module);\n\t\t\tif (loadedAssembly == null || !loadedAssembly.LoadedAssemblyReferencesInfo.HasErrors)\n\t\t\t\treturn;\n\t\t\tstring line1 = Properties.Resources.WarningSomeAssemblyReference;\n\t\t\tstring line2 = Properties.Resources.PropertyManuallyMissingReferencesListLoadedAssemblies;\n\t\t\tAddWarningMessage(module, output, line1, line2, Properties.Resources.ShowAssemblyLoad, Images.ViewCode, delegate {\n\t\t\t\tILSpyTreeNode assemblyNode = AssemblyTreeModel.FindTreeNode(module);\n\t\t\t\tassemblyNode.EnsureLazyChildren();\n\t\t\t\tAssemblyTreeModel.SelectNode(assemblyNode.Children.OfType<ReferenceFolderTreeNode>().Single());\n\t\t\t});\n\t\t}\n\n\t\tvoid AddReferenceAssemblyWarningMessage(MetadataFile module, ITextOutput output)\n\t\t{\n\t\t\tvar metadata = module.Metadata;\n\t\t\tif (!metadata.GetCustomAttributes(Handle.AssemblyDefinition).HasKnownAttribute(metadata, KnownAttribute.ReferenceAssembly))\n\t\t\t\treturn;\n\t\t\tstring line1 = Properties.Resources.WarningAsmMarkedRef;\n\t\t\tAddWarningMessage(module, output, line1);\n\t\t}\n\n\t\tvoid AddWarningMessage(MetadataFile module, ITextOutput output, string line1, string line2 = null,\n\t\t\tstring buttonText = null, System.Windows.Media.ImageSource buttonImage = null, RoutedEventHandler buttonClickHandler = null)\n\t\t{\n\t\t\tif (output is ISmartTextOutput fancyOutput)\n\t\t\t{\n\t\t\t\tstring text = line1;\n\t\t\t\tif (!string.IsNullOrEmpty(line2))\n\t\t\t\t\ttext += Environment.NewLine + line2;\n\t\t\t\tfancyOutput.AddUIElement(() => new StackPanel {\n\t\t\t\t\tMargin = new Thickness(5),\n\t\t\t\t\tOrientation = Orientation.Horizontal,\n\t\t\t\t\tChildren = {\n\t\t\t\t\t\tnew Image {\n\t\t\t\t\t\t\tWidth = 32,\n\t\t\t\t\t\t\tHeight = 32,\n\t\t\t\t\t\t\tSource = Images.Load(this, \"Images/Warning\")\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnew TextBlock {\n\t\t\t\t\t\t\tMargin = new Thickness(5, 0, 0, 0),\n\t\t\t\t\t\t\tText = text\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tfancyOutput.WriteLine();\n\t\t\t\tif (buttonText != null && buttonClickHandler != null)\n\t\t\t\t{\n\t\t\t\t\tfancyOutput.AddButton(buttonImage, buttonText, buttonClickHandler);\n\t\t\t\t\tfancyOutput.WriteLine();\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tWriteCommentLine(output, line1);\n\t\t\t\tif (!string.IsNullOrEmpty(line2))\n\t\t\t\t\tWriteCommentLine(output, line2);\n\t\t\t}\n\t\t}\n\n\t\tpublic override ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tvar module = assembly.GetMetadataFileOrNull();\n\t\t\tif (module == null)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (options.FullDecompilation && options.SaveAsProjectDirectory != null)\n\t\t\t{\n\t\t\t\tif (!WholeProjectDecompiler.CanUseSdkStyleProjectFormat(module))\n\t\t\t\t{\n\t\t\t\t\toptions.DecompilerSettings.UseSdkStyleProjectFormat = false;\n\t\t\t\t}\n\t\t\t\tvar decompiler = new ILSpyWholeProjectDecompiler(assembly, options) {\n\t\t\t\t\tProgressIndicator = options.Progress\n\t\t\t\t};\n\t\t\t\treturn decompiler.DecompileProject(module, options.SaveAsProjectDirectory, new TextOutputWriter(output), options.CancellationToken);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tAddReferenceAssemblyWarningMessage(module, output);\n\t\t\t\tAddReferenceWarningMessage(module, output);\n\t\t\t\toutput.WriteLine();\n\t\t\t\tbase.DecompileAssembly(assembly, output, options);\n\n\t\t\t\t// don't automatically load additional assemblies when an assembly node is selected in the tree view\n\t\t\t\tIAssemblyResolver assemblyResolver = assembly.GetAssemblyResolver(loadOnDemand: options.FullDecompilation && options.DecompilerSettings.AutoLoadAssemblyReferences);\n\t\t\t\tvar typeSystem = new DecompilerTypeSystem(module, assemblyResolver, options.DecompilerSettings);\n\t\t\t\tvar globalType = typeSystem.MainModule.TypeDefinitions.FirstOrDefault();\n\t\t\t\tif (globalType != null)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\"// Global type: \");\n\t\t\t\t\toutput.WriteReference(globalType, ILAmbience.EscapeName(globalType.FullName));\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t}\n\t\t\t\tvar metadata = module.Metadata;\n\t\t\t\tvar corHeader = module.CorHeader;\n\t\t\t\tif (module is PEFile peFile && corHeader != null)\n\t\t\t\t{\n\t\t\t\t\tvar entrypointHandle = MetadataTokenHelpers.EntityHandleOrNil(corHeader.EntryPointTokenOrRelativeVirtualAddress);\n\t\t\t\t\tif (!entrypointHandle.IsNil && entrypointHandle.Kind == HandleKind.MethodDefinition)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar entrypoint = typeSystem.MainModule.ResolveMethod(entrypointHandle, new Decompiler.TypeSystem.GenericContext());\n\t\t\t\t\t\tif (entrypoint != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toutput.Write(\"// Entry point: \");\n\t\t\t\t\t\t\toutput.WriteReference(entrypoint, ILAmbience.EscapeName(entrypoint.DeclaringType.FullName + \".\" + entrypoint.Name));\n\t\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\toutput.WriteLine(\"// Architecture: \" + GetPlatformDisplayName(peFile));\n\t\t\t\t\tif ((corHeader.Flags & System.Reflection.PortableExecutable.CorFlags.ILOnly) == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.WriteLine(\"// This assembly contains unmanaged code.\");\n\t\t\t\t\t}\n\t\t\t\t\tstring runtimeName = GetRuntimeDisplayName(module);\n\t\t\t\t\tif (runtimeName != null)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.WriteLine(\"// Runtime: \" + runtimeName);\n\t\t\t\t\t}\n\t\t\t\t\tif ((corHeader.Flags & System.Reflection.PortableExecutable.CorFlags.StrongNameSigned) != 0)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.WriteLine(\"// This assembly is signed with a strong name key.\");\n\t\t\t\t\t}\n\t\t\t\t\tif (peFile.Reader.ReadDebugDirectory().Any(d => d.Type == DebugDirectoryEntryType.Reproducible))\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.WriteLine(\"// This assembly was compiled using the /deterministic option.\");\n\t\t\t\t\t}\n\t\t\t\t\tif (module.Metadata.MetadataKind != MetadataKind.Ecma335)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.WriteLine(\"// This assembly was loaded with Windows Runtime projections applied.\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tstring runtimeName = GetRuntimeDisplayName(module);\n\t\t\t\t\tif (runtimeName != null)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.WriteLine(\"// Runtime: \" + runtimeName);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (metadata.IsAssembly)\n\t\t\t\t{\n\t\t\t\t\tvar asm = metadata.GetAssemblyDefinition();\n\t\t\t\t\tif (asm.HashAlgorithm != AssemblyHashAlgorithm.None)\n\t\t\t\t\t\toutput.WriteLine(\"// Hash algorithm: \" + asm.HashAlgorithm.ToString().ToUpper());\n\t\t\t\t\tif (!asm.PublicKey.IsNil)\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write(\"// Public key: \");\n\t\t\t\t\t\tvar reader = metadata.GetBlobReader(asm.PublicKey);\n\t\t\t\t\t\twhile (reader.RemainingBytes > 0)\n\t\t\t\t\t\t\toutput.Write(reader.ReadByte().ToString(\"x2\"));\n\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvar debugInfo = assembly.GetDebugInfoOrNull();\n\t\t\t\tif (debugInfo != null)\n\t\t\t\t{\n\t\t\t\t\toutput.WriteLine(\"// Debug info: \" + debugInfo.Description);\n\t\t\t\t}\n\t\t\t\toutput.WriteLine();\n\n\t\t\t\tCSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, options.DecompilerSettings);\n\t\t\t\tdecompiler.CancellationToken = options.CancellationToken;\n\t\t\t\tif (options.EscapeInvalidIdentifiers)\n\t\t\t\t{\n\t\t\t\t\tdecompiler.AstTransforms.Add(new EscapeInvalidIdentifiers());\n\t\t\t\t}\n\t\t\t\tSyntaxTree st;\n\t\t\t\tif (options.FullDecompilation)\n\t\t\t\t{\n\t\t\t\t\tst = decompiler.DecompileWholeModuleAsSingleFile();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tst = decompiler.DecompileModuleAndAssemblyAttributes();\n\t\t\t\t}\n\t\t\t\tWriteCode(output, options.DecompilerSettings, st, decompiler.TypeSystem);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tclass ILSpyWholeProjectDecompiler : WholeProjectDecompiler\n\t\t{\n\t\t\treadonly LoadedAssembly assembly;\n\t\t\treadonly DecompilationOptions options;\n\n\t\t\tpublic ILSpyWholeProjectDecompiler(LoadedAssembly assembly, DecompilationOptions options)\n\t\t\t\t: base(options.DecompilerSettings, assembly.GetAssemblyResolver(options.DecompilerSettings.AutoLoadAssemblyReferences, options.DecompilerSettings.ApplyWindowsRuntimeProjections), null, assembly.GetAssemblyReferenceClassifier(options.DecompilerSettings.ApplyWindowsRuntimeProjections), assembly.GetDebugInfoOrNull())\n\t\t\t{\n\t\t\t\tthis.assembly = assembly;\n\t\t\t\tthis.options = options;\n\t\t\t}\n\n\t\t\tprotected override IEnumerable<ProjectItemInfo> WriteResourceToFile(string fileName, string resourceName, Stream entryStream)\n\t\t\t{\n\t\t\t\tvar context = new ResourceFileHandlerContext(options);\n\t\t\t\tforeach (var handler in ResourceFileHandlers)\n\t\t\t\t{\n\t\t\t\t\tif (handler.CanHandle(fileName, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tentryStream.Position = 0;\n\t\t\t\t\t\tfileName = handler.WriteResourceToFile(assembly, fileName, entryStream, context);\n\n\t\t\t\t\t\treturn new[] { new ProjectItemInfo(handler.EntryType, fileName) { PartialTypes = context.PartialTypes }.With(context.AdditionalProperties) };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn base.WriteResourceToFile(fileName, resourceName, entryStream);\n\t\t\t}\n\t\t}\n\n\t\tCSharpAmbience CreateAmbience()\n\t\t{\n\t\t\tCSharpAmbience ambience = new CSharpAmbience();\n\t\t\t// Do not forget to update CSharpAmbienceTests.ILSpyMainTreeViewTypeFlags, if this ever changes.\n\t\t\tambience.ConversionFlags = ConversionFlags.ShowTypeParameterList | ConversionFlags.PlaceReturnTypeAfterParameterList;\n\t\t\tvar decompilerSettings = SettingsService.DecompilerSettings.Clone();\n\t\t\tif (!Enum.TryParse(AssemblyTreeModel.CurrentLanguageVersion?.Version, out Decompiler.CSharp.LanguageVersion languageVersion))\n\t\t\t\tlanguageVersion = Decompiler.CSharp.LanguageVersion.Latest;\n\t\t\tdecompilerSettings.SetLanguageVersion(languageVersion);\n\t\t\tif (decompilerSettings.LiftNullables)\n\t\t\t{\n\t\t\t\tambience.ConversionFlags |= ConversionFlags.UseNullableSpecifierForValueTypes;\n\t\t\t}\n\t\t\tif (decompilerSettings.IntroducePrivateProtectedAccessibility)\n\t\t\t{\n\t\t\t\tambience.ConversionFlags |= ConversionFlags.UsePrivateProtectedAccessibility;\n\t\t\t}\n\t\t\treturn ambience;\n\t\t}\n\n\t\tpublic override string EntityToString(IEntity entity, ConversionFlags conversionFlags)\n\t\t{\n\t\t\t// Do not forget to update CSharpAmbienceTests, if this ever changes.\n\t\t\tvar ambience = CreateAmbience();\n\t\t\tambience.ConversionFlags |= conversionFlags\n\t\t\t\t| ConversionFlags.ShowReturnType\n\t\t\t\t| ConversionFlags.ShowParameterList\n\t\t\t\t| ConversionFlags.ShowParameterModifiers;\n\t\t\treturn ambience.ConvertSymbol(entity);\n\t\t}\n\n\t\tpublic override string TypeToString(IType type, ConversionFlags conversionFlags = ConversionFlags.UseFullyQualifiedEntityNames | ConversionFlags.UseFullyQualifiedTypeNames)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(type));\n\t\t\tvar ambience = CreateAmbience();\n\t\t\t// Do not forget to update CSharpAmbienceTests.ILSpyMainTreeViewFlags, if this ever changes.\n\t\t\tambience.ConversionFlags |= conversionFlags;\n\t\t\tif (type is ITypeDefinition definition)\n\t\t\t{\n\t\t\t\treturn ambience.ConvertSymbol(definition);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn ambience.ConvertType(type);\n\t\t\t}\n\t\t}\n\n\t\tstatic string ToCSharpString(MetadataReader metadata, TypeDefinitionHandle handle, bool fullName, bool omitGenerics)\n\t\t{\n\t\t\tvar currentTypeDefHandle = handle;\n\t\t\tvar typeDef = metadata.GetTypeDefinition(currentTypeDefHandle);\n\t\t\tList<string> builder = new List<string>();\n\n\t\t\twhile (!currentTypeDefHandle.IsNil)\n\t\t\t{\n\t\t\t\tif (builder.Count > 0)\n\t\t\t\t\tbuilder.Add(\".\");\n\t\t\t\ttypeDef = metadata.GetTypeDefinition(currentTypeDefHandle);\n\t\t\t\tvar part = ReflectionHelper.SplitTypeParameterCountFromReflectionName(metadata.GetString(typeDef.Name), out int typeParamCount);\n\t\t\t\tvar genericParams = typeDef.GetGenericParameters();\n\t\t\t\tif (!omitGenerics && genericParams.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tbuilder.Add(\">\");\n\t\t\t\t\tint firstIndex = genericParams.Count - typeParamCount;\n\t\t\t\t\tfor (int i = genericParams.Count - 1; i >= genericParams.Count - typeParamCount; i--)\n\t\t\t\t\t{\n\t\t\t\t\t\tbuilder.Add(metadata.GetString(metadata.GetGenericParameter(genericParams[i]).Name));\n\t\t\t\t\t\tbuilder.Add(i == firstIndex ? \"<\" : \",\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbuilder.Add(part);\n\t\t\t\tcurrentTypeDefHandle = typeDef.GetDeclaringType();\n\t\t\t\tif (!fullName)\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (fullName && !typeDef.Namespace.IsNil)\n\t\t\t{\n\t\t\t\tbuilder.Add(\".\");\n\t\t\t\tbuilder.Add(metadata.GetString(typeDef.Namespace));\n\t\t\t}\n\n\t\t\tswitch (builder.Count)\n\t\t\t{\n\t\t\t\tcase 0:\n\t\t\t\t\treturn string.Empty;\n\t\t\t\tcase 1:\n\t\t\t\t\treturn builder[0];\n\t\t\t\tcase 2:\n\t\t\t\t\treturn builder[1] + builder[0];\n\t\t\t\tcase 3:\n\t\t\t\t\treturn builder[2] + builder[1] + builder[0];\n\t\t\t\tcase 4:\n\t\t\t\t\treturn builder[3] + builder[2] + builder[1] + builder[0];\n\t\t\t\tdefault:\n\t\t\t\t\tbuilder.Reverse();\n\t\t\t\t\treturn string.Concat(builder);\n\t\t\t}\n\t\t}\n\n\t\tpublic override string GetEntityName(MetadataFile module, EntityHandle handle, bool fullName, bool omitGenerics)\n\t\t{\n\t\t\tMetadataReader metadata = module.Metadata;\n\t\t\tswitch (handle.Kind)\n\t\t\t{\n\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\t\treturn ToCSharpString(metadata, (TypeDefinitionHandle)handle, fullName, omitGenerics);\n\t\t\t\tcase HandleKind.FieldDefinition:\n\t\t\t\t\tvar fd = metadata.GetFieldDefinition((FieldDefinitionHandle)handle);\n\t\t\t\t\tvar declaringType = fd.GetDeclaringType();\n\t\t\t\t\tif (fullName)\n\t\t\t\t\t\treturn ToCSharpString(metadata, declaringType, fullName, omitGenerics) + \".\" + metadata.GetString(fd.Name);\n\t\t\t\t\treturn metadata.GetString(fd.Name);\n\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\tvar md = metadata.GetMethodDefinition((MethodDefinitionHandle)handle);\n\t\t\t\t\tdeclaringType = md.GetDeclaringType();\n\t\t\t\t\tstring methodName = metadata.GetString(md.Name);\n\t\t\t\t\tswitch (methodName)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase \".ctor\":\n\t\t\t\t\t\tcase \".cctor\":\n\t\t\t\t\t\t\tvar td = metadata.GetTypeDefinition(declaringType);\n\t\t\t\t\t\t\tmethodName = ReflectionHelper.SplitTypeParameterCountFromReflectionName(metadata.GetString(td.Name));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"Finalize\":\n\t\t\t\t\t\t\tconst MethodAttributes finalizerAttributes = (MethodAttributes.Virtual | MethodAttributes.Family | MethodAttributes.HideBySig);\n\t\t\t\t\t\t\tif ((md.Attributes & finalizerAttributes) != finalizerAttributes)\n\t\t\t\t\t\t\t\tgoto default;\n\t\t\t\t\t\t\tMethodSignature<IType> methodSignature = md.DecodeSignature(MetadataExtensions.MinimalSignatureTypeProvider, default);\n\t\t\t\t\t\t\tif (methodSignature.GenericParameterCount != 0 || methodSignature.ParameterTypes.Length != 0)\n\t\t\t\t\t\t\t\tgoto default;\n\t\t\t\t\t\t\ttd = metadata.GetTypeDefinition(declaringType);\n\t\t\t\t\t\t\tmethodName = \"~\" + ReflectionHelper.SplitTypeParameterCountFromReflectionName(metadata.GetString(td.Name));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tvar genericParams = md.GetGenericParameters();\n\t\t\t\t\t\t\tif (!omitGenerics && genericParams.Count > 0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tmethodName += \"<\";\n\t\t\t\t\t\t\t\tint i = 0;\n\t\t\t\t\t\t\t\tforeach (var h in genericParams)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\t\t\t\t\tmethodName += \",\";\n\t\t\t\t\t\t\t\t\tvar gp = metadata.GetGenericParameter(h);\n\t\t\t\t\t\t\t\t\tmethodName += metadata.GetString(gp.Name);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tmethodName += \">\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (fullName)\n\t\t\t\t\t\treturn ToCSharpString(metadata, declaringType, fullName, omitGenerics) + \".\" + methodName;\n\t\t\t\t\treturn methodName;\n\t\t\t\tcase HandleKind.EventDefinition:\n\t\t\t\t\tvar ed = metadata.GetEventDefinition((EventDefinitionHandle)handle);\n\t\t\t\t\tdeclaringType = metadata.GetMethodDefinition(ed.GetAccessors().GetAny()).GetDeclaringType();\n\t\t\t\t\tif (fullName && !declaringType.IsNil)\n\t\t\t\t\t\treturn ToCSharpString(metadata, declaringType, fullName, omitGenerics) + \".\" + metadata.GetString(ed.Name);\n\t\t\t\t\treturn metadata.GetString(ed.Name);\n\t\t\t\tcase HandleKind.PropertyDefinition:\n\t\t\t\t\tvar pd = metadata.GetPropertyDefinition((PropertyDefinitionHandle)handle);\n\t\t\t\t\tdeclaringType = metadata.GetMethodDefinition(pd.GetAccessors().GetAny()).GetDeclaringType();\n\t\t\t\t\tif (fullName && !declaringType.IsNil)\n\t\t\t\t\t\treturn ToCSharpString(metadata, declaringType, fullName, omitGenerics) + \".\" + metadata.GetString(pd.Name);\n\t\t\t\t\treturn metadata.GetString(pd.Name);\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool ShowMember(IEntity member)\n\t\t{\n\t\t\tMetadataFile assembly = member.ParentModule.MetadataFile;\n\t\t\tvar decompilerSettings = SettingsService.DecompilerSettings.Clone();\n\t\t\tif (!Enum.TryParse(AssemblyTreeModel.CurrentLanguageVersion?.Version, out Decompiler.CSharp.LanguageVersion languageVersion))\n\t\t\t\tlanguageVersion = Decompiler.CSharp.LanguageVersion.Latest;\n\t\t\tdecompilerSettings.SetLanguageVersion(languageVersion);\n\t\t\treturn showAllMembers || !CSharpDecompiler.MemberIsHidden(assembly, member.MetadataToken, decompilerSettings);\n\t\t}\n\n\t\tpublic override RichText GetRichTextTooltip(IEntity entity)\n\t\t{\n\t\t\tvar flags = ConversionFlags.All & ~(ConversionFlags.ShowBody | ConversionFlags.PlaceReturnTypeAfterParameterList);\n\t\t\tvar output = new StringWriter();\n\t\t\tvar decoratedWriter = new TextWriterTokenWriter(output);\n\t\t\tvar writer = new CSharpHighlightingTokenWriter(TokenWriter.InsertRequiredSpaces(decoratedWriter), locatable: decoratedWriter);\n\t\t\tvar settings = SettingsService.DecompilerSettings.Clone();\n\t\t\tif (!Enum.TryParse(AssemblyTreeModel.CurrentLanguageVersion?.Version, out Decompiler.CSharp.LanguageVersion languageVersion))\n\t\t\t\tlanguageVersion = Decompiler.CSharp.LanguageVersion.Latest;\n\t\t\tsettings.SetLanguageVersion(languageVersion);\n\t\t\tif (!settings.LiftNullables)\n\t\t\t{\n\t\t\t\tflags &= ~ConversionFlags.UseNullableSpecifierForValueTypes;\n\t\t\t}\n\t\t\tif (settings.RecordClasses)\n\t\t\t{\n\t\t\t\tflags |= ConversionFlags.SupportRecordClasses;\n\t\t\t}\n\t\t\tif (settings.RecordStructs)\n\t\t\t{\n\t\t\t\tflags |= ConversionFlags.SupportRecordStructs;\n\t\t\t}\n\t\t\tif (settings.UnsignedRightShift)\n\t\t\t{\n\t\t\t\tflags |= ConversionFlags.SupportUnsignedRightShift;\n\t\t\t}\n\t\t\tif (settings.CheckedOperators)\n\t\t\t{\n\t\t\t\tflags |= ConversionFlags.SupportOperatorChecked;\n\t\t\t}\n\t\t\tif (settings.InitAccessors)\n\t\t\t{\n\t\t\t\tflags |= ConversionFlags.SupportInitAccessors;\n\t\t\t}\n\t\t\tif (settings.IntroducePrivateProtectedAccessibility)\n\t\t\t{\n\t\t\t\tflags |= ConversionFlags.UsePrivateProtectedAccessibility;\n\t\t\t}\n\t\t\tif (entity is IMethod m && m.IsLocalFunction)\n\t\t\t{\n\t\t\t\twriter.WriteIdentifier(Identifier.Create(\"(local)\"));\n\t\t\t}\n\t\t\tnew CSharpAmbience() {\n\t\t\t\tConversionFlags = flags,\n\t\t\t}.ConvertSymbol(entity, writer, settings.CSharpFormattingOptions);\n\t\t\treturn new RichText(output.ToString(), writer.HighlightingModel);\n\t\t}\n\n\t\tpublic override CodeMappingInfo GetCodeMappingInfo(MetadataFile module, EntityHandle member)\n\t\t{\n\t\t\treturn CSharpDecompiler.GetCodeMappingInfo(module, member);\n\t\t}\n\n\t\tCSharpBracketSearcher bracketSearcher = new CSharpBracketSearcher();\n\n\t\tpublic override IBracketSearcher BracketSearcher => bracketSearcher;\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Languages/ILAstLanguage.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.CSharp;\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX;\n\nusing SRM = System.Reflection.Metadata;\n\nnamespace ICSharpCode.ILSpy\n{\n#if DEBUG\n\t/// <summary>\n\t/// Represents the ILAst \"language\" used for debugging purposes.\n\t/// </summary>\n\tabstract class ILAstLanguage : Language\n\t{\n\t\tpublic event EventHandler StepperUpdated;\n\n\t\treadonly string name;\n\n\t\tprotected ILAstLanguage(string name)\n\t\t{\n\t\t\tthis.name = name;\n\t\t}\n\n\t\tprotected virtual void OnStepperUpdated(EventArgs e = null)\n\t\t{\n\t\t\tStepperUpdated?.Invoke(this, e ?? new EventArgs());\n\t\t}\n\n\t\tpublic Stepper Stepper { get; set; } = new Stepper();\n\n\t\tpublic override string Name { get { return name; } }\n\n\t\tinternal static IEnumerable<ILAstLanguage> GetDebugLanguages(DockWorkspace dockWorkspace)\n\t\t{\n\t\t\tyield return new TypedIL();\n\t\t\tyield return new BlockIL(CSharpDecompiler.GetILTransforms(), dockWorkspace);\n\t\t}\n\n\t\tpublic override string FileExtension {\n\t\t\tget {\n\t\t\t\treturn \".il\";\n\t\t\t}\n\t\t}\n\n\t\tpublic override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tbase.DecompileMethod(method, output, options);\n\t\t\tnew ReflectionDisassembler(output, options.CancellationToken)\n\t\t\t\t.DisassembleMethodHeader(method.ParentModule.MetadataFile, (SRM.MethodDefinitionHandle)method.MetadataToken);\n\t\t\toutput.WriteLine();\n\t\t\toutput.WriteLine();\n\t\t}\n\n\t\tclass TypedIL() : ILAstLanguage(\"Typed IL\")\n\t\t{\n\t\t\tpublic override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)\n\t\t\t{\n\t\t\t\tbase.DecompileMethod(method, output, options);\n\t\t\t\tvar module = method.ParentModule.MetadataFile;\n\t\t\t\tvar methodDef = module.Metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)method.MetadataToken);\n\t\t\t\tif (!methodDef.HasBody())\n\t\t\t\t\treturn;\n\t\t\t\tvar typeSystem = new DecompilerTypeSystem(module, module.GetAssemblyResolver());\n\t\t\t\tILReader reader = new ILReader(typeSystem.MainModule);\n\t\t\t\tvar methodBody = module.GetMethodBody(methodDef.RelativeVirtualAddress);\n\t\t\t\treader.WriteTypedIL((SRM.MethodDefinitionHandle)method.MetadataToken, methodBody, output, cancellationToken: options.CancellationToken);\n\t\t\t}\n\t\t}\n\n\t\tclass BlockIL(IReadOnlyList<IILTransform> transforms, DockWorkspace dockWorkspace) : ILAstLanguage(\"ILAst\")\n\t\t{\n\t\t\tpublic override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)\n\t\t\t{\n\t\t\t\tbase.DecompileMethod(method, output, options);\n\t\t\t\tvar module = method.ParentModule.MetadataFile;\n\t\t\t\tvar metadata = module.Metadata;\n\t\t\t\tvar methodDef = metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)method.MetadataToken);\n\t\t\t\tif (!methodDef.HasBody())\n\t\t\t\t\treturn;\n\t\t\t\tIAssemblyResolver assemblyResolver = module.GetAssemblyResolver();\n\t\t\t\tvar typeSystem = new DecompilerTypeSystem(module, assemblyResolver);\n\t\t\t\tvar reader = new ILReader(typeSystem.MainModule);\n\t\t\t\treader.UseDebugSymbols = options.DecompilerSettings.UseDebugSymbols;\n\t\t\t\treader.UseRefLocalsForAccurateOrderOfEvaluation = options.DecompilerSettings.UseRefLocalsForAccurateOrderOfEvaluation;\n\t\t\t\tvar methodBody = module.GetMethodBody(methodDef.RelativeVirtualAddress);\n\t\t\t\tILFunction il = reader.ReadIL((SRM.MethodDefinitionHandle)method.MetadataToken, methodBody, kind: ILFunctionKind.TopLevelFunction, cancellationToken: options.CancellationToken);\n\t\t\t\tvar decompiler = new CSharpDecompiler(typeSystem, options.DecompilerSettings) { CancellationToken = options.CancellationToken };\n\t\t\t\tILTransformContext context = decompiler.CreateILTransformContext(il);\n\t\t\t\tcontext.Stepper.StepLimit = options.StepLimit;\n\t\t\t\tcontext.Stepper.IsDebug = options.IsDebug;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\til.RunTransforms(transforms, context);\n\t\t\t\t}\n\t\t\t\tcatch (StepLimitReachedException)\n\t\t\t\t{\n\t\t\t\t}\n\t\t\t\tcatch (Exception ex)\n\t\t\t\t{\n\t\t\t\t\toutput.WriteLine(ex.ToString());\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\toutput.WriteLine(\"ILAst after the crash:\");\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\t// update stepper even if a transform crashed unexpectedly\n\t\t\t\t\tif (options.StepLimit == int.MaxValue)\n\t\t\t\t\t{\n\t\t\t\t\t\tStepper = context.Stepper;\n\t\t\t\t\t\tOnStepperUpdated(new EventArgs());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t(output as ISmartTextOutput)?.AddButton(Images.ViewCode, \"Show Steps\", delegate {\n\t\t\t\t\tdockWorkspace.ShowToolPane(DebugStepsPaneModel.PaneContentId);\n\t\t\t\t});\n\t\t\t\toutput.WriteLine();\n\t\t\t\til.WriteTo(output, DebugSteps.Options);\n\t\t\t}\n\t\t}\n\t}\n#endif\n}\n"
  },
  {
    "path": "ILSpy/Languages/ILLanguage.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Solution;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX;\n\nnamespace ICSharpCode.ILSpy\n{\n\t/// <summary>\n\t/// IL language support.\n\t/// </summary>\n\t/// <remarks>\n\t/// Currently comes in two versions:\n\t/// flat IL (detectControlStructure=false) and structured IL (detectControlStructure=true).\n\t/// </remarks>\n\t[Export(typeof(Language))]\n\t[Shared]\n\tpublic class ILLanguage(DockWorkspace dockWorkspace) : Language\n\t{\n\t\tprotected bool detectControlStructure = true;\n\n\t\tpublic override string Name {\n\t\t\tget { return \"IL\"; }\n\t\t}\n\n\t\tpublic override string FileExtension {\n\t\t\tget { return \".il\"; }\n\t\t}\n\n\t\tprotected virtual ReflectionDisassembler CreateDisassembler(ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tvar displaySettings = SettingsService.DisplaySettings;\n\t\t\toutput.IndentationString = options.DecompilerSettings.CSharpFormattingOptions.IndentationString;\n\t\t\treturn new ReflectionDisassembler(output, options.CancellationToken) {\n\t\t\t\tDetectControlStructure = detectControlStructure,\n\t\t\t\tShowSequencePoints = options.DecompilerSettings.ShowDebugInfo,\n\t\t\t\tShowMetadataTokens = displaySettings.ShowMetadataTokens,\n\t\t\t\tShowMetadataTokensInBase10 = displaySettings.ShowMetadataTokensInBase10,\n\t\t\t\tShowRawRVAOffsetAndBytes = displaySettings.ShowRawOffsetsAndBytesBeforeInstruction,\n\t\t\t\tExpandMemberDefinitions = options.DecompilerSettings.ExpandMemberDefinitions,\n\t\t\t\tDecodeCustomAttributeBlobs = displaySettings.DecodeCustomAttributeBlobs\n\t\t\t};\n\t\t}\n\n\t\tpublic override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tvar dis = CreateDisassembler(output, options);\n\t\t\tMetadataFile module = method.ParentModule.MetadataFile;\n\t\t\tdis.AssemblyResolver = module.GetAssemblyResolver();\n\t\t\tdis.DebugInfo = module.GetDebugInfoOrNull();\n\t\t\tdis.DisassembleMethod(module, (MethodDefinitionHandle)method.MetadataToken);\n\t\t}\n\n\t\tpublic override void DecompileField(IField field, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tvar dis = CreateDisassembler(output, options);\n\t\t\tMetadataFile module = field.ParentModule.MetadataFile;\n\t\t\tdis.AssemblyResolver = module.GetAssemblyResolver();\n\t\t\tdis.DebugInfo = module.GetDebugInfoOrNull();\n\t\t\tdis.DisassembleField(module, (FieldDefinitionHandle)field.MetadataToken);\n\t\t}\n\n\t\tpublic override void DecompileProperty(IProperty property, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tvar dis = CreateDisassembler(output, options);\n\t\t\tMetadataFile module = property.ParentModule.MetadataFile;\n\t\t\tdis.AssemblyResolver = module.GetAssemblyResolver();\n\t\t\tdis.DebugInfo = module.GetDebugInfoOrNull();\n\t\t\tdis.DisassembleProperty(module, (PropertyDefinitionHandle)property.MetadataToken);\n\t\t\tvar pd = module.Metadata.GetPropertyDefinition((PropertyDefinitionHandle)property.MetadataToken);\n\t\t\tvar accessors = pd.GetAccessors();\n\n\t\t\tif (!accessors.Getter.IsNil)\n\t\t\t{\n\t\t\t\toutput.WriteLine();\n\t\t\t\tdis.DisassembleMethod(module, accessors.Getter);\n\t\t\t}\n\t\t\tif (!accessors.Setter.IsNil)\n\t\t\t{\n\t\t\t\toutput.WriteLine();\n\t\t\t\tdis.DisassembleMethod(module, accessors.Setter);\n\t\t\t}\n\t\t\t/*foreach (var m in property.OtherMethods) {\n\t\t\t\toutput.WriteLine();\n\t\t\t\tdis.DisassembleMethod(m);\n\t\t\t}*/\n\t\t}\n\n\t\tpublic override void DecompileEvent(IEvent ev, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tvar dis = CreateDisassembler(output, options);\n\t\t\tMetadataFile module = ev.ParentModule.MetadataFile;\n\t\t\tdis.AssemblyResolver = module.GetAssemblyResolver();\n\t\t\tdis.DebugInfo = module.GetDebugInfoOrNull();\n\t\t\tdis.DisassembleEvent(module, (EventDefinitionHandle)ev.MetadataToken);\n\n\t\t\tvar ed = ((MetadataReader)module.Metadata).GetEventDefinition((EventDefinitionHandle)ev.MetadataToken);\n\t\t\tvar accessors = ed.GetAccessors();\n\t\t\tif (!accessors.Adder.IsNil)\n\t\t\t{\n\t\t\t\toutput.WriteLine();\n\t\t\t\tdis.DisassembleMethod(module, accessors.Adder);\n\t\t\t}\n\t\t\tif (!accessors.Remover.IsNil)\n\t\t\t{\n\t\t\t\toutput.WriteLine();\n\t\t\t\tdis.DisassembleMethod(module, accessors.Remover);\n\t\t\t}\n\t\t\tif (!accessors.Raiser.IsNil)\n\t\t\t{\n\t\t\t\toutput.WriteLine();\n\t\t\t\tdis.DisassembleMethod(module, accessors.Raiser);\n\t\t\t}\n\t\t\t/*foreach (var m in ev.OtherMethods) {\n\t\t\t\toutput.WriteLine();\n\t\t\t\tdis.DisassembleMethod(m);\n\t\t\t}*/\n\t\t}\n\n\t\tpublic override void DecompileType(ITypeDefinition type, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tvar dis = CreateDisassembler(output, options);\n\t\t\tMetadataFile module = type.ParentModule.MetadataFile;\n\t\t\tdis.AssemblyResolver = module.GetAssemblyResolver();\n\t\t\tdis.DebugInfo = module.GetDebugInfoOrNull();\n\t\t\tdis.DisassembleType(module, (TypeDefinitionHandle)type.MetadataToken);\n\t\t}\n\n\t\tpublic override void DecompileNamespace(string nameSpace, IEnumerable<ITypeDefinition> types, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tvar dis = CreateDisassembler(output, options);\n\t\t\tMetadataFile module = types.FirstOrDefault()?.ParentModule.MetadataFile;\n\t\t\tdis.AssemblyResolver = module.GetAssemblyResolver();\n\t\t\tdis.DebugInfo = module.GetDebugInfoOrNull();\n\t\t\tdis.DisassembleNamespace(nameSpace, module, types.Select(t => (TypeDefinitionHandle)t.MetadataToken));\n\t\t}\n\n\t\tpublic override ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\toutput.WriteLine(\"// \" + assembly.FileName);\n\t\t\toutput.WriteLine();\n\t\t\tvar module = assembly.GetMetadataFileOrNull();\n\n\t\t\tif (options.FullDecompilation && options.SaveAsProjectDirectory != null)\n\t\t\t{\n\t\t\t\tthrow new NotSupportedException($\"Language '{Name}' does not support exporting assemblies as projects!\");\n\t\t\t}\n\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar dis = CreateDisassembler(output, options);\n\n\t\t\t// don't automatically load additional assemblies when an assembly node is selected in the tree view\n\t\t\tdis.AssemblyResolver = module.GetAssemblyResolver(loadOnDemand: options.FullDecompilation);\n\t\t\tdis.DebugInfo = module.GetDebugInfoOrNull();\n\t\t\tif (options.FullDecompilation)\n\t\t\t\tdis.WriteAssemblyReferences(metadata);\n\t\t\tif (metadata.IsAssembly)\n\t\t\t\tdis.WriteAssemblyHeader(module);\n\t\t\toutput.WriteLine();\n\t\t\tdis.WriteModuleHeader(module);\n\t\t\tif (options.FullDecompilation)\n\t\t\t{\n\t\t\t\toutput.WriteLine();\n\t\t\t\toutput.WriteLine();\n\t\t\t\tdis.WriteModuleContents(module);\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic override RichText GetRichTextTooltip(IEntity entity)\n\t\t{\n\t\t\tvar output = new AvalonEditTextOutput() { IgnoreNewLineAndIndent = true };\n\n\t\t\tvar disasm = CreateDisassembler(output, dockWorkspace.ActiveTabPage.CreateDecompilationOptions());\n\t\t\tMetadataFile module = entity.ParentModule?.MetadataFile;\n\t\t\tif (module == null)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tswitch (entity.SymbolKind)\n\t\t\t{\n\t\t\t\tcase SymbolKind.TypeDefinition:\n\t\t\t\t\tdisasm.DisassembleTypeHeader(module, (TypeDefinitionHandle)entity.MetadataToken);\n\t\t\t\t\tbreak;\n\t\t\t\tcase SymbolKind.Field:\n\t\t\t\t\tdisasm.DisassembleFieldHeader(module, (FieldDefinitionHandle)entity.MetadataToken);\n\t\t\t\t\tbreak;\n\t\t\t\tcase SymbolKind.Property:\n\t\t\t\tcase SymbolKind.Indexer:\n\t\t\t\t\tdisasm.DisassemblePropertyHeader(module, (PropertyDefinitionHandle)entity.MetadataToken);\n\t\t\t\t\tbreak;\n\t\t\t\tcase SymbolKind.Event:\n\t\t\t\t\tdisasm.DisassembleEventHeader(module, (EventDefinitionHandle)entity.MetadataToken);\n\t\t\t\t\tbreak;\n\t\t\t\tcase SymbolKind.Method:\n\t\t\t\tcase SymbolKind.Operator:\n\t\t\t\tcase SymbolKind.Constructor:\n\t\t\t\tcase SymbolKind.Destructor:\n\t\t\t\tcase SymbolKind.Accessor:\n\t\t\t\t\tdisasm.DisassembleMethodHeader(module, (MethodDefinitionHandle)entity.MetadataToken);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\toutput.Write(GetDisplayName(entity, true, true, true));\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\treturn new DocumentHighlighter(output.GetDocument(), base.SyntaxHighlighting).HighlightLine(1).ToRichText();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Languages/IResourceFileHandler.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.IO;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.ILSpyX;\n\nnamespace ICSharpCode.ILSpy\n{\n\tpublic interface IResourceFileHandler\n\t{\n\t\tstring EntryType { get; }\n\t\tbool CanHandle(string name, ResourceFileHandlerContext context);\n\t\tstring WriteResourceToFile(LoadedAssembly assembly, string fileName, Stream stream, ResourceFileHandlerContext context);\n\t}\n\n\tpublic class ResourceFileHandlerContext\n\t{\n\t\treadonly List<PartialTypeInfo> partialTypes = new();\n\t\tinternal List<PartialTypeInfo> PartialTypes => partialTypes;\n\n\t\treadonly Dictionary<string, string> additionalProperties = new();\n\t\tpublic Dictionary<string, string> AdditionalProperties => additionalProperties;\n\n\t\tpublic DecompilationOptions DecompilationOptions { get; }\n\n\t\tpublic ResourceFileHandlerContext(DecompilationOptions options)\n\t\t{\n\t\t\tthis.DecompilationOptions = options;\n\t\t}\n\n\t\tpublic void AddPartialTypeInfo(PartialTypeInfo info)\n\t\t{\n\t\t\tthis.PartialTypes.Add(info);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Languages/Language.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.PortableExecutable;\n\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Output;\nusing ICSharpCode.Decompiler.Solution;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.Abstractions;\n\nnamespace ICSharpCode.ILSpy\n{\n\t/// <summary>\n\t/// Base class for language-specific decompiler implementations.\n\t/// </summary>\n\t/// <remarks>\n\t/// Implementations of this class must be thread-safe.\n\t/// </remarks>\n\tpublic abstract class Language : ILanguage\n\t{\n\t\tprotected static SettingsService SettingsService { get; } = App.ExportProvider.GetExportedValue<SettingsService>();\n\n\t\tprotected static AssemblyTreeModel AssemblyTreeModel { get; } = App.ExportProvider.GetExportedValue<AssemblyTreeModel>();\n\n\t\tprotected static ICollection<IResourceFileHandler> ResourceFileHandlers { get; } = App.ExportProvider.GetExportedValues<IResourceFileHandler>().ToArray();\n\n\t\t/// <summary>\n\t\t/// Gets the name of the language (as shown in the UI)\n\t\t/// </summary>\n\t\tpublic abstract string Name { get; }\n\n\t\t/// <summary>\n\t\t/// Gets the file extension used by source code files in this language.\n\t\t/// </summary>\n\t\tpublic abstract string FileExtension { get; }\n\n\t\tpublic virtual string ProjectFileExtension {\n\t\t\tget { return null; }\n\t\t}\n\n\t\tpublic virtual IReadOnlyList<LanguageVersion> LanguageVersions {\n\t\t\tget { return EmptyList<LanguageVersion>.Instance; }\n\t\t}\n\n\t\tpublic bool HasLanguageVersions => LanguageVersions.Count > 0;\n\n\t\t/// <summary>\n\t\t/// Gets the syntax highlighting used for this language.\n\t\t/// </summary>\n\t\tpublic virtual IHighlightingDefinition SyntaxHighlighting {\n\t\t\tget {\n\t\t\t\treturn HighlightingManager.Instance.GetDefinitionByExtension(FileExtension);\n\t\t\t}\n\t\t}\n\n\t\tpublic virtual TextView.IBracketSearcher BracketSearcher {\n\t\t\tget {\n\t\t\t\treturn TextView.DefaultBracketSearcher.DefaultInstance;\n\t\t\t}\n\t\t}\n\n\t\tpublic virtual void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tWriteCommentLine(output, TypeToString(method.DeclaringTypeDefinition) + \".\" + method.Name);\n\t\t}\n\n\t\tpublic virtual void DecompileProperty(IProperty property, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tWriteCommentLine(output, TypeToString(property.DeclaringTypeDefinition) + \".\" + property.Name);\n\t\t}\n\n\t\tpublic virtual void DecompileField(IField field, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tWriteCommentLine(output, TypeToString(field.DeclaringTypeDefinition) + \".\" + field.Name);\n\t\t}\n\n\t\tpublic virtual void DecompileEvent(IEvent @event, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tWriteCommentLine(output, TypeToString(@event.DeclaringTypeDefinition) + \".\" + @event.Name);\n\t\t}\n\n\t\tpublic virtual void DecompileType(ITypeDefinition type, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tWriteCommentLine(output, TypeToString(type));\n\t\t}\n\n\t\tpublic virtual void DecompileNamespace(string nameSpace, IEnumerable<ITypeDefinition> types, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tWriteCommentLine(output, nameSpace);\n\t\t}\n\n\t\tpublic virtual ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tWriteCommentLine(output, assembly.FileName);\n\t\t\tvar asm = assembly.GetMetadataFileOrNull();\n\t\t\tif (asm == null)\n\t\t\t\treturn null;\n\t\t\tif (options.FullDecompilation && options.SaveAsProjectDirectory != null)\n\t\t\t{\n\t\t\t\tthrow new NotSupportedException($\"Language '{Name}' does not support exporting assemblies as projects!\");\n\t\t\t}\n\t\t\tvar metadata = asm.Metadata;\n\t\t\tif (metadata.IsAssembly)\n\t\t\t{\n\t\t\t\tvar name = metadata.GetAssemblyDefinition();\n\t\t\t\tif ((name.Flags & System.Reflection.AssemblyFlags.WindowsRuntime) != 0)\n\t\t\t\t{\n\t\t\t\t\tWriteCommentLine(output, metadata.GetString(name.Name) + \" [WinRT]\");\n\t\t\t\t}\n\t\t\t\telse if (metadata.TryGetFullAssemblyName(out string assemblyName))\n\t\t\t\t{\n\t\t\t\t\tWriteCommentLine(output, assemblyName);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tWriteCommentLine(output, \"ERR: Could not read assembly name\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tWriteCommentLine(output, metadata.GetString(metadata.GetModuleDefinition().Name));\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic virtual void WriteCommentLine(ITextOutput output, string comment)\n\t\t{\n\t\t\toutput.WriteLine(\"// \" + comment);\n\t\t}\n\n\t\t#region TypeToString\n\t\t/// <summary>\n\t\t/// Converts a type definition, reference or specification into a string. This method is used by tree nodes and search results.\n\t\t/// </summary>\n\t\tpublic virtual string TypeToString(IType type, ConversionFlags conversionFlags = ConversionFlags.UseFullyQualifiedTypeNames | ConversionFlags.UseFullyQualifiedEntityNames)\n\t\t{\n\t\t\treturn new ILAmbience() { ConversionFlags = conversionFlags }.ConvertType(type);\n\t\t}\n\t\t#endregion\n\n\t\t/// <summary>\n\t\t/// Converts a member signature to a string.\n\t\t/// This is used for displaying the tooltip on a member reference.\n\t\t/// </summary>\n\t\tpublic virtual string GetTooltip(IEntity entity)\n\t\t{\n\t\t\treturn GetDisplayName(entity, true, true, true);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Converts a member signature to a string.\n\t\t/// This is used for displaying the tooltip on a member reference.\n\t\t/// </summary>\n\t\tpublic virtual RichText GetRichTextTooltip(IEntity entity)\n\t\t{\n\t\t\treturn GetTooltip(entity);\n\t\t}\n\n\t\t[Obsolete(\"Use EntityToString instead\")]\n\t\tpublic virtual string FieldToString(IField field, bool includeDeclaringTypeName, bool includeNamespace, bool includeNamespaceOfDeclaringTypeName)\n\t\t{\n\t\t\tif (field == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(field));\n\t\t\tvar flags = ConversionFlags.ShowTypeParameterList\n\t\t\t\t| ConversionFlags.PlaceReturnTypeAfterParameterList\n\t\t\t\t| ConversionFlags.ShowReturnType\n\t\t\t\t| ConversionFlags.ShowParameterList\n\t\t\t\t| ConversionFlags.ShowParameterModifiers;\n\t\t\tif (includeDeclaringTypeName)\n\t\t\t\tflags |= ConversionFlags.ShowDeclaringType;\n\t\t\tif (includeNamespace)\n\t\t\t\tflags |= ConversionFlags.UseFullyQualifiedTypeNames;\n\t\t\tif (includeNamespaceOfDeclaringTypeName)\n\t\t\t\tflags |= ConversionFlags.UseFullyQualifiedEntityNames;\n\t\t\treturn EntityToString(field, flags);\n\t\t}\n\n\t\t[Obsolete(\"Use EntityToString instead\")]\n\t\tpublic virtual string PropertyToString(IProperty property, bool includeDeclaringTypeName, bool includeNamespace, bool includeNamespaceOfDeclaringTypeName)\n\t\t{\n\t\t\tif (property == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(property));\n\t\t\tvar flags = ConversionFlags.ShowTypeParameterList\n\t\t\t\t| ConversionFlags.PlaceReturnTypeAfterParameterList\n\t\t\t\t| ConversionFlags.ShowReturnType\n\t\t\t\t| ConversionFlags.ShowParameterList\n\t\t\t\t| ConversionFlags.ShowParameterModifiers;\n\t\t\tif (includeDeclaringTypeName)\n\t\t\t\tflags |= ConversionFlags.ShowDeclaringType;\n\t\t\tif (includeNamespace)\n\t\t\t\tflags |= ConversionFlags.UseFullyQualifiedTypeNames;\n\t\t\tif (includeNamespaceOfDeclaringTypeName)\n\t\t\t\tflags |= ConversionFlags.UseFullyQualifiedEntityNames;\n\t\t\treturn EntityToString(property, flags);\n\t\t}\n\n\t\t[Obsolete(\"Use EntityToString instead\")]\n\t\tpublic virtual string MethodToString(IMethod method, bool includeDeclaringTypeName, bool includeNamespace, bool includeNamespaceOfDeclaringTypeName)\n\t\t{\n\t\t\tif (method == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(method));\n\t\t\tvar flags = ConversionFlags.ShowTypeParameterList\n\t\t\t\t| ConversionFlags.PlaceReturnTypeAfterParameterList\n\t\t\t\t| ConversionFlags.ShowReturnType\n\t\t\t\t| ConversionFlags.ShowParameterList\n\t\t\t\t| ConversionFlags.ShowParameterModifiers;\n\t\t\tif (includeDeclaringTypeName)\n\t\t\t\tflags |= ConversionFlags.ShowDeclaringType;\n\t\t\tif (includeNamespace)\n\t\t\t\tflags |= ConversionFlags.UseFullyQualifiedTypeNames;\n\t\t\tif (includeNamespaceOfDeclaringTypeName)\n\t\t\t\tflags |= ConversionFlags.UseFullyQualifiedEntityNames;\n\t\t\treturn EntityToString(method, flags);\n\t\t}\n\n\t\t[Obsolete(\"Use EntityToString instead\")]\n\t\tpublic virtual string EventToString(IEvent @event, bool includeDeclaringTypeName, bool includeNamespace, bool includeNamespaceOfDeclaringTypeName)\n\t\t{\n\t\t\tif (@event == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(@event));\n\t\t\tvar flags = ConversionFlags.ShowTypeParameterList\n\t\t\t\t| ConversionFlags.PlaceReturnTypeAfterParameterList\n\t\t\t\t| ConversionFlags.ShowReturnType\n\t\t\t\t| ConversionFlags.ShowParameterList\n\t\t\t\t| ConversionFlags.ShowParameterModifiers;\n\t\t\tif (includeDeclaringTypeName)\n\t\t\t\tflags |= ConversionFlags.ShowDeclaringType;\n\t\t\tif (includeNamespace)\n\t\t\t\tflags |= ConversionFlags.UseFullyQualifiedTypeNames;\n\t\t\tif (includeNamespaceOfDeclaringTypeName)\n\t\t\t\tflags |= ConversionFlags.UseFullyQualifiedEntityNames;\n\t\t\treturn EntityToString(@event, flags);\n\t\t}\n\n\t\tpublic virtual string EntityToString(IEntity entity, ConversionFlags conversionFlags)\n\t\t{\n\t\t\tvar ambience = new ILAmbience();\n\t\t\tambience.ConversionFlags = ConversionFlags.ShowTypeParameterList\n\t\t\t\t| ConversionFlags.PlaceReturnTypeAfterParameterList\n\t\t\t\t| ConversionFlags.ShowReturnType\n\t\t\t\t| ConversionFlags.ShowParameterList\n\t\t\t\t| ConversionFlags.ShowParameterModifiers\n\t\t\t\t| conversionFlags;\n\t\t\treturn ambience.ConvertSymbol(entity);\n\t\t}\n\n\t\tprotected string GetDisplayName(IEntity entity, bool includeDeclaringTypeName, bool includeNamespace, bool includeNamespaceOfDeclaringTypeName)\n\t\t{\n\t\t\tstring entityName;\n\t\t\tif (entity is ITypeDefinition t && !t.MetadataToken.IsNil)\n\t\t\t{\n\t\t\t\tMetadataReader metadata = t.ParentModule.MetadataFile.Metadata;\n\t\t\t\tvar typeDef = metadata.GetTypeDefinition((TypeDefinitionHandle)t.MetadataToken);\n\t\t\t\tentityName = ILAmbience.EscapeName(metadata.GetString(typeDef.Name));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tentityName = ILAmbience.EscapeName(entity.Name);\n\t\t\t}\n\t\t\tif (includeNamespace || includeDeclaringTypeName)\n\t\t\t{\n\t\t\t\tif (entity.DeclaringTypeDefinition != null)\n\t\t\t\t\treturn TypeToString(entity.DeclaringTypeDefinition, ConversionFlags.ShowDeclaringType | ConversionFlags.UseFullyQualifiedEntityNames) + \".\" + entityName;\n\t\t\t\treturn ILAmbience.EscapeName(entity.Namespace) + \".\" + entityName;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn entityName;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Used for WPF keyboard navigation.\n\t\t/// </summary>\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn Name;\n\t\t}\n\n\t\tpublic virtual bool ShowMember(IEntity member)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// This should produce a string representation of the entity for search to match search strings against.\n\t\t/// </summary>\n\t\tpublic virtual string GetEntityName(MetadataFile module, EntityHandle handle, bool fullName, bool omitGenerics)\n\t\t{\n\t\t\tMetadataReader metadata = module.Metadata;\n\t\t\tswitch (handle.Kind)\n\t\t\t{\n\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\t\tif (fullName)\n\t\t\t\t\t\treturn ILAmbience.EscapeName(((TypeDefinitionHandle)handle).GetFullTypeName(metadata).ToILNameString(omitGenerics));\n\t\t\t\t\tvar td = metadata.GetTypeDefinition((TypeDefinitionHandle)handle);\n\t\t\t\t\treturn ILAmbience.EscapeName(metadata.GetString(td.Name));\n\t\t\t\tcase HandleKind.FieldDefinition:\n\t\t\t\t\tvar fd = metadata.GetFieldDefinition((FieldDefinitionHandle)handle);\n\t\t\t\t\tif (fullName)\n\t\t\t\t\t\treturn ILAmbience.EscapeName(fd.GetDeclaringType().GetFullTypeName(metadata).ToILNameString(omitGenerics) + \".\" + metadata.GetString(fd.Name));\n\t\t\t\t\treturn ILAmbience.EscapeName(metadata.GetString(fd.Name));\n\t\t\t\tcase HandleKind.MethodDefinition:\n\t\t\t\t\tvar md = metadata.GetMethodDefinition((MethodDefinitionHandle)handle);\n\t\t\t\t\tstring methodName = metadata.GetString(md.Name);\n\t\t\t\t\tif (!omitGenerics)\n\t\t\t\t\t{\n\t\t\t\t\t\tint genericParamCount = md.GetGenericParameters().Count;\n\t\t\t\t\t\tif (genericParamCount > 0)\n\t\t\t\t\t\t\tmethodName += \"``\" + genericParamCount;\n\t\t\t\t\t}\n\t\t\t\t\tif (fullName)\n\t\t\t\t\t\treturn ILAmbience.EscapeName(md.GetDeclaringType().GetFullTypeName(metadata).ToILNameString(omitGenerics) + \".\" + methodName);\n\t\t\t\t\treturn ILAmbience.EscapeName(methodName);\n\t\t\t\tcase HandleKind.EventDefinition:\n\t\t\t\t\tvar ed = metadata.GetEventDefinition((EventDefinitionHandle)handle);\n\t\t\t\t\tvar declaringType = metadata.GetMethodDefinition(ed.GetAccessors().GetAny()).GetDeclaringType();\n\t\t\t\t\tif (fullName)\n\t\t\t\t\t\treturn ILAmbience.EscapeName(declaringType.GetFullTypeName(metadata).ToILNameString(omitGenerics) + \".\" + metadata.GetString(ed.Name));\n\t\t\t\t\treturn ILAmbience.EscapeName(metadata.GetString(ed.Name));\n\t\t\t\tcase HandleKind.PropertyDefinition:\n\t\t\t\t\tvar pd = metadata.GetPropertyDefinition((PropertyDefinitionHandle)handle);\n\t\t\t\t\tdeclaringType = metadata.GetMethodDefinition(pd.GetAccessors().GetAny()).GetDeclaringType();\n\t\t\t\t\tif (fullName)\n\t\t\t\t\t\treturn ILAmbience.EscapeName(declaringType.GetFullTypeName(metadata).ToILNameString(omitGenerics) + \".\" + metadata.GetString(pd.Name));\n\t\t\t\t\treturn ILAmbience.EscapeName(metadata.GetString(pd.Name));\n\t\t\t\tdefault:\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tpublic virtual CodeMappingInfo GetCodeMappingInfo(MetadataFile module, EntityHandle member)\n\t\t{\n\t\t\tvar declaringType = (TypeDefinitionHandle)member.GetDeclaringType(module.Metadata);\n\n\t\t\tif (declaringType.IsNil && member.Kind == HandleKind.TypeDefinition)\n\t\t\t{\n\t\t\t\tdeclaringType = (TypeDefinitionHandle)member;\n\t\t\t}\n\n\t\t\treturn new CodeMappingInfo(module, declaringType);\n\t\t}\n\n\t\tstatic readonly IReadOnlyDictionary<Machine, string> osMachineLookup = new Dictionary<Machine, string>\n\t\t{\n\t\t\t{ (Machine)0x4644, \"MacOS\" },\n\t\t\t{ (Machine)0x7b79, \"Linux\" },\n\t\t\t{ (Machine)0xadc4, \"FreeBSD\" },\n\t\t\t{ (Machine)0x1993, \"NetBSD\" },\n\t\t\t{ (Machine)0x1992, \"Sun\" },\n\t\t};\n\n\t\tpublic static string GetPlatformDisplayName(PEFile module)\n\t\t{\n\t\t\tvar headers = module.Reader.PEHeaders;\n\t\t\tvar architecture = headers.CoffHeader.Machine;\n\t\t\tvar characteristics = headers.CoffHeader.Characteristics;\n\t\t\tvar corflags = headers.CorHeader.Flags;\n\n\t\t\tvar modifier = string.Empty;\n\n\t\t\tif (!Enum.IsDefined(architecture))\n\t\t\t{\n\t\t\t\tforeach (var (osEnum, osText) in osMachineLookup)\n\t\t\t\t{\n\t\t\t\t\tvar candidate = architecture ^ osEnum;\n\t\t\t\t\tif (Enum.IsDefined(candidate))\n\t\t\t\t\t{\n\t\t\t\t\t\tmodifier = osText + \" \";\n\t\t\t\t\t\tarchitecture = candidate;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tswitch (architecture)\n\t\t\t{\n\t\t\t\tcase Machine.I386:\n\t\t\t\t\tif ((corflags & CorFlags.Prefers32Bit) != 0)\n\t\t\t\t\t\treturn modifier + \"AnyCPU (32-bit preferred)\";\n\t\t\t\t\tif ((corflags & CorFlags.Requires32Bit) != 0)\n\t\t\t\t\t\treturn modifier + \"x86\";\n\t\t\t\t\t// According to ECMA-335, II.25.3.3.1 CorFlags.Requires32Bit and Characteristics.Bit32Machine must be in sync\n\t\t\t\t\t// for assemblies containing managed code. However, this is not true for C++/CLI assemblies.\n\t\t\t\t\tif ((corflags & CorFlags.ILOnly) == 0 && (characteristics & Characteristics.Bit32Machine) != 0)\n\t\t\t\t\t\treturn modifier + \"x86\";\n\t\t\t\t\treturn modifier + \"AnyCPU (64-bit preferred)\";\n\t\t\t\tcase Machine.Amd64:\n\t\t\t\t\treturn modifier + \"x64\";\n\t\t\t\tcase Machine.IA64:\n\t\t\t\t\treturn modifier + \"Itanium\";\n\t\t\t\tdefault:\n\t\t\t\t\treturn architecture.ToString();\n\t\t\t}\n\t\t}\n\n\t\tpublic static string GetRuntimeDisplayName(MetadataFile module)\n\t\t{\n\t\t\treturn module.Metadata.MetadataVersion;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Languages/LanguageService.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Composition;\nusing System.Linq;\n\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpyX;\n\nusing TomsToolbox.Wpf;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[Export]\n\t[Shared]\n\tpublic class LanguageService : ObservableObjectBase\n\t{\n\t\tprivate readonly SettingsService settingsService;\n\t\tprivate readonly LanguageSettings languageSettings;\n\n\t\tpublic LanguageService(IEnumerable<Language> languages, SettingsService settingsService, DockWorkspace dockWorkspace)\n\t\t{\n\t\t\tthis.settingsService = settingsService;\n\t\t\tlanguageSettings = settingsService.SessionSettings.LanguageSettings;\n\n\t\t\tvar sortedLanguages = languages.ToList();\n\n\t\t\tsortedLanguages.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.Ordinal));\n#if DEBUG\n\t\t\tsortedLanguages.AddRange(ILAstLanguage.GetDebugLanguages(dockWorkspace));\n\t\t\tsortedLanguages.AddRange(CSharpLanguage.GetDebugLanguages());\n#endif\n\t\t\tAllLanguages = sortedLanguages.AsReadOnly();\n\n\t\t\tthis.language = GetLanguage(languageSettings.LanguageId);\n\t\t\tthis.languageVersion = Language.LanguageVersions.FirstOrDefault(v => v.Version == languageSettings.LanguageVersionId) ?? Language.LanguageVersions.LastOrDefault();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// A list of all languages.\n\t\t/// </summary>\n\t\tpublic ReadOnlyCollection<Language> AllLanguages { get; }\n\n\t\t/// <summary>\n\t\t/// Gets a language using its name.\n\t\t/// If the language is not found, C# is returned instead.\n\t\t/// </summary>\n\t\tpublic Language GetLanguage(string? name)\n\t\t{\n\t\t\treturn AllLanguages.FirstOrDefault(l => l.Name == name) ?? AllLanguages.First();\n\t\t}\n\n\t\tILLanguage? ilLanguage;\n\n\t\tpublic ILLanguage ILLanguage => ilLanguage ??= (ILLanguage)GetLanguage(\"IL\");\n\n\t\t/// <summary>\n\t\t/// This dictionary is necessary to remember language versions across language changes. For example, \n\t\t/// the user first select C# 10, then switches to IL, then switches back to C#. After that we must be\n\t\t/// able to restore the original selection (i.e., C# 10).\n\t\t/// </summary>\n\t\tprivate readonly Dictionary<Language, LanguageVersion?> languageVersionHistory = new();\n\n\t\tLanguage language;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the current language.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// While this isn't related to filtering, having it as part of the FilterSettings\n\t\t/// makes it easy to pass it down into all tree nodes.\n\t\t/// </remarks>\n\t\tpublic Language Language {\n\t\t\tget => language;\n\t\t\tset {\n\t\t\t\tif (language == value)\n\t\t\t\t\treturn;\n\n\t\t\t\tif (language is { HasLanguageVersions: true })\n\t\t\t\t{\n\t\t\t\t\tlanguageVersionHistory[language] = languageVersion;\n\t\t\t\t}\n\n\t\t\t\tlanguage = value;\n\t\t\t\tOnPropertyChanged();\n\n\t\t\t\tlanguageSettings.LanguageId = language.Name;\n\n\t\t\t\tif (language.HasLanguageVersions)\n\t\t\t\t{\n\t\t\t\t\tLanguageVersion = languageVersionHistory.TryGetValue(value, out var version) ? version : Language.LanguageVersions.Last();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tLanguageVersion = default;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tLanguageVersion? languageVersion;\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the current language version.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// While this isn't related to filtering, having it as part of the FilterSettings\n\t\t/// makes it easy to pass it down into all tree nodes.\n\t\t/// </remarks>\n\t\tpublic LanguageVersion? LanguageVersion {\n\t\t\tget { return languageVersion; }\n\t\t\tset {\n\t\t\t\tif (languageVersion == value)\n\t\t\t\t\treturn;\n\n\t\t\t\tlanguageVersion = value;\n\t\t\t\tOnPropertyChanged();\n\n\t\t\t\tif (Language.HasLanguageVersions)\n\t\t\t\t{\n\t\t\t\t\tlanguageVersionHistory[Language] = languageVersion;\n\t\t\t\t}\n\n\t\t\t\tlanguageSettings.LanguageVersionId = languageVersion?.Version;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/MainWindow.xaml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Window x:Class=\"ICSharpCode.ILSpy.MainWindow\"\n\t\txmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n\t\txmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n\t\txmlns:local=\"clr-namespace:ICSharpCode.ILSpy\"\n\t\txmlns:avalondock=\"https://github.com/Dirkster99/AvalonDock\"\n\t\txmlns:controls=\"clr-namespace:ICSharpCode.ILSpy.Controls\"\n\t\txmlns:docking=\"clr-namespace:ICSharpCode.ILSpy.Docking\"\n\t\txmlns:properties=\"clr-namespace:ICSharpCode.ILSpy.Properties\"\n\t\tTitle=\"ILSpy\"\n\t\tMinWidth=\"250\"\n\t\tMinHeight=\"200\"\n\t\tUseLayoutRounding=\"True\"\n\t\tTextOptions.TextFormattingMode=\"Display\"\n\t\txmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" d:DesignHeight=\"500\" d:DesignWidth=\"500\"\n\t\txmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" mc:Ignorable=\"d\"\n\t\txmlns:b=\"http://schemas.microsoft.com/xaml/behaviors\"\n\t\txmlns:themes=\"clr-namespace:ICSharpCode.ILSpy.Themes\"\n\t\txmlns:toms=\"urn:TomsToolbox\"\n\t\txmlns:viewModels=\"clr-namespace:ICSharpCode.ILSpy.ViewModels\"\n\t\txmlns:composition=\"urn:TomsToolbox.Composition\"\n\t\txmlns:commands=\"clr-namespace:ICSharpCode.ILSpy.Commands\"\n\t\txmlns:analyzers=\"clr-namespace:ICSharpCode.ILSpy.Analyzers\"\n\t\td:DataContext=\"{d:DesignInstance local:MainWindowViewModel}\">\n\t<Window.Resources>\n\n\t\t<DataTemplate DataType=\"{x:Type viewModels:TabPageModel}\">\n\t\t\t<ContentPresenter Content=\"{Binding Content}\" />\n\t\t</DataTemplate>\n\n\t\t<DataTemplate DataType=\"{x:Type viewModels:LegacyToolPaneModel}\">\n\t\t\t<ContentPresenter Content=\"{Binding Content}\" />\n\t\t</DataTemplate>\n\n\t</Window.Resources>\n\n\t<b:Interaction.Behaviors>\n\t\t<themes:WindowStyleManagerBehavior />\n\t</b:Interaction.Behaviors>\n\n\t<Window.InputBindings>\n\t\t<KeyBinding Key=\"R\" Modifiers=\"Control\" Command=\"{composition:Import analyzers:AnalyzeCommand}\" />\n\t\t<KeyBinding Key=\"Z\" Modifiers=\"Control\" Command=\"{x:Static NavigationCommands.BrowseBack}\" />\n\t</Window.InputBindings>\n\n\t<Window.TaskbarItemInfo>\n\t\t<TaskbarItemInfo />\n\t</Window.TaskbarItemInfo>\n\n\t<DockPanel>\n\t\t<!-- Main menu -->\n\t\t<ContentControl DockPanel.Dock=\"Top\" Content=\"{composition:Import controls:MainMenu}\"/>\n\t\t<!-- ToolBar -->\n\t\t<ContentControl DockPanel.Dock=\"Top\" Content=\"{composition:Import controls:MainToolBar}\" />\n\t\t<!-- Update panel -->\n\t\t<ContentControl DockPanel.Dock=\"Top\" Content=\"{composition:Import viewModels:UpdatePanelViewModel}\" />\n\t\t<!-- Status bar -->\n\t\t<StatusBar x:Name=\"statusBar\" DockPanel.Dock=\"Bottom\" Height=\"26\" Visibility=\"Collapsed\">\n\t\t\t<StatusBarItem DockPanel.Dock=\"Right\">\n\t\t\t\t<TextBlock VerticalAlignment=\"Center\"\n\t\t\t\t\t\t   HorizontalAlignment=\"Right\"\n\t\t\t\t\t\t   x:Name=\"statusLabel\"\n\t\t\t\t\t\t   ToolTip=\"{x:Static properties:Resources.Status}\"\n\t\t\t\t\t\t   Text=\"{x:Static properties:Resources.StandBy}\" />\n\t\t\t</StatusBarItem>\n\t\t</StatusBar>\n\n\t\t<avalondock:DockingManager x:Name=\"DockManager\"\n\t\t\t\t\t\t\t\t   DataContext=\"{Binding Workspace}\"\n\t\t\t\t\t\t\t\t   ActiveContent=\"{Binding ActiveTabPage, Mode=TwoWay, Converter={docking:TabPageGuardConverter}}\"\n\t\t\t\t\t\t\t\t   AllowMixedOrientation=\"True\">\n\n\t\t\t<avalondock:DockingManager.DocumentHeaderTemplate>\n\t\t\t\t<DataTemplate DataType=\"{x:Type viewModels:PaneModel}\">\n\t\t\t\t\t<TextBlock x:Name=\"headerText\" Text=\"{Binding Title}\" />\n\t\t\t\t\t<DataTemplate.Triggers>\n\t\t\t\t\t\t<DataTrigger Binding=\"{Binding IsActive}\" Value=\"True\">\n\t\t\t\t\t\t\t<Setter TargetName=\"headerText\" Property=\"FontWeight\" Value=\"Bold\" />\n\t\t\t\t\t\t</DataTrigger>\n\t\t\t\t\t</DataTemplate.Triggers>\n\t\t\t\t</DataTemplate>\n\t\t\t</avalondock:DockingManager.DocumentHeaderTemplate>\n\n\t\t\t<avalondock:DockingManager.LayoutItemContainerStyleSelector>\n\t\t\t\t<docking:PaneStyleSelector>\n\t\t\t\t\t<docking:PaneStyleSelector.ToolPaneStyle>\n\t\t\t\t\t\t<Style TargetType=\"{x:Type avalondock:LayoutAnchorableItem}\">\n\t\t\t\t\t\t\t<Setter Property=\"Title\" Value=\"{Binding Model.Title}\" />\n\t\t\t\t\t\t\t<Setter Property=\"Visibility\" Value=\"{Binding Model.IsVisible, Mode=TwoWay, Converter={toms:BooleanToVisibilityConverter VisibilityWhenBooleanIsFalse=Hidden}}\" />\n\t\t\t\t\t\t\t<Setter Property=\"ContentId\" Value=\"{Binding Model.ContentId}\" />\n\t\t\t\t\t\t\t<Setter Property=\"IsSelected\" Value=\"{Binding Model.IsSelected, Mode=TwoWay}\" />\n\t\t\t\t\t\t\t<Setter Property=\"IsActive\" Value=\"{Binding Model.IsActive, Mode=TwoWay}\" />\n\t\t\t\t\t\t\t<Setter Property=\"CanHide\" Value=\"{Binding Model.IsCloseable}\" />\n\t\t\t\t\t\t\t<Setter Property=\"HideCommand\" Value=\"{Binding Model.CloseCommand}\" />\n\t\t\t\t\t\t\t<Setter Property=\"CanClose\" Value=\"{Binding Model.IsCloseable}\" />\n\t\t\t\t\t\t\t<Setter Property=\"CloseCommand\" Value=\"{Binding Model.CloseCommand}\" />\n\t\t\t\t\t\t</Style>\n\t\t\t\t\t</docking:PaneStyleSelector.ToolPaneStyle>\n\t\t\t\t\t<docking:PaneStyleSelector.TabPageStyle>\n\t\t\t\t\t\t<Style TargetType=\"{x:Type avalondock:LayoutItem}\">\n\t\t\t\t\t\t\t<Setter Property=\"Title\" Value=\"{Binding Model.Title}\" />\n\t\t\t\t\t\t\t<Setter Property=\"Visibility\" Value=\"{Binding Model.IsVisible, Mode=TwoWay, Converter={toms:BooleanToVisibilityConverter VisibilityWhenBooleanIsFalse=Hidden}}\" />\n\t\t\t\t\t\t\t<Setter Property=\"ContentId\" Value=\"{Binding Model.ContentId}\" />\n\t\t\t\t\t\t\t<Setter Property=\"IsSelected\" Value=\"{Binding Model.IsSelected, Mode=TwoWay}\" />\n\t\t\t\t\t\t\t<Setter Property=\"IsActive\" Value=\"{Binding Model.IsActive, Mode=TwoWay}\" />\n\t\t\t\t\t\t\t<Setter Property=\"CloseCommand\" Value=\"{Binding Model.CloseCommand}\" />\n\t\t\t\t\t\t\t<Setter Property=\"CanClose\" Value=\"{Binding Model.IsCloseable, Mode=TwoWay}\" />\n\t\t\t\t\t\t</Style>\n\t\t\t\t\t</docking:PaneStyleSelector.TabPageStyle>\n\t\t\t\t</docking:PaneStyleSelector>\n\t\t\t</avalondock:DockingManager.LayoutItemContainerStyleSelector>\n\t\t</avalondock:DockingManager>\n\t</DockPanel>\n</Window>"
  },
  {
    "path": "ILSpy/MainWindow.xaml.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.ComponentModel;\nusing System.Composition;\nusing System.Drawing;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Media;\nusing System.Windows.Threading;\n\nusing Screen = System.Windows.Forms.Screen;\n\nnamespace ICSharpCode.ILSpy\n{\n\t/// <summary>\n\t/// The main window of the application.\n\t/// </summary>\n\t[Export]\n\t[Shared]\n#pragma warning disable MEF003 // Main window is a singleton\n\tpartial class MainWindow\n\t{\n\t\tprivate readonly SettingsService settingsService;\n\n\t\tpublic MainWindow(MainWindowViewModel mainWindowViewModel, SettingsService settingsService)\n\t\t{\n\t\t\tthis.settingsService = settingsService;\n\n\t\t\t// Make sure Images are initialized on the UI thread.\n\t\t\tthis.Icon = Images.ILSpyIcon;\n\n\t\t\tthis.DataContext = mainWindowViewModel;\n\n\t\t\tInitializeComponent();\n\n\t\t\tDispatcher.BeginInvoke(DispatcherPriority.Background, () => {\n\t\t\t\tmainWindowViewModel.Workspace.InitializeLayout();\n\t\t\t\tMessageBus.Send(this, new MainWindowLoadedEventArgs());\n\t\t\t});\n\t\t}\n\n\t\tvoid SetWindowBounds(Rect bounds)\n\t\t{\n\t\t\tthis.Left = bounds.Left;\n\t\t\tthis.Top = bounds.Top;\n\t\t\tthis.Width = bounds.Width;\n\t\t\tthis.Height = bounds.Height;\n\t\t}\n\n\t\tprotected override void OnSourceInitialized(EventArgs e)\n\t\t{\n\t\t\tbase.OnSourceInitialized(e);\n\n\t\t\tvar source = PresentationSource.FromVisual(this);\n\n\t\t\tvar sessionSettings = settingsService.SessionSettings;\n\n\t\t\t// Validate and Set Window Bounds\n\t\t\tvar windowBounds = Rect.Transform(sessionSettings.WindowBounds, source?.CompositionTarget?.TransformToDevice ?? Matrix.Identity);\n\t\t\tvar boundsRect = new Rectangle((int)windowBounds.Left, (int)windowBounds.Top, (int)windowBounds.Width, (int)windowBounds.Height);\n\n\t\t\tbool areBoundsValid = Screen.AllScreens.Any(screen => Rectangle.Intersect(boundsRect, screen.WorkingArea) is { Width: > 10, Height: > 10 });\n\n\t\t\tSetWindowBounds(areBoundsValid ? sessionSettings.WindowBounds : SessionSettings.DefaultWindowBounds);\n\n\t\t\tthis.WindowState = sessionSettings.WindowState;\n\t\t}\n\n\t\tprotected override void OnStateChanged(EventArgs e)\n\t\t{\n\t\t\tbase.OnStateChanged(e);\n\t\t\t// store window state in settings only if it's not minimized\n\t\t\tif (this.WindowState != WindowState.Minimized)\n\t\t\t\tsettingsService.SessionSettings.WindowState = this.WindowState;\n\t\t}\n\n\t\tprotected override void OnClosing(CancelEventArgs e)\n\t\t{\n\t\t\tbase.OnClosing(e);\n\n\t\t\tvar snapshot = settingsService.CreateSnapshot();\n\n\t\t\tvar sessionSettings = snapshot.GetSettings<SessionSettings>();\n\n\t\t\tMessageBus.Send(this, new ApplySessionSettingsEventArgs(sessionSettings));\n\n\t\t\tsessionSettings.WindowBounds = this.RestoreBounds;\n\t\t\t// store window state in settings only if it's not minimized\n\t\t\tif (this.WindowState != WindowState.Minimized)\n\t\t\t\tsessionSettings.WindowState = this.WindowState;\n\t\t\tsessionSettings.DockLayout.Serialize(new(DockManager));\n\n\t\t\tsnapshot.Save();\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/MainWindowViewModel.cs",
    "content": "// Copyright (c) 2021 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\n\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpyX;\n\nusing TomsToolbox.Wpf;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[Export]\n\t[Shared]\n\tpublic class MainWindowViewModel(SettingsService settingsService, LanguageService languageService, DockWorkspace dockWorkspace) : ObservableObjectBase\n\t{\n\t\tpublic DockWorkspace Workspace { get; } = dockWorkspace;\n\n\t\tpublic SessionSettings SessionSettings => settingsService.SessionSettings;\n\n\t\tpublic LanguageService LanguageService => languageService;\n\n\t\tpublic AssemblyListManager AssemblyListManager => settingsService.AssemblyListManager;\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CoffHeaderTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX.Extensions;\n\nusing TomsToolbox.Essentials;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tclass CoffHeaderTreeNode : ILSpyTreeNode\n\t{\n\t\tprivate PEFile module;\n\n\t\tpublic CoffHeaderTreeNode(PEFile module)\n\t\t{\n\t\t\tthis.module = module;\n\t\t}\n\n\t\tpublic override object Text => \"COFF Header\";\n\n\t\tpublic override object NavigationText => $\"{Text} ({module.Name})\";\n\n\t\tpublic override object Icon => Images.Header;\n\n\t\tpublic override bool View(TabPageModel tabPage)\n\t\t{\n\t\t\ttabPage.Title = Text.ToString();\n\t\t\ttabPage.SupportsLanguageSwitching = false;\n\n\t\t\tvar dataGrid = Helpers.PrepareDataGrid(tabPage, this);\n\n\t\t\tdataGrid.RowDetailsTemplateSelector = new CharacteristicsDataTemplateSelector(\"Characteristics\");\n\t\t\tdataGrid.RowDetailsVisibilityMode = DataGridRowDetailsVisibilityMode.Collapsed;\n\n\t\t\tdataGrid.Columns.Clear();\n\t\t\tdataGrid.AutoGenerateColumns = false;\n\t\t\tdataGrid.Columns.AddRange(\n\t\t\t\tnew[] {\n\t\t\t\t\tnew DataGridTextColumn { IsReadOnly = true, Header = \"Member\", Binding = new Binding(\"Member\") },\n\t\t\t\t\tnew DataGridTextColumn { IsReadOnly = true, Header = \"Offset\", Binding = new Binding(\"Offset\") { StringFormat = \"X8\" } },\n\t\t\t\t\tnew DataGridTextColumn { IsReadOnly = true, Header = \"Size\", Binding = new Binding(\"Size\") },\n\t\t\t\t\tnew DataGridTextColumn { IsReadOnly = true, Header = \"Value\", Binding = new Binding(\".\") { Converter = ByteWidthConverter.Instance } },\n\t\t\t\t\tnew DataGridTextColumn { IsReadOnly = true, Header = \"Meaning\", Binding = new Binding(\"Meaning\") }\n\t\t\t\t}\n\t\t\t);\n\t\t\tvar headers = module.Reader.PEHeaders;\n\t\t\tvar header = headers.CoffHeader;\n\n\t\t\tvar linkerDateTime = DateTimeOffset.FromUnixTimeSeconds(unchecked((uint)header.TimeDateStamp)).DateTime;\n\n\t\t\tvar entries = new List<Entry>();\n\t\t\tentries.Add(new Entry(headers.CoffHeaderStartOffset, (int)header.Machine, 2, \"Machine\", header.Machine.ToString()));\n\t\t\tentries.Add(new Entry(headers.CoffHeaderStartOffset + 2, (int)header.NumberOfSections, 2, \"Number of Sections\", \"Number of sections; indicates size of the Section Table, which immediately follows the headers.\"));\n\t\t\tentries.Add(new Entry(headers.CoffHeaderStartOffset + 4, header.TimeDateStamp, 4, \"Time/Date Stamp\", $\"{linkerDateTime} (UTC) / {linkerDateTime.ToLocalTime()} - Time and date the file was created in seconds since January 1st 1970 00:00:00 or 0. Note that for deterministic builds this value is meaningless.\"));\n\t\t\tentries.Add(new Entry(headers.CoffHeaderStartOffset + 8, header.PointerToSymbolTable, 4, \"Pointer to Symbol Table\", \"Always 0 in .NET executables.\"));\n\t\t\tentries.Add(new Entry(headers.CoffHeaderStartOffset + 12, header.NumberOfSymbols, 4, \"Number of Symbols\", \"Always 0 in .NET executables.\"));\n\t\t\tentries.Add(new Entry(headers.CoffHeaderStartOffset + 16, (int)header.SizeOfOptionalHeader, 2, \"Optional Header Size\", \"Size of the optional header.\"));\n\t\t\tEntry characteristics;\n\t\t\tentries.Add(characteristics = new Entry(headers.CoffHeaderStartOffset + 18, (int)header.Characteristics, 2, \"Characteristics\", \"Flags indicating attributes of the file.\", new[] {\n\t\t\t\tnew BitEntry(((int)header.Characteristics & 0x0001) != 0, \"<0001> Relocation info stripped from file\"),\n\t\t\t\tnew BitEntry(((int)header.Characteristics & 0x0002) != 0, \"<0002> File is executable\"),\n\t\t\t\tnew BitEntry(((int)header.Characteristics & 0x0004) != 0, \"<0004> Line numbers stripped from file\"),\n\t\t\t\tnew BitEntry(((int)header.Characteristics & 0x0008) != 0, \"<0008> Local symbols stripped from file\"),\n\t\t\t\tnew BitEntry(((int)header.Characteristics & 0x0010) != 0, \"<0010> Aggressively trim working set\"),\n\t\t\t\tnew BitEntry(((int)header.Characteristics & 0x0020) != 0, \"<0020> Large address aware\"),\n\t\t\t\tnew BitEntry(((int)header.Characteristics & 0x0040) != 0, \"<0040> Reserved\"),\n\t\t\t\tnew BitEntry(((int)header.Characteristics & 0x0080) != 0, \"<0080> Bytes of machine words are reversed (Low)\"),\n\t\t\t\tnew BitEntry(((int)header.Characteristics & 0x0100) != 0, \"<0100> 32-bit word machine\"),\n\t\t\t\tnew BitEntry(((int)header.Characteristics & 0x0200) != 0, \"<0200> Debugging info stripped from file in .DBG file\"),\n\t\t\t\tnew BitEntry(((int)header.Characteristics & 0x0400) != 0, \"<0400> If image is on removable media, copy and run from the swap file\"),\n\t\t\t\tnew BitEntry(((int)header.Characteristics & 0x0800) != 0, \"<0800> If image is on Net, copy and run from the swap file\"),\n\t\t\t\tnew BitEntry(((int)header.Characteristics & 0x1000) != 0, \"<1000> System\"),\n\t\t\t\tnew BitEntry(((int)header.Characteristics & 0x2000) != 0, \"<2000> DLL\"),\n\t\t\t\tnew BitEntry(((int)header.Characteristics & 0x4000) != 0, \"<4000> File should only be run on a UP machine\"),\n\t\t\t\tnew BitEntry(((int)header.Characteristics & 0x8000) != 0, \"<8000> Bytes of machine words are reversed (High)\"),\n\t\t\t}));\n\n\t\t\tdataGrid.ItemsSource = entries;\n\t\t\tdataGrid.SetDetailsVisibilityForItem(characteristics, Visibility.Visible);\n\t\t\ttabPage.Content = dataGrid;\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t}\n\t}\n\n\tpublic class CharacteristicsDataTemplateSelector : DataTemplateSelector\n\t{\n\t\tstring detailsFieldName;\n\n\t\tpublic CharacteristicsDataTemplateSelector(string detailsFieldName)\n\t\t{\n\t\t\tthis.detailsFieldName = detailsFieldName;\n\t\t}\n\n\t\tpublic override DataTemplate SelectTemplate(object item, DependencyObject container)\n\t\t{\n\t\t\tif (((Entry)item).Member == detailsFieldName)\n\t\t\t\treturn (DataTemplate)MetadataTableViews.Instance[\"HeaderFlagsDetailsDataGrid\"];\n\t\t\treturn null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/AssemblyRefTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class AssemblyRefTableTreeNode : MetadataTableTreeNode<AssemblyRefTableTreeNode.AssemblyRefEntry>\n\t{\n\t\tpublic AssemblyRefTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.AssemblyRef, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<AssemblyRefEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<AssemblyRefEntry>();\n\t\t\tforeach (var row in metadataFile.Metadata.AssemblyReferences)\n\t\t\t{\n\t\t\t\tlist.Add(new AssemblyRefEntry(metadataFile, row));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct AssemblyRefEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly AssemblyReferenceHandle handle;\n\t\t\treadonly System.Reflection.Metadata.AssemblyReference assemblyRef;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.AssemblyRef)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.AssemblyRef) * (RID - 1);\n\n\t\t\tpublic Version Version => assemblyRef.Version;\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic AssemblyFlags Flags => assemblyRef.Flags;\n\n\t\t\tpublic object FlagsTooltip => new FlagsTooltip((int)assemblyRef.Flags, null) {\n\t\t\t\tFlagGroup.CreateMultipleChoiceGroup(typeof(AssemblyFlags), selectedValue: (int)assemblyRef.Flags, includeAll: false)\n\t\t\t};\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int PublicKeyOrToken => MetadataTokens.GetHeapOffset(assemblyRef.PublicKeyOrToken);\n\n\t\t\tpublic string PublicKeyOrTokenTooltip {\n\t\t\t\tget {\n\t\t\t\t\tif (assemblyRef.PublicKeyOrToken.IsNil)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tSystem.Collections.Immutable.ImmutableArray<byte> token = metadataFile.Metadata.GetBlobContent(assemblyRef.PublicKeyOrToken);\n\t\t\t\t\treturn token.ToHexString(token.Length);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic string NameTooltip => $\"{MetadataTokens.GetHeapOffset(assemblyRef.Name):X} \\\"{Name}\\\"\";\n\n\t\t\tpublic string Name => metadataFile.Metadata.GetString(assemblyRef.Name);\n\n\t\t\tpublic string CultureTooltip => $\"{MetadataTokens.GetHeapOffset(assemblyRef.Culture):X} \\\"{Culture}\\\"\";\n\n\t\t\tpublic string Culture => metadataFile.Metadata.GetString(assemblyRef.Culture);\n\n\t\t\tpublic AssemblyRefEntry(MetadataFile metadataFile, AssemblyReferenceHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.assemblyRef = metadataFile.Metadata.GetAssemblyReference(handle);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/CorTables/AssemblyTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class AssemblyTableTreeNode : MetadataTableTreeNode<AssemblyTableTreeNode.AssemblyEntry>\n\t{\n\t\tpublic AssemblyTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.Assembly, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<AssemblyEntry> LoadTable()\n\t\t{\n\t\t\tif (metadataFile.Metadata.IsAssembly)\n\t\t\t{\n\t\t\t\treturn [new AssemblyEntry(metadataFile.Metadata, metadataFile.MetadataOffset)];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn [];\n\t\t\t}\n\t\t}\n\n\t\tinternal readonly struct AssemblyEntry\n\t\t{\n\t\t\treadonly int metadataOffset;\n\t\t\treadonly MetadataReader metadata;\n\t\t\treadonly AssemblyDefinition assembly;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(EntityHandle.AssemblyDefinition);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(EntityHandle.AssemblyDefinition);\n\n\t\t\tpublic int Offset => metadataOffset\n\t\t\t\t+ metadata.GetTableMetadataOffset(TableIndex.Assembly)\n\t\t\t\t+ metadata.GetTableRowSize(TableIndex.Assembly) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X4\", Kind = ColumnKind.Other)]\n\t\t\tpublic AssemblyHashAlgorithm HashAlgorithm => assembly.HashAlgorithm;\n\n\t\t\tpublic object HashAlgorithmTooltip => new FlagsTooltip() {\n\t\t\t\tFlagGroup.CreateSingleChoiceGroup(typeof(AssemblyHashAlgorithm), selectedValue: (int)assembly.HashAlgorithm, defaultFlag: new Flag(\"None (0000)\", 0, false), includeAny: false)\n\t\t\t};\n\n\t\t\t[ColumnInfo(\"X4\", Kind = ColumnKind.Other)]\n\t\t\tpublic AssemblyFlags Flags => assembly.Flags;\n\n\t\t\tpublic object FlagsTooltip => new FlagsTooltip() {\n\t\t\t\tFlagGroup.CreateMultipleChoiceGroup(typeof(AssemblyFlags), selectedValue: (int)assembly.Flags, includeAll: false)\n\t\t\t};\n\n\t\t\tpublic Version Version => assembly.Version;\n\n\t\t\tpublic string NameTooltip => $\"{MetadataTokens.GetHeapOffset(assembly.Name):X} \\\"{Name}\\\"\";\n\n\t\t\tpublic string Name => metadata.GetString(assembly.Name);\n\n\t\t\tpublic string CultureTooltip => $\"{MetadataTokens.GetHeapOffset(assembly.Culture):X} \\\"{Culture}\\\"\";\n\n\t\t\tpublic string Culture => metadata.GetString(assembly.Culture);\n\n\t\t\tpublic AssemblyEntry(MetadataReader metadata, int metadataOffset)\n\t\t\t{\n\t\t\t\tthis.metadata = metadata;\n\t\t\t\tthis.metadataOffset = metadataOffset;\n\t\t\t\tthis.assembly = metadata.GetAssemblyDefinition();\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/CorTables/ClassLayoutTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Buffers.Binary;\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class ClassLayoutTableTreeNode : MetadataTableTreeNode<ClassLayoutTableTreeNode.ClassLayoutEntry>\n\t{\n\t\tpublic ClassLayoutTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.ClassLayout, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<ClassLayoutEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<ClassLayoutEntry>();\n\n\t\t\tvar length = metadataFile.Metadata.GetTableRowCount(TableIndex.ClassLayout);\n\t\t\tReadOnlySpan<byte> ptr = metadataFile.Metadata.AsReadOnlySpan();\n\n\t\t\tfor (int rid = 1; rid <= length; rid++)\n\t\t\t{\n\t\t\t\tlist.Add(new ClassLayoutEntry(metadataFile, ptr, rid));\n\t\t\t}\n\n\t\t\treturn list;\n\t\t}\n\n\t\treadonly struct ClassLayout\n\t\t{\n\t\t\tpublic readonly ushort PackingSize;\n\t\t\tpublic readonly EntityHandle Parent;\n\t\t\tpublic readonly uint ClassSize;\n\n\t\t\tpublic ClassLayout(ReadOnlySpan<byte> ptr, int typeDefSize)\n\t\t\t{\n\t\t\t\tPackingSize = BinaryPrimitives.ReadUInt16LittleEndian(ptr);\n\t\t\t\tClassSize = BinaryPrimitives.ReadUInt32LittleEndian(ptr.Slice(2, 4));\n\t\t\t\tParent = MetadataTokens.TypeDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(6, typeDefSize)));\n\t\t\t}\n\t\t}\n\n\t\tinternal struct ClassLayoutEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly ClassLayout classLayout;\n\n\t\t\tpublic int RID { get; }\n\n\t\t\tpublic int Token => 0x0F000000 | RID;\n\n\t\t\tpublic int Offset { get; }\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Parent => MetadataTokens.GetToken(classLayout.Parent);\n\n\t\t\tpublic void OnParentClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(\"metadata\", classLayout.Parent)));\n\t\t\t}\n\n\t\t\tstring parentTooltip;\n\t\t\tpublic string ParentTooltip => GenerateTooltip(ref parentTooltip, metadataFile, classLayout.Parent);\n\n\t\t\t[ColumnInfo(\"X4\", Kind = ColumnKind.Other)]\n\t\t\tpublic ushort PackingSize => classLayout.PackingSize;\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic uint ClassSize => classLayout.ClassSize;\n\n\t\t\tpublic ClassLayoutEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.RID = row;\n\t\t\t\tvar metadata = metadataFile.Metadata;\n\t\t\t\tvar rowOffset = metadata.GetTableMetadataOffset(TableIndex.ClassLayout)\n\t\t\t\t\t+ metadata.GetTableRowSize(TableIndex.ClassLayout) * (row - 1);\n\t\t\t\tthis.Offset = metadataFile.MetadataOffset + rowOffset;\n\t\t\t\tthis.classLayout = new ClassLayout(ptr.Slice(rowOffset), metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4);\n\t\t\t\tthis.parentTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/ConstantTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class ConstantTableTreeNode : MetadataTableTreeNode<ConstantTableTreeNode.ConstantEntry>\n\t{\n\t\tpublic ConstantTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.Constant, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<ConstantEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<ConstantEntry>();\n\t\t\tfor (int row = 1; row <= metadataFile.Metadata.GetTableRowCount(TableIndex.Constant); row++)\n\t\t\t{\n\t\t\t\tlist.Add(new ConstantEntry(metadataFile, MetadataTokens.ConstantHandle(row)));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct ConstantEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly EntityHandle handle;\n\t\t\treadonly Constant constant;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.Constant)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.Constant) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic ConstantTypeCode Type => constant.TypeCode;\n\n\t\t\tpublic string TypeTooltip => constant.TypeCode.ToString();\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Parent => MetadataTokens.GetToken(constant.Parent);\n\n\t\t\tpublic void OnParentClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, constant.Parent, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring parentTooltip;\n\t\t\tpublic string ParentTooltip => GenerateTooltip(ref parentTooltip, metadataFile, constant.Parent);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int Value => MetadataTokens.GetHeapOffset(constant.Value);\n\n\t\t\tpublic string ValueTooltip {\n\t\t\t\tget {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic ConstantEntry(MetadataFile metadataFile, ConstantHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.constant = metadataFile.Metadata.GetConstant(handle);\n\t\t\t\tthis.parentTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/CustomAttributeTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tclass CustomAttributeTableTreeNode : MetadataTableTreeNode<CustomAttributeTableTreeNode.CustomAttributeEntry>\n\t{\n\t\tpublic CustomAttributeTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.CustomAttribute, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<CustomAttributeEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<CustomAttributeEntry>();\n\t\t\tforeach (var row in metadataFile.Metadata.CustomAttributes)\n\t\t\t{\n\t\t\t\tlist.Add(new CustomAttributeEntry(metadataFile, row));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct CustomAttributeEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly CustomAttributeHandle handle;\n\t\t\treadonly CustomAttribute customAttr;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.CustomAttribute)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.CustomAttribute) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Parent => MetadataTokens.GetToken(customAttr.Parent);\n\n\t\t\tpublic void OnParentClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, customAttr.Parent, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring parentTooltip;\n\t\t\tpublic string ParentTooltip => GenerateTooltip(ref parentTooltip, metadataFile, customAttr.Parent);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Constructor => MetadataTokens.GetToken(customAttr.Constructor);\n\n\t\t\tpublic void OnConstructorClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, customAttr.Constructor, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring constructorTooltip;\n\t\t\tpublic string ConstructorTooltip => GenerateTooltip(ref constructorTooltip, metadataFile, customAttr.Constructor);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int Value => MetadataTokens.GetHeapOffset(customAttr.Value);\n\n\t\t\tpublic string ValueTooltip {\n\t\t\t\tget {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic CustomAttributeEntry(MetadataFile metadataFile, CustomAttributeHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.customAttr = metadataFile.Metadata.GetCustomAttribute(handle);\n\t\t\t\tthis.parentTooltip = null;\n\t\t\t\tthis.constructorTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/DeclSecurityTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tclass DeclSecurityTableTreeNode : MetadataTableTreeNode<DeclSecurityTableTreeNode.DeclSecurityEntry>\n\t{\n\t\tpublic DeclSecurityTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.DeclSecurity, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<DeclSecurityEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<DeclSecurityEntry>();\n\t\t\tforeach (var row in metadataFile.Metadata.DeclarativeSecurityAttributes)\n\t\t\t{\n\t\t\t\tlist.Add(new DeclSecurityEntry(metadataFile, row));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct DeclSecurityEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly DeclarativeSecurityAttributeHandle handle;\n\t\t\treadonly DeclarativeSecurityAttribute declSecAttr;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.DeclSecurity)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.DeclSecurity) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Parent => MetadataTokens.GetToken(declSecAttr.Parent);\n\n\t\t\tpublic void OnParentClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, declSecAttr.Parent, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring parentTooltip;\n\t\t\tpublic string ParentTooltip => GenerateTooltip(ref parentTooltip, metadataFile, declSecAttr.Parent);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic DeclarativeSecurityAction Action => declSecAttr.Action;\n\n\t\t\tpublic string ActionTooltip {\n\t\t\t\tget {\n\t\t\t\t\treturn declSecAttr.Action.ToString();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int PermissionSet => MetadataTokens.GetHeapOffset(declSecAttr.PermissionSet);\n\n\t\t\tpublic string PermissionSetTooltip {\n\t\t\t\tget {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic DeclSecurityEntry(MetadataFile metadataFile, DeclarativeSecurityAttributeHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.declSecAttr = metadataFile.Metadata.GetDeclarativeSecurityAttribute(handle);\n\t\t\t\tthis.parentTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/EventMapTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tclass EventMapTableTreeNode : MetadataTableTreeNode<EventMapTableTreeNode.EventMapEntry>\n\t{\n\t\tpublic EventMapTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.EventMap, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<EventMapEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<EventMapEntry>();\n\n\t\t\tvar metadata = metadataFile.Metadata;\n\t\t\tvar length = metadata.GetTableRowCount(TableIndex.EventMap);\n\t\t\tReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();\n\t\t\tint typeDefSize = metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4;\n\t\t\tint eventDefSize = metadata.GetTableRowCount(TableIndex.Event) < ushort.MaxValue ? 2 : 4;\n\t\t\tfor (int rid = 1; rid <= length; rid++)\n\t\t\t{\n\t\t\t\tlist.Add(new EventMapEntry(metadataFile, ptr, rid, typeDefSize, eventDefSize));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\treadonly struct EventMap\n\t\t{\n\t\t\tpublic readonly TypeDefinitionHandle Parent;\n\t\t\tpublic readonly EventDefinitionHandle EventList;\n\n\t\t\tpublic EventMap(ReadOnlySpan<byte> ptr, int typeDefSize, int eventDefSize)\n\t\t\t{\n\t\t\t\tParent = MetadataTokens.TypeDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(0, typeDefSize)));\n\t\t\t\tEventList = MetadataTokens.EventDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(typeDefSize, eventDefSize)));\n\t\t\t}\n\t\t}\n\n\t\tinternal struct EventMapEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly EventMap eventMap;\n\n\t\t\tpublic int RID { get; }\n\t\t\tpublic int Token => 0x12000000 | RID;\n\t\t\tpublic int Offset { get; }\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Parent => MetadataTokens.GetToken(eventMap.Parent);\n\n\t\t\tpublic void OnParentClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, eventMap.Parent, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring parentTooltip;\n\t\t\tpublic string ParentTooltip => GenerateTooltip(ref parentTooltip, metadataFile, eventMap.Parent);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int EventList => MetadataTokens.GetToken(eventMap.EventList);\n\n\t\t\tpublic void OnEventListClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, eventMap.EventList, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring eventListTooltip;\n\t\t\tpublic string EventListTooltip => GenerateTooltip(ref eventListTooltip, metadataFile, eventMap.EventList);\n\n\t\t\tpublic EventMapEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row, int typeDefSize, int eventDefSize)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.RID = row;\n\t\t\t\tvar rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.EventMap)\n\t\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.EventMap) * (row - 1);\n\t\t\t\tthis.Offset = metadataFile.MetadataOffset + rowOffset;\n\t\t\t\tthis.eventMap = new EventMap(ptr.Slice(rowOffset), typeDefSize, eventDefSize);\n\t\t\t\tthis.parentTooltip = null;\n\t\t\t\tthis.eventListTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/EventTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class EventTableTreeNode : MetadataTableTreeNode<EventTableTreeNode.EventDefEntry>\n\t{\n\t\tpublic EventTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.Event, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<EventDefEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<EventDefEntry>();\n\t\t\tforeach (var row in metadataFile.Metadata.EventDefinitions)\n\t\t\t{\n\t\t\t\tlist.Add(new EventDefEntry(metadataFile, row));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct EventDefEntry : IMemberTreeNode\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly EventDefinitionHandle handle;\n\t\t\treadonly EventDefinition eventDef;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.Event)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.Event) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic EventAttributes Attributes => eventDef.Attributes;\n\n\t\t\tpublic object AttributesTooltip => new FlagsTooltip {\n\t\t\t\tFlagGroup.CreateMultipleChoiceGroup(typeof(EventAttributes), selectedValue: (int)eventDef.Attributes, includeAll: false),\n\t\t\t};\n\n\t\t\tpublic string NameTooltip => $\"{MetadataTokens.GetHeapOffset(eventDef.Name):X} \\\"{Name}\\\"\";\n\n\t\t\tpublic string Name => metadataFile.Metadata.GetString(eventDef.Name);\n\n\t\t\tIEntity IMemberTreeNode.Member {\n\t\t\t\tget {\n\t\t\t\t\treturn ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion)?.MainModule)?.GetDefinition(handle);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Type => MetadataTokens.GetToken(eventDef.Type);\n\n\t\t\tpublic void OnTypeClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, eventDef.Type, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring typeTooltip;\n\t\t\tpublic string TypeTooltip => GenerateTooltip(ref typeTooltip, metadataFile, eventDef.Type);\n\n\t\t\tpublic EventDefEntry(MetadataFile metadataFile, EventDefinitionHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.eventDef = metadataFile.Metadata.GetEventDefinition(handle);\n\t\t\t\tthis.typeTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/ExportedTypeTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class ExportedTypeTableTreeNode : MetadataTableTreeNode<ExportedTypeTableTreeNode.ExportedTypeEntry>\n\t{\n\t\tpublic ExportedTypeTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.ExportedType, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<ExportedTypeEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<ExportedTypeEntry>();\n\t\t\tvar metadata = metadataFile.Metadata;\n\t\t\tforeach (var row in metadata.ExportedTypes)\n\t\t\t{\n\t\t\t\tlist.Add(new ExportedTypeEntry(metadataFile, row, metadata.GetExportedType(row)));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct ExportedTypeEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly ExportedTypeHandle handle;\n\t\t\treadonly ExportedType type;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.ExportedType)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.ExportedType) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic TypeAttributes Attributes => type.Attributes;\n\n\t\t\tconst TypeAttributes otherFlagsMask = ~(TypeAttributes.VisibilityMask | TypeAttributes.LayoutMask | TypeAttributes.ClassSemanticsMask | TypeAttributes.StringFormatMask | TypeAttributes.CustomFormatMask);\n\n\t\t\tpublic object AttributesTooltip => new FlagsTooltip {\n\t\t\t\tFlagGroup.CreateSingleChoiceGroup(typeof(TypeAttributes), \"Visibility: \", (int)TypeAttributes.VisibilityMask, (int)(type.Attributes & TypeAttributes.VisibilityMask), new Flag(\"NotPublic (0000)\", 0, false), includeAny: false),\n\t\t\t\tFlagGroup.CreateSingleChoiceGroup(typeof(TypeAttributes), \"Class layout: \", (int)TypeAttributes.LayoutMask, (int)(type.Attributes & TypeAttributes.LayoutMask), new Flag(\"AutoLayout (0000)\", 0, false), includeAny: false),\n\t\t\t\tFlagGroup.CreateSingleChoiceGroup(typeof(TypeAttributes), \"Class semantics: \", (int)TypeAttributes.ClassSemanticsMask, (int)(type.Attributes & TypeAttributes.ClassSemanticsMask), new Flag(\"Class (0000)\", 0, false), includeAny: false),\n\t\t\t\tFlagGroup.CreateSingleChoiceGroup(typeof(TypeAttributes), \"String format: \", (int)TypeAttributes.StringFormatMask, (int)(type.Attributes & TypeAttributes.StringFormatMask), new Flag(\"AnsiClass (0000)\", 0, false), includeAny: false),\n\t\t\t\tFlagGroup.CreateSingleChoiceGroup(typeof(TypeAttributes), \"Custom format: \", (int)TypeAttributes.CustomFormatMask, (int)(type.Attributes & TypeAttributes.CustomFormatMask), new Flag(\"Value0 (0000)\", 0, false), includeAny: false),\n\t\t\t\tFlagGroup.CreateMultipleChoiceGroup(typeof(TypeAttributes), \"Flags:\", (int)otherFlagsMask, (int)(type.Attributes & otherFlagsMask), includeAll: false),\n\t\t\t};\n\n\t\t\tpublic int TypeDefId => type.GetTypeDefinitionId();\n\n\t\t\tpublic string TypeNameTooltip => $\"{MetadataTokens.GetHeapOffset(type.Name):X} \\\"{TypeName}\\\"\";\n\n\t\t\tpublic string TypeName => metadataFile.Metadata.GetString(type.Name);\n\n\t\t\tpublic string TypeNamespaceTooltip => $\"{MetadataTokens.GetHeapOffset(type.Namespace):X} \\\"{TypeNamespace}\\\"\";\n\n\t\t\tpublic string TypeNamespace => metadataFile.Metadata.GetString(type.Namespace);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Implementation => MetadataTokens.GetToken(type.Implementation);\n\n\t\t\tpublic void OnImplementationClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, type.Implementation, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring implementationTooltip;\n\t\t\tpublic string ImplementationTooltip => GenerateTooltip(ref implementationTooltip, metadataFile, type.Implementation);\n\n\t\t\tpublic ExportedTypeEntry(MetadataFile metadataFile, ExportedTypeHandle handle, ExportedType type)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.type = type;\n\t\t\t\tthis.implementationTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/CorTables/FieldLayoutTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Buffers.Binary;\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class FieldLayoutTableTreeNode : MetadataTableTreeNode<FieldLayoutTableTreeNode.FieldLayoutEntry>\n\t{\n\t\tpublic FieldLayoutTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.FieldLayout, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<FieldLayoutEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<FieldLayoutEntry>();\n\n\t\t\tvar metadata = metadataFile.Metadata;\n\t\t\tvar length = metadata.GetTableRowCount(TableIndex.FieldLayout);\n\t\t\tReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();\n\t\t\tint fieldDefSize = metadata.GetTableRowCount(TableIndex.Field) < ushort.MaxValue ? 2 : 4;\n\t\t\tfor (int rid = 1; rid <= length; rid++)\n\t\t\t{\n\t\t\t\tlist.Add(new FieldLayoutEntry(metadataFile, ptr, rid, fieldDefSize));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\treadonly struct FieldLayout\n\t\t{\n\t\t\tpublic readonly int Offset;\n\t\t\tpublic readonly FieldDefinitionHandle Field;\n\n\t\t\tpublic FieldLayout(ReadOnlySpan<byte> ptr, int fieldDefSize)\n\t\t\t{\n\t\t\t\tOffset = BinaryPrimitives.ReadInt32LittleEndian(ptr);\n\t\t\t\tField = MetadataTokens.FieldDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(4, fieldDefSize)));\n\t\t\t}\n\t\t}\n\n\t\tinternal struct FieldLayoutEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly FieldLayout fieldLayout;\n\n\t\t\tpublic int RID { get; }\n\t\t\tpublic int Token => 0x10000000 | RID;\n\t\t\tpublic int Offset { get; }\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Field => MetadataTokens.GetToken(fieldLayout.Field);\n\n\t\t\tpublic void OnFieldClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, fieldLayout.Field, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring fieldTooltip;\n\t\t\tpublic string FieldTooltip => GenerateTooltip(ref fieldTooltip, metadataFile, fieldLayout.Field);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic int FieldOffset => fieldLayout.Offset;\n\n\t\t\tpublic FieldLayoutEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row, int fieldDefSize)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.RID = row;\n\t\t\t\tvar rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.FieldLayout)\n\t\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.FieldLayout) * (row - 1);\n\t\t\t\tthis.Offset = metadataFile.MetadataOffset + rowOffset;\n\t\t\t\tthis.fieldLayout = new FieldLayout(ptr.Slice(rowOffset), fieldDefSize);\n\t\t\t\tthis.fieldTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/FieldMarshalTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class FieldMarshalTableTreeNode : MetadataTableTreeNode<FieldMarshalTableTreeNode.FieldMarshalEntry>\n\t{\n\t\tpublic FieldMarshalTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.FieldMarshal, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<FieldMarshalEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<FieldMarshalEntry>();\n\n\t\t\tvar metadata = metadataFile.Metadata;\n\t\t\tvar length = metadata.GetTableRowCount(TableIndex.FieldMarshal);\n\t\t\tReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();\n\t\t\tint hasFieldMarshalRefSize = metadata.ComputeCodedTokenSize(32768, TableMask.Field | TableMask.Param);\n\t\t\tint blobHeapSize = metadata.GetHeapSize(HeapIndex.Blob) < ushort.MaxValue ? 2 : 4;\n\t\t\tfor (int rid = 1; rid <= length; rid++)\n\t\t\t{\n\t\t\t\tlist.Add(new FieldMarshalEntry(metadataFile, ptr, rid, blobHeapSize, hasFieldMarshalRefSize));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\treadonly struct FieldMarshal\n\t\t{\n\t\t\tpublic readonly BlobHandle NativeType;\n\t\t\tpublic readonly EntityHandle Parent;\n\n\t\t\tpublic FieldMarshal(ReadOnlySpan<byte> ptr, int blobHeapSize, int hasFieldMarshalRefSize)\n\t\t\t{\n\t\t\t\tParent = Helpers.FromHasFieldMarshalTag((uint)Helpers.GetValueLittleEndian(ptr, hasFieldMarshalRefSize));\n\t\t\t\tNativeType = MetadataTokens.BlobHandle(Helpers.GetValueLittleEndian(ptr.Slice(hasFieldMarshalRefSize, blobHeapSize)));\n\t\t\t}\n\t\t}\n\n\t\tinternal struct FieldMarshalEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly FieldMarshal fieldMarshal;\n\n\t\t\tpublic int RID { get; }\n\t\t\tpublic int Token => 0x0D000000 | RID;\n\t\t\tpublic int Offset { get; }\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Parent => MetadataTokens.GetToken(fieldMarshal.Parent);\n\n\t\t\tpublic void OnParentClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, fieldMarshal.Parent, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring parentTooltip;\n\t\t\tpublic string ParentTooltip => GenerateTooltip(ref parentTooltip, metadataFile, fieldMarshal.Parent);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int NativeType => MetadataTokens.GetHeapOffset(fieldMarshal.NativeType);\n\n\t\t\tpublic FieldMarshalEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row, int blobHeapSize, int hasFieldMarshalRefSize)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.RID = row;\n\t\t\t\tvar rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.FieldMarshal)\n\t\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.FieldMarshal) * (row - 1);\n\t\t\t\tthis.Offset = metadataFile.MetadataOffset + rowOffset;\n\t\t\t\tthis.fieldMarshal = new FieldMarshal(ptr.Slice(rowOffset), blobHeapSize, hasFieldMarshalRefSize);\n\t\t\t\tthis.parentTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/FieldRVATableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Buffers.Binary;\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class FieldRVATableTreeNode : MetadataTableTreeNode<FieldRVATableTreeNode.FieldRVAEntry>\n\t{\n\t\tpublic FieldRVATableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.FieldRva, metadataFile)\n\t\t{\n\t\t}\n\n\t\tpublic override object Text => $\"1D FieldRVA ({metadataFile.Metadata.GetTableRowCount(TableIndex.FieldRva)})\";\n\n\t\tprotected override IReadOnlyList<FieldRVAEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<FieldRVAEntry>();\n\n\t\t\tvar metadata = metadataFile.Metadata;\n\t\t\tvar length = metadata.GetTableRowCount(TableIndex.FieldRva);\n\t\t\tReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();\n\t\t\tint metadataOffset = metadataFile.MetadataOffset;\n\t\t\tint fieldDefSize = metadata.GetTableRowCount(TableIndex.Field) < ushort.MaxValue ? 2 : 4;\n\t\t\tfor (int rid = 1; rid <= length; rid++)\n\t\t\t{\n\t\t\t\tlist.Add(new FieldRVAEntry(metadataFile, metadataOffset, ptr, rid, fieldDefSize));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\treadonly struct FieldRVA\n\t\t{\n\t\t\tpublic readonly int Offset;\n\t\t\tpublic readonly FieldDefinitionHandle Field;\n\n\t\t\tpublic FieldRVA(ReadOnlySpan<byte> ptr, int fieldDefSize)\n\t\t\t{\n\t\t\t\tOffset = BinaryPrimitives.ReadInt32LittleEndian(ptr);\n\t\t\t\tField = MetadataTokens.FieldDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(4, fieldDefSize)));\n\t\t\t}\n\t\t}\n\n\t\tinternal struct FieldRVAEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly FieldRVA fieldRVA;\n\n\t\t\tpublic int RID { get; }\n\t\t\tpublic int Token => 0x1D000000 | RID;\n\t\t\tpublic int Offset { get; }\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Field => MetadataTokens.GetToken(fieldRVA.Field);\n\n\t\t\tpublic void OnFieldClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, fieldRVA.Field, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring fieldTooltip;\n\t\t\tpublic string FieldTooltip => GenerateTooltip(ref fieldTooltip, metadataFile, fieldRVA.Field);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic int FieldOffset => fieldRVA.Offset;\n\n\t\t\tpublic FieldRVAEntry(MetadataFile metadataFile, int metadataOffset, ReadOnlySpan<byte> ptr, int row, int fieldDefSize)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.RID = row;\n\t\t\t\tvar rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.FieldRva)\n\t\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.FieldRva) * (row - 1);\n\t\t\t\tthis.Offset = metadataOffset + rowOffset;\n\t\t\t\tthis.fieldRVA = new FieldRVA(ptr.Slice(rowOffset), fieldDefSize);\n\t\t\t\tthis.fieldTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/FieldTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class FieldTableTreeNode : MetadataTableTreeNode<FieldTableTreeNode.FieldDefEntry>\n\t{\n\t\tpublic FieldTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.Field, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<FieldDefEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<FieldDefEntry>();\n\t\t\tforeach (var row in metadataFile.Metadata.FieldDefinitions)\n\t\t\t{\n\t\t\t\tlist.Add(new FieldDefEntry(metadataFile, row));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct FieldDefEntry : IMemberTreeNode\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly FieldDefinitionHandle handle;\n\t\t\treadonly FieldDefinition fieldDef;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.Field)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.Field) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic FieldAttributes Attributes => fieldDef.Attributes;\n\n\t\t\tconst FieldAttributes otherFlagsMask = ~(FieldAttributes.FieldAccessMask);\n\n\t\t\tpublic object AttributesTooltip => new FlagsTooltip() {\n\t\t\t\tFlagGroup.CreateSingleChoiceGroup(typeof(FieldAttributes), \"Field access: \", (int)FieldAttributes.FieldAccessMask, (int)(fieldDef.Attributes & FieldAttributes.FieldAccessMask), new Flag(\"CompilerControlled (0000)\", 0, false), includeAny: false),\n\t\t\t\tFlagGroup.CreateMultipleChoiceGroup(typeof(FieldAttributes), \"Flags:\", (int)otherFlagsMask, (int)(fieldDef.Attributes & otherFlagsMask), includeAll: false),\n\t\t\t};\n\n\t\t\tpublic string Name => metadataFile.Metadata.GetString(fieldDef.Name);\n\n\t\t\tpublic string NameTooltip => $\"{MetadataTokens.GetHeapOffset(fieldDef.Name):X} \\\"{Name}\\\"\";\n\n\t\t\tIEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion)?.MainModule)?.GetDefinition(handle);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int Signature => MetadataTokens.GetHeapOffset(fieldDef.Signature);\n\n\t\t\tstring signatureTooltip;\n\t\t\tpublic string SignatureTooltip => GenerateTooltip(ref signatureTooltip, metadataFile, handle);\n\n\t\t\tpublic FieldDefEntry(MetadataFile metadataFile, FieldDefinitionHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.fieldDef = metadataFile.Metadata.GetFieldDefinition(handle);\n\t\t\t\tthis.signatureTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/CorTables/FileTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tclass FileTableTreeNode : MetadataTableTreeNode<FileTableTreeNode.FileEntry>\n\t{\n\t\tpublic FileTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.File, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<FileEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<FileEntry>();\n\t\t\tforeach (var row in metadataFile.Metadata.AssemblyFiles)\n\t\t\t{\n\t\t\t\tlist.Add(new FileEntry(metadataFile, row));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct FileEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly AssemblyFileHandle handle;\n\t\t\treadonly AssemblyFile assemblyFile;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.File)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.File) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic int Attributes => assemblyFile.ContainsMetadata ? 1 : 0;\n\n\t\t\tpublic string AttributesTooltip => assemblyFile.ContainsMetadata ? \"ContainsMetaData\" : \"ContainsNoMetaData\";\n\n\t\t\tpublic string Name => metadataFile.Metadata.GetString(assemblyFile.Name);\n\n\t\t\tpublic string NameTooltip => $\"{MetadataTokens.GetHeapOffset(assemblyFile.Name):X} \\\"{Name}\\\"\";\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int HashValue => MetadataTokens.GetHeapOffset(assemblyFile.HashValue);\n\n\t\t\tpublic string HashValueTooltip {\n\t\t\t\tget {\n\t\t\t\t\tif (assemblyFile.HashValue.IsNil)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tSystem.Collections.Immutable.ImmutableArray<byte> token = metadataFile.Metadata.GetBlobContent(assemblyFile.HashValue);\n\t\t\t\t\treturn token.ToHexString(token.Length);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic FileEntry(MetadataFile metadataFile, AssemblyFileHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.assemblyFile = metadataFile.Metadata.GetAssemblyFile(handle);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/GenericParamConstraintTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class GenericParamConstraintTableTreeNode : MetadataTableTreeNode<GenericParamConstraintTableTreeNode.GenericParamConstraintEntry>\n\t{\n\t\tpublic GenericParamConstraintTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.GenericParamConstraint, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<GenericParamConstraintEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<GenericParamConstraintEntry>();\n\t\t\tvar metadata = metadataFile.Metadata;\n\t\t\tfor (int row = 1; row <= metadata.GetTableRowCount(TableIndex.GenericParamConstraint); row++)\n\t\t\t{\n\t\t\t\tlist.Add(new GenericParamConstraintEntry(metadataFile, MetadataTokens.GenericParameterConstraintHandle(row)));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct GenericParamConstraintEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly GenericParameterConstraintHandle handle;\n\t\t\treadonly GenericParameterConstraint genericParamConstraint;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.GenericParamConstraint)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.GenericParamConstraint) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Owner => MetadataTokens.GetToken(genericParamConstraint.Parameter);\n\n\t\t\tpublic void OnOwnerClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, genericParamConstraint.Parameter, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring ownerTooltip;\n\n\t\t\tpublic string OwnerTooltip {\n\t\t\t\tget {\n\t\t\t\t\tif (ownerTooltip == null)\n\t\t\t\t\t{\n\t\t\t\t\t\tITextOutput output = new PlainTextOutput();\n\t\t\t\t\t\tvar p = metadataFile.Metadata.GetGenericParameter(genericParamConstraint.Parameter);\n\t\t\t\t\t\toutput.Write(\"parameter \" + p.Index + (p.Name.IsNil ? \"\" : \" (\" + metadataFile.Metadata.GetString(p.Name) + \")\") + \" of \");\n\t\t\t\t\t\tp.Parent.WriteTo(metadataFile, output, default);\n\t\t\t\t\t\townerTooltip = output.ToString();\n\t\t\t\t\t}\n\t\t\t\t\treturn ownerTooltip;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Type => MetadataTokens.GetToken(genericParamConstraint.Type);\n\n\t\t\tpublic void OnTypeClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, genericParamConstraint.Type, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring typeTooltip;\n\t\t\tpublic string TypeTooltip => GenerateTooltip(ref typeTooltip, metadataFile, genericParamConstraint.Type);\n\n\t\t\tpublic GenericParamConstraintEntry(MetadataFile metadataFile, GenericParameterConstraintHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.genericParamConstraint = metadataFile.Metadata.GetGenericParameterConstraint(handle);\n\t\t\t\tthis.ownerTooltip = null;\n\t\t\t\tthis.typeTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/CorTables/GenericParamTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class GenericParamTableTreeNode : MetadataTableTreeNode<GenericParamTableTreeNode.GenericParamEntry>\n\t{\n\t\tpublic GenericParamTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.GenericParam, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<GenericParamEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<GenericParamEntry>();\n\t\t\tfor (int row = 1; row <= metadataFile.Metadata.GetTableRowCount(TableIndex.GenericParam); row++)\n\t\t\t{\n\t\t\t\tlist.Add(new GenericParamEntry(metadataFile, MetadataTokens.GenericParameterHandle(row)));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct GenericParamEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly GenericParameterHandle handle;\n\t\t\treadonly GenericParameter genericParam;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.GenericParam)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.GenericParam) * (RID - 1);\n\n\t\t\tpublic int Number => genericParam.Index;\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic GenericParameterAttributes Attributes => genericParam.Attributes;\n\n\t\t\tpublic object AttributesTooltip => new FlagsTooltip {\n\t\t\t\tFlagGroup.CreateSingleChoiceGroup(typeof(GenericParameterAttributes), \"Variance: \", (int)GenericParameterAttributes.VarianceMask, (int)(genericParam.Attributes & GenericParameterAttributes.VarianceMask), new Flag(\"None (0000)\", 0, false), includeAny: false),\n\t\t\t\tFlagGroup.CreateMultipleChoiceGroup(typeof(GenericParameterAttributes), \"Special Constraint: \", (int)GenericParameterAttributes.SpecialConstraintMask, (int)(genericParam.Attributes & GenericParameterAttributes.SpecialConstraintMask), includeAll: false),\n\t\t\t};\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Owner => MetadataTokens.GetToken(genericParam.Parent);\n\n\t\t\tpublic void OnOwnerClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, genericParam.Parent, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring ownerTooltip;\n\t\t\tpublic string OwnerTooltip => GenerateTooltip(ref ownerTooltip, metadataFile, genericParam.Parent);\n\n\t\t\tpublic string Name => metadataFile.Metadata.GetString(genericParam.Name);\n\n\t\t\tpublic string NameTooltip => $\"{MetadataTokens.GetHeapOffset(genericParam.Name):X} \\\"{Name}\\\"\";\n\n\t\t\tpublic GenericParamEntry(MetadataFile metadataFile, GenericParameterHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.genericParam = metadataFile.Metadata.GetGenericParameter(handle);\n\t\t\t\tthis.ownerTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/CorTables/ImplMapTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Buffers.Binary;\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nusing Mono.Cecil;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tclass ImplMapTableTreeNode : MetadataTableTreeNode<ImplMapTableTreeNode.ImplMapEntry>\n\t{\n\t\tpublic ImplMapTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.ImplMap, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<ImplMapEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<ImplMapEntry>();\n\t\t\tvar metadata = metadataFile.Metadata;\n\t\t\tvar length = metadata.GetTableRowCount(TableIndex.ImplMap);\n\t\t\tvar span = metadata.AsReadOnlySpan();\n\t\t\tint moduleRefSize = metadata.GetTableRowCount(TableIndex.ModuleRef) < ushort.MaxValue ? 2 : 4;\n\t\t\tint memberForwardedTagRefSize = metadata.ComputeCodedTokenSize(32768, TableMask.MethodDef | TableMask.Field);\n\t\t\tint stringHandleSize = metadata.GetHeapSize(HeapIndex.String) < ushort.MaxValue ? 2 : 4;\n\t\t\tfor (int rid = 1; rid <= length; rid++)\n\t\t\t{\n\t\t\t\tlist.Add(new ImplMapEntry(metadataFile, span, rid, moduleRefSize, memberForwardedTagRefSize, stringHandleSize));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\treadonly struct ImplMap\n\t\t{\n\t\t\tpublic readonly PInvokeAttributes MappingFlags;\n\t\t\tpublic readonly EntityHandle MemberForwarded;\n\t\t\tpublic readonly StringHandle ImportName;\n\t\t\tpublic readonly ModuleReferenceHandle ImportScope;\n\n\t\t\tpublic ImplMap(ReadOnlySpan<byte> span, int moduleRefSize, int memberForwardedTagRefSize, int stringHandleSize)\n\t\t\t{\n\t\t\t\tMappingFlags = (PInvokeAttributes)BinaryPrimitives.ReadUInt16LittleEndian(span);\n\t\t\t\tMemberForwarded = Helpers.FromMemberForwardedTag((uint)Helpers.GetValueLittleEndian(span.Slice(2, memberForwardedTagRefSize)));\n\t\t\t\tImportName = MetadataTokens.StringHandle(Helpers.GetValueLittleEndian(span.Slice(2 + memberForwardedTagRefSize, stringHandleSize)));\n\t\t\t\tImportScope = MetadataTokens.ModuleReferenceHandle(Helpers.GetValueLittleEndian(span.Slice(2 + memberForwardedTagRefSize + stringHandleSize, moduleRefSize)));\n\t\t\t}\n\t\t}\n\n\t\tinternal struct ImplMapEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly ImplMap implMap;\n\n\t\t\tpublic int RID { get; }\n\t\t\tpublic int Token => 0x1C000000 | RID;\n\t\t\tpublic int Offset { get; }\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic PInvokeAttributes MappingFlags => implMap.MappingFlags;\n\n\t\t\tconst PInvokeAttributes otherFlagsMask = ~(PInvokeAttributes.CallConvMask | PInvokeAttributes.CharSetMask);\n\n\t\t\tpublic object MappingFlagsTooltip => new FlagsTooltip {\n\t\t\t\tFlagGroup.CreateSingleChoiceGroup(typeof(PInvokeAttributes), \"Character set: \", (int)PInvokeAttributes.CharSetMask, (int)(implMap.MappingFlags & PInvokeAttributes.CharSetMask), new Flag(\"CharSetNotSpec (0000)\", 0, false), includeAny: false),\n\t\t\t\tFlagGroup.CreateSingleChoiceGroup(typeof(PInvokeAttributes), \"Calling convention: \", (int)PInvokeAttributes.CallConvMask, (int)(implMap.MappingFlags & PInvokeAttributes.CallConvMask), new Flag(\"Invalid (0000)\", 0, false), includeAny: false),\n\t\t\t\tFlagGroup.CreateMultipleChoiceGroup(typeof(PInvokeAttributes), \"Flags:\", (int)otherFlagsMask, (int)(implMap.MappingFlags & otherFlagsMask), includeAll: false),\n\t\t\t};\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int MemberForwarded => MetadataTokens.GetToken(implMap.MemberForwarded);\n\n\t\t\tpublic void OnMemberForwardedClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, implMap.MemberForwarded, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring memberForwardedTooltip;\n\t\t\tpublic string MemberForwardedTooltip => GenerateTooltip(ref memberForwardedTooltip, metadataFile, implMap.MemberForwarded);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int ImportScope => MetadataTokens.GetToken(implMap.ImportScope);\n\n\t\t\tpublic void OnImportScopeClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, implMap.ImportScope, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring importScopeTooltip;\n\t\t\tpublic string ImportScopeTooltip => GenerateTooltip(ref importScopeTooltip, metadataFile, implMap.ImportScope);\n\n\t\t\tpublic string ImportName => metadataFile.Metadata.GetString(implMap.ImportName);\n\n\t\t\tpublic string ImportNameTooltip => $\"{MetadataTokens.GetHeapOffset(implMap.ImportName):X} \\\"{ImportName}\\\"\";\n\n\t\t\tpublic ImplMapEntry(MetadataFile metadataFile, ReadOnlySpan<byte> span, int row, int moduleRefSize, int memberForwardedTagRefSize, int stringHandleSize)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.RID = row;\n\t\t\t\tvar rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.ImplMap)\n\t\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.ImplMap) * (row - 1);\n\t\t\t\tthis.Offset = metadataFile.MetadataOffset + rowOffset;\n\t\t\t\tthis.implMap = new ImplMap(span.Slice(rowOffset), moduleRefSize, memberForwardedTagRefSize, stringHandleSize);\n\t\t\t\tthis.importScopeTooltip = null;\n\t\t\t\tthis.memberForwardedTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/InterfaceImplTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class InterfaceImplTableTreeNode : MetadataTableTreeNode<InterfaceImplTableTreeNode.InterfaceImplEntry>\n\t{\n\t\tpublic InterfaceImplTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.InterfaceImpl, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<InterfaceImplEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<InterfaceImplEntry>();\n\t\t\tvar length = metadataFile.Metadata.GetTableRowCount(TableIndex.InterfaceImpl);\n\t\t\tReadOnlySpan<byte> ptr = metadataFile.Metadata.AsReadOnlySpan();\n\t\t\tfor (int rid = 1; rid <= length; rid++)\n\t\t\t{\n\t\t\t\tlist.Add(new InterfaceImplEntry(metadataFile, ptr, rid));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\treadonly struct InterfaceImpl\n\t\t{\n\t\t\tpublic readonly EntityHandle Class;\n\t\t\tpublic readonly EntityHandle Interface;\n\n\t\t\tpublic InterfaceImpl(ReadOnlySpan<byte> ptr, int classSize, int interfaceSize)\n\t\t\t{\n\t\t\t\tClass = MetadataTokens.TypeDefinitionHandle(Helpers.GetValueLittleEndian(ptr, classSize));\n\t\t\t\tInterface = Helpers.FromTypeDefOrRefTag((uint)Helpers.GetValueLittleEndian(ptr.Slice(classSize, interfaceSize)));\n\t\t\t}\n\t\t}\n\n\t\tinternal struct InterfaceImplEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly InterfaceImpl interfaceImpl;\n\n\t\t\tpublic int RID { get; }\n\n\t\t\tpublic int Token => 0x09000000 | RID;\n\n\t\t\tpublic int Offset { get; }\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Class => MetadataTokens.GetToken(interfaceImpl.Class);\n\n\t\t\tpublic void OnClassClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, interfaceImpl.Class, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring classTooltip;\n\t\t\tpublic string ClassTooltip => GenerateTooltip(ref classTooltip, metadataFile, interfaceImpl.Class);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Interface => MetadataTokens.GetToken(interfaceImpl.Interface);\n\n\t\t\tpublic void OnInterfaceClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, interfaceImpl.Interface, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring interfaceTooltip;\n\t\t\tpublic string InterfaceTooltip => GenerateTooltip(ref interfaceTooltip, metadataFile, interfaceImpl.Interface);\n\n\t\t\tpublic InterfaceImplEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.RID = row;\n\t\t\t\tvar rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.InterfaceImpl)\n\t\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.InterfaceImpl) * (row - 1);\n\t\t\t\tthis.Offset = metadataFile.MetadataOffset + rowOffset;\n\t\t\t\tthis.interfaceImpl = new InterfaceImpl(ptr.Slice(rowOffset), metadataFile.Metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4, metadataFile.Metadata.ComputeCodedTokenSize(16384, TableMask.TypeDef | TableMask.TypeRef | TableMask.TypeSpec));\n\t\t\t\tthis.interfaceTooltip = null;\n\t\t\t\tthis.classTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/ManifestResourceTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tclass ManifestResourceTableTreeNode : MetadataTableTreeNode<ManifestResourceTableTreeNode.ManifestResourceEntry>\n\t{\n\t\tpublic ManifestResourceTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.ManifestResource, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<ManifestResourceEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<ManifestResourceEntry>();\n\t\t\tvar metadata = metadataFile.Metadata;\n\t\t\tforeach (var row in metadata.ManifestResources)\n\t\t\t{\n\t\t\t\tlist.Add(new ManifestResourceEntry(metadataFile, row));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct ManifestResourceEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly ManifestResourceHandle handle;\n\t\t\treadonly ManifestResource manifestResource;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.ManifestResource)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.ManifestResource) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic ManifestResourceAttributes Attributes => manifestResource.Attributes;\n\n\t\t\tpublic object AttributesTooltip => manifestResource.Attributes.ToString();\n\n\t\t\tpublic string Name => metadataFile.Metadata.GetString(manifestResource.Name);\n\n\t\t\tpublic string NameTooltip => $\"{MetadataTokens.GetHeapOffset(manifestResource.Name):X} \\\"{Name}\\\"\";\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Implementation => MetadataTokens.GetToken(manifestResource.Implementation);\n\n\t\t\tpublic void OnImplementationClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, manifestResource.Implementation, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring implementationTooltip;\n\t\t\tpublic string ImplementationTooltip => GenerateTooltip(ref implementationTooltip, metadataFile, manifestResource.Implementation);\n\n\t\t\tpublic ManifestResourceEntry(MetadataFile metadataFile, ManifestResourceHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.manifestResource = metadataFile.Metadata.GetManifestResource(handle);\n\t\t\t\tthis.implementationTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/MemberRefTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class MemberRefTableTreeNode : MetadataTableTreeNode<MemberRefTableTreeNode.MemberRefEntry>\n\t{\n\t\tpublic MemberRefTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.MemberRef, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<MemberRefEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<MemberRefEntry>();\n\t\t\tforeach (var row in metadataFile.Metadata.MemberReferences)\n\t\t\t{\n\t\t\t\tlist.Add(new MemberRefEntry(metadataFile, row));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct MemberRefEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly MemberReferenceHandle handle;\n\t\t\treadonly MemberReference memberRef;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.MemberRef)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.MemberRef) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Parent => MetadataTokens.GetToken(memberRef.Parent);\n\n\t\t\tpublic void OnParentClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, memberRef.Parent, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring parentTooltip;\n\t\t\tpublic string ParentTooltip => GenerateTooltip(ref parentTooltip, metadataFile, memberRef.Parent);\n\n\t\t\tpublic string Name => metadataFile.Metadata.GetString(memberRef.Name);\n\n\t\t\tpublic string NameTooltip => $\"{MetadataTokens.GetHeapOffset(memberRef.Name):X} \\\"{Name}\\\"\";\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int Signature => MetadataTokens.GetHeapOffset(memberRef.Signature);\n\n\t\t\tstring signatureTooltip;\n\t\t\tpublic string SignatureTooltip => GenerateTooltip(ref signatureTooltip, metadataFile, handle);\n\n\t\t\tpublic MemberRefEntry(MetadataFile metadataFile, MemberReferenceHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.memberRef = metadataFile.Metadata.GetMemberReference(handle);\n\t\t\t\tthis.signatureTooltip = null;\n\t\t\t\tthis.parentTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/MethodImplTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class MethodImplTableTreeNode : MetadataTableTreeNode<MethodImplTableTreeNode.MethodImplEntry>\n\t{\n\t\tpublic MethodImplTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.MethodImpl, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<MethodImplEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<MethodImplEntry>();\n\t\t\tfor (int row = 1; row <= metadataFile.Metadata.GetTableRowCount(TableIndex.MethodImpl); row++)\n\t\t\t{\n\t\t\t\tlist.Add(new MethodImplEntry(metadataFile, MetadataTokens.MethodImplementationHandle(row)));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct MethodImplEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly MethodImplementationHandle handle;\n\t\t\treadonly MethodImplementation methodImpl;\n\n\t\t\tpublic int RID => MetadataTokens.GetToken(handle) & 0xFFFFFF;\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.MethodDef)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.MethodDef) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int MethodDeclaration => MetadataTokens.GetToken(methodImpl.MethodDeclaration);\n\n\t\t\tpublic void OnMethodDeclarationClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, methodImpl.MethodDeclaration, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring methodDeclarationTooltip;\n\t\t\tpublic string MethodDeclarationTooltip => GenerateTooltip(ref methodDeclarationTooltip, metadataFile, methodImpl.MethodDeclaration);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int MethodBody => MetadataTokens.GetToken(methodImpl.MethodBody);\n\n\t\t\tpublic void OnMethodBodyClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, methodImpl.MethodBody, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring methodBodyTooltip;\n\t\t\tpublic string MethodBodyTooltip => GenerateTooltip(ref methodBodyTooltip, metadataFile, methodImpl.MethodBody);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Type => MetadataTokens.GetToken(methodImpl.Type);\n\n\t\t\tpublic void OnTypeClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, methodImpl.Type, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring typeTooltip;\n\t\t\tpublic string TypeTooltip => GenerateTooltip(ref typeTooltip, metadataFile, methodImpl.Type);\n\n\t\t\tpublic MethodImplEntry(MetadataFile metadataFile, MethodImplementationHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.methodImpl = metadataFile.Metadata.GetMethodImplementation(handle);\n\t\t\t\tthis.typeTooltip = null;\n\t\t\t\tthis.methodBodyTooltip = null;\n\t\t\t\tthis.methodDeclarationTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/MethodSemanticsTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class MethodSemanticsTableTreeNode : MetadataTableTreeNode<MethodSemanticsTableTreeNode.MethodSemanticsEntry>\n\t{\n\t\tpublic MethodSemanticsTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.MethodSemantics, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<MethodSemanticsEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<MethodSemanticsEntry>();\n\t\t\tforeach (var row in metadataFile.Metadata.GetMethodSemantics())\n\t\t\t{\n\t\t\t\tlist.Add(new MethodSemanticsEntry(metadataFile, row.Handle, row.Semantics, row.Method, row.Association));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct MethodSemanticsEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly Handle handle;\n\t\t\treadonly MethodSemanticsAttributes semantics;\n\t\t\treadonly MethodDefinitionHandle method;\n\t\t\treadonly EntityHandle association;\n\n\t\t\tpublic int RID => MetadataTokens.GetToken(handle) & 0xFFFFFF;\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.MethodDef)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.MethodDef) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic MethodSemanticsAttributes Semantics => semantics;\n\n\t\t\tpublic string SemanticsTooltip => semantics.ToString();\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Method => MetadataTokens.GetToken(method);\n\n\t\t\tpublic void OnMethodClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, method, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring methodTooltip;\n\t\t\tpublic string MethodTooltip => GenerateTooltip(ref methodTooltip, metadataFile, method);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Association => MetadataTokens.GetToken(association);\n\n\t\t\tpublic void OnAssociationClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, association, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring associationTooltip;\n\t\t\tpublic string AssociationTooltip => GenerateTooltip(ref associationTooltip, metadataFile, association);\n\n\t\t\tpublic MethodSemanticsEntry(MetadataFile metadataFile, Handle handle, MethodSemanticsAttributes semantics, MethodDefinitionHandle method, EntityHandle association)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.semantics = semantics;\n\t\t\t\tthis.method = method;\n\t\t\t\tthis.association = association;\n\t\t\t\tthis.methodTooltip = null;\n\t\t\t\tthis.associationTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/MethodSpecTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class MethodSpecTableTreeNode : MetadataTableTreeNode<MethodSpecTableTreeNode.MethodSpecEntry>\n\t{\n\t\tpublic MethodSpecTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.MethodSpec, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<MethodSpecEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<MethodSpecEntry>();\n\t\t\tforeach (var row in metadataFile.Metadata.GetMethodSpecifications())\n\t\t\t{\n\t\t\t\tlist.Add(new MethodSpecEntry(metadataFile, row));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct MethodSpecEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly MethodSpecificationHandle handle;\n\t\t\treadonly MethodSpecification methodSpec;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.MethodSpec)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.MethodSpec) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Method => MetadataTokens.GetToken(methodSpec.Method);\n\n\t\t\tpublic void OnMethodClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, methodSpec.Method, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring methodTooltip;\n\t\t\tpublic string MethodTooltip => GenerateTooltip(ref methodTooltip, metadataFile, methodSpec.Method);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int Signature => MetadataTokens.GetHeapOffset(methodSpec.Signature);\n\n\t\t\tpublic string SignatureTooltip {\n\t\t\t\tget {\n\t\t\t\t\tITextOutput output = new PlainTextOutput();\n\t\t\t\t\tvar signature = methodSpec.DecodeSignature(new DisassemblerSignatureTypeProvider(metadataFile, output), default);\n\t\t\t\t\tbool first = true;\n\t\t\t\t\tforeach (var type in signature)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (first)\n\t\t\t\t\t\t\tfirst = false;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\toutput.Write(\", \");\n\t\t\t\t\t\ttype(ILNameSyntax.TypeName);\n\t\t\t\t\t}\n\t\t\t\t\treturn output.ToString();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic MethodSpecEntry(MetadataFile metadataFile, MethodSpecificationHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.methodSpec = metadataFile.Metadata.GetMethodSpecification(handle);\n\t\t\t\tthis.methodTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/CorTables/MethodTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class MethodTableTreeNode : MetadataTableTreeNode<MethodTableTreeNode.MethodDefEntry>\n\t{\n\t\tpublic MethodTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.MethodDef, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<MethodDefEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<MethodDefEntry>();\n\t\t\tforeach (var row in metadataFile.Metadata.MethodDefinitions)\n\t\t\t{\n\t\t\t\tlist.Add(new MethodDefEntry(metadataFile, row));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct MethodDefEntry : IMemberTreeNode\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly MethodDefinitionHandle handle;\n\t\t\treadonly MethodDefinition methodDef;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.MethodDef)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.MethodDef) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic MethodAttributes Attributes => methodDef.Attributes;\n\n\t\t\tconst MethodAttributes otherFlagsMask = ~(MethodAttributes.MemberAccessMask | MethodAttributes.VtableLayoutMask);\n\n\t\t\tpublic object AttributesTooltip => new FlagsTooltip {\n\t\t\t\tFlagGroup.CreateSingleChoiceGroup(typeof(MethodAttributes), \"Member access: \", (int)MethodAttributes.MemberAccessMask, (int)(methodDef.Attributes & MethodAttributes.MemberAccessMask), new Flag(\"CompilerControlled (0000)\", 0, false), includeAny: false),\n\t\t\t\tFlagGroup.CreateSingleChoiceGroup(typeof(MethodAttributes), \"Vtable layout: \", (int)MethodAttributes.VtableLayoutMask, (int)(methodDef.Attributes & MethodAttributes.VtableLayoutMask), new Flag(\"ReuseSlot (0000)\", 0, false), includeAny: false),\n\t\t\t\tFlagGroup.CreateMultipleChoiceGroup(typeof(MethodAttributes), \"Flags:\", (int)otherFlagsMask, (int)(methodDef.Attributes & otherFlagsMask), includeAll: false),\n\t\t\t};\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic MethodImplAttributes ImplAttributes => methodDef.ImplAttributes;\n\n\t\t\tpublic object ImplAttributesTooltip => new FlagsTooltip {\n\t\t\t\tFlagGroup.CreateSingleChoiceGroup(typeof(MethodImplAttributes), \"Code type: \", (int)MethodImplAttributes.CodeTypeMask, (int)(methodDef.ImplAttributes & MethodImplAttributes.CodeTypeMask), new Flag(\"IL (0000)\", 0, false), includeAny: false),\n\t\t\t\tFlagGroup.CreateSingleChoiceGroup(typeof(MethodImplAttributes), \"Managed type: \", (int)MethodImplAttributes.ManagedMask, (int)(methodDef.ImplAttributes & MethodImplAttributes.ManagedMask), new Flag(\"Managed (0000)\", 0, false), includeAny: false),\n\t\t\t};\n\n\t\t\tpublic int RVA => methodDef.RelativeVirtualAddress;\n\n\t\t\tpublic string Name => metadataFile.Metadata.GetString(methodDef.Name);\n\n\t\t\tpublic string NameTooltip => $\"{MetadataTokens.GetHeapOffset(methodDef.Name):X} \\\"{Name}\\\"\";\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int Signature => MetadataTokens.GetHeapOffset(methodDef.Signature);\n\n\t\t\tstring signatureTooltip;\n\n\t\t\tpublic string SignatureTooltip => GenerateTooltip(ref signatureTooltip, metadataFile, handle);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int ParamList => MetadataTokens.GetToken(methodDef.GetParameters().FirstOrDefault());\n\n\t\t\tpublic void OnParamListClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, methodDef.GetParameters().FirstOrDefault(), protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring paramListTooltip;\n\t\t\tpublic string ParamListTooltip {\n\t\t\t\tget {\n\t\t\t\t\tvar param = methodDef.GetParameters().FirstOrDefault();\n\t\t\t\t\tif (param.IsNil)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\treturn GenerateTooltip(ref paramListTooltip, metadataFile, param);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tIEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion)?.MainModule)?.GetDefinition(handle);\n\n\t\t\tpublic MethodDefEntry(MetadataFile metadataFile, MethodDefinitionHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.methodDef = metadataFile.Metadata.GetMethodDefinition(handle);\n\t\t\t\tthis.signatureTooltip = null;\n\t\t\t\tthis.paramListTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/ModuleRefTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class ModuleRefTableTreeNode : MetadataTableTreeNode<ModuleRefTableTreeNode.ModuleRefEntry>\n\t{\n\t\tpublic ModuleRefTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.ModuleRef, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<ModuleRefEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<ModuleRefEntry>();\n\t\t\tforeach (var row in metadataFile.Metadata.GetModuleReferences())\n\t\t\t{\n\t\t\t\tlist.Add(new ModuleRefEntry(metadataFile, row));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct ModuleRefEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly ModuleReferenceHandle handle;\n\t\t\treadonly ModuleReference moduleRef;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.ModuleRef)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.ModuleRef) * (RID - 1);\n\n\t\t\tpublic string Name => metadataFile.Metadata.GetString(moduleRef.Name);\n\n\t\t\tpublic string NameTooltip => $\"{MetadataTokens.GetHeapOffset(moduleRef.Name):X} \\\"{Name}\\\"\";\n\n\t\t\tpublic ModuleRefEntry(MetadataFile metadataFile, ModuleReferenceHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.moduleRef = metadataFile.Metadata.GetModuleReference(handle);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/CorTables/ModuleTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class ModuleTableTreeNode : MetadataTableTreeNode<ModuleTableTreeNode.ModuleEntry>\n\t{\n\t\tpublic ModuleTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.Module, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<ModuleEntry> LoadTable()\n\t\t{\n\t\t\treturn [new ModuleEntry(metadataFile, EntityHandle.ModuleDefinition)];\n\t\t}\n\n\t\tinternal struct ModuleEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly ModuleDefinitionHandle handle;\n\t\t\treadonly ModuleDefinition moduleDef;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.Module)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.Module) * (RID - 1);\n\n\t\t\tpublic int Generation => moduleDef.Generation;\n\n\t\t\tpublic string Name => metadataFile.Metadata.GetString(moduleDef.Name);\n\n\t\t\tpublic string NameTooltip => $\"{MetadataTokens.GetHeapOffset(moduleDef.Name):X} \\\"{Name}\\\"\";\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int Mvid => MetadataTokens.GetHeapOffset(moduleDef.Mvid);\n\n\t\t\tpublic string MvidTooltip => metadataFile.Metadata.GetGuid(moduleDef.Mvid).ToString();\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int GenerationId => MetadataTokens.GetHeapOffset(moduleDef.GenerationId);\n\n\t\t\tpublic string GenerationIdTooltip => moduleDef.GenerationId.IsNil ? null : metadataFile.Metadata.GetGuid(moduleDef.GenerationId).ToString();\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int BaseGenerationId => MetadataTokens.GetHeapOffset(moduleDef.BaseGenerationId);\n\n\t\t\tpublic string BaseGenerationIdTooltip => moduleDef.BaseGenerationId.IsNil ? null : metadataFile.Metadata.GetGuid(moduleDef.BaseGenerationId).ToString();\n\n\t\t\tpublic ModuleEntry(MetadataFile metadataFile, ModuleDefinitionHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.moduleDef = metadataFile.Metadata.GetModuleDefinition();\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/CorTables/NestedClassTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tclass NestedClassTableTreeNode : MetadataTableTreeNode<NestedClassTableTreeNode.NestedClassEntry>\n\t{\n\t\tpublic NestedClassTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.NestedClass, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<NestedClassEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<NestedClassEntry>();\n\t\t\tvar metadata = metadataFile.Metadata;\n\t\t\tvar length = metadata.GetTableRowCount(TableIndex.NestedClass);\n\t\t\tReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();\n\t\t\tint typeDefSize = metadataFile.Metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4;\n\t\t\tfor (int rid = 1; rid <= length; rid++)\n\t\t\t{\n\t\t\t\tlist.Add(new NestedClassEntry(metadataFile, ptr, rid, typeDefSize));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\treadonly struct NestedClass\n\t\t{\n\t\t\tpublic readonly TypeDefinitionHandle Nested;\n\t\t\tpublic readonly TypeDefinitionHandle Enclosing;\n\n\t\t\tpublic NestedClass(ReadOnlySpan<byte> ptr, int typeDefSize)\n\t\t\t{\n\t\t\t\tNested = MetadataTokens.TypeDefinitionHandle(Helpers.GetValueLittleEndian(ptr, typeDefSize));\n\t\t\t\tEnclosing = MetadataTokens.TypeDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(typeDefSize), typeDefSize));\n\t\t\t}\n\t\t}\n\n\t\tinternal struct NestedClassEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly NestedClass nestedClass;\n\n\t\t\tpublic int RID { get; }\n\t\t\tpublic int Token => 0x29000000 | RID;\n\t\t\tpublic int Offset { get; }\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int NestedClass => MetadataTokens.GetToken(nestedClass.Nested);\n\t\t\tpublic void OnNestedClassClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, nestedClass.Nested, protocol: \"metadata\")));\n\t\t\t}\n\t\t\tstring nestedClassTooltip;\n\t\t\tpublic string NestedClassTooltip => GenerateTooltip(ref nestedClassTooltip, metadataFile, nestedClass.Nested);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int EnclosingClass => MetadataTokens.GetToken(nestedClass.Enclosing);\n\t\t\tpublic void OnEnclosingClassClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, nestedClass.Enclosing, protocol: \"metadata\")));\n\t\t\t}\n\t\t\tstring enclosingClassTooltip;\n\t\t\tpublic string EnclosingClassTooltip => GenerateTooltip(ref enclosingClassTooltip, metadataFile, nestedClass.Enclosing);\n\n\t\t\tpublic NestedClassEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row, int typeDefSize)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.RID = row;\n\t\t\t\tvar rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.NestedClass)\n\t\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.NestedClass) * (row - 1);\n\t\t\t\tthis.Offset = metadataFile.MetadataOffset + rowOffset;\n\t\t\t\tthis.nestedClass = new NestedClass(ptr.Slice(rowOffset), typeDefSize);\n\t\t\t\tthis.nestedClassTooltip = null;\n\t\t\t\tthis.enclosingClassTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/ParamTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class ParamTableTreeNode : MetadataTableTreeNode<ParamTableTreeNode.ParamEntry>\n\t{\n\t\tpublic ParamTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.Param, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<ParamEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<ParamEntry>();\n\t\t\tfor (int row = 1; row <= metadataFile.Metadata.GetTableRowCount(TableIndex.Param); row++)\n\t\t\t{\n\t\t\t\tlist.Add(new ParamEntry(metadataFile, MetadataTokens.ParameterHandle(row)));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct ParamEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly ParameterHandle handle;\n\t\t\treadonly Parameter param;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.Param)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.Param) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic ParameterAttributes Attributes => param.Attributes;\n\n\t\t\tpublic object AttributesTooltip => new FlagsTooltip {\n\t\t\t\tFlagGroup.CreateMultipleChoiceGroup(typeof(ParameterAttributes), selectedValue: (int)param.Attributes, includeAll: false)\n\t\t\t};\n\n\t\t\tpublic string Name => metadataFile.Metadata.GetString(param.Name);\n\n\t\t\tpublic string NameTooltip => $\"{MetadataTokens.GetHeapOffset(param.Name):X} \\\"{Name}\\\"\";\n\n\t\t\tpublic int Sequence => param.SequenceNumber;\n\n\t\t\tpublic ParamEntry(MetadataFile metadataFile, ParameterHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.param = metadataFile.Metadata.GetParameter(handle);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tclass PropertyMapTableTreeNode : MetadataTableTreeNode<PropertyMapTableTreeNode.PropertyMapEntry>\n\t{\n\t\tpublic PropertyMapTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.PropertyMap, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<PropertyMapEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<PropertyMapEntry>();\n\t\t\tvar metadata = metadataFile.Metadata;\n\t\t\tvar length = metadata.GetTableRowCount(TableIndex.PropertyMap);\n\t\t\tReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();\n\t\t\tint typeDefSize = metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4;\n\t\t\tint propertyDefSize = metadata.GetTableRowCount(TableIndex.Property) < ushort.MaxValue ? 2 : 4;\n\t\t\tfor (int rid = 1; rid <= length; rid++)\n\t\t\t{\n\t\t\t\tlist.Add(new PropertyMapEntry(metadataFile, ptr, rid, typeDefSize, propertyDefSize));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\treadonly struct PropertyMap\n\t\t{\n\t\t\tpublic readonly TypeDefinitionHandle Parent;\n\t\t\tpublic readonly PropertyDefinitionHandle PropertyList;\n\n\t\t\tpublic PropertyMap(ReadOnlySpan<byte> ptr, int typeDefSize, int propertyDefSize)\n\t\t\t{\n\t\t\t\tParent = MetadataTokens.TypeDefinitionHandle(Helpers.GetValueLittleEndian(ptr, typeDefSize));\n\t\t\t\tPropertyList = MetadataTokens.PropertyDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(typeDefSize, propertyDefSize)));\n\t\t\t}\n\t\t}\n\n\t\tinternal struct PropertyMapEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly PropertyMap propertyMap;\n\n\t\t\tpublic int RID { get; }\n\t\t\tpublic int Token => 0x15000000 | RID;\n\t\t\tpublic int Offset { get; }\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Parent => MetadataTokens.GetToken(propertyMap.Parent);\n\n\t\t\tpublic void OnParentClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, propertyMap.Parent, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring parentTooltip;\n\t\t\tpublic string ParentTooltip => GenerateTooltip(ref parentTooltip, metadataFile, propertyMap.Parent);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int PropertyList => MetadataTokens.GetToken(propertyMap.PropertyList);\n\n\t\t\tpublic void OnPropertyListClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, propertyMap.PropertyList, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring propertyListTooltip;\n\t\t\tpublic string PropertyListTooltip => GenerateTooltip(ref propertyListTooltip, metadataFile, propertyMap.PropertyList);\n\n\t\t\tpublic PropertyMapEntry(MetadataFile metadataFile, ReadOnlySpan<byte> ptr, int row, int typeDefSize, int propertyDefSize)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.RID = row;\n\t\t\t\tvar rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.PropertyMap)\n\t\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.PropertyMap) * (row - 1);\n\t\t\t\tthis.Offset = metadataFile.MetadataOffset + rowOffset;\n\t\t\t\tthis.propertyMap = new PropertyMap(ptr.Slice(rowOffset), typeDefSize, propertyDefSize);\n\t\t\t\tthis.propertyListTooltip = null;\n\t\t\t\tthis.parentTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/PropertyTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class PropertyTableTreeNode : MetadataTableTreeNode<PropertyTableTreeNode.PropertyDefEntry>\n\t{\n\t\tpublic PropertyTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.Property, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<PropertyDefEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<PropertyDefEntry>();\n\n\t\t\tforeach (var row in metadataFile.Metadata.PropertyDefinitions)\n\t\t\t{\n\t\t\t\tlist.Add(new PropertyDefEntry(metadataFile, row));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct PropertyDefEntry : IMemberTreeNode\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly PropertyDefinitionHandle handle;\n\t\t\treadonly PropertyDefinition propertyDef;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.Property)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.Property) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic PropertyAttributes Attributes => propertyDef.Attributes;\n\n\t\t\tpublic object AttributesTooltip => new FlagsTooltip {\n\t\t\t\tFlagGroup.CreateMultipleChoiceGroup(typeof(PropertyAttributes), selectedValue: (int)propertyDef.Attributes, includeAll: false),\n\t\t\t};\n\n\t\t\tpublic string Name => metadataFile.Metadata.GetString(propertyDef.Name);\n\n\t\t\tpublic string NameTooltip => $\"{MetadataTokens.GetHeapOffset(propertyDef.Name):X} \\\"{Name}\\\"\";\n\n\t\t\tIEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion)?.MainModule)?.GetDefinition(handle);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int Signature => MetadataTokens.GetHeapOffset(propertyDef.Signature);\n\n\t\t\tstring signatureTooltip;\n\t\t\tpublic string SignatureTooltip => GenerateTooltip(ref signatureTooltip, metadataFile, handle);\n\n\t\t\tpublic PropertyDefEntry(MetadataFile metadataFile, PropertyDefinitionHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.propertyDef = metadataFile.Metadata.GetPropertyDefinition(handle);\n\t\t\t\tthis.signatureTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/PtrTableTreeNode.cs",
    "content": "// Copyright (c) 2024 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tclass PtrTableTreeNode : MetadataTableTreeNode<PtrTableTreeNode.PtrEntry>\n\t{\n\t\treadonly TableIndex referencedTableKind;\n\n\t\tpublic PtrTableTreeNode(TableIndex kind, MetadataFile metadataFile)\n\t\t\t: base(kind, metadataFile)\n\t\t{\n\t\t\tif (kind is not (TableIndex.EventPtr or TableIndex.FieldPtr or TableIndex.MethodPtr or TableIndex.ParamPtr or TableIndex.PropertyPtr))\n\t\t\t{\n\t\t\t\tthrow new ArgumentOutOfRangeException(\"PtrTable does not support \" + kind);\n\t\t\t}\n\n\t\t\tthis.referencedTableKind = kind switch {\n\t\t\t\tTableIndex.EventPtr => TableIndex.Event,\n\t\t\t\tTableIndex.FieldPtr => TableIndex.Field,\n\t\t\t\tTableIndex.MethodPtr => TableIndex.MethodDef,\n\t\t\t\tTableIndex.ParamPtr => TableIndex.Param,\n\t\t\t\tTableIndex.PropertyPtr => TableIndex.Property,\n\t\t\t\t_ => throw new NotImplementedException(), // unreachable\n\t\t\t};\n\t\t}\n\n\t\tprotected override IReadOnlyList<PtrEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<PtrEntry>();\n\n\t\t\tvar metadata = metadataFile.Metadata;\n\t\t\tvar length = metadata.GetTableRowCount(Kind);\n\t\t\tReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();\n\n\t\t\tint handleDefSize = metadataFile.Metadata.GetTableRowCount(referencedTableKind) < ushort.MaxValue ? 2 : 4;\n\n\t\t\tfor (int rid = 1; rid <= length; rid++)\n\t\t\t{\n\t\t\t\tlist.Add(new PtrEntry(metadataFile, Kind, referencedTableKind, handleDefSize, ptr, rid));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\treadonly struct HandlePtr\n\t\t{\n\t\t\tpublic readonly EntityHandle Handle;\n\n\t\t\tpublic HandlePtr(ReadOnlySpan<byte> ptr, TableIndex kind, int handleSize)\n\t\t\t{\n\t\t\t\tHandle = MetadataTokens.EntityHandle(((int)kind << 24) | Helpers.GetValueLittleEndian(ptr, handleSize));\n\t\t\t}\n\t\t}\n\n\t\tinternal struct PtrEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly HandlePtr handlePtr;\n\t\t\treadonly TableIndex kind;\n\n\t\t\tpublic int RID { get; }\n\n\t\t\tpublic int Token => ((int)kind << 24) | RID;\n\n\t\t\tpublic int Offset { get; }\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Handle => MetadataTokens.GetToken(handlePtr.Handle);\n\n\t\t\tpublic void OnHandleClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, handlePtr.Handle, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring handleTooltip;\n\t\t\tpublic string HandleTooltip => GenerateTooltip(ref handleTooltip, metadataFile, handlePtr.Handle);\n\n\t\t\tpublic PtrEntry(MetadataFile metadataFile, TableIndex kind, TableIndex handleKind, int handleDefSize, ReadOnlySpan<byte> ptr, int row)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.RID = row;\n\t\t\t\tthis.kind = kind;\n\t\t\t\tvar rowOffset = metadataFile.Metadata.GetTableMetadataOffset(kind)\n\t\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(kind) * (row - 1);\n\t\t\t\tthis.Offset = metadataFile.MetadataOffset + rowOffset;\n\n\t\t\t\tthis.handlePtr = new HandlePtr(ptr.Slice(rowOffset), handleKind, handleDefSize);\n\t\t\t\tthis.handleTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/StandAloneSigTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tclass StandAloneSigTableTreeNode : MetadataTableTreeNode<StandAloneSigTableTreeNode.StandAloneSigEntry>\n\t{\n\t\tpublic StandAloneSigTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.StandAloneSig, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<StandAloneSigEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<StandAloneSigEntry>();\n\t\t\tfor (int row = 1; row <= metadataFile.Metadata.GetTableRowCount(TableIndex.StandAloneSig); row++)\n\t\t\t{\n\t\t\t\tlist.Add(new StandAloneSigEntry(metadataFile, MetadataTokens.StandaloneSignatureHandle(row)));\n\t\t\t}\n\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct StandAloneSigEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly StandaloneSignatureHandle handle;\n\t\t\treadonly StandaloneSignature standaloneSig;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.StandAloneSig)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.StandAloneSig) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int Signature => MetadataTokens.GetHeapOffset(standaloneSig.Signature);\n\n\t\t\tstring signatureTooltip;\n\t\t\tpublic string SignatureTooltip => GenerateTooltip(ref signatureTooltip, metadataFile, handle);\n\n\t\t\tpublic StandAloneSigEntry(MetadataFile metadataFile, StandaloneSignatureHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.standaloneSig = metadataFile.Metadata.GetStandaloneSignature(handle);\n\t\t\t\tthis.signatureTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/CorTables/TypeDefTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class TypeDefTableTreeNode : MetadataTableTreeNode<TypeDefTableTreeNode.TypeDefEntry>\n\t{\n\t\tpublic TypeDefTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.TypeDef, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<TypeDefEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<TypeDefEntry>();\n\t\t\tforeach (var row in metadataFile.Metadata.TypeDefinitions)\n\t\t\t{\n\t\t\t\tlist.Add(new TypeDefEntry(metadataFile, row));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct TypeDefEntry : IMemberTreeNode\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly TypeDefinitionHandle handle;\n\t\t\treadonly TypeDefinition typeDef;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.TypeDef)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.TypeDef) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic TypeAttributes Attributes => typeDef.Attributes;\n\n\t\t\tconst TypeAttributes otherFlagsMask = ~(TypeAttributes.VisibilityMask | TypeAttributes.LayoutMask | TypeAttributes.ClassSemanticsMask | TypeAttributes.StringFormatMask | TypeAttributes.CustomFormatMask);\n\n\t\t\tpublic object AttributesTooltip => new FlagsTooltip {\n\t\t\t\tFlagGroup.CreateSingleChoiceGroup(typeof(TypeAttributes), \"Visibility: \", (int)TypeAttributes.VisibilityMask, (int)(typeDef.Attributes & TypeAttributes.VisibilityMask), new Flag(\"NotPublic (0000)\", 0, false), includeAny: false),\n\t\t\t\tFlagGroup.CreateSingleChoiceGroup(typeof(TypeAttributes), \"Class layout: \", (int)TypeAttributes.LayoutMask, (int)(typeDef.Attributes & TypeAttributes.LayoutMask), new Flag(\"AutoLayout (0000)\", 0, false), includeAny: false),\n\t\t\t\tFlagGroup.CreateSingleChoiceGroup(typeof(TypeAttributes), \"Class semantics: \", (int)TypeAttributes.ClassSemanticsMask, (int)(typeDef.Attributes & TypeAttributes.ClassSemanticsMask), new Flag(\"Class (0000)\", 0, false), includeAny: false),\n\t\t\t\tFlagGroup.CreateSingleChoiceGroup(typeof(TypeAttributes), \"String format: \", (int)TypeAttributes.StringFormatMask, (int)(typeDef.Attributes & TypeAttributes.StringFormatMask), new Flag(\"AnsiClass (0000)\", 0, false), includeAny: false),\n\t\t\t\tFlagGroup.CreateSingleChoiceGroup(typeof(TypeAttributes), \"Custom format: \", (int)TypeAttributes.CustomFormatMask, (int)(typeDef.Attributes & TypeAttributes.CustomFormatMask), new Flag(\"Value0 (0000)\", 0, false), includeAny: false),\n\t\t\t\tFlagGroup.CreateMultipleChoiceGroup(typeof(TypeAttributes), \"Flags:\", (int)otherFlagsMask, (int)(typeDef.Attributes & otherFlagsMask), includeAll: false),\n\t\t\t};\n\n\t\t\tpublic string NameTooltip => $\"{MetadataTokens.GetHeapOffset(typeDef.Name):X} \\\"{Name}\\\"\";\n\n\t\t\tpublic string Name => metadataFile.Metadata.GetString(typeDef.Name);\n\n\t\t\tpublic string NamespaceTooltip => $\"{MetadataTokens.GetHeapOffset(typeDef.Namespace):X} \\\"{Namespace}\\\"\";\n\n\t\t\tpublic string Namespace => metadataFile.Metadata.GetString(typeDef.Namespace);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int BaseType => MetadataTokens.GetToken(typeDef.BaseType);\n\n\t\t\tpublic void OnBaseTypeClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, typeDef.BaseType, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tpublic string BaseTypeTooltip {\n\t\t\t\tget {\n\t\t\t\t\tvar output = new PlainTextOutput();\n\t\t\t\t\tvar provider = new DisassemblerSignatureTypeProvider(metadataFile, output);\n\t\t\t\t\tif (typeDef.BaseType.IsNil)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tswitch (typeDef.BaseType.Kind)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase HandleKind.TypeDefinition:\n\t\t\t\t\t\t\tprovider.GetTypeFromDefinition(metadataFile.Metadata, (TypeDefinitionHandle)typeDef.BaseType, 0)(ILNameSyntax.Signature);\n\t\t\t\t\t\t\treturn output.ToString();\n\t\t\t\t\t\tcase HandleKind.TypeReference:\n\t\t\t\t\t\t\tprovider.GetTypeFromReference(metadataFile.Metadata, (TypeReferenceHandle)typeDef.BaseType, 0)(ILNameSyntax.Signature);\n\t\t\t\t\t\t\treturn output.ToString();\n\t\t\t\t\t\tcase HandleKind.TypeSpecification:\n\t\t\t\t\t\t\tprovider.GetTypeFromSpecification(metadataFile.Metadata, new Decompiler.Metadata.MetadataGenericContext(default(TypeDefinitionHandle), metadataFile.Metadata), (TypeSpecificationHandle)typeDef.BaseType, 0)(ILNameSyntax.Signature);\n\t\t\t\t\t\t\treturn output.ToString();\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int FieldList => MetadataTokens.GetToken(typeDef.GetFields().FirstOrDefault());\n\n\t\t\tpublic void OnFieldListClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, typeDef.GetFields().FirstOrDefault(), protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring fieldListTooltip;\n\t\t\tpublic string FieldListTooltip {\n\t\t\t\tget {\n\t\t\t\t\tvar @field = typeDef.GetFields().FirstOrDefault();\n\t\t\t\t\tif (@field.IsNil)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\treturn GenerateTooltip(ref fieldListTooltip, metadataFile, @field);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int MethodList => MetadataTokens.GetToken(typeDef.GetMethods().FirstOrDefault());\n\n\t\t\tpublic void OnMethodListClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, typeDef.GetMethods().FirstOrDefault(), protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring methodListTooltip;\n\t\t\tpublic string MethodListTooltip {\n\t\t\t\tget {\n\t\t\t\t\tvar method = typeDef.GetMethods().FirstOrDefault();\n\t\t\t\t\tif (method.IsNil)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\treturn GenerateTooltip(ref methodListTooltip, metadataFile, method);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tIEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion)?.MainModule)?.GetDefinition(handle);\n\n\t\t\tpublic TypeDefEntry(MetadataFile metadataFile, TypeDefinitionHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.typeDef = metadataFile.Metadata.GetTypeDefinition(handle);\n\t\t\t\tthis.methodListTooltip = null;\n\t\t\t\tthis.fieldListTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/CorTables/TypeRefTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class TypeRefTableTreeNode : MetadataTableTreeNode<TypeRefTableTreeNode.TypeRefEntry>\n\t{\n\t\tpublic TypeRefTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.TypeRef, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<TypeRefEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<TypeRefEntry>();\n\t\t\tforeach (var row in metadataFile.Metadata.TypeReferences)\n\t\t\t{\n\t\t\t\tlist.Add(new TypeRefEntry(metadataFile, row));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct TypeRefEntry\n\t\t{\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly TypeReferenceHandle handle;\n\t\t\treadonly TypeReference typeRef;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataFile.MetadataOffset\n\t\t\t\t+ metadataFile.Metadata.GetTableMetadataOffset(TableIndex.TypeRef)\n\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.TypeRef) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int ResolutionScope => MetadataTokens.GetToken(typeRef.ResolutionScope);\n\n\t\t\tpublic void OnResolutionScopeClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, typeRef.ResolutionScope, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring resolutionScopeTooltip;\n\t\t\tpublic string ResolutionScopeTooltip => GenerateTooltip(ref resolutionScopeTooltip, metadataFile, typeRef.ResolutionScope);\n\n\t\t\tpublic string NameTooltip => $\"{MetadataTokens.GetHeapOffset(typeRef.Name):X} \\\"{Name}\\\"\";\n\n\t\t\tpublic string Name => metadataFile.Metadata.GetString(typeRef.Name);\n\n\t\t\tpublic string NamespaceTooltip => $\"{MetadataTokens.GetHeapOffset(typeRef.Namespace):X} \\\"{Namespace}\\\"\";\n\n\t\t\tpublic string Namespace => metadataFile.Metadata.GetString(typeRef.Namespace);\n\n\t\t\tpublic TypeRefEntry(MetadataFile metadataFile, TypeReferenceHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.typeRef = metadataFile.Metadata.GetTypeReference(handle);\n\t\t\t\tthis.resolutionScopeTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/CorTables/TypeSpecTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class TypeSpecTableTreeNode : MetadataTableTreeNode<TypeSpecTableTreeNode.TypeSpecEntry>\n\t{\n\t\tpublic TypeSpecTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.TypeSpec, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<TypeSpecEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<TypeSpecEntry>();\n\t\t\tforeach (var row in metadataFile.Metadata.GetTypeSpecifications())\n\t\t\t{\n\t\t\t\tlist.Add(new TypeSpecEntry(metadataFile, row));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct TypeSpecEntry\n\t\t{\n\t\t\treadonly int metadataOffset;\n\t\t\treadonly MetadataFile module;\n\t\t\treadonly MetadataReader metadata;\n\t\t\treadonly TypeSpecificationHandle handle;\n\t\t\treadonly TypeSpecification typeSpec;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic int Offset => metadataOffset\n\t\t\t\t+ metadata.GetTableMetadataOffset(TableIndex.TypeSpec)\n\t\t\t\t+ metadata.GetTableRowSize(TableIndex.TypeSpec) * (RID - 1);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int Signature => MetadataTokens.GetHeapOffset(typeSpec.Signature);\n\n\t\t\tpublic string SignatureTooltip {\n\t\t\t\tget {\n\t\t\t\t\tITextOutput output = new PlainTextOutput();\n\t\t\t\t\ttypeSpec.DecodeSignature(new DisassemblerSignatureTypeProvider(module, output), default)(ILNameSyntax.Signature);\n\t\t\t\t\treturn output.ToString();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic TypeSpecEntry(MetadataFile metadataFile, TypeSpecificationHandle handle)\n\t\t\t{\n\t\t\t\tthis.module = metadataFile;\n\t\t\t\tthis.metadataOffset = metadataFile.MetadataOffset;\n\t\t\t\tthis.metadata = metadataFile.Metadata;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.typeSpec = metadata.GetTypeSpecification(handle);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/DataDirectoriesTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Reflection.PortableExecutable;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tclass DataDirectoriesTreeNode : ILSpyTreeNode\n\t{\n\t\tprivate PEFile module;\n\n\t\tpublic DataDirectoriesTreeNode(PEFile module)\n\t\t{\n\t\t\tthis.module = module;\n\t\t}\n\n\t\tpublic override object Text => \"Data Directories\";\n\n\t\tpublic override object NavigationText => $\"{Text} ({module.Name})\";\n\n\t\tpublic override object Icon => Images.ListFolder;\n\t\tpublic override object ExpandedIcon => Images.ListFolderOpen;\n\n\t\tpublic override bool View(ViewModels.TabPageModel tabPage)\n\t\t{\n\t\t\ttabPage.Title = Text.ToString();\n\t\t\ttabPage.SupportsLanguageSwitching = false;\n\n\t\t\tvar dataGrid = Helpers.PrepareDataGrid(tabPage, this);\n\t\t\t//dataGrid.AutoGenerateColumns = false;\n\t\t\t//dataGrid.Columns.Add(new DataGridTextColumn { IsReadOnly = true, Header = \"Name\", Binding = new Binding(\"Name\") });\n\t\t\t//dataGrid.Columns.Add(new DataGridTextColumn { IsReadOnly = true, Header = \"RVA\", Binding = new Binding(\"RVA\") { StringFormat = \"X8\" } });\n\t\t\t//dataGrid.Columns.Add(new DataGridTextColumn { IsReadOnly = true, Header = \"Size\", Binding = new Binding(\"Size\") { StringFormat = \"X8\" } });\n\t\t\t//dataGrid.Columns.Add(new DataGridTextColumn { IsReadOnly = true, Header = \"Section\", Binding = new Binding(\"Section\") });\n\t\t\tvar headers = module.Reader.PEHeaders;\n\t\t\tvar header = headers.PEHeader;\n\n\t\t\tvar entries = new DataDirectoryEntry[] {\n\t\t\t\tnew DataDirectoryEntry(headers, \"Export Table\", header.ExportTableDirectory),\n\t\t\t\tnew DataDirectoryEntry(headers, \"Import Table\", header.ImportTableDirectory),\n\t\t\t\tnew DataDirectoryEntry(headers, \"Resource Table\", header.ResourceTableDirectory),\n\t\t\t\tnew DataDirectoryEntry(headers, \"Exception Table\", header.ExceptionTableDirectory),\n\t\t\t\tnew DataDirectoryEntry(headers, \"Certificate Table\", header.CertificateTableDirectory),\n\t\t\t\tnew DataDirectoryEntry(headers, \"Base Relocation Table\", header.BaseRelocationTableDirectory),\n\t\t\t\tnew DataDirectoryEntry(headers, \"Debug Table\", header.DebugTableDirectory),\n\t\t\t\tnew DataDirectoryEntry(headers, \"Copyright Table\", header.CopyrightTableDirectory),\n\t\t\t\tnew DataDirectoryEntry(headers, \"Global Pointer Table\", header.GlobalPointerTableDirectory),\n\t\t\t\tnew DataDirectoryEntry(headers, \"Thread Local Storage Table\", header.ThreadLocalStorageTableDirectory),\n\t\t\t\tnew DataDirectoryEntry(headers, \"Load Config\", header.LoadConfigTableDirectory),\n\t\t\t\tnew DataDirectoryEntry(headers, \"Bound Import\", header.BoundImportTableDirectory),\n\t\t\t\tnew DataDirectoryEntry(headers, \"Import Address Table\", header.ImportAddressTableDirectory),\n\t\t\t\tnew DataDirectoryEntry(headers, \"Delay Import Descriptor\", header.DelayImportTableDirectory),\n\t\t\t\tnew DataDirectoryEntry(headers, \"CLI Header\", header.CorHeaderTableDirectory),\n\t\t\t};\n\n\t\t\tdataGrid.ItemsSource = entries;\n\n\t\t\ttabPage.Content = dataGrid;\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t}\n\n\t\tclass DataDirectoryEntry\n\t\t{\n\t\t\tpublic string Name { get; set; }\n\t\t\tpublic int RVA { get; set; }\n\t\t\tpublic int Size { get; set; }\n\t\t\tpublic string Section { get; set; }\n\n\t\t\tpublic DataDirectoryEntry(string name, int rva, int size, string section)\n\t\t\t{\n\t\t\t\tthis.Name = name;\n\t\t\t\tthis.RVA = rva;\n\t\t\t\tthis.Size = size;\n\t\t\t\tthis.Section = section;\n\t\t\t}\n\n\t\t\tpublic DataDirectoryEntry(PEHeaders headers, string name, DirectoryEntry entry)\n\t\t\t\t: this(name, entry.RelativeVirtualAddress, entry.Size, (headers.GetContainingSectionIndex(entry.RelativeVirtualAddress) >= 0) ? headers.SectionHeaders[headers.GetContainingSectionIndex(entry.RelativeVirtualAddress)].Name : \"\")\n\t\t\t{\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/DebugDirectory/CodeViewTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Reflection.PortableExecutable;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.ViewModels;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tsealed class CodeViewTreeNode : ILSpyTreeNode\n\t{\n\t\treadonly CodeViewDebugDirectoryData entry;\n\t\tpublic CodeViewTreeNode(CodeViewDebugDirectoryData entry)\n\t\t{\n\t\t\tthis.entry = entry;\n\t\t}\n\n\t\toverride public object Text => nameof(DebugDirectoryEntryType.CodeView);\n\n\t\tpublic override object ToolTip => \"Associated PDB file description.\";\n\n\t\tpublic override object Icon => Images.MetadataTable;\n\n\t\tpublic override bool View(TabPageModel tabPage)\n\t\t{\n\t\t\ttabPage.Title = Text.ToString();\n\t\t\ttabPage.SupportsLanguageSwitching = false;\n\n\t\t\tvar dataGrid = Helpers.PrepareDataGrid(tabPage, this);\n\n\t\t\tdataGrid.ItemsSource = new[] { entry };\n\n\t\t\ttabPage.Content = dataGrid;\n\n\t\t\treturn true;\n\t\t}\n\n\t\tsealed class PdbChecksumDebugDirectoryDataEntry\n\t\t{\n\t\t\treadonly CodeViewDebugDirectoryData entry;\n\t\t\tpublic PdbChecksumDebugDirectoryDataEntry(CodeViewDebugDirectoryData entry)\n\t\t\t{\n\t\t\t\tthis.entry = entry;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.WriteCommentLine(output, Text.ToString());\n\t\t\tlanguage.WriteCommentLine(output, $\"GUID: {entry.Guid}\");\n\t\t\tlanguage.WriteCommentLine(output, $\"Age: {entry.Age}\");\n\t\t\tlanguage.WriteCommentLine(output, $\"Path: {entry.Path}\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/DebugDirectory/DebugDirectoryEntryTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Reflection.PortableExecutable;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tsealed class DebugDirectoryEntryTreeNode : ILSpyTreeNode\n\t{\n\t\treadonly PEFile module;\n\t\treadonly PEReader reader;\n\t\treadonly DebugDirectoryEntry entry;\n\t\tpublic DebugDirectoryEntryTreeNode(PEFile module, DebugDirectoryEntry entry)\n\t\t{\n\t\t\tthis.module = module;\n\t\t\tthis.reader = module.Reader;\n\t\t\tthis.entry = entry;\n\t\t}\n\n\t\toverride public object Text => entry.Type.ToString();\n\n\t\tpublic override object NavigationText => $\"{Text} ({module.Name})\";\n\n\t\tpublic override object Icon => Images.MetadataTable;\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.WriteCommentLine(output, Text.ToString());\n\t\t\tif (entry.DataSize > 0)\n\t\t\t{\n\t\t\t\tlanguage.WriteCommentLine(output, $\"Raw Data ({entry.DataSize}):\");\n\t\t\t\tint dataOffset = module.Reader.IsLoadedImage ? entry.DataRelativeVirtualAddress : entry.DataPointer;\n\t\t\t\tvar data = module.Reader.GetEntireImage().GetContent(dataOffset, entry.DataSize);\n\t\t\t\tlanguage.WriteCommentLine(output, data.ToHexString(data.Length));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tlanguage.WriteCommentLine(output, $\"(no data)\");\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/DebugDirectory/PdbChecksumTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System.Reflection.PortableExecutable;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.ViewModels;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tsealed class PdbChecksumTreeNode : ILSpyTreeNode\n\t{\n\t\treadonly PdbChecksumDebugDirectoryData entry;\n\t\tpublic PdbChecksumTreeNode(PdbChecksumDebugDirectoryData entry)\n\t\t{\n\t\t\tthis.entry = entry;\n\t\t}\n\n\t\toverride public object Text => nameof(DebugDirectoryEntryType.PdbChecksum);\n\n\t\tpublic override object ToolTip\n\t\t\t=> \"The entry stores a crypto hash of the content of the symbol file the PE/COFF\\n\"\n\t\t\t + \"file was built with. The hash can be used to validate that a given PDB file was\\n\"\n\t\t\t + \"built with the PE/COFF file and not altered in any way. More than one entry can\\n\"\n\t\t\t + \"be present if multiple PDBs were produced during the build of the PE/COFF file\\n\"\n\t\t\t + \"(for example, private and public symbols).\";\n\n\t\tpublic override object Icon => Images.MetadataTable;\n\n\t\tpublic override bool View(TabPageModel tabPage)\n\t\t{\n\t\t\ttabPage.Title = Text.ToString();\n\t\t\ttabPage.SupportsLanguageSwitching = false;\n\n\t\t\tvar dataGrid = Helpers.PrepareDataGrid(tabPage, this);\n\n\t\t\tdataGrid.ItemsSource = new[] { new PdbChecksumDebugDirectoryDataEntry(entry) };\n\n\t\t\ttabPage.Content = dataGrid;\n\n\t\t\treturn true;\n\t\t}\n\n\t\tsealed class PdbChecksumDebugDirectoryDataEntry\n\t\t{\n\t\t\treadonly PdbChecksumDebugDirectoryData entry;\n\t\t\tpublic PdbChecksumDebugDirectoryDataEntry(PdbChecksumDebugDirectoryData entry)\n\t\t\t{\n\t\t\t\tthis.entry = entry;\n\t\t\t}\n\n\t\t\tpublic string AlgorithmName => entry.AlgorithmName;\n\n\t\t\tpublic string Checksum => entry.Checksum.ToHexString(entry.Checksum.Length);\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.WriteCommentLine(output, Text.ToString());\n\t\t\tlanguage.WriteCommentLine(output, $\"AlgorithmName: {entry.AlgorithmName}\");\n\t\t\tlanguage.WriteCommentLine(output, $\"Checksum: {entry.Checksum.ToHexString(entry.Checksum.Length)}\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/DebugDirectoryTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection.PortableExecutable;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tclass DebugDirectoryTreeNode : ILSpyTreeNode\n\t{\n\t\tprivate PEFile module;\n\n\t\tpublic DebugDirectoryTreeNode(PEFile module)\n\t\t{\n\t\t\tthis.module = module;\n\t\t\tthis.LazyLoading = true;\n\t\t}\n\n\t\tpublic override object Text => \"Debug Directory\";\n\n\t\tpublic override object NavigationText => $\"{Text} ({module.Name})\";\n\n\t\tpublic override object Icon => Images.ListFolder;\n\t\tpublic override object ExpandedIcon => Images.ListFolderOpen;\n\n\t\tpublic override bool View(ViewModels.TabPageModel tabPage)\n\t\t{\n\t\t\ttabPage.Title = Text.ToString();\n\t\t\ttabPage.SupportsLanguageSwitching = false;\n\n\t\t\tvar dataGrid = Helpers.PrepareDataGrid(tabPage, this);\n\t\t\tvar entries = new List<DebugDirectoryEntryView>();\n\t\t\tforeach (var entry in module.Reader.ReadDebugDirectory())\n\t\t\t{\n\t\t\t\tint dataOffset = module.Reader.IsLoadedImage ? entry.DataRelativeVirtualAddress : entry.DataPointer;\n\t\t\t\tvar data = module.Reader.GetEntireImage().GetContent(dataOffset, entry.DataSize);\n\n\t\t\t\tentries.Add(new DebugDirectoryEntryView(entry, data.ToHexString(data.Length)));\n\t\t\t}\n\n\t\t\tdataGrid.ItemsSource = entries.ToArray();\n\n\t\t\ttabPage.Content = dataGrid;\n\t\t\treturn true;\n\t\t}\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tforeach (var entry in module.Reader.ReadDebugDirectory())\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tswitch (entry.Type)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase DebugDirectoryEntryType.CodeView:\n\t\t\t\t\t\t\tvar codeViewData = module.Reader.ReadCodeViewDebugDirectoryData(entry);\n\t\t\t\t\t\t\tthis.Children.Add(new CodeViewTreeNode(codeViewData));\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase DebugDirectoryEntryType.EmbeddedPortablePdb:\n\t\t\t\t\t\t\tvar embeddedPortablePdbProvider = module.Reader.ReadEmbeddedPortablePdbDebugDirectoryData(entry);\n\t\t\t\t\t\t\tvar embeddedPortablePdbMetadataFile = new MetadataFile(MetadataFile.MetadataFileKind.ProgramDebugDatabase, module.FileName, embeddedPortablePdbProvider, isEmbedded: true);\n\t\t\t\t\t\t\tthis.Children.Add(new MetadataTreeNode(embeddedPortablePdbMetadataFile, \"Debug Metadata (Embedded)\"));\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase DebugDirectoryEntryType.PdbChecksum:\n\t\t\t\t\t\t\tvar pdbChecksumData = module.Reader.ReadPdbChecksumDebugDirectoryData(entry);\n\t\t\t\t\t\t\tthis.Children.Add(new PdbChecksumTreeNode(pdbChecksumData));\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase DebugDirectoryEntryType.Unknown:\n\t\t\t\t\t\tcase DebugDirectoryEntryType.Coff:\n\t\t\t\t\t\tcase DebugDirectoryEntryType.Reproducible:\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthis.Children.Add(new DebugDirectoryEntryTreeNode(module, entry));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException ex)\n\t\t\t\t{\n\t\t\t\t\tthis.Children.Add(new ErrorTreeNode(ex));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.WriteCommentLine(output, \"Data Directories\");\n\t\t}\n\n\t\tclass DebugDirectoryEntryView\n\t\t{\n\t\t\tpublic uint Timestamp { get; set; }\n\t\t\tpublic ushort MajorVersion { get; set; }\n\t\t\tpublic ushort MinorVersion { get; set; }\n\t\t\tpublic string Type { get; set; }\n\t\t\tpublic int SizeOfRawData { get; set; }\n\t\t\t[ColumnInfo(\"X8\")]\n\t\t\tpublic int AddressOfRawData { get; set; }\n\t\t\t[ColumnInfo(\"X8\")]\n\t\t\tpublic int PointerToRawData { get; set; }\n\t\t\tpublic string RawData { get; set; }\n\n\t\t\tpublic DebugDirectoryEntryView(DebugDirectoryEntry entry, string data)\n\t\t\t{\n\t\t\t\tthis.RawData = data;\n\t\t\t\tthis.Timestamp = entry.Stamp;\n\t\t\t\tthis.MajorVersion = entry.MajorVersion;\n\t\t\t\tthis.MinorVersion = entry.MinorVersion;\n\t\t\t\tthis.Type = entry.Type.ToString();\n\t\t\t\tthis.SizeOfRawData = entry.DataSize;\n\t\t\t\tthis.AddressOfRawData = entry.DataRelativeVirtualAddress;\n\t\t\t\tthis.PointerToRawData = entry.DataPointer;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/DebugMetadataTablesTreeNode.cs",
    "content": "// Copyright (c) 2021 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.ViewModels;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tclass DebugMetadataTablesTreeNode : ILSpyTreeNode\n\t{\n\t\tprivate MetadataFile metadataFile;\n\n\t\tpublic DebugMetadataTablesTreeNode(MetadataFile metadataFile)\n\t\t{\n\t\t\tthis.metadataFile = metadataFile;\n\t\t\tthis.LazyLoading = true;\n\t\t}\n\n\t\tpublic override object Text => \"Tables\";\n\n\t\tpublic override object NavigationText => $\"{Text} ({metadataFile.Name})\";\n\n\t\tpublic override object Icon => Images.MetadataTableGroup;\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tif (ShowTable(TableIndex.Document))\n\t\t\t\tthis.Children.Add(new DocumentTableTreeNode(metadataFile));\n\t\t\tif (ShowTable(TableIndex.MethodDebugInformation))\n\t\t\t\tthis.Children.Add(new MethodDebugInformationTableTreeNode(metadataFile));\n\t\t\tif (ShowTable(TableIndex.LocalScope))\n\t\t\t\tthis.Children.Add(new LocalScopeTableTreeNode(metadataFile));\n\t\t\tif (ShowTable(TableIndex.LocalVariable))\n\t\t\t\tthis.Children.Add(new LocalVariableTableTreeNode(metadataFile));\n\t\t\tif (ShowTable(TableIndex.LocalConstant))\n\t\t\t\tthis.Children.Add(new LocalConstantTableTreeNode(metadataFile));\n\t\t\tif (ShowTable(TableIndex.ImportScope))\n\t\t\t\tthis.Children.Add(new ImportScopeTableTreeNode(metadataFile));\n\t\t\tif (ShowTable(TableIndex.StateMachineMethod))\n\t\t\t\tthis.Children.Add(new StateMachineMethodTableTreeNode(metadataFile));\n\t\t\tif (ShowTable(TableIndex.CustomDebugInformation))\n\t\t\t\tthis.Children.Add(new CustomDebugInformationTableTreeNode(metadataFile));\n\n\t\t\tbool ShowTable(TableIndex table) => !SettingsService.DisplaySettings.HideEmptyMetadataTables || metadataFile.Metadata.GetTableRowCount(table) > 0;\n\t\t}\n\n\t\tpublic override bool View(TabPageModel tabPage)\n\t\t{\n\t\t\ttabPage.Title = Text.ToString();\n\t\t\ttabPage.SupportsLanguageSwitching = false;\n\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.WriteCommentLine(output, \"Metadata Tables\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/DebugTables/CustomDebugInformationTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Windows;\nusing System.Windows.Controls;\n\nusing ICSharpCode.Decompiler.DebugInfo;\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class CustomDebugInformationTableTreeNode : DebugMetadataTableTreeNode<CustomDebugInformationTableTreeNode.CustomDebugInformationEntry>\n\t{\n\t\tpublic CustomDebugInformationTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.CustomDebugInformation, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<CustomDebugInformationEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<CustomDebugInformationEntry>();\n\t\t\tforeach (var row in metadataFile.Metadata.CustomDebugInformation)\n\t\t\t{\n\t\t\t\tlist.Add(new CustomDebugInformationEntry(metadataFile, row));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tprotected override void ConfigureDataGrid(DataGrid view)\n\t\t{\n\t\t\tview.RowDetailsVisibilityMode = DataGridRowDetailsVisibilityMode.VisibleWhenSelected;\n\t\t\tview.RowDetailsTemplateSelector = new CustomDebugInformationDetailsTemplateSelector();\n\t\t}\n\n\t\tclass CustomDebugInformationDetailsTemplateSelector : DataTemplateSelector\n\t\t{\n\t\t\tpublic override DataTemplate SelectTemplate(object item, DependencyObject container)\n\t\t\t{\n\t\t\t\tvar entry = (CustomDebugInformationEntry)item;\n\t\t\t\tswitch (entry.kind)\n\t\t\t\t{\n\t\t\t\t\tcase CustomDebugInformationEntry.CustomDebugInformationKind.StateMachineHoistedLocalScopes:\n\t\t\t\t\tcase CustomDebugInformationEntry.CustomDebugInformationKind.CompilationMetadataReferences:\n\t\t\t\t\tcase CustomDebugInformationEntry.CustomDebugInformationKind.CompilationOptions:\n\t\t\t\t\tcase CustomDebugInformationEntry.CustomDebugInformationKind.TupleElementNames:\n\t\t\t\t\t\treturn (DataTemplate)MetadataTableViews.Instance[\"CustomDebugInformationDetailsDataGrid\"];\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn (DataTemplate)MetadataTableViews.Instance[\"CustomDebugInformationDetailsTextBlob\"];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tinternal struct CustomDebugInformationEntry\n\t\t{\n\t\t\treadonly int? offset;\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly CustomDebugInformationHandle handle;\n\t\t\treadonly CustomDebugInformation debugInfo;\n\t\t\tinternal readonly CustomDebugInformationKind kind;\n\n\t\t\tinternal enum CustomDebugInformationKind\n\t\t\t{\n\t\t\t\tNone,\n\t\t\t\tUnknown,\n\t\t\t\tStateMachineHoistedLocalScopes,\n\t\t\t\tDynamicLocalVariables,\n\t\t\t\tDefaultNamespaces,\n\t\t\t\tEditAndContinueLocalSlotMap,\n\t\t\t\tEditAndContinueLambdaAndClosureMap,\n\t\t\t\tEncStateMachineStateMap,\n\t\t\t\tEmbeddedSource,\n\t\t\t\tSourceLink,\n\t\t\t\tMethodSteppingInformation,\n\t\t\t\tCompilationOptions,\n\t\t\t\tCompilationMetadataReferences,\n\t\t\t\tTupleElementNames,\n\t\t\t\tTypeDefinitionDocuments\n\t\t\t}\n\n\t\t\tstatic CustomDebugInformationKind GetKind(MetadataReader metadata, GuidHandle h)\n\t\t\t{\n\t\t\t\tif (h.IsNil)\n\t\t\t\t\treturn CustomDebugInformationKind.None;\n\t\t\t\tvar guid = metadata.GetGuid(h);\n\t\t\t\tif (KnownGuids.StateMachineHoistedLocalScopes == guid)\n\t\t\t\t{\n\t\t\t\t\treturn CustomDebugInformationKind.StateMachineHoistedLocalScopes;\n\t\t\t\t}\n\t\t\t\tif (KnownGuids.DynamicLocalVariables == guid)\n\t\t\t\t{\n\t\t\t\t\treturn CustomDebugInformationKind.DynamicLocalVariables;\n\t\t\t\t}\n\t\t\t\tif (KnownGuids.DefaultNamespaces == guid)\n\t\t\t\t{\n\t\t\t\t\treturn CustomDebugInformationKind.DefaultNamespaces;\n\t\t\t\t}\n\t\t\t\tif (KnownGuids.EditAndContinueLocalSlotMap == guid)\n\t\t\t\t{\n\t\t\t\t\treturn CustomDebugInformationKind.EditAndContinueLocalSlotMap;\n\t\t\t\t}\n\t\t\t\tif (KnownGuids.EditAndContinueLambdaAndClosureMap == guid)\n\t\t\t\t{\n\t\t\t\t\treturn CustomDebugInformationKind.EditAndContinueLambdaAndClosureMap;\n\t\t\t\t}\n\t\t\t\tif (KnownGuids.EncStateMachineStateMap == guid)\n\t\t\t\t{\n\t\t\t\t\treturn CustomDebugInformationKind.EncStateMachineStateMap;\n\t\t\t\t}\n\t\t\t\tif (KnownGuids.EmbeddedSource == guid)\n\t\t\t\t{\n\t\t\t\t\treturn CustomDebugInformationKind.EmbeddedSource;\n\t\t\t\t}\n\t\t\t\tif (KnownGuids.SourceLink == guid)\n\t\t\t\t{\n\t\t\t\t\treturn CustomDebugInformationKind.SourceLink;\n\t\t\t\t}\n\t\t\t\tif (KnownGuids.MethodSteppingInformation == guid)\n\t\t\t\t{\n\t\t\t\t\treturn CustomDebugInformationKind.MethodSteppingInformation;\n\t\t\t\t}\n\t\t\t\tif (KnownGuids.CompilationOptions == guid)\n\t\t\t\t{\n\t\t\t\t\treturn CustomDebugInformationKind.CompilationOptions;\n\t\t\t\t}\n\t\t\t\tif (KnownGuids.CompilationMetadataReferences == guid)\n\t\t\t\t{\n\t\t\t\t\treturn CustomDebugInformationKind.CompilationMetadataReferences;\n\t\t\t\t}\n\t\t\t\tif (KnownGuids.TupleElementNames == guid)\n\t\t\t\t{\n\t\t\t\t\treturn CustomDebugInformationKind.TupleElementNames;\n\t\t\t\t}\n\t\t\t\tif (KnownGuids.TypeDefinitionDocuments == guid)\n\t\t\t\t{\n\t\t\t\t\treturn CustomDebugInformationKind.TypeDefinitionDocuments;\n\t\t\t\t}\n\n\t\t\t\treturn CustomDebugInformationKind.Unknown;\n\t\t\t}\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic object Offset => offset == null ? \"n/a\" : (object)offset;\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Parent => MetadataTokens.GetToken(debugInfo.Parent);\n\n\t\t\tpublic void OnParentClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, debugInfo.Parent, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring parentTooltip;\n\t\t\tpublic string ParentTooltip => GenerateTooltip(ref parentTooltip, metadataFile, debugInfo.Parent);\n\n\t\t\tstring kindString;\n\t\t\tpublic string Kind {\n\t\t\t\tget {\n\t\t\t\t\tif (kindString != null)\n\t\t\t\t\t\treturn kindString;\n\n\t\t\t\t\tGuid guid;\n\t\t\t\t\tif (kind != CustomDebugInformationKind.None)\n\t\t\t\t\t{\n\t\t\t\t\t\tguid = metadataFile.Metadata.GetGuid(debugInfo.Kind);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tguid = Guid.Empty;\n\t\t\t\t\t}\n\t\t\t\t\tkindString = kind switch {\n\t\t\t\t\t\tCustomDebugInformationKind.None => \"\",\n\t\t\t\t\t\tCustomDebugInformationKind.StateMachineHoistedLocalScopes => $\"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - State Machine Hoisted Local Scopes (C# / VB) [{guid}]\",\n\t\t\t\t\t\tCustomDebugInformationKind.DynamicLocalVariables => $\"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Dynamic Local Variables (C#) [{guid}]\",\n\t\t\t\t\t\tCustomDebugInformationKind.DefaultNamespaces => $\"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Default Namespaces (VB) [{guid}]\",\n\t\t\t\t\t\tCustomDebugInformationKind.EditAndContinueLocalSlotMap => $\"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Edit And Continue Local Slot Map (C# / VB) [{guid}]\",\n\t\t\t\t\t\tCustomDebugInformationKind.EditAndContinueLambdaAndClosureMap => $\"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Edit And Continue Lambda And Closure Map (C# / VB) [{guid}]\",\n\t\t\t\t\t\tCustomDebugInformationKind.EncStateMachineStateMap => $\"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Edit And Continue State Machine State Map (C# / VB) [{guid}]\",\n\t\t\t\t\t\tCustomDebugInformationKind.EmbeddedSource => $\"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Embedded Source (C# / VB) [{guid}]\",\n\t\t\t\t\t\tCustomDebugInformationKind.SourceLink => $\"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Source Link (C# / VB) [{guid}]\",\n\t\t\t\t\t\tCustomDebugInformationKind.MethodSteppingInformation => $\"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Method Stepping Information (C# / VB) [{guid}]\",\n\t\t\t\t\t\tCustomDebugInformationKind.CompilationOptions => $\"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Compilation Options (C# / VB) [{guid}]\",\n\t\t\t\t\t\tCustomDebugInformationKind.CompilationMetadataReferences => $\"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Compilation Metadata References (C# / VB) [{guid}]\",\n\t\t\t\t\t\tCustomDebugInformationKind.TupleElementNames => $\"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Tuple Element Names (C#) [{guid}]\",\n\t\t\t\t\t\tCustomDebugInformationKind.TypeDefinitionDocuments => $\"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Type Definition Documents (C# / VB) [{guid}]\",\n\t\t\t\t\t\t_ => $\"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Unknown [{guid}]\",\n\t\t\t\t\t};\n\t\t\t\t\treturn kindString;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int Value => MetadataTokens.GetHeapOffset(debugInfo.Value);\n\n\t\t\tpublic string ValueTooltip {\n\t\t\t\tget {\n\t\t\t\t\tif (debugInfo.Value.IsNil)\n\t\t\t\t\t\treturn \"<nil>\";\n\t\t\t\t\treturn metadataFile.Metadata.GetBlobReader(debugInfo.Value).ToHexString();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tobject rowDetails;\n\n\t\t\tpublic object RowDetails {\n\t\t\t\tget {\n\t\t\t\t\tif (rowDetails != null)\n\t\t\t\t\t\treturn rowDetails;\n\n\t\t\t\t\tif (debugInfo.Value.IsNil)\n\t\t\t\t\t\treturn null;\n\n\t\t\t\t\tvar reader = metadataFile.Metadata.GetBlobReader(debugInfo.Value);\n\t\t\t\t\tArrayList list;\n\n\t\t\t\t\tswitch (kind)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase CustomDebugInformationKind.None:\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\tcase CustomDebugInformationKind.StateMachineHoistedLocalScopes:\n\t\t\t\t\t\t\tlist = new ArrayList();\n\n\t\t\t\t\t\t\twhile (reader.RemainingBytes > 0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tuint offset = reader.ReadUInt32();\n\t\t\t\t\t\t\t\tuint length = reader.ReadUInt32();\n\t\t\t\t\t\t\t\tlist.Add(new { StartOffset = offset, Length = length });\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn rowDetails = list;\n\t\t\t\t\t\tcase CustomDebugInformationKind.SourceLink:\n\t\t\t\t\t\t\treturn reader.ReadUTF8(reader.RemainingBytes);\n\t\t\t\t\t\tcase CustomDebugInformationKind.CompilationOptions:\n\t\t\t\t\t\t\tlist = new ArrayList();\n\n\t\t\t\t\t\t\twhile (reader.RemainingBytes > 0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstring name = reader.ReadUTF8StringNullTerminated();\n\t\t\t\t\t\t\t\tstring value = reader.ReadUTF8StringNullTerminated();\n\t\t\t\t\t\t\t\tlist.Add(new { Name = name, Value = value });\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn rowDetails = list;\n\t\t\t\t\t\tcase CustomDebugInformationKind.CompilationMetadataReferences:\n\t\t\t\t\t\t\tlist = new ArrayList();\n\n\t\t\t\t\t\t\twhile (reader.RemainingBytes > 0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstring fileName = reader.ReadUTF8StringNullTerminated();\n\t\t\t\t\t\t\t\tstring aliases = reader.ReadUTF8StringNullTerminated();\n\t\t\t\t\t\t\t\tbyte flags = reader.ReadByte();\n\t\t\t\t\t\t\t\tuint timestamp = reader.ReadUInt32();\n\t\t\t\t\t\t\t\tuint fileSize = reader.ReadUInt32();\n\t\t\t\t\t\t\t\tGuid guid = reader.ReadGuid();\n\t\t\t\t\t\t\t\tlist.Add(new { FileName = fileName, Aliases = aliases, Flags = flags, Timestamp = timestamp, FileSize = fileSize, Guid = guid });\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn rowDetails = list;\n\t\t\t\t\t\tcase CustomDebugInformationKind.TupleElementNames:\n\t\t\t\t\t\t\tlist = new ArrayList();\n\t\t\t\t\t\t\twhile (reader.RemainingBytes > 0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tlist.Add(new { ElementName = reader.ReadUTF8StringNullTerminated() });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn rowDetails = list;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn reader.ToHexString();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic CustomDebugInformationEntry(MetadataFile metadataFile, CustomDebugInformationHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.offset = metadataFile.IsEmbedded ? null : (int?)metadataFile.Metadata.GetTableMetadataOffset(TableIndex.CustomDebugInformation)\n\t\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.CustomDebugInformation) * (MetadataTokens.GetRowNumber(handle) - 1);\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.debugInfo = metadataFile.Metadata.GetCustomDebugInformation(handle);\n\t\t\t\tthis.kind = GetKind(metadataFile.Metadata, debugInfo.Kind);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/DebugTables/DocumentTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.DebugInfo;\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class DocumentTableTreeNode : DebugMetadataTableTreeNode<DocumentTableTreeNode.DocumentEntry>\n\t{\n\t\tpublic DocumentTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.Document, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<DocumentEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<DocumentEntry>();\n\t\t\tforeach (var row in metadataFile.Metadata.Documents)\n\t\t\t{\n\t\t\t\tlist.Add(new DocumentEntry(metadataFile, row));\n\t\t\t}\n\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal readonly struct DocumentEntry\n\t\t{\n\t\t\treadonly int? offset;\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly DocumentHandle handle;\n\t\t\treadonly Document document;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic object Offset => offset == null ? \"n/a\" : offset;\n\n\t\t\tpublic string Name => metadataFile.Metadata.GetString(document.Name);\n\n\t\t\tpublic string NameTooltip => $\"{MetadataTokens.GetHeapOffset(document.Name):X} \\\"{Name}\\\"\";\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int HashAlgorithm => MetadataTokens.GetHeapOffset(document.HashAlgorithm);\n\n\t\t\tpublic string HashAlgorithmTooltip {\n\t\t\t\tget {\n\t\t\t\t\tif (document.HashAlgorithm.IsNil)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tGuid guid = metadataFile.Metadata.GetGuid(document.HashAlgorithm);\n\t\t\t\t\tif (guid == KnownGuids.HashAlgorithmSHA1)\n\t\t\t\t\t\treturn \"SHA1 [ff1816ec-aa5e-4d10-87f7-6f4963833460]\";\n\t\t\t\t\tif (guid == KnownGuids.HashAlgorithmSHA256)\n\t\t\t\t\t\treturn \"SHA256 [8829d00f-11b8-4213-878b-770e8597ac16]\";\n\t\t\t\t\treturn $\"Unknown [\" + guid + \"]\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int Hash => MetadataTokens.GetHeapOffset(document.Hash);\n\n\t\t\tpublic string HashTooltip {\n\t\t\t\tget {\n\t\t\t\t\tif (document.Hash.IsNil)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tSystem.Collections.Immutable.ImmutableArray<byte> token = metadataFile.Metadata.GetBlobContent(document.Hash);\n\t\t\t\t\treturn token.ToHexString(token.Length);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int Language => MetadataTokens.GetHeapOffset(document.Language);\n\n\t\t\tpublic string LanguageTooltip {\n\t\t\t\tget {\n\t\t\t\t\tif (document.Language.IsNil)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tGuid guid = metadataFile.Metadata.GetGuid(document.Language);\n\t\t\t\t\tif (guid == KnownGuids.CSharpLanguageGuid)\n\t\t\t\t\t\treturn \"Visual C# [3f5162f8-07c6-11d3-9053-00c04fa302a1]\";\n\t\t\t\t\tif (guid == KnownGuids.VBLanguageGuid)\n\t\t\t\t\t\treturn \"Visual Basic [3a12d0b8-c26c-11d0-b442-00a0244a1dd2]\";\n\t\t\t\t\tif (guid == KnownGuids.FSharpLanguageGuid)\n\t\t\t\t\t\treturn \"Visual F# [ab4f38c9-b6e6-43ba-be3b-58080b2ccce3]\";\n\t\t\t\t\treturn $\"Unknown [\" + guid + \"]\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic DocumentEntry(MetadataFile metadataFile, DocumentHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.offset = metadataFile.IsEmbedded ? null : (int?)metadataFile.Metadata.GetTableMetadataOffset(TableIndex.Document)\n\t\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.Document) * (MetadataTokens.GetRowNumber(handle) - 1);\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.document = metadataFile.Metadata.GetDocument(handle);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/DebugTables/ImportScopeTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class ImportScopeTableTreeNode : DebugMetadataTableTreeNode<ImportScopeTableTreeNode.ImportScopeEntry>\n\t{\n\t\tpublic ImportScopeTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.ImportScope, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<ImportScopeEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<ImportScopeEntry>();\n\t\t\tforeach (var row in metadataFile.Metadata.ImportScopes)\n\t\t\t{\n\t\t\t\tlist.Add(new ImportScopeEntry(metadataFile, row));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal readonly struct ImportScopeEntry\n\t\t{\n\t\t\treadonly int? offset;\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly ImportScopeHandle handle;\n\t\t\treadonly ImportScope localScope;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic object Offset => offset == null ? \"n/a\" : offset;\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Parent => MetadataTokens.GetToken(localScope.Parent);\n\n\t\t\tpublic void OnParentClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, localScope.Parent, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int Imports => MetadataTokens.GetHeapOffset(localScope.ImportsBlob);\n\n\t\t\tpublic ImportScopeEntry(MetadataFile metadataFile, ImportScopeHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.localScope = metadataFile.Metadata.GetImportScope(handle);\n\t\t\t\tthis.offset = metadataFile.IsEmbedded ? null : (int?)metadataFile.Metadata.GetTableMetadataOffset(TableIndex.ImportScope)\n\t\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.ImportScope) * (MetadataTokens.GetRowNumber(handle) - 1);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/DebugTables/LocalConstantTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class LocalConstantTableTreeNode : DebugMetadataTableTreeNode<LocalConstantTableTreeNode.LocalConstantEntry>\n\t{\n\t\tpublic LocalConstantTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.LocalConstant, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<LocalConstantEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<LocalConstantEntry>();\n\n\t\t\tforeach (var row in metadataFile.Metadata.LocalConstants)\n\t\t\t{\n\t\t\t\tlist.Add(new LocalConstantEntry(metadataFile, row));\n\t\t\t}\n\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal readonly struct LocalConstantEntry\n\t\t{\n\t\t\treadonly int? offset;\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly LocalConstantHandle handle;\n\t\t\treadonly LocalConstant localConst;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic object Offset => offset == null ? \"n/a\" : (object)offset;\n\n\t\t\tpublic string Name => metadataFile.Metadata.GetString(localConst.Name);\n\n\t\t\tpublic string NameTooltip => $\"{MetadataTokens.GetHeapOffset(localConst.Name):X} \\\"{Name}\\\"\";\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int Signature => MetadataTokens.GetHeapOffset(localConst.Signature);\n\n\t\t\tpublic LocalConstantEntry(MetadataFile metadataFile, LocalConstantHandle handle)\n\t\t\t{\n\t\t\t\tthis.offset = metadataFile.IsEmbedded ? null : (int?)metadataFile.Metadata.GetTableMetadataOffset(TableIndex.LocalConstant)\n\t\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.LocalConstant) * (MetadataTokens.GetRowNumber(handle) - 1);\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.localConst = metadataFile.Metadata.GetLocalConstant(handle);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/DebugTables/LocalScopeTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class LocalScopeTableTreeNode : DebugMetadataTableTreeNode<LocalScopeTableTreeNode.LocalScopeEntry>\n\t{\n\t\tpublic LocalScopeTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.LocalScope, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<LocalScopeEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<LocalScopeEntry>();\n\n\t\t\tforeach (var row in metadataFile.Metadata.LocalScopes)\n\t\t\t{\n\t\t\t\tlist.Add(new LocalScopeEntry(metadataFile, row));\n\t\t\t}\n\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct LocalScopeEntry\n\t\t{\n\t\t\treadonly int? offset;\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly LocalScopeHandle handle;\n\t\t\treadonly LocalScope localScope;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic object Offset => offset == null ? \"n/a\" : (object)offset;\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Method => MetadataTokens.GetToken(localScope.Method);\n\n\t\t\tpublic void OnMethodClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, localScope.Method, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring methodTooltip;\n\t\t\tpublic string MethodTooltip => GenerateTooltip(ref methodTooltip, metadataFile, localScope.Method);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int ImportScope => MetadataTokens.GetToken(localScope.ImportScope);\n\n\t\t\tpublic void OnImportScopeClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, localScope.ImportScope, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int VariableList => MetadataTokens.GetToken(localScope.GetLocalVariables().FirstOrDefault());\n\n\t\t\tpublic void OnVariableListClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, localScope.GetLocalVariables().FirstOrDefault(), protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int ConstantList => MetadataTokens.GetToken(localScope.GetLocalConstants().FirstOrDefault());\n\n\t\t\tpublic void OnConstantListClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, localScope.GetLocalConstants().FirstOrDefault(), protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tpublic int StartOffset => localScope.StartOffset;\n\n\t\t\tpublic int Length => localScope.Length;\n\n\t\t\tpublic LocalScopeEntry(MetadataFile metadataFile, LocalScopeHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.offset = metadataFile.IsEmbedded ? null : (int?)metadataFile.Metadata.GetTableMetadataOffset(TableIndex.LocalScope)\n\t\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.LocalScope) * (MetadataTokens.GetRowNumber(handle) - 1);\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.localScope = metadataFile.Metadata.GetLocalScope(handle);\n\t\t\t\tthis.methodTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/DebugTables/LocalVariableTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class LocalVariableTableTreeNode : DebugMetadataTableTreeNode<LocalVariableTableTreeNode.LocalVariableEntry>\n\t{\n\t\tpublic LocalVariableTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.LocalVariable, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<LocalVariableEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<LocalVariableEntry>();\n\n\t\t\tforeach (var row in metadataFile.Metadata.LocalVariables)\n\t\t\t{\n\t\t\t\tlist.Add(new LocalVariableEntry(metadataFile, row));\n\t\t\t}\n\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct LocalVariableEntry\n\t\t{\n\t\t\treadonly int? offset;\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly LocalVariableHandle handle;\n\t\t\treadonly LocalVariable localVar;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic object Offset => offset == null ? \"n/a\" : (object)offset;\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Other)]\n\t\t\tpublic LocalVariableAttributes Attributes => localVar.Attributes;\n\n\t\t\tpublic object AttributesTooltip => new FlagsTooltip() {\n\t\t\t\tFlagGroup.CreateMultipleChoiceGroup(typeof(LocalVariableAttributes)),\n\t\t\t};\n\n\t\t\tpublic int Index => localVar.Index;\n\n\t\t\tpublic string Name => metadataFile.Metadata.GetString(localVar.Name);\n\n\t\t\tpublic string NameTooltip => $\"{MetadataTokens.GetHeapOffset(localVar.Name):X} \\\"{Name}\\\"\";\n\n\t\t\tpublic LocalVariableEntry(MetadataFile metadataFile, LocalVariableHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.offset = metadataFile.IsEmbedded ? null : (int?)metadataFile.Metadata.GetTableMetadataOffset(TableIndex.LocalVariable)\n\t\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.LocalVariable) * (MetadataTokens.GetRowNumber(handle) - 1);\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.localVar = metadataFile.Metadata.GetLocalVariable(handle);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/DebugTables/MethodDebugInformationTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Text;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class MethodDebugInformationTableTreeNode : DebugMetadataTableTreeNode<MethodDebugInformationTableTreeNode.MethodDebugInformationEntry>\n\t{\n\t\tpublic MethodDebugInformationTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.MethodDebugInformation, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<MethodDebugInformationEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<MethodDebugInformationEntry>();\n\n\t\t\tforeach (var row in metadataFile.Metadata.MethodDebugInformation)\n\t\t\t{\n\t\t\t\tlist.Add(new MethodDebugInformationEntry(metadataFile, row));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct MethodDebugInformationEntry\n\t\t{\n\t\t\treadonly int? offset;\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly MethodDebugInformationHandle handle;\n\t\t\treadonly MethodDebugInformation debugInfo;\n\n\t\t\tpublic int RID => MetadataTokens.GetRowNumber(handle);\n\n\t\t\tpublic int Token => MetadataTokens.GetToken(handle);\n\n\t\t\tpublic object Offset => offset == null ? \"n/a\" : (object)offset;\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int Document => MetadataTokens.GetToken(debugInfo.Document);\n\n\t\t\tpublic void OnDocumentClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, debugInfo.Document, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tpublic string DocumentTooltip {\n\t\t\t\tget {\n\t\t\t\t\tif (debugInfo.Document.IsNil)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tvar document = metadataFile.Metadata.GetDocument(debugInfo.Document);\n\t\t\t\t\treturn $\"{MetadataTokens.GetHeapOffset(document.Name):X} \\\"{metadataFile.Metadata.GetString(document.Name)}\\\"\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.HeapOffset)]\n\t\t\tpublic int SequencePoints => MetadataTokens.GetHeapOffset(debugInfo.SequencePointsBlob);\n\n\t\t\tpublic string SequencePointsTooltip {\n\t\t\t\tget {\n\t\t\t\t\tif (debugInfo.SequencePointsBlob.IsNil)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tStringBuilder sb = new StringBuilder();\n\t\t\t\t\tforeach (var p in debugInfo.GetSequencePoints())\n\t\t\t\t\t{\n\t\t\t\t\t\tsb.AppendLine($\"document='{MetadataTokens.GetToken(p.Document):X8}', offset={p.Offset}, start={p.StartLine};{p.StartColumn}, end={p.EndLine};{p.EndColumn}, hidden={p.IsHidden}\");\n\t\t\t\t\t}\n\t\t\t\t\treturn sb.ToString().TrimEnd();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int LocalSignature => MetadataTokens.GetToken(debugInfo.LocalSignature);\n\n\t\t\tpublic void OnLocalSignatureClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, debugInfo.LocalSignature, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tpublic string LocalSignatureTooltip {\n\t\t\t\tget {\n\t\t\t\t\tif (debugInfo.LocalSignature.IsNil)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tITextOutput output = new PlainTextOutput();\n\t\t\t\t\tvar context = new MetadataGenericContext(default(TypeDefinitionHandle), metadataFile.Metadata);\n\t\t\t\t\tStandaloneSignature localSignature = metadataFile.Metadata.GetStandaloneSignature(debugInfo.LocalSignature);\n\t\t\t\t\tvar signatureDecoder = new DisassemblerSignatureTypeProvider(metadataFile, output);\n\t\t\t\t\tint index = 0;\n\t\t\t\t\tforeach (var item in localSignature.DecodeLocalSignature(signatureDecoder, context))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (index > 0)\n\t\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t\toutput.Write(\"[{0}] \", index);\n\t\t\t\t\t\titem(ILNameSyntax.Signature);\n\t\t\t\t\t\tindex++;\n\t\t\t\t\t}\n\t\t\t\t\treturn output.ToString();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic MethodDebugInformationEntry(MetadataFile metadataFile, MethodDebugInformationHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.offset = metadataFile.IsEmbedded ? null : (int?)metadataFile.Metadata.GetTableMetadataOffset(TableIndex.MethodDebugInformation)\n\t\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.MethodDebugInformation) * (MetadataTokens.GetRowNumber(handle) - 1);\n\t\t\t\tthis.handle = handle;\n\t\t\t\tthis.debugInfo = metadataFile.Metadata.GetMethodDebugInformation(handle);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/DebugTables/StateMachineMethodTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class StateMachineMethodTableTreeNode : DebugMetadataTableTreeNode<StateMachineMethodTableTreeNode.StateMachineMethodEntry>\n\t{\n\t\tpublic StateMachineMethodTableTreeNode(MetadataFile metadataFile)\n\t\t\t: base(TableIndex.StateMachineMethod, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected override IReadOnlyList<StateMachineMethodEntry> LoadTable()\n\t\t{\n\t\t\tvar list = new List<StateMachineMethodEntry>();\n\t\t\tvar length = metadataFile.Metadata.GetTableRowCount(TableIndex.StateMachineMethod);\n\t\t\tvar reader = metadataFile.Metadata.AsBlobReader();\n\t\t\treader.Offset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.StateMachineMethod);\n\n\t\t\tfor (int rid = 1; rid <= length; rid++)\n\t\t\t{\n\t\t\t\tlist.Add(new StateMachineMethodEntry(metadataFile, ref reader, rid));\n\t\t\t}\n\t\t\treturn list;\n\t\t}\n\n\t\tinternal struct StateMachineMethodEntry\n\t\t{\n\t\t\treadonly int? offset;\n\t\t\treadonly MetadataFile metadataFile;\n\t\t\treadonly MethodDefinitionHandle moveNextMethod;\n\t\t\treadonly MethodDefinitionHandle kickoffMethod;\n\n\t\t\tpublic int RID { get; }\n\n\t\t\tpublic int Token => 0x36000000 + RID;\n\n\t\t\tpublic object Offset => offset == null ? \"n/a\" : (object)offset;\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int MoveNextMethod => MetadataTokens.GetToken(moveNextMethod);\n\n\t\t\tpublic void OnMoveNextMethodClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, moveNextMethod, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring moveNextMethodTooltip;\n\t\t\tpublic string MoveNextMethodTooltip => GenerateTooltip(ref moveNextMethodTooltip, metadataFile, moveNextMethod);\n\n\t\t\t[ColumnInfo(\"X8\", Kind = ColumnKind.Token)]\n\t\t\tpublic int KickoffMethod => MetadataTokens.GetToken(kickoffMethod);\n\n\t\t\tpublic void OnKickofMethodClick()\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(metadataFile, kickoffMethod, protocol: \"metadata\")));\n\t\t\t}\n\n\t\t\tstring kickoffMethodTooltip;\n\t\t\tpublic string KickoffMethodTooltip => GenerateTooltip(ref kickoffMethodTooltip, metadataFile, kickoffMethod);\n\n\t\t\tpublic StateMachineMethodEntry(MetadataFile metadataFile, ref BlobReader reader, int row)\n\t\t\t{\n\t\t\t\tthis.metadataFile = metadataFile;\n\t\t\t\tthis.RID = row;\n\t\t\t\tint rowOffset = metadataFile.Metadata.GetTableMetadataOffset(TableIndex.StateMachineMethod)\n\t\t\t\t\t+ metadataFile.Metadata.GetTableRowSize(TableIndex.StateMachineMethod) * (row - 1);\n\t\t\t\tthis.offset = metadataFile.IsEmbedded ? null : (int?)rowOffset;\n\n\t\t\t\tint methodDefSize = metadataFile.Metadata.GetTableRowCount(TableIndex.MethodDef) < ushort.MaxValue ? 2 : 4;\n\t\t\t\tthis.moveNextMethod = MetadataTokens.MethodDefinitionHandle(methodDefSize == 2 ? reader.ReadInt16() : reader.ReadInt32());\n\t\t\t\tthis.kickoffMethod = MetadataTokens.MethodDefinitionHandle(methodDefSize == 2 ? reader.ReadInt16() : reader.ReadInt32());\n\t\t\t\tthis.kickoffMethodTooltip = null;\n\t\t\t\tthis.moveNextMethodTooltip = null;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/DosHeaderTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.ViewModels;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tclass DosHeaderTreeNode : ILSpyTreeNode\n\t{\n\t\tprivate PEFile module;\n\n\t\tpublic DosHeaderTreeNode(PEFile module)\n\t\t{\n\t\t\tthis.module = module;\n\t\t}\n\n\t\tpublic override object Text => \"DOS Header\";\n\n\t\tpublic override object NavigationText => $\"{Text} ({module.Name})\";\n\n\t\tpublic override object Icon => Images.Header;\n\n\t\tpublic override bool View(TabPageModel tabPage)\n\t\t{\n\t\t\ttabPage.Title = Text.ToString();\n\t\t\ttabPage.SupportsLanguageSwitching = false;\n\n\t\t\tvar view = Helpers.PrepareDataGrid(tabPage, this);\n\t\t\tvar reader = module.Reader.GetEntireImage().GetReader(0, 64);\n\n\t\t\tvar entries = new List<Entry>();\n\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_magic\", \"Magic Number (MZ)\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_cblp\", \"Bytes on last page of file\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_cp\", \"Pages in file\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_crlc\", \"Relocations\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_cparhdr\", \"Size of header in paragraphs\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_minalloc\", \"Minimum extra paragraphs needed\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_maxalloc\", \"Maximum extra paragraphs needed\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_ss\", \"Initial (relative) SS value\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_sp\", \"Initial SP value\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_csum\", \"Checksum\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_ip\", \"Initial IP value\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_cs\", \"Initial (relative) CS value\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_lfarlc\", \"File address of relocation table\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_ovno\", \"Overlay number\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_res[0]\", \"Reserved words\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_res[1]\", \"Reserved words\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_res[2]\", \"Reserved words\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_res[3]\", \"Reserved words\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_oemid\", \"OEM identifier (for e_oeminfo)\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_oeminfo\", \"OEM information; e_oemid specific\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_res2[0]\", \"Reserved words\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_res2[1]\", \"Reserved words\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_res2[2]\", \"Reserved words\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_res2[3]\", \"Reserved words\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_res2[4]\", \"Reserved words\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_res2[5]\", \"Reserved words\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_res2[6]\", \"Reserved words\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_res2[7]\", \"Reserved words\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_res2[8]\", \"Reserved words\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, \"e_res2[9]\", \"Reserved words\"));\n\t\t\tentries.Add(new Entry(reader.Offset, reader.ReadInt32(), 4, \"e_lfanew\", \"File address of new exe header\"));\n\n\t\t\tview.ItemsSource = entries;\n\n\t\t\ttabPage.Content = view;\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/FlagsFilterControl.xaml",
    "content": "<Control x:Class=\"ICSharpCode.ILSpy.Metadata.FlagsFilterControl\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" \n             xmlns:local=\"clr-namespace:ICSharpCode.ILSpy.Metadata\"\n             xmlns:dgx=\"urn:tom-englert.de/DataGridExtensions\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"450\" d:DesignWidth=\"800\">\n\t<Control.Template>\n\t\t<ControlTemplate>\n\t\t\t<Grid>\n\t\t\t\t<ToggleButton x:Name=\"ToggleButton\">\n\t\t\t\t\t<ToggleButton.Template>\n\t\t\t\t\t\t<ControlTemplate>\n\t\t\t\t\t\t\t<Border Background=\"#01010101\">\n\t\t\t\t\t\t\t\t<Control x:Name=\"FilterSymbol\" Style=\"{DynamicResource {x:Static dgx:DataGridFilter.IconStyleKey}}\" />\n\t\t\t\t\t\t\t</Border>\n\t\t\t\t\t\t</ControlTemplate>\n\t\t\t\t\t</ToggleButton.Template>\n\t\t\t\t</ToggleButton>\n\t\t\t\t<Popup d:DataContext=\"{d:DesignInstance dgx:DataGridFilterColumnControl}\"\n\t\t\t\t\tx:Name=\"Popup\" IsOpen=\"{Binding Path=IsChecked, ElementName=ToggleButton, Mode=TwoWay}\"\n\t\t\t\t\tAllowsTransparency=\"True\" StaysOpen=\"False\">\n\t\t\t\t\t<ListBox x:Name=\"ListBox\" SelectionMode=\"Extended\" SelectionChanged=\"ListBox_SelectionChanged\">\n\t\t\t\t\t\t<ListBox.ItemTemplate>\n\t\t\t\t\t\t\t<DataTemplate>\n\t\t\t\t\t\t\t\t<CheckBox DockPanel.Dock=\"Left\" Margin=\"3,2\" Content=\"{Binding Name}\" IsChecked=\"{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType=ListBoxItem}}\"/>\n\t\t\t\t\t\t\t</DataTemplate>\n\t\t\t\t\t\t</ListBox.ItemTemplate>\n\t\t\t\t\t</ListBox>\n\t\t\t\t</Popup>\n\t\t\t</Grid>\n\t\t</ControlTemplate>\n\t</Control.Template>\n</Control>\n"
  },
  {
    "path": "ILSpy/Metadata/FlagsFilterControl.xaml.cs",
    "content": "using System;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Controls;\n\nusing DataGridExtensions;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\t/// <summary>\n\t/// Interaction logic for FlagsFilterControl.xaml\n\t/// </summary>\n\tpublic partial class FlagsFilterControl\n\t{\n\t\tListBox listBox;\n\n\t\tpublic FlagsFilterControl()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\n\t\tpublic FlagsContentFilter Filter {\n\t\t\tget { return (FlagsContentFilter)GetValue(FilterProperty); }\n\t\t\tset { SetValue(FilterProperty, value); }\n\t\t}\n\n\t\tpublic Type FlagsType { get; set; }\n\n\t\t/// <summary>\n\t\t/// Identifies the Filter dependency property\n\t\t/// </summary>\n\t\tpublic static readonly DependencyProperty FilterProperty =\n\t\t\tDependencyProperty.Register(\"Filter\", typeof(FlagsContentFilter), typeof(FlagsFilterControl),\n\t\t\t\tnew FrameworkPropertyMetadata(new FlagsContentFilter(-1), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (sender, e) => ((FlagsFilterControl)sender).Filter_Changed()));\n\n\t\t/// <summary>When overridden in a derived class, is invoked whenever application code or internal processes call <see cref=\"M:System.Windows.FrameworkElement.ApplyTemplate\" />.</summary>\n\t\tpublic override void OnApplyTemplate()\n\t\t{\n\t\t\tbase.OnApplyTemplate();\n\n\t\t\tlistBox = Template.FindName(\"ListBox\", this) as ListBox;\n\t\t\tif (listBox != null)\n\t\t\t{\n\t\t\t\tlistBox.ItemsSource = FlagGroup.GetFlags(FlagsType, neutralItem: \"<All>\");\n\t\t\t}\n\n\t\t\tvar filter = Filter;\n\n\t\t\tif (filter == null || filter.Mask == -1)\n\t\t\t{\n\t\t\t\tlistBox?.SelectAll();\n\t\t\t}\n\t\t}\n\n\t\tprivate void Filter_Changed()\n\t\t{\n\t\t\tvar filter = Filter;\n\n\t\t\tif (filter == null || filter.Mask == -1)\n\t\t\t{\n\t\t\t\tlistBox?.SelectAll();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (listBox?.SelectedItems.Count != 0)\n\t\t\t\treturn;\n\n\t\t\tforeach (var item in listBox.Items.Cast<Flag>())\n\t\t\t{\n\t\t\t\tif ((item.Value & filter.Mask) != 0 || item.Value == 0)\n\t\t\t\t{\n\t\t\t\t\tlistBox.SelectedItems.Add(item);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)\n\t\t{\n\t\t\tif (e.RemovedItems?.OfType<Flag>().Any(f => f.Value == -1) == true)\n\t\t\t{\n\t\t\t\tFilter = new FlagsContentFilter(0);\n\t\t\t\tlistBox.UnselectAll();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (e.AddedItems?.OfType<Flag>().Any(f => f.Value == -1) == true)\n\t\t\t{\n\t\t\t\tFilter = new FlagsContentFilter(-1);\n\t\t\t\tlistBox.SelectAll();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tbool deselectAny = e.RemovedItems?.OfType<Flag>().Any(f => f.Value != -1) == true;\n\n\t\t\tint mask = 0;\n\t\t\tforeach (var item in listBox.SelectedItems.Cast<Flag>())\n\t\t\t{\n\t\t\t\tif (deselectAny && item.Value == -1)\n\t\t\t\t\tcontinue;\n\t\t\t\tmask |= item.Value;\n\t\t\t}\n\n\t\t\tFilter = new FlagsContentFilter(mask);\n\t\t}\n\t}\n\n\tpublic class FlagsContentFilter : IContentFilter\n\t{\n\t\tpublic int Mask { get; }\n\n\t\tpublic FlagsContentFilter(int mask)\n\t\t{\n\t\t\tthis.Mask = mask;\n\t\t}\n\n\t\tpublic bool IsMatch(object value)\n\t\t{\n\t\t\tif (value == null)\n\t\t\t\treturn true;\n\n\t\t\treturn Mask == -1 || (Mask & (int)value) != 0;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/FlagsTooltip.xaml",
    "content": "<Control x:Class=\"ICSharpCode.ILSpy.Metadata.FlagsTooltip\"\n\t\t xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n\t\t xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n\t\t xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n\t\t xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" \n\t\t xmlns:local=\"clr-namespace:ICSharpCode.ILSpy.Metadata\"\n\t\t x:Name=\"root\"\n\t\t mc:Ignorable=\"d\" \n\t\t d:DesignHeight=\"450\" d:DesignWidth=\"800\">\n\t<Control.Resources>\n\t\t<local:NullVisibilityConverter x:Key=\"nullVisConv\" />\n\n\t\t<DataTemplate DataType=\"{x:Type local:MultipleChoiceGroup}\">\n\t\t\t<StackPanel Orientation=\"Vertical\" Margin=\"3\">\n\t\t\t\t<TextBlock Text=\"{Binding Header}\" FontWeight=\"Bold\" Margin=\"0 0 0 3\" Visibility=\"{Binding Header, Converter={StaticResource nullVisConv}}\" />\n\t\t\t\t<ListBox ItemsSource=\"{Binding Flags}\" BorderThickness=\"0\" Background=\"Transparent\">\n\t\t\t\t\t<ListBox.ItemTemplate>\n\t\t\t\t\t\t<DataTemplate>\n\t\t\t\t\t\t\t<CheckBox DockPanel.Dock=\"Left\" Margin=\"3,2\" Content=\"{Binding Name}\" IsChecked=\"{Binding IsSelected, Mode=OneWay}\"/>\n\t\t\t\t\t\t</DataTemplate>\n\t\t\t\t\t</ListBox.ItemTemplate>\n\t\t\t\t</ListBox>\n\t\t\t</StackPanel>\n\t\t</DataTemplate>\n\n\t\t<DataTemplate DataType=\"{x:Type local:SingleChoiceGroup}\">\n\t\t\t<StackPanel Orientation=\"Horizontal\" Margin=\"3\">\n\t\t\t\t<TextBlock Text=\"{Binding Header}\" FontWeight=\"Bold\" Visibility=\"{Binding Header, Converter={StaticResource nullVisConv}}\" />\n\t\t\t\t<TextBlock Text=\"{Binding SelectedFlag.Name}\" />\n\t\t\t</StackPanel>\n\t\t</DataTemplate>\n\t</Control.Resources>\n\t<Control.Template>\n\t\t<ControlTemplate>\n\t\t\t<ItemsControl ItemsSource=\"{Binding Groups, ElementName=root}\">\n\t\t\t\t<ItemsControl.ItemsPanel>\n\t\t\t\t\t<ItemsPanelTemplate>\n\t\t\t\t\t\t<StackPanel Orientation=\"Vertical\" />\n\t\t\t\t\t</ItemsPanelTemplate>\n\t\t\t\t</ItemsControl.ItemsPanel>\n\t\t\t</ItemsControl>\n\t\t</ControlTemplate>\n\t</Control.Template>\n</Control>\n"
  },
  {
    "path": "ILSpy/Metadata/FlagsTooltip.xaml.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\nusing System.Reflection;\nusing System.Windows;\nusing System.Windows.Data;\n\nusing ICSharpCode.Decompiler.Util;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\t/// <summary>\n\t/// Interaction logic for FlagsTooltip.xaml\n\t/// </summary>\n\tpublic partial class FlagsTooltip : IEnumerable<FlagGroup>\n\t{\n\t\tpublic FlagsTooltip(int value = 0, Type flagsType = null)\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\n\t\tpublic void Add(FlagGroup group)\n\t\t{\n\t\t\tGroups.Add(group);\n\t\t}\n\n\t\tpublic IEnumerator<FlagGroup> GetEnumerator()\n\t\t{\n\t\t\treturn Groups.GetEnumerator();\n\t\t}\n\n\t\tIEnumerator IEnumerable.GetEnumerator()\n\t\t{\n\t\t\treturn Groups.GetEnumerator();\n\t\t}\n\n\t\tpublic List<FlagGroup> Groups { get; } = new List<FlagGroup>();\n\t}\n\n\tclass FlagActiveConverter : DependencyObject, IValueConverter\n\t{\n\t\tpublic int Value {\n\t\t\tget { return (int)GetValue(ValueProperty); }\n\t\t\tset { SetValue(ValueProperty, value); }\n\t\t}\n\n\t\tpublic static readonly DependencyProperty ValueProperty =\n\t\t\tDependencyProperty.Register(\"Value\", typeof(int), typeof(FlagActiveConverter), new PropertyMetadata(0));\n\n\t\tpublic object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n\t\t{\n\t\t\treturn Value == (int)value || ((int)value & Value) != 0;\n\t\t}\n\n\t\tpublic object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\t}\n\n\tpublic readonly struct Flag\n\t{\n\t\tpublic string Name { get; }\n\t\tpublic int Value { get; }\n\t\tpublic bool IsSelected { get; }\n\n\t\tpublic Flag(string name, int value, bool isSelected)\n\t\t{\n\t\t\tthis.Name = name;\n\t\t\tthis.Value = value;\n\t\t\tthis.IsSelected = isSelected;\n\t\t}\n\t}\n\n\tpublic abstract class FlagGroup\n\t{\n\t\tpublic static MultipleChoiceGroup CreateMultipleChoiceGroup(Type flagsType, string header = null, int mask = -1, int selectedValue = 0, bool includeAll = true)\n\t\t{\n\t\t\tMultipleChoiceGroup group = new MultipleChoiceGroup(GetFlags(flagsType, mask, selectedValue, includeAll ? \"<All>\" : null));\n\t\t\tgroup.Header = header;\n\t\t\tgroup.SelectedFlags = selectedValue;\n\t\t\treturn group;\n\t\t}\n\n\t\tpublic static SingleChoiceGroup CreateSingleChoiceGroup(Type flagsType, string header = null, int mask = -1, int selectedValue = 0, Flag defaultFlag = default, bool includeAny = true)\n\t\t{\n\t\t\tvar group = new SingleChoiceGroup(GetFlags(flagsType, mask, selectedValue, includeAny ? \"<Any>\" : null));\n\t\t\tgroup.Header = header;\n\t\t\tgroup.SelectedFlag = group.Flags.SingleOrDefault(f => f.Value == selectedValue);\n\t\t\tif (group.SelectedFlag.Name == null)\n\t\t\t{\n\t\t\t\tgroup.SelectedFlag = defaultFlag;\n\t\t\t}\n\t\t\treturn group;\n\t\t}\n\n\t\tpublic static IEnumerable<Flag> GetFlags(Type flagsType, int mask = -1, int selectedValues = 0, string neutralItem = null)\n\t\t{\n\t\t\tif (neutralItem != null)\n\t\t\t\tyield return new Flag(neutralItem, -1, false);\n\n\t\t\tforeach (var item in flagsType.GetFields(BindingFlags.Static | BindingFlags.Public))\n\t\t\t{\n\t\t\t\tif (item.Name.EndsWith(\"Mask\", StringComparison.Ordinal))\n\t\t\t\t\tcontinue;\n\t\t\t\tint value = (int)CSharpPrimitiveCast.Cast(TypeCode.Int32, item.GetRawConstantValue(), false);\n\t\t\t\tif ((value & mask) == 0)\n\t\t\t\t\tcontinue;\n\t\t\t\tyield return new Flag($\"{item.Name} ({value:X4})\", value, (selectedValues & value) != 0);\n\t\t\t}\n\t\t}\n\n\t\tpublic string Header { get; set; }\n\n\t\tpublic IList<Flag> Flags { get; protected set; }\n\t}\n\n\tpublic class MultipleChoiceGroup : FlagGroup\n\t{\n\t\tpublic MultipleChoiceGroup(IEnumerable<Flag> flags)\n\t\t{\n\t\t\tthis.Flags = flags.ToList();\n\t\t}\n\n\t\tpublic int SelectedFlags { get; set; }\n\t}\n\n\tpublic class SingleChoiceGroup : FlagGroup\n\t{\n\t\tpublic SingleChoiceGroup(IEnumerable<Flag> flags)\n\t\t{\n\t\t\tthis.Flags = flags.ToList();\n\t\t}\n\n\t\tpublic Flag SelectedFlag { get; set; }\n\t}\n\n\tclass NullVisibilityConverter : IValueConverter\n\t{\n\t\tpublic object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n\t\t{\n\t\t\tif (value == null)\n\t\t\t\treturn Visibility.Collapsed;\n\t\t\treturn Visibility.Visible;\n\t\t}\n\n\t\tpublic object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/GoToTokenCommand.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Composition;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Windows;\nusing System.Windows.Controls;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.Metadata;\nusing ICSharpCode.ILSpy.Properties;\n\nusing TomsToolbox.Wpf;\n\nnamespace ICSharpCode.ILSpy.Commands\n{\n\t[ExportContextMenuEntry(Header = nameof(Resources.GoToToken), Order = 10)]\n\t[Shared]\n\tclass GoToTokenCommand : IContextMenuEntry\n\t{\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tint token = GetSelectedToken(context.DataGrid, out MetadataFile module).Value;\n\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(module, MetadataTokens.Handle(token), protocol: \"metadata\")));\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\treturn context.DataGrid?.Name == \"MetadataView\" && GetSelectedToken(context.DataGrid, out _) != null;\n\t\t}\n\n\t\tprivate int? GetSelectedToken(DataGrid grid, out MetadataFile module)\n\t\t{\n\t\t\tmodule = null;\n\t\t\tif (grid == null)\n\t\t\t\treturn null;\n\t\t\tvar cell = grid.CurrentCell;\n\t\t\tif (!cell.IsValid)\n\t\t\t\treturn null;\n\t\t\tType type = cell.Item.GetType();\n\t\t\tvar property = type.GetProperty(cell.Column.Header.ToString());\n\t\t\tvar moduleField = type.GetField(\"module\", BindingFlags.NonPublic | BindingFlags.Instance);\n\t\t\tif (property == null || property.PropertyType != typeof(int) || !property.GetCustomAttributes(false).Any(a => a is ColumnInfoAttribute { Kind: ColumnKind.Token } c))\n\t\t\t\treturn null;\n\t\t\tmodule = (MetadataFile)moduleField.GetValue(cell.Item);\n\t\t\treturn (int)property.GetValue(cell.Item);\n\t\t}\n\t}\n\n\t[ExportContextMenuEntry(Header = nameof(Resources.Copy), Order = 10)]\n\t[Shared]\n\tclass CopyCommand : IContextMenuEntry\n\t{\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tstring content = GetSelectedCellContent(context.OriginalSource);\n\t\t\tClipboard.SetText(content);\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\treturn context.DataGrid?.Name == \"MetadataView\"\n\t\t\t\t&& GetSelectedCellContent(context.OriginalSource) != null;\n\t\t}\n\n\t\tprivate static string GetSelectedCellContent(DependencyObject originalSource)\n\t\t{\n\t\t\tvar cell = originalSource.AncestorsAndSelf().OfType<DataGridCell>().FirstOrDefault();\n\n\t\t\treturn cell?.Column.OnCopyingCellClipboardContent(cell.DataContext).ToString();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/Heaps/BlobHeapTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class BlobHeapTreeNode : MetadataHeapTreeNode\n\t{\n\t\treadonly List<BlobHeapEntry> list;\n\n\t\tpublic BlobHeapTreeNode(MetadataFile metadataFile)\n\t\t\t: base(HandleKind.Blob, metadataFile)\n\t\t{\n\t\t\tlist = new List<BlobHeapEntry>();\n\n\t\t\tvar metadata = metadataFile.Metadata;\n\t\t\tBlobHandle handle = MetadataTokens.BlobHandle(0);\n\t\t\tdo\n\t\t\t{\n\t\t\t\tBlobHeapEntry entry = new BlobHeapEntry(metadata, handle);\n\t\t\t\tlist.Add(entry);\n\t\t\t\thandle = metadata.GetNextHandle(handle);\n\t\t\t} while (!handle.IsNil);\n\t\t}\n\n\t\tpublic override object Text => $\"Blob Heap ({list.Count})\";\n\n\t\tpublic override bool View(ViewModels.TabPageModel tabPage)\n\t\t{\n\t\t\ttabPage.Title = Text.ToString();\n\t\t\ttabPage.SupportsLanguageSwitching = false;\n\n\t\t\tvar view = Helpers.PrepareDataGrid(tabPage, this);\n\n\t\t\tview.ItemsSource = list;\n\n\t\t\ttabPage.Content = view;\n\n\t\t\treturn true;\n\t\t}\n\n\t\tclass BlobHeapEntry\n\t\t{\n\t\t\treadonly MetadataReader metadata;\n\t\t\treadonly BlobHandle handle;\n\n\t\t\tpublic int Offset => metadata.GetHeapOffset(handle);\n\n\t\t\tpublic int Length => metadata.GetBlobReader(handle).Length;\n\n\t\t\tpublic string Value => metadata.GetBlobReader(handle).ToHexString();\n\n\t\t\tpublic BlobHeapEntry(MetadataReader metadata, BlobHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadata = metadata;\n\t\t\t\tthis.handle = handle;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/Heaps/GuidHeapTreeNode.cs",
    "content": "// Copyright (c) 2021 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class GuidHeapTreeNode : MetadataHeapTreeNode\n\t{\n\t\treadonly List<GuidHeapEntry> list;\n\n\t\tpublic GuidHeapTreeNode(MetadataFile metadataFile)\n\t\t\t: base(HandleKind.Guid, metadataFile)\n\t\t{\n\t\t\tlist = new List<GuidHeapEntry>();\n\t\t\tvar metadata = metadataFile.Metadata;\n\t\t\tint count = metadata.GetHeapSize(HeapIndex.Guid) >> 4;\n\t\t\tfor (int i = 1; i <= count; i++)\n\t\t\t{\n\t\t\t\tGuidHeapEntry entry = new GuidHeapEntry(metadata, MetadataTokens.GuidHandle(i));\n\t\t\t\tlist.Add(entry);\n\t\t\t}\n\t\t}\n\n\t\tpublic override object Text => $\"Guid Heap ({list.Count})\";\n\n\t\tpublic override bool View(ViewModels.TabPageModel tabPage)\n\t\t{\n\t\t\ttabPage.Title = Text.ToString();\n\t\t\ttabPage.SupportsLanguageSwitching = false;\n\n\t\t\tvar view = Helpers.PrepareDataGrid(tabPage, this);\n\n\t\t\tview.ItemsSource = list;\n\n\t\t\ttabPage.Content = view;\n\n\t\t\treturn true;\n\t\t}\n\n\t\tclass GuidHeapEntry\n\t\t{\n\t\t\treadonly MetadataReader metadata;\n\t\t\treadonly GuidHandle handle;\n\n\t\t\tpublic int Index => metadata.GetHeapOffset(handle);\n\n\t\t\tpublic int Length => 16;\n\n\t\t\tpublic string Value => metadata.GetGuid(handle).ToString();\n\n\t\t\tpublic GuidHeapEntry(MetadataReader metadata, GuidHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadata = metadata;\n\t\t\t\tthis.handle = handle;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/Heaps/StringHeapTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class StringHeapTreeNode : MetadataHeapTreeNode\n\t{\n\t\treadonly List<StringHeapEntry> list;\n\n\t\tpublic StringHeapTreeNode(MetadataFile metadataFile)\n\t\t\t: base(HandleKind.String, metadataFile)\n\t\t{\n\t\t\tlist = new List<StringHeapEntry>();\n\t\t\tvar metadata = metadataFile.Metadata;\n\t\t\tStringHandle handle = MetadataTokens.StringHandle(0);\n\t\t\tdo\n\t\t\t{\n\t\t\t\tStringHeapEntry entry = new StringHeapEntry(metadata, handle);\n\t\t\t\tlist.Add(entry);\n\t\t\t\thandle = metadata.GetNextHandle(handle);\n\t\t\t} while (!handle.IsNil);\n\t\t}\n\n\t\tpublic override object Text => $\"String Heap ({list.Count})\";\n\n\t\tpublic override bool View(ViewModels.TabPageModel tabPage)\n\t\t{\n\t\t\ttabPage.Title = Text.ToString();\n\t\t\ttabPage.SupportsLanguageSwitching = false;\n\n\t\t\tvar view = Helpers.PrepareDataGrid(tabPage, this);\n\n\t\t\tview.ItemsSource = list;\n\n\t\t\ttabPage.Content = view;\n\n\t\t\treturn true;\n\t\t}\n\n\t\tclass StringHeapEntry\n\t\t{\n\t\t\treadonly MetadataReader metadata;\n\t\t\treadonly StringHandle handle;\n\n\t\t\tpublic int Offset => metadata.GetHeapOffset(handle);\n\n\t\t\tpublic int Length => metadata.GetString(handle).Length;\n\n\t\t\tpublic string Value => metadata.GetString(handle);\n\n\t\t\tpublic StringHeapEntry(MetadataReader metadata, StringHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadata = metadata;\n\t\t\t\tthis.handle = handle;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/Heaps/UserStringHeapTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal class UserStringHeapTreeNode : MetadataHeapTreeNode\n\t{\n\t\treadonly List<UserStringHeapEntry> list;\n\n\t\tpublic UserStringHeapTreeNode(MetadataFile metadataFile)\n\t\t\t: base(HandleKind.UserString, metadataFile)\n\t\t{\n\t\t\tlist = new List<UserStringHeapEntry>();\n\t\t\tvar metadata = metadataFile.Metadata;\n\t\t\tUserStringHandle handle = MetadataTokens.UserStringHandle(0);\n\t\t\tdo\n\t\t\t{\n\t\t\t\tUserStringHeapEntry entry = new UserStringHeapEntry(metadata, handle);\n\t\t\t\tlist.Add(entry);\n\t\t\t\thandle = metadata.GetNextHandle(handle);\n\t\t\t} while (!handle.IsNil);\n\t\t}\n\n\t\tpublic override object Text => $\"UserString Heap ({list.Count})\";\n\n\t\tpublic override bool View(ViewModels.TabPageModel tabPage)\n\t\t{\n\t\t\ttabPage.Title = Text.ToString();\n\t\t\ttabPage.SupportsLanguageSwitching = false;\n\n\t\t\tvar view = Helpers.PrepareDataGrid(tabPage, this);\n\n\t\t\tview.ItemsSource = list;\n\n\t\t\ttabPage.Content = view;\n\n\t\t\treturn true;\n\t\t}\n\n\t\tclass UserStringHeapEntry\n\t\t{\n\t\t\treadonly MetadataReader metadata;\n\t\t\treadonly UserStringHandle handle;\n\n\t\t\tpublic int Offset => metadata.GetHeapOffset(handle);\n\n\t\t\tpublic int Length => metadata.GetUserString(handle).Length;\n\n\t\t\tpublic string Value => metadata.GetUserString(handle);\n\n\t\t\tpublic UserStringHeapEntry(MetadataReader metadata, UserStringHandle handle)\n\t\t\t{\n\t\t\t\tthis.metadata = metadata;\n\t\t\t\tthis.handle = handle;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/Helpers.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Globalization;\nusing System.Linq;\nusing System.Reflection;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Runtime.CompilerServices;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Documents;\nusing System.Windows.Media;\nusing System.Windows.Navigation;\n\nusing DataGridExtensions;\n\nusing ICSharpCode.Decompiler.Util;\nusing ICSharpCode.ILSpy.Controls;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.ViewModels;\n\nusing TomsToolbox.Wpf.Interactivity;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tstatic class Helpers\n\t{\n\t\tpublic static DataGrid PrepareDataGrid(TabPageModel tabPage, ILSpyTreeNode selectedNode)\n\t\t{\n\t\t\tif (!(tabPage.Content is DataGrid view && view.Name == \"MetadataView\"))\n\t\t\t{\n\t\t\t\tview = new MetaDataGrid() {\n\t\t\t\t\tName = \"MetadataView\",\n\t\t\t\t\tGridLinesVisibility = DataGridGridLinesVisibility.None,\n\t\t\t\t\tCanUserAddRows = false,\n\t\t\t\t\tCanUserDeleteRows = false,\n\t\t\t\t\tCanUserReorderColumns = false,\n\t\t\t\t\tHeadersVisibility = DataGridHeadersVisibility.Column,\n\t\t\t\t\tEnableColumnVirtualization = true,\n\t\t\t\t\tEnableRowVirtualization = true,\n\t\t\t\t\tRowHeight = 20,\n\t\t\t\t\tIsReadOnly = true,\n\t\t\t\t\tSelectionMode = DataGridSelectionMode.Single,\n\t\t\t\t\tSelectionUnit = DataGridSelectionUnit.FullRow,\n\t\t\t\t\tSelectedTreeNode = selectedNode,\n\t\t\t\t\tCellStyle = (Style)MetadataTableViews.Instance[\"DataGridCellStyle\"],\n\t\t\t\t};\n\t\t\t\tContextMenuProvider.Add(view);\n\t\t\t\tDataGridFilter.SetIsAutoFilterEnabled(view, true);\n\t\t\t\tDataGridFilter.SetContentFilterFactory(view, new RegexContentFilterFactory());\n\t\t\t\tAdvancedScrollWheelBehavior.SetAttach(view, AdvancedScrollWheelMode.WithoutAnimation);\n\t\t\t}\n\t\t\tDataGridFilter.GetFilter(view).Clear();\n\t\t\tview.RowDetailsTemplateSelector = null;\n\t\t\tview.RowDetailsVisibilityMode = DataGridRowDetailsVisibilityMode.Collapsed;\n\t\t\tview.EnableColumnVirtualization = true;\n\t\t\tview.EnableRowVirtualization = true;\n\t\t\t((MetaDataGrid)view).SelectedTreeNode = selectedNode;\n\t\t\tif (!view.AutoGenerateColumns)\n\t\t\t\tview.Columns.Clear();\n\t\t\tview.AutoGenerateColumns = true;\n\n\t\t\tview.AutoGeneratingColumn += View_AutoGeneratingColumn;\n\t\t\tview.AutoGeneratedColumns += View_AutoGeneratedColumns;\n\n\t\t\treturn view;\n\t\t}\n\n\t\tinternal static void View_AutoGeneratedColumns(object sender, EventArgs e)\n\t\t{\n\t\t\t((DataGrid)sender).AutoGeneratedColumns -= View_AutoGeneratedColumns;\n\t\t\t((DataGrid)sender).AutoGeneratingColumn -= View_AutoGeneratingColumn;\n\t\t}\n\n\t\tinternal static void View_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)\n\t\t{\n\t\t\tvar binding = new Binding(e.PropertyName) { Mode = BindingMode.OneWay };\n\t\t\te.Column = GetColumn();\n\t\t\tswitch (e.PropertyName)\n\t\t\t{\n\t\t\t\tcase \"RID\":\n\t\t\t\tcase \"Meaning\":\n\t\t\t\t\te.Column.SetTemplate((ControlTemplate)MetadataTableViews.Instance[\"DefaultFilter\"]);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"Token\":\n\t\t\t\tcase \"Offset\":\n\t\t\t\tcase \"RVA\":\n\t\t\t\tcase \"StartOffset\":\n\t\t\t\tcase \"Length\":\n\t\t\t\t\tbinding.StringFormat = \"X8\";\n\t\t\t\t\te.Column.SetTemplate((ControlTemplate)MetadataTableViews.Instance[\"HexFilter\"]);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"RowDetails\":\n\t\t\t\t\te.Cancel = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"Value\" when e.PropertyDescriptor is PropertyDescriptor dp && dp.ComponentType == typeof(Entry):\n\t\t\t\t\tbinding.Path = new PropertyPath(\".\");\n\t\t\t\t\tbinding.Converter = ByteWidthConverter.Instance;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\te.Cancel = e.PropertyName.Contains(\"Tooltip\");\n\t\t\t\t\tif (!e.Cancel)\n\t\t\t\t\t{\n\t\t\t\t\t\te.Column.SetTemplate((ControlTemplate)MetadataTableViews.Instance[\"DefaultFilter\"]);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!e.Cancel)\n\t\t\t{\n\t\t\t\tApplyAttributes((PropertyDescriptor)e.PropertyDescriptor, binding, e.Column);\n\t\t\t}\n\n\t\t\tDataGridColumn GetColumn()\n\t\t\t{\n\t\t\t\tif (e.PropertyType == typeof(bool))\n\t\t\t\t{\n\t\t\t\t\treturn new DataGridCheckBoxColumn() {\n\t\t\t\t\t\tHeader = e.PropertyName,\n\t\t\t\t\t\tSortMemberPath = e.PropertyName,\n\t\t\t\t\t\tBinding = binding\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tvar descriptor = (PropertyDescriptor)e.PropertyDescriptor;\n\n\t\t\t\tif (descriptor.Attributes.OfType<ColumnInfoAttribute>().Any(c => c.Kind == ColumnKind.Token || c.LinkToTable))\n\t\t\t\t{\n\t\t\t\t\treturn new DataGridTemplateColumn() {\n\t\t\t\t\t\tHeader = e.PropertyName,\n\t\t\t\t\t\tSortMemberPath = e.PropertyName,\n\t\t\t\t\t\tCellTemplate = GetOrCreateLinkCellTemplate(e.PropertyName, descriptor, binding)\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\treturn new DataGridTextColumn() {\n\t\t\t\t\tHeader = e.PropertyName,\n\t\t\t\t\tSortMemberPath = e.PropertyName,\n\t\t\t\t\tBinding = binding\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tstatic readonly Dictionary<string, DataTemplate> linkCellTemplates = new Dictionary<string, DataTemplate>();\n\n\t\tprivate static DataTemplate GetOrCreateLinkCellTemplate(string name, PropertyDescriptor descriptor, Binding binding)\n\t\t{\n\t\t\tif (linkCellTemplates.TryGetValue(name, out var template))\n\t\t\t{\n\t\t\t\treturn template;\n\t\t\t}\n\n\t\t\tvar tb = new FrameworkElementFactory(typeof(TextBlock));\n\t\t\tvar hyper = new FrameworkElementFactory(typeof(Hyperlink));\n\t\t\ttb.AppendChild(hyper);\n\t\t\thyper.AddHandler(Hyperlink.ClickEvent, new RoutedEventHandler(Hyperlink_Click));\n\t\t\tvar run = new FrameworkElementFactory(typeof(Run));\n\t\t\thyper.AppendChild(run);\n\t\t\trun.SetBinding(Run.TextProperty, binding);\n\n\t\t\tDataTemplate dataTemplate = new DataTemplate() { VisualTree = tb };\n\t\t\tlinkCellTemplates.Add(name, dataTemplate);\n\t\t\treturn dataTemplate;\n\n\t\t\tvoid Hyperlink_Click(object sender, RoutedEventArgs e)\n\t\t\t{\n\t\t\t\tvar hyperlink = (Hyperlink)sender;\n\t\t\t\tvar onClickMethod = descriptor.ComponentType.GetMethod(\"On\" + name + \"Click\", BindingFlags.Instance | BindingFlags.Public);\n\t\t\t\tif (onClickMethod != null)\n\t\t\t\t{\n\t\t\t\t\tonClickMethod.Invoke(hyperlink.DataContext, Array.Empty<object>());\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic void ApplyAttributes(PropertyDescriptor descriptor, Binding binding, DataGridColumn column)\n\t\t{\n\t\t\tif (descriptor.PropertyType.IsEnum)\n\t\t\t{\n\t\t\t\tbinding.Converter = new UnderlyingEnumValueConverter();\n\t\t\t\tstring key = descriptor.PropertyType.Name + \"Filter\";\n\t\t\t\tcolumn.SetTemplate((ControlTemplate)MetadataTableViews.Instance[key]);\n\t\t\t}\n\t\t\tvar columnInfo = descriptor.Attributes.OfType<ColumnInfoAttribute>().FirstOrDefault();\n\t\t\tif (columnInfo != null)\n\t\t\t{\n\t\t\t\tbinding.StringFormat = columnInfo.Format;\n\t\t\t\tif (!descriptor.PropertyType.IsEnum\n\t\t\t\t\t&& columnInfo.Format.StartsWith(\"X\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t{\n\t\t\t\t\tcolumn.SetTemplate((ControlTemplate)MetadataTableViews.Instance[\"HexFilter\"]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t[Obsolete(\"Use safe GetValueLittleEndian(ReadOnlySpan<byte>) or appropriate BinaryPrimitives.Read* method\")]\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static unsafe int GetValue(byte* ptr, int size)\n\t\t\t=> GetValueLittleEndian(new ReadOnlySpan<byte>(ptr, size));\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static int GetValueLittleEndian(ReadOnlySpan<byte> ptr, int size)\n\t\t\t=> GetValueLittleEndian(ptr.Slice(0, size));\n\n\t\t[MethodImpl(MethodImplOptions.AggressiveInlining)]\n\t\tpublic static int GetValueLittleEndian(ReadOnlySpan<byte> ptr)\n\t\t{\n\t\t\tint result = 0;\n\t\t\tfor (int i = 0; i < ptr.Length; i += 2)\n\t\t\t{\n\t\t\t\tresult |= ptr[i] << 8 * i;\n\t\t\t\tresult |= ptr[i + 1] << 8 * (i + 1);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tstatic Helpers()\n\t\t{\n\t\t\trowCounts = typeof(MetadataReader)\n\t\t\t\t.GetField(\"TableRowCounts\", BindingFlags.NonPublic | BindingFlags.Instance);\n\t\t\tcomputeCodedTokenSize = typeof(MetadataReader)\n\t\t\t\t.GetMethod(\"ComputeCodedTokenSize\", BindingFlags.Instance | BindingFlags.NonPublic);\n\t\t\tfromTypeDefOrRefTag = typeof(TypeDefinitionHandle).Assembly\n\t\t\t\t.GetType(\"System.Reflection.Metadata.Ecma335.TypeDefOrRefTag\")\n\t\t\t\t.GetMethod(\"ConvertToHandle\", BindingFlags.Static | BindingFlags.NonPublic);\n\t\t\tfromHasFieldMarshalTag = typeof(TypeDefinitionHandle).Assembly\n\t\t\t\t.GetType(\"System.Reflection.Metadata.Ecma335.HasFieldMarshalTag\")\n\t\t\t\t.GetMethod(\"ConvertToHandle\", BindingFlags.Static | BindingFlags.NonPublic);\n\t\t\tfromMemberForwardedTag = typeof(TypeDefinitionHandle).Assembly\n\t\t\t\t.GetType(\"System.Reflection.Metadata.Ecma335.MemberForwardedTag\")\n\t\t\t\t.GetMethod(\"ConvertToHandle\", BindingFlags.Static | BindingFlags.NonPublic);\n\t\t}\n\n\t\treadonly static FieldInfo rowCounts;\n\t\treadonly static MethodInfo computeCodedTokenSize;\n\t\treadonly static MethodInfo fromTypeDefOrRefTag;\n\t\treadonly static MethodInfo fromHasFieldMarshalTag;\n\t\treadonly static MethodInfo fromMemberForwardedTag;\n\n\t\tpublic static EntityHandle FromHasFieldMarshalTag(uint tag)\n\t\t{\n\t\t\treturn (EntityHandle)fromHasFieldMarshalTag.Invoke(null, new object[] { tag });\n\t\t}\n\n\t\tpublic static EntityHandle FromMemberForwardedTag(uint tag)\n\t\t{\n\t\t\treturn (EntityHandle)fromMemberForwardedTag.Invoke(null, new object[] { tag });\n\t\t}\n\n\t\tpublic static EntityHandle FromTypeDefOrRefTag(uint tag)\n\t\t{\n\t\t\treturn (EntityHandle)fromTypeDefOrRefTag.Invoke(null, new object[] { tag });\n\t\t}\n\n\t\tpublic static int ComputeCodedTokenSize(this MetadataReader metadata, int largeRowSize,\n\t\t\tTableMask mask)\n\t\t{\n\t\t\treturn (int)computeCodedTokenSize.Invoke(metadata, new object[] {\n\t\t\t\tlargeRowSize, rowCounts.GetValue(metadata), (ulong)mask }\n\t\t\t);\n\t\t}\n\n\t\tclass UnderlyingEnumValueConverter : IValueConverter\n\t\t{\n\t\t\tpublic object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n\t\t\t{\n\t\t\t\tvar t = value.GetType();\n\t\t\t\tif (t.IsEnum)\n\t\t\t\t{\n\t\t\t\t\treturn (int)CSharpPrimitiveCast.Cast(TypeCode.Int32, value, false);\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t\tpublic object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n\t\t\t{\n\t\t\t\tthrow new NotImplementedException();\n\t\t\t}\n\t\t}\n\n\t\tpublic static string ReadUTF8StringNullTerminated(this ref BlobReader reader)\n\t\t{\n\t\t\tint length = reader.IndexOf(0);\n\t\t\tstring s = reader.ReadUTF8(length);\n\t\t\treader.ReadByte();\n\t\t\treturn s;\n\t\t}\n\t}\n\n\tenum ColumnKind\n\t{\n\t\tHeapOffset,\n\t\tToken,\n\t\tOther\n\t}\n\n\t[AttributeUsage(AttributeTargets.Property)]\n\tclass ColumnInfoAttribute : Attribute\n\t{\n\t\tpublic string Format { get; }\n\n\t\tpublic ColumnKind Kind { get; set; }\n\n\t\tpublic bool LinkToTable { get; set; }\n\n\t\tpublic ColumnInfoAttribute(string format)\n\t\t{\n\t\t\tthis.Format = format;\n\t\t}\n\t}\n\n\t[Flags]\n\tinternal enum TableMask : ulong\n\t{\n\t\tModule = 0x1,\n\t\tTypeRef = 0x2,\n\t\tTypeDef = 0x4,\n\t\tFieldPtr = 0x8,\n\t\tField = 0x10,\n\t\tMethodPtr = 0x20,\n\t\tMethodDef = 0x40,\n\t\tParamPtr = 0x80,\n\t\tParam = 0x100,\n\t\tInterfaceImpl = 0x200,\n\t\tMemberRef = 0x400,\n\t\tConstant = 0x800,\n\t\tCustomAttribute = 0x1000,\n\t\tFieldMarshal = 0x2000,\n\t\tDeclSecurity = 0x4000,\n\t\tClassLayout = 0x8000,\n\t\tFieldLayout = 0x10000,\n\t\tStandAloneSig = 0x20000,\n\t\tEventMap = 0x40000,\n\t\tEventPtr = 0x80000,\n\t\tEvent = 0x100000,\n\t\tPropertyMap = 0x200000,\n\t\tPropertyPtr = 0x400000,\n\t\tProperty = 0x800000,\n\t\tMethodSemantics = 0x1000000,\n\t\tMethodImpl = 0x2000000,\n\t\tModuleRef = 0x4000000,\n\t\tTypeSpec = 0x8000000,\n\t\tImplMap = 0x10000000,\n\t\tFieldRva = 0x20000000,\n\t\tEnCLog = 0x40000000,\n\t\tEnCMap = 0x80000000,\n\t\tAssembly = 0x100000000,\n\t\tAssemblyRef = 0x800000000,\n\t\tFile = 0x4000000000,\n\t\tExportedType = 0x8000000000,\n\t\tManifestResource = 0x10000000000,\n\t\tNestedClass = 0x20000000000,\n\t\tGenericParam = 0x40000000000,\n\t\tMethodSpec = 0x80000000000,\n\t\tGenericParamConstraint = 0x100000000000,\n\t\tDocument = 0x1000000000000,\n\t\tMethodDebugInformation = 0x2000000000000,\n\t\tLocalScope = 0x4000000000000,\n\t\tLocalVariable = 0x8000000000000,\n\t\tLocalConstant = 0x10000000000000,\n\t\tImportScope = 0x20000000000000,\n\t\tStateMachineMethod = 0x40000000000000,\n\t\tCustomDebugInformation = 0x80000000000000,\n\t\tPtrTables = 0x4800A8,\n\t\tEncTables = 0xC0000000,\n\t\tTypeSystemTables = 0x1FC9FFFFFFFF,\n\t\tDebugTables = 0xFF000000000000,\n\t\tAllTables = 0xFF1FC9FFFFFFFF,\n\t\tValidPortablePdbExternalTables = 0x1FC93FB7FF57\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/HexFilterControl.xaml",
    "content": "<Control x:Class=\"ICSharpCode.ILSpy.Metadata.HexFilterControl\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" \n             xmlns:local=\"clr-namespace:ICSharpCode.ILSpy.Metadata\"\n             xmlns:dgx=\"urn:tom-englert.de/DataGridExtensions\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"450\" d:DesignWidth=\"800\">\n\t<Control.Template>\n\t\t<ControlTemplate>\n\t\t\t<Grid>\n\t\t\t\t<Control Style=\"{DynamicResource {x:Static dgx:DataGridFilter.IconStyleKey}}\"/>\n\t\t\t\t<StackPanel x:Name=\"inputPanel\" Orientation=\"Horizontal\" Margin=\"4,0,0,0\">\n\t\t\t\t\t<TextBlock Text=\"0x\"/>\n\t\t\t\t\t<TextBox x:Name=\"textBox\" TextChanged=\"TextBox_TextChanged\" MinWidth=\"20\" Style=\"{DynamicResource {x:Static dgx:DataGridFilter.ColumnHeaderSearchTextBoxStyleKey}}\" />\n\t\t\t\t</StackPanel>\n\t\t\t</Grid>\n\t\t\t<ControlTemplate.Triggers>\n\t\t\t\t<Trigger SourceName=\"textBox\" Property=\"Text\" Value=\"\">\n\t\t\t\t\t<Setter TargetName=\"inputPanel\" Property=\"Opacity\" Value=\"0\"/>\n\t\t\t\t</Trigger>\n\t\t\t\t<Trigger Property=\"IsMouseOver\" Value=\"True\">\n\t\t\t\t\t<Setter TargetName=\"inputPanel\" Property=\"Opacity\" Value=\"1\"/>\n\t\t\t\t</Trigger>\n\t\t\t\t<Trigger SourceName=\"textBox\" Property=\"IsFocused\" Value=\"True\">\n\t\t\t\t\t<Setter TargetName=\"inputPanel\" Property=\"Opacity\" Value=\"1\"/>\n\t\t\t\t</Trigger>\n\t\t\t</ControlTemplate.Triggers>\n\t\t</ControlTemplate>\n\t</Control.Template>\n</Control>\n"
  },
  {
    "path": "ILSpy/Metadata/HexFilterControl.xaml.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Documents;\nusing System.Windows.Input;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\nusing System.Windows.Navigation;\nusing System.Windows.Shapes;\n\nusing DataGridExtensions;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\t/// <summary>\n\t/// Interaction logic for HexFilterControl.xaml\n\t/// </summary>\n\tpublic partial class HexFilterControl\n\t{\n\t\tTextBox textBox;\n\n\t\tpublic HexFilterControl()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\n\t\tpublic override void OnApplyTemplate()\n\t\t{\n\t\t\tbase.OnApplyTemplate();\n\t\t\ttextBox = Template.FindName(\"textBox\", this) as TextBox;\n\t\t}\n\n\t\tprivate void TextBox_TextChanged(object sender, TextChangedEventArgs e)\n\t\t{\n\t\t\tvar text = ((TextBox)sender)?.Text;\n\n\t\t\tFilter = new ContentFilter(text);\n\t\t}\n\n\t\tpublic IContentFilter Filter {\n\t\t\tget { return (IContentFilter)GetValue(FilterProperty); }\n\t\t\tset { SetValue(FilterProperty, value); }\n\t\t}\n\t\t/// <summary>\n\t\t/// Identifies the Filter dependency property\n\t\t/// </summary>\n\t\tpublic static readonly DependencyProperty FilterProperty =\n\t\t\tDependencyProperty.Register(\"Filter\", typeof(IContentFilter), typeof(HexFilterControl),\n\t\t\t\tnew FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (o, args) => ((HexFilterControl)o).Filter_Changed(args.NewValue)));\n\n\t\tvoid Filter_Changed(object newValue)\n\t\t{\n\t\t\tvar textBox = this.textBox;\n\t\t\tif (textBox == null)\n\t\t\t\treturn;\n\n\t\t\ttextBox.Text = (newValue as ContentFilter)?.Value ?? string.Empty;\n\t\t}\n\n\t\tclass ContentFilter : IContentFilter\n\t\t{\n\t\t\treadonly string filter;\n\n\t\t\tpublic ContentFilter(string filter)\n\t\t\t{\n\t\t\t\tthis.filter = filter;\n\t\t\t}\n\n\t\t\tpublic bool IsMatch(object value)\n\t\t\t{\n\t\t\t\tif (string.IsNullOrWhiteSpace(filter))\n\t\t\t\t\treturn true;\n\t\t\t\tif (value == null)\n\t\t\t\t\treturn false;\n\n\t\t\t\treturn string.Format(\"{0:x8}\", value).IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0;\n\t\t\t}\n\n\t\t\tpublic string Value => filter;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/MetaDataGrid.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Media;\n\nusing ICSharpCode.AvalonEdit.Rendering;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.ViewModels;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tclass MetaDataGrid : DataGrid, IHaveState\n\t{\n\t\tprivate readonly MouseHoverLogic hoverLogic;\n\t\tprivate ToolTip toolTip;\n\n\t\tpublic ILSpyTreeNode SelectedTreeNode { get; set; }\n\n\t\tpublic MetaDataGrid()\n\t\t{\n\t\t\tthis.hoverLogic = new MouseHoverLogic(this);\n\t\t\tthis.hoverLogic.MouseHover += HoverLogic_MouseHover;\n\t\t\tthis.hoverLogic.MouseHoverStopped += HoverLogic_MouseHoverStopped;\n\t\t}\n\n\t\tprivate void HoverLogic_MouseHoverStopped(object sender, System.Windows.Input.MouseEventArgs e)\n\t\t{\n\t\t\t// Non-popup tooltips get closed as soon as the mouse starts moving again\n\t\t\tif (toolTip != null)\n\t\t\t{\n\t\t\t\ttoolTip.IsOpen = false;\n\t\t\t\te.Handled = true;\n\t\t\t}\n\t\t}\n\n\t\tprivate void HoverLogic_MouseHover(object sender, System.Windows.Input.MouseEventArgs e)\n\t\t{\n\t\t\tvar position = e.GetPosition(this);\n\t\t\tvar hit = VisualTreeHelper.HitTest(this, position);\n\t\t\tif (hit == null)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar cell = hit.VisualHit.GetParent<DataGridCell>();\n\t\t\tif (cell == null)\n\t\t\t\treturn;\n\t\t\tvar data = cell.DataContext;\n\t\t\tvar name = (string)cell.Column.Header;\n\t\t\tif (toolTip == null)\n\t\t\t{\n\t\t\t\ttoolTip = new ToolTip();\n\t\t\t\ttoolTip.Closed += ToolTipClosed;\n\t\t\t}\n\t\t\ttoolTip.PlacementTarget = this; // required for property inheritance\n\n\t\t\tvar pi = data?.GetType().GetProperty(name + \"Tooltip\");\n\t\t\tif (pi == null)\n\t\t\t\treturn;\n\t\t\tobject tooltip = pi.GetValue(data);\n\t\t\tif (tooltip is string s)\n\t\t\t{\n\t\t\t\tif (string.IsNullOrWhiteSpace(s))\n\t\t\t\t\treturn;\n\t\t\t\ttoolTip.Content = new TextBlock {\n\t\t\t\t\tText = s,\n\t\t\t\t\tTextWrapping = TextWrapping.Wrap\n\t\t\t\t};\n\t\t\t}\n\t\t\telse if (tooltip != null)\n\t\t\t{\n\t\t\t\ttoolTip.Content = tooltip;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\te.Handled = true;\n\t\t\ttoolTip.IsOpen = true;\n\t\t}\n\n\t\tprivate void ToolTipClosed(object sender, RoutedEventArgs e)\n\t\t{\n\t\t\tif (toolTip == sender)\n\t\t\t{\n\t\t\t\ttoolTip = null;\n\t\t\t}\n\t\t}\n\n\t\tpublic ViewState GetState()\n\t\t{\n\t\t\treturn new ViewState {\n\t\t\t\tDecompiledNodes = SelectedTreeNode == null\n\t\t\t\t\t? null\n\t\t\t\t\t: new HashSet<ILSpyTreeNode>(new[] { SelectedTreeNode })\n\t\t\t};\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/MetadataHeapTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Reflection.Metadata;\nusing System.Windows.Controls;\nusing System.Windows.Threading;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal abstract class MetadataHeapTreeNode : ILSpyTreeNode\n\t{\n\t\tprotected MetadataFile metadataFile;\n\t\tprotected int scrollTarget;\n\n\t\tpublic HandleKind Kind { get; }\n\n\t\tpublic override object NavigationText => $\"{Text} ({metadataFile.Name})\";\n\n\t\tpublic override object Icon => Images.Heap;\n\n\t\tpublic MetadataHeapTreeNode(HandleKind kind, MetadataFile metadataFile)\n\t\t{\n\t\t\tthis.Kind = kind;\n\t\t\tthis.metadataFile = metadataFile;\n\t\t}\n\n\t\tprotected void ScrollItemIntoView(DataGrid view, object item)\n\t\t{\n\t\t\tview.Loaded += View_Loaded;\n\t\t\tview.Dispatcher.BeginInvoke(() => view.SelectItem(item), DispatcherPriority.Background);\n\t\t}\n\n\t\tprivate void View_Loaded(object sender, System.Windows.RoutedEventArgs e)\n\t\t{\n\t\t\tDataGrid view = (DataGrid)sender;\n\t\t\tvar sv = view.FindVisualChild<ScrollViewer>();\n\t\t\tsv.ScrollToVerticalOffset(scrollTarget - 1);\n\t\t\tview.Loaded -= View_Loaded;\n\t\t\tthis.scrollTarget = default;\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/MetadataProtocolHandler.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Linq;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\t[Export(typeof(IProtocolHandler))]\n\t[Shared]\n\tclass MetadataProtocolHandler(AssemblyTreeModel assemblyTreeModel) : IProtocolHandler\n\t{\n\t\tpublic ILSpyTreeNode Resolve(string protocol, MetadataFile module, Handle handle, out bool newTabPage)\n\t\t{\n\t\t\tnewTabPage = true;\n\t\t\tif (protocol != \"metadata\")\n\t\t\t\treturn null;\n\t\t\tvar assemblyTreeNode = assemblyTreeModel.FindTreeNode(module) as AssemblyTreeNode;\n\t\t\tif (assemblyTreeNode == null)\n\t\t\t\treturn null;\n\t\t\tvar mxNode = assemblyTreeNode.Children.OfType<MetadataTreeNode>().FirstOrDefault();\n\t\t\tif (mxNode != null)\n\t\t\t{\n\t\t\t\tmxNode.EnsureLazyChildren();\n\t\t\t\tvar node = mxNode.FindNodeByHandleKind(handle.Kind);\n\t\t\t\tnode?.ScrollTo(handle);\n\t\t\t\treturn node;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/MetadataTableTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Windows.Controls;\nusing System.Windows.Threading;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.ViewModels;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tinternal abstract class MetadataTableTreeNode : ILSpyTreeNode\n\t{\n\t\tprotected readonly MetadataFile metadataFile;\n\t\tprotected int scrollTarget;\n\n\t\tpublic TableIndex Kind { get; }\n\n\t\tpublic override object Text => $\"{(int)Kind:X2} {Kind} ({metadataFile.Metadata.GetTableRowCount(Kind)})\";\n\n\t\tpublic override object NavigationText => $\"{(int)Kind:X2} {Kind} ({metadataFile.Name})\";\n\n\t\tpublic override object Icon => Images.MetadataTable;\n\n\t\tpublic MetadataTableTreeNode(TableIndex table, MetadataFile metadataFile)\n\t\t{\n\t\t\tthis.Kind = table;\n\t\t\tthis.metadataFile = metadataFile;\n\t\t}\n\n\t\tinternal void ScrollTo(Handle handle)\n\t\t{\n\t\t\tthis.scrollTarget = metadataFile.Metadata.GetRowNumber((EntityHandle)handle);\n\t\t}\n\n\t\tprotected void ScrollRowIntoView(DataGrid view, int row)\n\t\t{\n\t\t\tif (!view.IsLoaded)\n\t\t\t{\n\t\t\t\tview.Loaded += View_Loaded;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tView_Loaded(view, new System.Windows.RoutedEventArgs());\n\t\t\t}\n\t\t\tif (view.Items.Count > row && row >= 0)\n\t\t\t\tview.Dispatcher.BeginInvoke(() => view.SelectItem(view.Items[row]), DispatcherPriority.Background);\n\t\t}\n\n\t\tprivate void View_Loaded(object sender, System.Windows.RoutedEventArgs e)\n\t\t{\n\t\t\tDataGrid view = (DataGrid)sender;\n\t\t\tvar sv = view.FindVisualChild<ScrollViewer>();\n\t\t\tsv.ScrollToVerticalOffset(scrollTarget - 1);\n\t\t\tview.Loaded -= View_Loaded;\n\t\t\tthis.scrollTarget = default;\n\t\t}\n\n\t\tprotected static string GenerateTooltip(ref string tooltip, MetadataFile module, EntityHandle handle)\n\t\t{\n\t\t\tif (tooltip == null)\n\t\t\t{\n\t\t\t\tif (handle.IsNil)\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tITextOutput output = new PlainTextOutput();\n\t\t\t\tvar context = new MetadataGenericContext(default(TypeDefinitionHandle), module.Metadata);\n\t\t\t\tvar metadata = module.Metadata;\n\t\t\t\tswitch (handle.Kind)\n\t\t\t\t{\n\t\t\t\t\tcase HandleKind.ModuleDefinition:\n\t\t\t\t\t\toutput.Write(metadata.GetString(metadata.GetModuleDefinition().Name));\n\t\t\t\t\t\toutput.Write(\" (this module)\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HandleKind.ModuleReference:\n\t\t\t\t\t\tModuleReference moduleReference = metadata.GetModuleReference((ModuleReferenceHandle)handle);\n\t\t\t\t\t\toutput.Write(metadata.GetString(moduleReference.Name));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HandleKind.AssemblyReference:\n\t\t\t\t\t\tvar asmRef = new Decompiler.Metadata.AssemblyReference(metadata, (AssemblyReferenceHandle)handle);\n\t\t\t\t\t\toutput.Write(asmRef.ToString());\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HandleKind.Parameter:\n\t\t\t\t\t\tvar param = metadata.GetParameter((ParameterHandle)handle);\n\t\t\t\t\t\toutput.Write(param.SequenceNumber + \" - \" + metadata.GetString(param.Name));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HandleKind.EventDefinition:\n\t\t\t\t\t\tvar @event = metadata.GetEventDefinition((EventDefinitionHandle)handle);\n\t\t\t\t\t\toutput.Write(metadata.GetString(@event.Name));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HandleKind.PropertyDefinition:\n\t\t\t\t\t\tvar prop = metadata.GetPropertyDefinition((PropertyDefinitionHandle)handle);\n\t\t\t\t\t\toutput.Write(metadata.GetString(prop.Name));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HandleKind.AssemblyDefinition:\n\t\t\t\t\t\tvar ad = metadata.GetAssemblyDefinition();\n\t\t\t\t\t\toutput.Write(metadata.GetString(ad.Name));\n\t\t\t\t\t\toutput.Write(\" (this assembly)\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HandleKind.AssemblyFile:\n\t\t\t\t\t\tvar af = metadata.GetAssemblyFile((AssemblyFileHandle)handle);\n\t\t\t\t\t\toutput.Write(metadata.GetString(af.Name));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HandleKind.GenericParameter:\n\t\t\t\t\t\tvar gp = metadata.GetGenericParameter((GenericParameterHandle)handle);\n\t\t\t\t\t\toutput.Write(metadata.GetString(gp.Name));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HandleKind.ManifestResource:\n\t\t\t\t\t\tvar mfr = metadata.GetManifestResource((ManifestResourceHandle)handle);\n\t\t\t\t\t\toutput.Write(metadata.GetString(mfr.Name));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase HandleKind.Document:\n\t\t\t\t\t\tvar doc = metadata.GetDocument((DocumentHandle)handle);\n\t\t\t\t\t\toutput.Write(metadata.GetString(doc.Name));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\thandle.WriteTo(module, output, context);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\ttooltip = \"(\" + handle.Kind + \") \" + output.ToString();\n\t\t\t}\n\t\t\treturn tooltip;\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t}\n\t}\n\n\tinternal abstract class MetadataTableTreeNode<TEntry> : MetadataTableTreeNode\n\t\twhere TEntry : struct\n\t{\n\t\tpublic MetadataTableTreeNode(TableIndex kind, MetadataFile metadataFile)\n\t\t\t: base(kind, metadataFile)\n\t\t{\n\t\t}\n\n\t\tprotected abstract IReadOnlyList<TEntry> LoadTable();\n\n\t\tprotected virtual void ConfigureDataGrid(DataGrid view)\n\t\t{\n\t\t}\n\n\t\tpublic override bool View(TabPageModel tabPage)\n\t\t{\n\t\t\ttabPage.Title = Text.ToString();\n\t\t\ttabPage.SupportsLanguageSwitching = false;\n\n\t\t\tvar view = Helpers.PrepareDataGrid(tabPage, this);\n\t\t\tConfigureDataGrid(view);\n\n\t\t\tview.ItemsSource = LoadTable();\n\t\t\ttabPage.Content = view;\n\n\t\t\tScrollRowIntoView(view, scrollTarget);\n\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tinternal abstract class DebugMetadataTableTreeNode<TEntry> : MetadataTableTreeNode<TEntry>\n\t\twhere TEntry : struct\n\t{\n\t\tpublic DebugMetadataTableTreeNode(TableIndex kind, MetadataFile metadataFile)\n\t\t\t: base(kind, metadataFile)\n\t\t{\n\t\t}\n\t}\n\n\tinternal class UnsupportedMetadataTableTreeNode : MetadataTableTreeNode\n\t{\n\t\tpublic UnsupportedMetadataTableTreeNode(TableIndex kind, MetadataFile file)\n\t\t\t: base(kind, file)\n\t\t{\n\t\t}\n\t\tpublic override object Text => $\"{(int)Kind:X2} {Kind.ToString()} [unsupported] ({metadataFile.Metadata.GetTableRowCount(Kind)})\";\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\toutput.WriteLine($\"Unsupported table '{(int)Kind:X2} {Kind}' contains {metadataFile.Metadata.GetTableRowCount(Kind)} rows.\");\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Metadata/MetadataTableViews.xaml",
    "content": "<ResourceDictionary x:Class=\"ICSharpCode.ILSpy.Metadata.MetadataTableViews\"\n\t\t\t xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n\t\t\t xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n\t\t\t xmlns:controls=\"clr-namespace:ICSharpCode.ILSpy.Controls\"\n\t\t\t xmlns:local=\"clr-namespace:ICSharpCode.ILSpy.Metadata\"\n\t\t\t xmlns:reflection=\"clr-namespace:System.Reflection;assembly=mscorlib\"\n\t\t\t xmlns:cecil=\"clr-namespace:Mono.Cecil;assembly=Mono.Cecil\"\n\t\t\t xmlns:srm=\"clr-namespace:System.Reflection;assembly=System.Reflection.Metadata\"\n\t\t\t xmlns:dgx=\"urn:tom-englert.de/DataGridExtensions\">\n\t\n\t<Style x:Key=\"DataGridCellStyle\" TargetType=\"{x:Type DataGridCell}\" BasedOn=\"{StaticResource {x:Type DataGridCell}}\">\n\t\t<Setter Property=\"BorderThickness\" Value=\"0\" />\n\t\t<Setter Property=\"Padding\" Value=\"2\" />\n\t\t<Setter Property=\"VerticalContentAlignment\" Value=\"Center\" />\n\t\t<Setter Property=\"Template\">\n\t\t\t<Setter.Value>\n\t\t\t\t<ControlTemplate TargetType=\"{x:Type DataGridCell}\">\n\t\t\t\t\t<Border x:Name=\"Bd\"\n\t\t\t\t\t\t\tBorderBrush=\"{TemplateBinding BorderBrush}\"\n\t\t\t\t\t\t\tBorderThickness=\"{TemplateBinding BorderThickness}\"\n\t\t\t\t\t\t\tBackground=\"{TemplateBinding Background}\"\n\t\t\t\t\t\t\tSnapsToDevicePixels=\"True\">\n\t\t\t\t\t\t<ContentPresenter ContentTemplate=\"{TemplateBinding ContentTemplate}\"\n\t\t\t\t\t\t\t\t\t\t  Content=\"{TemplateBinding Content}\"\n\t\t\t\t\t\t\t\t\t\t  ContentStringFormat=\"{TemplateBinding ContentStringFormat}\"\n\t\t\t\t\t\t\t\t\t\t  SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\"\n\t\t\t\t\t\t\t\t\t\t  Margin=\"{TemplateBinding Padding}\"\n\t\t\t\t\t\t\t\t\t\t  HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\"\n\t\t\t\t\t\t\t\t\t\t  VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\" />\n\t\t\t\t\t</Border>\n\t\t\t\t</ControlTemplate>\n\t\t\t</Setter.Value>\n\t\t</Setter>\n\t</Style>\n\n\t<ControlTemplate x:Key=\"DefaultFilter\">\n\t\t<Grid>\n\t\t\t<Control Style=\"{DynamicResource {x:Static dgx:DataGridFilter.IconStyleKey}}\" />\n\t\t\t<TextBox Style=\"{DynamicResource {x:Static dgx:DataGridFilter.ColumnHeaderSearchTextBoxStyleKey}}\"\n\t\t\t\tText=\"{Binding Path=Filter, UpdateSourceTrigger=PropertyChanged}\" />\n\t\t</Grid>\n\t</ControlTemplate>\n\n\t<ControlTemplate x:Key=\"HexFilter\">\n\t\t<local:HexFilterControl Filter=\"{Binding Path=Filter, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dgx:DataGridFilterColumnControl}}\" />\n\t</ControlTemplate>\n\n\t<ControlTemplate x:Key=\"AssemblyFlagsFilter\">\n\t\t<local:FlagsFilterControl FlagsType=\"{x:Type srm:AssemblyFlags}\" Filter=\"{Binding Path=Filter, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dgx:DataGridFilterColumnControl}}\" />\n\t</ControlTemplate>\n\n\t<ControlTemplate x:Key=\"AssemblyHashAlgorithmFilter\">\n\t\t<local:FlagsFilterControl FlagsType=\"{x:Type srm:AssemblyHashAlgorithm}\" Filter=\"{Binding Path=Filter, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dgx:DataGridFilterColumnControl}}\" />\n\t</ControlTemplate>\n\n\t<ControlTemplate x:Key=\"MethodAttributesFilter\">\n\t\t<local:FlagsFilterControl FlagsType=\"{x:Type reflection:MethodAttributes}\" Filter=\"{Binding Path=Filter, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dgx:DataGridFilterColumnControl}}\" />\n\t</ControlTemplate>\n\n\t<ControlTemplate x:Key=\"MethodImplAttributesFilter\">\n\t\t<local:FlagsFilterControl FlagsType=\"{x:Type reflection:MethodImplAttributes}\" Filter=\"{Binding Path=Filter, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dgx:DataGridFilterColumnControl}}\" />\n\t</ControlTemplate>\n\n\t<ControlTemplate x:Key=\"MethodSemanticsAttributesFilter\">\n\t\t<local:FlagsFilterControl FlagsType=\"{x:Type srm:MethodSemanticsAttributes}\" Filter=\"{Binding Path=Filter, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dgx:DataGridFilterColumnControl}}\" />\n\t</ControlTemplate>\n\n\t<ControlTemplate x:Key=\"TypeAttributesFilter\">\n\t\t<local:FlagsFilterControl FlagsType=\"{x:Type reflection:TypeAttributes}\" Filter=\"{Binding Path=Filter, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dgx:DataGridFilterColumnControl}}\" />\n\t</ControlTemplate>\n\n\t<ControlTemplate x:Key=\"PropertyAttributesFilter\">\n\t\t<local:FlagsFilterControl FlagsType=\"{x:Type reflection:PropertyAttributes}\" Filter=\"{Binding Path=Filter, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dgx:DataGridFilterColumnControl}}\" />\n\t</ControlTemplate>\n\n\t<ControlTemplate x:Key=\"EventAttributesFilter\">\n\t\t<local:FlagsFilterControl FlagsType=\"{x:Type reflection:EventAttributes}\" Filter=\"{Binding Path=Filter, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dgx:DataGridFilterColumnControl}}\" />\n\t</ControlTemplate>\n\n\t<ControlTemplate x:Key=\"FieldAttributesFilter\">\n\t\t<local:FlagsFilterControl FlagsType=\"{x:Type reflection:FieldAttributes}\" Filter=\"{Binding Path=Filter, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dgx:DataGridFilterColumnControl}}\" />\n\t</ControlTemplate>\n\n\t<ControlTemplate x:Key=\"ManifestResourceAttributesFilter\">\n\t\t<local:FlagsFilterControl FlagsType=\"{x:Type srm:ManifestResourceAttributes}\" Filter=\"{Binding Path=Filter, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dgx:DataGridFilterColumnControl}}\" />\n\t</ControlTemplate>\n\n\t<ControlTemplate x:Key=\"GenericParameterAttributesFilter\">\n\t\t<local:FlagsFilterControl FlagsType=\"{x:Type reflection:GenericParameterAttributes}\" Filter=\"{Binding Path=Filter, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dgx:DataGridFilterColumnControl}}\" />\n\t</ControlTemplate>\n\n\t<ControlTemplate x:Key=\"PInvokeAttributesFilter\">\n\t\t<local:FlagsFilterControl FlagsType=\"{x:Type cecil:PInvokeAttributes}\" Filter=\"{Binding Path=Filter, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dgx:DataGridFilterColumnControl}}\" />\n\t</ControlTemplate>\n\n\t<Style x:Key=\"ItemContainerStyle\" TargetType=\"ListViewItem\">\n\t\t<Setter Property=\"HorizontalContentAlignment\" Value=\"Stretch\"/>\n\t</Style>\n\n\t<local:ByteWidthConverter x:Key=\"byteWidthConverter\" />\n\n\t<DataTemplate x:Key=\"CustomDebugInformationDetailsDataGrid\">\n\t\t<DataGrid ItemsSource=\"{Binding RowDetails, Mode=OneWay}\" GridLinesVisibility=\"None\" CanUserAddRows=\"False\"\n\t\t\t\t  CanUserDeleteRows=\"False\" CanUserReorderColumns=\"False\" HeadersVisibility=\"Column\" EnableColumnVirtualization=\"True\"\n\t\t\t\t  EnableRowVirtualization=\"True\" RowHeight=\"20\" IsReadOnly=\"True\" SelectionMode=\"Single\" SelectionUnit=\"FullRow\"\n\t\t\t\t  AutoGenerateColumns=\"True\" VerticalContentAlignment=\"Center\" AutoGeneratedColumns=\"DataGrid_AutoGeneratedColumns\" AutoGeneratingColumn=\"DataGrid_AutoGeneratingColumn\"\n\t\t\t\t  CellStyle=\"{StaticResource DataGridCellStyle}\" MaxHeight=\"250\">\n\t\t</DataGrid>\n\t</DataTemplate>\n\n\t<DataTemplate x:Key=\"CustomDebugInformationDetailsTextBlob\">\n\t\t<Grid MinWidth=\"800\" MaxWidth=\"800\" HorizontalAlignment=\"Left\">\n\t\t\t<Grid.ColumnDefinitions>\n\t\t\t\t<ColumnDefinition Width=\"*\" />\n\t\t\t</Grid.ColumnDefinitions>\n\t\t\t<TextBox IsReadOnly=\"True\" TextWrapping=\"Wrap\" IsReadOnlyCaretVisible=\"True\" Text=\"{Binding RowDetails, Mode=OneWay}\"\n\t\t\t\t\tMinLines=\"10\" MaxLines=\"25\" />\n\t\t</Grid>\n\t</DataTemplate>\n\n\t<DataTemplate x:Key=\"HeaderFlagsDetailsDataGrid\">\n\t\t<DataGrid ItemsSource=\"{Binding RowDetails, Mode=OneWay}\" GridLinesVisibility=\"None\" CanUserAddRows=\"False\"\n\t\t\t\t  CanUserDeleteRows=\"False\" CanUserReorderColumns=\"False\" RowHeaderWidth=\"0\" EnableColumnVirtualization=\"True\"\n\t\t\t\t  EnableRowVirtualization=\"True\" RowHeight=\"20\" HeadersVisibility=\"None\" IsReadOnly=\"True\" SelectionMode=\"Single\" SelectionUnit=\"FullRow\"\n\t\t\t\t  VerticalContentAlignment=\"Center\">\n\t\t</DataGrid>\n\t</DataTemplate>\n</ResourceDictionary>\n"
  },
  {
    "path": "ILSpy/Metadata/MetadataTableViews.xaml.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Documents;\nusing System.Windows.Input;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\nusing System.Windows.Navigation;\nusing System.Windows.Shapes;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\t/// <summary>\n\t/// Interaction logic for MetadataTableViews.xaml\n\t/// </summary>\n\tpublic partial class MetadataTableViews : ResourceDictionary\n\t{\n\t\tpublic MetadataTableViews()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\n\t\tstatic MetadataTableViews instance;\n\n\t\tpublic static MetadataTableViews Instance {\n\t\t\tget {\n\t\t\t\tif (instance == null)\n\t\t\t\t{\n\t\t\t\t\tinstance = new MetadataTableViews();\n\t\t\t\t}\n\t\t\t\treturn instance;\n\t\t\t}\n\t\t}\n\n\t\tprivate void DataGrid_AutoGeneratedColumns(object sender, EventArgs e)\n\t\t{\n\t\t\tHelpers.View_AutoGeneratedColumns(sender, e);\n\t\t}\n\n\t\tprivate void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)\n\t\t{\n\t\t\tHelpers.View_AutoGeneratingColumn(sender, e);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/MetadataTablesTreeNode.cs",
    "content": "// Copyright (c) 2021 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.ViewModels;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tclass MetadataTablesTreeNode : ILSpyTreeNode\n\t{\n\t\treadonly MetadataFile metadataFile;\n\n\t\tpublic MetadataTablesTreeNode(MetadataFile metadataFile)\n\t\t{\n\t\t\tthis.metadataFile = metadataFile;\n\t\t\tthis.LazyLoading = true;\n\t\t}\n\n\t\tpublic override object Text => \"Tables\";\n\n\t\tpublic override object NavigationText => $\"{Text} ({metadataFile.Name})\";\n\n\t\tpublic override object Icon => Images.MetadataTableGroup;\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tforeach (var table in Enum.GetValues<TableIndex>())\n\t\t\t{\n\t\t\t\tif (ShowTable(table, metadataFile.Metadata))\n\t\t\t\t\tthis.Children.Add(CreateTableTreeNode(table, metadataFile));\n\t\t\t}\n\t\t}\n\n\t\tinternal static bool ShowTable(TableIndex table, MetadataReader metadata) => !SettingsService.DisplaySettings.HideEmptyMetadataTables || metadata.GetTableRowCount(table) > 0;\n\n\t\tinternal static MetadataTableTreeNode CreateTableTreeNode(TableIndex table, MetadataFile metadataFile)\n\t\t{\n\t\t\tswitch (table)\n\t\t\t{\n\t\t\t\tcase TableIndex.Module:\n\t\t\t\t\treturn new ModuleTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.TypeRef:\n\t\t\t\t\treturn new TypeRefTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.TypeDef:\n\t\t\t\t\treturn new TypeDefTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.Field:\n\t\t\t\t\treturn new FieldTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.MethodDef:\n\t\t\t\t\treturn new MethodTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.Param:\n\t\t\t\t\treturn new ParamTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.InterfaceImpl:\n\t\t\t\t\treturn new InterfaceImplTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.MemberRef:\n\t\t\t\t\treturn new MemberRefTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.Constant:\n\t\t\t\t\treturn new ConstantTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.CustomAttribute:\n\t\t\t\t\treturn new CustomAttributeTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.FieldMarshal:\n\t\t\t\t\treturn new FieldMarshalTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.DeclSecurity:\n\t\t\t\t\treturn new DeclSecurityTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.ClassLayout:\n\t\t\t\t\treturn new ClassLayoutTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.FieldLayout:\n\t\t\t\t\treturn new FieldLayoutTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.StandAloneSig:\n\t\t\t\t\treturn new StandAloneSigTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.EventMap:\n\t\t\t\t\treturn new EventMapTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.Event:\n\t\t\t\t\treturn new EventTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.PropertyMap:\n\t\t\t\t\treturn new PropertyMapTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.Property:\n\t\t\t\t\treturn new PropertyTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.MethodSemantics:\n\t\t\t\t\treturn new MethodSemanticsTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.MethodImpl:\n\t\t\t\t\treturn new MethodImplTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.ModuleRef:\n\t\t\t\t\treturn new ModuleRefTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.TypeSpec:\n\t\t\t\t\treturn new TypeSpecTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.ImplMap:\n\t\t\t\t\treturn new ImplMapTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.FieldRva:\n\t\t\t\t\treturn new FieldRVATableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.Assembly:\n\t\t\t\t\treturn new AssemblyTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.AssemblyRef:\n\t\t\t\t\treturn new AssemblyRefTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.File:\n\t\t\t\t\treturn new FileTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.ExportedType:\n\t\t\t\t\treturn new ExportedTypeTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.ManifestResource:\n\t\t\t\t\treturn new ManifestResourceTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.NestedClass:\n\t\t\t\t\treturn new NestedClassTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.GenericParam:\n\t\t\t\t\treturn new GenericParamTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.MethodSpec:\n\t\t\t\t\treturn new MethodSpecTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.GenericParamConstraint:\n\t\t\t\t\treturn new GenericParamConstraintTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.Document:\n\t\t\t\t\treturn new DocumentTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.MethodDebugInformation:\n\t\t\t\t\treturn new MethodDebugInformationTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.LocalScope:\n\t\t\t\t\treturn new LocalScopeTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.LocalVariable:\n\t\t\t\t\treturn new LocalVariableTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.LocalConstant:\n\t\t\t\t\treturn new LocalConstantTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.ImportScope:\n\t\t\t\t\treturn new ImportScopeTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.StateMachineMethod:\n\t\t\t\t\treturn new StateMachineMethodTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.CustomDebugInformation:\n\t\t\t\t\treturn new CustomDebugInformationTableTreeNode(metadataFile);\n\t\t\t\tcase TableIndex.FieldPtr:\n\t\t\t\tcase TableIndex.EventPtr:\n\t\t\t\tcase TableIndex.MethodPtr:\n\t\t\t\tcase TableIndex.ParamPtr:\n\t\t\t\tcase TableIndex.PropertyPtr:\n\t\t\t\t\treturn new PtrTableTreeNode(table, metadataFile);\n\t\t\t\tdefault:\n\t\t\t\t\treturn new UnsupportedMetadataTableTreeNode(table, metadataFile);\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool View(TabPageModel tabPage)\n\t\t{\n\t\t\ttabPage.Title = Text.ToString();\n\t\t\ttabPage.SupportsLanguageSwitching = false;\n\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.WriteCommentLine(output, \"Metadata Tables\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/MetadataTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Windows.Data;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.ViewModels;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tclass MetadataTreeNode : ILSpyTreeNode\n\t{\n\t\tprivate readonly MetadataFile metadataFile;\n\t\tprivate readonly string title;\n\n\t\tpublic MetadataTreeNode(MetadataFile module, string title)\n\t\t{\n\t\t\tthis.metadataFile = module;\n\t\t\tthis.title = title;\n\t\t\tthis.LazyLoading = true;\n\t\t}\n\n\t\tpublic override object Text => title;\n\n\t\tpublic override object NavigationText => $\"{Text} ({metadataFile.Name})\";\n\n\t\tpublic override object Icon => Images.Metadata;\n\n\t\tpublic override bool View(TabPageModel tabPage)\n\t\t{\n\t\t\ttabPage.Title = Text.ToString();\n\t\t\ttabPage.SupportsLanguageSwitching = false;\n\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.WriteCommentLine(output, title);\n\n\t\t\tDumpMetadataInfo(language, output, this.metadataFile.Metadata);\n\t\t}\n\n\t\tinternal static void DumpMetadataInfo(Language language, ITextOutput output, MetadataReader metadata)\n\t\t{\n\t\t\tlanguage.WriteCommentLine(output, \"MetadataKind: \" + metadata.MetadataKind);\n\t\t\tlanguage.WriteCommentLine(output, \"MetadataVersion: \" + metadata.MetadataVersion);\n\n\t\t\tif (metadata.DebugMetadataHeader is { } header)\n\t\t\t{\n\t\t\t\toutput.WriteLine();\n\t\t\t\tlanguage.WriteCommentLine(output, \"Header:\");\n\t\t\t\tlanguage.WriteCommentLine(output, \"Id: \" + header.Id.ToHexString(header.Id.Length));\n\t\t\t\tlanguage.WriteCommentLine(output, \"EntryPoint: \" + MetadataTokens.GetToken(header.EntryPoint).ToString(\"X8\"));\n\t\t\t}\n\n\t\t\toutput.WriteLine();\n\t\t\tlanguage.WriteCommentLine(output, \"Tables:\");\n\n\t\t\tforeach (var table in Enum.GetValues<TableIndex>())\n\t\t\t{\n\t\t\t\tint count = metadata.GetTableRowCount(table);\n\t\t\t\tif (count > 0)\n\t\t\t\t{\n\t\t\t\t\tlanguage.WriteCommentLine(output, $\"{(byte)table:X2} {table}: {count} rows\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tif (metadataFile is PEFile module)\n\t\t\t{\n\t\t\t\tthis.Children.Add(new DosHeaderTreeNode(module));\n\t\t\t\tthis.Children.Add(new CoffHeaderTreeNode(module));\n\t\t\t\tthis.Children.Add(new OptionalHeaderTreeNode(module));\n\t\t\t\tthis.Children.Add(new DataDirectoriesTreeNode(module));\n\t\t\t\tthis.Children.Add(new DebugDirectoryTreeNode(module));\n\t\t\t}\n\t\t\tthis.Children.Add(new MetadataTablesTreeNode(metadataFile));\n\t\t\tthis.Children.Add(new StringHeapTreeNode(metadataFile));\n\t\t\tthis.Children.Add(new UserStringHeapTreeNode(metadataFile));\n\t\t\tthis.Children.Add(new GuidHeapTreeNode(metadataFile));\n\t\t\tthis.Children.Add(new BlobHeapTreeNode(metadataFile));\n\t\t}\n\n\t\tpublic MetadataTableTreeNode FindNodeByHandleKind(HandleKind kind)\n\t\t{\n\t\t\treturn this.Children.OfType<MetadataTablesTreeNode>().Single()\n\t\t\t\t.Children.OfType<MetadataTableTreeNode>().SingleOrDefault(x => x.Kind == (TableIndex)kind);\n\t\t}\n\t}\n\n\tclass Entry\n\t{\n\t\tpublic string Member { get; }\n\t\tpublic int Offset { get; }\n\t\tpublic int Size { get; }\n\t\tpublic object Value { get; }\n\t\tpublic string Meaning { get; }\n\n\t\tpublic IList<BitEntry> RowDetails { get; }\n\n\t\tpublic Entry(int offset, object value, int size, string member, string meaning, IList<BitEntry> rowDetails = null)\n\t\t{\n\t\t\tthis.Member = member;\n\t\t\tthis.Offset = offset;\n\t\t\tthis.Size = size;\n\t\t\tthis.Value = value;\n\t\t\tthis.Meaning = meaning;\n\t\t\tthis.RowDetails = rowDetails;\n\t\t}\n\t}\n\n\tclass BitEntry\n\t{\n\t\tpublic bool Value { get; }\n\t\tpublic string Meaning { get; }\n\n\t\tpublic BitEntry(bool value, string meaning)\n\t\t{\n\t\t\tthis.Value = value;\n\t\t\tthis.Meaning = meaning;\n\t\t}\n\t}\n\n\tclass ByteWidthConverter : IValueConverter\n\t{\n\t\tpublic static readonly ByteWidthConverter Instance = new ByteWidthConverter();\n\n\t\tpublic object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n\t\t{\n\t\t\treturn string.Format(\"{0:X\" + 2 * ((Entry)value).Size + \"}\", ((Entry)value).Value);\n\t\t}\n\n\t\tpublic object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Metadata/OptionalHeaderTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Reflection.PortableExecutable;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpyX.Extensions;\n\nusing TomsToolbox.Essentials;\n\nnamespace ICSharpCode.ILSpy.Metadata\n{\n\tclass OptionalHeaderTreeNode : ILSpyTreeNode\n\t{\n\t\tprivate PEFile module;\n\n\t\tpublic OptionalHeaderTreeNode(PEFile module)\n\t\t{\n\t\t\tthis.module = module;\n\t\t}\n\n\t\tpublic override object Text => \"Optional Header\";\n\n\t\tpublic override object NavigationText => $\"{Text} ({module.Name})\";\n\n\t\tpublic override object Icon => Images.Header;\n\n\t\tpublic override bool View(ViewModels.TabPageModel tabPage)\n\t\t{\n\t\t\ttabPage.Title = Text.ToString();\n\t\t\ttabPage.SupportsLanguageSwitching = false;\n\n\t\t\tvar dataGrid = Helpers.PrepareDataGrid(tabPage, this);\n\n\t\t\tdataGrid.RowDetailsTemplateSelector = new CharacteristicsDataTemplateSelector(\"DLL Characteristics\");\n\t\t\tdataGrid.RowDetailsVisibilityMode = DataGridRowDetailsVisibilityMode.Collapsed;\n\n\t\t\tdataGrid.Columns.Clear();\n\t\t\tdataGrid.AutoGenerateColumns = false;\n\t\t\tdataGrid.Columns.AddRange(\n\t\t\t\tnew[] {\n\t\t\t\t\tnew DataGridTextColumn { IsReadOnly = true, Header = \"Member\", Binding = new Binding(\"Member\") },\n\t\t\t\t\tnew DataGridTextColumn { IsReadOnly = true, Header = \"Offset\", Binding = new Binding(\"Offset\") { StringFormat = \"X8\" } },\n\t\t\t\t\tnew DataGridTextColumn { IsReadOnly = true, Header = \"Size\", Binding = new Binding(\"Size\") },\n\t\t\t\t\tnew DataGridTextColumn { IsReadOnly = true, Header = \"Value\", Binding = new Binding(\".\") { Converter = ByteWidthConverter.Instance } },\n\t\t\t\t\tnew DataGridTextColumn { IsReadOnly = true, Header = \"Meaning\", Binding = new Binding(\"Meaning\") }\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tvar headers = module.Reader.PEHeaders;\n\t\t\tvar reader = module.Reader.GetEntireImage().GetReader(headers.PEHeaderStartOffset, 128);\n\t\t\tvar header = headers.PEHeader;\n\t\t\tvar isPE32Plus = (header.Magic == PEMagic.PE32Plus);\n\n\t\t\tvar entries = new List<Entry>();\n\t\t\tushort dllCharacteristics;\n\t\t\tEntry characteristics;\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadUInt16(), 2, \"Magic\", header.Magic.ToString()));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadByte(), 1, \"Major Linker Version\", \"\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadByte(), 1, \"Minor Linker Version\", \"\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadInt32(), 4, \"Code Size\", \"Size of the code (text) section, or the sum of all code sections if there are multiple sections.\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadInt32(), 4, \"Initialized Data Size\", \"Size of the initialized data section, or the sum of all initialized data sections if there are multiple data sections.\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadInt32(), 4, \"Uninitialized Data Size\", \"Size of the uninitialized data section, or the sum of all uninitialized data sections if there are multiple uninitialized data sections.\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadInt32(), 4, \"Entry Point RVA\", \"RVA of entry point, needs to point to bytes 0xFF 0x25 followed by the RVA in a section marked execute / read for EXEs or 0 for DLLs\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadInt32(), 4, \"Base Of Code\", \"RVA of the code section.\"));\n\t\t\tentries.Add(new Entry(isPE32Plus ? 0 : headers.PEHeaderStartOffset + reader.Offset, isPE32Plus ? 0UL : reader.ReadUInt32(), isPE32Plus ? 0 : 4, \"Base Of Data\", \"PE32 only (not present in PE32Plus): RVA of the data section, relative to the Image Base.\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, isPE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), isPE32Plus ? 8 : 4, \"Image Base\", \"Shall be a multiple of 0x10000.\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadInt32(), 4, \"Section Alignment\", \"Shall be greater than File Alignment.\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadInt32(), 4, \"File Alignment\", \"\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadUInt16(), 2, \"Major OS Version\", \"\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadUInt16(), 2, \"Minor OS Version\", \"\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadUInt16(), 2, \"Major Image Version\", \"\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadUInt16(), 2, \"Minor Image Version\", \"\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadUInt16(), 2, \"Major Subsystem Version\", \"\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadUInt16(), 2, \"Minor Subsystem Version\", \"\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadUInt32(), 4, \"Win32VersionValue\", \"\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadInt32(), 4, \"Image Size\", \"Size, in bytes, of image, including all headers and padding; shall be a multiple of Section Alignment.\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadInt32(), 4, \"Header Size\", \"Combined size of MS-DOS Header, PE Header, PE Optional Header and padding; shall be a multiple of the file alignment.\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadInt32(), 4, \"File Checksum\", \"\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadUInt16(), 2, \"Subsystem\", header.Subsystem.ToString()));\n\t\t\tentries.Add(characteristics = new Entry(headers.PEHeaderStartOffset + reader.Offset, dllCharacteristics = reader.ReadUInt16(), 2, \"DLL Characteristics\", header.DllCharacteristics.ToString(), new[] {\n\t\t\t\t\tnew BitEntry((dllCharacteristics & 0x0001) != 0, \"<0001> Process Init (Reserved)\"),\n\t\t\t\t\tnew BitEntry((dllCharacteristics & 0x0002) != 0, \"<0002> Process Term (Reserved)\"),\n\t\t\t\t\tnew BitEntry((dllCharacteristics & 0x0004) != 0, \"<0004> Thread Init (Reserved)\"),\n\t\t\t\t\tnew BitEntry((dllCharacteristics & 0x0008) != 0, \"<0008> Thread Term (Reserved)\"),\n\t\t\t\t\tnew BitEntry((dllCharacteristics & 0x0010) != 0, \"<0010> Unused\"),\n\t\t\t\t\tnew BitEntry((dllCharacteristics & 0x0020) != 0, \"<0020> Image can handle a high entropy 64-bit virtual address space (ASLR)\"),\n\t\t\t\t\tnew BitEntry((dllCharacteristics & 0x0040) != 0, \"<0040> DLL can be relocated at load time\"),\n\t\t\t\t\tnew BitEntry((dllCharacteristics & 0x0080) != 0, \"<0080> Code integrity checks are enforced\"),\n\t\t\t\t\tnew BitEntry((dllCharacteristics & 0x0100) != 0, \"<0100> Image is NX compatible\"),\n\t\t\t\t\tnew BitEntry((dllCharacteristics & 0x0200) != 0, \"<0200> Isolation aware, but do not isolate the image\"),\n\t\t\t\t\tnew BitEntry((dllCharacteristics & 0x0400) != 0, \"<0400> Does not use structured exception handling (SEH)\"),\n\t\t\t\t\tnew BitEntry((dllCharacteristics & 0x0800) != 0, \"<0800> Do not bind the image\"),\n\t\t\t\t\tnew BitEntry((dllCharacteristics & 0x1000) != 0, \"<1000> Image must execute in an AppContainer\"),\n\t\t\t\t\tnew BitEntry((dllCharacteristics & 0x2000) != 0, \"<2000> Driver is a WDM Driver\"),\n\t\t\t\t\tnew BitEntry((dllCharacteristics & 0x4000) != 0, \"<4000> Image supports Control Flow Guard\"),\n\t\t\t\t\tnew BitEntry((dllCharacteristics & 0x8000) != 0, \"<8000> Image is Terminal Server aware\"),\n\t\t\t\t}));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, isPE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), isPE32Plus ? 8 : 4, \"Stack Reserve Size\", \"\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, isPE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), isPE32Plus ? 8 : 4, \"Stack Commit Size\", \"\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, isPE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), isPE32Plus ? 8 : 4, \"Heap Reserve Size\", \"\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, isPE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), isPE32Plus ? 8 : 4, \"Heap Commit Size\", \"\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadUInt32(), 4, \"Loader Flags\", \"\"));\n\t\t\tentries.Add(new Entry(headers.PEHeaderStartOffset + reader.Offset, reader.ReadInt32(), 4, \"Number of Data Directories\", \"\"));\n\n\t\t\tdataGrid.ItemsSource = entries;\n\t\t\tdataGrid.SetDetailsVisibilityForItem(characteristics, Visibility.Visible);\n\n\t\t\ttabPage.Content = dataGrid;\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.WriteCommentLine(output, \"Optional Header\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/NativeMethods.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Runtime.InteropServices;\n\nnamespace ICSharpCode.ILSpy\n{\n\t// Uses https://learn.microsoft.com/en-us/dotnet/standard/native-interop/pinvoke-source-generation\n\tinternal static partial class NativeMethods\n\t{\n\t\tconst int S_OK = 0;\n\n\t\t[LibraryImport(\"user32.dll\")]\n\t\tinternal static partial int GetDoubleClickTime();\n\n\t\t[LibraryImport(\"dwmapi.dll\")]\n\t\tinternal static partial int DwmSetWindowAttribute(IntPtr hwnd, DwmWindowAttribute attr, ref int attrValue, int attrSize);\n\n\t\tpublic static bool UseImmersiveDarkMode(IntPtr hWnd, bool enable)\n\t\t{\n\t\t\tint darkMode = enable ? 1 : 0;\n\t\t\tint hResult = DwmSetWindowAttribute(hWnd, DwmWindowAttribute.UseImmersiveDarkMode, ref darkMode, sizeof(int));\n\t\t\treturn hResult > S_OK;\n\t\t}\n\t}\n\n\tpublic enum DwmWindowAttribute : uint\n\t{\n\t\tNCRenderingEnabled = 1,\n\t\tNCRenderingPolicy,\n\t\tTransitionsForceDisabled,\n\t\tAllowNCPaint,\n\t\tCaptionButtonBounds,\n\t\tNonClientRtlLayout,\n\t\tForceIconicRepresentation,\n\t\tFlip3DPolicy,\n\t\tExtendedFrameBounds,\n\t\tHasIconicBitmap,\n\t\tDisallowPeek,\n\t\tExcludedFromPeek,\n\t\tCloak,\n\t\tCloaked,\n\t\tFreezeRepresentation,\n\t\tPassiveUpdateMode,\n\t\tUseHostBackdropBrush,\n\t\tUseImmersiveDarkMode = 20,\n\t\tWindowCornerPreference = 33,\n\t\tBorderColor,\n\t\tCaptionColor,\n\t\tTextColor,\n\t\tVisibleFrameBorderThickness,\n\t\tSystemBackdropType,\n\t\tLast\n\t}\n}\n"
  },
  {
    "path": "ILSpy/NavigationHistory.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\n\nnamespace ICSharpCode.ILSpy\n{\n\t/// <summary>\n\t/// Stores the navigation history.\n\t/// </summary>\n\tinternal sealed class NavigationHistory<T>\n\t\twhere T : class, IEquatable<T>\n\t{\n\t\tprivate const double NavigationSecondsBeforeNewEntry = 0.5;\n\n\t\tprivate DateTime lastNavigationTime = DateTime.MinValue;\n\t\tT current;\n\t\tList<T> back = new List<T>();\n\t\tList<T> forward = new List<T>();\n\n\t\tpublic T[] BackList => back.ToArray();\n\t\tpublic T[] ForwardList => forward.ToArray();\n\n\t\tpublic bool CanNavigateBack {\n\t\t\tget { return back.Count > 0; }\n\t\t}\n\n\t\tpublic bool CanNavigateForward {\n\t\t\tget { return forward.Count > 0; }\n\t\t}\n\n\t\tpublic T GoBack()\n\t\t{\n\t\t\tforward.Add(current);\n\t\t\tcurrent = back[back.Count - 1];\n\t\t\tback.RemoveAt(back.Count - 1);\n\t\t\treturn current;\n\t\t}\n\n\t\tpublic T GoForward()\n\t\t{\n\t\t\tback.Add(current);\n\t\t\tcurrent = forward[forward.Count - 1];\n\t\t\tforward.RemoveAt(forward.Count - 1);\n\t\t\treturn current;\n\t\t}\n\n\t\tpublic void RemoveAll(Predicate<T> predicate)\n\t\t{\n\t\t\tback.RemoveAll(predicate);\n\t\t\tforward.RemoveAll(predicate);\n\t\t}\n\n\t\tpublic void Clear()\n\t\t{\n\t\t\tback.Clear();\n\t\t\tforward.Clear();\n\t\t}\n\n\t\tpublic void UpdateCurrent(T node)\n\t\t{\n\t\t\tcurrent = node;\n\t\t}\n\n\t\tpublic void Record(T node)\n\t\t{\n\t\t\tvar navigationTime = DateTime.Now;\n\t\t\tvar period = navigationTime - lastNavigationTime;\n\n\t\t\tif (period.TotalSeconds < NavigationSecondsBeforeNewEntry)\n\t\t\t{\n\t\t\t\tcurrent = node;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (current != null)\n\t\t\t\t\tback.Add(current);\n\n\t\t\t\t// We only store a record once, and ensure it is on the top of the stack, so we just remove the old record\n\t\t\t\tback.Remove(node);\n\t\t\t\tcurrent = node;\n\t\t\t}\n\n\t\t\tforward.Clear();\n\n\t\t\tlastNavigationTime = navigationTime;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/NavigationState.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\n\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX.TreeView;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[DebuggerDisplay(\"Nodes = {treeNodes.Count}, State = [{ViewState}]\")]\n\tpublic class NavigationState : IEquatable<NavigationState>\n\t{\n\t\tprivate readonly HashSet<SharpTreeNode> treeNodes;\n\n\t\tpublic IEnumerable<SharpTreeNode> TreeNodes => treeNodes;\n\t\tpublic ViewState ViewState { get; private set; }\n\t\tpublic TabPageModel TabPage { get; private set; }\n\n\t\tpublic NavigationState(TabPageModel tabPage, ViewState viewState)\n\t\t{\n\t\t\tthis.TabPage = tabPage;\n\t\t\tthis.treeNodes = new HashSet<SharpTreeNode>((IEnumerable<SharpTreeNode>)viewState.DecompiledNodes ?? Array.Empty<SharpTreeNode>());\n\t\t\tViewState = viewState;\n\t\t}\n\n\t\tpublic NavigationState(TabPageModel tabPage, IEnumerable<SharpTreeNode> treeNodes)\n\t\t{\n\t\t\tthis.TabPage = tabPage;\n\t\t\tthis.treeNodes = new HashSet<SharpTreeNode>(treeNodes);\n\t\t}\n\n\t\tpublic bool Equals(NavigationState other)\n\t\t{\n\t\t\tif (!this.treeNodes.SetEquals(other.treeNodes))\n\t\t\t\treturn false;\n\n\t\t\tif (object.ReferenceEquals(this.ViewState, other.ViewState))\n\t\t\t\treturn true;\n\n\t\t\tif (this.ViewState == null)\n\t\t\t\treturn false;\n\n\t\t\treturn this.ViewState.Equals(other.ViewState);\n\t\t}\n\n\t\tpublic object NavigationText {\n\t\t\tget {\n\t\t\t\tif (this.treeNodes.Count == 1)\n\t\t\t\t\treturn this.treeNodes.First();\n\n\t\t\t\tif (this.treeNodes.Count > 0)\n\t\t\t\t\treturn string.Join(\", \", treeNodes.Select(tn => tn.NavigationText));\n\n\t\t\t\tif (this.ViewState?.ViewedUri is Uri uri)\n\t\t\t\t\treturn uri;\n\n\t\t\t\treturn ToString();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Options/DecompilerSettingsPanel.xaml",
    "content": "<UserControl x:Class=\"ICSharpCode.ILSpy.Options.DecompilerSettingsPanel\"\n             x:ClassModifier=\"internal\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:properties=\"clr-namespace:ICSharpCode.ILSpy.Properties\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" mc:Ignorable=\"d\"\n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n             xmlns:options=\"clr-namespace:ICSharpCode.ILSpy.Options\"\n             d:DataContext=\"{d:DesignInstance options:DecompilerSettingsViewModel}\">\n\t<DockPanel>\n\t\t<TextBlock Margin=\"3\" DockPanel.Dock=\"Top\" TextWrapping=\"Wrap\" Text=\"{x:Static properties:Resources.DecompilerSettingsPanelLongText}\" />\n\t\t<ScrollViewer>\n\t\t\t<ItemsControl ItemsSource=\"{Binding Settings}\">\n\t\t\t\t<ItemsControl.ItemTemplate>\n\t\t\t\t\t<DataTemplate>\n\t\t\t\t\t\t<Grid>\n\t\t\t\t\t\t\t<Expander Padding=\"0\" BorderThickness=\"0\" IsExpanded=\"True\">\n\t\t\t\t\t\t\t\t<Expander.Header>\n\t\t\t\t\t\t\t\t\t<CheckBox VerticalContentAlignment=\"Center\" \n\t\t\t\t\t\t\t\t\t          FontSize=\"16\" FontWeight=\"Bold\" \n\t\t\t\t\t\t\t\t\t          Content=\"{Binding Category}\"\n\t\t\t\t\t\t\t\t\t          IsChecked=\"{Binding AreAllItemsChecked, Mode=TwoWay}\"/>\n\t\t\t\t\t\t\t\t</Expander.Header>\n\t\t\t\t\t\t\t\t<ItemsControl ItemsSource=\"{Binding Settings}\">\n\t\t\t\t\t\t\t\t\t<ItemsControl.ItemTemplate>\n\t\t\t\t\t\t\t\t\t\t<DataTemplate>\n\t\t\t\t\t\t\t\t\t\t\t<CheckBox Margin=\"28,0,0,0\" IsChecked=\"{Binding IsEnabled}\" Content=\"{Binding Description}\" />\n\t\t\t\t\t\t\t\t\t\t</DataTemplate>\n\t\t\t\t\t\t\t\t\t</ItemsControl.ItemTemplate>\n\t\t\t\t\t\t\t\t</ItemsControl>\n\t\t\t\t\t\t\t</Expander>\n\t\t\t\t\t\t</Grid>\n\t\t\t\t\t</DataTemplate>\n\t\t\t\t</ItemsControl.ItemTemplate>\n\t\t\t</ItemsControl>\n\t\t</ScrollViewer>\n\t</DockPanel>\n</UserControl>"
  },
  {
    "path": "ILSpy/Options/DecompilerSettingsPanel.xaml.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Xml.Linq;\n\nusing ICSharpCode.ILSpyX.Settings;\n\nusing TomsToolbox.Wpf.Composition.AttributedModel;\n\nnamespace ICSharpCode.ILSpy.Options\n{\n\t/// <summary>\n\t/// Interaction logic for DecompilerSettingsPanel.xaml\n\t/// </summary>\n\t[DataTemplate(typeof(DecompilerSettingsViewModel))]\n\t[NonShared]\n\tinternal partial class DecompilerSettingsPanel\n\t{\n\t\tpublic DecompilerSettingsPanel()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Options/DecompilerSettingsViewModel.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Composition;\nusing System.Linq;\nusing System.Reflection;\n\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpyX.Settings;\n\nusing TomsToolbox.Wpf;\n\nnamespace ICSharpCode.ILSpy.Options\n{\n\t[ExportOptionPage(Order = 10)]\n\t[NonShared]\n\tpublic sealed class DecompilerSettingsViewModel : ObservableObjectBase, IOptionPage\n\t{\n\t\tprivate static readonly PropertyInfo[] propertyInfos = typeof(Decompiler.DecompilerSettings).GetProperties()\n\t\t\t.Where(p => p.GetCustomAttribute<BrowsableAttribute>()?.Browsable != false)\n\t\t\t.ToArray();\n\n\t\tpublic string Title => Resources.Decompiler;\n\n\t\tprivate DecompilerSettingsGroupViewModel[] settings;\n\t\tpublic DecompilerSettingsGroupViewModel[] Settings {\n\t\t\tget => settings;\n\t\t\tset => SetProperty(ref settings, value);\n\t\t}\n\n\t\tprivate DecompilerSettings decompilerSettings;\n\n\t\tpublic void Load(SettingsSnapshot snapshot)\n\t\t{\n\t\t\tdecompilerSettings = snapshot.GetSettings<DecompilerSettings>();\n\t\t\tLoadSettings();\n\t\t}\n\n\t\tprivate void LoadSettings()\n\t\t{\n\t\t\tthis.Settings = propertyInfos\n\t\t\t\t.Select(p => new DecompilerSettingsItemViewModel(p, decompilerSettings))\n\t\t\t\t.OrderBy(item => item.Category, NaturalStringComparer.Instance)\n\t\t\t\t.GroupBy(p => p.Category)\n\t\t\t\t.Select(g => new DecompilerSettingsGroupViewModel(g.Key, g.OrderBy(i => i.Description).ToArray()))\n\t\t\t\t.ToArray();\n\t\t}\n\n\t\tpublic void LoadDefaults()\n\t\t{\n\t\t\tvar defaults = new Decompiler.DecompilerSettings();\n\n\t\t\tforeach (var propertyInfo in propertyInfos)\n\t\t\t{\n\t\t\t\tpropertyInfo.SetValue(decompilerSettings, propertyInfo.GetValue(defaults));\n\t\t\t}\n\n\t\t\tLoadSettings();\n\t\t}\n\t}\n\n\tpublic sealed class DecompilerSettingsGroupViewModel : ObservableObjectBase\n\t{\n\t\tprivate bool? areAllItemsChecked;\n\n\t\tpublic DecompilerSettingsGroupViewModel(string category, DecompilerSettingsItemViewModel[] settings)\n\t\t{\n\t\t\tSettings = settings;\n\t\t\tCategory = category;\n\n\t\t\tareAllItemsChecked = GetAreAllItemsChecked(Settings);\n\n\t\t\tforeach (DecompilerSettingsItemViewModel viewModel in settings)\n\t\t\t{\n\t\t\t\tviewModel.PropertyChanged += Item_PropertyChanged;\n\t\t\t}\n\t\t}\n\n\t\tpublic bool? AreAllItemsChecked {\n\t\t\tget => areAllItemsChecked;\n\t\t\tset {\n\t\t\t\tSetProperty(ref areAllItemsChecked, value);\n\n\t\t\t\tif (!value.HasValue)\n\t\t\t\t\treturn;\n\n\t\t\t\tforeach (var setting in Settings)\n\t\t\t\t{\n\t\t\t\t\tsetting.IsEnabled = value.Value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic string Category { get; }\n\n\t\tpublic DecompilerSettingsItemViewModel[] Settings { get; }\n\n\t\tprivate void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)\n\t\t{\n\t\t\tif (e.PropertyName == nameof(DecompilerSettingsItemViewModel.IsEnabled))\n\t\t\t{\n\t\t\t\tAreAllItemsChecked = GetAreAllItemsChecked(Settings);\n\t\t\t}\n\t\t}\n\n\t\tprivate static bool? GetAreAllItemsChecked(ICollection<DecompilerSettingsItemViewModel> settings)\n\t\t{\n\t\t\tvar numberOfEnabledItems = settings.Count(item => item.IsEnabled);\n\n\t\t\tif (numberOfEnabledItems == settings.Count)\n\t\t\t\treturn true;\n\n\t\t\tif (numberOfEnabledItems == 0)\n\t\t\t\treturn false;\n\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tpublic sealed class DecompilerSettingsItemViewModel(PropertyInfo property, DecompilerSettings decompilerSettings) : ObservableObjectBase\n\t{\n\t\tprivate bool isEnabled = property.GetValue(decompilerSettings) is true;\n\n\t\tpublic PropertyInfo Property => property;\n\n\t\tpublic bool IsEnabled {\n\t\t\tget => isEnabled;\n\t\t\tset {\n\t\t\t\tif (SetProperty(ref isEnabled, value))\n\t\t\t\t{\n\t\t\t\t\tproperty.SetValue(decompilerSettings, value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic string Description { get; set; } = GetResourceString(property.GetCustomAttribute<DescriptionAttribute>()?.Description ?? property.Name);\n\n\t\tpublic string Category { get; set; } = GetResourceString(property.GetCustomAttribute<CategoryAttribute>()?.Category ?? Resources.Other);\n\n\t\tprivate static string GetResourceString(string key)\n\t\t{\n\t\t\tvar str = !string.IsNullOrEmpty(key) ? Resources.ResourceManager.GetString(key) : null;\n\t\t\treturn string.IsNullOrEmpty(key) || string.IsNullOrEmpty(str) ? key : str;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Options/DisplaySettings.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Windows.Media;\nusing System.Xml.Linq;\n\nusing ICSharpCode.ILSpyX.Settings;\n\nusing TomsToolbox.Wpf;\n\nnamespace ICSharpCode.ILSpy.Options\n{\n\t/// <summary>\n\t/// Description of DisplaySettings.\n\t/// </summary>\n\tpublic class DisplaySettings : ObservableObjectBase, ISettingsSection\n\t{\n\t\tFontFamily selectedFont;\n\t\tpublic FontFamily SelectedFont {\n\t\t\tget => selectedFont;\n\t\t\tset => SetProperty(ref selectedFont, value);\n\t\t}\n\n\t\tdouble selectedFontSize;\n\t\tpublic double SelectedFontSize {\n\t\t\tget => selectedFontSize;\n\t\t\tset => SetProperty(ref selectedFontSize, value);\n\t\t}\n\n\t\tbool showLineNumbers;\n\t\tpublic bool ShowLineNumbers {\n\t\t\tget => showLineNumbers;\n\t\t\tset => SetProperty(ref showLineNumbers, value);\n\t\t}\n\n\t\tbool showMetadataTokens;\n\t\tpublic bool ShowMetadataTokens {\n\t\t\tget => showMetadataTokens;\n\t\t\tset => SetProperty(ref showMetadataTokens, value);\n\t\t}\n\n\t\tbool showMetadataTokensInBase10;\n\t\tpublic bool ShowMetadataTokensInBase10 {\n\t\t\tget => showMetadataTokensInBase10;\n\t\t\tset => SetProperty(ref showMetadataTokensInBase10, value);\n\t\t}\n\n\t\tbool enableWordWrap;\n\t\tpublic bool EnableWordWrap {\n\t\t\tget => enableWordWrap;\n\t\t\tset => SetProperty(ref enableWordWrap, value);\n\t\t}\n\n\t\tbool sortResults;\n\t\tpublic bool SortResults {\n\t\t\tget => sortResults;\n\t\t\tset => SetProperty(ref sortResults, value);\n\t\t}\n\n\t\tbool foldBraces;\n\t\tpublic bool FoldBraces {\n\t\t\tget => foldBraces;\n\t\t\tset => SetProperty(ref foldBraces, value);\n\t\t}\n\n\t\tbool expandMemberDefinitions;\n\t\tpublic bool ExpandMemberDefinitions {\n\t\t\tget => expandMemberDefinitions;\n\t\t\tset => SetProperty(ref expandMemberDefinitions, value);\n\t\t}\n\n\t\tbool expandUsingDeclarations;\n\t\tpublic bool ExpandUsingDeclarations {\n\t\t\tget => expandUsingDeclarations;\n\t\t\tset => SetProperty(ref expandUsingDeclarations, value);\n\t\t}\n\n\t\tbool showDebugInfo;\n\t\tpublic bool ShowDebugInfo {\n\t\t\tget => showDebugInfo;\n\t\t\tset => SetProperty(ref showDebugInfo, value);\n\t\t}\n\n\t\tbool indentationUseTabs;\n\t\tpublic bool IndentationUseTabs {\n\t\t\tget => indentationUseTabs;\n\t\t\tset => SetProperty(ref indentationUseTabs, value);\n\t\t}\n\n\t\tint indentationTabSize;\n\t\tpublic int IndentationTabSize {\n\t\t\tget => indentationTabSize;\n\t\t\tset => SetProperty(ref indentationTabSize, value);\n\t\t}\n\n\t\tint indentationSize;\n\t\tpublic int IndentationSize {\n\t\t\tget => indentationSize;\n\t\t\tset => SetProperty(ref indentationSize, value);\n\t\t}\n\n\t\tbool highlightMatchingBraces;\n\t\tpublic bool HighlightMatchingBraces {\n\t\t\tget => highlightMatchingBraces;\n\t\t\tset => SetProperty(ref highlightMatchingBraces, value);\n\t\t}\n\n\t\tbool highlightCurrentLine;\n\t\tpublic bool HighlightCurrentLine {\n\t\t\tget => highlightCurrentLine;\n\t\t\tset => SetProperty(ref highlightCurrentLine, value);\n\t\t}\n\n\t\tbool hideEmptyMetadataTables;\n\t\tpublic bool HideEmptyMetadataTables {\n\t\t\tget => hideEmptyMetadataTables;\n\t\t\tset => SetProperty(ref hideEmptyMetadataTables, value);\n\t\t}\n\n\t\tbool useNestedNamespaceNodes;\n\t\tpublic bool UseNestedNamespaceNodes {\n\t\t\tget => useNestedNamespaceNodes;\n\t\t\tset => SetProperty(ref useNestedNamespaceNodes, value);\n\t\t}\n\n\t\tprivate bool styleWindowTitleBar;\n\t\tpublic bool StyleWindowTitleBar {\n\t\t\tget => styleWindowTitleBar;\n\t\t\tset => SetProperty(ref styleWindowTitleBar, value);\n\t\t}\n\n\t\tprivate bool showRawOffsetsAndBytesBeforeInstruction;\n\t\tpublic bool ShowRawOffsetsAndBytesBeforeInstruction {\n\t\t\tget => showRawOffsetsAndBytesBeforeInstruction;\n\t\t\tset => SetProperty(ref showRawOffsetsAndBytesBeforeInstruction, value);\n\t\t}\n\n\t\tprivate bool enableSmoothScrolling;\n\t\tpublic bool EnableSmoothScrolling {\n\t\t\tget => enableSmoothScrolling;\n\t\t\tset => SetProperty(ref enableSmoothScrolling, value);\n\t\t}\n\n\t\tprivate bool decodeCustomAttributeBlobs;\n\t\tpublic bool DecodeCustomAttributeBlobs {\n\t\t\tget => decodeCustomAttributeBlobs;\n\t\t\tset => SetProperty(ref decodeCustomAttributeBlobs, value);\n\t\t}\n\n\t\tpublic XName SectionName => \"DisplaySettings\";\n\n\t\tpublic void LoadFromXml(XElement section)\n\t\t{\n\t\t\tSelectedFont = new FontFamily((string)section.Attribute(\"Font\") ?? \"Consolas\");\n\t\t\tSelectedFontSize = (double?)section.Attribute(\"FontSize\") ?? 10.0 * 4 / 3;\n\t\t\tShowLineNumbers = (bool?)section.Attribute(\"ShowLineNumbers\") ?? false;\n\t\t\tShowMetadataTokens = (bool?)section.Attribute(\"ShowMetadataTokens\") ?? false;\n\t\t\tShowMetadataTokensInBase10 = (bool?)section.Attribute(\"ShowMetadataTokensInBase10\") ?? false;\n\t\t\tShowDebugInfo = (bool?)section.Attribute(\"ShowDebugInfo\") ?? false;\n\t\t\tEnableWordWrap = (bool?)section.Attribute(\"EnableWordWrap\") ?? false;\n\t\t\tSortResults = (bool?)section.Attribute(\"SortResults\") ?? true;\n\t\t\tFoldBraces = (bool?)section.Attribute(\"FoldBraces\") ?? false;\n\t\t\tExpandMemberDefinitions = (bool?)section.Attribute(\"ExpandMemberDefinitions\") ?? false;\n\t\t\tExpandUsingDeclarations = (bool?)section.Attribute(\"ExpandUsingDeclarations\") ?? false;\n\t\t\tIndentationUseTabs = (bool?)section.Attribute(\"IndentationUseTabs\") ?? true;\n\t\t\tIndentationSize = (int?)section.Attribute(\"IndentationSize\") ?? 4;\n\t\t\tIndentationTabSize = (int?)section.Attribute(\"IndentationTabSize\") ?? 4;\n\t\t\tHighlightMatchingBraces = (bool?)section.Attribute(\"HighlightMatchingBraces\") ?? true;\n\t\t\tHighlightCurrentLine = (bool?)section.Attribute(\"HighlightCurrentLine\") ?? false;\n\t\t\tHideEmptyMetadataTables = (bool?)section.Attribute(\"HideEmptyMetadataTables\") ?? true;\n\t\t\tUseNestedNamespaceNodes = (bool?)section.Attribute(\"UseNestedNamespaceNodes\") ?? false;\n\t\t\tShowRawOffsetsAndBytesBeforeInstruction = (bool?)section.Attribute(\"ShowRawOffsetsAndBytesBeforeInstruction\") ?? false;\n\t\t\tStyleWindowTitleBar = (bool?)section.Attribute(\"StyleWindowTitleBar\") ?? false;\n\t\t\tEnableSmoothScrolling = (bool?)section.Attribute(\"EnableSmoothScrolling\") ?? true;\n\t\t\tDecodeCustomAttributeBlobs = (bool?)section.Attribute(\"DecodeCustomAttributeBlobs\") ?? false;\n\t\t}\n\n\t\tpublic XElement SaveToXml()\n\t\t{\n\t\t\tvar section = new XElement(SectionName);\n\n\t\t\tsection.SetAttributeValue(\"Font\", SelectedFont.Source);\n\t\t\tsection.SetAttributeValue(\"FontSize\", SelectedFontSize);\n\t\t\tsection.SetAttributeValue(\"ShowLineNumbers\", ShowLineNumbers);\n\t\t\tsection.SetAttributeValue(\"ShowMetadataTokens\", ShowMetadataTokens);\n\t\t\tsection.SetAttributeValue(\"ShowMetadataTokensInBase10\", ShowMetadataTokensInBase10);\n\t\t\tsection.SetAttributeValue(\"ShowDebugInfo\", ShowDebugInfo);\n\t\t\tsection.SetAttributeValue(\"EnableWordWrap\", EnableWordWrap);\n\t\t\tsection.SetAttributeValue(\"SortResults\", SortResults);\n\t\t\tsection.SetAttributeValue(\"FoldBraces\", FoldBraces);\n\t\t\tsection.SetAttributeValue(\"ExpandMemberDefinitions\", ExpandMemberDefinitions);\n\t\t\tsection.SetAttributeValue(\"ExpandUsingDeclarations\", ExpandUsingDeclarations);\n\t\t\tsection.SetAttributeValue(\"IndentationUseTabs\", IndentationUseTabs);\n\t\t\tsection.SetAttributeValue(\"IndentationSize\", IndentationSize);\n\t\t\tsection.SetAttributeValue(\"IndentationTabSize\", IndentationTabSize);\n\t\t\tsection.SetAttributeValue(\"HighlightMatchingBraces\", HighlightMatchingBraces);\n\t\t\tsection.SetAttributeValue(\"HighlightCurrentLine\", HighlightCurrentLine);\n\t\t\tsection.SetAttributeValue(\"HideEmptyMetadataTables\", HideEmptyMetadataTables);\n\t\t\tsection.SetAttributeValue(\"UseNestedNamespaceNodes\", UseNestedNamespaceNodes);\n\t\t\tsection.SetAttributeValue(\"ShowRawOffsetsAndBytesBeforeInstruction\", ShowRawOffsetsAndBytesBeforeInstruction);\n\t\t\tsection.SetAttributeValue(\"StyleWindowTitleBar\", StyleWindowTitleBar);\n\t\t\tsection.SetAttributeValue(\"EnableSmoothScrolling\", EnableSmoothScrolling);\n\t\t\tsection.SetAttributeValue(\"DecodeCustomAttributeBlobs\", DecodeCustomAttributeBlobs);\n\n\t\t\treturn section;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Options/DisplaySettingsPanel.xaml",
    "content": "<UserControl x:Class=\"ICSharpCode.ILSpy.Options.DisplaySettingsPanel\"\n\t\t\t xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n\t\t\t xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n\t\t\t xmlns:properties=\"clr-namespace:ICSharpCode.ILSpy.Properties\"\n\t\t\t xmlns:local=\"clr-namespace:ICSharpCode.ILSpy.Options\"\n\t\t\t xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" mc:Ignorable=\"d\"\n\t\t\t xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n\t\t\t xmlns:themes=\"clr-namespace:ICSharpCode.ILSpy.Themes\"\n\t\t\t d:DataContext=\"{d:DesignInstance local:DisplaySettingsViewModel}\">\n\t<ScrollViewer HorizontalScrollBarVisibility=\"Auto\" VerticalScrollBarVisibility=\"Auto\">\n\t\t<StackPanel Orientation=\"Vertical\">\n\t\t\t<DockPanel>\n\t\t\t\t<Label DockPanel.Dock=\"Left\" Content=\"{x:Static properties:Resources.DisplaySettingsPanel_Theme}\" />\n\t\t\t\t<ComboBox ItemsSource=\"{x:Static themes:ThemeManager.AllThemes}\" SelectedItem=\"{Binding SessionSettings.Theme}\" VerticalContentAlignment=\"Center\" Margin=\"0,0,8,0\" />\n\t\t\t</DockPanel>\n\t\t\t<GroupBox Header=\"{x:Static properties:Resources.Font}\">\n\t\t\t\t<Grid>\n\t\t\t\t\t<Grid.ColumnDefinitions>\n\t\t\t\t\t\t<ColumnDefinition Width=\"Auto\" />\n\t\t\t\t\t\t<ColumnDefinition Width=\"*\" />\n\t\t\t\t\t\t<ColumnDefinition Width=\"Auto\" />\n\t\t\t\t\t\t<ColumnDefinition Width=\"Auto\" />\n\t\t\t\t\t</Grid.ColumnDefinitions>\n\t\t\t\t\t<Grid.RowDefinitions>\n\t\t\t\t\t\t<RowDefinition Height=\"Auto\" />\n\t\t\t\t\t\t<RowDefinition Height=\"50\" />\n\t\t\t\t\t</Grid.RowDefinitions>\n\t\t\t\t\t<Label Margin=\"3,0\" Content=\"{x:Static properties:Resources.DisplaySettingsPanel_Font}\"></Label>\n\t\t\t\t\t<ComboBox Grid.Row=\"0\" ItemsSource=\"{Binding FontFamilies}\" VerticalContentAlignment=\"Center\" SelectedItem=\"{Binding Settings.SelectedFont}\" Grid.Column=\"1\">\n\t\t\t\t\t\t<ComboBox.ItemTemplate>\n\t\t\t\t\t\t\t<DataTemplate>\n\t\t\t\t\t\t\t\t<TextBlock Text=\"{Binding Source}\" />\n\t\t\t\t\t\t\t</DataTemplate>\n\t\t\t\t\t\t</ComboBox.ItemTemplate>\n\t\t\t\t\t</ComboBox>\n\t\t\t\t\t<Label Grid.Row=\"0\" Grid.Column=\"2\" Margin=\"3,0\" Content=\"{x:Static properties:Resources.Size}\"></Label>\n\t\t\t\t\t<ComboBox Grid.Row=\"0\" Grid.Column=\"3\" ItemsSource=\"{Binding FontSizes}\" Text=\"{Binding Settings.SelectedFontSize, Converter={local:FontSizeConverter}}\" IsEditable=\"True\" Margin=\"3,0\" />\n\t\t\t\t\t<Border Grid.Row=\"1\" Grid.Column=\"0\" Grid.ColumnSpan=\"4\" BorderBrush=\"{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}\" BorderThickness=\"1\" Margin=\"3,5\">\n\t\t\t\t\t\t<TextBlock HorizontalAlignment=\"Center\" VerticalAlignment=\"Center\" Text=\"AaBbCcXxYyZz\" FontFamily=\"{Binding Settings.SelectedFont}\" FontSize=\"{Binding Settings.SelectedFontSize}\" />\n\t\t\t\t\t</Border>\n\t\t\t\t</Grid>\n\t\t\t</GroupBox>\n\t\t\t<GroupBox Header=\"{x:Static properties:Resources.Indentation}\">\n\t\t\t\t<StackPanel Margin=\"3\">\n\t\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.IndentationUseTabs}\" Content=\"{x:Static properties:Resources.UseTabsInsteadOfSpaces}\"></CheckBox>\n\t\t\t\t\t<StackPanel Orientation=\"Horizontal\">\n\t\t\t\t\t\t<Label Content=\"{x:Static properties:Resources.TabSize}\"></Label>\n\t\t\t\t\t\t<TextBox x:Name=\"tabSizeTextBox\" Width=\"50\" Margin=\"3\" Text=\"{Binding Settings.IndentationTabSize}\" PreviewTextInput=\"TextBox_PreviewTextInput\" />\n\t\t\t\t\t</StackPanel>\n\t\t\t\t\t<StackPanel Orientation=\"Horizontal\">\n\t\t\t\t\t\t<Label Content=\"{x:Static properties:Resources.IndentSize}\"></Label>\n\t\t\t\t\t\t<TextBox x:Name=\"indentSizeTextBox\" Width=\"50\" Margin=\"3\" Text=\"{Binding Settings.IndentationSize}\" PreviewTextInput=\"TextBox_PreviewTextInput\" />\n\t\t\t\t\t</StackPanel>\n\t\t\t\t</StackPanel>\n\t\t\t</GroupBox>\n\t\t\t<GroupBox Header=\"{x:Static properties:Resources.DecompilationViewOptions}\">\n\t\t\t\t<StackPanel Margin=\"3\">\n\t\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.ShowLineNumbers}\" Content=\"{x:Static properties:Resources.ShowLineNumbers}\"></CheckBox>\n\t\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.EnableWordWrap}\" Content=\"{x:Static properties:Resources.EnableWordWrap}\"></CheckBox>\n\t\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.FoldBraces}\" Content=\"{x:Static properties:Resources.EnableFoldingBlocksBraces}\"></CheckBox>\n\t\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.HighlightMatchingBraces}\" Content=\"{x:Static properties:Resources.HighlightMatchingBraces}\"></CheckBox>\n\t\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.HighlightCurrentLine}\" Content=\"{x:Static properties:Resources.HighlightCurrentLine}\"></CheckBox>\n\t\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.ExpandMemberDefinitions}\" Content=\"{x:Static properties:Resources.ExpandMemberDefinitionsAfterDecompilation}\"></CheckBox>\n\t\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.ExpandUsingDeclarations}\" Content=\"{x:Static properties:Resources.ExpandUsingDeclarationsAfterDecompilation}\"></CheckBox>\n\t\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.ShowDebugInfo}\" Content=\"{x:Static properties:Resources.ShowInfoFromDebugSymbolsAvailable}\"></CheckBox>\n\t\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.ShowRawOffsetsAndBytesBeforeInstruction}\" Content=\"{x:Static properties:Resources.ShowRawOffsetsAndBytesBeforeInstruction}\"></CheckBox>\n\t\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.DecodeCustomAttributeBlobs}\" Content=\"{x:Static properties:Resources.DecodeCustomAttributeBlobs}\"></CheckBox>\n\t\t\t\t</StackPanel>\n\t\t\t</GroupBox>\n\t\t\t<GroupBox Header=\"{x:Static properties:Resources.TreeViewOptions}\">\n\t\t\t\t<StackPanel Margin=\"3\">\n\t\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.ShowMetadataTokens}\" Content=\"{x:Static properties:Resources.ShowMetadataTokens}\"></CheckBox>\n\t\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.ShowMetadataTokensInBase10}\" Content=\"{x:Static properties:Resources.ShowMetadataTokensInBase10}\"></CheckBox>\n\t\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.HideEmptyMetadataTables}\" Content=\"{x:Static properties:Resources.HideEmptyMetadataTables}\"></CheckBox>\n\t\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.UseNestedNamespaceNodes}\" Content=\"{x:Static properties:Resources.UseNestedNamespaceNodes}\"></CheckBox>\n\t\t\t\t</StackPanel>\n\t\t\t</GroupBox>\n\t\t\t<GroupBox Header=\"{x:Static properties:Resources.OtherOptions}\">\n\t\t\t\t<StackPanel Margin=\"3\">\n\t\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.SortResults}\" Content=\"{x:Static properties:Resources.SortResultsFitness}\"></CheckBox>\n\t\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.StyleWindowTitleBar}\" Content=\"{x:Static properties:Resources.StyleTheWindowTitleBar}\"></CheckBox>\n\t\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.EnableSmoothScrolling}\" Content=\"{x:Static properties:Resources.EnableSmoothScrolling}\"></CheckBox>\n\t\t\t\t</StackPanel>\n\t\t\t</GroupBox>\n\t\t</StackPanel>\n\t</ScrollViewer>\n</UserControl>"
  },
  {
    "path": "ILSpy/Options/DisplaySettingsPanel.xaml.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Composition;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Media;\nusing System.Windows.Threading;\nusing System.Xml.Linq;\n\nusing ICSharpCode.ILSpyX.Settings;\n\nusing TomsToolbox.Wpf.Composition.AttributedModel;\nusing TomsToolbox.Wpf.Converters;\n\nnamespace ICSharpCode.ILSpy.Options\n{\n\t/// <summary>\n\t/// Interaction logic for DisplaySettingsPanel.xaml\n\t/// </summary>\n\t[NonShared]\n\t[DataTemplate(typeof(DisplaySettingsViewModel))]\n\tpublic partial class DisplaySettingsPanel\n\t{\n\t\tpublic DisplaySettingsPanel()\n\t\t{\n\t\t\tInitializeComponent();\n\n\t\t\tDataObject.AddPastingHandler(tabSizeTextBox, OnPaste);\n\t\t\tDataObject.AddPastingHandler(indentSizeTextBox, OnPaste);\n\t\t}\n\n\t\tprivate void TextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)\n\t\t{\n\t\t\tif (!e.Text.All(char.IsDigit))\n\t\t\t\te.Handled = true;\n\t\t}\n\n\t\tprivate static void OnPaste(object sender, DataObjectPastingEventArgs e)\n\t\t{\n\t\t\tif (!e.SourceDataObject.GetDataPresent(DataFormats.UnicodeText, true))\n\t\t\t\treturn;\n\n\t\t\tvar text = (string)e.SourceDataObject.GetData(DataFormats.UnicodeText, true) ?? string.Empty;\n\n\t\t\tif (!text.All(char.IsDigit))\n\t\t\t\te.CancelCommand();\n\t\t}\n\t}\n\n\tpublic sealed class FontSizeConverter : ValueConverter\n\t{\n\t\tprotected override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)\n\t\t{\n\t\t\tif (value is double d)\n\t\t\t{\n\t\t\t\treturn Math.Round(d / 4 * 3);\n\t\t\t}\n\n\t\t\treturn DependencyProperty.UnsetValue;\n\t\t}\n\n\t\tprotected override object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)\n\t\t{\n\t\t\tif (value is not string s)\n\t\t\t\treturn DependencyProperty.UnsetValue;\n\n\t\t\tif (double.TryParse(s, out double d))\n\t\t\t\treturn d * 4 / 3;\n\n\t\t\treturn 11.0 * 4 / 3;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Options/DisplaySettingsViewModel.cs",
    "content": "using ICSharpCode.ILSpyX.Settings;\nusing System.Windows.Media;\nusing System.Xml.Linq;\nusing System;\nusing System.Composition;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Windows;\n\nusing TomsToolbox.Wpf;\nusing ICSharpCode.ILSpy.Themes;\n\nnamespace ICSharpCode.ILSpy.Options\n{\n\t[ExportOptionPage(Order = 20)]\n\t[NonShared]\n\tpublic class DisplaySettingsViewModel : ObservableObjectBase, IOptionPage\n\t{\n\t\tprivate DisplaySettings settings = new();\n\t\tprivate FontFamily[] fontFamilies;\n\t\tprivate SessionSettings sessionSettings;\n\n\t\tpublic DisplaySettingsViewModel()\n\t\t{\n\t\t\tfontFamilies = [settings.SelectedFont];\n\n\t\t\tTask.Run(FontLoader).ContinueWith(continuation => {\n\t\t\t\tFontFamilies = continuation.Result;\n\t\t\t\tif (continuation.Exception == null)\n\t\t\t\t\treturn;\n\t\t\t\tforeach (var ex in continuation.Exception.InnerExceptions)\n\t\t\t\t{\n\t\t\t\t\tMessageBox.Show(ex.ToString());\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic string Title => Properties.Resources.Display;\n\n\t\tpublic DisplaySettings Settings {\n\t\t\tget => settings;\n\t\t\tset => SetProperty(ref settings, value);\n\t\t}\n\n\t\tpublic SessionSettings SessionSettings {\n\t\t\tget => sessionSettings;\n\t\t\tset => SetProperty(ref sessionSettings, value);\n\t\t}\n\n\t\tpublic FontFamily[] FontFamilies {\n\t\t\tget => fontFamilies;\n\t\t\tset => SetProperty(ref fontFamilies, value);\n\t\t}\n\n\t\tpublic int[] FontSizes { get; } = Enumerable.Range(6, 24 - 6 + 1).ToArray();\n\n\t\tpublic void Load(SettingsSnapshot snapshot)\n\t\t{\n\t\t\tSettings = snapshot.GetSettings<DisplaySettings>();\n\t\t\tSessionSettings = snapshot.GetSettings<SessionSettings>();\n\t\t}\n\n\t\tstatic bool IsSymbolFont(FontFamily fontFamily)\n\t\t{\n\t\t\tforeach (var tf in fontFamily.GetTypefaces())\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tif (tf.TryGetGlyphTypeface(out GlyphTypeface glyph))\n\t\t\t\t\t\treturn glyph.Symbol;\n\t\t\t\t}\n\t\t\t\tcatch (Exception)\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tstatic FontFamily[] FontLoader()\n\t\t{\n\t\t\treturn Fonts.SystemFontFamilies\n\t\t\t\t.Where(ff => !IsSymbolFont(ff))\n\t\t\t\t.OrderBy(ff => ff.Source)\n\t\t\t\t.ToArray();\n\t\t}\n\n\t\tpublic void LoadDefaults()\n\t\t{\n\t\t\tSettings.LoadFromXml(new XElement(\"empty\"));\n\t\t\tSessionSettings.Theme = ThemeManager.Current.DefaultTheme;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Options/MiscSettings.cs",
    "content": "// Copyright (c) 2022 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Xml.Linq;\n\nusing TomsToolbox.Wpf;\n\nnamespace ICSharpCode.ILSpyX.Settings\n{\n\tpublic class MiscSettings : ObservableObjectBase, ISettingsSection\n\t{\n\t\tprivate bool allowMultipleInstances;\n\t\tprivate bool loadPreviousAssemblies = true;\n\n\t\tpublic bool AllowMultipleInstances {\n\t\t\tget => allowMultipleInstances;\n\t\t\tset => SetProperty(ref allowMultipleInstances, value);\n\t\t}\n\n\t\tpublic bool LoadPreviousAssemblies {\n\t\t\tget => loadPreviousAssemblies;\n\t\t\tset => SetProperty(ref loadPreviousAssemblies, value);\n\t\t}\n\n\t\tpublic XName SectionName => \"MiscSettings\";\n\n\t\tpublic void LoadFromXml(XElement e)\n\t\t{\n\t\t\tAllowMultipleInstances = (bool?)e.Attribute(nameof(AllowMultipleInstances)) ?? false;\n\t\t\tLoadPreviousAssemblies = (bool?)e.Attribute(nameof(LoadPreviousAssemblies)) ?? true;\n\t\t}\n\n\t\tpublic XElement SaveToXml()\n\t\t{\n\t\t\tvar section = new XElement(SectionName);\n\n\t\t\tsection.SetAttributeValue(nameof(AllowMultipleInstances), AllowMultipleInstances);\n\t\t\tsection.SetAttributeValue(nameof(LoadPreviousAssemblies), LoadPreviousAssemblies);\n\n\t\t\treturn section;\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "ILSpy/Options/MiscSettingsPanel.xaml",
    "content": "<UserControl x:Class=\"ICSharpCode.ILSpy.Options.MiscSettingsPanel\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" mc:Ignorable=\"d\" \n\t\t\t xmlns:properties=\"clr-namespace:ICSharpCode.ILSpy.Properties\"\n\t\t\t xmlns:options=\"clr-namespace:ICSharpCode.ILSpy.Options\"\n\t\t\t d:DataContext=\"{d:DesignInstance options:MiscSettingsViewModel}\"\n             d:DesignHeight=\"300\" d:DesignWidth=\"300\">\n\t<StackPanel Orientation=\"Vertical\">\n\t\t<GroupBox Header=\"{x:Static properties:Resources.Misc}\">\n\t\t\t<StackPanel Margin=\"10\">\n\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.AllowMultipleInstances}\" Content=\"{x:Static properties:Resources.AllowMultipleInstances}\" />\n\t\t\t\t<CheckBox IsChecked=\"{Binding Settings.LoadPreviousAssemblies}\" Content=\"{x:Static properties:Resources.LoadAssembliesThatWereLoadedInTheLastInstance}\"/>\n\t\t\t\t<Button Command=\"{Binding AddRemoveShellIntegrationCommand}\" Content=\"{Binding AddRemoveShellIntegrationText, FallbackValue=temp}\" Margin=\"3\" />\n\t\t\t</StackPanel>\n\t\t</GroupBox>\n\t</StackPanel>\n</UserControl>\n"
  },
  {
    "path": "ILSpy/Options/MiscSettingsPanel.xaml.cs",
    "content": "// Copyright (c) 2017 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Windows.Controls;\nusing System.Xml.Linq;\n\nusing TomsToolbox.Wpf.Composition.AttributedModel;\n\nnamespace ICSharpCode.ILSpy.Options\n{\n\t/// <summary>\n\t/// Interaction logic for MiscSettingsPanel.xaml\n\t/// </summary>\n\t[DataTemplate(typeof(MiscSettingsViewModel))]\n\t[NonShared]\n\tpublic partial class MiscSettingsPanel\n\t{\n\t\tpublic MiscSettingsPanel()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Options/MiscSettingsViewModel.cs",
    "content": "// Copyright (c) 2017 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.IO;\nusing System.Reflection;\nusing System.Windows;\nusing System.Windows.Input;\nusing System.Xml.Linq;\n\nusing ICSharpCode.ILSpy.AppEnv;\nusing ICSharpCode.ILSpyX.Settings;\n\nusing Microsoft.Win32;\n\nusing TomsToolbox.Wpf;\n\nnamespace ICSharpCode.ILSpy.Options\n{\n\t[ExportOptionPage(Order = 30)]\n\t[NonShared]\n\tpublic class MiscSettingsViewModel : ObservableObjectBase, IOptionPage\n\t{\n\t\tprivate MiscSettings settings;\n\t\tpublic MiscSettings Settings {\n\t\t\tget => settings;\n\t\t\tset => SetProperty(ref settings, value);\n\t\t}\n\n\t\tpublic ICommand AddRemoveShellIntegrationCommand => new DelegateCommand(() => AppEnvironment.IsWindows, AddRemoveShellIntegration);\n\n\t\tconst string rootPath = @\"Software\\Classes\\{0}\\shell\";\n\t\tconst string fullPath = @\"Software\\Classes\\{0}\\shell\\Open with ILSpy\\command\";\n\n\t\tprivate void AddRemoveShellIntegration()\n\t\t{\n\t\t\tstring commandLine = CommandLineTools.ArgumentArrayToCommandLine(Path.ChangeExtension(Assembly.GetEntryAssembly()?.Location, \".exe\")) + \" \\\"%L\\\"\";\n\t\t\tif (RegistryEntriesExist())\n\t\t\t{\n\t\t\t\tif (MessageBox.Show(string.Format(Properties.Resources.RemoveShellIntegrationMessage, commandLine), \"ILSpy\", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)\n\t\t\t\t{\n\t\t\t\t\tRegistry.CurrentUser\n\t\t\t\t\t\t.CreateSubKey(string.Format(rootPath, \"dllfile\"))?\n\t\t\t\t\t\t.DeleteSubKeyTree(\"Open with ILSpy\");\n\t\t\t\t\tRegistry.CurrentUser\n\t\t\t\t\t\t.CreateSubKey(string.Format(rootPath, \"exefile\"))?\n\t\t\t\t\t\t.DeleteSubKeyTree(\"Open with ILSpy\");\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (MessageBox.Show(string.Format(Properties.Resources.AddShellIntegrationMessage, commandLine), \"ILSpy\", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)\n\t\t\t\t{\n\t\t\t\t\tRegistry.CurrentUser\n\t\t\t\t\t\t.CreateSubKey(string.Format(fullPath, \"dllfile\"))?\n\t\t\t\t\t\t.SetValue(\"\", commandLine);\n\t\t\t\t\tRegistry.CurrentUser\n\t\t\t\t\t\t.CreateSubKey(string.Format(fullPath, \"exefile\"))?\n\t\t\t\t\t\t.SetValue(\"\", commandLine);\n\t\t\t\t}\n\t\t\t}\n\t\t\tOnPropertyChanged(nameof(AddRemoveShellIntegrationText));\n\t\t}\n\n\t\tprivate static bool RegistryEntriesExist()\n\t\t{\n\t\t\treturn Registry.CurrentUser.OpenSubKey(string.Format(fullPath, \"dllfile\")) != null\n\t\t\t\t&& Registry.CurrentUser.OpenSubKey(string.Format(fullPath, \"exefile\")) != null;\n\t\t}\n\n\t\tpublic string AddRemoveShellIntegrationText {\n\t\t\tget {\n\t\t\t\treturn RegistryEntriesExist() ? Properties.Resources.RemoveShellIntegration : Properties.Resources.AddShellIntegration;\n\t\t\t}\n\t\t}\n\n\t\tpublic string Title => Properties.Resources.Misc;\n\n\t\tpublic void Load(SettingsSnapshot settings)\n\t\t{\n\t\t\tSettings = settings.GetSettings<MiscSettings>();\n\t\t}\n\n\t\tpublic void LoadDefaults()\n\t\t{\n\t\t\tSettings.LoadFromXml(new XElement(\"dummy\"));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Options/OptionsDialog.xaml",
    "content": "<Window x:Class=\"ICSharpCode.ILSpy.Options.OptionsDialog\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n        xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n        xmlns:properties=\"clr-namespace:ICSharpCode.ILSpy.Properties\"\n        xmlns:options=\"clr-namespace:ICSharpCode.ILSpy.Options\"\n        xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n        xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n        xmlns:toms=\"urn:TomsToolbox\"\n        mc:Ignorable=\"d\"\n        d:DataContext=\"{d:DesignInstance options:OptionsDialogViewModel}\"\n        Style=\"{StaticResource DialogWindow}\"\n        WindowStartupLocation=\"CenterOwner\"\n        ResizeMode=\"CanResizeWithGrip\"\n        Title=\"{x:Static properties:Resources.Options}\" Height=\"500\" Width=\"600\">\n\t<DockPanel>\n\t\t<StackPanel DockPanel.Dock=\"Bottom\" Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Margin=\"12,8\">\n\t\t\t<Button Margin=\"2,0\" \n\t\t\t        Command=\"{Binding ResetDefaultsCommand}\"\n\t\t\t        Content=\"{x:Static properties:Resources.ResetToDefaults}\" />\n\t\t\t<Button IsDefault=\"True\" Margin=\"2,0\" \n\t\t\t        toms:Button.DialogResult=\"true\"\n\t\t\t        Command=\"{Binding CommitCommand}\" \n\t\t\t        Content=\"{x:Static properties:Resources.OK}\" />\n\t\t\t<Button IsCancel=\"True\" Margin=\"2,0\" \n\t\t\t        Content=\"{x:Static properties:Resources.Cancel}\" />\n\t\t</StackPanel>\n\t\t<TabControl ItemsSource=\"{Binding OptionPages}\"\n\t\t\t\t\tSelectedIndex=\"0\"\n\t\t            SelectedValuePath=\"Content\"\n\t\t            SelectedValue=\"{Binding SelectedPage}\">\n\t\t\t<TabControl.ItemTemplate>\n\t\t\t\t<DataTemplate DataType=\"options:OptionsItemViewModel\">\n\t\t\t\t\t<TextBlock Text=\"{Binding Title}\" />\n\t\t\t\t</DataTemplate>\n\t\t\t</TabControl.ItemTemplate>\n\t\t\t<TabControl.ContentTemplate>\n\t\t\t\t<DataTemplate DataType=\"options:OptionsItemViewModel\">\n\t\t\t\t\t<ContentPresenter Content=\"{Binding Content}\" />\n\t\t\t\t</DataTemplate>\n\t\t\t</TabControl.ContentTemplate>\n\t\t</TabControl>\n\t</DockPanel>\n</Window>"
  },
  {
    "path": "ILSpy/Options/OptionsDialog.xaml.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Composition;\n\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Properties;\n\nnamespace ICSharpCode.ILSpy.Options\n{\n\t/// <summary>\n\t/// Interaction logic for OptionsDialog.xaml\n\t/// </summary>\n\tpublic sealed partial class OptionsDialog\n\t{\n\t\tpublic OptionsDialog(SettingsService settingsService)\n\t\t{\n\t\t\tDataContext = new OptionsDialogViewModel(settingsService);\n\t\t\tInitializeComponent();\n\t\t}\n\t}\n\n\tpublic interface IOptionsMetadata\n\t{\n\t\tint Order { get; }\n\t}\n\n\tpublic interface IOptionPage\n\t{\n\t\tstring Title { get; }\n\n\t\tvoid Load(SettingsSnapshot settings);\n\n\t\tvoid LoadDefaults();\n\t}\n\n\t[MetadataAttribute]\n\t[AttributeUsage(AttributeTargets.Class)]\n\tpublic sealed class ExportOptionPageAttribute() : ExportAttribute(\"OptionPages\", typeof(IOptionPage)), IOptionsMetadata\n\t{\n\t\tpublic int Order { get; set; }\n\t}\n\n\t[ExportMainMenuCommand(ParentMenuID = nameof(Resources._View), Header = nameof(Resources._Options), MenuCategory = nameof(Resources.Options), MenuOrder = 999)]\n\t[Shared]\n\tsealed class ShowOptionsCommand(AssemblyTreeModel assemblyTreeModel, SettingsService settingsService, MainWindow mainWindow) : SimpleCommand\n\t{\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tOptionsDialog dlg = new(settingsService) {\n\t\t\t\tOwner = mainWindow\n\t\t\t};\n\n\t\t\tif (dlg.ShowDialog() == true)\n\t\t\t{\n\t\t\t\tassemblyTreeModel.Refresh();\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Options/OptionsDialogViewModel.cs",
    "content": "// Copyright (c) 2024 Tom Englert for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Input;\n\nusing TomsToolbox.Essentials;\nusing TomsToolbox.Wpf;\n\n#nullable enable\n\nnamespace ICSharpCode.ILSpy.Options\n{\n\tpublic class OptionsItemViewModel(IOptionPage content) : ObservableObjectBase\n\t{\n\t\tpublic string Title { get; } = content.Title;\n\n\t\tpublic IOptionPage Content { get; } = content;\n\t}\n\n\tpublic class OptionsDialogViewModel : ObservableObjectBase\n\t{\n\t\tprivate IOptionPage? selectedPage;\n\n\t\tprivate SettingsSnapshot snapshot;\n\n\t\tprivate readonly IOptionPage[] optionPages = App.ExportProvider.GetExports<IOptionPage, IOptionsMetadata>(\"OptionPages\")\n\t\t\t.OrderBy(page => page.Metadata?.Order)\n\t\t\t.Select(item => item.Value)\n\t\t\t.ExceptNullItems()\n\t\t\t.ToArray();\n\n\t\tpublic OptionsDialogViewModel(SettingsService settingsService)\n\t\t{\n\t\t\tthis.snapshot = settingsService.CreateSnapshot();\n\n\t\t\tforeach (var optionPage in optionPages)\n\t\t\t{\n\t\t\t\toptionPage.Load(this.snapshot);\n\t\t\t}\n\n\t\t\tOptionPages = optionPages.Select(page => new OptionsItemViewModel(page)).ToArray();\n\t\t\tSelectedPage = optionPages.FirstOrDefault();\n\t\t}\n\n\t\tpublic OptionsItemViewModel[] OptionPages { get; }\n\n\t\tpublic IOptionPage? SelectedPage {\n\t\t\tget => selectedPage;\n\t\t\tset => SetProperty(ref selectedPage, value);\n\t\t}\n\n\t\tpublic ICommand CommitCommand => new DelegateCommand(Commit);\n\n\t\tpublic ICommand ResetDefaultsCommand => new DelegateCommand(ResetDefaults);\n\n\t\tprivate void ResetDefaults()\n\t\t{\n\t\t\tif (MessageBox.Show(Properties.Resources.ResetToDefaultsConfirmationMessage, \"ILSpy\", MessageBoxButton.YesNo) == MessageBoxResult.Yes)\n\t\t\t{\n\t\t\t\tSelectedPage?.LoadDefaults();\n\t\t\t}\n\t\t}\n\n\t\tprivate void Commit()\n\t\t{\n\t\t\tsnapshot.Save();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Properties/AssemblyInfo.cs",
    "content": "#region Using directives\n\nusing System.Diagnostics.CodeAnalysis;\nusing System.Reflection;\nusing System.Resources;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\nusing System.Runtime.Versioning;\n\n#endregion\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"ILSpy\")]\n[assembly: AssemblyDescription(\".NET assembly inspector and decompiler\")]\n[assembly: AssemblyCompany(\"ic#code\")]\n[assembly: AssemblyProduct(\"ILSpy\")]\n[assembly: AssemblyCopyright(\"Copyright 2011-2023 AlphaSierraPapa for the SharpDevelop Team\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// This sets the default COM visibility of types in the assembly to invisible.\n// If you need to expose a type to COM, use [ComVisible(true)] on that type.\n[assembly: ComVisible(false)]\n\n[assembly: AssemblyVersion(DecompilerVersionInfo.Major + \".\" + DecompilerVersionInfo.Minor + \".\" + DecompilerVersionInfo.Build + \".\" + DecompilerVersionInfo.Revision)]\n[assembly: AssemblyInformationalVersion(DecompilerVersionInfo.FullVersionWithCommitHash)]\n[assembly: NeutralResourcesLanguage(\"en-US\")]\n\n[assembly: SupportedOSPlatform(\"Windows7.0\")]\n[assembly: TargetPlatform(\"Windows10.0\")]\n\n[assembly: InternalsVisibleTo(\"ILSpy.AddIn, PublicKey=0024000004800000940000000602000000240000525341310004000001000100653c4a319be4f524972c3c5bba5fd243330f8e900287d9022d7821a63fd0086fd3801e3683dbe9897f2ecc44727023e9b40adcf180730af70c81c54476b3e5ba8b0f07f5132b2c3cc54347a2c1a9d64ebaaaf3cbffc1a18c427981e2a51d53d5ab02536b7550e732f795121c38a0abfdb38596353525d034baf9e6f1fd8ac4ac\")]\n[assembly: InternalsVisibleTo(\"ILSpy.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001004dcf3979c4e902efa4dd2163a039701ed5822e6f1134d77737296abbb97bf0803083cfb2117b4f5446a217782f5c7c634f9fe1fc60b4c11d62c5b3d33545036706296d31903ddcf750875db38a8ac379512f51620bb948c94d0831125fbc5fe63707cbb93f48c1459c4d1749eb7ac5e681a2f0d6d7c60fa527a3c0b8f92b02bf\")]\n\n[assembly: SuppressMessage(\"Microsoft.Usage\", \"CA2243:AttributeStringLiteralsShouldParseCorrectly\",\n\tJustification = \"AssemblyInformationalVersion does not need to be a parsable version\")]\n"
  },
  {
    "path": "ILSpy/Properties/Resources.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace ICSharpCode.ILSpy.Properties {\n    using System;\n    \n    \n    /// <summary>\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\n    /// </summary>\n    // This class was auto-generated by the StronglyTypedResourceBuilder\n    // class via a tool like ResGen or Visual Studio.\n    // To add or remove a member, edit your .ResX file then rerun ResGen\n    // with the /str option, or rebuild your VS project.\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"18.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    public class Resources {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal Resources() {\n        }\n        \n        /// <summary>\n        ///   Returns the cached ResourceManager instance used by this class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        public static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"ICSharpCode.ILSpy.Properties.Resources\", typeof(Resources).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   Overrides the current thread's CurrentUICulture property for all\n        ///   resource lookups using this strongly typed resource class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        public static global::System.Globalization.CultureInfo Culture {\n            get {\n                return resourceCulture;\n            }\n            set {\n                resourceCulture = value;\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _About.\n        /// </summary>\n        public static string _About {\n            get {\n                return ResourceManager.GetString(\"_About\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Add To Main List.\n        /// </summary>\n        public static string _AddMainList {\n            get {\n                return ResourceManager.GetString(\"_AddMainList\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Analy_zer.\n        /// </summary>\n        public static string _Analyzer {\n            get {\n                return ResourceManager.GetString(\"_Analyzer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Assemblies.\n        /// </summary>\n        public static string _Assemblies {\n            get {\n                return ResourceManager.GetString(\"_Assemblies\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Check for Updates.\n        /// </summary>\n        public static string _CheckUpdates {\n            get {\n                return ResourceManager.GetString(\"_CheckUpdates\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Collapse all tree nodes.\n        /// </summary>\n        public static string _CollapseTreeNodes {\n            get {\n                return ResourceManager.GetString(\"_CollapseTreeNodes\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Create _Diagram....\n        /// </summary>\n        public static string _CreateDiagram {\n            get {\n                return ResourceManager.GetString(\"_CreateDiagram\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _File.\n        /// </summary>\n        public static string _File {\n            get {\n                return ResourceManager.GetString(\"_File\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Help.\n        /// </summary>\n        public static string _Help {\n            get {\n                return ResourceManager.GetString(\"_Help\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Load Dependencies.\n        /// </summary>\n        public static string _LoadDependencies {\n            get {\n                return ResourceManager.GetString(\"_LoadDependencies\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _New.\n        /// </summary>\n        public static string _New {\n            get {\n                return ResourceManager.GetString(\"_New\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Open....\n        /// </summary>\n        public static string _Open {\n            get {\n                return ResourceManager.GetString(\"_Open\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Open Command Line Here.\n        /// </summary>\n        public static string _OpenCommandLineHere {\n            get {\n                return ResourceManager.GetString(\"_OpenCommandLineHere\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Open Containing Folder.\n        /// </summary>\n        public static string _OpenContainingFolder {\n            get {\n                return ResourceManager.GetString(\"_OpenContainingFolder\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Options....\n        /// </summary>\n        public static string _Options {\n            get {\n                return ResourceManager.GetString(\"_Options\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Reload.\n        /// </summary>\n        public static string _Reload {\n            get {\n                return ResourceManager.GetString(\"_Reload\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Remove.\n        /// </summary>\n        public static string _Remove {\n            get {\n                return ResourceManager.GetString(\"_Remove\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Remove Assemblies with load errors.\n        /// </summary>\n        public static string _RemoveAssembliesWithLoadErrors {\n            get {\n                return ResourceManager.GetString(\"_RemoveAssembliesWithLoadErrors\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Reset.\n        /// </summary>\n        public static string _Reset {\n            get {\n                return ResourceManager.GetString(\"_Reset\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Resources.\n        /// </summary>\n        public static string _Resources {\n            get {\n                return ResourceManager.GetString(\"_Resources\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Save Code....\n        /// </summary>\n        public static string _SaveCode {\n            get {\n                return ResourceManager.GetString(\"_SaveCode\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Search:.\n        /// </summary>\n        public static string _Search {\n            get {\n                return ResourceManager.GetString(\"_Search\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Search for:.\n        /// </summary>\n        public static string _SearchFor {\n            get {\n                return ResourceManager.GetString(\"_SearchFor\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Show debug steps.\n        /// </summary>\n        public static string _ShowDebugSteps {\n            get {\n                return ResourceManager.GetString(\"_ShowDebugSteps\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Toggle Folding.\n        /// </summary>\n        public static string _ToggleFolding {\n            get {\n                return ResourceManager.GetString(\"_ToggleFolding\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _View.\n        /// </summary>\n        public static string _View {\n            get {\n                return ResourceManager.GetString(\"_View\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Window.\n        /// </summary>\n        public static string _Window {\n            get {\n                return ResourceManager.GetString(\"_Window\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to About.\n        /// </summary>\n        public static string About {\n            get {\n                return ResourceManager.GetString(\"About\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Add preconfigured list....\n        /// </summary>\n        public static string AddPreconfiguredList {\n            get {\n                return ResourceManager.GetString(\"AddPreconfiguredList\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Add shell integration.\n        /// </summary>\n        public static string AddShellIntegration {\n            get {\n                return ResourceManager.GetString(\"AddShellIntegration\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to This will add &quot;{0}&quot; to the registry at &quot;HKCU\\Software\\Classes\\dllfile\\shell\\Open with ILSpy\\command&quot; and &quot;HKCU\\Software\\Classes\\exefile\\shell\\Open with ILSpy\\command&quot; to allow opening .dll and .exe files from the Windows Explorer context menu.\n        ///\n        ///Do you want to continue?.\n        /// </summary>\n        public static string AddShellIntegrationMessage {\n            get {\n                return ResourceManager.GetString(\"AddShellIntegrationMessage\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to |All Files|*.*.\n        /// </summary>\n        public static string AllFiles {\n            get {\n                return ResourceManager.GetString(\"AllFiles\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Allow multiple instances.\n        /// </summary>\n        public static string AllowMultipleInstances {\n            get {\n                return ResourceManager.GetString(\"AllowMultipleInstances\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Always use braces.\n        /// </summary>\n        public static string AlwaysBraces {\n            get {\n                return ResourceManager.GetString(\"AlwaysBraces\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Analyze.\n        /// </summary>\n        public static string Analyze {\n            get {\n                return ResourceManager.GetString(\"Analyze\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Assemblies.\n        /// </summary>\n        public static string Assemblies {\n            get {\n                return ResourceManager.GetString(\"Assemblies\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Assembly.\n        /// </summary>\n        public static string Assembly {\n            get {\n                return ResourceManager.GetString(\"Assembly\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to The directory is not empty. File will be overwritten.\n        ///Are you sure you want to continue?.\n        /// </summary>\n        public static string AssemblySaveCodeDirectoryNotEmpty {\n            get {\n                return ResourceManager.GetString(\"AssemblySaveCodeDirectoryNotEmpty\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Project Directory not empty.\n        /// </summary>\n        public static string AssemblySaveCodeDirectoryNotEmptyTitle {\n            get {\n                return ResourceManager.GetString(\"AssemblySaveCodeDirectoryNotEmptyTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Automatically check for updates every week.\n        /// </summary>\n        public static string AutomaticallyCheckUpdatesEveryWeek {\n            get {\n                return ResourceManager.GetString(\"AutomaticallyCheckUpdatesEveryWeek\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Back.\n        /// </summary>\n        public static string Back {\n            get {\n                return ResourceManager.GetString(\"Back\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Base Types.\n        /// </summary>\n        public static string BaseTypes {\n            get {\n                return ResourceManager.GetString(\"BaseTypes\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to C_lone.\n        /// </summary>\n        public static string C_lone {\n            get {\n                return ResourceManager.GetString(\"C_lone\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Cancel.\n        /// </summary>\n        public static string Cancel {\n            get {\n                return ResourceManager.GetString(\"Cancel\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Entity could not be resolved. Cannot analyze entities from missing assembly references. Add the missing reference and try again..\n        /// </summary>\n        public static string CannotAnalyzeMissingRef {\n            get {\n                return ResourceManager.GetString(\"CannotAnalyzeMissingRef\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Cannot create PDB file for {0} because the PE debug directory type &apos;CodeView&apos; is missing..\n        /// </summary>\n        public static string CannotCreatePDBFile {\n            get {\n                return ResourceManager.GetString(\"CannotCreatePDBFile\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Check again.\n        /// </summary>\n        public static string CheckAgain {\n            get {\n                return ResourceManager.GetString(\"CheckAgain\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Checking....\n        /// </summary>\n        public static string Checking {\n            get {\n                return ResourceManager.GetString(\"Checking\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Check for updates.\n        /// </summary>\n        public static string CheckUpdates {\n            get {\n                return ResourceManager.GetString(\"CheckUpdates\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Clear assembly list.\n        /// </summary>\n        public static string ClearAssemblyList {\n            get {\n                return ResourceManager.GetString(\"ClearAssemblyList\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Close.\n        /// </summary>\n        public static string Close {\n            get {\n                return ResourceManager.GetString(\"Close\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Collapse all tree nodes.\n        /// </summary>\n        public static string CollapseTreeNodes {\n            get {\n                return ResourceManager.GetString(\"CollapseTreeNodes\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Copy.\n        /// </summary>\n        public static string Copy {\n            get {\n                return ResourceManager.GetString(\"Copy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Copy error message.\n        /// </summary>\n        public static string CopyErrorMessage {\n            get {\n                return ResourceManager.GetString(\"CopyErrorMessage\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Copy FQ Name.\n        /// </summary>\n        public static string CopyName {\n            get {\n                return ResourceManager.GetString(\"CopyName\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Could not use SDK-style project format, because no compatible target-framework moniker was found..\n        /// </summary>\n        public static string CouldNotUseSdkStyleProjectFormat {\n            get {\n                return ResourceManager.GetString(\"CouldNotUseSdkStyleProjectFormat\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Create.\n        /// </summary>\n        public static string Create {\n            get {\n                return ResourceManager.GetString(\"Create\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Creating diagram....\n        /// </summary>\n        public static string CreatingDiagram {\n            get {\n                return ResourceManager.GetString(\"CreatingDiagram\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Culture.\n        /// </summary>\n        public static string CultureLabel {\n            get {\n                return ResourceManager.GetString(\"CultureLabel\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to DEBUG -- Decompile All.\n        /// </summary>\n        public static string DEBUGDecompile {\n            get {\n                return ResourceManager.GetString(\"DEBUGDecompile\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to DEBUG -- Decompile 100x.\n        /// </summary>\n        public static string DEBUGDecompile100x {\n            get {\n                return ResourceManager.GetString(\"DEBUGDecompile100x\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to DEBUG -- Disassemble All.\n        /// </summary>\n        public static string DEBUGDisassemble {\n            get {\n                return ResourceManager.GetString(\"DEBUGDisassemble\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to DEBUG -- Dump PDB as XML.\n        /// </summary>\n        public static string DEBUGDumpPDBAsXML {\n            get {\n                return ResourceManager.GetString(\"DEBUGDumpPDBAsXML\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Debug Steps.\n        /// </summary>\n        public static string DebugSteps {\n            get {\n                return ResourceManager.GetString(\"DebugSteps\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Debug this step.\n        /// </summary>\n        public static string DebugThisStep {\n            get {\n                return ResourceManager.GetString(\"DebugThisStep\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decode custom attribute blobs.\n        /// </summary>\n        public static string DecodeCustomAttributeBlobs {\n            get {\n                return ResourceManager.GetString(\"DecodeCustomAttributeBlobs\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompilation complete in {0:F1} seconds..\n        /// </summary>\n        public static string DecompilationCompleteInF1Seconds {\n            get {\n                return ResourceManager.GetString(\"DecompilationCompleteInF1Seconds\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompilation view options.\n        /// </summary>\n        public static string DecompilationViewOptions {\n            get {\n                return ResourceManager.GetString(\"DecompilationViewOptions\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompilation was cancelled..\n        /// </summary>\n        public static string DecompilationWasCancelled {\n            get {\n                return ResourceManager.GetString(\"DecompilationWasCancelled\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompile.\n        /// </summary>\n        public static string Decompile {\n            get {\n                return ResourceManager.GetString(\"Decompile\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompiler.\n        /// </summary>\n        public static string Decompiler {\n            get {\n                return ResourceManager.GetString(\"Decompiler\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Always inline local variables if possible.\n        /// </summary>\n        public static string DecompilerSettings_AggressiveInlining {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.AggressiveInlining\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Allow extension &apos;Add&apos; methods in collection initializer expressions.\n        /// </summary>\n        public static string DecompilerSettings_AllowExtensionAddMethodsInCollectionInitializerExpressions {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.AllowExtensionAddMethodsInCollectionInitializerExpressions\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use &apos;ref&apos; extension methods.\n        /// </summary>\n        public static string DecompilerSettings_AllowExtensionMethodSyntaxOnRef {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.AllowExtensionMethodSyntaxOnRef\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Always cast targets of explicit interface implementation calls.\n        /// </summary>\n        public static string DecompilerSettings_AlwaysCastTargetsOfExplicitInterfaceImplementationCalls {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.AlwaysCastTargetsOfExplicitInterfaceImplementationCalls\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Always move field initializers from constructors to declarations.\n        /// </summary>\n        public static string DecompilerSettings_AlwaysMoveInitializer {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.AlwaysMoveInitializer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Always qualify member references.\n        /// </summary>\n        public static string DecompilerSettings_AlwaysQualifyMemberReferences {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.AlwaysQualifyMemberReferences\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Always show enum member values.\n        /// </summary>\n        public static string DecompilerSettings_AlwaysShowEnumMemberValues {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.AlwaysShowEnumMemberValues\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Always use braces.\n        /// </summary>\n        public static string DecompilerSettings_AlwaysUseBraces {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.AlwaysUseBraces\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Always fully qualify namespaces using the &quot;global::&quot; prefix.\n        /// </summary>\n        public static string DecompilerSettings_AlwaysUseGlobal {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.AlwaysUseGlobal\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Apply Windows Runtime projections on loaded assemblies.\n        /// </summary>\n        public static string DecompilerSettings_ApplyWindowsRuntimeProjectionsOnLoadedAssemblies {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.ApplyWindowsRuntimeProjectionsOnLoadedAssemblies\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Array initializer expressions.\n        /// </summary>\n        public static string DecompilerSettings_ArrayInitializerExpressions {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.ArrayInitializerExpressions\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompile async IAsyncEnumerator methods.\n        /// </summary>\n        public static string DecompilerSettings_AsyncEnumerator {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.AsyncEnumerator\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Automatically load assembly references.\n        /// </summary>\n        public static string DecompilerSettings_AutoLoadAssemblyReferences {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.AutoLoadAssemblyReferences\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to User-defined checked operators.\n        /// </summary>\n        public static string DecompilerSettings_CheckedOperators {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.CheckedOperators\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Check for overflow and underflow in operators.\n        /// </summary>\n        public static string DecompilerSettings_CheckForOverflowUnderflow {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.CheckForOverflowUnderflow\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompile anonymous methods/lambdas.\n        /// </summary>\n        public static string DecompilerSettings_DecompileAnonymousMethodsLambdas {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DecompileAnonymousMethodsLambdas\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompile anonymous types.\n        /// </summary>\n        public static string DecompilerSettings_DecompileAnonymousTypes {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DecompileAnonymousTypes\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompile async methods.\n        /// </summary>\n        public static string DecompilerSettings_DecompileAsyncMethods {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DecompileAsyncMethods\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompile automatic events.\n        /// </summary>\n        public static string DecompilerSettings_DecompileAutomaticEvents {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DecompileAutomaticEvents\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompile automatic properties.\n        /// </summary>\n        public static string DecompilerSettings_DecompileAutomaticProperties {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DecompileAutomaticProperties\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompile await in catch/finally blocks.\n        /// </summary>\n        public static string DecompilerSettings_DecompileAwaitInCatchFinallyBlocks {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DecompileAwaitInCatchFinallyBlocks\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompile C# 1.0 &apos;public unsafe fixed int arr[10];&apos; members.\n        /// </summary>\n        public static string DecompilerSettings_DecompileC10PublicUnsafeFixedIntArr10Members {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DecompileC10PublicUnsafeFixedIntArr10Members\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompile [DecimalConstant(...)] as simple literal values.\n        /// </summary>\n        public static string DecompilerSettings_DecompileDecimalConstantAsSimpleLiteralValues {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DecompileDecimalConstantAsSimpleLiteralValues\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompile enumerators (yield return).\n        /// </summary>\n        public static string DecompilerSettings_DecompileEnumeratorsYieldReturn {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DecompileEnumeratorsYieldReturn\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompile expression trees.\n        /// </summary>\n        public static string DecompilerSettings_DecompileExpressionTrees {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DecompileExpressionTrees\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompile foreach statements with GetEnumerator extension methods.\n        /// </summary>\n        public static string DecompilerSettings_DecompileForEachWithGetEnumeratorExtension {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DecompileForEachWithGetEnumeratorExtension\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompile params collections.\n        /// </summary>\n        public static string DecompilerSettings_DecompileParamsCollections {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DecompileParamsCollections\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompile use of the &apos;dynamic&apos; type.\n        /// </summary>\n        public static string DecompilerSettings_DecompileUseOfTheDynamicType {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DecompileUseOfTheDynamicType\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Detect deconstruction assignments.\n        /// </summary>\n        public static string DecompilerSettings_Deconstruction {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.Deconstruction\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Detect awaited using and foreach statements.\n        /// </summary>\n        public static string DecompilerSettings_DetectAsyncUsingAndForeachStatements {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DetectAsyncUsingAndForeachStatements\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Detect foreach statements.\n        /// </summary>\n        public static string DecompilerSettings_DetectForeachStatements {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DetectForeachStatements\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Detect lock statements.\n        /// </summary>\n        public static string DecompilerSettings_DetectLockStatements {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DetectLockStatements\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Detect switch on string.\n        /// </summary>\n        public static string DecompilerSettings_DetectSwitchOnString {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DetectSwitchOnString\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Detect tuple comparisons.\n        /// </summary>\n        public static string DecompilerSettings_DetectTupleComparisons {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DetectTupleComparisons\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Detect using statements.\n        /// </summary>\n        public static string DecompilerSettings_DetectUsingStatements {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DetectUsingStatements\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Dictionary initializer expressions.\n        /// </summary>\n        public static string DecompilerSettings_DictionaryInitializerExpressions {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DictionaryInitializerExpressions\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Transform to do-while, if possible.\n        /// </summary>\n        public static string DecompilerSettings_DoWhileStatement {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.DoWhileStatement\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Expand params arguments by removing explicit array creation.\n        /// </summary>\n        public static string DecompilerSettings_ExpandParamsArguments {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.ExpandParamsArguments\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use file-scoped namespace declarations.\n        /// </summary>\n        public static string DecompilerSettings_FileScopedNamespaces {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.FileScopedNamespaces\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Treat Span&lt;T&gt; and ReadOnlySpan&lt;T&gt; as built-in types.\n        /// </summary>\n        public static string DecompilerSettings_FirstClassSpanTypes {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.FirstClassSpanTypes\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Transform to for, if possible.\n        /// </summary>\n        public static string DecompilerSettings_ForStatement {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.ForStatement\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to F#-specific options.\n        /// </summary>\n        public static string DecompilerSettings_FSpecificOptions {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.FSpecificOptions\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Function pointers.\n        /// </summary>\n        public static string DecompilerSettings_FunctionPointers {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.FunctionPointers\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompile getter-only automatic properties.\n        /// </summary>\n        public static string DecompilerSettings_GetterOnlyAutomaticProperties {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.GetterOnlyAutomaticProperties\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Include XML documentation comments in the decompiled code.\n        /// </summary>\n        public static string DecompilerSettings_IncludeXMLDocumentationCommentsInTheDecompiledCode {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.IncludeXMLDocumentationCommentsInTheDecompiledCode\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Allow init; accessors.\n        /// </summary>\n        public static string DecompilerSettings_InitAccessors {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.InitAccessors\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Insert using declarations.\n        /// </summary>\n        public static string DecompilerSettings_InsertUsingDeclarations {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.InsertUsingDeclarations\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Introduce local functions.\n        /// </summary>\n        public static string DecompilerSettings_IntroduceLocalFunctions {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.IntroduceLocalFunctions\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Introduce &apos;private protected&apos; accessibility.\n        /// </summary>\n        public static string DecompilerSettings_IntroducePrivateProtectedAccessibility {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.IntroducePrivateProtectedAccessibility\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Introduce static local functions.\n        /// </summary>\n        public static string DecompilerSettings_IntroduceStaticLocalFunctions {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.IntroduceStaticLocalFunctions\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to IsByRefLikeAttribute should be replaced with &apos;ref&apos; modifiers on structs.\n        /// </summary>\n        public static string DecompilerSettings_IsByRefLikeAttributeShouldBeReplacedWithRefModifiersOnStructs {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.IsByRefLikeAttributeShouldBeReplacedWithRefModifiersOnStructs\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to IsReadOnlyAttribute should be replaced with &apos;readonly&apos;/&apos;in&apos; modifiers on structs/parameters.\n        /// </summary>\n        public static string DecompilerSettings_IsReadOnlyAttributeShouldBeReplacedWithReadonlyInModifiersOnStructsParameters {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.IsReadOnlyAttributeShouldBeReplacedWithReadonlyInModifiersOnSt\" +\n                        \"ructsParameters\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to IsUnmanagedAttribute on type parameters should be replaced with &apos;unmanaged&apos; constraints.\n        /// </summary>\n        public static string DecompilerSettings_IsUnmanagedAttributeOnTypeParametersShouldBeReplacedWithUnmanagedConstraints {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.IsUnmanagedAttributeOnTypeParametersShouldBeReplacedWithUnmana\" +\n                        \"gedConstraints\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use nint/nuint types.\n        /// </summary>\n        public static string DecompilerSettings_NativeIntegers {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.NativeIntegers\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Nullable reference types.\n        /// </summary>\n        public static string DecompilerSettings_NullableReferenceTypes {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.NullableReferenceTypes\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompile ?. and ?[] operators.\n        /// </summary>\n        public static string DecompilerSettings_NullPropagation {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.NullPropagation\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Treat (U)IntPtr as n(u)int.\n        /// </summary>\n        public static string DecompilerSettings_NumericIntPtr {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.NumericIntPtr\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Object/collection initializer expressions.\n        /// </summary>\n        public static string DecompilerSettings_ObjectCollectionInitializerExpressions {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.ObjectCollectionInitializerExpressions\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Other.\n        /// </summary>\n        public static string DecompilerSettings_Other {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.Other\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Pattern combinators (and, or, not).\n        /// </summary>\n        public static string DecompilerSettings_PatternCombinators {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.PatternCombinators\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use pattern matching expressions.\n        /// </summary>\n        public static string DecompilerSettings_PatternMatching {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.PatternMatching\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Project export.\n        /// </summary>\n        public static string DecompilerSettings_ProjectExport {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.ProjectExport\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Ranges.\n        /// </summary>\n        public static string DecompilerSettings_Ranges {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.Ranges\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Read-only methods.\n        /// </summary>\n        public static string DecompilerSettings_ReadOnlyMethods {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.ReadOnlyMethods\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Record classes.\n        /// </summary>\n        public static string DecompilerSettings_RecordClasses {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.RecordClasses\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Record structs.\n        /// </summary>\n        public static string DecompilerSettings_RecordStructs {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.RecordStructs\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Recursive pattern matching.\n        /// </summary>\n        public static string DecompilerSettings_RecursivePatternMatching {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.RecursivePatternMatching\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to &apos;ref readonly&apos; parameters.\n        /// </summary>\n        public static string DecompilerSettings_RefReadOnlyParameters {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.RefReadOnlyParameters\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Relational patterns.\n        /// </summary>\n        public static string DecompilerSettings_RelationalPatterns {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.RelationalPatterns\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Remove dead and side effect free code (use with caution!).\n        /// </summary>\n        public static string DecompilerSettings_RemoveDeadAndSideEffectFreeCodeUseWithCaution {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.RemoveDeadAndSideEffectFreeCodeUseWithCaution\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Remove dead stores (use with caution!).\n        /// </summary>\n        public static string DecompilerSettings_RemoveDeadStores {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.RemoveDeadStores\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Remove optional arguments, if possible.\n        /// </summary>\n        public static string DecompilerSettings_RemoveOptionalArgumentsIfPossible {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.RemoveOptionalArgumentsIfPossible\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Required members.\n        /// </summary>\n        public static string DecompilerSettings_RequiredMembers {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.RequiredMembers\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to &apos;scoped&apos; lifetime annotation.\n        /// </summary>\n        public static string DecompilerSettings_ScopedRef {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.ScopedRef\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Separate local variable declarations and initializers (int x = 5; -&gt; int x; x = 5;), if possible.\n        /// </summary>\n        public static string DecompilerSettings_SeparateLocalVariableDeclarations {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.SeparateLocalVariableDeclarations\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show info from debug symbols, if available.\n        /// </summary>\n        public static string DecompilerSettings_ShowInfoFromDebugSymbolsIfAvailable {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.ShowInfoFromDebugSymbolsIfAvailable\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Sort custom attributes.\n        /// </summary>\n        public static string DecompilerSettings_SortCustomAttributes {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.SortCustomAttributes\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Detect switch on integer even if IL code does not use a jump table.\n        /// </summary>\n        public static string DecompilerSettings_SparseIntegerSwitch {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.SparseIntegerSwitch\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompile &apos;string.Concat(a, b)&apos; calls into &apos;a + b&apos;.\n        /// </summary>\n        public static string DecompilerSettings_StringConcat {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.StringConcat\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use struct field initializers and default constructors.\n        /// </summary>\n        public static string DecompilerSettings_StructDefaultConstructorsAndFieldInitializers {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.StructDefaultConstructorsAndFieldInitializers\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Switch expressions.\n        /// </summary>\n        public static string DecompilerSettings_SwitchExpressions {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.SwitchExpressions\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use switch on (ReadOnly)Span&lt;char&gt;.\n        /// </summary>\n        public static string DecompilerSettings_SwitchOnReadOnlySpanChar {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.SwitchOnReadOnlySpanChar\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Unsigned right shift (&gt;&gt;&gt;).\n        /// </summary>\n        public static string DecompilerSettings_UnsignedRightShift {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UnsignedRightShift\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use discards.\n        /// </summary>\n        public static string DecompilerSettings_UseDiscards {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseDiscards\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use enhanced using variable declarations.\n        /// </summary>\n        public static string DecompilerSettings_UseEnhancedUsing {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseEnhancedUsing\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use expression-bodied member syntax for get-only properties.\n        /// </summary>\n        public static string DecompilerSettings_UseExpressionBodiedMemberSyntaxForGetOnlyProperties {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseExpressionBodiedMemberSyntaxForGetOnlyProperties\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use extension method syntax.\n        /// </summary>\n        public static string DecompilerSettings_UseExtensionMethodSyntax {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseExtensionMethodSyntax\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use implicit conversions between tuple types.\n        /// </summary>\n        public static string DecompilerSettings_UseImplicitConversionsBetweenTupleTypes {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseImplicitConversionsBetweenTupleTypes\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use implicit method group conversions.\n        /// </summary>\n        public static string DecompilerSettings_UseImplicitMethodGroupConversions {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseImplicitMethodGroupConversions\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use lambda syntax, if possible.\n        /// </summary>\n        public static string DecompilerSettings_UseLambdaSyntaxIfPossible {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseLambdaSyntaxIfPossible\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use lifted operators for nullables.\n        /// </summary>\n        public static string DecompilerSettings_UseLiftedOperatorsForNullables {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseLiftedOperatorsForNullables\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use LINQ expression syntax.\n        /// </summary>\n        public static string DecompilerSettings_UseLINQExpressionSyntax {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseLINQExpressionSyntax\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use named arguments.\n        /// </summary>\n        public static string DecompilerSettings_UseNamedArguments {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseNamedArguments\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use nested directories for namespaces.\n        /// </summary>\n        public static string DecompilerSettings_UseNestedDirectoriesForNamespaces {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseNestedDirectoriesForNamespaces\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use non-trailing named arguments.\n        /// </summary>\n        public static string DecompilerSettings_UseNonTrailingNamedArguments {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseNonTrailingNamedArguments\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use new T() instead of Activator.CreateInstance&lt;T&gt;.\n        /// </summary>\n        public static string DecompilerSettings_UseObjectCreationOfGenericTypeParameter {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseObjectCreationOfGenericTypeParameter\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use out variable declarations.\n        /// </summary>\n        public static string DecompilerSettings_UseOutVariableDeclarations {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseOutVariableDeclarations\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use pattern-based fixed statement.\n        /// </summary>\n        public static string DecompilerSettings_UsePatternBasedFixedStatement {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UsePatternBasedFixedStatement\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use primary constructor syntax for non-record types.\n        /// </summary>\n        public static string DecompilerSettings_UsePrimaryConstructorDecompilerSettings_SyntaxForNonRecordTypes {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UsePrimaryConstructorDecompilerSettings.SyntaxForNonRecordType\" +\n                        \"s\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use primary constructor syntax with records.\n        /// </summary>\n        public static string DecompilerSettings_UsePrimaryConstructorSyntax {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UsePrimaryConstructorSyntax\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use primary constructor syntax for non-record types.\n        /// </summary>\n        public static string DecompilerSettings_UsePrimaryConstructorSyntaxForNonRecordTypes {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UsePrimaryConstructorSyntaxForNonRecordTypes\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use ref locals to accurately represent order of evaluation.\n        /// </summary>\n        public static string DecompilerSettings_UseRefLocalsForAccurateOrderOfEvaluation {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseRefLocalsForAccurateOrderOfEvaluation\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use new SDK style format for generated project files (*.csproj).\n        /// </summary>\n        public static string DecompilerSettings_UseSdkStyleProjectFormat {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseSdkStyleProjectFormat\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use stackalloc initializer syntax.\n        /// </summary>\n        public static string DecompilerSettings_UseStackallocInitializerSyntax {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseStackallocInitializerSyntax\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use string interpolation.\n        /// </summary>\n        public static string DecompilerSettings_UseStringInterpolation {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseStringInterpolation\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use throw expressions.\n        /// </summary>\n        public static string DecompilerSettings_UseThrowExpressions {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseThrowExpressions\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use tuple type syntax.\n        /// </summary>\n        public static string DecompilerSettings_UseTupleTypeSyntax {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseTupleTypeSyntax\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use variable names from debug symbols, if available.\n        /// </summary>\n        public static string DecompilerSettings_UseVariableNamesFromDebugSymbolsIfAvailable {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.UseVariableNamesFromDebugSymbolsIfAvailable\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to UTF-8 string literals.\n        /// </summary>\n        public static string DecompilerSettings_Utf8StringLiterals {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.Utf8StringLiterals\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to VB-specific options.\n        /// </summary>\n        public static string DecompilerSettings_VBSpecificOptions {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.VBSpecificOptions\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to &apos;with&apos; initializer expressions.\n        /// </summary>\n        public static string DecompilerSettings_WithExpressions {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettings.WithExpressions\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to The settings selected below are applied to the decompiler output in combination with the selection in the language drop-down. Selecting a lower language version in the drop-down will deactivate all selected options of the higher versions. Note that some settings implicitly depend on each other, e.g.: LINQ expressions cannot be introduced without first transforming static calls to extension method calls..\n        /// </summary>\n        public static string DecompilerSettingsPanelLongText {\n            get {\n                return ResourceManager.GetString(\"DecompilerSettingsPanelLongText\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompile to new tab.\n        /// </summary>\n        public static string DecompileToNewPanel {\n            get {\n                return ResourceManager.GetString(\"DecompileToNewPanel\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decompiling....\n        /// </summary>\n        public static string Decompiling {\n            get {\n                return ResourceManager.GetString(\"Decompiling\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Dependencies.\n        /// </summary>\n        public static string Dependencies {\n            get {\n                return ResourceManager.GetString(\"Dependencies\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Derived Types.\n        /// </summary>\n        public static string DerivedTypes {\n            get {\n                return ResourceManager.GetString(\"DerivedTypes\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Display.\n        /// </summary>\n        public static string Display {\n            get {\n                return ResourceManager.GetString(\"Display\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Display Code.\n        /// </summary>\n        public static string DisplayCode {\n            get {\n                return ResourceManager.GetString(\"DisplayCode\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Font:.\n        /// </summary>\n        public static string DisplaySettingsPanel_Font {\n            get {\n                return ResourceManager.GetString(\"DisplaySettingsPanel_Font\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Theme:.\n        /// </summary>\n        public static string DisplaySettingsPanel_Theme {\n            get {\n                return ResourceManager.GetString(\"DisplaySettingsPanel_Theme\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Download.\n        /// </summary>\n        public static string Download {\n            get {\n                return ResourceManager.GetString(\"Download\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to E_xit.\n        /// </summary>\n        public static string E_xit {\n            get {\n                return ResourceManager.GetString(\"E_xit\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Editor.\n        /// </summary>\n        public static string Editor {\n            get {\n                return ResourceManager.GetString(\"Editor\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Enable folding on all blocks in braces.\n        /// </summary>\n        public static string EnableFoldingBlocksBraces {\n            get {\n                return ResourceManager.GetString(\"EnableFoldingBlocksBraces\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Enable smooth scrolling.\n        /// </summary>\n        public static string EnableSmoothScrolling {\n            get {\n                return ResourceManager.GetString(\"EnableSmoothScrolling\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Enable word wrap.\n        /// </summary>\n        public static string EnableWordWrap {\n            get {\n                return ResourceManager.GetString(\"EnableWordWrap\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Enter a list name:.\n        /// </summary>\n        public static string EnterListName {\n            get {\n                return ResourceManager.GetString(\"EnterListName\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Exit.\n        /// </summary>\n        public static string Exit {\n            get {\n                return ResourceManager.GetString(\"Exit\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Expand member definitions after decompilation.\n        /// </summary>\n        public static string ExpandMemberDefinitionsAfterDecompilation {\n            get {\n                return ResourceManager.GetString(\"ExpandMemberDefinitionsAfterDecompilation\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Expand using declarations after decompilation.\n        /// </summary>\n        public static string ExpandUsingDeclarationsAfterDecompilation {\n            get {\n                return ResourceManager.GetString(\"ExpandUsingDeclarationsAfterDecompilation\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Extract all package entries.\n        /// </summary>\n        public static string ExtractAllPackageEntries {\n            get {\n                return ResourceManager.GetString(\"ExtractAllPackageEntries\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Extract package entry.\n        /// </summary>\n        public static string ExtractPackageEntry {\n            get {\n                return ResourceManager.GetString(\"ExtractPackageEntry\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Folding.\n        /// </summary>\n        public static string Folding {\n            get {\n                return ResourceManager.GetString(\"Folding\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Font.\n        /// </summary>\n        public static string Font {\n            get {\n                return ResourceManager.GetString(\"Font\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Forward.\n        /// </summary>\n        public static string Forward {\n            get {\n                return ResourceManager.GetString(\"Forward\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Generated PDB: {0}.\n        /// </summary>\n        public static string GeneratedPDBFile {\n            get {\n                return ResourceManager.GetString(\"GeneratedPDBFile\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Generate portable PDB.\n        /// </summary>\n        public static string GeneratePortable {\n            get {\n                return ResourceManager.GetString(\"GeneratePortable\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Generating portable PDB for {0}....\n        /// </summary>\n        public static string GeneratingPortablePDB {\n            get {\n                return ResourceManager.GetString(\"GeneratingPortablePDB\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Generation complete in {0} seconds..\n        /// </summary>\n        public static string GenerationCompleteInSeconds {\n            get {\n                return ResourceManager.GetString(\"GenerationCompleteInSeconds\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Failed to generate PDB for {0}: {1}.\n        /// </summary>\n        public static string GenerationFailedForAssembly {\n            get {\n                return ResourceManager.GetString(\"GenerationFailedForAssembly\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Generation was cancelled..\n        /// </summary>\n        public static string GenerationWasCancelled {\n            get {\n                return ResourceManager.GetString(\"GenerationWasCancelled\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Go to token.\n        /// </summary>\n        public static string GoToToken {\n            get {\n                return ResourceManager.GetString(\"GoToToken\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Hide empty metadata tables from tree view.\n        /// </summary>\n        public static string HideEmptyMetadataTables {\n            get {\n                return ResourceManager.GetString(\"HideEmptyMetadataTables\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Highlight current line.\n        /// </summary>\n        public static string HighlightCurrentLine {\n            get {\n                return ResourceManager.GetString(\"HighlightCurrentLine\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Highlight matching braces.\n        /// </summary>\n        public static string HighlightMatchingBraces {\n            get {\n                return ResourceManager.GetString(\"HighlightMatchingBraces\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to ILSpyAboutPage.txt.\n        /// </summary>\n        public static string ILSpyAboutPageTxt {\n            get {\n                return ResourceManager.GetString(\"ILSpyAboutPageTxt\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to ILSpy version .\n        /// </summary>\n        public static string ILSpyVersion {\n            get {\n                return ResourceManager.GetString(\"ILSpyVersion\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to A new ILSpy version is available..\n        /// </summary>\n        public static string ILSpyVersionAvailable {\n            get {\n                return ResourceManager.GetString(\"ILSpyVersionAvailable\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Indentation.\n        /// </summary>\n        public static string Indentation {\n            get {\n                return ResourceManager.GetString(\"Indentation\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Indent size:.\n        /// </summary>\n        public static string IndentSize {\n            get {\n                return ResourceManager.GetString(\"IndentSize\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Insert using declarations.\n        /// </summary>\n        public static string InsertUsingDeclarations {\n            get {\n                return ResourceManager.GetString(\"InsertUsingDeclarations\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Are you sure that you want to delete the selected assembly list?.\n        /// </summary>\n        public static string ListDeleteConfirmation {\n            get {\n                return ResourceManager.GetString(\"ListDeleteConfirmation\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to A list with the same name was found..\n        /// </summary>\n        public static string ListExistsAlready {\n            get {\n                return ResourceManager.GetString(\"ListExistsAlready\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Are you sure that you want to remove all assembly lists and recreate the default assembly lists?.\n        /// </summary>\n        public static string ListsResetConfirmation {\n            get {\n                return ResourceManager.GetString(\"ListsResetConfirmation\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Load assemblies that were loaded in the last instance..\n        /// </summary>\n        public static string LoadAssembliesThatWereLoadedInTheLastInstance {\n            get {\n                return ResourceManager.GetString(\"LoadAssembliesThatWereLoadedInTheLastInstance\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Loading....\n        /// </summary>\n        public static string Loading {\n            get {\n                return ResourceManager.GetString(\"Loading\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Location.\n        /// </summary>\n        public static string Location {\n            get {\n                return ResourceManager.GetString(\"Location\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Manage assembly _lists....\n        /// </summary>\n        public static string ManageAssembly_Lists {\n            get {\n                return ResourceManager.GetString(\"ManageAssembly_Lists\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Manage Assembly Lists.\n        /// </summary>\n        public static string ManageAssemblyLists {\n            get {\n                return ResourceManager.GetString(\"ManageAssemblyLists\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Metadata.\n        /// </summary>\n        public static string Metadata {\n            get {\n                return ResourceManager.GetString(\"Metadata\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Misc.\n        /// </summary>\n        public static string Misc {\n            get {\n                return ResourceManager.GetString(\"Misc\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Name.\n        /// </summary>\n        public static string Name {\n            get {\n                return ResourceManager.GetString(\"Name\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Navigation.\n        /// </summary>\n        public static string Navigation {\n            get {\n                return ResourceManager.GetString(\"Navigation\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Navigation failed because the target is hidden or a compiler-generated class.\n        ///Please disable all filters that might hide the item (i.e. activate &quot;View &gt; Show internal types and members&quot;) and try again..\n        /// </summary>\n        public static string NavigationFailed {\n            get {\n                return ResourceManager.GetString(\"NavigationFailed\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to .NET version .\n        /// </summary>\n        public static string NETFrameworkVersion {\n            get {\n                return ResourceManager.GetString(\"NETFrameworkVersion\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to New list.\n        /// </summary>\n        public static string NewList {\n            get {\n                return ResourceManager.GetString(\"NewList\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to New Tab.\n        /// </summary>\n        public static string NewTab {\n            get {\n                return ResourceManager.GetString(\"NewTab\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Nuget Package Browser.\n        /// </summary>\n        public static string NugetPackageBrowser {\n            get {\n                return ResourceManager.GetString(\"NugetPackageBrowser\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to OK.\n        /// </summary>\n        public static string OK {\n            get {\n                return ResourceManager.GetString(\"OK\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Open.\n        /// </summary>\n        public static string Open {\n            get {\n                return ResourceManager.GetString(\"Open\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Open Explorer.\n        /// </summary>\n        public static string OpenExplorer {\n            get {\n                return ResourceManager.GetString(\"OpenExplorer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Open From GAC.\n        /// </summary>\n        public static string OpenFrom {\n            get {\n                return ResourceManager.GetString(\"OpenFrom\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Open from _GAC....\n        /// </summary>\n        public static string OpenFrom_GAC {\n            get {\n                return ResourceManager.GetString(\"OpenFrom_GAC\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Delete.\n        /// </summary>\n        public static string OpenListDialog__Delete {\n            get {\n                return ResourceManager.GetString(\"OpenListDialog__Delete\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Open.\n        /// </summary>\n        public static string OpenListDialog__Open {\n            get {\n                return ResourceManager.GetString(\"OpenListDialog__Open\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Operation was cancelled..\n        /// </summary>\n        public static string OperationWasCancelled {\n            get {\n                return ResourceManager.GetString(\"OperationWasCancelled\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Options.\n        /// </summary>\n        public static string Options {\n            get {\n                return ResourceManager.GetString(\"Options\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Other.\n        /// </summary>\n        public static string Other {\n            get {\n                return ResourceManager.GetString(\"Other\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Other options.\n        /// </summary>\n        public static string OtherOptions {\n            get {\n                return ResourceManager.GetString(\"OtherOptions\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Other Resources.\n        /// </summary>\n        public static string OtherResources {\n            get {\n                return ResourceManager.GetString(\"OtherResources\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Portable PDB|*.pdb|All files|*.*.\n        /// </summary>\n        public static string PortablePDBPdbAllFiles {\n            get {\n                return ResourceManager.GetString(\"PortablePDBPdbAllFiles\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to You can change this by toggling the setting at Options &gt; Decompiler &gt; Project export &gt; Use new SDK style format for generated project files (*.csproj)..\n        /// </summary>\n        public static string ProjectExportFormatChangeSettingHint {\n            get {\n                return ResourceManager.GetString(\"ProjectExportFormatChangeSettingHint\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to A Non-SDK project was generated. Learn more at https://docs.microsoft.com/en-us/nuget/resources/check-project-format..\n        /// </summary>\n        public static string ProjectExportFormatNonSDKHint {\n            get {\n                return ResourceManager.GetString(\"ProjectExportFormatNonSDKHint\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to A SDK-style project was generated. Learn more at https://docs.microsoft.com/en-us/nuget/resources/check-project-format..\n        /// </summary>\n        public static string ProjectExportFormatSDKHint {\n            get {\n                return ResourceManager.GetString(\"ProjectExportFormatSDKHint\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Failed to decompile the assemblies {0} because the namespace names are too long or the directory structure is nested too deep.\n        ///\n        ///If you are using Windows 10.0.14393 (Windows 10 version 1607) or later, you can enable &quot;Long path support&quot; by creating a REG_DWORD registry key named &quot;LongPathsEnabled&quot; with value 0x1 at &quot;HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\FileSystem&quot; (see https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation for more information).\n        ///\n        ///If this does not [rest of string was truncated]&quot;;.\n        /// </summary>\n        public static string ProjectExportPathTooLong {\n            get {\n                return ResourceManager.GetString(\"ProjectExportPathTooLong\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to for ex. property getter/setter access. To get optimal decompilation results, please manually add the missing references to the list of loaded assemblies..\n        /// </summary>\n        public static string PropertyManuallyMissingReferencesListLoadedAssemblies {\n            get {\n                return ResourceManager.GetString(\"PropertyManuallyMissingReferencesListLoadedAssemblies\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Public Key Token.\n        /// </summary>\n        public static string PublicToken {\n            get {\n                return ResourceManager.GetString(\"PublicToken\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to R_ename.\n        /// </summary>\n        public static string R_ename {\n            get {\n                return ResourceManager.GetString(\"R_ename\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Referenced Types.\n        /// </summary>\n        public static string ReferencedTypes {\n            get {\n                return ResourceManager.GetString(\"ReferencedTypes\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Reference Name.\n        /// </summary>\n        public static string ReferenceName {\n            get {\n                return ResourceManager.GetString(\"ReferenceName\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to References.\n        /// </summary>\n        public static string References {\n            get {\n                return ResourceManager.GetString(\"References\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Reload all assemblies.\n        /// </summary>\n        public static string RefreshCommand_ReloadAssemblies {\n            get {\n                return ResourceManager.GetString(\"RefreshCommand_ReloadAssemblies\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Reload all assemblies.\n        /// </summary>\n        public static string ReloadAssemblies {\n            get {\n                return ResourceManager.GetString(\"ReloadAssemblies\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Remove.\n        /// </summary>\n        public static string Remove {\n            get {\n                return ResourceManager.GetString(\"Remove\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Remove dead and side effect free code.\n        /// </summary>\n        public static string RemoveDeadSideEffectFreeCode {\n            get {\n                return ResourceManager.GetString(\"RemoveDeadSideEffectFreeCode\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Remove shell integration.\n        /// </summary>\n        public static string RemoveShellIntegration {\n            get {\n                return ResourceManager.GetString(\"RemoveShellIntegration\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to This will remove &quot;{0}&quot; from the registry at &quot;HKCU\\Software\\Classes\\dllfile\\shell\\Open with ILSpy\\command&quot; and &quot;HKCU\\Software\\Classes\\exefile\\shell\\Open with ILSpy\\command&quot;.\n        ///\n        ///Do you want to continue?.\n        /// </summary>\n        public static string RemoveShellIntegrationMessage {\n            get {\n                return ResourceManager.GetString(\"RemoveShellIntegrationMessage\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Rename list.\n        /// </summary>\n        public static string RenameList {\n            get {\n                return ResourceManager.GetString(\"RenameList\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Reset to defaults.\n        /// </summary>\n        public static string ResetToDefaults {\n            get {\n                return ResourceManager.GetString(\"ResetToDefaults\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Do you really want to load the default settings for the active page?.\n        /// </summary>\n        public static string ResetToDefaultsConfirmationMessage {\n            get {\n                return ResourceManager.GetString(\"ResetToDefaultsConfirmationMessage\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Resources file (*.resources)|*.resources|Resource XML file|*.resx.\n        /// </summary>\n        public static string ResourcesFileFilter {\n            get {\n                return ResourceManager.GetString(\"ResourcesFileFilter\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Save.\n        /// </summary>\n        public static string Save {\n            get {\n                return ResourceManager.GetString(\"Save\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Save Code.\n        /// </summary>\n        public static string SaveCode {\n            get {\n                return ResourceManager.GetString(\"SaveCode\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Scope search to this assembly.\n        /// </summary>\n        public static string ScopeSearchToThisAssembly {\n            get {\n                return ResourceManager.GetString(\"ScopeSearchToThisAssembly\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Scope search to this namespace.\n        /// </summary>\n        public static string ScopeSearchToThisNamespace {\n            get {\n                return ResourceManager.GetString(\"ScopeSearchToThisNamespace\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Search....\n        /// </summary>\n        public static string Search {\n            get {\n                return ResourceManager.GetString(\"Search\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Search aborted, more than 1000 results found..\n        /// </summary>\n        public static string SearchAbortedMoreThan1000ResultsFound {\n            get {\n                return ResourceManager.GetString(\"SearchAbortedMoreThan1000ResultsFound\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Search (Ctrl+Shift+F or Ctrl+E).\n        /// </summary>\n        public static string SearchCtrlShiftFOrCtrlE {\n            get {\n                return ResourceManager.GetString(\"SearchCtrlShiftFOrCtrlE\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Searching....\n        /// </summary>\n        public static string Searching {\n            get {\n                return ResourceManager.GetString(\"Searching\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Search Microsoft Docs....\n        /// </summary>\n        public static string SearchMSDN {\n            get {\n                return ResourceManager.GetString(\"SearchMSDN\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Search.\n        /// </summary>\n        public static string SearchPane_Search {\n            get {\n                return ResourceManager.GetString(\"SearchPane_Search\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Select All.\n        /// </summary>\n        public static string Select {\n            get {\n                return ResourceManager.GetString(\"Select\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Select assemblies to open:.\n        /// </summary>\n        public static string SelectAssembliesOpen {\n            get {\n                return ResourceManager.GetString(\"SelectAssembliesOpen\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Select a list of assemblies (Alt+A).\n        /// </summary>\n        public static string SelectAssemblyListDropdownTooltip {\n            get {\n                return ResourceManager.GetString(\"SelectAssemblyListDropdownTooltip\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Select language to decompile to (Alt+L).\n        /// </summary>\n        public static string SelectLanguageDropdownTooltip {\n            get {\n                return ResourceManager.GetString(\"SelectLanguageDropdownTooltip\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Select a list:.\n        /// </summary>\n        public static string SelectList {\n            get {\n                return ResourceManager.GetString(\"SelectList\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Select PDB....\n        /// </summary>\n        public static string SelectPDB {\n            get {\n                return ResourceManager.GetString(\"SelectPDB\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Select target folder.\n        /// </summary>\n        public static string SelectPDBOutputFolder {\n            get {\n                return ResourceManager.GetString(\"SelectPDBOutputFolder\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Select version of language to output (Alt+E).\n        /// </summary>\n        public static string SelectVersionDropdownTooltip {\n            get {\n                return ResourceManager.GetString(\"SelectVersionDropdownTooltip\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to You must restart ILSpy for the change to take effect..\n        /// </summary>\n        public static string SettingsChangeRestartRequired {\n            get {\n                return ResourceManager.GetString(\"SettingsChangeRestartRequired\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Shell.\n        /// </summary>\n        public static string Shell {\n            get {\n                return ResourceManager.GetString(\"Shell\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show _all types and members.\n        /// </summary>\n        public static string Show_allTypesAndMembers {\n            get {\n                return ResourceManager.GetString(\"Show_allTypesAndMembers\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show public, private and internal.\n        /// </summary>\n        public static string Show_internalTypesMembers {\n            get {\n                return ResourceManager.GetString(\"Show_internalTypesMembers\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show only _public types and members.\n        /// </summary>\n        public static string Show_publiconlyTypesMembers {\n            get {\n                return ResourceManager.GetString(\"Show_publiconlyTypesMembers\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show all types and members.\n        /// </summary>\n        public static string ShowAllTypesAndMembers {\n            get {\n                return ResourceManager.GetString(\"ShowAllTypesAndMembers\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show assembly load log.\n        /// </summary>\n        public static string ShowAssemblyLoad {\n            get {\n                return ResourceManager.GetString(\"ShowAssemblyLoad\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to ShowChildIndexInBlock.\n        /// </summary>\n        public static string ShowChildIndexInBlock {\n            get {\n                return ResourceManager.GetString(\"ShowChildIndexInBlock\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show XML documentation in decompiled code.\n        /// </summary>\n        public static string ShowDocumentationDecompiledCode {\n            get {\n                return ResourceManager.GetString(\"ShowDocumentationDecompiledCode\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to ShowILRanges.\n        /// </summary>\n        public static string ShowILRanges {\n            get {\n                return ResourceManager.GetString(\"ShowILRanges\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show info from debug symbols, if available.\n        /// </summary>\n        public static string ShowInfoFromDebugSymbolsAvailable {\n            get {\n                return ResourceManager.GetString(\"ShowInfoFromDebugSymbolsAvailable\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show public, private and internal.\n        /// </summary>\n        public static string ShowInternalTypesMembers {\n            get {\n                return ResourceManager.GetString(\"ShowInternalTypesMembers\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show line numbers.\n        /// </summary>\n        public static string ShowLineNumbers {\n            get {\n                return ResourceManager.GetString(\"ShowLineNumbers\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show metadata tokens.\n        /// </summary>\n        public static string ShowMetadataTokens {\n            get {\n                return ResourceManager.GetString(\"ShowMetadataTokens\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show metadata tokens in base 10.\n        /// </summary>\n        public static string ShowMetadataTokensInBase10 {\n            get {\n                return ResourceManager.GetString(\"ShowMetadataTokensInBase10\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show only public types and members.\n        /// </summary>\n        public static string ShowPublicOnlyTypesMembers {\n            get {\n                return ResourceManager.GetString(\"ShowPublicOnlyTypesMembers\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show raw offsets and bytes before each instruction.\n        /// </summary>\n        public static string ShowRawOffsetsAndBytesBeforeInstruction {\n            get {\n                return ResourceManager.GetString(\"ShowRawOffsetsAndBytesBeforeInstruction\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show state after this step.\n        /// </summary>\n        public static string ShowStateAfterThisStep {\n            get {\n                return ResourceManager.GetString(\"ShowStateAfterThisStep\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show state before this step.\n        /// </summary>\n        public static string ShowStateBeforeThisStep {\n            get {\n                return ResourceManager.GetString(\"ShowStateBeforeThisStep\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Size:.\n        /// </summary>\n        public static string Size {\n            get {\n                return ResourceManager.GetString(\"Size\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Sort assembly _list by name.\n        /// </summary>\n        public static string SortAssembly_listName {\n            get {\n                return ResourceManager.GetString(\"SortAssembly_listName\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Sort assembly list by name.\n        /// </summary>\n        public static string SortAssemblyListName {\n            get {\n                return ResourceManager.GetString(\"SortAssemblyListName\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Sort results by fitness.\n        /// </summary>\n        public static string SortResultsFitness {\n            get {\n                return ResourceManager.GetString(\"SortResultsFitness\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Stand by....\n        /// </summary>\n        public static string StandBy {\n            get {\n                return ResourceManager.GetString(\"StandBy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Status.\n        /// </summary>\n        public static string Status {\n            get {\n                return ResourceManager.GetString(\"Status\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to String Table.\n        /// </summary>\n        public static string StringTable {\n            get {\n                return ResourceManager.GetString(\"StringTable\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Style the window title bar.\n        /// </summary>\n        public static string StyleTheWindowTitleBar {\n            get {\n                return ResourceManager.GetString(\"StyleTheWindowTitleBar\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Tab size:.\n        /// </summary>\n        public static string TabSize {\n            get {\n                return ResourceManager.GetString(\"TabSize\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Theme.\n        /// </summary>\n        public static string Theme {\n            get {\n                return ResourceManager.GetString(\"Theme\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Toggle All Folding.\n        /// </summary>\n        public static string ToggleFolding {\n            get {\n                return ResourceManager.GetString(\"ToggleFolding\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Tree view options.\n        /// </summary>\n        public static string TreeViewOptions {\n            get {\n                return ResourceManager.GetString(\"TreeViewOptions\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Type.\n        /// </summary>\n        public static string Type {\n            get {\n                return ResourceManager.GetString(\"Type\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to UI Language.\n        /// </summary>\n        public static string UILanguage {\n            get {\n                return ResourceManager.GetString(\"UILanguage\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to System.\n        /// </summary>\n        public static string UILanguage_System {\n            get {\n                return ResourceManager.GetString(\"UILanguage_System\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to No update for ILSpy found..\n        /// </summary>\n        public static string UpdateILSpyFound {\n            get {\n                return ResourceManager.GetString(\"UpdateILSpyFound\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to UseFieldSugar.\n        /// </summary>\n        public static string UseFieldSugar {\n            get {\n                return ResourceManager.GetString(\"UseFieldSugar\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to UseLogicOperationSugar.\n        /// </summary>\n        public static string UseLogicOperationSugar {\n            get {\n                return ResourceManager.GetString(\"UseLogicOperationSugar\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use nested namespace structure.\n        /// </summary>\n        public static string UseNestedNamespaceNodes {\n            get {\n                return ResourceManager.GetString(\"UseNestedNamespaceNodes\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use tabs instead of spaces.\n        /// </summary>\n        public static string UseTabsInsteadOfSpaces {\n            get {\n                return ResourceManager.GetString(\"UseTabsInsteadOfSpaces\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to You are using the latest release..\n        /// </summary>\n        public static string UsingLatestRelease {\n            get {\n                return ResourceManager.GetString(\"UsingLatestRelease\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to You are using a nightly build newer than the latest release..\n        /// </summary>\n        public static string UsingNightlyBuildNewerThanLatestRelease {\n            get {\n                return ResourceManager.GetString(\"UsingNightlyBuildNewerThanLatestRelease\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Value.\n        /// </summary>\n        public static string Value {\n            get {\n                return ResourceManager.GetString(\"Value\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Value (as string).\n        /// </summary>\n        public static string ValueString {\n            get {\n                return ResourceManager.GetString(\"ValueString\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use variable names from debug symbols, if available.\n        /// </summary>\n        public static string VariableNamesFromDebugSymbolsAvailable {\n            get {\n                return ResourceManager.GetString(\"VariableNamesFromDebugSymbolsAvailable\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Version.\n        /// </summary>\n        public static string Version {\n            get {\n                return ResourceManager.GetString(\"Version\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Version {0} is available..\n        /// </summary>\n        public static string VersionAvailable {\n            get {\n                return ResourceManager.GetString(\"VersionAvailable\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to View.\n        /// </summary>\n        public static string View {\n            get {\n                return ResourceManager.GetString(\"View\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Visual Studio Solution file|*.sln|All files|*.*.\n        /// </summary>\n        public static string VisualStudioSolutionFileSlnAllFiles {\n            get {\n                return ResourceManager.GetString(\"VisualStudioSolutionFileSlnAllFiles\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Warning: This assembly is marked as &apos;reference assembly&apos;, which means that it only contains metadata and no executable code..\n        /// </summary>\n        public static string WarningAsmMarkedRef {\n            get {\n                return ResourceManager.GetString(\"WarningAsmMarkedRef\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Warning: Some assembly references could not be resolved automatically. This might lead to incorrect decompilation of some parts,.\n        /// </summary>\n        public static string WarningSomeAssemblyReference {\n            get {\n                return ResourceManager.GetString(\"WarningSomeAssemblyReference\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Search for t:TypeName, m:Member or c:Constant; use exact match (=term), &apos;should not contain&apos; (-term) or &apos;must contain&apos; (+term); use /reg(ular)?Ex(pressions)?/ or both - t:/Type(Name)?/....\n        /// </summary>\n        public static string WatermarkText {\n            get {\n                return ResourceManager.GetString(\"WatermarkText\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Close all documents.\n        /// </summary>\n        public static string Window_CloseAllDocuments {\n            get {\n                return ResourceManager.GetString(\"Window_CloseAllDocuments\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to _Reset layout.\n        /// </summary>\n        public static string Window_ResetLayout {\n            get {\n                return ResourceManager.GetString(\"Window_ResetLayout\", resourceCulture);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "ILSpy/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"About\" xml:space=\"preserve\">\n    <value>About</value>\n  </data>\n  <data name=\"AddPreconfiguredList\" xml:space=\"preserve\">\n    <value>Add preconfigured list...</value>\n  </data>\n  <data name=\"AddShellIntegration\" xml:space=\"preserve\">\n    <value>Add shell integration</value>\n  </data>\n  <data name=\"AddShellIntegrationMessage\" xml:space=\"preserve\">\n    <value>This will add \"{0}\" to the registry at \"HKCU\\Software\\Classes\\dllfile\\shell\\Open with ILSpy\\command\" and \"HKCU\\Software\\Classes\\exefile\\shell\\Open with ILSpy\\command\" to allow opening .dll and .exe files from the Windows Explorer context menu.\n\nDo you want to continue?</value>\n  </data>\n  <data name=\"AllFiles\" xml:space=\"preserve\">\n    <value>|All Files|*.*</value>\n  </data>\n  <data name=\"AllowMultipleInstances\" xml:space=\"preserve\">\n    <value>Allow multiple instances</value>\n  </data>\n  <data name=\"AlwaysBraces\" xml:space=\"preserve\">\n    <value>Always use braces</value>\n  </data>\n  <data name=\"Analyze\" xml:space=\"preserve\">\n    <value>Analyze</value>\n  </data>\n  <data name=\"Assemblies\" xml:space=\"preserve\">\n    <value>Assemblies</value>\n  </data>\n  <data name=\"Assembly\" xml:space=\"preserve\">\n    <value>Assembly</value>\n  </data>\n  <data name=\"AssemblySaveCodeDirectoryNotEmpty\" xml:space=\"preserve\">\n    <value>The directory is not empty. File will be overwritten.\nAre you sure you want to continue?</value>\n  </data>\n  <data name=\"AssemblySaveCodeDirectoryNotEmptyTitle\" xml:space=\"preserve\">\n    <value>Project Directory not empty</value>\n  </data>\n  <data name=\"AutomaticallyCheckUpdatesEveryWeek\" xml:space=\"preserve\">\n    <value>Automatically check for updates every week</value>\n  </data>\n  <data name=\"Back\" xml:space=\"preserve\">\n    <value>Back</value>\n  </data>\n  <data name=\"BaseTypes\" xml:space=\"preserve\">\n    <value>Base Types</value>\n  </data>\n  <data name=\"C_lone\" xml:space=\"preserve\">\n    <value>C_lone</value>\n  </data>\n  <data name=\"Cancel\" xml:space=\"preserve\">\n    <value>Cancel</value>\n  </data>\n  <data name=\"CannotAnalyzeMissingRef\" xml:space=\"preserve\">\n    <value>Entity could not be resolved. Cannot analyze entities from missing assembly references. Add the missing reference and try again.</value>\n  </data>\n  <data name=\"CannotCreatePDBFile\" xml:space=\"preserve\">\n    <value>Cannot create PDB file for {0} because the PE debug directory type 'CodeView' is missing.</value>\n  </data>\n  <data name=\"CheckAgain\" xml:space=\"preserve\">\n    <value>Check again</value>\n  </data>\n  <data name=\"CheckUpdates\" xml:space=\"preserve\">\n    <value>Check for updates</value>\n  </data>\n  <data name=\"Checking\" xml:space=\"preserve\">\n    <value>Checking...</value>\n  </data>\n  <data name=\"ClearAssemblyList\" xml:space=\"preserve\">\n    <value>Clear assembly list</value>\n  </data>\n  <data name=\"Close\" xml:space=\"preserve\">\n    <value>Close</value>\n  </data>\n  <data name=\"CollapseTreeNodes\" xml:space=\"preserve\">\n    <value>Collapse all tree nodes</value>\n  </data>\n  <data name=\"Copy\" xml:space=\"preserve\">\n    <value>Copy</value>\n  </data>\n  <data name=\"CopyErrorMessage\" xml:space=\"preserve\">\n    <value>Copy error message</value>\n  </data>\n  <data name=\"CopyName\" xml:space=\"preserve\">\n    <value>Copy FQ Name</value>\n  </data>\n  <data name=\"CouldNotUseSdkStyleProjectFormat\" xml:space=\"preserve\">\n    <value>Could not use SDK-style project format, because no compatible target-framework moniker was found.</value>\n  </data>\n  <data name=\"Create\" xml:space=\"preserve\">\n    <value>Create</value>\n  </data>\n  <data name=\"CreatingDiagram\" xml:space=\"preserve\">\n    <value>Creating diagram...</value>\n  </data>\n  <data name=\"CultureLabel\" xml:space=\"preserve\">\n    <value>Culture</value>\n  </data>\n  <data name=\"DEBUGDecompile\" xml:space=\"preserve\">\n    <value>DEBUG -- Decompile All</value>\n  </data>\n  <data name=\"DEBUGDecompile100x\" xml:space=\"preserve\">\n    <value>DEBUG -- Decompile 100x</value>\n  </data>\n  <data name=\"DEBUGDisassemble\" xml:space=\"preserve\">\n    <value>DEBUG -- Disassemble All</value>\n  </data>\n  <data name=\"DEBUGDumpPDBAsXML\" xml:space=\"preserve\">\n    <value>DEBUG -- Dump PDB as XML</value>\n  </data>\n  <data name=\"DebugSteps\" xml:space=\"preserve\">\n    <value>Debug Steps</value>\n  </data>\n  <data name=\"DebugThisStep\" xml:space=\"preserve\">\n    <value>Debug this step</value>\n  </data>\n  <data name=\"DecodeCustomAttributeBlobs\" xml:space=\"preserve\">\n    <value>Decode custom attribute blobs</value>\n  </data>\n  <data name=\"DecompilationCompleteInF1Seconds\" xml:space=\"preserve\">\n    <value>Decompilation complete in {0:F1} seconds.</value>\n  </data>\n  <data name=\"DecompilationViewOptions\" xml:space=\"preserve\">\n    <value>Decompilation view options</value>\n  </data>\n  <data name=\"DecompilationWasCancelled\" xml:space=\"preserve\">\n    <value>Decompilation was cancelled.</value>\n  </data>\n  <data name=\"Decompile\" xml:space=\"preserve\">\n    <value>Decompile</value>\n  </data>\n  <data name=\"DecompileToNewPanel\" xml:space=\"preserve\">\n    <value>Decompile to new tab</value>\n  </data>\n  <data name=\"Decompiler\" xml:space=\"preserve\">\n    <value>Decompiler</value>\n  </data>\n  <data name=\"DecompilerSettings.AggressiveInlining\" xml:space=\"preserve\">\n    <value>Always inline local variables if possible</value>\n  </data>\n  <data name=\"DecompilerSettings.AllowExtensionAddMethodsInCollectionInitializerExpressions\" xml:space=\"preserve\">\n    <value>Allow extension 'Add' methods in collection initializer expressions</value>\n  </data>\n  <data name=\"DecompilerSettings.AllowExtensionMethodSyntaxOnRef\" xml:space=\"preserve\">\n    <value>Use 'ref' extension methods</value>\n  </data>\n  <data name=\"DecompilerSettings.AlwaysCastTargetsOfExplicitInterfaceImplementationCalls\" xml:space=\"preserve\">\n    <value>Always cast targets of explicit interface implementation calls</value>\n  </data>\n  <data name=\"DecompilerSettings.AlwaysMoveInitializer\" xml:space=\"preserve\">\n    <value>Always move field initializers from constructors to declarations</value>\n  </data>\n  <data name=\"DecompilerSettings.AlwaysQualifyMemberReferences\" xml:space=\"preserve\">\n    <value>Always qualify member references</value>\n  </data>\n  <data name=\"DecompilerSettings.AlwaysShowEnumMemberValues\" xml:space=\"preserve\">\n    <value>Always show enum member values</value>\n  </data>\n  <data name=\"DecompilerSettings.AlwaysUseBraces\" xml:space=\"preserve\">\n    <value>Always use braces</value>\n  </data>\n  <data name=\"DecompilerSettings.AlwaysUseGlobal\" xml:space=\"preserve\">\n    <value>Always fully qualify namespaces using the \"global::\" prefix</value>\n  </data>\n  <data name=\"DecompilerSettings.ApplyWindowsRuntimeProjectionsOnLoadedAssemblies\" xml:space=\"preserve\">\n    <value>Apply Windows Runtime projections on loaded assemblies</value>\n  </data>\n  <data name=\"DecompilerSettings.ArrayInitializerExpressions\" xml:space=\"preserve\">\n    <value>Array initializer expressions</value>\n  </data>\n  <data name=\"DecompilerSettings.AsyncEnumerator\" xml:space=\"preserve\">\n    <value>Decompile async IAsyncEnumerator methods</value>\n  </data>\n  <data name=\"DecompilerSettings.AutoLoadAssemblyReferences\" xml:space=\"preserve\">\n    <value>Automatically load assembly references</value>\n  </data>\n  <data name=\"DecompilerSettings.CheckForOverflowUnderflow\" xml:space=\"preserve\">\n    <value>Check for overflow and underflow in operators</value>\n  </data>\n  <data name=\"DecompilerSettings.CheckedOperators\" xml:space=\"preserve\">\n    <value>User-defined checked operators</value>\n  </data>\n  <data name=\"DecompilerSettings.DecompileAnonymousMethodsLambdas\" xml:space=\"preserve\">\n    <value>Decompile anonymous methods/lambdas</value>\n  </data>\n  <data name=\"DecompilerSettings.DecompileAnonymousTypes\" xml:space=\"preserve\">\n    <value>Decompile anonymous types</value>\n  </data>\n  <data name=\"DecompilerSettings.DecompileAsyncMethods\" xml:space=\"preserve\">\n    <value>Decompile async methods</value>\n  </data>\n  <data name=\"DecompilerSettings.DecompileAutomaticEvents\" xml:space=\"preserve\">\n    <value>Decompile automatic events</value>\n  </data>\n  <data name=\"DecompilerSettings.DecompileAutomaticProperties\" xml:space=\"preserve\">\n    <value>Decompile automatic properties</value>\n  </data>\n  <data name=\"DecompilerSettings.DecompileAwaitInCatchFinallyBlocks\" xml:space=\"preserve\">\n    <value>Decompile await in catch/finally blocks</value>\n  </data>\n  <data name=\"DecompilerSettings.DecompileC10PublicUnsafeFixedIntArr10Members\" xml:space=\"preserve\">\n    <value>Decompile C# 1.0 'public unsafe fixed int arr[10];' members</value>\n  </data>\n  <data name=\"DecompilerSettings.DecompileDecimalConstantAsSimpleLiteralValues\" xml:space=\"preserve\">\n    <value>Decompile [DecimalConstant(...)] as simple literal values</value>\n  </data>\n  <data name=\"DecompilerSettings.DecompileEnumeratorsYieldReturn\" xml:space=\"preserve\">\n    <value>Decompile enumerators (yield return)</value>\n  </data>\n  <data name=\"DecompilerSettings.DecompileExpressionTrees\" xml:space=\"preserve\">\n    <value>Decompile expression trees</value>\n  </data>\n  <data name=\"DecompilerSettings.DecompileForEachWithGetEnumeratorExtension\" xml:space=\"preserve\">\n    <value>Decompile foreach statements with GetEnumerator extension methods</value>\n  </data>\n  <data name=\"DecompilerSettings.DecompileParamsCollections\" xml:space=\"preserve\">\n    <value>Decompile params collections</value>\n  </data>\n  <data name=\"DecompilerSettings.DecompileUseOfTheDynamicType\" xml:space=\"preserve\">\n    <value>Decompile use of the 'dynamic' type</value>\n  </data>\n  <data name=\"DecompilerSettings.Deconstruction\" xml:space=\"preserve\">\n    <value>Detect deconstruction assignments</value>\n  </data>\n  <data name=\"DecompilerSettings.DetectAsyncUsingAndForeachStatements\" xml:space=\"preserve\">\n    <value>Detect awaited using and foreach statements</value>\n  </data>\n  <data name=\"DecompilerSettings.DetectForeachStatements\" xml:space=\"preserve\">\n    <value>Detect foreach statements</value>\n  </data>\n  <data name=\"DecompilerSettings.DetectLockStatements\" xml:space=\"preserve\">\n    <value>Detect lock statements</value>\n  </data>\n  <data name=\"DecompilerSettings.DetectSwitchOnString\" xml:space=\"preserve\">\n    <value>Detect switch on string</value>\n  </data>\n  <data name=\"DecompilerSettings.DetectTupleComparisons\" xml:space=\"preserve\">\n    <value>Detect tuple comparisons</value>\n  </data>\n  <data name=\"DecompilerSettings.DetectUsingStatements\" xml:space=\"preserve\">\n    <value>Detect using statements</value>\n  </data>\n  <data name=\"DecompilerSettings.DictionaryInitializerExpressions\" xml:space=\"preserve\">\n    <value>Dictionary initializer expressions</value>\n  </data>\n  <data name=\"DecompilerSettings.DoWhileStatement\" xml:space=\"preserve\">\n    <value>Transform to do-while, if possible</value>\n  </data>\n  <data name=\"DecompilerSettings.ExpandParamsArguments\" xml:space=\"preserve\">\n    <value>Expand params arguments by removing explicit array creation</value>\n  </data>\n  <data name=\"DecompilerSettings.FSpecificOptions\" xml:space=\"preserve\">\n    <value>F#-specific options</value>\n  </data>\n  <data name=\"DecompilerSettings.FileScopedNamespaces\" xml:space=\"preserve\">\n    <value>Use file-scoped namespace declarations</value>\n  </data>\n  <data name=\"DecompilerSettings.FirstClassSpanTypes\" xml:space=\"preserve\">\n    <value>Treat Span&lt;T&gt; and ReadOnlySpan&lt;T&gt; as built-in types</value>\n  </data>\n  <data name=\"DecompilerSettings.ForStatement\" xml:space=\"preserve\">\n    <value>Transform to for, if possible</value>\n  </data>\n  <data name=\"DecompilerSettings.FunctionPointers\" xml:space=\"preserve\">\n    <value>Function pointers</value>\n  </data>\n  <data name=\"DecompilerSettings.GetterOnlyAutomaticProperties\" xml:space=\"preserve\">\n    <value>Decompile getter-only automatic properties</value>\n  </data>\n  <data name=\"DecompilerSettings.IncludeXMLDocumentationCommentsInTheDecompiledCode\" xml:space=\"preserve\">\n    <value>Include XML documentation comments in the decompiled code</value>\n  </data>\n  <data name=\"DecompilerSettings.InitAccessors\" xml:space=\"preserve\">\n    <value>Allow init; accessors</value>\n  </data>\n  <data name=\"DecompilerSettings.InsertUsingDeclarations\" xml:space=\"preserve\">\n    <value>Insert using declarations</value>\n  </data>\n  <data name=\"DecompilerSettings.IntroduceLocalFunctions\" xml:space=\"preserve\">\n    <value>Introduce local functions</value>\n  </data>\n  <data name=\"DecompilerSettings.IntroducePrivateProtectedAccessibility\" xml:space=\"preserve\">\n    <value>Introduce 'private protected' accessibility</value>\n  </data>\n  <data name=\"DecompilerSettings.IntroduceStaticLocalFunctions\" xml:space=\"preserve\">\n    <value>Introduce static local functions</value>\n  </data>\n  <data name=\"DecompilerSettings.IsByRefLikeAttributeShouldBeReplacedWithRefModifiersOnStructs\" xml:space=\"preserve\">\n    <value>IsByRefLikeAttribute should be replaced with 'ref' modifiers on structs</value>\n  </data>\n  <data name=\"DecompilerSettings.IsReadOnlyAttributeShouldBeReplacedWithReadonlyInModifiersOnStructsParameters\" xml:space=\"preserve\">\n    <value>IsReadOnlyAttribute should be replaced with 'readonly'/'in' modifiers on structs/parameters</value>\n  </data>\n  <data name=\"DecompilerSettings.IsUnmanagedAttributeOnTypeParametersShouldBeReplacedWithUnmanagedConstraints\" xml:space=\"preserve\">\n    <value>IsUnmanagedAttribute on type parameters should be replaced with 'unmanaged' constraints</value>\n  </data>\n  <data name=\"DecompilerSettings.NativeIntegers\" xml:space=\"preserve\">\n    <value>Use nint/nuint types</value>\n  </data>\n  <data name=\"DecompilerSettings.NullPropagation\" xml:space=\"preserve\">\n    <value>Decompile ?. and ?[] operators</value>\n  </data>\n  <data name=\"DecompilerSettings.NullableReferenceTypes\" xml:space=\"preserve\">\n    <value>Nullable reference types</value>\n  </data>\n  <data name=\"DecompilerSettings.NumericIntPtr\" xml:space=\"preserve\">\n    <value>Treat (U)IntPtr as n(u)int</value>\n  </data>\n  <data name=\"DecompilerSettings.ObjectCollectionInitializerExpressions\" xml:space=\"preserve\">\n    <value>Object/collection initializer expressions</value>\n  </data>\n  <data name=\"DecompilerSettings.Other\" xml:space=\"preserve\">\n    <value>Other</value>\n  </data>\n  <data name=\"DecompilerSettings.PatternCombinators\" xml:space=\"preserve\">\n    <value>Pattern combinators (and, or, not)</value>\n  </data>\n  <data name=\"DecompilerSettings.PatternMatching\" xml:space=\"preserve\">\n    <value>Use pattern matching expressions</value>\n  </data>\n  <data name=\"DecompilerSettings.ProjectExport\" xml:space=\"preserve\">\n    <value>Project export</value>\n  </data>\n  <data name=\"DecompilerSettings.Ranges\" xml:space=\"preserve\">\n    <value>Ranges</value>\n  </data>\n  <data name=\"DecompilerSettings.ReadOnlyMethods\" xml:space=\"preserve\">\n    <value>Read-only methods</value>\n  </data>\n  <data name=\"DecompilerSettings.RecordClasses\" xml:space=\"preserve\">\n    <value>Record classes</value>\n  </data>\n  <data name=\"DecompilerSettings.RecordStructs\" xml:space=\"preserve\">\n    <value>Record structs</value>\n  </data>\n  <data name=\"DecompilerSettings.RecursivePatternMatching\" xml:space=\"preserve\">\n    <value>Recursive pattern matching</value>\n  </data>\n  <data name=\"DecompilerSettings.RefReadOnlyParameters\" xml:space=\"preserve\">\n    <value>'ref readonly' parameters</value>\n  </data>\n  <data name=\"DecompilerSettings.RelationalPatterns\" xml:space=\"preserve\">\n    <value>Relational patterns</value>\n  </data>\n  <data name=\"DecompilerSettings.RemoveDeadAndSideEffectFreeCodeUseWithCaution\" xml:space=\"preserve\">\n    <value>Remove dead and side effect free code (use with caution!)</value>\n  </data>\n  <data name=\"DecompilerSettings.RemoveDeadStores\" xml:space=\"preserve\">\n    <value>Remove dead stores (use with caution!)</value>\n  </data>\n  <data name=\"DecompilerSettings.RemoveOptionalArgumentsIfPossible\" xml:space=\"preserve\">\n    <value>Remove optional arguments, if possible</value>\n  </data>\n  <data name=\"DecompilerSettings.RequiredMembers\" xml:space=\"preserve\">\n    <value>Required members</value>\n  </data>\n  <data name=\"DecompilerSettings.ScopedRef\" xml:space=\"preserve\">\n    <value>'scoped' lifetime annotation</value>\n  </data>\n  <data name=\"DecompilerSettings.SeparateLocalVariableDeclarations\" xml:space=\"preserve\">\n    <value>Separate local variable declarations and initializers (int x = 5; -&gt; int x; x = 5;), if possible</value>\n  </data>\n  <data name=\"DecompilerSettings.ShowInfoFromDebugSymbolsIfAvailable\" xml:space=\"preserve\">\n    <value>Show info from debug symbols, if available</value>\n  </data>\n  <data name=\"DecompilerSettings.SortCustomAttributes\" xml:space=\"preserve\">\n    <value>Sort custom attributes</value>\n  </data>\n  <data name=\"DecompilerSettings.SparseIntegerSwitch\" xml:space=\"preserve\">\n    <value>Detect switch on integer even if IL code does not use a jump table</value>\n  </data>\n  <data name=\"DecompilerSettings.StringConcat\" xml:space=\"preserve\">\n    <value>Decompile 'string.Concat(a, b)' calls into 'a + b'</value>\n  </data>\n  <data name=\"DecompilerSettings.StructDefaultConstructorsAndFieldInitializers\" xml:space=\"preserve\">\n    <value>Use struct field initializers and default constructors</value>\n  </data>\n  <data name=\"DecompilerSettings.SwitchExpressions\" xml:space=\"preserve\">\n    <value>Switch expressions</value>\n  </data>\n  <data name=\"DecompilerSettings.SwitchOnReadOnlySpanChar\" xml:space=\"preserve\">\n    <value>Use switch on (ReadOnly)Span&lt;char&gt;</value>\n  </data>\n  <data name=\"DecompilerSettings.UnsignedRightShift\" xml:space=\"preserve\">\n    <value>Unsigned right shift (&gt;&gt;&gt;)</value>\n  </data>\n  <data name=\"DecompilerSettings.UseDiscards\" xml:space=\"preserve\">\n    <value>Use discards</value>\n  </data>\n  <data name=\"DecompilerSettings.UseEnhancedUsing\" xml:space=\"preserve\">\n    <value>Use enhanced using variable declarations</value>\n  </data>\n  <data name=\"DecompilerSettings.UseExpressionBodiedMemberSyntaxForGetOnlyProperties\" xml:space=\"preserve\">\n    <value>Use expression-bodied member syntax for get-only properties</value>\n  </data>\n  <data name=\"DecompilerSettings.UseExtensionMethodSyntax\" xml:space=\"preserve\">\n    <value>Use extension method syntax</value>\n  </data>\n  <data name=\"DecompilerSettings.UseImplicitConversionsBetweenTupleTypes\" xml:space=\"preserve\">\n    <value>Use implicit conversions between tuple types</value>\n  </data>\n  <data name=\"DecompilerSettings.UseImplicitMethodGroupConversions\" xml:space=\"preserve\">\n    <value>Use implicit method group conversions</value>\n  </data>\n  <data name=\"DecompilerSettings.UseLINQExpressionSyntax\" xml:space=\"preserve\">\n    <value>Use LINQ expression syntax</value>\n  </data>\n  <data name=\"DecompilerSettings.UseLambdaSyntaxIfPossible\" xml:space=\"preserve\">\n    <value>Use lambda syntax, if possible</value>\n  </data>\n  <data name=\"DecompilerSettings.UseLiftedOperatorsForNullables\" xml:space=\"preserve\">\n    <value>Use lifted operators for nullables</value>\n  </data>\n  <data name=\"DecompilerSettings.UseNamedArguments\" xml:space=\"preserve\">\n    <value>Use named arguments</value>\n  </data>\n  <data name=\"DecompilerSettings.UseNestedDirectoriesForNamespaces\" xml:space=\"preserve\">\n    <value>Use nested directories for namespaces</value>\n  </data>\n  <data name=\"DecompilerSettings.UseNonTrailingNamedArguments\" xml:space=\"preserve\">\n    <value>Use non-trailing named arguments</value>\n  </data>\n  <data name=\"DecompilerSettings.UseObjectCreationOfGenericTypeParameter\" xml:space=\"preserve\">\n    <value>Use new T() instead of Activator.CreateInstance&lt;T&gt;</value>\n  </data>\n  <data name=\"DecompilerSettings.UseOutVariableDeclarations\" xml:space=\"preserve\">\n    <value>Use out variable declarations</value>\n  </data>\n  <data name=\"DecompilerSettings.UsePatternBasedFixedStatement\" xml:space=\"preserve\">\n    <value>Use pattern-based fixed statement</value>\n  </data>\n  <data name=\"DecompilerSettings.UsePrimaryConstructorDecompilerSettings.SyntaxForNonRecordTypes\" xml:space=\"preserve\">\n    <value>Use primary constructor syntax for non-record types</value>\n  </data>\n  <data name=\"DecompilerSettings.UsePrimaryConstructorSyntax\" xml:space=\"preserve\">\n    <value>Use primary constructor syntax with records</value>\n  </data>\n  <data name=\"DecompilerSettings.UsePrimaryConstructorSyntaxForNonRecordTypes\" xml:space=\"preserve\">\n    <value>Use primary constructor syntax for non-record types</value>\n  </data>\n  <data name=\"DecompilerSettings.UseRefLocalsForAccurateOrderOfEvaluation\" xml:space=\"preserve\">\n    <value>Use ref locals to accurately represent order of evaluation</value>\n  </data>\n  <data name=\"DecompilerSettings.UseSdkStyleProjectFormat\" xml:space=\"preserve\">\n    <value>Use new SDK style format for generated project files (*.csproj)</value>\n  </data>\n  <data name=\"DecompilerSettings.UseStackallocInitializerSyntax\" xml:space=\"preserve\">\n    <value>Use stackalloc initializer syntax</value>\n  </data>\n  <data name=\"DecompilerSettings.UseStringInterpolation\" xml:space=\"preserve\">\n    <value>Use string interpolation</value>\n  </data>\n  <data name=\"DecompilerSettings.UseThrowExpressions\" xml:space=\"preserve\">\n    <value>Use throw expressions</value>\n  </data>\n  <data name=\"DecompilerSettings.UseTupleTypeSyntax\" xml:space=\"preserve\">\n    <value>Use tuple type syntax</value>\n  </data>\n  <data name=\"DecompilerSettings.UseVariableNamesFromDebugSymbolsIfAvailable\" xml:space=\"preserve\">\n    <value>Use variable names from debug symbols, if available</value>\n  </data>\n  <data name=\"DecompilerSettings.Utf8StringLiterals\" xml:space=\"preserve\">\n    <value>UTF-8 string literals</value>\n  </data>\n  <data name=\"DecompilerSettings.VBSpecificOptions\" xml:space=\"preserve\">\n    <value>VB-specific options</value>\n  </data>\n  <data name=\"DecompilerSettings.WithExpressions\" xml:space=\"preserve\">\n    <value>'with' initializer expressions</value>\n  </data>\n  <data name=\"DecompilerSettingsPanelLongText\" xml:space=\"preserve\">\n    <value>The settings selected below are applied to the decompiler output in combination with the selection in the language drop-down. Selecting a lower language version in the drop-down will deactivate all selected options of the higher versions. Note that some settings implicitly depend on each other, e.g.: LINQ expressions cannot be introduced without first transforming static calls to extension method calls.</value>\n  </data>\n  <data name=\"Decompiling\" xml:space=\"preserve\">\n    <value>Decompiling...</value>\n  </data>\n  <data name=\"Dependencies\" xml:space=\"preserve\">\n    <value>Dependencies</value>\n  </data>\n  <data name=\"DerivedTypes\" xml:space=\"preserve\">\n    <value>Derived Types</value>\n  </data>\n  <data name=\"Display\" xml:space=\"preserve\">\n    <value>Display</value>\n  </data>\n  <data name=\"DisplayCode\" xml:space=\"preserve\">\n    <value>Display Code</value>\n  </data>\n  <data name=\"DisplaySettingsPanel_Font\" xml:space=\"preserve\">\n    <value>Font:</value>\n  </data>\n  <data name=\"DisplaySettingsPanel_Theme\" xml:space=\"preserve\">\n    <value>Theme:</value>\n  </data>\n  <data name=\"Download\" xml:space=\"preserve\">\n    <value>Download</value>\n  </data>\n  <data name=\"E_xit\" xml:space=\"preserve\">\n    <value>E_xit</value>\n  </data>\n  <data name=\"Editor\" xml:space=\"preserve\">\n    <value>Editor</value>\n  </data>\n  <data name=\"EnableFoldingBlocksBraces\" xml:space=\"preserve\">\n    <value>Enable folding on all blocks in braces</value>\n  </data>\n  <data name=\"EnableSmoothScrolling\" xml:space=\"preserve\">\n    <value>Enable smooth scrolling</value>\n  </data>\n  <data name=\"EnableWordWrap\" xml:space=\"preserve\">\n    <value>Enable word wrap</value>\n  </data>\n  <data name=\"EnterListName\" xml:space=\"preserve\">\n    <value>Enter a list name:</value>\n  </data>\n  <data name=\"Exit\" xml:space=\"preserve\">\n    <value>Exit</value>\n  </data>\n  <data name=\"ExpandMemberDefinitionsAfterDecompilation\" xml:space=\"preserve\">\n    <value>Expand member definitions after decompilation</value>\n  </data>\n  <data name=\"ExpandUsingDeclarationsAfterDecompilation\" xml:space=\"preserve\">\n    <value>Expand using declarations after decompilation</value>\n  </data>\n  <data name=\"ExtractAllPackageEntries\" xml:space=\"preserve\">\n    <value>Extract all package entries</value>\n  </data>\n  <data name=\"ExtractPackageEntry\" xml:space=\"preserve\">\n    <value>Extract package entry</value>\n  </data>\n  <data name=\"Folding\" xml:space=\"preserve\">\n    <value>Folding</value>\n  </data>\n  <data name=\"Font\" xml:space=\"preserve\">\n    <value>Font</value>\n  </data>\n  <data name=\"Forward\" xml:space=\"preserve\">\n    <value>Forward</value>\n  </data>\n  <data name=\"GeneratePortable\" xml:space=\"preserve\">\n    <value>Generate portable PDB</value>\n  </data>\n  <data name=\"GeneratedPDBFile\" xml:space=\"preserve\">\n    <value>Generated PDB: {0}</value>\n  </data>\n  <data name=\"GeneratingPortablePDB\" xml:space=\"preserve\">\n    <value>Generating portable PDB for {0}...</value>\n  </data>\n  <data name=\"GenerationCompleteInSeconds\" xml:space=\"preserve\">\n    <value>Generation complete in {0} seconds.</value>\n  </data>\n  <data name=\"GenerationFailedForAssembly\" xml:space=\"preserve\">\n    <value>Failed to generate PDB for {0}: {1}</value>\n  </data>\n  <data name=\"GenerationWasCancelled\" xml:space=\"preserve\">\n    <value>Generation was cancelled.</value>\n  </data>\n  <data name=\"GoToToken\" xml:space=\"preserve\">\n    <value>Go to token</value>\n  </data>\n  <data name=\"HideEmptyMetadataTables\" xml:space=\"preserve\">\n    <value>Hide empty metadata tables from tree view</value>\n  </data>\n  <data name=\"HighlightCurrentLine\" xml:space=\"preserve\">\n    <value>Highlight current line</value>\n  </data>\n  <data name=\"HighlightMatchingBraces\" xml:space=\"preserve\">\n    <value>Highlight matching braces</value>\n  </data>\n  <data name=\"ILSpyAboutPageTxt\" xml:space=\"preserve\">\n    <value>ILSpyAboutPage.txt</value>\n  </data>\n  <data name=\"ILSpyVersion\" xml:space=\"preserve\">\n    <value>ILSpy version </value>\n  </data>\n  <data name=\"ILSpyVersionAvailable\" xml:space=\"preserve\">\n    <value>A new ILSpy version is available.</value>\n  </data>\n  <data name=\"IndentSize\" xml:space=\"preserve\">\n    <value>Indent size:</value>\n  </data>\n  <data name=\"Indentation\" xml:space=\"preserve\">\n    <value>Indentation</value>\n  </data>\n  <data name=\"InsertUsingDeclarations\" xml:space=\"preserve\">\n    <value>Insert using declarations</value>\n  </data>\n  <data name=\"ListDeleteConfirmation\" xml:space=\"preserve\">\n    <value>Are you sure that you want to delete the selected assembly list?</value>\n  </data>\n  <data name=\"ListExistsAlready\" xml:space=\"preserve\">\n    <value>A list with the same name was found.</value>\n  </data>\n  <data name=\"ListsResetConfirmation\" xml:space=\"preserve\">\n    <value>Are you sure that you want to remove all assembly lists and recreate the default assembly lists?</value>\n  </data>\n  <data name=\"LoadAssembliesThatWereLoadedInTheLastInstance\" xml:space=\"preserve\">\n    <value>Load assemblies that were loaded in the last instance.</value>\n  </data>\n  <data name=\"Loading\" xml:space=\"preserve\">\n    <value>Loading...</value>\n  </data>\n  <data name=\"Location\" xml:space=\"preserve\">\n    <value>Location</value>\n  </data>\n  <data name=\"ManageAssemblyLists\" xml:space=\"preserve\">\n    <value>Manage Assembly Lists</value>\n  </data>\n  <data name=\"ManageAssembly_Lists\" xml:space=\"preserve\">\n    <value>Manage assembly _lists...</value>\n  </data>\n  <data name=\"Metadata\" xml:space=\"preserve\">\n    <value>Metadata</value>\n  </data>\n  <data name=\"Misc\" xml:space=\"preserve\">\n    <value>Misc</value>\n  </data>\n  <data name=\"NETFrameworkVersion\" xml:space=\"preserve\">\n    <value>.NET version </value>\n  </data>\n  <data name=\"Name\" xml:space=\"preserve\">\n    <value>Name</value>\n  </data>\n  <data name=\"Navigation\" xml:space=\"preserve\">\n    <value>Navigation</value>\n  </data>\n  <data name=\"NavigationFailed\" xml:space=\"preserve\">\n    <value>Navigation failed because the target is hidden or a compiler-generated class.\nPlease disable all filters that might hide the item (i.e. activate \"View &gt; Show internal types and members\") and try again.</value>\n  </data>\n  <data name=\"NewList\" xml:space=\"preserve\">\n    <value>New list</value>\n  </data>\n  <data name=\"NewTab\" xml:space=\"preserve\">\n    <value>New Tab</value>\n  </data>\n  <data name=\"NugetPackageBrowser\" xml:space=\"preserve\">\n    <value>Nuget Package Browser</value>\n  </data>\n  <data name=\"OK\" xml:space=\"preserve\">\n    <value>OK</value>\n  </data>\n  <data name=\"Open\" xml:space=\"preserve\">\n    <value>Open</value>\n  </data>\n  <data name=\"OpenExplorer\" xml:space=\"preserve\">\n    <value>Open Explorer</value>\n  </data>\n  <data name=\"OpenFrom\" xml:space=\"preserve\">\n    <value>Open From GAC</value>\n  </data>\n  <data name=\"OpenFrom_GAC\" xml:space=\"preserve\">\n    <value>Open from _GAC...</value>\n  </data>\n  <data name=\"OpenListDialog__Delete\" xml:space=\"preserve\">\n    <value>_Delete</value>\n  </data>\n  <data name=\"OpenListDialog__Open\" xml:space=\"preserve\">\n    <value>_Open</value>\n  </data>\n  <data name=\"OperationWasCancelled\" xml:space=\"preserve\">\n    <value>Operation was cancelled.</value>\n  </data>\n  <data name=\"Options\" xml:space=\"preserve\">\n    <value>Options</value>\n  </data>\n  <data name=\"Other\" xml:space=\"preserve\">\n    <value>Other</value>\n  </data>\n  <data name=\"OtherOptions\" xml:space=\"preserve\">\n    <value>Other options</value>\n  </data>\n  <data name=\"OtherResources\" xml:space=\"preserve\">\n    <value>Other Resources</value>\n  </data>\n  <data name=\"PortablePDBPdbAllFiles\" xml:space=\"preserve\">\n    <value>Portable PDB|*.pdb|All files|*.*</value>\n  </data>\n  <data name=\"ProjectExportFormatChangeSettingHint\" xml:space=\"preserve\">\n    <value>You can change this by toggling the setting at Options &gt; Decompiler &gt; Project export &gt; Use new SDK style format for generated project files (*.csproj).</value>\n  </data>\n  <data name=\"ProjectExportFormatNonSDKHint\" xml:space=\"preserve\">\n    <value>A Non-SDK project was generated. Learn more at https://docs.microsoft.com/en-us/nuget/resources/check-project-format.</value>\n  </data>\n  <data name=\"ProjectExportFormatSDKHint\" xml:space=\"preserve\">\n    <value>A SDK-style project was generated. Learn more at https://docs.microsoft.com/en-us/nuget/resources/check-project-format.</value>\n  </data>\n  <data name=\"ProjectExportPathTooLong\" xml:space=\"preserve\">\n    <value>Failed to decompile the assemblies {0} because the namespace names are too long or the directory structure is nested too deep.\n\nIf you are using Windows 10.0.14393 (Windows 10 version 1607) or later, you can enable \"Long path support\" by creating a REG_DWORD registry key named \"LongPathsEnabled\" with value 0x1 at \"HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\FileSystem\" (see https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation for more information).\n\nIf this does not solve the problem and your system supports long paths, you can try to use a nested path structure. You can change this by toggling the setting at Options &gt; Decompiler &gt; Project export &gt; Use nested directories for namespaces. This helps because even on \"long-path-aware\" platforms, the length of a directory name is limited, on Windows/NTFS this is 255 characters.</value>\n  </data>\n  <data name=\"PropertyManuallyMissingReferencesListLoadedAssemblies\" xml:space=\"preserve\">\n    <value>for ex. property getter/setter access. To get optimal decompilation results, please manually add the missing references to the list of loaded assemblies.</value>\n  </data>\n  <data name=\"PublicToken\" xml:space=\"preserve\">\n    <value>Public Key Token</value>\n  </data>\n  <data name=\"R_ename\" xml:space=\"preserve\">\n    <value>R_ename</value>\n  </data>\n  <data name=\"ReferenceName\" xml:space=\"preserve\">\n    <value>Reference Name</value>\n  </data>\n  <data name=\"ReferencedTypes\" xml:space=\"preserve\">\n    <value>Referenced Types</value>\n  </data>\n  <data name=\"References\" xml:space=\"preserve\">\n    <value>References</value>\n  </data>\n  <data name=\"RefreshCommand_ReloadAssemblies\" xml:space=\"preserve\">\n    <value>Reload all assemblies</value>\n  </data>\n  <data name=\"ReloadAssemblies\" xml:space=\"preserve\">\n    <value>Reload all assemblies</value>\n  </data>\n  <data name=\"Remove\" xml:space=\"preserve\">\n    <value>Remove</value>\n  </data>\n  <data name=\"RemoveDeadSideEffectFreeCode\" xml:space=\"preserve\">\n    <value>Remove dead and side effect free code</value>\n  </data>\n  <data name=\"RemoveShellIntegration\" xml:space=\"preserve\">\n    <value>Remove shell integration</value>\n  </data>\n  <data name=\"RemoveShellIntegrationMessage\" xml:space=\"preserve\">\n    <value>This will remove \"{0}\" from the registry at \"HKCU\\Software\\Classes\\dllfile\\shell\\Open with ILSpy\\command\" and \"HKCU\\Software\\Classes\\exefile\\shell\\Open with ILSpy\\command\".\n\nDo you want to continue?</value>\n  </data>\n  <data name=\"RenameList\" xml:space=\"preserve\">\n    <value>Rename list</value>\n  </data>\n  <data name=\"ResetToDefaults\" xml:space=\"preserve\">\n    <value>Reset to defaults</value>\n  </data>\n  <data name=\"ResetToDefaultsConfirmationMessage\" xml:space=\"preserve\">\n    <value>Do you really want to load the default settings for the active page?</value>\n  </data>\n  <data name=\"ResourcesFileFilter\" xml:space=\"preserve\">\n    <value>Resources file (*.resources)|*.resources|Resource XML file|*.resx</value>\n  </data>\n  <data name=\"Save\" xml:space=\"preserve\">\n    <value>Save</value>\n  </data>\n  <data name=\"SaveCode\" xml:space=\"preserve\">\n    <value>Save Code</value>\n  </data>\n  <data name=\"ScopeSearchToThisAssembly\" xml:space=\"preserve\">\n    <value>Scope search to this assembly</value>\n  </data>\n  <data name=\"ScopeSearchToThisNamespace\" xml:space=\"preserve\">\n    <value>Scope search to this namespace</value>\n  </data>\n  <data name=\"Search\" xml:space=\"preserve\">\n    <value>Search...</value>\n  </data>\n  <data name=\"SearchAbortedMoreThan1000ResultsFound\" xml:space=\"preserve\">\n    <value>Search aborted, more than 1000 results found.</value>\n  </data>\n  <data name=\"SearchCtrlShiftFOrCtrlE\" xml:space=\"preserve\">\n    <value>Search (Ctrl+Shift+F or Ctrl+E)</value>\n  </data>\n  <data name=\"SearchMSDN\" xml:space=\"preserve\">\n    <value>Search Microsoft Docs...</value>\n  </data>\n  <data name=\"SearchPane_Search\" xml:space=\"preserve\">\n    <value>Search</value>\n  </data>\n  <data name=\"Searching\" xml:space=\"preserve\">\n    <value>Searching...</value>\n  </data>\n  <data name=\"Select\" xml:space=\"preserve\">\n    <value>Select All</value>\n  </data>\n  <data name=\"SelectAssembliesOpen\" xml:space=\"preserve\">\n    <value>Select assemblies to open:</value>\n  </data>\n  <data name=\"SelectAssemblyListDropdownTooltip\" xml:space=\"preserve\">\n    <value>Select a list of assemblies (Alt+A)</value>\n  </data>\n  <data name=\"SelectLanguageDropdownTooltip\" xml:space=\"preserve\">\n    <value>Select language to decompile to (Alt+L)</value>\n  </data>\n  <data name=\"SelectList\" xml:space=\"preserve\">\n    <value>Select a list:</value>\n  </data>\n  <data name=\"SelectPDB\" xml:space=\"preserve\">\n    <value>Select PDB...</value>\n  </data>\n  <data name=\"SelectPDBOutputFolder\" xml:space=\"preserve\">\n    <value>Select target folder</value>\n  </data>\n  <data name=\"SelectVersionDropdownTooltip\" xml:space=\"preserve\">\n    <value>Select version of language to output (Alt+E)</value>\n  </data>\n  <data name=\"SettingsChangeRestartRequired\" xml:space=\"preserve\">\n    <value>You must restart ILSpy for the change to take effect.</value>\n  </data>\n  <data name=\"Shell\" xml:space=\"preserve\">\n    <value>Shell</value>\n  </data>\n  <data name=\"ShowAllTypesAndMembers\" xml:space=\"preserve\">\n    <value>Show all types and members</value>\n  </data>\n  <data name=\"ShowAssemblyLoad\" xml:space=\"preserve\">\n    <value>Show assembly load log</value>\n  </data>\n  <data name=\"ShowChildIndexInBlock\" xml:space=\"preserve\">\n    <value>ShowChildIndexInBlock</value>\n  </data>\n  <data name=\"ShowDocumentationDecompiledCode\" xml:space=\"preserve\">\n    <value>Show XML documentation in decompiled code</value>\n  </data>\n  <data name=\"ShowILRanges\" xml:space=\"preserve\">\n    <value>ShowILRanges</value>\n  </data>\n  <data name=\"ShowInfoFromDebugSymbolsAvailable\" xml:space=\"preserve\">\n    <value>Show info from debug symbols, if available</value>\n  </data>\n  <data name=\"ShowInternalTypesMembers\" xml:space=\"preserve\">\n    <value>Show public, private and internal</value>\n  </data>\n  <data name=\"ShowLineNumbers\" xml:space=\"preserve\">\n    <value>Show line numbers</value>\n  </data>\n  <data name=\"ShowMetadataTokens\" xml:space=\"preserve\">\n    <value>Show metadata tokens</value>\n  </data>\n  <data name=\"ShowMetadataTokensInBase10\" xml:space=\"preserve\">\n    <value>Show metadata tokens in base 10</value>\n  </data>\n  <data name=\"ShowPublicOnlyTypesMembers\" xml:space=\"preserve\">\n    <value>Show only public types and members</value>\n  </data>\n  <data name=\"ShowRawOffsetsAndBytesBeforeInstruction\" xml:space=\"preserve\">\n    <value>Show raw offsets and bytes before each instruction</value>\n  </data>\n  <data name=\"ShowStateAfterThisStep\" xml:space=\"preserve\">\n    <value>Show state after this step</value>\n  </data>\n  <data name=\"ShowStateBeforeThisStep\" xml:space=\"preserve\">\n    <value>Show state before this step</value>\n  </data>\n  <data name=\"Show_allTypesAndMembers\" xml:space=\"preserve\">\n    <value>Show _all types and members</value>\n  </data>\n  <data name=\"Show_internalTypesMembers\" xml:space=\"preserve\">\n    <value>Show public, private and internal</value>\n  </data>\n  <data name=\"Show_publiconlyTypesMembers\" xml:space=\"preserve\">\n    <value>Show only _public types and members</value>\n  </data>\n  <data name=\"Size\" xml:space=\"preserve\">\n    <value>Size:</value>\n  </data>\n  <data name=\"SortAssemblyListName\" xml:space=\"preserve\">\n    <value>Sort assembly list by name</value>\n  </data>\n  <data name=\"SortAssembly_listName\" xml:space=\"preserve\">\n    <value>Sort assembly _list by name</value>\n  </data>\n  <data name=\"SortResultsFitness\" xml:space=\"preserve\">\n    <value>Sort results by fitness</value>\n  </data>\n  <data name=\"StandBy\" xml:space=\"preserve\">\n    <value>Stand by...</value>\n  </data>\n  <data name=\"Status\" xml:space=\"preserve\">\n    <value>Status</value>\n  </data>\n  <data name=\"StringTable\" xml:space=\"preserve\">\n    <value>String Table</value>\n  </data>\n  <data name=\"StyleTheWindowTitleBar\" xml:space=\"preserve\">\n    <value>Style the window title bar</value>\n  </data>\n  <data name=\"TabSize\" xml:space=\"preserve\">\n    <value>Tab size:</value>\n  </data>\n  <data name=\"Theme\" xml:space=\"preserve\">\n    <value>Theme</value>\n  </data>\n  <data name=\"ToggleFolding\" xml:space=\"preserve\">\n    <value>Toggle All Folding</value>\n  </data>\n  <data name=\"TreeViewOptions\" xml:space=\"preserve\">\n    <value>Tree view options</value>\n  </data>\n  <data name=\"Type\" xml:space=\"preserve\">\n    <value>Type</value>\n  </data>\n  <data name=\"UILanguage\" xml:space=\"preserve\">\n    <value>UI Language</value>\n  </data>\n  <data name=\"UILanguage_System\" xml:space=\"preserve\">\n    <value>System</value>\n  </data>\n  <data name=\"UpdateILSpyFound\" xml:space=\"preserve\">\n    <value>No update for ILSpy found.</value>\n  </data>\n  <data name=\"UseFieldSugar\" xml:space=\"preserve\">\n    <value>UseFieldSugar</value>\n  </data>\n  <data name=\"UseLogicOperationSugar\" xml:space=\"preserve\">\n    <value>UseLogicOperationSugar</value>\n  </data>\n  <data name=\"UseNestedNamespaceNodes\" xml:space=\"preserve\">\n    <value>Use nested namespace structure</value>\n  </data>\n  <data name=\"UseTabsInsteadOfSpaces\" xml:space=\"preserve\">\n    <value>Use tabs instead of spaces</value>\n  </data>\n  <data name=\"UsingLatestRelease\" xml:space=\"preserve\">\n    <value>You are using the latest release.</value>\n  </data>\n  <data name=\"UsingNightlyBuildNewerThanLatestRelease\" xml:space=\"preserve\">\n    <value>You are using a nightly build newer than the latest release.</value>\n  </data>\n  <data name=\"Value\" xml:space=\"preserve\">\n    <value>Value</value>\n  </data>\n  <data name=\"ValueString\" xml:space=\"preserve\">\n    <value>Value (as string)</value>\n  </data>\n  <data name=\"VariableNamesFromDebugSymbolsAvailable\" xml:space=\"preserve\">\n    <value>Use variable names from debug symbols, if available</value>\n  </data>\n  <data name=\"Version\" xml:space=\"preserve\">\n    <value>Version</value>\n  </data>\n  <data name=\"VersionAvailable\" xml:space=\"preserve\">\n    <value>Version {0} is available.</value>\n  </data>\n  <data name=\"View\" xml:space=\"preserve\">\n    <value>View</value>\n  </data>\n  <data name=\"VisualStudioSolutionFileSlnAllFiles\" xml:space=\"preserve\">\n    <value>Visual Studio Solution file|*.sln|All files|*.*</value>\n  </data>\n  <data name=\"WarningAsmMarkedRef\" xml:space=\"preserve\">\n    <value>Warning: This assembly is marked as 'reference assembly', which means that it only contains metadata and no executable code.</value>\n  </data>\n  <data name=\"WarningSomeAssemblyReference\" xml:space=\"preserve\">\n    <value>Warning: Some assembly references could not be resolved automatically. This might lead to incorrect decompilation of some parts,</value>\n  </data>\n  <data name=\"WatermarkText\" xml:space=\"preserve\">\n    <value>Search for t:TypeName, m:Member or c:Constant; use exact match (=term), 'should not contain' (-term) or 'must contain' (+term); use /reg(ular)?Ex(pressions)?/ or both - t:/Type(Name)?/...</value>\n  </data>\n  <data name=\"Window_CloseAllDocuments\" xml:space=\"preserve\">\n    <value>_Close all documents</value>\n  </data>\n  <data name=\"Window_ResetLayout\" xml:space=\"preserve\">\n    <value>_Reset layout</value>\n  </data>\n  <data name=\"_About\" xml:space=\"preserve\">\n    <value>_About</value>\n  </data>\n  <data name=\"_AddMainList\" xml:space=\"preserve\">\n    <value>_Add To Main List</value>\n  </data>\n  <data name=\"_Analyzer\" xml:space=\"preserve\">\n    <value>Analy_zer</value>\n  </data>\n  <data name=\"_Assemblies\" xml:space=\"preserve\">\n    <value>_Assemblies</value>\n  </data>\n  <data name=\"_CheckUpdates\" xml:space=\"preserve\">\n    <value>_Check for Updates</value>\n  </data>\n  <data name=\"_CollapseTreeNodes\" xml:space=\"preserve\">\n    <value>_Collapse all tree nodes</value>\n  </data>\n  <data name=\"_CreateDiagram\" xml:space=\"preserve\">\n    <value>Create _Diagram...</value>\n  </data>\n  <data name=\"_File\" xml:space=\"preserve\">\n    <value>_File</value>\n  </data>\n  <data name=\"_Help\" xml:space=\"preserve\">\n    <value>_Help</value>\n  </data>\n  <data name=\"_LoadDependencies\" xml:space=\"preserve\">\n    <value>_Load Dependencies</value>\n  </data>\n  <data name=\"_New\" xml:space=\"preserve\">\n    <value>_New</value>\n  </data>\n  <data name=\"_Open\" xml:space=\"preserve\">\n    <value>_Open...</value>\n  </data>\n  <data name=\"_OpenCommandLineHere\" xml:space=\"preserve\">\n    <value>_Open Command Line Here</value>\n  </data>\n  <data name=\"_OpenContainingFolder\" xml:space=\"preserve\">\n    <value>_Open Containing Folder</value>\n  </data>\n  <data name=\"_Options\" xml:space=\"preserve\">\n    <value>_Options...</value>\n  </data>\n  <data name=\"_Reload\" xml:space=\"preserve\">\n    <value>_Reload</value>\n  </data>\n  <data name=\"_Remove\" xml:space=\"preserve\">\n    <value>_Remove</value>\n  </data>\n  <data name=\"_RemoveAssembliesWithLoadErrors\" xml:space=\"preserve\">\n    <value>_Remove Assemblies with load errors</value>\n  </data>\n  <data name=\"_Reset\" xml:space=\"preserve\">\n    <value>_Reset</value>\n  </data>\n  <data name=\"_Resources\" xml:space=\"preserve\">\n    <value>Resources</value>\n  </data>\n  <data name=\"_SaveCode\" xml:space=\"preserve\">\n    <value>_Save Code...</value>\n  </data>\n  <data name=\"_Search\" xml:space=\"preserve\">\n    <value>_Search:</value>\n  </data>\n  <data name=\"_SearchFor\" xml:space=\"preserve\">\n    <value>_Search for:</value>\n  </data>\n  <data name=\"_ShowDebugSteps\" xml:space=\"preserve\">\n    <value>_Show debug steps</value>\n  </data>\n  <data name=\"_ToggleFolding\" xml:space=\"preserve\">\n    <value>Toggle Folding</value>\n  </data>\n  <data name=\"_View\" xml:space=\"preserve\">\n    <value>_View</value>\n  </data>\n  <data name=\"_Window\" xml:space=\"preserve\">\n    <value>_Window</value>\n  </data>\n</root>"
  },
  {
    "path": "ILSpy/Properties/WPFAssemblyInfo.cs",
    "content": "#region Using directives\n\nusing System.Windows;\n\n#endregion\n\n//In order to begin building localizable applications, set\n//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file\n//inside a <PropertyGroup>.  For example, if you are using US english\n//in your source files, set the <UICulture> to en-US.  Then uncomment\n//the NeutralResourceLanguage attribute below.  Update the \"en-US\" in\n//the line below to match the UICulture setting in the project file.\n\n//[assembly: NeutralResourcesLanguage(\"en-US\", UltimateResourceFallbackLocation.Satellite)]\n\n[assembly: ThemeInfo(\n\tResourceDictionaryLocation.None, //where theme specific resource dictionaries are located\n\t\t\t\t\t\t\t\t\t //(used if a resource is not found in the page,\n\t\t\t\t\t\t\t\t\t // or application resource dictionaries)\n\tResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located\n\t\t\t\t\t\t\t\t\t\t\t  //(used if a resource is not found in the page,\n\t\t\t\t\t\t\t\t\t\t\t  // app, or any theme specific resource dictionaries)\n)]\n"
  },
  {
    "path": "ILSpy/Properties/launchSettings.json",
    "content": "{\n\t\"profiles\": {\n\t\t\"ILSpy\": {\n\t\t\t\"commandName\": \"Executable\",\n\t\t\t\"executablePath\": \"./ilspy.exe\",\n\t\t\t\"commandLineArgs\": \"--newinstance\"\n\t\t},\n\t\t\"ILSpy single-instance\": {\n\t\t\t\"commandName\": \"Executable\",\n\t\t\t\"executablePath\": \"./ilspy.exe\"\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Search/SearchPane.xaml",
    "content": "<UserControl x:Class=\"ICSharpCode.ILSpy.Search.SearchPane\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n\t\txmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n\t\txmlns:controls=\"clr-namespace:ICSharpCode.ILSpy.Controls\"\n\t\txmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n\t    xmlns:properties=\"clr-namespace:ICSharpCode.ILSpy.Properties\"\n\t\txmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" x:Name=\"self\" mc:Ignorable=\"d\"\n\t\txmlns:toms=\"urn:TomsToolbox\"\n\t\txmlns:search=\"clr-namespace:ICSharpCode.ILSpy.Search\"\n\t\txmlns:spyX=\"clr-namespace:ICSharpCode.ILSpyX.Search;assembly=ICSharpCode.ILSpyX\"\n\t\txmlns:viewModels=\"clr-namespace:ICSharpCode.ILSpy.ViewModels\"\n\t\td:DesignHeight=\"300\" d:DesignWidth=\"300\" d:DataContext=\"{d:DesignInstance search:SearchPaneModel}\"\n\t\tviewModels:Pane.IsActive=\"{Binding IsActive}\">\n\t<Grid>\n\t\t<Grid.RowDefinitions>\n\t\t\t<RowDefinition Height=\"Auto\"/>\n\t\t\t<RowDefinition Height=\"3\" />\n\t\t\t<RowDefinition />\n\t\t</Grid.RowDefinitions>\n\t\t<Border BorderBrush=\"{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}\" Background=\"{DynamicResource {x:Static SystemColors.ControlBrushKey}}\" Margin=\"0\">\n\t\t\t<Grid>\n\t\t\t\t<Grid.ColumnDefinitions>\n\t\t\t\t\t<ColumnDefinition Width=\"*\" />\n\t\t\t\t\t<ColumnDefinition Width=\"Auto\" />\n\t\t\t\t</Grid.ColumnDefinitions>\n\t\t\t\t<controls:SearchBox x:Name=\"searchBox\" DockPanel.Dock=\"Top\" Grid.Column=\"0\" Grid.Row=\"0\" Margin=\"1\"\n\t\t\t\t\t\tPreviewKeyDown=\"SearchBox_PreviewKeyDown\"\n\t\t\t\t\t\tText=\"{Binding SearchTerm, UpdateSourceTrigger=PropertyChanged}\" ToolTip=\"{x:Static properties:Resources.SearchPane_Search}\" UpdateDelay=\"0:0:0.1\"\n\t\t\t\t\t\tTextChanged=\"SearchBox_TextChanged\"\n\t\t\t\t\t\tWatermarkColor=\"Gray\" WatermarkText=\"{x:Static properties:Resources.WatermarkText}\" />\n\t\t\t\t<StackPanel Grid.Column=\"1\" Grid.Row=\"0\" Orientation=\"Horizontal\">\n\t\t\t\t\t<Label Margin=\"0,-1\" Target=\"searchModeComboBox\" Content=\"{x:Static properties:Resources._SearchFor}\"/>\n\t\t\t\t\t<ComboBox Width=\"100\" Name=\"searchModeComboBox\" Margin=\"1\"\n\t\t\t\t\t\t\tTextSearch.TextPath=\"Name\"\n\t\t\t\t\t\t\tItemsSource=\"{Binding SearchModes}\"\n\t\t\t\t\t\t\tSelectedValuePath=\"Mode\"\n\t\t\t\t\t\t\tSelectedValue=\"{Binding SessionSettings.SelectedSearchMode, Mode=TwoWay}\"\n\t\t\t\t\t\t\tSelectionChanged=\"SearchModeComboBox_SelectionChanged\">\n\t\t\t\t\t\t<ComboBox.ItemTemplate>\n\t\t\t\t\t\t\t<DataTemplate DataType=\"{x:Type search:SearchModeModel}\">\n\t\t\t\t\t\t\t\t<StackPanel Orientation=\"Horizontal\">\n\t\t\t\t\t\t\t\t\t<Image Height=\"16\" Margin=\"0,0,4,0\" Width=\"16\" Source=\"{Binding Image}\" />\n\t\t\t\t\t\t\t\t\t<TextBlock Text=\"{Binding Name}\" />\n\t\t\t\t\t\t\t\t</StackPanel>\n\t\t\t\t\t\t\t</DataTemplate>\n\t\t\t\t\t\t</ComboBox.ItemTemplate>\n\t\t\t\t\t</ComboBox>\n\t\t\t\t</StackPanel>\n\t\t\t</Grid>\n\t\t</Border>\n\t\t<ProgressBar x:Name=\"searchProgressBar\" Grid.Row=\"1\" BorderThickness=\"0\" Background=\"{DynamicResource {x:Static SystemColors.ControlBrushKey}}\"/>\n\t\t<ListView Grid.Row=\"2\" BorderThickness=\"0,1,0,0\" HorizontalContentAlignment=\"Stretch\" KeyDown=\"ListBox_KeyDown\" MouseDown=\"ListBox_MouseDown\" MouseUp=\"ListBox_MouseUp\"\n\t\t\t\tMouseDoubleClick=\"ListBox_MouseDoubleClick\" Name=\"listBox\" SelectionMode=\"Single\" controls:SortableGridViewColumn.SortMode=\"Automatic\"\n\t\t\t\tcontrols:GridViewColumnAutoSize.AutoWidth=\"40%;40%;20%\" BorderBrush=\"{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}\"\n\t\t\t\tItemsSource=\"{Binding Results, ElementName=self}\"\n\t\t\t\ttoms:AdvancedScrollWheelBehavior.Attach=\"WithoutAnimation\">\n\t\t\t<ListView.View>\n\t\t\t\t<GridView AllowsColumnReorder=\"False\">\n\t\t\t\t\t<controls:SortableGridViewColumn Header=\"{x:Static properties:Resources.Name}\" SortBy=\"Name\">\n\t\t\t\t\t\t<controls:SortableGridViewColumn.CellTemplate>\n\t\t\t\t\t\t\t<DataTemplate DataType=\"{x:Type spyX:SearchResult}\">\n\t\t\t\t\t\t\t\t<DockPanel>\n\t\t\t\t\t\t\t\t\t<Image Height=\"16\" Margin=\"0,0,4,0\" Width=\"16\" Source=\"{Binding Image}\" />\n\t\t\t\t\t\t\t\t\t<TextBlock Text=\"{Binding Name}\" ToolTip=\"{Binding ToolTip}\" TextTrimming=\"CharacterEllipsis\" />\n\t\t\t\t\t\t\t\t</DockPanel>\n\t\t\t\t\t\t\t</DataTemplate>\n\t\t\t\t\t\t</controls:SortableGridViewColumn.CellTemplate>\n\t\t\t\t\t</controls:SortableGridViewColumn>\n\t\t\t\t\t<controls:SortableGridViewColumn Header=\"{x:Static properties:Resources.Location}\" SortBy=\"Location\">\n\t\t\t\t\t\t<controls:SortableGridViewColumn.CellTemplate>\n\t\t\t\t\t\t\t<DataTemplate DataType=\"{x:Type spyX:SearchResult}\">\n\t\t\t\t\t\t\t\t<DockPanel>\n\t\t\t\t\t\t\t\t\t<Image Height=\"16\" Margin=\"4,0,4,0\" Width=\"16\" Source=\"{Binding LocationImage}\" />\n\t\t\t\t\t\t\t\t\t<TextBlock Text=\"{Binding Location}\" ToolTip=\"{Binding Location}\" TextTrimming=\"CharacterEllipsis\" />\n\t\t\t\t\t\t\t\t</DockPanel>\n\t\t\t\t\t\t\t</DataTemplate>\n\t\t\t\t\t\t</controls:SortableGridViewColumn.CellTemplate>\n\t\t\t\t\t</controls:SortableGridViewColumn>\n\t\t\t\t\t<controls:SortableGridViewColumn Header=\"{x:Static properties:Resources.Assembly}\" SortBy=\"Assembly\">\n\t\t\t\t\t\t<controls:SortableGridViewColumn.CellTemplate>\n\t\t\t\t\t\t\t<DataTemplate DataType=\"{x:Type spyX:SearchResult}\">\n\t\t\t\t\t\t\t\t<DockPanel>\n\t\t\t\t\t\t\t\t\t<Image Height=\"16\" Margin=\"4,0,4,0\" Width=\"16\" Source=\"{Binding AssemblyImage}\" />\n\t\t\t\t\t\t\t\t\t<TextBlock Text=\"{Binding Assembly}\" ToolTip=\"{Binding Assembly}\" TextTrimming=\"CharacterEllipsis\" />\n\t\t\t\t\t\t\t\t</DockPanel>\n\t\t\t\t\t\t\t</DataTemplate>\n\t\t\t\t\t\t</controls:SortableGridViewColumn.CellTemplate>\n\t\t\t\t\t</controls:SortableGridViewColumn>\n\t\t\t\t</GridView>\n\t\t\t</ListView.View>\n\t\t</ListView>\n\t</Grid>\n</UserControl>"
  },
  {
    "path": "ILSpy/Search/SearchPane.xaml.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.ComponentModel;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.Text.RegularExpressions;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Input;\nusing System.Windows.Media;\nusing System.Windows.Threading;\n\nusing ICSharpCode.ILSpy.AppEnv;\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.Abstractions;\nusing ICSharpCode.ILSpyX.Extensions;\nusing ICSharpCode.ILSpyX.Search;\n\nusing TomsToolbox.Essentials;\nusing TomsToolbox.Wpf;\nusing TomsToolbox.Wpf.Composition.AttributedModel;\n\nnamespace ICSharpCode.ILSpy.Search\n{\n\t/// <summary>\n\t/// Search pane\n\t/// </summary>\n\t[DataTemplate(typeof(SearchPaneModel))]\n\t[NonShared]\n\tpublic partial class SearchPane\n\t{\n\t\tconst int MAX_RESULTS = 1000;\n\t\tconst int MAX_REFRESH_TIME_MS = 10; // More means quicker forward of data, fewer means better responsibility\n\t\tRunningSearch currentSearch;\n\t\tbool runSearchOnNextShow;\n\t\tIComparer<SearchResult> resultsComparer;\n\t\treadonly AssemblyTreeModel assemblyTreeModel;\n\t\treadonly ITreeNodeFactory treeNodeFactory;\n\t\treadonly SettingsService settingsService;\n\n\t\tpublic ObservableCollection<SearchResult> Results { get; } = [];\n\n\t\tstring SearchTerm => searchBox.Text;\n\n\t\tpublic SearchPane(AssemblyTreeModel assemblyTreeModel, ITreeNodeFactory treeNodeFactory, SettingsService settingsService)\n\t\t{\n\t\t\tthis.assemblyTreeModel = assemblyTreeModel;\n\t\t\tthis.treeNodeFactory = treeNodeFactory;\n\t\t\tthis.settingsService = settingsService;\n\n\t\t\tInitializeComponent();\n\n\t\t\tContextMenuProvider.Add(listBox);\n\t\t\tMessageBus<CurrentAssemblyListChangedEventArgs>.Subscribers += (sender, e) => CurrentAssemblyList_Changed();\n\t\t\tMessageBus<SettingsChangedEventArgs>.Subscribers += (sender, e) => Settings_PropertyChanged(sender, e);\n\n\t\t\tCompositionTarget.Rendering += UpdateResults;\n\t\t}\n\n\t\tvoid CurrentAssemblyList_Changed()\n\t\t{\n\t\t\tif (IsVisible)\n\t\t\t{\n\t\t\t\tStartSearch(this.SearchTerm);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tStartSearch(null);\n\t\t\t\trunSearchOnNextShow = true;\n\t\t\t}\n\t\t}\n\n\t\tvoid Settings_PropertyChanged(object sender, PropertyChangedEventArgs e)\n\t\t{\n\t\t\tif (sender is not LanguageSettings)\n\t\t\t\treturn;\n\n\t\t\tUpdateFilter();\n\t\t}\n\n\t\tvoid UpdateFilter()\n\t\t{\n\t\t\tif (IsVisible)\n\t\t\t{\n\t\t\t\tStartSearch(this.SearchTerm);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tStartSearch(null);\n\t\t\t\trunSearchOnNextShow = true;\n\t\t\t}\n\t\t}\n\n\t\tprotected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)\n\t\t{\n\t\t\tbase.OnPropertyChanged(e);\n\n\t\t\tif (e.Property == IsVisibleProperty)\n\t\t\t{\n\t\t\t\tif (e.NewValue as bool? != true)\n\t\t\t\t\treturn;\n\n\t\t\t\tif (!runSearchOnNextShow)\n\t\t\t\t\treturn;\n\n\t\t\t\trunSearchOnNextShow = false;\n\t\t\t\tStartSearch(this.SearchTerm);\n\t\t\t}\n\t\t\telse if (e.Property == Pane.IsActiveProperty)\n\t\t\t{\n\t\t\t\tif (e.NewValue as bool? != true)\n\t\t\t\t\treturn;\n\n\t\t\t\tif (IsMouseOver && Mouse.LeftButton == MouseButtonState.Pressed && !SearchTerm.IsNullOrEmpty())\n\t\t\t\t\treturn;\n\n\t\t\t\tFocusSearchBox();\n\t\t\t}\n\t\t}\n\n\t\tvoid FocusSearchBox()\n\t\t{\n\t\t\tthis.BeginInvoke(DispatcherPriority.Background, () => {\n\t\t\t\tsearchBox.Focus();\n\t\t\t\tsearchBox.SelectAll();\n\t\t\t});\n\t\t}\n\n\t\tvoid SearchBox_TextChanged(object sender, TextChangedEventArgs e)\n\t\t{\n\t\t\tStartSearch(searchBox.Text);\n\t\t}\n\n\t\tvoid SearchModeComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)\n\t\t{\n\t\t\tStartSearch(this.SearchTerm);\n\t\t}\n\n\t\tvoid ListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)\n\t\t{\n\t\t\tJumpToSelectedItem();\n\t\t\te.Handled = true;\n\t\t}\n\n\t\tprivate void ListBox_MouseDown(object sender, MouseButtonEventArgs e)\n\t\t{\n\t\t\tvar item = listBox.InputHitTest(e.GetPosition(listBox)) as DependencyObject;\n\t\t\twhile (item != null && item != listBox)\n\t\t\t{\n\t\t\t\tif (item is ListBoxItem)\n\t\t\t\t{\n\t\t\t\t\tlistBox.SelectedItem = ((ListBoxItem)item).DataContext;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\titem = VisualTreeHelper.GetParent(item);\n\t\t\t}\n\t\t}\n\n\t\tprivate void ListBox_MouseUp(object sender, MouseButtonEventArgs e)\n\t\t{\n\t\t\tif (e.ChangedButton == MouseButton.Middle)\n\t\t\t{\n\t\t\t\tJumpToSelectedItem(inNewTabPage: true);\n\t\t\t\te.Handled = true;\n\t\t\t}\n\t\t}\n\n\t\tvoid ListBox_KeyDown(object sender, KeyEventArgs e)\n\t\t{\n\t\t\tif (e.Key == Key.Return)\n\t\t\t{\n\t\t\t\te.Handled = true;\n\t\t\t\tJumpToSelectedItem(e.KeyboardDevice.Modifiers.HasFlag(ModifierKeys.Control));\n\t\t\t}\n\t\t\telse if (e.Key == Key.Up && listBox.SelectedIndex == 0)\n\t\t\t{\n\t\t\t\te.Handled = true;\n\t\t\t\tlistBox.SelectedIndex = -1;\n\t\t\t\tsearchBox.Focus();\n\t\t\t}\n\t\t}\n\n\t\tprotected override void OnKeyDown(KeyEventArgs e)\n\t\t{\n\t\t\tbase.OnKeyDown(e);\n\n\t\t\tif (e.KeyboardDevice.Modifiers != ModifierKeys.Control)\n\t\t\t\treturn;\n\n\t\t\tswitch (e.Key)\n\t\t\t{\n\t\t\t\tcase Key.T:\n\t\t\t\t\tsearchModeComboBox.SelectedValue = SearchMode.Type;\n\t\t\t\t\te.Handled = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase Key.M:\n\t\t\t\t\tsearchModeComboBox.SelectedValue = SearchMode.Member;\n\t\t\t\t\te.Handled = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase Key.S:\n\t\t\t\t\tsearchModeComboBox.SelectedValue = SearchMode.Literal;\n\t\t\t\t\te.Handled = true;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tvoid SearchBox_PreviewKeyDown(object sender, KeyEventArgs e)\n\t\t{\n\t\t\tif (e.Key != Key.Down || !listBox.HasItems)\n\t\t\t\treturn;\n\n\t\t\te.Handled = true;\n\t\t\tlistBox.MoveFocus(new(FocusNavigationDirection.First));\n\t\t\tlistBox.SelectedIndex = 0;\n\t\t}\n\n\t\tvoid UpdateResults(object sender, EventArgs e)\n\t\t{\n\t\t\tif (currentSearch == null)\n\t\t\t\treturn;\n\n\t\t\tvar timer = Stopwatch.StartNew();\n\t\t\tint resultsAdded = 0;\n\t\t\twhile (Results.Count < MAX_RESULTS && timer.ElapsedMilliseconds < MAX_REFRESH_TIME_MS && currentSearch.ResultQueue.TryTake(out var result))\n\t\t\t{\n\t\t\t\tResults.InsertSorted(result, resultsComparer);\n\t\t\t\t++resultsAdded;\n\t\t\t}\n\n\t\t\tif (resultsAdded <= 0 || Results.Count != MAX_RESULTS)\n\t\t\t\treturn;\n\n\t\t\tResults.Add(new() {\n\t\t\t\tName = Properties.Resources.SearchAbortedMoreThan1000ResultsFound,\n\t\t\t\tLocation = null!,\n\t\t\t\tAssembly = null!,\n\t\t\t\tImage = null!,\n\t\t\t\tLocationImage = null!,\n\t\t\t\tAssemblyImage = null!,\n\t\t\t});\n\n\t\t\tcurrentSearch.Cancel();\n\t\t}\n\n\t\tasync void StartSearch(string searchTerm)\n\t\t{\n\t\t\tif (currentSearch != null)\n\t\t\t{\n\t\t\t\tcurrentSearch.Cancel();\n\t\t\t\tcurrentSearch = null;\n\t\t\t}\n\n\t\t\tresultsComparer = settingsService.DisplaySettings.SortResults ?\n\t\t\t\tSearchResult.ComparerByFitness :\n\t\t\t\tSearchResult.ComparerByName;\n\t\t\tResults.Clear();\n\n\t\t\tRunningSearch startedSearch = null;\n\t\t\tif (!string.IsNullOrEmpty(searchTerm))\n\t\t\t{\n\n\t\t\t\tsearchProgressBar.IsIndeterminate = true;\n\t\t\t\tstartedSearch = new(await assemblyTreeModel.AssemblyList.GetAllAssemblies(),\n\t\t\t\t\tsearchTerm,\n\t\t\t\t\t(SearchMode)searchModeComboBox.SelectedIndex,\n\t\t\t\t\tassemblyTreeModel.CurrentLanguage,\n\t\t\t\t\tassemblyTreeModel.CurrentLanguageVersion,\n\t\t\t\t\ttreeNodeFactory,\n\t\t\t\t\tsettingsService);\n\t\t\t\tcurrentSearch = startedSearch;\n\n\t\t\t\tawait startedSearch.Run();\n\t\t\t}\n\n\t\t\tif (currentSearch == startedSearch)\n\t\t\t{\n\t\t\t\t//are we still running the same search\n\t\t\t\tsearchProgressBar.IsIndeterminate = false;\n\t\t\t}\n\t\t}\n\n\t\tvoid JumpToSelectedItem(bool inNewTabPage = false)\n\t\t{\n\t\t\tif (listBox.SelectedItem is SearchResult result)\n\t\t\t{\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(result.Reference, inNewTabPage));\n\t\t\t}\n\t\t}\n\n\t\tsealed class RunningSearch\n\t\t{\n\t\t\treadonly CancellationTokenSource cts = new();\n\t\t\treadonly IList<LoadedAssembly> assemblies;\n\t\t\treadonly SearchRequest searchRequest;\n\t\t\treadonly SearchMode searchMode;\n\t\t\treadonly Language language;\n\t\t\treadonly LanguageVersion languageVersion;\n\t\t\treadonly ApiVisibility apiVisibility;\n\t\t\treadonly ITreeNodeFactory treeNodeFactory;\n\t\t\treadonly SettingsService settingsService;\n\n\t\t\tpublic IProducerConsumerCollection<SearchResult> ResultQueue { get; } = new ConcurrentQueue<SearchResult>();\n\n\t\t\tpublic RunningSearch(IList<LoadedAssembly> assemblies, string searchTerm, SearchMode searchMode,\n\t\t\t\tLanguage language, LanguageVersion languageVersion, ITreeNodeFactory treeNodeFactory, SettingsService settingsService)\n\t\t\t{\n\t\t\t\tthis.assemblies = assemblies;\n\t\t\t\tthis.language = language;\n\t\t\t\tthis.languageVersion = languageVersion;\n\t\t\t\tthis.searchMode = searchMode;\n\t\t\t\tthis.apiVisibility = settingsService.SessionSettings.LanguageSettings.ShowApiLevel;\n\t\t\t\tthis.treeNodeFactory = treeNodeFactory;\n\t\t\t\tthis.settingsService = settingsService;\n\t\t\t\tthis.searchRequest = Parse(searchTerm);\n\t\t\t}\n\n\t\t\tSearchRequest Parse(string input)\n\t\t\t{\n\t\t\t\tstring[] parts = CommandLineTools.CommandLineToArgumentArray(input);\n\n\t\t\t\tSearchRequest request = new();\n\t\t\t\tList<string> keywords = new();\n\t\t\t\tRegex regex = null;\n\t\t\t\trequest.Mode = searchMode;\n\n\t\t\t\tforeach (string part in parts)\n\t\t\t\t{\n\t\t\t\t\t// Parse: [prefix:|@][\"]searchTerm[\"]\n\t\t\t\t\t// Find quotes used for escaping\n\t\t\t\t\tint prefixLength = part.IndexOfAny(new[] { '\"', '/' });\n\t\t\t\t\tif (prefixLength < 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t// no quotes\n\t\t\t\t\t\tprefixLength = part.Length;\n\t\t\t\t\t}\n\n\t\t\t\t\tint delimiterLength;\n\t\t\t\t\t// Find end of prefix\n\t\t\t\t\tif (part.StartsWith(\"@\", StringComparison.Ordinal))\n\t\t\t\t\t{\n\t\t\t\t\t\tprefixLength = 1;\n\t\t\t\t\t\tdelimiterLength = 0;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tprefixLength = part.IndexOf(':', 0, prefixLength);\n\t\t\t\t\t\tdelimiterLength = 1;\n\t\t\t\t\t}\n\t\t\t\t\tstring prefix;\n\t\t\t\t\tif (prefixLength <= 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tprefix = null;\n\t\t\t\t\t\tprefixLength = -1;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tprefix = part.Substring(0, prefixLength);\n\t\t\t\t\t}\n\n\t\t\t\t\t// unescape quotes\n\t\t\t\t\tstring searchTerm = part.Substring(prefixLength + delimiterLength).Trim();\n\t\t\t\t\tif (searchTerm.Length > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tsearchTerm = CommandLineTools.CommandLineToArgumentArray(searchTerm)[0];\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// if searchTerm is only \"@\" or \"prefix:\",\n\t\t\t\t\t\t// then we do not interpret it as prefix, but as searchTerm.\n\t\t\t\t\t\tsearchTerm = part;\n\t\t\t\t\t\tprefix = null;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (prefix == null || prefix.Length <= 2)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (regex == null && searchTerm.StartsWith(\"/\", StringComparison.Ordinal) && searchTerm.Length > 1)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tint searchTermLength = searchTerm.Length - 1;\n\t\t\t\t\t\t\tif (searchTerm.EndsWith(\"/\", StringComparison.Ordinal))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tsearchTermLength--;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\trequest.FullNameSearch |= searchTerm.Contains(\"\\\\.\");\n\n\t\t\t\t\t\t\tregex = CreateRegex(searchTerm.Substring(1, searchTermLength));\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\trequest.FullNameSearch |= searchTerm.Contains(\".\");\n\t\t\t\t\t\t\tkeywords.Add(searchTerm);\n\t\t\t\t\t\t}\n\t\t\t\t\t\trequest.OmitGenerics |= !(searchTerm.Contains(\"<\") || searchTerm.Contains(\"`\"));\n\t\t\t\t\t}\n\n\t\t\t\t\tswitch (prefix?.ToUpperInvariant())\n\t\t\t\t\t{\n\t\t\t\t\t\tcase \"@\":\n\t\t\t\t\t\t\trequest.Mode = SearchMode.Token;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"INNAMESPACE\":\n\t\t\t\t\t\t\trequest.InNamespace ??= searchTerm;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"INASSEMBLY\":\n\t\t\t\t\t\t\trequest.InAssembly ??= searchTerm;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"A\":\n\t\t\t\t\t\t\trequest.AssemblySearchKind = AssemblySearchKind.NameOrFileName;\n\t\t\t\t\t\t\trequest.Mode = SearchMode.Assembly;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"AF\":\n\t\t\t\t\t\t\trequest.AssemblySearchKind = AssemblySearchKind.FilePath;\n\t\t\t\t\t\t\trequest.Mode = SearchMode.Assembly;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"AN\":\n\t\t\t\t\t\t\trequest.AssemblySearchKind = AssemblySearchKind.FullName;\n\t\t\t\t\t\t\trequest.Mode = SearchMode.Assembly;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"N\":\n\t\t\t\t\t\t\trequest.Mode = SearchMode.Namespace;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"TM\":\n\t\t\t\t\t\t\trequest.Mode = SearchMode.Member;\n\t\t\t\t\t\t\trequest.MemberSearchKind = MemberSearchKind.All;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"T\":\n\t\t\t\t\t\t\trequest.Mode = SearchMode.Member;\n\t\t\t\t\t\t\trequest.MemberSearchKind = MemberSearchKind.Type;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"M\":\n\t\t\t\t\t\t\trequest.Mode = SearchMode.Member;\n\t\t\t\t\t\t\trequest.MemberSearchKind = MemberSearchKind.Member;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"MD\":\n\t\t\t\t\t\t\trequest.Mode = SearchMode.Member;\n\t\t\t\t\t\t\trequest.MemberSearchKind = MemberSearchKind.Method;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"F\":\n\t\t\t\t\t\t\trequest.Mode = SearchMode.Member;\n\t\t\t\t\t\t\trequest.MemberSearchKind = MemberSearchKind.Field;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"P\":\n\t\t\t\t\t\t\trequest.Mode = SearchMode.Member;\n\t\t\t\t\t\t\trequest.MemberSearchKind = MemberSearchKind.Property;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"E\":\n\t\t\t\t\t\t\trequest.Mode = SearchMode.Member;\n\t\t\t\t\t\t\trequest.MemberSearchKind = MemberSearchKind.Event;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"C\":\n\t\t\t\t\t\t\trequest.Mode = SearchMode.Literal;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"R\":\n\t\t\t\t\t\t\trequest.Mode = SearchMode.Resource;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tRegex CreateRegex(string s)\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\treturn new(s, RegexOptions.Compiled);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (ArgumentException)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\trequest.Keywords = keywords.ToArray();\n\t\t\t\trequest.RegEx = regex;\n\t\t\t\trequest.SearchResultFactory = new SearchResultFactory(language);\n\t\t\t\trequest.TreeNodeFactory = this.treeNodeFactory;\n\t\t\t\tvar decompilerSettings = settingsService.DecompilerSettings.Clone();\n\t\t\t\tif (!Enum.TryParse(this.languageVersion?.Version, out Decompiler.CSharp.LanguageVersion languageVersion))\n\t\t\t\t\tlanguageVersion = Decompiler.CSharp.LanguageVersion.Latest;\n\t\t\t\tdecompilerSettings.SetLanguageVersion(languageVersion);\n\t\t\t\trequest.DecompilerSettings = decompilerSettings;\n\n\t\t\t\treturn request;\n\t\t\t}\n\n\t\t\tpublic void Cancel()\n\t\t\t{\n\t\t\t\tcts.Cancel();\n\t\t\t}\n\n\t\t\tpublic async Task Run()\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tawait Task.Factory.StartNew(() => {\n\t\t\t\t\t\tvar searcher = GetSearchStrategy(searchRequest);\n\t\t\t\t\t\tif (searcher == null)\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tforeach (var loadedAssembly in assemblies)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvar module = loadedAssembly.GetMetadataFileOrNull();\n\t\t\t\t\t\t\t\tif (module == null)\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\tsearcher.Search(module, cts.Token);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (OperationCanceledException)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// ignore cancellation\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}, cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Current).ConfigureAwait(false);\n\t\t\t\t}\n\t\t\t\tcatch (TaskCanceledException)\n\t\t\t\t{\n\t\t\t\t\t// ignore cancellation\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tAbstractSearchStrategy GetSearchStrategy(SearchRequest request)\n\t\t\t{\n\t\t\t\tif (request.Keywords.Length == 0 && request.RegEx == null)\n\t\t\t\t\treturn null;\n\n\t\t\t\tswitch (request.Mode)\n\t\t\t\t{\n\t\t\t\t\tcase SearchMode.TypeAndMember:\n\t\t\t\t\t\treturn new MemberSearchStrategy(language, apiVisibility, request, ResultQueue);\n\t\t\t\t\tcase SearchMode.Type:\n\t\t\t\t\t\treturn new MemberSearchStrategy(language, apiVisibility, request, ResultQueue, MemberSearchKind.Type);\n\t\t\t\t\tcase SearchMode.Member:\n\t\t\t\t\t\treturn new MemberSearchStrategy(language, apiVisibility, request, ResultQueue, request.MemberSearchKind);\n\t\t\t\t\tcase SearchMode.Literal:\n\t\t\t\t\t\treturn new LiteralSearchStrategy(language, apiVisibility, request, ResultQueue);\n\t\t\t\t\tcase SearchMode.Method:\n\t\t\t\t\t\treturn new MemberSearchStrategy(language, apiVisibility, request, ResultQueue, MemberSearchKind.Method);\n\t\t\t\t\tcase SearchMode.Field:\n\t\t\t\t\t\treturn new MemberSearchStrategy(language, apiVisibility, request, ResultQueue, MemberSearchKind.Field);\n\t\t\t\t\tcase SearchMode.Property:\n\t\t\t\t\t\treturn new MemberSearchStrategy(language, apiVisibility, request, ResultQueue, MemberSearchKind.Property);\n\t\t\t\t\tcase SearchMode.Event:\n\t\t\t\t\t\treturn new MemberSearchStrategy(language, apiVisibility, request, ResultQueue, MemberSearchKind.Event);\n\t\t\t\t\tcase SearchMode.Token:\n\t\t\t\t\t\treturn new MetadataTokenSearchStrategy(language, apiVisibility, request, ResultQueue);\n\t\t\t\t\tcase SearchMode.Resource:\n\t\t\t\t\t\treturn new ResourceSearchStrategy(apiVisibility, request, ResultQueue);\n\t\t\t\t\tcase SearchMode.Assembly:\n\t\t\t\t\t\treturn new AssemblySearchStrategy(request, ResultQueue, AssemblySearchKind.NameOrFileName);\n\t\t\t\t\tcase SearchMode.Namespace:\n\t\t\t\t\t\treturn new NamespaceSearchStrategy(request, ResultQueue);\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n\n\t[ExportToolbarCommand(ToolTip = nameof(Properties.Resources.SearchCtrlShiftFOrCtrlE), ToolbarIcon = \"Images/Search\", ToolbarCategory = nameof(Properties.Resources.View), ToolbarOrder = 100)]\n\t[Shared]\n\tsealed class ShowSearchCommand : CommandWrapper\n\t{\n\t\tprivate readonly DockWorkspace dockWorkspace;\n\n\t\tpublic ShowSearchCommand(DockWorkspace dockWorkspace)\n\t\t\t: base(NavigationCommands.Search)\n\t\t{\n\t\t\tthis.dockWorkspace = dockWorkspace;\n\t\t\tvar gestures = NavigationCommands.Search.InputGestures;\n\n\t\t\tgestures.Clear();\n\t\t\tgestures.Add(new KeyGesture(Key.F, ModifierKeys.Control | ModifierKeys.Shift));\n\t\t\tgestures.Add(new KeyGesture(Key.E, ModifierKeys.Control));\n\t\t}\n\n\t\tprotected override void OnExecute(object sender, ExecutedRoutedEventArgs e)\n\t\t{\n\t\t\tdockWorkspace.ShowToolPane(SearchPaneModel.PaneContentId);\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Search/SearchPaneModel.cs",
    "content": "// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Windows.Input;\nusing System.Windows.Media;\n\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX.Search;\n\nnamespace ICSharpCode.ILSpy.Search\n{\n\tpublic class SearchModeModel\n\t{\n\t\tpublic SearchMode Mode { get; init; }\n\t\tpublic string Name { get; init; }\n\t\tpublic ImageSource Image { get; init; }\n\t}\n\n\t[ExportToolPane]\n\t[Shared]\n\tpublic class SearchPaneModel : ToolPaneModel\n\t{\n\t\tpublic const string PaneContentId = \"searchPane\";\n\n\t\tprivate readonly SettingsService settingsService;\n\t\tprivate string searchTerm;\n\n\t\tpublic SearchPaneModel(SettingsService settingsService)\n\t\t{\n\t\t\tthis.settingsService = settingsService;\n\t\t\tContentId = PaneContentId;\n\t\t\tTitle = Properties.Resources.SearchPane_Search;\n\t\t\tIcon = \"Images/Search\";\n\t\t\tShortcutKey = new(Key.F, ModifierKeys.Control | ModifierKeys.Shift);\n\t\t\tIsCloseable = true;\n\n\t\t\tMessageBus<ShowSearchPageEventArgs>.Subscribers += (_, e) => {\n\t\t\t\tSearchTerm = e.SearchTerm;\n\t\t\t\tShow();\n\t\t\t};\n\t\t\tMessageBus<ApplySessionSettingsEventArgs>.Subscribers += ApplySessionSettings;\n\t\t}\n\n\t\tprivate void ApplySessionSettings(object sender, ApplySessionSettingsEventArgs e)\n\t\t{\n\t\t\te.SessionSettings.SelectedSearchMode = SessionSettings.SelectedSearchMode;\n\t\t}\n\n\t\tpublic SearchModeModel[] SearchModes { get; } = [\n\t\t\tnew() { Mode = SearchMode.TypeAndMember, Image = Images.Library, Name = \"Types and Members\" },\n\t\t\tnew() { Mode = SearchMode.Type, Image = Images.Class, Name = \"Type\" },\n\t\t\tnew() { Mode = SearchMode.Member, Image = Images.Property, Name = \"Member\" },\n\t\t\tnew() { Mode = SearchMode.Method, Image = Images.Method, Name = \"Method\" },\n\t\t\tnew() { Mode = SearchMode.Field, Image = Images.Field, Name = \"Field\" },\n\t\t\tnew() { Mode = SearchMode.Property, Image = Images.Property, Name = \"Property\" },\n\t\t\tnew() { Mode = SearchMode.Event, Image = Images.Event, Name = \"Event\" },\n\t\t\tnew() { Mode = SearchMode.Literal, Image = Images.Literal, Name = \"Constant\" },\n\t\t\tnew() { Mode = SearchMode.Token, Image = Images.Library, Name = \"Metadata Token\" },\n\t\t\tnew() { Mode = SearchMode.Resource, Image = Images.Resource, Name = \"Resource\" },\n\t\t\tnew() { Mode = SearchMode.Assembly, Image = Images.Assembly, Name = \"Assembly\" },\n\t\t\tnew() { Mode = SearchMode.Namespace, Image = Images.Namespace, Name = \"Namespace\" }\n\t\t];\n\n\t\tpublic SessionSettings SessionSettings => settingsService.SessionSettings;\n\n\t\tpublic string SearchTerm {\n\t\t\tget => searchTerm;\n\t\t\tset => SetProperty(ref searchTerm, value);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Search/SearchResultFactory.cs",
    "content": "// Copyright (c) 2022 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\nusing System;\nusing System.Composition;\nusing System.Windows.Media;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Output;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpyX.Abstractions;\nusing ICSharpCode.ILSpyX.Search;\n\nnamespace ICSharpCode.ILSpy.Search\n{\n\tinternal class SearchResultFactory : ISearchResultFactory\n\t{\n\t\treadonly Language language;\n\n\t\tpublic SearchResultFactory(Language language)\n\t\t{\n\t\t\tthis.language = language;\n\t\t}\n\n\t\tfloat CalculateFitness(IEntity member)\n\t\t{\n\t\t\tstring text = member.Name;\n\n\t\t\t// Probably compiler generated types without meaningful names, show them last\n\t\t\tif (text.StartsWith(\"<\"))\n\t\t\t{\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\t// Constructors and destructors always have the same name in IL:\n\t\t\t// Use type name instead\n\t\t\tif (member.SymbolKind == SymbolKind.Constructor || member.SymbolKind == SymbolKind.Destructor)\n\t\t\t{\n\t\t\t\ttext = member.DeclaringType.Name;\n\t\t\t}\n\n\t\t\t// Ignore generic arguments, it not possible to search based on them either\n\t\t\ttext = ReflectionHelper.SplitTypeParameterCountFromReflectionName(text);\n\n\t\t\treturn 1.0f / text.Length;\n\t\t}\n\n\t\tstring GetLanguageSpecificName(IEntity member)\n\t\t{\n\t\t\tswitch (member)\n\t\t\t{\n\t\t\t\tcase ITypeDefinition t:\n\t\t\t\t\treturn language.TypeToString(t, ConversionFlags.None);\n\t\t\t\tcase IField f:\n\t\t\t\t\treturn language.EntityToString(f, ConversionFlags.ShowDeclaringType);\n\t\t\t\tcase IProperty p:\n\t\t\t\t\treturn language.EntityToString(p, ConversionFlags.ShowDeclaringType);\n\t\t\t\tcase IMethod m:\n\t\t\t\t\treturn language.EntityToString(m, ConversionFlags.ShowDeclaringType);\n\t\t\t\tcase IEvent e:\n\t\t\t\t\treturn language.EntityToString(e, ConversionFlags.ShowDeclaringType);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException(member?.GetType() + \" not supported!\");\n\t\t\t}\n\t\t}\n\n\t\tstatic ImageSource GetIcon(IEntity member)\n\t\t{\n\t\t\tswitch (member)\n\t\t\t{\n\t\t\t\tcase ITypeDefinition t:\n\t\t\t\t\treturn TypeTreeNode.GetIcon(t);\n\t\t\t\tcase IField f:\n\t\t\t\t\treturn FieldTreeNode.GetIcon(f);\n\t\t\t\tcase IProperty p:\n\t\t\t\t\treturn PropertyTreeNode.GetIcon(p);\n\t\t\t\tcase IMethod m:\n\t\t\t\t\treturn MethodTreeNode.GetIcon(m);\n\t\t\t\tcase IEvent e:\n\t\t\t\t\treturn EventTreeNode.GetIcon(e);\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new NotSupportedException(member?.GetType() + \" not supported!\");\n\t\t\t}\n\t\t}\n\n\t\tpublic MemberSearchResult Create(IEntity entity)\n\t\t{\n\t\t\tvar declaringType = entity.DeclaringTypeDefinition;\n\t\t\treturn new MemberSearchResult {\n\t\t\t\tMember = entity,\n\t\t\t\tFitness = CalculateFitness(entity),\n\t\t\t\tName = GetLanguageSpecificName(entity),\n\t\t\t\tLocation = declaringType != null ? language.TypeToString(declaringType, ConversionFlags.UseFullyQualifiedEntityNames | ConversionFlags.UseFullyQualifiedTypeNames) : entity.Namespace,\n\t\t\t\tAssembly = entity.ParentModule.FullAssemblyName,\n\t\t\t\tToolTip = entity.ParentModule.MetadataFile?.FileName,\n\t\t\t\tImage = GetIcon(entity),\n\t\t\t\tLocationImage = declaringType != null ? TypeTreeNode.GetIcon(declaringType) : Images.Namespace,\n\t\t\t\tAssemblyImage = Images.Assembly,\n\t\t\t};\n\t\t}\n\n\t\tpublic ResourceSearchResult Create(MetadataFile module, Resource resource, ITreeNode node, ITreeNode parent)\n\t\t{\n\t\t\treturn new ResourceSearchResult {\n\t\t\t\tResource = resource,\n\t\t\t\tFitness = 1.0f / resource.Name.Length,\n\t\t\t\tImage = node.Icon,\n\t\t\t\tName = resource.Name,\n\t\t\t\tLocationImage = parent.Icon,\n\t\t\t\tLocation = (string)parent.Text,\n\t\t\t\tAssembly = module.FullName,\n\t\t\t\tToolTip = module.FileName,\n\t\t\t\tAssemblyImage = Images.Assembly,\n\t\t\t};\n\t\t}\n\n\t\tpublic AssemblySearchResult Create(MetadataFile module)\n\t\t{\n\t\t\treturn new AssemblySearchResult {\n\t\t\t\tModule = module,\n\t\t\t\tFitness = 1.0f / module.Name.Length,\n\t\t\t\tName = module.Name,\n\t\t\t\tLocation = module.FileName,\n\t\t\t\tAssembly = module.FullName,\n\t\t\t\tToolTip = module.FileName,\n\t\t\t\tImage = Images.Assembly,\n\t\t\t\tLocationImage = Images.Library,\n\t\t\t\tAssemblyImage = Images.Assembly,\n\t\t\t};\n\t\t}\n\n\t\tpublic NamespaceSearchResult Create(MetadataFile module, INamespace ns)\n\t\t{\n\t\t\tvar name = ns.FullName.Length == 0 ? \"-\" : ns.FullName;\n\t\t\treturn new NamespaceSearchResult {\n\t\t\t\tNamespace = ns,\n\t\t\t\tName = name,\n\t\t\t\tFitness = 1.0f / name.Length,\n\t\t\t\tLocation = module.Name,\n\t\t\t\tAssembly = module.FullName,\n\t\t\t\tImage = Images.Namespace,\n\t\t\t\tLocationImage = Images.Assembly,\n\t\t\t\tAssemblyImage = Images.Assembly,\n\t\t\t};\n\t\t}\n\t}\n\n\t[Export(typeof(ITreeNodeFactory))]\n\t[Shared]\n\tinternal class TreeNodeFactory : ITreeNodeFactory\n\t{\n\t\tpublic ITreeNode Create(Resource resource)\n\t\t{\n\t\t\treturn ResourceTreeNode.Create(resource);\n\t\t}\n\n\t\tpublic ITreeNode CreateResourcesList(MetadataFile module)\n\t\t{\n\t\t\treturn new ResourceListTreeNode(module);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/SessionSettings.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Globalization;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Text;\nusing System.Text.RegularExpressions;\nusing System.Windows;\nusing System.Xml.Linq;\n\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpy.Themes;\nusing ICSharpCode.ILSpyX.Search;\nusing ICSharpCode.ILSpyX.Settings;\n\nnamespace ICSharpCode.ILSpy\n{\n\t/// <summary>\n\t/// Per-session setting:\n\t/// Loaded at startup; saved at exit.\n\t/// </summary>\n\tpublic sealed class SessionSettings : ISettingsSection\n\t{\n\t\tpublic XName SectionName => \"SessionSettings\";\n\n\t\tpublic void LoadFromXml(XElement section)\n\t\t{\n\t\t\tXElement filterSettings = section.Element(\"FilterSettings\") ?? new XElement(\"FilterSettings\");\n\n\t\t\tLanguageSettings = new(filterSettings, this);\n\t\t\tLanguageSettings.PropertyChanged += (sender, e) => PropertyChanged?.Invoke(sender, e);\n\n\t\t\tActiveAssemblyList = (string)section.Element(\"ActiveAssemblyList\");\n\t\t\tActiveTreeViewPath = section.Element(\"ActiveTreeViewPath\")?.Elements().Select(e => Unescape((string)e)).ToArray();\n\t\t\tActiveAutoLoadedAssembly = (string)section.Element(\"ActiveAutoLoadedAssembly\");\n\t\t\tWindowState = FromString((string)section.Element(\"WindowState\"), WindowState.Normal);\n\t\t\tWindowBounds = FromString((string)section.Element(\"WindowBounds\"), DefaultWindowBounds);\n\t\t\tSelectedSearchMode = FromString((string)section.Element(\"SelectedSearchMode\"), SearchMode.TypeAndMember);\n\t\t\tTheme = FromString((string)section.Element(nameof(Theme)), ThemeManager.Current.DefaultTheme);\n\t\t\tvar culture = (string)section.Element(nameof(CurrentCulture));\n\t\t\tCurrentCulture = string.IsNullOrEmpty(culture) ? null : culture;\n\t\t\tDockLayout = new(section.Element(\"DockLayout\"));\n\t\t}\n\n\t\tpublic LanguageSettings LanguageSettings { get; set; }\n\n\t\tpublic SearchMode SelectedSearchMode { get; set; }\n\n\t\tprivate string theme;\n\t\tpublic string Theme {\n\t\t\tget => theme;\n\t\t\tset => SetProperty(ref theme, value);\n\t\t}\n\n\t\tpublic string[] ActiveTreeViewPath;\n\t\tpublic string ActiveAutoLoadedAssembly;\n\n\t\tstring currentCulture;\n\n\t\tpublic string CurrentCulture {\n\t\t\tget { return currentCulture; }\n\t\t\tset {\n\t\t\t\tif (currentCulture != value)\n\t\t\t\t{\n\t\t\t\t\tcurrentCulture = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic string ActiveAssemblyList {\n\t\t\tget => activeAssemblyList;\n\t\t\tset {\n\t\t\t\tif (value != null && value != activeAssemblyList)\n\t\t\t\t{\n\t\t\t\t\tactiveAssemblyList = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic WindowState WindowState;\n\t\tpublic Rect WindowBounds;\n\t\tinternal static Rect DefaultWindowBounds = new(10, 10, 750, 550);\n\n\t\tpublic DockLayoutSettings DockLayout { get; set; }\n\n\t\tpublic XElement SaveToXml()\n\t\t{\n\t\t\tvar section = new XElement(SectionName);\n\n\t\t\tsection.Add(this.LanguageSettings.SaveAsXml());\n\t\t\tif (this.ActiveAssemblyList != null)\n\t\t\t{\n\t\t\t\tsection.Add(new XElement(\"ActiveAssemblyList\", this.ActiveAssemblyList));\n\t\t\t}\n\t\t\tif (this.ActiveTreeViewPath != null)\n\t\t\t{\n\t\t\t\tsection.Add(new XElement(\"ActiveTreeViewPath\", ActiveTreeViewPath.Select(p => new XElement(\"Node\", Escape(p)))));\n\t\t\t}\n\t\t\tif (this.ActiveAutoLoadedAssembly != null)\n\t\t\t{\n\t\t\t\tsection.Add(new XElement(\"ActiveAutoLoadedAssembly\", this.ActiveAutoLoadedAssembly));\n\t\t\t}\n\t\t\tsection.Add(new XElement(\"WindowState\", ToString(this.WindowState)));\n\t\t\tsection.Add(new XElement(\"WindowBounds\", ToString(this.WindowBounds)));\n\t\t\tsection.Add(new XElement(\"SelectedSearchMode\", ToString(this.SelectedSearchMode)));\n\t\t\tsection.Add(new XElement(nameof(Theme), ToString(this.Theme)));\n\t\t\tif (this.CurrentCulture != null)\n\t\t\t{\n\t\t\t\tsection.Add(new XElement(nameof(CurrentCulture), this.CurrentCulture));\n\t\t\t}\n\t\t\tvar dockLayoutElement = new XElement(\"DockLayout\");\n\t\t\tif (DockLayout.Valid)\n\t\t\t{\n\t\t\t\tdockLayoutElement.Add(DockLayout.SaveAsXml());\n\t\t\t}\n\t\t\tsection.Add(dockLayoutElement);\n\n\t\t\treturn section;\n\t\t}\n\n\t\tstatic Regex regex = new(\"\\\\\\\\x(?<num>[0-9A-f]{4})\");\n\t\tprivate string activeAssemblyList;\n\n\t\tstatic string Escape(string p)\n\t\t{\n\t\t\tStringBuilder sb = new();\n\t\t\tforeach (char ch in p)\n\t\t\t{\n\t\t\t\tif (char.IsLetterOrDigit(ch))\n\t\t\t\t\tsb.Append(ch);\n\t\t\t\telse\n\t\t\t\t\tsb.AppendFormat(\"\\\\x{0:X4}\", (int)ch);\n\t\t\t}\n\t\t\treturn sb.ToString();\n\t\t}\n\n\t\tstatic string Unescape(string p)\n\t\t{\n\t\t\treturn regex.Replace(p, m => ((char)int.Parse(m.Groups[\"num\"].Value, NumberStyles.HexNumber)).ToString());\n\t\t}\n\n\t\tstatic T FromString<T>(string s, T defaultValue)\n\t\t{\n\t\t\tif (s == null)\n\t\t\t\treturn defaultValue;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tTypeConverter c = TypeDescriptor.GetConverter(typeof(T));\n\t\t\t\treturn (T)c.ConvertFromInvariantString(s);\n\t\t\t}\n\t\t\tcatch (FormatException)\n\t\t\t{\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\t\t}\n\n\t\tstatic string ToString<T>(T obj)\n\t\t{\n\t\t\tTypeConverter c = TypeDescriptor.GetConverter(typeof(T));\n\t\t\treturn c.ConvertToInvariantString(obj);\n\t\t}\n\n\t\tpublic event PropertyChangedEventHandler PropertyChanged;\n\n\t\tprivate void OnPropertyChanged([CallerMemberName] string propertyName = null)\n\t\t{\n\t\t\tPropertyChanged?.Invoke(this, new(propertyName));\n\t\t}\n\n\t\tprivate bool SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)\n\t\t{\n\t\t\tif (EqualityComparer<T>.Default.Equals(field, value))\n\t\t\t\treturn false;\n\t\t\tfield = value;\n\t\t\tOnPropertyChanged(propertyName);\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/SolutionWriter.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Solution;\nusing ICSharpCode.Decompiler.Util;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX;\n\nnamespace ICSharpCode.ILSpy\n{\n\t/// <summary>\n\t/// An utility class that creates a Visual Studio solution containing projects for the\n\t/// decompiled assemblies.\n\t/// </summary>\n\tinternal class SolutionWriter\n\t{\n\t\t/// <summary>\n\t\t/// Creates a Visual Studio solution that contains projects with decompiled code\n\t\t/// of the specified <paramref name=\"assemblies\"/>. The solution file will be saved\n\t\t/// to the <paramref name=\"solutionFilePath\"/>. The directory of this file must either\n\t\t/// be empty or not exist.\n\t\t/// </summary>\n\t\t/// <param name=\"tabPage\"></param>\n\t\t/// <param name=\"textView\">A reference to the <see cref=\"DecompilerTextView\"/> instance.</param>\n\t\t/// <param name=\"solutionFilePath\">The target file path of the solution file.</param>\n\t\t/// <param name=\"language\"></param>\n\t\t/// <param name=\"assemblies\">The assembly nodes to decompile.</param>\n\t\t/// <exception cref=\"ArgumentException\">Thrown when <paramref name=\"solutionFilePath\"/> is null,\n\t\t/// an empty or a whitespace string.</exception>\n\t\t/// <exception cref=\"ArgumentNullException\">Thrown when <paramref name=\"textView\"/>> or\n\t\t/// <paramref name=\"assemblies\"/> is null.</exception>\n\t\tpublic static void CreateSolution(TabPageModel tabPage, DecompilerTextView textView, string solutionFilePath,\n\t\t\tLanguage language, List<LoadedAssembly> assemblies)\n\t\t{\n\t\t\tif (textView == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(textView));\n\t\t\t}\n\n\t\t\tif (string.IsNullOrWhiteSpace(solutionFilePath))\n\t\t\t{\n\t\t\t\tthrow new ArgumentException(\"The solution file path cannot be null or empty.\", nameof(solutionFilePath));\n\t\t\t}\n\n\t\t\tif (assemblies == null)\n\t\t\t{\n\t\t\t\tthrow new ArgumentNullException(nameof(assemblies));\n\t\t\t}\n\n\t\t\tvar writer = new SolutionWriter(solutionFilePath);\n\n\t\t\ttextView\n\t\t\t\t.RunWithCancellation(ct => writer.CreateSolution(tabPage, assemblies, language, ct))\n\t\t\t\t.Then(textView.ShowText)\n\t\t\t\t.HandleExceptions();\n\t\t}\n\n\t\treadonly string solutionFilePath;\n\t\treadonly string solutionDirectory;\n\t\treadonly ConcurrentBag<ProjectItem> projects;\n\t\treadonly ConcurrentBag<string> statusOutput;\n\n\t\tSolutionWriter(string solutionFilePath)\n\t\t{\n\t\t\tthis.solutionFilePath = solutionFilePath;\n\t\t\tsolutionDirectory = Path.GetDirectoryName(solutionFilePath);\n\t\t\tstatusOutput = new ConcurrentBag<string>();\n\t\t\tprojects = new ConcurrentBag<ProjectItem>();\n\t\t}\n\n\t\tasync Task<AvalonEditTextOutput> CreateSolution(TabPageModel tabPage, List<LoadedAssembly> allAssemblies, Language language, CancellationToken ct)\n\t\t{\n\t\t\tvar result = new AvalonEditTextOutput();\n\n\t\t\tvar assembliesByShortName = allAssemblies.GroupBy(_ => _.ShortName).ToDictionary(_ => _.Key, _ => _.ToList());\n\t\t\tbool first = true;\n\t\t\tbool abort = false;\n\n\t\t\tforeach (var (shortName, assemblies) in assembliesByShortName)\n\t\t\t{\n\t\t\t\tif (assemblies.Count == 1)\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (first)\n\t\t\t\t{\n\t\t\t\t\tresult.WriteLine(\"Duplicate assembly names selected, cannot generate a solution:\");\n\t\t\t\t\tabort = true;\n\t\t\t\t\tfirst = false;\n\t\t\t\t}\n\n\t\t\t\tresult.WriteLine(\"- \" + assemblies[0].Text + \" conflicts with \" + string.Join(\", \", assemblies.Skip(1).Select(a => a.Text)));\n\t\t\t}\n\n\t\t\tif (abort)\n\t\t\t\treturn result;\n\n\t\t\tStopwatch stopwatch = Stopwatch.StartNew();\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// Explicitly create an enumerable partitioner here to avoid Parallel.ForEach's special cases for lists,\n\t\t\t\t// as those seem to use static partitioning which is inefficient if assemblies take differently\n\t\t\t\t// long to decompile.\n\t\t\t\tawait Task.Run(() => Parallel.ForEach(Partitioner.Create(allAssemblies),\n\t\t\t\t\tnew ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = ct },\n\t\t\t\t\titem => WriteProject(tabPage, item, language, solutionDirectory, ct)))\n\t\t\t\t\t.ConfigureAwait(false);\n\n\t\t\t\tif (projects.Count == 0)\n\t\t\t\t{\n\t\t\t\t\tresult.WriteLine();\n\t\t\t\t\tresult.WriteLine(\"Solution could not be created, because none of the selected assemblies could be decompiled into a project.\");\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tawait Task.Run(() => SolutionCreator.WriteSolutionFile(solutionFilePath, projects.ToList()), ct)\n\t\t\t\t\t\t\t.ConfigureAwait(false);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (AggregateException ae)\n\t\t\t{\n\t\t\t\tif (ae.Flatten().InnerExceptions.All(e => e is OperationCanceledException))\n\t\t\t\t{\n\t\t\t\t\tresult.WriteLine();\n\t\t\t\t\tresult.WriteLine(\"Generation was cancelled.\");\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tresult.WriteLine();\n\t\t\t\tresult.WriteLine(\"Failed to generate the Visual Studio Solution. Errors:\");\n\t\t\t\tae.Handle(e => {\n\t\t\t\t\tresult.WriteLine(e.Message);\n\t\t\t\t\treturn true;\n\t\t\t\t});\n\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tforeach (var item in statusOutput)\n\t\t\t{\n\t\t\t\tresult.WriteLine(item);\n\t\t\t}\n\n\t\t\tif (statusOutput.Count == 0)\n\t\t\t{\n\t\t\t\tresult.WriteLine(\"Successfully decompiled the following assemblies into Visual Studio projects:\");\n\t\t\t\tforeach (var n in allAssemblies)\n\t\t\t\t{\n\t\t\t\t\tresult.WriteLine(n.Text.ToString());\n\t\t\t\t}\n\n\t\t\t\tresult.WriteLine();\n\n\t\t\t\tif (allAssemblies.Count == projects.Count)\n\t\t\t\t{\n\t\t\t\t\tresult.WriteLine(\"Created the Visual Studio Solution file.\");\n\t\t\t\t}\n\n\t\t\t\tresult.WriteLine();\n\t\t\t\tresult.WriteLine(\"Elapsed time: \" + stopwatch.Elapsed.TotalSeconds.ToString(\"F1\") + \" seconds.\");\n\t\t\t\tresult.WriteLine();\n\t\t\t\tresult.AddButton(null, Resources.OpenExplorer, delegate { ShellHelper.OpenFolderAndSelectItem(solutionFilePath); });\n\t\t\t}\n\n\t\t\treturn result;\n\t\t}\n\n\t\tvoid WriteProject(TabPageModel tabPage, LoadedAssembly loadedAssembly, Language language, string targetDirectory, CancellationToken ct)\n\t\t{\n\t\t\ttargetDirectory = Path.Combine(targetDirectory, loadedAssembly.ShortName);\n\n\t\t\tif (language.ProjectFileExtension == null)\n\t\t\t{\n\t\t\t\tstatusOutput.Add(\"-------------\");\n\t\t\t\tstatusOutput.Add($\"Language '{language.Name}' does not support exporting assemblies as projects!\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tstring projectFileName = Path.Combine(targetDirectory, loadedAssembly.ShortName + language.ProjectFileExtension);\n\n\t\t\tif (File.Exists(targetDirectory))\n\t\t\t{\n\t\t\t\tstatusOutput.Add(\"-------------\");\n\t\t\t\tstatusOutput.Add($\"Failed to create a directory '{targetDirectory}':{Environment.NewLine}A file with the same name already exists!\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!Directory.Exists(targetDirectory))\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tDirectory.CreateDirectory(targetDirectory);\n\t\t\t\t}\n\t\t\t\tcatch (Exception e)\n\t\t\t\t{\n\t\t\t\t\tstatusOutput.Add(\"-------------\");\n\t\t\t\t\tstatusOutput.Add($\"Failed to create a directory '{targetDirectory}':{Environment.NewLine}{e}\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tusing (var projectFileWriter = new StreamWriter(projectFileName))\n\t\t\t\t{\n\t\t\t\t\tvar projectFileOutput = new PlainTextOutput(projectFileWriter);\n\t\t\t\t\tvar options = tabPage.CreateDecompilationOptions();\n\t\t\t\t\toptions.FullDecompilation = true;\n\t\t\t\t\toptions.CancellationToken = ct;\n\t\t\t\t\toptions.SaveAsProjectDirectory = targetDirectory;\n\n\t\t\t\t\tvar projectInfo = language.DecompileAssembly(loadedAssembly, projectFileOutput, options);\n\t\t\t\t\tif (projectInfo != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tprojects.Add(new ProjectItem(projectFileName, projectInfo.PlatformName, projectInfo.Guid, projectInfo.TypeGuid));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (NotSupportedException e)\n\t\t\t{\n\t\t\t\tstatusOutput.Add(\"-------------\");\n\t\t\t\tstatusOutput.Add($\"Failed to decompile the assembly '{loadedAssembly.FileName}':{Environment.NewLine}{e.Message}\");\n\t\t\t}\n\t\t\tcatch (PathTooLongException e)\n\t\t\t{\n\t\t\t\tstatusOutput.Add(\"-------------\");\n\t\t\t\tstatusOutput.Add(string.Format(Properties.Resources.ProjectExportPathTooLong, loadedAssembly.FileName)\n\t\t\t\t\t+ Environment.NewLine + Environment.NewLine\n\t\t\t\t\t+ e.ToString());\n\t\t\t}\n\t\t\tcatch (Exception e) when (!(e is OperationCanceledException))\n\t\t\t{\n\t\t\t\tstatusOutput.Add(\"-------------\");\n\t\t\t\tstatusOutput.Add($\"Failed to decompile the assembly '{loadedAssembly.FileName}':{Environment.NewLine}{e}\");\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TaskHelper.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpy.TextView;\n\nnamespace ICSharpCode.ILSpy\n{\n\tpublic static class TaskHelper\n\t{\n\t\tpublic static readonly Task CompletedTask = FromResult<object>(null);\n\n\t\tpublic static Task<T> FromResult<T>(T result)\n\t\t{\n\t\t\tTaskCompletionSource<T> tcs = new TaskCompletionSource<T>();\n\t\t\ttcs.SetResult(result);\n\t\t\treturn tcs.Task;\n\t\t}\n\n\t\tpublic static Task<T> FromException<T>(Exception ex)\n\t\t{\n\t\t\tvar tcs = new TaskCompletionSource<T>();\n\t\t\ttcs.SetException(ex);\n\t\t\treturn tcs.Task;\n\t\t}\n\n\t\tpublic static Task<T> FromCancellation<T>()\n\t\t{\n\t\t\tvar tcs = new TaskCompletionSource<T>();\n\t\t\ttcs.SetCanceled();\n\t\t\treturn tcs.Task;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Sets the result of the TaskCompletionSource based on the result of the finished task.\n\t\t/// </summary>\n\t\tpublic static void SetFromTask<T>(this TaskCompletionSource<T> tcs, Task<T> task)\n\t\t{\n\t\t\tswitch (task.Status)\n\t\t\t{\n\t\t\t\tcase TaskStatus.RanToCompletion:\n\t\t\t\t\ttcs.SetResult(task.Result);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TaskStatus.Canceled:\n\t\t\t\t\ttcs.SetCanceled();\n\t\t\t\t\tbreak;\n\t\t\t\tcase TaskStatus.Faulted:\n\t\t\t\t\ttcs.SetException(task.Exception.InnerExceptions);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new InvalidOperationException(\"The input task must have already finished\");\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Sets the result of the TaskCompletionSource based on the result of the finished task.\n\t\t/// </summary>\n\t\tpublic static void SetFromTask(this TaskCompletionSource<object> tcs, Task task)\n\t\t{\n\t\t\tswitch (task.Status)\n\t\t\t{\n\t\t\t\tcase TaskStatus.RanToCompletion:\n\t\t\t\t\ttcs.SetResult(null);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TaskStatus.Canceled:\n\t\t\t\t\ttcs.SetCanceled();\n\t\t\t\t\tbreak;\n\t\t\t\tcase TaskStatus.Faulted:\n\t\t\t\t\ttcs.SetException(task.Exception.InnerExceptions);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new InvalidOperationException(\"The input task must have already finished\");\n\t\t\t}\n\t\t}\n\n\t\tpublic static Task Then<T>(this Task<T> task, Action<T> action)\n\t\t{\n\t\t\tif (action == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(action));\n\t\t\treturn task.ContinueWith(t => action(t.Result), CancellationToken.None, TaskContinuationOptions.NotOnCanceled, TaskScheduler.FromCurrentSynchronizationContext());\n\t\t}\n\n\t\tpublic static Task<U> Then<T, U>(this Task<T> task, Func<T, U> func)\n\t\t{\n\t\t\tif (func == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(func));\n\t\t\treturn task.ContinueWith(t => func(t.Result), CancellationToken.None, TaskContinuationOptions.NotOnCanceled, TaskScheduler.FromCurrentSynchronizationContext());\n\t\t}\n\n\t\tpublic static Task Then<T>(this Task<T> task, Func<T, Task> asyncFunc)\n\t\t{\n\t\t\tif (asyncFunc == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(asyncFunc));\n\t\t\treturn task.ContinueWith(t => asyncFunc(t.Result), CancellationToken.None, TaskContinuationOptions.NotOnCanceled, TaskScheduler.FromCurrentSynchronizationContext()).Unwrap();\n\t\t}\n\n\t\tpublic static Task<U> Then<T, U>(this Task<T> task, Func<T, Task<U>> asyncFunc)\n\t\t{\n\t\t\tif (asyncFunc == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(asyncFunc));\n\t\t\treturn task.ContinueWith(t => asyncFunc(t.Result), CancellationToken.None, TaskContinuationOptions.NotOnCanceled, TaskScheduler.FromCurrentSynchronizationContext()).Unwrap();\n\t\t}\n\n\t\tpublic static Task Then(this Task task, Action action)\n\t\t{\n\t\t\tif (action == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(action));\n\t\t\treturn task.ContinueWith(t => {\n\t\t\t\tt.Wait();\n\t\t\t\taction();\n\t\t\t}, CancellationToken.None, TaskContinuationOptions.NotOnCanceled, TaskScheduler.FromCurrentSynchronizationContext());\n\t\t}\n\n\t\tpublic static Task<U> Then<U>(this Task task, Func<U> func)\n\t\t{\n\t\t\tif (func == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(func));\n\t\t\treturn task.ContinueWith(t => {\n\t\t\t\tt.Wait();\n\t\t\t\treturn func();\n\t\t\t}, CancellationToken.None, TaskContinuationOptions.NotOnCanceled, TaskScheduler.FromCurrentSynchronizationContext());\n\t\t}\n\n\t\tpublic static Task Then(this Task task, Func<Task> asyncAction)\n\t\t{\n\t\t\tif (asyncAction == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(asyncAction));\n\t\t\treturn task.ContinueWith(t => {\n\t\t\t\tt.Wait();\n\t\t\t\treturn asyncAction();\n\t\t\t}, CancellationToken.None, TaskContinuationOptions.NotOnCanceled, TaskScheduler.FromCurrentSynchronizationContext()).Unwrap();\n\t\t}\n\n\t\tpublic static Task<U> Then<U>(this Task task, Func<Task<U>> asyncFunc)\n\t\t{\n\t\t\tif (asyncFunc == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(asyncFunc));\n\t\t\treturn task.ContinueWith(t => {\n\t\t\t\tt.Wait();\n\t\t\t\treturn asyncFunc();\n\t\t\t}, CancellationToken.None, TaskContinuationOptions.NotOnCanceled, TaskScheduler.FromCurrentSynchronizationContext()).Unwrap();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// If the input task fails, calls the action to handle the error.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// Returns a task that finishes successfully when error handling has completed.\n\t\t/// If the input task ran successfully, the returned task completes successfully.\n\t\t/// If the input task was cancelled, the returned task is cancelled as well.\n\t\t/// </returns>\n\t\tpublic static Task Catch<TException>(this Task task, Action<TException> action) where TException : Exception\n\t\t{\n\t\t\tif (action == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(action));\n\t\t\treturn task.ContinueWith(t => {\n\t\t\t\tif (t.IsFaulted)\n\t\t\t\t{\n\t\t\t\t\tException ex = t.Exception;\n\t\t\t\t\twhile (ex is AggregateException)\n\t\t\t\t\t\tex = ex.InnerException;\n\t\t\t\t\tif (ex is TException)\n\t\t\t\t\t\taction((TException)ex);\n\t\t\t\t\telse\n\t\t\t\t\t\tthrow t.Exception;\n\t\t\t\t}\n\t\t\t}, CancellationToken.None, TaskContinuationOptions.NotOnCanceled, TaskScheduler.FromCurrentSynchronizationContext());\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Ignore exceptions thrown by the task.\n\t\t/// </summary>\n\t\tpublic static void IgnoreExceptions(this Task task)\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Handle exceptions by displaying the error message in the text view.\n\t\t/// </summary>\n\t\tpublic static void HandleExceptions(this Task task)\n\t\t{\n\t\t\ttask.Catch<Exception>(exception => App.Current.Dispatcher.BeginInvoke(new Action(delegate {\n\t\t\t\tAvalonEditTextOutput output = new();\n\t\t\t\toutput.Write(exception.ToString());\n\t\t\t\tApp.ExportProvider.GetExportedValue<DockWorkspace>().ShowText(output);\n\t\t\t}))).IgnoreExceptions();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TextView/Asm-Mode.xshd",
    "content": "<SyntaxDefinition name=\"Asm\" extensions=\".s;.asm\" xmlns=\"http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008\">\n\t<Color name=\"Comment\" foreground=\"Green\" exampleText=\"; comment\" />\n\t<Color name=\"NumberLiteral\" foreground=\"Orange\" exampleText=\"0987654321\" />\n\t<Color name=\"String\" foreground=\"Magenta\" exampleText=\"&quot;Hello, World!&quot;\" />\n\t<Color name=\"Instructions\" foreground=\"Blue\" exampleText=\"nop\" />\n\t<Color name=\"Math Instructions\" foreground=\"#0080C0\" exampleText=\"nop\" />\n\t<Color name=\"Extended Instructions\" foreground=\"Brown\" exampleText=\"nop\" />\n\t<Color name=\"Registers\" foreground=\"#8080FF\" background=\"#EEEEEE\" exampleText=\"nop\" />\n\t<Color name=\"Directives\" foreground=\"Blue\" fontWeight=\"bold\" exampleText=\".class\" />\n\t<Color name=\"Directive Operands\" foreground=\"DarkBlue\" fontWeight=\"bold\" exampleText=\".class\" />\n\t<Color name=\"Address and Bytes\" exampleText=\"00000000003DEB40 56\" />\n\n\t<RuleSet ignoreCase=\"false\">\n\t\t<Keywords color=\"Instructions\">\n\t\t\t<Word>aaa</Word>\n\t\t\t<Word>aad</Word>\n\t\t\t<Word>aam</Word>\n\t\t\t<Word>aas</Word>\n\t\t\t<Word>adc</Word>\n\t\t\t<Word>add</Word>\n\t\t\t<Word>and</Word>\n\t\t\t<Word>call</Word>\n\t\t\t<Word>cbw</Word>\n\t\t\t<Word>cdqe</Word>\n\t\t\t<Word>clc</Word>\n\t\t\t<Word>cld</Word>\n\t\t\t<Word>cli</Word>\n\t\t\t<Word>cmc</Word>\n\t\t\t<Word>cmp</Word>\n\t\t\t<Word>cmps</Word>\n\t\t\t<Word>cmpsb</Word>\n\t\t\t<Word>cmpsw</Word>\n\t\t\t<Word>cwd</Word>\n\t\t\t<Word>daa</Word>\n\t\t\t<Word>das</Word>\n\t\t\t<Word>dec</Word>\n\t\t\t<Word>div</Word>\n\t\t\t<Word>esc</Word>\n\t\t\t<Word>hlt</Word>\n\t\t\t<Word>idiv</Word>\n\t\t\t<Word>imul</Word>\n\t\t\t<Word>in</Word>\n\t\t\t<Word>inc</Word>\n\t\t\t<Word>int</Word>\n\t\t\t<Word>into</Word>\n\t\t\t<Word>iret</Word>\n\t\t\t<Word>ja</Word>\n\t\t\t<Word>jae</Word>\n\t\t\t<Word>jb</Word>\n\t\t\t<Word>jbe</Word>\n\t\t\t<Word>jc</Word>\n\t\t\t<Word>jcxz</Word>\n\t\t\t<Word>je</Word>\n\t\t\t<Word>jg</Word>\n\t\t\t<Word>jge</Word>\n\t\t\t<Word>jl</Word>\n\t\t\t<Word>jle</Word>\n\t\t\t<Word>jmp</Word>\n\t\t\t<Word>jna</Word>\n\t\t\t<Word>jnae</Word>\n\t\t\t<Word>jnb</Word>\n\t\t\t<Word>jnbe</Word>\n\t\t\t<Word>jnc</Word>\n\t\t\t<Word>jne</Word>\n\t\t\t<Word>jng</Word>\n\t\t\t<Word>jnge</Word>\n\t\t\t<Word>jnl</Word>\n\t\t\t<Word>jnle</Word>\n\t\t\t<Word>jno</Word>\n\t\t\t<Word>jnp</Word>\n\t\t\t<Word>jns</Word>\n\t\t\t<Word>jnz</Word>\n\t\t\t<Word>jo</Word>\n\t\t\t<Word>jp</Word>\n\t\t\t<Word>jpe</Word>\n\t\t\t<Word>jpo</Word>\n\t\t\t<Word>js</Word>\n\t\t\t<Word>jz</Word>\n\t\t\t<Word>lahf</Word>\n\t\t\t<Word>lds</Word>\n\t\t\t<Word>lea</Word>\n\t\t\t<Word>les</Word>\n\t\t\t<Word>lods</Word>\n\t\t\t<Word>lodsb</Word>\n\t\t\t<Word>lodsw</Word>\n\t\t\t<Word>loop</Word>\n\t\t\t<Word>loope</Word>\n\t\t\t<Word>loopew</Word>\n\t\t\t<Word>loopne</Word>\n\t\t\t<Word>loopnew</Word>\n\t\t\t<Word>loopnz</Word>\n\t\t\t<Word>loopnzw</Word>\n\t\t\t<Word>loopw</Word>\n\t\t\t<Word>loopz</Word>\n\t\t\t<Word>loopzw</Word>\n\t\t\t<Word>mov</Word>\n\t\t\t<Word>movabs</Word>\n\t\t\t<Word>movs</Word>\n\t\t\t<Word>movsb</Word>\n\t\t\t<Word>movsw</Word>\n\t\t\t<Word>mul</Word>\n\t\t\t<Word>neg</Word>\n\t\t\t<Word>nop</Word>\n\t\t\t<Word>not</Word>\n\t\t\t<Word>or</Word>\n\t\t\t<Word>out</Word>\n\t\t\t<Word>pop</Word>\n\t\t\t<Word>popf</Word>\n\t\t\t<Word>push</Word>\n\t\t\t<Word>pushf</Word>\n\t\t\t<Word>rcl</Word>\n\t\t\t<Word>rcr</Word>\n\t\t\t<Word>ret</Word>\n\t\t\t<Word>retf</Word>\n\t\t\t<Word>retn</Word>\n\t\t\t<Word>rol</Word>\n\t\t\t<Word>ror</Word>\n\t\t\t<Word>sahf</Word>\n\t\t\t<Word>sal</Word>\n\t\t\t<Word>sar</Word>\n\t\t\t<Word>sbb</Word>\n\t\t\t<Word>scas</Word>\n\t\t\t<Word>scasb</Word>\n\t\t\t<Word>scasw</Word>\n\t\t\t<Word>shl</Word>\n\t\t\t<Word>shr</Word>\n\t\t\t<Word>stc</Word>\n\t\t\t<Word>std</Word>\n\t\t\t<Word>sti</Word>\n\t\t\t<Word>stos</Word>\n\t\t\t<Word>stosb</Word>\n\t\t\t<Word>stosw</Word>\n\t\t\t<Word>sub</Word>\n\t\t\t<Word>test</Word>\n\t\t\t<Word>wait</Word>\n\t\t\t<Word>xchg</Word>\n\t\t\t<Word>xlat</Word>\n\t\t\t<Word>xlatb</Word>\n\t\t\t<Word>xor</Word>\n\t\t\t<Word>bound</Word>\n\t\t\t<Word>enter</Word>\n\t\t\t<Word>ins</Word>\n\t\t\t<Word>insb</Word>\n\t\t\t<Word>insw</Word>\n\t\t\t<Word>leave</Word>\n\t\t\t<Word>outs</Word>\n\t\t\t<Word>outsb</Word>\n\t\t\t<Word>outsw</Word>\n\t\t\t<Word>popa</Word>\n\t\t\t<Word>pusha</Word>\n\t\t\t<Word>pushw</Word>\n\t\t\t<Word>arpl</Word>\n\t\t\t<Word>lar</Word>\n\t\t\t<Word>lsl</Word>\n\t\t\t<Word>sgdt</Word>\n\t\t\t<Word>sidt</Word>\n\t\t\t<Word>sldt</Word>\n\t\t\t<Word>smsw</Word>\n\t\t\t<Word>str</Word>\n\t\t\t<Word>verr</Word>\n\t\t\t<Word>verw</Word>\n\t\t\t<Word>clts</Word>\n\t\t\t<Word>lgdt</Word>\n\t\t\t<Word>lidt</Word>\n\t\t\t<Word>lldt</Word>\n\t\t\t<Word>lmsw</Word>\n\t\t\t<Word>ltr</Word>\n\t\t\t<Word>bsf</Word>\n\t\t\t<Word>bsr</Word>\n\t\t\t<Word>bt</Word>\n\t\t\t<Word>btc</Word>\n\t\t\t<Word>btr</Word>\n\t\t\t<Word>bts</Word>\n\t\t\t<Word>cdq</Word>\n\t\t\t<Word>cmpsd</Word>\n\t\t\t<Word>cwde</Word>\n\t\t\t<Word>insd</Word>\n\t\t\t<Word>iretd</Word>\n\t\t\t<Word>iretdf</Word>\n\t\t\t<Word>iretf</Word>\n\t\t\t<Word>jecxz</Word>\n\t\t\t<Word>lfs</Word>\n\t\t\t<Word>lgs</Word>\n\t\t\t<Word>lodsd</Word>\n\t\t\t<Word>loopd</Word>\n\t\t\t<Word>looped</Word>\n\t\t\t<Word>loopned</Word>\n\t\t\t<Word>loopnzd</Word>\n\t\t\t<Word>loopzd</Word>\n\t\t\t<Word>lss</Word>\n\t\t\t<Word>movsd</Word>\n\t\t\t<Word>movsx</Word>\n\t\t\t<Word>movsxd</Word>\n\t\t\t<Word>movzx</Word>\n\t\t\t<Word>outsd</Word>\n\t\t\t<Word>popad</Word>\n\t\t\t<Word>popfd</Word>\n\t\t\t<Word>pushad</Word>\n\t\t\t<Word>pushd</Word>\n\t\t\t<Word>pushfd</Word>\n\t\t\t<Word>scasd</Word>\n\t\t\t<Word>seta</Word>\n\t\t\t<Word>setae</Word>\n\t\t\t<Word>setb</Word>\n\t\t\t<Word>setbe</Word>\n\t\t\t<Word>setc</Word>\n\t\t\t<Word>sete</Word>\n\t\t\t<Word>setg</Word>\n\t\t\t<Word>setge</Word>\n\t\t\t<Word>setl</Word>\n\t\t\t<Word>setle</Word>\n\t\t\t<Word>setna</Word>\n\t\t\t<Word>setnae</Word>\n\t\t\t<Word>setnb</Word>\n\t\t\t<Word>setnbe</Word>\n\t\t\t<Word>setnc</Word>\n\t\t\t<Word>setne</Word>\n\t\t\t<Word>setng</Word>\n\t\t\t<Word>setnge</Word>\n\t\t\t<Word>setnl</Word>\n\t\t\t<Word>setnle</Word>\n\t\t\t<Word>setno</Word>\n\t\t\t<Word>setnp</Word>\n\t\t\t<Word>setns</Word>\n\t\t\t<Word>setnz</Word>\n\t\t\t<Word>seto</Word>\n\t\t\t<Word>setp</Word>\n\t\t\t<Word>setpe</Word>\n\t\t\t<Word>setpo</Word>\n\t\t\t<Word>sets</Word>\n\t\t\t<Word>setz</Word>\n\t\t\t<Word>shld</Word>\n\t\t\t<Word>shrd</Word>\n\t\t\t<Word>stosd</Word>\n\t\t\t<Word>bswap</Word>\n\t\t\t<Word>cmpxchg</Word>\n\t\t\t<Word>invd</Word>\n\t\t\t<Word>invlpg</Word>\n\t\t\t<Word>wbinvd</Word>\n\t\t\t<Word>xadd</Word>\n\t\t\t<Word>lock</Word>\n\t\t\t<Word>rep</Word>\n\t\t\t<Word>repe</Word>\n\t\t\t<Word>repne</Word>\n\t\t\t<Word>repnz</Word>\n\t\t\t<Word>repz</Word>\n\t\t\t<Word>cflush</Word>\n\t\t\t<Word>cpuid</Word>\n\t\t\t<Word>emms</Word>\n\t\t\t<Word>femms</Word>\n\t\t\t<Word>cmovo</Word>\n\t\t\t<Word>cmovno</Word>\n\t\t\t<Word>cmovb</Word>\n\t\t\t<Word>cmovc</Word>\n\t\t\t<Word>cmovnae</Word>\n\t\t\t<Word>cmovae</Word>\n\t\t\t<Word>cmovnb</Word>\n\t\t\t<Word>cmovnc</Word>\n\t\t\t<Word>cmove</Word>\n\t\t\t<Word>cmovz</Word>\n\t\t\t<Word>cmovne</Word>\n\t\t\t<Word>cmovnz</Word>\n\t\t\t<Word>cmovbe</Word>\n\t\t\t<Word>cmovna</Word>\n\t\t\t<Word>cmova</Word>\n\t\t\t<Word>cmovnbe</Word>\n\t\t\t<Word>cmovs</Word>\n\t\t\t<Word>cmovns</Word>\n\t\t\t<Word>cmovp</Word>\n\t\t\t<Word>cmovpe</Word>\n\t\t\t<Word>cmovnp</Word>\n\t\t\t<Word>cmovpo</Word>\n\t\t\t<Word>cmovl</Word>\n\t\t\t<Word>cmovnge</Word>\n\t\t\t<Word>cmovge</Word>\n\t\t\t<Word>cmovnl</Word>\n\t\t\t<Word>cmovle</Word>\n\t\t\t<Word>cmovng</Word>\n\t\t\t<Word>cmovg</Word>\n\t\t\t<Word>cmovnle</Word>\n\t\t\t<Word>cmpxchg486</Word>\n\t\t\t<Word>cmpxchg8b</Word>\n\t\t\t<Word>loadall</Word>\n\t\t\t<Word>loadall286</Word>\n\t\t\t<Word>ibts</Word>\n\t\t\t<Word>icebp</Word>\n\t\t\t<Word>int1</Word>\n\t\t\t<Word>int3</Word>\n\t\t\t<Word>int01</Word>\n\t\t\t<Word>int03</Word>\n\t\t\t<Word>iretw</Word>\n\t\t\t<Word>popaw</Word>\n\t\t\t<Word>popfw</Word>\n\t\t\t<Word>pushaw</Word>\n\t\t\t<Word>pushfw</Word>\n\t\t\t<Word>rdmsr</Word>\n\t\t\t<Word>rdpmc</Word>\n\t\t\t<Word>rdshr</Word>\n\t\t\t<Word>rdtsc</Word>\n\t\t\t<Word>rsdc</Word>\n\t\t\t<Word>rsldt</Word>\n\t\t\t<Word>rsm</Word>\n\t\t\t<Word>rsts</Word>\n\t\t\t<Word>salc</Word>\n\t\t\t<Word>smi</Word>\n\t\t\t<Word>smint</Word>\n\t\t\t<Word>smintold</Word>\n\t\t\t<Word>svdc</Word>\n\t\t\t<Word>svldt</Word>\n\t\t\t<Word>svts</Word>\n\t\t\t<Word>syscall</Word>\n\t\t\t<Word>sysenter</Word>\n\t\t\t<Word>sysexit</Word>\n\t\t\t<Word>sysret</Word>\n\t\t\t<Word>ud0</Word>\n\t\t\t<Word>ud1</Word>\n\t\t\t<Word>ud2</Word>\n\t\t\t<Word>umov</Word>\n\t\t\t<Word>xbts</Word>\n\t\t\t<Word>wrmsr</Word>\n\t\t\t<Word>wrshr</Word>\n\t\t</Keywords>\n\t\t<Keywords color=\"Math Instructions\">\n\t\t\t<Word>f2xm1</Word>\n\t\t\t<Word>fabs</Word>\n\t\t\t<Word>fadd</Word>\n\t\t\t<Word>faddp</Word>\n\t\t\t<Word>fbld</Word>\n\t\t\t<Word>fbstp</Word>\n\t\t\t<Word>fchs</Word>\n\t\t\t<Word>fclex</Word>\n\t\t\t<Word>fcom</Word>\n\t\t\t<Word>fcomp</Word>\n\t\t\t<Word>fcompp</Word>\n\t\t\t<Word>fdecstp</Word>\n\t\t\t<Word>fdisi</Word>\n\t\t\t<Word>fdiv</Word>\n\t\t\t<Word>fdivp</Word>\n\t\t\t<Word>fdivr</Word>\n\t\t\t<Word>fdivrp</Word>\n\t\t\t<Word>feni</Word>\n\t\t\t<Word>ffree</Word>\n\t\t\t<Word>fiadd</Word>\n\t\t\t<Word>ficom</Word>\n\t\t\t<Word>ficomp</Word>\n\t\t\t<Word>fidiv</Word>\n\t\t\t<Word>fidivr</Word>\n\t\t\t<Word>fild</Word>\n\t\t\t<Word>fimul</Word>\n\t\t\t<Word>fincstp</Word>\n\t\t\t<Word>finit</Word>\n\t\t\t<Word>fist</Word>\n\t\t\t<Word>fistp</Word>\n\t\t\t<Word>fisub</Word>\n\t\t\t<Word>fisubr</Word>\n\t\t\t<Word>fld</Word>\n\t\t\t<Word>fld1</Word>\n\t\t\t<Word>fldcw</Word>\n\t\t\t<Word>fldenv</Word>\n\t\t\t<Word>fldenvw</Word>\n\t\t\t<Word>fldl2e</Word>\n\t\t\t<Word>fldl2t</Word>\n\t\t\t<Word>fldlg2</Word>\n\t\t\t<Word>fldln2</Word>\n\t\t\t<Word>fldpi</Word>\n\t\t\t<Word>fldz</Word>\n\t\t\t<Word>fmul</Word>\n\t\t\t<Word>fmulp</Word>\n\t\t\t<Word>fnclex</Word>\n\t\t\t<Word>fndisi</Word>\n\t\t\t<Word>fneni</Word>\n\t\t\t<Word>fninit</Word>\n\t\t\t<Word>fnop</Word>\n\t\t\t<Word>fnsave</Word>\n\t\t\t<Word>fnsavew</Word>\n\t\t\t<Word>fnstcw</Word>\n\t\t\t<Word>fnstenv</Word>\n\t\t\t<Word>fnstenvw</Word>\n\t\t\t<Word>fnstsw</Word>\n\t\t\t<Word>fpatan</Word>\n\t\t\t<Word>fprem</Word>\n\t\t\t<Word>fptan</Word>\n\t\t\t<Word>frndint</Word>\n\t\t\t<Word>frstor</Word>\n\t\t\t<Word>frstorw</Word>\n\t\t\t<Word>fsave</Word>\n\t\t\t<Word>fsavew</Word>\n\t\t\t<Word>fscale</Word>\n\t\t\t<Word>fsqrt</Word>\n\t\t\t<Word>fst</Word>\n\t\t\t<Word>fstcw</Word>\n\t\t\t<Word>fstenv</Word>\n\t\t\t<Word>fstenvw</Word>\n\t\t\t<Word>fstp</Word>\n\t\t\t<Word>fstsw</Word>\n\t\t\t<Word>fsub</Word>\n\t\t\t<Word>fsubp</Word>\n\t\t\t<Word>fsubr</Word>\n\t\t\t<Word>fsubrp</Word>\n\t\t\t<Word>ftst</Word>\n\t\t\t<Word>fwait</Word>\n\t\t\t<Word>fxam</Word>\n\t\t\t<Word>fxch</Word>\n\t\t\t<Word>fxtract</Word>\n\t\t\t<Word>fyl2x</Word>\n\t\t\t<Word>fyl2xp1</Word>\n\t\t\t<Word>fsetpm</Word>\n\t\t\t<Word>fcos</Word>\n\t\t\t<Word>fldenvd</Word>\n\t\t\t<Word>fnsaved</Word>\n\t\t\t<Word>fnstenvd</Word>\n\t\t\t<Word>fprem1</Word>\n\t\t\t<Word>frstord</Word>\n\t\t\t<Word>fsaved</Word>\n\t\t\t<Word>fsin</Word>\n\t\t\t<Word>fsincos</Word>\n\t\t\t<Word>fstenvd</Word>\n\t\t\t<Word>fucom</Word>\n\t\t\t<Word>fucomp</Word>\n\t\t\t<Word>fucompp</Word>\n\t\t\t<Word>fcomi</Word>\n\t\t\t<Word>fcomip</Word>\n\t\t\t<Word>ffreep</Word>\n\t\t\t<Word>fcmovb</Word>\n\t\t\t<Word>fcmove</Word>\n\t\t\t<Word>fcmovbe</Word>\n\t\t\t<Word>fcmovu</Word>\n\t\t\t<Word>fcmovnb</Word>\n\t\t\t<Word>fcmovne</Word>\n\t\t\t<Word>fcmovnbe</Word>\n\t\t\t<Word>fcmovnu</Word>\n\t\t</Keywords>\n\t\t<Keywords color=\"Registers\">\n\t\t\t<Word>ah</Word>\n\t\t\t<Word>al</Word>\n\t\t\t<Word>ax</Word>\n\t\t\t<Word>bh</Word>\n\t\t\t<Word>bl</Word>\n\t\t\t<Word>bp</Word>\n\t\t\t<Word>bx</Word>\n\t\t\t<Word>ch</Word>\n\t\t\t<Word>cl</Word>\n\t\t\t<Word>cr0</Word>\n\t\t\t<Word>cr2</Word>\n\t\t\t<Word>cr3</Word>\n\t\t\t<Word>cr4</Word>\n\t\t\t<Word>cs</Word>\n\t\t\t<Word>cx</Word>\n\t\t\t<Word>dh</Word>\n\t\t\t<Word>di</Word>\n\t\t\t<Word>dl</Word>\n\t\t\t<Word>dr0</Word>\n\t\t\t<Word>dr1</Word>\n\t\t\t<Word>dr2</Word>\n\t\t\t<Word>dr3</Word>\n\t\t\t<Word>dr6</Word>\n\t\t\t<Word>dr7</Word>\n\t\t\t<Word>ds</Word>\n\t\t\t<Word>dx</Word>\n\t\t\t<Word>eax</Word>\n\t\t\t<Word>ebp</Word>\n\t\t\t<Word>ebx</Word>\n\t\t\t<Word>ecx</Word>\n\t\t\t<Word>edi</Word>\n\t\t\t<Word>edx</Word>\n\t\t\t<Word>es</Word>\n\t\t\t<Word>esi</Word>\n\t\t\t<Word>esp</Word>\n\t\t\t<Word>fs</Word>\n\t\t\t<Word>gs</Word>\n\t\t\t<Word>rax</Word>\n\t\t\t<Word>rbx</Word>\n\t\t\t<Word>rcx</Word>\n\t\t\t<Word>rdx</Word>\n\t\t\t<Word>rdi</Word>\n\t\t\t<Word>rsi</Word>\n\t\t\t<Word>rbp</Word>\n\t\t\t<Word>rsp</Word>\n\t\t\t<Word>r8</Word>\n\t\t\t<Word>r9</Word>\n\t\t\t<Word>r10</Word>\n\t\t\t<Word>r11</Word>\n\t\t\t<Word>r12</Word>\n\t\t\t<Word>r13</Word>\n\t\t\t<Word>r14</Word>\n\t\t\t<Word>r15</Word>\n\t\t\t<Word>r8d</Word>\n\t\t\t<Word>r9d</Word>\n\t\t\t<Word>r10d</Word>\n\t\t\t<Word>r11d</Word>\n\t\t\t<Word>r12d</Word>\n\t\t\t<Word>r13d</Word>\n\t\t\t<Word>r14d</Word>\n\t\t\t<Word>r15d</Word>\n\t\t\t<Word>r8w</Word>\n\t\t\t<Word>r9w</Word>\n\t\t\t<Word>r10w</Word>\n\t\t\t<Word>r11w</Word>\n\t\t\t<Word>r12w</Word>\n\t\t\t<Word>r13w</Word>\n\t\t\t<Word>r14w</Word>\n\t\t\t<Word>r15w</Word>\n\t\t\t<Word>r8b</Word>\n\t\t\t<Word>r9b</Word>\n\t\t\t<Word>r10b</Word>\n\t\t\t<Word>r11b</Word>\n\t\t\t<Word>r12b</Word>\n\t\t\t<Word>r13b</Word>\n\t\t\t<Word>r14b</Word>\n\t\t\t<Word>r15b</Word>\n\t\t\t<Word>si</Word>\n\t\t\t<Word>sp</Word>\n\t\t\t<Word>ss</Word>\n\t\t\t<Word>st</Word>\n\t\t\t<Word>tr3</Word>\n\t\t\t<Word>tr4</Word>\n\t\t\t<Word>tr5</Word>\n\t\t\t<Word>tr6</Word>\n\t\t\t<Word>tr7</Word>\n\t\t\t<Word>st0</Word>\n\t\t\t<Word>st1</Word>\n\t\t\t<Word>st2</Word>\n\t\t\t<Word>st3</Word>\n\t\t\t<Word>st4</Word>\n\t\t\t<Word>st5</Word>\n\t\t\t<Word>st6</Word>\n\t\t\t<Word>st7</Word>\n\t\t\t<Word>mm0</Word>\n\t\t\t<Word>mm1</Word>\n\t\t\t<Word>mm2</Word>\n\t\t\t<Word>mm3</Word>\n\t\t\t<Word>mm4</Word>\n\t\t\t<Word>mm5</Word>\n\t\t\t<Word>mm6</Word>\n\t\t\t<Word>mm7</Word>\n\t\t\t<Word>xmm0</Word>\n\t\t\t<Word>xmm1</Word>\n\t\t\t<Word>xmm2</Word>\n\t\t\t<Word>xmm3</Word>\n\t\t\t<Word>xmm4</Word>\n\t\t\t<Word>xmm5</Word>\n\t\t\t<Word>xmm6</Word>\n\t\t\t<Word>xmm7</Word>\n\t\t\t<Word>xmm8</Word>\n\t\t\t<Word>xmm9</Word>\n\t\t\t<Word>xmm10</Word>\n\t\t\t<Word>xmm11</Word>\n\t\t\t<Word>xmm12</Word>\n\t\t\t<Word>xmm13</Word>\n\t\t\t<Word>xmm14</Word>\n\t\t\t<Word>xmm15</Word>\n\t\t</Keywords>\n\t\t<Keywords color=\"Directives\">\n\t\t\t<Word>.186</Word>\n\t\t\t<Word>.286</Word>\n\t\t\t<Word>.286c</Word>\n\t\t\t<Word>.286p</Word>\n\t\t\t<Word>.287</Word>\n\t\t\t<Word>.386</Word>\n\t\t\t<Word>.386c</Word>\n\t\t\t<Word>.386p</Word>\n\t\t\t<Word>.387</Word>\n\t\t\t<Word>.486</Word>\n\t\t\t<Word>.486p</Word>\n\t\t\t<Word>.8086</Word>\n\t\t\t<Word>.8087</Word>\n\t\t\t<Word>.alpha</Word>\n\t\t\t<Word>.break</Word>\n\t\t\t<Word>.code</Word>\n\t\t\t<Word>.const</Word>\n\t\t\t<Word>.continue</Word>\n\t\t\t<Word>.cref</Word>\n\t\t\t<Word>.data</Word>\n\t\t\t<Word>.data?</Word>\n\t\t\t<Word>.dosseg</Word>\n\t\t\t<Word>.else</Word>\n\t\t\t<Word>.elseif</Word>\n\t\t\t<Word>.endif</Word>\n\t\t\t<Word>.endw</Word>\n\t\t\t<Word>.err</Word>\n\t\t\t<Word>.err1</Word>\n\t\t\t<Word>.err2</Word>\n\t\t\t<Word>.errb</Word>\n\t\t\t<Word>.errdef</Word>\n\t\t\t<Word>.errdif</Word>\n\t\t\t<Word>.errdifi</Word>\n\t\t\t<Word>.erre</Word>\n\t\t\t<Word>.erridn</Word>\n\t\t\t<Word>.erridni</Word>\n\t\t\t<Word>.errnb</Word>\n\t\t\t<Word>.errndef</Word>\n\t\t\t<Word>.errnz</Word>\n\t\t\t<Word>.exit</Word>\n\t\t\t<Word>.fardata</Word>\n\t\t\t<Word>.fardata?</Word>\n\t\t\t<Word>.if</Word>\n\t\t\t<Word>.lall</Word>\n\t\t\t<Word>.lfcond</Word>\n\t\t\t<Word>.list</Word>\n\t\t\t<Word>.listall</Word>\n\t\t\t<Word>.listif</Word>\n\t\t\t<Word>.listmacro</Word>\n\t\t\t<Word>.listmacroall</Word>\n\t\t\t<Word>.model</Word>\n\t\t\t<Word>.no87</Word>\n\t\t\t<Word>.nocref</Word>\n\t\t\t<Word>.nolist</Word>\n\t\t\t<Word>.nolistif</Word>\n\t\t\t<Word>.nolistmacro</Word>\n\t\t\t<Word>.radix</Word>\n\t\t\t<Word>.repeat</Word>\n\t\t\t<Word>.sall</Word>\n\t\t\t<Word>.seq</Word>\n\t\t\t<Word>.sfcond</Word>\n\t\t\t<Word>.stack</Word>\n\t\t\t<Word>.startup</Word>\n\t\t\t<Word>.tfcond</Word>\n\t\t\t<Word>.type</Word>\n\t\t\t<Word>.until</Word>\n\t\t\t<Word>.untilcxz</Word>\n\t\t\t<Word>.while</Word>\n\t\t\t<Word>.xall</Word>\n\t\t\t<Word>.xcref</Word>\n\t\t\t<Word>.xlist</Word>\n\t\t\t<Word>alias</Word>\n\t\t\t<Word>align</Word>\n\t\t\t<Word>assume</Word>\n\t\t\t<Word>catstr</Word>\n\t\t\t<Word>comm</Word>\n\t\t\t<Word>comment</Word>\n\t\t\t<Word>db</Word>\n\t\t\t<Word>dd</Word>\n\t\t\t<Word>df</Word>\n\t\t\t<Word>dosseg</Word>\n\t\t\t<Word>dq</Word>\n\t\t\t<Word>dt</Word>\n\t\t\t<Word>dup</Word>\n\t\t\t<Word>dw</Word>\n\t\t\t<Word>echo</Word>\n\t\t\t<Word>else</Word>\n\t\t\t<Word>elseif</Word>\n\t\t\t<Word>elseif1</Word>\n\t\t\t<Word>elseif2</Word>\n\t\t\t<Word>elseifb</Word>\n\t\t\t<Word>elseifdef</Word>\n\t\t\t<Word>elseifdif</Word>\n\t\t\t<Word>elseifdifi</Word>\n\t\t\t<Word>elseife</Word>\n\t\t\t<Word>elseifidn</Word>\n\t\t\t<Word>elseifidni</Word>\n\t\t\t<Word>elseifnb</Word>\n\t\t\t<Word>elseifndef</Word>\n\t\t\t<Word>end</Word>\n\t\t\t<Word>endif</Word>\n\t\t\t<Word>endm</Word>\n\t\t\t<Word>endp</Word>\n\t\t\t<Word>ends</Word>\n\t\t\t<Word>eq</Word>\n\t\t\t<Word>equ</Word>\n\t\t\t<Word>even</Word>\n\t\t\t<Word>exitm</Word>\n\t\t\t<Word>extern</Word>\n\t\t\t<Word>externdef</Word>\n\t\t\t<Word>extrn</Word>\n\t\t\t<Word>for</Word>\n\t\t\t<Word>forc</Word>\n\t\t\t<Word>ge</Word>\n\t\t\t<Word>goto</Word>\n\t\t\t<Word>group</Word>\n\t\t\t<Word>gt</Word>\n\t\t\t<Word>high</Word>\n\t\t\t<Word>highword</Word>\n\t\t\t<Word>if</Word>\n\t\t\t<Word>if1</Word>\n\t\t\t<Word>if2</Word>\n\t\t\t<Word>ifb</Word>\n\t\t\t<Word>ifdef</Word>\n\t\t\t<Word>ifdif</Word>\n\t\t\t<Word>ifdifi</Word>\n\t\t\t<Word>ife</Word>\n\t\t\t<Word>ifidn</Word>\n\t\t\t<Word>ifidni</Word>\n\t\t\t<Word>ifnb</Word>\n\t\t\t<Word>ifndef</Word>\n\t\t\t<Word>include</Word>\n\t\t\t<Word>includelib</Word>\n\t\t\t<Word>instr</Word>\n\t\t\t<Word>invoke</Word>\n\t\t\t<Word>irp</Word>\n\t\t\t<Word>irpc</Word>\n\t\t\t<Word>label</Word>\n\t\t\t<Word>le</Word>\n\t\t\t<Word>length</Word>\n\t\t\t<Word>lengthof</Word>\n\t\t\t<Word>local</Word>\n\t\t\t<Word>low</Word>\n\t\t\t<Word>lowword</Word>\n\t\t\t<Word>lroffset</Word>\n\t\t\t<Word>lt</Word>\n\t\t\t<Word>macro</Word>\n\t\t\t<Word>mask</Word>\n\t\t\t<Word>mod</Word>\n\t\t\t<Word>.msfloat</Word>\n\t\t\t<Word>name</Word>\n\t\t\t<Word>ne</Word>\n\t\t\t<Word>offset</Word>\n\t\t\t<Word>opattr</Word>\n\t\t\t<Word>option</Word>\n\t\t\t<Word>org</Word>\n\t\t\t<Word>%out</Word>\n\t\t\t<Word>page</Word>\n\t\t\t<Word>popcontext</Word>\n\t\t\t<Word>proc</Word>\n\t\t\t<Word>proto</Word>\n\t\t\t<Word>ptr</Word>\n\t\t\t<Word>public</Word>\n\t\t\t<Word>purge</Word>\n\t\t\t<Word>pushcontext</Word>\n\t\t\t<Word>record</Word>\n\t\t\t<Word>repeat</Word>\n\t\t\t<Word>rept</Word>\n\t\t\t<Word>seg</Word>\n\t\t\t<Word>segment</Word>\n\t\t\t<Word>short</Word>\n\t\t\t<Word>size</Word>\n\t\t\t<Word>sizeof</Word>\n\t\t\t<Word>sizestr</Word>\n\t\t\t<Word>struc</Word>\n\t\t\t<Word>struct</Word>\n\t\t\t<Word>substr</Word>\n\t\t\t<Word>subtitle</Word>\n\t\t\t<Word>subttl</Word>\n\t\t\t<Word>textequ</Word>\n\t\t\t<Word>this</Word>\n\t\t\t<Word>title</Word>\n\t\t\t<Word>type</Word>\n\t\t\t<Word>typedef</Word>\n\t\t\t<Word>union</Word>\n\t\t\t<Word>while</Word>\n\t\t\t<Word>width</Word>\n\t\t\t<Word>resb</Word>\n\t\t\t<Word>resw</Word>\n\t\t\t<Word>resd</Word>\n\t\t\t<Word>resq</Word>\n\t\t\t<Word>rest</Word>\n\t\t\t<Word>incbin</Word>\n\t\t\t<Word>times</Word>\n\t\t\t<Word>%define</Word>\n\t\t\t<Word>%idefine</Word>\n\t\t\t<Word>%xdefine</Word>\n\t\t\t<Word>%xidefine</Word>\n\t\t\t<Word>%undef</Word>\n\t\t\t<Word>%assign</Word>\n\t\t\t<Word>%iassign</Word>\n\t\t\t<Word>%strlen</Word>\n\t\t\t<Word>%substr</Word>\n\t\t\t<Word>%macro</Word>\n\t\t\t<Word>%imacro</Word>\n\t\t\t<Word>%endmacro</Word>\n\t\t\t<Word>%rotate</Word>\n\t\t\t<Word>%if</Word>\n\t\t\t<Word>%elif</Word>\n\t\t\t<Word>%else</Word>\n\t\t\t<Word>%endif</Word>\n\t\t\t<Word>%ifdef</Word>\n\t\t\t<Word>%ifndef</Word>\n\t\t\t<Word>%elifdef</Word>\n\t\t\t<Word>%elifndef</Word>\n\t\t\t<Word>%ifmacro</Word>\n\t\t\t<Word>%ifnmacro</Word>\n\t\t\t<Word>%elifmacro</Word>\n\t\t\t<Word>%elifnmacro</Word>\n\t\t\t<Word>%ifctk</Word>\n\t\t\t<Word>%ifnctk</Word>\n\t\t\t<Word>%elifctk</Word>\n\t\t\t<Word>%elifnctk</Word>\n\t\t\t<Word>%ifidn</Word>\n\t\t\t<Word>%ifnidn</Word>\n\t\t\t<Word>%elifidn</Word>\n\t\t\t<Word>%elifnidn</Word>\n\t\t\t<Word>%ifidni</Word>\n\t\t\t<Word>%ifnidni</Word>\n\t\t\t<Word>%elifidni</Word>\n\t\t\t<Word>%elifnidni</Word>\n\t\t\t<Word>%ifid</Word>\n\t\t\t<Word>%ifnid</Word>\n\t\t\t<Word>%elifid</Word>\n\t\t\t<Word>%elifnid</Word>\n\t\t\t<Word>%ifstr</Word>\n\t\t\t<Word>%ifnstr</Word>\n\t\t\t<Word>%elifstr</Word>\n\t\t\t<Word>%elifnstr</Word>\n\t\t\t<Word>%ifnum</Word>\n\t\t\t<Word>%ifnnum</Word>\n\t\t\t<Word>%elifnum</Word>\n\t\t\t<Word>%elifnnum</Word>\n\t\t\t<Word>%error</Word>\n\t\t\t<Word>%rep</Word>\n\t\t\t<Word>%endrep</Word>\n\t\t\t<Word>%exitrep</Word>\n\t\t\t<Word>%include</Word>\n\t\t\t<Word>%push</Word>\n\t\t\t<Word>%pop</Word>\n\t\t\t<Word>%repl</Word>\n\t\t\t<Word>endstruc</Word>\n\t\t\t<Word>istruc</Word>\n\t\t\t<Word>at</Word>\n\t\t\t<Word>iend</Word>\n\t\t\t<Word>alignb</Word>\n\t\t\t<Word>%arg</Word>\n\t\t\t<Word>%stacksize</Word>\n\t\t\t<Word>%local</Word>\n\t\t\t<Word>%line</Word>\n\t\t\t<Word>bits</Word>\n\t\t\t<Word>use16</Word>\n\t\t\t<Word>use32</Word>\n\t\t\t<Word>section</Word>\n\t\t\t<Word>absolute</Word>\n\t\t\t<Word>global</Word>\n\t\t\t<Word>common</Word>\n\t\t\t<Word>cpu</Word>\n\t\t\t<Word>import</Word>\n\t\t\t<Word>export</Word>\n\t\t</Keywords>\n\t\t<Keywords color=\"Directive Operands\">\n\t\t\t<Word>$</Word>\n\t\t\t<Word>?</Word>\n\t\t\t<Word>@b</Word>\n\t\t\t<Word>@f</Word>\n\t\t\t<Word>addr</Word>\n\t\t\t<Word>basic</Word>\n\t\t\t<Word>byte</Word>\n\t\t\t<Word>c</Word>\n\t\t\t<Word>carry?</Word>\n\t\t\t<Word>dword</Word>\n\t\t\t<Word>far</Word>\n\t\t\t<Word>far16</Word>\n\t\t\t<Word>fortran</Word>\n\t\t\t<Word>fword</Word>\n\t\t\t<Word>near</Word>\n\t\t\t<Word>near16</Word>\n\t\t\t<Word>overflow?</Word>\n\t\t\t<Word>parity?</Word>\n\t\t\t<Word>pascal</Word>\n\t\t\t<Word>qword</Word>\n\t\t\t<Word>real4</Word>\n\t\t\t<Word>real8</Word>\n\t\t\t<Word>real10</Word>\n\t\t\t<Word>sbyte</Word>\n\t\t\t<Word>sdword</Word>\n\t\t\t<Word>sign?</Word>\n\t\t\t<Word>stdcall</Word>\n\t\t\t<Word>sword</Word>\n\t\t\t<Word>syscall</Word>\n\t\t\t<Word>tbyte</Word>\n\t\t\t<Word>vararg</Word>\n\t\t\t<Word>word</Word>\n\t\t\t<Word>zero?</Word>\n\t\t\t<Word>flat</Word>\n\t\t\t<Word>near32</Word>\n\t\t\t<Word>far32</Word>\n\t\t\t<Word>abs</Word>\n\t\t\t<Word>all</Word>\n\t\t\t<Word>assumes</Word>\n\t\t\t<Word>at</Word>\n\t\t\t<Word>casemap</Word>\n\t\t\t<Word>common</Word>\n\t\t\t<Word>compact</Word>\n\t\t\t<Word>cpu</Word>\n\t\t\t<Word>dotname</Word>\n\t\t\t<Word>emulator</Word>\n\t\t\t<Word>epilogue</Word>\n\t\t\t<Word>error</Word>\n\t\t\t<Word>export</Word>\n\t\t\t<Word>expr16</Word>\n\t\t\t<Word>expr32</Word>\n\t\t\t<Word>farstack</Word>\n\t\t\t<Word>forceframe</Word>\n\t\t\t<Word>huge</Word>\n\t\t\t<Word>language</Word>\n\t\t\t<Word>large</Word>\n\t\t\t<Word>listing</Word>\n\t\t\t<Word>ljmp</Word>\n\t\t\t<Word>loadds</Word>\n\t\t\t<Word>m510</Word>\n\t\t\t<Word>medium</Word>\n\t\t\t<Word>memory</Word>\n\t\t\t<Word>nearstack</Word>\n\t\t\t<Word>nodotname</Word>\n\t\t\t<Word>noemulator</Word>\n\t\t\t<Word>nokeyword</Word>\n\t\t\t<Word>noljmp</Word>\n\t\t\t<Word>nom510</Word>\n\t\t\t<Word>none</Word>\n\t\t\t<Word>nonunique</Word>\n\t\t\t<Word>nooldmacros</Word>\n\t\t\t<Word>nooldstructs</Word>\n\t\t\t<Word>noreadonly</Word>\n\t\t\t<Word>noscoped</Word>\n\t\t\t<Word>nosignextend</Word>\n\t\t\t<Word>nothing</Word>\n\t\t\t<Word>notpublic</Word>\n\t\t\t<Word>oldmacros</Word>\n\t\t\t<Word>oldstructs</Word>\n\t\t\t<Word>os_dos</Word>\n\t\t\t<Word>para</Word>\n\t\t\t<Word>private</Word>\n\t\t\t<Word>prologue</Word>\n\t\t\t<Word>radix</Word>\n\t\t\t<Word>readonly</Word>\n\t\t\t<Word>req</Word>\n\t\t\t<Word>scoped</Word>\n\t\t\t<Word>setif2</Word>\n\t\t\t<Word>smallstack</Word>\n\t\t\t<Word>tiny</Word>\n\t\t\t<Word>use16</Word>\n\t\t\t<Word>use32</Word>\n\t\t\t<Word>uses</Word>\n\t\t\t<Word>a16</Word>\n\t\t\t<Word>a32</Word>\n\t\t\t<Word>o16</Word>\n\t\t\t<Word>o32</Word>\n\t\t\t<Word>nosplit</Word>\n\t\t\t<Word>$$</Word>\n\t\t\t<Word>seq</Word>\n\t\t\t<Word>wrt</Word>\n\t\t\t<Word>small</Word>\n\t\t\t<Word>.text</Word>\n\t\t\t<Word>.data</Word>\n\t\t\t<Word>.bss</Word>\n\t\t\t<Word>%0</Word>\n\t\t\t<Word>%1</Word>\n\t\t\t<Word>%2</Word>\n\t\t\t<Word>%3</Word>\n\t\t\t<Word>%4</Word>\n\t\t\t<Word>%5</Word>\n\t\t\t<Word>%6</Word>\n\t\t\t<Word>%7</Word>\n\t\t\t<Word>%8</Word>\n\t\t\t<Word>%9</Word>\n\t\t</Keywords>\n\t\t<Keywords color=\"Extended Instructions\">\n\t\t\t<Word>addpd</Word>\n\t\t\t<Word>addps</Word>\n\t\t\t<Word>addsd</Word>\n\t\t\t<Word>addss</Word>\n\t\t\t<Word>andpd</Word>\n\t\t\t<Word>andps</Word>\n\t\t\t<Word>andnpd</Word>\n\t\t\t<Word>andnps</Word>\n\t\t\t<Word>cmpeqpd</Word>\n\t\t\t<Word>cmpltpd</Word>\n\t\t\t<Word>cmplepd</Word>\n\t\t\t<Word>cmpunordpd</Word>\n\t\t\t<Word>cmpnepd</Word>\n\t\t\t<Word>cmpnltpd</Word>\n\t\t\t<Word>cmpnlepd</Word>\n\t\t\t<Word>cmpordpd</Word>\n\t\t\t<Word>cmpeqps</Word>\n\t\t\t<Word>cmpltps</Word>\n\t\t\t<Word>cmpleps</Word>\n\t\t\t<Word>cmpunordps</Word>\n\t\t\t<Word>cmpneps</Word>\n\t\t\t<Word>cmpnltps</Word>\n\t\t\t<Word>cmpnleps</Word>\n\t\t\t<Word>cmpordps</Word>\n\t\t\t<Word>cmpeqsd</Word>\n\t\t\t<Word>cmpltsd</Word>\n\t\t\t<Word>cmplesd</Word>\n\t\t\t<Word>cmpunordsd</Word>\n\t\t\t<Word>cmpnesd</Word>\n\t\t\t<Word>cmpnltsd</Word>\n\t\t\t<Word>cmpnlesd</Word>\n\t\t\t<Word>cmpordsd</Word>\n\t\t\t<Word>cmpeqss</Word>\n\t\t\t<Word>cmpltss</Word>\n\t\t\t<Word>cmpless</Word>\n\t\t\t<Word>cmpunordss</Word>\n\t\t\t<Word>cmpness</Word>\n\t\t\t<Word>cmpnltss</Word>\n\t\t\t<Word>cmpnless</Word>\n\t\t\t<Word>cmpordss</Word>\n\t\t\t<Word>comisd</Word>\n\t\t\t<Word>comiss</Word>\n\t\t\t<Word>cvtdq2pd</Word>\n\t\t\t<Word>cvtdq2ps</Word>\n\t\t\t<Word>cvtpd2dq</Word>\n\t\t\t<Word>cvtpd2pi</Word>\n\t\t\t<Word>cvtpd2ps</Word>\n\t\t\t<Word>cvtpi2pd</Word>\n\t\t\t<Word>cvtpi2ps</Word>\n\t\t\t<Word>cvtps2dq</Word>\n\t\t\t<Word>cvtps2pd</Word>\n\t\t\t<Word>cvtps2pi</Word>\n\t\t\t<Word>cvtss2sd</Word>\n\t\t\t<Word>cvtss2si</Word>\n\t\t\t<Word>cvtsd2si</Word>\n\t\t\t<Word>cvtsd2ss</Word>\n\t\t\t<Word>cvtsi2sd</Word>\n\t\t\t<Word>cvtsi2ss</Word>\n\t\t\t<Word>cvttpd2dq</Word>\n\t\t\t<Word>cvttpd2pi</Word>\n\t\t\t<Word>cvttps2dq</Word>\n\t\t\t<Word>cvttps2pi</Word>\n\t\t\t<Word>cvttsd2si</Word>\n\t\t\t<Word>cvttss2si</Word>\n\t\t\t<Word>divpd</Word>\n\t\t\t<Word>divps</Word>\n\t\t\t<Word>divsd</Word>\n\t\t\t<Word>divss</Word>\n\t\t\t<Word>fxrstor</Word>\n\t\t\t<Word>fxsave</Word>\n\t\t\t<Word>ldmxscr</Word>\n\t\t\t<Word>lfence</Word>\n\t\t\t<Word>mfence</Word>\n\t\t\t<Word>maskmovdqu</Word>\n\t\t\t<Word>maskmovdq</Word>\n\t\t\t<Word>maxpd</Word>\n\t\t\t<Word>maxps</Word>\n\t\t\t<Word>paxsd</Word>\n\t\t\t<Word>maxss</Word>\n\t\t\t<Word>minpd</Word>\n\t\t\t<Word>minps</Word>\n\t\t\t<Word>minsd</Word>\n\t\t\t<Word>minss</Word>\n\t\t\t<Word>movapd</Word>\n\t\t\t<Word>movaps</Word>\n\t\t\t<Word>movdq2q</Word>\n\t\t\t<Word>movdqa</Word>\n\t\t\t<Word>movdqu</Word>\n\t\t\t<Word>movhlps</Word>\n\t\t\t<Word>movhpd</Word>\n\t\t\t<Word>movhps</Word>\n\t\t\t<Word>movd</Word>\n\t\t\t<Word>movq</Word>\n\t\t\t<Word>movlhps</Word>\n\t\t\t<Word>movlpd</Word>\n\t\t\t<Word>movlps</Word>\n\t\t\t<Word>movmskpd</Word>\n\t\t\t<Word>movmskps</Word>\n\t\t\t<Word>movntdq</Word>\n\t\t\t<Word>movnti</Word>\n\t\t\t<Word>movntpd</Word>\n\t\t\t<Word>movntps</Word>\n\t\t\t<Word>movntq</Word>\n\t\t\t<Word>movq2dq</Word>\n\t\t\t<Word>movsd</Word>\n\t\t\t<Word>movss</Word>\n\t\t\t<Word>movupd</Word>\n\t\t\t<Word>movups</Word>\n\t\t\t<Word>mulpd</Word>\n\t\t\t<Word>mulps</Word>\n\t\t\t<Word>mulsd</Word>\n\t\t\t<Word>mulss</Word>\n\t\t\t<Word>orpd</Word>\n\t\t\t<Word>orps</Word>\n\t\t\t<Word>packssdw</Word>\n\t\t\t<Word>packsswb</Word>\n\t\t\t<Word>packuswb</Word>\n\t\t\t<Word>paddb</Word>\n\t\t\t<Word>paddsb</Word>\n\t\t\t<Word>paddw</Word>\n\t\t\t<Word>paddsw</Word>\n\t\t\t<Word>paddd</Word>\n\t\t\t<Word>paddsiw</Word>\n\t\t\t<Word>paddq</Word>\n\t\t\t<Word>paddusb</Word>\n\t\t\t<Word>paddusw</Word>\n\t\t\t<Word>pand</Word>\n\t\t\t<Word>pandn</Word>\n\t\t\t<Word>pause</Word>\n\t\t\t<Word>paveb</Word>\n\t\t\t<Word>pavgb</Word>\n\t\t\t<Word>pavgw</Word>\n\t\t\t<Word>pavgusb</Word>\n\t\t\t<Word>pdistib</Word>\n\t\t\t<Word>pextrw</Word>\n\t\t\t<Word>pcmpeqb</Word>\n\t\t\t<Word>pcmpeqw</Word>\n\t\t\t<Word>pcmpeqd</Word>\n\t\t\t<Word>pcmpgtb</Word>\n\t\t\t<Word>pcmpgtw</Word>\n\t\t\t<Word>pcmpgtd</Word>\n\t\t\t<Word>pf2id</Word>\n\t\t\t<Word>pf2iw</Word>\n\t\t\t<Word>pfacc</Word>\n\t\t\t<Word>pfadd</Word>\n\t\t\t<Word>pfcmpeq</Word>\n\t\t\t<Word>pfcmpge</Word>\n\t\t\t<Word>pfcmpgt</Word>\n\t\t\t<Word>pfmax</Word>\n\t\t\t<Word>pfmin</Word>\n\t\t\t<Word>pfmul</Word>\n\t\t\t<Word>pmachriw</Word>\n\t\t\t<Word>pmaddwd</Word>\n\t\t\t<Word>pmagw</Word>\n\t\t\t<Word>pmaxsw</Word>\n\t\t\t<Word>pmaxub</Word>\n\t\t\t<Word>pminsw</Word>\n\t\t\t<Word>pminub</Word>\n\t\t\t<Word>pmovmskb</Word>\n\t\t\t<Word>pmulhrwc</Word>\n\t\t\t<Word>pmulhriw</Word>\n\t\t\t<Word>pmulhrwa</Word>\n\t\t\t<Word>pmulhuw</Word>\n\t\t\t<Word>pmulhw</Word>\n\t\t\t<Word>pmullw</Word>\n\t\t\t<Word>pmuludq</Word>\n\t\t\t<Word>pmvzb</Word>\n\t\t\t<Word>pmvnzb</Word>\n\t\t\t<Word>pmvlzb</Word>\n\t\t\t<Word>pmvgezb</Word>\n\t\t\t<Word>pfnacc</Word>\n\t\t\t<Word>pfpnacc</Word>\n\t\t\t<Word>por</Word>\n\t\t\t<Word>prefetch</Word>\n\t\t\t<Word>prefetchw</Word>\n\t\t\t<Word>prefetchnta</Word>\n\t\t\t<Word>prefetcht0</Word>\n\t\t\t<Word>prefetcht1</Word>\n\t\t\t<Word>prefetcht2</Word>\n\t\t\t<Word>pfrcp</Word>\n\t\t\t<Word>pfrcpit1</Word>\n\t\t\t<Word>pfrcpit2</Word>\n\t\t\t<Word>pfrsqit1</Word>\n\t\t\t<Word>pfrsqrt</Word>\n\t\t\t<Word>pfsub</Word>\n\t\t\t<Word>pfsubr</Word>\n\t\t\t<Word>pi2fd</Word>\n\t\t\t<Word>pinsrw</Word>\n\t\t\t<Word>psadbw</Word>\n\t\t\t<Word>pshufd</Word>\n\t\t\t<Word>pshufhw</Word>\n\t\t\t<Word>pshuflw</Word>\n\t\t\t<Word>pshufw</Word>\n\t\t\t<Word>psllw</Word>\n\t\t\t<Word>pslld</Word>\n\t\t\t<Word>psllq</Word>\n\t\t\t<Word>pslldq</Word>\n\t\t\t<Word>psraw</Word>\n\t\t\t<Word>psrad</Word>\n\t\t\t<Word>psrlw</Word>\n\t\t\t<Word>psrld</Word>\n\t\t\t<Word>psrlq</Word>\n\t\t\t<Word>psrldq</Word>\n\t\t\t<Word>psubb</Word>\n\t\t\t<Word>psubw</Word>\n\t\t\t<Word>psubd</Word>\n\t\t\t<Word>psubq</Word>\n\t\t\t<Word>psubsb</Word>\n\t\t\t<Word>psubsw</Word>\n\t\t\t<Word>psubusb</Word>\n\t\t\t<Word>psubusw</Word>\n\t\t\t<Word>psubsiw</Word>\n\t\t\t<Word>pswapd</Word>\n\t\t\t<Word>punpckhbw</Word>\n\t\t\t<Word>punpckhwd</Word>\n\t\t\t<Word>punpckhdq</Word>\n\t\t\t<Word>punpckhqdq</Word>\n\t\t\t<Word>punpcklbw</Word>\n\t\t\t<Word>punpcklwd</Word>\n\t\t\t<Word>punpckldq</Word>\n\t\t\t<Word>punpcklqdq</Word>\n\t\t\t<Word>pxor</Word>\n\t\t\t<Word>rcpps</Word>\n\t\t\t<Word>rcpss</Word>\n\t\t\t<Word>rsqrtps</Word>\n\t\t\t<Word>rsqrtss</Word>\n\t\t\t<Word>sfence</Word>\n\t\t\t<Word>shufpd</Word>\n\t\t\t<Word>shufps</Word>\n\t\t\t<Word>sqrtpd</Word>\n\t\t\t<Word>sqrtps</Word>\n\t\t\t<Word>sqrtsd</Word>\n\t\t\t<Word>sqrtss</Word>\n\t\t\t<Word>stmxcsr</Word>\n\t\t\t<Word>subpd</Word>\n\t\t\t<Word>subps</Word>\n\t\t\t<Word>subsd</Word>\n\t\t\t<Word>subss</Word>\n\t\t\t<Word>ucomisd</Word>\n\t\t\t<Word>ucomiss</Word>\n\t\t\t<Word>unpckhpd</Word>\n\t\t\t<Word>unpckhps</Word>\n\t\t\t<Word>unpcklpd</Word>\n\t\t\t<Word>unpcklps</Word>\n\t\t\t<Word>xorpd</Word>\n\t\t\t<Word>xorps</Word>\n\t\t</Keywords>\n\t\t<Span color=\"Comment\" ruleSet=\"CommentMarkerSet\">\n\t\t\t<Begin>;</Begin>\n\t\t</Span>\n\t\t<Rule color=\"Address and Bytes\">\n\t\t\t^ \\s* [0-9A-F]+ \\s+ [0-9A-F]+\n\t\t</Rule>\n\t\t<Rule color=\"NumberLiteral\">\n\t\t\t\\b(0[xXhH])?[0-9a-fA-F_`]+[h]?  # hex number\n\t\t\t|\n\t\t\t(\t\\b\\d+(\\.[0-9]+)?   #number with optional floating point\n\t\t\t|\t\\.[0-9]+           #or just starting with floating point\n\t\t\t)\n\t\t\t([eE][+-]?[0-9]+)? # optional exponent\n\t\t</Rule>\n\t</RuleSet>\n\t<RuleSet name=\"CommentMarkerSet\" ignoreCase=\"false\">\n\t\t<Keywords foreground=\"#FFFF0000\" fontWeight=\"bold\">\n\t\t\t<Word>TODO</Word>\n\t\t\t<Word>FIXME</Word>\n\t\t</Keywords>\n\t\t<Keywords foreground=\"#EEE0E000\" fontWeight=\"bold\">\n\t\t\t<Word>HACK</Word>\n\t\t\t<Word>UNDONE</Word>\n\t\t</Keywords>\n\t</RuleSet>\n</SyntaxDefinition>"
  },
  {
    "path": "ILSpy/TextView/AvalonEditTextOutput.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Text;\nusing System.Windows;\n\nusing ICSharpCode.AvalonEdit.Document;\nusing ICSharpCode.AvalonEdit.Folding;\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.AvalonEdit.Rendering;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nusing TextLocation = ICSharpCode.Decompiler.CSharp.Syntax.TextLocation;\n\nnamespace ICSharpCode.ILSpy.TextView\n{\n\t/// <summary>\n\t/// A text segment that references some object. Used for hyperlinks in the editor.\n\t/// </summary>\n\tpublic sealed class ReferenceSegment : TextSegment\n\t{\n\t\tpublic object Reference;\n\t\tpublic bool IsLocal;\n\t\tpublic bool IsDefinition;\n\t}\n\n\t/// <summary>\n\t/// Stores the positions of the definitions that were written to the text output.\n\t/// </summary>\n\tsealed class DefinitionLookup\n\t{\n\t\tinternal Dictionary<object, int> definitions = new Dictionary<object, int>();\n\n\t\tpublic int GetDefinitionPosition(object definition)\n\t\t{\n\t\t\tint val;\n\t\t\tif (definitions.TryGetValue(definition, out val))\n\t\t\t\treturn val;\n\t\t\telse\n\t\t\t\treturn -1;\n\t\t}\n\n\t\tpublic void AddDefinition(object definition, int offset)\n\t\t{\n\t\t\tdefinitions[definition] = offset;\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Text output implementation for AvalonEdit.\n\t/// </summary>\n\tpublic sealed class AvalonEditTextOutput : ISmartTextOutput\n\t{\n\t\tint lastLineStart = 0;\n\t\tint lineNumber = 1;\n\t\treadonly StringBuilder b = new StringBuilder();\n\n\t\t/// <summary>Current indentation level</summary>\n\t\tint indent;\n\t\t/// <summary>Whether indentation should be inserted on the next write</summary>\n\t\tbool needsIndent;\n\n\t\tpublic string IndentationString { get; set; } = \"\\t\";\n\n\t\tinternal bool IgnoreNewLineAndIndent { get; set; }\n\n\t\tpublic string Title { get; set; } = Properties.Resources.NewTab;\n\n\t\t/// <summary>\n\t\t/// Gets/sets the <see cref=\"Uri\"/> that is displayed by this view.\n\t\t/// Used to identify the AboutPage and other views built into ILSpy in the navigation history.\n\t\t/// </summary>\n\t\tpublic Uri Address { get; set; }\n\n\t\tinternal readonly List<VisualLineElementGenerator> elementGenerators = new List<VisualLineElementGenerator>();\n\n\t\t/// <summary>List of all references that were written to the output</summary>\n\t\tTextSegmentCollection<ReferenceSegment> references = new TextSegmentCollection<ReferenceSegment>();\n\n\t\t/// <summary>Stack of the fold markers that are open but not closed yet</summary>\n\t\tStack<(NewFolding, int startLine)> openFoldings = new Stack<(NewFolding, int startLine)>();\n\n\t\t/// <summary>List of all foldings that were written to the output</summary>\n\t\tinternal readonly List<NewFolding> Foldings = new List<NewFolding>();\n\n\t\tinternal readonly DefinitionLookup DefinitionLookup = new DefinitionLookup();\n\n\t\tinternal bool EnableHyperlinks { get; set; }\n\n\t\t/// <summary>Embedded UIElements, see <see cref=\"UIElementGenerator\"/>.</summary>\n\t\tinternal readonly List<KeyValuePair<int, Lazy<UIElement>>> UIElements = new List<KeyValuePair<int, Lazy<UIElement>>>();\n\n\t\tpublic RichTextModel HighlightingModel { get; } = new RichTextModel();\n\n\t\tpublic AvalonEditTextOutput()\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the list of references (hyperlinks).\n\t\t/// </summary>\n\t\tinternal TextSegmentCollection<ReferenceSegment> References {\n\t\t\tget { return references; }\n\t\t}\n\n\t\tpublic void AddVisualLineElementGenerator(VisualLineElementGenerator elementGenerator)\n\t\t{\n\t\t\telementGenerators.Add(elementGenerator);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Controls the maximum length of the text.\n\t\t/// When this length is exceeded, an <see cref=\"OutputLengthExceededException\"/> will be thrown,\n\t\t/// thus aborting the decompilation.\n\t\t/// </summary>\n\t\tpublic int LengthLimit = int.MaxValue;\n\n\t\tpublic int TextLength {\n\t\t\tget { return b.Length; }\n\t\t}\n\n\t\tpublic TextLocation Location {\n\t\t\tget {\n\t\t\t\treturn new TextLocation(lineNumber, b.Length - lastLineStart + 1 + (needsIndent ? indent : 0));\n\t\t\t}\n\t\t}\n\n\t\t#region Text Document\n\t\tTextDocument textDocument;\n\n\t\t/// <summary>\n\t\t/// Prepares the TextDocument.\n\t\t/// This method may be called by the background thread writing to the output.\n\t\t/// Once the document is prepared, it can no longer be written to.\n\t\t/// </summary>\n\t\t/// <remarks>\n\t\t/// Calling this method on the background thread ensures the TextDocument's line tokenization\n\t\t/// runs in the background and does not block the GUI.\n\t\t/// </remarks>\n\t\tpublic void PrepareDocument()\n\t\t{\n\t\t\tif (textDocument == null)\n\t\t\t{\n\t\t\t\ttextDocument = new TextDocument(b.ToString());\n\t\t\t\ttextDocument.SetOwnerThread(null); // release ownership\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Retrieves the TextDocument.\n\t\t/// Once the document is retrieved, it can no longer be written to.\n\t\t/// </summary>\n\t\tpublic TextDocument GetDocument()\n\t\t{\n\t\t\tPrepareDocument();\n\t\t\ttextDocument.SetOwnerThread(System.Threading.Thread.CurrentThread); // acquire ownership\n\t\t\treturn textDocument;\n\t\t}\n\t\t#endregion\n\n\t\tpublic void Indent()\n\t\t{\n\t\t\tif (IgnoreNewLineAndIndent)\n\t\t\t\treturn;\n\t\t\tindent++;\n\t\t}\n\n\t\tpublic void Unindent()\n\t\t{\n\t\t\tif (IgnoreNewLineAndIndent)\n\t\t\t\treturn;\n\t\t\tindent--;\n\t\t}\n\n\t\tvoid WriteIndent()\n\t\t{\n\t\t\tif (IgnoreNewLineAndIndent)\n\t\t\t\treturn;\n\t\t\tDebug.Assert(textDocument == null);\n\t\t\tif (needsIndent)\n\t\t\t{\n\t\t\t\tneedsIndent = false;\n\t\t\t\tfor (int i = 0; i < indent; i++)\n\t\t\t\t{\n\t\t\t\t\tb.Append(IndentationString);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic void Write(char ch)\n\t\t{\n\t\t\tWriteIndent();\n\t\t\tb.Append(ch);\n\t\t}\n\n\t\tpublic void Write(string text)\n\t\t{\n\t\t\tWriteIndent();\n\t\t\tb.Append(text);\n\t\t}\n\n\t\tpublic void WriteLine()\n\t\t{\n\t\t\tDebug.Assert(textDocument == null);\n\t\t\tif (IgnoreNewLineAndIndent)\n\t\t\t{\n\t\t\t\tb.Append(' ');\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tb.AppendLine();\n\t\t\t\tneedsIndent = true;\n\t\t\t\tlastLineStart = b.Length;\n\t\t\t\tlineNumber++;\n\t\t\t}\n\t\t\tif (this.TextLength > LengthLimit)\n\t\t\t{\n\t\t\t\tthrow new OutputLengthExceededException();\n\t\t\t}\n\t\t}\n\n\t\tpublic void WriteReference(Decompiler.Disassembler.OpCodeInfo opCode, bool omitSuffix = false)\n\t\t{\n\t\t\tWriteIndent();\n\t\t\tint start = this.TextLength;\n\t\t\tif (omitSuffix)\n\t\t\t{\n\t\t\t\tint lastDot = opCode.Name.LastIndexOf('.');\n\t\t\t\tif (lastDot > 0)\n\t\t\t\t{\n\t\t\t\t\tb.Append(opCode.Name.Remove(lastDot + 1));\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tb.Append(opCode.Name);\n\t\t\t}\n\t\t\tint end = this.TextLength - 1;\n\t\t\treferences.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = opCode });\n\t\t}\n\n\t\tpublic void WriteReference(MetadataFile metadata, Handle handle, string text, string protocol = \"decompile\", bool isDefinition = false)\n\t\t{\n\t\t\tWriteIndent();\n\t\t\tint start = this.TextLength;\n\t\t\tb.Append(text);\n\t\t\tint end = this.TextLength;\n\t\t\tif (isDefinition)\n\t\t\t{\n\t\t\t\tthis.DefinitionLookup.AddDefinition((metadata, handle), this.TextLength);\n\t\t\t}\n\t\t\treferences.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = new EntityReference(metadata, handle, protocol), IsDefinition = isDefinition });\n\t\t}\n\n\t\tpublic void WriteReference(IType type, string text, bool isDefinition = false)\n\t\t{\n\t\t\tWriteIndent();\n\t\t\tint start = this.TextLength;\n\t\t\tb.Append(text);\n\t\t\tint end = this.TextLength;\n\t\t\tif (isDefinition)\n\t\t\t{\n\t\t\t\tthis.DefinitionLookup.AddDefinition(type, this.TextLength);\n\t\t\t}\n\t\t\treferences.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = type, IsDefinition = isDefinition });\n\t\t}\n\n\t\tpublic void WriteReference(IMember member, string text, bool isDefinition = false)\n\t\t{\n\t\t\tWriteIndent();\n\t\t\tint start = this.TextLength;\n\t\t\tb.Append(text);\n\t\t\tint end = this.TextLength;\n\t\t\tif (isDefinition)\n\t\t\t{\n\t\t\t\tthis.DefinitionLookup.AddDefinition(member, this.TextLength);\n\t\t\t}\n\t\t\treferences.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = member, IsDefinition = isDefinition });\n\t\t}\n\n\t\tpublic void WriteLocalReference(string text, object reference, bool isDefinition = false)\n\t\t{\n\t\t\tWriteIndent();\n\t\t\tint start = this.TextLength;\n\t\t\tb.Append(text);\n\t\t\tint end = this.TextLength;\n\t\t\tif (isDefinition)\n\t\t\t{\n\t\t\t\tthis.DefinitionLookup.AddDefinition(reference, this.TextLength);\n\t\t\t}\n\t\t\treferences.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = reference, IsLocal = true, IsDefinition = isDefinition });\n\t\t}\n\n\t\tinternal object InitialHighlightReference = null;\n\n\t\tpublic void SetInitialHighlight(object reference)\n\t\t{\n\t\t\tthis.InitialHighlightReference = reference;\n\t\t}\n\n\t\tpublic void MarkFoldStart(string collapsedText = \"...\", bool defaultCollapsed = false, bool isDefinition = false)\n\t\t{\n\t\t\tWriteIndent();\n\t\t\topenFoldings.Push((\n\t\t\t\tnew NewFolding {\n\t\t\t\t\tStartOffset = this.TextLength,\n\t\t\t\t\tName = collapsedText,\n\t\t\t\t\tDefaultClosed = defaultCollapsed,\n\t\t\t\t\tIsDefinition = isDefinition,\n\t\t\t\t}, lineNumber));\n\t\t}\n\n\t\tpublic void MarkFoldEnd()\n\t\t{\n\t\t\tvar (f, startLine) = openFoldings.Pop();\n\t\t\tf.EndOffset = this.TextLength;\n\t\t\tif (startLine != lineNumber)\n\t\t\t\tthis.Foldings.Add(f);\n\t\t}\n\n\t\tpublic void AddUIElement(Func<UIElement> element)\n\t\t{\n\t\t\tif (element != null)\n\t\t\t{\n\t\t\t\tif (this.UIElements.Count > 0 && this.UIElements.Last().Key == this.TextLength)\n\t\t\t\t\tthrow new InvalidOperationException(\"Only one UIElement is allowed for each position in the document\");\n\t\t\t\tthis.UIElements.Add(new KeyValuePair<int, Lazy<UIElement>>(this.TextLength, new Lazy<UIElement>(element)));\n\t\t\t}\n\t\t}\n\n\t\treadonly Stack<HighlightingColor> colorStack = new Stack<HighlightingColor>();\n\t\tHighlightingColor currentColor = new HighlightingColor();\n\t\tint currentColorBegin = -1;\n\n\t\tpublic void BeginSpan(HighlightingColor highlightingColor)\n\t\t{\n\t\t\tWriteIndent();\n\t\t\tif (currentColorBegin > -1)\n\t\t\t\tHighlightingModel.SetHighlighting(currentColorBegin, b.Length - currentColorBegin, currentColor);\n\t\t\tcolorStack.Push(currentColor);\n\t\t\tcurrentColor = currentColor.Clone();\n\t\t\tcurrentColorBegin = b.Length;\n\t\t\tcurrentColor.MergeWith(highlightingColor);\n\t\t\tcurrentColor.Freeze();\n\t\t}\n\n\t\tpublic void EndSpan()\n\t\t{\n\t\t\tHighlightingModel.SetHighlighting(currentColorBegin, b.Length - currentColorBegin, currentColor);\n\t\t\tcurrentColor = colorStack.Pop();\n\t\t\tcurrentColorBegin = b.Length;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TextView/BracketHighlightRenderer.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Windows.Media;\n\nusing ICSharpCode.AvalonEdit.Document;\nusing ICSharpCode.AvalonEdit.Rendering;\n\nnamespace ICSharpCode.ILSpy.TextView\n{\n\t/// <summary>\n\t/// Allows language specific search for matching brackets.\n\t/// </summary>\n\tpublic interface IBracketSearcher\n\t{\n\t\t/// <summary>\n\t\t/// Searches for a matching bracket from the given offset to the start of the document.\n\t\t/// </summary>\n\t\t/// <returns>A BracketSearchResult that contains the positions and lengths of the brackets. Return null if there is nothing to highlight.</returns>\n\t\tBracketSearchResult SearchBracket(IDocument document, int offset);\n\t}\n\n\tpublic class DefaultBracketSearcher : IBracketSearcher\n\t{\n\t\tpublic static readonly DefaultBracketSearcher DefaultInstance = new DefaultBracketSearcher();\n\n\t\tpublic BracketSearchResult SearchBracket(IDocument document, int offset)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Describes a pair of matching brackets found by <see cref=\"IBracketSearcher\"/>.\n\t/// </summary>\n\tpublic class BracketSearchResult\n\t{\n\t\tpublic int OpeningBracketOffset { get; private set; }\n\n\t\tpublic int OpeningBracketLength { get; private set; }\n\n\t\tpublic int ClosingBracketOffset { get; private set; }\n\n\t\tpublic int ClosingBracketLength { get; private set; }\n\n\t\tpublic BracketSearchResult(int openingBracketOffset, int openingBracketLength,\n\t\t\t\t\t\t\t\t   int closingBracketOffset, int closingBracketLength)\n\t\t{\n\t\t\tthis.OpeningBracketOffset = openingBracketOffset;\n\t\t\tthis.OpeningBracketLength = openingBracketLength;\n\t\t\tthis.ClosingBracketOffset = closingBracketOffset;\n\t\t\tthis.ClosingBracketLength = closingBracketLength;\n\t\t}\n\t}\n\n\tpublic class BracketHighlightRenderer : IBackgroundRenderer\n\t{\n\t\tBracketSearchResult result;\n\t\tPen borderPen;\n\t\tBrush backgroundBrush;\n\t\tICSharpCode.AvalonEdit.Rendering.TextView textView;\n\n\t\tpublic void SetHighlight(BracketSearchResult result)\n\t\t{\n\t\t\tif (this.result != result)\n\t\t\t{\n\t\t\t\tthis.result = result;\n\t\t\t\tthis.borderPen = (Pen)textView.FindResource(Themes.ResourceKeys.BracketHighlightBorderPen);\n\t\t\t\tthis.backgroundBrush = (SolidColorBrush)textView.FindResource(Themes.ResourceKeys.BracketHighlightBackgroundBrush);\n\t\t\t\ttextView.InvalidateLayer(this.Layer);\n\t\t\t}\n\t\t}\n\n\t\tpublic BracketHighlightRenderer(ICSharpCode.AvalonEdit.Rendering.TextView textView)\n\t\t{\n\t\t\tif (textView == null)\n\t\t\t\tthrow new ArgumentNullException(\"textView\");\n\n\t\t\tthis.borderPen = (Pen)textView.FindResource(Themes.ResourceKeys.BracketHighlightBorderPen);\n\t\t\tthis.backgroundBrush = (SolidColorBrush)textView.FindResource(Themes.ResourceKeys.BracketHighlightBackgroundBrush);\n\n\t\t\tthis.textView = textView;\n\n\t\t\tthis.textView.BackgroundRenderers.Add(this);\n\t\t}\n\n\t\tpublic KnownLayer Layer {\n\t\t\tget {\n\t\t\t\treturn KnownLayer.Selection;\n\t\t\t}\n\t\t}\n\n\t\tpublic void Draw(ICSharpCode.AvalonEdit.Rendering.TextView textView, DrawingContext drawingContext)\n\t\t{\n\t\t\tif (this.result == null)\n\t\t\t\treturn;\n\n\t\t\tBackgroundGeometryBuilder builder = new BackgroundGeometryBuilder();\n\n\t\t\tbuilder.CornerRadius = 1;\n\t\t\tbuilder.AlignToWholePixels = true;\n\t\t\tbuilder.BorderThickness = borderPen?.Thickness ?? 0;\n\n\t\t\tbuilder.AddSegment(textView, new TextSegment() { StartOffset = result.OpeningBracketOffset, Length = result.OpeningBracketLength });\n\t\t\tbuilder.CloseFigure(); // prevent connecting the two segments\n\t\t\tbuilder.AddSegment(textView, new TextSegment() { StartOffset = result.ClosingBracketOffset, Length = result.ClosingBracketLength });\n\n\t\t\tGeometry geometry = builder.CreateGeometry();\n\t\t\tif (geometry != null)\n\t\t\t{\n\t\t\t\tdrawingContext.DrawGeometry(backgroundBrush, borderPen, geometry);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/TextView/CSharp-Mode.xshd",
    "content": "<?xml version=\"1.0\"?>\n<SyntaxDefinition name=\"C#\" extensions=\".cs\" xmlns=\"http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008\">\n\t<!-- This is a variant of the AvalonEdit C# highlighting that has several constructs disabled.\n\t     The disabled constructs (e.g. contextual keywords) are highlighted using the CSharpLanguage.HighlightingTokenWriter instead.\n\t-->\n\t\n\t<!-- The named colors 'Comment' and 'String' are used in SharpDevelop to detect if a line is inside a multiline string/comment -->\n\t<Color name=\"Comment\" foreground=\"Green\" exampleText=\"// comment\" />\n\t<Color name=\"String\" foreground=\"Blue\" exampleText=\"string text = &quot;Hello, World!&quot;\"/>\n\t<Color name=\"StringInterpolation\" foreground=\"Black\" exampleText=\"string text = $&quot;Hello, {name}!&quot;\"/>\n\t<Color name=\"Char\" foreground=\"Magenta\" exampleText=\"char linefeed = '\\n';\"/>\n\t<Color name=\"Preprocessor\" foreground=\"Green\" exampleText=\"#region Title\" />\n\t<Color name=\"Punctuation\" exampleText=\"a(b.c);\" />\n\t<Color name=\"ValueTypeKeywords\" fontWeight=\"bold\" foreground=\"Red\" exampleText=\"bool b = true;\" />\n\t<Color name=\"ReferenceTypeKeywords\" foreground=\"Red\" exampleText=\"object o;\" />\n\t<Color name=\"NumberLiteral\" foreground=\"DarkBlue\" exampleText=\"3.1415f\"/>\n\t<Color name=\"ThisOrBaseReference\" fontWeight=\"bold\" exampleText=\"this.Do(); base.Do();\"/>\n\t<Color name=\"NullOrValueKeywords\" fontWeight=\"bold\" exampleText=\"if (value == null)\"/>\n\t<Color name=\"Keywords\" fontWeight=\"bold\" foreground=\"Blue\" exampleText=\"if (a) {} else {}\"/>\n\t<Color name=\"GotoKeywords\" foreground=\"Navy\" exampleText=\"continue; return null;\"/>\n\t<Color name=\"QueryKeywords\" foreground=\"Navy\" exampleText=\"from x in y select z;\"/>\n\t<Color name=\"ExceptionKeywords\" fontWeight=\"bold\" foreground=\"Teal\" exampleText=\"try {} catch {} finally {}\"/>\n\t<Color name=\"CheckedKeyword\" fontWeight=\"bold\" foreground=\"DarkGray\" exampleText=\"checked {}\"/>\n\t<Color name=\"UnsafeKeywords\" foreground=\"Olive\" exampleText=\"unsafe { fixed (..) {} }\"/>\n\t<Color name=\"OperatorKeywords\" fontWeight=\"bold\" foreground=\"Pink\" exampleText=\"public static implicit operator...\"/>\n\t<Color name=\"ParameterModifiers\" fontWeight=\"bold\" foreground=\"DeepPink\" exampleText=\"(ref int a, params int[] b)\"/>\n\t<Color name=\"Modifiers\" foreground=\"Brown\" exampleText=\"static readonly int a;\"/>\n\t<Color name=\"Visibility\" fontWeight=\"bold\" foreground=\"Blue\" exampleText=\"public override void ToString();\"/>\n\t<Color name=\"NamespaceKeywords\" fontWeight=\"bold\" foreground=\"Green\" exampleText=\"namespace A.B { using System; }\"/>\n\t<Color name=\"GetSetAddRemove\" foreground=\"SaddleBrown\" exampleText=\"int Prop { get; set; }\"/>\n\t<Color name=\"TrueFalse\" fontWeight=\"bold\" foreground=\"DarkCyan\" exampleText=\"b = false; a = true;\" />\n\t<Color name=\"TypeKeywords\" fontWeight=\"bold\" foreground=\"DarkCyan\" exampleText=\"if (x is int) { a = x as int; type = typeof(int); size = sizeof(int); c = new object(); }\"/>\n\t<Color name=\"AttributeKeywords\" foreground=\"Navy\" exampleText=\"[assembly: AssemblyVersion(&quot;1.0.0.*&quot;)]\" />\n\t\n\t<!-- Colors used for semantic highlighting -->\n\t<Color name=\"ReferenceTypes\" foreground=\"#004085\" exampleText=\"System.#{#Uri#}# uri;\"/>\n\t<Color name=\"InterfaceTypes\" foreground=\"#004085\" exampleText=\"System.#{#IDisposable#}# obj;\"/>\n\t<Color name=\"TypeParameters\" foreground=\"#004085\" exampleText=\"class MyList&lt;#{#T#}#&gt; { }\"/>\n\t<Color name=\"DelegateTypes\" foreground=\"#004085\" exampleText=\"System.#{#Action#}#; action;\"/>\n\t<Color name=\"ValueTypes\" fontWeight=\"bold\" foreground=\"#004085\" exampleText=\"System.#{#DateTime#}# date;\"/>\n\t<Color name=\"EnumTypes\" fontWeight=\"bold\" foreground=\"#004085\" exampleText=\"System.#{#ConsoleKey#}# key;\"/>\n\n\t<Color name=\"MethodDeclaration\" exampleText=\"override string #{#ToString#}#() { }\"/>\n\t<Color name=\"MethodCall\" foreground=\"MidnightBlue\" fontWeight=\"bold\" exampleText=\"o.#{#ToString#}#();\"/>\n\t<Color name=\"FieldDeclaration\" exampleText=\"private int #{#name#}#;\"/>\n\t<Color name=\"FieldAccess\" fontStyle=\"italic\" exampleText=\"return this.#{#name#}#;\"/>\n\t<Color name=\"PropertyDeclaration\" exampleText=\"private int #{#name#}# { get; set; }\"/>\n\t<Color name=\"PropertyAccess\" exampleText=\"return this.#{#name#}#;\"/>\n\t<Color name=\"EventDeclaration\" exampleText=\"private event Action #{#name#}#;\"/>\n\t<Color name=\"EventAccess\" exampleText=\"this.#{#name#}#?.Invoke();\"/>\n\t<Color name=\"Variable\" exampleText=\"var #{#name#}# = 42;\"/>\n\t<Color name=\"Parameter\" exampleText=\"void Method(string #{#name#}#) { }\"/>\n\n\t<Color name=\"InactiveCode\" foreground=\"Gray\" exampleText=\"#{#Deactivated by #if#}#\"/>\n\t<Color name=\"SemanticError\" foreground=\"DarkRed\" exampleText=\"o.#{#MissingMethod#}#()\"/>\n\t\n\t<Property name=\"DocCommentMarker\" value=\"///\" />\n\t\n\t<RuleSet name=\"CommentMarkerSet\">\n\t\t<Keywords fontWeight=\"bold\" foreground=\"Red\">\n\t\t\t<Word>TODO</Word>\n\t\t\t<Word>FIXME</Word>\n\t\t</Keywords>\n\t\t<Keywords fontWeight=\"bold\" foreground=\"#E0E000\">\n\t\t\t<Word>HACK</Word>\n\t\t\t<Word>UNDONE</Word>\n\t\t</Keywords>\n\t</RuleSet>\n\t\n\t<!-- This is the main ruleset. -->\n\t<RuleSet>\n\t\t<Span color=\"Preprocessor\">\n\t\t\t<Begin>\\#</Begin>\n\t\t\t<RuleSet name=\"PreprocessorSet\">\n\t\t\t\t<Span> <!-- preprocessor directives that allow comments -->\n\t\t\t\t\t<Begin fontWeight=\"bold\">\n\t\t\t\t\t\t(define|undef|if|elif|else|endif|line)\\b\n\t\t\t\t\t</Begin>\n\t\t\t\t\t<RuleSet>\n\t\t\t\t\t\t<Span color=\"Comment\" ruleSet=\"CommentMarkerSet\">\n\t\t\t\t\t\t\t<Begin>//</Begin>\n\t\t\t\t\t\t</Span>\n\t\t\t\t\t</RuleSet>\n\t\t\t\t</Span>\n\t\t\t\t<Span> <!-- preprocessor directives that don't allow comments -->\n\t\t\t\t\t<Begin fontWeight=\"bold\">\n\t\t\t\t\t\t(region|endregion|error|warning|pragma)\\b\n\t\t\t\t\t</Begin>\n\t\t\t\t</Span>\n\t\t\t</RuleSet>\n\t\t</Span>\n\t\t\n\t\t<Span color=\"Comment\">\n\t\t\t<Begin color=\"XmlDoc/DocComment\">///(?!/)</Begin>\n\t\t\t<RuleSet>\n\t\t\t\t<Import ruleSet=\"XmlDoc/DocCommentSet\"/>\n\t\t\t\t<Import ruleSet=\"CommentMarkerSet\"/>\n\t\t\t</RuleSet>\n\t\t</Span>\n\t\t\n\t\t<Span color=\"Comment\" ruleSet=\"CommentMarkerSet\">\n\t\t\t<Begin>//</Begin>\n\t\t</Span>\n\t\t\n\t\t<Span color=\"Comment\" ruleSet=\"CommentMarkerSet\" multiline=\"true\">\n\t\t\t<Begin>/\\*</Begin>\n\t\t\t<End>\\*/</End>\n\t\t</Span>\n\t\t\n\t\t<Span color=\"String\">\n\t\t\t<Begin>\"</Begin>\n\t\t\t<End>\"</End>\n\t\t\t<RuleSet>\n\t\t\t\t<!-- span for escape sequences -->\n\t\t\t\t<Span begin=\"\\\\\" end=\".\"/>\n\t\t\t</RuleSet>\n\t\t</Span>\n\t\t\n\t\t<Span color=\"Char\">\n\t\t\t<Begin>'</Begin>\n\t\t\t<End>'</End>\n\t\t\t<RuleSet>\n\t\t\t\t<!-- span for escape sequences -->\n\t\t\t\t<Span begin=\"\\\\\" end=\".\"/>\n\t\t\t</RuleSet>\n\t\t</Span>\n\t\t\n\t\t<Span color=\"String\" multiline=\"true\">\n\t\t\t<Begin color=\"String\">@\"</Begin>\n\t\t\t<End>\"</End>\n\t\t\t<RuleSet>\n\t\t\t\t<!-- span for escape sequences -->\n\t\t\t\t<Span begin='\"\"' end=\"\"/>\n\t\t\t</RuleSet>\n\t\t</Span>\n\t\t\n\t\t<Span color=\"String\">\n\t\t\t<Begin>\\$\"</Begin>\n\t\t\t<End>\"</End>\n\t\t\t<RuleSet>\n\t\t\t\t<!-- span for escape sequences -->\n\t\t\t\t<Span begin=\"\\\\\" end=\".\"/>\n\t\t\t\t<Span begin=\"\\{\\{\" end=\"\"/>\n\t\t\t\t<!-- string interpolation -->\n\t\t\t\t<Span begin=\"{\" end=\"}\" color=\"StringInterpolation\" ruleSet=\"\"/>\n\t\t\t</RuleSet>\n\t\t</Span>\n\n\t\t<!-- Digits -->\n\t\t<Rule color=\"NumberLiteral\">\n\t\t\t\\b0[xX][0-9a-fA-F]+  # hex number\n\t\t\t|\n\t\t\t(\t\\b\\d+(\\.[0-9]+)?   #number with optional floating point\n\t\t\t|\t\\.[0-9]+           #or just starting with floating point\n\t\t\t)\n\t\t\t([eE][+-]?[0-9]+)? # optional exponent\n\t\t</Rule>\n\t</RuleSet>\n</SyntaxDefinition>\n"
  },
  {
    "path": "ILSpy/TextView/CaretHighlightAdorner.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Documents;\nusing System.Windows.Media;\nusing System.Windows.Media.Animation;\nusing System.Windows.Threading;\n\nusing ICSharpCode.AvalonEdit.Editing;\n\nnamespace ICSharpCode.ILSpy.TextView\n{\n\t/// <summary>\n\t/// Animated rectangle around the caret.\n\t/// This is used after clicking links that lead to another location within the text view.\n\t/// </summary>\n\tsealed class CaretHighlightAdorner : Adorner\n\t{\n\t\treadonly Pen pen;\n\t\treadonly RectangleGeometry geometry;\n\n\t\tpublic CaretHighlightAdorner(TextArea textArea)\n\t\t\t: base(textArea.TextView)\n\t\t{\n\t\t\tRect min = textArea.Caret.CalculateCaretRectangle();\n\t\t\tmin.Offset(-textArea.TextView.ScrollOffset);\n\n\t\t\tRect max = min;\n\t\t\tdouble size = Math.Max(min.Width, min.Height) * 0.25;\n\t\t\tmax.Inflate(size, size);\n\n\t\t\tpen = new Pen(TextBlock.GetForeground(textArea.TextView).Clone(), 1);\n\n\t\t\tgeometry = new RectangleGeometry(min, 2, 2);\n\t\t\tgeometry.BeginAnimation(RectangleGeometry.RectProperty, new RectAnimation(min, max, new Duration(TimeSpan.FromMilliseconds(300))) { AutoReverse = true });\n\t\t\tpen.Brush.BeginAnimation(Brush.OpacityProperty, new DoubleAnimation(1, 0, new Duration(TimeSpan.FromMilliseconds(200))) { BeginTime = TimeSpan.FromMilliseconds(450) });\n\t\t}\n\n\t\tpublic static void DisplayCaretHighlightAnimation(TextArea textArea)\n\t\t{\n\t\t\tAdornerLayer layer = AdornerLayer.GetAdornerLayer(textArea.TextView);\n\t\t\tCaretHighlightAdorner adorner = new CaretHighlightAdorner(textArea);\n\t\t\tlayer.Add(adorner);\n\n\t\t\tDispatcherTimer timer = new DispatcherTimer();\n\t\t\ttimer.Interval = TimeSpan.FromSeconds(1);\n\t\t\ttimer.Tick += delegate {\n\t\t\t\ttimer.Stop();\n\t\t\t\tlayer.Remove(adorner);\n\t\t\t};\n\t\t\ttimer.Start();\n\t\t}\n\n\t\tprotected override void OnRender(DrawingContext drawingContext)\n\t\t{\n\t\t\tdrawingContext.DrawGeometry(null, pen, geometry);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TextView/DecompilerTextEditor.cs",
    "content": "using ICSharpCode.AvalonEdit;\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.AvalonEdit.Rendering;\n\nnamespace ICSharpCode.ILSpy.TextView;\n\npublic class DecompilerTextEditor : TextEditor\n{\n\tprotected override IVisualLineTransformer CreateColorizer(IHighlightingDefinition highlightingDefinition)\n\t{\n\t\treturn new ThemeAwareHighlightingColorizer(highlightingDefinition);\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TextView/DecompilerTextView.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.Globalization;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Controls.Primitives;\nusing System.Windows.Data;\nusing System.Windows.Documents;\nusing System.Windows.Input;\nusing System.Windows.Media;\nusing System.Windows.Media.Animation;\nusing System.Windows.Threading;\nusing System.Xml;\n\nusing ICSharpCode.AvalonEdit;\nusing ICSharpCode.AvalonEdit.Document;\nusing ICSharpCode.AvalonEdit.Editing;\nusing ICSharpCode.AvalonEdit.Folding;\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.AvalonEdit.Highlighting.Xshd;\nusing ICSharpCode.AvalonEdit.Rendering;\nusing ICSharpCode.AvalonEdit.Search;\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\nusing ICSharpCode.Decompiler.CSharp.ProjectDecompiler;\nusing ICSharpCode.Decompiler.Documentation;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.AvalonEdit;\nusing ICSharpCode.ILSpy.Options;\nusing ICSharpCode.ILSpy.Themes;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX;\n\nusing Microsoft.Win32;\n\nusing TomsToolbox.Composition;\nusing TomsToolbox.Wpf;\n\nusing ResourceKeys = ICSharpCode.ILSpy.Themes.ResourceKeys;\n\nnamespace ICSharpCode.ILSpy.TextView\n{\n\t/// <summary>\n\t/// Manages the TextEditor showing the decompiled code.\n\t/// Contains all the threading logic that makes the decompiler work in the background.\n\t/// </summary>\n\tpublic sealed partial class DecompilerTextView : UserControl, IHaveState, IProgress<DecompilationProgress>\n\t{\n\t\treadonly IExportProvider exportProvider;\n\t\treadonly SettingsService settingsService;\n\t\treadonly LanguageService languageService;\n\t\treadonly MainWindow mainWindow;\n\t\treadonly ReferenceElementGenerator referenceElementGenerator;\n\t\treadonly UIElementGenerator uiElementGenerator;\n\t\treadonly List<VisualLineElementGenerator?> activeCustomElementGenerators = new List<VisualLineElementGenerator?>();\n\t\treadonly BracketHighlightRenderer bracketHighlightRenderer;\n\t\tRichTextColorizer? activeRichTextColorizer;\n\t\tRichTextModel? activeRichTextModel;\n\t\tFoldingManager? foldingManager;\n\t\tILSpyTreeNode[]? decompiledNodes;\n\t\tUri? currentAddress;\n\t\tstring? currentTitle;\n\t\tbool expandMemberDefinitions;\n\n\t\tDefinitionLookup? definitionLookup;\n\t\tTextSegmentCollection<ReferenceSegment>? references;\n\t\tCancellationTokenSource? currentCancellationTokenSource;\n\n\t\treadonly TextMarkerService textMarkerService;\n\t\treadonly List<ITextMarker> localReferenceMarks = new List<ITextMarker>();\n\n\t\t#region Constructor\n\t\tpublic DecompilerTextView(IExportProvider exportProvider)\n\t\t{\n\t\t\tthis.exportProvider = exportProvider;\n\t\t\tsettingsService = exportProvider.GetExportedValue<SettingsService>();\n\t\t\tlanguageService = exportProvider.GetExportedValue<LanguageService>();\n\t\t\tmainWindow = exportProvider.GetExportedValue<MainWindow>();\n\n\t\t\tRegisterHighlighting();\n\n\t\t\tInitializeComponent();\n\n\t\t\tthis.referenceElementGenerator = new ReferenceElementGenerator(this.IsLink);\n\t\t\ttextEditor.TextArea.TextView.ElementGenerators.Add(referenceElementGenerator);\n\t\t\tthis.uiElementGenerator = new UIElementGenerator();\n\t\t\tthis.bracketHighlightRenderer = new BracketHighlightRenderer(textEditor.TextArea.TextView);\n\t\t\ttextEditor.TextArea.TextView.ElementGenerators.Add(uiElementGenerator);\n\t\t\ttextEditor.Options.RequireControlModifierForHyperlinkClick = false;\n\t\t\ttextEditor.TextArea.TextView.MouseHover += TextViewMouseHover;\n\t\t\ttextEditor.TextArea.TextView.MouseHoverStopped += TextViewMouseHoverStopped;\n\t\t\ttextEditor.TextArea.PreviewMouseDown += TextAreaMouseDown;\n\t\t\ttextEditor.TextArea.PreviewMouseUp += TextAreaMouseUp;\n\t\t\ttextEditor.TextArea.Caret.PositionChanged += HighlightBrackets;\n\t\t\ttextEditor.MouseMove += TextEditorMouseMove;\n\t\t\ttextEditor.MouseLeave += TextEditorMouseLeave;\n\t\t\ttextEditor.SetBinding(Control.FontFamilyProperty, new Binding { Source = settingsService.DisplaySettings, Path = new PropertyPath(\"SelectedFont\") });\n\t\t\ttextEditor.SetBinding(Control.FontSizeProperty, new Binding { Source = settingsService.DisplaySettings, Path = new PropertyPath(\"SelectedFontSize\") });\n\t\t\ttextEditor.SetBinding(TextEditor.WordWrapProperty, new Binding { Source = settingsService.DisplaySettings, Path = new PropertyPath(\"EnableWordWrap\") });\n\n\t\t\t// disable Tab editing command (useless for read-only editor); allow using tab for focus navigation instead\n\t\t\tRemoveEditCommand(EditingCommands.TabForward);\n\t\t\tRemoveEditCommand(EditingCommands.TabBackward);\n\n\t\t\ttextMarkerService = new TextMarkerService(textEditor.TextArea.TextView);\n\t\t\ttextEditor.TextArea.TextView.BackgroundRenderers.Add(textMarkerService);\n\t\t\ttextEditor.TextArea.TextView.LineTransformers.Add(textMarkerService);\n\t\t\ttextEditor.ShowLineNumbers = true;\n\n\t\t\tMessageBus<SettingsChangedEventArgs>.Subscribers += Settings_Changed;\n\n\t\t\t// SearchPanel\n\t\t\tSearchPanel searchPanel = SearchPanel.Install(textEditor.TextArea);\n\t\t\tsearchPanel.RegisterCommands(mainWindow.CommandBindings);\n\t\t\tsearchPanel.SetResourceReference(SearchPanel.MarkerBrushProperty, ResourceKeys.SearchResultBackgroundBrush);\n\t\t\tsearchPanel.Loaded += (_, _) => {\n\t\t\t\t// HACK: fix search text box\n\t\t\t\tvar textBox = searchPanel.Template.FindName(\"PART_searchTextBox\", searchPanel) as TextBox;\n\t\t\t\tif (textBox != null)\n\t\t\t\t{\n\t\t\t\t\t// the hardcoded but misaligned margin\n\t\t\t\t\ttextBox.Margin = new Thickness(3);\n\t\t\t\t\t// the hardcoded height\n\t\t\t\t\ttextBox.Height = double.NaN;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tShowLineMargin();\n\t\t\tSetHighlightCurrentLine();\n\n\t\t\tContextMenuProvider.Add(this);\n\n\t\t\ttextEditor.TextArea.TextView.SetResourceReference(ICSharpCode.AvalonEdit.Rendering.TextView.LinkTextForegroundBrushProperty, ResourceKeys.LinkTextForegroundBrush);\n\t\t\ttextEditor.TextArea.TextView.SetResourceReference(ICSharpCode.AvalonEdit.Rendering.TextView.CurrentLineBackgroundProperty, ResourceKeys.CurrentLineBackgroundBrush);\n\t\t\ttextEditor.TextArea.TextView.SetResourceReference(ICSharpCode.AvalonEdit.Rendering.TextView.CurrentLineBorderProperty, ResourceKeys.CurrentLineBorderPen);\n\n\t\t\tDataObject.AddSettingDataHandler(textEditor.TextArea, OnSettingData);\n\n\t\t\tthis.DataContextChanged += DecompilerTextView_DataContextChanged;\n\t\t}\n\n\t\tprivate void DecompilerTextView_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)\n\t\t{\n\t\t\tif (this.DataContext is PaneModel model)\n\t\t\t{\n\t\t\t\tmodel.Title = currentTitle ?? ILSpy.Properties.Resources.Decompiling;\n\t\t\t}\n\t\t}\n\n\t\tvoid RemoveEditCommand(RoutedUICommand command)\n\t\t{\n\t\t\tvar handler = textEditor.TextArea.DefaultInputHandler.Editing;\n\t\t\tvar inputBinding = handler.InputBindings.FirstOrDefault(b => b.Command == command);\n\t\t\tif (inputBinding != null)\n\t\t\t\thandler.InputBindings.Remove(inputBinding);\n\t\t\tvar commandBinding = handler.CommandBindings.FirstOrDefault(b => b.Command == command);\n\t\t\tif (commandBinding != null)\n\t\t\t\thandler.CommandBindings.Remove(commandBinding);\n\t\t}\n\t\t#endregion\n\n\t\t#region Line margin\n\n\t\tprivate void Settings_Changed(object? sender, SettingsChangedEventArgs e)\n\t\t{\n\t\t\tSettings_PropertyChanged(sender, e);\n\t\t}\n\n\t\tprivate void Settings_PropertyChanged(object? sender, PropertyChangedEventArgs e)\n\t\t{\n\t\t\tif (sender is not DisplaySettings)\n\t\t\t\treturn;\n\n\t\t\tswitch (e.PropertyName)\n\t\t\t{\n\t\t\t\tcase nameof(DisplaySettings.ShowLineNumbers):\n\t\t\t\t\tShowLineMargin();\n\t\t\t\t\tbreak;\n\t\t\t\tcase nameof(DisplaySettings.HighlightCurrentLine):\n\t\t\t\t\tSetHighlightCurrentLine();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tvoid ShowLineMargin()\n\t\t{\n\t\t\tforeach (var margin in this.textEditor.TextArea.LeftMargins)\n\t\t\t{\n\t\t\t\tif (margin is LineNumberMargin || margin is System.Windows.Shapes.Line)\n\t\t\t\t{\n\t\t\t\t\tmargin.Visibility = settingsService.DisplaySettings.ShowLineNumbers ? Visibility.Visible : Visibility.Collapsed;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid SetHighlightCurrentLine()\n\t\t{\n\t\t\ttextEditor.Options.HighlightCurrentLine = settingsService.DisplaySettings.HighlightCurrentLine;\n\t\t}\n\n\t\t#endregion\n\n\t\t#region Tooltip support\n\t\tToolTip? toolTip;\n\t\tPopup? popupToolTip;\n\n\t\tvoid TextViewMouseHover(object sender, MouseEventArgs e)\n\t\t{\n\t\t\tif (!TryCloseExistingPopup(false))\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tTextViewPosition? position = GetPositionFromMousePosition();\n\t\t\tif (position == null)\n\t\t\t\treturn;\n\t\t\tint offset = textEditor.Document.GetOffset(position.Value.Location);\n\t\t\tif (referenceElementGenerator.References == null)\n\t\t\t\treturn;\n\t\t\tReferenceSegment? seg = referenceElementGenerator.References.FindSegmentsContaining(offset).FirstOrDefault();\n\t\t\tif (seg == null)\n\t\t\t\treturn;\n\t\t\tobject? content = GenerateTooltip(seg);\n\n\t\t\tif (content != null)\n\t\t\t{\n\t\t\t\tpopupToolTip = content as Popup;\n\n\t\t\t\tif (popupToolTip != null)\n\t\t\t\t{\n\t\t\t\t\tvar popupPosition = GetPopupPosition(e);\n\t\t\t\t\tpopupToolTip.Closed += ToolTipClosed;\n\t\t\t\t\tpopupToolTip.Placement = PlacementMode.Relative;\n\t\t\t\t\tpopupToolTip.PlacementTarget = this;\n\t\t\t\t\tpopupToolTip.HorizontalOffset = popupPosition.X;\n\t\t\t\t\tpopupToolTip.VerticalOffset = popupPosition.Y;\n\t\t\t\t\tpopupToolTip.StaysOpen = true;  // We will close it ourselves\n\n\t\t\t\t\te.Handled = true;\n\t\t\t\t\tpopupToolTip.IsOpen = true;\n\t\t\t\t\tdistanceToPopupLimit = double.PositiveInfinity; // reset limit; we'll re-calculate it on the next mouse movement\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (toolTip == null)\n\t\t\t\t\t{\n\t\t\t\t\t\ttoolTip = new ToolTip();\n\t\t\t\t\t\ttoolTip.Closed += ToolTipClosed;\n\t\t\t\t\t}\n\t\t\t\t\ttoolTip.PlacementTarget = this; // required for property inheritance\n\n\t\t\t\t\tif (content is string s)\n\t\t\t\t\t{\n\t\t\t\t\t\ttoolTip.Content = new TextBlock {\n\t\t\t\t\t\t\tText = s,\n\t\t\t\t\t\t\tTextWrapping = TextWrapping.Wrap\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\ttoolTip.Content = content;\n\n\t\t\t\t\te.Handled = true;\n\t\t\t\t\ttoolTip.IsOpen = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool TryCloseExistingPopup(bool mouseClick)\n\t\t{\n\t\t\tif (popupToolTip != null)\n\t\t\t{\n\t\t\t\tif (popupToolTip.IsOpen && !mouseClick && popupToolTip is FlowDocumentTooltip t && !t.CloseWhenMouseMovesAway)\n\t\t\t\t{\n\t\t\t\t\treturn false; // Popup does not want to be closed yet\n\t\t\t\t}\n\t\t\t\tpopupToolTip.IsOpen = false;\n\t\t\t\tpopupToolTip = null;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary> Returns Popup position based on mouse position, in device independent units </summary>\n\t\tPoint GetPopupPosition(MouseEventArgs mouseArgs)\n\t\t{\n\t\t\tPoint mousePos = mouseArgs.GetPosition(this);\n\t\t\t// align Popup with line bottom\n\t\t\tTextViewPosition? logicalPos = textEditor.GetPositionFromPoint(mousePos);\n\t\t\tif (logicalPos.HasValue)\n\t\t\t{\n\t\t\t\tvar textView = textEditor.TextArea.TextView;\n\t\t\t\treturn textView.GetVisualPosition(logicalPos.Value, VisualYPosition.LineBottom)\n\t\t\t\t\t- textView.ScrollOffset\n\t\t\t\t\t+ new Vector(-4, 0);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn mousePos + new Vector(-4, 6);\n\t\t\t}\n\t\t}\n\n\t\tvoid TextViewMouseHoverStopped(object sender, MouseEventArgs e)\n\t\t{\n\t\t\t// Non-popup tooltips get closed as soon as the mouse starts moving again\n\t\t\tif (toolTip != null)\n\t\t\t{\n\t\t\t\ttoolTip.IsOpen = false;\n\t\t\t\te.Handled = true;\n\t\t\t}\n\t\t}\n\n\t\tdouble distanceToPopupLimit;\n\t\tconst double MaxMovementAwayFromPopup = 5;\n\n\t\tvoid TextEditorMouseMove(object sender, MouseEventArgs e)\n\t\t{\n\t\t\tif (popupToolTip != null && PresentationSource.FromVisual(popupToolTip.Child) != null)\n\t\t\t{\n\t\t\t\tdouble distanceToPopup = GetDistanceToPopup(e);\n\t\t\t\tif (distanceToPopup > distanceToPopupLimit)\n\t\t\t\t{\n\t\t\t\t\t// Close popup if mouse moved away, exceeding the limit\n\t\t\t\t\tTryCloseExistingPopup(false);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// reduce distanceToPopupLimit\n\t\t\t\t\tdistanceToPopupLimit = Math.Min(distanceToPopupLimit, distanceToPopup + MaxMovementAwayFromPopup);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdouble GetDistanceToPopup(MouseEventArgs e)\n\t\t{\n\t\t\tPoint p = popupToolTip!.Child.PointFromScreen(PointToScreen(e.GetPosition(this)));\n\t\t\tSize size = popupToolTip.Child.RenderSize;\n\t\t\tdouble x = 0;\n\t\t\tif (p.X < 0)\n\t\t\t\tx = -p.X;\n\t\t\telse if (p.X > size.Width)\n\t\t\t\tx = p.X - size.Width;\n\t\t\tdouble y = 0;\n\t\t\tif (p.Y < 0)\n\t\t\t\ty = -p.Y;\n\t\t\telse if (p.Y > size.Height)\n\t\t\t\ty = p.Y - size.Height;\n\t\t\treturn Math.Sqrt(x * x + y * y);\n\t\t}\n\n\t\tvoid TextEditorMouseLeave(object sender, MouseEventArgs e)\n\t\t{\n\t\t\tif (popupToolTip != null && !popupToolTip.IsMouseOver)\n\t\t\t{\n\t\t\t\t// do not close popup if mouse moved from editor to popup\n\t\t\t\tTryCloseExistingPopup(false);\n\t\t\t}\n\t\t}\n\n\t\tvoid OnUnloaded(object sender, EventArgs e)\n\t\t{\n\t\t\t// Close popup when another document gets selected\n\t\t\t// TextEditorMouseLeave is not sufficient for this because the mouse might be over the popup when the document switch happens (e.g. Ctrl+Tab)\n\t\t\tTryCloseExistingPopup(true);\n\t\t}\n\n\t\tvoid ToolTipClosed(object? sender, EventArgs e)\n\t\t{\n\t\t\tif (toolTip == sender)\n\t\t\t{\n\t\t\t\ttoolTip = null;\n\t\t\t}\n\t\t\tif (popupToolTip == sender)\n\t\t\t{\n\t\t\t\t// Because popupToolTip instances are created by the tooltip provider,\n\t\t\t\t// they might be reused; so we should detach the event handler\n\t\t\t\tif (popupToolTip != null)\n\t\t\t\t{\n\t\t\t\t\tpopupToolTip.Closed -= ToolTipClosed;\n\t\t\t\t}\n\t\t\t\tpopupToolTip = null;\n\t\t\t}\n\t\t}\n\n\t\tobject? GenerateTooltip(ReferenceSegment segment)\n\t\t{\n\t\t\tvar fontSize = settingsService.DisplaySettings.SelectedFontSize;\n\n\t\t\tif (segment.Reference is ICSharpCode.Decompiler.Disassembler.OpCodeInfo code)\n\t\t\t{\n\t\t\t\tXmlDocumentationProvider docProvider = XmlDocLoader.MscorlibDocumentation;\n\t\t\t\tDocumentationUIBuilder renderer = new DocumentationUIBuilder(new CSharpAmbience(), languageService.Language.SyntaxHighlighting, settingsService.DisplaySettings, mainWindow);\n\t\t\t\trenderer.AddSignatureBlock($\"{code.Name} (0x{code.Code:x})\");\n\t\t\t\tif (docProvider != null)\n\t\t\t\t{\n\t\t\t\t\tstring documentation = docProvider.GetDocumentation(\"F:System.Reflection.Emit.OpCodes.\" + code.EncodedName);\n\t\t\t\t\tif (documentation != null)\n\t\t\t\t\t{\n\t\t\t\t\t\trenderer.AddXmlDocumentation(documentation, null, null);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn new FlowDocumentTooltip(renderer.CreateDocument(), fontSize, mainWindow.ActualWidth);\n\t\t\t}\n\t\t\telse if (segment.Reference is IEntity entity)\n\t\t\t{\n\t\t\t\tvar document = CreateTooltipForEntity(entity);\n\t\t\t\tif (document == null)\n\t\t\t\t\treturn null;\n\t\t\t\treturn new FlowDocumentTooltip(document, fontSize, mainWindow.ActualWidth);\n\t\t\t}\n\t\t\telse if (segment.Reference is EntityReference unresolvedEntity)\n\t\t\t{\n\t\t\t\tvar assemblyList = exportProvider.GetExportedValue<AssemblyList>();\n\t\t\t\tvar module = unresolvedEntity.ResolveAssembly(assemblyList);\n\t\t\t\tif (module == null)\n\t\t\t\t\treturn null;\n\t\t\t\tvar typeSystem = new DecompilerTypeSystem(module,\n\t\t\t\t\tmodule.GetAssemblyResolver(),\n\t\t\t\t\tTypeSystemOptions.Default | TypeSystemOptions.Uncached);\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tHandle handle = unresolvedEntity.Handle;\n\t\t\t\t\tif (!handle.IsEntityHandle())\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tIEntity resolved = typeSystem.MainModule.ResolveEntity((EntityHandle)handle);\n\t\t\t\t\tif (resolved == null)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tvar document = CreateTooltipForEntity(resolved);\n\t\t\t\t\tif (document == null)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\treturn new FlowDocumentTooltip(document, fontSize, mainWindow.ActualWidth);\n\t\t\t\t}\n\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tFlowDocument? CreateTooltipForEntity(IEntity resolved)\n\t\t{\n\t\t\tLanguage currentLanguage = languageService.Language;\n\t\t\tDocumentationUIBuilder renderer = new DocumentationUIBuilder(new CSharpAmbience(), currentLanguage.SyntaxHighlighting, settingsService.DisplaySettings, mainWindow);\n\t\t\tRichText richText = currentLanguage.GetRichTextTooltip(resolved);\n\t\t\tif (richText == null)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\trenderer.AddSignatureBlock(richText.Text, richText.ToRichTextModel());\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (resolved.ParentModule == null || resolved.ParentModule.MetadataFile == null)\n\t\t\t\t\treturn null;\n\t\t\t\tvar docProvider = XmlDocLoader.LoadDocumentation(resolved.ParentModule.MetadataFile);\n\t\t\t\tif (docProvider != null)\n\t\t\t\t{\n\t\t\t\t\tstring documentation = docProvider.GetDocumentation(resolved.GetIdString());\n\t\t\t\t\tif (documentation != null)\n\t\t\t\t\t{\n\t\t\t\t\t\trenderer.AddXmlDocumentation(documentation, resolved, ResolveReference);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (XmlException)\n\t\t\t{\n\t\t\t\t// ignore\n\t\t\t}\n\t\t\treturn renderer.CreateDocument();\n\n\t\t\tIEntity? ResolveReference(string idString)\n\t\t\t{\n\t\t\t\tvar assemblyList = exportProvider.GetExportedValue<AssemblyList>();\n\t\t\t\treturn AssemblyTreeModel.FindEntityInRelevantAssemblies(idString, assemblyList.GetAssemblies());\n\t\t\t}\n\t\t}\n\n\t\tsealed class FlowDocumentTooltip : Popup\n\t\t{\n\t\t\treadonly FlowDocumentScrollViewer viewer;\n\n\t\t\tpublic FlowDocumentTooltip(FlowDocument document, double fontSize, double maxWith)\n\t\t\t{\n\t\t\t\tTextOptions.SetTextFormattingMode(this, TextFormattingMode.Display);\n\t\t\t\tviewer = new() {\n\t\t\t\t\tWidth = document.MinPageWidth + fontSize * 5,\n\t\t\t\t\tMaxWidth = maxWith,\n\t\t\t\t\tDocument = document\n\t\t\t\t};\n\t\t\t\tBorder border = new Border {\n\t\t\t\t\tBorderThickness = new Thickness(1),\n\t\t\t\t\tMaxHeight = 400,\n\t\t\t\t\tChild = viewer\n\t\t\t\t};\n\t\t\t\tborder.SetResourceReference(Border.BackgroundProperty, SystemColors.ControlBrushKey);\n\t\t\t\tborder.SetResourceReference(Border.BorderBrushProperty, SystemColors.ControlDarkBrushKey);\n\n\t\t\t\tthis.Child = border;\n\t\t\t\tviewer.SetResourceReference(ForegroundProperty, SystemColors.InfoTextBrushKey);\n\t\t\t\tdocument.TextAlignment = TextAlignment.Left;\n\t\t\t\tdocument.FontSize = fontSize;\n\t\t\t\tdocument.FontFamily = SystemFonts.SmallCaptionFontFamily;\n\t\t\t}\n\n\t\t\tpublic bool CloseWhenMouseMovesAway {\n\t\t\t\tget { return !this.IsKeyboardFocusWithin; }\n\t\t\t}\n\n\t\t\tprotected override void OnLostKeyboardFocus(KeyboardFocusChangedEventArgs e)\n\t\t\t{\n\t\t\t\tbase.OnLostKeyboardFocus(e);\n\t\t\t\tthis.IsOpen = false;\n\t\t\t}\n\n\t\t\tprotected override void OnMouseLeave(MouseEventArgs e)\n\t\t\t{\n\t\t\t\tbase.OnMouseLeave(e);\n\t\t\t\t// When the mouse is over the popup, it is possible for ILSpy to be minimized,\n\t\t\t\t// or moved into the background, and yet the popup stays open.\n\t\t\t\t// We don't have a good method here to check whether the mouse moved back into the text area\n\t\t\t\t// or somewhere else, so we'll just close the popup.\n\t\t\t\tif (CloseWhenMouseMovesAway)\n\t\t\t\t\tthis.IsOpen = false;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region Highlight brackets\n\t\tvoid HighlightBrackets(object? sender, EventArgs e)\n\t\t{\n\t\t\tif (settingsService.DisplaySettings.HighlightMatchingBraces)\n\t\t\t{\n\t\t\t\tvar result = languageService.Language.BracketSearcher.SearchBracket(textEditor.Document, textEditor.CaretOffset);\n\t\t\t\tbracketHighlightRenderer.SetHighlight(result);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbracketHighlightRenderer.SetHighlight(null);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region RunWithCancellation\n\t\tpublic void Report(DecompilationProgress value)\n\t\t{\n\t\t\tdouble v = (double)value.UnitsCompleted / value.TotalUnits;\n\t\t\tDispatcher.BeginInvoke(DispatcherPriority.Normal, delegate {\n\t\t\t\tprogressBar.IsIndeterminate = !double.IsFinite(v);\n\t\t\t\tprogressBar.Value = v * 100.0;\n\t\t\t\tprogressTitle.Text = !string.IsNullOrWhiteSpace(value.Title) ? value.Title : Properties.Resources.Decompiling;\n\t\t\t\tprogressText.Text = value.Status;\n\t\t\t\tprogressText.Visibility = !string.IsNullOrWhiteSpace(progressText.Text) ? Visibility.Visible : Visibility.Collapsed;\n\t\t\t\tvar taskBar = mainWindow.TaskbarItemInfo;\n\t\t\t\tif (taskBar != null)\n\t\t\t\t{\n\t\t\t\t\ttaskBar.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Normal;\n\t\t\t\t\ttaskBar.ProgressValue = v;\n\t\t\t\t}\n\t\t\t\tif (this.DataContext is TabPageModel model)\n\t\t\t\t{\n\t\t\t\t\tmodel.Title = progressTitle.Text;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Switches the GUI into \"waiting\" mode, then calls <paramref name=\"taskCreation\"/> to create\n\t\t/// the task.\n\t\t/// If another task is started before the previous task finishes running, the previous task is cancelled.\n\t\t/// </summary>\n\t\tpublic Task<T> RunWithCancellation<T>(Func<CancellationToken, Task<T>> taskCreation, string? progressTitle = null)\n\t\t{\n\t\t\tif (waitAdorner.Visibility != Visibility.Visible)\n\t\t\t{\n\t\t\t\twaitAdorner.Visibility = Visibility.Visible;\n\t\t\t\t// Work around a WPF bug by setting IsIndeterminate only while the progress bar is visible.\n\t\t\t\t// https://github.com/icsharpcode/ILSpy/issues/593\n\t\t\t\tthis.progressTitle.Text = progressTitle == null ? Properties.Resources.Decompiling : progressTitle;\n\t\t\t\tprogressBar.IsIndeterminate = true;\n\t\t\t\tprogressText.Text = null;\n\t\t\t\tprogressText.Visibility = Visibility.Collapsed;\n\t\t\t\twaitAdorner.BeginAnimation(OpacityProperty, new DoubleAnimation(0, 1, new Duration(TimeSpan.FromSeconds(0.5)), FillBehavior.Stop));\n\t\t\t\tvar taskBar = mainWindow.TaskbarItemInfo;\n\t\t\t\tif (taskBar != null)\n\t\t\t\t{\n\t\t\t\t\ttaskBar.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Indeterminate;\n\t\t\t\t}\n\t\t\t}\n\t\t\tCancellationTokenSource? previousCancellationTokenSource = currentCancellationTokenSource;\n\t\t\tvar myCancellationTokenSource = new CancellationTokenSource();\n\t\t\tcurrentCancellationTokenSource = myCancellationTokenSource;\n\t\t\t// cancel the previous only after current was set to the new one (avoid that the old one still finishes successfully)\n\t\t\tif (previousCancellationTokenSource != null)\n\t\t\t{\n\t\t\t\tpreviousCancellationTokenSource.Cancel();\n\t\t\t}\n\n\t\t\tvar tcs = new TaskCompletionSource<T>();\n\t\t\tTask<T> task;\n\t\t\ttry\n\t\t\t{\n\t\t\t\ttask = taskCreation(myCancellationTokenSource.Token);\n\t\t\t}\n\t\t\tcatch (OperationCanceledException)\n\t\t\t{\n\t\t\t\ttask = TaskHelper.FromCancellation<T>();\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\ttask = TaskHelper.FromException<T>(ex);\n\t\t\t}\n\t\t\tAction continuation = delegate {\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tif (currentCancellationTokenSource == myCancellationTokenSource)\n\t\t\t\t\t{\n\t\t\t\t\t\tcurrentCancellationTokenSource = null;\n\t\t\t\t\t\twaitAdorner.Visibility = Visibility.Collapsed;\n\t\t\t\t\t\tprogressBar.IsIndeterminate = false;\n\t\t\t\t\t\tprogressText.Text = null;\n\t\t\t\t\t\tprogressText.Visibility = Visibility.Collapsed;\n\t\t\t\t\t\tvar taskBar = mainWindow.TaskbarItemInfo;\n\t\t\t\t\t\tif (taskBar != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttaskBar.ProgressState = System.Windows.Shell.TaskbarItemProgressState.None;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (task.IsCanceled)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAvalonEditTextOutput output = new AvalonEditTextOutput();\n\t\t\t\t\t\t\toutput.WriteLine(\"The operation was canceled.\");\n\t\t\t\t\t\t\tShowOutput(output);\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttcs.SetFromTask(task);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\ttcs.SetCanceled();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tmyCancellationTokenSource.Dispose();\n\t\t\t\t}\n\t\t\t};\n\t\t\ttask.ContinueWith(delegate { Dispatcher.BeginInvoke(DispatcherPriority.Normal, continuation); });\n\t\t\treturn tcs.Task;\n\t\t}\n\n\t\tvoid CancelButton_Click(object sender, RoutedEventArgs e)\n\t\t{\n\t\t\tif (currentCancellationTokenSource != null)\n\t\t\t{\n\t\t\t\tcurrentCancellationTokenSource.Cancel();\n\t\t\t\t// Don't set to null: the task still needs to produce output and hide the wait adorner\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region ShowOutput\n\t\tpublic void ShowText(AvalonEditTextOutput textOutput)\n\t\t{\n\t\t\tShowNodes(textOutput, null);\n\t\t}\n\n\t\tpublic void ShowNode(AvalonEditTextOutput textOutput, ILSpyTreeNode node, IHighlightingDefinition? highlighting = null)\n\t\t{\n\t\t\tShowNodes(textOutput, new[] { node }, highlighting);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Shows the given output in the text view.\n\t\t/// Cancels any currently running decompilation tasks.\n\t\t/// </summary>\n\t\tpublic void ShowNodes(AvalonEditTextOutput textOutput, ILSpyTreeNode[]? nodes, IHighlightingDefinition? highlighting = null)\n\t\t{\n\t\t\t// Cancel the decompilation task:\n\t\t\tif (currentCancellationTokenSource != null)\n\t\t\t{\n\t\t\t\tcurrentCancellationTokenSource.Cancel();\n\t\t\t\tcurrentCancellationTokenSource = null; // prevent canceled task from producing output\n\t\t\t}\n\t\t\tif (this.nextDecompilationRun != null)\n\t\t\t{\n\t\t\t\t// remove scheduled decompilation run\n\t\t\t\tthis.nextDecompilationRun.TaskCompletionSource.TrySetCanceled();\n\t\t\t\tthis.nextDecompilationRun = null;\n\t\t\t}\n\t\t\tif (nodes != null && (string.IsNullOrEmpty(textOutput.Title)\n\t\t\t\t|| textOutput.Title == Properties.Resources.NewTab))\n\t\t\t{\n\t\t\t\ttextOutput.Title = string.Join(\", \", nodes.Select(n => n.Text));\n\t\t\t}\n\n\t\t\tdecompiledNodes = nodes;\n\t\t\tShowOutput(textOutput, highlighting);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Shows the given output in the text view.\n\t\t/// </summary>\n\t\tvoid ShowOutput(AvalonEditTextOutput textOutput, IHighlightingDefinition? highlighting = null, DecompilerTextViewState? state = null)\n\t\t{\n\t\t\tDebug.WriteLine(\"Showing {0} characters of output\", textOutput.TextLength);\n\t\t\tStopwatch w = Stopwatch.StartNew();\n\n\t\t\tClearLocalReferenceMarks();\n\t\t\ttextEditor.ScrollToHome();\n\t\t\tif (foldingManager != null)\n\t\t\t{\n\t\t\t\tFoldingManager.Uninstall(foldingManager);\n\t\t\t\tfoldingManager = null;\n\t\t\t}\n\t\t\ttextEditor.Document = null; // clear old document while we're changing the highlighting\n\t\t\tuiElementGenerator.UIElements = textOutput.UIElements;\n\t\t\treferenceElementGenerator.References = textOutput.References;\n\t\t\treferences = textOutput.References;\n\t\t\tdefinitionLookup = textOutput.DefinitionLookup;\n\t\t\ttextEditor.SyntaxHighlighting = highlighting;\n\t\t\ttextEditor.Options.EnableEmailHyperlinks = textOutput.EnableHyperlinks;\n\t\t\ttextEditor.Options.EnableHyperlinks = textOutput.EnableHyperlinks;\n\t\t\tactiveRichTextModel = null;\n\t\t\tif (activeRichTextColorizer != null)\n\t\t\t\ttextEditor.TextArea.TextView.LineTransformers.Remove(activeRichTextColorizer);\n\t\t\tif (textOutput.HighlightingModel != null)\n\t\t\t{\n\t\t\t\tactiveRichTextModel = textOutput.HighlightingModel;\n\t\t\t\tactiveRichTextColorizer = new RichTextColorizer(textOutput.HighlightingModel);\n\t\t\t\ttextEditor.TextArea.TextView.LineTransformers.Insert(highlighting == null ? 0 : 1, activeRichTextColorizer);\n\t\t\t}\n\n\t\t\t// Change the set of active element generators:\n\t\t\tforeach (var elementGenerator in activeCustomElementGenerators)\n\t\t\t{\n\t\t\t\ttextEditor.TextArea.TextView.ElementGenerators.Remove(elementGenerator);\n\t\t\t}\n\t\t\tactiveCustomElementGenerators.Clear();\n\n\t\t\tforeach (var elementGenerator in textOutput.elementGenerators)\n\t\t\t{\n\t\t\t\ttextEditor.TextArea.TextView.ElementGenerators.Add(elementGenerator);\n\t\t\t\tactiveCustomElementGenerators.Add(elementGenerator);\n\t\t\t}\n\n\t\t\tDebug.WriteLine(\"  Set-up: {0}\", w.Elapsed);\n\t\t\tw.Restart();\n\t\t\ttextEditor.Document = textOutput.GetDocument();\n\t\t\tDebug.WriteLine(\"  Assigning document: {0}\", w.Elapsed);\n\t\t\tw.Restart();\n\t\t\tif (textOutput.Foldings.Count > 0)\n\t\t\t{\n\t\t\t\tif (state != null)\n\t\t\t\t{\n\t\t\t\t\tstate.RestoreFoldings(textOutput.Foldings, settingsService.DisplaySettings.ExpandMemberDefinitions);\n\t\t\t\t\ttextEditor.ScrollToVerticalOffset(state.VerticalOffset);\n\t\t\t\t\ttextEditor.ScrollToHorizontalOffset(state.HorizontalOffset);\n\t\t\t\t}\n\t\t\t\tfoldingManager = FoldingManager.Install(textEditor.TextArea);\n\t\t\t\tfoldingManager.UpdateFoldings(textOutput.Foldings.OrderBy(f => f.StartOffset), -1);\n\t\t\t\tDebug.WriteLine(\"  Updating folding: {0}\", w.Elapsed);\n\t\t\t\tw.Restart();\n\t\t\t}\n\t\t\telse if (highlighting?.Name == \"XML\")\n\t\t\t{\n\t\t\t\tfoldingManager = FoldingManager.Install(textEditor.TextArea);\n\t\t\t\tvar foldingStrategy = new XmlFoldingStrategy();\n\t\t\t\tfoldingStrategy.UpdateFoldings(foldingManager, textEditor.Document);\n\t\t\t\tDebug.WriteLine(\"  Updating folding: {0}\", w.Elapsed);\n\t\t\t\tw.Restart();\n\t\t\t}\n\n\t\t\tif (this.DataContext is PaneModel model)\n\t\t\t{\n\t\t\t\tmodel.Title = textOutput.Title;\n\t\t\t}\n\t\t\tcurrentAddress = textOutput.Address;\n\t\t\tcurrentTitle = textOutput.Title;\n\t\t\texpandMemberDefinitions = settingsService.DisplaySettings.ExpandMemberDefinitions;\n\t\t\tSetLocalReferenceMarks(textOutput.InitialHighlightReference);\n\t\t}\n\t\t#endregion\n\n\t\t#region Decompile (for display)\n\t\t// more than 5M characters is too slow to output (when user browses treeview)\n\t\tpublic const int DefaultOutputLengthLimit = 5000000;\n\n\t\t// more than 75M characters can get us into trouble with memory usage\n\t\tpublic const int ExtendedOutputLengthLimit = 75000000;\n\n\t\tDecompilationContext? nextDecompilationRun;\n\n\t\t[Obsolete(\"Use DecompileAsync() instead\")]\n\t\tpublic void Decompile(ILSpy.Language language, IEnumerable<ILSpyTreeNode> treeNodes, DecompilationOptions options)\n\t\t{\n\t\t\tDecompileAsync(language, treeNodes, null, options).HandleExceptions();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Starts the decompilation of the given nodes.\n\t\t/// The result is displayed in the text view.\n\t\t/// If any errors occur, the error message is displayed in the text view, and the task returned by this method completes successfully.\n\t\t/// If the operation is cancelled (by starting another decompilation action); the returned task is marked as cancelled.\n\t\t/// </summary>\n\t\tpublic Task DecompileAsync(ILSpy.Language language, IEnumerable<ILSpyTreeNode> treeNodes, object? source, DecompilationOptions options)\n\t\t{\n\t\t\t// Some actions like loading an assembly list cause several selection changes in the tree view,\n\t\t\t// and each of those will start a decompilation action.\n\n\t\t\tbool isDecompilationScheduled = this.nextDecompilationRun != null;\n\t\t\tif (this.nextDecompilationRun != null)\n\t\t\t\tthis.nextDecompilationRun.TaskCompletionSource.TrySetCanceled();\n\t\t\tthis.nextDecompilationRun = new DecompilationContext(language, treeNodes.ToArray(), options, source);\n\t\t\tvar task = this.nextDecompilationRun.TaskCompletionSource.Task;\n\t\t\tif (!isDecompilationScheduled)\n\t\t\t{\n\t\t\t\tDispatcher.BeginInvoke(DispatcherPriority.Background, new Action(\n\t\t\t\t\tdelegate {\n\t\t\t\t\t\tvar context = this.nextDecompilationRun;\n\t\t\t\t\t\tthis.nextDecompilationRun = null;\n\t\t\t\t\t\tif (context != null)\n\t\t\t\t\t\t\tDoDecompile(context, DefaultOutputLengthLimit)\n\t\t\t\t\t\t\t\t.ContinueWith(t => context.TaskCompletionSource.SetFromTask(t)).HandleExceptions();\n\t\t\t\t\t}\n\t\t\t\t));\n\t\t\t}\n\t\t\treturn task;\n\t\t}\n\n\t\tsealed class DecompilationContext\n\t\t{\n\t\t\tpublic readonly ILSpy.Language Language;\n\t\t\tpublic readonly ILSpyTreeNode[] TreeNodes;\n\t\t\tpublic readonly DecompilationOptions Options;\n\t\t\tpublic readonly TaskCompletionSource<object?> TaskCompletionSource = new TaskCompletionSource<object?>();\n\t\t\tpublic readonly object? Source;\n\n\t\t\tpublic DecompilationContext(ILSpy.Language language, ILSpyTreeNode[] treeNodes, DecompilationOptions options, object? source = null)\n\t\t\t{\n\t\t\t\tthis.Language = language;\n\t\t\t\tthis.TreeNodes = treeNodes;\n\t\t\t\tthis.Options = options;\n\t\t\t\tthis.Source = source;\n\t\t\t}\n\t\t}\n\n\t\tTask DoDecompile(DecompilationContext context, int outputLengthLimit)\n\t\t{\n\t\t\treturn RunWithCancellation(\n\t\t\t\tdelegate (CancellationToken ct) { // creation of the background task\n\t\t\t\t\tcontext.Options.CancellationToken = ct;\n\t\t\t\t\tcontext.Options.Progress = this;\n\t\t\t\t\tdecompiledNodes = context.TreeNodes;\n\t\t\t\t\treturn DecompileAsync(context, outputLengthLimit);\n\t\t\t\t})\n\t\t\t.Then(\n\t\t\t\tdelegate (AvalonEditTextOutput textOutput) { // handling the result\n\t\t\t\t\tShowOutput(textOutput, context.Language.SyntaxHighlighting, context.Options.TextViewState);\n\t\t\t\t})\n\t\t\t.Catch<Exception>(exception => {\n\t\t\t\ttextEditor.SyntaxHighlighting = null;\n\t\t\t\tDebug.WriteLine(\"Decompiler crashed: \" + exception.ToString());\n\t\t\t\tAvalonEditTextOutput output = new AvalonEditTextOutput();\n\t\t\t\tif (exception is OutputLengthExceededException)\n\t\t\t\t{\n\t\t\t\t\tWriteOutputLengthExceededMessage(output, context, outputLengthLimit == DefaultOutputLengthLimit);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\toutput.WriteLine(exception.ToString());\n\t\t\t\t}\n\t\t\t\tShowOutput(output);\n\t\t\t});\n\t\t}\n\n\t\tTask<AvalonEditTextOutput> DecompileAsync(DecompilationContext context, int outputLengthLimit)\n\t\t{\n\t\t\tDebug.WriteLine(\"Start decompilation of {0} tree nodes\", context.TreeNodes.Length);\n\n\t\t\tTaskCompletionSource<AvalonEditTextOutput> tcs = new TaskCompletionSource<AvalonEditTextOutput>();\n\t\t\tif (context.TreeNodes.Length == 0)\n\t\t\t{\n\t\t\t\t// If there's nothing to be decompiled, don't bother starting up a thread.\n\t\t\t\t// (Improves perf in some cases since we don't have to wait for the thread-pool to accept our task)\n\t\t\t\ttcs.SetResult(new AvalonEditTextOutput());\n\t\t\t\treturn tcs.Task;\n\t\t\t}\n\n\t\t\tThread thread = new Thread(new ThreadStart(\n\t\t\t\tdelegate {\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tAvalonEditTextOutput textOutput = new AvalonEditTextOutput();\n\t\t\t\t\t\ttextOutput.LengthLimit = outputLengthLimit;\n\t\t\t\t\t\ttextOutput.SetInitialHighlight(context.Source);\n\t\t\t\t\t\tDecompileNodes(context, textOutput);\n\t\t\t\t\t\ttextOutput.PrepareDocument();\n\t\t\t\t\t\ttcs.SetResult(textOutput);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (OperationCanceledException)\n\t\t\t\t\t{\n\t\t\t\t\t\ttcs.SetCanceled();\n\t\t\t\t\t}\n\t\t\t\t\tcatch (Exception ex)\n\t\t\t\t\t{\n\t\t\t\t\t\ttcs.SetException(ex);\n\t\t\t\t\t}\n\t\t\t\t}));\n\t\t\tthread.Start();\n\t\t\treturn tcs.Task;\n\t\t}\n\n\t\tvoid DecompileNodes(DecompilationContext context, ITextOutput textOutput)\n\t\t{\n\t\t\tvar nodes = context.TreeNodes;\n\t\t\tif (textOutput is ISmartTextOutput smartTextOutput)\n\t\t\t{\n\t\t\t\tsmartTextOutput.Title = string.Join(\", \", nodes.Select(n => n.Text));\n\t\t\t}\n\t\t\tfor (int i = 0; i < nodes.Length; i++)\n\t\t\t{\n\t\t\t\tif (i > 0)\n\t\t\t\t\ttextOutput.WriteLine();\n\n\t\t\t\tcontext.Options.CancellationToken.ThrowIfCancellationRequested();\n\t\t\t\tnodes[i].Decompile(context.Language, textOutput, context.Options);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\t#region WriteOutputLengthExceededMessage\n\t\t/// <summary>\n\t\t/// Creates a message that the decompiler output was too long.\n\t\t/// The message contains buttons that allow re-trying (with larger limit) or saving to a file.\n\t\t/// </summary>\n\t\tvoid WriteOutputLengthExceededMessage(ISmartTextOutput output, DecompilationContext context, bool wasNormalLimit)\n\t\t{\n\t\t\tif (wasNormalLimit)\n\t\t\t{\n\t\t\t\toutput.WriteLine(\"You have selected too much code for it to be displayed automatically.\");\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\toutput.WriteLine(\"You have selected too much code; it cannot be displayed here.\");\n\t\t\t}\n\t\t\toutput.WriteLine();\n\t\t\tif (wasNormalLimit)\n\t\t\t{\n\t\t\t\toutput.AddButton(\n\t\t\t\t\tImages.ViewCode, Properties.Resources.DisplayCode,\n\t\t\t\t\tdelegate {\n\t\t\t\t\t\tDoDecompile(context, ExtendedOutputLengthLimit).HandleExceptions();\n\t\t\t\t\t});\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\n\t\t\toutput.AddButton(\n\t\t\t\tImages.Save, Properties.Resources.SaveCode,\n\t\t\t\tdelegate {\n\t\t\t\t\tSaveToDisk(context.Language, context.TreeNodes, context.Options);\n\t\t\t\t});\n\t\t\toutput.WriteLine();\n\t\t}\n\t\t#endregion\n\n\t\t#region JumpToReference\n\t\t/// <summary>\n\t\t/// Jumps to the definition referred to by the <see cref=\"ReferenceSegment\"/>.\n\t\t/// </summary>\n\t\tinternal void JumpToReference(ReferenceSegment referenceSegment, bool openInNewTab)\n\t\t{\n\t\t\tobject reference = referenceSegment.Reference;\n\t\t\tif (referenceSegment.IsLocal)\n\t\t\t{\n\t\t\t\tClearLocalReferenceMarks();\n\t\t\t\tSetLocalReferenceMarks(reference);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (definitionLookup != null)\n\t\t\t{\n\t\t\t\tint pos = definitionLookup.GetDefinitionPosition(reference);\n\t\t\t\tif (pos >= 0)\n\t\t\t\t{\n\t\t\t\t\ttextEditor.TextArea.Focus();\n\t\t\t\t\ttextEditor.Select(pos, 0);\n\t\t\t\t\ttextEditor.ScrollTo(textEditor.TextArea.Caret.Line, textEditor.TextArea.Caret.Column);\n\t\t\t\t\tDispatcher.Invoke(DispatcherPriority.Background, new Action(\n\t\t\t\t\t\tdelegate {\n\t\t\t\t\t\t\tCaretHighlightAdorner.DisplayCaretHighlightAnimation(textEditor.TextArea);\n\t\t\t\t\t\t}));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(reference, openInNewTab));\n\t\t}\n\n\t\tprivate void SetLocalReferenceMarks(object reference)\n\t\t{\n\t\t\tif (references == null || reference == null)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tforeach (var r in references)\n\t\t\t{\n\t\t\t\tif (reference.Equals(r.Reference))\n\t\t\t\t{\n\t\t\t\t\tvar mark = textMarkerService.Create(r.StartOffset, r.Length);\n\t\t\t\t\tmark.BackgroundColor = (Color)(r.IsDefinition ? FindResource(ResourceKeys.TextMarkerDefinitionBackgroundColor) : FindResource(ResourceKeys.TextMarkerBackgroundColor));\n\t\t\t\t\tlocalReferenceMarks.Add(mark);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tPoint? mouseDownPos;\n\n\t\tvoid TextAreaMouseDown(object sender, MouseButtonEventArgs e)\n\t\t{\n\t\t\tmouseDownPos = e.GetPosition(this);\n\t\t}\n\n\t\tvoid TextAreaMouseUp(object sender, MouseButtonEventArgs e)\n\t\t{\n\t\t\tif (mouseDownPos == null)\n\t\t\t\treturn;\n\t\t\tVector dragDistance = e.GetPosition(this) - mouseDownPos.Value;\n\t\t\tif (Math.Abs(dragDistance.X) < SystemParameters.MinimumHorizontalDragDistance\n\t\t\t\t&& Math.Abs(dragDistance.Y) < SystemParameters.MinimumVerticalDragDistance\n\t\t\t\t&& (e.ChangedButton == MouseButton.Left || e.ChangedButton == MouseButton.Middle))\n\t\t\t{\n\t\t\t\t// click without moving mouse\n\t\t\t\tvar referenceSegment = GetReferenceSegmentAtMousePosition();\n\t\t\t\tif (referenceSegment == null)\n\t\t\t\t{\n\t\t\t\t\tClearLocalReferenceMarks();\n\t\t\t\t}\n\t\t\t\telse if (referenceSegment.IsLocal || !referenceSegment.IsDefinition)\n\t\t\t\t{\n\t\t\t\t\ttextEditor.TextArea.ClearSelection();\n\t\t\t\t\t// cancel mouse selection to avoid AvalonEdit selecting between the new\n\t\t\t\t\t// cursor position and the mouse position.\n\t\t\t\t\ttextEditor.TextArea.MouseSelectionMode = MouseSelectionMode.None;\n\n\t\t\t\t\tJumpToReference(referenceSegment, e.ChangedButton == MouseButton.Middle || Keyboard.Modifiers.HasFlag(ModifierKeys.Shift));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid ClearLocalReferenceMarks()\n\t\t{\n\t\t\tforeach (var mark in localReferenceMarks)\n\t\t\t{\n\t\t\t\ttextMarkerService.Remove(mark);\n\t\t\t}\n\t\t\tlocalReferenceMarks.Clear();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Filters all ReferenceSegments that are no real links.\n\t\t/// </summary>\n\t\tbool IsLink(ReferenceSegment referenceSegment)\n\t\t{\n\t\t\treturn referenceSegment.IsLocal || !referenceSegment.IsDefinition;\n\t\t}\n\t\t#endregion\n\n\t\t#region SaveToDisk\n\t\t/// <summary>\n\t\t/// Shows the 'save file dialog', prompting the user to save the decompiled nodes to disk.\n\t\t/// </summary>\n\t\tpublic void SaveToDisk(ILSpy.Language language, IEnumerable<ILSpyTreeNode> treeNodes, DecompilationOptions options)\n\t\t{\n\t\t\tif (!treeNodes.Any())\n\t\t\t\treturn;\n\n\t\t\tSaveFileDialog dlg = new SaveFileDialog();\n\t\t\tdlg.DefaultExt = language.FileExtension;\n\t\t\tdlg.Filter = language.Name + \"|*\" + language.FileExtension + Properties.Resources.AllFiles;\n\t\t\tstring? nodeText = treeNodes.First().Text?.ToString();\n\t\t\tif (!string.IsNullOrWhiteSpace(nodeText))\n\t\t\t{\n\t\t\t\tdlg.FileName = WholeProjectDecompiler.CleanUpFileName(nodeText, language.FileExtension);\n\t\t\t}\n\t\t\tif (dlg.ShowDialog() == true)\n\t\t\t{\n\t\t\t\tSaveToDisk(new DecompilationContext(language, treeNodes.ToArray(), options), dlg.FileName);\n\t\t\t}\n\t\t}\n\n\t\tpublic void SaveToDisk(ILSpy.Language language, IEnumerable<ILSpyTreeNode> treeNodes, DecompilationOptions options, string fileName)\n\t\t{\n\t\t\tSaveToDisk(new DecompilationContext(language, treeNodes.ToArray(), options), fileName);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Starts the decompilation of the given nodes.\n\t\t/// The result will be saved to the given file name.\n\t\t/// </summary>\n\t\tvoid SaveToDisk(DecompilationContext context, string fileName)\n\t\t{\n\t\t\tRunWithCancellation(\n\t\t\t\tdelegate (CancellationToken ct) {\n\t\t\t\t\tcontext.Options.CancellationToken = ct;\n\t\t\t\t\treturn SaveToDiskAsync(context, fileName);\n\t\t\t\t})\n\t\t\t\t.Then(output => ShowOutput(output))\n\t\t\t\t.Catch((Exception ex) => {\n\t\t\t\t\ttextEditor.SyntaxHighlighting = null;\n\t\t\t\t\tDebug.WriteLine(\"Decompiler crashed: \" + ex.ToString());\n\t\t\t\t\t// Unpack aggregate exceptions as long as there's only a single exception:\n\t\t\t\t\t// (assembly load errors might produce nested aggregate exceptions)\n\t\t\t\t\tAvalonEditTextOutput output = new AvalonEditTextOutput();\n\t\t\t\t\toutput.WriteLine(ex.ToString());\n\t\t\t\t\tShowOutput(output);\n\t\t\t\t}).HandleExceptions();\n\t\t}\n\n\t\tTask<AvalonEditTextOutput> SaveToDiskAsync(DecompilationContext context, string fileName)\n\t\t{\n\t\t\tTaskCompletionSource<AvalonEditTextOutput> tcs = new TaskCompletionSource<AvalonEditTextOutput>();\n\t\t\tThread thread = new Thread(new ThreadStart(\n\t\t\t\tdelegate {\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tbool originalProjectFormatSetting = context.Options.DecompilerSettings.UseSdkStyleProjectFormat;\n\t\t\t\t\t\tcontext.Options.EscapeInvalidIdentifiers = true;\n\t\t\t\t\t\tcontext.Options.Progress = this;\n\t\t\t\t\t\tAvalonEditTextOutput output = new AvalonEditTextOutput {\n\t\t\t\t\t\t\tEnableHyperlinks = true,\n\t\t\t\t\t\t\tTitle = string.Join(\", \", context.TreeNodes.Select(n => n.Text))\n\t\t\t\t\t\t};\n\t\t\t\t\t\tStopwatch stopwatch = new Stopwatch();\n\t\t\t\t\t\tstopwatch.Start();\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tusing (StreamWriter w = new StreamWriter(fileName))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tDecompileNodes(context, new PlainTextOutput(w));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch (OperationCanceledException)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tw.WriteLine();\n\t\t\t\t\t\t\t\t\tw.WriteLine(Properties.Resources.DecompilationWasCancelled);\n\t\t\t\t\t\t\t\t\tthrow;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcatch (PathTooLongException pathTooLong) when (context.Options.SaveAsProjectDirectory != null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\toutput.WriteLine(Properties.Resources.ProjectExportPathTooLong, string.Join(\", \", context.TreeNodes.Select(n => n.Text)));\n\t\t\t\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t\t\t\t\toutput.WriteLine(pathTooLong.ToString());\n\t\t\t\t\t\t\t\t\ttcs.SetResult(output);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinally\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstopwatch.Stop();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\toutput.WriteLine(Properties.Resources.DecompilationCompleteInF1Seconds, stopwatch.Elapsed.TotalSeconds);\n\t\t\t\t\t\tif (context.Options.SaveAsProjectDirectory != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t\t\tbool useSdkStyleProjectFormat = context.Options.DecompilerSettings.UseSdkStyleProjectFormat;\n\t\t\t\t\t\t\tif (useSdkStyleProjectFormat)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutput.WriteLine(Properties.Resources.ProjectExportFormatSDKHint);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutput.WriteLine(Properties.Resources.ProjectExportFormatNonSDKHint);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\toutput.WriteLine(Properties.Resources.ProjectExportFormatChangeSettingHint);\n\t\t\t\t\t\t\tif (originalProjectFormatSetting != useSdkStyleProjectFormat)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutput.WriteLine(Properties.Resources.CouldNotUseSdkStyleProjectFormat);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t\toutput.AddButton(null, Properties.Resources.OpenExplorer, delegate { ShellHelper.OpenFolderAndSelectItem(fileName); });\n\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t\ttcs.SetResult(output);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (OperationCanceledException)\n\t\t\t\t\t{\n\t\t\t\t\t\ttcs.SetCanceled();\n\t\t\t\t\t}\n\t\t\t\t\tcatch (Exception ex)\n\t\t\t\t\t{\n\t\t\t\t\t\ttcs.SetException(ex);\n\t\t\t\t\t}\n\t\t\t\t}));\n\t\t\tthread.Start();\n\t\t\treturn tcs.Task;\n\t\t}\n\t\t#endregion\n\n\t\t#region Clipboard\n\t\tprivate void OnSettingData(object sender, DataObjectSettingDataEventArgs e)\n\t\t{\n\t\t\tif (e.Format == DataFormats.Html && e.DataObject is DataObject dataObject)\n\t\t\t{\n\t\t\t\te.CancelCommand();\n\t\t\t\tHtmlClipboard.SetHtml(dataObject, CreateHtmlFragmentFromSelection());\n\t\t\t}\n\t\t}\n\n\t\tprivate string CreateHtmlFragmentFromSelection()\n\t\t{\n\t\t\tvar options = new HtmlOptions(textEditor.TextArea.Options);\n\t\t\tvar highlighter = textEditor.TextArea.GetService(typeof(IHighlighter)) as IHighlighter;\n\t\t\tvar html = new StringBuilder();\n\n\t\t\tforeach (var segment in textEditor.TextArea.Selection.Segments)\n\t\t\t{\n\t\t\t\tvar line = textEditor.Document.GetLineByOffset(segment.StartOffset);\n\n\t\t\t\twhile (line != null && line.Offset < segment.EndOffset)\n\t\t\t\t{\n\t\t\t\t\tif (html.Length > 0)\n\t\t\t\t\t\thtml.AppendLine(\"<br>\");\n\n\t\t\t\t\tvar s = GetOverlap(segment, line);\n\t\t\t\t\tvar highlightedLine = highlighter?.HighlightLine(line.LineNumber) ?? new HighlightedLine(textEditor.Document, line);\n\n\t\t\t\t\tif (activeRichTextModel is not null)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar richTextHighlightedLine = new HighlightedLine(textEditor.Document, line);\n\t\t\t\t\t\tforeach (HighlightedSection richTextSection in activeRichTextModel.GetHighlightedSections(s.Offset, s.Length))\n\t\t\t\t\t\t\trichTextHighlightedLine.Sections.Add(richTextSection);\n\t\t\t\t\t\thighlightedLine.MergeWith(richTextHighlightedLine);\n\t\t\t\t\t}\n\n\t\t\t\t\thtml.Append(highlightedLine.ToHtml(s.Offset, s.Offset + s.Length, options));\n\t\t\t\t\tline = line.NextLine;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn html.ToString();\n\n\t\t\tstatic (int Offset, int Length) GetOverlap(ISegment segment1, ISegment segment2)\n\t\t\t{\n\t\t\t\tint start = Math.Max(segment1.Offset, segment2.Offset);\n\t\t\t\tint end = Math.Min(segment1.EndOffset, segment2.EndOffset);\n\t\t\t\treturn (start, end - start);\n\t\t\t}\n\t\t}\n\t\t#endregion\n\n\t\tinternal ReferenceSegment? GetReferenceSegmentAtMousePosition()\n\t\t{\n\t\t\tif (referenceElementGenerator.References == null)\n\t\t\t\treturn null;\n\t\t\tTextViewPosition? position = GetPositionFromMousePosition();\n\t\t\tif (position == null)\n\t\t\t\treturn null;\n\t\t\tint offset = textEditor.Document.GetOffset(position.Value.Location);\n\t\t\treturn referenceElementGenerator.References.FindSegmentsContaining(offset).FirstOrDefault();\n\t\t}\n\n\t\tinternal TextViewPosition? GetPositionFromMousePosition()\n\t\t{\n\t\t\tvar position = textEditor.TextArea.TextView.GetPosition(Mouse.GetPosition(textEditor.TextArea.TextView) + textEditor.TextArea.TextView.ScrollOffset);\n\t\t\tif (position == null)\n\t\t\t\treturn null;\n\t\t\tvar lineLength = textEditor.Document.GetLineByNumber(position.Value.Line).Length + 1;\n\t\t\tif (position.Value.Column == lineLength)\n\t\t\t\treturn null;\n\t\t\treturn position;\n\t\t}\n\n\t\tpublic DecompilerTextViewState? GetState()\n\t\t{\n\t\t\tif (decompiledNodes == null && currentAddress == null)\n\t\t\t\treturn null;\n\n\t\t\tvar state = new DecompilerTextViewState();\n\t\t\tif (foldingManager != null)\n\t\t\t\tstate.SaveFoldingsState(foldingManager.AllFoldings);\n\t\t\tstate.VerticalOffset = textEditor.VerticalOffset;\n\t\t\tstate.HorizontalOffset = textEditor.HorizontalOffset;\n\t\t\tstate.ExpandMemberDefinitions = expandMemberDefinitions;\n\t\t\tstate.DecompiledNodes = decompiledNodes == null ? null : new HashSet<ILSpyTreeNode>(decompiledNodes);\n\t\t\tstate.ViewedUri = currentAddress;\n\t\t\treturn state;\n\t\t}\n\n\t\tViewState? IHaveState.GetState() => GetState();\n\n\t\tpublic static void RegisterHighlighting()\n\t\t{\n\t\t\tHighlightingManager.Instance.RegisterHighlighting(\"ILAsm\", new[] { \".il\" }, \"ILAsm-Mode\");\n\t\t\tHighlightingManager.Instance.RegisterHighlighting(\"C#\", new[] { \".cs\" }, \"CSharp-Mode\");\n\t\t\tHighlightingManager.Instance.RegisterHighlighting(\"Asm\", new[] { \".s\", \".asm\" }, \"Asm-Mode\");\n\t\t\tHighlightingManager.Instance.RegisterHighlighting(\"xml\", new[] { \".xml\", \".baml\" }, \"XML-Mode\");\n\t\t}\n\n\t\t#region Unfold\n\t\tpublic void UnfoldAndScroll(int lineNumber)\n\t\t{\n\t\t\tif (lineNumber <= 0 || lineNumber > textEditor.Document.LineCount)\n\t\t\t\treturn;\n\t\t\tif (foldingManager == null)\n\t\t\t\treturn;\n\n\t\t\tvar line = textEditor.Document.GetLineByNumber(lineNumber);\n\n\t\t\t// unfold\n\t\t\tvar foldings = foldingManager.GetFoldingsContaining(line.Offset);\n\t\t\tif (foldings != null)\n\t\t\t{\n\t\t\t\tforeach (var folding in foldings)\n\t\t\t\t{\n\t\t\t\t\tif (folding.IsFolded)\n\t\t\t\t\t{\n\t\t\t\t\t\tfolding.IsFolded = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// scroll to\n\t\t\ttextEditor.ScrollTo(lineNumber, 0);\n\t\t}\n\n\t\tpublic FoldingManager? FoldingManager {\n\t\t\tget {\n\t\t\t\treturn foldingManager;\n\t\t\t}\n\t\t}\n\t\t#endregion\n\t}\n\n\t[DebuggerDisplay($\"{{{nameof(GetDebuggerDisplay)}(),nq}}\")]\n\tpublic class ViewState : IEquatable<ViewState>\n\t{\n\t\tpublic HashSet<ILSpyTreeNode>? DecompiledNodes;\n\t\tpublic Uri? ViewedUri;\n\n\t\tpublic virtual bool Equals(ViewState? other)\n\t\t{\n\t\t\treturn other != null\n\t\t\t\t&& ViewedUri == other.ViewedUri\n\t\t\t\t&& NullSafeSetEquals(DecompiledNodes, other.DecompiledNodes);\n\n\t\t\tstatic bool NullSafeSetEquals(HashSet<ILSpyTreeNode>? a, HashSet<ILSpyTreeNode>? b)\n\t\t\t{\n\t\t\t\tif (a == b)\n\t\t\t\t\treturn true;\n\t\t\t\tif (a == null || b == null)\n\t\t\t\t\treturn false;\n\t\t\t\treturn a.SetEquals(b);\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual string GetDebuggerDisplay()\n\t\t{\n\t\t\treturn $\"Nodes = {DecompiledNodes?.Count.ToString() ?? \"<null>\"}, ViewedUri = {ViewedUri?.ToString() ?? \"<null>\"}\";\n\t\t}\n\t}\n\n\tpublic class DecompilerTextViewState : ViewState\n\t{\n\t\tprivate List<(int StartOffset, int EndOffset)>? ExpandedFoldings;\n\t\tprivate int FoldingsChecksum;\n\t\tpublic bool ExpandMemberDefinitions;\n\t\tpublic double VerticalOffset;\n\t\tpublic double HorizontalOffset;\n\n\t\tpublic void SaveFoldingsState(IEnumerable<FoldingSection> foldings)\n\t\t{\n\t\t\tExpandedFoldings = foldings.Where(f => !f.IsFolded)\n\t\t\t\t.Select(f => (f.StartOffset, f.EndOffset)).ToList();\n\t\t\tFoldingsChecksum = unchecked(foldings.Select(f => f.StartOffset * 3 - f.EndOffset)\n\t\t\t\t.DefaultIfEmpty()\n\t\t\t\t.Aggregate((a, b) => a + b));\n\t\t}\n\n\t\tinternal void RestoreFoldings(List<NewFolding> list, bool expandMemberDefinitions)\n\t\t{\n\t\t\tif (ExpandedFoldings == null)\n\t\t\t\treturn;\n\t\t\tvar checksum = unchecked(list.Select(f => f.StartOffset * 3 - f.EndOffset)\n\t\t\t\t.DefaultIfEmpty()\n\t\t\t\t.Aggregate((a, b) => a + b));\n\t\t\tif (FoldingsChecksum == checksum)\n\t\t\t{\n\t\t\t\tforeach (var folding in list)\n\t\t\t\t{\n\t\t\t\t\tbool wasExpanded = ExpandedFoldings.Any(\n\t\t\t\t\t\tf => f.StartOffset == folding.StartOffset\n\t\t\t\t\t\t\t&& f.EndOffset == folding.EndOffset\n\t\t\t\t\t);\n\t\t\t\t\tbool isExpanded = !folding.DefaultClosed;\n\t\t\t\t\t// State of the folding was changed\n\t\t\t\t\tif (wasExpanded != isExpanded)\n\t\t\t\t\t{\n\t\t\t\t\t\t// The \"ExpandMemberDefinitions\" setting was not changed\n\t\t\t\t\t\tif (expandMemberDefinitions == ExpandMemberDefinitions)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// restore fold state\n\t\t\t\t\t\t\tfolding.DefaultClosed = !wasExpanded;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// only restore fold state if fold was not a definition\n\t\t\t\t\t\t\tif (!folding.IsDefinition)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfolding.DefaultClosed = !wasExpanded;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool Equals(ViewState? other)\n\t\t{\n\t\t\tif (other is DecompilerTextViewState vs)\n\t\t\t{\n\t\t\t\treturn base.Equals(vs)\n\t\t\t\t\t&& FoldingsChecksum == vs.FoldingsChecksum\n\t\t\t\t\t&& VerticalOffset == vs.VerticalOffset\n\t\t\t\t\t&& HorizontalOffset == vs.HorizontalOffset;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tprotected override string GetDebuggerDisplay()\n\t\t{\n\t\t\treturn $\"{base.GetDebuggerDisplay()}, ExpandMemberDefinitions = {ExpandMemberDefinitions}, VerticalOffset = {VerticalOffset}, HorizontalOffset = {HorizontalOffset}, FoldingsChecksum = {FoldingsChecksum}\";\n\t\t}\n\t}\n\n\tstatic class ExtensionMethods\n\t{\n\t\tpublic static void RegisterHighlighting(\n\t\t\tthis HighlightingManager manager,\n\t\t\tstring name,\n\t\t\tstring[] extensions,\n\t\t\tstring resourceName)\n\t\t{\n\t\t\tStream? resourceStream = typeof(DecompilerTextView).Assembly\n\t\t\t\t.GetManifestResourceStream(typeof(DecompilerTextView), resourceName + \".xshd\");\n\n\t\t\tif (resourceStream != null)\n\t\t\t{\n\t\t\t\tIHighlightingDefinition highlightingDefinition;\n\n\t\t\t\tusing (resourceStream)\n\t\t\t\tusing (XmlTextReader reader = new XmlTextReader(resourceStream))\n\t\t\t\t{\n\t\t\t\t\thighlightingDefinition = HighlightingLoader.Load(reader, manager);\n\t\t\t\t}\n\n\t\t\t\tmanager.RegisterHighlighting(\n\t\t\t\tname, extensions,\n\t\t\t\tdelegate {\n\t\t\t\t\tThemeManager.Current.ApplyHighlightingColors(highlightingDefinition);\n\t\t\t\t\treturn highlightingDefinition;\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// Converter to multiply a double by a factor provided as ConverterParameter\n\tpublic class MultiplyConverter : IValueConverter\n\t{\n\t\tpublic object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n\t\t{\n\t\t\tif (value is double d && parameter != null)\n\t\t\t{\n\t\t\t\tif (double.TryParse(parameter.ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out double factor))\n\t\t\t\t{\n\t\t\t\t\treturn d * factor;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn Binding.DoNothing;\n\t\t}\n\n\t\tpublic object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n\t\t{\n\t\t\tthrow new NotSupportedException();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TextView/DecompilerTextView.xaml",
    "content": "<UserControl x:Class=\"ICSharpCode.ILSpy.TextView.DecompilerTextView\" x:Name=\"self\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:properties=\"clr-namespace:ICSharpCode.ILSpy.Properties\"\n             xmlns:controls=\"clr-namespace:ICSharpCode.ILSpy.Controls\"\n             xmlns:local=\"clr-namespace:ICSharpCode.ILSpy.TextView\"\n             xmlns:editing=\"clr-namespace:ICSharpCode.AvalonEdit.Editing;assembly=ICSharpCode.AvalonEdit\"\n             xmlns:folding=\"clr-namespace:ICSharpCode.AvalonEdit.Folding;assembly=ICSharpCode.AvalonEdit\"\n             xmlns:styles=\"urn:TomsToolbox.Wpf.Styles\"\n             xmlns:themes=\"clr-namespace:ICSharpCode.ILSpy.Themes\">\n\t<UserControl.Resources>\n\t\t<SolidColorBrush x:Key=\"waitAdornerBackgoundBrush\" Color=\"{DynamicResource {x:Static SystemColors.WindowColorKey}}\" Opacity=\".75\" />\n\t\t<Style TargetType=\"{x:Type editing:TextArea}\">\n\t\t\t<Setter Property=\"FocusVisualStyle\" Value=\"{x:Null}\" />\n\t\t\t<Setter Property=\"SelectionForeground\" Value=\"{x:Null}\" />\n\t\t\t<Setter Property=\"SelectionCornerRadius\" Value=\"0.0\" />\n\t\t\t<Setter Property=\"SelectionBrush\">\n\t\t\t\t<Setter.Value>\n\t\t\t\t\t<SolidColorBrush Color=\"{DynamicResource {x:Static SystemColors.HighlightColorKey}}\" Opacity=\"0.3\" />\n\t\t\t\t</Setter.Value>\n\t\t\t</Setter>\n\t\t\t<Setter Property=\"SelectionBorder\">\n\t\t\t\t<Setter.Value>\n\t\t\t\t\t<Pen Brush=\"{DynamicResource {x:Static SystemColors.HighlightBrushKey}}\" Thickness=\"0\" />\n\t\t\t\t</Setter.Value>\n\t\t\t</Setter>\n\t\t</Style>\n\t\t<!-- Converter to compute a fraction of the control width for MaxWidth bindings -->\n\t\t<local:MultiplyConverter x:Key=\"MultiplyConverter\" />\n\t</UserControl.Resources>\n\t<Grid>\n\t\t<Border BorderThickness=\"1,1,0,1\" BorderBrush=\"{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}\">\n\t\t\t<Grid>\n\t\t\t\t<local:DecompilerTextEditor x:Name=\"textEditor\" AutomationProperties.Name=\"Decompilation\" FontFamily=\"Consolas\" FontSize=\"10pt\" IsReadOnly=\"True\"\n\t\t\t\t                            Background=\"{DynamicResource {x:Static themes:ResourceKeys.TextBackgroundBrush}}\"\n\t\t\t\t                            Foreground=\"{DynamicResource {x:Static themes:ResourceKeys.TextForegroundBrush}}\"\n\t\t\t\t                            LineNumbersForeground=\"{DynamicResource {x:Static themes:ResourceKeys.LineNumbersForegroundBrush}}\"\n\t\t\t\t                            folding:FoldingMargin.FoldingMarkerBackgroundBrush=\"{DynamicResource {x:Static SystemColors.WindowBrushKey}}\"\n\t\t\t\t                            folding:FoldingMargin.SelectedFoldingMarkerBackgroundBrush=\"{DynamicResource {x:Static SystemColors.WindowBrushKey}}\"\n\t\t\t\t                            folding:FoldingMargin.FoldingMarkerBrush=\"{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}\"\n\t\t\t\t                            folding:FoldingMargin.SelectedFoldingMarkerBrush=\"{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}\">\n\t\t\t\t\t<local:DecompilerTextEditor.Resources>\n\t\t\t\t\t\t<!-- prevent App-wide button style from applying to the buttons in the search box -->\n\t\t\t\t\t\t<Style TargetType=\"{x:Type Button}\">\n\t\t\t\t\t\t\t<Setter Property=\"Background\" Value=\"{DynamicResource {x:Static SystemColors.ControlBrushKey}}\" />\n\t\t\t\t\t\t\t<Setter Property=\"BorderBrush\" Value=\"{DynamicResource {x:Static styles:ResourceKeys.BorderBrush}}\" />\n\t\t\t\t\t\t\t<Setter Property=\"HorizontalContentAlignment\" Value=\"Center\" />\n\t\t\t\t\t\t\t<Setter Property=\"VerticalContentAlignment\" Value=\"Center\" />\n\t\t\t\t\t\t\t<Setter Property=\"Template\">\n\t\t\t\t\t\t\t\t<Setter.Value>\n\t\t\t\t\t\t\t\t\t<ControlTemplate TargetType=\"Button\">\n\t\t\t\t\t\t\t\t\t\t<Border BorderThickness=\"1\"\n\t\t\t\t\t\t\t\t\t\t        Background=\"{TemplateBinding Background}\"\n\t\t\t\t\t\t\t\t\t\t        BorderBrush=\"{TemplateBinding BorderBrush}\"\n\t\t\t\t\t\t\t\t\t\t        Padding=\"{TemplateBinding Padding}\">\n\t\t\t\t\t\t\t\t\t\t\t<ContentPresenter HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\"\n\t\t\t\t\t\t\t\t\t\t\t                  VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\" />\n\t\t\t\t\t\t\t\t\t\t</Border>\n\t\t\t\t\t\t\t\t\t</ControlTemplate>\n\t\t\t\t\t\t\t\t</Setter.Value>\n\t\t\t\t\t\t\t</Setter>\n\t\t\t\t\t\t\t<Style.Triggers>\n\t\t\t\t\t\t\t\t<Trigger Property=\"IsMouseOver\" Value=\"True\">\n\t\t\t\t\t\t\t\t\t<Setter Property=\"Background\" Value=\"{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}\" />\n\t\t\t\t\t\t\t\t</Trigger>\n\t\t\t\t\t\t\t</Style.Triggers>\n\t\t\t\t\t\t</Style>\n\t\t\t\t\t</local:DecompilerTextEditor.Resources>\n\t\t\t\t\t<local:DecompilerTextEditor.Template>\n\t\t\t\t\t\t<ControlTemplate TargetType=\"{x:Type local:DecompilerTextEditor}\">\n\t\t\t\t\t\t\t<controls:ZoomScrollViewer\n\t\t\t\t\t\t\t\tFocusable=\"False\"\n\t\t\t\t\t\t\t\tx:Name=\"PART_ScrollViewer\"\n\t\t\t\t\t\t\t\tMouseWheelZoom=\"True\"\n\t\t\t\t\t\t\t\tCanContentScroll=\"True\"\n\t\t\t\t\t\t\t\tVerticalScrollBarVisibility=\"Visible\"\n\t\t\t\t\t\t\t\tHorizontalScrollBarVisibility=\"Visible\"\n\t\t\t\t\t\t\t\tContent=\"{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TextArea}\"\n\t\t\t\t\t\t\t\tVerticalContentAlignment=\"Top\"\n\t\t\t\t\t\t\t\tHorizontalContentAlignment=\"Left\"\n\t\t\t\t\t\t\t\tBackground=\"{TemplateBinding Background}\"\n\t\t\t\t\t\t\t\tPadding=\"{TemplateBinding Padding}\"\n\t\t\t\t\t\t\t\tBorderBrush=\"{TemplateBinding BorderBrush}\"\n\t\t\t\t\t\t\t\tBorderThickness=\"{TemplateBinding BorderThickness}\"\n\t\t\t\t\t\t\t\tTextOptions.TextFormattingMode=\"{Binding CurrentZoom, ElementName=PART_ScrollViewer, Converter={x:Static local:ZoomLevelToTextFormattingModeConverter.Instance}}\"/>\n\t\t\t\t\t\t\t<ControlTemplate.Triggers>\n\t\t\t\t\t\t\t\t<Trigger Property=\"WordWrap\"\n\t\t\t\t\t\t\t\t         Value=\"True\">\n\t\t\t\t\t\t\t\t\t<Setter TargetName=\"PART_ScrollViewer\"\n\t\t\t\t\t\t\t\t\t        Property=\"HorizontalScrollBarVisibility\"\n\t\t\t\t\t\t\t\t\t        Value=\"Disabled\" />\n\t\t\t\t\t\t\t\t</Trigger>\n\t\t\t\t\t\t\t</ControlTemplate.Triggers>\n\t\t\t\t\t\t</ControlTemplate>\n\t\t\t\t\t</local:DecompilerTextEditor.Template>\n\t\t\t\t</local:DecompilerTextEditor>\n\t\t\t\t<Border Name=\"waitAdorner\" Background=\"{StaticResource waitAdornerBackgoundBrush}\" Visibility=\"Collapsed\">\n\t\t\t\t\t<Grid>\n\t\t\t\t\t\t<Grid.ColumnDefinitions>\n\t\t\t\t\t\t\t<ColumnDefinition Width=\"*\" />\n\t\t\t\t\t\t\t<!-- make center column auto-sized to content so it expands with the title -->\n\t\t\t\t\t\t\t<ColumnDefinition Width=\"Auto\" />\n\t\t\t\t\t\t\t<ColumnDefinition Width=\"*\" />\n\t\t\t\t\t\t</Grid.ColumnDefinitions>\n\t\t\t\t\t\t<StackPanel Grid.Column=\"1\" VerticalAlignment=\"Center\" HorizontalAlignment=\"Center\" MaxWidth=\"{Binding ActualWidth, ElementName=self, Converter={StaticResource MultiplyConverter}, ConverterParameter=0.75}\">\n\t\t\t\t\t\t\t<TextBlock Name=\"progressTitle\" FontSize=\"14pt\" Text=\"{x:Static properties:Resources.Decompiling}\" Margin=\"3\" TextWrapping=\"Wrap\" HorizontalAlignment=\"Center\" TextAlignment=\"Center\" />\n\t\t\t\t\t\t\t<ProgressBar Name=\"progressBar\" Height=\"16\" Width=\"{Binding ActualWidth, ElementName=self, Converter={StaticResource MultiplyConverter}, ConverterParameter=0.75}\" />\n\t\t\t\t\t\t\t<TextBlock Name=\"progressText\" Visibility=\"Collapsed\" Margin=\"3\" />\n\t\t\t\t\t\t\t<Button Click=\"CancelButton_Click\" HorizontalAlignment=\"Center\" Margin=\"3\" Content=\"{x:Static properties:Resources.Cancel}\" />\n\t\t\t\t\t\t</StackPanel>\n\t\t\t\t\t</Grid>\n\t\t\t\t</Border>\n\t\t\t</Grid>\n\t\t</Border>\n\t</Grid>\n</UserControl>"
  },
  {
    "path": "ILSpy/TextView/DocumentationUIBuilder.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Text;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Documents;\nusing System.Windows.Media;\nusing System.Xml.Linq;\n\nusing ICSharpCode.AvalonEdit.Document;\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.AvalonEdit.Utils;\nusing ICSharpCode.Decompiler.Documentation;\nusing ICSharpCode.Decompiler.Output;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.Options;\n\nnamespace ICSharpCode.ILSpy.TextView\n{\n\t/// <summary>\n\t/// Renders XML documentation into a WPF <see cref=\"FlowDocument\"/>.\n\t/// </summary>\n\tpublic class DocumentationUIBuilder\n\t{\n\t\treadonly IAmbience ambience;\n\t\treadonly IHighlightingDefinition highlightingDefinition;\n\t\treadonly DisplaySettings displaySettings;\n\t\treadonly MainWindow mainWindow;\n\t\treadonly FlowDocument document;\n\t\tBlockCollection blockCollection;\n\t\tInlineCollection inlineCollection;\n\n\t\tpublic DocumentationUIBuilder(IAmbience ambience, IHighlightingDefinition highlightingDefinition, DisplaySettings displaySettings, MainWindow mainWindow)\n\t\t{\n\t\t\tthis.ambience = ambience;\n\t\t\tthis.highlightingDefinition = highlightingDefinition;\n\t\t\tthis.displaySettings = displaySettings;\n\t\t\tthis.mainWindow = mainWindow;\n\t\t\tthis.document = new FlowDocument();\n\t\t\tthis.blockCollection = document.Blocks;\n\n\t\t\tthis.ShowSummary = true;\n\t\t\tthis.ShowAllParameters = true;\n\t\t\tthis.ShowReturns = true;\n\t\t\tthis.ShowThreadSafety = true;\n\t\t\tthis.ShowExceptions = true;\n\t\t\tthis.ShowTypeParameters = true;\n\n\t\t\tthis.ShowExample = true;\n\t\t\tthis.ShowPreliminary = true;\n\t\t\tthis.ShowSeeAlso = true;\n\t\t\tthis.ShowValue = true;\n\t\t\tthis.ShowPermissions = true;\n\t\t\tthis.ShowRemarks = true;\n\t\t}\n\n\t\tpublic FlowDocument CreateDocument()\n\t\t{\n\t\t\tFlushAddedText(true);\n\t\t\treturn document;\n\t\t}\n\n\t\tpublic bool ShowExceptions { get; set; }\n\t\tpublic bool ShowPermissions { get; set; }\n\t\tpublic bool ShowExample { get; set; }\n\t\tpublic bool ShowPreliminary { get; set; }\n\t\tpublic bool ShowRemarks { get; set; }\n\t\tpublic bool ShowSummary { get; set; }\n\t\tpublic bool ShowReturns { get; set; }\n\t\tpublic bool ShowSeeAlso { get; set; }\n\t\tpublic bool ShowThreadSafety { get; set; }\n\t\tpublic bool ShowTypeParameters { get; set; }\n\t\tpublic bool ShowValue { get; set; }\n\t\tpublic bool ShowAllParameters { get; set; }\n\n\t\tpublic void AddCodeBlock(string textContent, bool keepLargeMargin = false)\n\t\t{\n\t\t\tvar document = new TextDocument(textContent);\n\t\t\tvar highlighter = new DocumentHighlighter(document, highlightingDefinition);\n\t\t\tvar richText = DocumentPrinter.ConvertTextDocumentToRichText(document, highlighter).ToRichTextModel();\n\n\t\t\tvar block = new Paragraph();\n\t\t\tblock.Inlines.AddRange(richText.CreateRuns(document));\n\t\t\tblock.FontFamily = GetCodeFont();\n\t\t\tif (!keepLargeMargin)\n\t\t\t\tblock.Margin = new Thickness(0, 6, 0, 6);\n\t\t\tAddBlock(block);\n\t\t}\n\n\t\tpublic void AddSignatureBlock(string signature, RichTextModel highlighting = null)\n\t\t{\n\t\t\tvar document = new TextDocument(signature);\n\t\t\tvar richText = highlighting ?? DocumentPrinter.ConvertTextDocumentToRichText(document, new DocumentHighlighter(document, highlightingDefinition)).ToRichTextModel();\n\t\t\tvar block = new Paragraph();\n\t\t\t// HACK: measure width of signature using a TextBlock\n\t\t\t// Paragraph sadly does not support TextWrapping.NoWrap\n\t\t\tvar text = new TextBlock {\n\t\t\t\tFontFamily = GetCodeFont(),\n\t\t\t\tFontSize = displaySettings.SelectedFontSize,\n\t\t\t\tTextAlignment = TextAlignment.Left\n\t\t\t};\n\t\t\ttext.Inlines.AddRange(richText.CreateRuns(document));\n\t\t\ttext.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));\n\t\t\tthis.document.MinPageWidth = Math.Min(text.DesiredSize.Width, mainWindow.ActualWidth);\n\t\t\tblock.Inlines.AddRange(richText.CreateRuns(document));\n\t\t\tblock.FontFamily = GetCodeFont();\n\t\t\tblock.TextAlignment = TextAlignment.Left;\n\t\t\tAddBlock(block);\n\t\t}\n\n\t\tpublic void AddXmlDocumentation(string xmlDocumentation, IEntity declaringEntity, Func<string, IEntity> resolver)\n\t\t{\n\t\t\tif (xmlDocumentation == null)\n\t\t\t\treturn;\n\t\t\tDebug.WriteLine(xmlDocumentation);\n\t\t\tvar xml = XElement.Parse(\"<doc>\" + xmlDocumentation + \"</doc>\");\n\t\t\tAddDocumentationElement(new XmlDocumentationElement(xml, declaringEntity, resolver));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets/Sets the name of the parameter that should be shown.\n\t\t/// </summary>\n\t\tpublic string ParameterName { get; set; }\n\n\t\tpublic void AddDocumentationElement(XmlDocumentationElement element)\n\t\t{\n\t\t\tif (element == null)\n\t\t\t\tthrow new ArgumentNullException(\"element\");\n\t\t\tif (element.IsTextNode)\n\t\t\t{\n\t\t\t\tAddText(element.TextContent);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tswitch (element.Name)\n\t\t\t{\n\t\t\t\tcase \"b\":\n\t\t\t\t\tAddSpan(new Bold(), element.Children);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"i\":\n\t\t\t\t\tAddSpan(new Italic(), element.Children);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"c\":\n\t\t\t\t\tAddSpan(new Span { FontFamily = GetCodeFont() }, element.Children);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"code\":\n\t\t\t\t\tAddCodeBlock(element.TextContent);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"example\":\n\t\t\t\t\tif (ShowExample)\n\t\t\t\t\t\tAddSection(\"Example: \", element.Children);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"exception\":\n\t\t\t\t\tif (ShowExceptions)\n\t\t\t\t\t\tAddException(element.ReferencedEntity, element.Children);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"list\":\n\t\t\t\t\tAddList(element.GetAttribute(\"type\"), element.Children);\n\t\t\t\t\tbreak;\n\t\t\t\t//case \"note\":\n\t\t\t\t//\tthrow new NotImplementedException();\n\t\t\t\tcase \"para\":\n\t\t\t\t\tAddParagraph(new Paragraph { Margin = new Thickness(0, 5, 0, 5) }, element.Children);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"param\":\n\t\t\t\t\tif (ShowAllParameters || (ParameterName != null && ParameterName == element.GetAttribute(\"name\")))\n\t\t\t\t\t\tAddParam(element.GetAttribute(\"name\"), element.Children);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"paramref\":\n\t\t\t\t\tAddParamRef(element.GetAttribute(\"name\"));\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"permission\":\n\t\t\t\t\tif (ShowPermissions)\n\t\t\t\t\t\tAddPermission(element.ReferencedEntity, element.Children);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"preliminary\":\n\t\t\t\t\tif (ShowPreliminary)\n\t\t\t\t\t\tAddPreliminary(element.Children);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"remarks\":\n\t\t\t\t\tif (ShowRemarks)\n\t\t\t\t\t\tAddSection(\"Remarks: \", element.Children);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"returns\":\n\t\t\t\t\tif (ShowReturns)\n\t\t\t\t\t\tAddSection(\"Returns: \", element.Children);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"see\":\n\t\t\t\t\tAddSee(element);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"seealso\":\n\t\t\t\t\tif (inlineCollection != null)\n\t\t\t\t\t\tAddSee(element);\n\t\t\t\t\telse if (ShowSeeAlso)\n\t\t\t\t\t\tAddSection(new Run(\"See also: \"), () => AddSee(element));\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"summary\":\n\t\t\t\t\tif (ShowSummary)\n\t\t\t\t\t\tAddSection(\"Summary: \", element.Children);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"threadsafety\":\n\t\t\t\t\tif (ShowThreadSafety)\n\t\t\t\t\t\tAddThreadSafety(ParseBool(element.GetAttribute(\"static\")), ParseBool(element.GetAttribute(\"instance\")), element.Children);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"typeparam\":\n\t\t\t\t\tif (ShowTypeParameters)\n\t\t\t\t\t\tAddSection(\"Type parameter \" + element.GetAttribute(\"name\") + \": \", element.Children);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"typeparamref\":\n\t\t\t\t\tAddText(element.GetAttribute(\"name\"));\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"value\":\n\t\t\t\t\tif (ShowValue)\n\t\t\t\t\t\tAddSection(\"Value: \", element.Children);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"exclude\":\n\t\t\t\tcase \"filterpriority\":\n\t\t\t\tcase \"overloads\":\n\t\t\t\t\t// ignore children\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"br\":\n\t\t\t\t\tAddLineBreak();\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tforeach (var child in element.Children)\n\t\t\t\t\t\tAddDocumentationElement(child);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tvoid AddList(string type, IEnumerable<XmlDocumentationElement> items)\n\t\t{\n\t\t\tList list = new List();\n\t\t\tAddBlock(list);\n\t\t\tlist.Margin = new Thickness(0, 5, 0, 5);\n\t\t\tif (type == \"number\")\n\t\t\t\tlist.MarkerStyle = TextMarkerStyle.Decimal;\n\t\t\telse if (type == \"bullet\")\n\t\t\t\tlist.MarkerStyle = TextMarkerStyle.Disc;\n\t\t\tvar oldBlockCollection = blockCollection;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tforeach (var itemElement in items)\n\t\t\t\t{\n\t\t\t\t\tif (itemElement.Name == \"listheader\" || itemElement.Name == \"item\")\n\t\t\t\t\t{\n\t\t\t\t\t\tListItem item = new ListItem();\n\t\t\t\t\t\tblockCollection = item.Blocks;\n\t\t\t\t\t\tinlineCollection = null;\n\t\t\t\t\t\tforeach (var prop in itemElement.Children)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tAddDocumentationElement(prop);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tFlushAddedText(false);\n\t\t\t\t\t\tlist.ListItems.Add(item);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tblockCollection = oldBlockCollection;\n\t\t\t}\n\t\t}\n\n\t\tbool? ParseBool(string input)\n\t\t{\n\t\t\tif (bool.TryParse(input, out bool result))\n\t\t\t\treturn result;\n\t\t\telse\n\t\t\t\treturn null;\n\t\t}\n\n\t\tvoid AddThreadSafety(bool? staticThreadSafe, bool? instanceThreadSafe, IEnumerable<XmlDocumentationElement> children)\n\t\t{\n\t\t\tAddSection(\n\t\t\t\tnew Run(\"Thread-safety: \"),\n\t\t\t\tdelegate {\n\t\t\t\t\tif (staticThreadSafe == true)\n\t\t\t\t\t\tAddText(\"Any public static members of this type are thread safe. \");\n\t\t\t\t\telse if (staticThreadSafe == false)\n\t\t\t\t\t\tAddText(\"The static members of this type are not thread safe. \");\n\n\t\t\t\t\tif (instanceThreadSafe == true)\n\t\t\t\t\t\tAddText(\"Any public instance members of this type are thread safe. \");\n\t\t\t\t\telse if (instanceThreadSafe == false)\n\t\t\t\t\t\tAddText(\"Any instance members are not guaranteed to be thread safe. \");\n\n\t\t\t\t\tforeach (var child in children)\n\t\t\t\t\t\tAddDocumentationElement(child);\n\t\t\t\t});\n\t\t}\n\n\t\tvoid AddException(IEntity referencedEntity, IList<XmlDocumentationElement> children)\n\t\t{\n\t\t\tSpan span = new Span();\n\t\t\tif (referencedEntity != null)\n\t\t\t\tspan.Inlines.Add(ConvertReference(referencedEntity));\n\t\t\telse\n\t\t\t\tspan.Inlines.Add(\"Exception\");\n\t\t\tspan.Inlines.Add(\": \");\n\t\t\tAddSection(span, children);\n\t\t}\n\n\t\tvoid AddPermission(IEntity referencedEntity, IList<XmlDocumentationElement> children)\n\t\t{\n\t\t\tSpan span = new Span();\n\t\t\tspan.Inlines.Add(\"Permission\");\n\t\t\tif (referencedEntity != null)\n\t\t\t{\n\t\t\t\tspan.Inlines.Add(\" \");\n\t\t\t\tspan.Inlines.Add(ConvertReference(referencedEntity));\n\t\t\t}\n\t\t\tspan.Inlines.Add(\": \");\n\t\t\tAddSection(span, children);\n\t\t}\n\n\t\tInline ConvertReference(IEntity referencedEntity)\n\t\t{\n\t\t\tvar h = new Hyperlink(new Run(ambience.ConvertSymbol(referencedEntity)));\n\t\t\th.Click += (sender, e) => {\n\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(referencedEntity));\n\t\t\t};\n\t\t\treturn h;\n\t\t}\n\n\t\tvoid AddParam(string name, IEnumerable<XmlDocumentationElement> children)\n\t\t{\n\t\t\tSpan span = new Span();\n\t\t\tspan.Inlines.Add(new Run(name ?? string.Empty) { FontStyle = FontStyles.Italic });\n\t\t\tspan.Inlines.Add(\": \");\n\t\t\tAddSection(span, children);\n\t\t}\n\n\t\tvoid AddParamRef(string name)\n\t\t{\n\t\t\tif (name != null)\n\t\t\t{\n\t\t\t\tAddInline(new Run(name) { FontStyle = FontStyles.Italic });\n\t\t\t}\n\t\t}\n\n\t\tvoid AddPreliminary(IEnumerable<XmlDocumentationElement> children)\n\t\t{\n\t\t\tif (children.Any())\n\t\t\t{\n\t\t\t\tforeach (var child in children)\n\t\t\t\t\tAddDocumentationElement(child);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tAddText(\"[This is preliminary documentation and subject to change.]\");\n\t\t\t}\n\t\t}\n\n\t\tvoid AddSee(XmlDocumentationElement element)\n\t\t{\n\t\t\tIEntity referencedEntity = element.ReferencedEntity;\n\t\t\tif (referencedEntity != null)\n\t\t\t{\n\t\t\t\tif (element.Children.Any())\n\t\t\t\t{\n\t\t\t\t\tHyperlink link = new Hyperlink();\n\t\t\t\t\tlink.Click += (sender, e) => {\n\t\t\t\t\t\tMessageBus.Send(this, new NavigateToReferenceEventArgs(referencedEntity));\n\t\t\t\t\t};\n\t\t\t\t\tAddSpan(link, element.Children);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tAddInline(ConvertReference(referencedEntity));\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (element.GetAttribute(\"langword\") != null)\n\t\t\t{\n\t\t\t\tAddInline(new Run(element.GetAttribute(\"langword\")) { FontFamily = GetCodeFont() });\n\t\t\t}\n\t\t\telse if (element.GetAttribute(\"href\") != null)\n\t\t\t{\n\t\t\t\tUri uri;\n\t\t\t\tif (Uri.TryCreate(element.GetAttribute(\"href\"), UriKind.Absolute, out uri))\n\t\t\t\t{\n\t\t\t\t\tif (element.Children.Any())\n\t\t\t\t\t{\n\t\t\t\t\t\tAddSpan(new Hyperlink { NavigateUri = uri }, element.Children);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tAddInline(new Hyperlink(new Run(element.GetAttribute(\"href\"))) { NavigateUri = uri });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Invalid reference: print the cref value\n\t\t\t\tAddText(element.GetAttribute(\"cref\"));\n\t\t\t}\n\t\t}\n\n\t\tstatic string GetCref(string cref)\n\t\t{\n\t\t\tif (cref == null || cref.Trim().Length == 0)\n\t\t\t{\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t\tif (cref.Length < 2)\n\t\t\t{\n\t\t\t\treturn cref;\n\t\t\t}\n\t\t\tif (cref.Substring(1, 1) == \":\")\n\t\t\t{\n\t\t\t\treturn cref.Substring(2, cref.Length - 2);\n\t\t\t}\n\t\t\treturn cref;\n\t\t}\n\n\t\tFontFamily GetCodeFont()\n\t\t{\n\t\t\treturn displaySettings.SelectedFont;\n\t\t}\n\n\t\tpublic void AddInline(Inline inline)\n\t\t{\n\t\t\tFlushAddedText(false);\n\t\t\tif (inlineCollection == null)\n\t\t\t{\n\t\t\t\tvar para = new Paragraph();\n\t\t\t\tpara.Margin = new Thickness(0, 0, 0, 5);\n\t\t\t\tinlineCollection = para.Inlines;\n\t\t\t\tAddBlock(para);\n\t\t\t}\n\t\t\tinlineCollection.Add(inline);\n\t\t\tignoreWhitespace = false;\n\t\t}\n\n\t\tvoid AddSection(string title, IEnumerable<XmlDocumentationElement> children)\n\t\t{\n\t\t\tAddSection(new Run(title), children);\n\t\t}\n\n\t\tvoid AddSection(Inline title, IEnumerable<XmlDocumentationElement> children)\n\t\t{\n\t\t\tAddSection(\n\t\t\t\ttitle, delegate {\n\t\t\t\t\tforeach (var child in children)\n\t\t\t\t\t\tAddDocumentationElement(child);\n\t\t\t\t});\n\t\t}\n\n\t\tvoid AddSection(Inline title, Action addChildren)\n\t\t{\n\t\t\tvar section = new Section();\n\t\t\tAddBlock(section);\n\t\t\tvar oldBlockCollection = blockCollection;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tblockCollection = section.Blocks;\n\t\t\t\tinlineCollection = null;\n\n\t\t\t\tif (title != null)\n\t\t\t\t\tAddInline(new Bold(title));\n\n\t\t\t\taddChildren();\n\t\t\t\tFlushAddedText(false);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tblockCollection = oldBlockCollection;\n\t\t\t\tinlineCollection = null;\n\t\t\t}\n\t\t}\n\n\t\tvoid AddParagraph(Paragraph para, IEnumerable<XmlDocumentationElement> children)\n\t\t{\n\t\t\tAddBlock(para);\n\t\t\ttry\n\t\t\t{\n\t\t\t\tinlineCollection = para.Inlines;\n\n\t\t\t\tforeach (var child in children)\n\t\t\t\t\tAddDocumentationElement(child);\n\t\t\t\tFlushAddedText(false);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tinlineCollection = null;\n\t\t\t}\n\t\t}\n\n\t\tvoid AddSpan(Span span, IEnumerable<XmlDocumentationElement> children)\n\t\t{\n\t\t\tAddInline(span);\n\t\t\tvar oldInlineCollection = inlineCollection;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tinlineCollection = span.Inlines;\n\t\t\t\tforeach (var child in children)\n\t\t\t\t\tAddDocumentationElement(child);\n\t\t\t\tFlushAddedText(false);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tinlineCollection = oldInlineCollection;\n\t\t\t}\n\t\t}\n\n\t\tpublic void AddBlock(Block block)\n\t\t{\n\t\t\tFlushAddedText(true);\n\t\t\tblockCollection.Add(block);\n\t\t}\n\n\t\tStringBuilder addedText = new StringBuilder();\n\t\tbool ignoreWhitespace;\n\n\t\tpublic void AddLineBreak()\n\t\t{\n\t\t\tTrimEndOfAddedText();\n\t\t\taddedText.AppendLine();\n\t\t\tignoreWhitespace = true;\n\t\t}\n\n\t\tpublic void AddText(string textContent)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(textContent))\n\t\t\t\treturn;\n\t\t\tfor (int i = 0; i < textContent.Length; i++)\n\t\t\t{\n\t\t\t\tchar c = textContent[i];\n\t\t\t\tif (c == '\\n' && IsEmptyLineBefore(textContent, i))\n\t\t\t\t{\n\t\t\t\t\tAddLineBreak(); // empty line -> line break\n\t\t\t\t}\n\t\t\t\telse if (char.IsWhiteSpace(c))\n\t\t\t\t{\n\t\t\t\t\t// any whitespace sequence gets converted to a single space (like HTML)\n\t\t\t\t\tif (!ignoreWhitespace)\n\t\t\t\t\t{\n\t\t\t\t\t\taddedText.Append(' ');\n\t\t\t\t\t\tignoreWhitespace = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\taddedText.Append(c);\n\t\t\t\t\tignoreWhitespace = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbool IsEmptyLineBefore(string text, int i)\n\t\t{\n\t\t\t// Skip previous whitespace\n\t\t\tdo\n\t\t\t{\n\t\t\t\ti--;\n\t\t\t} while (i >= 0 && (text[i] == ' ' || text[i] == '\\r'));\n\t\t\t// Check if previous non-whitespace char is \\n\n\t\t\treturn i >= 0 && text[i] == '\\n';\n\t\t}\n\n\t\tvoid TrimEndOfAddedText()\n\t\t{\n\t\t\twhile (addedText.Length > 0 && addedText[addedText.Length - 1] == ' ')\n\t\t\t{\n\t\t\t\taddedText.Length--;\n\t\t\t}\n\t\t}\n\n\t\tvoid FlushAddedText(bool trim)\n\t\t{\n\t\t\tif (trim) // trim end of current text element\n\t\t\t\tTrimEndOfAddedText();\n\t\t\tif (addedText.Length == 0)\n\t\t\t\treturn;\n\t\t\tstring text = addedText.ToString();\n\t\t\taddedText.Length = 0;\n\t\t\tAddInline(new Run(text));\n\t\t\tignoreWhitespace = trim; // trim start of next text element\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TextView/EditorCommands.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\n\nusing ICSharpCode.ILSpy.Properties;\n\nnamespace ICSharpCode.ILSpy.TextView\n{\n\t[ExportContextMenuEntry(Header = nameof(Resources.Copy), Category = nameof(Resources.Editor))]\n\t[Shared]\n\tsealed class CopyContextMenuEntry : IContextMenuEntry\n\t{\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\treturn context.TextView != null;\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\treturn context.TextView != null && context.TextView.textEditor.SelectionLength > 0;\n\t\t}\n\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tcontext.TextView.textEditor.Copy();\n\t\t}\n\t}\n\n\t[ExportContextMenuEntry(Header = nameof(Resources.Select), Category = nameof(Resources.Editor))]\n\t[Shared]\n\tsealed class SelectAllContextMenuEntry : IContextMenuEntry\n\t{\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\treturn context.TextView != null;\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\treturn context.TextView != null;\n\t\t}\n\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tcontext.TextView.textEditor.SelectAll();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TextView/FoldingCommands.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Linq;\n\nusing ICSharpCode.AvalonEdit;\nusing ICSharpCode.AvalonEdit.Folding;\nusing ICSharpCode.ILSpy.Properties;\n\nnamespace ICSharpCode.ILSpy.TextView\n{\n\t[ExportContextMenuEntryAttribute(Header = nameof(Resources.ToggleFolding), Category = nameof(Resources.Folding))]\n\t[Shared]\n\tinternal sealed class ToggleAllContextMenuEntry : IContextMenuEntry\n\t{\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\treturn context.TextView != null;\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\treturn context.TextView != null && context.TextView.FoldingManager != null;\n\t\t}\n\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tif (null == context.TextView)\n\t\t\t\treturn;\n\t\t\tFoldingManager foldingManager = context.TextView.FoldingManager;\n\t\t\tif (null == foldingManager)\n\t\t\t\treturn;\n\t\t\tbool doFold = true;\n\t\t\tforeach (FoldingSection fm in foldingManager.AllFoldings)\n\t\t\t{\n\t\t\t\tif (fm.IsFolded)\n\t\t\t\t{\n\t\t\t\t\tdoFold = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tforeach (FoldingSection fm in foldingManager.AllFoldings)\n\t\t\t{\n\t\t\t\tfm.IsFolded = doFold;\n\t\t\t}\n\t\t}\n\t}\n\n\t[ExportContextMenuEntryAttribute(Header = nameof(Resources._ToggleFolding), Category = nameof(Resources.Folding))]\n\t[Shared]\n\tinternal sealed class ToggleContextMenuEntry : IContextMenuEntry\n\t{\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\treturn context.TextView != null;\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\treturn context.TextView != null && context.TextView.FoldingManager != null;\n\t\t}\n\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tvar textView = context.TextView;\n\t\t\tif (null == textView)\n\t\t\t\treturn;\n\t\t\tvar editor = textView.textEditor;\n\t\t\tFoldingManager foldingManager = context.TextView.FoldingManager;\n\t\t\tif (null == foldingManager)\n\t\t\t\treturn;\n\t\t\t// TODO: or use Caret if position is not given?\n\t\t\tvar posBox = context.Position;\n\t\t\tif (null == posBox)\n\t\t\t\treturn;\n\t\t\tTextViewPosition pos = posBox.Value;\n\t\t\t// look for folding on this line:\n\t\t\tFoldingSection folding = foldingManager.GetNextFolding(editor.Document.GetOffset(pos.Line, 1));\n\t\t\tif (folding == null || editor.Document.GetLineByOffset(folding.StartOffset).LineNumber != pos.Line)\n\t\t\t{\n\t\t\t\t// no folding found on current line: find innermost folding containing the mouse position\n\t\t\t\tfolding = foldingManager.GetFoldingsContaining(editor.Document.GetOffset(pos.Line, pos.Column)).LastOrDefault();\n\t\t\t}\n\t\t\tif (folding != null)\n\t\t\t{\n\t\t\t\tfolding.IsFolded = !folding.IsFolded;\n\t\t\t}\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "ILSpy/TextView/ILAsm-Mode.xshd",
    "content": "<SyntaxDefinition name=\"ILAsm\" extensions=\".il\" xmlns=\"http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008\">\n\t<Color name=\"Comment\" foreground=\"Green\" exampleText=\"// comment\" />\n\t<Color name=\"String\" foreground=\"Magenta\" exampleText=\"&quot;Hello, World!&quot;\" />\n\t<Color name=\"Instructions\" foreground=\"Blue\" exampleText=\"nop;\" />\n\t<Color name=\"Keywords\" foreground=\"Blue\" fontWeight=\"bold\" exampleText=\"true\" />\n\t<Color name=\"Directives\" foreground=\"Green\" fontWeight=\"bold\" exampleText=\".class\" />\n\t<Color name=\"Security\" foreground=\"Red\" exampleText=\"request\" />\n\t<Color name=\"Label\" exampleText=\"IL_0000:\" />\n\n\t<RuleSet ignoreCase=\"false\">\n\t\t<Keywords color=\"Instructions\">\n\t\t\t<Word>nop</Word>\n\t\t\t<Word>break</Word>\n\t\t\t<Word>ldarg.0</Word>\n\t\t\t<Word>ldarg.1</Word>\n\t\t\t<Word>ldarg.2</Word>\n\t\t\t<Word>ldarg.3</Word>\n\t\t\t<Word>ldloc.0</Word>\n\t\t\t<Word>ldloc.1</Word>\n\t\t\t<Word>ldloc.2</Word>\n\t\t\t<Word>ldloc.3</Word>\n\t\t\t<Word>stloc.0</Word>\n\t\t\t<Word>stloc.1</Word>\n\t\t\t<Word>stloc.2</Word>\n\t\t\t<Word>stloc.3</Word>\n\t\t\t<Word>ldarg.s</Word>\n\t\t\t<Word>ldarga.s</Word>\n\t\t\t<Word>starg.s</Word>\n\t\t\t<Word>ldloc.s</Word>\n\t\t\t<Word>ldloca.s</Word>\n\t\t\t<Word>stloc.s</Word>\n\t\t\t<Word>ldnull</Word>\n\t\t\t<Word>ldc.i4.m1</Word>\n\t\t\t<Word>ldc.i4.0</Word>\n\t\t\t<Word>ldc.i4.1</Word>\n\t\t\t<Word>ldc.i4.2</Word>\n\t\t\t<Word>ldc.i4.3</Word>\n\t\t\t<Word>ldc.i4.4</Word>\n\t\t\t<Word>ldc.i4.5</Word>\n\t\t\t<Word>ldc.i4.6</Word>\n\t\t\t<Word>ldc.i4.7</Word>\n\t\t\t<Word>ldc.i4.8</Word>\n\t\t\t<Word>ldc.i4.s</Word>\n\t\t\t<Word>ldc.i4</Word>\n\t\t\t<Word>ldc.i8</Word>\n\t\t\t<Word>ldc.r4</Word>\n\t\t\t<Word>ldc.r8</Word>\n\t\t\t<Word>dup</Word>\n\t\t\t<Word>pop</Word>\n\t\t\t<Word>jmp</Word>\n\t\t\t<Word>call</Word>\n\t\t\t<Word>calli</Word>\n\t\t\t<Word>ret</Word>\n\t\t\t<Word>br.s</Word>\n\t\t\t<Word>brfalse.s</Word>\n\t\t\t<Word>brtrue.s</Word>\n\t\t\t<Word>beq.s</Word>\n\t\t\t<Word>bge.s</Word>\n\t\t\t<Word>bgt.s</Word>\n\t\t\t<Word>ble.s</Word>\n\t\t\t<Word>blt.s</Word>\n\t\t\t<Word>bne.un.s</Word>\n\t\t\t<Word>bge.un.s</Word>\n\t\t\t<Word>bgt.un.s</Word>\n\t\t\t<Word>ble.un.s</Word>\n\t\t\t<Word>blt.un.s</Word>\n\t\t\t<Word>br</Word>\n\t\t\t<Word>brfalse</Word>\n\t\t\t<Word>brtrue</Word>\n\t\t\t<Word>beq</Word>\n\t\t\t<Word>bge</Word>\n\t\t\t<Word>bgt</Word>\n\t\t\t<Word>ble</Word>\n\t\t\t<Word>blt</Word>\n\t\t\t<Word>bne.un</Word>\n\t\t\t<Word>bge.un</Word>\n\t\t\t<Word>bgt.un</Word>\n\t\t\t<Word>ble.un</Word>\n\t\t\t<Word>blt.un</Word>\n\t\t\t<Word>switch</Word>\n\t\t\t<Word>ldind.i1</Word>\n\t\t\t<Word>ldind.u1</Word>\n\t\t\t<Word>ldind.i2</Word>\n\t\t\t<Word>ldind.u2</Word>\n\t\t\t<Word>ldind.i4</Word>\n\t\t\t<Word>ldind.u4</Word>\n\t\t\t<Word>ldind.i8</Word>\n\t\t\t<Word>ldind.i</Word>\n\t\t\t<Word>ldind.r4</Word>\n\t\t\t<Word>ldind.r8</Word>\n\t\t\t<Word>ldind.ref</Word>\n\t\t\t<Word>stind.ref</Word>\n\t\t\t<Word>stind.i1</Word>\n\t\t\t<Word>stind.i2</Word>\n\t\t\t<Word>stind.i4</Word>\n\t\t\t<Word>stind.i8</Word>\n\t\t\t<Word>stind.r4</Word>\n\t\t\t<Word>stind.r8</Word>\n\t\t\t<Word>add</Word>\n\t\t\t<Word>sub</Word>\n\t\t\t<Word>mul</Word>\n\t\t\t<Word>div</Word>\n\t\t\t<Word>div.un</Word>\n\t\t\t<Word>rem</Word>\n\t\t\t<Word>rem.un</Word>\n\t\t\t<Word>and</Word>\n\t\t\t<Word>or</Word>\n\t\t\t<Word>xor</Word>\n\t\t\t<Word>shl</Word>\n\t\t\t<Word>shr</Word>\n\t\t\t<Word>shr.un</Word>\n\t\t\t<Word>neg</Word>\n\t\t\t<Word>not</Word>\n\t\t\t<Word>conv.i1</Word>\n\t\t\t<Word>conv.i2</Word>\n\t\t\t<Word>conv.i4</Word>\n\t\t\t<Word>conv.i8</Word>\n\t\t\t<Word>conv.r4</Word>\n\t\t\t<Word>conv.r8</Word>\n\t\t\t<Word>conv.u4</Word>\n\t\t\t<Word>conv.u8</Word>\n\t\t\t<Word>callvirt</Word>\n\t\t\t<Word>cpobj</Word>\n\t\t\t<Word>ldobj</Word>\n\t\t\t<Word>ldstr</Word>\n\t\t\t<Word>newobj</Word>\n\t\t\t<Word>castclass</Word>\n\t\t\t<Word>isinst</Word>\n\t\t\t<Word>conv.r.un</Word>\n\t\t\t<Word>unbox</Word>\n\t\t\t<Word>throw</Word>\n\t\t\t<Word>ldfld</Word>\n\t\t\t<Word>ldflda</Word>\n\t\t\t<Word>stfld</Word>\n\t\t\t<Word>ldsfld</Word>\n\t\t\t<Word>ldsflda</Word>\n\t\t\t<Word>stsfld</Word>\n\t\t\t<Word>stobj</Word>\n\t\t\t<Word>conv.ovf.i1.un</Word>\n\t\t\t<Word>conv.ovf.i2.un</Word>\n\t\t\t<Word>conv.ovf.i4.un</Word>\n\t\t\t<Word>conv.ovf.i8.un</Word>\n\t\t\t<Word>conv.ovf.u1.un</Word>\n\t\t\t<Word>conv.ovf.u2.un</Word>\n\t\t\t<Word>conv.ovf.u4.un</Word>\n\t\t\t<Word>conv.ovf.u8.un</Word>\n\t\t\t<Word>conv.ovf.i.un</Word>\n\t\t\t<Word>conv.ovf.u.un</Word>\n\t\t\t<Word>box</Word>\n\t\t\t<Word>newarr</Word>\n\t\t\t<Word>ldlen</Word>\n\t\t\t<Word>ldelema</Word>\n\t\t\t<Word>ldelem</Word>\n\t\t\t<Word>ldelem.i1</Word>\n\t\t\t<Word>ldelem.u1</Word>\n\t\t\t<Word>ldelem.i2</Word>\n\t\t\t<Word>ldelem.u2</Word>\n\t\t\t<Word>ldelem.i4</Word>\n\t\t\t<Word>ldelem.u4</Word>\n\t\t\t<Word>ldelem.i8</Word>\n\t\t\t<Word>ldelem.i</Word>\n\t\t\t<Word>ldelem.r4</Word>\n\t\t\t<Word>ldelem.r8</Word>\n\t\t\t<Word>ldelem.ref</Word>\n\t\t\t<Word>stelem</Word>\n\t\t\t<Word>stelem.i</Word>\n\t\t\t<Word>stelem.i1</Word>\n\t\t\t<Word>stelem.i2</Word>\n\t\t\t<Word>stelem.i4</Word>\n\t\t\t<Word>stelem.i8</Word>\n\t\t\t<Word>stelem.r4</Word>\n\t\t\t<Word>stelem.r8</Word>\n\t\t\t<Word>stelem.ref</Word>\n\t\t\t<Word>conv.ovf.i1</Word>\n\t\t\t<Word>conv.ovf.u1</Word>\n\t\t\t<Word>conv.ovf.i2</Word>\n\t\t\t<Word>conv.ovf.u2</Word>\n\t\t\t<Word>conv.ovf.i4</Word>\n\t\t\t<Word>conv.ovf.u4</Word>\n\t\t\t<Word>conv.ovf.i8</Word>\n\t\t\t<Word>conv.ovf.u8</Word>\n\t\t\t<Word>refanyval</Word>\n\t\t\t<Word>ckfinite</Word>\n\t\t\t<Word>mkrefany</Word>\n\t\t\t<Word>ldtoken</Word>\n\t\t\t<Word>conv.u2</Word>\n\t\t\t<Word>conv.u1</Word>\n\t\t\t<Word>conv.i</Word>\n\t\t\t<Word>conv.ovf.i</Word>\n\t\t\t<Word>conv.ovf.u</Word>\n\t\t\t<Word>add.ovf</Word>\n\t\t\t<Word>add.ovf.un</Word>\n\t\t\t<Word>mul.ovf</Word>\n\t\t\t<Word>mul.ovf.un</Word>\n\t\t\t<Word>sub.ovf</Word>\n\t\t\t<Word>sub.ovf.un</Word>\n\t\t\t<Word>endfinally</Word>\n\t\t\t<Word>leave</Word>\n\t\t\t<Word>leave.s</Word>\n\t\t\t<Word>stind.i</Word>\n\t\t\t<Word>conv.u</Word>\n\t\t\t<Word>prefix7</Word>\n\t\t\t<Word>prefix6</Word>\n\t\t\t<Word>prefix5</Word>\n\t\t\t<Word>prefix4</Word>\n\t\t\t<Word>prefix3</Word>\n\t\t\t<Word>prefix2</Word>\n\t\t\t<Word>prefix1</Word>\n\t\t\t<Word>prefixref</Word>\n\t\t\t<Word>arglist</Word>\n\t\t\t<Word>ceq</Word>\n\t\t\t<Word>cgt</Word>\n\t\t\t<Word>cgt.un</Word>\n\t\t\t<Word>clt</Word>\n\t\t\t<Word>clt.un</Word>\n\t\t\t<Word>ldftn</Word>\n\t\t\t<Word>ldvirtftn</Word>\n\t\t\t<Word>ldarg</Word>\n\t\t\t<Word>ldarga</Word>\n\t\t\t<Word>starg</Word>\n\t\t\t<Word>ldloc</Word>\n\t\t\t<Word>ldloca</Word>\n\t\t\t<Word>stloc</Word>\n\t\t\t<Word>localloc</Word>\n\t\t\t<Word>endfilter</Word>\n\t\t\t<Word>unaligned.</Word>\n\t\t\t<Word>volatile.</Word>\n\t\t\t<Word>tail.</Word>\n\t\t\t<Word>initobj</Word>\n\t\t\t<Word>cpblk</Word>\n\t\t\t<Word>initblk</Word>\n\t\t\t<Word>rethrow</Word>\n\t\t\t<Word>sizeof</Word>\n\t\t\t<Word>refanytype</Word>\n\t\t\t<Word>illegal</Word>\n\t\t\t<Word>endmac</Word>\n\t\t\t<Word>brnull</Word>\n\t\t\t<Word>brnull.s</Word>\n\t\t\t<Word>brzero</Word>\n\t\t\t<Word>brzero.s</Word>\n\t\t\t<Word>brinst</Word>\n\t\t\t<Word>brinst.s</Word>\n\t\t\t<Word>ldind.u8</Word>\n\t\t\t<Word>ldelem.u8</Word>\n\t\t\t<Word>ldc.i4.M1</Word>\n\t\t\t<Word>endfault</Word>\n\t\t</Keywords>\n\t\t<Keywords color=\"Keywords\">\n\t\t\t<Word>void</Word>\n\t\t\t<Word>bool</Word>\n\t\t\t<Word>char</Word>\n\t\t\t<Word>wchar</Word>\n\t\t\t<Word>int</Word>\n\t\t\t<Word>int8</Word>\n\t\t\t<Word>int16</Word>\n\t\t\t<Word>int32</Word>\n\t\t\t<Word>int64</Word>\n\t\t\t<Word>uint8</Word>\n\t\t\t<Word>uint16</Word>\n\t\t\t<Word>uint32</Word>\n\t\t\t<Word>uint64</Word>\n\t\t\t<Word>float</Word>\n\t\t\t<Word>float32</Word>\n\t\t\t<Word>float64</Word>\n\t\t\t<Word>refany</Word>\n\t\t\t<Word>typedref</Word>\n\t\t\t<Word>object</Word>\n\t\t\t<Word>string</Word>\n\t\t\t<Word>native</Word>\n\t\t\t<Word>unsigned</Word>\n\t\t\t<Word>value</Word>\n\t\t\t<Word>valuetype</Word>\n\t\t\t<Word>class</Word>\n\t\t\t<Word>const</Word>\n\t\t\t<Word>vararg</Word>\n\t\t\t<Word>default</Word>\n\t\t\t<Word>stdcall</Word>\n\t\t\t<Word>thiscall</Word>\n\t\t\t<Word>fastcall</Word>\n\t\t\t<Word>unmanaged</Word>\n\t\t\t<Word>not_in_gc_heap</Word>\n\t\t\t<Word>beforefieldinit</Word>\n\t\t\t<Word>instance</Word>\n\t\t\t<Word>filter</Word>\n\t\t\t<Word>catch</Word>\n\t\t\t<Word>static</Word>\n\t\t\t<Word>public</Word>\n\t\t\t<Word>private</Word>\n\t\t\t<Word>synchronized</Word>\n\t\t\t<Word>interface</Word>\n\t\t\t<Word>extends</Word>\n\t\t\t<Word>implements</Word>\n\t\t\t<Word>handler</Word>\n\t\t\t<Word>finally</Word>\n\t\t\t<Word>fault</Word>\n\t\t\t<Word>to</Word>\n\t\t\t<Word>abstract</Word>\n\t\t\t<Word>auto</Word>\n\t\t\t<Word>sequential</Word>\n\t\t\t<Word>explicit</Word>\n\t\t\t<Word>wrapper</Word>\n\t\t\t<Word>ansi</Word>\n\t\t\t<Word>unicode</Word>\n\t\t\t<Word>autochar</Word>\n\t\t\t<Word>import</Word>\n\t\t\t<Word>enum</Word>\n\t\t\t<Word>virtual</Word>\n\t\t\t<Word>notremotable</Word>\n\t\t\t<Word>special</Word>\n\t\t\t<Word>il</Word>\n\t\t\t<Word>cil</Word>\n\t\t\t<Word>optil</Word>\n\t\t\t<Word>managed</Word>\n\t\t\t<Word>preservesig</Word>\n\t\t\t<Word>runtime</Word>\n\t\t\t<Word>method</Word>\n\t\t\t<Word>field</Word>\n\t\t\t<Word>bytearray</Word>\n\t\t\t<Word>final</Word>\n\t\t\t<Word>sealed</Word>\n\t\t\t<Word>specialname</Word>\n\t\t\t<Word>family</Word>\n\t\t\t<Word>assembly</Word>\n\t\t\t<Word>famandassem</Word>\n\t\t\t<Word>famorassem</Word>\n\t\t\t<Word>privatescope</Word>\n\t\t\t<Word>nested</Word>\n\t\t\t<Word>hidebysig</Word>\n\t\t\t<Word>newslot</Word>\n\t\t\t<Word>rtspecialname</Word>\n\t\t\t<Word>pinvokeimpl</Word>\n\t\t\t<Word>unmanagedexp</Word>\n\t\t\t<Word>reqsecobj</Word>\n\t\t\t<Word>.ctor</Word>\n\t\t\t<Word>.cctor</Word>\n\t\t\t<Word>initonly</Word>\n\t\t\t<Word>literal</Word>\n\t\t\t<Word>notserialized</Word>\n\t\t\t<Word>forwardref</Word>\n\t\t\t<Word>internalcall</Word>\n\t\t\t<Word>noinlining</Word>\n\t\t\t<Word>aggressiveinlining</Word>\n\t\t\t<Word>nomangle</Word>\n\t\t\t<Word>lasterr</Word>\n\t\t\t<Word>winapi</Word>\n\t\t\t<Word>cdecl</Word>\n\t\t\t<Word>stdcall</Word>\n\t\t\t<Word>thiscall</Word>\n\t\t\t<Word>fastcall</Word>\n\t\t\t<Word>as</Word>\n\t\t\t<Word>pinned</Word>\n\t\t\t<Word>modreq</Word>\n\t\t\t<Word>modopt</Word>\n\t\t\t<Word>serializable</Word>\n\t\t\t<Word>at</Word>\n\t\t\t<Word>tls</Word>\n\t\t\t<Word>true</Word>\n\t\t\t<Word>false</Word>\n\t\t\t<Word>strict</Word>\n\t\t\t<Word>type</Word>\n\t\t</Keywords>\n\t\t<Keywords color=\"Directives\">\n\t\t\t<Word>.class</Word>\n\t\t\t<Word>.namespace</Word>\n\t\t\t<Word>.method</Word>\n\t\t\t<Word>.field</Word>\n\t\t\t<Word>.emitbyte</Word>\n\t\t\t<Word>.try</Word>\n\t\t\t<Word>.maxstack</Word>\n\t\t\t<Word>.locals</Word>\n\t\t\t<Word>.entrypoint</Word>\n\t\t\t<Word>.zeroinit</Word>\n\t\t\t<Word>.pdirect</Word>\n\t\t\t<Word>.data</Word>\n\t\t\t<Word>.event</Word>\n\t\t\t<Word>.addon</Word>\n\t\t\t<Word>.removeon</Word>\n\t\t\t<Word>.fire</Word>\n\t\t\t<Word>.other</Word>\n\t\t\t<Word>protected</Word>\n\t\t\t<Word>.property</Word>\n\t\t\t<Word>.set</Word>\n\t\t\t<Word>.get</Word>\n\t\t\t<Word>default</Word>\n\t\t\t<Word>.import</Word>\n\t\t\t<Word>.permission</Word>\n\t\t\t<Word>.permissionset</Word>\n\t\t\t<Word>.line</Word>\n\t\t\t<Word>.language</Word>\n\t\t\t<Word>.interfaceimpl</Word>\n\t\t\t<Word>#line</Word>\n\t\t</Keywords>\n\t\t<Keywords color=\"Security\">\n\t\t\t<Word>request</Word>\n\t\t\t<Word>demand</Word>\n\t\t\t<Word>assert</Word>\n\t\t\t<Word>deny</Word>\n\t\t\t<Word>permitonly</Word>\n\t\t\t<Word>linkcheck</Word>\n\t\t\t<Word>inheritcheck</Word>\n\t\t\t<Word>reqmin</Word>\n\t\t\t<Word>reqopt</Word>\n\t\t\t<Word>reqrefuse</Word>\n\t\t\t<Word>prejitgrant</Word>\n\t\t\t<Word>prejitdeny</Word>\n\t\t\t<Word>noncasdemand</Word>\n\t\t\t<Word>noncaslinkdemand</Word>\n\t\t\t<Word>noncasinheritance</Word>\n\t\t</Keywords>\n\t\t<Keywords color=\"Directives\">\n\t\t\t<!-- custom value specifier -->\n\t\t\t<Word>.custom</Word>\n\t\t\t<!-- IL method attribute  -->\n\t\t\t<Word>init</Word>\n\t\t\t<!-- Class layout directives -->\n\t\t\t<Word>.size</Word>\n\t\t\t<Word>.pack</Word>\n\t\t\t<!-- Manifest-related keywords -->\n\t\t\t<Word>.file</Word>\n\t\t\t<Word>nometadata</Word>\n\t\t\t<Word>.hash</Word>\n\t\t\t<Word>.assembly</Word>\n\t\t\t<Word>implicitcom</Word>\n\t\t\t<Word>noappdomain</Word>\n\t\t\t<Word>noprocess</Word>\n\t\t\t<Word>nomachine</Word>\n\t\t\t<Word>.publickey</Word>\n\t\t\t<Word>.publickeytoken</Word>\n\t\t\t<Word>algorithm</Word>\n\t\t\t<Word>.ver</Word>\n\t\t\t<Word>.locale</Word>\n\t\t\t<Word>extern</Word>\n\t\t\t<Word>.export</Word>\n\t\t\t<Word>.manifestres</Word>\n\t\t\t<Word>.mresource</Word>\n\t\t\t<Word>.localized</Word>\n\t\t\t\n\t\t\t<!-- Field marshaling keywords -->\n\t\t\t<Word>.module</Word>\n\t\t\t<Word>marshal</Word>\n\t\t\t<Word>custom</Word>\n\t\t\t<Word>sysstring</Word>\n\t\t\t<Word>fixed</Word>\n\t\t\t<Word>variant</Word>\n\t\t\t<Word>currency</Word>\n\t\t\t<Word>syschar</Word>\n\t\t\t<Word>decimal</Word>\n\t\t\t<Word>date</Word>\n\t\t\t<Word>bstr</Word>\n\t\t\t<Word>tbstr</Word>\n\t\t\t<Word>lpstr</Word>\n\t\t\t<Word>lpwstr</Word>\n\t\t\t<Word>lptstr</Word>\n\t\t\t<Word>objectref</Word>\n\t\t\t<Word>iunknown</Word>\n\t\t\t<Word>idispatch</Word>\n\t\t\t<Word>struct</Word>\n\t\t\t<Word>safearray</Word>\n\t\t\t<Word>byvalstr</Word>\n\t\t\t<Word>lpvoid</Word>\n\t\t\t<Word>any</Word>\n\t\t\t<Word>array</Word>\n\t\t\t<Word>lpstruct</Word>\n\t\t\t\n\t\t\t<!-- VTable fixup keywords  -->\n\t\t\t<Word>.vtfixup</Word>\n\t\t\t<Word>fromunmanaged</Word>\n\t\t\t<Word>callmostderived</Word>\n\t\t\t<Word>.vtentry</Word>\n\t\t\t\n\t\t\t<!-- Parameter attributes  -->\n\t\t\t<Word>in</Word>\n\t\t\t<Word>out</Word>\n\t\t\t<Word>opt</Word>\n\t\t\t<Word>lcid</Word>\n\t\t\t<Word>retval</Word>\n\t\t\t<Word>.param</Word>\n\t\t\t\n\t\t\t<!-- Method implementations  -->\n\t\t\t<Word>.override</Word>\n\t\t\t<Word>with</Word>\n\t\t\t\n\t\t\t<!-- VariantType keywords  -->\n\t\t\t<Word>null</Word>\n\t\t\t<Word>error</Word>\n\t\t\t<Word>hresult</Word>\n\t\t\t<Word>carray</Word>\n\t\t\t<Word>userdefined</Word>\n\t\t\t<Word>record</Word>\n\t\t\t<Word>filetime</Word>\n\t\t\t<Word>blob</Word>\n\t\t\t<Word>stream</Word>\n\t\t\t<Word>storage</Word>\n\t\t\t<Word>streamed_object</Word>\n\t\t\t<Word>stored_object</Word>\n\t\t\t<Word>blob_object</Word>\n\t\t\t<Word>cf</Word>\n\t\t\t<Word>clsid</Word>\n\t\t\t<Word>vector</Word>\n\t\t\t\n\t\t\t<!-- Null reference keyword for InitOpt  -->\n\t\t\t<Word>nullref</Word>\n\t\t\t\n\t\t\t<!-- Header flags keywords  -->\n\t\t\t<Word>.subsystem</Word>\n\t\t\t<Word>.corflags</Word>\n\t\t\t<Word>.stackreserve</Word>\n\t\t\t<Word>alignment</Word>\n\t\t\t<Word>.imagebase</Word>\n\t\t</Keywords>\n\t\t<Span color=\"Comment\" ruleSet=\"CommentMarkerSet\">\n\t\t\t<Begin>//</Begin>\n\t\t</Span>\n\t\t<Span color=\"Comment\" ruleSet=\"CommentMarkerSet\">\n\t\t\t<Begin>/\\*</Begin>\n\t\t\t<End>\\*/</End>\n\t\t</Span>\n\t\t<Span color=\"String\">\n\t\t\t<Begin>\"</Begin>\n\t\t\t<End>\"</End>\n\t\t</Span>\n\t\t<Span>\n\t\t\t<Begin>'</Begin>\n\t\t\t<End>'</End>\n\t\t</Span>\n\t\t<Rule color=\"Label\">\n\t\t\t^ \\s* \\w+ :\n\t\t</Rule>\n\t</RuleSet>\n\t<RuleSet name=\"CommentMarkerSet\" ignoreCase=\"false\">\n\t\t<Keywords foreground=\"#FFFF0000\" fontWeight=\"bold\">\n\t\t\t<Word>TODO</Word>\n\t\t\t<Word>FIXME</Word>\n\t\t</Keywords>\n\t\t<Keywords foreground=\"#EEE0E000\" fontWeight=\"bold\">\n\t\t\t<Word>HACK</Word>\n\t\t\t<Word>UNDONE</Word>\n\t\t</Keywords>\n\t</RuleSet>\n</SyntaxDefinition>"
  },
  {
    "path": "ILSpy/TextView/OutputLengthExceededException.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.ILSpy.TextView\n{\n\t/// <summary>\n\t/// This exception gets used when the text output is longer than the specified limit.\n\t/// </summary>\n\tclass OutputLengthExceededException : Exception\n\t{\n\t\tpublic OutputLengthExceededException()\n\t\t{\n\t\t}\n\n\t\tpublic OutputLengthExceededException(string message) : base(message)\n\t\t{\n\t\t}\n\n\t\tpublic OutputLengthExceededException(string message, Exception innerException) : base(message, innerException)\n\t\t{\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/TextView/ReferenceElementGenerator.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Windows.Input;\n\nusing ICSharpCode.AvalonEdit.Document;\nusing ICSharpCode.AvalonEdit.Rendering;\n\nnamespace ICSharpCode.ILSpy.TextView\n{\n\t/// <summary>\n\t/// Creates hyperlinks in the text view.\n\t/// </summary>\n\tsealed class ReferenceElementGenerator : VisualLineElementGenerator\n\t{\n\t\treadonly Predicate<ReferenceSegment> isLink;\n\n\t\t/// <summary>\n\t\t/// The collection of references (hyperlinks).\n\t\t/// </summary>\n\t\tpublic TextSegmentCollection<ReferenceSegment> References { get; set; }\n\n\t\tpublic ReferenceElementGenerator(Predicate<ReferenceSegment> isLink)\n\t\t{\n\t\t\tif (isLink == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(isLink));\n\t\t\tthis.isLink = isLink;\n\t\t}\n\n\t\tpublic override int GetFirstInterestedOffset(int startOffset)\n\t\t{\n\t\t\tif (this.References == null)\n\t\t\t\treturn -1;\n\t\t\t// inform AvalonEdit about the next position where we want to build a hyperlink\n\t\t\tvar segment = this.References.FindFirstSegmentWithStartAfter(startOffset);\n\t\t\treturn segment != null ? segment.StartOffset : -1;\n\t\t}\n\n\t\tpublic override VisualLineElement ConstructElement(int offset)\n\t\t{\n\t\t\tif (this.References == null)\n\t\t\t\treturn null;\n\t\t\tforeach (var segment in this.References.FindSegmentsContaining(offset))\n\t\t\t{\n\t\t\t\t// skip all non-links\n\t\t\t\tif (!isLink(segment))\n\t\t\t\t\tcontinue;\n\t\t\t\t// ensure that hyperlinks don't span several lines (VisualLineElements can't contain line breaks)\n\t\t\t\tint endOffset = Math.Min(segment.EndOffset, CurrentContext.VisualLine.LastDocumentLine.EndOffset);\n\t\t\t\t// don't create hyperlinks with length 0\n\t\t\t\tif (offset < endOffset)\n\t\t\t\t{\n\t\t\t\t\treturn new VisualLineReferenceText(CurrentContext.VisualLine, endOffset - offset, this, segment);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// VisualLineElement that represents a piece of text and is a clickable link.\n\t/// </summary>\n\tsealed class VisualLineReferenceText : VisualLineText\n\t{\n\t\treadonly ReferenceElementGenerator parent;\n\t\treadonly ReferenceSegment referenceSegment;\n\n\t\t/// <summary>\n\t\t/// Creates a visual line text element with the specified length.\n\t\t/// It uses the <see cref=\"ITextRunConstructionContext.VisualLine\"/> and its\n\t\t/// <see cref=\"VisualLineElement.RelativeTextOffset\"/> to find the actual text string.\n\t\t/// </summary>\n\t\tpublic VisualLineReferenceText(VisualLine parentVisualLine, int length, ReferenceElementGenerator parent, ReferenceSegment referenceSegment) : base(parentVisualLine, length)\n\t\t{\n\t\t\tthis.parent = parent;\n\t\t\tthis.referenceSegment = referenceSegment;\n\t\t}\n\n\t\t/// <inheritdoc/>\n\t\tprotected override void OnQueryCursor(QueryCursorEventArgs e)\n\t\t{\n\t\t\te.Handled = true;\n\t\t\te.Cursor = referenceSegment.IsLocal ? Cursors.Arrow : Cursors.Hand;\n\t\t}\n\n\t\t/// <inheritdoc/>\n\t\tprotected override VisualLineText CreateInstance(int length)\n\t\t{\n\t\t\treturn new VisualLineReferenceText(ParentVisualLine, length, parent, referenceSegment);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TextView/ThemeAwareHighlightingColorizer.cs",
    "content": "using System.Collections.Generic;\n\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.AvalonEdit.Rendering;\nusing ICSharpCode.ILSpy.Themes;\n\nnamespace ICSharpCode.ILSpy.TextView;\n\n#nullable enable\n\npublic class ThemeAwareHighlightingColorizer : HighlightingColorizer\n{\n\tprivate readonly Dictionary<HighlightingColor, HighlightingColor> _darkColors = new();\n\tprivate readonly bool _isHighlightingThemeAware;\n\n\tpublic ThemeAwareHighlightingColorizer(IHighlightingDefinition highlightingDefinition)\n\t\t: base(highlightingDefinition)\n\t{\n\t\t_isHighlightingThemeAware = ThemeManager.Current.IsThemeAware(highlightingDefinition);\n\t}\n\n\tprotected override void ApplyColorToElement(VisualLineElement element, HighlightingColor color)\n\t{\n\t\tif (!_isHighlightingThemeAware && ThemeManager.Current.IsDarkTheme)\n\t\t{\n\t\t\tcolor = GetColorForDarkTheme(color);\n\t\t}\n\n\t\tbase.ApplyColorToElement(element, color);\n\t}\n\n\tprivate HighlightingColor GetColorForDarkTheme(HighlightingColor lightColor)\n\t{\n\t\tif (lightColor.Foreground is null && lightColor.Background is null)\n\t\t{\n\t\t\treturn lightColor;\n\t\t}\n\n\t\tif (!_darkColors.TryGetValue(lightColor, out var darkColor))\n\t\t{\n\t\t\t_darkColors[lightColor] = darkColor = ThemeManager.GetColorForDarkTheme(lightColor);\n\t\t}\n\n\t\treturn darkColor;\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TextView/UIElementGenerator.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Windows;\n\nusing ICSharpCode.AvalonEdit.Rendering;\n\nnamespace ICSharpCode.ILSpy.TextView\n{\n\tusing Pair = KeyValuePair<int, Lazy<UIElement>>;\n\n\t/// <summary>\n\t/// Embeds UIElements in the text output.\n\t/// </summary>\n\tsealed class UIElementGenerator : VisualLineElementGenerator, IComparer<Pair>\n\t{\n\t\t/// <summary>\n\t\t/// The list of embedded UI elements to be displayed.\n\t\t/// We store this as a sorted list of (offset, Lazy&lt;UIElement&gt;) pairs.\n\t\t/// The \"Lazy\" part is used to create UIElements on demand (and thus on the UI thread, not on the decompiler thread).\n\t\t/// </summary>\n\t\tpublic List<Pair> UIElements;\n\n\t\tpublic override int GetFirstInterestedOffset(int startOffset)\n\t\t{\n\t\t\tif (this.UIElements == null)\n\t\t\t\treturn -1;\n\t\t\tint r = this.UIElements.BinarySearch(new Pair(startOffset, null), this);\n\t\t\t// If the element isn't found, BinarySearch returns the complement of \"insertion position\".\n\t\t\t// We use this to find the next element (if there wasn't any exact match).\n\t\t\tif (r < 0)\n\t\t\t\tr = ~r;\n\t\t\tif (r < this.UIElements.Count)\n\t\t\t\treturn this.UIElements[r].Key;\n\t\t\telse\n\t\t\t\treturn -1;\n\t\t}\n\n\t\tpublic override VisualLineElement ConstructElement(int offset)\n\t\t{\n\t\t\tif (this.UIElements == null)\n\t\t\t\treturn null;\n\t\t\tint r = UIElements.BinarySearch(new Pair(offset, null), this);\n\t\t\tif (r >= 0)\n\t\t\t\treturn new InlineObjectElement(0, this.UIElements[r].Value.Value);\n\t\t\telse\n\t\t\t\treturn null;\n\t\t}\n\n\t\tint IComparer<Pair>.Compare(Pair x, Pair y)\n\t\t{\n\t\t\t// Compare (offset,Lazy<UIElement>) pairs by the offset.\n\t\t\t// Used in BinarySearch()\n\t\t\treturn x.Key.CompareTo(y.Key);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TextView/XML-Mode.xshd",
    "content": "<SyntaxDefinition name=\"XML\" extensions=\".xml;.xsl;.xslt;.xsd;.manifest;.config;.addin;.xshd;.wxs;.wxi;.wxl;.proj;.csproj;.vbproj;.ilproj;.booproj;.build;.xfrm;.targets;.xaml;.xpt;.xft;.map;.wsdl;.disco;.ps1xml;.nuspec\" xmlns=\"http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008\">\n\t<Color foreground=\"Green\" name=\"Comment\" exampleText=\"&lt;!-- comment --&gt;\" />\n\t<Color foreground=\"Blue\" name=\"CData\" exampleText=\"&lt;![CDATA[data]]&gt;\" />\n\t<Color foreground=\"Blue\" name=\"DocType\" exampleText=\"&lt;!DOCTYPE rootElement&gt;\" />\n\t<Color foreground=\"Blue\" name=\"XmlDeclaration\" exampleText='&lt;?xml version=\"1.0\"?&gt;' />\n\t<Color foreground=\"DarkMagenta\" name=\"XmlTag\" exampleText='&lt;tag attribute=\"value\" /&gt;' />\n\t<Color foreground=\"Red\" name=\"AttributeName\" exampleText='&lt;tag attribute=\"value\" /&gt;' />\n\t<Color foreground=\"Blue\" name=\"AttributeValue\" exampleText='&lt;tag attribute=\"value\" /&gt;' />\n\t<Color foreground=\"Teal\" name=\"Entity\" exampleText=\"index.aspx?a=1&amp;amp;b=2\" />\n\t<Color foreground=\"Olive\" name=\"BrokenEntity\" exampleText=\"index.aspx?a=1&amp;b=2\" />\n\t\n\t<RuleSet>\n\t\t<Span color=\"Comment\" multiline=\"true\">\n\t\t\t<Begin>&lt;!--</Begin>\n\t\t\t<End>--&gt;</End>\n\t\t</Span>\n\t\t<Span color=\"CData\" multiline=\"true\">\n\t\t\t<Begin>&lt;!\\[CDATA\\[</Begin>\n\t\t\t<End>]]&gt;</End>\n\t\t</Span>\n\t\t<Span color=\"DocType\" multiline=\"true\">\n\t\t\t<Begin>&lt;!DOCTYPE</Begin>\n\t\t\t<End>&gt;</End>\n\t\t</Span>\n\t\t<Span color=\"XmlDeclaration\" multiline=\"true\">\n\t\t\t<Begin>&lt;\\?</Begin>\n\t\t\t<End>\\?&gt;</End>\n\t\t</Span>\n\t\t<Span color=\"XmlTag\" multiline=\"true\">\n\t\t\t<Begin>&lt;</Begin>\n\t\t\t<End>&gt;</End>\n\t\t\t<RuleSet>\n\t\t\t\t<!-- Treat the position before '<' as end, as that's not a valid character\n\t\t\t\t     in attribute names and indicates the user forgot a closing quote. -->\n\t\t\t\t<Span color=\"AttributeValue\" multiline=\"true\" ruleSet=\"EntitySet\">\n\t\t\t\t\t<Begin>\"</Begin>\n\t\t\t\t\t<End>\"|(?=&lt;)</End>\n\t\t\t\t</Span>\n\t\t\t\t<Span color=\"AttributeValue\" multiline=\"true\" ruleSet=\"EntitySet\">\n\t\t\t\t\t<Begin>'</Begin>\n\t\t\t\t\t<End>'|(?=&lt;)</End>\n\t\t\t\t</Span>\n\t\t\t\t<Rule color=\"AttributeName\">[\\d\\w_\\-\\.]+(?=(\\s*=))</Rule>\n\t\t\t\t<Rule color=\"AttributeValue\">=</Rule>\n\t\t\t</RuleSet>\n\t\t</Span>\n\t\t<Import ruleSet=\"EntitySet\"/>\n\t</RuleSet>\n\t\n\t<RuleSet name=\"EntitySet\">\n\t\t<Rule color=\"Entity\">\n\t\t\t&amp;\n\t\t\t[\\w\\d\\#]+\n\t\t\t;\n\t\t</Rule>\n\n\t\t<Rule color=\"BrokenEntity\">\n\t\t\t&amp;\n\t\t\t[\\w\\d\\#]*\n\t\t\t#missing ;\n\t\t</Rule>\n\t</RuleSet>\n</SyntaxDefinition>"
  },
  {
    "path": "ILSpy/TextView/ZoomLevelToTextFormattingModeConverter.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\nusing System;\nusing System.Windows.Data;\nusing System.Windows.Media;\n\nnamespace ICSharpCode.ILSpy.TextView\n{\n\tsealed class ZoomLevelToTextFormattingModeConverter : IValueConverter\n\t{\n\t\tpublic static readonly ZoomLevelToTextFormattingModeConverter Instance = new ZoomLevelToTextFormattingModeConverter();\n\n\t\tpublic object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)\n\t\t{\n\t\t\treturn ((double)value) == 1.0 ? TextFormattingMode.Display : (object)TextFormattingMode.Ideal;\n\t\t}\n\n\t\tpublic object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)\n\t\t{\n\t\t\tthrow new NotSupportedException();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Themes/Base.Dark.xaml",
    "content": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n                    xmlns:styles=\"urn:TomsToolbox.Wpf.Styles\"\n                    xmlns:themes=\"clr-namespace:ICSharpCode.ILSpy.Themes\">\n\t<ResourceDictionary.MergedDictionaries>\n\t\t<ResourceDictionary Source=\"/AvalonDock.Themes.VS2013;component/darktheme.xaml\" />\n\t</ResourceDictionary.MergedDictionaries>\n\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.TextBackgroundBrush}\" Color=\"Black\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.TextForegroundBrush}\" Color=\"White\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.SearchResultBackgroundBrush}\" Color=\"#995A23\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.LineNumbersForegroundBrush}\" Color=\"Gray\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.CurrentLineBackgroundBrush}\" Color=\"#1614DCE0\" />\n\t<Pen x:Key=\"{x:Static themes:ResourceKeys.CurrentLineBorderPen}\" Brush=\"#3400FF6E\" Thickness=\"1\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.BracketHighlightBackgroundBrush}\" Color=\"#443399FF\" />\n\t<Pen x:Key=\"{x:Static themes:ResourceKeys.BracketHighlightBorderPen}\" Brush=\"#883399FF\" Thickness=\"1\" />\n\n\t<Color x:Key=\"{x:Static SystemColors.ControlLightLightColorKey}\">#333337</Color>\n\t<Color x:Key=\"{x:Static SystemColors.ControlLightColorKey}\">#464646</Color>\n\t<Color x:Key=\"{x:Static SystemColors.ControlColorKey}\">#252526</Color>\n\t<Color x:Key=\"{x:Static SystemColors.ControlDarkColorKey}\">#686868</Color>\n\t<Color x:Key=\"{x:Static SystemColors.ControlDarkDarkColorKey}\">#9E9E9E</Color>\n\t<Color x:Key=\"{x:Static SystemColors.ControlTextColorKey}\">#F1F1F1</Color>\n\t<Color x:Key=\"{x:Static SystemColors.GrayTextColorKey}\">#999999</Color>\n\t<Color x:Key=\"{x:Static SystemColors.HighlightColorKey}\">#3399FF</Color>\n\t<Color x:Key=\"{x:Static SystemColors.HighlightTextColorKey}\">#FFFFFF</Color>\n\t<Color x:Key=\"{x:Static SystemColors.InfoTextColorKey}\">#F1F1F1</Color>\n\t<Color x:Key=\"{x:Static SystemColors.InfoColorKey}\">#333337</Color>\n\t<Color x:Key=\"{x:Static SystemColors.MenuColorKey}\">#1B1B1C</Color>\n\t<Color x:Key=\"{x:Static SystemColors.MenuBarColorKey}\">#1B1B1C</Color>\n\t<Color x:Key=\"{x:Static SystemColors.MenuTextColorKey}\">#F1F1F1</Color>\n\t<Color x:Key=\"{x:Static SystemColors.WindowColorKey}\">#333337</Color>\n\t<Color x:Key=\"{x:Static SystemColors.WindowTextColorKey}\">#F1F1F1</Color>\n\t<Color x:Key=\"{x:Static SystemColors.ActiveCaptionColorKey}\">#2D2D30</Color>\n\t<Color x:Key=\"{x:Static SystemColors.ActiveBorderColorKey}\">#007ACC</Color>\n\t<Color x:Key=\"{x:Static SystemColors.ActiveCaptionTextColorKey}\">#F1F1F1</Color>\n\t<Color x:Key=\"{x:Static SystemColors.InactiveCaptionColorKey}\">#2D2D30</Color>\n\t<Color x:Key=\"{x:Static SystemColors.InactiveBorderColorKey}\">#434346</Color>\n\t<Color x:Key=\"{x:Static SystemColors.InactiveCaptionTextColorKey}\">#808080</Color>\n\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.ControlLightLightBrushKey}\" Color=\"#333337\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.ControlLightBrushKey}\" Color=\"#464646\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.ControlBrushKey}\" Color=\"#252526\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.ControlDarkBrushKey}\" Color=\"#686868\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.ControlDarkDarkBrushKey}\" Color=\"#9E9E9E\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.ControlTextBrushKey}\" Color=\"#F1F1F1\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.GrayTextBrushKey}\" Color=\"#999999\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.HighlightBrushKey}\" Color=\"#3399FF\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.HighlightTextBrushKey}\" Color=\"#FFFFFF\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.InfoTextBrushKey}\" Color=\"#F1F1F1\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.InfoBrushKey}\" Color=\"#333337\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.MenuBrushKey}\" Color=\"#1B1B1C\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.MenuBarBrushKey}\" Color=\"#1B1B1C\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.MenuTextBrushKey}\" Color=\"#F1F1F1\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.WindowBrushKey}\" Color=\"#333337\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.WindowTextBrushKey}\" Color=\"#F1F1F1\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.ActiveCaptionBrushKey}\" Color=\"#2D2D30\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.ActiveBorderBrushKey}\" Color=\"#007ACC\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.ActiveCaptionTextBrushKey}\" Color=\"#F1F1F1\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.InactiveCaptionBrushKey}\" Color=\"#2D2D30\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.InactiveBorderBrushKey}\" Color=\"#434346\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.InactiveCaptionTextBrushKey}\" Color=\"#808080\" />\n\n\t<SolidColorBrush x:Key=\"{x:Static styles:ResourceKeys.BorderBrush}\" Color=\"#464646\" />\n\t<SolidColorBrush x:Key=\"{x:Static styles:ResourceKeys.DisabledBrush}\" Color=\"#2D2D30\" />\n\t<Color x:Key=\"{x:Static themes:ResourceKeys.TextMarkerBackgroundColor}\">MediumVioletRed</Color>\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.LinkTextForegroundBrush}\">CornflowerBlue</SolidColorBrush>\n\n\t<styles:InvertGrayEffect x:Key=\"{x:Static themes:ResourceKeys.ThemeAwareButtonEffect}\" />\n\n</ResourceDictionary>\n"
  },
  {
    "path": "ILSpy/Themes/Base.Light.xaml",
    "content": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n                    xmlns:styles=\"urn:TomsToolbox.Wpf.Styles\"\n                    xmlns:themes=\"clr-namespace:ICSharpCode.ILSpy.Themes\">\n\t<ResourceDictionary.MergedDictionaries>\n\t\t<ResourceDictionary Source=\"/AvalonDock.Themes.VS2013;component/lighttheme.xaml\" />\n\t</ResourceDictionary.MergedDictionaries>\n\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.TextBackgroundBrush}\" Color=\"White\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.TextForegroundBrush}\" Color=\"Black\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.SearchResultBackgroundBrush}\" Color=\"LightGreen\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.LineNumbersForegroundBrush}\" Color=\"Gray\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.CurrentLineBackgroundBrush}\" Color=\"#1614DCE0\" />\n\t<Pen x:Key=\"{x:Static themes:ResourceKeys.CurrentLineBorderPen}\" Brush=\"#3400FF6E\" Thickness=\"1\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.BracketHighlightBackgroundBrush}\" Color=\"#160000FF\" />\n\t<Pen x:Key=\"{x:Static themes:ResourceKeys.BracketHighlightBorderPen}\" Brush=\"#340000FF\" Thickness=\"1\" />\n\n\t<Color x:Key=\"{x:Static SystemColors.ControlLightLightColorKey}\">#FCFCFC</Color>\n\t<Color x:Key=\"{x:Static SystemColors.ControlLightColorKey}\">#D8D8E0</Color>\n\t<Color x:Key=\"{x:Static SystemColors.ControlColorKey}\">#F5F5F5</Color>\n\t<Color x:Key=\"{x:Static SystemColors.ControlDarkColorKey}\">#C2C3C9</Color>\n\t<Color x:Key=\"{x:Static SystemColors.ControlDarkDarkColorKey}\">#686868</Color>\n\t<Color x:Key=\"{x:Static SystemColors.ControlTextColorKey}\">#1E1E1E</Color>\n\t<Color x:Key=\"{x:Static SystemColors.GrayTextColorKey}\">#717171</Color>\n\t<Color x:Key=\"{x:Static SystemColors.HighlightColorKey}\">#3399FF</Color>\n\t<Color x:Key=\"{x:Static SystemColors.HighlightTextColorKey}\">#FFFFFF</Color>\n\t<Color x:Key=\"{x:Static SystemColors.MenuColorKey}\">#F6F6F6</Color>\n\t<Color x:Key=\"{x:Static SystemColors.MenuBarColorKey}\">#F6F6F6</Color>\n\t<Color x:Key=\"{x:Static SystemColors.MenuTextColorKey}\">#1E1E1E</Color>\n\t<Color x:Key=\"{x:Static SystemColors.WindowColorKey}\">#FFFFFF</Color>\n\t<Color x:Key=\"{x:Static SystemColors.WindowTextColorKey}\">#1E1E1E</Color>\n\t<Color x:Key=\"{x:Static SystemColors.ActiveCaptionColorKey}\">#EEEEF2</Color>\n\t<Color x:Key=\"{x:Static SystemColors.ActiveBorderColorKey}\">#71BDE2</Color>\n\t<Color x:Key=\"{x:Static SystemColors.ActiveCaptionTextColorKey}\">#1E1E1E</Color>\n\t<Color x:Key=\"{x:Static SystemColors.InactiveCaptionColorKey}\">#EEEEF2</Color>\n\t<Color x:Key=\"{x:Static SystemColors.InactiveBorderColorKey}\">#CCCEDB</Color>\n\t<Color x:Key=\"{x:Static SystemColors.InactiveCaptionTextColorKey}\">#808080</Color>\n\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.ControlLightLightBrushKey}\" Color=\"#FCFCFC\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.ControlLightBrushKey}\" Color=\"#D8D8E0\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.ControlBrushKey}\" Color=\"#F5F5F5\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.ControlDarkBrushKey}\" Color=\"#C2C3C9\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.ControlDarkDarkBrushKey}\" Color=\"#686868\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.ControlTextBrushKey}\" Color=\"#1E1E1E\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.GrayTextBrushKey}\" Color=\"#717171\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.HighlightBrushKey}\" Color=\"#3399FF\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.HighlightTextBrushKey}\" Color=\"#FFFFFF\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.MenuBrushKey}\" Color=\"#F6F6F6\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.MenuBarBrushKey}\" Color=\"#F6F6F6\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.MenuTextBrushKey}\" Color=\"#1E1E1E\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.WindowBrushKey}\" Color=\"#FFFFFF\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.WindowTextBrushKey}\" Color=\"#1E1E1E\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.ActiveCaptionBrushKey}\" Color=\"#EEEEF2\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.ActiveBorderBrushKey}\" Color=\"#71BDE2\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.ActiveCaptionTextBrushKey}\" Color=\"#1E1E1E\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.InactiveCaptionBrushKey}\" Color=\"#EEEEF2\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.InactiveBorderBrushKey}\" Color=\"#CCCEDB\" />\n\t<SolidColorBrush x:Key=\"{x:Static SystemColors.InactiveCaptionTextBrushKey}\" Color=\"#808080\" />\n\n\t<SolidColorBrush x:Key=\"{x:Static styles:ResourceKeys.BorderBrush}\" Color=\"#CCCEDB\" />\n\t<SolidColorBrush x:Key=\"{x:Static styles:ResourceKeys.DisabledBrush}\" Color=\"#EEEEF2\" />\n\n</ResourceDictionary>\n"
  },
  {
    "path": "ILSpy/Themes/ResourceKeys.cs",
    "content": "// Copyright (c) 2021 Tom Englert\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Windows;\n\nnamespace ICSharpCode.ILSpy.Themes\n{\n\tpublic static class ResourceKeys\n\t{\n\t\tpublic static ResourceKey TextBackgroundBrush = new ComponentResourceKey(typeof(ResourceKeys), nameof(TextBackgroundBrush));\n\t\tpublic static ResourceKey TextForegroundBrush = new ComponentResourceKey(typeof(ResourceKeys), nameof(TextForegroundBrush));\n\t\tpublic static ResourceKey TextMarkerBackgroundColor = new ComponentResourceKey(typeof(ResourceKeys), nameof(TextMarkerBackgroundColor));\n\t\tpublic static ResourceKey TextMarkerDefinitionBackgroundColor = new ComponentResourceKey(typeof(ResourceKeys), nameof(TextMarkerDefinitionBackgroundColor));\n\t\tpublic static ResourceKey SearchResultBackgroundBrush = new ComponentResourceKey(typeof(ResourceKeys), nameof(SearchResultBackgroundBrush));\n\t\tpublic static ResourceKey LinkTextForegroundBrush = new ComponentResourceKey(typeof(ResourceKeys), nameof(LinkTextForegroundBrush));\n\t\tpublic static ResourceKey BracketHighlightBackgroundBrush = new ComponentResourceKey(typeof(ResourceKeys), nameof(BracketHighlightBackgroundBrush));\n\t\tpublic static ResourceKey BracketHighlightBorderPen = new ComponentResourceKey(typeof(ResourceKeys), nameof(BracketHighlightBorderPen));\n\t\tpublic static ResourceKey LineNumbersForegroundBrush = new ComponentResourceKey(typeof(ResourceKeys), nameof(LineNumbersForegroundBrush));\n\t\tpublic static ResourceKey CurrentLineBackgroundBrush = new ComponentResourceKey(typeof(ResourceKeys), nameof(CurrentLineBackgroundBrush));\n\t\tpublic static ResourceKey CurrentLineBorderPen = new ComponentResourceKey(typeof(ResourceKeys), nameof(CurrentLineBorderPen));\n\t\tpublic static ResourceKey ThemeAwareButtonEffect = new ComponentResourceKey(typeof(ResourceKeys), nameof(ThemeAwareButtonEffect));\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Themes/SyntaxColor.cs",
    "content": "#nullable enable\n\nusing System.Windows;\nusing System.Windows.Media;\n\nusing ICSharpCode.AvalonEdit.Highlighting;\n\nnamespace ICSharpCode.ILSpy.Themes;\n\npublic class SyntaxColor\n{\n\tpublic Color? Foreground { get; set; }\n\tpublic Color? Background { get; set; }\n\tpublic FontWeight? FontWeight { get; set; }\n\tpublic FontStyle? FontStyle { get; set; }\n\n\tpublic void ApplyTo(HighlightingColor color)\n\t{\n\t\tcolor.Foreground = Foreground is { } foreground ? new SimpleHighlightingBrush(foreground) : null;\n\t\tcolor.Background = Background is { } background ? new SimpleHighlightingBrush(background) : null;\n\t\tcolor.FontWeight = FontWeight ?? FontWeights.Normal;\n\t\tcolor.FontStyle = FontStyle ?? FontStyles.Normal;\n\t}\n\n\tpublic static void ResetColor(HighlightingColor color)\n\t{\n\t\tcolor.Foreground = null;\n\t\tcolor.Background = null;\n\t\tcolor.FontWeight = null;\n\t\tcolor.FontStyle = null;\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Themes/Theme.Dark.xaml",
    "content": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n                    xmlns:themes=\"clr-namespace:ICSharpCode.ILSpy.Themes\">\n\t<ResourceDictionary.MergedDictionaries>\n\t\t<ResourceDictionary Source=\"Base.Dark.xaml\" />\n\t</ResourceDictionary.MergedDictionaries>\n\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.TextBackgroundBrush}\" Color=\"#333337\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.TextForegroundBrush}\" Color=\"#F1F1F1\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.SearchResultBackgroundBrush}\" Color=\"#995A23\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.LineNumbersForegroundBrush}\" Color=\"Gray\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.CurrentLineBackgroundBrush}\" Color=\"#1614DCE0\" />\n\t<Pen x:Key=\"{x:Static themes:ResourceKeys.CurrentLineBorderPen}\" Brush=\"#3400FF6E\" Thickness=\"1\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.BracketHighlightBackgroundBrush}\" Color=\"#443399FF\" />\n\t<Pen x:Key=\"{x:Static themes:ResourceKeys.BracketHighlightBorderPen}\" Brush=\"#883399FF\" Thickness=\"1\" />\n\n\t<!-- ILAsm -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Comment\" Foreground=\"#FF57A64A\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.String\" Foreground=\"#FFD69D85\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Instructions\" Foreground=\"#FFD69D85\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Keywords\" Foreground=\"#FFD69D85\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Directives\" Foreground=\"#FF57A64A\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Security\" Foreground=\"#FF559CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Label\" />\n\n\t<!-- Asm -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Comment\" Foreground=\"#FF57A64A\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.NumberLiteral\" Foreground=\"Orange\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.String\" Foreground=\"#FFD69D85\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Instructions\" Foreground=\"#FFD69D85\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Math Instructions\" Foreground=\"#FFD69D85\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Extended Instructions\" Foreground=\"#FF559CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Registers\" Foreground=\"#8080FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Directives\" Foreground=\"#FFD69D85\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Directive Operands\" Foreground=\"#FFb5cea8\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Address and Bytes\" />\n\n\t<!-- CSharp -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Comment\" Foreground=\"#FF57A64A\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.String\" Foreground=\"#FFD69D85\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.StringInterpolation\" Foreground=\"#FFffd68f\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Char\" Foreground=\"#FFD69D85\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Preprocessor\" Foreground=\"#FF9B9B9B\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Punctuation\" Foreground=\"White\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ValueTypeKeywords\" Foreground=\"#FF00A0FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ReferenceTypeKeywords\" Foreground=\"#FF559CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.NumberLiteral\" Foreground=\"#FFb5cea8\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ThisOrBaseReference\" Foreground=\"#FF3a6a9b\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.NullOrValueKeywords\" Foreground=\"#FF559CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Keywords\" Foreground=\"#FFd8a0df\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.GotoKeywords\" Foreground=\"#FFd8a0df\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.QueryKeywords\" Foreground=\"#FFd8a0df\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ExceptionKeywords\" Foreground=\"#FFd8a0df\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.CheckedKeyword\" Foreground=\"#FF559CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.UnsafeKeywords\" Foreground=\"#FF559CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.OperatorKeywords\" Foreground=\"#FFD69D85\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ParameterModifiers\" Foreground=\"#FF559CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Modifiers\" Foreground=\"#FF559CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Visibility\" Foreground=\"#FF559CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.NamespaceKeywords\" Foreground=\"#FF559CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.GetSetAddRemove\" Foreground=\"#FF559CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.TrueFalse\" Foreground=\"#FF00A0FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.TypeKeywords\" Foreground=\"#FF559CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.AttributeKeywords\" Foreground=\"#FFD69D85\" />\n\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ReferenceTypes\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.InterfaceTypes\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.TypeParameters\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.DelegateTypes\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ValueTypes\" FontWeight=\"Bold\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.EnumTypes\" FontWeight=\"Bold\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.MethodDeclaration\" Foreground=\"#FFdcdcaa\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.MethodCall\" Foreground=\"#FFdcdcaa\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.FieldDeclaration\" FontStyle=\"Italic\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.FieldAccess\" FontStyle=\"Italic\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.PropertyDeclaration\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.PropertyAccess\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.EventDeclaration\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.EventAccess\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Variable\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Parameter\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.InactiveCode\" Foreground=\"Gray\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.SemanticError\" Foreground=\"DarkRed\" />\n\n\t<!-- XML -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.Comment\" Foreground=\"Green\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.CData\" Foreground=\"#FFD69D85\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.DocType\" Foreground=\"#FFD69D85\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.XmlDeclaration\" Foreground=\"#FFD69D85\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.XmlTag\" Foreground=\"#FFD69D85\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.AttributeName\" Foreground=\"#FF00A0FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.AttributeValue\" Foreground=\"#FFD69D85\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.Entity\" Foreground=\"#FFd8a0df\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.BrokenEntity\" Foreground=\"#FF559CD6\" />\n\n</ResourceDictionary>\n"
  },
  {
    "path": "ILSpy/Themes/Theme.Light.xaml",
    "content": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n                    xmlns:themes=\"clr-namespace:ICSharpCode.ILSpy.Themes\">\n\t<ResourceDictionary.MergedDictionaries>\n\t\t<ResourceDictionary Source=\"Base.Light.xaml\" />\n\t</ResourceDictionary.MergedDictionaries>\n\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.TextBackgroundBrush}\" Color=\"{DynamicResource {x:Static SystemColors.InfoColorKey}}\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.TextForegroundBrush}\" Color=\"{DynamicResource {x:Static SystemColors.InfoTextColorKey}}\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.SearchResultBackgroundBrush}\" Color=\"LightGreen\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.LineNumbersForegroundBrush}\" Color=\"Gray\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.CurrentLineBackgroundBrush}\" Color=\"#1614DCE0\" />\n\t<Pen x:Key=\"{x:Static themes:ResourceKeys.CurrentLineBorderPen}\" Brush=\"#3400FF6E\" Thickness=\"1\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.BracketHighlightBackgroundBrush}\" Color=\"#160000FF\" />\n\t<Pen x:Key=\"{x:Static themes:ResourceKeys.BracketHighlightBorderPen}\" Brush=\"#340000FF\" Thickness=\"1\" />\n\n\t<!-- ILAsm -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Comment\" Foreground=\"Green\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.String\" Foreground=\"Magenta\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Instructions\" Foreground=\"Blue\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Keywords\" Foreground=\"Blue\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Directives\" Foreground=\"Green\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Security\" Foreground=\"Red\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Label\" />\n\n\t<!-- Asm -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Comment\" Foreground=\"Green\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.NumberLiteral\" Foreground=\"Orange\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.String\" Foreground=\"Magenta\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Instructions\" Foreground=\"Blue\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Math Instructions\" Foreground=\"#0080C0\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Extended Instructions\" Foreground=\"Brown\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Registers\" Foreground=\"#8080FF\" Background=\"#EEEEEE\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Directives\" Foreground=\"Blue\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Directive Operands\" Foreground=\"DarkBlue\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Address and Bytes\" />\n\n\t<!-- CSharp -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Comment\" Foreground=\"Green\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.String\" Foreground=\"Blue\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.StringInterpolation\" Foreground=\"Black\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Char\" Foreground=\"Magenta\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Preprocessor\" Foreground=\"Green\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Punctuation\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ValueTypeKeywords\" Foreground=\"Red\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ReferenceTypeKeywords\" Foreground=\"Red\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.NumberLiteral\" Foreground=\"DarkBlue\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ThisOrBaseReference\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.NullOrValueKeywords\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Keywords\" Foreground=\"Blue\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.GotoKeywords\" Foreground=\"Navy\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.QueryKeywords\" Foreground=\"Navy\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ExceptionKeywords\" Foreground=\"Teal\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.CheckedKeyword\" Foreground=\"DarkGray\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.UnsafeKeywords\" Foreground=\"Olive\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.OperatorKeywords\" Foreground=\"Pink\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ParameterModifiers\" Foreground=\"DeepPink\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Modifiers\" Foreground=\"Brown\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Visibility\" Foreground=\"Blue\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.NamespaceKeywords\" Foreground=\"Green\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.GetSetAddRemove\" Foreground=\"SaddleBrown\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.TrueFalse\" Foreground=\"DarkCyan\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.TypeKeywords\" Foreground=\"DarkCyan\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.AttributeKeywords\" Foreground=\"Navy\" />\n\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ReferenceTypes\" Foreground=\"#004085\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.InterfaceTypes\" Foreground=\"#004085\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.TypeParameters\" Foreground=\"#004085\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.DelegateTypes\" Foreground=\"#004085\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ValueTypes\" FontWeight=\"Bold\" Foreground=\"#004085\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.EnumTypes\" FontWeight=\"Bold\" Foreground=\"#004085\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.MethodDeclaration\" Foreground=\"MidnightBlue\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.MethodCall\" Foreground=\"MidnightBlue\" FontWeight=\"Bold\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.FieldDeclaration\" FontStyle=\"Italic\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.FieldAccess\" FontStyle=\"Italic\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.PropertyDeclaration\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.PropertyAccess\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.EventDeclaration\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.EventAccess\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Variable\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Parameter\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.InactiveCode\" Foreground=\"Gray\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.SemanticError\" Foreground=\"DarkRed\" />\n\n\t<!-- XML -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.Comment\" Foreground=\"Green\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.CData\" Foreground=\"Blue\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.DocType\" Foreground=\"Blue\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.XmlDeclaration\" Foreground=\"Blue\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.XmlTag\" Foreground=\"DarkMagenta\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.AttributeName\" Foreground=\"Red\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.AttributeValue\" Foreground=\"Blue\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.Entity\" Foreground=\"Teal\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.BrokenEntity\" Foreground=\"Olive\" />\n\n</ResourceDictionary>\n"
  },
  {
    "path": "ILSpy/Themes/Theme.RSharpDark.xaml",
    "content": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n                    xmlns:themes=\"clr-namespace:ICSharpCode.ILSpy.Themes\">\n\t<ResourceDictionary.MergedDictionaries>\n\t\t<ResourceDictionary Source=\"Base.Dark.xaml\" />\n\t</ResourceDictionary.MergedDictionaries>\n\n\t<!-- Inspired from the ReSharper Dark theme, with some changes -->\n\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.TextBackgroundBrush}\" Color=\"#1E1E1E\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.TextForegroundBrush}\" Color=\"#DCDCDC\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.SearchResultBackgroundBrush}\" Color=\"#995A23\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.LineNumbersForegroundBrush}\" Color=\"#2B91AF\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.CurrentLineBackgroundBrush}\" Color=\"#0F0F0F\" />\n\t<Pen x:Key=\"{x:Static themes:ResourceKeys.CurrentLineBorderPen}\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.BracketHighlightBackgroundBrush}\" Color=\"#0E4583\" />\n\t<Pen x:Key=\"{x:Static themes:ResourceKeys.BracketHighlightBorderPen}\" />\n\n\t<Color x:Key=\"{x:Static themes:ResourceKeys.TextMarkerBackgroundColor}\">#483D8B</Color>\n\t<Color x:Key=\"{x:Static themes:ResourceKeys.TextMarkerDefinitionBackgroundColor}\">#800000</Color>\n\n\t<!-- ILAsm -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Comment\" Foreground=\"#57A64A\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.String\" Foreground=\"#D69D85\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Instructions\" Foreground=\"#D2691E\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Keywords\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Directives\" Foreground=\"#ADD8E6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Security\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Label\" Foreground=\"#696969\" />\n\n\t<!-- Asm -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Comment\" Foreground=\"#57A64A\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.NumberLiteral\" Foreground=\"#B5CEA8\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.String\" Foreground=\"#D69D85\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Instructions\" Foreground=\"#D2691E\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Math Instructions\" Foreground=\"#D2691E\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Extended Instructions\" Foreground=\"#D2691E\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Registers\" Foreground=\"#9CDCFE\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Directives\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Directive Operands\" Foreground=\"#9CDCFE\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Address and Bytes\" Foreground=\"#696969\" />\n\n\t<!-- CSharp -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Comment\" Foreground=\"#57A64A\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.String\" Foreground=\"#D69D85\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.StringInterpolation\" Foreground=\"#80FF80\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Char\" Foreground=\"#D69D85\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Preprocessor\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Punctuation\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ValueTypeKeywords\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ReferenceTypeKeywords\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.NumberLiteral\" Foreground=\"#B5CEA8\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ThisOrBaseReference\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.NullOrValueKeywords\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Keywords\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.GotoKeywords\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.QueryKeywords\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ExceptionKeywords\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.CheckedKeyword\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.UnsafeKeywords\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.OperatorKeywords\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ParameterModifiers\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Modifiers\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Visibility\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.NamespaceKeywords\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.GetSetAddRemove\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.TrueFalse\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.TypeKeywords\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.AttributeKeywords\" Foreground=\"#569CD6\" />\n\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ReferenceTypes\" Foreground=\"#ADD8E6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.InterfaceTypes\" Foreground=\"#ADD8E6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.TypeParameters\" Foreground=\"#ADD8E6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.DelegateTypes\" Foreground=\"#ADD8E6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ValueTypes\" Foreground=\"#ADB0E6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.EnumTypes\" Foreground=\"#ADB0E6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.MethodDeclaration\" Foreground=\"#00FFFF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.MethodCall\" Foreground=\"#00FFFF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.FieldDeclaration\" Foreground=\"#C4ADE6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.FieldAccess\" Foreground=\"#C4ADE6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.PropertyDeclaration\" Foreground=\"#C4ADE6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.PropertyAccess\" Foreground=\"#C4ADE6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.EventDeclaration\" Foreground=\"#DDA0DD\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.EventAccess\" Foreground=\"#DDA0DD\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Variable\" Foreground=\"#9CDCFE\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Parameter\" Foreground=\"#9CDCFE\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.InactiveCode\" Foreground=\"#A9A9A9\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.SemanticError\" Foreground=\"#FF3333\" />\n\n\t<!-- XML -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.Comment\" Foreground=\"#57A64A\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.CData\" Foreground=\"#C8C8C8\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.DocType\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.XmlDeclaration\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.XmlTag\" Foreground=\"#569CD6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.AttributeName\" Foreground=\"#92CAF4\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.AttributeValue\" Foreground=\"#C8C8C8\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.Entity\" Foreground=\"#92CAF4\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.BrokenEntity\" Foreground=\"#92CAF4\" />\n\n</ResourceDictionary>\n"
  },
  {
    "path": "ILSpy/Themes/Theme.RSharpLight.xaml",
    "content": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n                    xmlns:themes=\"clr-namespace:ICSharpCode.ILSpy.Themes\">\n\t<ResourceDictionary.MergedDictionaries>\n\t\t<ResourceDictionary Source=\"Base.Light.xaml\" />\n\t</ResourceDictionary.MergedDictionaries>\n\n\t<!-- Inspired from the ReSharper Light theme, with some changes -->\n\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.TextBackgroundBrush}\" Color=\"White\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.TextForegroundBrush}\" Color=\"Black\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.SearchResultBackgroundBrush}\" Color=\"#F6B94D\"/>\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.LineNumbersForegroundBrush}\" Color=\"#85A8AF\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.CurrentLineBackgroundBrush}\" Color=\"#F7F7F7\" />\n\t<Pen x:Key=\"{x:Static themes:ResourceKeys.CurrentLineBorderPen}\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.BracketHighlightBackgroundBrush}\" Color=\"#C4D5DB\" />\n\t<Pen x:Key=\"{x:Static themes:ResourceKeys.BracketHighlightBorderPen}\" />\n\n\t<Color x:Key=\"{x:Static themes:ResourceKeys.TextMarkerBackgroundColor}\">#87CEFA</Color>\n\t<Color x:Key=\"{x:Static themes:ResourceKeys.TextMarkerDefinitionBackgroundColor}\">#FFB6C1</Color>\n\n\t<!-- ILAsm -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Comment\" Foreground=\"#007F00\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.String\" Foreground=\"#A31515\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Instructions\" Foreground=\"#D2691E\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Keywords\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Directives\" Foreground=\"#00008B\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Security\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Label\" Foreground=\"#398A8A\" />\n\n\t<!-- Asm -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Comment\" Foreground=\"#007F00\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.NumberLiteral\" Foreground=\"#000000\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.String\" Foreground=\"#A31515\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Instructions\" Foreground=\"#D2691E\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Math Instructions\" Foreground=\"#D2691E\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Extended Instructions\" Foreground=\"#D2691E\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Registers\" Foreground=\"#1F377F\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Directives\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Directive Operands\" Foreground=\"#1F377F\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Address and Bytes\" Foreground=\"#398A8A\" />\n\n\t<!-- CSharp -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Comment\" Foreground=\"#007F00\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.String\" Foreground=\"#A31515\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.StringInterpolation\" Foreground=\"#008000\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Char\" Foreground=\"#A31515\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Preprocessor\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Punctuation\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ValueTypeKeywords\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ReferenceTypeKeywords\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.NumberLiteral\" Foreground=\"#000000\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ThisOrBaseReference\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.NullOrValueKeywords\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Keywords\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.GotoKeywords\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.QueryKeywords\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ExceptionKeywords\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.CheckedKeyword\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.UnsafeKeywords\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.OperatorKeywords\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ParameterModifiers\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Modifiers\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Visibility\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.NamespaceKeywords\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.GetSetAddRemove\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.TrueFalse\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.TypeKeywords\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.AttributeKeywords\" Foreground=\"#0000FF\" />\n\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ReferenceTypes\" Foreground=\"#00008B\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.InterfaceTypes\" Foreground=\"#00008B\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.TypeParameters\" Foreground=\"#00008B\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.DelegateTypes\" Foreground=\"#00008B\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ValueTypes\" Foreground=\"#3F008F\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.EnumTypes\" Foreground=\"#3F008F\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.MethodDeclaration\" Foreground=\"#008B8B\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.MethodCall\" Foreground=\"#008B8B\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.FieldDeclaration\" Foreground=\"#660E7A\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.FieldAccess\" Foreground=\"#660E7A\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.PropertyDeclaration\" Foreground=\"#660E7A\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.PropertyAccess\" Foreground=\"#660E7A\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.EventDeclaration\" Foreground=\"#FF00FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.EventAccess\" Foreground=\"#FF00FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Variable\" Foreground=\"#1F377F\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Parameter\" Foreground=\"#1F377F\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.InactiveCode\" Foreground=\"#A9A9A9\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.SemanticError\" Foreground=\"#FF0000\" />\n\n\t<!-- XML -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.Comment\" Foreground=\"#007F00\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.CData\" Foreground=\"#000000\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.DocType\" Foreground=\"#A31515\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.XmlDeclaration\" Foreground=\"#A31515\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.XmlTag\" Foreground=\"#A31515\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.AttributeName\" Foreground=\"#FF0000\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.AttributeValue\" Foreground=\"#0000FF\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.Entity\" Foreground=\"#FF0000\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.BrokenEntity\" Foreground=\"#FF0000\" />\n\n</ResourceDictionary>\n"
  },
  {
    "path": "ILSpy/Themes/Theme.VSCodeDarkPlus.xaml",
    "content": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n                    xmlns:themes=\"clr-namespace:ICSharpCode.ILSpy.Themes\">\n\t<ResourceDictionary.MergedDictionaries>\n\t\t<ResourceDictionary Source=\"Base.Dark.xaml\" />\n\t</ResourceDictionary.MergedDictionaries>\n\n\t<!--\n\t\tColors taken from the VS Code Dark+ theme\n\n\t\thttps://github.com/microsoft/vscode/blob/main/extensions/theme-defaults/themes/dark_vs.json\n\t\thttps://github.com/microsoft/vscode/blob/main/extensions/theme-defaults/themes/dark_plus.json\n\t-->\n\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.TextBackgroundBrush}\" Color=\"#1E1E1E\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.TextForegroundBrush}\" Color=\"#D4D4D4\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.SearchResultBackgroundBrush}\" Color=\"#613214\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.LineNumbersForegroundBrush}\" Color=\"#858585\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.CurrentLineBackgroundBrush}\" />\n\t<Pen x:Key=\"{x:Static themes:ResourceKeys.CurrentLineBorderPen}\" Brush=\"#282828\" Thickness=\"2\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.BracketHighlightBackgroundBrush}\" Color=\"#1B251B\" />\n\t<Pen x:Key=\"{x:Static themes:ResourceKeys.BracketHighlightBorderPen}\" Brush=\"#888888\" Thickness=\"1\" />\n\n\t<Color x:Key=\"{x:Static themes:ResourceKeys.TextMarkerBackgroundColor}\">#264F78</Color>\n\t<Color x:Key=\"{x:Static themes:ResourceKeys.TextMarkerDefinitionBackgroundColor}\">#343A40</Color>\n\n\t<!-- ILAsm -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Comment\" Foreground=\"#6A9955\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.String\" Foreground=\"#ce9178\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Instructions\" Foreground=\"#C586C0\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Keywords\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Directives\" Foreground=\"#DCDCAA\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Security\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Label\" Foreground=\"#6A9955\" />\n\n\t<!-- Asm -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Comment\" Foreground=\"#6A9955\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.NumberLiteral\" Foreground=\"#b5cea8\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.String\" Foreground=\"#ce9178\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Instructions\" Foreground=\"#C586C0\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Math Instructions\" Foreground=\"#C586C0\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Extended Instructions\" Foreground=\"#C586C0\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Registers\" Foreground=\"#DCDCAA\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Directives\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Directive Operands\" Foreground=\"#DCDCAA\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Address and Bytes\" Foreground=\"#ce9178\" />\n\n\t<!-- CSharp -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Comment\" Foreground=\"#6A9955\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.String\" Foreground=\"#ce9178\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.StringInterpolation\" Foreground=\"#d16969\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Char\" Foreground=\"#ce9178\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Preprocessor\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Punctuation\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ValueTypeKeywords\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ReferenceTypeKeywords\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.NumberLiteral\" Foreground=\"#b5cea8\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ThisOrBaseReference\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.NullOrValueKeywords\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Keywords\" Foreground=\"#C586C0\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.GotoKeywords\" Foreground=\"#C586C0\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.QueryKeywords\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ExceptionKeywords\" Foreground=\"#C586C0\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.CheckedKeyword\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.UnsafeKeywords\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.OperatorKeywords\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ParameterModifiers\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Modifiers\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Visibility\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.NamespaceKeywords\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.GetSetAddRemove\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.TrueFalse\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.TypeKeywords\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.AttributeKeywords\" Foreground=\"#569cd6\" />\n\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ReferenceTypes\" Foreground=\"#4EC9B0\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.InterfaceTypes\" Foreground=\"#4EC9B0\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.TypeParameters\" Foreground=\"#4EC9B0\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.DelegateTypes\" Foreground=\"#4EC9B0\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ValueTypes\" Foreground=\"#4EC9B0\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.EnumTypes\" Foreground=\"#4EC9B0\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.MethodDeclaration\" Foreground=\"#DCDCAA\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.MethodCall\" Foreground=\"#DCDCAA\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.FieldDeclaration\" Foreground=\"#9CDCFE\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.FieldAccess\" Foreground=\"#9CDCFE\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.PropertyDeclaration\" Foreground=\"#9CDCFE\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.PropertyAccess\" Foreground=\"#9CDCFE\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.EventDeclaration\" Foreground=\"#9CDCFE\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.EventAccess\" Foreground=\"#9CDCFE\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Variable\" Foreground=\"#9CDCFE\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Parameter\" Foreground=\"#9CDCFE\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.InactiveCode\" Foreground=\"#A6A6A6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.SemanticError\" Foreground=\"#f44747\" />\n\n\t<!-- XML -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.Comment\" Foreground=\"#6A9955\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.CData\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.DocType\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.XmlDeclaration\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.XmlTag\" Foreground=\"#569cd6\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.AttributeName\" Foreground=\"#9cdcfe\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.AttributeValue\" Foreground=\"#ce9178\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.Entity\" Foreground=\"#b5cea8\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.BrokenEntity\" Foreground=\"#f44747\" />\n\n</ResourceDictionary>\n"
  },
  {
    "path": "ILSpy/Themes/Theme.VSCodeLightPlus.xaml",
    "content": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n                    xmlns:themes=\"clr-namespace:ICSharpCode.ILSpy.Themes\">\n\t<ResourceDictionary.MergedDictionaries>\n\t\t<ResourceDictionary Source=\"Base.Light.xaml\" />\n\t</ResourceDictionary.MergedDictionaries>\n\n\t<!--\n\t\tColors taken from the VS Code Light+ theme\n\n\t\thttps://github.com/microsoft/vscode/blob/main/extensions/theme-defaults/themes/light_vs.json\n\t\thttps://github.com/microsoft/vscode/blob/main/extensions/theme-defaults/themes/light_plus.json\n\t-->\n\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.TextBackgroundBrush}\" Color=\"White\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.TextForegroundBrush}\" Color=\"Black\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.SearchResultBackgroundBrush}\" Color=\"#F8C9AB\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.LineNumbersForegroundBrush}\" Color=\"#237893\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.CurrentLineBackgroundBrush}\" />\n\t<Pen x:Key=\"{x:Static themes:ResourceKeys.CurrentLineBorderPen}\" Brush=\"#EEEEEE\" Thickness=\"2\" />\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.BracketHighlightBackgroundBrush}\" Color=\"#E5EFE5\" />\n\t<Pen x:Key=\"{x:Static themes:ResourceKeys.BracketHighlightBorderPen}\" Brush=\"#B9B9B9\" Thickness=\"1\" />\n\n\t<Color x:Key=\"{x:Static themes:ResourceKeys.TextMarkerBackgroundColor}\">#ADD6FF</Color>\n\t<Color x:Key=\"{x:Static themes:ResourceKeys.TextMarkerDefinitionBackgroundColor}\">#D6EAFF</Color>\n\n\t<!-- ILAsm -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Comment\" Foreground=\"#008000\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.String\" Foreground=\"#a31515\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Instructions\" Foreground=\"#AF00DB\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Keywords\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Directives\" Foreground=\"#795E26\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Security\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.ILAsm.Label\" Foreground=\"#0451a5\" />\n\n\t<!-- Asm -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Comment\" Foreground=\"#008000\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.NumberLiteral\" Foreground=\"#098658\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.String\" Foreground=\"#a31515\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Instructions\" Foreground=\"#AF00DB\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Math Instructions\" Foreground=\"#AF00DB\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Extended Instructions\" Foreground=\"#AF00DB\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Registers\" Foreground=\"#795E26\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Directives\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Directive Operands\" Foreground=\"#795E26\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.Asm.Address and Bytes\" Foreground=\"#0451a5\" />\n\n\t<!-- CSharp -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Comment\" Foreground=\"#008000\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.String\" Foreground=\"#a31515\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.StringInterpolation\" Foreground=\"#d16969\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Char\" Foreground=\"#a31515\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Preprocessor\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Punctuation\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ValueTypeKeywords\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ReferenceTypeKeywords\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.NumberLiteral\" Foreground=\"#098658\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ThisOrBaseReference\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.NullOrValueKeywords\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Keywords\" Foreground=\"#AF00DB\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.GotoKeywords\" Foreground=\"#AF00DB\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.QueryKeywords\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ExceptionKeywords\" Foreground=\"#AF00DB\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.CheckedKeyword\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.UnsafeKeywords\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.OperatorKeywords\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ParameterModifiers\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Modifiers\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Visibility\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.NamespaceKeywords\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.GetSetAddRemove\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.TrueFalse\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.TypeKeywords\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.AttributeKeywords\" Foreground=\"#0000ff\" />\n\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ReferenceTypes\" Foreground=\"#267f99\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.InterfaceTypes\" Foreground=\"#267f99\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.TypeParameters\" Foreground=\"#267f99\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.DelegateTypes\" Foreground=\"#267f99\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.ValueTypes\" Foreground=\"#267f99\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.EnumTypes\" Foreground=\"#267f99\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.MethodDeclaration\" Foreground=\"#795E26\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.MethodCall\" Foreground=\"#795E26\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.FieldDeclaration\" Foreground=\"#001080\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.FieldAccess\" Foreground=\"#001080\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.PropertyDeclaration\" Foreground=\"#001080\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.PropertyAccess\" Foreground=\"#001080\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.EventDeclaration\" Foreground=\"#001080\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.EventAccess\" Foreground=\"#001080\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Variable\" Foreground=\"#001080\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.Parameter\" Foreground=\"#001080\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.InactiveCode\" Foreground=\"#767676\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.C#.SemanticError\" Foreground=\"#cd3131\" />\n\n\t<!-- XML -->\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.Comment\" Foreground=\"#008000\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.CData\" Foreground=\"#800000\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.DocType\" Foreground=\"#800000\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.XmlDeclaration\" Foreground=\"#800000\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.XmlTag\" Foreground=\"#800000\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.AttributeName\" Foreground=\"#e50000\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.AttributeValue\" Foreground=\"#0000ff\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.Entity\" Foreground=\"#098658\" />\n\t<themes:SyntaxColor x:Key=\"SyntaxColor.XML.BrokenEntity\" Foreground=\"#cd3131\" />\n\n</ResourceDictionary>\n"
  },
  {
    "path": "ILSpy/Themes/ThemeManager.cs",
    "content": "// Copyright (c) 2021 Tom Englert\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Controls.Primitives;\nusing System.Windows.Media;\n\nusing ICSharpCode.AvalonEdit.Highlighting;\n\nnamespace ICSharpCode.ILSpy.Themes\n{\n\tpublic class ThemeManager\n\t{\n\t\tprivate const string _isThemeAwareKey = \"ILSpy.IsThemeAware\";\n\n\t\tprivate string? _theme;\n\t\tprivate readonly ResourceDictionary _themeDictionaryContainer = new();\n\t\tprivate readonly Dictionary<string, SyntaxColor> _syntaxColors = new();\n\n\t\tpublic static readonly ThemeManager Current = new();\n\n\t\tprivate ThemeManager()\n\t\t{\n\t\t\tApplication.Current.Resources.MergedDictionaries.Add(_themeDictionaryContainer);\n\t\t\tMessageBus<SettingsChangedEventArgs>.Subscribers += (sender, e) => Settings_Changed(sender, e);\n\t\t}\n\n\t\tpublic string DefaultTheme => \"Light\";\n\n\t\tpublic bool IsDarkTheme { get; private set; }\n\n\t\tpublic static IReadOnlyCollection<string> AllThemes => new[] {\n\t\t\t\"Light\",\n\t\t\t\"Dark\",\n\t\t\t\"VS Code Light+\",\n\t\t\t\"VS Code Dark+\",\n\t\t\t\"R# Light\",\n\t\t\t\"R# Dark\"\n\t\t};\n\n\t\tpublic string? Theme {\n\t\t\tget => _theme;\n\t\t\tset => UpdateTheme(value);\n\t\t}\n\n\t\tpublic Button CreateButton()\n\t\t{\n\t\t\treturn new Button {\n\t\t\t\tStyle = CreateButtonStyle()\n\t\t\t};\n\t\t}\n\n\t\tpublic Style CreateButtonStyle()\n\t\t{\n\t\t\treturn new Style(typeof(Button), (Style)Application.Current.FindResource(typeof(Button)));\n\t\t}\n\n\t\tpublic Style CreateToolBarButtonStyle()\n\t\t{\n\t\t\treturn new Style(typeof(Button), (Style)Application.Current.FindResource(ToolBar.ButtonStyleKey));\n\t\t}\n\n\t\tpublic Style CreateToolBarToggleButtonStyle()\n\t\t{\n\t\t\treturn new Style(typeof(ToggleButton), (Style)Application.Current.FindResource(ToolBar.ToggleButtonStyleKey));\n\t\t}\n\n\t\tpublic void ApplyHighlightingColors(IHighlightingDefinition highlightingDefinition)\n\t\t{\n\t\t\t// Make sure all color values are taken from the theme\n\t\t\tforeach (var color in highlightingDefinition.NamedHighlightingColors)\n\t\t\t\tSyntaxColor.ResetColor(color);\n\n\t\t\tvar prefix = $\"SyntaxColor.{highlightingDefinition.Name}.\";\n\n\t\t\tforeach (var (key, syntaxColor) in _syntaxColors)\n\t\t\t{\n\t\t\t\tvar color = highlightingDefinition.GetNamedColor(key.Substring(prefix.Length));\n\t\t\t\tif (color is not null)\n\t\t\t\t\tsyntaxColor.ApplyTo(color);\n\t\t\t}\n\n\t\t\thighlightingDefinition.Properties[_isThemeAwareKey] = bool.TrueString;\n\t\t}\n\n\t\tpublic bool IsThemeAware(IHighlightingDefinition highlightingDefinition)\n\t\t{\n\t\t\treturn highlightingDefinition.Properties.TryGetValue(_isThemeAwareKey, out var value) && value == bool.TrueString;\n\t\t}\n\n\t\tprivate void UpdateTheme(string? themeName)\n\t\t{\n\t\t\t_theme = themeName ?? DefaultTheme;\n\t\t\tif (!AllThemes.Contains(_theme))\n\t\t\t\t_theme = DefaultTheme;\n\n\t\t\tvar themeFileName = _theme\n\t\t\t\t.Replace(\"+\", \"Plus\")\n\t\t\t\t.Replace(\"#\", \"Sharp\")\n\t\t\t\t.Replace(\" \", \"\");\n\n\t\t\t_themeDictionaryContainer.MergedDictionaries.Clear();\n\t\t\t_syntaxColors.Clear();\n\n\t\t\t// Load SyntaxColor info from theme XAML\n\t\t\tvar resourceDictionary = new ResourceDictionary { Source = new Uri($\"/themes/Theme.{themeFileName}.xaml\", UriKind.Relative) };\n\t\t\t_themeDictionaryContainer.MergedDictionaries.Add(resourceDictionary);\n\n\t\t\tIsDarkTheme = resourceDictionary[ResourceKeys.TextBackgroundBrush] is SolidColorBrush { Color: { R: < 128, G: < 128, B: < 128 } };\n\n\t\t\t// Iterate over keys first, because we don't want to instantiate all values eagerly, if we don't need them.\n\t\t\tforeach (var item in resourceDictionary.Keys)\n\t\t\t{\n\t\t\t\tif (item is string key && key.StartsWith(\"SyntaxColor.\", StringComparison.Ordinal))\n\t\t\t\t{\n\t\t\t\t\tif (resourceDictionary[key] is SyntaxColor syntaxColor)\n\t\t\t\t\t\t_syntaxColors.TryAdd(key, syntaxColor);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static HighlightingColor GetColorForDarkTheme(HighlightingColor lightColor)\n\t\t{\n\t\t\tif (lightColor.Foreground is null && lightColor.Background is null)\n\t\t\t{\n\t\t\t\treturn lightColor;\n\t\t\t}\n\n\t\t\tvar darkColor = lightColor.Clone();\n\t\t\tdarkColor.Foreground = AdjustForDarkTheme(darkColor.Foreground);\n\t\t\tdarkColor.Background = AdjustForDarkTheme(darkColor.Background);\n\n\t\t\treturn darkColor;\n\t\t}\n\n\t\tprivate static HighlightingBrush? AdjustForDarkTheme(HighlightingBrush? lightBrush)\n\t\t{\n\t\t\tif (lightBrush is SimpleHighlightingBrush simpleBrush && simpleBrush.GetBrush(null) is SolidColorBrush brush)\n\t\t\t{\n\t\t\t\treturn new SimpleHighlightingBrush(AdjustForDarkTheme(brush.Color));\n\t\t\t}\n\n\t\t\treturn lightBrush;\n\t\t}\n\n\t\tprivate static Color AdjustForDarkTheme(Color color)\n\t\t{\n\t\t\tvar c = System.Drawing.Color.FromArgb(color.R, color.G, color.B);\n\t\t\tvar (h, s, l) = (c.GetHue(), c.GetSaturation(), c.GetBrightness());\n\n\t\t\t// Invert the lightness, but also increase it a bit\n\t\t\tl = 1f - MathF.Pow(l, 1.2f);\n\n\t\t\t// Desaturate the colors, as they'd be too intense otherwise\n\t\t\tif (s > 0.75f && l < 0.75f)\n\t\t\t{\n\t\t\t\ts *= 0.75f;\n\t\t\t\tl *= 1.2f;\n\t\t\t}\n\n\t\t\tvar (r, g, b) = HslToRgb(h, s, l);\n\t\t\treturn Color.FromArgb(color.A, r, g, b);\n\t\t}\n\n\t\tprivate static (byte r, byte g, byte b) HslToRgb(float h, float s, float l)\n\t\t{\n\t\t\t// https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB\n\n\t\t\tvar c = (1f - Math.Abs(2f * l - 1f)) * s;\n\t\t\th = h % 360f / 60f;\n\t\t\tvar x = c * (1f - Math.Abs(h % 2f - 1f));\n\n\t\t\tvar (r1, g1, b1) = (int)Math.Floor(h) switch {\n\t\t\t\t0 => (c, x, 0f),\n\t\t\t\t1 => (x, c, 0f),\n\t\t\t\t2 => (0f, c, x),\n\t\t\t\t3 => (0f, x, c),\n\t\t\t\t4 => (x, 0f, c),\n\t\t\t\t_ => (c, 0f, x)\n\t\t\t};\n\n\t\t\tvar m = l - c / 2f;\n\t\t\tvar r = (byte)((r1 + m) * 255f);\n\t\t\tvar g = (byte)((g1 + m) * 255f);\n\t\t\tvar b = (byte)((b1 + m) * 255f);\n\t\t\treturn (r, g, b);\n\t\t}\n\n\t\tprivate void Settings_Changed(object? sender, PropertyChangedEventArgs e)\n\t\t{\n\t\t\tif (sender is not SessionSettings settings || e.PropertyName != nameof(SessionSettings.Theme))\n\t\t\t\treturn;\n\n\t\t\tTheme = settings.Theme;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Themes/WindowStyleManagerBehavior.cs",
    "content": "// Copyright (c) 2021 Tom Englert\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.ComponentModel;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Interop;\nusing System.Windows.Media;\n\nusing ICSharpCode.ILSpy.Options;\n\nusing TomsToolbox.Essentials;\nusing TomsToolbox.Wpf;\nusing TomsToolbox.Wpf.Composition;\nusing TomsToolbox.Wpf.Interactivity;\n\nnamespace ICSharpCode.ILSpy.Themes\n{\n\tpublic class WindowStyleManagerBehavior : FrameworkElementBehavior<Window>\n\t{\n\t\tprivate static readonly DispatcherThrottle restartNotificationThrottle = new DispatcherThrottle(ShowRestartNotification);\n\n\t\tprivate INotifyChanged _foreground;\n\t\tprivate INotifyChanged _background;\n\n\t\tprotected override void OnAttached()\n\t\t{\n\t\t\tbase.OnAttached();\n\n\t\t\tMessageBus<SettingsChangedEventArgs>.Subscribers += (sender, e) => Settings_PropertyChanged(sender, e);\n\n\t\t\t_foreground = AssociatedObject.Track(Control.ForegroundProperty);\n\t\t\t_background = AssociatedObject.Track(Control.BackgroundProperty);\n\n\t\t\t_foreground.Changed += Color_Changed;\n\t\t\t_background.Changed += Color_Changed;\n\n\t\t\tUpdateWindowStyle(AssociatedObject.GetExportProvider().GetExportedValue<SettingsService>().DisplaySettings);\n\t\t\tApplyThemeToWindowCaption();\n\t\t}\n\n\t\tprotected override void OnDetaching()\n\t\t{\n\t\t\tbase.OnDetaching();\n\n\t\t\t_foreground.Changed -= Color_Changed;\n\t\t\t_background.Changed -= Color_Changed;\n\t\t}\n\n\t\tprivate void Color_Changed(object sender, EventArgs e)\n\t\t{\n\t\t\tApplyThemeToWindowCaption();\n\t\t}\n\n\t\tprivate void UpdateWindowStyle(DisplaySettings displaySettings)\n\t\t{\n\t\t\tvar window = AssociatedObject;\n\n\t\t\tif (displaySettings.StyleWindowTitleBar)\n\t\t\t{\n\t\t\t\twindow.Style = (Style)window.FindResource(TomsToolbox.Wpf.Styles.ResourceKeys.WindowStyle);\n\t\t\t}\n\t\t}\n\n\t\tprivate static void ShowRestartNotification()\n\t\t{\n\t\t\tMessageBox.Show(Properties.Resources.SettingsChangeRestartRequired);\n\t\t}\n\n\t\tprivate void Settings_PropertyChanged(object sender, PropertyChangedEventArgs e)\n\t\t{\n\t\t\tif (sender is not DisplaySettings displaySettings)\n\t\t\t\treturn;\n\n\t\t\tif (e.PropertyName != nameof(DisplaySettings.StyleWindowTitleBar))\n\t\t\t\treturn;\n\n\t\t\tif (!displaySettings.StyleWindowTitleBar)\n\t\t\t{\n\t\t\t\trestartNotificationThrottle.Tick();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tUpdateWindowStyle(displaySettings);\n\t\t}\n\n\t\tprivate void ApplyThemeToWindowCaption()\n\t\t{\n\t\t\tvar window = AssociatedObject;\n\n\t\t\tIntPtr hwnd = new WindowInteropHelper(window).Handle;\n\n\t\t\tif (hwnd != IntPtr.Zero)\n\t\t\t{\n\t\t\t\tvar foreground = ((window.Foreground as SolidColorBrush)?.Color).ToGray();\n\t\t\t\tvar background = ((window.Background as SolidColorBrush)?.Color).ToGray();\n\n\t\t\t\tvar isDarkTheme = background < foreground;\n\n\t\t\t\tNativeMethods.UseImmersiveDarkMode(hwnd, isDarkTheme);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvoid Initialized(object o, EventArgs eventArgs)\n\t\t\t\t{\n\t\t\t\t\tApplyThemeToWindowCaption();\n\t\t\t\t\twindow.SourceInitialized -= Initialized;\n\t\t\t\t}\n\n\t\t\t\twindow.SourceInitialized += Initialized;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Themes/generic.xaml",
    "content": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n\txmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n\txmlns:controls=\"clr-namespace:ICSharpCode.ILSpy.Controls\"\n\txmlns:themes=\"clr-namespace:ICSharpCode.ILSpy.Themes\">\n\t<ResourceDictionary.MergedDictionaries>\n\t\t<ResourceDictionary Source=\"../Controls/SearchBoxStyle.xaml\" />\n\t\t<ResourceDictionary Source=\"../Controls/ZoomScrollViewer.xaml\" />\n\t\t<ResourceDictionary Source=\"../Controls/TreeView/SharpTreeView.xaml\" />\n\t</ResourceDictionary.MergedDictionaries>\n\n\t<!-- SortableGridViewColumn.\n\t\tDisplays an up arrow or down arrow in the column header when the grid is sorted using that column.\n\t-->\n\t<controls:ColumnSortDirectionToVisibilityConverter x:Key=\"ColumnSortDirectionToVisibilityConverter\"/>\n\n\t<DataTemplate x:Key=\"{ComponentResourceKey {x:Type controls:SortableGridViewColumn}, ColumnHeaderTemplate}\">\n\t\t<StackPanel Orientation=\"Horizontal\">\n\t\t\t<TextBlock HorizontalAlignment=\"Center\" Text=\"{Binding}\"/>\n\t\t\t<Path x:Name=\"upArrow\"\n\t\t\t      Visibility=\"{Binding Path=Column.SortDirection, ConverterParameter={x:Static controls:ColumnSortDirection.Ascending}, RelativeSource={RelativeSource AncestorType={x:Type GridViewColumnHeader}}, Converter={StaticResource ColumnSortDirectionToVisibilityConverter}}\"\n\t\t\t      StrokeThickness = \"1\"\n\t\t\t      Fill            = \"Gray\"\n\t\t\t      Data            = \"M 5,10 L 15,10 L 10,5 L 5,10\"/>\n\t\t\t<Path x:Name=\"downArrow\"\n\t\t\t      Visibility=\"{Binding Path=Column.SortDirection, ConverterParameter={x:Static controls:ColumnSortDirection.Descending}, RelativeSource={RelativeSource AncestorType={x:Type GridViewColumnHeader}}, Converter={StaticResource ColumnSortDirectionToVisibilityConverter}}\"\n\t\t\t      StrokeThickness = \"1\"\n\t\t\t      Fill            = \"Gray\"\n\t\t\t      Data            = \"M 5,5 L 10,10 L 15,5 L 5,5\"/>\n\t\t</StackPanel>\n\t</DataTemplate>\n\n\t<Color x:Key=\"{x:Static themes:ResourceKeys.TextMarkerBackgroundColor}\">GreenYellow</Color>\n\t<Color x:Key=\"{x:Static themes:ResourceKeys.TextMarkerDefinitionBackgroundColor}\">LightSeaGreen</Color>\n\t<SolidColorBrush x:Key=\"{x:Static themes:ResourceKeys.LinkTextForegroundBrush}\">Blue</SolidColorBrush>\n</ResourceDictionary>"
  },
  {
    "path": "ILSpy/TreeNodes/AssemblyListTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.Linq;\nusing System.Windows;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.Util;\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.TreeView;\nusing ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// Represents a list of assemblies.\n\t/// This is used as (invisible) root node of the tree view.\n\t/// </summary>\n\tsealed class AssemblyListTreeNode : ILSpyTreeNode\n\t{\n\t\treadonly AssemblyList assemblyList;\n\n\t\tpublic AssemblyList AssemblyList {\n\t\t\tget { return assemblyList; }\n\t\t}\n\n\t\tpublic AssemblyListTreeNode(AssemblyList assemblyList)\n\t\t{\n\t\t\tArgumentNullException.ThrowIfNull(assemblyList);\n\n\t\t\tthis.assemblyList = assemblyList;\n\n\t\t\tBindToObservableCollection(assemblyList);\n\t\t}\n\n\t\tpublic override object Text {\n\t\t\tget { return assemblyList.ListName; }\n\t\t}\n\n\t\tvoid BindToObservableCollection(AssemblyList collection)\n\t\t{\n\t\t\tthis.Children.Clear();\n\t\t\tthis.Children.AddRange(collection.GetAssemblies().Select(a => new AssemblyTreeNode(a)));\n\t\t\tcollection.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {\n\t\t\t\tswitch (e.Action)\n\t\t\t\t{\n\t\t\t\t\tcase NotifyCollectionChangedAction.Add:\n\t\t\t\t\t\tthis.Children.InsertRange(e.NewStartingIndex, e.NewItems.Cast<LoadedAssembly>().Select(a => new AssemblyTreeNode(a)));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase NotifyCollectionChangedAction.Remove:\n\t\t\t\t\t\tthis.Children.RemoveRange(e.OldStartingIndex, e.OldItems.Count);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase NotifyCollectionChangedAction.Replace:\n\t\t\t\t\t\tthis.Children.RemoveRange(e.OldStartingIndex, e.OldItems.Count);\n\t\t\t\t\t\tthis.Children.InsertRange(e.NewStartingIndex, e.NewItems.Cast<LoadedAssembly>().Select(a => new AssemblyTreeNode(a)));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase NotifyCollectionChangedAction.Move:\n\t\t\t\t\t\tthrow new NotImplementedException();\n\t\t\t\t\tcase NotifyCollectionChangedAction.Reset:\n\t\t\t\t\t\tthis.Children.Clear();\n\t\t\t\t\t\tthis.Children.AddRange(collection.GetAssemblies().Select(a => new AssemblyTreeNode(a)));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new NotSupportedException(\"Invalid value for NotifyCollectionChangedAction\");\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\tpublic override bool CanDrop(IPlatformDragEventArgs e, int index)\n\t\t{\n\t\t\te.Effects = XPlatDragDropEffects.Move | XPlatDragDropEffects.Copy | XPlatDragDropEffects.Link;\n\t\t\tif (e.Data.GetDataPresent(AssemblyTreeNode.DataFormat))\n\t\t\t\treturn true;\n\t\t\tif (e.Data.GetDataPresent(DataFormats.FileDrop))\n\t\t\t\treturn true;\n\t\t\te.Effects = XPlatDragDropEffects.None;\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic override void Drop(IPlatformDragEventArgs e, int index)\n\t\t{\n\t\t\tstring[] files = e.Data.GetData(AssemblyTreeNode.DataFormat) as string[];\n\t\t\tif (files == null)\n\t\t\t\tfiles = e.Data.GetData(DataFormats.FileDrop) as string[];\n\t\t\tif (files != null)\n\t\t\t{\n\t\t\t\tvar assemblies = files\n\t\t\t\t\t.Where(file => file != null)\n\t\t\t\t\t.Select(file => assemblyList.OpenAssembly(file))\n\t\t\t\t\t.Where(asm => asm != null)\n\t\t\t\t\t.Distinct()\n\t\t\t\t\t.ToArray();\n\t\t\t\tassemblyList.Move(assemblies, index);\n\t\t\t\tvar nodes = assemblies.SelectArray(AssemblyTreeModel.FindTreeNode);\n\t\t\t\tAssemblyTreeModel.SelectNodes(nodes);\n\t\t\t}\n\t\t}\n\n\t\tpublic Action<SharpTreeNode> Select = delegate { };\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.WriteCommentLine(output, \"List: \" + assemblyList.ListName);\n\t\t\toutput.WriteLine();\n\t\t\tforeach (AssemblyTreeNode asm in this.Children)\n\t\t\t{\n\t\t\t\tlanguage.WriteCommentLine(output, new string('-', 60));\n\t\t\t\toutput.WriteLine();\n\t\t\t\tasm.Decompile(language, output, options);\n\t\t\t}\n\t\t}\n\n\t\t#region Find*Node\n\t\tpublic ILSpyTreeNode FindResourceNode(Resource resource)\n\t\t{\n\t\t\tif (resource == null)\n\t\t\t\treturn null;\n\t\t\tforeach (AssemblyTreeNode node in this.Children)\n\t\t\t{\n\t\t\t\tif (node.LoadedAssembly.IsLoaded)\n\t\t\t\t{\n\t\t\t\t\tnode.EnsureLazyChildren();\n\t\t\t\t\tforeach (var item in node.Children.OfType<ResourceListTreeNode>())\n\t\t\t\t\t{\n\t\t\t\t\t\tvar founded = item.Children.OfType<ResourceTreeNode>().Where(x => x.Resource == resource).FirstOrDefault();\n\t\t\t\t\t\tif (founded != null)\n\t\t\t\t\t\t\treturn founded;\n\n\t\t\t\t\t\tvar foundedResEntry = item.Children.OfType<ResourceEntryNode>().Where(x => resource.Name.Equals(x.Text)).FirstOrDefault();\n\t\t\t\t\t\tif (foundedResEntry != null)\n\t\t\t\t\t\t\treturn foundedResEntry;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic ILSpyTreeNode FindResourceNode(Resource resource, string name)\n\t\t{\n\t\t\tvar resourceNode = FindResourceNode(resource);\n\t\t\tif (resourceNode == null || name == null || name.Equals(resourceNode.Text))\n\t\t\t\treturn resourceNode;\n\n\t\t\tresourceNode.EnsureLazyChildren();\n\t\t\treturn resourceNode.Children.OfType<ILSpyTreeNode>().Where(x => name.Equals(x.Text)).FirstOrDefault() ?? resourceNode;\n\t\t}\n\n\t\tpublic AssemblyTreeNode FindAssemblyNode(IModule module)\n\t\t{\n\t\t\treturn FindAssemblyNode(module.MetadataFile);\n\t\t}\n\n\t\tpublic AssemblyTreeNode FindAssemblyNode(MetadataFile module)\n\t\t{\n\t\t\tif (module == null)\n\t\t\t\treturn null;\n\t\t\treturn FindAssemblyNode(module.GetLoadedAssembly());\n\t\t}\n\n\t\tpublic AssemblyTreeNode FindAssemblyNode(LoadedAssembly asm)\n\t\t{\n\t\t\tif (asm == null)\n\t\t\t\treturn null;\n\t\t\tApp.Current.Dispatcher.VerifyAccess();\n\t\t\tif (asm.ParentBundle != null)\n\t\t\t{\n\t\t\t\tvar bundle = FindAssemblyNode(asm.ParentBundle);\n\t\t\t\tif (bundle == null)\n\t\t\t\t\treturn null;\n\t\t\t\tbundle.EnsureLazyChildren();\n\t\t\t\tforeach (var node in TreeTraversal.PreOrder(bundle.Children, ExpandAndGetChildren).OfType<AssemblyTreeNode>())\n\t\t\t\t{\n\t\t\t\t\tif (node.LoadedAssembly == asm)\n\t\t\t\t\t\treturn node;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tforeach (AssemblyTreeNode node in this.Children)\n\t\t\t\t{\n\t\t\t\t\tif (node.LoadedAssembly == asm)\n\t\t\t\t\t\treturn node;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\n\t\t\tstatic SharpTreeNodeCollection ExpandAndGetChildren(SharpTreeNode node)\n\t\t\t{\n\t\t\t\tif (node is not PackageFolderTreeNode)\n\t\t\t\t\treturn null;\n\t\t\t\tnode.EnsureLazyChildren();\n\t\t\t\treturn node.Children;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Looks up the type node corresponding to the type definition.\n\t\t/// Returns null if no matching node is found.\n\t\t/// </summary>\n\t\tpublic TypeTreeNode FindTypeNode(ITypeDefinition def)\n\t\t{\n\t\t\tif (def == null)\n\t\t\t\treturn null;\n\t\t\tvar declaringType = def.DeclaringTypeDefinition;\n\t\t\tif (declaringType != null)\n\t\t\t{\n\t\t\t\tTypeTreeNode decl = FindTypeNode(declaringType);\n\t\t\t\tif (decl != null)\n\t\t\t\t{\n\t\t\t\t\tdecl.EnsureLazyChildren();\n\t\t\t\t\treturn decl.Children.OfType<TypeTreeNode>().FirstOrDefault(t => t.TypeDefinition.MetadataToken == def.MetadataToken && !t.IsHidden);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tAssemblyTreeNode asm = FindAssemblyNode(def.ParentModule);\n\t\t\t\tif (asm != null)\n\t\t\t\t{\n\t\t\t\t\treturn asm.FindTypeNode(def);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Looks up the method node corresponding to the method definition.\n\t\t/// Returns null if no matching node is found.\n\t\t/// </summary>\n\t\tpublic ILSpyTreeNode FindMethodNode(IMethod def)\n\t\t{\n\t\t\tTypeTreeNode typeNode = FindTypeNode(def.DeclaringTypeDefinition);\n\t\t\tif (typeNode == null)\n\t\t\t\treturn null;\n\t\t\t// method might be an accessor, must look for parent node\n\t\t\tILSpyTreeNode parentNode = typeNode;\n\t\t\tMethodTreeNode methodNode;\n\t\t\tparentNode.EnsureLazyChildren();\n\t\t\tswitch (def.AccessorOwner)\n\t\t\t{\n\t\t\t\tcase IProperty p:\n\t\t\t\t\tparentNode = parentNode.Children.OfType<PropertyTreeNode>().FirstOrDefault(m => m.PropertyDefinition.MetadataToken == p.MetadataToken && !m.IsHidden);\n\t\t\t\t\tif (parentNode == null)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tparentNode.EnsureLazyChildren();\n\t\t\t\t\tmethodNode = parentNode.Children.OfType<MethodTreeNode>().FirstOrDefault(m => m.MethodDefinition.MetadataToken == def.MetadataToken && !m.IsHidden);\n\t\t\t\t\tif (methodNode == null || methodNode.IsHidden)\n\t\t\t\t\t\treturn parentNode;\n\t\t\t\t\treturn methodNode;\n\t\t\t\tcase IEvent e:\n\t\t\t\t\tparentNode = parentNode.Children.OfType<EventTreeNode>().FirstOrDefault(m => m.EventDefinition.MetadataToken == e.MetadataToken && !m.IsHidden);\n\t\t\t\t\tif (parentNode == null)\n\t\t\t\t\t\treturn null;\n\t\t\t\t\tparentNode.EnsureLazyChildren();\n\t\t\t\t\tmethodNode = parentNode.Children.OfType<MethodTreeNode>().FirstOrDefault(m => m.MethodDefinition.MetadataToken == def.MetadataToken && !m.IsHidden);\n\t\t\t\t\tif (methodNode == null || methodNode.IsHidden)\n\t\t\t\t\t\treturn parentNode;\n\t\t\t\t\treturn methodNode;\n\t\t\t\tdefault:\n\t\t\t\t\tmethodNode = typeNode.Children.OfType<MethodTreeNode>().FirstOrDefault(m => m.MethodDefinition.MetadataToken == def.MetadataToken && !m.IsHidden);\n\t\t\t\t\tif (methodNode != null)\n\t\t\t\t\t\treturn methodNode;\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Looks up the field node corresponding to the field definition.\n\t\t/// Returns null if no matching node is found.\n\t\t/// </summary>\n\t\tpublic FieldTreeNode FindFieldNode(IField def)\n\t\t{\n\t\t\tTypeTreeNode typeNode = FindTypeNode(def.DeclaringTypeDefinition);\n\t\t\tif (typeNode == null)\n\t\t\t\treturn null;\n\t\t\ttypeNode.EnsureLazyChildren();\n\t\t\treturn typeNode.Children.OfType<FieldTreeNode>().FirstOrDefault(m => m.FieldDefinition.MetadataToken == def.MetadataToken && !m.IsHidden);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Looks up the property node corresponding to the property definition.\n\t\t/// Returns null if no matching node is found.\n\t\t/// </summary>\n\t\tpublic PropertyTreeNode FindPropertyNode(IProperty def)\n\t\t{\n\t\t\tTypeTreeNode typeNode = FindTypeNode(def.DeclaringTypeDefinition);\n\t\t\tif (typeNode == null)\n\t\t\t\treturn null;\n\t\t\ttypeNode.EnsureLazyChildren();\n\t\t\treturn typeNode.Children.OfType<PropertyTreeNode>().FirstOrDefault(m => m.PropertyDefinition.MetadataToken == def.MetadataToken && !m.IsHidden);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Looks up the event node corresponding to the event definition.\n\t\t/// Returns null if no matching node is found.\n\t\t/// </summary>\n\t\tpublic EventTreeNode FindEventNode(IEvent def)\n\t\t{\n\t\t\tTypeTreeNode typeNode = FindTypeNode(def.DeclaringTypeDefinition);\n\t\t\tif (typeNode == null)\n\t\t\t\treturn null;\n\t\t\ttypeNode.EnsureLazyChildren();\n\t\t\treturn typeNode.Children.OfType<EventTreeNode>().FirstOrDefault(m => m.EventDefinition.MetadataToken == def.MetadataToken && !m.IsHidden);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Looks up the event node corresponding to the namespace definition.\n\t\t/// Returns null if no matching node is found.\n\t\t/// </summary>\n\t\tpublic NamespaceTreeNode FindNamespaceNode(INamespace def)\n\t\t{\n\t\t\tvar module = def.ContributingModules.FirstOrDefault();\n\t\t\tif (module == null)\n\t\t\t\treturn null;\n\n\t\t\tAssemblyTreeNode assemblyNode = FindAssemblyNode(module);\n\t\t\tif (assemblyNode == null)\n\t\t\t\treturn null;\n\n\t\t\tassemblyNode.EnsureLazyChildren();\n\t\t\treturn assemblyNode.Children.OfType<NamespaceTreeNode>().FirstOrDefault(n => def.FullName.Length == 0 || def.FullName.Equals(n.Text));\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/AssemblyReferenceReferencedTypesTreeNode.cs",
    "content": "// Copyright (c) 2023 James May\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// Referenced Types node in assembly reference list\n\t/// </summary>\n\tpublic sealed class AssemblyReferenceReferencedTypesTreeNode : ILSpyTreeNode\n\t{\n\t\treadonly MetadataModule module;\n\t\treadonly AssemblyReference r;\n\n\t\tpublic AssemblyReferenceReferencedTypesTreeNode(MetadataModule module, AssemblyReference r)\n\t\t{\n\t\t\tthis.module = module ?? throw new ArgumentNullException(nameof(module));\n\t\t\tthis.r = r ?? throw new ArgumentNullException(nameof(r));\n\n\t\t\tthis.LazyLoading = true;\n\t\t}\n\n\t\tpublic override object Text => $\"{Properties.Resources.ReferencedTypes} ({r.TypeReferences.Length + r.ExportedTypes.Length})\";\n\t\tpublic override object Icon => Images.MetadataTable;\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tforeach (var typeRef in r.TypeReferences)\n\t\t\t\tthis.Children.Add(new TypeReferenceTreeNode(module, typeRef));\n\n\t\t\tforeach (var exportedType in r.ExportedTypes)\n\t\t\t\tthis.Children.Add(new ExportedTypeTreeNode(module, exportedType));\n\t\t}\n\n\t\tpublic override bool ShowExpander => !r.TypeReferences.IsEmpty || !r.ExportedTypes.IsEmpty;\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tEnsureLazyChildren();\n\t\t\tforeach (ILSpyTreeNode child in Children)\n\t\t\t\tchild.Decompile(language, output, options);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Windows;\nusing System.Windows.Media;\nusing System.Windows.Threading;\n\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.Themes;\nusing ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// Node within assembly reference list.\n\t/// </summary>\n\tpublic sealed class AssemblyReferenceTreeNode : ILSpyTreeNode\n\t{\n\t\tprivate enum LoadState\n\t\t{\n\t\t\tUnloaded,\n\t\t\tLoading,\n\t\t\tLoadded,\n\t\t\tFailed\n\t\t}\n\n\t\treadonly MetadataModule module;\n\t\treadonly AssemblyReference r;\n\t\treadonly AssemblyTreeNode parentAssembly;\n\t\tMetadataFile referencedModule;\n\t\tLoadState state;\n\n\t\tpublic AssemblyReferenceTreeNode(MetadataModule module, AssemblyReference r, AssemblyTreeNode parentAssembly)\n\t\t{\n\t\t\tthis.module = module ?? throw new ArgumentNullException(nameof(module));\n\t\t\tthis.r = r ?? throw new ArgumentNullException(nameof(r));\n\t\t\tthis.parentAssembly = parentAssembly ?? throw new ArgumentNullException(nameof(parentAssembly));\n\t\t\tthis.LazyLoading = true;\n\t\t}\n\n\t\tpublic AssemblyReference AssemblyReference => r;\n\n\t\tpublic override object Text {\n\t\t\tget { return ILAmbience.EscapeName(r.Name) + GetSuffixString(r.Handle); }\n\t\t}\n\n\t\tpublic override object NavigationText => $\"{Text} ({Properties.Resources.References})\";\n\n\t\tpublic override object Icon {\n\t\t\tget {\n\t\t\t\tif (state == LoadState.Unloaded)\n\t\t\t\t{\n\t\t\t\t\tstate = LoadState.Loading;\n\t\t\t\t\tDispatcher.CurrentDispatcher.BeginInvoke(() => {\n\t\t\t\t\t\tvar resolver = parentAssembly.LoadedAssembly.GetAssemblyResolver(SettingsService.DecompilerSettings.AutoLoadAssemblyReferences);\n\t\t\t\t\t\treferencedModule = resolver.Resolve(r);\n\t\t\t\t\t\tstate = referencedModule is null\n\t\t\t\t\t\t\t? LoadState.Failed\n\t\t\t\t\t\t\t: LoadState.Loadded;\n\t\t\t\t\t\tRaisePropertyChanged(nameof(Icon));\n\t\t\t\t\t}, DispatcherPriority.Background);\n\t\t\t\t}\n\t\t\t\treturn state switch {\n\t\t\t\t\tLoadState.Loadded => Images.Assembly,\n\t\t\t\t\tLoadState.Failed => Images.AssemblyWarning,\n\t\t\t\t\t_ => Images.AssemblyLoading,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool ShowExpander {\n\t\t\tget {\n\t\t\t\t// Special case for mscorlib: It likely doesn't have any children so call EnsureLazyChildren to\n\t\t\t\t// remove the expander from the node.\n\t\t\t\tif (r.Name == \"mscorlib\")\n\t\t\t\t{\n\t\t\t\t\t// See https://github.com/icsharpcode/ILSpy/issues/2548: Adding assemblies to the tree view\n\t\t\t\t\t// while the list of references is updated causes problems with WPF's ListView rendering.\n\t\t\t\t\t// Moving the assembly resolving out of the \"add assembly reference\"-loop by using the\n\t\t\t\t\t// dispatcher fixes the issue.\n\t\t\t\t\tDispatcher.CurrentDispatcher.BeginInvoke(EnsureLazyChildren, DispatcherPriority.Normal);\n\t\t\t\t}\n\t\t\t\treturn base.ShowExpander;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void ActivateItem(IPlatformRoutedEventArgs e)\n\t\t{\n\t\t\tif (parentAssembly.Parent is AssemblyListTreeNode assemblyListNode)\n\t\t\t{\n\t\t\t\tvar resolver = parentAssembly.LoadedAssembly.GetAssemblyResolver();\n\t\t\t\tassemblyListNode.Select(assemblyListNode.FindAssemblyNode(resolver.Resolve(r)));\n\t\t\t\te.Handled = true;\n\t\t\t}\n\t\t}\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tthis.Children.Add(new AssemblyReferenceReferencedTypesTreeNode(module, r));\n\n\t\t\tif (referencedModule != null)\n\t\t\t{\n\t\t\t\tvar module = (MetadataModule)referencedModule.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion)?.MainModule;\n\t\t\t\tforeach (var childRef in referencedModule.AssemblyReferences)\n\t\t\t\t\tthis.Children.Add(new AssemblyReferenceTreeNode(module, childRef, parentAssembly));\n\t\t\t}\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tvar loaded = parentAssembly.LoadedAssembly.LoadedAssemblyReferencesInfo.TryGetInfo(r.FullName, out var info);\n\t\t\tif (r.IsWindowsRuntime)\n\t\t\t{\n\t\t\t\toutput.WriteLine(r.FullName + \" [WinRT]\" + (!loaded ? \" (unresolved)\" : \"\"));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\toutput.WriteLine(r.FullName + (!loaded ? \" (unresolved)\" : \"\"));\n\t\t\t}\n\t\t\tif (loaded)\n\t\t\t{\n\t\t\t\toutput.Indent();\n\t\t\t\toutput.WriteLine(\"Assembly reference loading information:\");\n\t\t\t\tif (info.HasErrors)\n\t\t\t\t{\n\t\t\t\t\toutput.WriteLine(\"There were some problems during assembly reference load, see below for more information!\");\n\t\t\t\t\tstate = LoadState.Failed;\n\t\t\t\t}\n\t\t\t\tPrintAssemblyLoadLogMessages(output, info);\n\t\t\t\toutput.Unindent();\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t}\n\n\t\tinternal static void PrintAssemblyLoadLogMessages(ITextOutput output, UnresolvedAssemblyNameReference asm)\n\t\t{\n\t\t\tHighlightingColor red = GetColor(Colors.Red);\n\t\t\tHighlightingColor yellow = GetColor(Colors.Yellow);\n\n\t\t\tvar smartOutput = output as ISmartTextOutput;\n\n\t\t\tforeach (var item in asm.Messages)\n\t\t\t{\n\t\t\t\tswitch (item.Item1)\n\t\t\t\t{\n\t\t\t\t\tcase MessageKind.Error:\n\t\t\t\t\t\tsmartOutput?.BeginSpan(red);\n\t\t\t\t\t\toutput.Write(\"Error: \");\n\t\t\t\t\t\tsmartOutput?.EndSpan();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase MessageKind.Warning:\n\t\t\t\t\t\tsmartOutput?.BeginSpan(yellow);\n\t\t\t\t\t\toutput.Write(\"Warning: \");\n\t\t\t\t\t\tsmartOutput?.EndSpan();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\toutput.Write(item.Item1 + \": \");\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\toutput.WriteLine(item.Item2);\n\t\t\t}\n\n\t\t\tstatic HighlightingColor GetColor(Color color)\n\t\t\t{\n\t\t\t\tvar hc = new HighlightingColor {\n\t\t\t\t\tForeground = new SimpleHighlightingBrush(color),\n\t\t\t\t\tFontWeight = FontWeights.Bold\n\t\t\t\t};\n\t\t\t\tif (ThemeManager.Current.IsDarkTheme)\n\t\t\t\t{\n\t\t\t\t\treturn ThemeManager.GetColorForDarkTheme(hc);\n\t\t\t\t}\n\t\t\t\treturn hc;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/AssemblyTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Documents;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.CSharp.ProjectDecompiler;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Controls.TreeView;\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpy.Metadata;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.FileLoaders;\nusing ICSharpCode.ILSpyX.PdbProvider;\nusing ICSharpCode.ILSpyX.TreeView;\nusing ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;\n\nusing Microsoft.Win32;\n\nusing TypeDefinitionHandle = System.Reflection.Metadata.TypeDefinitionHandle;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// Tree node representing an assembly.\n\t/// This class is responsible for loading both namespace and type nodes.\n\t/// </summary>\n\tpublic sealed class AssemblyTreeNode : ILSpyTreeNode\n\t{\n\t\treadonly Dictionary<string, NamespaceTreeNode> namespaces = new Dictionary<string, NamespaceTreeNode>();\n\t\treadonly Dictionary<TypeDefinitionHandle, TypeTreeNode> typeDict = new Dictionary<TypeDefinitionHandle, TypeTreeNode>();\n\t\tICompilation typeSystem;\n\n\t\tpublic AssemblyTreeNode(LoadedAssembly assembly) : this(assembly, null)\n\t\t{\n\t\t}\n\n\t\tinternal AssemblyTreeNode(LoadedAssembly assembly, PackageEntry packageEntry)\n\t\t{\n\t\t\tthis.LoadedAssembly = assembly ?? throw new ArgumentNullException(nameof(assembly));\n\t\t\tthis.LazyLoading = true;\n\t\t\tthis.PackageEntry = packageEntry;\n\t\t\tInit();\n\t\t}\n\n\t\tpublic AssemblyList AssemblyList {\n\t\t\tget { return LoadedAssembly.AssemblyList; }\n\t\t}\n\n\t\tpublic LoadedAssembly LoadedAssembly { get; }\n\n\t\t/// <summary>\n\t\t/// If this assembly was loaded from a bundle; this property returns the bundle entry that the\n\t\t/// assembly was loaded from.\n\t\t/// </summary>\n\t\tpublic PackageEntry PackageEntry { get; }\n\n\t\t/// <summary>\n\t\t/// If this assembly is a bundle or package, returns the <see cref=\"LoadedAssembly.PackageKind\"/>,\n\t\t/// otherwise returns <see langword=\"null\"/>.\n\t\t/// Returns <see langword=\"null\"/> if this assembly was not yet loaded or an error occurred.\n\t\t/// </summary>\n\t\tpublic LoadedPackage.PackageKind? PackageKind {\n\t\t\tget {\n\t\t\t\tif (LoadedAssembly.HasLoadError || !LoadedAssembly.IsLoaded)\n\t\t\t\t\treturn null;\n\t\t\t\tvar loadResult = LoadedAssembly.GetLoadResultAsync().GetAwaiter().GetResult();\n\t\t\t\treturn loadResult.Package?.Kind;\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool IsAutoLoaded {\n\t\t\tget {\n\t\t\t\treturn LoadedAssembly.IsAutoLoaded;\n\t\t\t}\n\t\t}\n\n\t\tpublic override object Text => LoadedAssembly.Text;\n\n\t\tpublic override object Icon {\n\t\t\tget {\n\t\t\t\tif (LoadedAssembly.IsLoaded)\n\t\t\t\t{\n\t\t\t\t\tif (LoadedAssembly.HasLoadError)\n\t\t\t\t\t\treturn Images.AssemblyWarning;\n\t\t\t\t\tvar loadResult = LoadedAssembly.GetLoadResultAsync().GetAwaiter().GetResult();\n\t\t\t\t\tif (loadResult.Package != null)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn loadResult.Package.Kind switch {\n\t\t\t\t\t\t\tLoadedPackage.PackageKind.Zip => Images.NuGet,\n\t\t\t\t\t\t\t_ => Images.Library,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tif (loadResult.MetadataFile != null)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn loadResult.MetadataFile.Kind switch {\n\t\t\t\t\t\t\tMetadataFile.MetadataFileKind.PortableExecutable => Images.Assembly,\n\t\t\t\t\t\t\tMetadataFile.MetadataFileKind.ProgramDebugDatabase => Images.ProgramDebugDatabase,\n\t\t\t\t\t\t\tMetadataFile.MetadataFileKind.WebCIL => Images.WebAssemblyFile,\n\t\t\t\t\t\t\t_ => Images.MetadataFile,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn Images.Assembly;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn Images.FindAssembly;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tTextBlock tooltip;\n\n\t\tpublic override object ToolTip {\n\t\t\tget {\n\t\t\t\tif (LoadedAssembly.HasLoadError)\n\t\t\t\t\treturn \"Assembly could not be loaded. Click here for details.\";\n\n\t\t\t\tif (tooltip == null && LoadedAssembly.IsLoaded)\n\t\t\t\t{\n\t\t\t\t\ttooltip = new TextBlock();\n\t\t\t\t\tvar module = LoadedAssembly.GetMetadataFileOrNull();\n\t\t\t\t\tvar metadata = module?.Metadata;\n\t\t\t\t\tif (metadata?.IsAssembly == true && metadata.TryGetFullAssemblyName(out var assemblyName))\n\t\t\t\t\t{\n\t\t\t\t\t\ttooltip.Inlines.Add(new Bold(new Run(\"Name: \")));\n\t\t\t\t\t\ttooltip.Inlines.Add(new Run(assemblyName));\n\t\t\t\t\t\ttooltip.Inlines.Add(new LineBreak());\n\t\t\t\t\t}\n\t\t\t\t\ttooltip.Inlines.Add(new Bold(new Run(\"Location: \")));\n\t\t\t\t\ttooltip.Inlines.Add(new Run(LoadedAssembly.FileName));\n\t\t\t\t\tif (module != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (module is PEFile peFile)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttooltip.Inlines.Add(new LineBreak());\n\t\t\t\t\t\t\ttooltip.Inlines.Add(new Bold(new Run(\"Architecture: \")));\n\t\t\t\t\t\t\ttooltip.Inlines.Add(new Run(Language.GetPlatformDisplayName(peFile)));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstring runtimeName = Language.GetRuntimeDisplayName(module);\n\t\t\t\t\t\tif (runtimeName != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttooltip.Inlines.Add(new LineBreak());\n\t\t\t\t\t\t\ttooltip.Inlines.Add(new Bold(new Run(\"Runtime: \")));\n\t\t\t\t\t\t\ttooltip.Inlines.Add(new Run(runtimeName));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvar debugInfo = LoadedAssembly.GetDebugInfoOrNull();\n\t\t\t\t\t\ttooltip.Inlines.Add(new LineBreak());\n\t\t\t\t\t\ttooltip.Inlines.Add(new Bold(new Run(\"Debug info: \")));\n\t\t\t\t\t\ttooltip.Inlines.Add(new Run(debugInfo?.Description ?? \"none\"));\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tooltip;\n\t\t\t}\n\t\t}\n\n\t\tpublic void UpdateToolTip()\n\t\t{\n\t\t\ttooltip = null;\n\t\t\tRaisePropertyChanged(nameof(ToolTip));\n\t\t}\n\n\t\tpublic override bool ShowExpander {\n\t\t\tget { return !LoadedAssembly.HasLoadError; }\n\t\t}\n\n\t\tasync void Init()\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tawait this.LoadedAssembly.GetLoadResultAsync();\n\t\t\t\tRaisePropertyChanged(nameof(Text)); // shortname might have changed\n\t\t\t}\n\t\t\tcatch\n\t\t\t{\n\t\t\t\tRaisePropertyChanged(nameof(ShowExpander)); // cannot expand assemblies with load error\n\t\t\t}\n\t\t\t// change from \"Loading\" icon to final icon\n\t\t\tRaisePropertyChanged(nameof(Icon));\n\t\t\tRaisePropertyChanged(nameof(ExpandedIcon));\n\t\t\tRaisePropertyChanged(nameof(ToolTip));\n\t\t}\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tLoadResult loadResult;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tloadResult = LoadedAssembly.GetLoadResultAsync().GetAwaiter().GetResult();\n\t\t\t}\n\t\t\tcatch\n\t\t\t{\n\t\t\t\t// if we crashed on loading, then we don't have any children\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry\n\t\t\t{\n\t\t\t\tif (loadResult.MetadataFile != null)\n\t\t\t\t{\n\t\t\t\t\tswitch (loadResult.MetadataFile.Kind)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase MetadataFile.MetadataFileKind.PortableExecutable:\n\t\t\t\t\t\tcase MetadataFile.MetadataFileKind.WebCIL:\n\t\t\t\t\t\t\tLoadChildrenForExecutableFile(loadResult.MetadataFile);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tvar metadata = loadResult.MetadataFile;\n\t\t\t\t\t\t\tthis.Children.Add(new MetadataTablesTreeNode(metadata));\n\t\t\t\t\t\t\tthis.Children.Add(new StringHeapTreeNode(metadata));\n\t\t\t\t\t\t\tthis.Children.Add(new UserStringHeapTreeNode(metadata));\n\t\t\t\t\t\t\tthis.Children.Add(new GuidHeapTreeNode(metadata));\n\t\t\t\t\t\t\tthis.Children.Add(new BlobHeapTreeNode(metadata));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (loadResult.Package != null)\n\t\t\t\t{\n\t\t\t\t\tvar package = loadResult.Package;\n\t\t\t\t\tthis.Children.AddRange(PackageFolderTreeNode.LoadChildrenForFolder(package.RootFolder));\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (Exception ex)\n\t\t\t{\n\t\t\t\tApp.UnhandledException(ex);\n\t\t\t}\n\t\t}\n\n\t\tvoid LoadChildrenForExecutableFile(MetadataFile module)\n\t\t{\n\t\t\ttypeSystem = LoadedAssembly.GetTypeSystemOrNull();\n\t\t\tvar assembly = (MetadataModule)typeSystem.MainModule;\n\t\t\tthis.Children.Add(new MetadataTreeNode(module, Resources.Metadata));\n\t\t\tDecompiler.DebugInfo.IDebugInfoProvider debugInfo = LoadedAssembly.GetDebugInfoOrNull();\n\t\t\tif (debugInfo is PortableDebugInfoProvider ppdb\n\t\t\t\t&& ppdb.GetMetadataReader() is System.Reflection.Metadata.MetadataReader reader)\n\t\t\t{\n\t\t\t\tthis.Children.Add(new MetadataTreeNode(ppdb.ToMetadataFile(), $\"Debug Metadata ({(ppdb.IsEmbedded ? \"Embedded\" : \"From portable PDB\")})\"));\n\t\t\t}\n\t\t\tthis.Children.Add(new ReferenceFolderTreeNode(module, this));\n\t\t\tif (module.Resources.Any())\n\t\t\t\tthis.Children.Add(new ResourceListTreeNode(module));\n\t\t\tforeach (NamespaceTreeNode ns in namespaces.Values)\n\t\t\t{\n\t\t\t\tns.Children.Clear();\n\t\t\t}\n\t\t\tnamespaces.Clear();\n\t\t\tbool useNestedStructure = SettingsService.DisplaySettings.UseNestedNamespaceNodes;\n\t\t\tforeach (var type in assembly.TopLevelTypeDefinitions.OrderBy(t => t.ReflectionName, NaturalStringComparer.Instance))\n\t\t\t{\n\t\t\t\tvar ns = GetOrCreateNamespaceTreeNode(type.Namespace);\n\t\t\t\tTypeTreeNode node = new TypeTreeNode(type, this);\n\t\t\t\ttypeDict[(TypeDefinitionHandle)type.MetadataToken] = node;\n\t\t\t\tns.Children.Add(node);\n\t\t\t}\n\t\t\tforeach (NamespaceTreeNode ns in namespaces.Values\n\t\t\t\t.Where(ns => ns.Children.Count > 0 && ns.Parent == null)\n\t\t\t\t.OrderBy(n => n.Name, NaturalStringComparer.Instance))\n\t\t\t{\n\t\t\t\tthis.Children.Add(ns);\n\t\t\t\tSetPublicAPI(ns);\n\t\t\t}\n\n\t\t\tNamespaceTreeNode GetOrCreateNamespaceTreeNode(string @namespace)\n\t\t\t{\n\t\t\t\tif (!namespaces.TryGetValue(@namespace, out NamespaceTreeNode ns))\n\t\t\t\t{\n\t\t\t\t\tif (useNestedStructure)\n\t\t\t\t\t{\n\t\t\t\t\t\tint decimalIndex = @namespace.LastIndexOf('.');\n\t\t\t\t\t\tif (decimalIndex < 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar escapedNamespace = ILAmbience.EscapeName(@namespace);\n\t\t\t\t\t\t\tns = new NamespaceTreeNode(escapedNamespace);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar parentNamespaceTreeNode = GetOrCreateNamespaceTreeNode(@namespace.Substring(0, decimalIndex));\n\t\t\t\t\t\t\tvar escapedInnerNamespace = ILAmbience.EscapeName(@namespace.Substring(decimalIndex + 1));\n\t\t\t\t\t\t\tns = new NamespaceTreeNode(escapedInnerNamespace);\n\t\t\t\t\t\t\tparentNamespaceTreeNode.Children.Add(ns);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tvar escapedNamespace = ILAmbience.EscapeName(@namespace);\n\t\t\t\t\t\tns = new NamespaceTreeNode(escapedNamespace);\n\t\t\t\t\t}\n\t\t\t\t\tnamespaces.Add(@namespace, ns);\n\t\t\t\t}\n\t\t\t\treturn ns;\n\t\t\t}\n\t\t}\n\n\t\tprivate static void SetPublicAPI(NamespaceTreeNode ns)\n\t\t{\n\t\t\tforeach (NamespaceTreeNode innerNamespace in ns.Children.OfType<NamespaceTreeNode>())\n\t\t\t{\n\t\t\t\tSetPublicAPI(innerNamespace);\n\t\t\t}\n\t\t\tns.SetPublicAPI(ns.Children.OfType<ILSpyTreeNode>().Any(n => n.IsPublicAPI));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Finds the node for a top-level type.\n\t\t/// </summary>\n\t\tpublic TypeTreeNode FindTypeNode(ITypeDefinition type)\n\t\t{\n\t\t\tif (type == null)\n\t\t\t\treturn null;\n\t\t\tEnsureLazyChildren();\n\t\t\tTypeTreeNode node;\n\t\t\tif (typeDict.TryGetValue((TypeDefinitionHandle)type.MetadataToken, out node))\n\t\t\t\treturn node;\n\t\t\telse\n\t\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Finds the node for a namespace.\n\t\t/// </summary>\n\t\tpublic NamespaceTreeNode FindNamespaceNode(string namespaceName)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(namespaceName))\n\t\t\t\treturn null;\n\t\t\tEnsureLazyChildren();\n\t\t\tNamespaceTreeNode node;\n\t\t\tif (namespaces.TryGetValue(namespaceName, out node))\n\t\t\t\treturn node;\n\t\t\telse\n\t\t\t\treturn null;\n\t\t}\n\n\t\tpublic override bool CanDrag(SharpTreeNode[] nodes)\n\t\t{\n\t\t\t// prohibit dragging assemblies nested in nuget packages\n\t\t\treturn nodes.All(n => n is AssemblyTreeNode { PackageEntry: null });\n\t\t}\n\n\t\tpublic override void StartDrag(object dragSource, SharpTreeNode[] nodes, IPlatformDragDrop dragdropManager)\n\t\t{\n\t\t\tdragdropManager.DoDragDrop(dragSource, Copy(nodes), XPlatDragDropEffects.All);\n\t\t}\n\n\t\tpublic override bool CanDelete()\n\t\t{\n\t\t\t// prohibit deleting assemblies nested in nuget packages\n\t\t\treturn PackageEntry == null;\n\t\t}\n\n\t\tpublic override void Delete()\n\t\t{\n\t\t\tDeleteCore();\n\t\t}\n\n\t\tpublic override void DeleteCore()\n\t\t{\n\t\t\tLoadedAssembly.AssemblyList.Unload(LoadedAssembly);\n\t\t}\n\n\t\tinternal const string DataFormat = \"ILSpyAssemblies\";\n\n\t\tpublic override IPlatformDataObject Copy(SharpTreeNode[] nodes)\n\t\t{\n\t\t\tvar dataObject = new WpfWindowsDataObject(new DataObject());\n\t\t\tdataObject.SetData(DataFormat, nodes.OfType<AssemblyTreeNode>().Select(n => n.LoadedAssembly.FileName).ToArray());\n\t\t\treturn dataObject;\n\t\t}\n\n\t\tpublic override FilterResult Filter(LanguageSettings settings)\n\t\t{\n\t\t\tif (settings.SearchTermMatches(LoadedAssembly.ShortName))\n\t\t\t\treturn FilterResult.Match;\n\t\t\telse\n\t\t\t\treturn FilterResult.Recurse;\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tvoid HandleException(Exception ex, string message)\n\t\t\t{\n\t\t\t\tlanguage.WriteCommentLine(output, message);\n\n\t\t\t\toutput.WriteLine();\n\t\t\t\toutput.MarkFoldStart(\"Exception details\", true);\n\t\t\t\toutput.Write(ex.ToString());\n\t\t\t\toutput.MarkFoldEnd();\n\t\t\t}\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar loadResult = LoadedAssembly.GetLoadResultAsync().GetAwaiter().GetResult();\n\t\t\t\tif (loadResult.MetadataFile != null)\n\t\t\t\t{\n\t\t\t\t\tswitch (loadResult.MetadataFile.Kind)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase MetadataFile.MetadataFileKind.ProgramDebugDatabase:\n\t\t\t\t\t\tcase MetadataFile.MetadataFileKind.Metadata:\n\t\t\t\t\t\t\toutput.WriteLine(\"// \" + LoadedAssembly.FileName);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tlanguage.DecompileAssembly(LoadedAssembly, output, options);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (loadResult.Package != null)\n\t\t\t\t{\n\t\t\t\t\toutput.WriteLine(\"// \" + LoadedAssembly.FileName);\n\t\t\t\t\tDecompilePackage(loadResult.Package, output);\n\t\t\t\t}\n\t\t\t\telse if (loadResult.FileLoadException != null)\n\t\t\t\t{\n\t\t\t\t\tHandleException(loadResult.FileLoadException, loadResult.FileLoadException.Message);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (BadImageFormatException badImage)\n\t\t\t{\n\t\t\t\tHandleException(badImage, \"This file does not contain a managed assembly.\");\n\t\t\t}\n\t\t\tcatch (FileNotFoundException fileNotFound) when (options.SaveAsProjectDirectory == null)\n\t\t\t{\n\t\t\t\tHandleException(fileNotFound, \"The file was not found.\");\n\t\t\t}\n\t\t\tcatch (DirectoryNotFoundException dirNotFound) when (options.SaveAsProjectDirectory == null)\n\t\t\t{\n\t\t\t\tHandleException(dirNotFound, \"The directory was not found.\");\n\t\t\t}\n\t\t\tcatch (MetadataFileNotSupportedException notSupported)\n\t\t\t{\n\t\t\t\tHandleException(notSupported, notSupported.Message);\n\t\t\t}\n\t\t}\n\n\t\tprivate void DecompilePackage(LoadedPackage package, ITextOutput output)\n\t\t{\n\t\t\tswitch (package.Kind)\n\t\t\t{\n\t\t\t\tcase LoadedPackage.PackageKind.Zip:\n\t\t\t\t\toutput.WriteLine(\"// File format: .zip file\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase LoadedPackage.PackageKind.Bundle:\n\t\t\t\t\tvar header = package.BundleHeader;\n\t\t\t\t\toutput.WriteLine($\"// File format: .NET bundle {header.MajorVersion}.{header.MinorVersion}\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\toutput.WriteLine();\n\t\t\toutput.WriteLine(\"Entries:\");\n\t\t\tforeach (var entry in package.Entries)\n\t\t\t{\n\t\t\t\toutput.WriteLine($\" {entry.Name} ({entry.TryGetLength()} bytes)\");\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool Save(TabPageModel tabPage)\n\t\t{\n\t\t\tif (!LoadedAssembly.IsLoadedAsValidAssembly)\n\t\t\t\treturn false;\n\t\t\tLanguage language = this.Language;\n\t\t\tif (string.IsNullOrEmpty(language.ProjectFileExtension))\n\t\t\t\treturn false;\n\t\t\tSaveFileDialog dlg = new SaveFileDialog();\n\t\t\tdlg.FileName = WholeProjectDecompiler.CleanUpFileName(LoadedAssembly.ShortName, language.ProjectFileExtension);\n\t\t\tdlg.Filter = language.Name + \" project|*\" + language.ProjectFileExtension + \"|\" + language.Name + \" single file|*\" + language.FileExtension + \"|All files|*.*\";\n\t\t\tif (dlg.ShowDialog() == true)\n\t\t\t{\n\t\t\t\tvar options = DockWorkspace.ActiveTabPage.CreateDecompilationOptions();\n\t\t\t\toptions.FullDecompilation = true;\n\t\t\t\tif (dlg.FilterIndex == 1)\n\t\t\t\t{\n\t\t\t\t\toptions.SaveAsProjectDirectory = Path.GetDirectoryName(dlg.FileName);\n\t\t\t\t\tforeach (string entry in Directory.GetFileSystemEntries(options.SaveAsProjectDirectory))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!string.Equals(entry, dlg.FileName, StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvar result = MessageBox.Show(\n\t\t\t\t\t\t\t\tResources.AssemblySaveCodeDirectoryNotEmpty,\n\t\t\t\t\t\t\t\tResources.AssemblySaveCodeDirectoryNotEmptyTitle,\n\t\t\t\t\t\t\t\tMessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No);\n\t\t\t\t\t\t\tif (result == MessageBoxResult.No)\n\t\t\t\t\t\t\t\treturn true; // don't save, but mark the Save operation as handled\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ttabPage.ShowTextView(textView => textView.SaveToDisk(language, new[] { this }, options, dlg.FileName));\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\t// ToString is used by FindNodeByPath/GetPathForNode\n\t\t\t// Fixes #821 - Reload All Assemblies Should Point to the Correct Assembly\n\t\t\treturn LoadedAssembly.FileName;\n\t\t}\n\t}\n\n\t[ExportContextMenuEntry(Header = nameof(Resources._Remove), Icon = \"images/Delete\")]\n\t[Shared]\n\tsealed class RemoveAssembly : IContextMenuEntry\n\t{\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn false;\n\t\t\treturn context.SelectedTreeNodes.All(n => n is AssemblyTreeNode);\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn;\n\t\t\tforeach (var node in context.SelectedTreeNodes)\n\t\t\t{\n\t\t\t\tnode.Delete();\n\t\t\t}\n\t\t}\n\t}\n\n\t[ExportContextMenuEntry(Header = nameof(Resources._Reload), Icon = \"images/Refresh\")]\n\t[Shared]\n\tsealed class ReloadAssembly(AssemblyTreeModel assemblyTreeModel) : IContextMenuEntry\n\t{\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn false;\n\t\t\treturn context.SelectedTreeNodes.All(n => n is AssemblyTreeNode);\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn;\n\t\t\tvar paths = new List<string[]>();\n\t\t\tusing (context.TreeView.LockUpdates())\n\t\t\t{\n\t\t\t\tforeach (var node in context.SelectedTreeNodes)\n\t\t\t\t{\n\t\t\t\t\tpaths.Add(AssemblyTreeModel.GetPathForNode(node));\n\t\t\t\t\tvar la = ((AssemblyTreeNode)node).LoadedAssembly;\n\t\t\t\t\tla.AssemblyList.ReloadAssembly(la.FileName);\n\t\t\t\t}\n\t\t\t}\n\t\t\tassemblyTreeModel.SelectNodes(paths.Select(p => assemblyTreeModel.FindNodeByPath(p, true)).ToArray());\n\t\t\tassemblyTreeModel.RefreshDecompiledView();\n\t\t}\n\t}\n\n\t[ExportContextMenuEntry(Header = nameof(Resources._LoadDependencies), Category = nameof(Resources.Dependencies))]\n\t[Shared]\n\tsealed class LoadDependencies(AssemblyTreeModel assemblyTreeModel) : IContextMenuEntry\n\t{\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn false;\n\t\t\treturn context.SelectedTreeNodes.All(n => n is AssemblyTreeNode asm && asm.LoadedAssembly.IsLoadedAsValidAssembly);\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic async void Execute(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn;\n\t\t\tvar tasks = new List<Task>();\n\t\t\tforeach (var node in context.SelectedTreeNodes)\n\t\t\t{\n\t\t\t\tvar la = ((AssemblyTreeNode)node).LoadedAssembly;\n\t\t\t\tvar resolver = la.GetAssemblyResolver();\n\t\t\t\tvar module = la.GetMetadataFileOrNull();\n\t\t\t\tif (module != null)\n\t\t\t\t{\n\t\t\t\t\tvar metadata = module.Metadata;\n\t\t\t\t\tforeach (var assyRef in metadata.AssemblyReferences)\n\t\t\t\t\t{\n\t\t\t\t\t\ttasks.Add(resolver.ResolveAsync(new AssemblyReference(module, assyRef)));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait Task.WhenAll(tasks);\n\t\t\tassemblyTreeModel.RefreshDecompiledView();\n\t\t}\n\t}\n\n\t[ExportContextMenuEntry(Header = nameof(Resources._AddMainList), Category = nameof(Resources.Dependencies))]\n\t[Shared]\n\tsealed class AddToMainList(AssemblyTreeModel assemblyTreeModel) : IContextMenuEntry\n\t{\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn false;\n\t\t\treturn context.SelectedTreeNodes.Where(n => n is AssemblyTreeNode).Any(n => ((AssemblyTreeNode)n).IsAutoLoaded);\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn false;\n\t\t\treturn context.SelectedTreeNodes.Any(n => n is AssemblyTreeNode);\n\t\t}\n\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn;\n\t\t\tforeach (var node in context.SelectedTreeNodes)\n\t\t\t{\n\t\t\t\tvar loadedAssm = ((AssemblyTreeNode)node).LoadedAssembly;\n\t\t\t\tif (!loadedAssm.HasLoadError)\n\t\t\t\t{\n\t\t\t\t\tloadedAssm.IsAutoLoaded = false;\n\t\t\t\t\tnode.RaisePropertyChanged(nameof(ILSpyTreeNode.IsAutoLoaded));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tassemblyTreeModel.AssemblyList.RefreshSave();\n\t\t}\n\t}\n\n\t[ExportContextMenuEntry(Header = nameof(Resources._OpenContainingFolder), Category = nameof(Resources.Shell))]\n\t[Shared]\n\tsealed class OpenContainingFolder : IContextMenuEntry\n\t{\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn false;\n\t\t\treturn context.SelectedTreeNodes\n\t\t\t\t.All(n => {\n\t\t\t\t\tvar a = GetAssemblyTreeNode(n);\n\t\t\t\t\treturn a != null && File.Exists(a.LoadedAssembly.FileName);\n\t\t\t\t});\n\t\t}\n\n\t\tinternal static AssemblyTreeNode GetAssemblyTreeNode(SharpTreeNode node)\n\t\t{\n\t\t\twhile (node != null)\n\t\t\t{\n\t\t\t\tif (node is AssemblyTreeNode a)\n\t\t\t\t\treturn a;\n\t\t\t\tnode = node.Parent;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn false;\n\t\t\treturn context.SelectedTreeNodes\n\t\t\t\t.All(n => {\n\t\t\t\t\tvar a = GetAssemblyTreeNode(n);\n\t\t\t\t\treturn a != null && File.Exists(a.LoadedAssembly.FileName);\n\t\t\t\t});\n\t\t}\n\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn;\n\t\t\tvar paths = new List<string>();\n\t\t\tforeach (var n in context.SelectedTreeNodes)\n\t\t\t{\n\t\t\t\tvar node = GetAssemblyTreeNode(n);\n\t\t\t\tvar path = node.LoadedAssembly.FileName;\n\t\t\t\tif (File.Exists(path))\n\t\t\t\t{\n\t\t\t\t\tpaths.Add(path);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (paths.Count > 0)\n\t\t\t\tShellHelper.OpenFolderAndSelectItems(paths);\n\t\t}\n\t}\n\n\t[ExportContextMenuEntry(Header = nameof(Resources._OpenCommandLineHere), Category = nameof(Resources.Shell))]\n\t[Shared]\n\tsealed class OpenCmdHere : IContextMenuEntry\n\t{\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn false;\n\t\t\treturn context.SelectedTreeNodes\n\t\t\t\t.All(n => {\n\t\t\t\t\tvar a = OpenContainingFolder.GetAssemblyTreeNode(n);\n\t\t\t\t\treturn a != null && File.Exists(a.LoadedAssembly.FileName);\n\t\t\t\t});\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn false;\n\t\t\treturn context.SelectedTreeNodes\n\t\t\t\t.All(n => {\n\t\t\t\t\tvar a = OpenContainingFolder.GetAssemblyTreeNode(n);\n\t\t\t\t\treturn a != null && File.Exists(a.LoadedAssembly.FileName);\n\t\t\t\t});\n\t\t}\n\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn;\n\t\t\tforeach (var n in context.SelectedTreeNodes)\n\t\t\t{\n\t\t\t\tvar node = OpenContainingFolder.GetAssemblyTreeNode(n);\n\t\t\t\tvar path = Path.GetDirectoryName(node.LoadedAssembly.FileName);\n\t\t\t\tif (Directory.Exists(path))\n\t\t\t\t{\n\t\t\t\t\tGlobalUtils.ExecuteCommand(\"cmd.exe\", $\"/k \\\"cd /d {path}\\\"\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/BaseTypesEntryNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Linq;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX.TreeView;\nusing ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\tsealed class BaseTypesEntryNode : ILSpyTreeNode, IMemberTreeNode\n\t{\n\t\treadonly ITypeDefinition type;\n\n\t\tpublic BaseTypesEntryNode(ITypeDefinition type)\n\t\t{\n\t\t\tthis.type = type;\n\t\t}\n\n\t\tpublic override object Text => this.Language.TypeToString(type);\n\n\t\tpublic override object NavigationText => $\"{Text} ({Properties.Resources.BaseTypes})\";\n\n\t\tpublic override object Icon => type.Kind == TypeKind.Interface ? Images.Interface : Images.Class;\n\n\t\tpublic override void ActivateItem(IPlatformRoutedEventArgs e)\n\t\t{\n\t\t\te.Handled = ActivateItem(this, type);\n\t\t}\n\n\t\tinternal static bool ActivateItem(SharpTreeNode node, ITypeDefinition def)\n\t\t{\n\t\t\tif (def != null)\n\t\t\t{\n\t\t\t\tvar assemblyListNode = node.Ancestors().OfType<AssemblyListTreeNode>().FirstOrDefault();\n\t\t\t\tif (assemblyListNode != null)\n\t\t\t\t{\n\t\t\t\t\tassemblyListNode.Select(assemblyListNode.FindTypeNode(def));\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.WriteCommentLine(output, language.TypeToString(type));\n\t\t}\n\n\t\tIEntity IMemberTreeNode.Member => type;\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/BaseTypesTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Windows.Threading;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.TreeView;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// Lists the base types of a class.\n\t/// </summary>\n\tsealed class BaseTypesTreeNode : ILSpyTreeNode\n\t{\n\t\treadonly MetadataFile module;\n\t\treadonly ITypeDefinition type;\n\n\t\tpublic BaseTypesTreeNode(MetadataFile module, ITypeDefinition type)\n\t\t{\n\t\t\tthis.module = module;\n\t\t\tthis.type = type;\n\t\t\tthis.LazyLoading = true;\n\t\t}\n\n\t\tpublic override object Text => Properties.Resources.BaseTypes;\n\n\t\tpublic override object NavigationText => $\"{Text} ({this.Language.TypeToString(type)})\";\n\n\t\tpublic override object Icon => Images.SuperTypes;\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tAddBaseTypes(this.Children, module, type);\n\t\t}\n\n\t\tinternal static void AddBaseTypes(SharpTreeNodeCollection children, MetadataFile module, ITypeDefinition typeDefinition)\n\t\t{\n\t\t\tTypeDefinitionHandle handle = (TypeDefinitionHandle)typeDefinition.MetadataToken;\n\t\t\tDecompilerTypeSystem typeSystem = new DecompilerTypeSystem(module, module.GetAssemblyResolver(),\n\t\t\t\tTypeSystemOptions.Default | TypeSystemOptions.Uncached);\n\t\t\tvar t = typeSystem.MainModule.ResolveEntity(handle) as ITypeDefinition;\n\t\t\tforeach (var td in t.GetAllBaseTypeDefinitions().Reverse().Skip(1))\n\t\t\t{\n\t\t\t\tif (t.Kind != TypeKind.Interface || t.Kind == td.Kind)\n\t\t\t\t\tchildren.Add(new BaseTypesEntryNode(td));\n\t\t\t}\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tApp.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(EnsureLazyChildren));\n\t\t\tforeach (ILSpyTreeNode child in this.Children)\n\t\t\t{\n\t\t\t\tchild.Decompile(language, output, options);\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/TreeNodes/DerivedTypesEntryNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.ILSpyX;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\tusing ICSharpCode.Decompiler.TypeSystem;\n\tusing ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;\n\n\tclass DerivedTypesEntryNode : ILSpyTreeNode, IMemberTreeNode\n\t{\n\t\treadonly AssemblyList list;\n\t\treadonly ITypeDefinition type;\n\t\treadonly ThreadingSupport threading;\n\n\t\tpublic DerivedTypesEntryNode(AssemblyList list, ITypeDefinition type)\n\t\t{\n\t\t\tthis.list = list;\n\t\t\tthis.type = type;\n\t\t\tthis.LazyLoading = true;\n\t\t\tthreading = new ThreadingSupport();\n\t\t}\n\n\t\tpublic override bool ShowExpander => !type.IsSealed && base.ShowExpander;\n\n\t\tpublic override object Text {\n\t\t\tget { return Language.TypeToString(type) + GetSuffixString(type.MetadataToken); }\n\t\t}\n\n\t\tpublic override object NavigationText => $\"{Text} ({Properties.Resources.DerivedTypes})\";\n\n\t\tpublic override object Icon => TypeTreeNode.GetIcon(type);\n\n\t\tpublic override FilterResult Filter(LanguageSettings settings)\n\t\t{\n\t\t\tif (settings.ShowApiLevel == ApiVisibility.PublicOnly && !IsPublicAPI)\n\t\t\t\treturn FilterResult.Hidden;\n\t\t\tif (settings.SearchTermMatches(type.Name))\n\t\t\t{\n\t\t\t\tif (type.DeclaringType != null && (settings.ShowApiLevel != ApiVisibility.All || !LanguageService.Language.ShowMember(type)))\n\t\t\t\t\treturn FilterResult.Hidden;\n\t\t\t\telse\n\t\t\t\t\treturn FilterResult.Match;\n\t\t\t}\n\t\t\telse\n\t\t\t\treturn FilterResult.Recurse;\n\t\t}\n\n\t\tpublic override bool IsPublicAPI {\n\t\t\tget {\n\t\t\t\tswitch (type.Accessibility)\n\t\t\t\t{\n\t\t\t\t\tcase Accessibility.Public:\n\t\t\t\t\tcase Accessibility.Internal:\n\t\t\t\t\tcase Accessibility.ProtectedOrInternal:\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tthreading.LoadChildren(this, FetchChildren);\n\t\t}\n\n\t\tIEnumerable<ILSpyTreeNode> FetchChildren(CancellationToken ct)\n\t\t{\n\t\t\t// FetchChildren() runs on the main thread; but the enumerator will be consumed on a background thread\n\t\t\treturn DerivedTypesTreeNode.FindDerivedTypes(list, Language, type, ct);\n\t\t}\n\n\t\tpublic override void ActivateItem(IPlatformRoutedEventArgs e)\n\t\t{\n\t\t\te.Handled = BaseTypesEntryNode.ActivateItem(this, type);\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.WriteCommentLine(output, language.TypeToString(type));\n\t\t}\n\n\t\tIEntity IMemberTreeNode.Member => type;\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/DerivedTypesTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Threading;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.Analyzers;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// Lists the sub types of a class.\n\t/// </summary>\n\tsealed class DerivedTypesTreeNode : ILSpyTreeNode\n\t{\n\t\treadonly AssemblyList list;\n\t\treadonly ITypeDefinition type;\n\t\treadonly ThreadingSupport threading;\n\n\t\tpublic DerivedTypesTreeNode(AssemblyList list, ITypeDefinition type)\n\t\t{\n\t\t\tthis.list = list;\n\t\t\tthis.type = type;\n\t\t\tthis.LazyLoading = true;\n\t\t\tthis.threading = new ThreadingSupport();\n\t\t}\n\n\t\tpublic override object Text => Resources.DerivedTypes;\n\n\t\tpublic override object NavigationText => $\"{Text} ({this.Language.TypeToString(type)})\";\n\n\t\tpublic override object Icon => Images.SubTypes;\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tthreading.LoadChildren(this, FetchChildren);\n\t\t}\n\n\t\tIEnumerable<ILSpyTreeNode> FetchChildren(CancellationToken cancellationToken)\n\t\t{\n\t\t\t// FetchChildren() runs on the main thread; but the enumerator will be consumed on a background thread\n\t\t\treturn FindDerivedTypes(list, Language, type, cancellationToken);\n\t\t}\n\n\t\tinternal static IEnumerable<DerivedTypesEntryNode> FindDerivedTypes(AssemblyList list, Language language, ITypeDefinition type,\n\t\t\tCancellationToken cancellationToken)\n\t\t{\n\t\t\tvar context = new AnalyzerContext {\n\t\t\t\tCancellationToken = cancellationToken,\n\t\t\t\tLanguage = language,\n\t\t\t\tAssemblyList = list\n\t\t\t};\n\t\t\tvar scope = context.GetScopeOf(type);\n\n\t\t\tforeach (var td in scope.GetTypesInScope(cancellationToken))\n\t\t\t{\n\t\t\t\tforeach (var baseType in td.DirectBaseTypes)\n\t\t\t\t{\n\t\t\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\t\t\t\t\tif (baseType.FullName == type.FullName)\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return new DerivedTypesEntryNode(list, td);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tthreading.Decompile(language, output, options, EnsureLazyChildren);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/EventTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Reflection.Metadata;\nusing System.Windows.Media;\n\nusing ICSharpCode.Decompiler;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\tusing ICSharpCode.Decompiler.Output;\n\tusing ICSharpCode.Decompiler.TypeSystem;\n\tusing ICSharpCode.ILSpyX;\n\n\t/// <summary>\n\t/// Represents an event in the TreeView.\n\t/// </summary>\n\tpublic sealed class EventTreeNode : ILSpyTreeNode, IMemberTreeNode\n\t{\n\t\tpublic EventTreeNode(IEvent @event)\n\t\t{\n\t\t\tthis.EventDefinition = @event ?? throw new ArgumentNullException(nameof(@event));\n\t\t\tif (@event.CanAdd)\n\t\t\t\tthis.Children.Add(new MethodTreeNode(@event.AddAccessor));\n\t\t\tif (@event.CanRemove)\n\t\t\t\tthis.Children.Add(new MethodTreeNode(@event.RemoveAccessor));\n\t\t\tif (@event.CanInvoke)\n\t\t\t\tthis.Children.Add(new MethodTreeNode(@event.InvokeAccessor));\n\t\t\t//foreach (var m in ev.OtherMethods)\n\t\t\t//\tthis.Children.Add(new MethodTreeNode(m));\n\t\t}\n\n\t\tpublic IEvent EventDefinition { get; }\n\n\t\tpublic override object Text => GetText(GetEventDefinition(), this.Language) + GetSuffixString(EventDefinition);\n\n\t\tpublic override object NavigationText => GetText(GetEventDefinition(), Language, includeDeclaringTypeName: true);\n\n\t\tprivate IEvent GetEventDefinition()\n\t\t{\n\t\t\treturn ((MetadataModule)EventDefinition.ParentModule?.MetadataFile\n\t\t\t\t?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion)\n\t\t\t\t?.MainModule)?.GetDefinition((EventDefinitionHandle)EventDefinition.MetadataToken) ?? EventDefinition;\n\t\t}\n\n\t\tpublic static object GetText(IEvent ev, Language language, bool includeDeclaringTypeName = false)\n\t\t{\n\t\t\treturn language.EntityToString(ev, includeDeclaringTypeName ? ConversionFlags.ShowDeclaringType : ConversionFlags.None);\n\t\t}\n\n\t\tpublic override object Icon => GetIcon(GetEventDefinition());\n\n\t\tpublic static ImageSource GetIcon(IEvent @event)\n\t\t{\n\t\t\treturn Images.GetIcon(MemberIcon.Event, Images.GetOverlayIcon(@event.Accessibility), @event.IsStatic);\n\t\t}\n\n\t\tpublic override FilterResult Filter(LanguageSettings settings)\n\t\t{\n\t\t\tif (settings.ShowApiLevel == ApiVisibility.PublicOnly && !IsPublicAPI)\n\t\t\t\treturn FilterResult.Hidden;\n\t\t\tif (settings.SearchTermMatches(EventDefinition.Name) && (settings.ShowApiLevel == ApiVisibility.All || LanguageService.Language.ShowMember(EventDefinition)))\n\t\t\t\treturn FilterResult.Match;\n\t\t\telse\n\t\t\t\treturn FilterResult.Hidden;\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.DecompileEvent(EventDefinition, output, options);\n\t\t}\n\n\t\tpublic override bool IsPublicAPI {\n\t\t\tget {\n\t\t\t\tswitch (GetEventDefinition().Accessibility)\n\t\t\t\t{\n\t\t\t\t\tcase Accessibility.Public:\n\t\t\t\t\tcase Accessibility.ProtectedOrInternal:\n\t\t\t\t\tcase Accessibility.Protected:\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tIEntity IMemberTreeNode.Member => EventDefinition;\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn \"Event \" + EventDefinition.Name;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/ExportedTypeTreeNode.cs",
    "content": "// Copyright (c) 2023 James May\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// exported type within assembly reference list.\n\t/// </summary>\n\tpublic sealed class ExportedTypeTreeNode : ILSpyTreeNode\n\t{\n\t\treadonly MetadataModule module;\n\t\treadonly ExportedTypeMetadata r;\n\t\treadonly IType resolvedType;\n\n\t\tpublic ExportedTypeTreeNode(MetadataModule module, ExportedTypeMetadata r)\n\t\t{\n\t\t\tthis.module = module ?? throw new ArgumentNullException(nameof(module));\n\t\t\tthis.r = r ?? throw new ArgumentNullException(nameof(r));\n\t\t\tthis.resolvedType = module.ResolveType(r.Handle, default);\n\n\t\t\tthis.LazyLoading = true;\n\t\t}\n\n\t\tpublic override object Text\n\t\t\t=> Language.TypeToString(resolvedType) + GetSuffixString(r.Handle);\n\n\t\tpublic override object Icon => Images.ExportedType;\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tforeach (var exportedType in r.ExportedTypes)\n\t\t\t\tthis.Children.Add(new ExportedTypeTreeNode(module, exportedType));\n\t\t}\n\n\t\tpublic override bool ShowExpander => !r.ExportedTypes.IsEmpty;\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.WriteCommentLine(output, $\"{Language.TypeToString(resolvedType)} (Exported, IsForwarder: {r.IsForwarder}, Attributes: {(int)r.Attributes:X8})\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/FieldTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Reflection.Metadata;\nusing System.Windows.Media;\n\nusing ICSharpCode.Decompiler;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\tusing ICSharpCode.Decompiler.Output;\n\tusing ICSharpCode.Decompiler.TypeSystem;\n\tusing ICSharpCode.ILSpyX;\n\n\t/// <summary>\n\t/// Represents a field in the TreeView.\n\t/// </summary>\n\tpublic sealed class FieldTreeNode : ILSpyTreeNode, IMemberTreeNode\n\t{\n\t\tpublic IField FieldDefinition { get; }\n\n\t\tpublic FieldTreeNode(IField field)\n\t\t{\n\t\t\tthis.FieldDefinition = field ?? throw new ArgumentNullException(nameof(field));\n\t\t}\n\n\t\tpublic override object Text => GetText(GetFieldDefinition(), Language) + GetSuffixString(FieldDefinition);\n\n\t\tpublic override object NavigationText => GetText(GetFieldDefinition(), Language, includeDeclaringTypeName: true);\n\n\t\tprivate IField GetFieldDefinition()\n\t\t{\n\t\t\treturn ((MetadataModule)FieldDefinition.ParentModule?.MetadataFile\n\t\t\t\t?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion)\n\t\t\t\t?.MainModule)?.GetDefinition((FieldDefinitionHandle)FieldDefinition.MetadataToken) ?? FieldDefinition;\n\t\t}\n\n\t\tpublic static object GetText(IField field, Language language, bool includeDeclaringTypeName = false)\n\t\t{\n\t\t\treturn language.EntityToString(field, includeDeclaringTypeName ? ConversionFlags.ShowDeclaringType : ConversionFlags.None);\n\t\t}\n\n\t\tpublic override object Icon => GetIcon(GetFieldDefinition());\n\n\t\tpublic static ImageSource GetIcon(IField field)\n\t\t{\n\t\t\tif (field.DeclaringType.Kind == TypeKind.Enum && field.ReturnType.Kind == TypeKind.Enum)\n\t\t\t\treturn Images.GetIcon(MemberIcon.EnumValue, Images.GetOverlayIcon(field.Accessibility), false);\n\n\t\t\tif (field.IsConst)\n\t\t\t\treturn Images.GetIcon(MemberIcon.Literal, Images.GetOverlayIcon(field.Accessibility), false);\n\n\t\t\tif (field.IsReadOnly)\n\t\t\t\treturn Images.GetIcon(MemberIcon.FieldReadOnly, Images.GetOverlayIcon(field.Accessibility), field.IsStatic);\n\n\t\t\treturn Images.GetIcon(MemberIcon.Field, Images.GetOverlayIcon(field.Accessibility), field.IsStatic);\n\t\t}\n\n\t\tpublic override FilterResult Filter(LanguageSettings settings)\n\t\t{\n\t\t\tif (settings.ShowApiLevel == ApiVisibility.PublicOnly && !IsPublicAPI)\n\t\t\t\treturn FilterResult.Hidden;\n\t\t\tif (settings.SearchTermMatches(FieldDefinition.Name) && (settings.ShowApiLevel == ApiVisibility.All || LanguageService.Language.ShowMember(FieldDefinition)))\n\t\t\t\treturn FilterResult.Match;\n\t\t\telse\n\t\t\t\treturn FilterResult.Hidden;\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.DecompileField(FieldDefinition, output, options);\n\t\t}\n\n\t\tpublic override bool IsPublicAPI {\n\t\t\tget {\n\t\t\t\tswitch (GetFieldDefinition().Accessibility)\n\t\t\t\t{\n\t\t\t\t\tcase Accessibility.Public:\n\t\t\t\t\tcase Accessibility.Protected:\n\t\t\t\t\tcase Accessibility.ProtectedOrInternal:\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tIEntity IMemberTreeNode.Member => FieldDefinition;\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn \"Field \" + FieldDefinition.Name;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/FilterResult.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\tpublic enum FilterResult\n\t{\n\t\t/// <summary>\n\t\t/// Hides the node.\n\t\t/// </summary>\n\t\tHidden,\n\t\t/// <summary>\n\t\t/// Shows the node (and resets the search term for child nodes).\n\t\t/// </summary>\n\t\tMatch,\n\t\t/// <summary>\n\t\t/// Hides the node only if all children are hidden (and resets the search term for child nodes).\n\t\t/// </summary>\n\t\tMatchAndRecurse,\n\t\t/// <summary>\n\t\t/// Hides the node only if all children are hidden (doesn't reset the search term for child nodes).\n\t\t/// </summary>\n\t\tRecurse\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/ILSpyTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Windows.Threading;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpyX.Abstractions;\nusing ICSharpCode.ILSpyX.TreeView;\nusing ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// Base class of all ILSpy tree nodes.\n\t/// </summary>\n\tpublic abstract class ILSpyTreeNode : SharpTreeNode, ITreeNode\n\t{\n\t\tprotected ILSpyTreeNode()\n\t\t{\n\t\t\tMessageBus<SettingsChangedEventArgs>.Subscribers += (sender, e) => Settings_Changed(sender, e);\n\t\t}\n\n\t\tLanguageSettings LanguageSettings => SettingsService.SessionSettings.LanguageSettings;\n\n\t\tpublic Language Language => LanguageService.Language;\n\n\t\tprotected static AssemblyTreeModel AssemblyTreeModel { get; } = App.ExportProvider.GetExportedValue<AssemblyTreeModel>();\n\n\t\tprotected static ICollection<IResourceNodeFactory> ResourceNodeFactories { get; } = App.ExportProvider.GetExportedValues<IResourceNodeFactory>().ToArray();\n\n\t\tprotected static SettingsService SettingsService { get; } = App.ExportProvider.GetExportedValue<SettingsService>();\n\n\t\tprotected static LanguageService LanguageService { get; } = App.ExportProvider.GetExportedValue<LanguageService>();\n\n\t\tprotected static DockWorkspace DockWorkspace { get; } = App.ExportProvider.GetExportedValue<DockWorkspace>();\n\n\t\tpublic virtual FilterResult Filter(LanguageSettings settings)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(settings.SearchTerm))\n\t\t\t\treturn FilterResult.Match;\n\t\t\telse\n\t\t\t\treturn FilterResult.Hidden;\n\t\t}\n\n\t\tpublic abstract void Decompile(Language language, ITextOutput output, DecompilationOptions options);\n\n\t\t/// <summary>\n\t\t/// Used to implement special view logic for some items.\n\t\t/// This method is called on the main thread when only a single item is selected.\n\t\t/// If it returns false, normal decompilation is used to view the item.\n\t\t/// </summary>\n\t\tpublic virtual bool View(ViewModels.TabPageModel tabPage)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic override void ActivateItemSecondary(IPlatformRoutedEventArgs e)\n\t\t{\n\t\t\tvar assemblyTreeModel = AssemblyTreeModel;\n\n\t\t\tassemblyTreeModel.SelectNode(this, inNewTabPage: true);\n\n\t\t\tApp.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, assemblyTreeModel.RefreshDecompiledView);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Used to implement special save logic for some items.\n\t\t/// This method is called on the main thread when only a single item is selected.\n\t\t/// If it returns false, normal decompilation is used to save the item.\n\t\t/// </summary>\n\t\tpublic virtual bool Save(ViewModels.TabPageModel tabPage)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic override void OnChildrenChanged(NotifyCollectionChangedEventArgs e)\n\t\t{\n\t\t\tbase.OnChildrenChanged(e);\n\n\t\t\tif (e.NewItems != null)\n\t\t\t{\n\t\t\t\tif (IsVisible)\n\t\t\t\t{\n\t\t\t\t\tforeach (ILSpyTreeNode node in e.NewItems)\n\t\t\t\t\t\tApplyFilterToChild(node);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid ApplyFilterToChild(ILSpyTreeNode child)\n\t\t{\n\t\t\tFilterResult r = child.Filter(this.LanguageSettings);\n\n\t\t\tswitch (r)\n\t\t\t{\n\t\t\t\tcase FilterResult.Hidden:\n\t\t\t\t\tchild.IsHidden = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase FilterResult.Match:\n\t\t\t\t\tchild.IsHidden = false;\n\t\t\t\t\tbreak;\n\t\t\t\tcase FilterResult.Recurse:\n\t\t\t\tcase FilterResult.MatchAndRecurse:\n\t\t\t\t\tchild.EnsureChildrenFiltered();\n\t\t\t\t\tchild.IsHidden = child.Children.All(c => c.IsHidden);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new InvalidEnumArgumentException();\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual void Settings_Changed(object sender, PropertyChangedEventArgs e)\n\t\t{\n\t\t\tif (sender is not ILSpy.LanguageSettings)\n\t\t\t\treturn;\n\t\t\tif (e.PropertyName is not (nameof(LanguageSettings.LanguageId) or nameof(LanguageSettings.LanguageVersionId)))\n\t\t\t\treturn;\n\n\t\t\tRaisePropertyChanged(nameof(Text));\n\t\t\tif (IsVisible)\n\t\t\t{\n\t\t\t\tforeach (ILSpyTreeNode node in this.Children.OfType<ILSpyTreeNode>())\n\t\t\t\t\tApplyFilterToChild(node);\n\t\t\t}\n\t\t}\n\n\t\tinternal void EnsureChildrenFiltered()\n\t\t{\n\t\t\tEnsureLazyChildren();\n\t\t\tforeach (ILSpyTreeNode node in this.Children.OfType<ILSpyTreeNode>())\n\t\t\t\tApplyFilterToChild(node);\n\t\t}\n\n\t\tprotected string GetSuffixString(IMember member) => GetSuffixString(member.MetadataToken);\n\n\t\tprotected string GetSuffixString(EntityHandle handle)\n\t\t{\n\t\t\tif (!SettingsService.DisplaySettings.ShowMetadataTokens)\n\t\t\t\treturn string.Empty;\n\n\t\t\tint token = MetadataTokens.GetToken(handle);\n\t\t\tif (SettingsService.DisplaySettings.ShowMetadataTokensInBase10)\n\t\t\t\treturn \" @\" + token;\n\t\t\treturn \" @\" + token.ToString(\"x8\");\n\t\t}\n\n\t\tpublic virtual bool IsPublicAPI {\n\t\t\tget { return true; }\n\t\t}\n\n\t\tpublic virtual bool IsAutoLoaded {\n\t\t\tget { return false; }\n\t\t}\n\n\t\tIEnumerable<ITreeNode> ITreeNode.Children => this.Children.OfType<ILSpyTreeNode>();\n\t}\n}"
  },
  {
    "path": "ILSpy/TreeNodes/IMemberTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n#nullable enable\n\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// Interface implemented by all tree nodes\n\t/// (both in main tree view and in analyzer)\n\t/// that represent TypeSystem members.\n\t/// </summary>\n\tpublic interface IMemberTreeNode\n\t{\n\t\t/// <summary>\n\t\t/// Returns the entity that is represented by this tree node.\n\t\t/// May return null, if the member cannot be resolved.\n\t\t/// </summary>\n\t\tIEntity? Member { get; }\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/MemberReferenceTreeNode.cs",
    "content": "// Copyright (c) 2023 James May\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Output;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// Reference to member from assembly reference list.\n\t/// </summary>\n\tpublic sealed class MemberReferenceTreeNode : ILSpyTreeNode\n\t{\n\t\treadonly MetadataModule module;\n\t\treadonly MemberReferenceMetadata r;\n\t\treadonly IMember resolvedMember;\n\n\t\tpublic MemberReferenceTreeNode(MetadataModule module, MemberReferenceMetadata r)\n\t\t{\n\t\t\tthis.module = module ?? throw new ArgumentNullException(nameof(module));\n\t\t\tthis.r = r;\n\t\t\tthis.resolvedMember = r.MemberReferenceKind switch {\n\t\t\t\tMemberReferenceKind.Method => module.ResolveMethod(r.Handle, default),\n\t\t\t\tMemberReferenceKind.Field => (IMember)module.ResolveEntity(r.Handle),\n\t\t\t\t_ => throw new NotSupportedException(),\n\t\t\t};\n\t\t}\n\n\t\tpublic override object Text => Signature + GetSuffixString(r.Handle);\n\n\t\tpublic override object NavigationText => $\"{Text} ({Properties.Resources.ReferencedTypes})\";\n\n\t\tpublic override object Icon => r.MemberReferenceKind switch {\n\t\t\tMemberReferenceKind.Method => Images.MethodReference,\n\t\t\tMemberReferenceKind.Field => Images.FieldReference,\n\t\t\t_ => throw new NotSupportedException(),\n\t\t};\n\n\t\tpublic string Signature => Language.EntityToString(resolvedMember, ConversionFlags.None);\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.WriteCommentLine(output, Signature);\n\t\t}\n\n\t\tpublic override object ToolTip => Language.GetRichTextTooltip(resolvedMember);\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/MethodTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Reflection.Metadata;\nusing System.Windows.Media;\n\nusing ICSharpCode.Decompiler;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\tusing ICSharpCode.Decompiler.Output;\n\tusing ICSharpCode.Decompiler.TypeSystem;\n\tusing ICSharpCode.ILSpyX;\n\n\t/// <summary>\n\t/// Tree Node representing a field, method, property, or event.\n\t/// </summary>\n\tpublic sealed class MethodTreeNode : ILSpyTreeNode, IMemberTreeNode\n\t{\n\t\tpublic IMethod MethodDefinition { get; }\n\n\t\tpublic MethodTreeNode(IMethod method)\n\t\t{\n\t\t\tthis.MethodDefinition = method ?? throw new ArgumentNullException(nameof(method));\n\t\t}\n\n\t\tpublic override object Text => GetText(GetMethodDefinition(), Language) + GetSuffixString(MethodDefinition);\n\n\t\tpublic override object NavigationText => GetText(GetMethodDefinition(), Language, includeDeclaringTypeName: true);\n\n\t\tprivate IMethod GetMethodDefinition()\n\t\t{\n\t\t\treturn ((MetadataModule)MethodDefinition.ParentModule?.MetadataFile\n\t\t\t\t?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion)\n\t\t\t\t?.MainModule)?.GetDefinition((MethodDefinitionHandle)MethodDefinition.MetadataToken) ?? MethodDefinition;\n\t\t}\n\n\t\tpublic static object GetText(IMethod method, Language language, bool includeDeclaringTypeName = false)\n\t\t{\n\t\t\treturn language.EntityToString(method, includeDeclaringTypeName ? ConversionFlags.ShowDeclaringType : ConversionFlags.None);\n\t\t}\n\n\t\tpublic override object Icon => GetIcon(GetMethodDefinition());\n\n\t\tpublic static ImageSource GetIcon(IMethod method)\n\t\t{\n\t\t\tif (method.IsOperator)\n\t\t\t\treturn Images.GetIcon(MemberIcon.Operator, Images.GetOverlayIcon(method.Accessibility), false);\n\n\t\t\tif (method.IsExtensionMethod)\n\t\t\t\treturn Images.GetIcon(MemberIcon.ExtensionMethod, Images.GetOverlayIcon(method.Accessibility), false);\n\n\t\t\tif (method.IsConstructor)\n\t\t\t\treturn Images.GetIcon(MemberIcon.Constructor, Images.GetOverlayIcon(method.Accessibility), method.IsStatic);\n\n\t\t\tif (!method.HasBody && method.HasAttribute(KnownAttribute.DllImport))\n\t\t\t\treturn Images.GetIcon(MemberIcon.PInvokeMethod, Images.GetOverlayIcon(method.Accessibility), true);\n\n\t\t\treturn Images.GetIcon(method.IsVirtual ? MemberIcon.VirtualMethod : MemberIcon.Method,\n\t\t\t\tImages.GetOverlayIcon(method.Accessibility), method.IsStatic);\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.DecompileMethod(MethodDefinition, output, options);\n\t\t}\n\n\t\tpublic override FilterResult Filter(LanguageSettings settings)\n\t\t{\n\t\t\tif (settings.ShowApiLevel == ApiVisibility.PublicOnly && !IsPublicAPI)\n\t\t\t\treturn FilterResult.Hidden;\n\t\t\tif (settings.SearchTermMatches(MethodDefinition.Name) && (settings.ShowApiLevel == ApiVisibility.All || LanguageService.Language.ShowMember(MethodDefinition)))\n\t\t\t\treturn FilterResult.Match;\n\t\t\telse\n\t\t\t\treturn FilterResult.Hidden;\n\t\t}\n\n\t\tpublic override bool IsPublicAPI {\n\t\t\tget {\n\t\t\t\tswitch (GetMethodDefinition().Accessibility)\n\t\t\t\t{\n\t\t\t\t\tcase Accessibility.Public:\n\t\t\t\t\tcase Accessibility.Protected:\n\t\t\t\t\tcase Accessibility.ProtectedOrInternal:\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tIEntity IMemberTreeNode.Member => MethodDefinition;\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn \"Method \" + LanguageService.ILLanguage.EntityToString(MethodDefinition, ConversionFlags.None);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/ModuleReferenceTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Reflection.Metadata;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// Module reference in ReferenceFolderTreeNode.\n\t/// </summary>\n\tsealed class ModuleReferenceTreeNode : ILSpyTreeNode\n\t{\n\t\treadonly MetadataFile module;\n\t\treadonly AssemblyTreeNode parentAssembly;\n\t\treadonly MetadataReader metadata;\n\t\treadonly ModuleReferenceHandle handle;\n\t\treadonly ModuleReference reference;\n\t\treadonly AssemblyFileHandle fileHandle;\n\t\treadonly AssemblyFile file;\n\t\treadonly string moduleName;\n\t\treadonly bool containsMetadata;\n\n\t\tpublic ModuleReferenceTreeNode(AssemblyTreeNode parentAssembly, ModuleReferenceHandle r, MetadataFile module)\n\t\t{\n\t\t\tthis.parentAssembly = parentAssembly ?? throw new ArgumentNullException(nameof(parentAssembly));\n\t\t\tif (r.IsNil)\n\t\t\t\tthrow new ArgumentNullException(nameof(r));\n\t\t\tthis.handle = r;\n\t\t\tthis.module = module ?? throw new ArgumentNullException(nameof(module));\n\t\t\tthis.metadata = module.Metadata;\n\t\t\tthis.reference = module.Metadata.GetModuleReference(r);\n\t\t\tthis.moduleName = ILAmbience.EscapeName(metadata.GetString(reference.Name));\n\n\t\t\tforeach (var h in metadata.AssemblyFiles)\n\t\t\t{\n\t\t\t\tvar file = metadata.GetAssemblyFile(h);\n\t\t\t\tif (metadata.StringComparer.Equals(file.Name, moduleName))\n\t\t\t\t{\n\t\t\t\t\tthis.file = file;\n\t\t\t\t\tthis.fileHandle = h;\n\t\t\t\t\tthis.containsMetadata = file.ContainsMetadata;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic override object Text {\n\t\t\tget { return moduleName + GetSuffixString(handle); }\n\t\t}\n\n\t\tpublic override object NavigationText => $\"{Text} ({Properties.Resources.References})\";\n\n\t\tpublic override object Icon => Images.Library;\n\n\t\tpublic override void ActivateItem(IPlatformRoutedEventArgs e)\n\t\t{\n\t\t\tvar assemblyListNode = parentAssembly.Parent as AssemblyListTreeNode;\n\t\t\tif (assemblyListNode != null && containsMetadata)\n\t\t\t{\n\t\t\t\tvar resolver = parentAssembly.LoadedAssembly.GetAssemblyResolver();\n\t\t\t\tvar mainModule = parentAssembly.LoadedAssembly.GetMetadataFileOrNull();\n\t\t\t\tif (mainModule != null)\n\t\t\t\t{\n\t\t\t\t\tassemblyListNode.Select(assemblyListNode.FindAssemblyNode(resolver.ResolveModule(mainModule, metadata.GetString(reference.Name))));\n\t\t\t\t\te.Handled = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\toutput.WriteLine(moduleName);\n\t\t\toutput.WriteLine(containsMetadata ? \"contains metadata\" : \"contains no metadata\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/NamespaceTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// Namespace node. The loading of the type nodes is handled by the parent AssemblyTreeNode.\n\t/// </summary>\n\tpublic sealed class NamespaceTreeNode : ILSpyTreeNode\n\t{\n\t\treadonly string name;\n\t\tbool isPublicAPI;\n\n\t\tpublic string Name {\n\t\t\tget { return name; }\n\t\t}\n\n\t\tpublic NamespaceTreeNode(string name)\n\t\t{\n\t\t\tif (name == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(name));\n\t\t\tthis.name = name;\n\t\t}\n\n\t\tpublic override object Text {\n\t\t\tget { return name.Length == 0 ? \"-\" : name; }\n\t\t}\n\n\t\tpublic override object Icon {\n\t\t\tget { return Images.Namespace; }\n\t\t}\n\n\t\tpublic override bool IsPublicAPI => isPublicAPI;\n\n\t\tinternal void SetPublicAPI(bool value)\n\t\t{\n\t\t\tthis.isPublicAPI = value;\n\t\t}\n\n\t\tpublic override FilterResult Filter(LanguageSettings settings)\n\t\t{\n\t\t\tif (settings.SearchTermMatches(name))\n\t\t\t\treturn FilterResult.MatchAndRecurse;\n\t\t\telse\n\t\t\t\treturn FilterResult.Recurse;\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.DecompileNamespace(name, this.Children.OfType<TypeTreeNode>().Select(t => t.TypeDefinition), output, options);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/NaturalStringComparer.cs",
    "content": "// Copyright (c) 2015 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// .NET natural string comparison\n\t/// </summary>\n\tpublic sealed class NaturalStringComparer\n\t{\n\t\tpublic static readonly IComparer<string> Instance = StringComparer.Create(CultureInfo.CurrentCulture, CompareOptions.NumericOrdering);\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/PackageFolderTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.TreeView;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// Lists the embedded resources in an assembly.\n\t/// </summary>\n\tsealed class PackageFolderTreeNode : ILSpyTreeNode\n\t{\n\t\tpublic PackageFolder Folder { get; }\n\n\t\tpublic PackageFolderTreeNode(PackageFolder folder, string text = null)\n\t\t{\n\t\t\tthis.Folder = folder;\n\t\t\tthis.Text = text ?? folder.Name;\n\t\t\tthis.LazyLoading = true;\n\t\t}\n\n\t\tpublic override object Text { get; }\n\n\t\tpublic override object Icon => Images.FolderClosed;\n\n\t\tpublic override object ExpandedIcon => Images.FolderOpen;\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tthis.Children.AddRange(LoadChildrenForFolder(Folder));\n\t\t}\n\n\t\tinternal static IEnumerable<SharpTreeNode> LoadChildrenForFolder(PackageFolder root)\n\t\t{\n\t\t\tforeach (var folder in root.Folders.OrderBy(f => f.Name))\n\t\t\t{\n\t\t\t\tstring newName = folder.Name;\n\t\t\t\tvar subfolder = folder;\n\t\t\t\twhile (subfolder.Folders.Count == 1 && subfolder.Entries.Count == 0)\n\t\t\t\t{\n\t\t\t\t\t// special case: a folder that only contains a single sub-folder\n\t\t\t\t\tsubfolder = subfolder.Folders[0];\n\t\t\t\t\tnewName = $\"{newName}/{subfolder.Name}\";\n\t\t\t\t}\n\t\t\t\tyield return new PackageFolderTreeNode(subfolder, newName);\n\t\t\t}\n\t\t\tforeach (var entry in root.Entries.OrderBy(e => e.Name))\n\t\t\t{\n\t\t\t\tif (entry.Name.EndsWith(\".dll\", StringComparison.OrdinalIgnoreCase)\n\t\t\t\t\t|| entry.Name.EndsWith(\".exe\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t{\n\t\t\t\t\tvar asm = root.ResolveFileName(entry.Name);\n\t\t\t\t\tif (asm != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return new AssemblyTreeNode(asm, entry);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return ResourceTreeNode.Create(entry);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tyield return ResourceTreeNode.Create(entry);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/PropertyTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Reflection.Metadata;\nusing System.Windows.Media;\n\nusing ICSharpCode.Decompiler;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\tusing ICSharpCode.Decompiler.Output;\n\tusing ICSharpCode.Decompiler.TypeSystem;\n\tusing ICSharpCode.ILSpyX;\n\n\t/// <summary>\n\t/// Represents a property in the TreeView.\n\t/// </summary>\n\tpublic sealed class PropertyTreeNode : ILSpyTreeNode, IMemberTreeNode\n\t{\n\t\treadonly bool isIndexer;\n\n\t\tpublic PropertyTreeNode(IProperty property)\n\t\t{\n\t\t\tthis.PropertyDefinition = property ?? throw new ArgumentNullException(nameof(property));\n\t\t\tthis.isIndexer = property.IsIndexer;\n\n\t\t\tif (property.CanGet)\n\t\t\t\tthis.Children.Add(new MethodTreeNode(property.Getter));\n\t\t\tif (property.CanSet)\n\t\t\t\tthis.Children.Add(new MethodTreeNode(property.Setter));\n\t\t\t/*foreach (var m in property.OtherMethods)\n\t\t\t\tthis.Children.Add(new MethodTreeNode(m));*/\n\t\t}\n\n\t\tpublic IProperty PropertyDefinition { get; }\n\n\t\tpublic override object Text => GetText(GetPropertyDefinition(), Language) + GetSuffixString(PropertyDefinition);\n\n\t\tpublic override object NavigationText => GetText(GetPropertyDefinition(), Language, includeDeclaringTypeName: true);\n\n\t\tprivate IProperty GetPropertyDefinition()\n\t\t{\n\t\t\treturn ((MetadataModule)PropertyDefinition.ParentModule?.MetadataFile\n\t\t\t\t?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion)\n\t\t\t\t?.MainModule)?.GetDefinition((PropertyDefinitionHandle)PropertyDefinition.MetadataToken) ?? PropertyDefinition;\n\t\t}\n\n\t\tpublic static object GetText(IProperty property, Language language, bool includeDeclaringTypeName = false)\n\t\t{\n\t\t\treturn language.EntityToString(property, includeDeclaringTypeName ? ConversionFlags.ShowDeclaringType : ConversionFlags.None);\n\t\t}\n\n\t\tpublic override object Icon => GetIcon(GetPropertyDefinition());\n\n\t\tpublic static ImageSource GetIcon(IProperty property)\n\t\t{\n\t\t\treturn Images.GetIcon(property.IsIndexer ? MemberIcon.Indexer : MemberIcon.Property,\n\t\t\t\tImages.GetOverlayIcon(property.Accessibility), property.IsStatic);\n\t\t}\n\n\t\tpublic override FilterResult Filter(LanguageSettings settings)\n\t\t{\n\t\t\tif (settings.ShowApiLevel == ApiVisibility.PublicOnly && !IsPublicAPI)\n\t\t\t\treturn FilterResult.Hidden;\n\t\t\tif (settings.SearchTermMatches(PropertyDefinition.Name) && (settings.ShowApiLevel == ApiVisibility.All || LanguageService.Language.ShowMember(PropertyDefinition)))\n\t\t\t\treturn FilterResult.Match;\n\t\t\telse\n\t\t\t\treturn FilterResult.Hidden;\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.DecompileProperty(PropertyDefinition, output, options);\n\t\t}\n\n\t\tpublic override bool IsPublicAPI {\n\t\t\tget {\n\t\t\t\tswitch (GetPropertyDefinition().Accessibility)\n\t\t\t\t{\n\t\t\t\t\tcase Accessibility.Public:\n\t\t\t\t\tcase Accessibility.ProtectedOrInternal:\n\t\t\t\t\tcase Accessibility.Protected:\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tIEntity IMemberTreeNode.Member => PropertyDefinition;\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn \"Property \" + LanguageService.ILLanguage.EntityToString(PropertyDefinition, ConversionFlags.None);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/ReferenceFolderTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Linq;\nusing System.Windows.Threading;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.Properties;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// References folder.\n\t/// </summary>\n\tsealed class ReferenceFolderTreeNode : ILSpyTreeNode\n\t{\n\t\treadonly MetadataFile module;\n\t\treadonly AssemblyTreeNode parentAssembly;\n\n\t\tpublic ReferenceFolderTreeNode(MetadataFile module, AssemblyTreeNode parentAssembly)\n\t\t{\n\t\t\tthis.module = module;\n\t\t\tthis.parentAssembly = parentAssembly;\n\t\t\tthis.LazyLoading = true;\n\t\t}\n\n\t\tpublic override object Text => Resources.References;\n\n\t\tpublic override object NavigationText => $\"{Text} ({module.Name})\";\n\n\t\tpublic override object Icon => Images.ReferenceFolder;\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tvar metadata = module.Metadata;\n\t\t\tvar metadataModule = (MetadataModule)module.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion)?.MainModule;\n\t\t\tforeach (var r in module.AssemblyReferences.OrderBy(r => r.Name))\n\t\t\t\tthis.Children.Add(new AssemblyReferenceTreeNode(metadataModule, r, parentAssembly));\n\t\t\tforeach (var r in metadata.GetModuleReferences().OrderBy(r => metadata.GetString(metadata.GetModuleReference(r).Name)))\n\t\t\t\tthis.Children.Add(new ModuleReferenceTreeNode(parentAssembly, r, module));\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tstring targetFramework = parentAssembly.LoadedAssembly.GetTargetFrameworkIdAsync().GetAwaiter().GetResult();\n\t\t\tstring runtimePack = parentAssembly.LoadedAssembly.GetRuntimePackAsync().GetAwaiter().GetResult();\n\t\t\toutput.WriteLine($\"Detected TargetFramework-Id: {targetFramework}\");\n\t\t\toutput.WriteLine($\"Detected RuntimePack: {runtimePack}\");\n\n\t\t\tApp.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(EnsureLazyChildren));\n\t\t\toutput.WriteLine();\n\t\t\toutput.WriteLine(\"Referenced assemblies (in metadata order):\");\n\t\t\t// Show metadata order of references\n\t\t\tforeach (var node in this.Children.OfType<ILSpyTreeNode>())\n\t\t\t\tnode.Decompile(language, output, options);\n\n\t\t\toutput.WriteLine();\n\t\t\toutput.WriteLine();\n\t\t\t// Show full assembly load log:\n\t\t\toutput.WriteLine(\"Assembly load log including transitive references:\");\n\t\t\tvar info = parentAssembly.LoadedAssembly.LoadedAssemblyReferencesInfo;\n\n\t\t\tforeach (var asm in info.Entries)\n\t\t\t{\n\t\t\t\toutput.WriteLine(asm.FullName);\n\t\t\t\toutput.Indent();\n\t\t\t\tAssemblyReferenceTreeNode.PrintAssemblyLoadLogMessages(output, asm);\n\t\t\t\toutput.Unindent();\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/ResourceListTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Linq;\nusing System.Windows.Threading;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.Properties;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// Lists the embedded resources in an assembly.\n\t/// </summary>\n\tsealed class ResourceListTreeNode : ILSpyTreeNode\n\t{\n\t\treadonly MetadataFile module;\n\n\t\tpublic ResourceListTreeNode(MetadataFile module)\n\t\t{\n\t\t\tthis.LazyLoading = true;\n\t\t\tthis.module = module;\n\t\t}\n\n\t\tpublic override object Text => Resources._Resources;\n\n\t\tpublic override object NavigationText => $\"{Text} ({module.Name})\";\n\n\t\tpublic override object Icon => Images.FolderClosed;\n\n\t\tpublic override object ExpandedIcon => Images.FolderOpen;\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tforeach (Resource r in module.Resources.OrderBy(m => m.Name, NaturalStringComparer.Instance))\n\t\t\t\tthis.Children.Add(ResourceTreeNode.Create(r));\n\t\t}\n\n\t\tpublic override FilterResult Filter(LanguageSettings settings)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(settings.SearchTerm))\n\t\t\t\treturn FilterResult.MatchAndRecurse;\n\t\t\telse\n\t\t\t\treturn FilterResult.Recurse;\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tApp.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(EnsureLazyChildren));\n\t\t\tforeach (ILSpyTreeNode child in this.Children)\n\t\t\t{\n\t\t\t\tchild.Decompile(language, output, options);\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/ResourceNodes/CursorResourceEntryNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Composition;\nusing System.IO;\nusing System.Windows.Controls;\nusing System.Windows.Media.Imaging;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX.Abstractions;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t[Export(typeof(IResourceNodeFactory))]\n\t[Shared]\n\tsealed class CursorResourceNodeFactory : IResourceNodeFactory\n\t{\n\t\tstatic readonly string[] imageFileExtensions = { \".cur\" };\n\n\t\tpublic ITreeNode CreateNode(Resource resource)\n\t\t{\n\t\t\tstring key = resource.Name;\n\t\t\tforeach (string fileExt in imageFileExtensions)\n\t\t\t{\n\t\t\t\tif (key.EndsWith(fileExt, StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\treturn new CursorResourceEntryNode(key, resource.TryOpenStream);\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tsealed class CursorResourceEntryNode : ResourceEntryNode\n\t{\n\t\tpublic CursorResourceEntryNode(string key, Func<Stream> openStream)\n\t\t\t: base(key, openStream)\n\t\t{\n\t\t}\n\n\t\tpublic override object Icon => Images.ResourceImage;\n\n\t\tpublic override bool View(TabPageModel tabPage)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tAvalonEditTextOutput output = new AvalonEditTextOutput();\n\t\t\t\tBitmapImage image = new BitmapImage();\n\t\t\t\tbyte[] curData;\n\t\t\t\tusing (var data = OpenStream())\n\t\t\t\t{\n\t\t\t\t\tif (data == null)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t//HACK: windows imaging does not understand that .cur files have the same layout as .ico\n\t\t\t\t\t// so load to data, and modify the ResourceType in the header to make look like an icon...\n\t\t\t\t\tMemoryStream s = data as MemoryStream;\n\t\t\t\t\tif (s == null)\n\t\t\t\t\t{\n\t\t\t\t\t\t// data was stored in another stream type (e.g. PinnedBufferedMemoryStream)\n\t\t\t\t\t\ts = new MemoryStream();\n\t\t\t\t\t\tdata.CopyTo(s);\n\t\t\t\t\t}\n\t\t\t\t\tcurData = s.ToArray();\n\t\t\t\t}\n\t\t\t\tcurData[2] = 1;\n\t\t\t\tusing (Stream stream = new MemoryStream(curData))\n\t\t\t\t{\n\t\t\t\t\timage.BeginInit();\n\t\t\t\t\timage.StreamSource = stream;\n\t\t\t\t\timage.EndInit();\n\t\t\t\t}\n\n\t\t\t\toutput.AddUIElement(() => new Image { Source = image });\n\t\t\t\toutput.WriteLine();\n\t\t\t\toutput.AddButton(Images.Save, Resources.Save, delegate {\n\t\t\t\t\tSave(null);\n\t\t\t\t});\n\t\t\t\ttabPage.ShowTextView(textView => textView.ShowNode(output, this));\n\t\t\t\ttabPage.SupportsLanguageSwitching = false;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/ResourceNodes/IResourceNodeFactory.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpyX.Abstractions;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// This interface allows plugins to create custom nodes for resources.\n\t/// </summary>\n\tpublic interface IResourceNodeFactory\n\t{\n\t\tITreeNode CreateNode(Resource resource);\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/ResourceNodes/IconResourceEntryNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Composition;\nusing System.IO;\nusing System.Windows.Controls;\nusing System.Windows.Media.Imaging;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX.Abstractions;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t[Export(typeof(IResourceNodeFactory))]\n\t[Shared]\n\tsealed class IconResourceNodeFactory : IResourceNodeFactory\n\t{\n\t\tpublic ITreeNode CreateNode(Resource resource)\n\t\t{\n\t\t\tif (resource.Name.EndsWith(\".ico\", StringComparison.OrdinalIgnoreCase))\n\t\t\t{\n\t\t\t\treturn new IconResourceEntryNode(resource.Name, resource.TryOpenStream);\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tsealed class IconResourceEntryNode : ResourceEntryNode\n\t{\n\t\tpublic IconResourceEntryNode(string key, Func<Stream> data)\n\t\t\t: base(key, data)\n\t\t{\n\t\t}\n\n\t\tpublic override object Icon => Images.ResourceImage;\n\n\t\tpublic override bool View(TabPageModel tabPage)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tAvalonEditTextOutput output = new AvalonEditTextOutput();\n\t\t\t\tusing var data = OpenStream();\n\t\t\t\tif (data == null)\n\t\t\t\t\treturn false;\n\t\t\t\tIconBitmapDecoder decoder = new IconBitmapDecoder(data, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);\n\t\t\t\tforeach (var frame in decoder.Frames)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(String.Format(\"{0}x{1}, {2} bit: \", frame.PixelHeight, frame.PixelWidth, frame.Thumbnail.Format.BitsPerPixel));\n\t\t\t\t\tAddIcon(output, frame);\n\t\t\t\t\toutput.WriteLine();\n\t\t\t\t}\n\t\t\t\toutput.AddButton(Images.Save, Resources.Save, delegate {\n\t\t\t\t\tSave(null);\n\t\t\t\t});\n\t\t\t\ttabPage.ShowTextView(textView => textView.ShowNode(output, this));\n\t\t\t\ttabPage.SupportsLanguageSwitching = false;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tprivate static void AddIcon(AvalonEditTextOutput output, BitmapFrame frame)\n\t\t{\n\t\t\toutput.AddUIElement(() => new Image { Source = frame });\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/ResourceNodes/ImageListResourceEntryNode.cs",
    "content": "// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Drawing;\nusing System.IO;\nusing System.Windows.Forms;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpyX.Abstractions;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t[Export(typeof(IResourceNodeFactory))]\n\t[Shared]\n\tsealed class ImageListResourceEntryNodeFactory : IResourceNodeFactory\n\t{\n\t\tpublic ITreeNode CreateNode(Resource resource)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic ILSpyTreeNode CreateNode(string key, object data)\n\t\t{\n\t\t\tif (data is ImageListStreamer)\n\t\t\t\treturn new ImageListResourceEntryNode(key, (ImageListStreamer)data);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tsealed class ImageListResourceEntryNode : ILSpyTreeNode\n\t{\n\t\tprivate readonly string key;\n\t\tprivate readonly ImageList data;\n\n\t\tpublic ImageListResourceEntryNode(string key, ImageListStreamer data)\n\t\t{\n\t\t\tthis.LazyLoading = true;\n\t\t\tthis.key = key;\n\t\t\tthis.data = new ImageList();\n\t\t\tthis.data.ImageStream = data;\n\t\t}\n\n\t\tpublic override object Text {\n\t\t\tget { return key; }\n\t\t}\n\n\t\tpublic override object Icon => Images.ResourceImage;\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tint i = 0;\n\t\t\tforeach (Image image in this.data.Images)\n\t\t\t{\n\t\t\t\tusing var s = new MemoryStream();\n\t\t\t\timage.Save(s, System.Drawing.Imaging.ImageFormat.Bmp);\n\t\t\t\tvar node = ResourceEntryNode.Create(\"Image\" + i.ToString(), s.ToArray());\n\t\t\t\tif (node != null)\n\t\t\t\t\tChildren.Add(node);\n\t\t\t\t++i;\n\t\t\t}\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tEnsureLazyChildren();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/ResourceNodes/ImageResourceEntryNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Composition;\nusing System.IO;\nusing System.Windows.Controls;\nusing System.Windows.Media.Imaging;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX.Abstractions;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t[Export(typeof(IResourceNodeFactory))]\n\t[Shared]\n\tsealed class ImageResourceNodeFactory : IResourceNodeFactory\n\t{\n\t\tstatic readonly string[] imageFileExtensions = { \".png\", \".gif\", \".bmp\", \".jpg\" };\n\n\t\tpublic ITreeNode CreateNode(Resource resource)\n\t\t{\n\t\t\tstring key = resource.Name;\n\t\t\tforeach (string fileExt in imageFileExtensions)\n\t\t\t{\n\t\t\t\tif (key.EndsWith(fileExt, StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\treturn new ImageResourceEntryNode(key, resource.TryOpenStream);\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tsealed class ImageResourceEntryNode : ResourceEntryNode\n\t{\n\t\tpublic ImageResourceEntryNode(string key, Func<Stream> openStream)\n\t\t\t: base(key, openStream)\n\t\t{\n\t\t}\n\n\t\tpublic override object Icon => Images.ResourceImage;\n\n\t\tpublic override bool View(TabPageModel tabPage)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tAvalonEditTextOutput output = new AvalonEditTextOutput();\n\t\t\t\tBitmapImage image = new BitmapImage();\n\t\t\t\timage.BeginInit();\n\t\t\t\timage.StreamSource = OpenStream();\n\t\t\t\timage.EndInit();\n\t\t\t\toutput.AddUIElement(() => new Image { Source = image });\n\t\t\t\toutput.WriteLine();\n\t\t\t\toutput.AddButton(Images.Save, Resources.Save, delegate {\n\t\t\t\t\tSave(null);\n\t\t\t\t});\n\t\t\t\ttabPage.ShowTextView(textView => textView.ShowNode(output, this));\n\t\t\t\ttabPage.SupportsLanguageSwitching = false;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/ResourceNodes/ResourceEntryNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.CSharp.ProjectDecompiler;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Metadata;\n\nusing Microsoft.Win32;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// Entry in a .resources file\n\t/// </summary>\n\tpublic class ResourceEntryNode : ILSpyTreeNode\n\t{\n\t\tprivate readonly string key;\n\t\tprivate readonly Func<Stream> openStream;\n\n\t\tpublic override object Text => ILAmbience.EscapeName(key);\n\n\t\tpublic override object Icon => Images.Resource;\n\n\t\tprotected Stream OpenStream()\n\t\t{\n\t\t\treturn openStream();\n\t\t}\n\n\t\tpublic ResourceEntryNode(string key, Func<Stream> openStream)\n\t\t{\n\t\t\tif (key == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(key));\n\t\t\tif (openStream == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(openStream));\n\t\t\tthis.key = key;\n\t\t\tthis.openStream = openStream;\n\t\t}\n\n\t\tpublic static ILSpyTreeNode Create(Resource resource)\n\t\t{\n\t\t\tILSpyTreeNode result = null;\n\t\t\tforeach (var factory in ResourceNodeFactories)\n\t\t\t{\n\t\t\t\tresult = factory.CreateNode(resource) as ILSpyTreeNode;\n\t\t\t\tif (result != null)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn result ?? new ResourceTreeNode(resource);\n\t\t}\n\n\t\tpublic static ILSpyTreeNode Create(string name, byte[] data)\n\t\t{\n\t\t\treturn Create(new ByteArrayResource(name, data));\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tusing var data = OpenStream();\n\t\t\tlanguage.WriteCommentLine(output, string.Format(\"{0} = {1}\", key, data));\n\t\t}\n\n\t\tpublic override bool Save(ViewModels.TabPageModel tabPage)\n\t\t{\n\t\t\tSaveFileDialog dlg = new SaveFileDialog();\n\t\t\tdlg.FileName = Path.GetFileName(WholeProjectDecompiler.SanitizeFileName(key));\n\t\t\tif (dlg.ShowDialog() == true)\n\t\t\t{\n\t\t\t\tusing var data = OpenStream();\n\t\t\t\tusing var fs = dlg.OpenFile();\n\t\t\t\tdata.CopyTo(fs);\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/ResourceNodes/ResourceTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\nusing System.Reflection;\nusing System.Text;\n\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.AvalonEdit.Utils;\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.CSharp.ProjectDecompiler;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.Abstractions;\n\nusing Microsoft.Win32;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// This is the default resource entry tree node, which is used if no specific\n\t/// <see cref=\"IResourceNodeFactory\"/> exists for the given resource type. \n\t/// </summary>\n\tpublic class ResourceTreeNode : ILSpyTreeNode, IResourcesFileTreeNode\n\t{\n\t\tpublic ResourceTreeNode(Resource r)\n\t\t{\n\t\t\tif (r == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(r));\n\t\t\tthis.Resource = r;\n\t\t}\n\n\t\tpublic Resource Resource { get; }\n\n\t\tpublic override object Text => ILAmbience.EscapeName(Resource.Name);\n\n\t\tpublic override object Icon => Images.Resource;\n\n\t\tpublic override FilterResult Filter(LanguageSettings settings)\n\t\t{\n\t\t\tif (settings.ShowApiLevel == ApiVisibility.PublicOnly && (Resource.Attributes & ManifestResourceAttributes.VisibilityMask) == ManifestResourceAttributes.Private)\n\t\t\t\treturn FilterResult.Hidden;\n\t\t\tif (settings.SearchTermMatches(Resource.Name))\n\t\t\t\treturn FilterResult.Match;\n\t\t\telse\n\t\t\t\treturn FilterResult.Hidden;\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tvar sizeInBytes = Resource.TryGetLength();\n\t\t\tvar sizeInBytesText = sizeInBytes == null ? \"\" : \", \" + sizeInBytes + \" bytes\";\n\t\t\tlanguage.WriteCommentLine(output, $\"{Resource.Name} ({Resource.ResourceType}, {Resource.Attributes}{sizeInBytesText})\");\n\n\t\t\tISmartTextOutput smartOutput = output as ISmartTextOutput;\n\t\t\tif (smartOutput != null)\n\t\t\t{\n\t\t\t\tsmartOutput.AddButton(Images.Save, Resources.Save, delegate { Save(DockWorkspace.ActiveTabPage); });\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool View(TabPageModel tabPage)\n\t\t{\n\t\t\tStream s = Resource.TryOpenStream();\n\t\t\tif (s != null && s.Length < DecompilerTextView.DefaultOutputLengthLimit)\n\t\t\t{\n\t\t\t\ts.Position = 0;\n\t\t\t\tFileType type = GuessFileType.DetectFileType(s);\n\t\t\t\tif (type != FileType.Binary)\n\t\t\t\t{\n\t\t\t\t\ts.Position = 0;\n\t\t\t\t\tAvalonEditTextOutput output = new AvalonEditTextOutput();\n\t\t\t\t\toutput.Title = Resource.Name;\n\t\t\t\t\toutput.Write(FileReader.OpenStream(s, Encoding.UTF8).ReadToEnd());\n\t\t\t\t\tstring ext;\n\t\t\t\t\tif (type == FileType.Xml)\n\t\t\t\t\t\text = \".xml\";\n\t\t\t\t\telse\n\t\t\t\t\t\text = Path.GetExtension(WholeProjectDecompiler.SanitizeFileName(Resource.Name));\n\t\t\t\t\ttabPage.ShowTextView(textView => textView.ShowNode(output, this, HighlightingManager.Instance.GetDefinitionByExtension(ext)));\n\t\t\t\t\ttabPage.SupportsLanguageSwitching = false;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic override bool Save(TabPageModel tabPage)\n\t\t{\n\t\t\tStream s = Resource.TryOpenStream();\n\t\t\tif (s == null)\n\t\t\t\treturn false;\n\t\t\tSaveFileDialog dlg = new SaveFileDialog();\n\t\t\tdlg.FileName = Path.GetFileName(WholeProjectDecompiler.SanitizeFileName(Resource.Name));\n\t\t\tif (dlg.ShowDialog() == true)\n\t\t\t{\n\t\t\t\ts.Position = 0;\n\t\t\t\tusing (var fs = dlg.OpenFile())\n\t\t\t\t{\n\t\t\t\t\ts.CopyTo(fs);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic static ILSpyTreeNode Create(Resource resource)\n\t\t{\n\t\t\treturn ResourceEntryNode.Create(resource);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/ResourceNodes/ResourcesFileTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Composition;\nusing System.IO;\nusing System.Linq;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.CSharp.ProjectDecompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Util;\nusing ICSharpCode.ILSpy.Controls;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX.Abstractions;\n\nusing Microsoft.Win32;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t[Export(typeof(IResourceNodeFactory))]\n\t[Shared]\n\tsealed class ResourcesFileTreeNodeFactory : IResourceNodeFactory\n\t{\n\t\tpublic ITreeNode CreateNode(Resource resource)\n\t\t{\n\t\t\tif (resource.Name.EndsWith(\".resources\", StringComparison.OrdinalIgnoreCase))\n\t\t\t{\n\t\t\t\treturn new ResourcesFileTreeNode(resource);\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic ILSpyTreeNode CreateNode(string key, object data)\n\t\t{\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tsealed class ResourcesFileTreeNode : ResourceTreeNode, IResourcesFileTreeNode\n\t{\n\t\treadonly ICollection<KeyValuePair<string, string>> stringTableEntries = new ObservableCollection<KeyValuePair<string, string>>();\n\t\treadonly ICollection<SerializedObjectRepresentation> otherEntries = new ObservableCollection<SerializedObjectRepresentation>();\n\n\t\tpublic ResourcesFileTreeNode(Resource er)\n\t\t\t: base(er)\n\t\t{\n\t\t\tthis.LazyLoading = true;\n\t\t}\n\n\t\tpublic override object Icon => Images.ResourceResourcesFile;\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tStream s = Resource.TryOpenStream();\n\t\t\tif (s == null)\n\t\t\t\treturn;\n\t\t\ts.Position = 0;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tforeach (var entry in new ResourcesFile(s).OrderBy(e => e.Key, NaturalStringComparer.Instance))\n\t\t\t\t{\n\t\t\t\t\tProcessResourceEntry(entry);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (BadImageFormatException)\n\t\t\t{\n\t\t\t\t// ignore errors\n\t\t\t}\n\t\t\tcatch (EndOfStreamException)\n\t\t\t{\n\t\t\t\t// ignore errors\n\t\t\t}\n\t\t}\n\n\t\tprivate void ProcessResourceEntry(KeyValuePair<string, object> entry)\n\t\t{\n\t\t\tif (entry.Value is string)\n\t\t\t{\n\t\t\t\tstringTableEntries.Add(new KeyValuePair<string, string>(entry.Key, (string)entry.Value));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (entry.Value is byte[])\n\t\t\t{\n\t\t\t\tChildren.Add(ResourceEntryNode.Create(entry.Key, (byte[])entry.Value));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (entry.Value is MemoryStream ms)\n\t\t\t{\n\t\t\t\tChildren.Add(ResourceEntryNode.Create(entry.Key, ms.ToArray()));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (entry.Value == null)\n\t\t\t{\n\t\t\t\totherEntries.Add(new SerializedObjectRepresentation(entry.Key, \"null\", \"\"));\n\t\t\t}\n\t\t\telse if (entry.Value is ResourceSerializedObject so)\n\t\t\t{\n\t\t\t\totherEntries.Add(new SerializedObjectRepresentation(entry.Key, so.TypeName, \"<serialized>\"));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\totherEntries.Add(new SerializedObjectRepresentation(entry.Key, entry.Value.GetType().FullName, entry.Value.ToString()));\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool Save(TabPageModel tabPage)\n\t\t{\n\t\t\tStream s = Resource.TryOpenStream();\n\t\t\tif (s == null)\n\t\t\t\treturn false;\n\t\t\tSaveFileDialog dlg = new SaveFileDialog();\n\t\t\tdlg.FileName = Path.GetFileName(WholeProjectDecompiler.SanitizeFileName(Resource.Name));\n\t\t\tdlg.Filter = Resources.ResourcesFileFilter;\n\t\t\tif (dlg.ShowDialog() == true)\n\t\t\t{\n\t\t\t\ts.Position = 0;\n\t\t\t\tswitch (dlg.FilterIndex)\n\t\t\t\t{\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tusing (var fs = dlg.OpenFile())\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ts.CopyTo(fs);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tusing (var fs = dlg.OpenFile())\n\t\t\t\t\t\t\tusing (var writer = new ResXResourceWriter(fs))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tforeach (var entry in new ResourcesFile(s))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\twriter.AddResource(entry.Key, entry.Value);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (BadImageFormatException)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// ignore errors\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (EndOfStreamException)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// ignore errors\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tEnsureLazyChildren();\n\t\t\tbase.Decompile(language, output, options);\n\t\t\tvar textView = (DecompilerTextView)DockWorkspace.ActiveTabPage.Content;\n\t\t\tif (stringTableEntries.Count != 0)\n\t\t\t{\n\t\t\t\tISmartTextOutput smartOutput = output as ISmartTextOutput;\n\t\t\t\tif (null != smartOutput)\n\t\t\t\t{\n\t\t\t\t\tsmartOutput.AddUIElement(\n\t\t\t\t\t\tdelegate {\n\t\t\t\t\t\t\treturn new ResourceStringTable(stringTableEntries, textView);\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\toutput.WriteLine();\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t\tif (otherEntries.Count != 0)\n\t\t\t{\n\t\t\t\tISmartTextOutput smartOutput = output as ISmartTextOutput;\n\t\t\t\tif (null != smartOutput)\n\t\t\t\t{\n\t\t\t\t\tsmartOutput.AddUIElement(\n\t\t\t\t\t\tdelegate {\n\t\t\t\t\t\t\treturn new ResourceObjectTable(otherEntries, textView);\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t}\n\n\t\tinternal class SerializedObjectRepresentation\n\t\t{\n\t\t\tpublic SerializedObjectRepresentation(string key, string type, string value)\n\t\t\t{\n\t\t\t\tthis.Key = key;\n\t\t\t\tthis.Type = type;\n\t\t\t\tthis.Value = value;\n\t\t\t}\n\n\t\t\tpublic string Key { get; private set; }\n\t\t\tpublic string Type { get; private set; }\n\t\t\tpublic string Value { get; private set; }\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/ResourceNodes/XamlResourceNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Composition;\nusing System.IO;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX.Abstractions;\n\nnamespace ICSharpCode.ILSpy.Xaml\n{\n\t[Export(typeof(IResourceNodeFactory))]\n\t[Shared]\n\tsealed class XamlResourceNodeFactory : IResourceNodeFactory\n\t{\n\t\tpublic ITreeNode CreateNode(Resource resource)\n\t\t{\n\t\t\tif (resource.Name.EndsWith(\".xaml\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\treturn new XamlResourceEntryNode(resource.Name, resource.TryOpenStream);\n\t\t\telse\n\t\t\t\treturn null;\n\t\t}\n\t}\n\n\tsealed class XamlResourceEntryNode : ResourceEntryNode\n\t{\n\t\tstring xaml;\n\n\t\tpublic XamlResourceEntryNode(string key, Func<Stream> openStream) : base(key, openStream)\n\t\t{\n\t\t}\n\n\t\tpublic override bool View(TabPageModel tabPage)\n\t\t{\n\t\t\tAvalonEditTextOutput output = new AvalonEditTextOutput();\n\t\t\tIHighlightingDefinition highlighting = null;\n\n\t\t\ttabPage.ShowTextView(textView => textView.RunWithCancellation(\n\t\t\t\ttoken => Task.Factory.StartNew(\n\t\t\t\t\t() => {\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// cache read XAML because stream will be closed after first read\n\t\t\t\t\t\t\tif (xaml == null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tusing var data = OpenStream();\n\t\t\t\t\t\t\t\tif (data == null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\toutput.Write(\"ILSpy: Failed opening resource stream.\");\n\t\t\t\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t\t\t\t\treturn output;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tusing (var reader = new StreamReader(data))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\txaml = reader.ReadToEnd();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\toutput.Write(xaml);\n\t\t\t\t\t\t\thighlighting = HighlightingManager.Instance.GetDefinitionByExtension(\".xml\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (Exception ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toutput.Write(ex.ToString());\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn output;\n\t\t\t\t\t}, token)\n\t\t\t).Then(t => textView.ShowNode(t, this, highlighting)).HandleExceptions());\n\t\t\ttabPage.SupportsLanguageSwitching = false;\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/ResourceNodes/XmlResourceNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Composition;\nusing System.IO;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.ViewModels;\nusing ICSharpCode.ILSpyX.Abstractions;\n\nnamespace ICSharpCode.ILSpy.Xaml\n{\n\t[Export(typeof(IResourceNodeFactory))]\n\t[Shared]\n\tsealed class XmlResourceNodeFactory : IResourceNodeFactory\n\t{\n\t\tprivate readonly static string[] xmlFileExtensions = { \".xml\", \".xsd\", \".xslt\" };\n\n\t\tpublic ITreeNode CreateNode(Resource resource)\n\t\t{\n\t\t\tstring key = resource.Name;\n\t\t\tforeach (string fileExt in xmlFileExtensions)\n\t\t\t{\n\t\t\t\tif (key.EndsWith(fileExt, StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\treturn new XmlResourceEntryNode(key, resource.TryOpenStream);\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tsealed class XmlResourceEntryNode : ResourceEntryNode\n\t{\n\t\tstring xml;\n\n\t\tpublic XmlResourceEntryNode(string key, Func<Stream> data)\n\t\t\t: base(key, data)\n\t\t{\n\t\t}\n\n\t\tpublic override object Icon {\n\t\t\tget {\n\t\t\t\tstring text = (string)Text;\n\t\t\t\tif (text.EndsWith(\".xml\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\treturn Images.ResourceXml;\n\t\t\t\telse if (text.EndsWith(\".xsd\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\treturn Images.ResourceXsd;\n\t\t\t\telse if (text.EndsWith(\".xslt\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\treturn Images.ResourceXslt;\n\t\t\t\telse\n\t\t\t\t\treturn Images.Resource;\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool View(TabPageModel tabPage)\n\t\t{\n\t\t\tAvalonEditTextOutput output = new AvalonEditTextOutput();\n\t\t\tIHighlightingDefinition highlighting = null;\n\n\t\t\ttabPage.ShowTextView(textView => textView.RunWithCancellation(\n\t\t\t\ttoken => Task.Factory.StartNew(\n\t\t\t\t\t() => {\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// cache read XAML because stream will be closed after first read\n\t\t\t\t\t\t\tif (xml == null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tusing var data = OpenStream();\n\t\t\t\t\t\t\t\tif (data == null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\toutput.Write(\"ILSpy: Failed opening resource stream.\");\n\t\t\t\t\t\t\t\t\toutput.WriteLine();\n\t\t\t\t\t\t\t\t\treturn output;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tusing (var reader = new StreamReader(data))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\txml = reader.ReadToEnd();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\toutput.Write(xml);\n\t\t\t\t\t\t\thighlighting = HighlightingManager.Instance.GetDefinitionByExtension(\".xml\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (Exception ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toutput.Write(ex.ToString());\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn output;\n\t\t\t\t\t}, token)\n\t\t\t).Then(t => textView.ShowNode(t, this, highlighting))\n\t\t\t.HandleExceptions());\n\t\t\ttabPage.SupportsLanguageSwitching = false;\n\t\t\treturn true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/ThreadingSupport.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Threading;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpyX.TreeView;\n\n#nullable enable\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// Adds threading support to nodes\n\t/// </summary>\n\tclass ThreadingSupport\n\t{\n\t\treadonly Stopwatch stopwatch = new Stopwatch();\n\t\tCancellationTokenSource cancellationTokenSource = new CancellationTokenSource();\n\t\tTask<List<SharpTreeNode>>? loadChildrenTask;\n\n\t\tpublic bool IsRunning {\n\t\t\tget { return loadChildrenTask != null && !loadChildrenTask.IsCompleted; }\n\t\t}\n\n\t\tpublic long EllapsedMilliseconds => stopwatch.ElapsedMilliseconds;\n\n\t\tpublic void Cancel()\n\t\t{\n\t\t\tcancellationTokenSource.Cancel();\n\t\t\tloadChildrenTask = null;\n\t\t\tcancellationTokenSource = new CancellationTokenSource();\n\t\t\tstopwatch.Reset();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Starts loading the children of the specified node.\n\t\t/// </summary>\n\t\tpublic void LoadChildren(SharpTreeNode node, Func<CancellationToken, IEnumerable<SharpTreeNode>> fetchChildren)\n\t\t{\n\t\t\tstopwatch.Restart();\n\t\t\tnode.Children.Add(new LoadingTreeNode());\n\n\t\t\tCancellationToken ct = cancellationTokenSource.Token;\n\n\t\t\tvar fetchChildrenEnumerable = fetchChildren(ct);\n\t\t\tTask<List<SharpTreeNode>>? thisTask = null;\n\t\t\tthisTask = new Task<List<SharpTreeNode>>(\n\t\t\t\tdelegate {\n\t\t\t\t\tList<SharpTreeNode> result = new List<SharpTreeNode>();\n\t\t\t\t\tforeach (SharpTreeNode child in fetchChildrenEnumerable)\n\t\t\t\t\t{\n\t\t\t\t\t\tct.ThrowIfCancellationRequested();\n\t\t\t\t\t\tresult.Add(child);\n\t\t\t\t\t\tApp.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action<SharpTreeNode>(\n\t\t\t\t\t\t\tdelegate (SharpTreeNode newChild) {\n\t\t\t\t\t\t\t\t// don't access \"child\" here,\n\t\t\t\t\t\t\t\t// the background thread might already be running the next loop iteration\n\t\t\t\t\t\t\t\tif (loadChildrenTask == thisTask)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tnode.Children.Insert(node.Children.Count - 1, newChild);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}), child);\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t}, ct);\n\t\t\tloadChildrenTask = thisTask;\n\t\t\tthisTask.Start();\n\t\t\tthisTask.ContinueWith(\n\t\t\t\tdelegate (Task continuation) {\n\t\t\t\t\tApp.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(\n\t\t\t\t\t\tdelegate {\n\t\t\t\t\t\t\tif (loadChildrenTask == thisTask)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstopwatch.Stop();\n\t\t\t\t\t\t\t\tnode.Children.RemoveAt(node.Children.Count - 1); // remove 'Loading...'\n\t\t\t\t\t\t\t\tnode.RaisePropertyChanged(nameof(node.Text));\n\n\t\t\t\t\t\t\t\tif (continuation.Exception != null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tforeach (Exception ex in continuation.Exception.InnerExceptions)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tnode.Children.Add(new ErrorTreeNode(ex));\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}));\n\t\t\t\t});\n\n\t\t\t// Give the task a bit time to complete before we return to WPF - this keeps \"Loading...\"\n\t\t\t// from showing up for very short waits.\n\t\t\tthisTask.Wait(TimeSpan.FromMilliseconds(200));\n\t\t}\n\n\t\tpublic void Decompile(Language language, ITextOutput output, DecompilationOptions options, Action ensureLazyChildren)\n\t\t{\n\t\t\tvar loadChildrenTask = this.loadChildrenTask;\n\t\t\tif (loadChildrenTask == null)\n\t\t\t{\n\t\t\t\tApp.Current.Dispatcher.Invoke(DispatcherPriority.Normal, ensureLazyChildren);\n\t\t\t\tloadChildrenTask = this.loadChildrenTask;\n\t\t\t}\n\t\t\tif (loadChildrenTask != null)\n\t\t\t{\n\t\t\t\tforeach (ILSpyTreeNode child in loadChildrenTask.Result.Cast<ILSpyTreeNode>())\n\t\t\t\t{\n\t\t\t\t\tchild.Decompile(language, output, options);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tsealed class LoadingTreeNode : ILSpyTreeNode\n\t\t{\n\t\t\tpublic override object Text {\n\t\t\t\tget { return Resources.Loading; }\n\t\t\t}\n\n\t\t\tpublic override FilterResult Filter(LanguageSettings settings)\n\t\t\t{\n\t\t\t\treturn FilterResult.Match;\n\t\t\t}\n\n\t\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t\t{\n\t\t\t}\n\t\t}\n\n\t\t[ExportContextMenuEntry(Header = nameof(Resources.CopyErrorMessage))]\n\t\t[Shared]\n\t\tsealed class CopyErrorMessageContextMenu : IContextMenuEntry\n\t\t{\n\t\t\tpublic bool IsVisible(TextViewContext context)\n\t\t\t{\n\t\t\t\tif (context.SelectedTreeNodes != null && context.SelectedTreeNodes.All(n => n is ErrorTreeNode))\n\t\t\t\t\treturn true;\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tpublic void Execute(TextViewContext context)\n\t\t\t{\n\t\t\t\tStringBuilder builder = new StringBuilder();\n\t\t\t\tif (context.SelectedTreeNodes != null)\n\t\t\t\t{\n\t\t\t\t\tforeach (var node in context.SelectedTreeNodes.OfType<ErrorTreeNode>())\n\t\t\t\t\t{\n\t\t\t\t\t\tbuilder.AppendLine(node.Text.ToString());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tClipboard.SetText(builder.ToString());\n\t\t\t}\n\t\t}\n\t}\n\n\tsealed class ErrorTreeNode : ILSpyTreeNode\n\t{\n\t\tpublic Exception? Exception { get; }\n\n\t\tpublic override object Text { get; }\n\n\t\tpublic override object Icon => Images.Load(this, \"Images/Warning\");\n\n\t\tpublic ErrorTreeNode(Exception exception)\n\t\t\t: this(exception.Message)\n\t\t{\n\t\t\tthis.Exception = exception;\n\t\t}\n\n\t\tpublic ErrorTreeNode(string text)\n\t\t{\n\t\t\tthis.Text = text;\n\t\t}\n\n\t\tpublic override FilterResult Filter(LanguageSettings settings)\n\t\t{\n\t\t\treturn FilterResult.Match;\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\toutput.WriteLine(this.Text.ToString());\n\t\t\toutput.WriteLine();\n\t\t\tif (this.Exception != null)\n\t\t\t{\n\t\t\t\toutput.WriteLine(this.Exception.ToString());\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/TypeReferenceTreeNode.cs",
    "content": "// Copyright (c) 2023 James May\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Output;\nusing ICSharpCode.Decompiler.TypeSystem;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\t/// <summary>\n\t/// referenced type within assembly reference list.\n\t/// </summary>\n\tpublic sealed class TypeReferenceTreeNode : ILSpyTreeNode\n\t{\n\t\treadonly MetadataModule module;\n\t\treadonly TypeReferenceMetadata r;\n\t\treadonly IType resolvedType;\n\n\t\tpublic TypeReferenceTreeNode(MetadataModule module, TypeReferenceMetadata r)\n\t\t{\n\t\t\tthis.module = module ?? throw new ArgumentNullException(nameof(module));\n\t\t\tthis.r = r ?? throw new ArgumentNullException(nameof(r));\n\t\t\tthis.resolvedType = module.ResolveType(r.Handle, default);\n\n\t\t\tthis.LazyLoading = true;\n\t\t}\n\n\t\tpublic override object Text\n\t\t\t=> Language.TypeToString(resolvedType, ConversionFlags.None) + GetSuffixString(r.Handle);\n\n\t\tpublic override object NavigationText => $\"{Text} ({Properties.Resources.ReferencedTypes})\";\n\n\t\tpublic override object Icon => Images.TypeReference;\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tforeach (var typeRef in r.TypeReferences)\n\t\t\t\tthis.Children.Add(new TypeReferenceTreeNode(module, typeRef));\n\n\t\t\tforeach (var memberRef in r.MemberReferences)\n\t\t\t\tthis.Children.Add(new MemberReferenceTreeNode(module, memberRef));\n\t\t}\n\n\t\tpublic override bool ShowExpander => !r.TypeReferences.IsEmpty || !r.MemberReferences.IsEmpty;\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.WriteCommentLine(output, Language.TypeToString(resolvedType));\n\t\t\tEnsureLazyChildren();\n\t\t\tforeach (ILSpyTreeNode child in Children)\n\t\t\t{\n\t\t\t\toutput.Indent();\n\t\t\t\tchild.Decompile(language, output, options);\n\t\t\t\toutput.Unindent();\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/TreeNodes/TypeTreeNode.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Linq;\nusing System.Windows.Media;\n\nusing ICSharpCode.Decompiler;\n\nusing SRM = System.Reflection.Metadata;\n\nnamespace ICSharpCode.ILSpy.TreeNodes\n{\n\tusing ICSharpCode.Decompiler.Output;\n\tusing ICSharpCode.Decompiler.TypeSystem;\n\tusing ICSharpCode.ILSpyX;\n\n\tpublic sealed class TypeTreeNode : ILSpyTreeNode, IMemberTreeNode\n\t{\n\t\tpublic TypeTreeNode(ITypeDefinition typeDefinition, AssemblyTreeNode parentAssemblyNode)\n\t\t{\n\t\t\tthis.ParentAssemblyNode = parentAssemblyNode ?? throw new ArgumentNullException(nameof(parentAssemblyNode));\n\t\t\tthis.TypeDefinition = typeDefinition ?? throw new ArgumentNullException(nameof(typeDefinition));\n\t\t\tthis.LazyLoading = true;\n\t\t}\n\n\t\tpublic ITypeDefinition TypeDefinition { get; }\n\n\t\tpublic AssemblyTreeNode ParentAssemblyNode { get; }\n\n\t\tpublic override object Text => this.Language.TypeToString(GetTypeDefinition(), ConversionFlags.None)\n\t\t\t+ GetSuffixString(TypeDefinition.MetadataToken);\n\n\t\tpublic override object NavigationText => this.Language.TypeToString(GetTypeDefinition())\n\t\t\t+ GetSuffixString(TypeDefinition.MetadataToken);\n\n\t\tprivate ITypeDefinition GetTypeDefinition()\n\t\t{\n\t\t\treturn ((MetadataModule)ParentAssemblyNode.LoadedAssembly\n\t\t\t\t.GetMetadataFileOrNull()\n\t\t\t\t?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion)\n\t\t\t\t?.MainModule)?.GetDefinition((SRM.TypeDefinitionHandle)TypeDefinition.MetadataToken);\n\t\t}\n\n\t\tpublic override bool IsPublicAPI {\n\t\t\tget {\n\t\t\t\tswitch (GetTypeDefinition().Accessibility)\n\t\t\t\t{\n\t\t\t\t\tcase Accessibility.Public:\n\t\t\t\t\tcase Accessibility.Protected:\n\t\t\t\t\tcase Accessibility.ProtectedOrInternal:\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic override FilterResult Filter(LanguageSettings settings)\n\t\t{\n\t\t\tif (settings.ShowApiLevel == ApiVisibility.PublicOnly && !IsPublicAPI)\n\t\t\t\treturn FilterResult.Hidden;\n\t\t\tif (settings.SearchTermMatches(TypeDefinition.Name))\n\t\t\t{\n\t\t\t\tif (settings.ShowApiLevel == ApiVisibility.All || LanguageService.Language.ShowMember(TypeDefinition))\n\t\t\t\t\treturn FilterResult.Match;\n\t\t\t\telse\n\t\t\t\t\treturn FilterResult.Hidden;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn FilterResult.Recurse;\n\t\t\t}\n\t\t}\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tif (TypeDefinition.DirectBaseTypes.Any())\n\t\t\t\tthis.Children.Add(new BaseTypesTreeNode(ParentAssemblyNode.LoadedAssembly.GetMetadataFileOrNull(), TypeDefinition));\n\t\t\tif (!TypeDefinition.IsSealed)\n\t\t\t\tthis.Children.Add(new DerivedTypesTreeNode(ParentAssemblyNode.AssemblyList, TypeDefinition));\n\t\t\tforeach (var nestedType in TypeDefinition.NestedTypes.OrderBy(t => t.Name, NaturalStringComparer.Instance))\n\t\t\t{\n\t\t\t\tthis.Children.Add(new TypeTreeNode(nestedType, ParentAssemblyNode));\n\t\t\t}\n\t\t\tif (TypeDefinition.Kind == TypeKind.Enum)\n\t\t\t{\n\t\t\t\t// if the type is an enum, it's better to not sort by field name.\n\t\t\t\tforeach (var field in TypeDefinition.Fields)\n\t\t\t\t{\n\t\t\t\t\tthis.Children.Add(new FieldTreeNode(field));\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tforeach (var field in TypeDefinition.Fields.OrderBy(f => f.Name, NaturalStringComparer.Instance))\n\t\t\t\t{\n\t\t\t\t\tthis.Children.Add(new FieldTreeNode(field));\n\t\t\t\t}\n\t\t\t}\n\t\t\tforeach (var property in TypeDefinition.Properties.OrderBy(p => p.Name, NaturalStringComparer.Instance))\n\t\t\t{\n\t\t\t\tthis.Children.Add(new PropertyTreeNode(property));\n\t\t\t}\n\t\t\tforeach (var ev in TypeDefinition.Events.OrderBy(e => e.Name, NaturalStringComparer.Instance))\n\t\t\t{\n\t\t\t\tthis.Children.Add(new EventTreeNode(ev));\n\t\t\t}\n\t\t\tforeach (var method in TypeDefinition.Methods.OrderBy(m => m.Name, NaturalStringComparer.Instance))\n\t\t\t{\n\t\t\t\tif (method.MetadataToken.IsNil)\n\t\t\t\t\tcontinue;\n\t\t\t\tthis.Children.Add(new MethodTreeNode(method));\n\t\t\t}\n\t\t}\n\n\t\tpublic override bool CanExpandRecursively => true;\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tlanguage.DecompileType(GetTypeDefinition(), output, options);\n\t\t}\n\n\t\tpublic override object Icon => GetIcon(TypeDefinition);\n\n\t\tpublic static ImageSource GetIcon(ITypeDefinition type)\n\t\t{\n\t\t\treturn Images.GetIcon(GetTypeIcon(type, out bool isStatic), GetOverlayIcon(type), isStatic);\n\t\t}\n\n\t\tinternal static TypeIcon GetTypeIcon(IType type, out bool isStatic)\n\t\t{\n\t\t\tisStatic = false;\n\t\t\tswitch (type.Kind)\n\t\t\t{\n\t\t\t\tcase TypeKind.Interface:\n\t\t\t\t\treturn TypeIcon.Interface;\n\t\t\t\tcase TypeKind.Struct:\n\t\t\t\tcase TypeKind.Void:\n\t\t\t\t\treturn TypeIcon.Struct;\n\t\t\t\tcase TypeKind.Delegate:\n\t\t\t\t\treturn TypeIcon.Delegate;\n\t\t\t\tcase TypeKind.Enum:\n\t\t\t\t\treturn TypeIcon.Enum;\n\t\t\t\tdefault:\n\t\t\t\t\tisStatic = type.GetDefinition()?.IsStatic == true;\n\t\t\t\t\treturn TypeIcon.Class;\n\t\t\t}\n\t\t}\n\n\t\tstatic AccessOverlayIcon GetOverlayIcon(ITypeDefinition type)\n\t\t{\n\t\t\tswitch (type.Accessibility)\n\t\t\t{\n\t\t\t\tcase Accessibility.Public:\n\t\t\t\t\treturn AccessOverlayIcon.Public;\n\t\t\t\tcase Accessibility.Internal:\n\t\t\t\t\treturn AccessOverlayIcon.Internal;\n\t\t\t\tcase Accessibility.ProtectedAndInternal:\n\t\t\t\t\treturn AccessOverlayIcon.PrivateProtected;\n\t\t\t\tcase Accessibility.Protected:\n\t\t\t\tcase Accessibility.ProtectedOrInternal:\n\t\t\t\t\treturn AccessOverlayIcon.Protected;\n\t\t\t\tcase Accessibility.Private:\n\t\t\t\t\treturn AccessOverlayIcon.Private;\n\t\t\t\tdefault:\n\t\t\t\t\treturn AccessOverlayIcon.CompilerControlled;\n\t\t\t}\n\t\t}\n\n\t\tIEntity IMemberTreeNode.Member => TypeDefinition;\n\n\t\tpublic override string ToString()\n\t\t{\n\t\t\treturn TypeDefinition.ReflectionName;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Updates/AppUpdateService.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.ILSpy.Updates\n{\n\tinternal enum UpdateStrategy\n\t{\n\t\tNotifyOfUpdates,\n\t\t// AutoUpdate\n\t}\n\n\tinternal static class AppUpdateService\n\t{\n\t\tpublic static readonly UpdateStrategy updateStrategy = UpdateStrategy.NotifyOfUpdates;\n\n\t\tpublic static readonly Version CurrentVersion = new Version(DecompilerVersionInfo.Major + \".\" + DecompilerVersionInfo.Minor + \".\" + DecompilerVersionInfo.Build + \".\" + DecompilerVersionInfo.Revision);\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Updates/AvailableVersionInfo.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\n\nnamespace ICSharpCode.ILSpy.Updates\n{\n\tsealed class AvailableVersionInfo\n\t{\n\t\tpublic Version Version;\n\t\tpublic string DownloadUrl;\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Updates/UpdateService.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing System.Xml.Linq;\n\nnamespace ICSharpCode.ILSpy.Updates\n{\n\tinternal static class UpdateService\n\t{\n\t\tstatic readonly Uri UpdateUrl = new Uri(\"https://ilspy.net/updates.xml\");\n\t\tconst string band = \"stable\";\n\n\t\tpublic static AvailableVersionInfo LatestAvailableVersion { get; private set; }\n\n\t\tpublic static async Task<AvailableVersionInfo> GetLatestVersionAsync()\n\t\t{\n\t\t\tvar client = new HttpClient(new HttpClientHandler() {\n\t\t\t\tUseProxy = true,\n\t\t\t\tUseDefaultCredentials = true,\n\t\t\t});\n\t\t\tstring data = await client.GetStringAsync(UpdateUrl).ConfigureAwait(false);\n\n\t\t\tXDocument doc = XDocument.Load(new StringReader(data));\n\t\t\tvar bands = doc.Root.Elements(\"band\");\n\t\t\tvar currentBand = bands.FirstOrDefault(b => (string)b.Attribute(\"id\") == band) ?? bands.First();\n\t\t\tVersion version = new Version((string)currentBand.Element(\"latestVersion\"));\n\t\t\tstring url = (string)currentBand.Element(\"downloadUrl\");\n\t\t\tif (!(url.StartsWith(\"http://\", StringComparison.Ordinal) || url.StartsWith(\"https://\", StringComparison.Ordinal)))\n\t\t\t\turl = null; // don't accept non-urls\n\n\t\t\tLatestAvailableVersion = new AvailableVersionInfo { Version = version, DownloadUrl = url };\n\t\t\treturn LatestAvailableVersion;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// If automatic update checking is enabled, checks if there are any updates available.\n\t\t/// Returns the download URL if an update is available.\n\t\t/// Returns null if no update is available, or if no check was performed.\n\t\t/// </summary>\n\t\tpublic static async Task<string> CheckForUpdatesIfEnabledAsync(UpdateSettings settings)\n\t\t{\n\t\t\t// If we're in an MSIX package, updates work differently\n\t\t\tif (!settings.AutomaticUpdateCheckEnabled)\n\t\t\t\treturn null;\n\n\t\t\t// perform update check if we never did one before;\n\t\t\t// or if the last check wasn't in the past 7 days\n\t\t\tif (settings.LastSuccessfulUpdateCheck == null\n\t\t\t\t|| settings.LastSuccessfulUpdateCheck < DateTime.UtcNow.AddDays(-7)\n\t\t\t\t|| settings.LastSuccessfulUpdateCheck > DateTime.UtcNow)\n\t\t\t{\n\t\t\t\treturn await CheckForUpdateInternal(settings).ConfigureAwait(false);\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static Task<string> CheckForUpdatesAsync(UpdateSettings settings)\n\t\t{\n\t\t\treturn CheckForUpdateInternal(settings);\n\t\t}\n\n\t\tstatic async Task<string> CheckForUpdateInternal(UpdateSettings settings)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar v = await GetLatestVersionAsync().ConfigureAwait(false);\n\t\t\t\tsettings.LastSuccessfulUpdateCheck = DateTime.UtcNow;\n\t\t\t\tif (v.Version > AppUpdateService.CurrentVersion)\n\t\t\t\t\treturn v.DownloadUrl;\n\t\t\t\telse\n\t\t\t\t\treturn null;\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\t// ignore errors getting the version info\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Updates/UpdateSettings.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Xml.Linq;\n\nusing ICSharpCode.ILSpyX.Settings;\n\nusing TomsToolbox.Wpf;\n\nnamespace ICSharpCode.ILSpy.Updates\n{\n\tpublic sealed class UpdateSettings : ObservableObjectBase, ISettingsSection\n\t{\n\t\tpublic XName SectionName => \"UpdateSettings\";\n\n\t\tbool automaticUpdateCheckEnabled;\n\n\t\tpublic bool AutomaticUpdateCheckEnabled {\n\t\t\tget => automaticUpdateCheckEnabled;\n\t\t\tset => SetProperty(ref automaticUpdateCheckEnabled, value);\n\t\t}\n\n\t\tDateTime? lastSuccessfulUpdateCheck;\n\n\t\tpublic DateTime? LastSuccessfulUpdateCheck {\n\t\t\tget => lastSuccessfulUpdateCheck;\n\t\t\tset => SetProperty(ref lastSuccessfulUpdateCheck, value);\n\t\t}\n\n\t\tpublic void LoadFromXml(XElement section)\n\t\t{\n\t\t\tAutomaticUpdateCheckEnabled = (bool?)section.Element(\"AutomaticUpdateCheckEnabled\") ?? true;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tLastSuccessfulUpdateCheck = (DateTime?)section.Element(\"LastSuccessfulUpdateCheck\");\n\t\t\t}\n\t\t\tcatch (FormatException)\n\t\t\t{\n\t\t\t\t// avoid crashing on settings files invalid due to\n\t\t\t\t// https://github.com/icsharpcode/ILSpy/issues/closed/#issue/2\n\t\t\t}\n\t\t}\n\n\t\tpublic XElement SaveToXml()\n\t\t{\n\t\t\tvar section = new XElement(SectionName);\n\n\t\t\tsection.Add(new XElement(\"AutomaticUpdateCheckEnabled\", AutomaticUpdateCheckEnabled));\n\n\t\t\tif (LastSuccessfulUpdateCheck != null)\n\t\t\t{\n\t\t\t\tsection.Add(new XElement(\"LastSuccessfulUpdateCheck\", LastSuccessfulUpdateCheck));\n\t\t\t}\n\n\t\t\treturn section;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Util/GlobalUtils.cs",
    "content": "// Copyright (c) 2024 Tom Englert for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Diagnostics;\n\nnamespace ICSharpCode.ILSpy.Util\n{\n\tstatic class GlobalUtils\n\t{\n\t\tpublic static void OpenLink(string link)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tProcess.Start(new ProcessStartInfo { FileName = link, UseShellExecute = true });\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\t// Process.Start can throw several errors (not all of them documented),\n\t\t\t\t// just ignore all of them.\n\t\t\t}\n\t\t}\n\n\t\tpublic static void ExecuteCommand(string fileName, string arguments)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tProcess.Start(fileName, arguments);\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\t// Process.Start can throw several errors (not all of them documented),\n\t\t\t\t// just ignore all of them.\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Util/GraphVizGraph.cs",
    "content": "// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n#nullable enable\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Globalization;\nusing System.IO;\nusing System.Text.RegularExpressions;\n\nnamespace ICSharpCode.ILSpy.Util\n{\n#if DEBUG\n\t/// <summary>\n\t/// GraphViz graph.\n\t/// </summary>\n\tsealed class GraphVizGraph\n\t{\n\t\tList<GraphVizNode> nodes = new List<GraphVizNode>();\n\t\tList<GraphVizEdge> edges = new List<GraphVizEdge>();\n\n\t\tpublic string? rankdir;\n\t\tpublic string? Title;\n\n\t\tpublic void AddEdge(GraphVizEdge edge)\n\t\t{\n\t\t\tedges.Add(edge);\n\t\t}\n\n\t\tpublic void AddNode(GraphVizNode node)\n\t\t{\n\t\t\tnodes.Add(node);\n\t\t}\n\n\t\tpublic void Save(string fileName)\n\t\t{\n\t\t\tusing (StreamWriter writer = new StreamWriter(fileName))\n\t\t\t\tSave(writer);\n\t\t}\n\n\t\tpublic void Show()\n\t\t{\n\t\t\tShow(null);\n\t\t}\n\n\t\tpublic void Show(string? name)\n\t\t{\n\t\t\tif (name == null)\n\t\t\t\tname = Title;\n\t\t\tif (name != null)\n\t\t\t\tforeach (char c in Path.GetInvalidFileNameChars())\n\t\t\t\t\tname = name.Replace(c, '-');\n\t\t\tstring fileName = name != null ? Path.Combine(Path.GetTempPath(), name) : Path.GetTempFileName();\n\t\t\tSave(fileName + \".gv\");\n\t\t\tProcess.Start(\"dot\", \"\\\"\" + fileName + \".gv\\\" -Tpng -o \\\"\" + fileName + \".png\\\"\").WaitForExit();\n\t\t\tProcess.Start(fileName + \".png\");\n\t\t}\n\n\t\tstatic string Escape(string text)\n\t\t{\n\t\t\tif (Regex.IsMatch(text, @\"^[\\w\\d]+$\"))\n\t\t\t{\n\t\t\t\treturn text;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn \"\\\"\" + text.Replace(\"\\\\\", \"\\\\\\\\\").Replace(\"\\r\", \"\").Replace(\"\\n\", \"\\\\n\").Replace(\"\\\"\", \"\\\\\\\"\") + \"\\\"\";\n\t\t\t}\n\t\t}\n\n\t\tstatic void WriteGraphAttribute(TextWriter writer, string name, string? value)\n\t\t{\n\t\t\tif (value != null)\n\t\t\t\twriter.WriteLine(\"{0}={1};\", name, Escape(value));\n\t\t}\n\n\t\tinternal static void WriteAttribute(TextWriter writer, string name, double? value, ref bool isFirst)\n\t\t{\n\t\t\tif (value != null)\n\t\t\t{\n\t\t\t\tWriteAttribute(writer, name, value.Value.ToString(CultureInfo.InvariantCulture), ref isFirst);\n\t\t\t}\n\t\t}\n\n\t\tinternal static void WriteAttribute(TextWriter writer, string name, bool? value, ref bool isFirst)\n\t\t{\n\t\t\tif (value != null)\n\t\t\t{\n\t\t\t\tWriteAttribute(writer, name, value.Value ? \"true\" : \"false\", ref isFirst);\n\t\t\t}\n\t\t}\n\n\t\tinternal static void WriteAttribute(TextWriter writer, string name, string? value, ref bool isFirst)\n\t\t{\n\t\t\tif (value != null)\n\t\t\t{\n\t\t\t\tif (isFirst)\n\t\t\t\t\tisFirst = false;\n\t\t\t\telse\n\t\t\t\t\twriter.Write(',');\n\t\t\t\twriter.Write(\"{0}={1}\", name, Escape(value));\n\t\t\t}\n\t\t}\n\n\t\tpublic void Save(TextWriter writer)\n\t\t{\n\t\t\tif (writer == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(writer));\n\t\t\twriter.WriteLine(\"digraph G {\");\n\t\t\twriter.WriteLine(\"node [fontsize = 16];\");\n\t\t\tWriteGraphAttribute(writer, \"rankdir\", rankdir);\n\t\t\tforeach (GraphVizNode node in nodes)\n\t\t\t{\n\t\t\t\tnode.Save(writer);\n\t\t\t}\n\t\t\tforeach (GraphVizEdge edge in edges)\n\t\t\t{\n\t\t\t\tedge.Save(writer);\n\t\t\t}\n\t\t\twriter.WriteLine(\"}\");\n\t\t}\n\t}\n\n\tsealed class GraphVizEdge\n\t{\n\t\tpublic readonly string Source, Target;\n\n\t\t/// <summary>edge stroke color</summary>\n\t\tpublic string? color;\n\t\t/// <summary>use edge to affect node ranking</summary>\n\t\tpublic bool? constraint;\n\n\t\tpublic string? label;\n\n\t\tpublic string? style;\n\n\t\t/// <summary>point size of label</summary>\n\t\tpublic int? fontsize;\n\n\t\tpublic GraphVizEdge(string source, string target)\n\t\t{\n\t\t\tif (source == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(source));\n\t\t\tif (target == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(target));\n\t\t\tthis.Source = source;\n\t\t\tthis.Target = target;\n\t\t}\n\n\t\tpublic GraphVizEdge(int source, int target)\n\t\t{\n\t\t\tthis.Source = source.ToString(CultureInfo.InvariantCulture);\n\t\t\tthis.Target = target.ToString(CultureInfo.InvariantCulture);\n\t\t}\n\n\t\tpublic void Save(TextWriter writer)\n\t\t{\n\t\t\twriter.Write(\"{0} -> {1} [\", Source, Target);\n\t\t\tbool isFirst = true;\n\t\t\tGraphVizGraph.WriteAttribute(writer, \"label\", label, ref isFirst);\n\t\t\tGraphVizGraph.WriteAttribute(writer, \"style\", style, ref isFirst);\n\t\t\tGraphVizGraph.WriteAttribute(writer, \"fontsize\", fontsize, ref isFirst);\n\t\t\tGraphVizGraph.WriteAttribute(writer, \"color\", color, ref isFirst);\n\t\t\tGraphVizGraph.WriteAttribute(writer, \"constraint\", constraint, ref isFirst);\n\t\t\twriter.WriteLine(\"];\");\n\t\t}\n\t}\n\n\tsealed class GraphVizNode\n\t{\n\t\tpublic readonly string ID;\n\t\tpublic string? label;\n\n\t\tpublic string? labelloc;\n\n\t\t/// <summary>point size of label</summary>\n\t\tpublic int? fontsize;\n\n\t\t/// <summary>minimum height in inches</summary>\n\t\tpublic double? height;\n\n\t\t/// <summary>space around label</summary>\n\t\tpublic string? margin;\n\n\t\t/// <summary>node shape</summary>\n\t\tpublic string? shape;\n\n\t\tpublic GraphVizNode(string id)\n\t\t{\n\t\t\tif (id == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(id));\n\t\t\tthis.ID = id;\n\t\t}\n\n\t\tpublic GraphVizNode(int id)\n\t\t{\n\t\t\tthis.ID = id.ToString(CultureInfo.InvariantCulture);\n\t\t}\n\n\t\tpublic void Save(TextWriter writer)\n\t\t{\n\t\t\twriter.Write(ID);\n\t\t\twriter.Write(\" [\");\n\t\t\tbool isFirst = true;\n\t\t\tGraphVizGraph.WriteAttribute(writer, \"label\", label, ref isFirst);\n\t\t\tGraphVizGraph.WriteAttribute(writer, \"labelloc\", labelloc, ref isFirst);\n\t\t\tGraphVizGraph.WriteAttribute(writer, \"fontsize\", fontsize, ref isFirst);\n\t\t\tGraphVizGraph.WriteAttribute(writer, \"margin\", margin, ref isFirst);\n\t\t\tGraphVizGraph.WriteAttribute(writer, \"shape\", shape, ref isFirst);\n\t\t\twriter.WriteLine(\"];\");\n\t\t}\n\t}\n#endif\n}\n"
  },
  {
    "path": "ILSpy/Util/MessageBus.cs",
    "content": "// Copyright (c) 2024 Tom Englert for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Specialized;\nusing System.ComponentModel;\nusing System.Windows.Navigation;\n\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.ViewModels;\n\nusing TomsToolbox.Essentials;\n\n#nullable enable\n\nnamespace ICSharpCode.ILSpy.Util\n{\n\tpublic static class MessageBus\n\t{\n\t\tpublic static void Send<T>(object? sender, T e)\n\t\t\twhere T : EventArgs\n\t\t{\n\t\t\tMessageBus<T>.Send(sender, e);\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Simple, minimalistic message bus.\n\t/// </summary>\n\t/// <typeparam name=\"T\">The type of the message event arguments</typeparam>\n\tpublic static class MessageBus<T>\n\t\twhere T : EventArgs\n\t{\n\t\tprivate static readonly WeakEventSource<T> subscriptions = new();\n\n\t\tpublic static event EventHandler<T> Subscribers {\n\t\t\tadd => subscriptions.Subscribe(value);\n\t\t\tremove => subscriptions.Unsubscribe(value);\n\t\t}\n\n\t\tpublic static void Send(object? sender, T e)\n\t\t{\n\t\t\tsubscriptions.Raise(sender!, e);\n\t\t}\n\t}\n\n\tpublic abstract class WrappedEventArgs<T> : EventArgs\n\t{\n\t\tprivate readonly T inner;\n\n\t\tprotected WrappedEventArgs(T inner)\n\t\t{\n\t\t\tthis.inner = inner;\n\t\t}\n\n\t\tpublic static implicit operator T(WrappedEventArgs<T> outer)\n\t\t{\n\t\t\treturn outer.inner;\n\t\t}\n\t}\n\n\tpublic class CurrentAssemblyListChangedEventArgs(NotifyCollectionChangedEventArgs e) : WrappedEventArgs<NotifyCollectionChangedEventArgs>(e);\n\tpublic class TabPagesCollectionChangedEventArgs(NotifyCollectionChangedEventArgs e) : WrappedEventArgs<NotifyCollectionChangedEventArgs>(e);\n\n\tpublic class SettingsChangedEventArgs(PropertyChangedEventArgs e) : WrappedEventArgs<PropertyChangedEventArgs>(e);\n\n\tpublic class NavigateToReferenceEventArgs(object reference, object? source = null, bool inNewTabPage = false) : EventArgs\n\t{\n\t\tpublic object Reference { get; } = reference;\n\t\tpublic object? Source { get; } = source;\n\t\tpublic bool InNewTabPage { get; } = inNewTabPage;\n\t}\n\n\tpublic class NavigateToEventArgs(RequestNavigateEventArgs request, bool inNewTabPage = false) : EventArgs\n\t{\n\t\tpublic RequestNavigateEventArgs Request { get; } = request;\n\n\t\tpublic bool InNewTabPage { get; } = inNewTabPage;\n\t}\n\n\tpublic class AssemblyTreeSelectionChangedEventArgs() : EventArgs;\n\n\tpublic class ApplySessionSettingsEventArgs(SessionSettings sessionSettings) : EventArgs\n\t{\n\t\tpublic SessionSettings SessionSettings { get; } = sessionSettings;\n\t}\n\n\tpublic class MainWindowLoadedEventArgs() : EventArgs;\n\n\tpublic class ActiveTabPageChangedEventArgs(ViewState? viewState) : EventArgs\n\t{\n\t\tpublic ViewState? ViewState { get; } = viewState;\n\t}\n\n\tpublic class ResetLayoutEventArgs : EventArgs;\n\n\tpublic class ShowAboutPageEventArgs(TabPageModel tabPage) : EventArgs\n\t{\n\t\tpublic TabPageModel TabPage { get; } = tabPage;\n\t}\n\n\tpublic class ShowSearchPageEventArgs(string? searchTerm) : EventArgs\n\t{\n\t\tpublic string? SearchTerm { get; } = searchTerm;\n\t}\n\n\tpublic class CheckIfUpdateAvailableEventArgs(bool notify = false) : EventArgs\n\t{\n\t\tpublic bool Notify { get; } = notify;\n\t}\n}"
  },
  {
    "path": "ILSpy/Util/ResourceHelper.cs",
    "content": "// Copyright (c) 2024 Tom Englert for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nnamespace ICSharpCode.ILSpy.Util\n{\n\tinternal static class ResourceHelper\n\t{\n\t\tinternal static string GetString(string key)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty(key))\n\t\t\t\treturn null;\n\n\t\t\tstring value = Properties.Resources.ResourceManager.GetString(key);\n\n\t\t\treturn !string.IsNullOrEmpty(value) ? value : key;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Util/SettingsService.cs",
    "content": "// Copyright (c) 2024 Tom Englert for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.ComponentModel;\n\nusing ICSharpCode.ILSpy.Options;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.Settings;\n\nusing DecompilerSettings = ICSharpCode.ILSpyX.Settings.DecompilerSettings;\n\n#nullable enable\n\nnamespace ICSharpCode.ILSpy.Util\n{\n\tpublic class SettingsSnapshot(SettingsService parent, ISettingsProvider spySettings) : SettingsServiceBase(spySettings)\n\t{\n\t\tpublic void Save()\n\t\t{\n\t\t\tSpySettings.Update(root => {\n\t\t\t\tforeach (var section in sections.Values)\n\t\t\t\t{\n\t\t\t\t\tSaveSection(section, root);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tparent.Reload();\n\t\t}\n\t}\n\n\tpublic class SettingsService() : SettingsServiceBase(LoadSettings())\n\t{\n\t\tpublic SessionSettings SessionSettings => GetSettings<SessionSettings>();\n\n\t\tpublic DecompilerSettings DecompilerSettings => GetSettings<DecompilerSettings>();\n\n\t\tpublic DisplaySettings DisplaySettings => GetSettings<DisplaySettings>();\n\n\t\tpublic MiscSettings MiscSettings => GetSettings<MiscSettings>();\n\n\t\tprivate AssemblyListManager? assemblyListManager;\n\t\tpublic AssemblyListManager AssemblyListManager => assemblyListManager ??= new(SpySettings) {\n\t\t\tApplyWinRTProjections = DecompilerSettings.ApplyWindowsRuntimeProjections,\n\t\t\tUseDebugSymbols = DecompilerSettings.UseDebugSymbols\n\t\t};\n\n\t\tpublic AssemblyList LoadInitialAssemblyList()\n\t\t{\n\t\t\tvar loadPreviousAssemblies = MiscSettings.LoadPreviousAssemblies;\n\n\t\t\tif (loadPreviousAssemblies)\n\t\t\t{\n\t\t\t\treturn AssemblyListManager.LoadList(SessionSettings.ActiveAssemblyList);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tAssemblyListManager.ClearAll();\n\t\t\t\treturn AssemblyListManager.CreateList(AssemblyListManager.DefaultListName);\n\t\t\t}\n\t\t}\n\n\t\tpublic AssemblyList CreateEmptyAssemblyList()\n\t\t{\n\t\t\treturn AssemblyListManager.CreateList(string.Empty);\n\t\t}\n\n\t\tprivate bool reloading;\n\n\t\tpublic void Reload()\n\t\t{\n\t\t\treloading = true;\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tSpySettings = ILSpySettings.Load();\n\n\t\t\t\tforeach (var section in sections.Values)\n\t\t\t\t{\n\t\t\t\t\tvar element = SpySettings[section.SectionName];\n\n\t\t\t\t\tsection.LoadFromXml(element);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\treloading = false;\n\t\t\t}\n\t\t}\n\n\t\tpublic SettingsSnapshot CreateSnapshot()\n\t\t{\n\t\t\treturn new(this, SpySettings);\n\t\t}\n\n\t\tprotected override void Section_PropertyChanged(object? sender, PropertyChangedEventArgs e)\n\t\t{\n\t\t\tbase.Section_PropertyChanged(sender, e);\n\n\t\t\tif (!reloading)\n\t\t\t{\n\t\t\t\tvar section = (sender as IChildSettings)?.Parent ?? sender as ISettingsSection;\n\n\t\t\t\tif (section != null)\n\t\t\t\t{\n\t\t\t\t\tSpySettings.Update(root => {\n\t\t\t\t\t\tSaveSection(section, root);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (sender is DecompilerSettings decompilerSettings && assemblyListManager != null)\n\t\t\t{\n\t\t\t\tassemblyListManager.ApplyWinRTProjections = decompilerSettings.ApplyWindowsRuntimeProjections;\n\t\t\t\tassemblyListManager.UseDebugSymbols = decompilerSettings.UseDebugSymbols;\n\t\t\t}\n\n\t\t\tMessageBus.Send(sender, new SettingsChangedEventArgs(e));\n\t\t}\n\n\t\tprivate static ILSpySettings LoadSettings()\n\t\t{\n\t\t\tILSpySettings.SettingsFilePathProvider = new ILSpySettingsFilePathProvider();\n\t\t\treturn ILSpySettings.Load();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Util/ShellHelper.cs",
    "content": "// Copyright (c) 2025 sonyps5201314\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Runtime.InteropServices;\n\n#pragma warning disable CA1060 // Move pinvokes to native methods class\n\nnamespace ICSharpCode.ILSpy.Util\n{\n\tstatic class ShellHelper\n\t{\n\t\t[DllImport(\"shell32.dll\", CharSet = CharSet.Unicode)]\n\t\tstatic extern int SHParseDisplayName([MarshalAs(UnmanagedType.LPWStr)] string pszName, IntPtr pbc, out IntPtr ppidl, uint sfgaoIn, out uint psfgaoOut);\n\n\t\t[DllImport(\"shell32.dll\")]\n\t\tstatic extern int SHOpenFolderAndSelectItems(IntPtr pidlFolder, uint cidl, [MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl, uint dwFlags);\n\n\t\t[DllImport(\"shell32.dll\")]\n\t\tstatic extern IntPtr ILFindLastID(IntPtr pidl);\n\n\t\t[DllImport(\"ole32.dll\")]\n\t\tstatic extern void CoTaskMemFree(IntPtr pv);\n\n\t\tpublic static void OpenFolder(string folderPath)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tProcess.Start(new ProcessStartInfo { FileName = folderPath, UseShellExecute = true });\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t\t// Process.Start can throw several errors (not all of them documented),\n\t\t\t\t// just ignore all of them.\n\t\t\t}\n\t\t}\n\n\t\tpublic static void OpenFolderAndSelectItem(string path)\n\t\t{\n\t\t\t// Reuse the multi-item implementation for single item selection to avoid duplication.\n\t\t\tif (string.IsNullOrEmpty(path))\n\t\t\t\treturn;\n\t\t\tif (Directory.Exists(path))\n\t\t\t{\n\t\t\t\tOpenFolder(path);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!File.Exists(path))\n\t\t\t\treturn;\n\n\t\t\tOpenFolderAndSelectItems(path);\n\t\t}\n\n\t\tpublic static void OpenFolderAndSelectItems(params IEnumerable<string> paths)\n\t\t{\n\t\t\tif (paths == null)\n\t\t\t\treturn;\n\t\t\t// Group by containing folder\n\t\t\tvar files = paths.Distinct(StringComparer.OrdinalIgnoreCase).Where(p => !string.IsNullOrEmpty(p) && File.Exists(p)).ToList();\n\t\t\tif (files.Count == 0)\n\t\t\t\treturn;\n\n\t\t\tvar itemPidlAllocs = new List<IntPtr>();\n\t\t\tvar relativePidls = new List<IntPtr>();\n\n\t\t\tforeach (var group in files.GroupBy(Path.GetDirectoryName))\n\t\t\t{\n\t\t\t\tstring folder = group.Key;\n\t\t\t\tif (string.IsNullOrEmpty(folder) || !Directory.Exists(folder))\n\t\t\t\t\tcontinue;\n\n\t\t\t\tIntPtr folderPidl = IntPtr.Zero;\n\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tint hrFolder = SHParseDisplayName(folder, IntPtr.Zero, out folderPidl, 0, out uint attrs);\n\t\t\t\t\tMarshal.ThrowExceptionForHR(hrFolder);\n\n\t\t\t\t\tforeach (var file in group)\n\t\t\t\t\t{\n\t\t\t\t\t\tint hrItem = SHParseDisplayName(file, IntPtr.Zero, out var itemPidl, 0, out attrs);\n\t\t\t\t\t\tif (hrItem == 0 && itemPidl != IntPtr.Zero)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tIntPtr relative = ILFindLastID(itemPidl);\n\t\t\t\t\t\t\tif (relative != IntPtr.Zero)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\trelativePidls.Add(relative);\n\t\t\t\t\t\t\t\titemPidlAllocs.Add(itemPidl);\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (itemPidl != IntPtr.Zero)\n\t\t\t\t\t\t\tCoTaskMemFree(itemPidl);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (relativePidls.Count > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tint hr = SHOpenFolderAndSelectItems(folderPidl, (uint)relativePidls.Count, relativePidls.ToArray(), 0);\n\t\t\t\t\t\tMarshal.ThrowExceptionForHR(hr);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// nothing to select - open folder\n\t\t\t\t\t\tOpenFolder(folder);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch (Exception ex) when (ex is COMException or Win32Exception)\n\t\t\t\t{\n\t\t\t\t\t// fall back to Process.Start\n\t\t\t\t\tOpenFolder(folder);\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tforeach (var p in itemPidlAllocs)\n\t\t\t\t\t\tCoTaskMemFree(p);\n\t\t\t\t\tif (folderPidl != IntPtr.Zero)\n\t\t\t\t\t\tCoTaskMemFree(folderPidl);\n\n\t\t\t\t\titemPidlAllocs.Clear();\n\t\t\t\t\trelativePidls.Clear();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/ViewModels/CompareViewModel.cs",
    "content": "// Copyright (c) 2025 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Text.Json;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Input;\nusing System.Windows.Media;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.CSharp.OutputVisitor;\nusing ICSharpCode.Decompiler.Util;\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.Views;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;\n\n#nullable enable\n\nnamespace ICSharpCode.ILSpy.ViewModels\n{\n\tusing ICSharpCode.Decompiler.Output;\n\tusing ICSharpCode.Decompiler.TypeSystem;\n\n\tusing TomsToolbox.Wpf;\n\n\tclass CompareViewModel : ObservableObjectBase\n\t{\n\t\tprivate readonly TabPageModel tabPage;\n\t\tprivate readonly AssemblyTreeModel assemblyTreeModel;\n\t\tprivate LoadedAssembly leftAssembly;\n\t\tprivate LoadedAssembly rightAssembly;\n\t\tprivate ComparisonEntryTreeNode root;\n\t\tprivate bool updating = false;\n\t\tprivate bool showIdentical;\n\n\t\tpublic CompareViewModel(TabPageModel tabPage, AssemblyTreeModel assemblyTreeModel, LoadedAssembly left, LoadedAssembly right)\n\t\t{\n\t\t\tthis.tabPage = tabPage;\n\t\t\tthis.assemblyTreeModel = assemblyTreeModel;\n\t\t\tleftAssembly = left;\n\t\t\trightAssembly = right;\n\n\t\t\tvar leftTree = CreateEntityTree(left.GetTypeSystemOrNull()!);\n\t\t\tvar rightTree = CreateEntityTree(right.GetTypeSystemOrNull()!);\n\n\t\t\tthis.root = new ComparisonEntryTreeNode(MergeTrees(leftTree.Item2, rightTree.Item2), this);\n\n\t\t\tthis.SwapAssembliesCommand = new DelegateCommand(OnSwapAssemblies);\n\t\t\tthis.ExpandAllCommand = new DelegateCommand(OnExpandAll);\n\t\t\tthis.CopyToClipboardAsJSONCommand = new DelegateCommand(OnCopyToClipboardAsJSON);\n\n\t\t\tthis.PropertyChanged += CompareViewModel_PropertyChanged;\n\t\t}\n\n\t\tprivate void CompareViewModel_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)\n\t\t{\n\t\t\tswitch (e.PropertyName)\n\t\t\t{\n\t\t\t\tcase nameof(LeftAssembly):\n\t\t\t\tcase nameof(RightAssembly):\n\t\t\t\t\tif (updating)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tupdating = true;\n\t\t\t\t\tvar view = tabPage.Content;\n\t\t\t\t\ttabPage.ShowTextView(t => t.RunWithCancellation(token => Task.Run(DoCompare, token), $\"Comparing {LeftAssembly.Text} - {RightAssembly.Text}\").Then(_ => {\n\t\t\t\t\t\ttabPage.Title = $\"Compare {LeftAssembly.Text} - {RightAssembly.Text}\";\n\t\t\t\t\t\ttabPage.SupportsLanguageSwitching = false;\n\t\t\t\t\t\ttabPage.FrozenContent = true;\n\t\t\t\t\t\ttabPage.Content = view;\n\t\t\t\t\t\tupdating = false;\n\t\t\t\t\t}).HandleExceptions());\n\n\t\t\t\t\tTask<bool> DoCompare()\n\t\t\t\t\t{\n\t\t\t\t\t\tvar leftTree = CreateEntityTree(leftAssembly.GetTypeSystemOrNull()!);\n\t\t\t\t\t\tvar rightTree = CreateEntityTree(rightAssembly.GetTypeSystemOrNull()!);\n\n\t\t\t\t\t\tthis.RootEntry = new ComparisonEntryTreeNode(MergeTrees(leftTree.Item2, rightTree.Item2), this);\n\t\t\t\t\t\treturn Task.FromResult(true);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase nameof(ShowIdentical):\n\t\t\t\t\tthis.RootEntry.EnsureChildrenFiltered();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic LoadedAssembly LeftAssembly {\n\t\t\tget => leftAssembly;\n\t\t\tset {\n\t\t\t\tif (leftAssembly != value)\n\t\t\t\t{\n\t\t\t\t\tleftAssembly = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic LoadedAssembly RightAssembly {\n\t\t\tget => rightAssembly;\n\t\t\tset {\n\t\t\t\tif (rightAssembly != value)\n\t\t\t\t{\n\t\t\t\t\trightAssembly = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic ComparisonEntryTreeNode RootEntry {\n\t\t\tget => root;\n\t\t\tset {\n\t\t\t\tif (root != value)\n\t\t\t\t{\n\t\t\t\t\troot = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic bool ShowIdentical {\n\t\t\tget => showIdentical;\n\t\t\tset {\n\t\t\t\tif (showIdentical != value)\n\t\t\t\t{\n\t\t\t\t\tshowIdentical = value;\n\t\t\t\t\tOnPropertyChanged();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic ICommand SwapAssembliesCommand { get; set; }\n\t\tpublic ICommand ExpandAllCommand { get; set; }\n\t\tpublic ICommand CopyToClipboardAsJSONCommand { get; set; }\n\n\t\tvoid OnSwapAssemblies()\n\t\t{\n\t\t\tvar left = this.leftAssembly;\n\t\t\tthis.leftAssembly = this.rightAssembly;\n\t\t\tthis.rightAssembly = left;\n\t\t\tOnPropertyChanged(nameof(LeftAssembly));\n\t\t\tOnPropertyChanged(nameof(RightAssembly));\n\t\t}\n\n\t\tvoid OnExpandAll()\n\t\t{\n\t\t\tforeach (var node in RootEntry.DescendantsAndSelf())\n\t\t\t{\n\t\t\t\tnode.IsExpanded = true;\n\t\t\t}\n\t\t}\n\n\t\tvoid OnCopyToClipboardAsJSON()\n\t\t{\n\t\t\tvar options = new JsonSerializerOptions {\n\t\t\t\tWriteIndented = true\n\t\t\t};\n\n\t\t\tvar jsonEntry = ConvertToJson(this.root.Entry);\n\t\t\tvar json = JsonSerializer.Serialize(jsonEntry, options);\n\t\t\tClipboard.SetText(json);\n\t\t}\n\n\t\tprivate object ConvertToJson(Entry entry)\n\t\t{\n\t\t\tList<Entry> changedTypes = new();\n\t\t\tList<Entry> addedTypes = new();\n\t\t\tList<Entry> removedTypes = new();\n\n\t\t\tforeach (var item in TreeTraversal.PreOrder(entry, entry => entry.Children))\n\t\t\t{\n\t\t\t\tif (item.Entity is ITypeDefinition)\n\t\t\t\t{\n\t\t\t\t\tswitch (item.RecursiveKind)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase DiffKind.Add:\n\t\t\t\t\t\t\taddedTypes.Add(item);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DiffKind.Remove:\n\t\t\t\t\t\t\tremovedTypes.Add(item);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DiffKind.Update:\n\t\t\t\t\t\t\tchangedTypes.Add(item);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar result = new {\n\t\t\t\tleft = LeftAssembly.FileName.Replace('\\\\', '/'),\n\t\t\t\tright = RightAssembly.FileName.Replace('\\\\', '/'),\n\t\t\t\tchangedTypes = changedTypes.SelectArray(t => new { typeName = ((ITypeDefinition)t.Entity).FullName, changes = GetChanges(t.Children) }),\n\t\t\t\taddedTypes = addedTypes.SelectArray(t => new { typeName = ((ITypeDefinition)t.Entity).FullName, changes = GetChanges(t.Children) }),\n\t\t\t\tremovedTypes = removedTypes.SelectArray(t => new { typeName = ((ITypeDefinition)t.Entity).FullName, changes = GetChanges(t.Children) })\n\t\t\t};\n\t\t\treturn result;\n\n\t\t\tstring? GetEntityText(ISymbol? symbol) => symbol switch {\n\t\t\t\tITypeDefinition t => this.assemblyTreeModel.CurrentLanguage.TypeToString(t),\n\t\t\t\tIEntity m => this.assemblyTreeModel.CurrentLanguage.EntityToString(m, ConversionFlags.None),\n\t\t\t\tINamespace n => n.FullName,\n\t\t\t\tIModule m => m.FullAssemblyName,\n\t\t\t\t_ => null,\n\t\t\t};\n\n\t\t\tIEnumerable<object> GetChanges(List<Entry>? entries)\n\t\t\t{\n\t\t\t\tif (entries == null)\n\t\t\t\t\tyield break;\n\t\t\t\tforeach (var item in entries)\n\t\t\t\t{\n\t\t\t\t\tif (item.Kind is not (DiffKind.Add or DiffKind.Remove or DiffKind.Update))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tyield return new {\n\t\t\t\t\t\tname = GetEntityText(item.Entity),\n\t\t\t\t\t\toperation = item.Kind switch {\n\t\t\t\t\t\t\tDiffKind.Add => \"added\",\n\t\t\t\t\t\t\tDiffKind.Remove => \"removed\",\n\t\t\t\t\t\t\tDiffKind.Update => \"changed\",\n\t\t\t\t\t\t\t_ => throw new InvalidOperationException($\"Unexpected DiffKind: {item.Kind}\"),\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tEntry MergeTrees(Entry a, Entry b)\n\t\t{\n\t\t\tvar m = new Entry() {\n\t\t\t\tEntity = a.Entity,\n\t\t\t\tOtherEntity = b.Entity,\n\t\t\t\tSignature = a.Signature,\n\t\t\t};\n\n\t\t\tif (a.Children?.Count > 0 && b.Children?.Count > 0)\n\t\t\t{\n\t\t\t\tvar diff = CalculateDiff(a.Children, b.Children);\n\t\t\t\tm.Children ??= new();\n\n\t\t\t\tforeach (var (left, right) in diff)\n\t\t\t\t{\n\t\t\t\t\tif (left != null && right != null)\n\t\t\t\t\t\tm.Children.Add(MergeTrees(left, right));\n\t\t\t\t\telse if (left != null)\n\t\t\t\t\t\tm.Children.Add(left);\n\t\t\t\t\telse if (right != null)\n\t\t\t\t\t\tm.Children.Add(right);\n\t\t\t\t\telse\n\t\t\t\t\t\tDebug.Fail(\"wh00t?\");\n\t\t\t\t\tm.Children[^1].Parent = m;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (a.Children?.Count > 0)\n\t\t\t{\n\t\t\t\tm.Children ??= new();\n\t\t\t\tforeach (var child in a.Children)\n\t\t\t\t{\n\t\t\t\t\tchild.Parent = m;\n\t\t\t\t\tm.Children.Add(child);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (b.Children?.Count > 0)\n\t\t\t{\n\t\t\t\tm.Children ??= new();\n\t\t\t\tforeach (var child in b.Children)\n\t\t\t\t{\n\t\t\t\t\tchild.Parent = m;\n\t\t\t\t\tm.Children.Add(child);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn m;\n\t\t}\n\n\t\t(List<Entry>, Entry) CreateEntityTree(ICompilation typeSystem)\n\t\t{\n\t\t\tvar module = (MetadataModule)typeSystem.MainModule!;\n\t\t\tvar metadata = module.MetadataFile.Metadata;\n\t\t\tvar ambience = new CSharpAmbience();\n\t\t\tambience.ConversionFlags = ConversionFlags.All & ~ConversionFlags.ShowDeclaringType;\n\n\t\t\tList<Entry> results = new();\n\t\t\tDictionary<TypeDefinitionHandle, Entry> typeEntries = new();\n\t\t\tDictionary<string, Entry> namespaceEntries = new(StringComparer.Ordinal);\n\n\t\t\tEntry root = new Entry { Entity = module, Signature = module.FullAssemblyName };\n\n\t\t\t// typeEntries need a different signature: must include list of base types\n\n\t\t\tEntry? TryCreateEntry(IEntity entity)\n\t\t\t{\n\t\t\t\tif (entity.EffectiveAccessibility() != Accessibility.Public)\n\t\t\t\t\treturn null;\n\n\t\t\t\tEntry? parent = null;\n\n\t\t\t\tif (entity.DeclaringTypeDefinition != null\n\t\t\t\t\t&& !typeEntries.TryGetValue((TypeDefinitionHandle)entity.DeclaringTypeDefinition.MetadataToken, out parent))\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tvar entry = new Entry {\n\t\t\t\t\tSignature = ambience.ConvertSymbol(entity),\n\t\t\t\t\tEntity = entity,\n\t\t\t\t\tParent = parent,\n\t\t\t\t};\n\n\t\t\t\tif (parent != null)\n\t\t\t\t{\n\t\t\t\t\tparent.Children ??= new();\n\t\t\t\t\tparent.Children.Add(entry);\n\t\t\t\t}\n\n\t\t\t\treturn entry;\n\t\t\t}\n\n\t\t\tforeach (var typeDefHandle in metadata.TypeDefinitions)\n\t\t\t{\n\t\t\t\tvar typeDef = module.GetDefinition(typeDefHandle);\n\n\t\t\t\tif (typeDef.EffectiveAccessibility() != Accessibility.Public)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tvar entry = typeEntries[typeDefHandle] = new Entry {\n\t\t\t\t\tSignature = ambience.ConvertSymbol(typeDef),\n\t\t\t\t\tEntity = typeDef\n\t\t\t\t};\n\n\t\t\t\tif (typeDef.DeclaringType == null)\n\t\t\t\t{\n\t\t\t\t\tif (!namespaceEntries.TryGetValue(typeDef.Namespace, out var nsEntry))\n\t\t\t\t\t{\n\t\t\t\t\t\tnamespaceEntries[typeDef.Namespace] = nsEntry = new Entry { Parent = root, Signature = typeDef.Namespace, Entity = ResolveNamespace(typeDef.Namespace, typeDef.ParentModule!)! };\n\t\t\t\t\t\troot.Children ??= new();\n\t\t\t\t\t\troot.Children.Add(nsEntry);\n\t\t\t\t\t}\n\n\t\t\t\t\tentry.Parent = nsEntry;\n\t\t\t\t\tnsEntry.Children ??= new();\n\t\t\t\t\tnsEntry.Children.Add(entry);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach (var fieldHandle in metadata.FieldDefinitions)\n\t\t\t{\n\t\t\t\tvar fieldDef = module.GetDefinition(fieldHandle);\n\t\t\t\tvar entry = TryCreateEntry(fieldDef);\n\n\t\t\t\tif (entry != null)\n\t\t\t\t\tresults.Add(entry);\n\t\t\t}\n\n\t\t\tforeach (var eventHandle in metadata.EventDefinitions)\n\t\t\t{\n\t\t\t\tvar eventDef = module.GetDefinition(eventHandle);\n\t\t\t\tvar entry = TryCreateEntry(eventDef);\n\n\t\t\t\tif (entry != null)\n\t\t\t\t\tresults.Add(entry);\n\t\t\t}\n\n\t\t\tforeach (var propertyHandle in metadata.PropertyDefinitions)\n\t\t\t{\n\t\t\t\tvar propertyDef = module.GetDefinition(propertyHandle);\n\t\t\t\tvar entry = TryCreateEntry(propertyDef);\n\n\t\t\t\tif (entry != null)\n\t\t\t\t\tresults.Add(entry);\n\t\t\t}\n\n\t\t\tforeach (var methodHandle in metadata.MethodDefinitions)\n\t\t\t{\n\t\t\t\tvar methodDef = module.GetDefinition(methodHandle);\n\n\t\t\t\tif (methodDef.AccessorOwner != null)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tvar entry = TryCreateEntry(methodDef);\n\n\t\t\t\tif (entry != null)\n\t\t\t\t\tresults.Add(entry);\n\t\t\t}\n\n\t\t\treturn (results, root);\n\n\t\t\tINamespace? ResolveNamespace(string namespaceName, IModule module)\n\t\t\t{\n\t\t\t\tINamespace current = module.RootNamespace;\n\t\t\t\tstring[] parts = namespaceName.Split('.');\n\n\t\t\t\tfor (int i = 0; i < parts.Length; i++)\n\t\t\t\t{\n\t\t\t\t\tif (i == 0 && string.IsNullOrEmpty(parts[i]))\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tvar next = current.GetChildNamespace(parts[i]);\n\t\t\t\t\tif (next != null)\n\t\t\t\t\t\tcurrent = next;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\treturn current;\n\t\t\t}\n\t\t}\n\n\t\tList<(Entry? Left, Entry? Right)> CalculateDiff(List<Entry> left, List<Entry> right)\n\t\t{\n\t\t\tDictionary<string, List<Entry>> leftMap = new();\n\t\t\tDictionary<string, List<Entry>> rightMap = new();\n\n\t\t\tforeach (var item in left)\n\t\t\t{\n\t\t\t\tstring key = item.Signature;\n\t\t\t\tif (leftMap.ContainsKey(key))\n\t\t\t\t\tleftMap[key].Add(item);\n\t\t\t\telse\n\t\t\t\t\tleftMap[key] = [item];\n\t\t\t}\n\n\t\t\tforeach (var item in right)\n\t\t\t{\n\t\t\t\tstring key = item.Signature;\n\t\t\t\tif (rightMap.ContainsKey(key))\n\t\t\t\t\trightMap[key].Add(item);\n\t\t\t\telse\n\t\t\t\t\trightMap[key] = [item];\n\t\t\t}\n\n\t\t\tList<(Entry? Left, Entry? Right)> results = new();\n\n\t\t\tforeach (var (key, items) in leftMap)\n\t\t\t{\n\t\t\t\tif (rightMap.TryGetValue(key, out var rightEntries))\n\t\t\t\t{\n\t\t\t\t\tforeach (var item in items)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar other = rightEntries.Find(_ => EntryComparer.Instance.Equals(_, item));\n\t\t\t\t\t\tresults.Add((item, other));\n\t\t\t\t\t\tif (other == null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tSetKind(item, DiffKind.Remove);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tforeach (var item in items)\n\t\t\t\t\t{\n\t\t\t\t\t\tSetKind(item, DiffKind.Remove);\n\t\t\t\t\t\tresults.Add((item, null));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach (var (key, items) in rightMap)\n\t\t\t{\n\t\t\t\tif (leftMap.TryGetValue(key, out var leftEntries))\n\t\t\t\t{\n\t\t\t\t\tforeach (var item in items)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!leftEntries.Any(_ => EntryComparer.Instance.Equals(_, item)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tresults.Add((null, item));\n\t\t\t\t\t\t\tSetKind(item, DiffKind.Add);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tforeach (var item in items)\n\t\t\t\t\t{\n\t\t\t\t\t\tSetKind(item, DiffKind.Add);\n\t\t\t\t\t\tresults.Add((null, item));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn results;\n\n\t\t\tstatic void SetKind(Entry item, DiffKind kind)\n\t\t\t{\n\t\t\t\tif (item.Children?.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tforeach (var child in item.Children)\n\t\t\t\t\t{\n\t\t\t\t\t\tSetKind(child, kind);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\titem.Kind = kind;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tinternal static void Show(TabPageModel tabPage, LoadedAssembly left, LoadedAssembly right, AssemblyTreeModel assemblyTreeModel)\n\t\t{\n\t\t\ttabPage.ShowTextView(t => t.RunWithCancellation(token => Task.Run(DoCompare, token), $\"Comparing {left.Text} - {right.Text}\").Then(vm => {\n\t\t\t\ttabPage.Title = $\"Compare {left.Text} - {right.Text}\";\n\t\t\t\ttabPage.SupportsLanguageSwitching = false;\n\t\t\t\ttabPage.FrozenContent = true;\n\t\t\t\tvar compareView = new CompareView();\n\t\t\t\tcompareView.DataContext = vm;\n\t\t\t\ttabPage.Content = compareView;\n\t\t\t}));\n\n\t\t\tCompareViewModel DoCompare()\n\t\t\t{\n\t\t\t\treturn new CompareViewModel(tabPage, assemblyTreeModel, left, right);\n\t\t\t}\n\t\t}\n\t}\n\n\t[DebuggerDisplay($\"{{{nameof(GetDebuggerDisplay)}(),nq}}\")]\n\tpublic class Entry\n\t{\n\t\tprivate DiffKind? kind;\n\n\t\tpublic DiffKind RecursiveKind {\n\t\t\tget {\n\t\t\t\tif (kind != null)\n\t\t\t\t\treturn kind.Value;\n\t\t\t\tif (Children == null)\n\t\t\t\t\treturn DiffKind.None;\n\n\t\t\t\tint addCount = 0, removeCount = 0, updateCount = 0;\n\n\t\t\t\tforeach (var item in Children)\n\t\t\t\t{\n\t\t\t\t\tswitch (item.RecursiveKind)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase DiffKind.Add:\n\t\t\t\t\t\t\taddCount++;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DiffKind.Remove:\n\t\t\t\t\t\t\tremoveCount++;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase DiffKind.Update:\n\t\t\t\t\t\t\tupdateCount++;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (addCount == Children.Count)\n\t\t\t\t\treturn DiffKind.Add;\n\t\t\t\tif (removeCount == Children.Count)\n\t\t\t\t\treturn DiffKind.Remove;\n\t\t\t\tif (addCount > 0 || removeCount > 0 || updateCount > 0)\n\t\t\t\t\treturn DiffKind.Update;\n\t\t\t\treturn DiffKind.None;\n\t\t\t}\n\t\t}\n\n\t\tpublic DiffKind Kind {\n\t\t\tget => this.kind ?? DiffKind.None;\n\t\t\tset => this.kind = value;\n\t\t}\n\t\tpublic required string Signature { get; init; }\n\t\tpublic required ISymbol Entity { get; init; }\n\t\tpublic ISymbol? OtherEntity { get; init; }\n\n\t\tpublic Entry? Parent { get; set; }\n\t\tpublic List<Entry>? Children { get; set; }\n\n\t\tprivate string GetDebuggerDisplay()\n\t\t{\n\t\t\treturn $\"Entry{Kind}{Entity.ToString() ?? Signature}\";\n\t\t}\n\t}\n\n\tpublic class EntryComparer : IEqualityComparer<Entry>\n\t{\n\t\tpublic static EntryComparer Instance = new();\n\n\t\tpublic bool Equals(Entry? x, Entry? y)\n\t\t{\n\t\t\treturn x?.Signature == y?.Signature;\n\t\t}\n\n\t\tpublic int GetHashCode([DisallowNull] Entry obj)\n\t\t{\n\t\t\treturn obj.Signature.GetHashCode();\n\t\t}\n\t}\n\n\tpublic enum DiffKind\n\t{\n\t\tNone = ' ',\n\t\tAdd = '+',\n\t\tRemove = '-',\n\t\tUpdate = '~'\n\t}\n\n\tclass ComparisonEntryTreeNode : ILSpyTreeNode\n\t{\n\t\tprivate readonly Entry entry;\n\t\tprivate readonly CompareViewModel compareViewModel;\n\n\t\tinternal Entry Entry => entry;\n\n\t\tpublic ComparisonEntryTreeNode(Entry entry, CompareViewModel compareViewModel)\n\t\t{\n\t\t\tthis.entry = entry;\n\t\t\tthis.LazyLoading = entry.Children != null;\n\t\t\tthis.compareViewModel = compareViewModel;\n\t\t}\n\n\t\tprotected override void LoadChildren()\n\t\t{\n\t\t\tif (entry.Children == null)\n\t\t\t\treturn;\n\n\t\t\tforeach (var item in entry.Children.OrderBy(e => (-(int)e.RecursiveKind, e.Entity.SymbolKind, e.Signature)))\n\t\t\t{\n\t\t\t\tthis.Children.Add(new ComparisonEntryTreeNode(item, compareViewModel));\n\t\t\t}\n\t\t}\n\n\t\tpublic override object Text {\n\t\t\tget {\n\t\t\t\tstring? entityText = GetEntityText(entry.Entity);\n\t\t\t\tstring? otherText = GetEntityText(entry.OtherEntity);\n\n\t\t\t\treturn entityText + (otherText != null && entityText != otherText ? \" -> \" + otherText : \"\");\n\n\t\t\t\tstring? GetEntityText(ISymbol? symbol) => symbol switch {\n\t\t\t\t\tITypeDefinition t => this.Language.TypeToString(t, ConversionFlags.None) + GetSuffixString(t.MetadataToken),\n\t\t\t\t\tIEntity e => this.Language.EntityToString(e, ConversionFlags.All & ~(ConversionFlags.ShowDeclaringType | ConversionFlags.UseFullyQualifiedEntityNames | ConversionFlags.UseFullyQualifiedTypeNames)) + GetSuffixString(e.MetadataToken),\n\t\t\t\t\tINamespace n => n.FullName,\n\t\t\t\t\tIModule m => m.FullAssemblyName,\n\t\t\t\t\t_ => null,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tpublic override object Icon {\n\t\t\tget {\n\t\t\t\tswitch (entry.Entity)\n\t\t\t\t{\n\t\t\t\t\tcase ITypeDefinition t:\n\t\t\t\t\t\treturn TypeTreeNode.GetIcon(t);\n\t\t\t\t\tcase IMethod m:\n\t\t\t\t\t\treturn MethodTreeNode.GetIcon(m);\n\t\t\t\t\tcase IField f:\n\t\t\t\t\t\treturn FieldTreeNode.GetIcon(f);\n\t\t\t\t\tcase IProperty p:\n\t\t\t\t\t\treturn PropertyTreeNode.GetIcon(p);\n\t\t\t\t\tcase IEvent e:\n\t\t\t\t\t\treturn EventTreeNode.GetIcon(e);\n\t\t\t\t\tcase INamespace n:\n\t\t\t\t\t\treturn Images.Namespace;\n\t\t\t\t\tcase IModule m:\n\t\t\t\t\t\treturn Images.Assembly;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new NotSupportedException();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic override void Decompile(Language language, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t}\n\n\t\tpublic override void ActivateItem(IPlatformRoutedEventArgs e)\n\t\t{\n\t\t\tvar node = AssemblyTreeModel.FindTreeNode(entry.Entity);\n\t\t\tAssemblyTreeModel.SelectNode(node);\n\t\t}\n\n\t\tpublic override FilterResult Filter(LanguageSettings settings)\n\t\t{\n\t\t\treturn compareViewModel.ShowIdentical || entry.RecursiveKind != DiffKind.None ? FilterResult.Match : FilterResult.Hidden;\n\t\t}\n\n\t\tpublic override object? Background {\n\t\t\tget {\n\t\t\t\tswitch (entry.RecursiveKind)\n\t\t\t\t{\n\t\t\t\t\tcase DiffKind.Add:\n\t\t\t\t\t\treturn Brushes.LightGreen;\n\t\t\t\t\tcase DiffKind.Remove:\n\t\t\t\t\t\treturn Brushes.LightPink;\n\t\t\t\t\tcase DiffKind.Update:\n\t\t\t\t\t\treturn Brushes.LightBlue;\n\t\t\t\t}\n\n\t\t\t\treturn Brushes.Transparent;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/ViewModels/DebugStepsPaneModel.cs",
    "content": "// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Windows;\n\nnamespace ICSharpCode.ILSpy.ViewModels\n{\n#if DEBUG\n\t[ExportToolPane]\n\t[Shared]\n#endif\n\tpublic class DebugStepsPaneModel : ToolPaneModel\n\t{\n\t\tpublic const string PaneContentId = \"debugStepsPane\";\n\n\t\tpublic DebugStepsPaneModel()\n\t\t{\n\t\t\tContentId = PaneContentId;\n\t\t\tTitle = Properties.Resources.DebugSteps;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/ViewModels/LegacyToolPaneModel.cs",
    "content": "// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Windows;\n\nnamespace ICSharpCode.ILSpy.ViewModels\n{\n\tinternal enum LegacyToolPaneLocation\n\t{\n\t\tTop,\n\t\tBottom\n\t}\n\n\tinternal class LegacyToolPaneModel : ToolPaneModel\n\t{\n\t\tpublic LegacyToolPaneModel(string title, object content, LegacyToolPaneLocation location)\n\t\t{\n\t\t\tthis.Title = title;\n\t\t\tthis.Content = content;\n\t\t\tthis.IsCloseable = true;\n\t\t\tthis.Location = location;\n\t\t}\n\n\t\tpublic object Content { get; }\n\n\t\tpublic LegacyToolPaneLocation Location { get; }\n\t}\n}\n"
  },
  {
    "path": "ILSpy/ViewModels/ManageAssemblyListsViewModel.cs",
    "content": "// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.IO;\nusing System.Text.RegularExpressions;\nusing System.Windows;\nusing System.Windows.Input;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.Properties;\nusing ICSharpCode.ILSpyX;\n\nusing TomsToolbox.Wpf;\n\nusing DelegateCommand = ICSharpCode.ILSpy.Commands.DelegateCommand;\n\nnamespace ICSharpCode.ILSpy.ViewModels\n{\n\tpublic class ManageAssemblyListsViewModel : ObservableObjectBase\n\t{\n\t\tprivate readonly AssemblyListManager manager;\n\t\tprivate readonly Window parent;\n\t\tprivate readonly SessionSettings sessionSettings;\n\n\t\tpublic ManageAssemblyListsViewModel(Window parent, SettingsService settingsService)\n\t\t{\n\t\t\tthis.manager = settingsService.AssemblyListManager;\n\t\t\tthis.parent = parent;\n\t\t\tthis.sessionSettings = settingsService.SessionSettings;\n\n\t\t\tNewCommand = new DelegateCommand(ExecuteNew);\n\t\t\tCloneCommand = new DelegateCommand(ExecuteClone, CanExecuteClone);\n\t\t\tRenameCommand = new DelegateCommand(ExecuteRename, CanExecuteRename);\n\t\t\tResetCommand = new DelegateCommand(ExecuteReset);\n\t\t\tDeleteCommand = new DelegateCommand(ExecuteDelete, CanExecuteDelete);\n\t\t\tCreatePreconfiguredAssemblyListCommand = new DelegateCommand<PreconfiguredAssemblyList>(ExecuteCreatePreconfiguredAssemblyList);\n\t\t\tSelectAssemblyListCommand = new DelegateCommand(ExecuteSelectAssemblyList, CanExecuteSelectAssemblyList);\n\n\t\t\tPreconfiguredAssemblyLists = new List<PreconfiguredAssemblyList>(ResolvePreconfiguredAssemblyLists());\n\t\t}\n\n\t\tIEnumerable<PreconfiguredAssemblyList> ResolvePreconfiguredAssemblyLists()\n\t\t{\n\t\t\tyield return new PreconfiguredAssemblyList(AssemblyListManager.DotNet4List);\n\t\t\tyield return new PreconfiguredAssemblyList(AssemblyListManager.DotNet35List);\n\t\t\tyield return new PreconfiguredAssemblyList(AssemblyListManager.ASPDotNetMVC3List);\n\n\t\t\tvar basePath = DotNetCorePathFinder.FindDotNetExeDirectory();\n\t\t\tif (basePath == null)\n\t\t\t\tyield break;\n\n\t\t\tDictionary<string, string> foundVersions = new Dictionary<string, string>();\n\t\t\tDictionary<string, int> latestRevision = new Dictionary<string, int>();\n\n\t\t\tforeach (var sdkDir in Directory.GetDirectories(Path.Combine(basePath, \"shared\")))\n\t\t\t{\n\t\t\t\tif (sdkDir.EndsWith(\".Ref\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\t\tcontinue;\n\t\t\t\tforeach (var versionDir in Directory.GetDirectories(sdkDir))\n\t\t\t\t{\n\t\t\t\t\tvar match = Regex.Match(versionDir, @\"[/\\\\](?<name>[A-z0-9.]+)[/\\\\](?<version>\\d+\\.\\d+)(.(?<revision>\\d+))?(?<suffix>-.*)?$\");\n\t\t\t\t\tif (!match.Success)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tstring name = match.Groups[\"name\"].Value;\n\t\t\t\t\tint index = name.LastIndexOfAny(new[] { '/', '\\\\' });\n\t\t\t\t\tif (index >= 0)\n\t\t\t\t\t\tname = name.Substring(index + 1);\n\t\t\t\t\tstring text = name + \" \" + match.Groups[\"version\"].Value;\n\t\t\t\t\tif (!latestRevision.TryGetValue(text, out int revision))\n\t\t\t\t\t\trevision = -1;\n\t\t\t\t\tint newRevision = int.Parse(match.Groups[\"revision\"].Value);\n\t\t\t\t\tif (newRevision > revision)\n\t\t\t\t\t{\n\t\t\t\t\t\tlatestRevision[text] = newRevision;\n\t\t\t\t\t\tfoundVersions[text] = versionDir;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach (var pair in foundVersions)\n\t\t\t{\n\t\t\t\tyield return new PreconfiguredAssemblyList(pair.Key + \"(.\" + latestRevision[pair.Key] + \")\", pair.Value);\n\t\t\t}\n\t\t}\n\n\t\tpublic ObservableCollection<string> AssemblyLists => manager.AssemblyLists;\n\n\t\tpublic List<PreconfiguredAssemblyList> PreconfiguredAssemblyLists { get; }\n\n\t\tprivate string selectedAssemblyList;\n\n\t\tpublic string SelectedAssemblyList {\n\t\t\tget => selectedAssemblyList;\n\t\t\tset => SetProperty(ref selectedAssemblyList, value);\n\t\t}\n\n\t\tpublic ICommand NewCommand { get; }\n\t\tpublic ICommand CloneCommand { get; }\n\t\tpublic ICommand ResetCommand { get; }\n\t\tpublic ICommand RenameCommand { get; }\n\t\tpublic ICommand DeleteCommand { get; }\n\t\tpublic ICommand CreatePreconfiguredAssemblyListCommand { get; }\n\t\tpublic ICommand SelectAssemblyListCommand { get; }\n\n\t\tprivate void ExecuteNew()\n\t\t{\n\t\t\tCreateListDialog dlg = new CreateListDialog(Resources.NewList);\n\t\t\tdlg.Owner = parent;\n\t\t\tdlg.Closing += (s, args) => {\n\t\t\t\tif (dlg.DialogResult == true)\n\t\t\t\t{\n\t\t\t\t\tif (manager.AssemblyLists.Contains(dlg.ListName))\n\t\t\t\t\t{\n\t\t\t\t\t\targs.Cancel = true;\n\t\t\t\t\t\tMessageBox.Show(Resources.ListExistsAlready, null, MessageBoxButton.OK);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (dlg.ShowDialog() == true)\n\t\t\t{\n\t\t\t\tvar list = manager.CreateList(dlg.ListName);\n\t\t\t\tmanager.AddListIfNotExists(list);\n\t\t\t}\n\t\t}\n\n\t\tprivate bool CanExecuteClone()\n\t\t{\n\t\t\treturn selectedAssemblyList != null;\n\t\t}\n\n\t\tprivate void ExecuteClone()\n\t\t{\n\t\t\tCreateListDialog dlg = new CreateListDialog(Resources.NewList);\n\t\t\tdlg.Owner = parent;\n\t\t\tdlg.Closing += (s, args) => {\n\t\t\t\tif (dlg.DialogResult == true)\n\t\t\t\t{\n\t\t\t\t\tif (manager.AssemblyLists.Contains(dlg.ListName))\n\t\t\t\t\t{\n\t\t\t\t\t\targs.Cancel = true;\n\t\t\t\t\t\tMessageBox.Show(Resources.ListExistsAlready, null, MessageBoxButton.OK);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (dlg.ShowDialog() == true)\n\t\t\t{\n\t\t\t\tmanager.CloneList(SelectedAssemblyList, dlg.ListName);\n\t\t\t}\n\t\t}\n\n\t\tprivate void ExecuteReset()\n\t\t{\n\t\t\tif (MessageBox.Show(parent, Resources.ListsResetConfirmation,\n\t\t\t\t\"ILSpy\", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No, MessageBoxOptions.None) != MessageBoxResult.Yes)\n\t\t\t\treturn;\n\t\t\tmanager.ClearAll();\n\t\t\tmanager.CreateDefaultAssemblyLists();\n\t\t\tsessionSettings.ActiveAssemblyList = manager.AssemblyLists[0];\n\t\t}\n\n\t\tprivate void ExecuteDelete()\n\t\t{\n\t\t\tif (MessageBox.Show(parent, Resources.ListDeleteConfirmation,\n\"ILSpy\", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No, MessageBoxOptions.None) != MessageBoxResult.Yes)\n\t\t\t\treturn;\n\t\t\tstring assemblyList = SelectedAssemblyList;\n\t\t\tSelectedAssemblyList = null;\n\t\t\tint index = manager.AssemblyLists.IndexOf(assemblyList);\n\t\t\tmanager.DeleteList(assemblyList);\n\t\t\tif (manager.AssemblyLists.Count > 0)\n\t\t\t{\n\t\t\t\tSelectedAssemblyList = manager.AssemblyLists[Math.Max(0, index - 1)];\n\t\t\t\tif (sessionSettings.ActiveAssemblyList == assemblyList)\n\t\t\t\t{\n\t\t\t\t\tsessionSettings.ActiveAssemblyList = SelectedAssemblyList;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate bool CanExecuteDelete()\n\t\t{\n\t\t\treturn selectedAssemblyList != null;\n\t\t}\n\n\t\tprivate bool CanExecuteRename()\n\t\t{\n\t\t\treturn selectedAssemblyList != null;\n\t\t}\n\n\t\tprivate void ExecuteRename()\n\t\t{\n\t\t\tCreateListDialog dlg = new CreateListDialog(Resources.RenameList);\n\t\t\tdlg.Owner = parent;\n\t\t\tdlg.ListName = selectedAssemblyList;\n\t\t\tdlg.ListNameBox.SelectAll();\n\t\t\tdlg.Closing += (s, args) => {\n\t\t\t\tif (dlg.DialogResult == true)\n\t\t\t\t{\n\t\t\t\t\tif (dlg.ListName == selectedAssemblyList)\n\t\t\t\t\t{\n\t\t\t\t\t\targs.Cancel = true;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (manager.AssemblyLists.Contains(dlg.ListName))\n\t\t\t\t\t{\n\t\t\t\t\t\targs.Cancel = true;\n\t\t\t\t\t\tMessageBox.Show(Resources.ListExistsAlready, null, MessageBoxButton.OK);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (dlg.ShowDialog() == true)\n\t\t\t{\n\t\t\t\tstring assemblyList = SelectedAssemblyList;\n\t\t\t\tSelectedAssemblyList = dlg.ListName;\n\t\t\t\tmanager.RenameList(assemblyList, dlg.ListName);\n\t\t\t\tif (sessionSettings.ActiveAssemblyList == assemblyList)\n\t\t\t\t{\n\t\t\t\t\tsessionSettings.ActiveAssemblyList = manager.AssemblyLists[manager.AssemblyLists.Count - 1];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate void ExecuteCreatePreconfiguredAssemblyList(PreconfiguredAssemblyList config)\n\t\t{\n\t\t\tCreateListDialog dlg = new CreateListDialog(Resources.AddPreconfiguredList);\n\t\t\tdlg.Owner = parent;\n\t\t\tdlg.ListName = config.Name;\n\t\t\tdlg.ListNameBox.SelectAll();\n\t\t\tdlg.Closing += (s, args) => {\n\t\t\t\tif (dlg.DialogResult == true)\n\t\t\t\t{\n\t\t\t\t\tif (manager.AssemblyLists.Contains(dlg.ListName))\n\t\t\t\t\t{\n\t\t\t\t\t\targs.Cancel = true;\n\t\t\t\t\t\tMessageBox.Show(Resources.ListExistsAlready, null, MessageBoxButton.OK);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (dlg.ShowDialog() == true)\n\t\t\t{\n\t\t\t\tvar list = manager.CreateDefaultList(config.Name, config.Path, dlg.ListName);\n\t\t\t\tif (list.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tmanager.AddListIfNotExists(list);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate bool CanExecuteSelectAssemblyList()\n\t\t{\n\t\t\treturn SelectedAssemblyList != null;\n\t\t}\n\n\t\tprivate void ExecuteSelectAssemblyList()\n\t\t{\n\t\t\tsessionSettings.ActiveAssemblyList = SelectedAssemblyList;\n\t\t\tthis.parent.Close();\n\t\t}\n\t}\n\n\tpublic class PreconfiguredAssemblyList\n\t{\n\t\tpublic string Name { get; }\n\t\tpublic string Path { get; }\n\n\t\tpublic PreconfiguredAssemblyList(string name, string path = null)\n\t\t{\n\t\t\tthis.Name = name;\n\t\t\tthis.Path = path;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/ViewModels/PaneModel.cs",
    "content": "// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.ComponentModel;\nusing System.Windows;\nusing System.Windows.Input;\n\nusing ICSharpCode.ILSpy.Docking;\n\nusing TomsToolbox.Wpf;\n\nnamespace ICSharpCode.ILSpy.ViewModels\n{\n\tpublic abstract class PaneModel : ObservableObjectBase\n\t{\n\t\tprivate readonly Throttle titleChangeThrottle;\n\n\t\tprotected static DockWorkspace DockWorkspace => App.ExportProvider.GetExportedValue<DockWorkspace>();\n\n\t\tprotected PaneModel()\n\t\t{\n\t\t\ttitleChangeThrottle = new Throttle(() => OnPropertyChanged(nameof(Title)));\n\t\t}\n\n\t\tclass CloseCommandImpl : ICommand\n\t\t{\n\t\t\treadonly PaneModel model;\n\n\t\t\tpublic CloseCommandImpl(PaneModel model)\n\t\t\t{\n\t\t\t\tthis.model = model;\n\t\t\t\tthis.model.PropertyChanged += Model_PropertyChanged;\n\t\t\t}\n\n\t\t\tprivate void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)\n\t\t\t{\n\t\t\t\tif (e.PropertyName == nameof(model.IsCloseable))\n\t\t\t\t{\n\t\t\t\t\tCanExecuteChanged?.Invoke(this, EventArgs.Empty);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic event EventHandler CanExecuteChanged;\n\n\t\t\tpublic bool CanExecute(object parameter)\n\t\t\t{\n\t\t\t\treturn model.IsCloseable;\n\t\t\t}\n\n\t\t\tpublic void Execute(object parameter)\n\t\t\t{\n\t\t\t\tDockWorkspace.Remove(model);\n\t\t\t}\n\t\t}\n\n\t\tprivate bool isSelected;\n\n\t\tpublic bool IsSelected {\n\t\t\tget => isSelected;\n\t\t\tset => SetProperty(ref isSelected, value);\n\t\t}\n\n\t\tprivate bool isActive;\n\n\t\tpublic bool IsActive {\n\t\t\tget => isActive;\n\t\t\tset => SetProperty(ref isActive, value);\n\t\t}\n\n\t\tprivate bool isVisible;\n\n\t\tpublic bool IsVisible {\n\t\t\tget { return isVisible; }\n\t\t\tset {\n\t\t\t\tif (SetProperty(ref isVisible, value) && !value)\n\t\t\t\t{\n\t\t\t\t\t// When the pane is hidden, it should no longer be marked as active, else it won't raise an event when it is activated again.\n\t\t\t\t\tIsActive = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate bool isCloseable = true;\n\n\t\tpublic bool IsCloseable {\n\t\t\tget => isCloseable;\n\t\t\tset => SetProperty(ref isCloseable, value);\n\t\t}\n\n\t\tpublic ICommand CloseCommand => new CloseCommandImpl(this);\n\n\t\tprivate string contentId;\n\n\t\tpublic string ContentId {\n\t\t\tget => contentId;\n\t\t\tset => SetProperty(ref contentId, value);\n\t\t}\n\n\t\tprivate string title;\n\n\t\tpublic string Title {\n\t\t\tget => title;\n\t\t\tset {\n\t\t\t\ttitle = value;\n\t\t\t\ttitleChangeThrottle.Tick();\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic static class Pane\n\t{\n\t\t// Helper properties to enable binding state properties from the model to the view.\n\n\t\tpublic static readonly DependencyProperty IsActiveProperty = DependencyProperty.RegisterAttached(\n\t\t\t\"IsActive\", typeof(bool), typeof(Pane), new FrameworkPropertyMetadata(default(bool)));\n\t\tpublic static void SetIsActive(DependencyObject element, bool value)\n\t\t{\n\t\t\telement.SetValue(IsActiveProperty, value);\n\t\t}\n\t\tpublic static bool GetIsActive(DependencyObject element)\n\t\t{\n\t\t\treturn (bool)element.GetValue(IsActiveProperty);\n\t\t}\n\n\t\tpublic static readonly DependencyProperty IsVisibleProperty = DependencyProperty.RegisterAttached(\n\t\t\t\"IsVisible\", typeof(bool), typeof(Pane), new FrameworkPropertyMetadata(default(bool)));\n\t\tpublic static void SetIsVisible(DependencyObject element, bool value)\n\t\t{\n\t\t\telement.SetValue(IsVisibleProperty, value);\n\t\t}\n\t\tpublic static bool GetIsVisible(DependencyObject element)\n\t\t{\n\t\t\treturn (bool)element.GetValue(IsVisibleProperty);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/ViewModels/TabPageModel.cs",
    "content": "// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Composition;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Windows;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.ILSpy.TextView;\n\nusing TomsToolbox.Composition;\nusing TomsToolbox.Wpf;\n\n#nullable enable\n\nnamespace ICSharpCode.ILSpy.ViewModels\n{\n\t[Export]\n\t[NonShared]\n\tpublic class TabPageModel : PaneModel\n\t{\n\t\tpublic IExportProvider ExportProvider { get; }\n\n\t\tpublic TabPageModel(IExportProvider exportProvider)\n\t\t{\n\t\t\tExportProvider = exportProvider;\n\t\t\tTitle = Properties.Resources.NewTab;\n\t\t}\n\n\t\tprivate bool supportsLanguageSwitching = true;\n\n\t\tpublic bool SupportsLanguageSwitching {\n\t\t\tget => supportsLanguageSwitching;\n\t\t\tset => SetProperty(ref supportsLanguageSwitching, value);\n\t\t}\n\n\t\tprivate bool frozenContent;\n\n\t\tpublic bool FrozenContent {\n\t\t\tget => frozenContent;\n\t\t\tset => SetProperty(ref frozenContent, value);\n\t\t}\n\n\t\tprivate object? content;\n\n\t\tpublic object? Content {\n\t\t\tget => content;\n\t\t\tset => SetProperty(ref content, value);\n\t\t}\n\n\t\tpublic ViewState? GetState()\n\t\t{\n\t\t\treturn (Content as IHaveState)?.GetState();\n\t\t}\n\t}\n\n\tpublic static class TabPageModelExtensions\n\t{\n\t\tpublic static Task<T> ShowTextViewAsync<T>(this TabPageModel tabPage, Func<DecompilerTextView, Task<T>> action)\n\t\t{\n\t\t\tif (tabPage.Content is not DecompilerTextView textView)\n\t\t\t{\n\t\t\t\ttextView = new DecompilerTextView(tabPage.ExportProvider);\n\t\t\t\ttabPage.Content = textView;\n\t\t\t}\n\t\t\ttabPage.Title = Properties.Resources.Decompiling;\n\t\t\treturn action(textView);\n\t\t}\n\n\t\tpublic static Task ShowTextViewAsync(this TabPageModel tabPage, Func<DecompilerTextView, Task> action)\n\t\t{\n\t\t\tif (tabPage.Content is not DecompilerTextView textView)\n\t\t\t{\n\t\t\t\ttextView = new DecompilerTextView(tabPage.ExportProvider);\n\t\t\t\ttabPage.Content = textView;\n\t\t\t}\n\t\t\tstring oldTitle = tabPage.Title;\n\t\t\ttabPage.Title = Properties.Resources.Decompiling;\n\t\t\ttry\n\t\t\t{\n\t\t\t\treturn action(textView);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tif (tabPage.Title == Properties.Resources.Decompiling)\n\t\t\t\t{\n\t\t\t\t\ttabPage.Title = oldTitle;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static void ShowTextView(this TabPageModel tabPage, Action<DecompilerTextView> action)\n\t\t{\n\t\t\tif (tabPage.Content is not DecompilerTextView textView)\n\t\t\t{\n\t\t\t\ttextView = new DecompilerTextView(tabPage.ExportProvider);\n\t\t\t\ttabPage.Content = textView;\n\t\t\t}\n\t\t\tstring oldTitle = tabPage.Title;\n\t\t\ttabPage.Title = Properties.Resources.Decompiling;\n\t\t\taction(textView);\n\t\t\tif (tabPage.Title == Properties.Resources.Decompiling)\n\t\t\t{\n\t\t\t\ttabPage.Title = oldTitle;\n\t\t\t}\n\t\t}\n\n\t\tpublic static void Focus(this TabPageModel tabPage)\n\t\t{\n\t\t\tif (tabPage.Content is not FrameworkElement content)\n\t\t\t\treturn;\n\n\t\t\tvar focusable = content\n\t\t\t\t.VisualDescendantsAndSelf()\n\t\t\t\t.OfType<FrameworkElement>()\n\t\t\t\t.FirstOrDefault(item => item.Focusable);\n\n\t\t\tfocusable?.Focus();\n\t\t}\n\n\t\tpublic static DecompilationOptions CreateDecompilationOptions(this TabPageModel tabPage)\n\t\t{\n\t\t\tvar exportProvider = tabPage.ExportProvider;\n\t\t\tvar languageService = exportProvider.GetExportedValue<LanguageService>();\n\t\t\tvar settingsService = exportProvider.GetExportedValue<SettingsService>();\n\n\t\t\treturn new(languageService.LanguageVersion, settingsService.DecompilerSettings, settingsService.DisplaySettings) { Progress = tabPage.Content as IProgress<DecompilationProgress> };\n\t\t}\n\t}\n\n\tpublic interface IHaveState\n\t{\n\t\tViewState? GetState();\n\t}\n}"
  },
  {
    "path": "ILSpy/ViewModels/ToolPaneModel.cs",
    "content": "// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Windows.Input;\n\nnamespace ICSharpCode.ILSpy.ViewModels\n{\n\tpublic abstract class ToolPaneModel : PaneModel\n\t{\n\t\tpublic virtual void Show()\n\t\t{\n\t\t\tthis.IsActive = true;\n\t\t\tthis.IsVisible = true;\n\t\t}\n\n\t\tpublic KeyGesture ShortcutKey { get; protected set; }\n\n\t\tpublic string Icon { get; protected set; }\n\n\t\tpublic ICommand AssociatedCommand { get; set; }\n\t}\n}\n"
  },
  {
    "path": "ILSpy/ViewModels/UpdatePanelViewModel.cs",
    "content": "// Copyright (c) 2024 Tom Englert for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\nusing System.Threading.Tasks;\nusing System.Windows.Input;\n\nusing ICSharpCode.ILSpy.Updates;\n\nusing TomsToolbox.Wpf;\n\nnamespace ICSharpCode.ILSpy.ViewModels;\n\n[Export]\n[NonShared]\npublic class UpdatePanelViewModel : ObservableObjectBase\n{\n\tbool isPanelVisible;\n\tstring updateAvailableDownloadUrl;\n\treadonly SettingsService settingsService;\n\n\tpublic UpdatePanelViewModel(SettingsService settingsService)\n\t{\n\t\tthis.settingsService = settingsService;\n\n\t\tMessageBus<CheckIfUpdateAvailableEventArgs>.Subscribers += (_, e) => CheckIfUpdatesAvailableAsync(e.Notify).IgnoreExceptions();\n\t}\n\n\tpublic bool IsPanelVisible {\n\t\tget => isPanelVisible;\n\t\tset => SetProperty(ref isPanelVisible, value);\n\t}\n\n\tpublic string UpdateAvailableDownloadUrl {\n\t\tget => updateAvailableDownloadUrl;\n\t\tset => SetProperty(ref updateAvailableDownloadUrl, value);\n\t}\n\n\tpublic ICommand CloseCommand => new DelegateCommand(() => IsPanelVisible = false);\n\n\tpublic ICommand DownloadOrCheckUpdateCommand => new DelegateCommand(DownloadOrCheckUpdate);\n\n\t[PropertyDependency(nameof(UpdateAvailableDownloadUrl))]\n\tpublic string ButtonText => UpdateAvailableDownloadUrl != null\n\t\t? Properties.Resources.Download\n\t\t: Properties.Resources.CheckAgain;\n\n\t[PropertyDependency(nameof(UpdateAvailableDownloadUrl))]\n\tpublic string Message => UpdateAvailableDownloadUrl != null\n\t\t? Properties.Resources.ILSpyVersionAvailable\n\t\t: Properties.Resources.UpdateILSpyFound;\n\n\tasync Task CheckIfUpdatesAvailableAsync(bool notify = false)\n\t{\n\t\tvar settings = settingsService.GetSettings<UpdateSettings>();\n\n\t\tstring downloadUrl = notify\n\t\t\t? await UpdateService.CheckForUpdatesAsync(settings)\n\t\t\t: await UpdateService.CheckForUpdatesIfEnabledAsync(settings);\n\n\t\tAdjustUpdateUIAfterCheck(downloadUrl, notify);\n\t}\n\n\tasync void DownloadOrCheckUpdate()\n\t{\n\t\tif (updateAvailableDownloadUrl != null)\n\t\t{\n\t\t\tGlobalUtils.OpenLink(updateAvailableDownloadUrl);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tIsPanelVisible = false;\n\n\t\t\tstring downloadUrl = await UpdateService.CheckForUpdatesAsync(settingsService.GetSettings<UpdateSettings>());\n\n\t\t\tAdjustUpdateUIAfterCheck(downloadUrl, true);\n\t\t}\n\t}\n\n\tvoid AdjustUpdateUIAfterCheck(string downloadUrl, bool notify)\n\t{\n\t\tUpdateAvailableDownloadUrl = downloadUrl;\n\t\tIsPanelVisible = notify;\n\t}\n}"
  },
  {
    "path": "ILSpy/Views/CompareView.xaml",
    "content": "<UserControl x:Class=\"ICSharpCode.ILSpy.Views.CompareView\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" \n             xmlns:local=\"clr-namespace:ICSharpCode.ILSpy.Views\"\n\t\t\t xmlns:stv=\"clr-namespace:ICSharpCode.ILSpy.Controls.TreeView\"\n\t\t\t xmlns:controls=\"clr-namespace:ICSharpCode.ILSpy.Controls\"\n             xmlns:themes=\"clr-namespace:ICSharpCode.ILSpy.Themes\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"450\" d:DesignWidth=\"800\">\n\t<UserControl.Resources>\n\t\t<!-- Make images transparent if menu command is disabled -->\n\t\t<Style TargetType=\"{x:Type Image}\">\n\t\t\t<Style.Triggers>\n\t\t\t\t<DataTrigger Binding=\"{Binding RelativeSource={RelativeSource AncestorType={x:Type ButtonBase}, AncestorLevel=1}, Path=IsEnabled}\" Value=\"False\">\n\t\t\t\t\t<Setter Property=\"Opacity\" Value=\"0.30\" />\n\t\t\t\t</DataTrigger>\n\t\t\t</Style.Triggers>\n\t\t</Style>\n\t\t<Style TargetType=\"{x:Type Image}\" x:Key=\"DarkModeAwareImageStyle\">\n\t\t\t<Setter Property=\"Effect\" Value=\"{DynamicResource {x:Static themes:ResourceKeys.ThemeAwareButtonEffect}}\" />\n\t\t\t<Style.Triggers>\n\t\t\t\t<DataTrigger Binding=\"{Binding RelativeSource={RelativeSource AncestorType={x:Type ButtonBase}, AncestorLevel=1}, Path=IsEnabled}\" Value=\"False\">\n\t\t\t\t\t<Setter Property=\"Opacity\" Value=\"0.30\" />\n\t\t\t\t</DataTrigger>\n\t\t\t</Style.Triggers>\n\t\t</Style>\n\t</UserControl.Resources>\n\t<Grid>\n\t\t<Grid.RowDefinitions>\n\t\t\t<RowDefinition Height=\"Auto\" />\n\t\t\t<RowDefinition Height=\"*\" />\n\t\t</Grid.RowDefinitions>\n\t\t<ToolBar>\n\t\t\t<Button Command=\"{Binding SwapAssembliesCommand}\" ToolTip=\"Swap left and right\">\n\t\t\t\t<Image Width=\"16\" Height=\"16\" Source=\"{controls:XamlResource Images/SwitchSourceOrTarget}\"\n\t\t\t       Style=\"{StaticResource DarkModeAwareImageStyle}\" />\n\t\t\t</Button>\n\t\t\t<ToggleButton IsChecked=\"{Binding ShowIdentical}\" ToolTip=\"Show identical entries\">\n\t\t\t\t<Image Width=\"16\" Height=\"16\" Source=\"{controls:XamlResource Images/DictionaryContain}\"\n\t\t\t       Style=\"{StaticResource DarkModeAwareImageStyle}\" />\n\t\t\t</ToggleButton>\n\t\t\t<Button Command=\"{Binding ExpandAllCommand}\" ToolTip=\"Expand all\">\n\t\t\t\t<Image Width=\"16\" Height=\"16\" Source=\"{controls:XamlResource Images/ExpandAll}\"\n\t\t\t       Style=\"{StaticResource DarkModeAwareImageStyle}\" />\n\t\t\t</Button>\n\t\t\t<Button Command=\"{Binding CopyToClipboardAsJSONCommand}\" ToolTip=\"Copy to clipboard as JSON\">\n\t\t\t\t<Image Width=\"16\" Height=\"16\" Source=\"{controls:XamlResource Images/ResultToJSON}\"\n\t\t\t       Style=\"{StaticResource DarkModeAwareImageStyle}\" />\n\t\t\t</Button>\n\t\t</ToolBar>\n\t\t<stv:SharpTreeView Grid.Row=\"1\" Root=\"{Binding RootEntry}\" ShowRoot=\"True\">\n\t\t\t<stv:SharpTreeView.ItemContainerStyle>\n\t\t\t\t<Style TargetType=\"stv:SharpTreeViewItem\">\n\t\t\t\t\t<Setter Property=\"Template\">\n\t\t\t\t\t\t<Setter.Value>\n\t\t\t\t\t\t\t<ControlTemplate TargetType=\"{x:Type stv:SharpTreeViewItem}\">\n\t\t\t\t\t\t\t\t<Border Background=\"Transparent\">\n\t\t\t\t\t\t\t\t\t<Border Background=\"{TemplateBinding Background}\">\n\t\t\t\t\t\t\t\t\t\t<stv:SharpTreeNodeView x:Name=\"nodeView\" HorizontalAlignment=\"Left\" />\n\t\t\t\t\t\t\t\t\t</Border>\n\t\t\t\t\t\t\t\t</Border>\n\t\t\t\t\t\t\t\t<ControlTemplate.Triggers>\n\t\t\t\t\t\t\t\t\t<DataTrigger Binding=\"{Binding IsPublicAPI}\" Value=\"False\">\n\t\t\t\t\t\t\t\t\t\t<Setter Property=\"Foreground\" Value=\"{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}\" />\n\t\t\t\t\t\t\t\t\t</DataTrigger>\n\t\t\t\t\t\t\t\t\t<Trigger Property=\"IsSelected\" Value=\"True\">\n\t\t\t\t\t\t\t\t\t\t<Setter TargetName=\"nodeView\" Property=\"TextBackground\"\n\t\t\t\t\t\t\t\t\t\tValue=\"{DynamicResource {x:Static SystemColors.HighlightBrushKey}}\" />\n\t\t\t\t\t\t\t\t\t\t<Setter TargetName=\"nodeView\" Property=\"Foreground\"\n\t\t\t\t\t\t\t\t\t\tValue=\"{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}\" />\n\t\t\t\t\t\t\t\t\t</Trigger>\n\t\t\t\t\t\t\t\t\t<Trigger Property=\"IsEnabled\" Value=\"False\">\n\t\t\t\t\t\t\t\t\t\t<Setter TargetName=\"nodeView\" Property=\"Foreground\"\n\t\t\t\t\t\t\t\t\t\tValue=\"{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}\" />\n\t\t\t\t\t\t\t\t\t</Trigger>\n\t\t\t\t\t\t\t\t</ControlTemplate.Triggers>\n\t\t\t\t\t\t\t</ControlTemplate>\n\t\t\t\t\t\t</Setter.Value>\n\t\t\t\t\t</Setter>\n\t\t\t\t</Style>\n\t\t\t</stv:SharpTreeView.ItemContainerStyle>\n\t\t</stv:SharpTreeView>\n\t</Grid>\n</UserControl>\n"
  },
  {
    "path": "ILSpy/Views/CompareView.xaml.cs",
    "content": "// Copyright (c) 2025 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Windows.Controls;\n\nnamespace ICSharpCode.ILSpy.Views\n{\n\t/// <summary>\n\t/// Interaction logic for CompareView.xaml\n\t/// </summary>\n\tpublic partial class CompareView : UserControl\n\t{\n\t\tpublic CompareView()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Views/CreateListDialog.xaml",
    "content": "<Window\n\tx:Class=\"ICSharpCode.ILSpy.CreateListDialog\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n\txmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n\txmlns:properties=\"clr-namespace:ICSharpCode.ILSpy.Properties\"\t\n\tStyle=\"{DynamicResource DialogWindow}\"\n\tWindowStartupLocation=\"CenterOwner\"\n\tResizeMode=\"NoResize\"\n\tWidth=\"300\"\n\tHeight=\"150\"\n\tFocusManager.FocusedElement=\"{Binding ElementName=ListNameBox}\">\n\t<Grid Margin=\"12,8\">\n\t\t<Grid.RowDefinitions>\n\t\t\t<RowDefinition Height=\"Auto\" />\n\t\t\t<RowDefinition Height=\"Auto\" />\n\t\t</Grid.RowDefinitions>\n\t\t<StackPanel>\n\t\t\t<Label Content=\"{x:Static properties:Resources.EnterListName}\"/>\n\t\t\t<TextBox Margin=\"8,8\" Name=\"ListNameBox\" TextChanged=\"TextBox_TextChanged\"></TextBox>\n\t\t</StackPanel>\n\t\t<StackPanel Grid.Row=\"2\" Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Margin=\"8,0\">\n\t\t\t<Button IsDefault=\"True\" Margin=\"2,0\" IsEnabled=\"False\" Name=\"okButton\" Click=\"OKButton_Click\" Content=\"{x:Static properties:Resources.Create}\"/>\n\t\t\t<Button IsCancel=\"True\" Margin=\"2,0\" Content=\"{x:Static properties:Resources.Cancel}\"/>\n\t\t</StackPanel>\n\t</Grid>\n</Window>"
  },
  {
    "path": "ILSpy/Views/CreateListDialog.xaml.cs",
    "content": "using System.Windows;\nusing System.Windows.Controls;\n\nnamespace ICSharpCode.ILSpy\n{\n\t/// <summary>\n\t/// Interaction logic for Create.xaml\n\t/// </summary>\n\tpublic partial class CreateListDialog : Window\n\t{\n\t\tpublic CreateListDialog(string title)\n\t\t{\n\t\t\tInitializeComponent();\n\t\t\tthis.Title = title;\n\t\t}\n\n\t\tprivate void TextBox_TextChanged(object sender, TextChangedEventArgs e)\n\t\t{\n\t\t\tokButton.IsEnabled = !string.IsNullOrWhiteSpace(ListNameBox.Text);\n\t\t}\n\n\t\tprivate void OKButton_Click(object sender, RoutedEventArgs e)\n\t\t{\n\t\t\tif (!string.IsNullOrWhiteSpace(ListNameBox.Text))\n\t\t\t{\n\t\t\t\tthis.DialogResult = true;\n\t\t\t}\n\t\t}\n\n\t\tpublic string ListName {\n\t\t\tget => ListNameBox.Text;\n\t\t\tset => ListNameBox.Text = value;\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Views/DebugSteps.xaml",
    "content": "<UserControl x:Class=\"ICSharpCode.ILSpy.DebugSteps\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" \n             xmlns:local=\"clr-namespace:ICSharpCode.ILSpy\"\n\t\t\t xmlns:properties=\"clr-namespace:ICSharpCode.ILSpy.Properties\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"300\" d:DesignWidth=\"300\">\n\t<DockPanel>\n\t\t<StackPanel DockPanel.Dock=\"Top\" Orientation=\"Horizontal\">\n\t\t\t<CheckBox Margin=\"3\" Content=\"{x:Static properties:Resources.UseFieldSugar}\" IsChecked=\"{Binding UseFieldSugar, Source={x:Static local:DebugSteps.Options}}\" />\n\t\t\t<CheckBox Margin=\"3\" Content=\"{x:Static properties:Resources.UseLogicOperationSugar}\"  IsChecked=\"{Binding UseLogicOperationSugar, Source={x:Static local:DebugSteps.Options}}\" />\n\t\t\t<CheckBox Margin=\"3\" Content=\"{x:Static properties:Resources.ShowILRanges}\"  IsChecked=\"{Binding ShowILRanges, Source={x:Static local:DebugSteps.Options}}\" />\n\t\t\t<CheckBox Margin=\"3\" Content=\"{x:Static properties:Resources.ShowChildIndexInBlock}\"  IsChecked=\"{Binding ShowChildIndexInBlock, Source={x:Static local:DebugSteps.Options}}\" />\n\t\t</StackPanel>\n\t\t<TreeView Name=\"tree\" MouseDoubleClick=\"ShowStateAfter_Click\" KeyDown=\"tree_KeyDown\">\n\t\t\t<TreeView.ItemTemplate>\n\t\t\t\t<HierarchicalDataTemplate ItemsSource=\"{Binding Children}\">\n\t\t\t\t\t<TextBlock Text=\"{Binding Description}\" />\n\t\t\t\t</HierarchicalDataTemplate>\n\t\t\t</TreeView.ItemTemplate>\n\t\t\t<TreeView.ContextMenu>\n\t\t\t\t<ContextMenu>\n\t\t\t\t\t<MenuItem Header=\"{x:Static properties:Resources.ShowStateBeforeThisStep}\" Click=\"ShowStateBefore_Click\" InputGestureText=\"Shift+Enter\" />\n\t\t\t\t\t<MenuItem Header=\"{x:Static properties:Resources.ShowStateAfterThisStep}\" Click=\"ShowStateAfter_Click\" InputGestureText=\"Enter\" />\n\t\t\t\t\t<MenuItem Header=\"{x:Static properties:Resources.DebugThisStep}\" Click=\"DebugStep_Click\" />\n\t\t\t\t</ContextMenu>\n\t\t\t</TreeView.ContextMenu>\n\t\t</TreeView>\n\t</DockPanel>\n</UserControl>\n"
  },
  {
    "path": "ILSpy/Views/DebugSteps.xaml.cs",
    "content": "using System;\nusing System.Composition;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Input;\n\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.IL.Transforms;\nusing ICSharpCode.ILSpy.AssemblyTree;\nusing ICSharpCode.ILSpy.Docking;\nusing ICSharpCode.ILSpy.ViewModels;\n\nusing TomsToolbox.Wpf.Composition.AttributedModel;\n\nnamespace ICSharpCode.ILSpy\n{\n\t[DataTemplate(typeof(DebugStepsPaneModel))]\n\t[NonShared]\n\tpublic partial class DebugSteps : UserControl\n\t{\n\t\tprivate readonly AssemblyTreeModel assemblyTreeModel;\n\t\tprivate readonly SettingsService settingsService;\n\t\tprivate readonly LanguageService languageService;\n\t\tprivate readonly DockWorkspace dockWorkspace;\n\n\t\tstatic readonly ILAstWritingOptions writingOptions = new ILAstWritingOptions {\n\t\t\tUseFieldSugar = true,\n\t\t\tUseLogicOperationSugar = true\n\t\t};\n\n\t\tpublic static ILAstWritingOptions Options => writingOptions;\n\n#if DEBUG\n\t\tILAstLanguage language;\n#endif\n\t\tpublic DebugSteps(AssemblyTreeModel assemblyTreeModel, SettingsService settingsService, LanguageService languageService, DockWorkspace dockWorkspace)\n\t\t{\n\t\t\tthis.assemblyTreeModel = assemblyTreeModel;\n\t\t\tthis.settingsService = settingsService;\n\t\t\tthis.languageService = languageService;\n\t\t\tthis.dockWorkspace = dockWorkspace;\n\n\t\t\tInitializeComponent();\n\n#if DEBUG\n\t\t\tMessageBus<SettingsChangedEventArgs>.Subscribers += (sender, e) => Settings_PropertyChanged(sender, e);\n\t\t\tMessageBus<AssemblyTreeSelectionChangedEventArgs>.Subscribers += SelectionChanged;\n\n\t\t\twritingOptions.PropertyChanged += WritingOptions_PropertyChanged;\n\n\t\t\tif (languageService.Language is ILAstLanguage l)\n\t\t\t{\n\t\t\t\tl.StepperUpdated += ILAstStepperUpdated;\n\t\t\t\tlanguage = l;\n\t\t\t\tILAstStepperUpdated(null, null);\n\t\t\t}\n#endif\n\t\t}\n\n\t\tprivate void WritingOptions_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)\n\t\t{\n\t\t\tDecompileAsync(lastSelectedStep);\n\t\t}\n\n\t\tprivate void SelectionChanged(object sender, EventArgs e)\n\t\t{\n\t\t\tDispatcher.Invoke(() => {\n\t\t\t\ttree.ItemsSource = null;\n\t\t\t\tlastSelectedStep = int.MaxValue;\n\t\t\t});\n\t\t}\n\n\t\tprivate void Settings_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)\n\t\t{\n#if DEBUG\n\t\t\tif (sender is not LanguageSettings)\n\t\t\t\treturn;\n\n\t\t\tif (e.PropertyName == nameof(LanguageSettings.LanguageId))\n\t\t\t{\n\t\t\t\tif (language != null)\n\t\t\t\t{\n\t\t\t\t\tlanguage.StepperUpdated -= ILAstStepperUpdated;\n\t\t\t\t}\n\t\t\t\tif (languageService.Language is ILAstLanguage l)\n\t\t\t\t{\n\t\t\t\t\tl.StepperUpdated += ILAstStepperUpdated;\n\t\t\t\t\tlanguage = l;\n\t\t\t\t\tILAstStepperUpdated(null, null);\n\t\t\t\t}\n\t\t\t}\n#endif\n\t\t}\n\n\t\tprivate void ILAstStepperUpdated(object sender, EventArgs e)\n\t\t{\n#if DEBUG\n\t\t\tif (language == null)\n\t\t\t\treturn;\n\t\t\tDispatcher.Invoke(() => {\n\t\t\t\ttree.ItemsSource = language.Stepper.Steps;\n\t\t\t\tlastSelectedStep = int.MaxValue;\n\t\t\t});\n#endif\n\t\t}\n\n\t\tprivate void ShowStateAfter_Click(object sender, RoutedEventArgs e)\n\t\t{\n\t\t\tStepper.Node n = (Stepper.Node)tree.SelectedItem;\n\t\t\tif (n == null)\n\t\t\t\treturn;\n\t\t\tDecompileAsync(n.EndStep);\n\t\t}\n\n\t\tprivate void ShowStateBefore_Click(object sender, RoutedEventArgs e)\n\t\t{\n\t\t\tStepper.Node n = (Stepper.Node)tree.SelectedItem;\n\t\t\tif (n == null)\n\t\t\t\treturn;\n\t\t\tDecompileAsync(n.BeginStep);\n\t\t}\n\n\t\tprivate void DebugStep_Click(object sender, RoutedEventArgs e)\n\t\t{\n\t\t\tStepper.Node n = (Stepper.Node)tree.SelectedItem;\n\t\t\tif (n == null)\n\t\t\t\treturn;\n\t\t\tDecompileAsync(n.BeginStep, true);\n\t\t}\n\n\t\tint lastSelectedStep = int.MaxValue;\n\n\t\tvoid DecompileAsync(int step, bool isDebug = false)\n\t\t{\n\t\t\tlastSelectedStep = step;\n\n\t\t\tif (dockWorkspace.ActiveTabPage.FrozenContent)\n\t\t\t{\n\t\t\t\tdockWorkspace.ActiveTabPage = dockWorkspace.AddTabPage();\n\t\t\t}\n\n\t\t\tvar state = dockWorkspace.ActiveTabPage.GetState();\n\t\t\tdockWorkspace.ActiveTabPage.ShowTextViewAsync(textView => textView.DecompileAsync(assemblyTreeModel.CurrentLanguage, assemblyTreeModel.SelectedNodes, null,\n\t\t\t\tnew DecompilationOptions(assemblyTreeModel.CurrentLanguageVersion, settingsService.DecompilerSettings, settingsService.DisplaySettings) {\n\t\t\t\t\tStepLimit = step,\n\t\t\t\t\tIsDebug = isDebug,\n\t\t\t\t\tTextViewState = state as TextView.DecompilerTextViewState\n\t\t\t\t}));\n\t\t}\n\n\t\tprivate void tree_KeyDown(object sender, KeyEventArgs e)\n\t\t{\n\t\t\tif (e.Key == Key.Enter || e.Key == Key.Return)\n\t\t\t{\n\t\t\t\tif (e.KeyboardDevice.Modifiers == ModifierKeys.Shift)\n\t\t\t\t\tShowStateBefore_Click(sender, e);\n\t\t\t\telse\n\t\t\t\t\tShowStateAfter_Click(sender, e);\n\t\t\t\te.Handled = true;\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Views/ManageAssemblyLIstsDialog.xaml.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Controls.Primitives;\n\nusing ICSharpCode.ILSpy.ViewModels;\n\nnamespace ICSharpCode.ILSpy\n{\n\t/// <summary>\n\t/// Interaction logic for ManageAssemblyListsDialog.xaml\n\t/// </summary>\n\tpublic partial class ManageAssemblyListsDialog : Window\n\t{\n\t\tpublic ManageAssemblyListsDialog(SettingsService settingsService)\n\t\t{\n\t\t\tInitializeComponent();\n\t\t\tDataContext = new ManageAssemblyListsViewModel(this, settingsService);\n\t\t}\n\n\t\tprivate void PreconfiguredAssemblyListsMenuClick(object sender, RoutedEventArgs e)\n\t\t{\n\t\t\tvar menu = (ContextMenu)Resources[\"PreconfiguredAssemblyListsMenu\"];\n\t\t\tmenu.PlacementTarget = (Button)sender;\n\t\t\tmenu.Placement = PlacementMode.Bottom;\n\t\t\tmenu.IsOpen = true;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/Views/ManageAssemblyListsDialog.xaml",
    "content": "<Window\n\tx:Class=\"ICSharpCode.ILSpy.ManageAssemblyListsDialog\" \n\txmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" \n\txmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" \n\txmlns:properties=\"clr-namespace:ICSharpCode.ILSpy.Properties\"\n\txmlns:b=\"http://schemas.microsoft.com/xaml/behaviors\"\n\tTitle=\"{x:Static properties:Resources.ManageAssemblyLists}\"\n\tStyle=\"{DynamicResource DialogWindow}\"\n\tWindowStartupLocation=\"CenterOwner\"\n\tResizeMode=\"CanResizeWithGrip\"\n\tMinWidth=\"480\"\n\tMinHeight=\"250\"\n\tHeight=\"350\"\n\tWidth=\"480\"\n\tFocusManager.FocusedElement=\"{Binding ElementName=listView}\">\n\t<Window.Resources>\n\t\t<ContextMenu x:Key=\"PreconfiguredAssemblyListsMenu\" ItemsSource=\"{Binding PreconfiguredAssemblyLists}\" DisplayMemberPath=\"Name\">\n\t\t\t<ContextMenu.ItemContainerStyle>\n\t\t\t\t<Style TargetType=\"MenuItem\">\n\t\t\t\t\t<Setter Property=\"Command\" Value=\"{Binding DataContext.CreatePreconfiguredAssemblyListCommand, RelativeSource={RelativeSource AncestorType=Window}}\" />\n\t\t\t\t\t<Setter Property=\"CommandParameter\" Value=\"{Binding}\" />\n\t\t\t\t</Style>\n\t\t\t</ContextMenu.ItemContainerStyle>\n\t\t</ContextMenu>\n\t</Window.Resources>\n\t<Grid Margin=\"12,8\">\n\t\t<Grid.RowDefinitions>\n\t\t\t<RowDefinition Height=\"*\" />\n\t\t\t<RowDefinition Height=\"Auto\" />\n\t\t</Grid.RowDefinitions>\n\t\t<Grid.ColumnDefinitions>\n\t\t\t<ColumnDefinition Width=\"*\" />\n\t\t\t<ColumnDefinition Width=\"*\" />\n\t\t\t<ColumnDefinition Width=\"*\" />\n\t\t\t<ColumnDefinition Width=\"*\" />\n\t\t\t<ColumnDefinition Width=\"Auto\" />\n\t\t</Grid.ColumnDefinitions>\n\t\t<ListBox Name=\"listView\" Margin=\"0 8\" Grid.ColumnSpan=\"4\" SelectedItem=\"{Binding SelectedAssemblyList}\"\n\t\t\t\t SelectionMode=\"Single\" ItemsSource=\"{Binding AssemblyLists}\">\n\t\t\t<b:Interaction.Triggers>\n\t\t\t\t<b:EventTrigger EventName=\"MouseDoubleClick\">\n\t\t\t\t\t<b:InvokeCommandAction Command=\"{Binding SelectAssemblyListCommand}\" />\n\t\t\t\t</b:EventTrigger>\n\t\t\t\t<b:KeyTrigger Key=\"Return\" FiredOn=\"KeyDown\">\n\t\t\t\t\t<b:InvokeCommandAction Command=\"{Binding SelectAssemblyListCommand}\" />\n\t\t\t\t</b:KeyTrigger>\n\t\t\t\t<b:KeyTrigger Key=\"Delete\" FiredOn=\"KeyDown\">\n\t\t\t\t\t<b:InvokeCommandAction Command=\"{Binding DeleteCommand}\" CommandParameter=\"{Binding ., RelativeSource={RelativeSource AncestorType=Window}}\" />\n\t\t\t\t</b:KeyTrigger>\n\t\t\t</b:Interaction.Triggers>\n\t\t</ListBox>\n\n\t\t<StackPanel Grid.Column=\"5\" Grid.RowSpan=\"2\" Margin=\"4, 8\">\n\t\t\t<Button Margin=\"2 2 2 10\" Command=\"{Binding NewCommand}\" CommandParameter=\"{Binding ., RelativeSource={RelativeSource AncestorType=Window}}\" Content=\"{x:Static properties:Resources._New}\"/>\n\t\t\t<Button Margin=\"2\" Command=\"{Binding CloneCommand}\" CommandParameter=\"{Binding ., RelativeSource={RelativeSource AncestorType=Window}}\" Content=\"{x:Static properties:Resources.C_lone}\"/>\n\t\t\t<Button Margin=\"2\" Command=\"{Binding RenameCommand}\" CommandParameter=\"{Binding ., RelativeSource={RelativeSource AncestorType=Window}}\" Content=\"{x:Static properties:Resources.R_ename}\"/>\n\t\t\t<Button Margin=\"2\" Command=\"{Binding DeleteCommand}\" CommandParameter=\"{Binding ., RelativeSource={RelativeSource AncestorType=Window}}\" Content=\"{x:Static properties:Resources.OpenListDialog__Delete}\"/>\n\t\t\t<Button Margin=\"2 10 2 2\" Command=\"{Binding ResetCommand}\" CommandParameter=\"{Binding ., RelativeSource={RelativeSource AncestorType=Window}}\" Content=\"{x:Static properties:Resources._Reset}\"/>\n\t\t</StackPanel>\n\n\t\t<Button IsCancel=\"True\" Grid.Row=\"2\" Margin=\"2,0\" Content=\"{x:Static properties:Resources.Close}\" />\n\t\t<Button Grid.Row=\"2\" Grid.Column=\"1\" Grid.ColumnSpan=\"2\" Margin=\"2,0\" Content=\"{x:Static properties:Resources.AddPreconfiguredList}\" Click=\"PreconfiguredAssemblyListsMenuClick\" />\n\t</Grid>\n</Window>"
  },
  {
    "path": "ILSpy/Views/OpenFromGacDialog.xaml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Window\n\tx:Class=\"ICSharpCode.ILSpy.OpenFromGacDialog\" \n\txmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" \n\txmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" \n\txmlns:controls=\"clr-namespace:ICSharpCode.ILSpy.Controls\"\n    xmlns:properties=\"clr-namespace:ICSharpCode.ILSpy.Properties\"\n\tTitle=\"{x:Static properties:Resources.OpenFrom}\"\n\tStyle=\"{DynamicResource DialogWindow}\"\n\tWindowStartupLocation=\"CenterOwner\"\n\tResizeMode=\"CanResizeWithGrip\"\n\tMinWidth=\"200\"\n\tMinHeight=\"150\"\n\tHeight=\"350\"\n\tWidth=\"750\"\n\tFocusManager.FocusedElement=\"{Binding ElementName=filterTextBox}\">\n\t<Grid\n\t\tMargin=\"12,8\">\n\t\t<Grid.RowDefinitions>\n\t\t\t<RowDefinition\n\t\t\t\tHeight=\"Auto\" />\n\t\t\t<RowDefinition\n\t\t\t\tHeight=\"1*\" />\n\t\t\t<RowDefinition\n\t\t\t\tHeight=\"Auto\" />\n\t\t</Grid.RowDefinitions>\n\t\t<DockPanel>\n\t\t\t<Label DockPanel.Dock=\"Left\" Target=\"{Binding ElementName=filterTextBox}\" Content=\"{x:Static properties:Resources._Search}\"/>\n\t\t\t<TextBox Name=\"filterTextBox\" TextChanged=\"FilterTextBox_TextChanged\" />\n\t\t</DockPanel>\n\t\t<ListView Name=\"listView\" Grid.Row=\"1\" Margin=\"0, 8\" controls:SortableGridViewColumn.SortMode=\"Automatic\" SelectionChanged=\"ListView_SelectionChanged\">\n\t\t\t<ListView.View>\n\t\t\t\t<GridView>\n\t\t\t\t\t<controls:SortableGridViewColumn x:Name=\"nameColumn\" Width=\"300\" Header=\"{x:Static properties:Resources.ReferenceName}\" DisplayMemberBinding=\"{Binding ShortName}\" />\n\t\t\t\t\t<controls:SortableGridViewColumn Width=\"75\" Header=\"{x:Static properties:Resources.Version}\" DisplayMemberBinding=\"{Binding Version}\" />\n\t\t\t\t\t<controls:SortableGridViewColumn Width=\"65\" Header=\"{x:Static properties:Resources.CultureLabel}\" DisplayMemberBinding=\"{Binding Culture}\" />\n\t\t\t\t\t<controls:SortableGridViewColumn Width=\"115\" Header=\"{x:Static properties:Resources.PublicToken}\" DisplayMemberBinding=\"{Binding PublicKeyToken}\" />\n\t\t\t\t\t<controls:SortableGridViewColumn Width=\"1000\" Header=\"{x:Static properties:Resources.Location}\" DisplayMemberBinding=\"{Binding FileName}\" />\n\t\t\t\t</GridView>\n\t\t\t</ListView.View>\n\t\t</ListView>\n\t\t<StackPanel Grid.Row=\"2\" Orientation=\"Horizontal\" HorizontalAlignment=\"Right\">\n\t\t\t<Button IsDefault=\"True\" Margin=\"2,0\" IsEnabled=\"False\" Name=\"okButton\" Click=\"OKButton_Click\" Content=\"{x:Static properties:Resources.OpenListDialog__Open}\"/>\n\t\t\t<Button IsCancel=\"True\" Margin=\"2,0\" Content=\"{x:Static properties:Resources.Cancel}\"/>\n\t\t</StackPanel>\n\t\t<ProgressBar Grid.Row=\"1\" Height=\"10\" HorizontalAlignment=\"Stretch\" Name=\"gacReadingProgressBar\" VerticalAlignment=\"Bottom\" Visibility=\"Hidden\" />\n\t</Grid>\n</Window>"
  },
  {
    "path": "ILSpy/Views/OpenFromGacDialog.xaml.cs",
    "content": "// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Text;\nusing System.Threading;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Threading;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.Controls;\nusing ICSharpCode.ILSpyX.Extensions;\n\nusing TomsToolbox.Essentials;\n\nnamespace ICSharpCode.ILSpy\n{\n\t/// <summary>\n\t/// Interaction logic for OpenFromGacDialog.xaml\n\t/// </summary>\n\tpublic partial class OpenFromGacDialog : Window\n\t{\n\t\tObservableCollection<GacEntry> gacEntries = new ObservableCollection<GacEntry>();\n\t\tObservableCollection<GacEntry> filteredEntries = new ObservableCollection<GacEntry>();\n\t\tPredicate<GacEntry> filterMethod = _ => true;\n\t\tvolatile bool cancelFetchThread;\n\n\t\tpublic OpenFromGacDialog()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t\tlistView.ItemsSource = filteredEntries;\n\t\t\tSortableGridViewColumn.SetCurrentSortColumn(listView, nameColumn);\n\t\t\tSortableGridViewColumn.SetSortDirection(listView, ColumnSortDirection.Ascending);\n\n\t\t\tnew Thread(new ThreadStart(FetchGacContents)).Start();\n\t\t}\n\n\t\tprotected override void OnClosing(CancelEventArgs e)\n\t\t{\n\t\t\tbase.OnClosing(e);\n\t\t\tcancelFetchThread = true;\n\t\t}\n\n\t\t#region Fetch Gac Contents\n\t\tsealed class GacEntry\n\t\t{\n\t\t\treadonly AssemblyNameReference r;\n\t\t\treadonly string fileName;\n\t\t\tstring formattedVersion;\n\n\t\t\tpublic GacEntry(AssemblyNameReference r, string fileName)\n\t\t\t{\n\t\t\t\tthis.r = r;\n\t\t\t\tthis.fileName = fileName;\n\t\t\t}\n\n\t\t\tpublic string FullName {\n\t\t\t\tget { return r.FullName; }\n\t\t\t}\n\n\t\t\tpublic string ShortName {\n\t\t\t\tget { return r.Name; }\n\t\t\t}\n\n\t\t\tpublic string FileName {\n\t\t\t\tget { return fileName; }\n\t\t\t}\n\n\t\t\tpublic Version Version {\n\t\t\t\tget { return r.Version; }\n\t\t\t}\n\n\t\t\tpublic string FormattedVersion {\n\t\t\t\tget {\n\t\t\t\t\tif (formattedVersion == null)\n\t\t\t\t\t\tformattedVersion = Version.ToString();\n\t\t\t\t\treturn formattedVersion;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic string Culture {\n\t\t\t\tget {\n\t\t\t\t\tif (string.IsNullOrEmpty(r.Culture))\n\t\t\t\t\t\treturn \"neutral\";\n\t\t\t\t\treturn r.Culture;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic string PublicKeyToken {\n\t\t\t\tget {\n\t\t\t\t\tStringBuilder s = new StringBuilder();\n\t\t\t\t\tforeach (byte b in r.PublicKeyToken)\n\t\t\t\t\t\ts.Append(b.ToString(\"x2\"));\n\t\t\t\t\treturn s.ToString();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpublic override string ToString()\n\t\t\t{\n\t\t\t\treturn r.FullName;\n\t\t\t}\n\t\t}\n\n\t\tvoid FetchGacContents()\n\t\t{\n\t\t\tHashSet<string> fullNames = new HashSet<string>();\n\t\t\tUpdateProgressBar(pg => { pg.Visibility = Visibility.Visible; pg.IsIndeterminate = true; });\n\t\t\tvar list = UniversalAssemblyResolver.EnumerateGac().TakeWhile(_ => !cancelFetchThread).ToList();\n\t\t\tUpdateProgressBar(pg => { pg.IsIndeterminate = false; pg.Maximum = list.Count; });\n\t\t\tforeach (var r in list)\n\t\t\t{\n\t\t\t\tif (cancelFetchThread)\n\t\t\t\t\tbreak;\n\t\t\t\tif (fullNames.Add(r.FullName))\n\t\t\t\t{ // filter duplicates\n\t\t\t\t\tvar file = UniversalAssemblyResolver.GetAssemblyInGac(r);\n\t\t\t\t\tif (file != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar entry = new GacEntry(r, file);\n\t\t\t\t\t\tUpdateProgressBar(pg => { pg.Value++; AddNewEntry(entry); });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tUpdateProgressBar(pg => { pg.Visibility = Visibility.Hidden; });\n\t\t}\n\n\t\tvoid UpdateProgressBar(Action<ProgressBar> updateAction)\n\t\t{\n\t\t\tDispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() => updateAction(gacReadingProgressBar)));\n\t\t}\n\n\t\tvoid AddNewEntry(GacEntry entry)\n\t\t{\n\t\t\tgacEntries.Add(entry);\n\t\t\tif (filterMethod(entry))\n\t\t\t\tfilteredEntries.Add(entry);\n\t\t}\n\t\t#endregion\n\n\t\tvoid FilterTextBox_TextChanged(object sender, TextChangedEventArgs e)\n\t\t{\n\t\t\tstring filterString = filterTextBox.Text.Trim();\n\t\t\tif (filterString.Length == 0)\n\t\t\t\tfilterMethod = _ => true;\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar elements = filterString.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);\n\t\t\t\tfilterMethod = entry => elements.All(el => Contains(entry.FullName, el) || Contains(entry.FormattedVersion, el));\n\t\t\t}\n\n\t\t\tfilteredEntries.Clear();\n\t\t\tfilteredEntries.AddRange(gacEntries.Where(entry => filterMethod(entry)));\n\t\t}\n\n\t\tstatic bool Contains(string s, string subString)\n\t\t{\n\t\t\treturn s.IndexOf(subString, StringComparison.OrdinalIgnoreCase) >= 0;\n\t\t}\n\n\t\tvoid ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)\n\t\t{\n\t\t\tokButton.IsEnabled = listView.SelectedItems.Count > 0;\n\t\t}\n\n\t\tvoid OKButton_Click(object sender, RoutedEventArgs e)\n\t\t{\n\t\t\tthis.DialogResult = true;\n\t\t\tClose();\n\t\t}\n\n\t\tpublic string[] SelectedFileNames {\n\t\t\tget {\n\t\t\t\treturn listView.SelectedItems.OfType<GacEntry>().Select(e => e.FileName).ToArray();\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy/Views/UpdatePanel.xaml",
    "content": "<UserControl x:Class=\"ICSharpCode.ILSpy.Views.UpdatePanel\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" \n             xmlns:viewModels=\"clr-namespace:ICSharpCode.ILSpy.ViewModels\"\n             xmlns:toms=\"urn:TomsToolbox\"\n             mc:Ignorable=\"d\" d:DesignWidth=\"500\" d:DataContext=\"{d:DesignInstance viewModels:UpdatePanelViewModel}\">\n\t<Border BorderBrush=\"Black\" BorderThickness=\"1\" Visibility=\"{Binding IsPanelVisible, Converter={toms:BooleanToVisibilityConverter} }\">\n\t\t<DockPanel KeyboardNavigation.TabNavigation=\"Contained\">\n\t\t\t<Button DockPanel.Dock=\"Right\" MinWidth=\"0\" Command=\"{Binding CloseCommand}\" Content=\"X\" />\n\t\t\t<StackPanel Orientation=\"Horizontal\">\n\t\t\t\t<StackPanel Orientation=\"Horizontal\">\n\t\t\t\t\t<TextBlock Margin=\"4,0\" VerticalAlignment=\"Center\"\n \t\t\t\t               Text=\"{Binding Message}\" />\n\t\t\t\t\t<Button Content=\"{Binding ButtonText}\" \n\t\t\t\t\t        Command=\"{Binding DownloadOrCheckUpdateCommand}\"/>\n\t\t\t\t</StackPanel>\n\t\t\t</StackPanel>\n\t\t</DockPanel>\n\t</Border>\n</UserControl>\n"
  },
  {
    "path": "ILSpy/Views/UpdatePanel.xaml.cs",
    "content": "// Copyright (c) 2024 Tom Englert for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\n\nusing ICSharpCode.ILSpy.ViewModels;\n\nusing TomsToolbox.Wpf.Composition.AttributedModel;\n\nnamespace ICSharpCode.ILSpy.Views\n{\n\t/// <summary>\n\t/// Interaction logic for UpdatePanel.xaml\n\t/// </summary>\n\t[DataTemplate(typeof(UpdatePanelViewModel))]\n\t[NonShared]\n\tpublic partial class UpdatePanel\n\t{\n\t\tpublic UpdatePanel()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy/app.manifest",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<assembly manifestVersion=\"1.0\" xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n\t<assemblyIdentity version=\"1.0.0.0\" name=\"MyApplication.app\"/>\n\t<trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v2\">\n\t\t<security>\n\t\t\t<requestedPrivileges xmlns=\"urn:schemas-microsoft-com:asm.v3\">\n\t\t\t\t<!-- UAC Manifest Options\n             If you want to change the Windows User Account Control level replace the \n             requestedExecutionLevel node with one of the following.\n\n        <requestedExecutionLevel  level=\"asInvoker\" uiAccess=\"false\" />\n        <requestedExecutionLevel  level=\"requireAdministrator\" uiAccess=\"false\" />\n        <requestedExecutionLevel  level=\"highestAvailable\" uiAccess=\"false\" />\n\n            Specifying requestedExecutionLevel element will disable file and registry virtualization. \n            Remove this element if your application requires this virtualization for backwards\n            compatibility.\n        -->\n\t\t\t\t<requestedExecutionLevel level=\"asInvoker\" uiAccess=\"false\" />\n\t\t\t</requestedPrivileges>\n\t\t</security>\n\t</trustInfo>\n\n\t<compatibility xmlns=\"urn:schemas-microsoft-com:compatibility.v1\">\n\t\t<application>\n\t\t\t<!-- A list of the Windows versions that this application has been tested on and is\n           is designed to work with. Uncomment the appropriate elements and Windows will \n           automatically selected the most compatible environment. -->\n\n\t\t\t<!-- Windows Vista -->\n\t\t\t<!--<supportedOS Id=\"{e2011457-1546-43c5-a5fe-008deee3d3f0}\" />-->\n\n\t\t\t<!-- Windows 7 -->\n\t\t\t<!--<supportedOS Id=\"{35138b9a-5d96-4fbd-8e2d-a2440225f93a}\" />-->\n\n\t\t\t<!-- Windows 8 -->\n\t\t\t<!--<supportedOS Id=\"{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}\" />-->\n\n\t\t\t<!-- Windows 8.1 -->\n\t\t\t<!--<supportedOS Id=\"{1f676c76-80e1-4239-95bb-83d0f6d0da78}\" />-->\n\n\t\t\t<!-- Windows 10 -->\n\t\t\t<!--<supportedOS Id=\"{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}\" />-->\n\n\t\t</application>\n\t</compatibility>\n\n\t<!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher\n       DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need \n       to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should \n       also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. -->\n\t<application xmlns=\"urn:schemas-microsoft-com:asm.v3\">\n\t\t<windowsSettings>\n\t\t\t<!-- Enable per-monitor DPI awareness: https://github.com/Microsoft/WPF-Samples/tree/master/PerMonitorDPI -->\n\t\t\t<dpiAwareness xmlns=\"http://schemas.microsoft.com/SMI/2016/WindowsSettings\">PerMonitorV2, PerMonitor</dpiAwareness>\n\t\t\t<dpiAware xmlns=\"http://schemas.microsoft.com/SMI/2005/WindowsSettings\">True</dpiAware>\n\n\t\t\t<!-- Enable long path support: https://blogs.msdn.microsoft.com/jeremykuhne/2016/07/30/net-4-6-2-and-long-paths-on-windows-10/ -->\n\t\t\t<longPathAware xmlns=\"http://schemas.microsoft.com/SMI/2016/WindowsSettings\">True</longPathAware>\n\t\t</windowsSettings>\n\t</application>\n\n\t<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->\n\t<dependency>\n\t\t<dependentAssembly>\n\t\t\t<assemblyIdentity\n\t\t\t\ttype=\"win32\"\n\t\t\t\tname=\"Microsoft.Windows.Common-Controls\"\n\t\t\t\tversion=\"6.0.0.0\"\n\t\t\t\tprocessorArchitecture=\"*\"\n\t\t\t\tpublicKeyToken=\"6595b64144ccf1df\"\n\t\t\t\tlanguage=\"*\"\n        />\n\t\t</dependentAssembly>\n\t</dependency>\n\n</assembly>\n"
  },
  {
    "path": "ILSpy.AddIn/Decompiler/Dummy.cs",
    "content": "// Dummy types so that we can use compile some ICS.Decompiler classes in the AddIn context\n// without depending on SRM etc.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler\n{\n\tpublic class ReferenceLoadInfo\n\t{\n\t\tpublic void AddMessage(params object[] args) { }\n\t}\n\n\tenum MessageKind { Warning }\n\n\tpublic static class MetadataExtensions\n\t{\n\t\tpublic static string ToHexString(this IEnumerable<byte> bytes, int estimatedLength)\n\t\t{\n\t\t\tif (bytes == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(bytes));\n\n\t\t\tStringBuilder sb = new StringBuilder(estimatedLength * 2);\n\t\t\tforeach (var b in bytes)\n\t\t\t\tsb.AppendFormat(\"{0:x2}\", b);\n\t\t\treturn sb.ToString();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.AddIn/ILSpy.AddIn.csproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project>\r\n  <Import Sdk=\"Microsoft.NET.Sdk\" Project=\"Sdk.props\" />\r\n\r\n  <PropertyGroup>\r\n    <TargetFramework>net472</TargetFramework>\r\n    <RootNamespace>ICSharpCode.ILSpy.AddIn</RootNamespace>\r\n\r\n    <Company>IC#Code</Company>\r\n    <Description>ILSpy</Description>\r\n    <Version>1.7.1.0</Version>\r\n    <FileVersion>1.7.1.0</FileVersion>\r\n    <LangVersion>9.0</LangVersion>\r\n\r\n    <EnableDefaultItems>False</EnableDefaultItems>\r\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\r\n    <DefineConstants>TRACE;VSADDIN</DefineConstants>\r\n\r\n    <SignAssembly>True</SignAssembly>\r\n    <AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile>\r\n    <NoWarn>\r\n      MSB3277;<!-- this is due to Visual Studio package references weirdness, see https://github.com/dotnet/roslyn/discussions/49787 -->\r\n      VSSDK1009\r\n    </NoWarn>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Debug'\">\r\n    <DebugType>full</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\r\n    <DebugType>pdbonly</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <Reference Include=\"Microsoft.CSharp\" />\r\n    <Reference Include=\"System.Design\" />\r\n  </ItemGroup>\r\n\r\n  <PropertyGroup>\r\n    <ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"Microsoft.VisualStudio.SDK\" Version=\"15.0.1\" />\r\n    <!-- Intentionally using an old Roslyn version in the AddIn, so that we stay compatible with old VS versions. -->\r\n    <PackageReference Include=\"Microsoft.CodeAnalysis\" Version=\"2.4.0\" />\r\n    <PackageReference Include=\"Microsoft.CodeAnalysis.CSharp\" Version=\"2.4.0\" />\r\n    <PackageReference Include=\"Microsoft.VisualStudio.LanguageServices\" Version=\"2.4.0\" />\r\n    <PackageReference Include=\"Microsoft.VSSDK.BuildTools\" Version=\"17.6.2164\">\r\n      <PrivateAssets>all</PrivateAssets>\r\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\r\n    </PackageReference>\r\n    <PackageReference Include=\"Mono.Cecil\" Version=\"0.11.5\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"TunnelVisionLabs.ReferenceAssemblyAnnotator\" Version=\"1.0.0-alpha.160\" PrivateAssets=\"all\" />\r\n\r\n    <!-- Specifies the version of Microsoft.NETCore.App.Ref to obtain nullability information from. -->\r\n    <PackageDownload Include=\"Microsoft.NETCore.App.Ref\" Version=\"[8.0.0]\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\AssemblyReferences.cs\" Link=\"Decompiler\\AssemblyReferences.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\DotNetCorePathFinder.cs\" Link=\"Decompiler\\DotNetCorePathFinder.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\LightJson\\JsonArray.cs\" Link=\"Decompiler\\LightJson\\JsonArray.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\LightJson\\JsonObject.cs\" Link=\"Decompiler\\LightJson\\JsonObject.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\LightJson\\JsonValue.cs\" Link=\"Decompiler\\LightJson\\JsonValue.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\LightJson\\JsonValueType.cs\" Link=\"Decompiler\\LightJson\\JsonValueType.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\LightJson\\Serialization\\JsonParseException.cs\" Link=\"Decompiler\\LightJson\\Serialization\\JsonParseException.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\LightJson\\Serialization\\JsonReader.cs\" Link=\"Decompiler\\LightJson\\Serialization\\JsonReader.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\LightJson\\Serialization\\TextPosition.cs\" Link=\"Decompiler\\LightJson\\Serialization\\TextPosition.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\LightJson\\Serialization\\TextScanner.cs\" Link=\"Decompiler\\LightJson\\Serialization\\TextScanner.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\UniversalAssemblyResolver.cs\" Link=\"UniversalAssemblyResolver.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Util\\EmptyList.cs\" Link=\"Decompiler\\EmptyList.cs\" />\r\n    <Compile Include=\"Decompiler\\Dummy.cs\" />\r\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\r\n  </ItemGroup>\r\n\r\n  <PropertyGroup>\r\n    <ILSpyBuildPath>..\\ILSpy\\bin\\$(Configuration)\\net10.0-windows\\win-x64\\publish\\fwdependent\\</ILSpyBuildPath>\r\n  </PropertyGroup>\r\n\r\n  <Target Name=\"IncludeILSpyDistributionInVSIXSubFolder\" AfterTargets=\"ResolveProjectReferences\">\r\n    <ItemGroup>\r\n      <VSIXSourceItem Include=\"$(ILSpyBuildPath)*.dll;$(ILSpyBuildPath)ILSpy.exe;$(ILSpyBuildPath)*.json\">\r\n        <VSIXSubPath>\\x64\\ILSpy</VSIXSubPath>\r\n      </VSIXSourceItem>\r\n    </ItemGroup>\r\n  </Target>\r\n\r\n  <ItemGroup>\r\n    <Content Include=\"$(OutputPath)Mono.Cecil.dll\">\r\n      <IncludeInVSIX>true</IncludeInVSIX>\r\n      <VSIXSubPath>\\</VSIXSubPath>\r\n    </Content>\r\n    <Content Include=\"ILSpy-Large.ico\">\r\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\r\n      <IncludeInVSIX>true</IncludeInVSIX>\r\n    </Content>\r\n    <Content Include=\"Resources\\Images.png\" />\r\n    <Content Include=\"Resources\\Package.ico\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <None Include=\"ILSpyAddIn.en-US.vsct\">\r\n      <SubType>Designer</SubType>\r\n    </None>\r\n    <None Include=\"ILSpyAddIn.vsct\">\r\n      <SubType>Designer</SubType>\r\n    </None>\r\n    <None Include=\"source.extension.vsixmanifest.template\" />\r\n    <None Include=\"source.extension.vsixmanifest\">\r\n      <SubType>Designer</SubType>\r\n    </None>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <VSCTCompile Include=\"ILSpyAddIn.en-US.vsct\">\r\n      <ResourceName>Menus.ctmenu</ResourceName>\r\n      <SubType>Designer</SubType>\r\n      <DependentUpon>ILSpyAddIn.vsct</DependentUpon>\r\n    </VSCTCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"Key.snk\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <None Include=\"Properties\\launchSettings.json\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <Content Include=\"..\\LICENSE\" Link=\"license.txt\">\r\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\r\n      <IncludeInVSIX>true</IncludeInVSIX>\r\n    </Content>\r\n  </ItemGroup>\r\n\r\n  <PropertyGroup>\r\n    <UseCodebase>true</UseCodebase>\r\n    <RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild>\r\n    <RunAnalyzersDuringLiveAnalysis>true</RunAnalyzersDuringLiveAnalysis>\r\n    <Product>ILSpy.AddIn for Visual Studio 2017/2019</Product>\r\n  </PropertyGroup>\r\n\r\n  <Import Project=\"..\\ILSpy.AddIn.Shared\\ILSpy.AddIn.Shared.projitems\" Label=\"Shared\" />\r\n\r\n  <Import Sdk=\"Microsoft.NET.Sdk\" Project=\"Sdk.targets\" />\r\n\r\n  <Import Project=\"$(VSToolsPath)\\VSSDK\\Microsoft.VsSDK.targets\" Condition=\"Exists('$(VSToolsPath)\\VSSDK\\Microsoft.VsSDK.targets')\" />\r\n\r\n  <ItemGroup>\r\n    <Compile Update=\"..\\ILSpy.AddIn.Shared\\Resources.Designer.cs\">\r\n      <DesignTime>True</DesignTime>\r\n    </Compile>\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <Folder Include=\"Resources\\\" />\r\n  </ItemGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "ILSpy.AddIn/ILSpyAddIn.en-US.vsct",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<CommandTable xmlns=\"http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n\n  <!--  This is the file that defines the actual layout and type of the commands.\n        It is divided in different sections (e.g. command definition, command\n        placement, ...), with each defining a specific set of properties.\n        See the comment before each section for more details about how to\n        use it. -->\n\n  <!--  The VSCT compiler (the tool that translates this file into the binary \n        format that VisualStudio will consume) has the ability to run a preprocessor \n        on the vsct file; this preprocessor is (usually) the C++ preprocessor, so \n        it is possible to define includes and macros with the same syntax used \n        in C++ files. Using this ability of the compiler here, we include some files \n        defining some of the constants that we will use inside the file. -->\n\n  <!--This is the file that defines the IDs for all the commands exposed by VisualStudio. -->\n  <Extern href=\"stdidcmd.h\"/>\n\n  <!--This header contains the command ids for the menus provided by the shell. -->\n  <Extern href=\"vsshlids.h\"/>\n\n\n  <Include href=\"ILSpyAddIn.vsct\" />\n\n  <!--The Commands section is where we the commands, menus and menu groups are defined.\n      This section uses a Guid to identify the package that provides the command defined inside it. -->\n  <Commands package=\"guidILSpyAddInPkg\">\n    <!-- Inside this section we have different sub-sections: one for the menus, another  \n    for the menu groups, one for the buttons (the actual commands), one for the combos \n    and the last one for the bitmaps used. Each element is identified by a command id that  \n    is a unique pair of guid and numeric identifier; the guid part of the identifier is usually  \n    called \"command set\" and is used to group different command inside a logically related  \n    group; your package should define its own command set in order to avoid collisions  \n    with command ids defined by other packages. -->\n\n    \n    <!--Buttons section. -->\n    <!--This section defines the elements the user can interact with, like a menu command or a button \n        or combo box in a toolbar. -->\n    <Buttons>\n      <!--To define a menu group you have to specify its ID, the parent menu and its display priority. \n          The command is visible and enabled by default. If you need to change the visibility, status, etc, you can use\n          the CommandFlag node.\n          You can add more than one CommandFlag node e.g.:\n              <CommandFlag>DefaultInvisible</CommandFlag>\n              <CommandFlag>DynamicVisibility</CommandFlag>\n          If you do not want an image next to your command, remove the Icon node /> -->\n\n      <Button guid=\"guidILSpyAddInCmdSet\" id=\"cmdidOpenReferenceInILSpy\" priority=\"0x0600\" type=\"Button\">\n        <Parent guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyRefGroup\" />\n        <Icon guid=\"guidImages\" id=\"bmpLogo\" />\n        <CommandFlag>DynamicVisibility</CommandFlag>\n        <CommandFlag>DefaultInvisible</CommandFlag>\n        <Strings>\n          <ButtonText>Open in ILSpy</ButtonText>\n        </Strings>\n      </Button>\n      \n      <Button guid=\"guidILSpyAddInCmdSet\" id=\"cmdidOpenProjectOutputInILSpy\" priority=\"0x0600\" type=\"Button\">\n        <Parent guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyProjGroup\" />\n        <Icon guid=\"guidImages\" id=\"bmpLogo\" />\n        <CommandFlag>DynamicVisibility</CommandFlag>\n        <CommandFlag>DefaultInvisible</CommandFlag>\n        <Strings>\n          <ButtonText>Open output in ILSpy</ButtonText>\n        </Strings>\n      </Button>\n\n      <Button guid=\"guidILSpyAddInCmdSet\" id=\"cmdidOpenCodeItemInILSpy\" priority=\"0x0600\" type=\"Button\">\n        <Parent guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyCodeItemGroup\" />\n        <Icon guid=\"guidImages\" id=\"bmpLogo\" />\n        <CommandFlag>DynamicVisibility</CommandFlag>\n        <CommandFlag>DefaultInvisible</CommandFlag>\n        <Strings>\n          <ButtonText>Open code in ILSpy</ButtonText>\n        </Strings>\n      </Button>\n\n      <Button guid=\"guidILSpyAddInCmdSet\" id=\"cmdidOpenILSpy\" priority=\"0x0600\" type=\"Button\">\n        <Parent guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyGroup\" />\n        <Icon guid=\"guidImages\" id=\"bmpLogo\" />\n        <Strings>\n          <ButtonText>ILSpy</ButtonText>\n        </Strings>\n      </Button>\n    </Buttons>\n  </Commands>\n</CommandTable>\n"
  },
  {
    "path": "ILSpy.AddIn/ILSpyAddIn.vsct",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<CommandTable xmlns=\"http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n\n  <!--  This is the file that defines the actual layout and type of the commands.\n        It is divided in different sections (e.g. command definition, command\n        placement, ...), with each defining a specific set of properties.\n        See the comment before each section for more details about how to\n        use it. -->\n\n  <!--  The VSCT compiler (the tool that translates this file into the binary \n        format that VisualStudio will consume) has the ability to run a preprocessor \n        on the vsct file; this preprocessor is (usually) the C++ preprocessor, so \n        it is possible to define includes and macros with the same syntax used \n        in C++ files. Using this ability of the compiler here, we include some files \n        defining some of the constants that we will use inside the file. -->\n\n  <!--This is the file that defines the IDs for all the commands exposed by VisualStudio. -->\n  <Extern href=\"stdidcmd.h\"/>\n\n  <!--This header contains the command ids for the menus provided by the shell. -->\n  <Extern href=\"vsshlids.h\"/>\n\n  <!--The Commands section is where we the commands, menus and menu groups are defined.\n      This section uses a Guid to identify the package that provides the command defined inside it. -->\n  <Commands package=\"guidILSpyAddInPkg\">\n    <!-- Inside this section we have different sub-sections: one for the menus, another  \n    for the menu groups, one for the buttons (the actual commands), one for the combos \n    and the last one for the bitmaps used. Each element is identified by a command id that  \n    is a unique pair of guid and numeric identifier; the guid part of the identifier is usually  \n    called \"command set\" and is used to group different command inside a logically related  \n    group; your package should define its own command set in order to avoid collisions  \n    with command ids defined by other packages. -->\n\n\n    <!-- In this section you can define new menu groups. A menu group is a container for \n         other menus or buttons (commands); from a visual point of view you can see the \n         group as the part of a menu contained between two lines. The parent of a group \n         must be a menu. -->\n    <Groups>\n      <Group guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyGroup\" priority=\"0x0200\">\n        <Parent guid=\"guidSHLMainMenu\" id=\"IDM_VS_MENU_TOOLS\"/>\n      </Group>\n\n      <Group guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyProjGroup\" priority=\"0x0200\">\n        <Parent guid=\"guidSHLMainMenu\" id=\"IDM_VS_CTXT_PROJNODE\"/>\n      </Group>\n\n      <Group guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyCodeItemGroup\" priority=\"0x0200\">\n        <Parent guid=\"guidSHLMainMenu\" id=\"IDM_VS_CTXT_CODEWIN\"/>\n      </Group>\n\n      <Group guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyRefGroup\" priority=\"0x0200\">\n        <Parent guid=\"guidSHLMainMenu\" id=\"IDM_VS_CTXT_REFERENCE\"/>\n      </Group>\n    </Groups>\n\n    <!--The bitmaps section is used to define the bitmaps that are used for the commands.-->\n    <Bitmaps>\n      <!--  The bitmap id is defined in a way that is a little bit different from the others: \n            the declaration starts with a guid for the bitmap strip, then there is the resource id of the \n            bitmap strip containing the bitmaps and then there are the numeric ids of the elements used \n            inside a button definition. An important aspect of this declaration is that the element id \n            must be the actual index (1-based) of the bitmap inside the bitmap strip. -->\n      <Bitmap guid=\"guidImages\" href=\"Resources\\Images.png\" usedList=\"bmpLogo, bmpPic1, bmpPic2, bmpPicX, bmpPicArrows\"/>\n    </Bitmaps>\n  </Commands>\n  <CommandPlacements>\n    <CommandPlacement guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyRefGroup\" priority=\"0x0200\">\n      <Parent guid=\"guidSHLMainMenu\" id=\"IDM_VS_CTXT_PACKAGEREFERENCE\"/>\n    </CommandPlacement>\n    <CommandPlacement guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyRefGroup\" priority=\"0x0200\">\n      <Parent guid=\"guidSHLMainMenu\" id=\"IDM_VS_CTXT_PROJECTREFERENCE\"/>\n    </CommandPlacement>\n  </CommandPlacements>\n  <Symbols>\n    <!-- This is the package guid. -->\n    <GuidSymbol name=\"guidILSpyAddInPkg\" value=\"{a9120dbe-164a-4891-842f-fb7829273838}\" />\n\n    <!-- This is the guid used to group the menu commands together -->\n    <GuidSymbol name=\"guidILSpyAddInCmdSet\" value=\"{85ddb8ca-a842-4b1c-ba1a-94141fdf19d0}\">\n\n      <IDSymbol name=\"OpenILSpyGroup\" value=\"0x1010\" />\n      <IDSymbol name=\"OpenILSpyRefGroup\" value=\"0x1020\" />\n      <IDSymbol name=\"OpenILSpyProjGroup\" value=\"0x1030\" />\n      <IDSymbol name=\"OpenILSpyCodeItemGroup\" value=\"0x1040\" />\n      <IDSymbol name=\"OpenILSpyPackageRefGroup\" value=\"0x1050\" />\n      <IDSymbol name=\"OpenILSpyProjectRefGroup\" value=\"0x1060\" />\n      <IDSymbol name=\"cmdidOpenILSpy\" value=\"0x0100\" />\n      <IDSymbol name=\"cmdidOpenReferenceInILSpy\" value=\"0x0200\" />\n      <IDSymbol name=\"cmdidOpenProjectOutputInILSpy\" value=\"0x0300\" />\n      <IDSymbol name=\"cmdidOpenCodeItemInILSpy\" value=\"0x0400\" />\n    </GuidSymbol>\n\n    <GuidSymbol name=\"guidImages\" value=\"{2f654db9-4641-4638-9937-27c6202b2a6a}\" >\n      <IDSymbol name=\"bmpLogo\" value=\"1\" />\n      <IDSymbol name=\"bmpPic1\" value=\"2\" />\n      <IDSymbol name=\"bmpPic2\" value=\"3\" />\n      <IDSymbol name=\"bmpPicX\" value=\"4\" />\n      <IDSymbol name=\"bmpPicArrows\" value=\"5\" />\n      <IDSymbol name=\"bmpPicStrikethrough\" value=\"6\" />\n    </GuidSymbol>\n\n    <GuidSymbol name=\"guidReferenceContext\" value=\"{D309F791-903F-11D0-9EFC-00A0C911004F}\">\n      <IDSymbol name=\"IDM_VS_CTXT_PACKAGEREFERENCE\" value=\"0x04A3\"/>\n      <IDSymbol name=\"IDM_VS_CTXT_PROJECTREFERENCE\" value=\"0x04A7\"/>\n    </GuidSymbol>\n  </Symbols>\n\n</CommandTable>\n"
  },
  {
    "path": "ILSpy.AddIn/Properties/AssemblyInfo.cs",
    "content": "using System;\nusing System.Reflection;\nusing System.Resources;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyCopyright(\"\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n[assembly: ComVisible(false)]\n[assembly: CLSCompliant(false)]\n[assembly: NeutralResourcesLanguage(\"en-US\", UltimateResourceFallbackLocation.Satellite)]\n[assembly: InternalsVisibleTo(\"ILSpy.AddIn_IntegrationTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100653c4a319be4f524972c3c5bba5fd243330f8e900287d9022d7821a63fd0086fd3801e3683dbe9897f2ecc44727023e9b40adcf180730af70c81c54476b3e5ba8b0f07f5132b2c3cc54347a2c1a9d64ebaaaf3cbffc1a18c427981e2a51d53d5ab02536b7550e732f795121c38a0abfdb38596353525d034baf9e6f1fd8ac4ac\")]\n[assembly: InternalsVisibleTo(\"ILSpy.AddIn_UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100653c4a319be4f524972c3c5bba5fd243330f8e900287d9022d7821a63fd0086fd3801e3683dbe9897f2ecc44727023e9b40adcf180730af70c81c54476b3e5ba8b0f07f5132b2c3cc54347a2c1a9d64ebaaaf3cbffc1a18c427981e2a51d53d5ab02536b7550e732f795121c38a0abfdb38596353525d034baf9e6f1fd8ac4ac\")]\n"
  },
  {
    "path": "ILSpy.AddIn/Properties/launchSettings.json",
    "content": "{\n\t\"profiles\": {\n\t\t\"Visual Studio Extension\": {\n\t\t\t\"executablePath\": \"$(DevEnvDir)devenv.exe\",\n\t\t\t\"commandLineArgs\": \"/rootsuffix $(VSSDKTargetPlatformRegRootSuffix) /log\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.AddIn/README.md",
    "content": "Test cases for various types of projects as well as corresponding test plans are located in a separate repository.\n\n[https://github.com/icsharpcode/ILSpy-Addin-tests](https://github.com/icsharpcode/ILSpy-Addin-tests)"
  },
  {
    "path": "ILSpy.AddIn/source.extension.vsixmanifest.template",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<PackageManifest Version=\"2.0\" xmlns=\"http://schemas.microsoft.com/developer/vsx-schema/2011\" xmlns:d=\"http://schemas.microsoft.com/developer/vsx-schema-design/2011\">\n  <Metadata>\n    <Identity Id=\"a9120dbe-164a-4891-842f-fb7829273838\" Version=\"$INSERTVERSION$\" Language=\"en-US\" Publisher=\"ic#code\" />\n    <DisplayName>ILSpy</DisplayName>\n    <Description xml:space=\"preserve\">Integrates the ILSpy decompiler into Visual Studio.</Description>\n    <MoreInfo>https://ilspy.net</MoreInfo>\n    <License>LICENSE</License>\n    <Icon>ILSpy-Large.ico</Icon>\n  </Metadata>\n  <Installation>\n    <InstallationTarget Id=\"Microsoft.VisualStudio.Community\" Version=\"[15.0,17.0)\" />\n  </Installation>\n  <Dependencies>\n    <Dependency Id=\"Microsoft.Framework.NDP\" DisplayName=\"Microsoft .NET Framework\" d:Source=\"Manual\" Version=\"[4.5,)\" />\n  </Dependencies>\n  <Assets>\n    <Asset Type=\"Microsoft.VisualStudio.MefComponent\" d:Source=\"Project\" d:ProjectName=\"ILSpy.AddIn\" Path=\"|ILSpy.AddIn|\"/>\n  </Assets>\n  <Prerequisites>\n    <Prerequisite Id=\"Microsoft.VisualStudio.Component.CoreEditor\" Version=\"[15.0,)\" DisplayName=\"Visual Studio core editor\" />\n    <Prerequisite Id=\"Microsoft.VisualStudio.Component.Roslyn.LanguageServices\" Version=\"[15.0,)\" DisplayName=\"Roslyn Language Services\" />\n  </Prerequisites>\n</PackageManifest>\n"
  },
  {
    "path": "ILSpy.AddIn.Shared/AssemblyFileFinder.cs",
    "content": "using System;\nusing System.Linq;\nusing System.Text.RegularExpressions;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nnamespace ICSharpCode.ILSpy.AddIn\n{\n\tpublic class AssemblyFileFinder\n\t{\n\t\tpublic static string FindAssemblyFile(Mono.Cecil.AssemblyDefinition assemblyDefinition, string assemblyFile)\n\t\t{\n\t\t\tstring tfi = DetectTargetFrameworkId(assemblyDefinition, assemblyFile);\n\t\t\tUniversalAssemblyResolver assemblyResolver;\n\t\t\tif (IsReferenceAssembly(assemblyDefinition, assemblyFile))\n\t\t\t{\n\t\t\t\tassemblyResolver = new UniversalAssemblyResolver(null, throwOnError: false, tfi);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tassemblyResolver = new UniversalAssemblyResolver(assemblyFile, throwOnError: false, tfi);\n\t\t\t}\n\n\t\t\treturn assemblyResolver.FindAssemblyFile(AssemblyNameReference.Parse(assemblyDefinition.Name.FullName));\n\t\t}\n\n\t\tstatic readonly string RefPathPattern = @\"NuGetFallbackFolder[/\\\\][^/\\\\]+[/\\\\][^/\\\\]+[/\\\\]ref[/\\\\]\";\n\n\t\tpublic static bool IsReferenceAssembly(Mono.Cecil.AssemblyDefinition assemblyDef, string assemblyFile)\n\t\t{\n\t\t\tif (assemblyDef.CustomAttributes.Any(ca => ca.AttributeType.FullName == \"System.Runtime.CompilerServices.ReferenceAssemblyAttribute\"))\n\t\t\t\treturn true;\n\n\t\t\t// Try to detect reference assembly through specific path pattern\n\t\t\tvar refPathMatch = Regex.Match(assemblyFile, RefPathPattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);\n\t\t\treturn refPathMatch.Success;\n\t\t}\n\n\t\tstatic readonly string DetectTargetFrameworkIdRefPathPattern =\n\t\t\t@\"(Reference Assemblies[/\\\\]Microsoft[/\\\\]Framework[/\\\\](?<1>.NETFramework)[/\\\\]v(?<2>[^/\\\\]+)[/\\\\])\" +\n\t\t\t@\"|((NuGetFallbackFolder|packs|.nuget[/\\\\]packages)[/\\\\](?<1>[^/\\\\]+)\\\\(?<2>[^/\\\\]+)([/\\\\].*)?[/\\\\]ref[/\\\\])\";\n\n\t\tpublic static string DetectTargetFrameworkId(Mono.Cecil.AssemblyDefinition assembly, string assemblyPath = null)\n\t\t{\n\t\t\tif (assembly == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(assembly));\n\n\t\t\tconst string TargetFrameworkAttributeName = \"System.Runtime.Versioning.TargetFrameworkAttribute\";\n\n\t\t\tforeach (var attribute in assembly.CustomAttributes)\n\t\t\t{\n\t\t\t\tif (attribute.AttributeType.FullName != TargetFrameworkAttributeName)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (attribute.HasConstructorArguments)\n\t\t\t\t{\n\t\t\t\t\tif (attribute.ConstructorArguments[0].Value is string value)\n\t\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Optionally try to detect target version through assembly path as a fallback (use case: reference assemblies)\n\t\t\tif (assemblyPath != null)\n\t\t\t{\n\t\t\t\t/*\n\t\t\t\t * Detected path patterns (examples):\n\t\t\t\t * \n\t\t\t\t * - .NETFramework -> C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.6.1\\mscorlib.dll\n\t\t\t\t * - .NETCore      -> C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder\\microsoft.netcore.app\\2.1.0\\ref\\netcoreapp2.1\\System.Console.dll\n\t\t\t\t *                 -> C:\\Program Files\\dotnet\\packs\\Microsoft.NETCore.App.Ref\\3.0.0\\ref\\netcoreapp3.0\\System.Runtime.Extensions.dll\n\t\t\t\t * - .NETStandard  -> C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder\\netstandard.library\\2.0.3\\build\\netstandard2.0\\ref\\netstandard.dll\n\t\t\t\t */\n\t\t\t\tvar pathMatch = Regex.Match(assemblyPath, DetectTargetFrameworkIdRefPathPattern,\n\t\t\t\t\tRegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.ExplicitCapture);\n\t\t\t\tif (pathMatch.Success)\n\t\t\t\t{\n\t\t\t\t\tvar type = pathMatch.Groups[1].Value;\n\t\t\t\t\tvar version = pathMatch.Groups[2].Value;\n\n\t\t\t\t\tif (type == \".NETFramework\")\n\t\t\t\t\t{\n\t\t\t\t\t\treturn $\".NETFramework,Version=v{version}\";\n\t\t\t\t\t}\n\t\t\t\t\telse if (type.ToLower().Contains(\"netcore\"))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn $\".NETCoreApp,Version=v{version}\";\n\t\t\t\t\t}\n\t\t\t\t\telse if (type.ToLower().Contains(\"netstandard\"))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn $\".NETStandard,Version=v{version}\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn string.Empty;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.AddIn.Shared/Commands/AssemblyReferenceForILSpy.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nusing VSLangProj;\n\nnamespace ICSharpCode.ILSpy.AddIn.Commands\n{\n\t/// <summary>\n\t/// Represents an assembly reference item in Solution Explorer, which can be opened in ILSpy.\n\t/// </summary>\n\tclass AssemblyReferenceForILSpy\n\t{\n\t\tReference reference;\n\n\t\tAssemblyReferenceForILSpy(Reference reference)\n\t\t{\n\t\t\tthis.reference = reference;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Detects whether the given selected item represents a supported project.\n\t\t/// </summary>\n\t\t/// <param name=\"itemData\">Data object of selected item to check.</param>\n\t\t/// <returns><see cref=\"AssemblyReferenceForILSpy\"/> instance or <c>null</c>, if item is not a supported project.</returns>\n\t\tpublic static AssemblyReferenceForILSpy Detect(object itemData)\n\t\t{\n\t\t\treturn (itemData is Reference reference) ? new AssemblyReferenceForILSpy(reference) : null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// If possible retrieves parameters to use for launching ILSpy instance.\n\t\t/// </summary>\n\t\t/// <param name=\"projectReferences\">List of current project's references.</param>\n\t\t/// <returns>Parameters object or <c>null, if not applicable.</c></returns>\n\t\tpublic ILSpyParameters GetILSpyParameters(Dictionary<string, DetectedReference> projectReferences)\n\t\t{\n\t\t\tif (projectReferences.TryGetValue(reference.Name, out var refentry))\n\t\t\t\treturn new ILSpyParameters(new[] { refentry.AssemblyFile });\n\n\t\t\treturn null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.AddIn.Shared/Commands/NuGetReferenceForILSpy.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nusing EnvDTE;\n\nusing Microsoft.VisualStudio.Shell;\n\nusing VSLangProj;\n\nnamespace ICSharpCode.ILSpy.AddIn.Commands\n{\n\t/// <summary>\n\t/// Represents a NuGet package item in Solution Explorer, which can be opened in ILSpy.\n\t/// </summary>\n\tclass NuGetReferenceForILSpy\n\t{\n\t\tProjectItem projectItem;\n\n\t\tNuGetReferenceForILSpy(ProjectItem projectItem)\n\t\t{\n\t\t\tthis.projectItem = projectItem;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Detects whether the given selected item represents a supported project.\n\t\t/// </summary>\n\t\t/// <param name=\"itemData\">Data object of selected item to check.</param>\n\t\t/// <returns><see cref=\"NuGetReferenceForILSpy\"/> instance or <c>null</c>, if item is not a supported project.</returns>\n\t\tpublic static NuGetReferenceForILSpy Detect(object itemData)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tif (itemData is ProjectItem projectItem)\n\t\t\t{\n\t\t\t\tvar properties = Utils.GetProperties(projectItem.Properties, \"Type\", \"ExtenderCATID\");\n\t\t\t\tif (((properties[0] as string) == \"Package\") || ((properties[1] as string) == PrjBrowseObjectCATID.prjCATIDCSharpReferenceBrowseObject))\n\t\t\t\t{\n\t\t\t\t\treturn new NuGetReferenceForILSpy(projectItem);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// If possible retrieves parameters to use for launching ILSpy instance.\n\t\t/// </summary>\n\t\t/// <returns>Parameters object or <c>null, if not applicable.</c></returns>\n\t\tpublic ILSpyParameters GetILSpyParameters()\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tvar properties = Utils.GetProperties(projectItem.Properties, \"Name\", \"Version\", \"Path\");\n\t\t\tif (properties[0] != null && properties[1] != null && properties[2] != null)\n\t\t\t{\n\t\t\t\treturn new ILSpyParameters(new[] { $\"{properties[2]}\\\\{properties[0]}.{properties[1]}.nupkg\" });\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.AddIn.Shared/Commands/OpenCodeItemCommand.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Threading;\n\nusing Microsoft.CodeAnalysis;\nusing Microsoft.CodeAnalysis.Text;\nusing Microsoft.VisualStudio.Shell;\nusing Microsoft.VisualStudio.Shell.Interop;\nusing Microsoft.VisualStudio.Text;\n\nnamespace ICSharpCode.ILSpy.AddIn.Commands\n{\n\tclass OpenCodeItemCommand : ILSpyCommand\n\t{\n\t\tstatic OpenCodeItemCommand instance;\n\n\t\tpublic OpenCodeItemCommand(ILSpyAddInPackage owner)\n\t\t\t: base(owner, PkgCmdIDList.cmdidOpenCodeItemInILSpy)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\t\t}\n\n\t\tprotected override void OnBeforeQueryStatus(object sender, EventArgs e)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tif (sender is OleMenuCommand menuItem)\n\t\t\t{\n\t\t\t\tmenuItem.Visible = false;\n\n\t\t\t\t// Enable this item only if this is a .cs file!\n\t\t\t\tif (Utils.GetCurrentViewHost(owner, f => f.EndsWith(\".cs\")) == null)\n\t\t\t\t\treturn;\n\n\t\t\t\t// Enable this item only if this is a Roslyn document\n\t\t\t\tif (GetRoslynDocument() == null)\n\t\t\t\t\treturn;\n\n\t\t\t\tvar document = owner.DTE.ActiveDocument;\n\t\t\t\tmenuItem.Visible =\n\t\t\t\t\t(document?.ProjectItem?.ContainingProject?.ConfigurationManager != null) &&\n\t\t\t\t\t!string.IsNullOrEmpty(document.ProjectItem.ContainingProject.FileName);\n\t\t\t}\n\t\t}\n\n\t\tDocument GetRoslynDocument()\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tvar document = owner.DTE.ActiveDocument;\n\t\t\tvar id = owner.Workspace.CurrentSolution.GetDocumentIdsWithFilePath(document.FullName).FirstOrDefault();\n\t\t\tif (id == null)\n\t\t\t\treturn null;\n\n\t\t\treturn owner.Workspace.CurrentSolution.GetDocument(id);\n\t\t}\n\n\t\tprotected override async void OnExecute(object sender, EventArgs e)\n\t\t{\n\t\t\tawait ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();\n\n\t\t\tvar textView = Utils.GetCurrentViewHost(owner)?.TextView;\n\t\t\tif (textView == null)\n\t\t\t\treturn;\n\n\t\t\tSnapshotPoint caretPosition = textView.Caret.Position.BufferPosition;\n\t\t\tvar roslynDocument = GetRoslynDocument();\n\t\t\tif (roslynDocument == null)\n\t\t\t{\n\t\t\t\towner.ShowMessage(\"This element is not analyzable in current view.\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar ast = await roslynDocument.GetSyntaxRootAsync().ConfigureAwait(false);\n\t\t\tvar model = await roslynDocument.GetSemanticModelAsync().ConfigureAwait(false);\n\t\t\tvar node = ast.FindNode(new TextSpan(caretPosition.Position, 0), false, true);\n\t\t\tif (node == null)\n\t\t\t{\n\t\t\t\towner.ShowMessage(OLEMSGICON.OLEMSGICON_WARNING, \"Can't show ILSpy for this code element!\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar symbol = GetSymbolResolvableByILSpy(model, node);\n\t\t\tif (symbol == null)\n\t\t\t{\n\t\t\t\towner.ShowMessage(OLEMSGICON.OLEMSGICON_WARNING, \"Can't show ILSpy for this code element!\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar roslynProject = roslynDocument.Project;\n\t\t\tvar refsmap = GetReferences(roslynProject);\n\t\t\tvar symbolAssemblyName = symbol.ContainingAssembly?.Identity?.Name;\n\n\t\t\t// Add our own project as well (not among references)\n\t\t\tvar project = FindProject(owner.DTE.Solution.Projects.OfType<EnvDTE.Project>(), roslynProject.FilePath);\n\n\t\t\tif (project == null)\n\t\t\t{\n\t\t\t\towner.ShowMessage(OLEMSGICON.OLEMSGICON_WARNING, \"Can't show ILSpy for this code element!\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tstring assemblyName = roslynDocument.Project.AssemblyName;\n\t\t\tstring projectOutputPath = Utils.GetProjectOutputAssembly(project, roslynProject);\n\t\t\trefsmap.Add(assemblyName, new DetectedReference(assemblyName, projectOutputPath, true));\n\n\t\t\t// Divide into valid and invalid (= not found) referenced assemblies\n\t\t\tCheckAssemblies(refsmap, out var validRefs, out var invalidRefs);\n\t\t\tvar invalidSymbolReference = invalidRefs.FirstOrDefault(r => r.IsProjectReference && (r.Name == symbolAssemblyName));\n\t\t\tif (invalidSymbolReference != null)\n\t\t\t{\n\t\t\t\tif (string.IsNullOrEmpty(invalidSymbolReference.AssemblyFile))\n\t\t\t\t{\n\t\t\t\t\t// No assembly file given at all. This has been seen while project is still loading after opening...\n\t\t\t\t\towner.ShowMessage(OLEMSGICON.OLEMSGICON_WARNING,\n\t\t\t\t\t\t\"Symbol can't be opened. This might happen while project is loading.\",\n\t\t\t\t\t\tEnvironment.NewLine, invalidSymbolReference.AssemblyFile);\n\t\t\t\t}\n\t\t\t\telse if (invalidSymbolReference.IsProjectReference)\n\t\t\t\t{\n\t\t\t\t\t// Some project references don't have assemblies, maybe not compiled yet?\n\t\t\t\t\tif (owner.ShowMessage(\n\t\t\t\t\t\tOLEMSGBUTTON.OLEMSGBUTTON_YESNO, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, OLEMSGICON.OLEMSGICON_WARNING,\n\t\t\t\t\t\t\"The project output for '{1}' could not be found for analysis.{0}{0}Expected path:{0}{0}{2}{0}{0}Would you like to build the solution?\",\n\t\t\t\t\t\tEnvironment.NewLine, symbolAssemblyName, invalidSymbolReference.AssemblyFile\n\t\t\t\t\t\t) == (int)MessageButtonResult.IDYES)\n\t\t\t\t\t{\n\t\t\t\t\t\towner.DTE.ExecuteCommand(\"Build.BuildSolution\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// External assembly is missing, we should abort\n\t\t\t\t\towner.ShowMessage(OLEMSGICON.OLEMSGICON_WARNING,\n\t\t\t\t\t\t\"Referenced assembly{0}{0}'{1}'{0}{0} could not be found.\",\n\t\t\t\t\t\tEnvironment.NewLine, invalidSymbolReference.AssemblyFile);\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tOpenAssembliesInILSpy(new ILSpyParameters(validRefs.Select(r => r.AssemblyFile), \"--navigateto:\" +\n\t\t\t\t(symbol.OriginalDefinition ?? symbol).GetDocumentationCommentId()));\n\t\t}\n\n\t\tvoid CheckAssemblies(Dictionary<string, DetectedReference> inputReferenceList,\n\t\t\tout List<DetectedReference> validRefs,\n\t\t\tout List<DetectedReference> invalidRefs)\n\t\t{\n\t\t\tvalidRefs = new List<DetectedReference>();\n\t\t\tinvalidRefs = new List<DetectedReference>();\n\n\t\t\tforeach (var reference in inputReferenceList.Select(r => r.Value))\n\t\t\t{\n\t\t\t\tif ((reference.AssemblyFile == null) || !File.Exists(reference.AssemblyFile))\n\t\t\t\t{\n\t\t\t\t\tinvalidRefs.Add(reference);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvalidRefs.Add(reference);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tISymbol GetSymbolResolvableByILSpy(SemanticModel model, SyntaxNode node)\n\t\t{\n\t\t\tvar current = node;\n\t\t\twhile (current != null)\n\t\t\t{\n\t\t\t\tvar symbol = model.GetSymbolInfo(current).Symbol;\n\t\t\t\tif (symbol == null)\n\t\t\t\t{\n\t\t\t\t\tsymbol = model.GetDeclaredSymbol(current);\n\t\t\t\t}\n\n\t\t\t\t// ILSpy can only resolve some symbol types, so allow them, discard everything else\n\t\t\t\tif (symbol != null)\n\t\t\t\t{\n\t\t\t\t\tswitch (symbol.Kind)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase SymbolKind.ArrayType:\n\t\t\t\t\t\tcase SymbolKind.Event:\n\t\t\t\t\t\tcase SymbolKind.Field:\n\t\t\t\t\t\tcase SymbolKind.Method:\n\t\t\t\t\t\tcase SymbolKind.NamedType:\n\t\t\t\t\t\tcase SymbolKind.Namespace:\n\t\t\t\t\t\tcase SymbolKind.PointerType:\n\t\t\t\t\t\tcase SymbolKind.Property:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tsymbol = null;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (symbol != null)\n\t\t\t\t\treturn symbol;\n\n\t\t\t\tcurrent = current is IStructuredTriviaSyntax\n\t\t\t\t\t? ((IStructuredTriviaSyntax)current).ParentTrivia.Token.Parent\n\t\t\t\t\t: current.Parent;\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tinternal static void Register(ILSpyAddInPackage owner)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tinstance = new OpenCodeItemCommand(owner);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.AddIn.Shared/Commands/OpenILSpyCommand.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.Design;\nusing System.IO;\nusing System.Linq;\n\nusing Microsoft.VisualStudio.Shell;\n\nusing Mono.Cecil;\n\nusing DTEConstants = EnvDTE.Constants;\n\nnamespace ICSharpCode.ILSpy.AddIn.Commands\n{\n\tpublic class DetectedReference\n\t{\n\t\tpublic DetectedReference(string name, string assemblyFile, bool isProjectReference)\n\t\t{\n\t\t\tthis.Name = name;\n\t\t\tthis.AssemblyFile = assemblyFile;\n\t\t\tthis.IsProjectReference = isProjectReference;\n\t\t}\n\n\t\tpublic string Name { get; private set; }\n\t\tpublic string AssemblyFile { get; private set; }\n\t\tpublic bool IsProjectReference { get; private set; }\n\t}\n\n\tabstract class ILSpyCommand\n\t{\n\t\tprotected ILSpyAddInPackage owner;\n\n\t\tprotected ILSpyCommand(ILSpyAddInPackage owner, uint id)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tthis.owner = owner;\n\t\t\tCommandID menuCommandID = new CommandID(GuidList.guidILSpyAddInCmdSet, (int)id);\n\t\t\tOleMenuCommand menuItem = new OleMenuCommand(OnExecute, menuCommandID);\n\t\t\tmenuItem.BeforeQueryStatus += OnBeforeQueryStatus;\n\t\t\towner.MenuService.AddCommand(menuItem);\n\t\t}\n\n\t\tprotected virtual void OnBeforeQueryStatus(object sender, EventArgs e)\n\t\t{\n\t\t}\n\n\t\tprotected abstract void OnExecute(object sender, EventArgs e);\n\n\t\tprotected void OpenAssembliesInILSpy(ILSpyParameters parameters)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tif (parameters == null)\n\t\t\t\treturn;\n\n\t\t\tforeach (string assemblyFileName in parameters.AssemblyFileNames)\n\t\t\t{\n\t\t\t\tif (!File.Exists(assemblyFileName))\n\t\t\t\t{\n\t\t\t\t\towner.ShowMessage(\"Could not find assembly '{0}', please ensure the project and all references were built correctly!\", assemblyFileName);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar ilspyExe = new ILSpyInstance(parameters);\n\t\t\tilspyExe.Start();\n\t\t}\n\n\t\tprotected Dictionary<string, DetectedReference> GetReferences(Microsoft.CodeAnalysis.Project parentProject)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tvar dict = new Dictionary<string, DetectedReference>();\n\t\t\tforeach (var reference in parentProject.MetadataReferences)\n\t\t\t{\n\t\t\t\tusing (var assemblyDef = AssemblyDefinition.ReadAssembly(reference.Display))\n\t\t\t\t{\n\t\t\t\t\tstring assemblyName = assemblyDef.Name.Name;\n\t\t\t\t\tstring resolvedAssemblyFile = AssemblyFileFinder.FindAssemblyFile(assemblyDef, reference.Display);\n\t\t\t\t\tdict.Add(assemblyName, new DetectedReference(assemblyName, resolvedAssemblyFile, false));\n\t\t\t\t}\n\t\t\t}\n\t\t\tforeach (var projectReference in parentProject.ProjectReferences)\n\t\t\t{\n\t\t\t\tvar roslynProject = owner.Workspace.CurrentSolution.GetProject(projectReference.ProjectId);\n\t\t\t\tif (roslynProject != null)\n\t\t\t\t{\n\t\t\t\t\tvar project = FindProject(owner.DTE.Solution.Projects.OfType<EnvDTE.Project>(), roslynProject.FilePath);\n\t\t\t\t\tif (project != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tdict.Add(roslynProject.AssemblyName,\n\t\t\t\t\t\t\tnew DetectedReference(roslynProject.AssemblyName, Utils.GetProjectOutputAssembly(project, roslynProject), true));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn dict;\n\t\t}\n\n\t\tprotected EnvDTE.Project FindProject(IEnumerable<EnvDTE.Project> projects, string projectFile)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tforeach (var project in projects)\n\t\t\t{\n\t\t\t\tswitch (project.Kind)\n\t\t\t\t{\n\t\t\t\t\tcase DTEConstants.vsProjectKindSolutionItems:\n\t\t\t\t\t\t// This is a solution folder -> search in sub-projects\n\t\t\t\t\t\tvar subProject = FindProject(\n\t\t\t\t\t\t\tproject.ProjectItems.OfType<EnvDTE.ProjectItem>().Select(pi => pi.SubProject).OfType<EnvDTE.Project>(),\n\t\t\t\t\t\t\tprojectFile);\n\t\t\t\t\t\tif (subProject != null)\n\t\t\t\t\t\t\treturn subProject;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase DTEConstants.vsProjectKindUnmodeled:\n\t\t\t\t\t\t// Skip unloaded projects completely\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// Match by project's file name\n\t\t\t\t\t\tif (project.FileName == projectFile)\n\t\t\t\t\t\t\treturn project;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tclass OpenILSpyCommand : ILSpyCommand\n\t{\n\t\tstatic OpenILSpyCommand instance;\n\n\t\tpublic OpenILSpyCommand(ILSpyAddInPackage owner)\n\t\t\t: base(owner, PkgCmdIDList.cmdidOpenILSpy)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\t\t}\n\n\t\tprotected override void OnExecute(object sender, EventArgs e)\n\t\t{\n\t\t\tnew ILSpyInstance().Start();\n\t\t}\n\n\t\tinternal static void Register(ILSpyAddInPackage owner)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tinstance = new OpenILSpyCommand(owner);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.AddIn.Shared/Commands/OpenProjectOutputCommand.cs",
    "content": "using System;\nusing System.IO;\nusing System.Linq;\n\nusing Microsoft.VisualStudio.Shell;\n\nnamespace ICSharpCode.ILSpy.AddIn.Commands\n{\n\tclass OpenProjectOutputCommand : ILSpyCommand\n\t{\n\t\tstatic OpenProjectOutputCommand instance;\n\n\t\tpublic OpenProjectOutputCommand(ILSpyAddInPackage owner)\n\t\t\t: base(owner, PkgCmdIDList.cmdidOpenProjectOutputInILSpy)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\t\t}\n\n\t\tprotected override void OnBeforeQueryStatus(object sender, EventArgs e)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tif (sender is OleMenuCommand menuItem)\n\t\t\t{\n\t\t\t\tmenuItem.Visible = false;\n\n\t\t\t\tvar selectedItem = owner.DTE.SelectedItems.Item(1);\n\t\t\t\tmenuItem.Visible = (ProjectItemForILSpy.Detect(owner, selectedItem) != null);\n\t\t\t}\n\t\t}\n\n\t\tprotected override void OnExecute(object sender, EventArgs e)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tif (owner.DTE.SelectedItems.Count != 1)\n\t\t\t\treturn;\n\t\t\tvar projectItemWrapper = ProjectItemForILSpy.Detect(owner, owner.DTE.SelectedItems.Item(1));\n\t\t\tif (projectItemWrapper != null)\n\t\t\t{\n\t\t\t\tOpenAssembliesInILSpy(projectItemWrapper.GetILSpyParameters(owner));\n\t\t\t}\n\t\t}\n\n\t\tinternal static void Register(ILSpyAddInPackage owner)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tinstance = new OpenProjectOutputCommand(owner);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.AddIn.Shared/Commands/OpenReferenceCommand.cs",
    "content": "using System;\nusing System.Linq;\n\nusing EnvDTE;\n\nusing Microsoft.VisualStudio.Shell;\n\nusing VSLangProj;\n\nnamespace ICSharpCode.ILSpy.AddIn.Commands\n{\n\tclass OpenReferenceCommand : ILSpyCommand\n\t{\n\t\tstatic OpenReferenceCommand instance;\n\n\t\tpublic OpenReferenceCommand(ILSpyAddInPackage owner)\n\t\t\t: base(owner, PkgCmdIDList.cmdidOpenReferenceInILSpy)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\t\t}\n\n\t\tprotected override void OnBeforeQueryStatus(object sender, EventArgs e)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tif (sender is OleMenuCommand menuItem)\n\t\t\t{\n\t\t\t\tmenuItem.Visible = false;\n\n\t\t\t\tvar selectedItemData = owner.GetSelectedItemsData<object>().FirstOrDefault();\n\t\t\t\tif (selectedItemData == null)\n\t\t\t\t\treturn;\n\n\t\t\t\t/*\n\t\t\t\t * Assure that we only show the context menu item on items we intend:\n\t\t\t\t * - Project references\n\t\t\t\t * - NuGet package references\n\t\t\t\t */\n\t\t\t\tif ((AssemblyReferenceForILSpy.Detect(selectedItemData) != null)\n\t\t\t\t\t|| (ProjectReferenceForILSpy.Detect(selectedItemData) != null)\n\t\t\t\t\t|| (NuGetReferenceForILSpy.Detect(selectedItemData) != null))\n\t\t\t\t{\n\t\t\t\t\tmenuItem.Visible = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprotected override void OnExecute(object sender, EventArgs e)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tvar itemObject = owner.GetSelectedItemsData<object>().FirstOrDefault();\n\t\t\tif (itemObject == null)\n\t\t\t\treturn;\n\n\t\t\tvar referenceItem = AssemblyReferenceForILSpy.Detect(itemObject);\n\t\t\tif (referenceItem != null)\n\t\t\t{\n\t\t\t\tReference reference = itemObject as Reference;\n\t\t\t\tvar project = reference.ContainingProject;\n\t\t\t\tvar roslynProject = owner.Workspace.CurrentSolution.Projects.FirstOrDefault(p => p.FilePath == project.FileName);\n\t\t\t\tvar references = GetReferences(roslynProject);\n\t\t\t\tvar parameters = referenceItem.GetILSpyParameters(references);\n\t\t\t\tif (references.TryGetValue(reference.Name, out var path))\n\t\t\t\t\tOpenAssembliesInILSpy(parameters);\n\t\t\t\telse\n\t\t\t\t\towner.ShowMessage(\"Could not find reference '{0}', please ensure the project and all references were built correctly!\", reference.Name);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Handle project references\n\t\t\tvar projectRefItem = ProjectReferenceForILSpy.Detect(itemObject);\n\t\t\tif (projectRefItem != null)\n\t\t\t{\n\t\t\t\tvar projectItem = itemObject as ProjectItem;\n\t\t\t\tstring fileName = projectItem.ContainingProject?.FileName;\n\t\t\t\tif (!string.IsNullOrEmpty(fileName))\n\t\t\t\t{\n\t\t\t\t\tvar roslynProject = owner.Workspace.CurrentSolution.Projects.FirstOrDefault(p => p.FilePath == fileName);\n\t\t\t\t\tvar references = GetReferences(roslynProject);\n\t\t\t\t\tif (references.TryGetValue(projectItem.Name, out DetectedReference path))\n\t\t\t\t\t{\n\t\t\t\t\t\tOpenAssembliesInILSpy(projectRefItem.GetILSpyParameters(references));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tOpenAssembliesInILSpy(projectRefItem.GetILSpyParameters());\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Handle NuGet references\n\t\t\tvar nugetRefItem = NuGetReferenceForILSpy.Detect(itemObject);\n\t\t\tif (nugetRefItem != null)\n\t\t\t{\n\t\t\t\tOpenAssembliesInILSpy(nugetRefItem.GetILSpyParameters());\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tinternal static void Register(ILSpyAddInPackage owner)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tinstance = new OpenReferenceCommand(owner);\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "ILSpy.AddIn.Shared/Commands/ProjectItemForILSpy.cs",
    "content": "using System.IO;\nusing System.Linq;\n\nusing EnvDTE;\n\nusing Microsoft.VisualStudio.Shell;\n\nnamespace ICSharpCode.ILSpy.AddIn.Commands\n{\n\t/// <summary>\n\t/// Represents a project item in Solution Explorer, which can be opened in ILSpy.\n\t/// </summary>\n\tclass ProjectItemForILSpy\n\t{\n\t\tSelectedItem item;\n\t\tProject project;\n\t\tMicrosoft.CodeAnalysis.Project roslynProject;\n\n\t\tProjectItemForILSpy(Project project, Microsoft.CodeAnalysis.Project roslynProject, SelectedItem item)\n\t\t{\n\t\t\tthis.project = project;\n\t\t\tthis.roslynProject = roslynProject;\n\t\t\tthis.item = item;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Detects whether the given <see cref=\"SelectedItem\"/> represents a supported project.\n\t\t/// </summary>\n\t\t/// <param name=\"item\">Selected item to check.</param>\n\t\t/// <returns><see cref=\"ProjectItemForILSpy\"/> instance or <c>null</c>, if item is not a supported project.</returns>\n\t\tpublic static ProjectItemForILSpy Detect(ILSpyAddInPackage package, SelectedItem item)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tvar project = item.Project;\n\t\t\tvar roslynProject = package.Workspace.CurrentSolution.Projects.FirstOrDefault(p => p.FilePath == project.FileName);\n\t\t\tif (roslynProject == null)\n\t\t\t\treturn null;\n\n\t\t\treturn new ProjectItemForILSpy(project, roslynProject, item);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// If possible retrieves parameters to use for launching ILSpy instance.\n\t\t/// </summary>\n\t\t/// <param name=\"package\">Package instance.</param>\n\t\t/// <returns>Parameters object or <c>null, if not applicable.</c></returns>\n\t\tpublic ILSpyParameters GetILSpyParameters(ILSpyAddInPackage package)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\treturn new ILSpyParameters(new[] { Utils.GetProjectOutputAssembly(project, roslynProject) });\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.AddIn.Shared/Commands/ProjectReferenceForILSpy.cs",
    "content": "using System.Collections.Generic;\n\nusing EnvDTE;\n\nusing ICSharpCode.Decompiler.Metadata;\n\nusing Microsoft.VisualStudio.Shell;\n\nnamespace ICSharpCode.ILSpy.AddIn.Commands\n{\n\t/// <summary>\n\t/// Represents a project reference item in Solution Explorer, which can be opened in ILSpy.\n\t/// </summary>\n\tclass ProjectReferenceForILSpy\n\t{\n\t\tProjectItem projectItem;\n\t\tstring fusionName;\n\t\tstring resolvedPath;\n\n\t\tProjectReferenceForILSpy(ProjectItem projectItem, string fusionName, string resolvedPath)\n\t\t{\n\t\t\tthis.projectItem = projectItem;\n\t\t\tthis.fusionName = fusionName;\n\t\t\tthis.resolvedPath = resolvedPath;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Detects whether the given selected item represents a supported project.\n\t\t/// </summary>\n\t\t/// <param name=\"itemData\">Data object of selected item to check.</param>\n\t\t/// <returns><see cref=\"ProjectReferenceForILSpy\"/> instance or <c>null</c>, if item is not a supported project.</returns>\n\t\tpublic static ProjectReferenceForILSpy Detect(object itemData)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tif (itemData is ProjectItem projectItem)\n\t\t\t{\n\t\t\t\tvar properties = Utils.GetProperties(projectItem.Properties, \"FusionName\", \"ResolvedPath\");\n\t\t\t\tstring fusionName = properties[0] as string;\n\t\t\t\tstring resolvedPath = properties[1] as string;\n\t\t\t\tif ((fusionName != null) || (resolvedPath != null))\n\t\t\t\t{\n\t\t\t\t\treturn new ProjectReferenceForILSpy(projectItem, fusionName, resolvedPath);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// If possible retrieves parameters to use for launching ILSpy instance.\n\t\t/// </summary>\n\t\t/// <param name=\"projectReferences\">List of current project's references.</param>\n\t\t/// <returns>Parameters object or <c>null, if not applicable.</c></returns>\n\t\tpublic ILSpyParameters GetILSpyParameters(Dictionary<string, DetectedReference> projectReferences)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tstring fileName = projectItem.ContainingProject?.FileName;\n\t\t\tif (!string.IsNullOrEmpty(fileName))\n\t\t\t{\n\t\t\t\tif (projectReferences.TryGetValue(projectItem.Name, out DetectedReference path))\n\t\t\t\t{\n\t\t\t\t\treturn new ILSpyParameters(new[] { path.AssemblyFile });\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// If possible retrieves parameters to use for launching ILSpy instance.\n\t\t/// </summary>\n\t\t/// <returns>Parameters object or <c>null, if not applicable.</c></returns>\n\t\tpublic ILSpyParameters GetILSpyParameters()\n\t\t{\n\t\t\tif (resolvedPath != null)\n\t\t\t{\n\t\t\t\treturn new ILSpyParameters(new[] { $\"{resolvedPath}\" });\n\t\t\t}\n\t\t\telse if (!string.IsNullOrWhiteSpace(fusionName))\n\t\t\t{\n\t\t\t\treturn new ILSpyParameters(new string[] { UniversalAssemblyResolver.GetAssemblyInGac(Decompiler.Metadata.AssemblyNameReference.Parse(fusionName)) });\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.AddIn.Shared/GlobalSuppressions.cs",
    "content": "// This file is used by Code Analysis to maintain SuppressMessage\n// attributes that are applied to this project. Project-level\n// suppressions either have no target or are given a specific target\n// and scoped to a namespace, type, member, etc.\n//\n// To add a suppression to this file, right-click the message in the\n// Error List, point to \"Suppress Message(s)\", and click \"In Project\n// Suppression File\". You do not need to add suppressions to this\n// file manually.\n\n[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Design\", \"CA1017:MarkAssembliesWithComVisible\")]\n"
  },
  {
    "path": "ILSpy.AddIn.Shared/Guids.cs",
    "content": "// Guids.cs\n// MUST match guids.h\nusing System;\n\nnamespace ICSharpCode.ILSpy.AddIn\n{\n\tstatic class GuidList\n\t{\n#if VS2022\n\t\tpublic const string guidILSpyAddInPkgString = \"ebf12ca7-a1fd-4aee-a894-4a0c5682fc2f\";\n#else\n\t\tpublic const string guidILSpyAddInPkgString = \"a9120dbe-164a-4891-842f-fb7829273838\";\n#endif\n\t\tpublic const string guidILSpyAddInCmdSetString = \"85ddb8ca-a842-4b1c-ba1a-94141fdf19d0\";\n\n\t\tpublic static readonly Guid guidILSpyAddInCmdSet = new Guid(guidILSpyAddInCmdSetString);\n\t};\n}"
  },
  {
    "path": "ILSpy.AddIn.Shared/ILSpy.AddIn.Shared.projitems",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <MSBuildAllProjects Condition=\"'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' &lt; '16.0'\">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>\n    <HasSharedItems>true</HasSharedItems>\n    <SharedGUID>acab1e5d-b3df-4092-aa72-692f8341e520</SharedGUID>\n  </PropertyGroup>\n  <PropertyGroup Label=\"Configuration\">\n    <Import_RootNamespace>ILSpy.AddIn.Shared</Import_RootNamespace>\n  </PropertyGroup>\n  <ItemGroup>\n    <Compile Include=\"$(MSBuildThisFileDirectory)AssemblyFileFinder.cs\" />\n    <Compile Include=\"$(MSBuildThisFileDirectory)Commands\\AssemblyReferenceForILSpy.cs\" />\n    <Compile Include=\"$(MSBuildThisFileDirectory)Commands\\NuGetReferenceForILSpy.cs\" />\n    <Compile Include=\"$(MSBuildThisFileDirectory)Commands\\OpenCodeItemCommand.cs\" />\n    <Compile Include=\"$(MSBuildThisFileDirectory)Commands\\OpenILSpyCommand.cs\" />\n    <Compile Include=\"$(MSBuildThisFileDirectory)Commands\\OpenProjectOutputCommand.cs\" />\n    <Compile Include=\"$(MSBuildThisFileDirectory)Commands\\OpenReferenceCommand.cs\" />\n    <Compile Include=\"$(MSBuildThisFileDirectory)Commands\\ProjectItemForILSpy.cs\" />\n    <Compile Include=\"$(MSBuildThisFileDirectory)Commands\\ProjectReferenceForILSpy.cs\" />\n    <Compile Include=\"$(MSBuildThisFileDirectory)GlobalSuppressions.cs\" />\n    <Compile Include=\"$(MSBuildThisFileDirectory)Guids.cs\" />\n    <Compile Include=\"$(MSBuildThisFileDirectory)ILSpyAddInPackage.cs\" />\n    <Compile Include=\"$(MSBuildThisFileDirectory)ILSpyInstance.cs\" />\n    <Compile Include=\"$(MSBuildThisFileDirectory)PkgCmdID.cs\" />\n    <Compile Include=\"$(MSBuildThisFileDirectory)Resources.Designer.cs\">\n      <DependentUpon>Resources.resx</DependentUpon>\n      <DesignTime>True</DesignTime>\n      <AutoGen>True</AutoGen>\n    </Compile>\n    <Compile Include=\"$(MSBuildThisFileDirectory)SyntaxNodeExtensions.cs\" />\n    <Compile Include=\"$(MSBuildThisFileDirectory)Utils.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <EmbeddedResource Include=\"$(MSBuildThisFileDirectory)Resources.resx\">\n      <SubType>Designer</SubType>\n      <LastGenOutput>Resources.Designer.cs</LastGenOutput>\n      <Generator>ResXFileCodeGenerator</Generator>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"$(MSBuildThisFileDirectory)VSPackage.en-US.resx\">\n      <DependentUpon>VSPackage.resx</DependentUpon>\n      <LogicalName>VSPackage.en-US.resources</LogicalName>\n      <MergeWithCTO>true</MergeWithCTO>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"$(MSBuildThisFileDirectory)VSPackage.resx\">\n      <MergeWithCTO>true</MergeWithCTO>\n      <ManifestResourceName>VSPackage</ManifestResourceName>\n    </EmbeddedResource>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "ILSpy.AddIn.Shared/ILSpy.AddIn.Shared.shproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>acab1e5d-b3df-4092-aa72-692f8341e520</ProjectGuid>\n    <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>\n  </PropertyGroup>\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <Import Project=\"$(MSBuildExtensionsPath32)\\Microsoft\\VisualStudio\\v$(VisualStudioVersion)\\CodeSharing\\Microsoft.CodeSharing.Common.Default.props\" />\n  <Import Project=\"$(MSBuildExtensionsPath32)\\Microsoft\\VisualStudio\\v$(VisualStudioVersion)\\CodeSharing\\Microsoft.CodeSharing.Common.props\" />\n  <PropertyGroup />\n  <Import Project=\"ILSpy.AddIn.Shared.projitems\" Label=\"Shared\" />\n  <Import Project=\"$(MSBuildExtensionsPath32)\\Microsoft\\VisualStudio\\v$(VisualStudioVersion)\\CodeSharing\\Microsoft.CodeSharing.CSharp.targets\" />\n</Project>\n"
  },
  {
    "path": "ILSpy.AddIn.Shared/ILSpyAddInPackage.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.Design;\nusing System.Diagnostics;\nusing System.Globalization;\nusing System.Runtime.InteropServices;\nusing System.Threading;\n\nusing EnvDTE;\n\nusing ICSharpCode.ILSpy.AddIn.Commands;\n\nusing Microsoft;\nusing Microsoft.VisualStudio;\nusing Microsoft.VisualStudio.ComponentModelHost;\nusing Microsoft.VisualStudio.LanguageServices;\nusing Microsoft.VisualStudio.Shell;\nusing Microsoft.VisualStudio.Shell.Interop;\n\nusing Task = System.Threading.Tasks.Task;\n\nnamespace ICSharpCode.ILSpy.AddIn\n{\n\t/// <summary>\n\t/// This is the class that implements the package exposed by this assembly.\n\t///\n\t/// The minimum requirement for a class to be considered a valid package for Visual Studio\n\t/// is to implement the IVsPackage interface and register itself with the shell.\n\t/// This package uses the helper classes defined inside the Managed Package Framework (MPF)\n\t/// to do it: it derives from the Package class that provides the implementation of the \n\t/// IVsPackage interface and uses the registration attributes defined in the framework to \n\t/// register itself and its components with the shell.\n\t/// </summary>\n\t// This attribute tells the PkgDef creation utility (CreatePkgDef.exe) that this class is\n\t// a package.\n\t[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]\n\t// This attribute is used to register the information needed to show this package\n\t// in the Help/About dialog of Visual Studio.\n\t[InstalledProductRegistration(\"#110\", \"#112\", \"1.0\", IconResourceID = 400)]\n\t// This attribute is needed to let the shell know that this package exposes some menus.\n\t[ProvideMenuResource(\"Menus.ctmenu\", 1)]\n\t[Guid(GuidList.guidILSpyAddInPkgString)]\n\t[ProvideAutoLoad(VSConstants.UICONTEXT.SolutionExistsAndFullyLoaded_string, PackageAutoLoadFlags.BackgroundLoad)]\n\t[ProvideBindingPath]\n\tpublic sealed class ILSpyAddInPackage : AsyncPackage\n\t{\n\t\t/// <summary>\n\t\t/// Default constructor of the package.\n\t\t/// Inside this method you can place any initialization code that does not require \n\t\t/// any Visual Studio service because at this point the package object is created but \n\t\t/// not sited yet inside Visual Studio environment. The place to do all the other \n\t\t/// initialization is the Initialize method.\n\t\t/// </summary>\n\t\tpublic ILSpyAddInPackage()\n\t\t{\n\t\t\tDebug.WriteLine(string.Format(CultureInfo.CurrentCulture, \"Entering constructor for: {0}\", this.ToString()));\n\t\t}\n\n\t\tOleMenuCommandService menuService;\n\t\tpublic OleMenuCommandService MenuService => menuService;\n\n\t\tVisualStudioWorkspace workspace;\n\t\tpublic VisualStudioWorkspace Workspace => workspace;\n\n\t\tpublic EnvDTE80.DTE2 DTE => (EnvDTE80.DTE2)GetGlobalService(typeof(EnvDTE.DTE));\n\n\t\t/////////////////////////////////////////////////////////////////////////////\n\t\t// Overridden Package Implementation\n\t\t#region Package Members\n\n\t\t/// <summary>\n\t\t/// Initialization of the package; this method is called right after the package is sited, so this is the place\n\t\t/// where you can put all the initialization code that rely on services provided by VisualStudio.\n\t\t/// </summary>\n\t\tprotected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)\n\t\t{\n\t\t\tDebug.WriteLine($\"Entering {nameof(InitializeAsync)}() of: {this}\");\n\n\t\t\tawait base.InitializeAsync(cancellationToken, progress);\n\n\t\t\tawait JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);\n\t\t\tcancellationToken.ThrowIfCancellationRequested();\n\n\t\t\tvar componentModel = (IComponentModel)await GetServiceAsync(typeof(SComponentModel));\n\t\t\tAssumes.Present(componentModel);\n\n\t\t\t// Add our command handlers for menu (commands must exist in the .vsct file)\n\t\t\tthis.menuService = (OleMenuCommandService)await GetServiceAsync(typeof(IMenuCommandService));\n\t\t\tAssumes.Present(menuService);\n\n\t\t\tthis.workspace = componentModel.GetService<VisualStudioWorkspace>();\n\t\t\tAssumes.Present(workspace);\n\n\t\t\tOpenILSpyCommand.Register(this);\n\t\t\tOpenProjectOutputCommand.Register(this);\n\t\t\tOpenReferenceCommand.Register(this);\n\t\t\tOpenCodeItemCommand.Register(this);\n\t\t}\n\n\t\tprotected override int QueryClose(out bool canClose)\n\t\t{\n\t\t\tvar tempFiles = ILSpyInstance.TempFiles;\n\t\t\twhile (tempFiles.TryPop(out var filename))\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tSystem.IO.File.Delete(filename);\n\t\t\t\t}\n\t\t\t\tcatch (Exception)\n\t\t\t\t{\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn base.QueryClose(out canClose);\n\t\t}\n\n\t\t#endregion\n\n\t\tpublic void ShowMessage(string format, params object[] items)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tShowMessage(OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, OLEMSGICON.OLEMSGICON_INFO, format, items);\n\t\t}\n\n\t\tpublic void ShowMessage(OLEMSGICON icon, string format, params object[] items)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tShowMessage(OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, icon, format, items);\n\t\t}\n\n\t\tpublic int ShowMessage(OLEMSGBUTTON buttons, OLEMSGDEFBUTTON defaultButton, OLEMSGICON icon, string format, params object[] items)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tIVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell));\n\t\t\tif (uiShell == null)\n\t\t\t{\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\tGuid clsid = Guid.Empty;\n\t\t\tint result;\n\t\t\tMicrosoft.VisualStudio.ErrorHandler.ThrowOnFailure(\n\t\t\t\tuiShell.ShowMessageBox(\n\t\t\t\t\t0,\n\t\t\t\t\tref clsid,\n\t\t\t\t\t\"ILSpy AddIn\",\n\t\t\t\t\tstring.Format(CultureInfo.CurrentCulture, format, items),\n\t\t\t\t\tstring.Empty,\n\t\t\t\t\t0,\n\t\t\t\t\tbuttons,\n\t\t\t\t\tdefaultButton,\n\t\t\t\t\ticon,\n\t\t\t\t\t0,        // false\n\t\t\t\t\tout result\n\t\t\t\t)\n\t\t\t);\n\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic IEnumerable<T> GetSelectedItemsData<T>()\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tif (DTE.ToolWindows.SolutionExplorer.SelectedItems is IEnumerable<UIHierarchyItem> hierarchyItems)\n\t\t\t{\n\t\t\t\tforeach (var item in hierarchyItems)\n\t\t\t\t{\n\t\t\t\t\tif (item.Object is T typedItem)\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return typedItem;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy.AddIn.Shared/ILSpyInstance.cs",
    "content": "using System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Runtime.InteropServices;\n\nnamespace ICSharpCode.ILSpy.AddIn\n{\n\tclass ILSpyParameters\n\t{\n\t\tpublic ILSpyParameters(IEnumerable<string> assemblyFileNames, params string[] arguments)\n\t\t{\n\t\t\tthis.AssemblyFileNames = assemblyFileNames.ToArray();\n\t\t\tthis.Arguments = arguments;\n\t\t}\n\n\t\tpublic string[] AssemblyFileNames { get; private set; }\n\t\tpublic string[] Arguments { get; private set; }\n\t}\n\n\tclass ILSpyInstance\n\t{\n\t\tinternal static readonly ConcurrentStack<string> TempFiles = new ConcurrentStack<string>();\n\n\t\treadonly ILSpyParameters parameters;\n\t\tpublic ILSpyInstance(ILSpyParameters parameters = null)\n\t\t{\n\t\t\tthis.parameters = parameters;\n\t\t}\n\n\t\tstatic string GetILSpyPath()\n\t\t{\n\t\t\t// Only VS2022 supports arm64, so we can gloss over 2017-2019 support\n\t\t\tstring archPathSegment = \"x64\";\n\t\t\tif (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)\n\t\t\t{\n\t\t\t\tarchPathSegment = \"arm64\";\n\t\t\t}\n\n\t\t\tvar basePath = Path.GetDirectoryName(typeof(ILSpyAddInPackage).Assembly.Location);\n\t\t\treturn Path.Combine(basePath, archPathSegment, \"ILSpy\", \"ILSpy.exe\");\n\t\t}\n\n\t\tpublic void Start()\n\t\t{\n\t\t\tvar commandLineArguments = parameters?.AssemblyFileNames?.Concat(parameters.Arguments);\n\t\t\tstring ilSpyExe = GetILSpyPath();\n\n\t\t\tconst string defaultOptions = \"--navigateto:none\";\n\t\t\tstring argumentsToPass = defaultOptions;\n\n\t\t\tif ((commandLineArguments != null) && commandLineArguments.Any())\n\t\t\t{\n\t\t\t\tstring assemblyArguments = string.Join(\"\\r\\n\", commandLineArguments);\n\n\t\t\t\tstring filepath = Path.GetTempFileName();\n\t\t\t\tFile.WriteAllText(filepath, assemblyArguments);\n\n\t\t\t\tTempFiles.Push(filepath);\n\n\t\t\t\targumentsToPass = $\"@\\\"{filepath}\\\"\";\n\t\t\t}\n\n\t\t\tvar process = new Process() {\n\t\t\t\tStartInfo = new ProcessStartInfo() {\n\t\t\t\t\tFileName = ilSpyExe,\n\t\t\t\t\tUseShellExecute = false,\n\t\t\t\t\tArguments = argumentsToPass\n\t\t\t\t}\n\t\t\t};\n\t\t\tprocess.Start();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.AddIn.Shared/PkgCmdID.cs",
    "content": "// PkgCmdID.cs\n// MUST match PkgCmdID.h\n\nnamespace ICSharpCode.ILSpy.AddIn\n{\n\tstatic class PkgCmdIDList\n\t{\n\t\tpublic const uint cmdidOpenILSpy = 0x100;\n\t\tpublic const uint cmdidOpenReferenceInILSpy = 0x200;\n\t\tpublic const uint cmdidOpenProjectOutputInILSpy = 0x300;\n\t\tpublic const uint cmdidOpenCodeItemInILSpy = 0x0400;\n\t};\n}"
  },
  {
    "path": "ILSpy.AddIn.Shared/Resources.Designer.cs",
    "content": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace ICSharpCode.ILSpy.AddIn {\n    using System;\n    \n    \n    /// <summary>\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\n    /// </summary>\n    // This class was auto-generated by the StronglyTypedResourceBuilder\n    // class via a tool like ResGen or Visual Studio.\n    // To add or remove a member, edit your .ResX file then rerun ResGen\n    // with the /str option, or rebuild your VS project.\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"16.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    internal class Resources {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal Resources() {\n        }\n        \n        /// <summary>\n        ///   Returns the cached ResourceManager instance used by this class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"ICSharpCode.ILSpy.AddIn.Resources\", typeof(Resources).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   Overrides the current thread's CurrentUICulture property for all\n        ///   resource lookups using this strongly typed resource class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Globalization.CultureInfo Culture {\n            get {\n                return resourceCulture;\n            }\n            set {\n                resourceCulture = value;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "ILSpy.AddIn.Shared/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n    VS SDK Notes: This resx file contains the resources that will be consumed directly by your package.\n    For example, if you chose to create a tool window, there is a resource with ID 'CanNotCreateWindow'. This\n    is used in VsPkg.cs to determine the string to show the user if there is an error when attempting to create\n    the tool window.\n\n    Resources that are accessed directly from your package *by Visual Studio* are stored in the VSPackage.resx \n    file.\n-->\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "ILSpy.AddIn.Shared/SyntaxNodeExtensions.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nusing Microsoft.CodeAnalysis;\nusing Microsoft.CodeAnalysis.CSharp;\nusing Microsoft.CodeAnalysis.CSharp.Syntax;\nusing Microsoft.CodeAnalysis.Shared.Extensions;\nusing Microsoft.CodeAnalysis.Text;\n\nusing Roslyn.Utilities;\n\nnamespace ICSharpCode.ILSpy.AddIn\n{\n\tstatic class SyntaxNodeExtensions\n\t{\n\t\tpublic static IEnumerable<SyntaxNode> GetAncestors(this SyntaxNode node)\n\t\t{\n\t\t\tvar current = node.Parent;\n\n\t\t\twhile (current != null)\n\t\t\t{\n\t\t\t\tyield return current;\n\n\t\t\t\tcurrent = current is IStructuredTriviaSyntax\n\t\t\t\t\t? ((IStructuredTriviaSyntax)current).ParentTrivia.Token.Parent\n\t\t\t\t\t: current.Parent;\n\t\t\t}\n\t\t}\n\n\t\tpublic static IEnumerable<TNode> GetAncestors<TNode>(this SyntaxNode node)\n\t\t\twhere TNode : SyntaxNode\n\t\t{\n\t\t\tvar current = node.Parent;\n\t\t\twhile (current != null)\n\t\t\t{\n\t\t\t\tif (current is TNode)\n\t\t\t\t{\n\t\t\t\t\tyield return (TNode)current;\n\t\t\t\t}\n\n\t\t\t\tcurrent = current is IStructuredTriviaSyntax\n\t\t\t\t\t? ((IStructuredTriviaSyntax)current).ParentTrivia.Token.Parent\n\t\t\t\t\t: current.Parent;\n\t\t\t}\n\t\t}\n\n\t\tpublic static TNode GetAncestor<TNode>(this SyntaxNode node)\n\t\t\twhere TNode : SyntaxNode\n\t\t{\n\t\t\tif (node == null)\n\t\t\t{\n\t\t\t\treturn default(TNode);\n\t\t\t}\n\n\t\t\treturn node.GetAncestors<TNode>().FirstOrDefault();\n\t\t}\n\n\t\tpublic static TNode GetAncestorOrThis<TNode>(this SyntaxNode node)\n\t\t\twhere TNode : SyntaxNode\n\t\t{\n\t\t\tif (node == null)\n\t\t\t{\n\t\t\t\treturn default(TNode);\n\t\t\t}\n\n\t\t\treturn node.GetAncestorsOrThis<TNode>().FirstOrDefault();\n\t\t}\n\n\t\tpublic static IEnumerable<TNode> GetAncestorsOrThis<TNode>(this SyntaxNode node)\n\t\t\twhere TNode : SyntaxNode\n\t\t{\n\t\t\tvar current = node;\n\t\t\twhile (current != null)\n\t\t\t{\n\t\t\t\tif (current is TNode)\n\t\t\t\t{\n\t\t\t\t\tyield return (TNode)current;\n\t\t\t\t}\n\n\t\t\t\tcurrent = current is IStructuredTriviaSyntax\n\t\t\t\t\t? ((IStructuredTriviaSyntax)current).ParentTrivia.Token.Parent\n\t\t\t\t\t: current.Parent;\n\t\t\t}\n\t\t}\n\n\t\tpublic static bool HasAncestor<TNode>(this SyntaxNode node)\n\t\t\twhere TNode : SyntaxNode\n\t\t{\n\t\t\treturn node.GetAncestors<TNode>().Any();\n\t\t}\n\n\t\tpublic static bool CheckParent<T>(this SyntaxNode node, Func<T, bool> valueChecker) where T : SyntaxNode\n\t\t{\n\t\t\tif (node == null)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar parentNode = node.Parent as T;\n\t\t\tif (parentNode == null)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn valueChecker(parentNode);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns true if is a given token is a child token of of a certain type of parent node.\n\t\t/// </summary>\n\t\t/// <typeparam name=\"TParent\">The type of the parent node.</typeparam>\n\t\t/// <param name=\"node\">The node that we are testing.</param>\n\t\t/// <param name=\"childGetter\">A function that, when given the parent node, returns the child token we are interested in.</param>\n\t\tpublic static bool IsChildNode<TParent>(this SyntaxNode node, Func<TParent, SyntaxNode> childGetter)\n\t\t\twhere TParent : SyntaxNode\n\t\t{\n\t\t\tvar ancestor = node.GetAncestor<TParent>();\n\t\t\tif (ancestor == null)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar ancestorNode = childGetter(ancestor);\n\n\t\t\treturn node == ancestorNode;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns true if this node is found underneath the specified child in the given parent.\n\t\t/// </summary>\n\t\tpublic static bool IsFoundUnder<TParent>(this SyntaxNode node, Func<TParent, SyntaxNode> childGetter)\n\t\t\twhere TParent : SyntaxNode\n\t\t{\n\t\t\tvar ancestor = node.GetAncestor<TParent>();\n\t\t\tif (ancestor == null)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar child = childGetter(ancestor);\n\n\t\t\t// See if node passes through child on the way up to ancestor.\n\t\t\treturn node.GetAncestorsOrThis<SyntaxNode>().Contains(child);\n\t\t}\n\n\t\tpublic static SyntaxNode GetCommonRoot(this SyntaxNode node1, SyntaxNode node2)\n\t\t{\n\t\t\t//Contract.ThrowIfTrue(node1.RawKind == 0 || node2.RawKind == 0);\n\n\t\t\t// find common starting node from two nodes.\n\t\t\t// as long as two nodes belong to same tree, there must be at least one common root (Ex, compilation unit)\n\t\t\tvar ancestors = node1.GetAncestorsOrThis<SyntaxNode>();\n\t\t\tvar set = new HashSet<SyntaxNode>(node2.GetAncestorsOrThis<SyntaxNode>());\n\n\t\t\treturn ancestors.First(set.Contains);\n\t\t}\n\n\t\tpublic static int Width(this SyntaxNode node)\n\t\t{\n\t\t\treturn node.Span.Length;\n\t\t}\n\n\t\tpublic static int FullWidth(this SyntaxNode node)\n\t\t{\n\t\t\treturn node.FullSpan.Length;\n\t\t}\n\n\t\tpublic static SyntaxNode FindInnermostCommonNode(\n\t\t\tthis IEnumerable<SyntaxNode> nodes,\n\t\t\tFunc<SyntaxNode, bool> predicate)\n\t\t{\n\t\t\tIEnumerable<SyntaxNode> blocks = null;\n\t\t\tforeach (var node in nodes)\n\t\t\t{\n\t\t\t\tblocks = blocks == null\n\t\t\t\t\t? node.AncestorsAndSelf().Where(predicate)\n\t\t\t\t\t: blocks.Intersect(node.AncestorsAndSelf().Where(predicate));\n\t\t\t}\n\n\t\t\treturn blocks == null ? null : blocks.First();\n\t\t}\n\n\t\tpublic static TSyntaxNode FindInnermostCommonNode<TSyntaxNode>(this IEnumerable<SyntaxNode> nodes)\n\t\t\twhere TSyntaxNode : SyntaxNode\n\t\t{\n\t\t\treturn (TSyntaxNode)nodes.FindInnermostCommonNode(n => n is TSyntaxNode);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// create a new root node from the given root after adding annotations to the tokens\n\t\t/// \n\t\t/// tokens should belong to the given root\n\t\t/// </summary>\n\t\tpublic static SyntaxNode AddAnnotations(this SyntaxNode root, IEnumerable<Tuple<SyntaxToken, SyntaxAnnotation>> pairs)\n\t\t{\n\t\t\t//\t\t\tContract.ThrowIfNull(root);\n\t\t\t//\t\t\tContract.ThrowIfNull(pairs);\n\n\t\t\tvar tokenMap = pairs.GroupBy(p => p.Item1, p => p.Item2).ToDictionary(g => g.Key, g => g.ToArray());\n\t\t\treturn root.ReplaceTokens(tokenMap.Keys, (o, n) => o.WithAdditionalAnnotations(tokenMap[o]));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// create a new root node from the given root after adding annotations to the nodes\n\t\t/// \n\t\t/// nodes should belong to the given root\n\t\t/// </summary>\n\t\tpublic static SyntaxNode AddAnnotations(this SyntaxNode root, IEnumerable<Tuple<SyntaxNode, SyntaxAnnotation>> pairs)\n\t\t{\n\t\t\t//\t\t\tContract.ThrowIfNull(root);\n\t\t\t//\t\t\tContract.ThrowIfNull(pairs);\n\n\t\t\tvar tokenMap = pairs.GroupBy(p => p.Item1, p => p.Item2).ToDictionary(g => g.Key, g => g.ToArray());\n\t\t\treturn root.ReplaceNodes(tokenMap.Keys, (o, n) => o.WithAdditionalAnnotations(tokenMap[o]));\n\t\t}\n\n\t\tpublic static TextSpan GetContainedSpan(this IEnumerable<SyntaxNode> nodes)\n\t\t{\n\t\t\t//\t\t\tContract.ThrowIfNull(nodes);\n\t\t\t//\t\t\tContract.ThrowIfFalse(nodes.Any());\n\n\t\t\tTextSpan fullSpan = nodes.First().Span;\n\t\t\tforeach (var node in nodes)\n\t\t\t{\n\t\t\t\tfullSpan = TextSpan.FromBounds(\n\t\t\t\t\tMath.Min(fullSpan.Start, node.SpanStart),\n\t\t\t\t\tMath.Max(fullSpan.End, node.Span.End));\n\t\t\t}\n\n\t\t\treturn fullSpan;\n\t\t}\n\n\t\tpublic static IEnumerable<TextSpan> GetContiguousSpans(\n\t\t\tthis IEnumerable<SyntaxNode> nodes, Func<SyntaxNode, SyntaxToken> getLastToken = null)\n\t\t{\n\t\t\tSyntaxNode lastNode = null;\n\t\t\tTextSpan? textSpan = null;\n\t\t\tforeach (var node in nodes)\n\t\t\t{\n\t\t\t\tif (lastNode == null)\n\t\t\t\t{\n\t\t\t\t\ttextSpan = node.Span;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tvar lastToken = getLastToken == null\n\t\t\t\t\t\t? lastNode.GetLastToken()\n\t\t\t\t\t\t: getLastToken(lastNode);\n\t\t\t\t\tif (lastToken.GetNextToken(includeDirectives: true) == node.GetFirstToken())\n\t\t\t\t\t{\n\t\t\t\t\t\t// Expand the span\n\t\t\t\t\t\ttextSpan = TextSpan.FromBounds(textSpan.Value.Start, node.Span.End);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t// Return the last span, and start a new one\n\t\t\t\t\t\tyield return textSpan.Value;\n\t\t\t\t\t\ttextSpan = node.Span;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlastNode = node;\n\t\t\t}\n\n\t\t\tif (textSpan.HasValue)\n\t\t\t{\n\t\t\t\tyield return textSpan.Value;\n\t\t\t}\n\t\t}\n\n\t\t//public static bool OverlapsHiddenPosition(this SyntaxNode node, CancellationToken cancellationToken)\n\t\t//{\n\t\t//\treturn node.OverlapsHiddenPosition(node.Span, cancellationToken);\n\t\t//}\n\n\t\t//public static bool OverlapsHiddenPosition(this SyntaxNode node, TextSpan span, CancellationToken cancellationToken)\n\t\t//{\n\t\t//\treturn node.SyntaxTree.OverlapsHiddenPosition(span, cancellationToken);\n\t\t//}\n\n\t\t//public static bool OverlapsHiddenPosition(this SyntaxNode declaration, SyntaxNode startNode, SyntaxNode endNode, CancellationToken cancellationToken)\n\t\t//{\n\t\t//\tvar start = startNode.Span.End;\n\t\t//\tvar end = endNode.SpanStart;\n\n\t\t//\tvar textSpan = TextSpan.FromBounds(start, end);\n\t\t//\treturn declaration.OverlapsHiddenPosition(textSpan, cancellationToken);\n\t\t//}\n\n\t\tpublic static IEnumerable<T> GetAnnotatedNodes<T>(this SyntaxNode node, SyntaxAnnotation syntaxAnnotation) where T : SyntaxNode\n\t\t{\n\t\t\treturn node.GetAnnotatedNodesAndTokens(syntaxAnnotation).Select(n => n.AsNode()).OfType<T>();\n\t\t}\n\n\t\tpublic static bool IsKind(this SyntaxNode node, SyntaxKind kind1, SyntaxKind kind2)\n\t\t{\n\t\t\tif (node == null)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar csharpKind = node.Kind();\n\t\t\treturn csharpKind == kind1 || csharpKind == kind2;\n\t\t}\n\n\t\tpublic static bool IsKind(this SyntaxNode node, SyntaxKind kind1, SyntaxKind kind2, SyntaxKind kind3)\n\t\t{\n\t\t\tif (node == null)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar csharpKind = node.Kind();\n\t\t\treturn csharpKind == kind1 || csharpKind == kind2 || csharpKind == kind3;\n\t\t}\n\n\t\tpublic static bool IsKind(this SyntaxNode node, SyntaxKind kind1, SyntaxKind kind2, SyntaxKind kind3, SyntaxKind kind4)\n\t\t{\n\t\t\tif (node == null)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar csharpKind = node.Kind();\n\t\t\treturn csharpKind == kind1 || csharpKind == kind2 || csharpKind == kind3 || csharpKind == kind4;\n\t\t}\n\n\t\tpublic static bool IsKind(this SyntaxNode node, SyntaxKind kind1, SyntaxKind kind2, SyntaxKind kind3, SyntaxKind kind4, SyntaxKind kind5)\n\t\t{\n\t\t\tif (node == null)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar csharpKind = node.Kind();\n\t\t\treturn csharpKind == kind1 || csharpKind == kind2 || csharpKind == kind3 || csharpKind == kind4 || csharpKind == kind5;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the list of using directives that affect <paramref name=\"node\"/>. The list will be returned in\n\t\t/// top down order.  \n\t\t/// </summary>\n\t\tpublic static IEnumerable<UsingDirectiveSyntax> GetEnclosingUsingDirectives(this SyntaxNode node)\n\t\t{\n\t\t\treturn node.GetAncestorOrThis<CompilationUnitSyntax>().Usings\n\t\t\t\t.Concat(node.GetAncestorsOrThis<NamespaceDeclarationSyntax>()\n\t\t\t\t\t.Reverse()\n\t\t\t\t\t.SelectMany(n => n.Usings));\n\t\t}\n\n\t\tpublic static bool IsUnsafeContext(this SyntaxNode node)\n\t\t{\n\t\t\tif (node.GetAncestor<UnsafeStatementSyntax>() != null)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn node.GetAncestors<MemberDeclarationSyntax>().Any(\n\t\t\t\tm => m.GetModifiers().Any(SyntaxKind.UnsafeKeyword));\n\t\t}\n\n\t\tpublic static bool IsInStaticContext(this SyntaxNode node)\n\t\t{\n\t\t\t// this/base calls are always static.\n\t\t\tif (node.FirstAncestorOrSelf<ConstructorInitializerSyntax>() != null)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tvar memberDeclaration = node.FirstAncestorOrSelf<MemberDeclarationSyntax>();\n\t\t\tif (memberDeclaration == null)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tswitch (memberDeclaration.Kind())\n\t\t\t{\n\t\t\t\tcase SyntaxKind.MethodDeclaration:\n\t\t\t\tcase SyntaxKind.ConstructorDeclaration:\n\t\t\t\tcase SyntaxKind.PropertyDeclaration:\n\t\t\t\tcase SyntaxKind.EventDeclaration:\n\t\t\t\tcase SyntaxKind.IndexerDeclaration:\n\t\t\t\t\treturn memberDeclaration.GetModifiers().Any(SyntaxKind.StaticKeyword);\n\n\t\t\t\tcase SyntaxKind.FieldDeclaration:\n\t\t\t\t\t// Inside a field one can only access static members of a type.\n\t\t\t\t\treturn true;\n\n\t\t\t\tcase SyntaxKind.DestructorDeclaration:\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Global statements are not a static context.\n\t\t\tif (node.FirstAncestorOrSelf<GlobalStatementSyntax>() != null)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// any other location is considered static\n\t\t\treturn true;\n\t\t}\n\n\t\tpublic static NamespaceDeclarationSyntax GetInnermostNamespaceDeclarationWithUsings(this SyntaxNode contextNode)\n\t\t{\n\t\t\tvar usingDirectiveAncestor = contextNode.GetAncestor<UsingDirectiveSyntax>();\n\t\t\tif (usingDirectiveAncestor == null)\n\t\t\t{\n\t\t\t\treturn contextNode.GetAncestorsOrThis<NamespaceDeclarationSyntax>().FirstOrDefault(n => n.Usings.Count > 0);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// We are inside a using directive. In this case, we should find and return the first 'parent' namespace with usings.\n\t\t\t\tvar containingNamespace = usingDirectiveAncestor.GetAncestor<NamespaceDeclarationSyntax>();\n\t\t\t\tif (containingNamespace == null)\n\t\t\t\t{\n\t\t\t\t\t// We are inside a top level using directive (i.e. one that's directly in the compilation unit).\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn containingNamespace.GetAncestors<NamespaceDeclarationSyntax>().FirstOrDefault(n => n.Usings.Count > 0);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns all of the trivia to the left of this token up to the previous token (concatenates\n\t\t/// the previous token's trailing trivia and this token's leading trivia).\n\t\t/// </summary>\n\t\tpublic static IEnumerable<SyntaxTrivia> GetAllPrecedingTriviaToPreviousToken(this SyntaxToken token)\n\t\t{\n\t\t\tvar prevToken = token.GetPreviousToken(includeSkipped: true);\n\t\t\tif (prevToken.Kind() == SyntaxKind.None)\n\t\t\t{\n\t\t\t\treturn token.LeadingTrivia;\n\t\t\t}\n\n\t\t\treturn prevToken.TrailingTrivia.Concat(token.LeadingTrivia);\n\t\t}\n\n\t\tpublic static bool IsBreakableConstruct(this SyntaxNode node)\n\t\t{\n\t\t\tswitch (node.Kind())\n\t\t\t{\n\t\t\t\tcase SyntaxKind.DoStatement:\n\t\t\t\tcase SyntaxKind.WhileStatement:\n\t\t\t\tcase SyntaxKind.SwitchStatement:\n\t\t\t\tcase SyntaxKind.ForStatement:\n\t\t\t\tcase SyntaxKind.ForEachStatement:\n\t\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool IsContinuableConstruct(this SyntaxNode node)\n\t\t{\n\t\t\tswitch (node.Kind())\n\t\t\t{\n\t\t\t\tcase SyntaxKind.DoStatement:\n\t\t\t\tcase SyntaxKind.WhileStatement:\n\t\t\t\tcase SyntaxKind.ForStatement:\n\t\t\t\tcase SyntaxKind.ForEachStatement:\n\t\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool IsReturnableConstruct(this SyntaxNode node)\n\t\t{\n\t\t\tswitch (node.Kind())\n\t\t\t{\n\t\t\t\tcase SyntaxKind.AnonymousMethodExpression:\n\t\t\t\tcase SyntaxKind.SimpleLambdaExpression:\n\t\t\t\tcase SyntaxKind.ParenthesizedLambdaExpression:\n\t\t\t\tcase SyntaxKind.MethodDeclaration:\n\t\t\t\tcase SyntaxKind.ConstructorDeclaration:\n\t\t\t\tcase SyntaxKind.DestructorDeclaration:\n\t\t\t\tcase SyntaxKind.GetAccessorDeclaration:\n\t\t\t\tcase SyntaxKind.SetAccessorDeclaration:\n\t\t\t\tcase SyntaxKind.OperatorDeclaration:\n\t\t\t\tcase SyntaxKind.AddAccessorDeclaration:\n\t\t\t\tcase SyntaxKind.RemoveAccessorDeclaration:\n\t\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool IsAnyArgumentList(this SyntaxNode node)\n\t\t{\n\t\t\treturn node.IsKind(SyntaxKind.ArgumentList) ||\n\t\t\t\tnode.IsKind(SyntaxKind.AttributeArgumentList) ||\n\t\t\t\tnode.IsKind(SyntaxKind.BracketedArgumentList) ||\n\t\t\t\tnode.IsKind(SyntaxKind.TypeArgumentList);\n\t\t}\n\n\t\tpublic static bool IsAnyLambda(this SyntaxNode node)\n\t\t{\n\t\t\treturn\n\t\t\t\tnode.IsKind(SyntaxKind.ParenthesizedLambdaExpression) ||\n\t\t\t\tnode.IsKind(SyntaxKind.SimpleLambdaExpression);\n\t\t}\n\n\t\tpublic static bool IsAnyLambdaOrAnonymousMethod(this SyntaxNode node)\n\t\t{\n\t\t\treturn node.IsAnyLambda() || node.IsKind(SyntaxKind.AnonymousMethodExpression);\n\t\t}\n\n\t\tpublic static bool IsAnyAssignExpression(this SyntaxNode node)\n\t\t{\n\t\t\treturn SyntaxFacts.IsAssignmentExpression(node.Kind());\n\t\t}\n\n\t\tpublic static bool IsParentKind(this SyntaxNode node, SyntaxKind kind)\n\t\t{\n\t\t\treturn node != null && node.Parent.IsKind(kind);\n\t\t}\n\n\t\tpublic static bool IsParentKind(this SyntaxToken node, SyntaxKind kind)\n\t\t{\n\t\t\treturn node.Parent != null && node.Parent.IsKind(kind);\n\t\t}\n\n\t\tpublic static bool IsCompoundAssignExpression(this SyntaxNode node)\n\t\t{\n\t\t\tswitch (node.Kind())\n\t\t\t{\n\t\t\t\tcase SyntaxKind.AddAssignmentExpression:\n\t\t\t\tcase SyntaxKind.SubtractAssignmentExpression:\n\t\t\t\tcase SyntaxKind.MultiplyAssignmentExpression:\n\t\t\t\tcase SyntaxKind.DivideAssignmentExpression:\n\t\t\t\tcase SyntaxKind.ModuloAssignmentExpression:\n\t\t\t\tcase SyntaxKind.AndAssignmentExpression:\n\t\t\t\tcase SyntaxKind.ExclusiveOrAssignmentExpression:\n\t\t\t\tcase SyntaxKind.OrAssignmentExpression:\n\t\t\t\tcase SyntaxKind.LeftShiftAssignmentExpression:\n\t\t\t\tcase SyntaxKind.RightShiftAssignmentExpression:\n\t\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool IsLeftSideOfAssignExpression(this SyntaxNode node)\n\t\t{\n\t\t\treturn node.IsParentKind(SyntaxKind.SimpleAssignmentExpression) &&\n\t\t\t\t((AssignmentExpressionSyntax)node.Parent).Left == node;\n\t\t}\n\n\t\tpublic static bool IsLeftSideOfAnyAssignExpression(this SyntaxNode node)\n\t\t{\n\t\t\treturn node.Parent.IsAnyAssignExpression() &&\n\t\t\t\t((AssignmentExpressionSyntax)node.Parent).Left == node;\n\t\t}\n\n\t\tpublic static bool IsRightSideOfAnyAssignExpression(this SyntaxNode node)\n\t\t{\n\t\t\treturn node.Parent.IsAnyAssignExpression() &&\n\t\t\t\t((AssignmentExpressionSyntax)node.Parent).Right == node;\n\t\t}\n\n\t\tpublic static bool IsVariableDeclaratorValue(this SyntaxNode node)\n\t\t{\n\t\t\treturn\n\t\t\t\tnode.IsParentKind(SyntaxKind.EqualsValueClause) &&\n\t\t\t\tnode.Parent.IsParentKind(SyntaxKind.VariableDeclarator) &&\n\t\t\t\t((EqualsValueClauseSyntax)node.Parent).Value == node;\n\t\t}\n\n\t\tpublic static BlockSyntax FindInnermostCommonBlock(this IEnumerable<SyntaxNode> nodes)\n\t\t{\n\t\t\treturn nodes.FindInnermostCommonNode<BlockSyntax>();\n\t\t}\n\n\t\tpublic static IEnumerable<SyntaxNode> GetAncestorsOrThis(this SyntaxNode node, Func<SyntaxNode, bool> predicate)\n\t\t{\n\t\t\tvar current = node;\n\t\t\twhile (current != null)\n\t\t\t{\n\t\t\t\tif (predicate(current))\n\t\t\t\t{\n\t\t\t\t\tyield return current;\n\t\t\t\t}\n\n\t\t\t\tcurrent = current.Parent;\n\t\t\t}\n\t\t}\n\n\t\tpublic static SyntaxNode GetParent(this SyntaxNode node)\n\t\t{\n\t\t\treturn node != null ? node.Parent : null;\n\t\t}\n\n\t\tpublic static ValueTuple<SyntaxToken, SyntaxToken> GetBraces(this SyntaxNode node)\n\t\t{\n\t\t\tvar namespaceNode = node as NamespaceDeclarationSyntax;\n\t\t\tif (namespaceNode != null)\n\t\t\t{\n\t\t\t\treturn ValueTuple.Create(namespaceNode.OpenBraceToken, namespaceNode.CloseBraceToken);\n\t\t\t}\n\n\t\t\tvar baseTypeNode = node as BaseTypeDeclarationSyntax;\n\t\t\tif (baseTypeNode != null)\n\t\t\t{\n\t\t\t\treturn ValueTuple.Create(baseTypeNode.OpenBraceToken, baseTypeNode.CloseBraceToken);\n\t\t\t}\n\n\t\t\tvar accessorListNode = node as AccessorListSyntax;\n\t\t\tif (accessorListNode != null)\n\t\t\t{\n\t\t\t\treturn ValueTuple.Create(accessorListNode.OpenBraceToken, accessorListNode.CloseBraceToken);\n\t\t\t}\n\n\t\t\tvar blockNode = node as BlockSyntax;\n\t\t\tif (blockNode != null)\n\t\t\t{\n\t\t\t\treturn ValueTuple.Create(blockNode.OpenBraceToken, blockNode.CloseBraceToken);\n\t\t\t}\n\n\t\t\tvar switchStatementNode = node as SwitchStatementSyntax;\n\t\t\tif (switchStatementNode != null)\n\t\t\t{\n\t\t\t\treturn ValueTuple.Create(switchStatementNode.OpenBraceToken, switchStatementNode.CloseBraceToken);\n\t\t\t}\n\n\t\t\tvar anonymousObjectCreationExpression = node as AnonymousObjectCreationExpressionSyntax;\n\t\t\tif (anonymousObjectCreationExpression != null)\n\t\t\t{\n\t\t\t\treturn ValueTuple.Create(anonymousObjectCreationExpression.OpenBraceToken, anonymousObjectCreationExpression.CloseBraceToken);\n\t\t\t}\n\n\t\t\tvar initializeExpressionNode = node as InitializerExpressionSyntax;\n\t\t\tif (initializeExpressionNode != null)\n\t\t\t{\n\t\t\t\treturn ValueTuple.Create(initializeExpressionNode.OpenBraceToken, initializeExpressionNode.CloseBraceToken);\n\t\t\t}\n\n\t\t\treturn new ValueTuple<SyntaxToken, SyntaxToken>();\n\t\t}\n\n\t\tpublic static SyntaxTokenList GetModifiers(this SyntaxNode member)\n\t\t{\n\t\t\tif (member != null)\n\t\t\t{\n\t\t\t\tswitch (member.Kind())\n\t\t\t\t{\n\t\t\t\t\tcase SyntaxKind.EnumDeclaration:\n\t\t\t\t\t\treturn ((EnumDeclarationSyntax)member).Modifiers;\n\t\t\t\t\tcase SyntaxKind.ClassDeclaration:\n\t\t\t\t\tcase SyntaxKind.InterfaceDeclaration:\n\t\t\t\t\tcase SyntaxKind.StructDeclaration:\n\t\t\t\t\t\treturn ((TypeDeclarationSyntax)member).Modifiers;\n\t\t\t\t\tcase SyntaxKind.DelegateDeclaration:\n\t\t\t\t\t\treturn ((DelegateDeclarationSyntax)member).Modifiers;\n\t\t\t\t\tcase SyntaxKind.FieldDeclaration:\n\t\t\t\t\t\treturn ((FieldDeclarationSyntax)member).Modifiers;\n\t\t\t\t\tcase SyntaxKind.EventFieldDeclaration:\n\t\t\t\t\t\treturn ((EventFieldDeclarationSyntax)member).Modifiers;\n\t\t\t\t\tcase SyntaxKind.ConstructorDeclaration:\n\t\t\t\t\t\treturn ((ConstructorDeclarationSyntax)member).Modifiers;\n\t\t\t\t\tcase SyntaxKind.DestructorDeclaration:\n\t\t\t\t\t\treturn ((DestructorDeclarationSyntax)member).Modifiers;\n\t\t\t\t\tcase SyntaxKind.PropertyDeclaration:\n\t\t\t\t\t\treturn ((PropertyDeclarationSyntax)member).Modifiers;\n\t\t\t\t\tcase SyntaxKind.EventDeclaration:\n\t\t\t\t\t\treturn ((EventDeclarationSyntax)member).Modifiers;\n\t\t\t\t\tcase SyntaxKind.IndexerDeclaration:\n\t\t\t\t\t\treturn ((IndexerDeclarationSyntax)member).Modifiers;\n\t\t\t\t\tcase SyntaxKind.OperatorDeclaration:\n\t\t\t\t\t\treturn ((OperatorDeclarationSyntax)member).Modifiers;\n\t\t\t\t\tcase SyntaxKind.ConversionOperatorDeclaration:\n\t\t\t\t\t\treturn ((ConversionOperatorDeclarationSyntax)member).Modifiers;\n\t\t\t\t\tcase SyntaxKind.MethodDeclaration:\n\t\t\t\t\t\treturn ((MethodDeclarationSyntax)member).Modifiers;\n\t\t\t\t\tcase SyntaxKind.GetAccessorDeclaration:\n\t\t\t\t\tcase SyntaxKind.SetAccessorDeclaration:\n\t\t\t\t\tcase SyntaxKind.AddAccessorDeclaration:\n\t\t\t\t\tcase SyntaxKind.RemoveAccessorDeclaration:\n\t\t\t\t\t\treturn ((AccessorDeclarationSyntax)member).Modifiers;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn default(SyntaxTokenList);\n\t\t}\n\n\t\tpublic static SyntaxNode WithModifiers(this SyntaxNode member, SyntaxTokenList modifiers)\n\t\t{\n\t\t\tif (member != null)\n\t\t\t{\n\t\t\t\tswitch (member.Kind())\n\t\t\t\t{\n\t\t\t\t\tcase SyntaxKind.EnumDeclaration:\n\t\t\t\t\t\treturn ((EnumDeclarationSyntax)member).WithModifiers(modifiers);\n\t\t\t\t\tcase SyntaxKind.ClassDeclaration:\n\t\t\t\t\tcase SyntaxKind.InterfaceDeclaration:\n\t\t\t\t\tcase SyntaxKind.StructDeclaration:\n\t\t\t\t\t\treturn ((TypeDeclarationSyntax)member).WithModifiers(modifiers);\n\t\t\t\t\tcase SyntaxKind.DelegateDeclaration:\n\t\t\t\t\t\treturn ((DelegateDeclarationSyntax)member).WithModifiers(modifiers);\n\t\t\t\t\tcase SyntaxKind.FieldDeclaration:\n\t\t\t\t\t\treturn ((FieldDeclarationSyntax)member).WithModifiers(modifiers);\n\t\t\t\t\tcase SyntaxKind.EventFieldDeclaration:\n\t\t\t\t\t\treturn ((EventFieldDeclarationSyntax)member).WithModifiers(modifiers);\n\t\t\t\t\tcase SyntaxKind.ConstructorDeclaration:\n\t\t\t\t\t\treturn ((ConstructorDeclarationSyntax)member).WithModifiers(modifiers);\n\t\t\t\t\tcase SyntaxKind.DestructorDeclaration:\n\t\t\t\t\t\treturn ((DestructorDeclarationSyntax)member).WithModifiers(modifiers);\n\t\t\t\t\tcase SyntaxKind.PropertyDeclaration:\n\t\t\t\t\t\treturn ((PropertyDeclarationSyntax)member).WithModifiers(modifiers);\n\t\t\t\t\tcase SyntaxKind.EventDeclaration:\n\t\t\t\t\t\treturn ((EventDeclarationSyntax)member).WithModifiers(modifiers);\n\t\t\t\t\tcase SyntaxKind.IndexerDeclaration:\n\t\t\t\t\t\treturn ((IndexerDeclarationSyntax)member).WithModifiers(modifiers);\n\t\t\t\t\tcase SyntaxKind.OperatorDeclaration:\n\t\t\t\t\t\treturn ((OperatorDeclarationSyntax)member).WithModifiers(modifiers);\n\t\t\t\t\tcase SyntaxKind.ConversionOperatorDeclaration:\n\t\t\t\t\t\treturn ((ConversionOperatorDeclarationSyntax)member).WithModifiers(modifiers);\n\t\t\t\t\tcase SyntaxKind.MethodDeclaration:\n\t\t\t\t\t\treturn ((MethodDeclarationSyntax)member).WithModifiers(modifiers);\n\t\t\t\t\tcase SyntaxKind.GetAccessorDeclaration:\n\t\t\t\t\tcase SyntaxKind.SetAccessorDeclaration:\n\t\t\t\t\tcase SyntaxKind.AddAccessorDeclaration:\n\t\t\t\t\tcase SyntaxKind.RemoveAccessorDeclaration:\n\t\t\t\t\t\treturn ((AccessorDeclarationSyntax)member).WithModifiers(modifiers);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static TypeDeclarationSyntax WithModifiers(\n\t\t\tthis TypeDeclarationSyntax node, SyntaxTokenList modifiers)\n\t\t{\n\t\t\tswitch (node.Kind())\n\t\t\t{\n\t\t\t\tcase SyntaxKind.ClassDeclaration:\n\t\t\t\t\treturn ((ClassDeclarationSyntax)node).WithModifiers(modifiers);\n\t\t\t\tcase SyntaxKind.InterfaceDeclaration:\n\t\t\t\t\treturn ((InterfaceDeclarationSyntax)node).WithModifiers(modifiers);\n\t\t\t\tcase SyntaxKind.StructDeclaration:\n\t\t\t\t\treturn ((StructDeclarationSyntax)node).WithModifiers(modifiers);\n\t\t\t}\n\n\t\t\tthrow new InvalidOperationException();\n\t\t}\n\n\t\tpublic static bool CheckTopLevel(this SyntaxNode node, TextSpan span)\n\t\t{\n\t\t\tvar block = node as BlockSyntax;\n\t\t\tif (block != null)\n\t\t\t{\n\t\t\t\treturn block.ContainsInBlockBody(span);\n\t\t\t}\n\n\t\t\tvar field = node as FieldDeclarationSyntax;\n\t\t\tif (field != null)\n\t\t\t{\n\t\t\t\tforeach (var variable in field.Declaration.Variables)\n\t\t\t\t{\n\t\t\t\t\tif (variable.Initializer != null && variable.Initializer.Span.Contains(span))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar global = node as GlobalStatementSyntax;\n\t\t\tif (global != null)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tvar constructorInitializer = node as ConstructorInitializerSyntax;\n\t\t\tif (constructorInitializer != null)\n\t\t\t{\n\t\t\t\treturn constructorInitializer.ContainsInArgument(span);\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic static bool ContainsInArgument(this ConstructorInitializerSyntax initializer, TextSpan textSpan)\n\t\t{\n\t\t\tif (initializer == null)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn initializer.ArgumentList.Arguments.Any(a => a.Span.Contains(textSpan));\n\t\t}\n\n\t\tpublic static bool ContainsInBlockBody(this BlockSyntax block, TextSpan textSpan)\n\t\t{\n\t\t\tif (block == null)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar blockSpan = TextSpan.FromBounds(block.OpenBraceToken.Span.End, block.CloseBraceToken.SpanStart);\n\t\t\treturn blockSpan.Contains(textSpan);\n\t\t}\n\n\t\tpublic static bool IsDelegateOrConstructorOrMethodParameterList(this SyntaxNode node)\n\t\t{\n\t\t\tif (!node.IsKind(SyntaxKind.ParameterList))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn\n\t\t\t\tnode.IsParentKind(SyntaxKind.MethodDeclaration) ||\n\t\t\t\tnode.IsParentKind(SyntaxKind.ConstructorDeclaration) ||\n\t\t\t\tnode.IsParentKind(SyntaxKind.DelegateDeclaration);\n\t\t}\n\n\t}\n}\n"
  },
  {
    "path": "ILSpy.AddIn.Shared/Utils.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.IO;\nusing System.Linq;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\nusing EnvDTE;\n\nusing Microsoft.VisualStudio.Editor;\nusing Microsoft.VisualStudio.LanguageServices;\nusing Microsoft.VisualStudio.Shell;\nusing Microsoft.VisualStudio.Text;\nusing Microsoft.VisualStudio.Text.Editor;\nusing Microsoft.VisualStudio.TextManager.Interop;\n\nnamespace ICSharpCode.ILSpy.AddIn\n{\n\tpublic enum MessageButtonResult : int\n\t{\n\t\tIDOK = 1,\n\t\tIDCANCEL = 2,\n\t\tIDABORT = 3,\n\t\tIDRETRY = 4,\n\t\tIDIGNORE = 5,\n\t\tIDYES = 6,\n\t\tIDNO = 7,\n\t\tIDTRYAGAIN = 10,\n\t\tIDCONTINUE = 11,\n\t}\n\n\tstatic class Utils\n\t{\n\t\tpublic static byte[] HexStringToBytes(string hex)\n\t\t{\n\t\t\tif (hex == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(hex));\n\t\t\tvar result = new byte[hex.Length / 2];\n\t\t\tfor (int i = 0; i < hex.Length / 2; i++)\n\t\t\t{\n\t\t\t\tresult[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic static bool TryGetProjectFileName(dynamic referenceObject, out string fileName)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tfileName = referenceObject.Project.FileName;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tcatch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException)\n\t\t\t{\n\t\t\t\tfileName = null;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tpublic static object[] GetProperties(EnvDTE.Properties properties, params string[] names)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tvar values = new object[names.Length];\n\t\t\tforeach (object p in properties)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tif (p is Property property)\n\t\t\t\t\t{\n\t\t\t\t\t\tfor (int i = 0; i < names.Length; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (names[i] == property.Name)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvalues[i] = property.Value;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn values;\n\t\t}\n\n\t\tpublic static List<(string, object)> GetAllProperties(EnvDTE.Properties properties)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tvar result = new List<(string, object)>();\n\t\t\tfor (int i = 0; i < properties.Count; i++)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tif (properties.Item(i) is Property p)\n\t\t\t\t\t{\n\t\t\t\t\t\tresult.Add((p.Name, p.Value));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn result;\n\t\t}\n\n\t\tpublic static ITextSelection GetSelectionInCurrentView(IServiceProvider serviceProvider, Func<string, bool> predicate)\n\t\t{\n\t\t\tIWpfTextViewHost viewHost = GetCurrentViewHost(serviceProvider, predicate);\n\t\t\tif (viewHost == null)\n\t\t\t\treturn null;\n\n\t\t\treturn viewHost.TextView.Selection;\n\t\t}\n\n\t\tpublic static IWpfTextViewHost GetCurrentViewHost(IServiceProvider serviceProvider, Func<string, bool> predicate)\n\t\t{\n\t\t\tIWpfTextViewHost viewHost = GetCurrentViewHost(serviceProvider);\n\t\t\tif (viewHost == null)\n\t\t\t\treturn null;\n\n\t\t\tITextDocument textDocument = viewHost.GetTextDocument();\n\t\t\tif (textDocument == null || !predicate(textDocument.FilePath))\n\t\t\t\treturn null;\n\n\t\t\treturn viewHost;\n\t\t}\n\n\t\tpublic static IWpfTextViewHost GetCurrentViewHost(IServiceProvider serviceProvider)\n\t\t{\n\t\t\tIVsTextManager txtMgr = (IVsTextManager)serviceProvider.GetService(typeof(SVsTextManager));\n\t\t\tif (txtMgr == null)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tIVsTextView vTextView = null;\n\t\t\tint mustHaveFocus = 1;\n\t\t\ttxtMgr.GetActiveView(mustHaveFocus, null, out vTextView);\n\t\t\tIVsUserData userData = vTextView as IVsUserData;\n\t\t\tif (userData == null)\n\t\t\t\treturn null;\n\n\t\t\tobject holder;\n\t\t\tGuid guidViewHost = DefGuidList.guidIWpfTextViewHost;\n\t\t\tuserData.GetData(ref guidViewHost, out holder);\n\n\t\t\treturn holder as IWpfTextViewHost;\n\t\t}\n\n\t\tpublic static ITextDocument GetTextDocument(this IWpfTextViewHost viewHost)\n\t\t{\n\t\t\tITextDocument textDocument = null;\n\t\t\tviewHost.TextView.TextDataModel.DocumentBuffer.Properties.TryGetProperty(typeof(ITextDocument), out textDocument);\n\t\t\treturn textDocument;\n\t\t}\n\n\t\tpublic static VisualStudioWorkspace GetWorkspace(IServiceProvider serviceProvider)\n\t\t{\n\t\t\treturn (VisualStudioWorkspace)serviceProvider.GetService(typeof(VisualStudioWorkspace));\n\t\t}\n\n\t\tpublic static string GetProjectOutputAssembly(Project project, Microsoft.CodeAnalysis.Project roslynProject)\n\t\t{\n\t\t\tThreadHelper.ThrowIfNotOnUIThread();\n\n\t\t\tstring outputFileName = Path.GetFileName(roslynProject.OutputFilePath);\n\n\t\t\t// Get the directory path based on the project file.\n\t\t\tstring projectPath = Path.GetDirectoryName(project.FullName);\n\n\t\t\t// Get the output path based on the active configuration\n\t\t\tstring projectOutputPath = project.ConfigurationManager.ActiveConfiguration.Properties.Item(\"OutputPath\").Value.ToString();\n\n\t\t\t// Combine the project path and output path to get the bin path\n\t\t\tif ((projectPath != null) && (projectOutputPath != null) && (outputFileName != null))\n\t\t\t\treturn Path.Combine(projectPath, projectOutputPath, outputFileName);\n\n\t\t\treturn null;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.AddIn.Shared/VSPackage.en-US.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"110\" xml:space=\"preserve\">\n    <value>ILSpy.AddIn</value>\n  </data>\n  <data name=\"112\" xml:space=\"preserve\">\n    <value>Integration of the ILSpy Decompiler into Visual Studio.</value>\n  </data>\n</root>"
  },
  {
    "path": "ILSpy.AddIn.Shared/VSPackage.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n    VS SDK Notes: This resx file contains the resources that will be consumed from your package by Visual Studio.\n    For example, Visual Studio will attempt to load resource '400' from this resource stream when it needs to\n    load your package's icon. Because Visual Studio will always look in the VSPackage.resources stream first for\n    resources it needs, you should put additional resources that Visual Studio will load directly into this resx \n    file. \n\n    Resources that you would like to access directly from your package in a strong-typed fashion should be stored \n    in Resources.resx or another resx file.\n-->\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <assembly alias=\"System.Windows.Forms\" name=\"System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\" />\n  <data name=\"110\" xml:space=\"preserve\">\n    <value>ILSpy.AddIn</value>\n  </data>\n  <data name=\"112\" xml:space=\"preserve\">\n    <value>Integration of the ILSpy Decompiler into Visual Studio.</value>\n  </data>\n  <data name=\"400\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\ILSpy.AddIn\\Resources\\Package.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n</root>"
  },
  {
    "path": "ILSpy.AddIn.VS2022/Decompiler/Dummy.cs",
    "content": "// Dummy types so that we can use compile some ICS.Decompiler classes in the AddIn context\n// without depending on SRM etc.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace ICSharpCode.Decompiler\n{\n\tpublic class ReferenceLoadInfo\n\t{\n\t\tpublic void AddMessage(params object[] args) { }\n\t}\n\n\tenum MessageKind { Warning }\n\n\tpublic static class MetadataExtensions\n\t{\n\t\tpublic static string ToHexString(this IEnumerable<byte> bytes, int estimatedLength)\n\t\t{\n\t\t\tif (bytes == null)\n\t\t\t\tthrow new ArgumentNullException(nameof(bytes));\n\n\t\t\tStringBuilder sb = new StringBuilder(estimatedLength * 2);\n\t\t\tforeach (var b in bytes)\n\t\t\t\tsb.AppendFormat(\"{0:x2}\", b);\n\t\t\treturn sb.ToString();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.AddIn.VS2022/ILSpy.AddIn.VS2022.csproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project>\r\n  <Import Sdk=\"Microsoft.NET.Sdk\" Project=\"Sdk.props\" />\r\n\r\n  <PropertyGroup>\r\n    <TargetFramework>net472</TargetFramework>\r\n    <RootNamespace>ICSharpCode.ILSpy.AddIn</RootNamespace>\r\n\r\n    <Company>IC#Code</Company>\r\n    <Description>ILSpy</Description>\r\n    <Version>1.7.1.0</Version>\r\n    <FileVersion>1.7.1.0</FileVersion>\r\n    <LangVersion>9.0</LangVersion>\r\n\r\n    <EnableDefaultItems>False</EnableDefaultItems>\r\n    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>\r\n    <DefineConstants>TRACE;VSADDIN;VS2022</DefineConstants>\r\n\r\n    <SignAssembly>True</SignAssembly>\r\n    <AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile>\r\n    <NoWarn>\r\n      MSB3277;<!-- this is due to Visual Studio package references weirdness, see https://github.com/dotnet/roslyn/discussions/49787 -->\r\n      VSSDK1009\r\n    </NoWarn>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Debug'\">\r\n    <DebugType>full</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\r\n    <DebugType>pdbonly</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup>\r\n    <ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"Microsoft.VisualStudio.SDK\" Version=\"17.0.31902.203\" />\r\n    <PackageReference Include=\"Microsoft.CodeAnalysis\" Version=\"4.0.1\" />\r\n    <PackageReference Include=\"Microsoft.CodeAnalysis.CSharp\" Version=\"4.0.1\" />\r\n    <PackageReference Include=\"Microsoft.VisualStudio.LanguageServices\" Version=\"4.0.1\" />\r\n    <PackageReference Include=\"Microsoft.VSSDK.BuildTools\" Version=\"17.6.2164\">\r\n      <PrivateAssets>all</PrivateAssets>\r\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\r\n    </PackageReference>\r\n    <PackageReference Include=\"Mono.Cecil\" Version=\"0.11.5\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"TunnelVisionLabs.ReferenceAssemblyAnnotator\" Version=\"1.0.0-alpha.160\" PrivateAssets=\"all\" />\r\n\r\n    <!-- Specifies the version of Microsoft.NETCore.App.Ref to obtain nullability information from. -->\r\n    <PackageDownload Include=\"Microsoft.NETCore.App.Ref\" Version=\"[8.0.0]\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\AssemblyReferences.cs\" Link=\"Decompiler\\AssemblyReferences.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\DotNetCorePathFinder.cs\" Link=\"Decompiler\\DotNetCorePathFinder.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\LightJson\\JsonArray.cs\" Link=\"Decompiler\\LightJson\\JsonArray.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\LightJson\\JsonObject.cs\" Link=\"Decompiler\\LightJson\\JsonObject.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\LightJson\\JsonValue.cs\" Link=\"Decompiler\\LightJson\\JsonValue.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\LightJson\\JsonValueType.cs\" Link=\"Decompiler\\LightJson\\JsonValueType.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\LightJson\\Serialization\\JsonParseException.cs\" Link=\"Decompiler\\LightJson\\Serialization\\JsonParseException.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\LightJson\\Serialization\\JsonReader.cs\" Link=\"Decompiler\\LightJson\\Serialization\\JsonReader.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\LightJson\\Serialization\\TextPosition.cs\" Link=\"Decompiler\\LightJson\\Serialization\\TextPosition.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\LightJson\\Serialization\\TextScanner.cs\" Link=\"Decompiler\\LightJson\\Serialization\\TextScanner.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Metadata\\UniversalAssemblyResolver.cs\" Link=\"UniversalAssemblyResolver.cs\" />\r\n    <Compile Include=\"..\\ICSharpCode.Decompiler\\Util\\EmptyList.cs\" Link=\"Decompiler\\EmptyList.cs\" />\r\n    <Compile Include=\"Decompiler\\Dummy.cs\" />\r\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\r\n  </ItemGroup>\r\n\r\n  <PropertyGroup>\r\n    <ILSpyBuildPathX64>..\\ILSpy\\bin\\$(Configuration)\\net10.0-windows\\win-x64\\publish\\fwdependent\\</ILSpyBuildPathX64>\r\n    <ILSpyBuildPathArm64>..\\ILSpy\\bin\\$(Configuration)\\net10.0-windows\\win-arm64\\publish\\fwdependent\\</ILSpyBuildPathArm64>\r\n  </PropertyGroup>\r\n\r\n  <Target Name=\"IncludeILSpyDistributionInVSIXSubFolder\" AfterTargets=\"ResolveProjectReferences\">\r\n    <ItemGroup>\r\n      <VSIXSourceItem Include=\"$(ILSpyBuildPathX64)*.dll;$(ILSpyBuildPathX64)ILSpy.exe;$(ILSpyBuildPathX64)*.json\">\r\n        <VSIXSubPath>\\x64\\ILSpy</VSIXSubPath>\r\n      </VSIXSourceItem>\r\n      <VSIXSourceItem Include=\"$(ILSpyBuildPathArm64)*.dll;$(ILSpyBuildPathArm64)ILSpy.exe;$(ILSpyBuildPathArm64)*.json\">\r\n        <VSIXSubPath>\\arm64\\ILSpy</VSIXSubPath>\r\n      </VSIXSourceItem>\r\n    </ItemGroup>\r\n  </Target>\r\n\r\n  <ItemGroup>\r\n    <Content Include=\"$(OutputPath)Mono.Cecil.dll\">\r\n      <IncludeInVSIX>true</IncludeInVSIX>\r\n      <VSIXSubPath>\\</VSIXSubPath>\r\n    </Content>\r\n    <Content Include=\"ILSpy-Large.ico\">\r\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\r\n      <IncludeInVSIX>true</IncludeInVSIX>\r\n    </Content>\r\n    <Content Include=\"Resources\\Images.png\" />\r\n    <Content Include=\"Resources\\Package.ico\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <None Include=\"ILSpyAddIn.en-US.vsct\">\r\n      <SubType>Designer</SubType>\r\n    </None>\r\n    <None Include=\"ILSpyAddIn.vsct\">\r\n      <SubType>Designer</SubType>\r\n    </None>\r\n    <None Include=\"source.extension.vsixmanifest.template\" />\r\n    <None Include=\"source.extension.vsixmanifest\">\r\n      <SubType>Designer</SubType>\r\n    </None>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <VSCTCompile Include=\"ILSpyAddIn.en-US.vsct\">\r\n      <ResourceName>Menus.ctmenu</ResourceName>\r\n      <SubType>Designer</SubType>\r\n      <DependentUpon>ILSpyAddIn.vsct</DependentUpon>\r\n    </VSCTCompile>\r\n  </ItemGroup>\r\n  <ItemGroup>\r\n    <None Include=\"Key.snk\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <None Include=\"Properties\\launchSettings.json\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <Content Include=\"..\\LICENSE\" Link=\"license.txt\">\r\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\r\n      <IncludeInVSIX>true</IncludeInVSIX>\r\n    </Content>\r\n  </ItemGroup>\r\n\r\n  <PropertyGroup>\r\n    <UseCodebase>true</UseCodebase>\r\n    <RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild>\r\n    <RunAnalyzersDuringLiveAnalysis>true</RunAnalyzersDuringLiveAnalysis>\r\n    <Product>ILSpy.AddIn for Visual Studio 2022</Product>\r\n  </PropertyGroup>\r\n\r\n  <Import Project=\"..\\ILSpy.AddIn.Shared\\ILSpy.AddIn.Shared.projitems\" Label=\"Shared\" />\r\n\r\n  <Import Sdk=\"Microsoft.NET.Sdk\" Project=\"Sdk.targets\" />\r\n\r\n  <Import Project=\"$(VSToolsPath)\\VSSDK\\Microsoft.VsSDK.targets\" Condition=\"Exists('$(VSToolsPath)\\VSSDK\\Microsoft.VsSDK.targets')\" />\r\n\r\n  <ItemGroup>\r\n    <Compile Update=\"..\\ILSpy.AddIn.Shared\\Resources.Designer.cs\">\r\n      <DesignTime>True</DesignTime>\r\n    </Compile>\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <Folder Include=\"Resources\\\" />\r\n  </ItemGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "ILSpy.AddIn.VS2022/ILSpyAddIn.en-US.vsct",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<CommandTable xmlns=\"http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n\n  <!--  This is the file that defines the actual layout and type of the commands.\n        It is divided in different sections (e.g. command definition, command\n        placement, ...), with each defining a specific set of properties.\n        See the comment before each section for more details about how to\n        use it. -->\n\n  <!--  The VSCT compiler (the tool that translates this file into the binary \n        format that VisualStudio will consume) has the ability to run a preprocessor \n        on the vsct file; this preprocessor is (usually) the C++ preprocessor, so \n        it is possible to define includes and macros with the same syntax used \n        in C++ files. Using this ability of the compiler here, we include some files \n        defining some of the constants that we will use inside the file. -->\n\n  <!--This is the file that defines the IDs for all the commands exposed by VisualStudio. -->\n  <Extern href=\"stdidcmd.h\"/>\n\n  <!--This header contains the command ids for the menus provided by the shell. -->\n  <Extern href=\"vsshlids.h\"/>\n\n\n  <Include href=\"ILSpyAddIn.vsct\" />\n\n  <!--The Commands section is where we the commands, menus and menu groups are defined.\n      This section uses a Guid to identify the package that provides the command defined inside it. -->\n  <Commands package=\"guidILSpyAddInPkg\">\n    <!-- Inside this section we have different sub-sections: one for the menus, another  \n    for the menu groups, one for the buttons (the actual commands), one for the combos \n    and the last one for the bitmaps used. Each element is identified by a command id that  \n    is a unique pair of guid and numeric identifier; the guid part of the identifier is usually  \n    called \"command set\" and is used to group different command inside a logically related  \n    group; your package should define its own command set in order to avoid collisions  \n    with command ids defined by other packages. -->\n\n    \n    <!--Buttons section. -->\n    <!--This section defines the elements the user can interact with, like a menu command or a button \n        or combo box in a toolbar. -->\n    <Buttons>\n      <!--To define a menu group you have to specify its ID, the parent menu and its display priority. \n          The command is visible and enabled by default. If you need to change the visibility, status, etc, you can use\n          the CommandFlag node.\n          You can add more than one CommandFlag node e.g.:\n              <CommandFlag>DefaultInvisible</CommandFlag>\n              <CommandFlag>DynamicVisibility</CommandFlag>\n          If you do not want an image next to your command, remove the Icon node /> -->\n\n      <Button guid=\"guidILSpyAddInCmdSet\" id=\"cmdidOpenReferenceInILSpy\" priority=\"0x0600\" type=\"Button\">\n        <Parent guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyRefGroup\" />\n        <Icon guid=\"guidImages\" id=\"bmpLogo\" />\n        <CommandFlag>DynamicVisibility</CommandFlag>\n        <CommandFlag>DefaultInvisible</CommandFlag>\n        <Strings>\n          <ButtonText>Open in ILSpy</ButtonText>\n        </Strings>\n      </Button>\n      \n      <Button guid=\"guidILSpyAddInCmdSet\" id=\"cmdidOpenProjectOutputInILSpy\" priority=\"0x0600\" type=\"Button\">\n        <Parent guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyProjGroup\" />\n        <Icon guid=\"guidImages\" id=\"bmpLogo\" />\n        <CommandFlag>DynamicVisibility</CommandFlag>\n        <CommandFlag>DefaultInvisible</CommandFlag>\n        <Strings>\n          <ButtonText>Open output in ILSpy</ButtonText>\n        </Strings>\n      </Button>\n\n      <Button guid=\"guidILSpyAddInCmdSet\" id=\"cmdidOpenCodeItemInILSpy\" priority=\"0x0600\" type=\"Button\">\n        <Parent guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyCodeItemGroup\" />\n        <Icon guid=\"guidImages\" id=\"bmpLogo\" />\n        <CommandFlag>DynamicVisibility</CommandFlag>\n        <CommandFlag>DefaultInvisible</CommandFlag>\n        <Strings>\n          <ButtonText>Open code in ILSpy</ButtonText>\n        </Strings>\n      </Button>\n\n      <Button guid=\"guidILSpyAddInCmdSet\" id=\"cmdidOpenILSpy\" priority=\"0x0600\" type=\"Button\">\n        <Parent guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyGroup\" />\n        <Icon guid=\"guidImages\" id=\"bmpLogo\" />\n        <Strings>\n          <ButtonText>ILSpy</ButtonText>\n        </Strings>\n      </Button>\n    </Buttons>\n  </Commands>\n</CommandTable>\n"
  },
  {
    "path": "ILSpy.AddIn.VS2022/ILSpyAddIn.vsct",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<CommandTable xmlns=\"http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n\n  <!--  This is the file that defines the actual layout and type of the commands.\n        It is divided in different sections (e.g. command definition, command\n        placement, ...), with each defining a specific set of properties.\n        See the comment before each section for more details about how to\n        use it. -->\n\n  <!--  The VSCT compiler (the tool that translates this file into the binary \n        format that VisualStudio will consume) has the ability to run a preprocessor \n        on the vsct file; this preprocessor is (usually) the C++ preprocessor, so \n        it is possible to define includes and macros with the same syntax used \n        in C++ files. Using this ability of the compiler here, we include some files \n        defining some of the constants that we will use inside the file. -->\n\n  <!--This is the file that defines the IDs for all the commands exposed by VisualStudio. -->\n  <Extern href=\"stdidcmd.h\"/>\n\n  <!--This header contains the command ids for the menus provided by the shell. -->\n  <Extern href=\"vsshlids.h\"/>\n\n  <!--The Commands section is where we the commands, menus and menu groups are defined.\n      This section uses a Guid to identify the package that provides the command defined inside it. -->\n  <Commands package=\"guidILSpyAddInPkg\">\n    <!-- Inside this section we have different sub-sections: one for the menus, another  \n    for the menu groups, one for the buttons (the actual commands), one for the combos \n    and the last one for the bitmaps used. Each element is identified by a command id that  \n    is a unique pair of guid and numeric identifier; the guid part of the identifier is usually  \n    called \"command set\" and is used to group different command inside a logically related  \n    group; your package should define its own command set in order to avoid collisions  \n    with command ids defined by other packages. -->\n\n\n    <!-- In this section you can define new menu groups. A menu group is a container for \n         other menus or buttons (commands); from a visual point of view you can see the \n         group as the part of a menu contained between two lines. The parent of a group \n         must be a menu. -->\n    <Groups>\n      <Group guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyGroup\" priority=\"0x0200\">\n        <Parent guid=\"guidSHLMainMenu\" id=\"IDM_VS_MENU_TOOLS\"/>\n      </Group>\n\n      <Group guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyProjGroup\" priority=\"0x0200\">\n        <Parent guid=\"guidSHLMainMenu\" id=\"IDM_VS_CTXT_PROJNODE\"/>\n      </Group>\n\n      <Group guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyCodeItemGroup\" priority=\"0x0200\">\n        <Parent guid=\"guidSHLMainMenu\" id=\"IDM_VS_CTXT_CODEWIN\"/>\n      </Group>\n\n      <Group guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyRefGroup\" priority=\"0x0200\">\n        <Parent guid=\"guidSHLMainMenu\" id=\"IDM_VS_CTXT_REFERENCE\"/>\n      </Group>\n    </Groups>\n\n    <!--The bitmaps section is used to define the bitmaps that are used for the commands.-->\n    <Bitmaps>\n      <!--  The bitmap id is defined in a way that is a little bit different from the others: \n            the declaration starts with a guid for the bitmap strip, then there is the resource id of the \n            bitmap strip containing the bitmaps and then there are the numeric ids of the elements used \n            inside a button definition. An important aspect of this declaration is that the element id \n            must be the actual index (1-based) of the bitmap inside the bitmap strip. -->\n      <Bitmap guid=\"guidImages\" href=\"Resources\\Images.png\" usedList=\"bmpLogo, bmpPic1, bmpPic2, bmpPicX, bmpPicArrows\"/>\n    </Bitmaps>\n  </Commands>\n  <CommandPlacements>\n    <CommandPlacement guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyRefGroup\" priority=\"0x0200\">\n      <Parent guid=\"guidSHLMainMenu\" id=\"IDM_VS_CTXT_PACKAGEREFERENCE\"/>\n    </CommandPlacement>\n    <CommandPlacement guid=\"guidILSpyAddInCmdSet\" id=\"OpenILSpyRefGroup\" priority=\"0x0200\">\n      <Parent guid=\"guidSHLMainMenu\" id=\"IDM_VS_CTXT_PROJECTREFERENCE\"/>\n    </CommandPlacement>\n  </CommandPlacements>\n  <Symbols>\n    <!-- This is the package guid. -->\n    <GuidSymbol name=\"guidILSpyAddInPkg\" value=\"{ebf12ca7-a1fd-4aee-a894-4a0c5682fc2f}\" />\n\n    <!-- This is the guid used to group the menu commands together -->\n    <GuidSymbol name=\"guidILSpyAddInCmdSet\" value=\"{85ddb8ca-a842-4b1c-ba1a-94141fdf19d0}\">\n\n      <IDSymbol name=\"OpenILSpyGroup\" value=\"0x1010\" />\n      <IDSymbol name=\"OpenILSpyRefGroup\" value=\"0x1020\" />\n      <IDSymbol name=\"OpenILSpyProjGroup\" value=\"0x1030\" />\n      <IDSymbol name=\"OpenILSpyCodeItemGroup\" value=\"0x1040\" />\n      <IDSymbol name=\"OpenILSpyPackageRefGroup\" value=\"0x1050\" />\n      <IDSymbol name=\"OpenILSpyProjectRefGroup\" value=\"0x1060\" />\n      <IDSymbol name=\"cmdidOpenILSpy\" value=\"0x0100\" />\n      <IDSymbol name=\"cmdidOpenReferenceInILSpy\" value=\"0x0200\" />\n      <IDSymbol name=\"cmdidOpenProjectOutputInILSpy\" value=\"0x0300\" />\n      <IDSymbol name=\"cmdidOpenCodeItemInILSpy\" value=\"0x0400\" />\n    </GuidSymbol>\n\n    <GuidSymbol name=\"guidImages\" value=\"{2f654db9-4641-4638-9937-27c6202b2a6a}\" >\n      <IDSymbol name=\"bmpLogo\" value=\"1\" />\n      <IDSymbol name=\"bmpPic1\" value=\"2\" />\n      <IDSymbol name=\"bmpPic2\" value=\"3\" />\n      <IDSymbol name=\"bmpPicX\" value=\"4\" />\n      <IDSymbol name=\"bmpPicArrows\" value=\"5\" />\n      <IDSymbol name=\"bmpPicStrikethrough\" value=\"6\" />\n    </GuidSymbol>\n\n    <GuidSymbol name=\"guidReferenceContext\" value=\"{D309F791-903F-11D0-9EFC-00A0C911004F}\">\n      <IDSymbol name=\"IDM_VS_CTXT_PACKAGEREFERENCE\" value=\"0x04A3\"/>\n      <IDSymbol name=\"IDM_VS_CTXT_PROJECTREFERENCE\" value=\"0x04A7\"/>\n    </GuidSymbol>\n  </Symbols>\n\n</CommandTable>\n"
  },
  {
    "path": "ILSpy.AddIn.VS2022/Properties/AssemblyInfo.cs",
    "content": "using System;\nusing System.Reflection;\nusing System.Resources;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyCopyright(\"\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n[assembly: ComVisible(false)]\n[assembly: CLSCompliant(false)]\n[assembly: NeutralResourcesLanguage(\"en-US\", UltimateResourceFallbackLocation.Satellite)]\n[assembly: InternalsVisibleTo(\"ILSpy.AddIn_IntegrationTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100653c4a319be4f524972c3c5bba5fd243330f8e900287d9022d7821a63fd0086fd3801e3683dbe9897f2ecc44727023e9b40adcf180730af70c81c54476b3e5ba8b0f07f5132b2c3cc54347a2c1a9d64ebaaaf3cbffc1a18c427981e2a51d53d5ab02536b7550e732f795121c38a0abfdb38596353525d034baf9e6f1fd8ac4ac\")]\n[assembly: InternalsVisibleTo(\"ILSpy.AddIn_UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100653c4a319be4f524972c3c5bba5fd243330f8e900287d9022d7821a63fd0086fd3801e3683dbe9897f2ecc44727023e9b40adcf180730af70c81c54476b3e5ba8b0f07f5132b2c3cc54347a2c1a9d64ebaaaf3cbffc1a18c427981e2a51d53d5ab02536b7550e732f795121c38a0abfdb38596353525d034baf9e6f1fd8ac4ac\")]\n"
  },
  {
    "path": "ILSpy.AddIn.VS2022/Properties/launchSettings.json",
    "content": "{\n\t\"profiles\": {\n\t\t\"Visual Studio Extension\": {\n\t\t\t\"executablePath\": \"$(DevEnvDir)devenv.exe\",\n\t\t\t\"commandLineArgs\": \"/rootsuffix $(VSSDKTargetPlatformRegRootSuffix) /log\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.AddIn.VS2022/README.md",
    "content": "Test cases for various types of projects as well as corresponding test plans are located in a separate repository.\n\n[https://github.com/icsharpcode/ILSpy-Addin-tests](https://github.com/icsharpcode/ILSpy-Addin-tests)"
  },
  {
    "path": "ILSpy.AddIn.VS2022/source.extension.vsixmanifest.template",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<PackageManifest Version=\"2.0\" xmlns=\"http://schemas.microsoft.com/developer/vsx-schema/2011\" xmlns:d=\"http://schemas.microsoft.com/developer/vsx-schema-design/2011\">\n  <Metadata>\n    <Identity Id=\"ebf12ca7-a1fd-4aee-a894-4a0c5682fc2f\" Version=\"$INSERTVERSION$\" Language=\"en-US\" Publisher=\"SharpDevelop Team\" />\n    <DisplayName>ILSpy 2022</DisplayName>\n    <Description xml:space=\"preserve\">Integrates the ILSpy decompiler into Visual Studio.</Description>\n    <MoreInfo>https://ilspy.net</MoreInfo>\n    <License>LICENSE</License>\n    <Icon>ILSpy-Large.ico</Icon>\n\t<Tags>ILSpy;IL;decompile;decompiler;decompilation;C#;CSharp;.NET;Productivity;Open Source;Free</Tags>\n  </Metadata>\n  <Installation>\n\t<InstallationTarget Id=\"Microsoft.VisualStudio.Community\" Version =\"[17.0, 18.0)\">\n\t\t<ProductArchitecture>amd64</ProductArchitecture>\n\t</InstallationTarget>\n\t<InstallationTarget Id=\"Microsoft.VisualStudio.Community\" Version =\"[17.0, 18.0)\">\n\t\t<ProductArchitecture>arm64</ProductArchitecture>\n\t</InstallationTarget>\n  </Installation>\n  <Dependencies>\n    <Dependency Id=\"Microsoft.Framework.NDP\" DisplayName=\"Microsoft .NET Framework\" d:Source=\"Manual\" Version=\"[4.5,)\" />\n  </Dependencies>\n  <Assets>\n    <Asset Type=\"Microsoft.VisualStudio.MefComponent\" d:Source=\"Project\" d:ProjectName=\"ILSpy.AddIn.VS2022\" Path=\"|ILSpy.AddIn.VS2022|\"/>\n  </Assets>\n  <Prerequisites>\n    <Prerequisite Id=\"Microsoft.VisualStudio.Component.CoreEditor\" Version=\"[17.0,)\" DisplayName=\"Visual Studio core editor\" />\n    <Prerequisite Id=\"Microsoft.VisualStudio.Component.Roslyn.LanguageServices\" Version=\"[17.0,)\" DisplayName=\"Roslyn Language Services\" />\n  </Prerequisites>\n</PackageManifest>\n"
  },
  {
    "path": "ILSpy.BamlDecompiler/BamlResourceEntryNode.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.BamlDecompiler;\nusing ICSharpCode.ILSpy;\nusing ICSharpCode.ILSpy.TextView;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpy.ViewModels;\n\nnamespace ILSpy.BamlDecompiler\n{\n\tpublic sealed class BamlResourceEntryNode : ResourceEntryNode\n\t{\n\t\tpublic BamlResourceEntryNode(string key, Func<Stream> data) : base(key, data)\n\t\t{\n\t\t}\n\n\t\tpublic override bool View(TabPageModel tabPage)\n\t\t{\n\t\t\tIHighlightingDefinition highlighting = null;\n\n\t\t\ttabPage.SupportsLanguageSwitching = false;\n\t\t\ttabPage.ShowTextView(textView => textView.RunWithCancellation(\n\t\t\t\ttoken => Task.Factory.StartNew(\n\t\t\t\t\t() => {\n\t\t\t\t\t\tAvalonEditTextOutput output = new AvalonEditTextOutput();\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tLoadBaml(output, token);\n\t\t\t\t\t\t\thighlighting = HighlightingManager.Instance.GetDefinitionByExtension(\".xml\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (Exception ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toutput.Write(ex.ToString());\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn output;\n\t\t\t\t\t}, token))\n\t\t\t\t.Then(output => textView.ShowNode(output, this, highlighting))\n\t\t\t\t.HandleExceptions());\n\t\t\treturn true;\n\t\t}\n\n\t\tvoid LoadBaml(AvalonEditTextOutput output, CancellationToken cancellationToken)\n\t\t{\n\t\t\tvar asm = this.Ancestors().OfType<AssemblyTreeNode>().First().LoadedAssembly;\n\t\t\tusing var data = OpenStream();\n\t\t\tBamlDecompilerTypeSystem typeSystem = new BamlDecompilerTypeSystem(asm.GetMetadataFileOrNull(), asm.GetAssemblyResolver());\n\t\t\tvar decompiler = new XamlDecompiler(typeSystem, new BamlDecompilerSettings());\n\t\t\tdecompiler.CancellationToken = cancellationToken;\n\t\t\tvar result = decompiler.Decompile(data);\n\t\t\toutput.Write(result.Xaml.ToString());\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Composition;\nusing System.IO;\n\nusing ICSharpCode.BamlDecompiler;\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.CSharp.ProjectDecompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy;\nusing ICSharpCode.ILSpy.TreeNodes;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.Abstractions;\n\nnamespace ILSpy.BamlDecompiler\n{\n\t[Export(typeof(IResourceNodeFactory))]\n\t[Shared]\n\tpublic sealed class BamlResourceNodeFactory : IResourceNodeFactory\n\t{\n\t\tpublic ITreeNode CreateNode(Resource resource)\n\t\t{\n\t\t\tif (resource.Name.EndsWith(\".baml\", StringComparison.OrdinalIgnoreCase))\n\t\t\t\treturn new BamlResourceEntryNode(resource.Name, resource.TryOpenStream);\n\t\t\telse\n\t\t\t\treturn null;\n\t\t}\n\t}\n\n\t[Export(typeof(IResourceFileHandler))]\n\t[Shared]\n\tpublic sealed class BamlResourceFileHandler : IResourceFileHandler\n\t{\n\t\tpublic string EntryType => \"Page\";\n\t\tpublic bool CanHandle(string name, ResourceFileHandlerContext context) => name.EndsWith(\".baml\", StringComparison.OrdinalIgnoreCase);\n\n\t\tpublic string WriteResourceToFile(LoadedAssembly assembly, string fileName, Stream stream, ResourceFileHandlerContext context)\n\t\t{\n\t\t\tBamlDecompilerTypeSystem typeSystem = new BamlDecompilerTypeSystem(assembly.GetMetadataFileOrNull(), assembly.GetAssemblyResolver());\n\t\t\tvar decompiler = new XamlDecompiler(typeSystem, new BamlDecompilerSettings() {\n\t\t\t\tThrowOnAssemblyResolveErrors = context.DecompilationOptions.DecompilerSettings.ThrowOnAssemblyResolveErrors\n\t\t\t});\n\t\t\tdecompiler.CancellationToken = context.DecompilationOptions.CancellationToken;\n\t\t\tvar result = decompiler.Decompile(stream);\n\t\t\tvar typeDefinition = result.TypeName.HasValue ? typeSystem.MainModule.GetTypeDefinition(result.TypeName.Value.TopLevelTypeName) : null;\n\t\t\tif (typeDefinition != null)\n\t\t\t{\n\t\t\t\tfileName = WholeProjectDecompiler.SanitizeFileName(typeDefinition.ReflectionName + \".xaml\");\n\t\t\t\tvar partialTypeInfo = new PartialTypeInfo(typeDefinition);\n\t\t\t\tforeach (var member in result.GeneratedMembers)\n\t\t\t\t{\n\t\t\t\t\tpartialTypeInfo.AddDeclaredMember(member);\n\t\t\t\t}\n\t\t\t\tcontext.AddPartialTypeInfo(partialTypeInfo);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfileName = Path.ChangeExtension(fileName, \".xaml\");\n\t\t\t}\n\t\t\tcontext.AdditionalProperties.Add(\"Generator\", \"MSBuild:Compile\");\n\t\t\tcontext.AdditionalProperties.Add(\"SubType\", \"Designer\");\n\t\t\tstring saveFileName = Path.Combine(context.DecompilationOptions.SaveAsProjectDirectory, fileName);\n\t\t\tDirectory.CreateDirectory(Path.GetDirectoryName(saveFileName));\n\t\t\tresult.Xaml.Save(saveFileName);\n\t\t\treturn fileName;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project Sdk=\"Microsoft.NET.Sdk\">\r\n  <PropertyGroup>\r\n    <AssemblyName>ILSpy.BamlDecompiler.Plugin</AssemblyName>\r\n    <TargetFramework>net10.0-windows</TargetFramework>\r\n    <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers>\r\n    <IsPackable>false</IsPackable>\r\n    <GenerateAssemblyInfo>False</GenerateAssemblyInfo>\r\n    <BaseAddress>6488064</BaseAddress>\r\n    <UseWpf>true</UseWpf>\r\n    <EnableWindowsTargeting>true</EnableWindowsTargeting>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Debug'\">\r\n    <DebugType>full</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n    <CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\r\n    <DebugType>pdbonly</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup>\r\n    <OutputPath>..\\ILSpy\\bin\\$(Configuration)\\</OutputPath>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\ICSharpCode.BamlDecompiler\\ICSharpCode.BamlDecompiler.csproj\" />\r\n    <ProjectReference Include=\"..\\ILSpy\\ILSpy.csproj\" />\r\n    <ProjectReference Include=\"..\\ICSharpCode.Decompiler\\ICSharpCode.Decompiler.csproj\" />\r\n  </ItemGroup>\r\n\r\n</Project>"
  },
  {
    "path": "ILSpy.BamlDecompiler/Properties/AssemblyInfo.cs",
    "content": "#region Using directives\n\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\nusing System.Runtime.Versioning;\n\n#endregion\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"ILSpy.BamlDecompiler.Plugin\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"ILSpy.BamlDecompiler.Plugin\")]\n[assembly: AssemblyCopyright(\"Copyright 2011\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// This sets the default COM visibility of types in the assembly to invisible.\n// If you need to expose a type to COM, use [ComVisible(true)] on that type.\n[assembly: ComVisible(false)]\n[assembly: TargetPlatform(\"Windows10.0\")]\n[assembly: SupportedOSPlatform(\"Windows7.0\")]\n\n[assembly: InternalsVisibleTo(\"ILSpy.BamlDecompiler.Tests\")]\n\n// The assembly version has following format :\n//\n// Major.Minor.Build.Revision\n//\n// You can specify all the values or you can use the default the Revision and \n// Build Numbers by using the '*' as shown below:\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "ILSpy.BamlDecompiler/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"ILSpy.BamlDecompiler\": {\n      \"commandName\": \"Executable\",\n      \"executablePath\": \"$(SolutionDir)\\\\ILSpy\\\\bin\\\\Debug\\\\net6.0-windows\\\\ILSpy.exe\",\n      \"commandLineArgs\": \"/separate\"\n    }\n  }\n}"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/BamlTestRunner.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\nusing System.Linq;\nusing System.Xml.Linq;\n\nusing ICSharpCode.BamlDecompiler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Tests.Helpers;\nusing ICSharpCode.Decompiler.Util;\n\nusing NUnit.Framework;\n\nnamespace ILSpy.BamlDecompiler.Tests\n{\n\t[TestFixture, Parallelizable(ParallelScope.All)]\n\tpublic class BamlTestRunner\n\t{\n\t\t[Test]\n\t\tpublic void Simple()\n\t\t{\n\t\t\tRunTest(\"cases/simple\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void SimpleDictionary()\n\t\t{\n\t\t\tRunTest(\"cases/simpledictionary\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Resources()\n\t\t{\n\t\t\tRunTest(\"cases/resources\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void SimpleNames()\n\t\t{\n\t\t\tRunTest(\"cases/simplenames\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void AvalonDockBrushes()\n\t\t{\n\t\t\tRunTest(\"cases/avalondockbrushes\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void AvalonDockCommon()\n\t\t{\n\t\t\tRunTest(\"cases/avalondockcommon\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void AttachedEvent()\n\t\t{\n\t\t\tRunTest(\"cases/attachedevent\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Dictionary1()\n\t\t{\n\t\t\tRunTest(\"cases/dictionary1\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Issue775()\n\t\t{\n\t\t\tRunTest(\"cases/issue775\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MarkupExtension()\n\t\t{\n\t\t\tRunTest(\"cases/markupextension\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void SimplePropertyElement()\n\t\t{\n\t\t\tRunTest(\"cases/simplepropertyelement\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Issue445()\n\t\t{\n\t\t\tRunTest(\"cases/issue445\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void NamespacePrefix()\n\t\t{\n\t\t\tRunTest(\"cases/namespaceprefix\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void EscapeSequence()\n\t\t{\n\t\t\tRunTest(\"cases/escapesequence\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Issue1435()\n\t\t{\n\t\t\tRunTest(\"cases/issue1435\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Issue1546()\n\t\t{\n\t\t\tRunTest(\"cases/issue1546\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Issue1547()\n\t\t{\n\t\t\tRunTest(\"cases/issue1547\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Issue2052()\n\t\t{\n\t\t\tRunTest(\"cases/issue2052\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Issue2097()\n\t\t{\n\t\t\tRunTest(\"cases/issue2097\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Issue2116()\n\t\t{\n\t\t\tRunTest(\"cases/issue2116\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void Issue3318()\n\t\t{\n\t\t\tRunTest(\"cases/issue3318\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ReadonlyProperty()\n\t\t{\n\t\t\tRunTest(\"cases/readonlyproperty\");\n\t\t}\n\n\t\t#region RunTest\n\t\tvoid RunTest(string name)\n\t\t{\n\t\t\tRunTest(name, typeof(BamlTestRunner).Assembly.Location,\n\t\t\t\tPath.Combine(\n\t\t\t\t\tPath.GetDirectoryName(typeof(BamlTestRunner).Assembly.Location),\n\t\t\t\t\t\"../../../..\", name + \".xaml\"));\n\t\t}\n\n\t\tvoid RunTest(string name, string asmPath, string sourcePath)\n\t\t{\n\t\t\tusing (var fileStream = new FileStream(asmPath, FileMode.Open, FileAccess.Read))\n\t\t\t{\n\t\t\t\tvar module = new PEFile(asmPath, fileStream);\n\t\t\t\tvar resolver = new UniversalAssemblyResolver(asmPath, false, module.Metadata.DetectTargetFrameworkId());\n\t\t\t\tresolver.RemoveSearchDirectory(\".\");\n\t\t\t\tresolver.AddSearchDirectory(Path.GetDirectoryName(asmPath));\n\t\t\t\tvar res = module.Resources.First();\n\t\t\t\tStream bamlStream = LoadBaml(res, name + \".baml\");\n\t\t\t\tAssert.That(bamlStream, Is.Not.Null);\n\n\t\t\t\tBamlDecompilerTypeSystem typeSystem = new BamlDecompilerTypeSystem(module, resolver);\n\t\t\t\tvar decompiler = new XamlDecompiler(typeSystem, new BamlDecompilerSettings());\n\n\t\t\t\tXDocument document = decompiler.Decompile(bamlStream).Xaml;\n\n\t\t\t\tXamlIsEqual(File.ReadAllText(sourcePath), document.ToString());\n\t\t\t}\n\t\t}\n\n\t\tvoid XamlIsEqual(string input1, string input2)\n\t\t{\n\t\t\tvar diff = new StringWriter();\n\t\t\tif (!CodeComparer.Compare(input1, input2, diff, NormalizeLine))\n\t\t\t{\n\t\t\t\tAssert.Fail(diff.ToString());\n\t\t\t}\n\t\t}\n\n\t\tstring NormalizeLine(string line)\n\t\t{\n\t\t\treturn line.Trim();\n\t\t}\n\n\t\tStream LoadBaml(Resource res, string name)\n\t\t{\n\t\t\tif (res.ResourceType != ResourceType.Embedded)\n\t\t\t\treturn null;\n\t\t\tStream s = res.TryOpenStream();\n\t\t\tif (s == null)\n\t\t\t\treturn null;\n\t\t\ts.Position = 0;\n\t\t\tResourcesFile resources;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tresources = new ResourcesFile(s);\n\t\t\t}\n\t\t\tcatch (ArgumentException)\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tforeach (var entry in resources.OrderBy(e => e.Key))\n\t\t\t{\n\t\t\t\tif (entry.Key == name)\n\t\t\t\t{\n\t\t\t\t\tif (entry.Value is Stream)\n\t\t\t\t\t\treturn (Stream)entry.Value;\n\t\t\t\t\tif (entry.Value is byte[])\n\t\t\t\t\t\treturn new MemoryStream((byte[])entry.Value);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\t#endregion\n\t}\n}\n"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/AttachedEvent.xaml",
    "content": "<Window x:Class=\"ILSpy.BamlDecompiler.Tests.Cases.AttachedEvent\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:cases=\"clr-namespace:ILSpy.BamlDecompiler.Tests.Cases\" Title=\"ILSpy.BamlDecompiler.Tests.Cases\" Height=\"300\" Width=\"300\">\n\t<Grid AccessKeyManager.AccessKeyPressed=\"GridAccessKeyPressed\" />\n</Window>"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/AttachedEvent.xaml.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Windows;\nusing System.Windows.Input;\n\nnamespace ILSpy.BamlDecompiler.Tests.Cases\n{\n\t/// <summary>\n\t/// Interaction logic for AttachedEvent.xaml\n\t/// </summary>\n\tpublic partial class AttachedEvent : Window\n\t{\n\t\tpublic AttachedEvent()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\n\t\tvoid GridAccessKeyPressed(object sender, AccessKeyPressedEventArgs e)\n\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/AvalonDockBrushes.xaml",
    "content": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:ad=\"clr-namespace:AvalonDock\">\n\t<SolidColorBrush x:Key=\"ManagedContentTabControlNormalBorderBrush\" Color=\"#919B9C\" />\n\t<SolidColorBrush x:Key=\"{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.DefaultBackgroundBrush}, TypeInTargetAssembly={x:Type ad:DockingManager}}\" Color=\"#FFF4F2E8\" />\n\t<LinearGradientBrush x:Key=\"ManagedContentTabItemNormalBackground\" StartPoint=\"0,0\" EndPoint=\"0,1\">\n\t\t<GradientBrush.GradientStops>\n\t\t\t<GradientStop Color=\"#FFECEBE6\" Offset=\"0\" />\n\t\t\t<GradientStop Color=\"#FFFFFFFF\" Offset=\"1\" />\n\t\t</GradientBrush.GradientStops>\n\t</LinearGradientBrush>\n\t<LinearGradientBrush x:Key=\"ManagedContentTabItemInvNormalBackground\" StartPoint=\"0,0\" EndPoint=\"0,1\">\n\t\t<GradientBrush.GradientStops>\n\t\t\t<GradientStop Color=\"#FFFFFFFF\" Offset=\"0\" />\n\t\t\t<GradientStop Color=\"#FFECEBE6\" Offset=\"1\" />\n\t\t</GradientBrush.GradientStops>\n\t</LinearGradientBrush>\n\t<LinearGradientBrush x:Key=\"ManagedContentTabItemHotBackground\" StartPoint=\"0,0\" EndPoint=\"0,1\">\n\t\t<GradientBrush.GradientStops>\n\t\t\t<GradientStop Color=\"#FFFFFFFF\" Offset=\"0\" />\n\t\t\t<GradientStop Color=\"#FFECEBE6\" Offset=\"1\" />\n\t\t</GradientBrush.GradientStops>\n\t</LinearGradientBrush>\n\t<SolidColorBrush x:Key=\"ManagedContentTabItemSelectedBackground\" Color=\"#FFFCFCFE\" />\n\t<SolidColorBrush x:Key=\"ManagedContentTabItemDisabledBackground\" Color=\"#FFF5F4EA\" />\n\t<LinearGradientBrush x:Key=\"ManagedContentTabItemSelectedBorderBackround\" StartPoint=\"0,0\" EndPoint=\"0,1\">\n\t\t<GradientStop Color=\"#FFFFC73C\" Offset=\"0\" />\n\t\t<GradientStop Color=\"#FFE68B2C\" Offset=\"1\" />\n\t</LinearGradientBrush>\n\t<SolidColorBrush x:Key=\"ManagedContentTabItemSelectedBorderBrush\" Color=\"#FFE68B2C\" />\n\t<SolidColorBrush x:Key=\"ManagedContentTabItemHotBorderBackround\" Color=\"#FFFFC73C\" />\n\t<SolidColorBrush x:Key=\"ManagedContentTabItemHotBorderBrush\" Color=\"#FFE68B2C\" />\n\t<SolidColorBrush x:Key=\"ManagedContentTabItemDisabledBorderBrush\" Color=\"#FFC9C7BA\" />\n\t<LinearGradientBrush x:Key=\"{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.DockablePaneTitleBackgroundSelected}, TypeInTargetAssembly={x:Type ad:DockingManager}}\" StartPoint=\"0,0\" EndPoint=\"0,1\">\n\t\t<GradientBrush.GradientStops>\n\t\t\t<GradientStop Color=\"#FF3B80ED\" Offset=\"0\" />\n\t\t\t<GradientStop Color=\"#FF316AC5\" Offset=\"1\" />\n\t\t</GradientBrush.GradientStops>\n\t</LinearGradientBrush>\n\t<SolidColorBrush x:Key=\"{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.DockablePaneTitleBackground}, TypeInTargetAssembly={x:Type ad:DockingManager}}\" Color=\"#FFCCC5BA\" />\n\t<SolidColorBrush x:Key=\"{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.DockablePaneTitleForeground}, TypeInTargetAssembly={x:Type ad:DockingManager}}\" Color=\"Black\" />\n\t<SolidColorBrush x:Key=\"{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.DockablePaneTitleForegroundSelected}, TypeInTargetAssembly={x:Type ad:DockingManager}}\" Color=\"White\" />\n\t<SolidColorBrush x:Key=\"{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.PaneHeaderCommandBackground}, TypeInTargetAssembly={x:Type ad:DockingManager}}\" Color=\"{x:Static SystemColors.ControlLightLightColor}\" Opacity=\"0.5\" />\n\t<SolidColorBrush x:Key=\"{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.PaneHeaderCommandBorderBrush}, TypeInTargetAssembly={x:Type ad:DockingManager}}\" Color=\"{x:Static SystemColors.ControlDarkColor}\" />\n\t<LinearGradientBrush x:Key=\"{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.DocumentHeaderBackground}, TypeInTargetAssembly={x:Type ad:DockingManager}}\" StartPoint=\"0,0\" EndPoint=\"0,1\">\n\t\t<GradientStop Color=\"#FFFFFFFF\" Offset=\"0\" />\n\t\t<GradientStop Color=\"#FFE0E0E0\" Offset=\"1\" />\n\t</LinearGradientBrush>\n\t<SolidColorBrush x:Key=\"{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.DocumentHeaderForeground}, TypeInTargetAssembly={x:Type ad:DockingManager}}\" Color=\"{x:Static SystemColors.WindowTextColor}\" />\n\t<LinearGradientBrush x:Key=\"{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.DocumentHeaderBackgroundSelected}, TypeInTargetAssembly={x:Type ad:DockingManager}}\" StartPoint=\"0,0\" EndPoint=\"0,1\">\n\t\t<GradientStop Color=\"#FFFFFFFF\" Offset=\"0\" />\n\t\t<GradientStop Color=\"#FFC1D2EE\" Offset=\"1\" />\n\t</LinearGradientBrush>\n\t<SolidColorBrush x:Key=\"{ComponentResourceKey ResourceId={x:Static ad:AvalonDockBrushes.DocumentHeaderBackgroundMouseOver}, TypeInTargetAssembly={x:Type ad:DockingManager}}\" Color=\"White\" />\n</ResourceDictionary>"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/AvalonDockCommon.xaml",
    "content": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:ad=\"clr-namespace:AvalonDock\">\n\t<ResourceDictionary.MergedDictionaries>\n\t\t<ResourceDictionary Source=\"/AvalonDock;component/Resources/Brushes.xaml\" />\n\t</ResourceDictionary.MergedDictionaries>\n\t<ContextMenu x:Key=\"{ComponentResourceKey ResourceId={x:Static ad:ContextMenuElement.DockableFloatingWindow}, TypeInTargetAssembly={x:Type ad:DockingManager}}\">\n\t\t<MenuItem Command=\"ad:ManagedContentCommands.Show\" />\n\t\t<MenuItem Command=\"ad:ManagedContentCommands.Hide\" />\n\t\t<MenuItem Command=\"ad:DockableContentCommands.ShowAsDocument\" />\n\t\t<Separator />\n\t\t<MenuItem Command=\"ad:DockableFloatingWindowCommands.SetAsFloatingWindow\" />\n\t\t<MenuItem Command=\"ad:DockableFloatingWindowCommands.SetAsDockableWindow\" />\n\t</ContextMenu>\n\t<ContextMenu x:Key=\"{ComponentResourceKey ResourceId={x:Static ad:ContextMenuElement.DocumentFloatingWindow}, TypeInTargetAssembly={x:Type ad:DockingManager}}\">\n\t\t<MenuItem Command=\"ad:ManagedContentCommands.Close\" />\n\t\t<Separator />\n\t\t<MenuItem Command=\"ad:DocumentContentCommands.FloatingDocument\" />\n\t\t<MenuItem Command=\"ad:DocumentContentCommands.TabbedDocument\" />\n\t</ContextMenu>\n\t<Style x:Key=\"{x:Type ad:Resizer}\" TargetType=\"{x:Type ad:Resizer}\">\n\t\t<Setter Property=\"Background\" Value=\"#00FFFFFF\" />\n\t\t<Setter Property=\"Template\">\n\t\t\t<Setter.Value>\n\t\t\t\t<ControlTemplate TargetType=\"{x:Type ad:Resizer}\">\n\t\t\t\t\t<Border Background=\"{TemplateBinding Control.Background}\" />\n\t\t\t\t</ControlTemplate>\n\t\t\t</Setter.Value>\n\t\t</Setter>\n\t</Style>\n\t<Style x:Key=\"PaneHeaderCommandStyle\" TargetType=\"{x:Type Button}\">\n\t\t<Setter Property=\"Template\">\n\t\t\t<Setter.Value>\n\t\t\t\t<ControlTemplate TargetType=\"{x:Type Button}\">\n\t\t\t\t\t<Border Name=\"PaneHeaderCommandIntBorder\" Background=\"#00FFFFFF\" BorderThickness=\"1\" Margin=\"0\" Opacity=\"0.8\">\n\t\t\t\t\t\t<ContentPresenter />\n\t\t\t\t\t</Border>\n\t\t\t\t\t<ControlTemplate.Triggers>\n\t\t\t\t\t\t<Trigger Property=\"UIElement.IsMouseOver\" Value=\"True\">\n\t\t\t\t\t\t\t<Setter TargetName=\"PaneHeaderCommandIntBorder\" Property=\"Border.BorderBrush\" Value=\"{DynamicResource {ComponentResourceKey {x:Type ad:DockingManager}, {x:Static ad:AvalonDockBrushes.PaneHeaderCommandBorderBrush}}}\" />\n\t\t\t\t\t\t\t<Setter TargetName=\"PaneHeaderCommandIntBorder\" Property=\"Border.Background\" Value=\"{DynamicResource {ComponentResourceKey {x:Type ad:DockingManager}, {x:Static ad:AvalonDockBrushes.PaneHeaderCommandBackground}}}\" />\n\t\t\t\t\t\t\t<Setter TargetName=\"PaneHeaderCommandIntBorder\" Property=\"UIElement.Opacity\" Value=\"1\" />\n\t\t\t\t\t\t</Trigger>\n\t\t\t\t\t</ControlTemplate.Triggers>\n\t\t\t\t</ControlTemplate>\n\t\t\t</Setter.Value>\n\t\t</Setter>\n\t</Style>\n\t<Style x:Key=\"PaneHeaderContextMenuCommandStyle\" TargetType=\"{x:Type Border}\">\n\t\t<Setter Property=\"Background\" Value=\"#00FFFFFF\" />\n\t\t<Setter Property=\"BorderThickness\" Value=\"1\" />\n\t\t<Style.Triggers>\n\t\t\t<Trigger Property=\"UIElement.IsMouseOver\" Value=\"True\">\n\t\t\t\t<Setter Property=\"BorderBrush\" Value=\"{DynamicResource {ComponentResourceKey {x:Type ad:DockingManager}, {x:Static ad:AvalonDockBrushes.PaneHeaderCommandBorderBrush}}}\" />\n\t\t\t\t<Setter Property=\"Background\" Value=\"{DynamicResource {ComponentResourceKey {x:Type ad:DockingManager}, {x:Static ad:AvalonDockBrushes.PaneHeaderCommandBackground}}}\" />\n\t\t\t\t<Setter Property=\"UIElement.Opacity\" Value=\"1\" />\n\t\t\t</Trigger>\n\t\t</Style.Triggers>\n\t</Style>\n</ResourceDictionary>"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/CustomControl.cs",
    "content": "// Copyright (c) 2020 AlphaSierraPapa for the SharpDevelop Team\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Windows;\nusing System.Windows.Controls;\n\nnamespace ILSpy.BamlDecompiler.Tests.Cases\n{\n\tpublic class CustomControl : ContentControl\n\t{\n\t\tpublic static string SimpleProperty = \"Hi!\";\n\n\t\tpublic static readonly DependencyProperty CustomNameProperty = DependencyProperty.RegisterAttached(\"CustomName\", typeof(string), typeof(CustomControl));\n\n\t\tpublic static string GetCustomName(DependencyObject target)\n\t\t{\n\t\t\treturn (string)target.GetValue(CustomNameProperty);\n\t\t}\n\n\t\tpublic static void SetCustomName(DependencyObject target, string value)\n\t\t{\n\t\t\ttarget.SetValue(CustomNameProperty, value);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/Dictionary1.xaml",
    "content": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n\t<Color x:Key=\"VeryDark\" A=\"255\" R=\"70\" G=\"70\" B=\"70\" />\n\t<Color x:Key=\"Dark\" A=\"255\" R=\"102\" G=\"102\" B=\"102\" />\n\t<Color x:Key=\"Medium\" A=\"255\" R=\"140\" G=\"140\" B=\"140\" />\n\t<Color x:Key=\"Light\" A=\"255\" R=\"204\" G=\"204\" B=\"204\" />\n\t<Color x:Key=\"VeryLight\" A=\"255\" R=\"241\" G=\"241\" B=\"241\" />\n\t<Color x:Key=\"OffWhite\" A=\"255\" R=\"255\" G=\"255\" B=\"255\" />\n\t<Color x:Key=\"Highlight\" A=\"255\" R=\"220\" G=\"107\" B=\"47\" />\n\t<SolidColorBrush x:Key=\"VeryDarkBrush\" Color=\"{StaticResource VeryDark}\" />\n\t<SolidColorBrush x:Key=\"DarkBrush\" Color=\"{StaticResource Dark}\" />\n\t<SolidColorBrush x:Key=\"MediumBrush\" Color=\"{StaticResource Medium}\" />\n\t<SolidColorBrush x:Key=\"LightBrush\" Color=\"{StaticResource Light}\" />\n\t<SolidColorBrush x:Key=\"VeryLightBrush\" Color=\"{StaticResource VeryLight}\" />\n\t<SolidColorBrush x:Key=\"OffWhiteBrush\" Color=\"{StaticResource OffWhite}\" />\n\t<SolidColorBrush x:Key=\"HighlightBrush\" Color=\"{StaticResource Highlight}\" />\n\t<LinearGradientBrush x:Key=\"EdgeBorder\" StartPoint=\"0,0\" EndPoint=\"0,1\">\n\t\t<GradientStop Color=\"#0000\" Offset=\"0\" />\n\t\t<GradientStop Color=\"#1000\" Offset=\"0.65\" />\n\t\t<GradientStop Color=\"#3000\" Offset=\"1\" />\n\t</LinearGradientBrush>\n\t<SolidColorBrush x:Key=\"DisabledForegroundBrush\" Color=\"#6FFF\" />\n\t<SolidColorBrush x:Key=\"SelectedBackgroundBrush\" Color=\"{StaticResource Light}\" />\n</ResourceDictionary>"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/EscapeSequence.xaml",
    "content": "<UserControl xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:system=\"clr-namespace:System;assembly=System.Private.CoreLib\">\n\t<StackPanel>\n\t\t<FrameworkElement.Resources>\n\t\t\t<ResourceDictionary>\n\t\t\t\t<DataTemplate x:Key=\"key\" DataType=\"{}{http://planetsNS}Planet\">\n\t\t\t\t\t<StackPanel Orientation=\"Horizontal\">\n\t\t\t\t\t\t<TextBlock Width=\"100\" Text=\"{Binding Path=Element[{http://planetsNS}DiameterKM].Value}\" />\n\t\t\t\t\t\t<TextBlock Width=\"100\" Text=\"{Binding Path=Attribute[Name].Value}\" />\n\t\t\t\t\t\t<TextBlock Text=\"{Binding Path=Element[{http://planetsNS}Details].Value}\" />\n\t\t\t\t\t\t<TextBlock Text=\"{Binding Source={x:Static system:DateTime.Now}, StringFormat=Date: {0:dddd, MMMM dd}}\" />\n\t\t\t\t\t\t<TextBlock Text=\"{Binding Source={x:Static system:DateTime.Now}, StringFormat=Time: {0:HH:mm}}\" />\n\t\t\t\t\t</StackPanel>\n\t\t\t\t</DataTemplate>\n\t\t\t</ResourceDictionary>\n\t\t</FrameworkElement.Resources>\n\t\t<TextBlock Text=\"{Binding Path=ActualWidth, StringFormat=Window width: {0:#,#.0}}\" />\n\t\t<TextBlock Text=\"{Binding Path=ActualHeight, StringFormat=Window height: {0:C}}\" />\n\t\t<WrapPanel Margin=\"10\">\n\t\t\t<TextBlock Text=\"Width: \" />\n\t\t\t<TextBlock Text=\"{Binding ActualWidth, StringFormat={}{0:#,#.0}}\" />\n\t\t\t<StackPanel Margin=\"10\">\n\t\t\t\t<TextBlock Text=\"{Binding Source={x:Static system:DateTime.Now}, ConverterCulture=de-DE, StringFormat=German date: {0:D}}\" />\n\t\t\t\t<TextBlock Text=\"{Binding Source={x:Static system:DateTime.Now}, ConverterCulture=en-US, StringFormat=American date: {0:D}}\" />\n\t\t\t\t<TextBlock Text=\"{Binding Source={x:Static system:DateTime.Now}, ConverterCulture=ja-JP, StringFormat=Japanese date: {0:D}}\" />\n\t\t\t</StackPanel>\n\t\t</WrapPanel>\n\t</StackPanel>\n</UserControl>"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/Issue1435.xaml",
    "content": "<UserControl x:Class=\"ILSpy.BamlDecompiler.Tests.Cases.Issue1435\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" xmlns:local=\"clr-namespace:ILSpy.BamlDecompiler.Tests.Cases\" x:Name=\"SomeControlName\" AutomationProperties.Name=\"SomeAutomationName\">\n\t<Grid Name=\"SomeControlName2\" AutomationProperties.Name=\"SomeAutomationName2\" />\n</UserControl>\n"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/Issue1546.xaml",
    "content": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:PresentationOptions=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation/options\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:System=\"clr-namespace:System;assembly=mscorlib\">\n\t<SolidColorBrush x:Key=\"brushText\">#f1f1f1</SolidColorBrush>\n\t<SolidColorBrush x:Key=\"brushNormal\">#2d2d30</SolidColorBrush>\n\t<SolidColorBrush x:Key=\"brushFocused\">#3f3f41</SolidColorBrush>\n\t<SolidColorBrush x:Key=\"brushHighlight\">#007acc</SolidColorBrush>\n\t<SolidColorBrush x:Key=\"brushControlBackground\">#333337</SolidColorBrush>\n\t<SolidColorBrush x:Key=\"brushControlInactiveBorder\">#3f3f3f</SolidColorBrush>\n\t<SolidColorBrush x:Key=\"brushControlInactiveText\">#999999</SolidColorBrush>\n\t<SolidColorBrush x:Key=\"brushControlActive\">#686868</SolidColorBrush>\n\t<SolidColorBrush x:Key=\"brushControlActiveBorder\">#9e9e9e</SolidColorBrush>\n\t<Color x:Key=\"colorText\">#f1f1f1</Color>\n\t<Color x:Key=\"colorNormal\">#2d2d30</Color>\n\t<Color x:Key=\"colorFocused\">#3f3f41</Color>\n\t<Color x:Key=\"colorRED\">#b20000</Color>\n\t<Color x:Key=\"colorRED2\">#990000</Color>\n\t<Color x:Key=\"colorGREEN\">#009700</Color>\n\t<Color x:Key=\"colorGREEN2\">#007400</Color>\n\t<Color x:Key=\"colorHover\">#1c97ea</Color>\n\t<Color x:Key=\"colorHighlight\">#007acc</Color>\n\t<Color x:Key=\"colorControlBackground\">#333337</Color>\n\t<Color x:Key=\"colorControlInactiveBorder\">#3f3f3f</Color>\n\t<Color x:Key=\"colorControlInactiveText\">#999999</Color>\n\t<Color x:Key=\"colorControlActive\">#686868</Color>\n\t<Color x:Key=\"colorControlActiveBorder\">#9e9e9e</Color>\n\t<SolidColorBrush x:Key=\"ComboBoxNormalBorderBrush\" Color=\"#e3e9ef\" />\n\t<SolidColorBrush x:Key=\"ComboBoxNormalBackgroundBrush\" Color=\"#fff\" />\n\t<SolidColorBrush x:Key=\"ComboBoxDisabledForegroundBrush\" Color=\"#888\" />\n\t<SolidColorBrush x:Key=\"ComboBoxDisabledBackgroundBrush\" Color=\"#eee\" />\n\t<SolidColorBrush x:Key=\"ComboBoxDisabledBorderBrush\" Color=\"#888\" />\n\t<Color x:Key=\"GrayLightExColorKey\">#FFD1D1D1</Color>\n\t<SolidColorBrush x:Key=\"GrayLightExColorSolidKey\" PresentationOptions:Freeze=\"true\" Color=\"{StaticResource GrayLightExColorKey}\" />\n\t<Color x:Key=\"GrayLightColorKey\">#FFA3A3A3</Color>\n\t<SolidColorBrush x:Key=\"GrayLightColorSolidKey\" PresentationOptions:Freeze=\"true\" Color=\"{StaticResource GrayLightColorKey}\" />\n\t<Color x:Key=\"GrayColorKey\">#FF747474</Color>\n</ResourceDictionary>"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/Issue1547.xaml",
    "content": "<Window x:Class=\"ILSpy.BamlDecompiler.Tests.Cases.Issue1547\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:local=\"clr-namespace:ILSpy.BamlDecompiler.Tests.Cases\" Title=\"Issue1547\" Height=\"450\" Width=\"800\">\n\t<Grid>\n\t\t<Grid.RowDefinitions>\n\t\t\t<RowDefinition />\n\t\t\t<RowDefinition />\n\t\t</Grid.RowDefinitions>\n\t\t<Button>\n\t\t\t<FrameworkElement.Style>\n\t\t\t\t<Style TargetType=\"{x:Type Button}\">\n\t\t\t\t\t<Setter Property=\"Grid.Row\" Value=\"1\" />\n\t\t\t\t\t<Setter Property=\"Content\" Value=\"World!\" />\n\t\t\t\t</Style>\n\t\t\t</FrameworkElement.Style>\n\t\t</Button>\n\t\t<Button>\n\t\t\t<FrameworkElement.Style>\n\t\t\t\t<Style TargetType=\"{x:Type Button}\">\n\t\t\t\t\t<Setter Property=\"Grid.Row\" Value=\"0\" />\n\t\t\t\t\t<Setter Property=\"Content\" Value=\"Hello\" />\n\t\t\t\t</Style>\n\t\t\t</FrameworkElement.Style>\n\t\t</Button>\n\t</Grid>\n</Window>\n"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/Issue1547.xaml.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Documents;\nusing System.Windows.Input;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\nusing System.Windows.Shapes;\n\nnamespace ILSpy.BamlDecompiler.Tests.Cases\n{\n\t/// <summary>\n\t/// Interaction logic for Issue1547.xaml\n\t/// </summary>\n\tpublic partial class Issue1547 : Window\n\t{\n\t\tpublic Issue1547()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/Issue2052.xaml",
    "content": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n\t<Grid x:Key=\"grid\" x:XmlAttributeProperties.XmlSpace=\"preserve\" />\n</ResourceDictionary>"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/Issue2097.xaml",
    "content": "<Window x:Class=\"ILSpy.BamlDecompiler.Tests.Cases.Issue2097\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:local=\"clr-namespace:ILSpy.BamlDecompiler.Tests.Cases\" Title=\"{x:Static local:Issue2097Temp.Test}\" Height=\"450\" Width=\"800\">\n\t<Grid>\n\t\t<TextBlock Text=\"{x:Static local:Issue2097Temp.Test}\" />\n\t</Grid>\n</Window>\n"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/Issue2097.xaml.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Documents;\nusing System.Windows.Input;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\nusing System.Windows.Shapes;\n\nnamespace ILSpy.BamlDecompiler.Tests.Cases\n{\n\t/// <summary>\n\t/// Interaction logic for Issue2097.xaml\n\t/// </summary>\n\tpublic partial class Issue2097 : Window\n\t{\n\t\tpublic Issue2097()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\t}\n\n\tclass Issue2097Temp\n\t{\n\t\tpublic static string Test = \"Hello\";\n\t}\n}\n"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/Issue2116.xaml",
    "content": "<UserControl x:Class=\"ILSpy.BamlDecompiler.Tests.Cases.Issue2116\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" xmlns:local=\"clr-namespace:ILSpy.BamlDecompiler.Tests.Cases\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\">\n\t<FrameworkElement.Resources>\n\t\t<ResourceDictionary>\n\t\t\t<Style x:Key=\"TestStyle1\" />\n\t\t\t<Style x:Key=\"TestStyle2\" BasedOn=\"{StaticResource TestStyle1}\" />\n\t\t\t<Style x:Key=\"TestStyle2\" BasedOn=\"{StaticResource {x:Type local:Issue2116}}\" />\n\t\t\t<Style x:Key=\"TestStyle2\" BasedOn=\"{StaticResource {x:Static local:Issue2116.StyleKey1}}\" />\n\t\t</ResourceDictionary>\n\t</FrameworkElement.Resources>\n\t<Grid>\n\t\t<Grid Style=\"{StaticResource TestStyle1}\" />\n\t\t<Grid Style=\"{StaticResource {x:Type local:Issue2116}}\" />\n\t\t<Grid Style=\"{StaticResource {x:Static local:Issue2116.StyleKey1}}\" />\n\t</Grid>\n</UserControl>\n"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/Issue2116.xaml.cs",
    "content": "namespace ILSpy.BamlDecompiler.Tests.Cases\n{\n\tusing System.Windows;\n\tusing System.Windows.Controls;\n\n\tpublic partial class Issue2116 : UserControl\n\t{\n\t\tpublic static ComponentResourceKey StyleKey1 => new ComponentResourceKey(typeof(Issue2116), \"TestStyle1\");\n\t\tpublic static ComponentResourceKey StyleKey2 => new ComponentResourceKey(typeof(Issue2116), \"TestStyle2\");\n\n\t\tpublic Issue2116()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/Issue3318.xaml",
    "content": "<UserControl x:Class=\"ILSpy.BamlDecompiler.Tests.Cases.Issue3318\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:cases=\"clr-namespace:ILSpy.BamlDecompiler.Tests.Cases;assembly=ILSpy.BamlDecompiler.Tests\">\n\t<Grid Name=\"Root\" x:FieldModifier=\"public\" />\n</UserControl>\n"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/Issue3318.xaml.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Documents;\nusing System.Windows.Input;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\nusing System.Windows.Navigation;\nusing System.Windows.Shapes;\n\nnamespace ILSpy.BamlDecompiler.Tests.Cases\n{\n\t/// <summary>\n\t/// Interaction logic for Issue3318.xaml\n\t/// </summary>\n\tpublic partial class Issue3318 : UserControl\n\t{\n\t\tpublic Issue3318()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/Issue445.xaml",
    "content": "<UserControl x:Class=\"BamlTest.UserControl1\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:bamltest=\"clr-namespace:BamlTest\">\n\t<FrameworkElement.Resources>\n\t\t<ResourceDictionary>\n\t\t\t<Style x:Key=\"baseStyle\" TargetType=\"{x:Type Control}\" />\n\t\t</ResourceDictionary>\n\t</FrameworkElement.Resources>\n\t<Grid>\n\t\t<FrameworkElement.ContextMenu>\n\t\t\t<ContextMenu>\n\t\t\t\t<FrameworkElement.Resources>\n\t\t\t\t\t<ResourceDictionary>\n\t\t\t\t\t\t<Style x:Key=\"{x:Type Control}\" BasedOn=\"{StaticResource baseStyle}\" TargetType=\"{x:Type Control}\" />\n\t\t\t\t\t</ResourceDictionary>\n\t\t\t\t</FrameworkElement.Resources>\n\t\t\t</ContextMenu>\n\t\t</FrameworkElement.ContextMenu>\n\t</Grid>\n</UserControl>"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/Issue775.xaml",
    "content": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:MyNamespace=\"clr-namespace:ILSpy.BamlDecompiler.Tests.Cases\">\n\t<Style x:Key=\"style1\">\n\t\t<Setter Property=\"MyNamespace:CustomControl.CustomName\" Value=\"Test\" />\n\t</Style>\n</ResourceDictionary>"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/MarkupExtension.xaml",
    "content": "<Label xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" DataContext=\"{Binding Blub}\" Content=\"{Binding Path=Blah, StringFormat={}{0} items}\">\n\t<FrameworkElement.Style>\n\t\t<Style />\n\t</FrameworkElement.Style>\n</Label>"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/MyControl.xaml",
    "content": "<UserControl x:Class=\"ILSpy.BamlDecompiler.Tests.Cases.MyControl\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:cases=\"clr-namespace:ILSpy.BamlDecompiler.Tests.Cases\">\n\t<Grid />\n</UserControl>"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/MyControl.xaml.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Collections;\nusing System.Windows.Controls;\n\nnamespace ILSpy.BamlDecompiler.Tests.Cases\n{\n\t/// <summary>\n\t/// Interaction logic for MyControl.xaml\n\t/// </summary>\n\tpublic partial class MyControl : UserControl\n\t{\n\t\tpublic IList DataTypes { get; } = new ArrayList();\n\n\t\tpublic MyControl()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/NamespacePrefix.xaml",
    "content": "<Grid xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:cc=\"clr-namespace:ILSpy.BamlDecompiler.Tests.Cases\" xmlns:unk=\"clr-namespace:A;assembly=Unknown\">\n\t<cc:CustomControl Grid.Row=\"0\" Tag=\"{}{}{Test}\" CustomName=\"Custom1\">\n\t\t<FrameworkElement.Style>\n\t\t\t<Style />\n\t\t</FrameworkElement.Style>\n\t</cc:CustomControl>\n\t<Label ToolTip=\"{DynamicResource cc:CustomControl.SimpleProperty}\" Grid.Row=\"0\" cc:CustomControl.CustomName=\"Label1\">\n\t\t<FrameworkElement.Style>\n\t\t\t<Style />\n\t\t</FrameworkElement.Style>\n\t</Label>\n</Grid>"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/ReadonlyProperty.xaml",
    "content": "<Window x:Class=\"ILSpy.BamlDecompiler.Tests.Cases.ReadonlyProperty\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:local=\"clr-namespace:ILSpy.BamlDecompiler.Tests.Cases\" Title=\"ReadonlyProperty\" Height=\"450\" Width=\"800\">\n\t<Grid>\n\t\t<local:MyControl>\n\t\t\t<local:MyControl.DataTypes>\n\t\t\t\t<x:TypeExtension TypeName=\"Brush\" />\n\t\t\t</local:MyControl.DataTypes>\n\t\t</local:MyControl>\n    </Grid>\n</Window>\n"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/ReadonlyProperty.xaml.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Documents;\nusing System.Windows.Input;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\nusing System.Windows.Shapes;\n\nnamespace ILSpy.BamlDecompiler.Tests.Cases\n{\n\t/// <summary>\n\t/// Interaction logic for ReadonlyProperty.xaml\n\t/// </summary>\n\tpublic partial class ReadonlyProperty : Window\n\t{\n\t\tpublic ReadonlyProperty()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/Resources.xaml",
    "content": "<Window x:Class=\"ILSpy.BamlDecompiler.Tests.Cases.Resources\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:cases=\"clr-namespace:ILSpy.BamlDecompiler.Tests.Cases\" Title=\"ILSpy.BamlDecompiler.Tests.Cases\" Height=\"300\" Width=\"300\">\n\t<Grid>\n\t\t<Canvas>\n\t\t\t<FrameworkElement.Resources>\n\t\t\t\t<ResourceDictionary>\n\t\t\t\t\t<BooleanToVisibilityConverter x:Key=\"b\" />\n\t\t\t\t</ResourceDictionary>\n\t\t\t</FrameworkElement.Resources>\n\t\t</Canvas>\n\t\t<Canvas>\n\t\t\t<FrameworkElement.Resources>\n\t\t\t\t<ResourceDictionary>\n\t\t\t\t\t<BooleanToVisibilityConverter x:Key=\"b\" />\n\t\t\t\t</ResourceDictionary>\n\t\t\t</FrameworkElement.Resources>\n\t\t</Canvas>\n\t</Grid>\n</Window>"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/Resources.xaml.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Windows;\n\nnamespace ILSpy.BamlDecompiler.Tests.Cases\n{\n\t/// <summary>\n\t/// Interaction logic for Resources.xaml\n\t/// </summary>\n\tpublic partial class Resources : Window\n\t{\n\t\tpublic Resources()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/Simple.xaml",
    "content": "<Window x:Class=\"ILSpy.BamlDecompiler.Tests.Cases.Simple\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:cases=\"clr-namespace:ILSpy.BamlDecompiler.Tests.Cases\" Title=\"ILSpy.BamlDecompiler.Tests.Cases\" Height=\"300\" Width=\"300\">\n\t<Grid />\n</Window>"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/Simple.xaml.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Windows;\n\nnamespace ILSpy.BamlDecompiler.Tests.Cases\n{\n\t/// <summary>\n\t/// Interaction logic for Simple.xaml\n\t/// </summary>\n\tpublic partial class Simple : Window\n\t{\n\t\tpublic Simple()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/SimpleDictionary.xaml",
    "content": "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" />"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/SimpleNames.xaml",
    "content": "<Window x:Class=\"ILSpy.BamlDecompiler.Tests.Cases.SimpleNames\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:mc=\"clr-namespace:ILSpy.BamlDecompiler.Tests.Cases\" Title=\"ILSpy.BamlDecompiler.Tests.Cases\" Height=\"300\" Width=\"300\">\n\t<Grid>\n\t\t<Button Name=\"test\" />\n\t\t<mc:MyControl x:Name=\"test2\" />\n\t</Grid>\n</Window>"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/SimpleNames.xaml.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Windows;\n\nnamespace ILSpy.BamlDecompiler.Tests.Cases\n{\n\t/// <summary>\n\t/// Interaction logic for SimpleNames.xaml\n\t/// </summary>\n\tpublic partial class SimpleNames : Window\n\t{\n\t\tpublic SimpleNames()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Cases/SimplePropertyElement.xaml",
    "content": "<Label xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" Content=\"Blah\">\n\t<FrameworkElement.Style>\n\t\t<Style />\n\t</FrameworkElement.Style>\n</Label>"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <IsWindowsX64 Condition=\"$([MSBuild]::IsOsPlatform('Windows')) And $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) == X64\">true</IsWindowsX64>\r\n    <IsWindowsARM64 Condition=\"$([MSBuild]::IsOsPlatform('Windows')) And $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) == ARM64\">true</IsWindowsARM64>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup>\r\n    <TargetFramework>net10.0-windows</TargetFramework>\r\n    <RuntimeIdentifier Condition=\"$(IsWindowsX64) == true\">win-x64</RuntimeIdentifier>\r\n    <RuntimeIdentifier Condition=\"$(IsWindowsARM64) == true\">win-arm64</RuntimeIdentifier>\r\n\r\n    <IsPackable>false</IsPackable>\r\n    <OutputType>Exe</OutputType>\r\n\r\n    <EnableDefaultItems>false</EnableDefaultItems>\r\n    <UseWpf>true</UseWpf>\r\n\r\n    <ExtrasEnableDefaultPageItems>false</ExtrasEnableDefaultPageItems>\r\n    <ExtrasEnableDefaultResourceItems>false</ExtrasEnableDefaultResourceItems>\r\n\r\n    <AutoGenerateBindingRedirects>True</AutoGenerateBindingRedirects>\r\n    <EnableWindowsTargeting>true</EnableWindowsTargeting>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Debug'\">\r\n    <DebugType>full</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n    <CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\r\n    <DebugType>pdbonly</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"NUnit\" />\r\n    <PackageReference Include=\"NUnit3TestAdapter\" />\r\n    <PackageReference Include=\"AwesomeAssertions\" />\r\n    <PackageReference Include=\"Microsoft.Testing.Extensions.TrxReport\" />\r\n    <PackageReference Include=\"Microsoft.Testing.Extensions.VSTestBridge\" />\r\n    <PackageReference Include=\"coverlet.MTP\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\ICSharpCode.Decompiler.Tests\\ICSharpCode.Decompiler.Tests.csproj\" />\r\n    <ProjectReference Include=\"..\\ILSpy.BamlDecompiler\\ILSpy.BamlDecompiler.csproj\" />\r\n    <ProjectReference Include=\"..\\ILSpy\\ILSpy.csproj\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <Compile Include=\"BamlTestRunner.cs\" />\r\n    <Compile Include=\"Cases\\AttachedEvent.xaml.cs\">\r\n      <DependentUpon>AttachedEvent.xaml</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"Cases\\CustomControl.cs\" />\r\n    <Compile Include=\"Cases\\Issue1547.xaml.cs\" />\r\n    <Compile Include=\"Cases\\Issue2097.xaml.cs\" />\r\n    <Compile Include=\"Cases\\Issue2116.xaml.cs\" />\r\n    <Compile Include=\"Cases\\Issue3318.xaml.cs\" />\r\n    <Compile Include=\"Cases\\MyControl.xaml.cs\">\r\n      <DependentUpon>MyControl.xaml</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"Cases\\ReadonlyProperty.xaml.cs\" />\r\n    <Compile Include=\"Cases\\Resources.xaml.cs\">\r\n      <DependentUpon>Resources.xaml</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"Cases\\Simple.xaml.cs\">\r\n      <DependentUpon>Simple.xaml</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"Cases\\SimpleNames.xaml.cs\">\r\n      <DependentUpon>SimpleNames.xaml</DependentUpon>\r\n    </Compile>\r\n    <Compile Include=\"Mocks\\AvalonDock.cs\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <Page Include=\"Cases\\AttachedEvent.xaml\" />\r\n    <Page Include=\"Cases\\AvalonDockBrushes.xaml\" />\r\n    <Page Include=\"Cases\\AvalonDockCommon.xaml\" />\r\n    <Page Include=\"Cases\\EscapeSequence.xaml\">\r\n      <SubType>Designer</SubType>\r\n      <Generator>MSBuild:Compile</Generator>\r\n    </Page>\r\n    <Page Include=\"Cases\\Issue1435.xaml\">\r\n      <Generator>MSBuild:Compile</Generator>\r\n    </Page>\r\n    <Page Include=\"Cases\\Issue1546.xaml\">\r\n      <Generator>MSBuild:Compile</Generator>\r\n    </Page>\r\n    <Page Include=\"Cases\\Issue1547.xaml\">\r\n      <Generator>MSBuild:Compile</Generator>\r\n    </Page>\r\n    <Page Include=\"Cases\\Issue2052.xaml\">\r\n      <Generator>MSBuild:Compile</Generator>\r\n    </Page>\r\n    <Page Include=\"Cases\\Issue2097.xaml\">\r\n      <Generator>MSBuild:Compile</Generator>\r\n    </Page>\r\n    <Page Include=\"Cases\\Issue2116.xaml\">\r\n      <Generator>MSBuild:Compile</Generator>\r\n    </Page>\r\n    <Page Include=\"Cases\\Issue3318.xaml\">\r\n      <Generator>MSBuild:Compile</Generator>\r\n    </Page>\r\n    <Page Include=\"Cases\\Issue775.xaml\">\r\n      <SubType>Designer</SubType>\r\n    </Page>\r\n    <Page Include=\"Cases\\MarkupExtension.xaml\" />\r\n    <Page Include=\"Cases\\MyControl.xaml\" />\r\n    <Page Include=\"Cases\\NamespacePrefix.xaml\" />\r\n    <Page Include=\"Cases\\ReadonlyProperty.xaml\">\r\n      <Generator>MSBuild:Compile</Generator>\r\n    </Page>\r\n    <Page Include=\"Cases\\Resources.xaml\" />\r\n    <Page Include=\"Cases\\Simple.xaml\">\r\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\r\n    </Page>\r\n    <Page Include=\"Cases\\SimpleDictionary.xaml\" />\r\n    <Page Include=\"Cases\\SimpleNames.xaml\" />\r\n    <Page Include=\"Cases\\SimplePropertyElement.xaml\" />\r\n    <Page Include=\"Cases\\Dictionary1.xaml\" />\r\n    <Page Include=\"Cases\\Issue445.xaml\" />\r\n  </ItemGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "ILSpy.BamlDecompiler.Tests/Mocks/AvalonDock.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Windows;\nusing System.Windows.Controls.Primitives;\n\nnamespace AvalonDock\n{\n\tpublic class DockingManager\n\t{\n\t\tpublic DockingManager()\n\t\t{\n\t\t}\n\t}\n\n\tpublic class Resizer : Thumb\n\t{\n\t\tstatic Resizer()\n\t\t{\n\t\t\t//This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class.\n\t\t\t//This style is defined in themes\\generic.xaml\n\t\t\tDefaultStyleKeyProperty.OverrideMetadata(typeof(Resizer), new FrameworkPropertyMetadata(typeof(Resizer)));\n\t\t\tMinWidthProperty.OverrideMetadata(typeof(Resizer), new FrameworkPropertyMetadata(6.0, FrameworkPropertyMetadataOptions.AffectsParentMeasure));\n\t\t\tMinHeightProperty.OverrideMetadata(typeof(Resizer), new FrameworkPropertyMetadata(6.0, FrameworkPropertyMetadataOptions.AffectsParentMeasure));\n\t\t\tHorizontalAlignmentProperty.OverrideMetadata(typeof(Resizer), new FrameworkPropertyMetadata(HorizontalAlignment.Stretch, FrameworkPropertyMetadataOptions.AffectsParentMeasure));\n\t\t\tVerticalAlignmentProperty.OverrideMetadata(typeof(Resizer), new FrameworkPropertyMetadata(VerticalAlignment.Stretch, FrameworkPropertyMetadataOptions.AffectsParentMeasure));\n\t\t}\n\n\t}\n\n\tpublic enum AvalonDockBrushes\n\t{\n\t\tDefaultBackgroundBrush,\n\t\tDockablePaneTitleBackground,\n\t\tDockablePaneTitleBackgroundSelected,\n\t\tDockablePaneTitleForeground,\n\t\tDockablePaneTitleForegroundSelected,\n\t\tPaneHeaderCommandBackground,\n\t\tPaneHeaderCommandBorderBrush,\n\t\tDocumentHeaderBackground,\n\t\tDocumentHeaderForeground,\n\t\tDocumentHeaderForegroundSelected,\n\t\tDocumentHeaderForegroundSelectedActivated,\n\t\tDocumentHeaderBackgroundSelected,\n\t\tDocumentHeaderBackgroundSelectedActivated,\n\t\tDocumentHeaderBackgroundMouseOver,\n\t\tDocumentHeaderBorderBrushMouseOver,\n\t\tDocumentHeaderBorder,\n\t\tDocumentHeaderBorderSelected,\n\t\tDocumentHeaderBorderSelectedActivated,\n\t\tNavigatorWindowTopBackground,\n\t\tNavigatorWindowTitleForeground,\n\t\tNavigatorWindowDocumentTypeForeground,\n\t\tNavigatorWindowInfoTipForeground,\n\t\tNavigatorWindowForeground,\n\t\tNavigatorWindowBackground,\n\t\tNavigatorWindowSelectionBackground,\n\t\tNavigatorWindowSelectionBorderbrush,\n\t\tNavigatorWindowBottomBackground\n\t}\n\n\tpublic enum ContextMenuElement\n\t{\n\t\tDockablePane,\n\t\tDocumentPane,\n\t\tDockableFloatingWindow,\n\t\tDocumentFloatingWindow\n\t}\n}\n"
  },
  {
    "path": "ILSpy.Installer/AppPackage.cs",
    "content": "using System;\n\nnamespace ILSpy.Installer\n{\n\tinternal static class AppPackage\n\t{\n\t\tpublic static Version Version = new Version(DecompilerVersionInfo.Major + \".\" + DecompilerVersionInfo.Minor + \".\" + DecompilerVersionInfo.Build + \".\" + DecompilerVersionInfo.Revision);\n\t}\n}\n"
  },
  {
    "path": "ILSpy.Installer/ILSpy.Installer.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net472</TargetFramework>\r\n    <StartupObject>ILSpy.Installer.Builder</StartupObject>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup>\r\n    <DefineConstants>$(DefineConstants);$(PlatformForInstaller)</DefineConstants>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup>\r\n    <ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <None Remove=\"*.msi\" />\r\n    <None Remove=\"*.exe\" />\r\n    <None Remove=\"*.wxs\" />\r\n    <None Remove=\"*.wixpdb\" />\r\n    <None Remove=\"*.wixobj\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"WixSharp_wix4\" Version=\"2.12.2\" />\r\n  </ItemGroup>\r\n\r\n  <Target Name=\"PostBuild\" AfterTargets=\"PostBuildEvent\">\r\n    <Exec Command=\"cd .\\&#xD;&#xA;set ide=true&#xD;&#xA;&quot;$(TargetPath)&quot;\" />\r\n  </Target>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\ICSharpCode.Decompiler\\ICSharpCode.Decompiler.csproj\" />\r\n  </ItemGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "ILSpy.Installer/README.md",
    "content": "# Building the Installer\n\n## Dependencies\n\nSee https://github.com/oleg-shilo/wixsharp/wiki#dependencies\n\n```\ndotnet tool install --global wix\n```\n\nGitHub runners installed software https://github.com/actions/runner-images/blob/main/images/windows/Windows2025-Readme.md at time \nof writing WiX Toolset 3.14.1.8722\n\n\n## ILSpy Binaries\n\nIt is mandatory to first publish(.ps1) the respective target platforms, then setup can be built, eg\n\n```\nmsbuild ILSpy.Installer.sln /p:Configuration=\"Release\" /p:Platform=\"Any CPU\"\nmsbuild ILSpy.Installer.sln /p:Configuration=\"Release\" /p:Platform=\"Any CPU\" /p:DefineConstants=\"ARM64\"\n```"
  },
  {
    "path": "ILSpy.Installer/setup.cs",
    "content": "using System;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\n\nusing WixSharp;\nusing WixSharp.Controls;\n\nnamespace ILSpy.Installer\n{\n\tinternal class Builder\n\t{\n\t\tstatic public void Main()\n\t\t{\n\t\t\tCompiler.AutoGeneration.IgnoreWildCardEmptyDirectories = true;\n\n#if DEBUG\n\t\t\tvar buildConfiguration = \"Debug\";\n#else\n\t\t\tvar buildConfiguration = \"Release\";\n#endif\n\n#if ARM64\n\t\t\tvar buildPlatform = \"arm64\";\n#else\n\t\t\tvar buildPlatform = \"x64\";\n#endif\n\t\t\tvar buildOutputDir = $@\"ILSpy\\bin\\{buildConfiguration}\\net10.0-windows\\win-{buildPlatform}\\publish\\fwdependent\";\n\n\t\t\tvar project = new Project(\"ILSpy\",\n\t\t\t\t\t\t\t  new InstallDir(@\"%LocalAppData%\\Programs\\ILSpy\",\n\t\t\t\t\t\t\t\t  new DirFiles(Path.Combine(buildOutputDir, \"*.dll\")),\n\t\t\t\t\t\t\t\t  new DirFiles(Path.Combine(buildOutputDir, \"*.exe\")),\n\t\t\t\t\t\t\t\t  new DirFiles(Path.Combine(buildOutputDir, \"*.config\")),\n\t\t\t\t\t\t\t\t  new DirFiles(Path.Combine(buildOutputDir, \"*.json\")),\n\t\t\t\t\t\t\t\t  new Files(Path.Combine(buildOutputDir, \"ILSpy.resources.dll\")),\n\t\t\t\t\t\t\t\t  new Files(Path.Combine(buildOutputDir, \"ILSpy.ReadyToRun.Plugin.resources.dll\"))));\n\n#if ARM64\n\t\t\tproject.Platform = Platform.arm64;\n#else\n\t\t\tproject.Platform = Platform.x64;\n#endif\n\n\t\t\tproject.GUID = new Guid(\"a12fdab1-731b-4a98-9749-d481ce8692ab\");\n\t\t\tproject.Version = AppPackage.Version;\n\t\t\tproject.SourceBaseDir = Path.GetDirectoryName(Environment.CurrentDirectory);\n\t\t\tproject.Scope = InstallScope.perUser;\n\t\t\tproject.ControlPanelInfo.ProductIcon = @\"..\\ILSpy\\Images\\ILSpy.ico\";\n\t\t\tproject.ControlPanelInfo.Manufacturer = \"ICSharpCode Team\";\n\t\t\tproject.LocalizationFile = Path.Combine(Environment.CurrentDirectory, \"winui.wxl\");\n\t\t\tproject.Encoding = Encoding.UTF8;\n\n\t\t\tproject.MajorUpgrade = new MajorUpgrade {\n\t\t\t\tSchedule = UpgradeSchedule.afterInstallInitialize,\n\t\t\t\tAllowSameVersionUpgrades = true,\n\t\t\t\tDowngradeErrorMessage = \"A newer release of ILSpy is already installed on this system. Please uninstall it first to continue.\"\n\t\t\t};\n\n\t\t\tproject.UI = WUI.WixUI_InstallDir;\n\t\t\tproject.CustomUI =\n\t\t\t\tnew DialogSequence()\n\t\t\t\t\t.On(NativeDialogs.WelcomeDlg, Buttons.Next,\n\t\t\t\t\t\tnew ShowDialog(NativeDialogs.VerifyReadyDlg))\n\t\t\t\t\t.On(NativeDialogs.VerifyReadyDlg, Buttons.Back,\n\t\t\t\t\t\tnew ShowDialog(NativeDialogs.WelcomeDlg));\n\n\t\t\tproject.ResolveWildCards().FindFile(f => f.Name.EndsWith(\"ILSpy.exe\")).First()\n\t\t\t\t.Shortcuts = new[] {\n\t\t\t\t\tnew FileShortcut(\"ILSpy\", @\"%ProgramMenu%\")\n\t\t\t\t};\n\n\t\t\tCompiler.BuildMsi(project, Path.Combine(Environment.CurrentDirectory, \"wix\", $\"ILSpy-{AppPackage.Version}-{buildPlatform}.msi\"));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.Installer/winui.wxl",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<WixLocalization  Culture=\"en-US\" xmlns=\"http://wixtoolset.org/schemas/v4/wxl\">\n\t<String Id=\"VerifyReadyDlgInstallText\" Overridable=\"yes\" Value=\"Click Install to begin the installation. Click Cancel to exit the wizard.&#xD;&#xA;&#x9;&#xD;&#xA;&#x9;ILSpy will be installed for current user into following directory:&#xD;&#xA;&#x9;&#xD;&#xA;&#x9;[INSTALLDIR]\"></String>\n</WixLocalization>"
  },
  {
    "path": "ILSpy.Installer.sln",
    "content": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio Version 17\r\nVisualStudioVersion = 17.6.33723.286\r\nMinimumVisualStudioVersion = 10.0.40219.1\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ILSpy.Installer\", \"ILSpy.Installer\\ILSpy.Installer.csproj\", \"{D27793B2-C3F9-4410-AAD0-E117BEDCCEB0}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ICSharpCode.Decompiler\", \"ICSharpCode.Decompiler\\ICSharpCode.Decompiler.csproj\", \"{3FE7AE02-D69D-4C76-9BC0-CF700DFD09FE}\"\r\nEndProject\r\nGlobal\r\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n\t\tDebug|Any CPU = Debug|Any CPU\r\n\t\tRelease|Any CPU = Release|Any CPU\r\n\tEndGlobalSection\r\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n\t\t{D27793B2-C3F9-4410-AAD0-E117BEDCCEB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{D27793B2-C3F9-4410-AAD0-E117BEDCCEB0}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{D27793B2-C3F9-4410-AAD0-E117BEDCCEB0}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{D27793B2-C3F9-4410-AAD0-E117BEDCCEB0}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{3FE7AE02-D69D-4C76-9BC0-CF700DFD09FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{3FE7AE02-D69D-4C76-9BC0-CF700DFD09FE}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{3FE7AE02-D69D-4C76-9BC0-CF700DFD09FE}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{3FE7AE02-D69D-4C76-9BC0-CF700DFD09FE}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\tEndGlobalSection\r\n\tGlobalSection(SolutionProperties) = preSolution\r\n\t\tHideSolutionNode = FALSE\r\n\tEndGlobalSection\r\n\tGlobalSection(ExtensibilityGlobals) = postSolution\r\n\t\tSolutionGuid = {A343F649-2CFB-4022-9133-1BA55FBCE3D1}\r\n\tEndGlobalSection\r\nEndGlobal\r\n"
  },
  {
    "path": "ILSpy.ReadyToRun/ILSpy.ReadyToRun.csproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <AssemblyName>ILSpy.ReadyToRun.Plugin</AssemblyName>\r\n    <TargetFramework>net10.0-windows</TargetFramework>\r\n    <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers>\r\n    <GenerateAssemblyInfo>False</GenerateAssemblyInfo>\r\n    <NeutralResourcesLanguage>en-US</NeutralResourcesLanguage>\r\n    <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>\r\n    <UseWpf>true</UseWpf>\r\n    <IsPackable>false</IsPackable>\r\n    <EnableWindowsTargeting>true</EnableWindowsTargeting>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Debug'\">\r\n    <DebugType>full</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n    <CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\r\n    <DebugType>pdbonly</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup>\r\n    <OutputPath>..\\ILSpy\\bin\\$(Configuration)\\</OutputPath>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\ILSpy\\ILSpy.csproj\" />\r\n    <ProjectReference Include=\"..\\ICSharpCode.Decompiler\\ICSharpCode.Decompiler.csproj\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"Iced\" />\r\n    <PackageReference Include=\"ILCompiler.Reflection.ReadyToRun.Experimental\" />\r\n    <!-- ILCompiler.Reflection.ReadyToRun has dependencies on System.Reflection.Metadata and\r\n         System.Runtime.CompilerServices.Unsafe. Because the AddIn compiles into ILSpy's output\r\n         directory, we're at risk of overwriting our dependencies with different versions.\r\n         So ensure NuGet uses consistent versions (from our packages.props) for these.\r\n         -->\r\n    <PackageReference Include=\"System.Reflection.Metadata\" />\r\n    <PackageReference Include=\"System.Runtime.CompilerServices.Unsafe\" />\r\n  </ItemGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "ILSpy.ReadyToRun/Properties/AssemblyInfo.cs",
    "content": "using System;\nusing System.Reflection;\nusing System.Resources;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\nusing System.Runtime.Versioning;\n\n[assembly: TargetPlatform(\"Windows10.0\")]\n[assembly: SupportedOSPlatform(\"Windows7.0\")]\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: NeutralResourcesLanguage(\"en-US\")]\n"
  },
  {
    "path": "ILSpy.ReadyToRun/Properties/Resources.Designer.cs",
    "content": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace ILSpy.ReadyToRun.Properties {\n    using System;\n    \n    \n    /// <summary>\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\n    /// </summary>\n    // This class was auto-generated by the StronglyTypedResourceBuilder\n    // class via a tool like ResGen or Visual Studio.\n    // To add or remove a member, edit your .ResX file then rerun ResGen\n    // with the /str option, or rebuild your VS project.\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"16.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    public class Resources {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal Resources() {\n        }\n        \n        /// <summary>\n        ///   Returns the cached ResourceManager instance used by this class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        public static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"ILSpy.ReadyToRun.Properties.Resources\", typeof(Resources).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   Overrides the current thread's CurrentUICulture property for all\n        ///   resource lookups using this strongly typed resource class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        public static global::System.Globalization.CultureInfo Culture {\n            get {\n                return resourceCulture;\n            }\n            set {\n                resourceCulture = value;\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Disassembly Format.\n        /// </summary>\n        public static string DisassemblyFormat {\n            get {\n                return ResourceManager.GetString(\"DisassemblyFormat\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to ReadyToRun.\n        /// </summary>\n        public static string ReadyToRun {\n            get {\n                return ResourceManager.GetString(\"ReadyToRun\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show Debug Info.\n        /// </summary>\n        public static string ShowDebugInfo {\n            get {\n                return ResourceManager.GetString(\"ShowDebugInfo\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show Unwind Info.\n        /// </summary>\n        public static string ShowStackUnwindInfo {\n            get {\n                return ResourceManager.GetString(\"ShowStackUnwindInfo\", resourceCulture);\n            }\n        }\n\n\t\t/// <summary>\n\t\t///   Looks up a localized string similar to Show GC Info.\n\t\t/// </summary>\n\t\tpublic static string ShowGCInfo {\n\t\t\tget {\n\t\t\t\treturn ResourceManager.GetString(\"ShowGCInfo\", resourceCulture);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.ReadyToRun/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"DisassemblyFormat\" xml:space=\"preserve\">\n    <value>Disassembly Format</value>\n  </data>\n  <data name=\"ReadyToRun\" xml:space=\"preserve\">\n    <value>ReadyToRun</value>\n  </data>\n  <data name=\"ShowDebugInfo\" xml:space=\"preserve\">\n    <value>Show Debug Info</value>\n  </data>\n  <data name=\"ShowGCInfo\" xml:space=\"preserve\">\n    <value>Show GC Info</value>\n  </data>\n  <data name=\"ShowStackUnwindInfo\" xml:space=\"preserve\">\n    <value>Show Stack Unwind Info</value>\n  </data>\n</root>"
  },
  {
    "path": "ILSpy.ReadyToRun/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"ILSpy.ReadyToRun\": {\n      \"commandName\": \"Executable\",\n      \"executablePath\": \"C:\\\\Users\\\\sie_p\\\\Projects\\\\ILSpy\\\\ILSpy\\\\bin\\\\Debug\\\\net472\\\\ILSpy.exe\",\n      \"commandLineArgs\": \"/separate /language:ReadyToRun\"\n    }\n  }\n}"
  },
  {
    "path": "ILSpy.ReadyToRun/ReadyToRunDisassembler.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Reflection.Metadata.Ecma335;\n\nusing Iced.Intel;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.IL;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.ILSpy.Util;\n\nusing ILCompiler.Reflection.ReadyToRun;\nusing ILCompiler.Reflection.ReadyToRun.Amd64;\n\nnamespace ICSharpCode.ILSpy.ReadyToRun\n{\n\tinternal class ReadyToRunDisassembler\n\t{\n\t\tprivate readonly ITextOutput output;\n\t\tprivate readonly ReadyToRunReader reader;\n\t\tprivate readonly RuntimeFunction runtimeFunction;\n\t\tprivate readonly SettingsService settingsService;\n\n\t\tpublic ReadyToRunDisassembler(ITextOutput output, ReadyToRunReader reader, RuntimeFunction runtimeFunction, SettingsService settingsService)\n\t\t{\n\t\t\tthis.output = output;\n\t\t\tthis.reader = reader;\n\t\t\tthis.runtimeFunction = runtimeFunction;\n\t\t\tthis.settingsService = settingsService;\n\t\t}\n\n\t\tpublic void Disassemble(PEFile currentFile, int bitness, ulong address, bool showMetadataTokens, bool showMetadataTokensInBase10)\n\t\t{\n\t\t\tReadyToRunMethod readyToRunMethod = runtimeFunction.Method;\n\t\t\tWriteCommentLine(readyToRunMethod.SignatureString);\n\n\t\t\tvar options = settingsService.GetSettings<ReadyToRunOptions>();\n\n\t\t\tif (options.IsShowGCInfo)\n\t\t\t{\n\t\t\t\tif (readyToRunMethod.GcInfo != null)\n\t\t\t\t{\n\t\t\t\t\tstring[] lines = readyToRunMethod.GcInfo.ToString()?.Split(Environment.NewLine) ?? [];\n\t\t\t\t\tWriteCommentLine(\"GC info:\");\n\t\t\t\t\tforeach (string line in lines)\n\t\t\t\t\t{\n\t\t\t\t\t\tWriteCommentLine(line);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tWriteCommentLine(\"GC Info is not available for this method\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tDictionary<ulong, UnwindCode> unwindInfo = null;\n\t\t\tif (options.IsShowUnwindInfo && bitness == 64)\n\t\t\t{\n\t\t\t\tunwindInfo = WriteUnwindInfo();\n\t\t\t}\n\n\t\t\tbool isShowDebugInfo = options.IsShowDebugInfo;\n\t\t\tDebugInfoHelper debugInfo = null;\n\t\t\tif (isShowDebugInfo)\n\t\t\t{\n\t\t\t\tdebugInfo = WriteDebugInfo();\n\t\t\t}\n\n\t\t\tbyte[] codeBytes = new byte[runtimeFunction.Size];\n\t\t\tfor (int i = 0; i < runtimeFunction.Size; i++)\n\t\t\t{\n\t\t\t\tcodeBytes[i] = reader.Image[reader.GetOffset(runtimeFunction.StartAddress) + i];\n\t\t\t}\n\n\t\t\tvar codeReader = new ByteArrayCodeReader(codeBytes);\n\t\t\tvar decoder = Decoder.Create(bitness, codeReader);\n\t\t\tdecoder.IP = address;\n\t\t\tulong endRip = decoder.IP + (uint)codeBytes.Length;\n\n\t\t\tvar instructions = new InstructionList();\n\t\t\twhile (decoder.IP < endRip)\n\t\t\t{\n\t\t\t\tdecoder.Decode(out instructions.AllocUninitializedElement());\n\t\t\t}\n\n\t\t\tstring disassemblyFormat = options.DisassemblyFormat;\n\t\t\tFormatter formatter = null;\n\t\t\tif (disassemblyFormat.Equals(ReadyToRunOptions.intel))\n\t\t\t{\n\t\t\t\tformatter = new NasmFormatter();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tDebug.Assert(disassemblyFormat.Equals(ReadyToRunOptions.gas));\n\t\t\t\tformatter = new GasFormatter();\n\t\t\t}\n\t\t\tformatter.Options.DigitSeparator = \"`\";\n\t\t\tformatter.Options.FirstOperandCharIndex = 10;\n\t\t\tvar tempOutput = new StringOutput();\n\t\t\tulong baseInstrIP = instructions[0].IP;\n\n\t\t\tvar boundsMap = new Dictionary<uint, uint>();\n\t\t\tif (runtimeFunction.DebugInfo != null)\n\t\t\t{\n\t\t\t\tforeach (var bound in runtimeFunction.DebugInfo.BoundsList)\n\t\t\t\t{\n\t\t\t\t\t// ignoring the return value assuming the same key is always mapped to the same value in runtimeFunction.DebugInfo.BoundsList\n\t\t\t\t\tboundsMap.TryAdd(bound.NativeOffset, bound.ILOffset);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach (var instr in instructions)\n\t\t\t{\n\t\t\t\tint byteBaseIndex = (int)(instr.IP - address);\n\t\t\t\tif (isShowDebugInfo && runtimeFunction.DebugInfo != null)\n\t\t\t\t{\n\t\t\t\t\tif (byteBaseIndex >= 0 && boundsMap.TryGetValue((uint)byteBaseIndex, out uint boundILOffset))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (boundILOffset == (uint)DebugInfoBoundsType.Prolog)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tWriteCommentLine(\"Prolog\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (boundILOffset == (uint)DebugInfoBoundsType.Epilog)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tWriteCommentLine(\"Epilog\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tWriteCommentLine($\"IL_{boundILOffset:x4}\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (options.IsShowGCInfo)\n\t\t\t\t{\n\t\t\t\t\tDecorateGCInfo(instr, baseInstrIP, readyToRunMethod.GcInfo);\n\t\t\t\t}\n\t\t\t\tformatter.Format(instr, tempOutput);\n\t\t\t\toutput.Write(instr.IP.ToString(\"X16\"));\n\t\t\t\toutput.Write(\" \");\n\t\t\t\tint instrLen = instr.Length;\n\t\t\t\tfor (int i = 0; i < instrLen; i++)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(codeBytes[byteBaseIndex + i].ToString(\"X2\"));\n\t\t\t\t}\n\t\t\t\tint missingBytes = 10 - instrLen;\n\t\t\t\tfor (int i = 0; i < missingBytes; i++)\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\"  \");\n\t\t\t\t}\n\t\t\t\toutput.Write(\" \");\n\t\t\t\toutput.Write(tempOutput.ToStringAndReset());\n\t\t\t\tDecorateUnwindInfo(unwindInfo, baseInstrIP, instr);\n\t\t\t\tDecorateDebugInfo(instr, debugInfo, baseInstrIP);\n\t\t\t\tDecorateCallSite(currentFile, showMetadataTokens, showMetadataTokensInBase10, instr);\n\t\t\t\toutput.WriteLine();\n\t\t\t}\n\t\t\toutput.WriteLine();\n\t\t}\n\n\t\tprivate void DecorateGCInfo(Instruction instr, ulong baseInstrIP, BaseGcInfo gcInfo)\n\t\t{\n\t\t\tulong codeOffset = instr.IP - baseInstrIP;\n\t\t\tif (gcInfo != null && gcInfo.Transitions != null && gcInfo.Transitions.TryGetValue((int)codeOffset, out List<BaseGcTransition> transitionsForOffset))\n\t\t\t{\n\t\t\t\t// this value comes from a manual count of the spaces used for each instruction in Disassemble()\n\t\t\t\tstring indent = new string(' ', 36);\n\t\t\t\tforeach (var transition in transitionsForOffset)\n\t\t\t\t{\n\t\t\t\t\tWriteCommentLine(indent + transition.ToString());\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate void WriteCommentLine(string comment)\n\t\t{\n\t\t\toutput.WriteLine(\"; \" + comment);\n\t\t}\n\n\t\tprivate class NativeVarInfoRecord\n\t\t{\n\t\t\tpublic ulong codeOffset;\n\t\t\tpublic bool isStart;\n\t\t\tpublic bool isRegRelative;\n\t\t\tpublic string register;\n\t\t\tpublic int registerOffset;\n\t\t\tpublic Variable variable;\n\t\t}\n\n\t\tprivate class DebugInfoHelper\n\t\t{\n\t\t\tpublic List<NativeVarInfoRecord> records;\n\t\t\tpublic int i;\n\t\t\tpublic Dictionary<string, Dictionary<int, HashSet<Variable>>> registerRelativeVariables;\n\t\t\tpublic Dictionary<string, HashSet<Variable>> registerVariables;\n\n\t\t\tpublic DebugInfoHelper()\n\t\t\t{\n\t\t\t\tthis.registerRelativeVariables = new Dictionary<string, Dictionary<int, HashSet<Variable>>>();\n\t\t\t\tthis.registerVariables = new Dictionary<string, HashSet<Variable>>();\n\t\t\t}\n\n\t\t\tpublic void Update(ulong codeOffset)\n\t\t\t{\n\t\t\t\tHashSet<Variable> variables;\n\t\t\t\twhile (i < records.Count && records[i].codeOffset == codeOffset)\n\t\t\t\t{\n\t\t\t\t\tif (records[i].isRegRelative)\n\t\t\t\t\t{\n\t\t\t\t\t\tDictionary<int, HashSet<Variable>> offsetToVariableMap;\n\t\t\t\t\t\tif (records[i].isStart)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!this.registerRelativeVariables.TryGetValue(records[i].register, out offsetToVariableMap))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toffsetToVariableMap = new Dictionary<int, HashSet<Variable>>();\n\t\t\t\t\t\t\t\tthis.registerRelativeVariables.Add(records[i].register, offsetToVariableMap);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!offsetToVariableMap.TryGetValue(records[i].registerOffset, out variables))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvariables = new HashSet<Variable>();\n\t\t\t\t\t\t\t\toffsetToVariableMap.Add(records[i].registerOffset, variables);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tvariables.Add(records[i].variable);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toffsetToVariableMap = this.registerRelativeVariables[records[i].register];\n\t\t\t\t\t\t\tvariables = offsetToVariableMap[records[i].registerOffset];\n\t\t\t\t\t\t\tvariables.Remove(records[i].variable);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif (records[i].isStart)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!this.registerVariables.TryGetValue(records[i].register, out variables))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvariables = new HashSet<Variable>();\n\t\t\t\t\t\t\t\tthis.registerVariables.Add(records[i].register, variables);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tvariables.Add(records[i].variable);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// If the optimizing compiler decides that two variables will always have the same value within a basic block\n\t\t\t\t\t\t\t// It might assign the same location for two variables.\n\n\t\t\t\t\t\t\t// The compiler also generates potentially wrong 1 byte long debug info record for arguments in prolog.\n\t\t\t\t\t\t\t// These record might describe the same variable in overlapping ranges.\n\t\t\t\t\t\t\t// See https://cshung.github.io/posts/debug-info-debugging/ for the investigation.\n\t\t\t\t\t\t\tvariables = this.registerVariables[records[i].register];\n\t\t\t\t\t\t\tvariables.Remove(records[i].variable);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate DebugInfoHelper WriteDebugInfo()\n\t\t{\n\t\t\tList<NativeVarInfoRecord> records = new List<NativeVarInfoRecord>();\n\t\t\tforeach (RuntimeFunction runtimeFunction in runtimeFunction.Method.RuntimeFunctions)\n\t\t\t{\n\t\t\t\tDebugInfo debugInfo = runtimeFunction.DebugInfo;\n\t\t\t\tif (debugInfo != null && debugInfo.BoundsList.Count > 0)\n\t\t\t\t{\n\t\t\t\t\tfor (int i = 0; i < debugInfo.VariablesList.Count; ++i)\n\t\t\t\t\t{\n\t\t\t\t\t\tvar varLoc = debugInfo.VariablesList[i];\n\t\t\t\t\t\tif (varLoc.StartOffset == varLoc.EndOffset)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// This could happen if the compiler is generating bogus variable info mapping record that covers 0 instructions\n\t\t\t\t\t\t\t// See https://github.com/dotnet/runtime/issues/47202\n\t\t\t\t\t\t\t// Debug.Assert(false);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tswitch (varLoc.VariableLocation.VarLocType)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase VarLocType.VLT_STK:\n\t\t\t\t\t\t\tcase VarLocType.VLT_STK_BYREF:\n\t\t\t\t\t\t\t\trecords.Add(new NativeVarInfoRecord {\n\t\t\t\t\t\t\t\t\tcodeOffset = varLoc.StartOffset,\n\t\t\t\t\t\t\t\t\tisStart = true,\n\t\t\t\t\t\t\t\t\tisRegRelative = true,\n\t\t\t\t\t\t\t\t\tregister = DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data1),\n\t\t\t\t\t\t\t\t\tregisterOffset = varLoc.VariableLocation.Data2,\n\t\t\t\t\t\t\t\t\tvariable = varLoc.Variable\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t;\n\t\t\t\t\t\t\t\trecords.Add(new NativeVarInfoRecord {\n\t\t\t\t\t\t\t\t\tcodeOffset = varLoc.EndOffset,\n\t\t\t\t\t\t\t\t\tisStart = false,\n\t\t\t\t\t\t\t\t\tisRegRelative = true,\n\t\t\t\t\t\t\t\t\tregister = DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data1),\n\t\t\t\t\t\t\t\t\tregisterOffset = varLoc.VariableLocation.Data2,\n\t\t\t\t\t\t\t\t\tvariable = varLoc.Variable\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase VarLocType.VLT_REG:\n\t\t\t\t\t\t\t\trecords.Add(new NativeVarInfoRecord {\n\t\t\t\t\t\t\t\t\tcodeOffset = varLoc.StartOffset,\n\t\t\t\t\t\t\t\t\tisStart = true,\n\t\t\t\t\t\t\t\t\tisRegRelative = false,\n\t\t\t\t\t\t\t\t\tregister = DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data1),\n\t\t\t\t\t\t\t\t\tvariable = varLoc.Variable\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\trecords.Add(new NativeVarInfoRecord {\n\t\t\t\t\t\t\t\t\tcodeOffset = varLoc.EndOffset,\n\t\t\t\t\t\t\t\t\tisStart = false,\n\t\t\t\t\t\t\t\t\tisRegRelative = false,\n\t\t\t\t\t\t\t\t\tregister = DebugInfo.GetPlatformSpecificRegister(debugInfo.Machine, varLoc.VariableLocation.Data1),\n\t\t\t\t\t\t\t\t\tvariable = varLoc.Variable\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t// TODO\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\trecords.Sort((x, y) => {\n\t\t\t\tif (x.codeOffset < y.codeOffset)\n\t\t\t\t{\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t\telse if (x.codeOffset > y.codeOffset)\n\t\t\t\t{\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (!x.isStart && y.isStart)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn -1;\n\t\t\t\t\t}\n\t\t\t\t\telse if (x.isStart && !y.isStart)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn new DebugInfoHelper {\n\t\t\t\trecords = records\n\t\t\t};\n\t\t}\n\n\t\tprivate Dictionary<ulong, UnwindCode> WriteUnwindInfo()\n\t\t{\n\t\t\tDictionary<ulong, UnwindCode> unwindCodes = new Dictionary<ulong, UnwindCode>();\n\t\t\tif (runtimeFunction.UnwindInfo is UnwindInfo amd64UnwindInfo)\n\t\t\t{\n\t\t\t\tstring parsedFlags = \"\";\n\t\t\t\tif ((amd64UnwindInfo.Flags & (int)UnwindFlags.UNW_FLAG_EHANDLER) != 0)\n\t\t\t\t{\n\t\t\t\t\tparsedFlags += \" EHANDLER\";\n\t\t\t\t}\n\t\t\t\tif ((amd64UnwindInfo.Flags & (int)UnwindFlags.UNW_FLAG_UHANDLER) != 0)\n\t\t\t\t{\n\t\t\t\t\tparsedFlags += \" UHANDLER\";\n\t\t\t\t}\n\t\t\t\tif ((amd64UnwindInfo.Flags & (int)UnwindFlags.UNW_FLAG_CHAININFO) != 0)\n\t\t\t\t{\n\t\t\t\t\tparsedFlags += \" CHAININFO\";\n\t\t\t\t}\n\t\t\t\tif (parsedFlags.Length == 0)\n\t\t\t\t{\n\t\t\t\t\tparsedFlags = \" NHANDLER\";\n\t\t\t\t}\n\t\t\t\tWriteCommentLine($\"UnwindInfo:\");\n\t\t\t\tWriteCommentLine($\"Version:            {amd64UnwindInfo.Version}\");\n\t\t\t\tWriteCommentLine($\"Flags:              0x{amd64UnwindInfo.Flags:X2}{parsedFlags}\");\n\t\t\t\tWriteCommentLine($\"FrameRegister:      {((amd64UnwindInfo.FrameRegister == 0) ? \"none\" : amd64UnwindInfo.FrameRegister.ToString().ToLower())}\");\n\t\t\t\tfor (int unwindCodeIndex = 0; unwindCodeIndex < amd64UnwindInfo.UnwindCodes.Count; unwindCodeIndex++)\n\t\t\t\t{\n\t\t\t\t\tunwindCodes.Add((ulong)(amd64UnwindInfo.UnwindCodes[unwindCodeIndex].CodeOffset), amd64UnwindInfo.UnwindCodes[unwindCodeIndex]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn unwindCodes;\n\t\t}\n\n\t\tprivate void DecorateUnwindInfo(Dictionary<ulong, UnwindCode> unwindInfo, ulong baseInstrIP, Instruction instr)\n\t\t{\n\t\t\tulong nextInstructionOffset = instr.NextIP - baseInstrIP;\n\t\t\tif (unwindInfo != null && unwindInfo.ContainsKey(nextInstructionOffset))\n\t\t\t{\n\t\t\t\tUnwindCode unwindCode = unwindInfo[nextInstructionOffset];\n\t\t\t\toutput.Write($\" ; {unwindCode.UnwindOp}({unwindCode.OpInfoStr})\");\n\t\t\t}\n\t\t}\n\n\t\tprivate void DecorateDebugInfo(Instruction instr, DebugInfoHelper debugRecords, ulong baseInstrIP)\n\t\t{\n\t\t\tif (debugRecords != null)\n\t\t\t{\n\t\t\t\tHashSet<Variable> variables;\n\t\t\t\tInstructionInfoFactory factory = new InstructionInfoFactory();\n\t\t\t\tInstructionInfo info = factory.GetInfo(instr);\n\t\t\t\tulong codeOffset = instr.IP - baseInstrIP;\n\t\t\t\tdebugRecords.Update(codeOffset);\n\t\t\t\tforeach (UsedMemory usedMemInfo in info.GetUsedMemory())\n\t\t\t\t{\n\t\t\t\t\tstring baseRegister = usedMemInfo.Base.ToString();\n\t\t\t\t\tint displacement;\n\t\t\t\t\tunchecked\n\t\t\t\t\t{ displacement = (int)usedMemInfo.Displacement; }\n\t\t\t\t\tDictionary<int, HashSet<Variable>> offsetToVariableMap;\n\t\t\t\t\tif (debugRecords.registerRelativeVariables.TryGetValue(usedMemInfo.Base.ToString(), out offsetToVariableMap))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (offsetToVariableMap.TryGetValue(displacement, out variables))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toutput.Write($\";\");\n\t\t\t\t\t\t\tforeach (Variable variable in variables)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\toutput.Write($\" [{usedMemInfo.Base.ToString().ToLower()}{(displacement < 0 ? '-' : '+')}{Math.Abs(displacement):X}h] = {variable.Type} {variable.Index}\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tforeach (UsedRegister usedMemInfo in info.GetUsedRegisters())\n\t\t\t\t{\n\t\t\t\t\t// TODO, if the code is accessing EAX but the debug info maps to RAX, then this match is going to fail.\n\t\t\t\t\tif (debugRecords.registerVariables.TryGetValue(usedMemInfo.Register.ToString(), out variables))\n\t\t\t\t\t{\n\t\t\t\t\t\toutput.Write($\";\");\n\t\t\t\t\t\tforeach (Variable variable in variables)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toutput.Write($\" {usedMemInfo.Register.ToString().ToLower()} = {variable.Type} {variable.Index}\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate void DecorateCallSite(PEFile currentFile, bool showMetadataTokens, bool showMetadataTokensInBase10, Instruction instr)\n\t\t{\n\t\t\tif (instr.IsCallNearIndirect)\n\t\t\t{\n\t\t\t\tint importCellAddress = (int)instr.IPRelativeMemoryAddress;\n\t\t\t\tif (reader.ImportSignatures.ContainsKey(importCellAddress))\n\t\t\t\t{\n\t\t\t\t\toutput.Write(\" ; \");\n\t\t\t\t\tReadyToRunSignature signature = reader.ImportSignatures[importCellAddress];\n\t\t\t\t\tswitch (signature)\n\t\t\t\t\t{\n\t\t\t\t\t\tcase MethodDefEntrySignature methodDefSignature:\n\t\t\t\t\t\t\tvar methodDefToken = MetadataTokens.EntityHandle(unchecked((int)methodDefSignature.MethodDefToken));\n\t\t\t\t\t\t\tif (showMetadataTokens)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (showMetadataTokensInBase10)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\toutput.WriteReference(currentFile, methodDefToken, $\"({MetadataTokens.GetToken(methodDefToken)}) \", \"metadata\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\toutput.WriteReference(currentFile, methodDefToken, $\"({MetadataTokens.GetToken(methodDefToken):X8}) \", \"metadata\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tmethodDefToken.WriteTo(currentFile, output, default);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase MethodRefEntrySignature methodRefSignature:\n\t\t\t\t\t\t\tvar methodRefToken = MetadataTokens.EntityHandle(unchecked((int)methodRefSignature.MethodRefToken));\n\t\t\t\t\t\t\tif (showMetadataTokens)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (showMetadataTokensInBase10)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\toutput.WriteReference(currentFile, methodRefToken, $\"({MetadataTokens.GetToken(methodRefToken)}) \", \"metadata\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\toutput.WriteReference(currentFile, methodRefToken, $\"({MetadataTokens.GetToken(methodRefToken):X8}) \", \"metadata\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tmethodRefToken.WriteTo(currentFile, output, default);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\toutput.Write(reader.ImportSignatures[importCellAddress].ToString(new SignatureFormattingOptions()));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy.ReadyToRun/ReadyToRunLanguage.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n// #define STRESS\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Immutable;\nusing System.Composition;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.PortableExecutable;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.Disassembler;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.Solution;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy.Util;\nusing ICSharpCode.ILSpyX;\n\nusing ILCompiler.Reflection.ReadyToRun;\n\nusing TomsToolbox.Composition;\n\nusing MetadataReader = System.Reflection.Metadata.MetadataReader;\n\nnamespace ICSharpCode.ILSpy.ReadyToRun\n{\n#if STRESS\n\tclass DummyOutput : ITextOutput\n\t{\n\t\tpublic string IndentationString { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }\n\n\t\tpublic void Indent()\n\t\t{\n\t\t}\n\n\t\tpublic void MarkFoldEnd()\n\t\t{\n\t\t}\n\n\t\tpublic void MarkFoldStart(string collapsedText = \"...\", bool defaultCollapsed = false, bool isDefinition = false)\n\t\t{\n\t\t}\n\n\t\tpublic void Unindent()\n\t\t{\n\t\t}\n\n\t\tpublic void Write(char ch)\n\t\t{\n\t\t}\n\n\t\tpublic void Write(string text)\n\t\t{\n\t\t}\n\n\t\tpublic void WriteLine()\n\t\t{\n\t\t}\n\n\t\tpublic void WriteLocalReference(string text, object reference, bool isDefinition = false)\n\t\t{\n\t\t}\n\n\t\tpublic void WriteReference(OpCodeInfo opCode, bool omitSuffix = false)\n\t\t{\n\t\t}\n\n\t\tpublic void WriteReference(PEFile module, Handle handle, string text, string protocol = \"decompile\", bool isDefinition = false)\n\t\t{\n\t\t}\n\n\t\tpublic void WriteReference(IType type, string text, bool isDefinition = false)\n\t\t{\n\t\t}\n\n\t\tpublic void WriteReference(IMember member, string text, bool isDefinition = false)\n\t\t{\n\t\t}\n\n\t\tpublic void WriteReference(MetadataFile metadata, Handle handle, string text, string protocol = \"decompile\", bool isDefinition = false)\n\t\t{\n\t\t}\n\t}\n#endif\n\n\t[Export(typeof(Language))]\n\t[Shared]\n\tinternal class ReadyToRunLanguage(SettingsService settingsService, IExportProvider exportProvider) : Language\n\t{\n\t\tprivate static readonly ConditionalWeakTable<MetadataFile, ReadyToRunReaderCacheEntry> readyToRunReaders = new ConditionalWeakTable<MetadataFile, ReadyToRunReaderCacheEntry>();\n\n\t\tpublic override string Name => \"ReadyToRun\";\n\n\t\tpublic override string FileExtension {\n\t\t\tget { return \".asm\"; }\n\t\t}\n\n\t\tpublic override void WriteCommentLine(ITextOutput output, string comment)\n\t\t{\n\t\t\toutput.WriteLine(\"; \" + comment);\n\t\t}\n\n\t\tpublic override ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tPEFile module = assembly.GetMetadataFileAsync().GetAwaiter().GetResult() as PEFile;\n\t\t\tReadyToRunReaderCacheEntry cacheEntry = GetReader(assembly, module);\n\t\t\tif (cacheEntry.readyToRunReader == null)\n\t\t\t{\n\t\t\t\tWriteCommentLine(output, cacheEntry.failureReason);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tReadyToRunReader reader = cacheEntry.readyToRunReader;\n\t\t\t\tWriteCommentLine(output, $\"Machine                  : {reader.Machine}\");\n\t\t\t\tWriteCommentLine(output, $\"OperatingSystem          : {reader.OperatingSystem}\");\n\t\t\t\tWriteCommentLine(output, $\"CompilerIdentifier       : {reader.CompilerIdentifier}\");\n\t\t\t\tif (reader.OwnerCompositeExecutable != null)\n\t\t\t\t{\n\t\t\t\t\tWriteCommentLine(output, $\"OwnerCompositeExecutable : {reader.OwnerCompositeExecutable}\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn base.DecompileAssembly(assembly, output, options);\n\t\t}\n\n\t\tpublic override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tPEFile module = method.ParentModule.MetadataFile as PEFile;\n\t\t\tReadyToRunReaderCacheEntry cacheEntry = GetReader(module.GetLoadedAssembly(), module);\n\t\t\tif (cacheEntry.readyToRunReader == null)\n\t\t\t{\n\t\t\t\tWriteCommentLine(output, cacheEntry.failureReason);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tReadyToRunReader reader = cacheEntry.readyToRunReader;\n\t\t\t\tint bitness = -1;\n\t\t\t\tif (reader.Machine == Machine.Amd64)\n\t\t\t\t{\n\t\t\t\t\tbitness = 64;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tDebug.Assert(reader.Machine == Machine.I386);\n\t\t\t\t\tbitness = 32;\n\t\t\t\t}\n\t\t\t\tif (cacheEntry.methodMap == null)\n\t\t\t\t{\n\t\t\t\t\tIEnumerable<ReadyToRunMethod> readyToRunMethods = null;\n\t\t\t\t\tif (cacheEntry.compositeReadyToRunReader == null)\n\t\t\t\t\t{\n\t\t\t\t\t\treadyToRunMethods = reader.Methods;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treadyToRunMethods = cacheEntry.compositeReadyToRunReader.Methods\n\t\t\t\t\t\t\t.Where(m => {\n\t\t\t\t\t\t\t\tMetadataReader mr = m.ComponentReader.MetadataReader;\n\t\t\t\t\t\t\t\treturn string.Equals(mr.GetString(mr.GetAssemblyDefinition().Name), method.ParentModule.Name, StringComparison.OrdinalIgnoreCase);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tcacheEntry.methodMap = readyToRunMethods.ToList()\n\t\t\t\t\t\t\t.GroupBy(m => m.MethodHandle)\n\t\t\t\t\t\t\t.ToDictionary(g => g.Key, g => g.ToArray());\n\t\t\t\t}\n\t\t\t\tvar displaySettings = settingsService.DisplaySettings;\n\t\t\t\tbool showMetadataTokens = displaySettings.ShowMetadataTokens;\n\t\t\t\tbool showMetadataTokensInBase10 = displaySettings.ShowMetadataTokensInBase10;\n#if STRESS\n\t\t\t\tITextOutput originalOutput = output;\n\t\t\t\toutput = new DummyOutput();\n\t\t\t\t{\n\t\t\t\t\tforeach (var readyToRunMethod in reader.Methods)\n\t\t\t\t\t{\n#else\n\t\t\t\tif (cacheEntry.methodMap.TryGetValue(method.MetadataToken, out var methods))\n\t\t\t\t{\n\t\t\t\t\tforeach (var readyToRunMethod in methods)\n\t\t\t\t\t{\n#endif\n\t\t\t\t\t\tforeach (RuntimeFunction runtimeFunction in readyToRunMethod.RuntimeFunctions)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPEFile file = null;\n\t\t\t\t\t\t\tReadyToRunReader disassemblingReader = null;\n\t\t\t\t\t\t\tif (cacheEntry.compositeReadyToRunReader == null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisassemblingReader = reader;\n\t\t\t\t\t\t\t\tfile = method.ParentModule.MetadataFile as PEFile;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisassemblingReader = cacheEntry.compositeReadyToRunReader;\n\t\t\t\t\t\t\t\tfile = ((IlSpyAssemblyMetadata)readyToRunMethod.ComponentReader).Module;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tnew ReadyToRunDisassembler(output, disassemblingReader, runtimeFunction, settingsService).Disassemble(file, bitness, (ulong)runtimeFunction.StartAddress, showMetadataTokens, showMetadataTokensInBase10);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n#if STRESS\n\t\t\t\toutput = originalOutput;\n\t\t\t\toutput.WriteLine(\"Passed\");\n#endif\n\t\t\t}\n\t\t}\n\n\t\tpublic override RichText GetRichTextTooltip(IEntity entity)\n\t\t{\n\t\t\treturn exportProvider.GetExportedValue<LanguageService>().ILLanguage.GetRichTextTooltip(entity);\n\t\t}\n\n\t\tprivate ReadyToRunReaderCacheEntry GetReader(LoadedAssembly assembly, MetadataFile file)\n\t\t{\n\t\t\tReadyToRunReaderCacheEntry result;\n\t\t\tlock (readyToRunReaders)\n\t\t\t{\n\t\t\t\tif (!readyToRunReaders.TryGetValue(file, out result))\n\t\t\t\t{\n\t\t\t\t\tresult = new ReadyToRunReaderCacheEntry();\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tif ((file is not PEFile module) || (module.Reader == null))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tresult.readyToRunReader = null;\n\t\t\t\t\t\t\tresult.failureReason = \"File is not a valid PE file.\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tReadOnlyMemory<byte> content = module.Reader.GetEntireImage().GetContent().AsMemory();\n\t\t\t\t\t\t\tresult.readyToRunReader = new ReadyToRunReader(new ReadyToRunAssemblyResolver(assembly), new StandaloneAssemblyMetadata(module.Reader), module.Reader, module.FileName, content);\n\t\t\t\t\t\t\tif (result.readyToRunReader.Machine != Machine.Amd64 && result.readyToRunReader.Machine != Machine.I386)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tresult.failureReason = $\"Architecture {result.readyToRunReader.Machine} is not currently supported.\";\n\t\t\t\t\t\t\t\tresult.readyToRunReader = null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (result.readyToRunReader.OwnerCompositeExecutable != null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstring compositeModuleName = Path.GetFileNameWithoutExtension(result.readyToRunReader.OwnerCompositeExecutable);\n\t\t\t\t\t\t\t\tPEFile compositeFile = assembly.GetAssemblyResolver().ResolveModule(assembly.GetMetadataFileOrNull(), compositeModuleName) as PEFile;\n\t\t\t\t\t\t\t\tif (compositeFile == null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tresult.readyToRunReader = null;\n\t\t\t\t\t\t\t\t\tresult.failureReason = \"Composite File is not a valid PE file.\";\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tReadOnlyMemory<byte> compositeContent = compositeFile.Reader.GetEntireImage().GetContent().AsMemory();\n\t\t\t\t\t\t\t\t\tresult.compositeReadyToRunReader = new ReadyToRunReader(new ReadyToRunAssemblyResolver(assembly), compositeModuleName, compositeContent);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcatch (BadImageFormatException e)\n\t\t\t\t\t{\n\t\t\t\t\t\tresult.failureReason = e.Message;\n\t\t\t\t\t}\n\t\t\t\t\treadyToRunReaders.Add(file, result);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\tprivate class ReadyToRunAssemblyResolver : ILCompiler.Reflection.ReadyToRun.IAssemblyResolver\n\t\t{\n\t\t\tprivate LoadedAssembly loadedAssembly;\n\t\t\tprivate Decompiler.Metadata.IAssemblyResolver assemblyResolver;\n\n\t\t\tpublic ReadyToRunAssemblyResolver(LoadedAssembly loadedAssembly)\n\t\t\t{\n\t\t\t\tthis.loadedAssembly = loadedAssembly;\n\t\t\t\tassemblyResolver = loadedAssembly.GetAssemblyResolver();\n\t\t\t}\n\n\t\t\tpublic IAssemblyMetadata FindAssembly(MetadataReader metadataReader, AssemblyReferenceHandle assemblyReferenceHandle, string parentFile)\n\t\t\t{\n\t\t\t\treturn GetAssemblyMetadata(assemblyResolver.Resolve(new Decompiler.Metadata.AssemblyReference(metadataReader, assemblyReferenceHandle)));\n\t\t\t}\n\n\t\t\tpublic IAssemblyMetadata FindAssembly(string simpleName, string parentFile)\n\t\t\t{\n\t\t\t\treturn GetAssemblyMetadata(assemblyResolver.ResolveModule(loadedAssembly.GetMetadataFileOrNull(), simpleName));\n\t\t\t}\n\n\t\t\tprivate IAssemblyMetadata GetAssemblyMetadata(MetadataFile module)\n\t\t\t{\n\t\t\t\tif (module is not PEFile peFile || peFile.Reader == null)\n\t\t\t\t{\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn new IlSpyAssemblyMetadata(peFile);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tprivate class IlSpyAssemblyMetadata : StandaloneAssemblyMetadata\n\t\t{\n\t\t\tpublic PEFile Module { get; private set; }\n\n\t\t\tpublic IlSpyAssemblyMetadata(PEFile module) : base(module.Reader)\n\t\t\t{\n\t\t\t\tModule = module;\n\t\t\t}\n\t\t}\n\n\t\tprivate class ReadyToRunReaderCacheEntry\n\t\t{\n\t\t\tpublic ReadyToRunReader readyToRunReader;\n\t\t\tpublic ReadyToRunReader compositeReadyToRunReader;\n\t\t\tpublic string failureReason;\n\t\t\tpublic Dictionary<EntityHandle, ReadyToRunMethod[]> methodMap;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml",
    "content": "<UserControl x:Class=\"ICSharpCode.ILSpy.ReadyToRun.ReadyToRunOptionPage\"\n\txmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n\txmlns:properties=\"clr-namespace:ILSpy.ReadyToRun.Properties\"\n\txmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n\txmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" d:DesignHeight=\"500\" d:DesignWidth=\"500\" mc:Ignorable=\"d\"\n\txmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n\txmlns:readyToRun=\"clr-namespace:ICSharpCode.ILSpy.ReadyToRun\"\n\td:DataContext=\"{d:DesignInstance readyToRun:ReadyToRunOptionsViewModel}\">\n\t<Grid>\n\t\t<Grid.ColumnDefinitions>\n\t\t\t<ColumnDefinition />\n\t\t\t<ColumnDefinition />\n\t\t</Grid.ColumnDefinitions>\n\t\t<Grid.RowDefinitions>\n\t\t\t<RowDefinition Height=\"Auto\" />\n\t\t\t<RowDefinition Height=\"Auto\" />\n\t\t\t<RowDefinition Height=\"Auto\" />\n\t\t\t<RowDefinition Height=\"Auto\" />\n\t\t</Grid.RowDefinitions>\n\t\t<TextBlock Margin=\"3\" Text=\"{x:Static properties:Resources.DisassemblyFormat}\" />\n\t\t<ComboBox Grid.Row=\"0\" Grid.Column=\"1\" Margin=\"3\" ItemsSource=\"{Binding Options.DisassemblyFormats}\" SelectedItem=\"{Binding Options.DisassemblyFormat}\" />\n\t\t<TextBlock Grid.Row=\"1\" Grid.Column=\"0\"  Margin=\"3\" Text=\"{x:Static properties:Resources.ShowStackUnwindInfo}\"/>\n\t\t<CheckBox Grid.Row=\"1\" Grid.Column=\"1\" Margin=\"3\" IsChecked=\"{Binding Options.IsShowUnwindInfo}\" />\n\t\t<TextBlock Grid.Row=\"2\" Margin=\"3\" Text=\"{x:Static properties:Resources.ShowDebugInfo}\"/>\n\t\t<CheckBox Grid.Row=\"2\" Grid.Column=\"1\" Margin=\"3\" IsChecked=\"{Binding Options.IsShowDebugInfo}\" />\n\t\t<TextBlock Grid.Row=\"3\" Margin=\"3\" Text=\"{x:Static properties:Resources.ShowGCInfo}\"/>\n\t\t<CheckBox Grid.Row=\"3\" Grid.Column=\"1\" Margin=\"3\" IsChecked=\"{Binding Options.IsShowGCInfo}\" />\n\t</Grid>\n</UserControl>"
  },
  {
    "path": "ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Composition;\n\nusing ICSharpCode.ILSpy.Options;\nusing ICSharpCode.ILSpy.Util;\n\nusing TomsToolbox.Wpf;\nusing TomsToolbox.Wpf.Composition.AttributedModel;\n\nnamespace ICSharpCode.ILSpy.ReadyToRun\n{\n\t[DataTemplate(typeof(ReadyToRunOptionsViewModel))]\n\t[NonShared]\n\tpartial class ReadyToRunOptionPage\n\t{\n\t\tpublic ReadyToRunOptionPage()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\t}\n\n\t[ExportOptionPage(Order = 40)]\n\t[NonShared]\n\tclass ReadyToRunOptionsViewModel : ObservableObjectBase, IOptionPage\n\t{\n\t\tprivate ReadyToRunOptions options;\n\n\t\tpublic ReadyToRunOptions Options {\n\t\t\tget => options;\n\t\t\tset => SetProperty(ref options, value);\n\t\t}\n\n\t\tpublic string Title => global::ILSpy.ReadyToRun.Properties.Resources.ReadyToRun;\n\n\t\tpublic void Load(SettingsSnapshot snapshot)\n\t\t{\n\t\t\tOptions = snapshot.GetSettings<ReadyToRunOptions>();\n\t\t}\n\n\t\tpublic void LoadDefaults()\n\t\t{\n\t\t\tOptions.LoadFromXml(new(\"empty\"));\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy.ReadyToRun/ReadyToRunOptions.cs",
    "content": "// Copyright (c) 2018 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Xml.Linq;\n\nusing ICSharpCode.ILSpyX.Settings;\n\nusing TomsToolbox.Wpf;\n\nnamespace ICSharpCode.ILSpy.ReadyToRun\n{\n\tinternal partial class ReadyToRunOptions : ObservableObjectBase, ISettingsSection\n\t{\n\t\tprivate static readonly XNamespace ns = \"http://www.ilspy.net/ready-to-run\";\n\n\t\tinternal static string intel = \"Intel\";\n\t\tinternal static string gas = \"AT & T\";\n\t\tinternal static string[] disassemblyFormats = [intel, gas];\n\n\t\tpublic string[] DisassemblyFormats {\n\t\t\tget {\n\t\t\t\treturn disassemblyFormats;\n\t\t\t}\n\t\t}\n\n\t\tprivate bool isShowUnwindInfo;\n\t\tpublic bool IsShowUnwindInfo {\n\t\t\tget => isShowUnwindInfo;\n\t\t\tset => SetProperty(ref isShowUnwindInfo, value);\n\t\t}\n\n\t\tprivate bool isShowDebugInfo;\n\t\tpublic bool IsShowDebugInfo {\n\t\t\tget => isShowDebugInfo;\n\t\t\tset => SetProperty(ref isShowDebugInfo, value);\n\t\t}\n\n\t\tprivate bool isShowGCInfo;\n\t\tpublic bool IsShowGCInfo {\n\t\t\tget => isShowGCInfo;\n\t\t\tset => SetProperty(ref isShowGCInfo, value);\n\t\t}\n\n\t\tprivate string disassemblyFormat;\n\t\tpublic string DisassemblyFormat {\n\t\t\tget => disassemblyFormat;\n\t\t\tset => SetProperty(ref disassemblyFormat, value);\n\t\t}\n\n\t\tpublic XName SectionName { get; } = ns + \"ReadyToRunOptions\";\n\n\t\tpublic void LoadFromXml(XElement e)\n\t\t{\n\t\t\tXAttribute format = e.Attribute(\"DisassemblyFormat\");\n\t\t\tDisassemblyFormat = format == null ? intel : (string)format;\n\n\t\t\tXAttribute unwind = e.Attribute(\"IsShowUnwindInfo\");\n\t\t\tIsShowUnwindInfo = unwind != null && (bool)unwind;\n\n\t\t\tXAttribute debug = e.Attribute(\"IsShowDebugInfo\");\n\t\t\tIsShowDebugInfo = debug == null || (bool)debug;\n\n\t\t\tXAttribute showGc = e.Attribute(\"IsShowGCInfo\");\n\t\t\tIsShowGCInfo = showGc != null && (bool)showGc;\n\t\t}\n\n\t\tpublic XElement SaveToXml()\n\t\t{\n\t\t\tvar section = new XElement(SectionName);\n\n\t\t\tsection.SetAttributeValue(\"DisassemblyFormat\", disassemblyFormat);\n\t\t\tsection.SetAttributeValue(\"IsShowUnwindInfo\", isShowUnwindInfo);\n\t\t\tsection.SetAttributeValue(\"IsShowDebugInfo\", isShowDebugInfo);\n\t\t\tsection.SetAttributeValue(\"IsShowGCInfo\", isShowGCInfo);\n\n\t\t\treturn section;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.Tests/Analyzers/AnalyzerScopeTests.cs",
    "content": "// Copyright (c) 2024 Yuriy Zatuchnyy\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Linq;\nusing System.Threading.Tasks;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.CSharp.Resolver;\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX.Analyzers;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.ILSpy.Tests.Analyzers\n{\n\t[TestFixture]\n\tpublic class AnalyzerScopeTests\n\t{\n\t\tpublic class TestClass\n\t\t{\n\n\t\t}\n\n\t\t[Test]\n\t\tpublic void WhenPublicNestedClass_ThenNotInfiniteLoop()\n\t\t{\n\t\t\t// Given\n\t\t\tILSpyX.AssemblyList assemblyList = new ILSpyX.AssemblyList();\n\t\t\tvar file = new PEFile(this.GetType().Assembly.Location);\n\t\t\tvar td = file.Metadata.TypeDefinitions.First(td => td.GetFullTypeName(file.Metadata).Name == nameof(TestClass));\n\n\t\t\tDecompiler.Metadata.IAssemblyResolver assemblyResolver = new UniversalAssemblyResolver(null, false, null);\n\t\t\tICompilation compilation = new DecompilerTypeSystem(file, assemblyResolver);\n\t\t\tITypeResolveContext context = new CSharpResolver(compilation);\n\t\t\tvar module = ((IModuleReference)file).Resolve(context) as MetadataModule;\n\t\t\tIEntity entity = module.GetDefinition(td);\n\n\t\t\t// When \n\t\t\tvar task = Task.Run(() => {\n\t\t\t\tvar target = new AnalyzerScope(assemblyList, entity);\n\t\t\t});\n\n\t\t\tvar result = Task.WaitAny(new[] { task, Task.Delay(500) }); // 0.5 seconds\n\n\t\t\t// Then\n\t\t\tAssert.That(result == 0, \"The constructor should complete in less than 10 seconds\");\n\t\t}\n\n\t}\n}\n"
  },
  {
    "path": "ILSpy.Tests/Analyzers/ExportAnalyzerAttributeTests.cs",
    "content": "// Copyright (c) 2024 Andreas Weizel\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Linq;\n\nusing ICSharpCode.ILSpyX.Analyzers;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.ILSpy.Tests.Analyzers\n{\n\t[TestFixture]\n\tpublic class ExportAnalyzerAttributeTests\n\t{\n\t\t[Test]\n\t\tpublic void CollectAnalyzers()\n\t\t{\n\t\t\tvar analyzerNames = ExportAnalyzerAttribute.GetAnnotatedAnalyzers()\n\t\t\t\t.Select(analyzer => analyzer.AnalyzerType.Name)\n\t\t\t\t.ToArray();\n\t\t\tAssert.That(analyzerNames.Contains(\"AttributeAppliedToAnalyzer\"));\n\t\t\tAssert.That(analyzerNames.Contains(\"EventImplementedByAnalyzer\"));\n\t\t\tAssert.That(analyzerNames.Contains(\"MethodUsedByAnalyzer\"));\n\t\t\tAssert.That(analyzerNames.Contains(\"PropertyOverriddenByAnalyzer\"));\n\t\t\tAssert.That(analyzerNames.Contains(\"TypeInstantiatedByAnalyzer\"));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.Tests/Analyzers/MemberImplementsInterfaceAnalyzerTests.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection.Metadata;\nusing System.Reflection.PortableExecutable;\n\nusing ICSharpCode.Decompiler.Metadata;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.Decompiler.TypeSystem.Implementation;\nusing ICSharpCode.ILSpyX.Analyzers;\nusing ICSharpCode.ILSpyX.Analyzers.Builtin;\n\nusing NSubstitute;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.ILSpy.Tests.Analyzers\n{\n\t[TestFixture, Parallelizable(ParallelScope.All)]\n\tpublic class MemberImplementsInterfaceAnalyzerTests\n\t{\n\t\tstatic readonly SymbolKind[] ValidSymbolKinds = { SymbolKind.Event, SymbolKind.Indexer, SymbolKind.Method, SymbolKind.Property };\n\t\tstatic readonly SymbolKind[] InvalidSymbolKinds =\n\t\t\tEnum.GetValues(typeof(SymbolKind)).Cast<SymbolKind>().Except(ValidSymbolKinds).ToArray();\n\n\t\tstatic readonly TypeKind[] ValidTypeKinds = { TypeKind.Class, TypeKind.Struct };\n\t\tstatic readonly TypeKind[] InvalidTypeKinds = Enum.GetValues(typeof(TypeKind)).Cast<TypeKind>().Except(ValidTypeKinds).ToArray();\n\n\t\tprivate ICompilation testAssembly;\n\n\t\t[OneTimeSetUp]\n\t\tpublic void Setup()\n\t\t{\n\t\t\tstring fileName = GetType().Assembly.Location;\n\n\t\t\tusing (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))\n\t\t\t{\n\t\t\t\tvar module = new PEFile(fileName, stream, PEStreamOptions.PrefetchEntireImage, MetadataReaderOptions.None);\n\n\t\t\t\ttestAssembly = new SimpleCompilation(module.WithOptions(TypeSystemOptions.Default), MinimalCorlib.Instance);\n\t\t\t}\n\t\t}\n\n\t\t[Test]\n\t\tpublic void VerifyDoesNotShowForNoSymbol()\n\t\t{\n\t\t\t// Arrange\n\t\t\tvar analyzer = new MemberImplementsInterfaceAnalyzer();\n\n\t\t\t// Act\n\t\t\tvar shouldShow = analyzer.Show(symbol: null);\n\n\t\t\t// Assert\n\t\t\tAssert.That(!shouldShow, $\"The analyzer will be unexpectedly shown for no symbol\");\n\t\t}\n\n\t\t[Test]\n\t\t[TestCaseSource(nameof(InvalidSymbolKinds))]\n\t\tpublic void VerifyDoesNotShowForNonMembers(SymbolKind symbolKind)\n\t\t{\n\t\t\t// Arrange\n\t\t\tvar symbolMock = Substitute.For<ISymbol>();\n\t\t\tsymbolMock.SymbolKind.Returns(symbolKind);\n\t\t\tvar analyzer = new MemberImplementsInterfaceAnalyzer();\n\n\t\t\t// Act\n\t\t\tvar shouldShow = analyzer.Show(symbolMock);\n\n\t\t\t// Assert\n\t\t\tAssert.That(!shouldShow, $\"The analyzer will be unexpectedly shown for symbol '{symbolKind}'\");\n\t\t}\n\n\t\t[Test]\n\t\t[TestCaseSource(nameof(ValidSymbolKinds))]\n\t\tpublic void VerifyDoesNotShowForStaticMembers(SymbolKind symbolKind)\n\t\t{\n\t\t\t// Arrange\n\t\t\tvar memberMock = SetupMemberMock(symbolKind, TypeKind.Unknown, isStatic: true);\n\t\t\tvar analyzer = new MemberImplementsInterfaceAnalyzer();\n\n\t\t\t// Act\n\t\t\tvar shouldShow = analyzer.Show(memberMock);\n\n\t\t\t// Assert\n\t\t\tAssert.That(!shouldShow, $\"The analyzer will be unexpectedly shown for static symbol '{symbolKind}'\");\n\t\t}\n\n\t\t[Test]\n\t\t[Pairwise]\n\t\tpublic void VerifyDoesNotShowForUnsupportedTypes(\n\t\t\t[ValueSource(nameof(ValidSymbolKinds))] SymbolKind symbolKind,\n\t\t\t[ValueSource(nameof(InvalidTypeKinds))] TypeKind typeKind)\n\t\t{\n\t\t\t// Arrange\n\t\t\tvar memberMock = SetupMemberMock(symbolKind, typeKind, isStatic: true);\n\t\t\tvar analyzer = new MemberImplementsInterfaceAnalyzer();\n\n\t\t\t// Act\n\t\t\tvar shouldShow = analyzer.Show(memberMock);\n\n\t\t\t// Assert\n\t\t\tAssert.That(!shouldShow, $\"The analyzer will be unexpectedly shown for symbol '{symbolKind}' and '{typeKind}'\");\n\t\t}\n\n\t\t[Test]\n\t\t[Pairwise]\n\t\tpublic void VerifyShowsForSupportedTypes(\n\t\t\t[ValueSource(nameof(ValidSymbolKinds))] SymbolKind symbolKind,\n\t\t\t[ValueSource(nameof(ValidTypeKinds))] TypeKind typeKind)\n\t\t{\n\t\t\t// Arrange\n\t\t\tvar memberMock = SetupMemberMock(symbolKind, typeKind, isStatic: false);\n\t\t\tvar analyzer = new MemberImplementsInterfaceAnalyzer();\n\n\t\t\t// Act\n\t\t\tvar shouldShow = analyzer.Show(memberMock);\n\n\t\t\t// Assert\n\t\t\tAssert.That(shouldShow, $\"The analyzer will not be shown for symbol '{symbolKind}' and '{typeKind}'\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void VerifyReturnsOnlyInterfaceMembers()\n\t\t{\n\t\t\t// Arrange\n\t\t\tvar symbol = SetupSymbolForAnalysis(typeof(TestClass), nameof(TestClass.TestMethod));\n\t\t\tvar analyzer = new MemberImplementsInterfaceAnalyzer();\n\n\t\t\t// Act\n\t\t\tvar results = analyzer.Analyze(symbol, new AnalyzerContext() { AssemblyList = new ILSpyX.AssemblyList(), Language = new CSharpLanguage() });\n\n\t\t\t// Assert\n\t\t\tAssert.That(results, Is.Not.Null);\n\t\t\tAssert.That(results.Count(), Is.EqualTo(1));\n\t\t\tvar result = results.FirstOrDefault() as IMethod;\n\t\t\tAssert.That(result, Is.Not.Null);\n\t\t\tAssert.That(result.DeclaringTypeDefinition, Is.Not.Null);\n\t\t\tAssert.That(result.DeclaringTypeDefinition.Kind, Is.EqualTo(TypeKind.Interface));\n\t\t\tAssert.That(result.DeclaringTypeDefinition.Name, Is.EqualTo(nameof(ITestInterface)));\n\t\t}\n\n\t\tprivate ISymbol SetupSymbolForAnalysis(Type type, string methodName)\n\t\t{\n\t\t\tvar typeDefinition = testAssembly.FindType(type).GetDefinition();\n\t\t\treturn typeDefinition.Methods.First(m => m.Name == methodName);\n\t\t}\n\n\t\tprivate static IMember SetupMemberMock(SymbolKind symbolKind, TypeKind typeKind, bool isStatic)\n\t\t{\n\t\t\tvar memberMock = Substitute.For<IMember>();\n\t\t\tmemberMock.SymbolKind.Returns(symbolKind);\n\t\t\tmemberMock.DeclaringTypeDefinition.Kind.Returns(typeKind);\n\t\t\tmemberMock.IsStatic.Returns(isStatic);\n\t\t\treturn memberMock;\n\t\t}\n\n\t\tprivate interface ITestInterface\n\t\t{\n\t\t\tvoid TestMethod();\n\t\t}\n\n\t\tprivate class BaseClass\n\t\t{\n\t\t\tpublic virtual void TestMethod() => throw new NotImplementedException();\n\t\t}\n\n\t\tprivate class TestClass : BaseClass, ITestInterface\n\t\t{\n\t\t\tpublic override void TestMethod() => throw new NotImplementedException();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.Tests/Analyzers/MethodUsesAnalyzerTests.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.Analyzers;\nusing ICSharpCode.ILSpyX.Analyzers.Builtin;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.ILSpy.Tests.Analyzers\n{\n\t[TestFixture, Parallelizable(ParallelScope.All)]\n\tpublic class MethodUsesAnalyzerTests\n\t{\n\t\tAssemblyList assemblyList;\n\t\tCSharpLanguage language;\n\t\tLoadedAssembly testAssembly;\n\t\tICompilation testAssemblyTypeSystem;\n\t\tITypeDefinition typeDefinition;\n\n\t\t[OneTimeSetUp]\n\t\tpublic void Setup()\n\t\t{\n\t\t\tassemblyList = new AssemblyList();\n\t\t\ttestAssembly = assemblyList.OpenAssembly(typeof(MethodUsesAnalyzerTests).Assembly.Location);\n\t\t\tassemblyList.OpenAssembly(typeof(void).Assembly.Location);\n\t\t\ttestAssemblyTypeSystem = testAssembly.GetTypeSystemOrNull();\n\t\t\tlanguage = new CSharpLanguage();\n\t\t\ttypeDefinition = testAssemblyTypeSystem.FindType(typeof(TestCases.Main.MainAssembly)).GetDefinition();\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MainAssemblyUsesSystemStringEmpty()\n\t\t{\n\t\t\tvar context = new AnalyzerContext { AssemblyList = assemblyList, Language = language };\n\t\t\tIMethod symbol = typeDefinition.Methods.First(m => m.Name == \"UsesSystemStringEmpty\");\n\n\t\t\tvar results = new MethodUsesAnalyzer().Analyze(symbol, context).ToList();\n\n\t\t\tAssert.That(results.Count == 1);\n\t\t\tvar field = results.Single() as IField;\n\t\t\tAssert.That(field, Is.Not.Null);\n\t\t\tAssert.That(!field.MetadataToken.IsNil);\n\t\t\tAssert.That(\"System.String.Empty\", Is.EqualTo(field.FullName));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.Tests/Analyzers/TestCases/MainAssembly.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace ICSharpCode.ILSpy.Tests.Analyzers.TestCases.Main\n{\n\tclass MainAssembly\n\t{\n\t\tpublic string UsesSystemStringEmpty()\n\t\t{\n\t\t\treturn string.Empty;\n\t\t}\n\n\t\tpublic int UsesInt32()\n\t\t{\n\t\t\treturn int.Parse(\"1234\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.Tests/Analyzers/TypeUsedByAnalyzerTests.cs",
    "content": "// Copyright (c) 2020 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System.Linq;\n\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpyX;\nusing ICSharpCode.ILSpyX.Analyzers;\nusing ICSharpCode.ILSpyX.Analyzers.Builtin;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.ILSpy.Tests.Analyzers\n{\n\t[TestFixture, Parallelizable(ParallelScope.All)]\n\tpublic class TypeUsedByAnalyzerTests\n\t{\n\t\tAssemblyList assemblyList;\n\t\tCSharpLanguage language;\n\t\tLoadedAssembly testAssembly;\n\t\tICompilation testAssemblyTypeSystem;\n\n\t\t[OneTimeSetUp]\n\t\tpublic void Setup()\n\t\t{\n\t\t\tassemblyList = new AssemblyList();\n\t\t\ttestAssembly = assemblyList.OpenAssembly(typeof(MethodUsesAnalyzerTests).Assembly.Location);\n\t\t\ttestAssemblyTypeSystem = new DecompilerTypeSystem(testAssembly.GetMetadataFileOrNull(), testAssembly.GetAssemblyResolver());\n\t\t\tlanguage = new CSharpLanguage();\n\t\t}\n\n\t\t[Test]\n\t\tpublic void SystemInt32UsedByMainAssembly()\n\t\t{\n\t\t\tvar context = new AnalyzerContext { AssemblyList = assemblyList, Language = language };\n\t\t\tvar symbol = testAssemblyTypeSystem.FindType(typeof(int)).GetDefinition();\n\n\t\t\tvar results = new TypeUsedByAnalyzer().Analyze(symbol, context).ToList();\n\n\t\t\tAssert.That(results, Is.Not.Empty);\n\t\t\tvar method = results.OfType<IMethod>().SingleOrDefault(m => m.FullName == \"ICSharpCode.ILSpy.Tests.Analyzers.TestCases.Main.MainAssembly.UsesInt32\");\n\t\t\tAssert.That(method, Is.Not.Null);\n\t\t\tAssert.That(!method.MetadataToken.IsNil);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.Tests/CommandLineArgumentsTests.cs",
    "content": "using System;\n\nusing AwesomeAssertions;\n\nusing ICSharpCode.ILSpy.AppEnv;\n\nusing NUnit.Framework;\n\nnamespace ICSharpCode.ILSpy.Tests\n{\n\t[TestFixture]\n\tpublic class CommandLineArgumentsTests\n\t{\n\t\t[Test]\n\t\tpublic void VerifyEmptyArgumentsArray()\n\t\t{\n\t\t\tvar cmdLineArgs = CommandLineArguments.Create(new string[] { });\n\n\t\t\tcmdLineArgs.AssembliesToLoad.Should().BeEmpty();\n\t\t\tcmdLineArgs.SingleInstance.Should().BeNull();\n\t\t\tcmdLineArgs.NavigateTo.Should().BeNull();\n\t\t\tcmdLineArgs.Search.Should().BeNull();\n\t\t\tcmdLineArgs.Language.Should().BeNull();\n\t\t\tcmdLineArgs.NoActivate.Should().BeFalse();\n\t\t\tcmdLineArgs.ConfigFile.Should().BeNull();\n\t\t}\n\n\t\t[Test]\n\t\tpublic void VerifyHelpOption()\n\t\t{\n\t\t\tvar cmdLineArgs = CommandLineArguments.Create(new string[] { \"--help\" });\n\t\t\tcmdLineArgs.ArgumentsParser.IsShowingInformation.Should().BeTrue();\n\t\t}\n\n\t\t[Test]\n\t\tpublic void VerifyForceNewInstanceOption()\n\t\t{\n\t\t\tvar cmdLineArgs = CommandLineArguments.Create(new string[] { \"--newinstance\" });\n\t\t\tcmdLineArgs.SingleInstance.Should().NotBeNull();\n\t\t\tcmdLineArgs.SingleInstance.Value.Should().BeFalse();\n\t\t}\n\n\t\t[Test]\n\t\tpublic void VerifyNavigateToOption()\n\t\t{\n\t\t\tconst string navigateTo = \"MyNamespace.MyClass\";\n\t\t\tvar cmdLineArgs = CommandLineArguments.Create(new string[] { \"--navigateto\", navigateTo });\n\t\t\tcmdLineArgs.NavigateTo.Should().Be(navigateTo);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void VerifyNavigateToOption_NoneTest_Matching_VSAddin()\n\t\t{\n\t\t\tvar cmdLineArgs = CommandLineArguments.Create(new string[] { \"--navigateto:none\" });\n\t\t\tcmdLineArgs.NavigateTo.Should().Be(\"none\");\n\t\t}\n\n\t\t[Test]\n\t\tpublic void VerifyCaseSensitivityOfOptionsDoesntThrow()\n\t\t{\n\t\t\tvar cmdLineArgs = CommandLineArguments.Create(new string[] { \"--navigateTo:none\" });\n\n\t\t\tcmdLineArgs.ArgumentsParser.RemainingArguments.Count.Should().Be(1);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void VerifySearchOption()\n\t\t{\n\t\t\tconst string searchWord = \"TestContainers\";\n\t\t\tvar cmdLineArgs = CommandLineArguments.Create(new string[] { \"--search\", searchWord });\n\t\t\tcmdLineArgs.Search.Should().Be(searchWord);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void VerifyLanguageOption()\n\t\t{\n\t\t\tconst string language = \"csharp\";\n\t\t\tvar cmdLineArgs = CommandLineArguments.Create(new string[] { \"--language\", language });\n\t\t\tcmdLineArgs.Language.Should().Be(language);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void VerifyConfigOption()\n\t\t{\n\t\t\tconst string configFile = \"myilspyoptions.xml\";\n\t\t\tvar cmdLineArgs = CommandLineArguments.Create(new string[] { \"--config\", configFile });\n\t\t\tcmdLineArgs.ConfigFile.Should().Be(configFile);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void VerifyNoActivateOption()\n\t\t{\n\t\t\tvar cmdLineArgs = CommandLineArguments.Create(new string[] { \"--noactivate\" });\n\t\t\tcmdLineArgs.NoActivate.Should().BeTrue();\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MultipleAssembliesAsArguments()\n\t\t{\n\t\t\tvar cmdLineArgs = CommandLineArguments.Create(new string[] { \"assembly1\", \"assembly2\", \"assembly3\" });\n\t\t\tcmdLineArgs.AssembliesToLoad.Count.Should().Be(3);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void PassAtFileArguments()\n\t\t{\n\t\t\tstring filepath = System.IO.Path.GetTempFileName();\n\n\t\t\tSystem.IO.File.WriteAllText(filepath, \"assembly1\\r\\nassembly2\\r\\nassembly3\\r\\n--newinstance\\r\\n--noactivate\");\n\n\t\t\tvar cmdLineArgs = CommandLineArguments.Create(new string[] { $\"@{filepath}\" });\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tSystem.IO.File.Delete(filepath);\n\t\t\t}\n\t\t\tcatch (Exception)\n\t\t\t{\n\t\t\t}\n\n\t\t\tcmdLineArgs.SingleInstance.Should().NotBeNull();\n\t\t\tcmdLineArgs.SingleInstance.Value.Should().BeFalse();\n\t\t\tcmdLineArgs.NoActivate.Should().BeTrue();\n\t\t\tcmdLineArgs.AssembliesToLoad.Count.Should().Be(3);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ILSpy.Tests/ILSpy.Tests.csproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <IsWindowsX64 Condition=\"$([MSBuild]::IsOsPlatform('Windows')) And $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) == X64\">true</IsWindowsX64>\r\n    <IsWindowsARM64 Condition=\"$([MSBuild]::IsOsPlatform('Windows')) And $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) == ARM64\">true</IsWindowsARM64>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup>\r\n    <TargetFramework>net10.0-windows</TargetFramework>\r\n    <IsPackable>false</IsPackable>\r\n    <RuntimeIdentifier Condition=\"$(IsWindowsX64) == true\">win-x64</RuntimeIdentifier>\r\n    <RuntimeIdentifier Condition=\"$(IsWindowsARM64) == true\">win-arm64</RuntimeIdentifier>\r\n    <OutputType>Exe</OutputType>\r\n\r\n    <AllowUnsafeBlocks>True</AllowUnsafeBlocks>\r\n\r\n    <NoWarn>$(NoWarn);1701;1702;1705,67,169,1058,728,1720,649,168,251</NoWarn>\r\n\r\n    <EnableDefaultItems>false</EnableDefaultItems>\r\n\r\n    <RootNamespace>ICSharpCode.ILSpy.Tests</RootNamespace>\r\n    <AutoGenerateBindingRedirects>True</AutoGenerateBindingRedirects>\r\n\r\n    <SignAssembly>True</SignAssembly>\r\n    <AssemblyOriginatorKeyFile>..\\ICSharpCode.Decompiler\\ICSharpCode.Decompiler.snk</AssemblyOriginatorKeyFile>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Debug'\">\r\n    <DebugType>full</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\r\n    <DebugType>pdbonly</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|AnyCPU'\">\r\n    <DefineConstants>TRACE;DEBUG;NET46;ROSLYN;CS60;CS70</DefineConstants>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <Compile Include=\"Analyzers\\ExportAnalyzerAttributeTests.cs\" />\r\n    <Compile Include=\"Analyzers\\AnalyzerScopeTests.cs\" />\r\n    <Compile Include=\"Analyzers\\MemberImplementsInterfaceAnalyzerTests.cs\" />\r\n    <Compile Include=\"Analyzers\\MethodUsesAnalyzerTests.cs\" />\r\n    <Compile Include=\"Analyzers\\TestCases\\MainAssembly.cs\" />\r\n    <Compile Include=\"Analyzers\\TypeUsedByAnalyzerTests.cs\" />\r\n    <Compile Include=\"CommandLineArgumentsTests.cs\" />\r\n    <Compile Include=\"ResourceReaderWriterTests.cs\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <EmbeddedResource Include=\"Icon.ico\" />\r\n    <EmbeddedResource Include=\"Test.resources\" />\r\n    <EmbeddedResource Include=\"IconContainer.resx\">\r\n      <Generator>ResXCodeGenerator</Generator>\r\n    </EmbeddedResource>\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <EmbeddedResource Include=\"BitmapContainer.resources\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <PackageReference Include=\"DiffLib\" />\r\n    <PackageReference Include=\"NSubstitute\" />\r\n    <PackageReference Include=\"NSubstitute.Analyzers.CSharp\">\r\n      <PrivateAssets>all</PrivateAssets>\r\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\r\n    </PackageReference>\r\n    <PackageReference Include=\"System.Collections.Immutable\" />\r\n    <PackageReference Include=\"System.Reflection.Metadata\" />\r\n    <PackageReference Include=\"Microsoft.CodeAnalysis.CSharp\" />\r\n    <PackageReference Include=\"Microsoft.CodeAnalysis.VisualBasic\" />\r\n    <PackageReference Include=\"NUnit3TestAdapter\" />\r\n    <PackageReference Include=\"coverlet.MTP\" />\r\n    <PackageReference Include=\"NUnit\" />\r\n    <PackageReference Include=\"AwesomeAssertions\" />\r\n    <PackageReference Include=\"Microsoft.Testing.Extensions.TrxReport\" />\r\n    <PackageReference Include=\"Microsoft.Testing.Extensions.VSTestBridge\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\ICSharpCode.Decompiler\\ICSharpCode.Decompiler.csproj\" />\r\n    <ProjectReference Include=\"..\\ILSpy\\ILSpy.csproj\" />\r\n  </ItemGroup>\r\n\r\n</Project>"
  },
  {
    "path": "ILSpy.Tests/IconContainer.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <assembly alias=\"System.Windows.Forms\" name=\"System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\" />\n  <data name=\"Icon\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n</root>"
  },
  {
    "path": "ILSpy.Tests/ResourceReaderWriterTests.cs",
    "content": "// Copyright (c) 2023 Siegfried Pammer\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files (the \"Software\"), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify, merge,\n// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\n// to whom the Software is furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all copies or\n// substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\nusing System;\nusing System.Drawing;\nusing System.Globalization;\nusing System.IO;\nusing System.Linq;\nusing System.Xml.Linq;\nusing System.Xml.XPath;\n\nusing ICSharpCode.Decompiler.Util;\n\nusing NUnit.Framework;\nusing NUnit.Framework.Internal;\n\nusing TomsToolbox.Essentials;\n\nnamespace ICSharpCode.ILSpy.Tests\n{\n\t[TestFixture]\n\tpublic class ResourceReaderWriterTests\n\t{\n\t\tconst string winFormsAssemblyName = \", System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\";\n\t\tconst string msCorLibAssemblyName = \", mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\";\n\t\tconst string drawingAssemblyName = \", System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\";\n\n\t\t[Serializable]\n\t\tpublic class SerializableClass\n\t\t{\n\t\t\tpublic string Name { get; set; }\n\t\t\tpublic int Age { get; set; }\n\t\t}\n\n\t\tstatic readonly object[][] testWriteCases = {\n\t\t\tnew object[] { \"Decimal\", 1.0m, \"1.0\", \"System.Decimal\" + msCorLibAssemblyName },\n\t\t\tnew object[] { \"TimeSpan\", TimeSpan.FromSeconds(42), \"00:00:42\", \"System.TimeSpan\" + msCorLibAssemblyName },\n\t\t\tnew object[] { \"DateTime\", DateTime.Parse(\"06/18/2023 21:36:30\", CultureInfo.InvariantCulture), \"06/18/2023 21:36:30\", \"System.DateTime\" + msCorLibAssemblyName },\n\t\t};\n\n\t\tstatic readonly object[][] testReadCases = {\n\t\t\tnew object[] { \"Decimal\", 1.0m },\n\t\t\tnew object[] { \"TimeSpan\", TimeSpan.FromSeconds(42) },\n\t\t\tnew object[] { \"DateTime\", DateTime.Parse(\"06/18/2023 21:36:30\", CultureInfo.InvariantCulture) },\n\t\t};\n\n\t\tstatic Stream GetResource(string fileName)\n\t\t{\n\t\t\treturn typeof(ResourceReaderWriterTests).Assembly.GetManifestResourceStream(typeof(ResourceReaderWriterTests).Namespace + \".\" + fileName);\n\t\t}\n\n\t\tstatic MemoryStream ProduceResourcesTestFile<T>(string name, T value)\n\t\t{\n\t\t\tvar ms = new MemoryStream();\n\t\t\tvar writer = new System.Resources.ResourceWriter(ms);\n\t\t\twriter.AddResource(name, value);\n\t\t\twriter.Generate();\n\t\t\tms.Position = 0;\n\t\t\treturn ms;\n\t\t}\n\n\t\tstatic XElement ProduceResXTest<T>(string name, T value)\n\t\t{\n\t\t\tusing var ms = new MemoryStream();\n\t\t\tvar writer = new Decompiler.Util.ResXResourceWriter(ms);\n\t\t\twriter.AddResource(name, value);\n\t\t\twriter.Generate();\n\t\t\tms.Position = 0;\n\t\t\tvar doc = XDocument.Load(ms);\n\t\t\treturn doc.XPathSelectElement(\".//data\");\n\t\t}\n\n\t\t[TestCase(\"Null\", null)]\n\t\t[TestCase(\"String\", \"Hello World!\")]\n\t\t[TestCase(\"Char\", 'A')]\n\t\t[TestCase(\"Bool\", true)]\n\t\t[TestCase(\"Bool\", false)]\n\t\t[TestCase(\"Byte\", (byte)1)]\n\t\t[TestCase(\"SByte\", (sbyte)-1)]\n\t\t[TestCase(\"Int16\", (short)1)]\n\t\t[TestCase(\"UInt16\", (ushort)1)]\n\t\t[TestCase(\"Int32\", 1)]\n\t\t[TestCase(\"UInt32\", (uint)1)]\n\t\t[TestCase(\"Int64\", (long)1)]\n\t\t[TestCase(\"UInt64\", (ulong)1)]\n\t\t[TestCase(\"Single\", 1.0f)]\n\t\t[TestCase(\"Double\", 1.0d)]\n\t\t[TestCase(\"Bytes\", new byte[] { 42, 43, 44 })]\n\t\t[TestCaseSource(nameof(testReadCases))]\n\t\tpublic void Read(string name, object value)\n\t\t{\n\t\t\tusing var testFile = ProduceResourcesTestFile(name, value);\n\t\t\tusing var reader = new ResourcesFile(testFile);\n\t\t\tvar items = reader.ToArray();\n\t\t\tAssert.That(items.Length, Is.EqualTo(1));\n\t\t\tAssert.That(items[0].Key, Is.EqualTo(name));\n\t\t\tAssert.That(items[0].Value, Is.EqualTo(value));\n\t\t}\n\n\t\t[TestCase(\"Null\", null, null, \"System.Resources.ResXNullRef\" + winFormsAssemblyName)]\n\t\t[TestCase(\"String\", \"Hello World!\", \"Hello World!\", null)]\n\t\t[TestCase(\"Bool\", true, \"True\", \"System.Boolean\" + msCorLibAssemblyName)]\n\t\t[TestCase(\"Bool\", false, \"False\", \"System.Boolean\" + msCorLibAssemblyName)]\n\t\t[TestCase(\"Char\", 'A', \"A\", \"System.Char\" + msCorLibAssemblyName)]\n\t\t[TestCase(\"Byte\", (byte)1, \"1\", \"System.Byte\" + msCorLibAssemblyName)]\n\t\t[TestCase(\"SByte\", (sbyte)-1, \"-1\", \"System.SByte\" + msCorLibAssemblyName)]\n\t\t[TestCase(\"Int16\", (short)1, \"1\", \"System.Int16\" + msCorLibAssemblyName)]\n\t\t[TestCase(\"UInt16\", (ushort)1, \"1\", \"System.UInt16\" + msCorLibAssemblyName)]\n\t\t[TestCase(\"Int32\", 1, \"1\", \"System.Int32\" + msCorLibAssemblyName)]\n\t\t[TestCase(\"UInt32\", (uint)1, \"1\", \"System.UInt32\" + msCorLibAssemblyName)]\n\t\t[TestCase(\"Int64\", (long)1, \"1\", \"System.Int64\" + msCorLibAssemblyName)]\n\t\t[TestCase(\"UInt64\", (ulong)1, \"1\", \"System.UInt64\" + msCorLibAssemblyName)]\n\t\t[TestCase(\"Single\", 1.0f, \"1\", \"System.Single\" + msCorLibAssemblyName)]\n\t\t[TestCase(\"Double\", 1.0d, \"1\", \"System.Double\" + msCorLibAssemblyName)]\n\t\t[TestCaseSource(nameof(testWriteCases))]\n\t\tpublic void Write(string name, object value, string serializedValue, string typeName)\n\t\t{\n\t\t\tvar element = ProduceResXTest(name, value);\n\t\t\tAssert.That(element.Attribute(\"name\")?.Value, Is.EqualTo(name));\n\t\t\tif (typeName != null)\n\t\t\t{\n\t\t\t\tAssert.That(element.Attribute(\"type\")?.Value, Is.EqualTo(typeName));\n\t\t\t}\n\t\t\tvar v = element.Element(\"value\");\n\t\t\tAssert.That(v, Is.Not.Null);\n\t\t\tAssert.That(v.IsEmpty ? serializedValue == null : v.Value == serializedValue);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ResXSerializableClassIsRejected()\n\t\t{\n\t\t\tAssert.Throws<NotSupportedException>(\n\t\t\t\t() => ProduceResXTest(\"Serial\", new SerializableClass { Name = \"Hugo\", Age = 42 })\n\t\t\t);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void BitmapIsResourceSerializedObject()\n\t\t{\n\t\t\tStream stream = typeof(ResourceReaderWriterTests).Assembly\n\t\t\t\t.GetManifestResourceStream(typeof(ResourceReaderWriterTests).Namespace + \".Test.resources\");\n\t\t\tusing var reader = new ResourcesFile(stream);\n\t\t\tvar items = reader.ToArray();\n\t\t\tAssert.That(items.Length, Is.EqualTo(3));\n\t\t\tvar item = items.FirstOrDefault(i => i.Key == \"Bitmap\");\n\t\t\tAssert.That(item.Key, Is.Not.Null);\n\t\t\tAssert.That(item.Value, Is.InstanceOf<ResourceSerializedObject>());\n\t\t\tvar rso = (ResourceSerializedObject)item.Value;\n\t\t\tAssert.That(rso.TypeName, Is.Null);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void ByteArrayIsSupported()\n\t\t{\n\t\t\tStream stream = typeof(ResourceReaderWriterTests).Assembly\n\t\t\t\t.GetManifestResourceStream(typeof(ResourceReaderWriterTests).Namespace + \".Test.resources\");\n\t\t\tusing var reader = new ResourcesFile(stream);\n\t\t\tvar items = reader.ToArray();\n\t\t\tAssert.That(items.Length, Is.EqualTo(3));\n\t\t\tvar item = items.FirstOrDefault(i => i.Key == \"Byte[]\");\n\t\t\tAssert.That(item.Key, Is.Not.Null);\n\t\t\tAssert.That(item.Value, Is.InstanceOf<byte[]>());\n\t\t\tbyte[] array = (byte[])item.Value;\n\t\t\tAssert.That(array.Length, Is.EqualTo(3));\n\t\t\tAssert.That(array[0], Is.EqualTo(42));\n\t\t\tAssert.That(array[1], Is.EqualTo(43));\n\t\t\tAssert.That(array[2], Is.EqualTo(44));\n\t\t}\n\n\t\t[Test]\n\t\tpublic void MemoryStreamIsSupported()\n\t\t{\n\t\t\tStream stream = typeof(ResourceReaderWriterTests).Assembly\n\t\t\t\t.GetManifestResourceStream(typeof(ResourceReaderWriterTests).Namespace + \".Test.resources\");\n\t\t\tusing var reader = new ResourcesFile(stream);\n\t\t\tvar items = reader.ToArray();\n\t\t\tAssert.That(items.Length, Is.EqualTo(3));\n\t\t\tvar item = items.FirstOrDefault(i => i.Key == \"MemoryStream\");\n\t\t\tAssert.That(item.Key, Is.Not.Null);\n\t\t\tAssert.That(item.Value, Is.InstanceOf<MemoryStream>());\n\t\t}\n\n\t\t[Test]\n\t\tpublic void IconDataCanBeDeserializedFromResX()\n\t\t{\n\t\t\t// Uses new serialization format\n\t\t\tvar resourcesStream = GetResource(\"IconContainer.resources\");\n\t\t\tvar reader = new ResourcesFile(resourcesStream);\n\t\t\tvar item = reader.Single();\n\t\t\tAssert.That(item.Key, Is.EqualTo(\"Icon\"));\n\t\t\tAssert.That(item.Value, Is.InstanceOf<ResourceSerializedObject>());\n\t\t\tvar rso = (ResourceSerializedObject)item.Value;\n\t\t\tvar xml = ProduceResXTest(\"Icon\", rso);\n\t\t\tAssert.That(xml.GetAttribute(\"name\"), Is.EqualTo(\"Icon\"));\n\t\t\tAssert.That(xml.GetAttribute(\"type\"), Is.EqualTo(\"System.Drawing.Icon\" + drawingAssemblyName));\n\t\t\tAssert.That(xml.GetAttribute(\"mimetype\"), Is.EqualTo(\"application/x-microsoft.net.object.bytearray.base64\"));\n\t\t\tvar base64Icon = xml.Element(\"value\").Value;\n\t\t\tusing var memory = new MemoryStream(Convert.FromBase64String(base64Icon));\n\t\t\tnew Icon(memory);\n\t\t}\n\n\t\t[Test]\n\t\tpublic void BitmapDataCanBeDeserializedFromResX()\n\t\t{\n\t\t\t// Uses old serialization format\n\t\t\tvar resourcesStream = GetResource(\"BitmapContainer.resources\");\n\t\t\tvar reader = new ResourcesFile(resourcesStream);\n\t\t\tvar item = reader.Single(x => x.Key == \"Image1\");\n\t\t\tAssert.That(item.Value, Is.InstanceOf<ResourceSerializedObject>());\n\t\t\tvar rso = (ResourceSerializedObject)item.Value;\n\t\t\tvar xml = ProduceResXTest(\"Image1\", rso);\n\t\t\tAssert.That(xml.GetAttribute(\"name\"), Is.EqualTo(\"Image1\"));\n\t\t\tAssert.That(xml.GetAttribute(\"type\"), Is.Null);\n\t\t\tAssert.That(xml.GetAttribute(\"mimetype\"), Is.EqualTo(\"application/x-microsoft.net.object.binary.base64\"));\n\t\t}\n\t}\n}"
  },
  {
    "path": "ILSpy.VSExtensions.sln",
    "content": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio Version 17\r\nVisualStudioVersion = 17.7.33808.371\r\nMinimumVisualStudioVersion = 10.0.40219.1\r\nProject(\"{D954291E-2A0B-460D-934E-DC6B0785DB48}\") = \"ILSpy.AddIn.Shared\", \"ILSpy.AddIn.Shared\\ILSpy.AddIn.Shared.shproj\", \"{ACAB1E5D-B3DF-4092-AA72-692F8341E520}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ILSpy.AddIn\", \"ILSpy.AddIn\\ILSpy.AddIn.csproj\", \"{A1B6B501-15D4-4237-A4C3-5EFCB71B0F74}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ILSpy.AddIn.VS2022\", \"ILSpy.AddIn.VS2022\\ILSpy.AddIn.VS2022.csproj\", \"{31E6E2B0-24B4-4D2C-AC17-3B44DAACC9D4}\"\r\nEndProject\r\nGlobal\r\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n\t\tDebug|Any CPU = Debug|Any CPU\r\n\t\tRelease|Any CPU = Release|Any CPU\r\n\tEndGlobalSection\r\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n\t\t{A1B6B501-15D4-4237-A4C3-5EFCB71B0F74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{A1B6B501-15D4-4237-A4C3-5EFCB71B0F74}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{A1B6B501-15D4-4237-A4C3-5EFCB71B0F74}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{A1B6B501-15D4-4237-A4C3-5EFCB71B0F74}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{31E6E2B0-24B4-4D2C-AC17-3B44DAACC9D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{31E6E2B0-24B4-4D2C-AC17-3B44DAACC9D4}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{31E6E2B0-24B4-4D2C-AC17-3B44DAACC9D4}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{31E6E2B0-24B4-4D2C-AC17-3B44DAACC9D4}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\tEndGlobalSection\r\n\tGlobalSection(SolutionProperties) = preSolution\r\n\t\tHideSolutionNode = FALSE\r\n\tEndGlobalSection\r\n\tGlobalSection(ExtensibilityGlobals) = postSolution\r\n\t\tSolutionGuid = {84D734FE-9E9C-4593-8927-6F45FE3E460A}\r\n\tEndGlobalSection\r\n\tGlobalSection(SharedMSBuildProjectFiles) = preSolution\r\n\t\tILSpy.AddIn.Shared\\ILSpy.AddIn.Shared.projitems*{31e6e2b0-24b4-4d2c-ac17-3b44daacc9d4}*SharedItemsImports = 5\r\n\t\tILSpy.AddIn.Shared\\ILSpy.AddIn.Shared.projitems*{a1b6b501-15d4-4237-a4c3-5efcb71b0f74}*SharedItemsImports = 5\r\n\t\tILSpy.AddIn.Shared\\ILSpy.AddIn.Shared.projitems*{acab1e5d-b3df-4092-aa72-692f8341e520}*SharedItemsImports = 13\r\n\tEndGlobalSection\r\nEndGlobal\r\n"
  },
  {
    "path": "ILSpy.Wpf.slnf",
    "content": "{\n\t\"solution\": {\n\t\t\"path\": \"ILSpy.sln\",\n\t\t\"projects\": [\n\t\t\t\"ICSharpCode.Decompiler.TestRunner\\\\ICSharpCode.Decompiler.TestRunner.csproj\",\n\t\t\t\"ICSharpCode.Decompiler.Tests\\\\ICSharpCode.Decompiler.Tests.csproj\",\n\t\t\t\"ICSharpCode.Decompiler\\\\ICSharpCode.Decompiler.csproj\",\n\t\t\t\"ICSharpCode.ILSpyX\\\\ICSharpCode.ILSpyX.csproj\",\n\t\t\t\"ILSpy.BamlDecompiler.Tests\\\\ILSpy.BamlDecompiler.Tests.csproj\",\n\t\t\t\"ILSpy.BamlDecompiler\\\\ILSpy.BamlDecompiler.csproj\",\n\t\t\t\"ICSharpCode.BamlDecompiler\\\\ICSharpCode.BamlDecompiler.csproj\",\n\t\t\t\"ILSpy.ReadyToRun\\\\ILSpy.ReadyToRun.csproj\",\n\t\t\t\"ILSpy.Tests\\\\ILSpy.Tests.csproj\",\n\t\t\t\"ILSpy\\\\ILSpy.csproj\",\n\t\t\t\"TestPlugin\\\\TestPlugin.csproj\"\n\t\t]\n\t}\n}"
  },
  {
    "path": "ILSpy.XPlat.slnf",
    "content": "{\n\t\"solution\": {\n\t\t\"path\": \"ILSpy.sln\",\n\t\t\"projects\": [\n\t\t\t\"ICSharpCode.ILSpyCmd\\\\ICSharpCode.ILSpyCmd.csproj\",\n\t\t\t\"ICSharpCode.Decompiler.PowerShell\\\\ICSharpCode.Decompiler.PowerShell.csproj\",\n\t\t\t\"ICSharpCode.Decompiler.TestRunner\\\\ICSharpCode.Decompiler.TestRunner.csproj\",\n\t\t\t\"ICSharpCode.Decompiler.Tests\\\\ICSharpCode.Decompiler.Tests.csproj\",\n\t\t\t\"ICSharpCode.Decompiler\\\\ICSharpCode.Decompiler.csproj\",\n\t\t\t\"ICSharpCode.ILSpyX\\\\ICSharpCode.ILSpyX.csproj\"\n\t\t]\n\t}\n}"
  },
  {
    "path": "ILSpy.sln",
    "content": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio Version 17\r\nVisualStudioVersion = 17.0.32014.148\r\nMinimumVisualStudioVersion = 15.0\r\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"doc\", \"doc\", \"{F45DB999-7E72-4000-B5AD-3A7B485A0896}\"\r\n\tProjectSection(SolutionItems) = preProject\r\n\t\tdoc\\Command Line.txt = doc\\Command Line.txt\r\n\t\tdoc\\ILAst.txt = doc\\ILAst.txt\r\n\t\tdoc\\IntPtr.txt = doc\\IntPtr.txt\r\n\tEndProjectSection\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ILSpy\", \"ILSpy\\ILSpy.csproj\", \"{1E85EFF9-E370-4683-83E4-8A3D063FF791}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ICSharpCode.Decompiler\", \"ICSharpCode.Decompiler\\ICSharpCode.Decompiler.csproj\", \"{984CC812-9470-4A13-AFF9-CC44068D666C}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ICSharpCode.Decompiler.Tests\", \"ICSharpCode.Decompiler.Tests\\ICSharpCode.Decompiler.Tests.csproj\", \"{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"TestPlugin\", \"TestPlugin\\TestPlugin.csproj\", \"{F32EBCC8-0E53-4421-867E-05B3D6E10C70}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ILSpy.BamlDecompiler\", \"ILSpy.BamlDecompiler\\ILSpy.BamlDecompiler.csproj\", \"{A6BAD2BA-76BA-461C-8B6D-418607591247}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ILSpy.BamlDecompiler.Tests\", \"ILSpy.BamlDecompiler.Tests\\ILSpy.BamlDecompiler.Tests.csproj\", \"{1169E6D1-1899-43D4-A500-07CE4235B388}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ILSpy.Tests\", \"ILSpy.Tests\\ILSpy.Tests.csproj\", \"{B51C6636-B8D1-4200-9869-08F2689DE6C2}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ILSpy.ReadyToRun\", \"ILSpy.ReadyToRun\\ILSpy.ReadyToRun.csproj\", \"{0313F581-C63B-43BB-AA9B-07615DABD8A3}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ICSharpCode.ILSpyCmd\", \"ICSharpCode.ILSpyCmd\\ICSharpCode.ILSpyCmd.csproj\", \"{743B439A-E7AD-4A0A-BAB6-222E1EA83C6D}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ICSharpCode.Decompiler.PowerShell\", \"ICSharpCode.Decompiler.PowerShell\\ICSharpCode.Decompiler.PowerShell.csproj\", \"{50060E0C-FA25-41F4-B72F-8490324EC9F0}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ICSharpCode.Decompiler.TestRunner\", \"ICSharpCode.Decompiler.TestRunner\\ICSharpCode.Decompiler.TestRunner.csproj\", \"{4FBB470F-69EB-4C8B-8961-8B4DF4EBB999}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ICSharpCode.ILSpyX\", \"ICSharpCode.ILSpyX\\ICSharpCode.ILSpyX.csproj\", \"{F8EFCF9D-B9A3-4BA0-A1B2-B026A71DAC22}\"\r\nEndProject\r\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ICSharpCode.BamlDecompiler\", \"ICSharpCode.BamlDecompiler\\ICSharpCode.BamlDecompiler.csproj\", \"{81A30182-3378-4952-8880-F44822390040}\"\r\nEndProject\r\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Solution Items\", \"Solution Items\", \"{D0858E90-DCD5-4FD9-AA53-7262FAB8BEDB}\"\r\n\tProjectSection(SolutionItems) = preProject\r\n\t\t.editorconfig = .editorconfig\r\n\t\tDirectory.Build.props = Directory.Build.props\r\n\t\tDirectory.Packages.props = Directory.Packages.props\r\n\t\tglobal.json = global.json\r\n\tEndProjectSection\r\nEndProject\r\nGlobal\r\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n\t\tDebug|Any CPU = Debug|Any CPU\r\n\t\tRelease|Any CPU = Release|Any CPU\r\n\tEndGlobalSection\r\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n\t\t{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{1E85EFF9-E370-4683-83E4-8A3D063FF791}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{984CC812-9470-4A13-AFF9-CC44068D666C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{984CC812-9470-4A13-AFF9-CC44068D666C}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{984CC812-9470-4A13-AFF9-CC44068D666C}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{984CC812-9470-4A13-AFF9-CC44068D666C}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{A6BAD2BA-76BA-461C-8B6D-418607591247}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{A6BAD2BA-76BA-461C-8B6D-418607591247}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{1169E6D1-1899-43D4-A500-07CE4235B388}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{1169E6D1-1899-43D4-A500-07CE4235B388}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{1169E6D1-1899-43D4-A500-07CE4235B388}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{1169E6D1-1899-43D4-A500-07CE4235B388}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{B51C6636-B8D1-4200-9869-08F2689DE6C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{B51C6636-B8D1-4200-9869-08F2689DE6C2}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{B51C6636-B8D1-4200-9869-08F2689DE6C2}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{B51C6636-B8D1-4200-9869-08F2689DE6C2}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{0313F581-C63B-43BB-AA9B-07615DABD8A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{0313F581-C63B-43BB-AA9B-07615DABD8A3}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{0313F581-C63B-43BB-AA9B-07615DABD8A3}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{0313F581-C63B-43BB-AA9B-07615DABD8A3}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{743B439A-E7AD-4A0A-BAB6-222E1EA83C6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{743B439A-E7AD-4A0A-BAB6-222E1EA83C6D}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{743B439A-E7AD-4A0A-BAB6-222E1EA83C6D}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{743B439A-E7AD-4A0A-BAB6-222E1EA83C6D}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{50060E0C-FA25-41F4-B72F-8490324EC9F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{50060E0C-FA25-41F4-B72F-8490324EC9F0}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{50060E0C-FA25-41F4-B72F-8490324EC9F0}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{50060E0C-FA25-41F4-B72F-8490324EC9F0}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{4FBB470F-69EB-4C8B-8961-8B4DF4EBB999}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{4FBB470F-69EB-4C8B-8961-8B4DF4EBB999}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{4FBB470F-69EB-4C8B-8961-8B4DF4EBB999}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{4FBB470F-69EB-4C8B-8961-8B4DF4EBB999}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{F8EFCF9D-B9A3-4BA0-A1B2-B026A71DAC22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{F8EFCF9D-B9A3-4BA0-A1B2-B026A71DAC22}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{F8EFCF9D-B9A3-4BA0-A1B2-B026A71DAC22}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{F8EFCF9D-B9A3-4BA0-A1B2-B026A71DAC22}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{81A30182-3378-4952-8880-F44822390040}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{81A30182-3378-4952-8880-F44822390040}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{81A30182-3378-4952-8880-F44822390040}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{81A30182-3378-4952-8880-F44822390040}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\tEndGlobalSection\r\n\tGlobalSection(SolutionProperties) = preSolution\r\n\t\tHideSolutionNode = FALSE\r\n\tEndGlobalSection\r\n\tGlobalSection(ExtensibilityGlobals) = postSolution\r\n\t\tSolutionGuid = {C764218F-7633-4412-923D-558CE7EE0560}\r\n\tEndGlobalSection\r\nEndGlobal\r\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT license\n\nCopyright (c) 2011-2025 AlphaSierraPapa for the ILSpy team\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this\nsoftware and associated documentation files (the \"Software\"), to deal in the Software\nwithout restriction, including without limitation the rights to use, copy, modify, merge,\npublish, distribute, sublicense, and/or sell copies of the Software, and to permit persons\nto whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or\nsubstantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\nPURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\nFOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\nOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE."
  },
  {
    "path": "NuGet.config",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <packageSources>\n    <clear />\n    <add key=\"nuget.org\" value=\"https://api.nuget.org/v3/index.json\" />\n    <add key=\"dotnet-tools\" value=\"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json\" />\n    <add key=\"dotnet9-transport\" value=\"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet9-transport/nuget/v3/index.json\" />\n    <add key=\"dotnet10-transport\" value=\"https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10-transport/nuget/v3/index.json\" />\n  </packageSources>\n  <packageSourceMapping>\n    <packageSource key=\"nuget.org\">\n      <package pattern=\"*\" />\n      <package pattern=\"Microsoft.DiaSymReader.Native\" />\n      <package pattern=\"Microsoft.DiaSymReader\" />\n    </packageSource>\n    <packageSource key=\"dotnet10-transport\">\n      <package pattern=\"ILCompiler.Reflection.ReadyToRun.Experimental\" />\n    </packageSource>\n    <packageSource key=\"dotnet-tools\">\n      <package pattern=\"Microsoft.DiaSymReader.Converter.Xml\" />\n      <package pattern=\"Microsoft.DiaSymReader.PortablePdb\" />\n    </packageSource>\n  </packageSourceMapping>\n</configuration>\n"
  },
  {
    "path": "README.md",
    "content": "# ILSpy [![NuGet](https://img.shields.io/nuget/v/ICSharpCode.Decompiler.svg)](https://nuget.org/packages/ICSharpCode.Decompiler) ![Build ILSpy](https://github.com/icsharpcode/ILSpy/workflows/Build%20ILSpy/badge.svg?branch=master) [![Mastodon](https://img.shields.io/badge/dynamic/json?label=Mastodon&query=totalItems&url=https%3A%2F%2Fhachyderm.io%2Fusers%2Filspy%2Ffollowers.json&logo=mastodon&style=flat-square)](https://hachyderm.io/@ilspy) [![Bluesky](https://img.shields.io/badge/Bluesky-0285FF?logo=bluesky&logoColor=fff)](https://bsky.app/profile/ilspy.bsky.social) [![ILSpy VS extension](https://img.shields.io/badge/VS%20Extension-ILSpy-blue.svg)](https://visualstudiogallery.msdn.microsoft.com/8ef1d688-f80c-4380-8004-2ec7f814e7de) \n\nILSpy is the open-source .NET assembly browser and decompiler.\n\nDownload: [latest release](https://github.com/icsharpcode/ILSpy/releases) | [latest CI build (master)](https://github.com/icsharpcode/ILSpy/actions?query=workflow%3A%22Build+ILSpy%22+branch%3Amaster+is%3Asuccess+event%3Apush) | [Microsoft Store (RTM versions only)](https://apps.microsoft.com/store/detail/ilspy-fresh/XP8C26VDWLP4T4)\n\nDecompiler Frontends\n-------\n\nAside from the WPF UI ILSpy (downloadable via Releases, see also [plugins](https://github.com/icsharpcode/ILSpy/wiki/Plugins)), the following other frontends are available:\n\n* Visual Studio 2022/2026 ship with decompilation support for F12 enabled by default (using our engines v8.2 and v9.1 respectively).\n* Our Visual Studio 2022 extension [marketplace](https://marketplace.visualstudio.com/items?itemName=SharpDevelopTeam.ILSpy2022) (works with VS 2026 as well)\n* Our Visual Studio Code Extension [repository](https://github.com/icsharpcode/ilspy-vscode) | [marketplace](https://marketplace.visualstudio.com/items?itemName=icsharpcode.ilspy-vscode) | [open-vsx](https://open-vsx.org/extension/icsharpcode/ilspy-vscode)\n* Our dotnet tool for Linux/Mac/Windows - check out [ILSpyCmd](ICSharpCode.ILSpyCmd) in this repository | [dotnet tool install](https://www.nuget.org/packages/ilspycmd/)\n* [C# for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp) ships with decompilation support as well. To enable, activate the setting \"Enable Decompilation Support\".\n* In Visual Studio 2019, you have to manually enable F12 support. Go to Tools / Options / Text Editor / C# / Advanced and check \"Enable navigation to decompiled source\"\n* Our Visual Studio 2017/2019 extension [marketplace](https://marketplace.visualstudio.com/items?itemName=SharpDevelopTeam.ILSpy)\n* Our [ICSharpCode.Decompiler](https://www.nuget.org/packages/ICSharpCode.Decompiler/) NuGet for your own projects\n* Our Linux/Mac/Windows [PowerShell cmdlets](ICSharpCode.Decompiler.PowerShell) in this repository\n\nFeatures\n-------\n\n * Decompilation to C# (check out the [language support status](https://github.com/icsharpcode/ILSpy/issues/829))\n * Whole-project decompilation\n * Search for types/methods/properties (learn about the [options](https://github.com/icsharpcode/ILSpy/wiki/Search-Options))\n * Hyperlink-based type/method/property navigation\n * Base/Derived types navigation, history\n * Assembly metadata explorer ([feature walkthrough](https://github.com/icsharpcode/ILSpy/wiki/Metadata-Explorer))\n * BAML to XAML decompiler\n * ReadyToRun binary support for .NET Core (see the [tutorial](https://github.com/icsharpcode/ILSpy/wiki/ILSpy.ReadyToRun))\n * Extensible via [plugins](https://github.com/icsharpcode/ILSpy/wiki/Plugins)\n * Additional features in DEBUG builds ([for the devs](https://github.com/icsharpcode/ILSpy/wiki/Additional-Features-in-DEBUG-Builds))\n\nLicense\n-------\n\nILSpy is distributed under the MIT License. Please see the [About](doc/ILSpyAboutPage.txt) doc for details, \nas well as [third party notices](doc/third-party-notices.txt) for included open-source libraries.\n\nHow to build\n------------\n\n#### Windows:\n\n- Make sure Windows PowerShell (at least version) 5.0 or [PowerShell](https://github.com/PowerShell/PowerShell) 7+ is installed.\n- Clone the ILSpy repository using git.\n- Execute `git submodule update --init --recursive` to download the ILSpy-Tests submodule (used by some test cases).\n- Install Visual Studio (documented version: 18.0/2026). You need the following workload components:\n  - Workload \".NET Desktop Development\". This workload includes the .NET Framework 4.8 SDK and the .NET Framework 4.7.2 targeting pack, as well as the [.NET 10.0 SDK](https://dotnet.microsoft.com/download/dotnet/10.0) (ILSpy.csproj targets .NET 10.0, but we have net472 projects too).\n  - Workload \"Visual Studio extension development\" (Note: ILSpy.VSExtensions.sln is separate from ILSpy.sln and thus this workload is optional)\n  - Individual Component \"MSVC v143 - VS 2022 C++ x64/x86 build tools\" (or similar)\n    - _The VC++ toolset is optional_; if present it is used for `editbin.exe` to modify the stack size used by ILSpy.exe from 1MB to 16MB, because the decompiler makes heavy use of recursion, where small stack sizes lead to problems in very complex methods.\n- Open ILSpy.sln in Visual Studio.\n  - NuGet package restore will automatically download further dependencies\n  - Run project \"ILSpy\" for the ILSpy UI\n  - Use the Visual Studio \"Test Explorer\" to see/run the tests\n  - If you are only interested in a specific subset of ILSpy, you can also use\n    - ILSpy.Wpf.slnf: for the ILSpy WPF frontend\n    - ILSpy.XPlat.slnf: for the cross-platform CLI or PowerShell cmdlets\n    - ILSpy.AddIn.slnf: for the Visual Studio plugin\n\n**Note:** Visual Studio includes a version of the .NET SDK that is managed by the Visual Studio installer - once you update, it may get upgraded too.\nPlease note that ILSpy is only compatible with the .NET 10.0 SDK and Visual Studio will refuse to load some projects in the solution (and unit tests will fail). \nIf this problem occurs, please manually install the .NET 10.0 SDK from [here](https://dotnet.microsoft.com/download/dotnet/10.0).\n\n#### Unix / Mac:\n\n- Make sure [.NET 10.0 SDK](https://dotnet.microsoft.com/download/dotnet/10.0) is installed.\n- Make sure [PowerShell](https://github.com/PowerShell/PowerShell) is installed (formerly known as PowerShell Core)\n- Clone the repository using git.\n- Execute `git submodule update --init --recursive` to download the ILSpy-Tests submodule (used by some test cases).\n- Use `dotnet build ILSpy.XPlat.slnf` to build the non-Windows flavors of ILSpy (.NET Core Global Tool and PowerShell Core).\n\nHow to contribute\n-----------------\n\n- Report bugs\n- If you want to contribute a pull request, please add https://github.com/icsharpcode/ILSpy/blob/master/BuildTools/pre-commit to your `.git/hooks` to prevent checking in code with wrong formatting. We use tabs and not spaces. The build server runs the same script, so any pull requests using wrong formatting will fail.\n\nCurrent and past [contributors](https://github.com/icsharpcode/ILSpy/graphs/contributors).\n\nPrivacy Policy for ILSpy\n------------------------\n\nILSpy does not collect any personally identifiable information, nor does it send user files to 3rd party services. \nILSpy does not use any APM (Application Performance Management) service to collect telemetry or metrics.\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\n## Supported Versions\n\nSupported are the latest released version as well as the latest preview/rc version.\n\n## Reporting a Vulnerability\n\nSecurity issues and bugs should be reported privately to christoph.wille AT gmail.com. Please note that\nwe cannot guarantee a response time (*) although we will strive to get back to you within one business day. If you\ndo not hear back from Chris within a week, alternatively try to contact siegfriedpammer AT gmail.com.\n\nPlease do not open issues for anything you think might have a security implication.\n\n(*) We are an OSS project entirely run by volunteers and sometimes life<sup>tm</sup> will mean longer response times.\n"
  },
  {
    "path": "TestPlugin/AboutPageAddition.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \\doc\\copyright.txt)\n// This code is distributed under MIT X11 license (for details please see \\doc\\license.txt)\n\nusing System.Composition;\nusing System.Windows;\nusing System.Windows.Media;\n\nusing ICSharpCode.AvalonEdit.Highlighting;\nusing ICSharpCode.ILSpy;\n\nnamespace TestPlugin\n{\n\t[Export(typeof(IAboutPageAddition))]\n\t[Shared]\n\tpublic class AboutPageAddition : IAboutPageAddition\n\t{\n\t\tpublic void Write(ISmartTextOutput textOutput)\n\t\t{\n\t\t\ttextOutput.WriteLine();\n\t\t\ttextOutput.Write(\"This is a test.\");\n\t\t\ttextOutput.WriteLine();\n\t\t\ttextOutput.WriteLine();\n\t\t\ttextOutput.BeginSpan(new HighlightingColor {\n\t\t\t\tBackground = new SimpleHighlightingBrush(Colors.Black),\n\t\t\t\tFontStyle = FontStyles.Italic,\n\t\t\t\tForeground = new SimpleHighlightingBrush(Colors.Aquamarine)\n\t\t\t});\n\t\t\ttextOutput.Write(\"DO NOT PRESS THIS BUTTON --> \");\n\t\t\ttextOutput.AddButton(null, \"Test!\", (sender, args) => MessageBox.Show(\"Naughty Naughty!\", \"Naughty!\", MessageBoxButton.OK, MessageBoxImage.Exclamation));\n\t\t\ttextOutput.Write(\" <--\");\n\t\t\ttextOutput.WriteLine();\n\t\t\ttextOutput.EndSpan();\n\t\t\ttextOutput.WriteLine();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "TestPlugin/ContextMenuCommand.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \\doc\\copyright.txt)\n// This code is distributed under MIT X11 license (for details please see \\doc\\license.txt)\n\nusing System.Composition;\nusing System.Linq;\n\nusing ICSharpCode.ILSpy;\nusing ICSharpCode.ILSpy.TreeNodes;\n\nnamespace TestPlugin\n{\n\t[ExportContextMenuEntryAttribute(Header = \"_Save Assembly\")]\n\t[Shared]\n\tpublic class SaveAssembly : IContextMenuEntry\n\t{\n\t\tpublic bool IsVisible(TextViewContext context)\n\t\t{\n\t\t\treturn context.SelectedTreeNodes != null && context.SelectedTreeNodes.All(n => n is AssemblyTreeNode);\n\t\t}\n\n\t\tpublic bool IsEnabled(TextViewContext context)\n\t\t{\n\t\t\treturn context.SelectedTreeNodes != null && context.SelectedTreeNodes.Length == 1;\n\t\t}\n\n\t\tpublic void Execute(TextViewContext context)\n\t\t{\n\t\t\tif (context.SelectedTreeNodes == null)\n\t\t\t\treturn;\n\t\t\tAssemblyTreeNode node = (AssemblyTreeNode)context.SelectedTreeNodes[0];\n\t\t\tvar asm = node.LoadedAssembly.GetMetadataFileOrNull();\n\t\t\tif (asm != null)\n\t\t\t{\n\t\t\t\t/*SaveFileDialog dlg = new SaveFileDialog();\n\t\t\t\tdlg.FileName = node.LoadedAssembly.FileName;\n\t\t\t\tdlg.Filter = \"Assembly|*.dll;*.exe\";\n\t\t\t\tif (dlg.ShowDialog(MainWindow.Instance) == true) {\n\t\t\t\t\tasm.MainModule.Write(dlg.FileName);\n\t\t\t\t}*/\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "TestPlugin/CustomLanguage.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \\doc\\copyright.txt)\n// This code is distributed under MIT X11 license (for details please see \\doc\\license.txt)\n\nusing System.Composition;\nusing System.Reflection.Metadata;\nusing System.Windows.Controls;\n\nusing ICSharpCode.Decompiler;\nusing ICSharpCode.Decompiler.TypeSystem;\nusing ICSharpCode.ILSpy;\n\nnamespace TestPlugin\n{\n\t/// <summary>\n\t/// Adds a new language to the decompiler.\n\t/// </summary>\n\t[Export(typeof(Language))]\n\t[Shared]\n\tpublic class CustomLanguage : Language\n\t{\n\t\tpublic override string Name {\n\t\t\tget {\n\t\t\t\treturn \"Custom\";\n\t\t\t}\n\t\t}\n\n\t\tpublic override string FileExtension {\n\t\t\tget {\n\t\t\t\t// used in 'Save As' dialog\n\t\t\t\treturn \".txt\";\n\t\t\t}\n\t\t}\n\n\t\t// There are several methods available to override; in this sample, we deal with methods only\n\t\tpublic override void DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options)\n\t\t{\n\t\t\tvar module = ((MetadataModule)method.ParentModule).MetadataFile;\n\t\t\tvar methodDef = module.Metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken);\n\t\t\tif (methodDef.HasBody())\n\t\t\t{\n\t\t\t\tvar methodBody = module.GetMethodBody(methodDef.RelativeVirtualAddress);\n\t\t\t\toutput.WriteLine(\"Size of method: {0} bytes\", methodBody.GetCodeSize());\n\n\t\t\t\tISmartTextOutput smartOutput = output as ISmartTextOutput;\n\t\t\t\tif (smartOutput != null)\n\t\t\t\t{\n\t\t\t\t\t// when writing to the text view (but not when writing to a file), we can even add UI elements such as buttons:\n\t\t\t\t\tsmartOutput.AddButton(null, \"Click me!\", (sender, e) => (sender as Button).Content = \"I was clicked!\");\n\t\t\t\t\tsmartOutput.WriteLine();\n\t\t\t\t}\n\n\t\t\t\t// ICSharpCode.Decompiler.CSharp.CSharpDecompiler can be used to decompile to C#.\n\t\t\t\t/*\n\t\t\t\t\tModuleDefinition module = LoadModule(assemblyFileName);\n\t\t\t\t\tvar typeSystem = new DecompilerTypeSystem(module);\n\t\t\t\t\tCSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, new DecompilerSettings());\n\n\t\t\t\t\tdecompiler.AstTransforms.Add(new EscapeInvalidIdentifiers());\n\t\t\t\t\tSyntaxTree syntaxTree = decompiler.DecompileWholeModuleAsSingleFile();\n\t\t\t\t\tvar visitor = new CSharpOutputVisitor(output, FormattingOptionsFactory.CreateSharpDevelop());\n\t\t\t\t\tsyntaxTree.AcceptVisitor(visitor);\n\t\t\t\t*/\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "TestPlugin/CustomOptionPage.xaml",
    "content": "<UserControl x:Class=\"TestPlugin.CustomOptionPage\"\n\txmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n\txmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n\txmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" d:DesignHeight=\"500\" d:DesignWidth=\"500\"\n\txmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" mc:Ignorable=\"d\"\n\txmlns:testPlugin=\"clr-namespace:TestPlugin\"\n\td:DataContext=\"{d:DesignInstance testPlugin:CustomOptionsViewModel}\"\n\t>\n\t<StackPanel>\n\t\t<CheckBox IsChecked=\"{Binding  Options.UselessOption1}\">Useless option 1</CheckBox>\n\t\t<Slider Minimum=\"0\" Maximum=\"100\" Value=\"{Binding Options.UselessOption2}\"/>\n\t</StackPanel>\n</UserControl>"
  },
  {
    "path": "TestPlugin/CustomOptionPage.xaml.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \\doc\\copyright.txt)\n// This code is distributed under MIT X11 license (for details please see \\doc\\license.txt)\n\nusing System.Composition;\nusing System.Xml.Linq;\n\nusing ICSharpCode.ILSpy.Options;\nusing ICSharpCode.ILSpy.Util;\nusing ICSharpCode.ILSpyX.Settings;\n\nusing TomsToolbox.Wpf;\nusing TomsToolbox.Wpf.Composition.AttributedModel;\n\nnamespace TestPlugin\n{\n\t[DataTemplate(typeof(CustomOptionsViewModel))]\n\t[NonShared]\n\tpartial class CustomOptionPage\n\t{\n\t\tpublic CustomOptionPage()\n\t\t{\n\t\t\tInitializeComponent();\n\t\t}\n\t}\n\n\t[ExportOptionPage(Order = 0)]\n\t[NonShared]\n\tclass CustomOptionsViewModel : ObservableObjectBase, IOptionPage\n\t{\n\t\tprivate Options options;\n\n\t\tpublic string Title => \"TestPlugin\";\n\n\t\tpublic Options Options {\n\t\t\tget => options;\n\t\t\tset => SetProperty(ref options, value);\n\t\t}\n\n\t\tpublic void Load(SettingsSnapshot snapshot)\n\t\t{\n\t\t\tthis.Options = snapshot.GetSettings<Options>();\n\t\t}\n\n\t\tpublic void LoadDefaults()\n\t\t{\n\t\t\tOptions.LoadFromXml(new XElement(\"dummy\"));\n\t\t}\n\t}\n\n\tclass Options : ObservableObjectBase, ISettingsSection\n\t{\n\t\tstatic readonly XNamespace ns = \"http://www.ilspy.net/testplugin\";\n\n\t\tbool uselessOption1;\n\n\t\tpublic bool UselessOption1 {\n\t\t\tget => uselessOption1;\n\t\t\tset => SetProperty(ref uselessOption1, value);\n\t\t}\n\n\t\tdouble uselessOption2;\n\n\t\tpublic double UselessOption2 {\n\t\t\tget => uselessOption2;\n\t\t\tset => SetProperty(ref uselessOption2, value);\n\t\t}\n\n\t\tpublic XName SectionName { get; } = ns + \"CustomOptions\";\n\n\t\tpublic void LoadFromXml(XElement e)\n\t\t{\n\t\t\tUselessOption1 = (bool?)e.Attribute(\"useless1\") ?? false;\n\t\t\tUselessOption2 = (double?)e.Attribute(\"useless2\") ?? 50.0;\n\t\t}\n\n\t\tpublic XElement SaveToXml()\n\t\t{\n\t\t\tvar section = new XElement(SectionName);\n\n\t\t\tsection.SetAttributeValue(\"useless1\", UselessOption1);\n\t\t\tsection.SetAttributeValue(\"useless2\", UselessOption2);\n\n\t\t\treturn section;\n\t\t}\n\t}\n}"
  },
  {
    "path": "TestPlugin/MainMenuCommand.cs",
    "content": "// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \\doc\\copyright.txt)\n// This code is distributed under MIT X11 license (for details please see \\doc\\license.txt)\n\nusing System.Composition;\n\nusing ICSharpCode.ILSpy;\nusing ICSharpCode.ILSpy.AssemblyTree;\n\nnamespace TestPlugin\n{\n\t// Menu: menu into which the item is added\n\t// MenuIcon: optional, icon to use for the menu item. Must be embedded as \"Resource\" (WPF-style resource) in the same assembly as the command type.\n\t// Header: text on the menu item\n\t// MenuCategory: optional, used for grouping related menu items together. A separator is added between different groups.\n\t// MenuOrder: controls the order in which the items appear (items are sorted by this value)\n\t[ExportMainMenuCommand(ParentMenuID = \"_File\", MenuIcon = \"Clear.png\", Header = \"_Clear List\", MenuCategory = \"Open\", MenuOrder = 1.5)]\n\t// ToolTip: the tool tip\n\t// ToolbarIcon: The icon. Must be embedded as \"Resource\" (WPF-style resource) in the same assembly as the command type.\n\t// ToolbarCategory: optional, used for grouping related toolbar items together. A separator is added between different groups.\n\t// ToolbarOrder: controls the order in which the items appear (items are sorted by this value)\n\t[ExportToolbarCommand(ToolTip = \"Clears the current assembly list\", ToolbarIcon = \"Clear.png\", ToolbarCategory = \"Open\", ToolbarOrder = 1.5)]\n\t[Shared]\n\tpublic class UnloadAllAssembliesCommand(AssemblyTreeModel assemblyTreeModel) : SimpleCommand\n\t{\n\t\tpublic override void Execute(object parameter)\n\t\t{\n\t\t\tforeach (var loadedAssembly in assemblyTreeModel.AssemblyList.GetAssemblies())\n\t\t\t{\n\t\t\t\tloadedAssembly.AssemblyList.Unload(loadedAssembly);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "TestPlugin/Properties/AssemblyInfo.cs",
    "content": "#region Using directives\n\nusing System.Reflection;\nusing System.Runtime.InteropServices;\n\n#endregion\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyCopyright(\"Copyright 2011\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// This sets the default COM visibility of types in the assembly to invisible.\n// If you need to expose a type to COM, use [ComVisible(true)] on that type.\n[assembly: ComVisible(false)]\n"
  },
  {
    "path": "TestPlugin/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"TestPlugin\": {\n      \"commandName\": \"Executable\",\n      \"executablePath\": \".\\\\ILSpy.exe\",\n      \"commandLineArgs\": \"/separate\"\n    }\n  }\n}"
  },
  {
    "path": "TestPlugin/Readme.txt",
    "content": "ILSpy uses MEF (Managed Extensibility Framework) for plugins.\nPlugins must be placed in the same directory as ILSpy.exe, and must be called \"*.Plugin.dll\".\n\nTo write a plugin, you need to add a reference to ILSpy.exe and to System.Composition.AttributedModel.\nDepending on what your plugin is doing, you might also need references to the other libraries shipping with ILSpy.\n\nPlugins work by exporting types for certain extension points.\nHere is a list of extension points:\n\nAdding another language:\n\n\t[Export(typeof(Language))]\n\tpublic class CustomLanguage : Language\n\t\n\tThis adds an additional language to the combobox in the toolbar.\n\tThe language has to implement its own decompiler (all the way from IL), but it can also re-use\n\tthe ICSharpCode.Decompiler library to decompile to C#, and then translate the C# code to the target language.\n\n---\n\nAdding an entry to the main menu:\n\n\t[ExportMainMenuCommand(Menu = \"_File\", MenuIcon = \"Clear.png\", Header = \"_Clear List\", MenuCategory = \"Open\", MenuOrder = 1.5)]\n\tpublic class UnloadAllAssembliesCommand : SimpleCommand\n\t\n\tMenu: menu into which the item is added\n\tMenuIcon: optional, icon to use for the menu item. Must be embedded as \"Resource\" (WPF-style resource) in the same assembly as the command type.\n\tHeader: text on the menu item\n\tMenuCategory: optional, used for grouping related menu items together. A separator is added between different groups.\n\tMenuOrder: controls the order in which the items appear (items are sorted by this value)\n\n\tThe command class must implement WPF's ICommand interface.\n\n---\n\nAdding an entry to the tool bar:\n\n\t[ExportToolbarCommand(ToolTip = \"Clears the current assembly list\", ToolbarIcon = \"Clear.png\", ToolbarCategory = \"Open\", ToolbarOrder = 1.5)]\n\tpublic class UnloadAllAssembliesCommand : SimpleCommand\n\n\tToolTip: the tool tip\n\tToolbarIcon: The icon. Must be embedded as \"Resource\" (WPF-style resource) in the same assembly as the command type.\n\tToolbarCategory: optional, used for grouping related toolbar items together. A separator is added between different groups.\n\tToolbarOrder: controls the order in which the items appear (items are sorted by this value)\n\n\tThe command class must implement WPF's ICommand interface.\n\n---\n\nAdding an entry to the context menu:\n\n\t[ExportContextMenuEntry(Header = \"_Save Assembly\")]\n\tpublic class SaveAssembly : IContextMenuEntry\n\t\n\tIcon: optional, icon to use for the menu item. Must be embedded as \"Resource\" (WPF-style resource) in the same assembly as the command type.\n\tHeader: text on the menu item\n\tCategory: optional, used for grouping related menu items together. A separator is added between different groups.\n\tOrder: controls the order in which the items appear (items are sorted by this value)\n\t\n\tContext menu entries must implement IContextMenuEntry, which defines 3 methods:\n\tbool IsVisible, bool IsEnabled, and void Execute.\n\n---\n\nAdding an option page:\n\n\t[ExportOptionPage(\"TestPlugin\")]\n\tpartial class CustomOptionPage : UserControl, IOptionPage\n\t\n"
  },
  {
    "path": "TestPlugin/TestPlugin.csproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project Sdk=\"Microsoft.NET.Sdk\">\r\n  <PropertyGroup>\r\n    <TargetFramework>net10.0-windows</TargetFramework>\r\n    <AssemblyName>Test.Plugin</AssemblyName>\r\n    <UseWpf>true</UseWpf>\r\n    <EnableWindowsTargeting>true</EnableWindowsTargeting>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Debug'\">\r\n    <DebugType>full</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n    <CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>\r\n  </PropertyGroup>\r\n\r\n  <PropertyGroup Condition=\"'$(Configuration)' == 'Release'\">\r\n    <DebugType>pdbonly</DebugType>\r\n    <DebugSymbols>true</DebugSymbols>\r\n  </PropertyGroup>\r\n\r\n  <ItemGroup>\r\n    <ProjectReference Include=\"..\\ILSpy\\ILSpy.csproj\" />\r\n    <ProjectReference Include=\"..\\ICSharpCode.Decompiler\\ICSharpCode.Decompiler.csproj\" />\r\n  </ItemGroup>\r\n\r\n  <ItemGroup>\r\n    <Resource Include=\"Clear.png\" />\r\n    <None Include=\"Readme.txt\" />\r\n  </ItemGroup>\r\n\r\n</Project>"
  },
  {
    "path": "clean.bat",
    "content": "dotnet clean ILSpy.sln /p:Configuration=Debug \"/p:Platform=Any CPU\" %* || pause\ndotnet clean ILSpy.sln /p:Configuration=Release \"/p:Platform=Any CPU\" %* || pause"
  },
  {
    "path": "debugbuild.bat",
    "content": "dotnet build ILSpy.sln /p:Configuration=Debug \"/p:Platform=Any CPU\" %* || (pause && exit /b 1)\n"
  },
  {
    "path": "decompiler-nuget-demos.ipynb",
    "content": "{\n  \"cells\": [\n    {\n      \"cell_type\": \"markdown\",\n      \"metadata\": {},\n      \"source\": [\n        \"You must install **.NET Interactive Notebooks** extension in VS Code to run this notebook!\\n\",\n        \"\\n\",\n        \"Load the NuGet package and print out the version to make sure we are using the latest and greatest\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": 10,\n      \"metadata\": {\n        \"dotnet_interactive\": {\n          \"language\": \"csharp\"\n        },\n        \"vscode\": {\n          \"languageId\": \"polyglot-notebook\"\n        }\n      },\n      \"outputs\": [\n        {\n          \"data\": {\n            \"text/html\": [\n              \"<div><div></div><div></div><div><strong>Installed Packages</strong><ul><li><span>ICSharpCode.Decompiler, 8.1.0.7455</span></li></ul></div></div>\"\n            ]\n          },\n          \"metadata\": {},\n          \"output_type\": \"display_data\"\n        },\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"ICSharpCode.Decompiler, Version=8.1.0.7455, Culture=neutral, PublicKeyToken=d4bfe873e7598c49\\r\\n\"\n          ]\n        }\n      ],\n      \"source\": [\n        \"#r \\\"nuget: ICSharpCode.Decompiler, 8.1.0.7455\\\"\\n\",\n        \"\\n\",\n        \"using System.Reflection.Metadata;\\n\",\n        \"using ICSharpCode.Decompiler;\\n\",\n        \"using ICSharpCode.Decompiler.CSharp;\\n\",\n        \"using ICSharpCode.Decompiler.Metadata;\\n\",\n        \"using ICSharpCode.Decompiler.TypeSystem;\\n\",\n        \"\\n\",\n        \"Console.WriteLine(typeof(FullTypeName).Assembly.GetName());\"\n      ]\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"metadata\": {},\n      \"source\": [\n        \"You must have compiled **ILSpy.XPlat.slnf** first (run “dotnet build” in ICSharpCode.Decompiler.PowerShell folder). Make sure to modify **basePath** to your repository path.\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": 11,\n      \"metadata\": {\n        \"dotnet_interactive\": {\n          \"language\": \"csharp\"\n        },\n        \"vscode\": {\n          \"languageId\": \"polyglot-notebook\"\n        }\n      },\n      \"outputs\": [],\n      \"source\": [\n        \"const string basePath = @\\\"D:\\\\GitWorkspace\\\\ILSpy\\\\\\\";\\n\",\n        \"string testAssemblyPath = basePath + @\\\"ICSharpCode.Decompiler.PowerShell\\\\bin\\\\Release\\\\netstandard2.0\\\\ICSharpCode.Decompiler.dll\\\";\\n\",\n        \"\\n\",\n        \"var decompiler = new CSharpDecompiler(testAssemblyPath, new DecompilerSettings());\"\n      ]\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"metadata\": {},\n      \"source\": [\n        \"Get the count of types in this module\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": 12,\n      \"metadata\": {\n        \"dotnet_interactive\": {\n          \"language\": \"csharp\"\n        },\n        \"vscode\": {\n          \"languageId\": \"polyglot-notebook\"\n        }\n      },\n      \"outputs\": [\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"1532\\r\\n\"\n          ]\n        }\n      ],\n      \"source\": [\n        \"var types = decompiler.TypeSystem.MainModule.TypeDefinitions;\\n\",\n        \"Console.WriteLine(types.Count());\"\n      ]\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"metadata\": {},\n      \"source\": [\n        \"Decompile a known type (as a whole)\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": 13,\n      \"metadata\": {\n        \"dotnet_interactive\": {\n          \"language\": \"csharp\"\n        },\n        \"vscode\": {\n          \"languageId\": \"polyglot-notebook\"\n        }\n      },\n      \"outputs\": [\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"using System;\\r\\n\",\n            \"\\r\\n\",\n            \"namespace ICSharpCode.Decompiler.Util;\\r\\n\",\n            \"\\r\\n\",\n            \"public static class Empty<T>\\r\\n\",\n            \"{\\r\\n\",\n            \"\\tpublic static readonly T[] Array = System.Array.Empty<T>();\\r\\n\",\n            \"}\\r\\n\",\n            \"\\r\\n\"\n          ]\n        }\n      ],\n      \"source\": [\n        \"// ICSharpCode.Decompiler.Util.Empty<T> -> translates to `n, where n is the # of generic parameters\\n\",\n        \"var nameOfGenericType = new FullTypeName(\\\"ICSharpCode.Decompiler.Util.Empty`1\\\");\\n\",\n        \"Console.WriteLine(decompiler.DecompileTypeAsString(nameOfGenericType));\"\n      ]\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"metadata\": {},\n      \"source\": [\n        \"If you want to decompile one single member (sample: first method)\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": 14,\n      \"metadata\": {\n        \"dotnet_interactive\": {\n          \"language\": \"csharp\"\n        },\n        \"vscode\": {\n          \"languageId\": \"polyglot-notebook\"\n        }\n      },\n      \"outputs\": [\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"using System;\\r\\n\",\n            \"\\r\\n\",\n            \"static UniversalAssemblyResolver()\\r\\n\",\n            \"{\\r\\n\",\n            \"\\tgac_paths = GetGacPaths();\\r\\n\",\n            \"\\tZeroVersion = new Version(0, 0, 0, 0);\\r\\n\",\n            \"\\tif (Type.GetType(\\\"Mono.Runtime\\\") != null)\\r\\n\",\n            \"\\t{\\r\\n\",\n            \"\\t\\tdecompilerRuntime = DecompilerRuntime.Mono;\\r\\n\",\n            \"\\t}\\r\\n\",\n            \"\\telse if (typeof(object).Assembly.GetName().Name == \\\"System.Private.CoreLib\\\")\\r\\n\",\n            \"\\t{\\r\\n\",\n            \"\\t\\tdecompilerRuntime = DecompilerRuntime.NETCoreApp;\\r\\n\",\n            \"\\t}\\r\\n\",\n            \"\\telse if (Environment.OSVersion.Platform == PlatformID.Unix)\\r\\n\",\n            \"\\t{\\r\\n\",\n            \"\\t\\tdecompilerRuntime = DecompilerRuntime.Mono;\\r\\n\",\n            \"\\t}\\r\\n\",\n            \"}\\r\\n\",\n            \"\\r\\n\"\n          ]\n        }\n      ],\n      \"source\": [\n        \"var nameOfUniResolver =  new FullTypeName(\\\"ICSharpCode.Decompiler.Metadata.UniversalAssemblyResolver\\\");\\n\",\n        \"ITypeDefinition typeInfo = decompiler.TypeSystem.FindType(nameOfUniResolver).GetDefinition();\\n\",\n        \"var tokenOfFirstMethod = typeInfo.Methods.First().MetadataToken;\\n\",\n        \"Console.WriteLine(decompiler.DecompileAsString(tokenOfFirstMethod));\"\n      ]\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"metadata\": {},\n      \"source\": [\n        \"If you need access to low-level metadata tables\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": 15,\n      \"metadata\": {\n        \"dotnet_interactive\": {\n          \"language\": \"csharp\"\n        },\n        \"vscode\": {\n          \"languageId\": \"polyglot-notebook\"\n        }\n      },\n      \"outputs\": [],\n      \"source\": [\n        \"ITypeDefinition type = decompiler.TypeSystem.FindType(nameOfUniResolver).GetDefinition();\\n\",\n        \"var module = type.ParentModule.PEFile;\"\n      ]\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"metadata\": {},\n      \"source\": [\n        \"Get the child namespaces\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": 16,\n      \"metadata\": {\n        \"dotnet_interactive\": {\n          \"language\": \"csharp\"\n        },\n        \"vscode\": {\n          \"languageId\": \"polyglot-notebook\"\n        }\n      },\n      \"outputs\": [\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"Microsoft\\n\",\n            \"System\\n\",\n            \"LightJson\\n\",\n            \"Humanizer\\n\",\n            \"ICSharpCode\\n\",\n            \"FxResources\\n\",\n            \"Internal\\n\",\n            \"MS\\n\"\n          ]\n        }\n      ],\n      \"source\": [\n        \"var icsdns = decompiler.TypeSystem.RootNamespace;\\n\",\n        \"foreach (var cn in icsdns.ChildNamespaces) Console.WriteLine(cn.FullName);\"\n      ]\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"metadata\": {},\n      \"source\": [\n        \"Get types in a single namespace\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": 17,\n      \"metadata\": {\n        \"dotnet_interactive\": {\n          \"language\": \"csharp\"\n        },\n        \"vscode\": {\n          \"languageId\": \"polyglot-notebook\"\n        }\n      },\n      \"outputs\": [\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"LightJson.JsonArray\\r\\n\"\n          ]\n        }\n      ],\n      \"source\": [\n        \"var typesInNamespace = icsdns.ChildNamespaces.First(cn => cn.FullName == \\\"LightJson\\\").Types;\\n\",\n        \"Console.WriteLine(typesInNamespace.First().FullTypeName);\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": 18,\n      \"metadata\": {\n        \"dotnet_interactive\": {\n          \"language\": \"csharp\"\n        },\n        \"vscode\": {\n          \"languageId\": \"polyglot-notebook\"\n        }\n      },\n      \"outputs\": [],\n      \"source\": []\n    }\n  ],\n  \"metadata\": {\n    \"kernelspec\": {\n      \"display_name\": \".NET (C#)\",\n      \"language\": \"C#\",\n      \"name\": \".net-csharp\"\n    },\n    \"language_info\": {\n      \"file_extension\": \".cs\",\n      \"mimetype\": \"text/x-csharp\",\n      \"name\": \"csharp\",\n      \"pygments_lexer\": \"csharp\",\n      \"version\": \"8.0\"\n    }\n  },\n  \"nbformat\": 4,\n  \"nbformat_minor\": 4\n}\n"
  },
  {
    "path": "doc/Command Line.txt",
    "content": "ILSpy Command Line Arguments\n\nUsage:  <Assemblies> [options]\n        @ResponseFile.rsp\n\nArguments:\n  Assemblies                          Assemblies to load\n\nOptions:\n  --newinstance                       Start a new instance of ILSpy even if the user configuration is set to single-instance\n  -n|--navigateto <TYPENAME>          Navigates to the member specified by the given ID string.\n                                      The member is searched for only in the assemblies specified on the command line.\n                                      Example: 'ILSpy ILSpy.exe --navigateTo:T:ICSharpCode.ILSpy.CommandLineArguments'\n  -s|--search <SEARCHTERM>            Search for t:TypeName, m:Member or c:Constant; use exact match (=term),\n                                      'should not contain' (-term) or 'must contain' (+term); use\n                                      /reg(ular)?Ex(pressions)?/ or both - t:/Type(Name)?/...\n  -l|--language <LANGUAGEIDENTIFIER>  Selects the specified language.\n                                      Example: 'ILSpy --language:C#' or 'ILSpy --language:IL'\n  -c|--config <CONFIGFILENAME>        Provide a specific configuration file.\n                                      Example: 'ILSpy --config:myconfig.xml'\n  --noactivate                        Do not activate the existing ILSpy instance. \n                                      This option has no effect if a new ILSpy instance is being started.\n\nNote on @ResponseFile.rsp: \n\n* The response file should contain the arguments, one argument per line (not space-separated!).\n* Use it when the list of assemblies is too long to fit on the command line."
  },
  {
    "path": "doc/ILAst Pattern Matching.md",
    "content": "ILAst Pattern Matching\n=================\n\nSome IL instructions are classified as \"patterns\".\n```c#\nabstract class PatternMatchILInstruction : IStoreInstruction {\n   public ILInstruction TestedOperand { get; }\n   public ILVariable Variable { get; } // variable that receives the match result; may also be a temporary\n}\n\npublic bool IsPattern(this ILInstruction inst, out ILInstruction testedOperand) => inst switch {\n    PatternMatchILInstruction pm => testedOperand = pm.TestedOperand; return true;\n    LogicNot logicNot => IsPattern(logicNot.Operand, out testedOperand),\n    Comp comp => testedOperand = comp.Left; return IsConstant(comp.Right);\n}\n```\nEvery `match.*` instruction has the following properties:\n  * The `TestedOperand` specifies what gets matched against the pattern.\n  * The `Variable` stores the value of `TestedOperand` (after converting to the matched type, if appropriate).\n    * If this variable is also used outside the `match.*` node, it corresponds to the C# `single_variable_designation`.\n    * Otherwise it's a temporary used for pattern matching.\n    * I think in both cases it should have VariableKind.PatternVar\n  * The match instruction evaluates to `StackType.I4`: 0 if the pattern was matched, 1 otherwise.\n\nSome `match` instructions have a body with `List<ILInstruction> nestedPatterns`. Here every nested pattern must be a pattern according to `IsPattern()`, and the `testedOperand` of each must be a member of the `Variable` of the parent pattern. (members are: field, property, or deconstruction.result).\n(exception: `match.and`/`match.or`, these instead require the `testedOperand` to be exactly the `Variable` of the parent pattern)\n\n\nExamples\n--------\n1) `expr is var x`\n    =>\n    `match.var(x = expr)`\n    =>\n    ```\n    Block (VarPattern) {\n\t    stloc x(expr)\t\t// single eval expr\n\t    final: ldc.i4 1\t\t// match always\n    }\n    ```\n2) `expr is T x`\n\t=>\n    `match.type T(x = expr) {}`\n    =>\n\t```\n    Block (TypePattern) {\n        stloc x(isinst T(expr))\n        final: x != null\n    }\n\t```\n3) `expr is C { A: var x } z`\n\t=>\n    ```\n    match.type C(z = expr) {\n       match.var(x = z.A)\n    }\n    ```\n    =>\n\t```\n    Block (TypePattern) {\n        stloc z(isinst T(expr))\n        final: (z != null)\n            && Block(VarPattern) {\n                 stloc x(z.A)\n                 final: ldc.i4 1\n               }\n    }\n\t```\n4) `expr is C { A: var x, B: 42, C: { A: 4 } } z`\n    =>\n    ```\n    match.type C(z = expr) {\n        match.var (x = z.A),\n        comp (z.B == 42),\n        match.recursive (temp2 = z.C) {\n            comp (temp2.A == 4)\n        }\n    }\n    ```\n\t=>\n\t```\n    Block (TypePattern) {\n        stloc z(isinst C(expr))\n        final: (z != null)\n            && Block(VarPattern) {\n                 stloc x(z.A)\n                 final: ldc.i4 1\n               }\n            && comp (z.B == 42)\n            && Block(RecursivePattern) {\n                 stloc temp2(z.C)\n                 final: (temp2 != null)\n                     && comp (temp2.A == 4)\n               }\n    }\n\t```\n5) `expr is C(var x, var y, <4) { ... }`\n   =>\n   ```\n   match.recursive.type.deconstruct(C tmp1 = expr) {\n       match.var(x = deconstruct.result0(tmp1)),\n       match.var(y = deconstruct.result1(tmp1)),\n       comp(deconstruct.result2(tmp1) < 4),\n   }\n   ```\n\n6) `expr is C(1, D(2, 3))`\n    =>\n    ```\n    match.type.deconstruct(C c = expr) {\n        comp(deconstruct.result0(c) == 1),\n        match.type.deconstruct(D d = deconstruct.result1(c)) {\n            comp(deconstruct.result0(d) == 2),\n            comp(deconstruct.result1(d) == 2),\n        }\n    }\n    ```\n    \n7) `x is >= 0 and var y and <= 100`\n    ```\n    match.and(tmp1 = x) {\n        comp(tmp1 >= 0),\n        match.var(y = tmp1),\n        comp(tmp1 <= 100)\n    }\n    ```\n\n8) `x is not C _`\n    =>\n    ```\n    logic.not(\n        match.type(C tmp1 = x) {}\n    )\n    ```\n\n9) `expr is (var a, var b)` (when expr is object)\n    =>\n    ```\n    match.type.deconstruct(ITuple tmp = expr) {\n        match.var(a = deconstruct.result0(tmp)),\n        match.var(b = deconstruct.result1(tmp)),\n    }\n    ```\n    \n10) `expr is (var a, var b)` (when expr is ValueTuple<int, int>)\n    =>\n    ```\n    match.recursive(tmp = expr) {\n        match.var(a = tmp.Item1),\n        match.var(b = tmp.Item2),\n    }\n    ```"
  },
  {
    "path": "doc/ILAst.txt",
    "content": "The first step ICSharpCode.Decompiler performs to decompile a method is to\ntranslate the IL code into the 'ILAst'.\n\nAn ILAst node (ILInstruction in the code) usually has other nodes as arguments,\nand performs a computation with the result of those arguments.\n\nThe evaluation of a node results in either:\n * a value\n * void (which is invalid as an argument, but nodes in blocks may produce void results)\n * a thrown exception (which stops further evaluation until a matching catch block)\n * the execution of a branch instruction (which also stops evaluation until we reach the block container that contains the branch target)\n\nThe main differences between IL and ILAst are:\n * ILAst instructions may form trees\n * Types are explicit, not implicit\n * There is no evaluation stack\n   * Instead, \"stack slot\" variables are introduced\n"
  },
  {
    "path": "doc/ILSpyAboutPage.txt",
    "content": "ILSpy is the open-source .NET assembly browser and decompiler.\n\nWebsite: https://ilspy.net/\nFound a bug? https://github.com/icsharpcode/ILSpy/issues/new/choose\n\nCopyright 2011-2026 AlphaSierraPapa for the ILSpy team\nCurrent and past contributors: https://github.com/icsharpcode/ILSpy/graphs/contributors\n\nILSpy is distributed under the MIT License.\n\nILSpy uses other open-source libraries to make its magic happen, and we want to thank the people working\non those components! For the respective licenses and copyright information please see third-party notices."
  },
  {
    "path": "doc/IntPtr.txt",
    "content": "C# casts to/from IntPtr and UIntPtr don't behave like one would expect from the normal C# primitive types.\nFor example, they don't fully respect the checked/unchecked context.\n\nFirst, let's consider what methods we have available for converting between (U)IntPtr and normal C# types.\n\nPrimitives for constructing IntPtr/UIntPtr:\n * new IntPtr(int)    equivalent to: conv i4->i <sign extend>\n * new IntPtr(long)   equivalent to: conv.ovf i8->i\n * new IntPtr(void*)  equivalent to: nop\n * new UIntPtr(uint)  equivalent to: conv u4->u <zero extend>\n * new UIntPtr(ulong) equivalent to: conv.ovf u8->u\n * new UIntPtr(void*) equivalent to: nop\n\nPrimitives for getting the value back out:\n * IntPtr.ToInt32()    equivalent to: conv.ovf i->i4\n * IntPtr.ToInt64()    equivalent to: conv i->i8 <sign extend>\n * IntPtr.ToPointer()  equivalent to: nop\n * UIntPtr.ToUInt32()  equivalent to: conv.ovf u->u4\n * UIntPtr.ToUInt64()  equivalent to: conv u->u8 <zero extend>\n * UIntPtr.ToPointer() equivalent to: nop\n\nThe (U)IntPtr.op_Explicit implementations are equivalent to the corresponding primitives.\n(void*) is a useful type because all (U)IntPtr<->void* conversions are no-ops.\nC# pointer types act like a normal C# unsigned integer type (of 'native int' size), so we can\nuse `void*` whenever the target type is unsigned or the sign does not matter (overflow checking disabled).\n\nNext, we'll consider what the C# compiler does when casting between integer types and IntPtr.\nI tried all these conversions in both checked and unchecked mode, and the C# compiler was\nalways generating the same code in both modes!\n\nOK = cast behavior is as if IntPtr was a built-in type and the context does not matter:\n\t* sign/zero extension depending on source type\n\t* never throws OverflowException and never is supposed to\nCC = cast behavior is as if IntPtr was a built-in type and we are in a checked context:\n\t* sign/zero extension depending on source type\n\t* performs correct overflowing checking as in a direct cast to native (u)int\nfrom -> to = C# cast\ngenerated opcode sequence = what csc.exe produces for that cast\n\n     from ->    to  : generated opcode sequence            overall effect equivalent to\nOK short  ->  IntPtr: call op_Explicit(int32)              conv i2->i <sign extend>\nOK ushort ->  IntPtr: call op_Explicit(int32)              conv u2->u <zero extend>\n                      Sign extension in op_Explicit does not matter because sign bit is always 0 at that point.\nOK int    ->  IntPtr: call op_Explicit(int32)              conv i4->i <sign extend>\nCC uint   ->  IntPtr: conv.u8 + call op_Explicit(int64)    conv.ovf u4->i <zero extend>\nCC long   ->  IntPtr: call op_Explicit(int64)              conv.ovf i8->i\n   ulong  ->  IntPtr: call op_Explicit(int64)              conv.ovf i8->i\n   short  -> UIntPtr: conv.i8 + call op_Explicit(uint64)   32-bit: conv.ovf i2->u <sign extend>;  64-bit: conv i2->i <sign extend>\n                                                              OverflowException for negative input values only on 32-bit!\nOK ushort -> UIntPtr: call op_Explicit(uint32)             conv u2->u <zero extend>\n   int    -> UIntPtr: conv.i8 + call op_Explicit(uint64)   32-bit: conv.ovf i4->u <sign extend>;  64-bit: conv i4->i <sign extend>\n                                                              OverflowException for negative input values only on 32-bit!\nOK uint   -> UIntPtr: call op_Explicit(uint32)             conv u4->u <zero extend>\n   long   -> UIntPtr: call op_Explicit(uint64)             conv.ovf u8->u\nCC ulong  -> UIntPtr: call op_Explicit(uint64)             conv.ovf u8->u\n\nIf an unchecked conversion is desired and the desired entry is not marked 'OK',\nwe work around the problem by casting sourceType->void*->(U)IntPtr.\n\nIf a checked conversion is desired and the desired entry is not marked 'OK' or 'CC', we have to find a replacement.\n  signed type -> UIntPtr: (UIntPtr)(void*)value\n  ulong -> IntPtr:        (IntPtr)(long)value\n\nContinuing the conversion table for the other direction, (UIntPtr) to primitive types:\n     from ->    to  : generated opcode sequence            overall effect equivalent to\n   IntPtr -> short:  call int32 op_Explicit + conv.i2      conv.ovf i->i4; conv i4->i2\n   IntPtr -> ushort: call int32 op_Explicit + conv.u2      conv.ovf i->i4; conv i4->u2\nCC IntPtr -> int:    call int32 op_Explicit                conv.ovf i->i4\n   IntPtr -> uint:   call int32 op_Explicit                conv.ovf i->i4\nOK IntPtr -> long:   call int64 op_Explicit                conv i->i8 <sign extend>\n   IntPtr -> ulong:  call int64 op_Explicit                conv i->i8 <sign extend>\n   UIntPtr -> short:  call uint32 op_Explicit + conv.i2    conv.ovf u->u4; conv u4->i2\n   UIntPtr -> ushort: call uint32 op_Explicit + conv.u2    conv.ovf u->u4; conv u4->u2\n   UIntPtr -> int:    call uint32 op_Explicit              conv.ovf u->u4\nCC UIntPtr -> uint:   call uint32 op_Explicit              conv.ovf u->u4\n   UIntPtr -> long:   call uint64 op_Explicit              conv u->u8 <zero extend>\nOK UIntPtr -> ulong:  call uint64 op_Explicit              conv u->u8 <zero extend>\n\nIf an unchecked conversion is desired and the desired entry is not marked 'OK',\nwe work around the problem by casting (U)IntPtr->(u)long->targetType.\n(`void*` would also work instead of `ulong`/`long`, but let's avoid unsafe code where possible)\n\nIf a checked conversion is desired and the desired entry is not marked 'OK' or 'CC',\nwe also have to work around the problem, and this again works by casting via (u)long: (U)IntPtr->(u)long->targetType\n(note that `void*` is not always a valid alternative in this case)\n\nFinally, conversions between IntPtr and (U)IntPtr, or IntPtr and `void*` need special consideration:\n  * C# does not allow directly casting IntPtr <-> UIntPtr\n  * Casting via `void*` works but is always unchecked.\n  * These should work for checked conversions:\n     IntPtr -> UIntPtr: cast IntPtr->long->ulong->UIntPtr\n     IntPtr -> void*:   cast IntPtr->long->void*\n     UIntPtr -> IntPtr: cast UIntPtr->ulong->long->IntPtr\n     void*  -> IntPtr:  cast void*->long->IntPtr\n"
  },
  {
    "path": "doc/Pattern Matching.html",
    "content": "<html>\n<head><title>NRefactory Pattern Matching</title></head>\n<body>\n    The pattern matching API for the C# AST is similar to how regular\n    expressions work in .NET, except that it's working with AstNodes\n    instead of characters.<br>\n    First you declare a pattern, for example: \"X a = new X(...);\".<br>\n    <span style=\"color: #000080; \">var</span>&nbsp;pattern =&nbsp;<span\n      style=\"color: #008b8b; font-weight: bold; \">new</span>&nbsp;VariableDeclarationStatement&nbsp;<span\n      style=\"color: #235100; font-weight: normal; font-style: normal; \">{</span><br>\n    &nbsp;&nbsp;&nbsp;&nbsp;Type =&nbsp;<span style=\"color: #008b8b; font-weight: bold; \">new</span>&nbsp;<span\n      style=\"color: #191970; font-weight: bold; \">AnyNode</span><span\n      style=\"color: #235100; font-weight: normal; font-style: normal; \">(</span><span\n      style=\"color: #0000ff; \">\"type\"</span><span style=\"color: #235100;\n      font-weight: normal; font-style: normal; \">),</span><br>\n    &nbsp;&nbsp;&nbsp;&nbsp;Variables =&nbsp;<span style=\"color: #235100; font-weight: normal;\n      font-style: normal; \">{</span><br>\n    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: #008b8b; font-weight: bold; \">new</span>&nbsp;VariableInitializer&nbsp;<span\n      style=\"color: #235100; font-weight: normal; font-style: normal; \">{</span><br>\n    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Name = Pattern<span style=\"color: #235100; font-weight:\n      normal; font-style: normal; \">.</span>AnyString<span style=\"color:\n      #235100; font-weight: normal; font-style: normal; \">,</span><br>\n    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Initializer =&nbsp;<span style=\"color: #008b8b; font-weight:\n      bold; \">new</span>&nbsp;ObjectCreateExpression&nbsp;<span style=\"color:\n      #235100; font-weight: normal; font-style: normal; \">{</span><br>\n    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Type =&nbsp;<span style=\"color: #008b8b; font-weight:\n      bold; \">new</span>&nbsp;<span style=\"color: #191970; font-weight: bold;\n      \">Backreference</span><span style=\"color: #235100; font-weight:\n      normal; font-style: normal; \">(</span><span style=\"color: #0000ff;\n      \">\"type\"</span><span style=\"color: #235100; font-weight: normal;\n      font-style: normal; \">),</span><br>\n    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Arguments =&nbsp;<span style=\"color: #235100;\n      font-weight: normal; font-style: normal; \">{</span>&nbsp;<span\n      style=\"color: #008b8b; font-weight: bold; \">new</span>&nbsp;<span\n      style=\"color: #191970; font-weight: bold; \">Repeat</span><span\n      style=\"color: #235100; font-weight: normal; font-style: normal; \">(</span><span\n      style=\"color: #008b8b; font-weight: bold; \">new</span>&nbsp;<span\n      style=\"color: #191970; font-weight: bold; \">AnyNode</span><span\n      style=\"color: #235100; font-weight: normal; font-style: normal; \">())</span>&nbsp;<span\n      style=\"color: #235100; font-weight: normal; font-style: normal; \">}</span><br>\n    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Initializer =&nbsp;<span style=\"color: #008b8b;\n      font-weight: bold; \">new</span>&nbsp;<span style=\"color: #191970;\n      font-weight: bold; \">OptionalNode</span><span style=\"color:\n      #235100; font-weight: normal; font-style: normal; \">(</span><span\n      style=\"color: #008b8b; font-weight: bold; \">new</span>&nbsp;<span\n      style=\"color: #191970; font-weight: bold; \">AnyNode</span><span\n      style=\"color: #235100; font-weight: normal; font-style: normal; \">())</span><br>\n    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: #235100; font-weight: normal;\n      font-style: normal; \">}</span><br>\n    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: #235100; font-weight: normal;\n      font-style: normal; \">}</span><br>\n    &nbsp;&nbsp;&nbsp;&nbsp;<span style=\"color: #235100; font-weight: normal; font-style:\n      normal; \">}};</span><br>\n    <br>\n    This is a <b>pattern AST</b> - it is a C# AST using the normal C#\n    AST classes, but also contains special <b>pattern nodes</b>\n    (AnyNode, Repeat, OptionalNode, Backreference, NamedNode, Choice,\n    ...).<br>\n    If you call<br>\n    &nbsp;Match m = pattern<span style=\"color: #235100; font-weight: normal;\n      font-style: normal; \">.</span><span style=\"color: #191970;\n      font-weight: bold; \">Match</span><span style=\"color: #235100;\n      font-weight: normal; font-style: normal; \">(</span>someNode<span\n      style=\"color: rgb(35, 81, 0); font-weight: normal; font-style:\n      normal;\">);<br>\n    </span>then m.Success will be true if someNode is a\n    VariableDeclarationStatement that declares a single variable, which\n    is initialized to a new object of the variable type.<br>\n    Basically, Match performs a comparison of the pattern AST with\n    someNode. If the pattern AST does not contain any pattern nodes, the\n    match will be successful if the ASTs are syntactically identical\n    (whitespace/comments are not compared).<br>\n    &nbsp; AnyNode will match any non-null node, and optionally store the\n    node it was matched against in a named <b>capture group</b>.<br>\n    &nbsp; Backreference will match any node that is syntactically identical\n    to the node that was previously stored in the named capture group.<br>\n    &nbsp; Repeat can be used only in AstNodeCollections and will try to\n    match its child pattern against any number of nodes - this is\n    equivalent to * (Kleene star) in regular expressions.<br>\n    &nbsp; OptionalNode will match null nodes, or will try to match its child\n    pattern against the node. OptionalNode can also be used in\n    AstNodeCollections, where it is equivalent to a Repeat with\n    MinCount=0 and MaxCount=1.<br>\n    <br>\n    The resulting match object can also be used to retrieve the nodes\n    stored in the capture groups:<br>\n    <span style=\"color: #0000ff; font-weight: bold; \">if</span>&nbsp;<span\n      style=\"color: #235100; font-weight: normal; font-style: normal; \">(</span>m<span\n      style=\"color: #235100; font-weight: normal; font-style: normal; \">.</span>Success<span\n      style=\"color: #235100; font-weight: normal; font-style: normal; \">)</span>&nbsp;<span\n      style=\"color: #235100; font-weight: normal; font-style: normal; \">{</span><br>\n    &nbsp;&nbsp;&nbsp;&nbsp;m<span style=\"color: #235100; font-weight: normal; font-style:\n      normal; \">.</span>Get<span style=\"color: #235100; font-weight:\n      normal; font-style: normal; \">&lt;</span>AstType<span\n      style=\"color: #235100; font-weight: normal; font-style: normal; \">&gt;(</span><span\n      style=\"color: #0000ff; \">\"type\"</span><span style=\"color: #235100;\n      font-weight: normal; font-style: normal; \">).</span><span\n      style=\"color: #191970; font-weight: bold; \">Single</span><span\n      style=\"color: #235100; font-weight: normal; font-style: normal; \">().</span><span\n      style=\"color: #191970; font-weight: bold; \">ReplaceWith</span><span\n      style=\"color: #235100; font-weight: normal; font-style: normal; \">(</span><span\n      style=\"color: #008b8b; font-weight: bold; \">new</span>&nbsp;<span\n      style=\"color: #191970; font-weight: bold; \">SimpleType</span><span\n      style=\"color: #235100; font-weight: normal; font-style: normal; \">(</span><span\n      style=\"color: #0000ff; \">\"var\"</span><span style=\"color: #235100;\n      font-weight: normal; font-style: normal; \">));</span><br>\n    <span style=\"color: #235100; font-weight: normal; font-style:\n      normal; \">}</span><br>\n    <br>\n    This feature was originally written for the decompiler in ILSpy, but\n    it is also very useful for refactorings. You can also implement\n    custom pattern nodes (derive from the Pattern base class) with\n    custom match logic - for example if you want to check the semantics\n    of a node.<br>\n</body></html>"
  },
  {
    "path": "doc/README.md",
    "content": "# Files\n\n## License-Related\n\n|File|Contents/Usage|\n|---|---|\n|ILSpyAboutPage.txt|Binary inclusion in ILSpy for About listing ILSpy components' licenses and third party notices link|\n|third-party-notices.txt|Binary inclusion in ILSpy for third party libraries and code used in ILSpy and its components|\n|copyright.txt|Copyright notice for ILSpy|\n|license.txt|MIT license for ILSpy|\n\n## Other\n\n|File|Contents|\n|---|---|\n|   |   |"
  },
  {
    "path": "doc/Resources.txt",
    "content": "System.Resources.ResourceReader is unsuitable for deserializing resources in the ILSpy context,\nbecause it tries to deserialize custom resource types, which fails if the types are in a non-GAC assembly.\n\nSo we are instead using our own \"class ResourcesFile\", which is based on the\n.NET Core ResourceReader implementation.\n\nstruct ResourcesFileFormat {\n\tint32 magicNum; [check == ResourceManager.MagicNumber]\n\t\n\t// ResourceManager header:\n\tint32 resMgrHeaderVersion; [check >= 0]\n\tint32 numBytesToSkip; [check >= 0]\n\tif (resMgrHeaderVersion <= 1) {\n\t\tstring readerType;\n\t\tstring resourceSetType;\n\t} else {\n\t\tbyte _[numBytesToSkip];\n\t}\n\t\n\t// RuntimeResourceSet header:\n\tint32 version; [check in (1, 2)]\n\tint32 numResources; [check >=0]\n\tint32 numTypes; [check >=0]\n\tstring typeName[numTypes];\n\t.align 8;\n\tint32 nameHashes[numResources];\n\tint32 namePositions[numResources]; [check >= 0]\n\tint32 dataSectionOffset; [check >= current position in file]\n\tbyte remainderOfFile[];\n}\n\n// normal strings in this file format are stored as:\nstruct string {\n\tcompressedint len;\n\tbyte value[len]; // interpret as UTF-8\n}\n\n// NameEntry #i is stored starting at remainderOfFile[namePositions[i]]\n// (that is, namePositions is interpreted relative to the start of the remainderOfFile array)\nstruct NameEntry {\n\tcompressedint len;\n\tbyte name[len]; // interpret as UTF-16\n\tint32 dataOffset; [check >= 0]\n}\n\n// Found at position ResourcesFileFormat.dataSectionOffset+NameEntry.dataOffset in the file.\nstruct ValueEntry {\n\tif (version == 1) {\n\t\tcompressedint typeIndex;\n\t\tif (typeIndex == -1) {\n\t\t\t// no value stored; value is implicitly null\n\t\t} else {\n\t\t\tswitch (typeName[typeIndex]) {\n\t\t\t\tcase string:\n\t\t\t\tcase int, uint, long, ulong, sbyte, byte, short, ushort:\n\t\t\t\tcase float:\n\t\t\t\tcase double:\n\t\t\t\t\tT value; // value directly stored\n\t\t\t\tcase DateTime:\n\t\t\t\t\tint64 value; // new DateTime(_store.ReadInt64())\n\t\t\t\tcase TimeSpan:\n\t\t\t\t\tint64 value; // new TimeSpan(_store.ReadInt64())\n\t\t\t\tcase decimal:\n\t\t\t\t\tint32 value[4];\n\t\t\t\tdefault:\n\t\t\t\t\tbyte data[...]; // BinaryFormatter-serialized data using typeName[typeIndex]\n\t\t\t}\n\t\t}\n\t} else if (version == 2) {\n\t\tcompressedint typeCode;\n\t\t// note: unlike v1, no lookup into the typeName array!\n\t\tswitch (typeCode) {\n\t\t\tcase null:\n\t\t\t\t// no value stored; value is implicitly null\n\t\t\tcase string:\n\t\t\tcase bool:\n\t\t\tcase int, uint, long, ulong, sbyte, byte, short, ushort:\n\t\t\t\tT value;\n\t\t\tcase char:\n\t\t\t\tuint16 value;\n\t\t\tcase float:\n\t\t\tcase double:\n\t\t\tcase decimal:\n\t\t\t\tT value;\n\t\t\tcase DateTime:\n\t\t\t\tint64 value; // DateTime.FromBinary(_store.ReadInt64())\n\t\t\tcase TimeSpan:\n\t\t\t\tint64 value; // new TimeSpan(_store.ReadInt64())\n\t\t\tcase ResourceTypeCode.ByteArray:\n\t\t\t\tint32 len;\n\t\t\t\tbyte value[len];\n\t\t\tcase ResourceTypeCode.Stream:\n\t\t\t\tint32 len;\n\t\t\t\tbyte value[len];\n\t\t\tcase >= ResourceTypeCode.StartOfUserTypes:\n\t\t\t\tbyte data[...]; // BinaryFormatter-serialized data using typeName[typeCode - ResourceTypeCode.StartOfUserTypes]\n\t\t}\n\t}\n}"
  },
  {
    "path": "doc/copyright.txt",
    "content": "Copyright 2011-2026 for the ILSpy team\nby\n\n  AlphaSierraPapa, Christoph Wille\n  Vordernberger Strasse 27/8\n  A-8700 Leoben\n  Austria\n\n  email: office@alphasierrapapa.com\n  court of jurisdiction: Landesgericht Leoben"
  },
  {
    "path": "doc/third-party-notices.txt",
    "content": "ILSpy uses third-party libraries or other resources that may\nbe distributed under licenses different than the ILSpy software.\n\nIn the event that we accidentally failed to list a required notice,\nplease bring it to our attention through any of the ways detailed here:\n\n           https://github.com/icsharpcode/ILSpy/issues\n\nThe attached notices are provided for information only, and are sorted alphabetically.\n\nFor any licenses that require disclosure of source, sources are available at\nhttps://github.com/icsharpcode/ILSpy/.\n\n\nLicense Notice for AvalonDock (part of ILSpy)\n---------------------------\n\nhttps://github.com/Dirkster99/AvalonDock/blob/master/LICENSE\n\n\nMs-PL\nMicrosoft Public License (Ms-PL)\n\nThis license governs use of the accompanying software. If you use the software, \nyou accept this license. If you do not accept the license, do not use the software.\n\n1. Definitions\n\nThe terms \"reproduce,\" \"reproduction,\" \"derivative works,\" and \"distribution\" have \nthe same meaning here as under U.S. copyright law.\n\nA \"contribution\" is the original software, or any additions or changes to the software.\n\nA \"contributor\" is any person that distributes its contribution under this license.\n\n\"Licensed patents\" are a contributor's patent claims that read directly on its contribution.\n\n2. Grant of Rights\n\n(A) Copyright Grant- Subject to the terms of this license, including the license \nconditions and limitations in section 3, each contributor grants you a \nnon-exclusive, worldwide, royalty-free copyright license to reproduce its \ncontribution, prepare derivative works of its contribution, and distribute its \ncontribution or any derivative works that you create.\n\n(B) Patent Grant- Subject to the terms of this license, including the license \nconditions and limitations in section 3, each contributor grants you a\n non-exclusive, worldwide, royalty-free license under its licensed patents to \n make, have made, use, sell, offer for sale, import, and/or otherwise dispose \n of its contribution in the software or derivative works of the contribution \n in the software.\n\n3. Conditions and Limitations\n\n(A) No Trademark License- This license does not grant you rights to use any \ncontributors' name, logo, or trademarks.\n\n(B) If you bring a patent claim against any contributor over patents that \nyou claim are infringed by the software, your patent license from such \ncontributor to the software ends automatically.\n\n(C) If you distribute any portion of the software, you must retain all \ncopyright, patent, trademark, and attribution notices that are present \nin the software.\n\n(D) If you distribute any portion of the software in source code form, you \nmay do so only under this license by including a complete copy of this \nlicense with your distribution. If you distribute any portion of the software \nin compiled or object code form, you may only do so under a license that \ncomplies with this license.\n\n(E) The software is licensed \"as-is.\" You bear the risk of using it. The \ncontributors give no express warranties, guarantees or conditions. You may \nhave additional consumer rights under your local laws which this license \ncannot change. To the extent permitted under your local laws, the contributors \nexclude the implied warranties of merchantability, fitness for a particular \npurpose and non-infringement.\n\n\nLicense Notice for AvalonEdit (part of ILSpy)\n---------------------------\n\nhttps://github.com/icsharpcode/AvalonEdit/blob/master/LICENSE\n\nMIT License\n\nCopyright (c) AvalonEdit Contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n\nLicense Notice for CommandLineUtils (part of ICSharpCode.ILSpyCmd)\n---------------------------\n\nhttps://github.com/natemcmaster/CommandLineUtils/blob/master/LICENSE.txt\n\nApache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n    \"License\" shall mean the terms and conditions for use, reproduction,\n    and distribution as defined by Sections 1 through 9 of this document.\n\n    \"Licensor\" shall mean the copyright owner or entity authorized by\n    the copyright owner that is granting the License.\n\n    \"Legal Entity\" shall mean the union of the acting entity and all\n    other entities that control, are controlled by, or are under common\n    control with that entity. For the purposes of this definition,\n    \"control\" means (i) the power, direct or indirect, to cause the\n    direction or management of such entity, whether by contract or\n    otherwise, or (ii) ownership of fifty percent (50%) or more of the\n    outstanding shares, or (iii) beneficial ownership of such entity.\n\n    \"You\" (or \"Your\") shall mean an individual or Legal Entity\n    exercising permissions granted by this License.\n\n    \"Source\" form shall mean the preferred form for making modifications,\n    including but not limited to software source code, documentation\n    source, and configuration files.\n\n    \"Object\" form shall mean any form resulting from mechanical\n    transformation or translation of a Source form, including but\n    not limited to compiled object code, generated documentation,\n    and conversions to other media types.\n\n    \"Work\" shall mean the work of authorship, whether in Source or\n    Object form, made available under the License, as indicated by a\n    copyright notice that is included in or attached to the work\n    (an example is provided in the Appendix below).\n\n    \"Derivative Works\" shall mean any work, whether in Source or Object\n    form, that is based on (or derived from) the Work and for which the\n    editorial revisions, annotations, elaborations, or other modifications\n    represent, as a whole, an original work of authorship. For the purposes\n    of this License, Derivative Works shall not include works that remain\n    separable from, or merely link (or bind by name) to the interfaces of,\n    the Work and Derivative Works thereof.\n\n    \"Contribution\" shall mean any work of authorship, including\n    the original version of the Work and any modifications or additions\n    to that Work or Derivative Works thereof, that is intentionally\n    submitted to Licensor for inclusion in the Work by the copyright owner\n    or by an individual or Legal Entity authorized to submit on behalf of\n    the copyright owner. For the purposes of this definition, \"submitted\"\n    means any form of electronic, verbal, or written communication sent\n    to the Licensor or its representatives, including but not limited to\n    communication on electronic mailing lists, source code control systems,\n    and issue tracking systems that are managed by, or on behalf of, the\n    Licensor for the purpose of discussing and improving the Work, but\n    excluding communication that is conspicuously marked or otherwise\n    designated in writing by the copyright owner as \"Not a Contribution.\"\n\n    \"Contributor\" shall mean Licensor and any individual or Legal Entity\n    on behalf of whom a Contribution has been received by Licensor and\n    subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n    this License, each Contributor hereby grants to You a perpetual,\n    worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n    copyright license to reproduce, prepare Derivative Works of,\n    publicly display, publicly perform, sublicense, and distribute the\n    Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n    this License, each Contributor hereby grants to You a perpetual,\n    worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n    (except as stated in this section) patent license to make, have made,\n    use, offer to sell, sell, import, and otherwise transfer the Work,\n    where such license applies only to those patent claims licensable\n    by such Contributor that are necessarily infringed by their\n    Contribution(s) alone or by combination of their Contribution(s)\n    with the Work to which such Contribution(s) was submitted. If You\n    institute patent litigation against any entity (including a\n    cross-claim or counterclaim in a lawsuit) alleging that the Work\n    or a Contribution incorporated within the Work constitutes direct\n    or contributory patent infringement, then any patent licenses\n    granted to You under this License for that Work shall terminate\n    as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n    Work or Derivative Works thereof in any medium, with or without\n    modifications, and in Source or Object form, provided that You\n    meet the following conditions:\n\n    (a) You must give any other recipients of the Work or\n        Derivative Works a copy of this License; and\n\n    (b) You must cause any modified files to carry prominent notices\n        stating that You changed the files; and\n\n    (c) You must retain, in the Source form of any Derivative Works\n        that You distribute, all copyright, patent, trademark, and\n        attribution notices from the Source form of the Work,\n        excluding those notices that do not pertain to any part of\n        the Derivative Works; and\n\n    (d) If the Work includes a \"NOTICE\" text file as part of its\n        distribution, then any Derivative Works that You distribute must\n        include a readable copy of the attribution notices contained\n        within such NOTICE file, excluding those notices that do not\n        pertain to any part of the Derivative Works, in at least one\n        of the following places: within a NOTICE text file distributed\n        as part of the Derivative Works; within the Source form or\n        documentation, if provided along with the Derivative Works; or,\n        within a display generated by the Derivative Works, if and\n        wherever such third-party notices normally appear. The contents\n        of the NOTICE file are for informational purposes only and\n        do not modify the License. You may add Your own attribution\n        notices within Derivative Works that You distribute, alongside\n        or as an addendum to the NOTICE text from the Work, provided\n        that such additional attribution notices cannot be construed\n        as modifying the License.\n\n    You may add Your own copyright statement to Your modifications and\n    may provide additional or different license terms and conditions\n    for use, reproduction, or distribution of Your modifications, or\n    for any such Derivative Works as a whole, provided Your use,\n    reproduction, and distribution of the Work otherwise complies with\n    the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n    any Contribution intentionally submitted for inclusion in the Work\n    by You to the Licensor shall be under the terms and conditions of\n    this License, without any additional terms or conditions.\n    Notwithstanding the above, nothing herein shall supersede or modify\n    the terms of any separate license agreement you may have executed\n    with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n    names, trademarks, service marks, or product names of the Licensor,\n    except as required for reasonable and customary use in describing the\n    origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n    agreed to in writing, Licensor provides the Work (and each\n    Contributor provides its Contributions) on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n    implied, including, without limitation, any warranties or conditions\n    of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n    PARTICULAR PURPOSE. You are solely responsible for determining the\n    appropriateness of using or redistributing the Work and assume any\n    risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n    whether in tort (including negligence), contract, or otherwise,\n    unless required by applicable law (such as deliberate and grossly\n    negligent acts) or agreed to in writing, shall any Contributor be\n    liable to You for damages, including any direct, indirect, special,\n    incidental, or consequential damages of any character arising as a\n    result of this License or out of the use or inability to use the\n    Work (including but not limited to damages for loss of goodwill,\n    work stoppage, computer failure or malfunction, or any and all\n    other commercial damages or losses), even if such Contributor\n    has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n    the Work or Derivative Works thereof, You may choose to offer,\n    and charge a fee for, acceptance of support, warranty, indemnity,\n    or other liability obligations and/or rights consistent with this\n    License. However, in accepting such obligations, You may act only\n    on Your own behalf and on Your sole responsibility, not on behalf\n    of any other Contributor, and only if You agree to indemnify,\n    defend, and hold each Contributor harmless for any liability\n    incurred by, or claims asserted against, such Contributor by reason\n    of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\n\nLicense Notice for Data Grid Extensions (part of ILSpy)\n---------------------------\n\nhttps://github.com/dotnet/DataGridExtensions/blob/master/License\n\nThe MIT License (MIT)\nCopyright (c) .NET Foundation and Contributors\nAll Rights Reserved\n\nPermission is hereby granted, free of charge, to any person obtaining a copy \nof this software and associated documentation files (the \"Software\"), to deal \nin the Software without restriction, including without limitation the rights \nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell \ncopies of the Software, and to permit persons to whom the Software is \nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included \nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR \nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, \nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE \nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER \nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN \nTHE SOFTWARE.\n\n\nLicense Notice for Humanizer (part of ICSharpCode.Decompiler)\n---------------------------\n\nhttps://github.com/Humanizr/Humanizer/blob/master/LICENSE\n\nThe MIT License (MIT)\n\nCopyright (c) .NET Foundation and Contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n==============================================================================\n\nInflector (https://github.com/srkirkland/Inflector)\nThe MIT License (MIT)\nCopyright (c) 2013 Scott Kirkland\n\n==============================================================================\n\nByteSize (https://github.com/omar/ByteSize)\nThe MIT License (MIT)\nCopyright (c) 2013-2014 Omar Khudeira (http://omar.io)\n\n==============================================================================\n\n\nLicense Notice for Iced (part of ILSpy.ReadyToRun)\n---------------------------\n\nhttps://github.com/0xd4d/iced/blob/master/LICENSE.txt\n\nCopyright (C) 2018-2019 de4dot@gmail.com\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\nLicense Notice for ILCompiler.Reflection.ReadyToRun (part of ILSpy.ReadyToRun)\n---------------------------\n\nhttps://github.com/dotnet/runtime/blob/master/LICENSE.TXT\n\nThe MIT License (MIT)\n\nCopyright (c) .NET Foundation and Contributors\n\nAll rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n\nLicense Notice for K4os.Compression.LZ4 (part of ILSpy)\n---------------------------\n\nhttps://github.com/MiloszKrajewski/K4os.Compression.LZ4/blob/master/LICENSE\n\nMIT License\n\nCopyright (c) 2017 Milosz Krajewski\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n\nLicense Notice for LightJson (part of ICSharpCode.Decompiler)\n---------------------------\n\nhttps://github.com/MarcosLopezC/LightJson/blob/master/LICENSE.txt\n\nThe MIT License (MIT)\n\nCopyright (c) 2018 Marcos López C.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n\nLicense Notice for Mono.Cecil (part of ILSpy)\n---------------------------\n\nhttps://github.com/jbevain/cecil/blob/master/LICENSE.txt\n\nCopyright (c) 2008 - 2015 Jb Evain\nCopyright (c) 2008 - 2011 Novell, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\nLicense Notice for Tom's Toolbox (part of ILSpy)\n---------------------------\n\nhttps://github.com/tom-englert/TomsToolbox/blob/master/LICENSE\n\nThe MIT License (MIT)\nCopyright (c) tom-englert.de\nAll Rights Reserved\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "global.json",
    "content": "{\n  \"sdk\": {\n    \"version\": \"10.0.0\",\n    \"rollForward\": \"major\",\n    \"allowPrerelease\": true\n  },\n  \"test\": {\n    \"runner\": \"Microsoft.Testing.Platform\"\n  }\n}\n"
  },
  {
    "path": "publish.ps1",
    "content": "$output_arm64 = \"./ILSpy/bin/Release/net10.0-windows/win-arm64/publish/fwdependent\"\n$output_x64 = \"./ILSpy/bin/Release/net10.0-windows/win-x64/publish/fwdependent\"\n$output_x64_selfcontained = \"./ILSpy/bin/Release/net10.0-windows/win-x64/publish/selfcontained\"\n\ndotnet publish ./ILSpy/ILSpy.csproj -c Release --no-restore --no-self-contained -r win-arm64 -o $output_arm64\ndotnet publish ./ILSpy.ReadyToRun/ILSpy.ReadyToRun.csproj -c Release --no-restore --no-self-contained -r win-arm64 -o $output_arm64\ndotnet publish ./ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj -c Release --no-restore --no-self-contained -r win-arm64 -o $output_arm64\n\ndotnet publish ./ILSpy/ILSpy.csproj -c Release --no-restore --no-self-contained -r win-x64 -o $output_x64\ndotnet publish ./ILSpy.ReadyToRun/ILSpy.ReadyToRun.csproj -c Release --no-restore --no-self-contained -r win-x64 -o $output_x64\ndotnet publish ./ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj -c Release --no-restore --no-self-contained -r win-x64 -o $output_x64\n\ndotnet publish ./ILSpy/ILSpy.csproj -c Release --no-restore --self-contained -r win-x64 -o $output_x64_selfcontained\ndotnet publish ./ILSpy.ReadyToRun/ILSpy.ReadyToRun.csproj -c Release --no-restore --self-contained -r win-x64 -o $output_x64_selfcontained\ndotnet publish ./ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj -c Release --no-restore --self-contained -r win-x64 -o $output_x64_selfcontained"
  },
  {
    "path": "publishlocaldev.ps1",
    "content": "# For local development of the VSIX package - build and publish (VS2022 also needs arm64)\n\n$output_x64 = \"./ILSpy/bin/Release/net10.0-windows/win-x64/publish/fwdependent\"\n\ndotnet publish ./ILSpy/ILSpy.csproj -c Release --no-restore --no-self-contained -r win-x64 -o $output_x64\ndotnet publish ./ILSpy.ReadyToRun/ILSpy.ReadyToRun.csproj -c Release --no-restore --no-self-contained -r win-x64 -o $output_x64\ndotnet publish ./ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj -c Release --no-restore --no-self-contained -r win-x64 -o $output_x64\n\n$output_arm64 = \"./ILSpy/bin/Release/net10.0-windows/win-arm64/publish/fwdependent\"\n\ndotnet publish ./ILSpy/ILSpy.csproj -c Release --no-restore --no-self-contained -r win-arm64 -o $output_arm64\ndotnet publish ./ILSpy.ReadyToRun/ILSpy.ReadyToRun.csproj -c Release --no-restore --no-self-contained -r win-arm64 -o $output_arm64\ndotnet publish ./ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj -c Release --no-restore --no-self-contained -r win-arm64 -o $output_arm64"
  },
  {
    "path": "releasebuild.bat",
    "content": "dotnet build ILSpy.sln /p:Configuration=Release \"/p:Platform=Any CPU\" %* || (pause && exit /b 1)\n"
  },
  {
    "path": "updatedeps.bat",
    "content": "dotnet restore ILSpy.sln --force-evaluate -p:RestoreEnablePackagePruning=false"
  }
]